summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiyong Min <jiyong.min@samsung.com>2017-12-13 11:54:48 +0900
committerJiyong Min <jiyong.min@samsung.com>2017-12-13 11:55:54 +0900
commitdcc5a7178e7d3faf8f345642658392777c224191 (patch)
tree1b5df831d4ee38ba295e82007a46233f5ed865aa
parent9d9902cab7b41a28c59c6b43c5d917b89fb0badd (diff)
downloadGraphicsMagick-dcc5a7178e7d3faf8f345642658392777c224191.tar.gz
GraphicsMagick-dcc5a7178e7d3faf8f345642658392777c224191.tar.bz2
GraphicsMagick-dcc5a7178e7d3faf8f345642658392777c224191.zip
Imported Upstream version 1.3.26upstream/1.3.26
Change-Id: I51058668a831efe4bc05b6e19491dfae785698ac
-rw-r--r--ChangeLog252
-rw-r--r--ChangeLog.2001290
-rw-r--r--ChangeLog.20021417
-rw-r--r--ChangeLog.20034901
-rw-r--r--ChangeLog.20041491
-rw-r--r--ChangeLog.2005914
-rw-r--r--ChangeLog.2006189
-rw-r--r--ChangeLog.2007973
-rw-r--r--ChangeLog.20082127
-rw-r--r--ChangeLog.20091711
-rw-r--r--ChangeLog.2010668
-rw-r--r--ChangeLog.2011607
-rw-r--r--ChangeLog.2012868
-rw-r--r--ChangeLog.2013530
-rw-r--r--ChangeLog.2014895
-rw-r--r--ChangeLog.20152066
-rw-r--r--Copyright.txt285
-rw-r--r--GraphicsMagick.spec.in298
-rw-r--r--Magick++/AUTHORS19
-rw-r--r--Magick++/COPYING21
-rw-r--r--Magick++/ChangeLog1886
-rw-r--r--Magick++/Makefile.am244
-rw-r--r--Magick++/README64
-rw-r--r--Magick++/bin/GraphicsMagick++-config.176
-rwxr-xr-xMagick++/bin/GraphicsMagick++-config.in51
-rw-r--r--Magick++/demo/analyze.cpp67
-rw-r--r--Magick++/demo/button.cpp104
-rw-r--r--Magick++/demo/demo.cpp543
-rwxr-xr-xMagick++/demo/demos.tap48
-rw-r--r--Magick++/demo/detrans.cpp60
-rw-r--r--Magick++/demo/flip.cpp60
-rw-r--r--Magick++/demo/gravity.cpp87
-rw-r--r--Magick++/demo/model.miff155
-rw-r--r--Magick++/demo/piddle.cpp184
-rw-r--r--Magick++/demo/shapes.cpp125
-rw-r--r--Magick++/demo/smile.miffbin0 -> 4814 bytes
-rw-r--r--Magick++/demo/smile_anim.miffbin0 -> 15448 bytes
-rw-r--r--Magick++/demo/tile.miffbin0 -> 6025 bytes
-rw-r--r--Magick++/demo/zoom.cpp191
-rw-r--r--Magick++/lib/Blob.cpp169
-rw-r--r--Magick++/lib/BlobRef.cpp49
-rw-r--r--Magick++/lib/CoderInfo.cpp121
-rw-r--r--Magick++/lib/Color.cpp698
-rw-r--r--Magick++/lib/Drawable.cpp2146
-rw-r--r--Magick++/lib/Exception.cpp574
-rw-r--r--Magick++/lib/Functions.cpp22
-rw-r--r--Magick++/lib/Geometry.cpp519
-rw-r--r--Magick++/lib/GraphicsMagick++.pc.in12
-rw-r--r--Magick++/lib/Image.cpp4165
-rw-r--r--Magick++/lib/ImageRef.cpp98
-rw-r--r--Magick++/lib/Magick++.h14
-rw-r--r--Magick++/lib/Magick++/Blob.h82
-rw-r--r--Magick++/lib/Magick++/BlobRef.h46
-rw-r--r--Magick++/lib/Magick++/CoderInfo.h79
-rw-r--r--Magick++/lib/Magick++/Color.h462
-rw-r--r--Magick++/lib/Magick++/Drawable.h2921
-rw-r--r--Magick++/lib/Magick++/Exception.h337
-rw-r--r--Magick++/lib/Magick++/Functions.h20
-rw-r--r--Magick++/lib/Magick++/Geometry.h153
-rw-r--r--Magick++/lib/Magick++/Image.h1408
-rw-r--r--Magick++/lib/Magick++/ImageRef.h80
-rw-r--r--Magick++/lib/Magick++/Include.h1120
-rw-r--r--Magick++/lib/Magick++/Montage.h386
-rw-r--r--Magick++/lib/Magick++/Options.h288
-rw-r--r--Magick++/lib/Magick++/Pixels.h127
-rw-r--r--Magick++/lib/Magick++/STL.h2445
-rw-r--r--Magick++/lib/Magick++/Thread.h100
-rw-r--r--Magick++/lib/Magick++/TypeMetric.h57
-rw-r--r--Magick++/lib/Montage.cpp133
-rw-r--r--Magick++/lib/Options.cpp852
-rw-r--r--Magick++/lib/Pixels.cpp123
-rw-r--r--Magick++/lib/STL.cpp1614
-rw-r--r--Magick++/lib/Thread.cpp124
-rw-r--r--Magick++/lib/TypeMetric.cpp53
-rw-r--r--Magick++/tests/appendImages.cpp89
-rw-r--r--Magick++/tests/attributes.cpp1543
-rw-r--r--Magick++/tests/averageImages.cpp73
-rw-r--r--Magick++/tests/coalesceImages.cpp62
-rw-r--r--Magick++/tests/coderInfo.cpp134
-rw-r--r--Magick++/tests/color.cpp155
-rw-r--r--Magick++/tests/colorHistogram.cpp101
-rw-r--r--Magick++/tests/exceptions.cpp105
-rw-r--r--Magick++/tests/montageImages.cpp140
-rw-r--r--Magick++/tests/morphImages.cpp71
-rw-r--r--Magick++/tests/readWriteBlob.cpp258
-rw-r--r--Magick++/tests/readWriteImages.cpp119
-rw-r--r--Magick++/tests/test_image.miffbin0 -> 44138 bytes
-rw-r--r--Magick++/tests/test_image_anim.miffbin0 -> 15229 bytes
-rwxr-xr-xMagick++/tests/tests.tap29
-rw-r--r--Makefile.am401
-rw-r--r--Makefile.in10187
-rw-r--r--NEWS.txt3514
-rw-r--r--PerlMagick/.gdbinit4
-rw-r--r--PerlMagick/Changelog125
-rw-r--r--PerlMagick/MANIFEST472
-rw-r--r--PerlMagick/MANIFEST.SKIP11
-rw-r--r--PerlMagick/Magick.pm133
-rw-r--r--PerlMagick/Magick.pm.in133
-rw-r--r--PerlMagick/Magick.xs8017
-rw-r--r--PerlMagick/Makefile.PL118
-rw-r--r--PerlMagick/Makefile.PL.in129
-rw-r--r--PerlMagick/Makefile.am134
-rw-r--r--PerlMagick/Makefile.nt164
-rwxr-xr-xPerlMagick/PerlMagickCheck.sh.in47
-rw-r--r--PerlMagick/README.txt139
-rwxr-xr-xPerlMagick/build_manifest.sh6
-rw-r--r--PerlMagick/demo/Generic.ttfbin0 -> 22660 bytes
-rw-r--r--PerlMagick/demo/Makefile13
-rw-r--r--PerlMagick/demo/README6
-rw-r--r--PerlMagick/demo/Turtle.pm56
-rw-r--r--PerlMagick/demo/annotate.pl40
-rw-r--r--PerlMagick/demo/button.pl15
-rw-r--r--PerlMagick/demo/composite.pl44
-rw-r--r--PerlMagick/demo/demo.pl360
-rw-r--r--PerlMagick/demo/lsys.pl83
-rw-r--r--PerlMagick/demo/model.gifbin0 -> 23433 bytes
-rw-r--r--PerlMagick/demo/model.miffbin0 -> 98145 bytes
-rw-r--r--PerlMagick/demo/piddle.pl66
-rw-r--r--PerlMagick/demo/pink_flower.gifbin0 -> 544 bytes
-rw-r--r--PerlMagick/demo/red_flower.gifbin0 -> 694 bytes
-rw-r--r--PerlMagick/demo/shadow_text.pl16
-rw-r--r--PerlMagick/demo/shapes.pl39
-rw-r--r--PerlMagick/demo/smile.gifbin0 -> 1349 bytes
-rw-r--r--PerlMagick/demo/steganography.pl26
-rw-r--r--PerlMagick/demo/tile.gifbin0 -> 1566 bytes
-rw-r--r--PerlMagick/demo/tree.pl29
-rw-r--r--PerlMagick/demo/yellow_flower.gifbin0 -> 565 bytes
-rw-r--r--PerlMagick/t/MasterImage_70x46.ppm4
-rw-r--r--PerlMagick/t/blob.t34
-rw-r--r--PerlMagick/t/bzlib/input.miff9
-rw-r--r--PerlMagick/t/bzlib/input.miff.bz2bin0 -> 9064 bytes
-rw-r--r--PerlMagick/t/bzlib/read.t37
-rw-r--r--PerlMagick/t/bzlib/write.t35
-rw-r--r--PerlMagick/t/cgm/input.cgm1
-rw-r--r--PerlMagick/t/cgm/read.t28
-rw-r--r--PerlMagick/t/composite.t261
-rw-r--r--PerlMagick/t/features.pl.in5
-rw-r--r--PerlMagick/t/filter.t231
-rw-r--r--PerlMagick/t/fpx/input_256.fpxbin0 -> 80384 bytes
-rw-r--r--PerlMagick/t/fpx/input_bw.fpxbin0 -> 33792 bytes
-rw-r--r--PerlMagick/t/fpx/input_grayscale.fpxbin0 -> 33792 bytes
-rw-r--r--PerlMagick/t/fpx/input_jpeg.fpxbin0 -> 45056 bytes
-rw-r--r--PerlMagick/t/fpx/input_truecolor.fpxbin0 -> 80384 bytes
-rw-r--r--PerlMagick/t/fpx/read.t63
-rw-r--r--PerlMagick/t/fpx/write.t57
-rw-r--r--PerlMagick/t/getattribute.t100
-rw-r--r--PerlMagick/t/hdf/input_256.hdfbin0 -> 4189 bytes
-rw-r--r--PerlMagick/t/hdf/input_truecolor.hdfbin0 -> 9987 bytes
-rw-r--r--PerlMagick/t/hdf/read.t36
-rw-r--r--PerlMagick/t/hdf/write.t40
-rw-r--r--PerlMagick/t/hpgl/input.hpgl1
-rw-r--r--PerlMagick/t/hpgl/read.t37
-rw-r--r--PerlMagick/t/input.artbin0 -> 8168 bytes
-rw-r--r--PerlMagick/t/input.avsbin0 -> 12888 bytes
-rw-r--r--PerlMagick/t/input.biebin0 -> 280 bytes
-rw-r--r--PerlMagick/t/input.bmpbin0 -> 6414 bytes
-rw-r--r--PerlMagick/t/input.bmp24bin0 -> 9806 bytes
-rw-r--r--PerlMagick/t/input.dcxbin0 -> 15713 bytes
-rw-r--r--PerlMagick/t/input.dibbin0 -> 9792 bytes
-rw-r--r--PerlMagick/t/input.gifbin0 -> 3901 bytes
-rw-r--r--PerlMagick/t/input.gif87bin0 -> 3893 bytes
-rw-r--r--PerlMagick/t/input.hrz3361
-rw-r--r--PerlMagick/t/input.icobin0 -> 766 bytes
-rw-r--r--PerlMagick/t/input.im1bin0 -> 492 bytes
-rw-r--r--PerlMagick/t/input.im24bin0 -> 9692 bytes
-rw-r--r--PerlMagick/t/input.im8bin0 -> 4020 bytes
-rw-r--r--PerlMagick/t/input.macbin0 -> 54789 bytes
-rw-r--r--PerlMagick/t/input.miff9
-rw-r--r--PerlMagick/t/input.mtv2
-rw-r--r--PerlMagick/t/input.p7bin0 -> 3254 bytes
-rw-r--r--PerlMagick/t/input.pam8
-rw-r--r--PerlMagick/t/input.pcxbin0 -> 11613 bytes
-rw-r--r--PerlMagick/t/input.pictbin0 -> 10428 bytes
-rw-r--r--PerlMagick/t/input.psdbin0 -> 9700 bytes
-rw-r--r--PerlMagick/t/input.pxrbin0 -> 11264 bytes
-rw-r--r--PerlMagick/t/input.rlebin0 -> 10516 bytes
-rw-r--r--PerlMagick/t/input.sctbin0 -> 11708 bytes
-rw-r--r--PerlMagick/t/input.sgibin0 -> 11683 bytes
-rw-r--r--PerlMagick/t/input.tgabin0 -> 9678 bytes
-rw-r--r--PerlMagick/t/input.timbin0 -> 1088 bytes
-rw-r--r--PerlMagick/t/input.viffbin0 -> 5012 bytes
-rw-r--r--PerlMagick/t/input.wbmpbin0 -> 418 bytes
-rw-r--r--PerlMagick/t/input.xbm38
-rw-r--r--PerlMagick/t/input.xpm308
-rw-r--r--PerlMagick/t/input.xwdbin0 -> 9862 bytes
-rw-r--r--PerlMagick/t/input1_4.wpgbin0 -> 495 bytes
-rw-r--r--PerlMagick/t/input1_8_1.wpgbin0 -> 3145 bytes
-rw-r--r--PerlMagick/t/input2_4.wpgbin0 -> 707 bytes
-rw-r--r--PerlMagick/t/input2_8.wpgbin0 -> 6340 bytes
-rw-r--r--PerlMagick/t/input2_TC1.wpgbin0 -> 4625 bytes
-rw-r--r--PerlMagick/t/input_1555.bmpbin0 -> 6496 bytes
-rw-r--r--PerlMagick/t/input_16.miff9
-rw-r--r--PerlMagick/t/input_16.pctbin0 -> 6776 bytes
-rw-r--r--PerlMagick/t/input_16.tgabin0 -> 6484 bytes
-rw-r--r--PerlMagick/t/input_16rle.tgabin0 -> 6058 bytes
-rw-r--r--PerlMagick/t/input_24.tgabin0 -> 9704 bytes
-rw-r--r--PerlMagick/t/input_24rle.tgabin0 -> 9625 bytes
-rw-r--r--PerlMagick/t/input_32.pctbin0 -> 10454 bytes
-rw-r--r--PerlMagick/t/input_32.tgabin0 -> 12924 bytes
-rw-r--r--PerlMagick/t/input_32rle.tgabin0 -> 12779 bytes
-rw-r--r--PerlMagick/t/input_4444.bmpbin0 -> 6512 bytes
-rw-r--r--PerlMagick/t/input_565.bmpbin0 -> 6512 bytes
-rw-r--r--PerlMagick/t/input_64.pam248
-rw-r--r--PerlMagick/t/input_70x46.cmykbin0 -> 12880 bytes
-rw-r--r--PerlMagick/t/input_70x46.gray1
-rw-r--r--PerlMagick/t/input_70x46.rgb1
-rw-r--r--PerlMagick/t/input_70x46.rgba1
-rw-r--r--PerlMagick/t/input_70x46.uyvy1
-rw-r--r--PerlMagick/t/input_70x46.yuv1
-rw-r--r--PerlMagick/t/input_888.bmpbin0 -> 9808 bytes
-rw-r--r--PerlMagick/t/input_8888.bmpbin0 -> 12952 bytes
-rw-r--r--PerlMagick/t/input_888flip.bmpbin0 -> 9808 bytes
-rw-r--r--PerlMagick/t/input_complex_lsb_double_V4.matbin0 -> 10695 bytes
-rw-r--r--PerlMagick/t/input_gray.cinbin0 -> 5440 bytes
-rw-r--r--PerlMagick/t/input_gray.rlabin0 -> 11434 bytes
-rw-r--r--PerlMagick/t/input_gray.rlebin0 -> 3582 bytes
-rw-r--r--PerlMagick/t/input_gray_01bit.palmbin0 -> 476 bytes
-rw-r--r--PerlMagick/t/input_gray_01bit_rle.palmbin0 -> 716 bytes
-rw-r--r--PerlMagick/t/input_gray_01bit_scan.palmbin0 -> 370 bytes
-rw-r--r--PerlMagick/t/input_gray_02bit.palmbin0 -> 844 bytes
-rw-r--r--PerlMagick/t/input_gray_02bit_rle.palmbin0 -> 1412 bytes
-rw-r--r--PerlMagick/t/input_gray_02bit_scan.palmbin0 -> 827 bytes
-rw-r--r--PerlMagick/t/input_gray_04bit.palmbin0 -> 1672 bytes
-rw-r--r--PerlMagick/t/input_gray_04bit_rle.palmbin0 -> 2598 bytes
-rw-r--r--PerlMagick/t/input_gray_04bit_scan.palmbin0 -> 1421 bytes
-rw-r--r--PerlMagick/t/input_gray_08bit.fitsbin0 -> 8640 bytes
-rw-r--r--PerlMagick/t/input_gray_16bit.fitsbin0 -> 11520 bytes
-rw-r--r--PerlMagick/t/input_gray_32bit.fitsbin0 -> 17280 bytes
-rw-r--r--PerlMagick/t/input_gray_lsb_08bit.matbin0 -> 3456 bytes
-rw-r--r--PerlMagick/t/input_gray_lsb_16bit.matbin0 -> 7880 bytes
-rw-r--r--PerlMagick/t/input_gray_lsb_32bit.matbin0 -> 13248 bytes
-rw-r--r--PerlMagick/t/input_gray_lsb_double.fitsbin0 -> 31680 bytes
-rw-r--r--PerlMagick/t/input_gray_lsb_double.matbin0 -> 26312 bytes
-rw-r--r--PerlMagick/t/input_gray_lsb_double_V4.matbin0 -> 5978 bytes
-rw-r--r--PerlMagick/t/input_gray_lsb_float.matbin0 -> 12968 bytes
-rw-r--r--PerlMagick/t/input_gray_msb_08bit.matbin0 -> 20560 bytes
-rw-r--r--PerlMagick/t/input_gray_msb_16bit.fitsbin0 -> 11520 bytes
-rw-r--r--PerlMagick/t/input_gray_msb_32bit.fitsbin0 -> 17280 bytes
-rw-r--r--PerlMagick/t/input_gray_msb_64bit.fitsbin0 -> 31680 bytes
-rw-r--r--PerlMagick/t/input_gray_msb_double.fitsbin0 -> 31680 bytes
-rw-r--r--PerlMagick/t/input_gray_msb_float.fitsbin0 -> 17280 bytes
-rw-r--r--PerlMagick/t/input_jnx.jnxbin0 -> 8378 bytes
-rw-r--r--PerlMagick/t/input_logical_lsb_08bit.matbin0 -> 5880 bytes
-rw-r--r--PerlMagick/t/input_matte.miffbin0 -> 13050 bytes
-rw-r--r--PerlMagick/t/input_p1.pbm92
-rw-r--r--PerlMagick/t/input_p2.pgm272
-rw-r--r--PerlMagick/t/input_p3.ppm809
-rw-r--r--PerlMagick/t/input_p4.pbmbin0 -> 423 bytes
-rw-r--r--PerlMagick/t/input_p5.pgm4
-rw-r--r--PerlMagick/t/input_p6.ppm4
-rw-r--r--PerlMagick/t/input_p7.p7bin0 -> 3254 bytes
-rw-r--r--PerlMagick/t/input_rgb.cinbin0 -> 13904 bytes
-rw-r--r--PerlMagick/t/input_rgb.rlabin0 -> 11490 bytes
-rw-r--r--PerlMagick/t/input_rgb.txt240
-rw-r--r--PerlMagick/t/input_rgb_08bit.palmbin0 -> 3236 bytes
-rw-r--r--PerlMagick/t/input_rgb_08bit_cmap.palmbin0 -> 4250 bytes
-rw-r--r--PerlMagick/t/input_rgb_08bit_rle.palmbin0 -> 4596 bytes
-rw-r--r--PerlMagick/t/input_rgb_08bit_scan.palmbin0 -> 2717 bytes
-rw-r--r--PerlMagick/t/input_rgb_08bit_trans.palmbin0 -> 3236 bytes
-rw-r--r--PerlMagick/t/input_rgb_16bit.palmbin0 -> 6464 bytes
-rw-r--r--PerlMagick/t/input_rgb_16bit_rle.palmbin0 -> 12808 bytes
-rw-r--r--PerlMagick/t/input_rgb_16bit_scan.palmbin0 -> 5824 bytes
-rw-r--r--PerlMagick/t/input_rgb_16bit_trans.palmbin0 -> 6464 bytes
-rw-r--r--PerlMagick/t/input_rgb_lsb_08bit.matbin0 -> 9992 bytes
-rw-r--r--PerlMagick/t/jbig/input.jbigbin0 -> 281 bytes
-rw-r--r--PerlMagick/t/jbig/read.t25
-rw-r--r--PerlMagick/t/jbig/write.t30
-rw-r--r--PerlMagick/t/jng/input_gray.jngbin0 -> 996 bytes
-rw-r--r--PerlMagick/t/jng/input_gray_idat.jngbin0 -> 3874 bytes
-rw-r--r--PerlMagick/t/jng/input_gray_jdaa.jngbin0 -> 1946 bytes
-rw-r--r--PerlMagick/t/jng/input_gray_prog.jngbin0 -> 1110 bytes
-rw-r--r--PerlMagick/t/jng/input_gray_prog_idat.jngbin0 -> 3988 bytes
-rw-r--r--PerlMagick/t/jng/input_gray_prog_jdaa.jngbin0 -> 2178 bytes
-rw-r--r--PerlMagick/t/jng/input_idat.jngbin0 -> 4441 bytes
-rw-r--r--PerlMagick/t/jng/input_jdaa.jngbin0 -> 2278 bytes
-rw-r--r--PerlMagick/t/jng/input_prog.jngbin0 -> 1550 bytes
-rw-r--r--PerlMagick/t/jng/input_prog_idat.jngbin0 -> 4666 bytes
-rw-r--r--PerlMagick/t/jng/input_prog_jdaa.jngbin0 -> 2619 bytes
-rw-r--r--PerlMagick/t/jng/input_rose.jngbin0 -> 1325 bytes
-rw-r--r--PerlMagick/t/jng/read.t75
-rw-r--r--PerlMagick/t/jng/write.t55
-rw-r--r--PerlMagick/t/jp2/input.jp2bin0 -> 6410 bytes
-rw-r--r--PerlMagick/t/jp2/input.jpcbin0 -> 6410 bytes
-rw-r--r--PerlMagick/t/jp2/input.pgx2
-rw-r--r--PerlMagick/t/jp2/read.t40
-rw-r--r--PerlMagick/t/jpeg/input.jpgbin0 -> 1564 bytes
-rw-r--r--PerlMagick/t/jpeg/input.sfwbin0 -> 29241 bytes
-rw-r--r--PerlMagick/t/jpeg/input_plane.jpgbin0 -> 1805 bytes
-rw-r--r--PerlMagick/t/jpeg/read.t42
-rw-r--r--PerlMagick/t/jpeg/write.t41
-rw-r--r--PerlMagick/t/montage.t198
-rw-r--r--PerlMagick/t/mpeg/input.m2vbin0 -> 15924 bytes
-rw-r--r--PerlMagick/t/mpeg/input.mpgbin0 -> 11473 bytes
-rw-r--r--PerlMagick/t/mpeg/read.t38
-rw-r--r--PerlMagick/t/palm_std_colormap.palmbin0 -> 1174 bytes
-rw-r--r--PerlMagick/t/ping.t56
-rw-r--r--PerlMagick/t/png/input.mngbin0 -> 12920 bytes
-rw-r--r--PerlMagick/t/png/input_16.pngbin0 -> 2440 bytes
-rw-r--r--PerlMagick/t/png/input_256.pngbin0 -> 3841 bytes
-rw-r--r--PerlMagick/t/png/input_bw.pngbin0 -> 112 bytes
-rw-r--r--PerlMagick/t/png/input_mono.pngbin0 -> 616 bytes
-rw-r--r--PerlMagick/t/png/input_truecolor.pngbin0 -> 6967 bytes
-rw-r--r--PerlMagick/t/png/read-16.t58
-rw-r--r--PerlMagick/t/png/read.t71
-rw-r--r--PerlMagick/t/png/write-16.t69
-rw-r--r--PerlMagick/t/png/write.t76
-rw-r--r--PerlMagick/t/ps/input.eps132
-rw-r--r--PerlMagick/t/ps/input.miff9
-rw-r--r--PerlMagick/t/ps/input.ps134
-rw-r--r--PerlMagick/t/ps/read.t81
-rw-r--r--PerlMagick/t/ps/write.t38
-rw-r--r--PerlMagick/t/rad/input.radbin0 -> 20051 bytes
-rw-r--r--PerlMagick/t/rad/read.t26
-rw-r--r--PerlMagick/t/rad/write.t33
-rw-r--r--PerlMagick/t/read.t355
-rw-r--r--PerlMagick/t/reference/cgm/read.miff582
-rw-r--r--PerlMagick/t/reference/composite/Add.miffbin0 -> 24093 bytes
-rw-r--r--PerlMagick/t/reference/composite/Atop.miff101
-rw-r--r--PerlMagick/t/reference/composite/Bumpmap.miff119
-rw-r--r--PerlMagick/t/reference/composite/Clear.miff101
-rw-r--r--PerlMagick/t/reference/composite/Copy.miff101
-rw-r--r--PerlMagick/t/reference/composite/CopyBlue.miff101
-rw-r--r--PerlMagick/t/reference/composite/CopyGreen.miff101
-rw-r--r--PerlMagick/t/reference/composite/CopyOpacity.miffbin0 -> 32092 bytes
-rw-r--r--PerlMagick/t/reference/composite/CopyRed.miff101
-rw-r--r--PerlMagick/t/reference/composite/Difference.miff108
-rw-r--r--PerlMagick/t/reference/composite/Dissolve.miff101
-rw-r--r--PerlMagick/t/reference/composite/Divide.miff101
-rw-r--r--PerlMagick/t/reference/composite/In.miff101
-rw-r--r--PerlMagick/t/reference/composite/Minus.miff121
-rw-r--r--PerlMagick/t/reference/composite/Multiply.miff99
-rw-r--r--PerlMagick/t/reference/composite/Out.miff101
-rw-r--r--PerlMagick/t/reference/composite/Over.miff101
-rw-r--r--PerlMagick/t/reference/composite/Plus.miff101
-rw-r--r--PerlMagick/t/reference/composite/Subtract.miffbin0 -> 24093 bytes
-rw-r--r--PerlMagick/t/reference/composite/Xor.miff101
-rw-r--r--PerlMagick/t/reference/filter/Blur.miff9
-rw-r--r--PerlMagick/t/reference/filter/Border.miff9
-rw-r--r--PerlMagick/t/reference/filter/Channel.miff8
-rw-r--r--PerlMagick/t/reference/filter/Chop.miff9
-rw-r--r--PerlMagick/t/reference/filter/ColorFloodfill.miff8
-rw-r--r--PerlMagick/t/reference/filter/Colorize.miff9
-rw-r--r--PerlMagick/t/reference/filter/Contrast.miff5
-rw-r--r--PerlMagick/t/reference/filter/Convolve.miff9
-rw-r--r--PerlMagick/t/reference/filter/Crop.miff9
-rw-r--r--PerlMagick/t/reference/filter/Despeckle.miff9
-rw-r--r--PerlMagick/t/reference/filter/Edge.miffbin0 -> 9840 bytes
-rw-r--r--PerlMagick/t/reference/filter/Emboss.miffbin0 -> 9840 bytes
-rw-r--r--PerlMagick/t/reference/filter/Equalize.miffbin0 -> 9825 bytes
-rw-r--r--PerlMagick/t/reference/filter/Flip.miff9
-rw-r--r--PerlMagick/t/reference/filter/Flop.miff9
-rw-r--r--PerlMagick/t/reference/filter/Frame.miff9
-rw-r--r--PerlMagick/t/reference/filter/Gamma.miff8
-rw-r--r--PerlMagick/t/reference/filter/Implode.miff9
-rw-r--r--PerlMagick/t/reference/filter/Magnify.miff9
-rw-r--r--PerlMagick/t/reference/filter/MatteFloodfill.miff8
-rw-r--r--PerlMagick/t/reference/filter/Minify.miff9
-rw-r--r--PerlMagick/t/reference/filter/Modulate.miff8
-rw-r--r--PerlMagick/t/reference/filter/MotionBlur.miff6
-rw-r--r--PerlMagick/t/reference/filter/Negate.miffbin0 -> 9825 bytes
-rw-r--r--PerlMagick/t/reference/filter/Normalize.miffbin0 -> 9825 bytes
-rw-r--r--PerlMagick/t/reference/filter/OilPaint.miff9
-rw-r--r--PerlMagick/t/reference/filter/Opaque.miffbin0 -> 9825 bytes
-rw-r--r--PerlMagick/t/reference/filter/Quantize.miffbin0 -> 3781 bytes
-rw-r--r--PerlMagick/t/reference/filter/Raise.miff8
-rw-r--r--PerlMagick/t/reference/filter/Resize.miff9
-rw-r--r--PerlMagick/t/reference/filter/Roll.miff9
-rw-r--r--PerlMagick/t/reference/filter/Rotate0.miff5
-rw-r--r--PerlMagick/t/reference/filter/Rotate10.miffbin0 -> 13332 bytes
-rw-r--r--PerlMagick/t/reference/filter/Rotate180.miff5
-rw-r--r--PerlMagick/t/reference/filter/Rotate270.miff5
-rw-r--r--PerlMagick/t/reference/filter/Rotate90.miff5
-rw-r--r--PerlMagick/t/reference/filter/Sample.miff9
-rw-r--r--PerlMagick/t/reference/filter/Scale.miff9
-rw-r--r--PerlMagick/t/reference/filter/Segment.miffbin0 -> 3398 bytes
-rw-r--r--PerlMagick/t/reference/filter/Shade.miffbin0 -> 9840 bytes
-rw-r--r--PerlMagick/t/reference/filter/Sharpen.miffbin0 -> 9840 bytes
-rw-r--r--PerlMagick/t/reference/filter/Shave.miff9
-rw-r--r--PerlMagick/t/reference/filter/Shear.miffbin0 -> 20811 bytes
-rw-r--r--PerlMagick/t/reference/filter/Solarize.miffbin0 -> 9752 bytes
-rw-r--r--PerlMagick/t/reference/filter/Swirl.miff9
-rw-r--r--PerlMagick/t/reference/filter/Threshold.miffbin0 -> 3401 bytes
-rw-r--r--PerlMagick/t/reference/filter/Trim.miff8
-rw-r--r--PerlMagick/t/reference/filter/UnsharpMask.miff8
-rw-r--r--PerlMagick/t/reference/filter/Wave.miff9
-rw-r--r--PerlMagick/t/reference/jng/read_gray.miff10
-rw-r--r--PerlMagick/t/reference/jng/read_gray_idat.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/read_gray_jdaa.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/read_gray_prog.miff10
-rw-r--r--PerlMagick/t/reference/jng/read_gray_prog_idat.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/read_gray_prog_jdaa.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/read_idat.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/read_jdaa.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/read_prog.miff10
-rw-r--r--PerlMagick/t/reference/jng/read_prog_idat.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/read_prog_jdaa.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/write_gray.miff10
-rw-r--r--PerlMagick/t/reference/jng/write_gray_idat.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/write_gray_jdaa.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/write_gray_prog.miff10
-rw-r--r--PerlMagick/t/reference/jng/write_gray_prog_idat.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/write_gray_prog_jdaa.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/write_idat.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/write_jdaa.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/write_prog.miff10
-rw-r--r--PerlMagick/t/reference/jng/write_prog_idat.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jng/write_prog_jdaa.miffbin0 -> 13122 bytes
-rw-r--r--PerlMagick/t/reference/jp2/read_jp2.miff5
-rw-r--r--PerlMagick/t/reference/jp2/read_jpc.miff5
-rw-r--r--PerlMagick/t/reference/jp2/read_pgx.miff5
-rw-r--r--PerlMagick/t/reference/jpeg/read_non_interlaced.miff5
-rw-r--r--PerlMagick/t/reference/jpeg/read_plane_interlaced.miff5
-rw-r--r--PerlMagick/t/reference/jpeg/read_sfw.miffbin0 -> 833484 bytes
-rw-r--r--PerlMagick/t/reference/jpeg/write_non_interlaced.miff6
-rw-r--r--PerlMagick/t/reference/jpeg/write_plane_interlaced.miff6
-rw-r--r--PerlMagick/t/reference/read/gradient.miffbin0 -> 9752 bytes
-rw-r--r--PerlMagick/t/reference/read/granite.miffbin0 -> 16619 bytes
-rw-r--r--PerlMagick/t/reference/read/input1_4_wpg.miffbin0 -> 1201 bytes
-rw-r--r--PerlMagick/t/reference/read/input1_8_1_wpg.miffbin0 -> 3979 bytes
-rw-r--r--PerlMagick/t/reference/read/input2_8_wpg.miffbin0 -> 6055 bytes
-rw-r--r--PerlMagick/t/reference/read/input2_TC1_wpg.miffbin0 -> 5113 bytes
-rw-r--r--PerlMagick/t/reference/read/input_avs.miff5
-rw-r--r--PerlMagick/t/reference/read/input_bmp.miffbin0 -> 4144 bytes
-rw-r--r--PerlMagick/t/reference/read/input_bmp24.miff6
-rw-r--r--PerlMagick/t/reference/read/input_cmyk.miffbin0 -> 12989 bytes
-rw-r--r--PerlMagick/t/reference/read/input_dcx.miff6
-rw-r--r--PerlMagick/t/reference/read/input_dib.miff6
-rw-r--r--PerlMagick/t/reference/read/input_gif.miffbin0 -> 4120 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gif87.miffbin0 -> 4120 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray.miffbin0 -> 4092 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_08bit_fits.miffbin0 -> 4138 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_16bit_fits.miffbin0 -> 23151 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_32bit_fits.miffbin0 -> 39285 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_cin.miff6
-rw-r--r--PerlMagick/t/reference/read/input_gray_lsb_08bit_mat.miffbin0 -> 4153 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_lsb_16bit_mat.miff6
-rw-r--r--PerlMagick/t/reference/read/input_gray_lsb_32bit_mat.miff5
-rw-r--r--PerlMagick/t/reference/read/input_gray_lsb_double_V4_mat.miffbin0 -> 2339 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_lsb_double_fits.miffbin0 -> 39285 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_lsb_double_mat.miff6
-rw-r--r--PerlMagick/t/reference/read/input_gray_lsb_float_mat.miff6
-rw-r--r--PerlMagick/t/reference/read/input_gray_msb_08bit_mat.miffbin0 -> 5644 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_msb_16bit_fits.miffbin0 -> 23151 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_msb_32bit_fits.miffbin0 -> 39285 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_msb_64bit_fits.miff14
-rw-r--r--PerlMagick/t/reference/read/input_gray_msb_double_fits.miffbin0 -> 39285 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_msb_float_fits.miffbin0 -> 38433 bytes
-rw-r--r--PerlMagick/t/reference/read/input_gray_rla.miff6
-rw-r--r--PerlMagick/t/reference/read/input_gray_rle.miffbin0 -> 4180 bytes
-rw-r--r--PerlMagick/t/reference/read/input_hrz.miff5
-rw-r--r--PerlMagick/t/reference/read/input_ico.miffbin0 -> 4187 bytes
-rw-r--r--PerlMagick/t/reference/read/input_im1.miffbin0 -> 3328 bytes
-rw-r--r--PerlMagick/t/reference/read/input_im24.miff5
-rw-r--r--PerlMagick/t/reference/read/input_im8.miffbin0 -> 4092 bytes
-rw-r--r--PerlMagick/t/reference/read/input_logical_lsb_08bit_mat.miffbin0 -> 5803 bytes
-rw-r--r--PerlMagick/t/reference/read/input_mac.bmpbin0 -> 51902 bytes
-rw-r--r--PerlMagick/t/reference/read/input_miff.miff8
-rw-r--r--PerlMagick/t/reference/read/input_mtv.miff5
-rw-r--r--PerlMagick/t/reference/read/input_null_DarkOrange.miffbin0 -> 3325 bytes
-rw-r--r--PerlMagick/t/reference/read/input_null_black.miffbin0 -> 3325 bytes
-rw-r--r--PerlMagick/t/reference/read/input_null_white.miffbin0 -> 3325 bytes
-rw-r--r--PerlMagick/t/reference/read/input_p7.miffbin0 -> 4092 bytes
-rw-r--r--PerlMagick/t/reference/read/input_pbm_p1.miffbin0 -> 3328 bytes
-rw-r--r--PerlMagick/t/reference/read/input_pbm_p4.miffbin0 -> 3328 bytes
-rw-r--r--PerlMagick/t/reference/read/input_pcx.miff6
-rw-r--r--PerlMagick/t/reference/read/input_pgm_p2.miffbin0 -> 4092 bytes
-rw-r--r--PerlMagick/t/reference/read/input_pgm_p5.miffbin0 -> 4092 bytes
-rw-r--r--PerlMagick/t/reference/read/input_pict.miff5
-rw-r--r--PerlMagick/t/reference/read/input_ppm_p3.miff5
-rw-r--r--PerlMagick/t/reference/read/input_ppm_p6.miff5
-rw-r--r--PerlMagick/t/reference/read/input_psd.miff5
-rw-r--r--PerlMagick/t/reference/read/input_rgb.miff5
-rw-r--r--PerlMagick/t/reference/read/input_rgb_cin.miff6
-rw-r--r--PerlMagick/t/reference/read/input_rgb_lsb_08bit_mat.miffbin0 -> 9905 bytes
-rw-r--r--PerlMagick/t/reference/read/input_rgb_rla.miff6
-rw-r--r--PerlMagick/t/reference/read/input_rgba.miff5
-rw-r--r--PerlMagick/t/reference/read/input_rle.miff7
-rw-r--r--PerlMagick/t/reference/read/input_sgi.miff5
-rw-r--r--PerlMagick/t/reference/read/input_tga.miff5
-rw-r--r--PerlMagick/t/reference/read/input_tile.miff5
-rw-r--r--PerlMagick/t/reference/read/input_tim.miffbin0 -> 2199 bytes
-rw-r--r--PerlMagick/t/reference/read/input_uyvy.miff5
-rw-r--r--PerlMagick/t/reference/read/input_viff.miffbin0 -> 4092 bytes
-rw-r--r--PerlMagick/t/reference/read/input_wbmp.miffbin0 -> 3328 bytes
-rw-r--r--PerlMagick/t/reference/read/input_xbm.miffbin0 -> 3328 bytes
-rw-r--r--PerlMagick/t/reference/read/input_xc_black.miffbin0 -> 3325 bytes
-rw-r--r--PerlMagick/t/reference/read/input_xpm.miffbin0 -> 4092 bytes
-rw-r--r--PerlMagick/t/reference/read/input_xwd.miff6
-rw-r--r--PerlMagick/t/reference/read/topol_1.miff8
-rw-r--r--PerlMagick/t/reference/read/topol_2.miffbin0 -> 13594 bytes
-rw-r--r--PerlMagick/t/reference/read/topol_3.miff5
-rw-r--r--PerlMagick/t/reference/read/topol_4.miffbin0 -> 1153 bytes
-rw-r--r--PerlMagick/t/reference/read/topol_5.miff5
-rw-r--r--PerlMagick/t/reference/read/topol_7.miffbin0 -> 11165 bytes
-rw-r--r--PerlMagick/t/reference/ttf/annotate.miffbin0 -> 15093 bytes
-rw-r--r--PerlMagick/t/reference/ttf/label.miffbin0 -> 6929 bytes
-rw-r--r--PerlMagick/t/reference/ttf/read.miffbin0 -> 199078 bytes
-rw-r--r--PerlMagick/t/reference/wmf/clock.miffbin0 -> 51810 bytes
-rw-r--r--PerlMagick/t/reference/wmf/fjftest.miffbin0 -> 107242 bytes
-rw-r--r--PerlMagick/t/reference/wmf/ski.miffbin0 -> 22914 bytes
-rw-r--r--PerlMagick/t/reference/wmf/wizard.miffbin0 -> 65662 bytes
-rw-r--r--PerlMagick/t/reference/write/output_p7.miffbin0 -> 4123 bytes
-rw-r--r--PerlMagick/t/setattribute.t240
-rw-r--r--PerlMagick/t/subroutines.pl1300
-rw-r--r--PerlMagick/t/tiff/input_gray_01bit_minwhite.calsbin0 -> 3130 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_01bit_minwhite.tiffbin0 -> 1343 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_04bit.tiffbin0 -> 1878 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_04bit_matte.tiffbin0 -> 3646 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_08bit.tiffbin0 -> 3541 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_08bit_matte.tiffbin0 -> 6866 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_10bit.tiffbin0 -> 4369 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_12bit.tiffbin0 -> 5169 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_14bit.tiffbin0 -> 5979 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_16bit.tiffbin0 -> 6761 bytes
-rw-r--r--PerlMagick/t/tiff/input_gray_32bit.tiffbin0 -> 11817 bytes
-rw-r--r--PerlMagick/t/tiff/input_palette_16.tiffbin0 -> 1978 bytes
-rw-r--r--PerlMagick/t/tiff/input_palette_16_matte.tiffbin0 -> 3702 bytes
-rw-r--r--PerlMagick/t/tiff/input_palette_256.tiffbin0 -> 5082 bytes
-rw-r--r--PerlMagick/t/tiff/input_palette_256_matte.tiffbin0 -> 8364 bytes
-rw-r--r--PerlMagick/t/tiff/input_palette_256_planar_contig.tiffbin0 -> 5082 bytes
-rw-r--r--PerlMagick/t/tiff/input_palette_256_planar_separate.tiffbin0 -> 5082 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_08.tiffbin0 -> 9995 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_08_matte.tiffbin0 -> 13280 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_08_planar.tiffbin0 -> 10027 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_08_stripped.tiffbin0 -> 10027 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_08_tiled32x32.tiffbin0 -> 18812 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_10.tiffbin0 -> 12443 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_12.tiffbin0 -> 14835 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_14.tiffbin0 -> 17281 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_16.tiffbin0 -> 19666 bytes
-rw-r--r--PerlMagick/t/tiff/input_truecolor_32.tiffbin0 -> 34809 bytes
-rw-r--r--PerlMagick/t/tiff/read.t256
-rw-r--r--PerlMagick/t/tiff/write.t132
-rw-r--r--PerlMagick/t/topol_1.mez2
-rw-r--r--PerlMagick/t/topol_1.rasbin0 -> 12806 bytes
-rw-r--r--PerlMagick/t/topol_2.mez2
-rw-r--r--PerlMagick/t/topol_2.palbin0 -> 961 bytes
-rw-r--r--PerlMagick/t/topol_2.rasbin0 -> 13277 bytes
-rw-r--r--PerlMagick/t/topol_3.mez1
-rw-r--r--PerlMagick/t/topol_3.rasbin0 -> 1024 bytes
-rw-r--r--PerlMagick/t/topol_4.mez2
-rw-r--r--PerlMagick/t/topol_4.palbin0 -> 33 bytes
-rw-r--r--PerlMagick/t/topol_4.rasbin0 -> 1024 bytes
-rw-r--r--PerlMagick/t/topol_5.rasbin0 -> 12038 bytes
-rw-r--r--PerlMagick/t/topol_7.mez2
-rw-r--r--PerlMagick/t/topol_7.rasbin0 -> 12806 bytes
-rw-r--r--PerlMagick/t/ttf/input.ttfbin0 -> 22660 bytes
-rw-r--r--PerlMagick/t/ttf/read.t59
-rw-r--r--PerlMagick/t/wmf/clock.wmfbin0 -> 12406 bytes
-rw-r--r--PerlMagick/t/wmf/fjftest.wmfbin0 -> 2038 bytes
-rw-r--r--PerlMagick/t/wmf/read.t36
-rw-r--r--PerlMagick/t/wmf/ski.wmfbin0 -> 19664 bytes
-rw-r--r--PerlMagick/t/wmf/wizard.wmfbin0 -> 14578 bytes
-rw-r--r--PerlMagick/t/write.t278
-rw-r--r--PerlMagick/t/x/congrats.fig18
-rw-r--r--PerlMagick/t/x/congrats.miff11
-rw-r--r--PerlMagick/t/x/read.t67
-rw-r--r--PerlMagick/t/x/write.t47
-rw-r--r--PerlMagick/t/xfig/input.fig69
-rw-r--r--PerlMagick/t/xfig/read.t36
-rw-r--r--PerlMagick/t/zlib/input.miff9
-rw-r--r--PerlMagick/t/zlib/input.miff.gzbin0 -> 8761 bytes
-rw-r--r--PerlMagick/t/zlib/input_gray_lsb_08bit_zip.matbin0 -> 19106 bytes
-rw-r--r--PerlMagick/t/zlib/read.t46
-rw-r--r--PerlMagick/t/zlib/write.t35
-rw-r--r--PerlMagick/typemap1
-rw-r--r--README.txt352
-rw-r--r--TODO.txt54
-rw-r--r--TclMagick/AUTHORS2
-rw-r--r--TclMagick/COPYING1
-rw-r--r--TclMagick/ChangeLog700
-rw-r--r--TclMagick/INSTALL85
-rw-r--r--TclMagick/LICENSE39
-rw-r--r--TclMagick/Makefile.am13
-rw-r--r--TclMagick/Makefile.in820
-rw-r--r--TclMagick/NEWS0
-rw-r--r--TclMagick/README9
-rw-r--r--TclMagick/aclocal.m41043
-rwxr-xr-xTclMagick/configure19760
-rw-r--r--TclMagick/configure.ac120
-rw-r--r--TclMagick/debian/README.Debian24
-rw-r--r--TclMagick/debian/changelog39
-rw-r--r--TclMagick/debian/compat1
-rw-r--r--TclMagick/debian/control15
-rw-r--r--TclMagick/debian/copyright49
-rw-r--r--TclMagick/debian/dirs2
-rw-r--r--TclMagick/debian/docs1
-rwxr-xr-xTclMagick/debian/rules110
-rw-r--r--TclMagick/doc/TclMagick.html4002
-rw-r--r--TclMagick/doc/TkMagick.html70
-rw-r--r--TclMagick/doc/index.html97
-rw-r--r--TclMagick/doc/license.txt39
-rw-r--r--TclMagick/doc/style.css10
-rwxr-xr-xTclMagick/genconf.sh12
-rw-r--r--TclMagick/generic/Makefile.am25
-rw-r--r--TclMagick/generic/Makefile.in694
-rw-r--r--TclMagick/generic/TclMagick.c8179
-rw-r--r--TclMagick/generic/TclMagick.h63
-rw-r--r--TclMagick/generic/TclMagickAppInit.c183
-rw-r--r--TclMagick/generic/TkMagick.c259
-rw-r--r--TclMagick/generic/libttkcommon.c89
-rw-r--r--TclMagick/generic/libttkcommon.h20
-rw-r--r--TclMagick/generic/pkgIndex.tcl1
-rw-r--r--TclMagick/images/clippath.tifbin0 -> 932156 bytes
-rw-r--r--TclMagick/images/map6colors.gifbin0 -> 1217 bytes
-rw-r--r--TclMagick/images/pool.jpgbin0 -> 100534 bytes
-rw-r--r--TclMagick/images/sequence.miffbin0 -> 185750 bytes
-rw-r--r--TclMagick/images/tclmagick-big-diff.bmpbin0 -> 25134 bytes
-rw-r--r--TclMagick/images/tclmagick-small-copy.bmpbin0 -> 25134 bytes
-rw-r--r--TclMagick/images/tclmagick-small-diff.bmpbin0 -> 25134 bytes
-rw-r--r--TclMagick/images/tclmagick-small.bmpbin0 -> 25134 bytes
-rw-r--r--TclMagick/images/tclmagick-small.pngbin0 -> 9438 bytes
-rw-r--r--TclMagick/images/tclmagick.pngbin0 -> 67426 bytes
-rw-r--r--TclMagick/pkgIndex.tcl9
-rw-r--r--TclMagick/tests/test-bmp-compare.tcl129
-rw-r--r--TclMagick/tests/test-draw.tcl265
-rw-r--r--TclMagick/tests/test-pixel.tcl138
-rw-r--r--TclMagick/tests/test-wand.tcl1539
-rw-r--r--TclMagick/tests/tkmagick.tcl40
-rw-r--r--TclMagick/unix/Makefile.in430
-rwxr-xr-xTclMagick/unix/config/config.guess1522
-rwxr-xr-xTclMagick/unix/config/config.sub1771
-rwxr-xr-xTclMagick/unix/config/depcomp688
-rwxr-xr-xTclMagick/unix/config/install-sh527
-rw-r--r--TclMagick/unix/config/ltmain.sh9655
-rwxr-xr-xTclMagick/unix/config/missing376
-rw-r--r--TclMagick/unix/m4/acinclude.m49
-rw-r--r--TclMagick/unix/m4/libtool.m47982
-rw-r--r--TclMagick/unix/m4/ltoptions.m4384
-rw-r--r--TclMagick/unix/m4/ltsugar.m4123
-rw-r--r--TclMagick/unix/m4/ltversion.m423
-rw-r--r--TclMagick/unix/m4/lt~obsolete.m498
-rw-r--r--TclMagick/unix/m4/tcl.m44456
-rw-r--r--TclMagick/win/TclMagick.dsp120
-rw-r--r--TclMagick/win/TclMagick.dsw41
-rw-r--r--TclMagick/win/TkMagick.dsp111
-rw-r--r--acinclude.m4708
-rw-r--r--aclocal.m41294
-rw-r--r--coders/Makefile.am865
-rw-r--r--coders/art.c317
-rw-r--r--coders/avs.c425
-rw-r--r--coders/bmp.c2096
-rw-r--r--coders/cals.c621
-rw-r--r--coders/caption.c245
-rw-r--r--coders/cineon.c1490
-rw-r--r--coders/clipboard.c328
-rw-r--r--coders/cmyk.c892
-rw-r--r--coders/cut.c649
-rw-r--r--coders/dcm.c4949
-rw-r--r--coders/dcraw.c192
-rw-r--r--coders/dib.c1427
-rw-r--r--coders/dps.c598
-rw-r--r--coders/dpx.c4455
-rw-r--r--coders/emf.c482
-rw-r--r--coders/ept.c709
-rw-r--r--coders/fax.c330
-rw-r--r--coders/fits.c838
-rw-r--r--coders/fpx.c1092
-rw-r--r--coders/gif.c1553
-rw-r--r--coders/gradient.c185
-rw-r--r--coders/gray.c670
-rw-r--r--coders/histogram.c341
-rw-r--r--coders/hrz.c244
-rw-r--r--coders/html.c447
-rw-r--r--coders/icon.c456
-rw-r--r--coders/identity.c237
-rw-r--r--coders/info.c219
-rw-r--r--coders/jbig.c524
-rw-r--r--coders/jnx.c499
-rw-r--r--coders/jp2.c1240
-rw-r--r--coders/jpeg.c2722
-rw-r--r--coders/label.c227
-rw-r--r--coders/locale.c1117
-rw-r--r--coders/logo.c5412
-rw-r--r--coders/mac.c256
-rw-r--r--coders/map.c413
-rw-r--r--coders/mat.c1474
-rw-r--r--coders/matte.c201
-rw-r--r--coders/meta.c2425
-rw-r--r--coders/miff.c2748
-rw-r--r--coders/mono.c341
-rw-r--r--coders/mpc.c1366
-rw-r--r--coders/mpeg.c611
-rw-r--r--coders/mpr.c239
-rw-r--r--coders/msl.c4792
-rw-r--r--coders/mtv.c401
-rw-r--r--coders/mvg.c318
-rw-r--r--coders/null.c230
-rw-r--r--coders/otb.c373
-rw-r--r--coders/palm.c1981
-rw-r--r--coders/pcd.c1154
-rw-r--r--coders/pcl.c1199
-rw-r--r--coders/pcx.c1317
-rw-r--r--coders/pdb.c1007
-rw-r--r--coders/pdf.c1737
-rw-r--r--coders/pict.c1960
-rw-r--r--coders/pix.c296
-rw-r--r--coders/plasma.c252
-rw-r--r--coders/png.c9750
-rw-r--r--coders/pnm.c2059
-rw-r--r--coders/preview.c655
-rw-r--r--coders/ps.c1653
-rw-r--r--coders/ps2.c1223
-rw-r--r--coders/ps3.c2057
-rw-r--r--coders/psd.c2052
-rw-r--r--coders/pwp.c306
-rw-r--r--coders/rgb.c826
-rw-r--r--coders/rla.c727
-rw-r--r--coders/rle.c833
-rw-r--r--coders/sct.c349
-rw-r--r--coders/sfw.c431
-rw-r--r--coders/sgi.c1288
-rw-r--r--coders/stegano.c258
-rw-r--r--coders/sun.c1087
-rw-r--r--coders/svg.c4374
-rw-r--r--coders/tga.c1070
-rw-r--r--coders/tiff.c5613
-rw-r--r--coders/tile.c193
-rw-r--r--coders/tim.c468
-rw-r--r--coders/topol.c758
-rw-r--r--coders/ttf.c333
-rw-r--r--coders/txt.c1253
-rw-r--r--coders/uil.c341
-rw-r--r--coders/url.c304
-rw-r--r--coders/uyvy.c366
-rw-r--r--coders/vicar.c463
-rw-r--r--coders/vid.c366
-rw-r--r--coders/viff.c1350
-rw-r--r--coders/wbmp.c412
-rw-r--r--coders/webp.c715
-rw-r--r--coders/wmf.c2805
-rw-r--r--coders/wpg.c1481
-rw-r--r--coders/x.c186
-rw-r--r--coders/xbm.c580
-rw-r--r--coders/xc.c194
-rw-r--r--coders/xcf.c1861
-rw-r--r--coders/xpm.c1068
-rw-r--r--coders/xwd.c913
-rw-r--r--coders/yuv.c746
-rw-r--r--common.shi.in18
-rw-r--r--config/Makefile.am38
-rw-r--r--config/colors.mgk16
-rwxr-xr-xconfig/compile347
-rwxr-xr-xconfig/config.guess1421
-rwxr-xr-xconfig/config.sub1807
-rw-r--r--config/delegates.mgk.in127
-rwxr-xr-xconfig/depcomp791
-rwxr-xr-xconfig/install-sh501
-rw-r--r--config/log.mgk71
-rw-r--r--config/ltmain.sh11147
-rwxr-xr-xconfig/missing215
-rw-r--r--config/modules.mgk17
-rwxr-xr-xconfig/tap-driver.sh651
-rwxr-xr-xconfig/test-driver148
-rw-r--r--config/type-ghostscript.mgk.in401
-rw-r--r--config/type-solaris.mgk.in205
-rw-r--r--config/type-windows.mgk.in745
-rw-r--r--config/type.mgk.in4
-rwxr-xr-xconfigure32656
-rwxr-xr-xconfigure.ac3642
-rw-r--r--filters/Makefile.am32
-rw-r--r--filters/analyze.c164
-rwxr-xr-xlndir.sh97
-rw-r--r--locale/C.mgk1830
-rw-r--r--locale/Makefile39
-rw-r--r--locale/README.txt20
-rw-r--r--locale/locale.mgk69
-rw-r--r--m4/acx_pthread.m4305
-rw-r--r--m4/libtool.m48369
-rw-r--r--m4/ltoptions.m4437
-rw-r--r--m4/ltsugar.m4124
-rw-r--r--m4/ltversion.m423
-rw-r--r--magick/GraphicsMagick-config.171
-rw-r--r--magick/GraphicsMagick-config.in51
-rw-r--r--magick/GraphicsMagick.pc.in11
-rw-r--r--magick/Makefile.am332
-rw-r--r--magick/PreRvIcccm.c342
-rw-r--r--magick/PreRvIcccm.h127
-rw-r--r--magick/alpha_composite.h171
-rw-r--r--magick/analyze.c1010
-rw-r--r--magick/analyze.h66
-rw-r--r--magick/animate.c2580
-rw-r--r--magick/animate.h165
-rw-r--r--magick/annotate.c1923
-rw-r--r--magick/api.h125
-rw-r--r--magick/attribute.c3041
-rw-r--r--magick/attribute.h77
-rw-r--r--magick/average.c241
-rw-r--r--magick/average.h40
-rw-r--r--magick/bit_stream.c275
-rw-r--r--magick/bit_stream.h127
-rw-r--r--magick/blob.c5407
-rw-r--r--magick/blob.h570
-rw-r--r--magick/cdl.c252
-rw-r--r--magick/cdl.h32
-rw-r--r--magick/channel.c934
-rw-r--r--magick/channel.h52
-rw-r--r--magick/color.c966
-rw-r--r--magick/color.h103
-rw-r--r--magick/color_lookup.c1698
-rw-r--r--magick/color_lookup.h96
-rw-r--r--magick/colormap.c547
-rw-r--r--magick/colormap.h57
-rw-r--r--magick/colorspace.c2028
-rw-r--r--magick/colorspace.h129
-rw-r--r--magick/command.c17456
-rw-r--r--magick/command.h73
-rw-r--r--magick/common.h281
-rw-r--r--magick/compare.c1029
-rw-r--r--magick/compare.h108
-rw-r--r--magick/composite.c3805
-rw-r--r--magick/composite.h61
-rw-r--r--magick/compress.c1346
-rw-r--r--magick/compress.h83
-rw-r--r--magick/confirm_access.c111
-rw-r--r--magick/confirm_access.h53
-rw-r--r--magick/constitute.c2464
-rw-r--r--magick/constitute.h216
-rw-r--r--magick/decorate.c624
-rw-r--r--magick/decorate.h37
-rw-r--r--magick/delegate.c1622
-rw-r--r--magick/delegate.h136
-rw-r--r--magick/deprecate.c484
-rw-r--r--magick/deprecate.h95
-rw-r--r--magick/describe.c907
-rw-r--r--magick/describe.h40
-rw-r--r--magick/display.c13887
-rw-r--r--magick/display.h1562
-rw-r--r--magick/draw.c5873
-rw-r--r--magick/draw.h262
-rw-r--r--magick/effect.c4692
-rw-r--r--magick/effect.h73
-rw-r--r--magick/enhance.c1456
-rw-r--r--magick/enhance.h41
-rw-r--r--magick/enum_strings.c1756
-rw-r--r--magick/enum_strings.h85
-rw-r--r--magick/error.c954
-rw-r--r--magick/error.h481
-rw-r--r--magick/export.c3333
-rw-r--r--magick/floats.c966
-rw-r--r--magick/floats.h44
-rw-r--r--magick/forward.h46
-rw-r--r--magick/fx.c1788
-rw-r--r--magick/fx.h45
-rw-r--r--magick/gem.c1006
-rw-r--r--magick/gem.h65
-rw-r--r--magick/gradient.c142
-rw-r--r--magick/gradient.h39
-rw-r--r--magick/hclut.c273
-rw-r--r--magick/hclut.h33
-rw-r--r--magick/image.c3480
-rw-r--r--magick/image.h1090
-rw-r--r--magick/import.c3740
-rw-r--r--magick/list.c946
-rw-r--r--magick/list.h60
-rw-r--r--magick/locale.c343
-rw-r--r--magick/locale_c.h1800
-rw-r--r--magick/log.c1243
-rw-r--r--magick/log.h121
-rw-r--r--magick/magic.c381
-rw-r--r--magick/magic.h48
-rw-r--r--magick/magick.c1783
-rw-r--r--magick/magick.h161
-rw-r--r--magick/magick_config.h.in682
-rw-r--r--magick/magick_config_api.h.in20
-rw-r--r--magick/magick_endian.c209
-rw-r--r--magick/magick_endian.h30
-rw-r--r--magick/magick_types.h133
-rw-r--r--magick/magick_types.h.in133
-rw-r--r--magick/map.c1180
-rw-r--r--magick/map.h179
-rw-r--r--magick/memory.c553
-rw-r--r--magick/memory.h115
-rw-r--r--magick/module.c2283
-rw-r--r--magick/module.h84
-rw-r--r--magick/monitor.c196
-rw-r--r--magick/monitor.h55
-rw-r--r--magick/montage.c792
-rw-r--r--magick/montage.h40
-rw-r--r--magick/nt_base.c2681
-rw-r--r--magick/nt_base.h468
-rw-r--r--magick/nt_feature.c696
-rw-r--r--magick/nt_feature.h52
-rw-r--r--magick/omp_data_view.c212
-rw-r--r--magick/omp_data_view.h76
-rw-r--r--magick/operator.c2444
-rw-r--r--magick/operator.h84
-rw-r--r--magick/paint.c815
-rw-r--r--magick/paint.h43
-rw-r--r--magick/pixel_cache.c4788
-rw-r--r--magick/pixel_cache.h391
-rw-r--r--magick/pixel_iterator.c1320
-rw-r--r--magick/pixel_iterator.h289
-rw-r--r--magick/plasma.c222
-rw-r--r--magick/plasma.h40
-rw-r--r--magick/prefetch.h70
-rw-r--r--magick/profile.c1264
-rw-r--r--magick/profile.h90
-rw-r--r--magick/quantize.c2776
-rw-r--r--magick/quantize.h81
-rw-r--r--magick/random-private.h78
-rw-r--r--magick/random.c231
-rw-r--r--magick/random.h76
-rw-r--r--magick/registry.c514
-rw-r--r--magick/registry.h66
-rw-r--r--magick/render.c6152
-rw-r--r--magick/render.h363
-rw-r--r--magick/resize.c2072
-rw-r--r--magick/resize.h47
-rw-r--r--magick/resource.c940
-rw-r--r--magick/resource.h64
-rw-r--r--magick/segment.c1794
-rw-r--r--magick/semaphore.c651
-rw-r--r--magick/semaphore.h55
-rw-r--r--magick/shear.c1874
-rw-r--r--magick/shear.h37
-rw-r--r--magick/signature.c514
-rw-r--r--magick/signature.h64
-rw-r--r--magick/spinlock.h95
-rw-r--r--magick/static.c429
-rw-r--r--magick/static.h316
-rw-r--r--magick/statistics.c295
-rw-r--r--magick/statistics.h63
-rw-r--r--magick/studio.h509
-rw-r--r--magick/symbols.h1121
-rw-r--r--magick/tempfile.c565
-rw-r--r--magick/tempfile.h87
-rw-r--r--magick/texture.c348
-rw-r--r--magick/texture.h44
-rw-r--r--magick/timer.c439
-rw-r--r--magick/timer.h79
-rw-r--r--magick/transform.c1675
-rw-r--r--magick/transform.h46
-rw-r--r--magick/tsd.c154
-rw-r--r--magick/tsd.h41
-rw-r--r--magick/type.c916
-rw-r--r--magick/type.h117
-rw-r--r--magick/unix_port.c169
-rw-r--r--magick/unix_port.h63
-rw-r--r--magick/utility.c6383
-rw-r--r--magick/utility.h201
-rw-r--r--magick/version.c113
-rw-r--r--magick/version.h86
-rw-r--r--magick/version.h.in86
-rw-r--r--magick/widget.c9462
-rw-r--r--magick/widget.h102
-rw-r--r--magick/xwindow.c9642
-rw-r--r--magick/xwindow.h646
-rwxr-xr-xmkinstalldirs150
-rwxr-xr-xrungm.sh.in37
-rwxr-xr-xscripts/changelog2rst.sh4
-rw-r--r--scripts/docutils_htmldeco_writer.py70
-rwxr-xr-xscripts/format_c_api_doc.py603
-rwxr-xr-xscripts/format_c_api_docs.py128
-rw-r--r--scripts/html_fragments.py85
-rwxr-xr-xscripts/make_www.py94
-rwxr-xr-xscripts/named_colors.py416
-rwxr-xr-xscripts/omp_decimal_align.py19
-rwxr-xr-xscripts/pkginfo.sh32
-rwxr-xr-xscripts/relpath.py64
-rwxr-xr-xscripts/rst2htmldeco.py229
-rwxr-xr-xscripts/rst_pagelist.txt27
-rwxr-xr-xscripts/tap-driver.sh651
-rw-r--r--scripts/tap-functions.shi115
-rwxr-xr-xscripts/whatis.txt55
-rw-r--r--scripts/xsnap603
-rw-r--r--tests/Makefile.am69
-rw-r--r--tests/bitstream.c201
-rwxr-xr-xtests/common.shi5
-rw-r--r--tests/constitute.c334
-rwxr-xr-xtests/constitute.tap26
-rw-r--r--tests/drawtest.c406
-rwxr-xr-xtests/drawtests.tap9
-rw-r--r--tests/input_bilevel.miffbin0 -> 10050 bytes
-rw-r--r--tests/input_gray.miffbin0 -> 12342 bytes
-rw-r--r--tests/input_pallette.miffbin0 -> 12387 bytes
-rw-r--r--tests/input_truecolor.miff16
-rw-r--r--tests/input_truecolor10.dpxbin0 -> 19960 bytes
-rw-r--r--tests/input_truecolor12.dpxbin0 -> 22368 bytes
-rw-r--r--tests/input_truecolor16.dpxbin0 -> 26926 bytes
-rw-r--r--tests/input_truecolor_70x46.miff5
-rw-r--r--tests/maptest.c129
-rw-r--r--tests/rwblob.c527
-rwxr-xr-xtests/rwblob.tap319
-rwxr-xr-xtests/rwblob_sized.tap70
-rw-r--r--tests/rwfile.c630
-rwxr-xr-xtests/rwfile.tap482
-rwxr-xr-xtests/rwfile_deep.tap100
-rwxr-xr-xtests/rwfile_miff.tap33
-rwxr-xr-xtests/rwfile_pdf.tap27
-rwxr-xr-xtests/rwfile_sized.tap111
-rw-r--r--utilities/Makefile.am81
-rw-r--r--utilities/gm.110474
-rw-r--r--utilities/gm.c62
-rw-r--r--utilities/miff.4271
-rw-r--r--utilities/quantize.5236
-rw-r--r--utilities/tests/BetaRGB.iccbin0 -> 592 bytes
-rw-r--r--utilities/tests/common.sh16
-rwxr-xr-xutilities/tests/effects.tap270
-rwxr-xr-xutilities/tests/hald-clut.tap33
-rwxr-xr-xutilities/tests/help.tap29
-rwxr-xr-xutilities/tests/icc-transform.tap21
-rwxr-xr-xutilities/tests/identify.tap11
-rwxr-xr-xutilities/tests/list.tap21
-rwxr-xr-xutilities/tests/montage.tap18
-rwxr-xr-xutilities/tests/msl_composite.tap155
-rwxr-xr-xutilities/tests/pipe.tap37
-rwxr-xr-xutilities/tests/preview.tap22
-rw-r--r--utilities/tests/sunrise.jpgbin0 -> 37070 bytes
-rw-r--r--utilities/tests/sunrise.miffbin0 -> 200776 bytes
-rwxr-xr-xversion.sh106
-rw-r--r--wand/GraphicsMagickWand-config.171
-rw-r--r--wand/GraphicsMagickWand-config.in51
-rw-r--r--wand/GraphicsMagickWand.pc.in12
-rw-r--r--wand/Makefile.am82
-rw-r--r--wand/common.shi7
-rw-r--r--wand/drawing_wand.c5557
-rw-r--r--wand/drawing_wand.h416
-rw-r--r--wand/drawtest.c444
-rw-r--r--wand/input_256c.miffbin0 -> 4120 bytes
-rw-r--r--wand/input_bilevel.miffbin0 -> 3328 bytes
-rw-r--r--wand/input_gray.miffbin0 -> 4092 bytes
-rw-r--r--wand/input_truecolor.miff5
-rw-r--r--wand/magick_compat.c714
-rw-r--r--wand/magick_wand.c10954
-rw-r--r--wand/magick_wand.h383
-rw-r--r--wand/pixel_wand.c1608
-rw-r--r--wand/pixel_wand.h91
-rw-r--r--wand/sequence.miffbin0 -> 185750 bytes
-rw-r--r--wand/wand_api.h56
-rw-r--r--wand/wand_private.h47
-rw-r--r--wand/wand_symbols.h415
-rw-r--r--wand/wandtest.c267
-rwxr-xr-xwand/wandtests.tap11
-rwxr-xr-xwinpath.sh70
-rw-r--r--www/ChangeLog-2001.html440
-rw-r--r--www/ChangeLog-2001.rst290
-rw-r--r--www/ChangeLog-2002.html1753
-rw-r--r--www/ChangeLog-2002.rst1417
-rw-r--r--www/ChangeLog-2003.html4764
-rw-r--r--www/ChangeLog-2003.rst4901
-rw-r--r--www/ChangeLog-2004.html1608
-rw-r--r--www/ChangeLog-2004.rst1491
-rw-r--r--www/ChangeLog-2005.html1064
-rw-r--r--www/ChangeLog-2005.rst914
-rw-r--r--www/ChangeLog-2006.html279
-rw-r--r--www/ChangeLog-2006.rst189
-rw-r--r--www/ChangeLog-2007.html1079
-rw-r--r--www/ChangeLog-2007.rst973
-rw-r--r--www/ChangeLog-2008.html2329
-rw-r--r--www/ChangeLog-2008.rst2127
-rw-r--r--www/ChangeLog-2009.html1929
-rw-r--r--www/ChangeLog-2009.rst1711
-rw-r--r--www/ChangeLog-2010.html808
-rw-r--r--www/ChangeLog-2010.rst668
-rw-r--r--www/ChangeLog-2011.html731
-rw-r--r--www/ChangeLog-2011.rst607
-rw-r--r--www/ChangeLog-2012.html1058
-rw-r--r--www/ChangeLog-2012.rst868
-rw-r--r--www/ChangeLog-2013.html641
-rw-r--r--www/ChangeLog-2013.rst530
-rw-r--r--www/ChangeLog-2014.html1031
-rw-r--r--www/ChangeLog-2014.rst895
-rw-r--r--www/ChangeLog-2015.html2043
-rw-r--r--www/ChangeLog-2015.rst2066
-rw-r--r--www/ChangeLog-2016.html1061
-rw-r--r--www/ChangeLog-2016.rst911
-rw-r--r--www/Changelog.html341
-rw-r--r--www/Changelog.rst252
-rw-r--r--www/Changes.html69
-rw-r--r--www/Changes.rst86
-rw-r--r--www/Copyright.html266
-rw-r--r--www/FAQ.html799
-rw-r--r--www/FAQ.rst776
-rw-r--r--www/GraphicsMagick.html6371
-rw-r--r--www/Hg.html288
-rw-r--r--www/Hg.rst268
-rw-r--r--www/INSTALL-unix.html1009
-rw-r--r--www/INSTALL-unix.rst984
-rw-r--r--www/INSTALL-windows.html786
-rw-r--r--www/INSTALL-windows.rst771
-rw-r--r--www/ImageMagickObject.html133
-rw-r--r--www/ImageMagickObject.rst130
-rw-r--r--www/Magick++/Blob.html121
-rw-r--r--www/Magick++/Blob.rst93
-rw-r--r--www/Magick++/COPYING22
-rw-r--r--www/Magick++/Cache.fig35
-rw-r--r--www/Magick++/Cache.pngbin0 -> 1838 bytes
-rw-r--r--www/Magick++/ChangeLog.html2336
-rw-r--r--www/Magick++/ChangeLog.rst1886
-rw-r--r--www/Magick++/CoderInfo.html120
-rw-r--r--www/Magick++/CoderInfo.rst89
-rw-r--r--www/Magick++/Color.html384
-rw-r--r--www/Magick++/Color.rst317
-rw-r--r--www/Magick++/Drawable.html1127
-rw-r--r--www/Magick++/Drawable.rst1055
-rw-r--r--www/Magick++/Drawable_example_1.pngbin0 -> 1438 bytes
-rw-r--r--www/Magick++/Enumerations.html1321
-rw-r--r--www/Magick++/Enumerations.rst683
-rw-r--r--www/Magick++/Exception.html300
-rw-r--r--www/Magick++/Exception.rst184
-rw-r--r--www/Magick++/FormatCharacters.html107
-rw-r--r--www/Magick++/FormatCharacters.rst42
-rw-r--r--www/Magick++/Geometry.html427
-rw-r--r--www/Magick++/Geometry.rst240
-rw-r--r--www/Magick++/Image.fig98
-rw-r--r--www/Magick++/Image.html3003
-rw-r--r--www/Magick++/Image.pngbin0 -> 23923 bytes
-rw-r--r--www/Magick++/Image.rst2817
-rw-r--r--www/Magick++/ImageDesign.html55
-rw-r--r--www/Magick++/ImageDesign.rst28
-rw-r--r--www/Magick++/Montage.html208
-rw-r--r--www/Magick++/Montage.rst201
-rw-r--r--www/Magick++/PixelPacket.html138
-rw-r--r--www/Magick++/PixelPacket.rst57
-rw-r--r--www/Magick++/Pixels.html170
-rw-r--r--www/Magick++/Pixels.rst149
-rw-r--r--www/Magick++/README.txt5
-rw-r--r--www/Magick++/STL.html1966
-rw-r--r--www/Magick++/TypeMetric.html95
-rw-r--r--www/Magick++/TypeMetric.rst68
-rw-r--r--www/Magick++/gm-188x120t.pngbin0 -> 3929 bytes
-rw-r--r--www/Magick++/index.html238
-rw-r--r--www/Magick++/index.rst226
-rw-r--r--www/Magick++/montage-sample-framed.jpgbin0 -> 20198 bytes
-rw-r--r--www/Magick++/right_triangle.pngbin0 -> 150 bytes
-rw-r--r--www/Magick++/thumbnail-anatomy-framed.fig40
-rw-r--r--www/Magick++/thumbnail-anatomy-framed.jpgbin0 -> 14968 bytes
-rw-r--r--www/Magick++/thumbnail-anatomy-plain.fig35
-rw-r--r--www/Magick++/thumbnail-anatomy-plain.jpgbin0 -> 12609 bytes
-rw-r--r--www/Magick++/thumbnail-sample-framed.jpgbin0 -> 9315 bytes
-rw-r--r--www/Magick++/thumbnail-sample-plain.jpgbin0 -> 7387 bytes
-rw-r--r--www/Makefile.am326
-rw-r--r--www/NEWS.html3295
-rw-r--r--www/OpenMP.html10115
-rw-r--r--www/OpenMP.rst1490
-rw-r--r--www/README.html382
-rw-r--r--www/animate.html943
-rw-r--r--www/api/Makefile.am144
-rw-r--r--www/api/animate.html109
-rw-r--r--www/api/annotate.html154
-rw-r--r--www/api/api.html286
-rw-r--r--www/api/api.rst305
-rw-r--r--www/api/api_hyperlinks.rst55
-rw-r--r--www/api/attribute.html194
-rw-r--r--www/api/average.html75
-rw-r--r--www/api/blob.html667
-rw-r--r--www/api/cdl.html87
-rw-r--r--www/api/channel.html234
-rw-r--r--www/api/color.html136
-rw-r--r--www/api/colormap.html138
-rw-r--r--www/api/compare.html300
-rw-r--r--www/api/composite.html93
-rw-r--r--www/api/confirm_access.html110
-rw-r--r--www/api/constitute.html355
-rw-r--r--www/api/decorate.html141
-rw-r--r--www/api/deprecate.html338
-rw-r--r--www/api/describe.html76
-rw-r--r--www/api/display.html119
-rw-r--r--www/api/draw.html3223
-rw-r--r--www/api/effect.html920
-rw-r--r--www/api/enhance.html278
-rw-r--r--www/api/error.html421
-rw-r--r--www/api/export.html184
-rw-r--r--www/api/fx.html410
-rw-r--r--www/api/hclut.html88
-rw-r--r--www/api/image.html964
-rw-r--r--www/api/import.html184
-rw-r--r--www/api/list.html547
-rw-r--r--www/api/magick.html435
-rw-r--r--www/api/memory.html273
-rw-r--r--www/api/monitor.html144
-rw-r--r--www/api/montage.html150
-rw-r--r--www/api/operator.html161
-rw-r--r--www/api/paint.html201
-rw-r--r--www/api/pixel_cache.html1045
-rw-r--r--www/api/pixel_iterator.html600
-rw-r--r--www/api/plasma.html78
-rw-r--r--www/api/profile.html320
-rw-r--r--www/api/quantize.html354
-rw-r--r--www/api/registry.html163
-rw-r--r--www/api/render.html215
-rw-r--r--www/api/resize.html238
-rw-r--r--www/api/resource.html201
-rw-r--r--www/api/segment.html99
-rw-r--r--www/api/shear.html193
-rw-r--r--www/api/signature.html169
-rw-r--r--www/api/statistics.html79
-rw-r--r--www/api/texture.html106
-rw-r--r--www/api/transform.html400
-rw-r--r--www/api/types.html2844
-rw-r--r--www/api/types.rst2074
-rw-r--r--www/api/widget.html504
-rw-r--r--www/authors.html203
-rw-r--r--www/authors.rst198
-rw-r--r--www/batch.html276
-rw-r--r--www/benchmark.html259
-rw-r--r--www/benchmarks.html181
-rw-r--r--www/benchmarks.rst149
-rw-r--r--www/bugs.html63
-rw-r--r--www/bugs.rst33
-rw-r--r--www/color.html335
-rw-r--r--www/compare.html419
-rw-r--r--www/composite.html862
-rw-r--r--www/configure-target-setup.pngbin0 -> 34291 bytes
-rw-r--r--www/conjure.html470
-rw-r--r--www/contribute.html121
-rw-r--r--www/contribute.rst110
-rw-r--r--www/convert.html1909
-rw-r--r--www/display.html3677
-rw-r--r--www/docutils-api.css640
-rw-r--r--www/docutils-articles.css678
-rw-r--r--www/download.html103
-rw-r--r--www/download.rst89
-rw-r--r--www/favicon.icobin0 -> 922 bytes
-rw-r--r--www/formats.html1291
-rw-r--r--www/formats.rst815
-rw-r--r--www/gm.html18054
-rw-r--r--www/identify.html324
-rw-r--r--www/images/ball.pngbin0 -> 332 bytes
-rw-r--r--www/images/banner_bg.pngbin0 -> 207 bytes
-rw-r--r--www/images/gm-107x76.gifbin0 -> 1458 bytes
-rw-r--r--www/images/gm-107x76.pngbin0 -> 1486 bytes
-rw-r--r--www/images/gm-125x80t.pngbin0 -> 2728 bytes
-rw-r--r--www/images/patterns/bricks.pngbin0 -> 158 bytes
-rw-r--r--www/images/patterns/checkerboard.pngbin0 -> 161 bytes
-rw-r--r--www/images/patterns/circles.pngbin0 -> 222 bytes
-rw-r--r--www/images/patterns/crosshatch.pngbin0 -> 157 bytes
-rw-r--r--www/images/patterns/crosshatch30.pngbin0 -> 168 bytes
-rw-r--r--www/images/patterns/crosshatch45.pngbin0 -> 193 bytes
-rw-r--r--www/images/patterns/fishscales.pngbin0 -> 223 bytes
-rw-r--r--www/images/patterns/granite.pngbin0 -> 2848 bytes
-rw-r--r--www/images/patterns/gray0.pngbin0 -> 89 bytes
-rw-r--r--www/images/patterns/gray10.pngbin0 -> 181 bytes
-rw-r--r--www/images/patterns/gray100.pngbin0 -> 153 bytes
-rw-r--r--www/images/patterns/gray15.pngbin0 -> 189 bytes
-rw-r--r--www/images/patterns/gray20.pngbin0 -> 182 bytes
-rw-r--r--www/images/patterns/gray25.pngbin0 -> 158 bytes
-rw-r--r--www/images/patterns/gray30.pngbin0 -> 198 bytes
-rw-r--r--www/images/patterns/gray35.pngbin0 -> 217 bytes
-rw-r--r--www/images/patterns/gray40.pngbin0 -> 229 bytes
-rw-r--r--www/images/patterns/gray45.pngbin0 -> 202 bytes
-rw-r--r--www/images/patterns/gray5.pngbin0 -> 137 bytes
-rw-r--r--www/images/patterns/gray50.pngbin0 -> 157 bytes
-rw-r--r--www/images/patterns/gray55.pngbin0 -> 202 bytes
-rw-r--r--www/images/patterns/gray60.pngbin0 -> 213 bytes
-rw-r--r--www/images/patterns/gray65.pngbin0 -> 218 bytes
-rw-r--r--www/images/patterns/gray70.pngbin0 -> 211 bytes
-rw-r--r--www/images/patterns/gray75.pngbin0 -> 182 bytes
-rw-r--r--www/images/patterns/gray80.pngbin0 -> 206 bytes
-rw-r--r--www/images/patterns/gray85.pngbin0 -> 197 bytes
-rw-r--r--www/images/patterns/gray90.pngbin0 -> 200 bytes
-rw-r--r--www/images/patterns/gray95.pngbin0 -> 185 bytes
-rw-r--r--www/images/patterns/hexagons.pngbin0 -> 228 bytes
-rw-r--r--www/images/patterns/horizontal.pngbin0 -> 142 bytes
-rw-r--r--www/images/patterns/horizontalsaw.pngbin0 -> 186 bytes
-rw-r--r--www/images/patterns/hs_bdiagonal.pngbin0 -> 179 bytes
-rw-r--r--www/images/patterns/hs_cross.pngbin0 -> 155 bytes
-rw-r--r--www/images/patterns/hs_diagcross.pngbin0 -> 193 bytes
-rw-r--r--www/images/patterns/hs_fdiagonal.pngbin0 -> 189 bytes
-rw-r--r--www/images/patterns/hs_horizontal.pngbin0 -> 145 bytes
-rw-r--r--www/images/patterns/hs_vertical.pngbin0 -> 148 bytes
-rw-r--r--www/images/patterns/left30.pngbin0 -> 167 bytes
-rw-r--r--www/images/patterns/left45.pngbin0 -> 189 bytes
-rw-r--r--www/images/patterns/leftshingle.pngbin0 -> 204 bytes
-rw-r--r--www/images/patterns/octagons.pngbin0 -> 219 bytes
-rw-r--r--www/images/patterns/right30.pngbin0 -> 170 bytes
-rw-r--r--www/images/patterns/right45.pngbin0 -> 179 bytes
-rw-r--r--www/images/patterns/rightshingle.pngbin0 -> 217 bytes
-rw-r--r--www/images/patterns/rose.pngbin0 -> 6799 bytes
-rw-r--r--www/images/patterns/smallfishscales.pngbin0 -> 190 bytes
-rw-r--r--www/images/patterns/vertical.pngbin0 -> 143 bytes
-rw-r--r--www/images/patterns/verticalbricks.pngbin0 -> 177 bytes
-rw-r--r--www/images/patterns/verticalleftshingle.pngbin0 -> 235 bytes
-rw-r--r--www/images/patterns/verticalrightshingle.pngbin0 -> 232 bytes
-rw-r--r--www/images/patterns/verticalsaw.pngbin0 -> 194 bytes
-rw-r--r--www/images/right_triangle.pngbin0 -> 177 bytes
-rw-r--r--www/images/right_triangle_option.pngbin0 -> 177 bytes
-rw-r--r--www/import.html671
-rw-r--r--www/index.html144
-rw-r--r--www/index.rst171
-rw-r--r--www/links.html221
-rw-r--r--www/links.rst251
-rw-r--r--www/magick.css176
-rw-r--r--www/miff.html423
-rw-r--r--www/miff.rst359
-rw-r--r--www/mission.html69
-rw-r--r--www/mission.rst47
-rw-r--r--www/mogrify.html1713
-rw-r--r--www/montage.html1167
-rw-r--r--www/motion-picture.html791
-rw-r--r--www/motion-picture.rst643
-rw-r--r--www/perl.html2043
-rw-r--r--www/perl.rst1502
-rw-r--r--www/process.html128
-rw-r--r--www/process.rst102
-rw-r--r--www/programming.html110
-rw-r--r--www/programming.rst73
-rw-r--r--www/project.html61
-rw-r--r--www/project.rst62
-rw-r--r--www/quantize.html251
-rw-r--r--www/quantize.rst244
-rw-r--r--www/reference.html50
-rw-r--r--www/reference.rst29
-rw-r--r--www/security.html141
-rw-r--r--www/security.rst128
-rw-r--r--www/smile.c174
-rw-r--r--www/thanks.html146
-rw-r--r--www/thanks.rst127
-rw-r--r--www/time.html140
-rw-r--r--www/tools.html184
-rw-r--r--www/tools.rst174
-rw-r--r--www/utilities.html103
-rw-r--r--www/utilities.rst70
-rw-r--r--www/version.html170
-rw-r--r--www/wand/Makefile.am57
-rw-r--r--www/wand/drawing_wand.html3245
-rw-r--r--www/wand/magick_wand.html6629
-rw-r--r--www/wand/pixel_wand.html1087
-rw-r--r--www/wand/wand.html140
-rw-r--r--www/wand/wand.rst115
1321 files changed, 738719 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..64271c2
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,252 @@
+2017-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Make sure is up to date.
+
+ * www/index.rst: Update for 1.3.26 release.
+
+ * version.sh: Update library versioning for 1.3.26 release.
+
+ * magick/command.c (BatchCommand): Add ferror() checks around
+ batch input loop.
+
+2017-07-03 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Reject a PNG file if the file size is too small
+ (less than 61 bytes). Reject a JNG file if it is too small (less
+ than 147 bytes).
+ * coders/jpeg.c: Reject a JPEG file if the file size is too small
+ (less than 107 bytes).
+
+2017-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): Compute required file size and
+ verify that sufficient data exists in file before allocating
+ memory to decode the image data. Resolves problem with DPX file
+ with valid header (but a huge claimed image width) provided
+ provided via email on Thu, 29 Jun 2017 by LCatro. This issue has
+ been assigned CVE-2017-10799.
+
+2016-07-02 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Check whether reported object size overflows file size.
+
+2016-07-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Safety check for forged and or corrupted data.
+ This issue has been assigned CVE-2017-10800.
+
+2017-07-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c ("QuantumTransferMode"): Use a generalized method
+ to enforce that buffer overflow can not happen while importing
+ pixels. Resolves problem with RGB TIFF claiming only one sample
+ per pixel provided via email on Thu, 29 Jun 2017 by LCatro. This
+ issue has been assigned CVE-2017-10794.
+
+2017-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Convert bare 'unsigned int' to MagickPassFail
+ where suitable to make intentions clear. Convert True/False to
+ MagickTrue/MagickFalse or MagickPass/MagickFail according to
+ purpose. This is a continuation of a gradual migration and does
+ not represent an API change.
+
+2017-06-25 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Avoid NULL dereference when MAGN chunk processing
+ fails (https://sourceforge.net/p/graphicsmagick/bugs/426/). Expand
+ TABs.
+
+2017-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Update NEWS with changes since the previous release.
+
+ * www/programming.rst: Switch the Lua link to
+ https://github.com/arcapos/luagraphicsmagick, which is a more
+ complete and direct interface from Lua to GraphicsMagick's Wand
+ API.
+
+2017-06-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/gm-foo-dll.iss: Remove PerlMagick from
+ the slim Inno Setup installer builder and remove mention of
+ PerlMagick from the installer documentation.
+
+ * TclMagick/generic/TclMagick.c (magickCmd): Resolve SourceForge
+ patch #51 "TclMagick: memory access error; possible segfault".
+ (newMagickObj): Fix formatting of pointer value so it is 64-bit
+ safe. Resolves SourceForge patch #50 "TclMagick: 64-bit
+ portability issue".
+
+ * coders/pict.c (ReadPICTImage): Avoid possible use of negative
+ value when indexing array, which would cause buffer overflow.
+ Resolves SourceForge issue #427 "One possible buffer overflow
+ vulnerability in
+ GraphicsMagick-1.3.25/coders/pict.c:ReadPICTImage()".
+
+2017-06-22 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Stop memory leak when reading invalid JNG image.
+ Fixes CVE-2017-8350.
+
+2017-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c: Fix lcms2.h inclusion logic.
+
+ * wand/magick_wand.c (MagickSetImageOrientation): Eliminate use of
+ snprintf, which is not supported by older Visual Studio.
+
+2017-06-09 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Accept exIf chunks whose data segment
+ erroneously begins with "Exif\0\0".
+
+2017-06-01 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Removed experimental zxIF chunk support. That
+ proposal is dead.
+
+2017-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * config/log.mgk: Added documentation suggested by SourceForge
+ issue #419 "Consider a small patch to log.mgk".
+
+ * www/Changes.rst: Add missing link to most recent changes.
+
+2017-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Magick++/Image.rst: Improve documentation for Magick++
+ Image::iccColorProfile() and Image::renderingIntent().
+
+2017-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tiff: Update to libtiff 4.0.8.
+
+2017-03-19 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Quieted a new Coverity complaint about a potential
+ text buffer overrun.
+
+2017-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageInfo): Ignore empty magic prefix
+ specification and do not remove colon character from start of
+ filename. Resolves SourceForge bug #415 "Inconsistent Behavior w/
+ input_file Parameter".
+
+2017-03-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Added new private orNT PNG chunk, to
+ preserve image->orientation when it is defined and not
+ the default TopLeft.
+ * coders/jpeg.c: Mention image->orientation in the log when
+ writing a JPEG.
+
+2017-03-15 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOnePNGImage): Add version info about
+ gm, libpng, zlib, and lcms to the PNG debug log.
+
+2017-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ImportImageCommand): Fix handling of -frame
+ options. Option handling was incorrect due to option checking the
+ frame option after it had been freed. Checking the frame dash
+ option before freeing the argument solves the problem. From patch
+ provided by Victor Ananjevsky as SourceForge patch #49 "-frame
+ doesn't work in gm import".
+
+ * Magick++/lib/Image.cpp (attribute): Added Image attribute method
+ which accepts a 'char *' argument, and will remove the attribute
+ if the value argument is NULL. From patch provided by "Gints" as
+ SourceForge patch #46 "C++ api - method to clear/remove
+ attribute".
+
+ * VisualMagick/configure/configure.cpp (InitInstance): Applied
+ patch by Paul McConkey to allow the quantum command line argument
+ to set the default value in the wizard drop list. This allows
+ setting the quantum depth when the /nowizard argument was
+ supplied. Resolves SourceForge patch #48 "When running from the
+ command line configure.exe does not use the quantum argument".
+ The provided configure.exe still needs to be rebuilt to
+ incorporate this change.
+
+ * magick/command.c (MogrifyImage): The -orient command now also
+ updates the orientation in the EXIF profile, if it exists.
+
+ * Magick++/lib/Image.cpp (orientation): Update orientation in EXIF
+ profile, if it exists.
+
+2017-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c: Support PGX JPEG 2000 format for reading and
+ writing (within the bounds of what JasPer supports).
+
+2017-02-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (QuantumTransferMode): Fix out of bounds read when
+ reading CMYKA TIFF which claims to have only 2 samples per pixel.
+ Problem was reported via email on February 15, 2017 by Valon
+ Chu. This issue was assigned CVE-2017-6335.
+
+2017-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc (-geometry): Geometry documentation changes
+ suggested by Jon Wong.
+
+2017-01-26 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Added support for a proposed new PNG chunk
+ (zxIf, read-only) that is currently being discussed on the
+ png-mng-misc at lists.sourceforge.net mailing list. Enable
+ exIf and zxIf with CPPFLAGS="-DexIf_SUPPORTED -DxzIf_SUPPORTED".
+ If exIf is enabled, only the uncompressed exIF chunk will be
+ written and the hex-encoded zTXt chunk containing the raw Exif
+ profile won't be written.
+
+2017-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/msl.c (MSLStartElement): Change test for NULL image
+ pointer to before it is used rather than after it is used.
+ Problem reported by Petr Gajdos on 2017-01-25.
+
+2017-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * TclMagick/unix/m4/tcl.m4: Update tcl.m4 to TEA 3.10. File
+ supplied by Massimo Manghi.
+
+2017-01-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Added support for a proposed new PNG
+ chunk (exIf read-write, eXIf read-only) that is currently
+ being discussed on the png-mng-misc at lists.sourceforge.net
+ mailing list.
+
+2017-01-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Added read_user_chunk_callback() function
+ and used it to implement a private PNG caNv (canvas) chunk
+ for remembering the original dimensions and offsets when an
+ image is cropped. Previously we used the oFFs chunk for this
+ purpose, but this had potential conflicts with other applications
+ that also use the oFFs chunk.
+
+2017-01-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * TclMagick/Makefile.am (AM_DISTCHECK_CONFIGURE_FLAGS): Applied
+ patch by Massimo Manghi to set AM_DISTCHECK_CONFIGURE_FLAGS so
+ that 'make distcheck' remembers configuration options, and also to
+ uninstall pkgIndex.tcl.
+
+ * magick/image.c (SetImageEx): Use PixelIterateMonoSet() for
+ possibly improved efficiency.
+
+ * magick/pixel_iterator.c (PixelIterateMonoSet): New pixel
+ iterator intended for use when initializing image pixels, without
+ regard to existing values.
+
+2017-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Copyright.txt: Bump copyright years and rotate ChangeLog.
+
+
diff --git a/ChangeLog.2001 b/ChangeLog.2001
new file mode 100644
index 0000000..afb7757
--- /dev/null
+++ b/ChangeLog.2001
@@ -0,0 +1,290 @@
+2001-12-28 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Even more features and options were added to conjure
+ * Added CropBox support to PDF writer
+
+2001-12-26 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Conjure now supports having a list of files for the script to
+ process being passed on the command line.
+ * More features and options were added to conjure
+
+2001-12-25 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Made a huge number of improvements to conjure. It now supports
+ over 15 different commands for manipulating your images.
+
+2001-12-24 Cristy <cristy@mystic.es.dupont.com>
+
+ * Started a new scripting language utility, conjure.
+
+2001-12-20 Cristy <cristy@mystic.es.dupont.com>
+
+ * Display the search path in the event a utility cannot find a
+ particular configuration file (thanks to billr@corbis.com)
+
+2001-12-14 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Fixed some bugs in the new composite operators.
+
+2001-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added native BLOB support to coders/wmf.c.
+
+2001-12-13 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Added new composite operators to support PSD/XCF
+ layer compositing: NoCompositeOp, DarkenCompositeOp,
+ LightenCompositeOp, HueCompositeOp, SaturateCompositeOp,
+ ValueCompositeOp, ColorizeCompositeOp, LuminizeCompositeOp,
+ ScreenCompositeOp, OverlayCompositeOp.
+ * Modified the PSD coder to set the appropriate composite
+ operator.
+ * Modified the XCF coder to set the appropriate composite
+ operator.
+
+2001-12-10 Cristy <cristy@mystic.es.dupont.com>
+
+ * Removed the flatten option from ImageInfo.
+ * Added new compose member to ImageInfo that defines which of
+ the composite operators to use when flattening an image.
+
+2001-12-09 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Added new member to ImageInfo, flatten, used by PSD and XCF
+ to determine whether to flatten an image when read.
+ * PSD and XCF now respect image_info->flatten.
+ * Fixed bug in XCF loader when loading layered image as layers.
+ * Modified the convert program to set image_info->flatten if
+ -flatten is specified; we still call FlattenImages for other
+ formats that don't respect image_info->flatten.
+ * Modified Magick++'s Image class to support image_info->flatten.
+
+2001-12-08 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Improvements to the Photoshop (PSD) coder: 1) added support
+ for Duotone images loaded as grayscale as per PSD docs; and 2)
+ added option to composite layers when reading respects layer
+ visibility setting.
+
+2001-12-07 Cristy <cristy@mystic.es.dupont.com>
+
+ * -dissolve wasn't working for the composite program (thanks to
+ Rick Manbry).
+ * DCM coder failed to read a valid DCM image file.
+
+2001-12-06 Cristy <cristy@mystic.es.dupont.com>
+
+ * Stream buffer was not being freed in ReadStream().
+
+2001-12-05 Cristy <cristy@mystic.es.dupont.com>
+
+ * Corrected bias when downsizing an image with ResizeImage().
+
+2001-11-25 Cristy <cristy@mystic.es.dupont.com>
+
+ * AcquireImagePixels() can accept (x,y) outside the image area
+ (e.g. AcquireImagePixels(image,-3,-3,7,7,exception)).
+
+2001-11-22 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added limited SVG gradient support.
+
+2001-11-21 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added API method, PingBlob().
+
+2001-11-14 Cristy <cristy@mystic.es.dupont.com>
+
+ * Moved a few pixel related defines (e.g. Downscale()) to
+ a corresponding method to enforce strong type checking at
+ compile time.
+
+2001-11-12 Cristy <cristy@mystic.es.dupont.com>
+
+ * Previously ImageMagick did not write 8-bit ASCII PPM/PGM files
+ when QuantumDepth == 16.
+ * Added 'id' as an image attribute in PerlMagick (returns
+ ImageMagick registry ID).
+
+2001-11-10 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added SVG pattern support.
+ * Changed default background color to none.
+
+2001-11-06 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added support of reading and writing 16-bit raw PPM/PGM files.
+
+2001-11-05 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added -level to convert/mogrify (suggested by
+ mericson@phillynews.kom).
+
+2001-11-04 Cristy <cristy@mystic.es.dupont.com>
+
+ * -shadow/-shade were not distiguished.
+
+2001-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Makefile.PL.in: Install PerlMagick using
+ ImageMagick's configure prefix.
+
+2001-11-02 Cristy <cristy@mystic.es.dupont.com>
+
+ * Typecast offset to unsigned long in coders/pdf.c.
+
+2001-11-01 Cristy <cristy@mystic.es.dupont.com>
+
+ * Convert's -flatten, -average, etc. failed with an assert error.
+
+2001-10-30 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added support for On-the-air bitmap.
+
+2001-09-29 Glenn <randeg@alum.rpi.edu>
+
+ * When the delay setting for an image is greater than 4cs, duplicate
+ frames are inserted to achieve the desired delay while creating MPEG
+ files (contributed by Lawrence Livermore National Laboratory (LLNL)).
+
+2001-10-29 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick now has a registry for storing image blobs.
+
+2001-10-26 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added VMS patches (thanks to Jouk Jansen).
+
+2001-10-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fixed parsing bug for decorate #FFFFFF.
+
+2001-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added tests for mpeg2 library to configure.
+
+2001-10-22 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added a MPEG coder module.
+ * Added ImageType member to the image_info structure (suggested
+ by Glenn)
+
+2001-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Eliminated libMagick.so dependency on libxml by not listing -lxml
+ when doing modules link.
+
+2001-10-18 Cristy <cristy@mystic.es.dupont.com>
+
+ * Eliminated the libMagick.so dependancy on libtiff by moving
+ Huffman2DEncodeImage() from magick/compress.c to coders/pdf.c,
+ coders/ps2.c and coders/ps3.c (suggested by Bob Friesenhahn).
+ This change has the side-effect of elminating dependency on libpng
+ and libjpeg as well (which libtiff may depend on).
+
+2001-10-16 Cristy <cristy@mystic.es.dupont.com>
+
+ * Convert now supports -channel {Cyan,Magenta,Yellow,Black}.
+
+2001-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c updated for libwmf 0.2. Plenty of bugs remain within.
+
+2001-10-11 Cristy <cristy@mystic.es.dupont.com>
+
+ * QueryFontMetrics() of PerlMagick now recognizes embedded
+ special characters (e.g. %h).
+
+2001-10-10 Cristy <cristy@mystic.es.dupont.com>
+
+ * Fixed seg-fault for PingImage() on a JP2 image file.
+
+2001-10-07 Cristy <cristy@mystic.es.dupont.com>
+
+ * CloneImage() now uses a referenced counted pixel cache.
+
+2001-10-05 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added AcquireImagePixels() method.
+ * Changed the formal parameter from Image * to const Image *
+ for a number of methods (e.g. ZoomImage()).
+ * Added ExceptionInfo parameter to DispatchImage().
+
+2001-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Find libxml headers under Debian Linux (bug ID 921).
+
+2001-10-02 Cristy <cristy@mystic.es.dupont.com>
+
+ * Fixed assertion error on drawing stroked text.
+
+2001-10-01 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added blob test to the PerlMagick test suite.
+
+2001-09-30 Cristy <cristy@mystic.es.dupont.com>
+
+ * switched strcpy to strncpy to help protect against buffer
+ overflow.
+
+ * ltdl.c passed int reference but a long was needed; caused a
+ fault on Solaris 64-bit compiles.
+
+2001-09-25 Cristy <cristy@mystic.es.dupont.com>
+
+ * Removed most lint complaints from the source.
+ * strtod() returns different results on Linux and Solaris for 0x13.
+ * Added a MATLAB encoder contributed by Jaroslav Fojtik.
+
+2001-09-21 Cristy <cristy@mystic.es.dupont.com>
+
+ * Replaced TemporaryFilename() with UniqueImageFilename().
+ * ImageMagick CORE API is now 64-bit clean.
+
+2001-09-20 Cristy <cristy@mystic.es.dupont.com>
+
+ * Fixed svg.c to accept a viewbox with a negative offset.
+
+2001-09-15 Cristy <cristy@mystic.es.dupont.com>
+
+ * Surveying the code for 64-bit compatibility.
+ * The cloned colormap was too small (reported by Glenn).
+ * A blob was being unmapped more than once for multi-frame images.
+
+2001-09-12 Cristy <cristy@mystic.es.dupont.com>
+
+ * Text drawing now handles UTF8-encoding.
+ * Off-by-one GetImagePixels() fix in draw.c
+ * PingImage() now reports attributes for all images in an image
+ sequence.
+
+2001-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h: Rename QuantumLeap define to QuantumDepth.
+ QuantumDepth is set to the values 8 or 16, depending on user
+ configuration option.
+
+2001-09-09 Cristy <cristy@mystic.es.dupont.com>
+
+ * Updated PerlMagick signatures to reflect new message digest
+ algorithm.
+
+2001-09-08 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick defaults to 16-bit quantum. Set QuantumMagick
+ for 8-bit.
+ * Changed image->blob from BlobInfo to BlobInfo* so the Image
+ structure size is not dependent on the large-file preprocessor
+ defines.
+
+2001-09-07 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added -background to convert program usage text.
+ * DispatchImage() now properly handles grayscale images.
+
+2001-09-01 Glenn <randeg@alum.rpi.edu>
+
+ * The compression quality setting is now recognized when creating
+ MPEG images (contributed by Lawrence Livermore National Laboratory
+ (LLNL)).
diff --git a/ChangeLog.2002 b/ChangeLog.2002
new file mode 100644
index 0000000..470fb45
--- /dev/null
+++ b/ChangeLog.2002
@@ -0,0 +1,1417 @@
+2002-12-31 Cristy <cristy@mystic.es.dupont.com>
+
+ * magick/command.c: Do not quantize CMYK (bug fix).
+
+ * magick/render.c: Ensure that stroke is not drawn wider than
+ requested when antialiasing is disabled (bug fix).
+
+2002-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: For TransformRGBImage() and RGBTransformImage()
+ round values to int when creating tables rather than using scaling
+ to avoid rounding.
+
+2002-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c: Fixed compile problems.
+
+ * magick/image.c: SyncImage() performance optimizations.
+
+ * TransformRGBImage() cleanup/enhancements. Some rounding issues
+ remain.
+
+ * RGBTransformImage() cleanup/enhancements. Some rounding issues
+ remain.
+
+2002-12-24 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * BUGFIX: Fixed bug, introduced on 12/18/02, in which a misplaced
+ "}" caused an assertion failure after reading any opaque JNG
+ image.
+
+ * Added CloseBlob before returning a NULL JNG image.
+
+ * Merged png.c with IM-5.5.3-1, including a seemingly pointless
+ rename of SaveImageText string to SaveImageTag.
+
+2002-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: Optimized gray x, y, z, tables creation in
+ RGBTransformImage().
+
+2002-12-27 Cristy <cristy@mystic.es.dupont.com>
+
+ * coders/pcd.c: IsPCDImage() fix offset to test header magic.
+
+ * coders/pcd.c: Ensure that blob is closed on error.
+
+ * coders (all): Pass image->colorspace to TransformRGBImage()
+
+ * magick (animate.c, command.c, display.c, image.c, nt_feature.c)
+ Pass image->colorspace to TransformRGBImage().
+
+ * magick/nt_feature.c: Ensure that image is RGB prior to transfer
+ to HBITMAP.
+
+2002-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: Re-worked TransformRGBImage() again so that it
+ is now smoking fast for Q:8 and Q:16. Changed lookup tables, and
+ all per-pixel transforms to use only integer arithmetic. A
+ pre-multiplication scheme is used which should actually improve
+ the quantization error over using double arithmetic. It is
+ actually possible to improve Q:32 performance a bit more but is it
+ worth the effort?
+
+2002-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: Implemented logging for TransformRGBImage() and
+ RGBTransformImage().
+
+2002-12-24 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * The png codec would close the blob twice (second time raising an
+ assertion) if a libpng error was encountered.
+
+ * Sometimes the PNG writer would receive an invalid bit depth from
+ CompositeImages(); this is now ignored.
+
+2002-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: Re-wrote TransformRGBImage() so that it does not
+ penalize a Q:8 build. The function should be faster now, but no
+ timings have been made to verify that.
+
+2002-12-21 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Elimimated unused transparent_pixel array in png.c.
+
+ * Reverted to incrementing loops in bmp.c where the counter "i" is
+ used in the loop.
+
+2002-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Update MogrifyImage() so that gm is 9X faster
+ when transforming a color image to grayscale.
+
+2002-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated coders to use VerifyColormapIndex macro rather than slow
+ ConstrainColormapIndex() function.
+
+ * magick/constitute.c: Trial use of VerifyColormapIndex in
+ PushImagePixels() IndexQuantum case.
+
+2002-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/color.c: Added VerifyColormapIndex macro to verify range
+ of color index without a function call.
+
+ * coders/bmp.c: Updated to use VerifyColormapIndex macro.
+
+2002-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/bmp.c: Sped up RLE expansion and sped up byte-size
+ PseudoColor scanline conversion. Results in 50% speed-up when
+ running on SPARC.
+
+2002-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities: Removed legacy ImageMagick utilities which have been
+ rolled up into gm.c/command.c.
+
+2002-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: Fixed FormatString() format problems
+ identified by the compiler.
+
+2002-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h: Moved function prototypes for functions
+ implemented in code modules other than image.c to seperate header
+ files with names based on the implementation files.
+
+2002-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/enhance.c: Report appropriate message while leveling
+ image.
+
+2002-12-18 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Sync png.c and fx.c with IM-5.5.3. "gm convert -list format"
+ now includes zlib version info among the PNG info.
+
+ * ConvolveImage() logs kernel info as a "Transform" debug event.
+
+ * ReadJNGImage() now skips decoding JPEG subimage when "pinging"
+
+2002-12-17 Cristy <cristy@mystic.es.dupont.com>
+
+ * SVG element `stroke-dasharray: 0` no longer causes a
+ segmentation fault.
+
+2002-12-17 Cristy <cristy@mystic.es.dupont.com>
+
+ * CoaleseceImage() properly handles a dispose method of
+ BackgroundDispose.
+
+2002-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Updated to substitute for @GMDelegate@.
+
+ * magick/effect.c: Changed AdaptiveThresholdImage offset to double
+ so that it works with QuantumDepth=32. Thanks to Glenn for
+ pointing out this problem.
+
+ * magick/image.c: Adapted to AdaptiveThresholdImage API change.
+
+ * magick/image.h: Annotated global constants and functions with
+ the name of the source file where they are implemented. This is
+ in preparation to break up image.h into multiple header files to
+ diminish unnecessary header dependencies.
+
+ * coders/delegates.mgk.in: Updated to use @GMDelegate@ definition
+ and `gm` program rather than ImageMagick utility names.
+
+ * PerlMagick/t/read.t: Converted gradient test (which was not
+ working at all) to compare with a reference image.
+
+ * PerlMagick/t/jpeg/read.t: Re-wrote to compare with reference
+ image.
+
+ * PerlMagick/t/jpeg/write.t: Re-wrote to compare with reference
+ image.
+
+ * magick/image.c, magick/command.c: Moved MogrifyImage and
+ MogrifyImages from image.c to command.c in order to diminish
+ unnecessary inter-object coupling. Only functions in command.c
+ should use MogrifyImage or MogrifyImages. Some work remains to
+ accomplish that.
+
+2002-12-16 Cristy <cristy@mystic.es.dupont.com>
+
+ * coders/jpeg.c: Add missing break statements to fix colorspace
+ handling when image colorspace is CMYKColorspace or
+ YCbCrColorspace.
+
+ * magick/decorate.c: Cast to double in calculation.
+
+ * magick/enhance.c: Tweaks to equalization map calculation to
+ (hopefully) provide more consistent results.
+
+ * magick/resize.c: Use type double rather than long for minify
+ weighting constants.
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/image.h: AdaptiveThresholdImage offset must be a signed
+ type.
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Re-wrote PerlMagick filter.t tests so that they all compare
+ results with reference images rather than compare signatures.
+ This makes the tests easier to maintain and also makes it easier
+ to find errors in ImageMagick.
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Warnings reduction
+
+ * magick/list.c: Warnings reduction
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated PerlMagick tests for Emboss, Equalize, Gamma, Normalize,
+ OilPaint, and Gradient so that they pass at Q:8 under Windows.
+
+ * Updated PerlMagick tests for Emboss, and reading WMF, so that
+ they pass at Q:16 under Windows.
+
+ * VisualMagick\installer\ImageMagick-16.iss: Ported over from
+ ImageMagick-8.iss and verified.
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Major smashing of ImageMagick to GraphicsMagick in .txt files
+ and .html files.
+
+ * ImageMagick.html: Renamed to index.html.
+
+ * www/ImageMagick.html: Renamed to www/GraphicsMagick.html
+
+2002-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/list.c: Added GetFirstImageInList() function.
+
+ * magick/list.c: Added GetLastImageInList() function.
+
+ * coders/pcd.c: Re-implemented image tile labeling to avoid use of
+ MogrifyImages().
+
+2002-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added `commit` shell script to CVS for those who chose to use
+ it.
+
+2002-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c: Ensure that operating system call error return
+ values are never used in resource limit calculation.
+
+2002-12-12 William Radcliffe <billr@corbis.com>
+
+ * magick/magick.c: Fixed bugs in InitializeMagick, but I also
+ heavily commented the code so show what it seems to be doing. It
+ appears broken and needs testing on all platforms. Toward that
+ end, I added Log events so that we can see what it is doing.
+
+2002-12-12 William Radcliffe <billr@corbis.com>
+
+ * utilities/gm.c: Fixes a crashing bug in gm.c caused by an
+ attempt to free a bad pointer. Added comments to the code that
+ explain why this happens so that future developers don't fall into
+ the same trap. * win2k/IMDisplay/IMDisplay.rc Modified some of
+ the string resources that define supported file formats that were
+ in error. One example was eps with had a *.eps in the string
+ instead of just .eps. This caused the document class to ASSERT
+ under the debug build.
+
+2002-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Enable the module loading code for shared/DLL builds regardless
+ of whether the build is a "modules" build. This allows users to
+ add their own modules without requiring the use of a special
+ "modules" build.
+
+2002-12-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h: Backed out arbitrary name change from
+ ChannelThresholdImage() to ThresholdImageChannel() that snuck in
+ from Cristy's image.h changes.
+
+2002-12-11 Cristy <cristy@mystic.es.dupont.com>
+
+ * coders/psd.c: Reference cloned image Blob (not sure why needed
+ but must be important).
+
+2002-12-11 Cristy <cristy@mystic.es.dupont.com>
+
+ * magick/enhance.c: Fixed LevelImage() to accept percent
+ black/white points (.i.e. 90%).
+
+ * magick/enhance.c: Added LevelImageChannel().
+
+ * magick/enhance.c: Improved Q:8 performance of color
+ transformations (e.g. for Gamma) which are based on a mapping
+ array.
+
+ * coders/pcl.c: Fixed PCL coder to output proper color PCL
+ instructions.
+
+2002-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: Disabled SetImageInfo() code which uses
+ GetImageMagick() to test file magic via Is* methods so that we can
+ learn if eliminating use of these tests causes any ill effects.
+
+2002-12-09 William Radcliffe <billr@corbis.com>
+
+ * Moved xtrn.c from contrib area into coders area so that it can
+ be used from within the COM object. This is windows only code that
+ provides a back door way for the COM object to have data read or
+ written into VB arrays.
+
+2002-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/mac.c: Merged in fixes from ImageMagick version.
+
+ * magick/magick.mgk: Merged in fixes from ImageMagick version.
+
+2002-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: Fix ChannelImage() so that it does not destroy
+ CMYK(A) channels by forcing RGB.
+
+2002-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/version.h: Changed to release 1.0.0.
+
+ * magick/nt_base.c: Changed "ImageMagick" to "GraphicsMagick" so
+ registry lookups work for GraphicsMagick. Probably should be
+ configured via a magick_config.h define.
+
+ * VisualMagick/installer/ImageMagick-8.iss:
+ Changed for GraphicsMagick.
+
+ * utilities/conjure.c: Fix unterminated comment.
+
+2002-12-06 William Radcliffe <billr@corbis.com>
+
+ * coders/jpeg.c: Modification of JPEG APP1 detection logic to name
+ EXIF and XMP profiles as EXIF and XMP instead of APP1. THe current
+ algorithm is brute force.
+
+ * coders/meta.c: Modification deal with EXIF and XMP requests so
+ that you can ask for these blobs specifically if they exist.
+
+ * coders/pdf.c,ps.c,ps2.c,ps3.c: Cristy bug fixes to eliminate
+ redundant file access checking and fix embedded JPEG support.
+
+ * magick/random.c: Upgraded this to match current Cristy code. The
+ upgrade is to support more robust temporary filenames in another
+ change to this in utility.c however, I have not upgraded this code
+ yet because I don't understand it well enough.
+
+2002-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added build support for utilities/gm.c
+
+2002-12-06 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Relocated animate, conjure, display, and import functions into
+ command.c.
+
+ * Added utilities/gm.c; gm is a driver for all of the utility
+ functions (animate, composite, conjure, convert, display,
+ identify, import, mongrify, and montage), which are now run with
+ "gm convert [convert_options]", "gm identify [identify_options]",
+ etc.
+
+2002-12-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c: Remove bogus code for handling temporary file.
+
+2002-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated to Autoconf 2.57.
+
+ * Install libraries as -lGraphicsMagick and -lGraphicsMagick++
+ under Unix.
+
+ * Install headers under ${PREFIX}/include/GraphicsMagick under
+ Unix.
+
+ * Update *-config scripts to produce correct library and include
+ statements.
+
+ * Update PerlMagick to use correct library and include statements.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ * contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp:
+ Fixed serious problem with not installing custom error and warning
+ handlers in the new version of the COM object.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ * magick/constitute.c: Pass exceptions on write up into the
+ exception structure passed into the WriteImages function.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ * magick/image.c: Added orphan image functionality changes that
+ are purported to fix bugs in PDF and PS coders.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ * magick/locale.c: Hard coded the locale as per Cristy fix, but
+ also added a comment and disabled useless code.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ * VisualMagick/bin/magic.mgk: Added JNG as per the copy in magick
+ subdirectory.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ * tiff/libtiff/tiff.h: Minor changes to make reading older
+ Photoshop TIFF files spew fewer warnings.
+
+2002-12-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Optimized ConvolveImage() by normalizing the kernel values
+ instead of normalizing the pixels.
+
+2002-12-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * www/formats.html: Add JNG and fix libpng links.
+
+2002-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ChangeLog: Updated this ChangeLog to use the format prescribed
+ by the GNU coding standards.
+
+2002-12-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/png.c: Use PNG_SETJMP_NOT_THREAD_SAFE to indicate that
+ the C library's setjmp() API is not thread safe.
+
+ * Fix use of image_info->blob.
+
+2002-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Set up new CVS repository for GraphicsMagick based on current
+ ImageMagick 5.5.2 (pre-release) sources.
+
+2002-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Flashpix library now uses C++ standard <new> and iostreams
+ rather than legacy new and iostreams.
+
+2002-11-15 Cristy <cristy@mystic.es.dupont.com>
+
+ * The blob methods were enhanced to use GZip or BZip API methods
+ to compress/uncompress images (previously the external programs
+ gunzip or bunzip2 were used).
+
+2002-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update to Autoconf 2.56
+
+2002-11-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update to Autoconf 2.55
+
+2002-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Moved coder Register/Unregister method prototypes to static.h
+ since they are only needed by static.c.
+
+ * Removed defunct HDF and libmpeg2 support since it was confusing
+ to users.
+
+2002-11-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c: Set white background of embedded bitmaps to
+ transparent if the image background is a texture image, not-white,
+ or non-opaque. This improves the output when the WMF is rendered
+ on a non-default background.
+
+2002-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated Windows CVS to FreeType 2.1.2.
+
+2002-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated Windows CVS to Jasper 1.600.0.
+
+2002-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Verify sanity of sysconf(_SC_PAGE_SIZE) and
+ sysconf(_SC_PHYS_PAGES) before using their values.
+
+2002-11-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Modified IMdisplay so that larger images may be loaded
+ (primarily limited by Windows bitmap size limits).
+
+ * Added some more file types (EPS, GIF, MIFF, SVG, & WMF) to
+ IMdisplay's file open list.
+
+ * The list management methods were given more meaningful names.
+
+2002-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Modified IMdisplay so that Magick++ Images are stored by value
+ rather than via pointer.
+
+ * IMdisplay now uses minify(), magnify(), and zoom() methods where
+ appropriate.
+
+2002-11-04 Cristy <cristy@mystic.es.dupont.com>
+
+ * Quantizing a DirectClass image with less than 256 unique colors
+ is no longer lossy.
+
+ * Transparent TGA images had incorrect opacity values.
+
+2002-10-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added configure test for compiler __func__ support
+ (HAS___func__).
+
+ * Added configure test for ftime().
+
+2002-10-31 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * CMYK + alpha layered PSD files now correctly read!
+
+2002-10-30 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * ReadPSDImage() is now fully instrumented with logging
+
+ * Fixed long standing bug in ReadPSDImage, so it no longer returns
+ an extra layer
+
+2002-10-29 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Added three output formats: PNG24 (24-bit RGB PNG, opaque only),
+ PNG32 32-bit (RGBA PNG, semitransparency OK), and PNG8 (8-bit
+ indexed PNG, binary transparency only).
+
+2002-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/vid.c: Modified to be 10X faster for large images and to
+ take advantage of JPEG size optimizations.
+
+2002-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/xwindow.c: Optimize loading of TrueColor images with
+ gamma = 1.0.
+
+2002-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c: Added logging facilities.
+
+2002-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * display.c: removed unnecessary SignatureImage() calls which
+ dramatically slowed down loading images and quiting the program.
+
+ * xwindow.c: optimized image size reduction for the case where the
+ target size is a small fraction of the original size. This makes
+ creation of display's panner and thumbnail images tremendously
+ faster, with no noticeable degradation of thumbnail quality.
+
+2002-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added Windows95 define to VisualMagick magick_config.h to
+ disable use of features not available under Windows '95
+
+2002-10-21 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added large file pixel cache support for Windows NT.
+
+2002-10-21 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * PDF coder no longer uses ASCII85 encoding with TIFF for MUCH
+ smaller files!
+
+ * Cleaned up a few other things in PDF coder.
+
+2002-10-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated to Automake 1.7.1.
+
+2002-10-18 Cristy <cristy@mystic.es.dupont.com>
+
+ * PingBlob() improperly set the length of BlobInfo to zero.
+
+ * Fixed Ping() memory leak in PerlMagick.
+
+ * Fixed -map problem in convert/mogrify utilities.
+
+ * Fixed -remote problem with display utility (returns correct
+ error status).
+
+2002-10-16 Cristy <cristy@mystic.es.dupont.com>
+
+ * -border with a single value now produces correct results
+ (e.g. -border 10).
+
+ * Added -lat to convert/mogrify (local adaptive thresholding).
+
+2002-10-15 Cristy <cristy@mystic.es.dupont.com>
+
+ * Set locale type LC_NUMERIC to "C".
+
+ * Bug fix for PS2 encoder.
+
+ * Added PS-Adobe preamble to PS3 encoder.
+
+2002-10-14 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick 5.5.1 released.
+
+2002-10-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Use ImageMagick release number to allow multiple ImageMagick
+ releases to co-exist without interference on the same machine.
+
+2002-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Decided that DrawGet functions should return by value.
+
+2002-10-06 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Added detailed logging to BMP, PNG, and JPEG codecs, including
+ JPEG quality estimate.
+
+2002-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added draw.h "DrawGet" equivalents to most of the "DrawSet"
+ functions.
+
+ * Added an array size argument to DrawSetDashPattern and got rid
+ of the zero-termination garbage.
+
+ * Remove `Set` from the names of draw.h functions which update the
+ current affine transformation array (e.g. DrawSetRotate becomes
+ DrawRotate).
+
+2002-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated to Automake 1.7.
+
+2002-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Under Windows, a DllMain function which automatically
+ initializes ImageMagick (when ImageMagick is built using DLLs) may
+ be added by defining ProvideDllMain in magick_config.h
+
+2002-09-28 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added resource consumption methods, see magick/resource.c.
+
+2002-09-27 Cristy <cristy@mystic.es.dupont.com>
+
+ * Replaced underscores in commandline options with hyphens. For
+ backward compatibility, underscores will continue to be
+ recognized.
+
+ * Added -blue-primary, -green-primary, -red-primary, -white-point
+ options.
+
+2002-09-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Added BMP2 and BMP3 output formats.
+
+ * Changed chromaticity primary.z from 1.0 to
+ 1.0-(primary.x+primary.y) in the PNG and PCD codecs.
+
+2002-09-21 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added `exception` parameter to the ImageMagick progress monitor
+ API.
+
+ * Added enumerated types for the dispose member of the Image
+ structure.
+
+ * Added -version option to commandline utilities.
+
+2002-09-21 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * The xcf decoder would sometimes create artifacts when reading
+ RLE-encoded grayscale images, due to the green and blue samples
+ not being defined.
+
+2002-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update to Autoconf 2.54.
+
+2002-08-08 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added logging capabilities to the CORE API. This facility is
+ useful for debugging. Added "events" parameter to the -debug
+ commandline option.
+
+ * AcquireImagePixels() did not always return the same pixel values
+ for virtual pixels when the cache was stored on disk (very rare).
+
+ * new -virtual-pixel command line option.
+
+ * new PerlMagick virtual-pixel image attribute.
+
+2002-08-07 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick 5.4.9 released.
+
+2002-09-06 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Fixed some bugs in the Clipboard coder
+
+ * Added new ImageToHBITMAP function to NTFeature.c/.h in core
+
+ * Added support for Quantum==32 to IMDisplay
+
+2002-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fix formatting in the *.mgk files so that they are XML conformant
+
+2002-08-30 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * QuantizeImage() did not always produce proper bilevel images.
+
+2002-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Apply prefix/suffix transformations to ImageMagick program names
+ which are substituted into delegates.mgk. This fix was requested
+ by Glenn Randers-Pehrson.
+
+2002-08-25 Cristy <cristy@mystic.es.dupont.com>
+
+ * Arcs are now rendered properly.
+
+ * Use -authenticate to specifiy a password when viewing encrypted
+ PDF's.
+
+ * -page was previouly being ignored.
+
+ * Configure files are returned as blobs now (suggested by William
+ Radcliffe).
+
+2002-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added --disable-installed option to configure to support
+ building an ImageMagick which is not installed via hard-coded
+ paths. This is intended to be used for the ad-hoc binary
+ distributions built by ImageMagick Studio.
+
+ * The UseInstalledImageMagick define is to be used by builds
+ formally installed under a prefix, or via the Windows registry.
+
+ * Replaced GetMagickConfigurePath() with the three functions
+ FindConfigurationFile(), FindFontFile(), and FindModuleFile().
+
+ * Re-implemented InitializeMagick() to try harder at finding the
+ uninstalled ImageMagick without the help of MAGICK_HOME. In the
+ future, it can try even harder.
+
+ * Unix binaries packages (built with --disable-installed) should
+ now work using the same file layout as the distribution file.
+ There is no longer a need to put all files in the same directory.
+
+2002-08-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Under Windows, define UseInstalledImageMagick to locate
+ components using the registry rather than scanning the filesystem.
+
+2002-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added DrawSetTextEncoding() function to specify text encoding
+ (e.g. "UTF-8").
+
+2002-08-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Extend `convert -list type` output so it prints more details.
+
+ * Fix draw.c problem when specifying font family names that
+ contain spaces.
+
+2002-08-15 Cristy <cristy@mystic.es.dupont.com>
+
+ * Finished 32-Bit QuantumDepth support.
+
+ * Subimage memory leak fixed (bug report by William Radcliffe).
+
+ * Fixed subimage specification memory overrun.
+
+ * Subimage specification did not work properly under Windows.
+
+2002-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fix problem with TEXT encoder. It was prepending the filename
+ to the text.
+
+2002-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Render Postscript via Ghostscript DLL (gsdll32.dll) under
+ Windows if it can be loaded. Only ps.c currently uses this to
+ verify there are no problems.
+
+2002-08-14 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added 16-bit raw write support to PPM.
+
+2002-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Re-implemented ReadTTFImage() using the draw.h APIs.
+
+2002-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fixed a libtool bug in order to allow passing -m64 to allow
+ building 64-bit ImageMagick using gcc 3.1 or later under SPARC
+ Solaris.
+
+2002-08-04 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added experimental 32-bit QuantumDepth pixel support.
+
+ * Stream support was not thread-safe (bug report by William Radcliffe).
+
+ * Push/PopImagePixels() now recognizes the proper buffer length
+ (previously it operated on one scanline at a time).
+
+ * Deprecated Down/Upscale defines. Replaced them with
+ Scale*ToQuantum() and ScaleQuantumTo*() methods.
+
+2002-08-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Changed configure argument --disable-16bit-pixel to
+ --with-quantum-depth in order to make its usage more
+ straightforward and generic. Build ImageMagick using an eight-bit
+ quantum via --with-quantum-depth=8.
+
+ * Magick++ library builds as a DLL under Windows now.
+
+2002-07-31 Cristy <cristy@mystic.es.dupont.com>
+
+ * Delegates/modules are restricted to hard-coded search paths (a
+ security feature suggested by Bob Friesenhahn).
+
+2002-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added SubstituteString to utility.c for performing substitions
+ on strings.
+
+ * Added support for performing Ghostscript-related substitutions
+ while reading delegates.mgk and type.mgk files.
+
+2002-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added the Windows utility functions NTGhostscriptDLL(),
+ NTGhostscriptEXE(), and NTGhostscriptFonts(), to find the DLL,
+ executable, and font directory corresponding to the newest
+ Ghostscript install on the system.
+
+2002-07-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Split nt.c into ntbase.c and ntfeature.c
+
+ * Split nt.h into ntbase.h and ntfeature.h
+
+ * Invoke NTIsMagickConflict() under Cygwin to ensure that drive
+ letters in file specifications are not confused with magick
+ strings.
+
+ * Invoke NTGetTypeList() under Cygwin to read the list of Windows
+ fonts.
+
+2002-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Created Windows "setup.exe" style installation package for
+ ImageMagick.
+
+ * Include PerlMagick Perl extension for ActiveState ActivePerl as
+ checkmark install option in Windows installation package.
+
+ * Include ImageMagickObject OLE Object for WSH and Visual Basic
+ (not IIS!!!) as checkmark install option in Windows installation
+ package.
+
+ * Windows installation package establishes file extension
+ associations for ImageMagick.
+
+2002-07-17 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * PPM files were being written in P4 or P5 format if all pixels
+ were gray. This is correct behavior for the PNM format but not
+ for the PPM format.
+
+2002-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Load font information from Windows rather than depending on hand
+ edited type-windows.mgk file. Still not incorporated in Cygwin
+ build.
+
+2002-07-04 Cristy <cristy@mystic.es.dupont.com>
+
+ * Typos corrected in perl.html (thanks to Ron Savage);
+
+ * A color profile is now correctly referred to as ICM instead of
+ IPTC.
+
+ * Added XPM color compliance to colors.mgk.
+
+ * $image->Get(`clip-mask`) now returns the clipping image.
+
+2002-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added NTRegistryKeyLookup() to nt.c in order to look up
+ ImageMagick installation parameters from the Windows Registry.
+
+ * Updated GetMagickConfigurePath() in magick.c to use installation
+ path data from the Windows Registry (if available).
+
+ * Updated VisualMagick/ImageMagick.iss so that Windows Registry is
+ updated by install package.
+
+2002-07-03 Cristy <cristy@mystic.es.dupont.com>
+
+ * Semaphore.c will compile now when pthreads are not present.
+
+ * 8-Bit Quantum PCD images now read correctly.
+
+ * The antialias member of the ImageInfo structure was not being
+ cloned.
+
+2002-07-01 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick 5.4.7 released.
+
+2002-06-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt.c (readdir): Make readdir re-entrant for each instance
+ of DIR. This should improve thread safety.
+
+ * ltdl/ltdl.c : Support building as DLL under Win32.
+
+2002-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update to use Automake 1.6.2
+
+2002-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Try harder when searching for Ghostscript fonts under Linux.
+
+2002-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Identify PICT files via magic.mgk.
+
+2002-06-18 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added PerlMagick threading support (patch by Doug MacEachern).
+
+2002-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * CLIPBOARD and EMF modules compile under MinGW and Cygwin.
+
+2002-06-14 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * The wbmp writer would dump core if it received a DirectClass
+ image that contained only black and white pixels, because no
+ colormap exists.
+
+2002-06-09 Cristy <cristy@mystic.es.dupont.com>
+
+ * Label color could not be set (bug report by Ron Savage).
+
+ * Added CatchException() method to magick/error.c.
+
+2002-06-06 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick, version 5.4.6-1 released.
+
+2002-06-05 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added -encoding option to command line utilities.
+
+2002-06-02 Cristy <cristy@mystic.es.dupont.com>
+ * ImageMagick, version 5.4.6 released.
+
+2002-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ImageMagick may now be built (static build only) using the free
+ MinGW development package from http://www.mingw.org. Leonard's
+ "clipboard" coder is included in the build.
+
+2002-05-28 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Added new "clipboard" coder for reading/writing the system's
+ clipboard. Currently this is only implemented on Windows. For
+ example: `convert logo: clipboard:`, `convert clipboard: foo.png`.
+
+2002-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Support autotrace via delegates.mgk. For example: `convert
+ autotrace:file.png file.mvg`.
+
+2002-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added progress monitor support to DrawImage().
+
+2002-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added progress monitor support to wmf.c.
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added EscapeText() to utility.c to support escaping text.
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Text escaping for -draw and DrawAnnotation was not working
+ properly. Now it does. Backslash should act as a escape for the
+ the active quote character (', ", or }) as well as backslash. The
+ backslash should be discarded if it was used as an escape
+ character. In order to reliably pass a backslash, two successive
+ backslashes are required
+ (e.g. "\\").
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Modified Base64Encode() of utility.c so that it returns the
+ number of characters encoded. This avoids having to invoke
+ strlen() on possibly megabytes of data.
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fixed compilation error with Sun Workshop compiler (wmf.c).
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Implement polypolygon support in WMF renderer. Requires libwmf
+ 0.2.4 with draw_polypolygon IPA callback.
+
+2002-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added --enable-ccmalloc configure option.
+
+2002-05-09 Cristy <cristy@mystic.es.dupont.com>
+
+ * DCM patch provided by Shane Blackett.
+
+2002-05-07 Cristy <cristy@mystic.es.dupont.com>
+
+ * Lock mutex when destroying a SemaphoreInfo structure (patch
+ provided by William Radcliffe).
+
+ * Added mingw patches provided by Derry Bryson.
+
+2002-05-05 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick, version 5.4.5-1 released.
+
+2002-04-30 Cristy <cristy@mystic.es.dupont.com>
+
+ * Subimage specification did not work for TIFF (e.g. convert
+ `image.tiff[1]` image.png).
+
+2002-04-30 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick, version 5.4.5 released.
+
+2002-04-20 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added magic string detection for the FPX format (patch provided by
+ Marc).
+
+2002-04-18 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added ExceptionInfo parameter to C API method,
+ QueryColorDatabase().
+
+2002-04-17 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Fixed all known bugs with the IMDisplay utility for Windows.
+
+2002-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac (libtool_build_static_libs): Added
+ --enable-delegate-build option to suuport building ImageMagick
+ using delegate libraries in subdirectories of the ImageMagick
+ source directory.
+
+2002-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * WMF now supplies bitmaps as inline images rather than via a mpri
+ reference.
+
+2002-04-15 Cristy <cristy@mystic.es.dupont.com>
+
+ * Fixed DrawImage() to properly handle affine image transforms.
+
+ * Added AffineTransformImage() to C API.
+
+ * Added -transform option to convert/mogrify program.
+
+2002-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (MagickToMime): New method to return the MIME
+ media type corresponding to a specified magick tag.
+
+2002-04-12 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Fixed a bug in writing layer names in PSD files.
+
+2002-04-10 Cristy <cristy@mystic.es.dupont.com>
+
+ * Fixed PingImage() memory leak (thanks to Timo Vogel).
+
+ * Added encoding and unicode attributes to PerlMagick (patch
+ provided by Youki Kadobayashi).
+
+2002-04-08 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added reference counted blobs.
+
+ * Added MagickFatalError() and SetFatalErrorHandler() to the C
+ API.
+
+ * One color images caused memory corruption in QuantizeImage()
+ (thanks to Vincent Broz).
+
+ * Memory leak in NormalizeImage() (thanks to Vincent Broz).
+
+2002-04-06 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Added CCIS-601 4:2:2 YUV format read-write support.
+
+ * Added CCIS-601 4:2:2 MPEG-2 format write support.
+
+ * Fixed a bug introduced in 5.4.0 that caused files with "M2V"
+ suffix to be written in MPEG-1 instead of MPEG-2 format.
+
+2002-03-28 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageToBlob() only returned the first frame of a multi-frame
+ image.
+
+2002-04-05 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Fixed inversion of colors when converting CMYk JPEG to PDF
+
+2002-04-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fixed TTF preview function.
+
+2002-03-28 Cristy <cristy@mystic.es.dupont.com>
+
+ * DCM patches provided by Syam Gadde.
+
+ * Multi-frame MPC image files caused a fault under Windows.
+
+ * Copy entire comment from SVG (bug report from Bob Friesenhahn).
+
+ * Enlarged scanline buffer for JPEG-compressed TIFF's (bug report
+ from Bob Friesenhahn).
+
+2002-03-27 Cristy <cristy@mystic.es.dupont.com>
+
+ * ImageMagick, version 5.4.4, released.
+
+2002-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added preliminary version of C API for vector drawing commands
+ (draw.h & draw.c). This interface is subject to change, and has
+ not even been tested yet so it should not be used to support
+ production code. The previous draw.h and draw.c have been renamed
+ to render.h and render.c respectively.
+
+2002-03-25 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * Fixed bugs related to layered CMYK PSD images.
+
+2002-03-13 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * PSD coder now saves layer information (name, offset & opacity)
+ in hidden attributes.
+
+2002-03-13 Cristy <cristy@mystic.es.dupont.com>
+
+ * Enhanced MPC to read/write image sequences.
+
+2002-03-13 Cristy <cristy@mystic.es.dupont.com>
+
+ * A number of formats (e.g. JPEG, PS) did not handle DirectClass
+ grayscale images properly.
+
+2002-03-12 Cristy <cristy@mystic.es.dupont.com>
+
+ * Changed Clone*Info() API so structure members are set directly rather
+ than by the *clone=*info method (suggested by William Radcliffe).
+
+2002-03-11 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added AcquireString() to allocate read-only strings.
+
+2002-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/null.c (WriteNULLImage): Support writing "null:" image
+ type for use when profiling or testing ImageMagick.
+
+2002-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update to Autoconf 2.53 (new release)
+
+ * Update to Automake 1.6 (new release)
+
+2002-03-07 Cristy <cristy@mystic.es.dupont.com>
+
+ * Bob Friesenhahn's execution profile results in a number of
+ speed-ups with a faster LocaleCompare() algorithm and
+ self-adjusting lists.
+
+ * Recognize additional DCM metadata (suggested by Barry Branham).
+
+ * Fixed CopyOpacity composite operator for CMYKA images.
+
+2002-03-06 Cristy <cristy@mystic.es.dupont.com>
+
+ * Inlined AlphaComposite() and ValidateColormapIndex().
+
+ * Corrected compositing algorithm for the case where both source
+ and destination pixels had opacity values that were neither fully
+ transparent nor fully opaque.
+
+2002-03-05 Cristy <cristy@mystic.es.dupont.com>
+
+ * Memory overrun when drawing large circles.
+
+2002-03-04 Cristy <cristy@mystic.es.dupont.com>
+
+ * Removed bug introduced into Bob's Base64Encode() method.
+
+2002-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Added Base64Decode() and Base64Encode() to utility.c and updated
+ ReadInlineImage() in magick/constitute.c to use Base64Decode().
+
+2002-03-01 Cristy <cristy@mystic.es.dupont.com>
+
+ * GetTypeInfoByFamily() null pointer fault (reported by Bob
+ Friesenhahn).
+
+ * Added module version number (patch by Glenn Randers-Pehrson).
+
+2002-03-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * image->matte was not being set when reading GRAY-ALPHA PNG
+ files.
+
+2002-02-26 Cristy <cristy@mystic.es.dupont.com>
+
+ * Potential infinite loop in SyncBlob() (reported by Vladimir
+ Faiden).
+
+2002-02-26 Cristy <cristy@mystic.es.dupont.com>
+
+ * Gravity not respected when drawing text with the convert
+ program.
+
+2002-02-21 Cristy <cristy@mystic.es.dupont.com>
+
+ * MPEG multi-part filenames require an embedded %d, not %lu.
+
+ * WriteStream() did not write to fifo (thanks to William
+ Radcliffe).
+
+2002-02-20 Cristy <cristy@mystic.es.dupont.com>
+
+ * Annotation did not support SJIS properly (patch provided by
+ Katsutoshi Shibuya).
+
+2002-02-18 Cristy <cristy@mystic.es.dupont.com>
+
+ * Fixed memory overrun with -format option of the mogrify program.
+
+ * Labels were not positioned correctly for VID format.
+
+2002-02-16 Cristy <cristy@mystic.es.dupont.com>
+
+ * Replaced -copy/-replace options with +/-write in the convert
+ program.
+
+ * Median filtering speed enhancement using skip list contributed
+ by Mike Edmonds.
+
+2002-02-14 Cristy <cristy@mystic.es.dupont.com>
+
+ * Command line options now stay in effect for any image in command
+ line order until a another option is encountered or if -noop is
+ specified.
+
+2002-02-07 Cristy <cristy@mystic.es.dupont.com>
+
+ * SVG coders understands inline images.
+
+2002-02-06 Cristy <cristy@mystic.es.dupont.com>, Glenn Randers-Pehrson
+
+ * Made -scene consistent across all utilities. -snaps replaces
+ previous functionality of -scene for import program.
+
+2002-01-30 Cristy <cristy@mystic.es.dupont.com>
+
+ * Correctly draw arc when arc end/start are not integer
+ (patch contributed by Giuliano Pochini).
+
+2002-01-28 Cristy <cristy@mystic.es.dupont.com>, Glenn Randers-Pehrson
+
+ * Geometry strings respect -gravity (e.g. -gravity SouthWest -crop
+ 100x100).
+
+ * Postive offsets in geometry strings move within the image canvas
+ with respect to the gravity (SouthWest gravity is similar to
+ Postscript page offsets).
+
+2002-01-24 Cristy <cristy@mystic.es.dupont.com>
+
+ * Use -trim to trim the edges of an image.
+
+ * Palm pixmap supported contributed by Christopher R. Hawks.
+
+ * Added -mask to the convert/mogrify programs to add clips masks
+ to an image.
+
+2002-01-21 Cristy <cristy@mystic.es.dupont.com>
+
+ * Fixed occasional small memory leak associated with exceptions.
+
+ * Persistent cache is no longer updated (MPC coder).
+
+2002-01-20 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Fixed some bugs in the uncompressed PGM and PPM reader/writer
+ (pnm.c).
+
+2002-01-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Removed test for libwmf/font.h.
+
+2002-01-13 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * More bug fixes and improvements in PSD writer.
+
+2002-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magic.mgk: Added entries for detecting PFA and PFB
+ formats. Is this file used for anything anymore?
+
+ * coders/modules.mgk: Add support for PFA fonts.
+
+ * coders/ttf.c (RegisterTTFImage): Add support for PFA fonts.
+
+ * magick/annotate.c (RenderType): Add support for PFA fonts.
+
+2002-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Modified type.mgk so that it may include the additional files
+ type-windows.mgk, type-solaris.mgk, and type-ghostscript.mgk
+ depending on the operating system used, and the font files
+ available.
+
+2002-01-11 Leonard Rosenthol <leonardr@lazerware.com>
+
+ * PSD now supports writing layered images and IPTC data
+
+ * Fixed some bugs in XCF
+
+2002-01-11 Cristy <cristy@mystic.es.dupont.com>
+
+ * Added image list methods to the API.
+
+2002-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac : Renamed configure option --with-ttf-fontpath to
+ --with-fontpath since ImageMagick loads more than TrueType fonts.
+
+ * ChangeLog : Renamed Changelog.txt to ChangeLog in order to
+ conform to GNU and open-source standards.
+
+2002-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am : $(DESTDIR) already contains trailing `/`.
+
+2002-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c (wmf_magick_device_begin): Fix non-opaque fills.
+ Now properly fills with texture image.
+
+2002-01-05 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Fixed an out-of-bounds memset() and two other memory overruns
+ when decoding 1-bit AVI, BMP, and DIB images.
+
+2002-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fix lcms header inclusion in transform.c.
+
+2002-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c (magick_brush): Fixed bug with setting fill color.
+
+2002-01-03 Cristy <cristy@mystic.es.dupont.com>
+
+ * Postscript Level II is now DCS compliant.
+
diff --git a/ChangeLog.2003 b/ChangeLog.2003
new file mode 100644
index 0000000..b163677
--- /dev/null
+++ b/ChangeLog.2003
@@ -0,0 +1,4901 @@
+2003-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/annotate.c (RenderFreetype): Ensure that image storage
+ class is set to DirectClass. Text rendering was not working
+ properly on top of PseudoClass images.
+
+ * magick/map.c (MagickMapRemoveEntry): Logic didn't properly
+ handle removing entry in list.
+
+ * configure.ac: Added --enable-efence option to enable memory
+ debugging using Electric Fence.
+
+2003-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/maptest.c (main): Extended test to add an entry to the
+ list after an entry has already been removed.
+
+ * magick/image.c (ColorspaceTypeToString): Add support for LAB
+ colorspace.
+
+ * magick/map.c: Added signature members to all structures and
+ added assertions to ensure that the signature == MagickSignature
+ prior to use. MagickMapAllocateObject now initializes the object
+ reference count to one, and MagickMapDestroyObject decrements it
+ in order to be more correct even though the object reference count
+ is not actually used yet.
+ (MagickMapCopyString): Preserve a null argument, and use
+ AcquireString since it doesn't enlarge the string storage.
+ (MagickMapCopyBlob): Preserve null blobs.
+
+ * configure.ac: Search for the shmctl() function. Under current
+ Cygwin, this is hiding in -lcygipc.
+
+2003-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c: Fixed the composite operator list in the
+ CompositeImage documentation.
+
+ * www/api/types.html: Corrected list of composition
+ operators. Sometime prior to the creation of GraphicsMagick, the
+ "Replace" composite operators were renamed to be "Copy" composite
+ operators. Thanks to David Relson for bringing this problem to
+ our attention.
+
+ * PerlMagick/Magick.xs: Added "LAB" to colorspace types.
+
+ * magick/image.h (enum ColorSpace): Add LABColorspace enumeration.
+
+ * wand/magick_wand.h : Add some compatibility definitions to
+ translate from ImageMagick enumerations to existing GraphicsMagick
+ enumerations.
+
+2003-12-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/annotate.c: Use header synonyms defined by FreeType's
+ ftheader.h (included via <ft2build.h>) to include FreeType headers.
+ This will presumably be more portable in the future.
+
+ * configure.ac: <ft2build.h> is an optional prerequisite for
+ <freetype/freetype.h> and <libwmf/ipa.h> so include it when
+ testing for these headers.
+
+ * magick/annotate.c: Include <ft2build.h> if it is available.
+
+2003-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/wandtest.c: Ported from latest ImageMagick version.
+
+ * wand/drawing_wand.c: Adapted to be compatible with latest
+ ImageMagick version.
+
+ * wand/pixel_wand.c: Adapted to be compatible with latest
+ ImageMagick version.
+
+ * wand/magick_wand.c: Ported from latest ImageMagick version.
+
+ * magick/image.h (Image): Members color_profile, iptc_profile,
+ generic_profile, and generic_profiles are now deprecated and
+ private although they continue to work as before. Please migrate
+ existing code to use the GetImageProfile and SetImageProfile
+ functions since these members will eventually be removed.
+
+ * magick/image.c (GetImageProfile): New function to retrieve an
+ image profile. Return value differs from similarly named
+ ImageMagick method since the ImageMagick approach assumes a
+ particular storage method.
+ (SetImageProfile): New function to add (or remove) an image
+ profile. Does not execute CMS color profiles.
+
+ * magick/cache.c (SetImageVirtualPixelMethod): Return unsigned int to
+ make the Wand implementation happy.
+
+ * magick/image.c (TransformColorspace): Return unsigned int to
+ make the Wand implementation happy.
+ (SetImageType): Return unsigned int to make the Wand
+ implementation happy.
+
+ * magick/draw.h, magick/draw.c: Substitute `unsigned long` in
+ place of `size_t` in interfaces so that the draw API is not
+ sensitive to the definition of _LP64.
+
+ * locale/C.mgk: Added new messages required by Wand library.
+
+ * magick/error.c (ExceptionSeverityToTag): Add tag translations
+ for the WandWarning, WandError, & WandFatalError enumerations
+
+ * magick/error.h (enum ExceptionType): Add WandWarning, WandError,
+ & WandFatalError enumerations to ExceptionType for ImageMagick
+ API compatibility.
+
+ * magick/image.h (enum ChannelType): Add an `AllChannels`
+ enumeration to the ChannelType enumeration for ImageMagick
+ API compatibility.
+
+2003-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick, tests: Adjusted allowed error values for tests based
+ on new error computation arithmatic. Some tests were left failing
+ since the operation they test provides results which are
+ unreasonably inaccurate, or obviously broken.
+
+2003-12-17 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/jpeg.c: Changed "JPEG:preserve-settings from a key/value
+ pair to a simple flag. Save and restore attributes when
+ "-define JPEG:preserve-settings" appears on the commandline. Use
+ "+define JPEG:preserve-settings" to unset the flag.
+
+2003-12-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c: Include <ft2build.h> if it is available since some
+ libwmf installs don't work unless it is included before the libwmf
+ API headers.
+
+ * configure.ac: Check for <ft2build.h>.
+
+2003-12-16 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/jpeg.c: Changed stored jpeg quality attribute from
+ [jpeg-quality] to JPEG-Quality. Added attributes JPEG-Colorspace
+ and JPEG-Sampling-factors. Added code to save and restore
+ these attributes when "-define JPEG:preserve-settings=yes" is
+ present in the comandline. Quality is restored if the input
+ was a JPEG and the quality was preserved. Sampling factors
+ are restored if the input was a JPEG, sampling factors were
+ preserved, and the colorspace for the output file is the same
+ as that of the input file.
+
+2003-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * TclMagick/source/configure.ac: Add an initial TclMagick
+ configure-based build environment based on a template and macros
+ from the Tcl project. I recall that while the extension does build,
+ it is possible that it is not properly registered as a module to Tcl.
+
+2003-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (IsImagesEqual): Properly compute error distance
+ vectors. Math was missing the necessary sqrt call. Also,
+ pre-normalize the error differences to 1.0 in order to reduce the
+ storage size required to store the summation of error values.
+
+ * PerlMagick/t/composite.t: Update Minus and Xor reference images.
+
+ * magick/composite.c (CompositeImage): Incorporated fixes from
+ ImageMagick for XorCompositeOp, PlusCompositeOp, and
+ MinusCompositeOp. Thanks to John Cristy for bringing the need for
+ these fixes to our attention.
+
+ * magick/image.h (RoundToQuantum): Added missing parenthesis.
+
+2003-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/environment.imdoc: Document MAGICK_CODER_MODULE_PATH and
+ MAGICK_FILTER_MODULE_PATH.
+
+ * rungm.sh.in: Pass MAGICK_CODER_MODULE_PATH and
+ MAGICK_FILTER_MODULE_PATH in the environment so modules build may
+ be tested without first being installed.
+
+ * magick/module.c (FindMagickModule): Use the
+ MAGICK_CODER_MODULE_PATH environment variable to specify a search
+ path for coder modules. Use MAGICK_FILTER_MODULE_PATH to specify
+ a search path for filter modules.
+
+ * Makefile.am: Updated to Automake 1.8.
+ (install-exec-perl): Fixes which achieve a successful
+ `make distcheck` for the first time in *Magick history.
+
+ * configure.ac: Set scripts to executable.
+
+2003-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (uninstall-data-html): Pathnames were computed
+ incorrectly so documentation directories were being left behind.
+
+ * configure.ac: --without-frozenpaths is now the default. This
+ helps `make distcheck` work and makes the package more portable.
+ Path to gm was being incorrectly frozen when --without-frozenpaths
+ was specified.
+
+ * magick/delegate.c (ReadConfigureFile): Validate delegate paths
+ prior to substitution.
+
+ * rungm.sh.in (top_builddir): Use a more reliable scheme for
+ computing location of source and build directories.
+
+ * magick/Makefile.am: Improve include directory computation logic.
+
+ * configure.ac: Don't override includedir. Pass user-supplied LIBS
+ to the linker.
+
+2003-12-08 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/jpeg.c: store JPEG quality as "[jpeg_quality]" attribute.
+
+2003-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * rungm.sh.in: New script to support executing uninstalled
+ executables.
+
+ * magick/blob.c (GetConfigureBlob): New MAGICK_CONFIGURE_PATH
+ environment variable allows the user to specify the search path
+ for configuration (.mgk) files.
+
+2003-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * index.html: Added a table showing current stable release and
+ development version.
+
+2003-12-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc (use): Describe the syntax of the -process
+ argument.
+
+ * acinclude.m4 (AC_CHECK_CC_OPT): Add quoting in AC_CHECK_CC_OPT
+ definition. Change suggested by Patrick Welche
+
+2003-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (GetMagickInfo): Fix preprocessing logic error
+ which caused moby shared library build to not register static
+ modules.
+
+2003-12-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/module.c (ExecuteModuleProcess): Add some logging.
+
+ * magick/static.c (ExecuteStaticModuleProcess): Add some logging.
+
+2003-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer: Add optional build support for LZW.
+
+ * wand/Makefile.am: Add AUTOMAKE_OPTIONS.
+
+ * configure.ac: Update to Autoconf 2.59.
+
+2003-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/tasks-install-perlmagick.isx: Update
+ to reflect that the next release will use ActivePerl 5.8.1 Build
+ 807.
+
+ * VisualMagick/installer/inc/files-configs.isx: Updated the source
+ locations for the .mgk files. Install modules.mgk into the config
+ directory rather than the modules directory.
+
+ * configure.ac: Fixes to work with latest CVS libtool.
+
+ * libtool.m4: Update to latest CVS libtool.
+
+ * magick/modules.c, magick/static.c (ExecuteStaticModuleProcess):
+ Fix conditional compilation logic so that "moby" shared library
+ build works again.
+
+ * magick/compress.c, magick/mac.c: Use existing SaveImageText and
+ LoadImageText global constants rather than separate defines.
+
+2003-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Update to Autoconf 2.58.
+
+ * Makefile.am: Update to Automake 1.7.9.
+
+2003-11-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/draw.c (DrawComposite): Base64-encoded image was not
+ being deallocated. Bad memory leak.
+
+2003-11-03 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick: Updated installation procedure. Please read
+ BCBMagick/readme.txt for details.
+
+2003-11-03 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick: Released DLL Version. Please read BCBMagick/readme.txt
+ for details about installation and/or use.
+
+2003-11-03 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/utility.c (GetPathComponent): Added x, X, and +
+ characters to list of legal characters in subimage
+ specifications. Required by raw RGB image reader which accepts the
+ syntax "image.rgb[100x100+50+50]". Thanks to John Cristy for
+ catching that one.
+
+2003-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/locale.c (GetLocaleMessageFromID): Fix ID range checking
+ logic.
+
+2003-10-30 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * coders/jpeg.c: changed to not write gray CMYK images as
+ grayscales. That would not be a valid optimization.
+
+ * magick/color.c (IsGrayImage, IsMonochromeImage): Changed to
+ never return true for CMYK images. Separated images get wrong
+ colors when optimized to grayscales based on what these two
+ functions return. Gray and CMYK are two different color spaces.
+
+ * magick/nt_feature.c (NTIsMagickConflict): changed to accept
+ colon as part of the magick string, consistent with the way the
+ function is used.
+
+ * magick/utility.c, magick/utility.h (ExpandFilenames,
+ GetPathComponent): Fixed filename glob expansion. Added handling
+ of filename prefix-magick and sub-image specification to
+ GetPathComponent. Sub-image specification takes precedence over
+ any filename patterns.
+
+2003-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/static.c (ExecuteModuleProcess): Renamed from
+ ExecuteStaticModuleProcess. Only compiled if SupportMagickModules
+ is not defined.
+
+ * magick/type.c (GetTypeBlob): Eliminated function.
+ (ReadTypeConfigureFile): Use GetConfigureBlob() rather than
+ GetTypeBlob().
+
+ * magick/module.c (GetModuleBlob): Eliminate this function since
+ modules.mgk is now installed under
+ ${prefix}/share/GraphicsMagick-version/config so
+ GetConfigureBlob() may be used.
+ (lt_dlexit, etc.) Eliminate fake libltdl function wrappers used
+ for the static build.
+ (DestroyMagickModules): Added a new destroy function (simply
+ invokes DestroyModuleInfo()).
+ (GetModuleList): Learn where modules live by using
+ FindMagickModule() to locate the LOGO module rather than by using
+ the location of modules.mgk. This is necessary since now
+ modules.mgk may be seperate from the modules.
+ (GetModuleBlob): Eliminated function.
+ (InitializeMagickModules): New function to safely initialize the
+ module loader.
+ (OpenModule): Added logging messages.
+ (OpenModules): Added logging messages.
+ (ReadModuleConfigureFile): Use GetConfigureBlob() rather than
+ GetModuleBlob().
+ Totally eliminated the rat's-nest of conditional code dependent on
+ SupportMagickModules. Now all the code in module.c is dependent
+ on #if defined(SupportMagickModules).
+
+ * magick/magick.c (DestroyMagick): Invoke DestroyMagickModules().
+ (GetMagickInfo): #ifdef chunks of code which exist to support the
+ modules-build rather than forcing the module loader to pretend
+ that modules are being used when they are not. Pass module loading
+ exceptions back to the user rather than discarding them.
+ (GetMagickInfoArray): Don't inspect the exception status since may
+ short-circuits the operation. Use best-effort instead.
+ (ListMagickInfo): Don't inspect the current exception status so
+ that all the modules which did load successfully will be
+ represented.
+ (InitializeMagick): Invoke InitializeMagickModules().
+
+ * magick/log.c: (GetLogBlob): Eliminated function.
+ GetConfigureBlob() is safe to use now when configuring logging.
+ (LogToBlob): Simplified function. Only exists since FileToBlob()
+ may throw exceptions (which are logged, causing deadlock).
+ (ReadLogConfigureFile): Use GetConfigureBlob().
+
+ * magick/blob.c (GetConfigureBlob): Re-written to use the
+ MagickMap interface and to support the new `lib` and `share`
+ config directories. The directory
+ ${prefix}/lib/GraphicsMagick-version/config is scanned before
+ ${prefix}/share/GraphicsMagick-version/config.
+ (FileToBlob): Simplified implementation.
+
+ * config/Makefile.am: New makefile to install .mgk files.
+
+ * magick/magick_config.h.in: Added MagickLibConfigPath and
+ MagickShareConfigPath defines.
+
+ * configure.ac: Install configuration files (.mgk files) in
+ ${prefix}/lib/GraphicsMagick-version/config and
+ ${prefix}/share/GraphicsMagick-version/config. Architecture
+ independent files to under "share" while architecture dependnet
+ files go under "lib".
+
+ * Makefile.am: Added `config` subdirectory to distribution. All
+ .mgk files are moved from `coders` & `magick` into this single
+ directory.
+
+2003-10-21 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * magick/studio.h: small modifications to achieve DLL
+ compilation of library with Borland C++ Builder.
+
+ * coders/ps3.c (ZLIBEncode2Image): Fixed bug. Compilation
+ fail when HasZLIB is undefined because parameters 5 and 6,
+ are undefined.
+
+2003-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtool.m4: Updated libtool again to CVS latest version.
+ Libtool required some fixes for building DLLs under MinGW.
+
+ * magick/resource.c (InitializeMagickResources): Some code is
+ conditional based on HAVE_POPEN.
+
+ * magick/utility.c (SystemCommand): Improved conditional
+ compilation logic.
+
+ * magick/blob.c (OpenBlob): Code depending on popen() is
+ conditionally compiled based on HAVE_POPEN. Code depending on
+ pclose() is conditionally compiled based on HAVE_PCLOSE.
+
+ * configure.ac: Add test for _pclose(), pclose(), _popen(), and
+ popen().
+
+ * magick/locale.c (GetLocaleMessage): Add missing MagickExport.
+ (GetLocaleMessageFromID): Add missing MagickExport.
+
+ * VisualMagick/installer/inc/files-development.isx (Source):
+ Include all of the headers from the magick directory in the
+ development package. Including them individually is too error
+ prone.
+
+2003-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/magick/magick_config.h.in: Added
+ PREFIX_MAGICK_SYMBOLS as a configuration option.
+
+ * magick/module.c (_CoderInfo): Added register_function and
+ unregister_function members to record the module's register and
+ unregister function addresses.
+ (OpenModule): Locate the module's register and unregister
+ functions and save their address to the module's CoderInfo record.
+ (UnloadModule): Invoke the module unregister function using the
+ address recorded by OpenModule().
+ (TagToFunctionName): If PREFIX_MAGICK_SYMBOLS is defined, then add
+ a "Gm" prefix to the register and unregister function names.
+
+ * libtool: Updated libtool files to the latest CVS version.
+
+ * configure.ac: Changed define name from MAGICK_SYMBOL_PREFIX to
+ PREFIX_MAGICK_SYMBOLS since support is not available for
+ specifying an arbitrary prefix.
+
+2003-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Added --enable-symbol-prefix configure option
+ which prepends "Gm" to all GraphicsMagick library symbols using
+ the C pre-processor. In the future, this may change to support
+ specifying an arbitrary prefix, depending on experience.
+
+ * magick/studio.h: Include magick/symbols.h.
+
+ * magick/api.h: Include magick/symbols.h.
+
+ * magick/symbols.h: New header to support optionally remapping
+ library symbols. If MAGICK_SYMBOL_PREFIX is defined, then
+ library symbols are remapped.
+
+2003-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/api.h: Removed inclusion of <magick/semaphore.h> since it
+ is an implementation header.
+
+2003-10-13 Lars Skyum <lrs@stibo.dk>
+
+ * www/GraphicsMagick.html, www/animate.html, www/composite.html,
+ www/conjure.html, www/convert.html, www/display.html, www/gm.html,
+ www/identify.html, www/import.html, www/mogrify.html,
+ www/montage.html: added documentation for "-define" command line
+ option.
+
+ * doc/brief_options.imdoc, doc/options.imdoc: Added documentation
+ for "-define" command line option.
+
+ * doc/gmdocselect, doc/imdocselect: Changed "skipform" label in
+ sed scripts to just "skipf". Solaris sed had problems with the
+ long(?) "skipform" label.
+
+2003-10-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/composite.imdoc, doc/options.imdoc, doc/GraphicsMagick.imdoc:
+ Attempted to clarify the meaning of the compose arguments and how
+ composition works, as well as eliminating use of hard-coded values like
+ 255.
+
+ * www/links.html: Added a link to Michael Still's article
+ "Graphics from the command line".
+
+2003-10-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/*.c: Updated module descriptions so that they accurately
+ describe the module rather than saying "Read/Write GraphicsMagick
+ Image Format".
+
+ * coders/cineon.c: Fix source module description. Contrary to
+ opinion, ImageMagick did not invent the Cineon X image format so
+ description is now "Read/Write Cineon X Image Format."
+
+ * magick/magic.mgk: Added a CINEON entry for the Cineon X image
+ format.
+
+ * magick/static.c (RegisterStaticModules): Invoke
+ RegisterCINEONImage().
+
+ * coders/modules.mgk: Map "CIN" magick to CINEON module.
+
+2003-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * locale/C.mgk: Added message for "UnrecognizedCommand".
+
+ * magick/command.c (MagickCommand): No error was reported when a
+ subcommand failed to be matched so `gm foo` would silently return.
+ Now an error message is properly reported.
+
+2003-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Updated to Automake 1.7.8.
+
+ * various: Edits to eliminate minor issues detected by SGI C compiler.
+
+ * coders/ps3.c (WritePS3Image): Variable `value` was set but never
+ used so it is removed.
+
+ * magick/image.c (RGBTransformPacket): Removed inline request
+ since this function is too big to inline.
+
+ * magick/animate.c (XAnimateBackgroundImage): Fixed a GCC 3.X
+ "type pinning" warning.
+
+ * magick/display.c (XDisplayBackgroundImage): Fixed a GCC 3.X
+ "type pinning" warning.
+
+ * magick/render.c (GetPixelOpacity): Removed inline directive. No
+ one in their right mind could ever imagine this function inlining
+ successfully.
+
+ * magick/cache.c (IsNexusInCore): Adjusted so function inlines as
+ requested.
+
+ * coders/tiff.c (ReadTIFFImage): Improved logging information.
+ (WriteTIFFImage): Changed the way the bilevel/grayscale logic
+ works. Now bilevel images are treated similar to any other
+ grayscale image unless CCITT FAX3 or FAX4 compression is requested
+ (which selects the MINISWHITE photometric). The default is now to
+ write uncompressed bilevel images with MINISBLACK photometric.
+
+ * PerlMagick/t/composite.t: Use some reasonable error values.
+
+ * magick/image.c (GetImageDepth): Added special cases for
+ colormapped images and monochrome images in order to improve
+ performance.
+
+2003-10-09 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * NEWS: added info about color scaling, sampling-factor, and
+ changed a reference to "-coder-options" to "-define".
+
+2003-10-09 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * VisualMagick/bin/modules.mgk: added EPS3 mapping to PS3 module.
+
+ * coders/ps3.c, coders/tiff.c, magick/command.c, magick/image.c,
+ magick/image.h, magick/utility.c: Changed -coder-options option to
+ -define. Also renamed functions {Add,Remove,Access}CoderOption(s)
+ to {Add,Remove,Access}Definition(s). Changed ps coder-specific
+ option ps:image=imagemask to just ps:imagemask.
+
+2003-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/cineon.c: Imported and adapted Cineon image format coder
+ written by Kelly Bergougnoux <three3@users.sourceforge.net> with
+ assistance from John Cristy.
+
+2003-10-08 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/jpeg.c: Extended -sampling-factor option to allow
+ user to supply full set of sampling factors. If the full
+ set is not supplied, omitted ones are 1x1 by default, similar
+ to the behavior of "cjpeg -sample".
+
+ * magick/command.c: Accept multiple pairs of sampling factors.
+
+2003-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Re-arranged logging for improved
+ output. Cleaned up evaluation of SAMPLESPERPIXEL and
+ BITSPERSAMPLE. Provided support for the TIFF coder options
+ tiff:samples-per-pixel and tiff:bits-per-sample for power users.
+ (ReadTIFFImage): Colormap generation for PHOTOMETRIC_MINISBLACK
+ and PHOTOMETRIC_MINISWHITE was inaccurate. Seems to be accurate
+ now.
+
+ * PerlMagick/t/reference/read/input.miff: Updated due to Glenn's
+ change to scale macros.
+
+ * PerlMagick/t/tiff/input_gray_12bit.tiff: Replaced 12 bit image
+ with a different one which is written by GraphicsMagick.
+
+ * coders/ps3.c (WritePS3Image): Use AccessCoderOption().
+
+ * magick/image.c (AccessCoderOption): Added a function to use for
+ accessing coder-specific options.
+
+2003-10-08 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/attribute.c (TraceSVGClippingPath): optimized for speed
+ and precision in clipping mask generation by using lines to
+ connect Bezier curve anchor points where applicable.
+
+2003-10-07 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Revised ScaleColor5to8 and ScaleColor6to8 macros again, to
+ fill the low bits correctly.
+
+2003-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/tiff/read.t: Added 16-color and 256 color
+ colormapped tests with a matte channel.
+
+ * PerlMagick/t/tiff/write.t: Added 16-color and 256 color
+ colormapped tests with a matte channel.
+
+ * coders/tiff.c (WriteTIFFImage): When using LZW compression,
+ apply the horizontal differencing predictor to RGB truecolor and
+ deep gray images since the TIFF spec says that LZW compression is
+ usually improved by using horizontal differencing with continuous
+ tone images.
+ Re-implemented grayscale and colormapped scanline preparation to
+ use the new bit-stream interface. This is a bit slower, but very
+ flexible, and the implementation is very compact. Writing of a
+ matte (transparency) channel is now believed to be correct for all
+ depths.
+
+ * magick/command.c (MogrifyImage): Only transform the colorspace
+ if it has been set (i.e. is not UndefinedColorspace).
+
+2003-10-06 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/png.c (ReadOnePNGImage): PNG decoder would exit too
+ early when reading image.png[0].
+
+2003-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/tiff/write.t: Added TIFF write tests for 4
+ bits-per-sample TIFF images, both with and without a transparency
+ channel.
+
+ * magick/image.c (DescribeImage): Added -verbose support for
+ displaying individual channel depths.
+
+2003-10-06 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/image.c (SetImageInfo): cleaned up parsing of subimage
+ specification (image.psd[0]). It would fail sometimes due to
+ incorrect reuse of variables. It's a bit strange the code accepts
+ more range syntax-variations than can be stored in ImageInfo.
+
+2003-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (ChannelImage): The OpacityChannel, MatteChannel,
+ and BlackChannel operations set the matte channel to opaque, so
+ set image->matte to False for those operations.
+ (RGBTransformImage): Add an assertion to prevent passing the
+ colorspace argument `UndefinedColorspace`.
+ (TransformRGBImage): Add an assertion to prevent passing an image
+ with colorspace set to `UndefinedColorspace`.
+
+2003-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/log.c (LogToBlob): Since MagickSeek(file,0,SEEK_END) is
+ used to obtain the Blob size, MagickSeek(file,0,SEEK_SET) must be
+ used to restore the seek position. Thanks to John Cristy for
+ bringing this to our attention.
+
+2003-10-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/bit_stream.h: Added a bit-stream writer function.
+
+ * PerlMagick/t/reference/read/input_tim.miff: Reference image
+ was defective.
+
+2003-10-03 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/image.c, magick/image.h: Updated AddCoderOptions to
+ accept "flag" keys that have no values. They are placed in the
+ coder options map with an empty, zero length string value. Option
+ argument syntax is now: "key1[=[value1]],key2[=[value2]],..."
+
+2003-10-03 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/command.c: Updated +coder-options option to not clear the
+ entire map of coder options, but accept a list of names to remove
+ from the map. Use option argument "*" to clear the entire map of
+ coder options.
+
+ * magick/image.c, magick/image.h: Added function
+ RemoveCoderOptions. Added cast of signed char to unsigned char and
+ int in calls to isspace and isprint.
+
+ * magick/utility.c: Added cast of signed char to unsigned char and
+ int in calls to isspace and isprint. Added special handling of
+ +coder-options option in ExpandFilenames function.
+
+2003-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/reference/read/input_tim.miff: The TIM read results
+ changed somewhat due to Glenn's ScaleColor5to8 fix.
+
+2003-10-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Revised ScaleColor5to8 and ScaleColor6to8 macros to fill in the
+ low bytes.
+
+ * coders/bmp.c (ReadBMPImage): scaling of 8-8-8-8-bit images was
+ also slightly incorrect.
+
+2003-09-30 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/bmp.c (ReadBMPImage): scaling of 5-5-5-bit and 5-6-5-bit
+ images was slightly incorrect.
+
+2003-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): When using the generic bit-stream
+ marshaller to read colormapped/gray images, the slight performance
+ improvement from creating a special case for matte images did not
+ justify almost doubling the amount of code. Therefore, the two
+ loops are combined back into one.
+
+2003-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Fixed reading grayscale TIFFs
+ that have a transparency channel. Now uses a generic bit-stream
+ marshaller to allow reading any grayscale or colormapped TIFF with
+ any bits per sample in the range of 1 to 16.
+
+ * magick/bit_stream.h: Added a generic implementation for
+ marshalling from a bit-stream into a quantum. Still needs
+ re-writing for best performance.
+
+ * PerlMagick/t/tiff/read.t: Added a test case for reading 8-bit
+ grayscale TIFF with matte. Corrected grayscale 12-bit read
+ signatures. Added 16 color PseudoClass read test. Added 4-bit
+ grayscale read test.
+
+2003-09-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Add support for writing
+ DirectClass grayscale images at 4 bits per sample, including those
+ with an opacity channel. This allows writing smaller files
+ (half the size) when the image has 16 (or less) levels of gray.
+ Use "gm convert inimage.tiff -depth 4 outimage.tiff" to quickly
+ create grayscale TIFF file with 16 (or less) levels of gray.
+
+2003-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS: Updated NEWS file with changes since last update.
+
+ * index.html: Added a link to the www/AUTHORS.html file, as well
+ as text stating that GraphicsMagick is originally derived from
+ ImageMagick 5.5.2, with a link to the ImageMagick site.
+
+ * Makefile.am: Add rules to generate www/AUTHORS.html.
+
+ * www/AUTHORS.html: New HTML file based on the AUTHORS file in the
+ source package. GraphicsMagick has many authors.
+
+2003-09-25 William Radcliffe <billr@corbis.com>
+ * magick/image.c: Updated DescribeImage to cleanup EXIF data display
+ based on work by Cristy in ImageMagick.
+
+2003-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Add support for writing
+ colormapped TIFF images with 1, 2, & 4 bits per colormap index.
+ This allows writing smaller files.
+
+2003-09-24 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * coders/ps3.c: Now creates a correct %%BoundingBox for images
+ with resolution stored as pixels per centimeter. Renamed serialize
+ functions. Added comment headers where they were
+ missing. Reformatted code to be in alignment with GraphicsMagick
+ standard formatting.
+
+ * magick/map.c: Fixed semaphore double locking problem in
+ MagickMapCloneMap.
+
+2003-09-23 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick/readme.txt : Updated compilation instructions.
+
+ * BCBMagick/magick/libMagick.bpr : Updated project, now include map.c.
+
+ * BCBMagick/lcms/Projects/BCB6/lcms.bpr : Updated project, now
+ include cmscam02.c and cmsvirt.c. Much thanks to Alex Dvoretsky
+ for bringing this problem to my attention.
+
+2003-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h (Image): Moved private members to bottom of
+ structure.
+ (_ImageInfo): Moved private members to bottom of
+ structure.
+
+ * magick/Makefile.am (pkginclude_HEADERS): Don't install
+ semaphore.h.
+ (noinst_HEADERS): Distribute map.h and semaphore.h.
+
+ * magick/image.h (ImageInfo): Change coder_options member from
+ type `MagickMap` to type `void *`.
+
+ * coders/png.c: include magick/semaphore.h.
+
+ * magick/blob.c: include magick/semaphore.h.
+
+ * magick/color.c: include magick/semaphore.h.
+
+ * magick/constitute.c: include magick/semaphore.h.
+
+ * magick/delegate.c: include magick/semaphore.h.
+
+ * magick/log.c: include magick/semaphore.h.
+
+ * magick/magic.c: include magick/semaphore.h.
+
+ * magick/magick.c: include magick/semaphore.h.
+
+ * magick/module.c: include magick/semaphore.h.
+
+ * magick/semaphore.c: include magick/semaphore.h.
+
+ * magick/stream.c: include magick/semaphore.h.
+
+ * magick/tempfile.c: include magick/semaphore.h.
+
+ * magick/type.c: include magick/semaphore.h.
+
+ * magick/blob.h (_BlobInfo): Changed `Semaphore *` to `void *`.
+
+ * magick/cache.h (_CacheInfo): Changed `Semaphore *` to `void *`.
+
+ * magick/image.h (_Image): Changed `Semaphore *` to `void *`.
+
+ * magick/command.c: Updated each invokation of MagickMapAddEntry()
+ to add an exception argument.
+
+ * tests/maptest.c: Updated to pass an exception argument to
+ MagickMapAddEntry.
+
+ * magick/image.c (AddCoderOptions): Added exception argument
+ and some more error handling.
+
+ * magick/map.c: Added formal documentation for methods.
+ (MagickMapCloneMap): Added exception argument.
+ (MagickMapAddEntry): Added exception argument and status.
+
+2003-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/emf.c: Changed NotAnEMFFile to ImproperImageHeader.
+
+ * magick/map.h: Changed all size parmeters from type `unsigned
+ long` to `size_t`.
+
+ * magick/map.c (MagickMapCopyBlob): Add new function to support
+ copying a Blob in a MagickMap.
+ (MagickMapDeallocateBlob): Add new function to support
+ deallocating a Blob in MagickMap.
+
+2003-09-23 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * coders/ps3.c: Fixed handling the case when no -coder-options are
+ provided to the PS3 coder.
+
+2003-09-22 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * coders/ps3.c: Changed %%Creator version to use
+ MagickLibVersionText, increased precision in HiResBoundingBox,
+ added a coder specific option for rendering bilevel images with
+ the PS imagemask operator indstead of the image operator.
+
+ * magick/command.c: Added "-coder-options" command line argument
+ to all relevant command line utilities. Option argument to
+ -coder-options is a list of comma separated key-value pairs that
+ are saved in a MagickMap in ImageInfo for (de-)coders to use. See
+ PS3 coder for an example that checks for: -coder-options
+ "ps:image=imagemask"
+
+ * magick/image.c, magick/image.h: Added function AddCoderOptions().
+
+ * magick/map.c, magick/map.h: removed MS-DOS line terminators.
+
+2003-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/maptest.c (main): Test/demo program for key,value map API.
+
+ * magick/map.c, magick/map.h: Implementation of a key,value map
+ API for internal use.
+
+2003-09-19 William Radcliffe <billr@corbis.com>
+
+ * lcms/include/icc34.h lcms.h: Added back the icc34.h header and
+ changes to make lcms compile on Win32" icc34.h lcms.h.
+
+2003-09-19 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * coders/ps3.c: Fixed warnings from Solaris compiler.
+
+2003-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * locale/C.mgk: Eliminated the many "NotA" messages since they may
+ all be considered forms of "ImproperImageHeader". It is useful to
+ provide the origin of such messages in case the wrong coder has
+ been invoked, however, this is expensive to do via the message
+ database since it explodes the number of messages. The exception
+ logging can help here. Once the exception reports include the
+ reporting entity, it will be more clear when the software
+ misbehaves.
+
+ * magick/error.h (ThrowReaderException2): Remove since no longer
+ used.
+ (ThrowReaderException): Simplified implementation so that
+ ThrowException is not expanded twice.
+
+ * magick/error.h (ThrowReaderException3): Remove since never used.
+
+ * coders/xtrn.c (ReadXTRNImage): Use ThrowReaderException rather
+ than ThrowReaderException2.
+
+ * locale/C.mgk (MissingArgument) Updated to include %s so that the
+ description field appears earlier in the message.
+
+ * magick/error.c (DefaultErrorHandler): Added a hack to allow the
+ `reason` member to include a %s so that it may specify the
+ formating of the message. Care should be taken to not over-use
+ this hack.
+
+2003-09-18 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * coders/ps3.c: Major update of the PS3 coder. Now ascii85 encodes
+ all binary data. Many printer spoolers don't like the binary
+ data. The coder now creates much smaller files for bilevel, gray,
+ and colormapped images. Compression and image type is now
+ separated so they may be combined independently. Any alpha channel
+ is separated into a separate mask so it's possible to mask
+ bilevel, gray, colormapped, rgb, and CKYK images. You may also
+ mask a JPEG compressed PS file for instance. Clipping masks
+ created from a photoshop clipping path with -clip option is
+ converted to a corresponding postscript clipping path. New
+ functions need comment headers.
+
+ * magick/attribute.c: Added TracePSClippingPath for creating a
+ postscript clipping path from a photoshop clipping path.
+
+ * magick/compress.c, magick/compress.h: Added write-hook based
+ interface to compression functions. Required for ascii encoding
+ compressed, binary data. The interface between blob write
+ functions, compression functions, and encoding functions could
+ benefit from more of this work.
+
+ * magick/image.c: ClipPathImage now stores the name of the
+ clipping path in the mask image filename so that it is remembered
+ and may be used for creating a postscript clipping path for
+ postscript output.
+
+ * coders/modules.mgk: Added EPS3 mapping to module PS3.
+
+2003-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Coalesced various "Missing" error reports into
+ one "MissingArgument" error report in order to reduce the number
+ of messages to be maintained.
+
+ * locale/C.mgk: Removed almost all "Missing" messages.
+
+ * magick/gm_messages.mc: Added Microsoft message compiler source
+ file to CVS until which time it may be generated automatically
+ during the build.
+
+2003-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * locale/Makefile: Added ability to generate gm_messages.mc
+ (for Windows message compiler) as well as adding `clean` and
+ `install` targets.
+
+ * magick/delegate.h: Visual Studio .NET 2003 doesn't like
+ the chaining of GhostscriptVector members which share a
+ common return type. Splitting the definitions solves this
+ problem.
+
+2003-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/deprecate.h (MagickSignedType): Compatibility definition
+ to handle ImageMagick API change.
+ (MagickUnsignedType): Compatibility definition to handle
+ ImageMagick API change. The new names are just as useless as the
+ old names, but at least they are shorter.
+
+ * magick/command.c: Linux's sscanf has the terrible bug that it
+ improperly handles pulling out the first floating value from the
+ string "0x1". Instead of retrieving the value 0 and returning 1,
+ it returns 0, probably because it rejects the string as a hex
+ constant. As a result, all options which used sscanf to validate
+ this input are now converted to use IsGeometry().
+
+2003-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ltdl/ltdl.c: Update to libltdl current as of today.
+
+ * ltmain.sh: Update to libtool current as of today.
+
+ * configure.ac: For HPUX C++ compiler, add -AA to CXXFLAGS rather
+ than CXX.
+
+2003-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Decided that the standards conformance
+ defines create more problems than they solve so they are
+ removed.
+ Move the large-file tests to before the libtool configuration
+ since the libtool configuration was causing stdlib.h to be
+ included prior to the large file defines, and this causes
+ header failure with C++ under AIX.
+
+ * www/api/types.html: Update description of MonitorHandler.
+
+2003-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Set CXX to PTHREAD_CXX if necessary (and warn).
+
+ * acinclude.m4 (ACX_PTHREAD): Add check to see if xlC_r should be
+ used for AIX.
+
+2003-09-10 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/render.c: Fixed handling of arc primitive (see IM-5.5.8).
+
+2003-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/log.h: It seems that test programs are using
+ GetMagickModule so make it visible by default.
+
+ * configure.ac: Use GM_FUNC_MMAP_FILEIO macro to test mmap.
+
+ * acinclude.m4 (GM_FUNC_MMAP_FILEIO): New macro to test mmap's
+ capability to do coherent file I/O. The AC_FUNC_MMAP macro
+ was not testing the mmap features that GraphicsMagick uses, and
+ was failing on a number of systems.
+
+ * magick/blob.c (BlobMapModeToString): Only include this static
+ function if HAVE_MMAP is defined.
+
+ * coders/locale.c (WriteLOCALEImage): Fix FormatString argument
+ type inconsistencies.
+
+ * wand/magick_compat.h: Change MagickExport to WandExport.
+
+ * coders/jpeg.c, coders/locale.c, coders/meta.c, coders/miff.c,
+ coders/palm.c, coders/pict.c, coders/svg.c, coders/tiff.c,
+ coders/topol.c, magick/cache.c, magick/display.c, magick/image.c,
+ magick/widget.c: Removed unused values, changed storage types, or
+ added explicit casts, in order to reduce the number of "REMARK"s
+ when using the SGI IRIX compiler.
+
+ * magick/render.c (DrawClipPath): Fix memory leak of
+ clone_info->clip_path. Problem reported by Vladimir
+ <lvm@integrum.ru>.
+ (DestroyDrawInfo): Remove unnecessary checks for non-null prior to
+ invoking MagickFreeMemory. MagickFreeMemory already checks for
+ non-null.
+
+ * magick/log.h (GetCurrentFunction): Apparently Visual C++ 6.0
+ does not support __FUNCTION__. Problem reported by Vladimir
+ <lvm@integrum.ru>.
+
+ * wand/magick_compat.c: All functions in magick_compat.c must use
+ WandExport rather than MagickExport. Fix recommended by Vladimir
+ <lvm@integrum.ru>.
+
+ * magick/constitute.c (PushImagePixels): number_pixels was always
+ cast to a long during use, so change to store value in a long
+ instead.
+ (PopImagePixels): number_pixels was always
+ cast to a long during use, so change to store value in a long
+ instead.
+
+2003-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/psd.c: Eliminated warning regarding unused initialized
+ variable.
+
+ * magick/log.c: Eliminate type warnings regarding enum assignment.
+
+ * coders/locale.c (WriteLOCALEImage): Use UndefinedException
+ rather than 0 in severity_list terminating entry in order to avoid
+ a type conversion warning.
+
+ * magick/image.c (SetImageChannelDepth): Depth parameter was being
+ returned rather than status. Oops!
+
+ * magick/effect.c (BlurScanline): Due to automatic casting
+ conventions, computation was being done (at least with SGI
+ compiler) as type `unsigned long` rather than `long` as it should
+ have been.
+
+ * coders/jpeg.c, coders/meta.c, coders/miff.c, coders/msl.c,
+ coders/palm.c, coders/pcd.c, coders/psd.c, coders/svg.c,
+ coders/tiff.c, coders/xcf.c, magick/render.c, : Quench many SGI
+ compiler warnings regarding variables which are initialized but
+ never used.
+
+ * magick/xwindow.h: Undef gravity defines so that enumerated type
+ is used instead.
+
+2003-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/log.c (LogMagickEvent): Windows system logging
+ functionality is not currently ported to work with Cygwin so
+ disable when compiling under Cygwin.
+
+ * magick/log.c (Win32EventlogOutput): Remove spurious comma in enum.
+
+ * wand/drawing_wand.h: Remove junk comment marker that I forgot to
+ remove.
+
+ * magick/studio.h: Provide prototypes for strlcpy and vsnprintf if
+ the system doesn't provide them in the requested compilation
+ environment.
+
+ * configure.ac: Add necessary standards compilance definitions to
+ magick_config.h.
+ Check for strlcpy and vsnprintf prototypes.
+
+ * Makefile.am (DOCDIRS): www/api/types does not exist anymore.
+
+2003-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Move multithread tests prior to libtool
+ configuration in case value of CC is changed. Otherwise libtool
+ gets confused and refuses to run.
+
+ * acinclude.m4 (ACX_PTHREAD): If using AIX CC `xlc` use `xlc_r`
+ for multithread compiler.
+
+ * coders/jpeg.c: Undef HAVE_STDLIB_H before including the
+ jpeg headers or else we get an already defined error/warning.
+
+2003-09-04 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick : Updated whole directory tree to achieve correct
+ compilation with Borland C++ Buider 6.0.
+
+2003-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (ClipPathImage): Remove MS-DOS line terminations
+ (actually, extra carriage returns) which somehow crept into
+ ClipPathImage.
+
+ * locale/C.mgk: Added message for "PNG library is too old".
+
+2003-09-04 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/transform.c (ProfileImage): Bugfix: conditional
+ compilation based on LCMS being present or not now works as
+ expected. An exception is thrown if LCMS is not present and
+ profile conversion is used.
+
+2003-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/txt.c (ReadTXTImage): Fix strlen() pointer type warning.
+
+ * magick/image.c (TextureImage): Fixed return with no value warning.
+
+ * magick/color.c (GetColorInfoArray): Decided that the const
+ return value was a bad idea. Therefore, the return type has been
+ made non-const.
+
+ * magick/magick.c (GetMagickInfoArray): Decided that the const
+ return value was a bad idea. Therefore, the return type has been
+ made non-const.
+
+ * tests/constitute.c, tests/rwblob.c, tests/rwfile.c : Define
+ MAGICK_IMPLEMENTATION since these test programs using some internal
+ extensions.
+
+ * configure.ac: Test C++ compiler for __func__ support.
+
+ * magick/log.h: Added GetCurrentFunction() macro to handle
+ __func__ support determination. Re-wrote GetMagickModule() macro
+ to use GetCurrentFunction(). Changes should allow compilation of
+ Magick++ when the C compiler supports __func__ but the C++
+ compiler does not.
+
+ * configure.ac: Changed from using HAS___func__ define to
+ HAS_C__func__ since this feature may be language sensitive.
+
+ * locale/C.mgk: Added missing JNGCompressionNotSupported message.
+
+2003-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (Generate8BIMAttribute): Fix sscanf argument
+ type mis-match.
+
+ * coders/ps3.c (ZLIBEncodeImage): Fix mis-classified
+ ZipLibraryIsNotAvailable error report.
+
+ * coders/url.c (RegisterURLImage): Only register URL format
+ support if libxml2 is available.
+
+ * coders/msl.c (RegisterMSLImage): Only register MSL format
+ support if libxml2 is available.
+
+2003-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/histogram.c (WriteHISTOGRAMImage): Remove a useless loop.
+
+ * coders/wpg.c: Applied patch from Fojtik Jaroslav to support
+ reading WPGs which use the EXT token.
+
+2003-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/color.c (HistogramToFile): Renamed static method
+ `Histogram` to `HistogramToFile` to make it more clear what this
+ function does.
+ (GetColorHistogram): Added new function to support retrieving a
+ color histogram of the image. A color histogram contains a count
+ of how many times each color occurs in the image.
+
+ * magick/image.c (GetImageChannelDepth): Return an `unsigned int`
+ rather than `long`.
+
+2003-08-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: Add support for CopyCyan, CopyMagenta,
+ CopyYellow, and CopyBlack, composition operators.
+
+ * magick/composite.c (CompositeImage): Added support for
+ CopyCyanCompositeOp, CopyMagentaCompositeOp,
+ CopyYellowCompositeOp, and CopyBlackCompositeOp, composition
+ operators.
+
+2003-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/*: Updated to current ImageMagick Wand API (minus a few
+ unimplemented functions).
+
+ * magick/image.c (TextureImage): Add status return because Wand API
+ wants it. Inherit is_grayscale status from texture image.
+
+ * magick/fx.c (SolarizeImage): Add status return because Wand API
+ wants it.
+
+ * magick/resource.c (SetMagickResourceLimit): Add status return
+ because Wand API wants it.
+
+ * magick/draw.c (DrawPeekGraphicContext): Now returns a
+ copy of the current DrawInfo context rather than returning
+ a pointer into the context stack. The user must destroy
+ this copy using DestroyDrawInfo() once it is no longer
+ needed.
+
+2003-08-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/filters/LIBRARY.txt: This file is necessary to
+ incorporate analyze.c into the static build. Without it the
+ build fails.
+
+2003-08-23 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/transform.c: ProfileImage updated to handle alpha
+ channels and grayscale images. Also optimized color profiling of
+ color mapped images and fixed a few bugs in profiling of CMYK
+ images.
+
+ * magic/locale_c.h: added MagickExport to prototype declaration of
+ GetLocaleMessageFromID in WriteLOCALEImage again. Please update
+ your locale coder.
+
+2003-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wpg.c: Applied patch from Fojtik Jaroslav to use the
+ GetMagicInfo() function to obtain the format of embedded images,
+ and to provide a default WPG palette if the WPG file does not
+ supply a palette.
+
+2003-08-22 William Radcliffe <billr@corbis.com>
+
+ * magick\gm_messages.bin locale_c.h transform.c: Fixed missing
+ message problem and added support for new lcms error handler.
+
+2003-08-21 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/attribute.c, magick/image.c, magick/command.c: Added
+ "clippath" option for clipping named Photoshop clipping paths,
+ increased precision in clipping path knots, added comments, and
+ fixed a few bugs resulting from moving TraceClippingPath function
+ from ImageMagick to GraphicsMagick. Still need to update some of
+ the documentation.
+
+ * magick/locale_c.h, magick/studio.h: added MagickExport to
+ declaration of GetLocaleMessageFromID and moved include of
+ magick/locale_c.h after declaration of MagickExport. This fixes a
+ link error in dynamic, DLL version.
+
+ * coders/locale.h: added MagickExport to prototype declaration of
+ GetLocaleMessageFromID in WriteLOCALEImage.
+
+2003-08-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/subroutines.pl (testRead): Ignore useless TIFF
+ warning so that 12-bit TIFF test passes.
+
+ * magick/constitute.c (ReadImage): Ensure that the reported image
+ magic string is that of the user-specified input file rather than
+ a temporary file prepared by an external delegate program.
+
+ * magick/command.c (ImportImageCommand): Since
+ DestroyExceptionInfo() now sets the destroyed exception signature
+ to an invalid value, GetExceptionInfo(exception) must be invoked
+ when the intention is to simply purge the exception. This fix
+ resolves an abort when executing `gm import`.
+
+2003-08-18 William Radcliffe <billr@corbis.com>
+
+ * magick\gm_messages.bin locale_c.h transform.c: Updates that
+ add latest enhancments by Lars to color management code in
+ ProfileImage.
+
+2003-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wpg.c: Incorporated patch from Fojtik Jaroslav to support
+ rendering embedded WMFs.
+
+2003-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageChannelDepth): New function to transform
+ the specified channel so it fits the specified modulus depth.
+
+ * magick/blob.c (BlobToImage): Skip calling SetImageInfo() if
+ magick is already set.
+
+2003-08-18 William Radcliffe <billr@corbis.com>
+
+ * PerlMagick/Magick.xs: Some fixes to get PerlMagick compiling
+ again due to new ID based error macros.
+
+2003-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/error.h (enum): Remove spurious comma.
+
+2003-08-17 William Radcliffe <billr@corbis.com>
+
+ * coders\png.c: Had to modify a few exception calls to work with
+ newest macros.
+
+2003-08-17 William Radcliffe <billr@corbis.com>
+
+ * coders\locale.c magick/error.h locale.c locale_c.h studio.h:
+ The LOCALEH header file generator now adds an MGK_ prefiix to
+ all the ID defines as part of a fix to support the new error
+ and exception macros cross platform.
+
+2003-08-16 William Radcliffe <billr@corbis.com>
+
+ * wand\magick_wand.c pixel_wand.c: The wand api code was totally
+ left out of the large macro conversion below as an oversight.
+
+2003-08-15 William Radcliffe <billr@corbis.com>
+
+ * .\coders art.c avi.c avs.c bmp.c caption.c clipboard.c cmyk.c
+ cut.c dcm.c dib.c dps.c dpx.c emf.c ept.c fax.c fits.c fpx.c gif.c
+ gradient.c gray.c hdf.c histogram.c html.c icon.c jbig.c jp2.c
+ jpeg.c label.c locale.c logo.c map.c mat.c matte.c meta.c miff.c
+ mono.c mpc.c mpeg.c msl.c mtv.c mvg.c null.c otb.c palm.c pcd.c
+ pcl.c pcx.c pdb.c pdf.c pict.c pix.c png.c pnm.c preview.c ps.c
+ ps2.c ps3.c psd.c pwp.c rgb.c rla.c rle.c sct.c sfw.c sgi.c
+ stegano.c sun.c svg.c tga.c tiff.c tile.c tim.c topol.c ttf.c txt.c
+ uil.c url.c uyvy.c vicar.c vid.c viff.c wbmp.c wmf.c wpg.c x.c xbm.c
+ xc.c xcf.c xpm.c xtrn.c xwd.c yuv.c .\magick\animate.c annotate.c
+ blob.c cache.c cache_view.c color.c color.h command.c compress.c
+ constitute.c decorate.c delegate.c display.c draw.c effect.c
+ enhance.c error.c error.h fx.c gm_messages.bin image.c list.c
+ locale.c locale_c.h log.c mac.c magic.c magick.c module.c montage.c
+ nt_feature.c paint.c quantize.c registry.c render.c resize.c
+ segment.c semaphore.c shear.c signature.c static.c static.h
+ stream.c studio.h tempfile.h transform.c type.c utility.c widget.c
+ xwindow.c : Changes to support ID based message access and checking
+ all message usages. The main thing that was done was to remove all
+ the quotes around the "tags" used to lookup messages defined in
+ the locale\C.XML file. Macros were added to error.h to allow the
+ code to be compiled for either string based access or binary ID
+ based access. Using binary ID's will cause the code to fail to
+ compile if a message does not exist in C.XML, since no ID will be
+ created for a missing message. This change then allowed us to
+ easily track down all the messages that were "missing" or not
+ being accessed properly. The problems were massive and took many
+ days to resolve. I have left the code compiling in ID mode to keep
+ things in sync going forward and also because it makes message
+ lookup instantaneous. An ID is just an index into and array of
+ char *'s. There is still a lot of cleanup work remaining, but this
+ is a very good start.
+
+2003-08-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/error.c (GetLocaleExceptionMessage): Add check to avoid
+ duplicating severity prefix.
+
+ * magick/log.c (LogMagickEvent): Incorporated fix from Bill
+ Radcliffe to enable logging control flags to work properly again.
+
+ * NEWS: Updated news.
+
+ * magick/blob.c (OpenBlob): Rewind file descriptor so that first
+ read is at zero offset. This fixes reading GIFs via a
+ user-provided file handle.
+
+2003-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (GetImageDepth): Extend so that the actual
+ minimum depth required to represent the image is
+ returned. Previously only the values 8, 16, and 32 were
+ returned. This means that a value of one is returned for a
+ monochrome image. Also fixed a bug in that the pixels were
+ incremented while the depth was incremented, resulting in the
+ first image pixels not being properly evaluated for depth.
+ (SetImageDepth): Extend to support converting the image to
+ arbitrary modulus depths.
+ (GetImageChannelDepth): New function to obtain the modulus depth
+ for a specified image channel.
+
+2003-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/draw.c (MvgAutoWrapPrintf): StreamError reported when
+ DrawError was intended.
+
+ * coders/logo.c (ReadLOGOImage): Report FileOpenError rather than
+ BlobError if requested image does not exist.
+
+2003-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/cache.c (PersistCache): If HAVE_SYSCONF and _SC_PAGE_SIZE
+ are defined, then assume that sysconf works and don't use legacy
+ getpagesize() function.
+
+ * magick/studio.h (_XOPEN_SOURCE): Should be defined as 600 in
+ order to match _POSIX_C_SOURCE=200112L according to the Single
+ UNIX Specification v3. This is necessary for the vsnprintf
+ prototype to be visible.
+
+ * magick/attribute.c (ReadByte): Fix compilation warnings due to
+ casting `unsigned char *` to `char *` by changing function
+ definition to accept `unsigned char *` instead.
+
+ * magick/error.h (UndefinedException): UndefinedException should
+ be ExceptionType, not ExceptionBaseType.
+
+ * magick/magick.c (IsValidFilesystemPath): Eliminate warning about
+ unused function when UseInstalledMagick is defined.
+
+ * magick/error.c (ThrowLoggedException): Fix improper parameters
+ passed to LogMagickEvent() when reason is not available.
+
+003-08-07 William Radcliffe <billr@corbis.com>
+
+ * magick/log.c, log.h: Added ability to log by either severity
+ or by category of event. Made the defualt on windows to log all
+ fatal errors, errors, and warnings to the event log. This will
+ include anything generated by exceptions currently, but not any
+ normal "informational" logging.
+
+2003-08-07 William Radcliffe <billr@corbis.com>
+
+ * magick/log.c, log.h: Translation of event codes to mask vals
+ was not working. Code was left out of last update. It is now in.
+
+2003-08-07 William Radcliffe <billr@corbis.com>
+
+ * magick/error.c: Protect against NULL string passed into the
+ message lookup function.
+
+2003-08-07 William Radcliffe <billr@corbis.com>
+
+ * magick/locale.c: Switched use of IsAccessible to nonloggging
+ version to prevent recursive problems.
+
+2003-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/Makefile.am (noinst_HEADERS): Distribute locale_c.h.
+
+ * locale/Makefile: Output locale_c.h.
+
+ * utilities/gm.c (main): Fix typo in Unix InitializeMagick
+ invocation.
+
+ * configure.ac: Use ACX_PTHREAD pthreads test macro.
+
+ * magick/(semaphore.c,spinlock.h,studio.h): Change HasPTHREADS
+ conditional define to HAVE_PTHREAD.
+
+ * magick/Makefile.am (noinst_HEADERS): Include spinlock.h in
+ distribution.
+
+2003-08-06 William Radcliffe <billr@corbis.com>
+
+ * contrib\win32\ATL7\ImageMagickObject/ImageMagickObject.cpp,
+ ImageMagickObject_.h, ImageMagickObject.def, ImageMagickObject.rc
+ gm.rc: Changes to get things compiling again since all windows
+ specific logging support has been eliminated. The special build
+ script BuildImageMagickObject.cmd now compiles the message file
+ for resource based messages. The result is in gm_messages.bin.
+ The script also generates a special version of gm.exe that uses
+ the COM dll as a regular DLL and links to it. This is the long
+ desired Moby DLL build idea.
+
+ * magick/error.c, magick/error.h, magick/log.c, magick/log.h:
+ Upgrade of logging system to take over previous special logging
+ code for windows in nt_base.c. The new logic provides logging of
+ events to the debug api and the windows event log and also
+ provides a generic text file logging method.
+
+ * magick/gm_messages.bin, magick/ImageMagick.rc: New compiled
+ message file based on data in locale\C.mgk. RC file modified to
+ include this as a resource.
+
+ * magick/locale.c, magick/locale_c.h: locale_c.h is generated by
+ the LOCALEH format of the locale coder. The logic in locale.c uses
+ the tables in the header lookup messages. On windows, all the
+ messages are stored as resources, while on UNIX they remain in a
+ string table.
+
+ * locale/C.mgk: Removed duplicate messages and added some new
+ default messages that help to create a complete set of severity
+ strings.
+
+ * magick/command.c, magick/magick.c: Get rid compiler warnings.
+
+2003-08-05 William Radcliffe <billr@corbis.com>
+
+ * magick/command.c, magick/gm.c: Application level changes to
+ implement the client name - filename changes. The client name can
+ now be anything that the application wants and has nothing to do
+ with the saved filename of the application.
+
+ * magick/nt_base.c, magick/nt_base.h, magick/magick.c: Ripped out
+ old nt specific debugging and logging logic. Moving to the
+ standard logging. New and major revisions to InitializeMagick to
+ make the code more maintainable, reliable, and reaable. It should
+ be functionally identical, but implements the new split client
+ name and filename methododology.
+
+ * magick/utility.c, magick/utility.h: Added a couple of new
+ routines to support splitting the overloaded use of the client
+ name and client filename.
+
+ * coders/xtrn.c: Minor code cleanup
+
+2003-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Copyright.txt: Added missing copyright notice which is required
+ due to copying the rlecomp manual page into ImageMagick.
+
+ * doc/config_files.imdoc: Started documentation for configuration
+ files.
+
+ * magick/xwindow.c (XSignalHandler): Ensure that segment_info is
+ non-null before attempting to use it. Much thanks to John Cristy
+ for bringing this problem to our attention.
+
+2003-08-05 William Radcliffe <billr@corbis.com>
+
+ * coders/locale.c: Added several new formats to this coder to
+ generate windows message resource format messages and also to
+ generates a new header file format that will support a table based
+ version of the other magick/locale.c.
+
+ * coders/xtrn.c: Minor code cleanup
+
+2003-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Only configure C and C++ libtool tags.
+
+ * PerlMagick/t/reference/composite/*.miff: Added some composition
+ test reference images. These reference images will serve as
+ placeholders until better composition tests can be figured out.
+ It is not clear from the documentation what some of the
+ composition operators are supposed to do.
+
+2003-08-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * README.txt: Add documentation regarding using TRIO.
+
+ * configure.ac: Test for TRIO library if vsnprintf is not
+ available.
+
+ * magick/studio.h: Remap vsnprintf to trio_vsnprintf if TRIO is
+ available.
+
+ * coders/topol.c, coders/wmf.c, magick/magick.c, magick/nt_base.c,
+ magick/resource.c: Use traditional C comment form in C source
+ files.
+
+2003-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/log.h (LogEventType::AllEvents): Increase the value of
+ AllEvents so that it spans the complete positive range of a signed
+ integer.
+
+ * magick/xwindow.c, magick/xwindow.h: Incorporate patch from John
+ Cristy's ImageMagick to eliminate conditional dependence of
+ magick/xwindow.h on <X11/extensions/XShm.h>.
+
+ * magick/magick_config_api.h.in: HasSharedMemory define no longer
+ needed.
+
+2003-07-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/programming.html: Update Rmagick URL.
+
+ * GraphicsMagick.spec.in : Update according to instructions from
+ Troy Edwards.
+
+2003-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * GraphicsMagick.spec.in: Replaced GraphicsMagick.spec with
+ GraphicsMagick.spec.in, which is configured to produce
+ GraphicsMagick.spec.
+
+ * configure.ac: Configure GraphicsMagick.spec.
+
+2003-07-29 Troy Edwards <vallimar@sexorcisto.net>
+
+ * GraphicsMagick.spec: Updated to CVS build. Added the
+ GraphicsMagickWand files to the spec. Only try to remove the
+ unneeded perl package files if we are using PerlMagick.
+
+2003-07-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * GraphicsMagick.spec: Added RPM spec file authored by Troy
+ Edwards <vallimar@sexorcisto.net>.
+
+ * NEWS: Add note regarding EXIF fix.
+
+ * magick/attribute.c (GenerateEXIFAttribute): Look for the profile
+ name "EXIF" rather than "APP1".
+
+2003-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick_config_api.h.in: XWindowInfo structure in
+ xwindow.h needs HasSharedMemory define.
+
+ * magick/xwindow.c, magick/xwindow.h: Move inclusion of
+ <X11/extensions/shape.h> to xwindow.c.
+
+ * coders/dps.c, magick/xwindow.h: Move DPS includes to
+ coders/dps.c
+
+ * coders/Makefile.am: Substituted values are also set as
+ make variables, so use variables rather than substitutions.
+
+ * magick/log.c (GetLogBlob): MAGICK_HOME needs to take
+ precedence over the client path for the uninstalled build.
+
+ * magick/type.c (GetTypeBlob): MAGICK_HOME needs to take
+ precedence over the client path for the uninstalled build.
+
+ * magick/blob.c (GetConfigureBlob): MAGICK_HOME needs to take
+ precedence over the client path for the uninstalled build.
+
+ * magick/module.c (FindMagickModule): MAGICK_HOME needs to take
+ precedence over the client path for the uninstalled build.
+
+2003-07-24 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/attribute.c (TraceClippingPath): Improvements to clipping
+ path parsing.
+
+2003-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/cache.c: Disable the Windows open() extensions when
+ compiling using Borland C++.
+
+ * magick/log.c (LogMagickEvent): Unlock semaphore before
+ returning.
+
+ * ltdl/ltdl.h: Updated to latest CVS version.
+
+ * ltdl/ltdl.c: Updated to latest CVS version.
+
+ * Libtool: Updated to use latest CVS libtool.
+
+2003-07-17 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick: Contributed initial Borland C++ Builder 6.0 build
+ environment.
+
+2003-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/color.c (GetColorInfoArray): Added a function to access
+ the color definition list as an array.
+ (GetColorList): Added access locks to ensure that list is not
+ re-ordered while it is being traversed.
+
+ * www/Magick++/Image.html: Add some more information regarding raw
+ pixel access.
+
+2003-07-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/GraphicsMagickWand.pc.in (Cflags): Remove LFS_CPPFLAGS.
+
+ * wand/GraphicsMagickWand-config.in: Remove LFS_CPPFLAGS.
+
+ * magick/GraphicsMagick.pc.in (Cflags): Remove LFS_CPPFLAGS.
+
+ * magick/GraphicsMagick-config.in: Remove LFS_CPPFLAGS.
+
+ * configure.ac: Logic for setting LFS_CPPFLAGS was incomplete.
+
+ * coders/topol.c: Updated topol coder contributed by Jaroslav
+ Fojtik. Topol is coming to life!
+
+2003-07-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.h: Add a typedef for ssize_t
+
+ * magick/deprecate.h: ExtendedSignedIntegralType and
+ ExtendedUnsignedIntegralType are now deprecated types so they are
+ moved to deprecate.h. Existing code which uses these types should
+ continue to work.
+
+ * magick/blob.c (MapBlob): Change `offset` parameter from type
+ off_t to magick_off_t so that it is not LFS dependent.
+
+ * magick/cache.c (GetPixelCacheArea): Return magick_off_t.
+ (PersistCache): Change `offset` parameter to type magick_off_t.
+
+ * magick/cache.h (NexusInfo): Change `length` type from
+ ExtendedSignedIntegralType to magick_off_t.
+ (CacheInfo): Change `offset` and `length` types from
+ ExtendedSignedIntegralType to magick_off_t.
+
+ * magick/blob.c (BlobToFile): Use ssize_t rather than
+ ExtendedSignedIntegralType for count.
+ (TellBlob): Return magick_off_t rather than
+ ExtendedSignedIntegralType.
+
+ * configure.ac: Check for a ssize_t type.
+
+ * magick/blob.h (_BlobInfo): Change `offset` and `size` members
+ from ExtendedSignedIntegralType to magick_off_t.
+
+ * magick/blob.c (GetBlobSize): Return magick_off_t rather than
+ ExtendedSignedIntegralType.
+ (SeekBlob): Accept and return magick_off_t rather than
+ ExtendedSignedIntegralType.
+
+2003-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/monitor.c (MagickMonitor): Change `quantum` argument from
+ type ExtendedSignedIntegralType to magick_int64_t. Change `span`
+ argument from ExtendedUnsignedIntegralType to magick_uint64_t.
+
+ * magick/xwindow.c (XMagickMonitor): Change `quantum` argument from
+ type ExtendedSignedIntegralType to magick_int64_t. Change `span`
+ argument from ExtendedUnsignedIntegralType to magick_uint64_t.
+
+ * magick/widget.c (XMonitorWidget): Change `quantum` argument from
+ type ExtendedSignedIntegralType to magick_int64_t. Change `span`
+ argument from ExtendedUnsignedIntegralType to magick_uint64_t.
+
+ * magick/studio.h (QuantumTick): Change typecast from
+ ExtendedSignedIntegralType to magick_int64_t.
+
+ * magick/resource.c (AcquireMagickResource): Change `size`
+ argument type from ExtendedSignedIntegralType to magick_int64_t.
+ (LiberateMagickResource): Change `size` argument type from
+ ExtendedSignedIntegralType to magick_int64_t.
+
+ * magick/utility.c (FormatSize): Change `size` argument type from
+ ExtendedSignedIntegralType to magick_int64_t.
+
+ * magick/nt_base.c: Change MagickOffset to magick_off_t.
+
+ * magick/studio.h (magick_off_t): Change MagickOffset to magick_off_t.
+
+ * coders/topol.c: Insert dummy member into palettRAS structure
+ since Visual C++ doesn`t seem to handle empty structures.
+
+ * wand/GraphicsMagickWand.pc.in (prefix): Pass LFS CPPFLAGS.
+
+ * wand/GraphicsMagickWand-config.in: Pass LFS CPPFLAGS.
+
+ * wand/Makefile.am: Fix include path.
+
+ * magick/GraphicsMagick.pc.in (prefix): Pass LFS CPPFLAGS.
+
+ * magick/magick_config_api.h.in: Pass LFS configuration options
+ until the API is fixed so that it is not LFS sensitive anymore.
+
+ * magick/GraphicsMagick-config.in: Pass LFS CPPFLAGS.
+
+ * PerlMagick/Makefile.PL.in: Pass LFS CPPFLAGS.
+
+ * magick/Makefile.am: Install magick_types.h.
+
+ * magick/api.h: Include magick_types.h.
+
+ * magick/studio.h: Include magick_types.h rather than integral_types.h.
+ * VisualMagick/magick/magick_types.h.in: New header file (replacing
+ integral_types.h) to contain CPU and system-dependent primitive
+ typedefs.
+
+ * magick/magick_types.h.in: New header file (replacing
+ integral_types.h) to contain CPU and system-dependent primitive
+ typedefs.
+
+ * configure.ac: Use AC_SYS_LARGEFILE to test for large file
+ options. Update to determine integral typedefs for current CPU and
+ compiler options. Configure magick_types.h.
+
+ * magick/attribute.c (TraceClippingPath): Apply patch from Lars
+ Ruben Skyum which fixes clipping path parsing for paths generated
+ by Adobe software which pre-dates the Photoshop file format
+ specification.
+
+2003-07-08 William Radcliffe <billr@corbis.com>
+
+ * magick/semaphore.c: Modified the way the system handles the
+ initialization of Win32 critical sections to use a spin lock
+ on WIn32 to bootstrap the initialization of all other crtical
+ sections. This is not an issue on UNIX since static init is used.
+
+ * magick/magic.c module.c magick.c log.c resource.c constitute.c
+ color.c cache.c delegate.c registry.c type.c: Small modifications
+ were made to eliminate the side effect of unlocking semaphores
+ as part of the releasing procedure. This also eliminated the
+ apparent bug of the system double locking certain semaphores.
+ The locked flag should now not be needed, but remains in place
+ for the time being as an added safegaurd.
+
+2003-07-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * png.c: added missing #ifdef JNG_SUPPORTED/#endif directives.
+
+2003-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS: Updated news to include fixes and enhancements since the
+ 1.0 release.
+
+2003-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/semaphore.c (UnlockSemaphoreInfo): Bugfix, modify
+ the `locked` flag while still under protection of the lock.
+ This fix is necessary for thread-safety.
+
+2003-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (ReadJPEGImage): Conditionally copy exception.
+
+ * wand/Makefile.am (noinst_HEADERS): Need to distribute
+ magick_compat.h.
+ (EXTRA_DIST): Need to distribute GraphicsMagickWand-config.1.
+
+ * coders/wmf.c (ipa_bmp_draw): Use CopyException.
+ (ipa_device_begin): Use CopyException.
+ (lite_font_map): Use CopyException.
+ * coders/jpeg.c (ReadJPEGImage): Use CopyException.
+ * magick/image.c (GetImageException): Use CopyException.
+ * magick/constitute.c (WriteImages): Use CopyException.
+ * Makefile.am (DIST_SUBDIRS): wand needs to be included in
+ distribution.
+
+2003-06-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/static.c (RegisterStaticModules): Invoke
+ RegisterTOPOLImage.
+
+ * magick/magick.h (MagickInfo): Add member usage comments.
+
+ * magick/error.c (CatchException): Restore saved errno from
+ exception->error_number.
+ (CopyException): Copy error_number.
+ (DestroyExceptionInfo): Reset error_number to zero.
+ (GetExceptionInfo): Initialize error_number to zero.
+ (ThrowException): Save errno to exception-> error_number.
+ (ThrowLoggedException): Save errno to exception-> error_number.
+
+ * magick/error.h (ExceptionInfo): Borrow John Cristy's idea and
+ add a error_number member to ExceptionInfo to save the current
+ errno value. Otherwise CatchException may use some random errno.
+
+ * coders/Makefile.am: Build topol.c.
+
+ * coders/topol.c: Added initial TOPOL X image coder which is under
+ development by Jaroslav Fojtik. Not working yet.
+
+2003-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pwp.c (ReadPWPImage): Ensure that image is initialized
+ before invoking ThrowReaderException.
+
+ * magick/image.c (CloneImage): Use CopyException.
+
+ * magick/error.c (CopyException): Add function to support copying
+ ExceptionInfo structures.
+
+ * magick/error.h (ExceptionInfo): Replaced recently-added `whence`
+ member with module, function, and line members in order to keep
+ the information seperate, and match the parameters used by the
+ logging system.
+ (ThrowException): Log thrown exceptions.
+
+ * magick/error.c (ThrowLoggedException): New function used to
+ throw an exception, while recording and logging the location
+ where the exception is thrown.
+
+ * doc/options.imdoc (operation): Document TemporaryFile and
+ Exception events.
+
+ * magick/log.c (LogMagickEvent): Support logging ExceptionEvent.
+
+ * PerlMagick/Magick.xs: Added "Exception" event type.
+
+ * magick/log.h (LogEventType): Added ExceptionEvent.
+
+2003-06-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/error.c (ThrowException): Handle `whence`
+ member. MagickFreeMemory already checks for null pointer so don't
+ check again.
+ (DestroyExceptionInfo): Handle `whence` member. MagickFreeMemory
+ already checks for null pointer so don't check again.
+
+ * magick/error.h (ExceptionInfo): Add a `whence` member to support
+ the ability to record where the exception is was thrown.
+
+ * VisualMagick/installer: Install Wand files.
+
+2003-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (GetConfigureBlob): GetConfigureBlob should always
+ return a value.
+
+ * magick/type.c (GetTypeBlob): GetTypeBlob should always return a
+ value.
+
+ * magick/log.c (GetLogBlob): GetLogBlob should always return
+ a value.
+
+ * magick/magick.c (GetMagickInfoArray): Fixed array memory
+ allocation and clearing bug. Eliminate warnings.
+
+2003-06-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/files-configs.isx: For a static
+ build, install the configuration files directly into the
+ application directory.
+
+ * VisualMagick/installer/inc/uninstallrun-unregister-com.isx
+ (Filename): Change ImageMagickObject.dll path.
+
+ * VisualMagick/installer/inc/run-register-com.isx (Filename):
+ Change ImageMagickObject.dll path.
+
+ * VisualMagick/installer/inc/files-com.isx (Source): Install
+ ImageMagickObject.dll and MagickCMD.exe in the application
+ directory alongside gm.exe and the CORE DLLs.
+
+ * INSTALL-unix.txt: Add additional information regarding LZW.
+
+ * VisualMagick/magick/magick_config.h.in: Add additional notes
+ regarding UNISYS LZW patent.
+
+ * PerlMagick/Magick.xs: Applied Dissolve composite operator fix
+ obtained from from John Cristy's ImageMagick which ensures that an
+ unused matte channel is set to Opaque, and uses this knowledge to
+ simplify the math.
+
+ * VisualMagick/configure/configure.cpp: The `wand` library has a
+ linkage dependency on the `magick` library. Also don't include
+ the magick subdirectory so that headers must be included like
+ <magick/api.h> for safety.
+
+ * coders/xtrn.c: Fix magick header inclusion.
+
+ * lcms\src\cmserr.c: Fix magick header inclusion.
+
+2003-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Fix to formatting. Fix spelling of origin.
+
+ * PerlMagick/t/bzlib/read.t: Add test for reading BZipped file.
+
+ * PerlMagick/t/subroutines.pl (testRead): Skip testing reads
+ of compressed BLOBs because reading compressed BLOBs is not
+ supported yet.
+
+ * coders/bmp.c (ReadBMPImage): Only validate the file size value
+ for compressed BMPs.
+
+ * VisualMagick/wand, wand: First stab at building the Wand API
+ under Visual C++. Still does not build as a DLL.
+
+2003-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/static.h: Add prototypes for RegisterXTRNImage and
+ UnregisterXTRNImage.
+
+ * Makefile.am (DISTDIRS): Don't distribute the `guide`
+ subdirectory. It is available for checkout from CVS.
+
+ * www: Utilities documentation is updated from <imdoc> masters.
+ Formatting could be improved, but the content seems ok.
+
+ * doc/environment.imdoc: New file to describe environment
+ variables.
+
+ * coders/cut.c (ReadCUTImage): Use MagickAllocateMemory and
+ MagickFreeMemory rather than malloc and free.
+
+ * doc/gmdoc2html: Add GraphicsMagick styling to utility web pages.
+
+ * doc/Makefile: Additional documentation Makefile enhancements.
+
+ * AUTHORS: New file to acknowledge significant contributors
+ to the software. If an author is not listed here, please let
+ us know.
+
+ * configure.ac: test -a is not POSIX compliant.
+
+2003-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc: Source documentation for `gm` is now available via a `doc`
+ CVS module. A Makefile is provided which formats the
+ documentation and installs it into the `www` and `utilities`
+ subdirectories.
+
+2003-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand: Added Magick Wand library available via
+ -lGraphicsMagickWand and <wand/wand_api.h>. Use
+ GraphicsMagickWand-config or GraphicsMagickWand.pc to obtain the
+ compilation options required to use the library. Magick Wand is
+ authored by John Cristy. Magick Wand is provided as a separate
+ library from -lGraphicsMagick in order to assure the stability of
+ the core GraphicsMagick library while allowing Magick Wand to
+ to evolve.
+
+ * images: Replace existing logo images with cleaner ones.
+
+ * www: Update links to point to updated logo images.
+
+ * logos: New CVS directory to contain master logos.
+
+ * scripts/txt2html: Updated inline logo image link.
+
+ * scripts/format_c_api_docs: Updated inline logo image link.
+
+ * version.sh: Support versioning all libraries independently.
+
+ * coders/meta.c: Prefix include paths for safety.
+
+ * magick/image.h: (TransmitType) Removed unused enumeration.
+ (ProfileType) Removed unused enumeration.
+ (QuantumType) Moved enumeration to constitute.h
+ (StorageType) Moved enumeration to constitute.h
+
+ * magick/draw.c (DrawPeekGraphicContext): Added function to peek
+ at head of drawing context stack (function added for ImageMagick
+ compatability).
+
+ * magick/image.c (CycleColormapImage): Change return type from
+ `void` to `unsigned int` so that error status is returned to user.
+ (DescribeImage): Change return type from
+ `void` to `unsigned int` so that error status is returned to user.
+
+ * magick/list.c (ReplaceImageInList): Incorporated function from
+ John Cristy's ImageMagick to replace current image in the list.
+
+ * coders/sgi.c (ReadSGIImage): Applied patch from John Cristy's
+ ImageMagick to save the compression type for SGI images.
+
+2003-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/txt.c (WriteTXTImage): Apply patch from John Cristy's
+ ImageMagick to observe image depth while writing pixel colors.
+ This patch is not applied to the 1.0 branch because it represents
+ an output format change which could break a dependent application.
+ (IsTXT): Recognize files written by the TXT coder.
+ (ReadTXTImage): Reject files written by the TXT coder until support
+ for reading these files is implemented.
+ (IsTXT): Ensure that sscanf doesn't read outside of provided data
+ by using a fixed size buffer.
+
+2003-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Don't add -lfpx to LIBS while configuring
+ because the C compiler may fail to link with it in later
+ tests.
+
+2003-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: RotateImage is documented to take
+ `degrees` argument, not `degree`. SwirlImage is documented to
+ take `degrees` argument, not `degree`. SolarizeImage is
+ documented to take a `threshold` argument, not `factor`. Wave is
+ documented to take `amplitude` and `wavelength` arguments. Don't
+ transform colorspace to RGB when retrieving `pixel` color value.
+ Release memory acquired to store `length` pointer. Picked up
+ memory leak fix related to `SV **reference_vector` variable from
+ John Cristy's ImageMagick.
+
+ * configure: Incorporate patch to handle inline better.
+
+ * magick/utility.c (GetToken): Adjust code to avoid "end-of-loop
+ code not reached" warning.
+
+ * magick/log.c (GetLogBlob): Eliminate warning regarding
+ unreached code.
+
+ * magick/command.c (AnimateImageCommand): Eliminate warning regarding
+ unreached code.
+ (ConvertImageCommand): Eliminate warning regarding
+ unreached code.
+ (ImportImageCommand): Eliminate warning regarding
+ unreached code.
+
+ * magick/type.c (GetTypeBlob): Eliminate warning regarding
+ unreached code.
+
+ * magick/blob.c (GetConfigureBlob): Eliminate warning regarding
+ unreached code.
+
+ * coders/meta.c (super_fgets): Eliminated warnings regarding
+ comparison and return of incompatible pointer types.
+ (super_fgets_w): Eliminated warnings regarding
+ comparison and return of incompatible pointer types.
+
+ * magick/command.c (ConvertImageCommand): Eliminate warnings
+ noticed when using Sun's compiler.
+
+2003-06-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * acinclude.m4: Add `#undef inline` in front of C++ tests.
+
+ * coders/x.c (RegisterXImage): Only register the X coder if HasX11
+ is defined.
+
+2003-06-07 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/image.c (GetImageGeometry) Y was a function of width
+ instead of height when processing EastGravity or WestGravity
+ (bug report from Cristy).
+
+2003-06-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (LocaleNCompare): Documented that comparison is
+ case-insensitive.
+ (LocaleCompare): Documented that comparison is case-insensitive.
+
+ * magick/log.c (ParseEvents): LocaleNCompare already does
+ case-insensitive compare so lower-casing is not necessary.
+
+ * Magick++: Updates to cause exceptions to be thrown if a bad
+ geometry specification is supplied.
+
+2003-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/log.c (ReadConfigureFile): Move event parsing to
+ ParseEvents funtion.
+ (SetLogEventMask): Move event parsing to
+ ParseEvents funtion.
+
+ * magick/utility.c (GetGeometry): Validate that the geometry
+ string only contains valid characters.
+
+ * PerlMagick/t/subroutines.pl (testMontage): It seems that passing
+ an empty set of options to the SetImage method corrupts the image
+ options (surely a PerlMagick bug), so don't invoke SetImage unless
+ there are options to set.
+
+2003-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (VersionCommand): Add build information to
+ version output.
+
+ * configure.ac: Save configure/build parameters for later use in
+ version output.
+
+2003-06-04 William Radcliffe <billr@corbis.com>
+
+ * coders/meta.c: Added some casts to make things compile better.
+
+2003-06-03 William Radcliffe <billr@corbis.com>
+
+ * coders/meta.c: Was broken due to editing mistakes as well
+ as inherent incompatability with MagickReallocMemory macro.
+
+2003-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xpm.c (RegisterXPMImage): Module registration for PICON
+ should have been XPM. Thanks to John Cristy for noticing this
+ bug.
+
+ * coders/psd.c (ReadPSDImage): Applied John Cristy's patch to fix
+ a index calculation bug which is evident when QuantumDepth>8.
+
+2003-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/meta.c: Eliminated some compiler warnings.
+
+ * magick/transform.c (ProfileImage): Eliminated some compiler
+ warnings.
+
+ * magick/static.c (RegisterStaticModules): Invoke
+ RegisterXTRNImage if _VISUALC_ is defined.
+
+2003-06-02 William Radcliffe <billr@corbis.com>
+
+ * utilities/gm.c: made -format work again but had to add off flag
+ to MagickCommand to maintain backward compatability with previous
+ versions of GM.
+
+ * magick/command.c: Added flag to tell MagickCommand whether GM is
+ expected to process metadata requests. The COM object *always* does.
+
+ * magick/transform.c: Added error handling, memory leak avoidance
+ and performanc enhancment.
+
+2003-06-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * NEWS: Added Bug Fixes item with info about the JNG encoder fix.
+
+2003-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS: Listed significant changes (thus far) in version 1.1.
+
+ * version.sh: Updated LIBRARY_CURRENT and LIBRARY_REVISION since
+ some command.c interfaces have changed, and a new interface has
+ been added. The only user of these interfaces should be `gm` but
+ it always pays to be careful.
+
+ * utilities/gm.c (main): Use MagickCommand.
+
+ * magick/command.c (MagickCommand): New function to provide
+ API-level command access to the command functions provided by the
+ GM utility with an interface similar to ConvertImageCommand.
+ (AnimateImageCommand): Changed function arguments to match
+ ConvertImageCommand.
+ (ConjureImageCommand): Changed function arguments to match
+ ConvertImageCommand.
+ (DisplayImageCommand): Changed function arguments to match
+ ConvertImageCommand.
+ (ImportImageCommand): Changed function arguments to match
+ ConvertImageCommand.
+
+ * libxml/libxml2.def: Remove LIBRARY line since Visual C++ 6.0
+ doesn't like that the build library doesn't match the name
+ specified by LIBRARY.
+
+2003-05-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (GetMagickInfoArray): Resolve thread-safety
+ issue by accessing magick_list directly under the protection of a
+ lock rather than using the pointer returned by GetMagickInfo.
+ Added error handling for insufficient memory.
+
+ * coders/tile.c (RegisterTILEImage): Added a usage note in formats
+ listing.
+
+ * coders/viff.c (RegisterVIFFImage): Module definition for "XV"
+ was missing.
+
+ * coders/ps2.c (RegisterPS2Image): Module definition for "PS2" was
+ missing.
+
+ * coders/wmf.c (RegisterWMFImage): Added usage note in formats
+ listing.
+
+ * coders/xpm.c (RegisterXPMImage): Hide PM alias for XPM in the
+ formats listing.
+
+ * coders/logo.c (RegisterLOGOImage): Hide registrations for
+ GRANITE, LOGO, and NETSCAPE in the formats listing.
+
+ * coders/jpeg.c (RegisterJPEGImage): Module definition for "JPEG"
+ was missing.
+
+ * coders/html.c (RegisterHTMLImage): Module definition for "HTML"
+ was missing.
+
+ * coders/bmp.c (RegisterBMPImage): Module names for "BMP2" and
+ "BMP3" should be "BMP".
+
+2003-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (GetMagickInfoArray): New function to return
+ MagickInfo array.
+ (ListMagickInfo): Updated to use GetMagickInfoArray.
+ (ListModuleMap): New function to list module map to a file.
+
+ * utilities/gm.c: Centered the file header and made note of this
+ stupendously significant accomplishment.
+
+ * magick/command.c: Added a `-list modulemap` option. Added plural
+ forms of other list options for people who are are not limited to
+ the singular. Also `-list font` and `-list fonts` now work for
+ people who think in terms of fonts rather than type.
+
+2003-05-30 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * MNG encoder failed to set the JNG bit in the simplicity profile.
+
+ * MNG encoder failed to write FRAM chunks when all images were JNG.
+
+ * JNG encoder wrote the wrong alpha_sample_depth for opaque images.
+
+2003-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magic.c (ReadConfigureFile): Removed bogus embedded magic
+ data and ensured that errors with loading magic.mgk propogate to
+ the top.
+
+ * magick/constitute.c (ReadImage): When building delegate error
+ report, handle the case where the filename is empty (such as for
+ "LOGO:").
+
+ * coders/png.c (WritePNGImage): Ensure that most severe exception
+ is reported via exception argument.
+ (ReadMNGImage): Ensure that most severe exception is reported via
+ exception argument.
+
+ * magick/command.c (ConvertImageCommand): Ensure that most severe
+ exception is reported via exception argument.
+ (CompositeImageList): Ensure that most severe exception is
+ reported via exception argument.
+ (CompositeImageCommand): Ensure that most severe exception is
+ reported via exception argument.
+
+ * magick/constitute.c (WriteImages): Ensure that most severe
+ exception is reported via exception argument.
+
+ * utilities/gm.c: Centered file header because I didn't like it.
+
+ * locale/C.mgk: Removed some defunct messages.
+
+ * magick/blob.c (PingBlob): Report useful error message.
+ (BlobToImage): Report sensible error message for null blob.
+
+ * magick/utility.c (AcquireString): Change UnableToAquireString to
+ UnableToAllocateString.
+
+ * coders/xwd.c (ReadXWDImage): Report CorruptImage rather than
+ CorruptXWDImage.
+
+ * coders/xpm.c (ReadXPMImage): Report CorruptImage rather than
+ CorruptXPMImage.
+
+ * coders/xcf.c (load_level): Report CorruptImage rather than
+ CorruptXCFImage.
+
+ * coders/wbmp.c (ReadWBMPImage): Report CorruptImage rather than
+ CorruptWBMPImage.
+
+ * coders/pcd.c: Report CorruptImage rather than CorruptPCDImage.
+
+ * coders/otb.c (ReadOTBImage): Report CorruptImage rather than
+ CorruptOTBImage.
+
+ * magick/constitute.c (ReadInlineImage): Report CorruptImage
+ rather than CorruptInlineImage.
+
+ * coders/pdb.c (ReadPDBImage): Incorporated undocumented fix from
+ ImageMagick which obtains the image depth from the image depth
+ attribute, and increases the packet memory allocation. Report
+ CorruptImage rather than CorruptPDBImageFile.
+
+2003-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/bin/modules.mgk: Add mapping from SVGZ to SVG.
+
+ * coders/modules.mgk: Add mapping from SVGZ to SVG.
+
+ * coders/svg.c (RegisterSVGImage): Add registration for SVGZ
+ format.
+
+ * PerlMagick/t/zlib/read.t: Added test to check reading a file
+ with .gz extension. The blob portion of the test currently fails.
+
+ * coders/wpg.c (ReadWPGImage): Fix reading WPGs with embedded
+ Postscript. Ensure that scene numbers are sane. Bugs remain.
+
+ * magick/blob.c (OpenBlob): Recognize the .svgz extension as a
+ gzipped format. Not required in order to read .svgz files since
+ the blob file magic detects gzip files.
+
+ * magick/command.c (MontageImageCommand): Wrong exception
+ macro was being invoked. Steps have been taken to ensure that
+ this doesn't happen again.
+ (ImportUsage): Fix spelling of `type`.
+
+ * magick/magick.c (DestroyMagick): Decided that initialization
+ state should be tracked via an enum so that DestroyMagick will
+ take effect even if InitializeMagick has never been called.
+
+2003-05-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/png.c: png.c would dump core when writing a grayscale
+ image in png24 or png32 format.
+
+2003-05-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/ept.c (WriteEPTImage): Fixed writing EPT preview image and
+ added logging.
+
+ * magick/enhance.c (NegateImage): If image is in CMYK colorspace,
+ then negate the `K` channel as well.
+
+ * PerlMagick/Magick.xs: Fix spelling of `elevation` argument to
+ Shade method.
+
+ * magick/image.h (ImageInfo): Added more documenting comments.
+
+ * magick/image.c (CloneImage): Don't clone huffman ascii85
+ encoding support structure since it is not useful outside of the
+ current image context. Cloning a structure via pointer assignment
+ causes a memory leak.
+
+2003-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c: Incorporate math tweaks obtained from
+ ImageMagick which are purported to improve accuracy when rotating
+ and shearing using small angles. Also avoid unneccessarily
+ transforming CMYK images into RGB images.
+
+ * magick/paint.c (ColorFloodfillImage): Fix hang while
+ floodfilling using a pattern image with color similar to the
+ border color.
+
+ * coders/modules.mgk: Add missing mappings for PNG8,
+ PNG24, and PNG32.
+
+ * VisualMagick/bin/modules.mgk: Add missing mappings for PNG8,
+ PNG24, and PNG32.
+
+2003-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/log.c (GetLogBlob): Return an error if log.mgk can not
+ be accessed.
+
+ * locale/C.mgk: Added UnableToAccessLogFile.
+
+ * magick/blob.c (GetConfigureBlob): Only return result of
+ NTResourceToBlob if it is non-NULL.
+
+ * magick/type.c (GetTypeBlob): Search $MAGICK_HOME for
+ type.mgk. Only return result of NTResourceToBlob if it is
+ non-NULL.
+
+ * magick/magick.c (GetMagickInfo): Return an error if GetModuleInfo
+ reports an error.
+
+ * magick/module.c (GetModuleInfo): Return an error if modules.txt
+ fails to load.
+
+ * utility.c (SubstituteString): Fixed a bug which was introduced
+ while updating the code to use the memory allocation macros.
+
+2003-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/GraphicsMagick-config.in (usage): Added example
+ usage to the help output.
+
+ * magick/magick.c (InitializeMagick): Added a static flag to
+ ensure that the Magick library is initialized only one time.
+ (DestroyMagick): Ensure that Magick library resources are only
+ destroyed if it has previously been initialized.
+
+ * magick/nt_base.c (DllMain): Fix contributed by Achim Domma. For
+ a DLL build, update PATH during Magick DLL initialization to
+ include the directory where the Magick core DLL resides. This
+ allows the loadable modules to find the core DLLs, even if the
+ core DLLs are not already in the PATH.
+
+ * magick/image.c (TextureImage): Incorporate new implementation
+ authored by John Cristy of ImageMagick Studio. This
+ implementation is a full 7X (run-time) or 14X (user-time) faster
+ than the original ImageMagick implementation, and is about 2X
+ faster than the speeded-up version I commited on the 19th.
+
+2003-05-20 William Radcliffe <billr@corbis.com>
+
+ * VisualMagick\configure : Fixed bug with add on (plug-ins) not
+ building automatically in DLL mode.
+
+2003-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (TextureImage): Creation of tiled image textures
+ is speeded up by 3.7X.
+
+ * coders/tile.c (ReadTILEImage): Use TextureImage.
+
+ * VisualMagick/bin/modules.mgk: Map "PATTERN" to "LOGO".
+
+ * coders/modules.mgk: Map "PATTERN" to "LOGO".
+
+ * coders/logo.c (ReadLOGOImage): Add "PATTERN" tiling support in
+ order to be compatible with ImageMagick.
+
+ * magick/image.c (SetImageInfo): Map "MAGICK" magick to "IMAGE" in
+ order to be compatible with ImageMagick.
+
+2003-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Copyright.html: Try to fix formatting of XFig entry.
+
+ * www/windows.html: Update file names for 1.0.1 release.
+
+ * index.html: Mention 1.0.1 release as latest release.
+
+ * magick/magick_config_api.h.in: Add define for HasX11
+ so that it is possible to use functions in the installed
+ xwindow.h
+
+ * */*.c: Updated to use MagickAllocateMemory macro.
+
+2003-05-17 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/png.c: stifled compiler warnings about uninitialized
+ chunk and blob variables.
+
+2003-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.h (MagickAllocateMemory): New macro to allocate
+ memory.
+ (MagickFreeMemory): New macro to free memory.
+ (MagickReallocMemory): New macro to reallocate memory.
+
+ * */*.c,*/*.h: Updated to use MagickFreeMemory and
+ MagickReallocMemory. Eliminated warnings when compiling with
+ GCC 3.3 using -Wall.
+
+ * images: The logo image was determined to have a copyright
+ problem so replace with blank image until a replacement is
+ available.
+
+2003-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/magick/magick_config.h.in (HAVE_SYS_TYPES_H):
+ Moved this define back from nt_base.h since removing it was
+ causing some problems for Magick++.
+
+2003-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: (SetMagickInfo): Don't mask failure to
+ read magic.mgk.
+
+ * magick/constitute.c (ReadImage): Don't overwrite specific
+ exception info.
+
+ * magick/nt_base.c (NTResourceToBlob): Add logging similar
+ to that used in IsAccessible() in order to make operation
+ more clear.
+
+ * magick/module.c (FindMagickModule): Removed extraneous
+ "Searching for module file" log event.
+ (GetModuleBlob): Under Windows, don't clear or overwrite
+ an existing exception.
+
+ * magick/nt_base.h: Imported some obscure defines from
+ magick\magick_config.h.
+
+ * VisualMagick/magick/magick_config.h.in: Improved description
+ text and formatting. Moved some obscure defines to
+ magick/nt_base.h.
+
+ * locale/C.mgk: Added a "RegistryKeyLookupFailed" error message.
+
+ * magick/type.c (GetTypeBlob): Report registry key lookup
+ failures. Also ensure correct return value when an error is
+ reported.
+
+ * magick/log.c (GetLogBlob): Report registry key lookup failures.
+
+ * magick/delegate.c (ReadConfigureFile): Report registry key
+ lookup failures.
+
+ * magick/blob.c (GetConfigureBlob): Report registry key lookup
+ failures. Also ensure correct return value when an error is
+ reported.
+
+ * magick/module.c (FindMagickModule): Report registry key lookup
+ failures. Also ensure correct return value when an error is
+ reported.
+
+ * magick/nt_base.c (NTRegistryKeyLookup): Simplify base key lookup
+ code, and improve coding style.
+
+ * coders/logo.c, Copyright.txt, www/Copyright.html: Acknowledge
+ and respect the XFig copyright.
+
+ * VisualMagick/installer/inc/files-documentation.isx: QuickStart.txt
+ is no longer distributed so it is removed.
+
+2003-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h (RoundToQuantum): New macro to round positive
+ double to Quantum.
+
+ * magick/xwindow.c, magick/xwindow.h, magick/studio.h: Use FreeBSD
+ portability fixes from FreeBSD ports collection.
+
+ * configure.ac: Test for <machine/param.h> as used by some *BSD systems.
+
+ * QuickStart.txt, www/QuickStart.html: Don't distribute QuickStart.txt or
+ www/QuickStart.html since the content doesn't currently apply to
+ GraphicsMagick.
+
+2003-05-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * README.txt: Added text regarding where to obtain dcraw, a simple
+ but useful decoder for the proprietary raw file formats produced
+ by digital cameras (58 supported cameras!).
+
+ * configure.ac: Added support for finding dcraw.
+
+ * VisualMagick/bin/delegates.mgk: Added support for dcraw.
+
+ * coders/delegates.mgk.in: Added support for dcraw.
+
+ * version.sh (PACKAGE_RELEASE_DATE): Extract the most recent
+ update date from the ChangeLog file using awk.
+
+2003-05-12 William Radcliffe <billr@corbis.com>
+
+ * modules.mgk, magic.mgk : Sync up both of these for UNIX
+ as well as VisualMagick builds. Includes changes for the
+ meta.c code.
+
+2003-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/formats.html: Documented embedded gray intensity images.
+
+ * coders/logo.c: Added the embedded dithered gray intensity images
+ gray0, gray5, ..., through gray100 to support bilevel filling and
+ painting with an intensity resolution of 5%.
+
+ * www/formats.html: Added description of images available via
+ "IMAGE:" format tag, as well as providing a tiled preview.
+
+ * coders/logo.c: Renamed "transparent" image to "checkerboard"
+ since it is a better description. Added a set of tiny bilevel
+ images (accessed via IMAGE:) for use when tiling, filling, or for
+ use as a texture image. The complete set of image names available
+ via the IMAGE: coder are now BRICKS, CIRCLES, CROSSHATCH,
+ CROSSHATCH30, CROSSHATCH45, FISHSCALES, GRANITE, HEXAGONS,
+ HORIZONTAL, HORIZONTALSAW, HS_BDIAGONAL, HS_CROSS, HS_DIAGCROSS,
+ HS_FDIAGONAL, HS_HORIZONTAL, HS_VERTICAL, LEFT30, LEFT45,
+ LEFTSHINGLE, LOGO, NETSCAPE, OCTAGONS, RIGHT30, RIGHT45,
+ RIGHTSHINGLE, ROSE, SMALLFISHSCALES, CHECKERBOARD, VERTICAL,
+ VERTICALBRICKS, VERTICALLEFTSHINGLE, VERTICALRIGHTSHINGLE, &
+ VERTICALSAW. The HS_* variants are similar to the standard
+ pattern images provided with the Windows GDI.
+
+ * coders/msl.c (MSLStartElement): Don't reset gravity if the user
+ provides an x,y coordinate. Passing coodinates was loosing the
+ gravity setting.
+
+2003-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/modules.mgk: Support the IMAGE: format via the LOGO
+ module.
+ * win2k/IMDisplay/IMDisplayView.cpp (DoDisplayImage):
+ Transparent tile is created by reading "tile:image:transparent".
+ * coders/logo.c (ReadLOGOImage): Add IMAGE: format to front for
+ embedded images so that adding new images doesn't proliferate coder
+ registrations. Legacy logo magick names (GRANITE, LOGO, NETSCAPE,
+ and ROSE) are still supported, but they are also available in the
+ IMAGE file space (e.g. IMAGE:ROSE).
+
+2003-05-09 William Radcliffe <billr@corbis.com>
+
+ * VisualMagick\configure : Further refinements that support both
+ the new "big" library and the normal dynamic DLL buidling styles.
+
+2003-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/logo.c (ReadLOGOImage): Added a "TRANSPARENT" pattern
+ image which can be tiled to form the background of transparent
+ images.
+
+ * win32/IMDisplay/IMDisplayView.cpp: When displaying images which
+ include an opacity channel, use a checker-board pattern as the
+ image background so non-opaque pixels become evident.
+
+2003-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/meta.c : Add or fix commenting of DebugString so that
+ module does not require Windows.
+
+ * lcms: Updated to release 1.10.
+
+2003-05-07 William Radcliffe <billr@corbis.com>
+
+ * VisualMagick\bin : Brought the MGK files back into sync with
+ the rest of the package and added types for meta.c.
+
+ * VisualMagick\bin\win32\ATL : removed config files in order to
+ prevent very old ATL project from being picked up in the config
+
+2003-05-06 William Radcliffe <billr@corbis.com>
+
+ * VisualMagick\lcms\LIBRARY.txt : a define to prevent popup message
+ box behaviour.
+
+ * VisualMagick\configure\ : New feature - -t consolidates all the
+ coders into on library for the static build in order to make the
+ build process tolerable.
+
+ * coders\xtrn.c : new support for BSTR - wdie character data
+
+ * coders\svg.c : put back logic that allows the -size parameter to
+ control the pixel dimensions of the output image.
+
+ * coders\meta.c : added support for wide character parsing of iptc
+ and 8BIM formats.
+
+2003-05-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh : Update to reflect development status.
+
+2003-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * GraphicsMagick 1.0 Released.
+
+ * version.sh (LIBRARY_REVISION): Updated for the 1.0 release.
+
+ * magick/studio.h: Add fix to avoid problems caused by zlib
+ under AIX.
+
+ * magick/cache.h: Parameterized prototypes to make them easier
+ to follow.
+
+ * filters/analyze.c: Replace C++ comments with C comments.
+
+ * magick/command.c: For the composite, convert, identify, mogrify,
+ and montage commands, make sure a usage error is returned if a
+ usage message is printed. This is useful for ImageMagickObject
+ users who won't see the usage message if stdio is not supported.
+
+ * locale/C.mgk: Added "UsageError" error. Added missing closure
+ to <Corrupt> tag which caused most/many message lookups to fail.
+
+ * magick/nt_base.h: Fixed a compile problem caused by masking
+ internals in delegate.h
+
+ * magick/ImageMagick.rc: Added missing .mgk files.
+
+2003-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (lt_dlerror): Defining lt_dlerror to be
+ NTGetLastError was not a correct implementation since the
+ interface is defined to return a const pointer to a string, but
+ NTGetLastError returns an allocated string, causing a memory leak
+ if NTGetLastError is used in the place of lt_dlerror. A new
+ lt_dlerror function is added to fix this.
+ (lt_dlsetsearchpath): lt_dlsetsearchpath should return an int
+ and accept a const char *.
+ (lt_dlsym): lt_dlsym is supposed to take a const char *.
+
+ * magick/nt_base.h: lt_dlclose should return an `int`.
+
+ * magick/nt_base.c (lt_dlclose): Return status from lt_dlclose.
+
+ * magick/module.c (lt_dlclose): lt_dlclose is supposed to return
+ an `int`, not `void`. A return value of zero indicates success.
+
+ * VisualMagick/tests/run_constitute.bat: Add batch script to
+ run constitute tests.
+
+ * magick/module.c: Added a ltdl_initialized static flag to track
+ if libltdl has been initialized by lt_dlinit().
+ (TagToFunctionName): Use a stack buffer for the string rather than
+ allocating heap data.
+ (UnregisterModule): Report errors via exception info as the
+ interface suggests.
+ (UnloadModule): Report errors via exception info as the interface
+ suggests.
+ (DestroyModuleInfo): Only invoke lt_dlexit() if lt_dlinit() has
+ previously been invoked.
+
+ * locale/C.mgk: Added FailedToCloseModule module error.
+
+ * magick/module.c (UnloadModule): Report exception via exception
+ parameter rather than simply printing out an error message and
+ exiting.
+
+ * magick/Makefile.am (noinst_HEADERS): integral_types.h had to be
+ listed *somewhere* in order to make it into the distribution.
+
+ * Magick++/lib/Magick++/Image.h: InitializeMagick must be DLL
+ exported.
+
+2003-05-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (magick-version): Perform version.isx substitutions
+ via Makefile.am rather than configure.
+
+ * magick/magick_config_api.h.in: Added template header for
+ the installed magick_config.h.
+
+ * magick/magick.c (InitializeMagick): Improved the signal handling
+ and registration method. Signal handlers are only registered for a
+ signal if the current signal handling disposition for that signal
+ is set to the default (SIG_DFL). When a signal is caught,
+ DestroyMagick is invoked, the handling for the signal is set back
+ to SIG_DFL, and then the signal is re-raised to trigger the
+ default handler for that signal. This causes the process to behave
+ as closely to the default as possible (e.g. generating a core
+ file) while ensuring that DestroyMagick is executed. This also
+ ensures that signal handlers registered by API users are not
+ overridden by invoking InitializeMagick.
+
+ * configure.ac: Added tests for sigemptyset and
+ sigaction.
+ Add a check for the return type of signal handlers.
+ Test for the `raise` function.
+
+ * www/formats.html: Add an entry for CUR, Microsoft
+ Cursor Icon format.
+
+2003-05-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/semaphore.c (struct SemaphoreInfo): Added
+ `locked` and `thread_id` members. These are used to record
+ if the semaphore is locked, and to validate the thread
+ ID of the unlocker.
+
+ * www/links.html: Added link to Nathan Day's MagickDocs
+ "ImageMagick and GraphicsMagick documentation project"
+ site.
+ Added a link to an on-line article regarding the PHP front-end
+ to ImageMagick.
+
+ * coders/icon.c (ReadIconImage): Add support for Windows
+ .CUR format based on advice from Jean Piquemal.
+
+ * magick/image.c (SetImageInfo): Added missing CloseBlob
+ in error path for failure to allocate temporary file.
+
+ * coders/pcx.c (ReadPCXImage): Added support for reading
+ uncompressed PCX images based on code from Jean Piquemal.
+
+2003-05-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (AddNoiseImage): For gray images, wrong
+ pointer was being used to evaluate intensity, leading to a
+ black image with noise.
+ * magick/image.c (ChannelImage): Return the channel
+ image in RGBColorspace. Also properly support extracting
+ the opacity channel for images which are not CMYK.
+
+2003-04-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/Makefile.am (install-data-local): Install
+ magick_config_api.h rather than magick_config.h.
+
+ * magick/api.h: Removed inclusion of integral_types.h from
+ magick/api.h. It is included by magick/studio.h.
+
+ * magick/delegate.h: Mapped out a block of private implementation
+ code.
+
+ * configure.ac: Perform substitutions on magick_config_api.h.
+
+ * magick/magick_config_api.h.in: New header file template to
+ use for installed magick_config.h.
+
+ * magick/studio.h (MAGICK_IMPLEMENTATION): Added the define
+ MAGICK_IMPLEMENTATION used to enable private types, includes, and
+ defines in the headers. This supports hiding implementation stuff
+ that API users shouldn't see in the headers.
+
+ * utilities/Makefile.am (check): Cleaned up the utilities
+ test/demo a bit as well as using the undocumented "tmp:" prefix to
+ cause GraphicsMagick to remove temporary input files once they
+ have been read. This leaves just the final output file
+ "demo.miff" when the test completes.
+
+ * coders/jpeg.c (WriteJPEGImage): If the image resolution is
+ overwritten with 72DPI, make sure that the resolution units are
+ set to PixelsPerInchResolution.
+
+ * coders/jpeg.c (WriteJPEGImage): Don't overwrite the image
+ resolution if it is valid.
+
+ * magick/command.c (MogrifyImageCommand): Added -resample
+ option to match documentation.
+
+ * VisualMagick/configure: Added rpcrt4.lib to project settings
+ for Visual C++ 6.0 so that configure links. The code which
+ needs these interfaces is to support Visual C++ 7.0 XML-style
+ project files.
+
+2003-04-30 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * utilities/Makefile.am (check) Change % to %% in -label parameter.
+
+ * www/gm.html, utilities/gm.1, etc. Documented use of %% to convey
+ the % sign in -format, -comment, -label strings.
+
+2003-04-30 William Radcliffe <billr@corbis.com>
+
+ * magick/command.c: Changes from 2003-04-19 to free the arg
+ list when it was still pointed to by the option arg and accessed
+ on an exception. This caused gm to crash on any erroneous command
+ line argument.
+
+2003-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/windows.html: Updated to match current installer.
+
+ * VisualMagick/installer/inc/tasks-install-devel.isx (Name):
+ Added an installation checkbox so the user can select to install
+ development headers and libraries for C & C++.
+
+ * VisualMagick/installer/inc/files-perlmagick.isx (Source):
+ Only install PerlMagick PPD files if the user selects to install
+ PerlMagick.
+
+ * VisualMagick/installer/inc/files-com.isx (Source): Only
+ install ImageMagickObject files if the user selects to install
+ ImageMagickObject.
+
+ * magick/version.h.in: Added some documentation for the
+ functioning of MagickLibVersion and MagickLibVersionNumber.
+
+ * configure.ac: Perform substutions to create
+ VisualMagick/installer/inc/version.isx from
+ VisualMagick/installer/inc/version.isx.in. This allows Windows
+ versioning info to be updated from info in version.sh.
+
+ * Makefile.am (magick-version): For a VPATH build, update
+ VisualMagick/installer/inc/version.isx in the source directory if
+ it is out of date.
+
+2003-04-28 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/cache.c: CloneImagePixels(): applied Cristy's bugfix
+ from IM-5.5.7.
+
+2003-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/api.html: The demo program on the ImageMagick API page is
+ usually intended to be an exercise for the reader. It rarely
+ compiles or works. Sure enough the demo code was not even close
+ to compiling, didn't run, and did something totally different than
+ described. This is not a good way to treat new users. Now the
+ demo program compiles and runs, and its description is correct.
+
+ * www/magick.css, www/smile.c: Remove "Pair" advertisement which
+ was discovered appended at the end of these files.
+
+ * coders/jpeg.c (ReadJPEGImage): Check for failure of
+ AllocateImage. Close blob prior to error return.
+
+ * configure.ac: Perform substitutions on magick/version.h
+
+ * magick/version.h.in: New file to provide base for configured
+ magick/version.h
+
+ * version.sh (PACKAGE_RELEASE_DATE): Support setting a package
+ release date.
+
+ * configure.ac: Perform substitutions on PerlMagick/Magick.pm.in to
+ create PerlMagick/Magick.pm.in.
+
+ * PerlMagick/Magick.pm.in: @PACKAGE_VERSION@ is substituted while
+ configuring PerlMagick/Magick.pm.
+
+ * magick/magic.mgk, VisualMagick/bin/magic.mgk: Removed risky
+ entry for PICT which has been demonstrated to lead to a false
+ match in the real-world.
+
+ * coders/pict.c (ReadPICTImage): Ensure that PICT decoder don't
+ loop forever with an EOF condition if none of the PICT op-codes
+ encountered result in a condition which terminates the input loop.
+ If EOF is dectected while in the input loop a "corrupt image"
+ "unexpected end of file" error is reported.
+
+ * VisualMagick/installer: Updated installer.
+
+2003-04-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c, magick/blob.c, magick/studio.h: Added
+ Compilation fixes recommended by Harold Bien for for Borland C++.
+
+ * www/contribute.html: Added text regarding contributing to
+ GraphicsMagick.
+
+ * www/api/types.html: Documentation for GraphicsMagick API types
+ moved from www/api/types/*.html into this one file. Types
+ documentation is still very much under development.
+
+ * README.txt: Added note regarding the download location for free
+ Windows fonts which are kindly made available by Microsoft.
+
+ * VisualMagick/installer/gm-dynamic-full-*.iss: Install
+ nt_base.h and nt_feature.h.
+
+2003-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/windows.html: Updated for GraphicsMagick 1.0 and to
+ link to ImageMagickObject.html.
+
+ * www/programming.html: Added link to ImageMagickObject.html.
+
+ * www/ImageMagickObject.html: New file to provide some
+ documentation for ImageMagickObject.
+
+ * www: Found and fixed broken URL links.
+
+2003-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * FlashPIX: Applied patches from FreeBSD. Bumped package
+ version to version to 1.2.0.8.
+
+ * www/api.html: Updated to reflect GraphicsMagick
+
+ * www/*.html: Updated with format_c_api_docs script.
+
+ * Makefile.am (format_c_api_docs): Add a target to update
+ the C API documentation.
+
+ * scripts/format_c_api_docs: Add script which extracts and
+ formats the C API documentation into HTML files in the www/api
+ subdirectory.
+
+2003-04-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh (PACKAGE_VERSION): Update release version ID.
+
+ * magick/version.h (MagickReleaseDate): Update release date.
+
+ * magick/constitute.c (ConstituteImage): Fixed problems with
+ reading intensity (gray) pixel arrays.
+
+ * magick/image.c (GrayscalePseudoClassImage): Use
+ ScaleQuantumToIndex rather than ScaleQuantumToMap.
+
+ * magick/constitute.c (ConstituteImage): Use ScaleQuantumToIndex
+ macro to scale integral intensity values to colormap range.
+
+ * magick/image.h (ScaleQuantumToIndex): New macro to scale a
+ quantum to the maximum range of a colormap index. Useful when
+ writing to PsuedoClass grayscale images.
+
+ * VisualMagick/tests/run_constitute.bat: Batch script to run
+ constitute tests.
+
+ * VisualMagick/installer/*.iss: Updated for Beta1 release.
+
+2003-04-22 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * utilities/Makefile.am (check) fixed typos (RM -> RMDelegate
+ and removed stray "gm"), added -random-threshold, ordered-dither.
+
+ * magick/effect.c: Random-threshold was not treating non-gray
+ PseudoColor images correctly.
+
+2003-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/Makefile.am (check): Added code to put logo on demo
+ output.
+
+ * magick/command.c (MontageImageCommand): Pass exception rather
+ than &image->exception because image may be null, and it is
+ pointless to store the exception where it will not be reported to
+ the user anyway.
+
+ * utilities/Makefile.am (check): Ported Glenn Randers-Pehrson's
+ utilities demo script into the Makefile to serve as a check
+ target.
+ (check): Add definition to find Generic.ttf.
+
+ * locale/C.mgk: Fixed syntax error in <Option><FatalError>
+ section.
+
+ * www/development.html: New file to describe development
+ process.
+
+ * index.html, www/*.html: Added link to development.html
+ and improved formatting a bit.
+
+2003-04-21 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Fixed bug with compiling png.c with libpng versions
+ older than libpng-0.95.
+
+2003-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/programming.html: Added links to Delphi and Scheme
+ programming interfaces.
+
+ * configure.ac : Removed outdated test for jp2conf.h.
+
+2003-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Add argument expansion and deallocation code
+ to command functions which lacked this functionality.
+ Replace calls to Exit with a return to the invoking function.
+
+ * utilities/gm.c: Expect each subcommand to expand and deallocate
+ its own argument list. Treat subcommands more similarly.
+
+ * magick/magick.c (InitializeMagick): Seed the random number
+ generator.
+
+ * magick/utility.c (ExpandFilenames): Handle tilde expansion
+ properly. Handle relative glob specifications. Skip over "*"
+ argument to +profile properly. Don't expand VID: specifications
+ since the VID: coder will execute ExpandFilenames() later. Apply
+ format specifier prefix to globbed file names. Fix double frees
+ and rationalize memory management by always copying to a new
+ vector.
+
+2003-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (InitializeMagick): Decided to
+ move clean-up signal-handler registration from gm.c
+ to magick.c in order to ensure that resources are
+ cleaned up for all library users. This means that
+ if a user program wants to do something special for
+ signals registered to be caught by InitializeMagick
+ (SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGTERM, SIGXCPU,
+ & SIGXFSZ) then the user program should register its
+ own signal handlers after invoking InitializeMagick.
+ The user is then responsible for making sure that
+ DestroyMagick is invoked if an unexpected signal is
+ caught.
+
+ * tests/Makefile.am (check-constitute): Added
+ constitute tests.
+
+ * magick/constitute.c: New test program to ensure
+ that ConstituteImage and DispatchImage are working
+ correctly.
+
+2003-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/download.html: Added links to directories
+ at ftp.graphicsmagick.org.
+
+ * index.html: Add notice regarding 1.0 Beta0
+ availability.
+
+ * www/cvs.html: Updated CVS checkout information to
+ include the GraphicsMagick-1_0 branch.
+
+ * coders/psd.c (ReadPSDImage): Applied patch
+ (SourceForge patch ID 722849) from Derry Bryson to
+ fix a memory leak. An image was being leaked.
+
+ * magick/constitute.c (DispatchImage): Applied patch
+ (SourceForge patch ID 722655) from Derry Bryson to
+ correctly use the switch_map array rather than the
+ map array. Without this patch, DispatchImage does
+ not work at all.
+
+ * GraphicsMagick 1.0.0-beta0 release.
+
+ * version.sh: Updated for beta0 release.
+
+ * *.c magick/*.h: Update header inclusion to include
+ "magick/" prefix in order to ensure that there is no
+ confusion with headers from another package.
+
+2003-04-16 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/effect.c: 4x4 ordered dither threshold was
+ incorrect.
+
+2003-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (InitializeMagickResources):
+ Added the ability to obtain the amount of physical
+ memory by executing an external command.
+
+ * configure.ac: Check for getpagesize().
+ (MAGICK_PHYSICAL_MEMORY_COMMAND): Added a test for
+ an external command which (quickly) returns the
+ amount of physical memory installed on the machine.
+ Currently only activated for FreeBSD.
+ (MAGICK_PHYSICAL_MEMORY_COMMAND): Use sysctl to
+ determine total physical memory for Darwin.
+
+ * magick/delegate.c (ListDelegateInfo): If COLUMNS
+ environment variable is set, then use it to obtain
+ the screen width. Some shells dynamically update
+ COLUMNS, but COLUMNS may need to be explicitly
+ exported in order for it to be seen by subordinate
+ programs (such as gm).
+
+ * magick/effect.c (AddNoiseImage): Use IsGrayImage()
+ to check if the image is gray. Add missing columns
+ loop for intensity case (oops!).
+
+ * magick/command.c (DisplayImageCommand): Fix
+ -dispose option processing bug reported by
+ Felix Heimbrecht.
+
+ * coders/fpx.c: Check status from FPX_InitSystem().
+
+2003-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Define PERLMAINCC to be the C compiler
+ if there are no C++ dependencies, or the C++ compiler
+ if there are C++ dependencies.
+
+ * PerlMagick/Makefile.PL.in: Use PERLMAINCC to compile
+ and link perlmain.c. This allows using the C++ compiler
+ to link, which is useful when the build depends on C++
+ libraries like libfpx.
+
+ * ltmain.sh: Updated to libtool 1.5 release.
+
+ * Makefile.am ($(PERLMAGICK)/$(PERLSTATICNAME)): Add
+ rules to make sure that static PerlMagick is linked
+ against the current GraphicsMagick library.
+
+ * coders/miff.c (ReadMIFFImage): Properly scale
+ colormap entries.
+
+ * magick/image.c (TransformRGBImage): Eliminate 32-bit
+ integer overflow condition for Q:32 build while
+ transforming CMYK pixels.
+
+2003-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/ttf/read.t: Updated signatures and
+ reference image for FreeType 2.1.4.
+
+ * (PerlMagick/t/write.t, PerlMagick/t/montage.t,
+ PerlMagick/t/rad/read.t, PerlMagick/t/rad/write.t):
+ Fix signatures which were thrown off by previous
+ change to how signatures are specified to functions
+ in subroutines.pl.
+
+ * PerlMagick/t/cgm/read.t: Updated to use reference
+ image.
+
+ * PerlMagick/Makefile.PL.in: Perform substitutions
+ on generated Makefile to ensure that the proper
+ -lGraphicsMagick is used for a static build.
+
+ * ttf: Updated to FreeType 2.1.4. Now stored in
+ CVS as delegates/freetype2 rather than delegates/ttf
+ so be sure to re-checkout the ttf directory so that
+ the correct files are used.
+
+ * wmf/incude/libwmf/api.h: Updating FreeType caused
+ a problem since it introduced a copy of zlib and
+ api.h included zlib.h. Fixed problem by adding
+ a typedef for gzFile and not including zlib.h.
+
+ * utilities/gm.c: Fixed minor compilation problem
+ under Windows caused by a typo in the signal
+ handler registration code.
+
+2003-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: When building a static PerlMagick,
+ build PerlMagick as part of the `all` target and
+ don't do a `make clean` of PerlMagick at install
+ time.
+
+ * configure.ac (LIB_DPS): Add check to see if -lXt
+ is required by -ldps. XFree86 -ldps requires -lXt.
+
+ * FlashPIX: FlashPIX library now compiles under
+ FreeBSD 5.0.
+
+ * magick/deprecate.c (ValidateColormapIndex): Remove
+ non-interface deprecated function.
+
+ * magick/tempfile.c (AcquireTemporaryFileDescriptor):
+ Priortize use of mkstemp() over tempname() since *BSD
+ compilers whine about tempname() (although we do use
+ tempname() safely).
+
+ * magick/color.c (ConstrainColormapIndex): Removed
+ function since it is no longer used.
+
+ * magick/utility.c (TemporaryFilename): Removed
+ TemporaryFilename utility function since it is
+ no longer used and it makes *BSD compilers
+ complain.
+
+ * magick/studio.h: Don't define _ISOC99_SOURCE,
+ _POSIX_C_SOURCE, or _XOPEN_SOURCE when compiling
+ under FreeBSD since this maps out a `ushort`
+ definition required by /usr/include/sys/ipc.h.
+
+2003-04-11 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/png.c: Some grayscale PNG images and the
+ JNG alpha channel were decoded improperly at Q:32.
+
+ * magick/constitute.c (PopImagePixels): Changed many
+ instances of (Quantum) typecast to (unsigned char).
+
+2003-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/tiff/read.t: Added signature for 12-bit
+ TIFF test and a Q:32 build.
+
+ * PerlMagick/t/subroutines.pl: Extended routines
+ which are signature based to accept signatures for
+ Q:32 as well.
+
+ * PerlMagick/t/wmf/read.t: Relax error values slightly
+ to pass at Q:32.
+
+ * coders/miff.c (PushImageRLEPixels): Fix reading
+ RLE MIFF at Q:32. A fragment of old code was being
+ used to obtain the length.
+ (WriteRunlengthPacket): Fix writing RLE MIFF at Q:32.
+ In most cases the wrong scaling macro was being used.
+
+ * tests/Makefile.am (check-miff): Added MIFF tests
+ for supported compression options.
+
+2003-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/color.c (QueryColorDatabase): Extended to
+ support parsing Q:32 hex color specification strings.
+ Also add error reporting for failure to parse the
+ color specification. This resolves a bug that drawing
+ via the draw.c APIs was not working for Q:32 builds.
+
+ * utilities/gm.c (main): Add signal handlers to
+ make sure that program cleans-up on exit by invoking
+ DestroyMagick.
+
+ * magick/draw.c (DrawSetFillColor): Quote color
+ specification.
+ (DrawSetStrokeColor): Quote color specification.
+ (DrawSetTextUnderColor): Quote color specification.
+
+ * ltmain.sh: Update to latest CVS libtool.
+
+2003-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/enhance.c (NormalizeImage): Only normalize the opacity
+ channel if image->matte is true. This results in some (15%)
+ speedup. While it can be argued that the `K` in CMYK should be
+ normalized, it can also be argued that this is senseless since `K`
+ is not a "linear" measure like C, M, & Y are, and there may not be
+ any any value to normalizing CMY at all.
+ (EqualizeImage): Only equalize the opacity channel if image->matte
+ is true. This results in a 23% speedup.
+ (GammaImage): Minor loop optimization.
+ (LevelImage): Don't level the opacity channel. Doing so doesn't
+ make any sense.
+ (LevelImageChannel): Put loops inside switch statement rather than
+ around it.
+
+ * PerlMagick/t/tiff/read.t: Added grayscale 12-bit and 16-bit TIFF
+ read tests.
+
+2003-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Add support for reading
+ 12-bit grayscale TIFFs. Fix reading 16-bit grayscale TIFFs
+ when QuantumDepth=8.
+
+ * VisualMagick/installer/gm-dynamic-full-8.iss,
+ VisualMagick/installer/gm-dynamic-full-16.iss: Many C header
+ files were not being included in the distribution. Oops!
+
+2003-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * (index.html, www/*.html): Update to new web page style.
+
+ * scripts/txt2html: Update to output new web page style.
+
+ * ltmain.sh: Updated to latest CVS libtool.
+
+ * magick/tempfile.c (DestroyTemporaryFiles): Function was
+ crashing if it was executed twice.
+
+2003-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/delegates.mgk.in: Ralcgm was appending ".ps" to the
+ provided output file name, so change cgm delegate command so that
+ the input file is delivered via standard input, output is
+ re-directed to a file, and anything printed to stderr (such as
+ the Ralcgm program name and version) is sent to /dev/null.
+
+ * INSTALL-unix.txt: Added/corrected/improved documentation
+ regarding --disable-installed, --enable-shared, and
+ --with-modules.
+
+ * VisualMagick/magick/magick_config.h.in: Add more documentation
+ and explanatory notes in order to lessen confusion.
+
+ * Many files: Replaced "UseInstalledImageMagick" with
+ "UseInstalledMagick" for obvious reasons.
+
+2003-04-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/command.c, utilities/gm.c: Print "help" screen for a
+ tool when user types "gm tool" or "gm tool -help"
+
+ * magick/command.c, magick/effect.c: add -ordered-dither option.
+
+2003-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * locale/C.mgk: Fixed message associated with
+ "UnableToCreateTemporaryFile".
+
+ * magick/tempfile.c (AcquireTemporaryFileDescriptor): Decided
+ to return a pathname (if possible), even on failure, for use
+ in error reports. The function return status should be used
+ to determine if the function has succeeded.
+
+ * locale/locale.mgk: Updated copyright header.
+
+ * (magick/annotate.c, magick/attribute.c, magick/blob.c,
+ magick/cache.c, magick/constitute.c, magick/delegate.c,
+ magick/display.c, magick/image.c, magick/locale.c
+ magick/tempfile.c, magick/tempfile.h, magick/utility.c,
+ magick/xwindow.c, coders/dcm.c, coders/ept.c,
+ coders/histogram.c, coders/mpeg.c, coders/pdf.c,
+ coders/pict.c, coders/preview.c, coders/ps2.c,
+ coders/ps3.c, coders/ps.c, coders/pwp.c, coders/sfw.c,
+ coders/svg.c, coders/tiff.c, coders/url.c, coders/wpg.c):
+ Ensure that failure to allocate/create temporary file is
+ properly detected and reported.
+
+2003-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/type.c (GetTypeBlob): Prioritize hard-coded path
+ over Windows registry values.
+
+ * magick/log.c (GetLogBlob): Prioritize hard-coded path
+ over Windows registry values.
+
+ * magick/blob.c (GetConfigureBlob): Prioritize hard-coded path
+ over Windows registry values.
+
+ * magick/delegate.c (ReadConfigureFile): Perform substitutions
+ for "@GMDelegate@", "@GMDisplayDelegate@", "@MPEGDecodeDelegate@",
+ "@MPEGEncodeDelegate@", and "@HPGLDecodeDelegate@" while reading
+ delegates.mgk under windows.
+ (ListDelegateInfo): Format delegate command line to multiple
+ lines if necessary rather than truncating.
+
+ * configure.ac (MagickBinPathDefine): Added support for
+ a MagickBinPath definition.
+
+ * configure.ac (GSVersion): Added test to obtain version
+ of installed Ghostcript.
+
+ * magick/tempfile.c (AcquireTemporaryFileDescriptor): Open
+ flag should have been O_RDWR, not O_WRONLY!
+
+2003-04-03 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/utility.c: Simplified skipping over the "*" in
+ the +profile "*" option when expanding filenames.
+
+2003-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/bin/delegates.mgk: Update similarly to
+ coders/delegates.mgk.in.
+
+ * coders/delegates.mgk.in: Replaced `mpeg-decode` delegate
+ specification with `mpeg` delegate specification.
+
+ * PerlMagick/t/mpeg/read.t: Since -r option is no longer
+ supplied to mpeg2decode, the signatures must be updated.
+
+ * magick/utility.c (ExpandFilenames): Skip over no-argument
+ commands properly.
+
+ * coders/mpeg.c: Removed ReadMPEGImage since this is handled
+ entirely by delegate now.
+
+ * magick/command.c: Add convert -temporary option for use
+ when input files are temporary files which should be
+ automatically removed.
+
+ * magick/delegate.c (InvokeDelegate): Ensure that temporary
+ file access is secure.
+
+ * coders/ept.c (ReadEPTImage): Ensure that temporary file
+ specified by image_info->filename is liberated before
+ allocating a new temporary file name.
+
+ * coders/ps.c (ReadPSImage): Ensure that temporary file
+ specified by image_info->filename is liberated before
+ allocating a new temporary file name.
+
+ * coders/pdf.c (ReadPDFImage): Change TemporaryFilename
+ to AcquireTemporaryFileName.
+
+ * magick/tempfile.c (LiberateTemporaryFile): Now takes
+ a `char *` argument rather than `const char *`, and
+ erases the provided filename if it is the name of a valid
+ temporary file. This helps avoid errors. The return
+ status may be used to determine if a file was removed.
+ (AcquireTemporaryFileDescriptor): Decided that adding a
+ .tmp extension to temporary file names is unnecessary.
+
+ * coders/jp2.c (WriteJP2Image): Destroy pixel matrix
+ after encoding image. Cristy says that there is memory
+ corruption otherwise.
+
+2003-04-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/png.c: Use new temporary file manager for JNG components.
+ Merge with IM 5.5.7 (mostly cosmetic changes).
+
+2003-03-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/cache.c (OpenCache): Add some Windows-specific
+ open options.
+
+ * magick/resource.c (InitializeMagickResources): Increase
+ the number of "lowio" file handles available for use under
+ Windows.
+
+ * ltdl/ltdl.c: Incorporate more Darwin fixes from CVS libtool.
+
+ * coders/pcx.c (ReadPCXImage): Incorporate bugfix from
+ ImageMagick -- Not enough memory allocated for reading PCX
+ (bug report by Trevor Willis).
+
+ * magick/magick.c (InitializeMagick): Only invoke
+ SetLogEventMask() to set debug options based on
+ getenv("MAGICK_DEBUG") if the environment variable is set.
+
+2003-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/tempfile.c: Include tempfile.h rather than temporary.h
+
+ * magick/magick.c: Include tempfile.h rather than temporary.h
+
+ * coders/dcm.c, coders/ept.c, coders/histogram.c, coders/mpeg.c,
+ coders/pdf.c, coders/pict.c, coders/preview.c, coders/ps.c,
+ coders/ps2.c, coders/ps3.c, coders/pwp.c, coders/sfw.c,
+ coders/svg.c, coders/tiff.c, coders/url.c, coders/wpg.c,
+ magick/annotate.c, magick/attribute.c, magick/blob.c,
+ magick/cache.c, magick/constitute.c, magick/delegate.c,
+ magick/display.c, magick/image.c, magick/magick.c,
+ magick/utility.c, magick/xwindow.c: Updated to use new temporary
+ file allocation APIs.
+
+ * magick/tempfile.c: New temporary file allocation subsystem for
+ allocating, tracking, and deallocating temporary files. Use of
+ this subsystem should reduce the likelyhood that temporary
+ files will be left behind once the process exits.
+ If the environment variable MAGICK_TMPDIR is set, then its
+ value is used as the location to place temporary files.
+
+ * magick/utility.c (IsAccessibleAndNotEmpty): New function
+ for testing for file exists, is a regular file, and is not empty.
+ Used to test if a temporary file has been updated by a delegate.
+
+ * magick/log.c (SetLogEventMask): Add support for setting
+ TemporaryFileEvent.
+
+ * PerlMagick/Magick.xs: Added TemporaryFile log event type.
+
+ * magick/log.h (LogEventType): Add TemporaryFileEvent event
+ classification.
+
+2003-03-29 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/resize.c (SampleImage) and magick/render.c (DrawAffineImage():
+ Applied Cristy fix for bug that offset images to the top and left.
+
+ * magick/resize.c (ScaleImage): Fixed bug that caused intensity
+ levels to be one unit too high.
+
+ * coders/png.c: make JNG support depend on HasJPEG. Remove temp files.
+
+2003-03-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resize.c (ResizeImage): Applied fix authored by John
+ Cristy for distortion when using the bessel filter.
+
+ * magick/display.c: Applied fix authored by John Cristy which
+ eliminates bogging down when using the magnifier window on
+ large images.
+
+ * Several files: A few files included multiple copies of the
+ copyright header text due to either pilot error, or equipment
+ failure.
+
+2003-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am : Removed some debug code which was
+ accidentally committed to CVS.
+
+ * Copyright.txt: Add copyright statements to all the files,
+ including some apparently missing copyrights.
+
+2003-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+ * magick/Makefile.am: Added temporary.c and temporary.h. These
+ are not finished yet.
+
+ * magick/cache.c: Transferred optimization from ImageMagick
+ to read/write all requested pixel cache rows in one system
+ call when accessing the cache using file I/O, and the
+ requested columns equals the image columns.
+
+ * magick/resource.c: (ResourceInfo): Use type `double` rather
+ than `long double`. For many systems, the range of `long double`
+ is the same as `double`. On others, use of `long double` incurs
+ the cost of function calls since there is no hardware support.
+
+2003-03-22 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/effect.h, effect.c, command.c: Revised -random-dither
+ to require parameters: channel LOWxHIGH. Channel can presently
+ be "intensity", "opacity", or "all".
+
+2003-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ltdl/ltdl.c: Updated to latest CVS version. Claimed to
+ support loading modules under MacOS-X.
+
+ * magick/resource.c (InitializeMagickResources): Enable code
+ under Windows which queries system limits.
+
+ * magick/cache.c (S_MODE): Fixed portability problems with
+ definition.
+
+ * VisualMagick/bin/delegates.mgk: Fix typo in "mpeg-decode"
+ decode rule.
+
+ * libtool: Update to latest CVS version.
+
+ * configure.ac: Test zlib for gzseek and gztell.
+
+ * magick/effect.c (ChannelThresholdImage): The is_grayscale flag
+ was not be evaluated correctly.
+
+2003-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h (RoundSignedToQuantum): Added handy
+ RoundSignedToQuantum macro for munging doubles into Quantums.
+
+ * magick/effect.c (ThresholdImage): Added optimizations for
+ thresholding all pixels to white or black. Threshold using an
+ integral value rather than a double so compares are faster.
+ (ChannelThresholdImage): Threshold against integral values since
+ compares are faster. Invoke ThresholdImage for simple thresholding
+ across all channels since it is faster.
+
+2003-03-19 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/meta.c: #ifdef'ed out some dead code.
+
+ * magick/annotate.c: #ifdef'ed out some code that is only
+ used when HasTTF is defined.
+
+ * Added RandomThresholdImage() method and -random-threshold
+ commandline option.
+
+2003-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac (LIB_TIFF): Check for TIFFReadRGBATile and TIFFReadRGBAStrip
+ in libtiff before deciding to use it.
+
+ * magick/blob.c (WriteBlob): Move pointer increment into
+ paranthesis.
+ (ReadBlob): Move pointer increment into paranthesis.
+
+ * magick/gem.c (HSLTransform): Removed inline statement.
+ (TransformHSL): Removed inline statement.
+
+ * magick/random.[c|h]: Removed files from CVS.
+
+ * magick/command.c: Don't include random.h.
+
+ * PerlMagick/t/reference/jng: Update reference files to current output.
+
+2003-03-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Added tests for pread and pwrite functions.
+
+ * magick/image.c (GrayscalePseudoClassImage): Properly invoke
+ SyncImagePixels.
+
+ * magick/cache.c (SyncCacheNexus): Add back in is_monochrome and
+ is_grayscale flag resetting which was lost by copying over
+ ImageMagick's cache.c.
+ (FilePositionRead): Inline wrapper for reading a chunk of data at
+ an offset.
+ Cleans up some messy code, and makes it easy to use pread().
+ (FilePositionWrite): Inline wrapper for writing a chunk of data at
+ an offset.
+ Cleans up some messy code, and makes it easy to use pwrite().
+ Cache now uses pread() and pwrite() to access the cache if these
+ calls are available.
+
+ * magick/resource.c (InitializeMagickResources): Support setting
+ resource limits via the environment variables MAGICK_LIMIT_DISK,
+ MAGICK_LIMIT_FILES, MAGICK_LIMIT_MEMORY, and MAGICK_LIMIT_MAP.
+
+2003-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/stream.c (AcquirePixelStream): Store total pixels in
+ 64-bit type.
+ (SetPixelStream): Store total pixels in 64-bit type.
+
+ * coders/tiff.c (WriteTIFFImage): CoderError should be
+ MissingDelegateError.
+
+ * coders/ps3.c (Huffman2DEncodeImage): CoderError should be
+ MissingDelegateError.
+ (WritePS3Image): CoderError should be MissingDelegateError.
+
+ * coders/ps2.c (Huffman2DEncodeImage): CoderError should be
+ MissingDelegateError.
+
+ * coders/pdf.c (Huffman2DEncodeImage): CoderError should be
+ MissingDelegateError.
+
+ * coders/fpx.c (ReadFPXImage): CoderError should be
+ MissingDelegateError.
+ (WriteFPXImage): CoderError should be MissingDelegateError.
+
+ * coders/dps.c (ReadDPSImage): CoderError should be
+ MissingDelegateError.
+
+ * magick/image.c (AnimateImages): DelegateError should be
+ MissingDelegateError.
+
+ * magick/annotate.c (RenderX11): DelegateError should be
+ MissingDelegateError.
+
+ * magick/image.c (DisplayImages): DelegateError should be
+ MissingDelegateError.
+
+2003-03-17 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/image.c Relocated misplaced break in ChannelImage()
+ and sped up SetImageOpacity by avoiding blend operation when
+ setting the image fully opaque.
+
+2003-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/cache.c: Snarfed cache.c updates from ImageMagick.
+
+ * magick/command.c: Added -list resource support.
+
+2003-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/Makefile.am (random.c): Removed building, packaging,
+ and intialization of random.c functions since it is not actually
+ used.
+
+ * magick/semaphore.c (InitializeSemaphore): Only initialize
+ critical section if active_semaphore is not already true.
+
+ * magick/resource.c: Snarf resource.c updates from ImageMagick.
+
+ * PerlMagick/Magick.xs: Added missing log event types.
+
+ * magick/log.h (enum): Added ResourceEvent enumeration.
+
+ * magick/log.c (LogMagickEvent): fflush(stdout) at the end of
+ each log. Otherwise output may not be seen for a long time.
+ (SetLogEventMask): Add support for "-debug resource".
+
+ * coders/tiff.c (RegisterTIFFImage): Don't register encode and
+ decode handlers for TIFF if TIFF library is not available.
+
+ * magick/constitute.c (WriteImage): Fix cut-n-paste error
+ in log message ("decoder" --> "encoder").
+
+2003-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * index.html: Added a link to the GraphicsMagick mailing lists.
+
+ * Magick++/demo/zoom.cpp: Added dashed option support, including
+ a -resample option for image resampling.
+
+2003-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (DIST_SUBDIRS): Filters subdirectory needs to
+ be distributed.
+
+2003-03-14 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/render.c Ported Cristy's bugfix to DrawAffineImage().
+
+2003-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (DestroyImage): Comment out new assertions until
+ we are certain that there are no ill effects.
+
+ * coders/mat.c (ReadMATImage): Set image->depth to valid values.
+
+ * PerlMagick/Magick.xs: Update so that new DestroyImage assertions
+ aren't asserted.
+
+ * magick/list.c (DestroyImageList): Update so that new DestroyImage
+ assertions aren't asserted.
+
+ * coders/wpg.c (ReadWPGImage): Don't leave dangling pointer when
+ trimming list. Don't set image->depth to invalid values.
+
+2003-03-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (DestroyImage): Add assertions to verify
+ that destroyed image is not currently referenced by another
+ image. This should help prevent accidental continued use
+ of a destroyed image.
+ (DestroyImage): Added assertions to enforce that images
+ should not continue to reference the destroyed image.
+
+ * coders/wpg.c: Incorporated fixes from Jaroslav Fojtik.
+
+ * version.sh (PACKAGE_VERSION_ADDENDUM): Construct a package
+ snapshot version based on the ChangeLog modification time.
+ This requires GNU find to work propery since the -printf
+ option is used.
+
+ * configure.ac (LIB_GS): Do not test for the Ghostscript
+ library by default due to the issue of its embedded libjpeg
+ conflicting with libjpeg.
+
+ * coders/ept.c (ReadEPTImage): "PostscriptDelegateFailed" should
+ be classified as a DelegateError type.
+
+2003-03-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (BlobToFile): Truncate while opening file.
+ (ImageToFile): Truncate while opening file.
+
+ * magick/annotate.c (RenderFreetype): Missing freetype library
+ should result in a MissingDelegateError type rather than a
+ DelegateError type.
+
+ * INSTALL-windows.txt: Added a note regarding a workaround for
+ internal compiler errors while compiling image.c when using
+ Visual C++ 7.0.
+
+ * coders/jpeg.c (ReadICCProfile): Incorporate ImageMagick fix
+ to handle short JPEG ICC profiles.
+
+ * magick/integral_types.h: Ignore SIZEOF_LONG_LONG and
+ SIZEOF_UNSIGNED_LONG_LONG defines if _VISUALC_ is defined.
+
+2003-03-11 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * www/gm.html, utilities/gm.1, guide/gm.tex: Expanded description
+ of the -affine option.
+
+2003-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (GetImageDepth): Re-implemented using a single-pass
+ algorithm and 1/2 the code. Previous implementation didn't return
+ correct results for Q:32 build. Now it does.
+
+ * magick/command.c (IdentifyImageCommand): For identify, when
+ %q format specifier is present, image must be read rather than
+ pinged. If not, either the value 8 is returned, or there is a
+ crash due to reading an uninitialized image.
+
+2003-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/mat.c: Incorporate fixes from Jaroslav Fojtik. Close
+ Blob before rotating image.
+
+ * PerlMagick/README.txt: Update to reflect that PerlMagick is
+ part of GraphicsMagick.
+
+ * PerlMagick/t/input.mat: Added test image for Matlab format.
+
+ * PerlMagick/t/input.wpg: Added test image for WordPerfect Graphics Format.
+
+ * utilities/Makefile.am (ALLMANPAGES): Install gm.1 rather than
+ old utility manual pages.
+
+2003-03-09 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * www/gm.html, utilities/gm.1, guide/gm.tex: First cut at
+ manpage for gm, to replace individual utility manpages.
+
+2003-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c: Fix some erroneous log printf specifications.
+ Improved blob log messages a bit.
+
+ * magick/log.c (IsEventLogging): Use InitializeLogInfo().
+ (InitializeLogInfo): New function to intelligently initialize
+ logging subsystem. Only locks when initialization may be required,
+ and only locks long enough to determine if initialization is required.
+ This approach should avoid deadlocking while logging from functions
+ used to initialize logging.
+ (IsLogAccessible): No longer need this duplicate of IsAccessible().
+ (SetLogEventMask): Use InitializeLogInfo().
+
+ * coders/fpx.c (ReadFPXImage): FlashPIX library does not support
+ BLOB I/O so don't use OpenBlob/CloseBlob. Opening the blob caused
+ a conflict when the FlashPIX library attempted to open the file.
+
+2003-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Test for libtiff functions (TIFFClientOpen &
+ TIFFIsByteSwapped), which are required by GraphicsMagick, but
+ not found in older libtiff versions.
+
+ * magick/blob.c: Added logging for Blob open/close and memory
+ mapping operations.
+
+2003-03-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwblob.c (main): DestroyImage asserts on NULL so only
+ call it for non-null image.
+
+ * tests/rwfile.c (main): DestroyImage asserts on NULL so only
+ call it for non-null image.
+
+2003-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwblob.c (main): Add -pause option to require keypress to
+ exit program. Clean-up to avoid any appearance of leaks.
+
+ * tests/rwfile.c (main): Add -pause option to require keypress to
+ exit program. Clean-up to avoid any appearance of leaks.
+
+ * magick/static.c (ExecuteStaticModuleProcess): Don't bind in
+ process filter functions for Visual C++ since the build environment
+ doesn't support it yet.
+
+ * magick/log.c (GetLogBlob) Code wasn't actually testing current
+ directory for log.mgk, now it does.
+
+ * magick/log.c (IsEventLogging): Eliminate accidental recursive, or
+ repeated, initialization of the logging system.
+
+2003-03-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (WriteJP2Image): Improved -quality rate estimation
+ for very small files.
+
+2003-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (WriteJP2Image): Add additional logging support.
+
+ * tests/rwblob.c: Added BLOB read/write logging.
+
+ * tests/rwfile.c: Added file read/write logging.
+
+ * magick/module.c (FindMagickModule): Minor code cleanup and limit
+ directory and file name lengths to sensible values.
+
+ * magick/utility.c (IsAccessible): Log test failures along with
+ test failure reason [strerror(errno)]. Also log test success.
+
+ * VisualMagick/bin/delegates.mgk: -DSAFER does not work with
+ Ghostscript 8.0.
+
+ * magick/module.c: Needed to conditionally include nt_feature.h.
+
+2003-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/module.c (ExecuteModuleProcess): Updated to support locating
+ filter modules based on search rules.
+ (CoderInfo): Declare only in module.c since use is private to this
+ module.
+ (GetCoderInfo): Made static and commented out since currently unused.
+ (FindMagickModule): New function to search for a module.
+ (GetModuleBlob): Moved from blob.c, made static, and re-implemented
+ based on FindMagickModule.
+
+ * magick/blob.c: Moved GetTypeBlob() to type.c and made it static.
+ Moved GetModuleBlob() to module.c and made it static.
+
+2003-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/Makefile.am: MIFF module does not depend on -ljpeg, but
+ PNG module does (for JNG).
+
+ * filters/analyze.c (AnalyzeImage): Bugfix, image should be passed
+ as Image** rather than Image*.
+
+ * magick/utility.c (IsAccessible): Don't log errno if errno==0.
+
+2003-03-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/Makefile.am: Link with libFilters convenience library.
+
+ * VisualMagick/magick/magick_config.h.in: Change MagickModulesPath
+ to MagickCoderModulesPath and add a MagickFilterModulesPath to
+ locate filter modules.
+
+ * filters/Makefile.am: New makefile to build filter modules.
+
+ * configure.ac: Configure magick/GraphicsMagick.pc and
+ Magick++/lib/GraphicsMagick++.pc.
+ (MagickModulesSubdir): Add quantum depth to modules path to ensure
+ that modules with the correct depth are loaded. The modules path
+ is now
+ ${libdir}/GraphicsMagick-${PACKAGE_VERSION}/modules-Q${QuantumDepth}/coders.
+ (MagickCoderModulesPath): Rename MagickModulesPath to
+ MagickCoderModulesPath.
+ (MagickFilterModulesPath): Define to location of filter modules.
+
+ * magick/Makefile.am: Added rules to install GraphicsMagick.pc.
+
+ * magick/GraphicsMagick.pc.in: Added pkgconfig file for
+ -lGraphicsMagick.
+
+2003-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (WriteJP2Image): Quality factor calculation had
+ accidentally been removed. The calculation is back, but has been
+ biased up slightly so that a quality factor of 75 results in a
+ more reasonable 16:1 compression. Past a quality factor of 99.5,
+ the compression is set to 1:1 (non-lossy).
+
+2003-02-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Fixed bug with reading interlaced PNG images, introduced
+ yesterday.
+
+ * Fixed bug with skipping MNG subimages, also introduced
+ yesterday.
+
+2003-02-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (EXTRA_DIST): Forgot to distribute version.sh
+
+ * configure.ac: Use definitions from version.sh to drive
+ package versioning and naming. These definitions support
+ libtool's recommended approach to library versioning.
+
+ * version.sh: New file for managing release versioning.
+ Edit this file to change the release number, etc.
+
+ * PerlMagick/t/tiff/read.t: Added read tests for stripped,
+ planar contiguous, and planar seperated TIFFs.
+
+ * coders/tiff.c (ReadTIFFImage): Transferred stripped-TIFF
+ reading code from ImageMagick.
+ Enumerated reading methods to make the logic more clear.
+
+2003-02-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * JNG alpha sample depth was sometimes inconsistent.
+
+ * Bring only one line at a time into memory during PNG
+ read/write (Merge with Cristy's 5.5.6 update).
+
+2003-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Makefile.PL.in (LIBS): Put MAGICKLIB first to
+ decrease the probability that the wrong libMagick is used
+ when linking static PerlMagick.
+
+ * configure.ac (PerlMagick): Fix linker search path for
+ -lGraphicsMagick when linking a static PerlMagick. It seems
+ that libtool changed the location where it places static
+ libraries.
+
+ * PerlMagick/t/tiff/read.t: Added test for reading tiled TIFF.
+
+ * coders/tiff.c (ReadTIFFImage): Add optimized support for
+ reading tiled TIFFs.
+ (ReadTIFFImage): Optimize loops for reading tiled TIFFs as well.
+ (ReadTIFFImage): Eliminate compiler warning.
+ (ReadTIFFImage): Add some missing error handling for tiled TIFF.
+
+2003-02-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Optimize RGBA transfer loop.
+
+2003-02-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/render.c (DrawPrimitive): Return DrawPolygonPrimitive
+ status (edit transferred from ImageMagick).
+
+ * magick/utility.c (GetMagickGeometry): Scaling to an area now
+ preserves the image aspect ratio.
+
+2003-02-24 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * png.c: Added missing parentheses in typecast (cristy noticed
+ the bug that I introduced on 2/18).
+
+2003-02-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Add rules to produce www/README.html,
+ www/INSTALL-mac.html, www/INSTALL-unix.html, www/INSTALL-vms.html,
+ and www/INSTALL-windows.html
+
+ * www/README.html: New file produced from README.txt
+
+ * www/INSTALL-mac.html: New file produced from INSTALL-mac.txt.
+
+ * www/INSTALL-unix.html: New file produced from INSTALL-unix.txt.
+
+ * www/INSTALL-vms.html: New file produced from INSTALL-vms.txt.
+
+ * www/INSTALL-windows.html: New file produced from INSTALL-windows.txt.
+
+ * NEWS: Added news for GraphicsMagick 1.0.0.
+
+ * magick/locale.c: Added error messages to support JP2.
+
+ * locale/C.mgk: Added error messages to support JP2.
+
+ * locale/locale.mgk: Update to GraphicsMagick copyright.
+
+ * coders/jp2.c: Updated to use Jasper 1.700.1 interface
+ conventions. Jasper 1.700.1 is required now. Support
+ reading arbitrary quantum sizes up to 16-bits. Return
+ grayscale images as PseudoClass.
+
+ * jp2/: Updated Jasper sources to version 1.700.1.
+
+2003-02-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (ReadJP2Image): Obtain channel indexes by
+ ID rather than assuming index value. Validate that channel
+ geometry and encoding is supported.
+
+ * magick/effect.c (ThresholdImage): Additional performance
+ optimization. Work faster if image is already gray.
+
+2003-02-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (WriteJP2Image): Port to Jasper 1.7.
+ For Q:32, don't write 32-bit pixels rather than the
+ 16-bit pixels we told Jasper we would write.
+ (WriteJP2Image): Back-port to Jasper 1.6.
+
+2003-02-18 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/modules.mgk: Added JNG entry.
+
+2003-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (RegisterJP2Image): Added registration for
+ "PGX" magick tag.
+
+ * magick/magic.mgk: Added entry for JPEG V2's PGX format.
+
+ * PerlMagick/t/jp2/read.t: Added JPEG Version 2 read tests.
+
+ * coders/modules.mgk: Added JPC and PGX magick types to
+ support JPEG V2.
+
+ * magick/color.c (IsMonochromeImage): Re-arranged test logic
+ to short-circuit test using ORs.
+ (IsGrayImage): Re-arranged test logic to short-circuit test
+ using ORs.
+
+ * magick/constitute.c (PopImagePixels): Speed GrayQuantum
+ and GrayAlphaQuantum cases if is_grayscale is True.
+
+ * magick/quantize.c (AssignImageColors): Sync image to
+ update DirectClass pixels to new colormap.
+
+ * coders/fpx.c (RegisterFPXImage): FlashPIX does not
+ provide direct BLOB I/O support.
+
+ * magick/blob.c (BlobToImage): Add logging.
+ (BlobToFile): Add logging.
+
+2003-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/fpx.c (ReadFPXImage): Removing the input file is
+ antisocial.
+
+ * PerlMagick/t/fpx/*.fpx: Replaced with new copies. Files
+ seemed to be corrupt.
+
+ * PerlMagick/t/cgm/read.t: Specify file magick so that CGM
+ read test passes for BLOB case.
+
+ * PerlMagick/t/rad/read.t: Specify file magick so that RAD
+ read test passes for BLOB case.
+
+ * PerlMagick/t/jng/read.t: Add read tests for JNG.
+
+ * PerlMagick/t/jng/write.t: Add read/write tests for JNG.
+
+ * configure.ac (DELEGATES): Added `jng` to the DELEGATES list
+ so that JNG can be included in the PerlMagick tests.
+
+2003-02-18 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/png.c: Write proper JNG image_interlace_method.
+
+ * coders/png.c: Read and write proper MNG and JNG sRGB intent.
+
+ * PerlMagick/t/jng: Add twelve test files in JNG format.
+
+ * coders/png.c: Write proper progressive JNG output when
+ transparency is present.
+
+2003-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/version.c (GetMagickWebSite): New function.
+
+2003-02-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c (ipa_device_begin): Use MagickWebSite definition.
+
+ * www/Copyright.html: Updated to match Copyright.txt
+
+ * www/perl: Updated to reflect GraphicsMagick vs ImageMagick.
+
+ * magick/xwindow.c (XMakeImageMSBFirst): Minor loop optimizations.
+
+ * magick/constitute.c (ConstituteImage): Check for grayscale
+ and monochrome image if image is PseudoClass.
+
+2003-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/enhance.c (ContrastImage): Preserve is_grayscale flag.
+ (EqualizeImage): Preserve is_grayscale flag.
+ (ModulateImage): Preserve is_grayscale flag.
+ (NegateImage): Preserve is_grayscale flag.
+ (NormalizeImage): Preserve is_grayscale flag.
+
+ * magick/fx.c (ColorizeImage): Evaluate is_grayscale status.
+ (ConvolveImage): Preserve is_grayscale flag.
+ (ImplodeImage): Preserve is_grayscale flag.
+ (SolarizeImage): Preserve is_grayscale flag.
+ (OilPaintImage): Preserve is_grayscale flag.
+ (SwirlImage): Preserve is_grayscale flag.
+ (WaveImage): Preserve is_grayscale flag.
+
+ * magick/resize.c (MagnifyImage): Preserve is_grayscale flag.
+ (MinifyImage): Preserve is_grayscale flag.
+ (ResizeImage): Preserve is_grayscale flag.
+
+ * magick/decorate.c (FrameImage): Evaluate is_grayscale status.
+ (RaiseImage): Preserve is_grayscale.
+
+ * magick/shear.c (IntegralRotateImage): Preserve is_grayscale.
+ flag.
+ (XShearImage): Evaluate is_grayscale status.
+ (YShearImage): Evaluate is_grayscale status.
+
+ * magick/transform.c (ChopImage): Preserve is_grayscale flag.
+ (CropImage): Preserve is_grayscale flag.
+ (FlipImage): Preserve is_grayscale flag.
+ (FlopImage): Preserve is_grayscale flag.
+ (RollImage): Preserve is_grayscale flag.
+
+ * magick/effect.c (AddNoiseImage): If image colorspace is
+ GRAYColorspace, then add intensity noise, and transfer
+ image is_grayscale flag to output image.
+ (BlurImage): Preserve is_grayscale flag.
+ (DespeckleImage): Preserve is_grayscale flag.
+ (EdgeImage): Preserve is_grayscale flag.
+ (EmbossImage): Preserve is_grayscale flag.
+ (GaussianBlurImage): Preserve is_grayscale flag.
+ (MotionBlurImage): Preserve is_grayscale flag.
+ (ShadeImage): Preserve is_grayscale flag.
+ (SharpenImage): Preserve is_grayscale flag.
+ (UnsharpMaskImage): Preserve is_grayscale flag.
+
+ * magick/quantize.c (QuantizeImage): Pre-reduce gray images
+ to PseudoClass in order to quickly determine the number of
+ colors, and provide the expected PseudoClass output. Also
+ skip slow color quantization if there are already fewer
+ colors than requested.
+
+ * magick/image.c (GrayscalePseudoClassImage): New function
+ to quickly reduce an image to PseudoClass grayscale. This
+ is a fast way to determine the number of intensities in a
+ grayscale image. Either a compact sorted colormap or a faster,
+ contiguous linear colormap is created, depending on the
+ optimize_colormap flag. If the image is already PseudoClass,
+ and the optimize_colormap flag is True, then the existing
+ colormap is sorted and reduced.
+ (SyncImage): Preserve is_grayscale flag.
+ (ChannelImage): Result is grayscale.
+ (CycleColormapImage): Preserve is_grayscale and is_monochrome flags.
+ (SetImage): Evaluate is_grayscale flag.
+ (SetImageDepth): Preserve is_grayscale flag.
+ (SetImageOpacity): Preserve is_grayscale flag.
+ (SortColormapByIntensity): Preserve is_grayscale flag.
+ (TransformRGBImage): Evaluate is_grayscale flag.
+
+2003-02-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resize.c (SampleImage): Preserve grayscale and
+ monochrome flags.
+
+ * magick/quantize.c (AssignImageColors): Set image monochrome
+ flag to True when quantizing to two colors in GrayColorspace.
+
+ * magick/effect.c (SpreadImage): Preserve grayscale and
+ monochrome flags.
+ (AdaptiveThresholdImage): Short-circuit algorithm if image
+ flags indicate it is already monochrome. Set monochrome and
+ grayscale flags once algorithm completes.
+ (ThresholdImage): Short-circuit algorithm if image
+ flags indicate it is already monochrome. Set monochrome and
+ grayscale flags once algorithm completes.
+ (ChannelThresholdImage): Short-circuit algorithm if image
+ flags indicate it is already monochrome. Set monochrome and
+ grayscale flags once algorithm completes.
+ (ShadeImage): If grayscale shading is done, then set image
+ grayscale flag to True.
+
+ * magick/color.c (IsGrayImage): If the image is_grayscale
+ flag is True, then short-circuit the test. Update the flag
+ if the test is performed.
+ (IsMonochromeImage): If the image is_monochrome flag is True
+ then short-circuit the test. Update the flag if the test is
+ performed.
+
+ * magick/image.c (CloneImage): Copy image is_grayscale and
+ is_monochrome members.
+
+ * magick/cache.c (SyncCacheNexus): If image pixels are updated
+ then set image is_grayscale and is_monochrome members to False.
+ Algorithms which want to preserve the values of these members
+ should save their original values before processing the image
+ and restore them when processing is complete, or transfer them
+ from the input image to the output image.
+
+ * magick/constitute.c (ReadImage): If the returned image is
+ PseudoClass then invoke IsGrayImage() and IsMonochromeImage()
+ and cache the result in image is_grayscale and is_monochrome
+ members for later use.
+
+ * magick/image.h (Image): Added is_grayscale and is_monochrome
+ members to remember if image is grayscale or monochrome.
+
+2003-02-14 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * www/archives.html: commented out sites not mirroring GM yet.
+ Changed "ftp.simplesystems.org" to "ftp.graphicsmagick.org".
+ Added link to graphicsmagick.sf.net.
+
+2003-02-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (FormatString): Check for the availability of
+ vsprintf.
+
+ * magick/log.c (LogMagickEvent): Check for the availability of
+ vsprintf.
+
+ * configure.ac: Test for vsprintf.
+
+2003-02-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/annotate.c (RenderFreetype): Used smarter code to prepare
+ the beta argument for AlphaComposite.
+
+2003-02-12 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/logo.c: updated logo.c to produce the GraphicsMagick logo.
+
+2003-02-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * INSTALL-unix.txt: Document that default quantum depth is now 8.
+
+ * VisualMagick/magick/magick_config.h.in: Default quantum depth is now 8.
+
+ * configure.ac: Default quantum depth is now 8.
+
+ * tests/Makefile.am: Test format types that require a size
+ seperately since always specifying the size caused some formats
+ (e.g. PCD) to improperly fail.
+
+2003-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/NEWS.html: New HTML file for project news.
+
+ * scripts/txt2html: New script for formatting text into HTML.
+
+ * Makefile.am: Automated the generation of www/Changelog.html and
+ www/NEWS.html.
+
+ * coders/xpm.c (WritePICONImage): Close blob using correct image.
+
+ * tests/Makefile.am (CHECK_SIZED_FILES): Added files to tests
+ subdirectory so that tests don't need to use files from
+ PerlMagick.
+
+ * magick/image.c (TransformColorspace): New function to
+ simplify/centralize colorspace transform requests. Replaced calls
+ to RGBTransformImage and TransformRGBImage throughout the code
+ with calls to TransformColorspace.
+
+ * IMDisplay: Disable save function since it is not implemented yet.
+
+2003-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs (SetAttribute): Support changing back to
+ RGB or Transparent colorspace.
+
+2003-02-10 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Brought MNG handling of final delay into compliance with MNG spec.
+
+2003-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/bmp.c (WriteBMPImage): Added support for
+ bits_per_pixel==4.
+ (WriteBMPImage): Convert PseudoClass images with more than 256
+ colors to DirectClass.
+ (WriteBMPImage): Do not require 2-color images to pass the
+ IsMonochromeImage() test before writing them as one-bit-per-pixel
+ BMPs. Decided to allow this after four readers (including Windows
+ XP) displayed the image using the proper colormap.
+ (WriteBMPImage): BMP2 encoder was writing colormap using wrong format.
+
+ * images: Updated logo images to GraphicsMagick
+
+ * Added PDF Sages to web page as a sponsor.
+
+2003-02-08 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * www/GraphicsMagick.html: add "gm " prefix to examples.
+
+2003-02-07 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * index.html: Update to distinguish between ImageMagick and
+ GraphicsMagick, and to explain "gm" prefix of commandline utilities.
+
+2003-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_feature.c (CropImageToHBITMAP): Remove useless
+ autocrop support which was transferred from CropImage when
+ creating CropImageToHBITMAP.
+
+2003-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): RLE packet size was not
+ calculated correctly, causing RLE-compressed MIFF images with
+ depth>8 to not be read.
+
+2003-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/paint.c (ColorFloodfillImage): Transfered fix from
+ ImageMagick for the problem that floodfill using a tiled image
+ failed if the target color happened to match the current fill
+ color.
+
+2003-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Fixed preview error message.
+
+ * coders/preview.c: Previous update had broken noiseimage demo.
+ Also some cleanups.
+
+ * magick/display.c (XMagickCommand): No longer uses
+ MogrifyImage.
+
+ * coders/preview.c (WritePreviewImage): Re-wrote so that
+ MogrifyImage is no longer used. Resize image outside of the loop
+ to improve performance.
+
+2003-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ShadeImage): Use PixelIntensityToDouble macro.
+
+ * magick/image.h (PixelIntensityToDouble): Added
+ PixelIntensityToDouble macro to handle the case where pixel
+ intensity is used for floating arithmetic.
+
+2003-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Distribute files ChangeLog, INSTALL-mac.txt,
+ INSTALL-unix.txt, INSTALL-vms.txt INSTALL-windows.txt, and NEWS.
+
+2003-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/svg.c (SVGStartElement): Applied fix from ImageMagick to
+ compute SVG +> MVG viewbox correctly.
+
+ * magick/image.c (CloneImage): Applied fix from ImageMagick which
+ is purported to solve the problem that "negative (x,y) page offsets
+ did not clone properly".
+
+ * magick/gem.c (TransformHWB): Replace implementation with
+ ImageMagick's new version which is supposed to fix a rounding
+ error problem. Hard to say since implementation is totally
+ different.
+
+ * coders/msl.c (MSLStartElement): Applied fix for missing break
+ from ImageMagick.
+
+ * magick/integral_types.h: New header to include the integral
+ types typedefs. Needed new header in order to include in both
+ studio.h and api.h at the right point.
+
+ * magick/studio.h: Move nt_feature.h inclusion to the few modules
+ which actually use functions from it.
+
+ * magick/api.h: Added typedefs gm_int16_t, gm_uint16_t,
+ gm_int32_t, gm_uint32_t, gm_int64_t, gm_uint64_t to support
+ specifically sized types.
+
+ * configure.ac: Test for size of `short`, `unsigned short`, `int`,
+ `unsigned int`, `long`, `unsigned long`, `long long`, `unsigned
+ long long` assigning the result to the defines SIZEOF_SHORT,
+ SIZEOF_UNSIGNED_SHORT, SIZEOF_INT, SIZEOF_UNSIGNED_INT,
+ SIZEOF_LONG, SIZEOF_UNSIGNED_LONG, SIZEOF_LONG_LONG, and
+ SIZEOF_UNSIGNED_LONG_LONG respectively.
+
+2003-01-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/fx.c (OilPaintImage): Compute histogram using 8-bit quantums
+ for more sensible performance with Q:16 and Q:32 builds.
+
+ * magick/image.h (PixelIntensityToQuantum): Compute using integral
+ arithmetic for Q:8 and Q:16. Much faster than floating point!
+ (PixelIntensity): Compute using integral arithmetic for Q:8 and
+ Q:16. Much faster than floating point!
+
+2003-01-28 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * Fixed bug in png.c, introduced in IM-5.5.1. A pair of
+ { } brackets were omitted when logging was added, which lets
+ old versions of libpng write a zero-length iCCP chunk.
+
+2003-01-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (DespeckleImage): Put loops inside of case
+ statement rather than outside.
+ (SpreadImage): Improved algorithm so that -spread is 12X faster.
+
+ * magick/nt_feature.c (CropImageToHBITMAP): New function to return
+ a region of the image as a HBITMAP.
+
+2003-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fixed Copyright statement on all source files.
+
+ * magick/effect.c (ThresholdImage): Optimized loop.
+
+ * coders/tiff.c (ReadTIFFImage): Read bits more efficiently for
+ bits_per_sample=1.
+
+ * magick/command.c (MogrifyImage): Set image->dither to
+ image_info->dither prior to invoking SetImageType.
+
+ * magick/constitute.c (WriteImage): Set image->dither to
+ image_info->dither.
+
+ * magick/image.c (SetImageType): For case BilevelType, normalize
+ image, and threshold 50% if dithering is disabled. This is at
+ least 10X faster than quantizing with dither.
+ (AllocateImage): Initialize image->dither.
+ (CloneImage): Copy image->dither.
+
+ * magick/image.h: Added dither member to Image.
+
+2003-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/tiff/read.t: Added a test for reading 16-bit TIFF
+ images.
+
+ * coders/tiff.c (ReadTIFFImage): Support reading 16-bit TIFF images
+ with a Q:8 build.
+
+ * magick/color.c (ConstrainColormapIndex): Use VerifyColormapIndex.
+
+ * coders/pnm.c (ReadPNMImage): Use VerifyColormapIndex.
+
+ * coders/gif.c (DecodeImage): Use VerifyColormapIndex.
+
+ * magick/image.c (SyncImage): Use VerifyColormapIndex.
+
+2003-01-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (ReadBlobByte): Use getc when reading from FILE stream.
+
+ * configure.ac: Added tests for getc_unlocked and putc_unlocked.
+
+ * magick/blob.c (ReadBlobByte): Optimized reading from BlobStream.
+ (ReadBlobLSBLong): Optimized reading from BlobStream.
+ (ReadBlobLSBShort): Optimized reading from BlobStream.
+ (ReadBlobMSBLong): Optimized reading from BlobStream.
+ (ReadBlobMSBShort): Optimized reading from BlobStream.
+ (ReadBlobStream): New static inline function to read from BlobStream.
+ (WriteBlob): "Manually" copy data rather than using memcpy() for
+ very small copy sizes.
+ (WriteBlobByte): Use putc() when writing to a FILE stream.
+
+2003-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/gem.c (Hull): Count down loops. Might help.
+ (InterpolateColor): Pre-compute common sub-expressions to improve
+ performance.
+
+ * magick/segment.c (Classify): Implemented idea from Glenn
+ Randers-Pehrson to avoid use of pow() when WeightingExponent is
+ 2.0 (which it is). This makes image segmentation much faster
+ (e.g. 8X).
+
+ * magick/annotate.c (RenderFreetype): For images with
+ matte==False, simply set the opacity of the pixel to be updated to
+ OpaqueOpacity before alpha-compositing the pixel rather than using
+ SetImageType(TrueColorMatteType) to initialize the opacity of the
+ entire image. This is much faster and scales to large images.
+
+ * magick/image.c (SetImageType): Eliminated unnecessary conditionals.
+
+2003-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (InsertMedianList): Assign computed quantum
+ indexes to variables to avoid extra computations for
+ QuantumDepth>8.
+
+ * magick/composite.c (AlphaComposite): Pre-compute common
+ expressions in order to improve performance.
+
+ * magick/fx.c (ConvolveImage): Optimized loops.
+
+ * magick/paint.c (TransparentImage): Optimize for case fuzz == 0.
+
+ * magick/color.c (FuzzyColorMatch): Minor cleanup and optimization.
+
+ * magick/locale.c: Added error messages for convolve option.
+
+ * coders/locale.c: Picked up recent changes from ImageMagick version.
+
+ * locale/C.mgk: Added error messages for convolve option.
+
+ * magick/command.c (MogrifyImage): Added support for convolve option.
+
+ * coders/xcf.c (ReadXCFImage): Recognize latest GIMP XCF header.
+
+ * coders/dcm.c: Transferred the apparent salient fixes from
+ ImageMagick for a bug described as "Some DCM grayscale images did
+ not display correctly.".
+
+ * coders/miff.c (ReadMIFFImage): Reading RLE-compressed MIFFs is
+ now about 4X faster.
+
+ * magick/blob.c (OpenBlob): Use setvbuf() to increase stdio buffer
+ size to 16K. Solaris default is 1K. This should minimize system
+ call overhead for accessing large files.
+ (ReadBlob): "Manually" copy data rather than using memcpy() for
+ very small copy sizes.
+ (ReadBlobZC): New method, similar to ReadBlob, but provides the
+ opportunity for zero copy on read.
+
+ * magick/constitute.c (PushImagePixels): CMYKA case for
+ image->depth=16 was comparing with 8 instead.
+
+2003-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetMagickGeometry): Removed support for `~`
+ and disabled centering code until we learn where it should go (if
+ anywhere).
+
+ * magick/command.c : Add HWB colorspace transform support.
+
+ * PerlMagick/Magick.xs: Add HWB colorspace transform support.
+
+ * magick/image.c (RGBTransformImage): Add HWB colorspace transform
+ support.
+ (TransformRGBImage): Add HWB colorspace transform support.
+
+2003-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetMagickGeometry): Add support for new new
+ `~` geometry string flag. This also fixes a montage bug in which
+ thumbnails were mis-sized if the geometry specification incuded x
+ or y offsets.
+
+ * magick/image.h (GeometryFlags): Added CenterValue enumeration to
+ correspond with new `~` geometry string flag. Taking
+ ImageMagick's lead on this.
+
+ * magick/render.c: Transferred fixes from ImageMagick for an
+ artifact which occured at the 360 degree point when rendering
+ circles, ellipses, and arcs. Bug reported by io219@attbi.com.
+
+ * PerlMagick/Magick.xs: Add HSL colorspace transform support.
+
+ * magick/command.c: Add HSL colorspace transform support.
+
+ * magick/image.c (RGBTransformImage): Add HSL colorspace transform
+ support.
+ (TransformRGBImage): Add HSL colorspace transform support.
+
+2003-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated copyright statement on source files to reflect
+ the GraphicsMagick Group rather than ImageMagick Studio.
+
+ * magick/constitute.c (ConstituteImage): Simplified the switch
+ statement for inner loops by creating a simplified map in advance.
+ (DispatchImage): Simplified the switch statement for inner loops
+ by creating a simplified map in advance.
+
+ * magick/compress.c (HuffmanEncodeImage): Test and cache the
+ return value of LocaleCompare(image_info->magick,"FAX") so that
+ LocaleCompare is not executed repeatedly in the output loop.
+
+ * magick/color.c (IsGrayImage): Optimized loops.
+ (IsMonochromeImage): Optimized loops.
+ (IsOpaqueImage): Optimized loop.
+
+ * magick/delegate.c (InvokePostscriptDelegate): When using the
+ Ghostscript library, identify the library as "[ghostscript library]"
+ rather then "gsdll32" so that -verbose prints something useful for
+ both Windows and Unix.
+
+2003-01-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS: New file.
+
+ * magick/montage.c (MontageImages): Use ThumbnailImage() rather
+ than ZoomImage() to resize montage thumbnails provided that the
+ user has not specified an image filter, and the montage thumbnail
+ is smaller than the image. This should provide faster montages
+ for large images.
+
+ * magick/resize.c (ResizeImage): Added logging support.
+ (MagnifyImage): Added logging support.
+ (MinifyImage): Added logging support.
+ (SampleImage): Added logging support.
+ (ScaleImage): Added logging support.
+
+2003-01-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/transform.c (ProfileImage): Duplicate ImageMagick changes
+ to image colorspace handling. Avoids using
+ SetImageType(image,ColorSeparationMatteType).
+
+ * magick/fx.c (OilPaintImage): Replaced with ImageMagick version
+ since ImageMagick version has been updated to not penalize Q:8.
+ Optimized loops.
+
+ * magick/display.c (XDisplayImage): Display to 100% of
+ the screen size rather than 90% of the screen size.
+
+ * magick/enhance.c (ModulateImage): Ensure that arguments
+ are always positive values. Optimized loops.
+ (ContrastImage): Optimized loops.
+
+ * magick/gem.c (HSLTransform): Optimized performance by
+ eliminating redundant intermediate calculations. This
+ makes `gm convert -contrast` 21% faster.
+ (HSLTransform): Set to inline within the gem.c module.
+ (TransformHSL): Set to inline within the gem.c module.
+ (Contrast): Moved to bottom of gem.c module so HSLTransform
+ and TransformHSL can be inlined. Simplified conditionals.
+ (Modulate): Moved to bottom of gem.c module so HSLTransform
+ and TransformHSL can be inlined. No longer check/correct
+ negative values.
+
+2003-01-14 William Radcliffe <billr@corbis.com>
+
+ * magick/blob.c
+
+ * magick/blob.h
+ Added new stream type flag and support to match with the one
+ added to ImageMagick.
+
+2003-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (RGBTransformImage): Fixed bug (thanks to
+ Bill for finding it) and finished optimizing XYZ table
+ creation.
+ (AverageImages): Optimized loops.
+ (ChannelImage): Optimized loops. 3X speed-up for SPARC.
+
+ * magick/enhance.c: Optimized NegateImage().
+
+2003-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Set some common API structures to 0xbf prior to deallocation
+ to make accidental continued use more obvious.
+
+2003-01-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c: Minor optimizations to PopImagePixels()
+
+ * coders/dpx.c: Reading the DPX header was off by 4 bytes.
+
+ * coders/(art.c,avs.c,bmp.c,cmyk.c,dcm.c,dib.c,dpx.c,fax.c,
+ fits.c,gray.c,icon.c,map.c,miff.c,mono.c,mpc.c,mtv.c,otb.c,
+ pcx.c,pdb.c,pict.c,pix.c,pnm.c,pwp.c,rgb.c,rla.c,rle.c,sct.c,
+ sgi.c,sun.c,tga.c,tim.c,uyvy.c,vicar.c,viff.c,wbmp.c,xwd.c,
+ yuv.c): Ensure that blob is closed on unexpected EOF.
+
+ * magick/image.c: Optimized SetImageOpacity().
+ Optimized SetImage() for intializing non-opaque images. The
+ opacity channel was being intialized twice.
+
+2003-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c: Log entry and exit from coders so that
+ coders don't need to.
+
+ * Finished re-writing PushImagePixels() using coding practices
+ which may result in faster code.
+
+ * PerlMagick is changed from Image::Magick to Graphics::Magick
+ in order to avoid conflicts with the ImageMagick version. This
+ means that any Perl scripts based on the ImageMagick version need
+ to do a global replace of Image::Magick to Graphics::Magick.
+
+ * PerlMagick/reference/filter/Raise.miff: Replaced with new version.
+
+2003-01-08 William Radcliffe <billr@corbis.com>
+
+ * magick/nt_feature.c
+ Make ImageToHBITMAP function in nt_feature.c compile under Visual
+ C++ again.
+
+2003-01-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/delegates.mgk.in: Fix cgm entry. How did it become so
+ terribly broken?
+
+ * coders/dps.c: Adding logging support.
+
+ * PerlMagick/t/read.t: Changed file read tests to use image
+ compares with a reference image rather than comparing with a
+ signature.
+
+ * PerlMagick/t/wmf/read.t: Ditto.
+ magick/shear.c: Fixed documentation for RotateImage.
+
+2003-01-08 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/magick.c, magick/magick.h: Add "note" member of magick_info.
+
+ * coders/art.c, coders/fax.c, coders/dcm.c, coders/png.c: add notes
+ to format registrations.
+
+ * fx.c: changed default "colorize" behaviour to preserve image opacity.
+
+2003-01-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/svg.c: Allow the user to specify the initial background
+ color via the -background option. This is only useful if the SVG
+ doesn't draw its own background rectangle.
+
+2003-01-06 Albert Chin-A-Young <china@thewrittenword.com>
+
+ * ltdl/Makefile.am, ltdl/ltdl.c: Fix compilation problem
+ under Tru64 UNIX 5.1. The GraphicsMagick random.h was being
+ included when the system random.h was needed.
+
+ * configure.ac: Improve robustness of POSIX thread API tests
+ by including pthread.h when building the test program.
+
+2003-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c: In IsImagesEqual() only use type `long double`
+ for error summation if QuantumDepth > 16 and `long double` has
+ more range than `double`.
+
+ * magick/quantize.c: In QuantizeImage() only use type `long
+ double` for error summation if QuantumDepth > 16 and `long
+ double` has more range than `double`.
+
+ * Replaced redundant code with macros.
+
+ * Optimize mapping to monochrome.
+
+ * utilities/conjure.c: Had missed removing this file earlier.
+
+2003-01-04 Derry Bryson <dbryson@techass.com>
+
+ * magick/decorate.c: Use the ShadowFactor rather than ShadowModule
+ define in RaiseImage() (bug-fix).
+
diff --git a/ChangeLog.2004 b/ChangeLog.2004
new file mode 100644
index 0000000..904d19d
--- /dev/null
+++ b/ChangeLog.2004
@@ -0,0 +1,1491 @@
+2004-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (DescribeImage): Add normalized channel
+ statistics to output.
+
+ * NEWS: Updated with changes since July.
+
+ * magick/constitute.c (ImportImagePixelArea): For GrayQuantum,
+ GrayInvertedQuantum, GrayAlphaQuantum, and
+ GrayInvertedAlphaQuantum, observe image storage_class so that a
+ gray DirectClass image may be created.
+
+ * coders/tiff.c (ReadTIFFImage): Fix overflow when computing
+ colormap size for bits-per-sample of 32.
+ (WriteTIFFImage): Support writing 32-bit RGB(A) for
+ QuantumDepth=32 build.
+ (ReadTIFFImage): Support reading 32-bit RGB(A) for QuantumDepth=32
+ build. Support reading 32-bit grayscale without any quality loss
+ for QuantumDepth=32 build.
+
+2004-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): TrueColor 16-bits/sample RGB
+ images were being written incorrectly on little-endian CPUs.
+ Added byte swapping to fix this problem.
+
+2004-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/operator.c: New file for quantum operator implementation.
+ (QuantumOperatorImage): Moved from image.c.
+ (QuantumOperatorRegionImage): Moved from from image.c.
+
+2004-12-22 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * magick/Makefile.am (MAGICK_BASE_SRCS): Remove mention of
+ non-existent mmath.h.
+
+ * configure.ac: AC_LIBTOOL_SETUP is an internal macro and must not
+ be used externally (will be pulled in automatically).
+
+ * PerlMagick/Makefile.am: Missing file needed to be committed to CVS.
+
+ * tests/Makefile.am (TESTS_TIFF_XFAIL_TESTS): EPT and PTIF tests
+ are expected to fail if libtiff is missing.
+
+2004-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * TODO.txt: Organized todo list for 1.2 release.
+
+2004-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/bmp.c (WriteBMPImage): Handle the case where the image
+ has an over-sized colormap. Was writing on unallocated heap memory.
+
+ * coders/dib.c (WriteDIBImage): Handle the case where the image
+ has an over-sized colormap. Was writing on unallocated heap memory.
+
+2004-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/gem.c (Modulate): Hue argument now represents a rotation
+ from -180 degrees to +180 degrees expressed as an argument of 0 to
+ 2.0 (1.0 for no change). Note that this change also effects the
+ -modulate argument and the Magick++ modulate method(). This change
+ is made because the previous hue adjustment strategy only
+ succeeded in corrupting the image.
+
+2004-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (opendir): Ensure that data may not overwrite
+ the stack.
+ (readdir): Ensure that data may not overwrite the stack.
+
+ * magick/blob.c (ImageToBlob): Ensure that image->logging is
+ set prior to encoding image.
+
+ * magick/constitute.c (WriteImage): Ensure that image->logging is
+ set prior to encoding image.
+
+2004-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * rungm.sh.in: Compute final variable definitions from within
+ configure in order to improve MinGW test execution times.
+
+2004-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/gif.c: Fix two error-path memory leaks which were noticed
+ by Glenn Randers-Pehrson.
+
+2004-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c (UnregisterPNGImage): Eliminate Warning: module
+ registration for "JNG" from module "PNG" still present!
+
+2004-11-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (DispatchImage): Fix documentation error
+ regarding return status.
+
+2004-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.h: Only define HAVE_GLOBALMEMORYSTATUSEX for MSVC
+ 7.0 and later.
+
+2004-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Ensure that words in the
+ scanline are converted to little-endian format on little-endian
+ CPUs.
+
+2004-11-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (MagickStrlCat): New function which is
+ equivalent to to OpenBSD's strlcat() function. Concatenates one
+ string onto another within a fixed size buffer while ensuring null
+ termination.
+ (MagickStrlCpy): New function which is equivalent to OpenBSD's
+ strlcpy() function. Copies a string into a fixed size buffer
+ while ensuring null termination.
+
+ * coders/gif.c (DecodeImage): Improve handling of corrupt GIF
+ files. Resolves SourceForge bug #1042904. Also, eliminate a
+ potential memory leak.
+
+ * magick/constitute.c (WriteImages): ImageInfo argument is now a
+ const pointer.
+
+2004-10-26 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * magick/render.c (TracePath): Applied bugfix from Cristy.
+
+2004-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (InitializeMagickResources): Use
+ GlobalMemoryStatusEx if it is available.
+
+ * magick/nt_base.c (lt_dlopen): Handle errors while loading
+ modules rather than allow Windows to display a GUI dialog box.
+ (NTKernelAPISupported): New function to support testing to see if
+ a Windows kernel API is supported.
+
+ * magick/constitute.c (ExportImagePixelArea): Add special-case for
+ bilevel gray image in order to restore performance.
+ (ImportImagePixelArea): Add special-case for bilevel gray image in
+ order to restore performance.
+
+ * coders/jpeg.c (ReadJPEGImage): Fix GCC warning about variable
+ being clobbered by longjmp.
+
+ * Re-port build to MinGW. Modules build passes all tests.
+
+ * Skip build and install of modules if a key library is not available.
+
+ * Partial recode of metadata handling to use Get/Set profile
+ functions. Big job!
+
+ * GCC warnings reduction.
+
+ * Remove MVG detection from magic.mgk due to security risk.
+
+2004-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Properly detect and handle
+ errors reported by libtiff so that failure is reported rather than
+ writing a corrupted output file.
+ (WriteNewsProfile): Re-write so implementation is easier to
+ understand.
+
+2004-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c: Don't use deprecated tiff.h _SUPPORT defines.
+ Support retrieving and saving XMP profile. Use profile set/get
+ methods in implementation.
+
+ * coders/mat.c,coders/topol.c (ReadBlobWordLSB,ReadBlobDoublesLSB):
+ Use better variable name than `I` for image.
+
+2004-09-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (WriteMIFFImage): Ensure that MIFF files are never
+ written with bogus compression values.
+
+ * magick/image.h: Protected/hid constants which only exist to
+ support the library implementation.
+
+ * tests/Makefile.am (TESTS_X11_XFAIL_TESTS): Fixed syntax error.
+
+ * Makefile.am: Use one Makefile to rule them all as described in
+ Peter Miller's excellent paper, Recursive Make Considered Harmful,
+ "http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html".
+ Some glitches may remain.
+
+ * coders/tiff.c (TIFFErrors): Prevent possible stack overflow on
+ error.
+ (TIFFWarnings): Prevent possible stack overflow on error.
+
+ * magick/constitute.c (ImportImagePixelArea): For RGBQuantum
+ initialize the opacity channel since it is easier than altering
+ all code to properly access it.
+
+2004-09-02 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * magick/transform.c: Bugfix from Cristy in CoalesceImages().
+
+2004-08-26 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * Avoid error introduced in libpng-1.2.6 that causes the encoder
+ to write out-of-spec zlib header bytes.
+
+2004-08-24 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/bmp.c is said to have a potential buffer overrun.
+ Patch from Cristy applied (also to avi.c and dib.c).
+
+2004-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Use ExportImagePixelArea to
+ write grayscale and colormapped output.
+
+ * magick/constitute.c (ImportImagePixelArea): Implemented support
+ for GrayInvertedQuantum & GrayInvertedAlphaQuantum.
+ (ExportImagePixelArea): Implemented support for
+ GrayInvertedQuantum & GrayInvertedAlphaQuantum.
+
+ * magick/constitute.h (enum QuantumType): Added
+ GrayInvertedQuantum & GrayInvertedAlphaQuantum to support
+ min-is-white gray images.
+
+2004-08-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/tiff/write.t: Adjusted file naming.
+
+ * PerlMagick/t/tiff/read.t: Added more tests.
+
+ * coders/tiff.c (ReadTIFFImage): Use ImportImagePixelArea to read
+ PseudoClass tiff.
+ (WriteTIFFImage): Allow user to set the bits-per-sample define to
+ any value in the range of 1 to 32.
+ (ReadTIFFImage): Fix endian-reordering for DirectClass read and
+ bits-per-sample values ranging 9-15.
+
+ * coders/rgb.c: Support reading & writing 32-bit depths for raw
+ RGB images.
+
+ * coders/cmyk.c: Support reading & writing 32-bit depths for raw CMYK
+ images.
+
+ * coders/gray.c: Support reading & writing 32-bit depths for raw gray
+ images.
+
+ * magick/deprecate.c (PopImagePixels): Deprecated function.
+ (PushImagePixels): Deprecated function.
+
+ * magick/constitute.c (ExportImagePixelArea): New function to
+ export pixel region using specified QuantumType and
+ bits-per-sample.
+ (ImportImagePixelArea): New function to import pixel region using
+ specified QuantumType and bits-per-sample.
+
+2004-08-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/cache.c (ClonePixelCache): It appeared that cloning a
+ disk-based pixel cache was limited to the maximum value of
+ size_t. This would result in a truncated cache. The offset type
+ is changed from size_t to magick_off_t in order to avoid this.
+
+ * configure.ac: Check to see if the `char` type is unsigned,
+ mostly out of curiosity since the code does not currently make use
+ of the result.
+
+ * Fixed many compilation warnings when the compiler warning level
+ is set as high as possible.
+
+ * configure.ac: Check /usr/share/ghostscript/fonts for Ghostscript Type1
+ fonts.
+
+2004-08-13 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * tEXt and zTXt were inadvertently included in list of unused chunks.
+
+2004-08-09 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * fix incorrect argument to png_set_keep_unknown_chunks().
+
+2004-08-07 David R. Linn <drl@vuse.vanderbilt.edu>
+
+ * www/formats.html: Titles for JNG and MNG were reversed.
+
+2004-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/widget.c (XCommandWidget): Replace ImageMagick logo in
+ display command menu with GraphicsMagick logo.
+
+2004-08-05 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/png.c: Fixes for CERT security alert TA04-217A described
+ at "http://www.us-cert.gov/cas/techalerts/TA04-217A.html".
+
+2004-08-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h (Image): Changed type of `colors` and `depth`
+ members from type `unsigned long` to `unsigned int`. This change
+ is made because on 64-bit CPUs, `unsigned long` is a 64-bit
+ type. The depth member is often used in switch statements. It is
+ not recommended to use 64-bit types in switch statements. The
+ maximum number of colors in the colormap is limited to 64K so a
+ 64-bit type is not required.
+
+2004-08-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Restore previous 8/16
+ bits-per-sample support code in order to regain lost performance.
+
+2004-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Support reading RGB/CMYK scanline
+ oriented TIFF images with arbitrary depth.
+
+2004-07-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Update to Automake 1.9.
+
+2004-07-20 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick\magick\GM_magick.bpr: Updated to reflect changes since last update.
+
+ * BCBMagick\magick\libMagick.bpr: Updated to reflect changes since last update.
+
+ * BCBMagick\bzlib\GM_bzlib.bpr: Updated version number.
+
+ * BCBMagick\lcms\BCB6\GM_lcms.bpr: Updated version number.
+
+ * BCBMagick\Magickpp\lib\GM_magickpp.bpr: Updated version number.
+
+ * BCBMagick\ttf\GM_ttf.bpr: Updated version number.
+
+ * BCBMagick\zlib\GM_zlib.bpr: Updated version number.
+
+ * BCBMagick now support full LZW encoding (read/write).
+
+2004-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tiff/libtiff/tif_lzw.c: Replace with version which supports LZW encoding.
+
+ * magick/channel.c: New source file.
+ (ExportImageChannel): New function to export an image channel.
+ (ImportImageChannel): New function to import an image channel.
+
+2004-07-20 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * lcms/src/cmsio1.c: Test [testcms.c] related to lcms 1.13 fail
+ with error #12288 when perform "Checking saved linearization
+ devicelink". Fixed function __cmsSaveProfile(). "...malloc(0) is
+ implementation dependent and may return non NULL pointer on some
+ compilers, like VC++ and gcc. This is not the case of Borland C++
+ Builder" - Thanks to Marti Maria that have supplied me this
+ patched file: this will be part of the next lcms 1.14 which
+ probabily will be released on summer's end.
+
+2004-07-20 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * lcms/include/lcms.h: Modified to achieve BCBMagick DLL compilation.
+ Included modifications was introduced in GM in 2004-01-16 and
+ probabily lost with latest update of library.
+
+2004-07-20 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick: Updated lcms to version 1.13.
+ + Modified files: BCBMagick\All\bcbMagick.mak; BCBMagick\lcms\BCB6\GM_lcms.bpr;
+ BCBMagick\lcms\BCB6\lcms.bpg; BCBMagick\lcms\BCB6\lcms.bpr;
+ BCBMagick\lcms\BCB6\testcms.bpr
+ + Deleted files: BCBMagick\lcms\BCB6\lcms.cpp; BCBMagick\lcms\BCB6\testcms.cpp
+ + Added file: BCBMagick\lcms\BCB6\lcms.bpf
+
+2004-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Fix typo regarding -define tiff:samples-per-pixel.
+
+ * doc/GNUmakefile (utility-install): Utility HTML targets were not being installed.
+
+2004-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lcms: Updated to version 1.13.
+
+2004-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh (CVS_BRANCH_TAG): Record the CVS branch tag that
+ source package is obtained from.
+
+2004-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Pass essential flags on down to subordinate
+ configures when performing `make distcheck`. Support DESTDIR
+ installs for PERL 5.8.1 and later, which support DESTDIR
+ internally.
+
+2004-07-16 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick\coders\libCoders.bpr; BCBMagick\magick\GM_magick.bpr: include
+ file jbig.h could not be found during compilation. Solved.
+
+2004-07-15 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick\magick\magick_config.h.: enabled LZW compression by default.
+
+ * BCBMagick: included jbig delegate library.
+ + Modified these files into directory BCBMagick: All\bcbMagick.mak;
+ All\GMlib.bpg; All\GMdll.bpg; coders\libCoders.bpr; magick\GM_magick.bpr;
+ utilities\gm_lib.bpr; utilities\gm_dll.bpr
+ + Added these files into new directory BCBMagick\jbig: jbig.bpr;
+ jbig.bpf; GM_jbig.bpr; GM_jbig.c; tstcodec.bpr
+ + Modified file jbig\jbiglib\jbig.h;
+
+ * BCBMagick\readme.txt: updated documentation.
+
+2004-07-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyUsage): -ordered-dither help was
+ formatted incorrectly.
+
+ * doc/options.imdoc: Improve formatting a bit for manual pages and
+ fix some syntax errors.
+
+2004-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS: Updated to reflect changes since last update.
+
+2004-07-09 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/bmp.c (ReadBMPImage): Removed if-test on reading
+ red_mask, green_mask, and blue_mask. These are only *valid*
+ under certain conditions, but they are always present in the
+ file.
+
+2004-07-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Enable LZW compression by default.
+
+2004-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (WriteJPEGImage): Don't enable Huffman compression
+ for large images (> 16 Mpixels for the moment) in order to
+ conserve memory. When Huffman compression is enabled the entire
+ image is buffered in memory prior to encoding and writing
+ anything. Huffman compression is a method of eliminating
+ redundant data so when the Huffman compression is disabled, files
+ sizes will be larger, but otherwise the image is the same.
+
+ * wand/magick_wand.c (MagickSetPassphrase): String was being
+ copied to a null pointer. Now memory is allocated as required
+ prior to a copy.
+ Ensure that all unimplemented functions return a proper error
+ report.
+
+2004-07-01 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick: updated to GraphicsMagick v.1.2
+
+ * BCBMagick\All: project GMlib-1.1.bpr has been replaced with
+ GMlib.bpr
+
+ * BCBMagick\All: project GMdll-1.1.bpr has been replaced with
+ GMdll.bpr
+
+ * BCBMagick\readme.txt: updated documentation.
+
+2004-06-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): For -units, don't reset
+ resolution if units are undefined. Report an error if the -units
+ argument is not supported.
+
+2004-06-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): When setting image units, also
+ adjust existing image x_resolution and y_resolution so that
+ existing image resolution is not trashed.
+ (MogrifyImage): When re-sampling an image, report an error if the
+ image does not contain a valid resolution.
+
+2004-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pcx.c (WritePCXImage): Support writing large PCX files.
+ (WritePCXImage): Ensure that UndefinedResolution is handled
+ properly. Avoid round-off error for centimeter based resolution.
+
+2004-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Look for mozilla by default rather than netscape.
+
+2004-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/type.c (ReadTypeConfigureFile): Determine location of
+ Ghostscript fonts only once in order to improve performance.
+
+ * magick/nt_base.c (NTGhostscriptFonts): Properly determine
+ Ghostscript font location for Ghostscript 8.0 and later.
+
+ * GraphicsMagick.spec.in: Install *-config scripts with mode 755
+ rather than default 644.
+
+2004-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/module.c (InitializeModuleSearchPath): Evaluate and cache
+ module search path.
+ (FindMagickModule): Use cached module search path.
+ (OpenModules): Load all modules rather than just the modules in
+ the directory where the LOGO module is found. Besides allowing
+ user-provided modules in non-GraphicsMagick directories to be
+ loaded, this allows the "moby" shared build to load additional
+ modules via OpenModules.
+
+2004-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/Makefile.am (check): Add convert -list tests.
+
+2004-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Magick++ needs to be built as a static library
+ under Cygwin and MinGW since C++ exceptions don't work otherwise.
+ Be more assertive about that.
+
+ * magick/nt_base.h: Avoid conflict with ssize_t definition under
+ MinGW.
+
+2004-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (DispatchImage): Support 8-bit output to
+ common formats BGR, BGRO, BGRP, RGB, RGBO, and I as special cases
+ in order to improve performance.
+ (ConstituteImage): Support 8-bit input from common formats BGR,
+ BGRO, BGRP, RGB, RGBO, and I as special cases in order to improve
+ performance.
+
+2004-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ltmain.sh: Fix to allow exe wrapper to work under MinGW.
+
+ * wand/magick_compat.c (QueryMagickColor): Fixed DLL export.
+
+ * wand/magick_wand.c: Fixed some DLL exports (MagickExport->WandExport).
+
+2004-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageClipMask): Consistently report any
+ exceptions to image->exception.
+
+2004-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Update to Automake 1.8.5.
+
+ * magick/image.h (ImageInfo): New `progress` monitor to indicate
+ if progress monitor and busy cursor are enabled while displaying
+ an image. Defaults to True.
+
+ * magick/display.c, magick/xwindow.c: Use +progress to disable
+ progress monitor and busy cursor.
+
+ * magick/command.c (MogrifyUsage): Usage didn't list -operator.
+ (ConvertUsage): Usage didn't list -operator.
+
+2004-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/compress.c (HuffmanDecodeImage): Properly return error status.
+ (HuffmanEncode2Image): Properly return error status.
+
+ * magick/composite.c (CompositeImage): Properly return error status.
+
+ * magick/quantize.c (ClassifyImageColors): Properly return error status.
+ (GetImageQuantizeError): Properly return error status.
+ (OrderedDitherImage): Properly return error status.
+
+ * magick/profile.c (ProfileImage): Properly return error status.
+
+ * magick/paint.c (ColorFloodfillImage): Properly return error status.
+ (MatteFloodfillImage): Properly return error status.
+ (OpaqueImage): Properly return error status.
+ (TransparentImage): Properly return error status.
+
+ * magick/enhance.c (ContrastImage): Properly return error status.
+ (EqualizeImage): Properly return error status.
+ (GammaImage): Properly return error status.
+ (LevelImage): Properly return error status.
+ (LevelImageChannel): Properly return error status.
+ (ModulateImage): Properly return error status.
+ (NegateImage): Properly return error status.
+ (NormalizeImage): Properly return error status.
+
+ * magick/image.c (GetImageClipMask): New function to retrieve an
+ associated clip-mask image.
+ (SetImageClipMask): Clip-mask image parameter may be const since
+ it is cloned prior to storage.
+ (ChannelImage): Properly return error status.
+ (GradientImage): Properly return error status.
+ (RGBTransformImage): Properly return error status.
+ (TransformRGBImage): Properly return error status.
+ (SyncImage): Return an error status.
+
+ * magick/enhance.c (NegateImage): If image has a clip mask,
+ then force image to DirectClass so clip mask takes effect.
+
+2004-05-15 Vladimir Lukianov <lvm@integrum.ru>
+
+ * magick/image.c (SetImageOpacity): Ensure that image is
+ DirectClass. If specified opacity is TransparentOpacity, then
+ replace existing opacity with TransparentOpacity.
+
+2004-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Avoid duplicated test status messages for __func__
+ tests. Avoid duplicated test status message for jpeg 6b test.
+
+2004-04-19 Patrick Welche <prlw1@newn.cam.ac.uk>
+
+ * www/header.html: HTML syntax fixes.
+
+2004-04-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * : Change web pages to a frames-based design.
+
+2004-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/Makefile.am (check): Change geometry arguments which
+ were expressed as 0.0xVAL to avoid the problematic Linux scanf
+ feature back to 0xVAL.
+
+2004-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/symbols.h (GetMagickDimension): Added GetMagickDimension.
+
+2004-04-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetMagickDimension): New function to replace
+ occurances of scanf(geometry,"%lfx%lf",&w,&h) since Linux scanf()
+ and strtod() misbehave for strings that start with "0x". The Linux
+ versions always treat 0x as the start of a value expressed in hex
+ and can't be forced to read the leading value as a double. This
+ function has been applied globally to replace the problem scanf's.
+
+ * magick/version.h.in: Make it clear in the -version output that a
+ mutitude of copyrights and licenses apply to this software.
+
+ * magick/utility.c (GetPathComponent): Avoid strncpy() of
+ overlapping regions.
+
+ * magick/command.c (DisplayImageCommand): Eliminate double-free
+ of resource_info->image_geometry.
+ (DisplayImageCommand): `display` was improperly requiring at least
+ one argument (bug was added yesterday).
+
+2004-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/gm.c (main): Default usage message wasn't right for
+ aliased utility.
+
+ * configure.ac: Added the --enable-magick-compat option to install
+ compatibility links to emulate ImageMagick commands.
+
+ * magick/command.c: Ensure that each sub-command responds to -help
+ and -version appropriately.
+
+ * utilities/gm.c (main): Invoke appropriate sub-command if gm is
+ executed under a traditional alternate name such as "convert". The
+ user may create hard or symbolic links from `gm` to a traditional
+ ImageMagick utility name (or just copy `gm` to the desired
+ sub-command name) in order to be 100% command-line compatible with
+ ImageMagick 5.5.2. This is necessary in order to work with
+ existing software designed to execute ImageMagick utilities.
+
+2004-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/compress.c (Ascii85Tuple): Encoding bug is indeed fixed
+ on DEC Alpha. Also warnings reduction with Digital Unix compiler.
+
+2004-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/compress.c (Ascii85Tuple): Add casts to reduce compiler
+ warnings, and maybe even fix a bug.
+
+ * coders/pdf.c (ReadPDFImage): Double-check that Ghostscript
+ produced an output file since sometimes it reports success after
+ it has spewed an error message and has produced no output.
+
+2004-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/compress.c (HuffmanEncode2Image): Avoid out of bounds
+ array access.
+
+ * magick/studio.h (_FILE_OFFSET_BITS): Fix _FILE_OFFSET_BITS
+ #ifdef to avoid warnings when it is not defined.
+
+2004-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Fix minor shell syntax error (used ==).
+
+2004-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Merged in updates from 1.1 release branch.
+
+ * version.sh (PACKAGE_VERSION): Release version 1.1.
+ (PACKAGE_VERSION): Next major release will be 1.1. Bump library
+ versions since we anticipate adding interfaces.
+
+ * magick/studio.h: Disabled use of Windows message lookups
+ entirely since this doesn't seem to work for programs. It
+ probably only works for DLLs like ImageMagickObject.
+
+ * magick/delegate.c (ListDelegateInfo): Don't get stuck in a loop
+ if fprintf() returns zero.
+
+2004-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/*/*.bat: Add .exe to exe file names in order to
+ ensure that the executable is executed rather than something else
+ (such as a batch script).
+
+ * magick/locale.c: Only use Windows resource message lookup for
+ the DLL build since it doesn't seem to work for static
+ executables.
+
+ * magick/utility.c (SetClientPath): Ensure that client path is
+ null terminated.
+ (SetClientFilename): Initialize default client filename to ""
+ rather than "gm.exe" and ensure that filename is null terminated.
+ (SetClientName): Ensure that client path is null terminated.
+
+ * magick/blob.c (GetConfigureBlob): Enable logging the load of
+ log.mgk
+
+ * magick/log.c: Re-designed logging initialization in order to
+ avoid the "chicken and the egg" snafu. This allows logging the
+ initialization of the logging subsystem.
+
+2004-04-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/bin/log.mgk: Add comments to help document usage.
+
+ * config/log.mgk: Add comments to help document usage.
+
+ * magick/utility.c (IsAccessible): Use access() rather than stat().
+ (IsAccessibleNoLogging): Use access() rather than stat().
+ (IsDirectory): Implemented return status according to existing API
+ documentation.
+ (GetExecutionPathUsingName): Complete re-write in order to minimize
+ path computation logic and fix failure with partial paths.
+
+2004-03-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Add "Color" to the arguments available for -list.
+
+2004-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh (PACKAGE_CHANGE_DATE): Updated version to 1.1Beta3
+
+ * magick/nt_base.c (NTSystemComman): Have not been successful with using
+ MsgWaitForMultipleObjects() reliably, so back out usage of it for
+ now.
+
+ * magick/fx.c (ConvolveImage): Support convolution in CMYK
+ colorspace.
+
+2004-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh (PACKAGE_CHANGE_DATE): Update release to 1.1Beta2.
+
+ * magick/constitute.c (ReadImage): Ignore errors of type
+ ConfigureError when loading modules so that error report can still
+ report the familiar "No delegate for this image format" message
+ while still being able to report problems with loading a module if
+ it was found. This is a compromise which reports useless messages
+ when the modules are not found at all, but I can't think of a way
+ around it.
+
+ * magick/nt_base.c (NTSystemComman): Adjust
+ MsgWaitForMultipleObjects() arguments to wait for object to be
+ signaled only (FALSE) rather wait for object to be signaled as
+ well as an input event received(TRUE). It seems that process
+ status changes do not result in an input event, so the call was
+ deadlocking.
+
+ * magick/constitute.c (ReadImage): If module loading reported an
+ error, ReadImage immediately returned an error rather than trying
+ to use a delegate defined by delegates.mgk.
+
+2004-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Updated version to 1.1Beta1
+
+2004-03-24 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick/magick/libMagick.bpr: updated to latest source modifications.
+
+ * BCBMagick/magick/GM_Magick.bpr: updated to latest source modifications.
+
+2004-03-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/plasma.c (ReadPlasmaImage): srand() is already invoked by
+ InitializeMagick() so don't call it here.
+
+ * configure.ac: Check for rand_r().
+
+ * magick/tempfile.c (ComposeTemporaryFileName): The full range of
+ safe characters was not being used, thereby limiting the number of
+ unique temporary file names available.
+
+2004-03-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (GetImageStatistics): New function to obtain
+ image statistics (minimum, maximum, mean, variance, and standard
+ deviation).
+ (DescribeImage): Include image channel statistics in verbose
+ output.
+
+2004-03-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (DispatchImage): Removed some unreachable
+ code that was accidentially left in the switch statement.
+
+ * magick/pixel_iterator.c (PixelIterateDualRead): Extended so that
+ the region in each image may use a different origin.
+ (PixelIterateDualModify): Extended so that
+ the region in each image may use a different origin.
+
+ * magick/composite.c (CompositeImage): Fix XorCompositeOp overflow
+ condition which occured on non-Intel architectures.
+
+2004-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS: Updated with changes up to today's date.
+
+ * tests/constitute.c (main): Float type seems to require allowing
+ a bit of error for Q:32.
+
+ * magick/constitute.c (DispatchImage): Be more careful when
+ rounding pixel intensity.
+ (ConstituteImage): Be more careful when converting float and
+ double to Quantum.
+
+ * magick/composite.c (CompositeImage): Fix Multiply composite
+ operator for Q:32 build (was all black image).
+ (CompositeImage): Tidied up the documented composite operators so
+ the implementation is easier to understand.
+
+ * PerlMagick/t/ttf/read.t: Set a desired label size so output
+ image should be the same size as the reference image even if the
+ FreeType type hinter is disabled.
+
+ * magick/annotate.c (RenderFreetype): Improve outline bounding box
+ computation accuracy.
+
+2004-03-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/x/write.t: Don't test X11 if DISPLAY is not set.
+
+ * PerlMagick/t/x/read.t: Don't test X11 if DISPLAY is not set.
+
+2004-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/Makefile.am: Removed some apparently unnecessary library
+ dependencies.
+
+ * Makefile.am (windows-src): Added a way to generate a Windows
+ source zip file.
+
+2004-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: The -operator command now supports
+ floating-point and percent of range arguments.
+
+2004-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Added support for -operator command with
+ syntax "-operator channel operator rvalue" which applies a
+ arithmetic or bitwise operator to a specified image channel
+ or all channels.
+
+2004-03-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/filter.t: Fix Solarize test case.
+
+ * PerlMagick/t/wmf/read.t: Added another WMF test case.
+
+ * coders/wmf.c: Resolve WMF rendering bug with black color.
+
+ * magick/utility.c (StringToArgv): Free argv data prior to error
+ return.
+
+2004-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (WriteJPEGImage): If image_info->colorspace is set
+ to GRAYColorspace then make sure that image is in a gray
+ colorspace.
+
+ * magick/image.c (TransformRGBImage): If colorspace is already an
+ RGB type (RGBColorspace, GRAYColorspace, or TransparentColorspace),
+ then simply return. Do *not* set image->colorspace to RGBColorspace
+ since this potentially loses a valuable setting.
+
+2004-03-10 Peter Boos <pedib@colorfullife.com>
+
+ * magick/annotate.c (RenderFreetype): If DrawAnnotation is called
+ with a string containing only one character and this character is
+ not recognized by the TrueType engine, a crash occured due to the
+ failure of FT_Load_Glyph. The failure caused an uninitialized
+ glyph.image pointer to be used by FT_Done_Glyph() later in the
+ code. The solution is to initialize the glyph.image pointer to
+ null.
+
+2004-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (QuantumOperatorRegionImage): Properly handle
+ over and underflow of arithmetic operators.
+
+ * magick/draw.c (DrawGetFillOpacity): Use fill opacity, and invert
+ opacity range so it is 0.0 to 1.0 (was acting like transparency).
+ (DrawSetStrokeOpacity): Validate range of stroke_opacity.
+ (DrawSetFillOpacity): Save value to context->fill.opacity and
+ validate the range of fill_opacity.
+
+ * magick/image.c (QuantumOperatorImage): New function to apply an
+ arithmetic or bitwise operator to the pixel quantums in an image.
+ (QuantumOperatorRegionImage): New function to apply an arithmetic
+ or bitwise operator to the pixel quantums in an image region.
+
+ * magick/image.c (IsImagesEqual): Re-implemented using the new
+ pixel iteration functions as a proof of concept.
+
+ * magick/pixel_iterator.h: Added some pixel iteration functions in
+ order to make it easier to implement algorithms which only need to
+ iteratively access pixels in a region. These functions are not
+ part of the API yet so their interface should be considered
+ unstable.
+
+ * doc/GNUmakefile: Rename Makefile to GNUmakefile since it relies
+ on GNU make extensions.
+
+2004-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ConstituteImage): Add support for `T`
+ (transparency) and `O` (opacity) map types. Simplify
+ implementation.
+ (DispatchImage): Add support for `T` (transparency) and `O`
+ (opacity) map types. Simplify implementation.
+
+ * config/delegates.mgk.in: Quote delegate command names so
+ that they can contain embedded spaces.
+
+ * VisualMagick/bin/delegates.mgk: Quote delegate command names so
+ that they can contain embedded spaces.
+
+ * coders/tiff.c (WriteTIFFImage): Use the libtiff default endian
+ mode when writing TIFF rather than forcing MSB2LSB bit order.
+ (ReadTIFFImage): Enable reading in MSB2LSB bit order (better for
+ our byte-level parsing), enable memory mapping, and enable strip
+ chopping. Memory mapping and strip chopping are probably enabled
+ by default.
+
+ * magick/nt_base.c (NTSystemComman): Use
+ MsgWaitForMultipleObjects() rather than WaitForSingleObject() in
+ order to avoid possible deadlock when application code directly or
+ indirectly creates windows.
+
+2004-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/animate.c (XMagickCommand): URL should point to
+ http://graphicsmagick.org/.
+
+ * magick/display.c (XMagickCommand): URL should point to
+ http://graphicsmagick.org/.
+
+ * magick/image.c (DisplayImages): Changes to fix memory leaks in
+ X11 commands had bugs which seriously broke DisplayImages. Now
+ DisplayImages works properly again.
+
+ * magick/xwindow.c (XDestroyResourceInfo): New function to destroy
+ XResourceInfo.
+
+ * coders/x.c (WriteXImage): Implement based on DisplayImages().
+ (RegisterXImage): Always register X coder, but with read/write
+ support disabled if X11 not available.
+
+2004-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ImportImageCommand): Eliminate memory leaks.
+
+ * magick/memory.c (LiberateMemory): Use MagickFreeMemory macro for
+ implementation.
+ (ReacquireMemory): Use MagickReallocMemory macro for
+ implementation.
+ (AcquireMemory): Use MagickAllocateMemory for implementation.
+
+2004-02-26 Vladimir <lvm@integrum.ru>
+
+ * magick/memory.c (CloneMemory): Fixes to compile under Microsoft
+ Visual C++ 6.0.
+
+2004-02-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/animate.c (XAnimateImages): Memory leak reduction and
+ better integration with gm command.
+
+ * magick/display.c (XDisplayImage): Display was leaking memory
+ like a sieve. Now it doesn't.
+
+ * magick/memory.c (CloneMemory): Computation for when it is safe
+ to use memcpy() was incorrect. Use memmove() rather than
+ backwards-copy loop.
+
+ * Makefile.am ($(DIST_ARCHIVE_SRPM)): Added rules to build a
+ source RPM.
+
+ * configure.ac: Search for `buildrpm` or `rpm` programs in order to
+ support creating RPM packages on a system which has RPM installed.
+
+ * version.sh (PACKAGE_VERSION): Changed snapshot release naming so
+ that there is only one dash in the name and the snapshot date is
+ prefixed with `0` to assure proper directory sorting. This allows
+ snapshot naming to be acceptable to RPM. The snapshot package
+ name is now similar to GraphicsMagick-1.1.020040218.tar.bz2
+
+2004-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xwd.c (RegisterXWDImage): Always register XWD, but only
+ register read/write methods if it is supported.
+
+ * wand/magick_wand.c: Synchronized with latest ImageMagick API
+ changes.
+
+2004-02-16 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ * magick/resize.c (HorizontalFilter): Fixed: do process K channel
+ for CMYK images.
+ (VerticalFilter): do process K channel for CMYK images.
+
+2004-02-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tga.c (ReadTGAImage): Fix matte channel handling. For
+ 16-bit packets, use integer rather than floating point. Return
+ gray images as PseudoClass and set is_grayscale flag. Add
+ logging.
+
+ * magick/fx.c (WaveImage): Ensure that image is
+ DirectClass. Ensure that matte channel is initialized if
+ necessary. Include background color in is_grayscale evaluation.
+
+ * magick/gem.c (GenerateNoise): Scale noise to range of quantum.
+
+2004-02-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (WriteJP2Image): Support passing all documented
+ Jasper options using -define.
+
+2004-02-13 Peter Boos <pedib@colorfullife.com>
+
+ * coders/wmf.c (util_draw_arc): Fixes to improve handling for pie,
+ arc, and chord. These fixes produce correct output for
+ wmf/examples/fjftest.wmf, but it is not known if they are correct
+ for all cases.
+
+2004-02-12 Tim Hunter <cyclists@nc.rr.com>
+
+ * magick/profile.c (SetImageProfile): Bug fixes.
+
+2004-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xpm.c (UnregisterXPMImage): Unregister PICON registration.
+
+2004-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/Makefile.am (label_la_LDFLAGS): Add a dependency on the
+ math library since floor() is used.
+
+ * wand/magick_wand.c (MagickRemoveImageProfile): Use C comments in
+ C files.
+
+ * magick/constitute.c (MapQuantumType): Fix spurious comma in
+ enum definition.
+
+ * magick/blob.c (GetBlobStreamHandler): Apparently return type can
+ not be const.
+
+2004-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Check for Windows fonts under
+ /usr/X11R6/lib/X11/fonts/truetype (XFree86 standard location?).
+
+ * coders/jp2.c (WriteJP2Image): Support providing a compression
+ rate value (range 0.0 to 1.0) using command line syntax similar to
+ `-define jp2:rate=0.5`. In Magick++ this option may be accessed
+ similar to image.defineValue("jp2","rate","0.5");
+
+ * magick/command.c (DisplayImageCommand): Exit status was inverted
+ so `gm display` was returning 1 for successful commands, and 0 for
+ failures.
+ (AnimateImageCommand): Exit status was inverted so `gm animate`
+ was returning 1 for successful commands, and 0 for failures.
+
+2004-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.h (MagickReallocMemory): Solaris compiler
+ complains about cast so remove it.
+
+ * coders/xwd.c (WriteXWDImage): Right-size the pixels buffer and
+ tune writer loops a bit.
+
+ * magick/color.h (VerifyColormapIndex): Improve diagnostics.
+
+ * coders/pict.c (WritePICTImage): Eliminate use of uninitialized
+ data when writing RGB PICT. Fix OpenBlob assertion when writing
+ JPEG PICT.
+ (ReadPICTImage): Validate `tile_image` colormap indexes rather
+ than `image` colormap indexes. Preserve compression attribute from
+ tile image.
+
+ * magick/constitute.c (DispatchImage): Don't access image opacity
+ channel unless image->matte is True.
+
+2004-02-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c (UnregisterPNGImage): Destroy PNG semaphore.
+
+ * magick/image.c (SetImageInfo): Since we don't know what the
+ "IMPLICIT" specifier is supposed to do, support for it is
+ removed. Perhaps by removing support for it, we will be reminded
+ why it exists.
+
+ * magick/magick.c (DestroyMagickInfo): Invoke
+ UnregisterStaticModules().
+ (GetMagickInfo): Remove registration for "IMPLICIT" format since
+ its purpose is presumed bogus.
+
+ * magick/static.c (UnregisterStaticModules): New function so we
+ can unregister static modules.
+
+ * coders/plasma.c (UnregisterPLASMAImage): Unregister FRACTAL.
+
+ * coders/icon.c (UnregisterICONImage): Unregister CUR.
+
+ * coders/bmp.c (UnregisterBMPImage): Unregister BMP2 and BMP3.
+
+ * coders/meta.c (UnregisterMETAImage): Unregister APP1JPEG, IPTC,
+ IPTCTEXT, IPTCWTEXT, and PICON.
+
+ * coders/miff.c: Check for run-length termination before testing
+ memory and only check opacity channel if matte is valid.
+
+ * magick/compress.c: Check for run-length termination before
+ testing memory (bad read error).
+
+2004-02-07 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/bmp.c: Fix off-by-one error while initializing padding bytes.
+
+ * coders/dib.c: Fix off-by-one error while initializing padding bytes.
+
+ * magick/enhance.c: MaxMap vs MaxRGB error fixed. Reported by Cristy.
+
+2004-02-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * magick/compress.c: avoid a reference to uninitialized data.
+
+2004-02-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/dib.c: initialize padding bytes.
+
+2004-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/montage.c (MontageImages): Fix leak of texture image (big
+ leak).
+
+2004-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Fix detection of when to use a
+ temporary file when writing TIFF. Writing to TIFF BLOBs was
+ broken by the recent changes to make BlobInfo a private type.
+
+ * magick/render.c (DestroyEdge): Use memmove for overlapping copy.
+
+2004-02-03 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/bmp.c: initialize padding bytes.
+
+2004-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ConstituteImage): Added map support for `P`,
+ in order to skip over a pad quantum.
+ (DispatchImage): Added map support for `P`, in order to write a pad
+ quantum.
+
+ * magick/resize.c (HorizontalFilter): Don't process opacity
+ channel unless matte is enabled.
+ (VerticalFilter): Don't process opacity channel unless matte is
+ enabled.
+
+ * magick/compress.c (Ascii85Initialize): Don't overwrite an
+ existing ascii85 allocation.
+
+ * magick/utility.c (Strip): Use `memmove` rather than `memcpy` to
+ copy overlapping data.
+
+ * tests/rwfile.c (main): Fix memory leak in test. Only apply size
+ if format requires it.
+
+ * tests/rwblob.c (main): Fix memory leak in test. Only apply size
+ if format requires it.
+
+ * coders/mono.c (RegisterMONOImage): Mono is a raw format.
+
+ * magick/magic.c (GetMagicInfo): Ensure that magic tests are
+ within the range of header data which was read.
+
+2004-02-02 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/bmp.c: fix potential use of uninitialized data.
+
+ * coders/png.c: fix potential use of uninitialized data.
+
+2004-01-31 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * magick/studio.h: Fixed problem related to DLL version of BCBMagick.
+ Sometimes was incorrectly checked the presence of VC++ DLL. Thanks
+ very much to Oliver Bertini for bringing this problem to our attention.
+
+ * BCBMagick: added libpng delegate library in both static and DLL
+ modes.
+
+ * BCBMagick: removed all unuseful files from CVS.
+
+2004-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/render.c (CloneDrawInfo): Fixed nasty memory leak which
+ becomes painfully evident when using Magick++.
+
+ * magick/type.c (ReadTypeConfigureFile): Fix problem with parsing
+ <include> directive.
+
+ * configure.ac: The type.mgk generated had a syntax error.
+
+ * magick/effect.c (SpreadImage): Eliminate read from uninitialized
+ memory.
+
+ * magick/quantize.c (NodeInfo): Store nodes in a list similar to
+ ImageMagick.
+ (DestroyCubeInfo): Eliminate a small memory leak.
+
+2004-01-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/montage.c (MontageImages): Free thumbnails once they are
+ no longer needed (big leak).
+
+ * magick/blob.c (OpenBlob): Ensure that magick array is
+ fully initialized, even if the fread() is short.
+
+ * magick/list.c (ImageListToArray): Add a null pointer to the end
+ of the image list to serve as a handy list terminator.
+
+ * magick/tempfile.c (DestroyTemporaryFiles): Fix memory leak of
+ semaphore.
+
+ * magick/map.c (MagickMapDeallocateMap): Fix memory leak of
+ semaphore.
+
+ * coders/png.c (WriteOneJNGImage): Use DestroyBlob.
+
+ * magick/list.c (SyncNextImageInList): Use DestroyBlob.
+
+ * magick/image.c (AllocateNextImage): Use DestroyBlob.
+ (DestroyImage): DestroyBlob.
+
+ * coders/wpg.c (ExtractPostscript): Use DestroyBlob.
+
+ * magick/blob.c (DestroyBlob): New function. Similar to
+ DestroyBlobInfo except that it requires an Image * argument and
+ zeros the blob pointer. This one is preferred for use over
+ DestroyBlobInfo.
+
+2004-01-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/png.c: Add DestroyBlobInfo() calls to stop memory leak when
+ processing JNG datastreams.
+
+2004-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.h (MagickReallocMemory): Added a cast required to
+ make C++ Happy.
+
+ * coders/tiff.c: Adjust for bitstream API function renaming.
+
+ * magick/bit_stream.h: Rename BitStreamRead() to
+ BitStreamMSBRead() to indicate that it reads most significant bytes
+ first ("big endian" order). Rename BitStreamWrite() to
+ BitStreamMSBWrite() to indicate that it writes most significant
+ bytes first ("big endian" order).
+
+ * wand/magick_wand.c: Updated to lastest ImageMagick API.
+
+2004-01-26 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * magick/stream.c: (SetPixelStream) removed "const" from definition of
+ local variable [StreamHandler stream]. Borland C++Builder compiler signal
+ error "Cannot modify a const object".
+
+2004-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (TIFFMapBlob): Allow libtiff to access memory
+ mapped file (or BLOB in memory) directly. This provides a small
+ performance increase.
+
+ * magick/constitute.c (ReadImage): If a .mpc file is a temporary
+ file, then be sure to remove the associated .cache file when
+ removing the .mpc file.
+
+ * magick/log.h (LogEventType): ExceptionEventMask now maps to
+ WarningEventMask|ErrorEventMask|FatalErrorEventMask so that
+ `-debug exception` works again.
+
+ * magick/blob.c (CloseBlob): Allow CloseBlob to be invoked on a
+ blob which is not open (in UndefinedStream state).
+ (BlobInfo): The definition of BlobInfo is now private to blob.c.
+ (StreamType): The StreamType enumeration is now private to blob.c.
+ (GetBlobFileHandle): New function to access the blob file handle.
+ (GetBlobStreamHandler): New function to access the blob stream
+ handler.
+ (GetBlobStreamType): This function is removed entirely.
+ (BlobIsSeekable): New function to test if SeekBlob will work
+ properly for this blob type.
+ (GetBlobClosable): New function to test if the blob is allowed to
+ be closed by the library (may be an externally provided file
+ descriptor).
+ (GetBlobTemporary): New function to test if input file is a
+ temporary file which is to be removed.
+ (SetBlobClosable): New function to support setting the flag which
+ keeps the input file from being closed.
+ (SetBlobTemporary): New function to support setting the flag which
+ indicates that the input file is a temporary file.
+
+ * coders/jpeg.c (ReadJPEGImage): Invoke CloseBlob even if
+ blob is in UndefinedStream state.
+
+ * magick/error.h (ThrowReaderException): Ditto.
+ (ThrowWriterException): Ditto.
+ (ThrowWriterException2): Ditto.
+ (ThrowWriterException3): Ditto.
+
+ * magick/tempfile.h (ThrowReaderTemporaryFileException): Ditto.
+ (ThrowWriterTemporaryFileException): Ditto.
+
+ * coders/dps.c,coders/jpeg.c, coders/meta.c, coders/mvg.c,
+ coders/png.c, coders/tiff.c, magick/constitute.c, magick/stream.c:
+ Use new blob accessor functions.
+
+ * magick/cache.c (OpenCache): For Windows, set the sequential
+ access flag in all cases. Maybe it will make a difference.
+
+2004-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (GetConfigureBlob): Don't check Windows registry
+ if MagickLibConfigPath or MagickShareConfigPath is defined.
+
+ * magick/locale.c: Use a Unix-style message database for MinGW.
+
+ * rungm.sh.in: Translate environment paths to Windows format when
+ running under MinGW.
+
+ * magick/nt_base.c (mmap): Re-wrote mmap emulation to support
+ 64-bit file offsets and to support anonymous mapping.
+ (msync): A crude emulation of Unix msync().
+
+ * acinclude.m4 (GM_FUNC_MMAP_FILEIO): Change result define from
+ HAVE_MMAP to HAVE_MMAP_FILEIO so that it doesn't conflict with
+ Autoconf standard definition.
+
+2004-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/cache.c (OpenCache): While allocating the pixel cache
+ from the heap, reserve enough memory to contain a full PseudoClass
+ image in order to reduce the chance that there will be a memory
+ allocation failure while processing the image. This also avoids
+ the possibility that the image pixels will be block-copied to a
+ new location due to heap memory fragmentation. If there is
+ insufficient heap memory (malloc() fails), then a disk-based pixel
+ cache will be used.
+
+ * coders/wpg.c: Backed out Jaroslav Fojtik's patch from 2004-01-13
+ because WPG was failing PerlMagick's existing WPG read test.
+
+2004-01-16 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick: updated to recent Windows delegate libraries.
+
+ * BCBMagick: modified build procedure. Removed all unused directories
+ and include files.
+
+ * lcms/include/lcms.h: Modified to achieve BCBMagick compilation.
+
+ * tiff/libtiff/tiffio.h: Modified to achieve BCBMagick compilation
+
+ * ttf/include/freetype/config/ftoption.h: Modified to achieve
+ BCBMagick compilation
+
+ * Magick++/lib/Magick++/Include.h: Modified to achieve BCBMagick compilation.
+
+2004-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wpg.c: Applied patch from Jaroslav Fojtik to support
+ reading the CTM (current transform matrix). The CTM is not
+ applied yet (expect later patch).
+
+2004-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/sfw.c (ReadSFWImage): Added size_t cast.
+
+ * coders/msl.c (MSLStartElement): Added size_t cast.
+
+ * coders/meta.c (convertHTMLcodes): Added size_t cast.
+
+ * coders/locale.c: Add size_t casts and update to use memory
+ allocation macros.
+
+ * coders/html.c (WriteHTMLImage): Added size_t cast.
+
+ * magick/utility.h (MagickAllocateMemory): Added size_t cast.
+ (MagickReallocMemory): Added size_t cast.
+
+ * coders/bmp.c (WriteBMPImage): Added size_t cast.
+
+ * coders/art.c (ReadARTImage): Use memory allocation macros.
+
+ * VisualMagick/configure/configure.cpp: Update to support library
+ .def exports files with Visual C++ 7.0.
+
+ * Updated Windows delegate libraries: LCMS 1.12, FreeType 2.1.5,
+ BIG-KIT 1.5, libpng 1.2.5, libwmf 0.2.8.2, and zlib 1.2.1.
+
+ * Verified Windows static and DLL compilation with Visual C++ 6.0.
+
+ * Makefile.am: Update to automake 1.8.2.
+
+ * coders/gif.c (WriteGIFImage): Use ColorMatch rather than
+ FuzzyColorMatch when comparing colormap entries.
+
+2004-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/profile.c: Needed to include "magick/profile.h" in order
+ to obtain prototypes.
+
+2004-01-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/wandtest.c: Change MagickCloneWand to MagickGetImage since
+ the API name changed.
+
+ * wand/pixel_wand.c: Synchronized with
+ latest daily ImageMagick updates.
+
+ * wand/magick_wand.c (MagickRemoveImageProfile): Synchronized with
+ latest daily ImageMagick updates.
+
+ * magick/profile.c (DeleteImageProfile): New method to make
+ it easier to destroy an image profile.
+
+ * magick/profile.h: New source file to contain functions for
+ dealing with embedded image profiles.
+
+ * magick/profile.c: New source file to contain functions for
+ dealing with embedded image profiles.
+
+ * Makefile.am (DISTDIRS): Distribute TclMagick subdirectory.
+
+2004-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c: Ported over the latest ImageMagick Wand API
+ updates. Note that a comment now says that the Wand API will not
+ be finished until around 4th quarter of 2004. This represents a
+ 1-1/2 year slip from the original estimate!
+
+2004-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (IsImagesEqual): Simplified implementation.
+
+ * magick/magick.c: Removed some unused code.
+
+ * contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp
+ (IDispatch): Comment out InitializeSemaphore() so code compiles.
+
+ * libtool.m4: Updated to 2004-01-03 version of CVS libtool. This
+ should fix configure problems under AIX and IRIX.
+
+2004-01-03 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ * coders/sgi.c: opacity channel was lost when writing grayscale
+ SGI images. See bug report in magick-users list.
+
diff --git a/ChangeLog.2005 b/ChangeLog.2005
new file mode 100644
index 0000000..84f10c4
--- /dev/null
+++ b/ChangeLog.2005
@@ -0,0 +1,914 @@
+2005-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tiff: Update to libtiff 3.8.0.
+
+2005-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS: Updated with latest changes.
+
+ * tiff: Update to libtiff 3.7.4.
+
+2005-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lcms: Update to lcms 1.15.
+
+2005-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/enhance.c (LevelImage): Fix -level command parsing when a
+ percent symbol is supplied within the argument rather than at the
+ end.
+
+ * magick/utility.c (GetGeometry): Bounds-check geometry string
+ length.
+
+2005-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Decided to swap 10-bit subsampled 4:2:2 YCbCr by
+ default since this is what practically all sample files I have
+ been provided actually do. Ignore the fact that there is nothing
+ in the standard which supports this.
+
+2005-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (NormalizeSamplingFactor): Generalized
+ subsampling notation parsing support.
+
+2005-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (NormalizeSamplingFactor): Add some support for
+ normalizing industry-standard subsampling notation (e.g. 4:2:2)
+ into GraphicsMagick's unusual notation.
+
+2005-12-06 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Updates to use latest development autotools, including
+ development libtool 2.0.
+
+2005-12-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h: Added some useful macros for accessing
+ PixelPacket members in a generic way.
+
+ * coders/dpx.c (ReadDPXImage): For YCbCr with `A` sample, `A`
+ sample levels are like Luma.
+ (WriteDPXImage): For YCbCr with `A` sample, `A` sample levels are
+ like Luma.
+
+2005-12-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (RegisterTIFFImage): Report libtiff release
+ version rather than ABI version.
+
+2005-11-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resize.c: Revert yesterday's benign-appearing edits since
+ they caused a bizzare bug.
+
+2005-11-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): Improve performance when reading
+ YCbCr files. Handle files which use Printing Density on top of
+ YCbCr. Default YCbCr to Rec.709 if the transfer characteristic is
+ User Defined.
+
+ * coders/pcd.c (Upsample): Moved Upsample from gem.c to here since
+ PCD is the only user and it is not a general purpose function.
+
+2005-11-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/magick/magick_config.h.in: Remove unnecessary test
+ for WIN32.
+
+2005-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_compat.c (FormatMagickStringList): MagickExport since this
+ function is used by Ch extension.
+
+ * magick/log.c (LogMagickEventList): MagickExport since this
+ function is used by Ch extension.
+
+ * magick/utility.c (FormatStringList): MagickExport since this
+ function is used by Ch extension.
+
+ * coders/dpx.c (ReadDPXImage): Added support for dpx:swap-samples
+ define in order to handle files with Cb and Cr swapped. Fixed a
+ bug in the header reading which caused some valid files to fail to
+ read at all.
+ (WriteDPXImage): Added support for dpx:swap-samples define in
+ order to write files with Cb and Cr swapped.
+
+ * magick/profile.c (ProfileImage): Add support for ICC CMS
+ profiles in YCbCr space.
+
+2005-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/svg.c (ReadSVGImage): Eliminate memory leak.
+
+2005-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.h (Image): Added an orientation member to the Image
+ structure to record image orientation for the DPX, and TIFF
+ formats. Eventually formats which support IPTC and EXIF embedded
+ profiles should be supported by the orientation member as well.
+
+2005-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/magick/magick_types.h.in: Add patch for Ch.
+
+ * magick/command.c (TransmogrifyImage): Complete re-write of
+ mogrify file handling. Former version wrote to a temporary file
+ and then moved temporary file to replace original if necessary.
+ New version moves an existing writable file to a backup file with
+ tilde (`~`) added to end of file name, writes to the final output
+ file name, and removes the backup file on success. The new
+ approach satisfies formats which embed the output name in the file
+ (e.g. the DPX format) and still works when the output file exists
+ and is writeable, but is in non-writeable directory. The previous
+ approach would fail if the output file exists and is writable, but
+ the directory is not writeable.
+
+2005-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (AttributeToString): Use strncpy rather than
+ strlcpy to copy string. This is important since DPX header
+ strings are not null terminated and may need to fill all available
+ space. Certain short header fields like mp.film.manufacturer.id,
+ mp.film.type, and mp.perfs.offset were being truncated!
+
+2005-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (GetImageAttribute): Add more general support
+ for retrieving wildcarded attributes so that an identify -format
+ specification like `%[dpx:*]` works as expected.
+
+ * coders/tiff.c (WriteTIFFImage): Transform quality value into zip
+ compression quality level similar to what is done for MIFF/MNG/PNG.
+ Since default quality value is 75, this means that the default zip
+ quality level is 7.
+
+2005-09-24 Peter Wu <peterw@softintegration.com>
+
+ * Incorporate changes necessary so that GraphicsMagick can work
+ with the Ch C/C++ interpreter from SoftIntegration at
+ http://www.softintegration.com/.
+
+2005-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c: Incorporate all functionality from
+ cache.c, cache_view.c, and stream.c so that all private interfaces
+ can be fully hidden. As a result cache.c, cache_view.c, and
+ stream.c are now removed.
+
+2005-09-18 Michal Kowalczuk <sammael@brzydal.eu.org>
+
+ * coders/gif.c: Free global_colormap before returning with error.
+
+2005-09-18 Stepan Kasal <kasal@ucw.cz>
+
+ * Makefile.am (BUILT_SOURCES): Removed.
+
+ * magick/Makefile.am (MAGICK_BUILT_SRCS): Removed, too.
+
+2005-09-12 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * magick/profile.c (ProfileImage): Free color_profile->name
+ and iptc_profile->name when destroying the profile.
+
+2005-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/api.h: Eliminate requirement to include certain system
+ headers prior to including <magick/api.h>.
+
+ * utilities/gm.c: Move utility implementation to GMCommand() in
+ command.c
+
+2005-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Added support for reading and writing DPX Luma
+ files using proper video levels.
+
+ * magick/colorspace.h (enum ColorspaceType): Decided that
+ GRAYColorspace should be reserved for full-range grayscale data
+ while Rec601LumaColorspace and Rec709LumaColorspace should be for
+ video colorspaces. Therefore, GRAYColorspace is no longer a
+ synonym for Rec601LumaColorspace.
+
+ * magick/colorspace.c: Added support for influencing Cineon Log
+ colorspace transformations via image attributes.
+ Perform colorspace transformations in floating point rather than
+ integer in order to reduce the amount of noise added by
+ transform table quantization.
+
+ * coders/psd.c (WritePSDImage): Ensure that output image is 8 or
+ 16-bits regardless of specific image depth.
+
+ * coders/dpx.c: Added support for planar YCbCr 4:2:2.
+
+2005-08-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): 10 and 12-bit packed data was not
+ according to DPX specification. Added dpx:pixel-endian={lsb|msb}
+ to allow the user to specify the endian order of the pixel data in
+ case it does (or should not) not match the headers. Library Of
+ Congress format is 10-bit packed data in big-endian format, but is
+ marked as little-endian.
+
+2005-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Sample order for filled 10 bit samples matches DPX
+ specification (was intentionally reversed). RGB sample order is
+ changed to match DPX specifiation (i.e. BGR rather than RGB).
+ Disabled special support for Library Of Congress little-endian
+ 10-bit packed format.
+
+2005-08-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Extend all image rows to a 32-bit integer
+ boundary.
+
+2005-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Support the little-endian 10-bit packed format as
+ used by the Library Of Congress.
+
+2005-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c: Change how Jasper is intialized. Hopefully
+ eliminate memory leak when reading ICC color profile.
+
+ * Overall: Compilation warning elimination with GCC 4.0.1.
+
+ * magick/utility.c (SystemCommand): Always report error status if
+ a command fails.
+
+2005-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * zlib: Updated to version 1.2.3.
+
+ * coders/dpx.c: Use TriangleFilter for scaling chroma.
+
+2005-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Support proper encode and decode of YCbCr video
+ levels.
+
+ * magick/colorspace.c: Support Rec709YCbCrColorspace colorspace.
+
+2005-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/{animate.c, display.c, import.c, xwindow.c}: Rename all
+ symbols starting with `X` so that they are prefixed with `Magick`.
+ This eases maintenance since it is almost impossible to understand
+ code which pretends to be the X11 libraries. The few programs
+ which use the GraphicsMagick `X` functions will need to alter the
+ symbol names they use. Sorry.
+
+ * magick/command.c (DisplayImageCommand): Don't invoke
+ XrmDestroyDatabase() to destroy the resource database associated
+ with the display since it seems that XCloseDisplay() does this for
+ us.
+
+ * magick/image.c (DisplayImages): Don't invoke
+ XrmDestroyDatabase() to destroy the resource database associated
+ with the display since it seems that XCloseDisplay() does this for
+ us.
+
+ * coders/uyvy.c: Enforce image width restrictions.
+
+ * coders/dpx.c: Enforce image width restrictions when subsampling.
+
+2005-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Support reading and writing subsampled CbYCr
+ images. Colorimetery is not right yet.
+
+ * magick/colorspace.h (enum Rec709YCbCrColorspace): New
+ enumeration for Rec. 709 YcBCr colorspace.
+
+2005-06-21 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/png.c: Fixed a problem with reading 16-bit PNG images
+ using the Q8 quantum depth.
+
+2005-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): Add read support for CbYCr at 4:4:4.
+ (WriteDPXImage): Add write support for CbYCr at 4:4:4.
+
+2005-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): Only preserve source image
+ dimension and offset information if image size has not changed.
+ If image size has changed, the existing information may become
+ invalid.
+ (WriteDPXImage): Allow user to assign DPX header attribute values
+ using syntax like "-define dpx:mp.frame.position=1000".
+
+2005-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/fpx.c: Fix compilation problem due to additional
+ ExportImagePixelArea parameter.
+
+2005-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c (WriteMNGImage): Use -define mng:need-cacheoff to
+ write a libmng-specific nEED request to disable frame buffering.
+ This allows the MNG data to stream without increasing memory
+ consumption in the libmng client.
+
+2005-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (SMPTEStringToBits): Time code and user bits were
+ being displayed in wrong order on little endian CPUs. Thanks very
+ much for bug report from Jason Howard.
+ (SMPTEStringToBits): Similar fix for time code and user bits
+ string to binary.
+
+2005-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): Use StringToColorspaceType() to
+ parse colorspaces.
+ * coders/dpx.c (ReadDPXImage): Change existing
+ dpx:source-colorspace define to dpx:colorspace so it is easier to
+ remember.
+
+ * coders/cineon.c (ReadCINEONImage): Extract Cineon header
+ attributes in DPX compatible form so that it is possible to
+ convert Cineon to DPX while losing as little header information as
+ possible. Allow the user to set the existing image colorspace
+ using the cineon:colorspace define.
+
+2005-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (ReadJPEGImage): Report actual depth of JPEG file
+ (8 or 12 bits).
+
+ * coders/cineon.c (ReadCINEONImage): Report depth as 10 bits.
+
+2005-05-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Retrieve and restore the DPX user defined data
+ area. Make available as a "DPXUSERDATA" attached profile.
+
+2005-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/meta.c (ReadMETAImage): Fixed reading ICM color profile
+ files. Due to a typo ICM color profiles were being stored as IPTC
+ profiles. This restores proper operation of the -profile option.
+ (ReadMETAImage): Fix double free bug. Hopefully does not result
+ in a memory leak in other cases.
+
+2005-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (DescribeImage): If the image is DirectClass,
+ then don't compute the number of unique colors unless verbose is
+ greater than one. This change is made since computing the number
+ of unique colors may take hours for some images. The handling of
+ the -verbose argument is changed so that it is cumulative.
+ Specifying -verbose multiple times increases the level of
+ verbosity.
+
+2005-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (NTreaddir): Fix write beyond buffer length
+ reported in SourceForge issue #1182003. Only impacts Windows.
+
+2005-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadRowSamples): Added necessary masking necessary
+ in order to cleanly retrieve DPX 10 bit samples. Happened to work
+ properly without the masking with QuantumDepth=16.
+
+2005-05-16 Tavis Ormandy <taviso@gentoo.org>
+
+ * coders/xwd.c (ReadXWDImage): Fix for infinite loop in the xwd
+ decoder when calculating the shift r/g/b values and the mask is
+ set to zero.
+
+2005-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (ReadJP2Image): Return JP2 images as DirectClass
+ grayscale rather than PseudoClass.
+
+ * coders/gray.c (ReadGRAYImage): Return GRAY images as DirectClass
+ grayscale rather than PseudoClass.
+
+ * coders/dpx.c: Rewrote the DPX pixel reading/writing code yet
+ again to obtain up to 2X better performance. In the process,
+ support little-endian pixel storage.
+
+2005-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Added some performance optimizations for reading
+ and writing. Write the motion picture and television headers.
+
+ * magick/colorspace.c (TransformRGBImage): Update image colorspace
+ to RGB when transforming from Cineon log space to RGB.
+
+ * coders/dpx.c (WriteDPXImage): Set image date & time field.
+ (ReadDPXImage): Retrieve television header SMTPE time code and
+ user bits and return them as a formatted string.
+ (WriteDPXImage): Fix colorspace mapping logic. Was converting
+ Cineon log to RGB when it shouldn't be.
+
+2005-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): Default to big-endian output.
+
+ * magick/delegate.c (InvokePostscriptDelegate): Improved
+ Ghostscript API-based error reporting and logging.
+
+ * magick/attribute.c (GenerateEXIFAttribute): Extend EXIF
+ knowledge a bit. Pass more characters from EXIF_FMT_BYTE in case
+ the byte stream contains nulls.
+
+ * coders/dpx.c: Re-wrote the DPX read/write support in order to
+ hopefully surmount problems noticed when testing with files sent
+ to me.
+
+ * wand/pixel_wand.c (PixelSetYellowQuantum): Wrong PixelPacket
+ member was being set. Thanks to Cristy for the heads-up.
+
+ * magick/image.c (SetImageType): Revert change from 2005-03-12.
+ Some coders require that when the image is set to Bilevel type,
+ that it be PseudoClass.
+
+2005-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/tests/convolve.sh: Add a convolution parameter.
+
+2005-04-28 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * magick/command.c: "IsGeometry() test was rejecting valid
+ -convolve parameters. Also, the image returned by ConvolveImage()
+ was ignored.
+
+2005-04-25 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/png.c: Initialize several variables to avoid new
+ GCC 4.0.0 warnings.
+
+ * coders/pnm.c: Defend against malicious "P7" files that try
+ to set the colormap less than 256 bytes (bug fix from ImageMagick)
+
+2005-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): Fill out source information
+ header.
+
+ * Magick++: Added image leveling methods for Magick++.
+
+2005-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS: Update with latest news.
+
+ * magick/blob.c (WriteBlob): Move BlobStream write support to a
+ subroutine for easier maintenance.
+
+ * coders/dpx.c (ReadDPXImage): Support retrieving all DPX
+ attributes as image attributes.
+ (WriteDPXImage): Buffer writes for better performance on some
+ platforms.
+
+2005-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): Re-write sample marshalling to be
+ based on a series of tighter loops. Results in a small
+ performance increase.
+ (ReadDPXImage): Re-write sample marshalling to be
+ based on a series of tighter loops. Results in a small
+ performance increase.
+
+2005-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/Xwindow.c (XDelay): Prefer use of select() over poll()
+ since it is more portable. MacOS-X has a poll() but it doesn't
+ work right.
+
+2005-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick_endian.h: Renamed from endian.h in order to avoid
+ conflict with system headers.
+
+2005-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (WriteMIFFImage): Normalize image depth to 8/16/32.
+
+ * coders/gray.c (WriteGRAYImage): Normalize image depth to 8/16/32.
+
+ * coders/fits.c (WriteFITSImage): Normalize image depth to 8/16.
+
+ * tests/Makefile.am: Extended read/write tests to include 10, 12,
+ and 16-bit original test images.
+
+ * coders/dpx.c (ReadDPXImage): If samples are log encoded, then
+ set the image to CineonLogRGBColorspace.
+ (WriteDPXImage): If image samples are log encoded, then mark DPX
+ file as being log encoded.
+
+ * magick/colorspace.c (TransformRGBImage): Support translation
+ from log RGB to linear RGB based on Cineon guidelines.
+ (RGBTransformImage): Support translation from linear RGB to log RGB.
+
+ * magick/colorspace.h (enum CineonLogRGBColorspace): New
+ enumeration to record that the RGB values are log encoded in a
+ 2.048 density range as defined for the Cineon Digital Film System.
+
+2005-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Take advantage of ColorspaceTypeToString() and
+ StringToColorspaceType() functions in implementation.
+
+ * magick/colorspace.c (RGBTransformImage): Added support for
+ converting to Rec 709 grayscale colorspace.
+ (ColorspaceTypeToString): New function to translate from
+ ColorspaceType enumeration value to a string.
+ (StringToColorspaceType): New function to translate from a string
+ to a ColorspaceType enumeration value. * magick/colorspace.h
+ (enum Rec601LumaColorspace): New enumeration to support the Rec
+ 601 grayscale colorspace. This is the colorspace previously
+ represented by GRAYColorspace. If GRAYColorspace is specified,
+ then Rec601LumaColorspace is selected.
+ (enum Rec709LumaColorspace): New enumeration to support the Rec
+ 707 grayscale colorspace.
+
+2005-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (IdentifyImageCommand): Use +ping to force
+ identify to read the image pixels.
+
+ * magick/constitute.c (PingImage): Intentionally clear
+ user/elapsed timer when ping is used on an image since the results
+ are misleading.
+
+ * magick/image.c (DescribeImage): Only display pixel read rate if
+ the time accumulated is at least the timer's resolution.
+
+ * magick/cache.c (OpenCache): Fix a memory resource leak noticed
+ by Stefan v. Wachter <svwa-dev@mnet-online.de>. This error with
+ keeping track of resources may eventually cause GraphicsMagick to
+ run slower and slower due to using disk-based images rather than
+ memory-based images.
+
+2005-04-07 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/png.c: encoder now accepts image->depth other than 8 and 16.
+
+2005-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): First pass at a new SMPTE268M-2003
+ DPX writer.
+
+2005-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (AllocateString): Performance enhancement.
+ (CloneString): Performance enhancement.
+ (ConcatenateString): Performance enhancement.
+
+2005-03-31 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/jpeg.c: revised EOF test. It was rejecting good image
+ files. Needs more work.
+
+2005-03-30 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/pnm.c (ReadPNMImage): Throw a "Corrupt Image" exception
+ if EOF is encountered while reading scanlines in P1, P2, P3, or P4
+ formatted images (P5 and P6 were OK).
+
+2005-03-29 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/sgi.c (ReadSGIImage): Throw a "Corrupt Image" exception
+ if EOF is encountered while reading scanlines.
+
+2005-03-28 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/jpeg.c (ReadJPEGImage): Throw a "Corrupt Image" exception
+ if EOF is encountered while reading scanlines.
+
+ * coders/pcx.c (ReadPCXImage): Throw a "Corrupt Image" exception
+ if EOF is encountered while reading pixels.
+
+2005-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): First pass at a new SMPTE268M-2003
+ DPX reader.
+
+ * magick/bit_stream.h (WordStreamLSBRead): New function to parse
+ values from a stream which is defined by 32-bit words. Values are
+ read starting with the least significant bits.
+
+2005-03-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ExtensionTagsInitialize): Fix conditional use of
+ TIFFSetTagExtender().
+
+2005-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/endian.c: Imported libtiff's swab.c since its functions
+ are so useful and well-tested.
+
+ * magick/utility.c (FormatSize): Extend to support incredibly
+ large sizes.
+
+ * magick/image.c (DescribeImage): Use GetTimerResolution() when
+ computing pixels-per-second rate in order to avoid computing
+ astronomical rates when the time consumed is too small to measure.
+
+ * magick/timer.c (GetTimerResolution): New function to return the
+ timer's resolution.
+
+2005-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c (WritePDFImage): Eliminate cause of annoying
+ warning when PDFs are read by Ghostscript 8.5.
+
+2005-03-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.h (lt_dlerror): Needed to provide a mapping to
+ NTdlerror().
+
+ * coders/tiff.c (TIFFErrors): Update to make thread safe via
+ thread specific data.
+ (TIFFWarnings): Update to make thread safe via thread specific
+ data.
+
+ * magick/tsd.c (MagickTsdKeyCreate): New function to support
+ thread specific data.
+ (MagickTsdKeyDelete): ditto
+ (MagickTsdSetSpecific): ditto
+ (MagickTsdGetSpecific): ditto.
+
+2005-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (ReplaceImageColormap): New function to replace
+ the image colormap with a user-provided one. Colormap indexes are
+ adjusted to point to identical colors in the new colormap.
+
+ * magick/nt_base.h: Reorganized a bit to cluster code supporting
+ similar features in the same area of the header.
+
+ * magick/nt_base.c: Renamed wrappers for standard functions so
+ that they have the prefix `NT`. Macros are used to apply the new
+ names. This assures that there will not be conflicts if the library
+ is linked with a different package's wrapper functions.
+
+2005-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/quantize.c (GrayscalePseudoClassImage): Moved to here
+ from image.c. Added support for is_monochrome.
+
+2005-03-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * jp2: Updated Jasper library to version 1.701.0.
+
+ * magick/nt_base.c (NTGhostscriptFonts): Fixed a coding error
+ which was added when strcpy/strcat code was replaced with
+ strlcpy/strlcat. Ghostscript fonts were not being found.
+
+ * magick/constitute.c (ReadImage): Don't attempt to access image
+ members if image pointer is null. Oops!
+
+2005-03-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageType): Bilevel image is not required to
+ be PseudoClass type.
+
+ * coders/mpc.c (WriteMPCImage): Persist is_monochrome and
+ is_grayscale flags.
+ (ReadMPCImage): Restore is_monochrome and is_grayscale flags.
+
+ * magick/constitute.c (WriteImage): Extended logging to include
+ monochrome and grayscale flags.
+ (ReadImage): Extended logging to include monochrome and grayscale
+ flags.
+
+ * magick/image.c (DescribeImage): Include the effective pixel I/O
+ rate alongside the image read/write time. This provides an easier
+ way to evaluate image read/write performance when looking at
+ `identify` or `convert -verbose` output.
+
+ * coders/sun.c (ReadSUNImage): Ensure that pixel length value does
+ not overflow for large images.
+
+2005-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/cache.c (SetImagePixels): Improved documentation.
+ (GetImagePixels): Improved documentation.
+
+2005-03-10 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ * coders/png.c: Avoid attempting to write indexed PNG when
+ a color entry has more than one opacity level. The PNG format
+ supports this but GM's colormap does not, so erroneous files
+ were being written.
+
+2005-03-09 Arne Rusek <zonk@matfyz.cz>
+
+ * magick/attribute.c (GenerateEXIFAttribute): Offset type
+ correction to fix loop termination if size_t type is not `long`.
+
+2005-03-09 Alexander Yaworsky <yaworsky@users.sourceforge.net>
+
+ * coders/jbig.c (WriteJBIGImage): JBIG was writing an empty output
+ file. Apparently libjbig parameters have changed. Setting l0
+ parameter of jbg_enc_options to zero instead of -1 (like in
+ jbigkit's pbmtools) solved the problem.
+
+2005-03-07 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick\magick\GM_magick.bpr: Updated to reflect changes since
+ last update.
+
+ * BCBMagick\magick\libMagick.bpr: Updated to reflect changes since
+ last update.
+
+2005-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/alpha_composite.h (AlphaComposite): Moved AlphaComposite
+ to new alpha_composite.h header since it was causing porting
+ problems.
+
+ * magick/constitute.h (enum QuantumType): Added CIEYQuantum and
+ CIEXYZQuantum quantum import options.
+
+ * coders/tiff.c (ReadTIFFImage): Import LogLuv image data within
+ GraphicsMagick (rather than libtiff) so that color resolution is
+ not lost. Results in a small speedup as well.
+
+ * magick/constitute.c (ImportImagePixelArea): Add a speed-up for
+ importing bi-level images. Add support for importing pixels in
+ CIE XYZ and CIE Y colorspaces.
+
+ * coders/tiff.c (ReadTIFFImage): Support reading TIFF images which
+ fail to properly scale the samples to the sample size (e.g. 12
+ bits in a 16-bit sample).
+ (WriteTIFFImage): Adjustments to strip-size (rows-per-strip)
+ estimation.
+
+ * magick/constitute.c (ExportImagePixelArea): Support exporting
+ unsigned samples with values which span only part of the range.
+ For example, 12 bit data may be exported within 16 bit samples,
+ with a value range of 0 to 4095.
+ (ImportImagePixelArea): Support importing unsigned samples with
+ values which span only part of the range.
+
+2005-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Support reading TIFF files in
+ IEEEFP format.
+ (WriteTIFFImage): Support writing TIFF files in IEEEFP format.
+
+ * magick/constitute.c (ExportImagePixelArea): Support exporting
+ floating point data.
+ (ImportImagePixelArea): Support importing floating point data.
+
+2005-02-26 Albert Chin-A-Young <china@thewrittenword.com>
+
+ * acinclude.m4 (AC_CXX_IOS_BINARY): Added macro to detect if the
+ C++ compiler lacks support for ios::binary.
+
+ * configure.ac: Use AC_CXX_IOS_BINARY.
+
+2005-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Read grayscale TIFFs as
+ DirectClass rather than promoting to PseudoClass. Fix improper
+ multiple repeated "disassociate" operations when reading planar
+ images which contain an alpha channel.
+ (WriteTIFFImage): Fix improper multiple repeated "associate"
+ operations when writing planar images with an alpha channel.
+
+2005-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * win2k/IMDisplay/IMDisplayView.cpp (DoDisplayImage): Use
+ TextureImage to apply background pattern.
+
+ * magick/image.c (TextureImage): Alpha blend the texture onto the
+ background if the image has a matte channel.
+
+ * magick/constitute.h (enum QuantumType): Eliminated
+ GrayInvertedQuantum and GrayInvertedAlphaQuantum which were added
+ since GraphicsMagick 1.1. Replaced this "inverted" gray
+ functionality with the grayscale_inverted flag in
+ ExportPixelAreaOptions and ImportPixelAreaOptions.
+
+ * magick/constitute.c (ExportImagePixelArea): Added an extra
+ parameter for passing seldom used options via an
+ ExportPixelAreaOptions structure.
+ (ImportImagePixelArea): Added an extra parameter for passing
+ seldom used options via an ImportPixelAreaOptions structure.
+ (ExportPixelAreaOptionsInit): New function to initialize the
+ ExportPixelAreaOptions structure with defaults.
+ (ImportPixelAreaOptionsInit): New function to intialize the
+ ImportPixelAreaOptions structure with defaults.
+
+ * coders/jpeg.c (WriteJPEGImage): Don't use jpeglib private
+ BITS_IN_JSAMPLE definition to select JPEG bit depth.
+
+ * coders/tiff.c (ReadTIFFImage): Support using -define
+ tiff:alpha={unspecified|associated|unassociated} to specify the
+ alpha channel type in case the alpha channel is marked
+ incorrectly.
+ Properly read associated alpha images.
+ (WriteTIFFImage): Support using -define
+ tiff:alpha={unspecified|associated|unassociated} to override the
+ alpha channel type.
+ Properly write associated alpha images by default.
+
+2005-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WritePTIFImage): Ensure that pyramid image frames
+ are the same type as the original image.
+ (WriteTIFFImage): Added support for writing tiled TIFF.
+
+2005-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/render.c (TraceBezier): Avoid probable bug under Visual
+ C++ 7.0 or later due to the argument to pow not being promoted to
+ double.
+
+2005-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Re-wrote TIFF writing code.
+
+ * magick/image.h (MaxValueGivenBits): Renamed MaxRGBGivenBits
+ macro to MaxValueGivenBits.
+
+ * magick/constitute.h (enum QuantumType): Added UndefinedQuantum.
+
+ * magick/static.c (RegisterStaticModules): Support compiling
+ without PNG.
+
+2005-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/color.c (IsPaletteImage): Fix memory leak reported by
+ Stefan v. Wachter <svwa-dev@mnet-online.de>.
+
+ * magick/Makefile.am (MAGICK_INCLUDE_HDRS): Needed to install
+ magick/operator.h.
+
+ * coders/tiff.c (ReadTIFFImage): Re-wrote TIFF reading code again
+ for more flexibility and performance.
+
+2005-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Remove --disable-lzw option and HasLZW define.
+ LZW support is always enabled now.
+
+2005-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tga.c (WriteTGAImage): Incorporated patch from Stefan
+ v. Wachter to enable writing grayscale images as well as adding
+ more image type option smarts.
+
+ * coders/psd.c (ReadPSDImage): Fix stack overflow vulnerability
+ reported by Andrei Nigmatulin. See http://lwn.net/Articles/119713/
+ for details.
+
+2005-01-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * win2k/IMDisplay/IMDisplayDoc.cpp (DoReadImage): Ensure that image
+ is in RGB color space after being read since this is what Windows
+ expects.
+
+2005-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Handle extra samples in scanline
+ TIFFs.
+
+2005-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (DescribeImage): Report statistics for a virtual
+ gray channel for grayscale images rather than discrete red, green,
+ and blue.
+
+ * PerlMagick/Makefile.nt: JNG and JP2 to test list.
+
+ * configure.ac: Changed --without-fpx to --with-fpx due to
+ decision to default FlashPIX to `no`. FlashPIX library is not
+ very portable and is only known to work properly under SPARC
+ Solaris and Windows.
+
+ * NEWS: Updated with latest news.
+
+ * lcms: Updated to LCMS 1.14.
+
+2005-01-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (ReadJP2Image): Handle images in YCBCR colorspace.
+ (ReadJP2Image): Retrieve and store an ICC ICM color profile if
+ present.
+
+ * PerlMagick/t/tiff/read.t: Added test for reading truecolor
+ planar TIFF image.
+ Added test for reading 32-bit TrueColor TIFF image.
+ Added test for reading 32-bit grayscale TIFF image.
+
+ * coders/tiff.c (ReadTIFFImage): Fixed stripped TIFF reader.
+
+2005-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Only set TIFFTAG_PREDICTOR to 2
+ for bits-per-sample values that libtiff supports.
+
diff --git a/ChangeLog.2006 b/ChangeLog.2006
new file mode 100644
index 0000000..fa031f4
--- /dev/null
+++ b/ChangeLog.2006
@@ -0,0 +1,189 @@
+2006-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Magick++/Image.html: Fix documentation regarding retrieving
+ EXIF attribute.
+
+ * magick/command.c: Fix typo in usage messages.
+
+2006-11-02 Daniel Kobras <kobras@debian.org>
+
+ * coders/dcm.c: (ReadDCMImage) Prevent buffer overflow of
+ `photometric` array in DCM coder. Original patch thanks to
+ M Joonas Pihlaja. (CVE-2006-5456)
+
+ * coders/palm.c: (ReadPALMImage) Fix heap overflows of `one_row`
+ array in PALM coder. Original patch thanks to M Joonas Pihlaja.
+ (CVE-2006-5456)
+
+2006-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated libtool to latest CVS head version (1.2352 2006/10/24)
+ in order to fix a bootstrap nit.
+
+2006-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated autoconf to version 2.60, automake to version 1.10, and
+ libtool to latest CVS head version (1.2348 2006/10/22).
+
+2006-09-11 Daniel Kobras <kobras@debian.org>
+
+ * coders/xcf.c (ReadBlobStringWithLongSize): Add new parameter `max`
+ to prevent overflowing the `string` array. (CVE-2006-3743)
+ (ReadOneLayer): Adjust callers of ReadBlobStringWithLongSize(), and
+ guard against infinite loops on premature end-of-file.
+ (ReadXCFImage): Adjust callers of ReadBlobStringWithLongSize(), and
+ guard against infinite loops on premature end-of-file.
+
+2006-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/sgi.c (ReadSGIImage): Mostly applied Debian patch for
+ CVE-2006-4144 security issue related to RLE decoding. Also added
+ complete verification of file header.
+
+ * magick/image.c (ComputePixelError): Add progress monitor.
+ (GetImageStatisticsMean): Call progress monitor less often.
+ (GetImageStatisticsVariance): Call progress monitor less often.
+
+2006-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): ImageInfo `endian` option now
+ controls TIFF byte-order rather than bit-order when writing.
+
+ * coders/png.c (ReadOnePNGImage): Fix compilation problem. Patch
+ submitted by Aron Stansvik.
+
+2006-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (WriteJPEGImage): Clear the JPEG library
+ structures in order to ensure a completely clean slate.
+
+2006-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ConvertImageCommand): Fix memory leaks which
+ occured when an image was not returned.
+
+ * magick/command.c (IdentifyImageCommand): Ditto.
+
+ * magick/command.c (MogrifyImageCommand): Ditto.
+
+2006-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Add mention of -resample to convert and
+ mogrify usage messages.
+
+2006-05-31 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure.ac: Fix arguments to AC_CHECK_HEADER.
+
+2006-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): -define tiff:alpha= override was
+ only working if the TIFFTAG_EXTRASAMPLES tag was present. Now it
+ is always available when an alpha channel is present.
+
+2006-05-11 JH <jh@ops.everybox.com>
+
+ * GraphicsMagick.spec.in (files devel): Include
+ %{_libdir}/lib%{name}Wand.so.
+
+2006-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (NTGhostscriptEnumerateVersions): Recent GNU
+ Ghostscript identifies itself as "GPL Ghostscript".
+
+2006-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tiff: Updated bundled libtiff to version 3.8.2.
+
+2006-04-05 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c: Sets image is_grayscale flag as well as added more
+ symbolic constants.
+
+2006-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (IMAGE_DATA_ROUNDING): Thanks to Steve Sloan for
+ noticing that 8K is 8192 rather than 8092. Added a define to
+ allow tailoring the pixel data alignment boundary in case 8K is
+ not the right answer for some reason.
+
+2006-03-20 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c: Ensure that unusued opacity channel is set to opaque.
+
+ * PerlMagick/t/input.art: New ART test image.
+
+ * PerlMagick/t/input8.mat: New MATLAB test image (8-bit indexed).
+
+ * PerlMagick/t/input_dbl.mat: New MATLAB test image (double grey)
+
+ * PerlMagick/t/input_rgb.mat: New MATLAB test image (8-bit RGB)
+
+2006-03-19 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c: Use symbolic constants rather than plain numbers
+ so the module is more maintainable. Correct the format for the
+ day of the week.
+
+2006-03-13 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c (WriteMATLABImage): Add RGB writer support for
+ MATLAB format.
+
+2006-03-11 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c (ReadMATImage): RGB support for MAT reader.
+
+2006-03-02 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c: Fixes for observed crash. Byte and word formats
+ are working.
+
+2006-02-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/environment.imdoc: MAGICK_FONT_PATH has not been supported
+ since 1.1. Remove mention of it!
+
+2006-02-23 Mike Chiarappa <mikechiarappa@libero.it>
+
+ * BCBMagick: Updated to latest changes
+
+2006-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/sgi.c (ReadSGIImage): Properly compute image depth for
+ 16-bit SGI image files.
+
+2006-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetExecutionPathUsingName): Search executable
+ search path for binary.
+
+2006-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage, WriteDPXImage): Alpha channel in DPX
+ uses zero, or reference black, to represent an opaque pixel.
+
+2006-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/semaphore.c (AllocateSemaphoreInfo): Allow semaphores to
+ recurse on POSIX systems which support recursive semaphores but
+ also warn if the semaphore recurses.
+
+ * magick/log.c (SetLogEventMask): Avoid deadlock if invoked before
+ log.mgk has been loaded.
+
+ * magick/attribute.c (GenerateEXIFAttribute): Fix memory leak on
+ error which was reported by Micha Kowalczuk.
+
+2006-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ReadImage): Avoid crash if delegate fails
+ to return image.
+
+2006-01-03 Daniel Kobras <kobras@debian.org>
+
+ * magick/attribute.c (GenerateEXIFAttribute): Fix EXIF IFD stack
+ overflow vulnerability.
+
+ * configure.ac: Fix typo in HTMLDecodeDelegate.
+
diff --git a/ChangeLog.2007 b/ChangeLog.2007
new file mode 100644
index 0000000..2e16f1f
--- /dev/null
+++ b/ChangeLog.2007
@@ -0,0 +1,973 @@
+2007-12-23 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * VisualMagick/configure/configure.rc: Better positioning of frog,
+ changed original ImageMagick messages.
+
+ * VisualMagick/configure/configure.exe: New build.
+
+2007-12-22 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * magick/command.c: Fix compilability issue for Microsoft Visual
+ Studio 6.
+
+2007-12-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Use some improved tests for POSIX standard types
+ available in Autoconf 2.61.
+ Add support for configuring a magick_uintmax_t type.
+ Added support for configuring a magick_uintptr_t type.
+
+2007-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.h (MagickSafeMultiplySize_t): New function to
+ perform a safe multiply. A multiplication overflow results in
+ zero.
+ (MagickAllocateMemory): Check for size_t value truncation/overflow
+ and zero size before deciding to allocate memory. Any detected
+ failure results in a NULL pointer being returned.
+ (MagickReallocMemory): Add a type parameter to use in cast in
+ order to avoid C++ portability problem.
+
+ * PerlMagick/Magick.xs: Eliminate use of deprecated methods.
+
+ * magick/memory.c (MagickAcquireMemory): New function to allocate
+ memory.
+ (MagickAcquireMemoryArray): New function to allocate memory for an
+ array of objects.
+ (MagickCloneMemory): New function to intelligently copy memory.
+ (MagickReallocateMemory): New function to re-allocate memory.
+ (MagickReleaseMemory): New function to deallocate memory.
+
+ * magick/deprecate.c (AcquireMemory): Deprecated in favor of new
+ function MagickAcquireMemory().
+ (CloneMemory): Deprecated in favor of new function
+ MagickCloneMemory().
+ (LiberateMemory): Deprecated in favor of new function
+ MagickReleaseMemory().
+ (ReacquireMemory): Deprecated in favor of new function
+ MagickReallocateMemory().
+
+2007-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ReadImage): Log colorspace of returned image.
+ (WriteImage): Log colorspace of image to be written.
+
+ * coders/{miff.c,mpc.c,tga.c,tiff.c}: Use MagickBoolToString().
+
+ * magick/{constitute.c,xwindow.c}: Use MagickBoolToString().
+
+ * magick/image.h (MagickBoolToString): New macro to convert truth
+ value to a constant "True" or "False" string.
+
+2007-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (IsImagesEqual): Allow comparing images if the
+ colorspace enumeration is different but the images are both an RGB
+ type.
+
+2007-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Add support for -monitor option to `animate`,
+ `display`, and `import`.
+
+ * coders/fpx.c (WriteFPXImage): Fix compilation problem.
+
+ * coders/dpx.c (TentUpsampleChroma): Fix access beyond array. Use
+ integer calculations where possible.
+
+2007-11-07 Andy Armstrong <andy@hexten.net>
+
+ * PerlMagick/t/setattribute.t: Fix for typo which breaks
+ Test::Harness 3.00.
+
+2007-10-20 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * mat.c: Attempt to read `logic` type modification
+ as monochrome image.
+
+2007-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (ReadBlob?SBFoo): Return 0 on EOF conditions
+ rather than a magic value concocted using ~0. The magic value was
+ very sensitive to the size/range of the type used to pass and
+ store it, leading to increased possibility of error. There was
+ also concern that sometimes a successfully read value may match
+ the magic value. Added documentation that EOFBlob() may be used
+ to determine that the blob is in EOF state.
+
+ * coders/pix.c (ReadPIXImage): Avoid reliance on a particular
+ magic value being returned from ReadBlobMSBShort on EOF.
+
+ * coders/avs.c (ReadAVSImage): Avoid reliance on a particular
+ magic value being returned from ReadBlobMSBLong() on EOF.
+
+2007-10-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * wpg.c: Monochrome images are not using palette -
+ palette is discarded in this case.
+
+2007-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.h: Blob I/O APIs now use sized types so that passed
+ and returned data values are a specific size rather than
+ architecture dependent.
+
+ * PerlMagick/t/read.t: Added read test for unsigned 32-bit LSB MAT
+ format.
+
+2007-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dib.c (ReadDIBImage): Use appropriate sized cast for DIB
+ width and height values. Validate width and height values.
+
+ * coders/bmp.c (ReadBMPImage): Use appropriate sized cast for BMP
+ width and height values.
+
+ * magick/colorspace.c (RGBTransformImage): Use a better rounding
+ algorithm when converting to HSL/HWB colorspaces.
+
+ * magick/gem.c (TransformHSL): Avoid GCC opimization bug on
+ Opteron which caused wrong results. Ensure that returned values
+ fall within bounds 0.0 to 1.0.
+ (TransformHWB): Avoid GCC opimization bug on
+ Opteron which caused wrong results. Ensure that returned values
+ fall within bounds 0.0 to 1.0.
+
+ * PerlMagick/t/ttf/read.t: Relax strictness quite a bit for TTF
+ read tests in order to allow somewhat different FreeType output.
+
+2007-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colorspace.c (RGBTransformImage): Add missing break
+ statement. HWB colorspace was used rather than HSL.
+ (TransformRGBImage): Add missing break
+ statement. HWB colorspace was used rather than HSL.
+
+2007-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/sun.c (ReadSUNImage): Properly report SUN image depth.
+
+2007-09-28 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Ability to write multiple images to one MAT file.
+ Fixed bug - incorrect matrix size for gray image.
+
+2007-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c (IntegralRotateImage): Rotation by 270 degrees
+ was wrong. It was flipped from what it should be.
+
+2007-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (CommandProgressMonitor): Remove any preceding
+ whitespace in the task descriptions so that we don't need to
+ update all of the task descriptions right away.
+
+ * magick/colorspace.c (RGBTransformImage): Improve progress monitor message.
+ (TransformRGBImage): Improve progress monitor message.
+
+ * coders/miff.c (ReadMIFFImage): Add read progress monitor support.
+
+2007-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c (WritePDFImage): Fix writing PDF with CCITT
+ compression. Addresses SourceForge bug 1209177 "TIFF to PDF CCITT
+ compression fails".
+
+2007-09-14 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Ability to read multiple images from one MAT file.
+ changed ExtendedSignedIntegralType to magick_off_t that better
+ corresponds to file positioning.
+
+2007-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c (WritePDFImage): Use ThumbnailImage() to create
+ thumbnail.
+
+ * coders/preview.c (WritePreviewImage): Use ThumbnailImage() to
+ create thumbnail.
+
+ * coders/xpm.c (WritePICONImage): Use ThumbnailImage() to create
+ thumbnail.
+
+2007-09-14 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Several warnings has been suppressed.
+
+2007-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Fix writing to pipes and other
+ non-seekable output destinations.
+
+ * magick/blob.c (WriteBlobFile): New function to copy a disk file
+ to a blob stream.
+
+ * magick/profile.c (ProfileImage): Fix removing profiles.
+
+2007-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c (png_flush_data): Don't invoke SyncBlob() since it
+ does far more than force data to the output file.
+ (ReadPNGImage): Make sure that PNG read errors are reported to the
+ user.
+
+ * coders/jpeg.c (TerminateDestination): Don't invoke SyncBlob()
+ since it does far more than force data to the output file.
+
+ * magick/blob.c (SyncBlob): Remove from public interface.
+
+2007-09-12 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Allowed to read signed integer matrices.
+ Fixed loop break.
+
+2007-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Ensure that selected photometric
+ most closely matches the user's expectation. Remove compression
+ if requested compression type is not compatible with the selected
+ photometric.
+
+2007-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c (IntegralRotateImage): Use tiles to speed up
+ rotation by 90 or 270 degrees.
+
+2007-09-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c The flop image has been eliminated in a reader.
+ Code has been shrinked a little bit.
+
+2007-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (GetImageCharacteristics): Add progress monitor support.
+
+ * magick/color.c (IsMonochromeImage): Add progress monitor support.
+ (IsGrayImage): Add progress monitor support.
+ (IsOpaqueImage): Add progress monitor support.
+
+ * coders/dpx.c (ReadDPXImage): Added progress indication.
+
+ * coders/cineon.c (WriteCINEONImage): Added progress indication.
+
+ * magick/command.c : Added a -monitor command option for
+ `composite`, `convert`, `identify`, `mogrify`, and `montage` in
+ order to enable a simple progress indicator.
+
+2007-09-06 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Write native gray MAT data when gray image is detected.
+
+2007-09-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetExecutionPath): Add support for Apple OS-X,
+ Linux, and FreeBSD.
+
+2007-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: For Windows MinGW-based build, find Ghostscript
+ fonts installed under C:/Program Files/.
+
+ * VisualMagick/bin/delegates.mgk: Adjust quoting to Ghostscript arguments
+ so that Ghostscript DLL is passed correct commands.
+
+ * config/delegates.mgk.in: Adjust quoting to Ghostscript arguments
+ so that Ghostscript DLL is passed correct commands.
+
+ * configure.ac: Provide defaults for GSColorAlphaDevice and GSGrayDevice.
+
+ * magick/nt_base.c (NTGhostscriptGetString): Support "GPL Ghostscript".
+
+2007-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/ps.c (WritePSImage): Improved Postscript writer
+ performance.
+
+2007-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/profile.c (AllocateImageProfileIterator): New function to
+ allocate an image profile iterator.
+ (DeallocateImageProfileIterator): New function to deallocate an
+ image profile iterator.
+ (NextImageProfile): New function to advance the image profile
+ iterator to the next profile.
+
+ * magick/image.h (Image): Profiles are now stored in a generic
+ container. As planned years ago, the color_profile, iptc_profile,
+ generic_profile, and generic_profiles members are now removed.
+
+2007-09-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/bmp.c Ability to read true color bitmap with invalid palette size
+ like other readers do.
+
+2007-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (ClonePixelCacheMethods): Remove DLL export.
+ (DestroyCacheInfo): Remove DLL export.
+ (GetCacheInfo): Remove DLL export.
+ (ReferenceCache): Remove DLL export.
+
+2007-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageType): More tweaks to obtain the desired
+ behavior when converting to a bilevel image.
+
+ * coders/tiff.c (WriteTIFFImage): Logic which decided the output
+ subformat to write was too convoluted to understand, and in fact
+ palette images were not be written sometimes when they should be
+ (bug added on 2007-08-19). Deleted the convoluted code and
+ replaced with a different design which should be more correct and
+ flexible.
+ (ReadTIFFImage): Decided to read bilevel TIFF using a colormap
+ since there are significant internal advantages to doing so.
+ However, the writer is carefully designed to output normal bilevel
+ TIFF so this should not annoy TIFF users.
+
+ * magick/constitute.c (ImportImagePixelArea): Re-wrote grayscale
+ pseudoclass import to be more efficient and more tidy.
+
+2007-08-30 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/art.c Added ART writer
+
+2007-08-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (ReadBlobLSBFloat): Promoted to be a public
+ interface (was in mat.c).
+ (ReadBlobMSBFloat):Promoted to be a public interface (was in
+ mat.c).
+
+2007-08-29 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/art.c InsertRow has been replaced by ImportImagePixelArea
+
+2007-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c (ReadPNMImage): PNM "raw" formats are now read
+ using ImportImagePixelArea()
+
+ * magick/constitute.c (ExportImagePixelArea): Added an optional
+ export_info parameter for returning information back to the user.
+ (ImportImagePixelArea): Added an optional import_info parameter
+ for returning information back to the user.
+
+ * coders/jbig.c (ReadJBIGImage): Use ImportImagePixelArea().
+ (WriteJBIGImage): Use ExportImagePixelArea();
+
+ * coders/tiff.c (WriteTIFFImage): Make compression logic a bit
+ more tidy.
+
+ * coders/pcx.c (WritePCXImage): Use GetImageCharacteristics().
+
+ * coders/pcl.c (WritePCLImage): Use GetImageCharacteristics().
+
+ * coders/dib.c (WriteDIBImage): Use GetImageCharacteristics().
+
+ * coders/xpm.c (WritePICONImage): Use GetImageCharacteristics().
+
+ * coders/viff.c (WriteVIFFImage): Use GetImageCharacteristics().
+
+ * coders/tga.c (WriteTGAImage): Use GetImageCharacteristics().
+
+ * coders/sgi.c (WriteSGIImage): Use GetImageCharacteristics().
+
+ * coders/ps2.c (WritePS2Image): Use GetImageCharacteristics().
+
+ * coders/pdf.c (WritePDFImage): Use GetImageCharacteristics().
+
+ * coders/palm.c (WritePALMImage): Use GetImageCharacteristics().
+
+ * coders/ps.c (WritePSImage): Use GetImageCharacteristics().
+
+ * coders/jp2.c (WriteJP2Image): Use GetImageCharacteristics().
+
+ * coders/jpeg.c (WriteJPEGImage): Use GetImageCharacteristics().
+
+ * PerlMagick/t/read.t: Added read test for LSB `float` MAT.
+
+2007-08-26 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c: MAT reader now extensively uses ImportImagePixelArea.
+
+2007-08-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am: Add rwblob and rwfile tests for MAT format.
+
+ * magick/constitute.c: Re-wrote Export/Import Float/Double macros
+ because they did not actually work right, and to eliminate the
+ performance penalty for native order.
+
+2007-08-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: Add support for "native" endian parameter
+ in PerlMagick.
+
+ * magick/command.c: Utilities now understand "native" as an
+ argument to -endian.
+
+ * magick/image.h (enum EndianType): Added NativeEndian enum value.
+
+ * configure.ac: Test libtiff for TIFFSwabArrayOfTriples().
+
+ * magick/constitute.c (ExportImagePixelArea): Support export in
+ little, big, and native endian.
+ (ImportImagePixelArea): Support import in little, big, and native
+ endian.
+
+2007-08-23 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c (WriteMATLABImage): MAT writer uses
+ ExportImagePixelArea() now. Fix issues noticed by valgrind.
+
+2007-08-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c (WritePNMImage): Use `-quality 0` rather than
+ `-compress none` to select the PNM ASCII subformats. This change
+ is made based on the principle of least surprise.
+
+ * magick/constitute.c (ExportImagePixelArea): Add a GrayQuantum
+ implementation for exporting from two color PsuedoClass.
+
+ * coders/pnm.c (WritePNMImage): Use GetImageCharacteristics() and
+ ExportImagePixelArea() in implementation.
+
+2007-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ExportImagePixelArea): Performance
+ improvements.
+ (ImportImagePixelArea): Performance improvements.
+
+2007-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (IdentifyImageCommand): If "%r" is present in
+ -format specifier, then read whole image.
+
+ * magick/utility.c (TranslateTextEx): Undocumented "%r"
+ substitution now returns a string based on GetImageType() rather
+ than a concatentation of image class and "Matte".
+
+ * coders/tiff.c (WriteTIFFImage): Use GetImageCharacteristics().
+
+ * magick/image.c (GetImageCharacteristics): New function to
+ evaluate the basic characteristics of the image.
+ (GetImageType): Use GetImageCharacteristics().
+
+2007-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (RegisterDPXImage): Remove extra newline in usage
+ note.
+
+ * coders/fax.c (RegisterFAXImage): Fix note to reflect that the
+ output from this coder is *not* a TIFF subformat as was previously
+ claimed.
+
+ * coders/tiff.c (WriteTIFFImage): Output G3 TIFF FAX images as per
+ the TIFF Class F specification.
+
+2007-08-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/{api.h, studio.h}: Strip out legacy MacOS 9 and VMS "support".
+
+ * magick/{nt_base.c, unix_port.c} (MagickGetMMUPageSize): New function to obtain
+ the VM page size.
+
+ * magick/pixel_cache.c (PersistCache): Fix a terrible memory leak
+ when reading MPC files. Added Cache reference-count logging.
+
+2007-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (BenchMarkSubCommand): Added a new `benchmark`
+ GraphicsMagick command which can be used to perform benchmarking
+ on any other GraphicsMagick command.
+
+2007-08-11 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c (ReadMATImage): Support image is_grayscale flag.
+ Add some coder logging.
+
+2007-08-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/{paint.c, render.c, annotate.c}: Use AlphaComposite()
+ from alpha_composite.h.
+
+ * magick/alpha_composite.h (BlendComposite): Move inline
+ BlendComposite() to a header file since it is used in multiple
+ places.
+
+ * magick/{shear.c, image.c}: Use BlendComposite() from
+ alpha_composite.h.
+
+ * magick/image.c (SetImageDepth): Don't bother to test current
+ depth in advance. Preserve is_monochrome flag. Encapsulate
+ bit-reduction algorithm in a macro. Be a bit smarter with
+ PseudoClass images.
+ (SyncImage): Preserve is_monochrome flag. Improve performance
+ when image does not have an opacity channel.
+
+ * PerlMagick/t/read.t: Allow some error when reading double MAT.
+
+2007-08-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/read.t: Update MAT read tests according to
+ instructions from Fojtik Jaroslav.
+
+2007-08-06 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/wpg.c (ReadWPGImage): Support WPG files which use XOR
+ operator.
+
+2007-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (ReadBlobLSBdouble): Migrate from mat.c.
+ (ReadBlobMSBdouble): Migrate from mat.c.
+
+2007-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ExportImagePixelArea): Add optimized
+ support for 2 and 16 color PseudoClass.
+ (ImportImagePixelArea): Add optimized support for 2 and 16 color
+ PseudoClass.
+
+ * magick/constitute.c (ImportImagePixelArea): Add option to output
+ pad bytes at end of pixel data. Added optimized implementation of
+ IndexQuantum for bilevel images.
+
+ * coders/tiff.c (WriteTIFFImage): Be smarter when writing gray
+ Palette and grayscale TIFF images in order to not waste time.
+
+ * coders/bmp.c (ReadBMPImage): Use ImportImagePixelArea() when
+ reading and writing bilevel and colormapped images.
+ (WriteBMPImage): Use ExportImagePixelArea() when writing bilevel
+ images.
+
+ * magick/version.h.in: Added wrapping for copyright line to a
+ reasonable width.
+
+ * AUTHORS: Added Daniel Kobras.
+
+ * magick/command.c (VersionCommand): Added feature support list to
+ -version output.
+
+2007-08-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (AnimateImageCommand): Add support for -type to
+ `animate`.
+ (DisplayImageCommand): Add support for -type to `convert`
+
+ * config/delegates.mgk.in, VisualMagick/bin/delegates.mgk: Added
+ gs-gray and gs-color+alpha delegate definitions.
+
+ * coders/{ept.c, pdf.c, ps.c}: Respect a -type Bilevel, Grayscale,
+ TrueColor, or TrueColorMatte request by passing appropriate
+ options to Ghostscript for rendering..
+
+2007-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ImportImagePixelArea): Improved read speed
+ for bilevel gray image. Many thanks to Mark Mitchell for
+ inspiration and ideas.
+
+ * coders/caption.c (ReadCAPTIONImage): Eliminate use of strcpy().
+
+ * coders/pnm.c (ReadPNMImage): Add logging as well as support for
+ is_monochrome and is_grayscale flags.
+
+ * magick/color.h (IsMonochrome): Add parenthesis so macro is more
+ robust.
+
+2007-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/html.c (WriteHTMLImage): Eliminate use of strncat().
+
+ * coders/locale.c (ReadConfigureFile): Eliminate use of strncat().
+
+ * coders/png.c (ReadOnePNGImage): Eliminate use of strncat().
+
+ * magick/fx.c (ConvolveImage): Eliminate use of strncat().
+
+ * coders/tiff.c (WriteTIFFImage): Eliminate use of strncat().
+
+ * magick/delegate.c (InvokePostscriptDelegate): Eliminate
+ doubled-output when running in verbose mode.
+
+2007-07-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/delegate.c (InvokePostscriptDelegate): MagickSpawnVP()
+ requires three parameters.
+
+2007-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * bzlib: Updated bzip2 to 1.0.4.
+
+ * jbig: Updated jbigkit to 1.6
+
+ * jp2: Updated JasPer to 1.900.1.
+
+ * lcms: Updated lcms to 1.16
+
+ * png: Updated libpng to 1.2.18.
+
+2007-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xc.c (ReadXCImage): If ImageInfo type field is set to
+ TrueColorType or TrueColorMatteType type, then return a
+ DirectClass image, otherwise a PseudoClass image is returned as
+ before. From the command line this can be used like:
+ `gm convert -size 640x480 -type TrueColor xc:red red.miff`.
+ Programs may also use this in order to obtain a DirectClass
+ canvas image to draw on.
+
+ * magick/enhance.c (LevelImage): Fix potential buffer overflow
+ which was added since the 1.1 branch.
+
+2007-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/delegate.c (UnixShellTextEscape): Don't escape newline
+ character since it performs the opposite of what is desired.
+
+2007-07-23 Daniel Kobras <kobras@debian.org>
+
+ * magick/delegate.c (UnixShellTextEscape): Fix fencepost error
+ when checking whether escaping is safe.
+
+2007-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Retire VMS and MacOS 9 support from package.
+
+2007-07-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/{cmyk.c, gray.c, mono.c, rgb.c, uyvy.c, wbmp.c, yuv.c}
+ (ReadFOOImage): Check for EOF while searching for start of image
+ data.
+
+ * tests/Makefile.am: Don't test PTIF format with blob I/O since it
+ is not possible to pass the rwblob test and it is really an output
+ driver rather than a format.
+
+ * libtool: Update to latest CVS libtool.
+
+ * magick/constitute.c (ExportModulo8Quantum): Move Import and
+ Export macros from header file since they are not used anywhere
+ else.
+
+ * coders/dpx.c: Add underscore suffix to macro local variable
+ names in order to avoid conflict with names in code using the
+ macros.
+
+2007-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c: Reduce the number of warnings when compiling
+ the Wand library.
+
+ * coders/xwd.c (XWD_OVERFLOW): Eliminate comparison between signed
+ and unsigned.
+
+ * coders/pnm.c (ValidateScalingIndex): Eliminate check to see if
+ unsigned type is less than zero.
+
+ * magick/log.c (LogMagickEvent): Even though log file name comes
+ from a controlled source (log.mgk), perform safe numeric
+ substitution on it.
+
+ * coders/xwd.c (ReadXWDImage): Eliminate conflict between locally
+ defined OVERFLOW macro and similarly named macro under Windows.
+
+2007-07-18 Daniel Kobras <kobras@debian.org>
+
+ * coders/xwd.c (ReadXWDImage): Integer overflow fix
+ (CVE-2007-1797). From Debian patch
+ xwd_integer_overflow_fixes_CVE-2007-1797.
+ (ReadXWDImage): Fix for integer under/overflow. From Debian patch
+ xwd_overflow_fix.
+
+ * coders/wpg.c (ReadWPGImage): WPG segfault fix. From Debian
+ patch wpg_segfault_fix.
+
+ * coders/viff.c (ReadVIFFImage): Verify number of bands prior to
+ using image. From Debian patch viff_heap_corruption_fix.
+
+ * coders/sun.c (ReadSUNImage): Sun segfault fix. From Debian
+ patch sun_segfault_fix.
+
+ * magick/blob.c (ReadBlobStream): Never try to read data beyond
+ EOF in blob streams. Some (but not all) ReadBlob*() methods
+ already implemented similiar checks. Moving it to the central
+ ReadBlobStream() increases robustness and prevents out-of-bounds
+ reads. From Debian readblob_offset_robustness patch.
+
+ * coders/pnm.c (ReadPNMImage): Validate pixel scaling. From
+ Debian pnm_scale_fix patch.
+
+ * coders/pict.c (ReadPixmap): PICT segfault fix. From Debian
+ pict_segfault_fix patch.
+
+ * coders/pcx.c (ReadPCXImage): PCX heap overflow fix. From Debian
+ pcx_heap_overflow_fix patch.
+ (ReadPCXImage): PCX segfault fix. From Debian pcx_segfault_fix.
+
+ * magick/montage.c, PerlMagick/t/montage.t: Do not pass bogus
+ negative values to modulate shadow in montage. Instead, drop a
+ constant grey shadow like current ImageMagick. From Debian
+ montage_shadow_fix patch.
+
+ * coders/png.c (ReadMNGImage): MNG segfault fix. From Debian
+ mng_segfault_fix patch.
+
+ * utilities/miff.4: MIFF man page apropos fix. From
+ Debian miff_apropos_fix patch.
+
+ * coders/icon.c (ReadIconImage): Icon segfault fix. From Debian
+ icon_segfault_fix patch.
+
+ * tests/drawtest.c: Make sure filename strings do not run out of
+ bounds in drawtest. From Debian drawtest_segfault_fix patch.
+
+ * config/delegates.mgk.in: Remove obsolete option -2 when calling
+ dcraw as a delegate. From Debian dcraw_options_fix patch.
+
+ * coders/dcm.c (ReadDCMImage): Fix integer overflow in DCM
+ coder. (CVE-2007-1797). From Debian dcm_overflow_fix patch.
+
+ * coders/bmp.c (ReadBMPImage): Verify file seek success. From
+ Debian bmp_overflow_fix patch.
+
+2007-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.h (MagickReallocMemory): It seems that realloc()
+ frees the provided memory pointer if the requested size is zero.
+ This was causing MagickReallocMemory() to perform a double-free
+ under error conditions. Inspired by Debian
+ realloc_double_free_fix patch by Daniel Kobras.
+
+2007-07-18 Daniel Kobras <kobras@debian.org>
+
+ * magick/quantize.c (GrayscalePseudoClassImage): Fix computation
+ of memory required for colormap index
+ (colormap_heap_overflow_fix).
+
+2007-07-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (WriteRunlengthPacket): Converted excessively long
+ macro to a function and hopefully eliminate warnings when using
+ Visual Studio 2005.
+ * magick/pixel_cache.c (ClonePixelCache): Eliminate bug when
+ size_t is an unsigned type.
+
+2007-07-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageInfo): Address security issue noted by
+ CVE-2006-0082
+ http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-0082 in
+ which output filenames matching arbitrary printf specifications
+ may cause GraphicsMagick to crash.
+
+ * magick/utility.c (TranslateTextEx): New version of TranslateText
+ which allows copying each attribute via a user-provided callback
+ function.
+
+ * magick/delegate.c (InvokeDelegate): Implement secure delegate
+ execution in POSIX environments in order to avoid injection of
+ arbitrary shell commands via carefully crafted filenames. Fixes
+ Debian Bug 345238 "[CVE-2005-4601] Shell command injection in
+ delegate code (via file names)"
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=345238
+
+2007-07-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/forward.h: New header file to support forward type
+ declarations.
+
+ * coders/pnm.c (ReadPNMImage): Fix pixel scaling problem caused by
+ floating point rounding error.
+
+2007-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h: Provide pread() and pwrite() prototypes if they
+ are missing.
+
+ * configure.ac: Check for missing pread() and pwrite() prototypes.
+
+ * m4/ac_func_fseeko.m4: Use fixed version of AC_FUNC_FSEEKO.
+
+ * magick/utility.c (SystemCommand): Avoid use of snprintf.
+
+2007-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c: Only replace getc_unlocked() and putc__unlocked()
+ for a thread-safe build.
+
+ * magick/studio.h: Always use fseeko() and ftello() if they are
+ available.
+
+2007-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): Avoid using seek() if possible, and
+ don't use at all if the input is not seekable.
+
+ * coders/psd.c (ReadPSDImage): Eliminate memory leak when reading
+ PSD files. Fixes Sourceforge issue 1625477 "Memory leak reading
+ layered PSD Image".
+
+2007-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Fixed -affine command argument
+ validation. Fixes SourceForge issue 1743141 "Affine matrix option
+ parsing".
+
+ * config/magic.mgk: Added detection for BigTIFF.
+
+ * coders/tiff.c: Preliminary work to support BigTIFF.
+
+2007-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Fix problems encountered when reading and writing
+ from/to pipes or compressed files.
+
+2007-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): Improved the pixel data marshalling
+ in order to obtain better read performance for 10-bit DPX.
+
+ * magick/blob.c (OpenBlob): Added support for MAGICK_MMAP_READ and
+ MAGICK_MMAP_WRITE environment variable options to enable input and
+ output file access using mmap().
+
+2007-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (OpenBlob): Use MAGICK_IOBUF_SIZE to tune the size
+ of the I/O buffer. Sometimes performance is improved by using
+ something other than the current default of 16KB.
+
+2007-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): Handle case where compression
+ keyword is present but has value of `None`.
+
+2007-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (OpenBlob): Disable reading input files using
+ memory mapping since it has been learned that some operating
+ systems fail to do read-ahead on network files. Without
+ read-ahead, performance is poor.
+
+ * magick/resource.c (AcquireMagickResource): Map resource limit
+ was not being properly checked due to a typo. The memory limit
+ was being tested instead.
+
+ * coders/tiff.c (ReadTIFFImage): Use libtiff to decode OJPEG
+ compressed files into RGB. Probably requires new OJPEG
+ implementation from Joris Van Damme which is new in libtiff and
+ not yet released. I am not completely sure that this approach is
+ correct yet.
+
+2007-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/xwindow.c (MagickXGetWindowImage): Set image->depth
+ appropriately.
+
+ * many files: Compiler warnings reduction.
+
+2007-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/cineon.c (ReadCINEONImage): Alter sample scaling
+ algorithm a bit.
+
+ * tests/rwblob.c, tests/rwfile.c: Allow some slop when testing
+ Cineon format with QuantumDepth=8 since we are currently only
+ supporting 10 bit samples.
+
+2007-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (ReadJPEGImage): Fix reading 12-bit grayscale
+ JPEG.
+
+2007-05-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/cineon.c (WriteCINEONImage): Re-wrote Cineon writer from
+ scratch. There is no code originating from ImageMagick in this
+ source module any more.
+
+2007-04-30 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/art.c, coders.cut.c, coders/mat.c, coders/wpg.c: Add
+ support for PingImage() so that image identification is fast by
+ default. Also eliminates error message produced by mat.c due to
+ rotating an image which has no pixel cache.
+
+2007-04-09 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/wpg.c (ReadWPGImage): Fix for SourceForge bug id 1431805
+ "clip art wpg files cause access violation in graphics magick".
+
+2007-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (ModifyCache): Ensure that the cache nexus
+ is open. Fix for SourceForge bug id 1173713 "segfault in
+ ModifyCache"
+
+ * m4/acx_pthread.m4 (ACX_PTHREAD): Apply fixes necessary to
+ support C++ compiler properly.
+
+2007-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/GraphicsMagick.pc.in: Fix for SourceForge bug id 1576616
+ "Fix includedir variable in pkg-config files".
+
+ * magick/pixel_cache.c (GetOnePixel): Fix for SourceForge bug id
+ 1572357 "GetOnePixel definition appears incorrect". It is true
+ that this function is intended for read-only purposes and that the
+ PixelPacket value is returned directly.
+
+ * coders/pdf.c (WritePDFImage): Fix for SourceForge bug id 1510075
+ "Failed to write PDF with JPEG compression".
+
+ * magick/command.c (MogrifyImageCommand): Properly bubble up
+ errors and terminate further mogrify processing immediately. This
+ in response to SourceForge bug id 1391421 "problem doing resize on
+ 273x1 JPEG".
+
+ * magick/magick.c (InitializeMagickClientPathAndName): Fix for
+ SourceForge bug id 1315109 "segfault in InitializeMagick(NULL)".
+
+ * wand/magick_wand.c (MagickGetQuantumDepth): Fix for SourceForge
+ bug id 1353744 "MagickGetQuantumDepth doesn't work".
+
+ * PerlMagick/t/read.t: Added a test for WPG v1.
+
+2007-04-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c: Read Matlab files in both big and little endian
+ format.
+
+2007-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): Set DPX reference high quantity to
+ 2.047 rather than 2.048 since zero is assumed to occupy one count
+ and 2.047 seems to be the convention even though the DPX
+ specification says the default is 2.048. Technicolor uses 2.047.
+
+ * m4/acx_pthread.m4: Update version of ACX_PTHREAD macro used.
+
+2007-03-28 Fojtik Jaroslav <fojtik@humusoft.cz>
+
+ * coders/wpg.c: Support CTM translation in WPG reader.
+
+2007-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: Store 10-bit Luma samples in the filled 32-bit
+ storage word starting with the datum in the least significant
+ position.
+
+2007-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Updated autoconf to version 2.61.
+
+2007-02-10 Daniel Kobras <kobras@debian.org>
+
+ * coders/palm.c: (ReadPALMImage) Do not implicitly call
+ ReadBlobByte() twice in Min() macro. Patch thanks to Vladimir
+ Nadvornik. This was a regression introduced in patch for
+ CVE-2006-5456. (CVE-2007-0770)
+
diff --git a/ChangeLog.2008 b/ChangeLog.2008
new file mode 100644
index 0000000..5c453f5
--- /dev/null
+++ b/ChangeLog.2008
@@ -0,0 +1,2127 @@
+2008-12-28 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c: Ability to read extension blocks.
+
+ * coders/fits.c: Fixed MaxTextExtent limitation of blocks.
+
+2008-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/OpenMP.rst: Add results for Window Vista 64-bit / AMD Phenom
+ X4 9550.
+
+ * VisualMagick/installer/inc/body.isx: Revert yesterday's change
+ regarding the placement of config files. Place the config files
+ in a `config` subdirectory just as before.
+
+2008-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/body.isx: They say that when in Rome
+ you should do as the Roman's do. Based on this philosophy, all of
+ the coder and filter DLLs are now installed to the same directory
+ as the executables and DLLs which depend on them. This eases
+ operation under Windows Vista.
+
+2008-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c: First pass at supporting large file access under
+ Windows.
+
+2008-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (InitializeMagickResources): Improve resource
+ estimation for Microsoft Windows systems with large memory.
+
+ * magick/segment.c: Added some code to dump histograms with
+ `-verbose -verbose`.
+
+ * coders/tiff.c: Support reading/writing 16 and 24 bit float TIFF
+ files.
+
+ * magick/constitute.c (ExportViewPixelArea): Support exporting 16
+ and 24 bit short floats. Relies on code developed for
+ GraphicsMagick by Richard Nolde.
+ (ImportViewPixelArea): Support importing 16 and 24 bit short
+ floats. Relies on code developed for GraphicsMagick by Richard
+ Nolde.
+
+2008-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/operator.h (enum QuantumOperator): Added LogQuantumOp,
+ MaxQuantumOp, MinQuantumOp, and PowQuantumOp enumerations as well
+ as "Log", "Max", "Min", and "Pow" options to -operator.
+
+2008-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): The -write option was not
+ implemented in a useful fashion and the +write option never worked
+ at all. Re-implement -write and eliminate +write from the
+ documentation since +write is not needed.
+
+2008-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage, WriteTIFFImage) Support reading
+ and writing 64-bit integer TIFF.
+
+ * magick/constitute.c (ImportViewPixelArea): Add support for
+ importing 64-bit integer values.
+ (ImportViewPixelArea): Add support for exporting 64-bit integer
+ values.
+
+2008-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Fix bug with reading one bit per
+ sample RGB images.
+
+2008-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (OpenCache): Fix a code ordering problem
+ which results in `identify` throwing an assertion for PseudoClass
+ image files. This bug was added in the 1.3.2 release.
+
+ * coders/tiff.c (ReadTIFFImage): Fix bug with `ping` mode.
+
+2008-12-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c: Proper signed to unsigned conversion for 64 bit LSB images.
+
+2008-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/Makefile.am: When X11 is disabled, don't compile the
+ X11-specific source modules. Don't ever install any X11-related
+ header files.
+
+2008-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/segment.c (SegmentImage): Use `double` rather than 64-bit
+ integer to accumulate totalized values. Make the cluster summary
+ report more concise.
+
+2008-12-06 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c: Fix for 64 bit images.
+
+2008-12-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/segment.c (SegmentImage): Cluster threshold is expressed
+ as a percentage of total cluster pixels. Optimize for larger
+ images.
+
+2008-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/segment.c (SegmentImage): Accelerate using OpenMP.
+
+2008-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (ExpandFilenames): Remove some arbitrary
+ argument length limits. Pass -convolve argument without any
+ additional checking. Verify that strings are not truncated during
+ copy.
+ (ListFiles): Be more memory efficient.
+
+ * magick/fx.c (ConvolveImage): Fix formatting problem when logging
+ the convolution kernel used.
+
+ * magick/utility.c (TranslateTextEx): Support formatting huge
+ comment text.
+
+2008-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/fx.c (ConvolveImage): Don`t process opacity channel
+ unless image has one.
+
+ * magick/effect.c (MotionBlurImage): Use
+ AcquireOnePixelByReference() rather than AcquireImagePixels() to
+ retrieve one pixel. This is much more efficient.
+ (AdaptiveThresholdImage): Don`t process opacity channel unless
+ image has one.
+ (BlurImage): Don`t process opacity channel unless image has one.
+
+2008-11-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/profile.c (ProfileImage): +profile now supports a simple
+ exclusion syntax. For example, to strip all of the profiles
+ except for the ICM profile use +profile '!icm,*'. The new syntax
+ also allows multiple profile names to be listed at once. The
+ primary requirement is that all excluded profiles must be listed
+ prior to those to be stripped.
+
+2008-11-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/transform.c (RollImage): Remove image storage class
+ alteration.
+ (CompositeImageRegion): Ensure that the canvas image storage class
+ is correct.
+
+2008-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * config/delegates.mgk.in: Since we removed support for `spawn` a
+ long time ago, and no longer execute using the Unix shell by
+ default, we need to add an ampersand to the end of the two entries
+ previously using `spawn` so that the display program does not hang
+ when it invokes the external program.
+
+ * utilities/Makefile.am (UTILITIES_TESTS): Add preview-based
+ tests.
+
+ * coders/preview.c (WritePreviewImage): Solarize requires a
+ threshold argument.
+
+ * coders/vid.c (WriteVIDImage): Eliminate memory leak.
+
+ * magick/montage.c (MontageImages): Fix continued use of freed
+ memory.
+
+2008-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/omp_data_view.c (AccessThreadViewDataById): New function
+ to allow retrieving data via the index it was registered with.
+
+ * magick/enhance.c (BuildChannelHistograms): EnhanceImage() and
+ NormalizeImage() now share one common function for generating the
+ histogram.
+
+ * magick/enhance.c (ModulateImage): Improve performance a bit.
+ (ContrastImage): Improve performance a bit.
+ (GammaImage): Improve performance a bit.
+
+2008-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/authors.rst: List Mark Mitchell as an author.
+
+ * utilities/tests/msl_composite.sh: Fix `rm -f` without a valid
+ argument which annoyed NetBSD.
+
+ * coders/fits.c: Impose a limit on the length of the row PDU.
+ Make sure that GraphicsMagick version information does not
+ overflow the length allowed by a row PDU.
+
+2008-11-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (WriteJPEGImage): Use DCT algorithm default from
+ the library rather than the header file.
+
+ * magick: Adjust OpenMP scheduling options based on observed
+ behavior.
+
+2008-11-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c (IntegralRotateImage): Added OpenMP acceleration
+ for rotate by 90 and 270 degrees.
+
+ * configure.ac: New --disable-openmp-slow configure for disabling
+ use of OpenMP for algorithms which may run slower on operating
+ systems with crummy thread libraries. This still allows gaining
+ the benefits from OpenMP for CPU hogs. Verified to help with
+ FreeBSD 7.0 and Apple OS-X Leopard.
+
+ * magick/semaphore.c: Trimmed out the debug code in order to
+ obtain a bit more performance.
+
+2008-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c: Allow the user to specify the DCT method
+ (jpeg:dct-method), or if huffman encoding should be enabled
+ (jpeg:optimize-coding=true). Default the DCT method to the
+ libjpeg default rather than forcing it to JDCT_FLOAT since float
+ is slower on some systems.
+
+2008-11-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (BlobClose): Leak a little bit less memory when
+ reading a JP2 file.
+
+2008-11-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/wandtest.c: Eliminate memory leak.
+
+ * wand/drawing_wand.c (DestroyDrawingWand): Eliminate memory
+ leaks.
+
+ * coders/xwd.c (WriteXWDImage): Force colormapped images with more
+ than 256 colors to DirectClass.
+
+ * magick/enhance.c (ModulateImage): Improve progress message.
+
+ * coders/msl.c: Eliminate memory leaks.
+
+ * GraphicsMagick.spec.in: Apply RPM spec file fixes from Giacomo
+ Tenaglia for Red Hat Linux 4.
+
+2008-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/msl.c: Fix bug with attributes becoming appended to
+ themselves. Resolves SF issue 2255754. Reflowed code.
+
+2008-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: GraphicsMagick 1.3 released.
+ Next release on head will be 1.4.
+
+ * www/OpenMP.rst: Updated with latest measurement data.
+
+ * www/benchmarks.rst: Updated with latest benchmark data.
+
+ * coders/url.c (RegisterURLImage): Register HTTP and FTP URL
+ support in the "unstable" category since these are capable of
+ accessing the network and therefore represent a potential security
+ issue. Register the FILE URL support in the "stable" category
+ since it is capable of incorporating local disk files, which may
+ still represent a security security issue for server applications.
+ Note that disabling these functions might cause some existing MSL,
+ MVG and SVG scripts to stop working if they use external URLs.
+
+2008-11-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c (ReadPNMImage): Sequential multi-thread the PNM raw
+ format readers. Can improve read performance quite substantially
+ for large PBM and PGM files, and less so for PPM. There is most
+ benefit for systems with more I/O than one CPU core will support.
+ Systems with slow I/O and a relatively fast CPU may see somewhat
+ diminished read performance with more CPU consumption. As such,
+ this is effectively a verification that multi-threading the reader
+ is possible, and may be of benefit to power-users.
+
+ * magick/omp_data_view.c (AllocateThreadViewDataArray): New
+ function to allocate a thread view data array. Updated modules
+ using similar code to use this function in order eliminate
+ useless redundancy.
+
+2008-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c: Incorporate OMP thread views into the
+ pixel cache so usage is less invasive. Update OMP-enhanced source
+ modules to suit.
+ (GetImagePixelsEx): New function similar to GetImagePixels()
+ except that it reports exceptions to a user-provided structure.
+ (SetImagePixelsEx): New function similar to SetImagePixels()
+ except that it reports exceptions to a user-provided structure.
+ (SyncImagePixelsEx): New function similar to SyncImagePixels()
+ except that it reports exceptions to a user-provided structure.
+ (AccessImmutableIndexes): New function to access read-only
+ colormap indexes.
+ (AccessMutableIndexes): New function to access writeable colormap
+ indexes.
+ (AccessMutablePixels): New function to access writeable pixels.
+ (AccessDefaultCacheView): New function to access the default cache
+ view.
+
+2008-11-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (BenchmarkImageCommand): With no other
+ arguments, the benchmark command now defaults to one iteration.
+
+ * magick/effect.c (SpreadImage): Offsets array size is a prime
+ number to help avoid beating.
+ (SpreadImage): Ensure that spread loops are always terminal.
+
+ * magick/utility.c (MagickRandReentrant): Fix bug where rand() was
+ being continually re-seeded if rand_r() was not available.
+
+2008-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/tests/msl_composite.sh: Replace SVG image generation
+ with simpler approach which properly centers the text. Use our
+ own font so that tests will pass if the user does not have fonts
+ installed.
+
+ * magick/utility.c (GetMagickDimension): Extend to support parsing
+ optional x and y offset values and use to fix parsing for
+ -oil-paint and -unsharp when sscanf() is C'99 compliant.
+
+2008-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.h (AcquireOneCacheViewPixel): Pass pixel to
+ update by reference.
+ (AcquireOnePixelByReference): New private inline method which
+ passes pixel to update by reference.
+
+ * magick/omp_thread_view.h (AcquireOneThreadViewPixel): Pass pixel
+ to update by reference.
+
+ * magick/alpha_composite.h (BlendCompositePixel): Replace
+ BlendComposite with BlendCompositePixel, which passes the
+ composite pixel by reference.
+ (AlphaCompositePixel): Replace AlphaComposite with
+ AlphaCompositePixel, which passes the composite pixel by
+ reference.
+ (AtopCompositePixel): Replace AtopComposite with
+ AtopCompositePixel, which passes the composite pixel by reference.
+
+ * configure.ac: With excessive maintenance releases, the library
+ age portion of MAGICK_LIB_VERSION was overflowing its allotted
+ space. This resulted in 1.1.X releases reporting the wrong
+ MagickLibVersion as of 1.1.10. Fix this by supporting up to 99
+ values for each field.
+
+2008-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Fix passing the --with-windows-font-dir option via
+ DISTCHECK_CONFIG_FLAGS.
+
+ * utilities/tests/msl_composite.sh: Integrated MSL composition
+ test script contributed by Max Hohenegger, Max at hohenegger.eu.
+
+ * magick/command.c (ConjureImageCommand): Return status was
+ inverted so one was returned for command success rather than zero.
+
+2008-11-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Updated libpng to 1.2.33 release.
+
+ * magick/color.c (FuzzyColorMatch): If fuzz is zero then
+ completely use the result of ColorMatch() rather than entering
+ unnecessary expensive code.
+
+2008-10-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h: Make sure we don't conflict with OpenMP
+ implementation if it is active but we are not using it.
+
+2008-10-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h (HAVE_OPENMP): Add logic to make sure that
+ OpenMP is only engaged for OpenMP 2.0 or later.
+
+ * magick/command.c (VersionCommand): Report OpenMP version.
+
+ * Makefile.am: The Magick++ build was supposed to be optional. Now
+ it is.
+
+ * Makefile.am: Eliminated .tar.bz2 and .zip packages from the
+ distribution. The .tar.bz2 package was hardly smaller than the
+ .tar.gz package so it wasted 5.9MB with little benefit. The
+ compression ratio on the .zip archives is absolutely terrible so
+ eliminating zip eliminates huge 9.6MB and 25MB files from the
+ distribution equation. Windows users can easily learn how to use
+ the vastly more efficient 7-Zip format.
+
+2008-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Rationalize OpenMP tests to make sure that OpenMP
+ can not be enabled without thread support.
+
+2008-10-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c (CompositeImageRegion): Add some minimal
+ region limit checking. Not completed yet.
+
+ * magick/transform.c (RollImage): Accellerate using OpenMP.
+
+2008-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h (omp_get_thread_num): Remove spurious trailing
+ `;`.
+
+ * magick/render.c (DrawPrimitive): Make method private since
+ nothing else is using it.
+
+ * magick/omp_thread_view.h (AccessThreadView): Inline function for
+ a bit more performance.
+ (AcquireOneThreadViewPixel) Inline function for a bit more
+ performance.
+
+2008-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * pragma omp parallel for: Use consistent static scheduling
+ throughout and ensure that 64 threads can be usefully engaged on a
+ 1024 row image.
+
+ * magick/pixel_iterator.c (SetRegionThreads): Implement logic so
+ that pixel iterators execute single-threaded when invoked on tiny
+ regions.
+
+ * magick/pixel_cache.c (SetNexus): Make staging buffer memset()
+ conditional in order to dramatically diminish impact to small
+ accesses. This memset() only exists to make valgrind happy.
+
+2008-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Fix progress monitor for the case
+ of reading planar stripped images.
+
+2008-10-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (DespeckleImage): Accelerate using OpenMP.
+
+ * magick/paint.c (OpaqueImage): Update to use pixel iterators.
+ (TransparentImage): Update to use pixel iterators.
+
+ * magick/decorate.c (FrameImage): Accelerate using OpenMP.
+ (RaiseImage): Accelerate using OpenMP.
+
+2008-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c (CompositeImageRegion): Start of new function
+ to act as a lighter-weight yet more flexible image composition
+ interface.
+
+ * magick/transform.c (ChopImage): Accelerate using OpenMP.
+ (CropImage): Accelerate using OpenMP.
+ (FlipImage): Accelerate using OpenMP.
+ (FlopImage): Accelerate using OpenMP.
+
+ * magick/effect.c (ThresholdImage): Accelerate using OpenMP.
+
+2008-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (AcquireOneCacheViewPixel): Optimize
+ implementation.
+
+ * magick/effect.c (MedianFilterImage): Accelerate using OpenMP.
+ (ReduceNoiseImage): Accelerate using OpenMP.
+
+2008-10-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/fx.c (WaveImage): Accelerate using OpenMP.
+ (SwirlImage): Accelerate using OpenMP.
+ (ImplodeImage): Accelerate using OpenMP.
+
+2008-10-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (GetCacheViewRegion): New function to
+ return the region bounded by a pixel cache view.
+
+ * magick/constitute.c (ExportViewPixelArea): New function to
+ support exporting the pixels from a pixel cache view.
+ (ImportViewPixelArea): New function to support importing pixels
+ to a pixel cache view.
+
+ * magick/pixel_cache.c (ReadStream): Eliminated function.
+ (WriteStream): Eliminated function.
+ (ClonePixelCacheMethods): Eliminated function.
+
+ * magick/image.h: Eliminated StreamHandler call-back type.
+ Eliminated ImageInfo stream member.
+
+ * magick/pixel_cache.c (GetCacheViewArea): New function to return
+ the area of a cache view.
+ (AccessCacheViewPixels): New function to access already selected
+ cache view pixels.
+
+2008-10-19 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c: Remove unused exponential data.
+
+2008-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/omp_thread_view.c: Move OMP Thread View functions out of
+ pixel cache module and put them in this new module.
+
+ * coders/xtrn.c (ReadXTRNImage): XTRNSTREAM mode was never
+ implemented so remove unfinished stub code.
+
+2008-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageDepth): Needed to assign image depth
+ attribute to user-specified depth rather than only altering the
+ pixels.
+ (SetImageOpacity): Reimplement using pixel iterators.
+ (AverageImages): Accelerate using OpenMP.
+ (GetImageBoundingBox): Accelerate using OpenMP.
+
+2008-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ConstituteTextureImage): Accelerate using
+ OpenMP.
+
+ * magick/image.c (TextureImage): Accelerate using OpenMP.
+
+ * magick/render.c (DrawAffineImage): Accelerate using OpenMP.
+
+2008-10-13 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c Fixed palette problem for >8 bit images.
+
+2008-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): Using +page now resets image
+ page offsets as documented for convert and mogrify.
+
+2008-10-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (GradientImage): Re-do OpenMP accelleration based
+ on new pixel cache interface for better performance.
+
+ * coders/dpx.c (ReadDPXImage): Progress monitor needs to tick when
+ row count is updated.
+
+ * coders/fits.c (ReadFITSImage): Update to use
+ MagickFindRawImageMinMax().
+ (WriteFITSImage): Expand buffer size to MaxTextExtent. Include
+ GraphicsMagick version in FITS header.
+
+ * coders/mat.c (ReadMATImage): Update to use
+ MagickFindRawImageMinMax().
+
+ * magick/constitute.c (MagickFindRawImageMinMax): New internal
+ function to assist with finding the minimum and maximum data of
+ raw image files.
+
+2008-10-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (AcquireThreadViewPixels): Convert thread
+ set view convenience methods into library methods because the
+ inline methods were causing the Sun Studio compiler to produce
+ thread unsafe code. Due to likely beneficial inlining in the
+ library, this is not expected to cause any performance impact.
+
+2008-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/filter.t: Add a test for UnsharpMask.
+
+ * magick/effect.c (UnsharpMaskImage): Use Blur rather than
+ GaussianBlur to create blur image since it is faster.
+
+ * magick/pixel_cache.c (AllocateThreadViewDataSet): Add a
+ destructor function in case data should not be destroyed, or needs
+ something other than MagickFree().
+ (AllocateThreadViewDataSet): Use user-provided destructor to free
+ user data.
+
+ * scripts/format_c_api_doc.py: Improvements from Mark Mitchell to
+ perform keyword/target substitions and wrap function prototypes.
+
+ * coders/dpx.c (ReadDPXImage): Accellerate reader using OpenMP.
+
+2008-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/api/types.rst: Convert types.html to reStructured text
+ format.
+
+2008-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/monitor.c (MagickMonitorFormatted): New method to support
+ issuing a formatted progress monitor message. Use it throughout
+ so that file name is included in progress indication.
+
+2008-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Bootstrap with autoconf 2.63. Require autoconf
+ 2.62 to bootstrap.
+
+2008-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www: Adopted improved web page design by Mark Mitchell.
+
+2008-10-04 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c coders/mat.c Used a same piece of code to calculate
+ min and max data value.
+
+2008-09-30 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c Fixed 16 bit fits writer that wrote wrongly
+ shaped unsigned ints.
+
+2008-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/conjure.imdoc: Applied patches from Max at hohenegger.eu to
+ mention previously undocumented elements and to provide a
+ composition example.
+
+2008-09-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c (IntegralRotateImage): Accelerate rotation by 0
+ and 180 degrees using OpenMP.
+ (XShearImage): Accellerate using OpenMP (accellerates -rotate and
+ -shear).
+ (YShearImage): Accellerate using OpenMP (accellerates -rotate and
+ -shear).
+
+2008-09-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (MotionBlurImage): Enable OpenMP now that pixel
+ cache is re-entrant.
+
+ * magick/pixel_iterator.c: Updated to use thread view convenience
+ inline methods as proof of principle.
+
+ * magick/pixel_cache.h: Added convenience inline methods to make
+ use of thread views a bit more pleasant.
+
+2008-09-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ShadeImage): Fix valgrind gripe.
+ (MedianFilterImage): Fix valgrind gripe.
+
+2008-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c: Pixel cache is believed to be thread safe
+ now.
+
+ * magick/deprecate.c (AcquireCacheView): Deprecate this function.
+ (GetCacheView): Deprecate this function.
+ (SetCacheView): Deprecate this function.
+ (SyncCacheView): Deprecate this function.
+
+ * magick/pixel_cache.c (AcquireCacheViewPixels): New function to
+ replace AcquireCacheView().
+ (GetCacheViewPixels): New function to replace GetCacheView().
+ (SetCacheViewPixels): New function to replace SetCacheView().
+ (SyncCacheViewPixels): New function to replace SyncCacheView().
+
+ * coders/msl.c: Applied patches from Max at hohenegger.eu which
+ fix a MSL parsing error related to gamma, and erroneous text
+ comments which claim that elements can't have attributes.
+
+2008-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resize.c (ResizeImage): Move OpenMP instrumentation to
+ outer loop so that eventually there can be more performance.
+
+2008-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resize.c (MinifyImage): Accelerate using OpenMP.
+
+ * magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+ Accept -gaussian-blur as a synonym for -gaussian.
+ (ConvertImageCommand, MogrifyImageCommand): Provide access to
+ MinifyImage() via -minify.
+ (ConvertImageCommand, MogrifyImageCommand): Provide access to
+ Magnifyimage() via -magnify.
+
+2008-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/channel.c (ImportImageChannelsMasked): New function to
+ import all the channels from an image except for the channels
+ specified.
+
+ * magick/effect.c (AddNoiseImageChannel): New function to add
+ noise to an image channel.
+ (BlurImageChannel): New function to blur one image channel.
+ (GaussianBlurImageChannel): New function to gaussian blur an image
+ channel.
+ (UnsharpMaskImageChannel): New function to unsharpmask an image
+ channel.
+ (SharpenImageChannel): New function to sharpen an image channel.
+
+2008-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (MotionBlurImage): Use GetOptimalKernelWidth1D()
+ to estimate a reasonable convolution kernel size. Prepare code
+ for OpenMP but don't enable OpenMP until it runs faster.
+ (AddNoiseImageChannel): New function to apply noise to a specified
+ image channel.
+
+2008-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ConvertImageCommand): Provide `convert` access
+ to MotionBlurImage() via -motion-blur option.
+ (MogrifyImageCommand): Provide `mogrify` access to
+ MotionBlurImage() via -motion-blur option.
+
+2008-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (SpreadImage): Accelerate using OpenMP.
+
+ * coders/msl.c: Applied MSL patch from graphicsmagick-bugs list to
+ correct handling of geometry x,y values by setting gravity
+ attribute to ForgetGravity.
+
+2008-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ShadeImage): Accelerate using OpenMP.
+
+2008-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (RandomChannelThresholdImage): Accelerate using
+ OpenMP. Support individual thresholding of the color channels.
+ (BlurImage): Blur was failing for PseudoClass images. This bug
+ was added on 2008-09-08.
+
+ * magick/pixel_cache.c (AcquireOneCacheViewPixel): New function to
+ return just one pixel from a cache view.
+
+2008-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (EnhanceImage): Accelerate using OpenMP.
+ (BlurImageScanlines): Added optimizations.
+
+ * magick/shear.c (IntegralRotateImage): Add missing progress
+ indication for 90 and 270 degrees rotation.
+
+ * www/perl.html: Fix formatting of examples. Should address
+ SourceForge issue [ 2100339 ] "Wrong format in example script on
+ web page".
+
+2008-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (BlurImage): Accelerate using OpenMP.
+
+2008-09-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/fx.c (ColorizeImage): Re-implement using pixel iterators.
+ (MorphImages): Re-implement using pixel iterators.
+ (OilPaintImage): Accelerate using OpenMP.
+ (SolarizeImage): Re-implement using pixel iterators.
+
+2008-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/fx.c (ConvolveImage): Accelerate using OpenMP.
+
+ * magick/effect.c (AdaptiveThresholdImage): Accelerate using OpenMP.
+
+2008-09-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c: Exhuastive study of the pixel cache code
+ reveals that it is inscrutable and not implemented in a fashion
+ which enables useful multi-threading. Therefore, the cache view
+ interfaces are now made OpenMP-safe via a global critical section.
+
+2008-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_iterator.c: Reduce use of critical sections around
+ pixel cache to the bare minimum based on analysis and testing.
+ Unfortunately, testing shows that the pixel cache views are still
+ not 100% thread safe so the extra locking is still required.
+
+ * magick/pixel_cache.c (ModifyCache): Make implementation thread
+ safe. This required removing a thread-unsafe optimization from
+ Bill Radcliffe.
+
+ * magick/command.c (BenchmarkImageCommand): Restore original
+ client name for each loop so that it is not extended further for
+ each iteration.
+
+ * magick/semaphore.c (UnlockSemaphoreInfo): Decrement lock depth
+ under protection of the lock.
+
+2008-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (AddNoiseImagePixels): Update to pass per-thread
+ `seed` value for more performance.
+
+2008-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/gem.c (GenerateDifferentialNoise): Use
+ MagickRandReentrant(). Added a `seed` argument so that we can pass
+ a per-thread `seed` value.
+
+ * magick/utility.c (MagickRandNewSeed): New function to produce a
+ semi-random `seed` value.
+ (MagickRandReentrant): New function which works like rand() but
+ attempts to be re-entrant if possible by allowing a seed value to
+ be passed.
+
+2008-08-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/channel.c (SetImageChannelDepth): Re-implement using
+ QuantumOperatorImage().
+
+ * magick/image.c (SetImageDepth): Re-implement using
+ QuantumOperatorImage().
+
+ * magick/operator.h (QuantumOperator): Added DepthQuantumOp for
+ setting the channel depth.
+
+ * magick/command.c (BenchmarkImageCommand): Add CPU-based
+ iteration rate metric to benchmark output.
+
+ * magick/resource.c (ListMagickResourceInfo): Include quantum
+ depth, bits per pixel, and process address size in resource
+ output so that output is more complete.
+
+2008-08-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SyncImage): Re-implement using pixel iterators.
+ (SortColormapByIntensity): Re-implement using pixel iterators.
+ (ClipPathImage): Re-implement using pixel iterators.
+ (CycleColormapImage): Re-implement using pixel iterators.
+ (GetImageDepth): Re-implement using pixel iterators.
+ (GradientImage): Parallize inner loop for speedup with larger
+ images.
+ (ReplaceImageColormap): Re-implement using pixel iterators.
+ (SetImage): Re-implement using pixel iterators.
+
+2008-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/operator.c (QuantumGamma): Removed unnecessary OpenMP
+ request on inner loops.
+
+ * magick/enhance.c (EqualizeImage,NormalizeImage): Execute
+ histogram generation pixel iterator with just one thread to
+ decrease contention for the histogram array.
+
+ * magick/pixel_iterator.c (InitializePixelIteratorOptions): New
+ function to initialize PixelIteratorOptions with defaults.
+
+ * magick/pixel_iterator.h (PixelIteratorOptions): New structure to
+ support passing pixel iterator execution options.
+
+2008-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Updated for changes to date in 1.3 development code.
+
+ * magick/pixel_iterator.c: Execute pixel iterators in parallel via
+ OpenMP.
+
+ * magick/pixel_cache.c (OpenCacheView): Ensure that pixel cache is
+ open.
+ (GetCacheInfo): Allocate semaphore immediately.
+
+2008-08-16 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c Writer now creates valid images according to
+ http://fits.gsfc.nasa.gov/fits_verify.html
+ Fixed problems: 1) zeros in HDU, 2) wrong padding. 3) possible
+ strlen() overflow.
+
+2008-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/{compare.c, channel.c, enhance.c, image.c, operator.c}:
+ Update existing pixel iterator callback functions so that they are
+ OpenMP safe.
+
+2008-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/compare.c (InitializeDifferenceImageOptions): Renamed
+ from DifferenceImageOptionsDefaults().
+ (InitializeDifferenceStatistics): New function to initialize
+ DifferenceStatistics.
+ (ComputeAbsoluteError, ComputePeakAbsoluteError,
+ ComputeSquaredError): Use local totalizing structure on stack and
+ update cumulative statistics when the loop terminates.
+
+2008-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www: Convert HTML pages to use a vibrant green theme rather than
+ colors stolen from old GIMP web site.
+
+2008-08-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/{compare.imdoc, options.imdoc}: Added documentation for
+ `compare`.
+
+ * magick/compare.h (enum HighlightStyle): Added
+ AssignHighlightStyle for simple color assignment. `Annotate` is
+ now `Tint`.
+
+ * magick/command.c (CompareImageCommand): Useful options are now
+ -metric, -highlight-color, and -hightlight-style.
+
+2008-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/compare.c (DifferenceImagePixels): Fixed `Annotate`
+ difference annotation algorithm. Added `Threshold` and `Xor`
+ difference annotation algorithms.
+ (GetImageChannelDifference): New function for computing
+ statistical image error using various metrics. Inspired by
+ `imgcmp` from Jasper.
+ (GetImageChannelDistortion): New function for obtaining
+ statistical image error using various metrics for a specified
+ image channel. Signature is compatible with similar ImageMagick
+ function.
+ (GetImageDistortion): New function for obtaining statistical image
+ error using various metrics for all the active channels in the
+ image. Signature is compatible with similar ImageMagick function.
+
+ * magick/command.c (CompareImageCommand): Added a `compare`
+ subcommand which compares two images using various metrics, and/or
+ generates a difference image using various difference annotation
+ algorithms. Documentation not yet updated.
+
+2008-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_iterator.c: Split user context in all pixel
+ iterator APIs into a mutable data part, and an immutable data
+ part. This required modification to all modules using the pixel
+ iterator methods.
+
+2008-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickCompareImageChannels): Use
+ DifferenceImage().
+ (MagickCompareImages): Implement by calling
+ MagickCompareImageChannels().
+
+ * magick/compare.c (DifferenceImage): The ImageMagick-compatible
+ CompareImages() function signature was clearly an example of bad
+ design so rename CompareImages() to DifferenceImage() with a
+ signature which does not unnecessarily mix functionality and
+ allows for ease of future expansion.
+
+2008-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/Makefile.am (WAND_TESTS): Added Wand drawtest and wandtest
+ to automated test suite.
+
+2008-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ThresholdImage): Don't read uninitialized pixel
+ indexes (valgrind gripe).
+
+ * coders/tiff.c (CompressionSupported): Use
+ TIFFIsCODECConfigured() to test if a codec is supported.
+
+ * tests/{rwblob.c, rwfile.c}: use DestroyImageList() rather than
+ DestroyImage().
+
+ * coders/psd.c (RegisterPSDImage): Fix module registration memory leak.
+
+ * coders/jpeg.c (RegisterJPEGImage): Fix module registration memory leak.
+
+2008-07-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (DestroyBlob, DestroyBlobInfo): Implementation is
+ a bit more robust.
+
+2008-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (ReadJPEGImage): Remove over-write of
+ image->client_data. Resolves SourceForge issue [ 2018974 ]
+ client_data is not passed to streamhandler.
+
+ * coders/png.c (WriteOnePNGImage): Fix crash when writing PNG
+ images with transparency and either type Optimize is requested, or
+ the image is colormapped.
+
+2008-07-12 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Fixed problem: "In this case, the referenced
+ images had previously been deallocated but are still being used.
+ Since they are overwritten, their signatures are invalid.
+
+2008-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcm.c (ReadDCMImage): Report actual image depth.
+
+ * magick/resource.c (InitializeMagickResources): Set default
+ maximum memory limit to physical memory rather than 2X physical
+ memory. This decision is made since the system paging device is
+ often slower than files in the filesystem, and so memory mapping
+ is likely faster.
+
+ * magick/blob.c (OpenBlob): The MAGICK_IO_FSYNC environment
+ variable causes output files to be synchronized to disk when set
+ to TRUE.
+
+2008-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/GraphicsMagick.html: Improved formatting of documentation.
+
+2008-07-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageInfo): Make use of the new
+ `extension_treatment` field.
+
+ * coders/dcraw.c (ReadDCRAWImage): Added a coder module to proxy
+ from various common RAW camera format extensions to the `dcraw`
+ delegate.
+
+ * magick/magick.h (MagickInfo): Add an extension_treatment member
+ to indicate how file extensions should be treated for this coder.
+
+2008-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/{animate.c,quantize.c}: Replace !ColorMatch() with
+ NotColorMatch().
+
+ * utilities/Makefile.am (install-exec-local-utilities): Add back
+ in support for --enable-magick-compat which was accidentally
+ dropped in the new makefiles for GraphicsMagick 1.2. Resolves
+ SourceForge bug 2005883.
+
+ * magick/color.h (NotColorMatch): New macro for testing that two
+ colors are not the same. Opposite from existing ColorMatch().
+
+ * magick/command.c: Replaced the many duplicate enum conversion
+ code fragments with calls to functions in enum_strings.c.
+
+ * magick/enum_strings.c: Absorbed the many "ToString" and
+ "StringTo" functions from other source modules.
+
+ * magick/effect.c (ThresholdImage): Optimize for larger images.
+
+ * magick/constitute.c (ConstituteTextureImage): New function to
+ return a texture canvas image based on a tile image. Similar to
+ existing TextureImage() except better optimized for creating new
+ images and inherits tile image properties.
+
+ * magick/color.h (IsBlackPixel): New macro to test if a pixel is
+ black.
+ (IsWhitePixel): New macro to test if a pixel is white.
+
+ * coders/tile.c (ReadTILEImage): Use new ConstituteTextureImage()
+ function rather than TextureImage(). Also allow the user to
+ request a particular image type.
+
+ * coders/pdf.c (Huffman2DEncodeImage): Explicitly request a strip
+ per page when writing Group4 TIFF.
+
+ * coders/tiff.c (WriteTIFFImage): Place a generous default limit
+ on rows-per-strip when using Group3 or Group4 FAX compression.
+ The default limit is added since it is observed that the Group4
+ compressor fails with extremely huge strips. Added a define
+ "tiff:rows-per-strip" to allow the user to explicitly set the rows
+ per strip. Added a define "tiff:strip-per-page=true" to allow the
+ user to force one strip per page no matter what. Added progress
+ monitor support to tile writer.
+
+2008-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/configure/configure.cpp: The MAT coder now depends
+ on zlib so add explicit dependencies for it.
+
+ * wand/magick_wand.c (MagickNegateImage): Implemented previously
+ unimplemented Wand method.
+ (MagickGammaImageChannel): Implemented previously unimplemented
+ Wand method.
+
+ * magick/operator.h (enum QuantumOperator): Added GammaQuantumOp
+ and "gamma" operator. Renamed InvertQuantumOp to NegateQuantumOp.
+
+2008-06-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/operator.h (enum QuantumOperator): Added InvertQuantumOp
+ and "invert" operator.
+
+ * coders/xcf.c (GIMPBlendModeToCompositeOperator): For XCF format,
+ we do support GIMP_DIVIDE_MODE composition now. Disable progress
+ monitor during tile composition.
+
+ * magick/composite.c (DivideCompositePixels): New Divide composite
+ operator contributed by Michael Burian <michael.burian@sbg.at>.
+
+ * magick/image.h (enum CompositeOperator): Added DivideCompositeOp.
+
+ * magick/enum_strings.c (CompositeOperatorToString): New function
+ to convert a composite operator to a string.
+ (StringToCompositeOperator): New function to convert a string to a
+ composite operator.
+
+2008-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickThresholdImageChannel): Implement
+ previously unimplemented Wand function.
+ (MagickGetImageExtrema): Implement previously unimplemented Wand
+ function.
+ (MagickGetImageChannelExtrema): Implement previously unimplemented
+ Wand function.
+ (MagickQueryFonts): Implement previously unimplemented Wand
+ function.
+
+2008-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * scripts/format_c_api_docs: Scan compare.c for API definitions.
+
+ * wand/magick_wand.c (MagickCompareImageChannels): Enable use of
+ this function.
+ (MagickCompareImages): Enable use of this function.
+
+ * magick/compare.c: New source file.
+ (IsImagesEqual): Move here from magick/image.c.
+ (CompareImageChannels): Initial implementation of function roughly
+ similar to the one in ImageMagick.
+ (CompareImages): Initial implementation of function roughly
+ similar to the one in ImageMagick.
+
+ * magick/pixel_iterator.c (PixelIterateTripleModify): New pixel
+ iterator function to access two images as read-only and one as
+ read-write for updating existing pixels.
+ (PixelIterateTripleNew): New pixel iterator function to access two
+ images as read-only and one as read-write for creating new pixels.
+
+2008-06-22 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * mat.c Added CloseBlob().
+
+2008-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickSetImageFormat): Add method to support
+ setting the image format.
+
+2008-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/profile.c (ProfileImage): Convert to use pixel iterators.
+
+2008-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/channel.c (ImportImageChannel): Convert to use pixel
+ iterators.
+ (SetImageChannelDepth): Convert to use pixel
+ iterators.
+
+ * Magick++/lib/Image.cpp (quantize): Error measurement support was
+ being performed incorrectly. SyncImage() is not needed here.
+
+2008-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/channel.c (GetImageChannelDepth): Convert to use pixel
+ iterators.
+
+2008-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/mat.c (RegisterMATImage): Set blob support to false for
+ MAT coder until bug related to blobs is fixed.
+
+2008-06-16 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * mat.c Ability to read a new compressed MATLAB image format.
+
+2008-06-15 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * mat.c, wpg.c: For empty images a message ImageFileDoesNotContainAnyImageData
+ is returned.
+
+2008-06-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/channel.c (ChannelImage): Convert to use pixel iterators.
+ (ExportImageChannel): Convert to use pixel iterators.
+
+ * coders/dpx.c (WriteDPXImage): As an experimental feature, when
+ the environment variable MAGICK_RESERVE_STORAGE is set to "TRUE",
+ then the DPX format writer will request the required storage from
+ the filesystem in advance (if supported by the OS) or the full
+ amount of memory required (when writing to an in-memory BLOB).
+
+2008-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magic.c (InitializeMagicInfo): New function to initialize
+ file format detection.
+ (GetMagickFileFormat): New internal implementation function to
+ detect file format based on file header.
+ (GetMagicInfo): This internal implementation function is eliminated.
+ (MagicInfo): MagickInfo structure is now private to the
+ implementation.
+
+2008-06-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (ListMagickInfo): Replace "blob support"
+ indication with the coder stability classification.
+ (RegisterMagickInfo): Pay attention to coder classification.
+
+ * magick/magick.h (MagickInfo): Added a coder stability
+ classification field as well as the MAGICK_CODER_STABILITY
+ environment variable to choose which coders are enabled.
+
+2008-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (GetImageCharacteristics): Don't access image
+ pixels if they are not defined yet.
+
+ * coders/{avi.c,avs.c,dcm.c,ept.c,fits.c,mtv.c,palm.c,rla.c,tga.c}:
+ Readers are now much more robust when faced with reading random files.
+
+2008-06-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageInfo): Exclude all virtual delegates and
+ coders for pseudo-formats.
+
+2008-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcm.c (ReadDCMImage): Make DCM reader quit immediately on
+ EOF condition.
+
+ * coders/avi.c (ReadAVIImage): Make AVI reader more robust at
+ rejecting bad files.
+
+ * configure.ac: Eliminated --enable-delegate-build option that I
+ have not used or tested for almost ten years so it probably did
+ not work anyway. Use --with-ttf=/prefix to specify the the
+ installation prefix for freetype. Use
+ --with-ttf=/prefix/bin/freetype-config to specify the whole path
+ to freetype-config.
+
+2008-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): Add support for
+ -black-threshold and -white-threshold.
+
+ * magick/image.h (enum ChannelType): Added GrayChannel
+ enumeration.
+
+ * magick/operator.c (QuantumOperatorImageMultivalue): New
+ implementation function to make creating legacy functions like
+ black/white thresholding easier.
+
+ * wand/magick_wand.c (MagickBlackThresholdImage): Implemented.
+ (MagickWhiteThresholdImage): Implemented.
+
+ * magick/effect.c (BlackThresholdImage): Implemented a
+ BlackThresholdImage() which is similar to (but not identical to)
+ the one in ImageMagick.
+ (WhiteThresholdImage): Implemented a WhiteThresholdImage() which
+ is similar to (but not identical to) the one in ImageMagick.
+
+2008-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/operator.c: Added support for additional channel
+ operators (-operator) for applying noise to one or more channels.
+ The additional operators are Noise-Gaussian, Noise-Impulse,
+ Noise-Laplacian, Noise-Multiplicative, Noise-Poisson, and
+ Noise-Uniform. The amount of noise applied is controlled via the
+ numeric argument, which can specify the percentage of noise to
+ apply.
+
+ * magick/enum_strings.c: New source module to contain the various
+ EnumToString() and StringToEnum() functions which seem to multiply
+ like bunny-rabbits.
+
+ * magick/gem.c (GenerateNoise): Poisson noise generation was
+ taking excessively long and producing wrong results. Noise
+ generation was only producing the correct amount of noise in the
+ Q8 build.
+ (GenerateDifferentialNoise): New function to return noise in a
+ floating-point differential format.
+
+2008-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_iterator.h: Removed x,y coordinate information from
+ all of the callback definitions since a use for this information
+ has yet to be found.
+
+ * magick/composite.c (CompositeImage): Use individual callback
+ functions for the composition operations.
+
+ * coders/xcf.c (ReadXCFImage): Deal with grayscale images the
+ GraphicsMagick-way.
+
+2008-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xcf.c (ReadXCFImage): Validate XCF file data so that
+ corrupted files don't crash GraphicsMagick.
+
+2008-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): Incrementally read user data
+ part and check for EOF so that bogus files are rejected quickly.
+
+ * coders/cineon.c (ReadCINEONImage): Incrementally read user data
+ part and check for EOF so that bogus files are rejected quickly.
+
+2008-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pict.c (ReadPICTImage): Ensure that row_bytes calculation
+ does not overflow. Verify that RLE decode does not overflow
+ buffer. Validate image frame dimensions.
+
+ * coders/palm.c (ReadPALMImage): Validate PALM bits per pixel and
+ colormap indexes.
+
+ * magick/resource.c (ListMagickResourceInfo): List controlling
+ environment variable in `-list resource` output as a configuration
+ usage reminder.
+
+ * coders/pdf.c (ReadPDFImage): Properly deal with reading rotated
+ PDFs.
+
+2008-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * FAQ.txt: Added a FAQ for how to extract and combine CMYK image
+ channels to individual files.
+
+2008-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/fx.c (ConvolveImage): Eliminate unnecessary "range check"
+ feature since range checking is not where the CPU time is going.
+
+ * magick/effect.c (UnsharpMaskImage): Re-write implementation to
+ use pixel iterators.
+
+ * magick/pixel_iterator.c: Decided that the old per-pixel
+ iterations were not useful enough to keep since the region-based
+ ones are working fine. Moved pixel_row_iterator.c to
+ pixel_iterator.c and renamed functions to remove the `Row`
+ designation.
+
+ * magick/composite.c (CompositeImage): Automatically adjust
+ colorspace of composite image so that it is compatible with canvas
+ image.
+
+ * magick/alpha_composite.h (AlphaComposite): Fix alpha composite
+ when both pixels contain transparency.
+
+ * PerlMagick/demo/demo.pl: Use segmentation parameters which
+ are more suitable for our image.
+
+2008-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c (CompositeImage): CMYK copy composition
+ operators automatically set the image colorspace to CMYK.
+
+ * coders/tiff.c (WriteTIFFImage): CMYK must take precedence over
+ JPEG compression. We don't support JPEG compression in TIFF with
+ CMYK.
+
+2008-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ChannelThresholdImage): Re-implement using
+ pixel iterators. Support thresholding only the red channel by
+ eliminating the switch to intensity thresholding if only one
+ channel parameter is supplied.
+
+ * coders/tiff.c (WriteTIFFImage): Don't accidentially convert CMYK
+ images to RGB.
+
+ * magick/composite.c (CompositePixels): Handle CopyBlack properly
+ for CMYK images.
+
+ * magick/command.c (CompositeImageCommand): Support CopyCyan,
+ CopyMagenta, CopyYellow, and CopyBlack.
+
+ * magick/composite.c (CompositeImage): Preserve the canvas image
+ colorspace.
+
+ * doc/options.imdoc: Remove mention of thresholding at the channel
+ level since this never worked in a useful fashion and now only
+ simple intensity thresholding is available via -threshold.
+
+ * magick/command.c (MogrifyImage): Revert to using ThresholdImage() rather
+ than ChannelThresholdImage().
+
+ * PerlMagick/Magick.xs: Revert to using ThresholdImage() rather
+ than ChannelThresholdImage().
+
+2008-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (AddNoiseImage): Implemented using pixel
+ iterators.
+
+ * magick/pixel_row_iterator.c (PixelRowIterateDualNew): New pixel
+ iterator. Similar to existing PixelRowIterateDualModify except
+ that this one is for when initializing a new image.
+
+2008-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c (CompositeImage): Update image composition to
+ use pixel iterator methods.
+
+2008-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/enhance.c: Re-wrote all enhancement functions in this
+ module to be based on the pixel iterator methods.
+
+ * magick/command.c (ConvertImageCommand, MogrifyImageCommand,
+ DisplayImageCommand): Gamma multiple channel syntax was broken.
+ Now it is fixed.
+
+2008-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colorspace.c (RGBTransformImage): Optimized lookup table
+ generation performance to the maximum extent possible.
+ (TransformRGBImage): Optimized lookup table
+ generation performance to the maximum extent possible.
+
+ * magick/image.h (RoundDoubleToQuantum): New macro to explicitly
+ safely round a `double` to a Quantum.
+ (RoundFloatToQuantum): New macro to explicitly safely round a
+ `float` to a Quantum.
+
+ * configure.ac: Add OpenMP support library to LIBS so that
+ dependent applications will pick up this dependency without
+ themselves needing to enable OpenMP.
+
+ * magick/command.c (CompositeImageList): Don't overwrite matte
+ flag for CopyOpacity composition.
+
+ * magick/composite.c (CompositeImage): CopyOpacity composition
+ needs the opacity channel to be enabled.
+
+ * PerlMagick/Magick.xs: Dissolve composition with Opacity was not
+ working right. Now it does.
+
+2008-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/gem.c (HWBTransform): Hue value range was scaled wrong,
+ leading to clipping.
+ (TransformHWB): Hue value range was scaled wrong, leading to
+ clipping.
+
+2008-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colorspace.c (RGBTransformImage): Re-implement transform
+ loops using PixelRowIterateMonoModify() in order to simplify the
+ code.
+
+2008-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colorspace.c (TransformRGBImage): Re-implement transform
+ loops using PixelRowIterateMonoModify() in order to simplify the
+ code.
+
+ * magick/{pixel_iterator.h, pixel_row_iterator.h}: Pass pixel
+ colormap index/indexes to callback functions. Dependent code is
+ adjusted to match.
+
+2008-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ConvertImageCommand, MogrifyImageCommand,
+ MogrifyImage): Add command access to the new channel operators.
+
+ * magick/operator.c (QuantumOperatorRegionImage): Support the new
+ channel operators. Update to use PixelRowIterateMonoModify() for
+ a bit more performance.
+
+ * magick/operator.h (enum QuantumOperator): Added new operators
+ AssignQuantumOp, ThresholdQuantumOp, ThresholdBlackQuantumOp, and
+ ThresholdWhiteQuantumOp.
+
+2008-05-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (VersionCommand): Report if OpenMP is supported
+ by the build.
+
+ * configure.ac, Makefile.am: Install documentation according to
+ the conventions established by the configure script. This
+ installs the documentation under
+ /usr/local/share/doc/GraphicsMagick by default.
+
+2008-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * scripts/format_c_api_docs: Add pixel_iterator.c and
+ pixel_row_iterator.c to API documentation formatter.
+
+ * magick/api.h: Include pixel_iterator.h and pixel_row_iterator.h.
+
+ * magick/Makefile.am (MAGICK_INCLUDE_HDRS): Formally install
+ pixel_iterator.h and pixel_row_iterator.h.
+
+ * magick/image.c (IsImagesEqual): Update to use
+ PixelRowIterateDualRead().
+ (GetImageStatistics): Update to use PixelRowIterateMonoRead().
+
+ * magick/pixel_row_iterator.h: New interfaces which are similar to
+ the already existing interfaces in pixel_iterator.h except that
+ they pass a row to the callback rather than one pixel.
+
+ * magick/operator.c (QuantumOperatorRegionImage): Add progress
+ monitor support.
+
+ * magick/pixel_iterator.c (PixelIterateMonoRead): Add a
+ `description` argument and progress monitor support.
+ (PixelIterateMonoModify): Add a
+ `description` argument and progress monitor support.
+ (PixelIterateDualRead): Add a
+ `description` argument and progress monitor support.
+ (PixelIterateDualModify): Add a
+ `description` argument and progress monitor support.
+
+ * magick/resize.c (HorizontalFilter, VerticalFilter): Switch back
+ to RoundSignedToQuantum() since some pixels were experiencing
+ underflow. Localize some variables so that we don't have to
+ declare them as private for OpenMP.
+
+2008-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac, magick/resize.c, PerlMagick/Makefile.PL.in: Added
+ OpenMP support for parallelizing a task across multiple cores.
+
+2008-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac, magick/nt_base.h: Fix using libbz2 under MinGW.
+
+ * coders/{msl.c, svg.c, url.c}: Fix compilation with modern
+ libxml2 under MinGW.
+
+2008-05-08 Josue Andrade Gomes <josuegomes@gmail.com>
+
+ * magick/nt_base.h, libxml/include/win32config.h (vsnprintf):
+ Fixed compilation issue noticed with Visual C++ 2008.
+
+2008-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (GetMagickInfo): Simplify implementation.
+ (RegisterMagickInfo): Remove any existing entry since module
+ loading may result in duplicate entries.
+
+2008-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtool: Update to libtool 1.2.4.
+
+ * magick/magick.h (MagickInfo): Store string attributes as `const
+ char *` to statically allocated data rather than as heap allocated
+ strings. THIS IS AN INTERFACE CHANGE. Using a coder written to
+ the old interface is non-fatal but may resemble a small memory
+ leak. The reason for the change is to avoid at least 880 needless
+ malloc()/strlen()/strlcpy() operations at initialization time, and
+ at least 880 free() calls at destruction time. While these
+ operations did not take long, they are still an unnecessary
+ overhead, which is increased in thread-safe applications.
+
+ * magick/module.c (OpenModule): Ignore requests to open modules
+ which have already been opened.
+
+ * GraphicsMagick.spec.in: Add --with-included-ltdl to the default
+ options since this seems safest until the libltdl validation logic
+ is fully robust. This should be made user-configurable in the
+ future.
+
+ * magick/Makefile.am (magick_libGraphicsMagick_la_LIBADD): Apply
+ libltdl dependency argument as required for building.
+
+ * configure.ac: Intuit if the GraphicsMagick library will depend
+ on -lltdl.
+
+ * Magick++/bin/GraphicsMagick++-config.in: Use substitutions
+ rather than invoking GraphicsMagick-config in order to determine
+ GraphicsMagick library usage requirements. This avoids problems
+ when GraphicsMagick-config is not in the executable search path.
+
+2008-05-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * GraphicsMagick.spec.in: NEWS was renamed to NEWS.txt. Enable
+ libtool verbose output so it is possible to diagnose build
+ failures.
+
+2008-05-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * mat.c: gm convert -limit Pixels 1 input_gray_lsb_16bit.mat crap.miff
+ don't rotate partial image.
+
+2008-04-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (DestroyMagickInfoList): Use DestroyMagickInfo().
+ (UnregisterMagickInfo): Use DestroyMagickInfo().
+ (RegisterMagickInfo): Simplify dramatically by adding to the front
+ of the list rather than maintaining alpha order.
+
+ * magick/image.c (DestroyImageInfo): Tidy up and simplify code.
+
+ * magick/constitute.c (WriteImage): Comment out the "bi-modal
+ delegate" execution code until we determine what value it offers.
+ The test suite passes without it.
+
+ * magick/magick.h (struct MagickInfo): There is no need for `name`
+ to be allocated data so make it const.
+ (DestroyMagickInfo): Add a static function to destroy a MagickInfo
+ structure. Renamed previous DestroyMagickInfo to
+ DestroyMagickInfoList and made it static.
+
+2008-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: GraphicsMagick 1.2 released.
+ CVS head is now 1.3 development.
+
+ * png: Updated libpng to 1.2.27.
+
+2008-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageInfo): Ignore file extensions which
+ match defined virtual delegate entries (including stealth
+ entries).
+
+2008-04-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * BENCHMARKS.txt: Added timings for -blur.
+
+2008-04-27 Darko Kojic <dkc@sf.net>
+
+ * magick/effect.c (MedianFilterImage): Fixes to compile on ARM
+ CPU.
+
+2008-04-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.h (MagickInfo): Remove image_info member since I
+ can not find any purpose for it.
+
+ * coders/tiff.c (WriteTIFFImage): Remove assertion check on
+ scanline size since it has not caught anything.
+
+ * magick/image.c (SetImageInfo): Ensure that the file extension
+ does not trigger unwanted activity such as access to an X11
+ server, printer, or the launch delegate.
+
+ * config/Makefile.am (configshare_DATA): Install colors.mgk in
+ share path.
+
+ * magick/blob.c (GetConfigureBlob): Search `share` config path
+ prior to `lib` config path.
+
+2008-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOnePNGImage): TrueColor RGB was usually
+ written rather than the desired more compact format. This is a
+ first pass at fixing that.
+
+2008-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * BENCHMARKS.txt: Added a benchmark summary.
+
+2008-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Prepare 1.2beta1 release.
+
+ * NEWS.txt: Updated with latest news.
+
+2008-04-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtool: Update to 1.2965 2008-04-22
+
+ * coders/png.c (ReadOneJNGImage): Deal with ReadImage() returning
+ a NULL pointer when reading JPEG sub-image.
+
+2008-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/channel.c (ExportImageChannel): Added progress monitor
+ support.
+ (SetImageChannelDepth): Added progress monitor support.
+ (ChannelImage): Don't preserve matte channel when extracting
+ channel.
+
+ * magick/image.c (SetImageOpacity): Avoid integer overflow in Q32
+ build. Added progress monitor support.
+ (SyncImage): Added progress monitor support.
+ (SetImage): Added progress monitor support.
+ (CycleColormapImage): Added progress monitor support.
+ (GetImageBoundingBox): Added progress monitor support.
+ (SortColormapByIntensity): Added progress monitor support.
+
+2008-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac, magick/Makefile.am: Don't use libtdl unless we are
+ supposed to be using it!
+
+ * libtool: Updated to GNU libtool 1.2960 2008-04-19.
+
+ * configure.ac, magick/delegate.h: It seems that the modern
+ convention is to store ghostscript headers in a subdirectory
+ called `ghostscript` rather than `ps`.
+ We don't actually need Ghostscript errors.h and that is a good
+ thing since it seems that some newer Ghostscript calls it ierrors.h
+
+2008-04-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/files-dlls.isx: Comment out inclusion
+ of X11 support DLLs.
+
+ * VisualMagick/magick/magick_config.h.in: X11 is no longer in the
+ default Windows build.
+
+2008-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c: Eliminate various annoying warnings noticed
+ under MinGW.
+
+ * magick/spinlock.h (_spinlock_release): Use `long` rather than
+ `int` in order to eliminate warning under MinGW.
+
+ * magick/semaphore.c (spinlock_wait): Use `long` rather than `int`
+ in order to eliminate warning under MinGW.
+
+ * magick/log.c (LogMagickEventList): Eliminate warning under MinGW.
+
+ * magick/compress.h: Clean up interface definitions to use
+ magick_uint8_t for unsigned character data.
+
+ * coders/jpeg.c (ReadJPEGImage): Don't use GetPixelCachePresent()
+ since it is not DLL-exported.
+
+2008-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/yuv.c (ReadYUVImage): Report exception info correctly.
+
+ * coders/xpm.c (ReadXPMImage): Report exception info correctly.
+
+ * coders/xc.c (ReadXCImage): Report exception info correctly.
+
+ * coders/tiff.c (ReadTIFFImage): Report exception info correctly.
+
+ * coders/null.c (ReadNULLImage): Report exception info correctly.
+
+ * coders/jpeg.c (ReadJPEGImage): Report exception info correctly.
+ Use of Huffman optimization is now based on available memory
+ rather than a hard-coded image size.
+
+ * coders/gif.c (ReadGIFImage): Report exception info correctly.
+
+ * magick/utility.c (MagickSizeStrToInt64): New function to convert
+ a size string with optional units suffix to a 64-bit integer.
+ (MagickStrToInt64): New function to convert a string to a 64-bit
+ integer, with error checking.
+
+ * magick/image.c (SetImage): SetImage now returns error status.
+
+ * magick/command.c: Eliminated the long-deprecated -cache resource
+ limit option.
+
+ * magick/resource.c: Complete re-write of the resource limit
+ system. Resource specifications are now absolute except that they
+ support a binary metric suffix such as `K` to scale the value.
+ Added the `Pixels` limit type to limit the maximum number of
+ pixels allowed for each image.
+
+2008-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (WriteJPEGImage): Output grayscale images more
+ efficiently.
+
+2008-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lcms: Updated lcms to 1.17.
+
+ * png: Updated libpng to 1.2.26.
+
+2008-04-09 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c (ReadOnePNGImage) Use the low bits of the PNG
+ tRNS values instead of scaling them when reducing from 16-bits.
+
+2008-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Updated to Autoconf 2.62.
+
+2008-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImageCommand): New -create-directories
+ option automatically creates subdirectories as needed when
+ -output-directory option is used. This is useful when one
+ directory tree of files is being mogrified to a new tree.
+
+2008-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (MagickCreateDirectoryPath): New function to
+ create a directory path. Will be used later.
+ * configure.ac: Tweaks to produce a successful MinGW cross-compile.
+
+2008-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Added a simple sentinel
+ assertion to hopefully flush out any remaining cases where
+ ExportImagePixelArea() writes past the end of its buffer.
+
+ * magick/constitute.c (ExportImagePixelArea): GrayQuantum case for
+ DirectClass pixels was sometimes writing a zero byte one past the
+ end of the allocated buffer. Thanks to Josue Gomes for reporting
+ this bug.
+
+2008-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/{pcd.c,pcx.c,pdb.c,pict.c,stegano.c,wpg.c,xcf.c}:
+ Warnings reduction.
+
+ * magick/{channel.c,image.c,unix_port.c,render.c}: Warnings
+ reduction.
+
+ * coders/mat.c: Convert C99 comments to C89 comments so code can
+ compile with a C89 compiler.
+
+ * coders/tiff.c (WriteTIFFImage): Add an assertion to enforce that
+ the bytes output to the scanline is no more than the bytes
+ allocated for the scanline.
+
+ * NEWS.txt: Updated with latest NEWS.
+
+2008-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c (WritePDFImage): Default to ZIP compression if
+ available. Ignore Image compression setting since the useful
+ value (set by the user) usually comes from ImageInfo.
+
+ * coders/png.c (WriteOnePNGImage): Fix progress monitor when
+ writing PNG.
+
+ * magick/channel.c (GetImageChannelDepth): Added progress monitor
+ support.
+
+ * magick/signature.c (SignatureImage): Added progress monitor support.
+
+ * magick/image.c (GetImageDepth): Added progress monitor support.
+
+2008-04-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtool: Update to libtool 2.2.2.
+
+ * coders/jpeg.c: Convert more code to use size_t for sized values
+ rather than long.
+
+ * coders/wpg.c (InsertRow): Fix log format string specification.
+
+ * coders/dpx.c (WriteDPXImage): Fix typo in casts.
+
+ * coders/fpx.c (ReadFPXImage): Apply FreeBSD patch from Mikhail
+ Teterin to allow FlashPIX to work better for 64-bit builds.
+ Addresses SourceForge issue 1824658 "FPX should work again now".
+
+ * magick/blob.c (ImageToBlob): Fix typo in cast.
+
+2008-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * CONTRIBUTE.txt: Convert contribute.html to reStucturedText
+ format and generate HTML version from it.
+
+ * PROCESS.txt: Convert description of development process to
+ reStucturedText format and generate HTML version from it.
+
+ * INSTALL-windows.txt: Add instructions for how to install from
+ setup.exe style installer. Also add instructions for how the
+ distribution package is built.
+
+ * Copyright.txt: Reformat in reStucturedText format and generate
+ HTML version from it.
+
+ * VisualMagick/installer/inc/body.isx: No longer include
+ development headers and libraries in the Windows DLL install
+ package since they are large and they may only work with the
+ version of Visual C++ used to perform the build. It is much safer
+ for the developer to build the package from source with his own
+ compiler.
+
+2008-03-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fix compilation issues with Microsoft Visual Studio.
+
+2008-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage, WriteDPXImage): Use lookup tables to
+ speed up value conversion.
+
+ * magick/memory.h (MagickAllocateArray): Renamed from
+ MagickAllocateMemoryElements.
+
+2008-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: Use memory allocation macros like the rest
+ of the code.
+
+ * magick/memory.c (MagickMalloc): New function which behaves
+ similar to malloc().
+ (MagickMallocArray): New function for allocating an array.
+ (MagickRealloc): New function which behaves similar to realloc().
+ (MagickFree): New function which behaves similar to free().
+ (MagickAllocFunctions): New function to allow the user to specify
+ the memory allocation functions.
+
+ * magick/memory.h: New header file to define memory allocation
+ functions.
+
+ * magick/deprecate.c (DeleteImageList, DestroyImages,
+ GetImageList, GetImageListIndex, GetImageListSize, GetNextImage,
+ GetNumberScenes, GetPreviousImage, ParseImageGeometry,
+ PopImageList, PostscriptGeometry, PushImageList,
+ SetCacheThreshold, SetImageList, ShiftImageList, SizeBlob,
+ SpliceImageList, UnshiftImageList): Remove functions which were
+ already deprecated in ImageMagick 5.5.2 or earlier.
+
+2008-03-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): Support writing image which is
+ already in a YCbCr colorspace.
+ (ReadDPXImage): Return YCbCr images in YCbCr colorspace unless
+ they are also Cineon log encoded.
+
+ * magick/image.c (CloneImage): Use CloneImageAttributes().
+
+ * magick/attribute.c (CloneImageAttributes): New function for
+ copying image attributes from one image to another.
+
+ * magick/utility.c (TranslateTextEx): Check if the pixel cache is
+ initialized before using a function which requires using it.
+ Thanks to Micha Kowalczuk for bringing this issue to my
+ attention.
+
+ * magick/attribute.c (SetImageAttribute): Only apply
+ transformations to "comment" and "label" attributes.
+
+ * magick/pixel_cache.c (GetPixelCachePresent): New function to
+ test if the image pixel cache is present and initialized.
+
+2008-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colorspace.c (RGBTransformPacket): Rationalize casts for
+ improved performance.
+
+ * magick/image.c (GetImageDepth): Use table lookups to improve
+ performance.
+
+2008-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (AllocateImage): Transfer any attributes from
+ ImageInfo to allocated image.
+ (SetImageDepth): Use table lookups to improve performance.
+
+2008-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImageCommand): Added an
+ -output-directory option to `mogrify` to send output files to the
+ specified directory.
+
+2008-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/read.t: Add input_logical_lsb_08bit.mat to
+ PerlMagick tests.
+
+ * magick/nt_feature.c (CropImageToHBITMAP, ImageToHBITMAP): Use
+ GlobalFree() to free bitmap handle.
+
+2008-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/t/read.t: Added/adjusted WPG test files from Jaroslav
+ Fojtik.
+
+2008-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * AUTHORS.txt, BUGS.txt, FAQ.txt, NEWS.txt, PLATFORMS.txt,
+ TODO.txt, INSTALL-unix.txt, INSTALL-windows.txt: Use
+ reStructuredText format.
+
+ * Makefile.am: Use reStructuredText for more files.
+
+2008-02-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ReadImage): Disable colorspace override
+ code since it was being wrongly-triggered in X11 display commands.
+
+2008-02-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/body.html: Update to mention 1.1.11 release.
+
+2008-02-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colorspace.c (RndToInt): Cast result to `unsigned int`
+ rather than `int` in order to avoid possible value truncation with
+ Q32 build. Problem was reported by Kai-Uwe Behrmann.
+ (TransformRGBImage): Fix loop iterator which was looping one past
+ the end of the array. Reported by Kai-Uwe Behrmann.
+
+ * magick/command.c: Added a -set option to the composite, convert,
+ display, mogrify, import commands in order to allow setting an
+ image attribute.
+
+2008-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: Use MagickAcquireMemory() rather than
+ AquireMemory().
+
+ * coders/xwd.c (ReadXWDImage): Eliminate integer overflow
+ vulnerability (IDefense 09.19.07).
+
+ * coders/xbm.c (ReadXBMImage): ditto
+
+ * coders/xcf.c (ReadXCFImage): ditto
+
+ * coders/dib.c (ReadDIBImage): ditto
+
+ * coders/dcm.c (ReadDCMImage): ditto
+
+2008-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): The RFC 3949 specification for
+ Internet FAX recommends LSB2MSB fill order so document that.
+
+2008-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Use `-define
+ tiff:fill-order={msb2lsb|lsb2msb}` to control TIFF bit fill order.
+
+2008-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Updated to latest CVS libtool.
+
+ * coders/tiff.c (CompressionSupported): Use
+ TIFFGetConfiguredCODECs() to test if a requested compression type
+ is supported by libtiff. Based on advice from Frank Warmerdam.
+
+ * configure.ac: Add test for TIFFGetConfiguredCODECs() in libtiff.
+
+2008-02-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c: With libtiff 3.6.1, including tiff.h and tiffio.h
+ is not sufficient to obtain the definitions from tiffconf.h so
+ libtiff is assumed to not support any features, such as
+ compression. Avoid this problem by explicitly including
+ tiffconf.h if it is found. This resolves SourceForge issue
+ [1883527] compression of tiff-file has no effect.
+
+2008-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/setup.isx: Set Inno Setup installer
+ compression to "lzma/max".
+
+ * PerlMagick/Magick.xs: Eliminate use of memory allocation macros
+ since these failed miserably under Windows where it seems that
+ malloc, free, and realloc are redefined via macros by the Perl
+ build environment. This reverts changes made on 2007-12-01.
+
+ * magick/memory.c (MagickAcquireMemoryArray): Use implementation
+ from the 1.1 branch.
+
+ * magick/utility.h: Remove MagickSafeMultiplySize_t since it seems
+ that use of inline functions in Windows is a disaster area.
+
+2008-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (windows-dist): Create a 7z compressed Windows
+ comprehensive source package. See http://www.7-zip.org/ for
+ information on Windows 7-Zip and http://p7zip.sourceforge.net/ for
+ information on portable 7-Zip (P7ZIP).
+
+2008-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Add logging for image resolution
+ and resolution units.
+
+ * magick/version.h.in: Update copyright year to 2008.
+
+2008-02-01 Gary V. Vaughan <gary@gnu.org>
+
+ * configure.ac: Updated for libtool-2.1b.
+
+ * bootstrap (libtoolize): Libtoolize can figure out the mode and
+ directory for libltdl from configure.ac.
+
+2008-01-28 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * magick/Makefile.am: Update
+ magick_libGraphicsMagick_la_DEPENDENCIES to use LTDLDEPS.
+
+2008-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageInfo): Successfully read existing file
+ names in the form file[123] which were failing to read since they
+ appear to be a valid sub-image specification.
+
+2008-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (ExpandFilenames): If a filename appears to
+ contain a wildcard specification, first check to see if there is
+ file matching the unexpanded wildcard prior to engaging in the
+ slow task of wildcard expansion. Without this fix, expanding the
+ command line takes a very long time if there are a huge number of
+ files in the directory, and some file names appear to contain
+ wildcard specifications. Inspired by SourceForge bug reports [
+ 1878992 ] "literal square brackets in file name cause large delay"
+ and [ 1783209 ] "converting runs slowly when subimage is
+ specified", but this might not be the complete fix for the
+ problem.
+
+2008-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Update to Automake 1.10.1 and enable generation of
+ an lzma compressed source package.
+
+2008-01-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Added configure option --with-umem to enable use
+ of the umem memory allocation library available in Solaris 9,
+ Update 3 and later, or from
+ https://labs.omniti.com/trac/portableumem/. This library supports
+ concurrency in multi-threaded programs and supports debugging
+ memory issues. See
+ http://developers.sun.com/solaris/articles/libumem_library.html
+ for a description of how to use the library for debugging memory
+ issues.
+
+2008-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (VersionCommand): Include a "Large Memory" item
+ in the Feature Support list.
+
+ * coders/png.c (RegisterPNGImage): Remove reference to dead PNG
+ ftp site.
+
+ * VisualMagick/configure/configure.cpp (InitInstance): Remove
+ project dependency on dxguid.lib (Direct-X).
+
+2008-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Update libtool to latest CVS version.
+
+2008-01-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (DisplayImageCommand): No longer default to
+ reading standard input if stdin fails isatty() test. This
+ behavior was causing failure to launch from Gnome and it is
+ difficult to work around the issue from within a .desktop file.
+ (AnimateImageCommand): No longer default to
+ reading standard input if stdin fails isatty() test.
+
diff --git a/ChangeLog.2009 b/ChangeLog.2009
new file mode 100644
index 0000000..6df01e3
--- /dev/null
+++ b/ChangeLog.2009
@@ -0,0 +1,1711 @@
+
+2009-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/unix_port.c (MagickSpawnVP): Remove unneeded new line
+ character in error message format.
+
+ * Magick++/Makefile.am: Allow Magick++ to be built as a shared
+ library under MinGW and Cygwin. This requires a modern GCC in
+ order for C++ exceptions to work.
+
+ * utilities/tests/annotate.sh: MSYS is garbeling up draw command
+ so use a command file rather than using command line.
+
+ * coders/{fits.c,meta.c,locale.c}: Fix benign warnings noticed
+ under Cygwin 1.7.
+
+ * magick/{constitute.c,resource.c,utility.c}: Fix benign warnings
+ noticed under Cygwin 1.7.
+
+2009-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/module.c (DestroyModuleInfo): If the Jasper library is
+ used, then we can't invoke lt_dlexit() because this unloads the
+ Jasper library and Jasper sometimes registers an atexit() cleanup
+ handler. Unfortunately, this may annoy memory leak checkers.
+
+ * coders/jp2.c: Defer Jasper initialization to point of use.
+
+2009-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickCdlImage): New method to apply the ASC
+ CDL to an image.
+ (MagickHaldClutImage): New method to apply a Hald CLUT to an image.
+
+2009-12-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h atof(), atoi(), and atol() are legacy functions
+ which might not be thread safe, might not enforce reasonable
+ limits, and should not be used for new code. So we implement them
+ via strtod() and strtol().
+
+2009-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickGetImageBoundingBox): New method to
+ return the crop bounding box required to remove any solid-color
+ border from the image.
+ (MagickGetImageFuzz/MagickSetImageFuzz): New methods to get and
+ set the color comparison fuzz factor
+
+ * wand/pixel_wand.c (ClonePixelWand): New method to deep-copy an
+ existing pixel wand.
+ (ClonePixelWands): New method to deep-copy an array of existing
+ pixel wands.
+
+ * wand/magick_wand.c (MagickSetResolution): New method to set the
+ wand resolution. This one also works before the image has been
+ read (unlike MagickSetImageResolution()).
+ (MagickSetResolutionUnits): New method to set the wand resolution
+ units. Use in conjunction with MagickSetResolution(). This one
+ also works before the image has been read (unlike
+ MagickSetImageUnits()).
+
+2009-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/demo/demo.cpp (main): Stop using deprecated functions.
+
+ * wand/drawtest.c: Stop using deprecated functions.
+
+2009-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/module.c (ModuleAliases): J2C is supported by the JP2
+ coder.
+
+ * coders/jp2.c: JP2 is now an alias for JPC since many files use
+ that extension. Problem reported by Stefano Acerbetti.
+
+2009-12-09 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c: The png8 encoder would fail when trying to write
+ a 1-color image. Problem reported by Bob Clark.
+
+2009-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Define _GNU_SOURCE and _NETBSD_SOURCE so that
+ pwrite() and pread() prototypes are available under GNU Linux and
+ NetBSD.
+
+ * coders/tiff.c: Warnings reduction.
+
+ * magick/widget.c: Warnings reduction.
+
+ * magick/segment.c (Classify): Warnings reduction.
+
+ * magick/magic.c (struct StaticMagic): Length and offset can never
+ be negative so use an unsigned type rather than size_t.
+
+ * magick/render.c (TracePath): Fix access one beyond the end of
+ the points array.
+
+2009-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/gem.c (GetOptimalKernelWidth1D, GetOptimalKernelWidth2D):
+ In the Q32 build, convolution kernel size was estimated
+ incorrectly for large sigmas on 32-bit systems due to arithmetic
+ overflow.
+
+2009-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ConvolveImage): Moved here from fx.c since this
+ is a more suitable place for it to be.
+
+ * magick/enhance.c (GammaImage): Improve performance a bit.
+ Preserve full precision in Q32 build.
+
+2009-11-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/{channel.c,constitute.c,nt_base.h}: Start using the C'99
+ `restrict` keyword.
+
+2009-11-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickGetImageAttribute): New method to get
+ an image attribute. Patch contributed by Mikko Koppanen.
+ (MagickSetImageAttribute): New method to set an image attribute.
+ Patch contributed by Mikko Koppanen.
+
+ * magick/constitute.c (ReadImage): Log subimage and subrange.
+
+ * configure: Update to Autoconf 2.65.
+
+ * magick/attribute.c (GenerateIPTCAttribute): Returned IPTC string
+ values were one character too short.
+
+2009-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (AllocateImage): The documented shorthand for
+ specifying image size via filename[WIDTHxHEIGHT] was not working
+ for raw formats which use the image tile_info data.
+
+2009-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (ParseSubImageSpecification): Try to match
+ behavior of previous sub-image specification parser. Some
+ incantations did not produce the same results.
+
+ * win2k/IMDisplay/res/{IMDisplay.ico, IMDisplayDoc.ico}: Replaced
+ with GraphicsMagick icon prepared by Jaroslav Fojtik.
+
+ * coders/svg.c (ReadSVGImage): Use runtime initialization of
+ SAXModules rather than static initialization.
+
+ * magick/command.c: Commands now support reading an image from
+ stdin in conjunction with a subrange specification (e.g. "-[1]").
+ Problem was reported by Mario Becroft.
+
+ * magick/common.h: New header file to incorporate the common bits
+ shared by studio.h and api.h.
+
+ * ltdl/ltdl.c: Update libltdl to 2.2.6b in order to fix security
+ issue. Resolves CVE-2009-3736 as it pertains to GraphicsMagick.
+
+2009-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ConstituteImage, DispatchImage): `A` and
+ `T` should indicate transparency and `O` should indicate opacity.
+ Behavior was inconsistent. In some cases `O` meant transparency
+ while in other cases it meant opacity. Also, in a few cases, matte
+ was not getting enabled in the image as it should. Problems were
+ reported by Scott Kuhl.
+
+2009-11-10 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c: Also suppress new pedantic warnings from most
+ older libpng-1.4.0 betas.
+
+ * coders/png.c: Added a warning when attempting to use libpng-1.4beta
+ older than 1.4.0beta67.
+
+2009-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): Only invoke ProfileImage() if
+ an ICC CMS transform is to be performed. Otherwise invoke
+ SetImageProfile() to add the new profile.
+
+ * magick/profile.c (ProfileImage): Improve logging messages.
+
+ * coders/tiff.c (ReadTIFFImage): Allow CIELAB TIFF to be read.
+
+ * coders/jpeg.c (ReadJPEGImage): Detect and apply colorspaces
+ appropriately for ITU FAX JPEG.
+
+2009-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tiff: Updated to libtiff 3.9.2.
+
+2009-11-08 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c: Suppress new pedantic warnings from libpng
+ version 1.2.41 and 1.4.0 and later.
+
+2009-11-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Document difference between -recolor and
+ Adobe Flash color matrix.
+
+2009-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImageCommand): Convolve does not accept
+ an argument which looks like a geometry. Resolves SourceForge
+ issue #2890923 "Different handling of -convolve between convert
+ and mogrify".
+ (MogrifyImage): Validate that user-provided matrix is square when
+ parsing -convolve and -recolor commands in order to avoid a core
+ dump.
+
+ * coders/tiff.c (ReadTIFFImage): Improved/added more coder logging
+ statements.
+
+ * magick/xwindow.c: Reflowed some code and comments.
+
+ * magick/utility.c (SetClientName): Default client name does need
+ to be "Magick", so original value is restored.
+
+ * coders/mpc.c (ReadMPCImage): is_monochrome and is_grayscale
+ flags were not managed properly for the MPC coder.
+
+2009-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (ReadJPEGImage): Added jpeg:block-smoothing and
+ jpeg:fancy-upsampling defines to control these JPEG library
+ options.
+
+ * magick/image.c (SetImageInfo): Fix lockup due to hanging in loop
+ while parsing malformed sub-image specification (SourceForge issue
+ 2886560). Also fixes the ability to pass the image size via the
+ filename specification like "myfile.jpg[640x480]" rather than
+ needing to use -size.
+
+ * coders/jpeg.c (ReadJPEGImage): Fix image scaling when used with
+ IJG JPEG library version 7.
+
+2009-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c: Added support for a "Threads" limit, which
+ specifies how many threads may be used. Note that if
+ omp_set_nested(true) is used, GCC's GOMP seems to replicate this
+ number of threads for each level of threading rather than sharing
+ the specified number of threads across all teams. For example,
+ specifying four threads leads to sixteen active threads with
+ omp_set_nested(true) and nested threading. This GOMP behavior
+ does not seem to cause any harm.
+ (GetMagickResourceLimit): New accessor function to retrieve the
+ maximum limit for a resource.
+
+ * magick/module.c (ReadModuleConfigureFile): Default set of module
+ aliases is now statically initialized. The modules.mgk file is
+ now optional and can be used to support adding more modules, or
+ diverting existing format support to a user-provided module.
+
+ * magick/magick.c (DestroyMagick): Document that this function
+ should be invoked from the program's primary thread after any
+ threads using GraphicsMagick have terminated.
+ (GetMagickInfo): Was thread safe for access but not properly
+ thread safe during initialization. Is now fully thread safe.
+ (InitializeMagick): Fully initialize everything needed to
+ read/write files. Document that this function MUST be invoked
+ from the program's primary thread prior to using any other
+ GraphicsMagick functions.
+
+ * magick/color_lookup.c (ReadColorConfigureFile): The colors.mgk
+ is now optional so don't throw an exception if it is not found.
+
+ * magick/semaphore.c (AcquireSemaphoreInfo): Deprecated this
+ internal function. Use AllocateSemaphoreInfo() and
+ LockSemaphoreInfo() instead.
+ (LiberateSemaphoreInfo): Deprecated this internal function. Use
+ UnlockSemaphoreInfo() instead.
+
+2009-10-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * config/colors.mgk: Colors.mkg is now empty since it is used to
+ modify or extend the built-in color lookup table.
+
+ * magick/{constitute.c,delegate.c,log.c,magic.c,magick.c,tempfile.c}:
+ Explicitly initialize semaphores via InitializeMagick().
+
+ * magick/type.h: New header file to contain types and function
+ prototypes for functions in type.c.
+
+ * magick/color_lookup.c (ReadColorConfigureFile): Store RGB color
+ table in a static struct. Entries in the colors.mgk file are now
+ used to modify statically-defined entries, or add new definitions
+ to the color table.
+
+2009-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: --enable-libtool-verbose configure option is no
+ longer needed now that we have silent build capability.
+
+2009-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (GenerateEXIFAttribute): Add support for
+ retrieving GPS EXIF attributes. Based on work contributed by
+ Jukka Manner.
+
+ * Magick++/lib/STL.cpp, Magick++/lib/Magick++/STL.h (shadeImage):
+ ShadeImage was the result of a botched cut-and-paste. Corrected
+ now. Thanks to Jukka Manner for making me aware of this.
+
+2009-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/analyze.c: New source file to contain image analysis
+ functions. Moved functions from image.c and color.c to this file.
+
+ * magick/color_lookup.c: New source file to contain color lookup
+ functions. Moved associated functions from color.c to this file.
+
+ * magick/ImageMagick.rc: Remove inclusion of magic.mgk.
+
+ * magick/utility.c (MagickRoundUpStringLength): Use a bit less
+ memory.
+
+ * magick/color.c: Use most efficient string allocation function.
+
+ * config/Makefile.am: Eliminate use of magic.mgk.
+
+ * magick/magic.c: Store file header magic data in a static struct.
+
+2009-10-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/describe.c (DescribeImage): Include composition operator
+ in verbose output. Also use CompressionTypeToString() to convert
+ a compression enum to a string.
+
+2009-10-11 Toby Thain <qu1j0t3@users.sourceforge.net>
+
+ * coders/psd.c: Further fix for 2783535 reported by Daniel Kirsch.
+ Omit 0x0 layers from the image list, or they break compositing.
+
+2009-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/xwindow.c: Check for overflow on all array allocations.
+
+ * magick/command.c (MogrifyImages): If there is only one image in
+ the list, then -flatten does nothing at all.
+
+ * magick/transform.c (FlattenImages): If the user provides only
+ one image then return a clone of that image rather than reporting
+ an error.
+
+ * magick/texture.c (TextureImage): If an under-texture is applied,
+ then remove the matte channel.
+
+ * magick/xwindow.c (MagickXMakeImage): Apply a checkerboard
+ pattern when displaying non-opaque TrueColor images. Fix a second
+ integer overflow issue related to CVE-2009-1882.
+
+2009-10-10 Toby Thain <qu1j0t3@users.sourceforge.net>
+
+ * coders/psd.c: Fix for 2783535 reported by Daniel Kirsch. PSD
+ parser was confused by 0x0 pixel layers, resulting in image data
+ corruption of all following layers.
+
+2009-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/xwindow.c (MagickXMakeImage): Fix for CVE-2009-1882
+ "Integer overflow in the XMakeImage function". The problem is
+ that the shared memory segment allocated may be smaller than the
+ image size requires due to integer overflow. On some systems it
+ may be possible to crash GraphicsMagick (while displaying an image
+ file) but not likely to overwrite the heap since shared memory
+ segments are outside of the heap allocation.
+
+ * magick/memory.c (MagickMallocArray): Use MagickArraySize().
+
+ * magick/memory.c (MagickArraySize): New private function to
+ compute the size of an array and return zero if it overflows the
+ size_t type.
+
+2009-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcm.c (ReadDCMImage): Handle (UN)known type VRs correctly
+ and interpret the transfer syntax correctly. Added define
+ "dcm:avoid-scaling" to request that the coder should not scale
+ image samples unless necessary (i.e. when bits used > quantum
+ depth or maximum colormap depth, depending on image type). Work
+ is contributed by John Sergeant.
+
+2009-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am (CHECK_PDF_FILE_COMPRESS): Add PDF tests with
+ the various compression options.
+
+ * coders/pdf.c (WritePDFImage): If the input file used JPEG
+ compression and has not been converted to a bilevel or palette
+ image, then use JPEG compression with original settings. Problem
+ was reported by Marco Atzeri.
+
+2009-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * config/modules.mgk: DCRAW module entries were missing.
+
+ * coders/tiff.c (WriteGROUP4RAWImage): Was not working properly on
+ big-endian CPUs with libtiff 1.4.
+
+ * coders/ps2.c (WritePS2Image): Use ImageToJPEGBlob().
+
+ * coders/ps3.c (WritePS3Image): Use ImageToJPEGBlob().
+
+ * coders/pdf.c (WritePDFImage): Decouple from libtiff. Use ImageToJPEGBlob().
+
+ * coders/dcraw.c (RegisterDCRAWImage): Needed to register module
+ name.
+
+ * coders/cals.c (ReadCALSImage): Fix bug in CALS reader which
+ caused reading images taller than the image width to fail with an
+ error.
+
+ * magick/utility.c (AcquireString): Minor optimizations.
+ (AllocateString): Minor optimizations.
+ (CloneString): Minor optimizations.
+ (LocaleCompare): Minor optimizations.
+ (SubstituteString): Re-implemented in a more compact way which
+ might avoid some reallocations.
+
+ * magick/magick.c (ListModuleMap): Don't crash if `module` was not
+ set.
+
+ * magick/delegate.c (ListDelegateInfo): Fix insignificant memory
+ leak.
+
+ * magick/compress.c (ImageToJPEGBlob): Preserve JPEG settings if
+ feasable.
+
+2009-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c (WritePDFImage): Use ImageToHuffman2DBlob() and
+ ImageToJPEGBlob().
+
+ * coders/cals.c (WriteCALSImage): Use ImageToHuffman2DBlob().
+
+ * magick/compress.c (ImageToHuffman2DBlob): New private
+ convenience function to produce a CCIT Group4 blob.
+ (ImageToJPEGBlob): New private convenience function to produce a
+ JPEG blob.
+
+2009-09-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jp2.c (ReadJP2Image): Fix scaling problem noticed when
+ reading 12-bit JP2 format. Problem was reported by Steve Shaw.
+ (WriteJP2Image): Support writing JP2 files with arbitrary depth
+ ranging from 2 to 16 rather than just 8 or 16.
+
+2009-09-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/unix_port.c (MagickGetMMUPageSize): Cache returned page
+ size to eliminated repeated system calls.
+
+ * magick/operator.c (QuantumOperatorRegionImage): Fix missing
+ percent in progress monitor message.
+
+2009-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/meta.c (GetIPTCStream): Should return IPTC block length
+ rather than remaining blob length. Patch submitted by John
+ Sergeant.
+
+2009-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/meta.c (GetIPTCStream): IPTC blobs should be padded to an
+ even size. Patch submitted by John Sergeant.
+
+2009-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteGROUP4RAWImage): Added a GROUP4RAW encoder.
+
+ * coders/cals.c (Huffman2DEncodeImage): Fix test failures when
+ doing I/O to an in-memory blob.
+
+ * coders/pcl.c (WritePCLImage): Use a different control code to
+ (hopefully) eject the page. Patch submitted by John Sergeant.
+
+2009-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am: Add CALS tests. Skip testing deep images for
+ most formats which don't support deep images.
+
+ * coders/cals.c: CALS module was not being built under Windows
+ with MSVC. Now it is.
+
+ * VisualMagick/configure/configure.cpp (process_library): CALS
+ module is dependent on TIFF library.
+
+ * coders/cals.c (WriteCALSImage): Allow CALS writing at any time,
+ but only enable CALS reader if libtiff is present at build time.
+
+ * coders/{cals.c,pdf.c,ps2.c,ps3.c} (Huffman2DEncodeImage): Force
+ TIFF image type to bilevel type.
+
+ * config/modules.mgk, VisualMagick/bin/modules.mkg: CAL-->CALS
+ rather than CALS-->CAL.
+
+2009-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/benchmarks.rst: Updated GraphicsMagick vs ImageMagick
+ benchmark results.
+
+2009-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/cals.c (WriteCALSImage): Initial CALS Type 1 writer
+ implementation. Contributed by John Sergeant.
+
+ * coders/png.c (ReadOnePNGImage): Fresh pixels should be set using
+ SetImagePixels().
+
+2009-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Released GraphicsMagick 1.3.7.
+
+2009-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/msl.c, doc/conjure.imdoc: Add support for a new `profile`
+ command in MSL/conjure which applies, adds, or removes one or more
+ IPTC, ICC or generic profiles from a file. Work contributed by
+ John Sergeant.
+
+2009-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (NTGhostscriptFind): Make sure we close the
+ registry key. Log any Windows error messages.
+
+ * magick/profile.c (AppendImageProfile): New function to add or
+ append a profile. If the profile already exists, then the data
+ provided is appended to it.
+
+ * coders/jpeg.c (ReadGenericProfile,ReadICCProfile,ReadIPTCProfile):
+ Profile chunks need to be concatenated. Otherwise "chunked"
+ profiles become corrupted.
+
+2009-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/average.c (AverageImages): Moved from image.c to new
+ average.c file.
+
+ * magick/colormap.h (VerifyColormapIndex): Moved here from color.h
+
+ * magick/colormap.c (AllocateImageColormap): Moved from image.c to
+ new colormap.c source file.
+ (CycleColormapImage): Moved from image.c.
+ (ReplaceImageColormap): Moved from image.c.
+ (SortColormapByIntensity): Moved from image.c.
+ (MagickConstrainColormapIndex): Moved here from color.c.
+
+ * magick/describe.c (DescribeImage): Moved from image.c to new
+ describe.c source file.
+
+ * magick/plasma.c (PlasmaImage): Moved from image.c to new
+ plasma.c source file.
+
+ * magick/statistics.c (GetImageStatistics): Moved from image.c to
+ new statistics.c source file.
+
+ * magick/gradient.c (GradientImage): Moved from image.c to new
+ gradient.c source file.
+
+ * magick/texture.c (ConstituteTextureImage,TextureImage): Moved to
+ new texture.c source file.
+
+ * coders/svg.c (ENABLE_SVG_WRITER): Disable SVG writer by default
+ since it usually does not work correctly and is unlikely to work
+ correctly any time soon.
+
+2009-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/profile.c (ProfileImage): GlobExpression is case
+ sensitive so assure that its glob strings are always upper-cased.
+ Without this fix, lower-cased arguments like "icm" would fail to
+ be removed. This would not be much of a problem except that the
+ documentation claims that lower-case works.
+ (SetImageProfile): Assure that profile names are upper-cased.
+
+ * magick/fx.c (ColorMatrixImage): Add opaque opacity channel if
+ image currently lacks an opacity channel but the matrix updates
+ the opacity channel. Requested by Kerry Panchoo.
+
+2009-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/meta.c (GetIPTCStream): Updates from John.Sergeant to fix
+ issues with IPTC record 2 blocks and to deal better with IPTC
+ embedded in an 8BIM profile.
+
+ * PerlMagick/t/read.t: Added tests for Topol format.
+
+2009-09-12 Fojtik Jaroslav <JaFojtik@seznam.cz>
+ * coders/topol.c: Pallette overflow fixed for subtype 3.
+
+2009-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/tests/msl_composite.sh: Use a draw command file for
+ this test script too.
+
+ * utilities/tests/{black-threshold.sh,draw.sh,recolor.sh,
+ white-threshold.sh}: MSYS is sometimes wreaking havoc on arguments
+ with spaces in them so use work-arounds.
+
+2009-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (NTGhostscriptFind): Improve logging messages
+ when searching for Ghostscript.
+
+2009-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (CacheInfo): Add read_only member to
+ indicate if cache is allowed to be modified.
+ (ModifyCache): Clone cache if origin cache is read only.
+ (PersistCache): Persistent caches which are attached are treated
+ as read-only. This avoids crash with MPC images which are read
+ and subsequently modified.
+ Reverted pixel cache locking changes which were made yesterday
+ since I decided that they were too risky until file handle
+ management is addressed.
+
+2009-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (InitializeMagickResources): Increase
+ operating system file handle limits if necessary.
+
+ * magick/pixel_cache.c: Pixel cache file locking is now done at
+ point of access.
+
+ * magick/nt_base.c (NTGhostscriptFind): New function to find
+ Ghostscript under Windows, replacing previous Ghostgum
+ implementation.
+
+ * Copyright.txt: License is now based on MIT license exactly,
+ without extra edits. Ghostgum code has been eliminated so it is
+ no longer necessary to include its license.
+
+2009-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/delegate.c (GetPostscriptDelegateInfo): Add a gs-palette
+ delegate entry in order to force Ghostscript to output a
+ colormapped image if `-type palette` is specified prior to the
+ input filename. Ghostscript's dithering is much courser than
+ GraphicsMagick's -colors default (more similar to
+ -ordered-dither), but it is fast and produces smaller intermediate
+ files.
+
+ * coders/ps.c (ReadPSImage): Eliminate use of NULL pointer when
+ progress monitor is enabled. Was referring to image->filename
+ rather than image_info->filename as it should have.
+
+ * magick/delegate.c (InvokePostscriptDelegate): Added an
+ `exception` argument so that failure details can be returned.
+ Tried to reorganize the code so that it is more tolerant of errors
+ such as a dynamically-loadable DLL failing to load. On POSIX
+ systems, Ghostscript was not being invoked as securely as
+ expected.
+
+ * coders/Makefile.am: Only build the DPS module if the Display
+ Postscript library is available.
+
+ * coders/ept.c (ReadEPTImage): If we don`t have the Display
+ Postscript library, then don't try to use it as a fallback.
+
+ * coders/ps.c (ReadPSImage): If we don't have the Display
+ Postscript library, then don't try to use it as a fallback.
+
+ * magick/blob.c (CloseBlob): If blob was never allocated, then
+ don't try to close it.
+
+2009-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/index.rst: Mention 1.2.8 release.
+
+2009-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++: New Image methods cdl(), colorMatrix(), and haldClut()
+ added.
+
+2009-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c (IntegralRotateImage): Select tile sizes in a
+ more intelligent fashion.
+
+ * magick/pixel_cache.c (GetPixelCacheInCore): New private pixel
+ cache method to see if image pixels are in core.
+
+2009-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ReadImage): No longer clear the exception
+ at the start of ReadImage() and other similar functions. If the
+ user of the function cares, she can clear the exception in
+ advance. It is not right to overwrite exceptions which might not
+ have been reported/handled yet.
+
+ * magick/shear.c (IntegralRotateImage): Rotate by zero degrees
+ does not need to do any work.
+
+ * coders/*.c, magick/*.c: Include image dimensions in progress
+ monitor output when loading or saving a file. Eliminate redundant
+ text from progress messages.
+
+2009-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c: Eliminate memory leaks.
+
+ * magick/render.c (DrawDashPolygon): Avoid access beyond end of
+ array. Resolves SourceForge issue 2832125 "Crash on SVG
+ conversion".
+
+ * coders/png.c (ReadOnePNGImage): Ensure that opacity channel is
+ properly initialized. Resolves SourceForge issue 2831240
+ "Possible alpha channel issue with PNG w/palette and tRNS".
+
+2009-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.h (HAVE_TIFFSWABARRAYOFTRIPLES): Need to define
+ this since libtiff includes this function now.
+
+ * VisualMagick/tiff/libtiff/tiffconf.h.in: Enable all the options
+ by default.
+
+ * tiff: Updated to libtiff 3.9.1. 3.9.0 was broken.
+
+2009-08-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/profile.c (MagickFreeCMSTransform): Add a CMS transform
+ destructor since otherwise Visual Studio does not like it.
+
+ * tiff: Updated to libtiff 3.9.0.
+
+2009-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (TimeImageCommand): Add a simple `time`
+ sub-command to time the execution of any other GraphicsMagick
+ sub-command. Similar in concept to the `benchmark` sub-command
+ but produces output similar to the `time` command offered by the
+ zsh command shell. Handy for when `time` is not available, or
+ consistent output is desired.
+
+ * magick/magick.c (MagickGetFileSystemBlockSize): New private
+ function to allow getting desired filesystem block size.
+ (MagickSetFileSystemBlockSize): New private function to allow
+ setting desired filesystem block size.
+
+ * magick/pixel_cache.c (WriteCacheIndexes, WriteCachePixels):
+ Temporarily disable pixel cache row coalescing when writing to
+ disk until we come up with a good way to optimize write sizes.
+
+ * coders/meta.c (ReadMETAImage): Fix memory leak of profile blob.
+
+2009-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/tests/icc-transform.sh: Add a sanity-test for applying
+ ICC profiles.
+
+ * magick/profile.c (ProfileImage): Improve OpenMP performance.
+
+2009-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/render.c (DrawPolygonPrimitive): Drawing of points,
+ lines, and polygons is now accelerated using OpenMP with good
+ speed-up.
+
+2009-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/drawing_wand.c (DrawClearException): New function to clear
+ drawing wand exception.
+ (DrawGetException): New function to retrieve information regarding
+ the last drawing wand exception (if any).
+ (DrawRender): DrawRender() is now deprecated since it requires an
+ Image pointer to be embedded in the drawing wand. The image
+ passed is subsequently lost by CloneDrawingWand() since it must
+ clone the image using copy-on-write. Subsequent use of
+ DrawRender() on a cloned wand scribbles on an image the user does
+ not have access to. Use existing Wand function MagickDrawImage()
+ instead.
+ (DrawAllocateWand): DrawAllocateWand() is now deprecated since it
+ requires passing an Image pointer into the drawing wand. Use
+ existing DrawingWand function NewDrawingWand() instead.
+
+2009-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/drawing_wand.c (CloneDrawingWand): New function to
+ deep-copy a drawing wand.
+ (NewDrawingWand): Use a boolean flag to track if image is
+ allocated by the wand, or by the user. Most of the previous
+ DrawAllocateWand() code is moved into NewDrawingWand() so that the
+ boolean flag is easy to manage.
+
+2009-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Support writing grayscale
+ JPEG-compressed TIFF.
+
+2009-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Don't override the photometric
+ for grayscale JPEG-compressed TIFF.
+
+2009-08-08 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c: Made compatible with libpng-1.4.0beta74 and later
+ (won't work with libpng-1.4.0beta35 through beta73) due to change
+ in names of png_struct members "trans" and "trans_values").
+
+2009-08-08 Fojtik Jaroslav <JaFojtik@seznam.cz>
+ * coders/topol.c: Pallette is ignored for subtype 5 (RGB).
+
+2009-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/{cineon.c, dpx.c, locale.c, svg.c}, magick/{attribute.c,
+ effect.c, utility.c}: Eliminate warnings reported by GCC 4.4.0.
+
+2009-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Try to be more insistent about compilation failure
+ if libjpeg version is less than 6b. IRIX compiler only warns
+ about #error preprocessor statement.
+
+2009-07-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickSetCompressionQuality): New Wand
+ method to allow setting the compression quality.
+
+2009-07-29 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/topol.c: Fixed missing break. Added response to ping.
+
+2009-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pcx.c (ReadPCXImage): Detect improper rows, columns, or
+ depth. Fixes CVE-2008-1097 "Memory corruption in ImageMagick's
+ PCX coder".
+
+ * configure.ac: Update to Autoconf 2.64.
+
+2009-07-25 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/topol.c: Fixed several issues. Added possibility to read
+ TopoL level 2 images.
+
+2009-07-25 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * VisualMagick\configure\configure.cpp: Fixed library absolute path issue.
+
+2009-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/random.c (DestroyMagickRandomGenerator): Trick to free
+ thread specific random kernel contexts simply locks up with MSVC's
+ OpenMP, so remove this functionality.
+
+2009-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/random.c (DestroyMagickRandomGenerator): Cleanup thread
+ specific random kernel data.
+
+ * magick/tsd.c (MagickTsdKeyCreate): Fix glitch when built without
+ any threads support.
+
+2009-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/benchmarks.rst: Update GraphicsMagick vs ImageMagick image
+ processing benchmark results.
+
+2009-07-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/OpenMP.rst: Update performance measurements for readily
+ available systems.
+
+ * NEWS.txt: Updated to reflect latest changes.
+
+2009-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Updated libpng to 1.2.38.
+
+2009-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (GetImageInfo): Default interlace for ImageInfo
+ is now UndefinedInterlace so that it is possible to preserve the
+ original interlace setting for the image file. Code depending on
+ the previous default setting of NoInterlace is adjusted to suit.
+ This is a potentially risky change given the brittle nature of
+ some of the legacy code.
+
+ * coders/tiff.c (ReadTIFFImage): Stripped reader needs to read
+ planar TIFF plane-wise in order to work with libtiff's internal
+ buffering.
+ (ReadTIFFImage): Tiled reader needs to read planar TIFF plane-wise
+ in order to work with libtiff's internal buffering.
+ (WriteTIFFImage): Tiled writer needs to output planar TIFF
+ plane-wise in order to work with libtiff's internal buffering.
+
+2009-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MontageUsage): Reconcile montage help output
+ with actual montage options.
+
+2009-07-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Allow the user to be able to
+ specify rows_per_strip when using JPEG compression. The
+ rows_per_strip value rounded up to the nearest multiple of 16.
+
+2009-07-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Add the ability for the user to
+ manually specify the predictor using syntax like `-define
+ tiff:predictor=2`.
+
+2009-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/quantize.c (QuantizeImages): Avoid crash when using
+ -monitor +map on an image list.
+
+ * magick/command.c (BenchmarkImageCommand): Send benchmark report
+ to stderr so that it does not interfer with pipes.
+
+ * magick/cdl.c (CdlQuantum): Add range limiting of value before
+ applying power function.
+
+ * coders/dpx.c (ReadDPXImage, WriteDPXImage): Using floating point
+ calculations when building sample value lookup tables in order to
+ decrease error. In particular input values were being scaled too
+ low, resulting in improperly rounding down during processing of
+ the image.
+
+2009-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c (WritePDFImage): Incorporated updates from John
+ Sergeant to remove the font and thumbnail objects from PDF output.
+
+2009-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/cdl.c (CdlImage): New function to apply an ASC CDL
+ transform to the image. Original implementation by Clment Follet
+ from Workflowers but considerably re-worked by Bob Friesenhahn.
+ Available as -asc-cdl via the `convert` and `mogrify` subcommands.
+
+2009-07-04 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * www/formats.rst: MAT module can read compressed files.
+ Remove warning about unsupported compression.
+
+2009-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcm.c: Eliminate compiler warnings.
+
+2009-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcm.c: Significant re-write of the DICOM reader. Work
+ contributed by John Sergeant.
+
+2009-07-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (OpenBlob): Subsequent research shows that Direct
+ I/O will not be useful to ordinary file I/O due to specific
+ requirements for buffer alignments and I/O sizes. Support for
+ requesting it is removed.
+
+2009-07-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * www/formats.rst: ART module has writer for more than year.
+ So mark this here.
+
+2009-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac, magick/blob.c: Add experimental Solaris direct I/O
+ support which is enabled by setting the environment variable
+ MAGICK_DIRECTIO to TRUE. Direct I/O bypasses the filesystem
+ cache. Only works for NFS and UFS, and not for ZFS.
+
+2009-06-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * rungm.sh.in: Fix environment variable issues noticed while
+ running the test suite under MinGW.
+
+ * Makefile.am (TESTS_ENVIRONMENT): Fix environment variable issues
+ noticed while running the test suite under MinGW.
+
+ * magick/hclut.c (HaldClutImage): Don't convert Cineon Log to RGB.
+
+2009-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImageCommand): Cache mogrify argument
+ images so that they are only loaded once when mogrify is used to
+ process multiple image files.
+
+ * coders/dpx.c (WriteDPXImage): Fix leak of chroma image when
+ subsampling to 4:2:2.
+
+2009-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (ExpandFilenames): Expand @filename to a list
+ of arguments.
+
+2009-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImageCommand): Fix memory leak of
+ output_directory string buffer, if it was used.
+
+ * magick/utility.c (ExpandFilenames): Input wildcard file
+ specifications with a subdirectory component such as
+ "subdir/*.dpx" were not working.
+
+2009-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (InitializeMagick): Invoke InitializeMagickRegistry().
+
+ * magick/registry.c (RegistryInfo): There is no reason to expose
+ the RegistryInfo structure in the public interface so it is moved
+ to registry.c.
+ (InitializeMagickRegistry): Add a function for initializing the
+ magick registry.
+
+2009-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (CompareImageCommand): Report full error rather
+ than rounded error in error reports since sometimes the value
+ reported was rounded down to zero.
+
+ * utilities/tests/hald-clut-transform.sh: New test to verify that
+ Hald CLUT interpolation is working perfectly.
+
+ * utilities/tests/hald-clut-identity.sh: Renamed from
+ hald-clut.sh.
+
+2009-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (RegisterJPEGImage): Fix typo which caused IJG
+ library version to be shown for "JPG" format but not for "JPEG".
+ Also use a more descriptive name for JPEG library.
+
+ * magick/image.c (DescribeImage): Filter out spurious EXIF
+ attributes which already exist because we previously accessed
+ them. We do a full EXIF dump later.
+
+2009-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/FAQ.rst: Add a FAQ about how to process many files at once.
+
+2009-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Reduce usage of deprecated Autoconf macros.
+
+ * coders/jpeg.c (ReadJPEGImage): Set image orientation from EXIF
+ Orientation tag if it is present.
+
+ * www/formats.rst: Add TopoL format as per Jaroslav Fojtik.
+
+2009-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: User provided LDFLAGS was being overwritten under
+ Solaris.
+ * Many files: Additional reduction of shadowing warnings.
+
+2009-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): Fix leak of the entire mask
+ image supplied via -mask.
+
+ * utilities/tests/mask.sh: Add a test for applying a mask image
+ with -mask.
+
+2009-06-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (GenerateEXIFAttribute): Identify unknown
+ tags via their four-character hex value.
+
+ * magick/colorspace.c (CMYKToRGBTransform): Use symbolic notation
+ to access pixel quantum values.
+
+ * utilities/tests/identify.sh: Added a test for `identify
+ -verbose` on a well-populated JPEG file.
+
+ * PerlMagick/t/{jpeg/write.t, jng/read.t, jng/write.t}: Relax
+ allowed error for JPEG-related tests.
+
+ * magick/attribute.c (GenerateEXIFAttribute): Attribute allocation
+ size was too small causing overrun of memory buffer. Problem was
+ added on 2009-06-08.
+
+ * magick/image.c (AllocateDepthMap): Allocation size was one
+ element too small.
+ (GetImageDepth): Forgot to free depth map. Memory leak of 64K
+ bytes per iteration.
+
+2009-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/{mat.c, miff.c, pdf.c, ps3.c}: Have Zlib use our memory
+ allocators.
+
+ * magick/memory.c (MagickMallocCleared): New memory allocation
+ interface which is similar to MagickMalloc() except that returned
+ memory has been cleared first.
+
+ * magick/hclut.c (HaldClutImagePixels): Fix wrong accesses
+ detected by valgrind. Also improve execution performance.
+
+ * coders/xwd.c (WriteXWDImage): Fixed valgrind memcheck complaint
+ about access to uninitialized data.
+
+2009-06-09 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c Handle alpha channel for ImageMagick's alternative .txt
+
+2009-06-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteDPXImage): Fixed valgrind memcheck complaint
+ about access to uninitialized data.
+
+ * magick/attribute.c (GenerateEXIFAttribute): For EXIF STRING,
+ output unprintable characters using three-digit octal notation.
+
+ * coders/dpx.c (WriteDPXImage): Assure that offset count is
+ correct according to reported bytes written.
+
+ * utilities/tests/hald-clut.sh: Add a simple identity test for the
+ Hald CLUT support.
+
+2009-06-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c Handle alpha channel for ImageMagick's .txt
+
+2009-06-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/hclut.c (HaldClutImage): Add a Hald CLUT capability as
+ described at http://www.quelsolaar.com/technology/clut.html. This
+ allows a color transformation to be easily created and replicated
+ on any number of images. The algorithm is accessed by the
+ -hald-clut option of `convert` and `mogrify`. The original
+ algorithm is by Eskil Steenberg and was adapted for GraphicsMagick
+ by Clment Follet from Workflowers with support from Cdric
+ Lejeune of Workflowers.
+
+2009-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetMagickGeometry): Support `^` modifier to
+ geometry specification which indicates that specified size is a
+ minimum bounding box rather than a maximum bounding box while
+ preserving the image aspect ratio.
+
+2009-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (ListMagickResourceInfo): If supporting
+ OpenMP, then include a "Threads" limit in the output of `-list
+ resource`.
+
+ * coders/pnm.c (ReadPNMImage): Fix multi-thread issue detected by
+ valgrind's helgrind tool. Diminish compilation warnings.
+
+ * coders/dpx.c (ReadDPXImage): Diminish compilation warnings.
+
+ * magick/random.c (AcquireMagickRandomKernel): Fix potential
+ multi-thread issue detected by valgrind's helgrind tool.
+
+ * magick/magick.c (InitializeMagick): Semaphore subsystem needs to be
+ initialized before anything which uses it.
+
+ * magick/semaphore.c (InitializeSemaphore): Since we are using
+ PTHREAD_MUTEX_INITIALIZER to initialize primary POSIX mutex in the
+ semaphore subsystem, we should not explicitly initialize the
+ semaphore a second time.
+
+ * magick/segment.c (Classify): Fix multi-thread issue detected by
+ valgrind's helgrind tool.
+
+ * magick/render.c (DrawAffineImage): Use InterpolateViewColor() to
+ evalute a bi-linear interpolated point rather than obtaining a
+ pixel value from a close pixel. This provides better results.
+
+2009-06-02 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c Attempt to handle alpha channel.
+
+2009-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (InterpolateViewColor, InterpolateColor):
+ Moved from gem.c. Gem functions should not be accessing the pixel
+ cache.
+
+2009-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (CompareImageCommand): Add a -maximum-error
+ option to `compare` so that it can easily be used in boolean logic
+ when comparing images.
+
+2009-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am (TESTS_XFAIL_TESTS): If Ghostscript is not
+ available then XFAIL the tests which depend on it.
+
+ * magick/pixel_cache.c (GetCacheInfo): Assure that allocated
+ stuctures do not occupy the same cache lines.
+
+2009-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h (MAGICK_CACHE_LINE_SIZE): Allow cache line size
+ to be set in one place in case we want to configure for it later.
+
+ * magick/effect.c (AllocateMedianList): Assure that allocated
+ stuctures do not occupy the same cache lines.
+
+ * magick/random.c (AcquireMagickRandomKernel): Assure that
+ allocated random kernels do not occupy the same cache lines.
+
+ * magick/gem.c (GenerateDifferentialNoise): User is required to
+ supply random kernel.
+
+ * doc/options.imdoc: Document -format "%p". Problem was reported
+ by Stijn Sanders.
+
+2009-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/Makefile.am (coders_tiff_la_LIBADD): Libtiff may now also
+ depend on libjbig and the math library.
+
+ * doc/gmdoc2html: Fix link to ball.png. Problem was reported by
+ Wes Fox.
+
+ * VisualMagick/installer/inc/files-documentation.isx: Include Wand
+ API documentation.
+
+ * VisualMagick/installer/inc/icons-associate.isx: Fix Windows
+ Start menu link to web pages.
+
+ * configure.ac: --with-perl is changed to --without-perl since
+ building PerlMagick is no longer the default. Building PerlMagick
+ automatically has caused too many problems.
+
+ * PerlMagick/Makefile.am: GraphicsMagick no longer automatically
+ installs PerlMagick. Use the procedure described by
+ PerlMagick/README.txt to build and install PerlMagick.
+
+2009-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Debian stores Ghostscript fonts under
+ /usr/share/fonts/type1/gsfonts so check there for fonts. Issue
+ reported by Ralf Wildenhues.
+
+2009-05-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: Fix Ping of blob.
+
+ * PerlMagick/t/ping.t: Added tests for pinging files and blobs.
+
+ * www/perl.rst: Ping blob syntax is like $image->Ping(blob=>@blob).
+
+ * PerlMagick/Makefile.PL.in: Increase the probability of
+ PerlMagick build success by using the user-specified C compiler as
+ the linker if the C compiler was already used as the linker. This
+ helps if the C compiler used to build GraphicsMagick is a more
+ recent vintage than the one used to build Perl.
+
+ * PerlMagick/t/wmf/read.t: Test needs to be more lenient for
+ Linux.
+
+ * Makefile.am (TESTS_ENVIRONMENT): Pass a complete text
+ environment so that we don't need to execute rungm.sh in order to
+ run the test suite.
+
+2009-05-25 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * version.sh: Define PACKAGE_STRING.
+
+2009-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/tempfile.c (ComposeTemporaryFileName): Use new random
+ number generator.
+
+ * magick/random.c: Implement a random number generation system
+ based on George Marsaglia's multiply-with-carry generator.
+ Somewhat slower than rand() but produces better random numbers
+ with a period >2^60. Suggested by Mark Mitchell.
+
+2009-05-24 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c Small optimization:
+
+ Before: 2000 iter 34.08s user 34.24s total 58.420 iter/s
+
+ After: 2000 iter 21.55s user 21.76s total 91.891 iter/s
+
+2009-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (XFAIL_TESTS): Handle the case where FreeType is not
+ available by marking tests dependent on FreeType as XFAIL.
+ (TESTS): Reorder TESTS so that there will be no trailing spaces
+ since this confuses certain older versions of GNU make.
+
+2009-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/tempfile.c (ComposeTemporaryFileName): Use simpler code
+ (suggested by Mark Mitchell) to compute the substitution index.
+ (AcquireTemporaryFileDescriptor): Try harder to generate a
+ successful temporary file and fall through to alternative
+ implementations if the first does not succeed.
+
+ * magick/magick.c (InitializeMagick): Use MagickRandNewSeed() to
+ seed the default random number generator.
+
+ * magick/utility.c (MagickRandNewSeed): Include PID in random
+ number seed generation.
+
+2009-05-22 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c Fixed char vs int parameter problem.
+ Better detection of too dark 16bit or 32bit images.
+
+2009-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Enable parallel-tests and
+ color-tests options. Parallel test execution does not pass tests
+ yet.
+
+ * PerlMagick/PerlMagickCheck.sh.in: Run PerlMagick tests via a
+ normal check script rather than a check hook.
+
+ * coders/identity.c (ReadIdentityImage): Fix compilation with Sun
+ compiler.
+
+2009-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwfile.c: Allow the user to specify the basename for
+ temporary files.
+
+ * tests/Makefile.am: Add a set of TXT read/write tests. Pass the
+ file name specification to use for the rwfile-based tests.
+
+2009-05-21 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c Fixed endian set to native endian.
+
+2009-05-20 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c Faster read ImageMagick files.
+ Removed BImgBuff=NULL;
+
+2009-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/txt.c (WriteTXTImage): Ensure that image depth is 8, 16,
+ or 32.
+
+ * www/formats.rst: Add CALS to formats list.
+
+ * coders/cals.c (RegisterCALSImage): Consolidate duplicate text
+ strings.
+
+2009-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/cals.c: Add support for reading CALS type 1 format.
+ Contributed by John Sergeant.
+
+ * coders/identity.c: New coder to return a Hald identity CLUT
+ image.
+
+2009-05-19 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c Ability to read back Q32 txt files.
+
+2009-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Support Linux style silent build rules.
+
+2009-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Updated to Automake 1.11.
+
+2009-05-17 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c First attempt to read back txt file.
+ It is amazingly ineffective, but it seems to work.
+
+2009-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resize.c (HorizontalFilter, VerticalFilter): When
+ resizing a non-opaque image, attenuate the influence of
+ surrounding colors based on their degree of transparency in order
+ to avoid "halos" around objects caused by colors which are
+ transparent and therefore not part of the visible image. Patch
+ contributed by Pavel Merdin via SourceForge Tracker #2792322.
+ (VerticalFilter, VerticalFilter): Additional clean-up and
+ optimizations.
+
+2009-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): Added a -recolor command option
+ to provide access to ColorMatrixImage().
+
+ * magick/fx.c (ColorMatrixImage): New function to apply a color
+ matrix similar to Adobe Flash Flash.filters.colorMatrixFilter(),
+ and Windows GDI+ ColorMatrix class, (order up to 5x5) to the image
+ pixels.
+
+2009-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/perl.rst: Add missing PerlMagick debug event types.
+
+ * coders/pcl.c: Major improvements from John Sergeant. These
+ include: 1) Fixed 2 bit output where Max=BLACK - this always
+ produced negative images even when -negate was passed as a
+ parameter. The code now uses a two element palette to handle this
+ situation. 2) Added support for 8 bit pseudoclass images. 3)
+ Changed the coder to allow adjoin, placing each sub-image on a new
+ page. 4) Added support for compression. Any compression other
+ than "None" will cause the coder to to try to calculate and pick
+ the best out of the PCL set of RLE, Tiff RLE or delta compression
+ on a per row basis, as well as handling repeated rows and zero
+ rows intelligently.
+
+2009-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * utilities/Makefile.am (MAGICKPROGRAMS): Add a `compare`
+ ImageMagick compatibility link.
+
+ * INSTALL-unix.txt: Apply patch regarding GnuWin32 from John Wye,
+ SourceForge #2779009.
+
+2009-05-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Add the LDFLAGS option -Wl,-zlazyload when using
+ the Solaris linker.
+
+2009-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/url.c (ReadURLImage): Fix typos.
+
+2009-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (SystemCommand): Added access confirmation
+ checks for external commands.
+
+ * magick/unix_port.c (MagickSpawnVP): Added access confirmation
+ checks for external commands.
+
+ * coders/url.c (ReadURLImage): Added access confirmation checks
+ for URLs.
+
+ * magick/blob.c: Added access confirmation checks for files.
+
+ * magick/confirm_access.c (MagickConfirmAccess): Added an access
+ confirmation facility to allow the API user to monitor and/or
+ block access to files and URLs. This allows the API user to
+ implement a security policy based on actual accesses.
+
+2009-05-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Updated libpng to 1.2.35.
+
+ * lcms: Updated lcms to 1.18a.
+
+2009-05-01 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c (WriteOnePNGImage and WriteOneJNGImage): Changed
+ internal attribute png_bit_depth to png:bit-depth-written to avoid
+ confusion with planned new public png:bit-depth attribute.
+
+2009-04-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImages): Deal slightly better with the
+ case when MogrifyImage() expands one image into several. Still
+ don't know of a sane way to deal with -crop WIDTHxHEIGHT.
+
+ * magick/transform.c (TransformImage): Image which is updated may
+ be a list so account for that.
+
+ * configure.ac: Add a test for the `restrict` keyword so that
+ eventually we can use it.
+
+ * coders/jpeg.c (ReadJPEGImage): Tidy JPEG reader by moving JPEG
+ properties analysis code into subroutines.
+
+2009-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/display.imdoc: Fix documentation for crop and chop keyboard
+ accelerators. Fixes SourceForge bug #2593388 "error in the
+ documentation/Keyboard accelarators".
+
+2009-04-20 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c: Cosmetic-only, change `True` to `MagickTrue` or
+ `MagickPass` and `False` to `MagickFalse` or `MagickFail`.
+
+2009-04-20 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c: Check error return from CompressColormapTransFirst()
+
+2009-04-20 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c: Refrain from modifying image struct members
+ (matte, colors, depth) while writing a PNG.
+
+2009-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Document the direction of rotation.
+
+2009-04-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/log.c (LogMagickEventList): Use MagickPackageName from
+ version.h rather than hard-coding `GraphicsMagick`.
+
+2009-04-18 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/jpeg.c: Fixed a warning about `shadowed` variables.
+
+2009-04-17 Glenn Randers-Pehrson <glennrp@simple....>
+
+ * coders/png.c: Fixed some warnings about `shadowed` variables.
+
+2009-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Add tests for some reentrant versions of functions
+ where we are still using the non-rentrant versions.
+
+ * magick/composite.c (CompositeImage): Fix problem with
+ compositing images where the change image overlaps off the left
+ side of the canvas. Should fix SourceForge issue #2766200 `memory
+ allocation error when compositing small images`.
+
+2009-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/semaphore.c: Re-arrange ifdefs so that it is possible to
+ use pthreads under the WIN32 API.
+
+2009-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/bit_stream.c: Bitstream functions were often not inlining
+ and inline functions which don't inline are not much use.
+ Bitstream functions are now normal library functions.
+
+2009-03-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/bin/delegates.mgk: Remove bounding box option (-g) from
+ Postscript delegate specifications.
+
+ * config/delegates.mgk.in: Remove bounding box option (-g) from
+ Postscript delegate specifications.
+
+ * coders/{ept.c, pdf.c, ps.c} : PDF bounding box is sometimes
+ incorrect or not globally applicable so don't specify bounding box
+ when reading PDF files. Postscript files do need the bounding box
+ so make sure that it is still supplied. Resolves SF tracker issue
+ 2487651 `convert from pdf chops off rhs`.
+
+2009-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Magick++/Image.rst: Translate Image.html to reStructuredText
+ format for easier maintenance.
+
+2009-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/rgb.c: Compute the quantum type rather than using a
+ recurring conditional statement. It turns out that the -endian
+ option is working as it should.
+
+2009-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/{gray.c, rgb.c, cymk.c}: Work toward supporting the
+ -endian option. Not working properly yet.
+
+ * magick/enum_strings.c (EndianTypeToString): New function.
+ (InterlaceTypeToString): New function.
+
+2009-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/drawing_wand.c: Stripped out unused code.
+
+ * www/wand: Added formatted Wand API documentation.
+
+ * scripts/format_c_api_doc.py: Now supports --include-rst option.
+
+2009-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (GetImageBoundingBox): If we fail to find a
+ smaller bounding box, then the returned bounding box is the entire
+ image.
+
+2009-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/magick/magick_config.h.in: Provide configuration
+ access to the DisableSlowOpenMP define.
+
+ * PerlMagick/t/read.t: Add a test for HRZ Slow scan TV.
+
+ * magick/pixel_cache.c (ModifyCache): Set image `taint` flag and
+ clear monochrome and grayscale flags when pixels are accessed
+ read/write rather than at sync.
+
+ * coders/Makefile.am (MAGICK_CODER_SRCS): Add coders/hrz.c to
+ build.
+
+2009-01-27 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/hrz.c: New HRZ reader for slow scan TV.
+
+2009-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resize.c (ResizeImage): Make error handling more robust.
+
+ * magick/pixel_cache.c (SetNexus): Return a run-time error to
+ invoking code rather than exiting the program if the pixel staging
+ buffer fails to be allocated.
+
+2009-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Allow the user to force the
+ returned image to be TrueColor type for min-is-white and
+ min-is-black TIFF files. Previous to this, bilevel TIFF files
+ were always returned as PseudoClass.
+
+2009-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c, coders/pnm.c: Fix several race conditions
+ reported by Julian Seward.
+ (OpenCache): Restore conservative pre-allocation of pixel indexes
+ since a glitch was encountered that needs to be resolved.
+
+ * magick/{channel.c,compare.c,constitute.c,decorate.c,effect.c,fx.c,
+ image.c,operator.c,pixel_iterator.c,render.c,resize.c,segment.c,
+ shear.c,transform.c}: Use explicit OpenMP critical sections to
+ avoid possible cross-contention.
+
+ * coders/{dpx.c, pnm.c} Use explicit OpenMP critical sections to
+ avoid possible cross-contention.
+
+2009-01-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (OpenCache): Remove conservative
+ pre-allocation of pixel indexes.
+
+2009-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/index.rst: Reduce the amount of text on the front page.
+
+2009-01-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * GraphicsMagick.spec.in: The module .la files need to be
+ installed as part of the base install or else the modules will
+ fail to load.
+
+2009-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dib.c (ReadDIBImage): Fix assertion thrown for DIB files
+ with negative image height values.
+
+2009-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/bmp.c (ReadBMPImage): Fix assertion thrown for BMP files
+ with negative image height values. Resolves SF issue 2523536 `bug
+ in bmp coder`.
+
+ * Makefile.am: Don't install Magick++ headers if Magick++ is
+ disabled.
+
+ * GraphicsMagick.spec.in: --enable-lzw option is no longer used.
+
+2009-01-17 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c: More robust fits parsing.
+
+2009-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Updated news.
+
+2009-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colorspace.c (XYZTransformPackets): Fix arithmetic
+ overflow problem noticed for Q32 build when using GCC on
+ big-endian systems.
+
+ * magick/constitute.c: Update Richard Nolde's float 16 and 24
+ functions.
+
+ * magick/command.c (VersionCommand): Print some build information
+ for MSVC builds.
+
+2009-01-10 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c: Ability to skip unsupported multidimensional object.
+
+2009-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (GetBlobSize): It seems that under Windows, the
+ zip stream is not usable as a file handle. Switch back to using
+ stat instead, but use _stati64 if available.
+
+2009-01-04 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/fits.c: Fixed bug in scene count in extension block.
+ * coders/fits.c: Supported logging.
+
+2009-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Produce sprintf scaling strings for
+ platform-specific types.
+
+ * magick/magick_types.h.in: Include sprintf scaling strings for
+ platform-specific types.
+
+ * magick/constitute.c (WriteImage): If output stream is not
+ seekable and coder needs to use seek, then divert output to
+ temporary file, and then send file to stream.
+
+ * magick/blob.c (GetBlobSize): Simplify implementation.
+ (OpenBlob): Don't attempt to test header magic on file we are
+ writing. Silly benign bug in obtuse code.
+
+ * coders/tiff.c (ReadTIFFImage,WriteTIFFImage): Strip out use of
+ temporary file. Use TIFFClientOpen() for writing.
+
diff --git a/ChangeLog.2010 b/ChangeLog.2010
new file mode 100644
index 0000000..bba95f2
--- /dev/null
+++ b/ChangeLog.2010
@@ -0,0 +1,668 @@
+2011-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickDescribeImage): Was sending
+ descriptive output to stdout rather than returning it in an
+ allocated string as intended.
+
+2011-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/draw.c, wand/drawing_wand.c (MvgPrintf): Update to handle
+ C99 vsnprintf() return values.
+
+ * magick/draw.c, wand/drawing_wand.c (DrawAnnotation): Linux
+ glibc does not pass extended text characters if "%.1024s"
+ formatting convention is used. Apparently it assumes that such
+ characters may be UTF8 and returns -1 rather than outputting the
+ string, even if it is assured to fit.
+
+2010-12-30 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Matlab file level clarification.
+
+2010-12-27 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mac.c New MacPaint image format reader added.
+
+2010-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Default to using a LZMAPRESET
+ value of 1 based on testing which observed minimal benefit, and
+ substantially more cost, from larger values. Value may be
+ specified by the user using command line syntax like `-define
+ tiff:lzmapreset=7` for purposes of further experimentation. Also
+ adjusted default strip memory values for each preset level.
+
+2010-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: Add LZMA support to PerlMagick.
+
+ * coders/tiff.c (WriteTIFFImage): Add TIFF LZMA compressor support.
+
+2010-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImages): Should send -verbose output to
+ stderr rather than stdout since otherwise usage in pipelines may
+ be broken. Resolves SourceForge issue 3131790 "AVS -verbose
+ prints to stdout".
+
+2010-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtool: Upgrade to libtool 2.4.
+
+ * coders/pnm.c (ReadPNMImage): Start work on reading NetPBM PAM
+ format. Parses PAM header but pixels are not returned yet.
+
+ * magick/magic.c (StaticMagic): Be more specific when identifying
+ PNM subformats. Return the specific subformat name PBM, PGM, or
+ PPM rather than PNM. XV P7 format is now identified as "P7 332".
+ Add detection of NetPBM PAM format.
+
+2010-11-04 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * magick/effect.c: Added 5x5, 6x6, and 7x7 circular ordered dither
+ patterns to create a halftone effect.
+
+2010-09-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Document pcl:fit-to-page define.
+
+ * coders/pcl.c: Fix issue with printing a bi-level image on
+ Konica-Minolta printers. Define pcl:fit-to-page in order for the
+ printer to scale the image to fit the page. Patch by John
+ Sergeant.
+
+2010-09-19 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/png.c: removed an apparently harmless extra invocation
+ of ScaleShortToQuantum() due to cut-and-paste error in the
+ update of 2010-06-02. Also added a line to explicitly set
+ the opacity of the background_color to OpaqueOpacity.
+
+2010-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c (ReadPDFImage): Enable use of PDF crop box via
+ -define pdf:use-cropbox=true. Patch contributed by Chris Gilling.
+ SourceForge patch ID 3063794, "Add support for using crop box for
+ pdf import".
+
+2010-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/Image.cpp (backgroundColor, borderColor, matteColor):
+ Opacity part of user-specified color needs to be preserved.
+ Problem was reported by Alexander Zheltov.
+
+2010-09-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Applied Automake 1.11.1 patch by Ralf Wildenhues
+ which is necessary for the test suite to pass under Windows/MinGW
+ due to command line length limits.
+
+2010-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/draw.c, wand/drawing_wand.c: Pass full user-provided
+ double precision resolution to renderer. Truncating the
+ resolution causes problems in some cases. Resolves SourceForge
+ bug 3058387 "Incorrect Copy Compositing through C interface".
+
+2010-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (StringToList): Fix performance problem caused
+ by using strlcpy.
+
+ * coders/pnm.c (ReadPNMImage): Q8 build should be able to read
+ 16-bit PGM images.
+
+2010-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MontageImageCommand): Fix memory leak of
+ MontageInfo structure allocation in error handling path.
+
+ * magick/montage.c (MontageImages): Fix crash observed with
+ "-geometry x+0+0". Problem reported by Simon Rainer.
+
+2010-08-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Update to Automake 1.11.1.
+
+2010-08-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Use AC_USE_SYSTEM_EXTENSIONS to enable system API
+ extensions.
+
+2010-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (ModifyCache): Fix deadlock in
+ ClonePixelCache() which was caused by using the same semaphore
+ pointer in the source and destination images. Problem was
+ reported by Stefan Schramowski.
+
+2010-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/info.c (WriteINFOImage): Added an `INFO` coder which
+ produces textual image description output similar to `identify`
+ but may be used with convert like "gm convert myfile info:-".
+ Feature suggested by Stefan Schramowski.
+
+2010-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am (TESTS_PS_XFAIL_TESTS): Expect EPT tests to
+ fail if Ghostscript is missing.
+
+ * configure.ac: Updated to Autoconf 2.67.
+
+ * magick/render.c (DrawImage): Use StringToGravityType() to parse
+ gravity values.
+
+2010-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Document histogram-threshold setting.
+
+ * magick/enhance.c (NormalizeImage): Add support for
+ histogram-threshold setting to specify the percentage of the
+ histogram to discard when computing image normalization parameters
+ (default is 0.1%). For example `-set histogram-threshold 0.01
+ -normalize`.
+
+ * www/api/types.rst: Update Image structure member documentation.
+
+2010-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Add a test for posix_spawnp(). Results may be
+ used in later development.
+
+2010-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am (TESTS_PS_XFAIL_TESTS): PDF tests are expected
+ to fail if Ghostscript is not available.
+
+ * magick/utility.c (MagickStrlCat, MagickStrlCpy): Add handling
+ for the case where size is zero in order to be conformant with the
+ strlcat() and strlcpy() formal descriptions. GraphicsMagick does
+ its best to never pass a size of zero so an assertion that size is
+ not zero remains in order to help catch bugs in GraphicsMagick.
+ Issue was reported by Albert Cahalan.
+
+2010-07-10 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/png.c: Always scale tRNS color to 16-bit short. Otherwise,
+ transparency was sometimes lost while reading PNG files whose depth
+ is different from the Quantum depth.
+
+2010-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (LOG_TIFF_BLOB_IO): Define LOG_TIFF_BLOB_IO=1 when
+ building GraphicsMagick in order to enable verbose logging from
+ the TIFFClientOpen() registered callbacks when `coder` logging is
+ enabled.
+
+2010-06-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwfile.c: Deal with formats which don't have an extension
+ by prepending the magic specifier to the file name specification.
+
+ * coders/mpr.c (RegisterMPRImage): MPR and MPRI are not useful
+ file extensions.
+
+ * magick/command.c (CommandAccessMonitor): If the environment
+ variable MAGICK_ACCESS_MONITOR is set to TRUE then also log
+ invocations of the access monitor callback when -monitor is
+ specified. This feature is intended to assist with understanding
+ when the access monitor is invoked, and the arguments which are
+ passed.
+
+ * magick/blob.c (OpenBlob): Throw an exception on error rather
+ than depending on the invoking code to do so. Resolves
+ SourceForge bug #3023437 "Magick::Image::ping() does not throw
+ exception in all cases".
+
+2010-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): The -colors, -map, and
+ -monochrome options now take effect immediately rather than at the
+ end of all other processing. This is is more intuitive and
+ reasonable but may impact the output of scripts which place these
+ options prior to additional image processing operations.
+
+2010-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (BlobToImage): If a temporary file must be used
+ and the user has specified magic, then preserve the magic
+ specifier when reading the temporary file.
+
+ * coders/mat.c (RegisterMATImage): More accurately describe MATLAB
+ format support as "MATLAB Level 5".
+
+ * magick/magic.c (StaticMagic): Automatically detect MATLAB Level
+ 5 format based on file header.
+
+ * PerlMagick/PerlMagickCheck.sh.in: Run PerlMagick tests in
+ verbose mode so that all test output appears in "test-suite.log"
+ if there is a failure.
+
+ * coders/Makefile.am (coders_mat_la_LIBADD): MAT coder is
+ optionally dependent on zlib so zlib should be listed as a
+ dependency.
+
+ * magick/blob.c (BlobToFile): MAGICK_IO_FSYNC=TRUE in the
+ environment should cause file data to be explicitly synchronized
+ prior to close.
+
+2010-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/files-documentation.isx: There are
+ not currently any JPEG files in the www/images directory to
+ distribute.
+
+2010-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ltdl/config/ltmain.sh: Update libtool to 2.2.10.
+
+ * magick/profile.c: Support lcms 2.0.
+
+ * configure.ac: Add support for configuring for lcms 2.0,
+ controlled via a new --without-lcms2 option. By default lcms v2
+ is used if it is available, otherwise v1.1X is used if it is
+ available.
+
+2010-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ltdl/config/ltmain.sh: Update libtool to 2.2.8.
+
+2010-06-02 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/png.c correctly scale bKGD chunk data in Q16 build
+
+2010-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Magick++/Image.rst: Fix documentation error which wrongly
+ recommended multiplication by size of PixelPacket. Correction by
+ Roel Baardman.
+
+2010-05-23 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/txt.c (ReadTXTImage): Ability to read multiple images.
+
+2010-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (DispatchImage): `K` channel was always
+ output as black for "CMYK" specification unless image matte flag
+ was True. Bug report and proposed solution by Lance Brown.
+
+2010-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c (ShearImage): When one of the shear angles was
+ specified as zero, the shear request was ignored entirely. An
+ simple optimization was using || rather than && to test the
+ angles. Resolves SourceForge issue #2991685 "Shear command does
+ not handle zero angles correctly".
+
+2010-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (InitializeMagick, DestroyMagick):
+ InitializeMagick and DestroyMagick should be fully thread safe.
+
+2010-05-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/gif.c (ReadGIFImage): Set the opacity value of the opaque
+ color to transparent. Patch by Tim Baker.
+
+ * magick/image.c (SetImageColor): New function which is similar to
+ SetImage() but which accepts the pixel color as a parameter rather
+ than using the image background color. Patch by Tim Baker.
+
+ * magick/transform.c (CoalesceImages): When applying background
+ disposal, fill the image with the transparent color, if one
+ exists. Patch by Tim Baker. Resolves SourceForge patch ID
+ 2989472.
+
+2010-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/txt.c (ReadTXTImage): Matte channel was not being enabled
+ for non-opaque images.
+ (ReadTXTImage): Opacity values need to be inverted prior to
+ ingestion.
+
+2010-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Documentation for -flatten and -mosaic has
+ been improved.
+
+ * magick/transform.c (MosaicImages): The -mosaic command now
+ respects the composition option specified by -compose as well as
+ the image background color specified by -background.
+
+2010-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/*.c, magick/*.c: Eliminate many benign data race
+ conditions.
+
+2010-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * GraphicsMagick.spec.in: Avoid duplicate copies of documentation
+ files. Put documentation into a versioned directory as used by
+ Red Hat and CentOS. Include archive libraries in developer
+ package.
+
+ * PerlMagick/Makefile.PL.in: Include support for DESTDIR so that
+ RPM builds find the installed GraphicsMagick library.
+
+2010-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Under Solaris, make sure that OpenWindows Type1
+ fonts do exist before deciding to use them. OpenSolaris does not
+ provide these fonts.
+
+2010-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * GraphicsMagick.spec.in: Fix RPM build. PerlMagick was not being
+ built due to Makefile changes. Resolves SourceForge issue
+ #2952696 "RPM build broken: (Perl) file not found by glob".
+
+ * magick/quantize.c (ReduceImageColors): Progress message should
+ include the image file name.
+
+2010-03-24 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * Revised coders/jpeg.c to preserve the Exif profile.
+
+2010-03-24 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/png.c (ReadOnePNGImage): Eliminated some of the deprecated
+ direct access to ping_info->members.
+ Eliminated support of very old libpng versions (1.0.11 and earlier).
+
+2010-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/delegate.c (GetPostscriptDelegateInfo): Add support for
+ invoking "gs-cmyk" and "gs-cmyka" entries in delegates.mgk when
+ ColorSeparationType or ColorSeparationMatteType is requested.
+ Requisite entries in delegates.mgk are left for the user to add.
+
+2010-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (InitializeMagick): Don't initialize locale
+ settings in InitializeMagick(). Resolves SourceForge bug #2967282
+ "setlocale called by GraphicsMagick".
+
+2010-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/{command.c, display.c}: Make sure that `animate`,
+ `display`, and `identify` report any error only once, and then
+ proceed to the next file name rather than quitting. Problem was
+ reported by Patrick Welche.
+
+2010-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Released GraphicsMagick 1.3.12.
+
+2010-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Makefile.am: Update PerlMagick/Magick.pm in the
+ source tree (as required) since it is distributed source and
+ contains the current version number.
+
+2010-03-03 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/png.c: restored missing "US" in PNG_USER_CHUNK_CACHE_MAX
+ at line 102. Added some (unsigned long) typecasts on print statements
+ to stifle warnings.
+
+2010-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Updated libpng to 1.2.43. Resolves CVE-2010-0205 as
+ pertains to GraphicsMagick Windows build.
+
+2010-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwfile_DCX_*.sh: Add tests for reading and writing DCX.
+
+ * coders/pcx.c (WritePCXImage): DCX is not the same as PCX so only
+ write DCX when requested to (and vice-versa).
+
+ * utilities/tests/convert-pipe-out.sh: New test to verify that
+ `convert` can write to stdout.
+
+ * utilities/tests/convert-pipe-in.sh: New test to verify that
+ `convert` can read from stdin.
+
+ * utilities/tests/convert-pipe-filter.sh: New test to verify that
+ `convert` works properly as a filter.
+
+ * magick/image.c (SetImageInfo): The `rectify` parameter was found
+ to not be sufficient to meet requirements since it was
+ overloaded. The utilities would malfunction (hang or throw an
+ exception) if requested to write to stdout. As a result, this
+ parameter has been changed to a binary flag type parameter.
+ Existing True/False values are mapped to equivalents using the new
+ binary flag. This is intended to resolve Debian bug 571719
+ "graphicsmagick: "convert" command is broken", reported by
+ Vladimir Stavrinov.
+
+2010-02-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Released GraphicsMagick 1.3.11.
+
+2010-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c (GetCompositionPixelIteratorCallback):
+ OverCompositeOp and AtopCompositeOp may be replaced with
+ CopyCompositeOp in the case where neither image has a matte
+ channel.
+
+ * magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+ Added -extent option to apply a background color canvas behind the
+ image. Added -compose option to allow specifying the composition
+ operator to use.
+
+ * magick/transform.c (ExtentImage): New function apply a
+ background color canvas behind the image.
+
+2010-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Added a -thumbnail command to all of the GM
+ sub-commands which currently support -resize. This is a resize
+ method optimized for speed when reducing the size of the image
+ (such as when creating thumbnails).
+
+2010-02-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (LocaleCompare, LocaleNCompare): Fix array
+ index underflow which occurs if the char type is signed and the
+ character value is in the extended range. Problem reported by
+ Arseny Solokha. Resolves SourceForge patch #2953314.
+
+2010-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Released GraphicsMagick 1.3.10.
+
+2010-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/demo/demo.cpp (main): Split demo output frames into
+ individual files to enable easier viewing.
+
+2010-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/GraphicsMagick.imdoc: Improve usage synopsis for
+ `convert`. SourceForge feature request 2845965 "confusing
+ documentation".
+
+ * magick/display.c (MagickXDisplayImage): Image number was
+ incorrect in window title.
+
+ * magick/render.c (DrawImage): Path points data allocation was
+ much larger than it needed to be. Patch by Vladimir Lukianov.
+ Resolves SourceForge issue 2947851 "Memory allocation error on
+ vector graphics (or mem bomb)".
+
+ * magick/constitute.c (WriteImages): +adjoin was not working
+ correctly for the case when only one image frame is present. With
+ +adjoin and writing one frame to "foo%d.jpg" it was outputting
+ "foo%d.jpg" rather than "foo0.jpg". Problem reported by Frans
+ Coetzee.
+
+2010-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Released GraphicsMagick 1.3.9.
+
+2010-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/imdoc2man: Bare single quotes at the beginning of a line
+ need to be escaped in order to make roff happy. Problem reported
+ by Daniel Kobras.
+
+ * magick/command.c (ImportImageCommand): Don't assign a pointer to
+ static constant data into an array which uses heap allocated data.
+ Avoids a "double free" error when using gm import -frame. Patch
+ by Daniel Kobras.
+
+ * magick/color_lookup.c (QueryColorname): XPM does not support
+ RGBA color syntax, but it does support RGB. Patch by Daniel
+ Kobras.
+
+ * magick/blob.c (OpenBlob): Only form multi-part filename when
+ required.
+
+ * magick/display.c (MagickXDisplayImage): The display `-update`
+ option was only working in conjunction with the `-delay` option
+ with a delay setting of 2 or greater. Problem reported by Sami
+ Liedes. Patch by Vincent MAUGE. Resolves Debian bug ID 414779.
+
+2010-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (OpenBlob): Only apply scene substitution to
+ the filename if adjoin is false.
+
+ * magick/constitute.c (WriteImage): If adjoin is true, then
+ restore original filename specification since opening the blob
+ modifies it. Resolves Debian bug ID 552998.
+
+ * magick/image.c (SetImageInfo): Don't check filename for scene
+ substitution if adjoin is intentionally false. This allows saving
+ to file names which look like they contain a scene substitution
+ pattern.
+
+ * magick/command.c (MogrifyImage): Convolution failure results in
+ a crash rather than an error report. Resolves Debian bug ID
+ 539251.
+
+ * magick/deprecate.c: The string constants LoadImageText,
+ SaveImageText, LoadImagesText, and SaveImagesText should have been
+ deprecated, rather than being entirely removed.
+
+2010-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Makefile.am (install-data-html): Make sure that only the
+ necessary documentation files are installed.
+
+2010-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/body.isx: Strip out executable
+ components which depend on proprietary MFC and ATL libraries.
+ This means that "gmdisplay.exe" and "ImageMagickObject" are no
+ longer distributed or installed via the Windows setup installer.
+ When a new display application is developed based on open source
+ libraries, then the display functionality and associations can be
+ restored.
+
+2010-01-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/transform.c (FlattenImages): Apply the image background
+ color under the initial canvas image if it is non-opaque.
+
+ * magick/composite.c (MagickCompositeImageUnderColor): New private
+ function to apply a color underneath a non-opaque image.
+
+2010-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/prefetch.h: New header to provide wrapper macros for
+ compiler-specific explicit prefetch APIs.
+
+ * magick/effect.c (BlurImageScanlines): Solid color images which
+ only differed in the matte channel were not being blurred.
+
+ * magick/color.h (NotPixelMatch,PixelMatch): New macros to
+ fully-compare a pixel, including matte.
+
+ * magick/resource.c (SetMagickResourceLimit): Invoke
+ omp_set_num_threads() to set thread limit if ThreadsResource is
+ requested.
+
+ * magick/pixel_cache.c (AllocateThreadViewSet): The number of
+ cache views to allocate needs to be obtained from
+ omp_get_max_threads(). Otherwise there is a crash if the number
+ of threads is reduced from the original value.
+
+2010-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Released GraphicsMagick 1.3.8.
+
+ * NEWS.txt: Update for the 1.3.8 release.
+
+2010-01-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/benchmarks.rst: Update benchmark report to compare
+ performance with ImageMagick 6.5.8-10.
+
+2010-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c (RotateImage, ShearImage): Ensure that errors
+ propagate up to the API user. Don't overwrite a detailed
+ exception message with a generic one. Don't return a bogus image
+ if there is an error.
+
+2010-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/files-base.isx: Third party
+ executables not included in the Visual Studio build are no longer
+ bundled in the GraphicsMagick installer. This means that
+ hp2xx.exe, mpeg2dec.exe, and mpeg2enc.exe are no longer
+ distributed.
+
+ * www/Magick++/Image.rst: Emphasize that InitializeMagick() MUST
+ be invoked, and make sure that all of the examples show use of it.
+
+2010-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/delegate.c (InvokeDelegate): Use MagickSpawnVP() under
+ Windows as well.
+ (InvokePostscriptDelegate): Use MagickSpawnVP() under Windows as
+ well.
+
+ * magick/utility.c (MagickSpawnVP): Moved from unix_port.c.
+ Updated implementation to use spawnvp() rather than fork()/exec()
+ under Windows.
+
+ * configure.ac: Add check for Windows spawnvp function.
+ Add check for process.h.
+
+ * magick/semaphore.c (DestroySemaphore): POSIX mutex statically
+ initialized via PTHREAD_MUTEX_INITIALIZER should not be destroyed.
+
+ * configure.ac: DisableSlowOpenMP is now the default. Use
+ --enable-openmp-slow to enable OpenMP for algorithms which
+ sometimes run slower rather than faster.
+
+2010-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/version.h.in: Added MagickLibInterfaceNewest and
+ MagickLibInterfaceOldest preprocessor defines so that applications
+ may easily test for library versions while compiling.
+
+2010-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/render.c (DrawPolygonPrimitive): Use restrict keyword.
+
+ * magick/pixel_iterator.c: Use restrict keyword.
+
+ * utilities/Makefile.am: Modules are supported in the shared
+ library built so list-module.sh test should be expected to pass.
+
+ * configure.ac: Add WITH_SHARED_LIBS conditional.
+
+2010-01-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/version.h.in: Update copyright years.
+
+ * magick/semaphore.c: The return code from all pthread mutex APIs
+ are now checked (not just initialize and destroy), and any error
+ results in an immediate fatal exit.
diff --git a/ChangeLog.2011 b/ChangeLog.2011
new file mode 100644
index 0000000..b8d2adf
--- /dev/null
+++ b/ChangeLog.2011
@@ -0,0 +1,607 @@
+2011-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (AcquireCacheNexus):
+ MirrorVirtualPixelMethod was broken.
+
+2011-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Improve configuration support for Open64 Compiler
+ Suite: Version 4.2.5.2 compiler with OpenMP.
+
+ * coders/tga.c (ReadTGAImage): Assume that 32-bit TGA files have
+ an alpha channel, even if they are not marked as such. Fixes
+ SourceForge issue 3466908 "TGA with alpha".
+
+ * configure.ac: Revert changeset eaa27346d8e9 which tried to avoid
+ the OpenMP library being included multiple times because in some
+ cases it is not included at all.
+
+2011-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (VersionCommand): For MSVC builds, report if
+ SSE or SSE2 was used in the build.
+
+ * Release GraphicsMagick 1.3.13.
+
+ * Update libtiff to release 4.0.0
+
+2011-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update libpng to release 1.5.7
+
+2011-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update lcms2 to release 2.3
+
+2011-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Update Automake used to 1.11.2.
+
+2011-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/OpenMP.rst: Updated with new results, including 12-core
+ Intel Xeon E5649 and 16-core AMD Opteron 6220 "Bulldozer" CPUs.
+
+ * magick/studio.h: Enable building and running correctly with
+ Open64 Compiler Suite: Version 4.2.5.2 compiler with OpenMP.
+
+ * magick/command.c (BenchmarkImageCommand): Add -rawcsv option to
+ benchmark to output only original data in a CSV format.
+
+2011-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Fix various issues noticed when cross-compiling for the
+ i686-w64-mingw32 target.
+
+2011-12-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ConvolveImage): For Q8 and Q16 builds use
+ 'float' rather than 'double' for computations in order to improve
+ performance with some compilers.
+
+2011-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ConvolveImage): Special-case grayscale images
+ for better convolution performance.
+
+2011-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (BenchmarkUsage): -stepthreads now requires an
+ argument which is the increment (starting at zero) to the number
+ of threads for each step. This hastens benchmarking with a large
+ number of cores.
+
+2011-12-07 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/png.c: Eliminate use of FARDATA. It's no longer needed
+ and will no longer be supplied by png.h in libpng-1.6.0.
+
+2011-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (BenchmarkImageCommand): Added Karp-Flatt
+ metric to benchmark output.
+
+2011-12-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * GraphicsMagick.spec.in: Eliminate use of deprecated BuildPrereq
+ in RPM spec file.
+
+2011-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (WriteImagesFile): Should set file in
+ ImageInfo based on provided parameter rather than relying on it
+ already being set. File argument was not being used.
+
+2011-11-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c: For packed 10 bits, datums are now represented in
+ the same (reversed) order for all RGB and YCbCr formats.
+ Previously YCbCr 4:4:4 formats were not swapping the word datums
+ because the only real-world files encountered did not swap the
+ word datums. Resolves SourceForge bug 2057277 "DPX 10bit CbYCr
+ Image seems to be wrong".
+
+ * wand/magick_wand.c (MagickWriteImagesFile): New function to
+ append images to a provided file handle. Resolves SourceForge
+ issue 3046868 "added MagickWriteImagesFile".
+
+ * magick/constitute.c (WriteImagesFile): New function to append
+ images to a provided file handle.
+
+ * magick/blob.c (OpenBlob): Don't rewind already open file handle
+ passed to OpenBlob() since we don't know the intended state of
+ this file handle, and because it prevents appending to an existing
+ file. This change is part of the fix for SourceForge issue
+ 3046868 "added MagickWriteImagesFile".
+
+ * wand/magick_wand.c (MagickSetImageSavedType): New function to
+ allow specifying the storage type used when saving the file
+ (rather than changing the current image characteristics).
+ Resolves SourceForge patch 3110185
+ "MagickGetImageSavedType()/MagickSetImageSavedType() API".
+ (MagickGetImageSavedType): Return the storage type which will be
+ used when the image is saved.
+
+ * magick/annotate.c (RenderFreetype): Add support for drawing text
+ using a bitmap font. Resolves SourceForge patch 3230719 "add
+ support for drawing text with bitmap font to annotate.c".
+
+ * magick/profile.c (AppendImageProfile): Don't leak profile buffer
+ while appending a chunk to an existing profile. Resolves
+ SourceForge patch 3294496 "Fix a memory leak in
+ profile.c(AppendImageProfile)".
+
+2011-11-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (BenchmarkImageCommand): Include the number of
+ threads used in the benchmark results output.
+ (BenchmarkImageCommand): New benchmark option -stepthreads to
+ execute the specified command with an increasing number of threads
+ to measure how an algorithm benefits from threading.
+ (BenchmarkImageCommand): Fix benchmark argument parsing so it is
+ not order dependent.
+ (BenchmarkImageCommand): Add a speedup indication to -stepthreads
+ output.
+
+ * config/delegates.mgk.in: File names in gnuplot files need to be
+ surrounded by double quotes or gnuplot parser will reject them.
+
+2011-11-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (GetMedianList): Return PixelPacket via pointer
+ rather than by value.
+
+ * version.sh: For snapshots packages, PACKAGE_CHANGE_DATE now uses
+ a form like "snapshot-20111121" rather than "unreleased" so it is
+ possible to determine the vintage of an installed snapshot.
+
+2011-11-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tga.c (ReadTGAImage): Fix for poor TGA reading
+ performance due to excessive use of GetBlobByte(). Performance is
+ fixed by adding local buffering. Fixes SourceForge bug 3439531
+ "Slow TGA reading".
+
+2011-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (AdaptiveThresholdImage): More performance
+ improvements.
+
+2011-11-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/analyze.c (GetImageBoundingBox): Add a special case to
+ handle absolute color comparison.
+
+2011-11-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Update libpng to 1.5.6 release.
+
+2011-10-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Avoid linker warnings when building GraphicsMagick
+ regarding OpenMP library being included multiple times.
+
+2011-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/meta.c (GetIPTCStream): Eliminate possible use of
+ uninitialized data when parsing long format tag length.
+
+2011-10-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/import.c: Move low-level pixel import functions from
+ constitute.c to new file import.c.
+
+ * magick/export.c: Move low-level pixel export functions from
+ constitute.c to new file export.c.
+
+ * magick/floats.c: Move Richard Nolde's floating point conversion
+ functions from constitute.c to new file floats.c.
+
+2011-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtool: Updated to libtool 2.4.2.
+
+ * configure.ac: Automake conditional for HasPNG can not itself be
+ conditional. Indent PNG script code appropriately.
+
+2011-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Distribute lzma-compressed
+ tarball in 'xz' format rather than deprecated 'lzma' format.
+
+2011-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Fix syntax error with GSCMYKDevice ('==' rather
+ than '='). Thanks to Glenn Randers-Pehrson for noticing and
+ reporting the issue.
+
+2011-10-12 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * Use a "for" loop in configure.ac to find libpngNN.
+
+2011-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/pixel_wand.c (NewPixelWand): Invoke InitializeMagick()
+ automatically in case user forgets to do so.
+
+ * wand/drawing_wand.c (NewDrawingWand): Invoke InitializeMagick()
+ automatically in case user forgets to do so.
+
+ * wand/magick_wand.c (NewMagickWand): Invoke InitializeMagick()
+ automatically in case user forgets to do so.
+
+ * png: libpng sources were updated to release 1.5.4.
+
+2011-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): TIFFGetField() on
+ TIFFTAG_OPIIMAGEID was causing a crash due to an argument
+ mis-match between GraphicsMagick and libtiff. Also fixed a few
+ GCC 4.6 warnings. Problem was reported by Dylan Millikin.
+
+2011-10-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickSetDepth): New function to set the
+ depth used when reading from an image format which requires that
+ the depth be specified in advance.
+ (MagickReadImageBlob): Use BlobToImage() to read the blob.
+
+ * magick/effect.c (AdaptiveThresholdImage): Reduce or eliminate
+ expensive floating point calculations when possible.
+
+ * wand/magick_wand.c (MagickSetFormat): New Wand function to allow
+ setting the file or blob format before it has been read.
+
+2011-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/installer/inc/tasks-install-perlmagick.isx: Windows
+ setup installer now installs PerlMagick built against ActiveState
+ Perl v5.12.4 build 1205.
+
+ * magick/annotate.c (RenderFreetype): Eliminate spurious "out of
+ memory" exceptions due to empty text string.
+
+2011-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/module.c (ModuleAliases): PAM format is handled by PNM
+ coder.
+
+ * jpeg: Record that jpeg sources were updated to release v8c.
+
+ * lcms: Record that lcms sources were updated to release 2.2.
+
+ * png: Record that png sources were updated to release 1.5.4.
+
+ * tiff: Record that tiff sources were updated to release 4.0.0beta7.
+
+ * xml: Record that libxml2 sources were updated to release 2.7.8.
+
+ * zlib: Record that zlib sources were updated to release 1.2.5.
+
+ * VisualMagick/installer/inc/body.isx: Set MagickConfigDirectory
+ for DLL build so that .mgk files are put in application top
+ directory. This makes installation layout between static and DLL
+ builds more similar.
+
+2011-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/list.c (AppendImageToList): Documentation for
+ AppendImageToList() was wrong. Problem was reported by Brad
+ Harder.
+
+2011-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/display.c (MagickXMagickCommand): Display 'save' and
+ 'print' should display useful error details. Problem was reported
+ by Brad Harder.
+
+2011-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/semaphore.c (AllocateSemaphoreInfo): Enable pthread mutex
+ error checking if MAGICK_DEBUG is defined when the code is
+ compiled. This mode helps validate that mutexes are used
+ correctly. No longer enable recursive mutexes since the
+ GraphicsMagick logic should be able to operate without this
+ assistance.
+
+2011-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcm.c (DCM_ReadOffsetTable): Fix wrong cast noticed when
+ compiling with LLVM.
+
+2011-08-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/enhance.c (LevelImageChannel): Fix documented prototype.
+ Problem was reported by Brad Harder.
+
+2011-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (AcquireOneCacheViewPixelInlined): Only use
+ image colormap if the image storage class is PseudoClass.
+ Eliminates a core dump when the image is in CMYK space.
+
+2011-07-20 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/png.c: account for changed typecast of png_get_iCCP
+ argument in libpng15
+
+2011-07-20 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * configure.ac: look for libpng15, libpng14, libpng12, and libpng
+ in that order.
+
+2011-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Update to libpng 1.5.4.
+
+2011-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/docutils-articles.css: Style sheet syntax fixes. Patch by
+ Mark Mitchell.
+
+ * scripts/html_fragments.py: Use proper quoting in banner search
+ HTML. Patch by Mark Mitchell.
+
+2011-06-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageType): Fix documentation for enumeration
+ names. The types need "Type" as part of the name. Problem was
+ reported by Brad Harder.
+
+2011-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * scripts/html_fragments.py (banner_template): HTML banner
+ improvements to go along with style-sheet changes.
+
+ * www/docutils-articles.css: Style-sheet improvements by Mark
+ Mitchell to work better on small screens.
+
+2011-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/project.rst: Add a page for links to pages about the
+ project. The intention is to use this page to reduce the clutter
+ in the banner.
+
+2011-05-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Document tiff:group-three-options define.
+ * coders/tiff.c (WriteTIFFImage): Add support for a
+ tiff:group-three-options define to allow power-users to set the
+ value of the GROUP3OPTIONS tag.
+
+2011-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Makefile.am: Include Hg.*, remove CVS.*.
+
+ * scripts/html_fragments.py (nav_template): CVS tab changed to
+ Source, which links to Hg.html.
+
+ * www/Hg.rst: Document Hg repository access.
+
+2011-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * scripts/rst2htmldeco.py (docutils_opts): Do not include a
+ datestamp of any kind since it unnecessarily churns the
+ repository, particularly if the output file did not otherwise
+ change.
+
+ * INSTALL-unix.txt: Fix typo in description of --without-lzma.
+
+2011-05-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (ReadJPEGImage): Treat exceptions thrown by
+ jpeg_finish_decompress() as warnings rather than errors.
+ (JPEGErrorHandler): Handle JPEG errors directly rather than
+ passing them to a message formatting routine for handling. Also
+ added useful logging.
+ (JPEGMessageHandler): Only handle JPEG traces and warnings. Also
+ added useful logging.
+
+2011-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (EmitMessage): Treat an unhandled EXP marker as a
+ warning rather than a hard error. Resolves SourceForge issue
+ 3297995 "Unsupported marker type 0xdf".
+
+2011-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (AppendImages): If the input list only contains
+ one image, then return a new handle to the one image in the list
+ rather than reporting an exception. Problem was reported by Ravil
+ Rakhimgulov ("Hunter1972").
+
+2011-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageColorRegion): New function to set the
+ constant pixel color for a specified region of the image.
+ (AppendImages): Only color background pixels when needed.
+
+2011-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Added TIFF writer support for
+ JBIG1 compression. Not proven to work yet.
+
+ * magick/image.h (CompressionType): Added Group3Compression as an
+ alias for already existing FaxCompression. Added
+ JPEG2000Compression, JBIG1Compression, and JBIG2Compression for
+ future use.
+
+2011-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: For MinGW32 use 64-bit value formatting
+ conventions which will work with any version of the WIN32 CRT.
+
+2011-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (WriteJPEGImage): Properly handle errors reported
+ by the JPEG library when writing. Up to now, JPEG library simply
+ invoked exit(), which crashed or hung if driven by Magick++ API.
+ Fixes SourceForge bug 3106947 "Assertion failure when saving an
+ "invalid" image as JPEG".
+
+ * magick/module.c (ModuleAliases): Delete "XTRNBSTR"-entry. Fix by
+ Stefan Graff.
+
+ * contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp
+ (Perform): Member "Perform" - out-commented SafeArrayAccessData
+ and following SafeArrayUnaccessData. Fix by Stefan Graff.
+
+ * contrib/win32/ATL/ImageMagickObject/MagickImage.cpp: Delete
+ "XTRNSTREAM"-branch because "XTRNSTREAM" doesn't exist
+ anymore. Fix by Stefan Graff.
+
+ * coders/xtrn.c: In function "WriteXTRNImage" there is no branch
+ for XTRNARRAY. Fix by Stefan Graff.
+
+ * PerlMagick/Magick.xs: AdaptiveThreshold offset argument was
+ being parsed into an 'unsigned long' rather than 'double' as it
+ should have been. This resulted in inability to handle negative
+ offsets. Fixes SourceForge bug 3288735 "PerlMagick issue with
+ AdaptiveThreshold".
+
+ * coders/jpeg.c (ReadIPTCProfile): JPEG may deliver IPTC profile
+ in chunks but code was only allowing one chunk, even though it was
+ otherwise prepared to concatenate chunks. Fixes SourceForge bug
+ 2978422 "Clipping paths in JPG images are truncated".
+
+ * magick/utility.c (GetToken): Fix case where parser may run off
+ end of string. Also add asserts to check for passing null
+ pointer.
+
+2011-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/channel.c (ChannelImage): Report an error if the
+ requested channel is not compatible with the image colorspace.
+ Only deals with CMYK/RGB conflicts. Resolves SourceForge issue
+ 3283046 "Bug in CMYK".
+
+2011-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/txt.c (ReadTXTImage): Throw error if attempt to read
+ empty file.
+
+ * coders/{fits.c,mac.c,miff.c,pcd.c,pict.c,ps3.c,rla.c,txt.c}:
+ Format requires seekable stream.
+
+ * coders/pnm.c (WritePNMImage): Implement writer for PAM format.
+
+ * coders/ept.c (WriteEPTImage): Fix error handling for case when
+ TIFF writer fails.
+
+ * magick/constitute.c (ReadImage): Use of GetBlobStatus() to
+ evaluate image reader success is bogus.
+ (MagickGetQuantumSamplesPerPixel): New private method to return
+ the number of samples returned per pixel for a given quantum type.
+
+2011-03-14 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/png.c (WriteOnePNGImage(): Fixed a rounding error in
+ writing the pHYs chunk (it was truncating instead of rounding).
+
+2011-02-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (MagickPanicSignalHandler,MagickSignalHandler):
+ Don't invoke DestroyMagick() since there may be OpenMP worker
+ threads still running which are using data which would be
+ deallocated. Instead we invoke PurgeTemporaryFiles() to remove
+ any existing temporary files. Valgrind will report leaks if the
+ program is terminated by a signal but this causes no actual harm.
+ Resolves SourceForge issue 3165456 "^C causes semaphore failure in
+ MacOSX".
+ (MagickPanicSignalHandler): Invoke abort() in panic signal handler
+ so that we will reliably get a core dump.
+
+ * magick/tempfile.c (PurgeTemporaryFiles): New private function to
+ remove any existing temporary files but without destroying
+ temporary file semaphore.
+
+2011-02-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c (ReadPNMImage): Fix mis-placed break in PAM header
+ parser.
+
+ * wand/magick_wand.c (MagickWriteImageBlob): Improve the
+ documentation to mention the related use of MagickSetImageFormat()
+ and MagickResetIterator().
+
+2011-02-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/xwindow.c (MagickXBestFont): Check for a few more common
+ font names, and ensure to always check for "fixed" as a final
+ fallback.
+
+2011-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * config/delegates.mgk.in: Added gs-cmyk entry. Used if '-type
+ ColorSeparation' is specified on the command-line prior to the PDF
+ or Postscript file name. This entry specifies use of the
+ Ghostscript PAM driver which is capable of supporting CMYK output.
+ This may be useful if it is desired to apply CMYK color profiles
+ to the image returned from the PDF. As fair warning, it seems
+ that Ghostscript 8.62 outputs CMYK even if the PDF was in RGB
+ space if the PAM driver is used.
+
+ * coders/pnm.c (ReadPNMImage): Add support for reading netpbm's
+ PAM format.
+
+2011-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwblob.c, tests/rwfile.c: Fixes to help tests work when
+ testing with multiple frames.
+
+ * coders/sgi.c: SGI format is not documented to support multiple
+ frames. Remove the half-baked extension for it.
+
+2011-02-01 Glenn Randers-Pehrson <glennrp@simple...>
+
+ * coders/bmp.c (ReadBMPImage): Changed file_size greater than
+ expected from a corrupt-image error to a debug log entry.
+ File_size too small is still an error, and made that so also for
+ BI_RGB images which were previously exempted from the test.
+
+2011-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwblob.c, tests/rwfile.c: Validate the data in each image
+ frame, validate that each read returns the same number of frames,
+ and validate that the correct number of frames was ultimately
+ returned.
+
+ * magick/blob.c (SyncBlob): Disable bogus code which attempted to
+ replicate the blob I/O object across all images in the list when
+ the blob is synced. Leave a less bogus bit of code in place (but
+ commented out) in case such functionality is deemed to actually be
+ needed in the future. The previous code was copying structs on
+ top of each other, including a pointer member to a semaphore.
+
+2011-01-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Changes.rst: Add a new Changes page to wrap up the yearly
+ change logs to lessen download size.
+
+ * scripts/changelog2rst.sh: Simple utility to format ChangeLog
+ format into something resembling reStructuredText.
+
+ * www/Makefile.am: Use reStructuredText to format the ChangeLog
+ files to HTML so that we can inherit the improved formatting and
+ page style.
+
+ * coders/pnm.c (ReadPNMImage): Support for multi-frame PNM was
+ botched due to on-going edits to support PAM format.
+
+2011-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickDescribeImage): Was sending
+ descriptive output to stdout rather than returning it in an
+ allocated string as intended.
+
+2011-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/draw.c, wand/drawing_wand.c (MvgPrintf): Update to handle
+ C99 vsnprintf() return values.
+
+ * magick/draw.c, wand/drawing_wand.c (DrawAnnotation): Linux
+ glibc does not pass extended text characters if "%.1024s"
+ formatting convention is used. Apparently it assumes that such
+ characters may be UTF8 and returns -1 rather than outputting the
+ string, even if it is assured to fit.
+
diff --git a/ChangeLog.2012 b/ChangeLog.2012
new file mode 100644
index 0000000..794133e
--- /dev/null
+++ b/ChangeLog.2012
@@ -0,0 +1,868 @@
+2012-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Added -auto-orient to 'convert' and 'mogrify'
+ to automatically rotate the image upright for viewing based on its
+ current orientation setting.
+ Added -orient to support setting the image orientation.
+
+ * magick/shear.c (AutoOrientImage): New function to automatically
+ orient the image so that it is upright for normal viewing.
+
+2012-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * scripts/tap-functions.shi: Tidy TAP tests so that they may be
+ run alone, or via Perl's 'prove'.
+
+2012-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwfile.c (main): Test file name generation was not
+ correct.
+
+2012-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwfile.tap: Added -stdio tests for most file formats.
+ This tests I/O using an already-opened file handle passed via the
+ ImageInfo file member. Formats using the Ghostscript delegate are
+ not working right yet.
+
+2012-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwfile.c (main): Added a '-stdio' option to test
+ reading/writing files using file handles opened by the API user.
+
+ * magick/blob.c (CloseBlob): It should be possible to invoke
+ CloseBlob() multiple times, including blobs set to "exempt".
+ There were some issues when passing in file descriptors.
+
+2012-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/api/api.rst: Add another example Core C API example program.
+
+ * magick/blob.c (OpenBlob): Restore file position, rather than
+ rewind, after reading header bytes.
+
+ * magick/image.c (SetImageInfo): Restore file position after
+ reading header bytes. Resolves SourceForge issue 3597486
+ "ReadImage not working with file descriptors".
+
+2012-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick: WIN64 (64-bit Windows) installer improvements to
+ bring up to par with 32-bit installer.
+
+2012-12-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick: WIN64 (64-bit Windows) is supported now.
+
+2012-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c: Eliminate support for experimental
+ MAGICK_MMAP_WRITE, which never quite worked correctly and did not
+ provide performance benefits.
+
+2012-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (FileToBlob): Rewrite to be based on stdio.
+
+2012-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick_types.h.in: Changes to try to work better with the
+ Windows WIN64 API.
+
+2012-12-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageColorRegion): The provided color should
+ be in the same colorspace as the image. The image is no longer
+ converted to RGB with the expectation that the provided color is
+ always some particular RGB.
+ (AppendImages): No longer transform the canvas image to RGB. Now
+ append uses the first listed image to determine the colorspace
+ which should be used when appending the additional images and of
+ the output image. The additional images are converted to the
+ canvas image colorspace. Likewise, the background color is
+ assumed to be in the same colorspace as the first listed image so
+ that it is compatible and can be used to fill the background color
+ without translation.
+
+2012-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * rungm.sh.in: Remove extraneous space in first line which
+ prevents execution with T-shell (tsch). Reported by William
+ Langdon.
+
+2012-11-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/wand/wand.rst: Add a simple example of using the Wand API.
+
+2012-11-21 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * coders/bmp.c (ReadBMPImage): Fixed an old bug with decoding
+ chromaticity primaries.
+
+2012-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.h ("C"): Need to include wand/wand_symbols.h
+ after magick/api.h in order for options from magick_config.h to
+ take effect.
+
+ * magick/symbols.h (PSPageGeometry): Fix typo. Should map to
+ GmPSPageGeometry.
+
+2012-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/wand_symbols.h, magick/symbol.h: MagickWand API is now
+ prefixed with 'Gm' when the --enable-symbol-prefix configure
+ option is supplied. These changes are contributed by Ben Wu.
+ Details of changes are as follows:
+
+ 1. A new header file wand/wand_symbols.h which prefixes all
+ MagickWand API symbols with Gm.
+ 2. Modification to all the header files in wand/ to include
+ wand_symbols.h.
+ 3. Modification to magick/symbols.h to include additional
+ symbols which were colliding with names in ImageMagick.
+ 4. Modification to magick/error.c to exclude function
+ definitions for MagickError, MagickFatalError,
+ MagickWarning, and ThrowException when building with
+ --enable-symbol-prefix option. There four names were also
+ defined as macros so it appears that putting them in a
+ symbol-remapping file wont work.
+
+ * Makefile.am: Update Automake to 1.12.5.
+
+2012-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/COPYING: Change Magick++ usage license to be exactly
+ the MIT license without the additional sentence about retention of
+ copyright (which was already legally implicit).
+
+2012-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/symbols.h: Re-generate list of symbols to prefix.
+
+ * magick/utility.c (IsGlob): IsGlob can be more efficient.
+
+ * magick/floats.c: Use compile-time selection of endian-specific
+ code rather than run-time. Fix cast warning with 64-bit builds.
+
+2012-11-07 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * coders/png.c (WriteOnePNGImage): The wrong QuantumType was
+ sometimes passed to ExportImagePixelArea() by the PNG encoder.
+
+ * coders/png.c (ReadOnePNGImage): Let libpng unpack all sub-8-bit
+ pixels (see change of 2012-08-31 which lets libpng unpack sub-8-bit
+ palette images; this also lets libpng unpack the grayscale images).
+
+ * coders/png.c (ReadOnePNGImage): Corrected the reading of interlaced
+ images (see SourceForge bug 3420695, in which all passes are
+ displayed in a garbled manner instead of only the completed image).
+
+2012-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickGetImagePage): Need to use 'image'
+ rather than 'images' in order to work with iterator.
+ (MagickSetImagePage): Need to use 'image'
+ rather than 'images' in order to work with iterator.
+
+2012-10-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (TranslateTextEx): Fix bug with input string
+ read overrun if the input string ends with a single '%'. This
+ sometimes caused random heap data to be added to the output string
+ until another null character is reached. A simple work-around
+ without this fix is to use "%%" rather than "%". Fixes
+ SourceForge bug 3580219 "strange results with '%' in Annotate()".
+
+2012-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickSetImagePage): New method to support
+ setting the image page size and offsets.
+ (MagickGetImagePage): New method to support getting image page
+ size and offsets.
+
+2012-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Report fatal error if doing modules build and
+ libltdl is not found.
+
+2012-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ltdl: Libltdl is no longer bundled. Libltdl must be previously
+ installed on the system in order to build the modules
+ configuration.
+
+2012-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/index.rst: Update top index page for 1.3.17 release.
+
+ * NEWS.txt: Update NEWS for 1.3.17 release.
+
+ * version.sh: Update shared library versioning for 1.3.17 release.
+
+ * coders/jnx.c: Fix format string compilation warnings. Remove
+ MS-DOS line terminations.
+
+ * configure.ac: Module loading is now only supported by the
+ modules build and not just because shared libraries are enabled.
+ This means that libltdl is only depended upon by the modules
+ build. Sometime in the future, libltdl will no longer be bundled
+ in the GraphicsMagick source tree.
+
+2012-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac (LTDL_INIT): Request installable libltdl rather
+ than convenience.
+
+2012-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/bmp.c: Support alpha channel in uncompressed 32-bit BMP.
+ Resolves SourceForge issue 3566239 "Can't open BMP with alpha
+ created by photoshop".
+
+2012-10-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * dcraw/dcraw.c: Fixed situation when M_PI is not defined.
+
+2012-10-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/jnx.c: Add image attribute with geolocation.
+
+2012-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * dcraw: VisualMagick configure fixes to support linking with JPEG
+ and JPEG2000.
+
+2012-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * dcraw: Add dcraw to VisualMagick build.
+
+ * libxml: Update libxml2 to 2.9.0 release.
+
+2012-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tiff: Update libtiff to 4.0.3 release.
+
+ * lcms: Update liblcms2 to 2.4 release.
+
+ * png: Update libpng to 1.5.13 release.
+
+2012-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am: Update to Automake 1.12.4.
+
+2012-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Fix Debian bug 687738 "graphicsmagick:
+ repeated words suitable for suitable for in gm manpage" reported
+ by Jonas Smedegaard.
+
+2012-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Update with news since last release.
+
+ * configure.ac: Added the configure option
+ --enable-quantum-library-names to enable that shared library name
+ includes quantum depth to allow shared libraries with different
+ quantum depths to co-exist in same directory (only one can be used
+ for development).
+
+2012-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (AdaptiveThresholdImage): New implementation
+ contributed by Roberto de Deus Barbosa Murta. Executes in linear
+ time as threhold area is increased rather than being quadratic.
+
+2012-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/svg.c: Fix improper injection of XML headers as rendered
+ text.
+
+ * magick/render.c (DrawImage): Fix SourceForge issue 3499164
+ "Drawing of text fails if text starts with "," character". Fix
+ SourceForge issue 3411492 "Certain SVGs hang GraphicsMagick". Fix
+ SourceForge issue 1961000 "Could not print ',' via convert draw
+ text".
+
+2012-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c (lite_font_stringwidth): Simply return zero.
+ Returning a computed string width was causing text placement
+ problems when testing with libwmf's fulltest.wmf.
+
+2012-08-31 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * coders/png.c: ReadOnePNGImage: sub-8-bit palette images were
+ getting unpacked twice; once by libpng via png_set_packing()
+ and again by coders/png.c in a switch() statement around line 2500,
+ resulting in horizontally stretched pixels.
+
+2012-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Include lzip as a distribution
+ format again.
+
+2012-08-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: BrowseDelegate now defaults to 'xdg-open', but if
+ it is not found, then configure will search for firefox,
+ google-chrome, mozilla (in that order).
+
+2012-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: For testing on MinGW, assume that Postscript is
+ available since we don't have a good way to check for that.
+
+ * scripts/tap-functions.shi (test_count): Always execute the test
+ program rather than skipping execution since we want to make sure
+ the test program fails correctly as well.
+
+ * coders/gif.c (DecodeImage): Add a log message for attempted LZW
+ string data table overflow.
+
+2012-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (ConvolveImage): Allocate normalized convolution
+ kernel using cache-line aligned memory allocator.
+
+ * configure.ac: Remove support for legacy LZWDecodeDelegate and
+ LZWEncodeDelegate since these are not used any more.
+
+2012-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * scripts/tap-functions.shi: If a test declares that it needs
+ certain features, skip the test if required features are not
+ available.
+
+ * configure.ac: Build a supported features list and save to
+ common.shi script for use by test scripts.
+
+ * Makefile.am (LOG_COMPILER): Run Bourne-shell based TAP scripts
+ with the same shell $(SHELL) that configure selected for the
+ Makefile to use.
+
+2012-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Update to Automake 1.12.3.
+ Update test suite to use Automake TAP driver rather than legacy
+ tests.
+
+2012-08-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jnx.c (ExtractTileJPG): Add a trace of tile offset and size.
+
+2012-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jnx.c (ExtractTileJPG): Use a memory buffer for the JPEG
+ tile rather than a temporary file.
+
+2012-08-12 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * PerlMagick/t/input_jnx.jnx: Small JNX test file.
+
+2012-08-11 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/jnx.c: speedup.
+
+2012-08-10 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/jnx.c: changed malloc/free to MagickMalloc/MagickFree.
+
+2012-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jnx.c (ReadJNXImage): Add progress monitor support for
+ JNX.
+
+2012-08-06 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/jnx.c: Image cache is turned off to work-around memory
+ overflow.
+
+2012-08-05 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/jnx.c: Fixed.
+
+2012-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jnx.c: Add JNX coder for "Garmin proprietary Image
+ Format" (implementation by Jaroslav Fojtik) to the build. Code is
+ not yet working properly at this time.
+
+2012-08-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Remove use of -Wl,-zlazyload under Solaris since
+ it seems to decrease the stability of C++ exceptions in x86-64
+ build and does not measurably improve runtimes. Don't force use
+ of liblzma because libtiff is used. User should always have
+ control.
+
+2012-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/memory.c (MagickMallocAligned): Use RoundUpToAlignment()
+ macro to compute aligned pointer.
+
+ * magick/effect.c (EnhanceImage): Eliminate use of ugly Enhance
+ macro. Only filter based on color channels (ignore opacity).
+
+2012-07-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h (MAGICK_CACHE_LINE_SIZE): Assume a cache line
+ size of 64 bytes except for on PowerPC which uses 128.
+
+ * magick/pixel_cache.c: Use aligned memory allocator to allocate
+ structures and buffers which might suffer from false cache line
+ sharing
+
+ * magick/memory.c (MagickMallocAligned): Also round up allocation
+ size to alignment.
+
+2012-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c, magick/random.c, magick/semaphore.c: Use
+ aligned memory allocator to align allocations which should be
+ aligned to cache line boundary.
+
+2012-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/memory.h (MagickAllocateAlignedMemory): New macro to
+ allocate aligned memory.
+ (MagickFreeAlignedMemory): New macro to free aligned memory.
+
+ * magick/memory.c (MagickMallocAligned): New internal function to
+ allocate aligned memory.
+ (MagickFreeAligned): New internal function to free aligned memory.
+
+2012-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/common.h (MAGICK_ASSUME_ALIGNED): Add some GCC attribute
+ wrappers for useful features added by GCC 4.7.
+
+2012-07-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/gif.c (ReadGIFImage): Try to be better about reporting
+ failure when ReadBlob() fails to return the requested number of
+ bytes.
+
+2012-06-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/benchmarks.rst: Strip the outdated benchmark results from
+ the benchmarks page.
+
+ * magick/command.c (ImportImageCommand): Status returned from the
+ command was inverted.
+
+2012-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Release GraphicsMagick 1.3.16
+
+2012-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): -units was adjusting existing
+ resolution the wrong way around.
+
+2012-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * jpeg: Updated to IJG 8d release.
+
+ * libxml: Updated libxml to 2.8.0 release.
+
+ * zlib: Updated zlib to 1.2.7 release.
+
+ * magick/blob.c (MagickFileHandle): Refer to stdio, bzip2, and
+ gzip file handles using their own type. Eliminates warnings
+ observed when compiling with zlib 1.2.7.
+
+ * tiff: Updated libtiff to 4.0.2 release.
+
+ * png: Updated libpng to 1.5.11 release.
+
+2012-06-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Fix typo which caused the --without-lzma option to
+ be handled incorrectly. Resolves SourceForge issue 3535309
+ "graphicsmagick from 1.3.13 to 1.3.15 has broken lzma support".
+
+2012-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwfile.c (main): Verify that we can 'ping' the file using
+ PingImage(). Tests for some formats may take longer to complete.
+
+ * tests/rwblob.c (main): Verify that we can 'ping' the blob using
+ PingBlob(). Tests for some formats may take longer to complete.
+
+ * coders/xbm.c (ReadXBMImage): Fix memory leak of temporary X
+ bitmap image allocation encountered when reading in 'ping' mode.
+
+ * magick/blob.c (PingBlob): Re-write to be based on BlobToImage()
+ so that it works reliably.
+ (BlobToImage): Restore original input file name to image if
+ temporary file was used so that image 'filename' and
+ 'magick_filename' do not contain unexpected content due to using a
+ temporary file.
+
+2012-06-07 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * coders/png.c: Disable new libpng-1.5.10 test for invalid palette
+ index when reading a PNG or MNG (for speed), or when writing a MNG
+ (because a zero-length PLTE is valid in a MNG).
+
+2012-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (SetImageAttribute): Don't translate
+ 'comment' and 'label' attributes if the request is made while a
+ file is being read. This is a temporary workaround until there is
+ opportunity to modify the architecture so that there is a clear
+ split between user-provided settings and values obtained from the
+ input image.
+
+ * magick/blob.c (GetBlobIsOpen): New function to return if blob is
+ currently open.
+
+2012-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/typemap: Add typemap file needed by Perl 5.16.
+ Resolves SourceForge issue 3531512 "PerlMagick does not build with
+ perl 5.16".
+
+2012-05-29 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * coders/png.c: Ignore APNG chunks even if we are using a libpng
+ that was built with the "APNG patch".
+
+2012-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ConvertImageCommand): +repage does not require
+ an argument. Resolves SourceForge issue 3529158 "+repage option
+ not respected with convert command".
+
+ * configure: Update to Autoconf 2.69.
+
+ * magick/effect.c (MotionBlurImage): Motion blur does scale so
+ remove DisableSlowOpenMP for it.
+
+ * magick/command.c (BenchmarkImageCommand): Remove parenthesis
+ from output, and change "iter/sec cpu" to "iter/cpu" to ease
+ parsing.
+
+ * magick/pixel_cache.c (GetPixelCacheInCore): Consider read-only
+ memory-mapped cache as being "in-core". Otherwise MPC input files
+ are penalized.
+
+2012-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/api.h: Include <sys/types.h> on POSIX systems in order to
+ help assure that 'size_t' and 'ssize_t' are declared.
+
+2012-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick_config_api.h.in: Need to provide definitions for
+ 'size_t' and 'ssize_t' in case the system headers lack these types
+ because the definition of MagickExtentImage() requires them. This
+ should resolve PHP bug #62034 "gmagick does not compile".
+
+2012-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_iterator.c (GetRegionThreads): Don't thread region
+ if it is not memory-based.
+
+2012-05-09 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * coders/png.c (ReadOnePNGImage): make transparent_color elements
+ unsigned long instead of unsigned short, so 65537 is actually out of
+ range as expected, and won't match any pixel if no tRNS chunk is
+ present.
+
+2012-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/sfw.c (ReadSFWImage): Reader needs to be more robust
+ against corrupt or maligned headers. Resolves SourceForge issue
+ "sfw file crash".
+
+2012-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdf.c (WritePDFImage): Add file basename as the PDF
+ document title. Resolves SourceForge bug ID 2835140
+ "GraphicsMagick fails to add title attribute to PDF output".
+
+ * coders/sfw.c (ReadSFWImage): Restore original filename and
+ format.
+
+ * PerlMagick/t/jpeg/read.t: Add a test for reading Seattle
+ FilmWorks format based on the sample image from
+ http://www.algonet.se/~cyren/sfw/. Image was approved for
+ distribution in GraphicsMagick by Bengt Cyrn.
+
+ * magick/analyze.c (GetImageBoundingBox): Only apply opacity-based
+ bounding box detection if all three test points are non-opaque and
+ the same value. Resolves SourceForge bug ID 3522804 "convert
+ -trim fails on 8-bit PNG that ImageMagick can trim".
+
+ * coders/sfw.c (ReadSFWImage): Fix variety of bugs related to
+ closing Image and blob at wrong points. SFW reader is working
+ again. Resolves SourceForge bug ID 523430 "sfw file open failed".
+
+2012-05-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Animated movies inside 4D matrices are loaded now.
+
+2012-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_iterator.c: Limit the number of threads to use in
+ the loop rather than the total number of threads available.
+
+2012-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Release GraphicsMagick 1.3.15
+
+2012-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageInfo): Remove automatic adjoin mode
+ support logic.
+ (AddDefinition): Fix use of uninitialized variable.
+
+2012-04-23 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * doc/*.imdoc: some example commandlines in the documentation
+ were missing the leading "gm ".
+
+2012-04-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (FormMultiPartFilename): No longer add a
+ printf-style scene formatting specification to filenames which do
+ not have one and no longer automatically operate in 'adjoin' mode
+ in such cases. This is a BIG CHANGE for users who may have become
+ used to this automatic functionality. The simple solution to
+ update existing scripts depending on this behavior is to change
+ any bare filenames to include a format specification similar to
+ "image-%d.jpg" and add +adjoin to the command line. The reason
+ why this change is made is that the output files produced by any
+ given operation were unpredictable, and it was causing temporary
+ files to be leaked due to the renaming.
+
+2012-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/bmp.c (WriteBMPImage): Enforce that image width and
+ height do not exceed BMP dimensions. BMP dimensions are
+ represented by a signed type. BMPv2 supports maximum dimensions
+ of 32k by 32k.
+
+2012-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/info.c (WriteINFOImage): When driven by the 'convert'
+ utility, -format produces user-controlled formatted output similar
+ to -format in 'identify'. This is accomplished via a
+ 'info:format=value' define.
+
+ * magick/image.c (AddDefinition): New function for adding just one
+ define to definitions list.
+
+2012-04-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c (ReadPNMImage): Completely disable OpenMP in reader
+ because there is too much contention.
+
+ * magick/pixel_iterator.c: Dereference image to be modified in
+ non-threaded context in order to lessen contention.
+
+ * magick/semaphore.c (AllocateSemaphoreInfo): Make sure that
+ SemaphoreInfo does not share cache lines with another semaphore.
+
+2012-04-11 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * coders/png.c: fixed problem with bit depth when the encoder
+ decides to write RGBA instead of indexed PNG, by delaying the
+ call to png_set_tRNS() until after calling png_set_IHDR().
+
+2012-03-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Update bundled libpng to 1.5.10 release. Provides security
+ fix for CVE-2011-3048.
+
+ * wand/magick_compat.c (ParseGeometry): Use strlcpy() rather than
+ strncpy().
+ (CopyMagickString): Depend on strlcpy() because we provide it if
+ it is missing.
+ (ConcatenateMagickString): Depend on strlcat().
+
+ * coders/xcf.c (ReadXCFImage): Now respects image subimage and
+ subrange members so that returned image layers may be selected.
+ Based on patch from SourceForge issue 3513025 "XCF reads all
+ layers all the time".
+
+ * magick/resize.c (ThumbnailImage): Thumbnail default filter is
+ intended to be the box filter, but allow the user to override the
+ filter used. Resolves SourceForge issue 3513239 "-filter command
+ line argument ignored".
+
+2012-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+ Added support for '+noise random' and '-operator noise-random' to
+ 'convert' and 'mogrify'.
+
+ * magick/effect.c (AddNoiseImage): Added support for RandomNoise.
+ (AddNoiseImageChannel): Added support for RandomNoise.
+
+ * magick/enum_strings.c (StringToNoiseType): New function to
+ convert a string to a NoiseType enumeration value.
+ (NoiseTypeToString): New function to convert a NoiseType
+ enumeration value into a string.
+
+ * PerlMagick/Magick.xs: Added support for RandomNoise.
+
+ * magick/operator.c (QuantumOperatorRegionImage): Added support for
+ RandomNoise.
+
+ * magick/effect.c (AddNoiseImageChannel): Added support for
+ RandomNoise.
+
+ * magick/gem.c (GenerateDifferentialNoise): Added support for
+ RandomNoise.
+
+ * magick/random.h (MagickRandomRealInlined): The span of
+ MagickRandomRealInlined() is now slightly more accurate.
+
+ * magick/image.h (enum NoiseType): New enumeration value RandomNoise.
+
+2012-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): Add support for -repage option
+ to composite, convert, mogrify, and montage subcommands. Resets
+ or adjusts the current image page offsets based on a provided
+ geometry specification.
+
+ * magick/image.c (ResetImagePage): Add a function to adjust the
+ current image page canvas and position based on a relative page
+ specification.
+
+2012-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (MogrifyImage): Add support for -strip option
+ to composite, convert, mogrify, and montage subcommands. Removes
+ all profiles and text attributes from the image.
+
+ * magick/image.c (StripImage): New function to remove all profiles
+ and text attributes from the image.
+
+2012-02-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Release GraphicsMagick 1.3.14.
+
+ * NEWS.txt: Updated to describe updates since last release.
+
+2012-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Downgrade to Automake 1.11.2 so that test suite can run on
+ systems with limited command line length. This means that lzip
+ support is temporarily removed.
+
+ * magick/resize.c (ResizeImage): Resize filter argument was being
+ ignored. Filter from image 'filter' member was used instead.
+ Problem was reported by Steven Bakhtiari.
+
+2012-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tiff: Update bundled libtiff to 4.0.1 release.
+
+ * png: Update bundled libpng to 1.5.9 release.
+
+ * magick/memory.h: Decorate memory allocation functions with GCC
+ attribute 'alloc_size'.
+
+ * magick/common.h: Add support for GCC 4.3+ attributes
+ 'alloc_size', 'hot', 'cold'.
+
+ * magick/{log.h,monitor.h,utility.h}: Use double-underscore syntax
+ in GCC format attribute specifications to defend against
+ accidental macro expansion.
+
+2012-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xcf.c (ReadXCFImage): Fix reading XCF which is comprised
+ of different sized layers.
+
+2012-02-08 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ * coders/txt.c: Added "-define txt:with-im-header" option.
+
+2012-02-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Updated to libpng 1.5.8 release
+
+ * zlib: Updated to zlib 1.2.6 release
+
+2012-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Update to Automake 1.11.3. Add
+ lzip compressed archive to options.
+
+2012-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcraw.c (RegisterDCRAWImage): Add support for Mamiya
+ Photo RAW "MEF" format. Resolves SourceForge issue #3481508
+ "*.MEF file open incorrect".
+
+2012-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c (WriteJPEGImage): Convert RGB-compatible
+ colorspaces (e.g. CineonLog) to RGB by default since that was the
+ case prior to release 1.3.13. User can still override it
+ (avoiding removal of log encoding) by explicitly specifying the
+ desired colorspace. Problem was reported by Gary Margiotta.
+
+2012-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): When reading, save input file
+ endianness so that the endianness of the original file is
+ preserved by default. The user is able to override this default
+ via -endian. Problem was reported by JongAm Park.
+
+2012-01-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/OpenMP.rst: Updated OpenMP results based on latest OpenMP
+ tunings and the Intel Xeon E5649 CPU.
+
+2012-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcraw.c (ReadDCRAWImage): Fix memory leak of ImageInfo.
+ Resolves SourceForge bug #3475148 "memery leaks".
+
+ * magick/module.c (ModuleAliases): EMF format is supported by EMF
+ module and so mapping EMF to the WMF module caused EMF not to
+ work. Resolves SourceForge bug #3475147 "emf files can not be
+ opened". Note that the EMF module only works for Microsoft
+ Windows.
+
+2012-01-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/gem.c (Hull): Improve performance.
+
+ * magick/effect.c (DespeckleImage): Improve performance.
+
+2012-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/effect.c (DespeckleImage): Using schedule(static,4)
+ blocks any opportunity for speedup. This was a performance
+ regression. Oops!
+
+2012-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickExtentImage): Added
+ MagickExtentImage() to Wand API. Resolves SourceForge issue
+ #3471915 "MagickExtentImage in the Wand C API".
+
+2012-01-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/export.c (ExportViewPixelArea): Break up implementation
+ into subroutines to ease compilation.
+
+2012-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/import.c (ImportViewPixelArea): Break up implementation
+ into subroutines to ease compilation.
+
+2012-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h: Use Magick prefixed macro names for ftruncate,
+ mmap, and munmap in order to assure that introducing our macros
+ does not cause trouble with system headers.
diff --git a/ChangeLog.2013 b/ChangeLog.2013
new file mode 100644
index 0000000..ac1d344
--- /dev/null
+++ b/ChangeLog.2013
@@ -0,0 +1,530 @@
+2013-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh: Update for 1.3.19 release.
+
+ * www/index.rst: Update for 1.3.19 release.
+
+ * NEWS.txt: Update for 1.3.19 release.
+
+ * magick/blob.c (GetBlobTemporary): Add assertions to assure that
+ image and blob are valid structures.
+
+ * coders/png.c (ReadOnePNGImage): Fix problem peculiar to Q8 build
+ with reading 1-bit PNG files.
+
+ * PerlMagick/t/png/(write-16.t, read.t, write-16.t, write.t):
+ Update expected signatures
+
+ * coders/xpm.c (WriteXPMImage): Limit XPM color resolution to what
+ XPM can traditionally handle.
+
+ * magick/enhance.c (GammaImage): Eliminate a compiler warning.
+
+ * coders/png.c (ReadOnePNGImage): Eliminate a compiler warning.
+
+ * coders/pcl.c (WritePCLImage): Eliminate a compiler warning.
+
+2013-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/delegate.c (InvokePostscriptDelegate): Log return status.
+
+ * magick/nt_base.c (NTGhostscriptFonts): For Microsoft Windows,
+ also search c:\gs\fonts for Ghostscript font files.
+
+ * coders/ept.c (ReadEPTImage): Fix crash observed when Ghostscript
+ fails to produce output.
+
+2013-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/annotate.c: Simplify FreeType2 header inclusion.
+
+ * configure.ac: Only test for freetype/freetype.h if ft2build.h
+ was not found.
+
+2013-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ttf: Update FreeType to release 2.5.2.
+
+ * Updated build to use Automake 1.14.1.
+
+2013-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libxml: Update libxml2 to release 2.9.1.
+
+2013-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lcms/include/lcms2.h: Update lcms to release 2.5.
+
+ * png/README: Update PNG library to release 1.6.8.
+
+ * jpeg: Update Windows IJG JPEG library to release 9.
+
+2013-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/alpha_composite.h (BlendCompositePixel): Fix from Troy
+ Patteson to eliminate induced color problems when compositing two
+ images which include fully transparent pixels. Now fully
+ transparent pixels do not contribute any color to the composed
+ result. Opacity used when blending is now based on the average
+ opacity of both pixels. Resolves SourceForge issue #148 "Pixel
+ interpolation problem with rotated transparent images ".
+
+2013-12-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOnePNGImage): Properly scale 16-bit input
+ PNG down to 8-bit when using a Q8 build.
+
+2013-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/demo/piddle.cpp (main): Use DrawableDashArray to make
+ sure that it works.
+
+ * wand/drawing_wand.c (DrawSetStrokeDashArray): Fix defective
+ stroke-dasharray MVG generation. Resolves SourceForge issue "#255
+ DrawSetStrokeDashArray still fails".
+
+ * magick/draw.c (DrawSetStrokeDashArray): Fix defective
+ stroke-dasharray MVG generation.
+
+2013-12-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jpeg.c: Add value scaling changes which will be necessary
+ to support all the build depths supported by IJG JPEG 9a.
+
+ * coders/webp.c (ReadWEBPImage): Support 'ping'. Improve quality
+ of error reporting.
+
+ * GraphicsMagick.spec.in: Update RPM spec file to add
+ libwebp-devel as a build dependency, and libwebp as a run-time
+ depdendency.
+
+2013-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/webp.c: Incorporated simple WebP support as contributed
+ by "TIMEBUG" at users.sf.net plus a few security changes. Does not
+ yet support Windows Visual Studio build, input from a pipe,
+ attached profiles, animation, or incremental pixel I/O.
+ (RegisterWEBPImage): Register WebP as requiring seekable stream so
+ input from pipe works.
+
+2013-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/drawing_wand.c (DrawSetStrokeDashArray): Use array size
+ specified by user and don't expect user-provided array to be
+ terminated by 0.0. Resolves SourceForge bug "#250 Unexpected
+ results from DrawSetStrokeDashArray".
+
+ * magick/draw.c (DrawSetStrokeDashArray): Use array size specified
+ by user and don't expect user-provided array to be terminated by
+ 0.0.
+
+ * wand/drawing_wand.c (DrawGetStrokeDashArray): terminating 0.0 to
+ array returned to user.
+
+ * magick/draw.c (DrawGetStrokeDashArray): Add terminating 0.0 to
+ array returned to user.
+
+2013-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/annotate.c (RenderFreetype): Support rendering UTF-8
+ 21-bit code points. Was limited to 16-bit code points due to an
+ oversight/bug. Resolves SourceForge bug "#149 Rendering UTF-8
+ encoded file displays wrong glyphs".
+
+2013-11-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/constitute.c (ReadImage): Consistently initialize Image
+ page width and height to image width and height. Resolves
+ SourceForge bug #253 convert pdf output page is the wrong size
+ with -geometry "100%".
+
+2013-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): TIFFDefaultStripSize() sometimes
+ returns zero so make sure that rows-per-strip is at least one to
+ avoid divide by zero error. This bug was added in the current
+ development cycle.
+
+2013-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Update news since last release.
+
+ * magick/annotate.c (RenderFreetype): Support Johab, Latin-1, and
+ Latin-2 encodings.
+
+2013-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/drawing_wand.c (DrawSetStrokeLineJoin): BevelJoin should
+ produce MVG text "bevel".
+
+ * magick/draw.c (DrawSetStrokeLineJoin): BevelJoin should produce
+ MVG text "bevel". Fixes SourceForge bug "#245 error occured to
+ DrawableStrokeLineJoin(LineJoin.BevelJoin)".
+
+2013-10-16 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * Added calls to png_set_benign_errors() to allow benign errors
+ to be handled as warnings. In particular, GM builds with libpng-1.6.x
+ will not crash while copying a PNG with a "known incorrect ICC
+ profile".
+
+2013-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (NTGhostscriptEXE): Use gswin64c.exe as
+ Ghostscript executable name in a 64-bit application.
+
+2013-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (NTGhostscriptFind): 64-bit application should
+ not search for Ghostscript in 32-bit registry. SourceForge bug
+ #243 "GM on Windows will find Ghostscript only if both are 32 bit"
+
+2013-09-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c: As an extension to the standard PNM and PAM
+ formats, support writing 32-bit sample depth in the Q32 build, and
+ supporting reading 32-bit sample depth in all builds.
+
+2013-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c: Allow reading signed integer TIFF files even
+ though internal storage uses signed integers. Negative values
+ will be handled incorrectly and positive values will be scaled to
+ only 1/2 of the available unsigned range. Perhaps the situation
+ will improve in the future.
+
+ * tests/rwfile_miff.tap: Test MIFF with specific depths.
+
+ * tests/rwblob.c: Add support for -quality option.
+
+ * tests/rwfile.c: Add support for -quality option.
+
+ * tests/rwfile.tap: Add tests for PGM and PPM ASCII subformats.
+
+ * coders/pnm.c (WritePNMImage): PGM "P2" format writer was broken
+ at 8-bit depth due to lack of white-space between the output
+ values. Fixed now.
+
+2013-09-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): Fixes to be able to read MIFF
+ written by ImageMagick 6.X, including DirectClass grayscale
+ images. Interoperabilty is not completely assured since
+ ImageMagick is not consistent with itself and may only be able to
+ read the file it just wrote. Reading DirectClass grayscale RLE
+ compressed images is not supported yet.
+
+2013-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/profile.c (MagickFreeCMSTransform): Only delete the CMS
+ transform if it is non-null. If lcms returned a null transform,
+ an assertion was thrown in lcms when the pointer was freed.
+ Problem was reported by James Bardin.
+
+2013-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c: PseudoClass format was written incorrectly in
+ that sample storage size is supposed to be selected based on the
+ size of the colormap, but it was being selected based on the depth
+ parameter instead, leading to excessively sized files and failure
+ to read what was written. RLE compressed formats had the sense of
+ the alpha channel inverted from the other compression methods, and
+ contrary to the specification. PseudoClass with Alpha was not
+ supported at all, and reading a file claiming to be such caused an
+ assertion to be thrown. Note that these fixes may cause some
+ existing files to no longer be read correctly.
+
+ * coders/xpm.c (ReadXPMImage): XPM is rarely used to produce
+ 16-bit output. Set image depth based on the colormap.
+
+ * coders/tim.c (ReadTIMImage): PSX TIM is not able to produce more
+ than 8-bit output, set image depth appropriately.
+
+2013-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Increase rows-per-strip as
+ required to try to avoid more than 32K strips per image since some
+ programs seem to use a 16-bit strip counter and fail with more
+ than 32K strips. Problem was reported by Kevin Myers.
+
+ * magick/transform.c (MosaicImages): Fix unsigned underflow
+ problem with -mosaic when page offset is negative and exceeds
+ image width or height. This problem caused assertions, out of
+ memory errors, or pixel cache limit errors due to requesting an
+ image of outrageous size.
+
+2013-08-26 Jaroslav Fojtik <JaFojtik@seznam.cz>
+ * dcraw\dcraw.c Updated from autor
+ * dcraw\dcraw.c.patch
+
+2013-08-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c (ReadPNMImage): Fix SourceForge issue #237
+ "Incorrect MAXVAL scaling when reading PAM images".
+
+2013-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/render.c (DrawImage): Improve error handling so that
+ rendering bails on image access/update errors. Resolves
+ SourceForge issues #233 "Another SVG that hangs GraphicsMagick"
+ and #232 "Another SVG that hangs GraphicsMagick". The resolution
+ of the bug is to return from image access/update error right away
+ rather than adjusting the rendering density to produce a smaller
+ image.
+
+ * magick/error.h: Hide exception throwing convenience macros under
+ MAGICK_IMPLEMENTATION definition.
+
+ * Magick++/demo/demos.tap: Fix file naming for 'zoom' demos.
+
+ * magick/annotate.c (RenderFreetype): Improve error handling so
+ that rendering bails on image access/update errors.
+
+2013-08-02 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOnePNGImage): ping a png faster by
+ returning the image without reading the pixel data.
+
+2013-07-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/xwindow.c (MagickXMakeImage): Only use ThumbnailImage()
+ for DirectClass images in order to avoid a crash while creating
+ the panner image.
+
+2013-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * design/pixel-cache-struct.dot: Update structure relationships
+ diagram.
+
+ * design/pixel-cache.dot: Update call flow diagram.
+
+ * magick/pixel_cache.c: Eliminate use of internal functions
+ GetNexusIndexes(), GetNexusPixels(). Reduce usage of internal
+ function IsNexusInCore().
+
+2013-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: MAGICK_SSIZE_T should always be a signed type.
+
+ * coders/jpeg.c (WriteXMPProfile): Add support for writing 'XMP'
+ profile in JPEG.
+ (WriteJPEGImage): Restructure/tidy JPEG profile writing code.
+
+2013-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Return DirectClass images by
+ default for MINISWHITE and MINISBLACK TIFF formats.
+
+2013-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wpg.c, magick/attribute.c, magick/map.c, magick/render.c,
+ magick/widget.c, magick/xwindow.c: Fixes to reduce warnings with
+ GCC 4.8.0 at -O3 optimimization level, and for clang 3.2.
+
+2013-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/xwindow.c (MagickXMakeImage): Use ThumbnailImage() rather
+ than SampleImage() when creating the panner image to improve the
+ quality of the image.
+
+2013-03-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (tag_table): Add support for SubjectArea EXIF
+ tag. Resolves SourceForge issue #229 "Cannot Parse the
+ SubjectArea EXIF Info".
+
+2013-03-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Hg.rst, www/index.rst: Update SourceForge Mercurial
+ repository location (see
+ http://hg.code.sf.net/p/graphicsmagick/code) due to project
+ "upgrade". For the moment there are old and new
+ repositories. Changes will be pushed to the new repository.
+
+2013-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (InitializeMagickResources): Revert use of
+ omp_set_dynamic() since it caused a severe performance regression
+ when doing a -stepthreads benchmark or when the number of OpenMP
+ threads is set via OMP_NUM_THREADS.
+
+2013-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * INSTALL-unix.txt: Add a section about building Windows binaries
+ by cross-compiling from a Unix/Linux system.
+
+2013-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac, magick/magick_types.h.in: Fix issues noticed when
+ cross-compiling with MinGW64.
+
+2013-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * version.sh, www/index.rst: Prepare for 1.3.18 release.
+
+2013-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (DisplayImageCommand): display is supposed to
+ respond to +/-usePixmap, but was not. It was responding to
+ +/-use_pixmap. Now it responds to both.
+
+2013-03-03 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * doc/GraphicsMagick.imdoc: Relocated some <im> .. </im> tags, to
+ include several paragraphs that were omitted from the
+ GraphicsMagick man page (Environment, Configuration Files, and
+ Copyright).
+
+ * doc/imdoc2man: the </pre> tag was being deleted instead of
+ replaced with nothing, which caused the first line of the
+ subsequent material to be joined to the last line of the <pre>
+ block.
+
+2013-03-02 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOnePNGImage): Avoid a libpng16 warning about
+ storing unknown chunks.
+
+2013-02-25 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOnePNGImage): Call png_set_bKGD(), etc.,
+ after png_set_IHDR() because they depend on members of info_ptr
+ which are set by png_set_IHDR().
+
+2013-02-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (InitializeMagickResources): Enable the
+ dynamic adjustment of OpenMP threads if there is more than one
+ thread available.
+
+2013-02-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * configure.ac and configure: Check for libpng17 and libpng16.
+
+2013-02-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/programming.rst: Add mention of Clement Farabet's Lua
+ scripting language wrapper for GraphicsMagick.
+
+2013-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (GetCacheNexus): Re-write function so it
+ has a single point of return.
+ (AcquireCacheNexus): Reduce the number of return points.
+ (SetCacheNexus): Re-write function so it has a single point of
+ return.
+
+2013-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Update with latest news.
+
+ * magick/export.c (ExportAlphaQuantumType): Fix export of alpha
+ for RGBA image and depth 8. Due to typo, was exporting 16-bits
+ rather than 8, causing output corruption or crashes. Resolves
+ issue reported in SourceForge GraphicsMagick forum under title
+ "CMYK per-channel byte order TIFF crashes gm".
+
+2013-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h (MagickIsBlank): Add macro to substitute for ISO
+ C99 isblank() which is not globally available. Update 'gm batch'
+ code which had substituted isspace() for isblank() to use it.
+
+2013-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (BatchCommand): Flush stdout at key points in
+ order to ensure that user sees text when it is produced.
+
+2013-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/random.c (InitializeMagickRandomGenerator): Use
+ MagickTsdKeyCreate2() in order to avoid a small memory leak.
+
+ * magick/tsd.c (MagickTsdKeyCreate2): New private function to
+ support allocating a thread-specific data key with a specified
+ destructor function. For single-threaded build, MagickTsdKey_t is
+ now type void* and there is provision to support the destructor
+ function.
+
+2013-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (BatchCommand): New 'gm batch' command to
+ accept one or more GraphicsMagick commands from a specified text
+ file, standard input, or CLI. Feature is implemented by Kenneth
+ Xu. Submitted via SourceForge Patch #3602331 "Add interactive or
+ batch mode support to 1.3.17".
+
+2013-01-27 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOnePNGImage): Added PNG48 and PNG64 support.
+ Added PNG00 support (png encoder that inherits its color-type and
+ bit-depth from the input, if the input was a PNG datastream).
+
+2013-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOnePNGImage): PNG8 support was using
+ image->colors to decide if the input image is PseudoClass. This
+ is totally bogus. Use image->storage_class to determine if image
+ is PseudoClass and quantize image colors if it is not.
+
+ * magick/delegate.c (InvokePostscriptDelegate): Only invoke
+ MagickSpawnVP() if Ghostscript filename argument is non-empty.
+ This argument may be empty if Ghostscript is not found on a
+ Windows system. Report a "Failed to find Ghostscript" error if
+ the Ghostscript command name is empty. Resolves SourceForge issue
+ #3601816 "Win64 build crashes trying to convert PDF to any other
+ format".
+
+ * magick/utility.c (MagickSpawnVP): Verify that file argument is
+ non-NULL and not empty.
+
+2013-01-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick/tiff/LIBRARY.txt: Fix pre-processor definitions for
+ libtiff so that they use multiple statements rather than one long
+ statement. Resolves SourceForge issue 3601001 "libtiff won't
+ compile with ICL".
+
+2013-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/memory.h (MagickAllocateAlignedArray): New macro to wrap
+ use of MagickMallocAlignedArray().
+
+ * magick/memory.c (MagickMallocAlignedArray): New private function
+ to support safe allocation of an array in memory with a specified
+ alignment. Allocation may only be freed using MagickFreeAligned()
+ and the allocation may not be reallocated.
+
+2013-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/{animate.c,display.c,utility.c}: Only invoke chdir() if
+ path is not an empty string. Previously sometimes chdir() was
+ passed an empty string (because chdir() was not needed) and this
+ was ok because we ignored the error status. Now that we check the
+ chdir() error status, some X11 GUI functions (e.g. save file to
+ current directory) encounter annoying issues.
+
+ * magick/shear.c (IntegralRotateImage): Limit integral rotate to
+ two threads.
+
+ * coders/pnm.c (ReadPNMImage): Limit PNM reader to two threads.
+
+2013-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac (MAGICK_FEATURES): MinGW static build does not
+ build modules so MODULES feature should not be listed as
+ supported. Resolves MinGW test failures.
+
+ * coders/dpx.c (OrientationTypeToDPXOrientation): Return U16 type
+ as stored in DPX format.
+
+ * coders/cineon.c: Add support for reading/writing 'orientation'
+ setting.
+
+ * coders/mpc.c: Add support for reading/writing 'orientation'
+ setting.
+
+ * coders/miff.c: Add support for reading/writing 'orientation'
+ setting.
+
+ * Rotate ChangeLog for 2012 and update web page copyright years.
diff --git a/ChangeLog.2014 b/ChangeLog.2014
new file mode 100644
index 0000000..f2fd495
--- /dev/null
+++ b/ChangeLog.2014
@@ -0,0 +1,895 @@
+2014-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wpg.c (UnpackWPGRaster): Fix some compilation and
+ valgrind warnings.
+
+ * NEWS.txt: Updated news again.
+
+2014-12-31 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/wpg.c Fixed 2bpp issue.
+
+2014-12-31 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Validate MHDR chunk length.
+
+ * coders/png.c: Use ReadBlob() once instead of ReadBlobByte()
+ in a loop.
+
+ * coders/png.c: Avoid reading beyond the end of a tEXt keyword.
+
+2014-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xpm.c (ReadXPMImage): Detect short XPM rows and report
+ error to user rather than overrunning a buffer.
+
+ * coders/pcx.c (ReadPCXImage): Validate that header bytes per line
+ is sufficient to contain the indicated data.
+
+ * coders/pdb.c (ReadPDBImage): Fix indexes array overrun for 2 and
+ 4-bit PDB image files.
+
+ * coders/xpm.c (ReadXPMImage): Avoid strncpy() of overlapping
+ memory. Fix memory leaks in error paths.
+
+ * coders/viff.c (ReadVIFFImage): Validate index before using it to
+ access colormap.
+
+ * coders/{cineon.c, dpx.c} (StringToAttribute): Can't use
+ strlcpy() to copy string which might not be NULL-terminated since
+ strlcpy() continues searching for end of string after size bytes
+ have been copied.
+
+ * coders/meta.c (convertHTMLcodes): Avoid strcpy() of overlapping
+ memory.
+
+2014-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/process.rst: Update description of development process to be
+ more aligned with the process actually used.
+
+ * coders/wpg.c (ReadWPGImage): Avoid use of NULL pointer returned
+ from FlipImage(), FlopImage(), and RotateImage().
+
+ * coders/rle.c (ReadRLEImage): URT RLE reader is now more robust
+ with errant files.
+
+2014-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtool: Update bundled libtool to version 2.4.4.
+
+ * magick/constitute.c (WriteImage): Remove bogus use of
+ GetBlobStatus() as a catch-all for write errors. Coders should be
+ detecting write errors all by themselves.
+
+2014-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Updated with more improvements since previous release.
+
+ * coders/palm.c (WritePALMImage): Log header details.
+
+ * coders/pdb.c: PDB reader and writer need to be more robust when
+ calculating packets and buffer allocation. Also log header
+ details. Problem was reported by Hanno Böck.
+
+2014-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Updated with more improvements since previous release.
+
+ * ttf: Update bundled Freetype to 2.5.4.
+
+ * png: Update bundled libpng to 1.6.16.
+
+2014-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): The libtiff JBIG coder only
+ supports strip images, and fails when scanlines are requested.
+ Force use of stripped read method when the file uses JBIG
+ compression. It is still not possible to write JBIG compressed
+ TIFF files since there is not yet a strip writer. Problem
+ reported by Yuriy Kaminskiyon via the GM-bugs mailing list on
+ 2014-12-22.
+
+2014-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (QuantumTransferMode): Fix quantum transfer
+ handling for photometrics which might deliver one or three samples
+ per pixel. These were assuming that three samples were always
+ provided.
+
+2014-12-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Impose a 10-million limit on dimensions
+ when reading a PNG file.
+
+2014-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Updated with improvements since previous release.
+
+2014-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/statistics.c (GetImageStatistics): Failed to compute
+ statistics for the Black channel of CMYK image files. Problem
+ reported by Michael Below via Debian bug 773552:
+ "graphicsmagick-imagemagick-compat: convert to cmyk leaves k
+ channel empty".
+
+2014-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/delegate.c (InvokeDelegate): Windows spawnvp() splits
+ arguments into more arguments. Add escaping to avoid the
+ splitting. Resolves SourceForge bug #276 "dcraw 9.19 included
+ with gm 1.3.20 doesn't support paths with spaces."
+
+ * magick/utility.c (TranslateTextEx): Fix regression added on
+ 2014-12-13 (yesterday) which caused output file name passed to
+ delegate programs to be wrong.
+
+ * magick/annotate.c (RenderFreetype): Fix regression added in
+ 1.3.19 which caused spurious drawing errors to be produced while
+ rendering with text when all of the text is off the left-hand side
+ of the image.
+
+2014-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (CompareUsage): Options should be listed in
+ alphabetical order.
+
+ * magick/annotate.c (RenderFreetype): Immediately quit processing
+ and return an error if SyncImagePixels() reports a problem.
+
+ * coders/psd.c (ReadPSDImage): Return with an error right away if
+ SetImageEx() (to create solid-color background canvas) reports a
+ failure.
+
+ * magick/annotate.c (AnnotateImage): Document all of the
+ attributes which are supported.
+
+ * magick/utility.c (TranslateTextEx): Assure that attributes
+ requiring ImageInfo pointer are skipped. AnnotateImage() does not
+ pass ImageInfo. Also document all of the attributes which are
+ supported.
+
+ * doc/compare.imdoc: Compare documentation examples referred to
+ non-existing option -algorithm rather than the existing option
+ -highlight-style. Fixes SourceForge bug #286 "docs are wrong
+ about `-algorithm` option of `gm compare`?".
+
+ * Magick++/lib/Magick++/Geometry.h (Magick): Re-implemented
+ Magick++ Geometry to use bit-fields for booleans and used a union
+ to reserve space for the future as well as to achieve the same
+ size as in the previous release. Eliminated inline methods
+ because they make it impossible to change the class internal
+ design. ABI was broken already when limitPixels() and fillArea()
+ methods were added on 2014-11-28. Inline method instantiations in
+ already compiled applications will malfunction unless the
+ dependent applications are re-compiled.
+
+ * magick/image.c (SetImageEx): Add a new version of SetImage()
+ called SetImageEx() which reports exceptions to a provided
+ exception parameter rather than into the image.
+
+2014-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colormap.c (AllocateImageColormap): Refuse to allocate a
+ colormap larger than MaxColormapSize.
+
+ * coders/psd.c (ReadPSDImage): Avoid extremely long execution time
+ if the PSD colormap size is astonishingly large. Problem was
+ reported by Hanno Böck.
+
+2014-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dcm.c: Verify that DCM data is available before
+ attempting to use it. Avoids a crash due to improper DCM header.
+ Problem was reported by Hanno Böck.
+ (DCM_ReadNonNativeImages): Fix array over-run (off by one error)
+ while looking for end of multi-fragment frames.
+
+2014-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/sun.c: Thoroughly validate Sun Rasterfile headers and
+ verify that there are no arithmetic overflows in buffer-size
+ calculations. Problem was reported by Hanno Böck.
+
+2014-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/Magick++/Geometry.h (Magick::Geometry): Add and
+ document limitPixels() and fillArea() methods to support '@' and
+ '^' geometry qualifiers. Fill area contributed by Long Ho and
+ limitPixels() by Bob Friesenhahn.
+
+ * www/Magick++/Image.rst: Document extent and resize methods.
+
+ * Magick++/lib/STL.cpp (extentImage): New function object to
+ invoke image extent method. Original implementation contributed by
+ Long Ho. Subsequently modified by Bob Friesenhahn.
+ (resizeImage): New function object to invoke image resize
+ method. Contributed by Long Ho.
+
+ * Magick++/lib/Image.cpp (extent): New method to place image on
+ sized canvas of constant color using gravity. Contributed by Long
+ Ho.
+ (resize): New method to resize image specifying geometry, filter,
+ and blur. Original implementation contributed by Long Ho.
+ Subsequently modified by Bob Friesenhahn.
+
+2014-11-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/avi.c: AVI support in GraphicsMagick is completely
+ unusable and it could never compete with dedicated software like
+ 'ffmpeg'. Removing AVI support until such time it can be
+ supported properly.
+
+ * coders/viff.c: Add protections against buffer overflow by
+ verifying that buffer size allocation calculations do not
+ overflow. Also added header logging for read and write. Work
+ performed due to complaint by Hanno Böck.
+
+2014-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/common.h (MAGICK_NO_SANITIZE_ADDRESS): Add
+ MAGICK_NO_SANITIZE_ADDRESS macro definition for disabling
+ clang/GCC address sanitizer on a function if the need arises.
+
+2014-11-24 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadPNGImage): Do not attempt to clean up
+ a "previous" NULL PNG image.
+
+2014-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xwd.c (ReadXWDImage): Add logging of XWD header values.
+ Fix memory leaks in error reporting paths. Ping mode skips
+ allocating memory for data and colormap. Added a few more header
+ validation checks (not complete). XWD is put in
+ UnstableCoderClass until such time as header validation checks are
+ complete.
+
+2014-11-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdb.c (WritePDBImage): Use MagickAllocateArray() when
+ allocating packets.
+
+ * coders/dpx.c (ReadDPXImage): Validate DPX header orientation and
+ number of elements. Problem was reported by Hanno Böck.
+
+2014-11-20 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadJNGImage): Do not attempt to clean up
+ a "previous" NULL JNG image.
+
+2014-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/FAQ.rst: Add a FAQ entry regarding what 'identify' reports.
+ Resolves SF issue #280 "Better documentation for spurious gm
+ identify in Q8 compilation."
+
+2014-11-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/enhance.c (ModulateImage): ModulateImage() should produce
+ a progress indication even if only the colormap is modified.
+
+2014-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/psd.c (ReadPSDImage): Patch by Cédric Demière to fix
+ "Memory allocation failed" error when reading PSDs files which
+ have no layers. Delivered via SF patch #41 "PSD : files without
+ layers". Resolves SF bug #242 "Can not convert PSD to JPG or PNG
+ (gm convert: Memory allocation failed)".
+
+2014-11-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/webp.c (WriteWEBPImage): WebP fix by Roman Hiestand to
+ make WebP lossless format truely lossless.
+
+ * tests/rwblob.tap (check_types): Added a test for WebP lossless.
+
+ * tests/rwfile.tap: Added a test for WebP lossless.
+
+ * tests/rwblob.c: Added support for -define.
+
+ * tests/rwfile.c: Added support for -define.
+
+2014-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * webp, VisualMagick/webp: Updated bundled WebP to 0.4.2 release.
+
+2014-11-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/tests/attributes.cpp: Add a simple test for
+ Image::formatExpression().
+
+ * Magick++/lib/Image.cpp (formatExpression): Handle case where
+ TranslateText() returns NULL. Problem was reported by Dirk
+ Lemstra..
+
+2014-10-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/Image.cpp (formatExpression): New method to format
+ a string based on a format similar to command-line -format.
+ Feature was requested by Dirk Lemstra.
+
+ * magick/blob.c (BlobReserveSize): Don't throw an exception if
+ posix_fallocate() fails since it seems that it is not supported
+ for all filesystem types, and is only intended for optimization.
+
+ * Magick++/lib/Image.cpp (resolutionUnits): Return resolution
+ units from Image if available, else return the value from
+ ImageInfo. Issue was reported by Dirk Lemstra.
+
+2014-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c (ReadPNMImage): Validate PGM, PPM, and PAM header
+ MaxValue parameter. Issue was reported by Hanno Böck.
+
+ * coders/pcx.c (ReadPCXImage): Fix for CVE-2014-8355, eliminate
+ memory leaks in error paths, and add PCX header logging. Issue
+ was reported by Hanno Böck.
+
+2014-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/wand_symbols.h (MagickSetImageGamma): Fix typo in
+ wand/wand_symbols.h. Resolves SF bug #277.
+
+2014-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (TIFFIgnoreTags): Avoid warning about unused
+ strtol() return value on Linux.
+
+ * magick/random-private.h ("C"): Move random inlined
+ implementation bits to random-private.h, which is not installed,
+ or used outside of the core C library.
+
+2014-09-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/annotate.c (AnnotateImage): An empty text string should
+ not be treated as an error. Resolves Debian bug 759956.
+
+2014-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c: Added a new define called tiff:ignore-tags that
+ can be used to ignore tags in 'corrupted' files with unknown and
+ invalid tags. Without this patch the file cannot be read and
+ raises an error. Patch by Dirk Lemstra via SF patches #40.
+
+ * magick/type.c (ReadTypeConfigureFile): Support reading type
+ configuration file from Windows resource. Patch by Dirk Lemstra
+ via SF patches #32.
+
+ * Magick++/lib/Magick++/STL.h: Fixed code analysis warning in
+ STL.h. Patch by Dirk Lemstra via SF patches #32.
+
+ * Magick++/lib/Magick++/Include.h: Autolink WebP in Visual
+ Studio. Patch by Dirk Lemstra via SF patches #32.
+
+2014-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/psd.c (WritePSDImage): Fix small stack over-write if more
+ than 99 layers are written to PSD format. Similar to
+ CVE-2014-1947 for ImageMagick. Changed layer naming to use at
+ least 4 digits. Issue was brought to our attention by Rex Dieter
+ and change is mostly based on his patch.
+
+2014-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/enum_strings.c (StringToCompositeOperator): Support
+ composite operator names similar to the major brand, without
+ losing any compatibility with previous naming.
+
+2014-08-23 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+ * coders/png.c: Fixed handling of transparency when writing
+ indexed PNG. Reference: SourceForge Bug tracker [bugs:#267]
+ Transparency lost when converting from GIF to PNG.
+
+2014-08-17 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * VisualMagick\configure\configure.cpp Remove webp when attempting
+ to compile with Visual Studio 6.
+
+2014-08-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Update for 1.3.20 release.
+
+ * www/index.rst: Update for 1.3.20 release.
+
+ * version.sh: Update library versioning for next release.
+
+2014-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * png: Updated libpng to 1.6.12 release.
+
+ * zlib: Updated zlib to 1.2.8 release.
+
+2014-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Updated NEWS file to document changes since previous
+ release.
+
+2014-08-09 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * coders/webp.c webp cannot be compiled when HasWEBP is not set.
+
+2014-08-08 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Eliminated palette and depth optimization (see
+ https://sourceforge.net/p/graphicsmagick/feature-requests/35/).
+
+2014-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * dcraw/dcraw.c: Fix dcraw build for x64 target when only WIN64 is
+ defined (by also defining WIN32).
+
+ * VisualMagick/configure/configure.cpp (write_file): Fix problem
+ with x64 project naming which caused object file disambiguation
+ not to work for x64 target. Make line terminations consistent.
+
+2014-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * VisualMagick: VisualMagick fixes by Dirk Lemstra to improve
+ configure program so that it is possible to select QuantumDepth,
+ OpenMP, and 64-bit build via configure dialog boxes as well as
+ options on the command line. Also automatically detects and deals
+ with similarly named files in subdirectories so that WebP support
+ can now build successfully. Resolves SF patches 31, 33, 35, 37,
+ and 38.
+
+2014-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (NTResourceToBlob): Support loading mgk files
+ as Windows resource from library if MagickLibName is defined.
+ Patch contributed by Dirk Lemstra via SF patch #32.
+ (NTGhostscriptDLL): For Microsoft Windows, add support for a
+ MAGICK_GHOSTSCRIPT_PATH environment variable which specifies the
+ path to Ghostscript. If this environment variable is defined,
+ then the Windows registry is not used to find Ghostscript. Patch
+ contributed by Dirk Lemstra via SF patch #39.
+
+ * magick/log.c: Added SetLogMethod() to allow an
+ application/library to specify a function to be called for
+ logging. Patch contributed by Dirk Lemstra.
+
+2014-07-20 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/bmp.c: "opacity" read from a BMP3 is actually "alpha",
+ so store q->opacity=MaxRGB-opacity instead of q->opacity=opacity.
+ Reference: Bug tracker [bugs:#271] Blank result for BMP resize.
+
+2014-07-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * webp, VisualMagick/webp: Integrate webp 0.4.0 into windows
+ build. May require manual renaming of output object files in
+ project files to build webp until VisualMagick configure is
+ improved!
+
+2014-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c: fmin() and fmax() are defined by C'99 and
+ not available everywhere, so add and use MagickFmin() and
+ MagickFmax() to improve portability.
+
+2014-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/Magick++/Image.h (Magick): Fix complilation errors
+ caused by continued raw use of __attribute__.
+
+2014-06-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c: Fixes by Brendan Lane for color channel
+ overflows in modified/new quantum operators. Fixes test suite
+ results for Q32 build and makes LinearBurn and LinearDodge work
+ correctly at all.
+
+ * wand/pixel_wand.c (PixelSetMagenta): Fix documentation.
+ Resolves SourceForge bug #273 'Green Magenta' typo in docs.
+
+2014-06-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c: Composition improvements and additions
+ contributed by Brendan Lane via SourceForge patch #34 "Most of the
+ missing Photoshop separable compositing operations"
+ (https://sourceforge.net/p/graphicsmagick/patches/34/). These
+ composition operators were modified to include alpha in their
+ computations: Difference, Darken, Lighten, HardLight, and these
+ operators were added Overlay, Exclusion, ColorBurn, ColorDodge,
+ SoftLight, LinearBurn, LinearDodge, LinearLight, VividLight,
+ PinLight, HardMix.
+
+2014-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c (ScreenCompositePixels): Implementation of
+ Screen composite contributed by Brendan Lane. SourceForge patch
+ #30 "Missing Screen composite operation".
+
+ * wand/magick_compat.c: Re-worked Wand library implementation to
+ depend directly on GraphicsMagick library functionality rather
+ than using ImageMagick shim code from magick_compat.c and
+ magick_compat.h. The magick_compat.c source module becomes "dead
+ code", which remains only to support the existing ABI, and will be
+ deleted at the next major ABI break point.
+
+ * magick/utility.c (MagickFormatString): New private function to
+ format a string into a buffer with a specified size. Same as
+ previously existing FormatString() except requires a length
+ argument.
+
+2014-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_compat.h: Use MAGICK_ATTRIBUTE definition from
+ magick/common.h.
+
+ * magick/common.h (MAGICK_ATTRIBUTE): Don't undefine __attribute__
+ since this may be used by system or compiler headers. Define
+ private macro instead. Resolves SourceForge bug #270 "Compile
+ error with g++ -std=c++11".
+
+2014-06-06 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOnePNGImage): Free png_pixels and
+ quantum_scanline before error return. Use "png_error()"
+ instead of "ThrowException2()" for errors occuring while
+ decoding a PNG so proper cleanup will happen.
+
+2014-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Make sure that libtiff warnings
+ are promoted to errors for critical tags.
+
+2014-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (ReadTIFFImage): Be quite a lot more draconian
+ when retrieving the baseline standard TIFF tags we need in order
+ to avoid consuming uninitalized data later. An error with these
+ tags will result in failure to read the image file.
+
+2014-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/operator.c: Decided that ThresholdBlackNegateQuantumOp
+ and ThresholdWhiteNegateQuantumOp should set the result to white
+ or black respectively rather than being based on subtraction.
+
+2014-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Be ultra-pedantic with CPPFLAGS
+ and include paths in order to assure that only required
+ directories are supplied, and to avoid accidential collision with
+ system header files.
+
+2014-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/operator.h ("C"): New quantum operators
+ ThresholdBlackNegateQuantumOp and ThresholdWhiteNegateQuantumOp.
+ These correspond to -operator "Threshold-Black-Negate" and
+ "Threshold-White-Negate".
+
+2014-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/composite.c (MultiplyCompositePixels): Multiply
+ composition now uses SVG interpretation of how alpha should be
+ handled. No longer does a simple multiply of alpha channel.
+ Behavior change. Patch contributed by Sara Shafaei.
+
+ * coders/msl.c (ProcessMSLScript): Deal with case where
+ image_info->attributes is NULL.
+
+2014-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (TranslateTextEx): Support additional format
+ specifiers 'g', 'A', 'C', 'D', 'G', 'H', 'M', 'O', 'P', 'Q', 'T',
+ 'U', 'W', 'X', and '@'.
+ (GetMagickGeometry): Support '>' and '<' qualifiers with '@'
+ qualifier to specify if image should be resized if larger or
+ lesser than given area specification. Resolves SourceForge bug
+ #216 ">" wont take effect when use @ to specify the maximum area.
+
+ * magick/transform.c (GetImageMosaicDimensions): Move mosaic
+ dimensions code to a static function for possible future re-use.
+
+2014-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/gradient.c (GradientImage): Update image is_grayscale and
+ is_monochrome flags based on gradient color properties.
+
+2014-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetMagickGeometry): Deal with resize geometry
+ missing width or height (e.g. '640x' or 'x480') by substituting
+ the missing value with one which preserves the image aspect ratio.
+ This has been documented to be supported since almost the dawn of
+ GraphicsMagick but was not actually supported until now.
+
+2014-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Document WebP encoder options.
+
+ * coders/webp.c (WriteWEBPImage): Support all of the WebP encoder
+ options via -define arguments. Most of this work is contributed
+ by Roman Hiestand.
+
+ * configure.ac: User-provided LIBS should be prepended to LIBS
+ that configure script produces so that user option takes
+ precedence.
+
+2014-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * PerlMagick/Magick.xs: Added support for HardLight composition
+ operator.
+
+ * www/perl.rst: Update PerlMagick documentation, including the
+ composition operators.
+
+ * coders/xcf.c (GIMPBlendModeToCompositeOperator): Use new
+ HardLight composition operator to support XCF GIMP_HARDLIGHT_MODE
+ blend mode. Contributed by Sara Shafaei.
+
+ * coders/psd.c (CompositeOperatorToPSDBlendMode): Use new
+ HardLight composition operator to support PSD "hLit" blend mode.
+ Contributed by Sara Shafaei.
+
+ * wand/magick_wand.c (MagickOperatorImageChannel): New function to
+ apply an operator to an image channel. Contributed by Sara
+ Shafaei.
+
+ * magick/composite.c (HardLightCompositePixels): New HardLight
+ composition operator. Contributed by Sara Shafaei.
+
+2014-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (BenchmarkImageCommand): Add a CSV title line
+ and quoting to benchmark -rawcsv output.
+
+2014-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/webp.c: Add progress indication support to WebP writer.
+
+ * magick/command.c (VersionCommand): WebP support is included in
+ -version output.
+
+ * coders/webp.c: WebP coder identifies library version and header
+ ABI versions. Improve WebP error reporting.
+
+2014-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Allow specifying the TIFF image
+ software tag. In the special case that the string length is zero
+ (e.g. -set software '') then the tag is skipped entirely. This is
+ to support SourceForge feature request #37 "Option to prevent
+ addition of Exif Software tag" opened by Jean-Louis Grall. Please
+ note that this tag is not an EXIF tag.
+
+ * magick/command.c: composite, convert, display, mogrify, and
+ import now support +set to remove an existing image attribute.
+
+2014-03-16 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Don't block threads when PNG_SETJMP_SUPPORTED is
+ not enabled.
+
+ * coders/png.c: Changed prefix of macros defined in coders/png.c
+ from PNG_ to GMPNG_. PNG_ is reserved for macros defined by
+ libpng.
+
+2014-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c: Don't use setvbuf() to set stdio block size if
+ filesystem block size is zero (e.g. MAGICK_IOBUF_SIZE=0)
+
+2014-03-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/{rwblob.tap, rwfile.tap}: Added tests for WEBP.
+
+ * tests/{rwblob.c, rwfile.c}: Add lossy hint for WEBP.
+
+ * coders/webp.c (WriteWEBPImage): Fix inverted return status.
+ Added a tiny bit of logging.
+
+2014-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ttf: Updated FreeType to release 2.5.3 of March 6, 2014.
+ Provides security fixes for CVE-2014-2240.
+
+ * jpeg: Update to libjpeg 9a of 19-Jan-2014.
+
+ * png: Update to Libpng 1.6.10 - March 6, 2014.
+
+2014-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (NTResourceToBlob): According to Microsoft
+ Report article 193678 (http://support.microsoft.com/kb/193678),
+ FreeResource() is not needed in WIN32 and performs no useful
+ function. Remove use of it. Also remove use of UnlockResource()
+ which is similarly unuseful for WIN32.
+
+ * configure.ac (MAGICK_LIBRARY_REVISION): Test for Windows
+ _aligned_malloc() is not reliable. Use Windows CRT version to
+ decide if it is available.
+
+2014-03-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h: Make sure that Windows _aligned_malloc() is not
+ used under MinGW unless the CRT version allows it.
+
+2014-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (InterpolateViewColor): Applied patch by
+ Troy Patteson plus fixes to ignore opacity channel if image matte
+ is false. Replaces most of the code rewritten on 2014-02-16 and
+ which produced a faint darkened border. The results look stellar
+ now.
+
+2014-02-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/shear.c: Applied patch by Troy Patteson to improve
+ non-integral rotation by around 40% by minimizing added image
+ borders. This may cause small differences in results for some
+ images.
+
+ * reference/filter/Rotate10.miff: Update rotate 10 degrees
+ reference image so that PerlMagick test passes.
+
+ * magick/shear.c: Applied patch by Troy Patteson to fix
+ SourceForge issue #260 "Rotation exhibits clipping/shearing errors
+ for short wide images at some angles".
+
+2014-02-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc: Fix documentation to note that 'unspecified
+ alpha' is the GraphicsMagick default when writing TIFF rather than
+ 'associated alpha'. Much thanks to Mats Peterson for alerting us
+ of this error.
+
+2014-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/pixel_cache.c (InterpolateViewColor): Added a hack so that
+ affine transformations and displace composite do not have
+ background colored fringing on the transferred image edges when
+ the background is completely transparent. Fringing problem was
+ caused by one or more of the line ends being a transparent pixel
+ outside of the bounds of the original image content. May not be
+ the final solution.
+
+2014-02-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/semaphore.c (AcquireSemaphoreInfo): Document that this
+ function was deprecated.
+ (LiberateSemaphoreInfo): Document that this function was
+ deprecated.
+
+2014-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/psd.c (RegisterPSDImage): Set PSD to UnstableCoderClass
+ since its implementation is currently rather marginal. It may
+ even be that this coder deserves to be marked with the new
+ BrokenCoderClass. We are still looking for a volunteer to iron
+ out the wrinkles in the PSD reader.
+
+ * magick/magick.h (CoderClass): Added BrokenCoderClass to mark
+ coders which often malfunction or are not very useful in their
+ current condition. Sometimes there is still hope that problems
+ will be resolved and so the source file is not outright deleted.
+ This setting allows us to mark and use coders which might
+ malfunction by defining MAGICK_CODER_STABILITY=BROKEN in the
+ environment while not causing danger for normal use.
+
+2014-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c: Documentation improvements for
+ MagickSetInterlaceScheme() and MagickSetImageInterlaceScheme().
+ Resolves SourceForge bug #262 "setImageInterlaceScheme doesn't
+ make image progressive".
+
+2014-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/{ps.c, ps2.c, ps3.c, pdf.c}: Only use resolution from
+ image or -density if units was properly specified. Without units,
+ resolution is worthless.
+
+ * coders/ps3.c (WritePS3Image): Use image resolution similar to PDF
+ changes.
+
+ * coders/ps2.c (WritePS2Image): Use image resolution similar to PDF
+ changes.
+
+ * coders/ps.c (WritePSImage): Use image resolution similar to PDF
+ changes.
+
+ * coders/pdf.c (WritePDFImage): Use resolution from image if it
+ appears to be valid. Resolves SourceForge issue #261 "PNG Pixel
+ Density Not Preserved Converting to PDF".
+
+ * magick/enum_strings.c (StringToResolutionType): New function to
+ convert ResolutionType to C string.
+ (ResolutionTypeToString): New function to convert from C string to
+ ResolutionType.
+
+2014-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickGetImageGeometry): New function to get
+ the image geometry string. This function and the three others in
+ this change set are contributed by Sara Shafaei.
+ (MagickGetImageMatte): New function to read the image matte
+ (opacity) channel enable flag.
+ (MagickSetImageGeometry): New function to set the image geometry
+ string.
+ (MagickSetImageMatte): New function to set the image matte
+ (opacity) channel enable flag.
+
+2014-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.c (MagickDrawImage): Remove development debug
+ fprintf which causes each drawing primitive to be printed to
+ stderr.
+
+2014-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pnm.c (ReadPNMImage): Fix scaling of alpha in sub-ranged
+ pixels. Addresses SourceForge issue #237 "Incorrect MAXVAL
+ scaling when reading PAM images", which was not fully fixed in by
+ the previous attempt.
+
+2014-01-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/tsd.c: Implement TSD for "pure" OpenMP mode without
+ relying on POSIX or WIN32 TSD APIs.
+
+ * magick/semaphore.c: Implement OpenMP-based locking so that code
+ can compile in a "pure" OpenMP mode without relying on POSIX or
+ WIN32 locking APIs.
+
+ * configure.ac: --without-threads no longer disables use of
+ OpenMP. Use the already existing option --disable-openmp to
+ disable OpenMP.
+
+2014-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/common.h: Support use of clang/llvm __attribute__ and
+ __builtin extensions similar to the existing support for GCC.
+
+2014-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/Image.cpp (thumbnail): New method for fast image
+ resizing, particularly to make thumbnails.
+
+ * coders/gif.c: Log when Netscape loop exension is read and
+ written.
+
+ * coders/png.c (WriteOnePNGImage): In optimize mode, disable matte
+ channel immediately if there are no non-opaque pixels. Also added
+ some useful logging. Resolves SourceForge issue #252 "convert an
+ 8bit PNG result in a corrupted image ".
+
+ * wand/magick_wand.c (MagickSetImageGravity): New Wand method to
+ set image gravity.
+ (MagickGetImageGravity): New wand method to get image gravity.
+
+2014-01-02 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOnePNGImage): Use libpng function
+ png_set_strip_16_to_8() when scaling 16-bit input PNG down to
+ 8-bit in a Q8 build. The png_set_scale_16_to_8() function is
+ more accurate, but the slight difference causes reference tests
+ to fail and causes unexpected difference between the behavior
+ of PNG and other formats. If png_set_strip_16_to_8() is not
+ supported in libpng, then we use png_set_scale_16_to_8() if
+ that is available.
+
+2014-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * INSTALL-windows.txt: Update for 2014.
+
+ * INSTALL-unix.txt: Update for 2014.
+
+ * Copyright.txt: Update for 2014.
+
+ * NEWS.txt: Update for 2014.
+
+ * README.txt: Update for 2014.
+
+ * doc: Update for 2014.
+
+ * www: Update for 2014.
+
+ * VisualMagick/installer: Update for 2014.
+
+ * ChangeLog: Rotate Changelog to ChangeLog.2013 for 2014.
+
diff --git a/ChangeLog.2015 b/ChangeLog.2015
new file mode 100644
index 0000000..4f36390
--- /dev/null
+++ b/ChangeLog.2015
@@ -0,0 +1,2066 @@
+2015-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * ttf: Update bundled freetype to release 2.6.2.
+
+ * libxml: Update bundled libxml2 to release 2.9.3.
+
+2015-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * webp: Updated bundled libwebp to release 0.4.4.
+
+ * png: Updated bundled libpng to release 1.6.19.
+
+2015-11-05 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOnePNGImage): Added "volatile" to
+ several declarations to stop "might be clobbered" warnings.
+
+2015-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Update NEWS for 1.3.23 release.
+
+2015-11-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (IdentifyImageCommand): Fix problem that
+ identify with -format "%A" does not always report correct answer
+ due to insufficient analysis of image. Fixes SourceForge bug #326
+ "gm identify: transparency detection bug ".
+
+2015-11-05 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOnePNGImage): Restored a "volatile"
+ declaration that was accidentally deleted on 2015-11-03.
+
+2015-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Add checks for 'ps2write' and 'eps2write' as
+ Ghostscript Postscript and Encapsulated Postscript
+ writers. Resolves issue reported to graphicsmagick-bugs mailing
+ list on 2015-11-01 entitled "Failure to detect pswrite and
+ epswrite Ghostscript devices".
+
+2015-11-03 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadRawProfile): Issue a warning instead of
+ an error when attempting to read a zero-length profile.
+
+2015-11-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/studio.h (MagickSleep): Provide the macro 'MagickSleep'
+ to call a function which delays for one second. No longer provide
+ a macro 'sleep' in WIN32 compiles. Resolves issue reported to
+ graphicsmagick-bugs mailing list on 2005-11-01 entitled "MinGW
+ build error when sleep re#defined as Sleep".
+
+2015-10-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/demo/demos.tap: Add zoom test cases to test resize to
+ original dimensions, change height, and change width.
+
+ * magick/resize.c (ScaleImage): Fix regression introduced in
+ 1.3.22 release which results in pixel cache not open if the scale
+ width and height match the original. Patch by Troy Patteson.
+ Fixes part of SourceForge bug #323 "ScaleImage() issues in
+ v1.3.22".
+ (ScaleImage): Fix double free problem when scaled rows equals
+ original rows. This regression was added in the 1.3.22 release
+ via changset 080b99bba574. Based on patch by Troy Patteson.
+ Fixes remaining part SourceForge bug #323 "ScaleImage() issues in
+ v1.3.22".
+
+2015-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/Magick++/Image.rst (thumbnail): Paragraph heading fix.
+ Resolves SourceForge issue #321 "find tiny error in
+ Magick++/Image.html document".
+
+2015-10-06 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * docs/*.imdoc: Changed synopses in manpages to add "gm "
+ prefix to commands. Updated synopsis for "convert" to agree
+ with what's in the "gm" manpage.
+
+2015-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Remove CFLAGS and LDFLAGS deduplication code.
+ Resolves SourceForge bug #320 OS X "universal build failure".
+
+2015-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/index.rst: Updated for 1.3.22 release.
+
+ * NEWS.txt: Updated for 1.3.22 release.
+
+2015-09-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Brought up to date with changes thus far since last
+ release.
+
+ * magick/blob.c (OpenBlob): Disable fflush() of read-only handle
+ under Microsoft Windows, which produced a spurious error status,
+ blocking file reads for Visual Studio 2015 on Windows 2012 server.
+ Problem was reported and diagnosed by Dirk Lemstra.
+
+2015-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tiff: Update bundled libtiff sources to 4.0.6 release.
+
+ * magick/module.c (InitializeModuleSearchPath): Fix compilation
+ problem when UseInstalledMagick is not defined.
+
+2015-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xpm.c: Static string/array allocations are now more
+ const.
+
+ * coders/{ps.c, ps2.c, ps3.c}: Static string/array allocations are
+ now more const.
+
+ * coders/palm.c: Palm static arrays should be 'const'.
+
+ * coders/meta.c (jpeg_embed): Stop sharing writeable static string
+ 'psheader'.
+ (tag_spec): The 'tags' static array should be all 'const'.
+
+ * coders/jp2.c: Try to reduce the amount of non-const static data.
+
+ * coders/dcm.c (dicom_info): Try to make dicom_info array more
+ 'const'.
+
+ * coders/dpx.c: Eliminate use of static buffer strings.
+
+ * coders/png.c: Make MNG chunk id strings constant rather than
+ initialized data.
+
+ * magick/render.c (DrawAffineImage): Fix problem that sometimes
+ output rows are skipped when using OpenMP. Problem identification
+ and patch by Kevin Matzen. Resolves SourceForge issue #316
+ "-affine sometimes produces output with missing rows".
+
+2015-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/rwblob.tap: Add specific tests for BMP2 BMP3 subformats.
+
+ * tests/rwfile.tap: Add specific tests for BMP2 BMP3 PS2 PS3
+ subformats.
+
+2015-08-30 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * magick/ImageMagick.rc Replace Imagemagick.ico by GraphicsMagick.ico
+
+ * magick/Imagemagick.ico is no longer needed and not referenced anywhere.
+
+2015-08-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * README.txt: Fix SourceForge bug 314 "README: bad hg clone URL".
+
+ * magick/module.c (GetModuleListForDirectory): Fix Coverity 107017
+ "Copy into fixed size buffer" and 107013 "Overlapping buffer in
+ memory copy".
+ (UnloadModule): Fix SourceForge bug 312 "uninitialized variable
+ "name" in UnloadModule".
+
+ * coders/bmp.c (WriteBMPImage): Fix typo in fix on 2015-08-17.
+ Fixes Coverity 107014 "Test should be assignment".
+
+ * magick/module.c (OpenModules): Fix Coverity 107016 "Resource
+ leak".
+ (GetModuleListForDirectory): Fix Coverity 107015 "Resource leak".
+
+2015-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/bmp.c (WriteBMPImage): Fix inverted alpha channel when
+ writing BGRA8888 format. Problem was reported by 张铎 via the
+ graphicsmagick-help discussion list on 2015-08-17.
+
+2015-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (GenerateEXIFAttribute): Verify that entry
+ pointer is within the metadata buffer in order to avoid buffer
+ overflow. Resolution and patch by Federico Larumbe.
+
+ * magick/profile.c (SetImageProfile): Avoid crash given NULL
+ profile pointer. Resolution and patch by Federico Larumbe.
+
+2015-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (GenerateEXIFAttribute): Fix logic problem
+ while validating EXIF GPS_OFFSET. Problem reported by Federico
+ Larumbe.
+
+2015-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): Applied fix
+ (http://hg.code.sf.net/u/zacmorris/graphicsmagick/rev/edcc4c184b42)
+ by Zac Morris to detect buffer overrun while reading zip
+ compressed data.
+ (ReadMIFFImage): Fixed some memory leaks which were occuring when
+ an exception was thrown from zip-compressed data reader.
+
+2015-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WritePTIFImage): Fix SourceForge issue #269
+ "Convert creates SubfileType 0x2 instead of 0x1". From looking at
+ the code, this is a regression since the time support for the page
+ subfile type was added (probably via changeset 11831
+ (037eef0f67f2) on 2007-08-17).
+
+2015-07-19 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * dcraw/dcraw.c: Fixed bad define WIN32.
+
+2015-07-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt, www/Hg.rst, www/index.rst: Applied English bugs patch
+ by Amadu Jalloh.
+
+ * dcraw/dcraw.c: Add a port replacement for strnlen().
+
+2015-07-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * wand/magick_wand.h: The declaration for MagickGetImageGravity()
+ was missing. Resolves SourceForge bug #308 magick_wand.h misses
+ declaration of MagickGetImageGravity.
+
+2015-07-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * dcraw: Update bundled dcraw to release 9.26.0.
+
+ * png: Updated bundled libpng to release 1.6.17.
+
+ * lcms: Update bundled lcms2 to release 2.7.
+
+2015-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Brought up to date with changes thus far since last
+ release.
+
+ * magick/version.h.in (MagickCopyright): Update most recent
+ copyright year.
+
+ * magick/render.c (DrawAffineImage): Fix problem with negative x
+ offset. Resolves SourceForge issue #306 "gm fails to convert svg
+ to jpeg if svg has images with negative coordinates".
+
+ * magick/pixel_cache.c (ReadCachePixels): Add checks for integer
+ overflows.
+
+2015-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/module.c (ModuleAliases): Add a module alias for GRAYA.
+
+2015-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/montage.c (MontageImages): Fix Coverity 101317 "Resource
+ leak".
+
+ * magick/blob.c: Limit the data size passed to the read/write
+ calls to the filesystem blocksize and make multiple calls if
+ required.
+
+ * magick/pixel_cache.c: Limit the data size passed to the
+ read/write, pread/prwite calls and make multiple calls if
+ required.
+
+2015-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (WriteBlobFile): Properly handle short read. Read
+ data in units of filesystem block size.
+ (BlobToFile): Write data in units of filesystem block size.
+
+ * patches: Added directory of patches which may be useful when
+ integrating new versions of 3rd-party programs or libraries into
+ the VisualMagick build.
+
+ * libxml: Re-applied libxml changes which were used in prior
+ release.
+
+2015-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * webp: Updated bundled libwebp to release 0.4.3.
+
+ * ttf: Update bundled freetype to release 2.6.
+
+ * libxml: Update bundled libxml2 to release 2.9.2.
+
+ * tiff/VERSION: Update bundled libtiff to release 4.0.4.
+
+ * magick/nt_base.h (HAVE_TIFFISCODECCONFIGURED): Enable use of
+ TIFFIsCODECConfigured in MSVC build.
+
+ * coders/tiff.c: I am too lazy to modify VisualMagick configure so
+ it is possible to include jpeglib.h in tiff.c, so block out this
+ low-value code just for MSVC builds.
+
+2015-06-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac, magick/profile.c: Removed support for lcms 1.X.
+ No one should be using a lesser version than lcms 2.0.
+
+2015-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/blob.c (DisassociateBlob): Applied patch by Dirk Lemstra
+ to assure that the image blob is no longer shared with other
+ images when the image is written. This helps with thread safety.
+
+2015-06-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c: Add/fix utility usage messages for -box,
+ -convolve, -gravity, -linewidth, -list, -mattecolor, -render and
+ -shave. Resolves SourceForge issue #302 "MogrifyUsage prints
+ incomplete information ".
+
+2015-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Include JPEG headers to obtain
+ its BITS_IN_JSAMPLE definition. This is needed so we can know
+ what JPEG depth libtiff supports.
+
+ * www/index.rst: Add mention of GraphicsMagick having zero defects
+ reported by Coverity.
+
+2015-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/STL.cpp (adaptiveThresholdImage): Add a new
+ constructor which accepts a 'double' offset value. The previous
+ version of this constructor is deprecated and subject to removal
+ in the future. The size of the class is enlarged to store a
+ 'double' and so this is a break in the ABI when this class was
+ used. Code using this class should be re-compiled.
+
+ * Magick++/lib/Image.cpp (adaptiveThreshold): Add a new version of
+ this method which accepts a 'double' offset value. The previous
+ version of the method is deprecated and subject to removal in the
+ future. Problem was reported by Dirk Lemstra.
+
+2015-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/gray.c (ReadGRAYImage): Based on feedback from Glenn,
+ return a gray image from the reader, even if a channelized format
+ specifier is given.
+
+2015-05-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/gray.c (ReadGRAYImage): Fix read glitch caused by
+ incorrect memset(). Added missing break statement to switch.
+ Added more logging.
+ (RegisterGRAYImage): Register "gray" formats R, G, B, C, M, Y, K,
+ O such that they are not triggered by file extension. It is
+ necessary to apply a magick prefix to the file name (or set image
+ magick in the API) in order to force using these formats. This
+ avoids accidents in case the file extension was used for some
+ other purpose.
+
+2015-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/gray.c: Added support for "GRAYA" format. Format
+ specifiers "R", "G", "B", "A", "C", "M", and "Y" may now be used
+ to save and restore the associated channel using the same raw
+ format as "GRAY". These format specifiers were already supported
+ but did not appear to serve any useful function.
+
+2015-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Improve handling of libxml2 dependencies. Only
+ test for and use libwmflite. Full-up libwmf is no longer used.
+ * configure.ac: Deduplicate CFLAGS and LDFLAGS.
+
+2015-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOnePNGImage): Eliminate a "clobber"
+ compilation warning.
+
+ * coders/jpeg.c (WriteJPEGImage): Eliminate a "clobber"
+ compilation warning.
+
+ * configure.ac: Don't compute libwmf2 and libxml2 linkage path
+ based on claimed installation prefix. This is hoped to improve
+ configure reliability on multi-arch type systems.
+
+2015-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Use the first -I, -L, and -l arguments produced by
+ freetype-config and don't produce arguments based on installation
+ prefix. This is hoped to improve configure reliability on
+ multi-arch type systems.
+
+2015-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/tempfile.c (AcquireTemporaryFileDescriptor): P_tmpdir is
+ not an environment variable. Need to consider Windows environment
+ variables for Cygwin.
+
+ * magick/random.c (InitializeMagickRandomKernel): For Microsoft
+ Windows, use CryptGenRandom() to salt the built-in random number
+ generator.
+
+2015-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (MagickRandReentrant): Quiet Coverity 10092
+ "Calling risky function".
+ (MagickRandNewSeed): Quiet Coverity 10093 "Calling risky
+ function".
+
+ * coders/tga.c (ReadTGAImage): Quiet Coverity 10201 "Identical
+ code for different branches".
+
+ * coders/pcx.c (ReadPCXImage): Quiet Coverity 10218 "Identical
+ code for different branches".
+
+2015-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetGeometry): Fix handling of area geometries
+ in the form "5000000@". Resolves SourceForge issue #299 "-resize
+ with @ and > in geometry specification".
+
+2015-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Disable matte channel for
+ compression types which don't support it. Resolves SourceForge
+ bug #297 "GM distorts image using -transform".
+ (WriteTIFFImage): When type is Optimize, disable matte channel if
+ image is opaque.
+
+2015-05-09 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * webp/src/utils/endian_inl.h: Fixed defect in intrinsic function
+ byteswap_ulong for Visual Studio less than 2005.
+
+2015-05-08 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * VisualMagick/configure/system_page.cpp,
+ VisualMagick/configure/system_page.h: Suppress reloading .vcproj
+ when configuration type does not change.
+
+2015-05-08 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * VisualMagick/configure/system_page.cpp,
+ VisualMagick/configure/system_page.h,
+ VisualMagick/configure/target_page.h: Ability to re-use already
+ given paths. It is highly frustrating to enter path for different
+ configurations again and again.
+
+2015-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/vid.c (ReadVIDImage): Fix use of uninitialized variable
+ reported by MSVC 2003 (but not GCC, Clang, or Coverity).
+
+2015-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): Fix possible leak of profiles in
+ error path.
+
+ * coders/mpc.c (ReadMPCImage): Fix memory leak of values
+ allocation.
+ (ReadMPCImage): Fix possible leak of profiles in error path. Fixes
+ Coverity 80697 "Resource leak".
+
+2015-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): Fix memory leak of values
+ allocation.
+
+2015-05-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (ReadDPXImage): Hopefully quiet Coverity 10305
+ "Untrusted loop bound".
+
+ * coders/tga.c (ReadTGAImage): Hopefully quiet Coverity 53418
+ "Untrusted loop bound".
+
+ * magick/tempfile.c (AcquireTemporaryFileDescriptor): Eliminate
+ all use of operating system provided temporary file allocation
+ functions (all apparently flawed in one way or another) and rely
+ exclusively on our own implementation.
+
+ * magick/constitute.c (ConstituteImage): Quiet Coverity 53399
+ "Logically dead code".
+
+ * coders/webp.c (ReadWEBPImage): Quiet Coverity 53400 "Logically dead
+ code".
+
+ * coders/miff.c (WriteRunlengthPacket): More work to quiet
+ Coverity 10186 and 10214 "Missing break in switch".
+
+2015-05-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/tempfile.c (AcquireTemporaryFileDescriptor): Thoroughly
+ vet temporary file path. Might quiet Coverity 64613 "Use of
+ untrusted string value".
+
+ * wand/magick_compat.c (ParseGeometry): Another try at quieting
+ Coverity 10248 "Copy into fixed size buffer" and 10078
+ "Overlapping buffer in memory copy" in this dead code.
+
+ * magick/tempfile.c (AcquireTemporaryFileDescriptor): Remove
+ unneeded, almost certainly never used, and potentially insecure
+ use of mkstemp(). Will quiet Coverity 10315 "Insecure temporary
+ file".
+
+2015-04-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Keep Ghostscript gibberish from appearing in
+ Configure output.
+
+ * coders/miff.c (WriteRunlengthPacket): Quiet Coverity 10186 and
+ 10214 "Missing break in switch".
+
+ * magick/pixel_cache.c (GetCacheInfo): Quiet Coverity 10208 "Data
+ race condition".
+
+ * magick/blob.c (CloneBlobInfo): Quiet Coverity 10188 "Data race
+ condition".
+ (GetBlobInfo): Quiet Coverity 10191 "Data race condition".
+
+ * magick/image.c (AllocateImage): Quiet Coverity 10196 "Data race
+ condition".
+ (CloneImage): Quiet Coverity 10206 "Data race condition".
+
+ * magick/map.c (MagickMapAllocateMap): Quiet Coverity 10192, 10193
+ and 10228 "Data race condition".
+
+ * configure.ac: Use an algorithm to try to discover the best value
+ for GSCMYKDevice.
+
+ * VisualMagick/bin/delegates.mgk: Recipe for 'gs-cmyk' contained a
+ typo which breaks using '-type ColorSeparation'.
+
+ * coders/pwp.c (ReadPWPImage): Fix Coverity CID 64491 "Integer
+ handling issues".
+
+2015-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xcf.c (load_tile_rle): Quiet Coverity 10259 "Untrusted
+ loop bound".
+
+ * coders/sct.c (ReadSCTImage): Quiet Coverity 10285 "Untrusted
+ loop bound".
+
+ * coders/pwp.c (ReadPWPImage): Quiet Coverity 10299 "Untrusted
+ loop bound".
+
+ * coders/pcd.c (ReadPCDImage): Quiet Coverity 10301 "Untrusted
+ loop bound".
+
+ * coders/tga.c (ReadTGAImage): Quiet Coverity 53418 "Untrusted
+ loop bound".
+
+ * wand/magick_compat.c (ParseGeometry): Fix overlap strcpy() in
+ dead code. Quiets Coverity 10078 "Overlapping buffer in memory
+ copy" and 10248 "Copy into fixed size buffer".
+
+ * magick/segment.c (Classify): Fix Coverity 64317 "Resource leak".
+
+2015-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xcf.c (ReadXCFImage): Fix Coverity 64064 "Resource leak".
+
+ * coders/txt.c (ReadTXTImage): Fix Coverity 64061 "Resource leak".
+
+ * coders/rla.c (ReadRLAImage): Fix Coverity 64063 "Resource leak".
+
+ * coders/dib.c (ReadDIBImage): Fix Coverity 64057 Resource leak".
+
+ * magick/segment.c (Classify): Fix Coverity 64056 "Resource leak".
+
+ * magick/resize.c (SampleImage): Fix Coverity 64053, 64054, and
+ 64062 "Resource leak".
+
+ * magick/render.c (TraceStrokePolygon): Fix Coverity 64055, 64059,
+ and 64060 "Resource leak".
+
+ * magick/magick.c (ListModuleMap): Quiet Coverity 64058 "Resource
+ leak".
+
+2015-04-28 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/dpx.c: Fix Coverity 10305 "Untrusted loop bound".
+
+ * coders/cineon.c: Fix Coverity 10310 "Untrusted loop bound".
+
+2015-04-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/memory.c: All use of user-provided allocation functions
+ is done via MagickFree(), MagickMalloc(), and MagickRealloc().
+
+2015-04-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/colormap.c (MagickConstrainColormapIndex): For out of
+ range condition, specifically return 0 rather than setting index
+ to zero, and then returning index.
+
+ * coders/pcx.c (ReadPCXImage): Fix Coverity 10197 "Negative loop
+ bound".
+
+ * coders/map.c (ReadMAPImage): Allocate pixels after return case
+ for 'ping' mode.
+ (ReadMAPImage): Fix problem added in last commit due to multiple
+ uses of 'packet_size'.
+
+ * magick/floats.c (_Gm_convert_fp16_to_fp32)
+ (_Gm_convert_fp24_to_fp32): Fix Coverity 10094 "Logically dead
+ code".
+
+ * coders/pcx.c (ReadPCXImage): Fix Coverity 10197 "Negative loop
+ bound".
+
+ * coders/wpg.c (UnpackWPG2Raster): Always test for EOF from
+ ReadBlobByte(). Should fix Coverity 10205 "Negative loop bound".
+
+2015-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pcx.c (ReadPCXImage): Add some more integer-overflow
+ safety to computations. Add some casts.
+
+ * coders/meta.c (formatIPTC): Fix Coverity 10221 "Infinite loop".
+
+ * magick/attribute.c (GenerateEXIFAttribute): Fix Coverity 10320
+ "Untrusted array index read" and "Untrusted loop bound".
+
+2015-04-24 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/gif.c (ReadGIFImage): Attempt to fix Coverity issue
+ 10284 by using "opacity = (header[3] & 0xff)".
+
+2015-04-23 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * magick/blob.c (ReadBlobMSBLong, ReadBlobLSBLong): Attempt
+ to fix various "tainted" or "untrusted" variables
+ by masking off all but the lower 32 bits returned.
+
+2015-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xcf.c (ReadXCFImage): Fix Coverity 10216 "Integer
+ overflowed argument".
+
+ * magick/transform.c (FlipImage): Fix Coverity 61461 "Division or
+ modulo by zero".
+
+ * coders/gif.c: Protect against integer overflow in array size
+ calculations. Used unsigned type for colormap index.
+
+2015-04-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/map.c (ReadMAPImage): Maybe quiet Coverity 10326
+ "Untrusted pointer read".
+
+ * magick/utility.c (GlobExpression): See if testing for null
+ terminating character quiets Coverity 10246 "Untrusted value as
+ argument".
+
+ * magick/transform.c (FlipImage): Possibly quiet case #4 of
+ Coverity 10311 "Untrusted value as argument".
+
+ * magick/utility.c (Base64Encode): Quiet Coverity 10296 and 10272
+ "Use of untrusted scalar value".
+
+2015-04-22 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * magick/blob.c (ReadBlobMSBShort, ReadBlobLSBShort): Attempt
+ to fix various "tainted" or "untrusted" variables, e.g., in
+ coders/gif.c and coders/sgi.c by masking off all but the lower
+ 16 bits returned.
+
+2015-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tim.c (ReadTIMImage): Make TIM reader more robust against
+ EOF.
+
+ * coders/sct.c (ReadSCTImage): Make SCT reader more robust against
+ EOF.
+
+ * coders/pwp.c (ReadPWPImage): Test loop for EOF.
+
+ * coders/otb.c (ReadOTBImage): Make error reporting a bit more
+ robust.
+
+ * coders/jnx.c (ExtractTileJPG): Add some EOF checks.
+
+ * coders/cut.c (ReadCUTImage): Limit width/height to range of
+ signed integer.
+
+ * tests/rwfile.tap: Add a R/W file test for ART.
+
+ * tests/rwblob.tap: Add a R/W blob test for ART.
+
+ * coders/art.c (ReadARTImage): Improve error checking.
+
+2015-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/sun.c (ReadSUNImage): Try to quench Coverity 10280
+ "Untrusted loop bound".
+
+ * coders/mpc.c (ReadMPCImage): Port MIFF header reading fixes.
+
+2015-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): MIFF reader failed to read some
+ MIFF headers properly. Fixes SourceForge issue #298 "invalid next
+ size (normal)/memory corruption".
+
+2015-04-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadMNGImage): Fix Coverity 55862 "Resource leak"
+ and quiet Coverity 55825, 55826, and 55827 "Data race condition".
+
+2015-04-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GetToken): Fix an overlapping strlcpy() which
+ caused a crash in pedantic strlcpy() implementations while parsing
+ a SVG-style URL from text. Several other issues remain.
+
+2015-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ParseUnixCommandLine): Fix Coverity 59256
+ "Unused value".
+
+2015-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/display.c (MagickXROIImage): Fix Coverity 10179 "Missing
+ break in switch".
+ (MagickXCropImage): Fix Coverity 10211 "Missing break in switch".
+
+ * magick/utility.c (Base64Decode): Fix Coverity 10203 "Missing
+ break in switch".
+ (Tokenizer): Quench Coverity 10182 "Missing break in switch". Not
+ believed to be an actual problem.
+
+ * magick/command.c (ParseUnixCommandLine): Fix Coverity 10174 and
+ 10178 "Missing break in switch".
+ (ProcessBatchOptions): Fix Coverity 10180 "Missing break in
+ switch".
+ (ParseWindowsCommandLine): Fix Coverity 10220 "Missing break in
+ switch".
+
+ * coders/xwd.c (ReadXWDImage): Fix Coverity 10095 "Division or
+ modulo by zero". 3rd try.
+
+2015-04-14 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOneJNGImage): Fix Coverity 55829 and 55846
+ "Resource leak".
+
+2015-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+ 55831 "Resource leak". 2nd try.
+
+ * coders/vid.c (ReadVIDImage): Fix Coverity 55868 and 55874
+ "Resource leak". 2nd try.
+
+2015-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/psd.c (ReadPSDImage): Fix Coverity 55855 "Resource
+ leak". 2nd try.
+
+ * coders/pict.c (PictPixmapOp): Fix Coverity 55875 and 55883
+ "Resource leak". 2nd try.
+
+ * coders/pcx.c (WritePCXImage): Fix Coverity 55877 "Resource
+ leak". 2nd try.
+
+ * coders/meta.c (format8BIM): Fix Coverity 55842 "Resource
+ leak". 2nd try.
+
+ * coders/mat.c (WriteMATLABImage): Fix Coverity 55850 "Resource
+ leak". 2nd try.
+
+ * coders/dpx.c (ReadDPXImage): Fix Coverity 55878 "Resource leak".
+ 2nd try.
+
+ * coders/preview.c (WritePreviewImage): Fix Coverity 55988
+ "Resource leak".
+
+2015-04-12 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOneJNGImage): Avoid some memory leaks
+ newly reported by Coverity (work in progress)
+
+2015-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resize.c (ScaleImage): Fix Coverity 55824 "Division or
+ modulo by float zero".
+
+ * magick/annotate.c (AnnotateImage): Fix Coverity 55863
+ "Uninitialized scalar variable".
+
+ * wand/magick_wand.c (MagickDrawImage): Fix Coverity 55828
+ "Resource leak".
+ (MagickMontageImage): Fix Coverity 55835 "Resource leak".
+
+ * wand/drawing_wand.c (DrawComposite): Fix Coverity 55849
+ "Resource leak".
+
+ * magick/widget.c (MagickXColorBrowserWidget): Fix Coverity 55854
+ "Resource leak".
+
+ * magick/resize.c (ScaleImage): Fix Coverity 55841, 55853, 55858,
+ and 55860 "Resource leak".
+
+ * magick/render.c (ConvertPathToPolygon): Fix Coverity 55836
+ "Resource leak".
+ (DrawDashPolygon): Fix Coverity 55837 "Resource leak".
+
+ * magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+ 55831 "Resource leak".
+
+ * magick/paint.c (ColorFloodfillImage): Fix Coverity 55886
+ "Resource leak".
+
+ * magick/map.c (MagickMapAddEntry): Possibly silence 55844
+ "Resource leak".
+
+ * magick/image.c (CloneImage): Fix Coverity 55833 "Resource leak".
+
+ * magick/effect.c (BlurImage): Fix Coverity 55851 "Resource leak".
+
+ * magick/display.c (MagickXAnnotateEditImage): Fix Coverity 55830
+ "Resource leak".
+ (MagickXVisualDirectoryImage): Fix Coverity 55894 "Resource leak".
+
+ * magick/constitute.c (ReadImages): Fix Coverity 55834 "Resource
+ leak".
+ (ReadInlineImage): Fix Coverity 55843 "Resource leak".
+
+ * magick/compress.c (HuffmanEncode2Image): Fix Coverity 55839
+ "Resource leak".
+ (HuffmanDecodeImage): Fix Coverity 55859 "Resource leak".
+
+ * magick/color.c (GetColorHistogram): Fix Coverity 55845 "Resource
+ leak".
+ (ComputeCubeInfo): Fix Coverity 55857 "Resource leak".
+
+ * coders/yuv.c (ReadYUVImage): Fix Coverity 55890 "Resource leak".
+
+ * coders/wpg.c (UnpackWPG2Raster): Fix Coverity 55832 and 55848
+ "Resource leak".
+
+2015-04-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/vid.c (ReadVIDImage): Fix Coverity 55868 "Resource leak"
+ (ReadVIDImage): Fix Coverity 55874 "Resource leak".
+
+ * coders/txt.c (ReadTXTImage): Fix Coverity 55866 "Resource leak".
+
+ * coders/topol.c (ReadTOPOLImage): Fix Coverity 55865 "Resource
+ leak".
+
+ * coders/sgi.c (WriteSGIImage): Fix Coverity 55891 "Resource leak".
+
+ * coders/psd.c (ReadPSDImage): Fix Coverity 55855 "Resource leak".
+
+ * coders/pict.c (WritePICTImage): Fix Coverity 55867, 55875, 55883
+ "Resource leak". Fix Coverity 55892 "Resource leak".
+
+ * coders/pdb.c (ReadPDBImage): Fix Coverity 55840, 55856, and
+ 55885 "Resource leak".
+
+ * coders/pcx.c (WritePCXImage): Fix Coverity 55877 "Resource
+ leak".
+
+ * coders/mvg.c (ReadMVGImage): Fix Coverity 55873 "Resource leak".
+
+ * coders/mpeg.c (WriteMPEGImage): Fix Coverity 55880 "Resource
+ leak".
+
+ * coders/miff.c (WriteMIFFImage): Fix Coverity 55864 "Resource
+ leak".
+ (WriteMIFFImage): Fix Coverity 55872 "Resource leak".
+
+ * coders/meta.c (formatIPTCfromBuffer): Fix Coverity 55838
+ "Resource leak".
+ (format8BIM): Fix Coverity 55842 and 55852 "Resource leak".
+ (formatIPTC): Fix Coverity 5882 "Resource leak".
+
+ * coders/mat.c (ReadMATImage): Fix Coverity 55850 "Resource leak".
+
+ * coders/map.c (ReadMAPImage): Fix Coverity 55876 "Resource leak".
+
+ * coders/logo.c (ReadLOGOImage): Fix Coverity 55870 "Resource
+ leak".
+
+ * coders/label.c (ReadLABELImage): Fix Coverity 55869 "Resource
+ leak".
+
+ * coders/icon.c (ReadIconImage): Fix Coverity 55887 "Resource
+ leak".
+
+ * coders/fits.c (WriteFITSImage): Fix Coverity 55884 "Resource
+ leak".
+
+ * coders/dpx.c (WriteDPXImage): Fix Coverity 55861 "Resource
+ leak".
+ (ReadDPXImage): Fix Coverity 55878 "Resource leak".
+ (ReadDPXImage): Fix Coverity 55879 "Resource leak".
+
+ * coders/dib.c (WriteDIBImage): Fix Coverity 55881 "Resource
+ leak".
+ (WriteDIBImage): Fix Coverity 55895 "Resource leak".
+
+ * coders/cut.c (ReadCUTImage): Fix Coverity 55893 "Resource leak".
+
+ * coders/caption.c (ReadCAPTIONImage): Fix Coverity 55888
+ "Resource leak".
+ (ReadCAPTIONImage): Fix Coverity 55889 "Resource leak".
+ (ReadCAPTIONImage): Fix Coverity 55896 "Resource leak".
+
+ * magick/annotate.c (RenderX11): Silence Coverity 10106 "Logically
+ dead code".
+
+ * coders/xcf.c: Silence Coverity 10224, 10233, and 10236 "Improper
+ use of negative value".
+
+ * coders/mat.c (ReadMATImage): Silence Coverity 10175 "Improper
+ use of negative value"
+
+ * coders/tga.c (ReadTGAImage): Silence Coverity 10088 "Operands
+ don't affect result".
+
+ * magick/annotate.c (RenderFreetype): Silence Coverity 14396 and
+ 44755 "Unused value".
+
+ * coders/wpg.c (LoadWPG2Flags): Silence Coverity 10273 and 10253
+ "Unused value".
+
+ * magick/montage.c (MontageImages): Silence Coverity 10255 "Unused
+ value".
+ (MontageImages): Silence Coverity 10264 "Unused value".
+
+2015-04-09 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOneJNGImage): Avoid using a NULL alpha_image
+ or color_image. (ReadJNGImage): Removed an extraneous CloseBlob().
+
+2015-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (MagickCreateDirectoryPath): Silence Coverity
+ 10098 "Logically dead code".
+
+ * magick/resource.c (InitializeMagickResources): Silence Coverity
+ 10101 "Logically dead code".
+
+ * magick/magick.c (MagickSignalHandlerMessage): Fix Coverity 44725
+ "Logically dead code".
+
+ * magick/log.c (DestroyLogInfo): Silence Coverity 53659 and 53661
+ "Data race condition".
+ (ReadLogConfigureFile): Silence Coverity 53660 "Data race
+ condition".
+
+ * magick/effect.c (DespeckleImage): Fix error handling issue
+ caused by shadowed variable. Fixes Coverity 10099 "Logically dead
+ code".
+
+ * magick/command.c (TimeImageCommand): Fix Coverity 10097
+ "Logically dead code".
+
+ * magick/attribute.c (ReadMSBLong): Hopefully silence Coverity
+ 10276 "Unintended sign extension".
+
+ * coders/sgi.c (ReadSGIImage, WriteSGIImage): Fix Coverity 10243,
+ 10244, 10247, 10254, and 10294 "Unintended sign extension".
+
+2015-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/xwindow.c (MagickXMakeImage): Quiet Coverity 10282
+ "Unused value".
+
+2015-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Another change targeting
+ Coverity 44742 and 44746 "Unintended sign extension".
+
+2015-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/render.c (TracePath): Fix Coverity 10258 "Uninitialized
+ scalar variable".
+
+ * magick/widget.c (MagickXFontBrowserWidget): Fix Coverity 10323
+ "Sizeof not portable". 2nd try.
+
+ * coders/xwd.c (ReadXWDImage): Fix Coverity 10095, 10100, 10104
+ "Division or modulo by zero". 2nd try.
+
+ * magick/analyze.c (GetImageCharacteristics): Fix Coverity 10096
+ "Logically dead code".
+
+ * coders/yuv.c (ReadYUVImage): Fix Coverity 10260 "Structurally
+ dead code".
+
+ * coders/xcf.c (ReadXCFImage): Fix Coverity 10226 "Missing break
+ in switch".
+
+ * coders/tim.c (ReadTIMImage): Fix Coverity 10249 "Unused value".
+
+ * coders/tiff.c (CompressionSupported): Fix Coverity 44723
+ "Logically dead code".
+ (WriteTIFFImage): Fix Coverity 44742 and 44746 "Unintended sign
+ extension".
+
+ * coders/ps3.c (WritePS3Image): Validate results from TellBlob()
+ and SeekBlob(). Should quiet Coverity 10198 "Improper use of
+ negative value".
+
+ * coders/ps2.c (WritePS2Image): Validate results from TellBlob()
+ and SeekBlob(). Should quiet Coverity 10230 "Improper use of
+ negative value".
+
+ * coders/mpeg.c (WriteMPEGImage): Quiet Coverity 10176 "Missing
+ break in switch".
+
+ * coders/map.c (WriteMAPImage): Make MAP reader/writer more
+ robust. May quiet 10326 "Untrusted pointer read".
+
+ * coders/locale.c (ReadLOCALEImage): Quiet Coverity 10108
+ "Logically dead code".
+
+ * coders/rle.c: Make URT RLE reader more robust. Should quiet
+ Coverity CID 10070 "Bad bit shift operation", as well as 10235
+ "Improper use of negative value".
+
+2015-04-04 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (WriteOneJNGImage): Quiet Coverity CID issue 14370,
+ "Unused value" (status was ignored).
+
+ * coders/png.c (ReadOneJNGImage): Quiet Coverity CID issue 44724,
+ "Logically dead code" (skip_to_iend can't be true).
+
+ * coders/png.c (ReadOnePNGImage): Attempt to quiet Coverity
+ CID 10232 "Missing unlock", by using png_error() instead of
+ throwing an exception.
+
+2015-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xwd.c (ReadXWDImage): Fix Coverity 10104 "Division or
+ modulo by zero".
+
+ * magick/resize.c (ResizeImage): Fix Coverity 53404 "Division or
+ modulo by zero".
+
+ * coders/ps3.c (WritePS3MaskImage): Fix Coverity 53415 "Improper
+ use of negative value".
+
+ * coders/meta.c (parse8BIM): Fix Coverity 53413 "Improper use of
+ negative value".
+ (parse8BIMW): Fix Coverity 53414 "Improper use of negative value".
+
+ * magick/utility.c (GetMagickGeometry): Fix Coverity 53403 and
+ 53405 "Division or modulo by float zero".
+ (GetPathComponent): Fix Coverity 53417 "Wrong sizeof argument.
+
+ * magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+ 10256 "Wrong sizeof argument".
+
+ * magick/image.c (ResetImagePage): Fix Coverity 53401 "Division or
+ modulo by float zero" and 53402 "Division or modulo by float
+ zero".
+
+ * coders/histogram.c (WriteHISTOGRAMImage): Silence Coverity 10107
+ "Division or modulo by float zero". 2nd try.
+
+ * magick/xwindow.c (MagickXImportImage): Silence Coverity 10207
+ "Array compared against 0".
+
+ * magick/widget.c (MagickXColorBrowserWidget): Silence Coverity
+ 53406 "Identical code for different branches".
+ (MagickXListBrowserWidget): Silence Coverity 53407 "Identical code
+ for different branches".
+
+ * magick/animate.c (MagickXMagickCommand): Silence Coverity 53410
+ "Identical code for different branches".
+
+ * coders/rgb.c (WriteRGBImage): Silence Coverity 53409 "Identical
+ code for different branches".
+
+ * coders/cmyk.c (WriteCMYKImage): Silence Coverity 53408
+ "Identical code for different branches".
+
+ * magick/xwindow.c (MagickXMakeImage): Silence Coverity 44727
+ "Dereference after null check". 2nd try.
+
+ * magick/utility.c (EscapeString): Silence Coverity 53416
+ "Dereference before null check".
+
+ * coders/gif.c (WriteGIFImage): Fix Coverity 10219 "Dereference
+ null return value".
+
+ * magick/log.c (InitializeLogInfo): Hopefully silence Coverity
+ 53411 and 53412 "Data race condition".
+
+ * coders/cineon.c (AttributeToString): Silence Coverity 10079
+ "Buffer not null terminated". 2nd try. The buffer is not
+ required to be null terminated!
+
+ * coders/pict.c (ReadPICTImage): 10171 "Resource leak". 2nd try.
+
+ * coders/wmf.c (util_set_brush): Silence Coverity 44739
+ "Out-of-bounds access". 2nd try.
+
+2015-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/log.c (SetLogEventMask): Silence Coverity 10069 "Value
+ not atomically updated". Logging initialization is done
+ single-threaded entirely in InitializeLogInfo() now.
+
+2015-03-28 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOnePNGImage): Attempt to quiet Coverity
+ 44734 "Data race condition" by freeing mng_info->png_pixels
+ and mng_info->quantum_scanline separately from MngInfoFreeStruct.
+
+2015-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/widget.c (XEditText): Silence Coverity 10072 "Overlapping
+ buffer in memory copy"
+
+ * coders/locale.c (ReadConfigureFile): Silence Coverity 10075
+ "Overlapping buffer in memory copy".
+
+ * magick/xwindow.c (MagickXMakeWindow): Silence Coverity 10076
+ "Overlapping buffer in memory copy".
+
+ * coders/dcm.c (funcDCM_TransferSyntax): Silence Coverity 10083
+ "Unchecked return value".
+
+ * magick/static.c (ExecuteStaticModuleProcess): Silence Coverity
+ 10082 "Unchecked return value".
+
+ * coders/cals.c (ReadCALSImage): Silence Coverity 10086 "Unchecked
+ return value from library".
+ (ReadCALSImage): Silence Coverity 10085 "Unchecked return value".
+ (ReadCALSImage): Silence Coverity 10084 "Unchecked return value
+ from library".
+
+ * magick/enhance.c (ModulateImage): Silence Coverity 10087
+ "Unchecked return value".
+
+2014-03-24 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * coders/wpg.c More paranoa in checking ReadBlobByte() negative return.
+
+2015-03-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (Generate8BIMAttribute): Silence Coverity
+ 10195 "Argument cannot be negative".
+
+ * Magick++/lib/Image.cpp (syncPixels): Silence Coverity 44722
+ "Unchecked return value".
+ (fontTypeMetrics): Silence Coverity 44721 "Unchecked return
+ value".
+
+ * magick/render.c (ConvertPathToPolygon): Silence Coverity 10120
+ "Dereference after null check".
+
+ * magick/effect.c (EmbossImage): Silence Coverity 10114
+ "Dereference after null check".
+ (AdaptiveThresholdImage): Silence Coverity 10118 "Explicit null
+ dereferenced".
+
+ * coders/msl.c (MSLPushImage): Silence Coverity 10128 "Dereference
+ after null check".
+
+ * magick/render.c (DrawPolygonPrimitive): Silence Coverity 10136
+ "Dereference after null check".
+
+ * wand/drawing_wand.c (DrawSetStrokeDashArray): Silence Coverity
+ 10117 "Dereference after null check".
+
+ * magick/draw.c (DrawSetStrokeDashArray): Silence Coverity 10150
+ "Dereference after null check".
+
+ * wand/drawing_wand.c (DrawPushGraphicContext): Silence Coverity
+ 10151 "Dereference after null check".
+
+2015-03-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/meta.c (parse8BIM): Silence Coverity 10159 "Explicit null
+ dereferenced".
+ (parse8BIMW): Silence Coverity 10144 "Explicit null dereferenced".
+
+ * coders/uil.c (WriteUILImage): Silence Coverity 10202
+ "Dereference after null check". In fact, UIL output was not
+ working at all due to this bug.
+
+ * magick/xwindow.c (MagickXMakeImage): Silence Coverity 44727
+ "Dereference after null check".
+
+ * Magick++/lib/Image.cpp (colorMapSize): Silence Coverity 44728
+ "Dereference after null check".
+
+ * coders/vid.c (ReadVIDImage): Silence Coverity 44730 "Explicit
+ null dereferenced".
+
+ * coders/mpc.c (ReadMPCImage): Silence Coverity 44732 "Dereference
+ after null check".
+
+ * Magick++/lib/Image.cpp (signature): Silence Coverity 44735
+ "Dereference null return value".
+
+ * coders/ps.c (ReadPSImage): Ghostscript options concatenation
+ should be more secure against buffer overflow.
+
+ * coders/pdf.c (ReadPDFImage): Applied patch by Chris Gilling such
+ that '-define pdf:stop-on-error=true' will stop PDF processing
+ immediately upon an error.
+ (ReadPDFImage): Ghostscript options concatenation should be more
+ secure against buffer overflow.
+
+2015-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/animate.c (MagickXAnimateImages): Silence Coverity 44736
+ "Dereference null return value". Also fixed apparent memory leak
+ that Coverity did not notice.
+
+ * coders/fits.c (ReadFITSImage): Silence Coverity 10209
+ "Dereference before null check".
+
+ * magick/color_lookup.c (ReadColorConfigureFile): Silence Coverity
+ 44743 "Dereference before null check".
+
+ * magick/xwindow.c (MagickXMakeImage): Silence Coverity 44745
+ "Dereference before null check".
+
+ * coders/pict.c (ReadPICTImage): Hopefully address consequences of
+ Coverity 10292 "Untrusted loop bound" although it will likely
+ still complain.
+
+ * magick/utility.c (LocaleCompare, LocaleNCompare): Try to create
+ an implementation that Coverity won't label an "tainted sink", and
+ therefore result in a Coverity "Use of untrusted scalar value"
+ report whenever a string from an external source is compared. The
+ original implementations are not believed to be faulty.
+
+2015-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/command.c (ProcessBatchOptions): Silence Coverity 10080
+ "Buffer not null terminated".
+
+ * magick/widget.c (MagickXConfirmWidget): Silence Coverity 10089
+ "Copy-paste error". This is an amazing find by Coverity.
+
+ * magick/xwindow.c (MagickXImportImage): Silence Coverity 10207
+ "Array compared against 0".
+
+ * magick/quantize.c (GrayscalePseudoClassImage): Silence Coverity
+ 10256 "Wrong sizeof argument".
+
+ * coders/tiff.c (ReadTIFFImage): Fix Coverity 44747 and 44748
+ "Extra sizeof expression".
+
+2015-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/Magick++/Include.h (Magick): Fix compilation with
+ 'clang' under Linux. Build was broken yesterday.
+
+ * coders/tiff.c (QuantumTransferMode): Fix reading Old JPEG and
+ YCbCr sample images from libtiff pics-3.8.0.tar.gz image file
+ collection. There was a regression for YCbCr added in last
+ release.
+
+2015-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/bmp.c (ReadBMPImage): Fix Coverity 44726 "Division or
+ modulo by float zero". I don't think that this can actually
+ happen due to prior checks.
+
+ * magick/xwindow.c (MagickXMakeWindow): Silence Coverity 10281
+ "Copy into fixed size buffer".
+
+ * coders/pdf.c (ReadPDFImage): Silence Coverity 10241 "Copy into
+ fixed size buffer".
+
+ * magick/type.c (ReadTypeConfigureFile): Silence Coverity 10242
+ "Copy into fixed size buffer".
+
+ * magick/utility.c (GetPathComponent): Silence Coverity 10263
+ "Copy into fixed size buffer".
+
+ * coders/txt.c (ReadTXTImage): Silence Coverity 10287 "Copy into
+ fixed size buffer".
+
+ * coders/ps.c (WritePSImage): Silence Coverity 10289 "Copy into
+ fixed size buffer".
+
+ * magick/delegate.c (ReadConfigureFile): Silence Coverity 10297
+ "Copy into fixed size buffer".
+
+ * magick/log.c (ReadLogConfigureFile): Silence Coverity 10300
+ "Copy into fixed size buffer".
+
+ * coders/ps3.c (WritePS3Image): Silence Coverity 10303 "Copy into
+ fixed size buffer".
+
+ * coders/pdf.c (WritePDFImage): Silence Coverity 10304 "Copy into
+ fixed size buffer".
+
+ * coders/ps.c (ReadPSImage): Silence Coverity 10306 "Copy into
+ fixed size buffer".
+
+ * coders/msl.c (MSLStartElement): Silence Coverity 10308 "Copy
+ into fixed size buffer".
+
+ * coders/ps2.c (WritePS2Image): Silence Coverity 10309 "Copy into
+ fixed size buffer".
+
+ * Magick++/lib/Geometry.cpp (operator): Silence Coverity 44749
+ "Copy into fixed size buffer".
+
+ * Magick++/lib/Image.cpp (annotate): Silence Coverity 44750 "Copy
+ into fixed size buffer".
+
+ * coders/ept.c (ReadEPTImage): Silence Coverity 44751 "Copy into
+ fixed size buffer".
+
+ * coders/wmf.c (ipa_device_begin): Silence Coverity 44753 "Copy
+ into fixed size buffer".
+ (lite_font_map): Silence Coverity 44752 "Copy into fixed size
+ buffer".
+
+ * magick/random.c (InitializeMagickRandomKernel): Silence Coverity
+ 10091 "Don't Call" in the case where /dev/random is available.
+
+ * coders/mpeg.c (WriteMPEGParameterFiles): Fix Coverity 10190
+ "Resource leak". File descriptor was leaked under certain error
+ conditions.
+
+ * coders/wpg.c (UnpackWPG2Raster): Fix Coverity 10312
+ "Uninitialized scalar variable" gripe.
+
+ * magick/utility.c (ListFiles): Possibly address
+ Coverity 10245 "Sizeof not portable" gripe.
+
+ * magick/widget.c (MagickXFontBrowserWidget): Possibly address
+ Coverity 10323 "Sizeof not portable" gripe.
+
+ * coders/mat.c (WriteMATLABImage): FormatString() requires a
+ buffer of MaxTextExtent bytes. Use sprintf instead. Fix for
+ Coverity issue 10170.
+
+ * Magick++/lib/Geometry.cpp (string): FormatString() requires a
+ buffer of MaxTextExtent bytes. Fix for Coverity issue 44737.
+
+ * coders/wmf.c (draw_pattern_push): FormatString() requires a
+ buffer of MaxTextExtent bytes. Fix for Coverity issue 44741.
+ (ipa_device_begin): FormatString() requires a buffer of
+ MaxTextExtent bytes. Fix for Coverity issue 44740.
+ (util_set_brush): FormatString() requires a buffer of
+ MaxTextExtent bytes. Fix for Coverity issue 44739.
+ (ipa_region_clip): FormatString() requires a buffer of
+ MaxTextExtent bytes. Fix for Coverity issue 44738.
+
+2015-03-15 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (WritePNGImage) Avoid a Coverity gripe about
+ potential NULL dereference (actually it is impossible because
+ png_error() does not return. Fix for Coverity gripe 44731.
+
+ * coders/png.c (WritePNGImage) Avoid a null pointer dereference
+ while logging inherited color_type. Fix for Coverity issue 10185.
+
+ * coders/png.c (WriteOneJNGImage) Avoid possible unintended sign
+ extension. Fix for Coverity issue 44744.
+
+ * coders/png.c (WriteOnePNGImage) Quiet a false Coverity warning
+ about dereference after NULL check. Fix for Coverity issue 44729.
+
+ * coders/png.c (ReadOnePNGImage): Redid the "Respect the
+ PixelsResource limit" patch of March 7, using unsigned arithmetic
+ to determine the width limit. Sometimes the calculated
+ width limit was incorrectly zero.
+
+2015-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (SetImageInfo): Fix problems with reading
+ filenames that include a colon. Resolves SourceForge bug #294
+ "display and convert (probably other things too) choke on
+ filenames with colons in".
+
+ * magick/utility.c (GetPathComponent): Fix SubImagePath
+ extraction. Fixes SourceForge bug #66 "converting runs slowly when
+ subimage is specified".
+
+2015-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * doc/options.imdoc (-geometry): Document the significance of 'x'
+ as used in a geometry specification. In particular, document that
+ if width is specified without a trailing 'x' that height is set to
+ width. This is in response to SourceForge bug #296 "Strange
+ -resize WIDTH results with version 1.3.21".
+
+2015-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (GlobExpression): Remove use of IsSubimage().
+
+ * magick/image.c (IsSubimage): Re-implement with a more robust
+ solution. Combined with fixes to ps.c and pdf.c, allows selecting
+ specific pages, as well as re-ordering.
+
+ * coders/ps.c (ReadPSImage): Set image frame scene ids
+ appropriately.
+
+ * coders/pdf.c (ReadPDFImage): Set image frame scene ids
+ appropriately.
+
+ * magick/utility.c (TranslateTextEx): -format %Q should report
+ JPEG quality estimate if it is available. Resolves SourceForge
+ bug #293 "gm identify bug?".
+
+ * doc/options.imdoc: Documented JPEG-specific -format tags.
+
+2015-03-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/Image.cpp (repage): New method to reset page
+ settings. Contributed by Dirk Lemstra.
+
+2015-03-07 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOnePNGImage): Respect the PixelsResource
+ limit.
+
+ * coders/png.c (ReadOnePNGImage): Moved quantum_scanline
+ and png_pixels into the MngInfo struct. This prevents
+ memory leaks when reading malformed PNG images, but unfortunately
+ triggers a new complaint about a possible race condition.
+
+ * coders/png.c (ReadOnePNGImage): Removed two superflous calls to
+ CloseBlob().
+
+ * coders/png.c (ReadOnePNGImage): Do the allocation and free of
+ quantum_scanline outside the "pass" loop, i.e., do it once per
+ image rather than once per pass while decoding interlaced PNG
+ images. Log these when -debug coders is enabled.
+
+ * coders/png.c: Fixed typo recently introduced in the JNG reader
+ (status != MagickFalse should be status == MagickFalse).
+
+2015-03-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xwd.c (ReadXWDImage): Fix memory leaks in error paths.
+
+ * coders/xpm.c (ReadXPMImage): Fix memory leaks in error paths.
+
+ * coders/miff.c (ReadMIFFImage): Fix memory leak of Image in error
+ case.
+ (ReadMIFFImage): Fix memory leaks of zlib and bzlib2 context in
+ error path which reports decompression failure.
+
+ * coders/bmp.c (ReadBMPImage): BMP reader was wrongly rejecting
+ RLE-compressed files as being too small. Fixes SourceForge bug
+ #295 "1.3.21 identify regression". Also fixed 'ping' support code
+ which was still reading the pixels in 'ping' mode.
+ (ReadBMPImage): Fix memory leak when BMP is handled as a sequence.
+
+2015-03-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/palm.c (ReadPALMImage): PALM reader now applies PALM's
+ special non-linear colormap if the file does not provide a custom
+ colormap. Custom colormap size is verified to not exceed image
+ colors. Added logging statements regarding colormap.
+
+2015-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * www/index.rst: Update for 1.3.21 release.
+
+ * www/Changes.rst: Update for 1.3.21 release.
+
+ * NEWS.txt: Update NEWS for 1.3.21 release.
+
+ * version.sh: Bump/adjust library versioning.
+
+2015-02-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/delegate.c: Fix compilation under Cygwin. Thanks to Marco
+ Atzeri for advising us of this problem.
+
+2015-02-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/error.h (ThrowReaderException): More significant
+ exceptions (e.g. errors) should overwrite less significant
+ exceptions (e.g. warnings) thrown earlier.
+
+ * coders/bmp.c (ReadBMPImage): Detect 32-bit integer overflows and
+ other annoyances caused by intentionally broken files. Also, only
+ warn if the file header claims the file is larger than it is since
+ this is a benign issue.
+
+ * magick/blob.c (OpenBlob): Fix "magic header bytes" log message
+ count value.
+
+2015-02-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * NEWS.txt: Updated NEWS with more changes.
+
+ * Magick++/lib/Magick++/Include.h (Magick): Add GetImageGeometry
+ to MagickLib namespace in order to avoid a compilation problem
+ noticed with Visual C++ 6.0.
+
+2014-02-22 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ * VisualMagick\configure\configure.cpp Fixed crash.
+ Renamed debug to configure_d.exe to prevent mess.
+
+2015-02-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (InitializeMagick): Invoke
+ NTInitializeExceptionHandlers() under Windows.
+
+ * magick/nt_base.c (NTInitializeExceptionHandlers): Add a new
+ private function which disables pop-up Windows on exceptions and
+ registers a handler for Windows exceptions to clean up temporary
+ files prior to program exit.
+
+ * magick/magick.c (PanicDestroyMagick): Use
+ PurgeTemporaryFilesAsyncSafe() rather than PurgeTemporaryFiles().
+ (InitializeMagickSignalHandlers): Always register for SIGINT, even
+ under Microsoft Windows.
+
+ * magick/tempfile.c (PurgeTemporaryFilesAsyncSafe): New private
+ function to clean up temporary files prior to program exit.
+ Async-safe so it can be safely called from a signal handler.
+ Intentionally leaks memory.
+
+2015-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/attribute.c (GenerateEXIFAttribute): Fix crash while
+ parsing corrupt EXIF which was reported by Stijn Sanders on
+ 2015-02-17.
+
+ * Magick++/lib/{Blob.cpp, Image.cpp}: Incorrect lock scope
+ resulted in Magick++ locking not actually working to protect
+ critical sections in spite of no detected problems with locking
+ these past 16 years. Problem was detected using the
+ misc-unused-raii check from clang-tidy and was reported by Hyrum
+ Wright.
+
+ * coders/palm.c (ReadPALMImage): Add header logging to writer.
+ Writer still seeks and overwrites its own header so logging is not
+ entirely accurate yet.
+
+2015-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * libtool: Update GNU libtool to 2.4.6.
+
+ * coders/palm.c (ReadPALMImage): Fix support for transparency in
+ PALM reader.
+
+2015-02-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/palm.c (ReadPALMImage): Major re-work of PALM reader.
+ More log message improvements. More header validation.
+
+2015-02-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/palm.c (ReadPALMImage): Improve log messages. Add more
+ header validation. Check image pixel limits. Support 'ping'
+ mode.
+
+2015-02-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/palm.c (ReadPALMImage): PALM reader now supports 1, 2, 4,
+ 8, and 16-bit test files we were able to generate using
+ 'pnmtopalm'. A progress monitor was added. Memory leaks in error
+ paths were fixed.
+
+2015-02-12 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Insert "if (QuantumTick(...))" ahead of
+ each "if (!MagickMonitorFormatted(...)".
+
+2015-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/rla.c (ReadRLAImage): Assure that header ASCII strings
+ are properly terminated. Resolves Coverity CID 10322.
+
+2015-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.h (STDERR_FILENO): Provide definitions for
+ standard POSIX file numbers so that Visual Studio should compile.
+ Fixes SourceForge bug #291 "STDERR_FILENO (used in magick.c) is
+ not defined under Windows"
+
+2015-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++/lib/Image.cpp (Image::quiet()): Patch by Dirk Lemstra
+ to support silencing warnings in Magick++. Adds a quiet() method
+ which blocks (ignores) warning exceptions when passed a true
+ argument. Warning exceptions are still generated by default.
+
+ * coders/tiff.c: Support '-define tiff:report-warnings=true' to
+ enable that warnings reported by libtiff are thrown as warning
+ exceptions so that they may be caught or will be reported at the
+ gm command-line.
+
+2015-02-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (WriteTIFFImage): Use YCbCr encoding when JPEG
+ compression is requested for an RGB image.
+
+2015-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/tiff.c (QuantumTransferMode): Fix reading or writing
+ planar min-is-white or min-is-black images with an associated
+ alpha channel.
+
+2015-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/xpm.c (ReadXPMImage): Reading empty XPM file should not
+ cause bad memory access.
+
+ * coders/gif.c (DecodeImage): Assure that GIF decoder does not use
+ unitialized data.
+
+ * coders/jpeg.c (ReadJPEGImage): Verify that we support the number
+ of output components before proceeding to decode the image.
+
+2015-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/miff.c (ReadMIFFImage): MIFF needs to stop spinning if
+ zlib or bzlib report an error while decompressing. Solves problem
+ with file provided by Jodie Cunningham on 2015-01-25.
+
+ * coders/vicar.c (ReadVICARImage): Fix Vicar reader's dogged
+ determination to continue reading when there is nothing left to
+ read. Solves problem with file provided by Jodie Cunningham on
+ 2015-01-25.
+
+ * magick/magick.c (PanicDestroyMagick): Replace memory allocation
+ functions with dummy functions rather than NULL pointers.
+ (InitializeMagickSignalHandlers): Register
+ MagickPanicSignalHandler() for SIGSEGV.
+ (MagickPanicSignalHandler): Produce an informative message for the
+ user.
+ (MagickSignalHandlerMessage): Include more detailed information
+ from the signal handler via a common routine used by default
+ signal handlers.
+
+2015-01-25 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/bmp.c (ReadBMPImage): An attempt to address CID 10291.
+
+2015-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/nt_base.c (Exit): Changed to return 'void'. Function can
+ not return a value if it does not return.
+
+ * magick/error.c (DefaultFatalErrorHandler): Invoke
+ PanicDestroyMagick() rather than DestroyMagick(). If we are
+ really that short on memory, DestroyMagick() might not work.
+
+ * magick/magick.c (MagickPanicSignalHandler): Only use async-safe
+ functions in signal handler.
+ (PanicDestroyMagick): New function for emergency release of
+ persistent resources just prior to program exit. Async-safe and
+ does not acquire or release any heap memory.
+
+ * magick/export.c: Eliminate two 'clang' warnings.
+
+2015-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pdb.c (ReadPDBImage): Fix typo.
+
+ * coders/cineon.c (ReadCINEONImage): Enforce that Cineon image
+ info channels is valid. Solves problem with file provided by
+ Jodie Cunningham on 2015-01-24
+
+ * coders/fits.c (ReadFITSImage): Enforce valid bits-per-pixel
+ values. Add detailed header logging. Solves problem with file
+ provided by Jodie Cunningham on 2015-01-24
+
+2015-01-22 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadPNGImage): Check length of various MNG
+ chunks before using the chunk data.
+
+ * coders/png.c (WriteOnePNGImage): Use png_error() instead of
+ throwing an exception so cleanup in the setjmp block can happen,
+ including unlocking the semaphore. Addresses Coverity CID 10184.
+
+2015-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/gif.c (WriteGIFImage): Don't use an unchecked value from
+ GetImageAttribute(), even if the access succeeded before.
+ Resolves Coverity CID 10219.
+
+ * coders/dpx.c (StringToAttribute): Make sure that string is not
+ accidentally shortened by one character if it occupies the full
+ field size.
+ (ReadDPXImage): Validate that the bits per sample claimed by the
+ file header is a supported depth before using it further in the
+ code. This might resolve Coverity CID 10071 "Bad shift
+ operation".
+ (ReadDPXImage): Check for EOF while reading forward to element
+ data. Might solve Coverity CID 10305.
+
+ * coders/dib.c (ReadDIBImage): Resolve Coverity CID 10228 "Integer
+ overflowed argument".
+ (ReadDIBImage): Hopefully resolve Coverity CID 10268 "Various",
+ which is primarily about placing too much trust in the claimed
+ number of colors.
+
+ * coders/pnm.c (WritePNMImage): Fix overwrite of status by
+ progress monitor. Remaining issues may lurk within. May resolve
+ Coverity CID 10288.
+
+ * coders/pdb.c: Resolve Coverity CID 11173 "Buffer not null
+ terminated".
+
+2015-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (GetMagickInfoArray): Resolve Coverity CID 10212
+ "Missing unlock".
+
+ * magick/colormap.c (ReplaceImageColormap): Allocate new image
+ colormap up front in order to avoid the possibility that we are
+ left with an image with no colormap due to memory allocation
+ failure. If there is a memory allocation failure, then the
+ original colormap is preserved. Resolves Coverity CID 10194
+ "Dereference after null check".
+
+ * magick/utility.c (MagickStripSpacesFromString): New private
+ utility function to strip spaces from a string.
+
+ * magick/color_lookup.c (GetColorInfoArray): Resolves Coverity CID
+ 10231 "Missing unlock"
+ (ReadColorConfigureFile): Resolves Coverity CID 10261 "Use of
+ untrusted scalar value"
+ (GetColorInfo): Resolves Coverity CID 10077 "Overlapping buffer in
+ memory copy".
+
+2015-01-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c (ReadOnePNGImage): Use png_error() instead of
+ throwing an exception so cleanup in the setjmp block can happen,
+ including unlocking the semaphore. Resolves Coverity CID 10232.
+
+ * coders/png.c (ReadOnePNGImage): Moved a logging statement into a
+ block where "attribute" has been checked for NULL. Resolves
+ Coverity CIDs 10185 and 10187.
+
+ * coders/png.c (ReadMNGImage): Fixed a cut-and-paste typo
+ (change_delay should be change_timeout) reported by Coverity
+ CID 10090.
+
+2015-01-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/image.c (CloneImage): The definition is poor as to what a
+ non-orphan clone should do. However, the definition surely does
+ not include crashing the software or supplanting the original
+ image in an image list. Clone image blob and previous/next
+ pointers but do not supplant original image in list. Resolves
+ Coverity CID 10155.
+
+2015-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (WriteRowSamples): Ensure that callback function is
+ always defined. Resolves Coverity CID 10122.
+ (ReadRowSamples): Ensure that callback function is always
+ defined. Resolves Coverity CID 10125.
+
+ * magick/random.c (InitializeMagickRandomKernel): Avoid possible
+ double-close of file. Resolves Coverity CID 10257.
+
+ * coders/histogram.c (WriteHISTOGRAMImage): Avoid possible divide
+ by zero exception. Resolves Coverity CID 10107.
+
+ * magick/error.c (MagickFatalError): Document that
+ MagickFatalError() is not supposed to return (program must quit)
+ and add GCC/Clang hints to that effect.
+
+ * magick/bit_stream.c (BitAndMasks): Avoid possible access
+ one-beyond end of BitAndMasks array. It is not clear if there is
+ a possible bug with 32-bit quantums. If there is a bug, it has
+ not been noticed via testing. Resolves Coverity CID 10213.
+
+ * magick/tempfile.c (AcquireTemporaryFileDescriptor): Avoid buffer
+ overrun in the case of an astonishingly long environment variable
+ string. Resolves Coverity CID 10267.
+ (AddTemporaryFileToList): Use strlcpy() rather than strlcpy(). In
+ practice, should not make a difference. Will quiet Coverity CID
+ 10321.
+
+ * magick/command.c (GMCommandSingle): Don't use the address of a
+ stack allocation to update argv[0]. Removed updating argv[0] until
+ a better design can be found. Resolves Coverity CID 10223.
+ (GMCommandSingle): Plan B: Use static allocation from
+ SetClientName() to both store the new command name and provide
+ storage for argv[0].
+
+ * magick/utility.c (SystemCommand): Fix possible overwrite of
+ memory location due to uninitialized 'end' pointer. Resolves
+ Coverity CID 10251.
+
+ * magick/blob.c (WriteBlobFile): Was not closing file in certain
+ error conditions. Resolves Coverity CID 10237.
+
+ * coders/cineon.c (ReadCINEONImage): Don't trust file header so
+ much. Resolves Coverity CIDs 10079, 10310, 10325.
+
+ * coders/art.c (ReadARTImage): Fix signed vs unsigned comparison
+ caused by earlier changes.
+
+2014-01-17 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/wpg.c Do not execute wpg raster read in ping mode.
+
+2014-01-15 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/mat.c Properly deallocating zip structures.
+
+2015-01-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/sfw.c (ReadSFWImage): Fix pixel cache access errors in
+ 'ping' mode.
+
+2015-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/wmf.c (ReadWMFImage): Fix memory leak in 'ping' mode and
+ some error paths.
+
+2015-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/jbig.c (ReadJBIGImage): Fix memory leak in 'ping' mode.
+
+ * magick/delegate.c (InvokeDelegate): Fix memory leak of argument
+ list when invoking external program via MagickSpawnVP().
+
+2015-01-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (InitializeMagickResources): Base image width
+ and height default limits on the range of a 32-bit signed integer,
+ even for 64-bit builds. These limits are still beyond what most
+ computers in the world can handle. Limits can be increased by the
+ user.
+
+ * coders/xwd.c (ReadXWDImage): Check image size limits
+ immediately.
+
+ * coders/xc.c (ReadXCImage): Check image size limits immediately.
+
+ * coders/webp.c (ReadWEBPImage): Check image size limits
+ immediately.
+
+ * coders/viff.c (ReadVIFFImage): Check image size limits
+ immediately.
+
+ * coders/vicar.c (ReadVICARImage): Check image size limits
+ immediately.
+
+ * coders/txt.c (ReadTXTImage): Check image size limits
+ immediately.
+
+ * coders/ttf.c (ReadTTFImage): Check image size limits
+ immediately.
+
+ * coders/tim.c (ReadTIMImage): Check image size limits
+ immediately.
+
+ * coders/tiff.c (ReadTIFFImage): Check image size limits
+ immediately.
+
+ * coders/tga.c (ReadTGAImage): Check image size limits
+ immediately.
+
+ * coders/sgi.c (ReadSGIImage): Check image size limits
+ immediately.
+
+ * coders/sct.c (ReadSCTImage): Check image size limits
+ immediately.
+
+ * coders/rle.c (ReadRLEImage): Check image size limits
+ immediately.
+
+ * coders/rla.c (ReadRLAImage): Check image size limits
+ immediately.
+
+ * coders/psd.c (ReadPSDImage): Check image size limits
+ immediately.
+
+ * coders/pnm.c (ReadPNMImage): Check image size limits
+ immediately.
+
+ * coders/pix.c (ReadPIXImage): Check image size limits
+ immediately.
+
+ * coders/pict.c (ReadPICTImage): Check image size limits
+ immediately.
+
+ * coders/pdb.c (ReadPDBImage): Check image size limits
+ immediately.
+
+ * coders/pcx.c (ReadPCXImage): Check image size limits
+ immediately.
+
+ * coders/pcd.c (ReadPCDImage): Check image size limits
+ immediately.
+
+ * coders/otb.c (ReadOTBImage): Check image size limits
+ immediately.
+
+ * coders/null.c (ReadNULLImage): Check image size limits
+ immediately.
+
+ * coders/mvg.c (ReadMVGImage): Check image size limits
+ immediately.
+
+ * coders/mtv.c (ReadMTVImage): Check image size limits
+ immediately.
+
+ * coders/mpc.c (ReadMPCImage): Check image size limits
+ immediately.
+
+ * coders/miff.c (ReadMIFFImage): Check image size limits
+ immediately.
+
+ * coders/jpeg.c (ReadJPEGImage): Check image size limits
+ immediately.
+
+ * coders/jp2.c (ReadJP2Image): Check image size limits
+ immediately.
+
+ * coders/jbig.c (ReadJBIGImage): Check image size limits
+ immediately.
+
+ * coders/hdf.c (ReadHDFImage): Check image size limits
+ immediately.
+
+ * coders/gif.c (ReadGIFImage): Check image size limits
+ immediately.
+
+ * coders/fpx.c (ReadFPXImage): Check image size limits
+ immediately.
+
+ * coders/fax.c (ReadFAXImage): Check image size limits
+ immediately.
+
+ * coders/dpx.c (ReadDPXImage): Check image size limits
+ immediately.
+
+ * coders/dps.c (ReadDPSImage): Check image size limits
+ immediately.
+
+ * coders/dib.c (ReadDIBImage): Check image size limits
+ immediately.
+
+ * coders/dcm.c (ReadDCMImage): Check image size limits
+ immediately.
+
+ * coders/cut.c (ReadCUTImage): Check image size limits
+ immediately.
+
+ * coders/cineon.c (ReadCINEONImage): Check image size limits
+ immediately.
+
+ * coders/avs.c (ReadAVSImage): Check image size limits
+ immediately.
+
+ * coders/art.c (ReadARTImage): Check image size limits
+ immediately.
+
+ * coders/sun.c (ReadSUNImage): Check image size limits in advance
+ of allocating memory for pixels.
+
+ * coders/bmp.c (ReadBMPImage): Check image size limits in advance
+ of allocating memory for pixels.
+
+ * coders/sun.c (ReadSUNImage): There is no definition for Sun map
+ type RMT_RAW so it can not be supported. Update DirectClass
+ pixels directly rather using SyncImage(). Problem was reported by
+ Jodie Cunningham.
+
+2015-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/pict.c (ReadPICTImage): Fix PICT reader crash when
+ reading corrupted file.
+
+ * coders/sun.c (ReadSUNImage): Sun reader was still not as robust
+ as it should be. Now it is.
+
+2014-01-10 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ * coders/wpg.c Fixed reading behind EOF issue.
+
+2015-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/dpx.c (LSBPackedU32WordToOctets): Fix typo which adds
+ severe corruption to encoded little-endian 32-bit packed output.
+ The good news is that since the corruption is severe, it is easily
+ visually detected. The problem has corrupted all such
+ (little-endian 10-bit) output since it was originally implemented
+ on 2007-06-17 (changeset 11686, first released in GraphicsMagick
+ 1.1.8). GraphicsMagick preserves the endianness of input DPX
+ files by default, defaults to big-endian, and DPX files are
+ commonly big-endian, so this problem may not have occured for many
+ usages. Problem was reported by Steve Dabner on the
+ GraphicsMagick discussion mailing list.
+
+2015-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/magick.c (MagickPanicSignalHandler): Print a message in
+ the case of signals SIGXCPU and SIGXFSZ.
+
+ * coders/bmp.c (ReadBMPImage): Don't hang in endless loop if EOF
+ is encountered while checking for "BA" header.
+
+ * coders/icon.c (ReadIconImage): Limit icon image allocation size.
+
+2015-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/icon.c (ReadIconImage): Removed all of the
+ previously-existing DIB reading code from icon.c and use new
+ "ICODIB" reader to read DIB icons, or the PNG reader to read PNG
+ icons.
+
+ * coders/dib.c (ReadDIBImage): Added an "ICODIB" coder for
+ internal use which reads a Windows BMP 3 DIB followed by a Windows
+ ICO alpha mask. This allows existing DIB code to be used to read
+ ICO directory entries.
+
+2015-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * coders/icon.c: The Windows ICO reader is now more robust. Still
+ a work in progress since some files still can not be read or read
+ incorrectly.
+
+2015-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/resource.c (ListMagickResourceInfo): "kilo" for binary
+ prefixes is supposed to be "Ki".
+
+ * magick/utility.c (FormatSize): "kilo" for binary prefixes is
+ supposed to be "Ki".
+
+2015-01-01 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ * coders/png.c: Use WidthResource and HeightResource instead
+ of fixed 1-million limit for rows and columns.
+
+2015-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * magick/utility.c (FormatSize): Add 'i' to value range
+ identifiers since these are all in units of 2^10 rather than 1000.
+
+ * magick/pixel_cache.c (CheckImagePixelLimits): Fix typo and
+ produce an informative error message.
+
+ * magick/resource.c: Added support for Image width and height
+ pixels resource limits.
+
+ * magick/resource.h (ResourceType): New resource enumerations
+ WidthResource and HeightResource.
+
+ * magick/enum_strings.c (StringToResourceType): Added support for
+ parsing '-limit Width' and '-limit Height'.
+
+ * magick/pixel_cache.c (CheckImagePixelLimits): New function to
+ test image to see if it exceeds pixels limits.
+
+ * coders/viff.c (ReadVIFFImage): Make the VIFF reader robust with
+ detecting and reporting problems.
+
+2014-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Rotate Changelog for new year. Update documentation copyrights
+ for new year.
+
+
diff --git a/Copyright.txt b/Copyright.txt
new file mode 100644
index 0000000..88dca7f
--- /dev/null
+++ b/Copyright.txt
@@ -0,0 +1,285 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+======================================
+GraphicsMagick Copyrights and Licenses
+======================================
+
+This file is part of the GraphicsMagick software distributed by the
+GraphicsMagick Group.
+
+ [*Please note that the legal community considers 15 or more
+ total lines of code or text (not necessarily contiguous) to
+ be significant for the purposes of copyright. Repeated
+ changes such as renaming a symbol has similar significance
+ to changing one line of code.*]
+
+The licenses which components of this software fall under are as follows.
+
+1)
+
+ In November 2002, the GraphicsMagick Group created GraphicsMagick
+ from ImageMagick Studio's ImageMagick and applied the "MIT" style
+ license:
+
+ Copyright (C) 2002 - 2017 GraphicsMagick Group
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+2)
+
+ In October 1999, ImageMagick Studio assumed the responsibility for
+ the development of ImageMagick (forking from the distribution by
+ E. I. du Pont de Nemours and Company) and applied a new license:
+
+ Copyright (C) 2002 ImageMagick Studio, a non-profit organization dedicated
+ to making software imaging solutions freely available.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files ("ImageMagick"),
+ to deal in ImageMagick without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of ImageMagick, and to permit persons to whom the
+ ImageMagick is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of ImageMagick.
+
+ The software is provided "as is", without warranty of any kind, express or
+ implied, including but not limited to the warranties of merchantability,
+ fitness for a particular purpose and noninfringement. In no event shall
+ ImageMagick Studio be liable for any claim, damages or other liability,
+ whether in an action of contract, tort or otherwise, arising from, out of
+ or in connection with ImageMagick or the use or other dealings in
+ ImageMagick.
+
+ Except as contained in this notice, the name of the ImageMagick Studio
+ shall not be used in advertising or otherwise to promote the sale, use or
+ other dealings in ImageMagick without prior written authorization from the
+ ImageMagick Studio.
+
+3)
+
+ From 1991 to October 1999 (through ImageMagick 4.2.9), ImageMagick
+ was developed and distributed by E. I. du Pont de Nemours and
+ Company:
+
+ Copyright 1999 E. I. du Pont de Nemours and Company
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files
+ ("ImageMagick"), to deal in ImageMagick without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of ImageMagick, and to
+ permit persons to whom the ImageMagick is furnished to do so, subject
+ to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of ImageMagick.
+
+ The software is provided "as is", without warranty of any kind, express
+ or implied, including but not limited to the warranties of
+ merchantability, fitness for a particular purpose and noninfringement.
+ In no event shall E. I. du Pont de Nemours and Company be liable for
+ any claim, damages or other liability, whether in an action of
+ contract, tort or otherwise, arising from, out of or in connection with
+ ImageMagick or the use or other dealings in ImageMagick.
+
+ Except as contained in this notice, the name of the E. I. du Pont de
+ Nemours and Company shall not be used in advertising or otherwise to
+ promote the sale, use or other dealings in ImageMagick without prior
+ written authorization from the E. I. du Pont de Nemours and Company.
+
+4)
+
+ The GraphicsMagick Base64Decode() and Base64Encode() functions are
+ based on source code obtained from OpenSSH. This source code is
+ distributed under the following license:
+
+ Copyright (c) 2000 Markus Friedl. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR \`\`AS IS\'\' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+5)
+
+ Many of the pattern images in coders/logo.c are derived from XFig,
+ which is distributed under the following license:
+
+ | FIG : Facility for Interactive Generation of figures
+ | Copyright (c) 1985-1988 by Supoj Sutanthavibul
+ | Parts Copyright (c) 1989-2000 by Brian V. Smith
+ | Parts Copyright (c) 1991 by Paul King
+
+ Any party obtaining a copy of these files is granted, free of charge, a
+ full and unrestricted irrevocable, world-wide, paid up, royalty-free,
+ nonexclusive right and license to deal in this software and
+ documentation files (the "Software"), including without limitation the
+ rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons who receive
+ copies from any such party to do so, with the only requirement being
+ that this copyright notice remain intact.
+
+6)
+
+ The documentation for the composition operators is copied from the
+ rlecomp manual page, which is authored by Rod Bogart and John W.
+ Peterson. Rlecomp is part of the Utah Raster Toolkit distributed by the
+ University of Michigan and the University of Utah. The copyright for
+ this manual page is as follows:
+
+ Copyright (c) 1986, University of Utah
+
+ This software is copyrighted as noted below. It may be freely copied,
+ modified, and redistributed, provided that the copyright notice is
+ preserved on all copies.
+
+ There is no warranty or other guarantee of fitness for this software,
+ it is provided solely "as is". Bug reports or fixes may be sent
+ to the author, who may or may not act on them as he desires.
+
+ You may not include this software in a program or other software product
+ without supplying the source, or without informing the end-user that the
+ source is available for no extra charge.
+
+ If you modify this software, you should include a notice giving the
+ name of the person performing the modification, the date of modification,
+ and the reason for such modification.
+
+7)
+
+ The source code comprising magick_endian.c is originally derived
+ from libtiff which has the following license:
+
+ | Copyright (c) 1988-1997 Sam Leffler
+ | Copyright (c) 1991-1997 Silicon Graphics, Inc.
+
+ Permission to use, copy, modify, distribute, and sell this software and
+ its documentation for any purpose is hereby granted without fee, provided
+ that (i) the above copyright notices and this permission notice appear in
+ all copies of the software and related documentation, and (ii) the names of
+ Sam Leffler and Silicon Graphics may not be used in any advertising or
+ publicity relating to the software without the specific, prior written
+ permission of Sam Leffler and Silicon Graphics.
+
+ THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+ IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ OF THIS SOFTWARE.
+
+8)
+
+ The C++ API known as "Magick++", and which resides in the Magick++
+ directory, is distributed under the following license:
+
+ Copyright 1999 - 2012 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ ("Magick++"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject
+ to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+9)
+
+ The GraphicsMagick HaldClutImagePixels() function in magick/hclut.c
+ is based on source code from the HaldCLUT package by Eskil Steenberg
+ (http://www.quelsolaar.com/technology/clut.html) which is
+ distributed under the following license:
+
+ Copyright (c) 2005 Eskil Steenberg. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR \`\`AS IS\'\' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+10)
+
+ GraphicsMagick makes use of third-party "delegate" libraries to
+ support certain optional features. These libraries bear their own
+ copyrights and licenses, which may be more or less restrictive than the
+ GraphicsMagick license. For convenience, when GraphicsMagick is
+ bundled with (or compiled with) "delegate" libraries, a copy of the
+ licenses for these libraries is provided in a "licenses" directory.
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/GraphicsMagick.spec.in b/GraphicsMagick.spec.in
new file mode 100644
index 0000000..f137cbe
--- /dev/null
+++ b/GraphicsMagick.spec.in
@@ -0,0 +1,298 @@
+# Allow for selectively disabling from commandline
+%{!?quant:%define quant 8}
+%{!?perlm:%define perlm 1}
+%{!?cplus:%define cplus 1}
+
+%define base_version @PACKAGE_VERSION@
+
+# This is a one line description of the package.
+Summary: An X application for displaying and manipulating images.
+# This must be the name string from the rpm filename you plan to use.
+Name: @PACKAGE_NAME@
+# This must be the version string from the rpm filename you plan to use.
+Version: @PACKAGE_VERSION@@PACKAGE_VERSION_ADDENDUM@
+# This is the release number for a package of the same version (ie. if
+# we make a package and find it to be slightly broken and need to make
+# it again, the next package would be release number 2).
+Release: 1
+License: MIT
+# This is a group that the package belongs to in a higher level
+# package tool or the Red Hat installer.
+Group: X11/Applications/Graphics
+# This line points at the HOME location of the pristine source
+# file. It is used if you ever want to get the source again or check
+# for newer versions.
+Source: ftp://ftp.GraphicsMagick.org/pub/%{name}/%{name}-%{version}.tar.bz2
+Url: http://www.GraphicsMagick.org/
+# This line allows you to specify a directory as the "root" for
+# building and installing the new package. You can use this to help
+# test your package before having it installed on your machine.
+Buildroot: %{_tmppath}/%{name}-%{version}-root
+BuildRequires: bzip2-devel, freetype-devel, libjpeg-devel, libpng-devel
+BuildRequires: libtiff-devel, zlib-devel
+BuildRequires: freetype-devel >= 2.0.1
+BuildRequires: libwebp-devel
+Requires: bzip2, freetype, libjpeg, libpng, libwebp, zlib
+
+%description
+GraphicsMagick(TM) provides a powerful image manipulation and
+translation utility. It is capable of displaying still images and
+animations using the X Window system, provides a simple interface for
+interactively editing images, and is capable of importing selected
+windows or the entire desktop. GraphicsMagick can read and write over
+88 image formats, including JPEG, TIFF, WMF, SVG, PNG, PNM, GIF, and
+Photo CD. It can resize, rotate, sharpen, color reduce, or add special
+effects to the image and save the result to any supported format.
+GraphicsMagick may be used to create animated or transparent .gifs,
+create composite images, create thumbnail images, and much, much,
+more.
+
+GraphicsMagick is one of your choices if you need a program to manipulate
+and display images. If you want to develop your own applications
+which use GraphicsMagick code or APIs, you need to install
+GraphicsMagick-devel as well.
+
+%package devel
+Summary: Static libraries and header files for GraphicsMagick app development.
+Group: X11/Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+GraphicsMagick-devel contains the static libraries and header files you'll
+need to develop GraphicsMagick applications. GraphicsMagick is an image
+manipulation program.
+
+If you want to create applications that will use GraphicsMagick code or
+APIs, you need to install GraphicsMagick-devel as well as GraphicsMagick.
+You do not need to install it if you just want to use GraphicsMagick,
+however.
+
+%if %{perlm}
+%package perl
+Summary: GraphicsMagick perl bindings
+Group: System Environment/Libraries
+BuildRequires: perl >= 5.6.0
+Requires: %{name} = %{version}-%{release}, perl >= 5.6.0
+
+%description perl
+Perl bindings to GraphicsMagick.
+
+Install GraphicsMagick-perl if you want to use any perl scripts that use
+GraphicsMagick.
+%endif
+
+%if %{cplus}
+%package c++
+Summary: GraphicsMagick Magick++ library (C++ bindings)
+Group: System Environment/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description c++
+This package contains the Magick++ library, a C++ binding to the GraphicsMagick
+graphics manipulation library.
+
+Install GraphicsMagick-c++ if you want to use any applications that use
+Magick++.
+
+%package c++-devel
+Summary: C++ bindings for the GraphicsMagick library
+Group: Development/Libraries
+Requires: %{name} = %{version}, %{name}-c++ = %{version}
+Requires: %{name}-devel = %{version}, bzip2-devel, freetype-devel
+Requires: libjpeg-devel, libpng-devel, libtiff-devel, zlib-devel, libxml2-devel
+
+%description c++-devel
+GraphicsMagick-devel contains the static libraries and header files you'll
+need to develop GraphicsMagick applications using the Magick++ C++ bindings.
+GraphicsMagick is an image manipulation program.
+
+If you want to create applications that will use Magick++ code or APIs,
+you'll need to install GraphicsMagick-c++-devel, GraphicsMagick-devel and
+GraphicsMagick. You don't need to install it if you just want to use
+GraphicsMagick, or if you want to develop/compile applications using the
+GraphicsMagick C interface, however.
+%endif
+
+%prep
+%setup -q
+
+%build
+# If you have trouble during the installation phase, then
+# uncomment the two lines below. You may be using an older
+# libtool that sometimes has trouble linking the files.
+
+%if %{perlm}
+# Maybe this will fix perl installation issues.
+if [ -z "`perl -v | grep 5.8`" ]; then
+ export PERLOPTS="PREFIX=$RPM_BUILD_ROOT%{_prefix}"
+fi
+%endif
+
+# This shouldn't be there yet.
+rm -f PerlMagick/Makefile.PL
+
+%configure --with-included-ltdl \
+ --enable-shared \
+ --with-modules --with-frozenpaths \
+ --docdir=%{_datadir}/doc/%{name}-%{base_version} \
+%if %{perlm}
+ --with-perl \
+ --with-perl-options="$PERLOPTS" \
+%else
+ --without-perl \
+%endif
+%if %{cplus}
+ --with-magick-plus-plus \
+%else
+ --without-magick-plus-plus \
+%endif
+ --with-quantum-depth=%{quant}
+make
+%if %{perlm}
+make all-perl
+%endif
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install
+
+%if %{perlm}
+make DESTDIR=$RPM_BUILD_ROOT install-exec-perl
+# Remove unpackaged files.
+rm -f `find $RPM_BUILD_ROOT%{_libdir}/perl*/ -name perllocal.pod -type f`
+rm -f `find $RPM_BUILD_ROOT%{_libdir}/perl*/ -name .packlist -type f`
+%endif
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(644, root, root, 755)
+%doc %{_datadir}/%{name}-%{base_version}
+%{_libdir}/lib%{name}.so.*
+%{_libdir}/lib%{name}Wand.so.*
+%dir %{_libdir}/%{name}-%{base_version}
+%{_libdir}/%{name}-%{base_version}/config/*.mgk
+%dir %{_libdir}/%{name}-%{base_version}/modules-Q%{quant}
+%{_libdir}/%{name}-%{base_version}/modules-Q%{quant}/*/*.so
+%{_libdir}/%{name}-%{base_version}/modules-Q%{quant}/*/*.la
+%attr(755, root, root) %{_bindir}/gm
+%attr(644, root, man) %{_mandir}/man1/gm.1.gz
+%attr(644, root, man) %{_mandir}/man4/*gz
+%attr(644, root, man) %{_mandir}/man5/*gz
+%docdir %{_datadir}/doc/%{name}-%{base_version}
+%{_datadir}/doc/%{name}-%{base_version}/*
+
+%files devel
+%defattr(644, root, root, 755)
+%dir %{_includedir}/%{name}/wand
+%{_includedir}/%{name}/wand/*
+%dir %{_includedir}/%{name}/magick
+%{_includedir}/%{name}/magick/*
+%{_libdir}/lib%{name}Wand.*a
+%{_libdir}/lib%{name}Wand.so
+%{_libdir}/lib%{name}.*a
+%{_libdir}/lib%{name}.so
+%dir %{_libdir}/%{name}-%{base_version}/modules-Q%{quant}
+%{_libdir}/pkgconfig/%{name}.pc
+%{_libdir}/pkgconfig/%{name}Wand.pc
+#%{_bindir}/%{name}-config
+%attr(755, root, root) %{_bindir}/%{name}-config
+#%{_bindir}/%{name}Wand-config
+%attr(755, root, root) %{_bindir}/%{name}Wand-config
+%attr(644, root, man) %{_mandir}/man1/%{name}-config.1.gz
+%attr(644, root, man) %{_mandir}/man1/%{name}Wand-config.1.gz
+
+%if %{perlm}
+%files perl
+%defattr(644, root, root, 755)
+%dir %{_libdir}/perl*/site_perl/*/*/Graphics
+%{_libdir}/perl*/site_perl/*/*/Graphics/Magick.pm
+%dir %{_libdir}/perl*/site_perl/*/*/auto/Graphics/Magick
+%{_libdir}/perl*/site_perl/*/*/auto/Graphics/Magick/*
+%attr(644, root, man) %{_mandir}/man3/*gz
+%endif
+
+%if %{cplus}
+%files c++
+%defattr(644, root, root, 755)
+%{_libdir}/lib%{name}++.so.*
+
+%files c++-devel
+%defattr(644, root, root, 755)
+%{_includedir}/%{name}/Magick++.h
+%dir %{_includedir}/%{name}/Magick++
+%{_includedir}/%{name}/Magick++/*
+%{_libdir}/lib%{name}++.*a
+%{_libdir}/lib%{name}++.so
+%{_libdir}/pkgconfig/%{name}++.pc
+#%{_bindir}/%{name}++-config
+%attr(755, root, root) %{_bindir}/%{name}++-config
+%attr(644, root, man) %{_mandir}/man1/%{name}++-config.1.gz
+%endif
+
+%changelog
+* Fri Apr 16 2010 Bob Friesenhahn <bfriesen@graphicsmagick.org> 1.3.13
+- Avoided duplicate copies of documentation files. Put documentation
+ into a versioned directory as used by Red Hat and CentOS. Include
+ archive libraries in developer package.
+
+* Tue Apr 13 2010 Bob Friesenhahn <bfriesen@graphicsmagick.org> 1.3.13
+- Fixed PerlMagick build and install which was broken by Makefile
+ changes.
+
+* Wed Jan 23 2009 Bob Friesenhahn <bfriesen@graphicsmagick.org> 1.3
+- The module .la files need to be installed as part of the base
+ install or else the modules will fail to load.
+
+* Wed Jan 21 2009 Bob Friesenhahn <bfriesen@graphicsmagick.org> 1.3
+- --enable-lzw option is not longer needed
+
+* Tue Nov 11 2008 Giacomo Tenaglia 1.3 <gtenagli at sf . net>.
+- The *-config scripts were listed twice.
+- Add definition for %{_datadir}/doc directory
+
+* Wed Jun 02 2004 Bob Friesenhahn <bfriesen@graphicsmagick.org> 1.2
+- Install *-config scripts with mode 755 rather than default 644.
+
+* Sat Feb 21 2004 Bob Friesenhahn <bfriesen@graphicsmagick.org> 1.1-1
+- Added some comments.
+- Eliminated DATE variable.
+- Support creating RPMs of snapshots packages.
+- Don't remove /usr/include/magick or %{_datadir}/%{name} since they
+ are not created anymore.
+- Fixed location of .mgk files.
+
+* Mon Jul 28 2003 Bob Friesenhahn <bfriesen@graphicsmagick.org> 1.1-1
+- Changed default quantum depth to 8 bits.
+
+* Mon Jun 28 2003 Troy Edwards <vallimar@sexorcisto.net> 1.1-20030628
+- Updated to CVS build, added the GraphicsMagickWand files to the spec.
+- Only try to remove the unneeded perl package files if we are using
+ PerlMagick.
+
+* Mon Jun 09 2003 Troy Edwards <vallimar@sexorcisto.net> 1.0.2-3
+- removed libungif as a dependancy
+- changed with/without-magick_plus_plus -> with/without-magick-plus-plus
+- Use --with-perl-options instead of patching Makefile.in
+- Only set a perl prefix if we aren't using perl >= 5.8.0
+
+* Sat Jun 07 2003 Troy Edwards <vallimar@sexorcisto.net> 1.0.2-2
+- patch to pass DESTDIR to install-exec-perl since some users
+ reported problems
+
+* Sat Jun 07 2003 Troy Edwards <vallimar@sexorcisto.net> 1.0.2-1
+- updated to 1.0.2
+
+* Tue May 05 2003 Troy Edwards <vallimar@sexorcisto.net> 1.0-1
+- updated to 1.0 Final
+
+* Fri Apr 25 2003 Troy Edwards <vallimar@sexorcisto.net> 1.0-Beta1-1
+- updated to 1.0-Beta1
+
+* Mon Oct 22 2002 Troy Edwards <vallimar@sexorcisto.net>
+- updated to 1.0.0pre
diff --git a/Magick++/AUTHORS b/Magick++/AUTHORS
new file mode 100644
index 0000000..465cdcd
--- /dev/null
+++ b/Magick++/AUTHORS
@@ -0,0 +1,19 @@
+The author and maintainer of Magick++ is Bob Friesenhan
+<bfriesen@simple.dallas.tx.us>.
+
+Many thanks to John Cristy for developing the powerful ImageMagick
+package that Magick++ is based on and for enhancing ImageMagick API
+features in order to allow a cleaner implementation.
+
+Thanks to Bill Radcliffe <BillR@corbis.com> for his assistance with
+getting Magick++ to compile under Visual C++, and for maintaining the
+Windows build environment.
+
+Thanks to Albert Chin-A-Young <china@thewrittenword.com> for assisting
+with compilation issues related to the SGI C++ compiler, for providing
+access to the Sun C++ compiler, and for assistance with the configure
+script.
+
+Thanks to Leonard Rosenthol <leonardr@lazerware.com> for ensuring that
+Magick++ compiles on the Mac.
+
diff --git a/Magick++/COPYING b/Magick++/COPYING
new file mode 100644
index 0000000..5ea9dc7
--- /dev/null
+++ b/Magick++/COPYING
@@ -0,0 +1,21 @@
+
+Copyright 1999 - 2015 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files
+("Magick++"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Magick++/ChangeLog b/Magick++/ChangeLog
new file mode 100644
index 0000000..c44788c
--- /dev/null
+++ b/Magick++/ChangeLog
@@ -0,0 +1,1886 @@
+2017-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (orientation): Update orientation in EXIF profile,
+ if it exists.
+ (attribute): Added Image attribute method which accepts a 'char *'
+ argument, and will remove the attribute if the value argument is
+ NULL.
+
+2014-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Geometry.h (Magick::Geometry): Add and document
+ limitPixels() and fillArea() methods to support '@' and '^'
+ geometry qualifiers. Fill area contributed by Long Ho and
+ limitPixels() by Bob Friesenhahn.
+
+ * ../www/Magick++/Image.rst: Document extent and resize methods.
+
+ * lib/STL.cpp (extentImage): New function object to invoke image
+ extent method. Original implementation contributed by Long Ho.
+ Subsequently modified by Bob Friesenhahn.
+ (resizeImage): New function object to invoke image resize
+ method. Contributed by Long Ho.
+
+ * lib/Image.cpp (extent): New method to place image on sized
+ canvas of constant color using gravity. Contributed by Long Ho.
+ (resize): New method to resize image specifying geometry, filter,
+ and blur. Original implementation contributed by Long Ho.
+ Subsequently modified by Bob Friesenhahn.
+
+2014-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (thumbnail): New method for fast image resizing,
+ particularly to make thumbnails.
+
+2013-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableDashArray): DrawableDashArray now uses
+ C++ memory allocation rather than from GraphicsMagick library.
+ Also, implement direct copy constructor and assignment operator
+ rather than using dasyarray() method.
+
+2012-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * COPYING: Change Magick++ usage license to be exactly the MIT
+ license without the additional sentence about retention of
+ copyright (which was already legally implicit).
+
+2012-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (defineValue): Use AddDefinition() rather than
+ AddDefinitions().
+
+2012-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h (Magick): Added support for RandomNoise.
+
+2012-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/STL.cpp (stripImage): New unary function to to remove all
+ profiles and text attributes from the image.
+
+ * lib/Image.cpp (strip): New method to remove all profiles and
+ text attributes from the image.
+
+2011-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: Explicitly DLL import/export Magick++
+ symbols when building under MinGW GCC.
+
+2010-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h (Magick): Add LZMACompression
+
+2010-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (InitializeMagick): Don't use atexit(). C++
+ destructures are sufficient.
+
+2010-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (backgroundColor, borderColor, matteColor):
+ Opacity part of user-specified color needs to be preserved.
+ Problem was reported by Alexander Zheltov.
+
+2010-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/CoderInfo.h: Add default constructor, copy
+ constructor, and assignment operator.
+
+2010-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (Magick): Fix potential memory leak.
+
+2010-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * demo/shapes.cpp (main): Floodfill shape more agressively and
+ scale fuzz factor so that it provides the same results across
+ quantum depths.
+
+2009-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/STL.cpp, lib/Magick++/STL.h (shadeImage): ShadeImage was the
+ result of a botched cut-and-paste. Corrected now. Thanks to
+ Jukka Manner for making me aware of this.
+
+2009-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (cdl): New method to apply the ASC CDL.
+ (colorMatrix): New method to apply a color matrix to the image
+ channels.
+ (haldClut): New method to apply a color lookup table (Hald CLUT)
+ to the image.
+
+2009-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (attribute): Invoke modifyImage() to assure
+ exclusive access to image when updating attributes.
+
+2009-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (quantumOperator): New variant of method which
+ takes a 'double' argument, as it originally should. Previous
+ method taking a Quantum argument is still supported but marked
+ deprecated.
+
+2009-01-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: If the user defines STATIC_MAGICK in his
+ project, then the Windows DLL decorations are ignored. Without
+ this, Windows DLL-based code can't use a static GraphicsMagick.
+ This is recommended by SourceForge bug 2537627.
+
+ * lib/Magick++/Drawable.h: Apparently the only STL container which
+ may be DLL-exported is <vector> but we are using <list> so disable
+ DLL-export of list-based template objects.
+
+2008-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Color.cpp: Added an _isValid boolean to represent an invalid
+ color. Transparent black is no longer special and can be used in
+ drawing.
+ * lib/Pixels.cpp: Update to use new cache view interfaces provided
+ by GraphicsMagick 1.3.
+
+2008-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (addNoiseChannel): New method to add noise to a
+ specified channel.
+ (blurChannel): New method to blur a specified channel.
+ (gaussianBlurChannel): New method to gaussian blur a specified
+ channel.
+ (motionBlur): New method to motion blur the image.
+ (randomThresholdChannel): New method to apply random thresholding
+ or ordered dithering to the image.
+ (randomThresholdChannel): New method to apply random thresholding
+ or ordered dithering to the specified image channels.
+ (sharpenChannel): New method to sharpen a specified image channel.
+ (unsharpmaskChannel): New method to unsharpmask a specified image
+ channel.
+
+2008-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (quantize): Error measurement support was being
+ performed incorrectly. SyncImage() is not needed here.
+
+2008-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * demo/demo.cpp (main): Fix segmentation parameters so they are
+ more suitable for our image.
+
+2008-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (depth): Remove 8/16/32 restriction on depth
+ value.
+
+2008-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Geometry.cpp, lib/Image.cpp: Include <strings.h> since it is
+ needed in order to use strcpy().
+
+2007-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/{Drawable.cpp, Geometry.cpp, BlobRef.cpp, Blob.cpp,
+ Montage.cpp, Options.cpp, Image.cpp}: Eliminate use of deprecated
+ GraphicsMagick functions.
+
+ * lib/Magick++/{STL.h, Include.h}: Eliminate use of deprecated
+ GraphicsMagick functions.
+
+2007-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp: Include <cstdlib>
+
+2006-10-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (pixelColor): Don't enforce color "validity" when
+ setting the pixel color.
+
+2005-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (orientation): New accessor method to support
+ image orientation.
+
+2005-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/STL.cpp (levelImage): New function object for leveling the
+ image channels.
+ (levelChannelImage): New function object for leveling a specific
+ image channel.
+
+ * lib/Image.cpp (level): New method for leveling the image
+ channels.
+ (levelChannel): New method for leveling a specific image channel.
+
+2005-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h (Magick): Import CineonLogRGBColorspace
+ into Magick namespace.
+
+2005-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: Import Rec601LumaColorspace (was called
+ GRAYColorspace) and Rec709LumaColorspace into Magick
+ namespace. Use of GRAYColorspace is mapped via a macro into
+ Rec601LumaColorspace in order to avoid a user-visible API change.
+
+2004-08-17 Volker Lukas <vlukas@gmx.de>
+
+ * lib/Drawable.cpp: Fixes to ensure that drawable objects remain
+ coherent even if an exception is thrown within the assignment
+ operator.
+
+2004-07-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us> <bfriesen@simple.dallas.tx.us>
+
+ * demo/Makefile.am (AUTOMAKE_OPTIONS): Added nostdinc in order to
+ avoid accidentally using magick/list.h when including <list>.
+
+ * tests/Makefile.am (AUTOMAKE_OPTIONS): Added nostdinc in order to
+ avoid accidentally using magick/list.h when including <list>.
+
+ * tests/readWriteBlob.cpp: If MISSING_STD_IOS_BINARY is defined,
+ then ios::binary is not used. Use simple ifstream rather than
+ std::ifstream since we are already using the std namespace.
+
+2004-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: Disable unavoidable warnings under
+ Visual C++ when instantiating STL templates within DLL
+ code. Consensus from postings on the net is that as long as the
+ same C++ compiler is used throughout, these warnings are of no
+ concern.
+
+2004-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (coderInfoList): Make error reporting a bit
+ more lenient so that if an error occurs while loading a module it
+ is not reported as an exception unless no coders were found at
+ all.
+
+2004-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (clipMask): Use GetImageClipMask.
+
+2004-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/CoderInfo.cpp (CoderInfo): Sense of isReadable() and
+ isWritable() was inverted.
+
+2004-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: <inttypes.h> is not used. Inclusion
+ removed.
+
+2004-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Thread.cpp (lock): Have not been successful with using
+ MsgWaitForMultipleObjects() reliably, so back out usage of it for
+ now.
+
+2004-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Thread.cpp (lock): For MsgWaitForMultipleObjects, monitor
+ state change only. Otherwise lock may deadlock.
+
+2004-03-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (statistics): New method to obtain image
+ statistics (minimum, maximum, mean, variance, and standard
+ deviation).
+
+2004-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (quantumOperator): New image method to apply an
+ arithmetic or bitwise operator to the pixel quantums in an image.
+ Still needs documentation.
+ (quantumOperator): New image method to apply an arithmetic or
+ bitwise operator to the pixel quantums in an image region.
+
+2004-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (../www/Magick++/ChangeLog.html): Fix execution of
+ txt2html.
+
+ * lib/STL.cpp (composeImage): Added a function object to set/get
+ the Image composition option.
+
+ * lib/Image.cpp (compose): Added a method to set/get the Image
+ composition option.
+
+2004-03-06 Vladimir Lukianov <lvm@integrum.ru>
+
+ * lib/Thread.cpp (lock): Use MsgWaitForMultipleObjects() rather
+ than WaitForSingleObject() in order to avoid possible deadlock
+ when application code directly or indirectly creates windows.
+
+2004-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (interlaceType): Retrieve interlace setting from
+ Image rather than ImageInfo.
+
+2004-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (Image): Delete the allocated image reference
+ object if a Magick::Error is thrown by the Image constructor.
+ Otherwise the image reference object becomes a memory leak.
+
+2004-01-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (WriteImages): Pass Blob::MallocAllocator to
+ updateNoCopy() in order to ensure that correct deallocator is
+ used.
+
+ * tests/readWriteBlob.cpp (main): Needed to delete character array
+ using array [] reference.
+
+2004-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * demo/analyze.cpp (main): Fix a GNU C++ library portability
+ problem noticed under MinGW. The 'left' iostream manipulator seems
+ to be missing.
+
+2004-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am: coderInfo test is expected to fail for moby
+ builds when the package is not yet installed since a .la file
+ exists in the coders directory, but there is no associated .so
+ file. Therefore failures of the coderInfo test are now ignored.
+
+2003-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (defineValue): New method to support setting
+ format-specific defines.
+ (defineSet): New method to support setting or testing for
+ format-specific flags.
+
+2003-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (iccColorProfile): Implementation now uses the
+ profile method with profile name "ICM". Note that this now
+ invokes the color profile if the image already has one.
+ (iccColorProfile): Reimplement using new GetImageProfile function.
+ (iptcProfile): Reimplement using the new GetImageProfile and
+ SetImageProfile functions.
+ (profile): Reimplement using new GetImageProfile function.
+
+2003-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Makefile.am (pkglibdir): Improve header file
+ install location logic.
+
+2003-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * demo/analyze.cpp (main): New program to demonstrate using the
+ 'analyze' process module.
+
+ * demo/Makefile.am: Add rules to build analyze program.
+
+ * lib/Image.cpp (process): New method to execute process modules.
+
+ * lib/Image.cpp (attribute): New method to get and set named image
+ attributes.
+
+2003-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Color.cpp: Ensure that all non-default constructors set
+ opacity to opaque.
+
+2003-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (colorHistogram): If map key is not const,
+ then implicit type conversion occurs. Sun's C++ compiler doesn't
+ seem to handle that. The map key is now defined as const in the
+ insert arguments.
+
+2003-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/Makefile.am: Add build support for colorHistogram.cpp.
+
+ * tests/colorHistogram.cpp: New test program to test retrieving
+ color histograms from the image using colorHistogram().
+
+ * lib/Magick++/STL.h (colorHistogram): Added new template function
+ to retrieve a color histogram into a user-provided container.
+ Verified to work when using STL <vector> and <map> as the target
+ container types. When <map> is used, a user-specified color may
+ be used to perform lookups in the map to obtain the usage count
+ for that color.
+
+ * lib/Color.cpp (operator >=): Insufficient resolution was being
+ provided in order to reliably sort color objects in STL
+ containers. The updated algorithm should be fail-safe.
+
+2003-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (channelDepth): New method to set or get the
+ modulus depth for a specified channel.
+
+2003-08-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h (Magick): Added support for
+ CopyCyanCompositeOp, CopyMagentaCompositeOp,
+ CopyYellowCompositeOp, and CopyBlackCompositeOp, composition
+ operators.
+
+2003-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (depth): Method now only updates the
+ Image/ImageInfo depth member and retrieves the value of the Image
+ depth member.
+ (modulusDepth): New method to inspect the pixels for actual
+ modulus depth, or update/reduce the pixels to a specified modulus
+ depth. The depth method was performing this function so any code
+ which depended on the depth method to compute or set the modulus
+ depth should be updated to use modulusDepth() instead.
+
+2003-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (matte): If a new matte channel is created,
+ initialize it to opaque. Likewise, if the matte channel is
+ eliminated, initialize the unused channel to opaque.
+
+2003-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * demo/demo.cpp (main): Don't crop logo image.
+
+ * *.h, *.cpp: Include "Magick++/Include.h" before including any
+ compiler or system header in order to ensure that LFS defines are
+ properly applied. Inspired by patch from Albert Chin-A-Young.
+
+2003-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: Needed to import ThrowLoggedException.
+
+ * lib/Exception.cpp (throwException): Add originating source
+ module, source line, and function name (if available) to exception
+ report. This is useful in order to determine the exact conditions
+ that lead to the exception being thrown.
+
+ * lib/Magick++/Exception.h: Added ErrorCoder, WarningCoder,
+ ErrorConfigure, WarningConfigure, ErrorDraw, WarningDraw,
+ ErrorImage, WarningImage, ErrorMonitor, WarningMonitor,
+ ErrorRegistry, WarningRegistry, ErrorStream, WarningStream,
+ ErrorType, and WarningType, exception classes to support the full
+ set of exceptions that GraphicsMagick can throw.
+
+2003-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/CoderInfo.cpp (CoderInfo): Applied compilation fix from Mike
+ Chiarappa to compile using Borland C++.
+
+2003-06-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Geometry.cpp (string): Throw an exception if a string is
+ requested from an invalid geometry object.
+
+2003-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Geometry.cpp (operator =): If GetGeometry returns NoValue,
+ then assign an invalid geometry object to cause an exception if
+ the geometry is then used.
+
+2003-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Exception.h (ErrorModule): Added class to handle
+ module errors.
+
+ * lib/Magick++/Exception.h (WarningModule) Added class to handle
+ module warnings.
+
+2003-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (coderInfoList): Use GetMagickInfoArray to
+ access coder list.
+
+2003-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (affineTransformImage): Add function object
+ contributed by Vladimir Lukianov to apply an affine transform to
+ the image.
+
+ * lib/Image.cpp (affineTransform): Added method contributed by
+ Vladimir Lukianov to apply an affine transform to the image.
+
+2003-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: Decided to back out change which used
+ the _VISUALC_ define to trigger inclusion of <sys/types.h>.
+
+2003-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: If _VISUALC_ is defined, include
+ <sys/types.h>. This ensures that this necessary header is included
+ even if HAVE_SYS_TYPES_H is not defined in magick_config.h.
+
+2003-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (InitializeMagick): InitializeMagick is now a C++
+ function rather than a namespace inclusion. An atexit() handler
+ is registered to invoke DestroyMagick when the program
+ exits. Relying on static deconstruction to invoke DestroyMagick
+ proved to be unreliable due to translation unit destruction
+ uncertainty.
+
+2003-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (Image::Image (MagickLib::Image* image_)):
+ Incorporated recommended fix from Jukka Manner to avoid
+ a scenario which leaks an Options object.
+
+ * tests/coalesceImages.cpp: Updated to use modified
+ coalesceImages() interface.
+
+ * lib/Magick++/STL.h (coalesceImages): Replaced implementation
+ with one from Felix Heimbrecht. The template signature has changed
+ to return a new image sequence. This template API silently ceased
+ to funtion due to an ImageMagick CoalesceImages API change.
+
+2003-03-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/readWriteBlob.cpp (main): Added check for stream read
+ failure when reading blob data.
+ (class myBlob): Use get rather than read.
+
+2003-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/attributes.cpp : Change in the way that Magick++ retrieves
+ density caused tests to fail. Density now defaults to 72x72
+ (GraphicsMagick default) rather than invalid.
+
+2003-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * demo/Makefile.am (CLEANFILES): Fix clean target to
+ remove *_out.mvg output files as well.
+
+ * demo/zoom.cpp: Added a command-line parser for dash arguments as
+ well as an image "resample" capability.
+
+ * lib/Image.cpp (density): Obtain density from Image rather than
+ ImageInfo if the Image is valid.
+
+2003-03-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Makefile.am : Added rules to install GraphicsMagick++.pc.
+
+ * lib/GraphicsMagick++.pc.in : Added pkgconfig file for
+ -lGraphicsMagick++.
+
+2003-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (colorSpace): Pass image->colorspace to
+ TransformRGBColorspace.
+
+2003-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (writeImages): Should have been invoking
+ WriteImages rather than WriteImage!
+
+2003-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h: Add HSL and HWB colorspace
+ transformation support.
+
+2003-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (colorSpace): Support colorspace transforms other
+ than to and from RGB by translating to RGB as an intermediate
+ step.
+
+2002-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp: Added DrawablePushClipPath,
+ DrawablePopClipPath, and DrawableClipPath. Implementation
+ contributed by Vladimir <lvm@integrum.ru>.
+
+2002-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (colorMapSize): New method to set, or return the
+ colormap size.
+
+2002-11-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (adaptiveThreshold): New method.
+
+2002-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (coderInfoList): Intentionally ignore missing
+ delegate exceptions.
+
+2002-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Options.cpp (textEncoding): Had forgotten to implement
+ textEncoding!
+
+2002-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Color.cpp (Color): Use of 'new' and 'delete' in inlines was
+ causing memory allocation/deallocation problems for users of the
+ DLL build. Problem was identified by Marc Iwan.
+
+2002-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (compare): New method to compare current image
+ with a reference image.
+
+2002-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (textEncoding): New method to allow setting the
+ default text encoding (e.g. "UTF-8").
+
+ * lib/Drawable.cpp (DrawableText): Added an alternate constructor
+ to allow specifying the text encoding (e.g. "UTF-8").
+
+2002-08-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Overall: Now compiles as a DLL using Visual C++.
+
+2002-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (profile): Added method to store, delete, or
+ retrieve named application profiles.
+
+2002-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (type): Set the ImageInfo type attribute when
+ setting the image type. If the type attribute is set to something
+ other than UndefinedType (implying that the user has set a desired
+ output image type), then return that as the image type, otherwise
+ use GetImageType() to evaluate the image type.
+
+2002-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableTextUnderColor): New class to set the
+ text undercolor. When text undercolor is set, a rectangle of the
+ specified color is rendered under text annotations.
+
+2002-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Magick++ library no longer depends on iostreams at all.
+
+2002-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (throwImageException): ExceptionInfo was not being
+ properly initialized. This could cause some errors to cause an
+ abort in error.c rather than throwing an exception.
+
+2002-04-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (draw): Use draw.h drawing APIs to draw on image.
+ This means that MVG output no longer comes from code in
+ Drawable.cpp.
+
+2002-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/STL.cpp: Moved function object implementations from STL.h to
+ STL.cpp.
+
+2002-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (getConstPixels): Changed offset parameter type
+ from 'unsigned int' to 'int'.
+ (getPixels): Changed offset parameter type from 'unsigned int' to
+ 'int'.
+ (setPixels): Changed offset parameter type from 'unsigned int' to
+ 'int'.
+ (cacheThreshold): Changed argument type from 'const long' to
+ 'const int'.
+ (matteFloodfill): Changed offset parameter type from 'const long'
+ to 'const int'.
+
+ * lib/Pixels.cpp (getConst): New method to return read-only
+ pixels.
+ (get): Offset parameter types changed from 'unsigned int' to
+ 'int'.
+
+2002-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Drawable.h (DrawableDashOffset): Change dashoffset
+ type to 'double' rather than 'unsigned int' in order to match
+ ImageMagick.
+
+ * lib/Drawable.cpp (DrawableDashArray): Change dasharray type to
+ 'double' rather than 'unsigned int' in order to match
+ ImageMagick. Previous 'unsigned int' methods remain for
+ compatability reasons.
+
+2002-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableCompositeImage): Always output
+ composite images as inlined Base64.
+
+2002-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableCompositeImage): If magick attribute
+ string is specified, then composite image is supplied to
+ ImageMagick as inlined Base64 rather than by MPRI reference.
+
+ * lib/Blob.cpp (base64): Added methods to update Blob with data
+ from Base64-encoded string, or to return a Base64-encoded string
+ from Blob. Still needs documentation.
+
+2002-04-09 Dom Lachowicz <cinamod@hotmail.com>
+
+ * lib/Image.cpp (Image::ping): Added PingBlob function
+
+2002-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableDashArray::operator=): Added missing
+ assignment operator (fixes a bug).
+ (DrawableDashArray::DrawableDashArray): Added missing copy
+ constructor (fixes a bug).
+
+ * lib/Image.cpp (oilPaint): Changed argument type from unsigned
+ int to double.
+ (chromaBluePrimary): Changed argument type from float to double.
+ (chromaGreenPrimary): Changed argument type from float to double.
+ (chromaRedPrimary): Changed argument type from float to double.
+ (chromaWhitePoint): Changed argument type from float to double.
+ (getConstPixels): Changed argument type of x_ & _y from 'int' to
+ 'unsigned int'.
+ (getPixels): Changed argument type of x_ & _y from 'int' to
+ 'unsigned int'.
+
+2002-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (debug): Added method to set ImageMagick debug
+ flag so that it prints debugging information while it runs.
+
+2002-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp: Fixed a bunch of bugs related to
+ DrawableCompositeImage, DrawableFont, and inconsistencies
+ discovered by Gimpel lint.
+
+2002-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (draw): Properly delimit individual drawing
+ commands so that MVG output is correct.
+
+2002-03-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableViewbox): MVG syntax wasn't correct.
+
+ * lib/Image.cpp (draw): Fix algorithm used to append newlines to
+ MVG commands so that draw() may be invoked multiple times while
+ still producing valid MVG.
+
+2002-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableViewbox): New class to allow setting
+ the MVG output size.
+
+2002-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (print): Changed "mpr:" to "mpri:" in order to
+ finally get DrawableCompositeImage to work as intended.
+
+ * lib/Image.cpp (registerId): Bugfix. Register using
+ sizeof(MagickLib::Image) rather than sizeof(Image).
+
+2002-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableCompositeImage): Had failed to
+ initialize width and height in object to image width and height.
+
+2002-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (endianImage): New class to specify the
+ endian option for formats which support this notion (e.g. TIFF).
+
+ * lib/Image.cpp (endian): New method to specify the endian option
+ for formats which support this notion (e.g. TIFF).
+
+2002-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableFont): Support specifying a font via
+ font-family, font-style, font-weight, and font-stretch. Wildcard
+ matches are supported.
+
+2002-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (charcoal): Replace Magick++'s charcoal effect
+ with the output of ImageMagick's CharcoalImage function in order
+ to ensure consistency.
+
+ * lib/Magick++/CoderInfo.h (MatchType): Scope the MatchType
+ enumeration to the CoderInfo class so these enumeration names can
+ be re-used elsewhere without conflict. This results in a minor
+ API change to the coderInfoList() templated function since
+ enumerations must be specified like "CoderInfo::TrueMatch" rather
+ than just "TrueMatch". Hopefully not a problem since this
+ function and class were not documented outside of the headers
+ until this release.
+
+2002-02-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (coderInfoList): Finally wrote some
+ documentation.
+
+2002-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Options.cpp : Use DestroyImageList() rather than
+ DestroyImage().
+
+ * lib/Geometry.cpp (operator =): Use GetPageGeometry() rather than
+ PostscriptGeometry() to parse geometry specifications containing a
+ page size.
+
+2002-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Remove bogus cast of blob data in readImages().
+
+2002-01-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (throwImageException): Throwing exceptions was
+ leaking memory.
+
+ * lib/Exception.cpp (throwException): Throwing exceptions was
+ leaking memory.
+
+ * lib/Image.cpp (replaceImage): Updated to properly handle
+ registration ids.
+ (modifyImage): Updated to properly handle registration ids.
+
+2002-01-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (Magick::DrawableGravity::print):
+ Bugfix. Remove "Gravity" from the end of each gravity
+ specification string. Reported as PR#1084 by stefan@dotify.com.
+
+2002-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp, Magick++/Include.h: Use DestroyImageList() rather
+ than DestroyImages().
+
+2002-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Options.h (antiAlias): Bugfix, set
+ drawInfo->text_antialias to control text antialiasing.
+
+2002-01-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h : Imported new composition operators to
+ namespace: NoCompositeOp, DarkenCompositeOp, LightenCompositeOp,
+ HueCompositeOp, SaturateCompositeOp, ValueCompositeOp,
+ ColorizeCompositeOp, LuminizeCompositeOp, ScreenCompositeOp,
+ OverlayCompositeOp.
+
+2001-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (strokePattern): New method to specify image to
+ use as pattern while drawing stroked-outlines of drawn objects.
+ (fillPattern): New method to specify image to use as pattern while
+ filling drawn objects.
+ (penTexture): Method is officially deprecated. Don't use anymore.
+ (penColor): Method is officially deprecated. Don't use anymore.
+
+ * lib/Drawable.cpp (DrawablePushPattern): Support pushing
+ (starting) pattern definition.
+ (DrawablePopPattern): Support popping (terminating) pattern
+ definition.
+
+2001-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableCompositeImage): Read image
+ immediately if provided by filename, register with peristent
+ registry, and pass as perisistant image type.
+ (DrawableCompositeImage): Support specifying Image in memory.
+ Passed as perisistant image type.
+
+2001-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Color.cpp (operator std::string): Color string buffer was
+ one character too short!
+
+2001-12-20 Bob Friesenhahn <bfriesen@sun1107.ssd.usa.alcatel.com>
+
+ * lib/TypeMetric.cpp (characterWidth): Eliminate method.
+ (characterHeight): Eliminate method.
+ (all remaining methods): Change return type to 'double'. Fix
+ documentation in source files to reflect that units are in pixels
+ rather than points.
+ (descent): Renamed method from 'decent' to 'descent'.
+
+2001-11-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (Magick): Invoke DestroyMagick() to clean up
+ ImageMagick allocations.
+
+ * lib/Magick++/Include.h (ImageType): Added some missing enums to
+ Magick namespace.
+
+2001-11-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/CoderInfo.h (CoderInfo): Syntax fix.
+ ImageMagick bug #975.
+
+ * lib/Image.cpp (draw): Delete ostrstream data when it is no
+ longer needed. ImageMagick bug #988.
+
+2001-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (pixelColor): Implementation didn't handle pixels
+ indexes correctly. Now it does.
+
+2001-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (matteFloodfill): Coordinates are long values.
+ (floodFillOpacity): New method to floodfill opacity across pixels
+ matching color (within fuzz-factor) at point. Similar to
+ matteFloodfill except that color is selected from starting point.
+
+2001-10-29 Bob Friesenhahn <bfriesen@sun1107.ssd.usa.alcatel.com>
+
+ * lib/Image.cpp (strokeDashArray): Change to type double.
+ (strokeDashOffset): Change to type double.
+
+2001-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Geometry.cpp (Geometry): Add constructor from
+ MagickLib::RectangleInfo.
+
+ * lib/Image.cpp (boundingBox): Method to return smallest bounding
+ box enclosing non-border pixels.
+
+2001-10-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (getConstIndexes): Add method to obtain read-only
+ pixel indexes.
+ (getIndexes): Add method to obtain read-write pixel indexes.
+ (Image::Image): Send warnings from Image constructor to cerr
+ rather than throwing.
+
+ * lib/Color.cpp (Color(PixelPacket&)): Change argument to const
+ PixelPacket& as it should have been from the beginning.
+
+ * lib/Image.cpp (pixelColor): Reimplemented to be a const method.
+
+2001-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (getConstPixels): New method for returning a
+ read-only pixel view. Still requires documentation.
+
+ * lib/Magick++/STL.h (coderInfoList): Fixed compilation problem
+ when compiling with Visual C++.
+
+2001-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Color.h (scaleQuantumToDouble): Add polymorphic
+ version that accepts double to avoid downconversion error.
+
+2001-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Color.h (scaleQuantumToDouble): Cast Quantum to
+ double prior to division. Hopefully fix bug.
+
+2001-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Color.h (Color(const std::string)): Pass argument by reference.
+
+ * (operator=): Pass argument by const reference.
+
+2001-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (coderInfoList): New function to support
+ obtaining format coder information (as a list of type CoderInfo).
+
+ * lib/CoderInfo.cpp (CoderInfo): New class to support obtaining
+ format coder information.
+
+2001-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (depth): Use GetImageDepth and SetImageDepth
+ rather than just getting/setting depth attributes.
+
+ * lib/Magick++/STL.h (opacityImage): New unary function object to
+ set, or attenuate, image pixel opacity throughout the image.
+
+ * lib/Image.cpp (opacity): New method to set, or attenuate, image
+ pixel opacity throughout the image.
+
+ * lib/Magick++/STL.h (typeImage): New unary function object to set
+ image type.
+
+ * lib/Image.cpp (type): Added ability to set image type.
+
+2001-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (write(Blob)): Tell blob to use malloc allocator.
+
+ * lib/Blob.cpp (updateNoCopy): Added parameter so that user can
+ specify the allocation system (malloc or new) the memory came
+ from. Defaults to C++ memory allocator.
+
+2001-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (fileSize): Decided to change return type to off_t
+ for increased range and portability.
+
+2001-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (fileSize): Changed return value to double.
+
+2001-09-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (colorMap): Allocate a colormap if it does not
+ already exist.
+
+ * lib/Pixels.cpp (indexes): Don't attempt to validate image type.
+
+ * lib/Image.cpp (colorMap): Optimized more for performance.
+
+2001-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (fontTypeMetrics): New method to support
+ retrieving font metrics.
+
+ * lib/TypeMetric.cpp : New class to support font metrics
+ information.
+
+2001-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Color.h (scaleDoubleToQuantum): Inline static
+ method made from previous ScaleDoubleToQuantum #define.
+ (scaleQuantumToDouble): Inline static method made from previous
+ ScaleQuantumToDouble #define. Helps avoid possibility of clash
+ with user code.
+
+2001-08-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (colorMap): Automatically extend colormap if
+ specified index is past end of current colormap. Colormap is
+ limited to a maximum depth of MaxRGB entries.
+
+2001-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (clipMask): New method to add a clip mask to the
+ image. Adds clipping to any image operation wherever the clip
+ mask image is tranparent.
+
+2001-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (print): Add single quotes around file names
+ and font specifications.
+
+2001-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (read): Ensure that only a single image frame is
+ read.
+
+2001-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (flattenImages): New function to flatten a
+ layered image.
+
+ * lib/Montage.cpp (Montage): Montage initial defaults are no
+ longer drawn from ImageInfo. MontageInfo structure is entirely
+ filled out by updateMontageInfo();
+
+2001-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Montage.cpp (updateMontageInfo): Bugfix; colors which were
+ intentionally specified as invalid (unset) were being ignored.
+ This produced unattractive label text when doing a montage.
+
+2001-07-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (medianFilterImage): Changed argument from
+ unsigned int to const double.
+ (fillColorImage): New method.
+ (strokeColorImage): New method.
+ (isValidImage): New method.
+
+ * lib/Magick++/Image.h (edge): Change argument from unsigned int
+ to double.
+ (medianFilter): Changed argument from unsigned int to const
+ double.
+
+ * lib/Magick++/STL.h (edgeImage): Change argument from unsigned
+ int to double.
+
+ * demo/demo.cpp (main): Updated to match PerlMagick demo.
+
+2001-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (shaveImage): New function to shave edges
+ from image.
+
+ * lib/Image.cpp (shave): New method to shave edges from image.
+
+2001-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (quantize): Remove conditions on whether
+ quantization should be done. Now quantization is always done.
+
+2001-06-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Image.h (blur,charcoal,emboss,sharpen): Changed
+ radius and sigma parameters to match current ImageMagick defaults.
+
+2001-02-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Options.cpp (updateDrawInfo): The updateDrawInfo() method
+ was no longer needed. Due to ImageMagick changes, calling it was
+ causing some options to be lost.
+
+2001-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (fillRule): New method to specify the rule to use
+ when filling drawn objects.
+
+2001-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (erase): New method to reset image to background
+ color.
+ (strokeAntiAlias): New method to control antialiasing of stroked
+ objects.
+
+2001-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (channel): Renamed method from 'layer' to match
+ equivalent change in ImageMagick (ChannelImage). Enumeration
+ names *Layer renamed to *Channel.
+
+2001-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Montage.h (strokeColor): New method.
+ (fillColor): New method.
+
+ * lib/Image.cpp (replaceImage): Revised logic so that an inValid
+ image should be returned if a NULL pointer is passed. Before this
+ change the existing image was preserved.
+ (label): Work-around ImageMagick SetImageAttribute bug.
+
+2001-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp : Adjusted to ImageMagick animation parameter API
+ change.
+
+2000-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableCompositeImage): Support specifying
+ composition rule.
+
+2000-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (draw): Bugfix - the primitive string was not
+ properly null terminated. It is a wonder that the code usually
+ worked at all. Thanks to afatela@marktest.pt for reporting it.
+
+2000-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (deconstructImages): New STL function for
+ deconstructing an image list to assist with creating an animation.
+ (mosaicImages): New STL function for inlaying an image list to
+ form a single coherent picture.
+
+2000-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (convolve): New method to convolve image using
+ user-supplied convolution matrix.
+ (unsharpmask): New method to replace image with a sharpened
+ version of the original image using the unsharp mask algorithm.
+
+2000-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * : Adapted to ImageMagick API change which eliminates
+ AnnotateInfo.
+
+2000-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (annotateImage): Brought into sync with
+ annotate methods in Image.
+
+2000-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (annotate): Usage of Geometry parameter was
+ incorrect. Geometry parameter is used to specify bounding
+ area. This changes the interpretation for two of the annotate
+ methods (which probably weren't usable before).
+
+2000-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Color.h (alphaQuantum): Bugfix. Due to change in
+ treatment of opacity member, alphaQuantum() was not allowing value
+ to be set.
+
+2000-11-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableFillRule): New class to specify fill
+ rule (see SVG's fill-rule).
+ (DrawableDashOffset): New class to specify initial offset in dash
+ array.
+ (DrawableDashArray): New class to specify a stroke dash pattern.
+ (DrawableStrokeLineCap): New class to specify the shape to be used
+ at the end of open subpaths when they are stroked.
+ (DrawableStrokeLineJoin): New class to specify the shape to be
+ used at the corners of paths (or other vector shapes) when they
+ are stroked.
+ (DrawableMiterLimit): New class to specify extension limit for
+ miter joins.
+
+2000-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (annotate): Reimplement text rotation using affine
+ member of AnnotateInfo.
+ (strokeDashOffset): New method for specifying the dash offset to
+ use for drawing vector objects. Similar to SVG stroke-dashoffset.
+ (strokeDashArray): New method for specifying the dash pattern to
+ use for drawing vector objects. Similar to SVG stroke-dasharray
+ (strokeLineCap): New method to specify the shape to be used at the
+ end of open subpaths when they are stroked. Similar to SVG
+ stroke-linecap.
+ (strokLineJoin): New method to specify the shape to be used at the
+ corners of paths (or other vector shapes) when they are
+ stroked. Similar to SVG stroke-linejoin.
+ (strokeMiterLimit): New method to specify the miter limit when
+ joining lines using MiterJoin. Similar to SVG stroke-miterlimit.
+ (strokeWidth): Renamed lineWidth method to strokeWidth.
+
+2000-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Drawable.h (DrawableCompositeImage): Add a
+ short-form constructor to support specifying image location and
+ name, but without specifying rendered size (use existing image
+ size).
+
+2000-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Drawable.h (DrawablePopGraphicContext): New class
+ to pop graphic context.
+ (DrawablePushGraphicContext): New class to push graphic context.
+
+ * lib/Drawable.cpp (DrawableStrokeAntialias): New class to set
+ stroke antialiasing.
+ (DrawableTextAntialias): New class to set text antialiasing.
+
+2000-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (transformOrigin): New method to set origin of
+ coordinate system for use when annotating with text or drawing
+ (transformRotation): New method to set rotation for use when
+ annotating with text or drawing
+ (transformScale): New method to set scale for use when annotating
+ with text or drawing.
+ (transformSkewX): New method to set skew for use in X axis when
+ annotating with text or drawing.
+ (transformSkewY): New method to set skew for use in Y axis when
+ annotating with text or drawing.
+ (transformReset): New method to reset transformation to default.
+
+ * lib/Drawable.cpp (DrawablePath): New class for drawing SVG-style
+ vector paths.
+ (PathArcArgs): New class. Argument for PathArcArgs & PathArcAbs.
+ (PathArcAbs): New class. Draw arc using absolute coordinates.
+ (PathArcRel): New class. Draw arc using relative coordinates.
+ (PathClosePath): New class. Close drawing path.
+ (PathCurvetoArgs): New class. Argument class for PathCurvetoAbs &
+ PathCurvetoRel.
+ (PathCurvetoAbs): New class. Cubic bezier, absolute coordinates
+ (PathCurvetoRel): New class. Cubic bezier, relative coordinates
+ (PathSmoothCurvetoAbs): New class. Cubic bezier, absolute
+ coordinates
+ (PathSmoothCurvetoRel): New class. Cubic bezier, relative
+ coordinates
+ (PathQuadraticCurvetoArgs): New class. Argument class for
+ PathQuadraticCurvetoAbs and PathQuadraticCurvetoRel.
+ (PathQuadraticCurvetoAbs): New class. Quadratic bezier, absolute
+ coordinates
+ (PathQuadraticCurvetoRel): New class. Quadratic bezier, relative
+ coordinates
+ (PathSmoothQuadraticCurvetoAbs): New class. Quadratic bezier,
+ absolute coordinates
+ (PathSmoothQuadraticCurvetoRel): New class. Quadratic bezier,
+ relative coordinates
+ (PathLinetoAbs): New class. Line to, absolute coordinates
+ (PathLinetoRel): New class. Line to, relative coordinates
+ (PathLinetoHorizontalAbs): New class. Horizontal lineto, absolute
+ coordinates
+ (PathLinetoHorizontalRel): New class. Horizontal lineto, relative
+ coordinates
+ (PathLinetoVerticalAbs): New class. Veritical lineto, absolute
+ coordinates.
+ (PathLinetoVerticalRel): New class. Vertical lineto, relative
+ coordinates.
+ (PathMovetoAbs): New class. Moveto, absolute coordinates
+ (PathMovetoRel): New class. Moveto, relative coordinates
+
+2000-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableSkewX): New object to apply skew in X
+ direction.
+ (DrawableSkewY): New object to apply skew in Y direction.
+
+2000-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (edge): Change argument from 'unsigned int' to
+ 'double' in order to match ImageMagick API.
+
+2000-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableCompositeImage): Renamed from
+ DrawableImage.
+ (DrawableTextDecoration): Renamed form DrawableDecoration.
+ (all-classes): Complete re-write to write the drawing command to a
+ stream when draw() is invoked rather than at object construction
+ time. This may be somewhat slower for individual draw operations
+ but but should be at least as fast for lists of drawing commands,
+ and is more flexible going into the future. Drawable classes now
+ inherit from DrawableBase but are passed into STL lists and Image
+ draw() methods via the surrogate class Drawable. The upshot of
+ all this is that the existing published API has not been altered
+ but things work much differently under the covers.
+
+2000-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableStrokeColor): Renamed from
+ DrawableStroke
+ (DrawableFillColor): Renamed from DrawableFill
+ (DrawableRotation): New class to influence object rotation.
+ (DrawableScaling): New class to influence object scaling.
+ (DrawableTranslation): New class to influence object translation.
+
+2000-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableAffine): New class to influence object
+ scaling, rotation, and translation (as defined by SVG XML).
+ (DrawableAngle): New class to influence drawing angle.
+ (DrawableDecoration): New class to influence text decoration such
+ as underline.
+ (DrawableFill): New class to set object filling color.
+ (DrawableFillOpacity): New class to set opacity to use when
+ filling object.
+ (DrawableFont::): New class to set font.
+ (DrawableGravity): New class to set text placement gravity.
+ (DrawablePointSize): New class to set font point size.
+ (DrawableStroke): New class to set drawing stroke color.
+ (DrawableStrokeOpacity): New class to set drawing stroke opacity.
+ (DrawableStrokeWidth): New class to set drawing stroke width.
+
+2000-10-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableImage): Added width and height
+ parameters to specify size to scale rendered image to. This is
+ actually a bug-fix since it seems that the correct drawing command
+ was no longer being generated.
+
+2000-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (read): New overloaded method to read an image
+ based on an array of raw pixels, of specified type and mapping, in
+ memory.
+ (write): New overloaded method to write image to an array of
+ pixels, of specified type and mapping.
+ (Image): New overloaded constructor to construct an image based on
+ an array of raw pixels, of specified type and mapping, in memory.
+
+2000-09-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (colorize): API change to match change in
+ ImageMagick. Now accepts percentage of red, green, and blue to
+ colorize with using specified pen color.
+
+2000-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Drawable.h: Reverted Coordinate implemenation back
+ from and STL pair based implementation to a simple class. Maybe
+ this will improve portability. It is more understandable anyway.
+
+2000-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Options.cpp : Bugfix. Some DrawInfo attributes were not
+ being updated. This lead to options like fontPointsize not
+ changing the font.
+
+2000-08-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (blurImage, charcoalImage, embossImage,
+ sharpenImage): Expand order_ argument to radius_ & sigma_
+ arguments for more control (matches ImageMagick API change).
+
+ * lib/Image.cpp (blur, charcoal, emboss, sharpen): Expand order_
+ argument to radius_ & sigma_ arguments for more control (matches
+ ImageMagick API change).
+
+2000-08-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (read): Check returned Image for embedded
+ exception, as well as the existing parameter check. This fixes
+ the bug that warnings are not reported.
+
+2000-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * test/*.cpp demo/*.cpp: Added call to MagickIncarnate() to set
+ ImageMagick install location for Windows. Hopefully this hack can
+ be removed someday.
+
+2000-07-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (colorFuzz): Changed type to 'double' from
+ 'unsigned int' to match change in ImageMagick.
+
+ * lib/Color.cpp (Color*): Added copy constructor from base class.
+ (operator =): Added assignment operator from base class.
+
+2000-06-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h : Changed enumeration FilterType to
+ FilterTypes, and QuantumTypes to QuantumType in order to match
+ last-minute API change in ImageMagick.
+
+2000-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Pixels.cpp (indexes): Bugfix, use
+ GetCacheViewIndexes() rather than GetIndexes().
+
+2000-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Montage.h (gravity): Type of gravity_ argument, and
+ return value changed from 'unsigned int' to GravityType.
+
+2000-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (DrawableArc, DrawableBezier, DrawablePolyline,
+ RoundRectangle): Added support for new drawing objects.
+
+2000-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp: Removed all public methods which accept
+ Coordinate arguments except those that accept lists of
+ Coordinates. Converted remaining drawable object methods into
+ individual classes which inherit from Drawable (e.g. "circle"
+ becomes "DrawableCircle"). The constructor for each class is
+ compatible with the original method. This results in annoying
+ changes to user code but provides more implementation flexibility.
+
+2000-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp
+ (fillEllipse,fillRectangle,fillCircle,fillPolygon): Removed
+ methods. Object filling is now based on whether fillColor or
+ penTexture are valid or not. This reflects ImageMagick internal
+ changes.
+
+ * lib/Image.cpp (fillColor): New method to specify fill color when
+ drawing objects.
+ (strokeColor): New method to specify outline color when drawing
+ objects.
+ (penColor): Setting penColor now sets fillColor and
+ strokeColor. Getting penColor retrieves the value of
+ strokeColor. This supports backwards compatability.
+
+2000-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (lineWidth): Type changed from unsigned int to
+ double.
+
+2000-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (Magick):
+
+2000-03-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h
+ (blurImage,charcoalImage,edgeImage,embossImage,
+ reduceNoiseImage,sharpenImage): Modified to support order of the
+ pixel neighborhood. Backward compatable function objects
+ constructors are provided for embossImage, and reduceNoiseImage.
+
+ * lib/Image.cpp (blur,charcoal,edge,emboss,reduceNoise,sharpen):
+ Now accept unsigned int argument which represents the order of the
+ pixel neighborhood (e.g. 3). This is not a backwards compatable
+ change, however, backward compatable methods are provided for
+ emboss, and reduceNoise.
+
+2000-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Pixels.h (Pixels): Moved Image pixel methods to
+ Pixels class.
+
+2000-02-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (annotate): Re-wrote to improve performance.
+ (draw): Re-wrote to improve performance.
+
+2000-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Drawable.cpp (text): Bugfix: support spaces in annotation
+ text.
+
+2000-02-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (gaussianBlurImage): New function object to
+ Gaussian blur image.
+
+ * lib/Image.cpp (gaussianBlur): New method to Gaussian blur image.
+
+2000-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp : Call-back based LastError class is eliminated in
+ favor of ImageMagick 5.2's re-entrant ExceptionInfo reporting.
+ This should make Magick++ thread safe under Win32.
+
+2000-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (floodFillTexture): Fixed bug due to pixel pointer
+ becoming invalid in ImageMagick function.
+
+2000-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp : Added locking to reference counting to ensure
+ thread (pthread) safety.
+
+ * lib/Blob.cpp : Added locking to reference counting to ensure
+ thread (pthread) safety.
+
+ * lib/LastError.cpp: Added support for thread specific data
+ (pthreads) so that error reporting is thread safe.
+
+ * lib/Magick++/Thread.h: Added thread wrapper class to provide
+ thread-safe locking (pthreads) to Magick++.
+
+2000-01-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp: Added methods getPixels, setPixels, syncPixels,
+ readPixels, and writePixels, in order to provide low-level access
+ to Image pixels. This approach (direct wrapper around ImageMagick
+ functions) does not mean that the planned object-oriented wrapper
+ has been forgotten, only that this wrapper is not ready yet, and
+ users need to manipulate pixels *now*.
+
+2000-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/LastError.cpp: Complete re-implementation of LastError so
+ that it hides its implementation. Also assures that all memory is
+ explicitly deallocated at program exit to avoid the appearance of
+ a leak.
+
+2000-01-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (size): Bug-fix. Set image columns and rows as
+ well as image options columns and rows.
+
+ * lib/Image.cpp :Depth parameters are now all unsigned in for
+ consistency.
+
+ * lib/Image.cpp (write): Parameters for writing Blobs re-arranged
+ again to hopefully be more sensible.
+
+ * lib/Magick++/STL.h: Bug-fix. Re-number scenes from zero when
+ linking image range in container into a list. This provides
+ expected results.
+
+1999-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp
+ (write): Additional overloaded methods for BLOBs.
+ (read): Additional overloaded methods for BLOBs. Re-ordered
+ parameters for one existing method.
+ (Image): Additional overloaded methods for BLOBs. Re-ordered
+ parameters for one existing method.
+
+1999-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (floodFillTexture): Changed coordinates to
+ unsigned.
+
+1999-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (medianFilter): New method.
+
+1999-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (density): Bug fix. Was not setting image x & y
+ density.
+
+1999-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (page): psPageSize() is renamed to page() and now
+ properly returns the attribute from the image.
+
+1999-11-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp: Rename transformColorSpace() to colorSpace().
+ Added colorSpace() accessor method.
+
+1999-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Color.cpp: Re-implemented PixelPacket pointer so that it is
+ never NULL and added a 'valid' field for tracking object validity.
+
+1999-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (quantizeError): Eliminated method.
+
+1999-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (annotate & draw): Changed implementation to
+ reflect change to the way AnnotateInfo is managed by ImageMagick.
+
+1999-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (cacheThreshold): New method to set the pixel
+ cache threshold.
+
+ * lib/Magick++/Include.h (Magick): Added new enumerations from
+ classify.h.
+
+1999-10-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Options.h (fontPointsize): Argument is now a double
+ to match change in ImageMagick.
+
+ * lib/Image.cpp (fontPointsize): Argument is now a double to match
+ change in ImageMagick.
+
+1999-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Blob.cpp (BlobRef): Bugfix -- start blob reference count at
+ one rather than zero.
+
+1999-10-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (Image): Fixed Image constructors from Blob. The
+ image reference was not being instantiated as it should have been,
+ causing a crash.
+
+1999-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Blob.cpp: All blob length parameters are now of type size_t.
+
+ * lib/Image.cpp (write): Length estimate is now of type size_t.
+
+1999-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (rotate): No longer accepts a crop option since
+ ImageMagick no longer supports this.
+ (shear): No longer accepts a crop option since ImageMagick no
+ longer supports this.
+
+1999-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp:
+ (rotate): No longer accepts sharpen argument. User must sharpen
+ seperately if desired. This change is due to a similar change in
+ ImageMagick 5.0.
+ (condense): Removed method.
+ (uncondense): Removed method.
+ (condensed): Removed method.
+ (pixelColor): Adapted to 5.0.
+
+ * lib/Magick++/Color.h : Rewrote to efficiently use ImageMagick
+ 5.0's PixelPacket color representation.
+
+ * lib/Color.cpp : Rewrote to efficiently use ImageMagick 5.0's
+ PixelPacket color representation.
+
+1999-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (condensed): Bug fix. The condensed() method was
+ returning the opposite bool value than it should. Oops!
+
+1999-09-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Include.h (MagickLib): Eliminated requirement for
+ including <magick/define.h>.
+
+1999-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp: Added accessor methods for other key ImageMagick
+ structs.
+
+ * lib/Options.cpp (penTexture): Fixed bug with removing texture
+ caused by change in Image constructor.
+
+ * lib/Image.cpp: Changed strategy such that an Image containing a
+ null MagickLib::Image pointer is never constructed except for
+ under error conditions. Removed existing checks for null image
+ pointer on attribute methods.
+ Use image() and constImage() accessor methods as part of Image
+ implementation in order to clean-up code and ensure
+ const-correctness.
+
+1999-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/STL.h (Magick): Added STL function readImages().
+ Not tested yet.
+ (Magick): Added STL function writeImages(). Not tested yet.
+
+ * lib/Image.cpp: Removed support for 'text' attribute as this is
+ no longer present in ImageMagick as of 4.2.8.
+
+1999-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Image.cpp (condense): Skip condensing image if already
+ condensed.
+ (uncondense): Skip uncondensing image if not condensed.
+ (condensed): New method to test if image is condensed.
+ (classType): New method which supports conversion of the image
+ storage class. May result in loss of color information
+ (quantization is used) if a DirectClass image is converted to
+ PseudoClass.
+
+1999-07-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Magick++/Color.h (Magick::Color): Color parameters are now
+ stored in a MagickLib::RunlengthPacket structure which is
+ referenced via a pointer. This structure is either allocated by a
+ Magick::Color constructor or passed as an argument to a
+ Magick::Color constructor so that it may refer to to a
+ MagickLib::Image pixel. The owner of the structure is managed so
+ that the structure is only deleted if it was allocated by
+ Magick::Color.
+
+1999-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * overall : Removed 'Magick' prefix from all source file
+ names. Moved class headers to Magick++ subdirectory. This should
+ not break any code using the documented interface (via
+ Magick++.h).
+
+1999-07-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickImage.cpp (composite): Support composition placement
+ by gravity like PerlMagick does.
+
+1999-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickImage.cpp (Image): Added constructors to construct an
+ Image from a BLOB.
+
+1999-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/manipulate.cpp (main): Wrote a basic sanity test for
+ reading and writing BLOBS.
+
+1999-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickImage.cpp (read): Added support for reading an encoded
+ image stored in a BLOB. Uses new ImageMagick APIs introduced on
+ July 21, 1999.
+ (write): Added support for writing an encoded image to a BLOB.
+
+1999-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickInclude.h : Use new <magick/api.h> interface to
+ ImageMagick to avoid namespace-induced problems.
+
+ * configure.in : CPPFLAGS and LDFLAGS specified via the
+ environment take precidence over flags from Magick-config.
+
+1999-05-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickSTL.h (mapImages): New algorithm to map the sequence
+ of images to the color map of a provided image.
+ (quantizeImages): New algorithm to quantize a sequence of images
+ to a common color map.
+
+1999-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickBlob.cpp (updateNoCopy): New method to allow derived
+ classes to insert data into the base class without making a copy
+ of the data. This represents a transfer of ownership of the data
+ from the derived class to the base class.
+
+1999-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickColor.cpp (operator =): Adapted to new ImageMagick
+ 4.2.6 as of 5/23/99 which removes X11 compatability functions.
+
+ * lib/MagickGeometry.cpp (operator =): Adapted to new ImageMagick
+ 4.2.6 as of 5/23/99 which removes X11 compatability functions.
+
+1999-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickBlob.cpp (Blob): Support default constructor for Blob.
+
+1999-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickSTL.h (transformColorSpaceImage): New unary function
+ object to invoke transformColorSpace on STL container object.
+
+ * lib/MagickImage.cpp (transformColorSpace): New method to
+ transform the image data to a new colorspace.
+
+1999-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickImage.cpp (ping): Re-implemented to match (requested)
+ API change in ImageMagick 4.2.5. Method signature has changed to
+ be like 'read'.
+ (annotate): Added two new overloaded methods for text annotation
+ in order to support the new rotated text capability in ImageMagick
+ 4.2.5. To accomplish this, the default for gravity had to be
+ removed from several methods. This may impact existing code.
+ Still not sure if this is the best set of method signatures.
+
+1999-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickImage.cpp (ping): New method to obtain image size in
+ bytes and geometry without the overhead of reading the complete
+ image.
+ (uncondense): New method to uncompress run-length encoded pixels
+ into a simple array to make them easy to operate on.
+
+1999-05-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickImage.cpp (comment): Passing an empty string as the
+ comment results in no comment at all rather than a comment with no
+ data.
+
+1999-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickImage.cpp (iccColorProfile): Implemented method to set
+ ICC color profile from opaque object in memory (must be formatted
+ outside of Magick++).
+ (iptcProfile): Implemented method to set IPTC profile from opaque
+ object in memory (must be formatted outside of Magick++).
+
+ * lib/MagickBlob.cpp: New class to support managing user-supplied
+ opaque Binary Large OBjects (BLOBS) in the API. Reference counted
+ to improve semantics and to possibly reduce memory consumption.
+
+1999-05-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/Makefile.am (libMagick): Updated to use libtool 1.3 so that
+ shared library can be built.
+
+1999-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickImage.cpp (montageGeometry): Return Magick::Geometry
+ rather than std::string.
+
+1999-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickColor.cpp (alpha): Added support for setting alpha via
+ scaled-double to the Color class. The new method name is 'alpha'.
+
+1999-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * lib/MagickColor.cpp: Added support for setting an alpha value
+ (unscaled Quantum only) for use on DirectColor images that have
+ matte enabled. This requires ImageMagick 4.2.2 dated April 13,
+ 1999 or later to compile since Cristy added a special flag to
+ allow testing to see if the user has specified an opacity value:
+ "I added XColorFlags to magick/classify.h. If DoMatte is set in
+ color->flags then the opacity value is valid in color->pixel."
+
+1999-04-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * demo/flip.cpp (main): New file. Demonstrates use of flipImage
+ function object as well as morphImages algorithm.
+
+1999-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/color.cpp : New file to support testing the Magick::Color
+ classes.
+
+ * lib/MagickOptions.cpp: The ImageInfo filter member is now
+ ignored by ImageMagick (as of ImageMagick 4.2.2 April 10, 1998) so
+ support for setting it is removed. The Image filter member is
+ still updated. According to Cristy, this ImageMagick version
+ removes automatic sharpening of resized images. The blur member
+ is added to the Image structure. A blur value < 1 causes the image
+ to be sharpened when resizing while a value > 1 leaves the image
+ blurry. Magick++ does not yet support the blur member.
+
+
diff --git a/Magick++/Makefile.am b/Magick++/Makefile.am
new file mode 100644
index 0000000..62230e1
--- /dev/null
+++ b/Magick++/Makefile.am
@@ -0,0 +1,244 @@
+#
+# Top Makefile for Magick++
+#
+# Copyright (C) 1999-2014 Bob Friesenhahn
+#
+
+#AM_CPPFLAGS += -I$(top_srcdir)/Magick++/lib
+
+MAGICKPP_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/Magick++/lib
+
+if WITH_MAGICK_PLUS_PLUS
+LIBMAGICKPP = Magick++/lib/libGraphicsMagick++.la
+MAGICKPP_CHECK_PGRMS = $(MAGICKPP_CHECK_PGRMS_OPT)
+MAGICKPP_MANS = $(MAGICKPP_MANS_OPT)
+MAGICKPP_PKGCONFIG = $(MAGICKPP_PKGCONFIG_OPT)
+MAGICKPP_SCRPTS = $(MAGICKPP_SCRIPTS_OPT)
+MAGICKPP_TESTS = $(MAGICKPP_TEST_SCRIPTS_OPT)
+MAGICKPP_TOP_INCHEADERS = $(MAGICKPP_TOP_INCHEADERS_OPT)
+MAGICKPP_INCHEADERS = $(MAGICKPP_INCHEADERS_OPT)
+MAGICKPP_XFAIL_TESTS =
+else
+LIBMAGICKPP =
+MAGICKPP_CHECK_PGRMS =
+MAGICKPP_MANS =
+MAGICKPP_PKGCONFIG =
+MAGICKPP_SCRPTS =
+MAGICKPP_TESTS =
+MAGICKPP_TOP_INCHEADERS =
+MAGICKPP_INCHEADERS =
+MAGICKPP_XFAIL_TESTS =
+endif
+
+MAGICKPP_SCRIPTS_OPT = \
+ Magick++/bin/GraphicsMagick++-config
+
+MAGICKPP_MANS_OPT = \
+ Magick++/bin/GraphicsMagick++-config.1
+
+MAGICKPP_PKGCONFIG_OPT = \
+ Magick++/lib/GraphicsMagick++.pc
+
+MAGICKPP_TEST_SCRIPTS_OPT = \
+ Magick++/tests/tests.tap \
+ Magick++/demo/demos.tap
+
+MAGICKPP_EXTRA_DIST = \
+ Magick++/AUTHORS \
+ Magick++/COPYING \
+ Magick++/ChangeLog \
+ Magick++/README \
+ Magick++/bin/GraphicsMagick++-config.1 \
+ Magick++/bin/GraphicsMagick++-config.in \
+ Magick++/lib/GraphicsMagick++.pc.in \
+ Magick++/demo/model.miff \
+ Magick++/demo/smile.miff \
+ Magick++/demo/smile_anim.miff \
+ Magick++/demo/tile.miff \
+ $(MAGICKPP_TEST_SCRIPTS_OPT) \
+ Magick++/tests/test_image.miff \
+ Magick++/tests/test_image_anim.miff
+
+MAGICKPP_CLEANFILES = \
+ Magick++/demo/*_out*.* \
+ Magick++/demo/ir.out \
+ Magick++/tests/colorHistogram.txt \
+ Magick++/tests/testmagick_anim_out.miff \
+ Magick++/tests/ir.out
+
+Magick___lib_libGraphicsMagick___la_SOURCES = \
+ Magick++/lib/Blob.cpp \
+ Magick++/lib/BlobRef.cpp \
+ Magick++/lib/CoderInfo.cpp \
+ Magick++/lib/Color.cpp \
+ Magick++/lib/Drawable.cpp \
+ Magick++/lib/Exception.cpp \
+ Magick++/lib/Functions.cpp \
+ Magick++/lib/Geometry.cpp \
+ Magick++/lib/Image.cpp \
+ Magick++/lib/ImageRef.cpp \
+ Magick++/lib/Montage.cpp \
+ Magick++/lib/Options.cpp \
+ Magick++/lib/Pixels.cpp \
+ Magick++/lib/STL.cpp \
+ Magick++/lib/Thread.cpp \
+ Magick++/lib/TypeMetric.cpp \
+ Magick++/lib/Magick++.h \
+ Magick++/lib/Magick++/Blob.h \
+ Magick++/lib/Magick++/BlobRef.h \
+ Magick++/lib/Magick++/CoderInfo.h \
+ Magick++/lib/Magick++/Color.h \
+ Magick++/lib/Magick++/Drawable.h \
+ Magick++/lib/Magick++/Exception.h \
+ Magick++/lib/Magick++/Functions.h \
+ Magick++/lib/Magick++/Geometry.h \
+ Magick++/lib/Magick++/Image.h \
+ Magick++/lib/Magick++/ImageRef.h \
+ Magick++/lib/Magick++/Include.h \
+ Magick++/lib/Magick++/Montage.h \
+ Magick++/lib/Magick++/Options.h \
+ Magick++/lib/Magick++/Pixels.h \
+ Magick++/lib/Magick++/STL.h \
+ Magick++/lib/Magick++/Thread.h \
+ Magick++/lib/Magick++/TypeMetric.h
+
+Magick___lib_libGraphicsMagick___la_CPPFLAGS = \
+ $(MAGICKPP_CPPFLAGS)
+
+magickpptopincdir = $(topincludedir)
+
+magickpptopinc_HEADERS = $(MAGICKPP_TOP_INCHEADERS)
+
+MAGICKPP_TOP_INCHEADERS_OPT = \
+ Magick++/lib/Magick++.h
+
+magickppincdir = $(topincludedir)/Magick++
+
+magickppinc_HEADERS = $(MAGICKPP_INCHEADERS)
+
+MAGICKPP_INCHEADERS_OPT = \
+ Magick++/lib/Magick++/Blob.h \
+ Magick++/lib/Magick++/CoderInfo.h \
+ Magick++/lib/Magick++/Color.h \
+ Magick++/lib/Magick++/Drawable.h \
+ Magick++/lib/Magick++/Exception.h \
+ Magick++/lib/Magick++/Geometry.h \
+ Magick++/lib/Magick++/Image.h \
+ Magick++/lib/Magick++/Include.h \
+ Magick++/lib/Magick++/Montage.h \
+ Magick++/lib/Magick++/Pixels.h \
+ Magick++/lib/Magick++/STL.h \
+ Magick++/lib/Magick++/TypeMetric.h
+
+# -no-undefined -export-symbols-regex ".*"
+Magick___lib_libGraphicsMagick___la_LDFLAGS = -no-undefined \
+ $(MAGICK_LT_RELEASE_OPTS) \
+ -version-info $(MAGICK_PLUS_PLUS_LIBRARY_CURRENT):$(MAGICK_PLUS_PLUS_LIBRARY_REVISION):$(MAGICK_PLUS_PLUS_LIBRARY_AGE)
+Magick___lib_libGraphicsMagick___la_LIBADD = $(LIBMAGICK)
+
+MAGICKPP_CHECK_PGRMS_OPT = \
+ Magick++/demo/analyze \
+ Magick++/demo/button \
+ Magick++/demo/demo \
+ Magick++/demo/detrans \
+ Magick++/demo/flip \
+ Magick++/demo/gravity \
+ Magick++/demo/piddle \
+ Magick++/demo/shapes \
+ Magick++/demo/zoom \
+ Magick++/tests/appendImages \
+ Magick++/tests/attributes \
+ Magick++/tests/averageImages \
+ Magick++/tests/coalesceImages \
+ Magick++/tests/coderInfo \
+ Magick++/tests/color \
+ Magick++/tests/colorHistogram \
+ Magick++/tests/exceptions \
+ Magick++/tests/montageImages \
+ Magick++/tests/morphImages \
+ Magick++/tests/readWriteBlob \
+ Magick++/tests/readWriteImages
+
+Magick___demo_analyze_SOURCES = Magick++/demo/analyze.cpp
+Magick___demo_analyze_LDADD = $(LIBMAGICKPP)
+Magick___demo_analyze_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___demo_button_SOURCES = Magick++/demo/button.cpp
+Magick___demo_button_LDADD = $(LIBMAGICKPP)
+Magick___demo_button_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___demo_demo_SOURCES = Magick++/demo/demo.cpp
+Magick___demo_demo_LDADD = $(LIBMAGICKPP)
+Magick___demo_demo_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___demo_detrans_SOURCES = Magick++/demo/detrans.cpp
+Magick___demo_detrans_LDADD = $(LIBMAGICKPP)
+Magick___demo_detrans_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___demo_flip_SOURCES = Magick++/demo/flip.cpp
+Magick___demo_flip_LDADD = $(LIBMAGICKPP)
+Magick___demo_flip_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___demo_gravity_SOURCES = Magick++/demo/gravity.cpp
+Magick___demo_gravity_LDADD = $(LIBMAGICKPP)
+Magick___demo_gravity_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___demo_piddle_SOURCES = Magick++/demo/piddle.cpp
+Magick___demo_piddle_LDADD = $(LIBMAGICKPP)
+Magick___demo_piddle_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___demo_shapes_SOURCES = Magick++/demo/shapes.cpp
+Magick___demo_shapes_LDADD = $(LIBMAGICKPP)
+Magick___demo_shapes_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___demo_zoom_SOURCES = Magick++/demo/zoom.cpp
+Magick___demo_zoom_LDADD = $(LIBMAGICKPP)
+Magick___demo_zoom_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_appendImages_SOURCES = Magick++/tests/appendImages.cpp
+Magick___tests_appendImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_appendImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_attributes_SOURCES = Magick++/tests/attributes.cpp
+Magick___tests_attributes_LDADD = $(LIBMAGICKPP)
+Magick___tests_attributes_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_averageImages_SOURCES = Magick++/tests/averageImages.cpp
+Magick___tests_averageImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_averageImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_coalesceImages_SOURCES = Magick++/tests/coalesceImages.cpp
+Magick___tests_coalesceImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_coalesceImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_coderInfo_SOURCES = Magick++/tests/coderInfo.cpp
+Magick___tests_coderInfo_LDADD = $(LIBMAGICKPP)
+Magick___tests_coderInfo_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_color_SOURCES = Magick++/tests/color.cpp
+Magick___tests_color_LDADD = $(LIBMAGICKPP)
+Magick___tests_color_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_colorHistogram_SOURCES = Magick++/tests/colorHistogram.cpp
+Magick___tests_colorHistogram_LDADD = $(LIBMAGICKPP)
+Magick___tests_colorHistogram_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_exceptions_SOURCES = Magick++/tests/exceptions.cpp
+Magick___tests_exceptions_LDADD = $(LIBMAGICKPP)
+Magick___tests_exceptions_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_montageImages_SOURCES = Magick++/tests/montageImages.cpp
+Magick___tests_montageImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_montageImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_morphImages_SOURCES = Magick++/tests/morphImages.cpp
+Magick___tests_morphImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_morphImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_readWriteBlob_SOURCES = Magick++/tests/readWriteBlob.cpp
+Magick___tests_readWriteBlob_LDADD = $(LIBMAGICKPP)
+Magick___tests_readWriteBlob_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+
+Magick___tests_readWriteImages_SOURCES = Magick++/tests/readWriteImages.cpp
+Magick___tests_readWriteImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_readWriteImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
diff --git a/Magick++/README b/Magick++/README
new file mode 100644
index 0000000..ad42299
--- /dev/null
+++ b/Magick++/README
@@ -0,0 +1,64 @@
+
+This is Magick++, the object-oriented C++ API to the GraphicsMagick
+image-processing library, the most comprehensive open-source image
+processing solution available. Read the release notes for Magick++.
+
+Magick++ supports an object model which is inspired by PerlMagick.
+Magick++ executes faster than PerlMagick since it is accessed from a
+compiled language rather than from a scripting language. This makes it more
+suitable for Web CGI programs which must start-up and execute quickly.
+Images support implicit reference counting so that copy constructors and
+assignment incur almost no cost. The cost of actually copying an image (if
+necessary) is done just before modification and this copy is managed
+automatically by Magick++. De-referenced copies are automatically deleted.
+The image objects support value (rather than pointer) semantics so it is
+trivial to support multiple generations of an image in memory at one time.
+
+Magick++ provides integrated support for the Standard Template Library (STL)
+so that the powerful containers available (e.g. deque, vector, list, and
+map) can be used to write programs similar to those possible with PERL &
+PerlMagick. STL-compatable template versions of GraphicsMagick's list-style
+operations are provided so that operations may be performed on multiple
+images stored in STL containers.
+
+Documentation
+
+Detailed documentation are provided for all Magick++ classes, class methods,
+and template functions which comprise the API.
+
+Obtaining Magick++
+
+Magick++ is included as part of GraphicsMagick source releases and may be
+retrieved via ftp or CVS.
+
+Installation
+
+Once you have the sources available, follow these detailed installation
+instructions for UNIX and Windows.
+
+Usage
+
+A helper script named Magick++-config is installed under Unix which assists
+with recalling compilation options required to compile and link programs
+which use Magick++. For example, the following command will compile and
+link the source file example.cpp to produce the executable example (notice
+that quotes are backward quotes):
+
+ c++ `Magick++-config --cxxflags --cppflags --ldflags --libs` -o
+ example example.cpp
+
+Windows users may get started by manually editing a project file for one of
+the Magick++ demo programs.
+
+Reporting Bugs
+
+Please report any bugs via the Magick++ Bug Tracking System. Questions
+regarding usage should be directed to Bob Friesenhahn
+<bfriesen@simple.dallas.tx.us>.
+
+Related Packages
+
+Users who are interested in displaying their images at video game rates on a
+wide number of platforms and graphic environments (e.g. Windows, X11, BeOS,
+and Linux/CGI) may want to try PtcMagick, which provides a simple interface
+between Magick++ and OpenPTC.
diff --git a/Magick++/bin/GraphicsMagick++-config.1 b/Magick++/bin/GraphicsMagick++-config.1
new file mode 100644
index 0000000..ab61881
--- /dev/null
+++ b/Magick++/bin/GraphicsMagick++-config.1
@@ -0,0 +1,76 @@
+.ad l
+.nh
+.TH Magick++-Config 1 "2 May 2002" "GraphicsMagick"
+.SH NAME
+GraphicsMagick++-config \- get information about the installed version of Magick++
+.SH SYNOPSIS
+.B GraphicsMagick++-config
+.B [--cppflags]
+.B [--cxxflags]
+.B [--exec-prefix]
+.B [--ldflags]
+.B [--libs]
+.B [--prefix]
+.B [--version]
+.SH DESCRIPTION
+.B GraphicsMagick++-config
+prints the compiler and linker flags required to compile and link programs
+that use the
+.BR GraphicsMagick
+C++ Application Programmer Interface (known as
+.BR Magick++
+).
+.SH EXAMPLES
+To print the version of the installed distribution of
+.BR Magick++ ,
+use:
+
+.nf
+ GraphicsMagick++-config --version
+.fi
+
+To compile a program that calls the
+.BR GraphicsMagick
+C++ Application Programmer Interface, use:
+
+.nf
+ c++ `GraphicsMagick++-config --cxxflags --cppflags --ldflags --libs` program.cpp
+.fi
+
+.SH OPTIONS
+.TP
+.B --cppflags
+Print the preprocessor flags that are needed to find the
+.B GraphicsMagick
+C and C++ include files and defines to ensures that the GraphicsMagick data structures match between
+your program and the installed libraries.
+.TP
+.B --cxxflags
+Print the compiler flags that were used to compile
+.BR libMagick++ .
+.TP
+.B --exec-prefix
+Print the directory under which target specific binaries and executables are installed.
+.TP
+.B --ldflags
+Print the linker flags that are needed to link with the
+.B libMagick++
+library.
+.TP
+.B --libs
+Print the linker flags that are needed to link a program with
+.BR libMagick++ .
+.TP
+.B --prefix
+Print the directory under which the package is installed.
+.TP
+.B --version
+Print the version of the
+.B GraphicsMagick
+distribution to standard output.
+.SH COPYRIGHT
+Copyright (C) 2002 GraphicsMagick Group
+Copyright (C) 2000 ImageMagick Studio
+.SH AUTHORS
+Bob Friesenhahn, ImageMagick Studio
+
diff --git a/Magick++/bin/GraphicsMagick++-config.in b/Magick++/bin/GraphicsMagick++-config.in
new file mode 100755
index 0000000..9733be2
--- /dev/null
+++ b/Magick++/bin/GraphicsMagick++-config.in
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# Configure options script for re-calling compilation
+# options required to use the Magick++ library.
+#
+# Concept derived from gtk-config in the Gtk package except that Autoconf-style
+# configuration information is presented instead so that it may be used more
+# effictively in configure scripts.
+#
+usage='Usage: GraphicsMagick++-config [--cppflags] [--cxxflags] [--exec-prefix] [--ldflags] [--libs] [--prefix] [--version]
+
+ For example, "example.cpp" may be compiled to produce "example" as follows:
+
+ "c++ -o example example.cpp `GraphicsMagick++-config --cppflags --cxxflags --ldflags --libs`"'
+
+if test $# -eq 0; then
+ echo "${usage}" 1>&2
+ exit 1
+fi
+
+while test $# -gt 0; do
+ case $1 in
+ --prefix)
+ echo @PREFIX_DIR@
+ ;;
+ --exec-prefix)
+ echo @EXEC_PREFIX_DIR@
+ ;;
+ --version)
+ echo @PACKAGE_VERSION@
+ ;;
+ --cppflags)
+ echo '@MAGICK_API_CPPFLAGS@'
+ ;;
+ --cxxflags)
+ echo '@CXXFLAGS@'
+ ;;
+ --ldflags)
+ echo '@MAGICK_API_LDFLAGS@'
+ ;;
+ --libs)
+ echo '-lGraphicsMagick++ @MAGICK_API_LIBS@'
+ ;;
+ *)
+ echo "${usage}" 1>&2
+ exit 1
+ ;;
+ esac
+ shift
+done
+
diff --git a/Magick++/demo/analyze.cpp b/Magick++/demo/analyze.cpp
new file mode 100644
index 0000000..650ff7d
--- /dev/null
+++ b/Magick++/demo/analyze.cpp
@@ -0,0 +1,67 @@
+//
+// Demonstrate using the 'analyze' process module to compute
+// image statistics.
+//
+// Copyright Bob Friesenhahn, 2003, 2004
+//
+// Usage: analyze file...
+//
+
+#include <Magick++.h>
+#include <iostream>
+#include <iomanip>
+#include <list>
+using namespace std;
+using namespace Magick;
+int main(int argc,char **argv)
+{
+ if ( argc < 2 )
+ {
+ cout << "Usage: " << argv[0] << " file..." << endl;
+ exit( 1 );
+ }
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ {
+ std::list<std::string> attributes;
+
+ attributes.push_back("TopLeftColor");
+ attributes.push_back("TopRightColor");
+ attributes.push_back("BottomLeftColor");
+ attributes.push_back("BottomRightColor");
+ attributes.push_back("BrightnessMean");
+ attributes.push_back("BrightnessStddev");
+ attributes.push_back("SaturationMean");
+ attributes.push_back("SaturationStddev");
+
+ char **arg = &argv[1];
+ while ( *arg )
+ {
+ string fname(*arg);
+ try {
+ cout << "File: " << fname << endl;
+ Image image( fname );
+
+ /* Analyze module does not require an argument list */
+ image.process("analyze",0,0);
+
+ list<std::string>::iterator pos = attributes.begin();
+ while(pos != attributes.end())
+ {
+ cout << " " << setw(16) << setfill(' ') << setiosflags(ios::left)
+ << *pos << " = " << image.attribute(*pos) << endl;
+ pos++;
+ }
+ }
+ catch( Exception &error_ )
+ {
+ cout << error_.what() << endl;
+ }
+ ++arg;
+ }
+ }
+
+ return 0;
+}
diff --git a/Magick++/demo/button.cpp b/Magick++/demo/button.cpp
new file mode 100644
index 0000000..a38222d
--- /dev/null
+++ b/Magick++/demo/button.cpp
@@ -0,0 +1,104 @@
+//
+// Magick++ demo to generate a simple text button
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2003
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ //
+ // Options
+ //
+
+ string backGround = "xc:#CCCCCC"; // A solid color
+
+ // Color to use for decorative border
+ Color border = "#D4DCF3";
+
+ // Button size
+ string buttonSize = "120x20";
+
+ // Button background texture
+ string buttonTexture = "granite:";
+
+ // Button text
+ string text = "Button Text";
+
+ // Button text color
+ string textColor = "red";
+
+ // Font to use for text
+ string font = "Helvetica";
+
+ // Font point size
+ int fontPointSize = 16;
+
+ //
+ // Magick++ operations
+ //
+
+ Image button;
+
+ // Set button size
+ button.size( buttonSize );
+
+ // Read background image
+ button.read( backGround );
+
+ // Set background to buttonTexture
+ Image backgroundTexture( buttonTexture );
+ button.texture( backgroundTexture );
+
+ // Add some text
+ button.fillColor( textColor );
+ button.fontPointsize( fontPointSize );
+ button.font( font );
+ button.annotate( text, CenterGravity );
+
+ // Add a decorative frame
+ button.borderColor( border );
+ button.frame( "6x6+3+3" );
+
+ button.depth( 8 );
+
+ // Quantize to desired colors
+ // button.quantizeTreeDepth(8);
+ button.quantizeDither(false);
+ button.quantizeColors(64);
+ button.quantize();
+
+ // Save to file
+ cout << "Writing to \"button_out.miff\" ..." << endl;
+ button.compressType( RLECompression );
+ button.write("button_out.miff");
+
+ // Display on screen
+ // button.display();
+
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/demo/demo.cpp b/Magick++/demo/demo.cpp
new file mode 100644
index 0000000..6d66401
--- /dev/null
+++ b/Magick++/demo/demo.cpp
@@ -0,0 +1,543 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright (C) Copyright 1999 - 2010 Bob Friesenhahn
+//
+// Simple demo program for Magick++
+//
+// Concept and algorithms lifted from PerlMagick demo script written
+// by John Christy.
+//
+// Max run-time size 60MB (as compared with 95MB for PerlMagick) under SPARC Solaris
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize Magick
+ InitializeMagick(*argv);
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ // Common font to use.
+ string font = "Helvetica";
+
+ list<Image> montage;
+
+ {
+ //
+ // Read model & smile image.
+ //
+ cout << "Read images ..." << endl;
+
+ Image model( srcdir + "model.miff" );
+ model.label( "Magick++" );
+ model.borderColor( "black" );
+ model.backgroundColor( "black" );
+
+ Image smile( srcdir + "smile.miff" );
+ smile.label( "Smile" );
+ smile.borderColor( "black" );
+
+ //
+ // Create image stack.
+ //
+ cout << "Creating thumbnails..." << endl;
+
+ // Construct initial list containing seven copies of a null image
+ Image null;
+ null.size( Geometry(70,70) );
+ null.read( "NULL:black" );
+ list<Image> images( 7, null );
+
+ Image example = model;
+
+ // Each of the following follow the pattern
+ // 1. obtain reference to (own copy of) image
+ // 2. apply label to image
+ // 3. apply operation to image
+ // 4. append image to container
+
+ cout << " add noise ..." << endl;
+ example.label( "Add Noise" );
+ example.addNoise( LaplacianNoise );
+ images.push_back( example );
+
+ cout << " add noise (blue) ..." << endl;
+ example.label( "Add Noise\n(Blue Channel)" );
+ example.addNoiseChannel( BlueChannel, PoissonNoise );
+ images.push_back( example );
+
+ cout << " annotate ..." << endl;
+ example = model;
+ example.label( "Annotate" );
+ example.density( "72x72" );
+ example.fontPointsize( 18 );
+ example.font( font );
+ example.strokeColor( Color() );
+ example.fillColor( "gold" );
+ example.annotate( "Magick++", "+0+20", NorthGravity );
+ images.push_back( example );
+
+ cout << " blur ..." << endl;
+ example = model;
+ example.label( "Blur" );
+ example.blur( 0, 1.5 );
+ images.push_back( example );
+
+ cout << " blur red channel ..." << endl;
+ example = model;
+ example.label( "Blur Channel\n(Red Channel)" );
+ example.blurChannel( RedChannel, 0, 3.0 );
+ images.push_back( example );
+
+ cout << " border ..." << endl;
+ example = model;
+ example.label( "Border" );
+ example.borderColor( "gold" );
+ example.border( Geometry(6,6) );
+ images.push_back( example );
+
+ cout << " channel ..." << endl;
+ example = model;
+ example.label( "Channel\n(Red Channel)" );
+ example.channel( RedChannel );
+ images.push_back( example );
+
+ cout << " charcoal ..." << endl;
+ example = model;
+ example.label( "Charcoal" );
+ example.charcoal( );
+ images.push_back( example );
+
+ cout << " composite ..." << endl;
+ example = model;
+ example.label( "Composite" );
+ example.composite( smile, "+35+65", OverCompositeOp);
+ images.push_back( example );
+
+ cout << " contrast ..." << endl;
+ example = model;
+ example.label( "Contrast" );
+ example.contrast( false );
+ images.push_back( example );
+
+ cout << " convolve ..." << endl;
+ example = model;
+ example.label( "Convolve" );
+ {
+ // 3x3 matrix
+ const double kernel[] = { 1, 1, 1, 1, 4, 1, 1, 1, 1 };
+ example.convolve( 3, kernel );
+ }
+ images.push_back( example );
+
+ cout << " crop ..." << endl;
+ example = model;
+ example.label( "Crop" );
+ example.crop( "80x80+25+50" );
+ images.push_back( example );
+
+ cout << " despeckle ..." << endl;
+ example = model;
+ example.label( "Despeckle" );
+ example.despeckle( );
+ images.push_back( example );
+
+ cout << " draw ..." << endl;
+ example = model;
+ example.label( "Draw" );
+ example.fillColor(Color());
+ example.strokeColor( "gold" );
+ example.strokeWidth( 2 );
+ example.draw( DrawableCircle( 60,90, 60,120 ) );
+ images.push_back( example );
+
+ cout << " edge ..." << endl;
+ example = model;
+ example.label( "Detect Edges" );
+ example.edge( );
+ images.push_back( example );
+
+ cout << " emboss ..." << endl;
+ example = model;
+ example.label( "Emboss" );
+ example.emboss( );
+ images.push_back( example );
+
+ cout << " equalize ..." << endl;
+ example = model;
+ example.label( "Equalize" );
+ example.equalize( );
+ images.push_back( example );
+
+ cout << " explode ..." << endl;
+ example = model;
+ example.label( "Explode" );
+ example.backgroundColor( "#000000FF" );
+ example.implode( -1 );
+ images.push_back( example );
+
+ cout << " flip ..." << endl;
+ example = model;
+ example.label( "Flip" );
+ example.flip( );
+ images.push_back( example );
+
+ cout << " flop ..." << endl;
+ example = model;
+ example.label( "Flop" );
+ example.flop();
+ images.push_back( example );
+
+ cout << " frame ..." << endl;
+ example = model;
+ example.label( "Frame" );
+ example.frame( );
+ images.push_back( example );
+
+ cout << " gamma ..." << endl;
+ example = model;
+ example.label( "Gamma" );
+ example.gamma( 1.6 );
+ images.push_back( example );
+
+ cout << " gaussian blur ..." << endl;
+ example = model;
+ example.label( "Gaussian Blur" );
+ example.gaussianBlur( 0.0, 1.5 );
+ images.push_back( example );
+
+ cout << " gaussian blur channel ..." << endl;
+ example = model;
+ example.label( "Gaussian Blur\n(Green Channel)" );
+ example.gaussianBlurChannel( GreenChannel, 0.0, 1.5 );
+ images.push_back( example );
+
+ cout << " gradient ..." << endl;
+ Image gradient;
+ gradient.size( "130x194" );
+ gradient.read( "gradient:#20a0ff-#ffff00" );
+ gradient.label( "Gradient" );
+ images.push_back( gradient );
+
+ cout << " grayscale ..." << endl;
+ example = model;
+ example.label( "Grayscale" );
+ example.quantizeColorSpace( GRAYColorspace );
+ example.quantize( );
+ images.push_back( example );
+
+ cout << " implode ..." << endl;
+ example = model;
+ example.label( "Implode" );
+ example.implode( 0.5 );
+ images.push_back( example );
+
+ cout << " level ..." << endl;
+ example = model;
+ example.label( "Level" );
+ example.level( 0.20*MaxRGB, 0.90*MaxRGB, 1.20 );
+ images.push_back( example );
+
+ cout << " level red channel ..." << endl;
+ example = model;
+ example.label( "Level Channel\n(Red Channel)" );
+ example.levelChannel( RedChannel, 0.20*MaxRGB, 0.90*MaxRGB, 1.20 );
+ images.push_back( example );
+
+ cout << " median filter ..." << endl;
+ example = model;
+ example.label( "Median Filter" );
+ example.medianFilter( );
+ images.push_back( example );
+
+ cout << " modulate ..." << endl;
+ example = model;
+ example.label( "Modulate" );
+ example.modulate( 110, 110, 110 );
+ images.push_back( example );
+
+ cout << " monochrome ..." << endl;
+ example = model;
+ example.label( "Monochrome" );
+ example.quantizeColorSpace( GRAYColorspace );
+ example.quantizeColors( 2 );
+ example.quantizeDither( false );
+ example.quantize( );
+ images.push_back( example );
+
+ cout << " motion blur ..." << endl;
+ example = model;
+ example.label( "Motion Blur" );
+ example.motionBlur( 0.0, 7.0,45 );
+ images.push_back( example );
+
+ cout << " negate ..." << endl;
+ example = model;
+ example.label( "Negate" );
+ example.negate( );
+ images.push_back( example );
+
+ cout << " normalize ..." << endl;
+ example = model;
+ example.label( "Normalize" );
+ example.normalize( );
+ images.push_back( example );
+
+ cout << " oil paint ..." << endl;
+ example = model;
+ example.label( "Oil Paint" );
+ example.oilPaint( );
+ images.push_back( example );
+
+ cout << " operator divide ..." << endl;
+ example = model;
+ example.label( "Operator Divide\n(All/2.0)" );
+ example.quantumOperator( AllChannels, DivideQuantumOp, 2.0);
+ images.push_back( example );
+
+ cout << " operator rshift ..." << endl;
+ example = model;
+ example.label( "Operator RShift\n(All>>2)" );
+ example.quantumOperator( AllChannels, RShiftQuantumOp, 2.0);
+ images.push_back( example );
+
+ cout << " ordered dither 2x2 ..." << endl;
+ example = model;
+ example.label( "Ordered Dither\n(2x2)" );
+ example.randomThreshold( Geometry(2,2) );
+ images.push_back( example );
+
+ cout << " ordered dither 3x3..." << endl;
+ example = model;
+ example.label( "Ordered Dither\n(3x3)" );
+ example.randomThreshold( Geometry(3,3) );
+ images.push_back( example );
+
+ cout << " ordered dither 4x4..." << endl;
+ example = model;
+ example.label( "Ordered Dither\n(4x4)" );
+ example.randomThreshold( Geometry(4,4) );
+ images.push_back( example );
+
+ cout << " ordered dither red 4x4..." << endl;
+ example = model;
+ example.label( "Ordered Dither\n(Red 4x4)" );
+ example.randomThresholdChannel( Geometry(4,4), RedChannel);
+ images.push_back( example );
+
+ cout << " plasma ..." << endl;
+ Image plasma;
+ plasma.size( "130x194" );
+ plasma.read( "plasma:fractal" );
+ plasma.label( "Plasma" );
+ images.push_back( plasma );
+
+ cout << " quantize ..." << endl;
+ example = model;
+ example.label( "Quantize" );
+ example.quantize( );
+ images.push_back( example );
+
+ cout << " quantum operator ..." << endl;
+ example = model;
+ example.label( "Quantum Operator\nRed * 0.4" );
+ example.quantumOperator( RedChannel,MultiplyQuantumOp,0.40 );
+ images.push_back( example );
+
+ cout << " quantum operator ..." << endl;
+ example = model;
+ example.label( "Quantum Operator\nNoise Region" );
+ example.quantumOperator( 30,40,68,112,GreenChannel,NoiseGaussianQuantumOp,0.80*MaxRGB );
+ images.push_back( example );
+
+ cout << " quantum operator ..." << endl;
+ example = model;
+ example.label( "Quantum Operator\nTheshold Region" );
+ example.quantumOperator( 30,40,68,112,GrayChannel,ThresholdQuantumOp,0.35*MaxRGB );
+ images.push_back( example );
+
+ cout << " raise ..." << endl;
+ example = model;
+ example.label( "Raise" );
+ example.raise( );
+ images.push_back( example );
+
+ cout << " reduce noise ..." << endl;
+ example = model;
+ example.label( "Reduce Noise" );
+ example.reduceNoise( 1.0 );
+ images.push_back( example );
+
+ cout << " resize ..." << endl;
+ example = model;
+ example.label( "Resize" );
+ example.zoom( "50%" );
+ images.push_back( example );
+
+ cout << " roll ..." << endl;
+ example = model;
+ example.label( "Roll" );
+ example.roll( "+20+10" );
+ images.push_back( example );
+
+ cout << " rotate ..." << endl;
+ example = model;
+ example.label( "Rotate" );
+ example.rotate( 45 );
+ example.transparent( "black" );
+ images.push_back( example );
+
+ cout << " scale ..." << endl;
+ example = model;
+ example.label( "Scale" );
+ example.scale( "60%" );
+ images.push_back( example );
+
+ cout << " segment ..." << endl;
+ example = model;
+ example.label( "Segment" );
+ example.segment( 0.5, 0.25 );
+ images.push_back( example );
+
+ cout << " shade ..." << endl;
+ example = model;
+ example.label( "Shade" );
+ example.shade( 30, 30, false );
+ images.push_back( example );
+
+ cout << " sharpen ..." << endl;
+ example = model;
+ example.label("Sharpen");
+ example.sharpen( 0.0, 1.0 );
+ images.push_back( example );
+
+ cout << " shave ..." << endl;
+ example = model;
+ example.label("Shave");
+ example.shave( Geometry( 10, 10) );
+ images.push_back( example );
+
+ cout << " shear ..." << endl;
+ example = model;
+ example.label( "Shear" );
+ example.shear( 45, 45 );
+ example.transparent( "black" );
+ images.push_back( example );
+
+ cout << " spread ..." << endl;
+ example = model;
+ example.label( "Spread" );
+ example.spread( 3 );
+ images.push_back( example );
+
+ cout << " solarize ..." << endl;
+ example = model;
+ example.label( "Solarize" );
+ example.solarize( );
+ images.push_back( example );
+
+ cout << " swirl ..." << endl;
+ example = model;
+ example.backgroundColor( "#000000FF" );
+ example.label( "Swirl" );
+ example.swirl( 90 );
+ images.push_back( example );
+
+ cout << " threshold ..." << endl;
+ example = model;
+ example.label( "Threshold" );
+ example.threshold( MaxRGB/2.0 );
+ images.push_back( example );
+
+ cout << " threshold random ..." << endl;
+ example = model;
+ example.label( "Random\nThreshold" );
+ example.randomThreshold( Geometry(0.3*MaxRGB,0.85*MaxRGB) );
+ images.push_back( example );
+
+ cout << " unsharp mask ..." << endl;
+ example = model;
+ example.label( "Unsharp Mask" );
+ // radius_, sigma_, amount_, threshold_
+ example.unsharpmask( 0.0, 1.0, 1.0, 0.05);
+ images.push_back( example );
+
+ cout << " wave ..." << endl;
+ example = model;
+ example.label( "Wave" );
+ example.matte( true );
+ example.backgroundColor( "#000000FF" );
+ example.wave( 25, 150 );
+ images.push_back( example );
+
+ //
+ // Create image montage.
+ //
+ cout << "Montage images..." << endl;
+
+ for_each( images.begin(), images.end(), fontImage( font ) );
+ for_each( images.begin(), images.end(), strokeColorImage( Color("#600") ) );
+
+ MontageFramed montageOpts;
+ montageOpts.geometry( "130x194+10+5>" );
+ montageOpts.gravity( CenterGravity );
+ montageOpts.borderColor( "green" );
+ montageOpts.borderWidth( 1 );
+ montageOpts.tile( "7x4" );
+ montageOpts.compose( OverCompositeOp );
+ montageOpts.backgroundColor( "#ffffff" );
+ montageOpts.font( font );
+ montageOpts.pointSize( 18 );
+ montageOpts.fillColor( "#600" );
+ montageOpts.strokeColor( Color() );
+ montageOpts.compose(OverCompositeOp);
+ montageOpts.fileName( "Magick++ Demo" );
+ montageImages( &montage, images.begin(), images.end(), montageOpts );
+ }
+
+ Image& montage_image = montage.front();
+ {
+ // Create logo image
+ cout << "Adding logo image ..." << endl;
+ Image logo( "logo:" );
+ logo.zoom( "45%" );
+
+ // Composite logo into montage image
+ Geometry placement(0,0,(montage_image.columns()/2)-(logo.columns()/2),0);
+ montage_image.composite( logo, placement, OverCompositeOp );
+ }
+
+ for_each( montage.begin(), montage.end(), depthImage(8) );
+ for_each( montage.begin(), montage.end(), matteImage( false ) );
+ for_each( montage.begin(), montage.end(), compressTypeImage( RLECompression) );
+
+ cout << "Writing image \"demo_out.miff\" ..." << endl;
+ writeImages(montage.begin(),montage.end(),"demo_out_%d.miff",false);
+
+ // Uncomment following lines to display image to screen
+ // cout << "Display image..." << endl;
+ // montage_image.display();
+
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/demo/demos.tap b/Magick++/demo/demos.tap
new file mode 100755
index 0000000..ce31c1c
--- /dev/null
+++ b/Magick++/demo/demos.tap
@@ -0,0 +1,48 @@
+#!/bin/sh
+# -*- shell-script -*-
+#
+# Copyright 2004-2015 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+# This file is part of Magick++, the C++ API for GraphicsMagick and
+# ImageMagick. Please see the file "COPYING" included with Magick++
+# for usage and copying restrictions.
+#
+subdir=Magick++/demo
+. ./common.shi
+. ${top_srcdir}/scripts/tap-functions.shi
+
+SRCDIR=${top_srcdir}/${subdir}/
+export SRCDIR
+
+# Number of tests we plan to run
+test_plan_fn 75
+
+cd ${subdir} || exit 1
+
+test_command_fn "analyze" ${MEMCHECK} ./analyze "$SRCDIR/model.miff"
+test_command_fn "button" -F TTF ${MEMCHECK} ./button
+test_command_fn "demo" -F TTF ${MEMCHECK} ./demo
+#test_command_fn "detrans" ${MEMCHECK} ./detrans background_color file
+test_command_fn "flip" ${MEMCHECK} ./flip
+test_command_fn "gravity" -F TTF ${MEMCHECK} ./gravity
+test_command_fn "piddle" -F TTF ${MEMCHECK} ./piddle
+test_command_fn "shapes" -F TTF ${MEMCHECK} ./shapes
+ORIG_WIDTH=`${GM} identify -format "%w" ${SRCDIR}/model.miff`
+ORIG_HEIGHT=`${GM} identify -format "%h" ${SRCDIR}/model.miff`
+for filter in bessel blackman box catrom cubic gaussian hamming hanning hermite lanczos mitchell point quadratic sample scale sinc triangle
+do
+ test_command_fn "zoom ${filter}" ${MEMCHECK} ./zoom -filter $filter -geometry 600x600 ${SRCDIR}/model.miff zoom_${filter}_out.miff
+done
+for filter in bessel blackman box catrom cubic gaussian hamming hanning hermite lanczos mitchell point quadratic sample scale sinc triangle
+do
+ test_command_fn "zoom ${filter} (Copy)" ${MEMCHECK} ./zoom -filter $filter -geometry "${ORIG_WIDTH}x${ORIG_HEIGHT}" ${SRCDIR}/model.miff zoom_${filter}_nc_out.miff
+done
+for filter in bessel blackman box catrom cubic gaussian hamming hanning hermite lanczos mitchell point quadratic sample scale sinc triangle
+do
+ test_command_fn "zoom ${filter} (Width)" ${MEMCHECK} ./zoom -filter $filter -geometry "600x${ORIG_HEIGHT}!" ${SRCDIR}/model.miff zoom_${filter}_cw_out.miff
+done
+for filter in bessel blackman box catrom cubic gaussian hamming hanning hermite lanczos mitchell point quadratic sample scale sinc triangle
+do
+ test_command_fn "zoom ${filter} (Height)" ${MEMCHECK} ./zoom -filter $filter -geometry "${ORIG_WIDTH}x600!" ${SRCDIR}/model.miff zoom_${filter}_ch_out.miff
+done
+:
diff --git a/Magick++/demo/detrans.cpp b/Magick++/demo/detrans.cpp
new file mode 100644
index 0000000..1a515b1
--- /dev/null
+++ b/Magick++/demo/detrans.cpp
@@ -0,0 +1,60 @@
+//
+// Replace transparency in an image with a solid color using Magick++
+//
+// Useful to see how a transparent image looks on a particular
+// background color, or to create a similar looking effect without
+// transparency.
+//
+// Copyright Bob Friesenhahn, 2000
+//
+// Usage: detrans color file...
+//
+
+#include <Magick++.h>
+#include <iostream>
+using namespace std;
+using namespace Magick;
+int main(int argc,char **argv)
+{
+ if ( argc < 3 )
+ {
+ cout << "Usage: " << argv[0] << " background_color file..." << endl;
+ exit( 1 );
+ }
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ {
+ Color color;
+ try {
+ color = Color(argv[1]);
+ }
+ catch ( Exception error_ )
+ {
+ cout << error_.what() << endl;
+ cout.flush();
+ exit(1);
+ }
+
+ char **arg = &argv[2];
+ while ( *arg )
+ {
+ string fname(*arg);
+ try {
+ Image overlay( fname );
+ Image base( overlay.size(), color );
+ base.composite( overlay, 0, 0, OverCompositeOp );
+ base.matte( false );
+ base.write( fname );
+ }
+ catch( Exception &error_ )
+ {
+ cout << error_.what() << endl;
+ }
+ ++arg;
+ }
+ }
+
+ return 0;
+}
diff --git a/Magick++/demo/flip.cpp b/Magick++/demo/flip.cpp
new file mode 100644
index 0000000..61dae19
--- /dev/null
+++ b/Magick++/demo/flip.cpp
@@ -0,0 +1,60 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2003
+//
+// Demonstration of unary function-object based operations
+//
+// Reads the multi-frame file "smile_anim.miff" and writes a
+// flipped and morphed version to "flip_out.miff".
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+#include <algorithm>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ // Read images into STL list
+ list<Image> imageList;
+ readImages( &imageList, srcdir + "smile_anim.miff" );
+
+ // cout << "Total scenes: " << imageList.size() << endl;
+
+ // Flip images
+ for_each( imageList.begin(), imageList.end(), flipImage() );
+
+ // Create a morphed version, adding three frames between each
+ // existing frame.
+ list<Image> morphed;
+ morphImages( &morphed, imageList.begin(), imageList.end(), 3 );
+
+ // Write out images
+ cout << "Writing image \"flip_out.miff\" ..." << endl;
+ writeImages( morphed.begin(), morphed.end(), "flip_out.miff" );
+
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/demo/gravity.cpp b/Magick++/demo/gravity.cpp
new file mode 100644
index 0000000..7b10975
--- /dev/null
+++ b/Magick++/demo/gravity.cpp
@@ -0,0 +1,87 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 2000, 2001, 2003
+//
+// Demo of text annotation with gravity. Produces an animation showing
+// the effect of rotated text along with various gravity specifications.
+//
+// After running demo program, run 'animate gravity_out.miff' if you
+// are using X-Windows to see an animated result.
+//
+// Concept and algorithms lifted from PerlMagick demo script written
+// by John Christy.
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize GraphicsMagick
+ InitializeMagick(*argv);
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ // Common font to use.
+ string font = "Helvetica";
+
+ int x = 100;
+ int y = 100;
+
+ list<Image> animation;
+
+ Image base( Geometry(600,600), Color("white") );
+ base.depth(8);
+ base.strokeColor("#600");
+ base.fillColor(Color());
+ base.draw( DrawableLine( 300,100, 300,500 ) );
+ base.draw( DrawableLine( 100,300, 500,300 ) );
+ base.draw( DrawableRectangle( 100,100, 500,500 ) );
+ base.density( Geometry(72,72) );
+ base.strokeColor(Color());
+ base.fillColor("#600");
+ base.fontPointsize( 30 );
+ base.font( font );
+ base.boxColor( "red" );
+ base.animationDelay( 20 );
+ base.compressType( RLECompression );
+
+ for ( int angle = 0; angle < 360; angle += 30 )
+ {
+ cout << "angle " << angle << endl;
+ Image pic = base;
+ pic.annotate( "NorthWest", Geometry(0,0,x,y), NorthWestGravity, angle );
+ pic.annotate( "North", Geometry(0,0,0,y), NorthGravity, angle );
+ pic.annotate( "NorthEast", Geometry(0,0,x,y), NorthEastGravity, angle );
+ pic.annotate( "East", Geometry(0,0,x,0), EastGravity, angle );
+ pic.annotate( "Center", Geometry(0,0,0,0), CenterGravity, angle );
+ pic.annotate( "SouthEast", Geometry(0,0,x,y), SouthEastGravity, angle );
+ pic.annotate( "South", Geometry(0,0,0,y), SouthGravity, angle );
+ pic.annotate( "SouthWest", Geometry(0,0,x,y), SouthWestGravity, angle );
+ pic.annotate( "West", Geometry(0,0,x,0), WestGravity, angle );
+ animation.push_back( pic );
+ }
+ cout << "Writing image \"gravity_out.miff\" ..." << endl;
+ writeImages( animation.begin(), animation.end(), "gravity_out.miff" );
+ // system( "animate gravity_out.miff" );
+
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/demo/model.miff b/Magick++/demo/model.miff
new file mode 100644
index 0000000..1813b88
--- /dev/null
+++ b/Magick++/demo/model.miff
@@ -0,0 +1,155 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=128 rows=192 depth=8
+page=128x192+28+33
+
+:ZRETNDXRGZSGXQD]TIYRHZQGYPGXOFZSHgcZ]WNYRE\SHZRJTOIQLEYQI\QG^TJ^UJ[SFZSH^VLZRGVPBYUJ\WO_YMPKCYVNYRFQK>YSGUODLF<PMEQMEQK@SOGRNGOJB`[TgfY5A4C2B&6" 1 /
+2A-:#2-$#8-@-
+
+
+'7J_1BW)9MEZ'IZ&6GIY(GT#=N7C%73D 39*;;5?=6IH@URIVTLornaa^_^Zrsoa_[\ZUQMEB>6MJC3@&,#6$7&8';&6./72$ 0#7"3.1/% "          #*   &  UNDXRGWOCZQFZRF\TI[TJYRHZTJZQGYPF]UNSKFWPCZSF\SGVPCXTH[RH^UI]TJ^WM[UJXOD]THYRGVPDTPINKFTNETNCVQDVPCXQEWQHTNDVTLSRNPKESLCTOCQJ>UMF\WPLK<)5-;#7 +:*
+$7" (8+@+?+A*@.B8F%%6& #1)!/Tf7Oa2@V%>RDX%H^+3FIX$IVAP,8!3 <N$:H)EI=ljecb\^\X_\XMJGHC?D@:B>7B=5DA:PLCB>6QOG:E'/ 43/) * * % ,, % !5* 
+# ( ( , )  "  
+  '     WOERK>VOCYRDXSGWPGWQG\WL\UIZUGYOCUKAYPHXRG[UH^VF\TEPI<SMBZRG[RHYSIYQGZRD]UGZRGZSKPK@VRITOGUOGNI?\VLZSIPG?RNEZXPMHCJD>JF>MH<WQHTPJge__aO!./ 3F5F'$ $
+0:0C,A$6 BP&/@+*' /#89L O^.Wc6@R"@PQ_$GY(+?<I:D>G&;A*EK7LM;KJ>ZZQPMG=9/?=6<;3><3A>7GC<B@7D@7C?6@<3B?6FC;RUH#2)&;(8, 460 .
+* ' *    *&9%90( ,0/$ 
+""       XPDVPESMCTODUNCTMDRM@ZSGZQIWQF[TIYQFYQE\TM]VL]UH[SHVNCXREZRF[SISMCXPEZRF\UJ_XNYSFUPEXRH]WNZSKRKDXSITM@RKFQMGLH?KE=c_Uge]WOGOH?TQKXWR\`K.@0 %:*>0 34C=H:H.A. <I3B# % !4,
+4*,6+2.8NW2[a9EI.FK:CE5JJBLLEFC=D@:?;4>:3=:4=<3?<3>>5?>4A>5FB<CA8@?8C?8A=6A>7A>3@<5YXUEH<.<(<': .&=6$7-      
+* *>$6/,/21,!"   
+    UMBTMBSLBUOFWPFYQGVODYQEVPGTNE[UIZSFRKCZSK`YP]UK\SLWODYRD[RH[TIXRGYRF\SI\SLZRIYSGRMBYTMVPGOH<WQGPHAPI@RMINIELIBLG=fd\URLQJAXTJWWPyxp\`H.A!7.
+%87J8HPQ 7B. #5,B"4'3#
+!/9G%)!,'+ <;2AA8II?IG?CA9?=5ED?OLGA>6A@;@@:><5A>5@<4>=3><3><4?=4B?5A>4B@9B>8IF>@>5BA9DA:@=3C?8JIBEC@@B7,;) 33'   % " "  
+4$9(5!, ) - 1'   # % # + -.[RITMDUOEVOEZRJ\SKVNCXQHYSHUNBZRG]UJ[SE\TH_XJaYM\SJZRIZSI[RH\SGVPEWQFTNHZSNYSLSMBZVIPLDPJDPKCa]VXSMWROJE?NKDPQJRQLXUQdc\ebYvslyzq~|qUX>/B%9=P)<M"=IAN ^W!^P$0"5(74:#6:)GI:MM<FC7HE>IGB>;5>=4:91;93=;4=;4==6HG>@<4<93;93><3?;3@<4?=5?<2?=4@=3@=1A>3C?9A=7B<5A=4@?5>:1A=4A>5SPHZYQ880@B6&
+! /,
+ " ,(!   7,A<D$1 % ) /!  ! 0'3&5 5& & 3.]VLZSLVPHXRIXOGVOGWPE`XM\SH\TGYQF\TI`XJ_XJ`XM`XOYRJ]VM[THXPGZSKUPEYRIZSIRKBYSJ^XNUQEWRKOKEXVPQNIRPKQOKMKAUTOab]OMFTOIljdzyp~qzsiywlS[?2C@R!J\-7G>JUa9yh=oY3>D+QXFSVJ_`VQOJC@:@=8992980;;4==687/;:3<<5?=6>=3=<4;:477/;93?<5>=5<:3><4?=6?<5=;2?=4>;1>;1@=6B@9B>8@<5?<4B>6C@;B>7=9/HG@UUO;92<;3?A6% 3 0   "
+    
+0 1* $ " "   & ' 5':#60 , +3!5SNG[UOYQFZSJZSGRJ>[RK[SJ\UH^UI[RHYQEZQG`XK_XLXRH[TK[TG\VI[VJ[UNVQFWRHTOFPI?XRHTOEOJ>YTK[YSZYSURJ[YR``[PPL\\VkkdcaW]ZQ`\VywmqvqhyujVV=;DS[3RZ9NS<MO=MM@FB7>;4><3;9298185.<;58619809;2992;:3982;94:95=<5=<4<<3;:1;:2:91;:2==7?<6>;3=:4=;5?<5?<2<91C?7>;3?;4CA9A=7@<3?<4@<3A>9A@7A?7IGAVXS<<5;:3<;4=?5-% (%  # #
+#       " 
+
+ &
+! ! + . !63/0' WOERMCZQCYQC[SF^WK[SHZVK^XN^ULXOF^UJ]TJ\SI\UIZSJ]TKUODXQIecXXTLXRHVOFYQH]WPXSIPK@_[Sec[db\fe^QLF_ZWWVSHIFefaaaZppessi}zq}svqgusjmgad^S]\QCA7A>5>=797285,;9187198099068.97.86.993;:2;;0:93::2991982981==6==5;:1>=5>>6;8.>;2>=8><6?=4><5?;2=;3<=4@>8EA:@=4?<3<<3??7A=3A:4@=5;91EC=@=4IF>\\T?>8<:5<;4==6=?2 
+"("
+.- 2!     " #
+" # $ (!# ,"6 5$1/_UIWOBWPB\UH]VI[SF^VI]WM`YP_VL[SH[SF[SG]UJ]SK\SL]TJ^WLXRLVSJWRIXQGQLDXTKjg`WUM]XOhd]mkdXWQWTMd`[^ZWba[QOJSRLXWStrjrpetnhliclf_`]VNKBec^hiiEFC54,981<<4??7?>6980883982980;:0;81::1;;0::1993892:8197/98/::2<;3;;5<;5==6:9/<90<:2;:4=<5=<5><4;;1:92@<5A>6B@6?;2=<1==6?=4>=5=<3><4=;3<82KHAiidHF@;80==5995=<4880 -, ) !5 5,    
+"   ' ' "  % ' *
++ 2$70C7K MG<^WNYTIXQF^WJ\SGje[^XN`ZPYPG]TE[SF[SGYQDXQFZTIVOCTLDLE?ebZaZRUNFXTMZTMHD=baYxvpyypyxp][TYVNhe^b`Zttlwtmsnfuogg_U^VJUMDNG=UOEPJASQHkkg\[XWUO@?887/CC>MNN?>798/:93982:9086-:7/981881;:099/780;:2981@?8<91>:2?<5:92870:92;:2;:0<93<;2=<3;:5::3<:4=;4>;2=90=;4>:2<:2=;5=;5A<3@<2?<1>:3HEAa`^XWP:90::2<;39:/;<4=>,0. )12!7!
+
+     
+% & * Qa>KX2%1 ftC7H%"3BT(=T%%9*' .1#TOF^XN]WI\TH[UNZTJ]VLVOE`XKYQFOG=\VJ_ZNRI?XSIgd\b^XPOIYWPljada\}ztee^pqiz|xqdb[uxshhepojsqmdb[]XNWMDQI@PH<XQESNBSMBUPDMI@URMjifeb]iibMNH78087.45077076-97.;;198076/983983;:3<<2<:3;:3:92::4>=7=;3:92;9278/:91983:91::0:91=<2>;1<;6<:3<82;:3;93?<5=<4=:4<:4@>8>;5>;3>:4?=3?;2CB<ZZW[YTII@AA::90::0780<;4><, (   !"  ! " (.& &
+N^8vRxwF@Gg`3cb;Wf76K6HAN$3 1,199,[VL`XMXPE\VJVPEYSGUPDig^faXd]U`[S`\SUQJsrkznmeb^Tsqi{||vutorpktskqqla`[gedWUTNJCKE<HC;LH@OI=TPFTOBTOCWQFUQJVQJXWPSRKnmf\[TONLMMI;:498257-:;4>>888197/992JLH??;771;;3;:1:93<94;93@>9:9278.::2::199.990870:91::2:92;:3<;2=;3;91<92=;3;:1C?<=<3;:2;:3=:0>;5><6=:1?<3@<4A?7VVSZZU]\VEB<98/::2::1972>>602%     %( & &
+, 4'
+!1&5-:7H]c5mwD^d1TW,FU'F\+3@U[)0'=!4( (0FB8^XN`XM[TIZRH]XMliaeb[c_YqpgzzqqmhSOIxvmvuofe^_]Y\[Ya`^XUQjhajhb\YSNMHWUOPNJKF;PJ?OLBNK@MH;PLDPIBQKBSOGNKEUPJMLF`^Xsqirsk_]Wfb[\[Y??=FHA7609:6982972;;5<=888288187188/:90:82::3;93870::3;:1::1880982:91970:82;;3;:2;:3:91=;1>:2<;2>>7>=7=<2<;0::.<;1=<4?<3><5<;2@>4<80JHDiheCB<87-:92;93<;299187/FF=04'
+    " ) ) 4'  $ $4'2HF$VQ&3@KU+IU&V`3JP'R_/LX&QX) $,1(
+)+!LIA_WM^VKb^Yb^X^XR`^Xpoh~}vsqla_[_[Wfb_dbbcb]bb]utoRQMYUNSQKJG>KG@PNFQNIMH@NH>NI=OJ>PK?KE<PK@UOFLG?KF;TODVSLFB;YVQ{ysed_b`YXYVKMLPQOHJH672882980:9244,34,650560992;:378/:;3992882:9288/;:4:;6:92?>786/97/:91<:2;92992::0;9/;92;92;92<;3=;1;:2>;3>=1=:1><7?>5A?7=<4BA:jlgWUO98-<;4<92;:4:93::365.LNC*0 )#  ++ 12
+    QP,vGVX-[V.QR*@J%9B;CLT&9A**&5)"-#( 22)QL?YTKolgpif~yt~~yyxtecb_[Vc]Wwvtmnkca_X\ZV[[WUSMID=LJ@KHAJEAIE@NICNH=NH>QLCQK@OI=QMCSMDWSKXWMYWPZYTge]ge_nlhZYXXWT^_YSUQZ[X=<9883::665/87/561;:29938:7870871670780772770982;:565165076/86/871891:91983;;1<:099098/:91;82<94><4;:2:81<:2?;4?<6=<7@<5A>7>=5TSLpphUUM:91<;3991:81981<:39:2:93OQG!)+*( !
+ 40 #)
+9H,dqE$/*::=$)- :I#JY.T[+HW* 1'9/ & 7@$=?0ZXQC@8HE>JHA][Sfc^^ZVd_Xc`Vlj`gb\ZVRZWPVTPVRMoh^qmc_]W{wpmjgVSPLI@MJBMICID;KG>HC;PMELIB[ZWjigjkfSRI_\Xigcaa]HHFd_]khcYYT77164.560;;59:245.871:8189266.78188365/DC=DD>55/98198076/65.76/973982981:94882;:1;:1970981:9099/:92981<91<91=<5>=5><4=;4=92CB<JIEMJDSPMDC>980:;3991991<;4;;6993>>8?D7)-2#. -
+$ %   ' ?L1BT,$, 
+UY5Zb9;M#_f8]i: && %(*=FEQ'/"><6\\TUTIUQAIE=A=7B:2HE<C?8HD=LF<IB5?;0RJ?H?5IA7PJBSNDb]TQOIdc[liahe]^^Wppj][Vgg_YZUcb_XVUONH_^S[ZSrnftrmiijYUQkh`aa_OPM773652<<6EG@DE@65/76155.782760872772;<7??9780992670760:94993660772983:92=<5881;92AA9><687/97/:91;;2;:3;9/;90=;5DC=<;4;;0=;3<;5PPELO>?>9:92;:3<;5;:5::4>=7;;4771>=8;>-( ( , !." 
+" "   * "   
+.3DK&!5'33;*/03(%% .#51? 5- 97(ig[}zrolfwtlwtjtqjvrksy{~v~rsriefYa^OYTGXRCIG965,EA7RMAQLEXSKJG>NMFJFBHEAZWOca[qoh|zp}|qsrm}~\\Z^^X^_\FHEFHD==99:3672=>:65.64/65067198297299355000,68355145/3308:6662?>:992;:6><9<;376/BA<LKF;:5;93880:9/=;2<;5;;3:80?>7BA;@>6;:1><3=;2KLBLX7.3"@<8;:1<;4;:4;84<;5<<5;:4982A@8)5) $/ %,
+#/*   ,!    (80#
+ )"2!//#4!5 4-"6719JC#,-4"&==1nkbzun~x~kicvff[}uzv}}pvxnuxviwuhvuhkj]ggZ_`TZ[PGE8B=5C<6E?5IE9UQIUTMA?8dc[dd^JLIPSP894==:79413-77387489346077156034111-44/:83A=8@;5;8387411-::665.76.:93=<577/;:3980@?::94;:2=;1=90;:2:91:92=92<91=<5<;3;9398/@?7?J.*
+47,??6:929828839:3<;5;<3:91;92BD9)3&/&
+  
+         
+#!
+$+(
+(1$." +#2/"/$0' ,& &-IJ=mmfqrmrqltwox{tgf_gi_wy~}|~olbytsjg^WSGJE;36&*2MNDWWP]^ZOOLJKI>A>BDA?A?45369368533013/34194-?9/F<5J@:OF?SIDHA=C>:98143,87/76/87199156.:92@?::90=<4;;1<:0<<4;:2<<5:90;:0<;3=<5981:81=<53>%-(99/>=3::1981;:5<96<;4;:18819:4<?0
+ ,
+ &!         $0'% =9,- !+1)3#2$.  $- -&/"$NOJjjdy|ig`qqkmlh}{{}swvnztxm}\XRge^\WOifasri|zr}|pw{uxxuk`bS( #+6"CH>VWRY[UCB@32034/88367534152.4+#<2%E:.PD>TIBYNFND?G@=H@>E?:<:4640881870972883883;93::3;:3;9099198387/;:4>>:994;;4<;5;80980><6>E.$
+%=<3;:1:93971:92;:3:91::39:3>>6+,& %$ ,43     :A"@I%"## 7@#@L&(6!! .# '&5(
+.,(TTQoohhe^rqmxztNMLz|w~[ZV{vxq\]Xsrkywpd_WXTM_ZS`XLOG>`[Vyvtkx{~uvvpf]XOSUF  
+  )+ AJ8KNBAA932-55353.-$-"<0#I=1H<0K?4NB:B80?71<5/A;4C;7>:576/450550750883:;5::5<;697/;:298088.980<:6882::4992980880>:5>A5 "%@@7981:92983992<;4<;4<<4981>?9,5!/!40- 0&       !)EN&FL'!(   "-%3, !#     ?@7ee]ffclkh]\Xac][\YRPK}RPKsro_\WSOFed[KE=YQHaXM\UI`[Romg||woni~xywvnwywofcX29%    ' (<=K.CI:?A:+#'3%E3#P<)\B-jL7yYArU>pT@cI5Q@1F9.C9196/44-35.770791991:9287/:7/87/981;:087/;94;:298/=:4;71;70:70KMD! ! ! /4'>=6771:93891:93<;4;:2;:5994<A3#5+;0 2' 1 
+&*)3:G'4A#4?MV)KW(3=,5   $""!  '450DB@wvo\\WNJBXQHlhbTROURP^\W[VNNI@XRI[TLaZPVRFVNDVOIrqjzzsYXSnlheb]ljeXTMZZI$+   % 2 "9,@)/#4!W;%^>wKUДeԕfZ]\kLoP9]F5A9243,66.68088/:8275055.75.:9197187087/::287198/75.:82<9276/FJ=*&!1(!46.<;3;;1<;3982;:3;;3::4992:928>-  '#+  09?P)@P)JT0W_7Xb5<K$0;+2      !- &32:!``Sed]TMDSNE_c_POLMKIca^qmeVNDTMDXQH]ZOXTI^XL]VIb`Z_`ZNLEccbnmiig`VPIWSLd`YZZN$7'" ! & *
+.D-C
+&eF+vLӕakyropΔeyS`DV@12.'43+44-86.75.65.66176165.:939:255+870:82881770860@?7CC<Y[P" -"* &;;3<:3:92:92;:3983:9488175/?>7!$
+    
+0; ;L%1A7D 2ABO)4A"/ "    0&    5BDR,9L%K`/K^//=,2!FC:YUMYXTLJDLHCOIBke^[ULQJAVMDZSG]ZTde]a^S_]VllersmHFCXXTqmeWQI{tqiQKBVYF(:(
+// . ,>*9 ?+xOӓ_fr|~{mחdƉ[wO\@4*",.'23.33,57/67.65087154.99445-78187276177/66.75.<<6=>8\\R)3# ,/%4#.*0 984:92993884862;:499476/86/;;2  &$(3@#FR.$7*:(2/75=<H#&7   90
+ #5=;J"DY,BW)Od3CS(3C<J%?E2MKDSMGPKBSKAWRKYSIWOCZRC[SDZUNXVKPI@XUPonjqsmYXRSQLfc^RLEfd^ZWNOJ@]WLUVC%5"7 4
+$ aD*Sܗ]kt{ywroܙi̍`|NrMH5%)*#33/33+33*55/861751;9465.66-66077066/76075.65.66131.caX;?+ *231+78:+98298297287165.88188/65,;:3+-% "5,$-(/&.0@)8)5%419;=7@1A     5>& ! 4GI]/EV+<P$;MN_0H[+(<"/?A6QNFUOGUQHUODaZPZRFXQBVN?UNDXQIZVPQKFOMF__ZKGAHD?RKBMG?RKBWODXOGWPEPT@+<,    yT2āNޒ[hklmoopeܗcɉXzNvO_C.&$45012+11-21-65076.65/43.65/54076177065/75055.65153/RQKOQ>&/ 1/+9OV798-98188265076.87/77.68044-BB:#!.%4BL(39 '.?:K&2A1CEU,;D!0<<L( '"+ 1"  ' %# 'JN*53"0.B/A++ /DK\,3B* % ,
++6@B6MIAYQDXPCWPCc^O_XJVPDUMDXQJWRKNH?HC<SNEMG@UNFUODRLBTNDTOGUPDRMCPSA!)
+)Z3}DߔYdhkpmlibԏ\ÂR|OsHeE,)& 66000+12,10*54065/42,43-65/44-64-65065/74,76075/31*986VYL( #
+"4#8'&/.4!8:288276276/75/77378466065/CB.;>%1?I$6A1=,>4E=I!FS+?M%5F"0A6G#&7#
+ 6'! 
+:1HA'/*" !"*HG)./# 'AV,Rg3<M.) &+!027#GC7[SH]TG^XLZRGWSGYSJZRJ\VOPJ@SMDQJBPJ@VODYSIUOEUQHZUMVPGMF=XQHTUF
+6#e;͂DTk{͆ʃvehjk֔bŅSsDeD(&#/0*//)00,/0*32.43,43+64065044-54-34-87355/32)54,54.674NPI*1! ' "0-"   /2):90871660873:8387087123,A@79:'
+'R`6:J   
+ +' & .3!LF:[SF`WJUOEUOERL@TNCWPCUOCQJDPJ@QJ@RLCUOESNDQJBQKBPJ>QKA\YVLLB9/]@)@$vG׊JڐOՕ\QOޜcd[bcٗb\sLqDmI)% /0+//)-.(12-/0(12+23-23,23,54-45,23*33,13+33+54.54-771HIE/7*0 3:( & !&  560870893:9475086-77168043-GG=MT.is>=O$+;GP%08.75A?M$6D /?+9.A#2D$'3   )+  #-  #$# "  /%5/#   " 1 /BBM*;=*RNCZTJVMBVOCYREUMCTLBWPKRMCTMBSK@RJ>YTKTODOH<QJ@LG>:85?<8_D/wI~L'zD~@uLzYeHa;!d6g4ԈN̂L]3f;hA#b?jDuL+<-)*%./),-&./(/0)/1+33,33+32,31,32,43.55.77023-75,54+/.'IGDFG/-25F#." * %8(: "<<476199478067/662771650872\`?}DLY&)TW-:A7C0>?M&GU-1@ %6&!
+-' #!(*(" # ', ! !
+ 6%<?R!DV$+@-:?>/SLC\SHZRFVMCQI>RKDQLBUNDTLAULBPIBPKBSMBLF>KF>GA8G9._<&΅Nj6ɅIʅHd@'XB3S?1mS?^?i7҇KpAjA#W?)_H6UA.iI/_8vZB66/()"./(./*.0*//*10)21)22*1/+44.12-54/54/24.32,43-1/,FD>MR?*0,  !*'8( 64.:9377266067067077/76212/99/qxIQc.9H"BD\`3?I"9GIZ1H\0Ma6:J!# )+ %$)'     &" !  !-*='<*#7<M<Q0G/?6:!C@2YQG\UJRK@PI=QI>TLBTMAUM?QK?QJ>QJ?GB9G@7PA4@.#kF0[|F͈KisHyW;ZA,{\BnKɈTl{NwO7[@1D1&V@0lE(tG|Z369(A@<*+'/0+./(..(//(20+31,43/00*12,12-11,22-32-12/542<=:EK@   
+ ) ;:365.871:8387.87.77/77.32.IM8bqFJR+OR*\e8GX/Qe=8N%3DKX1=F! !  &  !#   (!'!  
+   "1+A,C(=0 !1 >PAS!';2C'9$/01!ID<TOCSK@QI?SLASM?UMAQK@NG9MH;KD:PB6I5*6%qL4is=ȄIhtMjCwOŇVhٕcjG^DqI0X7QwI_8
+ *+$99/75298477187087/86,33,66.NR0LV)Q_-M`0Uj<Nc6DX+;F!5:FF$  ,("#   )2+5LR/CG"?D!:8!! +:,=4@ %$ 4D9L2I7I:J(<.AAU$7J:L!6E)<,@- 7<AA0ID;VLBSM?QK<SK@OI>MF<QLDQG=K9+F3)5' V7$dw@t>\otlk_kb{Oʊ[PʌZʎ\uHe92!4
+,::?/12-01+,.'./)00(10*33.//*22-01+01+32*12,22-.0->><        65/86066077176/33-55.33,44.48&.=+9>R'Sc80:?I*6D>M U]0-,'%  "+, !(' GT+jm<sxDFP*   6C!AT#FW'[d;KZ/,B*@=NBT'LV&IO*==P$N]/6G<O#6H7I ,?'+8+:'66*WRHUODUPEQI?KC9LC;TA7H7(F7,7*#2dBk@h7یPcu{p^{̏sǃOfng}MwLi[, 91G*?9J"EL;@A:--%00*/0'0/(0/(13+43/0/,00+11-21,43/333FGF)-#   #    $ ' ##:9276/65-65-44,65-65.32+33*AN.( -,8$+.!3@R&Oa3'3",$(   #!'#3267?L&TZ6NW14<
+"ER-;H#,"(<:0OI?PJ@NF=R?3N:,I8+@0'5(!+  9 g:q>ߌRdpaӁIЇOvՌUp>ِYhҋYg>aL!7D0H,C$ ?R'EM811+,+$11)--'12-56/00)33-34-44041.20,762895')"
+$* !  % ,' 53.77/76.66.54.54-65.64-0/'HL736(-=8D 1?1D5K"BV-   "(-4-  *,GB3>FV/Xe;@H$@I- '-&0:H&Rb7IX+2@ 20CDX)L^6CT+R]6ER(&8 =L"KY,@O$-;
+$
+&4HO.T^:>M*+  ,0A?4OA9Q=/J7+D2'9*"."(-_4c3sAQUhЃOa1d.S(b9̄T˂Pj>Q."),A-A!2  1F5G?G212+-,'0/*-/)-/(00+01*22-22,33-63/22,783661 
+'  ') /,$&'78265/44/43-55.54.54,21*34+&,+6BS)P`6=G#:F$8J"0;$ )!/. &- +!0) & -/@Zh:CI&*. DP'KQ*DM(7F5?:J>U!8N9H>J!?L$KZ-FR'[d:nn</4 -?,>$91/#6!4&7'3,;38!N?3M:/I8.>.$2%+$  V3j:j:҂ITeiiݎWێ]džYłTk=W/qP(6B0E2 % /@@T"<P1D@J0CC;33123/22,-.(23.34-00+22.552.0);<8DG@ ;CIT(#- 
++* !0%.#' $01*86/55-65.54-54.65-21+22-7:)7>UY0V`8N^7EU1:G :B>3 
+\6tAi9xAڋL[yQ^DaIU;bC}Pf:U/n\.7J7I-C 25F#=O&?OCW%3G&18%>>:.0,01+./(12+12-11*11->?>3609:5IME/<]`2KN&   !() #%
+"88266/76/65/54.55-33+0/*63*jjHhnAOW/>J)6B%8B#DM)wS8
+>K&DR*9E"49S]7T^5>J!We;DN)Ua6We;AT*IY+Qb0Pd2Q`3GP*GS+@N#3CMO&ea/'3* <K 7E&10:;G0B@M#HQ,GF,M?,K9)J8*@.$. ( . c4i7z@y>^9C92-'"+'/'[5c6V/HI=P;K*<+
+/8K"7E;L- %:F,FHC,,(450451/1,995552663674>?<=?9(1#*
+     
+ 45-75/54+55.54.43-54+43+.,%[^Dl{IBM!&1+38AEH'L.aA.bJ1ӠΗurS@L6(#   8AR[32B'2$1<D$KP+AJ%KS.M\/R[3Y`9KY-9K <N#GV-^oAT`7?J$3A^p?M]24A8@.(7KQ09EFQ)QW1;A;DDI)FE+96 H?,N=/H8+A0'6'* $ [2_-k8n:h=[GYPSKLAO<Z3\4dK"/?EX!1A6G7L1EAQ'AR&5G+ 24
+ 4 8E*==6,-(47565622.330562684AC?;<8&1+ ! (+     $-54/44,55-64/43,44+43,0/*36)_oDgvE;F39*2,2 S2^<O1S5{Uݕiy؞tk×ukJ65+0?!;K&0>Vb:2=@M'Wa;ER(<K"Q_8Vd:<E#;A"@N%EW)CP#NX.RZ2BK#EP&IS&]i77C1;OZ4(7-5II/78>= >>#246A2;.0A<$H<)L:.F6+9)!/"#^8j8[.h6h6T';;G#Y0\2[:aR%BT>U!6L=Q >T#?R$@Q":G'0"* )6?ATM#ABDK5;>8-0+?@>893340586685CFD=@>/;&0 
+!# "")8H'68+54-43+54+54+42+34*11*/-(Q[;^n>#0 $-'65Bb:qE'sA%T9Z:U/k<j~~ΔrnT_E/xlD  ")(3GT.]lBDR&CR'GV-HX,Q]2CQ'[i=[i:Q[-S]3KT+RT-fl=T\3Z`;L[0MZ2JT/:B!HS1=E*AE)<B"5: #-EU//>&0?<'M>/J7+?.%1$!O/ˁJ]-c0t?J}MwGsFe;`8\<hXa.=O-C*@5KDW)=N+7 ' &7e]3u_5gc2,9BE>AA?+,(685=>=676;<;CFD>A=29(#5&5$ '-$%!##&67-5):KZ4JN40/'34,43)42,31+43)33*/.(AC1GY-Uj:3B,BDV+gC*S3`:!`1ϝІ[C Ojrvהlޝu֖mdvU?
+CT.L^2Xb7U[1R\2Tc9_nBXa9KW0FR'S]2PY2EP,LW/KKZY*\^@KN2GS+PY1:E$4BGT,CP+HQ1<E$#35G#GV1AO(<B%B9+I:/@1&6'&!#!l>&҇P{E`.[)g6a4\/[1\7e@]9%+
+1;'GID,/,586-0,8<8<>:BC?XWL?J(/B';/; 
+h<ٍO׈L}Ch1V%Y.i=nCuHpL_C1==$?P%AW&;O$0
+3 6 +@)>&, 2 + ( ?E622011.563>A=<=;797POI>E*- .<!*$2+>R^6Yg=IY.Va0jm;GP&V_5NO310'33,43+41*32+43/54/10*66+0:,91=<K)kW~]KxZIoM9iNS4$H&kFҊ`ޑ]uyys֎d{WuTʖn;6&2?K*JY1EU(4C)66A!<E'6>M]0O_3<I%3C);.>=M*;D#16#+-0067AAF$897CGU*FU+JS.KI.NA0I7+7( ,!$"&2' &%+4'4'3#(
+}I'φK܌MیO͂Ct<s?tAuEvHgGX@1{uh8:2BK;@H44>.6A05@,6B+*; - 3 )B4 * !0CF:0/*:<87848:7474@A=@J3%8 @S!5I0
+HW)K\.,;>Q$Ve8Q\+\h6>P$9GEO'13%22,33+43*43+22,24,31,64-9>'5E2G/Bo[`NyWC}ZFnH6E/0+qT0ԋ\ӃO\v|{y˃]gF‰b[I+?H&Ud>Qb:AU)<J%-2<=#3:1<LW2:E$<J'<L%5F5F->6A=>'.)24=>O%2<;B"GW,ES&IR/DA&IA)L=0@2(4'!*!0#!.#6*$/$ '+ 7) 7);*,`7l:ӅHڌJֈI~EvDyFyFuE[<WE6E?=99=@@DDBIDCKIGOLMPGKNFLFCM;<L+2F'?.E?N)KMD>?>>?<=>;?A;BD@BK92F9IBS%J^/Q`39@!* `h:RW+LS(:H!);,=0?8?$00*33+65,55,65+43*43.53+=?.4F?R,@Q*bLfQio_ELD#IS,>C!f;Y`x~{{kqOiI]<)[P2_i?_nBVg;?H%66@B%,;BQ+QZ1?M$BO*EU.CR,@K(7= 1:2@*:%1/;LY+QX.BEAI @I':;/'H;*D3)?1(3&!4& 4('6'"6*$0$ *2'8+"<+"D1&1$E*[2zA҅GЂEw@s?uCwFzKkF*`SC{+)*BBG@>CA>BAAFEDJGGLKJQMLRPOTJLIGP7J\/9KNR5KHF@A=563>?<@CAEJA*5! (4CH$VS/Y]8<D:C9E"5D#>M';L&7J"=N,-/%43+43,43,64,54-54.43+98-3@ 6J"<M#nw~nT:YZ3PS-MX5gU6j?ߏYhtw|{ԋdS5A!\<*aW5RZ4?G$PV.\c=;E$8G!M\1R\3LU.9D;I%:H%/;#',53B8C+6+8ouI__6n]"WK651(7,#K</B1(=/'-;+#9,$.#;-&7+$0% 0#7*";+!C1%I6*;,"0#vH+q=y@w>n6r9{EȀKvGQ2l_S-'(>?EEBHB?DB@GECHHFNJGMIGLHHOKJRNLUMPLBI-KL!QP@?>=341?A>@A@?@>"  039:)(1:8B>G GN-JX5N`<O`;@T-:L&.5!22,34.34.44.54.76/43)53+6=&-B(;¦ѵŢ}caT2FM(KU,OV)p[=jE-T/n?~I]jwktQQ-F(dB-ZN1?I"\e7jnGGP.;H"6E2B:J"9D!8@;H#2A#/+6BN$JU*NU%RX+:>(.DHQN$IE6?63C7/I:/E6.3&0#D4*>/'2& ;.%4(!:-%3'2%A/$C2&M:-H6,,!Y;+g=|Fv@q;x<҄HɁLlAI-uj^<63;:?IFJFCGEBIIFLIGNHFNHGLHFJHFJJJPLKQPOSKR5;G&KMH67457401+8:4DG#?B MR/35184=<B;C#4<EQ.IW1CQ+?Q'3A!00)54064/64,65+65/54-32+;=/;M,-@æ ~ǢlX]0GS%]e9Z[1fFiK6?1L1Z/N+֊Vse{R~M6?%F)]<'i_8Zb6CI'9A KT*:D5FEX)RT+OS+8C9F=H!LW/HY+JT,UW1RV,,83BTf6YdBNIFE>>H<8G90F6-0#@2(A1&8)!:-$A1)0$?0(4'9+"H3&H5(N;/[I?%=.(Z8KʀK|CىKގQӈSuHY5viLEB=:>KGKFCFFCHKHMJHMHELIELIGLHFLHIOKKQLJSNQK-29.KKI4528:5>?;;D+Yf8@I =F"cjC4>( -IR(1?)75C0<2;.=->/3&44.63,64,55,76/55.22*::12>"#0Ũ¡ʢ{paX0sMc|[jIQ;FR%DI## 6(j;ӂMގ\ՆYhEG)(K,a?(jY:CF#8@S[06A9INV)RN%GP(;F#>I%FK'KV/1?1939MS+R\2Pb2Ug6NT=B>=KDAJ>9K<4@1&6)D5+9+"4( ?1(B3+.!F6,8(>0%L7+M8+M8+nZK7-'#U<˂Oݓaacbb܎X}L.ui[QL?;AJGJEBDIFLGFJIFIMJOHGJGEIFFJIJNJIPLJSGHK!&IMD:9:,.*>?=\eNYg:IL%4?/, * (9=I>J%@Q/9L':M%-A+;)8-6!33+65+76.54,87087065.86-26!$-~˪pbsY:yYwVdZfT/?S$L[-OV+X`3j9tBՅSڋ[ʁWmA*(
+3=!_9$nN;\L529#2-5JF"HE8?2;/5+1@L()6CO&GS)DO'AH%4?2<!CA<A<;KB@K>8K<2=.#?1%E5):-&3%@1)D3-1#L:2:*?/%M:/Q=1M6,zdV\QH# #pO:bcdgggc[8zmf[S@<AHFKFDFIGJ@?DIHLKJMGDHFCGECGHGJKIOKJREEG)$*1$:::.2.220/2'( 1;/ +
+4$9+=/?CQ,O]>=M+1@.>1 %87D&43+54.66076.65.97176/96197-)-ΩݾַqYK-@?!OO,h`7aeY0H[/KV0NT-JR%gT(wEۉU݋Vٌ^mKpD'?$":!Z3 uJ7\E348 #'TL*VR-4<9C%!&  $ :I!3@GT);D?H%UX@JEC<;6I@<N@8K;1;-%C5)B3(:*"5$B2'B3)1#M<3=,"E3(Q<.V@4R</|gVlaT+''XE9זelfgkil[:upi`@:;GCFJFJB@CGDJMIMEDGCAEEBGFBIFCIGDKLHO@?B&3& 6;6-.,ECB``Y%2"/2$8*<*:$2 '4(% /
+#6 #5 '<%5,.&97165.65-87097098/541::329"^}Z¢{z;4 $ BP-L\1yPd_7Nb58F&=J%IZ*^V,yDهP]ލ]}SZ6]9T:#.) E#b9#eH4>2^O-E= *+8=!"-'1=J*6C ?I#PT->B9@ OL@KEC><9H>8O@9K;2<.&J:/@/%;+"6(G7*E7+2%I:/9) J5([B2[C4ZC6wbP~i& H;9[omnqqvY9vvmg<67KFGFADB@EKGLGDFCBFA?C@>CCAFDAFFCIFCE;:=BG<1=&*1$CA=IGA`_YKMC,9!)
+1!5,>)= 2 " //D';'8 .>!"%87365/772:9198.76-75177.AH/5 $P>#SA)-M;+RK/DN(wkEZ[4/@BQ)bm@IT*[[/NׄNfbρRc?W9`DcL9B0#D,T-`2`>'oSqT]N3+," (5Q`:GX0(;+MN.=@!67%OKIC??D>9K>8Q@9G7,=1&M<3F4,?/%5(I7-D5*1&I:/=-"G3&hN@`F8gOAx`N3.(800tWpptqu|V<tqgb@;;GEE@>@JHMLIM><>DDH>=@=:>B?CB@CDCG?>A448=;;ED?=C7$'mndRRHFFBWWUSTM3A("( "6 96,@#6 2 !5 /9IMW-GP.=@(64-551762:8086097098064+>>-u|afR<[G2kWDzflodkdCWg>fpEpGcG,^J*V؆O]iՇZnI{H*xW?uW?tY`Md8$`/W,d?*rM5lNs\DNQ-]k;-
+.
+!/ &7;CE%JG<GEE@<<C=;K?8P@6F70=2+K;3E4+A0$7(I80=.$/$P=4:*D0&oTFlQ@jYkXKE;0**`LtttzxvW>vjqhcB;<?=@GDFMJM@=CC@EHEJ=;=<9<@=@?=AA?B999124876?=7@@=BC?ji`rpiDC?EC>GGAIIB+2#1"9%=*?/F$:');I=JBR%Vb355$44-55/98187076/98/98/<:.x[;bx_CV@,vdR~h}gsgG`nBrvLnMZ3C ~P`TebuLT4eD-sUoTg<']1W9b?U+`6"xO2hItVgc?9@IC&N>(CA#36FC2UQMD@A:67A86H<3QB5A4->2/J:1G7,C3(5'J8.:-&/&!L:2:+$?+ {`MgSzpeY(%#dJ>ޚkxwzwyV<qtkc513EBFNJPDAC@?AHFIGDH<:=858=:<A>A>;>547*+.87:CB=;94==8MMJGEAKKEA?7A@9BA=JJB2;+'
+'<#7!7.A"6. !44C<L%AT)Vb/;;'32-55-86198276/982:8199/D.VA(E+?#8 6#/(NH(SJ(PI+@CdyU6L.9d<qׁN[`}VZ9c<&|R8r?&pC-uP9{O2jCkHK'qG1|T8W:rPgbG4E(M:$VG0JA8LHHGBC746>97H<5TA6<1)?4/J<0L9/?1%7)#L<16+&.&#K<3:.'9&ybK|dң~/)$D94È`~}ƁLjY;j_W626NJQGEI<9?JFLFCGB@D;9?326:7:>:;656335&')549IIHDC?::8BEF;;9<:3EB:FC?CC;EC>DD><B2$5."8"6)5-;=O(7K$$<2E *5(*55/44.873:82980:94985<94gHrQ:kE1g>)`?+[E3]T:ZN3`R6bhGjJW4/ E5&qLfbZنYUnHe6!C%X9g?*g7"M0E#R0xM4c<'yP:lD*Z3_BgUAcN:5 C*I@<IFH=;<100=84N@7N=16+'A73J<2H7/;.%9*"M<33)#3*'M?7:/(4(#aJ8Ʒük_SI4,,uUƆzĂƂvSbYO@=ALIN><=FCHHDKDADCAG:;@438969;9:443//1$%*025DCAIGE:<>159764A<6B?7@?6@>7DB??=6GE<@E4*;1 #
++)6LW6KY60A.:%
+ 34/56276/982;:3;;5;;5>;4ٴe^Bl@(hH4mR<eJpRZ@qK2Y<P0@&V@(xrOݑ[s`\ӄVtLW:+ N/f9 K1Y=oOfG_7T1f?)^;&ySuQiW>ucO`O=WREYUTRMO1/1301?95OA8E8.0*$>51K=5F7,;/(=1+G92.'$4-*NB:@51)##?+!˶񤕇q.$#vYIȆƀlЯ`WQGCFB>@C@BLIKHDKFCGDBD>>B;:=745436213--/#%)./3;98;71210466;94@<3@@6A@4A=6C?:KH@CA8GE?EH;+:!'79I=J#=C$! 9C(8;.772:90871<:3?>7??7>;4^cgHsF,gB)yWlQa>'uT9qH1{V9fE)kG{xYtN4āPkh_ی_xQjGQ.
+i?%Q4i< cFzU<B'Q.j<&d@+aDsRY=&U?*mrmd^XYE>>.,-732F=:PC:B6/-(":3.E:4E71?3/=1-D944/.71.J>8I>8&$",L:.[MDK5/΋ʃ~ϸȶ_UPB<@@<=IHILILIEJGDGA?B=<?@@C6460.2--0)(+#%)-.344411+664AD@FE?:7-@=6C@7C@5DA9LKCC@9FC=DA:EE<:C)'3(22=/9!(
+ BL-<A-981::2;:3>=6@?9A@9A?7xI'f{Uo?#gD+crWqYAqQmG.sJ2~\;Z]iKnM4l@^ihbԆ[|T^E<,(G,b7 xM/gD&: D.lL5|J3l>+nA-[?pV=n\KcWSPHIJDD95420-;77F=<MA:>5/,(#/*'A81A62B63;33<43;43;64B96LC@966"D5+zμ<) _ԒǁvӚqͽXLG>9?KFGNJKIFIDACB?B@=A98=@@D=<@./1--0&')!#&*+2044  <>8IHE:81<91@>5@=4@>5=;3DA:EC:EC:EB;GF=IK:19'/KU0#
+
+ "$A@7>=5>=6@>6B@:C@9BA9Y5uM`;_:jdL1waG{aEuZiPbC-oO3cbL4pW<aA%S.bcimvrUXA8958%3M.1G,uZAuR8yP7oG2pG1{O5cL=UOOSMQOIKA=>30/520?::?:9E=9=62/,'+'$:40<40B:7>88<99974?:9D<=C;;IDD&oug]<-+µfċĆīhM9ĴQFBC?DPJLNIMDADCADC@E>>@33732676:,-/$'*$&)#$&'*07:9  &+ ;:3B@8DA:?<4JHBDA8@>6A>6IF?FC:EA;DA:LMA25%& )
+( $ #
+.6??6>>7@>6@@8DB:DA9EC<lGU0}F&¶e[=uM2qO1yZ=vZnM6gFzYZF5lXB}aCuL,^d{ԓltQB;4446955;334 - P4#rP4pO6b>)\2{E+tA(oG5_QNPKMKGFFAA;573/.:65>:7?;7=85<7152,*'$3/.953;74A=:@;<?;;@;=F@AC=<ICB;2/y֯=30G:4xjɽѰc<xּDzȼND@HCIOIOLHJA>@GEGB?B?>A227.-1.-2((,!"&(*+ $&&(-88:&-#
+ '
+*816&>=6D@;B>8A?5CA9EA9FB;DA8B>7B?8D@;JGB<A3"0$7 /A- 6<A@4BA:EA9ED<FD<HE=IE>]7lCU8jFf{Sp<Z>gdmO8oO2dFmTpV>sV;kJ.ΐameNC42:79B@DC?A<;?69:A2%nN7fC,yT;cD+tWnO|E*pJ;]POUPRMFHF??:75511733?;9@;;@;9>97:6263/.+)0-,954943A;9FA@E??E@@IDCIDEGB??51TG?IBCIBA>1)vYoca?Ʒ¶OC?KDJNHNJDIGCFLHJ@<?B?C98<225+-/""%"#'*+,!%'(.76<,3&-  $3BW#4H!.25,A@9DB:A?7?<7B?7C@7EB;DB:EB;D@;FB9KM?<H(=L 6E.5<<+HG>IG=JG>KH@LHCOJBzA"u<u@!^.d8\8sC#fFfKiNkQ\G2~dHrST>*L:#T>%gM<ZG<814DBCIGGEBC>==;9<9:@?87hK3yS7\AvW<owWB8MCBGBEHDCC??A=<854301856?;9C>=A=;>:9;747411..1-*;52943;62G?@IDHFABKECKGFOIJ=32ח9.,RMME@BkRAvzqU®Ƶ䳠K@>LHLHEGHEIIEJGEI=<?A>C=<A76:$(("$&).)-. "&(-76<48.#2$5*;4F-@*,&11.CA=CA:B?8CA8DA9EB8EA9EB:C?8@=6ONHLQAIQ-;J-2OKBNI@PKDQMDOKCPKCxD&w@$qA%vU<sSlC$dEqO`:mMV6qZEv^FcB'oTkYBXB+;0(?>?GDDDBCA??<;;>=??>B=<D::AG?<eJ9kF-hQ8s_`XTWSTNIJJEFE@B>:9987757:68=::@<:D><C=;=97:746422/-/,*841;66;75>85HBCKEHKGGLGFQJMC88ͿRE=GA@MGKLB=Śsqʴߦ}D<7JGHKHHIFHJHKA@B<:?<;>?=F239!#%%(-(,. !(*,68;384' (7$91/ (
+" #*+::4HF?FD<C?9C@7HD;B@6C?6C?7A=8OOLLMCNS?IM>RNEPKAUOFXRIVOEUNF{I,uG,aDq̲c|]W1R(c=!U/eA-C/9#}_v[qQ5WD3A;:B?=;:8A=>FBDEBC>>@<;?A?E:;@;78H5&OD:UNLIDCPMOMHIA=<:86864644845>:8A<:C>=C>;?:6@;9>9986420.-,+31/963<76=84?:8HBCMGHNHJQLOF=;˸<11SMPGCCmYɒeŴv^ўt<41KIKLGJJEHEBG888211214<:>%(, &)$'+'*+!)*,87;699,%8';"75$9% # *9"  '&"?=8GE>FC;@>1A?6A>5C?5C@9HGBBA<PMHWTKe`XTND[UK\VM^WK^UKsU>mTbævd<\6gC~R8vA&e6_9"fNbI6)#?*`D+R;$C:1??=C@ADBBGCDC@@CA@CA@=;@FEJ%%(:77$!!GDF;88=:<B>@968220521635:66@;9A<;@<<?<9<96?:9?:<976541.+)30,751<54@:9@;;B:;KCEMGIRMPE<<̴bRJ=54LHKD-&зmVBĵu;33NJLJGJEADB?D78;//.+*+.01 !%($()()*&')55:;<>"0"6+?4 8 1G&<%8"2"   -/&FF;BA8A>3B?6C@7@?6=<5``[\[UHD;TPJa[Se\Se_Tc[NcYPn\E~t]]|VL+K'hcB_;dpVP>+-& T>*W<#dI+R@/;98C@>FCCDABB@CCAC444IHM''+**.99>@?CCAC:8:30.-,*755?>A=;@>:<B>>D?=A<;@<<=96<86>:8=98976644/,*0-*520942>96B<;A<9B><ICDQMNG>>vȰﶩoaqeYYMF?.}媝s;47PKNECEB?BC@C==A225*),$%'$&(,$'*'(+368::?+7"!6
+%;0E%?/G5J.
+! 3) & ,.%JIAFD;A>8>>6B@9HGBLMIYWPfbZa[Pi`WndZk`Sg]Q[vkNsMiFV7sIgC%];ӡurNpR}fL' 2"bGkKvU5@*>83A><968A>?DAB('*?>@87:%9:>879JIKKII@=?:89<:8-*(,*(<:=EBDB@CEBDFCCC?AB>=B;<?9;<99;:7654,+(-*&72.;30;54?;8B>;EB@HCBLHGG>=yqǻôC/(xkʺ;UH>6("ðyfXx=66MHJEBEFDGCADFEH??A112 %&,%&&$&+4684486=-&:$;/C.E/E,=,)4( + 5"8 , )440QQNJIC>;5;72>:6nle}vh^Tsj]tk]wk^shYʡuqK^>_>[6P*O% W/e5X5iA#c?(pP7qXAbF/nH1xP3fD'W='M=3B??JHIEBC 424C?A!<;?98:633GDC956?==99;212321%#" /,*;:<A?BDBEGEGHDEICDD>><87543,,,$&$#$ 3.,71,830=86C=:HBBGBCICEA;9~oc̺ȶgZS:00I=6NA8?3.C=>bRJN:-zoc:43GBDEBGECF@=??=AAAD''( "#$'%',035468041*. 6L&;(=$: )@/F 5 % "72E0- .D%:
+!#HIBMKGB@>IGEIE@]ZUqi_vl_rj]pgYe]O]b;x^>[@H}H*V7t@(o6l5cE@"hF,~^CA&xR7^=rH)[>~ZA2' =;9+*+IGI&%(/13A>A;88?==HED944"!",,+878,+.)*+%'(,(%942?<:C@?A<=8342//)*+%%%2.+4/,62/;74@96D=:C=?EAB?78sdY̵̼о՜<44PMNIDGLIIF>=|pƲ6$ǻeYO611A==DAC@>?<:<"# ! %(-125679217*4""4 1C5G:O4J1I4L1/ -C+<3 4 %/C!3-3$EHF^]Y_YNhd]ZVNcZO[SIE?4B<4nIkD%xSjcAϠoΡu\9WTeBrP`B(E({Q2e=T0nHY1ZE2&%!/.0NJK0//**-87896685497:ECC754544++*869*+.%') "%!! #$" #"*'$40.2/,50-931952;77=;;833h[R˸;s׼²C81GBAJDFIEDC83p2$ijPG@314A<<D@B:89545"02   !((,..2;<>@>FCH=7K/>BK!BO#-@&=>U")>(>6L'?8
+&;& )=*@( *"6!-<=.TPGdaXZVMKH=LG<TQFUPHb0yN'bdab9nAnE˛kV5d@oGA'3!~W9b@g@]={S0S-y\CA;6FBAA>?!4561/0;99/-,301<:;75:.,-))'0/.869338+-1#$&  /+'/-(30.63040-1.,3111-+RG@ͽydŲϺѹwi_70/HDDD@?RB<I;*TH@Ŵ6.(978A=>=::200%%'&63L*=  "#'++.9:=>?E>?C;J$.<%  "% !6!5 )?2J/I#;. "
+!6%9
+/ !6"7$67=3,D<0DA8/+$86-=;0=<4ŋPT(e_8tMS-X4kKZ1? lIX/#
+`B,{O2wQXvM-yN)~U4L5".&.,'210 !#646;97968('+113)'*87<*+/))+!!!&'&.,,312547103((* $     )'!2/*63/:732.+0.-2/-,)'I>5x|ʸ:0*GED:3/sh軱%}rd-&#A??1/0644,+()63I*> %&)*-/67;<<E=>G?F-(3$4"1 . (
+-
+*E-F1 %- +
+$9 /@1C)='7+@3E?D55GD:EB<A?;HFBMLFW'QR~Y7g;MlAwO5'
+C*ʙp`BgN:}`Ig_vVeEŜpS9&
+6 7 -DAQ9I!3  /5H5I,:edXwrpgspivrL&b6[7n<Y-ʟktKQ,H.j>'T0~X{S:aGl|Z|YA]ř_E2\G54'+'%...544HEE&''++,@?>457&(-'(,&&&'&$+**#"#        "630;665111/-8622/.20./& |dMιT;+ɿXH>κ碙1+&# qeX...200323349#!     !###$&124BCI56;5796=12;'7 2H2G 8, !   ) &-4IBS 4J-B.
+'1(<)EF4ebX`^R{yoVQGdAV<c8xGGS+qJ-5 yM0wOXoI{ZgFsQlM}ZtĞvpO8sY?vV>2'))(A>;A==766:88)),+)*/14')+&''##!$$% !  #  30-:5552/31/:8410-321's`Ir2#Ű'=<=3*&YQD.,-42221279; $) &(#+6%: ""# "%"&)47;+.2*,368>+/#2A'5, *  ' $3-.<C$6GAQBW%+?)  
+& //6$CC?;;6GB:HFBfBRΧcvAI!J&G"M0$p>%_9uHmHapJgBiI*\b];]\D0 vT;9'973743$$$<;:0...-.011-,0'(,$%(!"#+)# .)01  ' /% -'!96451.952;652/,431&!~xdk\I-J;,ĸҽoͺA3&1/0211G<5ƹ=3*""$*()002211:;<(*/%),+-B-A*A' $!&"% $!(#&,<=C8=: &-'
+  $:%;OE*sR?y[EQH&:M9P 2   ), )3"9<<8;:KKG441UبiGUmBb@; R3"xB*lGg@`;Ϊy`zO0uQ5b@b<^@"qOaE|bFpQYH7+$&$$((($$!&%%*+)&%(%'(%&)'%&WQD7-! % ' 44=9&-9!# 9);.#:5184/<849640-+420)$"si"
+Ŵ| 5)!s_I{kU9,%502<9;+(*_RJµ,%!$%()((.--0-.<;>-.3),-(3) %1 6E! $ % %$ ")24:>?EABD' () 
+.2ETA&d;)`9%fJ49@'5+2' 
+ ..3;*>?@/446;;/.*~NvJpJo@iCS5[8'[@.aFͣ~pKg;ҥokĥ]mLuNhG'`F\B2
+ .3+1";=;.0/47411-kD~YdEa=_@lB'r@*^3nI-a⻄yْћţ}Ũq_G1SA-iL{YiBZ5szO/mE(kL3[;"oR8gO8(TA,8' +' 3,9%, J8%;#72D(< N+5" 3 < E&F(?4+<96B=;:640.+744967A5+µNB:0../+*/$A4))% 43652696:6448786+'^SF-+-<:=/-. ./1>>B43915/:J$@S$"36<248 "!#(-.1547?>CCCIHJK,/&";C![a?" Q:%zM7{Q;hG2]?'nM+?7*/*02XS;9;*888022476240e>™rnOg8]=wU6i;'oE)iBXƇЂڎܤѯyz[eEbHoR~]eH|[8sK~^=rL-zX:fIa?mHlP4T@+z^iR;- " . 0 -K9(aJ3v[iW<F2Y?-N+O)R.( * D%K&N,B"=1(=:7@=;7421/-754;982($f[Q*'*:88>:=846:676321/-32197:8563//UIA4,$/.298<?<?(&*''(;:=66?9;7]f8cq7>H% !&!!"%"%+,076:78<==BMKPFHE/0 %C9OE$:7cE1rI4tI/vJ3bD*U?D<),30\V:OH*+) #'<><11056544/B"l?d@%X.cB%W>'I+kFkEd=ݵ}ΐɊ_tLqM*hb]BqUoQ`C+zY9vRgEeZ6mL/~dDuPlJ,zY9xeK{gMU9#]=&H'nI.aA`=&bF/eK7s`GdK3S,Z/`5P,. 3 F&O+D$&.%C><>:94221//976=<:+$|n*##;99<8:>:9=99;8841120.633<9;,&&xm& 0/3435>=@=;> !##)(+<<B336PO/@NXm8/7  !"%(.0422778<>=C@?EKJQIE=F6sR3uW4lR2b@*sM2jA'nA*dA)MC%HE*::<2UKp_TI)@?489921.444655Y.c:fA&iHjIT?-_K6fK3`C*ȜlUXhxP~U0}T0zPÜubEfM4uY<qWBmS;wS3Yd@rK`=eJ/pRkC*^5W;]@eH_>sG-m?'h7l='T17 S9#cB+Z0\1^1W.5 6 I&S-F$+5$C;9@;86212/1=;9>:9-)$sf.%:98:7:=:9>;9<::;8953020-8674*'ocW)&(1/2.-/97:C@D45< !$87:76=BA0+5 !4 5F/=7A[d/32
+ #)+.-.021623976<?>FDCKIIPcN?fB$z`5gY,M3a<$j=%pC+uK4fT8HJ)>=aPiZob"bY<NI<9:822.22.311R@,V<(qM1xVfGkI3iP>gSBU>-kM+TsGZotC!s4O)àtoQ}_FvWiy`E\kDI%yTwN]<oP6C+V7#T4 R4kJ0b>%R(e:%[2W.M*@ S0K&^6"a5[+V,8 =I%M)U/CD&C:7@<9841622@;8?;720,QE:Ź=4+533:78=;;<:<><;>;;<9:534+))PA;ͼ?4.769522,+-201<8=DBE<<?((*102;:A47.=>+64IWl5N_$]h(ur/>: #$(&&)#%&)+.117559:9>A@EIHPQMPeL6cI$iW'rY,Q5f<%rD+rE,qO0NK"9>?AABFH$VR3JF6:<922.43-21,iOt[E^;"f:l@'m@&rM8yW?mP:^F.qFzNrH[tKȔe͟lh]=mI1mKhGgI3tN_\6oK}T]P9$$ 7&7'bE-~O4[7 ~aCmC*e;&^4N)P)T-R(j:"b3V*O)8M1!K,N)Z4@ 8B72?<8952954@;:=84:754*$µnbX,));:7<9:>;;>:;?:;=9<><='""sg*!!<<?878424/,-0/2:9;AAD;9=-+0:9@453WK(^S+<KOc-IZ"N^(_c$ns36:!!$&(*,--,/1/499<?>EDDJHGN^TQ[K3cF)uU4kJ2pF-tD+tC*vL/U@%I=*OK0NP1HG'QI*HC289821-43,65.zWuSR7O1n< cBwhyYcDnElAT/^oDǗe˟kvReFtT|WuO\gDwQ{Vc@agI>. [I9eR@eQ=_?Q-a?pPmB)k=%m@'Y1h='a7#[/c0X(W-C!VC0TP@W>+T-M*5
+F$G7/@<9:54<87@=<<84=:8.'#q)!=:9?:<?;;?:;>:;?=>><=5,)ƻeXJ :89:9::99323,,,//2:9;>>@<;@=<D:7;rV>kW3;L>R\j0^l4LY$io7ru=24 #!#%$&'---43686:=;>B@CIGMIHPVKIgE4wN:}S;|N3wG*q?#oE*aJ4j_Bac<NR/RS1XQ/C?199632,43.44/bn_C|E*tM4tֶfeuS6|\=_;xPܵ^c3j=jibaWfxUhFrN]5\W8&>,!aL<dP?r^J`B+U-W1k: e6b7 ^4P'oF/lL4R(c0a/X(P'rXCRI9Q:+R,A@V,L6,@<8;65>:9@;:=86=88520L@8ĵK<4523<9:?9=?:=?;>@>?5/1pcXȻ/$&&'*)*433998;8:3250./634759<;@@?E86>nXFSN%BX$Vj0Yg,Zj0gx9V`(im5os8+, !#$$&*,,/446::;@?BECGLIQRPWYGApF/vF,wG+uD%uA&sF,pS6qb>]_6S]4`iERY4<>-;;742+75.75-ͨ}mG]:sOuM3bsR|_gI~_D|]BgE-P1͟pٰ}\ҥuYɤx_tRiid^BpN}RyPZ:$pN:aMwYFqS:{T5zKP-a0`2n>"b5c8 U/S/c8!Y+_+i7g7"n=)];)@)P*Q+Q+W/J1#B<9>97@<9>;:>;9<78>:<,$!(??A>:=>;<@;<C@A4'%õyn`.)*;9:)(')((20087::8;75841153543966;<:DRQBgp;JZ$Vg/P\'Ve0Wg0Ta*jr:tx9rs8.. !%'(,112557=:ADAHDDLLFFL5-b8"wE(wD(v@"s>"|N6bE+YK)=>PX2OZ1ir>HJ365263,95.84-b]wQuRgA+yXxky[y]kmsM2O-U/p@ UسXʚkxUT0Ya@eJ[9]`@[?)Y5zJ/aB{T[~H#P1J! W+g5s@&m?&Y/d6 ^;#T.s; ~I,oA)k@)P.,Y6"b;$U3 E#E*B:7?:8B>9@=:?;9<87=97<85B5.ȹfXR*#%DCE@=?CBD/()qjƼ4,(:9==:<=;<422.,+31277697986965722676://5BC?jrB_g.^f2MU#IT"Zj1]n2dq6ox9ec&mh33/#$&$'(**-22499@:7=UB?nWcG^1vE+uB(xC&wB%pA)Q; ;?!/78>V_1qy=CD.65287/:60:5/f[lKY=uP6tj~bdgvZbG}[B{U9\eiKrP~Yө|Ξv]iAcdAa@rMjLS;+rQ:Q8S$[)uA!i9]/T*rO0`5wC)nA)\0i9"~]@Z0m7o>$Y/J$[7$dT>RA,P21
+; X;,C96@<8D?<A<;>99@:9?:8?;80+*bUHi\U2'%:350&$pbZSG9521><==:<?<>@>A<:;412633757;8=88<87933688;/.2^^>x|=OU"DKXb+jw8`p/fu3kn/i^&n`+e`5''!$'('*-4+*rL;ĄfԍhȅbN2e4zF(zE(zD'oF,PH+5=$/39@ fmB_e6;<.76264.:7/;7-brMlLsL5gKygiStWvVu]gRuP8pRmGfFW@$ 6!M2}T5[|SΙbyH&s@"Y1|TeK; oB+^0f5k8g3m4R&mS1oW:c6 c8 `CnG,c1h6\,M$ l=%uA+nQ5~b{nXG6(A,E,E:5A<:B>:@;9?:9B::?97>98@<>0)'^QBƶrh`Ǹ_RF.)*=<;=;>=:>@;>A=??<??;?=8;969=:=>=?=;?;:>87888<B?5SM&dc6^c.gp4}Gu?xAz~Bb])ka0aU)XI- ;'!P4uOт]׌hЉe|YyE(t@!yB#xC%a@"D<*%:6>?KQ,W^5?@2762851;70:7-`rM`BkE3fh|aoZx\qWtZt\dMuYfNaKF&:#D+"B%F&9 sF(i@R5t9DN'T5A)]6f7g7"j<'p<%s;Z)a7{V9h?%S.kI-kG+T# p9k7!c0o<zC&x@ e7qaFeR8$=%E)I:3D>;B=9@;9A<;B<:B<<@;<>8:A==3-*B3,{yC6./*+?=@<9<;:?>;??=?@==A=@?<@A>BB>@<:=?;@@?EC@F><A769=;=^T6d`+rz>u=tAox:ps8jo3fn6zB`P$^E&O<'.&10V3Q+c<sOڌdِiЋfnLr>t@ sA&cD(j\<PE&FC!9?8=<?CC8750;92;71:6.WzS`CqVnbJvYžvpxauVDnK<|R?fSS;.7#N4&R6&nD-W2! 
+Q7&U8#u>V0>F'J0!K)f5s>%l=#h5 j5o9m<#lG+W4Y>$xZ@yG,V6I,m<%V-]+r;G'v@&R.jJ/qN7N- G)J=5E?<E>;C><D>>B>;@<=B==@::=8;?<>636.($2)$.&%959@<>?::><@>;?A>AA>@A?>B>AA>AA>AC?DA?C<:;;:>?=AECIDCJ407skE;VF>|6gr3qw8pm7`^._^-q`3[G%[H)gX4hn;VR(Y,P,iAyR֊cΆḃc_<g3m=#nJ1pNEA$:6IH'@:3-FE><83=93:7/<7/ʟsXolidyUr]d}ilM?c<-lE4/'S9,bE0uK2Y2 ,8'' X<(H.H(V/D#g>+gF5j:#xA'~H*K/q<$xA%h6wJ0]2W3mA%yD'cAxC*N(dB-k;&{B(L0uB)e2wD1j?*G'4K@9F?<F?<E@=F?@B=<C=;A<:@;:>9:<98<97><=C@AA>?@<=?:;?;<A>A@<?A>?A>@@=@A>@B@@C@C><?>;AA>@?=A;8<;8<A?EB?EFB9sj<dP!x+>xq4y{:vw@nh1gX.j_4`[2_J)cR-\b3]d4[Hd4R/e@~Vԇaшb͇cS5]0k@&uP7-$31ME!v*}u4B@8?<7>;2@<3E>7¡yϭ̫uwx`b=yQmaEoUn}aNJ, ,4!M2%X:'gB.[7&F,[<'\@-xQ9k9"p;j@H'w@&e=';"C%^4h:"e5p= g3j6Z.gD,T.Z3sE)P%Q*o@(wC)|G)|J0rB)zG2uE0K%M)S7$K@9E?<H@?F??EAAD?=D>=B>=@=:@;9?;:<87=89@<>@=??<=?;==9;?;>A>>@=?@>AA>@A>AA?@=;?<:>=;??<@>;?@=A@=A?;>@>B>:BkfA<}{5yy84AKr{<cc0LGZT+VATG$[\/ae2ol8WBf3P.mD~UՇ`ӈeЈdI)R'rE0aD.]V0&˯}<:4A>7?8/@:2B<3X5gC$qsph{bG[<kC%rQ4n[qdVD<J5&Z@*N4%aB2qM9]BU5<"cD0h=(a3q?'U4O0i9!@%$  +R9#H1P/h4xA(f7 S*S)N" Y*O3X@)]6[-U) \.V*N'H#`9%kC.L,I:3F>=HA?HB@GB?GB?D?>C=?B==A<:@;;=::<99=99@;>=;??<>>:9>;=@>>?<??<@?=@<;><9;;7<>;@=:@>9>A=@><AA>CEAEFCHDAHMK>=pn1sv8u;_h+{Gkw<QT%`^.ib-]M!TE"sl7`_*VT!fh6dM*f3W2pGсYԈbڎgۓnZ=h=&pH2o\-g_!761;80=82>:4?;1|Z<wL1]>qo|brS=jG/qQ6oP0ªxlrZ@XA4pPAZ8%_;)rH3g:#yMdC\7%]:&i='s?'S7R4t?$:D5&K8&0L=)kd;qvFjf=l?#u?#d4b3d1m5}S6v`EdF-_9$^0T,U8!>&F3eJ/rF,a4]6!SB:GA?KCAJCAJB@IBAE>>B==A<;?::?;:?;8>;;>9:@<=@=??<>?=>A>A>;=?===<=<;<<;=<:>=:==9=?<@><@?<>B?AB?CDBEHEIGEK:8=f\Drl6jo6u}<RX"lq8Nxs(YS`\,s^0eK%o-ii,[Xrq2jd8Y>!i8\8vOՇ^׊dnʆcsH/rF-g86p!VO+874:71<92?;3?:1iJ}P5x]lPzeKjTV@gMdH|\>{]:^fK!@$h@-W3#\2`3d7 n;o;h9 R*O)]/i6{B&[0(Q?0C,H/%VE-kb5\]1WV/dM,j8i8j9!l7w>${N1^Bj9 `0l6g8y]DU9%I4$F2"e:$O5^8%NA:NFELCCJD@KD@JCBF?@C>?@;<@;<?<;><;B=>@<<@<<D?>@=<?=?A>??;=?==>;<<:<?9=><>><?=:>>:>A>@@=@D@EDAGEBFLHM@>B99?HEDbc:u|<yu4@A_b0WV&|q OR#dR)aI"|9jh/ii*]UkY0qG[C#E$nHҁYԆa҅aȂ_~K0]1vK5}W)(ND&75486/97.:6-A<2fG*~\?`FB C$\?'nX`DT8nD,W6 J.8$,B&\7%\4#`4e4i;#h<&a4_1V-R(Q'W*N$=>-$K8+I/$^>5[O-xr>QK'PP+\R0lA&t?%i7k8j5q5u8f0^*j0o8h9!R-4 B)uG.>#ULHQHFLEDLDBLEDKDDIBCE?@C>>B><C?>B=AC>?A==?<>D@?A>>A?>@>>@=@=;>=;==;=<8;<9:>;>?<>B<@@<@B@CDAHEBFHEGHFI65;<<A@>DPO<uy;ws9IFOJ"ZK#i].mo,cZ+eS+qf3od4pa4]V'c[*ic0BC\9U2wOс[͂[˄^{Wd0\,mJyn%>;(<:486/:71:7/@:1iX4gL)jP2cB-\EvR;X8"X6iA']8"<&/!`M@Q=1@'W6$h?)c4e1h3e6e7a4Z,Y)d/j4[.T/<$B,#_?5fD8XM.rp<ZV.KN*\S2g;!o9n<"Y/a:y@%h/`,k5y?$m8j8P+9!(oF/T;1OHGSKINGDMFCNFEKDDICCIDEF@BG?AD??C>AD>AC>?@=<C>>C>@A>??==?<>>:><9<:9<<9=<9<=:=B<>A<@A?BCADEBEGEIHFJ88;66:>=B>=BGF>xvBrv=_f2^U+cV*kk,jr-lt2mk3um/b^&pm:t`4l]+zw:{q3g`0iH*F#a<wPvO~WІ_yUb5s,|u/43)=:595/<8/<8.=8,gN)kJ#jV0qZ8jU7s[<nS9F/ [E6ZD1J6&E1"eJ:pTDN9,?&^7#d5 f3n7n9 m=&_1p>"sD*h7 h1e/e4T2"R7,eB6iE7YK.mi;FK =C MD'`:xC(k9a: Q>%pD*n7r8u;v>!b0Y.C!-;2'a@+WA8H@>TLJQHGOGDNGENEBKDCKEEJDFG@CGBAFBBE@@E@AD?@A=?C>?@==B?>A<=>;<=:=;8;<9;=:;>;?A=AA=@B>BDBDFCFIFJ=;A54799;<;@BAG><>gaArt@Y_.ed3vu<fm.Zi0hx=hu:do3lo8quAbc3c\-ni1x:ye/t\.sH%C!a:jDYх_ԊdNJbb1RN&330;8495,:8.<9.=:0eQ+\D _D}Z3VD^W-WR*SI.nVCpUC`G7cJ9bE4Y=+?,(M/"_4d2o8o?'i:#yH0T8^7#]8#b;$`0d2Y3S7(dB4gD6YO1kd9YP(LF#EH'ZI,rE,l:"[2F+uF-e4f4l6i5c4H%2#/$.+"B7)G<6D<;OGGQIKPHHOHFMGEJEELFFMFHJCEHBAHCAFB@EABC?BA>CCAB@=>@???<?<9<=:==:><:=<:=><?A?BB?BD@DEBEHEHA=B:7=98;;:?=<CB@F=<CIE8qn=^[-WX+dk5R\*JX'Q^)^n9Zg2mo<ho:gs8nr=ed4gk5ll/f`*gG#F%X1jBxQ~ZʀYч`єmfN5/,*;8585.;:0:5.<7/]R-VR+[L&UM#aZ,iq<QU&<<ZM-`D.^A0rXGcL@G3)L=28."R5$f8#h6l5\'e6V:\5!D sC*zL0iD/V/G%U7*a?2eD8[Q3aT1aK%bP-VR.SC%^?&Q,H)X3 n?&U-N(M&^/[0D"2 A7+3#D:*b[JD>9GA>NEAOHGOIIQJKNIHMFGLEGKDHIDGFBAHCBEBCFBCD@BD@DC>AA=>@>?=:>=9<;9;:8<<;>=;>?==A>@DACIDHEAE><?@<A>=@::<<;><:?A>B@?D;::][;_b3UZ+TS&S[+IW)ES#Uc1bm6bi4[e0_k1ov=[\/UH ]N#e\,wO*V2X2d<kEnI~[ɂ]҈dˌhWB11/+84-:6/95.<8/CDJM"VW+cp;bl4W\'`d4PP&ZT-\K/_D/u[M\H;UA7SB7>1#X6%c3g2k3i0L,O,rB'wG.O.R2Q+F%cC1O3'c@4gG9LA$]O2VG'MBaO.gS2QH(G5a:%pB,\0E#M,- > I'0,  ;0J@2IA?HA>LEBRIIKEDSNMSLKOHHKDFLEIJDFGBDHCCFBCGACHCEDAEE>A@<??=@=;=<:<;:;:9<:8;<9:?<>B=BB>A?;>=8;A>@FAE?=B;:?=<@::=:9>BAD88;Z\CPX-LV*OR$=FCOFR%^i7`g3W].]a/\^-_b2cY1\T,YS)_K%P-Q,Q,W0h@sK}Zͅ^ˁ]ݑioS3*"22+64+:6-=9/@EDHT[*^j5R[(ST"Y]*_e4RT+`\4oY?qWHYB4cK6UA)8%[8%`2i0g,E!Y3S0F'K+V.Y4I,M2U;b:)zO;zM6cC+^?+X<&N=XA#dN/@?O>"Z4 K(W4#;!32-& /!% 9(:/%KDBGA=NHEJCDPJJOHGRJHQIGQJIPIHMGFGCCHCEHCDHADGBCE@BD?@A=@><>><=<:>;:=:9<;9:=;;@>@?;>;8;=9>B<@D>AGBEB?A;:A><B98<97=A?D<;@EJ6?N!?HUT)?E0<BL PW&ag6UZ.RT&a[+_Y.ja7]Z-``3hT-J*G%E"O)b9rK{V}X́XyU|\vT>*':7-:6,>8/BGKS'hr7dj.MV&WU$VQY[*bi>_a9dW2nV9uZ=uV2rErlC\:#]-g1f-sFR1I&H'u@$h5wA#e4xC$I(O2L,D$K1c:$^5d<']=#aH&`X1bV1T=$B(V6'Y:-K-A&8 2.%2N;(MC9G@<IB<MEBGBBUNMNGEMFEOGELGFKGILGGMHHLHJJFHIDEHCDFACB?@C>?@<?><?98=:9=;9;979968:88@=><9=?<>C?AC@CFADEBD;:>>=@77:87=<;?<;@?@9`\3bO*gQ-LH2:BL!QS%jh:TY+PV+Y[-C:RG'VM(TI"oP*P.D"D$M(X2iAtLtQzXeBpLqNI1 1+#94+95-KGGP&P[)T[)JV)XS(mY0SK NM&_T5WF(hQ1aBkL*sg=dY/V7a2Y'_6ܗaE$T/~G(?DK%D k?&I(M*T/H$F(wI/pD-pB*gC*qL.tU2mP-jG-b9#o>'_7"K-8+0:$8(3"O<+SKDD==IA=IC?JDARJGHBBPLKVNMNHJHCC?;<;89?;<C>AEABGBBFCDDADA>@?=><;>97:968644968:7;858;9;:8:C?AC=AD@DC@CC@B?<@<;?76876;98;:9=;88sQ8^@]BlH(PBLHYR%WR'US(WY-HR$A?\J-[F)Q:i?!K,xA!d2~E%R/b:lDpKcFqPc;ԒkͬPB441+<8-eU235JS+`oAUg:SX+ca7ZY/GF"`Q0hP5qT7G,]@$T8L7G3\1_-ȔcƆR~=P(Z3]2V(`,b1yH-H(W3X3I!E#~C%yG-d;&L%a3f4g2j5m7p9[1' "
+6&L7)^C2XC4$ :&[B0H=7F??HA:JC@MEEOGEHDBNIHSKIUMNPJLMIJGCGGACD?@B?>A>?D@DA>B<:;<9<96:647758858:6:425756=:<?;=GADE?CFBEC@CD=@@>@::>55<43998;889435_T8ri4yf/nM'XNMFZNYX+PN"_[.UY-JGRA%Q;![:l>!V)I#8
+M(xA$S2kGhBM,gEuN̕d١hO0,';6-SA 67UT.QM%IW-O^.Vh8etE^X0[N)sgB^J)P9jH+bC&Q?"M>!b;$W%Ɛ\~L<a/^/}F'V*d0g2h7N-R'W-M%k4u="j9!C"P)_,`,c.p:g1e2N*9#<'mZGhTAD,& *:>'I@@E=;H>9H@>OHFOHFJDCPIJRKLOIKOHKNIKOKNPJMQLPQKNPINLFLHDHDBEA>B>=?;9:746535436524<:9?;<C>?F@BGAAFBEB?B@<=D@B98<66:21676:556548LI7`a(},eX#QR#NNULTL"LN!XX*V[+ST(SJ(=2O6o?#S*:9!1 B H*e@g@{@ [7YؒakChN;1/'86/G1AASL$TD!Ub8U`4UR&cn<oe;dX4b_8RM%R?bB%lN.gQ2Q9"_9$R%y>X0\.Q+W&L,p=$k8u>M,W.U(`3}G'4I%O'X.a.g2d/i1n6l8 f9":<'D0$ePAfUDE0%255 E0&F@>D=:C<:HAANGENHENGEPJLQKMNIKMIMLHLNIMMILMIKLGHLGKJEHIFIGCFB?CA?B968312757637746<9<?;=E@BD>?DB@EBEB@C?<=JDG@=C346015458007317D@5_V#YSRS#FM JM OC[P&\[-TX(LO!RU)YR,<7<0S3J+R3R0N0< N&y?X6_0 N$T0wSƒbiM70-'85.I9NDo]4~a:vd9gb8jP,aO*id:mjCZS.pxD_V.Q:kQ2eI-YA'];#c6K|C"^5R%5i5W-Q*P*O%V'X*b7H%G#S+^0g2g/c-m8l8!e1k8[35 @/ O<-N8);)A.$( ="?-%GC?@=9B<8IC@QHFNGEPHGPJMOJIQIKPIMLGKOJMMIKJGJKGIIEHHDHIEIEADB>A@=>86:///756405836=9;@=?D@AEAAC@CGBFC@DA<>F?ADBG235015226003115=>5ke6RM(IM#?GTY0ZS)KDLIQU$IKUR&SL&H=O=cH$Q2X3X1W1R/:Y*^:\=&A K,nMZ<1*":4,]D$_K'hQ)zT.|V0gS/lO-j="hL*aN*M8__3cW1N3R8W5eG,`:!h6b>N*H*R'R" T Q(e/b.V+S&U,[1W-Y.S*`-e1i2c,k<$`0a,`/Z0F-4+>1P8%.B2&'I0"ZB-?1,HCB@;9D>;LDARJFQJHRKJQJKQLLPIIMGJNILLJLJHIMHLMHKJEIKFKKGKEBF@=@><=66:.-/533525846?:<A<;D??D@AD@BFBDC@C?:<B;=HDH549--3105,.1215224[cAcf;IL!RU+\[3KO"TJK<KO!QO#PL IF"K9dE%jG$Q-R-\5X2L(F"@y> X9T-3 6 J(~WL;,7/$eG*zY6mM+xR.|R-lK'Y9V4~W5X;kG&nN,gC%d<jC&U3\7pG1a5!cBR4}G+T+Z&\%q:n:X(HN!L&N)M$R%N# a-f0h/`.\3W,`-b1`5F+0*:5S>*-G4%gO9lP4XC)F;5FAAA<;D;;LDBSJIQJISLIQKKPJKNIIMHKLGNNILLIIKGKMHKKHIKFJKGICBE@?B=:=769//1646435735>9=?<<@<<B??EABEBBCAD=:>A<<HCH87<)+--/3,-0//2317LT8p{EQ^,W[,XO(L9^L"TBGKSP$A@IG&D.`A$]=^<E+H)]6R/M)@ M" zD*zH-I&='C! K*[C/8.T<|V/pM,cB a;wP-mE&jC nK+W<vR,yK(|G&uK'b> J*hC)]<)?L!~E,{H/G#Q! _+~F*V,T*G CF K$K$`.U'f2g0i0b/xL1U.Y,Y-U.B*II#JI%H:#& 9"hO8lS8aL1NC9F@?D>9D;7NECSIHQIFQJIQKKPJJQJHLIIKHMLGLLHJKGIKFJLGJLFHKFIBAF?>A=:<88<-,-546435736:79>;=@;;B>@C@BEABEAB;;>=9:EAD>>@(*-*,1*,/./143;>C3MY*DT%Oa,XW*`D$VHMFGGKA@7E=K5R8N5V>X?"X7_8O,W2O*Cc1gDuE,H0 %N3 N>+I9!C3~Y2a?`D"X:iCvL*yU0zX1sR/[9tI(P+sI)C!a@-iH2W8&Z3R(i8|D(rF0i;%n;!F&M&F!}AA?F"D H'c2Y*e/`)_.wI0P+U-M'R0W8"\V,R_-QK(9'2P?+mSgN7QE<HC?E?;F=;PGCPIDQJITKKQKKOIKPIJMJKMILNILNHMLFJIFKJGJKHHKHKEBH@?A::=769,*-337215412;8:>:>?9:C?>D?@C?CCAB;9=<97C?AB@F().(*-*)/--1448<>8CL$BH]\,uk6\R&WK%JAIHMA>)M4Y<E-L1\B"O5\8_:!N2[;#W1T,K"E'pQcF2B@:73*:3)S>"4*kR,zS1`Ac?d@{T1xC}?wn9{q>}Gk:mH'P-dB.a=(e@,]4 ]/tA)P.G(G'~C D!x@r<p;x?|?Ay>D"].U)l:#c0rA+oA*D#J&Q+[8$Y7_Q(Xe1\X4B*=(jW=foXDLC>ID?F@=E><PGCPHDQIITLLQKKNHLMILMHKNIKLGLNIMNJKJHKLIMMIKJGJGCGA?D;9>759)).215424725:49>:;?;;@<<A<=B?ACAA=:=;99B?@DAH+*/''+))/+*/76:665>=ng.nb-i^.mg8dR,VCLJE<E,F(R2J1R8O97&E+L-H-X7g?*d9[3Q&uTyYA70(:80>7'K= -]C%oK+L4^?Z6gH']Mrt7rw8om5li4}{DqU/kB$b@)^9%e?*h>)Y+q<!E%B#C!L)r<u=y@t? i:e3I%J$N'E$_0G+V5O.q?$;9N,Q1C.f`5XW-SE)A,#C2&nRyTQ=0NEDKCAE>;F?=NFCNFBRLIUMLRJKNIKNIMMIKNJKLHKNILPKMMILLGLLHNKHKFCEA?E98?446*),214313523958<::=::=;;A;>B>?C@C=:A;7:=;:CAD./4&&*)+,+*/55:445=:WX$rn5GE^[0[I VJ"H?L=P:M1O2P:N9>/2$0 >$D*W3rF.h>#g=%^>.S6%T8%J>5=83@1E8Q>rR,jG#V:`@lO'{r<Ewx=to;F.I.gI'k;j? ]A)c@,d>(c:"c3p;C#F#J%~C x?L%I%wB$Q+F ]-q<}B!Q/P+V,R)I!H%E"4M2!R9#[C'S=#PD(M=#@0!cH.UA2MFCKD@H@=G@=NG@MFDRKJSKJOKJOIJOJLMHJMHKMHMOJLNJKLHKLGKMIMJFLECGA@E88=558)(,//1201301756:8:<::<::@;=D>@D>A=;A87;<9;B@C139#'*)+,+,.66;227O?-lU,e]+JKLI"K>HFQM*J?!T@!V7X7H4F4=17)S8aE%H1I-oK3d=$e>'lK8kH4fH7hXLPH<G;!E7a_6iN*tM*pH%vU+yy>xAol8YK#[E!cG*R6vM.\8`<D2]A+]:$`<#oB&s>!K(H"P+z>J$X/yB"S$X+c2_.X,J# O# ]5V*N#U,Q*Y3QA&tk@_K*^D)WA*RL-QFhYGD;3B3$~fKaN>HC?JBAHA<G@;LE@KCARKKOJKNIJPILPKONILMIMLGKMIMKIIJHKKHKOINKGMEDHAAE<;>65:'(,.-0//1203534:78<99<::@<>B?@C>@?<?;8;=:<@?B77:#&*'),)(,557216N>3kR1eX,VO N@H>DDJB0S;oK(J,B-R? >07&gM)P>C-C'F,g@%a:%R2]:#[<+tWG]I7B6B6>:cG'mH'g@yS*uAXN">/G4P;pW1_L(l[1d7pW1N;M6fA(a8"o>%p7J'E"B y<O&N+U'[,j5f0d-h5k:!vA$I'L(J#P+}C"dJ&os?tq>YI&F4N=&[X5SKiU?dUB]L4wcJ_QFF@<GA?F>>GA=GB?HBAPIIOIINIIOIIOILNJLOJKLHKPJNNJMKHKMHKNIMIFKFEIBBF<;?757((+,*-//2.-1323:88;78:89>;>@>?B=B@<A=::>;;A?B99>&'+$&+&&*545125GC8dR2YO&oc4T;o_)TM G56' Q?aC @,<+J3N7N< I>ok7gT3T4&I-^6]6P/T7(Z?0^B5YA2I2N<F2]>eAuM(iE wV0J1A)J=km9cY,e[-ns>yxCl`.J:9+]=V5Y6N,F"H&z=F!H"K)i8[+`-d1uC+d3uH0f8!6X+I%zA i= ]G+rn=oq=bb2SJ"ZB(\H)RJ%M8#cM:I9&\K7UJAF?;C>;C>=E?=F?;HCBNIHPIIMIHNJKOHJRKMOJNLHNNKNNLMIFJKGKNJNGDHGEIB@G;:@659+*0**.//1.-0423:88=99;77=:;B@BEADA>C><>?<==;@=;A+*-&%)&'+225116:50dY+de,ok1fTvf(PDA8-/F;V=H47(C/\B#OBd^6zlHlO;hD1b?+`<$^7 c<)a>)U7&R9,bM<T@&S@@)^>hC$N*G/"1 C.dY1]M&?5_c1OFld4}|EI;A.Y=rD(L0M/g3u>"A"G"wA ~F${G*c9%f;$pC+T6xE-F#<
+I$K$G'k=#P1cN1mj?es4m{<rvAO>E1OB!gF18 B1&KA<C=;@;:D?<F?;@:5GB=NHFOJLOIKOIKNIKPKMQLLOJMOKOMILIFJJHKNJNIEJHEJDCG;;B66;+*0++.0/3*,0204:7;;8<978<::C?AB>C?=A>;>?:<?=?A?D++1 "&$'+10433822.RV,^f*gh)0eUO@G>F@F=:.:)=)Q<fL)UE$YE0oOBqN>lF2e>(a;%Z4"a9%h?(dA.V8'^H5P>!U=O8b?[6V3W@$6(0!:(P9hL4ZM/^l7VJ"U2hS*cJ'A-L0Q2_8#R,@J r:!I'sA!k>$J$I"R+b6L+t@&7R*Q'K$oB)C&9%TA!ae6qBVW&H:L:NF!VL&Y9$0 2$JD@@=:@:9D=<A;8=:4HD>NGFOHIPJIPIIPJNPKMQLNOLNOJMNILKHKJHLNKMIGIFDICBI<<C44:,,0((*.-1,,0//2757;8;<9:<8;@=@B?C><A>;??9<@<>CAE..1"&$)+103438110FN->FWU%ii,$!A4VG#;671@,H2O7`E!VA#[>0jH6d?+e?+f@)^9#_9%b9$qF0d>(c>.oO=O9U:gJ*c>mE"R3E2C2M<(B.I3]J-_W3ft=^Y1W; U:V@7.D)jJ-`B0S.`5^.g6yE(pA&R-H" `.c1V' e5zF*K%J#_6yN:a='F0@/TR"en6ba-\A V?!aa3oJnvCD,  
+ +!FAA=99;86A<9@;8=95IEBMHDNGFNJLOJMOJLOJLRLPOKONIMMJKKGJMHMNJNJGJFCHCBI==B359/.2&&(,,/++-0.0867:79858:79?<>C?B?<@>;B=9??;<@>C./3$%&)103428//1@F'5:NAOI#y'jZ:,J:L<I:G2M4J3bN(XG(`A3qO=rL:iC/^:!`;#c='pF/tH1k?)wO:jH5N7W<hP.wO+wN+J/F51$2#@*O;C6TH'pvDZN+_J1Q<%;0E4eF.jL9W9'^7#d9!b1c2pA(f=%M*\0h4h4`0h8}B"xB%{H/L2tG/W<VFfc2Z\&TES7rP/qQ2aS*[`-\\.O7#0" /&"F@@=89;76?:7=95>:7KFELGFNGGMHJQINOHKPILRLMOJNMHMLIKJHLKGMNJMHEIEBFCBG>=C348-.2""'+*,+*,/.2858;8:757978?<=A?C><C>;?=;>=9;A=A/04 )'+0.1335.-1HI/=<F9F9ZM&I8E6A5P<eI']AX>T@ gS-`I)L0 V9(_A.fA-h=#l@&^7c?+h>'g;$jA+aA,K6Q;83T;b>$H*kN0M>"/%:&M4^C'P@"IC#E1Z9Z>%X@#]E*cH4O4"Y:&X6 b;#c4c1p> p@&tE+c8#\-a0\-xD)H&I(H(I*gA)P8Q=NA\F!R6]@!lR-lD,N/CDcr9KA"60+E@==88<78>98=96>9;JFGKGFOHHPIHQIIQIMPJKQLONILMHLKGKIFLIFKLILJFJEAGDCH=<C529./3!$'*),,+..-043787;533868><>@>A>=C>:@>;<>:;B>A//4 &%*,,0448*+/PH1D?H=L?SF&^J+B;95YH$T>N7U>P8!kO8mN7`A.O/P1 c=(oC*xJ.qG-\6!X2`7"i@-eF2E7C8?.lG(? >%wX4eL-?15$\C*w\>]N*52H>iI(]=hI)jM/Y<!U5Y:S8 W2d4d1yB#|D$M*~K/pB/[0uA)L+T2P4L/S5^?$;#I0M9nS-M2ZAaG#e@'J5MZ&pFIJ#(!90/E@>;76;76=95>:8?;:LFFMFGOHJOIKMHHPHJPKKQLONJMMHLNIMLJLJGJLJNIGKCBFFEH==C208106!#(*),)).+,1338559647868=;@A=A=:??<A=;;;98@=A016%$*.-4237'*.G>/IA$J@ F9CB!`S1C;@AJ>cJ(XAO8hI7zT@rN8kF2_;(X4!`:%nC*mC)b;#h?$g>&g@/uP@^D2C3K9V6j7[4<%A+uV4D/C0RE%fW5bR/=;VG&eF'L5V@"sQ0tN,`1^:`D&_=%d7c2zA#P+P*K)I*S2T-\2V6I+O0[3^B#cE%?' ^J%kS-K2ZE"bM%J7G9gs:hx<=2A/:)@74A=<;65;77<96=96@<:LFELEFNHGNIHMHIOKLOIMOJMNJONJNMILJGLJEJLHMHEICCEFDG@?F006007!%&((()+,+.43755:447758?;:B?>?<@<:>=:<:8:=<@239"#',,1435(+.A;0WF&O>F9<7XJ$VK*A@!D?XB[@P9 fI7lH5c=)g@-d?,iC,jC,c9 b7a8f;"d='Z7%aA/fL;U? X@\8 U+G*C.B,sP'hN)_F'WE#REPC!H?UC$S; LB'L?#jK+rP1i= L,H2fF.b5]-v?"J(N(K#P'_0i8Z-J'F%i: *
+:' X@ aD%kS.WC"W?$^P-\Q*VQ(I?mh;]S&M4N;6,C>7>99<77=88<76973A<9NGDMFDMFEMHHNIIOHKPJMQKMNIMKHMJHLJGMJFKLFJIFKFBHEBG@?D-.3104!#'&)**),,),515437534755<:;A>@><?<:=><>;8:><>437!#%-,0349().86-QD O<O?H>YM%dY5;>"=@QAYB!C.fJ:_;'c>*nH5lC-jA)kC)d9vK/W;tJ/nG/]9%\7#^B,YL*P;Q5Y< B2."B-xS)qU+}a>]B#T?M?M@ R= V<VI+P< aA b< V0= G4_B+`6!_.m9K,L(BO%V+p<"d4D$O)A ' =*<% kI,y[8WA$X@#YL%TK$OJ%XK*gR.`G!O7XE B9C>6>:9;7:977:77;76B>9NIIKFFMGCMFGNGGNJKMHJLHJMIMLIMKHLIFLIFKNHMHEKCBHECH@?F-.4215!!%$')*)-+*/514626644224:8;C?@?<=?<A>:><77=::679 !(++.335&(.851RH&E9Q?RBRG&QJ*QR1ABD;B3V>0oL9kC+oI5jD1kA-oE+g="i=#pF)qF-k?&mB'nD.kA.N:"?BND O5D/72++=.^5kM#dDZ?#Z=!bF$bM)S:aB"\A!X@\?[1U-S4C3S:!b7"]-d4zC'd3C O,w@#)#
+C]0<:"N4tQ+qV/lP+XD!dR,ha2im9aW2cP-cZ0dU)UN&A=A@*@<6;98;::865:75:54B=<MIHKFFKFDNGGNFHOIINJKLIMNKOLJMLIMKHNHFKKHNKHMBBHDCHBAG-.3/05##'#$'**-,+-2026373230/2969A=A@=A?;>=:;;9:<:>78;! '*,1225)*,//-JF&H@UA_4YA =8ZU23.6-4'T8)jB,nC+a:$^9!`9#h<#f:!pF,rI-e;#oC-nB)\3i@,z^C[R+G;i@!Y7;2405*M5wY2rS2X>W?#^D%M7J5aD%aDbG"S8E$ U/V:B2^E+b:"f9"q=$g8F'F%O&C D L%D!>E$F)`BpU*iW)^G]T+`]1ad2_o5lf9gR-[P(]L"LJ"9@>B+=;7:89<99644:63721D?=NFFKEEKEDNGFLGEOIINIKNJMNKONJPOIOLHMJHLIGMKHMDBHDBFCCH/.1./2!#)"#&)(-)*-1025243140/1968?<@>;@?;<>:<;8;<8=97;"'*+2439)).,--@D%=;hQ*j:[6E;UK*I=-*B2"iB0g=$k@)i>%pE*d;"f9 lA&nE+kG,a:#c9"c9#iA-jB-[?&\Q+YK'lL%oO&L6O<#E2C2lQ.fI&]AQ:aJ-:.M=!eH'mQ(lT.[I(K;Q7`J&ND ^I.b;(i=(sA(b9$L,Q,Z2\1X.N&S,Q-R.O8RA^I$l[.UIRX+MT#RT&\`/^Q(eN*QE#F7vX1nU/E<)>9;<89;76531:63611C=?NFGLEALEELFGLHGMHINGJNIKNKKNILNHMKGKHEJKHMJHLEBIEBICDH--2-.3 #) !&))/''*0/13041151/1946@=A?<>><==;><9<:7::8;"%()/448'(-)**DE%^W,aO(kO'^<E7B9dX385bK:_GnH+vQ2rI+e9 Y.f<%l?'i?&h@*f;&f<$c<&lG4lF5iG*qX(_R(hS(zd3O=?/D4?6XE%_E#hI%dK)`N,XN-YI+aK'dU-m\5RF#JD"D=fR+jY3T<%X4!kC.g@*^<)A#T,g>%]2]2V-U,U.S1WB$hS1XGYM!NINQ!WW*`X0\P+Q@!WI&JF$OBgI$P?JA2<88<98646531;63730D?>LEEHC>LEEKFGLGGMHGOIHNHIOKKNJMMINLHMIEKNJMLJKEBIEAIBCI++2,.2$(+$'',((,/.12/50/21.0:56><A=<@>;?=:=<9:;8;:9="#&&,438**/'(*KF(NAmW-nY2H6I?SG/pZCqW<hF2zT<oQyR7i=%}Q7yO4nE2qD0oD,oF0m@*sF1nD2vM8oD/fC%f/xW'o\)p_,TM':/3&?1_G&fK'jL'xU1gN+ED#?:UK(dY.m[4KA!A34(
+L;mQ4\;)_=,mH0kC+N0!> Z1[0_4a3^6Z3V/_<!jW2gT/eW)`Q&^J&K=`K"nO,bG%[G'UH%UJ%YA!XF"QL&QH8853=98324211984751E@?LFEGBALFGKFFLHEKHGMHGOIKNILOJLNJMLHMJFLLHKKGJECJEBHBBG--2,+0&%+ (),'&+.-00.1/-00-0759=;A;9@<:?;9;;9::8::8< %##&(215+*0!#&SM2^N%m^-nr7RX&TS(YC+gF3`IkJ1yU<yQ6f?&g<$tJ3sJ6kC1nC-rE,nB+qG/xI0mA.jB*oB)fE)iW,kM!uc+n](M?>/XA'Y?!gL,uX5nR0uU4VE$9C"D@$\O*fY+gT-L;N= VM+OC$bG0S3#kG4lD+b=(7O,_4]1_2`5`9#\5#V1V6^M&gY/oBsc7lW1_H"rT.]9xX4cO,RK):4@5VG"m\5IA3:66;88312512853422EACJFEGB@LHFNIGMHGNHGMHHOHJOJLMILOILJGKIFNJHPLHNECIDDGDDF.-3))1'&-(*-&&+,,..,0,,0-,/645<:=:8=<;?>;<<:<:7:;9= "&$&(116-.3 !%^[=ha3_]+Yg,hy6^c0;*Q7&V;%Y7!a;(qH2xP7a9"e>+kA-qH2~S9[>sF,a6uG+wK3nF0g<%hA)nX6we?YG bO#fQ*_I+jO._E&T>!z]8r[4XE!K;6?83K8WE`M&=4I@!ST1^L1^8#S/`:$hB(A%A"W0_4]0]1a8#jC1e@/U2^>!mV+yd6~c:p]3gW,eT)x\3zV.xW3ZH(DC"JI)JE!fQ'PA!<81?9:;761/0512831411FABIDAFB@KGEKFDLEENIHMIJOIIMIKMJOOINNINJGLJGLKGJGDGDAGFDH.03%',)(.'(,('+,,1-,1--3+,0314<:><;=;;><<>=:<;7:><>"$' $$'004+.3$QQ7_[,ci4]j2Ub(ci45)<&P1^:%qL7V>vM4e;&c9"h=%`8"mB.sH0vK1i<'vI1sH.i?)nB.dD+[V-kk=O;!K8eL)_B!G5O@#N9tZ3}^6L9QC E@<2J6eL%[CZG%D68/[;&Y2J*G)K/K/U0Z1^4c7_4\2\6#_<,]8'cC&a6x[/d<wa8aO(YJ!mX-cM$WE!RE"]U1ZO*NBsW-`H+<52>:;9770..52163052.GBAHB@FA?LFCLECLEDMIHKGGNJKMHKNJONJNNKOJGLJGMHFIFCEDBGCBI246%%()(+&&+(&*()-++0-+/,+-326<:<<:>>;?=;<<:<;9<=<=$%( "")105,.3 $JE5`\-d_0V[+@MTT&E5P5#U5G*N3&gJ6hC+b9#d8!f<#_8"R.U0gA+pH2h?*b8"d9"tG1pN4mi:^i6K;F4R:kI*J=84WD&lS.oU/fW.i`6eW2F6U=!eH"dI!\D$G4H7_>)X2S3 V7&V5#]9&\5![2_6a5a6]4X2a<(]<*X:tS(`B]2jCXE$R@lV.hW-TF"UM(^M(bM&[F!gF#UA'=75<98745/--630642521FCDD?@FA?MGDMFDLEELHGKGFLHHOIJPJMOKNMJMJGLHFKHEJGDFCBECEI44:#"(++.&'-)'+*(,++/,,/-+.002:7<=;A=:?<9><9=;8:<;=$%(!""'0/3-.2 %HB3j_1YP&FJ;J[Y'Y@P4"nO9V9'9C%`;%`7 c7 oH/e>)pJ0bD_>#O0S1`8$h>(zM4qH1\Q)V],I=S@$L= J4C921Q>nS.`R*ie5n_2LJ$OB$R7aAtU/L44(Q@%_<(S4^>+V3 [7(Y4"Y2a6d8$`7!_8 _;%dA,`<([9'sT1kN&^EnR*mU0eM*q^5v`7zi@UH#TGjR&mU,XBW8G7#<:7?;8412.+-731631854FBDC??IBALGFJEELEGLEHKFHMHHMIJOJKNJMOIKKHKHFHHEJDAFBBEEEK47; !'*)1!#*%&*))-(*.+-/++.//1;9<=;@<:>>;>:8;869=:;''+!#")/-00/3 %E>2{g<`R)ML"9A[S_H'E-cF/uT>kF1d?*rL5Y>kA(]FqJ9cFXjI.bA._A.dC.U1]6!f;%[G$QP%MDO;kS5L; :4OD#U<mQ/p^0RR"u`4Q?P?lQ)e9sZ17(>9LB%X9#W?)]B3[7%]5#\/]/\1Z2W0Y4]:%U2X5!X8(pV6rW0dK']I#YHlP(g>dU.fX0XI"g[4\L$gM(fN'S=A5$=::=:;0/1/./754630952HDBC?=HB>KEBJFCKEFLFGKFGLGHMIJNIKNHJNJLJFKHEIGEJCBHBAHCAF79<!$)*/ "'$'+$')((,,*/,),.-0:8=><B<:<>;=<:<878<;;'*-#$(..0004!"(;8.n[3gS*VH#\Q%aU)D4 hL:nO9|^DgE-e?)aGwO4[4e>)kE2yX=}Z~\D]>-aE4kP?Y6$V1_6#T=#LF"LJ$bS0R;H7J?!UE'D2X@!xb3WP"sY1rS.nV+y`0|a3iS+8,TQ+\K,\;%Z<+_>,a;'jB.pH4|`LfT^6"]7 `<&V3!X1N*F,qX9hEaJ)WE"ZG!sU-t^6HC!OI%eX0SH"I?VL&p\5cM$>5&><=;99.,-0/3635641;72FB?A=;D@=IEBJCALGEMIHLGINIJMIKMHJMIJLIKIEIHDJFDIDCHB@HBBF::@#++. "&$&*$%)))+))-((,./0:8<?<D<:><:<;9:867<:?++/ "(,+2006!&71+gI*wR-`H"VL%4,1 Z>+iF1sR;vS:sM3`9"rJ2hB)V4!~_GtVpReG0eM;]>._C3w`yV?rH5r_I;="^I%jS-bP*g[1un=<6>.Q8rS)U@mP)tT-jS(v`1gJ%v\3TA!B9bG,[5U2[4W0R,V7#bF0];%Z2^8#pS?`H4cE+aD(]D%hL'pV5~kIhP-nY2iY0tk@k\6aW0pg;\O(NE"GJ bY.xh>EA1=97;85,)+101633522;86EABA=<GCAJEDHA@KFELHGMIHOJKLGKMIINKLLIMJGIGEGFDJFCGCAF?@E;<B %(+.!%%(*&%'((+))0+*-/,/98;>=@<:?<:<<:;;89<:=-,2!$&)*0/05##'0,,iL4\9hQ+J@):'L1$W8&W5 U2gA,qG.a7!e:$yR;dH5mQ=sT<{]FtXB_F2cG5mR<mUx]F`<'bK_R6q_7l\4[L(j]2wq:d^*WC"gX.yh2kS%vZ2oP+u`2tc2\?|\3eU*_T0hK4\6!Y4^6 `6_6!\3 U+X*W,U,R-N-a@&hBu\5bJ)bG$v]7fAuc9PM#`Z2sb9q]6r_8aQ,\W/nm=tl8xxDIH7>99966()+212521412<88FAAA<;IEBJFCGB@KDDLFFKGELGHKFGMIHMIJKHLJGKGDIHDJEBFCCHCBH=?C"#(),/$$&)&()&(*((-((,/,.:7:=;@=:<:9<=;<:89<:=.-0##')*,.24##(,+.N>6dE2bF1N5(T8+X:%\6#_;$Y4X0a7!mC+j?)pH3];&U7%tWDa~cLZ=.kP<{aJM.T2[4 k?(eE)dW/YN'UM,\M-^J#h`-_S$pg2q7wb-cL"w]2tAo]+kP%~a3uX5}bLlJ9\6"^8%Z3`5_3\1[/[-Z-\1W.T*U.^; eE(_F*r_:lV1hT+t?aX-qjBNN%OF$gZ2KALD{uEKgf6B>4@<<743*)+414622531?;8GBA@;<JDAJEAG@?KDBMHFKGEMGGNHIOJJMHKLGKMILIFKFDHCAFCAE@AJ:=E!%)()/!"$+#%)%'((),''*,+0647<;@<9><9><9=:7:<9=0.1!"(++-103"#%,-19+$F+O0V4"T3 V5!c@/uP9zT8f?(a9$j?&sF.a8!\:$N7#aG5u\?]@*V6$sZCM5"V/g:#f:!i@)tO.dK'cQ)OL)WI,cL*[Hod1zl4yc*wa/]I"aJ$zi7uf0x_.{f;_JgE3`:&`9%`6!]3^4^4]4]1^.Z-X-X.V-W/U-[6 d?)rL0qO4hT2qm;]a5SO)ea:\\6e]2JJ!XS)uC|J[Q->;3@<;532*)+41262352/><9E@@?9:KDAKDBHB?JECMFGMHGMIHOIJOJLNIJMHKKGKHFJHEIECICBFA@G?>G!$*)+/!%%*#%'&&*'(.'&+,)/637><A;9;:7:;8>;8>=:>104""'+*-116$$()+.?0)F'P,R0X6$K)M,U3b>)a:#Z/a6lA*kA*cG0cM5gMwZsV;cD/pS>lQ:a:$p@)_4`C#pT,ts=jX-XD"aM([H!UCj=t8{m-q[,gS+bJ%fS*xg3l7{e@bC/]9$e=+j?*a5\/^2X.^3[0[._1X.U+T)W-[1[2\2a2e:"T6 LH!cr?DN!TT'od8YA"aP0Xb3hi8|f9ZQ/<:3A<;0//,,.422312521@<;E?>>99KGCLF@HA@KDBKFGLGINGIMIKOHKOIKMILJGLHEKHDKDCJCBIB@G@AG$%***. $$'$')''(''+&&*,*.648=:@=:=97;:8<:7<;8=226 !%*)-106"%*&).<0.S7&c@*X4H&J&P,R-T0e=#tJ0n@)d9"kA+_A)\H*bM+ub@hK[>+vZBsW{U<m@(iA%sX0{a6pCsn<^J)lX0sX4`N/G5q_0u>kZ/XGn`4\Y,n:v]*\G&`?+_;(`9&a6!a5c6]4Y.Z-a4Z,\,Z.U+T)W)T+W.`.d1c6O6\X3TP(ouDje8VDiT0ra;eh;]Y0~r=`X1;61@;;/+-.,,643620420A=;A<>?99NHFMGEKDAJCCLEGKEEKGHLFGNGGNILMHJJFHJGKHEJEDIEBGBAGAAH')/*)/##&%&*$&)$&+$%*++-645<:=<9?:7<;9<:8;;8;438 $)(-//4#$()).0*+ C&\3 Y1Z5#V1U.a8#lA+lD+e:!j=&`8"[;'[@(`K+fP5P7&_C,cG0[>.X4gB&`G#oZ,k:RU<VW@VQ@MH8SLAMHAGE>OMA\[KQSAWUBccKacIXY9fa;\L4_A1\7$`;(`9#^3c7Y.[/^/]0^._-\,\/U+[+Y,Y,b/b-`2R/cD*dD'r\3eO+I3J>sd8tj=l\2zJgZ=:54@=:,*)/.-42352072/C?<@><@;:QIGNGELGEPIGKDDLGGKFHNGFNHJMIMMIJLFJJGJFFKFCIFBHBAECAG(*.')-###'&%)%$*$%*&%(*),525=:=<;?:8;<9<:8<;8;436 '&'-/06$'*&&*724D/&[8(fA-\7%pM9e>'b;%d<%g<'h;$f8f7`6O,a?*hI3kN;bC0mH1b='U1oH3tV4o`-te2n942*33+41*..(+.-*04.59/59'.2:CEUXXaa]KNO9==>@:QD7^<&d=*P0M)X/U-X-[0_1\-_.\+]+Z,[/Y*[-\-a/d1a1Z._1Z,O.gK.X;UG$rh6vb6h@vX8S@6;87<:7*)+0./632631720E@>@=<?;;SLHNFCPIFRKJMGDNGENHHNFINFJMGIKGILGJLGJHEKEDIDCHCAFCBG**-))- ! "%&&($$'$&&&%()).425;9>=<>;8;:7:98=:6;636 &(*-206$'+%%)602C(f@,[4N+_>(jD+dC-`HjA)i>#oA'zJ-k="_7`:%^8%N(S.mF/yR9i>%`3 dG%zl5wf1{e554-64-22)12)+.*.6608>,25)04?FIZ\WdaZAEI &)9-$O1S/N*U/yY?vXA~`HbC/N'\1\-Z,],]*[*X)X*Z+[+_-a1\-]-^.\0V/`6^7kT,lX-yV6lC'X/C2*@<:956**-414423511620E@>?;:A<:TMJNFCRHFTMHLFDOGEMGGLGIJEGKFGJEHLGIKFHGEHFDHBBFA@FDBG+*0'),! !("#&!#'!$$##(('-526<9?=:>;8=:7:<9;:8>86; %&',104%'*%&)422>%N+^7#_8#O-eA,cA,xXD{R:qD*{N5W>xQ6sG,a7!e=&mA*tG.mF.mF0Z?d;sZ-h6s:|zB54+53*32*43.+-)3;=/6?-25/6:?FI[]XZ]Y+26;2,R4"P-G)@! qNfH]@)kR;Q<+; J'O&Z+^+\)`.[*Z([)W'^.a/\,\.\2S(S(Q&V)Q+\3`2S'P)B6-@<9846)),414414311731FA@@;9@<;TLLJB>PHDXNIMFCPIFOHEKEFKFGIDGKFGLHJIFIHFJFDHBAE@@ECCH,+2&(-!!!)""'!"'!%'$$('&,208:8==:=<9<:8;<8<;8<98;%''-016$'*"%*3268#?V3!lC-W3 O-T1P0g?+k@(`7!bA/bJ}R<nC/mF.mD,pE.a7^7i?&hJ!Dy=xh1mi474-52*53)30)+-*/6:/7=035/58;DGXYVRMGK:3sSBfE3nG3K*fB)uLwL1\>(U9$D,C&L,P*W+Y-[+[*\*Z(Z)[/Z1V*T+]9#Y1U+U+R'R%U(U(T(T)O)@60=;:421,++3014113/0731D?@?9:@;:QKIJEAQJFVOIQJGQJIPHHIDDJCDKCFKFFLGIJGJJFIFCHCAD@@DBBH+-1&(, ""'$%($$&!!$$$)&'*00387:;:<;9997:<:>:8:86:!#''/-07&(,$%)126>+ >Q,`5 _;%T2V1D$W4 e=&M*@"c>*kC/]7#d=(b;$V-\.\.`3w^0ye/y=~h1y`252,54*42*10(,+'26948</04.59;ACZWLnP<b=(N8'YJ9X:%a?*[5Y2X3I,<!>"W5"h>*m@,rC.g;(U*W*[/^3c;'^<*P/K(S/c;%i=&c;$Y2N(G!I Q#O#R)J(<52=::2//,++6342002/-952D?@=9;?;9SLIHDAOFEVNKTLMQJKNGIGBBIBBIAEICDLFGKGKHFIFCIB?FB>FB@H-/4%'*"!!&!#&"%""&$%()(*1/365:<:=<9=979<9=97:97< !'(-005%&+$')/15G4)O,]8(tN;xR;V3X2Q-Q-d>(^C3M3"^8&jC-vQ8jB,wN8kC/g6q8 qE+i@|i6|:K{>22,21)1/)..),-+,17+04*-.+37;@@HB4=,0!%!D8,F-!; = 8F'M+E%O.[2j;%k<&h<&e8#wG3pE,kF-cA+W0e;(lB+a6 S/d=(Y0Q*S+S,S*T.J)E,<86>:92/./--6341/.20-954GAC<88<96QKGG@=NFDXPOSKMQIIICDC>=HCAD>AICDNGGMFKHDHGDGB?E?<C@?F./7%%,$'#$)!"& &"!''&+2/2859;8?;9=968:8=98;97= $&&+115&(-$#'//2I;2\:&O-Q2!\7&S.\8!eA*_:'`;'[9)U6&`:(kD.vN7rM:jC0gA-k@)qA)oV3h?t@vj1@>31)21)00+20,..)+02*/2*,.)03:BBTTJMMD-00*,+++&''"2.(QF<L9,B"F-9;#5 8!?#>F%O,D X2V/oJ-b=&X2!eA.tN5jB->#S4$a9%`9&]6!sL3gLK,S1H4,;86=970/.0./532-,-0-,:66EAA953?;9OIFD><KE>XNJTKKPJIGBAB>=JCAC=<KBCLFFKFHHEGEBGA=D>;@@?D/18$%-$"!#&##' $&'&+/.2669:8>98:859:8<97;98<""%&*125()/##'/04B62X7&V1Y6#`8%hC.lH1g?*]7#\4]7#^8$]6"`9'`8$U1V1X3Y3_6~EE}Awf6sU+u474+32*1.*20).-'*./(-1)-.)059ADWXPUVM257,,+./*00+20)(&HD<W@1B*<(:$D/I6"@*=%E*H$G#C E I G D#E%L-<E)64 ;3J-M3 C(dB.R>4<66:780-/3/1220.-,2/->95D@=634=99MFDC<;GA@ULJPJILGFB==@:;JDBE>=JBBNHGIEIGBGDBF@?A=<@=<B0/2&&*# "!$ && $'')/.2647;9=99=768;8<:6:=:="!&(,214*,0"#(004:1.K*U1b<)c;&_;,^9&U.`6!oC/nD/]6"kF5mG6h>*[3X3_9#W,xW/q7v:{p6o`,}h8{i342,32*32*22+*,**05(-0)..*19;AF[[PVWO49:./.0/*0.(53)31(@=7aYMZPFXRJZOBVD4I8%<+A+E-G-F'N,U+[*W)M! P! G
+K! M J"K$B7 9,* ^I3SE;;56;771/,311211/--3/.>;8C=>502=:9OHEC<:G??ULJOIFHDB=:8>:8F@@E>?KCBLGFFBBFACB@D?>C;:?=<A008&%*"" !%!%# &%$(-+0649;:?:9=666668:9=;9?$%'+-.3(+/ "%/05:21M/J-T1P,O+X1L(\6#b;)XAc<&N-\8(V/M)S/R+iH(Ui^)n_*s8?|p6tc.21-21.32,22--.*,04*-2',/(379BCZYLSSL/46,-).,'0/'.-&33,NMH`]Q_\RSSPZXR]ZPZQE^THVH9J5%;&>#G/M-Y-^-_,d/c.`+`.W,X+R'T'J O)972 C=4<88:651.0311311.,-3/-@<;B=?522A<9NGCA<:E>=SLJMHDD@@;78>97FABB<=KB@OHHE@BEBE@?D>=D;;?;:@128%$)"# !% $!"!'$$*+*0548:9>;9>63897<:8;;9>! &"$&.,.6*,0!"&//3:44Z>.]A0Y8&\5 `;$Q.J)T2"O/G(H+C*M/U;]G#YB!kU*u?Q{x:zx8tl1}z8~<x~:44-42.21+21)..,(-1+.1*/1*36?EE][OUTL056+-*1/)22-+-*>@=RSO[WKZVLPPNVTMTSKVQG^ZQYVLgbUbVIR5!T7#T8$Z5b4h4j4b-^+a0Z,Z,T'T%T'W,M0
+30.A<=7570.23021//,++1.+D?=?;<320A<<MFEB<9D=9RKIMGHA=<858=87F@?A=;JC@NEEC=>HCEDAC?>A;:?;9>45:$&*!"!' &!##%),+033798=:8=76;87:96;<;A""'&&,//4.-3$$+/.4513N9-T;-b?/X0gA*uP4J)O0 O3 \K$im5~HhS)x<oh,m\,@uk.eQ{h6vp8vl1wl3`X'ic143+10)32.20*..-&,1'-/(,.,28@EF[ZMTTK057+..//(11+*-)@DCRTQ\VK^\PNQLUTMWWRLKCZZRWUPXRMidZXJ;H+T4S0\3b5j7e5^1_.^+_.X*Z+_.],K.843B;:844201323,-,-+*1-+C>=>:<321A<=NFFC=;C<9SJILFE>::422;67H?=C>:HC?MECC>=JCDE?C?=C98>:8=68<$&*"#'!!& $$%),*.316:8=<9=75777997<<9@$#+&(*..1.-2"")..385622S5%Z3W2`;"R0E&]N&u~=vF}Cd4ACp^-yv<p_-n9u`0sn9vi3kX)q^2lA21*10,21+0/*,.,(-1&,/(.1)1:;AE\\NSSK168/10,-(.-&,-)DFDVSO\VK\[RMPOQRQXYVLKEVWQYVS`VNb^T\TFWH;O8)I*I'C(>&59$C/!E,8!?'E(I'Y18 <89@;:864411422,++,++3/-C>=;79301C==MEDA;9C>;QJGICC:8:200966E??C<:GA=KDC?:=GBAD@B@>D76<76;77>$%* # $# %$$)*(.306:8=;9?64854;97<<;?&%*')/./4,-/"!%.-0646?3$6#4M-D'U6'WA)la7jk+hx4zDp9xc/~o5Rxo6BЮoȣiu]-xD{i7v[2v]3xf910+31,52*1/(-.*+//,0/,03&.68AC\[NRQH/36*.,,-).-(-/+FEDVRM`ZNVUNJLLLNKUVTLJETURVUQ]XP`_Ub_R]YN]WMI?3QC3QB4H=/OD9UJ@EB<-.(**' !@<<?;9641421524+*+))+40/C@@6471.0D>>NFDB;9C>:RKHHBA6550.3746D><C>;GB@JCCA<=ICBC?@A=B97=54887<$%) " #""# #"#()).20597<<:?65:439889;;=%'*%(../5++0 &..4102`X8od4[Q*TG(RB!QD!vu;x{:uw9}Etv4te/h`.o6{g2{n3IHp?v^/|h6m;~d4rV'nX.10(31)1/(0/(..+*/0)..)+-'/47@C\[MOQI/47,.*//(.-'-0-HFDSNG\YLTSKIJIKMJTUSKJCOPLRRO]XN[VLNI@TOCYXPHG:MJ;_YLh\LjdV]\QFE?*+%%% &'$$%! !"! A><@;:633736414+)),),1//DBC536-+.B?>NGCC<<@<;OIFF@@5242/3745B<<D=:HA>HBAB><KFBD@BB?D75;44:88=$&* " #! " $ &$$&10376<;:@65:22777;;9>&&,&',004,,/ "&//3125QJ1`P"zk6LxEo7pp)uy7Jv{>nr4vd3mb-}r8g6te+j\(W>x^5w`1j<Ti[%sX,z_1//(22+21)0.)-,**./+.0)-0*24:?@_]POQK5<>..-00+0/)*,+JGA[SI\XPTSLIKIGIGTTOLJDRQJVTK]WM[SJOF<^XJPOIDD;JMDTWP_[QZWPRQKCA<)*&%%"&& #$!!%&$EA<>:7753756003&'*''*310EA@312...DA?LFDB;;@;=MHGGAB5251/1637A;=C<<JBBICB@<=HCDE@DA@C67965:9:A$&*!#"!%$!$('%(20487=;:>76<54987;=;A+,0&',0/5,-1!%//40.2XP;jW.gQ%gZ%k\&l2to0yv7zn1{p8ob0r[0RHbV)lM)tY/cL&P6pP0h<o>~IpZ0qX+iT%11)21)10*..+*,+'+,+./&,.(16:@A[YLKMG058*-+,/+.0,+..JHBb[N^\USSIIKIDEDTTMLKCQPKWTN\VJ[TJSLC_WJRQIDGBISNKSOZZSYWRSPLFA>12.$#&&%% !##,+(GA=;8:5547531/1%%)%&'31/C>=1/1/.1HCALGE>:;B=:PHFF??1/32/1413@9:D>=HAAHABB>=HDCCAD>>B669659:;?%'+!# %!!%&*(%,0.454:;9?86>65;76;=<A+-2#%+..4+,/#%',/2/-3PJ4eX*oe3SEfY!e_%hY'tZ+y\.~b7{^7oR.G5ZI(y]9{[5YB$]K*dG&eM(x_8qR)~k;yn:jZ/10*10)//(/0*+-)(++*-/'-/'16<CD\ZMIKH/67+.+..),-)*/.HGA]XJ\\VQQHOOMEGERSLKIDSPKUTOWQE\SFMH@aYISOGCGFLRRMOO^_VXVSRMJHC=251&&&%%!$$ 30-F@>:876545430./&%(&&'640D@=-,,..0IDCLEB>:7B<:OFDD>=0/2201411?:8F?>H@ALEBC><LFCDBC?>D65;348:;A)', $ &#'&+*'+1/3759:8@:9>75:55;=<A,,1#%*//1++/"#(..4--5QD6dL&]O"o^/m^-YY vb3iM'oT+vZ/rh3s\2zb<iW/q`2u_0jT+x^5sS-dK$u]3ze5gT&na5}uB21+21*10)21+-,)*,.*,/).0/47GID][OHKG179,.+.--+++*.-KIB]WJ[ZPPQJLMICDCRSOHGDTPIUTLYRF^SELF@^TGTMDHIJHIJPMM^^WXVSOKHIE;8:8&(+""!!# ##":32F?@;76;85421.-."#)$$&964B?>+++00/FB@KDA?9:B=>NGEB=<0/1--01/2>:8E><HAALDCF@=LFDEBB?=C97>539<:?((."$"&%+'&+1.3549:9A:8<76976<<;?../$$+//4*,0 "%0/3/04NB3bF"fL){k:cQ'cZ*oX,pT0wZ4}]6q\1i9yFgQ(ud:hR/iV.z_5lN&p\0oZ1~k;mX-ud9kh132*21)21-21+-,)(,.(-0*/3389FID\[NCHE38<./.-.,'***./LLD^ZL][QOQNHLHCFBUTQHFFWQJVTJ[TF^SFND@]TIZQIEEFJMOUUR_\UWUTPKHLE=:;:%')""#!  <74GA><77<75632/-.#"' !!963?9=,*.443EA?JDBA:;D?>JDFA<>101-,//-/>87C=9KD@IBBF@@NFDEA@>=A;8=75:;:@+)/!% $#(&&-20553887<86<859:8;:9=/02$%,-.4+-1#$'..1.07?92E.O8nY3_A#gW.qT*dG'X@tP.pK*vZ1q9jW*rd:nf;oe8yc7jN'td3xm9|d5s[1l`1sl;/0)11)01,11,++()-/).0*.0+14BHF[[LDHE5;?-/...)/21,13MQIb`Q[ZSLOOJLIAFCTUPIHFSJCYWK]WJ[QGMB<`XK^UJECEEJLNTNZZOTSQJGAOI<<=;')+$$ %#!><7C@:=96=87301,--#"%";77?::*(+533EA@KDBB<9E?>LDFB<>/.1-+./..=78F?=LE@IB?F?@MGFGCDA?B<;?446:;B-./  #!$&(#$*00365;99<88:87:88=:9@103"&+-.2-,/#$'-,0118<71R5`?"jH$}Z3kK%tV/`D#U9jG'oN+eL%re3pf0l^,k[.v\3_7nT+hZ)cP$_Fwh5wu:xs=20+21,21+11+.-**/0).1(,026<IKH][MGKF48;021-.(-00.22ORKa`UXYQLPNKNMBEFUTOFDAZREVTH[UK]QFRC8bYF^UHFEFFLOMTOY\PRTPMHCTLA9:8&+($%!! B@>A=;<:7965110,,-""$ $<9:<98()*:77FABJDB@;8E?=JBAA==0/4+,//.0:65G@<LEAJC?HB@NFFFAD@=C;:?325;;A,,2"% !&'+$&)..298<97;98<87=97=:9>0/4!$+--3-,0$$(..3//5@85fH-Z;_A#jQ+bF&oL,zS2vV1bE#rZ1r`1xh7kZ,u_2uX/_7|d3oh/tl3wb8wg8zo9xw;sx:32+32,43.01+/0,).-(+-*,/269KMJ_^QDHF159364+-,*-/.33KNI\\TXWRGIJJMMCEHTRNGBAWOCVSF\VG_TFQB6dZG_VFADEAIONRN[\RVURMGBRLC698!&# #"!! !DA<?:9<88:761/0*)- !"?:;854,+,978FA@MFD@;9FA>HCC?;=/.0*),-,.843D?<LEAIB?IABNGGDA@?<@<;@326=<A--1 !!!)'-(',,,176:98<76<76:86;::>126!#$*,-1+,2%$*/.2--1C=:]E.L0Q8Z?#]?%qP-RSuV.cM&[U%tm4|k9pT-oB~e9qb0h^*zt8qh3i`/gY,ka-ke.11*54,63-/.*),**./)-.(,016:JNL\\Q?ED06:/10+/-*.0/44JNI\]VVWUGHJILLBEEUSMKA@WNDXTH[TE^SEYJ;bZK\RCEFEBLRKPOZ\UVUTNICPKB376#&& ! !# '%$E@=>:9=875231.2((-!! #B==843/-.:86EAALFBA:8IB?ICB?==/,0)',,,.:57C><IC?IA>IBBNGGFAA?=A;9@116::?,-0 '')''++*.76:77=77;65987<:9>238#$(--2+-3(',,,//03<98VA*eL(q[1jM)dE"m;YW?UB]I"WQ%pk1hW$V:lW0}m=tb.m`,xs5d\$nb.nY*`Q"]P#32+33-21+/.+),-(.1).0).2.47LPMXYO=CB069.10+//*/2257IMI[\UTVRFGFJLJABBWSMRE=\SFYVK]UHaTD^Q<d]M[UIECBEGIDKHQYQSTQLFANH?266#&'!! !+)(D@==89;674252/2'(*!#"%C>=632.,,;76E>>KDC>98KDAJD@<;:-,0'&*,*.626E@=IC@HA?HA@MFDF@B>=A<:@427;:?,.1!%$'%&*+).63977>:8=86=98<<:=549"%),,0**1$&+-/2118978_Q-mZ%pS&nM%yc3mS'lV%rf1qk5vf2wm=oc+wj3o_-ti5~Bvv5pm3lf0ki0xq5zj3bQ"b_,43,21,30+22-*.,045,04*/5-59LOM\[NBDB379.0.+.-*.0/36FII[]XTUREGHJKHACBVTNWK=[SDZXK_WHbVDbVC_ZIZVIIB@JEHCHEFULKPMJE@MH?255'** " .,*D@==79:7:525312&')&"&C??222.,/;86E>=IDB=96OHDIC@<;;,,/$%(-+-624C>;JB?IA=H@>NEEHBC=<?<<@218;9?--4"%$((())(-527:8=95<87;87;98=338 $#)+-1*,0''+//3127978cW4q_*kI%jI!u`1hK%nR&zj5x>l]'zs:uu7uo5y{9TS{=kj1`R&j^+op3de*ib+`a'32+32-22,01+.22/31+-/*137=@PRN^]PDFE:=>133,0/-12048BGIVYUSVSGJIHKIADDYYOZN?ZQDXWN_WGg[IbWE`[J[VFPE>MEDCFG>QNFNLMKCNLC367"') % ""20.E?==9;:77744/.0$%'%$(B?=1/1/-1:74E?>LEA@;6OHBG@?>:;/.0%&)+**612D=<LD@IA<H@?KCEGAD@=>=;A33989=+-5&$)'&(,*.305:7<87>86;76<87<559!$(--2,,0(*//03014658YM.xj3pV-xg4{e6{d6gN#q`2Fto5pj4ux:nl1xAy}7{~=qz7in6{z@hZ&gY'jd0jc0ob010+41-21+/1-,00,.0,0/18;@CEVVP\[RAED7;<444-/0.01269CHITUUOQPMONJLIADDZXO[M>\TFUTM^VHe[IdYD^ZMZVINE:KBBBFK?PPIPLNLAQMB699&-- #!642C><>98;767440./#$'(((A=</--/-/;86F@?LEB?:6PHEJDC>:=.,/&%))(*301GA?NGCICAJBBLEDGBC@=B=;@22667<,.3##)%&+-*.20488=88>96;86<98>66;$%*--1,+0()/106225544f_=qm3m\-qh4p_2ve8mg6vr?u|?Fvh:ps9sx;v{>mv5cl+o}=mw:e`+fc/{w@}uBsi:oZ,22+42,42-.0,,-,..0,0029:;ABSTNZZO>EB39:-01,./)-0-45AFEPRQMONGJJHHH@BBXVO]P?[UFQQKYREc[I`XF]ZNZWLPF<MC@@DF>NNINILJ>PM@486',,"&$ ;96E?=?:8<77533///!!#*)+>;</--0./=86FABKDBB;5PIGKDD=88,+-#%(*))2/0ICARIFKDBKDBLEBHCBA=D>;A22455;-.2 ##)'&+)(-0/2:9=:8>86<96>:9>97; #$*--3*-0(),217216556^P7f_-^V'pg7rd3jY-d`-da.W]'lt7us>^g-ht4ns9ku2\k'jz<ic0lg5it7rs:k^1`Q&jV'33+12*43.00,,--),,).0.576=>QRJYYM?DA067.22./.)./-46?CAKNLJNMDGFDFE@CCXYPcXD]WJPRK^YJd]KbYG^]RYXOUJ=PE;BDC8HJGNILG;MI:585&*+$%%!"?;8E?;?:8<98633000 !#/-0>;;))*312<86GB@LECC<9QJGKEE<79.-1$$*('*0-/HB?RIEMFALFALECFAAA>A><A21666;.04!$#'$%,('-.-197>:7<87=97?:8>;9<!#$(0/3,,1)*-228-.466:I:*I7VO%[M%cJ%cH$gT(g_/ej4^d'kk._d,jr8ls7cl/Wg*]h0bc2hu=hv=hk7cW+o]1pa245012+11+/0,,.-+.1)/2-385;?RUNXZP=CC477-10,0.(++057>CBIMMKNOHJKGIH@BBWWPeYF\XJPSK]YJ`[K`ZKXYPWVLVK>WL@IKJ:GNGLIOJ?PL?695#') "# B?<D>;>96:866450-0#434;9:)),624=78JC@LDCE?;SMGMFE867--1$#&&'),,,JB?UKHLD@NFDOFGHCAA>@=;B.0568;//5"  %&#*+*.--098=;8?98<87;97=;9=#"#'//2*,0**-447,+.55:=51E1F6]M,S9^?Z?bO(ba/yy?gg+ah.^e.dn2hh2[^)_b0it=jq9ie;RF!]K&kO*\D!32*22+.0+/0,-//,/0+03-254;>PSLWXO=CD37:-12+/-',-043<??DJLQSWORQFHF@@>VVO_TBYRFNOH_ZM]XIZXJSUKUSJYOAUKBCAF9AKFIHNI>LK@586 %% "! !DA=D@<?97;74854.--"655976*).734?99HA@KDBG@<SLHLEC744/.1""%$$(-+,KDAVLINDAQIGRIFHBAA>@><@-.355;006!!""$%%')(,.-/87<:9>76;85::8>99>!% "%--/+,/'(.547.-0456F?6L4M5]N+ZI&ZB!W;lL*jT,th7TM ib0Z[#he.mG\L'c`/ce/]O#jS/hR-l[0kR,R910+33.230/.,-//*,.).0'/0/78MOJTUJ>CB177,/1+-.)-/-159<?BEIEJIHKIACBBCBVUL_UDVRIMOJ\YN]\N]\LRULRSHXP>RKAFDH<DMEGFOI>LLA386$((!$!"$#$%"FC?E@=>98<77733.-,=<;643('(866>88HA@MF@HA=TKFIB@4320.0$#'$$)-*-KDAUKFOFDUKHTLFJBCC>C?=B.-1437..2  "$'"$&*()+*.75998=76:659<:A99> % "&,-0,,1**/744@4#F8 dS.eH%fM&cR'xo:yd6_=rQ-za:r_3hS)pZ,fR%U@eI%kO'i9cN$rW3dJ$ZCO=cQ,oZ51/-22.010,,,(+*'**&+-&-0,48JMHUVK<@=387-11*-.(,.-27:?BBEGBHEFJG?B@@CATTL`YFTRJKOJYYMXXM]]OQTNSTJYQBRI?FBD>EKFIGRLAMKA496%** " "/.+KDAGA<?:6:65531--+FCA1/0'&&975@9:F@ALEALD?VLHIBA411202"#(""&++-KCAXLGPFEWMJTKFMEEE@C=<A./1335--0  ! !$$&*),)),86;96;:7:76;99>99=$!&+-1+,0**-F>8[B!U;bH"aCpW+lX)r8m4d6h@kDoQ-y_2kT%mQ(jI'\>vY1f9pT*y_9`F"dK$X?hY:i]9 \ No newline at end of file
diff --git a/Magick++/demo/piddle.cpp b/Magick++/demo/piddle.cpp
new file mode 100644
index 0000000..989ea93
--- /dev/null
+++ b/Magick++/demo/piddle.cpp
@@ -0,0 +1,184 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2002, 2003
+//
+// PerlMagick "piddle" demo re-implemented using Magick++ methods.
+// The PerlMagick "piddle" demo is written by John Cristy
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ // Common font to use.
+ string font = "Helvetica";
+
+ //
+ // Create a 300x300 white canvas.
+ //
+ Image image( "300x300", "white" );
+
+ // Drawing list
+ std::list<Magick::Drawable> drawList;
+
+ // Start drawing by pushing a drawing context with specified
+ // viewbox size
+ drawList.push_back(DrawablePushGraphicContext());
+ drawList.push_back(DrawableViewbox(0,0,image.columns(),image.rows()));
+
+ //
+ // Draw blue grid
+ //
+ drawList.push_back(DrawableStrokeColor("#ccf"));
+ for ( int i=0; i < 300; i += 10 )
+ {
+ drawList.push_back(DrawableLine(i,0, i,300));
+ drawList.push_back(DrawableLine(0,i, 300,i));
+ }
+
+ //
+ // Draw rounded rectangle.
+ //
+ drawList.push_back(DrawableFillColor("blue"));
+ drawList.push_back(DrawableStrokeColor("red"));
+ drawList.push_back(DrawableRoundRectangle(15,15, 70,70, 10,10));
+
+ drawList.push_back(DrawableFillColor("blue"));
+ drawList.push_back(DrawableStrokeColor("maroon"));
+ drawList.push_back(DrawableStrokeWidth(4));
+ drawList.push_back(DrawableRoundRectangle(15,15, 70,70, 10,10));
+
+ //
+ // Draw curve.
+ //
+ {
+ drawList.push_back(DrawableStrokeColor("black"));
+ drawList.push_back(DrawableStrokeWidth(4));
+ drawList.push_back(DrawableFillColor(Color()));
+
+ std::list<Magick::Coordinate> points;
+ points.push_back(Coordinate(20,20));
+ points.push_back(Coordinate(100,50));
+ points.push_back(Coordinate(50,100));
+ points.push_back(Coordinate(160,160));
+ drawList.push_back(DrawableBezier(points));
+ }
+
+ //
+ // Draw line
+ //
+ {
+ const double dash_array[] = {4.0, 3.0, 0.0};
+ drawList.push_back(DrawableDashArray(dash_array));
+ drawList.push_back(DrawableStrokeColor("red"));
+ drawList.push_back(DrawableStrokeWidth(1));
+ drawList.push_back(DrawableLine(10,200, 54,182));
+ drawList.push_back(DrawableDashArray((double *) 0));
+ }
+
+ //
+ // Draw arc within a circle.
+ //
+ drawList.push_back(DrawableStrokeColor("black"));
+ drawList.push_back(DrawableFillColor("yellow"));
+ drawList.push_back(DrawableStrokeWidth(4));
+ drawList.push_back(DrawableCircle(160,70, 200,70));
+
+ drawList.push_back(DrawableStrokeColor("black"));
+ drawList.push_back(DrawableFillColor("blue"));
+ drawList.push_back(DrawableStrokeWidth(4));
+ {
+ std::list<VPath> path;
+ path.push_back(PathMovetoAbs(Coordinate(160,70)));
+ path.push_back(PathLinetoVerticalRel(-40));
+ path.push_back(PathArcRel(PathArcArgs(40,40, 0, 0, 0, -40,40)));
+ path.push_back(PathClosePath());
+ drawList.push_back(DrawablePath(path));
+ }
+
+ //
+ // Draw pentogram.
+ //
+ {
+ drawList.push_back(DrawableStrokeColor("red"));
+ drawList.push_back(DrawableFillColor("LimeGreen"));
+ drawList.push_back(DrawableStrokeWidth(3));
+
+ std::list<Magick::Coordinate> points;
+ points.push_back(Coordinate(160,120));
+ points.push_back(Coordinate(130,190));
+ points.push_back(Coordinate(210,145));
+ points.push_back(Coordinate(110,145));
+ points.push_back(Coordinate(190,190));
+ points.push_back(Coordinate(160,120));
+ drawList.push_back(DrawablePolygon(points));
+ }
+
+ //
+ // Draw rectangle.
+ //
+ drawList.push_back(DrawableStrokeWidth(5));
+ drawList.push_back(DrawableFillColor(Color())); // No fill
+ drawList.push_back(DrawableStrokeColor("yellow"));
+ drawList.push_back(DrawableLine(200,260, 200,200));
+ drawList.push_back(DrawableLine(200,200, 260,200));
+ drawList.push_back(DrawableStrokeColor("red"));
+ drawList.push_back(DrawableLine(260,200, 260,260));
+ drawList.push_back(DrawableStrokeColor("green"));
+ drawList.push_back(DrawableLine(200,260, 260,260));
+
+ //
+ // Draw text.
+ //
+ drawList.push_back(DrawableFont(font));
+ drawList.push_back(DrawableFillColor("green"));
+ drawList.push_back(DrawableStrokeColor(Color())); // unset color
+ drawList.push_back(DrawablePointSize(24));
+ drawList.push_back(DrawableTranslation(30,140));
+ drawList.push_back(DrawableRotation(45.0));
+ drawList.push_back(DrawableText(0,0,"This is a test!"));
+
+ // Finish drawing by popping back to base context.
+ drawList.push_back(DrawablePopGraphicContext());
+
+ // Draw everything using completed drawing list
+ // image.debug(true);
+ image.draw(drawList);
+
+ // image.write( "piddle.mvg" );
+
+ cout << "Writing image \"piddle_out.miff\" ..." << endl;
+ image.depth( 8 );
+ image.compressType( RLECompression );
+ image.write( "piddle_out.miff" );
+ cout << "Writing MVG metafile \"piddle_out.mvg\" ..." << endl;
+ image.write( "piddle_out.mvg" );
+
+ // cout << "Display image..." << endl;
+ // image.display( );
+
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/demo/shapes.cpp b/Magick++/demo/shapes.cpp
new file mode 100644
index 0000000..0069773
--- /dev/null
+++ b/Magick++/demo/shapes.cpp
@@ -0,0 +1,125 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2002, 2003
+//
+// GD/PerlMagick example using Magick++ methods.
+//
+// Concept and algorithms lifted from PerlMagick demo script
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ // Common font to use.
+ string font = "Helvetica";
+
+ //
+ // Create a 300x300 white canvas.
+ //
+ Image image( "300x300", "white" );
+
+ //
+ // Draw texture-filled polygon
+ //
+ // Polygon list
+ std::list<Coordinate> poly_coord;
+ poly_coord.push_back( Coordinate(30,30) );
+ poly_coord.push_back( Coordinate(100,10) );
+ poly_coord.push_back( Coordinate(190,290) );
+ poly_coord.push_back( Coordinate(30,290) );
+
+ Image texture( srcdir + "tile.miff" );
+ image.penTexture( texture );
+ image.draw( DrawablePolygon( poly_coord ) );
+ texture.isValid( false );
+ image.penTexture( texture ); // Unset texture
+
+ //
+ // Draw filled ellipse with black border, and red fill color
+ //
+ image.strokeColor( "black" );
+ image.fillColor( "red" );
+ image.strokeWidth( 5 );
+ image.draw( DrawableEllipse( 100,100, 50,75, 0,360 ) );
+ image.fillColor( Color() ); // Clear out fill color
+
+ //
+ // Draw ellipse, and polygon, with black stroke, strokeWidth of 5
+ //
+ image.strokeColor( "black" );
+ image.strokeWidth( 5 );
+ list<Drawable> drawlist;
+
+ // Add polygon to list
+ poly_coord.clear();
+ poly_coord.push_back( Coordinate(30,30) );
+ poly_coord.push_back( Coordinate(100,10) );
+ poly_coord.push_back( Coordinate(190,290) );
+ poly_coord.push_back( Coordinate(30,290) );
+ drawlist.push_back( DrawablePolygon( poly_coord ) );
+ image.draw( drawlist );
+
+ //
+ // Floodfill object with blue
+ //
+ image.colorFuzz( MaxRGB*0.8 ); // 80%
+ image.floodFillColor( "+132+62", "blue" );
+
+ //
+ // Draw text
+ //
+ image.strokeColor(Color());
+ image.fillColor( "red" );
+ image.font( font );
+ image.fontPointsize( 18 );
+ image.annotate( "Hello world!", "+150+20" );
+
+ image.fillColor( "blue" );
+ image.font( font );
+ image.fontPointsize( 14 );
+ image.annotate( "Goodbye cruel world!", "+150+38" );
+
+ image.fillColor( "black" );
+ image.font( font );
+ image.fontPointsize( 14 );
+ image.annotate( "I'm climbing the wall!", "+280+120",
+ NorthWestGravity, 90.0 );
+ //image.display();
+ //
+ // Write image.
+ //
+
+ cout << "Writing image \"shapes_out.miff\" ..." << endl;
+ image.depth( 8 );
+ image.compressType( RLECompression );
+ image.write( "shapes_out.miff" );
+
+ // cout << "Display image..." << endl;
+ // image.display( );
+
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/demo/smile.miff b/Magick++/demo/smile.miff
new file mode 100644
index 0000000..0d7cb53
--- /dev/null
+++ b/Magick++/demo/smile.miff
Binary files differ
diff --git a/Magick++/demo/smile_anim.miff b/Magick++/demo/smile_anim.miff
new file mode 100644
index 0000000..281894d
--- /dev/null
+++ b/Magick++/demo/smile_anim.miff
Binary files differ
diff --git a/Magick++/demo/tile.miff b/Magick++/demo/tile.miff
new file mode 100644
index 0000000..911451a
--- /dev/null
+++ b/Magick++/demo/tile.miff
Binary files differ
diff --git a/Magick++/demo/zoom.cpp b/Magick++/demo/zoom.cpp
new file mode 100644
index 0000000..32e73cd
--- /dev/null
+++ b/Magick++/demo/zoom.cpp
@@ -0,0 +1,191 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 2001, 2002, 2003
+//
+// Resize image using specified resize algorithm with Magick++ API
+//
+// Usage: zoom [-density resolution] [-filter algorithm] [-geometry geometry]
+// [-resample resolution] input_file output_file
+//
+
+#include <Magick++.h>
+#include <iostream>
+#include <string>
+using namespace std;
+using namespace Magick;
+
+static void Usage ( char **argv )
+{
+ cout << "Usage: " << argv[0]
+ << " [-density resolution] [-filter algorithm] [-geometry geometry]"
+ << " [-resample resolution] input_file output_file" << endl
+ << " algorithm - bessel blackman box catrom cubic gaussian hamming hanning" << endl
+ << " hermite lanczos mitchell point quadratic sample scale sinc triangle" << endl;
+ exit(1);
+}
+
+static void ParseError (int position, char **argv)
+{
+ cout << "Argument \"" << argv[position] << "\" at position" << position
+ << "incorrect" << endl;
+ Usage(argv);
+}
+
+int main(int argc,char **argv)
+{
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ if ( argc < 2 )
+ Usage(argv);
+
+ enum ResizeAlgorithm
+ {
+ Zoom,
+ Scale,
+ Sample
+ };
+
+ {
+ Geometry density;
+ Geometry geometry;
+ Geometry resample;
+ Magick::FilterTypes filter(LanczosFilter);
+ ResizeAlgorithm resize_algorithm=Zoom;
+
+ int argv_index=1;
+ while ((argv_index < argc - 2) && (*argv[argv_index] == '-'))
+ {
+ std::string command(argv[argv_index]);
+ if (command.compare("-density") == 0)
+ {
+ argv_index++;
+ try {
+ density=Geometry(argv[argv_index]);
+ }
+ catch( exception &/* error_ */)
+ {
+ ParseError(argv_index,argv);
+ }
+ argv_index++;
+ continue;
+ }
+ else if (command.compare("-filter") == 0)
+ {
+ argv_index++;
+ std::string algorithm(argv[argv_index]);
+ if (algorithm.compare("point") == 0)
+ filter=PointFilter;
+ else if (algorithm.compare("box") == 0)
+ filter=BoxFilter;
+ else if (algorithm.compare("triangle") == 0)
+ filter=TriangleFilter;
+ else if (algorithm.compare("hermite") == 0)
+ filter=HermiteFilter;
+ else if (algorithm.compare("hanning") == 0)
+ filter=HanningFilter;
+ else if (algorithm.compare("hamming") == 0)
+ filter=HammingFilter;
+ else if (algorithm.compare("blackman") == 0)
+ filter=BlackmanFilter;
+ else if (algorithm.compare("gaussian") == 0)
+ filter=GaussianFilter;
+ else if (algorithm.compare("quadratic") == 0)
+ filter=QuadraticFilter;
+ else if (algorithm.compare("cubic") == 0)
+ filter=CubicFilter;
+ else if (algorithm.compare("catrom") == 0)
+ filter=CatromFilter;
+ else if (algorithm.compare("mitchell") == 0)
+ filter=MitchellFilter;
+ else if (algorithm.compare("lanczos") == 0)
+ filter=LanczosFilter;
+ else if (algorithm.compare("bessel") == 0)
+ filter=BesselFilter;
+ else if (algorithm.compare("sinc") == 0)
+ filter=SincFilter;
+ else if (algorithm.compare("sample") == 0)
+ resize_algorithm=Sample;
+ else if (algorithm.compare("scale") == 0)
+ resize_algorithm=Scale;
+ else
+ ParseError(argv_index,argv);
+ argv_index++;
+ continue;
+ }
+ else if (command.compare("-geometry") == 0)
+ {
+ argv_index++;
+ try {
+ geometry=Geometry(argv[argv_index]);
+ }
+ catch( exception &/* error_ */)
+ {
+ ParseError(argv_index,argv);
+ }
+ argv_index++;
+ continue;
+ }
+ else if (command.compare("-resample") == 0)
+ {
+ argv_index++;
+ try {
+ resample=Geometry(argv[argv_index]);
+ }
+ catch( exception &/* error_ */)
+ {
+ ParseError(argv_index,argv);
+ }
+ argv_index++;
+ continue;
+ }
+ ParseError(argv_index,argv);
+ }
+
+ if (argv_index>argc-1)
+ ParseError(argv_index,argv);
+ std::string input_file(argv[argv_index]);
+ argv_index++;
+ if (argv_index>argc)
+ ParseError(argv_index,argv);
+ std::string output_file(argv[argv_index]);
+
+ try {
+ Image image(input_file);
+ if (density.isValid())
+ image.density(density);
+ density=image.density();
+
+ if (resample.isValid())
+ {
+ geometry =
+ Geometry(static_cast<unsigned int>
+ (image.columns()*((double)resample.width()/density.width())+0.5),
+ static_cast<unsigned int>
+ (image.rows()*((double)resample.height()/density.height())+0.5));
+ image.density(resample);
+ }
+ switch (resize_algorithm)
+ {
+ case Sample:
+ image.sample(geometry);
+ break;
+ case Scale:
+ image.scale(geometry);
+ break;
+ case Zoom:
+ image.filterType(filter);
+ image.zoom(geometry);
+ break;
+ }
+ image.write(output_file);
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/Magick++/lib/Blob.cpp b/Magick++/lib/Blob.cpp
new file mode 100644
index 0000000..81f9534
--- /dev/null
+++ b/Magick++/lib/Blob.cpp
@@ -0,0 +1,169 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2004
+//
+// Implementation of Blob
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include "Magick++/Blob.h"
+#include "Magick++/BlobRef.h"
+
+#include <string.h>
+
+//
+// Implementation of Magick::Blob
+//
+
+// Default constructor
+Magick::Blob::Blob ( void )
+ : _blobRef(new Magick::BlobRef( 0, 0 ))
+{
+}
+
+// Construct with data
+Magick::Blob::Blob ( const void* data_, size_t length_ )
+ : _blobRef(new Magick::BlobRef( data_, length_ ))
+{
+}
+
+// Copy constructor (reference counted)
+Magick::Blob::Blob ( const Magick::Blob& blob_ )
+ : _blobRef(blob_._blobRef)
+{
+ // Increase reference count
+ Lock lock( &_blobRef->_mutexLock );
+ ++_blobRef->_refCount;
+}
+
+// Destructor (reference counted)
+Magick::Blob::~Blob ()
+{
+ bool doDelete = false;
+ {
+ Lock lock( &_blobRef->_mutexLock );
+ if ( --_blobRef->_refCount == 0 )
+ doDelete = true;
+ }
+
+ if ( doDelete )
+ {
+ // Delete old blob reference with associated data
+ delete _blobRef;
+ }
+ _blobRef=0;
+}
+
+// Assignment operator (reference counted)
+Magick::Blob& Magick::Blob::operator= ( const Magick::Blob& blob_ )
+{
+ if(this != &blob_)
+ {
+ {
+ Lock lock( &blob_._blobRef->_mutexLock );
+ ++blob_._blobRef->_refCount;
+ }
+ bool doDelete = false;
+ {
+ Lock lock( &_blobRef->_mutexLock );
+ if ( --_blobRef->_refCount == 0 )
+ doDelete = true;
+ }
+ if ( doDelete )
+ {
+ delete _blobRef;
+ }
+ _blobRef = blob_._blobRef;
+ }
+ return *this;
+}
+
+// Update object contents from Base64-encoded string representation.
+void Magick::Blob::base64 ( const std::string base64_ )
+{
+ size_t length;
+
+ unsigned char *decoded =
+ Base64Decode( base64_.c_str(), &length );
+
+ if(decoded)
+ updateNoCopy( static_cast<void*>(decoded), length,
+ Magick::Blob::MallocAllocator );
+}
+
+// Return Base64-encoded string representation.
+std::string Magick::Blob::base64 ( void )
+{
+ size_t encoded_length = 0;
+
+ char *encoded =
+ Base64Encode(static_cast<const unsigned char*>(data()), length(), &encoded_length);
+
+ if(encoded)
+ {
+ std::string result(encoded,encoded_length);
+ MagickFreeMemory(encoded);
+ return result;
+ }
+
+ return std::string();
+}
+
+// Update object contents, making a copy of the supplied data.
+// Any existing data in the object is deallocated.
+void Magick::Blob::update ( const void* data_, size_t length_ )
+{
+ bool doDelete = false;
+ {
+ Lock lock( &_blobRef->_mutexLock );
+ if ( --_blobRef->_refCount == 0 )
+ doDelete = true;
+ }
+ if ( doDelete )
+ {
+ // Delete old blob reference with associated data
+ delete _blobRef;
+ }
+
+ _blobRef = new Magick::BlobRef( data_, length_ );
+}
+
+// Update object contents, using supplied pointer directly (no copy)
+// Any existing data in the object is deallocated. The user must
+// ensure that the pointer supplied is not deleted or otherwise
+// modified after it has been supplied to this method.
+void Magick::Blob::updateNoCopy ( void* data_, size_t length_,
+ Magick::Blob::Allocator allocator_ )
+{
+ bool doDelete = false;
+ {
+ Lock lock( &_blobRef->_mutexLock );
+ if ( --_blobRef->_refCount == 0 )
+ doDelete = true;
+ }
+ if ( doDelete )
+ {
+ // Delete old blob reference with associated data
+ delete _blobRef;
+ }
+ _blobRef = new Magick::BlobRef( 0, 0 );
+ _blobRef->_data = data_;
+ _blobRef->_length = length_;
+ _blobRef->_allocator = allocator_;
+}
+
+// Obtain pointer to data
+const void* Magick::Blob::data( void ) const
+{
+ return _blobRef->_data;
+}
+
+// Obtain data length
+size_t Magick::Blob::length( void ) const
+{
+ return _blobRef->_length;
+}
+
diff --git a/Magick++/lib/BlobRef.cpp b/Magick++/lib/BlobRef.cpp
new file mode 100644
index 0000000..7eb90d8
--- /dev/null
+++ b/Magick++/lib/BlobRef.cpp
@@ -0,0 +1,49 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2004
+//
+// Implementation of Blob
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include "Magick++/Thread.h"
+#include "Magick++/BlobRef.h"
+
+#include <string.h>
+
+//
+// Implementation of Magick::BlobRef
+//
+
+// Construct with data, making private copy of data
+Magick::BlobRef::BlobRef ( const void* data_,
+ size_t length_ )
+ : _data(0),
+ _length(length_),
+ _allocator(Magick::Blob::NewAllocator),
+ _refCount(1),
+ _mutexLock()
+{
+ if( data_ )
+ {
+ _data = new unsigned char[length_];
+ memcpy( _data, data_, length_ );
+ }
+}
+
+// Destructor (actually destroys data)
+Magick::BlobRef::~BlobRef ( void )
+{
+ if ( _allocator == Magick::Blob::NewAllocator )
+ {
+ delete [] static_cast<unsigned char*>(_data);
+ _data=0;
+ }
+ else if ( _allocator == Magick::Blob::MallocAllocator )
+ {
+ MagickFreeMemory(_data);
+ }
+}
diff --git a/Magick++/lib/CoderInfo.cpp b/Magick++/lib/CoderInfo.cpp
new file mode 100644
index 0000000..0986c07
--- /dev/null
+++ b/Magick++/lib/CoderInfo.cpp
@@ -0,0 +1,121 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 2001-2010
+//
+// CoderInfo implementation
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include "Magick++/CoderInfo.h"
+#include "Magick++/Exception.h"
+
+using namespace std;
+
+// Default constructor
+Magick::CoderInfo::CoderInfo ( void )
+ : _name(),
+ _description(),
+ _isReadable(false),
+ _isWritable(false),
+ _isMultiFrame(false)
+{
+}
+
+// Copy constructor
+Magick::CoderInfo::CoderInfo ( const Magick::CoderInfo &coder_ )
+{
+ _name = coder_._name;
+ _description = coder_._description;
+ _isReadable = coder_._isReadable;
+ _isWritable = coder_._isWritable;
+ _isMultiFrame = coder_._isMultiFrame;
+}
+
+Magick::CoderInfo::CoderInfo ( const std::string &name_ )
+ : _name(),
+ _description(),
+ _isReadable(false),
+ _isWritable(false),
+ _isMultiFrame(false)
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ const Magick::MagickInfo *magickInfo = GetMagickInfo( name_.c_str(), &exceptionInfo );
+ throwException( exceptionInfo );
+ if( magickInfo == 0 )
+ {
+ throwExceptionExplicit(OptionError, "Coder not found", name_.c_str() );
+ }
+ else
+ {
+ _name = string(magickInfo->name);
+ _description = string(magickInfo->description);
+ _isReadable = ((magickInfo->decoder == 0) ? false : true);
+ _isWritable = ((magickInfo->encoder == 0) ? false : true);
+ _isMultiFrame = ((magickInfo->adjoin == 0) ? false : true);
+ }
+}
+
+Magick::CoderInfo::~CoderInfo ( void )
+{
+ // Nothing to do
+}
+
+// Format name
+std::string Magick::CoderInfo::name( void ) const
+{
+ return _name;
+}
+
+// Format description
+std::string Magick::CoderInfo::description( void ) const
+{
+ return _description;
+}
+
+// Format is readable
+bool Magick::CoderInfo::isReadable( void ) const
+{
+ return _isReadable;
+}
+
+// Format is writeable
+bool Magick::CoderInfo::isWritable( void ) const
+{
+ return _isWritable;
+}
+
+// Format supports multiple frames
+bool Magick::CoderInfo::isMultiFrame( void ) const
+{
+ return _isMultiFrame;
+}
+
+// Assignment operator
+Magick::CoderInfo& Magick::CoderInfo::operator= (const Magick::CoderInfo &coder_ )
+{
+ // If not being set to ourself
+ if (this != &coder_)
+ {
+ _name = coder_._name;
+ _description = coder_._description;
+ _isReadable = coder_._isReadable;
+ _isWritable = coder_._isWritable;
+ _isMultiFrame = coder_._isMultiFrame;
+ }
+ return *this;
+}
+
+// Construct from MagickLib::MagickInfo*
+Magick::CoderInfo::CoderInfo ( const MagickLib::MagickInfo *magickInfo_ )
+ : _name(string(magickInfo_->name ? magickInfo_->name : "")),
+ _description(string(magickInfo_->description ? magickInfo_->description : "")),
+ _isReadable(magickInfo_->decoder ? true : false),
+ _isWritable(magickInfo_->encoder ? true : false),
+ _isMultiFrame(magickInfo_->adjoin ? true : false)
+{
+ // Nothing more to do
+}
diff --git a/Magick++/lib/Color.cpp b/Magick++/lib/Color.cpp
new file mode 100644
index 0000000..591cbe2
--- /dev/null
+++ b/Magick++/lib/Color.cpp
@@ -0,0 +1,698 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003, 2008
+//
+// Color Implementation
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <string>
+
+using namespace std;
+
+#include "Magick++/Color.h"
+#include "Magick++/Exception.h"
+
+//
+// Color operator fuctions
+//
+int Magick::operator == ( const Magick::Color& left_,
+ const Magick::Color& right_ )
+{
+ return ( ( left_.isValid() == right_.isValid() ) &&
+ ( left_.redQuantum() == right_.redQuantum() ) &&
+ ( left_.greenQuantum() == right_.greenQuantum() ) &&
+ ( left_.blueQuantum() == right_.blueQuantum() )
+ );
+}
+int Magick::operator != ( const Magick::Color& left_,
+ const Magick::Color& right_ )
+{
+ return ( ! (left_ == right_) );
+}
+int Magick::operator > ( const Magick::Color& left_,
+ const Magick::Color& right_ )
+{
+ return ( !( left_ < right_ ) && ( left_ != right_ ) );
+}
+// Compare color intensities (similar to ImageMagick Intensity macro)
+// If intensities match, discriminate based on priority green, red,
+// & then blue.
+int Magick::operator < ( const Magick::Color& left_,
+ const Magick::Color& right_ )
+{
+ double left_intensity=left_.intensity();
+ double right_intensity=right_.intensity();
+ return (
+ (left_intensity < right_intensity)
+ || (
+ (left_intensity == right_intensity)
+ && (
+ (left_.greenQuantum() < right_.greenQuantum()) ||
+ (left_.redQuantum() < right_.redQuantum()) ||
+ (left_.blueQuantum() < right_.blueQuantum())
+ )
+ )
+ );
+}
+int Magick::operator >= ( const Magick::Color& left_,
+ const Magick::Color& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+int Magick::operator <= ( const Magick::Color& left_,
+ const Magick::Color& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+
+//
+// Color Implementation
+//
+
+// Default constructor
+Magick::Color::Color ( void )
+ : _pixel(new PixelPacket),
+ _pixelOwn(true),
+ _isValid(false),
+ _pixelType(RGBPixel)
+{
+ initPixel();
+}
+
+// Construct from RGB
+Magick::Color::Color ( Quantum red_,
+ Quantum green_,
+ Quantum blue_ )
+ : _pixel(new PixelPacket),
+ _pixelOwn(true),
+ _isValid(true),
+ _pixelType(RGBPixel)
+{
+ redQuantum ( red_ );
+ greenQuantum ( green_ );
+ blueQuantum ( blue_ );
+ alphaQuantum ( OpaqueOpacity );
+}
+
+// Construct from RGBA
+Magick::Color::Color ( Quantum red_,
+ Quantum green_,
+ Quantum blue_,
+ Quantum alpha_ )
+ : _pixel(new PixelPacket),
+ _pixelOwn(true),
+ _isValid(true),
+ _pixelType(RGBAPixel)
+{
+ redQuantum ( red_ );
+ greenQuantum ( green_ );
+ blueQuantum ( blue_ );
+ alphaQuantum ( alpha_ );
+}
+
+// Copy constructor
+Magick::Color::Color ( const Magick::Color & color_ )
+ : _pixel( new PixelPacket ),
+ _pixelOwn( true ),
+ _isValid( color_._isValid ),
+ _pixelType( color_._pixelType )
+{
+ *_pixel = *color_._pixel;
+}
+
+// Construct from color expressed as C++ string
+Magick::Color::Color ( const std::string &x11color_ )
+ : _pixel(new PixelPacket),
+ _pixelOwn(true),
+ _isValid(true),
+ _pixelType(RGBPixel)
+{
+ initPixel();
+
+ // Use operator = implementation
+ *this = x11color_;
+}
+
+// Construct from color expressed as C string
+Magick::Color::Color ( const char * x11color_ )
+ : _pixel(new PixelPacket),
+ _pixelOwn(true),
+ _isValid(true),
+ _pixelType(RGBPixel)
+{
+ initPixel();
+
+ // Use operator = implementation
+ *this = x11color_;
+}
+
+// Construct color via ImageMagick PixelPacket
+Magick::Color::Color ( const PixelPacket &color_ )
+ : _pixel(new PixelPacket),
+ _pixelOwn(true), // We allocated this pixel
+ _isValid(true),
+ _pixelType(RGBPixel) // RGB pixel by default
+{
+ *_pixel = color_;
+
+ if ( color_.opacity != OpaqueOpacity )
+ _pixelType = RGBAPixel;
+}
+
+// Protected constructor to construct with PixelPacket*
+// Used to point Color at a pixel.
+Magick::Color::Color ( PixelPacket* rep_, PixelType pixelType_ )
+ : _pixel(rep_),
+ _pixelOwn(false),
+ _isValid(true),
+ _pixelType(pixelType_)
+{
+}
+
+// Destructor
+Magick::Color::~Color( void )
+{
+ if ( _pixelOwn )
+ delete _pixel;
+ _pixel=0;
+}
+
+// Assignment operator
+Magick::Color& Magick::Color::operator = ( const Magick::Color& color_ )
+{
+ // If not being set to ourself
+ if ( this != &color_ )
+ {
+ // Copy pixel value
+ *_pixel = *color_._pixel;
+
+ // Validity
+ _isValid = color_._isValid;
+
+ // Copy pixel type
+ _pixelType = color_._pixelType;
+ }
+ return *this;
+}
+
+// Set color via X11 color specification string
+const Magick::Color& Magick::Color::operator = ( const std::string &x11color_ )
+{
+ initPixel();
+ PixelPacket target_color;
+ ExceptionInfo exception;
+ GetExceptionInfo( &exception );
+ if ( QueryColorDatabase( x11color_.c_str(), &target_color, &exception ) )
+ {
+ redQuantum( target_color.red );
+ greenQuantum( target_color.green );
+ blueQuantum( target_color.blue );
+ alphaQuantum( target_color.opacity );
+
+ if ( target_color.opacity > OpaqueOpacity )
+ _pixelType = RGBAPixel;
+ else
+ _pixelType = RGBPixel;
+ }
+ else
+ {
+ _isValid = false;
+ throwException(exception);
+ }
+ DestroyExceptionInfo( &exception );
+
+ return *this;
+}
+
+// Set color via X11 color specification C string
+const Magick::Color& Magick::Color::operator = ( const char * x11color_ )
+{
+ *this = std::string(x11color_);
+ return *this;
+}
+
+// Return X11 color specification string
+Magick::Color::operator std::string() const
+{
+ if ( !isValid() )
+ return std::string("none");
+
+ char colorbuf[MaxTextExtent];
+
+ if ( _pixelType == RGBAPixel )
+ GetColorTuple( _pixel, QuantumDepth, true, true, colorbuf );
+ else
+ GetColorTuple( _pixel, QuantumDepth, false, true, colorbuf );
+
+ return std::string(colorbuf);
+}
+
+// Set color via ImageMagick PixelPacket
+const Magick::Color& Magick::Color::operator= ( const MagickLib::PixelPacket &color_ )
+{
+ *_pixel = color_;
+ if ( color_.opacity != OpaqueOpacity )
+ _pixelType = RGBAPixel;
+ else
+ _pixelType = RGBPixel;
+ return *this;
+}
+
+// Set pixel
+// Used to point Color at a pixel in an image
+void Magick::Color::pixel ( PixelPacket* rep_, PixelType pixelType_ )
+{
+ if ( _pixelOwn )
+ delete _pixel;
+ _pixel = rep_;
+ _pixelOwn = false;
+ _isValid = true;
+ _pixelType = pixelType_;
+}
+
+// Does object contain valid color?
+bool Magick::Color::isValid ( void ) const
+{
+ return( _isValid );
+}
+void Magick::Color::isValid ( bool valid_ )
+{
+ if ( (valid_ && isValid()) || (!valid_ && !isValid()) )
+ return;
+
+ if ( !_pixelOwn )
+ {
+ _pixel = new PixelPacket;
+ _pixelOwn = true;
+ }
+
+ _isValid=valid_;
+
+ initPixel();
+}
+
+//
+// ColorHSL Implementation
+//
+
+Magick::ColorHSL::ColorHSL ( double hue_,
+ double saturation_,
+ double luminosity_ )
+ : Color ()
+{
+ Quantum red, green, blue;
+
+ HSLTransform ( hue_,
+ saturation_,
+ luminosity_,
+ &red,
+ &green,
+ &blue );
+
+ redQuantum ( red );
+ greenQuantum ( green );
+ blueQuantum ( blue );
+ alphaQuantum ( OpaqueOpacity );
+}
+
+// Null constructor
+Magick::ColorHSL::ColorHSL ( )
+ : Color ()
+{
+}
+
+// Copy constructor from base class
+Magick::ColorHSL::ColorHSL ( const Magick::Color & color_ )
+ : Color( color_ )
+{
+}
+
+// Destructor
+Magick::ColorHSL::~ColorHSL ( )
+{
+ // Nothing to do
+}
+
+void Magick::ColorHSL::hue ( double hue_ )
+{
+ double hue_val, saturation_val, luminosity_val;
+ TransformHSL ( redQuantum(),
+ greenQuantum(),
+ blueQuantum(),
+ &hue_val,
+ &saturation_val,
+ &luminosity_val );
+
+ hue_val = hue_;
+
+ Quantum red, green, blue;
+ HSLTransform ( hue_val,
+ saturation_val,
+ luminosity_val,
+ &red,
+ &green,
+ &blue
+ );
+
+ redQuantum ( red );
+ greenQuantum ( green );
+ blueQuantum ( blue );
+}
+
+double Magick::ColorHSL::hue ( void ) const
+{
+ double hue_val, saturation_val, luminosity_val;
+ TransformHSL ( redQuantum(),
+ greenQuantum(),
+ blueQuantum(),
+ &hue_val,
+ &saturation_val,
+ &luminosity_val );
+ return hue_val;
+}
+
+void Magick::ColorHSL::saturation ( double saturation_ )
+{
+ double hue_val, saturation_val, luminosity_val;
+ TransformHSL ( redQuantum(),
+ greenQuantum(),
+ blueQuantum(),
+ &hue_val,
+ &saturation_val,
+ &luminosity_val );
+
+ saturation_val = saturation_;
+
+ Quantum red, green, blue;
+ HSLTransform ( hue_val,
+ saturation_val,
+ luminosity_val,
+ &red,
+ &green,
+ &blue
+ );
+
+ redQuantum ( red );
+ greenQuantum ( green );
+ blueQuantum ( blue );
+}
+
+double Magick::ColorHSL::saturation ( void ) const
+{
+ double hue_val, saturation_val, luminosity_val;
+ TransformHSL ( redQuantum(),
+ greenQuantum(),
+ blueQuantum(),
+ &hue_val,
+ &saturation_val,
+ &luminosity_val );
+ return saturation_val;
+}
+
+void Magick::ColorHSL::luminosity ( double luminosity_ )
+{
+ double hue_val, saturation_val, luminosity_val;
+ TransformHSL ( redQuantum(),
+ greenQuantum(),
+ blueQuantum(),
+ &hue_val,
+ &saturation_val,
+ &luminosity_val );
+
+ luminosity_val = luminosity_;
+
+ Quantum red, green, blue;
+ HSLTransform ( hue_val,
+ saturation_val,
+ luminosity_val,
+ &red,
+ &green,
+ &blue
+ );
+
+ redQuantum ( red );
+ greenQuantum ( green );
+ blueQuantum ( blue );
+}
+
+double Magick::ColorHSL::luminosity ( void ) const
+{
+ double hue_val, saturation_val, luminosity_val;
+ TransformHSL ( redQuantum(),
+ greenQuantum(),
+ blueQuantum(),
+ &hue_val,
+ &saturation_val,
+ &luminosity_val );
+ return luminosity_val;
+}
+
+// Assignment from base class
+Magick::ColorHSL& Magick::ColorHSL::operator = ( const Magick::Color& color_ )
+{
+ *static_cast<Magick::Color*>(this) = color_;
+ return *this;
+}
+
+//
+// ColorGray Implementation
+//
+Magick::ColorGray::ColorGray ( double shade_ )
+ : Color ( scaleDoubleToQuantum( shade_ ),
+ scaleDoubleToQuantum( shade_ ),
+ scaleDoubleToQuantum( shade_ ) )
+{
+ alphaQuantum ( OpaqueOpacity );
+}
+
+// Null constructor
+Magick::ColorGray::ColorGray ( void )
+ : Color ()
+{
+}
+
+// Copy constructor from base class
+Magick::ColorGray::ColorGray ( const Magick::Color & color_ )
+ : Color( color_ )
+{
+}
+
+// Destructor
+Magick::ColorGray::~ColorGray ()
+{
+ // Nothing to do
+}
+
+void Magick::ColorGray::shade ( double shade_ )
+{
+ Quantum gray = scaleDoubleToQuantum( shade_ );
+ redQuantum ( gray );
+ greenQuantum ( gray );
+ blueQuantum ( gray );
+}
+
+double Magick::ColorGray::shade ( void ) const
+{
+ return scaleQuantumToDouble ( greenQuantum() );
+}
+
+// Assignment from base class
+Magick::ColorGray& Magick::ColorGray::operator = ( const Magick::Color& color_ )
+{
+ *static_cast<Magick::Color*>(this) = color_;
+ return *this;
+}
+
+//
+// ColorMono Implementation
+//
+Magick::ColorMono::ColorMono ( bool mono_ )
+ : Color ( ( mono_ ? MaxRGB : 0 ),
+ ( mono_ ? MaxRGB : 0 ),
+ ( mono_ ? MaxRGB : 0 ) )
+{
+ alphaQuantum ( OpaqueOpacity );
+}
+
+// Null constructor
+Magick::ColorMono::ColorMono ( void )
+ : Color ()
+{
+}
+
+// Copy constructor from base class
+Magick::ColorMono::ColorMono ( const Magick::Color & color_ )
+ : Color( color_ )
+{
+}
+
+// Destructor
+Magick::ColorMono::~ColorMono ()
+{
+ // Nothing to do
+}
+
+void Magick::ColorMono::mono ( bool mono_ )
+{
+ redQuantum ( mono_ ? MaxRGB : 0 );
+ greenQuantum ( mono_ ? MaxRGB : 0 );
+ blueQuantum ( mono_ ? MaxRGB : 0 );
+}
+
+bool Magick::ColorMono::mono ( void ) const
+{
+ if ( greenQuantum() )
+ return true;
+ else
+ return false;
+}
+
+// Assignment from base class
+Magick::ColorMono& Magick::ColorMono::operator = ( const Magick::Color& color_ )
+{
+ *static_cast<Magick::Color*>(this) = color_;
+ return *this;
+}
+
+//
+// ColorRGB Implementation
+//
+
+// Construct from red, green, and blue, components
+Magick::ColorRGB::ColorRGB ( double red_,
+ double green_,
+ double blue_ )
+ : Color ( scaleDoubleToQuantum(red_),
+ scaleDoubleToQuantum(green_),
+ scaleDoubleToQuantum(blue_) )
+{
+ alphaQuantum ( OpaqueOpacity );
+}
+// Null constructor
+Magick::ColorRGB::ColorRGB ( void )
+ : Color ()
+{
+}
+// Copy constructor from base class
+Magick::ColorRGB::ColorRGB ( const Magick::Color & color_ )
+ : Color( color_ )
+{
+}
+// Destructor
+Magick::ColorRGB::~ColorRGB ( void )
+{
+ // Nothing to do
+}
+
+// Assignment from base class
+Magick::ColorRGB& Magick::ColorRGB::operator = ( const Magick::Color& color_ )
+{
+ *static_cast<Magick::Color*>(this) = color_;
+ return *this;
+}
+
+//
+// ColorYUV Implementation
+//
+
+// R = Y +1.13980*V
+// G = Y-0.39380*U-0.58050*V
+// B = Y+2.02790*U
+//
+// U and V, normally -0.5 through 0.5, must be normalized to the range 0
+// through MaxRGB.
+//
+// Y = 0.29900*R+0.58700*G+0.11400*B
+// U = -0.14740*R-0.28950*G+0.43690*B
+// V = 0.61500*R-0.51500*G-0.10000*B
+//
+// U and V, normally -0.5 through 0.5, are normalized to the range 0
+// through MaxRGB. Note that U = 0.493*(B-Y), V = 0.877*(R-Y).
+//
+
+// Construct from color components
+Magick::ColorYUV::ColorYUV ( double y_,
+ double u_,
+ double v_ )
+ : Color ( scaleDoubleToQuantum(y_ + 1.13980 * v_ ),
+ scaleDoubleToQuantum(y_ - (0.39380 * u_) - (0.58050 * v_) ),
+ scaleDoubleToQuantum(y_ + 2.02790 * u_ ) )
+{
+ alphaQuantum ( OpaqueOpacity );
+}
+// Null constructor
+Magick::ColorYUV::ColorYUV ( void )
+ : Color ()
+{
+}
+// Copy constructor from base class
+Magick::ColorYUV::ColorYUV ( const Magick::Color & color_ )
+ : Color( color_ )
+{
+}
+// Destructor
+Magick::ColorYUV::~ColorYUV ( void )
+{
+ // Nothing to do
+}
+
+void Magick::ColorYUV::u ( double u_ )
+{
+ double V = v();
+ double Y = y();
+
+ redQuantum ( scaleDoubleToQuantum( Y + 1.13980 * V ) );
+ greenQuantum ( scaleDoubleToQuantum( Y - (0.39380 * u_) - (0.58050 * V) ) );
+ blueQuantum ( scaleDoubleToQuantum( Y + 2.02790 * u_ ) );
+}
+
+double Magick::ColorYUV::u ( void ) const
+{
+ return scaleQuantumToDouble( (-0.14740 * redQuantum()) - (0.28950 *
+ greenQuantum()) + (0.43690 * blueQuantum()) );
+}
+
+void Magick::ColorYUV::v ( double v_ )
+{
+ double U = u();
+ double Y = y();
+
+ redQuantum ( scaleDoubleToQuantum( Y + 1.13980 * v_ ) );
+ greenQuantum ( scaleDoubleToQuantum( Y - (0.39380 * U) - (0.58050 * v_) ) );
+ blueQuantum ( scaleDoubleToQuantum( Y + 2.02790 * U ) );
+}
+
+double Magick::ColorYUV::v ( void ) const
+{
+ return scaleQuantumToDouble((0.61500 * redQuantum()) -
+ (0.51500 * greenQuantum()) -
+ (0.10000 * blueQuantum()));
+}
+
+void Magick::ColorYUV::y ( double y_ )
+{
+ double U = u();
+ double V = v();
+
+ redQuantum ( scaleDoubleToQuantum( y_ + 1.13980 * V ) );
+ greenQuantum ( scaleDoubleToQuantum( y_ - (0.39380 * U) - (0.58050 * V) ) );
+ blueQuantum ( scaleDoubleToQuantum( y_ + 2.02790 * U ) );
+}
+
+double Magick::ColorYUV::y ( void ) const
+{
+ return scaleQuantumToDouble((0.29900 * redQuantum()) +
+ (0.58700 * greenQuantum()) +
+ (0.11400 * blueQuantum()));
+}
+
+// Assignment from base class
+Magick::ColorYUV& Magick::ColorYUV::operator = ( const Magick::Color& color_ )
+{
+ *static_cast<Magick::Color*>(this) = color_;
+ return *this;
+}
diff --git a/Magick++/lib/Drawable.cpp b/Magick++/lib/Drawable.cpp
new file mode 100644
index 0000000..c760823
--- /dev/null
+++ b/Magick++/lib/Drawable.cpp
@@ -0,0 +1,2146 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999 - 2016
+//
+// Implementation of Drawable (Graphic objects)
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+#define MAGICK_DRAWABLE_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <math.h>
+#include <string>
+
+#include "Magick++/Drawable.h"
+#include "Magick++/Image.h"
+
+using namespace std;
+
+MagickDLLDecl int Magick::operator == ( const Magick::Coordinate& left_,
+ const Magick::Coordinate& right_ )
+{
+ return ( ( left_.x() == right_.x() ) && ( left_.y() == right_.y() ) );
+}
+MagickDLLDecl int Magick::operator != ( const Magick::Coordinate& left_,
+ const Magick::Coordinate& right_ )
+{
+ return ( ! (left_ == right_) );
+}
+MagickDLLDecl int Magick::operator > ( const Magick::Coordinate& left_,
+ const Magick::Coordinate& right_ )
+{
+ return ( !( left_ < right_ ) && ( left_ != right_ ) );
+}
+MagickDLLDecl int Magick::operator < ( const Magick::Coordinate& left_,
+ const Magick::Coordinate& right_ )
+{
+ // Based on distance from origin
+ return ( (sqrt(left_.x()*left_.x() + left_.y()*left_.y())) <
+ (sqrt(right_.x()*right_.x() + right_.y()*right_.y())) );
+}
+MagickDLLDecl int Magick::operator >= ( const Magick::Coordinate& left_,
+ const Magick::Coordinate& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+MagickDLLDecl int Magick::operator <= ( const Magick::Coordinate& left_,
+ const Magick::Coordinate& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+
+/*virtual*/
+Magick::DrawableBase::~DrawableBase ( void )
+{
+}
+
+// Constructor
+Magick::Drawable::Drawable ( void )
+ : dp(0)
+{
+}
+
+// Construct from DrawableBase
+Magick::Drawable::Drawable ( const Magick::DrawableBase& original_ )
+ : dp(original_.copy())
+{
+}
+
+// Destructor
+Magick::Drawable::~Drawable ( void )
+{
+ delete dp;
+ dp = 0;
+}
+
+// Copy constructor
+Magick::Drawable::Drawable ( const Magick::Drawable& original_ )
+ : dp(original_.dp? original_.dp->copy(): 0)
+{
+}
+
+// Assignment operator
+Magick::Drawable& Magick::Drawable::operator= (const Magick::Drawable& original_ )
+{
+ if (this != &original_)
+ {
+ DrawableBase* temp_dp = (original_.dp ? original_.dp->copy() : 0);
+ delete dp;
+ dp = temp_dp;
+ }
+ return *this;
+}
+
+// Operator to invoke contained object
+void Magick::Drawable::operator()( MagickLib::DrawContext context_ ) const
+{
+ if(dp)
+ dp->operator()( context_ );
+}
+
+MagickDLLDecl int Magick::operator == ( const Magick::Drawable& /*left_*/,
+ const Magick::Drawable& /*right_*/ )
+{
+ return ( 1 );
+}
+MagickDLLDecl int Magick::operator != ( const Magick::Drawable& /*left_*/,
+ const Magick::Drawable& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator > ( const Magick::Drawable& /*left_*/,
+ const Magick::Drawable& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator < ( const Magick::Drawable& /*left_*/,
+ const Magick::Drawable& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator >= ( const Magick::Drawable& left_,
+ const Magick::Drawable& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+MagickDLLDecl int Magick::operator <= ( const Magick::Drawable& left_,
+ const Magick::Drawable& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+
+/*virtual*/
+Magick::VPathBase::~VPathBase ( void )
+{
+}
+
+// Constructor
+Magick::VPath::VPath ( void )
+ : dp(0)
+{
+}
+
+// Construct from VPathBase
+Magick::VPath::VPath ( const Magick::VPathBase& original_ )
+ : dp(original_.copy())
+{
+}
+
+// Destructor
+/* virtual */ Magick::VPath::~VPath ( void )
+{
+ delete dp;
+ dp = 0;
+}
+
+// Copy constructor
+Magick::VPath::VPath ( const Magick::VPath& original_ )
+ : dp(original_.dp? original_.dp->copy(): 0)
+{
+}
+
+// Assignment operator
+Magick::VPath& Magick::VPath::operator= (const Magick::VPath& original_ )
+{
+ if (this != &original_)
+ {
+ VPathBase* temp_dp = (original_.dp ? original_.dp->copy() : 0);
+ delete dp;
+ dp = temp_dp;
+ }
+ return *this;
+}
+
+// Operator to invoke contained object
+void Magick::VPath::operator()( MagickLib::DrawContext context_ ) const
+{
+ if(dp)
+ dp->operator()( context_ );
+}
+
+MagickDLLDecl int Magick::operator == ( const Magick::VPath& /*left_*/,
+ const Magick::VPath& /*right_*/ )
+{
+ return ( 1 );
+}
+MagickDLLDecl int Magick::operator != ( const Magick::VPath& /*left_*/,
+ const Magick::VPath& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator > ( const Magick::VPath& /*left_*/,
+ const Magick::VPath& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator < ( const Magick::VPath& /*left_*/,
+ const Magick::VPath& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator >= ( const Magick::VPath& left_,
+ const Magick::VPath& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+MagickDLLDecl int Magick::operator <= ( const Magick::VPath& left_,
+ const Magick::VPath& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+
+//
+// Drawable Objects
+//
+
+// Affine (scaling, rotation, and translation)
+Magick::DrawableAffine::DrawableAffine( double sx_, double sy_,
+ double rx_, double ry_,
+ double tx_, double ty_ )
+{
+ _affine.sx = sx_;
+ _affine.rx = rx_;
+ _affine.ry = ry_;
+ _affine.sy = sy_;
+ _affine.tx = tx_;
+ _affine.ty = ty_;
+}
+Magick::DrawableAffine::DrawableAffine( void )
+{
+ IdentityAffine(&_affine);
+}
+Magick::DrawableAffine::~DrawableAffine( void )
+{
+}
+void Magick::DrawableAffine::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawAffine( context_, &_affine );
+}
+Magick::DrawableBase* Magick::DrawableAffine::copy() const
+{
+ return new DrawableAffine(*this);
+}
+
+// Arc
+Magick::DrawableArc::~DrawableArc( void )
+{
+}
+void Magick::DrawableArc::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawArc( context_, _startX, _startY, _endX, _endY, _startDegrees, _endDegrees );
+}
+Magick::DrawableBase* Magick::DrawableArc::copy() const
+{
+ return new DrawableArc(*this);
+}
+
+//
+// Bezier curve
+//
+// Construct from coordinates (Coordinate list must contain at least three members)
+Magick::DrawableBezier::DrawableBezier ( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+// Copy constructor
+Magick::DrawableBezier::DrawableBezier( const Magick::DrawableBezier& original_ )
+ : DrawableBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+// Destructor
+Magick::DrawableBezier::~DrawableBezier( void )
+{
+}
+void Magick::DrawableBezier::operator()( MagickLib::DrawContext context_ ) const
+{
+ size_t num_coords = _coordinates.size();
+ PointInfo *coordinates = new PointInfo[num_coords];
+
+ PointInfo *q = coordinates;
+ CoordinateList::const_iterator p = _coordinates.begin();
+
+ while( p != _coordinates.end() )
+ {
+ q->x = p->x();
+ q->y = p->y();
+ q++;
+ p++;
+ }
+
+ DrawBezier( context_, (const unsigned long) num_coords, coordinates );
+ delete [] coordinates;
+}
+Magick::DrawableBase* Magick::DrawableBezier::copy() const
+{
+ return new DrawableBezier(*this);
+}
+
+//
+//Clip Path
+//
+
+// Pop (terminate) Clip path definition
+Magick::DrawablePopClipPath::~DrawablePopClipPath ( void )
+{
+}
+void Magick::DrawablePopClipPath::operator() ( MagickLib::DrawContext context_ ) const
+{
+ DrawPopClipPath( context_ );
+ DrawPopDefs(context_);
+}
+Magick::DrawableBase* Magick::DrawablePopClipPath::copy() const
+{
+ return new DrawablePopClipPath(*this);
+}
+
+// Push clip path definition
+Magick::DrawablePushClipPath::DrawablePushClipPath( const std::string &id_)
+ : _id(id_.c_str()) //multithread safe const char*
+{
+}
+Magick::DrawablePushClipPath::DrawablePushClipPath
+( const Magick::DrawablePushClipPath& original_ ) //multithread safe const char*
+ : DrawableBase (original_),
+ _id(original_._id.c_str())
+{
+}
+Magick::DrawablePushClipPath::~DrawablePushClipPath( void )
+{
+}
+void Magick::DrawablePushClipPath::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPushDefs(context_);
+ DrawPushClipPath( context_, _id.c_str());
+}
+Magick::DrawableBase* Magick::DrawablePushClipPath::copy() const
+{
+ return new DrawablePushClipPath(*this);
+}
+//
+// ClipPath
+//
+Magick::DrawableClipPath::DrawableClipPath( const std::string &id_ )
+:_id(id_.c_str())
+{
+}
+
+Magick::DrawableClipPath::DrawableClipPath ( const Magick::DrawableClipPath& original_ )
+ : DrawableBase (original_),
+ _id(original_._id.c_str())
+{
+}
+Magick::DrawableClipPath::~DrawableClipPath( void )
+{
+}
+void Magick::DrawableClipPath::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawSetClipPath( context_, _id.c_str());
+}
+Magick::DrawableBase* Magick::DrawableClipPath::copy() const
+{
+ return new DrawableClipPath(*this);
+}
+
+// Circle
+Magick::DrawableCircle::~DrawableCircle ( void )
+{
+}
+void Magick::DrawableCircle::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawCircle( context_, _originX, _originY, _perimX, _perimY );
+}
+Magick::DrawableBase* Magick::DrawableCircle::copy() const
+{
+ return new DrawableCircle(*this);
+}
+
+// Colorize at point using PaintMethod
+Magick::DrawableColor::~DrawableColor( void )
+{
+}
+void Magick::DrawableColor::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawColor( context_, _x, _y, _paintMethod );
+}
+Magick::DrawableBase* Magick::DrawableColor::copy() const
+{
+ return new DrawableColor(*this);
+}
+
+// Draw image at point
+Magick::DrawableCompositeImage::DrawableCompositeImage
+( double x_, double y_,
+ double width_, double height_,
+ const std::string &filename_,
+ Magick::CompositeOperator composition_ )
+ : _composition(composition_),
+ _x(x_),
+ _y(y_),
+ _width(width_),
+ _height(height_),
+ _image(new Image(filename_))
+{
+}
+Magick::DrawableCompositeImage::DrawableCompositeImage
+( double x_, double y_,
+ double width_, double height_,
+ const Magick::Image &image_,
+ Magick::CompositeOperator composition_ )
+ : _composition(composition_),
+ _x(x_),
+ _y(y_),
+ _width(width_),
+ _height(height_),
+ _image(new Image(image_))
+{
+}
+Magick::DrawableCompositeImage::DrawableCompositeImage
+( double x_, double y_,
+ double width_, double height_,
+ const std::string &filename_ )
+ :_composition(CopyCompositeOp),
+ _x(x_),
+ _y(y_),
+ _width(width_),
+ _height(height_),
+ _image(new Image(filename_))
+{
+}
+Magick::DrawableCompositeImage::DrawableCompositeImage
+( double x_, double y_,
+ double width_, double height_,
+ const Magick::Image &image_ )
+ :_composition(CopyCompositeOp),
+ _x(x_),
+ _y(y_),
+ _width(width_),
+ _height(height_),
+ _image(new Image(image_))
+{
+}
+Magick::DrawableCompositeImage::DrawableCompositeImage
+( double x_, double y_,
+ const std::string &filename_ )
+ : _composition(CopyCompositeOp),
+ _x(x_),
+ _y(y_),
+ _width(0),
+ _height(0),
+ _image(new Image(filename_))
+{
+ _width=_image->columns();
+ _height=_image->rows();
+}
+Magick::DrawableCompositeImage::DrawableCompositeImage
+( double x_, double y_,
+ const Magick::Image &image_ )
+ : _composition(CopyCompositeOp),
+ _x(x_),
+ _y(y_),
+ _width(0),
+ _height(0),
+ _image(new Image(image_))
+{
+ _width=_image->columns();
+ _height=_image->rows();
+}
+// Copy constructor
+Magick::DrawableCompositeImage::DrawableCompositeImage
+( const Magick::DrawableCompositeImage& original_ )
+ : Magick::DrawableBase(original_),
+ _composition(original_._composition),
+ _x(original_._x),
+ _y(original_._y),
+ _width(original_._width),
+ _height(original_._height),
+ _image(new Image(*original_._image))
+{
+}
+Magick::DrawableCompositeImage::~DrawableCompositeImage( void )
+{
+ delete _image;
+}
+// Assignment operator
+Magick::DrawableCompositeImage& Magick::DrawableCompositeImage::operator=
+(const Magick::DrawableCompositeImage& original_ )
+{
+ // If not being set to ourself
+ if ( this != &original_ )
+ {
+ _composition = original_._composition;
+ _x = original_._x;
+ _y = original_._y;
+ _width = original_._width;
+ _height = original_._height;
+ Image* temp_image = new Image(*original_._image);
+ delete _image;
+ _image = temp_image;
+ }
+ return *this;
+}
+void Magick::DrawableCompositeImage::filename( const std::string &filename_ )
+{
+ Image* temp_image = new Image(filename_);
+ delete _image;
+ _image = temp_image;
+}
+std::string Magick::DrawableCompositeImage::filename( void ) const
+{
+ return _image->fileName();
+}
+
+void Magick::DrawableCompositeImage::image( const Magick::Image &image_ )
+{
+ Image* temp_image = new Image(image_);
+ delete _image;
+ _image = temp_image;
+}
+Magick::Image Magick::DrawableCompositeImage::image( void ) const
+{
+ return *_image;
+}
+
+// Specify image format used to output Base64 inlined image data.
+void Magick::DrawableCompositeImage::magick( std::string magick_ )
+{
+ _image->magick( magick_ );
+}
+std::string Magick::DrawableCompositeImage::magick( void )
+{
+ return _image->magick();
+}
+
+void Magick::DrawableCompositeImage::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawComposite( context_, _composition, _x, _y, _width, _height,
+ _image->constImage() );
+}
+
+Magick::DrawableBase* Magick::DrawableCompositeImage::copy() const
+{
+ return new DrawableCompositeImage(*this);
+}
+
+// Ellipse
+Magick::DrawableEllipse::~DrawableEllipse( void )
+{
+}
+void Magick::DrawableEllipse::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawEllipse( context_, _originX, _originY, _radiusX, _radiusY,
+ _arcStart, _arcEnd );
+}
+Magick::DrawableBase* Magick::DrawableEllipse::copy() const
+{
+ return new DrawableEllipse(*this);
+}
+
+// Specify drawing fill color
+Magick::DrawableFillColor::DrawableFillColor( const Magick::Color &color_ )
+ : _color(color_)
+{
+}
+Magick::DrawableFillColor::DrawableFillColor
+( const Magick::DrawableFillColor& original_ )
+ : DrawableBase (original_),
+ _color(original_._color)
+{
+}
+Magick::DrawableFillColor::~DrawableFillColor( void )
+{
+}
+void Magick::DrawableFillColor::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ PixelPacket color = static_cast<PixelPacket>(_color);
+ DrawSetFillColor( context_, &color );
+}
+Magick::DrawableBase* Magick::DrawableFillColor::copy() const
+{
+ return new DrawableFillColor(*this);
+}
+
+// Specify drawing fill fule
+Magick::DrawableFillRule::~DrawableFillRule ( void )
+{
+}
+void Magick::DrawableFillRule::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetFillRule( context_, _fillRule );
+}
+Magick::DrawableBase* Magick::DrawableFillRule::copy() const
+{
+ return new DrawableFillRule(*this);
+}
+
+// Specify drawing fill opacity
+Magick::DrawableFillOpacity::~DrawableFillOpacity ( void )
+{
+}
+void Magick::DrawableFillOpacity::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetFillOpacity( context_, _opacity );
+}
+Magick::DrawableBase* Magick::DrawableFillOpacity::copy() const
+{
+ return new DrawableFillOpacity(*this);
+}
+
+// Specify text font
+Magick::DrawableFont::DrawableFont ( const std::string &font_ )
+ : _font(font_),
+ _family(),
+ _style(Magick::AnyStyle),
+ _weight(400),
+ _stretch(Magick::NormalStretch)
+{
+}
+Magick::DrawableFont::DrawableFont ( const std::string &family_,
+ Magick::StyleType style_,
+ const unsigned long weight_,
+ Magick::StretchType stretch_ )
+ : _font(),
+ _family(family_),
+ _style(style_),
+ _weight(weight_),
+ _stretch(stretch_)
+{
+}
+Magick::DrawableFont::DrawableFont ( const Magick::DrawableFont& original_ )
+ : DrawableBase (original_),
+ _font(original_._font),
+ _family(original_._family),
+ _style(original_._style),
+ _weight(original_._weight),
+ _stretch(original_._stretch)
+{
+}
+Magick::DrawableFont::~DrawableFont ( void )
+{
+}
+void Magick::DrawableFont::operator()( MagickLib::DrawContext context_ ) const
+{
+ // font
+ if(_font.length())
+ {
+ DrawSetFont( context_, _font.c_str() );
+ }
+
+ if(_family.length())
+ {
+ // font-family
+ DrawSetFontFamily( context_, _family.c_str() );
+
+ // font-style
+ DrawSetFontStyle( context_, _style );
+
+ // font-weight
+ DrawSetFontWeight( context_, _weight );
+
+ // font-stretch
+ DrawSetFontStretch( context_, _stretch );
+ }
+}
+Magick::DrawableBase* Magick::DrawableFont::copy() const
+{
+ return new DrawableFont(*this);
+}
+
+// Specify text positioning gravity
+Magick::DrawableGravity::~DrawableGravity ( void )
+{
+}
+void Magick::DrawableGravity::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetGravity( context_, _gravity );
+}
+Magick::DrawableBase* Magick::DrawableGravity::copy() const
+{
+ return new DrawableGravity(*this);
+}
+
+// Line
+Magick::DrawableLine::~DrawableLine ( void )
+{
+}
+void Magick::DrawableLine::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawLine( context_, _startX, _startY, _endX, _endY );
+}
+Magick::DrawableBase* Magick::DrawableLine::copy() const
+{
+ return new DrawableLine(*this);
+}
+
+// Change pixel matte value to transparent using PaintMethod
+Magick::DrawableMatte::~DrawableMatte ( void )
+{
+}
+void Magick::DrawableMatte::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawMatte( context_, _x, _y, _paintMethod );
+}
+Magick::DrawableBase* Magick::DrawableMatte::copy() const
+{
+ return new DrawableMatte(*this);
+}
+
+// Drawable Path
+Magick::DrawablePath::DrawablePath ( const VPathList &path_ )
+ : _path(path_)
+{
+}
+Magick::DrawablePath::DrawablePath ( const Magick::DrawablePath& original_ )
+ : DrawableBase (original_),
+ _path(original_._path)
+{
+}
+Magick::DrawablePath::~DrawablePath ( void )
+{
+}
+void Magick::DrawablePath::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawPathStart( context_ );
+
+ for( VPathList::const_iterator p = _path.begin();
+ p != _path.end(); p++ )
+ p->operator()( context_ ); // FIXME, how to quit loop on error?
+
+ DrawPathFinish( context_ );
+}
+Magick::DrawableBase* Magick::DrawablePath::copy() const
+{
+ return new DrawablePath(*this);
+}
+
+// Point
+Magick::DrawablePoint::~DrawablePoint ( void )
+{
+}
+void Magick::DrawablePoint::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawPoint( context_, _x, _y );
+}
+Magick::DrawableBase* Magick::DrawablePoint::copy() const
+{
+ return new DrawablePoint(*this);
+}
+
+// Text pointsize
+Magick::DrawablePointSize::~DrawablePointSize ( void )
+{
+}
+void Magick::DrawablePointSize::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetFontSize( context_, _pointSize );
+}
+Magick::DrawableBase* Magick::DrawablePointSize::copy() const
+{
+ return new DrawablePointSize(*this);
+}
+
+// Polygon (Coordinate list must contain at least three members)
+Magick::DrawablePolygon::DrawablePolygon ( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::DrawablePolygon::DrawablePolygon
+( const Magick::DrawablePolygon& original_ )
+ : DrawableBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::DrawablePolygon::~DrawablePolygon ( void )
+{
+}
+void Magick::DrawablePolygon::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ size_t num_coords = _coordinates.size();
+ PointInfo *coordinates = new PointInfo[num_coords];
+
+ PointInfo *q = coordinates;
+ CoordinateList::const_iterator p = _coordinates.begin();
+
+ while( p != _coordinates.end() )
+ {
+ q->x = p->x();
+ q->y = p->y();
+ q++;
+ p++;
+ }
+
+ DrawPolygon( context_, (const unsigned long) num_coords, coordinates );
+ delete [] coordinates;
+}
+Magick::DrawableBase* Magick::DrawablePolygon::copy() const
+{
+ return new DrawablePolygon(*this);
+}
+
+// Polyline (Coordinate list must contain at least three members)
+Magick::DrawablePolyline::DrawablePolyline
+( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::DrawablePolyline::DrawablePolyline
+( const Magick::DrawablePolyline& original_ )
+ : DrawableBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::DrawablePolyline::~DrawablePolyline ( void )
+{
+}
+void Magick::DrawablePolyline::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ size_t num_coords = _coordinates.size();
+ PointInfo *coordinates = new PointInfo[num_coords];
+
+ PointInfo *q = coordinates;
+ CoordinateList::const_iterator p = _coordinates.begin();
+
+ while( p != _coordinates.end() )
+ {
+ q->x = p->x();
+ q->y = p->y();
+ q++;
+ p++;
+ }
+
+ DrawPolyline( context_, (const unsigned long) num_coords, coordinates );
+ delete [] coordinates;
+}
+Magick::DrawableBase* Magick::DrawablePolyline::copy() const
+{
+ return new DrawablePolyline(*this);
+}
+
+// Pop Graphic Context
+Magick::DrawablePopGraphicContext::~DrawablePopGraphicContext ( void )
+{
+}
+void Magick::DrawablePopGraphicContext::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPopGraphicContext( context_ );
+}
+Magick::DrawableBase* Magick::DrawablePopGraphicContext::copy() const
+{
+ return new DrawablePopGraphicContext(*this);
+}
+
+// Push Graphic Context
+Magick::DrawablePushGraphicContext::~DrawablePushGraphicContext ( void )
+{
+}
+void Magick::DrawablePushGraphicContext::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPushGraphicContext( context_ );
+}
+Magick::DrawableBase* Magick::DrawablePushGraphicContext::copy() const
+{
+ return new DrawablePushGraphicContext(*this);
+}
+
+// Pop (terminate) Pattern definition
+Magick::DrawablePopPattern::~DrawablePopPattern ( void )
+{
+}
+void Magick::DrawablePopPattern::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPopPattern( context_ );
+}
+Magick::DrawableBase* Magick::DrawablePopPattern::copy() const
+{
+ return new DrawablePopPattern(*this);
+}
+
+// Push Pattern definition
+Magick::DrawablePushPattern::DrawablePushPattern
+( const std::string &id_, long x_, long y_,
+ long width_, long height_ )
+ : _id(id_),
+ _x(x_),
+ _y(y_),
+ _width(width_),
+ _height(height_)
+{
+}
+Magick::DrawablePushPattern::DrawablePushPattern
+( const Magick::DrawablePushPattern& original_ )
+ : DrawableBase (original_),
+ _id(original_._id),
+ _x(original_._x),
+ _y(original_._y),
+ _width(original_._width),
+ _height(original_._height)
+{
+}
+Magick::DrawablePushPattern::~DrawablePushPattern ( void )
+{
+}
+void Magick::DrawablePushPattern::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPushPattern( context_, _id.c_str(), _x, _y, _width, _height );
+}
+Magick::DrawableBase* Magick::DrawablePushPattern::copy() const
+{
+ return new DrawablePushPattern(*this);
+}
+
+// Rectangle
+Magick::DrawableRectangle::~DrawableRectangle ( void )
+{
+}
+void Magick::DrawableRectangle::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawRectangle( context_, _upperLeftX, _upperLeftY,
+ _lowerRightX, _lowerRightY );
+}
+Magick::DrawableBase* Magick::DrawableRectangle::copy() const
+{
+ return new DrawableRectangle(*this);
+}
+
+// Apply Rotation
+Magick::DrawableRotation::~DrawableRotation ( void )
+{
+}
+void Magick::DrawableRotation::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawRotate( context_, _angle );
+}
+Magick::DrawableBase* Magick::DrawableRotation::copy() const
+{
+ return new DrawableRotation(*this);
+}
+
+// Round Rectangle
+Magick::DrawableRoundRectangle::~DrawableRoundRectangle ( void )
+{
+}
+void Magick::DrawableRoundRectangle::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawRoundRectangle( context_, _centerX,_centerY, _width,_hight,
+ _cornerWidth, _cornerHeight);
+}
+Magick::DrawableBase* Magick::DrawableRoundRectangle::copy() const
+{
+ return new DrawableRoundRectangle(*this);
+}
+
+// Apply Scaling
+Magick::DrawableScaling::~DrawableScaling ( void )
+{
+}
+void Magick::DrawableScaling::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawScale( context_, _x, _y );
+}
+Magick::DrawableBase* Magick::DrawableScaling::copy() const
+{
+ return new DrawableScaling(*this);
+}
+
+// Apply Skew in the X direction
+Magick::DrawableSkewX::~DrawableSkewX ( void )
+{
+}
+void Magick::DrawableSkewX::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSkewX( context_, _angle );
+}
+Magick::DrawableBase* Magick::DrawableSkewX::copy() const
+{
+ return new DrawableSkewX(*this);
+}
+
+// Apply Skew in the Y direction
+Magick::DrawableSkewY::~DrawableSkewY ( void )
+{
+}
+void Magick::DrawableSkewY::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawSkewY( context_, _angle );
+}
+Magick::DrawableBase* Magick::DrawableSkewY::copy() const
+{
+ return new DrawableSkewY(*this);
+}
+
+// Stroke dasharray
+Magick::DrawableDashArray::DrawableDashArray( const double* dasharray_ )
+ : _size(0),
+ _dasharray(0)
+{
+ dasharray( dasharray_ );
+}
+// Deprecated, do not use for new code, and migrate existing code to
+// using double*
+Magick::DrawableDashArray::DrawableDashArray( const unsigned int* dasharray_ )
+ : _size(0),
+ _dasharray(0)
+{
+ dasharray( dasharray_ );
+}
+Magick::DrawableDashArray::DrawableDashArray
+(const Magick::DrawableDashArray& original_)
+ : DrawableBase (original_),
+ _size(original_._size),
+ _dasharray(new double[_size+1])
+{
+ // Copy elements
+ {
+ for (size_t i=0; i < _size; i++)
+ _dasharray[i]=original_._dasharray[i];
+ _dasharray[_size]=0.0;
+ }
+}
+Magick::DrawableDashArray::~DrawableDashArray( void )
+{
+ delete [] _dasharray;
+ _size = 0;
+ _dasharray = 0;
+}
+Magick::DrawableDashArray& Magick::DrawableDashArray::operator=
+(const Magick::DrawableDashArray &original_)
+{
+ if( this != &original_ )
+ {
+ delete [] _dasharray;
+ _size=original_._size;
+ _dasharray = new double[_size+1];
+ // Copy elements
+ {
+ for (size_t i=0; i < _size; i++)
+ _dasharray[i]=original_._dasharray[i];
+ _dasharray[_size]=0.0;
+ }
+ }
+ return *this;
+}
+// Invoke object
+void Magick::DrawableDashArray::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetStrokeDashArray( context_, (const unsigned long) _size, _dasharray );
+}
+Magick::DrawableBase* Magick::DrawableDashArray::copy() const
+{
+ return new DrawableDashArray(*this);
+}
+void Magick::DrawableDashArray::dasharray ( const double* dasharray_ )
+{
+ delete [] _dasharray;
+ _size = 0;
+ _dasharray = 0;
+
+ if(dasharray_)
+ {
+ // Count elements in dash array
+ size_t n = 0;
+ {
+ const double *p = dasharray_;
+ while(*p++ != 0.0)
+ n++;
+ }
+ _size = n;
+
+ // Allocate elements
+ _dasharray=new double[_size+1];
+ // Copy elements
+ {
+ for (size_t i=0; i < _size; i++)
+ _dasharray[i]=dasharray_[i];
+ _dasharray[_size]=0.0;
+ }
+ }
+}
+// This method is deprecated. Don't use for new code, and migrate existing
+// code to the const double* version.
+void Magick::DrawableDashArray::dasharray( const unsigned int* dasharray_ )
+{
+ if (_dasharray)
+ delete [] _dasharray;
+ _size = 0;
+ _dasharray = 0;
+
+ if(dasharray_)
+ {
+ // Count elements in dash array
+ size_t n = 0;
+ {
+ const unsigned int *p = dasharray_;
+ while(*p++ != 0)
+ n++;
+ }
+ _size = n;
+
+ // Allocate elements
+ _dasharray=new double[_size+1];
+ // Copy elements
+ {
+ for (size_t i=0; i < _size; i++)
+ _dasharray[i]=dasharray_[i];
+ _dasharray[_size]=0;
+ }
+ }
+}
+
+// Stroke dashoffset
+Magick::DrawableDashOffset::~DrawableDashOffset ( void )
+{
+}
+void Magick::DrawableDashOffset::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetStrokeDashOffset( context_, _offset );
+}
+Magick::DrawableBase* Magick::DrawableDashOffset::copy() const
+{
+ return new DrawableDashOffset(*this);
+}
+
+// Stroke linecap
+Magick::DrawableStrokeLineCap::~DrawableStrokeLineCap ( void )
+{
+}
+void Magick::DrawableStrokeLineCap::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetStrokeLineCap( context_, _linecap );
+}
+Magick::DrawableBase* Magick::DrawableStrokeLineCap::copy() const
+{
+ return new DrawableStrokeLineCap(*this);
+}
+
+// Stroke linejoin
+Magick::DrawableStrokeLineJoin::~DrawableStrokeLineJoin ( void )
+{
+}
+void Magick::DrawableStrokeLineJoin::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetStrokeLineJoin( context_, _linejoin );
+}
+Magick::DrawableBase* Magick::DrawableStrokeLineJoin::copy() const
+{
+ return new DrawableStrokeLineJoin(*this);
+}
+
+// Stroke miterlimit
+Magick::DrawableMiterLimit::~DrawableMiterLimit ( void )
+{
+}
+void Magick::DrawableMiterLimit::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetStrokeMiterLimit( context_, _miterlimit );
+}
+Magick::DrawableBase* Magick::DrawableMiterLimit::copy() const
+{
+ return new DrawableMiterLimit(*this);
+}
+
+// Stroke antialias
+Magick::DrawableStrokeAntialias::~DrawableStrokeAntialias ( void )
+{
+}
+void Magick::DrawableStrokeAntialias::operator()
+( MagickLib::DrawContext context_ ) const
+{
+ DrawSetStrokeAntialias( context_, static_cast<int>(_flag) );
+}
+Magick::DrawableBase* Magick::DrawableStrokeAntialias::copy() const
+{
+ return new DrawableStrokeAntialias(*this);
+}
+
+// Stroke color
+Magick::DrawableStrokeColor::DrawableStrokeColor
+( const Magick::Color &color_ )
+ : _color(color_)
+{
+}
+Magick::DrawableStrokeColor::DrawableStrokeColor
+( const Magick::DrawableStrokeColor& original_ )
+ : DrawableBase (original_),
+ _color(original_._color)
+{
+}
+Magick::DrawableStrokeColor::~DrawableStrokeColor ( void )
+{
+}
+void Magick::DrawableStrokeColor::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ PixelPacket color = static_cast<PixelPacket>(_color);
+ DrawSetStrokeColor( context_, &color );
+}
+Magick::DrawableBase* Magick::DrawableStrokeColor::copy() const
+{
+ return new DrawableStrokeColor(*this);
+}
+
+// Stroke opacity
+Magick::DrawableStrokeOpacity::~DrawableStrokeOpacity ( void )
+{
+}
+void Magick::DrawableStrokeOpacity::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetStrokeOpacity( context_, _opacity );
+}
+Magick::DrawableBase* Magick::DrawableStrokeOpacity::copy() const
+{
+ return new DrawableStrokeOpacity(*this);
+}
+
+// Stroke width
+Magick::DrawableStrokeWidth::~DrawableStrokeWidth ( void )
+{
+}
+void Magick::DrawableStrokeWidth::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetStrokeWidth( context_, _width );
+}
+Magick::DrawableBase* Magick::DrawableStrokeWidth::copy() const
+{
+ return new DrawableStrokeWidth(*this);
+}
+
+// Draw text at point
+Magick::DrawableText::DrawableText ( const double x_, const double y_,
+ const std::string &text_ )
+ : _x(x_),
+ _y(y_),
+ _text(text_),
+ _encoding()
+{
+}
+Magick::DrawableText::DrawableText ( const double x_, const double y_,
+ const std::string &text_, const std::string &encoding_)
+ : _x(x_),
+ _y(y_),
+ _text(text_),
+ _encoding(encoding_)
+{
+}
+Magick::DrawableText::DrawableText( const Magick::DrawableText& original_ )
+ : DrawableBase (original_),
+ _x(original_._x),
+ _y(original_._y),
+ _text(original_._text),
+ _encoding(original_._encoding)
+{
+}
+Magick::DrawableText::~DrawableText ( void )
+{
+}
+void Magick::DrawableText::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetTextEncoding( context_, _encoding.c_str() );
+ DrawAnnotation( context_, _x, _y,
+ reinterpret_cast<const unsigned char*>(_text.c_str()) );
+}
+Magick::DrawableBase* Magick::DrawableText::copy() const
+{
+ return new DrawableText(*this);
+}
+
+// Text antialias
+Magick::DrawableTextAntialias::DrawableTextAntialias ( bool flag_ )
+ : _flag(flag_)
+{
+}
+Magick::DrawableTextAntialias::DrawableTextAntialias( const Magick::DrawableTextAntialias &original_ )
+ : DrawableBase (original_),
+ _flag(original_._flag)
+{
+}
+Magick::DrawableTextAntialias::~DrawableTextAntialias ( void )
+{
+}
+void Magick::DrawableTextAntialias::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetTextAntialias( context_, static_cast<int>(_flag) );
+}
+Magick::DrawableBase* Magick::DrawableTextAntialias::copy() const
+{
+ return new DrawableTextAntialias(*this);
+}
+
+// Decoration (text decoration)
+Magick::DrawableTextDecoration::DrawableTextDecoration
+ ( Magick::DecorationType decoration_ )
+ : _decoration(decoration_)
+{
+}
+Magick::DrawableTextDecoration::DrawableTextDecoration
+ ( const Magick::DrawableTextDecoration &original_ )
+ : DrawableBase (original_),
+ _decoration(original_._decoration)
+{
+}
+Magick::DrawableTextDecoration::~DrawableTextDecoration( void )
+{
+}
+void Magick::DrawableTextDecoration::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetTextDecoration( context_, _decoration );
+}
+Magick::DrawableBase* Magick::DrawableTextDecoration::copy() const
+{
+ return new DrawableTextDecoration(*this);
+}
+
+// Set text undercolor
+Magick::DrawableTextUnderColor::DrawableTextUnderColor
+( const Magick::Color &color_ )
+ : _color(color_)
+{
+}
+Magick::DrawableTextUnderColor::DrawableTextUnderColor
+( const Magick::DrawableTextUnderColor& original_ )
+ : DrawableBase (original_),
+ _color(original_._color)
+{
+}
+Magick::DrawableTextUnderColor::~DrawableTextUnderColor ( void )
+{
+}
+void Magick::DrawableTextUnderColor::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ PixelPacket color = static_cast<PixelPacket>(_color);
+ DrawSetTextUnderColor( context_, &color );
+}
+Magick::DrawableBase* Magick::DrawableTextUnderColor::copy() const
+{
+ return new DrawableTextUnderColor(*this);
+}
+
+// Apply Translation
+Magick::DrawableTranslation::~DrawableTranslation ( void )
+{
+}
+void Magick::DrawableTranslation::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawTranslate( context_, _x, _y );
+}
+Magick::DrawableBase* Magick::DrawableTranslation::copy() const
+{
+ return new DrawableTranslation(*this);
+}
+
+// Set the size of the viewbox
+Magick::DrawableViewbox::~DrawableViewbox ( void )
+{
+}
+void Magick::DrawableViewbox::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawSetViewbox( context_, _x1, _y1, _x2, _y2 );
+}
+Magick::DrawableBase* Magick::DrawableViewbox::copy() const
+{
+ return new DrawableViewbox(*this);
+}
+
+//
+// Path Classes
+//
+
+//
+// PathArcArgs
+//
+MagickDLLDecl int Magick::operator == ( const Magick::PathArcArgs& /*left_*/,
+ const Magick::PathArcArgs& /*right_*/ )
+{
+ return ( 1 );
+}
+MagickDLLDecl int Magick::operator != ( const Magick::PathArcArgs& /*left_*/,
+ const Magick::PathArcArgs& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator > ( const Magick::PathArcArgs& /*left_*/,
+ const Magick::PathArcArgs& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator < ( const Magick::PathArcArgs& /*left_*/,
+ const Magick::PathArcArgs& /*right_*/ )
+{
+ return ( false );
+}
+MagickDLLDecl int Magick::operator >= ( const Magick::PathArcArgs& left_,
+ const Magick::PathArcArgs& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+MagickDLLDecl int Magick::operator <= ( const Magick::PathArcArgs& left_,
+ const Magick::PathArcArgs& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+// Default constructor
+Magick::PathArcArgs::PathArcArgs( void )
+ : _radiusX(0),
+ _radiusY(0),
+ _xAxisRotation(0),
+ _largeArcFlag(false),
+ _sweepFlag(false),
+ _x(0),
+ _y(0)
+{
+}
+// Normal constructor
+Magick::PathArcArgs::PathArcArgs( double radiusX_, double radiusY_,
+ double xAxisRotation_, bool largeArcFlag_,
+ bool sweepFlag_, double x_, double y_ )
+ : _radiusX(radiusX_),
+ _radiusY(radiusY_),
+ _xAxisRotation(xAxisRotation_),
+ _largeArcFlag(largeArcFlag_),
+ _sweepFlag(sweepFlag_),
+ _x(x_),
+ _y(y_)
+{
+}
+// Copy constructor
+Magick::PathArcArgs::PathArcArgs( const Magick::PathArcArgs &original_ )
+ : _radiusX(original_._radiusX),
+ _radiusY(original_._radiusY),
+ _xAxisRotation(original_._xAxisRotation),
+ _largeArcFlag(original_._largeArcFlag),
+ _sweepFlag(original_._sweepFlag),
+ _x(original_._x),
+ _y(original_._y)
+{
+}
+// Destructor
+Magick::PathArcArgs::~PathArcArgs ( void )
+{
+}
+
+// Path Arc
+Magick::PathArcAbs::PathArcAbs ( const Magick::PathArcArgs &coordinates_ )
+ : _coordinates(1,coordinates_)
+{
+}
+Magick::PathArcAbs::PathArcAbs ( const PathArcArgsList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathArcAbs::PathArcAbs ( const Magick::PathArcAbs& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathArcAbs::~PathArcAbs ( void )
+{
+}
+void Magick::PathArcAbs::operator()( MagickLib::DrawContext context_ ) const
+{
+ for( PathArcArgsList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ DrawPathEllipticArcAbsolute( context_, p->radiusX(), p->radiusY(),
+ p->xAxisRotation(), p->largeArcFlag(),
+ p->sweepFlag(), p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathArcAbs::copy() const
+{
+ return new PathArcAbs(*this);
+}
+
+Magick::PathArcRel::PathArcRel ( const Magick::PathArcArgs &coordinates_ )
+ : _coordinates(1,coordinates_)
+{
+}
+Magick::PathArcRel::PathArcRel ( const PathArcArgsList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathArcRel::PathArcRel ( const Magick::PathArcRel& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathArcRel::~PathArcRel ( void )
+{
+}
+void Magick::PathArcRel::operator()( MagickLib::DrawContext context_ ) const
+{
+ for( PathArcArgsList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ DrawPathEllipticArcRelative( context_, p->radiusX(), p->radiusY(),
+ p->xAxisRotation(), p->largeArcFlag(),
+ p->sweepFlag(), p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathArcRel::copy() const
+{
+ return new PathArcRel(*this);
+}
+
+//
+// Path Closepath
+//
+Magick::PathClosePath::~PathClosePath ( void )
+{
+}
+void Magick::PathClosePath::operator()( MagickLib::DrawContext context_ ) const
+{
+ DrawPathClose( context_ );
+}
+Magick::VPathBase* Magick::PathClosePath::copy() const
+{
+ return new PathClosePath(*this);
+}
+
+//
+// Path Curveto (Cubic Bezier)
+//
+MagickDLLDecl int Magick::operator == ( const Magick::PathCurvetoArgs& /*left_*/,
+ const Magick::PathCurvetoArgs& /*right_*/ )
+{
+ return ( 1 );
+}
+MagickDLLDecl int Magick::operator != ( const Magick::PathCurvetoArgs& /*left_*/,
+ const Magick::PathCurvetoArgs& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator > ( const Magick::PathCurvetoArgs& /*left_*/,
+ const Magick::PathCurvetoArgs& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator < ( const Magick::PathCurvetoArgs& /*left_*/,
+ const Magick::PathCurvetoArgs& /*right_*/ )
+{
+ return ( false );
+}
+MagickDLLDecl int Magick::operator >= ( const Magick::PathCurvetoArgs& left_,
+ const Magick::PathCurvetoArgs& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+MagickDLLDecl int Magick::operator <= ( const Magick::PathCurvetoArgs& left_,
+ const Magick::PathCurvetoArgs& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+// Default constructor
+Magick::PathCurvetoArgs::PathCurvetoArgs( void )
+ : _x1(0),
+ _y1(0),
+ _x2(0),
+ _y2(0),
+ _x(0),
+ _y(0)
+{
+}
+// Normal constructor
+Magick::PathCurvetoArgs::PathCurvetoArgs( double x1_, double y1_,
+ double x2_, double y2_,
+ double x_, double y_ )
+ : _x1(x1_),
+ _y1(y1_),
+ _x2(x2_),
+ _y2(y2_),
+ _x(x_),
+ _y(y_)
+{
+}
+// Copy constructor
+Magick::PathCurvetoArgs::PathCurvetoArgs( const PathCurvetoArgs &original_ )
+ : _x1(original_._x1),
+ _y1(original_._y1),
+ _x2(original_._x2),
+ _y2(original_._y2),
+ _x(original_._x),
+ _y(original_._y)
+{
+}
+// Destructor
+Magick::PathCurvetoArgs::~PathCurvetoArgs ( void )
+{
+}
+
+Magick::PathCurvetoAbs::PathCurvetoAbs ( const Magick::PathCurvetoArgs &args_ )
+ : _args(1,args_)
+{
+}
+Magick::PathCurvetoAbs::PathCurvetoAbs ( const PathCurveToArgsList &args_ )
+ : _args(args_)
+{
+}
+Magick::PathCurvetoAbs::PathCurvetoAbs
+ ( const Magick::PathCurvetoAbs& original_ )
+ : VPathBase (original_),
+ _args(original_._args)
+{
+}
+Magick::PathCurvetoAbs::~PathCurvetoAbs ( void )
+{
+}
+void Magick::PathCurvetoAbs::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ for( PathCurveToArgsList::const_iterator p = _args.begin();
+ p != _args.end(); p++ )
+ {
+ DrawPathCurveToAbsolute( context_, p->x1(), p->y1(), p->x2(), p->y2(),
+ p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathCurvetoAbs::copy() const
+{
+ return new PathCurvetoAbs(*this);
+}
+Magick::PathCurvetoRel::PathCurvetoRel ( const Magick::PathCurvetoArgs &args_ )
+ : _args(1,args_)
+{
+}
+Magick::PathCurvetoRel::PathCurvetoRel ( const PathCurveToArgsList &args_ )
+ : _args(args_)
+{
+}
+Magick::PathCurvetoRel::PathCurvetoRel
+( const Magick::PathCurvetoRel& original_ )
+ : VPathBase (original_),
+ _args(original_._args)
+{
+}
+Magick::PathCurvetoRel::~PathCurvetoRel ( void )
+{
+}
+void Magick::PathCurvetoRel::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ for( PathCurveToArgsList::const_iterator p = _args.begin();
+ p != _args.end(); p++ )
+ {
+ DrawPathCurveToRelative( context_, p->x1(), p->y1(), p->x2(), p->y2(),
+ p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathCurvetoRel::copy() const
+{
+ return new PathCurvetoRel(*this);
+}
+Magick::PathSmoothCurvetoAbs::PathSmoothCurvetoAbs
+( const Magick::Coordinate &coordinates_ )
+ : _coordinates(1,coordinates_)
+{
+}
+Magick::PathSmoothCurvetoAbs::PathSmoothCurvetoAbs
+( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathSmoothCurvetoAbs::PathSmoothCurvetoAbs
+( const Magick::PathSmoothCurvetoAbs& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathSmoothCurvetoAbs::~PathSmoothCurvetoAbs ( void )
+{
+}
+void Magick::PathSmoothCurvetoAbs::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ for( CoordinateList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ double x2 = p->x();
+ double y2 = p->y();
+ p++;
+ if (p == _coordinates.end())
+ break;
+ DrawPathCurveToSmoothAbsolute( context_, x2, y2, p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathSmoothCurvetoAbs::copy() const
+{
+ return new PathSmoothCurvetoAbs(*this);
+}
+Magick::PathSmoothCurvetoRel::PathSmoothCurvetoRel
+( const Magick::Coordinate &coordinates_ )
+ : _coordinates(1,coordinates_)
+{
+}
+Magick::PathSmoothCurvetoRel::PathSmoothCurvetoRel
+( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathSmoothCurvetoRel::PathSmoothCurvetoRel
+( const Magick::PathSmoothCurvetoRel& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathSmoothCurvetoRel::~PathSmoothCurvetoRel ( void )
+{
+}
+void Magick::PathSmoothCurvetoRel::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ for( CoordinateList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ double x2 = p->x();
+ double y2 = p->y();
+ p++;
+ if (p == _coordinates.end())
+ break;
+ DrawPathCurveToSmoothRelative( context_, x2, y2, p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathSmoothCurvetoRel::copy() const
+{
+ return new PathSmoothCurvetoRel(*this);
+}
+
+//
+// Quadratic Curveto (Quadratic Bezier)
+//
+MagickDLLDecl int Magick::operator ==
+( const Magick::PathQuadraticCurvetoArgs& /*left_*/,
+ const Magick::PathQuadraticCurvetoArgs& /*right_*/ )
+{
+ return ( 1 );
+}
+MagickDLLDecl int Magick::operator !=
+( const Magick::PathQuadraticCurvetoArgs& /*left_*/,
+ const Magick::PathQuadraticCurvetoArgs& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator >
+( const Magick::PathQuadraticCurvetoArgs& /*left_*/,
+ const Magick::PathQuadraticCurvetoArgs& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator <
+( const Magick::PathQuadraticCurvetoArgs& /*left_*/,
+ const Magick::PathQuadraticCurvetoArgs& /*right_*/ )
+{
+ return ( 0 );
+}
+MagickDLLDecl int Magick::operator >=
+( const Magick::PathQuadraticCurvetoArgs& left_,
+ const Magick::PathQuadraticCurvetoArgs& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+MagickDLLDecl int Magick::operator <=
+( const Magick::PathQuadraticCurvetoArgs& left_,
+ const Magick::PathQuadraticCurvetoArgs& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+// Default Constructor
+Magick::PathQuadraticCurvetoArgs::PathQuadraticCurvetoArgs( void )
+ : _x1(0),
+ _y1(0),
+ _x(0),
+ _y(0)
+{
+}
+// Normal Constructor
+Magick::PathQuadraticCurvetoArgs::PathQuadraticCurvetoArgs( double x1_,
+ double y1_,
+ double x_,
+ double y_ )
+ : _x1(x1_),
+ _y1(y1_),
+ _x(x_),
+ _y(y_)
+{
+}
+// Copy Constructor
+Magick::PathQuadraticCurvetoArgs::PathQuadraticCurvetoArgs( const PathQuadraticCurvetoArgs &original_ )
+ : _x1(original_._x1),
+ _y1(original_._y1),
+ _x(original_._x),
+ _y(original_._y)
+{
+}
+// Destructor
+Magick::PathQuadraticCurvetoArgs::~PathQuadraticCurvetoArgs ( void )
+{
+}
+
+Magick::PathQuadraticCurvetoAbs::PathQuadraticCurvetoAbs
+( const Magick::PathQuadraticCurvetoArgs &args_ )
+ : _args(1,args_)
+{
+}
+Magick::PathQuadraticCurvetoAbs::PathQuadraticCurvetoAbs
+( const PathQuadraticCurvetoArgsList &args_ )
+ : _args(args_)
+{
+}
+Magick::PathQuadraticCurvetoAbs::PathQuadraticCurvetoAbs
+( const Magick::PathQuadraticCurvetoAbs& original_ )
+ : VPathBase (original_),
+ _args(original_._args)
+{
+}
+Magick::PathQuadraticCurvetoAbs::~PathQuadraticCurvetoAbs ( void )
+{
+}
+void Magick::PathQuadraticCurvetoAbs::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ for( PathQuadraticCurvetoArgsList::const_iterator p = _args.begin();
+ p != _args.end(); p++ )
+ {
+ DrawPathCurveToQuadraticBezierAbsolute( context_, p->x1(), p->y1(),
+ p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathQuadraticCurvetoAbs::copy() const
+{
+ return new PathQuadraticCurvetoAbs(*this);
+}
+Magick::PathQuadraticCurvetoRel::PathQuadraticCurvetoRel
+( const Magick::PathQuadraticCurvetoArgs &args_ )
+ : _args(1,args_)
+{
+}
+Magick::PathQuadraticCurvetoRel::PathQuadraticCurvetoRel
+( const PathQuadraticCurvetoArgsList &args_ )
+ : _args(args_)
+{
+}
+Magick::PathQuadraticCurvetoRel::PathQuadraticCurvetoRel
+( const Magick::PathQuadraticCurvetoRel& original_ )
+ : VPathBase (original_),
+ _args(original_._args)
+{
+}
+Magick::PathQuadraticCurvetoRel::~PathQuadraticCurvetoRel ( void )
+{
+}
+void Magick::PathQuadraticCurvetoRel::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ for( PathQuadraticCurvetoArgsList::const_iterator p = _args.begin();
+ p != _args.end(); p++ )
+ {
+ DrawPathCurveToQuadraticBezierRelative( context_, p->x1(), p->y1(),
+ p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathQuadraticCurvetoRel::copy() const
+{
+ return new PathQuadraticCurvetoRel(*this);
+}
+Magick::PathSmoothQuadraticCurvetoAbs::PathSmoothQuadraticCurvetoAbs
+( const Magick::Coordinate &coordinate_ )
+ : _coordinates(1,coordinate_)
+{
+}
+Magick::PathSmoothQuadraticCurvetoAbs::PathSmoothQuadraticCurvetoAbs
+( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathSmoothQuadraticCurvetoAbs::PathSmoothQuadraticCurvetoAbs
+( const Magick::PathSmoothQuadraticCurvetoAbs& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathSmoothQuadraticCurvetoAbs::~PathSmoothQuadraticCurvetoAbs ( void )
+{
+}
+void Magick::PathSmoothQuadraticCurvetoAbs::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ for( CoordinateList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ DrawPathCurveToQuadraticBezierSmoothAbsolute( context_, p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathSmoothQuadraticCurvetoAbs::copy() const
+{
+ return new PathSmoothQuadraticCurvetoAbs(*this);
+}
+Magick::PathSmoothQuadraticCurvetoRel::PathSmoothQuadraticCurvetoRel
+( const Magick::Coordinate &coordinate_ )
+ : _coordinates(1,coordinate_)
+{
+}
+Magick::PathSmoothQuadraticCurvetoRel::PathSmoothQuadraticCurvetoRel
+( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathSmoothQuadraticCurvetoRel::PathSmoothQuadraticCurvetoRel
+( const PathSmoothQuadraticCurvetoRel& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathSmoothQuadraticCurvetoRel::~PathSmoothQuadraticCurvetoRel ( void )
+{
+}
+void Magick::PathSmoothQuadraticCurvetoRel::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ for( CoordinateList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ DrawPathCurveToQuadraticBezierSmoothRelative( context_, p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathSmoothQuadraticCurvetoRel::copy() const
+{
+ return new PathSmoothQuadraticCurvetoRel(*this);
+}
+
+//
+// Path Lineto
+//
+Magick::PathLinetoAbs::PathLinetoAbs ( const Magick::Coordinate& coordinate_ )
+ : _coordinates(1,coordinate_)
+{
+}
+Magick::PathLinetoAbs::PathLinetoAbs ( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathLinetoAbs::PathLinetoAbs ( const Magick::PathLinetoAbs& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathLinetoAbs::~PathLinetoAbs ( void )
+{
+}
+void Magick::PathLinetoAbs::operator()( MagickLib::DrawContext context_ ) const
+{
+ for( CoordinateList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ DrawPathLineToAbsolute( context_, p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathLinetoAbs::copy() const
+{
+ return new PathLinetoAbs(*this);
+}
+Magick::PathLinetoRel::PathLinetoRel ( const Magick::Coordinate& coordinate_ )
+ : _coordinates(1,coordinate_)
+{
+}
+Magick::PathLinetoRel::PathLinetoRel ( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathLinetoRel::PathLinetoRel ( const Magick::PathLinetoRel& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathLinetoRel::~PathLinetoRel ( void )
+{
+}
+void Magick::PathLinetoRel::operator()( MagickLib::DrawContext context_ ) const
+{
+ for( CoordinateList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ DrawPathLineToRelative( context_, p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathLinetoRel::copy() const
+{
+ return new PathLinetoRel(*this);
+}
+
+//
+// Path Horizontal Lineto
+//
+
+Magick::PathLinetoHorizontalAbs::~PathLinetoHorizontalAbs ( void )
+{
+}
+void Magick::PathLinetoHorizontalAbs::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPathLineToHorizontalAbsolute( context_, _x );
+}
+Magick::VPathBase* Magick::PathLinetoHorizontalAbs::copy() const
+{
+ return new PathLinetoHorizontalAbs(*this);
+}
+Magick::PathLinetoHorizontalRel::~PathLinetoHorizontalRel ( void )
+{
+}
+void Magick::PathLinetoHorizontalRel::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPathLineToHorizontalRelative( context_, _x );
+}
+Magick::VPathBase* Magick::PathLinetoHorizontalRel::copy() const
+{
+ return new PathLinetoHorizontalRel(*this);
+}
+
+//
+// Path Vertical Lineto
+//
+Magick::PathLinetoVerticalAbs::~PathLinetoVerticalAbs ( void )
+{
+}
+void Magick::PathLinetoVerticalAbs::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPathLineToVerticalAbsolute( context_, _y );
+}
+Magick::VPathBase* Magick::PathLinetoVerticalAbs::copy() const
+{
+ return new PathLinetoVerticalAbs(*this);
+}
+Magick::PathLinetoVerticalRel::~PathLinetoVerticalRel ( void )
+{
+}
+void Magick::PathLinetoVerticalRel::operator()
+ ( MagickLib::DrawContext context_ ) const
+{
+ DrawPathLineToVerticalRelative( context_, _y );
+}
+Magick::VPathBase* Magick::PathLinetoVerticalRel::copy() const
+{
+ return new PathLinetoVerticalRel(*this);
+}
+
+//
+// Path Moveto
+//
+
+Magick::PathMovetoAbs::PathMovetoAbs ( const Magick::Coordinate &coordinate_ )
+ : _coordinates(1,coordinate_)
+{
+}
+Magick::PathMovetoAbs::PathMovetoAbs ( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathMovetoAbs::PathMovetoAbs ( const Magick::PathMovetoAbs& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathMovetoAbs::~PathMovetoAbs ( void )
+{
+}
+void Magick::PathMovetoAbs::operator()( MagickLib::DrawContext context_ ) const
+{
+ for( CoordinateList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ DrawPathMoveToAbsolute( context_, p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathMovetoAbs::copy() const
+{
+ return new PathMovetoAbs(*this);
+}
+Magick::PathMovetoRel::PathMovetoRel ( const Magick::Coordinate &coordinate_ )
+ : _coordinates(1,coordinate_)
+{
+}
+Magick::PathMovetoRel::PathMovetoRel ( const CoordinateList &coordinates_ )
+ : _coordinates(coordinates_)
+{
+}
+Magick::PathMovetoRel::PathMovetoRel ( const Magick::PathMovetoRel& original_ )
+ : VPathBase (original_),
+ _coordinates(original_._coordinates)
+{
+}
+Magick::PathMovetoRel::~PathMovetoRel ( void )
+{
+}
+void Magick::PathMovetoRel::operator()( MagickLib::DrawContext context_ ) const
+{
+ for( CoordinateList::const_iterator p = _coordinates.begin();
+ p != _coordinates.end(); p++ )
+ {
+ DrawPathMoveToRelative( context_, p->x(), p->y() );
+ }
+}
+Magick::VPathBase* Magick::PathMovetoRel::copy() const
+{
+ return new PathMovetoRel(*this);
+}
+
+#if defined(EXPLICIT_TEMPLATE_INSTANTIATION)
+// template class std::list<Magick::Coordinate>;
+// template class std::list<const Magick::Drawable>;
+// template class std::list<const Magick::PathArcArgs>;
+// template class std::list<const Magick::PathCurvetoArgs>;
+// template class std::list<const Magick::PathQuadraticCurvetoArgs>;
+// template class std::list<const Magick::VPath>;
+#endif
diff --git a/Magick++/lib/Exception.cpp b/Magick++/lib/Exception.cpp
new file mode 100644
index 0000000..b09bdcd
--- /dev/null
+++ b/Magick++/lib/Exception.cpp
@@ -0,0 +1,574 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
+//
+// Implementation of Exception and derived classes
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <string>
+#include <errno.h>
+#include <string.h>
+
+using namespace std;
+
+#include "Magick++/Exception.h"
+
+// Construct with message string
+Magick::Exception::Exception( const std::string& what_ )
+ : std::exception(),
+ _what(what_)
+{
+}
+
+// Copy constructor
+Magick::Exception::Exception( const Magick::Exception& original_ )
+ : exception(original_),
+ _what(original_._what)
+{
+}
+
+// Assignment operator
+Magick::Exception& Magick::Exception::operator= (const Magick::Exception& original_ )
+{
+ if(this != &original_)
+ {
+ this->_what = original_._what;
+ }
+ return *this;
+}
+
+// Return message string
+/*virtual*/ const char* Magick::Exception::what( ) const throw()
+{
+ return _what.c_str();
+}
+
+/* Destructor */
+/*virtual*/ Magick::Exception::~Exception ( ) throw ()
+{
+}
+
+//
+// Warnings
+//
+
+Magick::Warning::Warning ( const std::string& what_ )
+ : Exception(what_)
+{
+}
+
+/*virtual*/ Magick::Warning::~Warning ( ) throw ()
+{
+}
+
+Magick::WarningUndefined::WarningUndefined ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningUndefined::~WarningUndefined ( ) throw ()
+{
+}
+
+Magick::WarningBlob::WarningBlob ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningBlob::~WarningBlob ( ) throw ()
+{
+}
+
+Magick::WarningCache::WarningCache ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningCache::~WarningCache ( ) throw ()
+{
+}
+
+Magick::WarningCoder::WarningCoder ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningCoder::~WarningCoder ( ) throw ()
+{
+}
+
+Magick::WarningConfigure::WarningConfigure ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningConfigure::~WarningConfigure ( ) throw ()
+{
+}
+
+Magick::WarningCorruptImage::WarningCorruptImage ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningCorruptImage::~WarningCorruptImage ( ) throw ()
+{
+}
+
+Magick::WarningDelegate::WarningDelegate ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningDelegate::~WarningDelegate ( ) throw ()
+{
+}
+
+Magick::WarningDraw::WarningDraw ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningDraw::~WarningDraw ( ) throw ()
+{
+}
+
+Magick::WarningFileOpen::WarningFileOpen ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningFileOpen::~WarningFileOpen ( ) throw ()
+{
+}
+
+Magick::WarningImage::WarningImage ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningImage::~WarningImage ( ) throw ()
+{
+}
+
+Magick::WarningMissingDelegate::WarningMissingDelegate ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningMissingDelegate::~WarningMissingDelegate ( ) throw ()
+{
+}
+
+Magick::WarningModule::WarningModule ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningModule::~WarningModule ( ) throw ()
+{
+}
+
+Magick::WarningMonitor::WarningMonitor ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningMonitor::~WarningMonitor ( ) throw ()
+{
+}
+
+Magick::WarningOption::WarningOption ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningOption::~WarningOption ( ) throw ()
+{
+}
+
+Magick::WarningRegistry::WarningRegistry ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningRegistry::~WarningRegistry ( ) throw ()
+{
+}
+
+Magick::WarningResourceLimit::WarningResourceLimit ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningResourceLimit::~WarningResourceLimit ( ) throw ()
+{
+}
+
+Magick::WarningStream::WarningStream ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningStream::~WarningStream ( ) throw ()
+{
+}
+
+Magick::WarningType::WarningType ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningType::~WarningType ( ) throw ()
+{
+}
+
+Magick::WarningXServer::WarningXServer ( const std::string& what_ )
+ : Warning(what_)
+{
+}
+
+/*virtual*/ Magick::WarningXServer::~WarningXServer ( ) throw ()
+{
+}
+
+//
+// Errors
+//
+
+Magick::Error::Error ( const std::string& what_ )
+ : Exception(what_)
+{
+}
+
+/*virtual*/ Magick::Error::~Error ( ) throw ()
+{
+}
+
+Magick::ErrorUndefined::ErrorUndefined ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorUndefined::~ErrorUndefined ( ) throw ()
+{
+}
+
+Magick::ErrorBlob::ErrorBlob ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorBlob::~ErrorBlob ( ) throw ()
+{
+}
+
+Magick::ErrorCache::ErrorCache ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorCache::~ErrorCache ( ) throw ()
+{
+}
+
+Magick::ErrorCoder::ErrorCoder ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorCoder::~ErrorCoder ( ) throw ()
+{
+}
+
+Magick::ErrorConfigure::ErrorConfigure ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorConfigure::~ErrorConfigure ( ) throw ()
+{
+}
+
+Magick::ErrorCorruptImage::ErrorCorruptImage ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorCorruptImage::~ErrorCorruptImage ( ) throw ()
+{
+}
+
+Magick::ErrorDelegate::ErrorDelegate ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorDelegate::~ErrorDelegate ( ) throw ()
+{
+}
+
+Magick::ErrorDraw::ErrorDraw ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorDraw::~ErrorDraw ( ) throw ()
+{
+}
+
+Magick::ErrorFileOpen::ErrorFileOpen ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorFileOpen::~ErrorFileOpen ( ) throw ()
+{
+}
+
+Magick::ErrorImage::ErrorImage ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorImage::~ErrorImage ( ) throw ()
+{
+}
+
+Magick::ErrorMissingDelegate::ErrorMissingDelegate ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorMissingDelegate::~ErrorMissingDelegate ( ) throw ()
+{
+}
+
+Magick::ErrorModule::ErrorModule ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorModule::~ErrorModule ( ) throw ()
+{
+}
+
+Magick::ErrorMonitor::ErrorMonitor ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorMonitor::~ErrorMonitor ( ) throw ()
+{
+}
+
+Magick::ErrorOption::ErrorOption ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorOption::~ErrorOption ( ) throw ()
+{
+}
+
+Magick::ErrorRegistry::ErrorRegistry ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorRegistry::~ErrorRegistry ( ) throw ()
+{
+}
+
+Magick::ErrorResourceLimit::ErrorResourceLimit ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorResourceLimit::~ErrorResourceLimit ( ) throw ()
+{
+}
+
+Magick::ErrorStream::ErrorStream ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorStream::~ErrorStream ( ) throw ()
+{
+}
+
+Magick::ErrorType::ErrorType ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorType::~ErrorType ( ) throw ()
+{
+}
+
+Magick::ErrorXServer::ErrorXServer ( const std::string& what_ )
+ : Error(what_)
+{
+}
+
+/*virtual*/ Magick::ErrorXServer::~ErrorXServer ( ) throw ()
+{
+}
+
+// Format and throw exception
+MagickDLLDecl void Magick::throwExceptionExplicit( const ExceptionType severity_,
+ const char* reason_,
+ const char* description_)
+{
+ // Just return if there is no reported error
+ if ( severity_ == UndefinedException )
+ return;
+
+ ExceptionInfo exception;
+
+ GetExceptionInfo( &exception );
+ ThrowException2( &exception, severity_, reason_, description_ );
+ throwException( exception );
+}
+
+// Throw C++ exception, resetting exception argument to default state
+MagickDLLDecl void Magick::throwException( ExceptionInfo &exception_,
+ const bool quiet_)
+{
+ // Just return if there is no reported error
+ if ( exception_.severity == UndefinedException )
+ return;
+
+ // Format error message GraphicsMagick-style
+ std::string message = SetClientName(0);
+ if ( exception_.reason != 0 )
+ {
+ message += std::string(": ");
+ message += std::string(exception_.reason);
+ }
+
+ if ( exception_.description != 0 )
+ message += " (" + std::string(exception_.description) + ")";
+
+ if ( exception_.module != 0)
+ {
+ char line_str[24];
+ sprintf( line_str, "%lu", exception_.line);
+ message += " reported by " + std::string(exception_.module);
+ message += ":" + std::string(line_str);
+ if ((exception_.function != 0) && strcmp("unknown",exception_.function))
+ message += " (" + std::string(exception_.function) + ")";
+ }
+
+ ExceptionType severity = exception_.severity;
+ DestroyExceptionInfo( &exception_ );
+ GetExceptionInfo( &exception_ );
+
+ if ((quiet_) && (severity < ErrorException))
+ return;
+
+ switch ( severity )
+ {
+ // Warnings
+ case ResourceLimitWarning :
+ throw WarningResourceLimit( message );
+ case TypeWarning :
+ throw WarningType( message );
+ case OptionWarning :
+ throw WarningOption( message );
+ case DelegateWarning :
+ throw WarningDelegate( message );
+ case MissingDelegateWarning :
+ throw WarningMissingDelegate( message );
+ case CorruptImageWarning :
+ throw WarningCorruptImage( message );
+ case FileOpenWarning :
+ throw WarningFileOpen( message );
+ case BlobWarning :
+ throw WarningBlob ( message );
+ case StreamWarning :
+ throw WarningStream ( message );
+ case CacheWarning :
+ throw WarningCache ( message );
+ case CoderWarning :
+ throw WarningCoder ( message );
+ case ModuleWarning :
+ throw WarningModule( message );
+ case DrawWarning :
+ throw WarningDraw( message );
+ case ImageWarning :
+ throw WarningImage( message );
+ case XServerWarning :
+ throw WarningXServer( message );
+ case MonitorWarning :
+ throw WarningMonitor( message );
+ case RegistryWarning :
+ throw WarningRegistry( message );
+ case ConfigureWarning :
+ throw WarningConfigure( message );
+ // Errors
+ case ResourceLimitError :
+ case ResourceLimitFatalError :
+ throw ErrorResourceLimit( message );
+ case TypeError :
+ case TypeFatalError :
+ throw ErrorType( message );
+ case OptionError :
+ case OptionFatalError :
+ throw ErrorOption( message );
+ case DelegateError :
+ case DelegateFatalError :
+ throw ErrorDelegate( message );
+ case MissingDelegateError :
+ case MissingDelegateFatalError :
+ throw ErrorMissingDelegate( message );
+ case CorruptImageError :
+ case CorruptImageFatalError :
+ throw ErrorCorruptImage( message );
+ case FileOpenError :
+ case FileOpenFatalError :
+ throw ErrorFileOpen( message );
+ case BlobError :
+ case BlobFatalError :
+ throw ErrorBlob ( message );
+ case StreamError :
+ case StreamFatalError :
+ throw ErrorStream ( message );
+ case CacheError :
+ case CacheFatalError :
+ throw ErrorCache ( message );
+ case CoderError :
+ case CoderFatalError :
+ throw ErrorCoder ( message );
+ case ModuleError :
+ case ModuleFatalError :
+ throw ErrorModule ( message );
+ case DrawError :
+ case DrawFatalError :
+ throw ErrorDraw ( message );
+ case ImageError :
+ case ImageFatalError :
+ throw ErrorImage ( message );
+ case XServerError :
+ case XServerFatalError :
+ throw ErrorXServer ( message );
+ case MonitorError :
+ case MonitorFatalError :
+ throw ErrorMonitor ( message );
+ case RegistryError :
+ case RegistryFatalError :
+ throw ErrorRegistry ( message );
+ case ConfigureError :
+ case ConfigureFatalError :
+ throw ErrorConfigure ( message );
+ case UndefinedException :
+ default :
+ throw ErrorUndefined( message );
+ }
+
+}
diff --git a/Magick++/lib/Functions.cpp b/Magick++/lib/Functions.cpp
new file mode 100644
index 0000000..ab39ea5
--- /dev/null
+++ b/Magick++/lib/Functions.cpp
@@ -0,0 +1,22 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2002, 2003
+//
+// Simple C++ function wrappers for ImageMagick equivalents
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <string>
+
+using namespace std;
+
+#include "Magick++/Functions.h"
+
+// Clone C++ string as allocated C string, de-allocating any existing string
+void Magick::CloneString( char **destination_, const std::string &source_ )
+{
+ MagickLib::CloneString( destination_, source_.c_str() );
+}
diff --git a/Magick++/lib/Geometry.cpp b/Magick++/lib/Geometry.cpp
new file mode 100644
index 0000000..9b0d39c
--- /dev/null
+++ b/Magick++/lib/Geometry.cpp
@@ -0,0 +1,519 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999 - 2014
+//
+// Geometry implementation
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <string>
+#include <ctype.h> // for isdigit
+#include <string.h> // for strcpy
+#include <cassert>
+
+using namespace std;
+
+#include "Magick++/Geometry.h"
+#include "Magick++/Exception.h"
+
+#define AbsoluteValue(x) ((x) < 0 ? -(x) : (x))
+
+// Does object contain valid geometry?
+void Magick::Geometry::isValid ( bool isValid_ )
+{
+ _flags._b._isValid = isValid_;
+}
+
+bool Magick::Geometry::isValid ( void ) const
+{
+ return _flags._b._isValid;
+}
+
+// Width
+void Magick::Geometry::width ( unsigned int width_ )
+{
+ _width = width_;
+ isValid( true );
+}
+unsigned int Magick::Geometry::width ( void ) const
+{
+ return _width;
+}
+
+// Height
+void Magick::Geometry::height ( unsigned int height_ )
+{
+ _height = height_;
+}
+unsigned int Magick::Geometry::height ( void ) const
+{
+ return _height;
+}
+
+// X offset from origin
+void Magick::Geometry::xOff ( unsigned int xOff_ )
+{
+ _xOff = xOff_;
+}
+unsigned int Magick::Geometry::xOff ( void ) const
+{
+ return _xOff;
+}
+
+// Y offset from origin
+void Magick::Geometry::yOff ( unsigned int yOff_ )
+{
+ _yOff = yOff_;
+}
+unsigned int Magick::Geometry::yOff ( void ) const
+{
+ return _yOff;
+}
+
+// Sign of X offset negative? (X origin at right)
+void Magick::Geometry::xNegative ( bool xNegative_ )
+{
+ _flags._b._xNegative = xNegative_;
+}
+bool Magick::Geometry::xNegative ( void ) const
+{
+ return _flags._b._xNegative;
+}
+
+// Sign of Y offset negative? (Y origin at bottom)
+void Magick::Geometry::yNegative ( bool yNegative_ )
+{
+ _flags._b._yNegative = yNegative_;
+}
+bool Magick::Geometry::yNegative ( void ) const
+{
+ return _flags._b._yNegative;
+}
+
+// Interpret width & height as percentages (%)
+void Magick::Geometry::percent ( bool percent_ )
+{
+ _flags._b._percent = percent_;
+}
+bool Magick::Geometry::percent ( void ) const
+{
+ return _flags._b._percent;
+}
+
+// Resize without preserving aspect ratio (!)
+void Magick::Geometry::aspect ( bool aspect_ )
+{
+ _flags._b._aspect = aspect_;
+}
+bool Magick::Geometry::aspect ( void ) const
+{
+ return _flags._b._aspect;
+}
+
+// Resize if image is greater than size (>)
+void Magick::Geometry::greater ( bool greater_ )
+{
+ _flags._b._greater = greater_;
+}
+bool Magick::Geometry::greater ( void ) const
+{
+ return _flags._b._greater;
+}
+
+// Resize if image is less than size (<)
+void Magick::Geometry::less ( bool less_ )
+{
+ _flags._b._less = less_;
+}
+bool Magick::Geometry::less ( void ) const
+{
+ return _flags._b._less;
+}
+
+// Resize image to fit total pixel area specified by dimensions (@).
+void Magick::Geometry::limitPixels ( bool limitPixels_ )
+{
+ _flags._b._limitPixels = limitPixels_;
+}
+bool Magick::Geometry::limitPixels ( void ) const
+{
+ return _flags._b._limitPixels;
+}
+
+// Resize image to fit a set of dimensions
+void Magick::Geometry::fillArea ( bool fillArea_ )
+{
+ _flags._b._fillArea = fillArea_;
+}
+bool Magick::Geometry::fillArea ( void ) const
+{
+ return _flags._b._fillArea;
+}
+
+
+int Magick::operator == ( const Magick::Geometry& left_,
+ const Magick::Geometry& right_ )
+{
+ return (
+ ( left_.isValid() == right_.isValid() ) &&
+ ( left_.width() == right_.width() ) &&
+ ( left_.height() == right_.height() ) &&
+ ( left_.xOff() == right_.xOff() ) &&
+ ( left_.yOff() == right_.yOff() ) &&
+ ( left_.xNegative() == right_.xNegative() ) &&
+ ( left_.yNegative() == right_.yNegative() ) &&
+ ( left_.percent() == right_.percent() ) &&
+ ( left_.aspect() == right_.aspect() ) &&
+ ( left_.greater() == right_.greater() ) &&
+ ( left_.less() == right_.less() ) &&
+ ( left_.limitPixels() == right_.limitPixels() ) &&
+ ( left_.fillArea() == right_.fillArea() )
+ );
+}
+int Magick::operator != ( const Magick::Geometry& left_,
+ const Magick::Geometry& right_ )
+{
+ return ( ! (left_ == right_) );
+}
+int Magick::operator > ( const Magick::Geometry& left_,
+ const Magick::Geometry& right_ )
+{
+ return ( !( left_ < right_ ) && ( left_ != right_ ) );
+}
+int Magick::operator < ( const Magick::Geometry& left_,
+ const Magick::Geometry& right_ )
+{
+ return (
+ ( left_.width() * left_.height() )
+ <
+ ( right_.width() * right_.height() )
+ );
+}
+int Magick::operator >= ( const Magick::Geometry& left_,
+ const Magick::Geometry& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+int Magick::operator <= ( const Magick::Geometry& left_,
+ const Magick::Geometry& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+
+// Construct using parameterized arguments
+Magick::Geometry::Geometry ( unsigned int width_,
+ unsigned int height_,
+ unsigned int xOff_,
+ unsigned int yOff_,
+ bool xNegative_,
+ bool yNegative_ )
+ : _width( width_ ),
+ _height( height_ ),
+ _xOff( xOff_ ),
+ _yOff( yOff_ )
+{
+ xNegative( xNegative_ );
+ yNegative( yNegative_ );
+ isValid( true );
+ percent( false );
+ aspect( false );
+ greater( false );
+ less( false );
+ limitPixels (false );
+ fillArea( false );
+}
+
+// Assignment from C++ string
+Magick::Geometry::Geometry ( const std::string &geometry_ )
+ : _width( 0 ),
+ _height( 0 ),
+ _xOff( 0 ),
+ _yOff( 0 )
+{
+ assert(sizeof(_flags._padding) >= sizeof(_flags._b));
+ xNegative( false );
+ yNegative( false );
+ isValid( false );
+ percent( false );
+ aspect( false );
+ greater( false );
+ less( false );
+ limitPixels (false );
+ fillArea( false );
+ *this = geometry_; // Use assignment operator
+}
+
+
+// Assignment from C character string
+Magick::Geometry::Geometry ( const char *geometry_ )
+ : _width( 0 ),
+ _height( 0 ),
+ _xOff( 0 ),
+ _yOff( 0 )
+{
+ xNegative( false );
+ yNegative( false );
+ isValid( false );
+ percent( false );
+ aspect( false );
+ greater( false );
+ less( false );
+ limitPixels ( false );
+ fillArea( false );
+ *this = geometry_; // Use assignment operator
+}
+
+// Copy constructor
+Magick::Geometry::Geometry ( const Geometry &geometry_ )
+ : _width( geometry_._width ),
+ _height( geometry_._height ),
+ _xOff( geometry_._xOff ),
+ _yOff( geometry_._yOff )
+{
+ xNegative( geometry_.xNegative() );
+ yNegative( geometry_.yNegative() );
+ isValid ( geometry_.isValid() );
+ percent( geometry_.percent() );
+ aspect( geometry_.aspect() );
+ greater( geometry_.greater() );
+ less( geometry_.less() );
+ limitPixels( geometry_.limitPixels() );
+ fillArea( geometry_.fillArea() );
+}
+
+// Default constructor
+Magick::Geometry::Geometry ( void )
+ : _width( 0 ),
+ _height( 0 ),
+ _xOff( 0 ),
+ _yOff( 0 )
+{
+ assert(sizeof(_flags._padding) >= sizeof(_flags._b));
+ xNegative( false );
+ yNegative( false );
+ isValid ( false );
+ percent( false );
+ aspect( false );
+ greater( false );
+ less( false );
+ limitPixels( false );
+ fillArea( false );
+}
+
+/* virtual */ Magick::Geometry::~Geometry ( void )
+{
+ // Nothing to do
+}
+
+Magick::Geometry& Magick::Geometry::operator = ( const Geometry& geometry_ )
+{
+ // If not being set to ourself
+ if ( this != &geometry_ )
+ {
+ _width = geometry_._width;
+ _height = geometry_._height;
+ _xOff = geometry_._xOff;
+ _yOff = geometry_._yOff;
+
+ xNegative( geometry_.xNegative() );
+ yNegative( geometry_.yNegative() );
+ isValid ( geometry_.isValid() );
+ percent( geometry_.percent() );
+ aspect( geometry_.aspect() );
+ greater( geometry_.greater() );
+ less( geometry_.less() );
+ limitPixels( geometry_.limitPixels() );
+ fillArea( geometry_.fillArea() );
+ }
+ return *this;
+}
+
+// Set value via geometry string
+/* virtual */ const Magick::Geometry&
+Magick::Geometry::operator = ( const std::string &geometry_ )
+{
+ char
+ geom[MaxTextExtent];
+
+ // If argument does not start with digit, presume that it is a
+ // page-size specification that needs to be converted to an
+ // equivalent geometry specification using PostscriptGeometry()
+ strlcpy(geom,geometry_.c_str(),sizeof(geom));
+ if ( geom[0] != '-' &&
+ geom[0] != '+' &&
+ geom[0] != 'x' &&
+ !isdigit(static_cast<int>(geom[0])))
+ {
+ char *pageptr = GetPageGeometry( geom );
+ if ( pageptr != 0 )
+ {
+ strlcpy(geom,pageptr,sizeof(geom));
+ MagickFreeMemory(pageptr);
+ }
+ }
+
+ long x = 0;
+ long y = 0;
+ unsigned long width_val = 0;
+ unsigned long height_val = 0;
+ int flags = GetGeometry (geom, &x, &y, &width_val, &height_val );
+
+ if (flags == NoValue)
+ {
+ // Total failure!
+ *this=Geometry();
+ isValid( false );
+ return *this;
+ }
+
+ if ( ( flags & WidthValue ) != 0 )
+ {
+ width( width_val );
+ isValid( true );
+ }
+
+ if ( ( flags & HeightValue ) != 0 )
+ height( height_val );
+
+ if ( ( flags & XValue ) != 0 )
+ {
+ xOff( static_cast<unsigned int>(AbsoluteValue(x)) );
+ isValid( true );
+ }
+
+ if ( ( flags & YValue ) != 0 )
+ {
+ yOff( static_cast<unsigned int>(AbsoluteValue(y)) );
+ isValid( true );
+ }
+
+ if ( ( flags & XNegative ) != 0 )
+ xNegative( true );
+
+ if ( ( flags & YNegative ) != 0 )
+ yNegative( true );
+
+ if ( ( flags & PercentValue ) != 0 ) // '%'
+ percent( true );
+
+ if ( ( flags & AspectValue ) != 0 ) // '!'
+ aspect( true );
+
+ if ( ( flags & LessValue ) != 0 ) // '<'
+ less( true );
+
+ if ( ( flags & GreaterValue ) != 0 ) // '>'
+ greater( true );
+
+ if ( ( flags & AreaValue ) != 0 ) // '@'
+ limitPixels( true );
+
+ if ( ( flags & MinimumValue ) != 0 ) // '^'
+ fillArea( true );
+
+ return *this;
+}
+
+
+// Set value via geometry C string
+/* virtual */ const Magick::Geometry& Magick::Geometry::operator = ( const char * geometry_ )
+{
+ *this = std::string(geometry_);
+ return *this;
+}
+
+// Return geometry string
+Magick::Geometry::operator std::string() const
+{
+ if (!isValid())
+ {
+ throwExceptionExplicit( OptionError, "Invalid geometry argument" );
+ }
+
+ string geometry;
+ char buffer[MaxTextExtent];
+
+ if ( _width )
+ {
+ FormatString( buffer, "%u", _width );
+ geometry += buffer;
+ }
+
+ if ( _width && _height )
+ {
+ FormatString( buffer, "%u", _height);
+ geometry += 'x';
+ geometry += buffer;
+ }
+
+ if ( _xOff || _yOff )
+ {
+ if ( xNegative() )
+ geometry += '-';
+ else
+ geometry += '+';
+
+ FormatString( buffer, "%u", _xOff);
+ geometry += buffer;
+
+ if ( yNegative() )
+ geometry += '-';
+ else
+ geometry += '+';
+
+ FormatString( buffer, "%u", _yOff);
+ geometry += buffer;
+ }
+
+ if ( percent() )
+ geometry += '%';
+
+ if ( aspect() )
+ geometry += '!';
+
+ if ( greater() )
+ geometry += '>';
+
+ if ( less() )
+ geometry += '<';
+
+ if ( limitPixels() )
+ geometry += '@';
+
+ if ( fillArea() )
+ geometry += '^';
+
+ return geometry;
+}
+
+// Construct from RectangleInfo
+Magick::Geometry::Geometry ( const MagickLib::RectangleInfo &rectangle_ )
+ : _width(static_cast<unsigned int>(rectangle_.width)),
+ _height(static_cast<unsigned int>(rectangle_.height)),
+ _xOff(static_cast<unsigned int>(AbsoluteValue(rectangle_.x))),
+ _yOff(static_cast<unsigned int>(AbsoluteValue(rectangle_.y)))
+{
+ xNegative(rectangle_.x < 0 ? true : false);
+ yNegative(rectangle_.y < 0 ? true : false);
+ isValid(true);
+ percent(false);
+ aspect(false);
+ greater(false);
+ less(false);
+ limitPixels(false);
+ fillArea(false);
+}
+
+// Return an ImageMagick RectangleInfo struct
+Magick::Geometry::operator MagickLib::RectangleInfo() const
+{
+ RectangleInfo rectangle;
+ rectangle.width = _width;
+ rectangle.height = _height;
+ xNegative() ? rectangle.x = static_cast<long>(0-_xOff) : rectangle.x = static_cast<long>(_xOff);
+ yNegative() ? rectangle.y = static_cast<long>(0-_yOff) : rectangle.y = static_cast<long>(_yOff);
+ return rectangle;
+}
diff --git a/Magick++/lib/GraphicsMagick++.pc.in b/Magick++/lib/GraphicsMagick++.pc.in
new file mode 100644
index 0000000..cb4f616
--- /dev/null
+++ b/Magick++/lib/GraphicsMagick++.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/GraphicsMagick
+
+
+Name: GraphicsMagick++
+Version: @PACKAGE_VERSION@
+Description: C++ API for GraphicsMagick image processing library
+Requires: GraphicsMagick
+Libs: -lGraphicsMagick++
+Cflags:
diff --git a/Magick++/lib/Image.cpp b/Magick++/lib/Image.cpp
new file mode 100644
index 0000000..01b9f79
--- /dev/null
+++ b/Magick++/lib/Image.cpp
@@ -0,0 +1,4165 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999-2017
+//
+// Implementation of Image
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <cstdlib>
+#include <string>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <string.h> // for strcpy
+
+using namespace std;
+
+#include "Magick++/Image.h"
+#include "Magick++/Functions.h"
+#include "Magick++/Pixels.h"
+#include "Magick++/Options.h"
+#include "Magick++/ImageRef.h"
+
+#define AbsoluteValue(x) ((x) < 0 ? -(x) : (x))
+
+// MagickDLLDeclExtern const std::string Magick::borderGeometryDefault = "6x6+0+0";
+// MagickDLLDeclExtern const std::string Magick::frameGeometryDefault = "25x25+6+6";
+// MagickDLLDeclExtern const std::string Magick::raiseGeometryDefault = "6x6+0+0";
+
+MagickDLLDeclExtern const char *Magick::borderGeometryDefault = "6x6+0+0";
+MagickDLLDeclExtern const char *Magick::frameGeometryDefault = "25x25+6+6";
+MagickDLLDeclExtern const char *Magick::raiseGeometryDefault = "6x6+0+0";
+
+static bool magick_initialized=false;
+
+//
+// Explicit template instantiations
+//
+
+//
+// Friend functions to compare Image objects
+//
+
+MagickDLLDecl int Magick::operator == ( const Magick::Image& left_,
+ const Magick::Image& right_ )
+{
+ // If image pixels and signature are the same, then the image is identical
+ return ( ( left_.rows() == right_.rows() ) &&
+ ( left_.columns() == right_.columns() ) &&
+ ( left_.signature() == right_.signature() )
+ );
+}
+MagickDLLDecl int Magick::operator != ( const Magick::Image& left_,
+ const Magick::Image& right_ )
+{
+ return ( ! (left_ == right_) );
+}
+MagickDLLDecl int Magick::operator > ( const Magick::Image& left_,
+ const Magick::Image& right_ )
+{
+ return ( !( left_ < right_ ) && ( left_ != right_ ) );
+}
+MagickDLLDecl int Magick::operator < ( const Magick::Image& left_,
+ const Magick::Image& right_ )
+{
+ // If image pixels are less, then image is smaller
+ return ( ( left_.rows() * left_.columns() ) <
+ ( right_.rows() * right_.columns() )
+ );
+}
+MagickDLLDecl int Magick::operator >= ( const Magick::Image& left_,
+ const Magick::Image& right_ )
+{
+ return ( ( left_ > right_ ) || ( left_ == right_ ) );
+}
+MagickDLLDecl int Magick::operator <= ( const Magick::Image& left_,
+ const Magick::Image& right_ )
+{
+ return ( ( left_ < right_ ) || ( left_ == right_ ) );
+}
+
+//
+// Image object implementation
+//
+
+// Construct from image file or image specification
+Magick::Image::Image( const std::string &imageSpec_ )
+ : _imgRef(new ImageRef)
+{
+ try
+ {
+ // Initialize, Allocate and Read images
+ read( imageSpec_ );
+ }
+ catch ( const Warning & /*warning_*/ )
+ {
+ // FIXME: need a way to report warnings in constructor
+ }
+ catch ( const Error & /* error_ */ )
+ {
+ // Release resources
+ delete _imgRef;
+ throw;
+ }
+}
+
+// Construct a blank image canvas of specified size and color
+Magick::Image::Image( const Geometry &size_,
+ const Color &color_ )
+ : _imgRef(new ImageRef)
+{
+ // xc: prefix specifies an X11 color string
+ std::string imageSpec("xc:");
+ imageSpec += color_;
+
+ try
+ {
+ // Set image size
+ size( size_ );
+
+ // Initialize, Allocate and Read images
+ read( imageSpec );
+ }
+ catch ( const Warning & /*warning_*/ )
+ {
+ // FIXME: need a way to report warnings in constructor
+ }
+ catch ( const Error & /* error_ */ )
+ {
+ // Release resources
+ delete _imgRef;
+ throw;
+ }
+}
+
+// Construct Image from in-memory BLOB
+Magick::Image::Image ( const Blob &blob_ )
+ : _imgRef(new ImageRef)
+{
+ try
+ {
+ // Initialize, Allocate and Read images
+ read( blob_ );
+ }
+ catch ( const Warning & /*warning_*/ )
+ {
+ // FIXME: need a way to report warnings in constructor
+ }
+ catch ( const Error & /* error_ */ )
+ {
+ // Release resources
+ delete _imgRef;
+ throw;
+ }
+}
+
+// Construct Image of specified size from in-memory BLOB
+Magick::Image::Image ( const Blob &blob_,
+ const Geometry &size_ )
+ : _imgRef(new ImageRef)
+{
+ try
+ {
+ // Read from Blob
+ read( blob_, size_ );
+ }
+ catch ( const Warning & /*warning_*/ )
+ {
+ // FIXME: need a way to report warnings in constructor
+ }
+ catch ( const Error & /* error_ */ )
+ {
+ // Release resources
+ delete _imgRef;
+ throw;
+ }
+}
+
+// Construct Image of specified size and depth from in-memory BLOB
+Magick::Image::Image ( const Blob &blob_,
+ const Geometry &size_,
+ const unsigned int depth_ )
+ : _imgRef(new ImageRef)
+{
+ try
+ {
+ // Read from Blob
+ read( blob_, size_, depth_ );
+ }
+ catch ( const Warning & /*warning_*/ )
+ {
+ // FIXME: need a way to report warnings in constructor
+ }
+ catch ( const Error & /* error_ */ )
+ {
+ // Release resources
+ delete _imgRef;
+ throw;
+ }
+}
+
+// Construct Image of specified size, depth, and format from in-memory BLOB
+Magick::Image::Image ( const Blob &blob_,
+ const Geometry &size_,
+ const unsigned int depth_,
+ const std::string &magick_ )
+ : _imgRef(new ImageRef)
+{
+ try
+ {
+ // Read from Blob
+ read( blob_, size_, depth_, magick_ );
+ }
+ catch ( const Warning & /*warning_*/ )
+ {
+ // FIXME: need a way to report warnings in constructor
+ }
+ catch ( const Error & /* error_ */ )
+ {
+ // Release resources
+ delete _imgRef;
+ throw;
+ }
+}
+
+// Construct Image of specified size, and format from in-memory BLOB
+Magick::Image::Image ( const Blob &blob_,
+ const Geometry &size_,
+ const std::string &magick_ )
+ : _imgRef(new ImageRef)
+{
+ try
+ {
+ // Read from Blob
+ read( blob_, size_, magick_ );
+ }
+ catch ( const Warning & /*warning_*/ )
+ {
+ // FIXME: need a way to report warnings in constructor
+ }
+ catch ( const Error & /* error_ */ )
+ {
+ // Release resources
+ delete _imgRef;
+ throw;
+ }
+}
+
+// Construct an image based on an array of raw pixels, of specified
+// type and mapping, in memory
+Magick::Image::Image ( const unsigned int width_,
+ const unsigned int height_,
+ const std::string &map_,
+ const StorageType type_,
+ const void *pixels_ )
+ : _imgRef(new ImageRef)
+{
+ try
+ {
+ read( width_, height_, map_.c_str(), type_, pixels_ );
+ }
+ catch ( const Warning & /*warning_*/ )
+ {
+ // FIXME: need a way to report warnings in constructor
+ }
+ catch ( const Error & /* error_ */ )
+ {
+ // Release resources
+ delete _imgRef;
+ throw;
+ }
+}
+
+// Default constructor
+Magick::Image::Image( void )
+ : _imgRef(new ImageRef)
+{
+}
+
+// Destructor
+/* virtual */
+Magick::Image::~Image()
+{
+ bool doDelete = false;
+ {
+ Lock lock( &_imgRef->_mutexLock );
+ if ( --_imgRef->_refCount == 0 )
+ doDelete = true;
+ }
+
+ if ( doDelete )
+ {
+ delete _imgRef;
+ }
+ _imgRef = 0;
+}
+
+// Local adaptive threshold image
+// http://www.dai.ed.ac.uk/HIPR2/adpthrsh.htm
+// Width x height define the size of the pixel neighborhood
+// offset = constant to subtract from pixel neighborhood mean
+void Magick::Image::adaptiveThreshold ( const unsigned int width_,
+ const unsigned int height_,
+ const double offset_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ AdaptiveThresholdImage( constImage(), width_, height_, offset_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+// Local adaptive threshold image
+// http://www.dai.ed.ac.uk/HIPR2/adpthrsh.htm
+// Width x height define the size of the pixel neighborhood
+// offset = constant to subtract from pixel neighborhood mean
+// This version is deprecated and subject to future deletion.
+void Magick::Image::adaptiveThreshold ( const unsigned int width_,
+ const unsigned int height_,
+ const unsigned int offset_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ AdaptiveThresholdImage( constImage(), width_, height_, offset_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Add noise to image
+void Magick::Image::addNoise( const NoiseType noiseType_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ AddNoiseImage ( image(),
+ noiseType_,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::addNoiseChannel( const ChannelType channel_,
+ const NoiseType noiseType_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ AddNoiseImageChannel ( image(),
+ channel_,
+ noiseType_,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Affine Transform image
+void Magick::Image::affineTransform ( const DrawableAffine &affine_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+
+ AffineMatrix _affine;
+ _affine.sx = affine_.sx();
+ _affine.sy = affine_.sy();
+ _affine.rx = affine_.rx();
+ _affine.ry = affine_.ry();
+ _affine.tx = affine_.tx();
+ _affine.ty = affine_.ty();
+
+ MagickLib::Image* newImage =
+ AffineTransformImage( image(), &_affine, &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Annotate using specified text, and placement location
+void Magick::Image::annotate ( const std::string &text_,
+ const Geometry &location_ )
+{
+ annotate ( text_, location_, NorthWestGravity, 0.0 );
+}
+// Annotate using specified text, bounding area, and placement gravity
+void Magick::Image::annotate ( const std::string &text_,
+ const Geometry &boundingArea_,
+ const GravityType gravity_ )
+{
+ annotate ( text_, boundingArea_, gravity_, 0.0 );
+}
+// Annotate with text using specified text, bounding area, placement
+// gravity, and rotation.
+void Magick::Image::annotate ( const std::string &text_,
+ const Geometry &boundingArea_,
+ const GravityType gravity_,
+ const double degrees_ )
+{
+ modifyImage();
+
+ DrawInfo *drawInfo
+ = options()->drawInfo();
+
+ drawInfo->text = const_cast<char *>(text_.c_str());
+
+ char boundingArea[MaxTextExtent];
+
+ drawInfo->geometry = 0;
+ if ( boundingArea_.isValid() ){
+ if ( boundingArea_.width() == 0 || boundingArea_.height() == 0 )
+ {
+ FormatString( boundingArea, "+%u+%u",
+ boundingArea_.xOff(), boundingArea_.yOff() );
+ }
+ else
+ {
+ strlcpy( boundingArea, string(boundingArea_).c_str(),
+ sizeof(boundingArea));
+ }
+ drawInfo->geometry = boundingArea;
+ }
+
+ drawInfo->gravity = gravity_;
+
+ AffineMatrix oaffine = drawInfo->affine;
+ if ( degrees_ != 0.0)
+ {
+ AffineMatrix affine;
+ affine.sx=1.0;
+ affine.rx=0.0;
+ affine.ry=0.0;
+ affine.sy=1.0;
+ affine.tx=0.0;
+ affine.ty=0.0;
+
+ AffineMatrix current = drawInfo->affine;
+#define DegreesToRadians(x) ((x)*3.14159265358979323846/180.0)
+ affine.sx=cos(DegreesToRadians(fmod(degrees_,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(degrees_,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(degrees_,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(degrees_,360.0)));
+
+ drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty
+ +current.tx;
+ }
+
+ AnnotateImage( image(), drawInfo );
+
+ // Restore original values
+ drawInfo->affine = oaffine;
+ drawInfo->text = 0;
+ drawInfo->geometry = 0;
+
+ throwImageException();
+}
+// Annotate with text (bounding area is entire image) and placement gravity.
+void Magick::Image::annotate ( const std::string &text_,
+ const GravityType gravity_ )
+{
+ modifyImage();
+
+ DrawInfo *drawInfo
+ = options()->drawInfo();
+
+ drawInfo->text = const_cast<char *>(text_.c_str());
+
+ drawInfo->gravity = gravity_;
+
+ AnnotateImage( image(), drawInfo );
+
+ drawInfo->gravity = NorthWestGravity;
+ drawInfo->text = 0;
+
+ throwImageException();
+}
+
+// Blur image
+void Magick::Image::blur( const double radius_, const double sigma_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ BlurImage( image(), radius_, sigma_, &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::blurChannel( const ChannelType channel_,
+ const double radius_, const double sigma_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ BlurImageChannel( image(), channel_,radius_, sigma_, &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Add border to image
+// Only uses width & height
+void Magick::Image::border( const Geometry &geometry_ )
+{
+ RectangleInfo borderInfo = geometry_;
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ BorderImage( image(), &borderInfo, &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Bake in the ASC-CDL, which is a convention for the for the exchange
+// of basic primary color grading information between for the exchange
+// of basic primary color grading information between equipment and
+// software from different manufacturers. It is a useful transform
+// for other purposes as well.
+void Magick::Image::cdl ( const std::string &cdl_ )
+{
+ modifyImage();
+ (void) CdlImage( image(), cdl_.c_str() );
+ throwImageException();
+}
+
+// Extract channel from image
+void Magick::Image::channel ( const ChannelType channel_ )
+{
+ modifyImage();
+ ChannelImage ( image(), channel_ );
+ throwImageException();
+}
+
+// Set or obtain modulus channel depth
+void Magick::Image::channelDepth ( const ChannelType channel_,
+ const unsigned int depth_)
+{
+ modifyImage();
+ SetImageChannelDepth( image(), channel_, depth_);
+ throwImageException();
+}
+unsigned int Magick::Image::channelDepth ( const ChannelType channel_ )
+{
+ unsigned int channel_depth;
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ channel_depth=GetImageChannelDepth( constImage(), channel_,
+ &exceptionInfo );
+ throwImageException( exceptionInfo );
+ return channel_depth;
+}
+
+
+// Charcoal-effect image
+void Magick::Image::charcoal( const double radius_, const double sigma_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ CharcoalImage( image(), radius_, sigma_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Chop image
+void Magick::Image::chop( const Geometry &geometry_ )
+{
+ RectangleInfo chopInfo = geometry_;
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ChopImage( image(), &chopInfo, &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Colorize
+void Magick::Image::colorize ( const unsigned int opacityRed_,
+ const unsigned int opacityGreen_,
+ const unsigned int opacityBlue_,
+ const Color &penColor_ )
+{
+ if ( !penColor_.isValid() )
+ {
+ throwExceptionExplicit( OptionError,
+ "Pen color argument is invalid");
+ }
+
+ char opacity[MaxTextExtent];
+ FormatString(opacity,"%u/%u/%u",opacityRed_,opacityGreen_,opacityBlue_);
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ColorizeImage ( image(), opacity,
+ penColor_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::colorize ( const unsigned int opacity_,
+ const Color &penColor_ )
+{
+ colorize( opacity_, opacity_, opacity_, penColor_ );
+}
+
+// Apply a color matrix to the image channels. The user supplied
+// matrix may be of order 1 to 5 (1x1 through 5x5).
+void Magick::Image::colorMatrix (const unsigned int order_,
+ const double *color_matrix_)
+{
+ modifyImage();
+ (void) ColorMatrixImage(image(),order_,color_matrix_);
+ throwImageException();
+}
+
+// Compare current image with another image
+// Sets meanErrorPerPixel, normalizedMaxError, and normalizedMeanError
+// in the current image. False is returned if the images are identical.
+bool Magick::Image::compare ( const Image &reference_ )
+{
+ modifyImage();
+ Image ref = reference_;
+ ref.modifyImage();
+ return static_cast<bool>(IsImagesEqual(image(), ref.image()));
+}
+
+// Composite two images
+void Magick::Image::composite ( const Image &compositeImage_,
+ const int xOffset_,
+ const int yOffset_,
+ const CompositeOperator compose_ )
+{
+ // Image supplied as compositeImage is composited with current image and
+ // results in updating current image.
+ modifyImage();
+
+ CompositeImage( image(),
+ compose_,
+ compositeImage_.constImage(),
+ xOffset_,
+ yOffset_ );
+ throwImageException();
+}
+void Magick::Image::composite ( const Image &compositeImage_,
+ const Geometry &offset_,
+ const CompositeOperator compose_ )
+{
+ modifyImage();
+
+ long x = offset_.xOff();
+ long y = offset_.yOff();
+ unsigned long width = columns();
+ unsigned long height = rows();
+
+ GetMagickGeometry (static_cast<std::string>(offset_).c_str(),
+ &x, &y,
+ &width, &height );
+
+ CompositeImage( image(),
+ compose_,
+ compositeImage_.constImage(),
+ x, y );
+ throwImageException();
+}
+void Magick::Image::composite ( const Image &compositeImage_,
+ const GravityType gravity_,
+ const CompositeOperator compose_ )
+{
+ modifyImage();
+
+ long x = 0;
+ long y = 0;
+
+ switch (gravity_)
+ {
+ case NorthWestGravity:
+ {
+ x = 0;
+ y = 0;
+ break;
+ }
+ case NorthGravity:
+ {
+ x = (columns() - compositeImage_.columns()) >> 1;
+ y = 0;
+ break;
+ }
+ case NorthEastGravity:
+ {
+ x = static_cast<long>(columns() - compositeImage_.columns());
+ y = 0;
+ break;
+ }
+ case WestGravity:
+ {
+ x = 0;
+ y = (rows() - compositeImage_.rows()) >> 1;
+ break;
+ }
+ case ForgetGravity:
+ case StaticGravity:
+ case CenterGravity:
+ default:
+ {
+ x = (columns() - compositeImage_.columns()) >> 1;
+ y = (rows() - compositeImage_.rows()) >> 1;
+ break;
+ }
+ case EastGravity:
+ {
+ x = static_cast<long>(columns() - compositeImage_.columns());
+ y = (rows() - compositeImage_.rows()) >> 1;
+ break;
+ }
+ case SouthWestGravity:
+ {
+ x = 0;
+ y = static_cast<long>(rows() - compositeImage_.rows());
+ break;
+ }
+ case SouthGravity:
+ {
+ x = (columns() - compositeImage_.columns()) >> 1;
+ y = static_cast<long>(rows() - compositeImage_.rows());
+ break;
+ }
+ case SouthEastGravity:
+ {
+ x = static_cast<long>(columns() - compositeImage_.columns());
+ y = static_cast<long>(rows() - compositeImage_.rows());
+ break;
+ }
+ }
+
+ CompositeImage( image(),
+ compose_,
+ compositeImage_.constImage(),
+ x, y );
+ throwImageException();
+}
+
+// Contrast image
+void Magick::Image::contrast ( const unsigned int sharpen_ )
+{
+ modifyImage();
+ ContrastImage ( image(), sharpen_ );
+ throwImageException();
+}
+
+// Convolve image. Applies a general image convolution kernel to the image.
+// order_ represents the number of columns and rows in the filter kernel.
+// kernel_ is an array of doubles representing the convolution kernel.
+void Magick::Image::convolve ( const unsigned int order_,
+ const double *kernel_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ConvolveImage ( image(), order_,
+ kernel_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Crop image
+void Magick::Image::crop ( const Geometry &geometry_ )
+{
+ RectangleInfo cropInfo = geometry_;
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ CropImage( image(),
+ &cropInfo,
+ &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Cycle Color Map
+void Magick::Image::cycleColormap ( const int amount_ )
+{
+ modifyImage();
+ CycleColormapImage( image(), amount_ );
+ throwImageException();
+}
+
+// Despeckle
+void Magick::Image::despeckle ( void )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ DespeckleImage( image(), &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Display image
+void Magick::Image::display( void )
+{
+ DisplayImages( imageInfo(), image() );
+}
+
+// Draw on image using single drawable
+void Magick::Image::draw ( const Magick::Drawable &drawable_ )
+{
+ modifyImage();
+
+ DrawContext context = DrawAllocateContext( options()->drawInfo(), image());
+
+ if(context)
+ {
+ drawable_.operator()(context);
+
+ if( constImage()->exception.severity == UndefinedException)
+ DrawRender(context);
+
+ DrawDestroyContext(context);
+ }
+
+ throwImageException();
+}
+
+// Draw on image using a drawable list
+void Magick::Image::draw ( const std::list<Magick::Drawable> &drawable_ )
+{
+ modifyImage();
+
+ DrawContext context = DrawAllocateContext( options()->drawInfo(), image());
+
+ if(context)
+ {
+ for( std::list<Magick::Drawable>::const_iterator p = drawable_.begin();
+ p != drawable_.end(); p++ )
+ {
+ p->operator()(context);
+ if( constImage()->exception.severity != UndefinedException)
+ break;
+ }
+
+ if( constImage()->exception.severity == UndefinedException)
+ DrawRender(context);
+
+ DrawDestroyContext(context);
+ }
+
+ throwImageException();
+}
+
+// Hilight edges in image
+void Magick::Image::edge ( const double radius_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ EdgeImage( image(), radius_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Emboss image (hilight edges)
+void Magick::Image::emboss ( const double radius_, const double sigma_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ EmbossImage( image(), radius_, sigma_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Enhance image (minimize noise)
+void Magick::Image::enhance ( void )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ EnhanceImage( image(), &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Equalize image (histogram equalization)
+void Magick::Image::equalize ( void )
+{
+ modifyImage();
+ EqualizeImage( image() );
+ throwImageException();
+}
+
+// Erase image to current "background color"
+void Magick::Image::erase ( void )
+{
+ modifyImage();
+ SetImage( image(), OpaqueOpacity );
+ throwImageException();
+}
+
+// Create an image canvas using background color sized according to
+// geometry and composite existing image on it, with image placement
+// controlled by gravity. Parameters are obtained from existing image
+// properties if they are not specified via a method parameter.
+// Parameters which are supported by image properties (gravity and
+// backgroundColor) update those image properties as a side-effect.
+void Magick::Image::extent ( const Geometry &geometry_ )
+{
+ RectangleInfo geometry;
+
+ (void) GetImageGeometry(image(),
+ static_cast<std::string>(geometry_).c_str(),
+ MagickFalse, &geometry);
+ if (geometry.width == 0)
+ geometry.width = columns();
+ if (geometry.height == 0)
+ geometry.height = rows();
+ geometry.x = (-geometry.x);
+ geometry.y = (-geometry.y);
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage = ExtentImage( image(), &geometry,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+void Magick::Image::extent ( const Geometry &geometry_,
+ const GravityType &gravity_ )
+{
+
+ image()->gravity=gravity_;
+ extent( geometry_ );
+}
+
+void Magick::Image::extent ( const Geometry &geometry_,
+ const Color &backgroundColor_ )
+{
+ backgroundColor( backgroundColor_ );
+ extent( geometry_ );
+}
+
+void Magick::Image::extent ( const Geometry &geometry_,
+ const Color &backgroundColor_,
+ const GravityType &gravity_ )
+{
+ backgroundColor( backgroundColor_ );
+ extent( geometry_, gravity_ );
+}
+
+// Flip image (reflect each scanline in the vertical direction)
+void Magick::Image::flip ( void )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ FlipImage( image(), &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Flood-fill color across pixels that match the color of the
+// target pixel and are neighbors of the target pixel.
+// Uses current fuzz setting when determining color match.
+void Magick::Image::floodFillColor( const unsigned int x_,
+ const unsigned int y_,
+ const Magick::Color &fillColor_ )
+{
+ floodFillTexture( x_, y_, Image( Geometry( 1, 1), fillColor_ ) );
+}
+void Magick::Image::floodFillColor( const Geometry &point_,
+ const Magick::Color &fillColor_ )
+{
+ floodFillTexture( point_, Image( Geometry( 1, 1), fillColor_) );
+}
+
+// Flood-fill color across pixels starting at target-pixel and
+// stopping at pixels matching specified border color.
+// Uses current fuzz setting when determining color match.
+void Magick::Image::floodFillColor( const unsigned int x_,
+ const unsigned int y_,
+ const Magick::Color &fillColor_,
+ const Magick::Color &borderColor_ )
+{
+ floodFillTexture( x_, y_, Image( Geometry( 1, 1), fillColor_),
+ borderColor_ );
+}
+void Magick::Image::floodFillColor( const Geometry &point_,
+ const Magick::Color &fillColor_,
+ const Magick::Color &borderColor_ )
+{
+ floodFillTexture( point_, Image( Geometry( 1, 1), fillColor_),
+ borderColor_ );
+}
+
+// Floodfill pixels matching color (within fuzz factor) of target
+// pixel(x,y) with replacement opacity value using method.
+void Magick::Image::floodFillOpacity( const unsigned int x_,
+ const unsigned int y_,
+ const unsigned int opacity_,
+ const PaintMethod method_ )
+{
+ modifyImage();
+ MatteFloodfillImage ( image(),
+ static_cast<PixelPacket>(pixelColor(x_,y_)),
+ opacity_,
+ static_cast<long>(x_), static_cast<long>(y_),
+ method_ );
+ throwImageException();
+}
+
+// Flood-fill texture across pixels that match the color of the
+// target pixel and are neighbors of the target pixel.
+// Uses current fuzz setting when determining color match.
+void Magick::Image::floodFillTexture( const unsigned int x_,
+ const unsigned int y_,
+ const Magick::Image &texture_ )
+{
+ modifyImage();
+
+ // Set drawing pattern
+ options()->fillPattern(texture_.constImage());
+
+ // Get pixel view
+ Pixels pixels(*this);
+ // Fill image
+ PixelPacket *target = pixels.get(x_, y_, 1, 1 );
+ if (target)
+ ColorFloodfillImage ( image(), // Image *image
+ options()->drawInfo(), // const DrawInfo *draw_info
+ *target, // const PixelPacket target
+ static_cast<long>(x_), // const long x_offset
+ static_cast<long>(y_), // const long y_offset
+ FloodfillMethod // const PaintMethod method
+ );
+
+ throwImageException();
+}
+void Magick::Image::floodFillTexture( const Magick::Geometry &point_,
+ const Magick::Image &texture_ )
+{
+ floodFillTexture( point_.xOff(), point_.yOff(), texture_ );
+}
+
+// Flood-fill texture across pixels starting at target-pixel and
+// stopping at pixels matching specified border color.
+// Uses current fuzz setting when determining color match.
+void Magick::Image::floodFillTexture( const unsigned int x_,
+ const unsigned int y_,
+ const Magick::Image &texture_,
+ const Magick::Color &borderColor_ )
+{
+ modifyImage();
+
+ // Set drawing fill pattern
+ options()->fillPattern(texture_.constImage());
+
+ ColorFloodfillImage ( image(),
+ options()->drawInfo(),
+ static_cast<PixelPacket>(borderColor_),
+ static_cast<long>(x_),
+ static_cast<long>(y_),
+ FillToBorderMethod
+ );
+
+ throwImageException();
+}
+void Magick::Image::floodFillTexture( const Magick::Geometry &point_,
+ const Magick::Image &texture_,
+ const Magick::Color &borderColor_ )
+{
+ floodFillTexture( point_.xOff(), point_.yOff(), texture_, borderColor_ );
+}
+
+// Flop image (reflect each scanline in the horizontal direction)
+void Magick::Image::flop ( void )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ FlopImage( image(), &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Frame image
+void Magick::Image::frame ( const Geometry &geometry_ )
+{
+ FrameInfo info;
+
+ info.x = static_cast<long>(geometry_.width());
+ info.y = static_cast<long>(geometry_.height());
+ info.width = columns() + ( static_cast<unsigned long>(info.x) << 1 );
+ info.height = rows() + ( static_cast<unsigned long>(info.y) << 1 );
+ info.outer_bevel = geometry_.xOff();
+ info.inner_bevel = geometry_.yOff();
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ FrameImage( image(), &info, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::frame ( const unsigned int width_,
+ const unsigned int height_,
+ const int innerBevel_, const int outerBevel_ )
+{
+ FrameInfo info;
+ info.x = static_cast<long>(width_);
+ info.y = static_cast<long>(height_);
+ info.width = columns() + ( static_cast<unsigned long>(info.x) << 1 );
+ info.height = rows() + ( static_cast<unsigned long>(info.y) << 1 );
+ info.outer_bevel = static_cast<long>(outerBevel_);
+ info.inner_bevel = static_cast<long>(innerBevel_);
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ FrameImage( image(), &info, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Gamma correct image
+void Magick::Image::gamma ( const double gamma_ )
+{
+ char gamma[MaxTextExtent + 1];
+ FormatString( gamma, "%3.6f", gamma_);
+
+ modifyImage();
+ GammaImage ( image(), gamma );
+}
+void Magick::Image::gamma ( const double gammaRed_,
+ const double gammaGreen_,
+ const double gammaBlue_ )
+{
+ char gamma[MaxTextExtent + 1];
+ FormatString( gamma, "%3.6f/%3.6f/%3.6f/",
+ gammaRed_, gammaGreen_, gammaBlue_);
+
+ modifyImage();
+ GammaImage ( image(), gamma );
+ throwImageException();
+}
+
+// Gaussian blur image
+// The number of neighbor pixels to be included in the convolution
+// mask is specified by 'width_'. The standard deviation of the
+// gaussian bell curve is specified by 'sigma_'.
+void Magick::Image::gaussianBlur ( const double width_, const double sigma_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ GaussianBlurImage( image(), width_, sigma_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::gaussianBlurChannel ( const ChannelType channel_,
+ const double width_, const double sigma_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ GaussianBlurImageChannel( image(), channel_, width_, sigma_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Implode image
+void Magick::Image::implode ( const double factor_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ImplodeImage( image(), factor_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Level image. Adjust the levels of the image by scaling the colors
+// falling between specified white and black points to the full
+// available quantum range. The parameters provided represent the
+// black, mid (gamma), and white points. The black point specifies
+// the darkest color in the image. Colors darker than the black point
+// are set to zero. Mid point (gamma) specifies a gamma correction to
+// apply to the image. White point specifies the lightest color in the
+// image. Colors brighter than the white point are set to the maximum
+// quantum value. The black and white point have the valid range 0 to
+// MaxRGB while gamma has a useful range of 0 to ten.
+void Magick::Image::level ( const double black_point,
+ const double white_point,
+ const double mid_point )
+{
+ modifyImage();
+ char levels[MaxTextExtent];
+ FormatString( levels, "%g,%g,%g",black_point,mid_point,white_point);
+ (void) LevelImage( image(), levels );
+ throwImageException();
+}
+
+// Apply a color lookup table (Hald CLUT) to the image.
+void Magick::Image::haldClut ( const Image &clutImage_ )
+{
+ modifyImage();
+ (void) HaldClutImage( image(), clutImage_.constImage() );
+ throwImageException();
+}
+
+// Level image channel. Adjust the levels of the image channel by
+// scaling the values falling between specified white and black points
+// to the full available quantum range. The parameters provided
+// represent the black, mid (gamma), and white points. The black
+// point specifies the darkest color in the image. Colors darker than
+// the black point are set to zero. Mid point (gamma) specifies a
+// gamma correction to apply to the image. White point specifies the
+// lightest color in the image. Colors brighter than the white point
+// are set to the maximum quantum value. The black and white point
+// have the valid range 0 to MaxRGB while gamma has a useful range of
+// 0 to ten.
+void Magick::Image::levelChannel ( const Magick::ChannelType channel,
+ const double black_point,
+ const double white_point,
+ const double mid_point )
+{
+ modifyImage();
+ (void) LevelImageChannel( image(), channel, black_point, mid_point,
+ white_point );
+ throwImageException();
+}
+
+// Magnify image by integral size
+void Magick::Image::magnify ( void )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ MagnifyImage( image(), &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Remap image colors with closest color from reference image
+void Magick::Image::map ( const Image &mapImage_ , const bool dither_ )
+{
+ modifyImage();
+ MapImage ( image(),
+ mapImage_.constImage(),
+ (dither_ == true ? 1 : 0) );
+ throwImageException();
+}
+// Floodfill designated area with replacement opacity value
+void Magick::Image::matteFloodfill ( const Color &target_ ,
+ const unsigned int opacity_,
+ const int x_, const int y_,
+ const Magick::PaintMethod method_ )
+{
+ modifyImage();
+ MatteFloodfillImage ( image(), static_cast<PixelPacket>(target_),
+ opacity_, x_, y_, method_ );
+ throwImageException();
+}
+
+// Filter image by replacing each pixel component with the median
+// color in a circular neighborhood
+void Magick::Image::medianFilter ( const double radius_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ MedianFilterImage ( image(), radius_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Reduce image by integral size
+void Magick::Image::minify ( void )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ MinifyImage( image(), &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Modulate percent hue, saturation, and brightness of an image
+void Magick::Image::modulate ( const double brightness_,
+ const double saturation_,
+ const double hue_ )
+{
+ char modulate[MaxTextExtent + 1];
+ FormatString( modulate, "%3.6f/%3.6f/%3.6f",
+ brightness_, saturation_, hue_);
+
+ modifyImage();
+ ModulateImage( image(), modulate );
+ throwImageException();
+}
+
+// Motion blur image with specified blur factor
+// The radius_ parameter specifies the radius of the Gaussian, in
+// pixels, not counting the center pixel. The sigma_ parameter
+// specifies the standard deviation of the Laplacian, in pixels.
+// The angle_ parameter specifies the angle the object appears
+// to be comming from (zero degrees is from the right).
+void Magick::Image::motionBlur ( const double radius_,
+ const double sigma_,
+ const double angle_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ MotionBlurImage( image(), radius_, sigma_, angle_, &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+
+// Negate image. Set grayscale_ to true to effect grayscale values
+// only
+void Magick::Image::negate ( const bool grayscale_ )
+{
+ modifyImage();
+ NegateImage ( image(), (grayscale_ == true ? 1 : 0) );
+ throwImageException();
+}
+
+// Normalize image
+void Magick::Image::normalize ( void )
+{
+ modifyImage();
+ NormalizeImage ( image() );
+ throwImageException();
+}
+
+// Oilpaint image
+void Magick::Image::oilPaint ( const double radius_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ OilPaintImage( image(), radius_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Set or attenuate the opacity channel. If the image pixels are
+// opaque then they are set to the specified opacity value, otherwise
+// they are blended with the supplied opacity value. The value of
+// opacity_ ranges from 0 (completely opaque) to MaxRGB. The defines
+// OpaqueOpacity and TransparentOpacity are available to specify
+// completely opaque or completely transparent, respectively.
+void Magick::Image::opacity ( const unsigned int opacity_ )
+{
+ modifyImage();
+ SetImageOpacity( image(), opacity_ );
+}
+
+// Change the color of an opaque pixel to the pen color.
+void Magick::Image::opaque ( const Color &opaqueColor_,
+ const Color &penColor_ )
+{
+ if ( !opaqueColor_.isValid() )
+ {
+ throwExceptionExplicit( OptionError,
+ "Opaque color argument is invalid" );
+ }
+ if ( !penColor_.isValid() )
+ {
+ throwExceptionExplicit( OptionError,
+ "Pen color argument is invalid" );
+ }
+
+ modifyImage();
+ OpaqueImage ( image(), opaqueColor_, penColor_ );
+ throwImageException();
+}
+
+// Ping is similar to read except only enough of the image is read to
+// determine the image columns, rows, and filesize. Access the
+// columns(), rows(), and fileSize() attributes after invoking ping.
+// The image data is not valid after calling ping.
+void Magick::Image::ping ( const std::string &imageSpec_ )
+{
+ options()->fileName( imageSpec_ );
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ PingImage( imageInfo(), &exceptionInfo );
+ replaceImage( image );
+ throwImageException( exceptionInfo );
+}
+
+// Ping is similar to read except only enough of the image is read
+// to determine the image columns, rows, and filesize. Access the
+// columns(), rows(), and fileSize() attributes after invoking
+// ping. The image data is not valid after calling ping.
+void Magick::Image::ping ( const Blob& blob_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ PingBlob( imageInfo(), blob_.data(), blob_.length(), &exceptionInfo );
+ replaceImage( image );
+ throwImageException( exceptionInfo );
+}
+
+// Execute a named process module using an argc/argv syntax similar to
+// that accepted by a C 'main' routine. An exception is thrown if the
+// requested process module doesn't exist, fails to load, or fails during
+// execution.
+void Magick::Image::process( std::string name_, const int argc, char **argv )
+{
+ modifyImage();
+
+ unsigned int status =
+ ExecuteModuleProcess( name_.c_str(), &image(), argc, argv );
+
+ if (status == false)
+ throwImageException( image()->exception );
+}
+
+// Quantize colors in image using current quantization settings
+// Set measureError_ to true in order to measure quantization error
+void Magick::Image::quantize ( const bool measureError_ )
+{
+ modifyImage();
+
+ if (measureError_)
+ options()->quantizeInfo()->measure_error=MagickTrue;
+ else
+ options()->quantizeInfo()->measure_error=MagickFalse;
+
+ QuantizeImage( options()->quantizeInfo(), image() );
+
+ throwImageException();
+}
+
+// Apply an arithmetic or bitwise operator to the image pixel quantums.
+void Magick::Image::quantumOperator ( const ChannelType channel_,
+ const QuantumOperator operator_,
+ Quantum rvalue_)
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ modifyImage();
+ QuantumOperatorImage( image(), channel_, operator_, static_cast<double>(rvalue_),
+ &exceptionInfo);
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::quantumOperator ( const ChannelType channel_,
+ const QuantumOperator operator_,
+ double rvalue_)
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ modifyImage();
+ QuantumOperatorImage( image(), channel_, operator_, rvalue_, &exceptionInfo);
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::quantumOperator ( const int x_,const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const ChannelType channel_,
+ const QuantumOperator operator_,
+ const Quantum rvalue_)
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ modifyImage();
+ QuantumOperatorRegionImage( image(), x_, y_, columns_, rows_, channel_,
+ operator_, static_cast<double>(rvalue_),
+ &exceptionInfo);
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::quantumOperator ( const int x_,const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const ChannelType channel_,
+ const QuantumOperator operator_,
+ const double rvalue_)
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ modifyImage();
+ QuantumOperatorRegionImage( image(), x_, y_, columns_, rows_, channel_,
+ operator_, rvalue_, &exceptionInfo);
+ throwImageException( exceptionInfo );
+}
+
+// Raise image (lighten or darken the edges of an image to give a 3-D
+// raised or lowered effect)
+void Magick::Image::raise ( const Geometry &geometry_ ,
+ const bool raisedFlag_ )
+{
+ RectangleInfo raiseInfo = geometry_;
+ modifyImage();
+ RaiseImage ( image(), &raiseInfo, (raisedFlag_ == true ? 1 : 0) );
+ throwImageException();
+}
+
+// Random threshold image.
+//
+// Changes the value of individual pixels based on the intensity
+// of each pixel compared to a random threshold. The result is a
+// low-contrast, two color image. The thresholds_ argument is a
+// geometry containing LOWxHIGH thresholds. If the string
+// contains 2x2, 3x3, or 4x4, then an ordered dither of order 2,
+// 3, or 4 will be performed instead. If a channel_ argument is
+// specified then only the specified channel is altered. This is
+// a very fast alternative to 'quantize' based dithering.
+void Magick::Image::randomThreshold( const Geometry &thresholds_ )
+{
+ randomThresholdChannel(thresholds_,AllChannels);
+}
+void Magick::Image::randomThresholdChannel( const Geometry &thresholds_,
+ const ChannelType channel_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ modifyImage();
+ (void) RandomChannelThresholdImage( image(),
+ MagickLib::ChannelTypeToString(channel_),
+ static_cast<std::string>(thresholds_).c_str(),
+ &exceptionInfo );
+ throwImageException();
+}
+
+// Read image into current object
+void Magick::Image::read ( const std::string &imageSpec_ )
+{
+ options()->fileName( imageSpec_ );
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ ReadImage( imageInfo(), &exceptionInfo );
+
+ // Ensure that multiple image frames were not read.
+ if ( image && image->next )
+ {
+ // Destroy any extra image frames
+ MagickLib::Image* next = image->next;
+ image->next = 0;
+ next->previous = 0;
+ DestroyImageList( next );
+
+ }
+ replaceImage( image );
+ throwImageException( exceptionInfo );
+ if ( image )
+ throwImageException( image->exception );
+}
+
+// Read image of specified size into current object
+void Magick::Image::read ( const Geometry &size_,
+ const std::string &imageSpec_ )
+{
+ size( size_ );
+ read( imageSpec_ );
+}
+
+// Read image from in-memory BLOB
+void Magick::Image::read ( const Blob &blob_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ BlobToImage( imageInfo(),
+ static_cast<const void *>(blob_.data()),
+ blob_.length(), &exceptionInfo );
+ replaceImage( image );
+ throwImageException( exceptionInfo );
+ if ( image )
+ throwImageException( image->exception );
+}
+
+// Read image of specified size from in-memory BLOB
+void Magick::Image::read ( const Blob &blob_,
+ const Geometry &size_ )
+{
+ // Set image size
+ size( size_ );
+ // Read from Blob
+ read( blob_ );
+}
+
+// Read image of specified size and depth from in-memory BLOB
+void Magick::Image::read ( const Blob &blob_,
+ const Geometry &size_,
+ const unsigned int depth_ )
+{
+ // Set image size
+ size( size_ );
+ // Set image depth
+ depth( depth_ );
+ // Read from Blob
+ read( blob_ );
+}
+
+// Read image of specified size, depth, and format from in-memory BLOB
+void Magick::Image::read ( const Blob &blob_,
+ const Geometry &size_,
+ const unsigned int depth_,
+ const std::string &magick_ )
+{
+ // Set image size
+ size( size_ );
+ // Set image depth
+ depth( depth_ );
+ // Set image magick
+ magick( magick_ );
+ // Read from Blob
+ read( blob_ );
+}
+
+// Read image of specified size, and format from in-memory BLOB
+void Magick::Image::read ( const Blob &blob_,
+ const Geometry &size_,
+ const std::string &magick_ )
+{
+ // Set image size
+ size( size_ );
+ // Set image magick
+ magick( magick_ );
+ // Read from Blob
+ read( blob_ );
+}
+
+// Read image based on raw pixels in memory (ConstituteImage)
+void Magick::Image::read ( const unsigned int width_,
+ const unsigned int height_,
+ const std::string &map_,
+ const StorageType type_,
+ const void *pixels_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ ConstituteImage( width_, height_, map_.c_str(), type_, pixels_,
+ &exceptionInfo );
+ replaceImage( image );
+ throwImageException( exceptionInfo );
+ if ( image )
+ throwImageException( image->exception );
+}
+
+// Reduce noise in image
+void Magick::Image::reduceNoise ( const double order_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ReduceNoiseImage( image(), order_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+void Magick::Image::repage()
+{
+ modifyImage();
+ options()->page(Geometry());
+ image()->page.width = 0U;
+ image()->page.height = 0U;
+ image()->page.x = 0;
+ image()->page.y = 0;
+}
+
+// Resize image, specifying geometry, filter, and blur
+void Magick::Image::resize ( const Geometry &geometry_,
+ const FilterTypes filterType_,
+ const double blur_ )
+{
+ long x = 0;
+ long y = 0;
+ unsigned long width = columns();
+ unsigned long height = rows();
+
+ GetMagickGeometry ( static_cast<std::string>(geometry_).c_str(),
+ &x, &y,
+ &width, &height );
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ResizeImage( image(), width, height, filterType_, blur_, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Resize image, specifying geometry and filter, with blur using Image
+// default.
+void Magick::Image::resize ( const Geometry &geometry_,
+ const FilterTypes filterType_ )
+{
+ resize (geometry_, filterType_, image()->blur);
+}
+
+// Resize image, specifying only geometry, with filter and blur
+// obtained from Image default. Same result as 'zoom' method.
+void Magick::Image::resize ( const Geometry &geometry_ )
+{
+ resize (geometry_, image()->filter, image()->blur);
+}
+
+// Roll image
+void Magick::Image::roll ( const Geometry &roll_ )
+{
+ long xOff = roll_.xOff();
+ if ( roll_.xNegative() )
+ xOff = 0 - xOff;
+ long yOff = roll_.yOff();
+ if ( roll_.yNegative() )
+ yOff = 0 - yOff;
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ RollImage( image(), xOff, yOff, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::roll ( const unsigned int columns_,
+ const unsigned int rows_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ RollImage( image(),
+ static_cast<long>(columns_),
+ static_cast<long>(rows_), &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Rotate image
+void Magick::Image::rotate ( const double degrees_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ RotateImage( image(), degrees_, &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Sample image
+void Magick::Image::sample ( const Geometry &geometry_ )
+{
+ long x = 0;
+ long y = 0;
+ unsigned long width = columns();
+ unsigned long height = rows();
+
+ GetMagickGeometry (static_cast<std::string>(geometry_).c_str(),
+ &x, &y,
+ &width, &height );
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ SampleImage( image(), width, height, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Scale image
+void Magick::Image::scale ( const Geometry &geometry_ )
+{
+ long x = 0;
+ long y = 0;
+ unsigned long width = columns();
+ unsigned long height = rows();
+
+ GetMagickGeometry (static_cast<std::string>(geometry_).c_str(),
+ &x, &y,
+ &width, &height );
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ScaleImage( image(), width, height, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Resize image using several algorithms to make smaller images very
+// quickly.
+void Magick::Image::thumbnail ( const Geometry &geometry_ )
+{
+ long x = 0;
+ long y = 0;
+ unsigned long width = columns();
+ unsigned long height = rows();
+
+ GetMagickGeometry (static_cast<std::string>(geometry_).c_str(),
+ &x, &y,
+ &width, &height );
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ThumbnailImage( image(), width, height, &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Segment (coalesce similar image components) by analyzing the
+// histograms of the color components and identifying units that are
+// homogeneous with the fuzzy c-means technique.
+void Magick::Image::segment ( const double clusterThreshold_,
+ const double smoothingThreshold_ )
+{
+ modifyImage();
+ SegmentImage ( image(),
+ options()->quantizeColorSpace(),
+ options()->verbose(),
+ clusterThreshold_,
+ smoothingThreshold_ );
+ throwImageException();
+ SyncImage( image() );
+ throwImageException();
+}
+
+// Shade image using distant light source
+void Magick::Image::shade ( const double azimuth_,
+ const double elevation_,
+ const bool colorShading_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ShadeImage( image(),
+ (colorShading_ == true ? 1 : 0),
+ azimuth_,
+ elevation_,
+ &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Sharpen pixels in image
+void Magick::Image::sharpen ( const double radius_, const double sigma_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ SharpenImage( image(),
+ radius_,
+ sigma_,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::sharpenChannel ( const ChannelType channel_,
+ const double radius_, const double sigma_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ SharpenImageChannel( image(),
+ channel_,
+ radius_,
+ sigma_,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Shave pixels from image edges.
+void Magick::Image::shave ( const Geometry &geometry_ )
+{
+ RectangleInfo shaveInfo = geometry_;
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ShaveImage( image(),
+ &shaveInfo,
+ &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Shear image
+void Magick::Image::shear ( const double xShearAngle_,
+ const double yShearAngle_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ ShearImage( image(),
+ xShearAngle_,
+ yShearAngle_,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Solarize image (similar to effect seen when exposing a photographic
+// film to light during the development process)
+void Magick::Image::solarize ( const double factor_ )
+{
+ modifyImage();
+ SolarizeImage ( image(), factor_ );
+ throwImageException();
+}
+
+// Spread pixels randomly within image by specified ammount
+void Magick::Image::spread ( const unsigned int amount_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ SpreadImage( image(),
+ amount_,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Add a digital watermark to the image (based on second image)
+void Magick::Image::stegano ( const Image &watermark_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ SteganoImage( image(),
+ watermark_.constImage(),
+ &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Stereo image (left image is current image)
+void Magick::Image::stereo ( const Image &rightImage_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ StereoImage( image(),
+ rightImage_.constImage(),
+ &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Remove all profiles and text attributes from the image.
+void Magick::Image::strip ( void )
+{
+ modifyImage();
+ MagickLib::StripImage(image());
+}
+
+// Swirl image
+void Magick::Image::swirl ( const double degrees_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ SwirlImage( image(), degrees_,
+ &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Texture image
+void Magick::Image::texture ( const Image &texture_ )
+{
+ modifyImage();
+ TextureImage( image(), texture_.constImage() );
+ throwImageException();
+}
+
+// Threshold image channels (below threshold becomes black, above
+// threshold becomes white).
+// The range of the threshold parameter is 0 to MaxRGB.
+void Magick::Image::threshold ( const double threshold_ )
+{
+ modifyImage();
+ ThresholdImage( image(), threshold_ );
+ throwImageException();
+}
+
+// Transform image based on image geometry only
+void Magick::Image::transform ( const Geometry &imageGeometry_ )
+{
+ modifyImage();
+ TransformImage ( &(image()), 0,
+ std::string(imageGeometry_).c_str() );
+ throwImageException();
+}
+// Transform image based on image and crop geometries
+void Magick::Image::transform ( const Geometry &imageGeometry_,
+ const Geometry &cropGeometry_ )
+{
+ modifyImage();
+ TransformImage ( &(image()), std::string(cropGeometry_).c_str(),
+ std::string(imageGeometry_).c_str() );
+ throwImageException();
+}
+
+// Add matte image to image, setting pixels matching color to transparent
+void Magick::Image::transparent ( const Color &color_ )
+{
+ if ( !color_.isValid() )
+ {
+ throwExceptionExplicit( OptionError,
+ "Color argument is invalid" );
+ }
+
+ std::string color = color_;
+
+ modifyImage();
+ TransparentImage ( image(), color_, TransparentOpacity );
+ throwImageException();
+}
+
+// Trim edges that are the background color from the image
+void Magick::Image::trim ( void )
+{
+ // width=0, height=0 trims edges
+ Geometry cropInfo(0,0);
+ crop ( cropInfo );
+}
+
+// Replace image with a sharpened version of the original image
+// using the unsharp mask algorithm.
+// radius_
+// the radius of the Gaussian, in pixels, not counting the
+// center pixel.
+// sigma_
+// the standard deviation of the Gaussian, in pixels.
+// amount_
+// the percentage of the difference between the original and
+// the blur image that is added back into the original.
+// threshold_
+// the threshold in pixels needed to apply the diffence amount.
+void Magick::Image::unsharpmask ( const double radius_,
+ const double sigma_,
+ const double amount_,
+ const double threshold_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ UnsharpMaskImage( image(),
+ radius_,
+ sigma_,
+ amount_,
+ threshold_,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+void Magick::Image::unsharpmaskChannel ( const ChannelType channel_,
+ const double radius_,
+ const double sigma_,
+ const double amount_,
+ const double threshold_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ UnsharpMaskImageChannel( image(),
+ channel_,
+ radius_,
+ sigma_,
+ amount_,
+ threshold_,
+ &exceptionInfo );
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Map image pixels to a sine wave
+void Magick::Image::wave ( const double amplitude_, const double wavelength_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* newImage =
+ WaveImage( image(),
+ amplitude_,
+ wavelength_,
+ &exceptionInfo);
+ replaceImage( newImage );
+ throwImageException( exceptionInfo );
+}
+
+// Write image to file
+void Magick::Image::write( const std::string &imageSpec_ )
+{
+ modifyImage();
+ fileName( imageSpec_ );
+ WriteImage( imageInfo(), image() );
+ throwImageException();
+}
+
+// Write image to in-memory BLOB
+void Magick::Image::write ( Blob *blob_ )
+{
+ modifyImage();
+ size_t length = 2048; // Efficient size for small images
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ void* data = ImageToBlob( imageInfo(),
+ image(),
+ &length,
+ &exceptionInfo);
+ throwImageException( exceptionInfo );
+ blob_->updateNoCopy( data, length, Blob::MallocAllocator );
+ throwImageException();
+}
+void Magick::Image::write ( Blob *blob_,
+ const std::string &magick_ )
+{
+ modifyImage();
+ magick(magick_);
+ size_t length = 2048; // Efficient size for small images
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ void* data = ImageToBlob( imageInfo(),
+ image(),
+ &length,
+ &exceptionInfo);
+ throwImageException( exceptionInfo );
+ blob_->updateNoCopy( data, length, Blob::MallocAllocator );
+ throwImageException();
+}
+void Magick::Image::write ( Blob *blob_,
+ const std::string &magick_,
+ const unsigned int depth_ )
+{
+ modifyImage();
+ magick(magick_);
+ depth(depth_);
+ size_t length = 2048; // Efficient size for small images
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ void* data = ImageToBlob( imageInfo(),
+ image(),
+ &length,
+ &exceptionInfo);
+ throwImageException( exceptionInfo );
+ blob_->updateNoCopy( data, length, Blob::MallocAllocator );
+ throwImageException();
+}
+
+// Write image to an array of pixels with storage type specified
+// by user (DispatchImage), e.g.
+// image.write( 0, 0, 640, 1, "RGB", 0, pixels );
+void Magick::Image::write ( const int x_,
+ const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const std::string &map_,
+ const StorageType type_,
+ void *pixels_ )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ DispatchImage( image(), x_, y_, columns_, rows_, map_.c_str(), type_,
+ pixels_,
+ &exceptionInfo);
+ throwImageException( exceptionInfo );
+}
+
+// Zoom image
+void Magick::Image::zoom( const Geometry &geometry_ )
+{
+ // Use resize() implementation.
+ resize( geometry_ );
+}
+
+/*
+ * Methods for setting image attributes
+ *
+ */
+
+// Join images into a single multi-image file
+void Magick::Image::adjoin ( const bool flag_ )
+{
+ modifyImage();
+ options()->adjoin( flag_ );
+}
+bool Magick::Image::adjoin ( void ) const
+{
+ return constOptions()->adjoin();
+}
+
+// Remove pixel aliasing
+void Magick::Image::antiAlias( const bool flag_ )
+{
+ modifyImage();
+ options()->antiAlias( static_cast<unsigned int>(flag_) );
+}
+bool Magick::Image::antiAlias( void )
+{
+ return static_cast<bool>( options()->antiAlias( ) );
+}
+
+// Animation inter-frame delay
+void Magick::Image::animationDelay ( const unsigned int delay_ )
+{
+ modifyImage();
+ image()->delay = delay_;
+}
+unsigned int Magick::Image::animationDelay ( void ) const
+{
+ return constImage()->delay;
+}
+
+// Number of iterations to play animation
+void Magick::Image::animationIterations ( const unsigned int iterations_ )
+{
+ modifyImage();
+ image()->iterations = iterations_;
+}
+unsigned int Magick::Image::animationIterations ( void ) const
+{
+ return constImage()->iterations;
+}
+
+// Access/Update a named image text attribute. Updates append the
+// provided to any existing attribute text. Pass NULL as the value to
+// remove an existing value or before a subsequent call to add new
+// text.
+void Magick::Image::attribute ( const std::string name_,
+ const char * value_ )
+{
+ modifyImage();
+ SetImageAttribute( image(), name_.c_str(), value_ );
+}
+void Magick::Image::attribute ( const std::string name_,
+ const std::string value_ )
+{
+ modifyImage();
+ SetImageAttribute( image(), name_.c_str(), value_.c_str() );
+}
+std::string Magick::Image::attribute ( const std::string name_ )
+{
+ const ImageAttribute * image_attribute =
+ GetImageAttribute( constImage(), name_.c_str() );
+
+ if ( image_attribute )
+ return std::string( image_attribute->value );
+
+ return std::string(); // Intentionally no exception
+}
+
+// Background color
+void Magick::Image::backgroundColor ( const Color &backgroundColor_ )
+{
+ modifyImage();
+
+ if ( backgroundColor_.isValid() )
+ {
+ image()->background_color = backgroundColor_;
+ }
+ else
+ {
+ image()->background_color = Color();
+ }
+
+ options()->backgroundColor( backgroundColor_ );
+}
+Magick::Color Magick::Image::backgroundColor ( void ) const
+{
+ return constOptions()->backgroundColor( );
+}
+
+// Background fill texture
+void Magick::Image::backgroundTexture ( const std::string &backgroundTexture_ )
+{
+ modifyImage();
+ options()->backgroundTexture( backgroundTexture_ );
+}
+std::string Magick::Image::backgroundTexture ( void ) const
+{
+ return constOptions()->backgroundTexture( );
+}
+
+// Original image columns
+unsigned int Magick::Image::baseColumns ( void ) const
+{
+ return constImage()->magick_columns;
+}
+
+// Original image name
+std::string Magick::Image::baseFilename ( void ) const
+{
+ return std::string(constImage()->magick_filename);
+}
+
+// Original image rows
+unsigned int Magick::Image::baseRows ( void ) const
+{
+ return constImage()->magick_rows;
+}
+
+// Border color
+void Magick::Image::borderColor ( const Color &borderColor_ )
+{
+ modifyImage();
+
+ if ( borderColor_.isValid() )
+ {
+ image()->border_color = borderColor_;
+ }
+ else
+ {
+ image()->border_color = Color();
+ }
+
+ options()->borderColor( borderColor_ );
+}
+Magick::Color Magick::Image::borderColor ( void ) const
+{
+ return constOptions()->borderColor( );
+}
+
+// Return smallest bounding box enclosing non-border pixels. The
+// current fuzz value is used when discriminating between pixels.
+// This is the crop bounding box used by crop(Geometry(0,0));
+Magick::Geometry Magick::Image::boundingBox ( void ) const
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ RectangleInfo bbox = GetImageBoundingBox( constImage(), &exceptionInfo);
+ throwImageException( exceptionInfo );
+ return Geometry( bbox );
+}
+
+// Text bounding-box base color
+void Magick::Image::boxColor ( const Color &boxColor_ )
+{
+ modifyImage();
+ options()->boxColor( boxColor_ );
+}
+Magick::Color Magick::Image::boxColor ( void ) const
+{
+ return constOptions()->boxColor( );
+}
+
+// Pixel cache threshold. Once this threshold is exceeded, all
+// subsequent pixels cache operations are to/from disk.
+// This setting is shared by all Image objects.
+/* static */
+void Magick::Image::cacheThreshold ( const unsigned int threshold_ )
+{
+ (void) SetMagickResourceLimit(MemoryResource,threshold_);
+ (void) SetMagickResourceLimit(MapResource,2*threshold_);
+}
+
+void Magick::Image::chromaBluePrimary ( const double x_, const double y_ )
+{
+ modifyImage();
+ image()->chromaticity.blue_primary.x = x_;
+ image()->chromaticity.blue_primary.y = y_;
+}
+void Magick::Image::chromaBluePrimary ( double *x_, double *y_ ) const
+{
+ *x_ = constImage()->chromaticity.blue_primary.x;
+ *y_ = constImage()->chromaticity.blue_primary.y;
+}
+
+void Magick::Image::chromaGreenPrimary ( const double x_, const double y_ )
+{
+ modifyImage();
+ image()->chromaticity.green_primary.x = x_;
+ image()->chromaticity.green_primary.y = y_;
+}
+void Magick::Image::chromaGreenPrimary ( double *x_, double *y_ ) const
+{
+ *x_ = constImage()->chromaticity.green_primary.x;
+ *y_ = constImage()->chromaticity.green_primary.y;
+}
+
+void Magick::Image::chromaRedPrimary ( const double x_, const double y_ )
+{
+ modifyImage();
+ image()->chromaticity.red_primary.x = x_;
+ image()->chromaticity.red_primary.y = y_;
+}
+void Magick::Image::chromaRedPrimary ( double *x_, double *y_ ) const
+{
+ *x_ = constImage()->chromaticity.red_primary.x;
+ *y_ = constImage()->chromaticity.red_primary.y;
+}
+
+void Magick::Image::chromaWhitePoint ( const double x_, const double y_ )
+{
+ modifyImage();
+ image()->chromaticity.white_point.x = x_;
+ image()->chromaticity.white_point.y = y_;
+}
+void Magick::Image::chromaWhitePoint ( double *x_, double *y_ ) const
+{
+ *x_ = constImage()->chromaticity.white_point.x;
+ *y_ = constImage()->chromaticity.white_point.y;
+}
+
+// Set image storage class
+void Magick::Image::classType ( const ClassType class_ )
+{
+ if ( classType() == PseudoClass && class_ == DirectClass )
+ {
+ // Use SyncImage to synchronize the DirectClass pixels with the
+ // color map and then set to DirectClass type.
+ modifyImage();
+ SyncImage( image() );
+ MagickFreeMemory(image()->colormap);
+ image()->storage_class = static_cast<MagickLib::ClassType>(DirectClass);
+ return;
+ }
+
+ if ( classType() == DirectClass && class_ == PseudoClass )
+ {
+ // Quantize to create PseudoClass color map
+ modifyImage();
+ quantizeColors(MaxRGB + 1);
+ quantize();
+ image()->storage_class = static_cast<MagickLib::ClassType>(PseudoClass);
+ }
+}
+
+// Associate a clip mask with the image. The clip mask must be the
+// same dimensions as the image. Pass an invalid image to unset an
+// existing clip mask.
+void Magick::Image::clipMask ( const Magick::Image & clipMask_ )
+{
+ modifyImage();
+
+ if( clipMask_.isValid() )
+ {
+ // Set clip mask
+ SetImageClipMask( image(), clipMask_.constImage() );
+ }
+ else
+ {
+ // Unset existing clip mask
+ SetImageClipMask( image(), 0 );
+ }
+}
+Magick::Image Magick::Image::clipMask ( void ) const
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ GetImageClipMask( constImage(), &exceptionInfo );
+ throwImageException( exceptionInfo );
+ return Magick::Image( image );
+}
+
+void Magick::Image::colorFuzz ( const double fuzz_ )
+{
+ modifyImage();
+ image()->fuzz = fuzz_;
+ options()->colorFuzz( fuzz_ );
+}
+double Magick::Image::colorFuzz ( void ) const
+{
+ return constOptions()->colorFuzz( );
+}
+
+// Set color in colormap at index
+void Magick::Image::colorMap ( const unsigned int index_,
+ const Color &color_ )
+{
+ MagickLib::Image* imageptr = image();
+
+ if (index_ > (MaxColormapSize-1) )
+ throwExceptionExplicit( OptionError,
+ "Colormap index must be less than MaxColormapSize" );
+
+ if ( !color_.isValid() )
+ throwExceptionExplicit( OptionError,
+ "Color argument is invalid");
+ modifyImage();
+
+ // Ensure that colormap size is large enough
+ if ( colorMapSize() < (index_+1) )
+ colorMapSize( index_ + 1 );
+
+ // Set color at index in colormap
+ (imageptr->colormap)[index_] = color_;
+}
+// Return color in colormap at index
+Magick::Color Magick::Image::colorMap ( const unsigned int index_ ) const
+{
+ const MagickLib::Image* imageptr = constImage();
+
+ if ( !imageptr->colormap )
+ throwExceptionExplicit( OptionError,
+ "Image does not contain a colormap");
+
+ if ( index_ > imageptr->colors-1 )
+ throwExceptionExplicit( OptionError,
+ "Index out of range");
+
+ return Magick::Color( (imageptr->colormap)[index_] );
+}
+
+// Colormap size (number of colormap entries)
+void Magick::Image::colorMapSize ( const unsigned int entries_ )
+{
+ if (entries_ >MaxColormapSize )
+ throwExceptionExplicit( OptionError,
+ "Colormap entries must not exceed MaxColormapSize" );
+
+ modifyImage();
+
+ MagickLib::Image* imageptr = image();
+
+ if( !imageptr->colormap )
+ {
+ // Allocate colormap
+ imageptr->colormap = MagickAllocateMemory(PixelPacket*,
+ entries_*sizeof(PixelPacket));
+ imageptr->colors = 0;
+ }
+ else if ( entries_ > imageptr->colors )
+ {
+ // Re-allocate colormap
+ MagickReallocMemory(PixelPacket*,imageptr->colormap,
+ (entries_)*sizeof(PixelPacket));
+ }
+
+ if ( !imageptr->colormap )
+ throwExceptionExplicit( ResourceLimitError,
+ "Failed to allocate colormap");
+
+ // Initialize any new new colormap entries as all black
+ Color black(0,0,0);
+ for( unsigned int i=imageptr->colors; i< (entries_-1); i++ )
+ (imageptr->colormap)[i] = black;
+
+ imageptr->colors = entries_;
+}
+unsigned int Magick::Image::colorMapSize ( void )
+{
+ const MagickLib::Image* imageptr = constImage();
+
+ if ( !imageptr->colormap )
+ throwExceptionExplicit( OptionError,
+ "Image does not contain a colormap");
+
+ return imageptr->colors;
+}
+
+// Image colorspace
+void Magick::Image::colorSpace( const ColorspaceType colorSpace_ )
+{
+ // Nothing to do?
+ if ( image()->colorspace == colorSpace_ )
+ return;
+
+ modifyImage();
+
+ if ( colorSpace_ != RGBColorspace &&
+ colorSpace_ != TransparentColorspace &&
+ colorSpace_ != GRAYColorspace )
+ {
+ if (image()->colorspace != RGBColorspace &&
+ image()->colorspace != TransparentColorspace &&
+ image()->colorspace != GRAYColorspace)
+ {
+ /* Transform to RGB colorspace as intermediate step */
+ TransformRGBImage( image(), image()->colorspace );
+ throwImageException();
+ }
+ /* Transform to final non-RGB colorspace */
+ RGBTransformImage( image(), colorSpace_ );
+ throwImageException();
+ return;
+ }
+
+ if ( colorSpace_ == RGBColorspace ||
+ colorSpace_ == TransparentColorspace ||
+ colorSpace_ == GRAYColorspace )
+ {
+ /* Transform to a RGB-type colorspace */
+ TransformRGBImage( image(), image()->colorspace );
+ throwImageException();
+ return;
+ }
+}
+Magick::ColorspaceType Magick::Image::colorSpace ( void ) const
+{
+ return constImage()->colorspace;
+}
+
+// Comment string
+void Magick::Image::comment ( const std::string &comment_ )
+{
+ modifyImage();
+ SetImageAttribute( image(), "Comment", NULL );
+ if ( comment_.length() > 0 )
+ SetImageAttribute( image(), "Comment", comment_.c_str() );
+ throwImageException();
+}
+std::string Magick::Image::comment ( void ) const
+{
+ const ImageAttribute * image_attribute =
+ GetImageAttribute( constImage(), "Comment" );
+
+ if ( image_attribute )
+ return std::string( image_attribute->value );
+
+ return std::string(); // Intentionally no exception
+}
+
+// Composition operator to be used when composition is implicitly used
+// (such as for image flattening).
+void Magick::Image::compose (const CompositeOperator compose_)
+{
+ image()->compose=compose_;
+}
+Magick::CompositeOperator Magick::Image::compose ( void ) const
+{
+ return constImage()->compose;
+}
+
+// Compression algorithm
+void Magick::Image::compressType ( const CompressionType compressType_ )
+{
+ modifyImage();
+ image()->compression = compressType_;
+ options()->compressType( compressType_ );
+}
+Magick::CompressionType Magick::Image::compressType ( void ) const
+{
+ return constOptions()->compressType( );
+}
+
+// Enable printing of debug messages from ImageMagick
+void Magick::Image::debug ( const bool flag_ )
+{
+ modifyImage();
+ options()->debug( flag_ );
+}
+bool Magick::Image::debug ( void ) const
+{
+ return constOptions()->debug();
+}
+
+// Tagged image format define (set/access coder-specific option) The
+// magick_ option specifies the coder the define applies to. The key_
+// option provides the key specific to that coder. The value_ option
+// provides the value to set (if any). See the defineSet() method if the
+// key must be removed entirely.
+void Magick::Image::defineValue ( const std::string &magick_,
+ const std::string &key_,
+ const std::string &value_ )
+{
+ modifyImage();
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ AddDefinition ( imageInfo(), magick_.c_str(), key_.c_str(), value_.c_str(), &exceptionInfo );
+ throwImageException( exceptionInfo );
+}
+std::string Magick::Image::defineValue ( const std::string &magick_,
+ const std::string &key_ ) const
+{
+ const char *definition =
+ AccessDefinition ( constImageInfo(), magick_.c_str(), key_.c_str() );
+ if (definition)
+ return std::string( definition );
+ return std::string( );
+}
+
+// Tagged image format define. Similar to the defineValue() method
+// except that passing the flag_ value 'true' creates a value-less
+// define with that format and key. Passing the flag_ value 'false'
+// removes any existing matching definition. The method returns 'true'
+// if a matching key exists, and 'false' if no matching key exists.
+void Magick::Image::defineSet ( const std::string &magick_,
+ const std::string &key_,
+ bool flag_ )
+{
+ modifyImage();
+ if (flag_)
+ {
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ std::string options = magick_ + ":" + key_ + "=";
+ AddDefinitions ( imageInfo(), options.c_str(), &exceptionInfo );
+ throwImageException( exceptionInfo );
+ }
+ else
+ {
+ std::string definition = magick_ + ":" + key_;
+ RemoveDefinitions( imageInfo(), definition.c_str() );
+ }
+}
+bool Magick::Image::defineSet ( const std::string &magick_,
+ const std::string &key_ ) const
+{
+ const char *definition =
+ AccessDefinition ( constImageInfo(), magick_.c_str(), key_.c_str() );
+ if (definition)
+ return true;
+ return false;
+}
+
+// Pixel resolution
+void Magick::Image::density ( const Geometry &density_ )
+{
+ modifyImage();
+ options()->density( density_ );
+ if ( density_.isValid() )
+ {
+ image()->x_resolution = density_.width();
+ if ( density_.height() != 0 )
+ {
+ image()->y_resolution = density_.height();
+ }
+ else
+ {
+ image()->y_resolution = density_.width();
+ }
+ }
+ else
+ {
+ // Reset to default
+ image()->x_resolution = 0;
+ image()->y_resolution = 0;
+ }
+}
+Magick::Geometry Magick::Image::density ( void ) const
+{
+ if (isValid())
+ {
+ unsigned int x_resolution=72;
+ unsigned int y_resolution=72;
+
+ if (constImage()->x_resolution > 0.0)
+ x_resolution=static_cast<unsigned int>(constImage()->x_resolution + 0.5);
+
+ if (constImage()->y_resolution > 0.0)
+ y_resolution=static_cast<unsigned int>(constImage()->y_resolution + 0.5);
+
+ return Geometry(x_resolution,y_resolution);
+ }
+
+ return constOptions()->density( );
+}
+
+// Image depth (bits allocated to red/green/blue components)
+void Magick::Image::depth ( const unsigned int depth_ )
+{
+ unsigned int depth = depth_;
+
+ if (depth > QuantumDepth)
+ depth=QuantumDepth;
+
+ modifyImage();
+ image()->depth=depth;
+ options()->depth( depth );
+}
+unsigned int Magick::Image::depth ( void ) const
+{
+ return constImage()->depth;
+}
+
+std::string Magick::Image::directory ( void ) const
+{
+ if ( constImage()->directory )
+ return std::string( constImage()->directory );
+
+ throwExceptionExplicit( CorruptImageWarning,
+ "Image does not contain a directory");
+
+ return std::string();
+}
+
+// Endianness (little like Intel or big like SPARC) for image
+// formats which support endian-specific options.
+void Magick::Image::endian ( const Magick::EndianType endian_ )
+{
+ modifyImage();
+ options()->endian( endian_ );
+ image()->endian = endian_;
+}
+Magick::EndianType Magick::Image::endian ( void ) const
+{
+ return constImage()->endian;
+}
+
+// Image file name
+void Magick::Image::fileName ( const std::string &fileName_ )
+{
+ modifyImage();
+
+ fileName_.copy( image()->filename,
+ sizeof(image()->filename) - 1 );
+ image()->filename[ fileName_.length() ] = 0; // Null terminate
+
+ options()->fileName( fileName_ );
+
+}
+std::string Magick::Image::fileName ( void ) const
+{
+ return constOptions()->fileName( );
+}
+
+// Image file size
+off_t Magick::Image::fileSize ( void ) const
+{
+ return GetBlobSize( constImage() );
+}
+
+// Color to use when drawing inside an object
+void Magick::Image::fillColor ( const Magick::Color &fillColor_ )
+{
+ modifyImage();
+ options()->fillColor(fillColor_);
+}
+Magick::Color Magick::Image::fillColor ( void ) const
+{
+ return constOptions()->fillColor();
+}
+
+// Rule to use when filling drawn objects
+void Magick::Image::fillRule ( const Magick::FillRule &fillRule_ )
+{
+ modifyImage();
+ options()->fillRule(fillRule_);
+}
+Magick::FillRule Magick::Image::fillRule ( void ) const
+{
+ return constOptions()->fillRule();
+}
+
+// Pattern to use while filling drawn objects.
+void Magick::Image::fillPattern ( const Image &fillPattern_ )
+{
+ modifyImage();
+ if(fillPattern_.isValid())
+ options()->fillPattern( fillPattern_.constImage() );
+ else
+ options()->fillPattern( static_cast<MagickLib::Image*>(NULL) );
+}
+Magick::Image Magick::Image::fillPattern ( void ) const
+{
+ // FIXME: This is inordinately innefficient
+ Image texture;
+
+ const MagickLib::Image* tmpTexture = constOptions()->fillPattern( );
+
+ if ( tmpTexture )
+ {
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ CloneImage( tmpTexture,
+ 0, // columns
+ 0, // rows
+ 1, // orphan
+ &exceptionInfo);
+ texture.replaceImage( image );
+ throwImageException( exceptionInfo );
+ }
+ return texture;
+}
+
+// Filter used by zoom
+void Magick::Image::filterType ( const Magick::FilterTypes filterType_ )
+{
+ modifyImage();
+ image()->filter = filterType_;
+}
+Magick::FilterTypes Magick::Image::filterType ( void ) const
+{
+ return constImage()->filter;
+}
+
+// Font name
+void Magick::Image::font ( const std::string &font_ )
+{
+ modifyImage();
+ options()->font( font_ );
+}
+std::string Magick::Image::font ( void ) const
+{
+ return constOptions()->font( );
+}
+
+// Font point size
+void Magick::Image::fontPointsize ( const double pointSize_ )
+{
+ modifyImage();
+ options()->fontPointsize( pointSize_ );
+}
+double Magick::Image::fontPointsize ( void ) const
+{
+ return constOptions()->fontPointsize( );
+}
+
+// Font type metrics
+void Magick::Image::fontTypeMetrics ( const std::string &text_,
+ TypeMetric *metrics )
+{
+ DrawInfo *drawInfo = options()->drawInfo();
+ drawInfo->text = const_cast<char *>(text_.c_str());
+ if (GetTypeMetrics( image(), drawInfo, &(metrics->_typeMetric) )
+ != MagickPass)
+ throwImageException();
+ drawInfo->text = 0;
+}
+
+// Image format string
+std::string Magick::Image::format ( void ) const
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ const MagickInfo * magick_info
+ = GetMagickInfo( constImage()->magick, &exceptionInfo);
+ throwImageException( exceptionInfo );
+
+ if (( magick_info != 0 ) &&
+ ( *magick_info->description != '\0' ))
+ return std::string(magick_info->description);
+
+ throwExceptionExplicit( CorruptImageWarning,
+ "Unrecognized image magick type" );
+ return std::string();
+}
+
+// Format the specified expression similar to command line '-format'.
+// For example "%wx%h" is converted to a string containing image
+// WIDTHxHEIGHT like "640x480".
+std::string Magick::Image::formatExpression ( const std::string expression )
+{
+ // TranslateText throws exceptions into Image.
+ modifyImage();
+ //MagickLib::Image = image( );
+ char *translated = MagickLib::TranslateText(constImageInfo( ),
+ image( ),
+ expression.c_str());
+ std::string translated_str;
+ if (translated != (char *) NULL)
+ {
+ translated_str=std::string(translated);
+ MagickFreeMemory(translated);
+ }
+ throwImageException( image( )->exception );
+ return translated_str;
+}
+
+// Gamma adjustment
+double Magick::Image::gamma ( void ) const
+{
+ return constImage()->gamma;
+}
+
+Magick::Geometry Magick::Image::geometry ( void ) const
+{
+ if ( constImage()->geometry )
+ {
+ return Geometry(constImage()->geometry);
+ }
+
+ throwExceptionExplicit( OptionWarning,
+ "Image does not contain a geometry");
+
+ return Geometry();
+}
+
+void Magick::Image::gifDisposeMethod ( const unsigned int disposeMethod_ )
+{
+ modifyImage();
+ image()->dispose = (DisposeType) disposeMethod_;
+}
+unsigned int Magick::Image::gifDisposeMethod ( void ) const
+{
+ // FIXME: It would be better to return an enumeration
+ return constImage()->dispose;
+}
+
+// ICC ICM color profile (BLOB)
+void Magick::Image::iccColorProfile( const Magick::Blob &colorProfile_ )
+{
+ profile("ICM",colorProfile_);
+}
+Magick::Blob Magick::Image::iccColorProfile( void ) const
+{
+ size_t length=0;
+ const void *data= (const void *) GetImageProfile(constImage(),"ICM",&length);
+ return Blob(data, length);
+}
+
+void Magick::Image::interlaceType ( const Magick::InterlaceType interlace_ )
+{
+ modifyImage();
+ image()->interlace = interlace_;
+ options()->interlaceType ( interlace_ );
+}
+Magick::InterlaceType Magick::Image::interlaceType ( void ) const
+{
+ return constImage()->interlace;
+}
+
+// IPTC profile (BLOB)
+void Magick::Image::iptcProfile( const Magick::Blob &iptcProfile_ )
+{
+ modifyImage();
+ SetImageProfile(image(),"IPTC",(const unsigned char*)iptcProfile_.data(),
+ iptcProfile_.length());
+}
+Magick::Blob Magick::Image::iptcProfile( void ) const
+{
+ size_t length=0;
+ const void *data=(const void *) GetImageProfile(constImage(),"IPTC",&length);
+ return Blob(data, length);
+}
+
+// Does object contain valid image?
+void Magick::Image::isValid ( const bool isValid_ )
+{
+ if ( !isValid_ )
+ {
+ delete _imgRef;
+ _imgRef = new ImageRef;
+ }
+ else if ( !isValid() )
+ {
+ // Construct with single-pixel black image to make
+ // image valid. This is an obvious hack.
+ size( Geometry(1,1) );
+ read( "xc:#000000" );
+ }
+}
+
+bool Magick::Image::isValid ( void ) const
+{
+ if ( rows() && columns() )
+ return true;
+
+ return false;
+}
+
+// Label image
+void Magick::Image::label ( const std::string &label_ )
+{
+ modifyImage();
+ SetImageAttribute ( image(), "Label", NULL );
+ if ( label_.length() > 0 )
+ SetImageAttribute ( image(), "Label", label_.c_str() );
+ throwImageException();
+}
+std::string Magick::Image::label ( void ) const
+{
+ const ImageAttribute * attribute =
+ GetImageAttribute( constImage(), "Label" );
+
+ if ( attribute )
+ return std::string( attribute->value );
+
+ return std::string();
+}
+
+void Magick::Image::magick ( const std::string &magick_ )
+{
+ modifyImage();
+
+ magick_.copy( image()->magick,
+ sizeof(image()->magick) - 1 );
+ image()->magick[ magick_.length() ] = 0;
+
+ options()->magick( magick_ );
+}
+std::string Magick::Image::magick ( void ) const
+{
+ if ( *(constImage()->magick) != '\0' )
+ return std::string(constImage()->magick);
+
+ return constOptions()->magick( );
+}
+
+void Magick::Image::matte ( const bool matteFlag_ )
+{
+ modifyImage();
+
+ // If matte channel is requested, but image doesn't already have a
+ // matte channel, then create an opaque matte channel. Likewise, if
+ // the image already has a matte channel but a matte channel is not
+ // desired, then set the matte channel to opaque.
+ if ((matteFlag_ && !constImage()->matte) ||
+ (constImage()->matte && !matteFlag_))
+ SetImageOpacity(image(),OpaqueOpacity);
+
+ image()->matte = matteFlag_;
+}
+bool Magick::Image::matte ( void ) const
+{
+ if ( constImage()->matte )
+ return true;
+ else
+ return false;
+}
+
+void Magick::Image::matteColor ( const Color &matteColor_ )
+{
+ modifyImage();
+
+ if ( matteColor_.isValid() )
+ {
+ image()->matte_color = matteColor_;
+ options()->matteColor( matteColor_ );
+ }
+ else
+ {
+ // Set to default matte color
+ Color tmpColor( "#BDBDBD" );
+ image()->matte_color = tmpColor;
+ options()->matteColor( tmpColor );
+ }
+}
+Magick::Color Magick::Image::matteColor ( void ) const
+{
+ return Color( constImage()->matte_color.red,
+ constImage()->matte_color.green,
+ constImage()->matte_color.blue );
+}
+
+double Magick::Image::meanErrorPerPixel ( void ) const
+{
+ return(constImage()->error.mean_error_per_pixel);
+}
+
+// Image modulus depth (minimum number of bits required to support
+// red/green/blue components without loss of accuracy)
+void Magick::Image::modulusDepth ( const unsigned int depth_ )
+{
+ modifyImage();
+ SetImageDepth( image(), depth_ );
+ options()->depth( depth_ );
+}
+unsigned int Magick::Image::modulusDepth ( void ) const
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ unsigned int depth=GetImageDepth( constImage(), &exceptionInfo );
+ throwImageException( exceptionInfo );
+ return depth;
+}
+
+void Magick::Image::monochrome ( const bool monochromeFlag_ )
+{
+ modifyImage();
+ options()->monochrome( monochromeFlag_ );
+}
+bool Magick::Image::monochrome ( void ) const
+{
+ return constOptions()->monochrome( );
+}
+
+Magick::Geometry Magick::Image::montageGeometry ( void ) const
+{
+ if ( constImage()->montage )
+ return Magick::Geometry(constImage()->montage);
+
+ throwExceptionExplicit( CorruptImageWarning,
+ "Image does not contain a montage" );
+
+ return Magick::Geometry();
+}
+
+double Magick::Image::normalizedMaxError ( void ) const
+{
+ return(constImage()->error.normalized_maximum_error);
+}
+
+double Magick::Image::normalizedMeanError ( void ) const
+{
+ return constImage()->error.normalized_mean_error;
+}
+
+// Image orientation
+void Magick::Image::orientation ( const Magick::OrientationType orientation_ )
+{
+ modifyImage();
+ image()->orientation = orientation_;
+ char orientation[MaxTextExtent];
+ FormatString(orientation,"%d",constImage()->orientation);
+ (void) SetImageAttribute(image(),"EXIF:Orientation",orientation);
+}
+Magick::OrientationType Magick::Image::orientation ( void ) const
+{
+ return constImage()->orientation;
+}
+
+void Magick::Image::penColor ( const Color &penColor_ )
+{
+ modifyImage();
+ options()->fillColor(penColor_);
+ options()->strokeColor(penColor_);
+}
+Magick::Color Magick::Image::penColor ( void ) const
+{
+ return constOptions()->fillColor();
+}
+
+void Magick::Image::penTexture ( const Image &penTexture_ )
+{
+ modifyImage();
+ if(penTexture_.isValid())
+ options()->fillPattern( penTexture_.constImage() );
+ else
+ options()->fillPattern( static_cast<MagickLib::Image*>(NULL) );
+}
+
+Magick::Image Magick::Image::penTexture ( void ) const
+{
+ // FIXME: This is inordinately innefficient
+ Image texture;
+
+ const MagickLib::Image* tmpTexture = constOptions()->fillPattern( );
+
+ if ( tmpTexture )
+ {
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ CloneImage( tmpTexture,
+ 0, // columns
+ 0, // rows
+ 1, // orphan
+ &exceptionInfo);
+ texture.replaceImage( image );
+ throwImageException( exceptionInfo );
+ }
+ return texture;
+}
+
+// Set the color of a pixel.
+void Magick::Image::pixelColor ( const unsigned int x_, const unsigned int y_,
+ const Color &color_ )
+{
+ // Test arguments to ensure they are within the image.
+ if ( y_ > rows() || x_ > columns() )
+ throwExceptionExplicit( OptionError,
+ "Access outside of image boundary" );
+
+ modifyImage();
+
+ // Set image to DirectClass
+ classType( DirectClass );
+
+ // Get pixel view
+ Pixels pixels(*this);
+ // Set pixel value
+ *(pixels.get(x_, y_, 1, 1 )) = color_;
+ // Tell ImageMagick that pixels have been updated
+ pixels.sync();
+
+ return;
+}
+// Get the color of a pixel
+Magick::Color Magick::Image::pixelColor ( const unsigned int x_,
+ const unsigned int y_ ) const
+{
+ ClassType storage_class;
+ storage_class = classType();
+ // DirectClass
+ const PixelPacket* pixel = getConstPixels( x_, y_, 1, 1 );
+ if ( storage_class == DirectClass )
+ {
+ if ( pixel )
+ return Color( *pixel );
+ }
+
+ // PseudoClass
+ if ( storage_class == PseudoClass )
+ {
+ const IndexPacket* indexes = getConstIndexes();
+ if ( indexes )
+ return colorMap( *indexes );
+ }
+
+ return Color(); // invalid
+}
+
+// Preferred size and location of an image canvas.
+void Magick::Image::page ( const Magick::Geometry &pageSize_ )
+{
+ modifyImage();
+ options()->page( pageSize_ );
+ image()->page = pageSize_;
+}
+Magick::Geometry Magick::Image::page ( void ) const
+{
+ return Geometry( constImage()->page.width,
+ constImage()->page.height,
+ AbsoluteValue(constImage()->page.x),
+ AbsoluteValue(constImage()->page.y),
+ constImage()->page.x < 0 ? true : false,
+ constImage()->page.y < 0 ? true : false);
+}
+
+// Add a named profile to an an image or remove a named profile by
+// passing an empty Blob (use default Blob constructor).
+// Valid names are:
+// "*", "8BIM", "ICM", "IPTC", or a generic profile name.
+void Magick::Image::profile( const std::string name_,
+ const Magick::Blob &profile_ )
+{
+ modifyImage();
+ int result = ProfileImage( image(), name_.c_str(),
+ (unsigned char *)profile_.data(),
+ profile_.length(), true);
+
+ if( !result )
+ throwImageException();
+}
+
+// Retrieve a named profile from the image.
+// Valid names are:
+// "8BIM", "8BIMTEXT", "APP1", "APP1JPEG", "ICC", "ICM", & "IPTC" or
+// an existing generic profile name.
+Magick::Blob Magick::Image::profile( const std::string name_ ) const
+{
+ size_t length=0;
+ const void *data=(const void *)
+ GetImageProfile(constImage(),name_.c_str(),&length);
+
+ if (data)
+ return Blob(data, length);
+
+ Blob blob;
+ Image temp_image = *this;
+ temp_image.write( &blob, name_ );
+ return blob;
+}
+
+void Magick::Image::quality ( const unsigned int quality_ )
+{
+ modifyImage();
+ options()->quality( quality_ );
+}
+unsigned int Magick::Image::quality ( void ) const
+{
+ return constOptions()->quality( );
+}
+
+void Magick::Image::quantizeColors ( const unsigned int colors_ )
+{
+ modifyImage();
+ options()->quantizeColors( colors_ );
+}
+unsigned int Magick::Image::quantizeColors ( void ) const
+{
+ return constOptions()->quantizeColors( );
+}
+
+void Magick::Image::quantizeColorSpace
+ ( const Magick::ColorspaceType colorSpace_ )
+{
+ modifyImage();
+ options()->quantizeColorSpace( colorSpace_ );
+}
+Magick::ColorspaceType Magick::Image::quantizeColorSpace ( void ) const
+{
+ return constOptions()->quantizeColorSpace( );
+}
+
+void Magick::Image::quantizeDither ( const bool ditherFlag_ )
+{
+ modifyImage();
+ options()->quantizeDither( ditherFlag_ );
+}
+bool Magick::Image::quantizeDither ( void ) const
+{
+ return constOptions()->quantizeDither( );
+}
+
+void Magick::Image::quantizeTreeDepth ( const unsigned int treeDepth_ )
+{
+ modifyImage();
+ options()->quantizeTreeDepth( treeDepth_ );
+}
+unsigned int Magick::Image::quantizeTreeDepth ( void ) const
+{
+ return constOptions()->quantizeTreeDepth( );
+}
+
+void Magick::Image::quiet ( const bool quiet_ )
+{
+ modifyImage();
+ options()->quiet(quiet_);
+}
+
+bool Magick::Image::quiet ( void ) const
+{
+ return(constOptions()->quiet());
+}
+
+void Magick::Image::renderingIntent
+ ( const Magick::RenderingIntent renderingIntent_ )
+{
+ modifyImage();
+ image()->rendering_intent = renderingIntent_;
+}
+Magick::RenderingIntent Magick::Image::renderingIntent ( void ) const
+{
+ return static_cast<Magick::RenderingIntent>(constImage()->rendering_intent);
+}
+
+void Magick::Image::resolutionUnits
+ ( const Magick::ResolutionType resolutionUnits_ )
+{
+ modifyImage();
+ image()->units = resolutionUnits_;
+ options()->resolutionUnits( resolutionUnits_ );
+}
+Magick::ResolutionType Magick::Image::resolutionUnits ( void ) const
+{
+ Magick::ResolutionType units;
+ const MagickLib::Image *image = constImage( );
+ if (image)
+ units = image->units;
+ else
+ units = constOptions()->resolutionUnits( );
+
+ return units;
+}
+
+void Magick::Image::scene ( const unsigned int scene_ )
+{
+ modifyImage();
+ image()->scene = scene_;
+}
+unsigned int Magick::Image::scene ( void ) const
+{
+ return constImage()->scene;
+}
+
+std::string Magick::Image::signature ( const bool force_ ) const
+{
+ Lock lock( &_imgRef->_mutexLock );
+
+ // Re-calculate image signature if necessary
+ if ( (force_) ||
+ !GetImageAttribute(constImage(), "Signature") ||
+ constImage()->taint )
+ {
+ SignatureImage( const_cast<MagickLib::Image *>(constImage()) );
+ }
+
+ const ImageAttribute * attribute =
+ GetImageAttribute(constImage(), "Signature");
+ if ((attribute != (const ImageAttribute *) NULL) &&
+ (attribute->value != (const char *) NULL))
+ return std::string( attribute->value );
+ else
+ return std::string();
+}
+
+void Magick::Image::size ( const Geometry &geometry_ )
+{
+ modifyImage();
+ options()->size( geometry_ );
+ image()->rows = geometry_.height();
+ image()->columns = geometry_.width();
+}
+Magick::Geometry Magick::Image::size ( void ) const
+{
+ return Magick::Geometry( constImage()->columns, constImage()->rows );
+}
+
+// Obtain image statistics. Statistics are normalized to the range of
+// 0.0 to 1.0 and are output to the specified ImageStatistics
+// structure.
+void Magick::Image::statistics ( ImageStatistics *statistics ) const
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ GetImageStatistics( constImage(), statistics, &exceptionInfo );
+ throwImageException( exceptionInfo );
+}
+
+// enabled/disable stroke anti-aliasing
+void Magick::Image::strokeAntiAlias ( const bool flag_ )
+{
+ modifyImage();
+ options()->strokeAntiAlias(flag_);
+}
+bool Magick::Image::strokeAntiAlias ( void ) const
+{
+ return constOptions()->strokeAntiAlias();
+}
+
+// Color to use when drawing object outlines
+void Magick::Image::strokeColor ( const Magick::Color &strokeColor_ )
+{
+ modifyImage();
+ options()->strokeColor(strokeColor_);
+}
+Magick::Color Magick::Image::strokeColor ( void ) const
+{
+ return constOptions()->strokeColor();
+}
+
+// dash pattern for drawing vector objects (default one)
+void Magick::Image::strokeDashArray ( const double* strokeDashArray_ )
+{
+ modifyImage();
+ options()->strokeDashArray( strokeDashArray_ );
+}
+
+const double* Magick::Image::strokeDashArray ( void ) const
+{
+ return constOptions()->strokeDashArray( );
+}
+
+// dash offset for drawing vector objects (default one)
+void Magick::Image::strokeDashOffset ( const double strokeDashOffset_ )
+{
+ modifyImage();
+ options()->strokeDashOffset( strokeDashOffset_ );
+}
+
+double Magick::Image::strokeDashOffset ( void ) const
+{
+ return constOptions()->strokeDashOffset( );
+}
+
+// Specify the shape to be used at the end of open subpaths when they
+// are stroked. Values of LineCap are UndefinedCap, ButtCap, RoundCap,
+// and SquareCap.
+void Magick::Image::strokeLineCap ( const Magick::LineCap lineCap_ )
+{
+ modifyImage();
+ options()->strokeLineCap( lineCap_ );
+}
+Magick::LineCap Magick::Image::strokeLineCap ( void ) const
+{
+ return constOptions()->strokeLineCap( );
+}
+
+// Specify the shape to be used at the corners of paths (or other
+// vector shapes) when they are stroked. Values of LineJoin are
+// UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
+void Magick::Image::strokeLineJoin ( const Magick::LineJoin lineJoin_ )
+{
+ modifyImage();
+ options()->strokeLineJoin( lineJoin_ );
+}
+Magick::LineJoin Magick::Image::strokeLineJoin ( void ) const
+{
+ return constOptions()->strokeLineJoin( );
+}
+
+// Specify miter limit. When two line segments meet at a sharp angle
+// and miter joins have been specified for 'lineJoin', it is possible
+// for the miter to extend far beyond the thickness of the line
+// stroking the path. The miterLimit' imposes a limit on the ratio of
+// the miter length to the 'lineWidth'. The default value of this
+// parameter is 4.
+void Magick::Image::strokeMiterLimit ( const unsigned int strokeMiterLimit_ )
+{
+ modifyImage();
+ options()->strokeMiterLimit( strokeMiterLimit_ );
+}
+unsigned int Magick::Image::strokeMiterLimit ( void ) const
+{
+ return constOptions()->strokeMiterLimit( );
+}
+
+// Pattern to use while stroking drawn objects.
+void Magick::Image::strokePattern ( const Image &strokePattern_ )
+{
+ modifyImage();
+ if(strokePattern_.isValid())
+ options()->strokePattern( strokePattern_.constImage() );
+ else
+ options()->strokePattern( static_cast<MagickLib::Image*>(NULL) );
+}
+Magick::Image Magick::Image::strokePattern ( void ) const
+{
+ // FIXME: This is inordinately innefficient
+ Image texture;
+
+ const MagickLib::Image* tmpTexture = constOptions()->strokePattern( );
+
+ if ( tmpTexture )
+ {
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* image =
+ CloneImage( tmpTexture,
+ 0, // columns
+ 0, // rows
+ 1, // orphan
+ &exceptionInfo);
+ throwImageException( exceptionInfo );
+ texture.replaceImage( image );
+ }
+ return texture;
+}
+
+// Stroke width for drawing lines, circles, ellipses, etc.
+void Magick::Image::strokeWidth ( const double strokeWidth_ )
+{
+ modifyImage();
+ options()->strokeWidth( strokeWidth_ );
+}
+double Magick::Image::strokeWidth ( void ) const
+{
+ return constOptions()->strokeWidth( );
+}
+
+void Magick::Image::subImage ( const unsigned int subImage_ )
+{
+ modifyImage();
+ options()->subImage( subImage_ );
+}
+unsigned int Magick::Image::subImage ( void ) const
+{
+ return constOptions()->subImage( );
+}
+
+void Magick::Image::subRange ( const unsigned int subRange_ )
+{
+ modifyImage();
+ options()->subRange( subRange_ );
+}
+unsigned int Magick::Image::subRange ( void ) const
+{
+ return constOptions()->subRange( );
+}
+
+// Annotation text encoding (e.g. "UTF-16")
+void Magick::Image::textEncoding ( const std::string &encoding_ )
+{
+ modifyImage();
+ options()->textEncoding( encoding_ );
+}
+std::string Magick::Image::textEncoding ( void ) const
+{
+ return constOptions()->textEncoding( );
+}
+
+void Magick::Image::tileName ( const std::string &tileName_ )
+{
+ modifyImage();
+ options()->tileName( tileName_ );
+}
+std::string Magick::Image::tileName ( void ) const
+{
+ return constOptions()->tileName( );
+}
+
+unsigned long Magick::Image::totalColors ( void )
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ unsigned long colors = GetNumberColors( image(), 0, &exceptionInfo);
+ throwImageException( exceptionInfo );
+ return colors;
+}
+
+// Origin of coordinate system to use when annotating with text or drawing
+void Magick::Image::transformOrigin ( const double x_, const double y_ )
+{
+ modifyImage();
+ options()->transformOrigin( x_, y_ );
+}
+
+// Rotation to use when annotating with text or drawing
+void Magick::Image::transformRotation ( const double angle_ )
+{
+ modifyImage();
+ options()->transformRotation( angle_ );
+}
+
+// Reset transformation parameters to default
+void Magick::Image::transformReset ( void )
+{
+ modifyImage();
+ options()->transformReset();
+}
+
+// Scale to use when annotating with text or drawing
+void Magick::Image::transformScale ( const double sx_, const double sy_ )
+{
+ modifyImage();
+ options()->transformScale( sx_, sy_ );
+}
+
+// Skew to use in X axis when annotating with text or drawing
+void Magick::Image::transformSkewX ( const double skewx_ )
+{
+ modifyImage();
+ options()->transformSkewX( skewx_ );
+}
+
+// Skew to use in Y axis when annotating with text or drawing
+void Magick::Image::transformSkewY ( const double skewy_ )
+{
+ modifyImage();
+ options()->transformSkewY( skewy_ );
+}
+
+// Image representation type
+Magick::ImageType Magick::Image::type ( void ) const
+{
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ ImageType image_type = constOptions()->type();
+ if ( image_type == UndefinedType )
+ image_type= GetImageType(constImage(), &exceptionInfo);
+ throwImageException( exceptionInfo );
+ return image_type;
+}
+void Magick::Image::type ( const Magick::ImageType type_)
+{
+ modifyImage();
+ options()->type( type_ );
+ SetImageType( image(), type_ );
+}
+
+void Magick::Image::verbose ( const bool verboseFlag_ )
+{
+ modifyImage();
+ options()->verbose( verboseFlag_ );
+}
+bool Magick::Image::verbose ( void ) const
+{
+ return constOptions()->verbose( );
+}
+
+void Magick::Image::view ( const std::string &view_ )
+{
+ modifyImage();
+ options()->view( view_ );
+}
+std::string Magick::Image::view ( void ) const
+{
+ return constOptions()->view( );
+}
+
+void Magick::Image::x11Display ( const std::string &display_ )
+{
+ modifyImage();
+ options()->x11Display( display_ );
+}
+std::string Magick::Image::x11Display ( void ) const
+{
+ return constOptions()->x11Display( );
+}
+
+void Magick::Image::xResolution ( const double x_resolution )
+{
+ modifyImage();
+ image()->x_resolution = x_resolution;
+}
+double Magick::Image::xResolution ( void ) const
+{
+ return constImage()->x_resolution;
+}
+
+void Magick::Image::yResolution ( const double y_resolution )
+{
+ modifyImage();
+ image()->y_resolution = y_resolution;
+}
+double Magick::Image::yResolution ( void ) const
+{
+ return constImage()->y_resolution;
+}
+
+// Copy Constructor
+Magick::Image::Image( const Image & image_ )
+ : _imgRef(image_._imgRef)
+{
+ Lock lock( &_imgRef->_mutexLock );
+
+ // Increase reference count
+ ++_imgRef->_refCount;
+}
+
+// Assignment operator
+Magick::Image& Magick::Image::operator=( const Magick::Image &image_ )
+{
+ if( this != &image_ )
+ {
+ {
+ Lock lock( &image_._imgRef->_mutexLock );
+ ++image_._imgRef->_refCount;
+ }
+
+ bool doDelete = false;
+ {
+ Lock lock( &_imgRef->_mutexLock );
+ if ( --_imgRef->_refCount == 0 )
+ doDelete = true;
+ }
+
+ if ( doDelete )
+ {
+ // Delete old image reference with associated image and options.
+ delete _imgRef;
+ _imgRef = 0;
+ }
+ // Use new image reference
+ _imgRef = image_._imgRef;
+ }
+
+ return *this;
+}
+
+//////////////////////////////////////////////////////////////////////
+//
+// Low-level Pixel Access Routines
+//
+// Also see the Pixels class, which provides support for multiple
+// cache views. The low-level pixel access routines in the Image
+// class are provided in order to support backward compatability.
+//
+//////////////////////////////////////////////////////////////////////
+
+// Transfers read-only pixels from the image to the pixel cache as
+// defined by the specified region
+const Magick::PixelPacket* Magick::Image::getConstPixels
+ ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ ) const
+{
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ const PixelPacket* p = AcquireImagePixels( constImage(),
+ x_, y_,
+ columns_, rows_,
+ &exceptionInfo );
+ throwImageException( exceptionInfo );
+ return p;
+}
+
+// Obtain read-only pixel indexes (valid for PseudoClass images)
+const Magick::IndexPacket* Magick::Image::getConstIndexes ( void ) const
+{
+ const Magick::IndexPacket* result = AccessImmutableIndexes( constImage() );
+
+ if( !result )
+ throwImageException();
+
+ return result;
+}
+
+// Obtain image pixel indexes (valid for PseudoClass images)
+Magick::IndexPacket* Magick::Image::getIndexes ( void )
+{
+ Magick::IndexPacket* result = AccessMutableIndexes( image() );
+
+ if( !result )
+ throwImageException();
+
+ return ( result );
+}
+
+// Transfers pixels from the image to the pixel cache as defined
+// by the specified region. Modified pixels may be subsequently
+// transferred back to the image via syncPixels.
+Magick::PixelPacket* Magick::Image::getPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+{
+ modifyImage();
+ PixelPacket* result = GetImagePixels( image(),
+ x_, y_,
+ columns_, rows_ );
+ if( !result )
+ throwImageException();
+
+ return result;
+}
+
+// Allocates a pixel cache region to store image pixels as defined
+// by the region rectangle. This area is subsequently transferred
+// from the pixel cache to the image via syncPixels.
+Magick::PixelPacket* Magick::Image::setPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+{
+ modifyImage();
+ PixelPacket* result = SetImagePixels( image(),
+ x_, y_,
+ columns_, rows_ );
+ if( !result )
+ throwImageException();
+
+ return result;
+}
+
+// Transfers the image cache pixels to the image.
+void Magick::Image::syncPixels ( void )
+{
+ if (SyncImagePixels( image() ) != MagickPass)
+ throwImageException();
+}
+
+// Transfers one or more pixel components from a buffer or file
+// into the image pixel cache of an image.
+// Used to support image decoders.
+void Magick::Image::readPixels ( const Magick::QuantumType quantum_,
+ const unsigned char *source_ )
+{
+ unsigned int quantum_size=depth();
+
+ if ( (quantum_ == IndexQuantum) || (quantum_ == IndexAlphaQuantum) )
+ {
+ if (colorMapSize() <= 256)
+ quantum_size=8;
+ else if (colorMapSize() <= 65536L)
+ quantum_size=16;
+ else
+ quantum_size=32;
+ }
+
+ (void) ImportImagePixelArea(image(),quantum_,quantum_size,source_,0,0);
+
+ throwImageException();
+}
+
+// Transfers one or more pixel components from the image pixel
+// cache to a buffer or file.
+// Used to support image encoders.
+void Magick::Image::writePixels ( const Magick::QuantumType quantum_,
+ unsigned char *destination_ )
+{
+ unsigned int quantum_size=depth();
+
+ if ( (quantum_ == IndexQuantum) || (quantum_ == IndexAlphaQuantum) )
+ {
+ if (colorMapSize() <= 256)
+ quantum_size=8;
+ else if (colorMapSize() <= 65536L)
+ quantum_size=16;
+ else
+ quantum_size=32;
+ }
+
+ (void) ExportImagePixelArea(image(),quantum_,quantum_size,destination_,0,0);
+
+ throwImageException();
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+// No end-user methods beyond this point
+//
+/////////////////////////////////////////////////////////////////////
+
+
+//
+// Construct using existing image and default options
+//
+Magick::Image::Image ( MagickLib::Image* image_ )
+ : _imgRef(new ImageRef( image_))
+{
+}
+
+// Get Magick::Options*
+Magick::Options* Magick::Image::options( void )
+{
+ return _imgRef->options();
+}
+const Magick::Options* Magick::Image::constOptions( void ) const
+{
+ return _imgRef->options();
+}
+
+// Get MagickLib::Image*
+MagickLib::Image*& Magick::Image::image( void )
+{
+ return _imgRef->image();
+}
+const MagickLib::Image* Magick::Image::constImage( void ) const
+{
+ return _imgRef->image();
+}
+
+// Get ImageInfo *
+MagickLib::ImageInfo* Magick::Image::imageInfo( void )
+{
+ return _imgRef->options()->imageInfo();
+}
+const MagickLib::ImageInfo * Magick::Image::constImageInfo( void ) const
+{
+ return _imgRef->options()->imageInfo();
+}
+
+// Get QuantizeInfo *
+MagickLib::QuantizeInfo* Magick::Image::quantizeInfo( void )
+{
+ return _imgRef->options()->quantizeInfo();
+}
+const MagickLib::QuantizeInfo * Magick::Image::constQuantizeInfo( void ) const
+{
+ return _imgRef->options()->quantizeInfo();
+}
+
+//
+// Replace current image
+//
+MagickLib::Image * Magick::Image::replaceImage
+ ( MagickLib::Image* replacement_ )
+{
+ MagickLib::Image* image;
+
+ if( replacement_ )
+ image = replacement_;
+ else
+ image = AllocateImage(constImageInfo());
+
+ {
+ Lock lock( &_imgRef->_mutexLock );
+
+ if ( _imgRef->_refCount == 1 )
+ {
+ // We own the image, just replace it, and de-register
+ _imgRef->id( -1 );
+ _imgRef->image(image);
+ }
+ else
+ {
+ // We don't own the image, dereference and replace with copy
+ --_imgRef->_refCount;
+ _imgRef = new ImageRef( image, constOptions() );
+ }
+ }
+
+ return _imgRef->_image;
+}
+
+//
+// Prepare to modify image or image options
+// Replace current image and options with copy if reference count > 1
+//
+void Magick::Image::modifyImage( void )
+{
+ {
+ Lock lock( &_imgRef->_mutexLock );
+ if ( _imgRef->_refCount == 1 )
+ {
+ // De-register image and return
+ _imgRef->id( -1 );
+ return;
+ }
+ }
+
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ replaceImage( CloneImage( image(),
+ 0, // columns
+ 0, // rows
+ 1, // orphan
+ &exceptionInfo) );
+ throwImageException( exceptionInfo );
+ return;
+}
+
+//
+// Test for an ImageMagick reported error and throw exception if one
+// has been reported. Secretly resets image->exception back to default
+// state even though this method is const.
+//
+void Magick::Image::throwImageException( void ) const
+{
+ // Throw C++ exception while resetting Image exception to default state
+ throwImageException( const_cast<MagickLib::Image*>(constImage())->exception );
+}
+
+// Register image with image registry or obtain registration id
+long Magick::Image::registerId( void )
+{
+ Lock lock( &_imgRef->_mutexLock );
+ if( _imgRef->id() < 0 )
+ {
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ _imgRef->id(SetMagickRegistry(ImageRegistryType, image(),
+ sizeof(MagickLib::Image),
+ &exceptionInfo));
+ throwImageException( exceptionInfo );
+ }
+ return _imgRef->id();
+}
+
+// Unregister image from image registry
+void Magick::Image::unregisterId( void )
+{
+ modifyImage();
+ _imgRef->id( -1 );
+}
+
+void Magick::Image::throwImageException( MagickLib::ExceptionInfo &exception_ ) const
+{
+ throwException( exception_, quiet() );
+}
+
+//
+// Create a local wrapper around DestroyMagick
+//
+namespace Magick
+{
+ extern "C" {
+ void MagickPlusPlusDestroyMagick(void);
+ }
+}
+
+void Magick::MagickPlusPlusDestroyMagick(void)
+{
+ if (magick_initialized)
+ {
+ magick_initialized=false;
+ MagickLib::DestroyMagick();
+ }
+}
+
+// C library initialization routine
+void MagickDLLDecl Magick::InitializeMagick(const char *path_)
+{
+ MagickLib::InitializeMagick(path_);
+ if (!magick_initialized)
+ {
+ magick_initialized=true;
+// atexit(MagickPlusPlusDestroyMagick);
+ }
+}
+
+//
+// Cleanup class to ensure that ImageMagick singletons are destroyed
+// so as to avoid any resemblence to a memory leak (which seems to
+// confuse users)
+//
+namespace Magick
+{
+
+ class MagickCleanUp
+ {
+ public:
+ MagickCleanUp( void );
+ ~MagickCleanUp( void );
+ };
+
+ // The destructor for this object is invoked when the destructors for
+ // static objects in this translation unit are invoked.
+ static MagickCleanUp magickCleanUpGuard;
+}
+
+Magick::MagickCleanUp::MagickCleanUp ( void )
+{
+ // Don't even think about invoking InitializeMagick here!
+}
+
+Magick::MagickCleanUp::~MagickCleanUp ( void )
+{
+ MagickPlusPlusDestroyMagick();
+}
diff --git a/Magick++/lib/ImageRef.cpp b/Magick++/lib/ImageRef.cpp
new file mode 100644
index 0000000..2dc3440
--- /dev/null
+++ b/Magick++/lib/ImageRef.cpp
@@ -0,0 +1,98 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
+//
+// Implementation of ImageRef
+//
+// This is an internal implementation class.
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/ImageRef.h"
+#include "Magick++/Exception.h"
+#include "Magick++/Options.h"
+
+// Construct with an image and default options
+Magick::ImageRef::ImageRef ( MagickLib::Image * image_ )
+ : _image(image_),
+ _options(new Options),
+ _id(-1),
+ _refCount(1),
+ _mutexLock()
+{
+}
+
+// Construct with an image and options
+// Inserts Image* in image, but copies Options into image.
+Magick::ImageRef::ImageRef ( MagickLib::Image * image_,
+ const Options * options_ )
+ : _image(image_),
+ _options(0),
+ _id(-1),
+ _refCount(1),
+ _mutexLock()
+{
+ _options = new Options( *options_ );
+}
+
+// Default constructor
+Magick::ImageRef::ImageRef ( void )
+ : _image(0),
+ _options(new Options),
+ _id(-1),
+ _refCount(1),
+ _mutexLock()
+{
+ // Allocate default image
+ _image = AllocateImage( _options->imageInfo() );
+
+ // Test for error and throw exception (like throwImageException())
+ throwException(_image->exception);
+}
+
+// Destructor
+Magick::ImageRef::~ImageRef( void )
+{
+ // Unregister image (if still registered)
+ if( _id > -1 )
+ {
+ DeleteMagickRegistry( _id );
+ _id=-1;
+ }
+
+ // Deallocate image
+ if ( _image )
+ {
+ DestroyImageList( _image );
+ _image = 0;
+ }
+
+ // Deallocate image options
+ delete _options;
+ _options = 0;
+}
+
+// Assign image to reference
+void Magick::ImageRef::image ( MagickLib::Image * image_ )
+{
+ if(_image)
+ DestroyImageList( _image );
+ _image = image_;
+}
+
+// Assign options to reference
+void Magick::ImageRef::options ( Magick::Options * options_ )
+{
+ delete _options;
+ _options = options_;
+}
+
+// Assign registration id to reference
+void Magick::ImageRef::id ( const long id_ )
+{
+ if( _id > -1 )
+ DeleteMagickRegistry( _id );
+ _id = id_;
+}
diff --git a/Magick++/lib/Magick++.h b/Magick++/lib/Magick++.h
new file mode 100644
index 0000000..a85f7da
--- /dev/null
+++ b/Magick++/lib/Magick++.h
@@ -0,0 +1,14 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000
+//
+// Simplified includes for Magick++.
+// Inclusion of this header is sufficient to use all Magick++ APIs.
+//
+#ifndef MagickPlusPlus_Header
+#include <Magick++/Include.h>
+#include <Magick++/Image.h>
+#include <Magick++/Pixels.h>
+#include <Magick++/STL.h>
+#define MagickPlusPlus_Header
+#endif // MagickPlusPlus_Header
diff --git a/Magick++/lib/Magick++/Blob.h b/Magick++/lib/Magick++/Blob.h
new file mode 100644
index 0000000..2179b0a
--- /dev/null
+++ b/Magick++/lib/Magick++/Blob.h
@@ -0,0 +1,82 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
+//
+// Reference counted container class for Binary Large Objects (BLOBs)
+//
+
+#if !defined(Magick_BlobRef_header)
+#define Magick_BlobRef_header
+
+#include "Magick++/Include.h"
+#include <string>
+
+namespace Magick
+{
+ // Forward decl
+ class BlobRef;
+
+ class MagickDLLDecl Blob
+ {
+
+ public:
+
+ enum Allocator
+ {
+ MallocAllocator,
+ NewAllocator
+ };
+
+ // Default constructor
+ Blob ( void );
+
+ // Construct object with data, making a copy of the supplied data.
+ Blob ( const void* data_, size_t length_ );
+
+ // Copy constructor (reference counted)
+ Blob ( const Blob& blob_ );
+
+ // Destructor (reference counted)
+ virtual ~Blob ();
+
+ // Assignment operator (reference counted)
+ Blob& operator= ( const Blob& blob_ );
+
+ // Update object contents from Base64-encoded string representation.
+ void base64 ( const std::string base64_ );
+ // Return Base64-encoded string representation.
+ std::string base64 ( void );
+
+ // Update object contents, making a copy of the supplied data.
+ // Any existing data in the object is deallocated.
+ void update ( const void* data_, size_t length_ );
+
+ // Update object contents, using supplied pointer directly (no
+ // copy). Any existing data in the object is deallocated. The user
+ // must ensure that the pointer supplied is not deleted or
+ // otherwise modified after it has been supplied to this method.
+ // Specify allocator_ as "MallocAllocator" if memory is allocated
+ // via the C language malloc() function, or "NewAllocator" if
+ // memory is allocated via C++ 'new'.
+ void updateNoCopy ( void* data_, size_t length_,
+ Allocator allocator_ = NewAllocator );
+
+ // Obtain pointer to data. The user should never try to modify or
+ // free this data since the Blob class manages its own data. The
+ // user must be finished with the data before allowing the Blob to
+ // be destroyed since the pointer is invalid once the Blob is
+ // destroyed.
+ const void* data ( void ) const;
+
+ // Obtain data length
+ size_t length ( void ) const;
+
+ protected:
+
+ private:
+ BlobRef * _blobRef;
+ };
+
+} // namespace Magick
+
+#endif // Magick_BlobRef_header
diff --git a/Magick++/lib/Magick++/BlobRef.h b/Magick++/lib/Magick++/BlobRef.h
new file mode 100644
index 0000000..c0a92fc
--- /dev/null
+++ b/Magick++/lib/Magick++/BlobRef.h
@@ -0,0 +1,46 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
+//
+// Blob reference class
+//
+// This is an internal implementation class that should not be
+// accessed by users.
+//
+
+#if !defined(Magick_Blob_header)
+#define Magick_Blob_header
+
+#include "Magick++/Include.h"
+#include "Magick++/Thread.h"
+#include "Magick++/Blob.h"
+
+namespace Magick
+{
+
+ class BlobRef {
+ public:
+ // There are no public methods in this class
+
+ // Construct with data, making private copy of data
+ BlobRef ( const void* data_, size_t length_ );
+
+ // Destructor (actually destroys data)
+ ~BlobRef ( void );
+
+ private:
+ // Copy constructor and assignment are not supported
+ BlobRef (const BlobRef&);
+ BlobRef& operator= (const BlobRef&);
+
+ public:
+ void * _data; // Blob data
+ size_t _length; // Blob length
+ Blob::Allocator _allocator; // Memory allocation system in use
+ int _refCount; // Reference count
+ MutexLock _mutexLock; // Mutex lock
+ };
+
+} // namespace Magick
+
+#endif // Magick_Blob_header
diff --git a/Magick++/lib/Magick++/CoderInfo.h b/Magick++/lib/Magick++/CoderInfo.h
new file mode 100644
index 0000000..5807758
--- /dev/null
+++ b/Magick++/lib/Magick++/CoderInfo.h
@@ -0,0 +1,79 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 2001-2010
+//
+// CoderInfo Definition
+//
+// Container for image format support information.
+//
+
+#if !defined (Magick_CoderInfo_header)
+#define Magick_CoderInfo_header
+
+#include "Magick++/Include.h"
+#include <string>
+
+namespace Magick
+{
+ class MagickDLLDecl CoderInfo
+ {
+ public:
+
+ enum MatchType {
+ AnyMatch, // match any coder
+ TrueMatch, // match coder if true
+ FalseMatch // match coder if false
+ };
+
+ // Default constructor
+ CoderInfo ( void );
+
+ // Copy constructor
+ CoderInfo ( const CoderInfo &coder_ );
+
+ // Construct with coder name
+ CoderInfo ( const std::string &name_ );
+
+ // Destructor
+ ~CoderInfo ( void );
+
+ // Format name
+ std::string name( void ) const;
+
+ // Format description
+ std::string description( void ) const;
+
+ // Format is readable
+ bool isReadable( void ) const;
+
+ // Format is writeable
+ bool isWritable( void ) const;
+
+ // Format supports multiple frames
+ bool isMultiFrame( void ) const;
+
+ // Assignment operator
+ CoderInfo& operator= (const CoderInfo &coder_ );
+
+ //
+ // Implemementation methods
+ //
+ CoderInfo ( const MagickLib::MagickInfo *magickInfo_ );
+
+ private:
+
+ std::string _name;
+ std::string _description;
+ bool _isReadable;
+ bool _isWritable;
+ bool _isMultiFrame;
+
+ };
+} // namespace Magick
+
+//
+// Inlines
+//
+
+
+#endif // Magick_CoderInfo_header
diff --git a/Magick++/lib/Magick++/Color.h b/Magick++/lib/Magick++/Color.h
new file mode 100644
index 0000000..c1820b7
--- /dev/null
+++ b/Magick++/lib/Magick++/Color.h
@@ -0,0 +1,462 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003, 2008
+//
+// Color Implementation
+//
+#if !defined (Magick_Color_header)
+#define Magick_Color_header
+
+#include "Magick++/Include.h"
+#include <string>
+
+namespace Magick
+{
+
+ class MagickDLLDecl Color;
+
+ // Compare two Color objects regardless of LHS/RHS
+ int MagickDLLDecl operator == ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator != ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator > ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator < ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator >= ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator <= ( const Magick::Color& left_, const Magick::Color& right_ );
+
+ // Base color class stores RGB components scaled to fit Quantum
+ class MagickDLLDecl Color
+ {
+ public:
+ Color ( Quantum red_,
+ Quantum green_,
+ Quantum blue_ );
+ Color ( Quantum red_,
+ Quantum green_,
+ Quantum blue_,
+ Quantum alpha_ );
+ Color ( const std::string &x11color_ );
+ Color ( const char * x11color_ );
+ Color ( void );
+ virtual ~Color ( void );
+ Color ( const Color & color_ );
+
+ // Red color (range 0 to MaxRGB)
+ void redQuantum ( Quantum red_ );
+ Quantum redQuantum ( void ) const;
+
+ // Green color (range 0 to MaxRGB)
+ void greenQuantum ( Quantum green_ );
+ Quantum greenQuantum ( void ) const;
+
+ // Blue color (range 0 to MaxRGB)
+ void blueQuantum ( Quantum blue_ );
+ Quantum blueQuantum ( void ) const;
+
+ // Alpha level (range OpaqueOpacity=0 to TransparentOpacity=MaxRGB)
+ void alphaQuantum ( Quantum alpha_ );
+ Quantum alphaQuantum ( void ) const;
+
+ // Scaled (to 1.0) version of alpha for use in sub-classes
+ // (range opaque=0 to transparent=1.0)
+ void alpha ( double alpha_ );
+ double alpha ( void ) const;
+
+ // Does object contain valid color?
+ void isValid ( bool valid_ );
+ bool isValid ( void ) const;
+
+ // Set color via X11 color specification string
+ const Color& operator= ( const std::string &x11color_ );
+ const Color& operator= ( const char * x11color_ );
+
+ // Assignment operator
+ Color& operator= ( const Color& color_ );
+
+ // Return X11 color specification string
+ /* virtual */ operator std::string() const;
+
+ // Return ImageMagick PixelPacket
+ operator PixelPacket() const;
+
+ // Construct color via ImageMagick PixelPacket
+ Color ( const PixelPacket &color_ );
+
+ // Set color via ImageMagick PixelPacket
+ const Color& operator= ( const PixelPacket &color_ );
+
+ //
+ // Public methods beyond this point are for Magick++ use only.
+ //
+
+ // Obtain pixel intensity as a double
+ double intensity ( void ) const
+ {
+ return (0.299*(_pixel->red)+0.587*(_pixel->green)+0.114*(_pixel->blue));
+ }
+
+ // Scale a value expressed as a double (0-1) to Quantum range (0-MaxRGB)
+ static Quantum scaleDoubleToQuantum( const double double_ )
+ {
+ return (static_cast<Magick::Quantum>(double_*MaxRGB));
+ }
+
+ // Scale a value expressed as a Quantum (0-MaxRGB) to double range (0-1)
+ static double scaleQuantumToDouble( const Quantum quantum_ )
+ {
+ return (static_cast<double>(quantum_)/MaxRGB);
+ }
+ static double scaleQuantumToDouble( const double quantum_ )
+ {
+ return (quantum_/MaxRGB);
+ }
+
+
+ protected:
+
+ // PixelType specifies the interpretation of PixelPacket members
+ // RGBPixel:
+ // Red = red;
+ // Green = green;
+ // Blue = blue;
+ // RGBAPixel:
+ // Red = red;
+ // Green = green;
+ // Blue = blue;
+ // Alpha = opacity;
+ // CYMKPixel:
+ // Cyan = red
+ // Yellow = green
+ // Magenta = blue
+ // Black(K) = opacity
+ enum PixelType
+ {
+ RGBPixel,
+ RGBAPixel,
+ CYMKPixel
+ };
+
+ // Constructor to construct with PixelPacket*
+ // Used to point Color at a pixel in an image
+ Color ( PixelPacket* rep_, PixelType pixelType_ );
+
+ // Set pixel
+ // Used to point Color at a pixel in an image
+ void pixel ( PixelPacket* rep_, PixelType pixelType_ );
+
+ // PixelPacket represents a color pixel:
+ // red = red (range 0 to MaxRGB)
+ // green = green (range 0 to MaxRGB)
+ // blue = blue (range 0 to MaxRGB)
+ // opacity = alpha (range OpaqueOpacity=0 to TransparentOpacity=MaxRGB)
+ // index = PseudoColor colormap index
+ PixelPacket* _pixel;
+
+ private:
+
+ // Common initializer for PixelPacket representation
+ void initPixel();
+
+ // Set true if we allocated pixel
+ bool _pixelOwn;
+
+ // Set true if pixel is "valid"
+ bool _isValid;
+
+ // Color type supported by _pixel
+ PixelType _pixelType;
+
+ };
+
+ //
+ // HSL Colorspace colors
+ //
+ class MagickDLLDecl ColorHSL : public Color
+ {
+ public:
+ ColorHSL ( double hue_, double saturation_, double luminosity_ );
+ ColorHSL ( void );
+ ColorHSL ( const Color & color_ );
+ /* virtual */ ~ColorHSL ( );
+
+ void hue ( double hue_ );
+ double hue ( void ) const;
+
+ void saturation ( double saturation_ );
+ double saturation ( void ) const;
+
+ void luminosity ( double luminosity_ );
+ double luminosity ( void ) const;
+
+ // Assignment operator from base class
+ ColorHSL& operator= ( const Color& color_ );
+
+ protected:
+ // Constructor to construct with PixelPacket*
+ ColorHSL ( PixelPacket* rep_, PixelType pixelType_ );
+ };
+
+ //
+ // Grayscale RGB color
+ //
+ // Grayscale is simply RGB with equal parts of red, green, and blue
+ // All double arguments have a valid range of 0.0 - 1.0.
+ class MagickDLLDecl ColorGray : public Color
+ {
+ public:
+ ColorGray ( double shade_ );
+ ColorGray ( void );
+ ColorGray ( const Color & color_ );
+ /* virtual */ ~ColorGray ();
+
+ void shade ( double shade_ );
+ double shade ( void ) const;
+
+ // Assignment operator from base class
+ ColorGray& operator= ( const Color& color_ );
+
+ protected:
+ // Constructor to construct with PixelPacket*
+ ColorGray ( PixelPacket* rep_, PixelType pixelType_ );
+ };
+
+ //
+ // Monochrome color
+ //
+ // Color arguments are constrained to 'false' (black pixel) and 'true'
+ // (white pixel)
+ class MagickDLLDecl ColorMono : public Color
+ {
+ public:
+ ColorMono ( bool mono_ );
+ ColorMono ( void );
+ ColorMono ( const Color & color_ );
+ /* virtual */ ~ColorMono ();
+
+ void mono ( bool mono_ );
+ bool mono ( void ) const;
+
+ // Assignment operator from base class
+ ColorMono& operator= ( const Color& color_ );
+
+ protected:
+ // Constructor to construct with PixelPacket*
+ ColorMono ( PixelPacket* rep_, PixelType pixelType_ );
+ };
+
+ //
+ // RGB color
+ //
+ // All color arguments have a valid range of 0.0 - 1.0.
+ class MagickDLLDecl ColorRGB : public Color
+ {
+ public:
+ ColorRGB ( double red_, double green_, double blue_ );
+ ColorRGB ( void );
+ ColorRGB ( const Color & color_ );
+ /* virtual */ ~ColorRGB ( void );
+
+ void red ( double red_ );
+ double red ( void ) const;
+
+ void green ( double green_ );
+ double green ( void ) const;
+
+ void blue ( double blue_ );
+ double blue ( void ) const;
+
+ // Assignment operator from base class
+ ColorRGB& operator= ( const Color& color_ );
+
+ protected:
+ // Constructor to construct with PixelPacket*
+ ColorRGB ( PixelPacket* rep_, PixelType pixelType_ );
+ };
+
+ //
+ // YUV Colorspace color
+ //
+ // Argument ranges:
+ // Y: 0.0 through 1.0
+ // U: -0.5 through 0.5
+ // V: -0.5 through 0.5
+ class MagickDLLDecl ColorYUV : public Color
+ {
+ public:
+ ColorYUV ( double y_, double u_, double v_ );
+ ColorYUV ( void );
+ ColorYUV ( const Color & color_ );
+ /* virtual */ ~ColorYUV ( void );
+
+ void u ( double u_ );
+ double u ( void ) const;
+
+ void v ( double v_ );
+ double v ( void ) const;
+
+ void y ( double y_ );
+ double y ( void ) const;
+
+ // Assignment operator from base class
+ ColorYUV& operator= ( const Color& color_ );
+
+ protected:
+ // Constructor to construct with PixelPacket*
+ ColorYUV ( PixelPacket* rep_, PixelType pixelType_ );
+ };
+} // namespace Magick
+
+//
+// Inlines
+//
+
+//
+// Color
+//
+
+// Common initializer for PixelPacket representation
+// Initialized transparent black
+inline void Magick::Color::initPixel()
+{
+ _pixel->red = 0;
+ _pixel->green = 0;
+ _pixel->blue = 0;
+ _pixel->opacity = TransparentOpacity;
+}
+
+inline void Magick::Color::redQuantum ( Magick::Quantum red_ )
+{
+ _pixel->red = red_;
+ _isValid = true;
+}
+
+inline Magick::Quantum Magick::Color::redQuantum ( void ) const
+{
+ return _pixel->red;
+}
+
+inline void Magick::Color::greenQuantum ( Magick::Quantum green_ )
+{
+ _pixel->green = green_;
+ _isValid = true;
+}
+
+inline Magick::Quantum Magick::Color::greenQuantum ( void ) const
+{
+ return _pixel->green;
+}
+
+inline void Magick::Color::blueQuantum ( Magick::Quantum blue_ )
+{
+ _pixel->blue = blue_;
+ _isValid = true;
+}
+
+inline Magick::Quantum Magick::Color::blueQuantum ( void ) const
+{
+ return _pixel->blue;
+}
+
+inline void Magick::Color::alphaQuantum ( Magick::Quantum alpha_ )
+{
+ _pixel->opacity = alpha_;
+ _isValid = true ;
+}
+
+inline Magick::Quantum Magick::Color::alphaQuantum ( void ) const
+{
+ return _pixel->opacity;
+}
+
+// Return ImageMagick PixelPacket struct based on color.
+inline Magick::Color::operator MagickLib::PixelPacket () const
+{
+ return *_pixel;
+}
+
+// Scaled version of alpha for use in sub-classes
+inline void Magick::Color::alpha ( double alpha_ )
+{
+ alphaQuantum( scaleDoubleToQuantum(alpha_) );
+}
+inline double Magick::Color::alpha ( void ) const
+{
+ return scaleQuantumToDouble( alphaQuantum() );
+}
+
+//
+// ColorHSL
+//
+inline Magick::ColorHSL::ColorHSL ( Magick::PixelPacket* rep_,
+ Magick::Color::PixelType pixelType_ )
+: Color( rep_, pixelType_ )
+{
+}
+
+//
+// ColorGray
+//
+inline Magick::ColorGray::ColorGray ( Magick::PixelPacket* rep_,
+ Magick::Color::PixelType pixelType_ )
+: Color( rep_, pixelType_ )
+{
+}
+
+//
+// ColorMono
+//
+inline Magick::ColorMono::ColorMono ( Magick::PixelPacket* rep_,
+ Magick::Color::PixelType pixelType_ )
+ : Color( rep_, pixelType_ )
+{
+}
+
+//
+// ColorRGB
+//
+inline Magick::ColorRGB::ColorRGB ( Magick::PixelPacket* rep_,
+ Magick::Color::PixelType pixelType_ )
+ : Color( rep_, pixelType_ )
+{
+}
+
+inline void Magick::ColorRGB::red ( double red_ )
+{
+ redQuantum( scaleDoubleToQuantum(red_) );
+}
+
+inline double Magick::ColorRGB::red ( void ) const
+{
+ return scaleQuantumToDouble( redQuantum() );
+}
+
+inline void Magick::ColorRGB::green ( double green_ )
+{
+ greenQuantum( scaleDoubleToQuantum(green_) );
+}
+
+inline double Magick::ColorRGB::green ( void ) const
+{
+ return scaleQuantumToDouble( greenQuantum() );
+}
+
+inline void Magick::ColorRGB::blue ( double blue_ )
+{
+ blueQuantum( scaleDoubleToQuantum(blue_) );
+}
+
+inline double Magick::ColorRGB::blue ( void ) const
+{
+ return scaleQuantumToDouble( blueQuantum() );
+}
+
+//
+// ColorYUV
+//
+
+inline Magick::ColorYUV::ColorYUV ( Magick::PixelPacket* rep_,
+ Magick::Color::PixelType pixelType_ )
+ : Color( rep_, pixelType_ )
+{
+}
+
+#endif // Magick_Color_header
diff --git a/Magick++/lib/Magick++/Drawable.h b/Magick++/lib/Magick++/Drawable.h
new file mode 100644
index 0000000..9d2e32e
--- /dev/null
+++ b/Magick++/lib/Magick++/Drawable.h
@@ -0,0 +1,2921 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
+//
+// Definition of Drawable (Graphic objects)
+//
+// The technique used for instantiating classes which derive from STL
+// templates is described in Microsoft MSDN Article ID: Q168958
+// "HOWTO: Exporting STL Components Inside & Outside of a Class".
+// "http://support.microsoft.com/kb/168958"
+//
+// Note that version 3.0 of this article says that that only STL
+// container template which supports DLL export is <vector> and we are
+// not using <vector> as part of the Drawable implementation.
+//
+
+#if !defined(Magick_Drawable_header)
+#define Magick_Drawable_header
+
+#include "Magick++/Include.h"
+
+#include <functional>
+#include <string>
+#include <list>
+#include <utility>
+#include "Magick++/Color.h"
+#include "Magick++/Geometry.h"
+
+#if defined(MagickDLLExplicitTemplate)
+# if defined(MAGICK_PLUSPLUS_IMPLEMENTATION)
+# define MagickDrawableExtern
+# else
+# pragma warning( disable: 4231 ) // Disable warning regarding using extern
+# define MagickDrawableExtern extern
+# endif // MAGICK_PLUSPLUS_IMPLEMENTATION
+#else
+# define MagickDrawableExtern
+#endif // MagickDLLExplicitTemplate
+
+namespace Magick
+{
+
+ //
+ // Representation of an x,y coordinate
+ //
+ class MagickDLLDecl Coordinate
+ {
+ public:
+
+ // Default Constructor
+ Coordinate ( void )
+ : _x(0),
+ _y(0)
+ { }
+
+ // Constructor, setting first & second
+ Coordinate ( double x_, double y_ )
+ : _x(x_),
+ _y(y_)
+ { }
+
+ // Destructor
+ virtual ~Coordinate ()
+ { }
+
+ // x coordinate member
+ void x ( double x_ )
+ {
+ _x = x_;
+ }
+ double x ( void ) const
+ {
+ return _x;
+ }
+
+ // y coordinate member
+ void y ( double y_ )
+ {
+ _y = y_;
+ }
+ double y ( void ) const
+ {
+ return _y;
+ }
+
+ private:
+ double _x;
+ double _y;
+ };
+
+ typedef std::list<Magick::Coordinate> CoordinateList;
+
+#if defined(MagickDLLExplicitTemplate)
+
+ MagickDrawableExtern template class MagickDLLDecl
+ std::allocator<Magick::Coordinate>;
+
+// MagickDrawableExtern template class MagickDLLDecl
+// std::list<Magick::Coordinate, std::allocator<Magick::Coordinate> >;
+
+#endif // MagickDLLExplicitTemplate
+
+ // Compare two Coordinate objects regardless of LHS/RHS
+ MagickDLLDeclExtern int operator == ( const Coordinate& left_,
+ const Coordinate& right_ );
+ MagickDLLDeclExtern int operator != ( const Coordinate& left_,
+ const Coordinate& right_ );
+ MagickDLLDeclExtern int operator > ( const Coordinate& left_,
+ const Coordinate& right_ );
+ MagickDLLDeclExtern int operator < ( const Coordinate& left_,
+ const Coordinate& right_ );
+ MagickDLLDeclExtern int operator >= ( const Coordinate& left_,
+ const Coordinate& right_ );
+ MagickDLLDeclExtern int operator <= ( const Coordinate& left_,
+ const Coordinate& right_ );
+
+ //
+ // Base class for all drawable objects
+ //
+ //struct MagickDLLDecl std::unary_function<MagickLib::DrawContext,void>;
+ class MagickDLLDecl DrawableBase:
+ public std::unary_function<MagickLib::DrawContext,void>
+ {
+ public:
+ // Constructor
+ DrawableBase ( void )
+ { }
+
+ // Destructor
+ virtual ~DrawableBase ( void );
+
+ // Operator to invoke equivalent draw API call
+ virtual void operator()( MagickLib::DrawContext ) const = 0;
+
+ // Return polymorphic copy of object
+ virtual DrawableBase* copy() const = 0;
+
+ private:
+ };
+
+ //
+ // Representation of a drawable surrogate object to manage drawable objects
+ //
+#undef Drawable // Conflict with <X11/Xproto.h>
+ class MagickDLLDecl Drawable
+ {
+ public:
+
+ // Constructor
+ Drawable ( void );
+
+ // Construct from DrawableBase
+ Drawable ( const DrawableBase& original_ );
+
+ // Destructor
+ ~Drawable ( void );
+
+ // Copy constructor
+ Drawable ( const Drawable& original_ );
+
+ // Assignment operator
+ Drawable& operator= (const Drawable& original_ );
+
+ // Operator to invoke contained object
+ void operator()( MagickLib::DrawContext context_ ) const;
+
+ private:
+ DrawableBase* dp;
+ };
+
+ // Compare two Drawable objects regardless of LHS/RHS
+ MagickDLLDeclExtern int operator == ( const Drawable& left_,
+ const Drawable& right_ );
+ MagickDLLDeclExtern int operator != ( const Drawable& left_,
+ const Drawable& right_ );
+ MagickDLLDeclExtern int operator > ( const Drawable& left_,
+ const Drawable& right_ );
+ MagickDLLDeclExtern int operator < ( const Drawable& left_,
+ const Drawable& right_ );
+ MagickDLLDeclExtern int operator >= ( const Drawable& left_,
+ const Drawable& right_ );
+ MagickDLLDeclExtern int operator <= ( const Drawable& left_,
+ const Drawable& right_ );
+
+ typedef std::list<Magick::Drawable> DrawableList;
+
+#if defined(MagickDLLExplicitTemplate)
+
+ MagickDrawableExtern template class MagickDLLDecl
+ std::allocator<Magick::Drawable>;
+
+// MagickDrawableExtern template class MagickDLLDecl
+// std::list<Magick::Drawable, std::allocator<Magick::Drawable> >;
+
+#endif // MagickDLLExplicitTemplate
+
+//
+// Base class for all drawable path elements for use with
+// DrawablePath
+//
+class MagickDLLDecl VPathBase
+{
+public:
+ // Constructor
+ VPathBase ( void )
+ { }
+
+ // Destructor
+ virtual ~VPathBase ( void );
+
+ // Assignment operator
+ // const VPathBase& operator= (const VPathBase& original_ );
+
+ // Operator to invoke equivalent draw API call
+ virtual void operator()( MagickLib::DrawContext context_ ) const = 0;
+
+ // Return polymorphic copy of object
+ virtual VPathBase* copy() const = 0;
+};
+
+//
+// Representation of a drawable path element surrogate object to
+// manage drawable path elements so they may be passed as a list to
+// DrawablePath.
+//
+class MagickDLLDecl VPath
+{
+public:
+ // Constructor
+ VPath ( void );
+
+ // Construct from VPathBase
+ VPath ( const VPathBase& original_ );
+
+ // Destructor
+ virtual ~VPath ( void );
+
+ // Copy constructor
+ VPath ( const VPath& original_ );
+
+ // Assignment operator
+ VPath& operator= (const VPath& original_ );
+
+ // Operator to invoke contained object
+ void operator()( MagickLib::DrawContext context_ ) const;
+
+private:
+ VPathBase* dp;
+};
+
+// Compare two VPath objects regardless of LHS/RHS
+MagickDLLDeclExtern int operator == ( const VPath& left_,
+ const VPath& right_ );
+MagickDLLDeclExtern int operator != ( const VPath& left_,
+ const VPath& right_ );
+MagickDLLDeclExtern int operator > ( const VPath& left_,
+ const VPath& right_ );
+MagickDLLDeclExtern int operator < ( const VPath& left_,
+ const VPath& right_ );
+MagickDLLDeclExtern int operator >= ( const VPath& left_,
+ const VPath& right_ );
+MagickDLLDeclExtern int operator <= ( const VPath& left_,
+ const VPath& right_ );
+
+typedef std::list<Magick::VPath> VPathList;
+
+#if defined(MagickDLLExplicitTemplate)
+
+MagickDrawableExtern template class MagickDLLDecl
+std::allocator<Magick::VPath>;
+
+// MagickDrawableExtern template class MagickDLLDecl
+// std::list<Magick::VPath, std::allocator<Magick::VPath> >;
+
+#endif // MagickDLLExplicitTemplate
+
+//
+// Drawable Objects
+//
+
+// Affine (scaling, rotation, and translation)
+class MagickDLLDecl DrawableAffine : public DrawableBase
+{
+public:
+ DrawableAffine ( double sx_, double sy_,
+ double rx_, double ry_,
+ double tx_, double ty_ );
+
+ DrawableAffine ( void );
+
+ /*virtual*/ ~DrawableAffine( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/
+ DrawableBase* copy() const;
+
+ void sx( const double sx_ )
+ {
+ _affine.sx = sx_;
+ }
+ double sx( void ) const
+ {
+ return _affine.sx;
+ }
+
+ void sy( const double sy_ )
+ {
+ _affine.sy = sy_;
+ }
+ double sy( void ) const
+ {
+ return _affine.sy;
+ }
+
+ void rx( const double rx_ )
+ {
+ _affine.rx = rx_;
+ }
+ double rx( void ) const
+ {
+ return _affine.rx;
+ }
+
+ void ry( const double ry_ )
+ {
+ _affine.ry = ry_;
+ }
+ double ry( void ) const
+ {
+ return _affine.ry;
+ }
+
+ void tx( const double tx_ )
+ {
+ _affine.tx = tx_;
+ }
+ double tx( void ) const
+ {
+ return _affine.tx;
+ }
+
+ void ty( const double ty_ )
+ {
+ _affine.ty = ty_;
+ }
+ double ty( void ) const
+ {
+ return _affine.ty;
+ }
+
+private:
+ MagickLib::AffineMatrix _affine;
+};
+
+// Arc
+class MagickDLLDecl DrawableArc : public DrawableBase
+{
+public:
+ DrawableArc ( double startX_, double startY_,
+ double endX_, double endY_,
+ double startDegrees_, double endDegrees_ )
+ : _startX(startX_),
+ _startY(startY_),
+ _endX(endX_),
+ _endY(endY_),
+ _startDegrees(startDegrees_),
+ _endDegrees(endDegrees_)
+ { }
+
+ /*virtual*/ ~DrawableArc( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void startX( double startX_ )
+ {
+ _startX = startX_;
+ }
+ double startX( void ) const
+ {
+ return _startX;
+ }
+
+ void startY( double startY_ )
+ {
+ _startY = startY_;
+ }
+ double startY( void ) const
+ {
+ return _startY;
+ }
+
+ void endX( double endX_ )
+ {
+ _endX = endX_;
+ }
+ double endX( void ) const
+ {
+ return _endX;
+ }
+
+ void endY( double endY_ )
+ {
+ _endY = endY_;
+ }
+ double endY( void ) const
+ {
+ return _endY;
+ }
+
+ void startDegrees( double startDegrees_ )
+ {
+ _startDegrees = startDegrees_;
+ }
+ double startDegrees( void ) const
+ {
+ return _startDegrees;
+ }
+
+ void endDegrees( double endDegrees_ )
+ {
+ _endDegrees = endDegrees_;
+ }
+ double endDegrees( void ) const
+ {
+ return _endDegrees;
+ }
+
+private:
+ double _startX;
+ double _startY;
+ double _endX;
+ double _endY;
+ double _startDegrees;
+ double _endDegrees;
+};
+
+// Bezier curve (Coordinate list must contain at least three members)
+class MagickDLLDecl DrawableBezier : public DrawableBase
+{
+public:
+ // Construct from coordinates
+ DrawableBezier ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ DrawableBezier ( const DrawableBezier& original_ );
+
+ // Destructor
+ /*virtual*/ ~DrawableBezier ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+
+
+// Pop (terminate) clip path definition
+class MagickDLLDecl DrawablePopClipPath : public DrawableBase
+{
+public:
+ DrawablePopClipPath ( void )
+ : _dummy(0)
+ {
+ }
+
+ /*virtual*/ ~DrawablePopClipPath ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ int _dummy;
+};
+
+// Push (create) Clip path definition
+class MagickDLLDecl DrawablePushClipPath : public DrawableBase
+{
+public:
+ DrawablePushClipPath ( const std::string &id_);
+
+ DrawablePushClipPath ( const DrawablePushClipPath& original_ );
+
+ /*virtual*/ ~DrawablePushClipPath ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ std::string _id;
+};
+
+// Named Clip Path
+class MagickDLLDecl DrawableClipPath : public DrawableBase
+{
+public:
+ DrawableClipPath ( const std::string &id_ );
+ DrawableClipPath ( const DrawableClipPath& original_ );
+
+ /*virtual*/ ~DrawableClipPath ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void clip_path( const std::string &id_ )
+ {
+ _id = id_.c_str(); //multithread safe
+ }
+ std::string clip_path( void ) const
+ {
+ return _id;
+ }
+
+private:
+ std::string _id;
+};
+
+// Circle
+class MagickDLLDecl DrawableCircle : public DrawableBase
+{
+public:
+ DrawableCircle ( double originX_, double originY_,
+ double perimX_, double perimY_ )
+ : _originX(originX_),
+ _originY(originY_),
+ _perimX(perimX_),
+ _perimY(perimY_)
+ {
+ }
+
+ /*virtual*/ ~DrawableCircle ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void originX( double originX_ )
+ {
+ _originX = originX_;
+ }
+ double originX( void ) const
+ {
+ return _originX;
+ }
+
+ void originY( double originY_ )
+ {
+ _originY = originY_;
+ }
+ double originY( void ) const
+ {
+ return _originY;
+ }
+
+ void perimX( double perimX_ )
+ {
+ _perimX = perimX_;
+ }
+ double perimX( void ) const
+ {
+ return _perimX;
+ }
+
+ void perimY( double perimY_ )
+ {
+ _perimY = perimY_;
+ }
+ double perimY( void ) const
+ {
+ return _perimY;
+ }
+
+private:
+ double _originX;
+ double _originY;
+ double _perimX;
+ double _perimY;
+};
+
+// Colorize at point using PaintMethod
+class MagickDLLDecl DrawableColor : public DrawableBase
+{
+public:
+ DrawableColor ( double x_, double y_,
+ PaintMethod paintMethod_ )
+ : _x(x_),
+ _y(y_),
+ _paintMethod(paintMethod_)
+ { }
+
+ /*virtual*/ ~DrawableColor ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+ void paintMethod( PaintMethod paintMethod_ )
+ {
+ _paintMethod = paintMethod_;
+ }
+ PaintMethod paintMethod( void ) const
+ {
+ return _paintMethod;
+ }
+
+private:
+ double _x;
+ double _y;
+ PaintMethod _paintMethod;
+};
+
+// Draw image at point, scaled to size specified by width and height
+class MagickDLLDecl Image;
+class MagickDLLDecl DrawableCompositeImage : public DrawableBase
+{
+public:
+ DrawableCompositeImage ( double x_, double y_,
+ const std::string &filename_ );
+
+ DrawableCompositeImage ( double x_, double y_,
+ const Image &image_ );
+
+ DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const std::string &filename_ );
+
+ DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const Image &image_ );
+
+ DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const std::string &filename_,
+ CompositeOperator composition_ );
+
+ DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const Image &image_,
+ CompositeOperator composition_ );
+
+ // Copy constructor
+ DrawableCompositeImage ( const DrawableCompositeImage& original_ );
+
+ // Destructor
+ /*virtual*/ ~DrawableCompositeImage( void );
+
+ // Assignment operator
+ DrawableCompositeImage& operator=
+ (const DrawableCompositeImage& original_ );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void composition( CompositeOperator composition_ )
+ {
+ _composition = composition_;
+ }
+ CompositeOperator composition( void ) const
+ {
+ return _composition;
+ }
+
+ void filename( const std::string &image_ );
+ std::string filename( void ) const;
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+ void width( double width_ )
+ {
+ _width = width_;
+ }
+ double width( void ) const
+ {
+ return _width;
+ }
+
+ void height( double height_ )
+ {
+ _height = height_;
+ }
+ double height( void ) const
+ {
+ return _height;
+ }
+
+ void image( const Image &image_ );
+ Magick::Image image( void ) const;
+
+ // Specify image format used to output Base64 inlined image data.
+ void magick( std::string magick_ );
+ std::string magick( void );
+
+private:
+ CompositeOperator _composition;
+ double _x;
+ double _y;
+ double _width;
+ double _height;
+ Image* _image;
+};
+
+// Ellipse
+class MagickDLLDecl DrawableEllipse : public DrawableBase
+{
+public:
+ DrawableEllipse ( double originX_, double originY_,
+ double radiusX_, double radiusY_,
+ double arcStart_, double arcEnd_ )
+ : _originX(originX_),
+ _originY(originY_),
+ _radiusX(radiusX_),
+ _radiusY(radiusY_),
+ _arcStart(arcStart_),
+ _arcEnd(arcEnd_)
+ { }
+
+ /*virtual*/ ~DrawableEllipse( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void originX( double originX_ )
+ {
+ _originX = originX_;
+ }
+ double originX( void ) const
+ {
+ return _originX;
+ }
+
+ void originY( double originY_ )
+ {
+ _originY = originY_;
+ }
+ double originY( void ) const
+ {
+ return _originY;
+ }
+
+ void radiusX( double radiusX_ )
+ {
+ _radiusX = radiusX_;
+ }
+ double radiusX( void ) const
+ {
+ return _radiusX;
+ }
+
+ void radiusY( double radiusY_ )
+ {
+ _radiusY = radiusY_;
+ }
+ double radiusY( void ) const
+ {
+ return _radiusY;
+ }
+
+ void arcStart( double arcStart_ )
+ {
+ _arcStart = arcStart_;
+ }
+ double arcStart( void ) const
+ {
+ return _arcStart;
+ }
+
+ void arcEnd( double arcEnd_ )
+ {
+ _arcEnd = arcEnd_;
+ }
+ double arcEnd( void ) const
+ {
+ return _arcEnd;
+ }
+
+private:
+ double _originX;
+ double _originY;
+ double _radiusX;
+ double _radiusY;
+ double _arcStart;
+ double _arcEnd;
+};
+
+// Specify drawing fill color
+class MagickDLLDecl DrawableFillColor : public DrawableBase
+{
+public:
+ DrawableFillColor ( const Color &color_ );
+
+ DrawableFillColor ( const DrawableFillColor& original_ );
+
+ /*virtual*/ ~DrawableFillColor( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void color( const Color &color_ )
+ {
+ _color = color_;
+ }
+ Color color( void ) const
+ {
+ return _color;
+ }
+
+private:
+ Color _color;
+};
+
+// Specify fill rule (fill-rule)
+class MagickDLLDecl DrawableFillRule : public DrawableBase
+{
+public:
+ DrawableFillRule ( const FillRule fillRule_ )
+ : _fillRule(fillRule_)
+ {
+ }
+
+ /*virtual*/ ~DrawableFillRule ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void fillRule( const FillRule fillRule_ )
+ {
+ _fillRule = fillRule_;
+ }
+ FillRule fillRule( void ) const
+ {
+ return _fillRule;
+ }
+
+private:
+ FillRule _fillRule;
+};
+
+// Specify drawing fill opacity
+class MagickDLLDecl DrawableFillOpacity : public DrawableBase
+{
+public:
+ DrawableFillOpacity ( double opacity_ )
+ : _opacity(opacity_)
+ {
+ }
+
+ /*virtual*/ ~DrawableFillOpacity ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void opacity( double opacity_ )
+ {
+ _opacity = opacity_;
+ }
+ double opacity( void ) const
+ {
+ return _opacity;
+ }
+
+private:
+ double _opacity;
+};
+
+// Specify text font
+class MagickDLLDecl DrawableFont : public DrawableBase
+{
+public:
+ DrawableFont ( const std::string &font_ );
+
+ DrawableFont ( const std::string &family_,
+ StyleType style_,
+ const unsigned long weight_,
+ StretchType stretch_ );
+ DrawableFont ( const DrawableFont& original_ );
+
+ /*virtual*/ ~DrawableFont ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void font( const std::string &font_ )
+ {
+ _font = font_;
+ }
+ std::string font( void ) const
+ {
+ return _font;
+ }
+
+private:
+ std::string _font;
+ std::string _family;
+ StyleType _style;
+ unsigned long _weight;
+ StretchType _stretch;
+};
+
+// Specify text positioning gravity
+class MagickDLLDecl DrawableGravity : public DrawableBase
+{
+public:
+ DrawableGravity ( GravityType gravity_ )
+ : _gravity(gravity_)
+ {
+ }
+
+ /*virtual*/ ~DrawableGravity ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void gravity( GravityType gravity_ )
+ {
+ _gravity = gravity_;
+ }
+ GravityType gravity( void ) const
+ {
+ return _gravity;
+ }
+
+private:
+ GravityType _gravity;
+};
+
+// Line
+class MagickDLLDecl DrawableLine : public DrawableBase
+{
+public:
+ DrawableLine ( double startX_, double startY_,
+ double endX_, double endY_ )
+ : _startX(startX_),
+ _startY(startY_),
+ _endX(endX_),
+ _endY(endY_)
+ { }
+
+ /*virtual*/ ~DrawableLine ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void startX( double startX_ )
+ {
+ _startX = startX_;
+ }
+ double startX( void ) const
+ {
+ return _startX;
+ }
+
+ void startY( double startY_ )
+ {
+ _startY = startY_;
+ }
+ double startY( void ) const
+ {
+ return _startY;
+ }
+
+ void endX( double endX_ )
+ {
+ _endX = endX_;
+ }
+ double endX( void ) const
+ {
+ return _endX;
+ }
+
+ void endY( double endY_ )
+ {
+ _endY = endY_;
+ }
+ double endY( void ) const
+ {
+ return _endY;
+ }
+
+private:
+ double _startX;
+ double _startY;
+ double _endX;
+ double _endY;
+};
+
+// Change pixel matte value to transparent using PaintMethod
+class MagickDLLDecl DrawableMatte : public DrawableBase
+{
+public:
+ DrawableMatte ( double x_, double y_,
+ PaintMethod paintMethod_ )
+ : _x(x_),
+ _y(y_),
+ _paintMethod(paintMethod_)
+ { }
+
+ /*virtual*/ ~DrawableMatte ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+ void paintMethod( PaintMethod paintMethod_ )
+ {
+ _paintMethod = paintMethod_;
+ }
+ PaintMethod paintMethod( void ) const
+ {
+ return _paintMethod;
+ }
+
+private:
+ double _x;
+ double _y;
+ PaintMethod _paintMethod;
+};
+
+// Drawable Path
+class MagickDLLDecl DrawablePath : public DrawableBase
+{
+public:
+ DrawablePath ( const VPathList &path_ );
+
+ DrawablePath ( const DrawablePath& original_ );
+
+ /*virtual*/ ~DrawablePath ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ VPathList _path;
+};
+
+// Point
+class MagickDLLDecl DrawablePoint : public DrawableBase
+{
+public:
+ DrawablePoint ( double x_, double y_ )
+ : _x(x_),
+ _y(y_)
+ { }
+
+ /*virtual*/ ~DrawablePoint ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+private:
+ double _x;
+ double _y;
+};
+
+// Text pointsize
+class MagickDLLDecl DrawablePointSize : public DrawableBase
+{
+public:
+ DrawablePointSize ( double pointSize_ )
+ : _pointSize(pointSize_)
+ { }
+
+ /*virtual*/ ~DrawablePointSize ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void pointSize( double pointSize_ )
+ {
+ _pointSize = pointSize_;
+ }
+ double pointSize( void ) const
+ {
+ return _pointSize;
+ }
+
+private:
+ double _pointSize;
+};
+
+// Polygon (Coordinate list must contain at least three members)
+class MagickDLLDecl DrawablePolygon : public DrawableBase
+{
+public:
+ DrawablePolygon ( const CoordinateList &coordinates_ );
+
+ DrawablePolygon ( const DrawablePolygon& original_ );
+
+ /*virtual*/ ~DrawablePolygon ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+
+// Polyline (Coordinate list must contain at least three members)
+class MagickDLLDecl DrawablePolyline : public DrawableBase
+{
+public:
+ DrawablePolyline ( const CoordinateList &coordinates_ );
+
+ DrawablePolyline ( const DrawablePolyline& original_ );
+
+ /*virtual*/ ~DrawablePolyline ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+
+// Pop Graphic Context
+class MagickDLLDecl DrawablePopGraphicContext : public DrawableBase
+{
+public:
+ DrawablePopGraphicContext ( void )
+ : _dummy(0)
+ {
+ }
+
+ /*virtual*/ ~DrawablePopGraphicContext ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ int _dummy;
+};
+
+// Push Graphic Context
+class MagickDLLDecl DrawablePushGraphicContext : public DrawableBase
+{
+public:
+ DrawablePushGraphicContext ( void )
+ : _dummy(0)
+ {
+ }
+
+ /*virtual*/ ~DrawablePushGraphicContext ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ int _dummy;
+};
+
+// Pop (terminate) Pattern definition
+class MagickDLLDecl DrawablePopPattern : public DrawableBase
+{
+public:
+ DrawablePopPattern ( void )
+ : _dummy(0)
+ {
+ }
+
+ /*virtual*/ ~DrawablePopPattern ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ int _dummy;
+};
+
+// Push (create) Pattern definition
+class MagickDLLDecl DrawablePushPattern : public DrawableBase
+{
+public:
+ DrawablePushPattern ( const std::string &id_, long x_, long y_,
+ long width_, long height_ );
+
+ DrawablePushPattern ( const DrawablePushPattern& original_ );
+
+ /*virtual*/ ~DrawablePushPattern ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+private:
+ std::string _id;
+ long _x;
+ long _y;
+ long _width;
+ long _height;
+};
+
+// Rectangle
+class MagickDLLDecl DrawableRectangle : public DrawableBase
+{
+public:
+ DrawableRectangle ( double upperLeftX_, double upperLeftY_,
+ double lowerRightX_, double lowerRightY_ )
+ : _upperLeftX(upperLeftX_),
+ _upperLeftY(upperLeftY_),
+ _lowerRightX(lowerRightX_),
+ _lowerRightY(lowerRightY_)
+ { }
+
+ /*virtual*/ ~DrawableRectangle ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void upperLeftX( double upperLeftX_ )
+ {
+ _upperLeftX = upperLeftX_;
+ }
+ double upperLeftX( void ) const
+ {
+ return _upperLeftX;
+ }
+
+ void upperLeftY( double upperLeftY_ )
+ {
+ _upperLeftY = upperLeftY_;
+ }
+ double upperLeftY( void ) const
+ {
+ return _upperLeftY;
+ }
+
+ void lowerRightX( double lowerRightX_ )
+ {
+ _lowerRightX = lowerRightX_;
+ }
+ double lowerRightX( void ) const
+ {
+ return _lowerRightX;
+ }
+
+ void lowerRightY( double lowerRightY_ )
+ {
+ _lowerRightY = lowerRightY_;
+ }
+ double lowerRightY( void ) const
+ {
+ return _lowerRightY;
+ }
+
+private:
+ double _upperLeftX;
+ double _upperLeftY;
+ double _lowerRightX;
+ double _lowerRightY;
+};
+
+// Apply Rotation
+class MagickDLLDecl DrawableRotation : public DrawableBase
+{
+public:
+ DrawableRotation ( double angle_ )
+ : _angle( angle_ )
+ { }
+
+ /*virtual*/ ~DrawableRotation ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void angle( double angle_ )
+ {
+ _angle = angle_;
+ }
+ double angle( void ) const
+ {
+ return _angle;
+ }
+
+private:
+ double _angle;
+};
+
+// Round Rectangle
+class MagickDLLDecl DrawableRoundRectangle : public DrawableBase
+{
+public:
+ DrawableRoundRectangle ( double centerX_, double centerY_,
+ double width_, double hight_,
+ double cornerWidth_, double cornerHeight_ )
+ : _centerX(centerX_),
+ _centerY(centerY_),
+ _width(width_),
+ _hight(hight_),
+ _cornerWidth(cornerWidth_),
+ _cornerHeight(cornerHeight_)
+ { }
+
+ /*virtual*/ ~DrawableRoundRectangle ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void centerX( double centerX_ )
+ {
+ _centerX = centerX_;
+ }
+ double centerX( void ) const
+ {
+ return _centerX;
+ }
+
+ void centerY( double centerY_ )
+ {
+ _centerY = centerY_;
+ }
+ double centerY( void ) const
+ {
+ return _centerY;
+ }
+
+ void width( double width_ )
+ {
+ _width = width_;
+ }
+ double width( void ) const
+ {
+ return _width;
+ }
+
+ void hight( double hight_ )
+ {
+ _hight = hight_;
+ }
+ double hight( void ) const
+ {
+ return _hight;
+ }
+
+ void cornerWidth( double cornerWidth_ )
+ {
+ _cornerWidth = cornerWidth_;
+ }
+ double cornerWidth( void ) const
+ {
+ return _cornerWidth;
+ }
+
+ void cornerHeight( double cornerHeight_ )
+ {
+ _cornerHeight = cornerHeight_;
+ }
+ double cornerHeight( void ) const
+ {
+ return _cornerHeight;
+ }
+
+private:
+ double _centerX;
+ double _centerY;
+ double _width;
+ double _hight;
+ double _cornerWidth;
+ double _cornerHeight;
+};
+
+// Apply Scaling
+class MagickDLLDecl DrawableScaling : public DrawableBase
+{
+public:
+ DrawableScaling ( double x_, double y_ )
+ : _x(x_),
+ _y(y_)
+ { }
+
+ /*virtual*/ ~DrawableScaling ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+private:
+ double _x;
+ double _y;
+};
+
+// Apply Skew in X direction
+class MagickDLLDecl DrawableSkewX : public DrawableBase
+{
+public:
+ DrawableSkewX ( double angle_ )
+ : _angle(angle_)
+ { }
+
+ /*virtual*/ ~DrawableSkewX ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void angle( double angle_ )
+ {
+ _angle = angle_;
+ }
+ double angle( void ) const
+ {
+ return _angle;
+ }
+
+private:
+ double _angle;
+};
+
+// Apply Skew in Y direction
+class MagickDLLDecl DrawableSkewY : public DrawableBase
+{
+public:
+ DrawableSkewY ( double angle_ )
+ : _angle(angle_)
+ { }
+
+ /*virtual*/ ~DrawableSkewY ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void angle( double angle_ )
+ {
+ _angle = angle_;
+ }
+ double angle( void ) const
+ {
+ return _angle;
+ }
+
+private:
+ double _angle;
+};
+
+// Stroke dasharray
+//
+// dasharray_ is an allocated array terminated by value 0.0 or 0.
+// The array is copied so the original does not need to be preserved.
+// Pass a null pointer to clear an existing dash array setting.
+class MagickDLLDecl DrawableDashArray : public DrawableBase
+{
+public:
+ DrawableDashArray( const double* dasharray_ );
+ DrawableDashArray( const unsigned int* dasharray_ ); // Deprecated
+ DrawableDashArray( const Magick::DrawableDashArray &original_ );
+
+ /*virtual*/ ~DrawableDashArray( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void dasharray( const double* dasharray_ );
+ void dasharray( const unsigned int* dasharray_ ); // Deprecated
+
+ const double* dasharray( void ) const
+ {
+ return _dasharray;
+ }
+
+ DrawableDashArray& operator=(const Magick::DrawableDashArray &original_);
+
+private:
+ size_t _size;
+ double *_dasharray;
+};
+
+// Stroke dashoffset
+class MagickDLLDecl DrawableDashOffset : public DrawableBase
+{
+public:
+ DrawableDashOffset ( const double offset_ )
+ : _offset(offset_)
+ { }
+
+ /*virtual*/ ~DrawableDashOffset ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void offset( const double offset_ )
+ {
+ _offset = offset_;
+ }
+ double offset( void ) const
+ {
+ return _offset;
+ }
+
+private:
+ double _offset;
+};
+
+// Stroke linecap
+class MagickDLLDecl DrawableStrokeLineCap : public DrawableBase
+{
+public:
+ DrawableStrokeLineCap ( LineCap linecap_ )
+ : _linecap(linecap_)
+ { }
+
+ /*virtual*/ ~DrawableStrokeLineCap ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void linecap( LineCap linecap_ )
+ {
+ _linecap = linecap_;
+ }
+ LineCap linecap( void ) const
+ {
+ return _linecap;
+ }
+
+private:
+ LineCap _linecap;
+};
+
+// Stroke linejoin
+class MagickDLLDecl DrawableStrokeLineJoin : public DrawableBase
+{
+public:
+ DrawableStrokeLineJoin ( LineJoin linejoin_ )
+ : _linejoin(linejoin_)
+ { }
+
+ /*virtual*/ ~DrawableStrokeLineJoin ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void linejoin( LineJoin linejoin_ )
+ {
+ _linejoin = linejoin_;
+ }
+ LineJoin linejoin( void ) const
+ {
+ return _linejoin;
+ }
+
+private:
+ LineJoin _linejoin;
+};
+
+// Stroke miterlimit
+class MagickDLLDecl DrawableMiterLimit : public DrawableBase
+{
+public:
+ DrawableMiterLimit ( unsigned int miterlimit_ )
+ : _miterlimit(miterlimit_)
+ { }
+
+ /*virtual*/ ~DrawableMiterLimit ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void miterlimit( unsigned int miterlimit_ )
+ {
+ _miterlimit = miterlimit_;
+ }
+ unsigned int miterlimit( void ) const
+ {
+ return _miterlimit;
+ }
+
+private:
+ unsigned int _miterlimit;
+};
+
+
+// Stroke antialias
+class MagickDLLDecl DrawableStrokeAntialias : public DrawableBase
+{
+public:
+ DrawableStrokeAntialias ( bool flag_ )
+ : _flag(flag_)
+ { }
+
+ /*virtual*/ ~DrawableStrokeAntialias ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void flag( bool flag_ )
+ {
+ _flag = flag_;
+ }
+ bool flag( void ) const
+ {
+ return _flag;
+ }
+
+private:
+ bool _flag;
+};
+
+// Stroke color
+class MagickDLLDecl DrawableStrokeColor : public DrawableBase
+{
+public:
+ DrawableStrokeColor ( const Color &color_ );
+
+ DrawableStrokeColor ( const DrawableStrokeColor& original_ );
+
+ /*virtual*/ ~DrawableStrokeColor ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void color( const Color& color_ )
+ {
+ _color = color_;
+ }
+ Color color( void ) const
+ {
+ return _color;
+ }
+
+private:
+ Color _color;
+};
+
+// Stroke opacity
+class MagickDLLDecl DrawableStrokeOpacity : public DrawableBase
+{
+public:
+ DrawableStrokeOpacity ( double opacity_ )
+ : _opacity(opacity_)
+ {
+ }
+
+ /*virtual*/ ~DrawableStrokeOpacity ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void opacity( double opacity_ )
+ {
+ _opacity = opacity_;
+ }
+ double opacity( void ) const
+ {
+ return _opacity;
+ }
+
+private:
+ double _opacity;
+};
+
+// Stroke width
+class MagickDLLDecl DrawableStrokeWidth : public DrawableBase
+{
+public:
+ DrawableStrokeWidth ( double width_ )
+ : _width(width_)
+ { }
+
+ /*virtual*/ ~DrawableStrokeWidth ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void width( double width_ )
+ {
+ _width = width_;
+ }
+ double width( void ) const
+ {
+ return _width;
+ }
+
+private:
+ double _width;
+};
+
+// Draw text at point
+class MagickDLLDecl DrawableText : public DrawableBase
+{
+public:
+ DrawableText ( const double x_, const double y_,
+ const std::string &text_ );
+ DrawableText ( const double x_, const double y_,
+ const std::string &text_, const std::string &encoding_);
+
+ DrawableText ( const DrawableText& original_ );
+
+ /*virtual*/ ~DrawableText ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void encoding(const std::string &encoding_)
+ {
+ _encoding = encoding_;
+ }
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+ void text( const std::string &text_ )
+ {
+ _text = text_;
+ }
+ std::string text( void ) const
+ {
+ return _text;
+ }
+
+private:
+ double _x;
+ double _y;
+ std::string _text;
+ std::string _encoding;
+};
+
+// Text antialias
+class MagickDLLDecl DrawableTextAntialias : public DrawableBase
+{
+public:
+ DrawableTextAntialias ( bool flag_ );
+
+ DrawableTextAntialias( const DrawableTextAntialias &original_ );
+
+ /*virtual*/ ~DrawableTextAntialias ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void flag( bool flag_ )
+ {
+ _flag = flag_;
+ }
+ bool flag( void ) const
+ {
+ return _flag;
+ }
+
+private:
+ bool _flag;
+};
+
+// Decoration (text decoration)
+class MagickDLLDecl DrawableTextDecoration : public DrawableBase
+{
+public:
+ DrawableTextDecoration ( DecorationType decoration_ );
+
+ DrawableTextDecoration ( const DrawableTextDecoration& original_ );
+
+ /*virtual*/ ~DrawableTextDecoration( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void decoration( DecorationType decoration_ )
+ {
+ _decoration = decoration_;
+ }
+ DecorationType decoration( void ) const
+ {
+ return _decoration;
+ }
+
+private:
+ DecorationType _decoration;
+};
+
+// Text undercolor box
+class MagickDLLDecl DrawableTextUnderColor : public DrawableBase
+{
+public:
+ DrawableTextUnderColor ( const Color &color_ );
+
+ DrawableTextUnderColor ( const DrawableTextUnderColor& original_ );
+
+ /*virtual*/ ~DrawableTextUnderColor ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void color( const Color& color_ )
+ {
+ _color = color_;
+ }
+ Color color( void ) const
+ {
+ return _color;
+ }
+
+private:
+ Color _color;
+};
+
+// Apply Translation
+class MagickDLLDecl DrawableTranslation : public DrawableBase
+{
+public:
+ DrawableTranslation ( double x_, double y_ )
+ : _x(x_),
+ _y(y_)
+ { }
+
+ /*virtual*/ ~DrawableTranslation ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ DrawableBase* copy() const;
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+private:
+ double _x;
+ double _y;
+};
+
+// Set the size of the viewbox
+class MagickDLLDecl DrawableViewbox : public DrawableBase
+{
+public:
+ DrawableViewbox(unsigned long x1_, unsigned long y1_,
+ unsigned long x2_, unsigned long y2_)
+ : _x1(x1_),
+ _y1(y1_),
+ _x2(x2_),
+ _y2(y2_) { }
+
+ /*virtual*/ ~DrawableViewbox ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/
+ DrawableBase* copy() const;
+
+ void x1( unsigned long x1_ )
+ {
+ _x1 = x1_;
+ }
+ unsigned long x1( void ) const
+ {
+ return _x1;
+ }
+
+ void y1( unsigned long y1_ )
+ {
+ _y1 = y1_;
+ }
+ unsigned long y1( void ) const
+ {
+ return _y1;
+ }
+
+ void x2( unsigned long x2_ )
+ {
+ _x2 = x2_;
+ }
+ unsigned long x2( void ) const
+ {
+ return _x2;
+ }
+
+ void y2( unsigned long y2_ )
+ {
+ _y2 = y2_;
+ }
+ unsigned long y2( void ) const
+ {
+ return _y2;
+ }
+
+private:
+ unsigned long _x1;
+ unsigned long _y1;
+ unsigned long _x2;
+ unsigned long _y2;
+};
+
+//
+// Path Element Classes To Support DrawablePath
+//
+class MagickDLLDecl PathArcArgs
+{
+public:
+ // Default constructor
+ PathArcArgs( void );
+
+ // Path arc argument
+ PathArcArgs( double radiusX_, double radiusY_,
+ double xAxisRotation_, bool largeArcFlag_,
+ bool sweepFlag_, double x_, double y_ );
+
+ PathArcArgs( const PathArcArgs &original_ );
+
+ ~PathArcArgs ( void );
+
+ void radiusX( double radiusX_ )
+ {
+ _radiusX = radiusX_;
+ }
+ double radiusX( void ) const
+ {
+ return _radiusX;
+ }
+
+ void radiusY( double radiusY_ )
+ {
+ _radiusY = radiusY_;
+ }
+ double radiusY( void ) const
+ {
+ return _radiusY;
+ }
+
+ void xAxisRotation( double xAxisRotation_ )
+ {
+ _xAxisRotation = xAxisRotation_;
+ }
+ double xAxisRotation( void ) const
+ {
+ return _xAxisRotation;
+ }
+
+ void largeArcFlag( bool largeArcFlag_ )
+ {
+ _largeArcFlag = largeArcFlag_;
+ }
+ bool largeArcFlag( void ) const
+ {
+ return _largeArcFlag;
+ }
+
+ void sweepFlag( bool sweepFlag_ )
+ {
+ _sweepFlag = sweepFlag_;
+ }
+ bool sweepFlag( void ) const
+ {
+ return _sweepFlag;
+ }
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+private:
+ double _radiusX; // X radius
+ double _radiusY; // Y radius
+ double _xAxisRotation; // Rotation relative to X axis
+ bool _largeArcFlag; // Draw longer of the two matching arcs
+ bool _sweepFlag; // Draw arc matching clock-wise rotation
+ double _x; // End-point X
+ double _y; // End-point Y
+};
+
+// Compare two PathArcArgs objects regardless of LHS/RHS
+MagickDLLDeclExtern int operator == ( const PathArcArgs& left_,
+ const PathArcArgs& right_ );
+MagickDLLDeclExtern int operator != ( const PathArcArgs& left_,
+ const PathArcArgs& right_ );
+MagickDLLDeclExtern int operator > ( const PathArcArgs& left_,
+ const PathArcArgs& right_ );
+MagickDLLDeclExtern int operator < ( const PathArcArgs& left_,
+ const PathArcArgs& right_ );
+MagickDLLDeclExtern int operator >= ( const PathArcArgs& left_,
+ const PathArcArgs& right_ );
+MagickDLLDeclExtern int operator <= ( const PathArcArgs& left_,
+ const PathArcArgs& right_ );
+
+typedef std::list<Magick::PathArcArgs> PathArcArgsList;
+
+#if defined(MagickDLLExplicitTemplate)
+
+MagickDrawableExtern template class MagickDLLDecl
+std::allocator<Magick::PathArcArgs>;
+
+// MagickDrawableExtern template class MagickDLLDecl
+// std::list<Magick::PathArcArgs, std::allocator<Magick::PathArcArgs> >;
+
+#endif // MagickDLLExplicitTemplate
+
+// Path Arc (Elliptical Arc)
+class MagickDLLDecl PathArcAbs : public VPathBase
+{
+public:
+ // Draw a single arc segment
+ PathArcAbs ( const PathArcArgs &coordinates_ );
+
+ // Draw multiple arc segments
+ PathArcAbs ( const PathArcArgsList &coordinates_ );
+
+ // Copy constructor
+ PathArcAbs ( const PathArcAbs& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathArcAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ PathArcArgsList _coordinates;
+};
+class MagickDLLDecl PathArcRel : public VPathBase
+{
+public:
+ // Draw a single arc segment
+ PathArcRel ( const PathArcArgs &coordinates_ );
+
+ // Draw multiple arc segments
+ PathArcRel ( const PathArcArgsList &coordinates_ );
+
+ PathArcRel ( const PathArcRel& original_ );
+
+ /*virtual*/ ~PathArcRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ PathArcArgsList _coordinates;
+};
+
+// Path Closepath
+class MagickDLLDecl PathClosePath : public VPathBase
+{
+public:
+ PathClosePath ( void )
+ : _dummy(0)
+ {
+ }
+
+ /*virtual*/ ~PathClosePath ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ int _dummy;
+};
+
+//
+// Curveto (Cubic Bezier)
+//
+class MagickDLLDecl PathCurvetoArgs
+{
+public:
+ PathCurvetoArgs( void );
+
+ PathCurvetoArgs( double x1_, double y1_,
+ double x2_, double y2_,
+ double x_, double y_ );
+
+ PathCurvetoArgs( const PathCurvetoArgs &original_ );
+
+ ~PathCurvetoArgs ( void );
+
+ void x1( double x1_ )
+ {
+ _x1 = x1_;
+ }
+double x1( void ) const
+{
+ return _x1;
+}
+
+void y1( double y1_ )
+{
+ _y1 = y1_;
+}
+double y1( void ) const
+{
+ return _y1;
+}
+
+void x2( double x2_ )
+{
+ _x2 = x2_;
+}
+double x2( void ) const
+{
+ return _x2;
+}
+
+void y2( double y2_ )
+{
+ _y2 = y2_;
+}
+double y2( void ) const
+{
+ return _y2;
+}
+
+void x( double x_ )
+{
+ _x = x_;
+}
+double x( void ) const
+{
+ return _x;
+}
+
+void y( double y_ )
+{
+ _y = y_;
+}
+double y( void ) const
+{
+ return _y;
+}
+
+private:
+double _x1;
+double _y1;
+double _x2;
+double _y2;
+double _x;
+double _y;
+};
+
+// Compare two PathCurvetoArgs objects regardless of LHS/RHS
+MagickDLLDeclExtern int operator == ( const PathCurvetoArgs& left_,
+ const PathCurvetoArgs& right_ );
+MagickDLLDeclExtern int operator != ( const PathCurvetoArgs& left_,
+ const PathCurvetoArgs& right_ );
+MagickDLLDeclExtern int operator > ( const PathCurvetoArgs& left_,
+ const PathCurvetoArgs& right_ );
+MagickDLLDeclExtern int operator < ( const PathCurvetoArgs& left_,
+ const PathCurvetoArgs& right_ );
+MagickDLLDeclExtern int operator >= ( const PathCurvetoArgs& left_,
+ const PathCurvetoArgs& right_ );
+MagickDLLDeclExtern int operator <= ( const PathCurvetoArgs& left_,
+ const PathCurvetoArgs& right_ );
+
+typedef std::list<Magick::PathCurvetoArgs> PathCurveToArgsList;
+
+#if defined(MagickDLLExplicitTemplate)
+
+MagickDrawableExtern template class MagickDLLDecl
+std::allocator<Magick::PathCurvetoArgs>;
+
+// MagickDrawableExtern template class MagickDLLDecl
+// std::list<Magick::PathCurvetoArgs, std::allocator<Magick::PathCurvetoArgs> >;
+
+#endif // MagickDLLExplicitTemplate
+
+class MagickDLLDecl PathCurvetoAbs : public VPathBase
+{
+public:
+ // Draw a single curve
+ PathCurvetoAbs ( const PathCurvetoArgs &args_ );
+
+ // Draw multiple curves
+ PathCurvetoAbs ( const PathCurveToArgsList &args_ );
+
+ // Copy constructor
+ PathCurvetoAbs ( const PathCurvetoAbs& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathCurvetoAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ PathCurveToArgsList _args;
+};
+class MagickDLLDecl PathCurvetoRel : public VPathBase
+{
+public:
+ // Draw a single curve
+ PathCurvetoRel ( const PathCurvetoArgs &args_ );
+
+ // Draw multiple curves
+ PathCurvetoRel ( const PathCurveToArgsList &args_ );
+
+ // Copy constructor
+ PathCurvetoRel ( const PathCurvetoRel& original_ );
+
+ /*virtual*/ ~PathCurvetoRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ PathCurveToArgsList _args;
+};
+class MagickDLLDecl PathSmoothCurvetoAbs : public VPathBase
+{
+public:
+ // Draw a single curve
+ PathSmoothCurvetoAbs ( const Magick::Coordinate &coordinates_ );
+
+ // Draw multiple curves
+ PathSmoothCurvetoAbs ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ PathSmoothCurvetoAbs ( const PathSmoothCurvetoAbs& original_ );
+
+ /*virtual*/ ~PathSmoothCurvetoAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/
+ VPathBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+class MagickDLLDecl PathSmoothCurvetoRel : public VPathBase
+{
+public:
+ // Draw a single curve
+ PathSmoothCurvetoRel ( const Coordinate &coordinates_ );
+
+ // Draw multiple curves
+ PathSmoothCurvetoRel ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ PathSmoothCurvetoRel ( const PathSmoothCurvetoRel& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathSmoothCurvetoRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/
+ VPathBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+
+//
+// Quadratic Curveto (Quadratic Bezier)
+//
+class MagickDLLDecl PathQuadraticCurvetoArgs
+{
+public:
+ // Default constructor
+ PathQuadraticCurvetoArgs( void );
+
+ // Parameterized constructor
+ PathQuadraticCurvetoArgs( double x1_, double y1_,
+ double x_, double y_ );
+
+ // Copy constructor
+ PathQuadraticCurvetoArgs( const PathQuadraticCurvetoArgs &original_ );
+
+ ~PathQuadraticCurvetoArgs ( void );
+
+ void x1( double x1_ )
+ {
+ _x1 = x1_;
+ }
+ double x1( void ) const
+ {
+ return _x1;
+ }
+
+ void y1( double y1_ )
+ {
+ _y1 = y1_;
+ }
+ double y1( void ) const
+ {
+ return _y1;
+ }
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+private:
+ double _x1;
+ double _y1;
+ double _x;
+ double _y;
+};
+
+// Compare two PathQuadraticCurvetoArgs objects regardless of LHS/RHS
+MagickDLLDeclExtern int operator == ( const PathQuadraticCurvetoArgs& left_,
+ const PathQuadraticCurvetoArgs& right_ );
+MagickDLLDeclExtern int operator != ( const PathQuadraticCurvetoArgs& left_,
+ const PathQuadraticCurvetoArgs& right_);
+MagickDLLDeclExtern int operator > ( const PathQuadraticCurvetoArgs& left_,
+ const PathQuadraticCurvetoArgs& right_);
+MagickDLLDeclExtern int operator < ( const PathQuadraticCurvetoArgs& left_,
+ const PathQuadraticCurvetoArgs& right_);
+MagickDLLDeclExtern int operator >= ( const PathQuadraticCurvetoArgs& left_,
+ const PathQuadraticCurvetoArgs& right_ );
+MagickDLLDeclExtern int operator <= ( const PathQuadraticCurvetoArgs& left_,
+ const PathQuadraticCurvetoArgs& right_ );
+
+typedef std::list<Magick::PathQuadraticCurvetoArgs> PathQuadraticCurvetoArgsList;
+
+#if defined(MagickDLLExplicitTemplate)
+
+MagickDrawableExtern template class MagickDLLDecl
+std::allocator<Magick::PathQuadraticCurvetoArgs>;
+
+// MagickDrawableExtern template class MagickDLLDecl
+// std::list<Magick::PathQuadraticCurvetoArgs, std::allocator<Magick::PathQuadraticCurvetoArgs> >;
+
+#endif // MagickDLLExplicitTemplate
+
+class MagickDLLDecl PathQuadraticCurvetoAbs : public VPathBase
+{
+public:
+ // Draw a single curve
+ PathQuadraticCurvetoAbs ( const Magick::PathQuadraticCurvetoArgs &args_ );
+
+ // Draw multiple curves
+ PathQuadraticCurvetoAbs ( const PathQuadraticCurvetoArgsList &args_ );
+
+ // Copy constructor
+ PathQuadraticCurvetoAbs ( const PathQuadraticCurvetoAbs& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathQuadraticCurvetoAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ PathQuadraticCurvetoArgsList _args;
+};
+class MagickDLLDecl PathQuadraticCurvetoRel : public VPathBase
+{
+public:
+ // Draw a single curve
+ PathQuadraticCurvetoRel ( const Magick::PathQuadraticCurvetoArgs &args_ );
+
+ // Draw multiple curves
+ PathQuadraticCurvetoRel ( const PathQuadraticCurvetoArgsList &args_ );
+
+ // Copy constructor
+ PathQuadraticCurvetoRel ( const PathQuadraticCurvetoRel& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathQuadraticCurvetoRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ PathQuadraticCurvetoArgsList _args;
+};
+class MagickDLLDecl PathSmoothQuadraticCurvetoAbs : public VPathBase
+{
+public:
+ // Draw a single curve
+ PathSmoothQuadraticCurvetoAbs ( const Magick::Coordinate &coordinate_ );
+
+ // Draw multiple curves
+ PathSmoothQuadraticCurvetoAbs ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ PathSmoothQuadraticCurvetoAbs ( const PathSmoothQuadraticCurvetoAbs& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathSmoothQuadraticCurvetoAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+class MagickDLLDecl PathSmoothQuadraticCurvetoRel : public VPathBase
+{
+public:
+ // Draw a single curve
+ PathSmoothQuadraticCurvetoRel ( const Magick::Coordinate &coordinate_ );
+
+ // Draw multiple curves
+ PathSmoothQuadraticCurvetoRel ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ PathSmoothQuadraticCurvetoRel ( const PathSmoothQuadraticCurvetoRel& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathSmoothQuadraticCurvetoRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+
+//
+// Path Lineto
+//
+class MagickDLLDecl PathLinetoAbs : public VPathBase
+{
+public:
+ // Draw to a single point
+ PathLinetoAbs ( const Magick::Coordinate& coordinate_ );
+
+ // Draw to multiple points
+ PathLinetoAbs ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ PathLinetoAbs ( const PathLinetoAbs& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathLinetoAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+class MagickDLLDecl PathLinetoRel : public VPathBase
+{
+public:
+ // Draw to a single point
+ PathLinetoRel ( const Magick::Coordinate& coordinate_ );
+
+ // Draw to multiple points
+ PathLinetoRel ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ PathLinetoRel ( const PathLinetoRel& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathLinetoRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+
+// Path Horizontal Lineto
+class MagickDLLDecl PathLinetoHorizontalAbs : public VPathBase
+{
+public:
+ PathLinetoHorizontalAbs ( double x_ )
+ : _x(x_)
+ {
+ }
+
+ /*virtual*/ ~PathLinetoHorizontalAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+private:
+ double _x;
+};
+class MagickDLLDecl PathLinetoHorizontalRel : public VPathBase
+{
+public:
+ PathLinetoHorizontalRel ( double x_ )
+ : _x(x_)
+ {
+ }
+
+ /*virtual*/ ~PathLinetoHorizontalRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+ void x( double x_ )
+ {
+ _x = x_;
+ }
+ double x( void ) const
+ {
+ return _x;
+ }
+
+private:
+ double _x;
+};
+
+// Path Vertical Lineto
+class MagickDLLDecl PathLinetoVerticalAbs : public VPathBase
+{
+public:
+ PathLinetoVerticalAbs ( double y_ )
+ : _y(y_)
+ {
+ }
+
+ /*virtual*/ ~PathLinetoVerticalAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+private:
+ double _y;
+};
+class MagickDLLDecl PathLinetoVerticalRel : public VPathBase
+{
+public:
+ PathLinetoVerticalRel ( double y_ )
+ : _y(y_)
+ {
+ }
+
+ /*virtual*/ ~PathLinetoVerticalRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+ void y( double y_ )
+ {
+ _y = y_;
+ }
+ double y( void ) const
+ {
+ return _y;
+ }
+
+private:
+ double _y;
+};
+
+// Path Moveto
+class MagickDLLDecl PathMovetoAbs : public VPathBase
+{
+public:
+ // Simple moveto
+ PathMovetoAbs ( const Magick::Coordinate &coordinate_ );
+
+ // Moveto followed by implicit linetos
+ PathMovetoAbs ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ PathMovetoAbs ( const PathMovetoAbs& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathMovetoAbs ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+class MagickDLLDecl PathMovetoRel : public VPathBase
+{
+public:
+ // Simple moveto
+ PathMovetoRel ( const Magick::Coordinate &coordinate_ );
+
+ // Moveto followed by implicit linetos
+ PathMovetoRel ( const CoordinateList &coordinates_ );
+
+ // Copy constructor
+ PathMovetoRel ( const PathMovetoRel& original_ );
+
+ // Destructor
+ /*virtual*/ ~PathMovetoRel ( void );
+
+ // Operator to invoke equivalent draw API call
+ /*virtual*/ void operator()( MagickLib::DrawContext context_ ) const;
+
+ // Return polymorphic copy of object
+ /*virtual*/ VPathBase* copy() const;
+
+private:
+ CoordinateList _coordinates;
+};
+
+} // namespace Magick
+
+#endif // Magick_Drawable_header
diff --git a/Magick++/lib/Magick++/Exception.h b/Magick++/lib/Magick++/Exception.h
new file mode 100644
index 0000000..7bdc544
--- /dev/null
+++ b/Magick++/lib/Magick++/Exception.h
@@ -0,0 +1,337 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
+//
+// Definition of Magick::Exception and derived classes
+// Magick::Warning* and Magick::Error*. Derived from C++ STD
+// 'exception' class for convenience.
+//
+// These classes form part of the Magick++ user interface.
+//
+
+#if !defined(Magick_Exception_header)
+#define Magick_Exception_header
+
+#include "Magick++/Include.h"
+#include <string>
+#include <exception>
+
+namespace Magick
+{
+ class MagickDLLDecl Exception : public std::exception
+ {
+ public:
+ Exception( const std::string& what_ );
+ Exception( const Exception& original_ );
+ Exception& operator= (const Exception& original_ );
+ virtual const char* what () const throw();
+ virtual ~Exception ( ) throw ();
+
+ private:
+ std::string _what;
+ };
+
+ //
+ // Warnings
+ //
+
+ class MagickDLLDecl Warning : public Exception
+ {
+ public:
+ explicit Warning ( const std::string& what_ );
+ ~Warning() throw ();
+ };
+
+ class MagickDLLDecl WarningUndefined : public Warning
+ {
+ public:
+ explicit WarningUndefined ( const std::string& what_ );
+ ~WarningUndefined() throw ();
+ };
+
+ class MagickDLLDecl WarningBlob: public Warning
+ {
+ public:
+ explicit WarningBlob ( const std::string& what_ );
+ ~WarningBlob() throw ();
+ };
+
+ class MagickDLLDecl WarningCache: public Warning
+ {
+ public:
+ explicit WarningCache ( const std::string& what_ );
+ ~WarningCache() throw ();
+ };
+
+ class MagickDLLDecl WarningCoder: public Warning
+ {
+ public:
+ explicit WarningCoder ( const std::string& what_ );
+ ~WarningCoder() throw ();
+ };
+
+ class MagickDLLDecl WarningConfigure: public Warning
+ {
+ public:
+ explicit WarningConfigure ( const std::string& what_ );
+ ~WarningConfigure() throw ();
+ };
+
+ class MagickDLLDecl WarningCorruptImage: public Warning
+ {
+ public:
+ explicit WarningCorruptImage ( const std::string& what_ );
+ ~WarningCorruptImage() throw ();
+ };
+
+ class MagickDLLDecl WarningDelegate : public Warning
+ {
+ public:
+ explicit WarningDelegate ( const std::string& what_ );
+ ~WarningDelegate() throw ();
+ };
+
+ class MagickDLLDecl WarningDraw : public Warning
+ {
+ public:
+ explicit WarningDraw ( const std::string& what_ );
+ ~WarningDraw() throw ();
+ };
+
+ class MagickDLLDecl WarningFileOpen: public Warning
+ {
+ public:
+ explicit WarningFileOpen ( const std::string& what_ );
+ ~WarningFileOpen() throw ();
+ };
+
+ class MagickDLLDecl WarningImage: public Warning
+ {
+ public:
+ explicit WarningImage ( const std::string& what_ );
+ ~WarningImage() throw ();
+ };
+
+ class MagickDLLDecl WarningMissingDelegate : public Warning
+ {
+ public:
+ explicit WarningMissingDelegate ( const std::string& what_ );
+ ~WarningMissingDelegate() throw ();
+ };
+
+ class MagickDLLDecl WarningModule : public Warning
+ {
+ public:
+ explicit WarningModule ( const std::string& what_ );
+ ~WarningModule() throw ();
+ };
+
+ class MagickDLLDecl WarningMonitor : public Warning
+ {
+ public:
+ explicit WarningMonitor ( const std::string& what_ );
+ ~WarningMonitor() throw ();
+ };
+
+ class MagickDLLDecl WarningOption : public Warning
+ {
+ public:
+ explicit WarningOption ( const std::string& what_ );
+ ~WarningOption() throw ();
+ };
+
+ class MagickDLLDecl WarningRegistry : public Warning
+ {
+ public:
+ explicit WarningRegistry ( const std::string& what_ );
+ ~WarningRegistry() throw ();
+ };
+
+ class MagickDLLDecl WarningResourceLimit : public Warning
+ {
+ public:
+ explicit WarningResourceLimit ( const std::string& what_ );
+ ~WarningResourceLimit() throw ();
+ };
+
+ class MagickDLLDecl WarningStream : public Warning
+ {
+ public:
+ explicit WarningStream ( const std::string& what_ );
+ ~WarningStream() throw ();
+ };
+
+ class MagickDLLDecl WarningType : public Warning
+ {
+ public:
+ explicit WarningType ( const std::string& what_ );
+ ~WarningType() throw ();
+ };
+
+ class MagickDLLDecl WarningXServer : public Warning
+ {
+ public:
+ explicit WarningXServer ( const std::string& what_ );
+ ~WarningXServer() throw ();
+ };
+
+ //
+ // Error exceptions
+ //
+
+ class MagickDLLDecl Error : public Exception
+ {
+ public:
+ explicit Error ( const std::string& what_ );
+ ~Error() throw ();
+ };
+
+ class MagickDLLDecl ErrorUndefined : public Error
+ {
+ public:
+ explicit ErrorUndefined ( const std::string& what_ );
+ ~ErrorUndefined() throw ();
+ };
+
+ class MagickDLLDecl ErrorBlob: public Error
+ {
+ public:
+ explicit ErrorBlob ( const std::string& what_ );
+ ~ErrorBlob() throw ();
+ };
+
+ class MagickDLLDecl ErrorCache: public Error
+ {
+ public:
+ explicit ErrorCache ( const std::string& what_ );
+ ~ErrorCache() throw ();
+ };
+
+ class MagickDLLDecl ErrorCoder: public Error
+ {
+ public:
+ explicit ErrorCoder ( const std::string& what_ );
+ ~ErrorCoder() throw ();
+ };
+
+ class MagickDLLDecl ErrorConfigure: public Error
+ {
+ public:
+ explicit ErrorConfigure ( const std::string& what_ );
+ ~ErrorConfigure() throw ();
+ };
+
+ class MagickDLLDecl ErrorCorruptImage: public Error
+ {
+ public:
+ explicit ErrorCorruptImage ( const std::string& what_ );
+ ~ErrorCorruptImage() throw ();
+ };
+
+ class MagickDLLDecl ErrorDelegate : public Error
+ {
+ public:
+ explicit ErrorDelegate ( const std::string& what_ );
+ ~ErrorDelegate() throw ();
+ };
+
+ class MagickDLLDecl ErrorDraw : public Error
+ {
+ public:
+ explicit ErrorDraw ( const std::string& what_ );
+ ~ErrorDraw() throw ();
+ };
+
+ class MagickDLLDecl ErrorFileOpen: public Error
+ {
+ public:
+ explicit ErrorFileOpen ( const std::string& what_ );
+ ~ErrorFileOpen() throw ();
+ };
+
+ class MagickDLLDecl ErrorImage: public Error
+ {
+ public:
+ explicit ErrorImage ( const std::string& what_ );
+ ~ErrorImage() throw ();
+ };
+
+ class MagickDLLDecl ErrorMissingDelegate : public Error
+ {
+ public:
+ explicit ErrorMissingDelegate ( const std::string& what_ );
+ ~ErrorMissingDelegate() throw ();
+ };
+
+ class MagickDLLDecl ErrorModule : public Error
+ {
+ public:
+ explicit ErrorModule ( const std::string& what_ );
+ ~ErrorModule() throw ();
+ };
+
+ class MagickDLLDecl ErrorMonitor : public Error
+ {
+ public:
+ explicit ErrorMonitor ( const std::string& what_ );
+ ~ErrorMonitor() throw ();
+ };
+
+ class MagickDLLDecl ErrorOption : public Error
+ {
+ public:
+ explicit ErrorOption ( const std::string& what_ );
+ ~ErrorOption() throw ();
+ };
+
+ class MagickDLLDecl ErrorRegistry : public Error
+ {
+ public:
+ explicit ErrorRegistry ( const std::string& what_ );
+ ~ErrorRegistry() throw ();
+ };
+
+ class MagickDLLDecl ErrorResourceLimit : public Error
+ {
+ public:
+ explicit ErrorResourceLimit ( const std::string& what_ );
+ ~ErrorResourceLimit() throw ();
+ };
+
+ class MagickDLLDecl ErrorStream : public Error
+ {
+ public:
+ explicit ErrorStream ( const std::string& what_ );
+ ~ErrorStream() throw ();
+ };
+
+ class MagickDLLDecl ErrorType : public Error
+ {
+ public:
+ explicit ErrorType ( const std::string& what_ );
+ ~ErrorType() throw ();
+ };
+
+ class MagickDLLDecl ErrorXServer : public Error
+ {
+ public:
+ explicit ErrorXServer ( const std::string& what_ );
+ ~ErrorXServer() throw ();
+ };
+
+ //
+ // No user-serviceable components beyond this point.
+ //
+
+ // Throw exception based on raw data
+ MagickDLLDeclExtern void throwExceptionExplicit( const MagickLib::ExceptionType severity_,
+ const char* reason_,
+ const char* description_ = 0 );
+
+ // Thow exception based on ImageMagick's ExceptionInfo
+ MagickDLLDeclExtern void throwException( MagickLib::ExceptionInfo &exception_,
+ const bool quiet_ = false );
+
+} // namespace Magick
+
+#endif // Magick_Exception_header
diff --git a/Magick++/lib/Magick++/Functions.h b/Magick++/lib/Magick++/Functions.h
new file mode 100644
index 0000000..a1811d0
--- /dev/null
+++ b/Magick++/lib/Magick++/Functions.h
@@ -0,0 +1,20 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2003
+//
+// Simple C++ function wrappers for often used or otherwise
+// inconvenient ImageMagick equivalents
+//
+
+#if !defined(Magick_Functions_header)
+#define Magick_Functions_header
+
+#include "Magick++/Include.h"
+#include <string>
+
+namespace Magick
+{
+ void MagickDLLDecl CloneString( char **destination_, const std::string &source_ );
+
+}
+#endif // Magick_Functions_header
diff --git a/Magick++/lib/Magick++/Geometry.h b/Magick++/lib/Magick++/Geometry.h
new file mode 100644
index 0000000..a46d94d
--- /dev/null
+++ b/Magick++/lib/Magick++/Geometry.h
@@ -0,0 +1,153 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999 - 2014
+//
+// Geometry Definition
+//
+// Representation of an ImageMagick geometry specification
+// X11 geometry specification plus hints
+
+#if !defined (Magick_Geometry_header)
+#define Magick_Geometry_header
+
+#include "Magick++/Include.h"
+#include <string>
+
+namespace Magick
+{
+
+ class MagickDLLDecl Geometry;
+
+ // Compare two Geometry objects regardless of LHS/RHS
+ int MagickDLLDecl operator == ( const Magick::Geometry& left_, const Magick::Geometry& right_ );
+ int MagickDLLDecl operator != ( const Magick::Geometry& left_, const Magick::Geometry& right_ );
+ int MagickDLLDecl operator > ( const Magick::Geometry& left_, const Magick::Geometry& right_ );
+ int MagickDLLDecl operator < ( const Magick::Geometry& left_, const Magick::Geometry& right_ );
+ int MagickDLLDecl operator >= ( const Magick::Geometry& left_, const Magick::Geometry& right_ );
+ int MagickDLLDecl operator <= ( const Magick::Geometry& left_, const Magick::Geometry& right_ );
+
+ class MagickDLLDecl Geometry
+ {
+ public:
+
+ Geometry ( unsigned int width_,
+ unsigned int height_,
+ unsigned int xOff_ = 0,
+ unsigned int yOff_ = 0,
+ bool xNegative_ = false,
+ bool yNegative_ = false );
+ Geometry ( const std::string &geometry_ );
+ Geometry ( const char * geometry_ );
+ Geometry ( const Geometry &geometry_ );
+ Geometry ( );
+ ~Geometry ( void );
+
+ // Width
+ void width ( unsigned int width_ );
+ unsigned int width ( void ) const;
+
+ // Height
+ void height ( unsigned int height_ );
+ unsigned int height ( void ) const;
+
+ // X offset from origin
+ void xOff ( unsigned int xOff_ );
+ unsigned int xOff ( void ) const;
+
+ // Y offset from origin
+ void yOff ( unsigned int yOff_ );
+ unsigned int yOff ( void ) const;
+
+ // Sign of X offset negative? (X origin at right)
+ void xNegative ( bool xNegative_ );
+ bool xNegative ( void ) const;
+
+ // Sign of Y offset negative? (Y origin at bottom)
+ void yNegative ( bool yNegative_ );
+ bool yNegative ( void ) const;
+
+ // Width and height are expressed as percentages
+ void percent ( bool percent_ );
+ bool percent ( void ) const;
+
+ // Resize without preserving aspect ratio (!)
+ void aspect ( bool aspect_ );
+ bool aspect ( void ) const;
+
+ // Resize if image is greater than size (>)
+ void greater ( bool greater_ );
+ bool greater ( void ) const;
+
+ // Resize if image is less than size (<)
+ void less ( bool less_ );
+ bool less ( void ) const;
+
+ // Resize image to fit total pixel area specified by dimensions (@).
+ void limitPixels ( bool limitPixels_ );
+ bool limitPixels ( void ) const;
+
+ // Dimensions are treated as minimum rather than maximum values (^)
+ void fillArea ( bool fillArea_ );
+ bool fillArea ( void ) const;
+
+ // Does object contain valid geometry?
+ void isValid ( bool isValid_ );
+ bool isValid ( void ) const;
+
+ // Set via geometry string
+ const Geometry& operator = ( const std::string &geometry_ );
+ const Geometry& operator = ( const char * geometry_ );
+
+ // Assignment operator
+ Geometry& operator= ( const Geometry& Geometry_ );
+
+ // Return geometry string
+ operator std::string() const;
+
+ //
+ // Public methods below this point are for Magick++ use only.
+ //
+
+ // Construct from RectangleInfo
+ Geometry ( const MagickLib::RectangleInfo &rectangle_ );
+
+ // Return an ImageMagick RectangleInfo struct
+ operator MagickLib::RectangleInfo() const;
+
+ private:
+ unsigned int _width;
+ unsigned int _height;
+ unsigned int _xOff;
+ unsigned int _yOff;
+ union
+ {
+ struct
+ {
+ // Bit-field for compact boolean storage
+ bool _xNegative : 1;
+ bool _yNegative : 1;
+ bool _isValid : 1;
+ bool _percent : 1; // Interpret width & height as percentages (%)
+ bool _aspect : 1; // Force exact size (!)
+ bool _greater : 1; // Re-size only if larger than geometry (>)
+ bool _less : 1; // Re-size only if smaller than geometry (<)
+ bool _limitPixels : 1;// Resize image to fit total pixel area (@).
+ bool _fillArea : 1; // Dimensions are treated as
+ // minimum rather than maximum
+ // values (^)
+ } _b;
+ struct
+ {
+ // Padding for future use.
+ unsigned int pad[2];
+ } _padding;
+ } _flags; // union
+ }; // class Geometry;
+} // namespace Magick
+
+//
+// Inlines
+//
+
+
+#endif // Magick_Geometry_header
diff --git a/Magick++/lib/Magick++/Image.h b/Magick++/lib/Magick++/Image.h
new file mode 100644
index 0000000..cf4e767
--- /dev/null
+++ b/Magick++/lib/Magick++/Image.h
@@ -0,0 +1,1408 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999 - 2015
+//
+// Definition of Image, the representation of a single image in Magick++
+//
+
+#if !defined(Magick_Image_header)
+#define Magick_Image_header
+
+#include "Magick++/Include.h"
+#include <string>
+#include <list>
+#include "Magick++/Blob.h"
+#include "Magick++/Color.h"
+#include "Magick++/Drawable.h"
+#include "Magick++/Exception.h"
+#include "Magick++/Geometry.h"
+#include "Magick++/TypeMetric.h"
+
+namespace Magick
+{
+ // Forward declarations
+ class Options;
+ class ImageRef;
+
+// extern MagickDLLDecl const std::string borderGeometryDefault;
+// extern MagickDLLDecl const std::string frameGeometryDefault;
+// extern MagickDLLDecl const std::string raiseGeometryDefault;
+ extern MagickDLLDecl const char *borderGeometryDefault;
+ extern MagickDLLDecl const char *frameGeometryDefault;
+ extern MagickDLLDecl const char *raiseGeometryDefault;
+
+ // Compare two Image objects regardless of LHS/RHS
+ // Image sizes and signatures are used as basis of comparison
+ int MagickDLLDecl operator == ( const Magick::Image& left_,
+ const Magick::Image& right_ );
+ int MagickDLLDecl operator != ( const Magick::Image& left_,
+ const Magick::Image& right_ );
+ int MagickDLLDecl operator > ( const Magick::Image& left_,
+ const Magick::Image& right_ );
+ int MagickDLLDecl operator < ( const Magick::Image& left_,
+ const Magick::Image& right_ );
+ int MagickDLLDecl operator >= ( const Magick::Image& left_,
+ const Magick::Image& right_ );
+ int MagickDLLDecl operator <= ( const Magick::Image& left_,
+ const Magick::Image& right_ );
+
+ // C library initialization routine
+ void MagickDLLDecl InitializeMagick(const char *path_);
+
+ //
+ // Image is the representation of an image. In reality, it actually
+ // a handle object which contains a pointer to a shared reference
+ // object (ImageRef). As such, this object is extremely space efficient.
+ //
+ class MagickDLLDecl Image
+ {
+ public:
+ // Construct from image file or image specification
+ Image( const std::string &imageSpec_ );
+
+ // Construct a blank image canvas of specified size and color
+ Image( const Geometry &size_, const Color &color_ );
+
+ // Construct Image from in-memory BLOB
+ Image ( const Blob &blob_ );
+
+ // Construct Image of specified size from in-memory BLOB
+ Image ( const Blob &blob_, const Geometry &size_ );
+
+ // Construct Image of specified size and depth from in-memory BLOB
+ Image ( const Blob &blob_, const Geometry &size,
+ const unsigned int depth );
+
+ // Construct Image of specified size, depth, and format from
+ // in-memory BLOB
+ Image ( const Blob &blob_, const Geometry &size,
+ const unsigned int depth_,
+ const std::string &magick_ );
+ // Construct Image of specified size, and format from in-memory
+ // BLOB
+ Image ( const Blob &blob_, const Geometry &size,
+ const std::string &magick_ );
+
+ // Construct an image based on an array of raw pixels, of
+ // specified type and mapping, in memory
+ Image ( const unsigned int width_,
+ const unsigned int height_,
+ const std::string &map_,
+ const StorageType type_,
+ const void *pixels_ );
+
+ // Default constructor
+ Image( void );
+
+ // Destructor
+ virtual ~Image();
+
+ /// Copy constructor
+ Image ( const Image & image_ );
+
+ // Assignment operator
+ Image& operator= ( const Image &image_ );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // Image operations
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ // Local adaptive threshold image
+ // http://www.dai.ed.ac.uk/HIPR2/adpthrsh.htm
+ // Width x height define the size of the pixel neighborhood
+ // offset = constant to subtract from pixel neighborhood mean
+ void adaptiveThreshold ( const unsigned int width,
+ const unsigned int height,
+ const double offset = 0.0 );
+ void adaptiveThreshold ( const unsigned int width,
+ const unsigned int height,
+ const unsigned int offset) MAGICK_FUNC_DEPRECATED;
+
+ // Add noise to image with specified noise type
+ void addNoise ( const NoiseType noiseType_ );
+ void addNoiseChannel ( const ChannelType channel_,
+ const NoiseType noiseType_);
+
+ // Transform image by specified affine (or free transform) matrix.
+ void affineTransform ( const DrawableAffine &affine );
+
+ //
+ // Annotate image (draw text on image)
+ //
+
+ // Gravity effects text placement in bounding area according to rules:
+ // NorthWestGravity text bottom-left corner placed at top-left
+ // NorthGravity text bottom-center placed at top-center
+ // NorthEastGravity text bottom-right corner placed at top-right
+ // WestGravity text left-center placed at left-center
+ // CenterGravity text center placed at center
+ // EastGravity text right-center placed at right-center
+ // SouthWestGravity text top-left placed at bottom-left
+ // SouthGravity text top-center placed at bottom-center
+ // SouthEastGravity text top-right placed at bottom-right
+
+ // Annotate using specified text, and placement location
+ void annotate ( const std::string &text_,
+ const Geometry &location_ );
+ // Annotate using specified text, bounding area, and placement
+ // gravity
+ void annotate ( const std::string &text_,
+ const Geometry &boundingArea_,
+ const GravityType gravity_ );
+ // Annotate with text using specified text, bounding area,
+ // placement gravity, and rotation.
+ void annotate ( const std::string &text_,
+ const Geometry &boundingArea_,
+ const GravityType gravity_,
+ const double degrees_ );
+ // Annotate with text (bounding area is entire image) and placement
+ // gravity.
+ void annotate ( const std::string &text_,
+ const GravityType gravity_ );
+
+ // Blur image with specified blur factor
+ // The radius_ parameter specifies the radius of the Gaussian, in
+ // pixels, not counting the center pixel. The sigma_ parameter
+ // specifies the standard deviation of the Laplacian, in pixels.
+ void blur ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 );
+ void blurChannel ( const ChannelType channel_,
+ const double radius_ = 0.0,
+ const double sigma_ = 1.0 );
+
+ // Border image (add border to image)
+ void border ( const Geometry &geometry_
+ = borderGeometryDefault );
+
+ // Bake in the ASC-CDL, which is a convention for the for the
+ // exchange of basic primary color grading information between for
+ // the exchange of basic primary color grading information between
+ // equipment and software from different manufacturers. It is a
+ // useful transform for other purposes as well.
+ void cdl ( const std::string &cdl_ );
+
+ // Extract channel from image
+ void channel ( const ChannelType channel_ );
+
+ // Set or obtain modulus channel depth
+ void channelDepth ( const ChannelType channel_,
+ const unsigned int depth_ );
+ unsigned int channelDepth ( const ChannelType channel_ );
+
+ // Charcoal effect image (looks like charcoal sketch)
+ // The radius_ parameter specifies the radius of the Gaussian, in
+ // pixels, not counting the center pixel. The sigma_ parameter
+ // specifies the standard deviation of the Laplacian, in pixels.
+ void charcoal ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 );
+
+ // Chop image (remove vertical or horizontal subregion of image)
+ // FIXME: describe how geometry argument is used to select either
+ // horizontal or vertical subregion of image.
+
+ void chop ( const Geometry &geometry_ );
+
+ // Colorize image with pen color, using specified percent opacity
+ // for red, green, and blue quantums
+ void colorize ( const unsigned int opacityRed_,
+ const unsigned int opacityGreen_,
+ const unsigned int opacityBlue_,
+ const Color &penColor_ );
+ // Colorize image with pen color, using specified percent opacity.
+ void colorize ( const unsigned int opacity_,
+ const Color &penColor_ );
+
+ // Apply a color matrix to the image channels. The user supplied
+ // matrix may be of order 1 to 5 (1x1 through 5x5).
+ void colorMatrix (const unsigned int order_,
+ const double *color_matrix_);
+
+ // Comment image (add comment string to image)
+ void comment ( const std::string &comment_ );
+
+ // Compare current image with another image
+ // Sets meanErrorPerPixel, normalizedMaxError, and normalizedMeanError
+ // in the current image. False is returned if the images are identical.
+ bool compare ( const Image &reference_ );
+
+ // Compose an image onto another at specified offset and using
+ // specified algorithm
+ void composite ( const Image &compositeImage_,
+ const int xOffset_,
+ const int yOffset_,
+ const CompositeOperator compose_
+ = InCompositeOp );
+ void composite ( const Image &compositeImage_,
+ const Geometry &offset_,
+ const CompositeOperator compose_
+ = InCompositeOp );
+ void composite ( const Image &compositeImage_,
+ const GravityType gravity_,
+ const CompositeOperator compose_
+ = InCompositeOp );
+
+ // Contrast image (enhance intensity differences in image)
+ void contrast ( const unsigned int sharpen_ );
+
+ // Convolve image. Applies a user-specified convolution to the image.
+ // order_ represents the number of columns and rows in the filter kernel.
+ // kernel_ is an array of doubles representing the convolution kernel.
+ void convolve ( const unsigned int order_,
+ const double *kernel_ );
+
+ // Crop image (subregion of original image)
+ void crop ( const Geometry &geometry_ );
+
+ // Cycle image colormap
+ void cycleColormap ( const int amount_ );
+
+ // Despeckle image (reduce speckle noise)
+ void despeckle ( void );
+
+ // Display image on screen
+ void display ( void );
+
+ // Draw on image using a single drawable
+ void draw ( const Drawable &drawable_ );
+
+ // Draw on image using a drawable list
+ void draw ( const std::list<Magick::Drawable> &drawable_ );
+
+ // Edge image (hilight edges in image)
+ void edge ( const double radius_ = 0.0 );
+
+ // Emboss image (hilight edges with 3D effect)
+ // The radius_ parameter specifies the radius of the Gaussian, in
+ // pixels, not counting the center pixel. The sigma_ parameter
+ // specifies the standard deviation of the Laplacian, in pixels.
+ void emboss ( const double radius_ = 0.0,
+ const double sigma_ = 1.0);
+
+ // Enhance image (minimize noise)
+ void enhance ( void );
+
+ // Equalize image (histogram equalization)
+ void equalize ( void );
+
+ // Erase image to current "background color"
+ void erase ( void );
+
+ // Create an image canvas using background color sized according
+ // to geometry and composite existing image on it, with image
+ // placement controlled by gravity. Parameters are obtained from
+ // existing image properties if they are not specified via a
+ // method parameter. Parameters which are supported by image
+ // properties (gravity and backgroundColor) update those image
+ // properties as a side-effect.
+ void extent ( const Geometry &geometry_ );
+
+ void extent ( const Geometry &geometry_,
+ const GravityType &gravity_ );
+
+ void extent ( const Geometry &geometry_,
+ const Color &backgroundColor_ );
+
+ void extent ( const Geometry &geometry_,
+ const Color &backgroundColor_,
+ const GravityType &gravity_ );
+
+ // Flip image (reflect each scanline in the vertical direction)
+ void flip ( void );
+
+ // Flood-fill color across pixels that match the color of the
+ // target pixel and are neighbors of the target pixel.
+ // Uses current fuzz setting when determining color match.
+ void floodFillColor( const unsigned int x_,
+ const unsigned int y_,
+ const Color &fillColor_ );
+ void floodFillColor( const Geometry &point_,
+ const Color &fillColor_ );
+
+ // Flood-fill color across pixels starting at target-pixel and
+ // stopping at pixels matching specified border color.
+ // Uses current fuzz setting when determining color match.
+ void floodFillColor( const unsigned int x_,
+ const unsigned int y_,
+ const Color &fillColor_,
+ const Color &borderColor_ );
+ void floodFillColor( const Geometry &point_,
+ const Color &fillColor_,
+ const Color &borderColor_ );
+
+ // Floodfill pixels matching color (within fuzz factor) of target
+ // pixel(x,y) with replacement opacity value using method.
+ void floodFillOpacity ( const unsigned int x_,
+ const unsigned int y_,
+ const unsigned int opacity_,
+ const PaintMethod method_ );
+
+ // Flood-fill texture across pixels that match the color of the
+ // target pixel and are neighbors of the target pixel.
+ // Uses current fuzz setting when determining color match.
+ void floodFillTexture( const unsigned int x_,
+ const unsigned int y_,
+ const Image &texture_ );
+ void floodFillTexture( const Geometry &point_,
+ const Image &texture_ );
+
+ // Flood-fill texture across pixels starting at target-pixel and
+ // stopping at pixels matching specified border color.
+ // Uses current fuzz setting when determining color match.
+ void floodFillTexture( const unsigned int x_,
+ const unsigned int y_,
+ const Image &texture_,
+ const Color &borderColor_ );
+ void floodFillTexture( const Geometry &point_,
+ const Image &texture_,
+ const Color &borderColor_ );
+
+ // Flop image (reflect each scanline in the horizontal direction)
+ void flop ( void );
+
+ // Frame image
+ void frame ( const Geometry &geometry_ = frameGeometryDefault );
+ void frame ( const unsigned int width_,
+ const unsigned int height_,
+ const int innerBevel_ = 6,
+ const int outerBevel_ = 6 );
+
+ // Gamma correct image
+ void gamma ( const double gamma_ );
+ void gamma ( const double gammaRed_,
+ const double gammaGreen_,
+ const double gammaBlue_ );
+
+ // Gaussian blur image
+ // The number of neighbor pixels to be included in the convolution
+ // mask is specified by 'width_'. The standard deviation of the
+ // gaussian bell curve is specified by 'sigma_'.
+ void gaussianBlur ( const double width_, const double sigma_ );
+ void gaussianBlurChannel ( const ChannelType channel_,
+ const double width_, const double sigma_ );
+
+ // Implode image (special effect)
+ void implode ( const double factor_ );
+
+ // Apply a color lookup table (Hald CLUT) to the image.
+ void haldClut ( const Image &clutImage_ );
+
+ // Label image
+ void label ( const std::string &label_ );
+
+ // Level image. Adjust the levels of the image by scaling the
+ // colors falling between specified white and black points to the
+ // full available quantum range. The parameters provided represent
+ // the black, mid (gamma), and white points. The black point
+ // specifies the darkest color in the image. Colors darker than
+ // the black point are set to zero. Mid point (gamma) specifies a
+ // gamma correction to apply to the image. White point specifies
+ // the lightest color in the image. Colors brighter than the
+ // white point are set to the maximum quantum value. The black and
+ // white point have the valid range 0 to MaxRGB while mid (gamma)
+ // has a useful range of 0 to ten.
+ void level ( const double black_point,
+ const double white_point,
+ const double mid_point=1.0 );
+
+ // Level image channel. Adjust the levels of the image channel by
+ // scaling the values falling between specified white and black
+ // points to the full available quantum range. The parameters
+ // provided represent the black, mid (gamma), and white points.
+ // The black point specifies the darkest color in the
+ // image. Colors darker than the black point are set to zero. Mid
+ // point (gamma) specifies a gamma correction to apply to the
+ // image. White point specifies the lightest color in the image.
+ // Colors brighter than the white point are set to the maximum
+ // quantum value. The black and white point have the valid range 0
+ // to MaxRGB while mid (gamma) has a useful range of 0 to ten.
+ void levelChannel ( const ChannelType channel,
+ const double black_point,
+ const double white_point,
+ const double mid_point=1.0 );
+
+ // Magnify image by integral size
+ void magnify ( void );
+
+ // Remap image colors with closest color from reference image
+ void map ( const Image &mapImage_ ,
+ const bool dither_ = false );
+
+ // Floodfill designated area with replacement opacity value
+ void matteFloodfill ( const Color &target_ ,
+ const unsigned int opacity_,
+ const int x_, const int y_,
+ const PaintMethod method_ );
+
+ // Filter image by replacing each pixel component with the median
+ // color in a circular neighborhood
+ void medianFilter ( const double radius_ = 0.0 );
+
+ // Reduce image by integral size
+ void minify ( void );
+
+ // Modulate percent hue, saturation, and brightness of an image.
+ // Modulation of saturation and brightness is as a ratio of the
+ // current value (1.0 for no change). Modulation of hue is an
+ // absolute rotation of -180 degrees to +180 degrees from the
+ // current position corresponding to an argument range of 0 to 2.0
+ // (1.0 for no change).
+ void modulate ( const double brightness_,
+ const double saturation_,
+ const double hue_ );
+
+ // Motion blur image with specified blur factor
+ // The radius_ parameter specifies the radius of the Gaussian, in
+ // pixels, not counting the center pixel. The sigma_ parameter
+ // specifies the standard deviation of the Laplacian, in pixels.
+ // The angle_ parameter specifies the angle the object appears
+ // to be comming from (zero degrees is from the right).
+ void motionBlur ( const double radius_,
+ const double sigma_,
+ const double angle_ );
+
+ // Negate colors in image. Set grayscale to only negate grayscale
+ // values in image.
+ void negate ( const bool grayscale_ = false );
+
+ // Normalize image (increase contrast by normalizing the pixel
+ // values to span the full range of color values)
+ void normalize ( void );
+
+ // Oilpaint image (image looks like oil painting)
+ void oilPaint ( const double radius_ = 3.0 );
+
+ // Set or attenuate the opacity channel in the image. If the image
+ // pixels are opaque then they are set to the specified opacity
+ // value, otherwise they are blended with the supplied opacity
+ // value. The value of opacity_ ranges from 0 (completely opaque)
+ // to MaxRGB. The defines OpaqueOpacity and TransparentOpacity are
+ // available to specify completely opaque or completely
+ // transparent, respectively.
+ void opacity ( const unsigned int opacity_ );
+
+ // Change color of opaque pixel to specified pen color.
+ void opaque ( const Color &opaqueColor_,
+ const Color &penColor_ );
+
+ // Ping is similar to read except only enough of the image is read
+ // to determine the image columns, rows, and filesize. Access the
+ // columns(), rows(), and fileSize() attributes after invoking
+ // ping. The image data is not valid after calling ping.
+ void ping ( const std::string &imageSpec_ );
+
+ // Ping is similar to read except only enough of the image is read
+ // to determine the image columns, rows, and filesize. Access the
+ // columns(), rows(), and fileSize() attributes after invoking
+ // ping. The image data is not valid after calling ping.
+ void ping ( const Blob &blob_ );
+
+ // Quantize image (reduce number of colors)
+ void quantize ( const bool measureError_ = false );
+
+ // Apply an arithmetic or bitwise operator to the image pixel quantums.
+ void quantumOperator ( const ChannelType channel_,
+ const QuantumOperator operator_,
+ Quantum rvalue_) MAGICK_FUNC_DEPRECATED;
+ void quantumOperator ( const ChannelType channel_,
+ const QuantumOperator operator_,
+ double rvalue_);
+ void quantumOperator ( const int x_,const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const ChannelType channel_,
+ const QuantumOperator operator_,
+ const Quantum rvalue_) MAGICK_FUNC_DEPRECATED;
+ void quantumOperator ( const int x_,const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const ChannelType channel_,
+ const QuantumOperator operator_,
+ const double rvalue_);
+
+ // Execute a named process module using an argc/argv syntax similar to
+ // that accepted by a C 'main' routine. An exception is thrown if the
+ // requested process module doesn't exist, fails to load, or fails during
+ // execution.
+ void process ( std::string name_,
+ const int argc_,
+ char **argv_ );
+
+ // Raise image (lighten or darken the edges of an image to give a
+ // 3-D raised or lowered effect)
+ void raise ( const Geometry &geometry_ = raiseGeometryDefault,
+ const bool raisedFlag_ = false );
+
+ // Random threshold image.
+ //
+ // Changes the value of individual pixels based on the intensity
+ // of each pixel compared to a random threshold. The result is a
+ // low-contrast, two color image. The thresholds_ argument is a
+ // geometry containing LOWxHIGH thresholds. If the string
+ // contains 2x2, 3x3, or 4x4, then an ordered dither of order 2,
+ // 3, or 4 will be performed instead. If a channel_ argument is
+ // specified then only the specified channel is altered. This is
+ // a very fast alternative to 'quantize' based dithering.
+ void randomThreshold( const Geometry &thresholds_ );
+ void randomThresholdChannel( const Geometry &thresholds_,
+ const ChannelType channel_ );
+
+ // Read single image frame into current object
+ void read ( const std::string &imageSpec_ );
+
+ // Read single image frame of specified size into current object
+ void read ( const Geometry &size_,
+ const std::string &imageSpec_ );
+
+ // Read single image frame from in-memory BLOB
+ void read ( const Blob &blob_ );
+
+ // Read single image frame of specified size from in-memory BLOB
+ void read ( const Blob &blob_,
+ const Geometry &size_ );
+
+ // Read single image frame of specified size and depth from
+ // in-memory BLOB
+ void read ( const Blob &blob_,
+ const Geometry &size_,
+ const unsigned int depth_ );
+
+ // Read single image frame of specified size, depth, and format
+ // from in-memory BLOB
+ void read ( const Blob &blob_,
+ const Geometry &size_,
+ const unsigned int depth_,
+ const std::string &magick_ );
+
+ // Read single image frame of specified size, and format from
+ // in-memory BLOB
+ void read ( const Blob &blob_,
+ const Geometry &size_,
+ const std::string &magick_ );
+
+ // Read single image frame from an array of raw pixels, with
+ // specified storage type (ConstituteImage), e.g.
+ // image.read( 640, 480, "RGB", 0, pixels );
+ void read ( const unsigned int width_,
+ const unsigned int height_,
+ const std::string &map_,
+ const StorageType type_,
+ const void *pixels_ );
+
+ // Reduce noise in image using a noise peak elimination filter
+ void reduceNoise ( void );
+ void reduceNoise ( const double order_ );
+
+ // Resets the image page canvas and position.
+ void repage();
+
+ // Resize image, specifying geometry, filter, and blur
+ void resize ( const Geometry &geometry_,
+ const FilterTypes filterType_,
+ const double blur_ );
+
+ // Resize image, specifying geometry and filter, with blur using
+ // Image default.
+ void resize ( const Geometry &geometry_,
+ const FilterTypes filterType_ );
+
+ // Resize image, specifying only geometry, with filter and blur
+ // obtained from Image default. Same result as 'zoom' method.
+ void resize ( const Geometry &geometry_ );
+
+ // Roll image (rolls image vertically and horizontally) by specified
+ // number of columnms and rows)
+ void roll ( const Geometry &roll_ );
+ void roll ( const unsigned int columns_,
+ const unsigned int rows_ );
+
+ // Rotate image counter-clockwise by specified number of degrees.
+ void rotate ( const double degrees_ );
+
+ // Resize image by using pixel sampling algorithm
+ void sample ( const Geometry &geometry_ );
+
+ // Resize image by using simple ratio algorithm
+ void scale ( const Geometry &geometry_ );
+
+ // Resize image using several algorithms to make smaller images
+ // very quickly.
+ void thumbnail ( const Geometry &geometry_ );
+
+ // Segment (coalesce similar image components) by analyzing the
+ // histograms of the color components and identifying units that
+ // are homogeneous with the fuzzy c-means technique. Also uses
+ // QuantizeColorSpace and Verbose image attributes
+ void segment ( const double clusterThreshold_ = 1.0,
+ const double smoothingThreshold_ = 1.5 );
+
+ // Shade image using distant light source
+ void shade ( const double azimuth_ = 30,
+ const double elevation_ = 30,
+ const bool colorShading_ = false );
+
+ // Sharpen pixels in image
+ // The radius_ parameter specifies the radius of the Gaussian, in
+ // pixels, not counting the center pixel. The sigma_ parameter
+ // specifies the standard deviation of the Laplacian, in pixels.
+ void sharpen ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 );
+ void sharpenChannel ( const ChannelType channel_,
+ const double radius_ = 0.0,
+ const double sigma_ = 1.0 );
+
+ // Shave pixels from image edges.
+ void shave ( const Geometry &geometry_ );
+
+ // Shear image (create parallelogram by sliding image by X or Y axis)
+ void shear ( const double xShearAngle_,
+ const double yShearAngle_ );
+
+ // Solarize image (similar to effect seen when exposing a
+ // photographic film to light during the development process)
+ void solarize ( const double factor_ = 50.0 );
+
+ // Spread pixels randomly within image by specified ammount
+ void spread ( const unsigned int amount_ = 3 );
+
+ // Add a digital watermark to the image (based on second image)
+ void stegano ( const Image &watermark_ );
+
+ // Create an image which appears in stereo when viewed with
+ // red-blue glasses (Red image on left, blue on right)
+ void stereo ( const Image &rightImage_ );
+
+ // Remove all profiles and text attributes from the image.
+ void strip ( void );
+
+ // Swirl image (image pixels are rotated by degrees)
+ void swirl ( const double degrees_ );
+
+ // Channel a texture on image background
+ void texture ( const Image &texture_ );
+
+ // Threshold image channels (below threshold becomes black, above
+ // threshold becomes white).
+ // The range of the threshold parameter is 0 to MaxRGB.
+ void threshold ( const double threshold_ );
+
+ // Transform image based on image and crop geometries
+ // Crop geometry is optional
+ void transform ( const Geometry &imageGeometry_ );
+ void transform ( const Geometry &imageGeometry_,
+ const Geometry &cropGeometry_ );
+
+ // Add matte image to image, setting pixels matching color to
+ // transparent
+ void transparent ( const Color &color_ );
+
+ // Trim edges that are the background color from the image
+ void trim ( void );
+
+ // Image representation type (also see type attribute)
+ // Available types:
+ // Bilevel Grayscale GrayscaleMatte
+ // Palette PaletteMatte TrueColor
+ // TrueColorMatte ColorSeparation ColorSeparationMatte
+ void type ( const ImageType type_ );
+
+ // Replace image with a sharpened version of the original image
+ // using the unsharp mask algorithm.
+ // radius_
+ // the radius of the Gaussian, in pixels, not counting the
+ // center pixel.
+ // sigma_
+ // the standard deviation of the Gaussian, in pixels.
+ // amount_
+ // the percentage of the difference between the original and
+ // the blur image that is added back into the original.
+ // threshold_
+ // the threshold in pixels needed to apply the diffence amount.
+ void unsharpmask ( const double radius_,
+ const double sigma_,
+ const double amount_,
+ const double threshold_ );
+ void unsharpmaskChannel ( const ChannelType channel_,
+ const double radius_,
+ const double sigma_,
+ const double amount_,
+ const double threshold_ );
+
+ // Map image pixels to a sine wave
+ void wave ( const double amplitude_ = 25.0,
+ const double wavelength_ = 150.0 );
+
+ // Write single image frame to a file
+ void write ( const std::string &imageSpec_ );
+
+ // Write single image frame to in-memory BLOB, with optional
+ // format and adjoin parameters.
+ void write ( Blob *blob_ );
+ void write ( Blob *blob_,
+ const std::string &magick_ );
+ void write ( Blob *blob_,
+ const std::string &magick_,
+ const unsigned int depth_ );
+
+ // Write single image frame to an array of pixels with storage
+ // type specified by user (DispatchImage), e.g.
+ // image.write( 0, 0, 640, 1, "RGB", 0, pixels );
+ void write ( const int x_,
+ const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const std::string& map_,
+ const StorageType type_,
+ void *pixels_ );
+
+ // Zoom image to specified size.
+ void zoom ( const Geometry &geometry_ );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // Image Attributes and Options
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ // Join images into a single multi-image file
+ void adjoin ( const bool flag_ );
+ bool adjoin ( void ) const;
+
+ // Anti-alias Postscript and TrueType fonts (default true)
+ void antiAlias( const bool flag_ );
+ bool antiAlias( void );
+
+ // Time in 1/100ths of a second which must expire before
+ // displaying the next image in an animated sequence.
+ void animationDelay ( const unsigned int delay_ );
+ unsigned int animationDelay ( void ) const;
+
+ // Number of iterations to loop an animation (e.g. Netscape loop
+ // extension) for.
+ void animationIterations ( const unsigned int iterations_ );
+ unsigned int animationIterations ( void ) const;
+
+ // Access/Update a named image text attribute. Updates append the
+ // provided to any existing attribute text. Pass NULL as the
+ // value to remove an existing value or before a subsequent call
+ // to add new text.
+ void attribute ( const std::string name_,
+ const char * value_ );
+ void attribute ( const std::string name_,
+ const std::string value_ );
+ std::string attribute ( const std::string name_ );
+
+ // Image background color
+ void backgroundColor ( const Color &color_ );
+ Color backgroundColor ( void ) const;
+
+ // Name of texture image to tile onto the image background
+ void backgroundTexture (const std::string &backgroundTexture_ );
+ std::string backgroundTexture ( void ) const;
+
+ // Base image width (before transformations)
+ unsigned int baseColumns ( void ) const;
+
+ // Base image filename (before transformations)
+ std::string baseFilename ( void ) const;
+
+ // Base image height (before transformations)
+ unsigned int baseRows ( void ) const;
+
+ // Image border color
+ void borderColor ( const Color &color_ );
+ Color borderColor ( void ) const;
+
+ // Return smallest bounding box enclosing non-border pixels. The
+ // current fuzz value is used when discriminating between pixels.
+ // This is the crop bounding box used by crop(Geometry(0,0));
+ Geometry boundingBox ( void ) const;
+
+ // Text bounding-box base color (default none)
+ void boxColor ( const Color &boxColor_ );
+ Color boxColor ( void ) const;
+
+ // Pixel cache threshold in megabytes. Once this memory threshold
+ // is exceeded, all subsequent pixels cache operations are to/from
+ // disk. This setting is shared by all Image objects.
+ static void cacheThreshold ( const unsigned int threshold_ );
+
+ // Chromaticity blue primary point (e.g. x=0.15, y=0.06)
+ void chromaBluePrimary ( const double x_, const double y_ );
+ void chromaBluePrimary ( double *x_, double *y_ ) const;
+
+ // Chromaticity green primary point (e.g. x=0.3, y=0.6)
+ void chromaGreenPrimary ( const double x_, const double y_ );
+ void chromaGreenPrimary ( double *x_, double *y_ ) const;
+
+ // Chromaticity red primary point (e.g. x=0.64, y=0.33)
+ void chromaRedPrimary ( const double x_, const double y_ );
+ void chromaRedPrimary ( double *x_, double *y_ ) const;
+
+ // Chromaticity white point (e.g. x=0.3127, y=0.329)
+ void chromaWhitePoint ( const double x_, const double y_ );
+ void chromaWhitePoint ( double *x_, double *y_ ) const;
+
+ // Image class (DirectClass or PseudoClass)
+ // NOTE: setting a DirectClass image to PseudoClass will result in
+ // the loss of color information if the number of colors in the
+ // image is greater than the maximum palette size (either 256 or
+ // 65536 entries depending on the value of QuantumDepth when
+ // ImageMagick was built).
+ void classType ( const ClassType class_ );
+ ClassType classType ( void ) const;
+
+ // Associate a clip mask with the image. The clip mask must be the
+ // same dimensions as the image. Pass an invalid image to unset an
+ // existing clip mask.
+ void clipMask ( const Image & clipMask_ );
+ Image clipMask ( void ) const;
+
+ // Colors within this distance are considered equal
+ void colorFuzz ( const double fuzz_ );
+ double colorFuzz ( void ) const;
+
+ // Color at colormap position index_
+ void colorMap ( const unsigned int index_,
+ const Color &color_ );
+ Color colorMap ( const unsigned int index_ ) const;
+
+ // Colormap size (number of colormap entries)
+ void colorMapSize ( const unsigned int entries_ );
+ unsigned int colorMapSize ( void );
+
+ // Image Color Space
+ void colorSpace( const ColorspaceType colorSpace_ );
+ ColorspaceType colorSpace ( void ) const;
+
+ // Image width
+ unsigned int columns ( void ) const;
+
+ // Image comment
+ std::string comment ( void ) const;
+
+ // Composition operator to be used when composition is implicitly
+ // used (such as for image flattening).
+ void compose (const CompositeOperator compose_);
+ CompositeOperator compose ( void ) const;
+
+ // Compression type
+ void compressType ( const CompressionType compressType_ );
+ CompressionType compressType ( void ) const;
+
+ // Enable printing of debug messages from ImageMagick
+ void debug ( const bool flag_ );
+ bool debug ( void ) const;
+
+ // Tagged image format define (set/access coder-specific option) The
+ // magick_ option specifies the coder the define applies to. The key_
+ // option provides the key specific to that coder. The value_ option
+ // provides the value to set (if any). See the defineSet() method if the
+ // key must be removed entirely.
+ void defineValue ( const std::string &magick_,
+ const std::string &key_,
+ const std::string &value_ );
+ std::string defineValue ( const std::string &magick_,
+ const std::string &key_ ) const;
+
+ // Tagged image format define. Similar to the defineValue() method
+ // except that passing the flag_ value 'true' creates a value-less
+ // define with that format and key. Passing the flag_ value 'false'
+ // removes any existing matching definition. The method returns 'true'
+ // if a matching key exists, and 'false' if no matching key exists.
+ void defineSet ( const std::string &magick_,
+ const std::string &key_,
+ bool flag_ );
+ bool defineSet ( const std::string &magick_,
+ const std::string &key_ ) const;
+
+ // Vertical and horizontal resolution in pixels of the image
+ //
+ // The resolution is expressed in resolution units as supported by
+ // the resolutionUnits() method.
+ //
+ // Please note that the underlying resolution is floating point
+ // and use of this method will result in rounding floating point
+ // value to integer vaues. Use the xResolution() and
+ // yResolution() methods when full accuracy is required.
+ void density ( const Geometry &geomery_ );
+ Geometry density ( void ) const;
+
+ // Image depth (bits allocated to red/green/blue components)
+ void depth ( const unsigned int depth_ );
+ unsigned int depth ( void ) const;
+
+ // Tile names from within an image montage
+ std::string directory ( void ) const;
+
+ // Endianness (little like Intel or big like SPARC) for image
+ // formats which support endian-specific options.
+ void endian ( const EndianType endian_ );
+ EndianType endian ( void ) const;
+
+ // Image file name
+ void fileName ( const std::string &fileName_ );
+ std::string fileName ( void ) const;
+
+ // Number of bytes of the image on disk
+ off_t fileSize ( void ) const;
+
+ // Color to use when filling drawn objects
+ void fillColor ( const Color &fillColor_ );
+ Color fillColor ( void ) const;
+
+ // Rule to use when filling drawn objects
+ void fillRule ( const FillRule &fillRule_ );
+ FillRule fillRule ( void ) const;
+
+ // Pattern to use while filling drawn objects.
+ void fillPattern ( const Image &fillPattern_ );
+ Image fillPattern ( void ) const;
+
+ // Filter to use when resizing image using 'zoom' or 'resize'.
+ void filterType ( const FilterTypes filterType_ );
+ FilterTypes filterType ( void ) const;
+
+ // Text rendering font
+ void font ( const std::string &font_ );
+ std::string font ( void ) const;
+
+ // Font point size
+ void fontPointsize ( const double pointSize_ );
+ double fontPointsize ( void ) const;
+
+ // Obtain font metrics for text string given current font,
+ // pointsize, and density settings.
+ void fontTypeMetrics( const std::string &text_,
+ TypeMetric *metrics );
+
+ // Long image format description
+ std::string format ( void ) const;
+
+ // Format the specified expression similar to command line '-format'.
+ // For example "%wx%h" is converted to a string containing image
+ // WIDTHxHEIGHT like "640x480".
+ std::string formatExpression( const std::string expression );
+
+ // Gamma level of the image
+ double gamma ( void ) const;
+
+ // Preferred size of the image when encoding
+ Geometry geometry ( void ) const;
+
+ // GIF disposal method
+ void gifDisposeMethod ( const unsigned int disposeMethod_ );
+ unsigned int gifDisposeMethod ( void ) const;
+
+ // ICC color profile (BLOB)
+ void iccColorProfile( const Blob &colorProfile_ );
+ Blob iccColorProfile( void ) const;
+
+ // Type of interlacing to use
+ void interlaceType ( const InterlaceType interlace_ );
+ InterlaceType interlaceType ( void ) const;
+
+ // IPTC profile (BLOB)
+ void iptcProfile( const Blob& iptcProfile_ );
+ Blob iptcProfile( void ) const;
+
+ // Does object contain valid image?
+ void isValid ( const bool isValid_ );
+ bool isValid ( void ) const;
+
+ // Image label
+ std::string label ( void ) const;
+
+ // Stroke width for drawing vector objects (default one)
+ // This method is now deprecated. Please use strokeWidth instead.
+ void lineWidth ( const double lineWidth_ );
+ double lineWidth ( void ) const;
+
+ // File type magick identifier (.e.g "GIF")
+ void magick ( const std::string &magick_ );
+ std::string magick ( void ) const;
+
+ // Image supports transparency (matte channel)
+ void matte ( const bool matteFlag_ );
+ bool matte ( void ) const;
+
+ // Transparent color
+ void matteColor ( const Color &matteColor_ );
+ Color matteColor ( void ) const;
+
+ // The mean error per pixel computed when an image is color reduced
+ double meanErrorPerPixel ( void ) const;
+
+ // Image modulus depth (minimum number of bits required to support
+ // red/green/blue components without loss of accuracy)
+ void modulusDepth ( const unsigned int modulusDepth_ );
+ unsigned int modulusDepth ( void ) const;
+
+ // Tile size and offset within an image montage
+ Geometry montageGeometry ( void ) const;
+
+ // Transform image to black and white
+ void monochrome ( const bool monochromeFlag_ );
+ bool monochrome ( void ) const;
+
+ // The normalized max error per pixel computed when an image is
+ // color reduced.
+ double normalizedMaxError ( void ) const;
+
+ // The normalized mean error per pixel computed when an image is
+ // color reduced.
+ double normalizedMeanError ( void ) const;
+
+ // Image orientation
+ void orientation ( const OrientationType orientation_ );
+ OrientationType orientation ( void ) const;
+
+ // Preferred size and location of an image canvas.
+ void page ( const Geometry &pageSize_ );
+ Geometry page ( void ) const;
+
+ // Pen color (deprecated, don't use any more)
+ void penColor ( const Color &penColor_ );
+ Color penColor ( void ) const;
+
+ // Pen texture image (deprecated, don't use any more)
+ void penTexture ( const Image &penTexture_ );
+ Image penTexture ( void ) const;
+
+ // Get/set pixel color at location x & y.
+ void pixelColor ( const unsigned int x_,
+ const unsigned int y_,
+ const Color &color_ );
+ Color pixelColor ( const unsigned int x_,
+ const unsigned int y_ ) const;
+
+ // Add or remove a named profile to/from the image. Remove the
+ // profile by passing an empty Blob (e.g. Blob()). Valid names are
+ // "*", "8BIM", "ICM", "IPTC", or a user/format-defined profile name.
+ void profile( const std::string name_,
+ const Blob &colorProfile_ );
+
+ // Retrieve a named profile from the image. Valid names are:
+ // "8BIM", "8BIMTEXT", "APP1", "APP1JPEG", "ICC", "ICM", & "IPTC"
+ // or an existing user/format-defined profile name.
+ Blob profile( const std::string name_ ) const;
+
+ // JPEG/MIFF/PNG compression level (default 75).
+ void quality ( const unsigned int quality_ );
+ unsigned int quality ( void ) const;
+
+ // Maximum number of colors to quantize to
+ void quantizeColors ( const unsigned int colors_ );
+ unsigned int quantizeColors ( void ) const;
+
+ // Colorspace to quantize in.
+ void quantizeColorSpace ( const ColorspaceType colorSpace_ );
+ ColorspaceType quantizeColorSpace ( void ) const;
+
+ // Dither image during quantization (default true).
+ void quantizeDither ( const bool ditherFlag_ );
+ bool quantizeDither ( void ) const;
+
+ // Quantization tree-depth
+ void quantizeTreeDepth ( const unsigned int treeDepth_ );
+ unsigned int quantizeTreeDepth ( void ) const;
+
+ // Suppress all warning messages. Error messages are still reported.
+ void quiet ( const bool quiet_ );
+ bool quiet ( void ) const;
+
+ // The type of rendering intent
+ void renderingIntent ( const RenderingIntent renderingIntent_ );
+ RenderingIntent renderingIntent ( void ) const;
+
+ // Units of image resolution
+ void resolutionUnits ( const ResolutionType resolutionUnits_ );
+ ResolutionType resolutionUnits ( void ) const;
+
+ // The number of pixel rows in the image
+ unsigned int rows ( void ) const;
+
+ // Image scene number
+ void scene ( const unsigned int scene_ );
+ unsigned int scene ( void ) const;
+
+ // Image signature. Set force_ to true in order to re-calculate
+ // the signature regardless of whether the image data has been
+ // modified.
+ std::string signature ( const bool force_ = false ) const;
+
+ // Width and height of a raw image
+ void size ( const Geometry &geometry_ );
+ Geometry size ( void ) const;
+
+ // Obtain image statistics. Statistics are normalized to the range
+ // of 0.0 to 1.0 and are output to the specified ImageStatistics
+ // structure.
+ void statistics ( ImageStatistics *statistics ) const;
+
+ // enabled/disable stroke anti-aliasing
+ void strokeAntiAlias( const bool flag_ );
+ bool strokeAntiAlias( void ) const;
+
+ // Color to use when drawing object outlines
+ void strokeColor ( const Color &strokeColor_ );
+ Color strokeColor ( void ) const;
+
+ // Specify the pattern of dashes and gaps used to stroke
+ // paths. The strokeDashArray represents a zero-terminated array
+ // of numbers that specify the lengths of alternating dashes and
+ // gaps in pixels. If an odd number of values is provided, then
+ // the list of values is repeated to yield an even number of
+ // values. A typical strokeDashArray_ array might contain the
+ // members 5 3 2 0, where the zero value indicates the end of the
+ // pattern array.
+ void strokeDashArray ( const double* strokeDashArray_ );
+ const double* strokeDashArray ( void ) const;
+
+ // While drawing using a dash pattern, specify distance into the
+ // dash pattern to start the dash (default 0).
+ void strokeDashOffset ( const double strokeDashOffset_ );
+ double strokeDashOffset ( void ) const;
+
+ // Specify the shape to be used at the end of open subpaths when
+ // they are stroked. Values of LineCap are UndefinedCap, ButtCap,
+ // RoundCap, and SquareCap.
+ void strokeLineCap ( const LineCap lineCap_ );
+ LineCap strokeLineCap ( void ) const;
+
+ // Specify the shape to be used at the corners of paths (or other
+ // vector shapes) when they are stroked. Values of LineJoin are
+ // UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
+ void strokeLineJoin ( const LineJoin lineJoin_ );
+ LineJoin strokeLineJoin ( void ) const;
+
+ // Specify miter limit. When two line segments meet at a sharp
+ // angle and miter joins have been specified for 'lineJoin', it is
+ // possible for the miter to extend far beyond the thickness of
+ // the line stroking the path. The miterLimit' imposes a limit on
+ // the ratio of the miter length to the 'lineWidth'. The default
+ // value of this parameter is 4.
+ void strokeMiterLimit ( const unsigned int miterLimit_ );
+ unsigned int strokeMiterLimit ( void ) const;
+
+ // Pattern image to use while stroking object outlines.
+ void strokePattern ( const Image &strokePattern_ );
+ Image strokePattern ( void ) const;
+
+ // Stroke width for drawing vector objects (default one)
+ void strokeWidth ( const double strokeWidth_ );
+ double strokeWidth ( void ) const;
+
+ // Subimage of an image sequence
+ void subImage ( const unsigned int subImage_ );
+ unsigned int subImage ( void ) const;
+
+ // Number of images relative to the base image
+ void subRange ( const unsigned int subRange_ );
+ unsigned int subRange ( void ) const;
+
+ // Annotation text encoding (e.g. "UTF-16")
+ void textEncoding ( const std::string &encoding_ );
+ std::string textEncoding ( void ) const;
+
+ // Tile name
+ void tileName ( const std::string &tileName_ );
+ std::string tileName ( void ) const;
+
+ // Number of colors in the image
+ unsigned long totalColors ( void );
+
+ // Origin of coordinate system to use when annotating with text or drawing
+ void transformOrigin ( const double x_,const double y_ );
+
+ // Rotation to use when annotating with text or drawing
+ void transformRotation ( const double angle_ );
+
+ // Reset transformation parameters to default
+ void transformReset ( void );
+
+ // Scale to use when annotating with text or drawing
+ void transformScale ( const double sx_, const double sy_ );
+
+ // Skew to use in X axis when annotating with text or drawing
+ void transformSkewX ( const double skewx_ );
+
+ // Skew to use in Y axis when annotating with text or drawing
+ void transformSkewY ( const double skewy_ );
+
+ // Image representation type (also see type operation)
+ // Available types:
+ // Bilevel Grayscale GrayscaleMatte
+ // Palette PaletteMatte TrueColor
+ // TrueColorMatte ColorSeparation ColorSeparationMatte
+ ImageType type ( void ) const;
+
+ // Print detailed information about the image
+ void verbose ( const bool verboseFlag_ );
+ bool verbose ( void ) const;
+
+ // FlashPix viewing parameters
+ void view ( const std::string &view_ );
+ std::string view ( void ) const;
+
+ // X11 display to display to, obtain fonts from, or to capture
+ // image from
+ void x11Display ( const std::string &display_ );
+ std::string x11Display ( void ) const;
+
+ // x resolution of the image
+ void xResolution ( const double x_resolution );
+ double xResolution ( void ) const;
+
+ // y resolution of the image
+ void yResolution ( const double y_resolution );
+ double yResolution ( void ) const;
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // Low-level Pixel Access Routines
+ //
+ // Also see the Pixels class, which provides support for multiple
+ // cache views.
+ //
+ //////////////////////////////////////////////////////////////////////
+
+
+ // Transfers read-only pixels from the image to the pixel cache as
+ // defined by the specified region
+ const PixelPacket* getConstPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ ) const;
+
+ // Obtain mutable image pixel indexes (valid for PseudoClass images)
+ IndexPacket* getIndexes ( void );
+
+ // Obtain immutable image pixel indexes (valid for PseudoClass images)
+ const IndexPacket* getConstIndexes ( void ) const;
+
+ // Transfers pixels from the image to the pixel cache as defined
+ // by the specified region. Modified pixels may be subsequently
+ // transferred back to the image via syncPixels. This method is
+ // valid for DirectClass images.
+ PixelPacket* getPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ );
+
+ // Allocates a pixel cache region to store image pixels as defined
+ // by the region rectangle. This area is subsequently transferred
+ // from the pixel cache to the image via syncPixels.
+ PixelPacket* setPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ );
+
+ // Transfers the image cache pixels to the image.
+ void syncPixels ( void );
+
+ // Transfers one or more pixel components from a buffer or file
+ // into the image pixel cache of an image.
+ // Used to support image decoders.
+ void readPixels ( const QuantumType quantum_,
+ const unsigned char *source_ );
+
+ // Transfers one or more pixel components from the image pixel
+ // cache to a buffer or file.
+ // Used to support image encoders.
+ void writePixels ( const QuantumType quantum_,
+ unsigned char *destination_ );
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // No user-serviceable parts beyond this point
+ //
+ //////////////////////////////////////////////////////////////////////
+
+
+ // Construct with MagickLib::Image and default options
+ Image ( MagickLib::Image* image_ );
+
+ // Retrieve Image*
+ MagickLib::Image*& image( void );
+ const MagickLib::Image* constImage( void ) const;
+
+ // Retrieve Options*
+ Options* options( void );
+ const Options* constOptions( void ) const;
+
+ // Retrieve ImageInfo*
+ MagickLib::ImageInfo * imageInfo( void );
+ const MagickLib::ImageInfo * constImageInfo( void ) const;
+
+ // Retrieve QuantizeInfo*
+ MagickLib::QuantizeInfo * quantizeInfo( void );
+ const MagickLib::QuantizeInfo * constQuantizeInfo( void ) const;
+
+ // Replace current image (reference counted)
+ MagickLib::Image* replaceImage ( MagickLib::Image* replacement_ );
+
+ // Prepare to update image (copy if reference > 1)
+ void modifyImage ( void );
+
+ // Test for ImageMagick error and throw exception if error
+ void throwImageException( void ) const;
+
+ // Register image with image registry or obtain registration id
+ long registerId( void );
+
+ // Unregister image from image registry
+ void unregisterId( void) ;
+
+ private:
+
+ void throwImageException( MagickLib::ExceptionInfo &exception_ ) const;
+
+ ImageRef * _imgRef;
+ };
+
+} // end of namespace Magick
+
+//
+// Inlines
+//
+
+
+//
+// Image
+//
+
+
+// Reduce noise in image using a noise peak elimination filter
+inline void Magick::Image::reduceNoise ( void )
+{
+ reduceNoise( 3.0 );
+}
+
+// Stroke width for drawing vector objects (default one)
+inline void Magick::Image::lineWidth ( const double lineWidth_ )
+{
+ strokeWidth( lineWidth_ );
+}
+inline double Magick::Image::lineWidth ( void ) const
+{
+ return strokeWidth( );
+}
+
+// Get image storage class
+inline Magick::ClassType Magick::Image::classType ( void ) const
+{
+ return static_cast<Magick::ClassType>(constImage()->storage_class);
+}
+
+// Get number of image columns
+inline unsigned int Magick::Image::columns ( void ) const
+{
+ return constImage()->columns;
+}
+
+// Get number of image rows
+inline unsigned int Magick::Image::rows ( void ) const
+{
+ return constImage()->rows;
+}
+
+#endif // Magick_Image_header
diff --git a/Magick++/lib/Magick++/ImageRef.h b/Magick++/lib/Magick++/ImageRef.h
new file mode 100644
index 0000000..3b45dc7
--- /dev/null
+++ b/Magick++/lib/Magick++/ImageRef.h
@@ -0,0 +1,80 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
+//
+// Definition of an Image reference
+//
+// This is a private implementation class which should never be
+// referenced by any user code.
+//
+
+#if !defined(Magick_ImageRef_header)
+#define Magick_ImageRef_header
+
+#include "Magick++/Include.h"
+#include "Magick++/Thread.h"
+
+namespace Magick
+{
+ class Options;
+
+ //
+ // Reference counted access to Image *
+ //
+ class MagickDLLDecl ImageRef {
+ friend class Image;
+ private:
+ // Construct with an image pointer and default options
+ ImageRef ( MagickLib::Image * image_ );
+ // Construct with an image pointer and options
+ ImageRef ( MagickLib::Image * image_, const Options * options_ );
+ // Construct with null image and default options
+ ImageRef ( void );
+ // Destroy image and options
+ ~ImageRef ( void );
+
+ // Copy constructor and assignment are not supported
+ ImageRef(const ImageRef&);
+ ImageRef& operator=(const ImageRef&);
+
+ void image ( MagickLib::Image * image_ );
+ MagickLib::Image *& image ( void );
+
+ void options ( Options * options_ );
+ Options * options ( void );
+
+ void id ( const long id_ );
+ long id ( void ) const;
+
+ MagickLib::Image * _image; // ImageMagick Image
+ Options * _options; // User-specified options
+ long _id; // Registry ID (-1 if not registered)
+ int _refCount; // Reference count
+ MutexLock _mutexLock;// Mutex lock
+ };
+
+} // end of namespace Magick
+
+//
+// Inlines
+//
+
+// Retrieve image from reference
+inline MagickLib::Image *& Magick::ImageRef::image ( void )
+{
+ return _image;
+}
+
+// Retrieve Options from reference
+inline Magick::Options * Magick::ImageRef::options ( void )
+{
+ return _options;
+}
+
+// Retrieve registration id from reference
+inline long Magick::ImageRef::id ( void ) const
+{
+ return _id;
+}
+
+#endif // Magick_ImageRef_header
diff --git a/Magick++/lib/Magick++/Include.h b/Magick++/lib/Magick++/Include.h
new file mode 100644
index 0000000..0b260dd
--- /dev/null
+++ b/Magick++/lib/Magick++/Include.h
@@ -0,0 +1,1120 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999 - 2015
+//
+// Inclusion of GraphicsMagick headers (with namespace magic)
+
+#ifndef Magick_Include_header
+#define Magick_Include_header
+
+#if !defined(_MAGICK_CONFIG_H)
+# define _MAGICK_CONFIG_H
+# if !defined(vms) && !defined(macintosh)
+# include "magick/magick_config.h"
+# else
+# include "magick_config.h"
+# endif
+# undef inline // Remove possible definition from config.h
+# undef class
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h> /* POSIX 1990 header and declares size_t and ssize_t */
+
+#if defined(__BORLANDC__)
+# include <vcl.h> /* Borland C++ Builder 4.0 requirement */
+#endif // defined(__BORLANDC__)
+
+//
+// Include GraphicsMagick headers into namespace "MagickLib". If
+// MAGICK_IMPLEMENTATION is defined, include GraphicsMagick development
+// headers. This scheme minimizes the possibility of conflict with
+// user code.
+//
+namespace MagickLib
+{
+#include <magick/api.h>
+#undef inline // Remove possible definition from config.h
+
+#undef class
+}
+
+//
+// Provide appropriate DLL imports/exports for Visual C++,
+// Borland C++Builder and MinGW builds.
+//
+#if (defined(WIN32) || defined(WIN64)) && !defined (__CYGWIN__) //&& !defined(__MINGW32__)
+# define MagickCplusPlusDLLSupported
+#endif
+#if defined(MagickCplusPlusDLLSupported)
+# if defined(_MT) && defined(_DLL) && !defined(_LIB) && !defined(STATIC_MAGICK)
+//
+// In a native Windows build, the following defines are used:
+//
+// _MT = Multithreaded
+// _DLL = Using code is part of a DLL
+// _LIB = Using code is being built as a library.
+// _MAGICKMOD_ = Build uses loadable modules (Magick++ does not care about this)
+//
+// In the case where GraphicsMagick is built as a static library but the
+// using code is dynamic, STATIC_MAGICK may be defined in the project to
+// override triggering dynamic library behavior.
+//
+# if defined(_VISUALC_)
+# define MagickDLLExplicitTemplate /* Explicit template instantiation in DLLs */
+# pragma warning( disable: 4273 ) /* Disable the stupid dll linkage warnings */
+# pragma warning( disable: 4251 )
+# endif
+# if !defined(MAGICK_IMPLEMENTATION)
+# define MagickDLLDecl __declspec(dllimport)
+# define MagickDLLDeclExtern extern __declspec(dllimport)
+# if defined(_VISUALC_)
+# pragma message( "Magick++ lib DLL import" )
+# endif
+# else
+# if defined(__BORLANDC__) || defined(__MINGW32__)
+# define MagickDLLDecl __declspec(dllexport)
+# define MagickDLLDeclExtern __declspec(dllexport)
+# if defined(__BORLANDC__)
+# pragma message( "BCBMagick++ lib DLL export" )
+# endif
+# else
+# define MagickDLLDecl __declspec(dllexport)
+# define MagickDLLDeclExtern extern __declspec(dllexport)
+# endif
+# if defined(_VISUALC_)
+# pragma message( "Magick++ lib DLL export" )
+# endif
+# endif
+# else
+# define MagickDLLDecl
+# define MagickDLLDeclExtern
+# if defined(_VISUALC_)
+# pragma message( "Magick++ lib static interface" )
+# endif
+# if defined(_MSC_VER) && defined(STATIC_MAGICK) && !defined(NOAUTOLINK_MAGICK)
+# if defined(_DEBUG)
+# if defined(HasBZLIB)
+# pragma comment(lib, "CORE_DB_bzlib_.lib")
+# endif
+# pragma comment(lib, "CORE_DB_coders_.lib")
+# pragma comment(lib, "CORE_DB_filters_.lib")
+# if defined(HasJBIG)
+# pragma comment(lib, "CORE_DB_jbig_.lib")
+# endif
+# if defined(HasJP2)
+# pragma comment(lib, "CORE_DB_jp2_.lib")
+# endif
+# if defined(HasJPEG)
+# pragma comment(lib, "CORE_DB_jpeg_.lib")
+# endif
+# if defined(HasLCMS)
+# pragma comment(lib, "CORE_DB_lcms_.lib")
+# endif
+# if defined(HasXML)
+# pragma comment(lib, "CORE_DB_libxml_.lib")
+# endif
+# pragma comment(lib, "CORE_DB_magick_.lib")
+# pragma comment(lib, "CORE_DB_Magick++_.lib")
+# if defined(HasPNG)
+# pragma comment(lib, "CORE_DB_png_.lib")
+# endif
+# if defined(HasTIFF)
+# pragma comment(lib, "CORE_DB_tiff_.lib")
+# endif
+# if defined(HasTTF)
+# pragma comment(lib, "CORE_DB_ttf_.lib")
+# endif
+# pragma comment(lib, "CORE_DB_wand_.lib")
+# if defined(HasWEBP)
+# pragma comment(lib, "CORE_DB_webp_.lib")
+# endif
+# if defined(HasWMFlite)
+# pragma comment(lib, "CORE_DB_wmf_.lib")
+# endif
+# if defined(HasX11)
+# pragma comment(lib, "CORE_DB_xlib_.lib")
+# endif
+# if defined(HasZLIB)
+# pragma comment(lib, "CORE_DB_zlib_.lib")
+# endif
+# else
+# if defined(HasBZLIB)
+# pragma comment(lib, "CORE_RL_bzlib_.lib")
+# endif
+# pragma comment(lib, "CORE_RL_coders_.lib")
+# pragma comment(lib, "CORE_RL_filters_.lib")
+# if defined(HasJBIG)
+# pragma comment(lib, "CORE_RL_jbig_.lib")
+# endif
+# if defined(HasJP2)
+# pragma comment(lib, "CORE_RL_jp2_.lib")
+# endif
+# if defined(HasJPEG)
+# pragma comment(lib, "CORE_RL_jpeg_.lib")
+# endif
+# if defined(HasLCMS)
+# pragma comment(lib, "CORE_RL_lcms_.lib")
+# endif
+# if defined(HasXML)
+# pragma comment(lib, "CORE_RL_libxml_.lib")
+# endif
+# pragma comment(lib, "CORE_RL_magick_.lib")
+# pragma comment(lib, "CORE_RL_Magick++_.lib")
+# if defined(HasPNG)
+# pragma comment(lib, "CORE_RL_png_.lib")
+# endif
+# if defined(HasTIFF)
+# pragma comment(lib, "CORE_RL_tiff_.lib")
+# endif
+# if defined(HasTTF)
+# pragma comment(lib, "CORE_RL_ttf_.lib")
+# endif
+# pragma comment(lib, "CORE_RL_wand_.lib")
+# if defined(HasWEBP)
+# pragma comment(lib, "CORE_RL_webp_.lib")
+# endif
+# if defined(HasWMFlite)
+# pragma comment(lib, "CORE_RL_wmf_.lib")
+# endif
+# if defined(HasX11)
+# pragma comment(lib, "CORE_RL_xlib_.lib")
+# endif
+# if defined(HasZLIB)
+# pragma comment(lib, "CORE_RL_zlib_.lib")
+# endif
+# endif
+# if defined(_WIN32_WCE)
+# pragma comment(lib, "wsock32.lib")
+# else
+# pragma comment(lib, "ws2_32.lib")
+# endif
+# endif
+# endif
+#else
+# define MagickDLLDecl
+# define MagickDLLDeclExtern
+#endif
+
+#if (defined(WIN32) || defined(WIN64)) && defined(_VISUALC_)
+# pragma warning(disable : 4996) /* function deprecation warnings */
+#endif
+
+#if defined(MAGICK_IMPLEMENTATION)
+namespace MagickLib
+{
+# include "magick/enum_strings.h"
+}
+#endif
+
+//
+// Import GraphicsMagick symbols and types which are used as part of the
+// Magick++ API definition into namespace "Magick".
+//
+namespace Magick
+{
+ // The datatype for an RGB component
+ using MagickLib::Quantum;
+
+ // Image class types
+ using MagickLib::ClassType;
+ using MagickLib::UndefinedClass;
+ using MagickLib::DirectClass;
+ using MagickLib::PseudoClass;
+
+ // Channel types
+ using MagickLib::ChannelType;
+ using MagickLib::UndefinedChannel;
+ using MagickLib::RedChannel;
+ using MagickLib::CyanChannel;
+ using MagickLib::GreenChannel;
+ using MagickLib::MagentaChannel;
+ using MagickLib::BlueChannel;
+ using MagickLib::YellowChannel;
+ using MagickLib::OpacityChannel;
+ using MagickLib::BlackChannel;
+ using MagickLib::MatteChannel;
+ using MagickLib::AllChannels;
+ using MagickLib::GrayChannel;
+
+ // Color-space types
+ using MagickLib::ColorspaceType;
+ using MagickLib::UndefinedColorspace;
+ using MagickLib::RGBColorspace;
+ using MagickLib::GRAYColorspace;
+ using MagickLib::TransparentColorspace;
+ using MagickLib::OHTAColorspace;
+ using MagickLib::XYZColorspace;
+ using MagickLib::YCbCrColorspace;
+ using MagickLib::YCCColorspace;
+ using MagickLib::YIQColorspace;
+ using MagickLib::YPbPrColorspace;
+ using MagickLib::YUVColorspace;
+ using MagickLib::CMYKColorspace;
+ using MagickLib::sRGBColorspace;
+ using MagickLib::HSLColorspace;
+ using MagickLib::HWBColorspace;
+ using MagickLib::LABColorspace;
+ using MagickLib::CineonLogRGBColorspace;
+ using MagickLib::Rec601LumaColorspace;
+ using MagickLib::Rec709LumaColorspace;
+ using MagickLib::Rec709YCbCrColorspace;
+
+ // Composition operations
+ using MagickLib::AddCompositeOp;
+ using MagickLib::AtopCompositeOp;
+ using MagickLib::BumpmapCompositeOp;
+ using MagickLib::ClearCompositeOp;
+ using MagickLib::ColorizeCompositeOp;
+ using MagickLib::CompositeOperator;
+ using MagickLib::CopyBlueCompositeOp;
+ using MagickLib::CopyCompositeOp;
+ using MagickLib::CopyGreenCompositeOp;
+ using MagickLib::CopyOpacityCompositeOp;
+ using MagickLib::CopyRedCompositeOp;
+ using MagickLib::DarkenCompositeOp;
+ using MagickLib::DifferenceCompositeOp;
+ using MagickLib::DisplaceCompositeOp;
+ using MagickLib::DissolveCompositeOp;
+ using MagickLib::HueCompositeOp;
+ using MagickLib::InCompositeOp;
+ using MagickLib::LightenCompositeOp;
+ using MagickLib::LuminizeCompositeOp;
+ using MagickLib::MinusCompositeOp;
+ using MagickLib::ModulateCompositeOp;
+ using MagickLib::MultiplyCompositeOp;
+ using MagickLib::NoCompositeOp;
+ using MagickLib::OutCompositeOp;
+ using MagickLib::OverCompositeOp;
+ using MagickLib::OverlayCompositeOp;
+ using MagickLib::PlusCompositeOp;
+ using MagickLib::SaturateCompositeOp;
+ using MagickLib::ScreenCompositeOp;
+ using MagickLib::SubtractCompositeOp;
+ using MagickLib::ThresholdCompositeOp;
+ using MagickLib::UndefinedCompositeOp;
+ using MagickLib::XorCompositeOp;
+ using MagickLib::CopyCyanCompositeOp;
+ using MagickLib::CopyMagentaCompositeOp;
+ using MagickLib::CopyYellowCompositeOp;
+ using MagickLib::CopyBlackCompositeOp;
+ using MagickLib::DivideCompositeOp;
+ using MagickLib::HardLightCompositeOp;
+ using MagickLib::ExclusionCompositeOp;
+ using MagickLib::ColorDodgeCompositeOp;
+ using MagickLib::ColorBurnCompositeOp;
+ using MagickLib::SoftLightCompositeOp;
+ using MagickLib::LinearBurnCompositeOp;
+ using MagickLib::LinearDodgeCompositeOp;
+ using MagickLib::LinearLightCompositeOp;
+ using MagickLib::VividLightCompositeOp;
+ using MagickLib::PinLightCompositeOp;
+ using MagickLib::HardMixCompositeOp;
+
+ // Compression algorithms
+ using MagickLib::CompressionType;
+ using MagickLib::UndefinedCompression;
+ using MagickLib::NoCompression;
+ using MagickLib::BZipCompression;
+ using MagickLib::FaxCompression;
+ using MagickLib::Group3Compression;
+ using MagickLib::Group4Compression;
+ using MagickLib::JPEGCompression;
+ using MagickLib::LZWCompression;
+ using MagickLib::RLECompression;
+ using MagickLib::ZipCompression;
+ using MagickLib::LZMACompression;
+ using MagickLib::JPEG2000Compression;
+ using MagickLib::JBIG1Compression;
+ using MagickLib::JBIG2Compression;
+
+ using MagickLib::DisposeType;
+ using MagickLib::UndefinedDispose;
+ using MagickLib::NoneDispose;
+ using MagickLib::BackgroundDispose;
+ using MagickLib::PreviousDispose;
+
+ // Endian options
+ using MagickLib::EndianType;
+ using MagickLib::UndefinedEndian;
+ using MagickLib::LSBEndian;
+ using MagickLib::MSBEndian;
+ using MagickLib::NativeEndian;
+
+ // Exception types
+ using MagickLib::ExceptionType;
+ using MagickLib::UndefinedException;
+ using MagickLib::EventException;
+ using MagickLib::ExceptionEvent;
+ using MagickLib::ResourceEvent;
+ using MagickLib::ResourceLimitEvent;
+ using MagickLib::TypeEvent;
+ using MagickLib::AnnotateEvent;
+ using MagickLib::OptionEvent;
+ using MagickLib::DelegateEvent;
+ using MagickLib::MissingDelegateEvent;
+ using MagickLib::CorruptImageEvent;
+ using MagickLib::FileOpenEvent;
+ using MagickLib::BlobEvent;
+ using MagickLib::StreamEvent;
+ using MagickLib::CacheEvent;
+ using MagickLib::CoderEvent;
+ using MagickLib::ModuleEvent;
+ using MagickLib::DrawEvent;
+ using MagickLib::RenderEvent;
+ using MagickLib::ImageEvent;
+ using MagickLib::WandEvent;
+ using MagickLib::TemporaryFileEvent;
+ using MagickLib::TransformEvent;
+ using MagickLib::XServerEvent;
+ using MagickLib::X11Event;
+ using MagickLib::UserEvent;
+ using MagickLib::MonitorEvent;
+ using MagickLib::LocaleEvent;
+ using MagickLib::DeprecateEvent;
+ using MagickLib::RegistryEvent;
+ using MagickLib::ConfigureEvent;
+ using MagickLib::WarningException;
+ using MagickLib::ExceptionWarning;
+ using MagickLib::ResourceWarning;
+ using MagickLib::ResourceLimitWarning;
+ using MagickLib::TypeWarning;
+ using MagickLib::AnnotateWarning;
+ using MagickLib::OptionWarning;
+ using MagickLib::DelegateWarning;
+ using MagickLib::MissingDelegateWarning;
+ using MagickLib::CorruptImageWarning;
+ using MagickLib::FileOpenWarning;
+ using MagickLib::BlobWarning;
+ using MagickLib::StreamWarning;
+ using MagickLib::CacheWarning;
+ using MagickLib::CoderWarning;
+ using MagickLib::ModuleWarning;
+ using MagickLib::DrawWarning;
+ using MagickLib::RenderWarning;
+ using MagickLib::ImageWarning;
+ using MagickLib::WandWarning;
+ using MagickLib::TemporaryFileWarning;
+ using MagickLib::TransformWarning;
+ using MagickLib::XServerWarning;
+ using MagickLib::X11Warning;
+ using MagickLib::UserWarning;
+ using MagickLib::MonitorWarning;
+ using MagickLib::LocaleWarning;
+ using MagickLib::DeprecateWarning;
+ using MagickLib::RegistryWarning;
+ using MagickLib::ConfigureWarning;
+ using MagickLib::ErrorException;
+ using MagickLib::ExceptionError;
+ using MagickLib::ResourceError;
+ using MagickLib::ResourceLimitError;
+ using MagickLib::TypeError;
+ using MagickLib::AnnotateError;
+ using MagickLib::OptionError;
+ using MagickLib::DelegateError;
+ using MagickLib::MissingDelegateError;
+ using MagickLib::CorruptImageError;
+ using MagickLib::FileOpenError;
+ using MagickLib::BlobError;
+ using MagickLib::StreamError;
+ using MagickLib::CacheError;
+ using MagickLib::CoderError;
+ using MagickLib::ModuleError;
+ using MagickLib::DrawError;
+ using MagickLib::RenderError;
+ using MagickLib::ImageError;
+ using MagickLib::WandError;
+ using MagickLib::TemporaryFileError;
+ using MagickLib::TransformError;
+ using MagickLib::XServerError;
+ using MagickLib::X11Error;
+ using MagickLib::UserError;
+ using MagickLib::MonitorError;
+ using MagickLib::LocaleError;
+ using MagickLib::DeprecateError;
+ using MagickLib::RegistryError;
+ using MagickLib::ConfigureError;
+ using MagickLib::FatalErrorException;
+ using MagickLib::ExceptionFatalError;
+ using MagickLib::ResourceFatalError;
+ using MagickLib::ResourceLimitFatalError;
+ using MagickLib::TypeFatalError;
+ using MagickLib::AnnotateFatalError;
+ using MagickLib::OptionFatalError;
+ using MagickLib::DelegateFatalError;
+ using MagickLib::MissingDelegateFatalError;
+ using MagickLib::CorruptImageFatalError;
+ using MagickLib::FileOpenFatalError;
+ using MagickLib::BlobFatalError;
+ using MagickLib::StreamFatalError;
+ using MagickLib::CacheFatalError;
+ using MagickLib::CoderFatalError;
+ using MagickLib::ModuleFatalError;
+ using MagickLib::DrawFatalError;
+ using MagickLib::RenderFatalError;
+ using MagickLib::ImageFatalError;
+ using MagickLib::WandFatalError;
+ using MagickLib::TemporaryFileFatalError;
+ using MagickLib::TransformFatalError;
+ using MagickLib::XServerFatalError;
+ using MagickLib::X11FatalError;
+ using MagickLib::UserFatalError;
+ using MagickLib::MonitorFatalError;
+ using MagickLib::LocaleFatalError;
+ using MagickLib::DeprecateFatalError;
+ using MagickLib::RegistryFatalError;
+ using MagickLib::ConfigureFatalError;
+
+ // Fill rules
+ using MagickLib::FillRule;
+ using MagickLib::UndefinedRule;
+ using MagickLib::EvenOddRule;
+ using MagickLib::NonZeroRule;
+
+ // Filter types
+ using MagickLib::FilterTypes;
+ using MagickLib::UndefinedFilter;
+ using MagickLib::PointFilter;
+ using MagickLib::BoxFilter;
+ using MagickLib::TriangleFilter;
+ using MagickLib::HermiteFilter;
+ using MagickLib::HanningFilter;
+ using MagickLib::HammingFilter;
+ using MagickLib::BlackmanFilter;
+ using MagickLib::GaussianFilter;
+ using MagickLib::QuadraticFilter;
+ using MagickLib::CubicFilter;
+ using MagickLib::CatromFilter;
+ using MagickLib::MitchellFilter;
+ using MagickLib::LanczosFilter;
+ using MagickLib::BesselFilter;
+ using MagickLib::SincFilter;
+
+ // Bit gravity
+ using MagickLib::GravityType;
+ using MagickLib::ForgetGravity;
+ using MagickLib::NorthWestGravity;
+ using MagickLib::NorthGravity;
+ using MagickLib::NorthEastGravity;
+ using MagickLib::WestGravity;
+ using MagickLib::CenterGravity;
+ using MagickLib::EastGravity;
+ using MagickLib::SouthWestGravity;
+ using MagickLib::SouthGravity;
+ using MagickLib::SouthEastGravity;
+ using MagickLib::StaticGravity;
+
+ // Image types
+ using MagickLib::ImageType;
+ using MagickLib::UndefinedType;
+ using MagickLib::BilevelType;
+ using MagickLib::GrayscaleType;
+ using MagickLib::GrayscaleMatteType;
+ using MagickLib::PaletteType;
+ using MagickLib::PaletteMatteType;
+ using MagickLib::TrueColorType;
+ using MagickLib::TrueColorMatteType;
+ using MagickLib::ColorSeparationType;
+ using MagickLib::ColorSeparationMatteType;
+ using MagickLib::OptimizeType;
+
+ // Interlace types
+ using MagickLib::InterlaceType;
+ using MagickLib::UndefinedInterlace;
+ using MagickLib::NoInterlace;
+ using MagickLib::LineInterlace;
+ using MagickLib::PlaneInterlace;
+ using MagickLib::PartitionInterlace;
+
+ // Line cap types
+ using MagickLib::LineCap;
+ using MagickLib::UndefinedCap;
+ using MagickLib::ButtCap;
+ using MagickLib::RoundCap;
+ using MagickLib::SquareCap;
+
+ // Line join types
+ using MagickLib::LineJoin;
+ using MagickLib::UndefinedJoin;
+ using MagickLib::MiterJoin;
+ using MagickLib::RoundJoin;
+ using MagickLib::BevelJoin;
+
+ // Noise types
+ using MagickLib::NoiseType;
+ using MagickLib::UniformNoise;
+ using MagickLib::GaussianNoise;
+ using MagickLib::MultiplicativeGaussianNoise;
+ using MagickLib::ImpulseNoise;
+ using MagickLib::LaplacianNoise;
+ using MagickLib::PoissonNoise;
+ using MagickLib::RandomNoise;
+
+ // Orientation types
+ using MagickLib::OrientationType;
+ using MagickLib::UndefinedOrientation;
+ using MagickLib::TopLeftOrientation;
+ using MagickLib::TopRightOrientation;
+ using MagickLib::BottomRightOrientation;
+ using MagickLib::BottomLeftOrientation;
+ using MagickLib::LeftTopOrientation;
+ using MagickLib::RightTopOrientation;
+ using MagickLib::RightBottomOrientation;
+ using MagickLib::LeftBottomOrientation;
+
+ // Paint methods
+ using MagickLib::PaintMethod;
+ using MagickLib::PointMethod;
+ using MagickLib::ReplaceMethod;
+ using MagickLib::FloodfillMethod;
+ using MagickLib::FillToBorderMethod;
+ using MagickLib::ResetMethod;
+
+ // Arithmetic and bitwise operators
+ using MagickLib::UndefinedQuantumOp;
+ using MagickLib::AddQuantumOp;
+ using MagickLib::AndQuantumOp;
+ using MagickLib::AssignQuantumOp;
+ using MagickLib::DivideQuantumOp;
+ using MagickLib::LShiftQuantumOp;
+ using MagickLib::MultiplyQuantumOp;
+ using MagickLib::OrQuantumOp;
+ using MagickLib::RShiftQuantumOp;
+ using MagickLib::SubtractQuantumOp;
+ using MagickLib::ThresholdQuantumOp;
+ using MagickLib::ThresholdBlackQuantumOp;
+ using MagickLib::ThresholdWhiteQuantumOp;
+ using MagickLib::ThresholdBlackNegateQuantumOp;
+ using MagickLib::ThresholdWhiteNegateQuantumOp;
+ using MagickLib::XorQuantumOp;
+ using MagickLib::NoiseGaussianQuantumOp;
+ using MagickLib::NoiseImpulseQuantumOp;
+ using MagickLib::NoiseLaplacianQuantumOp;
+ using MagickLib::NoiseMultiplicativeQuantumOp;
+ using MagickLib::NoisePoissonQuantumOp;
+ using MagickLib::NoiseUniformQuantumOp;
+ using MagickLib::NegateQuantumOp;
+ using MagickLib::GammaQuantumOp;
+ using MagickLib::DepthQuantumOp;
+ using MagickLib::LogQuantumOp;
+ using MagickLib::MaxQuantumOp;
+ using MagickLib::MinQuantumOp;
+ using MagickLib::PowQuantumOp;
+ using MagickLib::QuantumOperator;
+
+ // Preview types. Not currently used by Magick++
+ using MagickLib::PreviewType;
+ using MagickLib::UndefinedPreview;
+ using MagickLib::RotatePreview;
+ using MagickLib::ShearPreview;
+ using MagickLib::RollPreview;
+ using MagickLib::HuePreview;
+ using MagickLib::SaturationPreview;
+ using MagickLib::BrightnessPreview;
+ using MagickLib::GammaPreview;
+ using MagickLib::SpiffPreview;
+ using MagickLib::DullPreview;
+ using MagickLib::GrayscalePreview;
+ using MagickLib::QuantizePreview;
+ using MagickLib::DespecklePreview;
+ using MagickLib::ReduceNoisePreview;
+ using MagickLib::AddNoisePreview;
+ using MagickLib::SharpenPreview;
+ using MagickLib::BlurPreview;
+ using MagickLib::ThresholdPreview;
+ using MagickLib::EdgeDetectPreview;
+ using MagickLib::SpreadPreview;
+ using MagickLib::SolarizePreview;
+ using MagickLib::ShadePreview;
+ using MagickLib::RaisePreview;
+ using MagickLib::SegmentPreview;
+ using MagickLib::SwirlPreview;
+ using MagickLib::ImplodePreview;
+ using MagickLib::WavePreview;
+ using MagickLib::OilPaintPreview;
+ using MagickLib::CharcoalDrawingPreview;
+ using MagickLib::JPEGPreview;
+
+ // Quantum types
+ using MagickLib::QuantumType;
+ using MagickLib::IndexQuantum;
+ using MagickLib::GrayQuantum;
+ using MagickLib::IndexAlphaQuantum;
+ using MagickLib::GrayAlphaQuantum;
+ using MagickLib::RedQuantum;
+ using MagickLib::CyanQuantum;
+ using MagickLib::GreenQuantum;
+ using MagickLib::YellowQuantum;
+ using MagickLib::BlueQuantum;
+ using MagickLib::MagentaQuantum;
+ using MagickLib::AlphaQuantum;
+ using MagickLib::BlackQuantum;
+ using MagickLib::RGBQuantum;
+ using MagickLib::RGBAQuantum;
+ using MagickLib::CMYKQuantum;
+ using MagickLib::CIEYQuantum;
+ using MagickLib::CIEXYZQuantum;
+
+ // Quantum sample types
+ using MagickLib::QuantumSampleType;
+ using MagickLib::UndefinedQuantumSampleType;
+ using MagickLib::UnsignedQuantumSampleType;
+ using MagickLib::FloatQuantumSampleType;
+
+ // Rendering intents
+ using MagickLib::RenderingIntent;
+ using MagickLib::UndefinedIntent;
+ using MagickLib::SaturationIntent;
+ using MagickLib::PerceptualIntent;
+ using MagickLib::AbsoluteIntent;
+ using MagickLib::RelativeIntent;
+
+ // Resolution units
+ using MagickLib::ResolutionType;
+ using MagickLib::UndefinedResolution;
+ using MagickLib::PixelsPerInchResolution;
+ using MagickLib::PixelsPerCentimeterResolution;
+
+ // PixelPacket structure
+ using MagickLib::PixelPacket;
+
+ // IndexPacket type
+ using MagickLib::IndexPacket;
+
+ // ImageStatistics type
+ using MagickLib::ImageStatistics;
+
+ // StorageType type
+ using MagickLib::StorageType;
+ using MagickLib::CharPixel;
+ using MagickLib::ShortPixel;
+ using MagickLib::IntegerPixel;
+ using MagickLib::LongPixel;
+ using MagickLib::FloatPixel;
+ using MagickLib::DoublePixel;
+
+ // StretchType type
+ using MagickLib::StretchType;
+ using MagickLib::NormalStretch;
+ using MagickLib::UltraCondensedStretch;
+ using MagickLib::ExtraCondensedStretch;
+ using MagickLib::CondensedStretch;
+ using MagickLib::SemiCondensedStretch;
+ using MagickLib::SemiExpandedStretch;
+ using MagickLib::ExpandedStretch;
+ using MagickLib::ExtraExpandedStretch;
+ using MagickLib::UltraExpandedStretch;
+ using MagickLib::AnyStretch;
+
+ // StyleType type
+ using MagickLib::StyleType;
+ using MagickLib::NormalStyle;
+ using MagickLib::ItalicStyle;
+ using MagickLib::ObliqueStyle;
+ using MagickLib::AnyStyle;
+
+ // Decoration types
+ using MagickLib::DecorationType;
+ using MagickLib::NoDecoration;
+ using MagickLib::UnderlineDecoration;
+ using MagickLib::OverlineDecoration;
+ using MagickLib::LineThroughDecoration;
+
+ // Resource types
+ using MagickLib::ResourceType;
+ using MagickLib::DiskResource;
+ using MagickLib::FileResource;
+ using MagickLib::MapResource;
+ using MagickLib::MemoryResource;
+ using MagickLib::PixelsResource;
+ using MagickLib::ThreadsResource;
+ using MagickLib::WidthResource;
+ using MagickLib::HeightResource;
+
+ // Virtual pixel methods
+ using MagickLib::VirtualPixelMethod;
+ using MagickLib::UndefinedVirtualPixelMethod;
+ using MagickLib::ConstantVirtualPixelMethod;
+ using MagickLib::EdgeVirtualPixelMethod;
+ using MagickLib::MirrorVirtualPixelMethod;
+ using MagickLib::TileVirtualPixelMethod;
+
+#if defined(MAGICK_IMPLEMENTATION)
+ //
+ // GraphicsMagick symbols used in implementation code
+ //
+ using MagickLib::AccessDefinition;
+ using MagickLib::AccessImmutableIndexes;
+ using MagickLib::AccessMutableIndexes;
+ using MagickLib::AcquireCacheViewPixels;
+ using MagickLib::AcquireImagePixels;
+ using MagickLib::AdaptiveThresholdImage;
+ using MagickLib::AddDefinition;
+ using MagickLib::AddDefinitions;
+ using MagickLib::AddNoiseImage;
+ using MagickLib::AddNoiseImageChannel;
+ using MagickLib::AffineMatrix;
+ using MagickLib::AffineTransformImage;
+ using MagickLib::AllocateImage;
+ using MagickLib::AnnotateImage;
+ using MagickLib::AreaValue;
+ using MagickLib::AspectValue;
+ using MagickLib::Base64Decode;
+ using MagickLib::Base64Encode;
+ using MagickLib::BlobError;
+ using MagickLib::BlobFatalError;
+ using MagickLib::BlobToImage;
+ using MagickLib::BlobWarning;
+ using MagickLib::BlurImage;
+ using MagickLib::BlurImageChannel;
+ using MagickLib::BorderImage;
+ using MagickLib::CacheError;
+ using MagickLib::CacheFatalError;
+ using MagickLib::CacheWarning;
+ using MagickLib::CdlImage;
+ using MagickLib::ChannelImage;
+ using MagickLib::CharcoalImage;
+ using MagickLib::ChopImage;
+ using MagickLib::CloneDrawInfo;
+ using MagickLib::CloneImage;
+ using MagickLib::CloneImageInfo;
+ using MagickLib::CloneQuantizeInfo;
+ using MagickLib::CloseCacheView;
+ using MagickLib::CoderError;
+ using MagickLib::CoderFatalError;
+ using MagickLib::CoderWarning;
+ using MagickLib::ColorFloodfillImage;
+ using MagickLib::ColorizeImage;
+ using MagickLib::ColorMatrixImage;
+ using MagickLib::CompositeImage;
+ using MagickLib::ConfigureError;
+ using MagickLib::ConfigureFatalError;
+ using MagickLib::ConfigureWarning;
+ using MagickLib::ConstituteImage;
+ using MagickLib::ContrastImage;
+ using MagickLib::ConvolveImage;
+ using MagickLib::CopyException;
+ using MagickLib::CorruptImageError;
+ using MagickLib::CorruptImageFatalError;
+ using MagickLib::CorruptImageWarning;
+ using MagickLib::CropImage;
+ using MagickLib::CycleColormapImage;
+ using MagickLib::DelegateError;
+ using MagickLib::DelegateFatalError;
+ using MagickLib::DelegateWarning;
+ using MagickLib::DeleteMagickRegistry;
+ using MagickLib::DespeckleImage;
+ using MagickLib::DestroyDrawInfo;
+ using MagickLib::DestroyExceptionInfo;
+ using MagickLib::DestroyImageInfo;
+ using MagickLib::DestroyImageList;
+ using MagickLib::DestroyMagick;
+ using MagickLib::DestroyQuantizeInfo;
+ using MagickLib::DispatchImage;
+ using MagickLib::DisplayImages;
+ using MagickLib::DrawAffine;
+ using MagickLib::DrawAllocateContext;
+ using MagickLib::DrawAnnotation;
+ using MagickLib::DrawArc;
+ using MagickLib::DrawBezier;
+ using MagickLib::DrawCircle;
+ using MagickLib::DrawColor;
+ using MagickLib::DrawComment;
+ using MagickLib::DrawComposite;
+ using MagickLib::DrawContext;
+ using MagickLib::DrawDestroyContext;
+ using MagickLib::DrawEllipse;
+ using MagickLib::DrawError;
+ using MagickLib::DrawFatalError;
+ using MagickLib::DrawImage;
+ using MagickLib::DrawInfo;
+ using MagickLib::DrawLine;
+ using MagickLib::DrawMatte;
+ using MagickLib::DrawPathClose;
+ using MagickLib::DrawPathCurveToAbsolute;
+ using MagickLib::DrawPathCurveToQuadraticBezierAbsolute;
+ using MagickLib::DrawPathCurveToQuadraticBezierRelative;
+ using MagickLib::DrawPathCurveToQuadraticBezierSmoothAbsolute;
+ using MagickLib::DrawPathCurveToQuadraticBezierSmoothRelative;
+ using MagickLib::DrawPathCurveToRelative;
+ using MagickLib::DrawPathCurveToSmoothAbsolute;
+ using MagickLib::DrawPathCurveToSmoothRelative;
+ using MagickLib::DrawPathEllipticArcAbsolute;
+ using MagickLib::DrawPathEllipticArcRelative;
+ using MagickLib::DrawPathFinish;
+ using MagickLib::DrawPathLineToAbsolute;
+ using MagickLib::DrawPathLineToHorizontalAbsolute;
+ using MagickLib::DrawPathLineToHorizontalRelative;
+ using MagickLib::DrawPathLineToRelative;
+ using MagickLib::DrawPathLineToVerticalAbsolute;
+ using MagickLib::DrawPathLineToVerticalRelative;
+ using MagickLib::DrawPathMoveToAbsolute;
+ using MagickLib::DrawPathMoveToRelative;
+ using MagickLib::DrawPathStart;
+ using MagickLib::DrawPoint;
+ using MagickLib::DrawPolygon;
+ using MagickLib::DrawPolyline;
+ using MagickLib::DrawPopClipPath;
+ using MagickLib::DrawPopDefs;
+ using MagickLib::DrawPopGraphicContext;
+ using MagickLib::DrawPopPattern;
+ using MagickLib::DrawPushClipPath;
+ using MagickLib::DrawPushDefs;
+ using MagickLib::DrawPushGraphicContext;
+ using MagickLib::DrawPushPattern;
+ using MagickLib::DrawRectangle;
+ using MagickLib::DrawRender;
+ using MagickLib::DrawRotate;
+ using MagickLib::DrawRoundRectangle;
+ using MagickLib::DrawScale;
+ using MagickLib::DrawSetClipPath;
+ using MagickLib::DrawSetClipRule;
+ using MagickLib::DrawSetClipUnits;
+ using MagickLib::DrawSetFillColor;
+ using MagickLib::DrawSetFillColorString;
+ using MagickLib::DrawSetFillOpacity;
+ using MagickLib::DrawSetFillPatternURL;
+ using MagickLib::DrawSetFillRule;
+ using MagickLib::DrawSetFont;
+ using MagickLib::DrawSetFontFamily;
+ using MagickLib::DrawSetFontSize;
+ using MagickLib::DrawSetFontStretch;
+ using MagickLib::DrawSetFontStyle;
+ using MagickLib::DrawSetFontWeight;
+ using MagickLib::DrawSetGravity;
+ using MagickLib::DrawSetStrokeAntialias;
+ using MagickLib::DrawSetStrokeColor;
+ using MagickLib::DrawSetStrokeColorString;
+ using MagickLib::DrawSetStrokeDashArray;
+ using MagickLib::DrawSetStrokeDashOffset;
+ using MagickLib::DrawSetStrokeLineCap;
+ using MagickLib::DrawSetStrokeLineJoin;
+ using MagickLib::DrawSetStrokeMiterLimit;
+ using MagickLib::DrawSetStrokeOpacity;
+ using MagickLib::DrawSetStrokePatternURL;
+ using MagickLib::DrawSetStrokeWidth;
+ using MagickLib::DrawSetTextAntialias;
+ using MagickLib::DrawSetTextDecoration;
+ using MagickLib::DrawSetTextEncoding;
+ using MagickLib::DrawSetTextUnderColor;
+ using MagickLib::DrawSetTextUnderColorString;
+ using MagickLib::DrawSetViewbox;
+ using MagickLib::DrawSkewX;
+ using MagickLib::DrawSkewY;
+ using MagickLib::DrawTranslate;
+ using MagickLib::DrawWarning;
+ using MagickLib::EdgeImage;
+ using MagickLib::EmbossImage;
+ using MagickLib::EnhanceImage;
+ using MagickLib::EqualizeImage;
+ using MagickLib::ExceptionInfo;
+ using MagickLib::ExecuteModuleProcess;
+ using MagickLib::ExportImagePixelArea;
+ using MagickLib::ExtentImage;
+ using MagickLib::FileOpenError;
+ using MagickLib::FileOpenFatalError;
+ using MagickLib::FileOpenWarning;
+ using MagickLib::FlattenImages;
+ using MagickLib::FlipImage;
+ using MagickLib::FlopImage;
+ using MagickLib::FormatString;
+ using MagickLib::FrameImage;
+ using MagickLib::FrameInfo;
+ using MagickLib::GammaImage;
+ using MagickLib::GammaImage;
+ using MagickLib::GaussianBlurImage;
+ using MagickLib::GaussianBlurImageChannel;
+ using MagickLib::GetBlobSize;
+ using MagickLib::GetCacheViewIndexes;
+ using MagickLib::GetCacheViewPixels;
+ using MagickLib::GetColorTuple;
+ using MagickLib::GetDrawInfo;
+ using MagickLib::GetExceptionInfo;
+ using MagickLib::GetGeometry;
+ using MagickLib::GetImageAttribute;
+ using MagickLib::GetImageBoundingBox;
+ using MagickLib::GetImageChannelDepth;
+ using MagickLib::GetImageClipMask;
+ using MagickLib::GetImageDepth;
+ using MagickLib::GetImageGeometry;
+ using MagickLib::GetImageInfo;
+ using MagickLib::GetImagePixels;
+ using MagickLib::GetImageProfile;
+ using MagickLib::GetImageQuantizeError;
+ using MagickLib::GetImageStatistics;
+ using MagickLib::GetImageType;
+ using MagickLib::GetMagickGeometry;
+ using MagickLib::GetMagickInfo;
+ using MagickLib::GetMagickInfoArray;
+ using MagickLib::GetMagickRegistry;
+ using MagickLib::GetNumberColors;
+ using MagickLib::GetPageGeometry;
+ using MagickLib::GetQuantizeInfo;
+ using MagickLib::GetTypeMetrics;
+ using MagickLib::GlobExpression;
+ using MagickLib::GreaterValue;
+ using MagickLib::HaldClutImage;
+ using MagickLib::HSLTransform;
+ using MagickLib::HeightValue;
+ using MagickLib::IdentityAffine;
+ using MagickLib::ImageAttribute;
+ using MagickLib::ImageError;
+ using MagickLib::ImageFatalError;
+ using MagickLib::ImageInfo;
+ using MagickLib::ImageInfoRegistryType;
+ using MagickLib::ImageRegistryType;
+ using MagickLib::ImageToBlob;
+ using MagickLib::ImageWarning;
+ using MagickLib::ImplodeImage;
+ using MagickLib::ImportImagePixelArea;
+ using MagickLib::IsEventLogging;
+ using MagickLib::IsGeometry;
+ using MagickLib::IsImagesEqual;
+ using MagickLib::IsSubimage;
+ using MagickLib::LessValue;
+ using MagickLib::LevelImage;
+ using MagickLib::LevelImageChannel;
+ using MagickLib::LocaleCompare;
+ using MagickLib::LogMagickEvent;
+ using MagickLib::MagickFree;
+ using MagickLib::MagickInfo;
+ using MagickLib::MagickMalloc;
+ using MagickLib::MagickRealloc;
+ using MagickLib::MagickStrlCpy;
+ using MagickLib::MagickToMime;
+ using MagickLib::MagnifyImage;
+ using MagickLib::MapImage;
+ using MagickLib::MatteFloodfillImage;
+ using MagickLib::MedianFilterImage;
+ using MagickLib::MinifyImage;
+ using MagickLib::MinimumValue;
+ using MagickLib::MissingDelegateError;
+ using MagickLib::MissingDelegateFatalError;
+ using MagickLib::MissingDelegateWarning;
+ using MagickLib::ModulateImage;
+ using MagickLib::ModuleError;
+ using MagickLib::ModuleFatalError;
+ using MagickLib::ModuleWarning;
+ using MagickLib::MonitorError;
+ using MagickLib::MonitorFatalError;
+ using MagickLib::MonitorWarning;
+ using MagickLib::MontageInfo;
+ using MagickLib::MotionBlurImage;
+ using MagickLib::NegateImage;
+ using MagickLib::NoValue;
+ using MagickLib::NoiseType;
+ using MagickLib::NormalizeImage;
+ using MagickLib::OilPaintImage;
+ using MagickLib::OpaqueImage;
+ using MagickLib::OpenCacheView;
+ using MagickLib::OptionError;
+ using MagickLib::OptionFatalError;
+ using MagickLib::OptionWarning;
+ using MagickLib::PercentValue;
+ using MagickLib::PingBlob;
+ using MagickLib::PingImage;
+ using MagickLib::PointInfo;
+ using MagickLib::PopImagePixels;
+ using MagickLib::ProfileImage;
+ using MagickLib::ProfileInfo;
+ using MagickLib::PushImagePixels;
+ using MagickLib::QuantizeImage;
+ using MagickLib::QuantizeInfo;
+ using MagickLib::QuantumOperatorImage;
+ using MagickLib::QuantumOperatorRegionImage;
+ using MagickLib::QueryColorDatabase;
+ using MagickLib::RGBTransformImage;
+ using MagickLib::RaiseImage;
+ using MagickLib::RandomChannelThresholdImage;
+ using MagickLib::ReadImage;
+ using MagickLib::RectangleInfo;
+ using MagickLib::RectangleInfo;
+ using MagickLib::ReduceNoiseImage;
+ using MagickLib::RegisterMagickInfo;
+ using MagickLib::RegistryError;
+ using MagickLib::RegistryFatalError;
+ using MagickLib::RegistryType;
+ using MagickLib::RegistryWarning;
+ using MagickLib::RemoveDefinitions;
+ using MagickLib::ResizeImage;
+ using MagickLib::ResourceLimitError;
+ using MagickLib::ResourceLimitFatalError;
+ using MagickLib::ResourceLimitWarning;
+ using MagickLib::RollImage;
+ using MagickLib::RotateImage;
+ using MagickLib::SampleImage;
+ using MagickLib::ScaleImage;
+ using MagickLib::SegmentImage;
+ using MagickLib::SetCacheViewPixels;
+ using MagickLib::SetClientName;
+ using MagickLib::SetImage;
+ using MagickLib::SetImageAttribute;
+ using MagickLib::SetImageChannelDepth;
+ using MagickLib::SetImageClipMask;
+ using MagickLib::SetImageDepth;
+ using MagickLib::SetImageInfo;
+ using MagickLib::SetImageOpacity;
+ using MagickLib::SetImagePixels;
+ using MagickLib::SetImageProfile;
+ using MagickLib::SetImageType;
+ using MagickLib::SetLogEventMask;
+ using MagickLib::SetMagickInfo;
+ using MagickLib::SetMagickRegistry;
+ using MagickLib::SetMagickResourceLimit;
+ using MagickLib::SetMagickResourceLimit;
+ using MagickLib::ShadeImage;
+ using MagickLib::SharpenImage;
+ using MagickLib::SharpenImageChannel;
+ using MagickLib::ShaveImage;
+ using MagickLib::ShearImage;
+ using MagickLib::SignatureImage;
+ using MagickLib::SolarizeImage;
+ using MagickLib::SpreadImage;
+ using MagickLib::SteganoImage;
+ using MagickLib::StereoImage;
+ using MagickLib::StreamError;
+ using MagickLib::StreamFatalError;
+ using MagickLib::StreamWarning;
+ using MagickLib::SwirlImage;
+ using MagickLib::SyncCacheViewPixels;
+ using MagickLib::SyncImage;
+ using MagickLib::SyncImagePixels;
+ using MagickLib::TextureImage;
+ using MagickLib::ThresholdImage;
+ using MagickLib::ThrowException;
+ using MagickLib::ThrowLoggedException;
+ using MagickLib::ThumbnailImage;
+ using MagickLib::TransformHSL;
+ using MagickLib::TransformImage;
+ using MagickLib::TransformRGBImage;
+ using MagickLib::TransparentImage;
+ using MagickLib::TypeError;
+ using MagickLib::TypeFatalError;
+ using MagickLib::TypeWarning;
+ using MagickLib::UndefinedException;
+ using MagickLib::UndefinedRegistryType;
+ using MagickLib::UnregisterMagickInfo;
+ using MagickLib::UnsharpMaskImage;
+ using MagickLib::UnsharpMaskImageChannel;
+ using MagickLib::ViewInfo;
+ using MagickLib::WaveImage;
+ using MagickLib::WidthValue;
+ using MagickLib::WriteImage;
+ using MagickLib::XNegative;
+ using MagickLib::XServerError;
+ using MagickLib::XServerFatalError;
+ using MagickLib::XServerWarning;
+ using MagickLib::XValue;
+ using MagickLib::YNegative;
+ using MagickLib::YValue;
+ using MagickLib::ZoomImage;
+
+
+#endif // MAGICK_IMPLEMENTATION
+
+}
+
+#endif // Magick_Include_header
diff --git a/Magick++/lib/Magick++/Montage.h b/Magick++/lib/Magick++/Montage.h
new file mode 100644
index 0000000..2d7dc0e
--- /dev/null
+++ b/Magick++/lib/Magick++/Montage.h
@@ -0,0 +1,386 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
+//
+// Definition of Montage class used to specify montage options.
+//
+
+#if !defined(Magick_Montage_header)
+#define Magick_Montage_header
+
+#include "Magick++/Include.h"
+#include <string>
+#include "Magick++/Color.h"
+#include "Magick++/Geometry.h"
+
+//
+// Basic (Un-framed) Montage
+//
+namespace Magick
+{
+ class MagickDLLDecl Montage
+ {
+ public:
+ Montage( void );
+ virtual ~Montage( void );
+
+ // Specifies the background color that thumbnails are imaged upon.
+ void backgroundColor ( const Color &backgroundColor_ );
+ Color backgroundColor ( void ) const;
+
+ // Specifies the image composition algorithm for thumbnails. This
+ // controls the algorithm by which the thumbnail image is placed
+ // on the background. Use of OverCompositeOp is recommended for
+ // use with images that have transparency. This option may have
+ // negative side-effects for images without transparency.
+ void compose ( CompositeOperator compose_ );
+ CompositeOperator compose ( void ) const;
+
+ // Specifies the image filename to be used for the generated
+ // montage images. To handle the case were multiple montage images
+ // are generated, a printf-style format may be embedded within the
+ // filename. For example, a filename specification of
+ // image%02d.miff names the montage images as image00.miff,
+ // image01.miff, etc.
+ void fileName( const std::string &fileName_ );
+ std::string fileName( void ) const;
+
+ // Specifies the fill color to use for the label text.
+ void fillColor ( const Color &fill_ );
+ Color fillColor ( void ) const;
+
+ // Specifies the thumbnail label font.
+ void font ( const std::string &font_ );
+ std::string font ( void ) const;
+
+ // Specifies the size of the generated thumbnail.
+ void geometry ( const Geometry &geometry_ );
+ Geometry geometry ( void ) const;
+
+ // Specifies the thumbnail positioning within the specified
+ // geometry area. If the thumbnail is smaller in any dimension
+ // than the geometry, then it is placed according to this
+ // specification
+ void gravity ( GravityType gravity_ );
+ GravityType gravity ( void ) const;
+
+ // Specifies the format used for the image label. Special format
+ // characters may be embedded in the format string to include
+ // information about the image.
+ void label( const std::string &label_ );
+ std::string label( void ) const;
+
+ // Specifies the pen color to use for the label text (same as fill).
+ void penColor ( const Color &pen_ );
+ Color penColor ( void ) const;
+
+ // Specifies the thumbnail label font size.
+ void pointSize ( unsigned int pointSize_ );
+ unsigned int pointSize ( void ) const;
+
+ // Enable/disable drop-shadow on thumbnails.
+ void shadow ( bool shadow_ );
+ bool shadow ( void ) const;
+
+ // Specifies the stroke color to use for the label text .
+ void strokeColor ( const Color &stroke_ );
+ Color strokeColor ( void ) const;
+
+ // Specifies a texture image to use as montage background. The
+ // built-in textures "granite:" and "plasma:" are available. A
+ // texture is the same as a background image.
+ void texture ( const std::string &texture_ );
+ std::string texture ( void ) const;
+
+ // Specifies the maximum number of montage columns and rows in the
+ // montage. The montage is built by filling out all cells in a row
+ // before advancing to the next row. Once the montage has reached
+ // the maximum number of columns and rows, a new montage image is
+ // started.
+ void tile ( const Geometry &tile_ );
+ Geometry tile ( void ) const;
+
+ // Specifies the montage title
+ void title ( const std::string &title_ );
+ std::string title ( void ) const;
+
+ // Specifies a montage color to set transparent. This option can
+ // be set the same as the background color in order for the
+ // thumbnails to appear without a background when rendered on an
+ // HTML page. For best effect, ensure that the transparent color
+ // selected does not occur in the rendered thumbnail colors.
+ void transparentColor ( const Color &transparentColor_ );
+ Color transparentColor ( void ) const;
+
+ //
+ // Implementation methods/members
+ //
+
+ // Update elements in existing MontageInfo structure
+ virtual void updateMontageInfo ( MagickLib::MontageInfo &montageInfo_ ) const;
+
+ protected:
+
+ private:
+ Color _backgroundColor; // Color that thumbnails are composed on
+ CompositeOperator _compose; // Composition algorithm to use (e.g. ReplaceCompositeOp)
+ std::string _fileName; // Filename to save montages to
+ Color _fill; // Fill color
+ std::string _font; // Label font
+ Geometry _geometry; // Thumbnail width & height plus border width & height
+ GravityType _gravity; // Thumbnail position (e.g. SouthWestGravity)
+ std::string _label; // Thumbnail label (applied to image prior to montage)
+ unsigned int _pointSize; // Font point size
+ bool _shadow; // Enable drop-shadows on thumbnails
+ Color _stroke; // Outline color
+ std::string _texture; // Background texture image
+ Geometry _tile; // Thumbnail rows and colmns
+ std::string _title; // Montage title
+ Color _transparentColor; // Transparent color
+ };
+
+ //
+ // Montage With Frames (Extends Basic Montage)
+ //
+ class MagickDLLDecl MontageFramed : public Montage
+ {
+ public:
+ MontageFramed ( void );
+ /* virtual */ ~MontageFramed ( void );
+
+ // Specifies the background color within the thumbnail frame.
+ void borderColor ( const Color &borderColor_ );
+ Color borderColor ( void ) const;
+
+ // Specifies the border (in pixels) to place between a thumbnail
+ // and its surrounding frame. This option only takes effect if
+ // thumbnail frames are enabled (via frameGeometry) and the
+ // thumbnail geometry specification doesn't also specify the
+ // thumbnail border width.
+ void borderWidth ( unsigned int borderWidth_ );
+ unsigned int borderWidth ( void ) const;
+
+ // Specifies the geometry specification for frame to place around
+ // thumbnail. If this parameter is not specified, then the montage
+ // is unframed.
+ void frameGeometry ( const Geometry &frame_ );
+ Geometry frameGeometry ( void ) const;
+
+ // Specifies the thumbnail frame color.
+ void matteColor ( const Color &matteColor_ );
+ Color matteColor ( void ) const;
+
+ //
+ // Implementation methods/members
+ //
+
+ // Update elements in existing MontageInfo structure
+ /* virtual */ void updateMontageInfo ( MagickLib::MontageInfo &montageInfo_ ) const;
+
+ protected:
+
+ private:
+
+ Color _borderColor; // Frame border color
+ unsigned int _borderWidth; // Pixels between thumbnail and surrounding frame
+ Geometry _frame; // Frame geometry (width & height frame thickness)
+ Color _matteColor; // Frame foreground color
+ };
+} // namespace Magick
+
+//
+// Inlines
+//
+
+//
+// Implementation of Montage
+//
+
+inline void Magick::Montage::backgroundColor ( const Magick::Color &backgroundColor_ )
+{
+ _backgroundColor = backgroundColor_;
+}
+inline Magick::Color Magick::Montage::backgroundColor ( void ) const
+{
+ return _backgroundColor;
+}
+
+inline void Magick::Montage::compose ( Magick::CompositeOperator compose_ )
+{
+ _compose = compose_;
+}
+inline Magick::CompositeOperator Magick::Montage::compose ( void ) const
+{
+ return _compose;
+}
+
+inline void Magick::Montage::fileName( const std::string &fileName_ )
+{
+ _fileName = fileName_;
+}
+inline std::string Magick::Montage::fileName( void ) const
+{
+ return _fileName;
+}
+
+inline void Magick::Montage::fillColor ( const Color &fill_ )
+{
+ _fill=fill_;
+}
+inline Magick::Color Magick::Montage::fillColor ( void ) const
+{
+ return _fill;
+}
+
+inline void Magick::Montage::font ( const std::string &font_ )
+{
+ _font = font_;
+}
+inline std::string Magick::Montage::font ( void ) const
+{
+ return _font;
+}
+
+inline void Magick::Montage::geometry ( const Magick::Geometry &geometry_ )
+{
+ _geometry = geometry_;
+}
+inline Magick::Geometry Magick::Montage::geometry ( void ) const
+{
+ return _geometry;
+}
+
+inline void Magick::Montage::gravity ( Magick::GravityType gravity_ )
+{
+ _gravity = gravity_;
+}
+inline Magick::GravityType Magick::Montage::gravity ( void ) const
+{
+ return _gravity;
+}
+
+// Apply as attribute to all images before doing montage
+inline void Magick::Montage::label( const std::string &label_ )
+{
+ _label = label_;
+}
+inline std::string Magick::Montage::label( void ) const
+{
+ return _label;
+}
+
+inline void Magick::Montage::penColor ( const Color &pen_ )
+{
+ _fill=pen_;
+ _stroke=Color("none");
+}
+inline Magick::Color Magick::Montage::penColor ( void ) const
+{
+ return _fill;
+}
+
+inline void Magick::Montage::pointSize ( unsigned int pointSize_ )
+{
+ _pointSize = pointSize_;
+}
+inline unsigned int Magick::Montage::pointSize ( void ) const
+{
+ return _pointSize;
+}
+
+inline void Magick::Montage::shadow ( bool shadow_ )
+{
+ _shadow = shadow_;
+}
+inline bool Magick::Montage::shadow ( void ) const
+{
+ return _shadow;
+}
+
+inline void Magick::Montage::strokeColor ( const Color &stroke_ )
+{
+ _stroke=stroke_;
+}
+inline Magick::Color Magick::Montage::strokeColor ( void ) const
+{
+ return _stroke;
+}
+
+inline void Magick::Montage::texture ( const std::string &texture_ )
+{
+ _texture = texture_;
+}
+inline std::string Magick::Montage::texture ( void ) const
+{
+ return _texture;
+}
+
+inline void Magick::Montage::tile ( const Geometry &tile_ )
+{
+ _tile = tile_;
+}
+inline Magick::Geometry Magick::Montage::tile ( void ) const
+{
+ return _tile;
+}
+
+inline void Magick::Montage::title ( const std::string &title_ )
+{
+ _title = title_;
+}
+inline std::string Magick::Montage::title ( void ) const
+{
+ return _title;
+}
+
+// Applied after the fact to montage with TransparentImage()
+inline void Magick::Montage::transparentColor ( const Magick::Color &transparentColor_ )
+{
+ _transparentColor = transparentColor_;
+}
+inline Magick::Color Magick::Montage::transparentColor ( void ) const
+{
+ return _transparentColor;
+}
+
+//
+// Implementation of MontageFramed
+//
+
+inline void Magick::MontageFramed::borderColor ( const Magick::Color &borderColor_ )
+{
+ _borderColor = borderColor_;
+}
+inline Magick::Color Magick::MontageFramed::borderColor ( void ) const
+{
+ return _borderColor;
+}
+
+inline void Magick::MontageFramed::borderWidth ( unsigned int borderWidth_ )
+{
+ _borderWidth = borderWidth_;
+}
+inline unsigned int Magick::MontageFramed::borderWidth ( void ) const
+{
+ return _borderWidth;
+}
+
+inline void Magick::MontageFramed::frameGeometry ( const Magick::Geometry &frame_ )
+{
+ _frame = frame_;
+}
+inline Magick::Geometry Magick::MontageFramed::frameGeometry ( void ) const
+{
+ return _frame;
+}
+
+inline void Magick::MontageFramed::matteColor ( const Magick::Color &matteColor_ )
+{
+ _matteColor = matteColor_;
+}
+inline Magick::Color Magick::MontageFramed::matteColor ( void ) const
+{
+ return _matteColor;
+}
+
+#endif // Magick_Montage_header
diff --git a/Magick++/lib/Magick++/Options.h b/Magick++/lib/Magick++/Options.h
new file mode 100644
index 0000000..4592db3
--- /dev/null
+++ b/Magick++/lib/Magick++/Options.h
@@ -0,0 +1,288 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
+//
+// Definition of Options
+//
+// Options which may be applied to an image. These options are the
+// equivalent of options supplied to ImageMagick utilities.
+//
+// This is an internal implementation class and is not part of the
+// Magick++ API
+//
+
+#if !defined(Magick_Options_header)
+#define Magick_Options_header
+
+#include "Magick++/Include.h"
+#include <string>
+#include "Magick++/Color.h"
+#include "Magick++/Geometry.h"
+#include "Magick++/Drawable.h"
+
+namespace Magick
+{
+ class /*MagickDLLDecl*/ Image;
+
+ class Options
+ {
+
+ public:
+ Options( void );
+ Options( const Options& options_ );
+ ~Options();
+
+ // Remove pixel aliasing
+ void antiAlias( bool flag_ );
+ bool antiAlias( void ) const;
+
+ // Join images into a single multi-image file
+ void adjoin ( bool flag_ );
+ bool adjoin ( void ) const;
+
+ // Image background color
+ void backgroundColor ( const Color &color_ );
+ Color backgroundColor ( void ) const;
+
+ // Name of texture image to tile onto the image background
+ void backgroundTexture ( const std::string &backgroundTexture_ );
+ std::string backgroundTexture ( void ) const;
+
+ // Image border color
+ void borderColor ( const Color &color_ );
+ Color borderColor ( void ) const;
+
+ // Text bounding-box base color (default none)
+ void boxColor ( const Color &boxColor_ );
+ Color boxColor ( void ) const;
+
+ // Colors within this distance are considered equal
+ void colorFuzz ( double fuzz_ );
+ double colorFuzz ( void ) const;
+
+ // Compression type ( NoCompression, BZipCompression,
+ // FaxCompression, JPEGCompression, LZWCompression,
+ // RLECompression, or ZipCompression )
+ void compressType ( CompressionType compressType_ );
+ CompressionType compressType ( void ) const;
+
+ // Enable printing of debug messages from ImageMagick
+ void debug ( bool flag_ );
+ bool debug ( void ) const;
+
+ // Vertical and horizontal resolution in pixels of the image
+ void density ( const Geometry &geomery_ );
+ Geometry density ( void ) const;
+
+ // Image depth (8 or 16)
+ void depth ( unsigned int depth_ );
+ unsigned int depth ( void ) const;
+
+ // Endianness (little like Intel or big like SPARC) for image
+ // formats which support endian-specific options.
+ void endian ( EndianType endian_ );
+ EndianType endian ( void ) const;
+
+ // Image filename to read or write
+ void fileName ( const std::string &fileName_ );
+ std::string fileName ( void ) const;
+
+ // Color to use when filling drawn objects
+ void fillColor ( const Color &fillColor_ );
+ Color fillColor ( void ) const;
+
+ // Fill pattern
+ void fillPattern ( const MagickLib::Image *fillPattern_ );
+ const MagickLib::Image* fillPattern ( void ) const;
+
+ // Rule to use when filling drawn objects
+ void fillRule ( const FillRule &fillRule_ );
+ FillRule fillRule ( void ) const;
+
+ // Font name
+ void font ( const std::string &font_ );
+ std::string font ( void ) const;
+
+ // Font point size
+ void fontPointsize ( double pointSize_ );
+ double fontPointsize ( void ) const;
+
+ std::string format ( void ) const;
+
+ // Image interlace scheme
+ void interlaceType ( InterlaceType interlace_ );
+ InterlaceType interlaceType ( void ) const;
+
+ // Image format to write or read
+ void magick ( const std::string &magick_ );
+ std::string magick ( void ) const;
+
+ // Transparent color
+ void matteColor ( const Color &matteColor_ );
+ Color matteColor ( void ) const;
+
+ // Write as a monochrome image
+ void monochrome ( bool monochromeFlag_ );
+ bool monochrome ( void ) const;
+
+ // Preferred size and location of an image canvas.
+ void page ( const Geometry &pageSize_ );
+ Geometry page ( void ) const;
+
+ // Desired image quality factor
+ void quality ( unsigned int quality_ );
+ unsigned int quality ( void ) const;
+
+ // Maximum number of colors to quantize to
+ void quantizeColors ( unsigned int colors_ );
+ unsigned int quantizeColors ( void ) const;
+
+ // Colorspace to quantize in.
+ void quantizeColorSpace ( ColorspaceType colorSpace_ );
+ ColorspaceType quantizeColorSpace ( void ) const;
+
+ // Dither image during quantization.
+ void quantizeDither ( bool ditherFlag_ );
+ bool quantizeDither ( void ) const;
+
+ // Quantization tree-depth
+ void quantizeTreeDepth ( unsigned int treeDepth_ );
+ unsigned int quantizeTreeDepth ( void ) const;
+
+ // Suppress all warning messages. Error messages are still reported.
+ void quiet ( const bool quiet_ );
+ bool quiet ( void ) const;
+
+ // Units of resolution to interpret density
+ void resolutionUnits ( ResolutionType resolutionUnits_ );
+ ResolutionType resolutionUnits ( void ) const;
+
+ // Image size (required for raw formats)
+ void size ( const Geometry &geometry_ );
+ Geometry size ( void ) const;
+
+ // enabled/disable stroke anti-aliasing
+ void strokeAntiAlias( bool flag_ );
+ bool strokeAntiAlias( void ) const ;
+
+ // Color to use when drawing object outlines
+ void strokeColor ( const Color &strokeColor_ );
+ Color strokeColor ( void ) const;
+
+ // Control the pattern of dashes and gaps used to stroke
+ // paths. The strokeDashArray represents a list of numbers that
+ // specify the lengths of alternating dashes and gaps in user
+ // units. If an odd number of values is provided, then the list of
+ // values is repeated to yield an even number of values.
+ void strokeDashArray ( const double* strokeDashArray_ );
+ const double* strokeDashArray ( void ) const;
+
+ // While drawing using strokeDashArray, specify distance into the dash
+ // pattern to start the dash (default 0).
+ void strokeDashOffset ( double strokeDashOffset_ );
+ double strokeDashOffset ( void ) const;
+
+ // Specify the shape to be used at the end of open subpaths when
+ // they are stroked. Values of LineCap are UndefinedCap, ButtCap,
+ // RoundCap, and SquareCap.
+ void strokeLineCap ( LineCap lineCap_ );
+ LineCap strokeLineCap ( void ) const;
+
+ // Specify the shape to be used at the corners of paths (or other
+ // vector shapes) when they are stroked. Values of LineJoin are
+ // UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
+ void strokeLineJoin ( LineJoin lineJoin_ );
+ LineJoin strokeLineJoin ( void ) const;
+
+ // Specify miter limit. When two line segments meet at a sharp
+ // angle and miter joins have been specified for 'lineJoin', it is
+ // possible for the miter to extend far beyond the thickness of
+ // the line stroking the path. The miterLimit' imposes a limit on
+ // the ratio of the miter length to the 'stroke_width'. The default
+ // value of this parameter is 4.
+ void strokeMiterLimit ( unsigned int miterLimit_ );
+ unsigned int strokeMiterLimit ( void ) const;
+
+ // Pattern image to use for stroked outlines
+ void strokePattern ( const MagickLib::Image *strokePattern_ );
+ const MagickLib::Image* strokePattern ( void ) const;
+
+ // Stroke width for drawing vector objects (default one)
+ void strokeWidth ( double strokeWidth_ );
+ double strokeWidth ( void ) const;
+
+ void subImage ( unsigned int subImage_ );
+ unsigned int subImage ( void ) const;
+
+ // Sub-frame number to return
+ void subRange ( unsigned int subRange_ );
+ unsigned int subRange ( void ) const;
+
+ // Annotation text encoding (e.g. "UTF-16")
+ void textEncoding ( const std::string &encoding_ );
+ std::string textEncoding ( void ) const;
+
+ void tileName ( const std::string &tileName_ );
+ std::string tileName ( void ) const;
+
+ // Image representation type
+ void type ( const ImageType type_ );
+ ImageType type ( void ) const;
+
+ // Origin of coordinate system to use when annotating with text or drawing
+ void transformOrigin ( double tx_, double ty_ );
+
+ // Reset transformation parameters to default
+ void transformReset ( void );
+
+ // Rotation to use when annotating with text or drawing
+ void transformRotation ( double angle_ );
+
+ // Scale to use when annotating with text or drawing
+ void transformScale ( double sx_, double sy_ );
+
+ // Skew to use in X axis when annotating with text or drawing
+ void transformSkewX ( double skewx_ );
+
+ // Skew to use in Y axis when annotating with text or drawing
+ void transformSkewY ( double skewy_ );
+
+ // Return verbose information about an image, or an operation
+ void verbose ( bool verboseFlag_ );
+ bool verbose ( void ) const;
+
+ void view ( const std::string &view_ );
+ std::string view ( void ) const;
+
+ // X11 display name
+ void x11Display ( const std::string &display_ );
+ std::string x11Display ( void ) const;
+
+ //
+ // Internal implementation methods. Please do not use.
+ //
+
+ MagickLib::DrawInfo* drawInfo( void );
+ MagickLib::ImageInfo * imageInfo( void );
+ MagickLib::QuantizeInfo * quantizeInfo( void );
+
+ // Construct using raw structures
+ Options( const MagickLib::ImageInfo* imageInfo_,
+ const MagickLib::QuantizeInfo* quantizeInfo_,
+ const MagickLib::DrawInfo* drawInfo_ );
+
+ protected:
+
+ private:
+
+ // Assignment not supported
+ Options& operator= ( const Options& );
+
+ MagickLib::ImageInfo* _imageInfo;
+ MagickLib::QuantizeInfo* _quantizeInfo;
+ MagickLib::DrawInfo* _drawInfo;
+ bool _quiet;
+ };
+} // namespace Magick
+
+#endif // Magick_Options_header
diff --git a/Magick++/lib/Magick++/Pixels.h b/Magick++/lib/Magick++/Pixels.h
new file mode 100644
index 0000000..fc5d13a
--- /dev/null
+++ b/Magick++/lib/Magick++/Pixels.h
@@ -0,0 +1,127 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
+//
+// Representation of a pixel view.
+//
+
+#if !defined(Magick_Pixels_header)
+#define Magick_Pixels_header
+
+#include "Magick++/Include.h"
+#include "Magick++/Color.h"
+#include "Magick++/Image.h"
+
+namespace Magick
+{
+ class MagickDLLDecl Pixels
+ {
+ public:
+
+ // Construct pixel view using specified image.
+ Pixels( Magick::Image &image_ );
+
+ // Destroy pixel view
+ ~Pixels( void );
+
+ // Transfer pixels from the image to the pixel view as defined by
+ // the specified region. Modified pixels may be subsequently
+ // transferred back to the image via sync.
+ PixelPacket* get ( const int x_, const int y_,
+ const unsigned int columns_,const unsigned int rows_ );
+
+ // Transfer read-only pixels from the image to the pixel view as
+ // defined by the specified region.
+ const PixelPacket* getConst ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ );
+
+ // Transfers the image view pixels to the image.
+ void sync ( void );
+
+ // Allocate a pixel view region to store image pixels as defined
+ // by the region rectangle. This area is subsequently transferred
+ // from the pixel view to the image via sync.
+ PixelPacket* set ( const int x_, const int y_,
+ const unsigned int columns_, const unsigned int rows_ );
+
+ // Return pixel colormap index array
+ IndexPacket* indexes ( void );
+
+ // Left ordinate of view
+ int x ( void ) const;
+
+ // Top ordinate of view
+ int y ( void ) const;
+
+ // Width of view
+ unsigned int columns ( void ) const;
+
+ // Height of view
+ unsigned int rows ( void ) const;
+
+#if 0
+ // Transfer one or more pixel components from a buffer or file
+ // into the image pixel view of an image. Used to support image
+ // decoders.
+ void decode ( const QuantumType quantum_,
+ const unsigned char *source_ )
+ {
+ MagickLib::ReadPixelCache( _image.image(), quantum_, source_ );
+ }
+
+ // Transfer one or more pixel components from the image pixel
+ // view to a buffer or file. Used to support image encoders.
+ void encode ( const QuantumType quantum_,
+ const unsigned char *destination_ )
+ {
+ MagickLib::WritePixelCache( _image.image(), quantum_, destination_ );
+ }
+#endif
+ private:
+
+ // Copying and assigning Pixels is not supported.
+ Pixels( const Pixels& pixels_ );
+ const Pixels& operator=( const Pixels& pixels_ );
+
+ Magick::Image _image; // Image reference
+ MagickLib::ViewInfo* _view; // Image view handle
+ int _x; // Left ordinate of view
+ int _y; // Top ordinate of view
+ unsigned int _columns; // Width of view
+ unsigned int _rows; // Height of view
+ MagickLib:: ExceptionInfo _exception; // Any thrown exception
+
+ }; // class Pixels
+
+} // Magick namespace
+
+//
+// Inline methods
+//
+
+// Left ordinate of view
+inline int Magick::Pixels::x ( void ) const
+{
+ return _x;
+}
+
+// Top ordinate of view
+inline int Magick::Pixels::y ( void ) const
+{
+ return _y;
+}
+
+// Width of view
+inline unsigned int Magick::Pixels::columns ( void ) const
+{
+ return _columns;
+}
+
+// Height of view
+inline unsigned int Magick::Pixels::rows ( void ) const
+{
+ return _rows;
+}
+
+#endif // Magick_Pixels_header
diff --git a/Magick++/lib/Magick++/STL.h b/Magick++/lib/Magick++/STL.h
new file mode 100644
index 0000000..bacf655
--- /dev/null
+++ b/Magick++/lib/Magick++/STL.h
@@ -0,0 +1,2445 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999 - 2015
+//
+// Definition and implementation of template functions for using
+// Magick::Image with STL containers.
+//
+
+#ifndef Magick_STL_header
+#define Magick_STL_header
+
+#include "Magick++/Include.h"
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <map>
+#include <utility>
+
+#include "Magick++/CoderInfo.h"
+#include "Magick++/Drawable.h"
+#include "Magick++/Exception.h"
+#include "Magick++/Montage.h"
+
+namespace Magick
+{
+ //
+ // STL function object declarations/definitions
+ //
+
+ // Function objects provide the means to invoke an operation on one
+ // or more image objects in an STL-compatable container. The
+ // arguments to the function object constructor(s) are compatible
+ // with the arguments to the equivalent Image class method and
+ // provide the means to supply these options when the function
+ // object is invoked.
+
+ // For example, to read a GIF animation, set the color red to
+ // transparent for all frames, and write back out:
+ //
+ // list<image> images;
+ // readImages( &images, "animation.gif" );
+ // for_each( images.begin(), images.end(), transparentImage( "red" ) );
+ // writeImages( images.begin(), images.end(), "animation.gif" );
+
+ // Local adaptive threshold image
+ // http://www.dai.ed.ac.uk/HIPR2/adpthrsh.htm
+ // Width x height define the size of the pixel neighborhood
+ // offset = constant to subtract from pixel neighborhood mean
+ class MagickDLLDecl adaptiveThresholdImage : public std::unary_function<Image&,void>
+ {
+ public:
+ adaptiveThresholdImage( const unsigned int width_,
+ const unsigned int height_,
+ const double offset_ = 0.0 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _width;
+ unsigned int _height;
+ double _offset;
+ };
+
+ // Add noise to image with specified noise type
+ class MagickDLLDecl addNoiseImage : public std::unary_function<Image&,void>
+ {
+ public:
+ addNoiseImage ( NoiseType noiseType_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ NoiseType _noiseType;
+ };
+
+ // Transform image by specified affine (or free transform) matrix.
+ class MagickDLLDecl affineTransformImage : public std::unary_function<Image&,void>
+ {
+ public:
+ affineTransformImage( const DrawableAffine &affine_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ DrawableAffine _affine;
+ };
+
+ // Annotate image (draw text on image)
+ class MagickDLLDecl annotateImage : public std::unary_function<Image&,void>
+ {
+ public:
+ // Annotate using specified text, and placement location
+ annotateImage ( const std::string &text_,
+ const Geometry &geometry_ );
+
+ // Annotate using specified text, bounding area, and placement
+ // gravity
+ annotateImage ( const std::string &text_,
+ const Geometry &geometry_,
+ const GravityType gravity_ );
+
+ // Annotate with text using specified text, bounding area,
+ // placement gravity, and rotation.
+ annotateImage ( const std::string &text_,
+ const Geometry &geometry_,
+ const GravityType gravity_,
+ const double degrees_ );
+
+ // Annotate with text (bounding area is entire image) and
+ // placement gravity.
+ annotateImage ( const std::string &text_,
+ const GravityType gravity_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ // Copy constructor and assignment are not supported
+ annotateImage(const annotateImage&);
+ annotateImage& operator=(const annotateImage&);
+
+ const std::string _text;
+ const Geometry _geometry;
+ const GravityType _gravity;
+ const double _degrees;
+ };
+
+ // Blur image with specified blur factor
+ class MagickDLLDecl blurImage : public std::unary_function<Image&,void>
+ {
+ public:
+ blurImage( const double radius_ = 1, const double sigma_ = 0.5 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _radius;
+ double _sigma;
+ };
+
+ // Border image (add border to image)
+ class MagickDLLDecl borderImage : public std::unary_function<Image&,void>
+ {
+ public:
+ borderImage( const Geometry &geometry_ = borderGeometryDefault );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+ // Extract channel from image
+ class MagickDLLDecl channelImage : public std::unary_function<Image&,void>
+ {
+ public:
+ channelImage( const ChannelType channel_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ ChannelType _channel;
+ };
+
+ // Charcoal effect image (looks like charcoal sketch)
+ class MagickDLLDecl charcoalImage : public std::unary_function<Image&,void>
+ {
+ public:
+ charcoalImage( const double radius_ = 1, const double sigma_ = 0.5 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _radius;
+ double _sigma;
+ };
+
+ // Chop image (remove vertical or horizontal subregion of image)
+ class MagickDLLDecl chopImage : public std::unary_function<Image&,void>
+ {
+ public:
+ chopImage( const Geometry &geometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+ // Colorize image using pen color at specified percent opacity
+ class MagickDLLDecl colorizeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ colorizeImage( const unsigned int opacityRed_,
+ const unsigned int opacityGreen_,
+ const unsigned int opacityBlue_,
+ const Color &penColor_ );
+
+ colorizeImage( const unsigned int opacity_,
+ const Color &penColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _opacityRed;
+ unsigned int _opacityGreen;
+ unsigned int _opacityBlue;
+ Color _penColor;
+ };
+
+ // Bake in the ASC-CDL, which is a convention for the for the
+ // exchange of basic primary color grading information between for
+ // the exchange of basic primary color grading information between
+ // equipment and software from different manufacturers. It is a
+ // useful transform for other purposes as well.
+ class MagickDLLDecl cdlImage : public std::unary_function<Image&,void>
+ {
+ public:
+ cdlImage( const std::string &cdl_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _cdl;
+ };
+
+ // Apply a color matrix to the image channels. The user supplied
+ // matrix may be of order 1 to 5 (1x1 through 5x5).
+ class MagickDLLDecl colorMatrixImage : public std::unary_function<Image&,void>
+ {
+ public:
+ colorMatrixImage( const unsigned int order_,
+ const double *color_matrix_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _order;
+ const double *_color_matrix;
+ };
+
+ // Convert the image colorspace representation
+ class MagickDLLDecl colorSpaceImage : public std::unary_function<Image&,void>
+ {
+ public:
+ colorSpaceImage( ColorspaceType colorSpace_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ ColorspaceType _colorSpace;
+ };
+
+ // Comment image (add comment string to image)
+ class MagickDLLDecl commentImage : public std::unary_function<Image&,void>
+ {
+ public:
+ commentImage( const std::string &comment_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _comment;
+ };
+
+ // Compose an image onto another at specified offset and using
+ // specified algorithm
+ class MagickDLLDecl compositeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ compositeImage( const Image &compositeImage_,
+ int xOffset_,
+ int yOffset_,
+ CompositeOperator compose_ = InCompositeOp );
+
+ compositeImage( const Image &compositeImage_,
+ const Geometry &offset_,
+ CompositeOperator compose_ = InCompositeOp );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Image _compositeImage;
+ int _xOffset;
+ int _yOffset;
+ CompositeOperator _compose;
+ };
+
+ // Contrast image (enhance intensity differences in image)
+ class MagickDLLDecl contrastImage : public std::unary_function<Image&,void>
+ {
+ public:
+ contrastImage( const unsigned int sharpen_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _sharpen;
+ };
+
+ // Crop image (subregion of original image)
+ class MagickDLLDecl cropImage : public std::unary_function<Image&,void>
+ {
+ public:
+ cropImage( const Geometry &geometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+ // Cycle image colormap
+ class MagickDLLDecl cycleColormapImage : public std::unary_function<Image&,void>
+ {
+ public:
+ cycleColormapImage( const int amount_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ int _amount;
+ };
+
+ // Despeckle image (reduce speckle noise)
+ class MagickDLLDecl despeckleImage : public std::unary_function<Image&,void>
+ {
+ public:
+ despeckleImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Draw on image
+ class MagickDLLDecl drawImage : public std::unary_function<Image&,void>
+ {
+ public:
+ // Draw on image using a single drawable
+ // Store in list to make implementation easier
+ drawImage( const Drawable &drawable_ );
+
+ // Draw on image using a drawable list
+ drawImage( const DrawableList &drawable_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ DrawableList _drawableList;
+ };
+
+ // Edge image (hilight edges in image)
+ class MagickDLLDecl edgeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ edgeImage( const double radius_ = 0.0 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _radius;
+ };
+
+ // Emboss image (hilight edges with 3D effect)
+ class MagickDLLDecl embossImage : public std::unary_function<Image&,void>
+ {
+ public:
+ embossImage( void );
+ embossImage( const double radius_, const double sigma_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _radius;
+ double _sigma;
+ };
+
+ // Enhance image (minimize noise)
+ class MagickDLLDecl enhanceImage : public std::unary_function<Image&,void>
+ {
+ public:
+ enhanceImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Equalize image (histogram equalization)
+ class MagickDLLDecl equalizeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ equalizeImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Create an image canvas using background color sized according to
+ // geometry and composite existing image on it, with image placement
+ // controlled by gravity. Parameters are obtained from existing
+ // image properties if they are not specified via a method
+ // parameter. Parameters which are supported by image properties
+ // (gravity and backgroundColor) update those image properties as a
+ // side-effect.
+ class MagickDLLDecl extentImage : public std::unary_function<Image&,void>
+ {
+ public:
+ // Extent image using a geometry
+ extentImage ( const Geometry &geometry_ );
+
+ // Extent image using a geometry & gravity
+ extentImage ( const Geometry &geometry_,
+ const GravityType &gravity_ );
+
+ // Extent image using a geometry & background color
+ extentImage ( const Geometry &geometry_,
+ const Color &backgroundColor_ );
+
+ // Extent image using a geometry, background color & gravity
+ extentImage ( const Geometry &geometry_,
+ const Color &backgroundColor_,
+ const GravityType &gravity_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ // Copy constructor and assignment are not supported
+ extentImage(const extentImage&);
+ extentImage& operator=(const extentImage&);
+
+ const Geometry _geometry;
+ const Color _backgroundColor;
+ const GravityType _gravity;
+ };
+
+ // Color to use when filling drawn objects
+ class MagickDLLDecl fillColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ fillColorImage( const Color &fillColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _fillColor;
+ };
+
+ // Flip image (reflect each scanline in the vertical direction)
+ class MagickDLLDecl flipImage : public std::unary_function<Image&,void>
+ {
+ public:
+ flipImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Flood-fill image with color
+ class MagickDLLDecl floodFillColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ // Flood-fill color across pixels starting at target-pixel and
+ // stopping at pixels matching specified border color.
+ // Uses current fuzz setting when determining color match.
+ floodFillColorImage( const unsigned int x_,
+ const unsigned int y_,
+ const Color &fillColor_ );
+
+ floodFillColorImage( const Geometry &point_,
+ const Color &fillColor_ );
+
+ // Flood-fill color across pixels starting at target-pixel and
+ // stopping at pixels matching specified border color.
+ // Uses current fuzz setting when determining color match.
+ floodFillColorImage( const unsigned int x_,
+ const unsigned int y_,
+ const Color &fillColor_,
+ const Color &borderColor_ );
+
+ floodFillColorImage( const Geometry &point_,
+ const Color &fillColor_,
+ const Color &borderColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _x;
+ unsigned int _y;
+ Color _fillColor;
+ Color _borderColor;
+ };
+
+ // Flood-fill image with texture
+ class MagickDLLDecl floodFillTextureImage : public std::unary_function<Image&,void>
+ {
+ public:
+ // Flood-fill texture across pixels that match the color of the
+ // target pixel and are neighbors of the target pixel.
+ // Uses current fuzz setting when determining color match.
+ floodFillTextureImage( const unsigned int x_,
+ const unsigned int y_,
+ const Image &texture_ );
+
+ floodFillTextureImage( const Geometry &point_,
+ const Image &texture_ );
+
+ // Flood-fill texture across pixels starting at target-pixel and
+ // stopping at pixels matching specified border color.
+ // Uses current fuzz setting when determining color match.
+ floodFillTextureImage( const unsigned int x_,
+ const unsigned int y_,
+ const Image &texture_,
+ const Color &borderColor_ );
+
+ floodFillTextureImage( const Geometry &point_,
+ const Image &texture_,
+ const Color &borderColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _x;
+ unsigned int _y;
+ Image _texture;
+ Color _borderColor;
+ };
+
+ // Flop image (reflect each scanline in the horizontal direction)
+ class MagickDLLDecl flopImage : public std::unary_function<Image&,void>
+ {
+ public:
+ flopImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Frame image
+ class MagickDLLDecl frameImage : public std::unary_function<Image&,void>
+ {
+ public:
+ frameImage( const Geometry &geometry_ = frameGeometryDefault );
+
+ frameImage( const unsigned int width_, const unsigned int height_,
+ const int innerBevel_ = 6, const int outerBevel_ = 6 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _width;
+ unsigned int _height;
+ int _outerBevel;
+ int _innerBevel;
+ };
+
+ // Gamma correct image
+ class MagickDLLDecl gammaImage : public std::unary_function<Image&,void>
+ {
+ public:
+ gammaImage( const double gamma_ );
+
+ gammaImage ( const double gammaRed_,
+ const double gammaGreen_,
+ const double gammaBlue_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _gammaRed;
+ double _gammaGreen;
+ double _gammaBlue;
+ };
+
+ // Gaussian blur image
+ // The number of neighbor pixels to be included in the convolution
+ // mask is specified by 'width_'. The standard deviation of the
+ // gaussian bell curve is specified by 'sigma_'.
+ class MagickDLLDecl gaussianBlurImage : public std::unary_function<Image&,void>
+ {
+ public:
+ gaussianBlurImage( const double width_, const double sigma_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _width;
+ double _sigma;
+ };
+
+ // Implode image (special effect)
+ class MagickDLLDecl implodeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ implodeImage( const double factor_ = 50 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _factor;
+ };
+
+ // Apply a color lookup table (Hald CLUT) to the image.
+ class MagickDLLDecl haldClutImage : public std::unary_function<Image&,void>
+ {
+ public:
+ haldClutImage( const Image &haldClutImage_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Image _haldClutImage;
+ };
+
+ // Set image validity. Valid images become empty (inValid) if
+ // argument is false.
+ class MagickDLLDecl isValidImage : public std::unary_function<Image&,void>
+ {
+ public:
+ isValidImage( const bool isValid_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _isValid;
+ };
+
+ // Label image
+ class MagickDLLDecl labelImage : public std::unary_function<Image&,void>
+ {
+ public:
+ labelImage( const std::string &label_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _label;
+ };
+
+ // Level image
+ class MagickDLLDecl levelImage : public std::unary_function<Image&,void>
+ {
+ public:
+ levelImage( const double black_point,
+ const double white_point,
+ const double mid_point=1.0 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _black_point;
+ double _white_point;
+ double _mid_point;
+ };
+
+ // Level image channel
+ class MagickDLLDecl levelChannelImage : public std::unary_function<Image&,void>
+ {
+ public:
+ levelChannelImage( const Magick::ChannelType channel,
+ const double black_point,
+ const double white_point,
+ const double mid_point=1.0 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Magick::ChannelType _channel;
+ double _black_point;
+ double _white_point;
+ double _mid_point;
+ };
+
+ // Magnify image by integral size
+ class MagickDLLDecl magnifyImage : public std::unary_function<Image&,void>
+ {
+ public:
+ magnifyImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Remap image colors with closest color from reference image
+ class MagickDLLDecl mapImage : public std::unary_function<Image&,void>
+ {
+ public:
+ mapImage( const Image &mapImage_ ,
+ const bool dither_ = false );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Image _mapImage;
+ bool _dither;
+ };
+
+ // Floodfill designated area with a matte value
+ class MagickDLLDecl matteFloodfillImage : public std::unary_function<Image&,void>
+ {
+ public:
+ matteFloodfillImage( const Color &target_ ,
+ const unsigned int matte_,
+ const int x_, const int y_,
+ const PaintMethod method_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _target;
+ unsigned int _matte;
+ int _x;
+ int _y;
+ PaintMethod _method;
+ };
+
+ // Filter image by replacing each pixel component with the median
+ // color in a circular neighborhood
+ class MagickDLLDecl medianFilterImage : public std::unary_function<Image&,void>
+ {
+ public:
+ medianFilterImage( const double radius_ = 0.0 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _radius;
+ };
+
+ // Reduce image by integral size
+ class MagickDLLDecl minifyImage : public std::unary_function<Image&,void>
+ {
+ public:
+ minifyImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Modulate percent hue, saturation, and brightness of an image.
+ // Modulation of saturation and brightness is as a ratio of the
+ // current value (1.0 for no change). Modulation of hue is an
+ // absolute rotation of -180 degrees to +180 degrees from the
+ // current position corresponding to an argument range of 0 to 2.0
+ // (1.0 for no change).
+ class MagickDLLDecl modulateImage : public std::unary_function<Image&,void>
+ {
+ public:
+ modulateImage( const double brightness_,
+ const double saturation_,
+ const double hue_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _brightness;
+ double _saturation;
+ double _hue;
+ };
+
+ // Negate colors in image. Set grayscale to only negate grayscale
+ // values in image.
+ class MagickDLLDecl negateImage : public std::unary_function<Image&,void>
+ {
+ public:
+ negateImage( const bool grayscale_ = false );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _grayscale;
+ };
+
+ // Normalize image (increase contrast by normalizing the pixel
+ // values to span the full range of color values)
+ class MagickDLLDecl normalizeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ normalizeImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Oilpaint image (image looks like oil painting)
+ class MagickDLLDecl oilPaintImage : public std::unary_function<Image&,void>
+ {
+ public:
+ oilPaintImage( const double radius_ = 3 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _radius;
+ };
+
+ // Set or attenuate the image opacity channel. If the image pixels
+ // are opaque then they are set to the specified opacity value,
+ // otherwise they are blended with the supplied opacity value. The
+ // value of opacity_ ranges from 0 (completely opaque) to
+ // MaxRGB. The defines OpaqueOpacity and TransparentOpacity are
+ // available to specify completely opaque or completely transparent,
+ // respectively.
+ class MagickDLLDecl opacityImage : public std::unary_function<Image&,void>
+ {
+ public:
+ opacityImage( const unsigned int opacity_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _opacity;
+ };
+
+ // Change color of opaque pixel to specified pen color.
+ class MagickDLLDecl opaqueImage : public std::unary_function<Image&,void>
+ {
+ public:
+ opaqueImage( const Color &opaqueColor_,
+ const Color &penColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _opaqueColor;
+ Color _penColor;
+ };
+
+ // Quantize image (reduce number of colors)
+ class MagickDLLDecl quantizeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ quantizeImage( const bool measureError_ = false );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _measureError;
+ };
+
+ // Raise image (lighten or darken the edges of an image to give a
+ // 3-D raised or lowered effect)
+ class MagickDLLDecl raiseImage : public std::unary_function<Image&,void>
+ {
+ public:
+ raiseImage( const Geometry &geometry_ = raiseGeometryDefault,
+ const bool raisedFlag_ = false );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ bool _raisedFlag;
+ };
+
+ // Reduce noise in image using a noise peak elimination filter
+ class MagickDLLDecl reduceNoiseImage : public std::unary_function<Image&,void>
+ {
+ public:
+ reduceNoiseImage( void );
+
+ reduceNoiseImage (const unsigned int order_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _order;
+ };
+
+ // Resize image to a certain geomtry
+ class MagickDLLDecl resizeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ resizeImage( const Geometry &geometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+ // Roll image (rolls image vertically and horizontally) by specified
+ // number of columnms and rows)
+ class MagickDLLDecl rollImage : public std::unary_function<Image&,void>
+ {
+ public:
+ rollImage( const Geometry &roll_ );
+
+ rollImage( const int columns_, const int rows_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ int _columns;
+ int _rows;
+ };
+
+ // Rotate image counter-clockwise by specified number of degrees.
+ class MagickDLLDecl rotateImage : public std::unary_function<Image&,void>
+ {
+ public:
+ rotateImage( const double degrees_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _degrees;
+ };
+
+ // Resize image by using pixel sampling algorithm
+ class MagickDLLDecl sampleImage : public std::unary_function<Image&,void>
+ {
+ public:
+ sampleImage( const Geometry &geometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+ // Resize image by using simple ratio algorithm
+ class MagickDLLDecl scaleImage : public std::unary_function<Image&,void>
+ {
+ public:
+ scaleImage( const Geometry &geometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+ // Segment (coalesce similar image components) by analyzing the
+ // histograms of the color components and identifying units that are
+ // homogeneous with the fuzzy c-means technique.
+ // Also uses QuantizeColorSpace and Verbose image attributes
+ class MagickDLLDecl segmentImage : public std::unary_function<Image&,void>
+ {
+ public:
+ segmentImage( const double clusterThreshold_ = 1.0,
+ const double smoothingThreshold_ = 1.5 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _clusterThreshold;
+ double _smoothingThreshold;
+ };
+
+ // Shade image using distant light source
+ class MagickDLLDecl shadeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ shadeImage( const double azimuth_ = 30,
+ const double elevation_ = 30,
+ const bool colorShading_ = false );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _azimuth;
+ double _elevation;
+ bool _colorShading;
+ };
+
+ // Sharpen pixels in image
+ class MagickDLLDecl sharpenImage : public std::unary_function<Image&,void>
+ {
+ public:
+ sharpenImage( const double radius_ = 1, const double sigma_ = 0.5 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _radius;
+ double _sigma;
+ };
+
+ // Shave pixels from image edges.
+ class MagickDLLDecl shaveImage : public std::unary_function<Image&,void>
+ {
+ public:
+ shaveImage( const Geometry &geometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+
+ // Shear image (create parallelogram by sliding image by X or Y axis)
+ class MagickDLLDecl shearImage : public std::unary_function<Image&,void>
+ {
+ public:
+ shearImage( const double xShearAngle_,
+ const double yShearAngle_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _xShearAngle;
+ double _yShearAngle;
+ };
+
+ // Solarize image (similar to effect seen when exposing a
+ // photographic film to light during the development process)
+ class MagickDLLDecl solarizeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ solarizeImage( const double factor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _factor;
+ };
+
+ // Spread pixels randomly within image by specified ammount
+ class MagickDLLDecl spreadImage : public std::unary_function<Image&,void>
+ {
+ public:
+ spreadImage( const unsigned int amount_ = 3 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _amount;
+ };
+
+ // Add a digital watermark to the image (based on second image)
+ class MagickDLLDecl steganoImage : public std::unary_function<Image&,void>
+ {
+ public:
+ steganoImage( const Image &waterMark_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Image _waterMark;
+ };
+
+ // Create an image which appears in stereo when viewed with red-blue glasses
+ // (Red image on left, blue on right)
+ class MagickDLLDecl stereoImage : public std::unary_function<Image&,void>
+ {
+ public:
+ stereoImage( const Image &rightImage_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Image _rightImage;
+ };
+
+ // Color to use when drawing object outlines
+ class MagickDLLDecl strokeColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ strokeColorImage( const Color &strokeColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _strokeColor;
+ };
+
+ // Swirl image (image pixels are rotated by degrees)
+ class MagickDLLDecl swirlImage : public std::unary_function<Image&,void>
+ {
+ public:
+ swirlImage( const double degrees_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _degrees;
+ };
+
+ // Remove all profiles and text attributes from the image.
+ class MagickDLLDecl stripImage : public std::unary_function<Image&,void>
+ {
+ public:
+ stripImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Channel a texture on image background
+ class MagickDLLDecl textureImage : public std::unary_function<Image&,void>
+ {
+ public:
+ textureImage( const Image &texture_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Image _texture;
+ };
+
+ // Threshold image
+ class MagickDLLDecl thresholdImage : public std::unary_function<Image&,void>
+ {
+ public:
+ thresholdImage( const double threshold_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _threshold;
+ };
+
+ // Transform image based on image and crop geometries
+ class MagickDLLDecl transformImage : public std::unary_function<Image&,void>
+ {
+ public:
+ transformImage( const Geometry &imageGeometry_ );
+
+ transformImage( const Geometry &imageGeometry_,
+ const Geometry &cropGeometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _imageGeometry;
+ Geometry _cropGeometry;
+ };
+
+ // Set image color to transparent
+ class MagickDLLDecl transparentImage : public std::unary_function<Image&,void>
+ {
+ public:
+ transparentImage( const Color& color_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _color;
+ };
+
+ // Trim edges that are the background color from the image
+ class MagickDLLDecl trimImage : public std::unary_function<Image&,void>
+ {
+ public:
+ trimImage( void );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ };
+
+ // Map image pixels to a sine wave
+ class MagickDLLDecl waveImage : public std::unary_function<Image&,void>
+ {
+ public:
+ waveImage( const double amplitude_ = 25.0,
+ const double wavelength_ = 150.0 );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _amplitude;
+ double _wavelength;
+ };
+
+ // Zoom image to specified size.
+ class MagickDLLDecl zoomImage : public std::unary_function<Image&,void>
+ {
+ public:
+ zoomImage( const Geometry &geometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+ //
+ // Function object image attribute accessors
+ //
+
+ // Anti-alias Postscript and TrueType fonts (default true)
+ class MagickDLLDecl antiAliasImage : public std::unary_function<Image&,void>
+ {
+ public:
+ antiAliasImage( const bool flag_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _flag;
+ };
+
+ // Join images into a single multi-image file
+ class MagickDLLDecl adjoinImage : public std::unary_function<Image&,void>
+ {
+ public:
+ adjoinImage( const bool flag_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _flag;
+ };
+
+ // Time in 1/100ths of a second which must expire before displaying
+ // the next image in an animated sequence.
+ class MagickDLLDecl animationDelayImage : public std::unary_function<Image&,void>
+ {
+ public:
+ animationDelayImage( const unsigned int delay_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _delay;
+ };
+
+ // Number of iterations to loop an animation (e.g. Netscape loop
+ // extension) for.
+ class MagickDLLDecl animationIterationsImage : public std::unary_function<Image&,void>
+ {
+ public:
+ animationIterationsImage( const unsigned int iterations_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _iterations;
+ };
+
+ // Image background color
+ class MagickDLLDecl backgroundColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ backgroundColorImage( const Color &color_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _color;
+ };
+
+ // Name of texture image to tile onto the image background
+ class MagickDLLDecl backgroundTextureImage : public std::unary_function<Image&,void>
+ {
+ public:
+ backgroundTextureImage( const std::string &backgroundTexture_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _backgroundTexture;
+ };
+
+ // Image border color
+ class MagickDLLDecl borderColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ borderColorImage( const Color &color_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _color;
+ };
+
+ // Text bounding-box base color (default none)
+ class MagickDLLDecl boxColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ boxColorImage( const Color &boxColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _boxColor;
+ };
+
+ // Chromaticity blue primary point (e.g. x=0.15, y=0.06)
+ class MagickDLLDecl chromaBluePrimaryImage : public std::unary_function<Image&,void>
+ {
+ public:
+ chromaBluePrimaryImage( const double x_, const double y_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _x;
+ double _y;
+ };
+
+ // Chromaticity green primary point (e.g. x=0.3, y=0.6)
+ class MagickDLLDecl chromaGreenPrimaryImage : public std::unary_function<Image&,void>
+ {
+ public:
+ chromaGreenPrimaryImage( const double x_, const double y_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _x;
+ double _y;
+ };
+
+ // Chromaticity red primary point (e.g. x=0.64, y=0.33)
+ class MagickDLLDecl chromaRedPrimaryImage : public std::unary_function<Image&,void>
+ {
+ public:
+ chromaRedPrimaryImage( const double x_, const double y_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _x;
+ double _y;
+ };
+
+ // Chromaticity white point (e.g. x=0.3127, y=0.329)
+ class MagickDLLDecl chromaWhitePointImage : public std::unary_function<Image&,void>
+ {
+ public:
+ chromaWhitePointImage( const double x_, const double y_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _x;
+ double _y;
+ };
+
+ // Colors within this distance are considered equal
+ class MagickDLLDecl colorFuzzImage : public std::unary_function<Image&,void>
+ {
+ public:
+ colorFuzzImage( const double fuzz_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _fuzz;
+ };
+
+ // Color at colormap position index_
+ class MagickDLLDecl colorMapImage : public std::unary_function<Image&,void>
+ {
+ public:
+ colorMapImage( const unsigned int index_, const Color &color_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _index;
+ Color _color;
+ };
+
+ // Composition operator to be used when composition is implicitly used
+ // (such as for image flattening).
+ class MagickDLLDecl composeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ composeImage( const CompositeOperator compose_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ CompositeOperator _compose;
+ };
+
+ // Compression type
+ class MagickDLLDecl compressTypeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ compressTypeImage( const CompressionType compressType_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ CompressionType _compressType;
+ };
+
+ // Vertical and horizontal resolution in pixels of the image
+ class MagickDLLDecl densityImage : public std::unary_function<Image&,void>
+ {
+ public:
+ densityImage( const Geometry &geomery_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geomery;
+ };
+
+ // Image depth (bits allocated to red/green/blue components)
+ class MagickDLLDecl depthImage : public std::unary_function<Image&,void>
+ {
+ public:
+ depthImage( const unsigned int depth_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _depth;
+ };
+
+ // Endianness (LSBEndian like Intel or MSBEndian like SPARC) for image
+ // formats which support endian-specific options.
+ class MagickDLLDecl endianImage : public std::unary_function<Image&,void>
+ {
+ public:
+ endianImage( const EndianType endian_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ EndianType _endian;
+ };
+
+ // Image file name
+ class MagickDLLDecl fileNameImage : public std::unary_function<Image&,void>
+ {
+ public:
+ fileNameImage( const std::string &fileName_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _fileName;
+ };
+
+ // Filter to use when resizing image
+ class MagickDLLDecl filterTypeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ filterTypeImage( const FilterTypes filterType_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ FilterTypes _filterType;
+ };
+
+ // Text rendering font
+ class MagickDLLDecl fontImage : public std::unary_function<Image&,void>
+ {
+ public:
+ fontImage( const std::string &font_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _font;
+ };
+
+ // Font point size
+ class MagickDLLDecl fontPointsizeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ fontPointsizeImage( const unsigned int pointsize_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _pointsize;
+ };
+
+ // GIF disposal method
+ class MagickDLLDecl gifDisposeMethodImage : public std::unary_function<Image&,void>
+ {
+ public:
+ gifDisposeMethodImage( const unsigned int disposeMethod_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _disposeMethod;
+ };
+
+ // Type of interlacing to use
+ class MagickDLLDecl interlaceTypeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ interlaceTypeImage( const InterlaceType interlace_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ InterlaceType _interlace;
+ };
+
+ // Linewidth for drawing vector objects (default one)
+ class MagickDLLDecl lineWidthImage : public std::unary_function<Image&,void>
+ {
+ public:
+ lineWidthImage( const double lineWidth_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ double _lineWidth;
+ };
+
+ // File type magick identifier (.e.g "GIF")
+ class MagickDLLDecl magickImage : public std::unary_function<Image&,void>
+ {
+ public:
+ magickImage( const std::string &magick_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _magick;
+ };
+
+ // Image supports transparent color
+ class MagickDLLDecl matteImage : public std::unary_function<Image&,void>
+ {
+ public:
+ matteImage( const bool matteFlag_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _matteFlag;
+ };
+
+ // Transparent color
+ class MagickDLLDecl matteColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ matteColorImage( const Color &matteColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _matteColor;
+ };
+
+ // Indicate that image is black and white
+ class MagickDLLDecl monochromeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ monochromeImage( const bool monochromeFlag_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _monochromeFlag;
+ };
+
+ // Pen color
+ class MagickDLLDecl penColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ penColorImage( const Color &penColor_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Color _penColor;
+ };
+
+ // Pen texture image.
+ class MagickDLLDecl penTextureImage : public std::unary_function<Image&,void>
+ {
+ public:
+ penTextureImage( const Image &penTexture_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Image _penTexture;
+ };
+
+ // Set pixel color at location x & y.
+ class MagickDLLDecl pixelColorImage : public std::unary_function<Image&,void>
+ {
+ public:
+ pixelColorImage( const unsigned int x_,
+ const unsigned int y_,
+ const Color &color_);
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _x;
+ unsigned int _y;
+ Color _color;
+ };
+
+ // Postscript page size.
+ class MagickDLLDecl pageImage : public std::unary_function<Image&,void>
+ {
+ public:
+ pageImage( const Geometry &pageSize_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _pageSize;
+ };
+
+ // JPEG/MIFF/PNG compression level (default 75).
+ class MagickDLLDecl qualityImage : public std::unary_function<Image&,void>
+ {
+ public:
+ qualityImage( const unsigned int quality_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _quality;
+ };
+
+ // Maximum number of colors to quantize to
+ class MagickDLLDecl quantizeColorsImage : public std::unary_function<Image&,void>
+ {
+ public:
+ quantizeColorsImage( const unsigned int colors_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _colors;
+ };
+
+ // Colorspace to quantize in.
+ class MagickDLLDecl quantizeColorSpaceImage : public std::unary_function<Image&,void>
+ {
+ public:
+ quantizeColorSpaceImage( const ColorspaceType colorSpace_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ ColorspaceType _colorSpace;
+ };
+
+ // Dither image during quantization (default true).
+ class MagickDLLDecl quantizeDitherImage : public std::unary_function<Image&,void>
+ {
+ public:
+ quantizeDitherImage( const bool ditherFlag_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _ditherFlag;
+ };
+
+ // Quantization tree-depth
+ class MagickDLLDecl quantizeTreeDepthImage : public std::unary_function<Image&,void>
+ {
+ public:
+ quantizeTreeDepthImage( const unsigned int treeDepth_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _treeDepth;
+ };
+
+ // The type of rendering intent
+ class MagickDLLDecl renderingIntentImage : public std::unary_function<Image&,void>
+ {
+ public:
+ renderingIntentImage( const RenderingIntent renderingIntent_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ RenderingIntent _renderingIntent;
+ };
+
+ // Units of image resolution
+ class MagickDLLDecl resolutionUnitsImage : public std::unary_function<Image&,void>
+ {
+ public:
+ resolutionUnitsImage( const ResolutionType resolutionUnits_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ ResolutionType _resolutionUnits;
+ };
+
+ // Image scene number
+ class MagickDLLDecl sceneImage : public std::unary_function<Image&,void>
+ {
+ public:
+ sceneImage( const unsigned int scene_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _scene;
+ };
+
+ // Width and height of a raw image
+ class MagickDLLDecl sizeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ sizeImage( const Geometry &geometry_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Geometry _geometry;
+ };
+
+ // Subimage of an image sequence
+ class MagickDLLDecl subImageImage : public std::unary_function<Image&,void>
+ {
+ public:
+ subImageImage( const unsigned int subImage_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _subImage;
+ };
+
+ // Number of images relative to the base image
+ class MagickDLLDecl subRangeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ subRangeImage( const unsigned int subRange_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ unsigned int _subRange;
+ };
+
+ // Tile name
+ class MagickDLLDecl tileNameImage : public std::unary_function<Image&,void>
+ {
+ public:
+ tileNameImage( const std::string &tileName_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _tileName;
+ };
+
+ // Image storage type
+ class MagickDLLDecl typeImage : public std::unary_function<Image&,void>
+ {
+ public:
+ typeImage( const ImageType type_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ Magick::ImageType _type;
+ };
+
+
+ // Print detailed information about the image
+ class MagickDLLDecl verboseImage : public std::unary_function<Image&,void>
+ {
+ public:
+ verboseImage( const bool verbose_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ bool _verbose;
+ };
+
+ // FlashPix viewing parameters
+ class MagickDLLDecl viewImage : public std::unary_function<Image&,void>
+ {
+ public:
+ viewImage( const std::string &view_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _view;
+ };
+
+ // X11 display to display to, obtain fonts from, or to capture
+ // image from
+ class MagickDLLDecl x11DisplayImage : public std::unary_function<Image&,void>
+ {
+ public:
+ x11DisplayImage( const std::string &display_ );
+
+ void operator()( Image &image_ ) const;
+
+ private:
+ std::string _display;
+ };
+
+ //////////////////////////////////////////////////////////
+ //
+ // Implementation template definitions. Not for end-use.
+ //
+ //////////////////////////////////////////////////////////
+
+ // Link images together into an image list based on the ordering of
+ // the container implied by the iterator. This step is done in
+ // preparation for use with ImageMagick functions which operate on
+ // lists of images.
+ // Images are selected by range, first_ to last_ so that a subset of
+ // the container may be selected. Specify first_ via the
+ // container's begin() method and last_ via the container's end()
+ // method in order to specify the entire container.
+ template <class InputIterator>
+ void linkImages( InputIterator first_,
+ InputIterator last_ ) {
+
+ MagickLib::Image* previous = 0;
+ int scene = 0;
+ for ( InputIterator iter = first_; iter != last_; ++iter )
+ {
+ // Unless we reduce the reference count to one, the same image
+ // structure may occur more than once in the container, causing
+ // the linked list to fail.
+ iter->modifyImage();
+
+ MagickLib::Image* current = iter->image();
+
+ current->previous = previous;
+ current->next = 0;
+ current->scene = scene++;
+
+ if ( previous != 0)
+ previous->next = current;
+
+ previous = current;
+ }
+ }
+
+ // Remove links added by linkImages. This should be called after the
+ // ImageMagick function call has completed to reset the image list
+ // back to its pristine un-linked state.
+ template <class InputIterator>
+ void unlinkImages( InputIterator first_,
+ InputIterator last_ ) {
+ for( InputIterator iter = first_; iter != last_; ++iter )
+ {
+ MagickLib::Image* image = iter->image();
+ image->previous = 0;
+ image->next = 0;
+ }
+ }
+
+ // Insert images in image list into existing container (appending to container)
+ // The images should not be deleted since only the image ownership is passed.
+ // The options are copied into the object.
+ template <class Container>
+ void insertImages( Container *sequence_,
+ MagickLib::Image* images_ ) {
+ MagickLib::Image *image = images_;
+ if ( image )
+ {
+ do
+ {
+ MagickLib::Image* next_image = image->next;
+ image->next = 0;
+
+ if (next_image != 0)
+ next_image->previous=0;
+
+ sequence_->push_back( Magick::Image( image ) );
+
+ image=next_image;
+ } while( image );
+
+ return;
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // Template definitions for documented API
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ template <class InputIterator>
+ void animateImages( InputIterator first_,
+ InputIterator last_ ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickLib::AnimateImages( first_->imageInfo(), first_->image() );
+ MagickLib::GetImageException( first_->image(), &exceptionInfo );
+ unlinkImages( first_, last_ );
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ // Append images from list into single image in either horizontal or
+ // vertical direction.
+ template <class InputIterator>
+ void appendImages( Image *appendedImage_,
+ InputIterator first_,
+ InputIterator last_,
+ bool stack_ = false) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickLib::Image* image = MagickLib::AppendImages( first_->image(),
+ stack_,
+ &exceptionInfo );
+ unlinkImages( first_, last_ );
+ appendedImage_->replaceImage( image );
+ throwException( exceptionInfo, appendedImage_->quiet() );
+ }
+
+ // Average a set of images.
+ // All the input images must be the same size in pixels.
+ template <class InputIterator>
+ void averageImages( Image *averagedImage_,
+ InputIterator first_,
+ InputIterator last_ ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickLib::Image* image = MagickLib::AverageImages( first_->image(),
+ &exceptionInfo );
+ unlinkImages( first_, last_ );
+ averagedImage_->replaceImage( image );
+ throwException( exceptionInfo, averagedImage_->quiet() );
+ }
+
+ // Merge a sequence of images.
+ // This is useful for GIF animation sequences that have page
+ // offsets and disposal methods. A container to contain
+ // the updated image sequence is passed via the coalescedImages_
+ // option.
+ template <class InputIterator, class Container >
+ void coalesceImages( Container *coalescedImages_,
+ InputIterator first_,
+ InputIterator last_ ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+
+ // Build image list
+ linkImages( first_, last_ );
+ MagickLib::Image* images = MagickLib::CoalesceImages( first_->image(),
+ &exceptionInfo);
+ // Unlink image list
+ unlinkImages( first_, last_ );
+
+ // Ensure container is empty
+ coalescedImages_->clear();
+
+ // Move images to container
+ insertImages( coalescedImages_, images );
+
+ // Report any error
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ // Return format coders matching specified conditions.
+ //
+ // The default (if no match terms are supplied) is to return all
+ // available format coders.
+ //
+ // For example, to return all readable formats:
+ // list<CoderInfo> coderList;
+ // coderInfoList( &coderList, CoderInfo::TrueMatch, CoderInfo::AnyMatch, CoderInfo::AnyMatch)
+ //
+ template <class Container >
+ void coderInfoList( Container *container_,
+ CoderInfo::MatchType isReadable_ = CoderInfo::AnyMatch,
+ CoderInfo::MatchType isWritable_ = CoderInfo::AnyMatch,
+ CoderInfo::MatchType isMultiFrame_ = CoderInfo::AnyMatch
+ ) {
+ // Obtain first entry in MagickInfo list
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ MagickLib::MagickInfo **coder_list =
+ MagickLib::GetMagickInfoArray( &exceptionInfo );
+ if( !coder_list )
+ {
+ throwException( exceptionInfo );
+ throwExceptionExplicit(MagickLib::MissingDelegateError,
+ "Coder array not returned!", 0 );
+ }
+
+ // Clear out container
+ container_->clear();
+
+ for ( int i=0; coder_list[i] != 0; i++)
+ {
+ // Skip stealth coders
+ if ( coder_list[i]->stealth )
+ continue;
+
+ try {
+ CoderInfo coderInfo( coder_list[i]->name );
+
+ // Test isReadable_
+ if ( isReadable_ != CoderInfo::AnyMatch &&
+ (( coderInfo.isReadable() && isReadable_ != CoderInfo::TrueMatch ) ||
+ ( !coderInfo.isReadable() && isReadable_ != CoderInfo::FalseMatch )) )
+ continue;
+
+ // Test isWritable_
+ if ( isWritable_ != CoderInfo::AnyMatch &&
+ (( coderInfo.isWritable() && isWritable_ != CoderInfo::TrueMatch ) ||
+ ( !coderInfo.isWritable() && isWritable_ != CoderInfo::FalseMatch )) )
+ continue;
+
+ // Test isMultiFrame_
+ if ( isMultiFrame_ != CoderInfo::AnyMatch &&
+ (( coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::TrueMatch ) ||
+ ( !coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::FalseMatch )) )
+ continue;
+
+ // Append matches to container
+ container_->push_back( coderInfo );
+ }
+ // Intentionally ignore missing module errors
+ catch ( Magick::ErrorModule )
+ {
+ continue;
+ }
+ }
+ MagickLib::MagickFree(coder_list);
+ coder_list=0;
+ MagickLib::DestroyExceptionInfo( &exceptionInfo );
+ }
+
+ //
+ // Fill container with color histogram.
+ // Entries are of type "std::pair<Color,unsigned long>". Use the pair
+ // "first" member to access the Color and the "second" member to access
+ // the number of times the color occurs in the image.
+ //
+ // For example:
+ //
+ // Using <map>:
+ //
+ // Image image("image.miff");
+ // map<Color,unsigned long> histogram;
+ // colorHistogram( &histogram, image );
+ // std::map<Color,unsigned long>::const_iterator p=histogram.begin();
+ // while (p != histogram.end())
+ // {
+ // cout << setw(10) << (int)p->second << ": ("
+ // << setw(quantum_width) << (int)p->first.redQuantum() << ","
+ // << setw(quantum_width) << (int)p->first.greenQuantum() << ","
+ // << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
+ // << endl;
+ // p++;
+ // }
+ //
+ // Using <vector>:
+ //
+ // Image image("image.miff");
+ // std::vector<std::pair<Color,unsigned long> > histogram;
+ // colorHistogram( &histogram, image );
+ // std::vector<std::pair<Color,unsigned long> >::const_iterator p=histogram.begin();
+ // while (p != histogram.end())
+ // {
+ // cout << setw(10) << (int)p->second << ": ("
+ // << setw(quantum_width) << (int)p->first.redQuantum() << ","
+ // << setw(quantum_width) << (int)p->first.greenQuantum() << ","
+ // << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
+ // << endl;
+ // p++;
+ // }
+
+ template <class Container >
+ void colorHistogram( Container *histogram_, const Image image)
+ {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+
+ // Obtain histogram array
+ unsigned long colors;
+ MagickLib::HistogramColorPacket *histogram_array =
+ MagickLib::GetColorHistogram( image.constImage(), &colors, &exceptionInfo );
+ throwException( exceptionInfo, image.quiet() );
+
+ // Clear out container
+ histogram_->clear();
+
+ // Transfer histogram array to container
+ for ( unsigned long i=0; i < colors; i++)
+ {
+ histogram_->insert(histogram_->end(),std::pair<const Color,unsigned long>
+ ( Color(histogram_array[i].pixel.red,
+ histogram_array[i].pixel.green,
+ histogram_array[i].pixel.blue),
+ histogram_array[i].count) );
+ }
+
+ // Deallocate histogram array
+ MagickLib::MagickFree(histogram_array);
+ histogram_array = 0;
+ }
+
+ // Break down an image sequence into constituent parts. This is
+ // useful for creating GIF or MNG animation sequences.
+ template <class InputIterator, class Container >
+ void deconstructImages( Container *deconstructedImages_,
+ InputIterator first_,
+ InputIterator last_ ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+
+ // Build image list
+ linkImages( first_, last_ );
+ MagickLib::Image* images = MagickLib::DeconstructImages( first_->image(),
+ &exceptionInfo);
+ // Unlink image list
+ unlinkImages( first_, last_ );
+
+ // Ensure container is empty
+ deconstructedImages_->clear();
+
+ // Move images to container
+ insertImages( deconstructedImages_, images );
+
+ // Report any error
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ //
+ // Display an image sequence
+ //
+ template <class InputIterator>
+ void displayImages( InputIterator first_,
+ InputIterator last_ ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickLib::DisplayImages( first_->imageInfo(), first_->image() );
+ MagickLib::GetImageException( first_->image(), &exceptionInfo );
+ unlinkImages( first_, last_ );
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ // Merge a sequence of image frames which represent image layers.
+ // This is useful for combining Photoshop layers into a single image.
+ template <class InputIterator>
+ void flattenImages( Image *flattendImage_,
+ InputIterator first_,
+ InputIterator last_ ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickLib::Image* image = MagickLib::FlattenImages( first_->image(),
+ &exceptionInfo );
+ unlinkImages( first_, last_ );
+ flattendImage_->replaceImage( image );
+ throwException( exceptionInfo, flattendImage_->quiet() );
+ }
+
+ // Replace the colors of a sequence of images with the closest color
+ // from a reference image.
+ // Set dither_ to true to enable dithering. Set measureError_ to
+ // true in order to evaluate quantization error.
+ template <class InputIterator>
+ void mapImages( InputIterator first_,
+ InputIterator last_,
+ const Image& mapImage_,
+ bool dither_ = false,
+ bool measureError_ = false ) {
+
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickLib::MapImages( first_->image(),
+ mapImage_.constImage(),
+ dither_ );
+ MagickLib::GetImageException( first_->image(), &exceptionInfo );
+ if ( exceptionInfo.severity != MagickLib::UndefinedException )
+ {
+ unlinkImages( first_, last_ );
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ MagickLib::Image* image = first_->image();
+ while( image )
+ {
+ // Calculate quantization error
+ if ( measureError_ )
+ {
+ MagickLib::GetImageQuantizeError( image );
+ if ( image->exception.severity > MagickLib::UndefinedException )
+ {
+ unlinkImages( first_, last_ );
+ throwException( exceptionInfo, first_->quiet() );
+ }
+ }
+
+ // Udate DirectClass representation of pixels
+ MagickLib::SyncImage( image );
+ if ( image->exception.severity > MagickLib::UndefinedException )
+ {
+ unlinkImages( first_, last_ );
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ // Next image
+ image=image->next;
+ }
+
+ unlinkImages( first_, last_ );
+ }
+
+ // Create a composite image by combining several separate images.
+ template <class Container, class InputIterator>
+ void montageImages( Container *montageImages_,
+ InputIterator first_,
+ InputIterator last_,
+ const Montage &montageOpts_ ) {
+
+ MagickLib::MontageInfo* montageInfo =
+ static_cast<MagickLib::MontageInfo*>(MagickLib::MagickMalloc(sizeof(MagickLib::MontageInfo)));
+
+ // Update montage options with those set in montageOpts_
+ montageOpts_.updateMontageInfo( *montageInfo );
+
+ // Update options which must transfer to image options
+ if ( montageOpts_.label().length() != 0 )
+ first_->label( montageOpts_.label() );
+
+ // Create linked image list
+ linkImages( first_, last_ );
+
+ // Reset output container to pristine state
+ montageImages_->clear();
+
+ // Do montage
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image *images = MagickLib::MontageImages( first_->image(),
+ montageInfo,
+ &exceptionInfo );
+ if ( images != 0 )
+ {
+ insertImages( montageImages_, images );
+ }
+
+ // Clean up any allocated data in montageInfo
+ MagickLib::DestroyMontageInfo( montageInfo );
+
+ // Unlink linked image list
+ unlinkImages( first_, last_ );
+
+ // Report any montage error
+ throwException( exceptionInfo, first_->quiet() );
+
+ // Apply transparency to montage images
+ if ( montageImages_->size() > 0 && montageOpts_.transparentColor().isValid() )
+ {
+ for_each( first_, last_, transparentImage( montageOpts_.transparentColor() ) );
+ }
+
+ // Report any transparentImage() error
+ MagickLib::GetImageException( first_->image(), &exceptionInfo );
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ // Morph a set of images
+ template <class InputIterator, class Container >
+ void morphImages( Container *morphedImages_,
+ InputIterator first_,
+ InputIterator last_,
+ unsigned int frames_ ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+
+ // Build image list
+ linkImages( first_, last_ );
+ MagickLib::Image* images = MagickLib::MorphImages( first_->image(), frames_,
+ &exceptionInfo);
+ // Unlink image list
+ unlinkImages( first_, last_ );
+
+ // Ensure container is empty
+ morphedImages_->clear();
+
+ // Move images to container
+ insertImages( morphedImages_, images );
+
+ // Report any error
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ // Inlay a number of images to form a single coherent picture.
+ template <class InputIterator>
+ void mosaicImages( Image *mosaicImage_,
+ InputIterator first_,
+ InputIterator last_ ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickLib::Image* image = MagickLib::MosaicImages( first_->image(),
+ &exceptionInfo );
+ unlinkImages( first_, last_ );
+ mosaicImage_->replaceImage( image );
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ // Quantize colors in images using current quantization settings
+ // Set measureError_ to true in order to measure quantization error
+ template <class InputIterator>
+ void quantizeImages( InputIterator first_,
+ InputIterator last_,
+ bool measureError_ = false ) {
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+
+ linkImages( first_, last_ );
+
+ MagickLib::QuantizeImages( first_->quantizeInfo(),
+ first_->image() );
+ MagickLib::GetImageException( first_->image(), &exceptionInfo );
+ if ( exceptionInfo.severity > MagickLib::UndefinedException )
+ {
+ unlinkImages( first_, last_ );
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+ MagickLib::Image* image = first_->image();
+ while( image != 0 )
+ {
+ // Calculate quantization error
+ if ( measureError_ )
+ MagickLib::GetImageQuantizeError( image );
+
+ // Update DirectClass representation of pixels
+ MagickLib::SyncImage( image );
+
+ // Next image
+ image=image->next;
+ }
+
+ unlinkImages( first_, last_ );
+ }
+
+ // Read images into existing container (appending to container)
+ // FIXME: need a way to specify options like size, depth, and density.
+ template <class Container>
+ void readImages( Container *sequence_,
+ const std::string &imageSpec_ ) {
+ MagickLib::ImageInfo *imageInfo = MagickLib::CloneImageInfo(0);
+ imageSpec_.copy( imageInfo->filename, MaxTextExtent-1 );
+ imageInfo->filename[ imageSpec_.length() ] = 0;
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image* images = MagickLib::ReadImage( imageInfo, &exceptionInfo );
+ MagickLib::DestroyImageInfo(imageInfo);
+ insertImages( sequence_, images);
+ throwException( exceptionInfo );
+ }
+ template <class Container>
+ void readImages( Container *sequence_,
+ const Blob &blob_ ) {
+ MagickLib::ImageInfo *imageInfo = MagickLib::CloneImageInfo(0);
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ MagickLib::Image *images = MagickLib::BlobToImage( imageInfo,
+ blob_.data(),
+ blob_.length(), &exceptionInfo );
+ MagickLib::DestroyImageInfo(imageInfo);
+ insertImages( sequence_, images );
+ throwException( exceptionInfo );
+ }
+
+ // Write Images
+ //
+ // If an attribute is not supported as an explicit argument
+ // (e.g. 'magick'), then the attribute must be set on the involved
+ // images in the container prior to invoking writeImages() since
+ // attributes from the individual images are the ones which are
+ // used.
+ template <class InputIterator>
+ void writeImages( InputIterator first_,
+ InputIterator last_,
+ const std::string &imageSpec_,
+ bool adjoin_ = true ) {
+
+ first_->adjoin( adjoin_ );
+
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+
+ linkImages( first_, last_ );
+ int errorStat = MagickLib::WriteImages( first_->constImageInfo(),
+ first_->image(),
+ imageSpec_.c_str(),
+ &exceptionInfo );
+ unlinkImages( first_, last_ );
+
+ if ( errorStat != false )
+ {
+ MagickLib::DestroyExceptionInfo( &exceptionInfo );
+ return;
+ }
+
+ throwException( exceptionInfo, first_->quiet() );
+ }
+ // Write images to BLOB
+ //
+ // If an attribute is not supported as an explicit argument
+ // (e.g. 'magick'), then the attribute must be set on the involved
+ // images in the container prior to invoking writeImages() since
+ // attributes from the individual images are the ones which are
+ // used.
+ template <class InputIterator>
+ void writeImages( InputIterator first_,
+ InputIterator last_,
+ Blob *blob_,
+ bool adjoin_ = true) {
+
+ first_->adjoin( adjoin_ );
+
+ linkImages( first_, last_ );
+
+ MagickLib::ExceptionInfo exceptionInfo;
+ MagickLib::GetExceptionInfo( &exceptionInfo );
+ size_t length = 2048; // Efficient size for small images
+ void* data = MagickLib::ImageToBlob( first_->imageInfo(),
+ first_->image(),
+ &length,
+ &exceptionInfo);
+ blob_->updateNoCopy( data, length, Magick::Blob::MallocAllocator );
+
+ unlinkImages( first_, last_ );
+
+ throwException( exceptionInfo, first_->quiet() );
+ }
+
+} // namespace Magick
+
+#endif // Magick_STL_header
diff --git a/Magick++/lib/Magick++/Thread.h b/Magick++/lib/Magick++/Thread.h
new file mode 100644
index 0000000..65af5c6
--- /dev/null
+++ b/Magick++/lib/Magick++/Thread.h
@@ -0,0 +1,100 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2003
+//
+// Definition of types and classes to support threads
+//
+// This class is a Magick++ implementation class and is not intended
+// for use by end-users.
+//
+#if !defined (Magick_Thread_header)
+#define Magick_Thread_header
+
+#include "Magick++/Include.h"
+
+#if defined(_VISUALC_)
+#include <windows.h>
+#if defined(_MT)
+struct win32_mutex {
+ HANDLE id;
+};
+
+// This is a binary semphore -- increase for a counting semaphore
+#define MAXSEMLEN 1
+#endif // defined(_MT)
+#endif // defined(_VISUALC_)
+
+#if defined(HasPTHREADS)
+# include <pthread.h>
+#endif // defined(HasPTHREADS)
+
+namespace Magick
+{
+ // Mutex lock wrapper
+ class MagickDLLDecl MutexLock
+ {
+ public:
+ // Default constructor
+ MutexLock(void);
+
+ // Destructor
+ ~MutexLock(void);
+
+ // Lock mutex
+ void lock(void);
+
+ // Unlock mutex
+ void unlock(void);
+
+ private:
+
+ // Don't support copy constructor
+ MutexLock ( const MutexLock& original_ );
+
+ // Don't support assignment
+ MutexLock& operator = ( const MutexLock& original_ );
+
+#if defined(HasPTHREADS)
+ pthread_mutex_t _mutex;
+#endif
+#if defined(_MT) && defined(_VISUALC_)
+ win32_mutex _mutex;
+#endif
+ };
+
+ // Lock mutex while object is in scope
+ class MagickDLLDecl Lock
+ {
+ public:
+ // Construct with mutex lock (locks mutex)
+ Lock( MutexLock *mutexLock_ );
+
+ // Destrutor (unlocks mutex)
+ ~Lock( void );
+ private:
+
+ // Don't support copy constructor
+ Lock ( const Lock& original_ );
+
+ // Don't support assignment
+ Lock& operator = ( const Lock& original_ );
+
+ MutexLock* _mutexLock;
+ };
+}
+
+// Construct with mutex lock (locks mutex)
+inline Magick::Lock::Lock( MutexLock *mutexLock_ )
+ : _mutexLock(mutexLock_)
+{
+ _mutexLock->lock();
+}
+
+// Destrutor (unlocks mutex)
+inline Magick::Lock::~Lock( void )
+{
+ _mutexLock->unlock();
+ _mutexLock=0;
+}
+
+#endif // Magick_Thread_header
diff --git a/Magick++/lib/Magick++/TypeMetric.h b/Magick++/lib/Magick++/TypeMetric.h
new file mode 100644
index 0000000..4e5f63e
--- /dev/null
+++ b/Magick++/lib/Magick++/TypeMetric.h
@@ -0,0 +1,57 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 2001, 2002
+//
+// TypeMetric Definition
+//
+// Container for font type metrics
+//
+
+#if !defined (Magick_TypeMetric_header)
+#define Magick_TypeMetric_header
+
+#include "Magick++/Include.h"
+
+namespace Magick
+{
+ class MagickDLLDecl TypeMetric
+ {
+ friend class Image;
+ public:
+
+ TypeMetric ( void );
+ ~TypeMetric ( void );
+
+ // Ascent, the distance in pixels from the text baseline to the
+ // highest/upper grid coordinate used to place an outline point.
+ double ascent ( void ) const;
+
+ // Descent, the distance in pixels from the baseline to the lowest
+ // grid coordinate used to place an outline point. Always a
+ // negative value.
+ double descent ( void ) const;
+
+ // Text width in pixels.
+ double textWidth ( void ) const;
+
+ // Text height in pixels.
+ double textHeight ( void ) const;
+
+ // Maximum horizontal advance in pixels.
+ double maxHorizontalAdvance ( void ) const;
+
+ //
+ // Public methods below this point are for Magick++ use only.
+ //
+
+ private:
+ MagickLib::TypeMetric _typeMetric;
+ };
+} // namespace Magick
+
+//
+// Inlines
+//
+
+
+#endif // Magick_TypeMetric_header
diff --git a/Magick++/lib/Montage.cpp b/Magick++/lib/Montage.cpp
new file mode 100644
index 0000000..ff6caeb
--- /dev/null
+++ b/Magick++/lib/Montage.cpp
@@ -0,0 +1,133 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
+//
+// Implementation of Montage
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <string>
+#include <string.h>
+
+#include "Magick++/Montage.h"
+#include "Magick++/Functions.h"
+
+Magick::Montage::Montage ( void )
+ : _backgroundColor("#ffffff"),
+ _compose(OverCompositeOp),
+ _fileName(),
+ _fill("#000000ff"),
+ _font(),
+ _geometry("120x120+4+3>"),
+ _gravity(CenterGravity),
+ _label(),
+ _pointSize(12),
+ _shadow(false),
+ _stroke(),
+ _texture(),
+ _tile("6x4"),
+ _title(),
+ _transparentColor()
+{
+}
+
+Magick::Montage::~Montage( void )
+{
+ // Nothing to do
+}
+
+Magick::MontageFramed::MontageFramed ( void )
+ : _borderColor("#dfdfdf"),
+ _borderWidth(0),
+ _frame(),
+ _matteColor("#bdbdbd")
+{
+}
+
+/* virtual */ Magick::MontageFramed::~MontageFramed ( void )
+{
+ // Nothing to do
+}
+
+void Magick::Montage::updateMontageInfo ( MontageInfo &montageInfo_ ) const
+{
+
+ memset(&montageInfo_,0,sizeof(MontageInfo));
+
+ // background_color
+ montageInfo_.background_color = _backgroundColor;
+ // border_color
+ montageInfo_.border_color = Color();
+ // border_width
+ montageInfo_.border_width = 0;
+ // filename
+ _fileName.copy( montageInfo_.filename, MaxTextExtent - 1 );
+ montageInfo_.filename[ _fileName.length() ] = 0; // null terminate
+ // fill
+ montageInfo_.fill = _fill;
+ // font
+ if ( _font.length() != 0 )
+ Magick::CloneString( &montageInfo_.font, _font );
+ else
+ MagickFreeMemory(montageInfo_.font);
+ // frame
+ MagickFreeMemory(montageInfo_.frame);
+ // geometry
+ if ( _geometry.isValid() )
+ Magick::CloneString( &montageInfo_.geometry, _geometry );
+ else
+ MagickFreeMemory(montageInfo_.geometry);
+ // gravity
+ montageInfo_.gravity = _gravity;
+ // matte_color
+ montageInfo_.matte_color = Color();
+ // pointsize
+ montageInfo_.pointsize = _pointSize;
+ // shadow
+ montageInfo_.shadow = static_cast<int>(_shadow);
+ // signature (validity stamp)
+ montageInfo_.signature = MagickSignature;
+ // stroke
+ montageInfo_.stroke = _stroke;
+ // texture
+ if ( _texture.length() != 0 )
+ Magick::CloneString( &montageInfo_.texture, _texture );
+ else
+ MagickFreeMemory(montageInfo_.texture);
+ // tile
+ if ( _tile.isValid() )
+ Magick::CloneString( &montageInfo_.tile, _tile );
+ else
+ MagickFreeMemory(montageInfo_.tile);
+ // title
+ if ( _title.length() != 0 )
+ Magick::CloneString( &montageInfo_.title, _title );
+ else
+ MagickFreeMemory(montageInfo_.title);
+}
+
+//
+// Implementation of MontageFramed
+//
+
+/* virtual */ void
+Magick::MontageFramed::updateMontageInfo ( MontageInfo &montageInfo_ ) const
+{
+ // Do base updates
+ Montage::updateMontageInfo ( montageInfo_ );
+
+ // border_color
+ montageInfo_.border_color = _borderColor;
+ // border_width
+ montageInfo_.border_width = _borderWidth;
+ // frame
+ if ( _frame.isValid() )
+ Magick::CloneString( &montageInfo_.frame, _frame );
+ else
+ MagickFreeMemory(montageInfo_.frame);
+ // matte_color
+ montageInfo_.matte_color = _matteColor;
+}
diff --git a/Magick++/lib/Options.cpp b/Magick++/lib/Options.cpp
new file mode 100644
index 0000000..bd4dd44
--- /dev/null
+++ b/Magick++/lib/Options.cpp
@@ -0,0 +1,852 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
+//
+// Implementation of Options
+//
+// A wrapper around DrawInfo, ImageInfo, and QuantizeInfo
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <string>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include "Magick++/Options.h"
+#include "Magick++/Functions.h"
+#include "Magick++/Exception.h"
+
+#define DegreesToRadians(x) ((x)*3.14159265358979323846/180.0)
+
+// Constructor
+Magick::Options::Options( void )
+ : _imageInfo(MagickAllocateMemory(ImageInfo*,sizeof(ImageInfo))),
+ _quantizeInfo(MagickAllocateMemory(QuantizeInfo*,sizeof(QuantizeInfo))),
+ _drawInfo(MagickAllocateMemory(DrawInfo*,sizeof(DrawInfo))),
+ _quiet(false)
+{
+ // Initialize image info with defaults
+ GetImageInfo( _imageInfo );
+
+ // Initialize quantization info
+ GetQuantizeInfo( _quantizeInfo );
+
+ // Initialize drawing info
+ GetDrawInfo( _imageInfo, _drawInfo );
+}
+
+// Copy constructor
+Magick::Options::Options( const Magick::Options& options_ )
+ : _imageInfo(CloneImageInfo( options_._imageInfo )),
+ _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)),
+ _drawInfo(CloneDrawInfo(_imageInfo, options_._drawInfo)),
+ _quiet(options_._quiet)
+{
+}
+
+// Construct using raw structures
+Magick::Options::Options( const MagickLib::ImageInfo* imageInfo_,
+ const MagickLib::QuantizeInfo* quantizeInfo_,
+ const MagickLib::DrawInfo* drawInfo_ )
+: _imageInfo(0),
+ _quantizeInfo(0),
+ _drawInfo(0),
+ _quiet(false)
+{
+ _imageInfo = CloneImageInfo(imageInfo_);
+ _quantizeInfo = CloneQuantizeInfo(quantizeInfo_);
+ _drawInfo = CloneDrawInfo(imageInfo_,drawInfo_);
+}
+
+// Destructor
+Magick::Options::~Options()
+{
+ // Destroy image info
+ DestroyImageInfo( _imageInfo );
+ _imageInfo=0;
+
+ // Destroy quantization info
+ DestroyQuantizeInfo( _quantizeInfo );
+ _quantizeInfo=0;
+
+ // Destroy drawing info
+ DestroyDrawInfo( _drawInfo );
+ _drawInfo=0;
+}
+
+/*
+ * Methods for setting image attributes
+ *
+ */
+
+// Anti-alias Postscript and TrueType fonts (default true)
+void Magick::Options::antiAlias( bool flag_ )
+{
+ _drawInfo->text_antialias = static_cast<unsigned int>( flag_ );
+}
+bool Magick::Options::antiAlias( void ) const
+{
+ return static_cast<bool>(_drawInfo->text_antialias);
+}
+
+void Magick::Options::adjoin ( bool flag_ )
+{
+ _imageInfo->adjoin = static_cast<unsigned int>(flag_);
+}
+bool Magick::Options::adjoin ( void ) const
+{
+ return static_cast<bool>(_imageInfo->adjoin);
+}
+
+void Magick::Options::backgroundColor ( const Magick::Color &color_ )
+{
+ _imageInfo->background_color = color_;
+}
+Magick::Color Magick::Options::backgroundColor ( void ) const
+{
+ return Magick::Color( _imageInfo->background_color );
+}
+
+void Magick::Options::backgroundTexture ( const std::string &backgroundTexture_ )
+{
+ if ( backgroundTexture_.length() == 0 )
+ {
+ MagickFreeMemory(_imageInfo->texture);
+ }
+ else
+ {
+ Magick::CloneString( &_imageInfo->texture, backgroundTexture_ );
+ }
+}
+std::string Magick::Options::backgroundTexture ( void ) const
+{
+ if ( _imageInfo->texture )
+ return std::string( _imageInfo->texture );
+ else
+ return std::string();
+}
+
+void Magick::Options::borderColor ( const Color &color_ )
+{
+ _imageInfo->border_color = color_;
+ _drawInfo->border_color = color_;
+}
+Magick::Color Magick::Options::borderColor ( void ) const
+{
+ return Magick::Color( _imageInfo->border_color );
+}
+
+// Text bounding-box base color
+void Magick::Options::boxColor ( const Magick::Color &boxColor_ )
+{
+ _drawInfo->undercolor = boxColor_;
+}
+Magick::Color Magick::Options::boxColor ( void ) const
+{
+ return Magick::Color( _drawInfo->undercolor );
+}
+
+void Magick::Options::compressType ( CompressionType compressType_ )
+{
+ _imageInfo->compression = compressType_;
+}
+Magick::CompressionType Magick::Options::compressType ( void ) const
+{
+ return static_cast<Magick::CompressionType>(_imageInfo->compression);
+}
+
+void Magick::Options::colorFuzz ( double fuzz_ )
+{
+ _imageInfo->fuzz = fuzz_;
+}
+double Magick::Options::colorFuzz ( void ) const
+{
+ return _imageInfo->fuzz;
+}
+
+// Enable printing of debug messages from ImageMagick
+void Magick::Options::debug ( bool flag_ )
+{
+ if(flag_)
+ {
+ SetLogEventMask("All");
+ }
+ else
+ {
+ SetLogEventMask("None");
+ }
+}
+bool Magick::Options::debug ( void ) const
+{
+ if( IsEventLogging() )
+ {
+ return true;
+ }
+ return false;
+}
+
+void Magick::Options::density ( const Magick::Geometry &density_ )
+{
+ if ( !density_.isValid() )
+ {
+ MagickFreeMemory(_imageInfo->density);
+ }
+ else
+ {
+ Magick::CloneString( &_imageInfo->density, density_ );
+ }
+}
+Magick::Geometry Magick::Options::density ( void ) const
+{
+ if ( _imageInfo->density )
+ return Geometry( _imageInfo->density );
+
+ return Geometry();
+}
+
+void Magick::Options::depth ( unsigned int depth_ )
+{
+ _imageInfo->depth = depth_;
+}
+unsigned int Magick::Options::depth ( void ) const
+{
+ return _imageInfo->depth;
+}
+
+// Endianness (little like Intel or big like SPARC) for image
+// formats which support endian-specific options.
+void Magick::Options::endian ( Magick::EndianType endian_ )
+{
+ _imageInfo->endian = endian_;
+}
+Magick::EndianType Magick::Options::endian ( void ) const
+{
+ return _imageInfo->endian;
+}
+
+void Magick::Options::fileName ( const std::string &fileName_ )
+{
+ fileName_.copy( _imageInfo->filename, MaxTextExtent-1 );
+ _imageInfo->filename[ fileName_.length() ] = 0;
+}
+std::string Magick::Options::fileName ( void ) const
+{
+ return std::string( _imageInfo->filename );
+}
+
+// Color to use when drawing inside an object
+void Magick::Options::fillColor ( const Magick::Color &fillColor_ )
+{
+ _drawInfo->fill = fillColor_;
+}
+Magick::Color Magick::Options::fillColor ( void ) const
+{
+ return _drawInfo->fill;
+}
+
+// Pattern image to use when filling objects
+void Magick::Options::fillPattern ( const MagickLib::Image *fillPattern_ )
+{
+ if ( _drawInfo->fill_pattern )
+ {
+ DestroyImageList( _drawInfo->fill_pattern );
+ _drawInfo->fill_pattern = 0;
+ }
+
+ if ( fillPattern_ )
+ {
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ _drawInfo->fill_pattern =
+ CloneImage( const_cast<MagickLib::Image*>(fillPattern_),
+ 0,
+ 0,
+ static_cast<int>(true),
+ &exceptionInfo );
+ throwException( exceptionInfo, _quiet );
+ }
+}
+const MagickLib::Image* Magick::Options::fillPattern ( void ) const
+{
+ return _drawInfo->fill_pattern;
+}
+
+// Rule to use when filling drawn objects
+void Magick::Options::fillRule ( const Magick::FillRule &fillRule_ )
+{
+ _drawInfo->fill_rule = fillRule_;
+}
+Magick::FillRule Magick::Options::fillRule ( void ) const
+{
+ return _drawInfo->fill_rule;
+}
+
+void Magick::Options::font ( const std::string &font_ )
+{
+ if ( font_.length() == 0 )
+ {
+ MagickFreeMemory(_imageInfo->font);
+ MagickFreeMemory(_drawInfo->font);
+ }
+ else
+ {
+ Magick::CloneString( &_imageInfo->font, font_ );
+ Magick::CloneString( &_drawInfo->font, font_ );
+ }
+}
+std::string Magick::Options::font ( void ) const
+{
+ if ( _imageInfo->font )
+ return std::string( _imageInfo->font );
+
+ return std::string();
+}
+
+void Magick::Options::fontPointsize ( double pointSize_ )
+{
+ _imageInfo->pointsize = pointSize_;
+ _drawInfo->pointsize = pointSize_;
+}
+double Magick::Options::fontPointsize ( void ) const
+{
+ return _imageInfo->pointsize;
+}
+
+std::string Magick::Options::format ( void ) const
+{
+ ExceptionInfo exception;
+
+ const MagickInfo * magick_info = 0;
+ GetExceptionInfo(&exception);
+ if ( *_imageInfo->magick != '\0' )
+ magick_info = GetMagickInfo( _imageInfo->magick , &exception);
+
+ if (( magick_info != 0 ) &&
+ ( *magick_info->description != '\0' ))
+ return std::string( magick_info->description );
+
+ return std::string();
+}
+
+void Magick::Options::interlaceType ( Magick::InterlaceType interlace_ )
+{
+ _imageInfo->interlace = interlace_;
+}
+Magick::InterlaceType Magick::Options::interlaceType ( void ) const
+{
+ return static_cast<Magick::InterlaceType>(_imageInfo->interlace);
+}
+
+void Magick::Options::magick ( const std::string &magick_ )
+{
+ ExceptionInfo exception;
+
+ FormatString( _imageInfo->filename, "%.1024s:", magick_.c_str() );
+ GetExceptionInfo(&exception);
+ SetImageInfo( _imageInfo, 1, &exception);
+ if ( _imageInfo->magick[0] == '\0' )
+ throwExceptionExplicit( OptionWarning,
+ "Unrecognized image format",
+ magick_.c_str() );
+}
+std::string Magick::Options::magick ( void ) const
+{
+ if ( _imageInfo->magick[0] != '\0' )
+ return std::string( _imageInfo->magick );
+
+ return std::string();
+}
+
+void Magick::Options::matteColor ( const Magick::Color &matteColor_ )
+{
+ _imageInfo->matte_color = matteColor_;
+}
+Magick::Color Magick::Options::matteColor ( void ) const
+{
+ return Magick::Color( _imageInfo->matte_color );
+}
+
+void Magick::Options::monochrome ( bool monochromeFlag_ )
+{
+ _imageInfo->monochrome = monochromeFlag_;
+}
+bool Magick::Options::monochrome ( void ) const
+{
+ return static_cast<bool>(_imageInfo->monochrome);
+}
+
+void Magick::Options::page ( const Magick::Geometry &pageSize_ )
+{
+ if ( !pageSize_.isValid() )
+ {
+ MagickFreeMemory(_imageInfo->page);
+ }
+ else
+ {
+ Magick::CloneString( &_imageInfo->page, pageSize_ );
+ }
+}
+Magick::Geometry Magick::Options::page ( void ) const
+{
+ if ( _imageInfo->page )
+ return Geometry( _imageInfo->page );
+
+ return Geometry();
+}
+
+void Magick::Options::quality ( unsigned int quality_ )
+{
+ _imageInfo->quality = quality_;
+}
+unsigned int Magick::Options::quality ( void ) const
+{
+ return _imageInfo->quality;
+}
+
+void Magick::Options::quantizeColors ( unsigned int colors_ )
+{
+ _quantizeInfo->number_colors = colors_;
+}
+unsigned int Magick::Options::quantizeColors ( void ) const
+{
+ return _quantizeInfo->number_colors;
+}
+
+void Magick::Options::quantizeColorSpace ( Magick::ColorspaceType colorSpace_ )
+{
+ _quantizeInfo->colorspace = colorSpace_;
+}
+Magick::ColorspaceType Magick::Options::quantizeColorSpace ( void ) const
+{
+ return static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace);
+}
+
+void Magick::Options::quantizeDither ( bool ditherFlag_ )
+{
+ _imageInfo->dither = ditherFlag_;
+ _quantizeInfo->dither = ditherFlag_;
+}
+bool Magick::Options::quantizeDither ( void ) const
+{
+ return static_cast<bool>(_imageInfo->dither);
+}
+
+void Magick::Options::quantizeTreeDepth ( unsigned int treeDepth_ )
+{
+ _quantizeInfo->tree_depth = treeDepth_;
+}
+unsigned int Magick::Options::quantizeTreeDepth ( void ) const
+{
+ return _quantizeInfo->tree_depth;
+}
+
+void Magick::Options::quiet(const bool quiet_)
+{
+ _quiet=quiet_;
+}
+
+bool Magick::Options::quiet(void) const
+{
+ return(_quiet);
+}
+
+void Magick::Options::resolutionUnits ( Magick::ResolutionType resolutionUnits_ )
+{
+ _imageInfo->units = resolutionUnits_;
+}
+Magick::ResolutionType Magick::Options::resolutionUnits ( void ) const
+{
+ return static_cast<Magick::ResolutionType>(_imageInfo->units);
+}
+
+void Magick::Options::size ( const Geometry &geometry_ )
+{
+ MagickFreeMemory(_imageInfo->size);
+
+ if ( geometry_.isValid() )
+ Magick::CloneString( &_imageInfo->size, geometry_ );
+}
+Magick::Geometry Magick::Options::size ( void ) const
+{
+ if ( _imageInfo->size )
+ return Geometry( _imageInfo->size );
+
+ return Geometry();
+}
+
+void Magick::Options::strokeAntiAlias( bool flag_ )
+{
+ flag_ ? _drawInfo->stroke_antialias=1 : _drawInfo->stroke_antialias=0;
+}
+bool Magick::Options::strokeAntiAlias( void ) const
+{
+ return (_drawInfo->stroke_antialias != 0 ? true : false);
+}
+
+// Color to use when drawing object outlines
+void Magick::Options::strokeColor ( const Magick::Color &strokeColor_ )
+{
+ _drawInfo->stroke = strokeColor_;
+}
+Magick::Color Magick::Options::strokeColor ( void ) const
+{
+ return _drawInfo->stroke;
+}
+
+void Magick::Options::strokeDashArray ( const double* strokeDashArray_ )
+{
+ MagickFreeMemory(_drawInfo->dash_pattern);
+
+ if(strokeDashArray_)
+ {
+ // Count elements in dash array
+ unsigned int x;
+ for (x=0; strokeDashArray_[x]; x++) {};
+ // Allocate elements
+ _drawInfo->dash_pattern = MagickAllocateMemory(double*,(x+1)*sizeof(double));
+ // Copy elements
+ memcpy(_drawInfo->dash_pattern,strokeDashArray_,
+ (x+1)*sizeof(double));
+ }
+}
+const double* Magick::Options::strokeDashArray ( void ) const
+{
+ return _drawInfo->dash_pattern;
+}
+
+void Magick::Options::strokeDashOffset ( double strokeDashOffset_ )
+{
+ _drawInfo->dash_offset = strokeDashOffset_;
+}
+double Magick::Options::strokeDashOffset ( void ) const
+{
+ return _drawInfo->dash_offset;
+}
+
+// Specify the shape to be used at the end of open subpaths when they
+// are stroked. Values of LineCap are ButtCap, RoundCap, and
+// SquareCap.
+void Magick::Options::strokeLineCap ( Magick::LineCap lineCap_ )
+{
+ _drawInfo->linecap = lineCap_;
+}
+Magick::LineCap Magick::Options::strokeLineCap ( void ) const
+{
+ return _drawInfo->linecap;
+}
+
+// Specify the shape to be used at the corners of paths (or other
+// vector shapes) when they are stroked.
+void Magick::Options::strokeLineJoin ( Magick::LineJoin lineJoin_ )
+{
+ _drawInfo->linejoin = lineJoin_;
+}
+Magick::LineJoin Magick::Options::strokeLineJoin ( void ) const
+{
+ return _drawInfo->linejoin;
+}
+
+// miterLimit for drawing lines, circles, ellipses, etc.
+void Magick::Options::strokeMiterLimit ( unsigned int miterLimit_ )
+{
+ _drawInfo->miterlimit = miterLimit_;
+}
+unsigned int Magick::Options::strokeMiterLimit ( void ) const
+{
+ return _drawInfo->miterlimit;
+}
+
+// Pattern image to use for stroked outlines
+void Magick::Options::strokePattern ( const MagickLib::Image *strokePattern_ )
+{
+ if ( _drawInfo->stroke_pattern )
+ {
+ DestroyImageList( _drawInfo->stroke_pattern );
+ _drawInfo->stroke_pattern = 0;
+ }
+
+ if ( strokePattern_ )
+ {
+ ExceptionInfo exceptionInfo;
+ GetExceptionInfo( &exceptionInfo );
+ _drawInfo->stroke_pattern =
+ CloneImage( const_cast<MagickLib::Image*>(strokePattern_),
+ 0,
+ 0,
+ static_cast<int>(true),
+ &exceptionInfo );
+ throwException( exceptionInfo, _quiet );
+ }
+}
+const MagickLib::Image* Magick::Options::strokePattern ( void ) const
+{
+ return _drawInfo->stroke_pattern;
+}
+
+// Stroke width for drawing lines, circles, ellipses, etc.
+void Magick::Options::strokeWidth ( double strokeWidth_ )
+{
+ _drawInfo->stroke_width = strokeWidth_;
+}
+double Magick::Options::strokeWidth ( void ) const
+{
+ return _drawInfo->stroke_width;
+}
+
+void Magick::Options::subImage ( unsigned int subImage_ )
+{
+ _imageInfo->subimage = subImage_;
+}
+unsigned int Magick::Options::subImage ( void ) const
+{
+ return _imageInfo->subimage;
+}
+
+void Magick::Options::subRange ( unsigned int subRange_ )
+{
+ _imageInfo->subrange = subRange_;
+}
+unsigned int Magick::Options::subRange ( void ) const
+{
+ return _imageInfo->subrange;
+}
+
+// Annotation text encoding (e.g. "UTF-16")
+void Magick::Options::textEncoding ( const std::string &encoding_ )
+{
+ CloneString(&_drawInfo->encoding, encoding_.c_str());
+}
+std::string Magick::Options::textEncoding ( void ) const
+{
+ if ( _drawInfo->encoding && *_drawInfo->encoding )
+ return std::string( _drawInfo->encoding );
+
+ return std::string();
+}
+
+void Magick::Options::tileName ( const std::string &tileName_ )
+{
+ if ( tileName_.length() == 0 )
+ {
+ MagickFreeMemory(_imageInfo->tile);
+ }
+ else
+ {
+ Magick::CloneString( &_imageInfo->tile, tileName_ );
+ }
+}
+std::string Magick::Options::tileName ( void ) const
+{
+ if ( _imageInfo->tile )
+ return std::string( _imageInfo->tile );
+ return std::string();
+}
+
+// Image representation type
+void Magick::Options::type ( const Magick::ImageType type_ )
+{
+ _imageInfo->type = type_;
+}
+Magick::ImageType Magick::Options::type ( void ) const
+{
+ return _imageInfo->type;
+}
+
+// Origin of coordinate system to use when annotating with text or drawing
+void Magick::Options::transformOrigin ( double tx_, double ty_ )
+{
+ AffineMatrix current = _drawInfo->affine;
+ AffineMatrix affine;
+ affine.sx=1.0;
+ affine.rx=0.0;
+ affine.ry=0.0;
+ affine.sy=1.0;
+ affine.tx=0.0;
+ affine.ty=0.0;
+
+ affine.tx = tx_;
+ affine.ty = ty_;
+
+ _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
+}
+
+// Reset transformation parameters to default
+void Magick::Options::transformReset ( void )
+{
+ _drawInfo->affine.sx=1.0;
+ _drawInfo->affine.rx=0.0;
+ _drawInfo->affine.ry=0.0;
+ _drawInfo->affine.sy=1.0;
+ _drawInfo->affine.tx=0.0;
+ _drawInfo->affine.ty=0.0;
+}
+
+// Rotation to use when annotating with text or drawing
+void Magick::Options::transformRotation ( double angle_ )
+{
+ AffineMatrix current = _drawInfo->affine;
+ AffineMatrix affine;
+ affine.sx=1.0;
+ affine.rx=0.0;
+ affine.ry=0.0;
+ affine.sy=1.0;
+ affine.tx=0.0;
+ affine.ty=0.0;
+
+ affine.sx=cos(DegreesToRadians(fmod(angle_,360.0)));
+ affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
+ affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
+ affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
+
+ _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
+}
+
+// Scale to use when annotating with text or drawing
+void Magick::Options::transformScale ( double sx_, double sy_ )
+{
+ AffineMatrix current = _drawInfo->affine;
+ AffineMatrix affine;
+ affine.sx=1.0;
+ affine.rx=0.0;
+ affine.ry=0.0;
+ affine.sy=1.0;
+ affine.tx=0.0;
+ affine.ty=0.0;
+
+ affine.sx = sx_;
+ affine.sy = sy_;
+
+ _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
+}
+
+// Skew to use in X axis when annotating with text or drawing
+void Magick::Options::transformSkewX ( double skewx_ )
+{
+ AffineMatrix current = _drawInfo->affine;
+ AffineMatrix affine;
+ affine.sx=1.0;
+ affine.rx=0.0;
+ affine.ry=0.0;
+ affine.sy=1.0;
+ affine.tx=0.0;
+ affine.ty=0.0;
+
+ affine.sx=1.0;
+ affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
+ affine.sy=1.0;
+
+ _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
+}
+
+// Skew to use in Y axis when annotating with text or drawing
+void Magick::Options::transformSkewY ( double skewy_ )
+{
+ AffineMatrix current = _drawInfo->affine;
+ AffineMatrix affine;
+ affine.sx=1.0;
+ affine.rx=0.0;
+ affine.ry=0.0;
+ affine.sy=1.0;
+ affine.tx=0.0;
+ affine.ty=0.0;
+
+ affine.sx=1.0;
+ affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
+ affine.sy=1.0;
+
+ _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
+}
+
+void Magick::Options::verbose ( bool verboseFlag_ )
+{
+ _imageInfo->verbose = verboseFlag_;
+}
+bool Magick::Options::verbose ( void ) const
+{
+ return static_cast<bool>(_imageInfo->verbose);
+}
+
+void Magick::Options::view ( const std::string &view_ )
+{
+ if ( view_.length() == 0 )
+ {
+ MagickFreeMemory(_imageInfo->view);
+ }
+ else
+ {
+ Magick::CloneString( &_imageInfo->view, view_ );
+ }
+}
+std::string Magick::Options::view ( void ) const
+{
+ if ( _imageInfo->view )
+ return std::string( _imageInfo->view );
+
+ return std::string();
+}
+
+void Magick::Options::x11Display ( const std::string &display_ )
+{
+ if ( display_.length() == 0 )
+ {
+ MagickFreeMemory(_imageInfo->server_name);
+ }
+ else
+ {
+ Magick::CloneString( &_imageInfo->server_name, display_ );
+ }
+}
+std::string Magick::Options::x11Display ( void ) const
+{
+ if ( _imageInfo->server_name )
+ return std::string( _imageInfo->server_name );
+
+ return std::string();
+}
+
+//
+// Internal implementation methods. Please do not use.
+//
+
+MagickLib::DrawInfo * Magick::Options::drawInfo( void )
+{
+ return _drawInfo;
+}
+
+MagickLib::ImageInfo * Magick::Options::imageInfo( void )
+{
+ return _imageInfo;
+}
+
+MagickLib::QuantizeInfo * Magick::Options::quantizeInfo( void )
+{
+ return _quantizeInfo;
+}
diff --git a/Magick++/lib/Pixels.cpp b/Magick++/lib/Pixels.cpp
new file mode 100644
index 0000000..875afea
--- /dev/null
+++ b/Magick++/lib/Pixels.cpp
@@ -0,0 +1,123 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003, 2008
+//
+// Pixels Implementation
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Include.h"
+#include <string> // This is here to compile with Visual C++
+#include "Magick++/Thread.h"
+#include "Magick++/Exception.h"
+#include "Magick++/Pixels.h"
+
+namespace Magick
+{
+
+
+}
+
+// Construct pixel view using specified image.
+Magick::Pixels::Pixels( Magick::Image &image_ )
+ : _image(image_),
+ _view(OpenCacheView(_image.image())),
+ _x(0),
+ _y(0),
+ _columns(0),
+ _rows(0)
+{
+ GetExceptionInfo( &_exception );
+
+ if (!_view)
+ _image.throwImageException();
+}
+
+// Destroy pixel view
+Magick::Pixels::~Pixels( void )
+{
+ if ( _view )
+ CloseCacheView( _view );
+}
+
+// Transfer pixels from the image to the pixel view as defined by
+// the specified region. Modified pixels may be subsequently
+// transferred back to the image via sync.
+Magick::PixelPacket* Magick::Pixels::get ( const int x_,
+ const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+{
+ _x = x_;
+ _y = y_;
+ _columns = columns_;
+ _rows = rows_;
+
+ PixelPacket* pixels = GetCacheViewPixels( _view, x_, y_, columns_, rows_,
+ &_exception );
+ if ( !pixels )
+ throwException( _exception, _image.quiet() );
+
+ return pixels;
+}
+
+// Transfer read-only pixels from the image to the pixel view as
+// defined by the specified region.
+const Magick::PixelPacket* Magick::Pixels::getConst ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+{
+ _x = x_;
+ _y = y_;
+ _columns = columns_;
+ _rows = rows_;
+
+ const PixelPacket* pixels =
+ AcquireCacheViewPixels(_view, x_, y_, columns_, rows_, &_exception );
+
+ if ( !pixels )
+ throwException( _exception, _image.quiet() );
+
+ return pixels;
+}
+
+// Transfers the image view pixels to the image.
+void Magick::Pixels::sync ( void )
+{
+ if( !SyncCacheViewPixels( _view, &_exception ) )
+ throwException( _exception, _image.quiet() );
+}
+
+// Allocate a pixel view region to store image pixels as defined
+// by the region rectangle. This area is subsequently transferred
+// from the pixel view to the image via 'sync'.
+Magick::PixelPacket* Magick::Pixels::set ( const int x_,
+ const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+{
+ _x = x_;
+ _y = y_;
+ _columns = columns_;
+ _rows = rows_;
+
+ PixelPacket* pixels = SetCacheViewPixels( _view, static_cast<long>(x_), static_cast<long>(y_),
+ columns_, rows_ , &_exception);
+ if ( !pixels )
+ throwException( _exception, _image.quiet() );
+
+ return pixels;
+}
+
+// Return pixel colormap index array
+Magick::IndexPacket* Magick::Pixels::indexes ( void )
+{
+ IndexPacket* pixel_indexes = GetCacheViewIndexes( _view );
+
+ if ( !pixel_indexes )
+ _image.throwImageException();
+
+ return pixel_indexes;
+}
diff --git a/Magick++/lib/STL.cpp b/Magick++/lib/STL.cpp
new file mode 100644
index 0000000..f4a122d
--- /dev/null
+++ b/Magick++/lib/STL.cpp
@@ -0,0 +1,1614 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999 - 2015
+//
+// Implementation of STL classes and functions
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include <Magick++/Image.h>
+#include <Magick++/STL.h>
+
+// Local adaptive threshold image
+Magick::adaptiveThresholdImage::adaptiveThresholdImage( const unsigned int width_,
+ const unsigned int height_,
+ const double offset_ )
+ : _width(width_),
+ _height(height_),
+ _offset(offset_)
+{
+}
+void Magick::adaptiveThresholdImage::operator()( Magick::Image &image_ ) const
+{
+ image_.adaptiveThreshold( _width, _height, _offset );
+}
+
+// Add noise to image with specified noise type
+Magick::addNoiseImage::addNoiseImage( Magick::NoiseType noiseType_ )
+ : _noiseType( noiseType_ )
+{
+}
+void Magick::addNoiseImage::operator()( Magick::Image &image_ ) const
+{
+ image_.addNoise( _noiseType );
+}
+
+// Transform image by specified affine (or free transform) matrix.
+Magick::affineTransformImage::affineTransformImage( const DrawableAffine &affine_ )
+ : _affine( affine_ )
+{
+}
+void Magick::affineTransformImage::operator()( Magick::Image &image_ ) const
+{
+ image_.affineTransform( _affine );
+}
+
+// Annotate image (draw text on image)
+
+// Annotate using specified text, and placement location
+Magick::annotateImage::annotateImage ( const std::string &text_,
+ const Magick::Geometry &geometry_ )
+ : _text( text_ ),
+ _geometry( geometry_ ),
+ _gravity( Magick::NorthWestGravity ),
+ _degrees( 0 )
+{
+}
+// Annotate using specified text, bounding area, and placement gravity
+Magick::annotateImage::annotateImage ( const std::string &text_,
+ const Magick::Geometry &geometry_,
+ const Magick::GravityType gravity_ )
+ : _text( text_ ),
+ _geometry( geometry_ ),
+ _gravity( gravity_ ),
+ _degrees( 0 )
+{
+}
+// Annotate with text using specified text, bounding area, placement
+// gravity, and rotation.
+Magick::annotateImage::annotateImage ( const std::string &text_,
+ const Magick::Geometry &geometry_,
+ const Magick::GravityType gravity_,
+ const double degrees_ )
+ : _text( text_ ),
+ _geometry( geometry_ ),
+ _gravity( gravity_ ),
+ _degrees( degrees_ )
+{
+}
+// Annotate with text (bounding area is entire image) and placement
+// gravity.
+Magick::annotateImage::annotateImage ( const std::string &text_,
+ const Magick::GravityType gravity_ )
+ : _text( text_ ),
+ _geometry( ),
+ _gravity( gravity_ ),
+ _degrees( 0 )
+{
+}
+void Magick::annotateImage::operator()( Magick::Image &image_ ) const
+{
+ image_.annotate( _text, _geometry, _gravity, _degrees );
+}
+
+// Blur image with specified blur factor
+Magick::blurImage::blurImage( const double radius_, const double sigma_ )
+ : _radius( radius_ ),
+ _sigma( sigma_ )
+{
+}
+void Magick::blurImage::operator()( Magick::Image &image_ ) const
+{
+ image_.blur( _radius, _sigma );
+}
+
+// Border image (add border to image)
+Magick::borderImage::borderImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::borderImage::operator()( Magick::Image &image_ ) const
+{
+ image_.border( _geometry );
+}
+
+// Extract channel from image
+Magick::channelImage::channelImage( const Magick::ChannelType channel_ )
+ : _channel( channel_ )
+{
+}
+void Magick::channelImage::operator()( Magick::Image &image_ ) const
+{
+ image_.channel( _channel );
+}
+
+// Charcoal effect image (looks like charcoal sketch)
+Magick::charcoalImage::charcoalImage( const double radius_, const double sigma_ )
+ : _radius( radius_ ),
+ _sigma( sigma_ )
+{
+}
+void Magick::charcoalImage::operator()( Magick::Image &image_ ) const
+{
+ image_.charcoal( _radius, _sigma );
+}
+
+// Chop image (remove vertical or horizontal subregion of image)
+Magick::chopImage::chopImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::chopImage::operator()( Magick::Image &image_ ) const
+{
+ image_.chop( _geometry );
+}
+
+// Colorize image using pen color at specified percent opacity
+Magick::colorizeImage::colorizeImage( const unsigned int opacityRed_,
+ const unsigned int opacityGreen_,
+ const unsigned int opacityBlue_,
+ const Magick::Color &penColor_ )
+ : _opacityRed ( opacityRed_ ),
+ _opacityGreen ( opacityGreen_ ),
+ _opacityBlue ( opacityBlue_ ),
+ _penColor( penColor_ )
+{
+}
+Magick::colorizeImage::colorizeImage( const unsigned int opacity_,
+ const Magick::Color &penColor_ )
+ : _opacityRed ( opacity_ ),
+ _opacityGreen ( opacity_ ),
+ _opacityBlue ( opacity_ ),
+ _penColor( penColor_ )
+{
+}
+void Magick::colorizeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.colorize( _opacityRed, _opacityGreen, _opacityBlue, _penColor );
+}
+
+// Bake in the ASC-CDL, which is a convention for the for the exchange
+// of basic primary color grading information between for the exchange
+// of basic primary color grading information between equipment and
+// software from different manufacturers. It is a useful transform
+// for other purposes as well.
+Magick::cdlImage::cdlImage( const std::string &cdl_ )
+ : _cdl ( cdl_ )
+{
+}
+void Magick::cdlImage::operator()( Image &image_ ) const
+{
+ image_.cdl( _cdl.c_str() );
+}
+
+// Apply a color matrix to the image channels. The user supplied
+// matrix may be of order 1 to 5 (1x1 through 5x5).
+Magick::colorMatrixImage::colorMatrixImage( const unsigned int order_,
+ const double *color_matrix_ )
+ : _order( order_ ),
+ _color_matrix( color_matrix_ )
+{
+}
+void Magick::colorMatrixImage::operator()( Image &image_ ) const
+{
+ image_.colorMatrix( _order, _color_matrix );
+}
+
+// Convert the image colorspace representation
+Magick::colorSpaceImage::colorSpaceImage( Magick::ColorspaceType colorSpace_ )
+ : _colorSpace( colorSpace_ )
+{
+}
+void Magick::colorSpaceImage::operator()( Magick::Image &image_ ) const
+{
+ image_.colorSpace( _colorSpace );
+}
+
+// Comment image (add comment string to image)
+Magick::commentImage::commentImage( const std::string &comment_ )
+ : _comment( comment_ )
+{
+}
+void Magick::commentImage::operator()( Magick::Image &image_ ) const
+{
+ image_.comment( _comment );
+}
+
+// Compose an image onto another at specified offset and using
+// specified algorithm
+Magick::compositeImage::compositeImage( const Magick::Image &compositeImage_,
+ int xOffset_,
+ int yOffset_,
+ Magick::CompositeOperator compose_ )
+ : _compositeImage( compositeImage_ ),
+ _xOffset ( xOffset_ ),
+ _yOffset ( yOffset_ ),
+ _compose ( compose_ )
+{
+}
+Magick::compositeImage::compositeImage( const Magick::Image &compositeImage_,
+ const Magick::Geometry &offset_,
+ Magick::CompositeOperator compose_ )
+ : _compositeImage( compositeImage_ ),
+ _xOffset ( offset_.xOff() ),
+ _yOffset ( offset_.yOff() ),
+ _compose ( compose_ )
+{
+}
+void Magick::compositeImage::operator()( Image &image_ ) const
+{
+ image_.composite( _compositeImage, _xOffset, _yOffset, _compose );
+}
+
+// Contrast image (enhance intensity differences in image)
+Magick::contrastImage::contrastImage( const unsigned int sharpen_ )
+ : _sharpen( sharpen_ )
+{
+}
+void Magick::contrastImage::operator()( Magick::Image &image_ ) const
+{
+ image_.contrast( _sharpen );
+}
+
+// Crop image (subregion of original image)
+Magick::cropImage::cropImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::cropImage::operator()( Magick::Image &image_ ) const
+{
+ image_.crop( _geometry );
+}
+
+// Cycle image colormap
+Magick::cycleColormapImage::cycleColormapImage( const int amount_ )
+ : _amount( amount_ )
+{
+}
+void Magick::cycleColormapImage::operator()( Magick::Image &image_ ) const
+{
+ image_.cycleColormap( _amount );
+}
+
+// Despeckle image (reduce speckle noise)
+Magick::despeckleImage::despeckleImage( void )
+{
+}
+void Magick::despeckleImage::operator()( Magick::Image &image_ ) const
+{
+ image_.despeckle( );
+}
+
+// Draw on image
+Magick::drawImage::drawImage( const Magick::Drawable &drawable_ )
+ : _drawableList()
+{
+ _drawableList.push_back( drawable_ );
+}
+Magick::drawImage::drawImage( const std::list<Magick::Drawable> &drawable_ )
+ : _drawableList( drawable_ )
+{
+}
+void Magick::drawImage::operator()( Magick::Image &image_ ) const
+{
+ image_.draw( _drawableList );
+}
+
+// Edge image (hilight edges in image)
+Magick::edgeImage::edgeImage( const double radius_ )
+ : _radius( radius_ )
+{
+}
+void Magick::edgeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.edge( _radius );
+}
+
+// Emboss image (hilight edges with 3D effect)
+Magick::embossImage::embossImage( void )
+ : _radius( 1 ),
+ _sigma( 0.5 )
+{
+}
+Magick::embossImage::embossImage( const double radius_, const double sigma_ )
+ : _radius( radius_ ),
+ _sigma( sigma_ )
+{
+}
+void Magick::embossImage::operator()( Magick::Image &image_ ) const
+{
+ image_.emboss( _radius, _sigma );
+}
+
+// Enhance image (minimize noise)
+Magick::enhanceImage::enhanceImage( void )
+{
+}
+void Magick::enhanceImage::operator()( Magick::Image &image_ ) const
+{
+ image_.enhance( );
+}
+
+// Equalize image (histogram equalization)
+Magick::equalizeImage::equalizeImage( void )
+{
+}
+void Magick::equalizeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.equalize( );
+}
+
+// Create an image canvas using background color sized according to
+// geometry and composite existing image on it, with image placement
+// controlled by gravity. Parameters are obtained from existing image
+// properties if they are not specified via a method parameter.
+// Parameters which are supported by image properties (gravity and
+// backgroundColor) update those image properties as a side-effect.
+Magick::extentImage::extentImage( const Geometry &geometry_ )
+ : _geometry( geometry_ ),
+ _backgroundColor( ),
+ _gravity( Magick::ForgetGravity )
+
+{
+}
+Magick::extentImage::extentImage( const Geometry &geometry_,
+ const GravityType &gravity_ )
+ : _geometry( geometry_ ),
+ _backgroundColor( ),
+ _gravity( gravity_ )
+{
+}
+Magick::extentImage::extentImage( const Geometry &geometry_,
+ const Color &backgroundColor_ )
+ : _geometry( geometry_ ),
+ _backgroundColor( backgroundColor_ ),
+ _gravity( Magick::ForgetGravity )
+{
+}
+
+Magick::extentImage::extentImage( const Geometry &geometry_,
+ const Color &backgroundColor_,
+ const GravityType &gravity_ )
+ : _geometry( geometry_ ),
+ _backgroundColor( backgroundColor_ ),
+ _gravity( gravity_ )
+{
+}
+void Magick::extentImage::operator()( Magick::Image &image_ ) const
+{
+ // Support accessing the four image method permutations.
+ if ( (_backgroundColor.isValid()) && (_gravity != Magick::ForgetGravity) )
+ image_.extent( _geometry, _backgroundColor, _gravity );
+ else if ( _backgroundColor.isValid() )
+ image_.extent( _geometry, _backgroundColor );
+ else if ( _gravity != Magick::ForgetGravity )
+ image_.extent( _geometry, _gravity );
+ else
+ image_.extent( _geometry );
+}
+
+// Color to use when filling drawn objects
+Magick::fillColorImage::fillColorImage( const Magick::Color &fillColor_ )
+ : _fillColor( fillColor_ )
+{
+}
+void Magick::fillColorImage::operator()( Magick::Image &image_ ) const
+{
+ image_.fillColor( _fillColor );
+}
+
+// Flip image (reflect each scanline in the vertical direction)
+Magick::flipImage::flipImage( void )
+{
+}
+void Magick::flipImage::operator()( Magick::Image &image_ ) const
+{
+ image_.flip( );
+}
+
+// Flood-fill image with color
+// Flood-fill color across pixels starting at target-pixel and
+// stopping at pixels matching specified border color. Uses current
+// fuzz setting when determining color match.
+Magick::floodFillColorImage::floodFillColorImage( const unsigned int x_,
+ const unsigned int y_,
+ const Magick::Color &fillColor_ )
+ : _x(x_),
+ _y(y_),
+ _fillColor(fillColor_),
+ _borderColor()
+{
+}
+Magick::floodFillColorImage::floodFillColorImage( const Magick::Geometry &point_,
+ const Magick::Color &fillColor_ )
+ : _x(point_.xOff()),
+ _y(point_.yOff()),
+ _fillColor(fillColor_),
+ _borderColor()
+{
+}
+// Flood-fill color across pixels starting at target-pixel and
+// stopping at pixels matching specified border color. Uses current
+// fuzz setting when determining color match.
+Magick::floodFillColorImage::floodFillColorImage( const unsigned int x_,
+ const unsigned int y_,
+ const Magick::Color &fillColor_,
+ const Magick::Color &borderColor_ )
+ : _x(x_),
+ _y(y_),
+ _fillColor(fillColor_),
+ _borderColor(borderColor_)
+{
+}
+Magick::floodFillColorImage::floodFillColorImage( const Geometry &point_,
+ const Color &fillColor_,
+ const Color &borderColor_ )
+ : _x(point_.xOff()),
+ _y(point_.yOff()),
+ _fillColor(fillColor_),
+ _borderColor(borderColor_)
+{
+}
+void Magick::floodFillColorImage::operator()( Magick::Image &image_ ) const
+{
+ if ( _borderColor.isValid() )
+ {
+ image_.floodFillColor( _x, _y, _fillColor, _borderColor );
+ }
+ else
+ {
+ image_.floodFillColor( _x, _y, _fillColor );
+ }
+}
+
+// Flood-fill image with texture
+
+// Flood-fill texture across pixels that match the color of the target
+// pixel and are neighbors of the target pixel. Uses current fuzz
+// setting when determining color match.
+Magick::floodFillTextureImage::floodFillTextureImage( const unsigned int x_,
+ const unsigned int y_,
+ const Magick::Image &texture_ )
+ : _x(x_),
+ _y(y_),
+ _texture(texture_),
+ _borderColor()
+{
+}
+Magick::floodFillTextureImage::floodFillTextureImage( const Magick::Geometry &point_,
+ const Magick::Image &texture_ )
+ : _x(point_.xOff()),
+ _y(point_.yOff()),
+ _texture(texture_),
+ _borderColor()
+{
+}
+// Flood-fill texture across pixels starting at target-pixel and
+// stopping at pixels matching specified border color. Uses current
+// fuzz setting when determining color match.
+Magick::floodFillTextureImage::floodFillTextureImage( const unsigned int x_,
+ const unsigned int y_,
+ const Magick::Image &texture_,
+ const Magick::Color &borderColor_ )
+ : _x(x_),
+ _y(y_),
+ _texture(texture_),
+ _borderColor(borderColor_)
+{
+}
+Magick::floodFillTextureImage::floodFillTextureImage( const Magick::Geometry &point_,
+ const Magick::Image &texture_,
+ const Magick::Color &borderColor_ )
+ : _x(point_.xOff()),
+ _y(point_.yOff()),
+ _texture(texture_),
+ _borderColor(borderColor_)
+{
+}
+void Magick::floodFillTextureImage::operator()( Magick::Image &image_ ) const
+{
+ if ( _borderColor.isValid() )
+ {
+ image_.floodFillTexture( _x, _y, _texture, _borderColor );
+ }
+ else
+ {
+ image_.floodFillTexture( _x, _y, _texture );
+ }
+}
+
+// Flop image (reflect each scanline in the horizontal direction)
+Magick::flopImage::flopImage( void )
+{
+}
+void Magick::flopImage::operator()( Magick::Image &image_ ) const
+{
+ image_.flop( );
+}
+
+// Frame image
+Magick::frameImage::frameImage( const Magick::Geometry &geometry_ )
+ : _width( geometry_.width() ),
+ _height( geometry_.height() ),
+ _outerBevel( geometry_.xOff() ),
+ _innerBevel( geometry_.yOff() )
+{
+}
+Magick::frameImage::frameImage( const unsigned int width_, const unsigned int height_,
+ const int innerBevel_, const int outerBevel_ )
+ : _width( width_ ),
+ _height( height_ ),
+ _outerBevel( outerBevel_ ),
+ _innerBevel( innerBevel_ )
+{
+}
+void Magick::frameImage::operator()( Magick::Image &image_ ) const
+{
+ image_.frame( _width, _height, _innerBevel, _outerBevel );
+}
+
+// Gamma correct image
+Magick::gammaImage::gammaImage( const double gamma_ )
+ : _gammaRed( gamma_ ),
+ _gammaGreen( gamma_ ),
+ _gammaBlue( gamma_ )
+{
+}
+Magick::gammaImage::gammaImage ( const double gammaRed_,
+ const double gammaGreen_,
+ const double gammaBlue_ )
+ : _gammaRed( gammaRed_ ),
+ _gammaGreen( gammaGreen_ ),
+ _gammaBlue( gammaBlue_ )
+{
+}
+void Magick::gammaImage::operator()( Magick::Image &image_ ) const
+{
+ image_.gamma( _gammaRed, _gammaGreen, _gammaBlue );
+}
+
+// Gaussian blur image
+// The number of neighbor pixels to be included in the convolution
+// mask is specified by 'width_'. The standard deviation of the
+// gaussian bell curve is specified by 'sigma_'.
+Magick::gaussianBlurImage::gaussianBlurImage( const double width_,
+ const double sigma_ )
+ : _width( width_ ),
+ _sigma( sigma_ )
+{
+}
+void Magick::gaussianBlurImage::operator()( Magick::Image &image_ ) const
+{
+ image_.gaussianBlur( _width, _sigma );
+}
+
+// Implode image (special effect)
+Magick::implodeImage::implodeImage( const double factor_ )
+ : _factor( factor_ )
+{
+}
+void Magick::implodeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.implode( _factor );
+}
+
+// Apply a color lookup table (Hald CLUT) to the image.
+Magick::haldClutImage::haldClutImage( const Image &haldClutImage_ )
+ : _haldClutImage ( haldClutImage_ )
+{
+}
+void Magick::haldClutImage::operator()( Image &image_ ) const
+{
+ image_.haldClut( _haldClutImage );
+}
+
+// Set image validity. Valid images become empty (inValid) if argument
+// is false.
+Magick::isValidImage::isValidImage( const bool isValid_ )
+ : _isValid( isValid_ )
+{
+}
+void Magick::isValidImage::operator()( Magick::Image &image_ ) const
+{
+ image_.isValid( _isValid );
+}
+
+// Label image
+Magick::labelImage::labelImage( const std::string &label_ )
+ : _label( label_ )
+{
+}
+void Magick::labelImage::operator()( Magick::Image &image_ ) const
+{
+ image_.label( _label );
+}
+
+// Level image
+Magick::levelImage::levelImage( const double black_point,
+ const double white_point,
+ const double mid_point )
+ : _black_point(black_point),
+ _white_point(white_point),
+ _mid_point(mid_point)
+{
+}
+void Magick::levelImage::operator()( Magick::Image &image_ ) const
+{
+ image_.level( _black_point, _white_point, _mid_point );
+}
+
+// Level image channel
+Magick::levelChannelImage::levelChannelImage( const Magick::ChannelType channel,
+ const double black_point,
+ const double white_point,
+ const double mid_point )
+ : _channel(channel),
+ _black_point(black_point),
+ _white_point(white_point),
+ _mid_point(mid_point)
+{
+}
+void Magick::levelChannelImage::operator()( Magick::Image &image_ ) const
+{
+ image_.levelChannel( _channel, _black_point, _white_point, _mid_point );
+}
+
+// Magnify image by integral size
+Magick::magnifyImage::magnifyImage( void )
+{
+}
+void Magick::magnifyImage::operator()( Magick::Image &image_ ) const
+{
+ image_.magnify( );
+}
+
+// Remap image colors with closest color from reference image
+Magick::mapImage::mapImage( const Magick::Image &mapImage_ ,
+ const bool dither_ )
+ : _mapImage( mapImage_ ),
+ _dither( dither_ )
+{
+}
+void Magick::mapImage::operator()( Magick::Image &image_ ) const
+{
+ image_.map( _mapImage, _dither );
+}
+
+// Floodfill designated area with a matte value
+Magick::matteFloodfillImage::matteFloodfillImage( const Color &target_ ,
+ const unsigned int matte_,
+ const int x_, const int y_,
+ const PaintMethod method_ )
+ : _target( target_ ),
+ _matte( matte_ ),
+ _x( x_ ),
+ _y( y_ ),
+ _method( method_ )
+{
+}
+void Magick::matteFloodfillImage::operator()( Magick::Image &image_ ) const
+{
+ image_.matteFloodfill( _target, _matte, _x, _y, _method );
+}
+
+// Filter image by replacing each pixel component with the median
+// color in a circular neighborhood
+Magick::medianFilterImage::medianFilterImage( const double radius_ )
+ : _radius( radius_ )
+{
+}
+void Magick::medianFilterImage::operator()( Magick::Image &image_ ) const
+{
+ image_.medianFilter( _radius );
+}
+
+// Reduce image by integral size
+Magick::minifyImage::minifyImage( void )
+{
+}
+void Magick::minifyImage::operator()( Magick::Image &image_ ) const
+{
+ image_.minify( );
+}
+
+// Modulate percent hue, saturation, and brightness of an image
+Magick::modulateImage::modulateImage( const double brightness_,
+ const double saturation_,
+ const double hue_ )
+ : _brightness( brightness_ ),
+ _saturation( saturation_ ),
+ _hue( hue_ )
+{
+}
+void Magick::modulateImage::operator()( Magick::Image &image_ ) const
+{
+ image_.modulate( _brightness, _saturation, _hue );
+}
+
+// Negate colors in image. Set grayscale to only negate grayscale
+// values in image.
+Magick::negateImage::negateImage( const bool grayscale_ )
+ : _grayscale( grayscale_ )
+{
+}
+void Magick::negateImage::operator()( Magick::Image &image_ ) const
+{
+ image_.negate( _grayscale );
+}
+
+// Normalize image (increase contrast by normalizing the pixel values
+// to span the full range of color values)
+Magick::normalizeImage::normalizeImage( void )
+{
+}
+void Magick::normalizeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.normalize( );
+}
+
+// Oilpaint image (image looks like oil painting)
+Magick::oilPaintImage::oilPaintImage( const double radius_ )
+ : _radius( radius_ )
+{
+}
+void Magick::oilPaintImage::operator()( Magick::Image &image_ ) const
+{
+ image_.oilPaint( _radius );
+}
+
+// Set or attenuate the image opacity channel. If the image pixels are
+// opaque then they are set to the specified opacity value, otherwise
+// they are blended with the supplied opacity value. The value of
+// opacity_ ranges from 0 (completely opaque) to MaxRGB. The defines
+// OpaqueOpacity and TransparentOpacity are available to specify
+// completely opaque or completely transparent, respectively.
+Magick::opacityImage::opacityImage( const unsigned int opacity_ )
+ : _opacity( opacity_ )
+{
+}
+void Magick::opacityImage::operator()( Magick::Image &image_ ) const
+{
+ image_.opacity( _opacity );
+}
+
+// Change color of opaque pixel to specified pen color.
+Magick::opaqueImage::opaqueImage( const Magick::Color &opaqueColor_,
+ const Magick::Color &penColor_ )
+ : _opaqueColor( opaqueColor_ ),
+ _penColor( penColor_ )
+{
+}
+void Magick::opaqueImage::operator()( Magick::Image &image_ ) const
+{
+ image_.opaque( _opaqueColor, _penColor );
+}
+
+// Quantize image (reduce number of colors)
+Magick::quantizeImage::quantizeImage( const bool measureError_ )
+ : _measureError( measureError_ )
+{
+}
+void Magick::quantizeImage::operator()( Image &image_ ) const
+{
+ image_.quantize( _measureError );
+}
+
+// Raise image (lighten or darken the edges of an image to give a 3-D
+// raised or lowered effect)
+Magick::raiseImage::raiseImage( const Magick::Geometry &geometry_ ,
+ const bool raisedFlag_ )
+ : _geometry( geometry_ ),
+ _raisedFlag( raisedFlag_ )
+{
+}
+void Magick::raiseImage::operator()( Magick::Image &image_ ) const
+{
+ image_.raise( _geometry, _raisedFlag );
+}
+
+// Reduce noise in image using a noise peak elimination filter
+Magick::reduceNoiseImage::reduceNoiseImage( void )
+ : _order(3)
+{
+}
+Magick::reduceNoiseImage::reduceNoiseImage ( const unsigned int order_ )
+ : _order(order_)
+{
+}
+void Magick::reduceNoiseImage::operator()( Image &image_ ) const
+{
+ image_.reduceNoise( _order );
+}
+
+// Resize image to a certain geometry
+Magick::resizeImage::resizeImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::resizeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.resize( _geometry );
+}
+
+// Roll image (rolls image vertically and horizontally) by specified
+// number of columnms and rows)
+Magick::rollImage::rollImage( const Magick::Geometry &roll_ )
+ : _columns( roll_.width() ),
+ _rows( roll_.height() )
+{
+}
+Magick::rollImage::rollImage( const int columns_,
+ const int rows_ )
+ : _columns( columns_ ),
+ _rows( rows_ )
+{
+}
+void Magick::rollImage::operator()( Magick::Image &image_ ) const
+{
+ image_.roll( _columns, _rows );
+}
+
+// Rotate image counter-clockwise by specified number of degrees.
+Magick::rotateImage::rotateImage( const double degrees_ )
+ : _degrees( degrees_ )
+{
+}
+void Magick::rotateImage::operator()( Magick::Image &image_ ) const
+{
+ image_.rotate( _degrees );
+}
+
+// Resize image by using pixel sampling algorithm
+Magick::sampleImage::sampleImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::sampleImage::operator()( Magick::Image &image_ ) const
+{
+ image_.sample( _geometry );
+}
+
+// Resize image by using simple ratio algorithm
+Magick::scaleImage::scaleImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::scaleImage::operator()( Magick::Image &image_ ) const
+{
+ image_.scale( _geometry );
+}
+
+// Segment (coalesce similar image components) by analyzing the
+// histograms of the color components and identifying units that are
+// homogeneous with the fuzzy c-means technique. Also uses
+// QuantizeColorSpace and Verbose image attributes
+Magick::segmentImage::segmentImage( const double clusterThreshold_ ,
+ const double smoothingThreshold_ )
+ : _clusterThreshold( clusterThreshold_ ),
+ _smoothingThreshold( smoothingThreshold_ )
+{
+}
+void Magick::segmentImage::operator()( Magick::Image &image_ ) const
+{
+ image_.segment( _clusterThreshold, _smoothingThreshold );
+}
+
+// Shade image using distant light source
+Magick::shadeImage::shadeImage( const double azimuth_,
+ const double elevation_,
+ const bool colorShading_)
+ : _azimuth( azimuth_ ),
+ _elevation( elevation_ ),
+ _colorShading (colorShading_)
+{
+}
+void Magick::shadeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.shade( _azimuth, _elevation, _colorShading );
+}
+
+// Sharpen pixels in image
+Magick::sharpenImage::sharpenImage( const double radius_, const double sigma_ )
+ : _radius( radius_ ),
+ _sigma( sigma_ )
+{
+}
+void Magick::sharpenImage::operator()( Magick::Image &image_ ) const
+{
+ image_.sharpen( _radius, _sigma );
+}
+
+// Shave pixels from image edges.
+Magick::shaveImage::shaveImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::shaveImage::operator()( Magick::Image &image_ ) const
+{
+ image_.shave( _geometry );
+}
+
+// Shear image (create parallelogram by sliding image by X or Y axis)
+Magick::shearImage::shearImage( const double xShearAngle_,
+ const double yShearAngle_ )
+ : _xShearAngle( xShearAngle_ ),
+ _yShearAngle( yShearAngle_ )
+{
+}
+void Magick::shearImage::operator()( Magick::Image &image_ ) const
+{
+ image_.shear( _xShearAngle, _yShearAngle );
+}
+
+// Solarize image (similar to effect seen when exposing a photographic
+// film to light during the development process)
+Magick::solarizeImage::solarizeImage( const double factor_ )
+ : _factor( factor_ )
+{
+}
+void Magick::solarizeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.solarize( _factor );
+}
+
+// Spread pixels randomly within image by specified ammount
+Magick::spreadImage::spreadImage( const unsigned int amount_ )
+ : _amount( amount_ )
+{
+}
+void Magick::spreadImage::operator()( Magick::Image &image_ ) const
+{
+ image_.spread( _amount );
+}
+
+// Add a digital watermark to the image (based on second image)
+Magick::steganoImage::steganoImage( const Magick::Image &waterMark_ )
+ : _waterMark( waterMark_ )
+{
+}
+void Magick::steganoImage::operator()( Magick::Image &image_ ) const
+{
+ image_.stegano( _waterMark );
+}
+
+// Create an image which appears in stereo when viewed with red-blue
+// glasses (Red image on left, blue on right)
+Magick::stereoImage::stereoImage( const Magick::Image &rightImage_ )
+ : _rightImage( rightImage_ )
+{
+}
+void Magick::stereoImage::operator()( Magick::Image &image_ ) const
+{
+ image_.stereo( _rightImage );
+}
+
+// Color to use when drawing object outlines
+Magick::strokeColorImage::strokeColorImage( const Magick::Color &strokeColor_ )
+ : _strokeColor( strokeColor_ )
+{
+}
+void Magick::strokeColorImage::operator()( Magick::Image &image_ ) const
+{
+ image_.strokeColor( _strokeColor );
+}
+
+// Swirl image (image pixels are rotated by degrees)
+Magick::swirlImage::swirlImage( const double degrees_ )
+ : _degrees( degrees_ )
+{
+}
+void Magick::swirlImage::operator()( Magick::Image &image_ ) const
+{
+ image_.swirl( _degrees );
+}
+
+// Remove all profiles and text attributes from the image.
+Magick::stripImage::stripImage( void )
+{
+}
+void Magick::stripImage::operator()( Magick::Image &image_ ) const
+{
+ image_.strip( );
+}
+
+// Channel a texture on image background
+Magick::textureImage::textureImage( const Magick::Image &texture_ )
+ : _texture( texture_ )
+{
+}
+void Magick::textureImage::operator()( Magick::Image &image_ ) const
+{
+ image_.texture( _texture );
+}
+
+// Threshold image
+Magick::thresholdImage::thresholdImage( const double threshold_ )
+ : _threshold( threshold_ )
+{
+}
+void Magick::thresholdImage::operator()( Magick::Image &image_ ) const
+{
+ image_.threshold( _threshold );
+}
+
+// Transform image based on image and crop geometries
+Magick::transformImage::transformImage( const Magick::Geometry &imageGeometry_ )
+ : _imageGeometry( imageGeometry_ ),
+ _cropGeometry( )
+{
+}
+Magick::transformImage::transformImage( const Magick::Geometry &imageGeometry_,
+ const Geometry &cropGeometry_ )
+ : _imageGeometry( imageGeometry_ ),
+ _cropGeometry( cropGeometry_ )
+{
+}
+void Magick::transformImage::operator()( Magick::Image &image_ ) const
+{
+ if ( _cropGeometry.isValid() )
+ image_.transform( _imageGeometry, _cropGeometry );
+ else
+ image_.transform( _imageGeometry );
+}
+
+// Set image color to transparent
+Magick::transparentImage::transparentImage( const Magick::Color& color_ )
+ : _color( color_ )
+{
+}
+void Magick::transparentImage::operator()( Magick::Image &image_ ) const
+{
+ image_.transparent( _color );
+}
+
+// Trim edges that are the background color from the image
+Magick::trimImage::trimImage( void )
+{
+}
+void Magick::trimImage::operator()( Magick::Image &image_ ) const
+{
+ image_.trim( );
+}
+
+// Map image pixels to a sine wave
+Magick::waveImage::waveImage( const double amplitude_,
+ const double wavelength_ )
+ : _amplitude( amplitude_ ),
+ _wavelength( wavelength_ )
+{
+}
+void Magick::waveImage::operator()( Magick::Image &image_ ) const
+{
+ image_.wave( _amplitude, _wavelength );
+}
+
+// Zoom image to specified size.
+Magick::zoomImage::zoomImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::zoomImage::operator()( Magick::Image &image_ ) const
+{
+ image_.zoom( _geometry );
+}
+
+//
+// Function object image attribute accessors
+//
+
+// Anti-alias Postscript and TrueType fonts (default true)
+Magick::antiAliasImage::antiAliasImage( const bool flag_ )
+ : _flag( flag_ )
+{
+}
+void Magick::antiAliasImage::operator()( Magick::Image &image_ ) const
+{
+ image_.antiAlias( _flag );
+}
+
+// Join images into a single multi-image file
+Magick::adjoinImage::adjoinImage( const bool flag_ )
+ : _flag( flag_ )
+{
+}
+void Magick::adjoinImage::operator()( Magick::Image &image_ ) const
+{
+ image_.adjoin( _flag );
+}
+
+// Time in 1/100ths of a second which must expire before displaying
+// the next image in an animated sequence.
+Magick::animationDelayImage::animationDelayImage( const unsigned int delay_ )
+ : _delay( delay_ )
+{
+}
+void Magick::animationDelayImage::operator()( Magick::Image &image_ ) const
+{
+ image_.animationDelay( _delay );
+}
+
+// Number of iterations to loop an animation (e.g. Netscape loop
+// extension) for.
+Magick::animationIterationsImage::animationIterationsImage( const unsigned int iterations_ )
+ : _iterations( iterations_ )
+{
+}
+void Magick::animationIterationsImage::operator()( Magick::Image &image_ ) const
+{
+ image_.animationIterations( _iterations );
+}
+
+// Image background color
+Magick::backgroundColorImage::backgroundColorImage( const Magick::Color &color_ )
+ : _color( color_ )
+{
+}
+void Magick::backgroundColorImage::operator()( Magick::Image &image_ ) const
+{
+ image_.backgroundColor( _color );
+}
+
+// Name of texture image to tile onto the image background
+Magick::backgroundTextureImage::backgroundTextureImage( const std::string &backgroundTexture_ )
+ : _backgroundTexture( backgroundTexture_ )
+{
+}
+void Magick::backgroundTextureImage::operator()( Magick::Image &image_ ) const
+{
+ image_.backgroundTexture( _backgroundTexture );
+}
+
+// Image border color
+Magick::borderColorImage::borderColorImage( const Magick::Color &color_ )
+ : _color( color_ )
+{
+}
+void Magick::borderColorImage::operator()( Magick::Image &image_ ) const
+{
+ image_.borderColor( _color );
+}
+
+// Text bounding-box base color (default none)
+Magick::boxColorImage::boxColorImage( const Magick::Color &boxColor_ )
+ : _boxColor( boxColor_ ) { }
+
+void Magick::boxColorImage::operator()( Magick::Image &image_ ) const
+{
+ image_.boxColor( _boxColor );
+}
+
+// Chromaticity blue primary point (e.g. x=0.15, y=0.06)
+Magick::chromaBluePrimaryImage::chromaBluePrimaryImage( const double x_,
+ const double y_ )
+ : _x( x_ ),
+ _y( y_ )
+{
+}
+void Magick::chromaBluePrimaryImage::operator()( Magick::Image &image_ ) const
+{
+ image_.chromaBluePrimary( _x, _y );
+}
+
+// Chromaticity green primary point (e.g. x=0.3, y=0.6)
+Magick::chromaGreenPrimaryImage::chromaGreenPrimaryImage( const double x_,
+ const double y_ )
+ : _x( x_ ),
+ _y( y_ )
+{
+}
+void Magick::chromaGreenPrimaryImage::operator()( Magick::Image &image_ ) const
+{
+ image_.chromaGreenPrimary( _x, _y );
+}
+
+// Chromaticity red primary point (e.g. x=0.64, y=0.33)
+Magick::chromaRedPrimaryImage::chromaRedPrimaryImage( const double x_,
+ const double y_ )
+ : _x( x_ ),
+ _y( y_ )
+{
+}
+void Magick::chromaRedPrimaryImage::operator()( Magick::Image &image_ ) const
+{
+ image_.chromaRedPrimary( _x, _y );
+}
+
+// Chromaticity white point (e.g. x=0.3127, y=0.329)
+Magick::chromaWhitePointImage::chromaWhitePointImage( const double x_,
+ const double y_ )
+ : _x( x_ ),
+ _y( y_ )
+{
+}
+void Magick::chromaWhitePointImage::operator()( Magick::Image &image_ ) const
+{
+ image_.chromaWhitePoint( _x, _y );
+}
+
+// Colors within this distance are considered equal
+Magick::colorFuzzImage::colorFuzzImage( const double fuzz_ )
+ : _fuzz( fuzz_ )
+{
+}
+void Magick::colorFuzzImage::operator()( Magick::Image &image_ ) const
+{
+ image_.colorFuzz( _fuzz );
+}
+
+// Color at colormap position index_
+Magick::colorMapImage::colorMapImage( const unsigned int index_,
+ const Color &color_ )
+ : _index( index_ ),
+ _color( color_ )
+{
+}
+void Magick::colorMapImage::operator()( Magick::Image &image_ ) const
+{
+ image_.colorMap( _index, _color );
+}
+
+// Composition operator to be used when composition is implicitly used
+// (such as for image flattening).
+Magick::composeImage::composeImage( const CompositeOperator compose_ )
+ : _compose( compose_ )
+{
+}
+void Magick::composeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.compose( _compose );
+}
+
+// Compression type
+Magick::compressTypeImage::compressTypeImage( const CompressionType compressType_ )
+ : _compressType( compressType_ )
+{
+}
+void Magick::compressTypeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.compressType( _compressType );
+}
+
+// Vertical and horizontal resolution in pixels of the image
+Magick::densityImage::densityImage( const Geometry &geomery_ )
+ : _geomery( geomery_ )
+{
+}
+void Magick::densityImage::operator()( Magick::Image &image_ ) const
+{
+ image_.density( _geomery );
+}
+
+// Image depth (bits allocated to red/green/blue components)
+Magick::depthImage::depthImage( const unsigned int depth_ )
+ : _depth( depth_ )
+{
+}
+void Magick::depthImage::operator()( Magick::Image &image_ ) const
+{
+ image_.depth( _depth );
+}
+
+// Endianness (LSBEndian like Intel or MSBEndian like SPARC) for image
+// formats which support endian-specific options.
+Magick::endianImage::endianImage( const Magick::EndianType endian_ )
+ : _endian( endian_ )
+{
+}
+void Magick::endianImage::operator()( Magick::Image &image_ ) const
+{
+ image_.endian( _endian );
+}
+
+// Image file name
+Magick::fileNameImage::fileNameImage( const std::string &fileName_ )
+ : _fileName( fileName_ )
+{
+}
+void Magick::fileNameImage::operator()( Magick::Image &image_ ) const
+{
+ image_.fileName( _fileName );
+}
+
+// Filter to use when resizing image
+Magick::filterTypeImage::filterTypeImage( const FilterTypes filterType_ )
+ : _filterType( filterType_ )
+{
+}
+void Magick::filterTypeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.filterType( _filterType );
+}
+
+// Text rendering font
+Magick::fontImage::fontImage( const std::string &font_ )
+ : _font( font_ )
+{
+}
+void Magick::fontImage::operator()( Magick::Image &image_ ) const
+{
+ image_.font( _font );
+}
+
+// Font point size
+Magick::fontPointsizeImage::fontPointsizeImage( const unsigned int pointsize_ )
+ : _pointsize( pointsize_ )
+{
+}
+void Magick::fontPointsizeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.fontPointsize( _pointsize );
+}
+
+// GIF disposal method
+Magick::gifDisposeMethodImage::gifDisposeMethodImage( const unsigned int disposeMethod_ )
+ : _disposeMethod( disposeMethod_ )
+{
+}
+void Magick::gifDisposeMethodImage::operator()( Magick::Image &image_ ) const
+{
+ image_.gifDisposeMethod( _disposeMethod );
+}
+
+// Type of interlacing to use
+Magick::interlaceTypeImage::interlaceTypeImage( const InterlaceType interlace_ )
+ : _interlace( interlace_ )
+{
+}
+void Magick::interlaceTypeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.interlaceType( _interlace );
+}
+
+// Linewidth for drawing vector objects (default one)
+Magick::lineWidthImage::lineWidthImage( const double lineWidth_ )
+ : _lineWidth( lineWidth_ )
+{
+}
+void Magick::lineWidthImage::operator()( Magick::Image &image_ ) const
+{
+ image_.lineWidth( _lineWidth );
+}
+
+// File type magick identifier (.e.g "GIF")
+Magick::magickImage::magickImage( const std::string &magick_ )
+ : _magick( magick_ )
+{
+}
+void Magick::magickImage::operator()( Magick::Image &image_ ) const
+{
+ image_.magick( _magick );
+}
+
+// Image supports transparent color
+Magick::matteImage::matteImage( const bool matteFlag_ )
+ : _matteFlag( matteFlag_ )
+{
+}
+void Magick::matteImage::operator()( Magick::Image &image_ ) const
+{
+ image_.matte( _matteFlag );
+}
+
+// Transparent color
+Magick::matteColorImage::matteColorImage( const Color &matteColor_ )
+ : _matteColor( matteColor_ )
+{
+}
+void Magick::matteColorImage::operator()( Magick::Image &image_ ) const
+{
+ image_.matteColor( _matteColor );
+}
+
+// Indicate that image is black and white
+Magick::monochromeImage::monochromeImage( const bool monochromeFlag_ )
+ : _monochromeFlag( monochromeFlag_ )
+{
+}
+void Magick::monochromeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.monochrome( _monochromeFlag );
+}
+
+// Pen color
+Magick::penColorImage::penColorImage( const Color &penColor_ )
+ : _penColor( penColor_ )
+{
+}
+void Magick::penColorImage::operator()( Magick::Image &image_ ) const
+{
+ image_.penColor( _penColor );
+}
+
+// Pen texture image.
+Magick::penTextureImage::penTextureImage( const Image &penTexture_ )
+ : _penTexture( penTexture_ )
+{
+}
+void Magick::penTextureImage::operator()( Magick::Image &image_ ) const
+{
+ image_.penTexture( _penTexture );
+}
+
+// Set pixel color at location x & y.
+Magick::pixelColorImage::pixelColorImage( const unsigned int x_,
+ const unsigned int y_,
+ const Color &color_)
+ : _x( x_ ),
+ _y( y_ ),
+ _color( color_ ) { }
+
+void Magick::pixelColorImage::operator()( Magick::Image &image_ ) const
+{
+ image_.pixelColor( _x, _y, _color );
+}
+
+// Postscript page size.
+Magick::pageImage::pageImage( const Geometry &pageSize_ )
+ : _pageSize( pageSize_ )
+{
+}
+void Magick::pageImage::operator()( Magick::Image &image_ ) const
+{
+ image_.page( _pageSize );
+}
+
+// JPEG/MIFF/PNG compression level (default 75).
+Magick::qualityImage::qualityImage( const unsigned int quality_ )
+ : _quality( quality_ )
+{
+}
+void Magick::qualityImage::operator()( Magick::Image &image_ ) const
+{
+ image_.quality( _quality );
+}
+
+// Maximum number of colors to quantize to
+Magick::quantizeColorsImage::quantizeColorsImage( const unsigned int colors_ )
+ : _colors( colors_ )
+{
+}
+void Magick::quantizeColorsImage::operator()( Magick::Image &image_ ) const
+{
+ image_.quantizeColors( _colors );
+}
+
+// Colorspace to quantize in.
+Magick::quantizeColorSpaceImage::quantizeColorSpaceImage( const ColorspaceType colorSpace_ )
+ : _colorSpace( colorSpace_ )
+{
+}
+void Magick::quantizeColorSpaceImage::operator()( Magick::Image &image_ ) const
+{
+ image_.quantizeColorSpace( _colorSpace );
+}
+
+// Dither image during quantization (default true).
+Magick::quantizeDitherImage::quantizeDitherImage( const bool ditherFlag_ )
+ : _ditherFlag( ditherFlag_ )
+{
+}
+void Magick::quantizeDitherImage::operator()( Magick::Image &image_ ) const
+{
+ image_.quantizeDither( _ditherFlag );
+}
+
+// Quantization tree-depth
+Magick::quantizeTreeDepthImage::quantizeTreeDepthImage( const unsigned int treeDepth_ )
+ : _treeDepth( treeDepth_ ) { }
+
+void Magick::quantizeTreeDepthImage::operator()( Magick::Image &image_ ) const
+{
+ image_.quantizeTreeDepth( _treeDepth );
+}
+
+// The type of rendering intent
+Magick::renderingIntentImage::renderingIntentImage( const Magick::RenderingIntent renderingIntent_ )
+ : _renderingIntent( renderingIntent_ )
+{
+}
+void Magick::renderingIntentImage::operator()( Magick::Image &image_ ) const
+{
+ image_.renderingIntent( _renderingIntent );
+}
+
+// Units of image resolution
+Magick::resolutionUnitsImage::resolutionUnitsImage( const Magick::ResolutionType resolutionUnits_ )
+ : _resolutionUnits( resolutionUnits_ )
+{
+}
+void Magick::resolutionUnitsImage::operator()( Magick::Image &image_ ) const
+{
+ image_.resolutionUnits( _resolutionUnits );
+}
+
+// Image scene number
+Magick::sceneImage::sceneImage( const unsigned int scene_ )
+ : _scene( scene_ )
+{
+}
+void Magick::sceneImage::operator()( Magick::Image &image_ ) const
+{
+ image_.scene( _scene );
+}
+
+// Width and height of a raw image
+Magick::sizeImage::sizeImage( const Magick::Geometry &geometry_ )
+ : _geometry( geometry_ )
+{
+}
+void Magick::sizeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.size( _geometry );
+}
+
+// Subimage of an image sequence
+Magick::subImageImage::subImageImage( const unsigned int subImage_ )
+ : _subImage( subImage_ )
+{
+}
+void Magick::subImageImage::operator()( Magick::Image &image_ ) const
+{
+ image_.subImage( _subImage );
+}
+
+// Number of images relative to the base image
+Magick::subRangeImage::subRangeImage( const unsigned int subRange_ )
+ : _subRange( subRange_ )
+{
+}
+void Magick::subRangeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.subRange( _subRange );
+}
+
+// Tile name
+Magick::tileNameImage::tileNameImage( const std::string &tileName_ )
+ : _tileName( tileName_ )
+{
+}
+void Magick::tileNameImage::operator()( Magick::Image &image_ ) const
+{
+ image_.tileName( _tileName );
+}
+
+// Image storage type
+Magick::typeImage::typeImage( const Magick::ImageType type_ )
+ : _type( type_ )
+{
+}
+void Magick::typeImage::operator()( Magick::Image &image_ ) const
+{
+ image_.type( _type );
+}
+
+// Print detailed information about the image
+Magick::verboseImage::verboseImage( const bool verbose_ )
+ : _verbose( verbose_ )
+{
+}
+void Magick::verboseImage::operator()( Magick::Image &image_ ) const
+{
+ image_.verbose( _verbose );
+}
+
+// FlashPix viewing parameters
+Magick::viewImage::viewImage( const std::string &view_ )
+ : _view( view_ ) { }
+
+void Magick::viewImage::operator()( Magick::Image &image_ ) const
+{
+ image_.view( _view );
+}
+
+// X11 display to display to, obtain fonts from, or to capture image
+// from
+Magick::x11DisplayImage::x11DisplayImage( const std::string &display_ )
+ : _display( display_ )
+{
+}
+void Magick::x11DisplayImage::operator()( Magick::Image &image_ ) const
+{
+ image_.x11Display( _display );
+}
diff --git a/Magick++/lib/Thread.cpp b/Magick++/lib/Thread.cpp
new file mode 100644
index 0000000..57dbbe3
--- /dev/null
+++ b/Magick++/lib/Thread.cpp
@@ -0,0 +1,124 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
+//
+// Implementation of thread support
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/Thread.h"
+#include "Magick++/Exception.h"
+
+#include <string.h>
+
+// Default constructor
+Magick::MutexLock::MutexLock(void)
+#if defined(HasPTHREADS)
+ // POSIX threads
+ : _mutex()
+{
+ ::pthread_mutexattr_t attr;
+ int sysError;
+ if ( (sysError = ::pthread_mutexattr_init( &attr )) == 0 )
+ if ( (sysError = ::pthread_mutex_init( &_mutex, &attr )) == 0 )
+ {
+ ::pthread_mutexattr_destroy( &attr );
+ return;
+ }
+ throwExceptionExplicit( OptionError, "mutex initialization failed",
+ strerror(sysError) );
+}
+#else
+#if defined(_VISUALC_) && defined(_MT)
+// Win32 threads
+ : _mutex()
+{
+ SECURITY_ATTRIBUTES security;
+
+ /* Allow the semaphore to be inherited */
+ security.nLength = sizeof(security);
+ security.lpSecurityDescriptor = NULL;
+ security.bInheritHandle = TRUE;
+
+ /* Create the semaphore, with initial value signaled */
+ _mutex.id = ::CreateSemaphore(&security, 1, MAXSEMLEN, NULL);
+ if ( _mutex.id != NULL )
+ return;
+ throwExceptionExplicit( OptionError, "mutex initialization failed" );
+}
+#else
+// Threads not supported
+{
+}
+#endif
+#endif
+
+// Destructor
+Magick::MutexLock::~MutexLock(void)
+{
+#if defined(HasPTHREADS)
+ int sysError;
+ if ( (sysError = ::pthread_mutex_destroy( &_mutex )) == 0 )
+ return;
+ throwExceptionExplicit( OptionError, "mutex destruction failed",
+ strerror(sysError) );
+#endif
+#if defined(_MT) && defined(_VISUALC_)
+ if ( ::CloseHandle(_mutex.id) != 0 )
+ return;
+ throwExceptionExplicit( OptionError, "mutex destruction failed" );
+#endif
+}
+
+// Lock mutex
+void Magick::MutexLock::lock(void)
+{
+#if defined(HasPTHREADS)
+ int sysError;
+ if ( (sysError = ::pthread_mutex_lock( &_mutex )) == 0)
+ return;
+ throwExceptionExplicit( OptionError, "mutex lock failed",
+ strerror(sysError));
+#endif
+#if defined(_MT) && defined(_VISUALC_)
+#if 1
+ if (WaitForSingleObject(_mutex.id,INFINITE) != WAIT_FAILED)
+ return;
+ throwExceptionExplicit( OptionError, "mutex lock failed" );
+#else
+ // Following code is not known to work correctly yet.
+ while(1)
+ {
+ DWORD status=MsgWaitForMultipleObjects(1, &_mutex.id, FALSE, INFINITE,
+ QS_ALLEVENTS);
+ // Loop if return was due to message received (which we don't care about).
+ if (status == (WAIT_OBJECT_0+1))
+ continue;
+ // If return was due to handle state change, then object is available.
+ if ((status - WAIT_OBJECT_0) == 0)
+ return;
+ }
+ // If we get here, then there was an unexpected return value.
+ throwExceptionExplicit( OptionError, "mutex lock failed" );
+#endif
+#endif
+}
+
+// Unlock mutex
+void Magick::MutexLock::unlock(void)
+{
+#if defined(HasPTHREADS)
+ int sysError;
+ if ( (sysError = ::pthread_mutex_unlock( &_mutex )) == 0)
+ return;
+ throwExceptionExplicit( OptionError, "mutex unlock failed",
+ strerror(sysError) );
+#endif
+#if defined(_MT) && defined(_VISUALC_)
+ if ( ReleaseSemaphore(_mutex.id, 1, NULL) == TRUE )
+ return;
+ throwExceptionExplicit( OptionError, "mutex unlock failed" );
+#endif
+}
diff --git a/Magick++/lib/TypeMetric.cpp b/Magick++/lib/TypeMetric.cpp
new file mode 100644
index 0000000..aece758
--- /dev/null
+++ b/Magick++/lib/TypeMetric.cpp
@@ -0,0 +1,53 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 2001
+//
+// TypeMetric implementation
+//
+
+#define MAGICK_IMPLEMENTATION
+#define MAGICK_PLUSPLUS_IMPLEMENTATION
+
+#include "Magick++/TypeMetric.h"
+#include <string.h>
+
+// Default constructor
+Magick::TypeMetric::TypeMetric ( void )
+{
+ memset( &_typeMetric, 0, sizeof(_typeMetric));
+}
+
+Magick::TypeMetric::~TypeMetric ( void )
+{
+ // Nothing to do
+}
+
+// Ascent, expressed in pixels
+double Magick::TypeMetric::ascent ( void ) const
+{
+ return _typeMetric.ascent;
+}
+
+// Descent, expressed in pixels
+double Magick::TypeMetric::descent ( void ) const
+{
+ return _typeMetric.descent;
+}
+
+// Text width, expressed in pixels
+double Magick::TypeMetric::textWidth ( void ) const
+{
+ return _typeMetric.width;
+}
+
+// Text height, expressed in pixels
+double Magick::TypeMetric::textHeight ( void ) const
+{
+ return _typeMetric.height;
+}
+
+// Maximum horizontal advance, expressed in pixels
+double Magick::TypeMetric::maxHorizontalAdvance ( void ) const
+{
+ return _typeMetric.max_advance;
+}
diff --git a/Magick++/tests/appendImages.cpp b/Magick++/tests/appendImages.cpp
new file mode 100644
index 0000000..c8dcb91
--- /dev/null
+++ b/Magick++/tests/appendImages.cpp
@@ -0,0 +1,89 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2003
+//
+// Test STL appendImages function
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+#include <vector>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ //
+ // Test appendImages
+ //
+
+ list<Image> imageList;
+ readImages( &imageList, srcdir + "test_image_anim.miff" );
+
+ Image appended;
+
+ // Horizontal
+ appendImages( &appended, imageList.begin(), imageList.end() );
+ // appended.display();
+ if (( appended.signature() != "3a90bb0bb8f69f6788ab99e9e25598a0d6c5cdbbb797f77ad68011e0a8b1689d" ) &&
+ ( appended.signature() != "7b8f52c6331487119eeda8063887a85650f76b86a3dce7086bf93d8b49e6ddc3" ))
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Horizontal append failed, signature = "
+ << appended.signature() << endl;
+ appended.write("appendImages_horizontal_out.miff");
+ // appended.display();
+ }
+
+ // Vertical
+ appendImages( &appended, imageList.begin(), imageList.end(), true );
+ if (( appended.signature() != "d73d25ccd6011936d08b6d0d89183b7a61790544c2195269aff4db2f782ffc08" ) &&
+ ( appended.signature() != "d0bbbb124a690fc7a275b19a9116fd7e1079786d97e02da319122617b3416de2" ))
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Vertical append failed, signature = "
+ << appended.signature() << endl;
+ appended.write("appendImages_vertical_out.miff");
+ // appended.display();
+ }
+
+ }
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/Magick++/tests/attributes.cpp b/Magick++/tests/attributes.cpp
new file mode 100644
index 0000000..a82299b
--- /dev/null
+++ b/Magick++/tests/attributes.cpp
@@ -0,0 +1,1543 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
+//
+// Tests for setting/getting Magick::Image attributes
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ volatile int failures=0;
+
+ try {
+
+ unsigned int columns = 640;
+ unsigned int rows = 480;
+ Geometry geometry(columns,rows);
+ Color canvasColor( "red" );
+ Image image( geometry, canvasColor);
+
+ //
+ // antiAlias
+ //
+
+ // Test default value
+ if ( image.antiAlias() != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", antiAlias default not true" << endl;
+ }
+
+ // Test setting false
+ image.antiAlias( false );
+ if ( image.antiAlias() != false )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", antiAlias not false" << endl;
+ }
+
+ // Test setting true
+ image.antiAlias( true );
+ if ( image.antiAlias() != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", antiAlias not true" << endl;
+ }
+
+ //
+ // adjoin
+ //
+
+ // Test default value
+ if ( image.adjoin() != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", adjoin default not 'true' as expected" << endl;
+ }
+
+ // Test setting false
+ image.adjoin( false );
+ if ( image.adjoin() != false )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", adjoin failed set to 'false'" << endl;
+ }
+
+ // Test setting true
+ image.adjoin( true );
+ if ( image.adjoin() != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", adjoin failed set to 'true'" << endl;
+ }
+
+ //
+ // animationDelay
+ //
+
+ // Test default value
+ if ( image.animationDelay() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", animationDelay default ("
+ << image.animationDelay()
+ << ") not 0 as expected" << endl;
+ }
+
+ // Test setting to 0
+ image.animationDelay( 0 );
+ if ( image.animationDelay() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set animationDelay to 0" << endl;
+ }
+
+ // Test setting to 100
+ image.animationDelay( 100 );
+ if ( image.animationDelay() != 100 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set animationDelay to 100" << endl;
+ }
+ image.animationDelay(0);
+
+ //
+ // animationIterations
+ //
+
+ // Test default value
+ if ( image.animationIterations() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", animationIterations default ("
+ << image.animationIterations()
+ << ") not 0 as expected" << endl;
+ }
+
+ // Test setting to 0
+ image.animationIterations( 0 );
+ if ( image.animationIterations() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set animationIterations to 0" << endl;
+ }
+
+ // Test setting to 100
+ image.animationIterations( 100 );
+ if ( image.animationIterations() != 100 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set animationIterations to 100" << endl;
+ }
+ image.animationIterations( 0 );
+
+ //
+ // backgroundColor
+ //
+
+ // Test default value.
+ if ( image.backgroundColor() != ColorRGB("white") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", backgroundColor default ("
+ << string(image.backgroundColor())
+ << ") is incorrect" << endl;
+ }
+
+ // Test setting to blue
+ image.backgroundColor("blue");
+ if ( !image.backgroundColor().isValid() )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", backgroundColor ("
+ << string(image.backgroundColor())
+ << ") failed set to 'blue'" << endl;
+ }
+ else
+ if ( string(image.backgroundColor()) != "#0000FF" &&
+ string(image.backgroundColor()) != "#00000000FFFF" &&
+ string(image.backgroundColor()) != "#0000000000000000FFFFFFFF" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", backgroundColor ("
+ << string(image.backgroundColor()) << ") is incorrect"
+ << endl;
+ }
+
+ // Test setting using hex color
+ image.backgroundColor("#00AAFF");
+ if ( !image.backgroundColor().isValid() )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", backgroundColor ("
+ << string(image.backgroundColor())
+ << ") is incorrectly invalid" << endl;
+ }
+ else
+ if ( string(image.backgroundColor()) != "#00AAFF" &&
+ string(image.backgroundColor()) != "#0000AAAAFFFF" &&
+ string(image.backgroundColor()) != "#00000000AAAAAAAAFFFFFFFF" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", backgroundColor ("
+ << string(image.backgroundColor())
+ << ") is incorrect"
+ << endl;
+ }
+
+ //
+ // backgroundTexture
+ //
+
+ // Test default value
+ if ( image.backgroundTexture() != "" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", backgroundTexture default ("
+ << image.backgroundTexture()
+ << ") is incorrect" << endl;
+ }
+
+ // Test setting/getting value
+ image.backgroundTexture("afile.jpg");
+ if ( image.backgroundTexture() != "afile.jpg" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", backgroundTexture ("
+ << image.backgroundTexture()
+ << ") is incorrect" << endl;
+ }
+
+ // Test setting back to default
+ image.backgroundTexture("");
+ if ( image.backgroundTexture() != "" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", backgroundTexture ("
+ << image.backgroundTexture()
+ << ") failed to set to \"\"" << endl;
+ }
+
+ //
+ // baseColumns
+ //
+ if ( image.baseColumns() != columns )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", baseColumns ("
+ << image.baseColumns()
+ << ") is not equal to "
+ << columns
+ << " as expected"
+ << endl;
+ }
+
+
+ //
+ // baseFilename
+ //
+ // Base filename is color for xc images
+ if ( image.baseFilename() != "#FF0000" &&
+ image.baseFilename() != "#FFFF00000000" &&
+ image.baseFilename() != "#FFFFFFFF0000000000000000")
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", baseFilename ("
+ << image.baseFilename()
+ << ") is incorrect"
+ << endl;
+ }
+
+ //
+ // baseRows
+ //
+ if ( image.baseRows() != rows )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", baseRows ("
+ << image.baseRows()
+ << ") != rows ("
+ << rows
+ << ")"
+ << endl;
+ }
+
+ //
+ // borderColor
+ //
+ if ( image.borderColor() != ColorRGB("#dfdfdf") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", borderColor default ("
+ << string(image.borderColor())
+ << ") is incorrect" << endl;
+ }
+
+ image.borderColor("#FF0000");
+ if ( image.borderColor() != Color("#FF0000") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set borderColor ("
+ << string(image.borderColor())
+ << ")" << endl;
+ }
+
+ image.borderColor("black");
+ if ( image.borderColor() != Color("#000000") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set borderColor ("
+ << string(image.borderColor())
+ << ")"
+ << endl;
+ }
+
+ //
+ // boxColor
+ //
+ image.boxColor("#FF0000");
+ if ( image.boxColor() != Color("#FF0000") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set boxColor ("
+ << string(image.boxColor())
+ << ")"
+ << endl;
+ }
+
+ image.boxColor("black");
+ if ( image.boxColor() != Color("#000000") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set boxColor ("
+ << string(image.boxColor())
+ << ") to #000000"
+ << endl;
+ }
+
+ //
+ // chromaBluePrimary
+ //
+ {
+ // Test default setting
+ double x, y;
+ image.chromaBluePrimary( &x, &y );
+ if ( x != 0 || y != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", chromaBluePrimary x/y defaults are non-zero"
+ << endl;
+ }
+
+ // Test set/get
+ image.chromaBluePrimary( 50, 100 );
+ image.chromaBluePrimary( &x, &y );
+ if ( x != 50 || y != 100 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", chromaBluePrimary x/y failed set/get" << endl;
+ }
+ }
+
+ //
+ // chromaGreenPrimary
+ //
+ {
+ // Test default setting
+ double x, y;
+ image.chromaGreenPrimary( &x, &y );
+ if ( x != 0 || y != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", chromaGreenPrimary x/y defaults are non-zero" << endl;
+ }
+
+ // Test set/get
+ image.chromaGreenPrimary( 50, 100 );
+ image.chromaGreenPrimary( &x, &y );
+ if ( x != 50 || y != 100 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", chromaGreenPrimary x/y failed set/get" << endl;
+ }
+ }
+
+ //
+ // chromaRedPrimary
+ //
+ {
+ // Test default setting
+ double x, y;
+ image.chromaRedPrimary( &x, &y );
+ if ( x != 0 || y != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", chromaRedPrimary x/y defaults are non-zero" << endl;
+ }
+
+ // Test set/get
+ image.chromaRedPrimary( 50, 100 );
+ image.chromaRedPrimary( &x, &y );
+ if ( x != 50 || y != 100 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", chromaRedPrimary x/y failed set/get" << endl;
+ }
+ }
+
+ //
+ // chromaWhitePoint
+ //
+ {
+ // Test default setting
+ double x, y;
+ image.chromaWhitePoint( &x, &y );
+ if ( x != 0 || y != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", chromaWhitePoint x/y defaults are non-zero" << endl;
+ }
+
+ // Test set/get
+ image.chromaWhitePoint( 50, 100 );
+ image.chromaWhitePoint( &x, &y );
+ if ( x != 50 || y != 100 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", chromaWhitePoint x/y failed set/get" << endl;
+ }
+ }
+
+ //
+ // classType
+ //
+ if ( image.classType() != PseudoClass )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", classType is not PseudoClass" << endl;
+ }
+
+ //
+ // colorFuzz
+ //
+
+ // Test default
+ if ( image.colorFuzz() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", colorFuzz default is non-zero" << endl;
+ }
+
+ // Test set/get
+ image.colorFuzz( 2 );
+ if ( image.colorFuzz() != 2 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", colorFuzz failed to set/get" << endl;
+ }
+ image.colorFuzz( 0 );
+
+ //
+ // colorMap
+ //
+ // Test default (first color is image canvas base color)
+ if ( image.colorMap(0) != canvasColor )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", colorMap(0) ("
+ << string(image.colorMap(0))
+ << ") is not canvas base color " << endl;
+ }
+
+ // Test setting/getting colorMap
+ image.colorMap(0,"#00AAFF");
+ if ( image.colorMap(0) != Color("#00AAFF") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", failed to set/get colorMap(0)" << endl;
+ }
+ image.colorMap(0,canvasColor);
+
+ //
+ // columns
+ //
+ if ( image.columns() != columns )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", columns is not equal to canvas image columns" << endl;
+ }
+
+ //
+ // comment
+ //
+ // Test default
+ if ( image.comment().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", comment default non-zero length" << endl;
+ }
+
+ // Test set/get
+ {
+ std::string comment("This is a comment.");
+ image.comment( comment );
+ if ( image.comment() != comment )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", comment set/get failed" << endl;
+ }
+ }
+
+ // Test resetting comment
+ image.comment( string() );
+ if ( image.comment().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", comment failed to reset" << endl;
+ }
+
+ //
+ // compressType
+ //
+ // Test default
+ if ( image.compressType() != UndefinedCompression )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", compressType default is incorrect" << endl;
+ }
+
+ // Test set/get
+ image.compressType(RLECompression);
+ if ( image.compressType() != RLECompression )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", compressType set/get failed" << endl;
+ }
+ image.compressType(UndefinedCompression);
+
+ //
+ // density
+ //
+ {
+ // Test defaults
+ if ( image.density() != Geometry(72,72) )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", density default is not 72x72 as expected" << endl;
+ }
+
+ // Test set/get
+ Geometry density(150,75);
+ image.density(density);
+ if ( image.density() != density )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", density set/get failed" << endl;
+ }
+
+
+ if ( image.xResolution() != 150 ||
+ image.yResolution() != 75 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", density set/get failed" << endl;
+ }
+
+ image.density("72x72");
+
+ }
+
+ //
+ // Format specific defines
+ //
+ if (image.defineSet("foo","bar"))
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", define for foo:bar incorrectly reports set."
+ << endl;
+ }
+
+ image.defineSet("foo","bar",true);
+ if (!image.defineSet("foo","bar"))
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", define for foo:bar incorrectly reports not set."
+ << endl;
+ }
+
+ image.defineSet("foo","bar",false);
+ if (image.defineSet("foo","bar"))
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", define for foo:bar incorrectly reports set."
+ << endl;
+ }
+
+ image.defineValue("foo","bar","value");
+ std::string value = image.defineValue("foo","bar");
+ if (image.defineValue("foo","bar") != "value")
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", define for foo:bar incorrectly reports value \""
+ << value << "\""
+ << endl;
+ }
+
+ image.defineSet("foo","bar",false);
+ if (image.defineSet("foo","bar"))
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", define for foo:bar incorrectly reports set."
+ << endl;
+ }
+
+ //
+ // depth
+ //
+ if ( image.depth() != QuantumDepth )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", depth ("
+ << image.depth()
+ << ") is not equal to " << QuantumDepth << endl;
+ }
+
+ //
+ // Directory
+ //
+ {
+ // Since this is not a montage image, simply verify error report
+ bool caughtException = false;
+ cout << "Testing throwing and catching exceptions. A program crash or a message" << endl
+ << "that the exception was not caught indicates a test failure. A properly" << endl
+ << "formatted exception message indicates success:" << endl;
+ try
+ {
+ //image.directory();
+ Magick::Image bad_image("foo");
+ }
+ catch ( Exception &exception_)
+ {
+ cout << "Caught exception, good!:" << endl
+ << " \"" << exception_.what() << "\"" << endl;
+ caughtException = true;
+ }
+ if ( caughtException != true )
+ {
+ ++failures;
+ cout << "failed to catch exception!" << endl;
+ }
+ }
+
+ //
+ // fileName
+ //
+ // Test default
+ if ( image.fileName() != string("xc:") + string(canvasColor) )
+ {
+ ++failures;
+ cout << "Line: "
+ << __LINE__
+ << ", fileName ("
+ << image.fileName()
+ << ") is not canvas color ("
+ << string(canvasColor)
+ <<") as expected" << endl;
+ }
+
+ // Set/get value
+ image.fileName("filename.jpg");
+ if ( image.fileName() != "filename.jpg" )
+ {
+ ++failures;
+ cout << "Line: "
+ << __LINE__
+ << ", fileName ("
+ << image.fileName()
+ << ") failed to set/get" << endl;
+ }
+ image.fileName(canvasColor);
+
+ //
+ // fileSize
+ //
+ // Test default
+ if ( image.fileSize() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", fileSize ("
+ << static_cast<long>(image.fileSize())
+ << ") is not zero as expected" << endl;
+ }
+
+ //
+ // filterType
+ //
+ // Test default
+ if ( image.filterType() != UndefinedFilter )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", filterType default ("
+ << (int)image.filterType()
+ << ") is incorrect" << endl;
+ }
+
+ // Test set/get
+ image.filterType( TriangleFilter );
+ if ( image.filterType() != TriangleFilter )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", filterType set/get failed"
+ << endl;
+ }
+
+ //
+ // font
+ //
+
+ // Test set/get
+ image.font("helvetica");
+ if ( image.font() != "helvetica" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", font set/get failed" << endl;
+ }
+ // Test set to null font
+ image.font( string() );
+ if ( image.font().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", font failed to unset" << endl;
+ }
+
+ //
+ // fontPointsize
+ //
+ // Test default
+ if ( image.fontPointsize() != 12 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", fontPointsize ("
+ << image.fontPointsize()
+ << ") is not default of 12 as expected"
+ << endl;
+ }
+
+ // Test set/get
+ image.fontPointsize(10);
+ if ( image.fontPointsize() != 10 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", fontPointsize set/get failed" << endl;
+ }
+ image.fontPointsize(12);
+
+ //
+ // format
+ //
+ if ( image.format() != "Constant image uniform color" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", format (" << image.format() << ") is not expected value" << endl;
+ }
+
+ //
+ // formatExpression
+ //
+ {
+ std::string formatSpec("%wx%h");
+ std::string expected("640x480");
+ if ( image.formatExpression(formatSpec) != expected )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", formatExpression (" << image.formatExpression(formatSpec)
+ << ") is not expected value" << endl;
+ }
+ }
+
+ //
+ // gamma
+ //
+ if ( image.gamma() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", gamma correction is not zero as expected" << endl;
+ }
+
+ //
+ // geometry
+ //
+ {
+ bool caughtException = false;
+ try
+ {
+ image.geometry();
+ }
+ catch ( Exception )
+ {
+ caughtException = true;
+ }
+ if ( caughtException != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", geometry failed to report missing image geometry";
+ }
+ }
+
+ //
+ // gifDisposeMethod
+ //
+ // Test default
+ if ( image.gifDisposeMethod() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", gifDisposeMethod default is not zero as expected" << endl;
+ }
+
+ // Test set/get
+ image.gifDisposeMethod(4);
+ if ( image.gifDisposeMethod() != 4 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", gifDisposeMethod set/get failed" << endl;
+ }
+ image.gifDisposeMethod(0);
+
+ //
+ // interlaceType
+ //
+ // Test default
+ if ( image.interlaceType() != UndefinedInterlace )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", interlaceType default is not UndefinedInterlace as expected" << endl;
+ }
+
+ // Test set/get
+ image.interlaceType( PlaneInterlace );
+ if ( image.interlaceType() != PlaneInterlace )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", interlaceType set/get failed" << endl;
+ }
+ image.interlaceType(NoInterlace);
+
+ //
+ // label
+ //
+ // Test default
+ if ( image.label().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", label default is not empty string as expected" << endl;
+ }
+
+ // Test set/get
+ image.label("How now brown cow?");
+ if ( image.label() != "How now brown cow?" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", label set/get failed" << endl;
+ }
+ // Test set to default
+ image.label( string() );
+ if ( image.label().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", label failed to unset" << endl;
+ }
+
+ //
+ // lineWidth
+ //
+ // Test default
+ if ( image.lineWidth() != 1 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", lineWidth default is not 1 as expected" << endl;
+ }
+
+ // Test set/get
+ image.lineWidth(2);
+ if ( image.lineWidth() != 2 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", lineWidth set/get failed" << endl;
+ }
+ image.lineWidth(1);
+
+ //
+ // magick
+ //
+ // Test canvas default
+ if ( image.magick() != "XC" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", magick canvas default is not XC as expected" << endl;
+ }
+
+ // Test set/get
+ image.magick("GIF");
+ if ( image.magick() != "GIF" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", magick set/get failed" << endl;
+ }
+
+ image.magick("XC");
+
+ //
+ // matte
+ //
+ // Test default
+ if ( image.matte() != false )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", matte default is not false as expected" << endl;
+ }
+
+ // Test set/get
+ image.matte(true);
+ if ( image.matte() != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", matte set/get failed" << endl;
+ }
+ image.matte(false);
+
+ //
+ // matteColor
+ //
+ // Test default
+ if ( image.matteColor() != Color("#BDBDBD") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", matteColor default is not #BDBDBD as expected" << endl;
+ }
+
+ // Test set/get
+ image.matteColor(ColorRGB(0.5,0.5,1));
+ if ( image.matteColor() != ColorRGB(0.5,0.5,1) )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", matteColor set/get failed" << endl;
+ }
+
+ // Test unset
+ image.matteColor( Color() );
+
+ image.matteColor("#BDBDBD");
+
+ //
+ // meanErrorPerPixel
+ //
+ if ( image.meanErrorPerPixel() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", meanErrorPerPixel is not zero as expected" << endl;
+ }
+
+ //
+ // montageGeometry
+ //
+ {
+ bool caughtException = false;
+ try
+ {
+ image.montageGeometry();
+ }
+ catch ( Exception )
+ {
+ caughtException = true;
+ }
+ if ( caughtException != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", montageGeometry failed to report missing montage geometry";
+ }
+ }
+
+ //
+ // monochrome
+ //
+ // Test default
+ if ( image.monochrome() != false )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", monochrome is not false as expected" << endl;
+ }
+
+ // Test set/get
+ image.monochrome(true);
+ if ( image.monochrome() != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", monochrome get/set failed" << endl;
+ }
+ image.monochrome(false);
+
+ //
+ // normalizedMaxError
+ //
+ if ( image.normalizedMaxError() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ",normalizedMaxError is not zero as expected" << endl;
+ }
+
+ //
+ // normalizedMeanError
+ //
+ if ( image.normalizedMeanError() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", normalizedMeanError is not zero as expected" << endl;
+ }
+
+ //
+ // penColor
+ //
+
+ image.penColor(ColorRGB(0.5,0.5,1));
+ if ( image.penColor() != ColorRGB(0.5,0.5,1) )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", penColor ("
+ << string(image.penColor())
+ << ") set/get failed" << endl;
+ }
+
+ //
+ // strokeColor
+ //
+
+ image.strokeColor(ColorRGB(0.5,0.5,1));
+ if ( image.strokeColor() != ColorRGB(0.5,0.5,1) )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", strokeColor ("
+ << string(image.strokeColor())
+ << ") set/get failed" << endl;
+ }
+
+
+ //
+ // fillColor
+ //
+
+ image.fillColor(ColorRGB(0.5,0.5,1));
+ if ( image.fillColor() != ColorRGB(0.5,0.5,1) )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", fillColor ("
+ << string(image.fillColor())
+ << ") set/get failed" << endl;
+ }
+
+ //
+ // pixelColor
+ //
+ // Test default
+ if ( image.pixelColor(40,60) != canvasColor )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", pixelColor default ("
+ << string(image.pixelColor(40,60))
+ << ") is not canvas color ("
+ << string(canvasColor)
+ << ") as expected" << endl;
+ }
+
+ // Test set/get
+ image.pixelColor(40,60, ColorRGB(0.5,1,1));
+ if ( image.pixelColor(40,60) != ColorRGB(0.5,1,1) )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", pixelColor set/get failed" << endl;
+ }
+
+ //
+ // page
+ //
+ // Test default
+ if ( image.page() != Geometry(image.columns(),image.rows(),0,0) )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", page default "
+ << "(" << string(image.page()) << ")"
+ << " is not image dimensions as expected" << endl;
+ }
+
+ // Test set/get
+ image.page("letter+43+43>");
+ if ( image.page() != "612x792+43+43" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", page set/get failed (" << string(image.page()) << ")" << endl;
+ }
+
+ //
+ // quality
+ //
+ // Test default
+ if ( image.quality() != 75 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", quality default is not 75 as expected" << endl;
+ }
+
+ // Test set/get
+ image.quality(65);
+ if ( image.quality() != 65 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", quality set/get failed" << endl;
+ }
+ image.quality(75);
+
+ //
+ // quantizeColors
+ //
+ // Test default
+ if ( image.quantizeColors() != 256 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", quantizeColors is not 256 as expected" << endl;
+ }
+
+ // Test set/get
+ image.quantizeColors(200);
+ if ( image.quantizeColors() != 200 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", quantizeColors set/get failed" << endl;
+ }
+ image.quantizeColors(0);
+
+ //
+ // quantizeColorSpace
+ //
+ // Test default
+ if ( image.quantizeColorSpace() != RGBColorspace )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", quantizeColorSpace is not RGBColorspace as expected" << endl;
+ }
+
+ // Test set/get
+ image.quantizeColorSpace(YIQColorspace);
+ if ( image.quantizeColorSpace() != YIQColorspace )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", quantizeColorSpace set/get failed" << endl;
+ }
+ image.quantizeColorSpace(RGBColorspace);
+
+ //
+ // quantizeDither
+ //
+ // Test default
+ if ( image.quantizeDither() != true )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", quantizeDither is not true as expected" << endl;
+ }
+
+ // Test set/get
+ image.quantizeDither(false);
+ if ( image.quantizeDither() != false )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", quantizeDither get/set failed" << endl;
+ }
+ image.quantizeDither(true);
+
+ //
+ // quantizeTreeDepth
+ //
+ if ( image.quantizeTreeDepth() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", quantizeTreeDepth default is "
+ << image.quantizeTreeDepth()
+ << " rather than zero as expected" << endl;
+ }
+
+ image.quantizeTreeDepth(7);
+ if ( image.quantizeTreeDepth() != 7 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", quantizeTreeDepth set/get failed" << endl;
+ }
+ image.quantizeTreeDepth(8);
+
+ //
+ // renderingIntent
+ //
+ if ( image.renderingIntent() != UndefinedIntent )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", renderingIntent default is not UndefinedIntent as expected"
+ << endl;
+ }
+
+ image.renderingIntent(PerceptualIntent);
+ if ( image.renderingIntent() != PerceptualIntent )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", renderingIntent set/get failed" << endl;
+ }
+ image.renderingIntent(UndefinedIntent);
+
+ //
+ // resolutionUnits
+ //
+ if ( image.resolutionUnits() != UndefinedResolution )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", resolutionUnits default is not UndefinedResolution as expected"
+ << endl;
+ }
+
+ image.resolutionUnits(PixelsPerCentimeterResolution);
+ if ( image.resolutionUnits() != PixelsPerCentimeterResolution )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", resolutionUnits set/get failed" << endl;
+ }
+ image.resolutionUnits(UndefinedResolution);
+
+ //
+ // rows
+ //
+ if ( image.rows() != rows )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", rows is canvas rows as expected" << endl;
+ }
+
+ //
+ // scene
+ //
+ if ( image.scene() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", scene default is not zero as expected" << endl;
+ }
+
+ image.scene(5);
+ if ( image.scene() != 5 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", scene set/get failed" << endl;
+ }
+ image.scene(0);
+
+ //
+ // signature
+ //
+
+ if ( image.signature() != "3af362f5b4ad66e9c4a684427fad20c12f2fd9c3c1c7128b00a050d7bec72f44" &&
+ image.signature() != "a529e8fe1d83890d893a153777be5f0fd48cf21e0124adee65da248694a204b2" &&
+ image.signature() != "573301a0edb9861de8d02b57e445ba5ea689a494d53a6299e8693b7479ba9cb6")
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", signature ("
+ << image.signature()
+ << ") is incorrect" << endl;
+ image.display();
+ }
+
+ //
+ // size
+ //
+ if ( image.size() != geometry )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", size ("
+ << string(image.size())
+ << ") is not equal to geometry ("
+ << string(geometry)
+ << ")"
+ << endl;
+ }
+
+ image.size("800x600");
+ if ( image.size() != Geometry("800x600") )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", size set/get failed" << endl;
+ }
+ image.size( geometry );
+
+ //
+ // subImage
+ //
+ if ( image.subImage() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", subImage default is not zero as expected" << endl;
+ }
+
+ image.subImage(5);
+ if ( image.subImage() != 5 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", subImage set/get failed" << endl;
+ }
+ image.subImage(0);
+
+ //
+ // subRange
+ //
+ if ( image.subRange() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", subRange default is not zero as expected" << endl;
+ }
+
+ image.subRange(5);
+ if ( image.subRange() != 5 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", subRange set/get failed" << endl;
+ }
+ image.subRange(0);
+
+ //
+ // tileName
+ //
+ if ( image.tileName().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", tileName default is not empty string as expected" << endl;
+ }
+
+ image.tileName("How now brown cow?");
+ if ( image.tileName() != "How now brown cow?" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", tileName set/get failed" << endl;
+ }
+
+ image.tileName( string() );
+ if ( image.tileName().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", tileName failed to unset" << endl;
+ }
+
+ //
+ // totalColors
+ //
+ if ( image.totalColors() != 2 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << ", totalColors is " << image.totalColors()
+ << " rather than 2 as expected" << endl;
+ }
+
+ //
+ // type
+ //
+ image.type(PaletteType);
+ if ( image.type() != PaletteType )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", type is not PaletteType as expected. Reported type "
+ << (int) image.type() << endl;
+ }
+
+ //
+ // verbose
+ //
+ if ( image.verbose() != false )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", verbose is not false as expected" << endl;
+ }
+
+ //
+ // view
+ //
+ if ( image.view().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", view default is not empty string as expected" << endl;
+ }
+
+ image.view("How now brown cow?");
+ if ( image.view() != "How now brown cow?" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", view set/get failed" << endl;
+ }
+
+ image.view( string() );
+ if ( image.view().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", view failed to unset" << endl;
+ }
+
+ //
+ // x11Display
+ //
+ if ( image.x11Display().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", x11Display default is not empty string as expected" << endl;
+ }
+
+ image.x11Display(":0.0");
+ if ( image.x11Display() != ":0.0" )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", x11Display set/get failed" << endl;
+ }
+
+ image.x11Display( string() );
+ if ( image.x11Display().length() != 0 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", x11Display failed to unset" << endl;
+ }
+
+ //
+ // xResolution
+ //
+ if ( image.xResolution() != 72 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", xResolution default (" << image.xResolution()
+ << ") is not zero as expected" << endl;
+ }
+
+ //
+ // yResolution
+ //
+ if ( image.yResolution() != 72 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << ", yResolution default (" << image.yResolution()
+ << ") is not zero as expected" << endl;
+ }
+ }
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/tests/averageImages.cpp b/Magick++/tests/averageImages.cpp
new file mode 100644
index 0000000..551888c
--- /dev/null
+++ b/Magick++/tests/averageImages.cpp
@@ -0,0 +1,73 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2003
+//
+// Test STL averageImages function
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+#include <vector>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ //
+ // Test averageImages
+ //
+
+ list<Image> imageList;
+ readImages( &imageList, srcdir + "test_image_anim.miff" );
+
+ Image averaged;
+ averageImages( &averaged, imageList.begin(), imageList.end() );
+ // averaged.display();
+ if ( averaged.signature() != "e0c649d1cb9c773507799c22ee437f32e15570e55d58ecc62f0c5a0c6dc36368" &&
+ averaged.signature() != "76e3d52bdb28335843afa0f82adcedd1b0794472bb193f311399322863266ed2" &&
+ averaged.signature() != "c2a2a727df34c85e3b6528c06cb12967574d6c85e1d0501055506765c578f7cc")
+ {
+ cout << "Line: " << __LINE__
+ << " Averaging image failed, signature = "
+ << averaged.signature() << endl;
+ averaged.display();
+ ++failures;
+ }
+ }
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/Magick++/tests/coalesceImages.cpp b/Magick++/tests/coalesceImages.cpp
new file mode 100644
index 0000000..4db76f9
--- /dev/null
+++ b/Magick++/tests/coalesceImages.cpp
@@ -0,0 +1,62 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2003
+//
+// Test STL coalesceImages function
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+#include <vector>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ //
+ // Test coalesceImages
+ //
+
+ list<Image> imageList;
+ readImages( &imageList, srcdir + "test_image_anim.miff" );
+
+ list<Image> coalescedList;
+ coalesceImages( &coalescedList, imageList.begin(), imageList.end() );
+ }
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/Magick++/tests/coderInfo.cpp b/Magick++/tests/coderInfo.cpp
new file mode 100644
index 0000000..e5c5df0
--- /dev/null
+++ b/Magick++/tests/coderInfo.cpp
@@ -0,0 +1,134 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 2001, 2002, 2003
+//
+// Test Magick::CoderInfo class and Magick::coderInfoList
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+
+using namespace std;
+
+using namespace Magick;
+
+int test( CoderInfo::MatchType isReadable_,
+ CoderInfo::MatchType isWritable_,
+ CoderInfo::MatchType isMultiFrame_ )
+{
+ int result = 0;
+ list<CoderInfo> coderList;
+ coderInfoList( &coderList, isReadable_, isWritable_, isMultiFrame_ );
+ list<CoderInfo>::iterator entry = coderList.begin();
+ while( entry != coderList.end() )
+ {
+ // Readable
+ if ( isReadable_ != CoderInfo::AnyMatch &&
+ (( entry->isReadable() && isReadable_ != CoderInfo::TrueMatch ) ||
+ ( !entry->isReadable() && isReadable_ != CoderInfo::FalseMatch )) )
+ {
+ cout << "Entry \""
+ << entry->name()
+ << "\" has unexpected readablity state ("
+ << static_cast<int>(entry->isReadable())
+ << ")"
+ << endl;
+ ++result;
+ }
+
+ // Writable
+ if ( isWritable_ != CoderInfo::AnyMatch &&
+ (( entry->isWritable() && isWritable_ != CoderInfo::TrueMatch ) ||
+ ( !entry->isWritable() && isWritable_ != CoderInfo::FalseMatch )) )
+ {
+ cout << "Entry \""
+ << entry->name()
+ << "\" has unexpected writablity state ("
+ << static_cast<int>(entry->isWritable())
+ << ")"
+ << endl;
+ ++result;
+ }
+
+ // MultiFrame
+ if ( isMultiFrame_ != CoderInfo::AnyMatch &&
+ (( entry->isMultiFrame() && isMultiFrame_ != CoderInfo::TrueMatch ) ||
+ ( !entry->isMultiFrame() && isMultiFrame_ != CoderInfo::FalseMatch )) )
+ {
+ cout << "Entry \""
+ << entry->name()
+ << "\" has unexpected multiframe state ("
+ << static_cast<int>(entry->isMultiFrame())
+ << ")"
+ << endl;
+ ++result;
+ }
+
+ entry++;
+ }
+
+ return result;
+}
+
+int main( int /*argc*/, char **argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try {
+
+ CoderInfo coderInfo("GIF");
+ if ( coderInfo.name() != string("GIF") )
+ {
+ cout << "Unexpected coder name \""
+ << coderInfo.name()
+ << "\""
+ << endl;
+ ++failures;
+ }
+
+ if( coderInfo.description() != string("CompuServe graphics interchange format") )
+ {
+ cout << "Unexpected coder description \""
+ << coderInfo.description()
+ << "\""
+ << endl;
+ ++failures;
+ }
+
+ failures += test(CoderInfo::AnyMatch,CoderInfo::AnyMatch,CoderInfo::AnyMatch);
+ failures += test(CoderInfo::FalseMatch,CoderInfo::FalseMatch,CoderInfo::FalseMatch);
+
+ failures += test(CoderInfo::TrueMatch,CoderInfo::AnyMatch,CoderInfo::AnyMatch);
+ failures += test(CoderInfo::FalseMatch,CoderInfo::AnyMatch,CoderInfo::AnyMatch);
+
+ failures += test(CoderInfo::AnyMatch,CoderInfo::TrueMatch,CoderInfo::AnyMatch);
+ failures += test(CoderInfo::AnyMatch,CoderInfo::FalseMatch,CoderInfo::AnyMatch);
+
+ failures += test(CoderInfo::AnyMatch,CoderInfo::AnyMatch,CoderInfo::TrueMatch);
+ failures += test(CoderInfo::AnyMatch,CoderInfo::AnyMatch,CoderInfo::FalseMatch);
+ }
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/tests/color.cpp b/Magick++/tests/color.cpp
new file mode 100644
index 0000000..1e9c45b
--- /dev/null
+++ b/Magick++/tests/color.cpp
@@ -0,0 +1,155 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
+//
+// Test Magick::Color classes
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char **argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try {
+
+ //
+ // Verify conversion from named colors as well as ColorRGB constructor
+ //
+
+ {
+ struct colorStr
+ {
+ const char* color;
+ double red;
+ double green;
+ double blue;
+ };
+
+ // Convert ratios from rgb.txt via value/255
+ struct colorStr colorMap [] =
+ {
+ { "red", 1,0,0 },
+ { "green", 0,0.5019607843137256,0 },
+ { "blue", 0,0,1 },
+ { "black", 0,0,0 },
+ { "white", 1,1,1 },
+ { "cyan", 0,1,1 },
+ { "magenta", 1,0,1 },
+ { "yellow", 1,1,0 },
+ { NULL, 0,0,0 }
+ };
+
+ for ( int i = 0; colorMap[i].color != NULL; i++ )
+ {
+ {
+ Color color( colorMap[i].color );
+ ColorRGB colorMatch( colorMap[i].red,
+ colorMap[i].green,
+ colorMap[i].blue );
+ if ( color != colorMatch )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__ << " Color(\""
+ << colorMap[i].color << "\") is "
+ << string(color)
+ << " rather than "
+ << string(colorMatch)
+ << endl;
+ // printf ("Green: %10.16f\n", color.green());
+ }
+ }
+ }
+ }
+
+ // Test conversion to/from X11-style color specifications
+ {
+ const char * colorStrings[] =
+ {
+ "#ABC",
+ "#AABBCC",
+ "#AAAABBBBCCCC",
+ NULL
+ };
+
+#if QuantumDepth == 8
+ string expectedString = "#AABBCC";
+#elif QuantumDepth == 16
+ string expectedString = "#AAAABBBBCCCC";
+#elif QuantumDepth == 32
+ string expectedString = "#AAAAAAAABBBBBBBBCCCCCCCC";
+#else
+# error Quantum depth not supported!
+#endif
+
+ for ( int i = 0; colorStrings[i] != NULL; ++i )
+ {
+ if ( string(Color(colorStrings[i])) != expectedString )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Conversion from " << colorStrings[i]
+ << " is "
+ << string(Color(colorStrings[i])) << " rather than "
+ << expectedString
+ << endl;
+ }
+ }
+ }
+
+ // Test ColorGray
+ {
+#undef MagickEpsilon
+#define MagickEpsilon 1.0e-12
+ double resolution = 1.0/MaxRGB;
+ double max_error = resolution + MagickEpsilon;
+
+ if ( resolution < 0.0001 )
+ resolution = 0.0001;
+
+ for( double value = 0; value < 1.0 + MagickEpsilon; value += resolution )
+ {
+ ColorGray gray(value);
+ if ( gray.shade() < value - max_error || gray.shade() > value + max_error )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " shade is "
+ << gray.shade()
+ << " rather than nominal"
+ << value
+ << endl;
+ }
+ }
+ }
+
+ }
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Magick++/tests/colorHistogram.cpp b/Magick++/tests/colorHistogram.cpp
new file mode 100644
index 0000000..7e4368b
--- /dev/null
+++ b/Magick++/tests/colorHistogram.cpp
@@ -0,0 +1,101 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 2003
+//
+// Test STL colorHistogram function
+//
+
+#undef USE_VECTOR
+#define USE_MAP
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <iomanip>
+#if defined(USE_VECTOR)
+# include <vector>
+# include <utility>
+#endif
+#if defined(USE_MAP)
+# include <map>
+#endif
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize GraphicsMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ // Read image
+ Image image;
+ image.read( srcdir + "test_image.miff" );
+
+ // Create histogram vector
+#if defined(USE_MAP)
+ std::map<Color,unsigned long> histogram;
+#elif defined(USE_VECTOR)
+ std::vector<std::pair<Color,unsigned long> > histogram;
+#endif
+
+ colorHistogram( &histogram, image );
+
+ // Print out histogram
+#if (QuantumDepth == 8)
+ int quantum_width=3;
+#elif (QuantumDepth == 16)
+ int quantum_width=5;
+#else
+ int quantum_width=10;
+#endif
+
+ cout << "Histogram for file \"" << image.fileName() << "\"" << endl
+ << histogram.size() << " entries:" << endl;
+
+#if defined(USE_MAP)
+ std::map<Color,unsigned long>::const_iterator p=histogram.begin();
+#elif defined(USE_VECTOR)
+ std::vector<std::pair<Color,unsigned long> >::const_iterator p=histogram.begin();
+#endif
+ while (p != histogram.end())
+ {
+ cout << setw(10) << (int)p->second << ": ("
+ << setw(quantum_width) << (int)p->first.redQuantum() << ","
+ << setw(quantum_width) << (int)p->first.greenQuantum() << ","
+ << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
+ << endl;
+ p++;
+ }
+ }
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/Magick++/tests/exceptions.cpp b/Magick++/tests/exceptions.cpp
new file mode 100644
index 0000000..3a4ef3d
--- /dev/null
+++ b/Magick++/tests/exceptions.cpp
@@ -0,0 +1,105 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999-2010
+//
+// Tests for throwing exceptions
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+ // Initialize GraphicsMagick
+ InitializeMagick(*argv);
+
+ volatile int failures=0;
+
+ cout << "Checking for working exceptions (may crash and burn) ..." << endl;
+ cout.flush();
+
+ {
+ // Basic exception test
+ try
+ {
+ failures++;
+ cout << "Throwing native 'int' exception" << endl;
+ cout.flush();
+ throw int(100);
+ }
+ catch ( int /*value_*/ )
+ {
+ cout << "Successfully caught native 'int' exception" << endl;
+ cout.flush();
+ failures--;
+ }
+
+ // Throw a Magick++ exception class.
+ try
+ {
+ failures++;
+ cout << "Throwing 'Magick::WarningResourceLimit' exception" << endl;
+ cout.flush();
+ throw WarningResourceLimit("How now brown cow?");
+ }
+ catch( Exception & /*error_*/ )
+ {
+ cout << "Successfully caught 'Magick::WarningResourceLimit' exception" << endl;
+ cout.flush();
+ failures--;
+ }
+
+ // A more complex test
+ try
+ {
+ unsigned int columns = 640;
+ unsigned int rows = 480;
+ Geometry geometry(columns,rows);
+ Color canvasColor( "red" );
+ Image image( geometry, canvasColor);
+ {
+ try
+ {
+ failures++;
+ cout << "Throwing library 'Magick::Exception' exception" << endl;
+ cout.flush();
+ image.directory();
+ }
+ catch ( Exception& /*error_*/ )
+ {
+ cout << "Successfully caught library 'Magick::Exception' exception" << endl;
+ cout.flush();
+ failures--;
+ }
+ }
+
+ }
+ catch( Exception &error_ )
+ {
+ cout << "Bogus catch: Caught exception: " << error_.what() << endl;
+ cout.flush();
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Bogus catch: Caught exception: " << error_.what() << endl;
+ cout.flush();
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ cout.flush();
+ return 1;
+ }
+ cout << "Exception testing passed!" << endl;
+ }
+
+ return 0;
+}
diff --git a/Magick++/tests/montageImages.cpp b/Magick++/tests/montageImages.cpp
new file mode 100644
index 0000000..8b24d11
--- /dev/null
+++ b/Magick++/tests/montageImages.cpp
@@ -0,0 +1,140 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2002, 2003
+//
+// Test STL montageImages function
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+#include <vector>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** /*argv*/)
+{
+
+ // Initialize ImageMagick install location for Windows
+ // InitializeMagick(*argv);
+ InitializeMagick("");
+
+ int failures=0;
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ //
+ // Test montageImages
+ //
+
+ list<Image> imageList;
+ readImages( &imageList, srcdir + "test_image_anim.miff" );
+
+ vector<Image> montage;
+ MontageFramed montageOpts;
+
+ // Default montage
+ montageImages( &montage, imageList.begin(), imageList.end(), montageOpts );
+
+ {
+ Geometry targetGeometry(128, 126 );
+ if ( montage[0].montageGeometry() != targetGeometry )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Montage geometry ("
+ << string(montage[0].montageGeometry())
+ << ") is incorrect (expected "
+ << string(targetGeometry)
+ << ")"
+ << endl;
+ }
+ }
+
+ if ( montage[0].columns() != 768 || montage[0].rows() != 126 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Montage columns/rows ("
+ << montage[0].columns() << "x"
+ << montage[0].rows()
+ << ") incorrect. (expected 768x124)" << endl;
+ }
+
+ // Montage with options set
+ montage.clear();
+ montageOpts.borderColor( "green" );
+ montageOpts.borderWidth( 1 );
+ montageOpts.compose( OverCompositeOp );
+ montageOpts.fileName( "Montage" );
+ montageOpts.frameGeometry( "6x6+3+3" );
+ montageOpts.geometry("50x50+2+2>");
+ montageOpts.gravity( CenterGravity );
+ montageOpts.penColor( "yellow" );
+ montageOpts.shadow( true );
+ montageOpts.texture( "granite:" );
+ montageOpts.tile("2x1");
+ montageImages( &montage, imageList.begin(), imageList.end(), montageOpts );
+
+ if ( montage.size() != 3 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Montage images failed, number of montage frames is "
+ << montage.size()
+ << " rather than 3 as expected." << endl;
+ }
+
+ {
+ Geometry targetGeometry( 66, 70 );
+ if ( montage[0].montageGeometry() != targetGeometry )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Montage geometry ("
+ << string(montage[0].montageGeometry())
+ << ") is incorrect (expected "
+ << string(targetGeometry)
+ << ")."
+ << endl;
+ }
+ }
+
+ if ( montage[0].columns() != 132 || montage[0].rows() != 70 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Montage columns/rows ("
+ << montage[0].columns() << "x"
+ << montage[0].rows()
+ << ") incorrect. (expected 132x68)" << endl;
+ }
+ }
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/Magick++/tests/morphImages.cpp b/Magick++/tests/morphImages.cpp
new file mode 100644
index 0000000..00a0c82
--- /dev/null
+++ b/Magick++/tests/morphImages.cpp
@@ -0,0 +1,71 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2003
+//
+// Test STL morphImages function
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+#include <vector>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char **argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ //
+ // Test morphImages
+ //
+
+ list<Image> imageList;
+ readImages( &imageList, srcdir + "test_image_anim.miff" );
+
+ list<Image> morphed;
+ morphImages( &morphed, imageList.begin(), imageList.end(), 3 );
+
+ if ( morphed.size() != 21 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Morph images failed, number of frames is "
+ << morphed.size()
+ << " rather than 21 as expected." << endl;
+ }
+ }
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/Magick++/tests/readWriteBlob.cpp b/Magick++/tests/readWriteBlob.cpp
new file mode 100644
index 0000000..27af159
--- /dev/null
+++ b/Magick++/tests/readWriteBlob.cpp
@@ -0,0 +1,258 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2003
+//
+// Test reading/writing BLOBs using Magick++
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+using namespace Magick;
+
+//
+// Some compilers (e.g. older Tru64 UNIX) lack ios::binary
+//
+#if defined(MISSING_STD_IOS_BINARY)
+# define IOS_IN_BINARY ios::in
+#else
+# define IOS_IN_BINARY ios::in | ios::binary
+#endif
+
+// A derived Blob class to exercise updateNoCopy()
+class myBlob : public Blob
+{
+public:
+ // Construct from open binary stream
+ myBlob( ifstream &stream_ )
+ : Blob()
+ {
+ unsigned char* blobData = new unsigned char[100000];
+ char* c= reinterpret_cast<char *>(blobData);
+ size_t blobLen=0;
+ while( (blobLen< 100000) && stream_.get(*c) )
+ {
+ c++;
+ blobLen++;
+ }
+ if ((!stream_.eof()) || (blobLen == 0))
+ {
+ cout << "Failed to stream into blob!" << endl;
+ exit(1);
+ }
+
+ // Insert data into blob
+ updateNoCopy( reinterpret_cast<void*>(blobData), blobLen,
+ Blob::NewAllocator );
+ }
+};
+
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try
+ {
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ string testimage;
+
+ //
+ // Test reading BLOBs
+ //
+ {
+ string signature("");
+ {
+ Image image(srcdir + "test_image.miff");
+ signature = image.signature();
+ }
+
+ // Read raw data from file into BLOB
+ testimage = srcdir + "test_image.miff";
+ ifstream in( testimage.c_str(), IOS_IN_BINARY );
+ if( !in )
+ {
+ cout << "Failed to open file " << testimage << " for input!" << endl;
+ exit(1);
+ }
+ unsigned char* blobData = new unsigned char[100000];
+ char* c=reinterpret_cast<char *>(blobData);
+ size_t blobLen=0;
+ while( (blobLen< 100000) && in.get(*c) )
+ {
+ c++;
+ blobLen++;
+ }
+ if ((!in.eof()) || (blobLen == 0))
+ {
+ cout << "Failed to read file " << testimage << " for input!" << endl;
+ exit(1);
+ }
+ in.close();
+
+ // Construct Magick++ Blob
+ Blob blob(static_cast<const void*>(blobData), blobLen);
+ delete [] blobData;
+
+ // If construction of image fails, an exception should be thrown
+ {
+ // Construct with blob data only
+ Image image( blob );
+ if ( image.signature() != signature )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image signature "
+ << image.signature()
+ << " != "
+ << signature << endl;
+ }
+ }
+
+ {
+ // Construct with image geometry and blob data
+ Image image( blob, Geometry(148,99));
+ if ( image.signature() != signature )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image signature "
+ << image.signature()
+ << " != "
+ << signature << endl;
+ }
+ }
+
+ {
+ // Construct default image, and then read in blob data
+ Image image;
+ image.read( blob );
+ if ( image.signature() != signature )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image signature "
+ << image.signature()
+ << " != "
+ << signature << endl;
+ }
+ }
+
+ {
+ // Construct default image, and then read in blob data with
+ // image geometry
+ Image image;
+ image.read( blob, Geometry(148,99) );
+ if ( image.signature() != signature )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image signature "
+ << image.signature()
+ << " != "
+ << signature << endl;
+ }
+ }
+
+ }
+
+ // Test writing BLOBs
+ {
+ Blob blob;
+ string signature("");
+ {
+ Image image(srcdir + "test_image.miff");
+ image.magick("MIFF");
+ image.write( &blob );
+ signature = image.signature();
+ }
+ {
+ Image image(blob);
+ if ( image.signature() != signature )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image signature "
+ << image.signature()
+ << " != "
+ << signature << endl;
+ image.display();
+ }
+ }
+
+ }
+ // Test writing BLOBs via STL writeImages
+ {
+ Blob blob;
+
+ list<Image> first;
+ readImages( &first, srcdir + "test_image_anim.miff" );
+ writeImages( first.begin(), first.end(), &blob, true );
+ }
+
+ // Test constructing a BLOB from a derived class
+ {
+
+ string signature("");
+ {
+ Image image(srcdir + "test_image.miff");
+ signature = image.signature();
+ }
+
+ // Read raw data from file into BLOB
+ testimage = srcdir + "test_image.miff";
+ ifstream in( testimage.c_str(), IOS_IN_BINARY );
+ if( !in )
+ {
+ cout << "Failed to open file for input!" << endl;
+ exit(1);
+ }
+
+ myBlob blob( in );
+ in.close();
+
+ Image image( blob );
+ if ( image.signature() != signature )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image signature "
+ << image.signature()
+ << " != "
+ << signature << endl;
+ }
+ }
+ }
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+
diff --git a/Magick++/tests/readWriteImages.cpp b/Magick++/tests/readWriteImages.cpp
new file mode 100644
index 0000000..a3af750
--- /dev/null
+++ b/Magick++/tests/readWriteImages.cpp
@@ -0,0 +1,119 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2003
+//
+// Test STL readImages and writeImages functions
+//
+
+#include <Magick++.h>
+#include <string>
+#include <iostream>
+#include <list>
+#include <vector>
+
+using namespace std;
+
+using namespace Magick;
+
+int main( int /*argc*/, char ** argv)
+{
+
+ // Initialize ImageMagick install location for Windows
+ InitializeMagick(*argv);
+
+ int failures=0;
+
+ try {
+
+ string srcdir("");
+ if(getenv("SRCDIR") != 0)
+ srcdir = getenv("SRCDIR");
+
+ //
+ // Test readImages and writeImages
+ //
+
+ list<Image> first;
+ readImages( &first, srcdir + "test_image_anim.miff" );
+
+ if ( first.size() != 6 )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Read images failed, number of frames is "
+ << first.size()
+ << " rather than 6 as expected." << endl;
+ }
+
+ writeImages( first.begin(), first.end(), "testmagick_anim_out.miff" );
+
+ list<Image> second;
+ readImages( &second, "testmagick_anim_out.miff" );
+
+ list<Image>::iterator firstIter = first.begin();
+ list<Image>::iterator secondIter = second.begin();
+ while( firstIter != first.end() && secondIter != second.end() )
+ {
+ if ( *firstIter != *secondIter )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image scene: " << secondIter->scene()
+ << " is not equal to original" << endl;
+ }
+
+ if ( firstIter->scene() != secondIter->scene() )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image scene: " << secondIter->scene()
+ << " is not equal to original "
+ << firstIter->scene()
+ << endl;
+ }
+
+ if ( firstIter->rows() != secondIter->rows() )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image rows " << secondIter->rows()
+ << " are not equal to original "
+ << firstIter->rows()
+ << endl;
+ }
+
+ if ( firstIter->columns() != secondIter->columns() )
+ {
+ ++failures;
+ cout << "Line: " << __LINE__
+ << " Image columns " << secondIter->columns()
+ << " are not equal to original "
+ << firstIter->rows()
+ << endl;
+ }
+
+ firstIter++;
+ secondIter++;
+ }
+ }
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ if ( failures )
+ {
+ cout << failures << " failures" << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/Magick++/tests/test_image.miff b/Magick++/tests/test_image.miff
new file mode 100644
index 0000000..85b09f5
--- /dev/null
+++ b/Magick++/tests/test_image.miff
Binary files differ
diff --git a/Magick++/tests/test_image_anim.miff b/Magick++/tests/test_image_anim.miff
new file mode 100644
index 0000000..b8e5f0c
--- /dev/null
+++ b/Magick++/tests/test_image_anim.miff
Binary files differ
diff --git a/Magick++/tests/tests.tap b/Magick++/tests/tests.tap
new file mode 100755
index 0000000..80a3c8d
--- /dev/null
+++ b/Magick++/tests/tests.tap
@@ -0,0 +1,29 @@
+#!/bin/sh
+# -*- shell-script -*-
+#
+# Copyright 2004-2012 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+# This file is part of Magick++, the C++ API for GraphicsMagick and
+# ImageMagick. Please see the file "COPYING" included with Magick++
+# for usage and copying restrictions.
+#
+subdir=Magick++/tests
+. ./common.shi
+. ${top_srcdir}/scripts/tap-functions.shi
+
+SRCDIR=${top_srcdir}/${subdir}/
+export SRCDIR
+
+progs='appendImages attributes averageImages coalesceImages coderInfo color
+ colorHistogram exceptions montageImages morphImages readWriteBlob readWriteImages'
+
+# Number of tests we plan to run
+test_plan_fn 12
+
+cd ${subdir} || exit 1
+
+for prog in $progs
+do
+ test_command_fn "$prog" ${MEMCHECK} "./$prog"
+done
+:
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..c52c67e
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,401 @@
+# Copyright (C) 2004-2014 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Top-Level Makefile for building GraphicsMagick
+#
+#
+
+# Don't require all the GNU mandated files
+# Use XZ_OPT (a environment variable) to tune xz compression levels (e.g. XZ_OPT=-8e)
+# nostdinc
+AUTOMAKE_OPTIONS = 1.12 subdir-objects nostdinc color-tests parallel-tests dist-bzip2 dist-xz foreign dist-lzip
+
+topincludedir = @includedir@/GraphicsMagick
+
+# CPPFLAGS required by all C/C++ code
+AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
+
+ACLOCAL_AMFLAGS = -I m4
+
+MODULECOMMONFLAGS = -no-undefined -export-symbols-regex ".*" -shared -module -avoid-version
+MODULECOMMONCPPFLAGS = $(AM_CPPFLAGS)
+
+# Options to pass when running configure in the distcheck target.
+#
+# We want to preserve user-provided option variables so the same
+# compiler, headers, and libraries are used as for a normal build.
+DISTCHECK_CONFIGURE_FLAGS=$(DISTCHECK_CONFIG_FLAGS)
+
+## Make sure these will be cleaned even when they're not built by
+## default.
+CLEANFILES = \
+ $(MAGICKPP_CLEANFILES) \
+ $(UTILITIES_CLEANFILES) \
+ $(TESTS_CLEANFILES) \
+ $(WAND_CLEANFILES)
+
+bin_PROGRAMS = \
+ $(UTILITIES_PGMS)
+
+# Binary scripts
+bin_SCRIPTS = \
+ $(MAGICK_BIN_SCRPTS) \
+ $(MAGICKPP_SCRPTS) \
+ $(WAND_BIN_SCRPTS)
+
+include_HEADERS =
+
+# Headers which are not installed but which are distributed
+noinst_HEADERS = \
+ $(MAGICK_NOINST_HDRS)
+
+if WIN32_NATIVE_BUILD
+SRCDIR='$(shell @WinPathScript@ $(srcdir)/)'
+else
+SRCDIR="$(srcdir)/"
+endif
+
+# Run the tests with a proper shell detected at configure time.
+LOG_COMPILER = $(SHELL)
+
+SH_LOG_COMPILER = $(LOG_COMPILER)
+TAP_LOG_COMPILER = $(LOG_COMPILER)
+
+# Test extensions
+TEST_EXTENSIONS = .sh .tap
+
+# Tests with .tap extensions use the TAP protocol and TAP driver
+TAP_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
+ $(top_srcdir)/scripts/tap-driver.sh
+
+# Environment parameters to be used during tests
+TESTS_ENVIRONMENT = \
+ MAKE="$(MAKE)" \
+ MAKEFLAGS="$(MAKEFLAGS)" \
+ MEMCHECK="$(MEMCHECK)"
+
+# Tests to run
+TESTS = \
+ $(PERLMAGICK_TESTS) \
+ $(TESTS_TESTS) \
+ $(MAGICKPP_TESTS) \
+ $(WAND_TESTS) \
+ $(UTILITIES_TESTS)
+
+# Tests which are expected to fail
+XFAIL_TESTS = \
+ $(TESTS_XFAIL_TESTS) \
+ $(MAGICKPP_XFAIL_TESTS) \
+ $(UTILITIES_XFAIL_TESTS)
+
+# Be sure to list CHANGELOGS in reverse chronological order in case we
+# should want to concatenate them.
+CHANGELOGS = \
+ ChangeLog \
+ ChangeLog.2015 \
+ ChangeLog.2014 \
+ ChangeLog.2013 \
+ ChangeLog.2012 \
+ ChangeLog.2011 \
+ ChangeLog.2010 \
+ ChangeLog.2009 \
+ ChangeLog.2008 \
+ ChangeLog.2007 \
+ ChangeLog.2006 \
+ ChangeLog.2005 \
+ ChangeLog.2004 \
+ ChangeLog.2003 \
+ ChangeLog.2002 \
+ ChangeLog.2001
+
+TOP_EXTRA_DIST = \
+ $(CHANGELOGS) \
+ Copyright.txt \
+ NEWS.txt \
+ README.txt \
+ TODO.txt \
+ lndir.sh \
+ version.sh \
+ winpath.sh
+
+
+# Additional files to distribute
+EXTRA_DIST = \
+ $(TOP_EXTRA_DIST) \
+ $(CONFIG_EXTRA_DIST) \
+ $(MAGICK_EXTRA_DIST) \
+ $(MAGICKPP_EXTRA_DIST) \
+ $(TESTS_EXTRA_DIST) \
+ $(UTILITIES_EXTRA_DIST) \
+ $(WAND_EXTRA_DIST) \
+ $(WWWW_EXTRA_DIST) \
+ $(WWWAPI_EXTRA_DIST) \
+ $(WWWWANDAPI_EXTRA_DIST)
+
+lib_LTLIBRARIES = $(LIBMAGICK) $(LIBMAGICKPP) $(LIBWAND)
+
+check_PROGRAMS = \
+ $(TESTS_CHECK_PGRMS) \
+ $(MAGICKPP_CHECK_PGRMS) \
+ $(WAND_CHECK_PGRMS)
+
+check_SCRIPTS = \
+ $(PERLMAGICK_CHECKSCRIPTS)
+
+AM_LDFLAGS =
+noinst_LTLIBRARIES =
+EXTRA_LTLIBRARIES =
+BUILT_SOURCES =
+MOSTLYCLEANFILES =
+
+include config/Makefile.am
+include coders/Makefile.am
+include magick/Makefile.am
+include filters/Makefile.am
+include Magick++/Makefile.am
+include tests/Makefile.am
+include wand/Makefile.am
+include www/Makefile.am
+include www/api/Makefile.am
+include www/wand/Makefile.am
+include utilities/Makefile.am
+include PerlMagick/Makefile.am
+
+# Pkgconfig directory
+pkgconfigdir = $(libdir)/pkgconfig
+
+# Files to install in Pkgconfig directory
+pkgconfig_DATA = \
+ $(MAGICK_PKGCONFIG) \
+ $(MAGICKPP_PKGCONFIG) \
+ $(WAND_PKGCONFIG)
+
+# Manual pages to install
+man_MANS = \
+ $(MAGICK_MANS) \
+ $(MAGICKPP_MANS) \
+ $(UTILITIES_MANS) \
+ $(WAND_MANS)
+
+# Files to install in the package's doc directory
+doc_DATA = \
+ Copyright.txt \
+ $(CHANGELOGS) \
+ NEWS.txt
+
+if MAINTAINER_MODE
+MAINTAINER_TARGETS = \
+ magick-version \
+ GraphicsMagick.spec \
+ $(PERLMAGICK_MAINTAINER_TARGETS) \
+ $(WWW_MAINTAINER_TARGETS) \
+ $(WWWAPI_MAINTAINER_TARGETS) \
+ $(WWWWANDAPI_MAINTAINER_TARGETS)
+
+# Target to build just the web pages.
+.PHONY: www
+www : $(WWW_MAINTAINER_TARGETS) $(WWWAPI_MAINTAINER_TARGETS) $(WWWWANDAPI_MAINTAINER_TARGETS)
+
+endif
+
+all-local: $(MAGICKPP_LOCAL_TARGETS) \
+ $(PERLMAGICK_ALL_LOCAL_TARGETS) $(MAINTAINER_TARGETS)
+
+install-exec-local: $(PERLMAGICK_INSTALL_EXEC_LOCAL_TARGETS) \
+ $(UTILITIES_INSTALL_EXEC_LOCAL_TARGETS)
+
+install-data-local: $(MAGICK_INSTALL_DATA_LOCAL_TARGETS) \
+ $(PERLMAGICK_INSTALL_DATA_LOCAL_TARGETS) \
+ $(HTML_INSTALL_DATA_TARGETS)
+
+uninstall-local: $(MAGICK_UNINSTALL_LOCAL_TARGETS) \
+ $(PERLMAGICK_UNINSTALL_LOCAL_TARGETS) \
+ $(HTML_UNINSTALL_DATA_TARGETS) \
+ $(UTILITIES_UNINSTALL_LOCAL_TARGETS)
+
+clean-local: $(PERLMAGICK_CLEAN_LOCAL_TARGETS)
+
+distclean-local: $(PERLMAGICK_DISTCLEAN_LOCAL_TARGETS)
+
+maintainer-clean-local: $(PERLMAGICK_MAINTAINER_CLEAN_LOCAL_TARGETS)
+
+check-local: $(PERLMAGICK_CHECK_LOCAL_TARGETS)
+
+# drd: valgrind's newer thread error detector
+drd:
+ $(MAKE) MEMCHECK='valgrind --tool=drd --check-stack-var=yes --var-info=yes \
+ --quiet $(VALGRIND_EXTRA_OPTS)' check
+
+# helgrind: valgrind's older thread error detector
+helgrind:
+ $(MAKE) MEMCHECK='valgrind --tool=helgrind --error-exitcode=2 --quiet \
+ $(VALGRIND_EXTRA_OPTS)' check
+
+# memcheck: valgrind's memory access checker.
+# The suppressions which come with valgrind are usually insufficient
+# to handle certain pthread library aspects and gomp and so errors
+# will be reported which are unrelated to GraphicsMagick. When first
+# starting with a new system (or after a major system update), it is
+# good to execute the test suite like 'make memcheck
+# VALGRIND_EXTRA_OPTS=--gen-suppressions=all' to create valgrind
+# suppression entries in the test log. Tell valgrind about the
+# suppressions by creating a .valgrindrc file with content like:
+# --memcheck:suppressions=mysupp.supp
+memcheck:
+ $(MAKE) MEMCHECK='valgrind --tool=memcheck --leak-check=full --read-var-info=yes \
+ --error-exitcode=2 --track-origins=yes --num-callers=12 \
+ --quiet $(VALGRIND_EXTRA_OPTS)' check
+
+# ptrcheck: valgrind's experimental pointer checking tool.
+ptrcheck:
+ $(MAKE) MEMCHECK='valgrind --tool=exp-ptrcheck --quiet $(VALGRIND_EXTRA_OPTS)' check
+
+# Non-Automake subdirectories to distribute
+DISTDIRS = locale scripts www PerlMagick TclMagick
+dist-hook:
+ ( \
+ builddir=`pwd` ; \
+ cd $(srcdir) && \
+ ( \
+ for dir in $(DISTDIRS) ; do \
+ find $$dir -depth -print | egrep -v '(~$$)|(/\.hg)|(/\.#)|(/\.deps)|(\.pyc)' \
+ | cpio -pdum $$builddir/$(distdir) 2> /dev/null ; \
+ done \
+ ) \
+ )
+
+#
+# Additional install rules
+#
+
+# Ensure that version.h at $(srcdir)/magick/version.h is kept up to date.
+magick-version: magick/version.h
+ @if test -f "$(srcdir)/VisualMagick/installer/inc/version.isx.in" ; then \
+ ./config.status --file="$(srcdir)/VisualMagick/installer/inc/version.isx" 2> /dev/null ; \
+ fi
+ @if test -n "$(VPATH)" ; then \
+ cmp magick/version.h $(srcdir)/magick/version.h > /dev/null ; \
+ if test $$? -eq 1 ; then \
+ echo "Updating $(srcdir)/magick/version.h ..."; \
+ cp magick/version.h $(srcdir)/magick/version.h ; \
+ fi ; \
+ fi ; \
+ touch magick-version
+
+magick/version.h: $(top_srcdir)/ChangeLog $(top_srcdir)/version.sh
+
+
+# Automatically reconfigure libtool
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+
+#
+# Build Windows source Zip and 7Zip balls
+#
+if HAS_ZIP
+DIST_WINDOWS_SRC_ZIP=$(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-windows.zip
+else
+DIST_WINDOWS_SRC_ZIP=
+endif
+if HAS_P7ZIP
+DIST_WINDOWS_SRC_7ZIP=$(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-windows.7z
+else
+DIST_WINDOWS_SRC_7ZIP=
+endif
+$(DIST_WINDOWS_SRC_7ZIP) windows-dist:
+ if test -d $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM) ; then \
+ chmod -R u+w $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM) ; \
+ rm -rf $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM) ; \
+ fi
+ hg --repository $(top_srcdir) archive --rev $(HG_BRANCH_TAG) $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)
+if HAS_P7ZIP
+ rm -f $(DIST_WINDOWS_SRC_7ZIP)
+ $(P7ZIP) a -t7z -mx=9 $(DIST_WINDOWS_SRC_7ZIP) $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)
+ chmod 644 $(DIST_WINDOWS_SRC_7ZIP)
+endif # HAS_P7ZIP
+ rm -rf $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)
+
+#
+# RPM build support
+#
+if HAS_RPM
+
+DIST_ARCHIVE_SRPM=$(distdir)-1.src.rpm
+.PHONY: srpm
+$(DIST_ARCHIVE_SRPM) srpm: $(distdir).tar.bz2
+ rm -f $(DIST_ARCHIVE_SRPM)
+ $(RPM) --define="_sourcedir `pwd`" --define="_srcrpmdir `pwd`" --nodeps -bs GraphicsMagick.spec
+ @echo ==============================================================
+ @echo $(DIST_ARCHIVE_SRPM) is ready for distribution.
+ @echo ==============================================================
+
+RPMDIR=rpmbuild
+RPMARCH=$(MAGICK_TARGET_CPU)
+
+DIST_ARCHIVE_RPM= \
+ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm \
+ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-c++-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm \
+ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-c++-devel-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm \
+ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-devel-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm \
+ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-perl-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm
+
+.PHONY: rpm
+rpm:
+ rm -rf $(RPMDIR)
+ $(MKDIR_P) $(RPMDIR)
+ $(MKDIR_P) $(RPMDIR)/BUILD
+ $(MKDIR_P) $(RPMDIR)/RPMS
+ $(RPM) --define="_sourcedir `pwd`" --define="_rpmdir `pwd`/$(RPMDIR)/RPMS" \
+ --define="_builddir `pwd`/$(RPMDIR)/BUILD" --define='quant $(QuantumDepth)' \
+ --nodeps -bb GraphicsMagick.spec
+ rm -rf rpmbuild
+ @echo ==============================================================
+ @echo $(DIST_ARCHIVE_RPM) is ready for distribution.
+ @echo ==============================================================
+
+else
+DIST_ARCHIVE_RPM=
+endif # HAS_RPM
+
+#
+# Build a validated snapshot release and move to the snapshots directory.
+#
+SNAPSHOT_DIRECTORY=/ftp/pub/GraphicsMagick/snapshots
+snapshot: distcheck
+ $(MAKE) $(DIST_ARCHIVE_SRPM)
+ $(MAKE) $(DIST_WINDOWS_SRC_7ZIP)
+ mv $(DIST_ARCHIVES) $(DIST_WINDOWS_SRC_7ZIP) $(DIST_ARCHIVE_SRPM) $(SNAPSHOT_DIRECTORY)/
+ cp $(top_srcdir)/ChangeLog $(SNAPSHOT_DIRECTORY)/ChangeLog.txt
+ cp $(top_srcdir)/www/Changelog.html $(SNAPSHOT_DIRECTORY)/ChangeLog.html
+
+COVERITY_EMAIL=bfriesen@simple.dallas.tx.us
+COVERITY_TARBALL=GraphicsMagick.xz
+COVERITY_VERSION=snapshot-@PACKAGE_CHANGE_DATE@
+COVERITY_DESCRIPTION='Ubuntu Q@QuantumDepth@'
+coverity:
+ $(MAKE) clean
+ cov-build --dir cov-int $(MAKE)
+ tar caf $(COVERITY_TARBALL) cov-int
+ curl --limit-rate 50K \
+ --form token=`cat $$HOME/.coverity_key_gm` \
+ --form email=$(COVERITY_EMAIL) \
+ --form file=@$(COVERITY_TARBALL) \
+ --form version=$(COVERITY_VERSION) \
+ --form description=$(COVERITY_DESCRIPTION) \
+ https://scan.coverity.com/builds?project=GraphicsMagick
+ $(RM) $(COVERITY_TARBALL)
+
+# Rules for a profiled build (according to Paolo Bonzini <bonzini@gnu.org>)
+#.PHONY: profile
+#profile:
+# $(MAKE) clean
+# $(MAKE) CFLAGS="$(CFLAGS) -fprofile-generate"
+# $(MAKE) check
+# $(MAKE) mostlyclean
+# $(MAKE) CFLAGS="$(CFLAGS) -fprofile-use"
+#
+#CLEANFILES = *.gcda *.gcno
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..ace40a6
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,10187 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2004-2014 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Top-Level Makefile for building GraphicsMagick
+#
+#
+
+# Copyright (C) 2004 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for Magick library configuration files
+#
+#
+
+# Copyright (C) 2004-2016 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building GraphicsMagick coder modules
+#
+#
+
+# Copyright (C) 2004-2014 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building GraphicsMagick library
+#
+#
+
+# Copyright (C) 2004-2014 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building GraphicsMagick filter modules
+#
+#
+
+#
+# Top Makefile for Magick++
+#
+# Copyright (C) 1999-2014 Bob Friesenhahn
+#
+
+#AM_CPPFLAGS += -I$(top_srcdir)/Magick++/lib
+
+# Copyright (C) 2004-2012 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for GraphicsMagick tests invoked via the C API
+#
+
+# Copyright (C) 2004 - 2014 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building Wand library
+#
+
+# Copyright (C) 2008 - 2017 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building HTML files
+#
+
+# Copyright (C) 2008-2011 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building API HTML files
+#
+
+# Copyright (C) 2009 - 2012 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building Wand API HTML files
+#
+
+# Copyright (C) 2004-2012 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building GraphicsMagick utilities
+#
+#
+
+# Copyright (C) 2004-2010 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building PerlMagick
+#
+#
+
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = $(am__EXEEXT_1)
+TESTS = $(PERLMAGICK_TESTS) $(TESTS_TESTS) $(am__EXEEXT_6) \
+ $(WAND_TESTS) $(UTILITIES_TESTS)
+XFAIL_TESTS = $(am__EXEEXT_7) $(am__EXEEXT_7) $(am__EXEEXT_7)
+check_PROGRAMS = $(am__EXEEXT_2) $(am__EXEEXT_4) $(am__EXEEXT_5)
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(include_HEADERS) $(magickinc_HEADERS) \
+ $(am__magickppinc_HEADERS_DIST) \
+ $(am__magickpptopinc_HEADERS_DIST) $(noinst_HEADERS) \
+ $(wandinc_HEADERS) $(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/magick/magick_config.h \
+ $(top_builddir)/magick/magick_config_api.h
+CONFIG_CLEAN_FILES = GraphicsMagick.spec \
+ Magick++/bin/GraphicsMagick++-config \
+ Magick++/lib/GraphicsMagick++.pc PerlMagick/Magick.pm \
+ PerlMagick/Makefile.PL PerlMagick/PerlMagickCheck.sh \
+ PerlMagick/t/features.pl config/delegates.mgk \
+ config/type-ghostscript.mgk config/type-solaris.mgk \
+ config/type-windows.mgk config/type.mgk \
+ magick/GraphicsMagick-config magick/GraphicsMagick.pc \
+ magick/magick_types.h magick/version.h common.shi rungm.sh \
+ wand/GraphicsMagickWand-config wand/GraphicsMagickWand.pc
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(codersdir)" "$(DESTDIR)$(filtersdir)" \
+ "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
+ "$(DESTDIR)$(man4dir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(configlibdir)" "$(DESTDIR)$(configsharedir)" \
+ "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" \
+ "$(DESTDIR)$(includedir)" "$(DESTDIR)$(magickincdir)" \
+ "$(DESTDIR)$(magickppincdir)" "$(DESTDIR)$(magickpptopincdir)" \
+ "$(DESTDIR)$(wandincdir)"
+LTLIBRARIES = $(coders_LTLIBRARIES) $(filters_LTLIBRARIES) \
+ $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+Magick___lib_libGraphicsMagick___la_DEPENDENCIES = $(LIBMAGICK)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_Magick___lib_libGraphicsMagick___la_OBJECTS = \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Blob.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-BlobRef.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-CoderInfo.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Color.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Drawable.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Exception.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Functions.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Geometry.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Image.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-ImageRef.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Montage.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Options.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Pixels.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-STL.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-Thread.lo \
+ Magick++/lib/Magick___lib_libGraphicsMagick___la-TypeMetric.lo
+Magick___lib_libGraphicsMagick___la_OBJECTS = \
+ $(am_Magick___lib_libGraphicsMagick___la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+Magick___lib_libGraphicsMagick___la_LINK = $(LIBTOOL) $(AM_V_lt) \
+ --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+ $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
+ $(Magick___lib_libGraphicsMagick___la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MAGICK_PLUS_PLUS_TRUE@am_Magick___lib_libGraphicsMagick___la_rpath = \
+@WITH_MAGICK_PLUS_PLUS_TRUE@ -rpath $(libdir)
+coders_art_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_art_la_OBJECTS = coders/coders_art_la-art.lo
+coders_art_la_OBJECTS = $(am_coders_art_la_OBJECTS)
+coders_art_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_art_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_art_la_rpath = -rpath $(codersdir)
+coders_avs_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_avs_la_OBJECTS = coders/coders_avs_la-avs.lo
+coders_avs_la_OBJECTS = $(am_coders_avs_la_OBJECTS)
+coders_avs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_avs_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_avs_la_rpath = -rpath $(codersdir)
+coders_bmp_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_bmp_la_OBJECTS = coders/coders_bmp_la-bmp.lo
+coders_bmp_la_OBJECTS = $(am_coders_bmp_la_OBJECTS)
+coders_bmp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_bmp_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_bmp_la_rpath = -rpath $(codersdir)
+coders_cals_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_cals_la_OBJECTS = coders/coders_cals_la-cals.lo
+coders_cals_la_OBJECTS = $(am_coders_cals_la_OBJECTS)
+coders_cals_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_cals_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_cals_la_rpath = -rpath $(codersdir)
+coders_caption_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_caption_la_OBJECTS = coders/coders_caption_la-caption.lo
+coders_caption_la_OBJECTS = $(am_coders_caption_la_OBJECTS)
+coders_caption_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_caption_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_caption_la_rpath = -rpath $(codersdir)
+coders_cineon_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_cineon_la_OBJECTS = coders/coders_cineon_la-cineon.lo
+coders_cineon_la_OBJECTS = $(am_coders_cineon_la_OBJECTS)
+coders_cineon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_cineon_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_cineon_la_rpath = -rpath $(codersdir)
+am__DEPENDENCIES_1 =
+coders_clipboard_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_clipboard_la_OBJECTS = \
+ coders/coders_clipboard_la-clipboard.lo
+coders_clipboard_la_OBJECTS = $(am_coders_clipboard_la_OBJECTS)
+coders_clipboard_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_clipboard_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@HasWINGDI32_TRUE@@WITH_MODULES_TRUE@am_coders_clipboard_la_rpath = \
+@HasWINGDI32_TRUE@@WITH_MODULES_TRUE@ -rpath $(codersdir)
+coders_cmyk_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_cmyk_la_OBJECTS = coders/coders_cmyk_la-cmyk.lo
+coders_cmyk_la_OBJECTS = $(am_coders_cmyk_la_OBJECTS)
+coders_cmyk_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_cmyk_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_cmyk_la_rpath = -rpath $(codersdir)
+coders_cut_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_cut_la_OBJECTS = coders/coders_cut_la-cut.lo
+coders_cut_la_OBJECTS = $(am_coders_cut_la_OBJECTS)
+coders_cut_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_cut_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_cut_la_rpath = -rpath $(codersdir)
+coders_dcm_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_dcm_la_OBJECTS = coders/coders_dcm_la-dcm.lo
+coders_dcm_la_OBJECTS = $(am_coders_dcm_la_OBJECTS)
+coders_dcm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_dcm_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_dcm_la_rpath = -rpath $(codersdir)
+coders_dcraw_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_dcraw_la_OBJECTS = coders/coders_dcraw_la-dcraw.lo
+coders_dcraw_la_OBJECTS = $(am_coders_dcraw_la_OBJECTS)
+coders_dcraw_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_dcraw_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_dcraw_la_rpath = -rpath $(codersdir)
+coders_dib_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_dib_la_OBJECTS = coders/coders_dib_la-dib.lo
+coders_dib_la_OBJECTS = $(am_coders_dib_la_OBJECTS)
+coders_dib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_dib_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_dib_la_rpath = -rpath $(codersdir)
+coders_dps_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_coders_dps_la_OBJECTS = coders/coders_dps_la-dps.lo
+coders_dps_la_OBJECTS = $(am_coders_dps_la_OBJECTS)
+coders_dps_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_dps_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasDPS_TRUE@@WITH_MODULES_TRUE@am_coders_dps_la_rpath = -rpath \
+@HasDPS_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_dpx_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_dpx_la_OBJECTS = coders/coders_dpx_la-dpx.lo
+coders_dpx_la_OBJECTS = $(am_coders_dpx_la_OBJECTS)
+coders_dpx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_dpx_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_dpx_la_rpath = -rpath $(codersdir)
+coders_emf_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_emf_la_OBJECTS = coders/coders_emf_la-emf.lo
+coders_emf_la_OBJECTS = $(am_coders_emf_la_OBJECTS)
+coders_emf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_emf_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasWINGDI32_TRUE@@WITH_MODULES_TRUE@am_coders_emf_la_rpath = -rpath \
+@HasWINGDI32_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_ept_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_ept_la_OBJECTS = coders/ept.lo
+coders_ept_la_OBJECTS = $(am_coders_ept_la_OBJECTS)
+coders_ept_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_ept_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasTIFF_TRUE@@WITH_MODULES_TRUE@am_coders_ept_la_rpath = -rpath \
+@HasTIFF_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_fax_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_fax_la_OBJECTS = coders/coders_fax_la-fax.lo
+coders_fax_la_OBJECTS = $(am_coders_fax_la_OBJECTS)
+coders_fax_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_fax_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_fax_la_rpath = -rpath $(codersdir)
+coders_fits_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_fits_la_OBJECTS = coders/coders_fits_la-fits.lo
+coders_fits_la_OBJECTS = $(am_coders_fits_la_OBJECTS)
+coders_fits_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_fits_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_fits_la_rpath = -rpath $(codersdir)
+coders_fpx_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_fpx_la_OBJECTS = coders/coders_fpx_la-fpx.lo
+coders_fpx_la_OBJECTS = $(am_coders_fpx_la_OBJECTS)
+coders_fpx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_fpx_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasFPX_TRUE@@WITH_MODULES_TRUE@am_coders_fpx_la_rpath = -rpath \
+@HasFPX_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_gif_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_gif_la_OBJECTS = coders/coders_gif_la-gif.lo
+coders_gif_la_OBJECTS = $(am_coders_gif_la_OBJECTS)
+coders_gif_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_gif_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_gif_la_rpath = -rpath $(codersdir)
+coders_gradient_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_gradient_la_OBJECTS = coders/coders_gradient_la-gradient.lo
+coders_gradient_la_OBJECTS = $(am_coders_gradient_la_OBJECTS)
+coders_gradient_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_gradient_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_gradient_la_rpath = -rpath $(codersdir)
+coders_gray_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_gray_la_OBJECTS = coders/coders_gray_la-gray.lo
+coders_gray_la_OBJECTS = $(am_coders_gray_la_OBJECTS)
+coders_gray_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_gray_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_gray_la_rpath = -rpath $(codersdir)
+coders_histogram_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_histogram_la_OBJECTS = \
+ coders/coders_histogram_la-histogram.lo
+coders_histogram_la_OBJECTS = $(am_coders_histogram_la_OBJECTS)
+coders_histogram_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_histogram_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_histogram_la_rpath = -rpath $(codersdir)
+coders_hrz_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_hrz_la_OBJECTS = coders/coders_hrz_la-hrz.lo
+coders_hrz_la_OBJECTS = $(am_coders_hrz_la_OBJECTS)
+coders_hrz_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_hrz_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_hrz_la_rpath = -rpath $(codersdir)
+coders_html_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_html_la_OBJECTS = coders/coders_html_la-html.lo
+coders_html_la_OBJECTS = $(am_coders_html_la_OBJECTS)
+coders_html_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_html_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_html_la_rpath = -rpath $(codersdir)
+coders_icon_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_icon_la_OBJECTS = coders/coders_icon_la-icon.lo
+coders_icon_la_OBJECTS = $(am_coders_icon_la_OBJECTS)
+coders_icon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_icon_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_icon_la_rpath = -rpath $(codersdir)
+coders_identity_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_identity_la_OBJECTS = coders/coders_identity_la-identity.lo
+coders_identity_la_OBJECTS = $(am_coders_identity_la_OBJECTS)
+coders_identity_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_identity_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_identity_la_rpath = -rpath $(codersdir)
+coders_info_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_info_la_OBJECTS = coders/coders_info_la-info.lo
+coders_info_la_OBJECTS = $(am_coders_info_la_OBJECTS)
+coders_info_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_info_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_info_la_rpath = -rpath $(codersdir)
+coders_jbig_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_jbig_la_OBJECTS = coders/coders_jbig_la-jbig.lo
+coders_jbig_la_OBJECTS = $(am_coders_jbig_la_OBJECTS)
+coders_jbig_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_jbig_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@HasJBIG_TRUE@@WITH_MODULES_TRUE@am_coders_jbig_la_rpath = -rpath \
+@HasJBIG_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_jnx_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_jnx_la_OBJECTS = coders/coders_jnx_la-jnx.lo
+coders_jnx_la_OBJECTS = $(am_coders_jnx_la_OBJECTS)
+coders_jnx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_jnx_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasJPEG_TRUE@@WITH_MODULES_TRUE@am_coders_jnx_la_rpath = -rpath \
+@HasJPEG_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_jp2_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_coders_jp2_la_OBJECTS = coders/coders_jp2_la-jp2.lo
+coders_jp2_la_OBJECTS = $(am_coders_jp2_la_OBJECTS)
+coders_jp2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_jp2_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasJP2_TRUE@@WITH_MODULES_TRUE@am_coders_jp2_la_rpath = -rpath \
+@HasJP2_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_jpeg_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_jpeg_la_OBJECTS = coders/coders_jpeg_la-jpeg.lo
+coders_jpeg_la_OBJECTS = $(am_coders_jpeg_la_OBJECTS)
+coders_jpeg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_jpeg_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@HasJPEG_TRUE@@WITH_MODULES_TRUE@am_coders_jpeg_la_rpath = -rpath \
+@HasJPEG_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_label_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_label_la_OBJECTS = coders/coders_label_la-label.lo
+coders_label_la_OBJECTS = $(am_coders_label_la_OBJECTS)
+coders_label_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_label_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_label_la_rpath = -rpath $(codersdir)
+coders_locale_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_locale_la_OBJECTS = coders/coders_locale_la-locale.lo
+coders_locale_la_OBJECTS = $(am_coders_locale_la_OBJECTS)
+coders_locale_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_locale_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_locale_la_rpath = -rpath $(codersdir)
+coders_logo_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_logo_la_OBJECTS = coders/coders_logo_la-logo.lo
+coders_logo_la_OBJECTS = $(am_coders_logo_la_OBJECTS)
+coders_logo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_logo_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_logo_la_rpath = -rpath $(codersdir)
+coders_mac_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_mac_la_OBJECTS = coders/coders_mac_la-mac.lo
+coders_mac_la_OBJECTS = $(am_coders_mac_la_OBJECTS)
+coders_mac_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_mac_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_mac_la_rpath = -rpath $(codersdir)
+coders_map_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_map_la_OBJECTS = coders/coders_map_la-map.lo
+coders_map_la_OBJECTS = $(am_coders_map_la_OBJECTS)
+coders_map_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_map_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_map_la_rpath = -rpath $(codersdir)
+coders_mat_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_mat_la_OBJECTS = coders/coders_mat_la-mat.lo
+coders_mat_la_OBJECTS = $(am_coders_mat_la_OBJECTS)
+coders_mat_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_mat_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_mat_la_rpath = -rpath $(codersdir)
+coders_matte_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_matte_la_OBJECTS = coders/coders_matte_la-matte.lo
+coders_matte_la_OBJECTS = $(am_coders_matte_la_OBJECTS)
+coders_matte_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_matte_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_matte_la_rpath = -rpath $(codersdir)
+coders_meta_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_meta_la_OBJECTS = coders/coders_meta_la-meta.lo
+coders_meta_la_OBJECTS = $(am_coders_meta_la_OBJECTS)
+coders_meta_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_meta_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_meta_la_rpath = -rpath $(codersdir)
+coders_miff_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_miff_la_OBJECTS = coders/coders_miff_la-miff.lo
+coders_miff_la_OBJECTS = $(am_coders_miff_la_OBJECTS)
+coders_miff_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_miff_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_miff_la_rpath = -rpath $(codersdir)
+coders_mono_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_mono_la_OBJECTS = coders/coders_mono_la-mono.lo
+coders_mono_la_OBJECTS = $(am_coders_mono_la_OBJECTS)
+coders_mono_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_mono_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_mono_la_rpath = -rpath $(codersdir)
+coders_mpc_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_mpc_la_OBJECTS = coders/coders_mpc_la-mpc.lo
+coders_mpc_la_OBJECTS = $(am_coders_mpc_la_OBJECTS)
+coders_mpc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_mpc_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_mpc_la_rpath = -rpath $(codersdir)
+coders_mpeg_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_mpeg_la_OBJECTS = coders/coders_mpeg_la-mpeg.lo
+coders_mpeg_la_OBJECTS = $(am_coders_mpeg_la_OBJECTS)
+coders_mpeg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_mpeg_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_mpeg_la_rpath = -rpath $(codersdir)
+coders_mpr_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_mpr_la_OBJECTS = coders/coders_mpr_la-mpr.lo
+coders_mpr_la_OBJECTS = $(am_coders_mpr_la_OBJECTS)
+coders_mpr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_mpr_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_mpr_la_rpath = -rpath $(codersdir)
+coders_msl_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_msl_la_OBJECTS = coders/coders_msl_la-msl.lo
+coders_msl_la_OBJECTS = $(am_coders_msl_la_OBJECTS)
+coders_msl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_msl_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_msl_la_rpath = -rpath $(codersdir)
+coders_mtv_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_mtv_la_OBJECTS = coders/coders_mtv_la-mtv.lo
+coders_mtv_la_OBJECTS = $(am_coders_mtv_la_OBJECTS)
+coders_mtv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_mtv_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_mtv_la_rpath = -rpath $(codersdir)
+coders_mvg_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_mvg_la_OBJECTS = coders/coders_mvg_la-mvg.lo
+coders_mvg_la_OBJECTS = $(am_coders_mvg_la_OBJECTS)
+coders_mvg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_mvg_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_mvg_la_rpath = -rpath $(codersdir)
+coders_null_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_null_la_OBJECTS = coders/coders_null_la-null.lo
+coders_null_la_OBJECTS = $(am_coders_null_la_OBJECTS)
+coders_null_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_null_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_null_la_rpath = -rpath $(codersdir)
+coders_otb_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_otb_la_OBJECTS = coders/coders_otb_la-otb.lo
+coders_otb_la_OBJECTS = $(am_coders_otb_la_OBJECTS)
+coders_otb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_otb_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_otb_la_rpath = -rpath $(codersdir)
+coders_palm_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_palm_la_OBJECTS = coders/coders_palm_la-palm.lo
+coders_palm_la_OBJECTS = $(am_coders_palm_la_OBJECTS)
+coders_palm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_palm_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_palm_la_rpath = -rpath $(codersdir)
+coders_pcd_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_pcd_la_OBJECTS = coders/coders_pcd_la-pcd.lo
+coders_pcd_la_OBJECTS = $(am_coders_pcd_la_OBJECTS)
+coders_pcd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_pcd_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_pcd_la_rpath = -rpath $(codersdir)
+coders_pcl_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_pcl_la_OBJECTS = coders/coders_pcl_la-pcl.lo
+coders_pcl_la_OBJECTS = $(am_coders_pcl_la_OBJECTS)
+coders_pcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_pcl_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_pcl_la_rpath = -rpath $(codersdir)
+coders_pcx_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_pcx_la_OBJECTS = coders/coders_pcx_la-pcx.lo
+coders_pcx_la_OBJECTS = $(am_coders_pcx_la_OBJECTS)
+coders_pcx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_pcx_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_pcx_la_rpath = -rpath $(codersdir)
+coders_pdb_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_pdb_la_OBJECTS = coders/coders_pdb_la-pdb.lo
+coders_pdb_la_OBJECTS = $(am_coders_pdb_la_OBJECTS)
+coders_pdb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_pdb_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_pdb_la_rpath = -rpath $(codersdir)
+coders_pdf_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_pdf_la_OBJECTS = coders/coders_pdf_la-pdf.lo
+coders_pdf_la_OBJECTS = $(am_coders_pdf_la_OBJECTS)
+coders_pdf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_pdf_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_pdf_la_rpath = -rpath $(codersdir)
+coders_pict_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_pict_la_OBJECTS = coders/coders_pict_la-pict.lo
+coders_pict_la_OBJECTS = $(am_coders_pict_la_OBJECTS)
+coders_pict_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_pict_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_pict_la_rpath = -rpath $(codersdir)
+coders_pix_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_pix_la_OBJECTS = coders/coders_pix_la-pix.lo
+coders_pix_la_OBJECTS = $(am_coders_pix_la_OBJECTS)
+coders_pix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_pix_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_pix_la_rpath = -rpath $(codersdir)
+coders_plasma_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_plasma_la_OBJECTS = coders/coders_plasma_la-plasma.lo
+coders_plasma_la_OBJECTS = $(am_coders_plasma_la_OBJECTS)
+coders_plasma_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_plasma_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_plasma_la_rpath = -rpath $(codersdir)
+coders_png_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_png_la_OBJECTS = coders/coders_png_la-png.lo
+coders_png_la_OBJECTS = $(am_coders_png_la_OBJECTS)
+coders_png_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_png_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasPNG_TRUE@@WITH_MODULES_TRUE@am_coders_png_la_rpath = -rpath \
+@HasPNG_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_pnm_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_pnm_la_OBJECTS = coders/coders_pnm_la-pnm.lo
+coders_pnm_la_OBJECTS = $(am_coders_pnm_la_OBJECTS)
+coders_pnm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_pnm_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_pnm_la_rpath = -rpath $(codersdir)
+coders_preview_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_preview_la_OBJECTS = coders/coders_preview_la-preview.lo
+coders_preview_la_OBJECTS = $(am_coders_preview_la_OBJECTS)
+coders_preview_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_preview_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_preview_la_rpath = -rpath $(codersdir)
+coders_ps_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_ps_la_OBJECTS = coders/coders_ps_la-ps.lo
+coders_ps_la_OBJECTS = $(am_coders_ps_la_OBJECTS)
+coders_ps_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_ps_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_ps_la_rpath = -rpath $(codersdir)
+coders_ps2_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_ps2_la_OBJECTS = coders/coders_ps2_la-ps2.lo
+coders_ps2_la_OBJECTS = $(am_coders_ps2_la_OBJECTS)
+coders_ps2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_ps2_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_ps2_la_rpath = -rpath $(codersdir)
+coders_ps3_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_ps3_la_OBJECTS = coders/coders_ps3_la-ps3.lo
+coders_ps3_la_OBJECTS = $(am_coders_ps3_la_OBJECTS)
+coders_ps3_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_ps3_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_ps3_la_rpath = -rpath $(codersdir)
+coders_psd_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_psd_la_OBJECTS = coders/coders_psd_la-psd.lo
+coders_psd_la_OBJECTS = $(am_coders_psd_la_OBJECTS)
+coders_psd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_psd_la_LDFLAGS) $(LDFLAGS) -o $@
+@ENABLE_BROKEN_CODERS_TRUE@@WITH_MODULES_TRUE@am_coders_psd_la_rpath = \
+@ENABLE_BROKEN_CODERS_TRUE@@WITH_MODULES_TRUE@ -rpath \
+@ENABLE_BROKEN_CODERS_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_pwp_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_pwp_la_OBJECTS = coders/coders_pwp_la-pwp.lo
+coders_pwp_la_OBJECTS = $(am_coders_pwp_la_OBJECTS)
+coders_pwp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_pwp_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_pwp_la_rpath = -rpath $(codersdir)
+coders_rgb_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_rgb_la_OBJECTS = coders/coders_rgb_la-rgb.lo
+coders_rgb_la_OBJECTS = $(am_coders_rgb_la_OBJECTS)
+coders_rgb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_rgb_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_rgb_la_rpath = -rpath $(codersdir)
+coders_rla_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_rla_la_OBJECTS = coders/coders_rla_la-rla.lo
+coders_rla_la_OBJECTS = $(am_coders_rla_la_OBJECTS)
+coders_rla_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_rla_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_rla_la_rpath = -rpath $(codersdir)
+coders_rle_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_rle_la_OBJECTS = coders/coders_rle_la-rle.lo
+coders_rle_la_OBJECTS = $(am_coders_rle_la_OBJECTS)
+coders_rle_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_rle_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_rle_la_rpath = -rpath $(codersdir)
+coders_sct_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_sct_la_OBJECTS = coders/coders_sct_la-sct.lo
+coders_sct_la_OBJECTS = $(am_coders_sct_la_OBJECTS)
+coders_sct_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_sct_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_sct_la_rpath = -rpath $(codersdir)
+coders_sfw_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_sfw_la_OBJECTS = coders/coders_sfw_la-sfw.lo
+coders_sfw_la_OBJECTS = $(am_coders_sfw_la_OBJECTS)
+coders_sfw_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_sfw_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_sfw_la_rpath = -rpath $(codersdir)
+coders_sgi_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_sgi_la_OBJECTS = coders/coders_sgi_la-sgi.lo
+coders_sgi_la_OBJECTS = $(am_coders_sgi_la_OBJECTS)
+coders_sgi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_sgi_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_sgi_la_rpath = -rpath $(codersdir)
+coders_stegano_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_stegano_la_OBJECTS = coders/coders_stegano_la-stegano.lo
+coders_stegano_la_OBJECTS = $(am_coders_stegano_la_OBJECTS)
+coders_stegano_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_stegano_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_stegano_la_rpath = -rpath $(codersdir)
+coders_sun_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_sun_la_OBJECTS = coders/coders_sun_la-sun.lo
+coders_sun_la_OBJECTS = $(am_coders_sun_la_OBJECTS)
+coders_sun_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_sun_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_sun_la_rpath = -rpath $(codersdir)
+coders_svg_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_svg_la_OBJECTS = coders/coders_svg_la-svg.lo
+coders_svg_la_OBJECTS = $(am_coders_svg_la_OBJECTS)
+coders_svg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_svg_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_svg_la_rpath = -rpath $(codersdir)
+coders_tga_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_tga_la_OBJECTS = coders/coders_tga_la-tga.lo
+coders_tga_la_OBJECTS = $(am_coders_tga_la_OBJECTS)
+coders_tga_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_tga_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_tga_la_rpath = -rpath $(codersdir)
+coders_tiff_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_tiff_la_OBJECTS = coders/coders_tiff_la-tiff.lo
+coders_tiff_la_OBJECTS = $(am_coders_tiff_la_OBJECTS)
+coders_tiff_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_tiff_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@HasTIFF_TRUE@@WITH_MODULES_TRUE@am_coders_tiff_la_rpath = -rpath \
+@HasTIFF_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_tile_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_tile_la_OBJECTS = coders/coders_tile_la-tile.lo
+coders_tile_la_OBJECTS = $(am_coders_tile_la_OBJECTS)
+coders_tile_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_tile_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_tile_la_rpath = -rpath $(codersdir)
+coders_tim_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_tim_la_OBJECTS = coders/coders_tim_la-tim.lo
+coders_tim_la_OBJECTS = $(am_coders_tim_la_OBJECTS)
+coders_tim_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_tim_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_tim_la_rpath = -rpath $(codersdir)
+coders_topol_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_topol_la_OBJECTS = coders/coders_topol_la-topol.lo
+coders_topol_la_OBJECTS = $(am_coders_topol_la_OBJECTS)
+coders_topol_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_topol_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_topol_la_rpath = -rpath $(codersdir)
+coders_ttf_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_ttf_la_OBJECTS = coders/coders_ttf_la-ttf.lo
+coders_ttf_la_OBJECTS = $(am_coders_ttf_la_OBJECTS)
+coders_ttf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_ttf_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_ttf_la_rpath = -rpath $(codersdir)
+coders_txt_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_txt_la_OBJECTS = coders/coders_txt_la-txt.lo
+coders_txt_la_OBJECTS = $(am_coders_txt_la_OBJECTS)
+coders_txt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_txt_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_txt_la_rpath = -rpath $(codersdir)
+coders_uil_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_uil_la_OBJECTS = coders/coders_uil_la-uil.lo
+coders_uil_la_OBJECTS = $(am_coders_uil_la_OBJECTS)
+coders_uil_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_uil_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_uil_la_rpath = -rpath $(codersdir)
+coders_url_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_coders_url_la_OBJECTS = coders/coders_url_la-url.lo
+coders_url_la_OBJECTS = $(am_coders_url_la_OBJECTS)
+coders_url_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_url_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_url_la_rpath = -rpath $(codersdir)
+coders_uyvy_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_uyvy_la_OBJECTS = coders/coders_uyvy_la-uyvy.lo
+coders_uyvy_la_OBJECTS = $(am_coders_uyvy_la_OBJECTS)
+coders_uyvy_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_uyvy_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_uyvy_la_rpath = -rpath $(codersdir)
+coders_vicar_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_vicar_la_OBJECTS = coders/coders_vicar_la-vicar.lo
+coders_vicar_la_OBJECTS = $(am_coders_vicar_la_OBJECTS)
+coders_vicar_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_vicar_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+@WITH_MODULES_TRUE@am_coders_vicar_la_rpath = -rpath $(codersdir)
+coders_vid_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_vid_la_OBJECTS = coders/coders_vid_la-vid.lo
+coders_vid_la_OBJECTS = $(am_coders_vid_la_OBJECTS)
+coders_vid_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_vid_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_vid_la_rpath = -rpath $(codersdir)
+coders_viff_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_viff_la_OBJECTS = coders/coders_viff_la-viff.lo
+coders_viff_la_OBJECTS = $(am_coders_viff_la_OBJECTS)
+coders_viff_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_viff_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_viff_la_rpath = -rpath $(codersdir)
+coders_wbmp_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_wbmp_la_OBJECTS = coders/coders_wbmp_la-wbmp.lo
+coders_wbmp_la_OBJECTS = $(am_coders_wbmp_la_OBJECTS)
+coders_wbmp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_wbmp_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@WITH_MODULES_TRUE@am_coders_wbmp_la_rpath = -rpath $(codersdir)
+coders_webp_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_webp_la_OBJECTS = coders/coders_webp_la-webp.lo
+coders_webp_la_OBJECTS = $(am_coders_webp_la_OBJECTS)
+coders_webp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(coders_webp_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+@HasWEBP_TRUE@@WITH_MODULES_TRUE@am_coders_webp_la_rpath = -rpath \
+@HasWEBP_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_wmf_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_coders_wmf_la_OBJECTS = coders/coders_wmf_la-wmf.lo
+coders_wmf_la_OBJECTS = $(am_coders_wmf_la_OBJECTS)
+coders_wmf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_wmf_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_wmf_la_rpath = -rpath $(codersdir)
+coders_wpg_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_wpg_la_OBJECTS = coders/coders_wpg_la-wpg.lo
+coders_wpg_la_OBJECTS = $(am_coders_wpg_la_OBJECTS)
+coders_wpg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_wpg_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_wpg_la_rpath = -rpath $(codersdir)
+coders_x_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_x_la_OBJECTS = coders/coders_x_la-x.lo
+coders_x_la_OBJECTS = $(am_coders_x_la_OBJECTS)
+coders_x_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_x_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasX11_TRUE@@WITH_MODULES_TRUE@am_coders_x_la_rpath = -rpath \
+@HasX11_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_xbm_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_xbm_la_OBJECTS = coders/coders_xbm_la-xbm.lo
+coders_xbm_la_OBJECTS = $(am_coders_xbm_la_OBJECTS)
+coders_xbm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_xbm_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_xbm_la_rpath = -rpath $(codersdir)
+coders_xc_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_xc_la_OBJECTS = coders/coders_xc_la-xc.lo
+coders_xc_la_OBJECTS = $(am_coders_xc_la_OBJECTS)
+coders_xc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_xc_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_xc_la_rpath = -rpath $(codersdir)
+coders_xcf_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_xcf_la_OBJECTS = coders/coders_xcf_la-xcf.lo
+coders_xcf_la_OBJECTS = $(am_coders_xcf_la_OBJECTS)
+coders_xcf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_xcf_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_xcf_la_rpath = -rpath $(codersdir)
+coders_xpm_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_xpm_la_OBJECTS = coders/coders_xpm_la-xpm.lo
+coders_xpm_la_OBJECTS = $(am_coders_xpm_la_OBJECTS)
+coders_xpm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_xpm_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_xpm_la_rpath = -rpath $(codersdir)
+coders_xwd_la_DEPENDENCIES = $(LIBMAGICK) $(am__DEPENDENCIES_1)
+am_coders_xwd_la_OBJECTS = coders/coders_xwd_la-xwd.lo
+coders_xwd_la_OBJECTS = $(am_coders_xwd_la_OBJECTS)
+coders_xwd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_xwd_la_LDFLAGS) $(LDFLAGS) -o $@
+@HasX11_TRUE@@WITH_MODULES_TRUE@am_coders_xwd_la_rpath = -rpath \
+@HasX11_TRUE@@WITH_MODULES_TRUE@ $(codersdir)
+coders_yuv_la_DEPENDENCIES = $(LIBMAGICK)
+am_coders_yuv_la_OBJECTS = coders/coders_yuv_la-yuv.lo
+coders_yuv_la_OBJECTS = $(am_coders_yuv_la_OBJECTS)
+coders_yuv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(coders_yuv_la_LDFLAGS) $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_coders_yuv_la_rpath = -rpath $(codersdir)
+filters_analyze_la_DEPENDENCIES = $(LIBMAGICK)
+am_filters_analyze_la_OBJECTS = filters/filters_analyze_la-analyze.lo
+filters_analyze_la_OBJECTS = $(am_filters_analyze_la_OBJECTS)
+filters_analyze_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(filters_analyze_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@WITH_MODULES_TRUE@am_filters_analyze_la_rpath = -rpath $(filtersdir)
+@WITH_MODULES_FALSE@magick_libGraphicsMagick_la_DEPENDENCIES = \
+@WITH_MODULES_FALSE@ $(am__DEPENDENCIES_1)
+@WITH_MODULES_TRUE@magick_libGraphicsMagick_la_DEPENDENCIES = \
+@WITH_MODULES_TRUE@ $(am__DEPENDENCIES_1)
+am__magick_libGraphicsMagick_la_SOURCES_DIST = \
+ magick/alpha_composite.h magick/analyze.c magick/analyze.h \
+ magick/annotate.c magick/api.h magick/attribute.c \
+ magick/attribute.h magick/average.c magick/average.h \
+ magick/bit_stream.c magick/bit_stream.h magick/blob.c \
+ magick/blob.h magick/cdl.c magick/cdl.h magick/channel.c \
+ magick/channel.h magick/common.h magick/compare.c \
+ magick/compare.h magick/confirm_access.c \
+ magick/confirm_access.h magick/color.c magick/color.h \
+ magick/color_lookup.c magick/color_lookup.h magick/colormap.c \
+ magick/colormap.h magick/colorspace.c magick/colorspace.h \
+ magick/command.c magick/command.h magick/composite.c \
+ magick/composite.h magick/compress.c magick/compress.h \
+ magick/constitute.c magick/constitute.h magick/decorate.c \
+ magick/decorate.h magick/delegate.c magick/delegate.h \
+ magick/deprecate.c magick/deprecate.h magick/describe.c \
+ magick/describe.h magick/draw.c magick/draw.h magick/effect.c \
+ magick/effect.h magick/enhance.c magick/enhance.h \
+ magick/enum_strings.c magick/enum_strings.h magick/error.c \
+ magick/error.h magick/export.c magick/floats.c magick/floats.h \
+ magick/forward.h magick/fx.c magick/fx.h magick/gem.c \
+ magick/gem.h magick/gradient.c magick/gradient.h \
+ magick/hclut.c magick/hclut.h magick/image.c magick/image.h \
+ magick/import.c magick/list.c magick/list.h magick/locale.c \
+ magick/locale_c.h magick/log.c magick/log.h magick/magic.c \
+ magick/magic.h magick/magick.c magick/magick.h \
+ magick/magick_endian.c magick/magick_endian.h magick/map.c \
+ magick/map.h magick/memory.c magick/memory.h magick/module.c \
+ magick/module.h magick/monitor.c magick/monitor.h \
+ magick/montage.c magick/montage.h magick/omp_data_view.c \
+ magick/omp_data_view.h magick/operator.c magick/operator.h \
+ magick/paint.c magick/paint.h magick/pixel_cache.h \
+ magick/pixel_cache.c magick/pixel_iterator.c \
+ magick/pixel_iterator.h magick/plasma.c magick/plasma.h \
+ magick/prefetch.h magick/profile.c magick/profile.h \
+ magick/quantize.c magick/quantize.h magick/registry.c \
+ magick/registry.h magick/random.c magick/random.h \
+ magick/render.c magick/render.h magick/resize.c \
+ magick/resize.h magick/resource.c magick/resource.h \
+ magick/segment.c magick/semaphore.c magick/semaphore.h \
+ magick/shear.c magick/shear.h magick/signature.c \
+ magick/signature.h magick/spinlock.h magick/static.c \
+ magick/static.h magick/statistics.c magick/statistics.h \
+ magick/studio.h magick/symbols.h magick/tempfile.c \
+ magick/tempfile.h magick/texture.c magick/texture.h \
+ magick/timer.c magick/timer.h magick/transform.c \
+ magick/transform.h magick/tsd.c magick/tsd.h magick/type.c \
+ magick/type.h magick/unix_port.c magick/utility.c \
+ magick/utility.h magick/version.c magick/version.h \
+ magick/animate.c magick/animate.h magick/display.c \
+ magick/display.h magick/PreRvIcccm.c magick/PreRvIcccm.h \
+ magick/widget.c magick/widget.h magick/xwindow.c \
+ magick/xwindow.h magick/nt_feature.c magick/nt_feature.h \
+ magick/nt_base.c magick/nt_base.h coders/png.c coders/art.c \
+ coders/avs.c coders/bmp.c coders/cals.c coders/caption.c \
+ coders/cineon.c coders/cmyk.c coders/cut.c coders/dcm.c \
+ coders/dcraw.c coders/dib.c coders/dpx.c coders/fax.c \
+ coders/fits.c coders/gif.c coders/gradient.c coders/gray.c \
+ coders/histogram.c coders/hrz.c coders/html.c coders/icon.c \
+ coders/identity.c coders/info.c coders/label.c coders/locale.c \
+ coders/logo.c coders/mac.c coders/map.c coders/mat.c \
+ coders/matte.c coders/meta.c coders/miff.c coders/mono.c \
+ coders/mpc.c coders/mpeg.c coders/mpr.c coders/msl.c \
+ coders/mtv.c coders/mvg.c coders/null.c coders/otb.c \
+ coders/palm.c coders/pcd.c coders/pcl.c coders/pcx.c \
+ coders/pdb.c coders/pdf.c coders/pict.c coders/pix.c \
+ coders/plasma.c coders/pnm.c coders/preview.c coders/ps.c \
+ coders/ps2.c coders/ps3.c coders/pwp.c coders/rgb.c \
+ coders/rla.c coders/rle.c coders/sct.c coders/sfw.c \
+ coders/sgi.c coders/stegano.c coders/sun.c coders/svg.c \
+ coders/tga.c coders/tile.c coders/tim.c coders/topol.c \
+ coders/ttf.c coders/txt.c coders/uil.c coders/url.c \
+ coders/uyvy.c coders/vicar.c coders/vid.c coders/viff.c \
+ coders/wbmp.c coders/wmf.c coders/wpg.c coders/xbm.c \
+ coders/xc.c coders/xcf.c coders/xpm.c coders/yuv.c \
+ coders/psd.c coders/dps.c coders/clipboard.c coders/emf.c \
+ coders/fpx.c coders/jbig.c coders/jnx.c coders/jpeg.c \
+ coders/jp2.c coders/ept.c coders/tiff.c coders/x.c \
+ coders/xwd.c coders/webp.c filters/analyze.c
+@HasX11_TRUE@am__objects_1 = \
+@HasX11_TRUE@ magick/magick_libGraphicsMagick_la-animate.lo \
+@HasX11_TRUE@ magick/magick_libGraphicsMagick_la-display.lo \
+@HasX11_TRUE@ magick/magick_libGraphicsMagick_la-PreRvIcccm.lo \
+@HasX11_TRUE@ magick/magick_libGraphicsMagick_la-widget.lo \
+@HasX11_TRUE@ magick/magick_libGraphicsMagick_la-xwindow.lo
+am__objects_2 = magick/magick_libGraphicsMagick_la-analyze.lo \
+ magick/magick_libGraphicsMagick_la-annotate.lo \
+ magick/magick_libGraphicsMagick_la-attribute.lo \
+ magick/magick_libGraphicsMagick_la-average.lo \
+ magick/magick_libGraphicsMagick_la-bit_stream.lo \
+ magick/magick_libGraphicsMagick_la-blob.lo \
+ magick/magick_libGraphicsMagick_la-cdl.lo \
+ magick/magick_libGraphicsMagick_la-channel.lo \
+ magick/magick_libGraphicsMagick_la-compare.lo \
+ magick/magick_libGraphicsMagick_la-confirm_access.lo \
+ magick/magick_libGraphicsMagick_la-color.lo \
+ magick/magick_libGraphicsMagick_la-color_lookup.lo \
+ magick/magick_libGraphicsMagick_la-colormap.lo \
+ magick/magick_libGraphicsMagick_la-colorspace.lo \
+ magick/magick_libGraphicsMagick_la-command.lo \
+ magick/magick_libGraphicsMagick_la-composite.lo \
+ magick/magick_libGraphicsMagick_la-compress.lo \
+ magick/magick_libGraphicsMagick_la-constitute.lo \
+ magick/magick_libGraphicsMagick_la-decorate.lo \
+ magick/magick_libGraphicsMagick_la-delegate.lo \
+ magick/magick_libGraphicsMagick_la-deprecate.lo \
+ magick/magick_libGraphicsMagick_la-describe.lo \
+ magick/magick_libGraphicsMagick_la-draw.lo \
+ magick/magick_libGraphicsMagick_la-effect.lo \
+ magick/magick_libGraphicsMagick_la-enhance.lo \
+ magick/magick_libGraphicsMagick_la-enum_strings.lo \
+ magick/magick_libGraphicsMagick_la-error.lo \
+ magick/magick_libGraphicsMagick_la-export.lo \
+ magick/magick_libGraphicsMagick_la-floats.lo \
+ magick/magick_libGraphicsMagick_la-fx.lo \
+ magick/magick_libGraphicsMagick_la-gem.lo \
+ magick/magick_libGraphicsMagick_la-gradient.lo \
+ magick/magick_libGraphicsMagick_la-hclut.lo \
+ magick/magick_libGraphicsMagick_la-image.lo \
+ magick/magick_libGraphicsMagick_la-import.lo \
+ magick/magick_libGraphicsMagick_la-list.lo \
+ magick/magick_libGraphicsMagick_la-locale.lo \
+ magick/magick_libGraphicsMagick_la-log.lo \
+ magick/magick_libGraphicsMagick_la-magic.lo \
+ magick/magick_libGraphicsMagick_la-magick.lo \
+ magick/magick_libGraphicsMagick_la-magick_endian.lo \
+ magick/magick_libGraphicsMagick_la-map.lo \
+ magick/magick_libGraphicsMagick_la-memory.lo \
+ magick/magick_libGraphicsMagick_la-module.lo \
+ magick/magick_libGraphicsMagick_la-monitor.lo \
+ magick/magick_libGraphicsMagick_la-montage.lo \
+ magick/magick_libGraphicsMagick_la-omp_data_view.lo \
+ magick/magick_libGraphicsMagick_la-operator.lo \
+ magick/magick_libGraphicsMagick_la-paint.lo \
+ magick/magick_libGraphicsMagick_la-pixel_cache.lo \
+ magick/magick_libGraphicsMagick_la-pixel_iterator.lo \
+ magick/magick_libGraphicsMagick_la-plasma.lo \
+ magick/magick_libGraphicsMagick_la-profile.lo \
+ magick/magick_libGraphicsMagick_la-quantize.lo \
+ magick/magick_libGraphicsMagick_la-registry.lo \
+ magick/magick_libGraphicsMagick_la-random.lo \
+ magick/magick_libGraphicsMagick_la-render.lo \
+ magick/magick_libGraphicsMagick_la-resize.lo \
+ magick/magick_libGraphicsMagick_la-resource.lo \
+ magick/magick_libGraphicsMagick_la-segment.lo \
+ magick/magick_libGraphicsMagick_la-semaphore.lo \
+ magick/magick_libGraphicsMagick_la-shear.lo \
+ magick/magick_libGraphicsMagick_la-signature.lo \
+ magick/magick_libGraphicsMagick_la-static.lo \
+ magick/magick_libGraphicsMagick_la-statistics.lo \
+ magick/magick_libGraphicsMagick_la-tempfile.lo \
+ magick/magick_libGraphicsMagick_la-texture.lo \
+ magick/magick_libGraphicsMagick_la-timer.lo \
+ magick/magick_libGraphicsMagick_la-transform.lo \
+ magick/magick_libGraphicsMagick_la-tsd.lo \
+ magick/magick_libGraphicsMagick_la-type.lo \
+ magick/magick_libGraphicsMagick_la-unix_port.lo \
+ magick/magick_libGraphicsMagick_la-utility.lo \
+ magick/magick_libGraphicsMagick_la-version.lo $(am__objects_1)
+@CYGWIN_BUILD_TRUE@@WIN32_NATIVE_BUILD_FALSE@am__objects_3 = magick/magick_libGraphicsMagick_la-nt_feature.lo
+@WIN32_NATIVE_BUILD_TRUE@am__objects_3 = magick/magick_libGraphicsMagick_la-nt_base.lo \
+@WIN32_NATIVE_BUILD_TRUE@ magick/magick_libGraphicsMagick_la-nt_feature.lo
+@HasPNG_TRUE@am__objects_4 = \
+@HasPNG_TRUE@ coders/magick_libGraphicsMagick_la-png.lo
+@ENABLE_BROKEN_CODERS_TRUE@am__objects_5 = coders/magick_libGraphicsMagick_la-psd.lo
+@HasDPS_TRUE@am__objects_6 = \
+@HasDPS_TRUE@ coders/magick_libGraphicsMagick_la-dps.lo
+@HasWINGDI32_TRUE@am__objects_7 = coders/magick_libGraphicsMagick_la-clipboard.lo \
+@HasWINGDI32_TRUE@ coders/magick_libGraphicsMagick_la-emf.lo
+@HasFPX_TRUE@am__objects_8 = \
+@HasFPX_TRUE@ coders/magick_libGraphicsMagick_la-fpx.lo
+@HasJBIG_TRUE@am__objects_9 = \
+@HasJBIG_TRUE@ coders/magick_libGraphicsMagick_la-jbig.lo
+@HasJPEG_TRUE@am__objects_10 = \
+@HasJPEG_TRUE@ coders/magick_libGraphicsMagick_la-jnx.lo \
+@HasJPEG_TRUE@ coders/magick_libGraphicsMagick_la-jpeg.lo
+@HasJP2_TRUE@am__objects_11 = \
+@HasJP2_TRUE@ coders/magick_libGraphicsMagick_la-jp2.lo
+@HasTIFF_TRUE@am__objects_12 = \
+@HasTIFF_TRUE@ coders/magick_libGraphicsMagick_la-ept.lo \
+@HasTIFF_TRUE@ coders/magick_libGraphicsMagick_la-tiff.lo
+@HasX11_TRUE@am__objects_13 = coders/magick_libGraphicsMagick_la-x.lo \
+@HasX11_TRUE@ coders/magick_libGraphicsMagick_la-xwd.lo
+@HasWEBP_TRUE@am__objects_14 = \
+@HasWEBP_TRUE@ coders/magick_libGraphicsMagick_la-webp.lo
+am__objects_15 = $(am__objects_4) \
+ coders/magick_libGraphicsMagick_la-art.lo \
+ coders/magick_libGraphicsMagick_la-avs.lo \
+ coders/magick_libGraphicsMagick_la-bmp.lo \
+ coders/magick_libGraphicsMagick_la-cals.lo \
+ coders/magick_libGraphicsMagick_la-caption.lo \
+ coders/magick_libGraphicsMagick_la-cineon.lo \
+ coders/magick_libGraphicsMagick_la-cmyk.lo \
+ coders/magick_libGraphicsMagick_la-cut.lo \
+ coders/magick_libGraphicsMagick_la-dcm.lo \
+ coders/magick_libGraphicsMagick_la-dcraw.lo \
+ coders/magick_libGraphicsMagick_la-dib.lo \
+ coders/magick_libGraphicsMagick_la-dpx.lo \
+ coders/magick_libGraphicsMagick_la-fax.lo \
+ coders/magick_libGraphicsMagick_la-fits.lo \
+ coders/magick_libGraphicsMagick_la-gif.lo \
+ coders/magick_libGraphicsMagick_la-gradient.lo \
+ coders/magick_libGraphicsMagick_la-gray.lo \
+ coders/magick_libGraphicsMagick_la-histogram.lo \
+ coders/magick_libGraphicsMagick_la-hrz.lo \
+ coders/magick_libGraphicsMagick_la-html.lo \
+ coders/magick_libGraphicsMagick_la-icon.lo \
+ coders/magick_libGraphicsMagick_la-identity.lo \
+ coders/magick_libGraphicsMagick_la-info.lo \
+ coders/magick_libGraphicsMagick_la-label.lo \
+ coders/magick_libGraphicsMagick_la-locale.lo \
+ coders/magick_libGraphicsMagick_la-logo.lo \
+ coders/magick_libGraphicsMagick_la-mac.lo \
+ coders/magick_libGraphicsMagick_la-map.lo \
+ coders/magick_libGraphicsMagick_la-mat.lo \
+ coders/magick_libGraphicsMagick_la-matte.lo \
+ coders/magick_libGraphicsMagick_la-meta.lo \
+ coders/magick_libGraphicsMagick_la-miff.lo \
+ coders/magick_libGraphicsMagick_la-mono.lo \
+ coders/magick_libGraphicsMagick_la-mpc.lo \
+ coders/magick_libGraphicsMagick_la-mpeg.lo \
+ coders/magick_libGraphicsMagick_la-mpr.lo \
+ coders/magick_libGraphicsMagick_la-msl.lo \
+ coders/magick_libGraphicsMagick_la-mtv.lo \
+ coders/magick_libGraphicsMagick_la-mvg.lo \
+ coders/magick_libGraphicsMagick_la-null.lo \
+ coders/magick_libGraphicsMagick_la-otb.lo \
+ coders/magick_libGraphicsMagick_la-palm.lo \
+ coders/magick_libGraphicsMagick_la-pcd.lo \
+ coders/magick_libGraphicsMagick_la-pcl.lo \
+ coders/magick_libGraphicsMagick_la-pcx.lo \
+ coders/magick_libGraphicsMagick_la-pdb.lo \
+ coders/magick_libGraphicsMagick_la-pdf.lo \
+ coders/magick_libGraphicsMagick_la-pict.lo \
+ coders/magick_libGraphicsMagick_la-pix.lo \
+ coders/magick_libGraphicsMagick_la-plasma.lo \
+ coders/magick_libGraphicsMagick_la-pnm.lo \
+ coders/magick_libGraphicsMagick_la-preview.lo \
+ coders/magick_libGraphicsMagick_la-ps.lo \
+ coders/magick_libGraphicsMagick_la-ps2.lo \
+ coders/magick_libGraphicsMagick_la-ps3.lo \
+ coders/magick_libGraphicsMagick_la-pwp.lo \
+ coders/magick_libGraphicsMagick_la-rgb.lo \
+ coders/magick_libGraphicsMagick_la-rla.lo \
+ coders/magick_libGraphicsMagick_la-rle.lo \
+ coders/magick_libGraphicsMagick_la-sct.lo \
+ coders/magick_libGraphicsMagick_la-sfw.lo \
+ coders/magick_libGraphicsMagick_la-sgi.lo \
+ coders/magick_libGraphicsMagick_la-stegano.lo \
+ coders/magick_libGraphicsMagick_la-sun.lo \
+ coders/magick_libGraphicsMagick_la-svg.lo \
+ coders/magick_libGraphicsMagick_la-tga.lo \
+ coders/magick_libGraphicsMagick_la-tile.lo \
+ coders/magick_libGraphicsMagick_la-tim.lo \
+ coders/magick_libGraphicsMagick_la-topol.lo \
+ coders/magick_libGraphicsMagick_la-ttf.lo \
+ coders/magick_libGraphicsMagick_la-txt.lo \
+ coders/magick_libGraphicsMagick_la-uil.lo \
+ coders/magick_libGraphicsMagick_la-url.lo \
+ coders/magick_libGraphicsMagick_la-uyvy.lo \
+ coders/magick_libGraphicsMagick_la-vicar.lo \
+ coders/magick_libGraphicsMagick_la-vid.lo \
+ coders/magick_libGraphicsMagick_la-viff.lo \
+ coders/magick_libGraphicsMagick_la-wbmp.lo \
+ coders/magick_libGraphicsMagick_la-wmf.lo \
+ coders/magick_libGraphicsMagick_la-wpg.lo \
+ coders/magick_libGraphicsMagick_la-xbm.lo \
+ coders/magick_libGraphicsMagick_la-xc.lo \
+ coders/magick_libGraphicsMagick_la-xcf.lo \
+ coders/magick_libGraphicsMagick_la-xpm.lo \
+ coders/magick_libGraphicsMagick_la-yuv.lo $(am__objects_5) \
+ $(am__objects_6) $(am__objects_7) $(am__objects_8) \
+ $(am__objects_9) $(am__objects_10) $(am__objects_11) \
+ $(am__objects_12) $(am__objects_13) $(am__objects_14)
+am__objects_16 = filters/magick_libGraphicsMagick_la-analyze.lo
+@WITH_MODULES_FALSE@am_magick_libGraphicsMagick_la_OBJECTS = \
+@WITH_MODULES_FALSE@ $(am__objects_2) $(am__objects_3) \
+@WITH_MODULES_FALSE@ $(am__objects_15) $(am__objects_16)
+@WITH_MODULES_TRUE@am_magick_libGraphicsMagick_la_OBJECTS = \
+@WITH_MODULES_TRUE@ $(am__objects_2) $(am__objects_3)
+magick_libGraphicsMagick_la_OBJECTS = \
+ $(am_magick_libGraphicsMagick_la_OBJECTS)
+magick_libGraphicsMagick_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(magick_libGraphicsMagick_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+wand_libGraphicsMagickWand_la_DEPENDENCIES = $(LIBMAGICK) \
+ $(am__DEPENDENCIES_1)
+am__objects_17 = wand/wand_libGraphicsMagickWand_la-drawing_wand.lo \
+ wand/wand_libGraphicsMagickWand_la-magick_compat.lo \
+ wand/wand_libGraphicsMagickWand_la-magick_wand.lo \
+ wand/wand_libGraphicsMagickWand_la-pixel_wand.lo
+am_wand_libGraphicsMagickWand_la_OBJECTS = $(am__objects_17)
+wand_libGraphicsMagickWand_la_OBJECTS = \
+ $(am_wand_libGraphicsMagickWand_la_OBJECTS)
+wand_libGraphicsMagickWand_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) \
+ $(wand_libGraphicsMagickWand_la_LDFLAGS) $(LDFLAGS) -o $@
+am__EXEEXT_1 = utilities/gm$(EXEEXT)
+am__EXEEXT_2 = tests/bitstream$(EXEEXT) tests/constitute$(EXEEXT) \
+ tests/drawtest$(EXEEXT) tests/maptest$(EXEEXT) \
+ tests/rwblob$(EXEEXT) tests/rwfile$(EXEEXT)
+am__EXEEXT_3 = Magick++/demo/analyze$(EXEEXT) \
+ Magick++/demo/button$(EXEEXT) Magick++/demo/demo$(EXEEXT) \
+ Magick++/demo/detrans$(EXEEXT) Magick++/demo/flip$(EXEEXT) \
+ Magick++/demo/gravity$(EXEEXT) Magick++/demo/piddle$(EXEEXT) \
+ Magick++/demo/shapes$(EXEEXT) Magick++/demo/zoom$(EXEEXT) \
+ Magick++/tests/appendImages$(EXEEXT) \
+ Magick++/tests/attributes$(EXEEXT) \
+ Magick++/tests/averageImages$(EXEEXT) \
+ Magick++/tests/coalesceImages$(EXEEXT) \
+ Magick++/tests/coderInfo$(EXEEXT) \
+ Magick++/tests/color$(EXEEXT) \
+ Magick++/tests/colorHistogram$(EXEEXT) \
+ Magick++/tests/exceptions$(EXEEXT) \
+ Magick++/tests/montageImages$(EXEEXT) \
+ Magick++/tests/morphImages$(EXEEXT) \
+ Magick++/tests/readWriteBlob$(EXEEXT) \
+ Magick++/tests/readWriteImages$(EXEEXT)
+@WITH_MAGICK_PLUS_PLUS_TRUE@am__EXEEXT_4 = $(am__EXEEXT_3)
+am__EXEEXT_5 = wand/drawtest$(EXEEXT) wand/wandtest$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+am_Magick___demo_analyze_OBJECTS = \
+ Magick++/demo/Magick___demo_analyze-analyze.$(OBJEXT)
+Magick___demo_analyze_OBJECTS = $(am_Magick___demo_analyze_OBJECTS)
+@WITH_MAGICK_PLUS_PLUS_TRUE@am__DEPENDENCIES_2 = Magick++/lib/libGraphicsMagick++.la
+Magick___demo_analyze_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___demo_button_OBJECTS = \
+ Magick++/demo/Magick___demo_button-button.$(OBJEXT)
+Magick___demo_button_OBJECTS = $(am_Magick___demo_button_OBJECTS)
+Magick___demo_button_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___demo_demo_OBJECTS = \
+ Magick++/demo/Magick___demo_demo-demo.$(OBJEXT)
+Magick___demo_demo_OBJECTS = $(am_Magick___demo_demo_OBJECTS)
+Magick___demo_demo_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___demo_detrans_OBJECTS = \
+ Magick++/demo/Magick___demo_detrans-detrans.$(OBJEXT)
+Magick___demo_detrans_OBJECTS = $(am_Magick___demo_detrans_OBJECTS)
+Magick___demo_detrans_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___demo_flip_OBJECTS = \
+ Magick++/demo/Magick___demo_flip-flip.$(OBJEXT)
+Magick___demo_flip_OBJECTS = $(am_Magick___demo_flip_OBJECTS)
+Magick___demo_flip_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___demo_gravity_OBJECTS = \
+ Magick++/demo/Magick___demo_gravity-gravity.$(OBJEXT)
+Magick___demo_gravity_OBJECTS = $(am_Magick___demo_gravity_OBJECTS)
+Magick___demo_gravity_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___demo_piddle_OBJECTS = \
+ Magick++/demo/Magick___demo_piddle-piddle.$(OBJEXT)
+Magick___demo_piddle_OBJECTS = $(am_Magick___demo_piddle_OBJECTS)
+Magick___demo_piddle_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___demo_shapes_OBJECTS = \
+ Magick++/demo/Magick___demo_shapes-shapes.$(OBJEXT)
+Magick___demo_shapes_OBJECTS = $(am_Magick___demo_shapes_OBJECTS)
+Magick___demo_shapes_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___demo_zoom_OBJECTS = \
+ Magick++/demo/Magick___demo_zoom-zoom.$(OBJEXT)
+Magick___demo_zoom_OBJECTS = $(am_Magick___demo_zoom_OBJECTS)
+Magick___demo_zoom_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_appendImages_OBJECTS = Magick++/tests/Magick___tests_appendImages-appendImages.$(OBJEXT)
+Magick___tests_appendImages_OBJECTS = \
+ $(am_Magick___tests_appendImages_OBJECTS)
+Magick___tests_appendImages_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_attributes_OBJECTS = \
+ Magick++/tests/Magick___tests_attributes-attributes.$(OBJEXT)
+Magick___tests_attributes_OBJECTS = \
+ $(am_Magick___tests_attributes_OBJECTS)
+Magick___tests_attributes_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_averageImages_OBJECTS = Magick++/tests/Magick___tests_averageImages-averageImages.$(OBJEXT)
+Magick___tests_averageImages_OBJECTS = \
+ $(am_Magick___tests_averageImages_OBJECTS)
+Magick___tests_averageImages_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_coalesceImages_OBJECTS = Magick++/tests/Magick___tests_coalesceImages-coalesceImages.$(OBJEXT)
+Magick___tests_coalesceImages_OBJECTS = \
+ $(am_Magick___tests_coalesceImages_OBJECTS)
+Magick___tests_coalesceImages_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_coderInfo_OBJECTS = \
+ Magick++/tests/Magick___tests_coderInfo-coderInfo.$(OBJEXT)
+Magick___tests_coderInfo_OBJECTS = \
+ $(am_Magick___tests_coderInfo_OBJECTS)
+Magick___tests_coderInfo_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_color_OBJECTS = \
+ Magick++/tests/Magick___tests_color-color.$(OBJEXT)
+Magick___tests_color_OBJECTS = $(am_Magick___tests_color_OBJECTS)
+Magick___tests_color_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_colorHistogram_OBJECTS = Magick++/tests/Magick___tests_colorHistogram-colorHistogram.$(OBJEXT)
+Magick___tests_colorHistogram_OBJECTS = \
+ $(am_Magick___tests_colorHistogram_OBJECTS)
+Magick___tests_colorHistogram_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_exceptions_OBJECTS = \
+ Magick++/tests/Magick___tests_exceptions-exceptions.$(OBJEXT)
+Magick___tests_exceptions_OBJECTS = \
+ $(am_Magick___tests_exceptions_OBJECTS)
+Magick___tests_exceptions_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_montageImages_OBJECTS = Magick++/tests/Magick___tests_montageImages-montageImages.$(OBJEXT)
+Magick___tests_montageImages_OBJECTS = \
+ $(am_Magick___tests_montageImages_OBJECTS)
+Magick___tests_montageImages_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_morphImages_OBJECTS = Magick++/tests/Magick___tests_morphImages-morphImages.$(OBJEXT)
+Magick___tests_morphImages_OBJECTS = \
+ $(am_Magick___tests_morphImages_OBJECTS)
+Magick___tests_morphImages_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_readWriteBlob_OBJECTS = Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.$(OBJEXT)
+Magick___tests_readWriteBlob_OBJECTS = \
+ $(am_Magick___tests_readWriteBlob_OBJECTS)
+Magick___tests_readWriteBlob_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_Magick___tests_readWriteImages_OBJECTS = Magick++/tests/Magick___tests_readWriteImages-readWriteImages.$(OBJEXT)
+Magick___tests_readWriteImages_OBJECTS = \
+ $(am_Magick___tests_readWriteImages_OBJECTS)
+Magick___tests_readWriteImages_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_tests_bitstream_OBJECTS = \
+ tests/tests_bitstream-bitstream.$(OBJEXT)
+tests_bitstream_OBJECTS = $(am_tests_bitstream_OBJECTS)
+tests_bitstream_DEPENDENCIES = $(LIBMAGICK)
+am_tests_constitute_OBJECTS = \
+ tests/tests_constitute-constitute.$(OBJEXT)
+tests_constitute_OBJECTS = $(am_tests_constitute_OBJECTS)
+tests_constitute_DEPENDENCIES = $(LIBMAGICK)
+am_tests_drawtest_OBJECTS = tests/tests_drawtest-drawtest.$(OBJEXT)
+tests_drawtest_OBJECTS = $(am_tests_drawtest_OBJECTS)
+tests_drawtest_DEPENDENCIES = $(LIBMAGICK)
+am_tests_maptest_OBJECTS = tests/tests_maptest-maptest.$(OBJEXT)
+tests_maptest_OBJECTS = $(am_tests_maptest_OBJECTS)
+tests_maptest_DEPENDENCIES = $(LIBMAGICK)
+am_tests_rwblob_OBJECTS = tests/tests_rwblob-rwblob.$(OBJEXT)
+tests_rwblob_OBJECTS = $(am_tests_rwblob_OBJECTS)
+tests_rwblob_DEPENDENCIES = $(LIBMAGICK)
+am_tests_rwfile_OBJECTS = tests/tests_rwfile-rwfile.$(OBJEXT)
+tests_rwfile_OBJECTS = $(am_tests_rwfile_OBJECTS)
+tests_rwfile_DEPENDENCIES = $(LIBMAGICK)
+am_utilities_gm_OBJECTS = utilities/gm.$(OBJEXT)
+utilities_gm_OBJECTS = $(am_utilities_gm_OBJECTS)
+utilities_gm_DEPENDENCIES = $(LIBMAGICK)
+utilities_gm_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(utilities_gm_LDFLAGS) $(LDFLAGS) -o $@
+am_wand_drawtest_OBJECTS = wand/wand_drawtest-drawtest.$(OBJEXT)
+wand_drawtest_OBJECTS = $(am_wand_drawtest_OBJECTS)
+wand_drawtest_DEPENDENCIES = $(LIBWAND)
+wand_drawtest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(wand_drawtest_LDFLAGS) $(LDFLAGS) -o $@
+am_wand_wandtest_OBJECTS = wand/wand_wandtest-wandtest.$(OBJEXT)
+wand_wandtest_OBJECTS = $(am_wand_wandtest_OBJECTS)
+wand_wandtest_DEPENDENCIES = $(LIBWAND)
+wand_wandtest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(wand_wandtest_LDFLAGS) $(LDFLAGS) -o $@
+SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES =
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+am__v_CXX_1 =
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+am__v_CXXLD_1 =
+SOURCES = $(Magick___lib_libGraphicsMagick___la_SOURCES) \
+ $(coders_art_la_SOURCES) $(coders_avs_la_SOURCES) \
+ $(coders_bmp_la_SOURCES) $(coders_cals_la_SOURCES) \
+ $(coders_caption_la_SOURCES) $(coders_cineon_la_SOURCES) \
+ $(coders_clipboard_la_SOURCES) $(coders_cmyk_la_SOURCES) \
+ $(coders_cut_la_SOURCES) $(coders_dcm_la_SOURCES) \
+ $(coders_dcraw_la_SOURCES) $(coders_dib_la_SOURCES) \
+ $(coders_dps_la_SOURCES) $(coders_dpx_la_SOURCES) \
+ $(coders_emf_la_SOURCES) $(coders_ept_la_SOURCES) \
+ $(coders_fax_la_SOURCES) $(coders_fits_la_SOURCES) \
+ $(coders_fpx_la_SOURCES) $(coders_gif_la_SOURCES) \
+ $(coders_gradient_la_SOURCES) $(coders_gray_la_SOURCES) \
+ $(coders_histogram_la_SOURCES) $(coders_hrz_la_SOURCES) \
+ $(coders_html_la_SOURCES) $(coders_icon_la_SOURCES) \
+ $(coders_identity_la_SOURCES) $(coders_info_la_SOURCES) \
+ $(coders_jbig_la_SOURCES) $(coders_jnx_la_SOURCES) \
+ $(coders_jp2_la_SOURCES) $(coders_jpeg_la_SOURCES) \
+ $(coders_label_la_SOURCES) $(coders_locale_la_SOURCES) \
+ $(coders_logo_la_SOURCES) $(coders_mac_la_SOURCES) \
+ $(coders_map_la_SOURCES) $(coders_mat_la_SOURCES) \
+ $(coders_matte_la_SOURCES) $(coders_meta_la_SOURCES) \
+ $(coders_miff_la_SOURCES) $(coders_mono_la_SOURCES) \
+ $(coders_mpc_la_SOURCES) $(coders_mpeg_la_SOURCES) \
+ $(coders_mpr_la_SOURCES) $(coders_msl_la_SOURCES) \
+ $(coders_mtv_la_SOURCES) $(coders_mvg_la_SOURCES) \
+ $(coders_null_la_SOURCES) $(coders_otb_la_SOURCES) \
+ $(coders_palm_la_SOURCES) $(coders_pcd_la_SOURCES) \
+ $(coders_pcl_la_SOURCES) $(coders_pcx_la_SOURCES) \
+ $(coders_pdb_la_SOURCES) $(coders_pdf_la_SOURCES) \
+ $(coders_pict_la_SOURCES) $(coders_pix_la_SOURCES) \
+ $(coders_plasma_la_SOURCES) $(coders_png_la_SOURCES) \
+ $(coders_pnm_la_SOURCES) $(coders_preview_la_SOURCES) \
+ $(coders_ps_la_SOURCES) $(coders_ps2_la_SOURCES) \
+ $(coders_ps3_la_SOURCES) $(coders_psd_la_SOURCES) \
+ $(coders_pwp_la_SOURCES) $(coders_rgb_la_SOURCES) \
+ $(coders_rla_la_SOURCES) $(coders_rle_la_SOURCES) \
+ $(coders_sct_la_SOURCES) $(coders_sfw_la_SOURCES) \
+ $(coders_sgi_la_SOURCES) $(coders_stegano_la_SOURCES) \
+ $(coders_sun_la_SOURCES) $(coders_svg_la_SOURCES) \
+ $(coders_tga_la_SOURCES) $(coders_tiff_la_SOURCES) \
+ $(coders_tile_la_SOURCES) $(coders_tim_la_SOURCES) \
+ $(coders_topol_la_SOURCES) $(coders_ttf_la_SOURCES) \
+ $(coders_txt_la_SOURCES) $(coders_uil_la_SOURCES) \
+ $(coders_url_la_SOURCES) $(coders_uyvy_la_SOURCES) \
+ $(coders_vicar_la_SOURCES) $(coders_vid_la_SOURCES) \
+ $(coders_viff_la_SOURCES) $(coders_wbmp_la_SOURCES) \
+ $(coders_webp_la_SOURCES) $(coders_wmf_la_SOURCES) \
+ $(coders_wpg_la_SOURCES) $(coders_x_la_SOURCES) \
+ $(coders_xbm_la_SOURCES) $(coders_xc_la_SOURCES) \
+ $(coders_xcf_la_SOURCES) $(coders_xpm_la_SOURCES) \
+ $(coders_xwd_la_SOURCES) $(coders_yuv_la_SOURCES) \
+ $(filters_analyze_la_SOURCES) \
+ $(magick_libGraphicsMagick_la_SOURCES) \
+ $(wand_libGraphicsMagickWand_la_SOURCES) \
+ $(Magick___demo_analyze_SOURCES) \
+ $(Magick___demo_button_SOURCES) $(Magick___demo_demo_SOURCES) \
+ $(Magick___demo_detrans_SOURCES) $(Magick___demo_flip_SOURCES) \
+ $(Magick___demo_gravity_SOURCES) \
+ $(Magick___demo_piddle_SOURCES) \
+ $(Magick___demo_shapes_SOURCES) $(Magick___demo_zoom_SOURCES) \
+ $(Magick___tests_appendImages_SOURCES) \
+ $(Magick___tests_attributes_SOURCES) \
+ $(Magick___tests_averageImages_SOURCES) \
+ $(Magick___tests_coalesceImages_SOURCES) \
+ $(Magick___tests_coderInfo_SOURCES) \
+ $(Magick___tests_color_SOURCES) \
+ $(Magick___tests_colorHistogram_SOURCES) \
+ $(Magick___tests_exceptions_SOURCES) \
+ $(Magick___tests_montageImages_SOURCES) \
+ $(Magick___tests_morphImages_SOURCES) \
+ $(Magick___tests_readWriteBlob_SOURCES) \
+ $(Magick___tests_readWriteImages_SOURCES) \
+ $(tests_bitstream_SOURCES) $(tests_constitute_SOURCES) \
+ $(tests_drawtest_SOURCES) $(tests_maptest_SOURCES) \
+ $(tests_rwblob_SOURCES) $(tests_rwfile_SOURCES) \
+ $(utilities_gm_SOURCES) $(wand_drawtest_SOURCES) \
+ $(wand_wandtest_SOURCES)
+DIST_SOURCES = $(Magick___lib_libGraphicsMagick___la_SOURCES) \
+ $(coders_art_la_SOURCES) $(coders_avs_la_SOURCES) \
+ $(coders_bmp_la_SOURCES) $(coders_cals_la_SOURCES) \
+ $(coders_caption_la_SOURCES) $(coders_cineon_la_SOURCES) \
+ $(coders_clipboard_la_SOURCES) $(coders_cmyk_la_SOURCES) \
+ $(coders_cut_la_SOURCES) $(coders_dcm_la_SOURCES) \
+ $(coders_dcraw_la_SOURCES) $(coders_dib_la_SOURCES) \
+ $(coders_dps_la_SOURCES) $(coders_dpx_la_SOURCES) \
+ $(coders_emf_la_SOURCES) $(coders_ept_la_SOURCES) \
+ $(coders_fax_la_SOURCES) $(coders_fits_la_SOURCES) \
+ $(coders_fpx_la_SOURCES) $(coders_gif_la_SOURCES) \
+ $(coders_gradient_la_SOURCES) $(coders_gray_la_SOURCES) \
+ $(coders_histogram_la_SOURCES) $(coders_hrz_la_SOURCES) \
+ $(coders_html_la_SOURCES) $(coders_icon_la_SOURCES) \
+ $(coders_identity_la_SOURCES) $(coders_info_la_SOURCES) \
+ $(coders_jbig_la_SOURCES) $(coders_jnx_la_SOURCES) \
+ $(coders_jp2_la_SOURCES) $(coders_jpeg_la_SOURCES) \
+ $(coders_label_la_SOURCES) $(coders_locale_la_SOURCES) \
+ $(coders_logo_la_SOURCES) $(coders_mac_la_SOURCES) \
+ $(coders_map_la_SOURCES) $(coders_mat_la_SOURCES) \
+ $(coders_matte_la_SOURCES) $(coders_meta_la_SOURCES) \
+ $(coders_miff_la_SOURCES) $(coders_mono_la_SOURCES) \
+ $(coders_mpc_la_SOURCES) $(coders_mpeg_la_SOURCES) \
+ $(coders_mpr_la_SOURCES) $(coders_msl_la_SOURCES) \
+ $(coders_mtv_la_SOURCES) $(coders_mvg_la_SOURCES) \
+ $(coders_null_la_SOURCES) $(coders_otb_la_SOURCES) \
+ $(coders_palm_la_SOURCES) $(coders_pcd_la_SOURCES) \
+ $(coders_pcl_la_SOURCES) $(coders_pcx_la_SOURCES) \
+ $(coders_pdb_la_SOURCES) $(coders_pdf_la_SOURCES) \
+ $(coders_pict_la_SOURCES) $(coders_pix_la_SOURCES) \
+ $(coders_plasma_la_SOURCES) $(coders_png_la_SOURCES) \
+ $(coders_pnm_la_SOURCES) $(coders_preview_la_SOURCES) \
+ $(coders_ps_la_SOURCES) $(coders_ps2_la_SOURCES) \
+ $(coders_ps3_la_SOURCES) $(coders_psd_la_SOURCES) \
+ $(coders_pwp_la_SOURCES) $(coders_rgb_la_SOURCES) \
+ $(coders_rla_la_SOURCES) $(coders_rle_la_SOURCES) \
+ $(coders_sct_la_SOURCES) $(coders_sfw_la_SOURCES) \
+ $(coders_sgi_la_SOURCES) $(coders_stegano_la_SOURCES) \
+ $(coders_sun_la_SOURCES) $(coders_svg_la_SOURCES) \
+ $(coders_tga_la_SOURCES) $(coders_tiff_la_SOURCES) \
+ $(coders_tile_la_SOURCES) $(coders_tim_la_SOURCES) \
+ $(coders_topol_la_SOURCES) $(coders_ttf_la_SOURCES) \
+ $(coders_txt_la_SOURCES) $(coders_uil_la_SOURCES) \
+ $(coders_url_la_SOURCES) $(coders_uyvy_la_SOURCES) \
+ $(coders_vicar_la_SOURCES) $(coders_vid_la_SOURCES) \
+ $(coders_viff_la_SOURCES) $(coders_wbmp_la_SOURCES) \
+ $(coders_webp_la_SOURCES) $(coders_wmf_la_SOURCES) \
+ $(coders_wpg_la_SOURCES) $(coders_x_la_SOURCES) \
+ $(coders_xbm_la_SOURCES) $(coders_xc_la_SOURCES) \
+ $(coders_xcf_la_SOURCES) $(coders_xpm_la_SOURCES) \
+ $(coders_xwd_la_SOURCES) $(coders_yuv_la_SOURCES) \
+ $(filters_analyze_la_SOURCES) \
+ $(am__magick_libGraphicsMagick_la_SOURCES_DIST) \
+ $(wand_libGraphicsMagickWand_la_SOURCES) \
+ $(Magick___demo_analyze_SOURCES) \
+ $(Magick___demo_button_SOURCES) $(Magick___demo_demo_SOURCES) \
+ $(Magick___demo_detrans_SOURCES) $(Magick___demo_flip_SOURCES) \
+ $(Magick___demo_gravity_SOURCES) \
+ $(Magick___demo_piddle_SOURCES) \
+ $(Magick___demo_shapes_SOURCES) $(Magick___demo_zoom_SOURCES) \
+ $(Magick___tests_appendImages_SOURCES) \
+ $(Magick___tests_attributes_SOURCES) \
+ $(Magick___tests_averageImages_SOURCES) \
+ $(Magick___tests_coalesceImages_SOURCES) \
+ $(Magick___tests_coderInfo_SOURCES) \
+ $(Magick___tests_color_SOURCES) \
+ $(Magick___tests_colorHistogram_SOURCES) \
+ $(Magick___tests_exceptions_SOURCES) \
+ $(Magick___tests_montageImages_SOURCES) \
+ $(Magick___tests_morphImages_SOURCES) \
+ $(Magick___tests_readWriteBlob_SOURCES) \
+ $(Magick___tests_readWriteImages_SOURCES) \
+ $(tests_bitstream_SOURCES) $(tests_constitute_SOURCES) \
+ $(tests_drawtest_SOURCES) $(tests_maptest_SOURCES) \
+ $(tests_rwblob_SOURCES) $(tests_rwfile_SOURCES) \
+ $(utilities_gm_SOURCES) $(wand_drawtest_SOURCES) \
+ $(wand_wandtest_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man1dir = $(mandir)/man1
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+NROFF = nroff
+MANS = $(man_MANS)
+DATA = $(configlib_DATA) $(configshare_DATA) $(doc_DATA) \
+ $(pkgconfig_DATA)
+am__magickppinc_HEADERS_DIST = Magick++/lib/Magick++/Blob.h \
+ Magick++/lib/Magick++/CoderInfo.h \
+ Magick++/lib/Magick++/Color.h Magick++/lib/Magick++/Drawable.h \
+ Magick++/lib/Magick++/Exception.h \
+ Magick++/lib/Magick++/Geometry.h Magick++/lib/Magick++/Image.h \
+ Magick++/lib/Magick++/Include.h \
+ Magick++/lib/Magick++/Montage.h Magick++/lib/Magick++/Pixels.h \
+ Magick++/lib/Magick++/STL.h Magick++/lib/Magick++/TypeMetric.h
+am__magickpptopinc_HEADERS_DIST = Magick++/lib/Magick++.h
+HEADERS = $(include_HEADERS) $(magickinc_HEADERS) \
+ $(magickppinc_HEADERS) $(magickpptopinc_HEADERS) \
+ $(noinst_HEADERS) $(wandinc_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+AM_RECURSIVE_TARGETS = cscope check recheck
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+@WITH_MAGICK_PLUS_PLUS_TRUE@am__EXEEXT_6 = \
+@WITH_MAGICK_PLUS_PLUS_TRUE@ $(MAGICKPP_TEST_SCRIPTS_OPT)
+am__EXEEXT_7 =
+TEST_SUITE_LOG = test-suite.log
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+am__test_logs3 = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+TEST_LOGS = $(am__test_logs3:.tap.log=.log)
+TAP_LOG_COMPILE = $(TAP_LOG_COMPILER) $(AM_TAP_LOG_FLAGS) \
+ $(TAP_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/GraphicsMagick.spec.in \
+ $(srcdir)/Magick++/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/PerlMagick/Makefile.am $(srcdir)/coders/Makefile.am \
+ $(srcdir)/common.shi.in $(srcdir)/config/Makefile.am \
+ $(srcdir)/filters/Makefile.am $(srcdir)/magick/Makefile.am \
+ $(srcdir)/rungm.sh.in $(srcdir)/tests/Makefile.am \
+ $(srcdir)/utilities/Makefile.am $(srcdir)/wand/Makefile.am \
+ $(srcdir)/www/Makefile.am $(srcdir)/www/api/Makefile.am \
+ $(srcdir)/www/wand/Makefile.am \
+ $(top_srcdir)/Magick++/bin/GraphicsMagick++-config.in \
+ $(top_srcdir)/Magick++/lib/GraphicsMagick++.pc.in \
+ $(top_srcdir)/PerlMagick/Magick.pm.in \
+ $(top_srcdir)/PerlMagick/Makefile.PL.in \
+ $(top_srcdir)/PerlMagick/PerlMagickCheck.sh.in \
+ $(top_srcdir)/PerlMagick/t/features.pl.in \
+ $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \
+ $(top_srcdir)/config/config.sub \
+ $(top_srcdir)/config/delegates.mgk.in \
+ $(top_srcdir)/config/depcomp $(top_srcdir)/config/install-sh \
+ $(top_srcdir)/config/ltmain.sh $(top_srcdir)/config/missing \
+ $(top_srcdir)/config/tap-driver.sh \
+ $(top_srcdir)/config/test-driver \
+ $(top_srcdir)/config/type-ghostscript.mgk.in \
+ $(top_srcdir)/config/type-solaris.mgk.in \
+ $(top_srcdir)/config/type-windows.mgk.in \
+ $(top_srcdir)/config/type.mgk.in \
+ $(top_srcdir)/magick/GraphicsMagick-config.in \
+ $(top_srcdir)/magick/GraphicsMagick.pc.in \
+ $(top_srcdir)/magick/magick_config.h.in \
+ $(top_srcdir)/magick/magick_config_api.h.in \
+ $(top_srcdir)/magick/magick_types.h.in \
+ $(top_srcdir)/magick/version.h.in \
+ $(top_srcdir)/wand/GraphicsMagickWand-config.in \
+ $(top_srcdir)/wand/GraphicsMagickWand.pc.in ChangeLog \
+ config/compile config/config.guess config/config.sub \
+ config/depcomp config/install-sh config/ltmain.sh \
+ config/missing mkinstalldirs
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).tar.lz \
+ $(distdir).tar.xz
+GZIP_ENV = --best
+DIST_TARGETS = dist-lzip dist-xz dist-bzip2 dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BIN_DIR = @BIN_DIR@
+BrowseDelegate = @BrowseDelegate@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CGMDecodeDelegate = @CGMDecodeDelegate@
+CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+ConvertDelegate = @ConvertDelegate@
+DATA_DIR = @DATA_DIR@
+DCRAWDecodeDelegate = @DCRAWDecodeDelegate@
+DEFS = @DEFS@
+DELEGATES = @DELEGATES@
+DEPDIR = @DEPDIR@
+DIRSEP = @DIRSEP@
+DISTCHECK_CONFIG_FLAGS = @DISTCHECK_CONFIG_FLAGS@
+DLLTOOL = @DLLTOOL@
+DOC_DIR = @DOC_DIR@
+DOTDecodeDelegate = @DOTDecodeDelegate@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVIDecodeDelegate = @DVIDecodeDelegate@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEC_PREFIX_DIR = @EXEC_PREFIX_DIR@
+EXEEXT = @EXEEXT@
+EditorDelegate = @EditorDelegate@
+FGREP = @FGREP@
+FIGDecodeDelegate = @FIGDecodeDelegate@
+GMDelegate = @GMDelegate@
+GREP = @GREP@
+GSCMYKDevice = @GSCMYKDevice@
+GSColorAlphaDevice = @GSColorAlphaDevice@
+GSColorDevice = @GSColorDevice@
+GSEPSDevice = @GSEPSDevice@
+GSGrayDevice = @GSGrayDevice@
+GSMonoDevice = @GSMonoDevice@
+GSPDFDevice = @GSPDFDevice@
+GSPSDevice = @GSPSDevice@
+GSPaletteDevice = @GSPaletteDevice@
+GSVersion = @GSVersion@
+HG_BRANCH_TAG = @HG_BRANCH_TAG@
+HPGLDecodeDelegate = @HPGLDecodeDelegate@
+HTMLDecodeDelegate = @HTMLDecodeDelegate@
+HTML_DIR = @HTML_DIR@
+ILBMDecodeDelegate = @ILBMDecodeDelegate@
+ILBMEncodeDelegate = @ILBMEncodeDelegate@
+INCLUDE_DIR = @INCLUDE_DIR@
+INFO_DIR = @INFO_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INT16_T = @INT16_T@
+INT32_F = @INT32_F@
+INT32_T = @INT32_T@
+INT64_F = @INT64_F@
+INT64_T = @INT64_T@
+INT8_T = @INT8_T@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LFS_CPPFLAGS = @LFS_CPPFLAGS@
+LIBEXEC_DIR = @LIBEXEC_DIR@
+LIBOBJS = @LIBOBJS@
+LIBRARY_EXTRA_CPPFLAGS = @LIBRARY_EXTRA_CPPFLAGS@
+LIBS = @LIBS@
+LIBSTDCLDFLAGS = @LIBSTDCLDFLAGS@
+LIBTOOL = @LIBTOOL@
+
+# Automatically reconfigure libtool
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LIB_BZLIB = @LIB_BZLIB@
+LIB_DIR = @LIB_DIR@
+LIB_DL = @LIB_DL@
+LIB_DPS = @LIB_DPS@
+LIB_FPX = @LIB_FPX@
+LIB_GDI32 = @LIB_GDI32@
+LIB_GS = @LIB_GS@
+LIB_JBIG = @LIB_JBIG@
+LIB_JP2 = @LIB_JP2@
+LIB_JPEG = @LIB_JPEG@
+LIB_LCMS = @LIB_LCMS@
+LIB_LZMA = @LIB_LZMA@
+LIB_MATH = @LIB_MATH@
+LIB_OMP = @LIB_OMP@
+LIB_PNG = @LIB_PNG@
+LIB_THREAD = @LIB_THREAD@
+LIB_TIFF = @LIB_TIFF@
+LIB_TRIO = @LIB_TRIO@
+LIB_TTF = @LIB_TTF@
+LIB_UMEM = @LIB_UMEM@
+LIB_WEBP = @LIB_WEBP@
+LIB_WMF = @LIB_WMF@
+LIB_WMF_DEPS = @LIB_WMF_DEPS@
+LIB_X11 = @LIB_X11@
+LIB_XEXT = @LIB_XEXT@
+LIB_XML = @LIB_XML@
+LIB_XML_DEPS = @LIB_XML_DEPS@
+LIB_ZLIB = @LIB_ZLIB@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALSTATE_DIR = @LOCALSTATE_DIR@
+LPDelegate = @LPDelegate@
+LPRDelegate = @LPRDelegate@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LaunchDelegate = @LaunchDelegate@
+MAGICKLIB = @MAGICKLIB@
+MAGICKLIBDIR = @MAGICKLIBDIR@
+MAGICK_API_CFLAGS = @MAGICK_API_CFLAGS@
+MAGICK_API_CPPFLAGS = @MAGICK_API_CPPFLAGS@
+MAGICK_API_LDFLAGS = @MAGICK_API_LDFLAGS@
+MAGICK_API_LIBS = @MAGICK_API_LIBS@
+MAGICK_API_PC_CPPFLAGS = @MAGICK_API_PC_CPPFLAGS@
+MAGICK_CODER_MODULE_PATH = @MAGICK_CODER_MODULE_PATH@
+MAGICK_CONFIGURE_BUILD_PATH = @MAGICK_CONFIGURE_BUILD_PATH@
+MAGICK_CONFIGURE_SRC_PATH = @MAGICK_CONFIGURE_SRC_PATH@
+MAGICK_DEP_LIBS = @MAGICK_DEP_LIBS@
+MAGICK_FEATURES = @MAGICK_FEATURES@
+MAGICK_FILTER_MODULE_PATH = @MAGICK_FILTER_MODULE_PATH@
+MAGICK_LIBRARY_AGE = @MAGICK_LIBRARY_AGE@
+MAGICK_LIBRARY_CURRENT = @MAGICK_LIBRARY_CURRENT@
+MAGICK_LIBRARY_REVISION = @MAGICK_LIBRARY_REVISION@
+MAGICK_LIB_INTERFACE_NEWEST = @MAGICK_LIB_INTERFACE_NEWEST@
+MAGICK_LIB_INTERFACE_OLDEST = @MAGICK_LIB_INTERFACE_OLDEST@
+MAGICK_LIB_VERSION = @MAGICK_LIB_VERSION@
+MAGICK_LIB_VERSION_NUMBER = @MAGICK_LIB_VERSION_NUMBER@
+MAGICK_LIB_VERSION_TEXT = @MAGICK_LIB_VERSION_TEXT@
+MAGICK_LT_RELEASE_OPTS = @MAGICK_LT_RELEASE_OPTS@
+MAGICK_PLUS_PLUS_LIBRARY_AGE = @MAGICK_PLUS_PLUS_LIBRARY_AGE@
+MAGICK_PLUS_PLUS_LIBRARY_CURRENT = @MAGICK_PLUS_PLUS_LIBRARY_CURRENT@
+MAGICK_PLUS_PLUS_LIBRARY_REVISION = @MAGICK_PLUS_PLUS_LIBRARY_REVISION@
+MAGICK_SIZE_T = @MAGICK_SIZE_T@
+MAGICK_SIZE_T_F = @MAGICK_SIZE_T_F@
+MAGICK_SSIZE_T = @MAGICK_SSIZE_T@
+MAGICK_SSIZE_T_F = @MAGICK_SSIZE_T_F@
+MAGICK_TARGET_CPU = @MAGICK_TARGET_CPU@
+MAGICK_TARGET_OS = @MAGICK_TARGET_OS@
+MAGICK_TARGET_VENDOR = @MAGICK_TARGET_VENDOR@
+MAGICK_WAND_LIBRARY_AGE = @MAGICK_WAND_LIBRARY_AGE@
+MAGICK_WAND_LIBRARY_CURRENT = @MAGICK_WAND_LIBRARY_CURRENT@
+MAGICK_WAND_LIBRARY_REVISION = @MAGICK_WAND_LIBRARY_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MAN_DIR = @MAN_DIR@
+MKDIR_P = @MKDIR_P@
+MODULE_EXTRA_CPPFLAGS = @MODULE_EXTRA_CPPFLAGS@
+MPEGDecodeDelegate = @MPEGDecodeDelegate@
+MPEGEncodeDelegate = @MPEGEncodeDelegate@
+MVDelegate = @MVDelegate@
+MagickBinPath = @MagickBinPath@
+MagickCoderModulesPath = @MagickCoderModulesPath@
+MagickFilterModulesPath = @MagickFilterModulesPath@
+MagickLibConfigPath = @MagickLibConfigPath@
+MagickLibPath = @MagickLibPath@
+MagickShareConfigPath = @MagickShareConfigPath@
+MagickSharePath = @MagickSharePath@
+MogrifyDelegate = @MogrifyDelegate@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OLDINCLUDE_DIR = @OLDINCLUDE_DIR@
+OPENMP_CFLAGS = @OPENMP_CFLAGS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+P7ZIP = @P7ZIP@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_CHANGE_DATE = @PACKAGE_CHANGE_DATE@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_RELEASE_DATE = @PACKAGE_RELEASE_DATE@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_ADDENDUM = @PACKAGE_VERSION_ADDENDUM@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PERLMAINCC = @PERLMAINCC@
+PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
+PERL_SUPPORTS_DESTDIR = @PERL_SUPPORTS_DESTDIR@
+PREFIX_DIR = @PREFIX_DIR@
+PSDelegate = @PSDelegate@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_CXX = @PTHREAD_CXX@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PrintDelegate = @PrintDelegate@
+QuantumDepth = @QuantumDepth@
+RANLIB = @RANLIB@
+RPM = @RPM@
+RST2HTML = @RST2HTML@
+SBIN_DIR = @SBIN_DIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHAREDSTATE_DIR = @SHAREDSTATE_DIR@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSCONF_DIR = @SYSCONF_DIR@
+ShowImageDelegate = @ShowImageDelegate@
+SysCtlDelegate = @SysCtlDelegate@
+TXT2HTML = @TXT2HTML@
+UINT16_T = @UINT16_T@
+UINT32_F = @UINT32_F@
+UINT32_T = @UINT32_T@
+UINT64_F = @UINT64_F@
+UINT64_T = @UINT64_T@
+UINT8_T = @UINT8_T@
+UINTMAX_F = @UINTMAX_F@
+UINTMAX_T = @UINTMAX_T@
+UINTPTR_F = @UINTPTR_F@
+UINTPTR_T = @UINTPTR_T@
+VERSION = @VERSION@
+WinPathScript = @WinPathScript@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ZIP = @ZIP@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+acx_pthread_config = @acx_pthread_config@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+freetype_config = @freetype_config@
+ghostscript_font_dir = @ghostscript_font_dir@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+type_include_files = @type_include_files@
+windows_font_dir = @windows_font_dir@
+xml2_config = @xml2_config@
+
+# Don't require all the GNU mandated files
+# Use XZ_OPT (a environment variable) to tune xz compression levels (e.g. XZ_OPT=-8e)
+# nostdinc
+AUTOMAKE_OPTIONS = 1.12 subdir-objects nostdinc color-tests parallel-tests dist-bzip2 dist-xz foreign dist-lzip
+topincludedir = @includedir@/GraphicsMagick
+
+# CPPFLAGS required by all C/C++ code
+AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
+ACLOCAL_AMFLAGS = -I m4
+MODULECOMMONFLAGS = -no-undefined -export-symbols-regex ".*" -shared -module -avoid-version
+MODULECOMMONCPPFLAGS = $(AM_CPPFLAGS)
+
+# Options to pass when running configure in the distcheck target.
+#
+# We want to preserve user-provided option variables so the same
+# compiler, headers, and libraries are used as for a normal build.
+DISTCHECK_CONFIGURE_FLAGS = $(DISTCHECK_CONFIG_FLAGS)
+CLEANFILES = \
+ $(MAGICKPP_CLEANFILES) \
+ $(UTILITIES_CLEANFILES) \
+ $(TESTS_CLEANFILES) \
+ $(WAND_CLEANFILES)
+
+
+# Binary scripts
+bin_SCRIPTS = \
+ $(MAGICK_BIN_SCRPTS) \
+ $(MAGICKPP_SCRPTS) \
+ $(WAND_BIN_SCRPTS)
+
+include_HEADERS =
+
+# Headers which are not installed but which are distributed
+noinst_HEADERS = \
+ $(MAGICK_NOINST_HDRS)
+
+@WIN32_NATIVE_BUILD_FALSE@SRCDIR = "$(srcdir)/"
+@WIN32_NATIVE_BUILD_TRUE@SRCDIR = '$(shell @WinPathScript@ $(srcdir)/)'
+
+# Run the tests with a proper shell detected at configure time.
+LOG_COMPILER = $(SHELL)
+SH_LOG_COMPILER = $(LOG_COMPILER)
+TAP_LOG_COMPILER = $(LOG_COMPILER)
+
+# Test extensions
+TEST_EXTENSIONS = .sh .tap
+
+# Tests with .tap extensions use the TAP protocol and TAP driver
+TAP_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
+ $(top_srcdir)/scripts/tap-driver.sh
+
+
+# Environment parameters to be used during tests
+TESTS_ENVIRONMENT = \
+ MAKE="$(MAKE)" \
+ MAKEFLAGS="$(MAKEFLAGS)" \
+ MEMCHECK="$(MEMCHECK)"
+
+
+# Be sure to list CHANGELOGS in reverse chronological order in case we
+# should want to concatenate them.
+CHANGELOGS = \
+ ChangeLog \
+ ChangeLog.2015 \
+ ChangeLog.2014 \
+ ChangeLog.2013 \
+ ChangeLog.2012 \
+ ChangeLog.2011 \
+ ChangeLog.2010 \
+ ChangeLog.2009 \
+ ChangeLog.2008 \
+ ChangeLog.2007 \
+ ChangeLog.2006 \
+ ChangeLog.2005 \
+ ChangeLog.2004 \
+ ChangeLog.2003 \
+ ChangeLog.2002 \
+ ChangeLog.2001
+
+TOP_EXTRA_DIST = \
+ $(CHANGELOGS) \
+ Copyright.txt \
+ NEWS.txt \
+ README.txt \
+ TODO.txt \
+ lndir.sh \
+ version.sh \
+ winpath.sh
+
+
+# Additional files to distribute
+EXTRA_DIST = \
+ $(TOP_EXTRA_DIST) \
+ $(CONFIG_EXTRA_DIST) \
+ $(MAGICK_EXTRA_DIST) \
+ $(MAGICKPP_EXTRA_DIST) \
+ $(TESTS_EXTRA_DIST) \
+ $(UTILITIES_EXTRA_DIST) \
+ $(WAND_EXTRA_DIST) \
+ $(WWWW_EXTRA_DIST) \
+ $(WWWAPI_EXTRA_DIST) \
+ $(WWWWANDAPI_EXTRA_DIST)
+
+lib_LTLIBRARIES = $(LIBMAGICK) $(LIBMAGICKPP) $(LIBWAND)
+check_SCRIPTS = \
+ $(PERLMAGICK_CHECKSCRIPTS)
+
+AM_LDFLAGS =
+noinst_LTLIBRARIES =
+EXTRA_LTLIBRARIES =
+BUILT_SOURCES =
+MOSTLYCLEANFILES =
+
+# Where architecture-independent configuration files get installed
+# (share/GraphicsMagick-version)
+configsharedir = $(MagickShareConfigPath)
+configshare_DATA = \
+ config/colors.mgk \
+ config/log.mgk \
+ config/modules.mgk
+
+
+# Where architecture-dependent configuration files get installed
+# (lib/GraphicsMagick-version)
+configlibdir = $(MagickLibConfigPath)
+configlib_DATA = \
+ config/delegates.mgk \
+ config/type-ghostscript.mgk \
+ config/type.mgk \
+ config/type-solaris.mgk \
+ config/type-windows.mgk
+
+CONFIG_EXTRA_DIST = \
+ config/colors.mgk \
+ config/delegates.mgk.in \
+ config/log.mgk \
+ config/modules.mgk \
+ config/type-ghostscript.mgk.in \
+ config/type-solaris.mgk.in \
+ config/type-windows.mgk.in \
+ config/type.mgk.in
+
+
+# Where coder modules get installed
+codersdir = $(MagickCoderModulesPath)
+@HasDPS_TRUE@MAGICK_DPS_MODULES = coders/dps.la
+@HasDPS_TRUE@MAGICK_DPS_SRCS = coders/dps.c
+@HasFPX_TRUE@MAGICK_FPX_MODULES = coders/fpx.la
+@HasFPX_TRUE@MAGICK_FPX_SRCS = coders/fpx.c
+@HasWINGDI32_TRUE@MAGICK_GDI32_MODULES = coders/clipboard.la coders/emf.la
+@HasWINGDI32_TRUE@MAGICK_GDI32_SRCS = coders/clipboard.c coders/emf.c
+@HasJBIG_TRUE@MAGICK_JBIG_MODULES = coders/jbig.la
+@HasJBIG_TRUE@MAGICK_JBIG_SRCS = coders/jbig.c
+@HasJPEG_TRUE@MAGICK_JPEG_MODULES = coders/jnx.la coders/jpeg.la
+@HasJPEG_TRUE@MAGICK_JPEG_SRCS = coders/jnx.c coders/jpeg.c
+@HasJP2_TRUE@MAGICK_JP2_MODULES = coders/jp2.la
+@HasJP2_TRUE@MAGICK_JP2_SRCS = coders/jp2.c
+@HasPNG_TRUE@MAGICK_PNG_MODULES = coders/png.la
+@HasPNG_TRUE@MAGICK_PNG_SRCS = coders/png.c
+@HasTIFF_TRUE@MAGICK_TIFF_MODULES = coders/ept.la coders/tiff.la
+@HasTIFF_TRUE@MAGICK_TIFF_SRCS = coders/ept.c coders/tiff.c
+@HasX11_TRUE@MAGICK_X11_CODER_MODULES = coders/x.la coders/xwd.la
+@HasX11_TRUE@MAGICK_X11_CODER_SRCS = coders/x.c coders/xwd.c
+@HasWEBP_TRUE@MAGICK_WEBP_MODULES = coders/webp.la
+@HasWEBP_TRUE@MAGICK_WEBP_SRCS = coders/webp.c
+@ENABLE_BROKEN_CODERS_TRUE@MAGICK_BROKEN_MODULES = coders/psd.la
+@ENABLE_BROKEN_CODERS_TRUE@MAGICK_BROKEN_SRCS = coders/psd.c
+MAGICK_CODER_CPPFLAGS = \
+ $(MODULECOMMONCPPFLAGS) \
+ $(MODULE_EXTRA_CPPFLAGS)
+
+MAGICK_CODER_SRCS = \
+ $(MAGICK_PNG_SRCS) \
+ coders/art.c \
+ coders/avs.c \
+ coders/bmp.c \
+ coders/cals.c \
+ coders/caption.c \
+ coders/cineon.c \
+ coders/cmyk.c \
+ coders/cut.c \
+ coders/dcm.c \
+ coders/dcraw.c \
+ coders/dib.c \
+ coders/dpx.c \
+ coders/fax.c \
+ coders/fits.c \
+ coders/gif.c \
+ coders/gradient.c \
+ coders/gray.c \
+ coders/histogram.c \
+ coders/hrz.c \
+ coders/html.c \
+ coders/icon.c \
+ coders/identity.c \
+ coders/info.c \
+ coders/label.c \
+ coders/locale.c \
+ coders/logo.c \
+ coders/mac.c \
+ coders/map.c \
+ coders/mat.c \
+ coders/matte.c \
+ coders/meta.c \
+ coders/miff.c \
+ coders/mono.c \
+ coders/mpc.c \
+ coders/mpeg.c \
+ coders/mpr.c \
+ coders/msl.c \
+ coders/mtv.c \
+ coders/mvg.c \
+ coders/null.c \
+ coders/otb.c \
+ coders/palm.c \
+ coders/pcd.c \
+ coders/pcl.c \
+ coders/pcx.c \
+ coders/pdb.c \
+ coders/pdf.c \
+ coders/pict.c \
+ coders/pix.c \
+ coders/plasma.c \
+ coders/pnm.c \
+ coders/preview.c \
+ coders/ps.c \
+ coders/ps2.c \
+ coders/ps3.c \
+ coders/pwp.c \
+ coders/rgb.c \
+ coders/rla.c \
+ coders/rle.c \
+ coders/sct.c \
+ coders/sfw.c \
+ coders/sgi.c \
+ coders/stegano.c \
+ coders/sun.c \
+ coders/svg.c \
+ coders/tga.c \
+ coders/tile.c \
+ coders/tim.c \
+ coders/topol.c \
+ coders/ttf.c \
+ coders/txt.c \
+ coders/uil.c \
+ coders/url.c \
+ coders/uyvy.c \
+ coders/vicar.c \
+ coders/vid.c \
+ coders/viff.c \
+ coders/wbmp.c \
+ coders/wmf.c \
+ coders/wpg.c \
+ coders/xbm.c \
+ coders/xc.c \
+ coders/xcf.c \
+ coders/xpm.c \
+ coders/yuv.c \
+ $(MAGICK_BROKEN_SRCS) \
+ $(MAGICK_DPS_SRCS) \
+ $(MAGICK_GDI32_SRCS) \
+ $(MAGICK_FPX_SRCS) \
+ $(MAGICK_JBIG_SRCS) \
+ $(MAGICK_JPEG_SRCS) \
+ $(MAGICK_JP2_SRCS) \
+ $(MAGICK_TIFF_SRCS) \
+ $(MAGICK_X11_CODER_SRCS) \
+ $(MAGICK_WEBP_SRCS)
+
+@WITH_MODULES_FALSE@coders_LTLIBRARIES =
+@WITH_MODULES_TRUE@coders_LTLIBRARIES = \
+@WITH_MODULES_TRUE@ coders/art.la \
+@WITH_MODULES_TRUE@ coders/avs.la \
+@WITH_MODULES_TRUE@ coders/bmp.la \
+@WITH_MODULES_TRUE@ coders/cals.la \
+@WITH_MODULES_TRUE@ coders/caption.la \
+@WITH_MODULES_TRUE@ coders/cineon.la \
+@WITH_MODULES_TRUE@ coders/cmyk.la \
+@WITH_MODULES_TRUE@ coders/cut.la \
+@WITH_MODULES_TRUE@ coders/dcm.la \
+@WITH_MODULES_TRUE@ coders/dcraw.la \
+@WITH_MODULES_TRUE@ coders/dib.la \
+@WITH_MODULES_TRUE@ coders/dpx.la \
+@WITH_MODULES_TRUE@ coders/fax.la \
+@WITH_MODULES_TRUE@ coders/fits.la \
+@WITH_MODULES_TRUE@ coders/gif.la \
+@WITH_MODULES_TRUE@ coders/gradient.la \
+@WITH_MODULES_TRUE@ coders/gray.la \
+@WITH_MODULES_TRUE@ coders/histogram.la \
+@WITH_MODULES_TRUE@ coders/hrz.la \
+@WITH_MODULES_TRUE@ coders/html.la \
+@WITH_MODULES_TRUE@ coders/icon.la \
+@WITH_MODULES_TRUE@ coders/identity.la \
+@WITH_MODULES_TRUE@ coders/info.la \
+@WITH_MODULES_TRUE@ coders/label.la \
+@WITH_MODULES_TRUE@ coders/locale.la \
+@WITH_MODULES_TRUE@ coders/logo.la \
+@WITH_MODULES_TRUE@ coders/mac.la \
+@WITH_MODULES_TRUE@ coders/map.la \
+@WITH_MODULES_TRUE@ coders/mat.la \
+@WITH_MODULES_TRUE@ coders/matte.la \
+@WITH_MODULES_TRUE@ coders/meta.la \
+@WITH_MODULES_TRUE@ coders/miff.la \
+@WITH_MODULES_TRUE@ coders/mono.la \
+@WITH_MODULES_TRUE@ coders/mpc.la \
+@WITH_MODULES_TRUE@ coders/mpeg.la \
+@WITH_MODULES_TRUE@ coders/mpr.la \
+@WITH_MODULES_TRUE@ coders/msl.la \
+@WITH_MODULES_TRUE@ coders/mtv.la \
+@WITH_MODULES_TRUE@ coders/mvg.la \
+@WITH_MODULES_TRUE@ coders/null.la \
+@WITH_MODULES_TRUE@ coders/otb.la \
+@WITH_MODULES_TRUE@ coders/palm.la \
+@WITH_MODULES_TRUE@ coders/pcd.la \
+@WITH_MODULES_TRUE@ coders/pcl.la \
+@WITH_MODULES_TRUE@ coders/pcx.la \
+@WITH_MODULES_TRUE@ coders/pdb.la \
+@WITH_MODULES_TRUE@ coders/pdf.la \
+@WITH_MODULES_TRUE@ coders/pict.la \
+@WITH_MODULES_TRUE@ coders/pix.la \
+@WITH_MODULES_TRUE@ coders/plasma.la \
+@WITH_MODULES_TRUE@ coders/pnm.la \
+@WITH_MODULES_TRUE@ coders/preview.la \
+@WITH_MODULES_TRUE@ coders/ps.la \
+@WITH_MODULES_TRUE@ coders/ps2.la \
+@WITH_MODULES_TRUE@ coders/ps3.la \
+@WITH_MODULES_TRUE@ coders/pwp.la \
+@WITH_MODULES_TRUE@ coders/rgb.la \
+@WITH_MODULES_TRUE@ coders/rla.la \
+@WITH_MODULES_TRUE@ coders/rle.la \
+@WITH_MODULES_TRUE@ coders/sct.la \
+@WITH_MODULES_TRUE@ coders/sfw.la \
+@WITH_MODULES_TRUE@ coders/sgi.la \
+@WITH_MODULES_TRUE@ coders/stegano.la \
+@WITH_MODULES_TRUE@ coders/sun.la \
+@WITH_MODULES_TRUE@ coders/svg.la \
+@WITH_MODULES_TRUE@ coders/tga.la \
+@WITH_MODULES_TRUE@ coders/tile.la \
+@WITH_MODULES_TRUE@ coders/tim.la \
+@WITH_MODULES_TRUE@ coders/topol.la \
+@WITH_MODULES_TRUE@ coders/ttf.la \
+@WITH_MODULES_TRUE@ coders/txt.la \
+@WITH_MODULES_TRUE@ coders/uil.la \
+@WITH_MODULES_TRUE@ coders/url.la \
+@WITH_MODULES_TRUE@ coders/uyvy.la \
+@WITH_MODULES_TRUE@ coders/vicar.la \
+@WITH_MODULES_TRUE@ coders/vid.la \
+@WITH_MODULES_TRUE@ coders/viff.la \
+@WITH_MODULES_TRUE@ coders/wbmp.la \
+@WITH_MODULES_TRUE@ coders/wmf.la \
+@WITH_MODULES_TRUE@ coders/wpg.la \
+@WITH_MODULES_TRUE@ coders/xbm.la \
+@WITH_MODULES_TRUE@ coders/xc.la \
+@WITH_MODULES_TRUE@ coders/xcf.la \
+@WITH_MODULES_TRUE@ coders/xpm.la \
+@WITH_MODULES_TRUE@ coders/yuv.la \
+@WITH_MODULES_TRUE@ $(MAGICK_BROKEN_MODULES) \
+@WITH_MODULES_TRUE@ $(MAGICK_DPS_MODULES) $(MAGICK_FPX_MODULES) $(MAGICK_GDI32_MODULES) \
+@WITH_MODULES_TRUE@ $(MAGICK_JBIG_MODULES) $(MAGICK_JPEG_MODULES) $(MAGICK_JP2_MODULES) \
+@WITH_MODULES_TRUE@ $(MAGICK_PNG_MODULES) $(MAGICK_TIFF_MODULES) $(MAGICK_X11_CODER_MODULES) \
+@WITH_MODULES_TRUE@ $(MAGICK_WEBP_MODULES)
+
+
+# ART coder module
+coders_art_la_SOURCES = coders/art.c
+coders_art_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_art_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_art_la_LIBADD = $(LIBMAGICK)
+
+# AVS coder module
+coders_avs_la_SOURCES = coders/avs.c
+coders_avs_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_avs_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_avs_la_LIBADD = $(LIBMAGICK)
+
+# BMP coder module
+coders_bmp_la_SOURCES = coders/bmp.c
+coders_bmp_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_bmp_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_bmp_la_LIBADD = $(LIBMAGICK)
+
+# CALS coder module
+coders_cals_la_SOURCES = coders/cals.c
+coders_cals_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_cals_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_cals_la_LIBADD = $(LIBMAGICK)
+
+# CAPTION coder module
+coders_caption_la_SOURCES = coders/caption.c
+coders_caption_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_caption_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_caption_la_LIBADD = $(LIBMAGICK)
+
+# CINEON coder module
+coders_cineon_la_SOURCES = coders/cineon.c
+coders_cineon_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_cineon_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_cineon_la_LIBADD = $(LIBMAGICK)
+
+# CLIPBOARD coder module
+coders_clipboard_la_SOURCES = coders/clipboard.c
+coders_clipboard_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_clipboard_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_clipboard_la_LIBADD = $(LIBMAGICK) $(LIB_GDI32)
+
+# CMYK coder module
+coders_cmyk_la_SOURCES = coders/cmyk.c
+coders_cmyk_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_cmyk_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_cmyk_la_LIBADD = $(LIBMAGICK)
+
+# CUT coder module
+coders_cut_la_SOURCES = coders/cut.c
+coders_cut_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_cut_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_cut_la_LIBADD = $(LIBMAGICK)
+
+# DCM coder module
+coders_dcm_la_SOURCES = coders/dcm.c
+coders_dcm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dcm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dcm_la_LIBADD = $(LIBMAGICK)
+
+# DCRAW coder module
+coders_dcraw_la_SOURCES = coders/dcraw.c
+coders_dcraw_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dcraw_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dcraw_la_LIBADD = $(LIBMAGICK)
+
+# DIB coder module
+coders_dib_la_SOURCES = coders/dib.c
+coders_dib_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dib_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dib_la_LIBADD = $(LIBMAGICK)
+
+# DPS coder module
+coders_dps_la_SOURCES = coders/dps.c
+coders_dps_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dps_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dps_la_LIBADD = $(LIBMAGICK) $(LIB_DPS) $(LIB_XEXT) $(LIB_X11)
+
+# DPX coder module
+coders_dpx_la_SOURCES = coders/dpx.c
+coders_dpx_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dpx_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dpx_la_LIBADD = $(LIBMAGICK)
+
+# EMF coder module
+coders_emf_la_SOURCES = coders/emf.c
+coders_emf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_emf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_emf_la_LIBADD = $(LIBMAGICK) $(LIB_GDI32)
+
+# EPT coder module
+coders_ept_la_SOURCES = coders/ept.c
+coders_epd_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ept_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ept_la_LIBADD = $(LIBMAGICK) $(LIB_GS) $(LIB_MATH)
+
+# FAX coder module
+coders_fax_la_SOURCES = coders/fax.c
+coders_fax_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_fax_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_fax_la_LIBADD = $(LIBMAGICK)
+
+# FITS coder module
+coders_fits_la_SOURCES = coders/fits.c
+coders_fits_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_fits_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_fits_la_LIBADD = $(LIBMAGICK) $(LIB_MATH)
+
+# FPX coder module
+coders_fpx_la_SOURCES = coders/fpx.c
+coders_fpx_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_fpx_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_fpx_la_LIBADD = $(LIBMAGICK) $(LIB_FPX)
+
+# GIF coder module
+coders_gif_la_SOURCES = coders/gif.c
+coders_gif_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_gif_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_gif_la_LIBADD = $(LIBMAGICK)
+
+# GRAY coder module
+coders_gray_la_SOURCES = coders/gray.c
+coders_gray_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_gray_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_gray_la_LIBADD = $(LIBMAGICK)
+
+# GRADIENT coder module
+coders_gradient_la_SOURCES = coders/gradient.c
+coders_gradient_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_gradient_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_gradient_la_LIBADD = $(LIBMAGICK)
+
+# HISTOGRAM coder module
+coders_histogram_la_SOURCES = coders/histogram.c
+coders_histogram_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_histogram_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_histogram_la_LIBADD = $(LIBMAGICK)
+
+# HRZ coder module
+coders_hrz_la_SOURCES = coders/hrz.c
+coders_hrz_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_hrz_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_hrz_la_LIBADD = $(LIBMAGICK)
+
+# HTML coder module
+coders_html_la_SOURCES = coders/html.c
+coders_html_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_html_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_html_la_LIBADD = $(LIBMAGICK)
+
+# ICON coder module
+coders_icon_la_SOURCES = coders/icon.c
+coders_icon_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_icon_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_icon_la_LIBADD = $(LIBMAGICK)
+
+# Identity coder module
+coders_identity_la_SOURCES = coders/identity.c
+coders_identity_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_identity_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_identity_la_LIBADD = $(LIBMAGICK)
+
+# Info coder module
+coders_info_la_SOURCES = coders/info.c
+coders_info_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_info_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_info_la_LIBADD = $(LIBMAGICK)
+
+# JBIG coder module
+coders_jbig_la_SOURCES = coders/jbig.c
+coders_jbig_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_jbig_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_jbig_la_LIBADD = $(LIBMAGICK) $(LIB_JBIG)
+
+# JNX coder module
+coders_jnx_la_SOURCES = coders/jnx.c
+coders_jnx_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_jnx_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_jnx_la_LIBADD = $(LIBMAGICK) $(LIB_JPEG)
+
+# JPEG coder module
+coders_jpeg_la_SOURCES = coders/jpeg.c
+coders_jpeg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_jpeg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_jpeg_la_LIBADD = $(LIBMAGICK) $(LIB_JPEG)
+
+# JPEG 2000 coder module
+coders_jp2_la_SOURCES = coders/jp2.c
+coders_jp2_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_jp2_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_jp2_la_LIBADD = $(LIBMAGICK) $(LIB_JP2) $(LIB_JPEG) $(LIB_MATH)
+
+# LABEL coder module
+coders_label_la_SOURCES = coders/label.c
+coders_label_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_label_la_LDFLAGS = $(MODULECOMMONFLAGS) $(LIB_MATH)
+coders_label_la_LIBADD = $(LIBMAGICK)
+
+# LOCALE coder module
+coders_locale_la_SOURCES = coders/locale.c
+coders_locale_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_locale_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_locale_la_LIBADD = $(LIBMAGICK)
+
+# LOGO coder module
+coders_logo_la_SOURCES = coders/logo.c
+coders_logo_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_logo_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_logo_la_LIBADD = $(LIBMAGICK)
+
+# MAC coder module
+coders_mac_la_SOURCES = coders/mac.c
+coders_mac_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mac_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mac_la_LIBADD = $(LIBMAGICK)
+
+# MAP coder module
+coders_map_la_SOURCES = coders/map.c
+coders_map_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_map_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_map_la_LIBADD = $(LIBMAGICK)
+
+# MAT coder module
+coders_mat_la_SOURCES = coders/mat.c
+coders_mat_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mat_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mat_la_LIBADD = $(LIBMAGICK) $(LIB_ZLIB) $(LIB_MATH)
+
+# MATTE coder module
+coders_matte_la_SOURCES = coders/matte.c
+coders_matte_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_matte_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_matte_la_LIBADD = $(LIBMAGICK)
+
+# META coder module
+coders_meta_la_SOURCES = coders/meta.c
+coders_meta_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_meta_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_meta_la_LIBADD = $(LIBMAGICK)
+
+# MIFF coder module
+coders_miff_la_SOURCES = coders/miff.c
+coders_miff_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_miff_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_miff_la_LIBADD = $(LIBMAGICK) $(LIB_ZLIB) $(LIB_BZLIB)
+
+# MONO coder module
+coders_mono_la_SOURCES = coders/mono.c
+coders_mono_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mono_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mono_la_LIBADD = $(LIBMAGICK)
+
+# MPC coder module
+coders_mpc_la_SOURCES = coders/mpc.c
+coders_mpc_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mpc_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mpc_la_LIBADD = $(LIBMAGICK)
+
+# MPEG coder module
+coders_mpeg_la_SOURCES = coders/mpeg.c
+coders_mpeg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mpeg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mpeg_la_LIBADD = $(LIBMAGICK)
+
+# MPR coder module
+coders_mpr_la_SOURCES = coders/mpr.c
+coders_mpr_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mpr_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mpr_la_LIBADD = $(LIBMAGICK)
+
+# MSL coder module
+coders_msl_la_SOURCES = coders/msl.c
+coders_msl_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_msl_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_msl_la_LIBADD = $(LIBMAGICK) $(LIB_XML) $(LIB_XML_DEPS)
+
+# MTV coder module
+coders_mtv_la_SOURCES = coders/mtv.c
+coders_mtv_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mtv_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mtv_la_LIBADD = $(LIBMAGICK)
+
+# MVG coder module
+coders_mvg_la_SOURCES = coders/mvg.c
+coders_mvg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mvg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mvg_la_LIBADD = $(LIBMAGICK)
+
+# NULL coder module
+coders_null_la_SOURCES = coders/null.c
+coders_null_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_null_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_null_la_LIBADD = $(LIBMAGICK)
+
+# OTB coder module
+coders_otb_la_SOURCES = coders/otb.c
+coders_otb_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_otb_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_otb_la_LIBADD = $(LIBMAGICK)
+
+# PALM coder module
+coders_palm_la_SOURCES = coders/palm.c
+coders_palm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_palm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_palm_la_LIBADD = $(LIBMAGICK)
+
+# PCD coder module
+coders_pcd_la_SOURCES = coders/pcd.c
+coders_pcd_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pcd_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pcd_la_LIBADD = $(LIBMAGICK)
+
+# PCL coder module
+coders_pcl_la_SOURCES = coders/pcl.c
+coders_pcl_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pcl_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pcl_la_LIBADD = $(LIBMAGICK)
+
+# PCX coder module
+coders_pcx_la_SOURCES = coders/pcx.c
+coders_pcx_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pcx_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pcx_la_LIBADD = $(LIBMAGICK)
+
+# PDB coder module
+coders_pdb_la_SOURCES = coders/pdb.c
+coders_pdb_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pdb_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pdb_la_LIBADD = $(LIBMAGICK)
+
+# PDF coder module
+coders_pdf_la_SOURCES = coders/pdf.c
+coders_pdf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pdf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pdf_la_LIBADD = $(LIBMAGICK) $(LIB_ZLIB) $(LIB_GS)
+
+# PICT coder module
+coders_pict_la_SOURCES = coders/pict.c
+coders_pict_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pict_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pict_la_LIBADD = $(LIBMAGICK)
+
+# PIX coder module
+coders_pix_la_SOURCES = coders/pix.c
+coders_pix_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pix_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pix_la_LIBADD = $(LIBMAGICK)
+
+# PNG coder module
+coders_png_la_SOURCES = coders/png.c
+coders_png_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_png_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_png_la_LIBADD = $(LIBMAGICK) $(LIB_PNG) $(LIB_JPEG) $(LIB_ZLIB) $(LIB_MATH)
+
+# PLASMA coder module
+coders_plasma_la_SOURCES = coders/plasma.c
+coders_plasma_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_plasma_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_plasma_la_LIBADD = $(LIBMAGICK)
+
+# PNM coder module
+coders_pnm_la_SOURCES = coders/pnm.c
+coders_pnm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pnm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pnm_la_LIBADD = $(LIBMAGICK)
+
+# PREVIEW coder module
+coders_preview_la_SOURCES = coders/preview.c
+coders_preview_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_preview_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_preview_la_LIBADD = $(LIBMAGICK)
+
+# PS coder module
+coders_ps_la_SOURCES = coders/ps.c
+coders_ps_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ps_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ps_la_LIBADD = $(LIBMAGICK) $(LIB_GS) $(LIB_MATH)
+
+# PS2 coder module
+coders_ps2_la_SOURCES = coders/ps2.c
+coders_ps2_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ps2_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ps2_la_LIBADD = $(LIBMAGICK) $(LIB_TIFF) $(LIB_JBIG) $(LIB_JPEG) $(LIB_LZMA) $(LIB_ZLIB) $(LIB_MATH)
+
+# PS3 coder module
+coders_ps3_la_SOURCES = coders/ps3.c
+coders_ps3_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ps3_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ps3_la_LIBADD = $(LIBMAGICK) $(LIB_TIFF) $(LIB_JBIG) $(LIB_JPEG) $(LIB_LZMA) $(LIB_ZLIB) $(LIB_MATH)
+
+# PSD coder module
+coders_psd_la_SOURCES = coders/psd.c
+coders_psd_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_psd_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_psd_la_LIBADD = $(LIBMAGICK)
+
+# PWP coder module
+coders_pwp_la_SOURCES = coders/pwp.c
+coders_pwp_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pwp_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pwp_la_LIBADD = $(LIBMAGICK)
+
+# RGB coder module
+coders_rgb_la_SOURCES = coders/rgb.c
+coders_rgb_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_rgb_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_rgb_la_LIBADD = $(LIBMAGICK)
+
+# RLA coder module
+coders_rla_la_SOURCES = coders/rla.c
+coders_rla_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_rla_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_rla_la_LIBADD = $(LIBMAGICK)
+
+# RLE coder module
+coders_rle_la_SOURCES = coders/rle.c
+coders_rle_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_rle_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_rle_la_LIBADD = $(LIBMAGICK)
+
+# SCT coder module
+coders_sct_la_SOURCES = coders/sct.c
+coders_sct_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_sct_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_sct_la_LIBADD = $(LIBMAGICK)
+
+# SFW coder module
+coders_sfw_la_SOURCES = coders/sfw.c
+coders_sfw_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_sfw_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_sfw_la_LIBADD = $(LIBMAGICK)
+
+# SGI coder module
+coders_sgi_la_SOURCES = coders/sgi.c
+coders_sgi_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_sgi_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_sgi_la_LIBADD = $(LIBMAGICK)
+
+# STEGANO coder module
+coders_stegano_la_SOURCES = coders/stegano.c
+coders_stegano_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_stegano_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_stegano_la_LIBADD = $(LIBMAGICK)
+
+# SUN coder module
+coders_sun_la_SOURCES = coders/sun.c
+coders_sun_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_sun_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_sun_la_LIBADD = $(LIBMAGICK)
+
+# SVG coder module
+coders_svg_la_SOURCES = coders/svg.c
+coders_svg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_svg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_svg_la_LIBADD = $(LIBMAGICK) $(LIB_XML) $(LIB_XML_DEPS)
+
+# TGA coder module
+coders_tga_la_SOURCES = coders/tga.c
+coders_tga_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_tga_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_tga_la_LIBADD = $(LIBMAGICK)
+
+# TIFF coder module
+coders_tiff_la_SOURCES = coders/tiff.c
+coders_tiff_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_tiff_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_tiff_la_LIBADD = $(LIBMAGICK) $(LIB_TIFF) $(LIB_JBIG) $(LIB_JPEG) $(LIB_LZMA) $(LIB_ZLIB) $(LIB_MATH)
+
+# TILE coder module
+coders_tile_la_SOURCES = coders/tile.c
+coders_tile_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_tile_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_tile_la_LIBADD = $(LIBMAGICK)
+
+# TIM coder module
+coders_tim_la_SOURCES = coders/tim.c
+coders_tim_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_tim_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_tim_la_LIBADD = $(LIBMAGICK)
+
+# TOPOL coder module
+coders_topol_la_SOURCES = coders/topol.c
+coders_topol_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_topol_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_topol_la_LIBADD = $(LIBMAGICK)
+
+# TTF coder module
+coders_ttf_la_SOURCES = coders/ttf.c
+coders_ttf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ttf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ttf_la_LIBADD = $(LIBMAGICK)
+
+# TXT coder module
+coders_txt_la_SOURCES = coders/txt.c
+coders_txt_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_txt_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_txt_la_LIBADD = $(LIBMAGICK) $(LIB_MATH)
+
+# UIL coder module
+coders_uil_la_SOURCES = coders/uil.c
+coders_uil_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_uil_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_uil_la_LIBADD = $(LIBMAGICK)
+
+# URL coder module
+coders_url_la_SOURCES = coders/url.c
+coders_url_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_url_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_url_la_LIBADD = $(LIBMAGICK) $(LIB_XML) $(LIB_XML_DEPS)
+
+# UYVY coder module
+coders_uyvy_la_SOURCES = coders/uyvy.c
+coders_uyvy_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_uyvy_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_uyvy_la_LIBADD = $(LIBMAGICK)
+
+# VICAR coder module
+coders_vicar_la_SOURCES = coders/vicar.c
+coders_vicar_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_vicar_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_vicar_la_LIBADD = $(LIBMAGICK)
+
+# VID coder module
+coders_vid_la_SOURCES = coders/vid.c
+coders_vid_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_vid_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_vid_la_LIBADD = $(LIBMAGICK)
+
+# VIFF coder module
+coders_viff_la_SOURCES = coders/viff.c
+coders_viff_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_viff_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_viff_la_LIBADD = $(LIBMAGICK)
+
+# WBMP coder module
+coders_wbmp_la_SOURCES = coders/wbmp.c
+coders_wbmp_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_wbmp_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_wbmp_la_LIBADD = $(LIBMAGICK)
+
+# WMF coder module
+coders_wmf_la_SOURCES = coders/wmf.c
+coders_wmf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_wmf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_wmf_la_LIBADD = $(LIBMAGICK) $(LIB_WMF) $(LIB_WMF_DEPS) $(LIB_MATH)
+
+# WPG coder module
+coders_wpg_la_SOURCES = coders/wpg.c
+coders_wpg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_wpg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_wpg_la_LIBADD = $(LIBMAGICK)
+
+# X coder module
+coders_x_la_SOURCES = coders/x.c
+coders_x_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_x_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_x_la_LIBADD = $(LIBMAGICK) $(LIB_X11)
+
+# XBM coder module
+coders_xbm_la_SOURCES = coders/xbm.c
+coders_xbm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xbm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xbm_la_LIBADD = $(LIBMAGICK)
+
+# XC coder module
+coders_xc_la_SOURCES = coders/xc.c
+coders_xc_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xc_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xc_la_LIBADD = $(LIBMAGICK)
+
+# XCF coder module
+coders_xcf_la_SOURCES = coders/xcf.c
+coders_xcf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xcf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xcf_la_LIBADD = $(LIBMAGICK)
+
+# XPM coder module
+coders_xpm_la_SOURCES = coders/xpm.c
+coders_xpm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xpm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xpm_la_LIBADD = $(LIBMAGICK)
+
+# XWD coder module
+coders_xwd_la_SOURCES = coders/xwd.c
+coders_xwd_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xwd_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xwd_la_LIBADD = $(LIBMAGICK) $(LIB_X11)
+
+# YUV coder module
+coders_yuv_la_SOURCES = coders/yuv.c
+coders_yuv_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_yuv_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_yuv_la_LIBADD = $(LIBMAGICK)
+
+# WEBP coder module
+coders_webp_la_SOURCES = coders/webp.c
+coders_webp_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_webp_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_webp_la_LIBADD = $(LIBMAGICK) $(LIB_WEBP)
+magickincdir = $(topincludedir)/magick
+
+# Headers which are installed
+magickinc_HEADERS = \
+ $(MAGICK_INCLUDE_HDRS)
+
+MAGICK_BIN_SCRPTS = \
+ magick/GraphicsMagick-config
+
+MAGICK_PKGCONFIG = \
+ magick/GraphicsMagick.pc
+
+MAGICK_MANS = \
+ magick/GraphicsMagick-config.1
+
+LIBMAGICK = magick/libGraphicsMagick.la
+@WITH_MODULES_FALSE@magick_libGraphicsMagick_la_SOURCES = $(MAGICK_BASE_SRCS) $(MAGICK_PLATFORM_SRCS) $(MAGICK_CODER_SRCS) $(MAGICK_FILTER_SRCS)
+@WITH_MODULES_TRUE@magick_libGraphicsMagick_la_SOURCES = $(MAGICK_BASE_SRCS) $(MAGICK_PLATFORM_SRCS)
+@WITH_MODULES_FALSE@magick_libGraphicsMagick_la_LIBADD = $(MAGICK_DEP_LIBS)
+@WITH_MODULES_TRUE@magick_libGraphicsMagick_la_LIBADD = $(MAGICK_DEP_LIBS)
+magick_libGraphicsMagick_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBRARY_EXTRA_CPPFLAGS)
+magick_libGraphicsMagick_la_LDFLAGS = \
+ -no-undefined -export-symbols-regex ".*" \
+ $(MAGICK_LT_RELEASE_OPTS) \
+ -version-info $(MAGICK_LIBRARY_CURRENT):$(MAGICK_LIBRARY_REVISION):$(MAGICK_LIBRARY_AGE)
+
+#magick_libGraphicsMagick_la_DEPENDENCIES =
+@HasX11_TRUE@MAGICK_X11_BASE_SRCS = \
+@HasX11_TRUE@ magick/animate.c \
+@HasX11_TRUE@ magick/animate.h \
+@HasX11_TRUE@ magick/display.c \
+@HasX11_TRUE@ magick/display.h \
+@HasX11_TRUE@ magick/PreRvIcccm.c \
+@HasX11_TRUE@ magick/PreRvIcccm.h \
+@HasX11_TRUE@ magick/widget.c \
+@HasX11_TRUE@ magick/widget.h \
+@HasX11_TRUE@ magick/xwindow.c \
+@HasX11_TRUE@ magick/xwindow.h
+
+
+# Library base sources
+MAGICK_BASE_SRCS = \
+ magick/alpha_composite.h \
+ magick/analyze.c \
+ magick/analyze.h \
+ magick/annotate.c \
+ magick/api.h \
+ magick/attribute.c \
+ magick/attribute.h \
+ magick/average.c \
+ magick/average.h \
+ magick/bit_stream.c \
+ magick/bit_stream.h \
+ magick/blob.c \
+ magick/blob.h \
+ magick/cdl.c \
+ magick/cdl.h \
+ magick/channel.c \
+ magick/channel.h \
+ magick/common.h \
+ magick/compare.c \
+ magick/compare.h \
+ magick/confirm_access.c \
+ magick/confirm_access.h \
+ magick/color.c \
+ magick/color.h \
+ magick/color_lookup.c \
+ magick/color_lookup.h \
+ magick/colormap.c \
+ magick/colormap.h \
+ magick/colorspace.c \
+ magick/colorspace.h \
+ magick/command.c \
+ magick/command.h \
+ magick/composite.c \
+ magick/composite.h \
+ magick/compress.c \
+ magick/compress.h \
+ magick/constitute.c \
+ magick/constitute.h \
+ magick/decorate.c \
+ magick/decorate.h \
+ magick/delegate.c \
+ magick/delegate.h \
+ magick/deprecate.c \
+ magick/deprecate.h \
+ magick/describe.c \
+ magick/describe.h \
+ magick/draw.c \
+ magick/draw.h \
+ magick/effect.c \
+ magick/effect.h \
+ magick/enhance.c \
+ magick/enhance.h \
+ magick/enum_strings.c \
+ magick/enum_strings.h \
+ magick/error.c \
+ magick/error.h \
+ magick/export.c \
+ magick/floats.c \
+ magick/floats.h \
+ magick/forward.h \
+ magick/fx.c \
+ magick/fx.h \
+ magick/gem.c \
+ magick/gem.h \
+ magick/gradient.c \
+ magick/gradient.h \
+ magick/hclut.c \
+ magick/hclut.h \
+ magick/image.c \
+ magick/image.h \
+ magick/import.c \
+ magick/list.c \
+ magick/list.h \
+ magick/locale.c \
+ magick/locale_c.h \
+ magick/log.c \
+ magick/log.h \
+ magick/magic.c \
+ magick/magic.h \
+ magick/magick.c \
+ magick/magick.h \
+ magick/magick_endian.c \
+ magick/magick_endian.h \
+ magick/map.c \
+ magick/map.h \
+ magick/memory.c \
+ magick/memory.h \
+ magick/module.c \
+ magick/module.h \
+ magick/monitor.c \
+ magick/monitor.h \
+ magick/montage.c \
+ magick/montage.h \
+ magick/omp_data_view.c \
+ magick/omp_data_view.h \
+ magick/operator.c \
+ magick/operator.h \
+ magick/paint.c \
+ magick/paint.h \
+ magick/pixel_cache.h \
+ magick/pixel_cache.c \
+ magick/pixel_iterator.c \
+ magick/pixel_iterator.h \
+ magick/plasma.c \
+ magick/plasma.h \
+ magick/prefetch.h \
+ magick/profile.c \
+ magick/profile.h \
+ magick/quantize.c \
+ magick/quantize.h \
+ magick/registry.c \
+ magick/registry.h \
+ magick/random.c \
+ magick/random.h \
+ magick/render.c \
+ magick/render.h \
+ magick/resize.c \
+ magick/resize.h \
+ magick/resource.c \
+ magick/resource.h \
+ magick/segment.c \
+ magick/semaphore.c \
+ magick/semaphore.h \
+ magick/shear.c \
+ magick/shear.h \
+ magick/signature.c \
+ magick/signature.h \
+ magick/spinlock.h \
+ magick/static.c \
+ magick/static.h \
+ magick/statistics.c \
+ magick/statistics.h \
+ magick/studio.h \
+ magick/symbols.h \
+ magick/tempfile.c \
+ magick/tempfile.h \
+ magick/texture.c \
+ magick/texture.h \
+ magick/timer.c \
+ magick/timer.h \
+ magick/transform.c \
+ magick/transform.h \
+ magick/tsd.c \
+ magick/tsd.h \
+ magick/type.c \
+ magick/type.h \
+ magick/unix_port.c \
+ magick/utility.c \
+ magick/utility.h \
+ magick/version.c \
+ magick/version.h \
+ $(MAGICK_X11_BASE_SRCS)
+
+@CYGWIN_BUILD_FALSE@@WIN32_NATIVE_BUILD_FALSE@MAGICK_PLATFORM_SRCS =
+@CYGWIN_BUILD_TRUE@@WIN32_NATIVE_BUILD_FALSE@MAGICK_PLATFORM_SRCS = \
+@CYGWIN_BUILD_TRUE@@WIN32_NATIVE_BUILD_FALSE@ magick/nt_feature.c \
+@CYGWIN_BUILD_TRUE@@WIN32_NATIVE_BUILD_FALSE@ magick/nt_feature.h
+
+@WIN32_NATIVE_BUILD_TRUE@MAGICK_PLATFORM_SRCS = \
+@WIN32_NATIVE_BUILD_TRUE@ magick/nt_base.c \
+@WIN32_NATIVE_BUILD_TRUE@ magick/nt_base.h \
+@WIN32_NATIVE_BUILD_TRUE@ magick/nt_feature.c \
+@WIN32_NATIVE_BUILD_TRUE@ magick/nt_feature.h
+
+MAGICK_INCLUDE_HDRS = \
+ magick/api.h \
+ magick/analyze.h \
+ magick/attribute.h \
+ magick/average.h \
+ magick/blob.h \
+ magick/cdl.h \
+ magick/channel.h \
+ magick/color.h \
+ magick/color_lookup.h \
+ magick/colormap.h \
+ magick/colorspace.h \
+ magick/command.h \
+ magick/common.h \
+ magick/compare.h \
+ magick/composite.h \
+ magick/compress.h \
+ magick/confirm_access.h \
+ magick/constitute.h \
+ magick/decorate.h \
+ magick/delegate.h \
+ magick/describe.h \
+ magick/deprecate.h \
+ magick/draw.h \
+ magick/effect.h \
+ magick/enhance.h \
+ magick/error.h \
+ magick/forward.h \
+ magick/fx.h \
+ magick/gem.h \
+ magick/gradient.h \
+ magick/hclut.h \
+ magick/image.h \
+ magick/list.h \
+ magick/log.h \
+ magick/magic.h \
+ magick/magick.h \
+ magick/magick_types.h \
+ magick/memory.h \
+ magick/module.h \
+ magick/monitor.h \
+ magick/montage.h \
+ magick/operator.h \
+ magick/paint.h \
+ magick/pixel_cache.h \
+ magick/pixel_iterator.h \
+ magick/plasma.h \
+ magick/profile.h \
+ magick/quantize.h \
+ magick/random.h \
+ magick/registry.h \
+ magick/render.h \
+ magick/resize.h \
+ magick/resource.h \
+ magick/shear.h \
+ magick/signature.h \
+ magick/statistics.h \
+ magick/symbols.h \
+ magick/texture.h \
+ magick/timer.h \
+ magick/transform.h \
+ magick/type.h \
+ magick/utility.h \
+ magick/version.h
+
+MAGICK_NOINST_HDRS = \
+ magick/alpha_composite.h \
+ magick/animate.h \
+ magick/bit_stream.h \
+ magick/display.h \
+ magick/floats.h \
+ magick/locale_c.h \
+ magick/map.h \
+ magick/nt_base.h \
+ magick/nt_feature.h \
+ magick/omp_data_view.h \
+ magick/prefetch.h \
+ magick/random-private.h \
+ magick/semaphore.h \
+ magick/spinlock.h \
+ magick/static.h \
+ magick/studio.h \
+ magick/tempfile.h \
+ magick/unix_port.h \
+ magick/widget.h \
+ magick/xwindow.h
+
+MAGICK_EXTRA_DIST = \
+ magick/GraphicsMagick-config.in \
+ $(MAGICK_MANS) \
+ magick/GraphicsMagick.pc.in \
+ magick/nt_base.c \
+ magick/nt_feature.c
+
+
+# Install magick_config_api.h as magick_config.h
+MAGICK_INSTALL_DATA_LOCAL_TARGETS = magick-install-data-local
+
+# Uninstall magick_config.h
+MAGICK_UNINSTALL_LOCAL_TARGETS = magick-uninstall-local
+
+# Where filter modules get installed
+filtersdir = $(MagickFilterModulesPath)
+MAGICK_FILTER_CPPFLAGS = $(AM_CPPFLAGS)
+MAGICK_FILTER_SRCS = \
+ filters/analyze.c
+
+@WITH_MODULES_FALSE@filters_LTLIBRARIES =
+@WITH_MODULES_TRUE@filters_LTLIBRARIES = \
+@WITH_MODULES_TRUE@ filters/analyze.la
+
+filters_CPPFLAGS = $(MAGICK_FILTER_CPPFLAGS)
+
+# Analyze filter module
+filters_analyze_la_SOURCES = filters/analyze.c
+filters_analyze_la_CPPFLAGS = $(MAGICK_FILTER_CPPFLAGS)
+filters_analyze_la_LDFLAGS = $(MODULECOMMONFLAGS)
+filters_analyze_la_LIBADD = $(LIBMAGICK)
+MAGICKPP_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/Magick++/lib
+@WITH_MAGICK_PLUS_PLUS_FALSE@LIBMAGICKPP =
+@WITH_MAGICK_PLUS_PLUS_TRUE@LIBMAGICKPP = Magick++/lib/libGraphicsMagick++.la
+@WITH_MAGICK_PLUS_PLUS_FALSE@MAGICKPP_CHECK_PGRMS =
+@WITH_MAGICK_PLUS_PLUS_TRUE@MAGICKPP_CHECK_PGRMS = $(MAGICKPP_CHECK_PGRMS_OPT)
+@WITH_MAGICK_PLUS_PLUS_FALSE@MAGICKPP_MANS =
+@WITH_MAGICK_PLUS_PLUS_TRUE@MAGICKPP_MANS = $(MAGICKPP_MANS_OPT)
+@WITH_MAGICK_PLUS_PLUS_FALSE@MAGICKPP_PKGCONFIG =
+@WITH_MAGICK_PLUS_PLUS_TRUE@MAGICKPP_PKGCONFIG = $(MAGICKPP_PKGCONFIG_OPT)
+@WITH_MAGICK_PLUS_PLUS_FALSE@MAGICKPP_SCRPTS =
+@WITH_MAGICK_PLUS_PLUS_TRUE@MAGICKPP_SCRPTS = $(MAGICKPP_SCRIPTS_OPT)
+@WITH_MAGICK_PLUS_PLUS_FALSE@MAGICKPP_TESTS =
+@WITH_MAGICK_PLUS_PLUS_TRUE@MAGICKPP_TESTS = $(MAGICKPP_TEST_SCRIPTS_OPT)
+@WITH_MAGICK_PLUS_PLUS_FALSE@MAGICKPP_TOP_INCHEADERS =
+@WITH_MAGICK_PLUS_PLUS_TRUE@MAGICKPP_TOP_INCHEADERS = $(MAGICKPP_TOP_INCHEADERS_OPT)
+@WITH_MAGICK_PLUS_PLUS_FALSE@MAGICKPP_INCHEADERS =
+@WITH_MAGICK_PLUS_PLUS_TRUE@MAGICKPP_INCHEADERS = $(MAGICKPP_INCHEADERS_OPT)
+@WITH_MAGICK_PLUS_PLUS_FALSE@MAGICKPP_XFAIL_TESTS =
+@WITH_MAGICK_PLUS_PLUS_TRUE@MAGICKPP_XFAIL_TESTS =
+MAGICKPP_SCRIPTS_OPT = \
+ Magick++/bin/GraphicsMagick++-config
+
+MAGICKPP_MANS_OPT = \
+ Magick++/bin/GraphicsMagick++-config.1
+
+MAGICKPP_PKGCONFIG_OPT = \
+ Magick++/lib/GraphicsMagick++.pc
+
+MAGICKPP_TEST_SCRIPTS_OPT = \
+ Magick++/tests/tests.tap \
+ Magick++/demo/demos.tap
+
+MAGICKPP_EXTRA_DIST = \
+ Magick++/AUTHORS \
+ Magick++/COPYING \
+ Magick++/ChangeLog \
+ Magick++/README \
+ Magick++/bin/GraphicsMagick++-config.1 \
+ Magick++/bin/GraphicsMagick++-config.in \
+ Magick++/lib/GraphicsMagick++.pc.in \
+ Magick++/demo/model.miff \
+ Magick++/demo/smile.miff \
+ Magick++/demo/smile_anim.miff \
+ Magick++/demo/tile.miff \
+ $(MAGICKPP_TEST_SCRIPTS_OPT) \
+ Magick++/tests/test_image.miff \
+ Magick++/tests/test_image_anim.miff
+
+MAGICKPP_CLEANFILES = \
+ Magick++/demo/*_out*.* \
+ Magick++/demo/ir.out \
+ Magick++/tests/colorHistogram.txt \
+ Magick++/tests/testmagick_anim_out.miff \
+ Magick++/tests/ir.out
+
+Magick___lib_libGraphicsMagick___la_SOURCES = \
+ Magick++/lib/Blob.cpp \
+ Magick++/lib/BlobRef.cpp \
+ Magick++/lib/CoderInfo.cpp \
+ Magick++/lib/Color.cpp \
+ Magick++/lib/Drawable.cpp \
+ Magick++/lib/Exception.cpp \
+ Magick++/lib/Functions.cpp \
+ Magick++/lib/Geometry.cpp \
+ Magick++/lib/Image.cpp \
+ Magick++/lib/ImageRef.cpp \
+ Magick++/lib/Montage.cpp \
+ Magick++/lib/Options.cpp \
+ Magick++/lib/Pixels.cpp \
+ Magick++/lib/STL.cpp \
+ Magick++/lib/Thread.cpp \
+ Magick++/lib/TypeMetric.cpp \
+ Magick++/lib/Magick++.h \
+ Magick++/lib/Magick++/Blob.h \
+ Magick++/lib/Magick++/BlobRef.h \
+ Magick++/lib/Magick++/CoderInfo.h \
+ Magick++/lib/Magick++/Color.h \
+ Magick++/lib/Magick++/Drawable.h \
+ Magick++/lib/Magick++/Exception.h \
+ Magick++/lib/Magick++/Functions.h \
+ Magick++/lib/Magick++/Geometry.h \
+ Magick++/lib/Magick++/Image.h \
+ Magick++/lib/Magick++/ImageRef.h \
+ Magick++/lib/Magick++/Include.h \
+ Magick++/lib/Magick++/Montage.h \
+ Magick++/lib/Magick++/Options.h \
+ Magick++/lib/Magick++/Pixels.h \
+ Magick++/lib/Magick++/STL.h \
+ Magick++/lib/Magick++/Thread.h \
+ Magick++/lib/Magick++/TypeMetric.h
+
+Magick___lib_libGraphicsMagick___la_CPPFLAGS = \
+ $(MAGICKPP_CPPFLAGS)
+
+magickpptopincdir = $(topincludedir)
+magickpptopinc_HEADERS = $(MAGICKPP_TOP_INCHEADERS)
+MAGICKPP_TOP_INCHEADERS_OPT = \
+ Magick++/lib/Magick++.h
+
+magickppincdir = $(topincludedir)/Magick++
+magickppinc_HEADERS = $(MAGICKPP_INCHEADERS)
+MAGICKPP_INCHEADERS_OPT = \
+ Magick++/lib/Magick++/Blob.h \
+ Magick++/lib/Magick++/CoderInfo.h \
+ Magick++/lib/Magick++/Color.h \
+ Magick++/lib/Magick++/Drawable.h \
+ Magick++/lib/Magick++/Exception.h \
+ Magick++/lib/Magick++/Geometry.h \
+ Magick++/lib/Magick++/Image.h \
+ Magick++/lib/Magick++/Include.h \
+ Magick++/lib/Magick++/Montage.h \
+ Magick++/lib/Magick++/Pixels.h \
+ Magick++/lib/Magick++/STL.h \
+ Magick++/lib/Magick++/TypeMetric.h
+
+
+# -no-undefined -export-symbols-regex ".*"
+Magick___lib_libGraphicsMagick___la_LDFLAGS = -no-undefined \
+ $(MAGICK_LT_RELEASE_OPTS) \
+ -version-info $(MAGICK_PLUS_PLUS_LIBRARY_CURRENT):$(MAGICK_PLUS_PLUS_LIBRARY_REVISION):$(MAGICK_PLUS_PLUS_LIBRARY_AGE)
+
+Magick___lib_libGraphicsMagick___la_LIBADD = $(LIBMAGICK)
+MAGICKPP_CHECK_PGRMS_OPT = \
+ Magick++/demo/analyze \
+ Magick++/demo/button \
+ Magick++/demo/demo \
+ Magick++/demo/detrans \
+ Magick++/demo/flip \
+ Magick++/demo/gravity \
+ Magick++/demo/piddle \
+ Magick++/demo/shapes \
+ Magick++/demo/zoom \
+ Magick++/tests/appendImages \
+ Magick++/tests/attributes \
+ Magick++/tests/averageImages \
+ Magick++/tests/coalesceImages \
+ Magick++/tests/coderInfo \
+ Magick++/tests/color \
+ Magick++/tests/colorHistogram \
+ Magick++/tests/exceptions \
+ Magick++/tests/montageImages \
+ Magick++/tests/morphImages \
+ Magick++/tests/readWriteBlob \
+ Magick++/tests/readWriteImages
+
+Magick___demo_analyze_SOURCES = Magick++/demo/analyze.cpp
+Magick___demo_analyze_LDADD = $(LIBMAGICKPP)
+Magick___demo_analyze_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___demo_button_SOURCES = Magick++/demo/button.cpp
+Magick___demo_button_LDADD = $(LIBMAGICKPP)
+Magick___demo_button_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___demo_demo_SOURCES = Magick++/demo/demo.cpp
+Magick___demo_demo_LDADD = $(LIBMAGICKPP)
+Magick___demo_demo_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___demo_detrans_SOURCES = Magick++/demo/detrans.cpp
+Magick___demo_detrans_LDADD = $(LIBMAGICKPP)
+Magick___demo_detrans_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___demo_flip_SOURCES = Magick++/demo/flip.cpp
+Magick___demo_flip_LDADD = $(LIBMAGICKPP)
+Magick___demo_flip_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___demo_gravity_SOURCES = Magick++/demo/gravity.cpp
+Magick___demo_gravity_LDADD = $(LIBMAGICKPP)
+Magick___demo_gravity_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___demo_piddle_SOURCES = Magick++/demo/piddle.cpp
+Magick___demo_piddle_LDADD = $(LIBMAGICKPP)
+Magick___demo_piddle_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___demo_shapes_SOURCES = Magick++/demo/shapes.cpp
+Magick___demo_shapes_LDADD = $(LIBMAGICKPP)
+Magick___demo_shapes_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___demo_zoom_SOURCES = Magick++/demo/zoom.cpp
+Magick___demo_zoom_LDADD = $(LIBMAGICKPP)
+Magick___demo_zoom_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_appendImages_SOURCES = Magick++/tests/appendImages.cpp
+Magick___tests_appendImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_appendImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_attributes_SOURCES = Magick++/tests/attributes.cpp
+Magick___tests_attributes_LDADD = $(LIBMAGICKPP)
+Magick___tests_attributes_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_averageImages_SOURCES = Magick++/tests/averageImages.cpp
+Magick___tests_averageImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_averageImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_coalesceImages_SOURCES = Magick++/tests/coalesceImages.cpp
+Magick___tests_coalesceImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_coalesceImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_coderInfo_SOURCES = Magick++/tests/coderInfo.cpp
+Magick___tests_coderInfo_LDADD = $(LIBMAGICKPP)
+Magick___tests_coderInfo_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_color_SOURCES = Magick++/tests/color.cpp
+Magick___tests_color_LDADD = $(LIBMAGICKPP)
+Magick___tests_color_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_colorHistogram_SOURCES = Magick++/tests/colorHistogram.cpp
+Magick___tests_colorHistogram_LDADD = $(LIBMAGICKPP)
+Magick___tests_colorHistogram_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_exceptions_SOURCES = Magick++/tests/exceptions.cpp
+Magick___tests_exceptions_LDADD = $(LIBMAGICKPP)
+Magick___tests_exceptions_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_montageImages_SOURCES = Magick++/tests/montageImages.cpp
+Magick___tests_montageImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_montageImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_morphImages_SOURCES = Magick++/tests/morphImages.cpp
+Magick___tests_morphImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_morphImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_readWriteBlob_SOURCES = Magick++/tests/readWriteBlob.cpp
+Magick___tests_readWriteBlob_LDADD = $(LIBMAGICKPP)
+Magick___tests_readWriteBlob_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+Magick___tests_readWriteImages_SOURCES = Magick++/tests/readWriteImages.cpp
+Magick___tests_readWriteImages_LDADD = $(LIBMAGICKPP)
+Magick___tests_readWriteImages_CPPFLAGS = $(MAGICKPP_CPPFLAGS)
+TESTS_CHECK_PGRMS = \
+ tests/bitstream \
+ tests/constitute \
+ tests/drawtest \
+ tests/maptest \
+ tests/rwblob \
+ tests/rwfile
+
+tests_bitstream_SOURCES = tests/bitstream.c
+tests_bitstream_LDADD = $(LIBMAGICK)
+tests_bitstream_CPPFLAGS = $(AM_CPPFLAGS)
+tests_constitute_SOURCES = tests/constitute.c
+tests_constitute_CPPFLAGS = $(AM_CPPFLAGS)
+tests_constitute_LDADD = $(LIBMAGICK)
+tests_maptest_SOURCES = tests/maptest.c
+tests_maptest_CPPFLAGS = $(AM_CPPFLAGS)
+tests_maptest_LDADD = $(LIBMAGICK)
+tests_rwblob_SOURCES = tests/rwblob.c
+tests_rwblob_CPPFLAGS = $(AM_CPPFLAGS)
+tests_rwblob_LDADD = $(LIBMAGICK)
+tests_rwfile_SOURCES = tests/rwfile.c
+tests_rwfile_CPPFLAGS = $(AM_CPPFLAGS)
+tests_rwfile_LDADD = $(LIBMAGICK)
+tests_drawtest_SOURCES = tests/drawtest.c
+tests_drawtest_CPPFLAGS = $(AM_CPPFLAGS)
+tests_drawtest_LDADD = $(LIBMAGICK)
+TESTS_XFAIL_TESTS =
+TESTS_TESTS = \
+ tests/constitute.tap \
+ tests/drawtests.tap \
+ tests/rwblob.tap \
+ tests/rwblob_sized.tap \
+ tests/rwfile.tap \
+ tests/rwfile_sized.tap \
+ tests/rwfile_miff.tap \
+ tests/rwfile_pdf.tap \
+ tests/rwfile_deep.tap
+
+TESTS_EXTRA_DIST = \
+ tests/common.shi \
+ tests/input_bilevel.miff \
+ tests/input_gray.miff \
+ tests/input_pallette.miff \
+ tests/input_truecolor_70x46.miff \
+ tests/input_truecolor.miff \
+ tests/input_truecolor10.dpx \
+ tests/input_truecolor12.dpx \
+ tests/input_truecolor16.dpx \
+ $(TESTS_TESTS)
+
+TESTS_CLEANFILES = \
+ tests/*out*.*
+
+wandincdir = $(topincludedir)/wand
+WAND_CPPFLAGS = $(AM_CPPFLAGS)
+WAND_SOURCES = \
+ wand/drawing_wand.c \
+ wand/drawing_wand.h \
+ wand/magick_compat.c \
+ wand/magick_wand.c \
+ wand/magick_wand.h \
+ wand/pixel_wand.c \
+ wand/pixel_wand.h \
+ wand/wand_api.h \
+ wand/wand_private.h
+
+WAND_INCLUDE_HDRS = \
+ wand/drawing_wand.h \
+ wand/magick_wand.h \
+ wand/pixel_wand.h \
+ wand/wand_api.h \
+ wand/wand_symbols.h
+
+
+# Headers which are installed
+wandinc_HEADERS = \
+ $(WAND_INCLUDE_HDRS)
+
+WAND_BIN_SCRPTS = \
+ wand/GraphicsMagickWand-config
+
+WAND_PKGCONFIG = \
+ wand/GraphicsMagickWand.pc
+
+WAND_MANS = \
+ wand/GraphicsMagickWand-config.1
+
+LIBWAND = wand/libGraphicsMagickWand.la
+wand_libGraphicsMagickWand_la_SOURCES = $(WAND_SOURCES)
+wand_libGraphicsMagickWand_la_CPPFLAGS = $(WAND_CPPFLAGS)
+wand_libGraphicsMagickWand_la_LDFLAGS = -no-undefined -export-symbols-regex ".*" \
+ $(MAGICK_LT_RELEASE_OPTS) \
+ -version-info $(MAGICK_WAND_LIBRARY_CURRENT):$(MAGICK_WAND_LIBRARY_REVISION):$(MAGICK_WAND_LIBRARY_AGE)
+
+wand_libGraphicsMagickWand_la_LIBADD = $(LIBMAGICK) $(LIB_MATH)
+WAND_EXTRA_DIST = \
+ wand/GraphicsMagickWand-config.1 \
+ wand/input_256c.miff \
+ wand/input_bilevel.miff \
+ wand/input_gray.miff \
+ wand/input_truecolor.miff \
+ wand/sequence.miff \
+ wand/common.shi \
+ $(WAND_TESTS)
+
+wand_drawtest_LDADD = $(LIBWAND)
+wand_drawtest_CPPFLAGS = $(WAND_CPPFLAGS)
+wand_drawtest_LDFLAGS = $(LDFLAGS)
+wand_drawtest_SOURCES = wand/drawtest.c
+wand_wandtest_LDADD = $(LIBWAND)
+wand_wandtest_CPPFLAGS = $(WAND_CPPFLAGS)
+wand_wandtest_LDFLAGS = $(LDFLAGS)
+wand_wandtest_SOURCES = wand/wandtest.c
+WAND_CHECK_PGRMS = \
+ wand/drawtest \
+ wand/wandtest
+
+WAND_TESTS = \
+ wand/wandtests.tap
+
+WAND_CLEANFILES = \
+ wand/*_out.*
+
+WWWDIR = $(top_srcdir)/www
+
+# Install HTML files
+DOCDIRS = www www/api www/images www/Magick++ www/wand
+HTML_INSTALL_DATA_TARGETS = install-data-html
+
+# Uninstall HTML files
+HTML_UNINSTALL_DATA_TARGETS = uninstall-data-html
+
+# These files are built from reStructuredText
+RST2HTML_TARGETS = \
+ $(WWWDIR)/ChangeLog-2001.html \
+ $(WWWDIR)/ChangeLog-2002.html \
+ $(WWWDIR)/ChangeLog-2003.html \
+ $(WWWDIR)/ChangeLog-2004.html \
+ $(WWWDIR)/ChangeLog-2005.html \
+ $(WWWDIR)/ChangeLog-2006.html \
+ $(WWWDIR)/ChangeLog-2007.html \
+ $(WWWDIR)/ChangeLog-2008.html \
+ $(WWWDIR)/ChangeLog-2009.html \
+ $(WWWDIR)/ChangeLog-2010.html \
+ $(WWWDIR)/ChangeLog-2011.html \
+ $(WWWDIR)/ChangeLog-2012.html \
+ $(WWWDIR)/ChangeLog-2013.html \
+ $(WWWDIR)/ChangeLog-2014.html \
+ $(WWWDIR)/ChangeLog-2015.html \
+ $(WWWDIR)/ChangeLog-2016.html \
+ $(WWWDIR)/Changelog.html \
+ $(WWWDIR)/Changes.html \
+ $(WWWDIR)/Copyright.html \
+ $(WWWDIR)/FAQ.html \
+ $(WWWDIR)/Hg.html \
+ $(WWWDIR)/INSTALL-unix.html \
+ $(WWWDIR)/INSTALL-windows.html \
+ $(WWWDIR)/ImageMagickObject.html \
+ $(WWWDIR)/Magick++/Blob.html \
+ $(WWWDIR)/Magick++/ChangeLog.html \
+ $(WWWDIR)/Magick++/CoderInfo.html \
+ $(WWWDIR)/Magick++/Color.html \
+ $(WWWDIR)/Magick++/Drawable.html \
+ $(WWWDIR)/Magick++/Enumerations.html \
+ $(WWWDIR)/Magick++/Exception.html \
+ $(WWWDIR)/Magick++/FormatCharacters.html \
+ $(WWWDIR)/Magick++/Geometry.html \
+ $(WWWDIR)/Magick++/Image.html \
+ $(WWWDIR)/Magick++/ImageDesign.html \
+ $(WWWDIR)/Magick++/Montage.html \
+ $(WWWDIR)/Magick++/PixelPacket.html \
+ $(WWWDIR)/Magick++/Pixels.html \
+ $(WWWDIR)/Magick++/TypeMetric.html \
+ $(WWWDIR)/Magick++/index.html \
+ $(WWWDIR)/NEWS.html \
+ $(WWWDIR)/OpenMP.html \
+ $(WWWDIR)/README.html \
+ $(WWWDIR)/api/api.html \
+ $(WWWDIR)/authors.html \
+ $(WWWDIR)/benchmarks.html \
+ $(WWWDIR)/bugs.html \
+ $(WWWDIR)/contribute.html \
+ $(WWWDIR)/download.html \
+ $(WWWDIR)/formats.html \
+ $(WWWDIR)/index.html \
+ $(WWWDIR)/links.html \
+ $(WWWDIR)/miff.html \
+ $(WWWDIR)/mission.html \
+ $(WWWDIR)/motion-picture.html \
+ $(WWWDIR)/perl.html \
+ $(WWWDIR)/process.html \
+ $(WWWDIR)/programming.html \
+ $(WWWDIR)/project.html \
+ $(WWWDIR)/quantize.html \
+ $(WWWDIR)/reference.html \
+ $(WWWDIR)/security.html \
+ $(WWWDIR)/thanks.html \
+ $(WWWDIR)/tools.html \
+ $(WWWDIR)/utilities.html \
+ $(WWWDIR)/wand/wand.html
+
+
+# These files are existing reStructuredText files
+WWW_RST_FILES = \
+ $(WWWDIR)/Changes.rst \
+ $(WWWDIR)/FAQ.rst \
+ $(WWWDIR)/Hg.rst \
+ $(WWWDIR)/ImageMagickObject.rst \
+ $(WWWDIR)/Magick++/Blob.rst \
+ $(WWWDIR)/Magick++/CoderInfo.rst \
+ $(WWWDIR)/Magick++/Color.rst \
+ $(WWWDIR)/Magick++/Drawable.rst \
+ $(WWWDIR)/Magick++/Enumerations.rst \
+ $(WWWDIR)/Magick++/Exception.rst \
+ $(WWWDIR)/Magick++/FormatCharacters.rst \
+ $(WWWDIR)/Magick++/Geometry.rst \
+ $(WWWDIR)/Magick++/Image.rst \
+ $(WWWDIR)/Magick++/ImageDesign.rst \
+ $(WWWDIR)/Magick++/Montage.rst \
+ $(WWWDIR)/Magick++/PixelPacket.rst \
+ $(WWWDIR)/Magick++/Pixels.rst \
+ $(WWWDIR)/Magick++/TypeMetric.rst \
+ $(WWWDIR)/Magick++/index.rst \
+ $(WWWDIR)/OpenMP.rst \
+ $(WWWDIR)/api/api.rst \
+ $(WWWDIR)/authors.rst \
+ $(WWWDIR)/benchmarks.rst \
+ $(WWWDIR)/bugs.rst \
+ $(WWWDIR)/contribute.rst \
+ $(WWWDIR)/download.rst \
+ $(WWWDIR)/formats.rst \
+ $(WWWDIR)/index.rst \
+ $(WWWDIR)/links.rst \
+ $(WWWDIR)/miff.rst \
+ $(WWWDIR)/mission.rst \
+ $(WWWDIR)/motion-picture.rst \
+ $(WWWDIR)/perl.rst \
+ $(WWWDIR)/process.rst \
+ $(WWWDIR)/programming.rst \
+ $(WWWDIR)/project.rst \
+ $(WWWDIR)/quantize.rst \
+ $(WWWDIR)/reference.rst \
+ $(WWWDIR)/security.rst \
+ $(WWWDIR)/thanks.rst \
+ $(WWWDIR)/tools.rst \
+ $(WWWDIR)/utilities.rst
+
+
+# These are the HTML files which are packaged
+WWW_HTML_FILES = \
+ $(WWWDIR)/ChangeLog-2001.html \
+ $(WWWDIR)/ChangeLog-2002.html \
+ $(WWWDIR)/ChangeLog-2003.html \
+ $(WWWDIR)/ChangeLog-2004.html \
+ $(WWWDIR)/ChangeLog-2005.html \
+ $(WWWDIR)/ChangeLog-2006.html \
+ $(WWWDIR)/ChangeLog-2007.html \
+ $(WWWDIR)/ChangeLog-2008.html \
+ $(WWWDIR)/ChangeLog-2009.html \
+ $(WWWDIR)/ChangeLog-2010.html \
+ $(WWWDIR)/ChangeLog-2011.html \
+ $(WWWDIR)/ChangeLog-2012.html \
+ $(WWWDIR)/ChangeLog-2013.html \
+ $(WWWDIR)/ChangeLog-2014.html \
+ $(WWWDIR)/ChangeLog-2015.html \
+ $(WWWDIR)/ChangeLog-2016.html \
+ $(WWWDIR)/Changelog.html \
+ $(WWWDIR)/Changes.html \
+ $(WWWDIR)/Copyright.html \
+ $(WWWDIR)/FAQ.html \
+ $(WWWDIR)/GraphicsMagick.html \
+ $(WWWDIR)/Hg.html \
+ $(WWWDIR)/INSTALL-unix.html \
+ $(WWWDIR)/INSTALL-windows.html \
+ $(WWWDIR)/ImageMagickObject.html \
+ $(WWWDIR)/ImageMagickObject.rst \
+ $(WWWDIR)/Magick++/Blob.html \
+ $(WWWDIR)/Magick++/ChangeLog.html \
+ $(WWWDIR)/Magick++/CoderInfo.html \
+ $(WWWDIR)/Magick++/Color.html \
+ $(WWWDIR)/Magick++/Drawable.html \
+ $(WWWDIR)/Magick++/Enumerations.html \
+ $(WWWDIR)/Magick++/Exception.html \
+ $(WWWDIR)/Magick++/FormatCharacters.html \
+ $(WWWDIR)/Magick++/Geometry.html \
+ $(WWWDIR)/Magick++/Image.html \
+ $(WWWDIR)/Magick++/ImageDesign.html \
+ $(WWWDIR)/Magick++/Montage.html \
+ $(WWWDIR)/Magick++/PixelPacket.html \
+ $(WWWDIR)/Magick++/Pixels.html \
+ $(WWWDIR)/Magick++/TypeMetric.html \
+ $(WWWDIR)/Magick++/index.html \
+ $(WWWDIR)/NEWS.html \
+ $(WWWDIR)/OpenMP.html \
+ $(WWWDIR)/README.html \
+ $(WWWDIR)/animate.html \
+ $(WWWDIR)/api/api.html \
+ $(WWWDIR)/authors.html \
+ $(WWWDIR)/benchmarks.html \
+ $(WWWDIR)/bugs.html \
+ $(WWWDIR)/color.html \
+ $(WWWDIR)/compare.html \
+ $(WWWDIR)/composite.html \
+ $(WWWDIR)/conjure.html \
+ $(WWWDIR)/contribute.html \
+ $(WWWDIR)/convert.html \
+ $(WWWDIR)/display.html \
+ $(WWWDIR)/docutils-api.css \
+ $(WWWDIR)/docutils-articles.css \
+ $(WWWDIR)/download.html \
+ $(WWWDIR)/formats.html \
+ $(WWWDIR)/gm.html \
+ $(WWWDIR)/identify.html \
+ $(WWWDIR)/import.html \
+ $(WWWDIR)/index.html \
+ $(WWWDIR)/links.html \
+ $(WWWDIR)/miff.html \
+ $(WWWDIR)/mission.html \
+ $(WWWDIR)/mogrify.html \
+ $(WWWDIR)/montage.html \
+ $(WWWDIR)/motion-picture.html \
+ $(WWWDIR)/perl.html \
+ $(WWWDIR)/process.html \
+ $(WWWDIR)/programming.html \
+ $(WWWDIR)/project.html \
+ $(WWWDIR)/quantize.html \
+ $(WWWDIR)/reference.html \
+ $(WWWDIR)/security.html \
+ $(WWWDIR)/thanks.html \
+ $(WWWDIR)/tools.html \
+ $(WWWDIR)/utilities.html\
+ $(WWWDIR)/wand/wand.html
+
+WWWW_EXTRA_DIST = $(WWW_HTML_FILES) $(WWW_RST_FILES)
+WWW_MAINTAINER_TARGETS = $(WWW_HTML_FILES) $(WWWDIR)/color.html
+@MAINTAINER_MODE_TRUE@NAMED_COLORS = $(top_srcdir)/scripts/named_colors.py
+@MAINTAINER_MODE_TRUE@RST2HTMLDECO = $(top_srcdir)/scripts/rst2htmldeco.py
+@MAINTAINER_MODE_TRUE@RELPATH = $(top_srcdir)/scripts/relpath.py
+@MAINTAINER_MODE_TRUE@OMP_DECIMAL_ALIGN = $(top_srcdir)/scripts/omp_decimal_align.py
+@MAINTAINER_MODE_TRUE@RST2HTML_COMMAND = $(RST2HTMLDECO) --cloak-email-addresses --link-stylesheet=docutils-articles.css
+
+#
+# Build HTML version of ChangeLogs
+#
+@MAINTAINER_MODE_TRUE@CHANGELOG2RST = $(top_srcdir)/scripts/changelog2rst.sh
+wwwapidir = $(htmldir)/api
+WWWAPIDIR = $(top_srcdir)/www/api
+WWWAPI_HTML_TARGETS = \
+ $(WWWAPIDIR)/animate.html \
+ $(WWWAPIDIR)/annotate.html \
+ $(WWWAPIDIR)/attribute.html \
+ $(WWWAPIDIR)/average.html \
+ $(WWWAPIDIR)/blob.html \
+ $(WWWAPIDIR)/cdl.html \
+ $(WWWAPIDIR)/channel.html \
+ $(WWWAPIDIR)/color.html \
+ $(WWWAPIDIR)/colormap.html \
+ $(WWWAPIDIR)/compare.html \
+ $(WWWAPIDIR)/composite.html \
+ $(WWWAPIDIR)/confirm_access.html \
+ $(WWWAPIDIR)/constitute.html \
+ $(WWWAPIDIR)/decorate.html \
+ $(WWWAPIDIR)/deprecate.html \
+ $(WWWAPIDIR)/describe.html \
+ $(WWWAPIDIR)/display.html \
+ $(WWWAPIDIR)/draw.html \
+ $(WWWAPIDIR)/effect.html \
+ $(WWWAPIDIR)/enhance.html \
+ $(WWWAPIDIR)/error.html \
+ $(WWWAPIDIR)/export.html \
+ $(WWWAPIDIR)/fx.html \
+ $(WWWAPIDIR)/hclut.html \
+ $(WWWAPIDIR)/image.html \
+ $(WWWAPIDIR)/import.html \
+ $(WWWAPIDIR)/list.html \
+ $(WWWAPIDIR)/magick.html \
+ $(WWWAPIDIR)/memory.html \
+ $(WWWAPIDIR)/monitor.html \
+ $(WWWAPIDIR)/montage.html \
+ $(WWWAPIDIR)/operator.html \
+ $(WWWAPIDIR)/paint.html \
+ $(WWWAPIDIR)/pixel_cache.html \
+ $(WWWAPIDIR)/pixel_iterator.html \
+ $(WWWAPIDIR)/plasma.html \
+ $(WWWAPIDIR)/profile.html \
+ $(WWWAPIDIR)/quantize.html \
+ $(WWWAPIDIR)/registry.html \
+ $(WWWAPIDIR)/render.html \
+ $(WWWAPIDIR)/resize.html \
+ $(WWWAPIDIR)/resource.html \
+ $(WWWAPIDIR)/segment.html \
+ $(WWWAPIDIR)/shear.html \
+ $(WWWAPIDIR)/signature.html \
+ $(WWWAPIDIR)/statistics.html \
+ $(WWWAPIDIR)/texture.html \
+ $(WWWAPIDIR)/transform.html \
+ $(WWWAPIDIR)/types.html \
+ $(WWWAPIDIR)/widget.html
+
+WWWWAPI_FILES = \
+ www/api/animate.html \
+ www/api/annotate.html \
+ www/api/api_hyperlinks.rst \
+ www/api/attribute.html \
+ www/api/average.html \
+ www/api/blob.html \
+ www/api/cdl.html \
+ www/api/channel.html \
+ www/api/color.html \
+ www/api/colormap.html \
+ www/api/compare.html \
+ www/api/composite.html \
+ www/api/confirm_access.html \
+ www/api/constitute.html \
+ www/api/decorate.html \
+ www/api/deprecate.html \
+ www/api/describe.html \
+ www/api/display.html \
+ www/api/draw.html \
+ www/api/effect.html \
+ www/api/export.html \
+ www/api/enhance.html \
+ www/api/error.html \
+ www/api/fx.html \
+ www/api/hclut.html \
+ www/api/image.html \
+ www/api/import.html \
+ www/api/list.html \
+ www/api/magick.html \
+ www/api/memory.html \
+ www/api/monitor.html \
+ www/api/montage.html \
+ www/api/operator.html \
+ www/api/paint.html \
+ www/api/pixel_cache.html \
+ www/api/pixel_iterator.html \
+ www/api/plasma.html \
+ www/api/profile.html \
+ www/api/quantize.html \
+ www/api/registry.html \
+ www/api/render.html \
+ www/api/resize.html \
+ www/api/resource.html \
+ www/api/segment.html \
+ www/api/shear.html \
+ www/api/signature.html \
+ www/api/statistics.html \
+ www/api/texture.html \
+ www/api/transform.html \
+ www/api/types.html \
+ www/api/widget.html
+
+WWWAPI_EXTRA_DIST = \
+ $(WWWWAPI_FILES)
+
+WWWAPI_MAINTAINER_TARGETS = $(WWWAPI_HTML_TARGETS)
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@APIWHATIS = $(top_srcdir)/scripts/whatis.txt
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@FORMATCAPI = $(top_srcdir)/scripts/format_c_api_doc.py
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@APIRST2HTML_COMMAND = $(RST2HTMLDECO) \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ --link-stylesheet=../docutils-articles.css`
+
+wwwwandapidir = $(htmldir)/wand
+WWWWANDAPIDIR = $(top_srcdir)/www/wand
+WWWWANDAPI_HTML_TARGETS = \
+ $(WWWWANDAPIDIR)/drawing_wand.html \
+ $(WWWWANDAPIDIR)/magick_wand.html \
+ $(WWWWANDAPIDIR)/pixel_wand.html
+
+WWWWANDAPI_FILES = \
+ www/wand/drawing_wand.html \
+ www/wand/magick_wand.html \
+ www/wand/pixel_wand.html
+
+WWWWANDAPI_EXTRA_DIST = \
+ www/wand/wand.rst \
+ $(WWWWANDAPI_FILES)
+
+WWWWANDAPI_MAINTAINER_TARGETS = $(WWWWANDAPI_HTML_TARGETS)
+UTILITIES_PGMS = \
+ utilities/gm
+
+utilities_gm_LDADD = $(LIBMAGICK)
+utilities_gm_LDFLAGS = $(LDFLAGS)
+utilities_gm_SOURCES = utilities/gm.c
+UTILITIES_XFAIL_TESTS =
+
+# Tests to run
+UTILITIES_TESTS = \
+ utilities/tests/effects.tap \
+ utilities/tests/pipe.tap \
+ utilities/tests/hald-clut.tap \
+ utilities/tests/help.tap \
+ utilities/tests/icc-transform.tap \
+ utilities/tests/identify.tap \
+ utilities/tests/list.tap \
+ utilities/tests/montage.tap \
+ utilities/tests/msl_composite.tap \
+ utilities/tests/preview.tap
+
+UTILITIES_MANS = \
+ utilities/gm.1 \
+ utilities/miff.4 \
+ utilities/quantize.5
+
+UTILITIES_EXTRA_DIST = \
+ $(UTILITIES_MANS) \
+ $(UTILITIES_TESTS) \
+ utilities/tests/BetaRGB.icc \
+ utilities/tests/common.sh \
+ utilities/tests/sunrise.jpg \
+ utilities/tests/sunrise.miff
+
+UTILITIES_CLEANFILES = \
+ utilities/tests/*_out.miff \
+ utilities/tests/*_out.pnm \
+ utilities/tests/*_out.txt \
+ utilities/tests/demo*.miff \
+ utilities/tests/gm.core \
+ utilities/tests/core
+
+
+# Install/Uninstall ImageMagick compatibility links
+@MAGICK_COMPAT_TRUE@MAGICKPROGRAMS = animate compare composite conjure convert display identify import mogrify montage
+@MAGICK_COMPAT_TRUE@UTILITIES_INSTALL_EXEC_LOCAL_TARGETS = install-exec-local-utilities
+@MAGICK_COMPAT_TRUE@UTILITIES_UNINSTALL_LOCAL_TARGETS = uninstall-local-utilities
+PERLMAGICK = PerlMagick
+PERLMAGICK_MAINTAINER_TARGETS = $(top_srcdir)/$(PERLMAGICK)/Magick.pm
+@WITH_PERL_TRUE@PERLMAKEMAKER = $(PERLMAGICK)/Makefile.PL
+@WITH_PERL_TRUE@PERLMAKEFILE = $(PERLMAGICK)/Makefile
+@WITH_PERL_TRUE@PERLMAGICK_ALL_LOCAL_TARGETS = all-perl
+#PERLMAGICK_INSTALL_EXEC_LOCAL_TARGETS = install-exec-perl
+@WITH_PERL_TRUE@PERLMAGICK_INSTALL_DATA_LOCAL_TARGETS =
+#PERLMAGICK_UNINSTALL_LOCAL_TARGETS = uninstall-exec-perl
+@WITH_PERL_TRUE@PERLMAGICK_CLEAN_LOCAL_TARGETS = clean-perl
+@WITH_PERL_TRUE@PERLMAGICK_DISTCLEAN_LOCAL_TARGETS = clean-perl
+@WITH_PERL_TRUE@PERLMAGICK_MAINTAINER_CLEAN_LOCAL_TARGETS = distclean-local
+#PERLMAGICK_CHECK_LOCAL_TARGETS = check-perl
+@WITH_PERL_TRUE@PERLMAGICK_TESTS = PerlMagick/PerlMagickCheck.sh
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@PERLMAGICK_CHECKSCRIPTS = perl-build
+
+#PERLMAGICK_CHECKSCRIPTS = perl-build
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@PERLMAGICK_CHECKSCRIPTS =
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@PERLSTATICNAME = PerlMagick
+
+# Pkgconfig directory
+pkgconfigdir = $(libdir)/pkgconfig
+
+# Files to install in Pkgconfig directory
+pkgconfig_DATA = \
+ $(MAGICK_PKGCONFIG) \
+ $(MAGICKPP_PKGCONFIG) \
+ $(WAND_PKGCONFIG)
+
+
+# Manual pages to install
+man_MANS = \
+ $(MAGICK_MANS) \
+ $(MAGICKPP_MANS) \
+ $(UTILITIES_MANS) \
+ $(WAND_MANS)
+
+
+# Files to install in the package's doc directory
+doc_DATA = \
+ Copyright.txt \
+ $(CHANGELOGS) \
+ NEWS.txt
+
+@MAINTAINER_MODE_TRUE@MAINTAINER_TARGETS = \
+@MAINTAINER_MODE_TRUE@ magick-version \
+@MAINTAINER_MODE_TRUE@ GraphicsMagick.spec \
+@MAINTAINER_MODE_TRUE@ $(PERLMAGICK_MAINTAINER_TARGETS) \
+@MAINTAINER_MODE_TRUE@ $(WWW_MAINTAINER_TARGETS) \
+@MAINTAINER_MODE_TRUE@ $(WWWAPI_MAINTAINER_TARGETS) \
+@MAINTAINER_MODE_TRUE@ $(WWWWANDAPI_MAINTAINER_TARGETS)
+
+
+# Non-Automake subdirectories to distribute
+DISTDIRS = locale scripts www PerlMagick TclMagick
+@HAS_ZIP_FALSE@DIST_WINDOWS_SRC_ZIP =
+
+#
+# Build Windows source Zip and 7Zip balls
+#
+@HAS_ZIP_TRUE@DIST_WINDOWS_SRC_ZIP = $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-windows.zip
+@HAS_P7ZIP_FALSE@DIST_WINDOWS_SRC_7ZIP =
+@HAS_P7ZIP_TRUE@DIST_WINDOWS_SRC_7ZIP = $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-windows.7z
+
+#
+# RPM build support
+#
+@HAS_RPM_TRUE@DIST_ARCHIVE_SRPM = $(distdir)-1.src.rpm
+@HAS_RPM_TRUE@RPMDIR = rpmbuild
+@HAS_RPM_TRUE@RPMARCH = $(MAGICK_TARGET_CPU)
+@HAS_RPM_FALSE@DIST_ARCHIVE_RPM =
+@HAS_RPM_TRUE@DIST_ARCHIVE_RPM = \
+@HAS_RPM_TRUE@ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm \
+@HAS_RPM_TRUE@ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-c++-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm \
+@HAS_RPM_TRUE@ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-c++-devel-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm \
+@HAS_RPM_TRUE@ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-devel-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm \
+@HAS_RPM_TRUE@ $(RPMDIR)/$(RPMARCH)/$(PACKAGE_NAME)-perl-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)-1.$(RPMARCH).rpm
+
+
+#
+# Build a validated snapshot release and move to the snapshots directory.
+#
+SNAPSHOT_DIRECTORY = /ftp/pub/GraphicsMagick/snapshots
+COVERITY_EMAIL = bfriesen@simple.dallas.tx.us
+COVERITY_TARBALL = GraphicsMagick.xz
+COVERITY_VERSION = snapshot-@PACKAGE_CHANGE_DATE@
+COVERITY_DESCRIPTION = 'Ubuntu Q@QuantumDepth@'
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .lo .log .o .obj .sh .sh$(EXEEXT) .tap .tap$(EXEEXT) .trs
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/config/Makefile.am $(srcdir)/coders/Makefile.am $(srcdir)/magick/Makefile.am $(srcdir)/filters/Makefile.am $(srcdir)/Magick++/Makefile.am $(srcdir)/tests/Makefile.am $(srcdir)/wand/Makefile.am $(srcdir)/www/Makefile.am $(srcdir)/www/api/Makefile.am $(srcdir)/www/wand/Makefile.am $(srcdir)/utilities/Makefile.am $(srcdir)/PerlMagick/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+$(srcdir)/config/Makefile.am $(srcdir)/coders/Makefile.am $(srcdir)/magick/Makefile.am $(srcdir)/filters/Makefile.am $(srcdir)/Magick++/Makefile.am $(srcdir)/tests/Makefile.am $(srcdir)/wand/Makefile.am $(srcdir)/www/Makefile.am $(srcdir)/www/api/Makefile.am $(srcdir)/www/wand/Makefile.am $(srcdir)/utilities/Makefile.am $(srcdir)/PerlMagick/Makefile.am $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+magick/magick_config.h: magick/stamp-h1
+ @test -f $@ || rm -f magick/stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) magick/stamp-h1
+
+magick/stamp-h1: $(top_srcdir)/magick/magick_config.h.in $(top_builddir)/config.status
+ @rm -f magick/stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status magick/magick_config.h
+$(top_srcdir)/magick/magick_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f magick/stamp-h1
+ touch $@
+
+magick/magick_config_api.h: magick/stamp-h2
+ @test -f $@ || rm -f magick/stamp-h2
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) magick/stamp-h2
+
+magick/stamp-h2: $(top_srcdir)/magick/magick_config_api.h.in $(top_builddir)/config.status
+ @rm -f magick/stamp-h2
+ cd $(top_builddir) && $(SHELL) ./config.status magick/magick_config_api.h
+
+distclean-hdr:
+ -rm -f magick/magick_config.h magick/stamp-h1 magick/magick_config_api.h magick/stamp-h2
+GraphicsMagick.spec: $(top_builddir)/config.status $(srcdir)/GraphicsMagick.spec.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+Magick++/bin/GraphicsMagick++-config: $(top_builddir)/config.status $(top_srcdir)/Magick++/bin/GraphicsMagick++-config.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+Magick++/lib/GraphicsMagick++.pc: $(top_builddir)/config.status $(top_srcdir)/Magick++/lib/GraphicsMagick++.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+PerlMagick/Magick.pm: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/Magick.pm.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+PerlMagick/Makefile.PL: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/Makefile.PL.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+PerlMagick/PerlMagickCheck.sh: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/PerlMagickCheck.sh.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+PerlMagick/t/features.pl: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/t/features.pl.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+config/delegates.mgk: $(top_builddir)/config.status $(top_srcdir)/config/delegates.mgk.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+config/type-ghostscript.mgk: $(top_builddir)/config.status $(top_srcdir)/config/type-ghostscript.mgk.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+config/type-solaris.mgk: $(top_builddir)/config.status $(top_srcdir)/config/type-solaris.mgk.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+config/type-windows.mgk: $(top_builddir)/config.status $(top_srcdir)/config/type-windows.mgk.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+config/type.mgk: $(top_builddir)/config.status $(top_srcdir)/config/type.mgk.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+magick/GraphicsMagick-config: $(top_builddir)/config.status $(top_srcdir)/magick/GraphicsMagick-config.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+magick/GraphicsMagick.pc: $(top_builddir)/config.status $(top_srcdir)/magick/GraphicsMagick.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+magick/magick_types.h: $(top_builddir)/config.status $(top_srcdir)/magick/magick_types.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+magick/version.h: $(top_builddir)/config.status $(top_srcdir)/magick/version.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+common.shi: $(top_builddir)/config.status $(srcdir)/common.shi.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+rungm.sh: $(top_builddir)/config.status $(srcdir)/rungm.sh.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+wand/GraphicsMagickWand-config: $(top_builddir)/config.status $(top_srcdir)/wand/GraphicsMagickWand-config.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+wand/GraphicsMagickWand.pc: $(top_builddir)/config.status $(top_srcdir)/wand/GraphicsMagickWand.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+
+install-codersLTLIBRARIES: $(coders_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(coders_LTLIBRARIES)'; test -n "$(codersdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(codersdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(codersdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(codersdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(codersdir)"; \
+ }
+
+uninstall-codersLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(coders_LTLIBRARIES)'; test -n "$(codersdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(codersdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(codersdir)/$$f"; \
+ done
+
+clean-codersLTLIBRARIES:
+ -test -z "$(coders_LTLIBRARIES)" || rm -f $(coders_LTLIBRARIES)
+ @list='$(coders_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+install-filtersLTLIBRARIES: $(filters_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(filters_LTLIBRARIES)'; test -n "$(filtersdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(filtersdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(filtersdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(filtersdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(filtersdir)"; \
+ }
+
+uninstall-filtersLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(filters_LTLIBRARIES)'; test -n "$(filtersdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(filtersdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(filtersdir)/$$f"; \
+ done
+
+clean-filtersLTLIBRARIES:
+ -test -z "$(filters_LTLIBRARIES)" || rm -f $(filters_LTLIBRARIES)
+ @list='$(filters_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+Magick++/lib/$(am__dirstamp):
+ @$(MKDIR_P) Magick++/lib
+ @: > Magick++/lib/$(am__dirstamp)
+Magick++/lib/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) Magick++/lib/$(DEPDIR)
+ @: > Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Blob.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-BlobRef.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-CoderInfo.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Color.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Drawable.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Exception.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Functions.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Geometry.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Image.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-ImageRef.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Montage.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Options.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Pixels.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-STL.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Thread.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+Magick++/lib/Magick___lib_libGraphicsMagick___la-TypeMetric.lo: \
+ Magick++/lib/$(am__dirstamp) \
+ Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/lib/libGraphicsMagick++.la: $(Magick___lib_libGraphicsMagick___la_OBJECTS) $(Magick___lib_libGraphicsMagick___la_DEPENDENCIES) $(EXTRA_Magick___lib_libGraphicsMagick___la_DEPENDENCIES) Magick++/lib/$(am__dirstamp)
+ $(AM_V_CXXLD)$(Magick___lib_libGraphicsMagick___la_LINK) $(am_Magick___lib_libGraphicsMagick___la_rpath) $(Magick___lib_libGraphicsMagick___la_OBJECTS) $(Magick___lib_libGraphicsMagick___la_LIBADD) $(LIBS)
+coders/$(am__dirstamp):
+ @$(MKDIR_P) coders
+ @: > coders/$(am__dirstamp)
+coders/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) coders/$(DEPDIR)
+ @: > coders/$(DEPDIR)/$(am__dirstamp)
+coders/coders_art_la-art.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/art.la: $(coders_art_la_OBJECTS) $(coders_art_la_DEPENDENCIES) $(EXTRA_coders_art_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_art_la_LINK) $(am_coders_art_la_rpath) $(coders_art_la_OBJECTS) $(coders_art_la_LIBADD) $(LIBS)
+coders/coders_avs_la-avs.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/avs.la: $(coders_avs_la_OBJECTS) $(coders_avs_la_DEPENDENCIES) $(EXTRA_coders_avs_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_avs_la_LINK) $(am_coders_avs_la_rpath) $(coders_avs_la_OBJECTS) $(coders_avs_la_LIBADD) $(LIBS)
+coders/coders_bmp_la-bmp.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/bmp.la: $(coders_bmp_la_OBJECTS) $(coders_bmp_la_DEPENDENCIES) $(EXTRA_coders_bmp_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_bmp_la_LINK) $(am_coders_bmp_la_rpath) $(coders_bmp_la_OBJECTS) $(coders_bmp_la_LIBADD) $(LIBS)
+coders/coders_cals_la-cals.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/cals.la: $(coders_cals_la_OBJECTS) $(coders_cals_la_DEPENDENCIES) $(EXTRA_coders_cals_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_cals_la_LINK) $(am_coders_cals_la_rpath) $(coders_cals_la_OBJECTS) $(coders_cals_la_LIBADD) $(LIBS)
+coders/coders_caption_la-caption.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/caption.la: $(coders_caption_la_OBJECTS) $(coders_caption_la_DEPENDENCIES) $(EXTRA_coders_caption_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_caption_la_LINK) $(am_coders_caption_la_rpath) $(coders_caption_la_OBJECTS) $(coders_caption_la_LIBADD) $(LIBS)
+coders/coders_cineon_la-cineon.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/cineon.la: $(coders_cineon_la_OBJECTS) $(coders_cineon_la_DEPENDENCIES) $(EXTRA_coders_cineon_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_cineon_la_LINK) $(am_coders_cineon_la_rpath) $(coders_cineon_la_OBJECTS) $(coders_cineon_la_LIBADD) $(LIBS)
+coders/coders_clipboard_la-clipboard.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/clipboard.la: $(coders_clipboard_la_OBJECTS) $(coders_clipboard_la_DEPENDENCIES) $(EXTRA_coders_clipboard_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_clipboard_la_LINK) $(am_coders_clipboard_la_rpath) $(coders_clipboard_la_OBJECTS) $(coders_clipboard_la_LIBADD) $(LIBS)
+coders/coders_cmyk_la-cmyk.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/cmyk.la: $(coders_cmyk_la_OBJECTS) $(coders_cmyk_la_DEPENDENCIES) $(EXTRA_coders_cmyk_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_cmyk_la_LINK) $(am_coders_cmyk_la_rpath) $(coders_cmyk_la_OBJECTS) $(coders_cmyk_la_LIBADD) $(LIBS)
+coders/coders_cut_la-cut.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/cut.la: $(coders_cut_la_OBJECTS) $(coders_cut_la_DEPENDENCIES) $(EXTRA_coders_cut_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_cut_la_LINK) $(am_coders_cut_la_rpath) $(coders_cut_la_OBJECTS) $(coders_cut_la_LIBADD) $(LIBS)
+coders/coders_dcm_la-dcm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/dcm.la: $(coders_dcm_la_OBJECTS) $(coders_dcm_la_DEPENDENCIES) $(EXTRA_coders_dcm_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_dcm_la_LINK) $(am_coders_dcm_la_rpath) $(coders_dcm_la_OBJECTS) $(coders_dcm_la_LIBADD) $(LIBS)
+coders/coders_dcraw_la-dcraw.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/dcraw.la: $(coders_dcraw_la_OBJECTS) $(coders_dcraw_la_DEPENDENCIES) $(EXTRA_coders_dcraw_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_dcraw_la_LINK) $(am_coders_dcraw_la_rpath) $(coders_dcraw_la_OBJECTS) $(coders_dcraw_la_LIBADD) $(LIBS)
+coders/coders_dib_la-dib.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/dib.la: $(coders_dib_la_OBJECTS) $(coders_dib_la_DEPENDENCIES) $(EXTRA_coders_dib_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_dib_la_LINK) $(am_coders_dib_la_rpath) $(coders_dib_la_OBJECTS) $(coders_dib_la_LIBADD) $(LIBS)
+coders/coders_dps_la-dps.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/dps.la: $(coders_dps_la_OBJECTS) $(coders_dps_la_DEPENDENCIES) $(EXTRA_coders_dps_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_dps_la_LINK) $(am_coders_dps_la_rpath) $(coders_dps_la_OBJECTS) $(coders_dps_la_LIBADD) $(LIBS)
+coders/coders_dpx_la-dpx.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/dpx.la: $(coders_dpx_la_OBJECTS) $(coders_dpx_la_DEPENDENCIES) $(EXTRA_coders_dpx_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_dpx_la_LINK) $(am_coders_dpx_la_rpath) $(coders_dpx_la_OBJECTS) $(coders_dpx_la_LIBADD) $(LIBS)
+coders/coders_emf_la-emf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/emf.la: $(coders_emf_la_OBJECTS) $(coders_emf_la_DEPENDENCIES) $(EXTRA_coders_emf_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_emf_la_LINK) $(am_coders_emf_la_rpath) $(coders_emf_la_OBJECTS) $(coders_emf_la_LIBADD) $(LIBS)
+coders/ept.lo: coders/$(am__dirstamp) coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/ept.la: $(coders_ept_la_OBJECTS) $(coders_ept_la_DEPENDENCIES) $(EXTRA_coders_ept_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_ept_la_LINK) $(am_coders_ept_la_rpath) $(coders_ept_la_OBJECTS) $(coders_ept_la_LIBADD) $(LIBS)
+coders/coders_fax_la-fax.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/fax.la: $(coders_fax_la_OBJECTS) $(coders_fax_la_DEPENDENCIES) $(EXTRA_coders_fax_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_fax_la_LINK) $(am_coders_fax_la_rpath) $(coders_fax_la_OBJECTS) $(coders_fax_la_LIBADD) $(LIBS)
+coders/coders_fits_la-fits.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/fits.la: $(coders_fits_la_OBJECTS) $(coders_fits_la_DEPENDENCIES) $(EXTRA_coders_fits_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_fits_la_LINK) $(am_coders_fits_la_rpath) $(coders_fits_la_OBJECTS) $(coders_fits_la_LIBADD) $(LIBS)
+coders/coders_fpx_la-fpx.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/fpx.la: $(coders_fpx_la_OBJECTS) $(coders_fpx_la_DEPENDENCIES) $(EXTRA_coders_fpx_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_fpx_la_LINK) $(am_coders_fpx_la_rpath) $(coders_fpx_la_OBJECTS) $(coders_fpx_la_LIBADD) $(LIBS)
+coders/coders_gif_la-gif.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/gif.la: $(coders_gif_la_OBJECTS) $(coders_gif_la_DEPENDENCIES) $(EXTRA_coders_gif_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_gif_la_LINK) $(am_coders_gif_la_rpath) $(coders_gif_la_OBJECTS) $(coders_gif_la_LIBADD) $(LIBS)
+coders/coders_gradient_la-gradient.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/gradient.la: $(coders_gradient_la_OBJECTS) $(coders_gradient_la_DEPENDENCIES) $(EXTRA_coders_gradient_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_gradient_la_LINK) $(am_coders_gradient_la_rpath) $(coders_gradient_la_OBJECTS) $(coders_gradient_la_LIBADD) $(LIBS)
+coders/coders_gray_la-gray.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/gray.la: $(coders_gray_la_OBJECTS) $(coders_gray_la_DEPENDENCIES) $(EXTRA_coders_gray_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_gray_la_LINK) $(am_coders_gray_la_rpath) $(coders_gray_la_OBJECTS) $(coders_gray_la_LIBADD) $(LIBS)
+coders/coders_histogram_la-histogram.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/histogram.la: $(coders_histogram_la_OBJECTS) $(coders_histogram_la_DEPENDENCIES) $(EXTRA_coders_histogram_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_histogram_la_LINK) $(am_coders_histogram_la_rpath) $(coders_histogram_la_OBJECTS) $(coders_histogram_la_LIBADD) $(LIBS)
+coders/coders_hrz_la-hrz.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/hrz.la: $(coders_hrz_la_OBJECTS) $(coders_hrz_la_DEPENDENCIES) $(EXTRA_coders_hrz_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_hrz_la_LINK) $(am_coders_hrz_la_rpath) $(coders_hrz_la_OBJECTS) $(coders_hrz_la_LIBADD) $(LIBS)
+coders/coders_html_la-html.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/html.la: $(coders_html_la_OBJECTS) $(coders_html_la_DEPENDENCIES) $(EXTRA_coders_html_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_html_la_LINK) $(am_coders_html_la_rpath) $(coders_html_la_OBJECTS) $(coders_html_la_LIBADD) $(LIBS)
+coders/coders_icon_la-icon.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/icon.la: $(coders_icon_la_OBJECTS) $(coders_icon_la_DEPENDENCIES) $(EXTRA_coders_icon_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_icon_la_LINK) $(am_coders_icon_la_rpath) $(coders_icon_la_OBJECTS) $(coders_icon_la_LIBADD) $(LIBS)
+coders/coders_identity_la-identity.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/identity.la: $(coders_identity_la_OBJECTS) $(coders_identity_la_DEPENDENCIES) $(EXTRA_coders_identity_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_identity_la_LINK) $(am_coders_identity_la_rpath) $(coders_identity_la_OBJECTS) $(coders_identity_la_LIBADD) $(LIBS)
+coders/coders_info_la-info.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/info.la: $(coders_info_la_OBJECTS) $(coders_info_la_DEPENDENCIES) $(EXTRA_coders_info_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_info_la_LINK) $(am_coders_info_la_rpath) $(coders_info_la_OBJECTS) $(coders_info_la_LIBADD) $(LIBS)
+coders/coders_jbig_la-jbig.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/jbig.la: $(coders_jbig_la_OBJECTS) $(coders_jbig_la_DEPENDENCIES) $(EXTRA_coders_jbig_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_jbig_la_LINK) $(am_coders_jbig_la_rpath) $(coders_jbig_la_OBJECTS) $(coders_jbig_la_LIBADD) $(LIBS)
+coders/coders_jnx_la-jnx.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/jnx.la: $(coders_jnx_la_OBJECTS) $(coders_jnx_la_DEPENDENCIES) $(EXTRA_coders_jnx_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_jnx_la_LINK) $(am_coders_jnx_la_rpath) $(coders_jnx_la_OBJECTS) $(coders_jnx_la_LIBADD) $(LIBS)
+coders/coders_jp2_la-jp2.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/jp2.la: $(coders_jp2_la_OBJECTS) $(coders_jp2_la_DEPENDENCIES) $(EXTRA_coders_jp2_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_jp2_la_LINK) $(am_coders_jp2_la_rpath) $(coders_jp2_la_OBJECTS) $(coders_jp2_la_LIBADD) $(LIBS)
+coders/coders_jpeg_la-jpeg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/jpeg.la: $(coders_jpeg_la_OBJECTS) $(coders_jpeg_la_DEPENDENCIES) $(EXTRA_coders_jpeg_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_jpeg_la_LINK) $(am_coders_jpeg_la_rpath) $(coders_jpeg_la_OBJECTS) $(coders_jpeg_la_LIBADD) $(LIBS)
+coders/coders_label_la-label.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/label.la: $(coders_label_la_OBJECTS) $(coders_label_la_DEPENDENCIES) $(EXTRA_coders_label_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_label_la_LINK) $(am_coders_label_la_rpath) $(coders_label_la_OBJECTS) $(coders_label_la_LIBADD) $(LIBS)
+coders/coders_locale_la-locale.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/locale.la: $(coders_locale_la_OBJECTS) $(coders_locale_la_DEPENDENCIES) $(EXTRA_coders_locale_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_locale_la_LINK) $(am_coders_locale_la_rpath) $(coders_locale_la_OBJECTS) $(coders_locale_la_LIBADD) $(LIBS)
+coders/coders_logo_la-logo.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/logo.la: $(coders_logo_la_OBJECTS) $(coders_logo_la_DEPENDENCIES) $(EXTRA_coders_logo_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_logo_la_LINK) $(am_coders_logo_la_rpath) $(coders_logo_la_OBJECTS) $(coders_logo_la_LIBADD) $(LIBS)
+coders/coders_mac_la-mac.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/mac.la: $(coders_mac_la_OBJECTS) $(coders_mac_la_DEPENDENCIES) $(EXTRA_coders_mac_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_mac_la_LINK) $(am_coders_mac_la_rpath) $(coders_mac_la_OBJECTS) $(coders_mac_la_LIBADD) $(LIBS)
+coders/coders_map_la-map.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/map.la: $(coders_map_la_OBJECTS) $(coders_map_la_DEPENDENCIES) $(EXTRA_coders_map_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_map_la_LINK) $(am_coders_map_la_rpath) $(coders_map_la_OBJECTS) $(coders_map_la_LIBADD) $(LIBS)
+coders/coders_mat_la-mat.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/mat.la: $(coders_mat_la_OBJECTS) $(coders_mat_la_DEPENDENCIES) $(EXTRA_coders_mat_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_mat_la_LINK) $(am_coders_mat_la_rpath) $(coders_mat_la_OBJECTS) $(coders_mat_la_LIBADD) $(LIBS)
+coders/coders_matte_la-matte.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/matte.la: $(coders_matte_la_OBJECTS) $(coders_matte_la_DEPENDENCIES) $(EXTRA_coders_matte_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_matte_la_LINK) $(am_coders_matte_la_rpath) $(coders_matte_la_OBJECTS) $(coders_matte_la_LIBADD) $(LIBS)
+coders/coders_meta_la-meta.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/meta.la: $(coders_meta_la_OBJECTS) $(coders_meta_la_DEPENDENCIES) $(EXTRA_coders_meta_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_meta_la_LINK) $(am_coders_meta_la_rpath) $(coders_meta_la_OBJECTS) $(coders_meta_la_LIBADD) $(LIBS)
+coders/coders_miff_la-miff.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/miff.la: $(coders_miff_la_OBJECTS) $(coders_miff_la_DEPENDENCIES) $(EXTRA_coders_miff_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_miff_la_LINK) $(am_coders_miff_la_rpath) $(coders_miff_la_OBJECTS) $(coders_miff_la_LIBADD) $(LIBS)
+coders/coders_mono_la-mono.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/mono.la: $(coders_mono_la_OBJECTS) $(coders_mono_la_DEPENDENCIES) $(EXTRA_coders_mono_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_mono_la_LINK) $(am_coders_mono_la_rpath) $(coders_mono_la_OBJECTS) $(coders_mono_la_LIBADD) $(LIBS)
+coders/coders_mpc_la-mpc.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/mpc.la: $(coders_mpc_la_OBJECTS) $(coders_mpc_la_DEPENDENCIES) $(EXTRA_coders_mpc_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_mpc_la_LINK) $(am_coders_mpc_la_rpath) $(coders_mpc_la_OBJECTS) $(coders_mpc_la_LIBADD) $(LIBS)
+coders/coders_mpeg_la-mpeg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/mpeg.la: $(coders_mpeg_la_OBJECTS) $(coders_mpeg_la_DEPENDENCIES) $(EXTRA_coders_mpeg_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_mpeg_la_LINK) $(am_coders_mpeg_la_rpath) $(coders_mpeg_la_OBJECTS) $(coders_mpeg_la_LIBADD) $(LIBS)
+coders/coders_mpr_la-mpr.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/mpr.la: $(coders_mpr_la_OBJECTS) $(coders_mpr_la_DEPENDENCIES) $(EXTRA_coders_mpr_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_mpr_la_LINK) $(am_coders_mpr_la_rpath) $(coders_mpr_la_OBJECTS) $(coders_mpr_la_LIBADD) $(LIBS)
+coders/coders_msl_la-msl.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/msl.la: $(coders_msl_la_OBJECTS) $(coders_msl_la_DEPENDENCIES) $(EXTRA_coders_msl_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_msl_la_LINK) $(am_coders_msl_la_rpath) $(coders_msl_la_OBJECTS) $(coders_msl_la_LIBADD) $(LIBS)
+coders/coders_mtv_la-mtv.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/mtv.la: $(coders_mtv_la_OBJECTS) $(coders_mtv_la_DEPENDENCIES) $(EXTRA_coders_mtv_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_mtv_la_LINK) $(am_coders_mtv_la_rpath) $(coders_mtv_la_OBJECTS) $(coders_mtv_la_LIBADD) $(LIBS)
+coders/coders_mvg_la-mvg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/mvg.la: $(coders_mvg_la_OBJECTS) $(coders_mvg_la_DEPENDENCIES) $(EXTRA_coders_mvg_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_mvg_la_LINK) $(am_coders_mvg_la_rpath) $(coders_mvg_la_OBJECTS) $(coders_mvg_la_LIBADD) $(LIBS)
+coders/coders_null_la-null.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/null.la: $(coders_null_la_OBJECTS) $(coders_null_la_DEPENDENCIES) $(EXTRA_coders_null_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_null_la_LINK) $(am_coders_null_la_rpath) $(coders_null_la_OBJECTS) $(coders_null_la_LIBADD) $(LIBS)
+coders/coders_otb_la-otb.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/otb.la: $(coders_otb_la_OBJECTS) $(coders_otb_la_DEPENDENCIES) $(EXTRA_coders_otb_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_otb_la_LINK) $(am_coders_otb_la_rpath) $(coders_otb_la_OBJECTS) $(coders_otb_la_LIBADD) $(LIBS)
+coders/coders_palm_la-palm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/palm.la: $(coders_palm_la_OBJECTS) $(coders_palm_la_DEPENDENCIES) $(EXTRA_coders_palm_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_palm_la_LINK) $(am_coders_palm_la_rpath) $(coders_palm_la_OBJECTS) $(coders_palm_la_LIBADD) $(LIBS)
+coders/coders_pcd_la-pcd.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pcd.la: $(coders_pcd_la_OBJECTS) $(coders_pcd_la_DEPENDENCIES) $(EXTRA_coders_pcd_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pcd_la_LINK) $(am_coders_pcd_la_rpath) $(coders_pcd_la_OBJECTS) $(coders_pcd_la_LIBADD) $(LIBS)
+coders/coders_pcl_la-pcl.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pcl.la: $(coders_pcl_la_OBJECTS) $(coders_pcl_la_DEPENDENCIES) $(EXTRA_coders_pcl_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pcl_la_LINK) $(am_coders_pcl_la_rpath) $(coders_pcl_la_OBJECTS) $(coders_pcl_la_LIBADD) $(LIBS)
+coders/coders_pcx_la-pcx.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pcx.la: $(coders_pcx_la_OBJECTS) $(coders_pcx_la_DEPENDENCIES) $(EXTRA_coders_pcx_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pcx_la_LINK) $(am_coders_pcx_la_rpath) $(coders_pcx_la_OBJECTS) $(coders_pcx_la_LIBADD) $(LIBS)
+coders/coders_pdb_la-pdb.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pdb.la: $(coders_pdb_la_OBJECTS) $(coders_pdb_la_DEPENDENCIES) $(EXTRA_coders_pdb_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pdb_la_LINK) $(am_coders_pdb_la_rpath) $(coders_pdb_la_OBJECTS) $(coders_pdb_la_LIBADD) $(LIBS)
+coders/coders_pdf_la-pdf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pdf.la: $(coders_pdf_la_OBJECTS) $(coders_pdf_la_DEPENDENCIES) $(EXTRA_coders_pdf_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pdf_la_LINK) $(am_coders_pdf_la_rpath) $(coders_pdf_la_OBJECTS) $(coders_pdf_la_LIBADD) $(LIBS)
+coders/coders_pict_la-pict.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pict.la: $(coders_pict_la_OBJECTS) $(coders_pict_la_DEPENDENCIES) $(EXTRA_coders_pict_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pict_la_LINK) $(am_coders_pict_la_rpath) $(coders_pict_la_OBJECTS) $(coders_pict_la_LIBADD) $(LIBS)
+coders/coders_pix_la-pix.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pix.la: $(coders_pix_la_OBJECTS) $(coders_pix_la_DEPENDENCIES) $(EXTRA_coders_pix_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pix_la_LINK) $(am_coders_pix_la_rpath) $(coders_pix_la_OBJECTS) $(coders_pix_la_LIBADD) $(LIBS)
+coders/coders_plasma_la-plasma.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/plasma.la: $(coders_plasma_la_OBJECTS) $(coders_plasma_la_DEPENDENCIES) $(EXTRA_coders_plasma_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_plasma_la_LINK) $(am_coders_plasma_la_rpath) $(coders_plasma_la_OBJECTS) $(coders_plasma_la_LIBADD) $(LIBS)
+coders/coders_png_la-png.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/png.la: $(coders_png_la_OBJECTS) $(coders_png_la_DEPENDENCIES) $(EXTRA_coders_png_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_png_la_LINK) $(am_coders_png_la_rpath) $(coders_png_la_OBJECTS) $(coders_png_la_LIBADD) $(LIBS)
+coders/coders_pnm_la-pnm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pnm.la: $(coders_pnm_la_OBJECTS) $(coders_pnm_la_DEPENDENCIES) $(EXTRA_coders_pnm_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pnm_la_LINK) $(am_coders_pnm_la_rpath) $(coders_pnm_la_OBJECTS) $(coders_pnm_la_LIBADD) $(LIBS)
+coders/coders_preview_la-preview.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/preview.la: $(coders_preview_la_OBJECTS) $(coders_preview_la_DEPENDENCIES) $(EXTRA_coders_preview_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_preview_la_LINK) $(am_coders_preview_la_rpath) $(coders_preview_la_OBJECTS) $(coders_preview_la_LIBADD) $(LIBS)
+coders/coders_ps_la-ps.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/ps.la: $(coders_ps_la_OBJECTS) $(coders_ps_la_DEPENDENCIES) $(EXTRA_coders_ps_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_ps_la_LINK) $(am_coders_ps_la_rpath) $(coders_ps_la_OBJECTS) $(coders_ps_la_LIBADD) $(LIBS)
+coders/coders_ps2_la-ps2.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/ps2.la: $(coders_ps2_la_OBJECTS) $(coders_ps2_la_DEPENDENCIES) $(EXTRA_coders_ps2_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_ps2_la_LINK) $(am_coders_ps2_la_rpath) $(coders_ps2_la_OBJECTS) $(coders_ps2_la_LIBADD) $(LIBS)
+coders/coders_ps3_la-ps3.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/ps3.la: $(coders_ps3_la_OBJECTS) $(coders_ps3_la_DEPENDENCIES) $(EXTRA_coders_ps3_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_ps3_la_LINK) $(am_coders_ps3_la_rpath) $(coders_ps3_la_OBJECTS) $(coders_ps3_la_LIBADD) $(LIBS)
+coders/coders_psd_la-psd.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/psd.la: $(coders_psd_la_OBJECTS) $(coders_psd_la_DEPENDENCIES) $(EXTRA_coders_psd_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_psd_la_LINK) $(am_coders_psd_la_rpath) $(coders_psd_la_OBJECTS) $(coders_psd_la_LIBADD) $(LIBS)
+coders/coders_pwp_la-pwp.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/pwp.la: $(coders_pwp_la_OBJECTS) $(coders_pwp_la_DEPENDENCIES) $(EXTRA_coders_pwp_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_pwp_la_LINK) $(am_coders_pwp_la_rpath) $(coders_pwp_la_OBJECTS) $(coders_pwp_la_LIBADD) $(LIBS)
+coders/coders_rgb_la-rgb.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/rgb.la: $(coders_rgb_la_OBJECTS) $(coders_rgb_la_DEPENDENCIES) $(EXTRA_coders_rgb_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_rgb_la_LINK) $(am_coders_rgb_la_rpath) $(coders_rgb_la_OBJECTS) $(coders_rgb_la_LIBADD) $(LIBS)
+coders/coders_rla_la-rla.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/rla.la: $(coders_rla_la_OBJECTS) $(coders_rla_la_DEPENDENCIES) $(EXTRA_coders_rla_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_rla_la_LINK) $(am_coders_rla_la_rpath) $(coders_rla_la_OBJECTS) $(coders_rla_la_LIBADD) $(LIBS)
+coders/coders_rle_la-rle.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/rle.la: $(coders_rle_la_OBJECTS) $(coders_rle_la_DEPENDENCIES) $(EXTRA_coders_rle_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_rle_la_LINK) $(am_coders_rle_la_rpath) $(coders_rle_la_OBJECTS) $(coders_rle_la_LIBADD) $(LIBS)
+coders/coders_sct_la-sct.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/sct.la: $(coders_sct_la_OBJECTS) $(coders_sct_la_DEPENDENCIES) $(EXTRA_coders_sct_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_sct_la_LINK) $(am_coders_sct_la_rpath) $(coders_sct_la_OBJECTS) $(coders_sct_la_LIBADD) $(LIBS)
+coders/coders_sfw_la-sfw.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/sfw.la: $(coders_sfw_la_OBJECTS) $(coders_sfw_la_DEPENDENCIES) $(EXTRA_coders_sfw_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_sfw_la_LINK) $(am_coders_sfw_la_rpath) $(coders_sfw_la_OBJECTS) $(coders_sfw_la_LIBADD) $(LIBS)
+coders/coders_sgi_la-sgi.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/sgi.la: $(coders_sgi_la_OBJECTS) $(coders_sgi_la_DEPENDENCIES) $(EXTRA_coders_sgi_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_sgi_la_LINK) $(am_coders_sgi_la_rpath) $(coders_sgi_la_OBJECTS) $(coders_sgi_la_LIBADD) $(LIBS)
+coders/coders_stegano_la-stegano.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/stegano.la: $(coders_stegano_la_OBJECTS) $(coders_stegano_la_DEPENDENCIES) $(EXTRA_coders_stegano_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_stegano_la_LINK) $(am_coders_stegano_la_rpath) $(coders_stegano_la_OBJECTS) $(coders_stegano_la_LIBADD) $(LIBS)
+coders/coders_sun_la-sun.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/sun.la: $(coders_sun_la_OBJECTS) $(coders_sun_la_DEPENDENCIES) $(EXTRA_coders_sun_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_sun_la_LINK) $(am_coders_sun_la_rpath) $(coders_sun_la_OBJECTS) $(coders_sun_la_LIBADD) $(LIBS)
+coders/coders_svg_la-svg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/svg.la: $(coders_svg_la_OBJECTS) $(coders_svg_la_DEPENDENCIES) $(EXTRA_coders_svg_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_svg_la_LINK) $(am_coders_svg_la_rpath) $(coders_svg_la_OBJECTS) $(coders_svg_la_LIBADD) $(LIBS)
+coders/coders_tga_la-tga.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/tga.la: $(coders_tga_la_OBJECTS) $(coders_tga_la_DEPENDENCIES) $(EXTRA_coders_tga_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_tga_la_LINK) $(am_coders_tga_la_rpath) $(coders_tga_la_OBJECTS) $(coders_tga_la_LIBADD) $(LIBS)
+coders/coders_tiff_la-tiff.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/tiff.la: $(coders_tiff_la_OBJECTS) $(coders_tiff_la_DEPENDENCIES) $(EXTRA_coders_tiff_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_tiff_la_LINK) $(am_coders_tiff_la_rpath) $(coders_tiff_la_OBJECTS) $(coders_tiff_la_LIBADD) $(LIBS)
+coders/coders_tile_la-tile.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/tile.la: $(coders_tile_la_OBJECTS) $(coders_tile_la_DEPENDENCIES) $(EXTRA_coders_tile_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_tile_la_LINK) $(am_coders_tile_la_rpath) $(coders_tile_la_OBJECTS) $(coders_tile_la_LIBADD) $(LIBS)
+coders/coders_tim_la-tim.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/tim.la: $(coders_tim_la_OBJECTS) $(coders_tim_la_DEPENDENCIES) $(EXTRA_coders_tim_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_tim_la_LINK) $(am_coders_tim_la_rpath) $(coders_tim_la_OBJECTS) $(coders_tim_la_LIBADD) $(LIBS)
+coders/coders_topol_la-topol.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/topol.la: $(coders_topol_la_OBJECTS) $(coders_topol_la_DEPENDENCIES) $(EXTRA_coders_topol_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_topol_la_LINK) $(am_coders_topol_la_rpath) $(coders_topol_la_OBJECTS) $(coders_topol_la_LIBADD) $(LIBS)
+coders/coders_ttf_la-ttf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/ttf.la: $(coders_ttf_la_OBJECTS) $(coders_ttf_la_DEPENDENCIES) $(EXTRA_coders_ttf_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_ttf_la_LINK) $(am_coders_ttf_la_rpath) $(coders_ttf_la_OBJECTS) $(coders_ttf_la_LIBADD) $(LIBS)
+coders/coders_txt_la-txt.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/txt.la: $(coders_txt_la_OBJECTS) $(coders_txt_la_DEPENDENCIES) $(EXTRA_coders_txt_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_txt_la_LINK) $(am_coders_txt_la_rpath) $(coders_txt_la_OBJECTS) $(coders_txt_la_LIBADD) $(LIBS)
+coders/coders_uil_la-uil.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/uil.la: $(coders_uil_la_OBJECTS) $(coders_uil_la_DEPENDENCIES) $(EXTRA_coders_uil_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_uil_la_LINK) $(am_coders_uil_la_rpath) $(coders_uil_la_OBJECTS) $(coders_uil_la_LIBADD) $(LIBS)
+coders/coders_url_la-url.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/url.la: $(coders_url_la_OBJECTS) $(coders_url_la_DEPENDENCIES) $(EXTRA_coders_url_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_url_la_LINK) $(am_coders_url_la_rpath) $(coders_url_la_OBJECTS) $(coders_url_la_LIBADD) $(LIBS)
+coders/coders_uyvy_la-uyvy.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/uyvy.la: $(coders_uyvy_la_OBJECTS) $(coders_uyvy_la_DEPENDENCIES) $(EXTRA_coders_uyvy_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_uyvy_la_LINK) $(am_coders_uyvy_la_rpath) $(coders_uyvy_la_OBJECTS) $(coders_uyvy_la_LIBADD) $(LIBS)
+coders/coders_vicar_la-vicar.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/vicar.la: $(coders_vicar_la_OBJECTS) $(coders_vicar_la_DEPENDENCIES) $(EXTRA_coders_vicar_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_vicar_la_LINK) $(am_coders_vicar_la_rpath) $(coders_vicar_la_OBJECTS) $(coders_vicar_la_LIBADD) $(LIBS)
+coders/coders_vid_la-vid.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/vid.la: $(coders_vid_la_OBJECTS) $(coders_vid_la_DEPENDENCIES) $(EXTRA_coders_vid_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_vid_la_LINK) $(am_coders_vid_la_rpath) $(coders_vid_la_OBJECTS) $(coders_vid_la_LIBADD) $(LIBS)
+coders/coders_viff_la-viff.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/viff.la: $(coders_viff_la_OBJECTS) $(coders_viff_la_DEPENDENCIES) $(EXTRA_coders_viff_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_viff_la_LINK) $(am_coders_viff_la_rpath) $(coders_viff_la_OBJECTS) $(coders_viff_la_LIBADD) $(LIBS)
+coders/coders_wbmp_la-wbmp.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/wbmp.la: $(coders_wbmp_la_OBJECTS) $(coders_wbmp_la_DEPENDENCIES) $(EXTRA_coders_wbmp_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_wbmp_la_LINK) $(am_coders_wbmp_la_rpath) $(coders_wbmp_la_OBJECTS) $(coders_wbmp_la_LIBADD) $(LIBS)
+coders/coders_webp_la-webp.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/webp.la: $(coders_webp_la_OBJECTS) $(coders_webp_la_DEPENDENCIES) $(EXTRA_coders_webp_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_webp_la_LINK) $(am_coders_webp_la_rpath) $(coders_webp_la_OBJECTS) $(coders_webp_la_LIBADD) $(LIBS)
+coders/coders_wmf_la-wmf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/wmf.la: $(coders_wmf_la_OBJECTS) $(coders_wmf_la_DEPENDENCIES) $(EXTRA_coders_wmf_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_wmf_la_LINK) $(am_coders_wmf_la_rpath) $(coders_wmf_la_OBJECTS) $(coders_wmf_la_LIBADD) $(LIBS)
+coders/coders_wpg_la-wpg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/wpg.la: $(coders_wpg_la_OBJECTS) $(coders_wpg_la_DEPENDENCIES) $(EXTRA_coders_wpg_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_wpg_la_LINK) $(am_coders_wpg_la_rpath) $(coders_wpg_la_OBJECTS) $(coders_wpg_la_LIBADD) $(LIBS)
+coders/coders_x_la-x.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/x.la: $(coders_x_la_OBJECTS) $(coders_x_la_DEPENDENCIES) $(EXTRA_coders_x_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_x_la_LINK) $(am_coders_x_la_rpath) $(coders_x_la_OBJECTS) $(coders_x_la_LIBADD) $(LIBS)
+coders/coders_xbm_la-xbm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/xbm.la: $(coders_xbm_la_OBJECTS) $(coders_xbm_la_DEPENDENCIES) $(EXTRA_coders_xbm_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_xbm_la_LINK) $(am_coders_xbm_la_rpath) $(coders_xbm_la_OBJECTS) $(coders_xbm_la_LIBADD) $(LIBS)
+coders/coders_xc_la-xc.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/xc.la: $(coders_xc_la_OBJECTS) $(coders_xc_la_DEPENDENCIES) $(EXTRA_coders_xc_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_xc_la_LINK) $(am_coders_xc_la_rpath) $(coders_xc_la_OBJECTS) $(coders_xc_la_LIBADD) $(LIBS)
+coders/coders_xcf_la-xcf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/xcf.la: $(coders_xcf_la_OBJECTS) $(coders_xcf_la_DEPENDENCIES) $(EXTRA_coders_xcf_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_xcf_la_LINK) $(am_coders_xcf_la_rpath) $(coders_xcf_la_OBJECTS) $(coders_xcf_la_LIBADD) $(LIBS)
+coders/coders_xpm_la-xpm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/xpm.la: $(coders_xpm_la_OBJECTS) $(coders_xpm_la_DEPENDENCIES) $(EXTRA_coders_xpm_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_xpm_la_LINK) $(am_coders_xpm_la_rpath) $(coders_xpm_la_OBJECTS) $(coders_xpm_la_LIBADD) $(LIBS)
+coders/coders_xwd_la-xwd.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/xwd.la: $(coders_xwd_la_OBJECTS) $(coders_xwd_la_DEPENDENCIES) $(EXTRA_coders_xwd_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_xwd_la_LINK) $(am_coders_xwd_la_rpath) $(coders_xwd_la_OBJECTS) $(coders_xwd_la_LIBADD) $(LIBS)
+coders/coders_yuv_la-yuv.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+
+coders/yuv.la: $(coders_yuv_la_OBJECTS) $(coders_yuv_la_DEPENDENCIES) $(EXTRA_coders_yuv_la_DEPENDENCIES) coders/$(am__dirstamp)
+ $(AM_V_CCLD)$(coders_yuv_la_LINK) $(am_coders_yuv_la_rpath) $(coders_yuv_la_OBJECTS) $(coders_yuv_la_LIBADD) $(LIBS)
+filters/$(am__dirstamp):
+ @$(MKDIR_P) filters
+ @: > filters/$(am__dirstamp)
+filters/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) filters/$(DEPDIR)
+ @: > filters/$(DEPDIR)/$(am__dirstamp)
+filters/filters_analyze_la-analyze.lo: filters/$(am__dirstamp) \
+ filters/$(DEPDIR)/$(am__dirstamp)
+
+filters/analyze.la: $(filters_analyze_la_OBJECTS) $(filters_analyze_la_DEPENDENCIES) $(EXTRA_filters_analyze_la_DEPENDENCIES) filters/$(am__dirstamp)
+ $(AM_V_CCLD)$(filters_analyze_la_LINK) $(am_filters_analyze_la_rpath) $(filters_analyze_la_OBJECTS) $(filters_analyze_la_LIBADD) $(LIBS)
+magick/$(am__dirstamp):
+ @$(MKDIR_P) magick
+ @: > magick/$(am__dirstamp)
+magick/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) magick/$(DEPDIR)
+ @: > magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-analyze.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-annotate.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-attribute.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-average.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-bit_stream.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-blob.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-cdl.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-channel.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-compare.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-confirm_access.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-color.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-color_lookup.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-colormap.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-colorspace.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-command.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-composite.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-compress.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-constitute.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-decorate.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-delegate.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-deprecate.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-describe.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-draw.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-effect.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-enhance.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-enum_strings.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-error.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-export.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-floats.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-fx.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-gem.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-gradient.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-hclut.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-image.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-import.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-list.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-locale.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-log.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-magic.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-magick.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-magick_endian.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-map.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-memory.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-module.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-monitor.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-montage.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-omp_data_view.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-operator.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-paint.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-pixel_cache.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-pixel_iterator.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-plasma.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-profile.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-quantize.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-registry.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-random.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-render.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-resize.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-resource.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-segment.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-semaphore.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-shear.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-signature.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-static.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-statistics.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-tempfile.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-texture.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-timer.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-transform.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-tsd.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-type.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-unix_port.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-utility.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-version.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-animate.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-display.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-PreRvIcccm.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-widget.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-xwindow.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-nt_feature.lo: \
+ magick/$(am__dirstamp) magick/$(DEPDIR)/$(am__dirstamp)
+magick/magick_libGraphicsMagick_la-nt_base.lo: magick/$(am__dirstamp) \
+ magick/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-png.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-art.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-avs.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-bmp.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-cals.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-caption.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-cineon.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-cmyk.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-cut.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-dcm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-dcraw.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-dib.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-dpx.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-fax.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-fits.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-gif.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-gradient.lo: \
+ coders/$(am__dirstamp) coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-gray.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-histogram.lo: \
+ coders/$(am__dirstamp) coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-hrz.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-html.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-icon.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-identity.lo: \
+ coders/$(am__dirstamp) coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-info.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-label.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-locale.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-logo.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-mac.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-map.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-mat.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-matte.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-meta.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-miff.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-mono.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-mpc.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-mpeg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-mpr.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-msl.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-mtv.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-mvg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-null.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-otb.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-palm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pcd.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pcl.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pcx.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pdb.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pdf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pict.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pix.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-plasma.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pnm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-preview.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-ps.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-ps2.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-ps3.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-pwp.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-rgb.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-rla.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-rle.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-sct.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-sfw.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-sgi.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-stegano.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-sun.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-svg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-tga.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-tile.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-tim.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-topol.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-ttf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-txt.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-uil.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-url.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-uyvy.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-vicar.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-vid.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-viff.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-wbmp.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-wmf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-wpg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-xbm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-xc.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-xcf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-xpm.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-yuv.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-psd.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-dps.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-clipboard.lo: \
+ coders/$(am__dirstamp) coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-emf.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-fpx.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-jbig.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-jnx.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-jpeg.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-jp2.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-ept.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-tiff.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-x.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-xwd.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+coders/magick_libGraphicsMagick_la-webp.lo: coders/$(am__dirstamp) \
+ coders/$(DEPDIR)/$(am__dirstamp)
+filters/magick_libGraphicsMagick_la-analyze.lo: \
+ filters/$(am__dirstamp) filters/$(DEPDIR)/$(am__dirstamp)
+
+magick/libGraphicsMagick.la: $(magick_libGraphicsMagick_la_OBJECTS) $(magick_libGraphicsMagick_la_DEPENDENCIES) $(EXTRA_magick_libGraphicsMagick_la_DEPENDENCIES) magick/$(am__dirstamp)
+ $(AM_V_CCLD)$(magick_libGraphicsMagick_la_LINK) -rpath $(libdir) $(magick_libGraphicsMagick_la_OBJECTS) $(magick_libGraphicsMagick_la_LIBADD) $(LIBS)
+wand/$(am__dirstamp):
+ @$(MKDIR_P) wand
+ @: > wand/$(am__dirstamp)
+wand/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) wand/$(DEPDIR)
+ @: > wand/$(DEPDIR)/$(am__dirstamp)
+wand/wand_libGraphicsMagickWand_la-drawing_wand.lo: \
+ wand/$(am__dirstamp) wand/$(DEPDIR)/$(am__dirstamp)
+wand/wand_libGraphicsMagickWand_la-magick_compat.lo: \
+ wand/$(am__dirstamp) wand/$(DEPDIR)/$(am__dirstamp)
+wand/wand_libGraphicsMagickWand_la-magick_wand.lo: \
+ wand/$(am__dirstamp) wand/$(DEPDIR)/$(am__dirstamp)
+wand/wand_libGraphicsMagickWand_la-pixel_wand.lo: \
+ wand/$(am__dirstamp) wand/$(DEPDIR)/$(am__dirstamp)
+
+wand/libGraphicsMagickWand.la: $(wand_libGraphicsMagickWand_la_OBJECTS) $(wand_libGraphicsMagickWand_la_DEPENDENCIES) $(EXTRA_wand_libGraphicsMagickWand_la_DEPENDENCIES) wand/$(am__dirstamp)
+ $(AM_V_CCLD)$(wand_libGraphicsMagickWand_la_LINK) -rpath $(libdir) $(wand_libGraphicsMagickWand_la_OBJECTS) $(wand_libGraphicsMagickWand_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+Magick++/demo/$(am__dirstamp):
+ @$(MKDIR_P) Magick++/demo
+ @: > Magick++/demo/$(am__dirstamp)
+Magick++/demo/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) Magick++/demo/$(DEPDIR)
+ @: > Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+Magick++/demo/Magick___demo_analyze-analyze.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/analyze$(EXEEXT): $(Magick___demo_analyze_OBJECTS) $(Magick___demo_analyze_DEPENDENCIES) $(EXTRA_Magick___demo_analyze_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/analyze$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_analyze_OBJECTS) $(Magick___demo_analyze_LDADD) $(LIBS)
+Magick++/demo/Magick___demo_button-button.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/button$(EXEEXT): $(Magick___demo_button_OBJECTS) $(Magick___demo_button_DEPENDENCIES) $(EXTRA_Magick___demo_button_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/button$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_button_OBJECTS) $(Magick___demo_button_LDADD) $(LIBS)
+Magick++/demo/Magick___demo_demo-demo.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/demo$(EXEEXT): $(Magick___demo_demo_OBJECTS) $(Magick___demo_demo_DEPENDENCIES) $(EXTRA_Magick___demo_demo_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/demo$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_demo_OBJECTS) $(Magick___demo_demo_LDADD) $(LIBS)
+Magick++/demo/Magick___demo_detrans-detrans.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/detrans$(EXEEXT): $(Magick___demo_detrans_OBJECTS) $(Magick___demo_detrans_DEPENDENCIES) $(EXTRA_Magick___demo_detrans_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/detrans$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_detrans_OBJECTS) $(Magick___demo_detrans_LDADD) $(LIBS)
+Magick++/demo/Magick___demo_flip-flip.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/flip$(EXEEXT): $(Magick___demo_flip_OBJECTS) $(Magick___demo_flip_DEPENDENCIES) $(EXTRA_Magick___demo_flip_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/flip$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_flip_OBJECTS) $(Magick___demo_flip_LDADD) $(LIBS)
+Magick++/demo/Magick___demo_gravity-gravity.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/gravity$(EXEEXT): $(Magick___demo_gravity_OBJECTS) $(Magick___demo_gravity_DEPENDENCIES) $(EXTRA_Magick___demo_gravity_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/gravity$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_gravity_OBJECTS) $(Magick___demo_gravity_LDADD) $(LIBS)
+Magick++/demo/Magick___demo_piddle-piddle.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/piddle$(EXEEXT): $(Magick___demo_piddle_OBJECTS) $(Magick___demo_piddle_DEPENDENCIES) $(EXTRA_Magick___demo_piddle_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/piddle$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_piddle_OBJECTS) $(Magick___demo_piddle_LDADD) $(LIBS)
+Magick++/demo/Magick___demo_shapes-shapes.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/shapes$(EXEEXT): $(Magick___demo_shapes_OBJECTS) $(Magick___demo_shapes_DEPENDENCIES) $(EXTRA_Magick___demo_shapes_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/shapes$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_shapes_OBJECTS) $(Magick___demo_shapes_LDADD) $(LIBS)
+Magick++/demo/Magick___demo_zoom-zoom.$(OBJEXT): \
+ Magick++/demo/$(am__dirstamp) \
+ Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/demo/zoom$(EXEEXT): $(Magick___demo_zoom_OBJECTS) $(Magick___demo_zoom_DEPENDENCIES) $(EXTRA_Magick___demo_zoom_DEPENDENCIES) Magick++/demo/$(am__dirstamp)
+ @rm -f Magick++/demo/zoom$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___demo_zoom_OBJECTS) $(Magick___demo_zoom_LDADD) $(LIBS)
+Magick++/tests/$(am__dirstamp):
+ @$(MKDIR_P) Magick++/tests
+ @: > Magick++/tests/$(am__dirstamp)
+Magick++/tests/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) Magick++/tests/$(DEPDIR)
+ @: > Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+Magick++/tests/Magick___tests_appendImages-appendImages.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/appendImages$(EXEEXT): $(Magick___tests_appendImages_OBJECTS) $(Magick___tests_appendImages_DEPENDENCIES) $(EXTRA_Magick___tests_appendImages_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/appendImages$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_appendImages_OBJECTS) $(Magick___tests_appendImages_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_attributes-attributes.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/attributes$(EXEEXT): $(Magick___tests_attributes_OBJECTS) $(Magick___tests_attributes_DEPENDENCIES) $(EXTRA_Magick___tests_attributes_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/attributes$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_attributes_OBJECTS) $(Magick___tests_attributes_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_averageImages-averageImages.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/averageImages$(EXEEXT): $(Magick___tests_averageImages_OBJECTS) $(Magick___tests_averageImages_DEPENDENCIES) $(EXTRA_Magick___tests_averageImages_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/averageImages$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_averageImages_OBJECTS) $(Magick___tests_averageImages_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_coalesceImages-coalesceImages.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/coalesceImages$(EXEEXT): $(Magick___tests_coalesceImages_OBJECTS) $(Magick___tests_coalesceImages_DEPENDENCIES) $(EXTRA_Magick___tests_coalesceImages_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/coalesceImages$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_coalesceImages_OBJECTS) $(Magick___tests_coalesceImages_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_coderInfo-coderInfo.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/coderInfo$(EXEEXT): $(Magick___tests_coderInfo_OBJECTS) $(Magick___tests_coderInfo_DEPENDENCIES) $(EXTRA_Magick___tests_coderInfo_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/coderInfo$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_coderInfo_OBJECTS) $(Magick___tests_coderInfo_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_color-color.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/color$(EXEEXT): $(Magick___tests_color_OBJECTS) $(Magick___tests_color_DEPENDENCIES) $(EXTRA_Magick___tests_color_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/color$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_color_OBJECTS) $(Magick___tests_color_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_colorHistogram-colorHistogram.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/colorHistogram$(EXEEXT): $(Magick___tests_colorHistogram_OBJECTS) $(Magick___tests_colorHistogram_DEPENDENCIES) $(EXTRA_Magick___tests_colorHistogram_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/colorHistogram$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_colorHistogram_OBJECTS) $(Magick___tests_colorHistogram_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_exceptions-exceptions.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/exceptions$(EXEEXT): $(Magick___tests_exceptions_OBJECTS) $(Magick___tests_exceptions_DEPENDENCIES) $(EXTRA_Magick___tests_exceptions_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/exceptions$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_exceptions_OBJECTS) $(Magick___tests_exceptions_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_montageImages-montageImages.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/montageImages$(EXEEXT): $(Magick___tests_montageImages_OBJECTS) $(Magick___tests_montageImages_DEPENDENCIES) $(EXTRA_Magick___tests_montageImages_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/montageImages$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_montageImages_OBJECTS) $(Magick___tests_montageImages_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_morphImages-morphImages.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/morphImages$(EXEEXT): $(Magick___tests_morphImages_OBJECTS) $(Magick___tests_morphImages_DEPENDENCIES) $(EXTRA_Magick___tests_morphImages_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/morphImages$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_morphImages_OBJECTS) $(Magick___tests_morphImages_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/readWriteBlob$(EXEEXT): $(Magick___tests_readWriteBlob_OBJECTS) $(Magick___tests_readWriteBlob_DEPENDENCIES) $(EXTRA_Magick___tests_readWriteBlob_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/readWriteBlob$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_readWriteBlob_OBJECTS) $(Magick___tests_readWriteBlob_LDADD) $(LIBS)
+Magick++/tests/Magick___tests_readWriteImages-readWriteImages.$(OBJEXT): \
+ Magick++/tests/$(am__dirstamp) \
+ Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+
+Magick++/tests/readWriteImages$(EXEEXT): $(Magick___tests_readWriteImages_OBJECTS) $(Magick___tests_readWriteImages_DEPENDENCIES) $(EXTRA_Magick___tests_readWriteImages_DEPENDENCIES) Magick++/tests/$(am__dirstamp)
+ @rm -f Magick++/tests/readWriteImages$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(Magick___tests_readWriteImages_OBJECTS) $(Magick___tests_readWriteImages_LDADD) $(LIBS)
+tests/$(am__dirstamp):
+ @$(MKDIR_P) tests
+ @: > tests/$(am__dirstamp)
+tests/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) tests/$(DEPDIR)
+ @: > tests/$(DEPDIR)/$(am__dirstamp)
+tests/tests_bitstream-bitstream.$(OBJEXT): tests/$(am__dirstamp) \
+ tests/$(DEPDIR)/$(am__dirstamp)
+
+tests/bitstream$(EXEEXT): $(tests_bitstream_OBJECTS) $(tests_bitstream_DEPENDENCIES) $(EXTRA_tests_bitstream_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/bitstream$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_bitstream_OBJECTS) $(tests_bitstream_LDADD) $(LIBS)
+tests/tests_constitute-constitute.$(OBJEXT): tests/$(am__dirstamp) \
+ tests/$(DEPDIR)/$(am__dirstamp)
+
+tests/constitute$(EXEEXT): $(tests_constitute_OBJECTS) $(tests_constitute_DEPENDENCIES) $(EXTRA_tests_constitute_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/constitute$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_constitute_OBJECTS) $(tests_constitute_LDADD) $(LIBS)
+tests/tests_drawtest-drawtest.$(OBJEXT): tests/$(am__dirstamp) \
+ tests/$(DEPDIR)/$(am__dirstamp)
+
+tests/drawtest$(EXEEXT): $(tests_drawtest_OBJECTS) $(tests_drawtest_DEPENDENCIES) $(EXTRA_tests_drawtest_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/drawtest$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_drawtest_OBJECTS) $(tests_drawtest_LDADD) $(LIBS)
+tests/tests_maptest-maptest.$(OBJEXT): tests/$(am__dirstamp) \
+ tests/$(DEPDIR)/$(am__dirstamp)
+
+tests/maptest$(EXEEXT): $(tests_maptest_OBJECTS) $(tests_maptest_DEPENDENCIES) $(EXTRA_tests_maptest_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/maptest$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_maptest_OBJECTS) $(tests_maptest_LDADD) $(LIBS)
+tests/tests_rwblob-rwblob.$(OBJEXT): tests/$(am__dirstamp) \
+ tests/$(DEPDIR)/$(am__dirstamp)
+
+tests/rwblob$(EXEEXT): $(tests_rwblob_OBJECTS) $(tests_rwblob_DEPENDENCIES) $(EXTRA_tests_rwblob_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/rwblob$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_rwblob_OBJECTS) $(tests_rwblob_LDADD) $(LIBS)
+tests/tests_rwfile-rwfile.$(OBJEXT): tests/$(am__dirstamp) \
+ tests/$(DEPDIR)/$(am__dirstamp)
+
+tests/rwfile$(EXEEXT): $(tests_rwfile_OBJECTS) $(tests_rwfile_DEPENDENCIES) $(EXTRA_tests_rwfile_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/rwfile$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_rwfile_OBJECTS) $(tests_rwfile_LDADD) $(LIBS)
+utilities/$(am__dirstamp):
+ @$(MKDIR_P) utilities
+ @: > utilities/$(am__dirstamp)
+utilities/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) utilities/$(DEPDIR)
+ @: > utilities/$(DEPDIR)/$(am__dirstamp)
+utilities/gm.$(OBJEXT): utilities/$(am__dirstamp) \
+ utilities/$(DEPDIR)/$(am__dirstamp)
+
+utilities/gm$(EXEEXT): $(utilities_gm_OBJECTS) $(utilities_gm_DEPENDENCIES) $(EXTRA_utilities_gm_DEPENDENCIES) utilities/$(am__dirstamp)
+ @rm -f utilities/gm$(EXEEXT)
+ $(AM_V_CCLD)$(utilities_gm_LINK) $(utilities_gm_OBJECTS) $(utilities_gm_LDADD) $(LIBS)
+wand/wand_drawtest-drawtest.$(OBJEXT): wand/$(am__dirstamp) \
+ wand/$(DEPDIR)/$(am__dirstamp)
+
+wand/drawtest$(EXEEXT): $(wand_drawtest_OBJECTS) $(wand_drawtest_DEPENDENCIES) $(EXTRA_wand_drawtest_DEPENDENCIES) wand/$(am__dirstamp)
+ @rm -f wand/drawtest$(EXEEXT)
+ $(AM_V_CCLD)$(wand_drawtest_LINK) $(wand_drawtest_OBJECTS) $(wand_drawtest_LDADD) $(LIBS)
+wand/wand_wandtest-wandtest.$(OBJEXT): wand/$(am__dirstamp) \
+ wand/$(DEPDIR)/$(am__dirstamp)
+
+wand/wandtest$(EXEEXT): $(wand_wandtest_OBJECTS) $(wand_wandtest_DEPENDENCIES) $(EXTRA_wand_wandtest_DEPENDENCIES) wand/$(am__dirstamp)
+ @rm -f wand/wandtest$(EXEEXT)
+ $(AM_V_CCLD)$(wand_wandtest_LINK) $(wand_wandtest_OBJECTS) $(wand_wandtest_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f Magick++/demo/*.$(OBJEXT)
+ -rm -f Magick++/lib/*.$(OBJEXT)
+ -rm -f Magick++/lib/*.lo
+ -rm -f Magick++/tests/*.$(OBJEXT)
+ -rm -f coders/*.$(OBJEXT)
+ -rm -f coders/*.lo
+ -rm -f filters/*.$(OBJEXT)
+ -rm -f filters/*.lo
+ -rm -f magick/*.$(OBJEXT)
+ -rm -f magick/*.lo
+ -rm -f tests/*.$(OBJEXT)
+ -rm -f utilities/*.$(OBJEXT)
+ -rm -f wand/*.$(OBJEXT)
+ -rm -f wand/*.lo
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_analyze-analyze.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_button-button.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_demo-demo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_detrans-detrans.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_flip-flip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_gravity-gravity.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_piddle-piddle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_shapes-shapes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/demo/$(DEPDIR)/Magick___demo_zoom-zoom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Blob.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-BlobRef.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-CoderInfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Color.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Drawable.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Exception.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Functions.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Geometry.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Image.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-ImageRef.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Montage.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Options.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Pixels.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-STL.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Thread.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-TypeMetric.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_appendImages-appendImages.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_attributes-attributes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_averageImages-averageImages.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_coalesceImages-coalesceImages.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_coderInfo-coderInfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_color-color.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_colorHistogram-colorHistogram.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_exceptions-exceptions.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_montageImages-montageImages.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_morphImages-morphImages.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_readWriteBlob-readWriteBlob.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Magick++/tests/$(DEPDIR)/Magick___tests_readWriteImages-readWriteImages.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_art_la-art.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_avs_la-avs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_bmp_la-bmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_cals_la-cals.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_caption_la-caption.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_cineon_la-cineon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_clipboard_la-clipboard.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_cmyk_la-cmyk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_cut_la-cut.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_dcm_la-dcm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_dcraw_la-dcraw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_dib_la-dib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_dps_la-dps.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_dpx_la-dpx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_emf_la-emf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_fax_la-fax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_fits_la-fits.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_fpx_la-fpx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_gif_la-gif.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_gradient_la-gradient.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_gray_la-gray.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_histogram_la-histogram.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_hrz_la-hrz.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_html_la-html.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_icon_la-icon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_identity_la-identity.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_info_la-info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_jbig_la-jbig.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_jnx_la-jnx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_jp2_la-jp2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_jpeg_la-jpeg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_label_la-label.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_locale_la-locale.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_logo_la-logo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_mac_la-mac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_map_la-map.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_mat_la-mat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_matte_la-matte.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_meta_la-meta.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_miff_la-miff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_mono_la-mono.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_mpc_la-mpc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_mpeg_la-mpeg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_mpr_la-mpr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_msl_la-msl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_mtv_la-mtv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_mvg_la-mvg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_null_la-null.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_otb_la-otb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_palm_la-palm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pcd_la-pcd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pcl_la-pcl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pcx_la-pcx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pdb_la-pdb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pdf_la-pdf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pict_la-pict.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pix_la-pix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_plasma_la-plasma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_png_la-png.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pnm_la-pnm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_preview_la-preview.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_ps2_la-ps2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_ps3_la-ps3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_ps_la-ps.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_psd_la-psd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_pwp_la-pwp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_rgb_la-rgb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_rla_la-rla.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_rle_la-rle.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_sct_la-sct.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_sfw_la-sfw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_sgi_la-sgi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_stegano_la-stegano.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_sun_la-sun.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_svg_la-svg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_tga_la-tga.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_tiff_la-tiff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_tile_la-tile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_tim_la-tim.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_topol_la-topol.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_ttf_la-ttf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_txt_la-txt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_uil_la-uil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_url_la-url.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_uyvy_la-uyvy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_vicar_la-vicar.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_vid_la-vid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_viff_la-viff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_wbmp_la-wbmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_webp_la-webp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_wmf_la-wmf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_wpg_la-wpg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_x_la-x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_xbm_la-xbm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_xc_la-xc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_xcf_la-xcf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_xpm_la-xpm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_xwd_la-xwd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/coders_yuv_la-yuv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/ept.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-art.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-avs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-bmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-cals.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-caption.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-cineon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-clipboard.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-cmyk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-cut.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-dcm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-dcraw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-dib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-dps.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-dpx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-emf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-ept.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-fax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-fits.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-fpx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-gif.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-gradient.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-gray.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-histogram.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-hrz.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-html.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-icon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-identity.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-jbig.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-jnx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-jp2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-jpeg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-label.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-locale.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-logo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-mac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-map.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-mat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-matte.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-meta.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-miff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-mono.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpeg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-msl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-mtv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-mvg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-null.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-otb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-palm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pdb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pdf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pict.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-plasma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-png.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pnm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-preview.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-psd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-pwp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-rgb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-rla.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-rle.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-sct.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-sfw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-sgi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-stegano.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-sun.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-svg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-tga.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-tiff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-tile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-tim.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-topol.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-ttf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-txt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-uil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-url.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-uyvy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-vicar.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-vid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-viff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-wbmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-webp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-wmf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-wpg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-xbm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-xc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-xcf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-xpm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-xwd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@coders/$(DEPDIR)/magick_libGraphicsMagick_la-yuv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@filters/$(DEPDIR)/filters_analyze_la-analyze.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@filters/$(DEPDIR)/magick_libGraphicsMagick_la-analyze.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-PreRvIcccm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-analyze.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-animate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-annotate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-attribute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-average.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-bit_stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-blob.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-cdl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-channel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-color.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-color_lookup.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-colormap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-colorspace.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-command.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-compare.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-composite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-compress.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-confirm_access.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-constitute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-decorate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-delegate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-deprecate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-describe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-display.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-draw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-effect.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-enhance.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-enum_strings.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-export.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-floats.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-fx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-gem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-gradient.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-hclut.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-image.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-import.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-list.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-locale.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-log.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-magic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-magick.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-magick_endian.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-map.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-memory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-module.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-monitor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-montage.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-nt_base.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-nt_feature.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-omp_data_view.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-operator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-paint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-pixel_cache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-pixel_iterator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-plasma.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-profile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-quantize.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-random.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-registry.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-render.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-resize.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-resource.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-segment.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-semaphore.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-shear.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-signature.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-static.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-statistics.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-tempfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-texture.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-timer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-transform.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-tsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-type.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-unix_port.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-utility.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-version.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-widget.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@magick/$(DEPDIR)/magick_libGraphicsMagick_la-xwindow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_bitstream-bitstream.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_constitute-constitute.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_drawtest-drawtest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_maptest-maptest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_rwblob-rwblob.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_rwfile-rwfile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@utilities/$(DEPDIR)/gm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@wand/$(DEPDIR)/wand_drawtest-drawtest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-drawing_wand.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-magick_compat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-magick_wand.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-pixel_wand.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@wand/$(DEPDIR)/wand_wandtest-wandtest.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+coders/coders_art_la-art.lo: coders/art.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_art_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_art_la-art.lo -MD -MP -MF coders/$(DEPDIR)/coders_art_la-art.Tpo -c -o coders/coders_art_la-art.lo `test -f 'coders/art.c' || echo '$(srcdir)/'`coders/art.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_art_la-art.Tpo coders/$(DEPDIR)/coders_art_la-art.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/art.c' object='coders/coders_art_la-art.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_art_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_art_la-art.lo `test -f 'coders/art.c' || echo '$(srcdir)/'`coders/art.c
+
+coders/coders_avs_la-avs.lo: coders/avs.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_avs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_avs_la-avs.lo -MD -MP -MF coders/$(DEPDIR)/coders_avs_la-avs.Tpo -c -o coders/coders_avs_la-avs.lo `test -f 'coders/avs.c' || echo '$(srcdir)/'`coders/avs.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_avs_la-avs.Tpo coders/$(DEPDIR)/coders_avs_la-avs.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/avs.c' object='coders/coders_avs_la-avs.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_avs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_avs_la-avs.lo `test -f 'coders/avs.c' || echo '$(srcdir)/'`coders/avs.c
+
+coders/coders_bmp_la-bmp.lo: coders/bmp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_bmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_bmp_la-bmp.lo -MD -MP -MF coders/$(DEPDIR)/coders_bmp_la-bmp.Tpo -c -o coders/coders_bmp_la-bmp.lo `test -f 'coders/bmp.c' || echo '$(srcdir)/'`coders/bmp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_bmp_la-bmp.Tpo coders/$(DEPDIR)/coders_bmp_la-bmp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/bmp.c' object='coders/coders_bmp_la-bmp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_bmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_bmp_la-bmp.lo `test -f 'coders/bmp.c' || echo '$(srcdir)/'`coders/bmp.c
+
+coders/coders_cals_la-cals.lo: coders/cals.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_cals_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_cals_la-cals.lo -MD -MP -MF coders/$(DEPDIR)/coders_cals_la-cals.Tpo -c -o coders/coders_cals_la-cals.lo `test -f 'coders/cals.c' || echo '$(srcdir)/'`coders/cals.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_cals_la-cals.Tpo coders/$(DEPDIR)/coders_cals_la-cals.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/cals.c' object='coders/coders_cals_la-cals.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_cals_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_cals_la-cals.lo `test -f 'coders/cals.c' || echo '$(srcdir)/'`coders/cals.c
+
+coders/coders_caption_la-caption.lo: coders/caption.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_caption_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_caption_la-caption.lo -MD -MP -MF coders/$(DEPDIR)/coders_caption_la-caption.Tpo -c -o coders/coders_caption_la-caption.lo `test -f 'coders/caption.c' || echo '$(srcdir)/'`coders/caption.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_caption_la-caption.Tpo coders/$(DEPDIR)/coders_caption_la-caption.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/caption.c' object='coders/coders_caption_la-caption.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_caption_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_caption_la-caption.lo `test -f 'coders/caption.c' || echo '$(srcdir)/'`coders/caption.c
+
+coders/coders_cineon_la-cineon.lo: coders/cineon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_cineon_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_cineon_la-cineon.lo -MD -MP -MF coders/$(DEPDIR)/coders_cineon_la-cineon.Tpo -c -o coders/coders_cineon_la-cineon.lo `test -f 'coders/cineon.c' || echo '$(srcdir)/'`coders/cineon.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_cineon_la-cineon.Tpo coders/$(DEPDIR)/coders_cineon_la-cineon.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/cineon.c' object='coders/coders_cineon_la-cineon.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_cineon_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_cineon_la-cineon.lo `test -f 'coders/cineon.c' || echo '$(srcdir)/'`coders/cineon.c
+
+coders/coders_clipboard_la-clipboard.lo: coders/clipboard.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_clipboard_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_clipboard_la-clipboard.lo -MD -MP -MF coders/$(DEPDIR)/coders_clipboard_la-clipboard.Tpo -c -o coders/coders_clipboard_la-clipboard.lo `test -f 'coders/clipboard.c' || echo '$(srcdir)/'`coders/clipboard.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_clipboard_la-clipboard.Tpo coders/$(DEPDIR)/coders_clipboard_la-clipboard.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/clipboard.c' object='coders/coders_clipboard_la-clipboard.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_clipboard_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_clipboard_la-clipboard.lo `test -f 'coders/clipboard.c' || echo '$(srcdir)/'`coders/clipboard.c
+
+coders/coders_cmyk_la-cmyk.lo: coders/cmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_cmyk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_cmyk_la-cmyk.lo -MD -MP -MF coders/$(DEPDIR)/coders_cmyk_la-cmyk.Tpo -c -o coders/coders_cmyk_la-cmyk.lo `test -f 'coders/cmyk.c' || echo '$(srcdir)/'`coders/cmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_cmyk_la-cmyk.Tpo coders/$(DEPDIR)/coders_cmyk_la-cmyk.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/cmyk.c' object='coders/coders_cmyk_la-cmyk.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_cmyk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_cmyk_la-cmyk.lo `test -f 'coders/cmyk.c' || echo '$(srcdir)/'`coders/cmyk.c
+
+coders/coders_cut_la-cut.lo: coders/cut.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_cut_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_cut_la-cut.lo -MD -MP -MF coders/$(DEPDIR)/coders_cut_la-cut.Tpo -c -o coders/coders_cut_la-cut.lo `test -f 'coders/cut.c' || echo '$(srcdir)/'`coders/cut.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_cut_la-cut.Tpo coders/$(DEPDIR)/coders_cut_la-cut.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/cut.c' object='coders/coders_cut_la-cut.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_cut_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_cut_la-cut.lo `test -f 'coders/cut.c' || echo '$(srcdir)/'`coders/cut.c
+
+coders/coders_dcm_la-dcm.lo: coders/dcm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dcm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_dcm_la-dcm.lo -MD -MP -MF coders/$(DEPDIR)/coders_dcm_la-dcm.Tpo -c -o coders/coders_dcm_la-dcm.lo `test -f 'coders/dcm.c' || echo '$(srcdir)/'`coders/dcm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_dcm_la-dcm.Tpo coders/$(DEPDIR)/coders_dcm_la-dcm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dcm.c' object='coders/coders_dcm_la-dcm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dcm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_dcm_la-dcm.lo `test -f 'coders/dcm.c' || echo '$(srcdir)/'`coders/dcm.c
+
+coders/coders_dcraw_la-dcraw.lo: coders/dcraw.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dcraw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_dcraw_la-dcraw.lo -MD -MP -MF coders/$(DEPDIR)/coders_dcraw_la-dcraw.Tpo -c -o coders/coders_dcraw_la-dcraw.lo `test -f 'coders/dcraw.c' || echo '$(srcdir)/'`coders/dcraw.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_dcraw_la-dcraw.Tpo coders/$(DEPDIR)/coders_dcraw_la-dcraw.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dcraw.c' object='coders/coders_dcraw_la-dcraw.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dcraw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_dcraw_la-dcraw.lo `test -f 'coders/dcraw.c' || echo '$(srcdir)/'`coders/dcraw.c
+
+coders/coders_dib_la-dib.lo: coders/dib.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_dib_la-dib.lo -MD -MP -MF coders/$(DEPDIR)/coders_dib_la-dib.Tpo -c -o coders/coders_dib_la-dib.lo `test -f 'coders/dib.c' || echo '$(srcdir)/'`coders/dib.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_dib_la-dib.Tpo coders/$(DEPDIR)/coders_dib_la-dib.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dib.c' object='coders/coders_dib_la-dib.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_dib_la-dib.lo `test -f 'coders/dib.c' || echo '$(srcdir)/'`coders/dib.c
+
+coders/coders_dps_la-dps.lo: coders/dps.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dps_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_dps_la-dps.lo -MD -MP -MF coders/$(DEPDIR)/coders_dps_la-dps.Tpo -c -o coders/coders_dps_la-dps.lo `test -f 'coders/dps.c' || echo '$(srcdir)/'`coders/dps.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_dps_la-dps.Tpo coders/$(DEPDIR)/coders_dps_la-dps.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dps.c' object='coders/coders_dps_la-dps.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dps_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_dps_la-dps.lo `test -f 'coders/dps.c' || echo '$(srcdir)/'`coders/dps.c
+
+coders/coders_dpx_la-dpx.lo: coders/dpx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dpx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_dpx_la-dpx.lo -MD -MP -MF coders/$(DEPDIR)/coders_dpx_la-dpx.Tpo -c -o coders/coders_dpx_la-dpx.lo `test -f 'coders/dpx.c' || echo '$(srcdir)/'`coders/dpx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_dpx_la-dpx.Tpo coders/$(DEPDIR)/coders_dpx_la-dpx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dpx.c' object='coders/coders_dpx_la-dpx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_dpx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_dpx_la-dpx.lo `test -f 'coders/dpx.c' || echo '$(srcdir)/'`coders/dpx.c
+
+coders/coders_emf_la-emf.lo: coders/emf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_emf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_emf_la-emf.lo -MD -MP -MF coders/$(DEPDIR)/coders_emf_la-emf.Tpo -c -o coders/coders_emf_la-emf.lo `test -f 'coders/emf.c' || echo '$(srcdir)/'`coders/emf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_emf_la-emf.Tpo coders/$(DEPDIR)/coders_emf_la-emf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/emf.c' object='coders/coders_emf_la-emf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_emf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_emf_la-emf.lo `test -f 'coders/emf.c' || echo '$(srcdir)/'`coders/emf.c
+
+coders/coders_fax_la-fax.lo: coders/fax.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_fax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_fax_la-fax.lo -MD -MP -MF coders/$(DEPDIR)/coders_fax_la-fax.Tpo -c -o coders/coders_fax_la-fax.lo `test -f 'coders/fax.c' || echo '$(srcdir)/'`coders/fax.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_fax_la-fax.Tpo coders/$(DEPDIR)/coders_fax_la-fax.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/fax.c' object='coders/coders_fax_la-fax.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_fax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_fax_la-fax.lo `test -f 'coders/fax.c' || echo '$(srcdir)/'`coders/fax.c
+
+coders/coders_fits_la-fits.lo: coders/fits.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_fits_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_fits_la-fits.lo -MD -MP -MF coders/$(DEPDIR)/coders_fits_la-fits.Tpo -c -o coders/coders_fits_la-fits.lo `test -f 'coders/fits.c' || echo '$(srcdir)/'`coders/fits.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_fits_la-fits.Tpo coders/$(DEPDIR)/coders_fits_la-fits.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/fits.c' object='coders/coders_fits_la-fits.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_fits_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_fits_la-fits.lo `test -f 'coders/fits.c' || echo '$(srcdir)/'`coders/fits.c
+
+coders/coders_fpx_la-fpx.lo: coders/fpx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_fpx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_fpx_la-fpx.lo -MD -MP -MF coders/$(DEPDIR)/coders_fpx_la-fpx.Tpo -c -o coders/coders_fpx_la-fpx.lo `test -f 'coders/fpx.c' || echo '$(srcdir)/'`coders/fpx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_fpx_la-fpx.Tpo coders/$(DEPDIR)/coders_fpx_la-fpx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/fpx.c' object='coders/coders_fpx_la-fpx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_fpx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_fpx_la-fpx.lo `test -f 'coders/fpx.c' || echo '$(srcdir)/'`coders/fpx.c
+
+coders/coders_gif_la-gif.lo: coders/gif.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_gif_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_gif_la-gif.lo -MD -MP -MF coders/$(DEPDIR)/coders_gif_la-gif.Tpo -c -o coders/coders_gif_la-gif.lo `test -f 'coders/gif.c' || echo '$(srcdir)/'`coders/gif.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_gif_la-gif.Tpo coders/$(DEPDIR)/coders_gif_la-gif.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/gif.c' object='coders/coders_gif_la-gif.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_gif_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_gif_la-gif.lo `test -f 'coders/gif.c' || echo '$(srcdir)/'`coders/gif.c
+
+coders/coders_gradient_la-gradient.lo: coders/gradient.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_gradient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_gradient_la-gradient.lo -MD -MP -MF coders/$(DEPDIR)/coders_gradient_la-gradient.Tpo -c -o coders/coders_gradient_la-gradient.lo `test -f 'coders/gradient.c' || echo '$(srcdir)/'`coders/gradient.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_gradient_la-gradient.Tpo coders/$(DEPDIR)/coders_gradient_la-gradient.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/gradient.c' object='coders/coders_gradient_la-gradient.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_gradient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_gradient_la-gradient.lo `test -f 'coders/gradient.c' || echo '$(srcdir)/'`coders/gradient.c
+
+coders/coders_gray_la-gray.lo: coders/gray.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_gray_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_gray_la-gray.lo -MD -MP -MF coders/$(DEPDIR)/coders_gray_la-gray.Tpo -c -o coders/coders_gray_la-gray.lo `test -f 'coders/gray.c' || echo '$(srcdir)/'`coders/gray.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_gray_la-gray.Tpo coders/$(DEPDIR)/coders_gray_la-gray.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/gray.c' object='coders/coders_gray_la-gray.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_gray_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_gray_la-gray.lo `test -f 'coders/gray.c' || echo '$(srcdir)/'`coders/gray.c
+
+coders/coders_histogram_la-histogram.lo: coders/histogram.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_histogram_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_histogram_la-histogram.lo -MD -MP -MF coders/$(DEPDIR)/coders_histogram_la-histogram.Tpo -c -o coders/coders_histogram_la-histogram.lo `test -f 'coders/histogram.c' || echo '$(srcdir)/'`coders/histogram.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_histogram_la-histogram.Tpo coders/$(DEPDIR)/coders_histogram_la-histogram.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/histogram.c' object='coders/coders_histogram_la-histogram.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_histogram_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_histogram_la-histogram.lo `test -f 'coders/histogram.c' || echo '$(srcdir)/'`coders/histogram.c
+
+coders/coders_hrz_la-hrz.lo: coders/hrz.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_hrz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_hrz_la-hrz.lo -MD -MP -MF coders/$(DEPDIR)/coders_hrz_la-hrz.Tpo -c -o coders/coders_hrz_la-hrz.lo `test -f 'coders/hrz.c' || echo '$(srcdir)/'`coders/hrz.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_hrz_la-hrz.Tpo coders/$(DEPDIR)/coders_hrz_la-hrz.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/hrz.c' object='coders/coders_hrz_la-hrz.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_hrz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_hrz_la-hrz.lo `test -f 'coders/hrz.c' || echo '$(srcdir)/'`coders/hrz.c
+
+coders/coders_html_la-html.lo: coders/html.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_html_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_html_la-html.lo -MD -MP -MF coders/$(DEPDIR)/coders_html_la-html.Tpo -c -o coders/coders_html_la-html.lo `test -f 'coders/html.c' || echo '$(srcdir)/'`coders/html.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_html_la-html.Tpo coders/$(DEPDIR)/coders_html_la-html.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/html.c' object='coders/coders_html_la-html.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_html_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_html_la-html.lo `test -f 'coders/html.c' || echo '$(srcdir)/'`coders/html.c
+
+coders/coders_icon_la-icon.lo: coders/icon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_icon_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_icon_la-icon.lo -MD -MP -MF coders/$(DEPDIR)/coders_icon_la-icon.Tpo -c -o coders/coders_icon_la-icon.lo `test -f 'coders/icon.c' || echo '$(srcdir)/'`coders/icon.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_icon_la-icon.Tpo coders/$(DEPDIR)/coders_icon_la-icon.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/icon.c' object='coders/coders_icon_la-icon.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_icon_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_icon_la-icon.lo `test -f 'coders/icon.c' || echo '$(srcdir)/'`coders/icon.c
+
+coders/coders_identity_la-identity.lo: coders/identity.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_identity_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_identity_la-identity.lo -MD -MP -MF coders/$(DEPDIR)/coders_identity_la-identity.Tpo -c -o coders/coders_identity_la-identity.lo `test -f 'coders/identity.c' || echo '$(srcdir)/'`coders/identity.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_identity_la-identity.Tpo coders/$(DEPDIR)/coders_identity_la-identity.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/identity.c' object='coders/coders_identity_la-identity.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_identity_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_identity_la-identity.lo `test -f 'coders/identity.c' || echo '$(srcdir)/'`coders/identity.c
+
+coders/coders_info_la-info.lo: coders/info.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_info_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_info_la-info.lo -MD -MP -MF coders/$(DEPDIR)/coders_info_la-info.Tpo -c -o coders/coders_info_la-info.lo `test -f 'coders/info.c' || echo '$(srcdir)/'`coders/info.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_info_la-info.Tpo coders/$(DEPDIR)/coders_info_la-info.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/info.c' object='coders/coders_info_la-info.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_info_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_info_la-info.lo `test -f 'coders/info.c' || echo '$(srcdir)/'`coders/info.c
+
+coders/coders_jbig_la-jbig.lo: coders/jbig.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_jbig_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_jbig_la-jbig.lo -MD -MP -MF coders/$(DEPDIR)/coders_jbig_la-jbig.Tpo -c -o coders/coders_jbig_la-jbig.lo `test -f 'coders/jbig.c' || echo '$(srcdir)/'`coders/jbig.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_jbig_la-jbig.Tpo coders/$(DEPDIR)/coders_jbig_la-jbig.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/jbig.c' object='coders/coders_jbig_la-jbig.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_jbig_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_jbig_la-jbig.lo `test -f 'coders/jbig.c' || echo '$(srcdir)/'`coders/jbig.c
+
+coders/coders_jnx_la-jnx.lo: coders/jnx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_jnx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_jnx_la-jnx.lo -MD -MP -MF coders/$(DEPDIR)/coders_jnx_la-jnx.Tpo -c -o coders/coders_jnx_la-jnx.lo `test -f 'coders/jnx.c' || echo '$(srcdir)/'`coders/jnx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_jnx_la-jnx.Tpo coders/$(DEPDIR)/coders_jnx_la-jnx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/jnx.c' object='coders/coders_jnx_la-jnx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_jnx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_jnx_la-jnx.lo `test -f 'coders/jnx.c' || echo '$(srcdir)/'`coders/jnx.c
+
+coders/coders_jp2_la-jp2.lo: coders/jp2.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_jp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_jp2_la-jp2.lo -MD -MP -MF coders/$(DEPDIR)/coders_jp2_la-jp2.Tpo -c -o coders/coders_jp2_la-jp2.lo `test -f 'coders/jp2.c' || echo '$(srcdir)/'`coders/jp2.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_jp2_la-jp2.Tpo coders/$(DEPDIR)/coders_jp2_la-jp2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/jp2.c' object='coders/coders_jp2_la-jp2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_jp2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_jp2_la-jp2.lo `test -f 'coders/jp2.c' || echo '$(srcdir)/'`coders/jp2.c
+
+coders/coders_jpeg_la-jpeg.lo: coders/jpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_jpeg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_jpeg_la-jpeg.lo -MD -MP -MF coders/$(DEPDIR)/coders_jpeg_la-jpeg.Tpo -c -o coders/coders_jpeg_la-jpeg.lo `test -f 'coders/jpeg.c' || echo '$(srcdir)/'`coders/jpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_jpeg_la-jpeg.Tpo coders/$(DEPDIR)/coders_jpeg_la-jpeg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/jpeg.c' object='coders/coders_jpeg_la-jpeg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_jpeg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_jpeg_la-jpeg.lo `test -f 'coders/jpeg.c' || echo '$(srcdir)/'`coders/jpeg.c
+
+coders/coders_label_la-label.lo: coders/label.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_label_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_label_la-label.lo -MD -MP -MF coders/$(DEPDIR)/coders_label_la-label.Tpo -c -o coders/coders_label_la-label.lo `test -f 'coders/label.c' || echo '$(srcdir)/'`coders/label.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_label_la-label.Tpo coders/$(DEPDIR)/coders_label_la-label.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/label.c' object='coders/coders_label_la-label.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_label_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_label_la-label.lo `test -f 'coders/label.c' || echo '$(srcdir)/'`coders/label.c
+
+coders/coders_locale_la-locale.lo: coders/locale.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_locale_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_locale_la-locale.lo -MD -MP -MF coders/$(DEPDIR)/coders_locale_la-locale.Tpo -c -o coders/coders_locale_la-locale.lo `test -f 'coders/locale.c' || echo '$(srcdir)/'`coders/locale.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_locale_la-locale.Tpo coders/$(DEPDIR)/coders_locale_la-locale.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/locale.c' object='coders/coders_locale_la-locale.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_locale_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_locale_la-locale.lo `test -f 'coders/locale.c' || echo '$(srcdir)/'`coders/locale.c
+
+coders/coders_logo_la-logo.lo: coders/logo.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_logo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_logo_la-logo.lo -MD -MP -MF coders/$(DEPDIR)/coders_logo_la-logo.Tpo -c -o coders/coders_logo_la-logo.lo `test -f 'coders/logo.c' || echo '$(srcdir)/'`coders/logo.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_logo_la-logo.Tpo coders/$(DEPDIR)/coders_logo_la-logo.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/logo.c' object='coders/coders_logo_la-logo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_logo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_logo_la-logo.lo `test -f 'coders/logo.c' || echo '$(srcdir)/'`coders/logo.c
+
+coders/coders_mac_la-mac.lo: coders/mac.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mac_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_mac_la-mac.lo -MD -MP -MF coders/$(DEPDIR)/coders_mac_la-mac.Tpo -c -o coders/coders_mac_la-mac.lo `test -f 'coders/mac.c' || echo '$(srcdir)/'`coders/mac.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_mac_la-mac.Tpo coders/$(DEPDIR)/coders_mac_la-mac.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mac.c' object='coders/coders_mac_la-mac.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mac_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_mac_la-mac.lo `test -f 'coders/mac.c' || echo '$(srcdir)/'`coders/mac.c
+
+coders/coders_map_la-map.lo: coders/map.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_map_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_map_la-map.lo -MD -MP -MF coders/$(DEPDIR)/coders_map_la-map.Tpo -c -o coders/coders_map_la-map.lo `test -f 'coders/map.c' || echo '$(srcdir)/'`coders/map.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_map_la-map.Tpo coders/$(DEPDIR)/coders_map_la-map.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/map.c' object='coders/coders_map_la-map.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_map_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_map_la-map.lo `test -f 'coders/map.c' || echo '$(srcdir)/'`coders/map.c
+
+coders/coders_mat_la-mat.lo: coders/mat.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_mat_la-mat.lo -MD -MP -MF coders/$(DEPDIR)/coders_mat_la-mat.Tpo -c -o coders/coders_mat_la-mat.lo `test -f 'coders/mat.c' || echo '$(srcdir)/'`coders/mat.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_mat_la-mat.Tpo coders/$(DEPDIR)/coders_mat_la-mat.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mat.c' object='coders/coders_mat_la-mat.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_mat_la-mat.lo `test -f 'coders/mat.c' || echo '$(srcdir)/'`coders/mat.c
+
+coders/coders_matte_la-matte.lo: coders/matte.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_matte_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_matte_la-matte.lo -MD -MP -MF coders/$(DEPDIR)/coders_matte_la-matte.Tpo -c -o coders/coders_matte_la-matte.lo `test -f 'coders/matte.c' || echo '$(srcdir)/'`coders/matte.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_matte_la-matte.Tpo coders/$(DEPDIR)/coders_matte_la-matte.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/matte.c' object='coders/coders_matte_la-matte.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_matte_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_matte_la-matte.lo `test -f 'coders/matte.c' || echo '$(srcdir)/'`coders/matte.c
+
+coders/coders_meta_la-meta.lo: coders/meta.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_meta_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_meta_la-meta.lo -MD -MP -MF coders/$(DEPDIR)/coders_meta_la-meta.Tpo -c -o coders/coders_meta_la-meta.lo `test -f 'coders/meta.c' || echo '$(srcdir)/'`coders/meta.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_meta_la-meta.Tpo coders/$(DEPDIR)/coders_meta_la-meta.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/meta.c' object='coders/coders_meta_la-meta.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_meta_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_meta_la-meta.lo `test -f 'coders/meta.c' || echo '$(srcdir)/'`coders/meta.c
+
+coders/coders_miff_la-miff.lo: coders/miff.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_miff_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_miff_la-miff.lo -MD -MP -MF coders/$(DEPDIR)/coders_miff_la-miff.Tpo -c -o coders/coders_miff_la-miff.lo `test -f 'coders/miff.c' || echo '$(srcdir)/'`coders/miff.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_miff_la-miff.Tpo coders/$(DEPDIR)/coders_miff_la-miff.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/miff.c' object='coders/coders_miff_la-miff.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_miff_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_miff_la-miff.lo `test -f 'coders/miff.c' || echo '$(srcdir)/'`coders/miff.c
+
+coders/coders_mono_la-mono.lo: coders/mono.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mono_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_mono_la-mono.lo -MD -MP -MF coders/$(DEPDIR)/coders_mono_la-mono.Tpo -c -o coders/coders_mono_la-mono.lo `test -f 'coders/mono.c' || echo '$(srcdir)/'`coders/mono.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_mono_la-mono.Tpo coders/$(DEPDIR)/coders_mono_la-mono.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mono.c' object='coders/coders_mono_la-mono.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mono_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_mono_la-mono.lo `test -f 'coders/mono.c' || echo '$(srcdir)/'`coders/mono.c
+
+coders/coders_mpc_la-mpc.lo: coders/mpc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mpc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_mpc_la-mpc.lo -MD -MP -MF coders/$(DEPDIR)/coders_mpc_la-mpc.Tpo -c -o coders/coders_mpc_la-mpc.lo `test -f 'coders/mpc.c' || echo '$(srcdir)/'`coders/mpc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_mpc_la-mpc.Tpo coders/$(DEPDIR)/coders_mpc_la-mpc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mpc.c' object='coders/coders_mpc_la-mpc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mpc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_mpc_la-mpc.lo `test -f 'coders/mpc.c' || echo '$(srcdir)/'`coders/mpc.c
+
+coders/coders_mpeg_la-mpeg.lo: coders/mpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mpeg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_mpeg_la-mpeg.lo -MD -MP -MF coders/$(DEPDIR)/coders_mpeg_la-mpeg.Tpo -c -o coders/coders_mpeg_la-mpeg.lo `test -f 'coders/mpeg.c' || echo '$(srcdir)/'`coders/mpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_mpeg_la-mpeg.Tpo coders/$(DEPDIR)/coders_mpeg_la-mpeg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mpeg.c' object='coders/coders_mpeg_la-mpeg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mpeg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_mpeg_la-mpeg.lo `test -f 'coders/mpeg.c' || echo '$(srcdir)/'`coders/mpeg.c
+
+coders/coders_mpr_la-mpr.lo: coders/mpr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mpr_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_mpr_la-mpr.lo -MD -MP -MF coders/$(DEPDIR)/coders_mpr_la-mpr.Tpo -c -o coders/coders_mpr_la-mpr.lo `test -f 'coders/mpr.c' || echo '$(srcdir)/'`coders/mpr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_mpr_la-mpr.Tpo coders/$(DEPDIR)/coders_mpr_la-mpr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mpr.c' object='coders/coders_mpr_la-mpr.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mpr_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_mpr_la-mpr.lo `test -f 'coders/mpr.c' || echo '$(srcdir)/'`coders/mpr.c
+
+coders/coders_msl_la-msl.lo: coders/msl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_msl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_msl_la-msl.lo -MD -MP -MF coders/$(DEPDIR)/coders_msl_la-msl.Tpo -c -o coders/coders_msl_la-msl.lo `test -f 'coders/msl.c' || echo '$(srcdir)/'`coders/msl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_msl_la-msl.Tpo coders/$(DEPDIR)/coders_msl_la-msl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/msl.c' object='coders/coders_msl_la-msl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_msl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_msl_la-msl.lo `test -f 'coders/msl.c' || echo '$(srcdir)/'`coders/msl.c
+
+coders/coders_mtv_la-mtv.lo: coders/mtv.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mtv_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_mtv_la-mtv.lo -MD -MP -MF coders/$(DEPDIR)/coders_mtv_la-mtv.Tpo -c -o coders/coders_mtv_la-mtv.lo `test -f 'coders/mtv.c' || echo '$(srcdir)/'`coders/mtv.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_mtv_la-mtv.Tpo coders/$(DEPDIR)/coders_mtv_la-mtv.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mtv.c' object='coders/coders_mtv_la-mtv.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mtv_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_mtv_la-mtv.lo `test -f 'coders/mtv.c' || echo '$(srcdir)/'`coders/mtv.c
+
+coders/coders_mvg_la-mvg.lo: coders/mvg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mvg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_mvg_la-mvg.lo -MD -MP -MF coders/$(DEPDIR)/coders_mvg_la-mvg.Tpo -c -o coders/coders_mvg_la-mvg.lo `test -f 'coders/mvg.c' || echo '$(srcdir)/'`coders/mvg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_mvg_la-mvg.Tpo coders/$(DEPDIR)/coders_mvg_la-mvg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mvg.c' object='coders/coders_mvg_la-mvg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_mvg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_mvg_la-mvg.lo `test -f 'coders/mvg.c' || echo '$(srcdir)/'`coders/mvg.c
+
+coders/coders_null_la-null.lo: coders/null.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_null_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_null_la-null.lo -MD -MP -MF coders/$(DEPDIR)/coders_null_la-null.Tpo -c -o coders/coders_null_la-null.lo `test -f 'coders/null.c' || echo '$(srcdir)/'`coders/null.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_null_la-null.Tpo coders/$(DEPDIR)/coders_null_la-null.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/null.c' object='coders/coders_null_la-null.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_null_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_null_la-null.lo `test -f 'coders/null.c' || echo '$(srcdir)/'`coders/null.c
+
+coders/coders_otb_la-otb.lo: coders/otb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_otb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_otb_la-otb.lo -MD -MP -MF coders/$(DEPDIR)/coders_otb_la-otb.Tpo -c -o coders/coders_otb_la-otb.lo `test -f 'coders/otb.c' || echo '$(srcdir)/'`coders/otb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_otb_la-otb.Tpo coders/$(DEPDIR)/coders_otb_la-otb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/otb.c' object='coders/coders_otb_la-otb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_otb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_otb_la-otb.lo `test -f 'coders/otb.c' || echo '$(srcdir)/'`coders/otb.c
+
+coders/coders_palm_la-palm.lo: coders/palm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_palm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_palm_la-palm.lo -MD -MP -MF coders/$(DEPDIR)/coders_palm_la-palm.Tpo -c -o coders/coders_palm_la-palm.lo `test -f 'coders/palm.c' || echo '$(srcdir)/'`coders/palm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_palm_la-palm.Tpo coders/$(DEPDIR)/coders_palm_la-palm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/palm.c' object='coders/coders_palm_la-palm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_palm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_palm_la-palm.lo `test -f 'coders/palm.c' || echo '$(srcdir)/'`coders/palm.c
+
+coders/coders_pcd_la-pcd.lo: coders/pcd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pcd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pcd_la-pcd.lo -MD -MP -MF coders/$(DEPDIR)/coders_pcd_la-pcd.Tpo -c -o coders/coders_pcd_la-pcd.lo `test -f 'coders/pcd.c' || echo '$(srcdir)/'`coders/pcd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pcd_la-pcd.Tpo coders/$(DEPDIR)/coders_pcd_la-pcd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pcd.c' object='coders/coders_pcd_la-pcd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pcd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pcd_la-pcd.lo `test -f 'coders/pcd.c' || echo '$(srcdir)/'`coders/pcd.c
+
+coders/coders_pcl_la-pcl.lo: coders/pcl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pcl_la-pcl.lo -MD -MP -MF coders/$(DEPDIR)/coders_pcl_la-pcl.Tpo -c -o coders/coders_pcl_la-pcl.lo `test -f 'coders/pcl.c' || echo '$(srcdir)/'`coders/pcl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pcl_la-pcl.Tpo coders/$(DEPDIR)/coders_pcl_la-pcl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pcl.c' object='coders/coders_pcl_la-pcl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pcl_la-pcl.lo `test -f 'coders/pcl.c' || echo '$(srcdir)/'`coders/pcl.c
+
+coders/coders_pcx_la-pcx.lo: coders/pcx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pcx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pcx_la-pcx.lo -MD -MP -MF coders/$(DEPDIR)/coders_pcx_la-pcx.Tpo -c -o coders/coders_pcx_la-pcx.lo `test -f 'coders/pcx.c' || echo '$(srcdir)/'`coders/pcx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pcx_la-pcx.Tpo coders/$(DEPDIR)/coders_pcx_la-pcx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pcx.c' object='coders/coders_pcx_la-pcx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pcx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pcx_la-pcx.lo `test -f 'coders/pcx.c' || echo '$(srcdir)/'`coders/pcx.c
+
+coders/coders_pdb_la-pdb.lo: coders/pdb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pdb_la-pdb.lo -MD -MP -MF coders/$(DEPDIR)/coders_pdb_la-pdb.Tpo -c -o coders/coders_pdb_la-pdb.lo `test -f 'coders/pdb.c' || echo '$(srcdir)/'`coders/pdb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pdb_la-pdb.Tpo coders/$(DEPDIR)/coders_pdb_la-pdb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pdb.c' object='coders/coders_pdb_la-pdb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pdb_la-pdb.lo `test -f 'coders/pdb.c' || echo '$(srcdir)/'`coders/pdb.c
+
+coders/coders_pdf_la-pdf.lo: coders/pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pdf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pdf_la-pdf.lo -MD -MP -MF coders/$(DEPDIR)/coders_pdf_la-pdf.Tpo -c -o coders/coders_pdf_la-pdf.lo `test -f 'coders/pdf.c' || echo '$(srcdir)/'`coders/pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pdf_la-pdf.Tpo coders/$(DEPDIR)/coders_pdf_la-pdf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pdf.c' object='coders/coders_pdf_la-pdf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pdf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pdf_la-pdf.lo `test -f 'coders/pdf.c' || echo '$(srcdir)/'`coders/pdf.c
+
+coders/coders_pict_la-pict.lo: coders/pict.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pict_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pict_la-pict.lo -MD -MP -MF coders/$(DEPDIR)/coders_pict_la-pict.Tpo -c -o coders/coders_pict_la-pict.lo `test -f 'coders/pict.c' || echo '$(srcdir)/'`coders/pict.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pict_la-pict.Tpo coders/$(DEPDIR)/coders_pict_la-pict.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pict.c' object='coders/coders_pict_la-pict.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pict_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pict_la-pict.lo `test -f 'coders/pict.c' || echo '$(srcdir)/'`coders/pict.c
+
+coders/coders_pix_la-pix.lo: coders/pix.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pix_la-pix.lo -MD -MP -MF coders/$(DEPDIR)/coders_pix_la-pix.Tpo -c -o coders/coders_pix_la-pix.lo `test -f 'coders/pix.c' || echo '$(srcdir)/'`coders/pix.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pix_la-pix.Tpo coders/$(DEPDIR)/coders_pix_la-pix.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pix.c' object='coders/coders_pix_la-pix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pix_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pix_la-pix.lo `test -f 'coders/pix.c' || echo '$(srcdir)/'`coders/pix.c
+
+coders/coders_plasma_la-plasma.lo: coders/plasma.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_plasma_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_plasma_la-plasma.lo -MD -MP -MF coders/$(DEPDIR)/coders_plasma_la-plasma.Tpo -c -o coders/coders_plasma_la-plasma.lo `test -f 'coders/plasma.c' || echo '$(srcdir)/'`coders/plasma.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_plasma_la-plasma.Tpo coders/$(DEPDIR)/coders_plasma_la-plasma.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/plasma.c' object='coders/coders_plasma_la-plasma.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_plasma_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_plasma_la-plasma.lo `test -f 'coders/plasma.c' || echo '$(srcdir)/'`coders/plasma.c
+
+coders/coders_png_la-png.lo: coders/png.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_png_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_png_la-png.lo -MD -MP -MF coders/$(DEPDIR)/coders_png_la-png.Tpo -c -o coders/coders_png_la-png.lo `test -f 'coders/png.c' || echo '$(srcdir)/'`coders/png.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_png_la-png.Tpo coders/$(DEPDIR)/coders_png_la-png.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/png.c' object='coders/coders_png_la-png.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_png_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_png_la-png.lo `test -f 'coders/png.c' || echo '$(srcdir)/'`coders/png.c
+
+coders/coders_pnm_la-pnm.lo: coders/pnm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pnm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pnm_la-pnm.lo -MD -MP -MF coders/$(DEPDIR)/coders_pnm_la-pnm.Tpo -c -o coders/coders_pnm_la-pnm.lo `test -f 'coders/pnm.c' || echo '$(srcdir)/'`coders/pnm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pnm_la-pnm.Tpo coders/$(DEPDIR)/coders_pnm_la-pnm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pnm.c' object='coders/coders_pnm_la-pnm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pnm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pnm_la-pnm.lo `test -f 'coders/pnm.c' || echo '$(srcdir)/'`coders/pnm.c
+
+coders/coders_preview_la-preview.lo: coders/preview.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_preview_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_preview_la-preview.lo -MD -MP -MF coders/$(DEPDIR)/coders_preview_la-preview.Tpo -c -o coders/coders_preview_la-preview.lo `test -f 'coders/preview.c' || echo '$(srcdir)/'`coders/preview.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_preview_la-preview.Tpo coders/$(DEPDIR)/coders_preview_la-preview.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/preview.c' object='coders/coders_preview_la-preview.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_preview_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_preview_la-preview.lo `test -f 'coders/preview.c' || echo '$(srcdir)/'`coders/preview.c
+
+coders/coders_ps_la-ps.lo: coders/ps.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_ps_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_ps_la-ps.lo -MD -MP -MF coders/$(DEPDIR)/coders_ps_la-ps.Tpo -c -o coders/coders_ps_la-ps.lo `test -f 'coders/ps.c' || echo '$(srcdir)/'`coders/ps.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_ps_la-ps.Tpo coders/$(DEPDIR)/coders_ps_la-ps.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ps.c' object='coders/coders_ps_la-ps.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_ps_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_ps_la-ps.lo `test -f 'coders/ps.c' || echo '$(srcdir)/'`coders/ps.c
+
+coders/coders_ps2_la-ps2.lo: coders/ps2.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_ps2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_ps2_la-ps2.lo -MD -MP -MF coders/$(DEPDIR)/coders_ps2_la-ps2.Tpo -c -o coders/coders_ps2_la-ps2.lo `test -f 'coders/ps2.c' || echo '$(srcdir)/'`coders/ps2.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_ps2_la-ps2.Tpo coders/$(DEPDIR)/coders_ps2_la-ps2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ps2.c' object='coders/coders_ps2_la-ps2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_ps2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_ps2_la-ps2.lo `test -f 'coders/ps2.c' || echo '$(srcdir)/'`coders/ps2.c
+
+coders/coders_ps3_la-ps3.lo: coders/ps3.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_ps3_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_ps3_la-ps3.lo -MD -MP -MF coders/$(DEPDIR)/coders_ps3_la-ps3.Tpo -c -o coders/coders_ps3_la-ps3.lo `test -f 'coders/ps3.c' || echo '$(srcdir)/'`coders/ps3.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_ps3_la-ps3.Tpo coders/$(DEPDIR)/coders_ps3_la-ps3.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ps3.c' object='coders/coders_ps3_la-ps3.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_ps3_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_ps3_la-ps3.lo `test -f 'coders/ps3.c' || echo '$(srcdir)/'`coders/ps3.c
+
+coders/coders_psd_la-psd.lo: coders/psd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_psd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_psd_la-psd.lo -MD -MP -MF coders/$(DEPDIR)/coders_psd_la-psd.Tpo -c -o coders/coders_psd_la-psd.lo `test -f 'coders/psd.c' || echo '$(srcdir)/'`coders/psd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_psd_la-psd.Tpo coders/$(DEPDIR)/coders_psd_la-psd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/psd.c' object='coders/coders_psd_la-psd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_psd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_psd_la-psd.lo `test -f 'coders/psd.c' || echo '$(srcdir)/'`coders/psd.c
+
+coders/coders_pwp_la-pwp.lo: coders/pwp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pwp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_pwp_la-pwp.lo -MD -MP -MF coders/$(DEPDIR)/coders_pwp_la-pwp.Tpo -c -o coders/coders_pwp_la-pwp.lo `test -f 'coders/pwp.c' || echo '$(srcdir)/'`coders/pwp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_pwp_la-pwp.Tpo coders/$(DEPDIR)/coders_pwp_la-pwp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pwp.c' object='coders/coders_pwp_la-pwp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_pwp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_pwp_la-pwp.lo `test -f 'coders/pwp.c' || echo '$(srcdir)/'`coders/pwp.c
+
+coders/coders_rgb_la-rgb.lo: coders/rgb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_rgb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_rgb_la-rgb.lo -MD -MP -MF coders/$(DEPDIR)/coders_rgb_la-rgb.Tpo -c -o coders/coders_rgb_la-rgb.lo `test -f 'coders/rgb.c' || echo '$(srcdir)/'`coders/rgb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_rgb_la-rgb.Tpo coders/$(DEPDIR)/coders_rgb_la-rgb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/rgb.c' object='coders/coders_rgb_la-rgb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_rgb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_rgb_la-rgb.lo `test -f 'coders/rgb.c' || echo '$(srcdir)/'`coders/rgb.c
+
+coders/coders_rla_la-rla.lo: coders/rla.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_rla_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_rla_la-rla.lo -MD -MP -MF coders/$(DEPDIR)/coders_rla_la-rla.Tpo -c -o coders/coders_rla_la-rla.lo `test -f 'coders/rla.c' || echo '$(srcdir)/'`coders/rla.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_rla_la-rla.Tpo coders/$(DEPDIR)/coders_rla_la-rla.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/rla.c' object='coders/coders_rla_la-rla.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_rla_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_rla_la-rla.lo `test -f 'coders/rla.c' || echo '$(srcdir)/'`coders/rla.c
+
+coders/coders_rle_la-rle.lo: coders/rle.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_rle_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_rle_la-rle.lo -MD -MP -MF coders/$(DEPDIR)/coders_rle_la-rle.Tpo -c -o coders/coders_rle_la-rle.lo `test -f 'coders/rle.c' || echo '$(srcdir)/'`coders/rle.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_rle_la-rle.Tpo coders/$(DEPDIR)/coders_rle_la-rle.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/rle.c' object='coders/coders_rle_la-rle.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_rle_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_rle_la-rle.lo `test -f 'coders/rle.c' || echo '$(srcdir)/'`coders/rle.c
+
+coders/coders_sct_la-sct.lo: coders/sct.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_sct_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_sct_la-sct.lo -MD -MP -MF coders/$(DEPDIR)/coders_sct_la-sct.Tpo -c -o coders/coders_sct_la-sct.lo `test -f 'coders/sct.c' || echo '$(srcdir)/'`coders/sct.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_sct_la-sct.Tpo coders/$(DEPDIR)/coders_sct_la-sct.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/sct.c' object='coders/coders_sct_la-sct.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_sct_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_sct_la-sct.lo `test -f 'coders/sct.c' || echo '$(srcdir)/'`coders/sct.c
+
+coders/coders_sfw_la-sfw.lo: coders/sfw.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_sfw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_sfw_la-sfw.lo -MD -MP -MF coders/$(DEPDIR)/coders_sfw_la-sfw.Tpo -c -o coders/coders_sfw_la-sfw.lo `test -f 'coders/sfw.c' || echo '$(srcdir)/'`coders/sfw.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_sfw_la-sfw.Tpo coders/$(DEPDIR)/coders_sfw_la-sfw.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/sfw.c' object='coders/coders_sfw_la-sfw.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_sfw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_sfw_la-sfw.lo `test -f 'coders/sfw.c' || echo '$(srcdir)/'`coders/sfw.c
+
+coders/coders_sgi_la-sgi.lo: coders/sgi.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_sgi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_sgi_la-sgi.lo -MD -MP -MF coders/$(DEPDIR)/coders_sgi_la-sgi.Tpo -c -o coders/coders_sgi_la-sgi.lo `test -f 'coders/sgi.c' || echo '$(srcdir)/'`coders/sgi.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_sgi_la-sgi.Tpo coders/$(DEPDIR)/coders_sgi_la-sgi.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/sgi.c' object='coders/coders_sgi_la-sgi.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_sgi_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_sgi_la-sgi.lo `test -f 'coders/sgi.c' || echo '$(srcdir)/'`coders/sgi.c
+
+coders/coders_stegano_la-stegano.lo: coders/stegano.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_stegano_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_stegano_la-stegano.lo -MD -MP -MF coders/$(DEPDIR)/coders_stegano_la-stegano.Tpo -c -o coders/coders_stegano_la-stegano.lo `test -f 'coders/stegano.c' || echo '$(srcdir)/'`coders/stegano.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_stegano_la-stegano.Tpo coders/$(DEPDIR)/coders_stegano_la-stegano.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/stegano.c' object='coders/coders_stegano_la-stegano.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_stegano_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_stegano_la-stegano.lo `test -f 'coders/stegano.c' || echo '$(srcdir)/'`coders/stegano.c
+
+coders/coders_sun_la-sun.lo: coders/sun.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_sun_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_sun_la-sun.lo -MD -MP -MF coders/$(DEPDIR)/coders_sun_la-sun.Tpo -c -o coders/coders_sun_la-sun.lo `test -f 'coders/sun.c' || echo '$(srcdir)/'`coders/sun.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_sun_la-sun.Tpo coders/$(DEPDIR)/coders_sun_la-sun.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/sun.c' object='coders/coders_sun_la-sun.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_sun_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_sun_la-sun.lo `test -f 'coders/sun.c' || echo '$(srcdir)/'`coders/sun.c
+
+coders/coders_svg_la-svg.lo: coders/svg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_svg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_svg_la-svg.lo -MD -MP -MF coders/$(DEPDIR)/coders_svg_la-svg.Tpo -c -o coders/coders_svg_la-svg.lo `test -f 'coders/svg.c' || echo '$(srcdir)/'`coders/svg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_svg_la-svg.Tpo coders/$(DEPDIR)/coders_svg_la-svg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/svg.c' object='coders/coders_svg_la-svg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_svg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_svg_la-svg.lo `test -f 'coders/svg.c' || echo '$(srcdir)/'`coders/svg.c
+
+coders/coders_tga_la-tga.lo: coders/tga.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_tga_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_tga_la-tga.lo -MD -MP -MF coders/$(DEPDIR)/coders_tga_la-tga.Tpo -c -o coders/coders_tga_la-tga.lo `test -f 'coders/tga.c' || echo '$(srcdir)/'`coders/tga.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_tga_la-tga.Tpo coders/$(DEPDIR)/coders_tga_la-tga.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/tga.c' object='coders/coders_tga_la-tga.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_tga_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_tga_la-tga.lo `test -f 'coders/tga.c' || echo '$(srcdir)/'`coders/tga.c
+
+coders/coders_tiff_la-tiff.lo: coders/tiff.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_tiff_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_tiff_la-tiff.lo -MD -MP -MF coders/$(DEPDIR)/coders_tiff_la-tiff.Tpo -c -o coders/coders_tiff_la-tiff.lo `test -f 'coders/tiff.c' || echo '$(srcdir)/'`coders/tiff.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_tiff_la-tiff.Tpo coders/$(DEPDIR)/coders_tiff_la-tiff.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/tiff.c' object='coders/coders_tiff_la-tiff.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_tiff_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_tiff_la-tiff.lo `test -f 'coders/tiff.c' || echo '$(srcdir)/'`coders/tiff.c
+
+coders/coders_tile_la-tile.lo: coders/tile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_tile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_tile_la-tile.lo -MD -MP -MF coders/$(DEPDIR)/coders_tile_la-tile.Tpo -c -o coders/coders_tile_la-tile.lo `test -f 'coders/tile.c' || echo '$(srcdir)/'`coders/tile.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_tile_la-tile.Tpo coders/$(DEPDIR)/coders_tile_la-tile.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/tile.c' object='coders/coders_tile_la-tile.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_tile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_tile_la-tile.lo `test -f 'coders/tile.c' || echo '$(srcdir)/'`coders/tile.c
+
+coders/coders_tim_la-tim.lo: coders/tim.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_tim_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_tim_la-tim.lo -MD -MP -MF coders/$(DEPDIR)/coders_tim_la-tim.Tpo -c -o coders/coders_tim_la-tim.lo `test -f 'coders/tim.c' || echo '$(srcdir)/'`coders/tim.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_tim_la-tim.Tpo coders/$(DEPDIR)/coders_tim_la-tim.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/tim.c' object='coders/coders_tim_la-tim.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_tim_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_tim_la-tim.lo `test -f 'coders/tim.c' || echo '$(srcdir)/'`coders/tim.c
+
+coders/coders_topol_la-topol.lo: coders/topol.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_topol_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_topol_la-topol.lo -MD -MP -MF coders/$(DEPDIR)/coders_topol_la-topol.Tpo -c -o coders/coders_topol_la-topol.lo `test -f 'coders/topol.c' || echo '$(srcdir)/'`coders/topol.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_topol_la-topol.Tpo coders/$(DEPDIR)/coders_topol_la-topol.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/topol.c' object='coders/coders_topol_la-topol.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_topol_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_topol_la-topol.lo `test -f 'coders/topol.c' || echo '$(srcdir)/'`coders/topol.c
+
+coders/coders_ttf_la-ttf.lo: coders/ttf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_ttf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_ttf_la-ttf.lo -MD -MP -MF coders/$(DEPDIR)/coders_ttf_la-ttf.Tpo -c -o coders/coders_ttf_la-ttf.lo `test -f 'coders/ttf.c' || echo '$(srcdir)/'`coders/ttf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_ttf_la-ttf.Tpo coders/$(DEPDIR)/coders_ttf_la-ttf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ttf.c' object='coders/coders_ttf_la-ttf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_ttf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_ttf_la-ttf.lo `test -f 'coders/ttf.c' || echo '$(srcdir)/'`coders/ttf.c
+
+coders/coders_txt_la-txt.lo: coders/txt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_txt_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_txt_la-txt.lo -MD -MP -MF coders/$(DEPDIR)/coders_txt_la-txt.Tpo -c -o coders/coders_txt_la-txt.lo `test -f 'coders/txt.c' || echo '$(srcdir)/'`coders/txt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_txt_la-txt.Tpo coders/$(DEPDIR)/coders_txt_la-txt.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/txt.c' object='coders/coders_txt_la-txt.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_txt_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_txt_la-txt.lo `test -f 'coders/txt.c' || echo '$(srcdir)/'`coders/txt.c
+
+coders/coders_uil_la-uil.lo: coders/uil.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_uil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_uil_la-uil.lo -MD -MP -MF coders/$(DEPDIR)/coders_uil_la-uil.Tpo -c -o coders/coders_uil_la-uil.lo `test -f 'coders/uil.c' || echo '$(srcdir)/'`coders/uil.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_uil_la-uil.Tpo coders/$(DEPDIR)/coders_uil_la-uil.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/uil.c' object='coders/coders_uil_la-uil.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_uil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_uil_la-uil.lo `test -f 'coders/uil.c' || echo '$(srcdir)/'`coders/uil.c
+
+coders/coders_url_la-url.lo: coders/url.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_url_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_url_la-url.lo -MD -MP -MF coders/$(DEPDIR)/coders_url_la-url.Tpo -c -o coders/coders_url_la-url.lo `test -f 'coders/url.c' || echo '$(srcdir)/'`coders/url.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_url_la-url.Tpo coders/$(DEPDIR)/coders_url_la-url.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/url.c' object='coders/coders_url_la-url.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_url_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_url_la-url.lo `test -f 'coders/url.c' || echo '$(srcdir)/'`coders/url.c
+
+coders/coders_uyvy_la-uyvy.lo: coders/uyvy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_uyvy_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_uyvy_la-uyvy.lo -MD -MP -MF coders/$(DEPDIR)/coders_uyvy_la-uyvy.Tpo -c -o coders/coders_uyvy_la-uyvy.lo `test -f 'coders/uyvy.c' || echo '$(srcdir)/'`coders/uyvy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_uyvy_la-uyvy.Tpo coders/$(DEPDIR)/coders_uyvy_la-uyvy.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/uyvy.c' object='coders/coders_uyvy_la-uyvy.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_uyvy_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_uyvy_la-uyvy.lo `test -f 'coders/uyvy.c' || echo '$(srcdir)/'`coders/uyvy.c
+
+coders/coders_vicar_la-vicar.lo: coders/vicar.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_vicar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_vicar_la-vicar.lo -MD -MP -MF coders/$(DEPDIR)/coders_vicar_la-vicar.Tpo -c -o coders/coders_vicar_la-vicar.lo `test -f 'coders/vicar.c' || echo '$(srcdir)/'`coders/vicar.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_vicar_la-vicar.Tpo coders/$(DEPDIR)/coders_vicar_la-vicar.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/vicar.c' object='coders/coders_vicar_la-vicar.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_vicar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_vicar_la-vicar.lo `test -f 'coders/vicar.c' || echo '$(srcdir)/'`coders/vicar.c
+
+coders/coders_vid_la-vid.lo: coders/vid.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_vid_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_vid_la-vid.lo -MD -MP -MF coders/$(DEPDIR)/coders_vid_la-vid.Tpo -c -o coders/coders_vid_la-vid.lo `test -f 'coders/vid.c' || echo '$(srcdir)/'`coders/vid.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_vid_la-vid.Tpo coders/$(DEPDIR)/coders_vid_la-vid.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/vid.c' object='coders/coders_vid_la-vid.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_vid_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_vid_la-vid.lo `test -f 'coders/vid.c' || echo '$(srcdir)/'`coders/vid.c
+
+coders/coders_viff_la-viff.lo: coders/viff.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_viff_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_viff_la-viff.lo -MD -MP -MF coders/$(DEPDIR)/coders_viff_la-viff.Tpo -c -o coders/coders_viff_la-viff.lo `test -f 'coders/viff.c' || echo '$(srcdir)/'`coders/viff.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_viff_la-viff.Tpo coders/$(DEPDIR)/coders_viff_la-viff.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/viff.c' object='coders/coders_viff_la-viff.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_viff_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_viff_la-viff.lo `test -f 'coders/viff.c' || echo '$(srcdir)/'`coders/viff.c
+
+coders/coders_wbmp_la-wbmp.lo: coders/wbmp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_wbmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_wbmp_la-wbmp.lo -MD -MP -MF coders/$(DEPDIR)/coders_wbmp_la-wbmp.Tpo -c -o coders/coders_wbmp_la-wbmp.lo `test -f 'coders/wbmp.c' || echo '$(srcdir)/'`coders/wbmp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_wbmp_la-wbmp.Tpo coders/$(DEPDIR)/coders_wbmp_la-wbmp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/wbmp.c' object='coders/coders_wbmp_la-wbmp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_wbmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_wbmp_la-wbmp.lo `test -f 'coders/wbmp.c' || echo '$(srcdir)/'`coders/wbmp.c
+
+coders/coders_webp_la-webp.lo: coders/webp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_webp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_webp_la-webp.lo -MD -MP -MF coders/$(DEPDIR)/coders_webp_la-webp.Tpo -c -o coders/coders_webp_la-webp.lo `test -f 'coders/webp.c' || echo '$(srcdir)/'`coders/webp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_webp_la-webp.Tpo coders/$(DEPDIR)/coders_webp_la-webp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/webp.c' object='coders/coders_webp_la-webp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_webp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_webp_la-webp.lo `test -f 'coders/webp.c' || echo '$(srcdir)/'`coders/webp.c
+
+coders/coders_wmf_la-wmf.lo: coders/wmf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_wmf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_wmf_la-wmf.lo -MD -MP -MF coders/$(DEPDIR)/coders_wmf_la-wmf.Tpo -c -o coders/coders_wmf_la-wmf.lo `test -f 'coders/wmf.c' || echo '$(srcdir)/'`coders/wmf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_wmf_la-wmf.Tpo coders/$(DEPDIR)/coders_wmf_la-wmf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/wmf.c' object='coders/coders_wmf_la-wmf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_wmf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_wmf_la-wmf.lo `test -f 'coders/wmf.c' || echo '$(srcdir)/'`coders/wmf.c
+
+coders/coders_wpg_la-wpg.lo: coders/wpg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_wpg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_wpg_la-wpg.lo -MD -MP -MF coders/$(DEPDIR)/coders_wpg_la-wpg.Tpo -c -o coders/coders_wpg_la-wpg.lo `test -f 'coders/wpg.c' || echo '$(srcdir)/'`coders/wpg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_wpg_la-wpg.Tpo coders/$(DEPDIR)/coders_wpg_la-wpg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/wpg.c' object='coders/coders_wpg_la-wpg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_wpg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_wpg_la-wpg.lo `test -f 'coders/wpg.c' || echo '$(srcdir)/'`coders/wpg.c
+
+coders/coders_x_la-x.lo: coders/x.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_x_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_x_la-x.lo -MD -MP -MF coders/$(DEPDIR)/coders_x_la-x.Tpo -c -o coders/coders_x_la-x.lo `test -f 'coders/x.c' || echo '$(srcdir)/'`coders/x.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_x_la-x.Tpo coders/$(DEPDIR)/coders_x_la-x.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/x.c' object='coders/coders_x_la-x.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_x_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_x_la-x.lo `test -f 'coders/x.c' || echo '$(srcdir)/'`coders/x.c
+
+coders/coders_xbm_la-xbm.lo: coders/xbm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xbm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_xbm_la-xbm.lo -MD -MP -MF coders/$(DEPDIR)/coders_xbm_la-xbm.Tpo -c -o coders/coders_xbm_la-xbm.lo `test -f 'coders/xbm.c' || echo '$(srcdir)/'`coders/xbm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_xbm_la-xbm.Tpo coders/$(DEPDIR)/coders_xbm_la-xbm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xbm.c' object='coders/coders_xbm_la-xbm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xbm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_xbm_la-xbm.lo `test -f 'coders/xbm.c' || echo '$(srcdir)/'`coders/xbm.c
+
+coders/coders_xc_la-xc.lo: coders/xc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_xc_la-xc.lo -MD -MP -MF coders/$(DEPDIR)/coders_xc_la-xc.Tpo -c -o coders/coders_xc_la-xc.lo `test -f 'coders/xc.c' || echo '$(srcdir)/'`coders/xc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_xc_la-xc.Tpo coders/$(DEPDIR)/coders_xc_la-xc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xc.c' object='coders/coders_xc_la-xc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_xc_la-xc.lo `test -f 'coders/xc.c' || echo '$(srcdir)/'`coders/xc.c
+
+coders/coders_xcf_la-xcf.lo: coders/xcf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xcf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_xcf_la-xcf.lo -MD -MP -MF coders/$(DEPDIR)/coders_xcf_la-xcf.Tpo -c -o coders/coders_xcf_la-xcf.lo `test -f 'coders/xcf.c' || echo '$(srcdir)/'`coders/xcf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_xcf_la-xcf.Tpo coders/$(DEPDIR)/coders_xcf_la-xcf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xcf.c' object='coders/coders_xcf_la-xcf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xcf_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_xcf_la-xcf.lo `test -f 'coders/xcf.c' || echo '$(srcdir)/'`coders/xcf.c
+
+coders/coders_xpm_la-xpm.lo: coders/xpm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xpm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_xpm_la-xpm.lo -MD -MP -MF coders/$(DEPDIR)/coders_xpm_la-xpm.Tpo -c -o coders/coders_xpm_la-xpm.lo `test -f 'coders/xpm.c' || echo '$(srcdir)/'`coders/xpm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_xpm_la-xpm.Tpo coders/$(DEPDIR)/coders_xpm_la-xpm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xpm.c' object='coders/coders_xpm_la-xpm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xpm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_xpm_la-xpm.lo `test -f 'coders/xpm.c' || echo '$(srcdir)/'`coders/xpm.c
+
+coders/coders_xwd_la-xwd.lo: coders/xwd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xwd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_xwd_la-xwd.lo -MD -MP -MF coders/$(DEPDIR)/coders_xwd_la-xwd.Tpo -c -o coders/coders_xwd_la-xwd.lo `test -f 'coders/xwd.c' || echo '$(srcdir)/'`coders/xwd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_xwd_la-xwd.Tpo coders/$(DEPDIR)/coders_xwd_la-xwd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xwd.c' object='coders/coders_xwd_la-xwd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_xwd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_xwd_la-xwd.lo `test -f 'coders/xwd.c' || echo '$(srcdir)/'`coders/xwd.c
+
+coders/coders_yuv_la-yuv.lo: coders/yuv.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_yuv_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/coders_yuv_la-yuv.lo -MD -MP -MF coders/$(DEPDIR)/coders_yuv_la-yuv.Tpo -c -o coders/coders_yuv_la-yuv.lo `test -f 'coders/yuv.c' || echo '$(srcdir)/'`coders/yuv.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/coders_yuv_la-yuv.Tpo coders/$(DEPDIR)/coders_yuv_la-yuv.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/yuv.c' object='coders/coders_yuv_la-yuv.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(coders_yuv_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/coders_yuv_la-yuv.lo `test -f 'coders/yuv.c' || echo '$(srcdir)/'`coders/yuv.c
+
+filters/filters_analyze_la-analyze.lo: filters/analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(filters_analyze_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT filters/filters_analyze_la-analyze.lo -MD -MP -MF filters/$(DEPDIR)/filters_analyze_la-analyze.Tpo -c -o filters/filters_analyze_la-analyze.lo `test -f 'filters/analyze.c' || echo '$(srcdir)/'`filters/analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) filters/$(DEPDIR)/filters_analyze_la-analyze.Tpo filters/$(DEPDIR)/filters_analyze_la-analyze.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filters/analyze.c' object='filters/filters_analyze_la-analyze.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(filters_analyze_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o filters/filters_analyze_la-analyze.lo `test -f 'filters/analyze.c' || echo '$(srcdir)/'`filters/analyze.c
+
+magick/magick_libGraphicsMagick_la-analyze.lo: magick/analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-analyze.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-analyze.Tpo -c -o magick/magick_libGraphicsMagick_la-analyze.lo `test -f 'magick/analyze.c' || echo '$(srcdir)/'`magick/analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-analyze.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-analyze.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/analyze.c' object='magick/magick_libGraphicsMagick_la-analyze.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-analyze.lo `test -f 'magick/analyze.c' || echo '$(srcdir)/'`magick/analyze.c
+
+magick/magick_libGraphicsMagick_la-annotate.lo: magick/annotate.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-annotate.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-annotate.Tpo -c -o magick/magick_libGraphicsMagick_la-annotate.lo `test -f 'magick/annotate.c' || echo '$(srcdir)/'`magick/annotate.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-annotate.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-annotate.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/annotate.c' object='magick/magick_libGraphicsMagick_la-annotate.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-annotate.lo `test -f 'magick/annotate.c' || echo '$(srcdir)/'`magick/annotate.c
+
+magick/magick_libGraphicsMagick_la-attribute.lo: magick/attribute.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-attribute.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-attribute.Tpo -c -o magick/magick_libGraphicsMagick_la-attribute.lo `test -f 'magick/attribute.c' || echo '$(srcdir)/'`magick/attribute.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-attribute.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-attribute.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/attribute.c' object='magick/magick_libGraphicsMagick_la-attribute.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-attribute.lo `test -f 'magick/attribute.c' || echo '$(srcdir)/'`magick/attribute.c
+
+magick/magick_libGraphicsMagick_la-average.lo: magick/average.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-average.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-average.Tpo -c -o magick/magick_libGraphicsMagick_la-average.lo `test -f 'magick/average.c' || echo '$(srcdir)/'`magick/average.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-average.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-average.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/average.c' object='magick/magick_libGraphicsMagick_la-average.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-average.lo `test -f 'magick/average.c' || echo '$(srcdir)/'`magick/average.c
+
+magick/magick_libGraphicsMagick_la-bit_stream.lo: magick/bit_stream.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-bit_stream.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-bit_stream.Tpo -c -o magick/magick_libGraphicsMagick_la-bit_stream.lo `test -f 'magick/bit_stream.c' || echo '$(srcdir)/'`magick/bit_stream.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-bit_stream.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-bit_stream.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/bit_stream.c' object='magick/magick_libGraphicsMagick_la-bit_stream.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-bit_stream.lo `test -f 'magick/bit_stream.c' || echo '$(srcdir)/'`magick/bit_stream.c
+
+magick/magick_libGraphicsMagick_la-blob.lo: magick/blob.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-blob.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-blob.Tpo -c -o magick/magick_libGraphicsMagick_la-blob.lo `test -f 'magick/blob.c' || echo '$(srcdir)/'`magick/blob.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-blob.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-blob.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/blob.c' object='magick/magick_libGraphicsMagick_la-blob.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-blob.lo `test -f 'magick/blob.c' || echo '$(srcdir)/'`magick/blob.c
+
+magick/magick_libGraphicsMagick_la-cdl.lo: magick/cdl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-cdl.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-cdl.Tpo -c -o magick/magick_libGraphicsMagick_la-cdl.lo `test -f 'magick/cdl.c' || echo '$(srcdir)/'`magick/cdl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-cdl.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-cdl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/cdl.c' object='magick/magick_libGraphicsMagick_la-cdl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-cdl.lo `test -f 'magick/cdl.c' || echo '$(srcdir)/'`magick/cdl.c
+
+magick/magick_libGraphicsMagick_la-channel.lo: magick/channel.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-channel.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-channel.Tpo -c -o magick/magick_libGraphicsMagick_la-channel.lo `test -f 'magick/channel.c' || echo '$(srcdir)/'`magick/channel.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-channel.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-channel.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/channel.c' object='magick/magick_libGraphicsMagick_la-channel.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-channel.lo `test -f 'magick/channel.c' || echo '$(srcdir)/'`magick/channel.c
+
+magick/magick_libGraphicsMagick_la-compare.lo: magick/compare.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-compare.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-compare.Tpo -c -o magick/magick_libGraphicsMagick_la-compare.lo `test -f 'magick/compare.c' || echo '$(srcdir)/'`magick/compare.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-compare.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-compare.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/compare.c' object='magick/magick_libGraphicsMagick_la-compare.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-compare.lo `test -f 'magick/compare.c' || echo '$(srcdir)/'`magick/compare.c
+
+magick/magick_libGraphicsMagick_la-confirm_access.lo: magick/confirm_access.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-confirm_access.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-confirm_access.Tpo -c -o magick/magick_libGraphicsMagick_la-confirm_access.lo `test -f 'magick/confirm_access.c' || echo '$(srcdir)/'`magick/confirm_access.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-confirm_access.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-confirm_access.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/confirm_access.c' object='magick/magick_libGraphicsMagick_la-confirm_access.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-confirm_access.lo `test -f 'magick/confirm_access.c' || echo '$(srcdir)/'`magick/confirm_access.c
+
+magick/magick_libGraphicsMagick_la-color.lo: magick/color.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-color.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-color.Tpo -c -o magick/magick_libGraphicsMagick_la-color.lo `test -f 'magick/color.c' || echo '$(srcdir)/'`magick/color.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-color.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-color.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/color.c' object='magick/magick_libGraphicsMagick_la-color.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-color.lo `test -f 'magick/color.c' || echo '$(srcdir)/'`magick/color.c
+
+magick/magick_libGraphicsMagick_la-color_lookup.lo: magick/color_lookup.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-color_lookup.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-color_lookup.Tpo -c -o magick/magick_libGraphicsMagick_la-color_lookup.lo `test -f 'magick/color_lookup.c' || echo '$(srcdir)/'`magick/color_lookup.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-color_lookup.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-color_lookup.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/color_lookup.c' object='magick/magick_libGraphicsMagick_la-color_lookup.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-color_lookup.lo `test -f 'magick/color_lookup.c' || echo '$(srcdir)/'`magick/color_lookup.c
+
+magick/magick_libGraphicsMagick_la-colormap.lo: magick/colormap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-colormap.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-colormap.Tpo -c -o magick/magick_libGraphicsMagick_la-colormap.lo `test -f 'magick/colormap.c' || echo '$(srcdir)/'`magick/colormap.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-colormap.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-colormap.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/colormap.c' object='magick/magick_libGraphicsMagick_la-colormap.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-colormap.lo `test -f 'magick/colormap.c' || echo '$(srcdir)/'`magick/colormap.c
+
+magick/magick_libGraphicsMagick_la-colorspace.lo: magick/colorspace.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-colorspace.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-colorspace.Tpo -c -o magick/magick_libGraphicsMagick_la-colorspace.lo `test -f 'magick/colorspace.c' || echo '$(srcdir)/'`magick/colorspace.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-colorspace.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-colorspace.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/colorspace.c' object='magick/magick_libGraphicsMagick_la-colorspace.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-colorspace.lo `test -f 'magick/colorspace.c' || echo '$(srcdir)/'`magick/colorspace.c
+
+magick/magick_libGraphicsMagick_la-command.lo: magick/command.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-command.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-command.Tpo -c -o magick/magick_libGraphicsMagick_la-command.lo `test -f 'magick/command.c' || echo '$(srcdir)/'`magick/command.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-command.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-command.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/command.c' object='magick/magick_libGraphicsMagick_la-command.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-command.lo `test -f 'magick/command.c' || echo '$(srcdir)/'`magick/command.c
+
+magick/magick_libGraphicsMagick_la-composite.lo: magick/composite.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-composite.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-composite.Tpo -c -o magick/magick_libGraphicsMagick_la-composite.lo `test -f 'magick/composite.c' || echo '$(srcdir)/'`magick/composite.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-composite.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-composite.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/composite.c' object='magick/magick_libGraphicsMagick_la-composite.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-composite.lo `test -f 'magick/composite.c' || echo '$(srcdir)/'`magick/composite.c
+
+magick/magick_libGraphicsMagick_la-compress.lo: magick/compress.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-compress.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-compress.Tpo -c -o magick/magick_libGraphicsMagick_la-compress.lo `test -f 'magick/compress.c' || echo '$(srcdir)/'`magick/compress.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-compress.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-compress.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/compress.c' object='magick/magick_libGraphicsMagick_la-compress.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-compress.lo `test -f 'magick/compress.c' || echo '$(srcdir)/'`magick/compress.c
+
+magick/magick_libGraphicsMagick_la-constitute.lo: magick/constitute.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-constitute.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-constitute.Tpo -c -o magick/magick_libGraphicsMagick_la-constitute.lo `test -f 'magick/constitute.c' || echo '$(srcdir)/'`magick/constitute.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-constitute.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-constitute.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/constitute.c' object='magick/magick_libGraphicsMagick_la-constitute.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-constitute.lo `test -f 'magick/constitute.c' || echo '$(srcdir)/'`magick/constitute.c
+
+magick/magick_libGraphicsMagick_la-decorate.lo: magick/decorate.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-decorate.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-decorate.Tpo -c -o magick/magick_libGraphicsMagick_la-decorate.lo `test -f 'magick/decorate.c' || echo '$(srcdir)/'`magick/decorate.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-decorate.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-decorate.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/decorate.c' object='magick/magick_libGraphicsMagick_la-decorate.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-decorate.lo `test -f 'magick/decorate.c' || echo '$(srcdir)/'`magick/decorate.c
+
+magick/magick_libGraphicsMagick_la-delegate.lo: magick/delegate.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-delegate.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-delegate.Tpo -c -o magick/magick_libGraphicsMagick_la-delegate.lo `test -f 'magick/delegate.c' || echo '$(srcdir)/'`magick/delegate.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-delegate.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-delegate.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/delegate.c' object='magick/magick_libGraphicsMagick_la-delegate.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-delegate.lo `test -f 'magick/delegate.c' || echo '$(srcdir)/'`magick/delegate.c
+
+magick/magick_libGraphicsMagick_la-deprecate.lo: magick/deprecate.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-deprecate.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-deprecate.Tpo -c -o magick/magick_libGraphicsMagick_la-deprecate.lo `test -f 'magick/deprecate.c' || echo '$(srcdir)/'`magick/deprecate.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-deprecate.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-deprecate.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/deprecate.c' object='magick/magick_libGraphicsMagick_la-deprecate.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-deprecate.lo `test -f 'magick/deprecate.c' || echo '$(srcdir)/'`magick/deprecate.c
+
+magick/magick_libGraphicsMagick_la-describe.lo: magick/describe.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-describe.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-describe.Tpo -c -o magick/magick_libGraphicsMagick_la-describe.lo `test -f 'magick/describe.c' || echo '$(srcdir)/'`magick/describe.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-describe.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-describe.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/describe.c' object='magick/magick_libGraphicsMagick_la-describe.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-describe.lo `test -f 'magick/describe.c' || echo '$(srcdir)/'`magick/describe.c
+
+magick/magick_libGraphicsMagick_la-draw.lo: magick/draw.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-draw.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-draw.Tpo -c -o magick/magick_libGraphicsMagick_la-draw.lo `test -f 'magick/draw.c' || echo '$(srcdir)/'`magick/draw.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-draw.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-draw.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/draw.c' object='magick/magick_libGraphicsMagick_la-draw.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-draw.lo `test -f 'magick/draw.c' || echo '$(srcdir)/'`magick/draw.c
+
+magick/magick_libGraphicsMagick_la-effect.lo: magick/effect.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-effect.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-effect.Tpo -c -o magick/magick_libGraphicsMagick_la-effect.lo `test -f 'magick/effect.c' || echo '$(srcdir)/'`magick/effect.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-effect.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-effect.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/effect.c' object='magick/magick_libGraphicsMagick_la-effect.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-effect.lo `test -f 'magick/effect.c' || echo '$(srcdir)/'`magick/effect.c
+
+magick/magick_libGraphicsMagick_la-enhance.lo: magick/enhance.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-enhance.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-enhance.Tpo -c -o magick/magick_libGraphicsMagick_la-enhance.lo `test -f 'magick/enhance.c' || echo '$(srcdir)/'`magick/enhance.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-enhance.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-enhance.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/enhance.c' object='magick/magick_libGraphicsMagick_la-enhance.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-enhance.lo `test -f 'magick/enhance.c' || echo '$(srcdir)/'`magick/enhance.c
+
+magick/magick_libGraphicsMagick_la-enum_strings.lo: magick/enum_strings.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-enum_strings.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-enum_strings.Tpo -c -o magick/magick_libGraphicsMagick_la-enum_strings.lo `test -f 'magick/enum_strings.c' || echo '$(srcdir)/'`magick/enum_strings.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-enum_strings.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-enum_strings.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/enum_strings.c' object='magick/magick_libGraphicsMagick_la-enum_strings.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-enum_strings.lo `test -f 'magick/enum_strings.c' || echo '$(srcdir)/'`magick/enum_strings.c
+
+magick/magick_libGraphicsMagick_la-error.lo: magick/error.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-error.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-error.Tpo -c -o magick/magick_libGraphicsMagick_la-error.lo `test -f 'magick/error.c' || echo '$(srcdir)/'`magick/error.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-error.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-error.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/error.c' object='magick/magick_libGraphicsMagick_la-error.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-error.lo `test -f 'magick/error.c' || echo '$(srcdir)/'`magick/error.c
+
+magick/magick_libGraphicsMagick_la-export.lo: magick/export.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-export.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-export.Tpo -c -o magick/magick_libGraphicsMagick_la-export.lo `test -f 'magick/export.c' || echo '$(srcdir)/'`magick/export.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-export.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-export.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/export.c' object='magick/magick_libGraphicsMagick_la-export.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-export.lo `test -f 'magick/export.c' || echo '$(srcdir)/'`magick/export.c
+
+magick/magick_libGraphicsMagick_la-floats.lo: magick/floats.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-floats.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-floats.Tpo -c -o magick/magick_libGraphicsMagick_la-floats.lo `test -f 'magick/floats.c' || echo '$(srcdir)/'`magick/floats.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-floats.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-floats.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/floats.c' object='magick/magick_libGraphicsMagick_la-floats.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-floats.lo `test -f 'magick/floats.c' || echo '$(srcdir)/'`magick/floats.c
+
+magick/magick_libGraphicsMagick_la-fx.lo: magick/fx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-fx.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-fx.Tpo -c -o magick/magick_libGraphicsMagick_la-fx.lo `test -f 'magick/fx.c' || echo '$(srcdir)/'`magick/fx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-fx.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-fx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/fx.c' object='magick/magick_libGraphicsMagick_la-fx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-fx.lo `test -f 'magick/fx.c' || echo '$(srcdir)/'`magick/fx.c
+
+magick/magick_libGraphicsMagick_la-gem.lo: magick/gem.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-gem.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-gem.Tpo -c -o magick/magick_libGraphicsMagick_la-gem.lo `test -f 'magick/gem.c' || echo '$(srcdir)/'`magick/gem.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-gem.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-gem.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/gem.c' object='magick/magick_libGraphicsMagick_la-gem.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-gem.lo `test -f 'magick/gem.c' || echo '$(srcdir)/'`magick/gem.c
+
+magick/magick_libGraphicsMagick_la-gradient.lo: magick/gradient.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-gradient.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-gradient.Tpo -c -o magick/magick_libGraphicsMagick_la-gradient.lo `test -f 'magick/gradient.c' || echo '$(srcdir)/'`magick/gradient.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-gradient.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-gradient.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/gradient.c' object='magick/magick_libGraphicsMagick_la-gradient.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-gradient.lo `test -f 'magick/gradient.c' || echo '$(srcdir)/'`magick/gradient.c
+
+magick/magick_libGraphicsMagick_la-hclut.lo: magick/hclut.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-hclut.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-hclut.Tpo -c -o magick/magick_libGraphicsMagick_la-hclut.lo `test -f 'magick/hclut.c' || echo '$(srcdir)/'`magick/hclut.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-hclut.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-hclut.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/hclut.c' object='magick/magick_libGraphicsMagick_la-hclut.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-hclut.lo `test -f 'magick/hclut.c' || echo '$(srcdir)/'`magick/hclut.c
+
+magick/magick_libGraphicsMagick_la-image.lo: magick/image.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-image.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-image.Tpo -c -o magick/magick_libGraphicsMagick_la-image.lo `test -f 'magick/image.c' || echo '$(srcdir)/'`magick/image.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-image.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-image.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/image.c' object='magick/magick_libGraphicsMagick_la-image.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-image.lo `test -f 'magick/image.c' || echo '$(srcdir)/'`magick/image.c
+
+magick/magick_libGraphicsMagick_la-import.lo: magick/import.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-import.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-import.Tpo -c -o magick/magick_libGraphicsMagick_la-import.lo `test -f 'magick/import.c' || echo '$(srcdir)/'`magick/import.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-import.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-import.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/import.c' object='magick/magick_libGraphicsMagick_la-import.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-import.lo `test -f 'magick/import.c' || echo '$(srcdir)/'`magick/import.c
+
+magick/magick_libGraphicsMagick_la-list.lo: magick/list.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-list.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-list.Tpo -c -o magick/magick_libGraphicsMagick_la-list.lo `test -f 'magick/list.c' || echo '$(srcdir)/'`magick/list.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-list.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-list.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/list.c' object='magick/magick_libGraphicsMagick_la-list.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-list.lo `test -f 'magick/list.c' || echo '$(srcdir)/'`magick/list.c
+
+magick/magick_libGraphicsMagick_la-locale.lo: magick/locale.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-locale.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-locale.Tpo -c -o magick/magick_libGraphicsMagick_la-locale.lo `test -f 'magick/locale.c' || echo '$(srcdir)/'`magick/locale.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-locale.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-locale.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/locale.c' object='magick/magick_libGraphicsMagick_la-locale.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-locale.lo `test -f 'magick/locale.c' || echo '$(srcdir)/'`magick/locale.c
+
+magick/magick_libGraphicsMagick_la-log.lo: magick/log.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-log.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-log.Tpo -c -o magick/magick_libGraphicsMagick_la-log.lo `test -f 'magick/log.c' || echo '$(srcdir)/'`magick/log.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-log.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-log.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/log.c' object='magick/magick_libGraphicsMagick_la-log.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-log.lo `test -f 'magick/log.c' || echo '$(srcdir)/'`magick/log.c
+
+magick/magick_libGraphicsMagick_la-magic.lo: magick/magic.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-magic.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-magic.Tpo -c -o magick/magick_libGraphicsMagick_la-magic.lo `test -f 'magick/magic.c' || echo '$(srcdir)/'`magick/magic.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-magic.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-magic.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/magic.c' object='magick/magick_libGraphicsMagick_la-magic.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-magic.lo `test -f 'magick/magic.c' || echo '$(srcdir)/'`magick/magic.c
+
+magick/magick_libGraphicsMagick_la-magick.lo: magick/magick.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-magick.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-magick.Tpo -c -o magick/magick_libGraphicsMagick_la-magick.lo `test -f 'magick/magick.c' || echo '$(srcdir)/'`magick/magick.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-magick.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-magick.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/magick.c' object='magick/magick_libGraphicsMagick_la-magick.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-magick.lo `test -f 'magick/magick.c' || echo '$(srcdir)/'`magick/magick.c
+
+magick/magick_libGraphicsMagick_la-magick_endian.lo: magick/magick_endian.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-magick_endian.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-magick_endian.Tpo -c -o magick/magick_libGraphicsMagick_la-magick_endian.lo `test -f 'magick/magick_endian.c' || echo '$(srcdir)/'`magick/magick_endian.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-magick_endian.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-magick_endian.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/magick_endian.c' object='magick/magick_libGraphicsMagick_la-magick_endian.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-magick_endian.lo `test -f 'magick/magick_endian.c' || echo '$(srcdir)/'`magick/magick_endian.c
+
+magick/magick_libGraphicsMagick_la-map.lo: magick/map.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-map.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-map.Tpo -c -o magick/magick_libGraphicsMagick_la-map.lo `test -f 'magick/map.c' || echo '$(srcdir)/'`magick/map.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-map.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-map.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/map.c' object='magick/magick_libGraphicsMagick_la-map.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-map.lo `test -f 'magick/map.c' || echo '$(srcdir)/'`magick/map.c
+
+magick/magick_libGraphicsMagick_la-memory.lo: magick/memory.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-memory.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-memory.Tpo -c -o magick/magick_libGraphicsMagick_la-memory.lo `test -f 'magick/memory.c' || echo '$(srcdir)/'`magick/memory.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-memory.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-memory.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/memory.c' object='magick/magick_libGraphicsMagick_la-memory.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-memory.lo `test -f 'magick/memory.c' || echo '$(srcdir)/'`magick/memory.c
+
+magick/magick_libGraphicsMagick_la-module.lo: magick/module.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-module.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-module.Tpo -c -o magick/magick_libGraphicsMagick_la-module.lo `test -f 'magick/module.c' || echo '$(srcdir)/'`magick/module.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-module.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-module.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/module.c' object='magick/magick_libGraphicsMagick_la-module.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-module.lo `test -f 'magick/module.c' || echo '$(srcdir)/'`magick/module.c
+
+magick/magick_libGraphicsMagick_la-monitor.lo: magick/monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-monitor.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-monitor.Tpo -c -o magick/magick_libGraphicsMagick_la-monitor.lo `test -f 'magick/monitor.c' || echo '$(srcdir)/'`magick/monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-monitor.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-monitor.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/monitor.c' object='magick/magick_libGraphicsMagick_la-monitor.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-monitor.lo `test -f 'magick/monitor.c' || echo '$(srcdir)/'`magick/monitor.c
+
+magick/magick_libGraphicsMagick_la-montage.lo: magick/montage.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-montage.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-montage.Tpo -c -o magick/magick_libGraphicsMagick_la-montage.lo `test -f 'magick/montage.c' || echo '$(srcdir)/'`magick/montage.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-montage.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-montage.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/montage.c' object='magick/magick_libGraphicsMagick_la-montage.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-montage.lo `test -f 'magick/montage.c' || echo '$(srcdir)/'`magick/montage.c
+
+magick/magick_libGraphicsMagick_la-omp_data_view.lo: magick/omp_data_view.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-omp_data_view.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-omp_data_view.Tpo -c -o magick/magick_libGraphicsMagick_la-omp_data_view.lo `test -f 'magick/omp_data_view.c' || echo '$(srcdir)/'`magick/omp_data_view.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-omp_data_view.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-omp_data_view.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/omp_data_view.c' object='magick/magick_libGraphicsMagick_la-omp_data_view.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-omp_data_view.lo `test -f 'magick/omp_data_view.c' || echo '$(srcdir)/'`magick/omp_data_view.c
+
+magick/magick_libGraphicsMagick_la-operator.lo: magick/operator.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-operator.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-operator.Tpo -c -o magick/magick_libGraphicsMagick_la-operator.lo `test -f 'magick/operator.c' || echo '$(srcdir)/'`magick/operator.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-operator.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-operator.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/operator.c' object='magick/magick_libGraphicsMagick_la-operator.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-operator.lo `test -f 'magick/operator.c' || echo '$(srcdir)/'`magick/operator.c
+
+magick/magick_libGraphicsMagick_la-paint.lo: magick/paint.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-paint.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-paint.Tpo -c -o magick/magick_libGraphicsMagick_la-paint.lo `test -f 'magick/paint.c' || echo '$(srcdir)/'`magick/paint.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-paint.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-paint.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/paint.c' object='magick/magick_libGraphicsMagick_la-paint.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-paint.lo `test -f 'magick/paint.c' || echo '$(srcdir)/'`magick/paint.c
+
+magick/magick_libGraphicsMagick_la-pixel_cache.lo: magick/pixel_cache.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-pixel_cache.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-pixel_cache.Tpo -c -o magick/magick_libGraphicsMagick_la-pixel_cache.lo `test -f 'magick/pixel_cache.c' || echo '$(srcdir)/'`magick/pixel_cache.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-pixel_cache.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-pixel_cache.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/pixel_cache.c' object='magick/magick_libGraphicsMagick_la-pixel_cache.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-pixel_cache.lo `test -f 'magick/pixel_cache.c' || echo '$(srcdir)/'`magick/pixel_cache.c
+
+magick/magick_libGraphicsMagick_la-pixel_iterator.lo: magick/pixel_iterator.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-pixel_iterator.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-pixel_iterator.Tpo -c -o magick/magick_libGraphicsMagick_la-pixel_iterator.lo `test -f 'magick/pixel_iterator.c' || echo '$(srcdir)/'`magick/pixel_iterator.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-pixel_iterator.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-pixel_iterator.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/pixel_iterator.c' object='magick/magick_libGraphicsMagick_la-pixel_iterator.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-pixel_iterator.lo `test -f 'magick/pixel_iterator.c' || echo '$(srcdir)/'`magick/pixel_iterator.c
+
+magick/magick_libGraphicsMagick_la-plasma.lo: magick/plasma.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-plasma.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-plasma.Tpo -c -o magick/magick_libGraphicsMagick_la-plasma.lo `test -f 'magick/plasma.c' || echo '$(srcdir)/'`magick/plasma.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-plasma.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-plasma.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/plasma.c' object='magick/magick_libGraphicsMagick_la-plasma.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-plasma.lo `test -f 'magick/plasma.c' || echo '$(srcdir)/'`magick/plasma.c
+
+magick/magick_libGraphicsMagick_la-profile.lo: magick/profile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-profile.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-profile.Tpo -c -o magick/magick_libGraphicsMagick_la-profile.lo `test -f 'magick/profile.c' || echo '$(srcdir)/'`magick/profile.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-profile.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-profile.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/profile.c' object='magick/magick_libGraphicsMagick_la-profile.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-profile.lo `test -f 'magick/profile.c' || echo '$(srcdir)/'`magick/profile.c
+
+magick/magick_libGraphicsMagick_la-quantize.lo: magick/quantize.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-quantize.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-quantize.Tpo -c -o magick/magick_libGraphicsMagick_la-quantize.lo `test -f 'magick/quantize.c' || echo '$(srcdir)/'`magick/quantize.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-quantize.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-quantize.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/quantize.c' object='magick/magick_libGraphicsMagick_la-quantize.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-quantize.lo `test -f 'magick/quantize.c' || echo '$(srcdir)/'`magick/quantize.c
+
+magick/magick_libGraphicsMagick_la-registry.lo: magick/registry.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-registry.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-registry.Tpo -c -o magick/magick_libGraphicsMagick_la-registry.lo `test -f 'magick/registry.c' || echo '$(srcdir)/'`magick/registry.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-registry.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-registry.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/registry.c' object='magick/magick_libGraphicsMagick_la-registry.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-registry.lo `test -f 'magick/registry.c' || echo '$(srcdir)/'`magick/registry.c
+
+magick/magick_libGraphicsMagick_la-random.lo: magick/random.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-random.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-random.Tpo -c -o magick/magick_libGraphicsMagick_la-random.lo `test -f 'magick/random.c' || echo '$(srcdir)/'`magick/random.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-random.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-random.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/random.c' object='magick/magick_libGraphicsMagick_la-random.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-random.lo `test -f 'magick/random.c' || echo '$(srcdir)/'`magick/random.c
+
+magick/magick_libGraphicsMagick_la-render.lo: magick/render.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-render.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-render.Tpo -c -o magick/magick_libGraphicsMagick_la-render.lo `test -f 'magick/render.c' || echo '$(srcdir)/'`magick/render.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-render.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-render.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/render.c' object='magick/magick_libGraphicsMagick_la-render.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-render.lo `test -f 'magick/render.c' || echo '$(srcdir)/'`magick/render.c
+
+magick/magick_libGraphicsMagick_la-resize.lo: magick/resize.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-resize.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-resize.Tpo -c -o magick/magick_libGraphicsMagick_la-resize.lo `test -f 'magick/resize.c' || echo '$(srcdir)/'`magick/resize.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-resize.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-resize.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/resize.c' object='magick/magick_libGraphicsMagick_la-resize.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-resize.lo `test -f 'magick/resize.c' || echo '$(srcdir)/'`magick/resize.c
+
+magick/magick_libGraphicsMagick_la-resource.lo: magick/resource.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-resource.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-resource.Tpo -c -o magick/magick_libGraphicsMagick_la-resource.lo `test -f 'magick/resource.c' || echo '$(srcdir)/'`magick/resource.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-resource.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-resource.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/resource.c' object='magick/magick_libGraphicsMagick_la-resource.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-resource.lo `test -f 'magick/resource.c' || echo '$(srcdir)/'`magick/resource.c
+
+magick/magick_libGraphicsMagick_la-segment.lo: magick/segment.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-segment.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-segment.Tpo -c -o magick/magick_libGraphicsMagick_la-segment.lo `test -f 'magick/segment.c' || echo '$(srcdir)/'`magick/segment.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-segment.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-segment.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/segment.c' object='magick/magick_libGraphicsMagick_la-segment.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-segment.lo `test -f 'magick/segment.c' || echo '$(srcdir)/'`magick/segment.c
+
+magick/magick_libGraphicsMagick_la-semaphore.lo: magick/semaphore.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-semaphore.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-semaphore.Tpo -c -o magick/magick_libGraphicsMagick_la-semaphore.lo `test -f 'magick/semaphore.c' || echo '$(srcdir)/'`magick/semaphore.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-semaphore.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-semaphore.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/semaphore.c' object='magick/magick_libGraphicsMagick_la-semaphore.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-semaphore.lo `test -f 'magick/semaphore.c' || echo '$(srcdir)/'`magick/semaphore.c
+
+magick/magick_libGraphicsMagick_la-shear.lo: magick/shear.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-shear.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-shear.Tpo -c -o magick/magick_libGraphicsMagick_la-shear.lo `test -f 'magick/shear.c' || echo '$(srcdir)/'`magick/shear.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-shear.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-shear.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/shear.c' object='magick/magick_libGraphicsMagick_la-shear.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-shear.lo `test -f 'magick/shear.c' || echo '$(srcdir)/'`magick/shear.c
+
+magick/magick_libGraphicsMagick_la-signature.lo: magick/signature.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-signature.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-signature.Tpo -c -o magick/magick_libGraphicsMagick_la-signature.lo `test -f 'magick/signature.c' || echo '$(srcdir)/'`magick/signature.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-signature.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-signature.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/signature.c' object='magick/magick_libGraphicsMagick_la-signature.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-signature.lo `test -f 'magick/signature.c' || echo '$(srcdir)/'`magick/signature.c
+
+magick/magick_libGraphicsMagick_la-static.lo: magick/static.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-static.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-static.Tpo -c -o magick/magick_libGraphicsMagick_la-static.lo `test -f 'magick/static.c' || echo '$(srcdir)/'`magick/static.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-static.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-static.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/static.c' object='magick/magick_libGraphicsMagick_la-static.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-static.lo `test -f 'magick/static.c' || echo '$(srcdir)/'`magick/static.c
+
+magick/magick_libGraphicsMagick_la-statistics.lo: magick/statistics.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-statistics.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-statistics.Tpo -c -o magick/magick_libGraphicsMagick_la-statistics.lo `test -f 'magick/statistics.c' || echo '$(srcdir)/'`magick/statistics.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-statistics.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-statistics.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/statistics.c' object='magick/magick_libGraphicsMagick_la-statistics.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-statistics.lo `test -f 'magick/statistics.c' || echo '$(srcdir)/'`magick/statistics.c
+
+magick/magick_libGraphicsMagick_la-tempfile.lo: magick/tempfile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-tempfile.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-tempfile.Tpo -c -o magick/magick_libGraphicsMagick_la-tempfile.lo `test -f 'magick/tempfile.c' || echo '$(srcdir)/'`magick/tempfile.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-tempfile.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-tempfile.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/tempfile.c' object='magick/magick_libGraphicsMagick_la-tempfile.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-tempfile.lo `test -f 'magick/tempfile.c' || echo '$(srcdir)/'`magick/tempfile.c
+
+magick/magick_libGraphicsMagick_la-texture.lo: magick/texture.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-texture.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-texture.Tpo -c -o magick/magick_libGraphicsMagick_la-texture.lo `test -f 'magick/texture.c' || echo '$(srcdir)/'`magick/texture.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-texture.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-texture.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/texture.c' object='magick/magick_libGraphicsMagick_la-texture.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-texture.lo `test -f 'magick/texture.c' || echo '$(srcdir)/'`magick/texture.c
+
+magick/magick_libGraphicsMagick_la-timer.lo: magick/timer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-timer.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-timer.Tpo -c -o magick/magick_libGraphicsMagick_la-timer.lo `test -f 'magick/timer.c' || echo '$(srcdir)/'`magick/timer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-timer.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-timer.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/timer.c' object='magick/magick_libGraphicsMagick_la-timer.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-timer.lo `test -f 'magick/timer.c' || echo '$(srcdir)/'`magick/timer.c
+
+magick/magick_libGraphicsMagick_la-transform.lo: magick/transform.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-transform.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-transform.Tpo -c -o magick/magick_libGraphicsMagick_la-transform.lo `test -f 'magick/transform.c' || echo '$(srcdir)/'`magick/transform.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-transform.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-transform.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/transform.c' object='magick/magick_libGraphicsMagick_la-transform.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-transform.lo `test -f 'magick/transform.c' || echo '$(srcdir)/'`magick/transform.c
+
+magick/magick_libGraphicsMagick_la-tsd.lo: magick/tsd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-tsd.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-tsd.Tpo -c -o magick/magick_libGraphicsMagick_la-tsd.lo `test -f 'magick/tsd.c' || echo '$(srcdir)/'`magick/tsd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-tsd.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-tsd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/tsd.c' object='magick/magick_libGraphicsMagick_la-tsd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-tsd.lo `test -f 'magick/tsd.c' || echo '$(srcdir)/'`magick/tsd.c
+
+magick/magick_libGraphicsMagick_la-type.lo: magick/type.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-type.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-type.Tpo -c -o magick/magick_libGraphicsMagick_la-type.lo `test -f 'magick/type.c' || echo '$(srcdir)/'`magick/type.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-type.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-type.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/type.c' object='magick/magick_libGraphicsMagick_la-type.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-type.lo `test -f 'magick/type.c' || echo '$(srcdir)/'`magick/type.c
+
+magick/magick_libGraphicsMagick_la-unix_port.lo: magick/unix_port.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-unix_port.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-unix_port.Tpo -c -o magick/magick_libGraphicsMagick_la-unix_port.lo `test -f 'magick/unix_port.c' || echo '$(srcdir)/'`magick/unix_port.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-unix_port.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-unix_port.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/unix_port.c' object='magick/magick_libGraphicsMagick_la-unix_port.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-unix_port.lo `test -f 'magick/unix_port.c' || echo '$(srcdir)/'`magick/unix_port.c
+
+magick/magick_libGraphicsMagick_la-utility.lo: magick/utility.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-utility.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-utility.Tpo -c -o magick/magick_libGraphicsMagick_la-utility.lo `test -f 'magick/utility.c' || echo '$(srcdir)/'`magick/utility.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-utility.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-utility.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/utility.c' object='magick/magick_libGraphicsMagick_la-utility.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-utility.lo `test -f 'magick/utility.c' || echo '$(srcdir)/'`magick/utility.c
+
+magick/magick_libGraphicsMagick_la-version.lo: magick/version.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-version.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-version.Tpo -c -o magick/magick_libGraphicsMagick_la-version.lo `test -f 'magick/version.c' || echo '$(srcdir)/'`magick/version.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-version.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-version.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/version.c' object='magick/magick_libGraphicsMagick_la-version.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-version.lo `test -f 'magick/version.c' || echo '$(srcdir)/'`magick/version.c
+
+magick/magick_libGraphicsMagick_la-animate.lo: magick/animate.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-animate.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-animate.Tpo -c -o magick/magick_libGraphicsMagick_la-animate.lo `test -f 'magick/animate.c' || echo '$(srcdir)/'`magick/animate.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-animate.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-animate.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/animate.c' object='magick/magick_libGraphicsMagick_la-animate.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-animate.lo `test -f 'magick/animate.c' || echo '$(srcdir)/'`magick/animate.c
+
+magick/magick_libGraphicsMagick_la-display.lo: magick/display.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-display.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-display.Tpo -c -o magick/magick_libGraphicsMagick_la-display.lo `test -f 'magick/display.c' || echo '$(srcdir)/'`magick/display.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-display.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-display.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/display.c' object='magick/magick_libGraphicsMagick_la-display.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-display.lo `test -f 'magick/display.c' || echo '$(srcdir)/'`magick/display.c
+
+magick/magick_libGraphicsMagick_la-PreRvIcccm.lo: magick/PreRvIcccm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-PreRvIcccm.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-PreRvIcccm.Tpo -c -o magick/magick_libGraphicsMagick_la-PreRvIcccm.lo `test -f 'magick/PreRvIcccm.c' || echo '$(srcdir)/'`magick/PreRvIcccm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-PreRvIcccm.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-PreRvIcccm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/PreRvIcccm.c' object='magick/magick_libGraphicsMagick_la-PreRvIcccm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-PreRvIcccm.lo `test -f 'magick/PreRvIcccm.c' || echo '$(srcdir)/'`magick/PreRvIcccm.c
+
+magick/magick_libGraphicsMagick_la-widget.lo: magick/widget.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-widget.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-widget.Tpo -c -o magick/magick_libGraphicsMagick_la-widget.lo `test -f 'magick/widget.c' || echo '$(srcdir)/'`magick/widget.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-widget.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-widget.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/widget.c' object='magick/magick_libGraphicsMagick_la-widget.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-widget.lo `test -f 'magick/widget.c' || echo '$(srcdir)/'`magick/widget.c
+
+magick/magick_libGraphicsMagick_la-xwindow.lo: magick/xwindow.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-xwindow.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-xwindow.Tpo -c -o magick/magick_libGraphicsMagick_la-xwindow.lo `test -f 'magick/xwindow.c' || echo '$(srcdir)/'`magick/xwindow.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-xwindow.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-xwindow.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/xwindow.c' object='magick/magick_libGraphicsMagick_la-xwindow.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-xwindow.lo `test -f 'magick/xwindow.c' || echo '$(srcdir)/'`magick/xwindow.c
+
+magick/magick_libGraphicsMagick_la-nt_feature.lo: magick/nt_feature.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-nt_feature.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-nt_feature.Tpo -c -o magick/magick_libGraphicsMagick_la-nt_feature.lo `test -f 'magick/nt_feature.c' || echo '$(srcdir)/'`magick/nt_feature.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-nt_feature.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-nt_feature.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/nt_feature.c' object='magick/magick_libGraphicsMagick_la-nt_feature.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-nt_feature.lo `test -f 'magick/nt_feature.c' || echo '$(srcdir)/'`magick/nt_feature.c
+
+magick/magick_libGraphicsMagick_la-nt_base.lo: magick/nt_base.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT magick/magick_libGraphicsMagick_la-nt_base.lo -MD -MP -MF magick/$(DEPDIR)/magick_libGraphicsMagick_la-nt_base.Tpo -c -o magick/magick_libGraphicsMagick_la-nt_base.lo `test -f 'magick/nt_base.c' || echo '$(srcdir)/'`magick/nt_base.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) magick/$(DEPDIR)/magick_libGraphicsMagick_la-nt_base.Tpo magick/$(DEPDIR)/magick_libGraphicsMagick_la-nt_base.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='magick/nt_base.c' object='magick/magick_libGraphicsMagick_la-nt_base.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o magick/magick_libGraphicsMagick_la-nt_base.lo `test -f 'magick/nt_base.c' || echo '$(srcdir)/'`magick/nt_base.c
+
+coders/magick_libGraphicsMagick_la-png.lo: coders/png.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-png.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-png.Tpo -c -o coders/magick_libGraphicsMagick_la-png.lo `test -f 'coders/png.c' || echo '$(srcdir)/'`coders/png.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-png.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-png.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/png.c' object='coders/magick_libGraphicsMagick_la-png.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-png.lo `test -f 'coders/png.c' || echo '$(srcdir)/'`coders/png.c
+
+coders/magick_libGraphicsMagick_la-art.lo: coders/art.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-art.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-art.Tpo -c -o coders/magick_libGraphicsMagick_la-art.lo `test -f 'coders/art.c' || echo '$(srcdir)/'`coders/art.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-art.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-art.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/art.c' object='coders/magick_libGraphicsMagick_la-art.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-art.lo `test -f 'coders/art.c' || echo '$(srcdir)/'`coders/art.c
+
+coders/magick_libGraphicsMagick_la-avs.lo: coders/avs.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-avs.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-avs.Tpo -c -o coders/magick_libGraphicsMagick_la-avs.lo `test -f 'coders/avs.c' || echo '$(srcdir)/'`coders/avs.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-avs.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-avs.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/avs.c' object='coders/magick_libGraphicsMagick_la-avs.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-avs.lo `test -f 'coders/avs.c' || echo '$(srcdir)/'`coders/avs.c
+
+coders/magick_libGraphicsMagick_la-bmp.lo: coders/bmp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-bmp.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-bmp.Tpo -c -o coders/magick_libGraphicsMagick_la-bmp.lo `test -f 'coders/bmp.c' || echo '$(srcdir)/'`coders/bmp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-bmp.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-bmp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/bmp.c' object='coders/magick_libGraphicsMagick_la-bmp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-bmp.lo `test -f 'coders/bmp.c' || echo '$(srcdir)/'`coders/bmp.c
+
+coders/magick_libGraphicsMagick_la-cals.lo: coders/cals.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-cals.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-cals.Tpo -c -o coders/magick_libGraphicsMagick_la-cals.lo `test -f 'coders/cals.c' || echo '$(srcdir)/'`coders/cals.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-cals.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-cals.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/cals.c' object='coders/magick_libGraphicsMagick_la-cals.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-cals.lo `test -f 'coders/cals.c' || echo '$(srcdir)/'`coders/cals.c
+
+coders/magick_libGraphicsMagick_la-caption.lo: coders/caption.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-caption.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-caption.Tpo -c -o coders/magick_libGraphicsMagick_la-caption.lo `test -f 'coders/caption.c' || echo '$(srcdir)/'`coders/caption.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-caption.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-caption.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/caption.c' object='coders/magick_libGraphicsMagick_la-caption.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-caption.lo `test -f 'coders/caption.c' || echo '$(srcdir)/'`coders/caption.c
+
+coders/magick_libGraphicsMagick_la-cineon.lo: coders/cineon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-cineon.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-cineon.Tpo -c -o coders/magick_libGraphicsMagick_la-cineon.lo `test -f 'coders/cineon.c' || echo '$(srcdir)/'`coders/cineon.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-cineon.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-cineon.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/cineon.c' object='coders/magick_libGraphicsMagick_la-cineon.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-cineon.lo `test -f 'coders/cineon.c' || echo '$(srcdir)/'`coders/cineon.c
+
+coders/magick_libGraphicsMagick_la-cmyk.lo: coders/cmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-cmyk.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-cmyk.Tpo -c -o coders/magick_libGraphicsMagick_la-cmyk.lo `test -f 'coders/cmyk.c' || echo '$(srcdir)/'`coders/cmyk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-cmyk.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-cmyk.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/cmyk.c' object='coders/magick_libGraphicsMagick_la-cmyk.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-cmyk.lo `test -f 'coders/cmyk.c' || echo '$(srcdir)/'`coders/cmyk.c
+
+coders/magick_libGraphicsMagick_la-cut.lo: coders/cut.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-cut.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-cut.Tpo -c -o coders/magick_libGraphicsMagick_la-cut.lo `test -f 'coders/cut.c' || echo '$(srcdir)/'`coders/cut.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-cut.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-cut.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/cut.c' object='coders/magick_libGraphicsMagick_la-cut.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-cut.lo `test -f 'coders/cut.c' || echo '$(srcdir)/'`coders/cut.c
+
+coders/magick_libGraphicsMagick_la-dcm.lo: coders/dcm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-dcm.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-dcm.Tpo -c -o coders/magick_libGraphicsMagick_la-dcm.lo `test -f 'coders/dcm.c' || echo '$(srcdir)/'`coders/dcm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-dcm.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-dcm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dcm.c' object='coders/magick_libGraphicsMagick_la-dcm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-dcm.lo `test -f 'coders/dcm.c' || echo '$(srcdir)/'`coders/dcm.c
+
+coders/magick_libGraphicsMagick_la-dcraw.lo: coders/dcraw.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-dcraw.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-dcraw.Tpo -c -o coders/magick_libGraphicsMagick_la-dcraw.lo `test -f 'coders/dcraw.c' || echo '$(srcdir)/'`coders/dcraw.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-dcraw.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-dcraw.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dcraw.c' object='coders/magick_libGraphicsMagick_la-dcraw.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-dcraw.lo `test -f 'coders/dcraw.c' || echo '$(srcdir)/'`coders/dcraw.c
+
+coders/magick_libGraphicsMagick_la-dib.lo: coders/dib.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-dib.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-dib.Tpo -c -o coders/magick_libGraphicsMagick_la-dib.lo `test -f 'coders/dib.c' || echo '$(srcdir)/'`coders/dib.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-dib.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-dib.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dib.c' object='coders/magick_libGraphicsMagick_la-dib.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-dib.lo `test -f 'coders/dib.c' || echo '$(srcdir)/'`coders/dib.c
+
+coders/magick_libGraphicsMagick_la-dpx.lo: coders/dpx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-dpx.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-dpx.Tpo -c -o coders/magick_libGraphicsMagick_la-dpx.lo `test -f 'coders/dpx.c' || echo '$(srcdir)/'`coders/dpx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-dpx.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-dpx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dpx.c' object='coders/magick_libGraphicsMagick_la-dpx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-dpx.lo `test -f 'coders/dpx.c' || echo '$(srcdir)/'`coders/dpx.c
+
+coders/magick_libGraphicsMagick_la-fax.lo: coders/fax.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-fax.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-fax.Tpo -c -o coders/magick_libGraphicsMagick_la-fax.lo `test -f 'coders/fax.c' || echo '$(srcdir)/'`coders/fax.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-fax.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-fax.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/fax.c' object='coders/magick_libGraphicsMagick_la-fax.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-fax.lo `test -f 'coders/fax.c' || echo '$(srcdir)/'`coders/fax.c
+
+coders/magick_libGraphicsMagick_la-fits.lo: coders/fits.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-fits.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-fits.Tpo -c -o coders/magick_libGraphicsMagick_la-fits.lo `test -f 'coders/fits.c' || echo '$(srcdir)/'`coders/fits.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-fits.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-fits.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/fits.c' object='coders/magick_libGraphicsMagick_la-fits.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-fits.lo `test -f 'coders/fits.c' || echo '$(srcdir)/'`coders/fits.c
+
+coders/magick_libGraphicsMagick_la-gif.lo: coders/gif.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-gif.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-gif.Tpo -c -o coders/magick_libGraphicsMagick_la-gif.lo `test -f 'coders/gif.c' || echo '$(srcdir)/'`coders/gif.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-gif.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-gif.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/gif.c' object='coders/magick_libGraphicsMagick_la-gif.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-gif.lo `test -f 'coders/gif.c' || echo '$(srcdir)/'`coders/gif.c
+
+coders/magick_libGraphicsMagick_la-gradient.lo: coders/gradient.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-gradient.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-gradient.Tpo -c -o coders/magick_libGraphicsMagick_la-gradient.lo `test -f 'coders/gradient.c' || echo '$(srcdir)/'`coders/gradient.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-gradient.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-gradient.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/gradient.c' object='coders/magick_libGraphicsMagick_la-gradient.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-gradient.lo `test -f 'coders/gradient.c' || echo '$(srcdir)/'`coders/gradient.c
+
+coders/magick_libGraphicsMagick_la-gray.lo: coders/gray.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-gray.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-gray.Tpo -c -o coders/magick_libGraphicsMagick_la-gray.lo `test -f 'coders/gray.c' || echo '$(srcdir)/'`coders/gray.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-gray.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-gray.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/gray.c' object='coders/magick_libGraphicsMagick_la-gray.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-gray.lo `test -f 'coders/gray.c' || echo '$(srcdir)/'`coders/gray.c
+
+coders/magick_libGraphicsMagick_la-histogram.lo: coders/histogram.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-histogram.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-histogram.Tpo -c -o coders/magick_libGraphicsMagick_la-histogram.lo `test -f 'coders/histogram.c' || echo '$(srcdir)/'`coders/histogram.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-histogram.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-histogram.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/histogram.c' object='coders/magick_libGraphicsMagick_la-histogram.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-histogram.lo `test -f 'coders/histogram.c' || echo '$(srcdir)/'`coders/histogram.c
+
+coders/magick_libGraphicsMagick_la-hrz.lo: coders/hrz.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-hrz.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-hrz.Tpo -c -o coders/magick_libGraphicsMagick_la-hrz.lo `test -f 'coders/hrz.c' || echo '$(srcdir)/'`coders/hrz.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-hrz.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-hrz.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/hrz.c' object='coders/magick_libGraphicsMagick_la-hrz.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-hrz.lo `test -f 'coders/hrz.c' || echo '$(srcdir)/'`coders/hrz.c
+
+coders/magick_libGraphicsMagick_la-html.lo: coders/html.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-html.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-html.Tpo -c -o coders/magick_libGraphicsMagick_la-html.lo `test -f 'coders/html.c' || echo '$(srcdir)/'`coders/html.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-html.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-html.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/html.c' object='coders/magick_libGraphicsMagick_la-html.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-html.lo `test -f 'coders/html.c' || echo '$(srcdir)/'`coders/html.c
+
+coders/magick_libGraphicsMagick_la-icon.lo: coders/icon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-icon.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-icon.Tpo -c -o coders/magick_libGraphicsMagick_la-icon.lo `test -f 'coders/icon.c' || echo '$(srcdir)/'`coders/icon.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-icon.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-icon.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/icon.c' object='coders/magick_libGraphicsMagick_la-icon.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-icon.lo `test -f 'coders/icon.c' || echo '$(srcdir)/'`coders/icon.c
+
+coders/magick_libGraphicsMagick_la-identity.lo: coders/identity.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-identity.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-identity.Tpo -c -o coders/magick_libGraphicsMagick_la-identity.lo `test -f 'coders/identity.c' || echo '$(srcdir)/'`coders/identity.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-identity.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-identity.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/identity.c' object='coders/magick_libGraphicsMagick_la-identity.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-identity.lo `test -f 'coders/identity.c' || echo '$(srcdir)/'`coders/identity.c
+
+coders/magick_libGraphicsMagick_la-info.lo: coders/info.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-info.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-info.Tpo -c -o coders/magick_libGraphicsMagick_la-info.lo `test -f 'coders/info.c' || echo '$(srcdir)/'`coders/info.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-info.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-info.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/info.c' object='coders/magick_libGraphicsMagick_la-info.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-info.lo `test -f 'coders/info.c' || echo '$(srcdir)/'`coders/info.c
+
+coders/magick_libGraphicsMagick_la-label.lo: coders/label.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-label.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-label.Tpo -c -o coders/magick_libGraphicsMagick_la-label.lo `test -f 'coders/label.c' || echo '$(srcdir)/'`coders/label.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-label.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-label.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/label.c' object='coders/magick_libGraphicsMagick_la-label.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-label.lo `test -f 'coders/label.c' || echo '$(srcdir)/'`coders/label.c
+
+coders/magick_libGraphicsMagick_la-locale.lo: coders/locale.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-locale.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-locale.Tpo -c -o coders/magick_libGraphicsMagick_la-locale.lo `test -f 'coders/locale.c' || echo '$(srcdir)/'`coders/locale.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-locale.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-locale.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/locale.c' object='coders/magick_libGraphicsMagick_la-locale.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-locale.lo `test -f 'coders/locale.c' || echo '$(srcdir)/'`coders/locale.c
+
+coders/magick_libGraphicsMagick_la-logo.lo: coders/logo.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-logo.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-logo.Tpo -c -o coders/magick_libGraphicsMagick_la-logo.lo `test -f 'coders/logo.c' || echo '$(srcdir)/'`coders/logo.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-logo.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-logo.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/logo.c' object='coders/magick_libGraphicsMagick_la-logo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-logo.lo `test -f 'coders/logo.c' || echo '$(srcdir)/'`coders/logo.c
+
+coders/magick_libGraphicsMagick_la-mac.lo: coders/mac.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-mac.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-mac.Tpo -c -o coders/magick_libGraphicsMagick_la-mac.lo `test -f 'coders/mac.c' || echo '$(srcdir)/'`coders/mac.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-mac.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-mac.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mac.c' object='coders/magick_libGraphicsMagick_la-mac.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-mac.lo `test -f 'coders/mac.c' || echo '$(srcdir)/'`coders/mac.c
+
+coders/magick_libGraphicsMagick_la-map.lo: coders/map.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-map.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-map.Tpo -c -o coders/magick_libGraphicsMagick_la-map.lo `test -f 'coders/map.c' || echo '$(srcdir)/'`coders/map.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-map.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-map.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/map.c' object='coders/magick_libGraphicsMagick_la-map.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-map.lo `test -f 'coders/map.c' || echo '$(srcdir)/'`coders/map.c
+
+coders/magick_libGraphicsMagick_la-mat.lo: coders/mat.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-mat.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-mat.Tpo -c -o coders/magick_libGraphicsMagick_la-mat.lo `test -f 'coders/mat.c' || echo '$(srcdir)/'`coders/mat.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-mat.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-mat.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mat.c' object='coders/magick_libGraphicsMagick_la-mat.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-mat.lo `test -f 'coders/mat.c' || echo '$(srcdir)/'`coders/mat.c
+
+coders/magick_libGraphicsMagick_la-matte.lo: coders/matte.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-matte.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-matte.Tpo -c -o coders/magick_libGraphicsMagick_la-matte.lo `test -f 'coders/matte.c' || echo '$(srcdir)/'`coders/matte.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-matte.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-matte.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/matte.c' object='coders/magick_libGraphicsMagick_la-matte.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-matte.lo `test -f 'coders/matte.c' || echo '$(srcdir)/'`coders/matte.c
+
+coders/magick_libGraphicsMagick_la-meta.lo: coders/meta.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-meta.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-meta.Tpo -c -o coders/magick_libGraphicsMagick_la-meta.lo `test -f 'coders/meta.c' || echo '$(srcdir)/'`coders/meta.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-meta.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-meta.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/meta.c' object='coders/magick_libGraphicsMagick_la-meta.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-meta.lo `test -f 'coders/meta.c' || echo '$(srcdir)/'`coders/meta.c
+
+coders/magick_libGraphicsMagick_la-miff.lo: coders/miff.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-miff.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-miff.Tpo -c -o coders/magick_libGraphicsMagick_la-miff.lo `test -f 'coders/miff.c' || echo '$(srcdir)/'`coders/miff.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-miff.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-miff.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/miff.c' object='coders/magick_libGraphicsMagick_la-miff.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-miff.lo `test -f 'coders/miff.c' || echo '$(srcdir)/'`coders/miff.c
+
+coders/magick_libGraphicsMagick_la-mono.lo: coders/mono.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-mono.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-mono.Tpo -c -o coders/magick_libGraphicsMagick_la-mono.lo `test -f 'coders/mono.c' || echo '$(srcdir)/'`coders/mono.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-mono.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-mono.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mono.c' object='coders/magick_libGraphicsMagick_la-mono.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-mono.lo `test -f 'coders/mono.c' || echo '$(srcdir)/'`coders/mono.c
+
+coders/magick_libGraphicsMagick_la-mpc.lo: coders/mpc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-mpc.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpc.Tpo -c -o coders/magick_libGraphicsMagick_la-mpc.lo `test -f 'coders/mpc.c' || echo '$(srcdir)/'`coders/mpc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpc.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mpc.c' object='coders/magick_libGraphicsMagick_la-mpc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-mpc.lo `test -f 'coders/mpc.c' || echo '$(srcdir)/'`coders/mpc.c
+
+coders/magick_libGraphicsMagick_la-mpeg.lo: coders/mpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-mpeg.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpeg.Tpo -c -o coders/magick_libGraphicsMagick_la-mpeg.lo `test -f 'coders/mpeg.c' || echo '$(srcdir)/'`coders/mpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpeg.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpeg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mpeg.c' object='coders/magick_libGraphicsMagick_la-mpeg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-mpeg.lo `test -f 'coders/mpeg.c' || echo '$(srcdir)/'`coders/mpeg.c
+
+coders/magick_libGraphicsMagick_la-mpr.lo: coders/mpr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-mpr.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpr.Tpo -c -o coders/magick_libGraphicsMagick_la-mpr.lo `test -f 'coders/mpr.c' || echo '$(srcdir)/'`coders/mpr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpr.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-mpr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mpr.c' object='coders/magick_libGraphicsMagick_la-mpr.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-mpr.lo `test -f 'coders/mpr.c' || echo '$(srcdir)/'`coders/mpr.c
+
+coders/magick_libGraphicsMagick_la-msl.lo: coders/msl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-msl.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-msl.Tpo -c -o coders/magick_libGraphicsMagick_la-msl.lo `test -f 'coders/msl.c' || echo '$(srcdir)/'`coders/msl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-msl.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-msl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/msl.c' object='coders/magick_libGraphicsMagick_la-msl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-msl.lo `test -f 'coders/msl.c' || echo '$(srcdir)/'`coders/msl.c
+
+coders/magick_libGraphicsMagick_la-mtv.lo: coders/mtv.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-mtv.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-mtv.Tpo -c -o coders/magick_libGraphicsMagick_la-mtv.lo `test -f 'coders/mtv.c' || echo '$(srcdir)/'`coders/mtv.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-mtv.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-mtv.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mtv.c' object='coders/magick_libGraphicsMagick_la-mtv.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-mtv.lo `test -f 'coders/mtv.c' || echo '$(srcdir)/'`coders/mtv.c
+
+coders/magick_libGraphicsMagick_la-mvg.lo: coders/mvg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-mvg.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-mvg.Tpo -c -o coders/magick_libGraphicsMagick_la-mvg.lo `test -f 'coders/mvg.c' || echo '$(srcdir)/'`coders/mvg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-mvg.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-mvg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/mvg.c' object='coders/magick_libGraphicsMagick_la-mvg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-mvg.lo `test -f 'coders/mvg.c' || echo '$(srcdir)/'`coders/mvg.c
+
+coders/magick_libGraphicsMagick_la-null.lo: coders/null.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-null.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-null.Tpo -c -o coders/magick_libGraphicsMagick_la-null.lo `test -f 'coders/null.c' || echo '$(srcdir)/'`coders/null.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-null.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-null.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/null.c' object='coders/magick_libGraphicsMagick_la-null.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-null.lo `test -f 'coders/null.c' || echo '$(srcdir)/'`coders/null.c
+
+coders/magick_libGraphicsMagick_la-otb.lo: coders/otb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-otb.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-otb.Tpo -c -o coders/magick_libGraphicsMagick_la-otb.lo `test -f 'coders/otb.c' || echo '$(srcdir)/'`coders/otb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-otb.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-otb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/otb.c' object='coders/magick_libGraphicsMagick_la-otb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-otb.lo `test -f 'coders/otb.c' || echo '$(srcdir)/'`coders/otb.c
+
+coders/magick_libGraphicsMagick_la-palm.lo: coders/palm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-palm.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-palm.Tpo -c -o coders/magick_libGraphicsMagick_la-palm.lo `test -f 'coders/palm.c' || echo '$(srcdir)/'`coders/palm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-palm.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-palm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/palm.c' object='coders/magick_libGraphicsMagick_la-palm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-palm.lo `test -f 'coders/palm.c' || echo '$(srcdir)/'`coders/palm.c
+
+coders/magick_libGraphicsMagick_la-pcd.lo: coders/pcd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pcd.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcd.Tpo -c -o coders/magick_libGraphicsMagick_la-pcd.lo `test -f 'coders/pcd.c' || echo '$(srcdir)/'`coders/pcd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcd.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pcd.c' object='coders/magick_libGraphicsMagick_la-pcd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pcd.lo `test -f 'coders/pcd.c' || echo '$(srcdir)/'`coders/pcd.c
+
+coders/magick_libGraphicsMagick_la-pcl.lo: coders/pcl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pcl.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcl.Tpo -c -o coders/magick_libGraphicsMagick_la-pcl.lo `test -f 'coders/pcl.c' || echo '$(srcdir)/'`coders/pcl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcl.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pcl.c' object='coders/magick_libGraphicsMagick_la-pcl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pcl.lo `test -f 'coders/pcl.c' || echo '$(srcdir)/'`coders/pcl.c
+
+coders/magick_libGraphicsMagick_la-pcx.lo: coders/pcx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pcx.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcx.Tpo -c -o coders/magick_libGraphicsMagick_la-pcx.lo `test -f 'coders/pcx.c' || echo '$(srcdir)/'`coders/pcx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcx.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pcx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pcx.c' object='coders/magick_libGraphicsMagick_la-pcx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pcx.lo `test -f 'coders/pcx.c' || echo '$(srcdir)/'`coders/pcx.c
+
+coders/magick_libGraphicsMagick_la-pdb.lo: coders/pdb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pdb.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pdb.Tpo -c -o coders/magick_libGraphicsMagick_la-pdb.lo `test -f 'coders/pdb.c' || echo '$(srcdir)/'`coders/pdb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pdb.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pdb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pdb.c' object='coders/magick_libGraphicsMagick_la-pdb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pdb.lo `test -f 'coders/pdb.c' || echo '$(srcdir)/'`coders/pdb.c
+
+coders/magick_libGraphicsMagick_la-pdf.lo: coders/pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pdf.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pdf.Tpo -c -o coders/magick_libGraphicsMagick_la-pdf.lo `test -f 'coders/pdf.c' || echo '$(srcdir)/'`coders/pdf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pdf.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pdf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pdf.c' object='coders/magick_libGraphicsMagick_la-pdf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pdf.lo `test -f 'coders/pdf.c' || echo '$(srcdir)/'`coders/pdf.c
+
+coders/magick_libGraphicsMagick_la-pict.lo: coders/pict.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pict.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pict.Tpo -c -o coders/magick_libGraphicsMagick_la-pict.lo `test -f 'coders/pict.c' || echo '$(srcdir)/'`coders/pict.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pict.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pict.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pict.c' object='coders/magick_libGraphicsMagick_la-pict.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pict.lo `test -f 'coders/pict.c' || echo '$(srcdir)/'`coders/pict.c
+
+coders/magick_libGraphicsMagick_la-pix.lo: coders/pix.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pix.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pix.Tpo -c -o coders/magick_libGraphicsMagick_la-pix.lo `test -f 'coders/pix.c' || echo '$(srcdir)/'`coders/pix.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pix.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pix.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pix.c' object='coders/magick_libGraphicsMagick_la-pix.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pix.lo `test -f 'coders/pix.c' || echo '$(srcdir)/'`coders/pix.c
+
+coders/magick_libGraphicsMagick_la-plasma.lo: coders/plasma.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-plasma.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-plasma.Tpo -c -o coders/magick_libGraphicsMagick_la-plasma.lo `test -f 'coders/plasma.c' || echo '$(srcdir)/'`coders/plasma.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-plasma.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-plasma.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/plasma.c' object='coders/magick_libGraphicsMagick_la-plasma.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-plasma.lo `test -f 'coders/plasma.c' || echo '$(srcdir)/'`coders/plasma.c
+
+coders/magick_libGraphicsMagick_la-pnm.lo: coders/pnm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pnm.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pnm.Tpo -c -o coders/magick_libGraphicsMagick_la-pnm.lo `test -f 'coders/pnm.c' || echo '$(srcdir)/'`coders/pnm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pnm.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pnm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pnm.c' object='coders/magick_libGraphicsMagick_la-pnm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pnm.lo `test -f 'coders/pnm.c' || echo '$(srcdir)/'`coders/pnm.c
+
+coders/magick_libGraphicsMagick_la-preview.lo: coders/preview.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-preview.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-preview.Tpo -c -o coders/magick_libGraphicsMagick_la-preview.lo `test -f 'coders/preview.c' || echo '$(srcdir)/'`coders/preview.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-preview.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-preview.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/preview.c' object='coders/magick_libGraphicsMagick_la-preview.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-preview.lo `test -f 'coders/preview.c' || echo '$(srcdir)/'`coders/preview.c
+
+coders/magick_libGraphicsMagick_la-ps.lo: coders/ps.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-ps.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps.Tpo -c -o coders/magick_libGraphicsMagick_la-ps.lo `test -f 'coders/ps.c' || echo '$(srcdir)/'`coders/ps.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ps.c' object='coders/magick_libGraphicsMagick_la-ps.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-ps.lo `test -f 'coders/ps.c' || echo '$(srcdir)/'`coders/ps.c
+
+coders/magick_libGraphicsMagick_la-ps2.lo: coders/ps2.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-ps2.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps2.Tpo -c -o coders/magick_libGraphicsMagick_la-ps2.lo `test -f 'coders/ps2.c' || echo '$(srcdir)/'`coders/ps2.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps2.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ps2.c' object='coders/magick_libGraphicsMagick_la-ps2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-ps2.lo `test -f 'coders/ps2.c' || echo '$(srcdir)/'`coders/ps2.c
+
+coders/magick_libGraphicsMagick_la-ps3.lo: coders/ps3.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-ps3.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps3.Tpo -c -o coders/magick_libGraphicsMagick_la-ps3.lo `test -f 'coders/ps3.c' || echo '$(srcdir)/'`coders/ps3.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps3.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-ps3.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ps3.c' object='coders/magick_libGraphicsMagick_la-ps3.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-ps3.lo `test -f 'coders/ps3.c' || echo '$(srcdir)/'`coders/ps3.c
+
+coders/magick_libGraphicsMagick_la-pwp.lo: coders/pwp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-pwp.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-pwp.Tpo -c -o coders/magick_libGraphicsMagick_la-pwp.lo `test -f 'coders/pwp.c' || echo '$(srcdir)/'`coders/pwp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-pwp.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-pwp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/pwp.c' object='coders/magick_libGraphicsMagick_la-pwp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-pwp.lo `test -f 'coders/pwp.c' || echo '$(srcdir)/'`coders/pwp.c
+
+coders/magick_libGraphicsMagick_la-rgb.lo: coders/rgb.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-rgb.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-rgb.Tpo -c -o coders/magick_libGraphicsMagick_la-rgb.lo `test -f 'coders/rgb.c' || echo '$(srcdir)/'`coders/rgb.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-rgb.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-rgb.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/rgb.c' object='coders/magick_libGraphicsMagick_la-rgb.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-rgb.lo `test -f 'coders/rgb.c' || echo '$(srcdir)/'`coders/rgb.c
+
+coders/magick_libGraphicsMagick_la-rla.lo: coders/rla.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-rla.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-rla.Tpo -c -o coders/magick_libGraphicsMagick_la-rla.lo `test -f 'coders/rla.c' || echo '$(srcdir)/'`coders/rla.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-rla.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-rla.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/rla.c' object='coders/magick_libGraphicsMagick_la-rla.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-rla.lo `test -f 'coders/rla.c' || echo '$(srcdir)/'`coders/rla.c
+
+coders/magick_libGraphicsMagick_la-rle.lo: coders/rle.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-rle.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-rle.Tpo -c -o coders/magick_libGraphicsMagick_la-rle.lo `test -f 'coders/rle.c' || echo '$(srcdir)/'`coders/rle.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-rle.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-rle.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/rle.c' object='coders/magick_libGraphicsMagick_la-rle.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-rle.lo `test -f 'coders/rle.c' || echo '$(srcdir)/'`coders/rle.c
+
+coders/magick_libGraphicsMagick_la-sct.lo: coders/sct.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-sct.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-sct.Tpo -c -o coders/magick_libGraphicsMagick_la-sct.lo `test -f 'coders/sct.c' || echo '$(srcdir)/'`coders/sct.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-sct.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-sct.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/sct.c' object='coders/magick_libGraphicsMagick_la-sct.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-sct.lo `test -f 'coders/sct.c' || echo '$(srcdir)/'`coders/sct.c
+
+coders/magick_libGraphicsMagick_la-sfw.lo: coders/sfw.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-sfw.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-sfw.Tpo -c -o coders/magick_libGraphicsMagick_la-sfw.lo `test -f 'coders/sfw.c' || echo '$(srcdir)/'`coders/sfw.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-sfw.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-sfw.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/sfw.c' object='coders/magick_libGraphicsMagick_la-sfw.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-sfw.lo `test -f 'coders/sfw.c' || echo '$(srcdir)/'`coders/sfw.c
+
+coders/magick_libGraphicsMagick_la-sgi.lo: coders/sgi.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-sgi.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-sgi.Tpo -c -o coders/magick_libGraphicsMagick_la-sgi.lo `test -f 'coders/sgi.c' || echo '$(srcdir)/'`coders/sgi.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-sgi.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-sgi.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/sgi.c' object='coders/magick_libGraphicsMagick_la-sgi.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-sgi.lo `test -f 'coders/sgi.c' || echo '$(srcdir)/'`coders/sgi.c
+
+coders/magick_libGraphicsMagick_la-stegano.lo: coders/stegano.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-stegano.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-stegano.Tpo -c -o coders/magick_libGraphicsMagick_la-stegano.lo `test -f 'coders/stegano.c' || echo '$(srcdir)/'`coders/stegano.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-stegano.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-stegano.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/stegano.c' object='coders/magick_libGraphicsMagick_la-stegano.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-stegano.lo `test -f 'coders/stegano.c' || echo '$(srcdir)/'`coders/stegano.c
+
+coders/magick_libGraphicsMagick_la-sun.lo: coders/sun.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-sun.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-sun.Tpo -c -o coders/magick_libGraphicsMagick_la-sun.lo `test -f 'coders/sun.c' || echo '$(srcdir)/'`coders/sun.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-sun.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-sun.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/sun.c' object='coders/magick_libGraphicsMagick_la-sun.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-sun.lo `test -f 'coders/sun.c' || echo '$(srcdir)/'`coders/sun.c
+
+coders/magick_libGraphicsMagick_la-svg.lo: coders/svg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-svg.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-svg.Tpo -c -o coders/magick_libGraphicsMagick_la-svg.lo `test -f 'coders/svg.c' || echo '$(srcdir)/'`coders/svg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-svg.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-svg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/svg.c' object='coders/magick_libGraphicsMagick_la-svg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-svg.lo `test -f 'coders/svg.c' || echo '$(srcdir)/'`coders/svg.c
+
+coders/magick_libGraphicsMagick_la-tga.lo: coders/tga.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-tga.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-tga.Tpo -c -o coders/magick_libGraphicsMagick_la-tga.lo `test -f 'coders/tga.c' || echo '$(srcdir)/'`coders/tga.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-tga.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-tga.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/tga.c' object='coders/magick_libGraphicsMagick_la-tga.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-tga.lo `test -f 'coders/tga.c' || echo '$(srcdir)/'`coders/tga.c
+
+coders/magick_libGraphicsMagick_la-tile.lo: coders/tile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-tile.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-tile.Tpo -c -o coders/magick_libGraphicsMagick_la-tile.lo `test -f 'coders/tile.c' || echo '$(srcdir)/'`coders/tile.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-tile.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-tile.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/tile.c' object='coders/magick_libGraphicsMagick_la-tile.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-tile.lo `test -f 'coders/tile.c' || echo '$(srcdir)/'`coders/tile.c
+
+coders/magick_libGraphicsMagick_la-tim.lo: coders/tim.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-tim.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-tim.Tpo -c -o coders/magick_libGraphicsMagick_la-tim.lo `test -f 'coders/tim.c' || echo '$(srcdir)/'`coders/tim.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-tim.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-tim.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/tim.c' object='coders/magick_libGraphicsMagick_la-tim.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-tim.lo `test -f 'coders/tim.c' || echo '$(srcdir)/'`coders/tim.c
+
+coders/magick_libGraphicsMagick_la-topol.lo: coders/topol.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-topol.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-topol.Tpo -c -o coders/magick_libGraphicsMagick_la-topol.lo `test -f 'coders/topol.c' || echo '$(srcdir)/'`coders/topol.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-topol.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-topol.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/topol.c' object='coders/magick_libGraphicsMagick_la-topol.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-topol.lo `test -f 'coders/topol.c' || echo '$(srcdir)/'`coders/topol.c
+
+coders/magick_libGraphicsMagick_la-ttf.lo: coders/ttf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-ttf.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-ttf.Tpo -c -o coders/magick_libGraphicsMagick_la-ttf.lo `test -f 'coders/ttf.c' || echo '$(srcdir)/'`coders/ttf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-ttf.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-ttf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ttf.c' object='coders/magick_libGraphicsMagick_la-ttf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-ttf.lo `test -f 'coders/ttf.c' || echo '$(srcdir)/'`coders/ttf.c
+
+coders/magick_libGraphicsMagick_la-txt.lo: coders/txt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-txt.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-txt.Tpo -c -o coders/magick_libGraphicsMagick_la-txt.lo `test -f 'coders/txt.c' || echo '$(srcdir)/'`coders/txt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-txt.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-txt.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/txt.c' object='coders/magick_libGraphicsMagick_la-txt.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-txt.lo `test -f 'coders/txt.c' || echo '$(srcdir)/'`coders/txt.c
+
+coders/magick_libGraphicsMagick_la-uil.lo: coders/uil.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-uil.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-uil.Tpo -c -o coders/magick_libGraphicsMagick_la-uil.lo `test -f 'coders/uil.c' || echo '$(srcdir)/'`coders/uil.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-uil.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-uil.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/uil.c' object='coders/magick_libGraphicsMagick_la-uil.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-uil.lo `test -f 'coders/uil.c' || echo '$(srcdir)/'`coders/uil.c
+
+coders/magick_libGraphicsMagick_la-url.lo: coders/url.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-url.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-url.Tpo -c -o coders/magick_libGraphicsMagick_la-url.lo `test -f 'coders/url.c' || echo '$(srcdir)/'`coders/url.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-url.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-url.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/url.c' object='coders/magick_libGraphicsMagick_la-url.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-url.lo `test -f 'coders/url.c' || echo '$(srcdir)/'`coders/url.c
+
+coders/magick_libGraphicsMagick_la-uyvy.lo: coders/uyvy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-uyvy.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-uyvy.Tpo -c -o coders/magick_libGraphicsMagick_la-uyvy.lo `test -f 'coders/uyvy.c' || echo '$(srcdir)/'`coders/uyvy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-uyvy.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-uyvy.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/uyvy.c' object='coders/magick_libGraphicsMagick_la-uyvy.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-uyvy.lo `test -f 'coders/uyvy.c' || echo '$(srcdir)/'`coders/uyvy.c
+
+coders/magick_libGraphicsMagick_la-vicar.lo: coders/vicar.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-vicar.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-vicar.Tpo -c -o coders/magick_libGraphicsMagick_la-vicar.lo `test -f 'coders/vicar.c' || echo '$(srcdir)/'`coders/vicar.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-vicar.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-vicar.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/vicar.c' object='coders/magick_libGraphicsMagick_la-vicar.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-vicar.lo `test -f 'coders/vicar.c' || echo '$(srcdir)/'`coders/vicar.c
+
+coders/magick_libGraphicsMagick_la-vid.lo: coders/vid.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-vid.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-vid.Tpo -c -o coders/magick_libGraphicsMagick_la-vid.lo `test -f 'coders/vid.c' || echo '$(srcdir)/'`coders/vid.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-vid.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-vid.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/vid.c' object='coders/magick_libGraphicsMagick_la-vid.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-vid.lo `test -f 'coders/vid.c' || echo '$(srcdir)/'`coders/vid.c
+
+coders/magick_libGraphicsMagick_la-viff.lo: coders/viff.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-viff.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-viff.Tpo -c -o coders/magick_libGraphicsMagick_la-viff.lo `test -f 'coders/viff.c' || echo '$(srcdir)/'`coders/viff.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-viff.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-viff.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/viff.c' object='coders/magick_libGraphicsMagick_la-viff.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-viff.lo `test -f 'coders/viff.c' || echo '$(srcdir)/'`coders/viff.c
+
+coders/magick_libGraphicsMagick_la-wbmp.lo: coders/wbmp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-wbmp.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-wbmp.Tpo -c -o coders/magick_libGraphicsMagick_la-wbmp.lo `test -f 'coders/wbmp.c' || echo '$(srcdir)/'`coders/wbmp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-wbmp.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-wbmp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/wbmp.c' object='coders/magick_libGraphicsMagick_la-wbmp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-wbmp.lo `test -f 'coders/wbmp.c' || echo '$(srcdir)/'`coders/wbmp.c
+
+coders/magick_libGraphicsMagick_la-wmf.lo: coders/wmf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-wmf.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-wmf.Tpo -c -o coders/magick_libGraphicsMagick_la-wmf.lo `test -f 'coders/wmf.c' || echo '$(srcdir)/'`coders/wmf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-wmf.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-wmf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/wmf.c' object='coders/magick_libGraphicsMagick_la-wmf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-wmf.lo `test -f 'coders/wmf.c' || echo '$(srcdir)/'`coders/wmf.c
+
+coders/magick_libGraphicsMagick_la-wpg.lo: coders/wpg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-wpg.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-wpg.Tpo -c -o coders/magick_libGraphicsMagick_la-wpg.lo `test -f 'coders/wpg.c' || echo '$(srcdir)/'`coders/wpg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-wpg.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-wpg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/wpg.c' object='coders/magick_libGraphicsMagick_la-wpg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-wpg.lo `test -f 'coders/wpg.c' || echo '$(srcdir)/'`coders/wpg.c
+
+coders/magick_libGraphicsMagick_la-xbm.lo: coders/xbm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-xbm.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-xbm.Tpo -c -o coders/magick_libGraphicsMagick_la-xbm.lo `test -f 'coders/xbm.c' || echo '$(srcdir)/'`coders/xbm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-xbm.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-xbm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xbm.c' object='coders/magick_libGraphicsMagick_la-xbm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-xbm.lo `test -f 'coders/xbm.c' || echo '$(srcdir)/'`coders/xbm.c
+
+coders/magick_libGraphicsMagick_la-xc.lo: coders/xc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-xc.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-xc.Tpo -c -o coders/magick_libGraphicsMagick_la-xc.lo `test -f 'coders/xc.c' || echo '$(srcdir)/'`coders/xc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-xc.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-xc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xc.c' object='coders/magick_libGraphicsMagick_la-xc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-xc.lo `test -f 'coders/xc.c' || echo '$(srcdir)/'`coders/xc.c
+
+coders/magick_libGraphicsMagick_la-xcf.lo: coders/xcf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-xcf.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-xcf.Tpo -c -o coders/magick_libGraphicsMagick_la-xcf.lo `test -f 'coders/xcf.c' || echo '$(srcdir)/'`coders/xcf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-xcf.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-xcf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xcf.c' object='coders/magick_libGraphicsMagick_la-xcf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-xcf.lo `test -f 'coders/xcf.c' || echo '$(srcdir)/'`coders/xcf.c
+
+coders/magick_libGraphicsMagick_la-xpm.lo: coders/xpm.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-xpm.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-xpm.Tpo -c -o coders/magick_libGraphicsMagick_la-xpm.lo `test -f 'coders/xpm.c' || echo '$(srcdir)/'`coders/xpm.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-xpm.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-xpm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xpm.c' object='coders/magick_libGraphicsMagick_la-xpm.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-xpm.lo `test -f 'coders/xpm.c' || echo '$(srcdir)/'`coders/xpm.c
+
+coders/magick_libGraphicsMagick_la-yuv.lo: coders/yuv.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-yuv.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-yuv.Tpo -c -o coders/magick_libGraphicsMagick_la-yuv.lo `test -f 'coders/yuv.c' || echo '$(srcdir)/'`coders/yuv.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-yuv.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-yuv.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/yuv.c' object='coders/magick_libGraphicsMagick_la-yuv.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-yuv.lo `test -f 'coders/yuv.c' || echo '$(srcdir)/'`coders/yuv.c
+
+coders/magick_libGraphicsMagick_la-psd.lo: coders/psd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-psd.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-psd.Tpo -c -o coders/magick_libGraphicsMagick_la-psd.lo `test -f 'coders/psd.c' || echo '$(srcdir)/'`coders/psd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-psd.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-psd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/psd.c' object='coders/magick_libGraphicsMagick_la-psd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-psd.lo `test -f 'coders/psd.c' || echo '$(srcdir)/'`coders/psd.c
+
+coders/magick_libGraphicsMagick_la-dps.lo: coders/dps.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-dps.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-dps.Tpo -c -o coders/magick_libGraphicsMagick_la-dps.lo `test -f 'coders/dps.c' || echo '$(srcdir)/'`coders/dps.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-dps.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-dps.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/dps.c' object='coders/magick_libGraphicsMagick_la-dps.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-dps.lo `test -f 'coders/dps.c' || echo '$(srcdir)/'`coders/dps.c
+
+coders/magick_libGraphicsMagick_la-clipboard.lo: coders/clipboard.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-clipboard.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-clipboard.Tpo -c -o coders/magick_libGraphicsMagick_la-clipboard.lo `test -f 'coders/clipboard.c' || echo '$(srcdir)/'`coders/clipboard.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-clipboard.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-clipboard.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/clipboard.c' object='coders/magick_libGraphicsMagick_la-clipboard.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-clipboard.lo `test -f 'coders/clipboard.c' || echo '$(srcdir)/'`coders/clipboard.c
+
+coders/magick_libGraphicsMagick_la-emf.lo: coders/emf.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-emf.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-emf.Tpo -c -o coders/magick_libGraphicsMagick_la-emf.lo `test -f 'coders/emf.c' || echo '$(srcdir)/'`coders/emf.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-emf.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-emf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/emf.c' object='coders/magick_libGraphicsMagick_la-emf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-emf.lo `test -f 'coders/emf.c' || echo '$(srcdir)/'`coders/emf.c
+
+coders/magick_libGraphicsMagick_la-fpx.lo: coders/fpx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-fpx.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-fpx.Tpo -c -o coders/magick_libGraphicsMagick_la-fpx.lo `test -f 'coders/fpx.c' || echo '$(srcdir)/'`coders/fpx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-fpx.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-fpx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/fpx.c' object='coders/magick_libGraphicsMagick_la-fpx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-fpx.lo `test -f 'coders/fpx.c' || echo '$(srcdir)/'`coders/fpx.c
+
+coders/magick_libGraphicsMagick_la-jbig.lo: coders/jbig.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-jbig.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-jbig.Tpo -c -o coders/magick_libGraphicsMagick_la-jbig.lo `test -f 'coders/jbig.c' || echo '$(srcdir)/'`coders/jbig.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-jbig.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-jbig.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/jbig.c' object='coders/magick_libGraphicsMagick_la-jbig.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-jbig.lo `test -f 'coders/jbig.c' || echo '$(srcdir)/'`coders/jbig.c
+
+coders/magick_libGraphicsMagick_la-jnx.lo: coders/jnx.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-jnx.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-jnx.Tpo -c -o coders/magick_libGraphicsMagick_la-jnx.lo `test -f 'coders/jnx.c' || echo '$(srcdir)/'`coders/jnx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-jnx.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-jnx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/jnx.c' object='coders/magick_libGraphicsMagick_la-jnx.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-jnx.lo `test -f 'coders/jnx.c' || echo '$(srcdir)/'`coders/jnx.c
+
+coders/magick_libGraphicsMagick_la-jpeg.lo: coders/jpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-jpeg.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-jpeg.Tpo -c -o coders/magick_libGraphicsMagick_la-jpeg.lo `test -f 'coders/jpeg.c' || echo '$(srcdir)/'`coders/jpeg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-jpeg.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-jpeg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/jpeg.c' object='coders/magick_libGraphicsMagick_la-jpeg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-jpeg.lo `test -f 'coders/jpeg.c' || echo '$(srcdir)/'`coders/jpeg.c
+
+coders/magick_libGraphicsMagick_la-jp2.lo: coders/jp2.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-jp2.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-jp2.Tpo -c -o coders/magick_libGraphicsMagick_la-jp2.lo `test -f 'coders/jp2.c' || echo '$(srcdir)/'`coders/jp2.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-jp2.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-jp2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/jp2.c' object='coders/magick_libGraphicsMagick_la-jp2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-jp2.lo `test -f 'coders/jp2.c' || echo '$(srcdir)/'`coders/jp2.c
+
+coders/magick_libGraphicsMagick_la-ept.lo: coders/ept.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-ept.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-ept.Tpo -c -o coders/magick_libGraphicsMagick_la-ept.lo `test -f 'coders/ept.c' || echo '$(srcdir)/'`coders/ept.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-ept.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-ept.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/ept.c' object='coders/magick_libGraphicsMagick_la-ept.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-ept.lo `test -f 'coders/ept.c' || echo '$(srcdir)/'`coders/ept.c
+
+coders/magick_libGraphicsMagick_la-tiff.lo: coders/tiff.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-tiff.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-tiff.Tpo -c -o coders/magick_libGraphicsMagick_la-tiff.lo `test -f 'coders/tiff.c' || echo '$(srcdir)/'`coders/tiff.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-tiff.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-tiff.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/tiff.c' object='coders/magick_libGraphicsMagick_la-tiff.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-tiff.lo `test -f 'coders/tiff.c' || echo '$(srcdir)/'`coders/tiff.c
+
+coders/magick_libGraphicsMagick_la-x.lo: coders/x.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-x.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-x.Tpo -c -o coders/magick_libGraphicsMagick_la-x.lo `test -f 'coders/x.c' || echo '$(srcdir)/'`coders/x.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-x.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-x.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/x.c' object='coders/magick_libGraphicsMagick_la-x.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-x.lo `test -f 'coders/x.c' || echo '$(srcdir)/'`coders/x.c
+
+coders/magick_libGraphicsMagick_la-xwd.lo: coders/xwd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-xwd.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-xwd.Tpo -c -o coders/magick_libGraphicsMagick_la-xwd.lo `test -f 'coders/xwd.c' || echo '$(srcdir)/'`coders/xwd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-xwd.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-xwd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/xwd.c' object='coders/magick_libGraphicsMagick_la-xwd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-xwd.lo `test -f 'coders/xwd.c' || echo '$(srcdir)/'`coders/xwd.c
+
+coders/magick_libGraphicsMagick_la-webp.lo: coders/webp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT coders/magick_libGraphicsMagick_la-webp.lo -MD -MP -MF coders/$(DEPDIR)/magick_libGraphicsMagick_la-webp.Tpo -c -o coders/magick_libGraphicsMagick_la-webp.lo `test -f 'coders/webp.c' || echo '$(srcdir)/'`coders/webp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) coders/$(DEPDIR)/magick_libGraphicsMagick_la-webp.Tpo coders/$(DEPDIR)/magick_libGraphicsMagick_la-webp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='coders/webp.c' object='coders/magick_libGraphicsMagick_la-webp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o coders/magick_libGraphicsMagick_la-webp.lo `test -f 'coders/webp.c' || echo '$(srcdir)/'`coders/webp.c
+
+filters/magick_libGraphicsMagick_la-analyze.lo: filters/analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT filters/magick_libGraphicsMagick_la-analyze.lo -MD -MP -MF filters/$(DEPDIR)/magick_libGraphicsMagick_la-analyze.Tpo -c -o filters/magick_libGraphicsMagick_la-analyze.lo `test -f 'filters/analyze.c' || echo '$(srcdir)/'`filters/analyze.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) filters/$(DEPDIR)/magick_libGraphicsMagick_la-analyze.Tpo filters/$(DEPDIR)/magick_libGraphicsMagick_la-analyze.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filters/analyze.c' object='filters/magick_libGraphicsMagick_la-analyze.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(magick_libGraphicsMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o filters/magick_libGraphicsMagick_la-analyze.lo `test -f 'filters/analyze.c' || echo '$(srcdir)/'`filters/analyze.c
+
+wand/wand_libGraphicsMagickWand_la-drawing_wand.lo: wand/drawing_wand.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_libGraphicsMagickWand_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wand/wand_libGraphicsMagickWand_la-drawing_wand.lo -MD -MP -MF wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-drawing_wand.Tpo -c -o wand/wand_libGraphicsMagickWand_la-drawing_wand.lo `test -f 'wand/drawing_wand.c' || echo '$(srcdir)/'`wand/drawing_wand.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-drawing_wand.Tpo wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-drawing_wand.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wand/drawing_wand.c' object='wand/wand_libGraphicsMagickWand_la-drawing_wand.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_libGraphicsMagickWand_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wand/wand_libGraphicsMagickWand_la-drawing_wand.lo `test -f 'wand/drawing_wand.c' || echo '$(srcdir)/'`wand/drawing_wand.c
+
+wand/wand_libGraphicsMagickWand_la-magick_compat.lo: wand/magick_compat.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_libGraphicsMagickWand_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wand/wand_libGraphicsMagickWand_la-magick_compat.lo -MD -MP -MF wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-magick_compat.Tpo -c -o wand/wand_libGraphicsMagickWand_la-magick_compat.lo `test -f 'wand/magick_compat.c' || echo '$(srcdir)/'`wand/magick_compat.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-magick_compat.Tpo wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-magick_compat.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wand/magick_compat.c' object='wand/wand_libGraphicsMagickWand_la-magick_compat.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_libGraphicsMagickWand_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wand/wand_libGraphicsMagickWand_la-magick_compat.lo `test -f 'wand/magick_compat.c' || echo '$(srcdir)/'`wand/magick_compat.c
+
+wand/wand_libGraphicsMagickWand_la-magick_wand.lo: wand/magick_wand.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_libGraphicsMagickWand_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wand/wand_libGraphicsMagickWand_la-magick_wand.lo -MD -MP -MF wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-magick_wand.Tpo -c -o wand/wand_libGraphicsMagickWand_la-magick_wand.lo `test -f 'wand/magick_wand.c' || echo '$(srcdir)/'`wand/magick_wand.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-magick_wand.Tpo wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-magick_wand.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wand/magick_wand.c' object='wand/wand_libGraphicsMagickWand_la-magick_wand.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_libGraphicsMagickWand_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wand/wand_libGraphicsMagickWand_la-magick_wand.lo `test -f 'wand/magick_wand.c' || echo '$(srcdir)/'`wand/magick_wand.c
+
+wand/wand_libGraphicsMagickWand_la-pixel_wand.lo: wand/pixel_wand.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_libGraphicsMagickWand_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wand/wand_libGraphicsMagickWand_la-pixel_wand.lo -MD -MP -MF wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-pixel_wand.Tpo -c -o wand/wand_libGraphicsMagickWand_la-pixel_wand.lo `test -f 'wand/pixel_wand.c' || echo '$(srcdir)/'`wand/pixel_wand.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-pixel_wand.Tpo wand/$(DEPDIR)/wand_libGraphicsMagickWand_la-pixel_wand.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wand/pixel_wand.c' object='wand/wand_libGraphicsMagickWand_la-pixel_wand.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_libGraphicsMagickWand_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wand/wand_libGraphicsMagickWand_la-pixel_wand.lo `test -f 'wand/pixel_wand.c' || echo '$(srcdir)/'`wand/pixel_wand.c
+
+tests/tests_bitstream-bitstream.o: tests/bitstream.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_bitstream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_bitstream-bitstream.o -MD -MP -MF tests/$(DEPDIR)/tests_bitstream-bitstream.Tpo -c -o tests/tests_bitstream-bitstream.o `test -f 'tests/bitstream.c' || echo '$(srcdir)/'`tests/bitstream.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_bitstream-bitstream.Tpo tests/$(DEPDIR)/tests_bitstream-bitstream.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/bitstream.c' object='tests/tests_bitstream-bitstream.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_bitstream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_bitstream-bitstream.o `test -f 'tests/bitstream.c' || echo '$(srcdir)/'`tests/bitstream.c
+
+tests/tests_bitstream-bitstream.obj: tests/bitstream.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_bitstream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_bitstream-bitstream.obj -MD -MP -MF tests/$(DEPDIR)/tests_bitstream-bitstream.Tpo -c -o tests/tests_bitstream-bitstream.obj `if test -f 'tests/bitstream.c'; then $(CYGPATH_W) 'tests/bitstream.c'; else $(CYGPATH_W) '$(srcdir)/tests/bitstream.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_bitstream-bitstream.Tpo tests/$(DEPDIR)/tests_bitstream-bitstream.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/bitstream.c' object='tests/tests_bitstream-bitstream.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_bitstream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_bitstream-bitstream.obj `if test -f 'tests/bitstream.c'; then $(CYGPATH_W) 'tests/bitstream.c'; else $(CYGPATH_W) '$(srcdir)/tests/bitstream.c'; fi`
+
+tests/tests_constitute-constitute.o: tests/constitute.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_constitute_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_constitute-constitute.o -MD -MP -MF tests/$(DEPDIR)/tests_constitute-constitute.Tpo -c -o tests/tests_constitute-constitute.o `test -f 'tests/constitute.c' || echo '$(srcdir)/'`tests/constitute.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_constitute-constitute.Tpo tests/$(DEPDIR)/tests_constitute-constitute.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/constitute.c' object='tests/tests_constitute-constitute.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_constitute_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_constitute-constitute.o `test -f 'tests/constitute.c' || echo '$(srcdir)/'`tests/constitute.c
+
+tests/tests_constitute-constitute.obj: tests/constitute.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_constitute_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_constitute-constitute.obj -MD -MP -MF tests/$(DEPDIR)/tests_constitute-constitute.Tpo -c -o tests/tests_constitute-constitute.obj `if test -f 'tests/constitute.c'; then $(CYGPATH_W) 'tests/constitute.c'; else $(CYGPATH_W) '$(srcdir)/tests/constitute.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_constitute-constitute.Tpo tests/$(DEPDIR)/tests_constitute-constitute.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/constitute.c' object='tests/tests_constitute-constitute.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_constitute_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_constitute-constitute.obj `if test -f 'tests/constitute.c'; then $(CYGPATH_W) 'tests/constitute.c'; else $(CYGPATH_W) '$(srcdir)/tests/constitute.c'; fi`
+
+tests/tests_drawtest-drawtest.o: tests/drawtest.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_drawtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_drawtest-drawtest.o -MD -MP -MF tests/$(DEPDIR)/tests_drawtest-drawtest.Tpo -c -o tests/tests_drawtest-drawtest.o `test -f 'tests/drawtest.c' || echo '$(srcdir)/'`tests/drawtest.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_drawtest-drawtest.Tpo tests/$(DEPDIR)/tests_drawtest-drawtest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/drawtest.c' object='tests/tests_drawtest-drawtest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_drawtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_drawtest-drawtest.o `test -f 'tests/drawtest.c' || echo '$(srcdir)/'`tests/drawtest.c
+
+tests/tests_drawtest-drawtest.obj: tests/drawtest.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_drawtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_drawtest-drawtest.obj -MD -MP -MF tests/$(DEPDIR)/tests_drawtest-drawtest.Tpo -c -o tests/tests_drawtest-drawtest.obj `if test -f 'tests/drawtest.c'; then $(CYGPATH_W) 'tests/drawtest.c'; else $(CYGPATH_W) '$(srcdir)/tests/drawtest.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_drawtest-drawtest.Tpo tests/$(DEPDIR)/tests_drawtest-drawtest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/drawtest.c' object='tests/tests_drawtest-drawtest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_drawtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_drawtest-drawtest.obj `if test -f 'tests/drawtest.c'; then $(CYGPATH_W) 'tests/drawtest.c'; else $(CYGPATH_W) '$(srcdir)/tests/drawtest.c'; fi`
+
+tests/tests_maptest-maptest.o: tests/maptest.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_maptest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_maptest-maptest.o -MD -MP -MF tests/$(DEPDIR)/tests_maptest-maptest.Tpo -c -o tests/tests_maptest-maptest.o `test -f 'tests/maptest.c' || echo '$(srcdir)/'`tests/maptest.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_maptest-maptest.Tpo tests/$(DEPDIR)/tests_maptest-maptest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/maptest.c' object='tests/tests_maptest-maptest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_maptest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_maptest-maptest.o `test -f 'tests/maptest.c' || echo '$(srcdir)/'`tests/maptest.c
+
+tests/tests_maptest-maptest.obj: tests/maptest.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_maptest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_maptest-maptest.obj -MD -MP -MF tests/$(DEPDIR)/tests_maptest-maptest.Tpo -c -o tests/tests_maptest-maptest.obj `if test -f 'tests/maptest.c'; then $(CYGPATH_W) 'tests/maptest.c'; else $(CYGPATH_W) '$(srcdir)/tests/maptest.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_maptest-maptest.Tpo tests/$(DEPDIR)/tests_maptest-maptest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/maptest.c' object='tests/tests_maptest-maptest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_maptest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_maptest-maptest.obj `if test -f 'tests/maptest.c'; then $(CYGPATH_W) 'tests/maptest.c'; else $(CYGPATH_W) '$(srcdir)/tests/maptest.c'; fi`
+
+tests/tests_rwblob-rwblob.o: tests/rwblob.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_rwblob_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_rwblob-rwblob.o -MD -MP -MF tests/$(DEPDIR)/tests_rwblob-rwblob.Tpo -c -o tests/tests_rwblob-rwblob.o `test -f 'tests/rwblob.c' || echo '$(srcdir)/'`tests/rwblob.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_rwblob-rwblob.Tpo tests/$(DEPDIR)/tests_rwblob-rwblob.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/rwblob.c' object='tests/tests_rwblob-rwblob.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_rwblob_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_rwblob-rwblob.o `test -f 'tests/rwblob.c' || echo '$(srcdir)/'`tests/rwblob.c
+
+tests/tests_rwblob-rwblob.obj: tests/rwblob.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_rwblob_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_rwblob-rwblob.obj -MD -MP -MF tests/$(DEPDIR)/tests_rwblob-rwblob.Tpo -c -o tests/tests_rwblob-rwblob.obj `if test -f 'tests/rwblob.c'; then $(CYGPATH_W) 'tests/rwblob.c'; else $(CYGPATH_W) '$(srcdir)/tests/rwblob.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_rwblob-rwblob.Tpo tests/$(DEPDIR)/tests_rwblob-rwblob.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/rwblob.c' object='tests/tests_rwblob-rwblob.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_rwblob_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_rwblob-rwblob.obj `if test -f 'tests/rwblob.c'; then $(CYGPATH_W) 'tests/rwblob.c'; else $(CYGPATH_W) '$(srcdir)/tests/rwblob.c'; fi`
+
+tests/tests_rwfile-rwfile.o: tests/rwfile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_rwfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_rwfile-rwfile.o -MD -MP -MF tests/$(DEPDIR)/tests_rwfile-rwfile.Tpo -c -o tests/tests_rwfile-rwfile.o `test -f 'tests/rwfile.c' || echo '$(srcdir)/'`tests/rwfile.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_rwfile-rwfile.Tpo tests/$(DEPDIR)/tests_rwfile-rwfile.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/rwfile.c' object='tests/tests_rwfile-rwfile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_rwfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_rwfile-rwfile.o `test -f 'tests/rwfile.c' || echo '$(srcdir)/'`tests/rwfile.c
+
+tests/tests_rwfile-rwfile.obj: tests/rwfile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_rwfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_rwfile-rwfile.obj -MD -MP -MF tests/$(DEPDIR)/tests_rwfile-rwfile.Tpo -c -o tests/tests_rwfile-rwfile.obj `if test -f 'tests/rwfile.c'; then $(CYGPATH_W) 'tests/rwfile.c'; else $(CYGPATH_W) '$(srcdir)/tests/rwfile.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_rwfile-rwfile.Tpo tests/$(DEPDIR)/tests_rwfile-rwfile.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/rwfile.c' object='tests/tests_rwfile-rwfile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_rwfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_rwfile-rwfile.obj `if test -f 'tests/rwfile.c'; then $(CYGPATH_W) 'tests/rwfile.c'; else $(CYGPATH_W) '$(srcdir)/tests/rwfile.c'; fi`
+
+wand/wand_drawtest-drawtest.o: wand/drawtest.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_drawtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wand/wand_drawtest-drawtest.o -MD -MP -MF wand/$(DEPDIR)/wand_drawtest-drawtest.Tpo -c -o wand/wand_drawtest-drawtest.o `test -f 'wand/drawtest.c' || echo '$(srcdir)/'`wand/drawtest.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) wand/$(DEPDIR)/wand_drawtest-drawtest.Tpo wand/$(DEPDIR)/wand_drawtest-drawtest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wand/drawtest.c' object='wand/wand_drawtest-drawtest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_drawtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wand/wand_drawtest-drawtest.o `test -f 'wand/drawtest.c' || echo '$(srcdir)/'`wand/drawtest.c
+
+wand/wand_drawtest-drawtest.obj: wand/drawtest.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_drawtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wand/wand_drawtest-drawtest.obj -MD -MP -MF wand/$(DEPDIR)/wand_drawtest-drawtest.Tpo -c -o wand/wand_drawtest-drawtest.obj `if test -f 'wand/drawtest.c'; then $(CYGPATH_W) 'wand/drawtest.c'; else $(CYGPATH_W) '$(srcdir)/wand/drawtest.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) wand/$(DEPDIR)/wand_drawtest-drawtest.Tpo wand/$(DEPDIR)/wand_drawtest-drawtest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wand/drawtest.c' object='wand/wand_drawtest-drawtest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_drawtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wand/wand_drawtest-drawtest.obj `if test -f 'wand/drawtest.c'; then $(CYGPATH_W) 'wand/drawtest.c'; else $(CYGPATH_W) '$(srcdir)/wand/drawtest.c'; fi`
+
+wand/wand_wandtest-wandtest.o: wand/wandtest.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_wandtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wand/wand_wandtest-wandtest.o -MD -MP -MF wand/$(DEPDIR)/wand_wandtest-wandtest.Tpo -c -o wand/wand_wandtest-wandtest.o `test -f 'wand/wandtest.c' || echo '$(srcdir)/'`wand/wandtest.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) wand/$(DEPDIR)/wand_wandtest-wandtest.Tpo wand/$(DEPDIR)/wand_wandtest-wandtest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wand/wandtest.c' object='wand/wand_wandtest-wandtest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_wandtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wand/wand_wandtest-wandtest.o `test -f 'wand/wandtest.c' || echo '$(srcdir)/'`wand/wandtest.c
+
+wand/wand_wandtest-wandtest.obj: wand/wandtest.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_wandtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wand/wand_wandtest-wandtest.obj -MD -MP -MF wand/$(DEPDIR)/wand_wandtest-wandtest.Tpo -c -o wand/wand_wandtest-wandtest.obj `if test -f 'wand/wandtest.c'; then $(CYGPATH_W) 'wand/wandtest.c'; else $(CYGPATH_W) '$(srcdir)/wand/wandtest.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) wand/$(DEPDIR)/wand_wandtest-wandtest.Tpo wand/$(DEPDIR)/wand_wandtest-wandtest.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wand/wandtest.c' object='wand/wand_wandtest-wandtest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(wand_wandtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wand/wand_wandtest-wandtest.obj `if test -f 'wand/wandtest.c'; then $(CYGPATH_W) 'wand/wandtest.c'; else $(CYGPATH_W) '$(srcdir)/wand/wandtest.c'; fi`
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Blob.lo: Magick++/lib/Blob.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Blob.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Blob.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Blob.lo `test -f 'Magick++/lib/Blob.cpp' || echo '$(srcdir)/'`Magick++/lib/Blob.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Blob.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Blob.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Blob.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Blob.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Blob.lo `test -f 'Magick++/lib/Blob.cpp' || echo '$(srcdir)/'`Magick++/lib/Blob.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-BlobRef.lo: Magick++/lib/BlobRef.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-BlobRef.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-BlobRef.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-BlobRef.lo `test -f 'Magick++/lib/BlobRef.cpp' || echo '$(srcdir)/'`Magick++/lib/BlobRef.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-BlobRef.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-BlobRef.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/BlobRef.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-BlobRef.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-BlobRef.lo `test -f 'Magick++/lib/BlobRef.cpp' || echo '$(srcdir)/'`Magick++/lib/BlobRef.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-CoderInfo.lo: Magick++/lib/CoderInfo.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-CoderInfo.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-CoderInfo.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-CoderInfo.lo `test -f 'Magick++/lib/CoderInfo.cpp' || echo '$(srcdir)/'`Magick++/lib/CoderInfo.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-CoderInfo.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-CoderInfo.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/CoderInfo.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-CoderInfo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-CoderInfo.lo `test -f 'Magick++/lib/CoderInfo.cpp' || echo '$(srcdir)/'`Magick++/lib/CoderInfo.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Color.lo: Magick++/lib/Color.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Color.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Color.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Color.lo `test -f 'Magick++/lib/Color.cpp' || echo '$(srcdir)/'`Magick++/lib/Color.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Color.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Color.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Color.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Color.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Color.lo `test -f 'Magick++/lib/Color.cpp' || echo '$(srcdir)/'`Magick++/lib/Color.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Drawable.lo: Magick++/lib/Drawable.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Drawable.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Drawable.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Drawable.lo `test -f 'Magick++/lib/Drawable.cpp' || echo '$(srcdir)/'`Magick++/lib/Drawable.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Drawable.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Drawable.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Drawable.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Drawable.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Drawable.lo `test -f 'Magick++/lib/Drawable.cpp' || echo '$(srcdir)/'`Magick++/lib/Drawable.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Exception.lo: Magick++/lib/Exception.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Exception.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Exception.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Exception.lo `test -f 'Magick++/lib/Exception.cpp' || echo '$(srcdir)/'`Magick++/lib/Exception.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Exception.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Exception.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Exception.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Exception.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Exception.lo `test -f 'Magick++/lib/Exception.cpp' || echo '$(srcdir)/'`Magick++/lib/Exception.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Functions.lo: Magick++/lib/Functions.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Functions.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Functions.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Functions.lo `test -f 'Magick++/lib/Functions.cpp' || echo '$(srcdir)/'`Magick++/lib/Functions.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Functions.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Functions.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Functions.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Functions.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Functions.lo `test -f 'Magick++/lib/Functions.cpp' || echo '$(srcdir)/'`Magick++/lib/Functions.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Geometry.lo: Magick++/lib/Geometry.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Geometry.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Geometry.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Geometry.lo `test -f 'Magick++/lib/Geometry.cpp' || echo '$(srcdir)/'`Magick++/lib/Geometry.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Geometry.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Geometry.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Geometry.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Geometry.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Geometry.lo `test -f 'Magick++/lib/Geometry.cpp' || echo '$(srcdir)/'`Magick++/lib/Geometry.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Image.lo: Magick++/lib/Image.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Image.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Image.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Image.lo `test -f 'Magick++/lib/Image.cpp' || echo '$(srcdir)/'`Magick++/lib/Image.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Image.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Image.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Image.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Image.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Image.lo `test -f 'Magick++/lib/Image.cpp' || echo '$(srcdir)/'`Magick++/lib/Image.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-ImageRef.lo: Magick++/lib/ImageRef.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-ImageRef.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-ImageRef.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-ImageRef.lo `test -f 'Magick++/lib/ImageRef.cpp' || echo '$(srcdir)/'`Magick++/lib/ImageRef.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-ImageRef.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-ImageRef.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/ImageRef.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-ImageRef.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-ImageRef.lo `test -f 'Magick++/lib/ImageRef.cpp' || echo '$(srcdir)/'`Magick++/lib/ImageRef.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Montage.lo: Magick++/lib/Montage.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Montage.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Montage.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Montage.lo `test -f 'Magick++/lib/Montage.cpp' || echo '$(srcdir)/'`Magick++/lib/Montage.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Montage.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Montage.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Montage.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Montage.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Montage.lo `test -f 'Magick++/lib/Montage.cpp' || echo '$(srcdir)/'`Magick++/lib/Montage.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Options.lo: Magick++/lib/Options.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Options.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Options.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Options.lo `test -f 'Magick++/lib/Options.cpp' || echo '$(srcdir)/'`Magick++/lib/Options.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Options.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Options.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Options.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Options.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Options.lo `test -f 'Magick++/lib/Options.cpp' || echo '$(srcdir)/'`Magick++/lib/Options.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Pixels.lo: Magick++/lib/Pixels.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Pixels.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Pixels.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Pixels.lo `test -f 'Magick++/lib/Pixels.cpp' || echo '$(srcdir)/'`Magick++/lib/Pixels.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Pixels.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Pixels.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Pixels.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Pixels.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Pixels.lo `test -f 'Magick++/lib/Pixels.cpp' || echo '$(srcdir)/'`Magick++/lib/Pixels.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-STL.lo: Magick++/lib/STL.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-STL.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-STL.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-STL.lo `test -f 'Magick++/lib/STL.cpp' || echo '$(srcdir)/'`Magick++/lib/STL.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-STL.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-STL.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/STL.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-STL.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-STL.lo `test -f 'Magick++/lib/STL.cpp' || echo '$(srcdir)/'`Magick++/lib/STL.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-Thread.lo: Magick++/lib/Thread.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-Thread.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Thread.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Thread.lo `test -f 'Magick++/lib/Thread.cpp' || echo '$(srcdir)/'`Magick++/lib/Thread.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Thread.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-Thread.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/Thread.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-Thread.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-Thread.lo `test -f 'Magick++/lib/Thread.cpp' || echo '$(srcdir)/'`Magick++/lib/Thread.cpp
+
+Magick++/lib/Magick___lib_libGraphicsMagick___la-TypeMetric.lo: Magick++/lib/TypeMetric.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/lib/Magick___lib_libGraphicsMagick___la-TypeMetric.lo -MD -MP -MF Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-TypeMetric.Tpo -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-TypeMetric.lo `test -f 'Magick++/lib/TypeMetric.cpp' || echo '$(srcdir)/'`Magick++/lib/TypeMetric.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-TypeMetric.Tpo Magick++/lib/$(DEPDIR)/Magick___lib_libGraphicsMagick___la-TypeMetric.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/lib/TypeMetric.cpp' object='Magick++/lib/Magick___lib_libGraphicsMagick___la-TypeMetric.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___lib_libGraphicsMagick___la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/lib/Magick___lib_libGraphicsMagick___la-TypeMetric.lo `test -f 'Magick++/lib/TypeMetric.cpp' || echo '$(srcdir)/'`Magick++/lib/TypeMetric.cpp
+
+Magick++/demo/Magick___demo_analyze-analyze.o: Magick++/demo/analyze.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_analyze_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_analyze-analyze.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_analyze-analyze.Tpo -c -o Magick++/demo/Magick___demo_analyze-analyze.o `test -f 'Magick++/demo/analyze.cpp' || echo '$(srcdir)/'`Magick++/demo/analyze.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_analyze-analyze.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_analyze-analyze.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/analyze.cpp' object='Magick++/demo/Magick___demo_analyze-analyze.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_analyze_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_analyze-analyze.o `test -f 'Magick++/demo/analyze.cpp' || echo '$(srcdir)/'`Magick++/demo/analyze.cpp
+
+Magick++/demo/Magick___demo_analyze-analyze.obj: Magick++/demo/analyze.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_analyze_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_analyze-analyze.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_analyze-analyze.Tpo -c -o Magick++/demo/Magick___demo_analyze-analyze.obj `if test -f 'Magick++/demo/analyze.cpp'; then $(CYGPATH_W) 'Magick++/demo/analyze.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/analyze.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_analyze-analyze.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_analyze-analyze.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/analyze.cpp' object='Magick++/demo/Magick___demo_analyze-analyze.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_analyze_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_analyze-analyze.obj `if test -f 'Magick++/demo/analyze.cpp'; then $(CYGPATH_W) 'Magick++/demo/analyze.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/analyze.cpp'; fi`
+
+Magick++/demo/Magick___demo_button-button.o: Magick++/demo/button.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_button_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_button-button.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_button-button.Tpo -c -o Magick++/demo/Magick___demo_button-button.o `test -f 'Magick++/demo/button.cpp' || echo '$(srcdir)/'`Magick++/demo/button.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_button-button.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_button-button.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/button.cpp' object='Magick++/demo/Magick___demo_button-button.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_button_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_button-button.o `test -f 'Magick++/demo/button.cpp' || echo '$(srcdir)/'`Magick++/demo/button.cpp
+
+Magick++/demo/Magick___demo_button-button.obj: Magick++/demo/button.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_button_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_button-button.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_button-button.Tpo -c -o Magick++/demo/Magick___demo_button-button.obj `if test -f 'Magick++/demo/button.cpp'; then $(CYGPATH_W) 'Magick++/demo/button.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/button.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_button-button.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_button-button.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/button.cpp' object='Magick++/demo/Magick___demo_button-button.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_button_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_button-button.obj `if test -f 'Magick++/demo/button.cpp'; then $(CYGPATH_W) 'Magick++/demo/button.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/button.cpp'; fi`
+
+Magick++/demo/Magick___demo_demo-demo.o: Magick++/demo/demo.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_demo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_demo-demo.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_demo-demo.Tpo -c -o Magick++/demo/Magick___demo_demo-demo.o `test -f 'Magick++/demo/demo.cpp' || echo '$(srcdir)/'`Magick++/demo/demo.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_demo-demo.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_demo-demo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/demo.cpp' object='Magick++/demo/Magick___demo_demo-demo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_demo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_demo-demo.o `test -f 'Magick++/demo/demo.cpp' || echo '$(srcdir)/'`Magick++/demo/demo.cpp
+
+Magick++/demo/Magick___demo_demo-demo.obj: Magick++/demo/demo.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_demo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_demo-demo.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_demo-demo.Tpo -c -o Magick++/demo/Magick___demo_demo-demo.obj `if test -f 'Magick++/demo/demo.cpp'; then $(CYGPATH_W) 'Magick++/demo/demo.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/demo.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_demo-demo.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_demo-demo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/demo.cpp' object='Magick++/demo/Magick___demo_demo-demo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_demo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_demo-demo.obj `if test -f 'Magick++/demo/demo.cpp'; then $(CYGPATH_W) 'Magick++/demo/demo.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/demo.cpp'; fi`
+
+Magick++/demo/Magick___demo_detrans-detrans.o: Magick++/demo/detrans.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_detrans_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_detrans-detrans.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_detrans-detrans.Tpo -c -o Magick++/demo/Magick___demo_detrans-detrans.o `test -f 'Magick++/demo/detrans.cpp' || echo '$(srcdir)/'`Magick++/demo/detrans.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_detrans-detrans.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_detrans-detrans.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/detrans.cpp' object='Magick++/demo/Magick___demo_detrans-detrans.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_detrans_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_detrans-detrans.o `test -f 'Magick++/demo/detrans.cpp' || echo '$(srcdir)/'`Magick++/demo/detrans.cpp
+
+Magick++/demo/Magick___demo_detrans-detrans.obj: Magick++/demo/detrans.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_detrans_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_detrans-detrans.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_detrans-detrans.Tpo -c -o Magick++/demo/Magick___demo_detrans-detrans.obj `if test -f 'Magick++/demo/detrans.cpp'; then $(CYGPATH_W) 'Magick++/demo/detrans.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/detrans.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_detrans-detrans.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_detrans-detrans.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/detrans.cpp' object='Magick++/demo/Magick___demo_detrans-detrans.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_detrans_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_detrans-detrans.obj `if test -f 'Magick++/demo/detrans.cpp'; then $(CYGPATH_W) 'Magick++/demo/detrans.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/detrans.cpp'; fi`
+
+Magick++/demo/Magick___demo_flip-flip.o: Magick++/demo/flip.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_flip_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_flip-flip.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_flip-flip.Tpo -c -o Magick++/demo/Magick___demo_flip-flip.o `test -f 'Magick++/demo/flip.cpp' || echo '$(srcdir)/'`Magick++/demo/flip.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_flip-flip.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_flip-flip.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/flip.cpp' object='Magick++/demo/Magick___demo_flip-flip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_flip_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_flip-flip.o `test -f 'Magick++/demo/flip.cpp' || echo '$(srcdir)/'`Magick++/demo/flip.cpp
+
+Magick++/demo/Magick___demo_flip-flip.obj: Magick++/demo/flip.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_flip_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_flip-flip.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_flip-flip.Tpo -c -o Magick++/demo/Magick___demo_flip-flip.obj `if test -f 'Magick++/demo/flip.cpp'; then $(CYGPATH_W) 'Magick++/demo/flip.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/flip.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_flip-flip.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_flip-flip.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/flip.cpp' object='Magick++/demo/Magick___demo_flip-flip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_flip_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_flip-flip.obj `if test -f 'Magick++/demo/flip.cpp'; then $(CYGPATH_W) 'Magick++/demo/flip.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/flip.cpp'; fi`
+
+Magick++/demo/Magick___demo_gravity-gravity.o: Magick++/demo/gravity.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_gravity_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_gravity-gravity.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_gravity-gravity.Tpo -c -o Magick++/demo/Magick___demo_gravity-gravity.o `test -f 'Magick++/demo/gravity.cpp' || echo '$(srcdir)/'`Magick++/demo/gravity.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_gravity-gravity.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_gravity-gravity.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/gravity.cpp' object='Magick++/demo/Magick___demo_gravity-gravity.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_gravity_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_gravity-gravity.o `test -f 'Magick++/demo/gravity.cpp' || echo '$(srcdir)/'`Magick++/demo/gravity.cpp
+
+Magick++/demo/Magick___demo_gravity-gravity.obj: Magick++/demo/gravity.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_gravity_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_gravity-gravity.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_gravity-gravity.Tpo -c -o Magick++/demo/Magick___demo_gravity-gravity.obj `if test -f 'Magick++/demo/gravity.cpp'; then $(CYGPATH_W) 'Magick++/demo/gravity.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/gravity.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_gravity-gravity.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_gravity-gravity.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/gravity.cpp' object='Magick++/demo/Magick___demo_gravity-gravity.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_gravity_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_gravity-gravity.obj `if test -f 'Magick++/demo/gravity.cpp'; then $(CYGPATH_W) 'Magick++/demo/gravity.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/gravity.cpp'; fi`
+
+Magick++/demo/Magick___demo_piddle-piddle.o: Magick++/demo/piddle.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_piddle_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_piddle-piddle.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_piddle-piddle.Tpo -c -o Magick++/demo/Magick___demo_piddle-piddle.o `test -f 'Magick++/demo/piddle.cpp' || echo '$(srcdir)/'`Magick++/demo/piddle.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_piddle-piddle.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_piddle-piddle.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/piddle.cpp' object='Magick++/demo/Magick___demo_piddle-piddle.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_piddle_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_piddle-piddle.o `test -f 'Magick++/demo/piddle.cpp' || echo '$(srcdir)/'`Magick++/demo/piddle.cpp
+
+Magick++/demo/Magick___demo_piddle-piddle.obj: Magick++/demo/piddle.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_piddle_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_piddle-piddle.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_piddle-piddle.Tpo -c -o Magick++/demo/Magick___demo_piddle-piddle.obj `if test -f 'Magick++/demo/piddle.cpp'; then $(CYGPATH_W) 'Magick++/demo/piddle.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/piddle.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_piddle-piddle.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_piddle-piddle.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/piddle.cpp' object='Magick++/demo/Magick___demo_piddle-piddle.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_piddle_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_piddle-piddle.obj `if test -f 'Magick++/demo/piddle.cpp'; then $(CYGPATH_W) 'Magick++/demo/piddle.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/piddle.cpp'; fi`
+
+Magick++/demo/Magick___demo_shapes-shapes.o: Magick++/demo/shapes.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_shapes_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_shapes-shapes.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_shapes-shapes.Tpo -c -o Magick++/demo/Magick___demo_shapes-shapes.o `test -f 'Magick++/demo/shapes.cpp' || echo '$(srcdir)/'`Magick++/demo/shapes.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_shapes-shapes.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_shapes-shapes.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/shapes.cpp' object='Magick++/demo/Magick___demo_shapes-shapes.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_shapes_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_shapes-shapes.o `test -f 'Magick++/demo/shapes.cpp' || echo '$(srcdir)/'`Magick++/demo/shapes.cpp
+
+Magick++/demo/Magick___demo_shapes-shapes.obj: Magick++/demo/shapes.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_shapes_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_shapes-shapes.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_shapes-shapes.Tpo -c -o Magick++/demo/Magick___demo_shapes-shapes.obj `if test -f 'Magick++/demo/shapes.cpp'; then $(CYGPATH_W) 'Magick++/demo/shapes.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/shapes.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_shapes-shapes.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_shapes-shapes.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/shapes.cpp' object='Magick++/demo/Magick___demo_shapes-shapes.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_shapes_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_shapes-shapes.obj `if test -f 'Magick++/demo/shapes.cpp'; then $(CYGPATH_W) 'Magick++/demo/shapes.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/shapes.cpp'; fi`
+
+Magick++/demo/Magick___demo_zoom-zoom.o: Magick++/demo/zoom.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_zoom_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_zoom-zoom.o -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_zoom-zoom.Tpo -c -o Magick++/demo/Magick___demo_zoom-zoom.o `test -f 'Magick++/demo/zoom.cpp' || echo '$(srcdir)/'`Magick++/demo/zoom.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_zoom-zoom.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_zoom-zoom.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/zoom.cpp' object='Magick++/demo/Magick___demo_zoom-zoom.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_zoom_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_zoom-zoom.o `test -f 'Magick++/demo/zoom.cpp' || echo '$(srcdir)/'`Magick++/demo/zoom.cpp
+
+Magick++/demo/Magick___demo_zoom-zoom.obj: Magick++/demo/zoom.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_zoom_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/demo/Magick___demo_zoom-zoom.obj -MD -MP -MF Magick++/demo/$(DEPDIR)/Magick___demo_zoom-zoom.Tpo -c -o Magick++/demo/Magick___demo_zoom-zoom.obj `if test -f 'Magick++/demo/zoom.cpp'; then $(CYGPATH_W) 'Magick++/demo/zoom.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/zoom.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/demo/$(DEPDIR)/Magick___demo_zoom-zoom.Tpo Magick++/demo/$(DEPDIR)/Magick___demo_zoom-zoom.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/demo/zoom.cpp' object='Magick++/demo/Magick___demo_zoom-zoom.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___demo_zoom_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/demo/Magick___demo_zoom-zoom.obj `if test -f 'Magick++/demo/zoom.cpp'; then $(CYGPATH_W) 'Magick++/demo/zoom.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/demo/zoom.cpp'; fi`
+
+Magick++/tests/Magick___tests_appendImages-appendImages.o: Magick++/tests/appendImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_appendImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_appendImages-appendImages.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_appendImages-appendImages.Tpo -c -o Magick++/tests/Magick___tests_appendImages-appendImages.o `test -f 'Magick++/tests/appendImages.cpp' || echo '$(srcdir)/'`Magick++/tests/appendImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_appendImages-appendImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_appendImages-appendImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/appendImages.cpp' object='Magick++/tests/Magick___tests_appendImages-appendImages.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_appendImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_appendImages-appendImages.o `test -f 'Magick++/tests/appendImages.cpp' || echo '$(srcdir)/'`Magick++/tests/appendImages.cpp
+
+Magick++/tests/Magick___tests_appendImages-appendImages.obj: Magick++/tests/appendImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_appendImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_appendImages-appendImages.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_appendImages-appendImages.Tpo -c -o Magick++/tests/Magick___tests_appendImages-appendImages.obj `if test -f 'Magick++/tests/appendImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/appendImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/appendImages.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_appendImages-appendImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_appendImages-appendImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/appendImages.cpp' object='Magick++/tests/Magick___tests_appendImages-appendImages.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_appendImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_appendImages-appendImages.obj `if test -f 'Magick++/tests/appendImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/appendImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/appendImages.cpp'; fi`
+
+Magick++/tests/Magick___tests_attributes-attributes.o: Magick++/tests/attributes.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_attributes_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_attributes-attributes.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_attributes-attributes.Tpo -c -o Magick++/tests/Magick___tests_attributes-attributes.o `test -f 'Magick++/tests/attributes.cpp' || echo '$(srcdir)/'`Magick++/tests/attributes.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_attributes-attributes.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_attributes-attributes.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/attributes.cpp' object='Magick++/tests/Magick___tests_attributes-attributes.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_attributes_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_attributes-attributes.o `test -f 'Magick++/tests/attributes.cpp' || echo '$(srcdir)/'`Magick++/tests/attributes.cpp
+
+Magick++/tests/Magick___tests_attributes-attributes.obj: Magick++/tests/attributes.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_attributes_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_attributes-attributes.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_attributes-attributes.Tpo -c -o Magick++/tests/Magick___tests_attributes-attributes.obj `if test -f 'Magick++/tests/attributes.cpp'; then $(CYGPATH_W) 'Magick++/tests/attributes.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/attributes.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_attributes-attributes.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_attributes-attributes.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/attributes.cpp' object='Magick++/tests/Magick___tests_attributes-attributes.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_attributes_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_attributes-attributes.obj `if test -f 'Magick++/tests/attributes.cpp'; then $(CYGPATH_W) 'Magick++/tests/attributes.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/attributes.cpp'; fi`
+
+Magick++/tests/Magick___tests_averageImages-averageImages.o: Magick++/tests/averageImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_averageImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_averageImages-averageImages.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_averageImages-averageImages.Tpo -c -o Magick++/tests/Magick___tests_averageImages-averageImages.o `test -f 'Magick++/tests/averageImages.cpp' || echo '$(srcdir)/'`Magick++/tests/averageImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_averageImages-averageImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_averageImages-averageImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/averageImages.cpp' object='Magick++/tests/Magick___tests_averageImages-averageImages.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_averageImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_averageImages-averageImages.o `test -f 'Magick++/tests/averageImages.cpp' || echo '$(srcdir)/'`Magick++/tests/averageImages.cpp
+
+Magick++/tests/Magick___tests_averageImages-averageImages.obj: Magick++/tests/averageImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_averageImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_averageImages-averageImages.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_averageImages-averageImages.Tpo -c -o Magick++/tests/Magick___tests_averageImages-averageImages.obj `if test -f 'Magick++/tests/averageImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/averageImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/averageImages.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_averageImages-averageImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_averageImages-averageImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/averageImages.cpp' object='Magick++/tests/Magick___tests_averageImages-averageImages.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_averageImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_averageImages-averageImages.obj `if test -f 'Magick++/tests/averageImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/averageImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/averageImages.cpp'; fi`
+
+Magick++/tests/Magick___tests_coalesceImages-coalesceImages.o: Magick++/tests/coalesceImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_coalesceImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_coalesceImages-coalesceImages.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_coalesceImages-coalesceImages.Tpo -c -o Magick++/tests/Magick___tests_coalesceImages-coalesceImages.o `test -f 'Magick++/tests/coalesceImages.cpp' || echo '$(srcdir)/'`Magick++/tests/coalesceImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_coalesceImages-coalesceImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_coalesceImages-coalesceImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/coalesceImages.cpp' object='Magick++/tests/Magick___tests_coalesceImages-coalesceImages.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_coalesceImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_coalesceImages-coalesceImages.o `test -f 'Magick++/tests/coalesceImages.cpp' || echo '$(srcdir)/'`Magick++/tests/coalesceImages.cpp
+
+Magick++/tests/Magick___tests_coalesceImages-coalesceImages.obj: Magick++/tests/coalesceImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_coalesceImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_coalesceImages-coalesceImages.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_coalesceImages-coalesceImages.Tpo -c -o Magick++/tests/Magick___tests_coalesceImages-coalesceImages.obj `if test -f 'Magick++/tests/coalesceImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/coalesceImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/coalesceImages.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_coalesceImages-coalesceImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_coalesceImages-coalesceImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/coalesceImages.cpp' object='Magick++/tests/Magick___tests_coalesceImages-coalesceImages.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_coalesceImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_coalesceImages-coalesceImages.obj `if test -f 'Magick++/tests/coalesceImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/coalesceImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/coalesceImages.cpp'; fi`
+
+Magick++/tests/Magick___tests_coderInfo-coderInfo.o: Magick++/tests/coderInfo.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_coderInfo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_coderInfo-coderInfo.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_coderInfo-coderInfo.Tpo -c -o Magick++/tests/Magick___tests_coderInfo-coderInfo.o `test -f 'Magick++/tests/coderInfo.cpp' || echo '$(srcdir)/'`Magick++/tests/coderInfo.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_coderInfo-coderInfo.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_coderInfo-coderInfo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/coderInfo.cpp' object='Magick++/tests/Magick___tests_coderInfo-coderInfo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_coderInfo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_coderInfo-coderInfo.o `test -f 'Magick++/tests/coderInfo.cpp' || echo '$(srcdir)/'`Magick++/tests/coderInfo.cpp
+
+Magick++/tests/Magick___tests_coderInfo-coderInfo.obj: Magick++/tests/coderInfo.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_coderInfo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_coderInfo-coderInfo.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_coderInfo-coderInfo.Tpo -c -o Magick++/tests/Magick___tests_coderInfo-coderInfo.obj `if test -f 'Magick++/tests/coderInfo.cpp'; then $(CYGPATH_W) 'Magick++/tests/coderInfo.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/coderInfo.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_coderInfo-coderInfo.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_coderInfo-coderInfo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/coderInfo.cpp' object='Magick++/tests/Magick___tests_coderInfo-coderInfo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_coderInfo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_coderInfo-coderInfo.obj `if test -f 'Magick++/tests/coderInfo.cpp'; then $(CYGPATH_W) 'Magick++/tests/coderInfo.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/coderInfo.cpp'; fi`
+
+Magick++/tests/Magick___tests_color-color.o: Magick++/tests/color.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_color_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_color-color.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_color-color.Tpo -c -o Magick++/tests/Magick___tests_color-color.o `test -f 'Magick++/tests/color.cpp' || echo '$(srcdir)/'`Magick++/tests/color.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_color-color.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_color-color.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/color.cpp' object='Magick++/tests/Magick___tests_color-color.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_color_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_color-color.o `test -f 'Magick++/tests/color.cpp' || echo '$(srcdir)/'`Magick++/tests/color.cpp
+
+Magick++/tests/Magick___tests_color-color.obj: Magick++/tests/color.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_color_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_color-color.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_color-color.Tpo -c -o Magick++/tests/Magick___tests_color-color.obj `if test -f 'Magick++/tests/color.cpp'; then $(CYGPATH_W) 'Magick++/tests/color.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/color.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_color-color.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_color-color.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/color.cpp' object='Magick++/tests/Magick___tests_color-color.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_color_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_color-color.obj `if test -f 'Magick++/tests/color.cpp'; then $(CYGPATH_W) 'Magick++/tests/color.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/color.cpp'; fi`
+
+Magick++/tests/Magick___tests_colorHistogram-colorHistogram.o: Magick++/tests/colorHistogram.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_colorHistogram_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_colorHistogram-colorHistogram.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_colorHistogram-colorHistogram.Tpo -c -o Magick++/tests/Magick___tests_colorHistogram-colorHistogram.o `test -f 'Magick++/tests/colorHistogram.cpp' || echo '$(srcdir)/'`Magick++/tests/colorHistogram.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_colorHistogram-colorHistogram.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_colorHistogram-colorHistogram.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/colorHistogram.cpp' object='Magick++/tests/Magick___tests_colorHistogram-colorHistogram.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_colorHistogram_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_colorHistogram-colorHistogram.o `test -f 'Magick++/tests/colorHistogram.cpp' || echo '$(srcdir)/'`Magick++/tests/colorHistogram.cpp
+
+Magick++/tests/Magick___tests_colorHistogram-colorHistogram.obj: Magick++/tests/colorHistogram.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_colorHistogram_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_colorHistogram-colorHistogram.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_colorHistogram-colorHistogram.Tpo -c -o Magick++/tests/Magick___tests_colorHistogram-colorHistogram.obj `if test -f 'Magick++/tests/colorHistogram.cpp'; then $(CYGPATH_W) 'Magick++/tests/colorHistogram.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/colorHistogram.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_colorHistogram-colorHistogram.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_colorHistogram-colorHistogram.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/colorHistogram.cpp' object='Magick++/tests/Magick___tests_colorHistogram-colorHistogram.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_colorHistogram_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_colorHistogram-colorHistogram.obj `if test -f 'Magick++/tests/colorHistogram.cpp'; then $(CYGPATH_W) 'Magick++/tests/colorHistogram.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/colorHistogram.cpp'; fi`
+
+Magick++/tests/Magick___tests_exceptions-exceptions.o: Magick++/tests/exceptions.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_exceptions_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_exceptions-exceptions.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_exceptions-exceptions.Tpo -c -o Magick++/tests/Magick___tests_exceptions-exceptions.o `test -f 'Magick++/tests/exceptions.cpp' || echo '$(srcdir)/'`Magick++/tests/exceptions.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_exceptions-exceptions.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_exceptions-exceptions.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/exceptions.cpp' object='Magick++/tests/Magick___tests_exceptions-exceptions.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_exceptions_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_exceptions-exceptions.o `test -f 'Magick++/tests/exceptions.cpp' || echo '$(srcdir)/'`Magick++/tests/exceptions.cpp
+
+Magick++/tests/Magick___tests_exceptions-exceptions.obj: Magick++/tests/exceptions.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_exceptions_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_exceptions-exceptions.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_exceptions-exceptions.Tpo -c -o Magick++/tests/Magick___tests_exceptions-exceptions.obj `if test -f 'Magick++/tests/exceptions.cpp'; then $(CYGPATH_W) 'Magick++/tests/exceptions.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/exceptions.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_exceptions-exceptions.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_exceptions-exceptions.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/exceptions.cpp' object='Magick++/tests/Magick___tests_exceptions-exceptions.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_exceptions_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_exceptions-exceptions.obj `if test -f 'Magick++/tests/exceptions.cpp'; then $(CYGPATH_W) 'Magick++/tests/exceptions.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/exceptions.cpp'; fi`
+
+Magick++/tests/Magick___tests_montageImages-montageImages.o: Magick++/tests/montageImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_montageImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_montageImages-montageImages.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_montageImages-montageImages.Tpo -c -o Magick++/tests/Magick___tests_montageImages-montageImages.o `test -f 'Magick++/tests/montageImages.cpp' || echo '$(srcdir)/'`Magick++/tests/montageImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_montageImages-montageImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_montageImages-montageImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/montageImages.cpp' object='Magick++/tests/Magick___tests_montageImages-montageImages.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_montageImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_montageImages-montageImages.o `test -f 'Magick++/tests/montageImages.cpp' || echo '$(srcdir)/'`Magick++/tests/montageImages.cpp
+
+Magick++/tests/Magick___tests_montageImages-montageImages.obj: Magick++/tests/montageImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_montageImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_montageImages-montageImages.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_montageImages-montageImages.Tpo -c -o Magick++/tests/Magick___tests_montageImages-montageImages.obj `if test -f 'Magick++/tests/montageImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/montageImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/montageImages.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_montageImages-montageImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_montageImages-montageImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/montageImages.cpp' object='Magick++/tests/Magick___tests_montageImages-montageImages.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_montageImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_montageImages-montageImages.obj `if test -f 'Magick++/tests/montageImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/montageImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/montageImages.cpp'; fi`
+
+Magick++/tests/Magick___tests_morphImages-morphImages.o: Magick++/tests/morphImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_morphImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_morphImages-morphImages.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_morphImages-morphImages.Tpo -c -o Magick++/tests/Magick___tests_morphImages-morphImages.o `test -f 'Magick++/tests/morphImages.cpp' || echo '$(srcdir)/'`Magick++/tests/morphImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_morphImages-morphImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_morphImages-morphImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/morphImages.cpp' object='Magick++/tests/Magick___tests_morphImages-morphImages.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_morphImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_morphImages-morphImages.o `test -f 'Magick++/tests/morphImages.cpp' || echo '$(srcdir)/'`Magick++/tests/morphImages.cpp
+
+Magick++/tests/Magick___tests_morphImages-morphImages.obj: Magick++/tests/morphImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_morphImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_morphImages-morphImages.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_morphImages-morphImages.Tpo -c -o Magick++/tests/Magick___tests_morphImages-morphImages.obj `if test -f 'Magick++/tests/morphImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/morphImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/morphImages.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_morphImages-morphImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_morphImages-morphImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/morphImages.cpp' object='Magick++/tests/Magick___tests_morphImages-morphImages.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_morphImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_morphImages-morphImages.obj `if test -f 'Magick++/tests/morphImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/morphImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/morphImages.cpp'; fi`
+
+Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.o: Magick++/tests/readWriteBlob.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_readWriteBlob_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_readWriteBlob-readWriteBlob.Tpo -c -o Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.o `test -f 'Magick++/tests/readWriteBlob.cpp' || echo '$(srcdir)/'`Magick++/tests/readWriteBlob.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_readWriteBlob-readWriteBlob.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_readWriteBlob-readWriteBlob.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/readWriteBlob.cpp' object='Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_readWriteBlob_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.o `test -f 'Magick++/tests/readWriteBlob.cpp' || echo '$(srcdir)/'`Magick++/tests/readWriteBlob.cpp
+
+Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.obj: Magick++/tests/readWriteBlob.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_readWriteBlob_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_readWriteBlob-readWriteBlob.Tpo -c -o Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.obj `if test -f 'Magick++/tests/readWriteBlob.cpp'; then $(CYGPATH_W) 'Magick++/tests/readWriteBlob.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/readWriteBlob.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_readWriteBlob-readWriteBlob.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_readWriteBlob-readWriteBlob.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/readWriteBlob.cpp' object='Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_readWriteBlob_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_readWriteBlob-readWriteBlob.obj `if test -f 'Magick++/tests/readWriteBlob.cpp'; then $(CYGPATH_W) 'Magick++/tests/readWriteBlob.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/readWriteBlob.cpp'; fi`
+
+Magick++/tests/Magick___tests_readWriteImages-readWriteImages.o: Magick++/tests/readWriteImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_readWriteImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_readWriteImages-readWriteImages.o -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_readWriteImages-readWriteImages.Tpo -c -o Magick++/tests/Magick___tests_readWriteImages-readWriteImages.o `test -f 'Magick++/tests/readWriteImages.cpp' || echo '$(srcdir)/'`Magick++/tests/readWriteImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_readWriteImages-readWriteImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_readWriteImages-readWriteImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/readWriteImages.cpp' object='Magick++/tests/Magick___tests_readWriteImages-readWriteImages.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_readWriteImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_readWriteImages-readWriteImages.o `test -f 'Magick++/tests/readWriteImages.cpp' || echo '$(srcdir)/'`Magick++/tests/readWriteImages.cpp
+
+Magick++/tests/Magick___tests_readWriteImages-readWriteImages.obj: Magick++/tests/readWriteImages.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_readWriteImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Magick++/tests/Magick___tests_readWriteImages-readWriteImages.obj -MD -MP -MF Magick++/tests/$(DEPDIR)/Magick___tests_readWriteImages-readWriteImages.Tpo -c -o Magick++/tests/Magick___tests_readWriteImages-readWriteImages.obj `if test -f 'Magick++/tests/readWriteImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/readWriteImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/readWriteImages.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) Magick++/tests/$(DEPDIR)/Magick___tests_readWriteImages-readWriteImages.Tpo Magick++/tests/$(DEPDIR)/Magick___tests_readWriteImages-readWriteImages.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Magick++/tests/readWriteImages.cpp' object='Magick++/tests/Magick___tests_readWriteImages-readWriteImages.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(Magick___tests_readWriteImages_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Magick++/tests/Magick___tests_readWriteImages-readWriteImages.obj `if test -f 'Magick++/tests/readWriteImages.cpp'; then $(CYGPATH_W) 'Magick++/tests/readWriteImages.cpp'; else $(CYGPATH_W) '$(srcdir)/Magick++/tests/readWriteImages.cpp'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+ -rm -rf Magick++/demo/.libs Magick++/demo/_libs
+ -rm -rf Magick++/lib/.libs Magick++/lib/_libs
+ -rm -rf Magick++/tests/.libs Magick++/tests/_libs
+ -rm -rf coders/.libs coders/_libs
+ -rm -rf filters/.libs filters/_libs
+ -rm -rf magick/.libs magick/_libs
+ -rm -rf tests/.libs tests/_libs
+ -rm -rf utilities/.libs utilities/_libs
+ -rm -rf wand/.libs wand/_libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-man1: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+install-man4: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man4dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man4dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man4dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.4[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^4][0-9a-z]*$$,4,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man4dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man4dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man4dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man4dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man4:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man4dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.4[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^4][0-9a-z]*$$,4,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man4dir)'; $(am__uninstall_files_from_dir)
+install-man5: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-configlibDATA: $(configlib_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(configlib_DATA)'; test -n "$(configlibdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(configlibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(configlibdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configlibdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(configlibdir)" || exit $$?; \
+ done
+
+uninstall-configlibDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(configlib_DATA)'; test -n "$(configlibdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(configlibdir)'; $(am__uninstall_files_from_dir)
+install-configshareDATA: $(configshare_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(configshare_DATA)'; test -n "$(configsharedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(configsharedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(configsharedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configsharedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(configsharedir)" || exit $$?; \
+ done
+
+uninstall-configshareDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(configshare_DATA)'; test -n "$(configsharedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(configsharedir)'; $(am__uninstall_files_from_dir)
+install-docDATA: $(doc_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \
+ done
+
+uninstall-docDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+install-magickincHEADERS: $(magickinc_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(magickinc_HEADERS)'; test -n "$(magickincdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(magickincdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(magickincdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(magickincdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(magickincdir)" || exit $$?; \
+ done
+
+uninstall-magickincHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(magickinc_HEADERS)'; test -n "$(magickincdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(magickincdir)'; $(am__uninstall_files_from_dir)
+install-magickppincHEADERS: $(magickppinc_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(magickppinc_HEADERS)'; test -n "$(magickppincdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(magickppincdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(magickppincdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(magickppincdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(magickppincdir)" || exit $$?; \
+ done
+
+uninstall-magickppincHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(magickppinc_HEADERS)'; test -n "$(magickppincdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(magickppincdir)'; $(am__uninstall_files_from_dir)
+install-magickpptopincHEADERS: $(magickpptopinc_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(magickpptopinc_HEADERS)'; test -n "$(magickpptopincdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(magickpptopincdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(magickpptopincdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(magickpptopincdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(magickpptopincdir)" || exit $$?; \
+ done
+
+uninstall-magickpptopincHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(magickpptopinc_HEADERS)'; test -n "$(magickpptopincdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(magickpptopincdir)'; $(am__uninstall_files_from_dir)
+install-wandincHEADERS: $(wandinc_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(wandinc_HEADERS)'; test -n "$(wandincdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(wandincdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(wandincdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(wandincdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(wandincdir)" || exit $$?; \
+ done
+
+uninstall-wandincHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(wandinc_HEADERS)'; test -n "$(wandincdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(wandincdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+.sh.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.sh$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.tap.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TAP_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TAP_LOG_DRIVER_FLAGS) $(TAP_LOG_DRIVER_FLAGS) -- $(TAP_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.tap$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TAP_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TAP_LOG_DRIVER_FLAGS) $(TAP_LOG_DRIVER_FLAGS) -- $(TAP_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__post_remove_distdir)
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=../.. --prefix="$$dc_install_base" \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \
+ $(HEADERS) all-local
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(codersdir)" "$(DESTDIR)$(filtersdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man4dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(configlibdir)" "$(DESTDIR)$(configsharedir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(magickincdir)" "$(DESTDIR)$(magickppincdir)" "$(DESTDIR)$(magickpptopincdir)" "$(DESTDIR)$(wandincdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f Magick++/demo/$(DEPDIR)/$(am__dirstamp)
+ -rm -f Magick++/demo/$(am__dirstamp)
+ -rm -f Magick++/lib/$(DEPDIR)/$(am__dirstamp)
+ -rm -f Magick++/lib/$(am__dirstamp)
+ -rm -f Magick++/tests/$(DEPDIR)/$(am__dirstamp)
+ -rm -f Magick++/tests/$(am__dirstamp)
+ -rm -f coders/$(DEPDIR)/$(am__dirstamp)
+ -rm -f coders/$(am__dirstamp)
+ -rm -f filters/$(DEPDIR)/$(am__dirstamp)
+ -rm -f filters/$(am__dirstamp)
+ -rm -f magick/$(DEPDIR)/$(am__dirstamp)
+ -rm -f magick/$(am__dirstamp)
+ -rm -f tests/$(DEPDIR)/$(am__dirstamp)
+ -rm -f tests/$(am__dirstamp)
+ -rm -f utilities/$(DEPDIR)/$(am__dirstamp)
+ -rm -f utilities/$(am__dirstamp)
+ -rm -f wand/$(DEPDIR)/$(am__dirstamp)
+ -rm -f wand/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-checkPROGRAMS \
+ clean-codersLTLIBRARIES clean-filtersLTLIBRARIES clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-local \
+ clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf Magick++/demo/$(DEPDIR) Magick++/lib/$(DEPDIR) Magick++/tests/$(DEPDIR) coders/$(DEPDIR) filters/$(DEPDIR) magick/$(DEPDIR) tests/$(DEPDIR) utilities/$(DEPDIR) wand/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-local distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-codersLTLIBRARIES install-configlibDATA \
+ install-configshareDATA install-data-local install-docDATA \
+ install-filtersLTLIBRARIES install-includeHEADERS \
+ install-magickincHEADERS install-magickppincHEADERS \
+ install-magickpptopincHEADERS install-man \
+ install-pkgconfigDATA install-wandincHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS \
+ install-exec-local install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1 install-man4 install-man5
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf Magick++/demo/$(DEPDIR) Magick++/lib/$(DEPDIR) Magick++/tests/$(DEPDIR) coders/$(DEPDIR) filters/$(DEPDIR) magick/$(DEPDIR) tests/$(DEPDIR) utilities/$(DEPDIR) wand/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic \
+ maintainer-clean-local
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-codersLTLIBRARIES uninstall-configlibDATA \
+ uninstall-configshareDATA uninstall-docDATA \
+ uninstall-filtersLTLIBRARIES uninstall-includeHEADERS \
+ uninstall-libLTLIBRARIES uninstall-local \
+ uninstall-magickincHEADERS uninstall-magickppincHEADERS \
+ uninstall-magickpptopincHEADERS uninstall-man \
+ uninstall-pkgconfigDATA uninstall-wandincHEADERS
+
+uninstall-man: uninstall-man1 uninstall-man4 uninstall-man5
+
+.MAKE: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am all-local am--refresh check \
+ check-TESTS check-am check-local clean clean-binPROGRAMS \
+ clean-checkPROGRAMS clean-codersLTLIBRARIES clean-cscope \
+ clean-filtersLTLIBRARIES clean-generic clean-libLTLIBRARIES \
+ clean-libtool clean-local clean-noinstLTLIBRARIES cscope \
+ cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+ dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \
+ dist-zip distcheck distclean distclean-compile \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-local distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-binPROGRAMS install-binSCRIPTS \
+ install-codersLTLIBRARIES install-configlibDATA \
+ install-configshareDATA install-data install-data-am \
+ install-data-local install-docDATA install-dvi install-dvi-am \
+ install-exec install-exec-am install-exec-local \
+ install-filtersLTLIBRARIES install-html install-html-am \
+ install-includeHEADERS install-info install-info-am \
+ install-libLTLIBRARIES install-magickincHEADERS \
+ install-magickppincHEADERS install-magickpptopincHEADERS \
+ install-man install-man1 install-man4 install-man5 install-pdf \
+ install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
+ install-strip install-wandincHEADERS installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic maintainer-clean-local mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-codersLTLIBRARIES uninstall-configlibDATA \
+ uninstall-configshareDATA uninstall-docDATA \
+ uninstall-filtersLTLIBRARIES uninstall-includeHEADERS \
+ uninstall-libLTLIBRARIES uninstall-local \
+ uninstall-magickincHEADERS uninstall-magickppincHEADERS \
+ uninstall-magickpptopincHEADERS uninstall-man uninstall-man1 \
+ uninstall-man4 uninstall-man5 uninstall-pkgconfigDATA \
+ uninstall-wandincHEADERS
+
+.PRECIOUS: Makefile
+
+magick-install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(magickincdir)
+ $(INSTALL_HEADER) magick/magick_config_api.h $(DESTDIR)$(magickincdir)/magick_config.h
+magick-uninstall-local:
+ rm -f $(DESTDIR)$(magickincdir)/magick_config.h
+install-data-html:
+ $(mkinstalldirs) $(DESTDIR)$(htmldir)
+ @for dir in $(DOCDIRS) ; do \
+ $(mkinstalldirs) $(DESTDIR)$(htmldir)/$$dir && \
+ for file in $(srcdir)/$$dir/*.* ; do \
+ case $$file in \
+ *.c | *.css | *.gif | *.html | *.ico | *.jpg | *.png ) \
+ echo "$(INSTALL_DATA) $$file $(DESTDIR)$(htmldir)/$$dir" ; \
+ $(INSTALL_DATA) "$$file" $(DESTDIR)$(htmldir)/$$dir ; \
+ ;; \
+ esac \
+ done ; \
+ done
+# rm -f $(DESTDIR)$(htmldir)/index.html
+uninstall-data-html:
+ for dir in $(DOCDIRS) ; do \
+ rm -f -r $(DESTDIR)$(htmldir)/$$dir ; \
+ done
+
+@MAINTAINER_MODE_TRUE@$(RST2HTML_TARGETS) : \
+@MAINTAINER_MODE_TRUE@ $(top_srcdir)/scripts/html_fragments.py \
+@MAINTAINER_MODE_TRUE@ $(top_srcdir)/scripts/rst2htmldeco.py \
+@MAINTAINER_MODE_TRUE@ $(top_srcdir)/scripts/omp_decimal_align.py \
+@MAINTAINER_MODE_TRUE@ $(WWWDIR)/Makefile.am
+
+# Build HTML version of RST file
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/%.html: $(top_srcdir)/%.txt
+@MAINTAINER_MODE_TRUE@ $(RST2HTMLDECO) --link-stylesheet=`$(RELPATH) $(top_srcdir)/www $@`docutils-articles.css \
+@MAINTAINER_MODE_TRUE@ --url-prefix=`$(RELPATH) $(top_srcdir)/www $@` $< $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/%.html: $(top_srcdir)/%.rst
+@MAINTAINER_MODE_TRUE@ $(RST2HTMLDECO) --link-stylesheet=`$(RELPATH) $(top_srcdir)/www $@`docutils-articles.css \
+@MAINTAINER_MODE_TRUE@ --url-prefix=`$(RELPATH) $(top_srcdir)/www $@` $< | $(OMP_DECIMAL_ALIGN) > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/Changelog.rst: $(top_srcdir)/ChangeLog
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2016.rst: $(top_srcdir)/ChangeLog.2016
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2015.rst: $(top_srcdir)/ChangeLog.2015
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2014.rst: $(top_srcdir)/ChangeLog.2014
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2013.rst: $(top_srcdir)/ChangeLog.2013
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2012.rst: $(top_srcdir)/ChangeLog.2012
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2011.rst: $(top_srcdir)/ChangeLog.2011
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2010.rst: $(top_srcdir)/ChangeLog.2010
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2009.rst: $(top_srcdir)/ChangeLog.2009
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2008.rst: $(top_srcdir)/ChangeLog.2008
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2007.rst: $(top_srcdir)/ChangeLog.2007
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2006.rst: $(top_srcdir)/ChangeLog.2006
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2005.rst: $(top_srcdir)/ChangeLog.2005
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2004.rst: $(top_srcdir)/ChangeLog.2004
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2003.rst: $(top_srcdir)/ChangeLog.2003
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2002.rst: $(top_srcdir)/ChangeLog.2002
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/ChangeLog-2001.rst: $(top_srcdir)/ChangeLog.2001
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+@MAINTAINER_MODE_TRUE@$(top_srcdir)/www/Magick++/ChangeLog.rst: $(top_srcdir)/Magick++/ChangeLog
+@MAINTAINER_MODE_TRUE@ $(CHANGELOG2RST) < $^ > $@
+
+# Build color.html
+@MAINTAINER_MODE_TRUE@$(WWWDIR)/color.html : $(NAMED_COLORS)
+@MAINTAINER_MODE_TRUE@ $(NAMED_COLORS) > $@
+
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@$(WWWAPI_HTML_TARGETS) : $(FORMATCAPI) $(RST2HTMLDECO) $(APIWHATIS) $(top_srcdir)/scripts/html_fragments.py $(top_srcdir)/www/api/Makefile.am $(top_srcdir)/www/api/api_hyperlinks.rst
+
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@$(WWWAPIDIR)/%.apirst : $(top_srcdir)/magick/%.c
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(FORMATCAPI) --whatis-file $(APIWHATIS) $< $@
+
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@$(WWWAPIDIR)/%.html : $(WWWAPIDIR)/%.apirst
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(RST2HTMLDECO) --link-stylesheet=`$(RELPATH) $(top_srcdir)/www $@`docutils-api.css \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ --url-prefix=`$(RELPATH) $(top_srcdir)/www $@` $< $@
+
+#APIWHATIS = $(top_srcdir)/scripts/whatis.txt
+#FORMATCAPI = $(top_srcdir)/scripts/format_c_api_doc.py
+
+#APIRST2HTML_COMMAND = $(RST2HTMLDECO) \
+# --link-stylesheet=../docutils-articles.css`
+
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@$(WWWWANDAPI_HTML_TARGETS) : $(FORMATCAPI) \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(RST2HTMLDECO) \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(APIWHATIS) \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(top_srcdir)/scripts/html_fragments.py \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(top_srcdir)/www/wand/Makefile.am \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(top_srcdir)/www/api/api_hyperlinks.rst
+
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@$(WWWWANDAPIDIR)/%.apirst : $(top_srcdir)/wand/%.c
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(FORMATCAPI) --whatis-file $(APIWHATIS) \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ --include-rst ../api/api_hyperlinks.rst $< $@
+
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@$(WWWWANDAPIDIR)/%.html : $(WWWWANDAPIDIR)/%.apirst
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ $(RST2HTMLDECO) --link-stylesheet=`$(RELPATH) $(top_srcdir)/www $@`docutils-api.css \
+@HasRST2HTML_TRUE@@MAINTAINER_MODE_TRUE@ --url-prefix=`$(RELPATH) $(top_srcdir)/www $@` $< $@
+
+utilities/tests/montage.log : \
+ utilities/tests/effects.tap
+@MAGICK_COMPAT_TRUE@install-exec-local-utilities:
+@MAGICK_COMPAT_TRUE@ $(mkdir_p) $(DESTDIR)$(bindir)
+@MAGICK_COMPAT_TRUE@ cd $(DESTDIR)$(bindir) ; \
+@MAGICK_COMPAT_TRUE@ gm=`echo "gm" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+@MAGICK_COMPAT_TRUE@ for name in $(MAGICKPROGRAMS) ; \
+@MAGICK_COMPAT_TRUE@ do \
+@MAGICK_COMPAT_TRUE@ target=`echo "$$name" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+@MAGICK_COMPAT_TRUE@ rm -f $$target ; \
+@MAGICK_COMPAT_TRUE@ $(LN_S) $$gm $$target ; \
+@MAGICK_COMPAT_TRUE@ done
+@MAGICK_COMPAT_TRUE@uninstall-local-utilities:
+@MAGICK_COMPAT_TRUE@ cd $(DESTDIR)$(bindir) ; \
+@MAGICK_COMPAT_TRUE@ for name in $(MAGICKPROGRAMS) ; \
+@MAGICK_COMPAT_TRUE@ do \
+@MAGICK_COMPAT_TRUE@ target=`echo "$$name" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+@MAGICK_COMPAT_TRUE@ rm -f $$target ; \
+@MAGICK_COMPAT_TRUE@ done
+
+# If source files are missing, see if they can be obtained via VPATH
+# and create a linked tree.
+perl-sources:
+ @if test -n "$(VPATH)" ; then \
+ echo "Linking PerlMagick Sources ..." ; \
+ imagemagick=`(cd $(VPATH) ; pwd)` && \
+ ( cd $(PERLMAGICK) && \
+ sh $$imagemagick/lndir.sh $$imagemagick/$(PERLMAGICK) ) \
+ fi ; \
+ touch perl-sources
+
+# The substituted file Magick.pm needs to be copied to the PerlMagick
+# source directory since it becomes part of the source distribution.
+$(top_srcdir)/$(PERLMAGICK)/Magick.pm : $(PERLMAGICK)/Magick.pm
+ @if test -n "$(VPATH)" ; then \
+ echo "Updating $(PERLMAGICK)/Magick.pm ..." ; \
+ cp $(PERLMAGICK)/Magick.pm $(top_srcdir)/$(PERLMAGICK)/Magick.pm ; \
+ fi
+
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@$(PERLMAKEFILE): perl-sources $(LIBMAGICK) $(PERLMAKEMAKER)
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@ cd $(PERLMAGICK) && @PERL@ Makefile.PL $(PERL_MAKE_OPTIONS)
+
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@install-exec-perl: $(PERLMAKEFILE)
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@ ( cd $(PERLMAGICK) && $(MAKE) CC='@CC@' && \
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@ $(MAKE) CC='@CC@' install )
+
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@all-perl: perl-sources
+
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@uninstall-exec-perl: $(PERLMAKEFILE)
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@ echo "Uninstall not supported for PerlMagick"
+
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@check-perl: $(PERLMAKEFILE)
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@ cd $(PERLMAGICK) && $(abs_top_builddir)/rungm.sh $(MAKE) CC='@CC@' test
+
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@perl-build: $(PERLMAKEFILE)
+@WITH_PERL_DYNAMIC_TRUE@@WITH_PERL_TRUE@ ( cd $(PERLMAGICK) && $(MAKE) CC='@CC@' )
+
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@$(PERLMAKEFILE): perl-sources $(LIBMAGICK) $(PERLMAKEMAKER)
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ cd $(PERLMAGICK) && @PERL@ Makefile.PL MAP_TARGET=$(PERLSTATICNAME) $(PERL_MAKE_OPTIONS) && $(MAKE) Makefile ; $(MAKE) Makefile
+
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@$(PERLMAGICK)/$(PERLSTATICNAME): $(LIBMAGICK) $(PERLMAKEFILE)
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ ( rm -f $(PERLMAGICK)/$(PERLSTATICNAME) ; cd $(PERLMAGICK) && $(MAKE) CC='@CC@' $(PERLSTATICNAME) ; $(MAKE) CC='@CC@' $(PERLSTATICNAME) )
+
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@all-perl: $(PERLMAGICK)/$(PERLSTATICNAME)
+
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@install-exec-perl: $(PERLMAGICK)/$(PERLSTATICNAME)
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ rm -f "$(DESTDIR)$(BIN_DIR)/$(PERLSTATICNAME)"
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ if test "x$(DESTDIR)" = "x" -o "$(PERL_SUPPORTS_DESTDIR)" = 'yes' ; then \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ ( cd $(PERLMAGICK) && \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ $(MAKE) -f Makefile.aperl CC='@CC@' inst_perl MAP_TARGET=$(PERLSTATICNAME) \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ INSTALLBIN="$(BIN_DIR)" \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ ) ; \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ else \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ ( cd $(PERLMAGICK) && \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ $(MAKE) -f Makefile.aperl CC='@CC@' inst_perl MAP_TARGET=$(PERLSTATICNAME) \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ INSTALLBIN="$(DESTDIR)$(BIN_DIR)" PREFIX="$(DESTDIR)$(prefix)" \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ ) ; \
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ fi
+
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@uninstall-exec-perl:
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ rm -f '$(DESTDIR)$(BIN_DIR)/$(PERLSTATICNAME)'
+
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@check-perl: $(PERLMAGICK)/$(PERLSTATICNAME)
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@ cd $(PERLMAGICK) && $(abs_top_builddir)/rungm.sh $(MAKE) -f Makefile.aperl CC='@CC@' test
+
+@WITH_PERL_DYNAMIC_FALSE@@WITH_PERL_STATIC_TRUE@@WITH_PERL_TRUE@perl-build: $(PERLMAGICK)/$(PERLSTATICNAME)
+
+@WITH_PERL_TRUE@clean-perl:
+@WITH_PERL_TRUE@ (cd $(PERLMAGICK) && \
+@WITH_PERL_TRUE@ ( if test -f Makefile.old ; then $(MAKE) -f Makefile.old CC='@CC@' clean ; fi ) ; \
+@WITH_PERL_TRUE@ ( if test -f Makefile ; then $(MAKE) CC='@CC@' clean ; fi ) ; \
+@WITH_PERL_TRUE@ ( if test -f Makefile ; then $(MAKE) CC='@CC@' clean ; fi ) ; \
+@WITH_PERL_TRUE@ rm -f Makefile.old PerlMagick ; \
+@WITH_PERL_TRUE@ rm -f t/output* t/jng/*_tmp.jng t/*/output* )
+@WITH_PERL_TRUE@ rm -f perl-sources
+
+@WITH_PERL_TRUE@distclean-perl: clean-perl
+
+# Satisfy makefile requirements if not building PERL
+@WITH_PERL_FALSE@all-perl:
+@WITH_PERL_FALSE@install-exec-perl:
+@WITH_PERL_FALSE@uninstall-exec-perl:
+@WITH_PERL_FALSE@check-perl:
+@WITH_PERL_FALSE@clean-perl:
+@WITH_PERL_FALSE@distclean-perl:
+
+# Target to build just the web pages.
+@MAINTAINER_MODE_TRUE@.PHONY: www
+@MAINTAINER_MODE_TRUE@www : $(WWW_MAINTAINER_TARGETS) $(WWWAPI_MAINTAINER_TARGETS) $(WWWWANDAPI_MAINTAINER_TARGETS)
+
+all-local: $(MAGICKPP_LOCAL_TARGETS) \
+ $(PERLMAGICK_ALL_LOCAL_TARGETS) $(MAINTAINER_TARGETS)
+
+install-exec-local: $(PERLMAGICK_INSTALL_EXEC_LOCAL_TARGETS) \
+ $(UTILITIES_INSTALL_EXEC_LOCAL_TARGETS)
+
+install-data-local: $(MAGICK_INSTALL_DATA_LOCAL_TARGETS) \
+ $(PERLMAGICK_INSTALL_DATA_LOCAL_TARGETS) \
+ $(HTML_INSTALL_DATA_TARGETS)
+
+uninstall-local: $(MAGICK_UNINSTALL_LOCAL_TARGETS) \
+ $(PERLMAGICK_UNINSTALL_LOCAL_TARGETS) \
+ $(HTML_UNINSTALL_DATA_TARGETS) \
+ $(UTILITIES_UNINSTALL_LOCAL_TARGETS)
+
+clean-local: $(PERLMAGICK_CLEAN_LOCAL_TARGETS)
+
+distclean-local: $(PERLMAGICK_DISTCLEAN_LOCAL_TARGETS)
+
+maintainer-clean-local: $(PERLMAGICK_MAINTAINER_CLEAN_LOCAL_TARGETS)
+
+check-local: $(PERLMAGICK_CHECK_LOCAL_TARGETS)
+
+# drd: valgrind's newer thread error detector
+drd:
+ $(MAKE) MEMCHECK='valgrind --tool=drd --check-stack-var=yes --var-info=yes \
+ --quiet $(VALGRIND_EXTRA_OPTS)' check
+
+# helgrind: valgrind's older thread error detector
+helgrind:
+ $(MAKE) MEMCHECK='valgrind --tool=helgrind --error-exitcode=2 --quiet \
+ $(VALGRIND_EXTRA_OPTS)' check
+
+# memcheck: valgrind's memory access checker.
+# The suppressions which come with valgrind are usually insufficient
+# to handle certain pthread library aspects and gomp and so errors
+# will be reported which are unrelated to GraphicsMagick. When first
+# starting with a new system (or after a major system update), it is
+# good to execute the test suite like 'make memcheck
+# VALGRIND_EXTRA_OPTS=--gen-suppressions=all' to create valgrind
+# suppression entries in the test log. Tell valgrind about the
+# suppressions by creating a .valgrindrc file with content like:
+# --memcheck:suppressions=mysupp.supp
+memcheck:
+ $(MAKE) MEMCHECK='valgrind --tool=memcheck --leak-check=full --read-var-info=yes \
+ --error-exitcode=2 --track-origins=yes --num-callers=12 \
+ --quiet $(VALGRIND_EXTRA_OPTS)' check
+
+# ptrcheck: valgrind's experimental pointer checking tool.
+ptrcheck:
+ $(MAKE) MEMCHECK='valgrind --tool=exp-ptrcheck --quiet $(VALGRIND_EXTRA_OPTS)' check
+dist-hook:
+ ( \
+ builddir=`pwd` ; \
+ cd $(srcdir) && \
+ ( \
+ for dir in $(DISTDIRS) ; do \
+ find $$dir -depth -print | egrep -v '(~$$)|(/\.hg)|(/\.#)|(/\.deps)|(\.pyc)' \
+ | cpio -pdum $$builddir/$(distdir) 2> /dev/null ; \
+ done \
+ ) \
+ )
+
+#
+# Additional install rules
+#
+
+# Ensure that version.h at $(srcdir)/magick/version.h is kept up to date.
+magick-version: magick/version.h
+ @if test -f "$(srcdir)/VisualMagick/installer/inc/version.isx.in" ; then \
+ ./config.status --file="$(srcdir)/VisualMagick/installer/inc/version.isx" 2> /dev/null ; \
+ fi
+ @if test -n "$(VPATH)" ; then \
+ cmp magick/version.h $(srcdir)/magick/version.h > /dev/null ; \
+ if test $$? -eq 1 ; then \
+ echo "Updating $(srcdir)/magick/version.h ..."; \
+ cp magick/version.h $(srcdir)/magick/version.h ; \
+ fi ; \
+ fi ; \
+ touch magick-version
+
+magick/version.h: $(top_srcdir)/ChangeLog $(top_srcdir)/version.sh
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+$(DIST_WINDOWS_SRC_7ZIP) windows-dist:
+ if test -d $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM) ; then \
+ chmod -R u+w $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM) ; \
+ rm -rf $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM) ; \
+ fi
+ hg --repository $(top_srcdir) archive --rev $(HG_BRANCH_TAG) $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)
+@HAS_P7ZIP_TRUE@ rm -f $(DIST_WINDOWS_SRC_7ZIP)
+@HAS_P7ZIP_TRUE@ $(P7ZIP) a -t7z -mx=9 $(DIST_WINDOWS_SRC_7ZIP) $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)
+@HAS_P7ZIP_TRUE@ chmod 644 $(DIST_WINDOWS_SRC_7ZIP)
+ rm -rf $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM)
+@HAS_RPM_TRUE@.PHONY: srpm
+@HAS_RPM_TRUE@$(DIST_ARCHIVE_SRPM) srpm: $(distdir).tar.bz2
+@HAS_RPM_TRUE@ rm -f $(DIST_ARCHIVE_SRPM)
+@HAS_RPM_TRUE@ $(RPM) --define="_sourcedir `pwd`" --define="_srcrpmdir `pwd`" --nodeps -bs GraphicsMagick.spec
+@HAS_RPM_TRUE@ @echo ==============================================================
+@HAS_RPM_TRUE@ @echo $(DIST_ARCHIVE_SRPM) is ready for distribution.
+@HAS_RPM_TRUE@ @echo ==============================================================
+
+@HAS_RPM_TRUE@.PHONY: rpm
+@HAS_RPM_TRUE@rpm:
+@HAS_RPM_TRUE@ rm -rf $(RPMDIR)
+@HAS_RPM_TRUE@ $(MKDIR_P) $(RPMDIR)
+@HAS_RPM_TRUE@ $(MKDIR_P) $(RPMDIR)/BUILD
+@HAS_RPM_TRUE@ $(MKDIR_P) $(RPMDIR)/RPMS
+@HAS_RPM_TRUE@ $(RPM) --define="_sourcedir `pwd`" --define="_rpmdir `pwd`/$(RPMDIR)/RPMS" \
+@HAS_RPM_TRUE@ --define="_builddir `pwd`/$(RPMDIR)/BUILD" --define='quant $(QuantumDepth)' \
+@HAS_RPM_TRUE@ --nodeps -bb GraphicsMagick.spec
+@HAS_RPM_TRUE@ rm -rf rpmbuild
+@HAS_RPM_TRUE@ @echo ==============================================================
+@HAS_RPM_TRUE@ @echo $(DIST_ARCHIVE_RPM) is ready for distribution.
+@HAS_RPM_TRUE@ @echo ==============================================================
+snapshot: distcheck
+ $(MAKE) $(DIST_ARCHIVE_SRPM)
+ $(MAKE) $(DIST_WINDOWS_SRC_7ZIP)
+ mv $(DIST_ARCHIVES) $(DIST_WINDOWS_SRC_7ZIP) $(DIST_ARCHIVE_SRPM) $(SNAPSHOT_DIRECTORY)/
+ cp $(top_srcdir)/ChangeLog $(SNAPSHOT_DIRECTORY)/ChangeLog.txt
+ cp $(top_srcdir)/www/Changelog.html $(SNAPSHOT_DIRECTORY)/ChangeLog.html
+coverity:
+ $(MAKE) clean
+ cov-build --dir cov-int $(MAKE)
+ tar caf $(COVERITY_TARBALL) cov-int
+ curl --limit-rate 50K \
+ --form token=`cat $$HOME/.coverity_key_gm` \
+ --form email=$(COVERITY_EMAIL) \
+ --form file=@$(COVERITY_TARBALL) \
+ --form version=$(COVERITY_VERSION) \
+ --form description=$(COVERITY_DESCRIPTION) \
+ https://scan.coverity.com/builds?project=GraphicsMagick
+ $(RM) $(COVERITY_TARBALL)
+
+# Rules for a profiled build (according to Paolo Bonzini <bonzini@gnu.org>)
+#.PHONY: profile
+#profile:
+# $(MAKE) clean
+# $(MAKE) CFLAGS="$(CFLAGS) -fprofile-generate"
+# $(MAKE) check
+# $(MAKE) mostlyclean
+# $(MAKE) CFLAGS="$(CFLAGS) -fprofile-use"
+#
+#CLEANFILES = *.gcda *.gcno
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS.txt b/NEWS.txt
new file mode 100644
index 0000000..d38a018
--- /dev/null
+++ b/NEWS.txt
@@ -0,0 +1,3514 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+===================
+GraphicsMagick News
+===================
+
+This file was last updated on July 4, 2017
+
+Please note that this file records news for the associated development
+branch and that each development branch has its own NEWS file. See the
+ChangeLog file for full details.
+
+.. contents::
+ :local:
+
+
+1.3.26 (July 4, 2017)
+=====================
+
+Special Issues:
+
+* None
+
+Security Fixes:
+
+* DPX: Fix excessive use of memory (DOS issue) due to file header
+ claiming large image dimensions but insufficient backing
+ data. (CVE-2017-10799).
+
+* JNG: Fix memory leak when reading invalid JNG image (CVE-2017-8350).
+
+* MAT: Fix excessive use of memory (DOS issue) due to continuing
+ processing with insufficient data and claimed large image
+ size. Verify each file extent to make sure that it is within range
+ of file size. (CVE-2017-10800).
+
+* META: Fix heap overflow while parsing 8BIM chunk (CVE-2016-7800).
+
+* PCX: Fix denial of service issue.
+
+* RLE: Fix abnomally slow operation (denial of service issue) with
+ intentionally corrupt colormapped file.
+
+* PICT: Fix possible buffer overflow vulnerability given suitably
+ truncated input file.
+
+* PNG: Enforce spec requirement that the dimensions of the JPEG
+ embedded in a JDAT chunk must match the JHDR dimensions
+ (CVE-2016-9830).
+
+* PNG: Avoid NULL dereference when MAGN chunk processing fails.
+
+* SCT: Fix stack-buffer read overflow (underflow?) while reading SCT
+ header.
+
+* SGI: Fix denial of service issues. Delay large memory allocations
+ until file header has fully passed sanity checks.
+
+* TIFF: Fix out of bounds read when reading CMYKA TIFF which claims to
+ have only 2 samples per pixel (CVE-2017-6335).
+
+* TIFF: Fix out of bounds read when reading RGB TIFF which claims to
+ have only 1 sample per pixel (CVE-2017-10794).
+
+* WPG: Fix heap overflow (CVE-2016-7996). Fix assertion crash
+ (CVE-2016-7997).
+
+Bug fixes:
+
+* DifferenceImage(): Fix Fix all-black difference image if an input
+ file is colormapped.
+
+* EXIF orientation was not being properly detected for some files.
+
+* -frame: The `import` command -frame handling was improperly
+ implemented and was using already freed data.
+
+* GIF: Fixes for "Excessive LZW string data" problem.
+
+* Magick++: Bug fixes to PathSmoothCurvetoRel::operator() and
+ PathSmoothCurvetoRel::operator().
+
+* PAM: Support writing GRAYSCALE PAM format.
+
+* PNG: Fix memory leaks.
+
+* SVG: Fixed a memory leak. Fixed a possible null pointer dereference.
+
+* TclMagick: Problem that TkMagick could not resolve functions from
+ TclMagick under Linux is fixed.
+
+* TclMagick: Fix parser validatation in magickCmd() to avoid crash
+ given a syntax error.
+
+* TIFF: Fix for reading old JPEG files (avoids "Improper call to JPEG
+ library in state 0. (LibJpeg).").
+
+* TXT: Fixed memory leak.
+
+* XCF: Error checking is improved.
+
+New Features:
+
+* EXIF rotation: Support is added such that the EXIF orientation tag
+ is updated when the image is rotated.
+
+* MAT: Now support reading multiple images from Matlab V4 format.
+
+* Magick++: Orientation method now updates orientation in EXIF
+ profile, if it exists.
+
+* Magick++: Added Image attribute method which accepts a 'char *'
+ argument, and will remove the attribute if the value argument is
+ NULL.
+
+* -orient: The -orient command line option now also updates the
+ orientation in the EXIF profile, if it exists.
+
+* PGX: Support PGX JPEG 2000 format for reading and writing (within
+ the bounds of what JasPer supports).
+
+* Wand API: Added MagickAutoOrientImage(),
+ MagickGetImageOrientation(), MagickSetImageOrientation(),
+ MagickRemoveImageOption(), and MagickClearException().
+
+
+Feature improvements:
+
+* None
+
+Windows Delegate Updates/Additions:
+
+* TIFF: Updated to libtiff 4.0.8.
+
+Build Changes:
+
+* TclMagick: Updated configure to use latest TEA tcl.m4 version 3.10.
+ Support for AM_DISTCHECK_CONFIGURE_FLAGS so that 'make distcheck'
+ remembers configuration options, and also to uninstall pkgIndex.tcl.
+
+* VisualMagick Configure: A 'quantum' command line argument is added
+ to set the default quantum depth in the wizard drop-down list. This
+ This allows setting the quantum depth when the /nowizard argument
+ was supplied.
+
+Behavior Changes:
+
+* The installer for the Windows build no longer includes IMDisplay
+ (simple display program), ImageMagickDLL, and PerlMagick for
+ ActiveState Perl. These are still available to build from the
+ source tree. All of these depend on proprietary components.
+
+1.3.25 (September 5, 2016)
+==========================
+
+Special Issues:
+
+* None
+
+Security Fixes:
+
+* EscapeParenthesis(): I was notified by Gustavo Grieco of a heap
+ overflow in EscapeParenthesis() used in the text annotation code.
+ While not being able to reproduce the issue, the implementation of
+ this function is completely redone. This issue was assigned
+ CVE-2016-7447 after the release.
+
+* Utah RLE: Reject truncated/absurd files which caused huge memory
+ allocations and/or consumed huge CPU. Problem was reported by
+ Agostino Sarubbo based on testing with AFL. This issue was assigned
+ CVE-2016-7448 after the release.
+
+* SVG/MVG: Fix another case of CVE-2016-2317 (heap buffer overflow) in
+ the MVG rendering code (also impacts SVG). This issue (remaining
+ part) was assigned CVE-2016-7446 after the release.
+
+* TIFF: Fix heap buffer read overflow while copying sized TIFF
+ attributes. Problem was reported by Agostino Sarubbo based on
+ testing with AFL. This issue was assigned CVE-2016-7449 after the
+ release.
+
+Bug fixes:
+
+* GetToken(): Fix obscure bug (read beyond end of string buffer)
+ noticed while parsing a MVG file. This problem was reported by
+ Gustavo Grieco.
+
+* MVG rendering: Fix undesired hard errors when some objects were
+ drawn outside of the image bounds. Requests to draw objects
+ entirely outside of the image should be silently ignored.
+
+* MVG/SVG rendering: Fix gradient size sanity checks which were
+ causing gradient requests to fail. Due to a design weakness in that
+ gradient images allocate resources rather than being computations at
+ point of use, the maximum gradient image size is now hard-limited to
+ 5000x5000 pixels until the design problem is fixed. Some SVG icons
+ (as small as 8x8 pixels) authored using Inkscape request absurdly
+ huge gradients. Gradient sizes as large as 20,000x20,000 have been
+ observed in SVG icon files delivered by packages on an Ubuntu Linux
+ system.
+
+* SVG: Fix some memory leaks which occur on parsing error.
+
+New Features:
+
+* None
+
+Feature improvements:
+
+* ElapsedTime(): Use clock_gettime() (when available with default
+ linkage) to obtain elapsed time.
+
+* DescribeImage(): Provide 6 digits of seconds precision in in elapsed
+ time output. Previously the resolution was rounded up to a full
+ second.
+
+Windows Delegate Updates/Additions:
+
+* webp: Updated bundled libwebp to release 0.5.1.
+
+* libxml: Updated bundled libxml2 to release 2.9.4.
+
+* lcms: Updated bundled lcms2 to release 2.8.
+
+* png: Update bundled libpng to release 1.6.24.
+
+Build Changes:
+
+* OpenMP is properly configured for clang 3.8 using its own '-lomp'
+ rather than '-lgomp'.
+
+Behavior Changes:
+
+* SVG: Some SVG files may be rejected due to absurdly large gradient
+ requests.
+
+* The 'identify' and 'info' functionality only shows the pixel read
+ rate if image was not read in 'ping' mode. Provide 6 digits of
+ seconds precision in in elapsed time output.
+
+1.3.24 (May 30, 2016)
+==========================
+
+.. _`GCC bug 53967` : http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967
+
+Special Issues:
+
+* A shell exploit (CVE-2016-5118) was discovered associated with a
+ filename syntax where file names starting with '|' are intepreted as
+ shell commands executed via popen(). Insufficient sanitization in
+ the SVG and MVG renderers allows such filenames to be passed through
+ from potentially untrusted files. There might be other ways for
+ untrusted inputs to produce such filenames. Due to this issue,
+ support for the feature is removed entirely.
+
+* A shell exploit was discovered associated with the gnuplot delegate
+ and which is triggered by the 'gplt' entry in delegates.mgk. A
+ remote exploit is possible if the attacker can cause a provided SVG
+ or MVG file to be rendered (or the user opens a provided file). The
+ gnuplot program must be installed in order for the exploit to be
+ successful. It is strongly recommended to remove this entry in all
+ delegates.mgk files.
+
+* Due to `GCC bug 53967`_, several key agorithms (e.g. convolution)
+ may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+ enabled for floating point math (`-mfpmath=sse`) if the GCC option
+ `-frename-registers` is used. Default 32-bit builds do not
+ experience the problem since they use '387 math. It is not clear in
+ what version of GCC this problem started but it was not noticed by
+ the developers until the GCC 4.6 timeframe. Other compilers do not
+ suffer from this bug. Please lobby the GCC project to fix this
+ embarrassing performance bug.
+
+Security Fixes:
+
+* BLOB: Remove support for reading input from a shell command, or
+ writing output to a shell command, by prefixing the specified
+ filename (containing the command) with a '|'. This feature provided
+ a remote shell execution opportunity.
+
+* DIB: Fixed out of bounds reads. Added more header validations.
+
+* JNG: File size limits are enforced.
+
+* MAT: Fixed denial of service opportunity. Fix hang on corrupt deflate stream.
+
+* META: Fixed out of bounds reads and writes.
+
+* MIFF: Fixed thrown assertion.
+
+* MSL: Ignore the file extension on MSL files. It is necessary to add
+ a "msl:" prefix to MSL files to read the as an image.
+
+* MVG: No longer assume that files ending with extension ".mvg" are
+ MVG files. MVG parsing does more validity checking on its input.
+ Assure that enough PrimitiveInfo structures are allocated in advance
+ to support a given vector path (heap overflow problem).
+
+* PCX: Fixed unreasonable memory allocation due to intentionally
+ corrupt file.
+
+* PDB: Fixed a heap buffer overflow and out of bounds read.
+
+* PICT: Fixed an out of bounds write.
+
+* PS: Ghostscript is now always run with -dSAFER for safer execution.
+
+* PSD: Fixed segmentation violations, heap buffer overflows, and out
+ of bounds writes.
+
+* RLE: Fixed out of bounds reads and writes.
+
+* ReadImages(): Fixed a possible infinite recursion due to a crafted input file.
+
+* RotateImage(): Fixed thrown assertion.
+
+* SGI: Fixed out of bounds writes.
+
+* SUN: Fixed out of bounds reads and writes.
+
+* SVG: Fixed heap and stack buffer overflows, as well as segmentation
+ violations (CVE-2016-2317 and CVE-2016-2318). Also fixed endless
+ loop, unexpectedly large memory allocation, divide by zero, and
+ recursion issues.
+
+* TIFF: Fixed an assertion while reading. Fixed benign heap overflow.
+
+* TMP: Adding a "tmp:" prefix to a filename no longer removes the file
+ since this seems dangerous.
+
+* VIFF: Fix excessive memory allocation with intentionally corrupted input file.
+
+* XCF: Fixed a heap buffer overflow.
+
+* XPM: Fixed several heap buffer overflows, and out of bound
+ reads/writes. Also fixed a case of excessive memory allocation.
+
+* delegate.mgk: The default delegate.mgk file has been pared down in
+ order to reduce security exposure.
+
+* gnuplot ('gplt' delegate in delegates.mgk): Support for rendering
+ gnuplot files is removed since the format is inherently insecure.
+
+* File names: File names starting with a '|' character are no longer
+ interpreted as shell commands to be executed as input or output.
+
+
+Bug fixes:
+
+* BMP: Fix reading 24-bit Microsoft BMP which claims to have a
+ colormap.
+
+* FILE: `file://` URLs are properly supported now (they never worked
+ before).
+
+* JP2: It is now possible to write lossless JPEG 2000 "JP2" format.
+
+* SVG: Support font-size "medium".
+
+New Features:
+
+* Blob I/O C APIs: Added signed versions of short and long Read/Write
+ functions.
+
+* FILE: `file://` URLs are properly supported now (they never worked
+ before).
+
+* MAT: Matlab V4 is now partially supported.
+
+* Magick++: Added double-precision xResolution() and yResolution()
+ methods to support setting the horizontal and vertical resolution
+ with double floating point precision.
+
+* Mogrify now supports a -preserve-timestamp option to preserve file
+ access and modification timestamps.
+
+Feature improvements:
+
+Windows Delegate Updates/Additions:
+
+* Updated bundled libpng to release 1.6.19.
+
+* Updated bundled libwebp to release 0.4.4.
+
+* Update bundled libxml2 to release 2.9.3.
+
+* Update bundled freetype to release 2.6.2.
+
+Build Changes:
+
+* Added ``--enable-broken-coders`` configure option to enable file
+ format support which may be broken or cause security issues. The
+ PSD format is now classified as "broken" (until it is fixed).
+
+Behavior Changes:
+
+* PSD format is not included in the build by default.
+
+* Files ending with ".mvg" and ".msl" are not assumed to be image
+ files by default.
+
+* File names starting with '|' are no longer treated as shell
+ commands.
+
+* Gnuplot and POV delegate support is removed from the default
+ delegate.mgk file.
+
+1.3.23 (November 7, 2015)
+==========================
+
+Special Issues:
+
+* Due to `GCC bug 53967`_, several key agorithms (e.g. convolution)
+ may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+ enabled for floating point math (`-mfpmath=sse`) if the GCC option
+ `-frename-registers` is used. Default 32-bit builds do not
+ experience the problem since they use '387 math. It is not clear in
+ what version of GCC this problem started but it was not noticed by
+ the developers until the GCC 4.6 timeframe. Other compilers do not
+ suffer from this bug. Please lobby the GCC project to fix this
+ embarrassing performance bug.
+
+
+Security Fixes:
+
+* ScaleImage(): While not strictly a security issue, requesting to
+ scale an image while retaining the original number of rows will lead
+ to a program crash or memory corruption due to double-free.
+
+Bug fixes:
+
+* ScaleImage(): Fix problem with new width/height match original
+ (regression added by 1.3.22).
+
+* ScaleImage(): Fix double-free when new rows matches original rows
+ (regression added by 1.3.22).
+
+* MinGW build fix related to eliminating a sleep() macro which
+ conflicts with a MinGW-provided inline sleep() function.
+
+* PNG: Issue a warning instead of an error when attempting to read a
+ PNG file containing a zero-length profile. This allows the file to
+ be read.
+
+* identify: Fix problem in that `identify -format "%A"` (to test if
+ transparency is supported in image) does not always produce the
+ correct results.
+
+New Features:
+
+* None.
+
+Feature improvements:
+
+* None.
+
+Performance Improvements:
+
+* None.
+
+Windows Delegate Updates/Additions:
+
+* None.
+
+Build Changes:
+
+* Configure: Removed CFLAGS and LDFLAGS deduplication code which
+ caused problems for user-provided CFLAGS and LDFLAGS which added and
+ then removed compiler/linker options. Specifically, this fixes a
+ problem with creating OS X universal builds.
+
+* Configure: Add tests for 'ps2write' and 'eps2write' which are
+ available in recent Ghostscript.
+
+Behavior Changes:
+
+* None
+
+
+1.3.22 (October 4, 2015)
+==========================
+
+.. _`GCC bug 53967` : http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967
+
+
+Thanks:
+
+* Coverity: We thank Coverity for providing free service for free
+ software projects, and thank Jodie Cunningham for getting the
+ project set up in Coverity.
+
+Special Issues:
+
+* Due to `GCC bug 53967`_, several key agorithms (e.g. convolution)
+ may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+ enabled for floating point math (`-mfpmath=sse`) if the GCC option
+ `-frename-registers` is used. Default 32-bit builds do not
+ experience the problem since they use '387 math. It is not clear in
+ what version of GCC this problem started but it was not noticed by
+ the developers until the GCC 4.6 timeframe. Other compilers do not
+ suffer from this bug. Please lobby the GCC project to fix this
+ embarrassing performance bug.
+
+* Magick++: Any libraries or applications using Magick++ should be
+ rebuilt in order to use this new release. Libraries and
+ applications will be able to continue to use prior versions of
+ Magick++ without being re-built, while benefiting from updated C
+ libraries, provided that the system supports library versioning.
+
+Security Fixes:
+
+* General Coverity fixes. Some might have security consequences.
+
+* Ghostscript options concatenation is more secure against buffer
+ overflow.
+
+* Windows: Built-in random number generator is now salted using
+ CryptGenRandom(). This improves the robustness of the temporary
+ file allocator.
+
+Bug fixes:
+
+* Coverity Fixes: Large amounts of fixes due to Coverity static
+ analysis. See the ChangeLog and Mercurial for details. Coverity now
+ reports zero issues.
+
+* General: Fix problems with reading filenames that include a colon.
+
+* General: Fixed performance problem with sub-image path extraction
+ when there are many files in the directory.
+
+* General: Add missing options in utility help messages.
+
+* BMP: Reader was wrongly rejecting RLE-compressed files as being too
+ small (regression added in 1.3.21 release).
+
+* BMP: Fix inverted alpha channel when writing BGRA8888 format.
+
+* DrawAffineImage(): Fix problem with negative x offset.
+
+* DrawAffineImage(): Fix problem that sometimes output rows are skipped when using OpenMP.
+
+* EXIF: Properly validate GPS_OFFSET.
+
+* -format: %Q now reports JPEG quality estimate if it is available.
+
+* -geometry: Fix handling of area geometries in the form "5000000@".
+
+* MagickGetImageGravity(): Prototype was missing in header files.
+
+* MIFF: Memory leak fixes.
+
+* MIFF: MIFF reader failed to read some MIFF headers properly.
+
+* MIFF: Detect buffer overrun attempt while reading zip compressed data.
+
+* PDF: Set image frame scene ids appropriately.
+
+* PNG: Memory leak fixes.
+
+* PS: Set image frame scene ids appropriately.
+
+* PTIF: Mark reduced frames as SubfileType 0x2 instead of 0x1.
+
+* SetImageProfile(): Avoid crash given NULL profile pointer.
+
+* TIFF: Fix reading Old JPEG and YCbCr sample images from libtiff
+ pics-3.8.0.tar.gz image file collection.
+
+* TIFF: Disable matte channel for compression types which don't
+ support it.
+
+* XPM: Memory leak fixes.
+
+* XWD: Memory leak fixes.
+
+New Features:
+
+* GRAYA: New subformat for gray coder which supports alpha channel.
+ Format specifiers "R", "G", "B", "A", "C", "M", and "Y" may now be
+ used to save and restore the associated channel using the same raw
+ format as "GRAY".
+
+* Magick++: Image::repage() method added to support resetting 'page'.
+
+* PDF: Added '-define pdf:stop-on-error=true' optoin to cause PDF
+ reading to quit immediately upon any error.
+
+* Subframe specification: Now specific PS and PDF pages may be
+ selected, including re-ordering.
+
+Feature improvements:
+
+* PALM: Still a work in progress. Closer to working using netpbm's
+ implementation as a reference.
+
+Performance Improvements:
+
+* None.
+
+Windows Delegate Updates/Additions:
+
+* dcraw: Update bundled dcraw to release 9.26.0.
+
+* lcms: Update bundled lcms2 to release 2.7.
+
+* png: Updated bundled libpng to release 1.6.17.
+
+* tiff: Update bundled libtiff to release 4.0.6.
+
+* ttf: Update bundled freetype to release 2.6.
+
+* webp: Updated bundled libwebp to release 0.4.3.
+
+* libxml: Update bundled libxml2 to release 2.9.2.
+
+Build Changes:
+
+* lcms ("Little CMS") v1 is no longer supported.
+
+* VisualMagick: Remember and re-use already given paths.
+
+Behavior Changes:
+
+Magick++: adaptiveThreshold() now accepts a 'double' value and the
+previous version of the method (using 'unsigned int') is deprecated.
+The STL function-object equivalent of the deprecated method is removed
+entirely.
+
+
+1.3.21 (February 28, 2015)
+==========================
+
+.. _`AddressSanitizer` : https://code.google.com/p/address-sanitizer/
+
+.. _`Valgrind` : http://www.valgrind.org/
+
+.. _`American fuzzy lop` : http://lcamtuf.coredump.cx/afl/
+
+Thanks:
+
+ * Gynvael Coldwind and Mateusz Jurczyk of the Google Security Team
+ provided test files which allowed us to find and fix security
+ problems in the software.
+
+ * Hanno Bck provided test files which allowed us to find and fix
+ security problems in the software.
+
+ * Tobias Ospelt provided test files and advice which allowed us to
+ find and fix security problems in the software.
+
+ * Michal Zalewski provided test files which allowed us to find and
+ fix security problems in the software.
+
+ * Jodie Cunningham did lots of fuzzing to find issues and set up the
+ project on Coverity for automatic analysis.
+
+ * `American fuzzy lop`_ was used to produce and discover many of the
+ files which caused problems for the software.
+
+ * `AddressSanitizer`_ (ASan) was used to detect and isolate memory
+ access issues.
+
+ * `Valgrind`_ was used to detect and isolate memory access issues as
+ well as memory leaks
+
+Special Issues:
+
+ * Due to `GCC bug 53967`_, several key agorithms (e.g. convolution)
+ may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+ enabled for floating point math (`-mfpmath=sse`) if the GCC option
+ `-frename-registers` is used. Default 32-bit builds do not
+ experience the problem since they use '387 math. It is not clear
+ in what version of GCC this problem started but it was not noticed
+ by the developers until the GCC 4.6 timeframe. Other compilers do
+ not suffer from this bug. Please lobby the GCC project to fix
+ this embarrassing performance bug.
+
+ * Magick++: Any libraries or applications using Magick++ should be
+ rebuilt in order to use this new release. Libraries and
+ applications will be able to continue to use prior versions of
+ Magick++ without being re-built, while benefiting from updated C
+ libraries, provided that the system supports library versioning.
+
+Security Fixes:
+
+ * Annotate: Some requestable text-substitution attributes caused a
+ crash.
+
+ * All formats: Image dimensions are checked to assure that they are
+ within limits before proceeding to read the image.
+
+ * BMP: Fix hang (endless loop) for certain files.
+
+ * DCM: Fix crash as well as small heap over-write.
+
+ * DPX: Fix crash due to DPX file reporting more elements than it
+ has.
+
+ * MNG: Validate MHDR chunk length to avoid huge memory allocation
+ and DOS.
+
+ * PCX: Fix for CVE-2014-8355. Validate file header in order to avoid
+ buffer overun later.
+
+ * PDB: Detect arithmetic overflows when calculating buffer sizes.
+ Fix crash in writer when image width is not even multiple of 16.
+ Fix buffer overrun with 2 and 4-bit PDB image files.
+
+ * PNM: Validate PGM, PPM, and PAM header MaxValue parameter to avoid
+ crash on poorly-formed input.
+
+ * PNG: Impose a 10-million limit on dimensions when reading a PNG
+ file to avoid denial of service.
+
+ * PSD: Avoid problems caused by huge PSD colormap size.
+
+ * PSD: Fix small stack over-write if more than 99 layers are written
+ to PSD format.
+
+ * PSD: Returns immediately if pixel limit was exceeded.
+
+ * RLE: URT RLE reader is now more robust with errant files.
+
+ * SUN: Header validation is now made fully robust, and arithmetic
+ overflows in buffer-size calculations are detected to avoid heap
+ overwrite.
+
+ * TIFF: Fix crashes for photometrics which may deliver one or three
+ samples per pixel (was assuming always three).
+
+ * VIFF: Fixes to prevent buffer overflow. Validate colormap indexes.
+
+ * Windows delegates: Fix unexpected argument splitting when invoking
+ an external delegate program via delegates.mgk.
+
+ * WPG: Fix use of NULL pointers. Fix buffer overflows.
+
+ * XPM: Detect truncated row and quit with error rather than
+ over-running a buffer.
+
+ * XWD: Improve header validation. Added to UnstableCoderClass since
+ the reader for this format should not be entrusted with
+ untrustworthy input.
+
+Bug fixes:
+
+ * CIN: Fix problem with text attribute values which are not NULL
+ terminated. Validate sizes claimed by Cineon header.
+
+ * Coverity: Fixes for many issues detected by Coverity scan (see
+ ChangeLog).
+
+ * DPX: Fix problem with text attribute values which are not NULL
+ terminated.
+
+ * DPX: Fix severe corruption of little-endian 32-bit packed output.
+ Corruption was severe enough that it would have been noticed
+ immediately.
+
+ * Delegates: Fix possible memory leaks when invoking external
+ application.
+
+ * FITS: Properly validate values provided by file header.
+
+ * GIF: Fix use of uninitialized data.
+
+ * JBIG: Fix memory leaks.
+
+ * JNG: Fix double-free error in error path.
+
+ * JPEG: Verify the number of output components before attempting to
+ decode the image.
+
+ * Magick++: Image resolutionUnits() was not always returning correct
+ value.
+
+ * Magick++: Locking has not been working properly since the code was
+ written in 1998. Apparently the issue has not been significant
+ enough to cause run-time issues.
+
+ * ICO: Windows icon reader is now much more robust.
+
+ * MIFF: Reader now quits with an error if zip or bzip2 stream is
+ corrupted.
+
+ * MAT: Fix memory leaks.
+
+ * PALM: Reader now reads various input formats (up to version 2)
+ correctly whereas it was crashing or otherwise malfunctioning
+ before. More work remains, particularly in the writer.
+
+ * PCX: Eliminate memory leaks in error paths.
+
+ * PDB: In PDB writer, void possible under-allocation due to
+ arthimetic overflow when allocating packets.
+
+ * PICT: Fix PICT reader crash with corrupted file.
+
+ * PNG: Fix double-free error in error path.
+
+ * PNG: Fixed handling of transparency when writing indexed PNG.
+
+ * PNG: Avoid reading beyond the end of a tEXt keyword.
+
+ * PSD: Fix error when reading PSDs files which have no layers.
+
+ * RLA: Fix possible crash due to file header.
+
+ * Signal Handling: Signal handling is now more robust and handles
+ SIGSEGV and other critical signals. The sole purpose of the
+ default signal handling is to remove any temporary files and quit.
+ An informative message is printed for signals other than SIGINT.
+
+ * SUN: Sun raster reader was not completely robust. Now it is.
+
+ * SWF: Fix pixel cache access errors in 'ping' mode.
+
+ * Text annotation: An empty text string is no longer treated as an
+ error.
+
+ * Text annotation: Fix regression added in 1.3.19 which caused
+ spurious drawing errors to be produced while rendering with text
+ when all of the text is off the left-hand side of the image.
+
+ * TIFF: Fix unreliable reading JBIG compressed files by forcing use
+ of strip reader rather than sometimes using scanline reader (which
+ libtiff's JBIG codec does not support).
+
+ * TIFF: Fix reading or writing planar min-is-white or min-is-black
+ images with an associated alpha channel.
+
+ * WebP: WebP writer now writes truely lossless output when
+ requested.
+
+ * identify / GetImageStatistics(): Failed to compute statistics for
+ the Black channel of CMYK image files.
+
+ * VICAR: Fix problem with continuing to "read" data when there is no
+ more data left to read.
+
+ * WMF: Fix memory leaks.
+
+ * WPG: Fix potential DOS due to long reads during an error
+ condition.
+
+ * XPM: Avoid strncpy() of overlapping memory. Fixed memory leaks in
+ error paths. Fixed bad memory access caused by empty file.
+
+New Features:
+
+ * compose: Supports composite operator names similar to the major
+ \*Magick brand, without losing any compatibility with previous
+ naming.
+
+ * ICO: Windows ICO reader now supports reading PNG-encoded files.
+
+ * Magick++ Geometry: New methods limitPixels() and fillArea() to
+ support '@' and '^' geometry qualifiers. This enhancement breaks
+ the ABI due to previous use of inline methods and no place to put
+ the new flags.
+
+ * Magick++ Image::extent(): New method to place image on sized
+ canvas of constant color using gravity.
+
+ * Magick++ Image::formatExpression(): New method format a string
+ based on a format similar to command-line -format.
+
+ * Magick++ Image::resize(): New method to resize image specifying
+ geometry, filter, and blur.
+
+ * Magick++ STL extentImage: New function object to invoke image
+ extent method.
+
+ * Magick++ Image::quiet(). New method which blocks (ignores)
+ warning exceptions when passed a 'true' argument.
+
+ * Resource limits: Added support for image Width and Height limits.
+ Default image Width and Height limits are based on the range of a
+ 32-bit signed integer, even for 64-bit builds which may have
+ sufficient numeric range to image an entire galaxy. Limits may be
+ increased as desired.
+
+ * TIFF: Use define tiff:ignore-tags to ignore tags in 'corrupted'
+ files with unknown and invalid tags. Use to read TIFF files which
+ otherwise can not be read due to errors.
+
+ * TIFF: Use '-define tiff:report-warnings=true' to enable that
+ warnings reported by libtiff are thrown as warning exceptions so
+ that they may be caught or will be reported at the gm
+ command-line.
+
+ * Windows Exceptions: A handler is registered (due to calling
+ InitializeMagick()) to capture Windows Exceptions in a similar
+ manner to the existing POSIX signal handler. If an application is
+ using the library and wants to provide its own Windows exception
+ handling, then it should make any changes after invoking
+ InitializeMagick().
+
+Feature improvements:
+
+ * None.
+
+Performance Improvements:
+
+ * None.
+
+Windows Delegate Updates/Additions:
+
+ * PNG: Update bundled libpng to 1.6.16. Resolves known security
+ issues.
+
+ * FreeType: Update bundled Freetype to 2.5.4. Resolves known
+ security issues.
+
+ * WebP: Update bundled WebP to 0.4.2 release.
+
+ * WebP is auto-linked in Visual Studio.
+
+Build Changes:
+
+ * WebP is not included in the build when building with Visual Studio
+ 6 (1998 vintage compiler!) since it requires more modern C.
+
+Behavior Changes:
+
+ * AVI: Support for this format is removed since the implementation
+ was worthless.
+
+ * TIFF: Now uses YCbCr encoding when JPEG compression is requested
+ for an RGB image.
+
+
+1.3.20 (August 16, 2014)
+=========================
+
+Special Issues:
+
+ * Due to `GCC bug 53967`_, several key agorithms (e.g. convolution)
+ may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+ enabled for floating point math (`-mfpmath=sse`) if the GCC option
+ `-frename-registers` is used. Default 32-bit builds do not
+ experience the problem since they use '387 math. It is not clear
+ in what version of GCC this problem started but it was not noticed
+ by the developers until the GCC 4.6 timeframe. Other compilers do
+ not suffer from this bug. Please lobby the GCC project to fix
+ this embarrassing performance bug.
+
+Security Fixes:
+
+ * No security issues were reported or fixed.
+
+Bug fixes:
+
+ * Compilation: No longer undefine __attribute__ since this may be
+ used by system or compiler headers and cause problems.
+
+ * BMP: Alpha channel from BMP3 format was inverted.
+
+ * PNG: Fix round-trip repeatability issue (due to rounding
+ algorithm) with modern versions of libpng. Prefer the less
+ accurate method which does not alter the image.
+
+ * PNG: Fix some memory leaks in error-handling paths.
+
+ * PNM: Scaling of alpha in sub-ranged pixels is fixed.
+
+ * Wand API: Removed development debug fprintf which causes each
+ drawing primitive to be printed to stderr.
+
+ * PS, PS2, PS3, PDF: Only use resolution from image or -density if
+ units were properly specified. Without units, resolution is
+ worthless.
+
+ * PS, PS2, PS3, PDF: Use resolution from image if it appears to be
+ valid.
+
+ * WebP: Fix inverted return status which caused failure to be
+ reported instead of success.
+
+ * Rotation clipping/shearing errors for short wide images at some
+ angles are fixed.
+
+ * -geometry: Deal with resize geometry missing width or height
+ (e.g. '640x' or 'x480') by substituting the missing value with one
+ which preserves the image aspect ratio. This has been documented
+ to be supported since almost the dawn of GraphicsMagick but was
+ not actually supported until now.
+
+ * -geometry: Support '>' and '<' qualifiers with '@' qualifier to
+ specify if image should be resized if larger or lesser than given
+ area specification.
+
+New Features:
+
+ * Wand API: MagickSetImageGravity() - New function to set image
+ gravity.
+
+ * Wand API: MagickGetImageGravity() - New function to get image
+ gravity.
+
+ * Wand API: MagickSetImageMatte() - New function to set the image
+ matte channel enable flag.
+
+ * Wand API: MagickGetImageMatte() - New function to read the image
+ matte channel enable flag.
+
+ * Wand API: MagickSetImageGeometry() - New function to set the image
+ geometry string.
+
+ * Wand API: MagickGetImageGeometry() - New function to get the image
+ geometry string.
+
+ * Wand API: MagickOperatorImageChannel() - New function to apply an
+ operator to an image channel.
+
+ * Magick++ API: New Image::thumbnail() method for fast image
+ resizing, particularly to make thumbnails.
+
+ * Core C API: Added SetLogMethod() to allow an application/library
+ to specify a function to be called for logging.
+
+ * Clang/LLVM: Provide support for clang/llvm attribute and builtin
+ specifiers similar to that provided for GCC.
+
+ * OpenMP: OpenMP native locking and thread specific data is
+ supported via a configuration option (is not the default). This
+ offers a "pure" OpenMP compilation mode. No real value for this
+ compilation mode has been observed yet but it seems worthy to
+ support.
+
+ * Coders: Added BrokenCoderClass to mark coders which often
+ malfunction or are not very useful in their current condition.
+
+ * Composition: Added HardLight composition operator, which is now
+ used by PSD and XCF formats, and available via command line,
+ Magick++ API, PerlMagick API, and Wand API.
+
+ * Composition: Added ScreenCompositePixels composition operator.
+
+ * Composition: Added missing Photoshop separable compositing
+ operations, Overlay, Exclusion, ColorBurn, ColorDodge, SoftLight,
+ LinearBurn, LinearDodge, LinearLight, VividLight, PinLight,
+ HardMix.
+
+ * +set: Command line utilities now support +set to remove an
+ existing image attribute.
+
+ * -format: Support additional format specifiers 'g', 'A', 'C', 'D',
+ 'G', 'H', 'M', 'O', 'P', 'Q', 'T', 'U', 'W', 'X', and '@', similar
+ to the major brand.
+
+ * -operator: New quantum operators ThresholdBlackNegateQuantumOp and
+ ThresholdWhiteNegateQuantumOp. These correspond to -operator
+ "Threshold-Black-Negate" and "Threshold-White-Negate".
+
+ * TIFF: Now support setting the TIFF "Software" tag for users who do
+ not want to admit to using GraphicsMagick.
+
+ * WebP: All of the WebP encoder encoder options are now supported
+ by -define arguments.
+
+
+Feature improvements:
+
+ * Pixel interpolation quality is greatly improved, with minimal
+ impact on performance. Pixel interpolation now also works well
+ given an alpha channel.
+
+ * WebP: WebP support is now prepared to compile with most WebP
+ library versions and supports all features except for those
+ pertaining to "RIFF" container support.
+
+Performance Improvements:
+
+ * Non-integral image rotation performance has been improved by about
+ 40%, with lower memory usage as well.
+
+ * GradientImage: Update image is_grayscale and is_monochrome flags
+ based on gradient color properties.
+
+Windows Delegate Updates/Additions:
+
+ * PNG: Libpng 1.6.12 - June 12, 2014.
+
+ * JPEG: libjpeg 9a of January 19, 2014.
+
+ * FreeType: FreeType 2.5.3 of March 6, 2014.
+
+ * WebP: webp 0.4.0 of January 20, 2013.
+
+ * zlib: zlib 1.2.8 of April 28, 2013.
+
+Build Changes:
+
+ * --without-threads no longer disables use of OpenMP. Use the
+ already existing option --disable-openmp to disable OpenMP.
+
+ * Makefiles: Include paths are now exceedingly pedantic to make sure
+ that only the required directories are included.
+
+ * VisualMagick configure: Improve configure program so that it is
+ possible to select QuantumDepth, OpenMP, and 64-bit build via
+ configure dialog boxes as well as options on the command line.
+ Also automatically detects and deals with similarly named files in
+ subdirectories so that WebP support can now build successfully.
+
+Behavior Changes:
+
+ * MultiplyCompositePixels: Multiply composition now uses SVG
+ interpretation of how alpha should be handled. No longer does a
+ simple multiply of alpha channel.
+
+ * Composition: The Difference, Darken, Lighten, and HardLight
+ composition operators were modified to support alpha in their
+ computations.
+
+ * PNG: Using -optimize no longer triggers palette and depth
+ optimizations since their implementations have been problematic.
+
+
+1.3.19 (December 31, 2013)
+==========================
+
+Special Issues:
+
+ * Due to `GCC bug 53967`_, several key agorithms (e.g. convolution)
+ may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+ enabled for floating point math (`-mfpmath=sse`) if the GCC option
+ `-frename-registers` is used. Default 32-bit builds do not
+ experience the problem since they use '387 math. It is not clear
+ in what version of GCC this problem started but it was not noticed
+ by the developers until the GCC 4.6 timeframe. Other compilers do
+ not suffer from this bug.
+
+Security Fixes:
+
+ * EPT: Fix crash observed when Ghostscript fails to produce useful
+ output. This was particularly noticeable when Ghostscript was not
+ installed. This crash could be used to cause denial of service.
+
+ * PNG: With libpng 1.6.X, avoid a crash while copying a PNG with a
+ "known incorrect ICC profile". This crash could be used to cause
+ denial of service.
+
+Bug fixes:
+
+ * Build: Fix cross-compilation for MinGW64 on Linux build machine.
+
+ * Build: configure FreeType test no longer insists that
+ <freetype/freetype.h> can be included.
+
+ * CMS profile: Only delete the CMS transform if it is non-null.
+ Fixed assertion observed when lcms returned a null profile and
+ GraphicsMagick attempted to deallocate it.
+
+ * Drawing: Improve error handling logic so that drawing returns
+ quickly on pixel access errors rather than plowing on ahead. This
+ avoids problems with SVGs which take seemingly forever to render.
+
+ * Drawing via C/C++ APIs: `BevelJoin` no longer causes a MVG parsing
+ error.
+
+ * EPT: Fix crash observed when Ghostscript fails to produce useful
+ output. This was particularly noticeable when Ghostscript was not
+ installed.
+
+ * OpenMP: Revert use of omp_set_dynamic() since it caused
+ performance issues when using GCC's GOMP implementation and the
+ number of threads to use is specified.
+
+ * EXIF profile: Support the `SubjectArea` EXIF tag.
+
+ * MIFF writer: PseudoClass format was written incorrectly for depth
+ greater than 8.
+
+ * MIFF writer: RLE compressed format used inverted alpha from the
+ other subformats contrary to the MIFF specification.
+
+ * MIFF reader: Fixes to be able to read MIFF written by
+ ImageMagick 6.X, including DirectClass grayscale images (except
+ for RLE compressed).
+
+ * Mosaic: Fixed unsigned underflow problem with -mosaic when page
+ offset is negative and exceeds image width or height, resulting in
+ assertions, out of memory errors, or pixel cache limit errors.
+
+ * PDF: Consistently initialize Image page width and height to image
+ width and height. While general to all of GraphicsMagick, this
+ change is to assure that the PDF writer computes page dimensioning
+ consistently. PDF page dimensioning was wrong if the image had
+ been resized with -geometry "100%".
+
+ * PAM: Fix MAXVAL scaling when reading PAM images. PAM was only
+ working correctly for images with 256 or 64k levels.
+
+ * PNM: PGM "P2" format writer wrote bad output for 8-bit depth.
+
+ * PNG: With libpng 1.6.X, avoid a crash while copying a PNG with a
+ "known incorrect ICC profile".
+
+ * PNG: Q8 GM build now correctly reads 16-bit PNG files.
+
+ * TIFF writer: Try to avoid writing more than 32k strips per image
+ by increasing rows-per-strip since some programs fail to read
+ images with more than 32k strips per image.
+
+ * TIM reader: PSX TIM reports 8-bit depth (rather than 16).
+
+ * TTF font rendering: Improve FreeType rendering error logic so that
+ rendering returns immediately on pixel access errors rather than
+ plowing on ahead.
+
+ * TTF font rendering: Support rendering UTF-8 up to 21-bit code
+ points. Was only supporting 16-bit code points.
+
+ * Wand API: DrawSetStrokeDashArray() / DrawGetStrokeDashArray(), fix
+ failure to work properly due to this code path never being tested.
+
+ * Windows Ghostscript: 64-bit GraphicsMagick no longer requires both
+ 32-bit and 64-bit builds of Ghostscript to be installed in order
+ to read Postscript and PDF formats.
+
+ * XPM reader: Reported depth now depends on the colormap rather than
+ always claiming to be 16-bit.
+
+New Features:
+
+ * JPEG: Add support for writing 'XMP' profile.
+
+ * PNM: As a simple non-standard extension to the standard PNM and
+ PAM formats, support writing and reading 32-bit sample depth.
+ Writing such files is only supported by the Q32 build although
+ they may be read by any build.
+
+ * WebP: Now supports reading and writing Google's WebP format. This
+ feature is not currently supported by the Windows Visual Studio
+ build.
+
+Feature improvements:
+
+ * Pixel composition based on BlendCompositePixel() is enhanced to
+ completely eliminate under-color from the blending if the
+ under-pixel is fully transparent. Also blends based on the
+ average opacity of both pixels rather than only the over-pixel.
+ This change did not result in any change in the GM test suite
+ results but it is possible that there could be some negative
+ impact from it. Please report any issues noticed which are due to
+ this change.
+
+ * X11 `display`: For DirectClass image, use ThumbnailImage() rather
+ than SampleImage() when creating the panner icon to improve the
+ quality of the image.
+
+Performance Improvements:
+
+ * PNG: `ping` a PNG faster by avoiding reading the image data.
+
+Windows Delegate Updates:
+
+ * Updated IJG JPEG library to release 9.
+
+ * Updated PNG library to release 1.6.8.
+
+ * Updated lcms2 library to release 2.5.
+
+ * Updated libxml2 library to release 2.9.1.
+
+ * Updated FreeType library to release 2.5.2.
+
+Behavior Changes:
+
+ * MIFF: Now writes PseudoClass images correctly when depth is
+ greater than 8. This impacts the reader, which will not be able
+ to read previously written incorrect format correctly. Images
+ like this should be very rare. The solution is to use an older
+ GraphicsMagick version to convert such images to a valid storage
+ format (with a depth of 8) so that they may be read with this
+ version.
+
+ * MIFF: Now writes RLE-compressed RGBA images with correct
+ alpha. This impacts the reader, which will not be able to read
+ previously written incorrect format correctly. Images like this
+ should be very rare. A solution is to use an older GraphicsMagick
+ version to use a compression algorithm other than RLE so that they
+ are read correctly with this version. Another solution is to
+ process problematic images with '-operator Opacity Negate 0' to
+ invert the alpha channel.
+
+ * TIFF: Returns DirectClass images by default for MINISWHITE and
+ MINISBLACK TIFF formats (rather then colormapped).
+
+ * Windows: Also search c:\gs\fonts for Ghostscript font files. This
+ search path is normally hard-coded into Ghostscript binaries and
+ is a convenient place to put fonts so they may be shared by
+ multiple Ghostscript versions.
+
+ * XPM: Now limits color resolution to 16-bits, even with Q32 build.
+
+
+1.3.18 (March 10, 2013)
+==========================
+
+Special Issues:
+
+ * Due to `GCC bug 53967`_, several key agorithms (e.g. convolution)
+ may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+ enabled for floating point math (`-mfpmath=sse`) if the GCC option
+ `-frename-registers` is used. Default 32-bit builds do not
+ experience the problem since they use '387 math. It is not clear
+ in what version of GCC this problem started but it was not noticed
+ by the developers until the GCC 4.6 timeframe. Other compilers do
+ not suffer from this bug.
+
+Security Fixes:
+
+ * None.
+
+Bug fixes:
+
+ * Fixed bug with format substitutions if input string ends with a
+ single '%'.
+
+ * BMP: Fixed an old bug with decoding chromaticity primaries.
+
+ * PNG: Fixed reading of interlaced images. Fix reading of sub-8-bit
+ palette and grayscale images. Some PNG sub-formats were written
+ incorrectly. Fix crash in PNG8 writer if image colors happened to
+ be non-zero but image was not actually colormapped.
+
+ * PNG: Configure script now also searches for libpng versions 16 and
+ 17.
+
+ * TIFF: Fix a crash which was noticed when writing RGBA separated
+ (planar) format.
+
+ * `--enable-symbol-prefix` was not prefixing all of the C
+ symbols. Some core C library functions were not prefixed. This
+ option applies to the Wand library API as well now.
+
+ * C API: When input is from a user-provided file descriptor, the
+ file position is restored after reading the file header bytes.
+ Previously the file position was rewound to the beginning of the
+ file. This allows reading embedded image data from the current
+ offset in a file, and allows continuing to use the stream after
+ GraphicsMagick has returned the image.
+
+ * C API: It is now possible to invoke CloseBlob() multiple times.
+
+ * display: Display was supposed to respond to +/-usePixmap, but was
+ not. It was responding to +/-use_pixmap. Now it responds to both.
+
+ * Windows/VisualMagick: Fix building GraphicsMagick with Intel ICC
+ compiler driven by Visual Studio Professional 2012.
+
+ * Windows: Avoid a crash and produce a useful diagnostic if
+ Ghostscript is needed but not yet installed.
+
+
+New Features:
+
+ * GM utility: New 'batch' command was contributed by Kenneth Xu
+ which supports executing any number of other GM utility
+ sub-commands in a single invocation in a sort of "batch" script.
+ Input may be piped from standard input, from a specified file, or
+ from a 'GM >' command prompt. This utilities front-end allows any
+ other program/script to drive 'gm' using a co-process model and
+ speeds up execution by eliminating utility start-up/shut-down
+ time.
+
+ * WIN64 (64-bit Windows): Windows 64-bit is now officially supported.
+
+ * convert/mogrify: Now support -auto-orient to automatically rotate
+ the image upright for viewing based on its current orientation
+ setting. Also support -orient to support setting the current
+ image orientation. Please note that the orientation property of
+ EXIF profiles is not yet updated so the EXIF profile will be wrong
+ after using -auto-orient.
+
+ * C API: AutoOrientImage(), new function to automatically orient
+ the image so that it is upright for normal viewing.
+
+ * Wand API: MagickGetImagePage()/MagickSetImagePage(), new functions
+ to support getting and setting the image page size and offsets.
+
+ * PNG: Added PNG48 and PNG64 support. Added PNG00 support (png
+ encoder that inherits its color-type and bit-depth from the input,
+ if the input was a PNG datastream).
+
+Feature improvements:
+
+ * GraphicsMagick TAP tests may now be run stand-alone using Perl's
+ 'prove' TAP test driver.
+
+Performance Improvements:
+
+ * Detection of glob specifications in file names is more efficient.
+
+Windows Delegate Updates:
+
+ * None.
+
+Behavior Changes:
+
+ * ltdl: Libltdl is no longer bundled. Libltdl must be previously
+ installed on the system in order to build the modules
+ configuration.
+
+ * AppendImages() now converts subsequent images to the colorspace of
+ the first image, and no longer converts the first image to RGB.
+ Instead, it is assumed the user knows what she/he is doing.
+
+ * SetImageColorRegion() no longer automatically converts the image
+ to RGB. The user is responsible for assuring that the provided
+ color is in the same colorspace as the image.
+
+
+1.3.17 (October 13, 2012)
+==========================
+
+Security Fixes:
+
+ * PNG: Fix for CVE-2012-3438. The Magick_png_malloc function in
+ coders/png.c in GraphicsMagick 6.7.8-6 does not use the proper
+ variable type for the allocation size, which might allow remote
+ attackers to cause a denial of service (crash) via a crafted PNG
+ file that triggers incorrect memory allocation.
+
+ * Automake (derived): Fix for CVE-2012-3386: The "make distcheck"
+ rule in GNU Automake before 1.11.6 and 1.12.x before 1.12.2 grants
+ world-writable permissions to the extraction directory, which
+ introduces a race condition that allows local users to execute
+ arbitrary code via unspecified vectors.
+
+Bug fixes:
+
+ * PNG: Reading sub-8-bit palette images is fixed (images looked
+ stretched).
+
+ * SVG: Fixed bug which allowed MVG and SVG files with long vector
+ paths to crash the software.
+
+ * SVG: Ignore XML headers rather than rendering them as text.
+
+ * MVG/SVG/WMF/-draw: It is now possible to draw a plain ','
+ character.
+
+ * WMF: Fixed a bug which caused wrong centered-text placement.
+
+ * import: Return status was inverted.
+
+ * configure: Don't force that liblzma is used just because libtiff
+ is used.
+
+New Features:
+
+ * The configure script now supports a --enable-quantum-library-names
+ option to enable that shared library name includes quantum depth
+ to allow shared libraries with different quantum depths to
+ co-exist in same directory (only one can be used for development).
+
+ * JNX: Support is added for reading the Garmin proprietary Image
+ Format.
+
+ * BMP: Support an alpha channel in uncompressed 32-bit BMP.
+
+Feature improvements:
+
+ * `-lat`: The adaptive threshold algorithm is replaced with a new
+ algorithm which scales linearly (rather than quadratically) with
+ area size.
+
+ * Tests: Test suite is re-written to use TAP-based tests.
+
+ * GIF: Reader tries to be better at detecting and reporting
+ failures.
+
+Performance Improvements:
+
+ * -lat: Adaptive threshold is much faster with large area sizes.
+
+Windows Delegate Updates:
+
+ * Dcraw 9.16 is now included in the build (with JPEG and JPEG2000
+ support).
+
+ * Libxml2 is updated to the 2.9.0 release.
+
+ * Libtiff is updated to the 4.0.3 release.
+
+ * Lcms2 is updated to the 2.4 release.
+
+ * Libpng is updated to the 1.5.13 release.
+
+Behavior Changes:
+
+ * Loading modules is only supported for the modules build.
+ Previously any build using shared libraries could load modules.
+
+ * Bundled libltdl is now configured as 'installable' rather than
+ 'convenience'.
+
+ * -enhance: Only filter based on color channels (ignore opacity).
+
+ * BrowseDelegate: Web browser (for viewing help information) now
+ defaults to 'xdg-open', but if it is not found, then configure
+ will search for firefox, google-chrome, mozilla (in that order).
+
+1.3.16 (June 24, 2012)
+==========================
+
+Security Fixes:
+
+ * Don't translate 'comment' and 'label' attributes if the request is
+ made while a file is being read. Only translate such attributes
+ if they come from the command line or API user.
+
+Bug fixes:
+
+ * SWT: SWT reader suffered from a number of implementation errors
+ which caused it not to work any more. Works again.
+
+ * XBM: Fix memory leak observed when reading file in 'ping' mode.
+
+ * Support -trim on images which use a consistent (single color)
+ transparent background. In this case, trim is done based on
+ opacity rather than foreground color.
+
+ * Include <sys/types.h> in order to assure that 'size_t' and
+ 'ssize_t' are declared. This is necessary since
+ MagickExtentImage() uses these types as part of its definition.
+
+ * `+repage` was not working because parser was insisting that it
+ should include an argument.
+
+ * -units was scaling existing resolution the wrong way around
+ (i.e. multiplying rather than dividing).
+
+ * PerlMagick: Fix compilation with Perl 5.16.
+
+ * PingBlob(): PingBlob was not working for all cases. Is now based
+ on BlobToImage() for assured reliability.
+
+New Features:
+
+ None
+
+Feature improvements:
+
+ * MAT: Animated movies inside 4D matrices are loaded now.
+
+ * PDF: File base name is used as the document title.
+
+ * PNG: Fix issues observed specifically with libpng 1.5.10.
+
+Performance Improvements:
+
+ * Pixel iterators should be more efficient now if the image uses a
+ file-backed cache.
+
+ * Motion blur algorithm does scale well as cores are added so
+ include OpenMP support for it by default.
+
+Windows Delegate Updates:
+
+ * JPEG: Updated to IJG 8d release.
+
+ * PNG: Updated to 1.5.11 release
+
+ * TIFF: Updated to 4.0.2 release.
+
+ * Zlib: Updated to 1.2.7 release.
+
+ * libxml2: Updated to 2.8.0 release.
+
+Behavior Changes:
+
+ None
+
+1.3.15 (April 28, 2012)
+==========================
+
+Security Fixes:
+
+ * Libpng in Windows build is updated to 1.5.10 release. Provides a
+ fix for CVE-2011-3048.
+
+Bug fixes:
+
+ * PNG - fixed problem with bit depth when the encoder decides to
+ write RGBA instead of indexed PNG.
+
+ * Fixed some temporary file leaks which were caused by the temporary
+ file name being automatically extended to include a scene number,
+ and therefore fail to be deleted.
+
+New Features:
+
+ * Added '+noise random' and '-operator noise-random' to 'convert'
+ and 'mogrify'. This modulates the existing image data with
+ uniformly random noise.
+
+ * Added -strip option in composite, convert, mogrify, and montage to
+ remove all profiles and text attributes from the image.
+
+ * Added -repage option to composite, convert, mogrify, and montage
+ subcommands to reset or adjust the current image page offsets
+ based on a provided geometry specification.
+
+ * New C function StripImage() to remove all profiles and text
+ attributes from the image.
+
+ * New C function ResetImagePage() to adjust the current image page
+ canvas and position based on a relative page specification.
+
+ * C functions GenerateDifferentialNoise(), AddNoiseImageChannel(),
+ QuantumOperatorRegionImage(), AddNoiseImage() updated to support
+ RandomNoise enumeration.
+
+ * New C++ Image method strip(), and unary function stripImage() to
+ remove all profiles and text attributes from the image.
+
+ * XCF format now respects image subimage and subrange members so
+ that returned image layers may be selected.
+
+ * The INFO coder (e.g. output file "info:-") now respects the
+ -format option so that its output may be adjusted identically to
+ how -format works for 'identify'.
+
+ * TclMagick now supports Random noise.
+
+Feature improvements:
+
+ * C function ThumbnailImage() now allows the user to override the
+ filter used, but still defaults to using the box filter.
+
+Performance Improvements:
+
+ * None
+
+Behavior Changes:
+
+ * No longer add a printf-style scene formatting specification to
+ filenames which do not have one and no longer automatically
+ operate in 'adjoin' mode in such cases. If multiple numbered
+ files are intended to be output, then add +adjoin to the command
+ line and use an output filename specification similar to
+ "image-%d.jpg". Output files are now completely specified and
+ predictable but this may break some existing usages which
+ anticipate the automatic file numbering.
+
+1.3.14 (February 25, 2012)
+==========================
+
+Security Fixes:
+
+ * Windows bundled libpng updated to the 1.5.9 release, which fixes
+ the dire CVE-2011-3026 buffer overrun bug.
+
+Bug fixes:
+
+ * EMF format : Fixed wrong module mapping which caused EMF reading
+ to not work under Windows.
+
+ * TGA format: Assume that 32-bit TGA files have an alpha channel,
+ even if they are not marked as such.
+
+ * XCF format: Fix reading XCF which is comprised of different sized
+ layers.
+
+ * JPEG & CineonLog: Convert RGB-compatible colorspaces
+ (e.g. CineonLog) to RGB by default since that was the case prior
+ to release 1.3.13.
+
+ * RAW formats: Small memory leak in dcraw module was fixed.
+
+ * Resize: ResizeImage() was ignoring its resize filter argument and
+ was using the filter setting from the Image structure instead.
+
+ * The mirror virtual pixel method was broken.
+
+New Features:
+
+ * Open64 Compiler Suite: Version 5.0 is fully supported.
+
+ * Wand API: Added MagickExtentImage().
+
+ * MEF RAW: Mamiya Photo RAW "MEF" format is now supported.
+
+Feature improvements:
+
+ * DPX format: Original file endianness is preserved by default.
+
+ * PNG library: Updated libpng to 1.5.9 release.
+
+ * TIFF library: Updated libtiff to 4.0.1 release.
+
+ * Zlib library: Updated to zlib 1.2.6 release.
+
+Performance Improvements:
+
+ * Despeckle algorithm (-despeckle) is many times faster.
+
+Behavior Changes:
+
+ * DPX format: Original file endianness is preserved by default.
+
+1.3.13 (December 24, 2011)
+==========================
+
+Security Fixes:
+
+ None
+
+Bug fixes:
+
+ * In I/O blob, don't rewind already open file handle passed to
+ OpenBlob() since we don't know the intended state of this file
+ handle, and because it prevents appending to an existing file.
+
+ * In AppendImageProfile(), don't leak profile buffer while appending
+ a chunk to an existing profile.
+
+ * Fix deadlock in ClonePixelCache() which was caused by using the
+ same semaphore pointer in the source and destination images.
+
+ * Removed bogus SyncBlob() code which sometimes caused a crash and
+ was not useful.
+
+ * Fixed crash or hang which occured when the user entered CONTROL-C
+ while threaded code was being executed.
+
+ * Fix core dump in AcquireOneCacheViewPixelInlined() when the image
+ is in CMYK space.
+
+ * In MontageImages (montage), fix crash observed with "-geometry
+ x+0+0".
+
+ * The TIFF reader was crashing for images which use the
+ TIFFTAG_OPIIMAGEID tag.
+
+ * AppendImages() (-append) was failing when only one image was
+ provided.
+
+ * The `animate`, `display`, and `identify` commands now report any
+ error only once, and then proceed to the next file name rather
+ than quitting.
+
+ * Don't change the locale settings in InitializeMagick() since this
+ may cause problems for international users. API users are still
+ responsible for assuring that locale settings don't break floating
+ point parsing and output (i.e. floating point decimal needs to be
+ '.' rather than ',').
+
+ * RPM build is fixed (PerlMagick build was broken).
+
+ * RPM build installs documentation to expected places on Red Hat
+ type systems.
+
+ * Fixes for usage with OpenSolaris.
+
+ * DESTDIR is supported by PerlMagick build.
+
+ * The matte channel was not being properly enabled or respected for
+ TXT images.
+
+ * InitializeMagick() and DestroyMagick() are now fully thread safe.
+
+ * When a shear angle was zero, the shear request was being
+ ignored entirely.
+
+ * In DispatchImage(), the `K` channel was always output as black for
+ "CMYK" specification unless the image matte flag was True.
+
+ * MATLAB fixes.
+
+ * PNG fixes.
+
+ * PCL fixes for printing bi-level image on Konica-Minolta printers.
+
+ * EPT error handling fixes.
+
+ * JPEG reader was sometimes truncating large IPTC profiles.
+
+ * JPEG writer now handles errors properly rather than allowing
+ libjpeg to exit the program (or hanging if driven by Magick++).
+
+ * JPEG reader now treats an unhandled EXP marker as a warning rather
+ than a hard error.
+
+ * File open errors are now reliably reported.
+
+ * Improved rendering precision when using the drawing APIs.
+
+ * For the Magick++ Image backgroundColor(), borderColor(), and
+ matteColor() methods, preserve the opacity part of the
+ user-specified color.
+
+New Features:
+
+ * Add support for drawing text using a bitmap font.
+
+ * benchmark command supports a -stepthreads option to execute the
+ specified command with an increasing number of threads to measure
+ how an algorithm benefits from threading. This mode includes a
+ column to show the speedup compared with one thread, and the
+ Karp-Flatt metric
+
+ * Added support for invoking "gs-cmyk" and "gs-cmyka" entries in
+ delegates.mgk when ColorSeparationType or ColorSeparationMatteType
+ is requested. These cause Ghostscript to always output CMYK PAM
+ format (even if the input file was not in CMYK format).
+
+ * EXIF profiles are preserved when writing JPEG files.
+
+ * The -mosaic command now respects the composition option specified
+ by -compose as well as the image background color specified by
+ -background.
+
+ * The TXT coder now supports multiple image frames.
+
+ * For image normalization (-normalize), add support for
+ histogram-threshold setting to specify the percentage of the
+ histogram to discard when computing image normalization parameters
+ (default is 0.1%). For example `-set histogram-threshold 0.01
+ -normalize`.
+
+ * Added an `INFO` coder which produces textual image description
+ output similar to `identify` but may be used with convert like "gm
+ convert myfile info:-".
+
+ * Support application of the PDF crop box via '-define
+ pdf:use-cropbox=true'.
+
+ * For PCL printer output, define pcl:fit-to-page in order for the
+ printer to scale the image to fit the page.
+
+ * Added order dither 5x5, 6x6, and 7x7 circular dither patterns to
+ create a halftone effect.
+
+ * PNM subformats are now reported as the specific subformat rather
+ than just "PNM".
+
+ * NetPBM's PAM format is now supported.
+
+ * MacPaint image format reader is added.
+
+ * Added TIFF LZMA compressor support.
+
+ * Added TIFF support for a tiff:group-three-options define to allow
+ power-users to set the value of the GROUP3OPTIONS tag.
+
+ * New core C API function SetImageColorRegion() to set the constant
+ pixel color for a specified region of the image.
+
+ * New Wand C API function MagickWriteImagesFile() to append images
+ to a provided file handle.
+
+ * New Wand C API function MagickSetImageSavedType() to allow
+ specifying the storage type used when saving the file (rather than
+ changing the current image characteristics).
+
+ * In Wand C API, the functions NewPixelWand(), NewDrawingWand(), and
+ NewMagickWand() invoke InitializeMagick() automatically in case
+ user forgets to do so.
+
+ * New Wand C API function MagickSetFormat() to allow setting the
+ file or blob format before it has been read.
+
+ * New Wand C API function MagickSetDepth() to set the depth used
+ when reading from an image format which requires that the depth be
+ specified in advance.
+
+Feature improvements:
+
+ * Now compiles properly with libpng 1.4.X and 1.5.X.
+
+ * Lcms 2.X is supported.
+
+Performance Improvements:
+
+ * TGA read performance improved.
+
+ * PNM read/write performance improved.
+
+ * Convolution (-convolve, -sharpen, -guassian, etc.) is faster.
+
+ * Adaptive threshold image (-lat) is faster.
+
+ * Image trimming (-trim) is faster.
+
+Behavior Changes:
+
+ * For DPX format and packed 10 bits, datums are now represented in
+ the same (reversed) order for all RGB and YCbCr formats.
+ Previously YCbCr 4:4:4 formats were not swapping the word datums
+ because the only real-world files encountered did not swap the
+ word datums.
+
+ * The -colors, -map, and -monochrome options now take effect
+ immediately rather than at the end of all other processing.
+
+ * Removed non-standard multi-frame extension for SGI format.
+
+ * Windows install footprint is more consistent between DLL and
+ static builds.
+
+ * LZMA compressed tarball is in 'xz' format rather than deprecated
+ 'lzma' format.
+
+1.3.12 (March 8, 2010)
+==========================
+
+Security Fixes:
+
+ * Updated libpng Windows sources to 1.2.43 in order to resolve
+ CVE-2010-0205 as it pertains to the GraphicsMagick Windows build.
+
+Bug fixes:
+
+ * Filter mode (write to stdout) was completely broken.
+
+ * Should now compile with libpng 1.4.
+
+ * Windows PerlMagick build identified itself as the wrong version.
+
+New Features:
+
+ * None
+
+Feature improvements:
+
+ * None
+
+Performance Improvements:
+
+ * None
+
+Behavior Changes:
+
+ * DCX output format is only written on request. Previously the PCX
+ coder would automatically switch to DCX format if multiple frames
+ would be written.
+
+1.3.11 (February 21, 2010)
+==========================
+
+Security Fixes:
+
+ * Fixed array underflow on systems using signed char which could
+ result in a program crash due to extended characters in filenames
+ or in certain file formats.
+
+Bug fixes:
+
+ * Fixed array underflow on systems using signed char which could
+ result in a program crash due to extended characters in filenames
+ or in certain file formats.
+
+New Features:
+
+ * Added a -thumbnail command to 'convert' and 'mogrify'. This is a
+ faster way to scale down the image when speed is a primary
+ concern.
+
+ * Added a -extent command to 'convert' and 'mogrify' which
+ composites the image on top of a backing canvas image of solid
+ color.
+
+ * Added support for -compose to the 'convert' and 'mogrify', which
+ were documented to support it (but did not).
+
+Feature improvements:
+
+ * None
+
+Performance Improvements:
+
+ * Requests for 'Over' and 'Atop' composition are converted to a
+ request for the (faster) 'Copy' composition when both images are
+ opaque.
+
+Behavior Changes:
+
+ * None
+
+1.3.10 (February 10, 2010)
+==========================
+
+Security Fixes:
+
+ * None
+
+Bug fixes:
+
+ * +adjoin was not working correctly for the case when only one image
+ frame is present. With +adjoin and writing one frame to
+ "foo%d.jpg" it was outputting "foo%d.jpg" rather than "foo0.jpg".
+
+ * When drawing paths, memory allocation for the points was much
+ larger than it needed to be (patch by Vladimir Lukianov).
+
+New Features:
+
+ * None
+
+Feature improvements:
+
+ * None
+
+Performance Improvements:
+
+ * None
+
+Behavior Changes:
+
+ * To reiterate the change which first appeared in 1.3.9, there is no
+ longer an implicit +adjoin if the output file name happens to
+ contain a %d sequence, or there are multiple frames and the output
+ file format only supports storing one frame. Specify +adjoin if
+ scene number substition is desired in the output file names.
+
+1.3.9 (February 4, 2010)
+========================
+
+Security Fixes:
+
+ * None
+
+Bug fixes:
+
+ * Fix "double free" error when using gm import -frame.
+
+ * XPM does not support RGBA color syntax, so return RGB instead.
+
+ * The display '-update' option was only working in conjunction with
+ the '-delay' option with a delay setting of 2 or greater.
+
+ * For formats which support multiple frames, output with +adjoin to
+ filenames containing a scene specification (e.g. foo%02d.tiff) was
+ resulting in wrong output file names.
+
+ * -convolve was crashing rather than reporting an error.
+
+ * Fixed crash if the number of OpenMP threads was reduced from the
+ original value via '-limit threads' or omp_set_num_threads().
+
+ * -blur was not blurring the opacity channel for solid-color images.
+
+ * When installing HTML documentation, many files were included which
+ are not part of the formatted documentation.
+
+ * Several deleted global string constants are restored with
+ deprecated status in order to assure that symbols are not removed
+ from the ABI.
+
+New Features:
+
+ * None
+
+Feature improvements:
+
+ * None
+
+Performance Improvements:
+
+ * None
+
+Behavior Changes:
+
+ * There is no longer an implicit 'adjoin' if an output filename
+ contains an apparent scene specification (e.g. foo%02d.tiff) and
+ multiple files are not needed to save the image.. It is necessary
+ to use +adjoin. For example ``gm convert foo.pdf +adjoin
+ %02d.tiff``.
+
+ * -flatten now applies the image background color under the first
+ image in the list if it is not already opaque.
+
+1.3.8 (January 21, 2010)
+========================
+
+Security Fixes:
+
+ * Fix for CVE-2009-1882 "Integer overflow in the XMakeImage
+ function".
+
+ * Fix lockup due to hanging in loop while parsing malformed
+ sub-image specification (SourceForge issue 2886560).
+
+ * Libltdl: Updated libtool to 2.2.6b in order to fix security issue.
+ Resolves CVE-2009-3736 as it pertains to GraphicsMagick.
+
+Bug fixes:
+
+ * -convolve, -recolor: Validate that user-provided matrix is square
+ when parsing -convolve and -recolor commands in order to avoid a
+ core dump.
+
+ * CALS: Reading images taller than the image width resulted in a
+ failure.
+
+ * ConstituteImage(), DispatchImage(): 'A' and 'T' should indicate
+ transparency and 'O' should indicate opacity. Behavior was
+ inconsistent. In some cases 'O' meant transparency while in other
+ cases it meant opacity. Also, in a few cases, matte was not
+ getting enabled in the image as it should.
+
+ * DCRAW: Module name was not registered so modules based builds were
+ not supporting formats provided via 'dcraw'.
+
+ * GetOptimalKernelWidth1D(), GetOptimalKernelWidth2D(): In the Q32
+ build, convolution kernel size was estimated incorrectly for large
+ sigmas on 32-bit systems due to arithmetic overflow. This could
+ cause wrong results for -convolve, -blur, -sharpen, and other
+ algorithms which use these functions.
+
+ * Image Size: Fixed the ability to pass the image size via the
+ filename specification like "myfile.jpg[640x480]" rather than
+ needing to use -size.
+
+ * IPTC: Blob data needed to be padded to an even size. Size is now
+ correctly reported.
+
+ * IPTC: Returned IPTC string values were one character too short.
+
+ * Large Files: Large pixel cache files were not working under GNU
+ Linux.
+
+ * JP2: Fixed some value scaling problems.
+
+ * JP2: Fix possible crash at exit when Jasper is used by a modules
+ build.
+
+ * MPC: is_monochrome and is_grayscale flags were not managed
+ properly for the MPC coder.
+
+ * PCL: Page was not always being ejected.
+
+ * PNG: The png8 encoder would fail when trying to write a 1-color
+ image.
+
+ * PSD: PSD parser was confused by 0x0 pixel layers, resulting in
+ image data corruption of all following layers.
+
+ * -rotate, -shear: Some internally-reported errors were potentially
+ being lost.
+
+ * Subrange/stdin: Commands now support reading an image from stdin
+ in conjunction with a subrange specification (e.g. "-[1]").
+
+ * Magick++ STL ShadeImage: Implementation was completely botched.
+
+New Features:
+
+ * CALS Type 1 files may now be written (Work contributed by John
+ Sergeant). CALS support is dependent on the TIFF library.
+
+ * GROUP4RAW encoder supports reading/writing RAW Group4 data.
+
+ * JP2: JPEG 2000 may now be written in arbitrary bit depths ranging
+ from 2 to 16 rather than just 8 or 16.
+
+ * JPEG: IJG JPEG library version 7 is now supported.
+
+ * JPEG: Added jpeg:block-smoothing and jpeg:fancy-upsampling defines
+ to control these JPEG library options.
+
+ * JPEG: Detect and apply colorspaces appropriately for ITU FAX JPEG.
+
+ * Resource Limits: There is now a "threads" resource limit which
+ allows specifying the number of OpenMP threads which may be used,
+ similar to the OMP_NUM_THREADS environment variable.
+
+ * TIFF: Allow CIELAB TIFF to be read.
+
+ * MagickGetImageAttribute()/MagickSetImageAttribute(): New Wand
+ methods to support getting and setting an image attribute.
+ Contributed by Mikko Koppanen.
+
+ * ClonePixelWand(): New Wand method to deep-copy an existing pixel
+ wand.
+
+ * ClonePixelWands(): New Wand method to deep-copy an array of
+ existing pixel wands.
+
+ * MagickCdlImage(): New Wand method to apply the ASC CDL to an
+ image.
+
+ * MagickGetImageBoundingBox(): New Wand method to return the crop
+ bounding box required to remove any solid-color border from the
+ image.
+
+ * MagickGetImageFuzz(), MagickSetImageFuzz(): New Wand methods to
+ get and set the color comparison fuzz factor.
+
+ * MagickHaldClutImage(): New Wand method to apply a Hald CLUT to an
+ image.
+
+ * MagickSetResolution(): New Wand method to set the wand resolution.
+
+ * MagickSetResolutionUnits(): New Wand method to set the wand
+ resolution units.
+
+ * Magick++: Allow Magick++ library to built as a DLL under MinGW and
+ Cygwin. This requires a modern GCC in order for C++ exceptions to
+ work.
+
+Feature improvements:
+
+ * Cygwin: Cygwin 1.7 is now supported.
+
+ * JPEG compression settings are preserved (if possible) when
+ inserting JPEG blobs into formats which use JPEG.
+
+ * PDF: If the original file used JPEG compression, then use JPEG
+ compression with original settings (if possible).
+
+ * TIFF: Update Windows build to use libtiff 3.9.2.
+
+ * X11 Display: Apply a checkerboard pattern underneath transparent
+ images which use more than simple binary transparency.
+
+Performance Improvements:
+
+ * Gamma: Performance is improved for Q8 and Q16 builds. Also
+ preserve full precision in Q32 build.
+
+ * String data is dealt with a bit more efficiently (fewer
+ allocations, less memory, and less CPU).
+
+Behavior Changes:
+
+ * InitializeMagick() MUST be invoked prior to using any Magick API
+ function. Failure to do so will likely lead to an immediate
+ application crash. This is due to initialization and runtime
+ changes intended to improve thread safety and efficiency.
+ Previously it was only strongly recommended to invoke
+ InitializeMagick().
+
+ * ConstituteImage(), DispatchImage(): 'A' and 'T' should indicate
+ transparency and 'O' should indicate opacity. Behavior was
+ inconsistent. In some cases 'O' meant transparency while in other
+ cases it meant opacity. Also, in a few cases, matte was not
+ getting enabled in the image as it should.
+
+ * colors.mgk: Is now empty to default and is optional. Previous
+ content is now compiled into the library in an efficient way, but
+ existing values may be modified, or new values added by adding
+ entries to color.mgk.
+
+ * DisableSlowOpenMP is now the default. Use --enable-openmp-slow to
+ enable OpenMP for algorithms which sometimes run slower rather
+ than faster.
+
+ * magic.mgk: This configuration file is no longer used since this
+ data is now compiled into the library in an efficient way.
+
+ * modules.mgk: Is now empty to default and is optional. Previous
+ content is now compiled into the library in an efficient way, but
+ existing values may be modified, or new values added by adding
+ entries to modules.mgk.
+
+ * Third party executables not included in the Visual Studio build
+ are no longer bundled in the GraphicsMagick installer. This means
+ that hp2xx.exe, mpeg2dec.exe, and mpeg2enc.exe are no longer
+ distributed.
+
+1.3.7 (September 17, 2009)
+==========================
+
+Security Fixes:
+
+ * PCX: Detect improper rows, columns, or depth. Fixes CVE-2008-1097
+ "Memory corruption in ImageMagick's PCX coder".
+
+ * DrawDashPolygon: Avoid a crash which sometimes occured with tiny
+ polygons.
+
+Bug fixes:
+
+ * JPEG: Profile chunks need to be concatenated in order to build
+ the whole profile. This was not working so embedded profiles
+ larger than 32K or maybe 64K were being corrupted. This bug was
+ introduced in GraphicsMagick 1.2.
+
+ * Meta: Fix memory leaks.
+
+ * Meta: Work better with with IPTC record 2 blocks and deal better
+ with IPTC embedded in an 8BIM profile. Fixes by John Sergeant.
+
+ * MPC: Fix crash when reading MPC and the input image is modified.
+
+ * PNG: Ensure that the opacity channel is properly initialized.
+
+ * -profile: Lowercase arguments were sometimes not working as
+ expected.
+
+ * Topol: Topol reader actually works now and is included in test
+ suite.
+
+ * TIFF: Read and write JPEG-compressed grayscale TIFF correctly.
+
+ * VisualMagick configure now works properly when output paths are
+ specified.
+
+ * WMF: Eliminate memory leaks.
+
+New Features:
+
+ * MagickWand: New method MagickSetCompressionQuality() to allow
+ setting the compression quality.
+
+ * MagickWand: New method CloneDrawingWand() to deep-copy a drawing
+ wand.
+
+ * MagickWand: New method DrawGetException() to retrieve information
+ regarding the last drawing wand exception (if any).
+
+ * MagickWand: New method DrawClearException() to clear a drawing wand
+ exception.
+
+ * Magick++: New Image method cdl() to apply the ASC CDL.
+
+ * Magick++: New Image method colorMatrix() to apply a color matrix
+ to the image channels.
+
+ * Magick++: New Image method haldClut() to apply a color lookup
+ table (Hald CLUT) to the image.
+
+ * MSL/Conjure: Added a new 'profile' command which applies, adds, or
+ removes one or more IPTC, ICC or generic profiles from a file.
+ Work contributed by John Sergeant.
+
+ * Added a 'time' subcommand to provide Unix-style 'time' output when
+ a 'time' capability is missing, or the reporting format is
+ inconsistent. For example 'gm time convert ...'.
+
+Feature improvements:
+
+ * ColorMatrixImage(): Add opaque opacity channel when needed.
+
+ * PDF & PS: Use '-type palette' prior to input file name to cause
+ Ghostscript to return a dithered colormapped image.
+
+ * PNG: Now compiles with libpng-1.4.0beta74 and later.
+
+ * TIFF: Libtiff in Windows build is upgraded to 3.9.1. This allows
+ GraphicsMagick to read and write 16 and 24 bit float TIFF files.
+
+ * Windows code to find Ghostscript is rewritten from scratch.
+
+Performance Improvements:
+
+ * Drawing of points, lines, and polygons (and complex shapes based
+ on these) is now accelerated using OpenMP with excellent speed-up.
+
+ * ICC color transforms now see linear speedup from OpenMP.
+
+ * Rotate: For rotations of 90 or 270 degrees, tile sizes are
+ selected more appropriately.
+
+Behavior Changes:
+
+ * No longer clear the exception structure at the start of
+ ReadImage() and other similar functions since this sometimes masks
+ errors. The API user is expected to make sure that the exception
+ structure is clean prior to invoking a function.
+
+ * SVG: Writer is now disabled since it usually does not work properly.
+
+1.3.6 (July 25, 2009)
+=====================
+
+Security Fixes:
+
+ * None.
+
+Bug fixes:
+
+ * Composition was failing when the change image overlaps off the
+ left side of the canvas.
+
+ * EPT, PDF, PS: PDF bounding box is sometimes incorrect or not
+ globally applicable so don't specify bounding box when reading PDF
+ files.
+
+ * OpenMP: Fix (benign) multi-thread cross-contentions (detected by
+ valgrind's Helgrind).
+
+ * TIFF: Fix problem with reading one bit per sample RGB images.
+
+ * TIFF: Writer was using rows-per-strip of 8 when writing
+ JPEG-compressed TIFF. This does not work for vertical
+ subsampling, and some TIFF readers insist on 16. The
+ rows-per-strip is now required to be a multiple of 16.
+
+ * TIFF: In some cases, the TIFF reader and writer were accessing
+ planar TIFF in row-order rather than plane-order, which resulted
+ in sever buffering problems in libtiff, and failure when
+ compression was used.
+
+ * -write now works usefully as documented.
+
+ * Temporary file name generator was not random enough, resulting in
+ some file name collisions for GraphicsMagick processes started at
+ the same time.
+
+ * PerlMagick: Fixed Ping on a BLOB.
+
+ * GetImageDepth was leaking memory.
+
+ * Convert/mogrify -mask option was leaking memory.
+
+ * Mogrify -output-directory option was leaking memory.
+
+ * DPX: Fixed memory leak encountered when subsampling to 4:2:2.
+
+ * DPX: Values read received insuficient scaling, which round-tripped
+ correctly, but rounded-down excessively if any image processing
+ was applied.
+
+New Features:
+
+ * Added HRS reader for slow scan TV (contributed by Fojtik Jaroslav).
+
+ * Pthreads (POSIX threads) API may now be used under the WIN32 API.
+
+ * New access confirmation facility (MagickConfirmAccess) to allow
+ the API user to monitor and/or block access to files and URLs.
+ This allows the API user to implement a security policy based on
+ actual accesses.
+
+ * New color matrix function (ColorMatrixImage) to apply a color
+ matrix similar to Adobe Flash Flash.filters.colorMatrixFilter(),
+ and Windows GDI+ ColorMatrix class, (order up to 5x5) to the image
+ pixels. This is accessible via the -recolor command option.
+
+ * Added an IDENTITY coder to return a Hald identity CLUT image of
+ specified order (e.g. "identity:8").
+
+ * Added a Hald CLUT capability as described at
+ http://www.quelsolaar.com/technology/clut.html. This allows a
+ color transformation to be easily created and replicated on any
+ number of images. The algorithm is accessed by the -hald-clut
+ option of 'convert' and 'mogrify'. Original algorithm by Eskil
+ Steenberg and adapted for GraphicsMagick by Clment Follet, with
+ additional work by Bob Friesenhahn.
+
+ * Added support for the ASC CDL transform. Available as -asc-cdl
+ via the 'convert' and 'mogrify' subcommands. Original
+ implementation by Clment Follet but considerably re-worked by Bob
+ Friesenhahn. Implementation passes the +/- 1 count accuracy
+ requirement required by the ASC CDL SOP tests.
+
+ * Added support for reading CALS Type 1 format (contributed by John
+ Sergeant). CALS is a standard raster format used by the US
+ Department of Defense for storing blueprint images.
+
+ * Added a random number generation system based on George
+ Marsaglia's multiply-with-carry generator. Somewhat slower than
+ rand() but produces better random numbers with a period >2^60.
+ This is a much better random number generator than the C library
+ rand() and the algorithm is integrated in a way which maximizes
+ multi-thread performance.
+
+ * The 'compare' command now supports a -maximum-error option to
+ specify the maximum image error so that it may be used to support
+ boolean logic in automated test scripts.
+
+ * For OpenMP-builds, the '-list resource' output now indicates the
+ number of threads which will be used.
+
+Feature improvements:
+
+ * Image resize now avoids adding "halos" around objects when
+ resizing an image which contains transparency (patch contributed by
+ Pavel Merdin).
+
+ * DICOM: The DICOM reader is completely re-written and is much more
+ functional now. A few features (e.g. RLE compression) are still
+ missing. This work is contributed by John Sergeant.
+
+ * EXIF: Unprintable characters in EXIF attribute strings are now
+ returned using three-digit octal notation. Unknown tags are
+ identified via their four-character hex value.
+
+ * PCL: PCL writer is rewritten to fix many bugs, add support for
+ compression, add support for 8 bit PseudoClass images, and
+ dramatically improve usability (work contributed by John Sergeant).
+
+ * TIFF: Allow the user to force the returned image to be TrueColor
+ type for min-is-white and min-is-black TIFF files.
+
+ * TIFF: User can now specify the predictor using syntax like
+ '-define tiff:predictor=2'.
+
+ * TIFF: User can now specify the rows-per-strip value when using
+ JPEG compression.
+
+ * TXT: The TXT reader is now capable of reading image files written
+ by the TXT writer, as well continuing to render ASCII text into an
+ image (work contributed by Fojtik Jaroslav).
+
+ * Utilities @file.txt syntax for including a list of files to use as
+ an argument now really works as expected. This may be used to
+ inject any other text into the command line as well. As a result,
+ the 'mogrify' utility may be invoked on thousands of files at once
+ while obtaining the list of files to process from a text file.
+
+ * The 'mogrify' utility now caches argument images so that they are
+ loaded only once when mogrify is used to process multiple image
+ files.
+
+Performance Improvements:
+
+ * -median and -noise now see reliable linear speedup as threads are
+ added.
+
+Behavior Changes:
+
+ * PerlMagick is configured but no longer built by default.
+
+ * Use '-interlace Line' to produce an interlaced GIF, PNG, or
+ progressive JPEG.
+
+1.3.5 (January 26, 2009)
+=========================
+
+Security Fixes:
+
+ * BMP and DIB formats were throwing an assertion for negative height
+ values. This caused the process to crash.
+
+Bug fixes:
+
+ * Don't install Magick++ headers if C++ is disabled.
+
+ * Linux RPM SPEC file needs to always install the loadable module
+ .la files or else the modules won't load.
+
+ * Windows runtime DLLs were for the wrong compiler version,
+ resulting in failure to execute if the correct runtime DLLs are
+ not available.
+
+New Features:
+
+ * None
+
+Feature improvements:
+
+ * FITS: Parsing is more robust.
+
+Performance Improvements:
+
+ * None
+
+1.3.4 (January 13, 2009)
+=========================
+
+Security Fixes:
+
+ * None.
+
+Bug fixes:
+
+ * Now runs under Windows Vista (as a 32-bit application).
+
+ * Fix for colorspace transform math overflow in Q32 build.
+
+New Features:
+
+ * Windows build supports OpenMP and requires Windows 2000 or later
+ (source code still supports Windows '98).
+
+ * Support large files under Windows.
+
+ * Support reading/writing 16 and 24 bit float TIFF files.
+
+ * Support reading/writing 64 bit integer TIFF files.
+
+ * Added "Log", "Max", "Min", and "Pow" options to -operator.
+
+Feature improvements:
+
+ * Debug logging now properly prints 64-bit offset values.
+
+Performance Improvements:
+
+ * Improve resource estimation for Microsoft Windows systems.
+
+1.3.3 (December 9, 2008)
+========================
+
+Security Fixes:
+
+ * None.
+
+Bug fixes:
+
+ * 'identify' was throwing an assertion when used on colormapped
+ files (this bug was introduced by 1.3.2).
+
+ * With the -segment option, eliminate trashing the image colors when
+ used on huge images.
+
+ * 'identify -format "%c"' now reports the entire comment regardless
+ of size.
+
+ * Argument to -convolve is no longer arbitrarily truncated so huge
+ convolution kernels may now be specified from the command line.
+
+Performance Improvements:
+
+ * Image segmentation (-segment) is now accelerated using OpenMP and
+ uses several other tactics to improve execution performance.
+
+ * 'identify "*"' now successfully works in a 32-bit application when
+ used in a directory containing a million files.
+
+ * 'identify' now executes quickly when used on TIFF files.
+
+1.3.2 (November 29, 2008)
+=========================
+
+Security Fixes:
+
+ * None.
+
+Bug fixes:
+
+ * -roll was failing for colormapped images.
+
+ * VID: Memory leak fix.
+
+ * PREVIEW: Solarize parameter was wrong.
+
+ * Delegates previously using 'spawn' needed an ampersand so that
+ starting the child process does not hang the GUI.
+
+Feature improvements:
+
+ * +profile now supports an exclusion syntax. For example ``+profile
+ '!icm,*'`` removes all of the profiles except for the ICM profile.
+ The new syntax also allows multiple profiles to be listed at once.
+
+Performance Improvements:
+
+ * AdaptiveThreshold, Blur, Convolve, and MotionBlur no longer
+ process the opacity channel unless the image has one.
+
+1.3.1 (November 17, 2008)
+=========================
+
+Security Fixes:
+
+ * None.
+
+Bug fixes:
+
+ * RPM build, Fixes to successfully build binary RPMs for Red Hat
+ Linux 4.
+
+ * MSL/conjure, Fix bug with attributes becoming appended to
+ themselves. Fix memory leaks.
+
+Feature improvements:
+
+ * New --disable-openmp-slow configure option for disabling use of
+ OpenMP for algorithms which may run slower on operating systems
+ with crummy thread libraries.
+
+ * JPEG, Allow user to specify DCT encoding method via
+ jpeg:dct-method define. Also allow control over whether huffman
+ encoding is used via jpeg:optimize-coding define.
+
+Performance Improvements:
+
+ * OpenMP (parallel processing) improvements for these functions:
+
+ - Rotate by 90 and 270 degrees (-rotate)
+
+1.3 (November 9, 2008)
+======================
+
+Security fixes:
+
+ * AVI reader: Re-worked to be more robust against crash or DOS.
+
+ * AVS reader: Re-worked to be more robust against crash or DOS.
+
+ * DCM reader: Re-worked to be more robust against crash or DOS.
+
+ * EPT reader: Re-worked to be more robust against crash or DOS.
+
+ * FITS reader: Re-worked to be more robust against crash or DOS.
+
+ * MTV reader: Re-worked to be more robust against crash or DOS.
+
+ * PALM reader: Re-worked to be more robust against crash or DOS.
+
+ * RLA reader: Re-worked to be more robust against crash or DOS.
+
+ * TGA reader: Re-worked to be more robust against crash or DOS.
+
+ * Avoid possible crash in GetImageCharacteristics() when substituting
+ text in comment read from file.
+
+ * Cineon reader: Fixed crash with broken file from Sami Liedes.
+
+ * Palm reader: Fixed crash with broken files from Sami Liedes.
+
+ * PICT reader: Fixed crash with broken files from Sami Liedes.
+
+ * DPX reader: Validate file data better to avoid improper operation with
+ intentionally (or accidentally) defective files.
+
+ * XCF reader: Fixed crash with broken files from Sami Liedes.
+
+Bug fixes:
+
+ * Libbz2 is now detected for MinGW.
+
+ * Install documentation under /usr/local/share/doc/GraphicsMagick by
+ default, according to GNU conventions.
+
+ * In PerlMagick, Dissolve composition was not working right.
+
+ * FITS: Ensure that written format conforms to specification.
+
+ * TIFF:
+
+ - Don't accidentially convert CMYK images to RGB.
+
+ - Eliminated a memory leak in the codec support detection code.
+
+ * JPEG: Removed over-write of image->client_data.
+
+ * PDF: Try to properly deal with reading rotated PDFs.
+
+ * PNG: Fixed crash when writing PNG images with transparency and either
+ optimize is requested, or the image is colormapped.
+
+ * Configure: Fixed the --enable-magick-compat configure option, which
+ had stopped working.
+
+ * Configure: Fixed --without-magick-plus-plus so that it works again. This
+ stopped working in the 1.2 release cycle.
+
+ * Configure: Fixed MagickLibVersion text string generation so that it
+ is now correct when a component of the release number exceeds '9'.
+ Now components can safely count up to '99' before there is a problem.
+
+Performance Improvements:
+
+ * OpenMP (parallel processing) improvements for these functions:
+
+ - Affine transform (-affine -transform)
+ - Average images (-average)
+ - Add noise (+noise)
+ - Black threshold (-black-threshold)
+ - Blur (-blur)
+ - Border (-border)
+ - Channel import, export, and depth-setting (-channel, -depth)
+ - Clip path
+ - Coalesce (-coalesce)
+ - Colorize (-colorize)
+ - Colorspace transformation (-colorspace)
+ - Compare images ('compare' command)
+ - Composition ('composite' command)
+ - Convolution (-convolve, -edge, -emboss, -gaussian, -sharpen)
+ - Contrast adjust (-contrast)
+ - Crop (-crop)
+ - CycleColormap (-cycle)
+ - Depth setting (-depth, -operator depth)
+ - Despeckle (-despeckle)
+ - Enhance (-enhance)
+ - Equalize (-equalize)
+ - Flatten (-flatten)
+ - Flip (-flip)
+ - Flop (-flop)
+ - Frame (-frame)
+ - Gamma adjust (-gamma, -operator gamma)
+ - Gradient
+ - Implode (-implode)
+ - Levels adjust image (-level)
+ - Local adaptive threshold (-lat)
+ - Median filter (-median)
+ - Minify image (-minify)
+ - Modulate image (-modulate)
+ - Morph image (-morph)
+ - Mosiac (-mosaic)
+ - Motion blur (-motion-blur)
+ - Negate image (-negate)
+ - Noise filter (-noise)
+ - Normalize image (-normalize)
+ - Oil Paint (-paint)
+ - Opaque (-opaque)
+ - Ordered dither (-ordered-dither)
+ - Operators (-operator)
+ - Profile adjust (ICC) (-profile)
+ - Random threshold (-random-threshold)
+ - Resize image (-resize)
+ - Raise image (-raise)
+ - Roll image (-roll)
+ - Rotate image (-rotate)
+ - Shade image (-shade)
+ - Shear image (-shear)
+ - Shave (-shave)
+ - Solarize image (-solarize)
+ - Spread image (-spread)
+ - Statistics computation (identify -verbose)
+ - Swirl (-swirl)
+ - Threshold channel (-threshold, -operator threshold)
+ - Threshold image (-threshold)
+ - Transparent (-transparent)
+ - Trim image (-trim)
+ - UnsharpMaskImage (-unsharp)
+ - Wave (-wave)
+ - White threshold (-white-threshold)
+
+ * Improved coder management performance.
+
+ * XCF (GIMP) reader is much faster.
+
+New Features:
+
+ * Use MAGICK_CODER_STABILITY environment variable to enable a subset
+ of the coders based on their stability classification.
+
+ * Use MAGICK_IO_FSYNC environment variable to cause written file to
+ be synchronized to disk to avoid possible data loss on power fail.
+
+ * Added 'compare' command to statistically or visually compare two
+ image files.
+
+ * Added new channel operators (-operator):
+
+ - Assign
+ - Gamma
+ - Depth
+ - Negate
+ - Noise-Gaussian
+ - Noise-Impulse
+ - Noise-Laplacian
+ - Noise-Multiplicative
+ - Noise-Poisson
+ - Noise-Uniform
+ - Threshold
+ - ThresholdBlack
+ - ThresholdWhite
+
+ * New composition operators (-compose):
+
+ - CopyBlack
+ - CopyCyan
+ - CopyMagenta
+ - CopyYellow
+ - Divide
+
+ * Added -motion-blur to motion blur the image.
+
+ * Mogrify and convert now support -black-threshold and -white-threshold.
+
+ * MAT: Now supports reading compressed files.
+
+ * FITS: Now supports 8, 16, 32 bit integer, float, and double images
+ and writes correct FITS format.
+
+ * DCRAW: Coder proxy module allows reading digital camera files as if
+ they were natively supported.
+
+ * New C API functions:
+
+ - AddNoiseImageChannel(), add noise to an image channel.
+ - BlurImageChannel(), blur an image channel.
+ - GaussianBlurImageChannel(), gaussian blur an image channel.
+ - ImportImageChannelsMasked(), import selected image channels.
+ - SharpenImageChannel(), sharpen an image channel.
+ - UnsharpMaskImageChannel(), unsharpmask an image channel.
+ - New cache view interfaces to correct shortcomings of original
+ ones. New interfaces are AcquireCacheViewPixels(),
+ AcquireOneCacheViewPixel(), AcquireCacheViewIndexes(),
+ GetCacheViewPixels(), SetCacheViewPixels(), and
+ SyncCacheViewPixels(). The deprecated functions are
+ AcquireCacheView(), GetCacheView(), SetCacheView(), and
+ SyncCacheView().
+ - GetCacheViewRegion() reports region bounded by a cache view.
+ - GetCacheViewArea() reports area bounded by a cache view.
+ - ExportViewPixelArea() exports a cache view as formatted pixels.
+ - ImportViewPixelArea imports formatted pixels into a cache view.
+
+ * Removed C API functions:
+
+ - ReadStream()
+ - WriteStream()
+
+ * Magick++ C++ API improvements
+
+ - Color class no longer considers transparent black to be an invalid
+ color.
+ - New Image methods addNoiseChannel(), blurChannel(),
+ gaussianBlurChannel(), motionBlur(), randomThresholdChannel(),
+ randomThresholdChannel(), sharpenChannel(), unsharpmaskChannel().
+
+Feature improvements:
+
+ * -ordered-dither and -random-threshold may now be used to individually
+ dither any named channel.
+ * Mogrify and convert now support -minify to halve the image size.
+ * Mogrify and convert now support -magnify to double the image size.
+
+1.2 (April 29, 2008)
+====================
+
+Security fixes:
+
+ * Fixes for CERT security alert TA04-217A described at
+ "http://www.us-cert.gov/cas/techalerts/TA04-217A.html".
+ * AVI, BMP, & DIB security fixes.
+ * PSD security fixes.
+ * P7 format security fix.
+ * Fix EXIF IFD stack overflow vulnerability.
+ * SGI security fix for RLE encoding (CVE-2006-4144)
+ * XCF security fix (CVE-2006-3743)
+ * PALM heap overflow fix (CVE-2006-5456)
+ * DCM security fix (CVE-2006-5456)
+ * Fix for shell command injection in delegate code via file names)
+ (CVE-2005-4601). Delegate execution is much more secure now.
+ * Don't use filenames as printf specifications (CVE-2006-0082).
+ * Fix integer overflow in DCM coder (CVE-2007-1797).
+ * XWD integer overflow fix (CVE-2007-1797).
+ * Implementation has replaced usage of strcpy, strcat, and strncat
+ with the more security conscious strlcat and strlcpy.
+ * DCM, DIB, XCF, XBM, and XWD security fix for integer overflow
+ vulnerability (IDefense 09.19.07).
+ * Do not access X11 or invoke convenience or stealth delegate programs
+ based on the file extension. In particular, these file extensions are
+ rejected for consideration as a format specifier: 'autotrace',
+ 'browse', 'dcraw', 'edit', 'gs-color', 'gs-color+alpha', 'gs-gray',
+ 'gs-mono', 'launch', 'mpeg-encode', 'print', 'scan', 'show', 'win',
+ 'xc', and 'x'.
+
+Bug fixes:
+
+ * The configure script now searches for a web browser in the order
+ mozilla, firefox, and finally netscape.
+ * When the user specifies the -units option, the current image
+ resolution values are now re-scaled to match the new units.
+ * Properly determine Ghostscript font location for Ghostscript 8.0 and later.
+ * GraphicsMagick now successfully builds and passes all tests under
+ Digital Unix 5.1, using the vendor compiler.
+ * Ghostscript sometimes displays an error message and fails, yet it
+ returns a success error code to GraphicsMagick. Verify that
+ Ghostscript has updated the output file before attempting to use it.
+ * Fixed a configure script syntax error when testing for trio.
+ * When requesting a list of formats, all of the modules in the module
+ search path are considered. Previously only the modules in the same
+ directory as the LOGO module were listed.
+ * Ensure that an image clip mask is respected by the negate algorithm.
+ * The BMP writer was sometimes writing incorrect BMP v4 files.
+ * Support reading and writing large PCX files.
+ * The Red Hat source RPM was failing to install the -config scripts
+ with execute permissions.
+ * Fixed a bug which could cause possible truncation while cloning the
+ image cache.
+ * Ensure that MIFF files indicate the compression which was actually used.
+ * Properly handle errors from libtiff so that corrupted images are not
+ output.
+ * Fix for stripped-TIFF reader. Discard extra samples beyond alpha in
+ scanline TIFFs.
+ * Endian option now controls TIFF byte-order rather than bit-order.
+ * TIFF writer can now write to pipes and other non-seekable output
+ destinations.
+ * JBIG writer was writing empty files for some libjbig releases.
+ * Improved handling of corrupt GIF files.
+ * Handle large SUN format images.
+ * Properly compute image depth for 16-bit SGI image files.
+ * For the gmdisplay program, ensure that only RGB data is sent to Windows.
+ * Many memory leak fixes.
+ * PDF writer is fixed so that Ghoscript 8.5 doesn't warn about the output.
+ * PDF writer now writes proper output with CCITT compression.
+ * Properly use fseeko() and ftello() if they are available.
+ * Fixed a infinite loop bug in the XWD reader.
+ * Fix minor memory leak in ProfileImage().
+ * Fixed -level command parsing when a percent symbol is supplied within the
+ argument rather than at the end.
+ * Fix pixel scaling problem caused by floating point
+ rounding error (noticed under AIX).
+ * Fixed a memory leak in the GIF coder in the error return path.
+ * Fix for SourceForge bug id 1353744 "MagickGetQuantumDepth doesn't work".
+ * Fix for SourceForge bug id 1315109 "segfault in InitializeMagick(NULL)".
+ * Fix for SourceForge bug id 1391421 "problem doing resize on 273x1 JPEG".
+ * Fix for SourceForge bug id 1510075 "Failed to write PDF with JPEG compression".
+ * Fix for SourceForge bug id 1572357 "GetOnePixel definition appears incorrect".
+ * Fix for SourceForge bug id 1576616 Fix includedir variable in pkg-config files".
+ * Fix for SourceForge bug id 1173713 "segfault in ModifyCache".
+ * Fix for SourceForge bug id 1431805 "clip art wpg files cause access violation
+ in graphics magick".
+ * Fix for SourceForge bug id 1743141 "Affine matrix option parsing".
+ * Fix for SourceForge bug id 1625477 "Memory leak reading layered PSD Image".
+ * Fix for SourceForge bug id 1878992 "literal square brackets in file
+ name cause large delay and bug id 1783209 "converting runs slowly
+ when subimage is specified".
+ * Fix for SourceForge bug id 1883527 "compression of tiff-file has no effect".
+ * Successfully read files in the form "file[123]".
+ * Fix reading 12-bit grayscale JPEG.
+ * Set image depth appropriately when importing image from X11 display.
+ * Fix map resource tracking.
+ * Fix reading recent variants of ImageMagick's MIFF format.
+ * Output bilevel TIFF meeting the TIFF Class F specification.
+
+New Utilities:
+
+ * A 'benchmark' subcommand is now available to benchmark the
+ performance of any other arbitrary subcommand (e.g. 'convert').
+
+Feature improvements:
+
+ * LZW compression is now enabled by default.
+ * Support industry-standard subsampling notation like "4:2:2".
+ * If gm is executed under a traditional alternate name (e.g.
+ convert), it will invoke the appropriate sub-command. This allows
+ use of hard links, symbolic links, or just copying 'gm' to the
+ desired sub-command name in order to achieve 100% ImageMagick 5.5.2
+ utility compatibility.
+ * Provide the --enable-magick-compat option when configuring to install
+ ImageMagick utilities compatibility links.
+ * Identify -verbose output includes normalized (0.0-1.0) statistics.
+ * Identify and convert now print "pixels per second" rates to help
+ evaluate performance.
+ * Added the identify +ping option to force reading the complete file.
+ * The display program now supports the +progress option to disable any
+ visual progress indication (and hourglass cursor) while loading images.
+ * Support writing grayscale TGA files.
+ * Provide explicit support for Rec 601 and Rec 709 grayscale spaces.
+ * Include some support for a log RGB space based on the 2.048 density
+ range as defined for the Cineon Digital Film System.
+ * Added utilities command-line support for industry standard subsampling
+ notation like 4:4:4 and 4:2:2.
+ * Use MAGICK_IOBUF_SIZE to tune the size of the I/O buffer.
+ * Use -type Bilevel, Grayscale, TrueColor, or TrueColorMatte to
+ influence the type of image that Ghostscript returns.
+ * Use '-define tiff:fill-order={msb2lsb|lsb2msb}' to control TIFF bit
+ fill order.
+ * The -version option now dumps a feature list as well as the build
+ options.
+ * The -endian option now supports the option 'native'.
+ * A -monitor is added to enable progress monitoring for the command line
+ utilities.
+ * Use the -output-directory option to 'mogrify' to send output files to
+ the specified directory.
+ * Use the -create-directories option in conjunction with
+ -output-directory and 'mogrify' to create any necessary subdirectories.
+ * A Pixels resource limit is added. Use '-limit Pixels value' to limit
+ the maximum number of pixels in an image to 'value'.
+ * The already supported option '-type Optimize' is now honored by
+ formats that need to choose a subformat based on the properties of
+ the image. Grueling tests of many/all pixels are not performed
+ unless '-type Optimize' is supplied.
+ * Added a a -set option to the composite, convert, display, mogrify,
+ import commands in order to allow setting an image attribute.
+ * Display utility no longer defaults to reading from standard input if
+ stdin is not a tty.
+ * May now be configured to use the umem memory allocation library
+ available in Solaris 9, Update 3 and later, or from the portable umem
+ project.
+
+Coder additions/improvements:
+
+ * Replaced existing DPX "support" with all-new DPX support conforming
+ to the SMPTE 268M-2003 standard.
+ * Cineon reader completely rewritten.
+ * TIFF coder is completely re-written. Now supports reading and
+ writing RGB, CMYK, and grayscale, scanline-oriented TIFF images
+ with arbitrary (1 to 32 bits) depth. Includes support for tiled
+ TIFF, floating point TIFF, LogLuv TIFF, BigTIFF, arbitrary depths,
+ and associated alpha.
+ * TIFF coder now supports retrieving and saving XMP profiles.
+ * MATLAB support is much improved and supports writing as well.
+ * WPG reader now supports CTM translations.
+ * ART format now supports writing.
+ * Support 32-bit raw RGB images.
+ * Support 32-bit raw CMYK images.
+ * Support 32-bit raw gray images.
+ * JP2 coder reads images in YCbCr colorspace and retrieves an embedded
+ ICC ICM color profile if present.
+
+API enhancements:
+
+ * Added ExportImageChannel() and ImportImageChannel() APIs to support
+ exporting and importing pixel regions with an arbitary range of (1
+ to 32) bits per quantum.
+ * Added image leveling methods for Magick++.
+ * Generalized GetImageAttribute() support for retrieving wildcarded
+ attributes so that an identify -format specification like
+ ``"%[dpx:*]"`` works as expected.
+ * Incorporated changes changes necessary so that GraphicsMagick can
+ work with the Ch C/C++ interpreter from SoftIntegration at
+ http://www.softintegration.com/.
+ * Added MagickAllocFunctions() to allow the API user to replace the
+ underlying memory allocator functions.
+ * Added MagickMalloc() and deprecated AcquireMemory().
+ * Added MagickCloneMemory() and deprecated CloneMemory().
+ * Added MagickMallocArray() to safely allocate N items of size S.
+ * Added MagickRealloc() and deprecated ReacquireMemory().
+ * Added MagickFree() and deprecated LiberateMemory().
+
+Performance improvments:
+
+ * The DispatchImage() and ConstituteImage() functions incorporate
+ special case code for BGR, BGRO, BGRP, RGB, RGBO, and I formats (8
+ bit only) in order to improve performance dramatically.
+ * When writing very large JPEG images, don't enable Huffman compression
+ since doing so requires libjpeg to buffer the entire image in memory.
+ * When using the 'identify' -verbose option, -verbose must be specified
+ twice in order to obtain the color count. This makes normal use of
+ -verbose much faster.
+ * Significantly improved read/write speed for bilevel and gray images.
+ * TIFF I/O is considerably faster.
+ * Postscript writer is 10-15X faster.
+ * PNM formats writer is 10-100X faster.
+ * Rotate by 90 or 270 degrees is 2-9X faster.
+
+Windows-specific improvements/changes:
+
+ * For the MinGW and Cygwin builds, the Magick++ library is forced to
+ build as a static library since otherwise C++ exceptions don't work.
+ * MinGW cross-build is available from a Linux or FreeBSD host.
+ * Determine location of Ghostscript fonts only once in order to improve
+ performance.
+ * Updated bzip2 to 1.0.4.
+ * Updated Jasper library to version 1.900.1.
+ * Updated jbigkit to 1.6
+ * Updated lcms to 1.17
+ * Updated libpng to 1.2.27.
+ * Updated libtiff to 3.8.2
+ * Updated zlib to 1.2.3.
+ * Libtiff supports LZW compression.
+ * X11 is no longer part of the default build and will not be included
+ in the distributed install packages (but can still be built).
+ * Find latest Ghostscript which idenfies itself as "GPL Ghostscript".
+ * Use GlobalMemoryStatusEx(), if available, to determine how much
+ physical memory is available. Important for large-memory machines.
+ * Fixed NTreaddir() so that it does not write beyond its buffer.
+ * Fixed opendir() emulation function so it can't overwrite the stack.
+ * FlashPIX library sources are no longer distributed in the Windows
+ source package and building FlashPIX is disabled by default.
+ FlashPIX may still be built by adding the library (separately
+ distributed).
+ * Fix bitmap handle leak in CropImageToHBITMAP() and ImageToHBITMAP().
+
+1.1 (Released April 4, 2004)
+============================
+
+Bug fixes:
+
+ * Semaphore fix which is necessary for proper multi-threaded operation.
+ * Configure script fix to ensure that -lfpx is not supplied to the C
+ compiler during subsequent tests since this fails on some systems.
+ * Fix for East and West gravity computations.
+ * System error reports (errno) associated with an exception are now
+ correctly obtained from the context existing when the exception was
+ thrown rather than the context of the reporting function.
+ * JNG encoder fix. Files were being written with incorrect
+ alpha_sample_value in the header. These can be repaired by reading
+ them into GM 1.1 and rewriting them.
+ * XPM fix to module registration.
+ * PSD fix for index calculation when QuantumDepth>8.
+ * Validate that geometry specifications only include allowed
+ characters.
+ * SGI fix to save compression type while writing.
+ * EXIF attributes were not being retrieved when requested.
+ * Fix for bug when reading an image via a user-provided file
+ descriptor.
+ * The reported image magick string is now always that of the original
+ input file (it was sometimes being reported as the format produced by
+ an intermediate delegate program).
+ * Fixes to color profiling of CMYK images.
+ * Memory leak fixed in DrawClipPath().
+ * Arc drawing is fixed.
+ * Command-line parsing bug under Linux due to Linux's sscanfs
+ inability to parse strings like "0x1" as "%fx%f" is fixed.
+ * Scaling of 5 and 6-bit colors was slightly incorrect in BMP, AVI,
+ DIB, and TIM datastreams.
+ * GM utility now reports an error rather than silently returning if
+ an unsupported sub-command is provided.
+ * TIFF coder was writing 16-bit per sample RGB images incorrectly on
+ little-endian CPUs.
+
+Performance improvements:
+
+ * Texture tiling is now 7X faster.
+ * Color profile processing speed improvements for colormapped images.
+
+Utilities enhancements:
+
+ * For Unix, 'gm version' now includes a dump of the configure and
+ build parameters.
+ * Logging of thrown exceptions is now supported. Use '-debug
+ exception'. This is useful to learn when and where errors are
+ reported.
+ * The -define option is added in order to support supplying
+ additional options to coders without needing to add additional
+ command line options or structure members.
+ * The output of 'gm identify -verbose' now provides a nice dump
+ of EXIF data.
+ * The -sampling-factor option now accepts as many HxV pairs as
+ there are JPEG components. Omitted ones default to 1x1.
+ * The convert and montage commands now support an -operator command to
+ perform arithmetic and bitwise operations on specified image channels.
+
+Coder additions/improvements
+
+ * The META coder supports wide characters for the IPTC and 8BIM
+ formats.
+ * The XTRN coder now supports wide characters.
+ * An "IMAGE" coder is provided which provides access to a large
+ number of images (derived from XFig) suitable for use as patterns,
+ or as test images.
+ * The "PATTERN" coder now returns an image pattern tiled to size
+ (equivalent results to TILE:IMAGE:pattern). This is for ImageMagick
+ compatibility.
+ * The CINEON coder now supports reading and writing images in CINEON
+ "CIN" linear gray and RGB formats. The read support is still very
+ weak, but it works for common images.
+ * The JPEG coder now estimates the original JPEG quality and sampling
+ factors and will reuse these options when writing JPEG if the image
+ is of the same type and the option "-define JPEG:preserve-settings"
+ is supplied.
+ * The JPEG-2000 coder now supports all Jasper library arguments using
+ command line syntax similar to '-define jp2:rate=0.5'.
+ * Reading and writting compressed SVG (SVGZ) is now supported.
+ * The TXT coder now observes depth when writing.
+ * The TIFF coder now outputs colormapped images with 1, 2, 4, and 8
+ bits per sample in order to provide much smaller file sizes for
+ images with very few colors.
+ * Many TIFF coder enhancements. Now reads colormapped and grayscale
+ images at arbitrary (even odd) bits-per-sample sizes. Now properly
+ supports an opacity channel (at any bits-per-sample value) for
+ grayscale images. Bilevel grayscale images are treated similar to any
+ other grayscale image unless CCITT FAX3/FAX4 compression is
+ requested. Now allows the user to specify an arbitrary
+ bits-per-sample value for grayscale images (even odd values) using
+ "-define tiff:bits-per-sample=value". Now automatically stores the
+ image as TrueColor RGB pixels if the image compression is set to JPEG.
+ TIFF files are now written in using the TIFF library's default endian
+ order rather than always big endian.
+ * The WPG coder now renders embedded WMFs.
+ * The PS3 coder is completely re-written to work much better and
+ support more features (see ChangeLog).
+
+Code structure enhancements:
+
+ * Error handling has been improved and validated through testing.
+ Some errors were being lost, unnecessarily ignored, or reported as
+ something else entirely.
+ * The number of error text messages to be maintained has been reduced
+ by consolidating similar messages.
+ * The memory allocator functions have been replaced with similar
+ macros in order to eliminate warnings with GCC 3.3, avoid
+ accidentally casting away const, and allow memory debuggers to
+ report memory allocations and frees against the correct functions.
+ The previously-used functions remain in the library for the purpose
+ of compatibility.
+ * <magick/xwindow.h> no longer depends on magick_config.h defines.
+ * The text string localization code has been replaced with a simpler
+ version written by Bill Radcliffe.
+ * Added key,value "map" APIs (somewhat similar to C++'s <map>) for
+ internal use.
+
+API enhancements:
+
+ * Incorporated John Cristy's Wand API's in a new GraphicsMagickWand
+ library.
+ * API definition is no longer dependent on types which vary in size
+ (e.g. size_t) depending on large file compilation options. This means
+ that applications may now be compiled without any special large file
+ options and still work properly with the library.
+ * Thrown exceptions (ExceptionInfo structure) now include source
+ file, source line, function name, and current system error number.
+ * The GetMagickInfoArray() function is added to replace use of
+ GetMagickInfo() for code which needs to access the coder list. This
+ is necessary since invoking GetMagickInfo() may re-order the coder
+ list, causing problems for code which traverses the list. Using
+ GetMagickInfo() to access individual list elements is safe.
+ * Added the CopyException function to support copying exception info
+ from one structure to another.
+ * Added the ReplaceImageInList function to replace an image in an
+ image list.
+ * Added the DrawPeekGraphicContext function to access the current
+ DrawInfo structure in the drawing context stack. Use of this
+ function is not recommended since it voilates proper programming
+ practices. It is added to support the Wand API's.
+ * GetImageDepth() now returns an integral value between 1 and
+ QuantumDepth and is no longer limited to the values 8, 16, and 32.
+ * SetImageDepth() supports setting the image modulus depth to any
+ integral value between 1 and QuantumDepth. This effects the effective
+ numeric precision, not the storage depth, since the quantum storage
+ type is still a Quantum.
+ * GetImageChannelDepth() supports retrieving the modulus depth for a
+ specified channel.
+ * SetImageChannelDepth() supports setting the modulus depth for a
+ specified channel.
+ * ProfileImage is updated to handle alpha channels and grayscale
+ images.
+ * Added GetImageProfile() to retrieve a CMS profile from an image.
+ * Added SetImageProfile() to attach a CMS profile to an image without
+ adjusting the image pixels.
+ * Added DeleteImageProfile() to remove a CMS profile from an image.
+ * ConstituteImage() and DispatchImage() now support 'T' (transparency),
+ 'O' (opacity), and 'P' (pad) options.
+ * CompositeImage() now supports CopyCyanCompositeOp,
+ CopyMagentaCompositeOp, CopyYellowCompositeOp, and
+ CopyBlackCompositeOp, composition operators.
+ * GetColorHistogram() obtains a color histogram for the image.
+ * QuantumOperatorImage() and QuantumOperatorRegionImage() support
+ arithmetic and bitwise operations on specified image channels.
+ * The semaphore.h header is no longer installed or included in the
+ API headers since these functions are private interfaces.
+ * Configure using --enable-symbol-prefix or define
+ PREFIX_MAGICK_SYMBOLS to use the C preprocessor to prefix all library
+ symbols with "Gm". This prevents library symbol conflicts with other
+ libraries.
+
+PerlMagick fixes:
+
+ * Adjusted a number of function option names so that they match the
+ documentation.
+ * Memory leak fixed.
+ * Reading files (e.g. GIF) via a file descriptor is fixed.
+
+Build improvements:
+
+ * The TRIO library may be used to provide a replacement for vsnprintf
+ if the C library doesn't provide it. This improves security on old
+ systems.
+ * Configure only configures for C & C++ languages.
+ * Configure now does a better job of figuring out how to build a
+ thread-safe library across multiple operating systems.
+ * Configure incorporates a new mmap() test which tests the
+ functionality which is needed so that mmap() is not unnecessarily
+ rejected on a number of systems. This improves performance for large
+ files on those systems.
+ * Configure/build fixes for IBM's AIX operating system.
+
+Windows-specific improvements:
+
+ * The static install package now uses the "uninstalled"
+ configuration so that it does not depend on the Windows registry in
+ order to run. This allows files from the static install package to
+ be copied to another computer without running an installer.
+ * The executable search path is extended at run-time to include the
+ directory where the CORE DLLs reside in order to ensure that they
+ are found.
+ * Adding the -t option to VisualMagick configure enables building
+ all of the coders into one library in order to save build time and
+ simplify linkage.
+ * The XTRN coder now supports wide characters.
+ * LCMS library updated to version 1.10.
+ * GMDisplay displays a checkerboard pattern behind transparent images.
+ * Support is provided for issuing log messages to the Windows standard
+ logging system.
+ * Project files are now provided for use with Borland C++ Builder 6.0.
+ * Updated LCMS version to 1.12.
+ * Updated FreeType version to 2.1.5.
+ * Updated JBIG-KIT to version 1.5.
+ * Updated libpng to version 1.2.5.
+ * Updated libwmf to version 0.2.8.2.
+ * Updates zlib to version 1.2.1.
+ * ActivePerl 5.8.1 Build 807 now supported.
+ * GraphicsMagick now compiles using Visual Studio .NET 2003.
+
+---------------------------------------------------------------------------
+
+1.0 (Released in May, 2003)
+===========================
+
+GraphicsMagick support services:
+
+ * Master web site at "http://www.GraphicsMagick.org/".
+ * Mailing lists, bug tracking, and forums available via
+ "https://sourceforge.net/projects/graphicsmagick/".
+ * Mercurial Web via "http://hg.code.sf.net/p/graphicsmagick/code/".
+ * Mercurial mirror via SourceForge (find instructions at
+ "http://www.graphicsmagick.org/Hg.html").
+ * FTP via "ftp://ftp.graphicsmagick.org/pub/GraphicsMagick".
+
+Project maintenance improvements:
+
+ * ChangeLog conforms to the GNU standard and all CVS commits include
+ useful log messages.
+ * CVS commit messages posted to graphicsmagick-commit mail list.
+ * CVS commit messages contain CVSWeb URL references.
+
+Footprint changes from ImageMagick:
+
+ * Library -lMagick renamed to -lGraphicsMagick.
+ * Library -lMagick++ renamed to -lGraphicsMagick++.
+ * Utilities consolidated into a single 'gm' utility (e.g. use 'gm
+ convert').
+ * Script Magick-config renamed to GraphicsMagick-config.
+ * Script Magick++-config renamed to GraphicsMagick++-config.
+ * Headers installed under ${PREFIX}/include/GraphicsMagick.
+ * PerlMagick namespace renamed from "Image::Magick" to "Graphics::Magick".
+ * Pkgconfig files GraphicsMagick.pc and GraphicsMagick++.pc are
+ installed in $libdir/pkgconfig to assist pkg-config users.
+ * Coder modules installed to lib/GraphicsMagick-1.0/modules-Q8/coders.
+ * Filter modules installed to lib/GraphicsMagick-1.0/modules-Q8/filters.
+
+Many performance enhancements:
+
+ * Default QuantumDepth is 8 since this is adequate for most purposes
+ and more efficient than 16.
+ * The Magick++ demo (compiled with QuantumDepth=8 and -O2) runs about
+ 1.8X faster under SPARC/Solaris than the same demo with ImageMagick
+ 5.5.4.
+ * Colorspace transformations are much faster.
+ * Grayscale/monochrome image handling is much faster.
+ * PseudoClass image handling is faster.
+ * Text annotations using FreeType are much faster.
+ * Image file I/O is much faster.
+ * RLE-compressed MIFF reading much faster.
+
+Code structure enhancements:
+
+ * All utility support functions moved to magick/command.c in order to
+ significantly reduce link dependencies, allowing statically-linked
+ programs to be smaller.
+ * Use of MogrifyImage() eliminated except for by utilities.
+ * Re-builds due to changes to <magick/image.h> reduced by splitting the
+ header into multiple headers.
+ * ISO C '99 typedefs (gm_int16_t, gm_uint16_t, gm_int32_t, gm_uint32_t,
+ gm_int64_t, gm_uint64_t) are available for use.
+
+Feature enhancements:
+
+ * Module loader always enabled for shared builds to allow extension.
+ * Loading of arbitrary filter modules (via -process option) supported
+ under Unix as well as Windows.
+ * SVG coder allows specifying size and initial background color.
+ * JPEG-2000 coder (JP2) updated to work with Jasper 1.7.
+ * HWB and HSL image colorspace translation support.
+ * JNG/MNG/PNG format support tracks ImageMagick version.
+ * BMP encoder can write 16-color indexed BMPs now as well as 2-color
+ BMPs (not restricted to monochrome).
+ * TIFF decoder now includes optimized support for tiled and stripped
+ TIFF.
+ * The -random-threshold option (RandomThresholdImage()) is added to
+ threshold an image to bilevel using random thresholding.
+
+Major bug fixes:
+
+ * 100% successful test completion at all quantum depths (8/16/32).
+ * A temporary file management subsystem is added to ensure that all
+ temporary files are removed before program exit. Temporary files are
+ created and used in a secure fashion to avoid the possibility that a
+ "trojan" temporary file (e.g. a symbolic link, or a file containing
+ unsafe content) is created before a delegate has the chance to write
+ to it. The environment variable MAGICK_TMPDIR allows the user to
+ specify where temporary files are created without altering where
+ other programs create their temporary files. Temporary filenames are
+ created in 8+3 format to hopefully be more acceptable to ralcgm.
+ * When dithering is disabled, don't dither when converting to a
+ PseudoClass, grayscale, or monochrome image. Disabling dithering
+ may cause these translations to be much faster.
+ * PICON format works with BLOBs.
+ * No longer removes input file when pinging a FlashPIX file.
+ * Arc drawing and texture fill fixes from ImageMagick.
+ * Sample, scale and affine fixes from ImageMagick.
+ * MIFF colormaps are now scaled properly while reading.
+ * CMYK translation works for QuantumDepth=32.
+ * ConstituteImage now works properly for grayscale images.
+ * Built-in tilde expansion and filename globbing now works properly.
+ * InitializeMagick now registers signal handlers to ensure that
+ resources are released before program exit. This helps avoid
+ temporary file leaks due to the user using "CONTROL-C".
+ * The installed <magick/magick_config.h> header now only contains
+ the few definitions required by the API headers. This should
+ significantly reduce or eliminate conflicts with other package
+ headers.
+
+Windows platform enhancements:
+
+ * Configure updated for Visual C++ 7.0.
+ * OLE object (ImageMagickObject) re-written to work with Visual C++ 7.0
+ * New function, CropImageToHBITMAP(), to return a region of the image
+ as a Windows HBITMAP.
+ * Use vsnprintf to format strings under Windows (safer).
+
+---------------------------------------------------------------------------
+
+On November 19, 2002, GraphicsMagick was created as a fork of
+ImageMagick, several days before the ImageMagick 5.5.2 release.
+
+The objectives of GraphicsMagick are to:
+
+ * Use an open development model.
+ * Encourage new developers to join the project.
+ * Avoid unnecessary source code "churn".
+ * Establish and preserve a stable API.
+ * Use efficient coding practices which result in fast code.
+ * Improve memory efficiency.
+ * Use a release process which assures a working product.
+ * Maintain an accurate ChangeLog.
+
+
+---------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/PerlMagick/.gdbinit b/PerlMagick/.gdbinit
new file mode 100644
index 0000000..db4184d
--- /dev/null
+++ b/PerlMagick/.gdbinit
@@ -0,0 +1,4 @@
+$cwd
+$cdir
+dir ../coders
+dir ../magick
diff --git a/PerlMagick/Changelog b/PerlMagick/Changelog
new file mode 100644
index 0000000..45bddd8
--- /dev/null
+++ b/PerlMagick/Changelog
@@ -0,0 +1,125 @@
+Revision history for Perl extension Image::Magick.
+
+4.24 Sat May 15 1999
+ - Added degrees to AnnotateImage() for text rotation.
+4.20 Fri Feb 15 1999
+ - Change the ColorFloodfill() parameters.
+4.19 Fri Feb 01 1999
+ - Changed version to reflect the ImageMagick release #.
+1.58 Fri Jan 01 1999
+ - Added Blob method.
+1.54 Tue Dec 01 1998
+ - Changed XMontageImages method to MontageImages method.
+1.53 Tue Nov 20 1998
+ - Added a call to the new method, GetMagickInfo.
+1.52 Tue Nov 3 1998
+ - Added global_colormap to QuantizeImage. Added methods
+ Stereo and Stegano.
+1.49 Wed Oct 21 1998
+ - AppendImage interface changed.
+1.48 Sun Oct 11 1998
+ - '$im->[1]->Display();' previously would cause a seg fault.
+1.47 Wed Sep 30 1998
+ - Added ColorFloodfill() and MatteFloodfill() methods.
+1.46 Sat Sep 22 1998
+ - This is hopefully the final release for ImageMagick 4.1
+ where Perlmagick passs all 300 regression tests.
+1.45 Sat Sep 12 1998
+ - Revised the suite of tests (thanks to Bob Friesenhahn). For
+ consistency across all methods, you can now say
+ Read(filename=>'image.gif'). Added chromaticity attributes.
+ You can now read/write from a Perl filehandle.
+ Fixed a number of minor bugs and nits.
+1.44 Fri Sep 4 1998
+ - Added a suite of tests (thanks to bfriesen@simple.dallas.tx.us).
+1.43 Thr Aug 27 1998
+ - Added RemoteCommand method to send a command to a remote
+ display program. PerlMagick was not always honoring the
+ adjoin option.
+1.42 Wed Aug 12 1998
+ - Added Transform method to accept a fully-qualified geometry
+ specification for crop and image size.
+1.40 Fri Jul 10 1998
+ - Added new image scaling filters.
+1.38 Mon Jun 8 1998
+ - Added the Append method.
+1.36 Fri May 8 1998
+ - Quantize and Segment methods needed to call SyncImage.
+1.35 Fri Apr 16 1998
+ - version change to match ImageMagick version change
+1.34 Fri Mar 25 1998
+ - you can now specify a color name for pixel set attribute
+1.33 Fri Mar 15 1998
+ - Added view as an image attribute (for FlashPix).
+1.32 Fri Jan 30 1998
+ - Added LayerImage function.
+1.31 Fri Jan 26 1998
+ - added ReplaceRed, ReplaceGreen, ReplaceBlue, and ReplaceMatte
+ composite operators.
+1.30 Fri Dec 24 1997
+ - removed resource->immutable to complete NT port.
+1.29 Fri Dec 20 1997
+ - Fixed a couple of casts to get rid of compiler warnings.
+1.28 Fri Dec 15 1997
+ - AnnotateInfo structure has changed again to fix a memory leak.
+1.27 Fri Dec 05 1997
+ - AnnotateInfo structure has changed.
+1.26 Mon Dec 01 1997
+ - Added support for pen and box for the Set method.
+1.25 Thu Nov 27 1997
+ - Added MogrifyRegion method.
+1.24 Thu Nov 18 1997
+ - Montage method only returned the first image of a sequence
+1.23 Thu Nov 6 1997
+ - Added geometry to method Composite.
+1.22 Thu Oct 30 1997
+ - Changed error status from external int to method SetErrorStatus.
+ - Added a call to SetClientname.
+1.20 Thu Oct 23 1997
+ - fixed WriteImage to conform to the adjoin option
+ - properly initialized ParseImageGeometry to match requirements of
+ ImageMagick 3.9.1
+1.17 Thu Oct 15 1997
+ - Added addition parameters to PingImage.
+1.16 Thu Sep 9 1997
+ - New distribution for CPAN
+1.15 Thu Aug 28 1997
+ - Add PingImage routine
+1.14 Tue Aug 12 1997
+ - Added numeric error handling
+ - Add QueryColors routine
+1.12 Tue June 03 1997
+ - Changed $q->DisplayMethod() to be more robust.
+1.11 Tue June 03 1997
+ - Added $q->animate() method
+1.10 Tue May 20 1997
+ - Access individual pixels of an image; Set('pixel[4,4]'=>'255,255,255')
+1.07 Tue May 06 1997
+ - Clone is an alias of Copy.
+1.05 Fri Apr 25 1997
+ - Added allignment to function Annotate (left, center, right). Requires
+ ImageMagick 3.8.5 to compile.
+1.03 Mon Apr 11 1997
+ - some objects were not being destroyed when dereferenced due to an
+ incorrect reference count.
+1.01 Mon Apr 02 1997
+ - Frame routine faulted if bad parameters were specified.
+1.00 Mon Apr 01 1997
+ - presumably there are no bugs.
+0.94 Wed Mar 12 1997
+ - Micellanous Montage routine fixes (thanks to
+ bfriesen@simple.dallas.tx.us).
+0.93 Mon Mar 10 1997
+ - Fixed segmentation fault from the Montage routine.
+ - Fixed the Set routine to correctly set the page, delay, and dispose
+ image attribute.
+0.92 Sat Mar 01 1997
+ - changed the Draw Operator parameters to make it more intutitive
+ - added non-filled rectangles, circles, and polygons to Draw operator.
+ - added Copy operator
+0.91 Thu Feb. 28 1997
+ - handles individual images of a multi-image sequence
+0.90 Mon Feb. 17 1997
+ - released Alpha version
+0.10 Fri Jan 31 1997
+ - original version; created by h2xs 1.18
diff --git a/PerlMagick/MANIFEST b/PerlMagick/MANIFEST
new file mode 100644
index 0000000..d53af28
--- /dev/null
+++ b/PerlMagick/MANIFEST
@@ -0,0 +1,472 @@
+Changelog
+demo/annotate.pl
+demo/button.pl
+demo/composite.pl
+demo/demo.pl
+demo/Generic.ttf
+demo/lsys.pl
+demo/Makefile
+demo/model.gif
+demo/model.miff
+demo/piddle.pl
+demo/pink_flower.gif
+demo/README
+demo/red_flower.gif
+demo/shadow_text.pl
+demo/shapes.pl
+demo/smile.gif
+demo/steganography.pl
+demo/tile.gif
+demo/tree.pl
+demo/Turtle.pm
+demo/yellow_flower.gif
+Magick.pm
+Magick.pm.in
+Magick.xs
+Makefile.am
+Makefile.nt
+Makefile.PL
+Makefile.PL.in
+MANIFEST This list of files
+MANIFEST.SKIP
+PerlMagickCheck.sh.in
+README.txt
+t/blob.t
+t/bzlib/input.miff
+t/bzlib/input.miff.bz2
+t/bzlib/read.t
+t/bzlib/write.t
+t/cgm/input.cgm
+t/cgm/read.t
+t/composite.t
+t/features.pl.in
+t/filter.t
+t/fpx/input_256.fpx
+t/fpx/input_bw.fpx
+t/fpx/input_grayscale.fpx
+t/fpx/input_jpeg.fpx
+t/fpx/input_truecolor.fpx
+t/fpx/read.t
+t/fpx/write.t
+t/getattribute.t
+t/hdf/input_256.hdf
+t/hdf/input_truecolor.hdf
+t/hdf/read.t
+t/hdf/write.t
+t/hpgl/input.hpgl
+t/hpgl/read.t
+t/input.art
+t/input.avs
+t/input.bie
+t/input.bmp
+t/input.bmp24
+t/input.dcx
+t/input.dib
+t/input.gif
+t/input.gif87
+t/input.hrz
+t/input.ico
+t/input.im1
+t/input.im24
+t/input.im8
+t/input.mac
+t/input.miff
+t/input.mtv
+t/input.p7
+t/input.pam
+t/input.pcx
+t/input.pict
+t/input.psd
+t/input.pxr
+t/input.rle
+t/input.sct
+t/input.sgi
+t/input.tga
+t/input.tim
+t/input.viff
+t/input.wbmp
+t/input.xbm
+t/input.xpm
+t/input.xwd
+t/input1_4.wpg
+t/input1_8_1.wpg
+t/input2_4.wpg
+t/input2_8.wpg
+t/input2_TC1.wpg
+t/input_1555.bmp
+t/input_16.miff
+t/input_16.pct
+t/input_16.tga
+t/input_16rle.tga
+t/input_24.tga
+t/input_24rle.tga
+t/input_32.pct
+t/input_32.tga
+t/input_32rle.tga
+t/input_4444.bmp
+t/input_565.bmp
+t/input_64.pam
+t/input_70x46.cmyk
+t/input_70x46.gray
+t/input_70x46.rgb
+t/input_70x46.rgba
+t/input_70x46.uyvy
+t/input_70x46.yuv
+t/input_888.bmp
+t/input_8888.bmp
+t/input_888flip.bmp
+t/input_complex_lsb_double_V4.mat
+t/input_gray.cin
+t/input_gray.rla
+t/input_gray.rle
+t/input_gray_01bit.palm
+t/input_gray_01bit_rle.palm
+t/input_gray_01bit_scan.palm
+t/input_gray_02bit.palm
+t/input_gray_02bit_rle.palm
+t/input_gray_02bit_scan.palm
+t/input_gray_04bit.palm
+t/input_gray_04bit_rle.palm
+t/input_gray_04bit_scan.palm
+t/input_gray_08bit.fits
+t/input_gray_16bit.fits
+t/input_gray_32bit.fits
+t/input_gray_lsb_08bit.mat
+t/input_gray_lsb_16bit.mat
+t/input_gray_lsb_32bit.mat
+t/input_gray_lsb_double.fits
+t/input_gray_lsb_double.mat
+t/input_gray_lsb_double_V4.mat
+t/input_gray_lsb_float.mat
+t/input_gray_msb_08bit.mat
+t/input_gray_msb_16bit.fits
+t/input_gray_msb_32bit.fits
+t/input_gray_msb_64bit.fits
+t/input_gray_msb_double.fits
+t/input_gray_msb_float.fits
+t/input_jnx.jnx
+t/input_logical_lsb_08bit.mat
+t/input_matte.miff
+t/input_p1.pbm
+t/input_p2.pgm
+t/input_p3.ppm
+t/input_p4.pbm
+t/input_p5.pgm
+t/input_p6.ppm
+t/input_p7.p7
+t/input_rgb.cin
+t/input_rgb.rla
+t/input_rgb.txt
+t/input_rgb_08bit.palm
+t/input_rgb_08bit_cmap.palm
+t/input_rgb_08bit_rle.palm
+t/input_rgb_08bit_scan.palm
+t/input_rgb_08bit_trans.palm
+t/input_rgb_16bit.palm
+t/input_rgb_16bit_rle.palm
+t/input_rgb_16bit_scan.palm
+t/input_rgb_16bit_trans.palm
+t/input_rgb_lsb_08bit.mat
+t/jbig/input.jbig
+t/jbig/read.t
+t/jbig/write.t
+t/jng/input_gray.jng
+t/jng/input_gray_idat.jng
+t/jng/input_gray_jdaa.jng
+t/jng/input_gray_prog.jng
+t/jng/input_gray_prog_idat.jng
+t/jng/input_gray_prog_jdaa.jng
+t/jng/input_idat.jng
+t/jng/input_jdaa.jng
+t/jng/input_prog.jng
+t/jng/input_prog_idat.jng
+t/jng/input_prog_jdaa.jng
+t/jng/input_rose.jng
+t/jng/read.t
+t/jng/write.t
+t/jp2/input.jp2
+t/jp2/input.jpc
+t/jp2/input.pgx
+t/jp2/read.t
+t/jpeg/input.jpg
+t/jpeg/input.sfw
+t/jpeg/input_plane.jpg
+t/jpeg/read.t
+t/jpeg/write.t
+t/MasterImage_70x46.ppm
+t/montage.t
+t/mpeg/input.m2v
+t/mpeg/input.mpg
+t/mpeg/read.t
+t/palm_std_colormap.palm
+t/ping.t
+t/png/input.mng
+t/png/input_16.png
+t/png/input_256.png
+t/png/input_bw.png
+t/png/input_mono.png
+t/png/input_truecolor.png
+t/png/read-16.t
+t/png/read.t
+t/png/write-16.t
+t/png/write.t
+t/ps/input.eps
+t/ps/input.miff
+t/ps/input.ps
+t/ps/read.t
+t/ps/write.t
+t/rad/input.rad
+t/rad/read.t
+t/rad/write.t
+t/read.t
+t/reference/cgm/read.miff
+t/reference/composite/Add.miff
+t/reference/composite/Atop.miff
+t/reference/composite/Bumpmap.miff
+t/reference/composite/Clear.miff
+t/reference/composite/Copy.miff
+t/reference/composite/CopyBlue.miff
+t/reference/composite/CopyGreen.miff
+t/reference/composite/CopyOpacity.miff
+t/reference/composite/CopyRed.miff
+t/reference/composite/Difference.miff
+t/reference/composite/Dissolve.miff
+t/reference/composite/Divide.miff
+t/reference/composite/In.miff
+t/reference/composite/Minus.miff
+t/reference/composite/Multiply.miff
+t/reference/composite/Out.miff
+t/reference/composite/Over.miff
+t/reference/composite/Plus.miff
+t/reference/composite/Subtract.miff
+t/reference/composite/Xor.miff
+t/reference/filter/Blur.miff
+t/reference/filter/Border.miff
+t/reference/filter/Channel.miff
+t/reference/filter/Chop.miff
+t/reference/filter/ColorFloodfill.miff
+t/reference/filter/Colorize.miff
+t/reference/filter/Contrast.miff
+t/reference/filter/Convolve.miff
+t/reference/filter/Crop.miff
+t/reference/filter/Despeckle.miff
+t/reference/filter/Edge.miff
+t/reference/filter/Emboss.miff
+t/reference/filter/Equalize.miff
+t/reference/filter/Flip.miff
+t/reference/filter/Flop.miff
+t/reference/filter/Frame.miff
+t/reference/filter/Gamma.miff
+t/reference/filter/Implode.miff
+t/reference/filter/Magnify.miff
+t/reference/filter/MatteFloodfill.miff
+t/reference/filter/Minify.miff
+t/reference/filter/Modulate.miff
+t/reference/filter/MotionBlur.miff
+t/reference/filter/Negate.miff
+t/reference/filter/Normalize.miff
+t/reference/filter/OilPaint.miff
+t/reference/filter/Opaque.miff
+t/reference/filter/Quantize.miff
+t/reference/filter/Raise.miff
+t/reference/filter/Resize.miff
+t/reference/filter/Roll.miff
+t/reference/filter/Rotate0.miff
+t/reference/filter/Rotate10.miff
+t/reference/filter/Rotate180.miff
+t/reference/filter/Rotate270.miff
+t/reference/filter/Rotate90.miff
+t/reference/filter/Sample.miff
+t/reference/filter/Scale.miff
+t/reference/filter/Segment.miff
+t/reference/filter/Shade.miff
+t/reference/filter/Sharpen.miff
+t/reference/filter/Shave.miff
+t/reference/filter/Shear.miff
+t/reference/filter/Solarize.miff
+t/reference/filter/Swirl.miff
+t/reference/filter/Threshold.miff
+t/reference/filter/Trim.miff
+t/reference/filter/UnsharpMask.miff
+t/reference/filter/Wave.miff
+t/reference/jng/read_gray.miff
+t/reference/jng/read_gray_idat.miff
+t/reference/jng/read_gray_jdaa.miff
+t/reference/jng/read_gray_prog.miff
+t/reference/jng/read_gray_prog_idat.miff
+t/reference/jng/read_gray_prog_jdaa.miff
+t/reference/jng/read_idat.miff
+t/reference/jng/read_jdaa.miff
+t/reference/jng/read_prog.miff
+t/reference/jng/read_prog_idat.miff
+t/reference/jng/read_prog_jdaa.miff
+t/reference/jng/write_gray.miff
+t/reference/jng/write_gray_idat.miff
+t/reference/jng/write_gray_jdaa.miff
+t/reference/jng/write_gray_prog.miff
+t/reference/jng/write_gray_prog_idat.miff
+t/reference/jng/write_gray_prog_jdaa.miff
+t/reference/jng/write_idat.miff
+t/reference/jng/write_jdaa.miff
+t/reference/jng/write_prog.miff
+t/reference/jng/write_prog_idat.miff
+t/reference/jng/write_prog_jdaa.miff
+t/reference/jp2/read_jp2.miff
+t/reference/jp2/read_jpc.miff
+t/reference/jp2/read_pgx.miff
+t/reference/jpeg/read_non_interlaced.miff
+t/reference/jpeg/read_plane_interlaced.miff
+t/reference/jpeg/read_sfw.miff
+t/reference/jpeg/write_non_interlaced.miff
+t/reference/jpeg/write_plane_interlaced.miff
+t/reference/read/gradient.miff
+t/reference/read/granite.miff
+t/reference/read/input1_4_wpg.miff
+t/reference/read/input1_8_1_wpg.miff
+t/reference/read/input2_8_wpg.miff
+t/reference/read/input2_TC1_wpg.miff
+t/reference/read/input_avs.miff
+t/reference/read/input_bmp.miff
+t/reference/read/input_bmp24.miff
+t/reference/read/input_cmyk.miff
+t/reference/read/input_dcx.miff
+t/reference/read/input_dib.miff
+t/reference/read/input_gif.miff
+t/reference/read/input_gif87.miff
+t/reference/read/input_gray.miff
+t/reference/read/input_gray_08bit_fits.miff
+t/reference/read/input_gray_16bit_fits.miff
+t/reference/read/input_gray_32bit_fits.miff
+t/reference/read/input_gray_cin.miff
+t/reference/read/input_gray_lsb_08bit_mat.miff
+t/reference/read/input_gray_lsb_16bit_mat.miff
+t/reference/read/input_gray_lsb_32bit_mat.miff
+t/reference/read/input_gray_lsb_double_fits.miff
+t/reference/read/input_gray_lsb_double_mat.miff
+t/reference/read/input_gray_lsb_double_V4_mat.miff
+t/reference/read/input_gray_lsb_float_mat.miff
+t/reference/read/input_gray_msb_08bit_mat.miff
+t/reference/read/input_gray_msb_16bit_fits.miff
+t/reference/read/input_gray_msb_32bit_fits.miff
+t/reference/read/input_gray_msb_64bit_fits.miff
+t/reference/read/input_gray_msb_double_fits.miff
+t/reference/read/input_gray_msb_float_fits.miff
+t/reference/read/input_gray_rla.miff
+t/reference/read/input_gray_rle.miff
+t/reference/read/input_hrz.miff
+t/reference/read/input_ico.miff
+t/reference/read/input_im1.miff
+t/reference/read/input_im24.miff
+t/reference/read/input_im8.miff
+t/reference/read/input_logical_lsb_08bit_mat.miff
+t/reference/read/input_mac.bmp
+t/reference/read/input_miff.miff
+t/reference/read/input_mtv.miff
+t/reference/read/input_null_black.miff
+t/reference/read/input_null_DarkOrange.miff
+t/reference/read/input_null_white.miff
+t/reference/read/input_p7.miff
+t/reference/read/input_pbm_p1.miff
+t/reference/read/input_pbm_p4.miff
+t/reference/read/input_pcx.miff
+t/reference/read/input_pgm_p2.miff
+t/reference/read/input_pgm_p5.miff
+t/reference/read/input_pict.miff
+t/reference/read/input_ppm_p3.miff
+t/reference/read/input_ppm_p6.miff
+t/reference/read/input_psd.miff
+t/reference/read/input_rgb.miff
+t/reference/read/input_rgb_cin.miff
+t/reference/read/input_rgb_lsb_08bit_mat.miff
+t/reference/read/input_rgb_rla.miff
+t/reference/read/input_rgba.miff
+t/reference/read/input_rle.miff
+t/reference/read/input_sgi.miff
+t/reference/read/input_tga.miff
+t/reference/read/input_tile.miff
+t/reference/read/input_tim.miff
+t/reference/read/input_uyvy.miff
+t/reference/read/input_viff.miff
+t/reference/read/input_wbmp.miff
+t/reference/read/input_xbm.miff
+t/reference/read/input_xc_black.miff
+t/reference/read/input_xpm.miff
+t/reference/read/input_xwd.miff
+t/reference/read/topol_1.miff
+t/reference/read/topol_2.miff
+t/reference/read/topol_3.miff
+t/reference/read/topol_4.miff
+t/reference/read/topol_5.miff
+t/reference/read/topol_7.miff
+t/reference/ttf/annotate.miff
+t/reference/ttf/label.miff
+t/reference/ttf/read.miff
+t/reference/wmf/clock.miff
+t/reference/wmf/fjftest.miff
+t/reference/wmf/ski.miff
+t/reference/wmf/wizard.miff
+t/reference/write/output_p7.miff
+t/setattribute.t
+t/subroutines.pl
+t/tiff/input_gray_01bit_minwhite.cals
+t/tiff/input_gray_01bit_minwhite.tiff
+t/tiff/input_gray_04bit.tiff
+t/tiff/input_gray_04bit_matte.tiff
+t/tiff/input_gray_08bit.tiff
+t/tiff/input_gray_08bit_matte.tiff
+t/tiff/input_gray_10bit.tiff
+t/tiff/input_gray_12bit.tiff
+t/tiff/input_gray_14bit.tiff
+t/tiff/input_gray_16bit.tiff
+t/tiff/input_gray_32bit.tiff
+t/tiff/input_palette_16.tiff
+t/tiff/input_palette_16_matte.tiff
+t/tiff/input_palette_256.tiff
+t/tiff/input_palette_256_matte.tiff
+t/tiff/input_palette_256_planar_contig.tiff
+t/tiff/input_palette_256_planar_separate.tiff
+t/tiff/input_truecolor_08.tiff
+t/tiff/input_truecolor_08_matte.tiff
+t/tiff/input_truecolor_08_planar.tiff
+t/tiff/input_truecolor_08_stripped.tiff
+t/tiff/input_truecolor_08_tiled32x32.tiff
+t/tiff/input_truecolor_10.tiff
+t/tiff/input_truecolor_12.tiff
+t/tiff/input_truecolor_14.tiff
+t/tiff/input_truecolor_16.tiff
+t/tiff/input_truecolor_32.tiff
+t/tiff/read.t
+t/tiff/write.t
+t/topol_1.mez
+t/topol_1.ras
+t/topol_2.mez
+t/topol_2.pal
+t/topol_2.ras
+t/topol_3.mez
+t/topol_3.ras
+t/topol_4.mez
+t/topol_4.pal
+t/topol_4.ras
+t/topol_5.ras
+t/topol_7.mez
+t/topol_7.ras
+t/ttf/input.ttf
+t/ttf/read.t
+t/wmf/clock.wmf
+t/wmf/fjftest.wmf
+t/wmf/read.t
+t/wmf/ski.wmf
+t/wmf/wizard.wmf
+t/write.t
+t/x/congrats.fig
+t/x/congrats.miff
+t/x/read.t
+t/x/write.t
+t/xfig/input.fig
+t/xfig/read.t
+t/zlib/input.miff
+t/zlib/input.miff.gz
+t/zlib/input_gray_lsb_08bit_zip.mat
+t/zlib/read.t
+t/zlib/write.t
+typemap
diff --git a/PerlMagick/MANIFEST.SKIP b/PerlMagick/MANIFEST.SKIP
new file mode 100644
index 0000000..f90b4df
--- /dev/null
+++ b/PerlMagick/MANIFEST.SKIP
@@ -0,0 +1,11 @@
+.*\.gdbinit$
+.*core$
+Makefile.old$
+\.bak$
+\.old$
+^Makefile$
+~$
+\.orig$
+\.o$
+\.bak$
+^build_manifest\.sh$
diff --git a/PerlMagick/Magick.pm b/PerlMagick/Magick.pm
new file mode 100644
index 0000000..dc171d7
--- /dev/null
+++ b/PerlMagick/Magick.pm
@@ -0,0 +1,133 @@
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1998,1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+
+package Graphics::Magick;
+
+# Released Feb. 17, 1997 by Kyle Shorter (magick@wizards.dupont.com)
+# Public Domain
+
+use strict;
+use Carp;
+use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);
+
+require 5.002;
+require Exporter;
+require DynaLoader;
+require AutoLoader;
+
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+@EXPORT =
+ qw(
+ Success Transparent Opaque MaxRGB WarningException
+ ResourceLimitWarning TypeWarning OptionWarning DelegateWarning
+ MissingDelegateWarning CorruptImageWarning FileOpenWarning
+ BlobWarning StreamWarning CacheWarning CoderWarning ModuleWarning
+ DrawWarning ImageWarning XServerWarning RegistryWarning
+ ConfigureWarning ErrorException ResourceLimitError TypeError
+ OptionError DelegateError MissingDelegateError CorruptImageError
+ FileOpenError BlobError StreamError CacheError CoderError
+ ModuleError DrawError ImageError XServerError RegistryError
+ ConfigureError FatalErrorException
+ );
+
+# This version identifier must match the package version.
+$VERSION = '1.3.26';
+
+sub AUTOLOAD {
+ # This AUTOLOAD is used to 'autoload' constants from the constant()
+ # XS function. If a constant is not found then control is passed
+ # to the AUTOLOAD in AutoLoader.
+
+ my $constname;
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ my $val = constant($constname, @_ ? $_[0] : 0);
+ if ($! != 0) {
+ if ($! =~ /Invalid/) {
+ $AutoLoader::AUTOLOAD = $AUTOLOAD;
+ goto &AutoLoader::AUTOLOAD;
+ }
+ else {
+ my($pack,$file,$line) = caller;
+ die "Your vendor has not defined PerlMagick macro $pack\:\:$constname, used at $file line $line.\n";
+ }
+ }
+ eval "sub $AUTOLOAD { $val }";
+ goto &$AUTOLOAD;
+}
+
+bootstrap Graphics::Magick $VERSION;
+
+# Preloaded methods go here.
+
+sub new
+{
+ my $this = shift;
+ my $class = ref($this) || $this || "Graphics::Magick";
+ my $self = [ ];
+ bless $self, $class;
+ $self->set(@_) if @_;
+ return $self;
+}
+
+sub New
+{
+ my $this = shift;
+ my $class = ref($this) || $this || "Graphics::Magick";
+ my $self = [ ];
+ bless $self, $class;
+ $self->set(@_) if @_;
+ return $self;
+}
+
+# Autoload methods go after =cut, and are processed by the autosplit program.
+
+1;
+__END__
+
+=head1 NAME
+
+Graphics::Magick - Perl extension for calling GraphicsMagick's libGraphicsMagick routines
+
+=head1 SYNOPSIS
+
+ use Graphics::Magick;
+ p = new Graphics::Magick;
+ p->Read("imagefile");
+ p->Set(attribute => value, ...)
+ ($a, ...) = p->Get("attribute", ...)
+ p->routine(parameter => value, ...)
+ p->Mogrify("Routine", parameter => value, ...)
+ p->Write("filename");
+
+=head1 DESCRIPTION
+
+This Perl extension allows the reading, manipulation and writing of
+a large number of image file formats using the GraphicsMagick library.
+It was originally developed to be used by CGI scripts for Web pages.
+
+A Web page has been set up for this extension. See:
+
+ http://www.GraphicsMagick.org/www/perl.html
+
+=head1 AUTHOR
+
+Kyle Shorter magick@wizards.dupont.com
+
+=head1 BUGS
+
+Has all the bugs of GraphicsMagick and much, much more!
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut
diff --git a/PerlMagick/Magick.pm.in b/PerlMagick/Magick.pm.in
new file mode 100644
index 0000000..b572d6b
--- /dev/null
+++ b/PerlMagick/Magick.pm.in
@@ -0,0 +1,133 @@
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1998,1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+
+package Graphics::Magick;
+
+# Released Feb. 17, 1997 by Kyle Shorter (magick@wizards.dupont.com)
+# Public Domain
+
+use strict;
+use Carp;
+use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);
+
+require 5.002;
+require Exporter;
+require DynaLoader;
+require AutoLoader;
+
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+@EXPORT =
+ qw(
+ Success Transparent Opaque MaxRGB WarningException
+ ResourceLimitWarning TypeWarning OptionWarning DelegateWarning
+ MissingDelegateWarning CorruptImageWarning FileOpenWarning
+ BlobWarning StreamWarning CacheWarning CoderWarning ModuleWarning
+ DrawWarning ImageWarning XServerWarning RegistryWarning
+ ConfigureWarning ErrorException ResourceLimitError TypeError
+ OptionError DelegateError MissingDelegateError CorruptImageError
+ FileOpenError BlobError StreamError CacheError CoderError
+ ModuleError DrawError ImageError XServerError RegistryError
+ ConfigureError FatalErrorException
+ );
+
+# This version identifier must match the package version.
+$VERSION = '@PACKAGE_VERSION@';
+
+sub AUTOLOAD {
+ # This AUTOLOAD is used to 'autoload' constants from the constant()
+ # XS function. If a constant is not found then control is passed
+ # to the AUTOLOAD in AutoLoader.
+
+ my $constname;
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ my $val = constant($constname, @_ ? $_[0] : 0);
+ if ($! != 0) {
+ if ($! =~ /Invalid/) {
+ $AutoLoader::AUTOLOAD = $AUTOLOAD;
+ goto &AutoLoader::AUTOLOAD;
+ }
+ else {
+ my($pack,$file,$line) = caller;
+ die "Your vendor has not defined PerlMagick macro $pack\:\:$constname, used at $file line $line.\n";
+ }
+ }
+ eval "sub $AUTOLOAD { $val }";
+ goto &$AUTOLOAD;
+}
+
+bootstrap Graphics::Magick $VERSION;
+
+# Preloaded methods go here.
+
+sub new
+{
+ my $this = shift;
+ my $class = ref($this) || $this || "Graphics::Magick";
+ my $self = [ ];
+ bless $self, $class;
+ $self->set(@_) if @_;
+ return $self;
+}
+
+sub New
+{
+ my $this = shift;
+ my $class = ref($this) || $this || "Graphics::Magick";
+ my $self = [ ];
+ bless $self, $class;
+ $self->set(@_) if @_;
+ return $self;
+}
+
+# Autoload methods go after =cut, and are processed by the autosplit program.
+
+1;
+__END__
+
+=head1 NAME
+
+Graphics::Magick - Perl extension for calling GraphicsMagick's libGraphicsMagick routines
+
+=head1 SYNOPSIS
+
+ use Graphics::Magick;
+ p = new Graphics::Magick;
+ p->Read("imagefile");
+ p->Set(attribute => value, ...)
+ ($a, ...) = p->Get("attribute", ...)
+ p->routine(parameter => value, ...)
+ p->Mogrify("Routine", parameter => value, ...)
+ p->Write("filename");
+
+=head1 DESCRIPTION
+
+This Perl extension allows the reading, manipulation and writing of
+a large number of image file formats using the GraphicsMagick library.
+It was originally developed to be used by CGI scripts for Web pages.
+
+A Web page has been set up for this extension. See:
+
+ http://www.GraphicsMagick.org/www/perl.html
+
+=head1 AUTHOR
+
+Kyle Shorter magick@wizards.dupont.com
+
+=head1 BUGS
+
+Has all the bugs of GraphicsMagick and much, much more!
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut
diff --git a/PerlMagick/Magick.xs b/PerlMagick/Magick.xs
new file mode 100644
index 0000000..2e366cd
--- /dev/null
+++ b/PerlMagick/Magick.xs
@@ -0,0 +1,8017 @@
+/*
+% Copyright (C) 2003 - 2014 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% PPPP EEEEE RRRR L %
+% P P E R R L %
+% PPPP EEE RRRR L %
+% P E R R L %
+% P EEEEE R R LLLLL %
+% %
+% M M AAA GGGG IIIII CCCC K K %
+% MM MM A A G I C K K %
+% M M M AAAAA G GGG I C KKK %
+% M M A A G G I C K K %
+% M M A A GGGG IIIII CCCC K K %
+% %
+% %
+% Object-oriented Perl interface to GraphicsMagick %
+% %
+% %
+% Software Design %
+% Kyle Shorter %
+% John Cristy %
+% February 1997 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PerlMagick is an objected-oriented Perl interface to GraphicsMagick. Use
+% the module to read, manipulate, or write an image or image sequence from
+% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#define MAGICK_IMPLEMENTATION 1
+#if !defined(WIN32)
+#define MagickExport
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define PERL_NO_GET_CONTEXT /* faster */
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include <math.h>
+#define MAGICK_IMPLEMENTATION 1
+#include <magick/api.h>
+#include <magick/locale_c.h>
+#undef tainted
+#if !defined(WIN32)
+#include <setjmp.h>
+#else
+#undef setjmp
+#undef longjmp
+#include <setjmpex.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ Define declarations.
+*/
+#define ArrayReference (char **) 4
+#ifndef aTHX_
+#define aTHX_
+#define pTHX_
+#define dTHX
+#endif
+#define DegreesToRadians(x) ((x)*3.14159265358979323846/180.0)
+#define DoubleReference (char **) 2
+#define EndOf(array) (&array[NumberOf(array)])
+#define False 0
+#define ImageReference (char **) 3
+#define IntegerReference (char **) 1
+#define MaxArguments 28
+#define MY_CXT_KEY PackageName "::ContextKey_" XS_VERSION
+#ifndef START_MY_CXT
+#define MY_CXT_INIT
+#define MY_CXT my_cxt
+#define dMY_CXT
+#endif
+#ifndef na
+#define na PL_na
+#endif
+#define NumberOf(array) (sizeof(array)/sizeof(*array))
+#define PackageName "Graphics::Magick"
+#ifndef PerlIO_findFILE
+#define PerlIO_findFILE(f) (FILE *) (f)
+#endif
+#define StringReference (char **) 0
+#ifndef sv_undef
+#define sv_undef PL_sv_undef
+#endif
+#define True 1
+
+/*
+ Typedef and structure declarations.
+*/
+typedef struct _Arguments
+{
+ char
+ *method,
+ **type;
+} Arguments;
+
+struct ArgumentList
+{
+ long
+ int_reference;
+
+ double
+ double_reference;
+
+ char
+ *string_reference;
+
+ Image
+ *image_reference;
+
+ SV
+ *array_reference;
+
+ size_t
+ length;
+};
+
+typedef struct _my_cxt_t
+{
+ jmp_buf
+ *error_jump; /* long jump return for FATAL errors */
+
+ SV
+ *error_list; /* Perl variable for storing messages */
+} my_cxt_t;
+
+struct PackageInfo
+{
+ ImageInfo
+ *image_info;
+
+ DrawInfo
+ *draw_info;
+
+ QuantizeInfo
+ *quantize_info;
+};
+
+typedef void
+ *Graphics__Magick; /* data type for the Graphics::Magick package */
+
+/*
+ Static declarations. The strings in this list must be expressed
+ in the exact same order as the equivalent enumeration.
+*/
+static char
+ *AlignTypes[] =
+ {
+ "Undefined", "Left", "Center", "Right", (char *) NULL
+ },
+ *BooleanTypes[] =
+ {
+ "False", "True", (char *) NULL
+ },
+ *ChannelTypes[] =
+ {
+ "Undefined", "Red", "Cyan", "Green", "Magenta", "Blue", "Yellow",
+ "Opacity", "Black", "Matte", "All", "Gray", (char *) NULL
+ },
+ *ClassTypes[] =
+ {
+ "Undefined", "DirectClass", "PseudoClass", (char *) NULL
+ },
+ *ColorspaceTypes[] =
+ {
+ "Undefined", "RGB", "Gray", "Transparent", "OHTA", "XYZ", "YCC",
+ "YIQ", "YPbPr", "YUV", "CMYK", "sRGB", "HSL", "HWB", "LAB", "CineonLog",
+ "Rec601Luma", "Rec601YCbCr", "Rec709Luma", "Rec709YCbCr", (char *) NULL
+ },
+ *CompositeTypes[] =
+ {
+ "Undefined", "Over", "In", "Out", "Atop", "Xor", "Plus", "Minus",
+ "Add", "Subtract", "Difference", "Multiply", "Bumpmap", "Copy",
+ "CopyRed", "CopyGreen", "CopyBlue", "CopyOpacity", "Clear", "Dissolve",
+ "Displace", "Modulate", "Threshold", "No", "Darken", "Lighten",
+ "Hue", "Saturate", "Colorize", "Luminize", "Screen", "Overlay",
+ "CopyCyan", "CopyMagenta", "CopyYellow", "CopyBlack", "Divide",
+ "HardLight", "Exclusion", "ColorDodge", "ColorBurn", "SoftLight",
+ "LinearBurn", "LinearDodge", "LinearLight", "VividLight", "PinLight",
+ "HardMix",
+ (char *) NULL
+ },
+ *CompressionTypes[] =
+ {
+ "Undefined", "None", "BZip", "Fax", "Group4", "JPEG", "LosslessJPEG",
+ "LZW", "RLE", "Zip", "LZMA", "JPEG2000", "JBIG1", "JBIG2", (char *) NULL
+ },
+ *DisposeTypes[] =
+ {
+ "Undefined", "None", "Background", "Previous", (char *) NULL
+ },
+ *EndianTypes[] =
+ {
+ "Undefined", "LSB", "MSB", "Native", (char *) NULL
+ },
+ *FilterTypess[] =
+ {
+ "Undefined", "Point", "Box", "Triangle", "Hermite", "Hanning",
+ "Hamming", "Blackman", "Gaussian", "Quadratic", "Cubic", "Catrom",
+ "Mitchell", "Lanczos", "Bessel", "Sinc", (char *) NULL
+ },
+ *GravityTypes[] =
+ {
+ "Forget", "NorthWest", "North", "NorthEast", "West", "Center",
+ "East", "SouthWest", "South", "SouthEast", "Static", (char *) NULL
+ },
+ *ImageTypes[] =
+ {
+ "Undefined", "Bilevel", "Grayscale", "GrayscaleMatte", "Palette",
+ "PaletteMatte", "TrueColor", "TrueColorMatte", "ColorSeparation",
+ "ColorSeparationMatte", "Optimize", (char *) NULL
+ },
+ *IntentTypes[] =
+ {
+ "Undefined", "Saturation", "Perceptual", "Absolute", "Relative",
+ (char *) NULL
+ },
+ *InterlaceTypes[] =
+ {
+ "Undefined", "None", "Line", "Plane", "Partition", (char *) NULL
+ },
+ *LogEventTypes[] =
+ {
+ "No", "Configure", "Annotate", "Render", "Transform", "Locale",
+ "Coder", "X11", "Cache", "Blob", "Deprecate", "User", "Resource",
+ "TemporaryFile", "Exception", "All", (char *) NULL
+ },
+ *MethodTypes[] =
+ {
+ "Point", "Replace", "Floodfill", "FillToBorder", "Reset", (char *) NULL
+ },
+ *ModeTypes[] =
+ {
+ "Undefined", "Frame", "Unframe", "Concatenate", (char *) NULL
+ },
+ *NoiseTypes[] =
+ {
+ "Uniform", "Gaussian", "Multiplicative", "Impulse", "Laplacian",
+ "Poisson", "Random", (char *) NULL
+ },
+ *PreviewTypes[] =
+ {
+ "Undefined", "Rotate", "Shear", "Roll", "Hue", "Saturation",
+ "Brightness", "Gamma", "Spiff", "Dull", "Grayscale", "Quantize",
+ "Despeckle", "ReduceNoise", "AddNoise", "Sharpen", "Blur",
+ "Threshold", "EdgeDetect", "Spread", "Solarize", "Shade", "Raise",
+ "Segment", "Swirl", "Implode", "Wave", "OilPaint", "Charcoal",
+ "JPEG", (char *) NULL
+ },
+ *PrimitiveTypes[] =
+ {
+ "Undefined", "point", "line", "rectangle", "roundRectangle", "arc",
+ "ellipse", "circle", "polyline", "polygon", "bezier", "path", "color",
+ "matte", "text", "image", (char *) NULL
+ },
+ *ResolutionTypes[] =
+ {
+ "Undefined", "PixelsPerInch", "PixelsPerCentimeter", (char *) NULL
+ },
+ *StretchTypes[] =
+ {
+ "Normal", "UltraCondensed", "ExtraCondensed", "Condensed",
+ "SemiCondensed", "SemiExpanded", "Expanded", "ExtraExpanded",
+ "UltraExpanded", "Any", (char *) NULL
+ },
+ *StyleTypes[] =
+ {
+ "Normal", "Italic", "Oblique", "Any", (char *) NULL
+ },
+ *VirtualPixelMethods[] =
+ {
+ "Undefined", "", "Constant", "Edge", "Mirror", "Tile",
+ (char *) NULL
+ };
+
+static struct
+ Methods
+ {
+ char
+ *name;
+
+ Arguments
+ arguments[MaxArguments];
+ } Methods[] =
+ {
+ { "comment", { {"comment", StringReference} } },
+ { "label", { {"label", StringReference} } },
+ { "AddNoise", { {"noise", NoiseTypes} } },
+ { "Colorize", { {"fill", StringReference}, {"opacity", StringReference} } },
+ { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference}, {"fill", StringReference},
+ {"color", StringReference} } },
+ { "Blur", { {"geometry", StringReference}, {"radius", DoubleReference},
+ {"sigma", DoubleReference} } },
+ { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference}, {"x", IntegerReference},
+ {"y", IntegerReference} } },
+ { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference}, {"x", IntegerReference},
+ {"y", IntegerReference} } },
+ { "Despeckle", },
+ { "Edge", { {"radius", DoubleReference} } },
+ { "Emboss", { {"geometry", StringReference}, {"radius", DoubleReference},
+ {"sigma", DoubleReference} } },
+ { "Enhance", },
+ { "Flip", },
+ { "Flop", },
+ { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference}, {"inner", IntegerReference},
+ {"outer", IntegerReference}, {"fill", StringReference},
+ {"color", StringReference} } },
+ { "Implode", { {"amount", DoubleReference} } },
+ { "Magnify", },
+ { "MedianFilter", { {"radius", DoubleReference} } },
+ { "Minify", },
+ { "OilPaint", { {"radius", DoubleReference} } },
+ { "ReduceNoise", { {"radius", DoubleReference} } },
+ { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
+ {"y", IntegerReference} } },
+ { "Rotate", { {"degrees", DoubleReference},
+ {"color", StringReference} } },
+ { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference} } },
+ { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference} } },
+ { "Shade", { {"geometry", StringReference}, {"azimuth", DoubleReference},
+ {"elevation", DoubleReference}, {"gray", BooleanTypes} } },
+ { "Sharpen", { {"geometry", StringReference}, {"radius", DoubleReference},
+ {"sigma", DoubleReference} } },
+ { "Shear", { {"geometry", StringReference}, {"x", IntegerReference},
+ {"y", DoubleReference}, {"color", StringReference} } },
+ { "Spread", { {"radius", IntegerReference} } },
+ { "Swirl", { {"degrees", DoubleReference} } },
+ { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference}, {"filter", FilterTypess},
+ {"blur", DoubleReference } } },
+ { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference}, {"filter", FilterTypess},
+ {"blur", DoubleReference } } },
+ { "Annotate", { {"text", StringReference}, {"font", StringReference},
+ {"point", DoubleReference}, {"density", StringReference},
+ {"undercolor", StringReference}, {"stroke", StringReference},
+ {"fill", StringReference}, {"geometry", StringReference},
+ {"sans", StringReference}, {"x", IntegerReference},
+ {"y", IntegerReference}, {"gravity", GravityTypes},
+ {"translate", StringReference}, {"scale", StringReference},
+ {"rotate", DoubleReference}, {"skewX", DoubleReference},
+ {"skewY", DoubleReference}, {"strokewidth", IntegerReference},
+ {"antialias", BooleanTypes}, {"family", StringReference},
+ {"style", StyleTypes}, {"stretch", StretchTypes},
+ {"weight", IntegerReference}, {"align", AlignTypes},
+ {"encoding", StringReference}, {"affine", ArrayReference} } },
+ { "ColorFloodfill", { {"geometry", StringReference},
+ {"x", IntegerReference}, {"y", IntegerReference},
+ {"fill", StringReference}, {"bordercolor", StringReference},
+ {"fuzz", DoubleReference} } },
+ { "Composite", { {"image", ImageReference}, {"compose", CompositeTypes},
+ {"geometry", StringReference}, {"x", IntegerReference},
+ {"y", IntegerReference}, {"gravity", GravityTypes},
+ {"opacity", DoubleReference}, {"tile", BooleanTypes},
+ {"rotate", DoubleReference}, {"color", StringReference},
+ {"mask", ImageReference} } },
+ { "Contrast", { {"sharp", BooleanTypes} } },
+ { "CycleColormap", { {"display", IntegerReference} } },
+ { "Draw", { {"primitive", PrimitiveTypes}, {"points", StringReference},
+ {"method", MethodTypes}, {"stroke", StringReference},
+ {"fill", StringReference}, {"strokewidth", DoubleReference},
+ {"font", StringReference}, {"bordercolor", StringReference},
+ {"x", DoubleReference}, {"y", DoubleReference},
+ {"translate", StringReference}, {"scale", StringReference},
+ {"rotate", DoubleReference}, {"skewX", DoubleReference},
+ {"skewY", DoubleReference}, {"tile", ImageReference},
+ {"pointsize", DoubleReference}, {"antialias", BooleanTypes},
+ {"density", StringReference}, {"linewidth", DoubleReference},
+ {"affine", ArrayReference} } },
+ { "Equalize", },
+ { "Gamma", { {"gamma", StringReference}, {"red", DoubleReference},
+ {"green", DoubleReference}, {"blue", DoubleReference} } },
+ { "Map", { {"image", ImageReference}, {"dither", BooleanTypes} } },
+ { "MatteFloodfill", { {"geometry", StringReference},
+ {"x", IntegerReference}, {"y", IntegerReference},
+ {"opacity", IntegerReference}, {"bordercolor", StringReference},
+ {"fuzz", DoubleReference} } },
+ { "Modulate", { {"factor", StringReference}, {"bright", DoubleReference},
+ {"saturation", DoubleReference}, {"hue", DoubleReference} } },
+ { "Negate", { {"gray", BooleanTypes} } },
+ { "Normalize", },
+ { "NumberColors", },
+ { "Opaque", { {"color", StringReference}, {"fill", StringReference},
+ {"fuzz", DoubleReference} } },
+ { "Quantize", { {"colors", IntegerReference}, {"tree", IntegerReference},
+ {"colorspace", ColorspaceTypes}, {"dither", BooleanTypes},
+ {"measure", BooleanTypes}, {"global", BooleanTypes} } },
+ { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference}, {"raise", BooleanTypes} } },
+ { "Segment", { {"geometry", StringReference}, {"cluster", DoubleReference},
+ {"smooth", DoubleReference}, {"colorspace", ColorspaceTypes},
+ {"verbose", BooleanTypes} } },
+ { "Signature", },
+ { "Solarize", { {"threshold", DoubleReference} } },
+ { "Sync", },
+ { "Texture", { {"texture", ImageReference} } },
+ { "Sans", { {"geometry", StringReference}, {"crop", StringReference},
+ {"filter", FilterTypess} } },
+ { "Transparent", { {"color", StringReference},
+ {"opacity", IntegerReference}, {"fuzz", DoubleReference} } },
+ { "Threshold", { {"threshold", StringReference} } },
+ { "Charcoal", { {"geometry", StringReference}, {"radius", DoubleReference},
+ {"sigma", DoubleReference} } },
+ { "Trim", { {"fuzz", DoubleReference} } },
+ { "Wave", { {"geometry", StringReference}, {"amplitude", DoubleReference},
+ {"wavelength", DoubleReference} } },
+ { "Channel", { {"channel", ChannelTypes} } },
+ { "Condense", },
+ { "Stereo", { {"image", ImageReference} } },
+ { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
+ { "Deconstruct", },
+ { "GaussianBlur", { {"geometry", StringReference},
+ {"radius", DoubleReference}, {"sigma", DoubleReference} } },
+ { "Convolve", { {"coefficients", ArrayReference} } },
+ { "Profile", { {"name", StringReference}, {"profile", StringReference} } },
+ { "UnsharpMask", { {"geometry", StringReference},
+ {"radius", DoubleReference}, {"sigma", DoubleReference},
+ {"amount", DoubleReference}, {"threshold", DoubleReference} } },
+ { "MotionBlur", { {"geometry", StringReference},
+ {"radius", DoubleReference}, {"sigma", DoubleReference},
+ {"angle", DoubleReference} } },
+ { "OrderedDither", },
+ { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
+ {"height", IntegerReference} } },
+ { "Level", { {"level", StringReference}, {"black-point", DoubleReference},
+ {"mid-point", DoubleReference}, {"white-point", DoubleReference} } },
+ { "Clip", },
+ { "AffineTransform", { {"affine", ArrayReference},
+ {"translate", StringReference}, {"scale", StringReference},
+ {"rotate", DoubleReference}, {"skewX", DoubleReference},
+ {"skewY", DoubleReference} } },
+ { "Compare", { {"image", ImageReference} } },
+ { "AdaptiveThreshold", { {"geometry", StringReference},
+ {"width", IntegerReference}, {"height", IntegerReference},
+ {"offset", IntegerReference} } },
+ };
+
+#ifdef START_MY_CXT
+ START_MY_CXT
+#else
+ static my_cxt_t
+ my_cxt = { (jmp_buf *) NULL, (SV *) NULL };
+#endif
+
+/*
+ Forward declarations.
+*/
+static Image
+ *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***);
+
+static int
+ strEQcase(const char *,const char *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e P a c k a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ClonePackageInfo makes a duplicate of the given info, or if info is
+% NULL, a new one.
+%
+% The format of the ClonePackageInfo routine is:
+%
+% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info)
+%
+% A description of each parameter follows:
+%
+% o clone_info: Method ClonePackageInfo returns a duplicate of the given
+% info, or if info is NULL, a new one.
+%
+% o info: a structure of type info.
+%
+%
+*/
+static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info)
+{
+ struct PackageInfo
+ *clone_info;
+
+ clone_info=MagickAllocateMemory(struct PackageInfo *,sizeof(struct PackageInfo));
+ if (!info)
+ {
+ clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
+ clone_info->draw_info=
+ CloneDrawInfo(clone_info->image_info,(DrawInfo *) NULL);
+ clone_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
+ return(clone_info);
+ }
+ *clone_info=(*info);
+ clone_info->image_info=CloneImageInfo(info->image_info);
+ clone_info->draw_info=CloneDrawInfo(info->image_info,info->draw_info);
+ clone_info->quantize_info=CloneQuantizeInfo(info->quantize_info);
+ return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% c o n s t a n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method constant returns a double value for the specified name.
+%
+% The format of the constant routine is:
+%
+% double constant(char *name,int sans)
+%
+% A description of each parameter follows:
+%
+% o value: Method constant returns a double value for the specified name.
+%
+% o name: The name of the constant.
+%
+% o sans: This integer value is not used.
+%
+%
+*/
+static double constant(char *name,int sans)
+{
+ (void) sans;
+
+ errno=0;
+ switch (*name)
+ {
+ case 'B':
+ {
+ if (strEQ(name,"BlobError"))
+ return(BlobError);
+ if (strEQ(name,"BlobWarning"))
+ return(BlobWarning);
+ break;
+ }
+ case 'C':
+ {
+ if (strEQ(name,"CacheError"))
+ return(CacheError);
+ if (strEQ(name,"CacheWarning"))
+ return(CacheWarning);
+ if (strEQ(name,"CoderError"))
+ return(CoderError);
+ if (strEQ(name,"CoderWarning"))
+ return(CoderWarning);
+ if (strEQ(name,"ConfigureError"))
+ return(ConfigureError);
+ if (strEQ(name,"ConfigureWarning"))
+ return(ConfigureWarning);
+ if (strEQ(name,"CorruptImageError"))
+ return(CorruptImageError);
+ if (strEQ(name,"CorruptImageWarning"))
+ return(CorruptImageWarning);
+ break;
+ }
+ case 'D':
+ {
+ if (strEQ(name,"DelegateError"))
+ return(DelegateError);
+ if (strEQ(name,"DelegateWarning"))
+ return(DelegateWarning);
+ if (strEQ(name,"DrawError"))
+ return(DrawError);
+ if (strEQ(name,"DrawWarning"))
+ return(DrawWarning);
+ break;
+ }
+ case 'E':
+ {
+ if (strEQ(name,"ErrorException"))
+ return(ErrorException);
+ break;
+ }
+ case 'F':
+ {
+ if (strEQ(name,"FatalErrorException"))
+ return(FatalErrorException);
+ if (strEQ(name,"FileOpenError"))
+ return(FileOpenError);
+ if (strEQ(name,"FileOpenWarning"))
+ return(FileOpenWarning);
+ break;
+ }
+ case 'I':
+ {
+ if (strEQ(name,"ImageError"))
+ return(ImageError);
+ if (strEQ(name,"ImageWarning"))
+ return(ImageWarning);
+ break;
+ }
+ case 'M':
+ {
+ if (strEQ(name,"MaxRGB"))
+ return(MaxRGB);
+ if (strEQ(name,"MissingDelegateError"))
+ return(MissingDelegateError);
+ if (strEQ(name,"MissingDelegateWarning"))
+ return(MissingDelegateWarning);
+ if (strEQ(name,"ModuleError"))
+ return(ModuleError);
+ if (strEQ(name,"ModuleWarning"))
+ return(ModuleWarning);
+ break;
+ }
+ case 'O':
+ {
+ if (strEQ(name,"Opaque"))
+ return(OpaqueOpacity);
+ if (strEQ(name,"OptionError"))
+ return(OptionError);
+ if (strEQ(name,"OptionWarning"))
+ return(OptionWarning);
+ break;
+ }
+ case 'R':
+ {
+ if (strEQ(name,"ResourceLimitError"))
+ return(ResourceLimitError);
+ if (strEQ(name,"ResourceLimitWarning"))
+ return(ResourceLimitWarning);
+ if (strEQ(name,"RegistryError"))
+ return(RegistryError);
+ if (strEQ(name,"RegistryWarning"))
+ return(RegistryWarning);
+ break;
+ }
+ case 'S':
+ {
+ if (strEQ(name,"StreamError"))
+ return(StreamError);
+ if (strEQ(name,"StreamWarning"))
+ return(StreamWarning);
+ if (strEQ(name,"Success"))
+ return(0);
+ break;
+ }
+ case 'T':
+ {
+ if (strEQ(name,"Transparent"))
+ return(TransparentOpacity);
+ if (strEQ(name,"TypeError"))
+ return(TypeError);
+ if (strEQ(name,"TypeWarning"))
+ return(TypeWarning);
+ break;
+ }
+ case 'W':
+ {
+ if (strEQ(name,"WarningException"))
+ return(WarningException);
+ break;
+ }
+ case 'X':
+ {
+ if (strEQ(name,"XServerError"))
+ return(XServerError);
+ if (strEQ(name,"XServerWarning"))
+ return(XServerWarning);
+ break;
+ }
+ }
+ errno=EINVAL;
+ return(0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y P a c k a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyPackageInfo frees a previously created info structure.
+%
+% The format of the DestroyPackageInfo routine is:
+%
+% DestroyPackageInfo(struct PackageInfo *info)
+%
+% A description of each parameter follows:
+%
+% o info: a structure of type info.
+%
+%
+*/
+static void DestroyPackageInfo(struct PackageInfo *info)
+{
+ DestroyImageInfo(info->image_info);
+ DestroyDrawInfo(info->draw_info);
+ DestroyQuantizeInfo(info->quantize_info);
+ MagickFreeMemory(info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetList is recursively called by SetupList to traverse the
+% Graphics__Magick reference. If building an reference_vector (see SetupList),
+% *current is the current position in *reference_vector and *last is the final
+% entry in *reference_vector.
+%
+% The format of the GetList routine is:
+%
+% GetList(info)
+%
+% A description of each parameter follows:
+%
+% o info: a structure of type info.
+%
+%
+*/
+static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,int *current,
+ int *last)
+{
+ Image
+ *image;
+
+ if (!reference)
+ return(NULL);
+ switch (SvTYPE(reference))
+ {
+ case SVt_PVAV:
+ {
+ AV
+ *av;
+
+ Image
+ *head,
+ *previous;
+
+ int
+ n;
+
+ register int
+ i;
+
+ /*
+ Array of images.
+ */
+ previous=(Image *) NULL;
+ head=(Image *) NULL;
+ av=(AV *) reference;
+ n=av_len(av);
+ for (i=0; i <= n; i++)
+ {
+ SV
+ **rv;
+
+ rv=av_fetch(av,i,0);
+ if (rv && *rv && sv_isobject(*rv))
+ {
+ image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last);
+ if (!image)
+ continue;
+ if (image == previous)
+ {
+ ExceptionInfo
+ exception;
+
+ GetExceptionInfo(&exception);
+ image=CloneImage(image,0,0,True,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ if (image == (Image *) NULL)
+ return(NULL);
+ }
+ image->previous=previous;
+ *(previous ? &previous->next : &head)=image;
+ for (previous=image; previous->next; previous=previous->next);
+ }
+ }
+ return(head);
+ }
+ case SVt_PVMG:
+ {
+ /*
+ Blessed scalar, one image.
+ */
+ image=(Image *) SvIV(reference);
+ if (!image)
+ return(NULL);
+ image->previous=(Image *) NULL;
+ image->next=(Image *) NULL;
+ if (reference_vector)
+ {
+ if (*current == *last)
+ {
+ *last+=256;
+ if (*reference_vector)
+ {
+ MagickReallocMemory(SV **,*reference_vector,*last*sizeof(*reference_vector));
+ }
+ else
+ {
+ *reference_vector=
+ MagickAllocateMemory(SV **,*last*sizeof(*reference_vector));
+ }
+ }
+ (*reference_vector)[*current]=reference;
+ (*reference_vector)[++(*current)]=NULL;
+ }
+ return(image);
+ }
+ }
+ (void) fprintf(stderr,"GetList: UnrecognizedType %ld\n",
+ (long) SvTYPE(reference));
+ return((Image *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t P a c k a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetPackageInfo looks up or creates an info structure for the given
+% Graphics__Magick reference. If it does create a new one, the information in
+% package_info is used to initialize it.
+%
+% The format of the GetPackageInfo routine is:
+%
+% struct PackageInfo *GetPackageInfo(void *reference,
+% struct PackageInfo *package_info)
+%
+% A description of each parameter follows:
+%
+% o info: a structure of type info.
+%
+%
+*/
+static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
+ struct PackageInfo *package_info)
+{
+ char
+ message[MaxTextExtent];
+
+ struct PackageInfo
+ *clone_info;
+
+ SV
+ *sv;
+
+ FormatString(message,"%s::Ref%lx_%s",PackageName,(long) reference,
+ XS_VERSION);
+ sv=perl_get_sv(message,(TRUE | 0x02));
+ if (!sv)
+ {
+ MagickError(ResourceLimitError,UnableToGetPackageInfo,message);
+ return(package_info);
+ }
+ if (SvREFCNT(sv) == 0)
+ (void) SvREFCNT_inc(sv);
+ if (SvIOKp(sv) && (clone_info=(struct PackageInfo *) SvIV(sv)))
+ return(clone_info);
+ clone_info=ClonePackageInfo(package_info);
+ sv_setiv(sv,(IV) clone_info);
+ return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L o o k u p S t r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method LookupStr searches through a list of strings matching it to string
+% and return its index in the list, or -1 for not found .
+%
+% The format of the LookupStr routine is:
+%
+% int LookupStr(char **list,const char *string)
+%
+% A description of each parameter follows:
+%
+% o status: Method LookupStr returns the index of string in the list
+% otherwise -1.
+%
+% o list: a list of strings.
+%
+% o string: a character string.
+%
+%
+*/
+static int LookupStr(char **list,const char *string)
+{
+ int
+ longest,
+ offset;
+
+ register char
+ **p;
+
+ offset=(-1);
+ longest=0;
+ for (p=list; *p; p++)
+ if (strEQcase(string,*p) > longest)
+ {
+ offset=p-list;
+ longest=strEQcase(string,*p);
+ }
+ return(offset);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k E r r o r H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickErrorHandler replaces GraphicsMagick's fatal error handler. This
+% stores the message in a Perl variable,and longjmp's to return the error to
+% Perl. If the error_flag variable is set, it also calls the Perl warn
+% routine. Note that this doesn't exit but returns control to Perl; the
+% Graphics::Magick handle may be left in a bad state.
+%
+% The format of the MagickErrorHandler routine is:
+%
+% MagickErrorHandler(const ExceptionType severity,const char *reason,
+% const char *qualifier)
+%
+% A description of each parameter follows:
+%
+% o severity: The severity of the exception.
+%
+% o reason: The reason of the exception.
+%
+% o description: The exception description.
+%
+%
+*/
+static void MagickErrorHandler(const ExceptionType severity,const char *reason,
+ const char *description)
+{
+ char
+ text[MaxTextExtent];
+
+ dTHX; /* perl context */
+ dMY_CXT;
+ errno=0;
+ FormatString(text,"Exception %d: %.1024s%s%.1024s%s%s%.64s%s",severity,
+ (reason ? GetLocaleExceptionMessage(severity,reason) : "ERROR"),
+ description ? " (" : "",
+ description ? GetLocaleExceptionMessage(severity,description) : "",
+ description ? ")" : "",errno ? " [" : "",errno ? strerror(errno) : "",
+ errno? "]" : "");
+ if ((MY_CXT.error_list == NULL) || (MY_CXT.error_jump == NULL))
+ {
+ /*
+ Set up error buffer.
+ */
+ warn("%s",text);
+ if (MY_CXT.error_jump == NULL)
+ exit((int) severity % 100);
+ }
+ if (MY_CXT.error_list)
+ {
+ if (SvCUR(MY_CXT.error_list))
+ sv_catpv(MY_CXT.error_list,"\n");
+ sv_catpv(MY_CXT.error_list,text);
+ }
+ longjmp(*MY_CXT.error_jump,(int) severity);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W a r n i n g H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickWarningHandler replaces the GraphicsMagick warning handler. This
+% stores the (possibly multiple) reasons in a Perl variable for later
+% returning.
+%
+% The format of the MagickWarningHandler routine is:
+%
+% MagickWarningHandler(const ExceptionType severity,const char *reason,
+% const char *description)
+%
+% A description of each parameter follows:
+%
+% o severity: Specifies the numeric severity category.
+%
+% o reason: The reason of the exception.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+
+static void MagickWarningHandler(const ExceptionType severity,
+ const char *reason,const char *description)
+{
+ char
+ text[MaxTextExtent];
+
+ dTHX; /* perl context */
+ dMY_CXT;
+ errno=0;
+ if (!reason)
+ return;
+ FormatString(text,"Exception %d: %.1024s%s%.1024s%s%s%.64s%s",severity,
+ (reason ? GetLocaleExceptionMessage(severity,reason) : "WARNING"),
+ description ? " (" : "",
+ description ? GetLocaleExceptionMessage(severity,description) : "",
+ description ? ")" : "",errno ? " [" : "",errno ? strerror(errno) : "",
+ errno? "]" : "");
+ if (MY_CXT.error_list == NULL)
+ {
+ /*
+ Set up reason buffer.
+ */
+ warn("%s",text);
+ if (MY_CXT.error_list == NULL)
+ return;
+ }
+ if (SvCUR(MY_CXT.error_list))
+ sv_catpv(MY_CXT.error_list,"\n"); /* add \n separator between reasons */
+ sv_catpv(MY_CXT.error_list,text);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t A t t r i b u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SetAttribute sets the attribute to the value in sval. This can
+% change either or both of image or info.
+%
+% The format of the SetAttribute routine is:
+%
+% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
+% SV *sval)
+%
+% A description of each parameter follows:
+%
+% o status: Method SetAttribute returns the index of string in the list
+% otherwise -1.
+%
+% o list: a list of strings.
+%
+% o string: a character string.
+%
+%
+*/
+static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
+ char *attribute,SV *sval)
+{
+ DoublePixelPacket
+ pixel;
+
+ ExceptionInfo
+ exception;
+
+ int
+ sp;
+
+ long
+ x,
+ y;
+
+ PixelPacket
+ *color,
+ target_color;
+
+ GetExceptionInfo(&exception);
+ switch (*attribute)
+ {
+ case 'A':
+ case 'a':
+ {
+ if (LocaleCompare(attribute,"adjoin") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(BooleanTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->adjoin=sp != 0;
+ return;
+ }
+ if (LocaleCompare(attribute,"antialias") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(BooleanTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ {
+ info->image_info->antialias=sp != 0;
+ info->draw_info->text_antialias=sp != 0;
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"authenticate") == 0)
+ {
+ if (info)
+ (void) CloneString(&info->image_info->authenticate,SvPV(sval,na));
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare(attribute,"background") == 0)
+ {
+ (void) QueryColorDatabase(SvPV(sval,na),&target_color,
+ image ? &image->exception : &exception);
+ if (info)
+ info->image_info->background_color=target_color;
+ for ( ; image; image=image->next)
+ image->background_color=target_color;
+ return;
+ }
+ if (LocaleCompare(attribute,"blue-primary") == 0)
+ {
+ for ( ; image; image=image->next)
+ (void) sscanf(SvPV(sval,na),"%lf%*[,/]%lf",
+ &image->chromaticity.blue_primary.x,
+ &image->chromaticity.blue_primary.y);
+ return;
+ }
+ if (LocaleCompare(attribute,"bordercolor") == 0)
+ {
+ (void) QueryColorDatabase(SvPV(sval,na),&target_color,
+ image ? &image->exception : &exception);
+ if (info)
+ {
+ info->image_info->border_color=target_color;
+ info->draw_info->border_color=target_color;
+ }
+ for ( ; image; image=image->next)
+ image->border_color=target_color;
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(attribute,"cache-threshold") == 0)
+ {
+ SetMagickResourceLimit(MemoryResource,SvIV(sval));
+ SetMagickResourceLimit(MapResource,2*SvIV(sval));
+ return;
+ }
+ if (LocaleCompare(attribute,"clip-mask") == 0)
+ {
+ Image
+ *clip_mask;
+
+ clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL);
+ for ( ; image; image=image->next)
+ SetImageClipMask(image,clip_mask);
+ return;
+ }
+ if (LocaleNCompare(attribute,"colormap",8) == 0)
+ {
+ for ( ; image; image=image->next)
+ {
+ int
+ i;
+
+ if (image->storage_class == DirectClass)
+ continue;
+ i=0;
+ (void) sscanf(attribute,"%*[^[][%d",&i);
+ if (i > (long) image->colors)
+ i%=image->colors;
+ if (strchr(SvPV(sval,na),',') == 0)
+ QueryColorDatabase(SvPV(sval,na),image->colormap+i,
+ image ? &image->exception : &exception);
+ else
+ {
+ color=image->colormap+i;
+ pixel.red=color->red;
+ pixel.green=color->green;
+ pixel.blue=color->blue;
+ (void) sscanf(SvPV(sval,na),"%lf%*[,/]%lf%*[,/]%lf",&pixel.red,
+ &pixel.green,&pixel.blue);
+ color->red=(Quantum) ((pixel.red < 0) ? 0 :
+ (pixel.red > MaxRGB) ? MaxRGB : pixel.red+0.5);
+ color->green=(Quantum) ((pixel.green < 0) ? 0 :
+ (pixel.green > MaxRGB) ? MaxRGB : pixel.green+0.5);
+ color->blue=(Quantum) ((pixel.blue < 0) ? 0 :
+ (pixel.blue > MaxRGB) ? MaxRGB : pixel.blue+0.5);
+ }
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"colorspace") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(ColorspaceTypes,SvPV(sval,na)) :
+ SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedColorspace,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->colorspace=(ColorspaceType) sp;
+ for ( ; image; image=image->next)
+ TransformColorspace(image,(ColorspaceType) sp);
+ return;
+ }
+ if (LocaleCompare(attribute,"compression") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(CompressionTypes,SvPV(sval,na)) :
+ SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedImageCompression,
+ SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->compression=(CompressionType) sp;
+ for ( ; image; image=image->next)
+ image->compression=(CompressionType) sp;
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare(attribute,"debug") == 0)
+ {
+ SetLogEventMask(SvPV(sval,na));
+ return;
+ }
+ if (LocaleCompare(attribute,"delay") == 0)
+ {
+ for ( ; image; image=image->next)
+ image->delay=SvIV(sval);
+ return;
+ }
+ if (LocaleCompare(attribute,"disk-limit") == 0)
+ {
+ SetMagickResourceLimit(DiskResource,SvIV(sval));
+ return;
+ }
+ if (LocaleCompare(attribute,"density") == 0)
+ {
+ if (!IsGeometry(SvPV(sval,na)))
+ {
+ MagickError(OptionError,MissingGeometry,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ {
+ (void) CloneString(&info->image_info->density,SvPV(sval,na));
+ (void) CloneString(&info->draw_info->density,SvPV(sval,na));
+ }
+ for ( ; image; image=image->next)
+ {
+ int
+ count;
+
+ count=sscanf(info->image_info->density,"%lfx%lf",
+ &image->x_resolution,&image->y_resolution);
+ if (count != 2)
+ image->y_resolution=image->x_resolution;
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"depth") == 0)
+ {
+ if (info)
+ info->image_info->depth=SvIV(sval);
+ for ( ; image; image=image->next)
+ SetImageDepth(image,SvIV(sval));
+ return;
+ }
+ if (LocaleCompare(attribute,"dispose") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(DisposeTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ sp=SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedDisposeMethod,
+ SvPV(sval,na));
+ return;
+ }
+ for ( ; image; image=image->next)
+ image->dispose=(DisposeType) sp;
+ return;
+ }
+ if (LocaleCompare(attribute,"dither") == 0)
+ {
+ if (info)
+ {
+ sp=SvPOK(sval) ? LookupStr(BooleanTypes,SvPV(sval,na)) :
+ SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(sval,na));
+ return;
+ }
+ info->image_info->dither=sp != 0;
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"display") == 0)
+ {
+ display:
+ if (info)
+ {
+ (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
+ (void) CloneString(&info->draw_info->server_name,SvPV(sval,na));
+ }
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'E':
+ case 'e':
+ {
+ if (LocaleCompare(attribute,"endian") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(EndianTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedEndianType,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->endian=(EndianType) sp;
+ for ( ; image; image=image->next)
+ image->endian=(EndianType) sp;
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(attribute,"filename") == 0)
+ {
+ if (info)
+ (void) strncpy(info->image_info->filename,SvPV(sval,na),
+ MaxTextExtent-1);
+ for ( ; image; image=image->next)
+ (void) strncpy(image->filename,SvPV(sval,na),MaxTextExtent-1);
+ return;
+ }
+ if (LocaleCompare(attribute,"file") == 0)
+ {
+ if (info)
+ info->image_info->file=PerlIO_findFILE(IoIFP(sv_2io(sval)));
+ return;
+ }
+ if (LocaleCompare(attribute,"fill") == 0)
+ {
+ if (info)
+ {
+ (void) QueryColorDatabase(SvPV(sval,na),&info->draw_info->fill,
+ image ? &image->exception : &exception);
+ (void) QueryColorDatabase(SvPV(sval,na),&info->image_info->pen,
+ image ? &image->exception : &exception);
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"font") == 0)
+ {
+ if (info)
+ {
+ (void) CloneString(&info->image_info->font,SvPV(sval,na));
+ (void) CloneString(&info->draw_info->font,SvPV(sval,na));
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"fuzz") == 0)
+ {
+ if (info)
+ info->image_info->fuzz=SvNV(sval);
+ for ( ; image; image=image->next)
+ image->fuzz=SvNV(sval);
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(attribute,"gamma") == 0)
+ {
+ for ( ; image; image=image->next)
+ image->gamma=SvNV(sval);
+ return;
+ }
+ if (LocaleCompare(attribute,"gravity") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(GravityTypes,SvPV(sval,na)) :
+ SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedGravityType,SvPV(sval,na));
+ return;
+ }
+ for ( ; image; image=image->next)
+ image->gravity=(GravityType) sp;
+ return;
+ }
+ if (LocaleCompare(attribute,"green-primary") == 0)
+ {
+ for ( ; image; image=image->next)
+ (void) sscanf(SvPV(sval,na),"%lf%*[,/]%lf",
+ &image->chromaticity.green_primary.x,
+ &image->chromaticity.green_primary.y);
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'I':
+ case 'i':
+ {
+ if (LocaleNCompare(attribute,"index",5) == 0)
+ {
+ long
+ index;
+
+ IndexPacket
+ *indexes;
+
+ register PixelPacket
+ *p;
+
+ for ( ; image; image=image->next)
+ {
+ if (image->storage_class != PseudoClass)
+ continue;
+ x=0;
+ y=0;
+ (void) sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
+ p=GetImagePixels(image,(long) (x % image->columns),
+ (long) (y % image->rows),1,1);
+ if (p == (PixelPacket *) NULL)
+ break;
+ indexes=GetIndexes(image);
+ (void) sscanf(SvPV(sval,na),"%ld",&index);
+ if ((index >= 0) && (index < (long) image->colors))
+ *indexes=(IndexPacket) index;
+ (void) SyncImagePixels(image);
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"iterations") == 0)
+ {
+ iterations:
+ for ( ; image; image=image->next)
+ image->iterations=SvIV(sval);
+ return;
+ }
+ if (LocaleCompare(attribute,"interlace") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(InterlaceTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedInterlaceType,
+ SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->interlace=(InterlaceType) sp;
+ for ( ; image; image=image->next)
+ image->interlace=(InterlaceType) sp;
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'L':
+ case 'l':
+ {
+ if (LocaleCompare(attribute,"loop") == 0)
+ goto iterations;
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare(attribute,"magick") == 0)
+ {
+ if (info)
+ {
+ ExceptionInfo
+ exception;
+
+ GetExceptionInfo(&exception);
+ FormatString(info->image_info->filename,"%.1024s:",SvPV(sval,na));
+ SetImageInfo(info->image_info,SETMAGICK_WRITE,&exception);
+ if (*info->image_info->magick == '\0')
+ MagickError(OptionError,UnrecognizedImageFormat,
+ info->image_info->filename);
+ else
+ for ( ; image; image=image->next)
+ (void) strncpy(image->magick,info->image_info->magick,
+ MaxTextExtent-1);
+ DestroyExceptionInfo(&exception);
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"map-limit") == 0)
+ {
+ SetMagickResourceLimit(MapResource,SvIV(sval));
+ return;
+ }
+ if (LocaleCompare(attribute,"mattecolor") == 0)
+ {
+ (void) QueryColorDatabase(SvPV(sval,na),&target_color,
+ image ? &image->exception : &exception);
+ if (info)
+ info->image_info->matte_color=target_color;
+ for ( ; image; image=image->next)
+ image->matte_color=target_color;
+ return;
+ }
+ if (LocaleCompare(attribute,"matte") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(BooleanTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(sval,na));
+ return;
+ }
+ for ( ; image; image=image->next)
+ image->matte=sp != 0;
+ return;
+ }
+ if (LocaleCompare(attribute,"memory-limit") == 0)
+ {
+ SetMagickResourceLimit(MemoryResource,SvIV(sval));
+ return;
+ }
+ if (LocaleCompare(attribute,"monochrome") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(BooleanTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->monochrome=sp != 0;
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'P':
+ case 'p':
+ {
+ if (LocaleCompare(attribute,"page") == 0)
+ {
+ char
+ *geometry;
+
+ geometry=GetPageGeometry(SvPV(sval,na));
+ if (info)
+ (void) CloneString(&info->image_info->page,geometry);
+ for ( ; image; image=image->next)
+ (void) GetImageGeometry(image,geometry,False,&image->page);
+ MagickFreeMemory(geometry);
+ return;
+ }
+ if (LocaleCompare(attribute,"pen") == 0)
+ {
+ if (info)
+ (void) QueryColorDatabase(SvPV(sval,na),&info->draw_info->fill,
+ image ? &image->exception : &exception);
+ return;
+ }
+ if (LocaleNCompare(attribute,"pixel",5) == 0)
+ {
+ register PixelPacket
+ *p;
+
+ for ( ; image; image=image->next)
+ {
+ x=0;
+ y=0;
+ (void) sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
+ p=GetImagePixels(image,(long) (x % image->columns),
+ (long) (y % image->rows),1,1);
+ if (p == (PixelPacket *) NULL)
+ break;
+ image->storage_class=DirectClass;
+ if (strchr(SvPV(sval,na),',') == 0)
+ QueryColorDatabase(SvPV(sval,na),p,
+ image ? &image->exception : &exception);
+ else
+ {
+ pixel.red=p->red;
+ pixel.green=p->green;
+ pixel.blue=p->blue;
+ pixel.opacity=p->opacity;
+ (void) sscanf(SvPV(sval,na),"%lf%*[,/]%lf%*[,/]%lf%*[,/]%lf",
+ &pixel.red,&pixel.green,&pixel.blue,&pixel.opacity);
+ p->red=(Quantum) ((pixel.red < 0) ? 0 :
+ (pixel.red > MaxRGB) ? MaxRGB : pixel.red+0.5);
+ p->green=(Quantum) ((pixel.green < 0) ? 0 :
+ (pixel.green > MaxRGB) ? MaxRGB : pixel.green+0.5);
+ p->blue=(Quantum) ((pixel.blue < 0) ? 0 :
+ (pixel.blue > MaxRGB) ? MaxRGB : pixel.blue+0.5);
+ p->opacity=(Quantum) ((pixel.opacity < 0) ? 0 :
+ (pixel.opacity > MaxRGB) ? MaxRGB : pixel.opacity+0.5);
+ }
+ (void) SyncImagePixels(image);
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"pointsize") == 0)
+ {
+ if (info)
+ {
+ (void) sscanf(SvPV(sval,na),"%lf",&info->image_info->pointsize);
+ (void) sscanf(SvPV(sval,na),"%lf",&info->draw_info->pointsize);
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"preview") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(PreviewTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->preview_type=(PreviewType) sp;
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'Q':
+ case 'q':
+ {
+ if (LocaleCompare(attribute,"quality") == 0)
+ {
+ if (info)
+ info->image_info->quality=SvIV(sval);
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(attribute,"red-primary") == 0)
+ {
+ for ( ; image; image=image->next)
+ (void) sscanf(SvPV(sval,na),"%lf%*[,/]%lf",
+ &image->chromaticity.red_primary.x,
+ &image->chromaticity.red_primary.y);
+ return;
+ }
+ if (LocaleCompare(attribute,"render") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(IntentTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedIntentType,SvPV(sval,na));
+ return;
+ }
+ for ( ; image; image=image->next)
+ image->rendering_intent=(RenderingIntent) sp;
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(attribute,"sampling-factor") == 0)
+ {
+ if (!IsGeometry(SvPV(sval,na)))
+ {
+ MagickError(OptionError,MissingGeometry,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ (void) CloneString(&info->image_info->sampling_factor,
+ SvPV(sval,na));
+ return;
+ }
+ if (LocaleCompare(attribute,"scene") == 0)
+ {
+ for ( ; image; image=image->next)
+ image->scene=SvIV(sval);
+ return;
+ }
+ if (LocaleCompare(attribute,"subimage") == 0)
+ {
+ if (info)
+ info->image_info->subimage=SvIV(sval);
+ return;
+ }
+ if (LocaleCompare(attribute,"subrange") == 0)
+ {
+ if (info)
+ info->image_info->subrange=SvIV(sval);
+ return;
+ }
+ if (LocaleCompare(attribute,"server") == 0)
+ goto display;
+ if (LocaleCompare(attribute,"size") == 0)
+ {
+ if (info)
+ {
+ if (!IsGeometry(SvPV(sval,na)))
+ {
+ MagickError(OptionError,MissingGeometry,SvPV(sval,na));
+ return;
+ }
+ (void) CloneString(&info->image_info->size,SvPV(sval,na));
+ }
+ return;
+ }
+ if (LocaleCompare(attribute,"stroke") == 0)
+ {
+ if (info)
+ (void) QueryColorDatabase(SvPV(sval,na),&info->draw_info->stroke,
+ image ? &image->exception : &exception);
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare(attribute,"tile") == 0)
+ {
+ if (info)
+ (void) CloneString(&info->image_info->tile,SvPV(sval,na));
+ return;
+ }
+ if (LocaleCompare(attribute,"texture") == 0)
+ {
+ if (info)
+ (void) CloneString(&info->image_info->texture,SvPV(sval,na));
+ return;
+ }
+ if (LocaleCompare(attribute,"type") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(ImageTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->type=(ImageType) sp;
+ for ( ; image; image=image->next)
+ SetImageType(image,(ImageType) sp);
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'U':
+ case 'u':
+ {
+ if (LocaleCompare(attribute,"units") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(ResolutionTypes,SvPV(sval,na)) :
+ SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,MissingType,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->units=(ResolutionType) sp;
+ for ( ; image; image=image->next)
+ image->units=(ResolutionType) sp;
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'V':
+ case 'v':
+ {
+ if (LocaleCompare(attribute,"verbose") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(BooleanTypes,SvPV(sval,na)) : SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(sval,na));
+ return;
+ }
+ if (info)
+ info->image_info->verbose=sp != 0;
+ return;
+ }
+ if (LocaleCompare(attribute,"view") == 0)
+ {
+ if (info)
+ (void) CloneString(&info->image_info->view,SvPV(sval,na));
+ return;
+ }
+ if (LocaleCompare(attribute,"virtual-pixel") == 0)
+ {
+ sp=SvPOK(sval) ? LookupStr(VirtualPixelMethods,SvPV(sval,na)) :
+ SvIV(sval);
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedVirtualPixelMethod,
+ SvPV(sval,na));
+ return;
+ }
+ for ( ; image; image=image->next)
+ SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp);
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(attribute,"white-point") == 0)
+ {
+ for ( ; image; image=image->next)
+ (void) sscanf(SvPV(sval,na),"%lf%*[,/]%lf",
+ &image->chromaticity.white_point.x,
+ &image->chromaticity.white_point.y);
+ return;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ default:
+ {
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ }
+ DestroyExceptionInfo(&exception);
+ if (image == (Image *) NULL)
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ for ( ; image; image=image->next)
+ (void) SetImageAttribute(image,attribute,SvPV(sval,na));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t u p L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SetupList returns the list of all the images linked by their
+% image->next and image->previous link lists for use with GraphicsMagick. If
+% info is non-NULL, an info structure is returned in *info. If
+% reference_vector is non-NULL,an array of SV* are returned in
+% *reference_vector. Reference_vector is used when the images are going to be
+% replaced with new Image*'s.
+%
+% The format of the SetupList routine is:
+%
+% Image *SetupList(SV *reference,struct PackageInfo **info,
+% SV ***reference_vector)
+%
+% A description of each parameter follows:
+%
+% o status: Method SetupList returns the index of string in the list
+% otherwise -1.
+%
+% o list: a list of strings.
+%
+% o string: a character string.
+%
+%
+*/
+static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
+ SV ***reference_vector)
+{
+ Image
+ *image;
+
+ int
+ current,
+ last;
+
+ if (reference_vector)
+ *reference_vector=NULL;
+ if (info)
+ *info=NULL;
+ current=0;
+ last=0;
+ image=GetList(aTHX_ reference,reference_vector,&current,&last);
+ if (info && (SvTYPE(reference) == SVt_PVAV))
+ *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% s t r E Q c a s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method strEQcase compares two strings and returns 0 if they are the
+% same or if the second string runs out first. The comparison is case
+% insensitive.
+%
+% The format of the strEQcase routine is:
+%
+% int strEQcase(const char *p,const char *q)
+%
+% A description of each parameter follows:
+%
+% o status: Method strEQcase returns zero if strings p and q are the
+% same or if the second string runs out first.
+%
+% o p: a character string.
+%
+% o q: a character string.
+%
+%
+*/
+static int strEQcase(const char *p,const char *q)
+{
+ char
+ c;
+
+ register int
+ i;
+
+ for (i=0 ; (c=(*q)) != 0; i++)
+ {
+ if ((isUPPER(c) ? toLOWER(c) : c) != (isUPPER(*p) ? toLOWER(*p) : *p))
+ return(0);
+ p++;
+ q++;
+ }
+ return(i);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G r a p h i c s : : M a g i c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+MODULE = Graphics::Magick PACKAGE = Graphics::Magick
+
+PROTOTYPES: ENABLE
+
+BOOT:
+ InitializeMagick(PackageName);
+ SetWarningHandler(MagickWarningHandler);
+ SetErrorHandler(MagickErrorHandler);
+ { MY_CXT_INIT; }
+
+double
+constant(name,argument)
+ char *name
+ int argument
+
+#
+###############################################################################
+# #
+# #
+# #
+# A n i m a t e #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Animate(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ AnimateImage = 1
+ animate = 2
+ animateimage = 3
+ PPCODE:
+ {
+ jmp_buf
+ error_jmp;
+
+ Image
+ *image;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info,
+ *package_info;
+
+ SV
+ *reference;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ package_info=(struct PackageInfo *) NULL;
+ status=0;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ package_info=ClonePackageInfo(info);
+ if (items == 2)
+ SetAttribute(aTHX_ package_info,NULL,"server",ST(1));
+ else
+ if (items > 2)
+ for (i=2; i < items; i+=2)
+ SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i));
+ AnimateImages(package_info->image_info,image);
+ (void) CatchImageException(image);
+
+ MethodException:
+ if (package_info)
+ DestroyPackageInfo(package_info);
+ sv_setiv(MY_CXT.error_list,(IV)
+ (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# A p p e n d #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Append(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ AppendImage = 1
+ append = 2
+ appendimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ *attribute;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ jmp_buf
+ error_jmp;
+
+ Image
+ *image;
+
+ int
+ stack;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *av_reference,
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ attribute=NULL;
+ av=NULL;
+ status=0;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ av=newAV();
+ av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ info=GetPackageInfo(aTHX_ (void *) av,info);
+ /*
+ Get options.
+ */
+ stack=True;
+ for (i=2; i < items; i+=2)
+ {
+ attribute=(char *) SvPV(ST(i-1),na);
+ switch (*attribute)
+ {
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(attribute,"stack") == 0)
+ {
+ stack=LookupStr(BooleanTypes,SvPV(ST(i),na));
+ if (stack < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(ST(i),na));
+ return;
+ }
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ default:
+ {
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ }
+ }
+ GetExceptionInfo(&exception);
+ image=AppendImages(image,stack,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ for ( ; image; image=image->next)
+ {
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ }
+ ST(0)=av_reference;
+ MY_CXT.error_jump=NULL;
+ SvREFCNT_dec(MY_CXT.error_list); /* can't return warning messages */
+ MY_CXT.error_list=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ MY_CXT.error_jump=NULL;
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# A v e r a g e #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Average(ref)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ AverageImage = 1
+ average = 2
+ averageimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ *p;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ jmp_buf
+ error_jmp;
+
+ Image
+ *image;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ status=0;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ GetExceptionInfo(&exception);
+ image=AverageImages(image,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ /*
+ Create blessed Perl array for the returned image.
+ */
+ av=newAV();
+ ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ info=GetPackageInfo(aTHX_ (void *) av,info);
+ FormatString(info->image_info->filename,"average-%.*s",MaxTextExtent-9,
+ ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
+ (void) strncpy(image->filename,info->image_info->filename,MaxTextExtent-1);
+ SetImageInfo(info->image_info,SETMAGICK_WRITE,&image->exception);
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list); /* return messages in string context */
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# B l o b T o I m a g e #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+BlobToImage(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ BlobToImage = 1
+ blobtoimage = 2
+ blobto = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ **keep,
+ **list;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ Image
+ *image;
+
+ int
+ ac,
+ n;
+
+ jmp_buf
+ error_jmp;
+
+ register char
+ **p;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ STRLEN
+ *length;
+
+ SV
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ number_images;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ number_images=0;
+ ac=(items < 2) ? 1 : items-1;
+ list=MagickAllocateMemory(char **,(ac+1)*sizeof(*list));
+ length=MagickAllocateMemory(STRLEN *,(ac+1)*sizeof(length));
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto ReturnIt;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ if (SvTYPE(reference) != SVt_PVAV)
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,NULL);
+ goto ReturnIt;
+ }
+ av=(AV *) reference;
+ info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL);
+ n=1;
+ if (items <= 1)
+ {
+ MagickError(OptionError,NoBlobDefined,NULL);
+ goto ReturnIt;
+ }
+ for (n=0, i=0; i < ac; i++)
+ {
+ list[n]=(char *) (SvPV(ST(i+1),length[n]));
+ if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
+ {
+ list[n]=(char *) (SvPV(ST(i+2),length[n]));
+ continue;
+ }
+ n++;
+ }
+ list[n]=(char *) NULL;
+ keep=list;
+ MY_CXT.error_jump=(&error_jmp);
+ if (setjmp(error_jmp))
+ goto ReturnIt;
+ GetExceptionInfo(&exception);
+ for (i=number_images=0; i < n; i++)
+ {
+ image=BlobToImage(info->image_info,list[i],length[i],&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ for ( ; image; image=image->next)
+ {
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ number_images++;
+ }
+ }
+ DestroyExceptionInfo(&exception);
+ /*
+ Free resources.
+ */
+ for (i=0; i < n; i++)
+ if (list[i])
+ for (p=keep; list[i] != *p++; )
+ if (*p == NULL)
+ {
+ MagickFreeMemory(list[i]);
+ break;
+ }
+
+ ReturnIt:
+ MagickFreeMemory(list);
+ MagickFreeMemory(length);
+ sv_setiv(MY_CXT.error_list,(IV) number_images);
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# C o a l e s c e #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Coalesce(ref)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ CoalesceImage = 1
+ coalesce = 2
+ coalesceimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ jmp_buf
+ error_jmp;
+
+ Image
+ *image;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *av_reference,
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ status=0;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ av=newAV();
+ av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ GetExceptionInfo(&exception);
+ image=CoalesceImages(image,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ for ( ; image; image=image->next)
+ {
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ }
+ ST(0)=av_reference;
+ MY_CXT.error_jump=NULL;
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# C o p y #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Copy(ref)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ CopyImage = 1
+ copy = 2
+ copyimage = 3
+ CloneImage = 4
+ clone = 5
+ cloneimage = 6
+ Clone = 7
+ PPCODE:
+ {
+ AV
+ *av;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ Image
+ *clone,
+ *image;
+
+ jmp_buf
+ error_jmp;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ status=0;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (image == (Image *) NULL)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ /*
+ Create blessed Perl array for the returned image.
+ */
+ av=newAV();
+ ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ GetExceptionInfo(&exception);
+ for ( ; image; image=image->next)
+ {
+ clone=CloneImage(image,0,0,True,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ sv=newSViv((IV) clone);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ }
+ DestroyExceptionInfo(&exception);
+ info=GetPackageInfo(aTHX_ (void *) av,info);
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# D e s t r o y #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+DESTROY(ref)
+ Graphics::Magick ref=NO_INIT
+ PPCODE:
+ {
+ SV
+ *reference;
+
+ if (!sv_isobject(ST(0)))
+ croak("ReferenceIsNotMyType");
+ reference=SvRV(ST(0));
+ switch (SvTYPE(reference))
+ {
+ case SVt_PVAV:
+ {
+ char
+ message[MaxTextExtent];
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *sv;
+
+ /*
+ Array (AV *) reference
+ */
+ FormatString(message,"%s::Ref%lx_%s",PackageName,(long) reference,
+ XS_VERSION);
+ sv=perl_get_sv(message,FALSE);
+ if (sv)
+ {
+ if ((SvREFCNT(sv) == 1) && SvIOK(sv) &&
+ (info=(struct PackageInfo *) SvIV(sv)))
+ {
+ DestroyPackageInfo(info);
+ sv_setiv(sv,0);
+ }
+ }
+ break;
+ }
+ case SVt_PVMG:
+ {
+ Image
+ *image;
+
+ /*
+ Blessed scalar = (Image *) SvIV(reference)
+ */
+ image=(Image *) SvIV(reference);
+ if (image)
+ {
+ if (image->previous && image->previous->next == image)
+ image->previous->next=0;
+ if (image->next && image->next->previous == image)
+ image->next->previous=0;
+ DestroyImage(image);
+ sv_setiv(reference,0);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# D i s p l a y #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Display(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ DisplayImage = 1
+ display = 2
+ displayimage = 3
+ PPCODE:
+ {
+ jmp_buf
+ error_jmp;
+
+ Image
+ *image;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info,
+ *package_info;
+
+ SV
+ *reference;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ status=0;
+ package_info=(struct PackageInfo *) NULL;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (image == (Image *) NULL)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ package_info=ClonePackageInfo(info);
+ if (items == 2)
+ SetAttribute(aTHX_ package_info,NULL,"server",ST(1));
+ else
+ if (items > 2)
+ for (i=2; i < items; i+=2)
+ SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i));
+ DisplayImages(package_info->image_info,image);
+ (void) CatchImageException(image);
+
+ MethodException:
+ if (package_info)
+ DestroyPackageInfo(package_info);
+ sv_setiv(MY_CXT.error_list,(IV) status);
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# F l a t t e n #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Flatten(ref)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ FlattenImage = 1
+ flatten = 2
+ flattenimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ *p;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ jmp_buf
+ error_jmp;
+
+ Image
+ *image;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ status=0;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ GetExceptionInfo(&exception);
+ image=FlattenImages(image,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ /*
+ Create blessed Perl array for the returned image.
+ */
+ av=newAV();
+ ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ info=GetPackageInfo(aTHX_ (void *) av,info);
+ FormatString(info->image_info->filename,"average-%.*s",MaxTextExtent-9,
+ ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
+ (void) strncpy(image->filename,info->image_info->filename,MaxTextExtent-1);
+ SetImageInfo(info->image_info,SETMAGICK_WRITE,&image->exception);
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list); /* return messages in string context */
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# G e t #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Get(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ GetAttributes = 1
+ GetAttribute = 2
+ get = 3
+ getattributes = 4
+ getattribute = 5
+ PPCODE:
+ {
+ char
+ *attribute,
+ color[MaxTextExtent];
+
+ const ImageAttribute
+ *image_attribute;
+
+ Image
+ *image;
+
+ const unsigned char *
+ profile_info;
+
+ size_t
+ profile_length;
+
+ int
+ j;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *reference,
+ *s;
+
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ XSRETURN_EMPTY;
+ }
+ reference=SvRV(ST(0));
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image && !info)
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,NULL);
+ XSRETURN_EMPTY;
+ }
+ EXTEND(sp,items);
+ for (i=1; i < items; i++)
+ {
+ attribute=(char *) SvPV(ST(i),na);
+ s=NULL;
+ switch (*attribute)
+ {
+ case 'A':
+ case 'a':
+ {
+ if (LocaleCompare(attribute,"adjoin") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->adjoin);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"antialias") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->antialias);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"authenticate") == 0)
+ {
+ if (info)
+ s=newSVpv(info->image_info->authenticate,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare(attribute,"background") == 0)
+ {
+ if (!image)
+ break;
+ FormatString(color,"%u,%u,%u,%u",image->background_color.red,
+ image->background_color.green,image->background_color.blue,
+ image->background_color.opacity);
+ s=newSVpv(color,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"base-columns") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->magick_columns);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"base-filename") == 0)
+ {
+ if (image)
+ s=newSVpv(image->magick_filename,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"base-height") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->magick_rows);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"base-rows") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->magick_rows);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"base-width") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->magick_columns);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"blue-primary") == 0)
+ {
+ if (!image)
+ break;
+ FormatString(color,"%g,%g",image->chromaticity.blue_primary.x,
+ image->chromaticity.blue_primary.y);
+ s=newSVpv(color,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"bordercolor") == 0)
+ {
+ if (!image)
+ break;
+ FormatString(color,"%u,%u,%u,%u",image->border_color.red,
+ image->border_color.green,image->border_color.blue,
+ image->border_color.opacity);
+ s=newSVpv(color,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(attribute,"class") == 0)
+ {
+ if (!image)
+ break;
+#if defined(__cplusplus) || defined(c_plusplus)
+ j=image->c_class;
+#else
+ j=image->storage_class;
+#endif
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(ClassTypes)-1))
+ {
+ (void) sv_setpv(s,ClassTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"clip-mask") == 0)
+ {
+ if (image)
+ {
+ SV
+ *sv;
+
+ if (image->clip_mask == (Image *) NULL)
+ ClipImage(image);
+ sv=newSViv((IV) image->clip_mask);
+ s=sv_bless(newRV(sv),SvSTASH(reference));
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"compression") == 0)
+ {
+ j=info ? info->image_info->compression : image->compression;
+ if (info)
+ if (info->image_info->compression == UndefinedCompression)
+ j=image->compression;
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(CompressionTypes)-1))
+ {
+ (void) sv_setpv(s,CompressionTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"colorspace") == 0)
+ {
+ j=image ? image->colorspace : RGBColorspace;
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(ColorspaceTypes)-1))
+ {
+ (void) sv_setpv(s,ColorspaceTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"colors") == 0)
+ {
+ if (image)
+ s=newSViv((long) GetNumberColors(image,(FILE *) NULL,
+ &image->exception));
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleNCompare(attribute,"colormap",8) == 0)
+ {
+ if (!image || !image->colormap)
+ break;
+ j=0;
+ (void) sscanf(attribute,"%*[^[][%d",&j);
+ if (j > (long) image->colors)
+ j%=image->colors;
+ FormatString(color,"%u,%u,%u,%u",image->colormap[j].red,
+ image->colormap[j].green,image->colormap[j].blue,
+ image->colormap[j].opacity);
+ s=newSVpv(color,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"columns") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->columns);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"comment") == 0)
+ {
+ const ImageAttribute
+ *attribute;
+
+ attribute=GetImageAttribute(image,"comment");
+ if (attribute != (ImageAttribute *) NULL)
+ s=newSVpv(attribute->value,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare(attribute,"density") == 0)
+ {
+ char
+ geometry[MaxTextExtent];
+
+ if (!image)
+ break;
+ FormatString(geometry,"%gx%g",image->x_resolution,
+ image->y_resolution);
+ s=newSVpv(geometry,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"dispose") == 0)
+ {
+ if (!image)
+ break;
+
+ j=image->dispose;
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(DisposeTypes)-1))
+ {
+ (void) sv_setpv(s,DisposeTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"delay") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->delay);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"depth") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->depth);
+ if (image)
+ s=newSViv((long) GetImageDepth(image,&image->exception));
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"dither") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->dither);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"display") == 0) /* same as server */
+ {
+ if (info && info->image_info->server_name)
+ s=newSVpv(info->image_info->server_name,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"directory") == 0)
+ {
+ if (image && image->directory)
+ s=newSVpv(image->directory,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'E':
+ case 'e':
+ {
+ if (LocaleCompare(attribute,"endian") == 0)
+ {
+ j=info ? info->image_info->endian : image->endian;
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(EndianTypes)-1))
+ {
+ (void) sv_setpv(s,EndianTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"error") == 0)
+ {
+ if (image)
+ s=newSVnv(image->error.mean_error_per_pixel);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(attribute,"filesize") == 0)
+ {
+ if (image)
+ s=newSViv((long) GetBlobSize(image));
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"filename") == 0)
+ {
+ if (image)
+ s=newSVpv(image->filename,0);
+ else
+ if (info && info->image_info->filename &&
+ *info->image_info->filename)
+ s=newSVpv(info->image_info->filename,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"filter") == 0)
+ {
+ j=image->filter;
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(FilterTypess)-1))
+ {
+ (void) sv_setpv(s,FilterTypess[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"font") == 0)
+ {
+ if (info && info->image_info->font)
+ s=newSVpv(info->image_info->font,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"format") == 0)
+ {
+ ExceptionInfo
+ exception;
+
+ const MagickInfo
+ *magick_info;
+
+ magick_info=(const MagickInfo *) NULL;
+ if (info && (*info->image_info->magick != '\0'))
+ {
+ GetExceptionInfo(&exception);
+ magick_info=
+ GetMagickInfo(info->image_info->magick,&exception);
+ DestroyExceptionInfo(&exception);
+ }
+ else
+ if (image)
+ magick_info=GetMagickInfo(image->magick,&image->exception);
+ if ((magick_info != (const MagickInfo *) NULL) &&
+ (*magick_info->description != '\0'))
+ s=newSVpv((char *) magick_info->description,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"fuzz") == 0)
+ {
+ if (info)
+ s=newSVnv(info->image_info->fuzz);
+ else
+ if (image)
+ s=newSVnv(image->fuzz);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(attribute,"gamma") == 0)
+ {
+ if (image)
+ s=newSVnv(image->gamma);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"geometry") == 0)
+ {
+ if (image && image->geometry)
+ s=newSVpv(image->geometry,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"gravity") == 0)
+ {
+ j=image->gravity;
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(GravityTypes)-1))
+ {
+ (void) sv_setpv(s,GravityTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"green-primary") == 0)
+ {
+ if (!image)
+ break;
+ FormatString(color,"%g,%g",image->chromaticity.green_primary.x,
+ image->chromaticity.green_primary.y);
+ s=newSVpv(color,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(attribute,"height") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->rows);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare(attribute,"icm") == 0)
+ {
+ if (image)
+ {
+ profile_info=GetImageProfile(image,"ICM",&profile_length);
+ s=newSVpv((const char *) profile_info,profile_length);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"id") == 0)
+ {
+ if (image)
+ s=newSViv(SetMagickRegistry(ImageRegistryType,image,0,
+ &image->exception));
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleNCompare(attribute,"index",5) == 0)
+ {
+ char
+ name[MaxTextExtent];
+
+ const IndexPacket
+ *indexes;
+
+ long
+ x,
+ y;
+
+ if (!image)
+ break;
+ if (image->storage_class != PseudoClass)
+ break;
+ x=0;
+ y=0;
+ (void) sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
+ (void) AcquireImagePixels(image,(long) (x % image->columns),
+ (long) (y % image->rows),1,1,&image->exception);
+ indexes=AccessImmutableIndexes(image);
+ FormatString(name,"%u",*indexes);
+ s=newSVpv(name,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"iptc") == 0)
+ {
+ if (image)
+ {
+ profile_info=GetImageProfile(image,"IPTC",&profile_length);
+ s=newSVpv((const char *) profile_info,profile_length);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
+ {
+ if (image)
+ s=newSViv((long) image->iterations);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"interlace") == 0)
+ {
+ j=info ? info->image_info->interlace : image->interlace;
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(InterlaceTypes)-1))
+ {
+ (void) sv_setpv(s,InterlaceTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'L':
+ case 'l':
+ {
+ if (LocaleCompare(attribute,"label") == 0)
+ {
+ const ImageAttribute
+ *attribute;
+
+ if (!image)
+ break;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (ImageAttribute *) NULL)
+ s=newSVpv(attribute->value,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
+ {
+ if (image)
+ s=newSViv((long) image->iterations);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare(attribute,"magick") == 0)
+ {
+ if (info && *info->image_info->magick)
+ s=newSVpv(info->image_info->magick,0);
+ else
+ if (image)
+ s=newSVpv(image->magick,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"maximum-error") == 0)
+ {
+ if (image)
+ s=newSVnv(image->error.normalized_maximum_error);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"mean-error") == 0)
+ {
+ if (image)
+ s=newSVnv(image->error.normalized_mean_error);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"monochrome") == 0)
+ {
+ if (!image)
+ continue;
+ j=info ? info->image_info->monochrome :
+ IsMonochromeImage(image,&image->exception);
+ s=newSViv(j);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"mattecolor") == 0)
+ {
+ if (!image)
+ break;
+ FormatString(color,"%u,%u,%u,%u",image->matte_color.red,
+ image->matte_color.green,image->matte_color.blue,
+ image->matte_color.opacity);
+ s=newSVpv(color,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"matte") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->matte);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"montage") == 0)
+ {
+ if (image && image->montage)
+ s=newSVpv(image->montage,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'P':
+ case 'p':
+ {
+ if (LocaleCompare(attribute,"page") == 0)
+ {
+ if (info && info->image_info->page)
+ s=newSVpv(info->image_info->page,0);
+ else
+ if (image)
+ {
+ char
+ geometry[MaxTextExtent];
+
+ FormatString(geometry,"%lux%lu%+ld%+ld",image->page.width,
+ image->page.height,image->page.x,image->page.y);
+ s=newSVpv(geometry,0);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleNCompare(attribute,"pixel",5) == 0)
+ {
+ char
+ name[MaxTextExtent];
+
+ long
+ x,
+ y;
+
+ PixelPacket
+ pixel;
+
+ if (!image)
+ break;
+ x=0;
+ y=0;
+ (void) sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
+ (void) AcquireOnePixelByReference(image,&pixel,(long) (x % image->columns),
+ (long) (y % image->rows),&image->exception);
+ FormatString(name,"%u,%u,%u,%u",pixel.red,pixel.green,pixel.blue,
+ pixel.opacity);
+ s=newSVpv(name,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"pointsize") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->pointsize);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"preview") == 0)
+ {
+ s=newSViv(info->image_info->preview_type);
+ if ((info->image_info->preview_type != UndefinedPreview) &&
+ (info->image_info->preview_type < (long) NumberOf(PreviewTypes)-1))
+ {
+ (void) sv_setpv(s,
+ PreviewTypes[info->image_info->preview_type]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'Q':
+ case 'q':
+ {
+ if (LocaleCompare(attribute,"quality") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->quality);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(attribute,"rendering-intent") == 0)
+ {
+ j=image->rendering_intent;
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(IntentTypes)-1))
+ {
+ (void) sv_setpv(s,IntentTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"red-primary") == 0)
+ {
+ if (!image)
+ break;
+ FormatString(color,"%g,%g",image->chromaticity.red_primary.x,
+ image->chromaticity.red_primary.y);
+ s=newSVpv(color,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"rows") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->rows);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(attribute,"sampling-factor") == 0)
+ {
+ if (info && info->image_info->sampling_factor)
+ s=newSVpv(info->image_info->sampling_factor,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"subimage") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->subimage);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"subrange") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->subrange);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"server") == 0) /* same as display */
+ {
+ if (info && info->image_info->server_name)
+ s=newSVpv(info->image_info->server_name,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"size") == 0)
+ {
+ if (info && info->image_info->size)
+ s=newSVpv(info->image_info->size,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"scene") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->scene);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"signature") == 0)
+ {
+ const ImageAttribute
+ *attribute;
+
+ if (!image)
+ break;
+ (void) SignatureImage(image);
+ attribute=GetImageAttribute(image,"signature");
+ if (attribute != (ImageAttribute *) NULL)
+ s=newSVpv(attribute->value,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare(attribute,"taint") == 0)
+ {
+ if (image)
+ s=newSViv((long) IsTaintImage(image));
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"tile") == 0)
+ {
+ if (info && info->image_info->tile)
+ s=newSVpv(info->image_info->tile,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"texture") == 0)
+ {
+ if (info && info->image_info->texture)
+ s=newSVpv(info->image_info->texture,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"type") == 0)
+ {
+ if (!image)
+ break;
+ j=(long) GetImageType(image,&image->exception);
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(ImageTypes)-1))
+ {
+ (void) sv_setpv(s,ImageTypes[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'U':
+ case 'u':
+ {
+ if (LocaleCompare(attribute,"units") == 0)
+ {
+ j=info ? info->image_info->units : image->units;
+ if (info)
+ if (info->image_info->units == UndefinedResolution)
+ j=image->units;
+ if (j == UndefinedResolution)
+ s=newSVpv("undefined units",0);
+ else
+ if (j == PixelsPerInchResolution)
+ s=newSVpv("pixels / inch",0);
+ else
+ s=newSVpv("pixels / centimeter",0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'V':
+ case 'v':
+ {
+ if (LocaleCompare(attribute,"verbose") == 0)
+ {
+ if (info)
+ s=newSViv((long) info->image_info->verbose);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"view") == 0)
+ {
+ if (info && info->image_info->view)
+ s=newSVpv(info->image_info->view,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"virtual-pixel") == 0)
+ {
+ if (!image)
+ break;
+ j=(long) GetImageVirtualPixelMethod(image);
+ s=newSViv(j);
+ if ((j >= 0) && (j < (long) NumberOf(VirtualPixelMethods)-1))
+ {
+ (void) sv_setpv(s,VirtualPixelMethods[j]);
+ SvIOK_on(s);
+ }
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(attribute,"white-point") == 0)
+ {
+ if (!image)
+ break;
+ FormatString(color,"%g,%g",image->chromaticity.white_point.x,
+ image->chromaticity.white_point.y);
+ s=newSVpv(color,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ if (LocaleCompare(attribute,"width") == 0)
+ {
+ if (image)
+ s=newSViv((long) image->columns);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(attribute,"x-resolution") == 0)
+ {
+ if (image)
+ s=newSVnv(image->x_resolution);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(attribute,"y-resolution") == 0)
+ {
+ if (image)
+ s=newSVnv(image->y_resolution);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ continue;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ default:
+ {
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ }
+ if (image == (Image *) NULL)
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ else
+ {
+ image_attribute=GetImageAttribute(image,attribute);
+ if (image_attribute == (ImageAttribute *) NULL)
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ else
+ {
+ s=newSVpv(image_attribute->value,0);
+ PUSHs(s ? sv_2mortal(s) : &sv_undef);
+ }
+ }
+ }
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# I m a g e T o B l o b #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+ImageToBlob(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ ImageToBlob = 1
+ imagetoblob = 2
+ toblob = 3
+ blob = 4
+ PPCODE:
+ {
+ char
+ filename[MaxTextExtent];
+
+ ExceptionInfo
+ exception;
+
+ Image
+ *image,
+ *next;
+
+ int
+ scene;
+
+ register int
+ i;
+
+ jmp_buf
+ error_jmp;
+
+ struct PackageInfo
+ *info,
+ *package_info;
+
+ size_t
+ length;
+
+ SV
+ *reference;
+
+ void
+ *blob;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ package_info=(struct PackageInfo *) NULL;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ MY_CXT.error_jump=(&error_jmp);
+ if (setjmp(error_jmp))
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ package_info=ClonePackageInfo(info);
+ for (i=2; i < items; i+=2)
+ SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i));
+ (void) strncpy(filename,package_info->image_info->filename,MaxTextExtent-1);
+ scene=0;
+ for (next=image; next; next=next->next)
+ {
+ (void) strncpy(next->filename,filename,MaxTextExtent-1);
+ next->scene=scene++;
+ }
+ SetImageInfo(package_info->image_info,SETMAGICK_WRITE,&image->exception);
+ EXTEND(sp,(long) GetImageListLength(image));
+ GetExceptionInfo(&exception);
+ for ( ; image; image=image->next)
+ {
+ length=0;
+ blob=ImageToBlob(package_info->image_info,image,&length,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (blob != (char *) NULL)
+ {
+ PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
+ MagickFreeMemory(blob);
+ }
+ if (package_info->image_info->adjoin)
+ break;
+ }
+ DestroyExceptionInfo(&exception);
+
+ MethodException:
+ if (package_info)
+ DestroyPackageInfo(package_info);
+ SvREFCNT_dec(MY_CXT.error_list); /* throw away all errors */
+ MY_CXT.error_list=NULL;
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# M o g r i f y #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Mogrify(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ Comment = 1
+ CommentImage = 2
+ Label = 3
+ LabelImage = 4
+ AddNoise = 5
+ AddNoiseImage = 6
+ Colorize = 7
+ ColorizeImage = 8
+ Border = 9
+ BorderImage = 10
+ Blur = 11
+ BlurImage = 12
+ Chop = 13
+ ChopImage = 14
+ Crop = 15
+ CropImage = 16
+ Despeckle = 17
+ DespeckleImage = 18
+ Edge = 19
+ EdgeImage = 20
+ Emboss = 21
+ EmbossImage = 22
+ Enhance = 23
+ EnhanceImage = 24
+ Flip = 25
+ FlipImage = 26
+ Flop = 27
+ FlopImage = 28
+ Frame = 29
+ FrameImage = 30
+ Implode = 31
+ ImplodeImage = 32
+ Magnify = 33
+ MagnifyImage = 34
+ MedianFilter = 35
+ MedianFilterImage = 36
+ Minify = 37
+ MinifyImage = 38
+ OilPaint = 39
+ OilPaintImage = 40
+ ReduceNoise = 41
+ ReduceNoiseImage = 42
+ Roll = 43
+ RollImage = 44
+ Rotate = 45
+ RotateImage = 46
+ Sample = 47
+ SampleImage = 48
+ Scale = 49
+ ScaleImage = 50
+ Shade = 51
+ ShadeImage = 52
+ Sharpen = 53
+ SharpenImage = 54
+ Shear = 55
+ ShearImage = 56
+ Spread = 57
+ SpreadImage = 58
+ Swirl = 59
+ SwirlImage = 60
+ Resize = 61
+ ResizeImage = 62
+ Zoom = 63
+ ZoomImage = 64
+ Annotate = 65
+ AnnotateImage = 66
+ ColorFloodfill = 67
+ ColorFloodfillImage= 68
+ Composite = 69
+ CompositeImage = 70
+ Contrast = 71
+ ContrastImage = 72
+ CycleColormap = 73
+ CycleColormapImage = 74
+ Draw = 75
+ DrawImage = 76
+ Equalize = 77
+ EqualizeImage = 78
+ Gamma = 79
+ GammaImage = 80
+ Map = 81
+ MapImage = 82
+ MatteFloodfill = 83
+ MatteFloodfillImage= 84
+ Modulate = 85
+ ModulateImage = 86
+ Negate = 87
+ NegateImage = 88
+ Normalize = 89
+ NormalizeImage = 90
+ NumberColors = 91
+ NumberColorsImage = 92
+ Opaque = 93
+ OpaqueImage = 94
+ Quantize = 95
+ QuantizeImage = 96
+ Raise = 97
+ RaiseImage = 98
+ Segment = 99
+ SegmentImage = 100
+ Signature = 101
+ SignatureImage = 102
+ Solarize = 103
+ SolarizeImage = 104
+ Sync = 105
+ SyncImage = 106
+ Texture = 107
+ TextureImage = 108
+ Sans = 109
+ SansImage = 110
+ Transparent = 111
+ TransparentImage = 112
+ Threshold = 113
+ ThresholdImage = 114
+ Charcoal = 115
+ CharcoalImage = 116
+ Trim = 117
+ TrimImage = 118
+ Wave = 119
+ WaveImage = 120
+ Channel = 121
+ ChannelImage = 122
+ Stereo = 125
+ StereoImage = 126
+ Stegano = 127
+ SteganoImage = 128
+ Deconstruct = 129
+ DeconstructImage = 130
+ GaussianBlur = 131
+ GaussianBlurImage = 132
+ Convolve = 133
+ ConvolveImage = 134
+ Profile = 135
+ ProfileImage = 136
+ UnsharpMask = 137
+ UnsharpMaskImage = 138
+ MotionBlur = 139
+ MotionBlurImage = 140
+ OrderedDither = 141
+ OrderedDitherImage = 142
+ Shave = 143
+ ShaveImage = 144
+ Level = 145
+ LevelImage = 146
+ Clip = 147
+ ClipImage = 148
+ AffineTransform = 149
+ AffineTransformImage = 150
+ Compare = 151
+ CompareImage = 152
+ AdaptiveThreshold = 153
+ AdaptiveThresholdImage = 154
+ MogrifyRegion = 666
+ PPCODE:
+ {
+ AffineMatrix
+ affine,
+ current;
+
+ char
+ *attribute,
+ /* absolute_geometry[MaxTextExtent], */
+ attribute_flag[MaxArguments],
+ message[MaxTextExtent],
+ *value;
+
+ double
+ angle;
+
+ ExceptionInfo
+ exception;
+
+ FrameInfo
+ frame_info;
+
+ jmp_buf
+ error_jmp;
+
+ Image
+ *image,
+ *next,
+ *region_image;
+
+ int
+ base,
+ flags,
+ j,
+ k,
+ y;
+
+ PixelPacket
+ fill_color;
+
+ RectangleInfo
+ geometry,
+ region_info;
+
+ register int
+ i,
+ x;
+
+ struct PackageInfo
+ *info;
+
+ struct Methods
+ *rp;
+
+ SV
+ **pv,
+ *reference,
+ **reference_vector;
+
+ struct ArgumentList
+ argument_list[MaxArguments];
+
+ volatile int
+ number_images;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ reference_vector=NULL;
+ region_image=NULL;
+ number_images=0;
+ base=2;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto ReturnIt;
+ }
+ reference=SvRV(ST(0));
+ region_info.width=0;
+ region_info.height=0;
+ region_info.x=0;
+ region_info.y=0;
+ region_image=(Image *) NULL;
+ image=SetupList(aTHX_ reference,&info,&reference_vector);
+ if (ix && (ix != 666))
+ {
+ /*
+ Called as Method(...)
+ */
+ ix=(ix+1)/2;
+ rp=(&Methods[ix-1]);
+ attribute=rp->name;
+ }
+ else
+ {
+ /*
+ Called as Mogrify("Method",...)
+ */
+ attribute=(char *) SvPV(ST(1),na);
+ if (ix)
+ {
+ flags=GetImageGeometry(image,attribute,False,&region_info);
+ attribute=(char *) SvPV(ST(2),na);
+ base++;
+ }
+ for (rp=Methods; ; rp++)
+ {
+ if (rp >= EndOf(Methods))
+ {
+ MagickError(OptionError,UnrecognizedPerlMagickMethod,attribute);
+ goto ReturnIt;
+ }
+ if (strEQcase(attribute,rp->name))
+ break;
+ }
+ ix=rp-Methods+1;
+ base++;
+ }
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,attribute);
+ goto ReturnIt;
+ }
+ Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
+ Zero(&attribute_flag,NumberOf(attribute_flag),char);
+ for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
+ {
+ int
+ longest;
+
+ Arguments
+ *pp,
+ *qq;
+
+ struct ArgumentList
+ *al;
+
+ SV
+ *sv;
+
+ longest=0;
+ pp=(Arguments *) NULL;
+ qq=rp->arguments;
+ if (i == items)
+ {
+ pp=rp->arguments,
+ sv=ST(i-1);
+ }
+ else
+ for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
+ {
+ if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
+ break;
+ if (strEQcase(attribute,qq->method) > longest)
+ {
+ pp=qq;
+ longest=strEQcase(attribute,qq->method);
+ }
+ }
+ if (pp == (Arguments *) NULL)
+ {
+ MagickError(OptionError,UnrecognizedOption,attribute);
+ goto continue_outer_loop;
+ }
+ al=(&argument_list[pp-rp->arguments]);
+ if (pp->type == IntegerReference)
+ al->int_reference=SvIV(sv);
+ else
+ if (pp->type == StringReference)
+ al->string_reference=(char *) SvPV(sv,al->length);
+ else
+ if (pp->type == DoubleReference)
+ al->double_reference=SvNV(sv);
+ else
+ if (pp->type == ImageReference)
+ {
+ if (!sv_isobject(sv) ||
+ !(al->image_reference=SetupList(aTHX_ SvRV(sv),
+ (struct PackageInfo **) NULL,(SV ***) NULL)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,
+ PackageName);
+ goto ReturnIt;
+ }
+ }
+ else
+ if (pp->type == ArrayReference)
+ al->array_reference=SvRV(sv);
+ else
+ if (!SvPOK(sv)) /* not a string; just get number */
+ al->int_reference=SvIV(sv);
+ else
+ {
+ /*
+ Is a string; look up name.
+ */
+ al->int_reference=LookupStr(pp->type,SvPV(sv,na));
+ if ((al->int_reference < 0) &&
+ ((al->int_reference=SvIV(sv)) <= 0))
+ {
+ FormatString(message,"invalid %.60s value",pp->method);
+ MagickError(OptionError,message,attribute);
+ goto continue_outer_loop;
+ }
+ }
+ attribute_flag[pp-rp->arguments]++;
+ continue_outer_loop: ;
+ }
+ MY_CXT.error_jump=(&error_jmp);
+ if (setjmp(error_jmp))
+ goto ReturnIt;
+ (void) memset((char *) &fill_color,0,sizeof(PixelPacket));
+ pv=reference_vector;
+ GetExceptionInfo(&exception);
+ for (next=image; next; next=next->next)
+ {
+ image=next;
+ SetGeometry(image,&geometry);
+ if ((region_info.width*region_info.height) != 0)
+ {
+ region_image=image;
+ image=CropImage(image,&region_info,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ }
+ switch (ix)
+ {
+ default:
+ {
+ FormatString(message,"%ld",(long) ix);
+ MagickError(OptionError,UnrecognizedPerlMagickMethod,message);
+ goto ReturnIt;
+ }
+ case 1: /* Comment */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].string_reference=(char *) NULL;
+ (void) SetImageAttribute(image,"comment",(char *) NULL);
+ (void) SetImageAttribute(image,"comment",
+ argument_list[0].string_reference);
+ break;
+ }
+ case 2: /* Label */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].string_reference=(char *) NULL;
+ (void) SetImageAttribute(image,"label",(char *) NULL);
+ (void) SetImageAttribute(image,"label",
+ argument_list[0].string_reference);
+ break;
+ }
+ case 3: /* AddNoise */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].int_reference=UniformNoise;
+ image=AddNoiseImage(image,(NoiseType) argument_list[0].int_reference,
+ &exception);
+ break;
+ }
+ case 4: /* Colorize */
+ {
+ PixelPacket
+ target;
+
+ (void) AcquireOnePixelByReference(image,&target,0,0,&exception);
+ if (attribute_flag[0])
+ (void) QueryColorDatabase(argument_list[0].string_reference,&target,
+ &exception);
+ if (!attribute_flag[1])
+ argument_list[1].string_reference="100";
+ image=ColorizeImage(image,argument_list[1].string_reference,target,
+ &exception);
+ break;
+ }
+ case 5: /* Border */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ if (attribute_flag[1])
+ geometry.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.height=argument_list[2].int_reference;
+ if (attribute_flag[3])
+ QueryColorDatabase(argument_list[3].string_reference,&fill_color,
+ &exception);
+ if (attribute_flag[4])
+ QueryColorDatabase(argument_list[4].string_reference,&fill_color,
+ &exception);
+ if (attribute_flag[3] || attribute_flag[4])
+ image->border_color=fill_color;
+ image=BorderImage(image,&geometry,&exception);
+ break;
+ }
+ case 6: /* Blur */
+ {
+ double
+ radius,
+ sigma;
+
+ radius=0.0;
+ sigma=1.0;
+ if (attribute_flag[1])
+ radius=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ sigma=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",
+ &radius,&sigma);
+ image=BlurImage(image,radius,sigma,&exception);
+ break;
+ }
+ case 7: /* Chop */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ if (attribute_flag[1])
+ geometry.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.height=argument_list[2].int_reference;
+ if (attribute_flag[3])
+ geometry.x=argument_list[3].int_reference;
+ if (attribute_flag[4])
+ geometry.y=argument_list[4].int_reference;
+ image=ChopImage(image,&geometry,&exception);
+ break;
+ }
+ case 8: /* Crop */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ if (attribute_flag[1])
+ geometry.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.height=argument_list[2].int_reference;
+ if (attribute_flag[3])
+ geometry.x=argument_list[3].int_reference;
+ if (attribute_flag[4])
+ geometry.y=argument_list[4].int_reference;
+ image=CropImage(image,&geometry,&exception);
+ break;
+ }
+ case 9: /* Despeckle */
+ {
+ image=DespeckleImage(image,&exception);
+ break;
+ }
+ case 10: /* Edge */
+ {
+ double
+ radius;
+
+ radius=0.0;
+ if (attribute_flag[0])
+ radius=argument_list[0].double_reference;
+ image=EdgeImage(image,radius,&exception);
+ break;
+ }
+ case 11: /* Emboss */
+ {
+ double
+ radius,
+ sigma;
+
+ radius=0.0;
+ sigma=1.0;
+ if (attribute_flag[1])
+ radius=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ sigma=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",
+ &radius,&sigma);
+ image=EmbossImage(image,radius,sigma,&exception);
+ break;
+ }
+ case 12: /* Enhance */
+ {
+ image=EnhanceImage(image,&exception);
+ break;
+ }
+ case 13: /* Flip */
+ {
+ image=FlipImage(image,&exception);
+ break;
+ }
+ case 14: /* Flop */
+ {
+ image=FlopImage(image,&exception);
+ break;
+ }
+ case 15: /* Frame */
+ {
+ if (attribute_flag[0])
+ {
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ frame_info.width=geometry.width;
+ frame_info.height=geometry.height;
+ frame_info.outer_bevel=geometry.x;
+ frame_info.inner_bevel=geometry.y;
+ }
+ if (attribute_flag[1])
+ frame_info.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ frame_info.height=argument_list[2].int_reference;
+ if (attribute_flag[3])
+ frame_info.inner_bevel=argument_list[3].int_reference;
+ if (attribute_flag[4])
+ frame_info.outer_bevel=argument_list[4].int_reference;
+ if (attribute_flag[5])
+ QueryColorDatabase(argument_list[5].string_reference,&fill_color,
+ &exception);
+ if (attribute_flag[6])
+ QueryColorDatabase(argument_list[6].string_reference,&fill_color,
+ &exception);
+ frame_info.x=(long) frame_info.width;
+ frame_info.y=(long) frame_info.height;
+ frame_info.width=image->columns+2*frame_info.x;
+ frame_info.height=image->rows+2*frame_info.y;
+ if (attribute_flag[5] || attribute_flag[6])
+ image->matte_color=fill_color;
+ image=FrameImage(image,&frame_info,&exception);
+ break;
+ }
+ case 16: /* Implode */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].double_reference=0.5;
+ image=ImplodeImage(image,argument_list[0].double_reference,
+ &exception);
+ break;
+ }
+ case 17: /* Magnify */
+ {
+ image=MagnifyImage(image,&exception);
+ break;
+ }
+ case 18: /* MedianFilter */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].double_reference=0.0;
+ image=MedianFilterImage(image,argument_list[0].double_reference,
+ &exception);
+ break;
+ }
+ case 19: /* Minify */
+ {
+ image=MinifyImage(image,&exception);
+ break;
+ }
+ case 20: /* OilPaint */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].double_reference=0.0;
+ image=OilPaintImage(image,argument_list[0].double_reference,
+ &exception);
+ break;
+ }
+ case 21: /* ReduceNoise */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].double_reference=0.0;
+ image=ReduceNoiseImage(image,argument_list[0].double_reference,
+ &exception);
+ break;
+ }
+ case 22: /* Roll */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ if (attribute_flag[1])
+ geometry.x=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.y=argument_list[2].int_reference;
+ image=RollImage(image,geometry.x,geometry.y,&exception);
+ break;
+ }
+ case 23: /* Rotate */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].double_reference=90.0;
+ if (attribute_flag[1])
+ QueryColorDatabase(argument_list[1].string_reference,
+ &image->background_color,&exception);
+ image=RotateImage(image,argument_list[0].double_reference,&exception);
+ break;
+ }
+ case 24: /* Sample */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ True,&geometry);
+ if (attribute_flag[1])
+ geometry.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.height=argument_list[2].int_reference;
+ image=SampleImage(image,geometry.width,geometry.height,&exception);
+ break;
+ }
+ case 25: /* Scale */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ True,&geometry);
+ if (attribute_flag[1])
+ geometry.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.height=argument_list[2].int_reference;
+ image=ScaleImage(image,geometry.width,geometry.height,&exception);
+ break;
+ }
+ case 26: /* Shade */
+ {
+ double
+ azimuth,
+ elevation;
+
+ azimuth=30.0;
+ if (attribute_flag[1])
+ azimuth=argument_list[1].double_reference;
+ elevation=30.0;
+ if (attribute_flag[2])
+ elevation=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",&azimuth,
+ &elevation);
+ image=ShadeImage(image,argument_list[3].int_reference,azimuth,
+ elevation,&exception);
+ break;
+ }
+ case 27: /* Sharpen */
+ {
+ double
+ radius,
+ sigma;
+
+ radius=0.0;
+ sigma=1.0;
+ if (attribute_flag[1])
+ radius=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ sigma=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",
+ &radius,&sigma);
+ image=SharpenImage(image,radius,sigma,&exception);
+ break;
+ }
+ case 28: /* Shear */
+ {
+ double
+ x_shear,
+ y_shear;
+
+ x_shear=45.0;
+ y_shear=45.0;
+ if (attribute_flag[1])
+ x_shear=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ y_shear=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",&x_shear,
+ &y_shear);
+ if (attribute_flag[3])
+ QueryColorDatabase(argument_list[3].string_reference,
+ &image->background_color,&exception);
+ image=ShearImage(image,x_shear,y_shear,&exception);
+ break;
+ }
+ case 29: /* Spread */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].int_reference=1;
+ image=SpreadImage(image,argument_list[0].int_reference,&exception);
+ break;
+ }
+ case 30: /* Swirl */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].double_reference=50.0;
+ image=SwirlImage(image,argument_list[0].double_reference,&exception);
+ break;
+ }
+ case 31: /* Resize */
+ case 32: /* Zoom */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ True,&geometry);
+ if (attribute_flag[1])
+ geometry.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.height=argument_list[2].int_reference;
+ if (!attribute_flag[3])
+ argument_list[3].int_reference=(long) LanczosFilter;
+ if (!attribute_flag[4])
+ argument_list[4].double_reference=1.0;
+ image=ResizeImage(image,geometry.width,geometry.height,
+ (FilterTypes) argument_list[3].int_reference,
+ argument_list[4].double_reference,&exception);
+ break;
+ }
+ case 33: /* Annotate */
+ {
+ DrawInfo
+ *draw_info;
+
+ draw_info=CloneDrawInfo(info ? info->image_info :
+ (ImageInfo *) NULL,info ? info->draw_info : (DrawInfo *) NULL);
+ if (attribute_flag[1])
+ (void) CloneString(&draw_info->font,
+ argument_list[1].string_reference);
+ if (attribute_flag[2])
+ draw_info->pointsize=argument_list[2].double_reference;
+ if (attribute_flag[3])
+ (void) CloneString(&draw_info->density,
+ argument_list[3].string_reference);
+ if (attribute_flag[0])
+ (void) CloneString(&draw_info->text,
+ argument_list[0].string_reference);
+ if (attribute_flag[4])
+ (void) QueryColorDatabase(argument_list[4].string_reference,
+ &draw_info->undercolor,&exception);
+ if (attribute_flag[5])
+ (void) QueryColorDatabase(argument_list[5].string_reference,
+ &draw_info->stroke,&exception);
+ if (attribute_flag[6])
+ (void) QueryColorDatabase(argument_list[6].string_reference,
+ &draw_info->fill,&exception);
+ if (attribute_flag[7])
+ (void) CloneString(&draw_info->geometry,
+ argument_list[7].string_reference);
+ if (attribute_flag[9] || attribute_flag[10])
+ {
+ if (!attribute_flag[9])
+ argument_list[9].int_reference=0;
+ if (!attribute_flag[10])
+ argument_list[10].int_reference=0;
+ FormatString(message,"%+ld%+ld",argument_list[9].int_reference,
+ argument_list[10].int_reference);
+ (void) CloneString(&draw_info->geometry,message);
+ }
+ if (attribute_flag[11])
+ draw_info->gravity=(GravityType) argument_list[11].int_reference;
+ if (attribute_flag[25])
+ {
+ AV
+ *av;
+
+ av=(AV *) argument_list[25].array_reference;
+ if (av_len(av) >= 1)
+ draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
+ if (av_len(av) >= 2)
+ draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
+ if (av_len(av) >= 3)
+ draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
+ if (av_len(av) >= 4)
+ draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
+ if (av_len(av) >= 5)
+ draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
+ if (av_len(av) >= 6)
+ draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
+ }
+ for (j=12; j < 17; j++)
+ {
+ if (!attribute_flag[j])
+ continue;
+ value=argument_list[j].string_reference;
+ angle=argument_list[j].double_reference;
+ current=draw_info->affine;
+ IdentityAffine(&affine);
+ switch (j)
+ {
+ case 12:
+ {
+ /*
+ Translate.
+ */
+ k=sscanf(value,"%lf%*[,/]%lf",&affine.tx,&affine.ty);
+ if (k == 1)
+ affine.ty=affine.tx;
+ break;
+ }
+ case 13:
+ {
+ /*
+ Scale.
+ */
+ k=sscanf(value,"%lf%*[,/]%lf",&affine.sx,&affine.sy);
+ if (k == 1)
+ affine.sy=affine.sx;
+ break;
+ }
+ case 14:
+ {
+ /*
+ Rotate.
+ */
+ if (angle == 0.0)
+ break;
+ affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ case 15:
+ {
+ /*
+ SkewX.
+ */
+ affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ case 16:
+ {
+ /*
+ SkewY.
+ */
+ affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ }
+ draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
+ current.tx;
+ draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
+ current.ty;
+ }
+ if (attribute_flag[17])
+ draw_info->stroke_width=argument_list[17].int_reference;
+ if (attribute_flag[18])
+ draw_info->text_antialias=argument_list[18].int_reference != 0;
+ if (attribute_flag[19])
+ (void) CloneString(&draw_info->family,
+ argument_list[19].string_reference);
+ if (attribute_flag[20])
+ draw_info->style=(StyleType) argument_list[20].int_reference;
+ if (attribute_flag[21])
+ draw_info->stretch=(StretchType) argument_list[21].int_reference;
+ if (attribute_flag[22])
+ draw_info->weight=argument_list[22].int_reference;
+ if (attribute_flag[23])
+ draw_info->align=(AlignType) argument_list[23].int_reference;
+ if (attribute_flag[24])
+ (void) CloneString(&draw_info->encoding,
+ argument_list[24].string_reference);
+ if (attribute_flag[26])
+ (void) QueryColorDatabase(argument_list[26].string_reference,
+ &draw_info->undercolor,&exception);
+ AnnotateImage(image,draw_info);
+ DestroyDrawInfo(draw_info);
+ break;
+ }
+ case 34: /* ColorFloodfill */
+ {
+ DrawInfo
+ *draw_info;
+
+ PixelPacket
+ target;
+
+ draw_info=CloneDrawInfo(info ? info->image_info :
+ (ImageInfo *) NULL,info ? info->draw_info : (DrawInfo *) NULL);
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ if (attribute_flag[1])
+ geometry.x=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.y=argument_list[2].int_reference;
+ if (attribute_flag[3])
+ (void) QueryColorDatabase(argument_list[3].string_reference,
+ &draw_info->fill,&exception);
+ if (attribute_flag[4])
+ QueryColorDatabase(argument_list[4].string_reference,&fill_color,
+ &exception);
+ (void) AcquireOnePixelByReference(image,&target,(long) (geometry.x % image->columns),
+ (long) (geometry.y % image->rows),&exception);
+ if (attribute_flag[4])
+ target=fill_color;
+ if (attribute_flag[5])
+ image->fuzz=argument_list[5].double_reference;
+ ColorFloodfillImage(image,draw_info,target,geometry.x,geometry.y,
+ attribute_flag[4] ? FillToBorderMethod : FloodfillMethod);
+ DestroyDrawInfo(draw_info);
+ break;
+ }
+ case 35: /* Composite */
+ {
+ char
+ composite_geometry[MaxTextExtent];
+
+ CompositeOperator
+ compose;
+
+ double
+ opacity;
+
+ Image
+ *composite_image,
+ *mask_image,
+ *rotate_image;
+
+ compose=OverCompositeOp;
+ if (attribute_flag[0])
+ composite_image=argument_list[0].image_reference;
+ else
+ {
+ MagickError(OptionError,CompositeImageRequired,NULL);
+ goto ReturnIt;
+ }
+ if (attribute_flag[1])
+ compose=(CompositeOperator) argument_list[1].int_reference;
+ opacity=OpaqueOpacity;
+ if (attribute_flag[6])
+ {
+ opacity=argument_list[6].double_reference;
+ if (compose == DissolveCompositeOp)
+ {
+ register PixelPacket
+ *q;
+
+ if (!composite_image->matte)
+ SetImageOpacity(composite_image,OpaqueOpacity);
+ for (y=0; y < (long) composite_image->rows; y++)
+ {
+ q=GetImagePixels(composite_image,0,y,
+ composite_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=(long) composite_image->columns; x > 0; x--)
+ {
+ q->opacity=(Quantum) ((opacity*(MaxRGB-q->opacity))/100.0);
+ q++;
+ }
+ if (!SyncImagePixels(composite_image))
+ break;
+ }
+ }
+ else
+ {
+ if (opacity != OpaqueOpacity)
+ SetImageOpacity(composite_image,(unsigned int) opacity);
+ }
+ }
+ if (attribute_flag[9])
+ QueryColorDatabase(argument_list[9].string_reference,
+ &composite_image->background_color,&exception);
+ rotate_image=(Image *) NULL;
+ if (attribute_flag[8])
+ {
+ /*
+ Rotate image.
+ */
+ rotate_image=RotateImage(composite_image,
+ argument_list[8].double_reference,&exception);
+ if (rotate_image == (Image *) NULL)
+ break;
+ }
+ if (attribute_flag[7] && argument_list[7].int_reference)
+ {
+ /*
+ Tile image on background.
+ */
+ for (y=0; y < (long) image->rows; y+=composite_image->rows)
+ for (x=0; x < (long) image->columns; x+=composite_image->columns)
+ {
+ if (attribute_flag[8])
+ (void) CompositeImage(image,compose,rotate_image,x,y);
+ else
+ (void) CompositeImage(image,compose,composite_image,x,y);
+ (void) CatchImageException(image);
+ }
+ if (attribute_flag[8])
+ DestroyImage(rotate_image);
+ break;
+ }
+ if (attribute_flag[2])
+ flags=GetGeometry(argument_list[2].string_reference,&geometry.x,
+ &geometry.y,&geometry.width,&geometry.height);
+ if (attribute_flag[3])
+ geometry.x=argument_list[3].int_reference;
+ if (attribute_flag[4])
+ geometry.y=argument_list[4].int_reference;
+ if (attribute_flag[5])
+ image->gravity=(GravityType) argument_list[5].int_reference;
+ if (attribute_flag[10])
+ {
+ mask_image=argument_list[10].image_reference;
+ SetImageType(composite_image,TrueColorMatteType);
+ if (!composite_image->matte)
+ SetImageOpacity(composite_image,OpaqueOpacity);
+ (void) CompositeImage(composite_image,CopyOpacityCompositeOp,
+ mask_image,0,0);
+ }
+ /*
+ Composite image.
+ */
+ FormatString(composite_geometry,"%lux%lu%+ld%+ld",
+ composite_image->columns,composite_image->rows,geometry.x,
+ geometry.y);
+ flags=GetImageGeometry(image,composite_geometry,False,&geometry);
+ if (!attribute_flag[8])
+ CompositeImage(image,compose,composite_image,geometry.x,geometry.y);
+ else
+ {
+ /*
+ Rotate image.
+ */
+ geometry.x-=(long)
+ (rotate_image->columns-composite_image->columns)/2;
+ geometry.y-=(long) (rotate_image->rows-composite_image->rows)/2;
+ CompositeImage(image,compose,rotate_image,geometry.x,geometry.y);
+ DestroyImage(rotate_image);
+ }
+ break;
+ }
+ case 36: /* Contrast */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].int_reference=0;
+ ContrastImage(image,argument_list[0].int_reference);
+ break;
+ }
+ case 37: /* CycleColormap */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].int_reference=6;
+ CycleColormapImage(image,argument_list[0].int_reference);
+ break;
+ }
+ case 38: /* Draw */
+ {
+ DrawInfo
+ *draw_info;
+
+ draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
+ info ? info->draw_info : (DrawInfo *) NULL);
+ draw_info->fill.opacity=TransparentOpacity;
+ draw_info->stroke.opacity=OpaqueOpacity;
+ (void) CloneString(&draw_info->primitive,"Point");
+ if (attribute_flag[0] && (argument_list[0].int_reference > 0))
+ (void) CloneString(&draw_info->primitive,
+ PrimitiveTypes[argument_list[0].int_reference]);
+ if (attribute_flag[1])
+ {
+ if (LocaleCompare(draw_info->primitive,"path") == 0)
+ {
+ (void) ConcatenateString(&draw_info->primitive," '");
+ ConcatenateString(&draw_info->primitive,
+ argument_list[1].string_reference);
+ (void) ConcatenateString(&draw_info->primitive,"'");
+ }
+ else
+ {
+ (void) ConcatenateString(&draw_info->primitive," ");
+ ConcatenateString(&draw_info->primitive,
+ argument_list[1].string_reference);
+ }
+ }
+ if (attribute_flag[2])
+ {
+ (void) ConcatenateString(&draw_info->primitive," ");
+ (void) ConcatenateString(&draw_info->primitive,
+ MethodTypes[argument_list[2].int_reference]);
+ }
+ if (attribute_flag[3])
+ (void) QueryColorDatabase(argument_list[3].string_reference,
+ &draw_info->stroke,&exception);
+ if (attribute_flag[4])
+ (void) QueryColorDatabase(argument_list[4].string_reference,
+ &draw_info->fill,&exception);
+ if (attribute_flag[5])
+ draw_info->stroke_width=argument_list[5].double_reference;
+ if (attribute_flag[6])
+ (void) CloneString(&draw_info->font,
+ argument_list[6].string_reference);
+ if (attribute_flag[7])
+ (void) QueryColorDatabase(argument_list[7].string_reference,
+ &draw_info->border_color,&exception);
+ if (attribute_flag[8])
+ draw_info->affine.tx=argument_list[8].double_reference;
+ if (attribute_flag[9])
+ draw_info->affine.ty=argument_list[9].double_reference;
+ if (attribute_flag[20])
+ {
+ AV
+ *av;
+
+ av=(AV *) argument_list[20].array_reference;
+ if (av_len(av) >= 1)
+ draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
+ if (av_len(av) >= 2)
+ draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
+ if (av_len(av) >= 3)
+ draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
+ if (av_len(av) >= 4)
+ draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
+ if (av_len(av) >= 5)
+ draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
+ if (av_len(av) >= 6)
+ draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
+ }
+ for (j=10; j < 15; j++)
+ {
+ if (!attribute_flag[j])
+ continue;
+ value=argument_list[j].string_reference;
+ angle=argument_list[j].double_reference;
+ current=draw_info->affine;
+ IdentityAffine(&affine);
+ switch (j)
+ {
+ case 10:
+ {
+ /*
+ Translate.
+ */
+ k=sscanf(value,"%lf%*[,/]%lf",&affine.tx,&affine.ty);
+ if (k == 1)
+ affine.ty=affine.tx;
+ break;
+ }
+ case 11:
+ {
+ /*
+ Scale.
+ */
+ k=sscanf(value,"%lf%*[,/]%lf",&affine.sx,&affine.sy);
+ if (k == 1)
+ affine.sy=affine.sx;
+ break;
+ }
+ case 12:
+ {
+ /*
+ Rotate.
+ */
+ if (angle == 0.0)
+ break;
+ affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ case 13:
+ {
+ /*
+ SkewX.
+ */
+ affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ case 14:
+ {
+ /*
+ SkewY.
+ */
+ affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ }
+ draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ draw_info->affine.tx=
+ current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ draw_info->affine.ty=
+ current.rx*affine.tx+current.sy*affine.ty+current.ty;
+ }
+ if (attribute_flag[15])
+ draw_info->fill_pattern=
+ CloneImage(argument_list[15].image_reference,0,0,True,&exception);
+ if (attribute_flag[16])
+ draw_info->pointsize=argument_list[16].double_reference;
+ if (attribute_flag[17])
+ {
+ draw_info->stroke_antialias=argument_list[17].int_reference != 0;
+ draw_info->text_antialias=argument_list[17].int_reference != 0;
+ }
+ if (attribute_flag[18])
+ (void) CloneString(&draw_info->density,
+ argument_list[18].string_reference);
+ if (attribute_flag[19])
+ draw_info->stroke_width=argument_list[19].double_reference;
+ DrawImage(image,draw_info);
+ DestroyDrawInfo(draw_info);
+ break;
+ }
+ case 39: /* Equalize */
+ {
+ EqualizeImage(image);
+ break;
+ }
+ case 40: /* Gamma */
+ {
+ if (!attribute_flag[1])
+ argument_list[1].double_reference=1.0;
+ if (!attribute_flag[2])
+ argument_list[2].double_reference=1.0;
+ if (!attribute_flag[3])
+ argument_list[3].double_reference=1.0;
+ if (!attribute_flag[0])
+ {
+ FormatString(message,"%g,%g,%g",
+ argument_list[1].double_reference,
+ argument_list[2].double_reference,
+ argument_list[3].double_reference);
+ argument_list[0].string_reference=message;
+ }
+ GammaImage(image,argument_list[0].string_reference);
+ break;
+ }
+ case 41: /* Map */
+ {
+ if (!attribute_flag[1])
+ argument_list[1].int_reference=1;
+ if (!attribute_flag[0])
+ {
+ MagickError(OptionError,MapImageRequired,NULL);
+ goto ReturnIt;
+ }
+ (void) MapImages(image,argument_list[0].image_reference,
+ argument_list[1].int_reference);
+ break;
+ }
+ case 42: /* MatteFloodfill */
+ {
+ PixelPacket
+ target;
+
+ unsigned int
+ opacity;
+
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ if (attribute_flag[1])
+ geometry.x=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.y=argument_list[2].int_reference;
+ if (attribute_flag[4])
+ QueryColorDatabase(argument_list[4].string_reference,&fill_color,
+ &exception);
+ opacity=TransparentOpacity;
+ if (attribute_flag[3])
+ opacity=argument_list[3].int_reference;
+ if (!image->matte)
+ SetImageOpacity(image,OpaqueOpacity);
+ (void) AcquireOnePixelByReference(image,&target,(long) (geometry.x % image->columns),
+ (long) (geometry.y % image->rows),&exception);
+ if (attribute_flag[4])
+ target=fill_color;
+ if (attribute_flag[5])
+ image->fuzz=argument_list[5].double_reference;
+ MatteFloodfillImage(image,target,opacity,geometry.x,geometry.y,
+ attribute_flag[4] ? FillToBorderMethod : FloodfillMethod);
+ break;
+ }
+ case 43: /* Modulate */
+ {
+ if (!attribute_flag[1])
+ argument_list[1].double_reference=100.0;
+ if (!attribute_flag[2])
+ argument_list[2].double_reference=100.0;
+ if (!attribute_flag[3])
+ argument_list[3].double_reference=100.0;
+ FormatString(message,"%g,%g,%g",
+ argument_list[1].double_reference,
+ argument_list[2].double_reference,
+ argument_list[3].double_reference);
+ if (!attribute_flag[0])
+ argument_list[0].string_reference=message;
+ ModulateImage(image,argument_list[0].string_reference);
+ break;
+ }
+ case 44: /* Negate */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].int_reference=0;
+ NegateImage(image,argument_list[0].int_reference);
+ break;
+ }
+ case 45: /* Normalize */
+ {
+ NormalizeImage(image);
+ break;
+ }
+ case 46: /* NumberColors */
+ break;
+ case 47: /* Opaque */
+ {
+ PixelPacket
+ fill_color,
+ target;
+
+ (void) AcquireOnePixelByReference(image,&target,0,0,&exception);
+ if (attribute_flag[0])
+ (void) QueryColorDatabase(argument_list[0].string_reference,
+ &target,&exception);
+ (void) AcquireOnePixelByReference(image,&fill_color,0,0,&exception);
+ if (attribute_flag[1])
+ (void) QueryColorDatabase(argument_list[1].string_reference,
+ &fill_color,&exception);
+ if (attribute_flag[2])
+ image->fuzz=argument_list[2].double_reference;
+ OpaqueImage(image,target,fill_color);
+ break;
+ }
+ case 48: /* Quantize */
+ {
+ QuantizeInfo
+ quantize_info;
+
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.number_colors=
+ attribute_flag[0] ? argument_list[0].int_reference : (info ?
+ info->quantize_info->number_colors : MaxRGB + 1);
+ quantize_info.tree_depth=attribute_flag[1] ?
+ argument_list[1].int_reference :
+ (info ? info->quantize_info->tree_depth : 8);
+ quantize_info.colorspace=(ColorspaceType)
+ (attribute_flag[2] ? argument_list[2].int_reference :
+ (info? info->quantize_info->colorspace : RGBColorspace));
+ quantize_info.dither=attribute_flag[3] ?
+ argument_list[3].int_reference :
+ (info ? info->quantize_info->dither : False);
+ quantize_info.measure_error=attribute_flag[4] ?
+ argument_list[4].int_reference :
+ (info ? info->quantize_info->measure_error : False);
+ if (attribute_flag[5] && argument_list[5].int_reference)
+ {
+ (void) QuantizeImages(&quantize_info,image);
+ goto ReturnIt;
+ }
+ if ((image->storage_class == DirectClass) ||
+ (image->colors > quantize_info.number_colors) ||
+ (quantize_info.colorspace == GRAYColorspace))
+ (void) QuantizeImage(&quantize_info,image);
+ else
+ CompressImageColormap(image);
+ break;
+ }
+ case 49: /* Raise */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ if (attribute_flag[1])
+ geometry.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.height=argument_list[2].int_reference;
+ if (!attribute_flag[3])
+ argument_list[3].int_reference=1;
+ RaiseImage(image,&geometry,argument_list[3].int_reference);
+ break;
+ }
+ case 50: /* Segment */
+ {
+ ColorspaceType
+ colorspace;
+
+ double
+ cluster_threshold,
+ smoothing_threshold;
+
+ unsigned int
+ verbose;
+
+ cluster_threshold=1.0;
+ smoothing_threshold=1.5;
+ colorspace=RGBColorspace;
+ verbose=False;
+ if (attribute_flag[1])
+ cluster_threshold=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ smoothing_threshold=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",
+ &cluster_threshold,&smoothing_threshold);
+ if (attribute_flag[3])
+ colorspace=(ColorspaceType) argument_list[3].int_reference;
+ if (attribute_flag[4])
+ verbose=argument_list[4].int_reference != 0;
+ (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
+ smoothing_threshold);
+ break;
+ }
+ case 51: /* Signature */
+ {
+ (void) SignatureImage(image);
+ break;
+ }
+ case 52: /* Solarize */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].double_reference=50.0;
+ SolarizeImage(image,argument_list[0].double_reference);
+ break;
+ }
+ case 53: /* Sync */
+ {
+ (void) SyncImage(image);
+ break;
+ }
+ case 54: /* Texture */
+ {
+ if (!attribute_flag[0])
+ break;
+ TextureImage(image,argument_list[0].image_reference);
+ break;
+ }
+ case 55: /* Sans */
+ break;
+ case 56: /* Transparent */
+ {
+ PixelPacket
+ target;
+
+ unsigned int
+ opacity;
+
+ (void) AcquireOnePixelByReference(image,&target,0,0,&exception);
+ if (attribute_flag[0])
+ (void) QueryColorDatabase(argument_list[0].string_reference,
+ &target,&exception);
+ opacity=TransparentOpacity;
+ if (attribute_flag[1])
+ opacity=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ image->fuzz=argument_list[2].double_reference;
+ TransparentImage(image,target,opacity);
+ break;
+ }
+ case 57: /* Threshold */
+ {
+ double
+ threshold;
+
+ int
+ count;
+
+ if (!attribute_flag[0])
+ argument_list[0].string_reference="50%";
+ count=sscanf(argument_list[0].string_reference,"%lf",&threshold);
+ if (count > 0)
+ {
+ if (strchr(argument_list[0].string_reference,'%') != (char *) NULL)
+ threshold *= MaxRGB/100.0;
+ (void) ThresholdImage(image,threshold);
+ }
+ break;
+ }
+ case 58: /* Charcoal */
+ {
+ double
+ radius,
+ sigma;
+
+ radius=0.0;
+ sigma=1.0;
+ if (attribute_flag[1])
+ radius=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ sigma=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",
+ &radius,&sigma);
+ image=CharcoalImage(image,radius,sigma,&exception);
+ break;
+ }
+ case 59: /* Trim */
+ {
+ if (attribute_flag[0])
+ image->fuzz=argument_list[0].double_reference;
+ flags=GetGeometry("0x0",&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ image=CropImage(image,&geometry,&exception);
+ break;
+ }
+ case 60: /* Wave */
+ {
+ double
+ amplitude,
+ wavelength;
+
+ amplitude=25.0;
+ wavelength=150.0;
+ if (attribute_flag[1])
+ amplitude=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ wavelength=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",
+ &amplitude,&wavelength);
+ image=WaveImage(image,amplitude,wavelength,&exception);
+ break;
+ }
+ case 61: /* Channel */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].int_reference=1;
+ ChannelImage(image,(ChannelType) argument_list[0].int_reference);
+ break;
+ }
+ case 63: /* Stereo */
+ {
+ if (!attribute_flag[0])
+ {
+ MagickError(OptionError,StereoImageRequired,NULL);
+ goto ReturnIt;
+ }
+ image=StereoImage(image,argument_list[0].image_reference,&exception);
+ break;
+ }
+ case 64: /* Stegano */
+ {
+ if (!attribute_flag[1])
+ argument_list[1].int_reference=0;
+ if (!attribute_flag[0])
+ {
+ MagickError(OptionError,SteganoImageRequired,NULL);
+ goto ReturnIt;
+ }
+ image->offset=argument_list[1].int_reference;
+ image=SteganoImage(image,argument_list[0].image_reference,&exception);
+ break;
+ }
+ case 65: /* Deconstruct */
+ {
+ image=DeconstructImages(image,&exception);
+ break;
+ }
+ case 66: /* GaussianBlur */
+ {
+ double
+ radius,
+ sigma;
+
+ radius=0.0;
+ sigma=1.0;
+ if (attribute_flag[1])
+ radius=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ sigma=argument_list[2].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",
+ &radius,&sigma);
+ image=GaussianBlurImage(image,radius,sigma,&exception);
+ break;
+ }
+ case 67: /* Convolve */
+ {
+ AV
+ *av;
+
+ double
+ *kernel;
+
+ unsigned int
+ radius;
+
+ if (!attribute_flag[0])
+ break;
+ av=(AV *) argument_list[0].array_reference;
+ radius=(unsigned int) sqrt(av_len(av)+1);
+ kernel=MagickAllocateMemory(double *,radius*radius*sizeof(double));
+ for (j=0; j < (av_len(av)+1); j++)
+ kernel[j]=(double) SvNV(*(av_fetch(av,j,0)));
+ for ( ; j < (long) (radius*radius); j++)
+ kernel[j]=0.0;
+ image=ConvolveImage(image,radius,kernel,&exception);
+ MagickFreeMemory(kernel);
+ break;
+ }
+ case 68: /* Profile */
+ {
+ if (!attribute_flag[0])
+ argument_list[0].string_reference="*";
+ if (!attribute_flag[1])
+ argument_list[1].string_reference=(char *) NULL;
+ (void) ProfileImage(image,argument_list[0].string_reference,
+ (unsigned char *) argument_list[1].string_reference,
+ argument_list[1].length,True);
+ break;
+ }
+ case 69: /* UnsharpMask */
+ {
+ double
+ amount,
+ radius,
+ sigma,
+ threshold;
+
+ radius=0.0;
+ sigma=1.0;
+ amount=1.0;
+ threshold=0.05;
+ if (attribute_flag[1])
+ radius=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ sigma=argument_list[2].double_reference;
+ if (attribute_flag[3])
+ amount=argument_list[3].double_reference;
+ if (attribute_flag[4])
+ threshold=argument_list[4].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf%lf%lf",
+ &radius,&sigma,&amount,&threshold);
+ image=UnsharpMaskImage(image,radius,sigma,amount,threshold,
+ &exception);
+ break;
+ }
+ case 70: /* MotionBlur */
+ {
+ double
+ angle,
+ radius,
+ sigma;
+
+ radius=0.0;
+ sigma=1.0;
+ angle=1.0;
+ if (attribute_flag[1])
+ radius=argument_list[1].double_reference;
+ if (attribute_flag[2])
+ sigma=argument_list[2].double_reference;
+ if (attribute_flag[3])
+ angle=argument_list[3].double_reference;
+ if (attribute_flag[0])
+ (void) sscanf(argument_list[0].string_reference,"%lfx%lf",
+ &radius,&sigma);
+ image=MotionBlurImage(image,radius,sigma,angle,&exception);
+ break;
+ }
+ case 71: /* OrderedDither */
+ {
+ (void) OrderedDitherImage(image);
+ break;
+ }
+ case 72: /* Shave */
+ {
+ if (attribute_flag[0])
+ flags=GetImageGeometry(image,argument_list[0].string_reference,
+ False,&geometry);
+ if (attribute_flag[1])
+ geometry.width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ geometry.height=argument_list[2].int_reference;
+ image=ShaveImage(image,&geometry,&exception);
+ break;
+ }
+ case 73: /* Level */
+ {
+ if (!attribute_flag[1])
+ argument_list[1].double_reference=0.0;
+ if (!attribute_flag[2])
+ argument_list[2].double_reference=1.0;
+ if (!attribute_flag[3])
+ argument_list[3].double_reference=MaxRGB;
+ if (!attribute_flag[0])
+ {
+ FormatString(message,"%g,%g,%g",
+ argument_list[1].double_reference,
+ argument_list[2].double_reference,
+ argument_list[3].double_reference);
+ argument_list[0].string_reference=message;
+ }
+ LevelImage(image,argument_list[0].string_reference);
+ break;
+ }
+ case 74: /* Clip */
+ {
+ (void) ClipImage(image);
+ break;
+ }
+ case 75: /* AffineTransform */
+ {
+ DrawInfo
+ *draw_info;
+
+ draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
+ info ? info->draw_info : (DrawInfo *) NULL);
+ if (attribute_flag[0])
+ {
+ AV
+ *av;
+
+ av=(AV *) argument_list[0].array_reference;
+ if (av_len(av) >= 1)
+ draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
+ if (av_len(av) >= 2)
+ draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
+ if (av_len(av) >= 3)
+ draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
+ if (av_len(av) >= 4)
+ draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
+ if (av_len(av) >= 5)
+ draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
+ if (av_len(av) >= 6)
+ draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
+ }
+ for (j=1; j < 6; j++)
+ {
+ if (!attribute_flag[j])
+ continue;
+ value=argument_list[j].string_reference;
+ angle=argument_list[j].double_reference;
+ current=draw_info->affine;
+ IdentityAffine(&affine);
+ switch (j)
+ {
+ case 1:
+ {
+ /*
+ Translate.
+ */
+ k=sscanf(value,"%lf%*[,/]%lf",&affine.tx,&affine.ty);
+ if (k == 1)
+ affine.ty=affine.tx;
+ break;
+ }
+ case 2:
+ {
+ /*
+ Scale.
+ */
+ k=sscanf(value,"%lf%*[,/]%lf",&affine.sx,&affine.sy);
+ if (k == 1)
+ affine.sy=affine.sx;
+ break;
+ }
+ case 3:
+ {
+ /*
+ Rotate.
+ */
+ if (angle == 0.0)
+ break;
+ affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ case 4:
+ {
+ /*
+ SkewX.
+ */
+ affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ case 5:
+ {
+ /*
+ SkewY.
+ */
+ affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ }
+ draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ draw_info->affine.tx=
+ current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ draw_info->affine.ty=
+ current.rx*affine.tx+current.sy*affine.ty+current.ty;
+ }
+ image=AffineTransformImage(image,&draw_info->affine,&exception);
+ DestroyDrawInfo(draw_info);
+ break;
+ }
+ case 76: /* Compare */
+ {
+ if (!attribute_flag[0])
+ {
+ MagickError(OptionError,ReferenceImageRequired,NULL);
+ goto ReturnIt;
+ }
+ (void) IsImagesEqual(image,argument_list[0].image_reference);
+ break;
+ }
+ case 77: /* AdaptiveThreshold */
+ {
+ double
+ offset;
+
+ unsigned long
+ height,
+ width;
+
+ height=3;
+ width=3;
+ offset=0.0;
+ if (attribute_flag[1])
+ width=argument_list[1].int_reference;
+ if (attribute_flag[2])
+ height=argument_list[2].int_reference;
+ if (attribute_flag[3])
+ offset=argument_list[3].int_reference;;
+ if (attribute_flag[0])
+ {
+ (void) sscanf(argument_list[0].string_reference,"%lux%lu%lf",
+ &width,&height,&offset);
+ if (strchr(argument_list[0].string_reference,'%') != (char *) NULL)
+ offset*=(double) MaxRGB/100.0;
+ }
+ image=AdaptiveThresholdImage(image,width,height,offset,&exception);
+ break;
+ }
+ }
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (next != (Image *) NULL)
+ (void) CatchImageException(next);
+ if (region_image != (Image *) NULL)
+ {
+ unsigned int
+ status;
+
+ /*
+ Composite region.
+ */
+ status=CompositeImage(region_image,CopyCompositeOp,image,
+ region_info.x,region_info.y);
+ (void) CatchImageException(region_image);
+ DestroyImage(image);
+ image=region_image;
+ }
+ if (image)
+ {
+ number_images++;
+ if (next && (next != image))
+ {
+ image->next=next->next;
+ next->previous=0;
+ DestroyImage(next);
+ }
+ sv_setiv(*pv,(IV) image);
+ next=image;
+ }
+ if (*pv)
+ pv++;
+ }
+ DestroyExceptionInfo(&exception);
+
+ ReturnIt:
+ MagickFreeMemory(reference_vector);
+ sv_setiv(MY_CXT.error_list,(IV) number_images);
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# M o n t a g e #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Montage(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ MontageImage = 1
+ montage = 2
+ montageimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ *attribute;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ Image
+ *image,
+ *next;
+
+ int
+ sp;
+
+ jmp_buf
+ error_jmp;
+
+ MontageInfo
+ *montage_info;
+
+ PixelPacket
+ transparent_color;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *av_reference,
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ status=0;
+ attribute=NULL;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ av=newAV();
+ av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ /*
+ Get options.
+ */
+ info=GetPackageInfo(aTHX_ (void *) av,info);
+ montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
+ GetExceptionInfo(&exception);
+ (void) QueryColorDatabase("none",&transparent_color,&exception);
+ for (i=2; i < items; i+=2)
+ {
+ attribute=(char *) SvPV(ST(i-1),na);
+ switch (*attribute)
+ {
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare(attribute,"background") == 0)
+ {
+ (void) QueryColorDatabase(SvPV(ST(i),na),
+ &montage_info->background_color,&exception);
+ break;
+ }
+ if (LocaleCompare(attribute,"bordercolor") == 0)
+ {
+ (void) QueryColorDatabase(SvPV(ST(i),na),
+ &montage_info->border_color,&exception);
+ break;
+ }
+ if (LocaleCompare(attribute,"borderwidth") == 0)
+ {
+ montage_info->border_width=SvIV(ST(i));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(attribute,"compose") == 0)
+ {
+ sp=!SvPOK(ST(i)) ? SvIV(ST(i)) :
+ LookupStr(CompositeTypes,SvPV(ST(i),na));
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,
+ SvPV(ST(i),na));
+ break;
+ }
+ for (next=image; next; next=next->next)
+ next->compose=(CompositeOperator) sp;
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(attribute,"fill") == 0)
+ {
+ (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->fill,
+ &exception);
+ break;
+ }
+ if (LocaleCompare(attribute,"font") == 0)
+ {
+ (void) CloneString(&montage_info->font,SvPV(ST(i),na));
+ break;
+ }
+ if (LocaleCompare(attribute,"frame") == 0)
+ {
+ char
+ *p;
+
+ p=SvPV(ST(i),na);
+ if (!IsGeometry(p))
+ {
+ MagickError(OptionError,MissingGeometry,p);
+ break;
+ }
+ (void) CloneString(&montage_info->frame,p);
+ if (*p == '\0')
+ montage_info->frame=(char *) NULL;
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(attribute,"geometry") == 0)
+ {
+ char
+ *p;
+
+ p=SvPV(ST(i),na);
+ if (!IsGeometry(p))
+ {
+ MagickError(OptionError,MissingGeometry,p);
+ break;
+ }
+ (void) CloneString(&montage_info->geometry,p);
+ if (*p == '\0')
+ montage_info->geometry=(char *) NULL;
+ break;
+ }
+ if (LocaleCompare(attribute,"gravity") == 0)
+ {
+ int
+ in;
+
+ in=!SvPOK(ST(i)) ? SvIV(ST(i)) :
+ LookupStr(GravityTypes,SvPV(ST(i),na));
+ if (in < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(ST(i),na));
+ return;
+ }
+ montage_info->gravity=(GravityType) in;
+ for (next=image; next; next=next->next)
+ next->gravity=(GravityType) in;
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'L':
+ case 'l':
+ {
+ if (LocaleCompare(attribute,"label") == 0)
+ {
+ for (next=image; next; next=next->next)
+ (void) SetImageAttribute(next,"label",SvPV(ST(i),na));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare(attribute,"mattecolor") == 0)
+ {
+ (void) QueryColorDatabase(SvPV(ST(i),na),
+ &montage_info->matte_color,&exception);
+ break;
+ }
+ if (LocaleCompare(attribute,"mode") == 0)
+ {
+ int
+ in;
+
+ in=!SvPOK(ST(i)) ? SvIV(ST(i)) :
+ LookupStr(ModeTypes,SvPV(ST(i),na));
+ switch (in)
+ {
+ default:
+ {
+ MagickError(OptionError,UnrecognizedModeType,
+ SvPV(ST(i),na));
+ break;
+ }
+ case FrameMode:
+ {
+ (void) CloneString(&montage_info->frame,"15x15+3+3");
+ montage_info->shadow=True;
+ break;
+ }
+ case UnframeMode:
+ {
+ montage_info->frame=(char *) NULL;
+ montage_info->shadow=False;
+ montage_info->border_width=0;
+ break;
+ }
+ case ConcatenateMode:
+ {
+ montage_info->frame=(char *) NULL;
+ montage_info->shadow=False;
+ (void) CloneString(&montage_info->geometry,"+0+0");
+ montage_info->border_width=0;
+ }
+ }
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'P':
+ case 'p':
+ {
+ if (LocaleCompare(attribute,"pointsize") == 0)
+ {
+ montage_info->pointsize=SvIV(ST(i));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(attribute,"shadow") == 0)
+ {
+ sp=!SvPOK(ST(i)) ? SvIV(ST(i)) :
+ LookupStr(BooleanTypes,SvPV(ST(i),na));
+ if (sp < 0)
+ {
+ MagickError(OptionError,UnrecognizedType,SvPV(ST(i),na));
+ break;
+ }
+ montage_info->shadow=sp != 0;
+ break;
+ }
+ if (LocaleCompare(attribute,"stroke") == 0)
+ {
+ (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->stroke,
+ &exception);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare(attribute,"texture") == 0)
+ {
+ (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
+ break;
+ }
+ if (LocaleCompare(attribute,"tile") == 0)
+ {
+ char *p=SvPV(ST(i),na);
+ if (!IsGeometry(p))
+ {
+ MagickError(OptionError,MissingGeometry,p);
+ break;
+ }
+ (void) CloneString(&montage_info->tile,p);
+ if (*p == '\0')
+ montage_info->tile=(char *) NULL;
+ break;
+ }
+ if (LocaleCompare(attribute,"title") == 0)
+ {
+ (void) CloneString(&montage_info->title,SvPV(ST(i),na));
+ break;
+ }
+ if (LocaleCompare(attribute,"transparent") == 0)
+ {
+ (void) AcquireOnePixelByReference(image,&transparent_color,0,0,&exception);
+ QueryColorDatabase(SvPV(ST(i),na),&transparent_color,
+ &exception);
+ for (next=image; next; next=next->next)
+ TransparentImage(next,transparent_color,TransparentOpacity);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ default:
+ {
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ }
+ }
+ image=MontageImages(image,montage_info,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ DestroyMontageInfo(montage_info);
+ if (transparent_color.opacity != TransparentOpacity)
+ for (next=image; next; next=next->next)
+ TransparentImage(next,transparent_color,TransparentOpacity);
+ for ( ; image; image=image->next)
+ {
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ }
+ ST(0)=av_reference;
+ MY_CXT.error_jump=NULL;
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# M o r p h #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Morph(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ MorphImage = 1
+ morph = 2
+ morphimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ *attribute;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ Image
+ *image;
+
+ jmp_buf
+ error_jmp;
+
+ int
+ number_frames;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *av_reference,
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ av=NULL;
+ status=0;
+ attribute=NULL;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ av=newAV();
+ av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ info=GetPackageInfo(aTHX_ (void *) av,info);
+ /*
+ Get attribute.
+ */
+ number_frames=30;
+ for (i=2; i < items; i+=2)
+ {
+ attribute=(char *) SvPV(ST(i-1),na);
+ switch (*attribute)
+ {
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(attribute,"frames") == 0)
+ {
+ number_frames=SvIV(ST(i));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ default:
+ {
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ }
+ }
+ GetExceptionInfo(&exception);
+ image=MorphImages(image,number_frames,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ for ( ; image; image=image->next)
+ {
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ }
+ ST(0)=av_reference;
+ MY_CXT.error_jump=NULL;
+ SvREFCNT_dec(MY_CXT.error_list); /* can't return warning messages */
+ MY_CXT.error_list=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ MY_CXT.error_jump=NULL;
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# M o s a i c #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Mosaic(ref)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ MosaicImage = 1
+ mosaic = 2
+ mosaicimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ jmp_buf
+ error_jmp;
+
+ Image
+ *image;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ status=0;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ GetExceptionInfo(&exception);
+ image=MosaicImages(image,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ /*
+ Create blessed Perl array for the returned image.
+ */
+ av=newAV();
+ ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ info=GetPackageInfo(aTHX_ (void *) av,info);
+ (void) strncpy(image->filename,info->image_info->filename,MaxTextExtent-1);
+ SetImageInfo(info->image_info,SETMAGICK_WRITE,&image->exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list); /* return messages in string context */
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# P i n g #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Ping(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ PingImage = 1
+ ping = 2
+ pingimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ **keep,
+ **list,
+ message[MaxTextExtent];
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ Image
+ *image,
+ *next;
+
+ int
+ ac,
+ n;
+
+ jmp_buf
+ error_jmp;
+
+ register char
+ **p;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info,
+ *package_info;
+
+ SV
+ *reference,
+ *rv,
+ *sv;
+
+ unsigned int
+ status;
+
+ unsigned long
+ count;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ package_info=(struct PackageInfo *) NULL;
+ ac=(items < 2) ? 1 : items-1;
+ list=MagickAllocateMemory(char **,(ac+1)*sizeof(*list));
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ av=(AV *) reference;
+ info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL);
+ package_info=ClonePackageInfo(info);
+ n=1;
+ if (items <= 1)
+ *list=(char *) (*package_info->image_info->filename ?
+ package_info->image_info->filename : "XC:black");
+ else
+ for (n=0, i=0; i < ac; i++)
+ {
+ STRLEN
+ length;
+
+ list[n]=(char *) SvPV(ST(i+1),length);
+ if ((items >= 3) && strEQcase(list[n],"blob"))
+ {
+ package_info->image_info->blob=(void *) (SvPV(ST(i+2),length));
+ package_info->image_info->length=(size_t) length;
+ continue;
+ }
+ if ((items >= 3) && strEQcase(list[n],"filename"))
+ continue;
+ if ((items >= 3) && strEQcase(list[n],"file"))
+ {
+ package_info->image_info->file=
+ PerlIO_findFILE(IoIFP(sv_2io(ST(i+2))));
+ continue;
+ }
+ n++;
+ }
+ list[n]=(char *) NULL;
+ keep=list;
+ MY_CXT.error_jump=(&error_jmp);
+ if (setjmp(error_jmp))
+ goto ReturnIt;
+ status=ExpandFilenames(&n,&list);
+ if (status == False)
+ {
+ MagickError(ResourceLimitError,MemoryAllocationFailed,NULL);
+ goto ReturnIt;
+ }
+ count=0;
+ GetExceptionInfo(&exception);
+ for (i=0; i < n; i++)
+ {
+ (void) strncpy(package_info->image_info->filename,list[i],
+ MaxTextExtent-1);
+ image=PingImage(package_info->image_info,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ count+=GetImageListLength(image);
+ EXTEND(sp,4*count);
+ for (next=image; next; next=next->next)
+ {
+ FormatString(message,"%lu",next->columns);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%lu",next->rows);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%lu",(unsigned long) GetBlobSize(next));
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ PUSHs(sv_2mortal(newSVpv(next->magick,0)));
+ }
+ DestroyImageList(image);
+ }
+ DestroyExceptionInfo(&exception);
+ /*
+ Free resources.
+ */
+ for (i=0; i < n; i++)
+ if (list[i])
+ for (p=keep; list[i] != *p++; )
+ if (*p == NULL)
+ {
+ MagickFreeMemory(list[i]);
+ break;
+ }
+
+ ReturnIt:
+ if (package_info)
+ DestroyPackageInfo(package_info);
+ MagickFreeMemory(list);
+ SvREFCNT_dec(MY_CXT.error_list); /* throw away all errors */
+ MY_CXT.error_list=NULL;
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# Q u e r y C o l o r #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+QueryColor(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ querycolor = 1
+ PPCODE:
+ {
+ char
+ *name,
+ message[MaxTextExtent];
+
+ ExceptionInfo
+ exception;
+
+ PixelPacket
+ color;
+
+ register int
+ i;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ if (items == 1)
+ {
+ char
+ **colorlist;
+
+ unsigned long
+ colors;
+
+ colorlist=GetColorList("*",&colors);
+ EXTEND(sp,colors);
+ for (i=0; i < colors; i++)
+ {
+ PUSHs(sv_2mortal(newSVpv(colorlist[i],0)));
+ MagickFreeMemory(colorlist[i]);
+ }
+ MagickFreeMemory(colorlist);
+ goto MethodException;
+ }
+ EXTEND(sp,4*items);
+ GetExceptionInfo(&exception);
+ for (i=1; i < items; i++)
+ {
+ name=(char *) SvPV(ST(i),na);
+ if (!QueryColorDatabase(name,&color,&exception))
+ {
+ PUSHs(&sv_undef);
+ continue;
+ }
+ FormatString(message,"%u",color.red);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%u",color.green);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%u",color.blue);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%u",color.opacity);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ }
+ DestroyExceptionInfo(&exception);
+
+ MethodException:
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# Q u e r y C o l o r N a m e #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+QueryColorname(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ querycolorname = 1
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ message[MaxTextExtent];
+
+ ExceptionInfo
+ exception;
+
+ Image
+ *image;
+
+ PixelPacket
+ target_color;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *reference; /* reference is the SV* of ref=SvIV(reference) */
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ reference=SvRV(ST(0));
+ av=(AV *) reference;
+ info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL);
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ EXTEND(sp,items);
+ GetExceptionInfo(&exception);
+ for (i=1; i < items; i++)
+ {
+ (void) QueryColorDatabase(SvPV(ST(i),na),&target_color,&exception);
+ (void) QueryColorname(image,&target_color,SVGCompliance,message,
+ &image->exception);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ }
+ DestroyExceptionInfo(&exception);
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# Q u e r y F o n t #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+QueryFont(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ queryfont = 1
+ PPCODE:
+ {
+ char
+ *name,
+ message[MaxTextExtent];
+
+ ExceptionInfo
+ exception;
+
+ register int
+ i;
+
+ volatile const TypeInfo
+ *type_info;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ if (items == 1)
+ {
+ char
+ **typelist;
+
+ unsigned long
+ types;
+
+ typelist=GetTypeList("*",&types);
+ EXTEND(sp,types);
+ for (i=0; i < types; i++)
+ {
+ PUSHs(sv_2mortal(newSVpv(typelist[i],0)));
+ MagickFreeMemory(typelist[i]);
+ }
+ MagickFreeMemory(typelist);
+ goto MethodException;
+ }
+ EXTEND(sp,10*items);
+ GetExceptionInfo(&exception);
+ for (i=1; i < items; i++)
+ {
+ name=(char *) SvPV(ST(i),na);
+ type_info=GetTypeInfo(name,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (type_info == (TypeInfo *) NULL)
+ {
+ PUSHs(&sv_undef);
+ continue;
+ }
+ if (type_info->name == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
+ if (type_info->description == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
+ if (type_info->family == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
+ PUSHs(sv_2mortal(newSVpv(StyleTypes[(long) type_info->style],0)));
+ PUSHs(sv_2mortal(newSVpv(StretchTypes[(long) type_info->stretch],0)));
+ FormatString(message,"%lu",type_info->weight);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ if (type_info->encoding == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
+ if (type_info->foundry == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
+ if (type_info->format == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
+ if (type_info->metrics == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
+ if (type_info->glyphs == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
+ }
+ DestroyExceptionInfo(&exception);
+
+ MethodException:
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# Q u e r y F o n t M e t r i c s #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+QueryFontMetrics(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ queryfontmetrics = 1
+ PPCODE:
+ {
+ AffineMatrix
+ affine,
+ current;
+
+ AV
+ *av;
+
+ char
+ *attribute,
+ message[MaxTextExtent];
+
+ double
+ x,
+ y;
+
+ DrawInfo
+ *draw_info;
+
+ Image
+ *image;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *reference; /* reference is the SV* of ref=SvIV(reference) */
+
+ TypeMetric
+ metrics;
+
+ unsigned int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ reference=SvRV(ST(0));
+ av=(AV *) reference;
+ info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL);
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ draw_info=CloneDrawInfo(info->image_info,info->draw_info);
+ CloneString(&draw_info->text,"");
+ current=draw_info->affine;
+ IdentityAffine(&affine);
+ x=0.0;
+ y=0.0;
+ EXTEND(sp,7*items);
+ for (i=2; i < items; i+=2)
+ {
+ attribute=(char *) SvPV(ST(i-1),na);
+ switch (*attribute)
+ {
+ case 'd':
+ case 'D':
+ {
+ if (LocaleCompare(attribute,"density") == 0)
+ {
+ CloneString(&draw_info->density,SvPV(ST(i),na));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'e':
+ case 'E':
+ {
+ if (LocaleCompare(attribute,"encoding") == 0)
+ {
+ CloneString(&draw_info->encoding,SvPV(ST(i),na));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'f':
+ case 'F':
+ {
+ if (LocaleCompare(attribute,"font") == 0)
+ {
+ CloneString(&draw_info->font,SvPV(ST(i),na));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'g':
+ case 'G':
+ {
+ if (LocaleCompare(attribute,"geometry") == 0)
+ {
+ CloneString(&draw_info->geometry,SvPV(ST(i),na));
+ break;
+ }
+ if (LocaleCompare(attribute,"gravity") == 0)
+ {
+ draw_info->gravity=(GravityType)
+ LookupStr(GravityTypes,SvPV(ST(i),na));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'p':
+ case 'P':
+ {
+ if (LocaleCompare(attribute,"pointsize") == 0)
+ {
+ (void) sscanf(SvPV(ST(i),na),"%lf",&draw_info->pointsize);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'r':
+ case 'R':
+ {
+ if (LocaleCompare(attribute,"rotate") == 0)
+ {
+ (void) sscanf(SvPV(ST(i),na),"%lf%*[,/]%lf",&affine.rx,
+ &affine.ry);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 's':
+ case 'S':
+ {
+ if (LocaleCompare(attribute,"scale") == 0)
+ {
+ (void) sscanf(SvPV(ST(i),na),"%lf%*[,/]%lf",&affine.sx,
+ &affine.sy);
+ break;
+ }
+ if (LocaleCompare(attribute,"skew") == 0)
+ {
+ double
+ x_angle,
+ y_angle;
+
+ x_angle=0.0;
+ y_angle=0.0;
+ (void) sscanf(SvPV(ST(i),na),"%lf%*[,/]%lf",&x_angle,&y_angle);
+ affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
+ affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 't':
+ case 'T':
+ {
+ if (LocaleCompare(attribute,"text") == 0)
+ {
+ CloneString(&draw_info->text,SvPV(ST(i),na));
+ break;
+ }
+ if (LocaleCompare(attribute,"translate") == 0)
+ {
+ (void) sscanf(SvPV(ST(i),na),"%lf%*[,/]%lf",&affine.tx,
+ &affine.ty);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'x':
+ case 'X':
+ {
+ if (LocaleCompare(attribute,"x") == 0)
+ {
+ (void) sscanf(SvPV(ST(i),na),"%lf",&x);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'y':
+ case 'Y':
+ {
+ if (LocaleCompare(attribute,"y") == 0)
+ {
+ (void) sscanf(SvPV(ST(i),na),"%lf",&y);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ default:
+ {
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ }
+ }
+ draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
+ if (draw_info->geometry == (char *) NULL)
+ {
+ draw_info->geometry=AllocateString((char *) NULL);
+ FormatString(draw_info->geometry,"%g,%g",x,y);
+ }
+ status=GetTypeMetrics(image,draw_info,&metrics);
+ (void) CatchImageException(image);
+ if (status == False)
+ PUSHs(&sv_undef);
+ else
+ {
+ FormatString(message,"%g",metrics.pixels_per_em.x);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%g",metrics.pixels_per_em.y);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%g",metrics.ascent);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%g",metrics.descent);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%g",metrics.width);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%g",metrics.height);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ FormatString(message,"%g",metrics.max_advance);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ }
+ DestroyDrawInfo(draw_info);
+
+ MethodException:
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# Q u e r y F o r m a t #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+QueryFormat(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ queryformat = 1
+ PPCODE:
+ {
+ char
+ message[MaxTextExtent],
+ *name;
+
+ ExceptionInfo
+ exception;
+
+ register int
+ i;
+
+ volatile const MagickInfo
+ *magick_info;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ GetExceptionInfo(&exception);
+ if (items == 1)
+ {
+ register volatile const MagickInfo
+ *p;
+
+ magick_info=GetMagickInfo("*",&exception);
+ if (magick_info == (const MagickInfo *) NULL)
+ {
+ PUSHs(&sv_undef);
+ goto MethodException;
+ }
+ i=0;
+ for (p=magick_info; p != (MagickInfo *) NULL; p=p->next)
+ i++;
+ EXTEND(sp,i);
+ for (p=magick_info; p != (MagickInfo *) NULL; p=p->next)
+ {
+ if (p->stealth)
+ continue;
+ if (p->name == (char *) NULL)
+ {
+ PUSHs(&sv_undef);
+ continue;
+ }
+ (void) strncpy(message,p->name,MaxTextExtent-1);
+ LocaleLower(message);
+ PUSHs(sv_2mortal(newSVpv(message,0)));
+ }
+ goto MethodException;
+ }
+ EXTEND(sp,8*items);
+ for (i=1; i < items; i++)
+ {
+ name=(char *) SvPV(ST(i),na);
+ magick_info=GetMagickInfo(name,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (magick_info == (const MagickInfo *) NULL)
+ {
+ PUSHs(&sv_undef);
+ continue;
+ }
+ PUSHs(sv_2mortal(newSVpv(magick_info->adjoin ? "1" : "0",0)));
+ PUSHs(sv_2mortal(newSVpv(magick_info->blob_support ? "1" : "0",0)));
+ PUSHs(sv_2mortal(newSVpv(magick_info->raw ? "1" : "0",0)));
+ PUSHs(sv_2mortal(newSVpv(magick_info->decoder ? "1" : "0",0)));
+ PUSHs(sv_2mortal(newSVpv(magick_info->encoder ? "1" : "0",0)));
+ if (magick_info->description == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
+ if (magick_info->module == (char *) NULL)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
+ }
+ DestroyExceptionInfo(&exception);
+
+ MethodException:
+ SvREFCNT_dec(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# R e a d #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Read(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ ReadImage = 1
+ read = 2
+ readimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ **keep,
+ **list;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ Image
+ *image;
+
+ int
+ ac,
+ n;
+
+ jmp_buf
+ error_jmp;
+
+ register char
+ **p;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info,
+ *package_info;
+
+ SV
+ *reference,
+ *rv,
+ *sv;
+
+ unsigned int
+ status;
+
+ volatile int
+ number_images;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ package_info=(struct PackageInfo *) NULL;
+ number_images=0;
+ ac=(items < 2) ? 1 : items-1;
+ list=MagickAllocateMemory(char **,(ac+1)*sizeof(*list));
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto ReturnIt;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ if (SvTYPE(reference) != SVt_PVAV)
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,NULL);
+ goto ReturnIt;
+ }
+ av=(AV *) reference;
+ info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL);
+ package_info=ClonePackageInfo(info);
+ n=1;
+ if (items <= 1)
+ *list=(char *) (*package_info->image_info->filename ?
+ package_info->image_info->filename : "XC:black");
+ else
+ for (n=0, i=0; i < ac; i++)
+ {
+ list[n]=(char *) SvPV(ST(i+1),na);
+ if ((items >= 3) &&
+ strEQcase(package_info->image_info->filename,"blob"))
+ {
+ STRLEN
+ length;
+
+ i++;
+ package_info->image_info->blob=(void *) (SvPV(ST(i),length));
+ package_info->image_info->length=length;
+ }
+ if ((items >= 3) && strEQcase(list[n],"filename"))
+ continue;
+ if ((items >= 3) && strEQcase(list[n],"file"))
+ {
+ package_info->image_info->file=
+ PerlIO_findFILE(IoIFP(sv_2io(ST(i+2))));
+ continue;
+ }
+ n++;
+ }
+ list[n]=(char *) NULL;
+ keep=list;
+ MY_CXT.error_jump=(&error_jmp);
+ if (setjmp(error_jmp))
+ goto ReturnIt;
+ status=ExpandFilenames(&n,&list);
+ if (status == False)
+ {
+ MagickError(ResourceLimitError,MemoryAllocationFailed,NULL);
+ goto ReturnIt;
+ }
+ GetExceptionInfo(&exception);
+ number_images=0;
+ for (i=0; i < n; i++)
+ {
+ (void) strncpy(package_info->image_info->filename,list[i],
+ MaxTextExtent-1);
+ image=ReadImage(package_info->image_info,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ for ( ; image; image=image->next)
+ {
+ sv=newSViv((IV) image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ number_images++;
+ }
+ }
+ DestroyExceptionInfo(&exception);
+ /*
+ Free resources.
+ */
+ for (i=0; i < n; i++)
+ if (list[i])
+ for (p=keep; list[i] != *p++; )
+ if (*p == NULL)
+ {
+ MagickFreeMemory(list[i]);
+ break;
+ }
+
+ ReturnIt:
+ if (package_info)
+ DestroyPackageInfo(package_info);
+ MagickFreeMemory(list);
+ sv_setiv(MY_CXT.error_list,(IV) number_images);
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# R e m o t e #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Remote(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ RemoteCommand = 1
+ remote = 2
+ remoteCommand = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ SV
+ *reference;
+
+ struct PackageInfo
+ *info;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ reference=SvRV(ST(0));
+ av=(AV *) reference;
+ info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL);
+#if defined(XlibSpecificationRelease)
+ {
+ Display
+ *display;
+
+ register int
+ i;
+
+ display=XOpenDisplay(info->image_info->server_name);
+ for (i=1; i < items; i++)
+ XRemoteCommand(display,(char *) NULL,(char *) SvPV(ST(i),na));
+ }
+#endif
+ SvREFCNT_dec(MY_CXT.error_list); /* throw away all errors */
+ MY_CXT.error_list=NULL;
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# S e t #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Set(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ SetAttributes = 1
+ SetAttribute = 2
+ set = 3
+ setattributes = 4
+ setattribute = 5
+ PPCODE:
+ {
+ Image
+ *image;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *reference; /* reference is the SV* of ref=SvIV(reference) */
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (items == 2)
+ SetAttribute(aTHX_ info,image,"size",ST(1));
+ else
+ for (i=2; i < items; i+=2)
+ SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i));
+
+ MethodException:
+ sv_setiv(MY_CXT.error_list,(IV) (SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# T r a n s f o r m #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Transform(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ TransformImage = 1
+ transform = 2
+ transformimage = 3
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ *attribute,
+ *crop_geometry,
+ *geometry;
+
+ ExceptionInfo
+ exception;
+
+ HV
+ *hv;
+
+ Image
+ *clone,
+ *image;
+
+ jmp_buf
+ error_jmp;
+
+ register int
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *av_reference,
+ *reference,
+ *rv,
+ *sv;
+
+ volatile int
+ status;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ av=NULL;
+ status=0;
+ attribute=NULL;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ av=newAV();
+ av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ MY_CXT.error_jump=(&error_jmp);
+ status=setjmp(error_jmp);
+ if (status)
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ info=GetPackageInfo(aTHX_ (void *) av,info);
+ /*
+ Get attribute.
+ */
+ crop_geometry=(char *) NULL;
+ geometry=(char *) NULL;
+ for (i=2; i < items; i+=2)
+ {
+ attribute=(char *) SvPV(ST(i-1),na);
+ switch (*attribute)
+ {
+ case 'c':
+ case 'C':
+ {
+ if (LocaleCompare(attribute,"crop") == 0)
+ {
+ crop_geometry=SvPV(ST(i),na);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ case 'g':
+ case 'G':
+ {
+ if (LocaleCompare(attribute,"geometry") == 0)
+ {
+ geometry=SvPV(ST(i),na);
+ break;
+ }
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ default:
+ {
+ MagickError(OptionError,UnrecognizedAttribute,attribute);
+ break;
+ }
+ }
+ }
+ GetExceptionInfo(&exception);
+ for ( ; image; image=image->next)
+ {
+ clone=CloneImage(image,0,0,True,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (clone == (Image *) NULL)
+ goto MethodException;
+ TransformImage(&clone,crop_geometry,geometry);
+ (void) CatchImageException(clone);
+ for ( ; clone; clone=clone->next)
+ {
+ sv=newSViv((IV) clone);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ }
+ }
+ DestroyExceptionInfo(&exception);
+ ST(0)=av_reference;
+ MY_CXT.error_jump=NULL;
+ SvREFCNT_dec(MY_CXT.error_list); /* can't return warning messages */
+ MY_CXT.error_list=NULL;
+ XSRETURN(1);
+
+ MethodException:
+ MY_CXT.error_jump=NULL;
+ sv_setiv(MY_CXT.error_list,(IV) (status ? status : SvCUR(MY_CXT.error_list) != 0));
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+#
+###############################################################################
+# #
+# #
+# #
+# W r i t e #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+Write(ref,...)
+ Graphics::Magick ref=NO_INIT
+ ALIAS:
+ WriteImage = 1
+ write = 2
+ writeimage = 3
+ PPCODE:
+ {
+ char
+ filename[MaxTextExtent];
+
+ Image
+ *image,
+ *next;
+
+ int
+ scene;
+
+ register int
+ i;
+
+ jmp_buf
+ error_jmp;
+
+ struct PackageInfo
+ *info,
+ *package_info;
+
+ SV
+ *reference;
+
+ volatile int
+ number_images;
+
+ dMY_CXT;
+ MY_CXT.error_list=newSVpv("",0);
+ number_images=0;
+ package_info=(struct PackageInfo *) NULL;
+ if (!sv_isobject(ST(0)))
+ {
+ MagickError(OptionError,ReferenceIsNotMyType,PackageName);
+ goto MethodException;
+ }
+ reference=SvRV(ST(0));
+ MY_CXT.error_jump=(&error_jmp);
+ if (setjmp(error_jmp))
+ goto MethodException;
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL);
+ if (!image)
+ {
+ MagickError(OptionError,NoImagesDefined,NULL);
+ goto MethodException;
+ }
+ package_info=ClonePackageInfo(info);
+ if (items == 2)
+ SetAttribute(aTHX_ package_info,NULL,"filename",ST(1));
+ else
+ if (items > 2)
+ for (i=2; i < items; i+=2)
+ SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i));
+ (void) strncpy(filename,package_info->image_info->filename,MaxTextExtent-1);
+ scene=0;
+ for (next=image; next; next=next->next)
+ {
+ (void) strncpy(next->filename,filename,MaxTextExtent-1);
+ next->scene=scene++;
+ }
+ (void) SetImageInfo(package_info->image_info,
+ (SETMAGICK_WRITE |
+ (!package_info->image_info->adjoin ? SETMAGICK_RECTIFY: 0U)),
+ &image->exception);
+ for (next=image; next; next=next->next)
+ {
+ (void) WriteImage(package_info->image_info,next);
+ (void) CatchImageException(next);
+ number_images++;
+ if (package_info->image_info->adjoin)
+ break;
+ }
+ package_info->image_info->file=(FILE *) NULL;
+
+ MethodException:
+ if (package_info)
+ DestroyPackageInfo(package_info);
+ sv_setiv(MY_CXT.error_list,(IV) number_images);
+ SvPOK_on(MY_CXT.error_list);
+ ST(0)=sv_2mortal(MY_CXT.error_list);
+ MY_CXT.error_list=NULL;
+ MY_CXT.error_jump=NULL;
+ XSRETURN(1);
+ }
+
+# Local Variables:
+# mode: c
+# c-basic-offset: 2
+# fill-column: 78
+# End:
+
diff --git a/PerlMagick/Makefile.PL b/PerlMagick/Makefile.PL
new file mode 100644
index 0000000..154deb2
--- /dev/null
+++ b/PerlMagick/Makefile.PL
@@ -0,0 +1,118 @@
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1998,1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# NOTE: set TEST_VERBOSE=1 in order to see verbose output from tests.
+#
+# In order to run just one test verbosely do something like
+# make TEST_VERBOSE=1 TEST_FILES=t/filter.t test
+
+use ExtUtils::MakeMaker;
+use Config;
+
+# Compute test specification
+my $delegate_tests='t/*.t';
+my $delegate;
+foreach $delegate (qw/ bzlib jbig jng jp2 jpeg lcms png ps tiff ttf wmf x xfig zlib/) {
+ if( -d "t/$delegate" ) {
+ $delegate_tests .= " t/$delegate/*.t";
+ }
+}
+
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile
+ (
+ # Module description
+ 'ABSTRACT' => 'GraphicsMagick PERL Extension',
+
+ # Perl module name is Graphics::Magick
+ 'NAME' => 'Graphics::Magick',
+
+ # Module author
+ 'AUTHOR' => 'GraphicsMagick Group',
+
+ # Module version
+ 'VERSION' => '1.4',
+
+ # Preprocessor defines
+ 'DEFINE' => ' -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES=1 -DHAVE_CONFIG_H', # e.g., '-DHAVE_SOMETHING'
+
+ # Header search specfication and preprocessor flags
+ 'INC' => '-I../ -I/home/bfriesen/src/graphics/GraphicsMagick-head -I/usr/local/include/freetype2 -I/usr/openwin/include -I/usr/openwin/include/X11 -I/usr/include/libxml2',
+
+ # C compiler
+ 'CC' => 'gcc-4.4.3 -std=gnu99',
+
+ # C pre-processor flags (e.g. -I & -D options)
+ # 'CPPFLAGS' => "$Config{'cppflags'} -I/usr/local/include/freetype2 -I/usr/openwin/include -I/usr/openwin/include/X11 -I/usr/include/libxml2",
+
+ # C compiler flags (e.g. -O -g)
+ 'CCFLAGS' => "$Config{'ccflags'} -fopenmp -march=opteron-sse3 -O2 -g -Wall -Winline -W -Wformat-security -Wpointer-arith -Wdisabled-optimization -Wmissing-noreturn -Wno-unknown-pragmas -Wall -D_REENTRANT -pthreads",
+
+ # Linker
+ 'LD' => $Config{'ld'} == $Config{'cc'} ? 'gcc-4.4.3 -std=gnu99' : $Config{'ld'},
+
+ # Linker flags for building an executable
+ 'LDFLAGS' => "-L/home/bfriesen/build/GraphicsMagick-16-static/magick/.libs $Config{'ldflags'}",
+
+ # Linker flags for building a dynamically loadable module
+ 'LDDLFLAGS' => "-L/home/bfriesen/build/GraphicsMagick-16-static/magick/.libs $Config{'lddlflags'}",
+
+ # Install PerlMagick binary into GraphicsMagick bin directory
+ 'INSTALLBIN' => '/usr/local/bin',
+
+ # Library specification
+ 'LIBS' => ['-L/home/bfriesen/build/GraphicsMagick-16-static/magick/.libs -lGraphicsMagick -Wl,-zlazyload -L/usr/local/lib -R/usr/local/lib -L/usr/local/lib -R/usr/local/lib -L/usr/openwin/lib -R/usr/openwin/lib -L/usr/local/lib -L/usr/lib -ljbig -llcms -ltiff -lfreetype -ljasper -ljpeg -lpng -lwmflite -ldpstk -ldps -lXext -lSM -lICE -lX11 -lsocket -lnsl -lbz2 -lxml2 -lz -lm -lgomp -lpthread'],
+
+ # Perl binary name (if a Perl binary is built)
+ 'MAP_TARGET' => 'PerlMagick',
+
+ # Let CFLAGS drive optimization flags by setting OPTIMIZE to empty
+ # 'OPTIMIZE' => '',
+
+ # Use same compiler as GraphicsMagick
+ 'PERLMAINCC' => 'gcc-4.4.3',
+
+ # Set Perl installation prefix to GraphicsMagick installation prefix
+# 'PREFIX' => '/usr/local',
+
+ # Include delegate directories in tests
+ test => { TESTS => $delegate_tests},
+
+ ($Config{'archname'} =~ /-object$/i ? ('CAPI' => 'TRUE') : ()),
+);
+
+
+#
+# Substitutions for "makeaperl" section.
+#
+sub MY::makeaperl {
+ package MY; # so that "SUPER" works right
+ my $inherited = shift->SUPER::makeaperl(@_);
+
+ # Stinky ExtUtils::MM_Unix likes to append its own library path to $(CC),
+ # prior to any user-specified library path so that an installed library is
+ # used rather than the library just built. This substitution function
+ # tries to insert our library path first. Also, use the same compiler used
+ # to build perlmain.c to link so that a C++ compiler may be used if
+ # necessary.
+ $inherited =~ s:MAP_LINKCMD\s.*\s*\$\(CC\):MAP_LINKCMD = \$(PERLMAINCC) -L/home/bfriesen/build/GraphicsMagick-16-static/magick/.libs: ;
+ $inherited;
+ }
+
+#
+# Substitutions for "test" section.
+#
+#sub MY::test {
+# package MY; # so that "SUPER" works right
+# my $inherited = shift->SUPER::test(@_);
+#
+ # Run tests in our environment
+# $inherited =~ s:PERL_DL_NONLAZY=1:/bin/bash ../rungm.sh PERL_DL_NONLAZY=1:g ;
+# $inherited;
+# }
diff --git a/PerlMagick/Makefile.PL.in b/PerlMagick/Makefile.PL.in
new file mode 100644
index 0000000..9937e8e
--- /dev/null
+++ b/PerlMagick/Makefile.PL.in
@@ -0,0 +1,129 @@
+# Copyright (C) 2003-2010 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1998,1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# NOTE: set TEST_VERBOSE=1 in order to see verbose output from tests.
+#
+# In order to run just one test verbosely do something like
+# make TEST_VERBOSE=1 TEST_FILES=t/filter.t test
+
+use ExtUtils::MakeMaker;
+use Config;
+
+my $magick_CPPFLAGS='@CPPFLAGS@';
+my $magick_DEFS='@LFS_CPPFLAGS@ @DEFS@';
+my $magick_CFLAGS='@CFLAGS@';
+my $magick_CC='@CC@';
+my $magick_CPPFLAGS='-I../ -I@top_srcdir@ @CPPFLAGS@';
+my $magick_LDFLAGS='@LDFLAGS@';
+my $magick_BIN_DIR="$ENV{'DESTDIR'}@BIN_DIR@";
+my $magick_DEP_LIBS='@MAGICK_DEP_LIBS@';
+my $magick_PERLMAINCC='@PERLMAINCC@';
+my $magick_LIB_DIR="$ENV{'DESTDIR'}@MAGICKLIBDIR@";
+
+# Compute test specification
+my $delegate_tests='t/*.t';
+my $delegate;
+foreach $delegate (qw/@DELEGATES@/) {
+ if( -d "t/$delegate" ) {
+ $delegate_tests .= " t/$delegate/*.t";
+ }
+}
+
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile
+ (
+ # Module description
+ 'ABSTRACT' => 'GraphicsMagick PERL Extension',
+
+ # Perl module name is Graphics::Magick
+ 'NAME' => 'Graphics::Magick',
+
+ # Module author
+ 'AUTHOR' => 'GraphicsMagick Group',
+
+ # Module version
+ 'VERSION' => '@PACKAGE_VERSION@',
+
+ # Preprocessor defines
+ 'DEFINE' => $magick_DEFS, # e.g., '-DHAVE_SOMETHING'
+
+ # Header search specfication and preprocessor flags
+ 'INC' => $magick_CPPFLAGS,
+
+ # C compiler
+ 'CC' => $magick_CC,
+
+ # C pre-processor flags (e.g. -I & -D options)
+ # 'CPPFLAGS' => "$Config{'cppflags'} $magick_CPPFLAGS",
+
+ # C compiler flags (e.g. -O -g)
+ 'CCFLAGS' => "$Config{'ccflags'} $magick_CFLAGS",
+
+ # Linker
+ 'LD' => $Config{'ld'} == $Config{'cc'} ? $magick_CC : $Config{'ld'},
+
+ # Linker flags for building an executable
+ 'LDFLAGS' => "-L$magick_LIB_DIR $Config{'ldflags'}",
+
+ # Linker flags for building a dynamically loadable module
+ 'LDDLFLAGS' => "-L$magick_LIB_DIR $Config{'lddlflags'}",
+
+ # Install PerlMagick binary into GraphicsMagick bin directory
+ 'INSTALLBIN' => $magick_BIN_DIR,
+
+ # Library specification
+ 'LIBS' => ["-L$magick_LIB_DIR -lGraphicsMagick $magick_LDFLAGS $magick_DEP_LIBS"],
+
+ # Perl binary name (if a Perl binary is built)
+ 'MAP_TARGET' => 'PerlMagick',
+
+ # Let CFLAGS drive optimization flags by setting OPTIMIZE to empty
+ # 'OPTIMIZE' => '',
+
+ # Use same compiler as GraphicsMagick
+ 'PERLMAINCC' => $magick_PERLMAINCC,
+
+ # Set Perl installation prefix to GraphicsMagick installation prefix
+# 'PREFIX' => '@prefix@',
+
+ # Include delegate directories in tests
+ test => { TESTS => $delegate_tests},
+
+ ($Config{'archname'} =~ /-object$/i ? ('CAPI' => 'TRUE') : ()),
+);
+
+
+#
+# Substitutions for "makeaperl" section.
+#
+sub MY::makeaperl {
+ package MY; # so that "SUPER" works right
+ my $inherited = shift->SUPER::makeaperl(@_);
+
+ # Stinky ExtUtils::MM_Unix likes to append its own library path to $(CC),
+ # prior to any user-specified library path so that an installed library is
+ # used rather than the library just built. This substitution function
+ # tries to insert our library path first. Also, use the same compiler used
+ # to build perlmain.c to link so that a C++ compiler may be used if
+ # necessary.
+ $inherited =~ s:MAP_LINKCMD\s.*\s*\$\(CC\):MAP_LINKCMD = \$(PERLMAINCC) -L@MAGICKLIBDIR@: ;
+ $inherited;
+ }
+
+#
+# Substitutions for "test" section.
+#
+#sub MY::test {
+# package MY; # so that "SUPER" works right
+# my $inherited = shift->SUPER::test(@_);
+#
+ # Run tests in our environment
+# $inherited =~ s:PERL_DL_NONLAZY=1:@SHELL@ ../rungm.sh PERL_DL_NONLAZY=1:g ;
+# $inherited;
+# }
diff --git a/PerlMagick/Makefile.am b/PerlMagick/Makefile.am
new file mode 100644
index 0000000..44cd6ac
--- /dev/null
+++ b/PerlMagick/Makefile.am
@@ -0,0 +1,134 @@
+# Copyright (C) 2004-2010 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building PerlMagick
+#
+#
+
+# If source files are missing, see if they can be obtained via VPATH
+# and create a linked tree.
+perl-sources:
+ @if test -n "$(VPATH)" ; then \
+ echo "Linking PerlMagick Sources ..." ; \
+ imagemagick=`(cd $(VPATH) ; pwd)` && \
+ ( cd $(PERLMAGICK) && \
+ sh $$imagemagick/lndir.sh $$imagemagick/$(PERLMAGICK) ) \
+ fi ; \
+ touch perl-sources
+
+# The substituted file Magick.pm needs to be copied to the PerlMagick
+# source directory since it becomes part of the source distribution.
+$(top_srcdir)/$(PERLMAGICK)/Magick.pm : $(PERLMAGICK)/Magick.pm
+ @if test -n "$(VPATH)" ; then \
+ echo "Updating $(PERLMAGICK)/Magick.pm ..." ; \
+ cp $(PERLMAGICK)/Magick.pm $(top_srcdir)/$(PERLMAGICK)/Magick.pm ; \
+ fi
+
+
+PERLMAGICK=PerlMagick
+PERLMAGICK_MAINTAINER_TARGETS=$(top_srcdir)/$(PERLMAGICK)/Magick.pm
+
+if WITH_PERL
+
+PERLMAKEMAKER=$(PERLMAGICK)/Makefile.PL
+PERLMAKEFILE=$(PERLMAGICK)/Makefile
+
+PERLMAGICK_ALL_LOCAL_TARGETS = all-perl
+#PERLMAGICK_INSTALL_EXEC_LOCAL_TARGETS = install-exec-perl
+PERLMAGICK_INSTALL_DATA_LOCAL_TARGETS =
+#PERLMAGICK_UNINSTALL_LOCAL_TARGETS = uninstall-exec-perl
+PERLMAGICK_CLEAN_LOCAL_TARGETS = clean-perl
+PERLMAGICK_DISTCLEAN_LOCAL_TARGETS = clean-perl
+PERLMAGICK_MAINTAINER_CLEAN_LOCAL_TARGETS = distclean-local
+#PERLMAGICK_CHECK_LOCAL_TARGETS = check-perl
+
+PERLMAGICK_TESTS = PerlMagick/PerlMagickCheck.sh
+
+#PERLMAGICK_CHECKSCRIPTS = perl-build
+
+if WITH_PERL_DYNAMIC
+
+PERLMAGICK_CHECKSCRIPTS =
+
+$(PERLMAKEFILE): perl-sources $(LIBMAGICK) $(PERLMAKEMAKER)
+ cd $(PERLMAGICK) && @PERL@ Makefile.PL $(PERL_MAKE_OPTIONS)
+
+install-exec-perl: $(PERLMAKEFILE)
+ ( cd $(PERLMAGICK) && $(MAKE) CC='@CC@' && \
+ $(MAKE) CC='@CC@' install )
+
+all-perl: perl-sources
+
+uninstall-exec-perl: $(PERLMAKEFILE)
+ echo "Uninstall not supported for PerlMagick"
+
+check-perl: $(PERLMAKEFILE)
+ cd $(PERLMAGICK) && $(abs_top_builddir)/rungm.sh $(MAKE) CC='@CC@' test
+
+perl-build: $(PERLMAKEFILE)
+ ( cd $(PERLMAGICK) && $(MAKE) CC='@CC@' )
+
+else
+if WITH_PERL_STATIC
+
+PERLSTATICNAME=PerlMagick
+
+PERLMAGICK_CHECKSCRIPTS = perl-build
+
+$(PERLMAKEFILE): perl-sources $(LIBMAGICK) $(PERLMAKEMAKER)
+ cd $(PERLMAGICK) && @PERL@ Makefile.PL MAP_TARGET=$(PERLSTATICNAME) $(PERL_MAKE_OPTIONS) && $(MAKE) Makefile ; $(MAKE) Makefile
+
+$(PERLMAGICK)/$(PERLSTATICNAME): $(LIBMAGICK) $(PERLMAKEFILE)
+ ( rm -f $(PERLMAGICK)/$(PERLSTATICNAME) ; cd $(PERLMAGICK) && $(MAKE) CC='@CC@' $(PERLSTATICNAME) ; $(MAKE) CC='@CC@' $(PERLSTATICNAME) )
+
+all-perl: $(PERLMAGICK)/$(PERLSTATICNAME)
+
+install-exec-perl: $(PERLMAGICK)/$(PERLSTATICNAME)
+ rm -f "$(DESTDIR)$(BIN_DIR)/$(PERLSTATICNAME)"
+ if test "x$(DESTDIR)" = "x" -o "$(PERL_SUPPORTS_DESTDIR)" = 'yes' ; then \
+ ( cd $(PERLMAGICK) && \
+ $(MAKE) -f Makefile.aperl CC='@CC@' inst_perl MAP_TARGET=$(PERLSTATICNAME) \
+ INSTALLBIN="$(BIN_DIR)" \
+ ) ; \
+ else \
+ ( cd $(PERLMAGICK) && \
+ $(MAKE) -f Makefile.aperl CC='@CC@' inst_perl MAP_TARGET=$(PERLSTATICNAME) \
+ INSTALLBIN="$(DESTDIR)$(BIN_DIR)" PREFIX="$(DESTDIR)$(prefix)" \
+ ) ; \
+ fi
+
+uninstall-exec-perl:
+ rm -f '$(DESTDIR)$(BIN_DIR)/$(PERLSTATICNAME)'
+
+check-perl: $(PERLMAGICK)/$(PERLSTATICNAME)
+ cd $(PERLMAGICK) && $(abs_top_builddir)/rungm.sh $(MAKE) -f Makefile.aperl CC='@CC@' test
+
+perl-build: $(PERLMAGICK)/$(PERLSTATICNAME)
+
+endif # WITH_PERL_STATIC
+endif # WTIH_PERL_DYNAMIC
+
+
+clean-perl:
+ (cd $(PERLMAGICK) && \
+ ( if test -f Makefile.old ; then $(MAKE) -f Makefile.old CC='@CC@' clean ; fi ) ; \
+ ( if test -f Makefile ; then $(MAKE) CC='@CC@' clean ; fi ) ; \
+ ( if test -f Makefile ; then $(MAKE) CC='@CC@' clean ; fi ) ; \
+ rm -f Makefile.old PerlMagick ; \
+ rm -f t/output* t/jng/*_tmp.jng t/*/output* )
+ rm -f perl-sources
+
+distclean-perl: clean-perl
+
+else
+# Satisfy makefile requirements if not building PERL
+all-perl:
+install-exec-perl:
+uninstall-exec-perl:
+check-perl:
+clean-perl:
+distclean-perl:
+endif # WITH_PERL
diff --git a/PerlMagick/Makefile.nt b/PerlMagick/Makefile.nt
new file mode 100644
index 0000000..8abe3d9
--- /dev/null
+++ b/PerlMagick/Makefile.nt
@@ -0,0 +1,164 @@
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1998,1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+use ExtUtils::MakeMaker;
+use Config;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+#
+# NOTE: The current ActiveState binary distribution does not completely setup
+# the values in C:/Perl/lib/Config.pm. You must manually modify the values of
+# libpth to add the VisualC++ library path. It should look similar to one of
+# the following examples in order to work properly.
+#
+# Random developer
+# libpth='"C:\Perl\lib\CORE" "D:\DevStudio\VC98\lib"'
+#
+# Visual Studio 6.0 default install:
+# libpth='"C:\Program Files\Microsoft Visual Studio\VC98\lib" "C:\Perl\lib\CORE"'
+#
+# Visual Studio 7.0 default install:
+# libpth='"C:\Program Files\Microsoft Visual Studio .NET\vc7\lib" "C:\Perl\lib\CORE"'
+#
+# Visual Studio 7.1 default install:
+# libpth='"C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\lib" "C:\Perl\lib\CORE"'
+#
+# Visual Studio 9.0 default install (C:\Perl\lib\Config.pm):
+# libpth='"C:\Program Files\Microsoft Visual Studio 9.0\VC\lib" "C:\Perl\lib\CORE"'
+#
+WriteMakefile(
+ 'ABSTRACT' => 'GraphicsMagick PERL Extension',
+ 'AUTHOR' => 'GraphicsMagick Group',
+ 'NAME' => 'Graphics::Magick',
+ 'VERSION_FROM' => 'Magick.pm', # finds $VERSION
+ 'LIBS' => ['-L..\VisualMagick\lib -L..\VisualMagick\bin -lCORE_RL_magick_.lib'],
+ 'DEFINE' => '-D_VISUALC_ -D_WINDOWS', # e.g., '-DHAVE_SOMETHING'
+ 'INC' => '-I.. -I..\xlib\include',
+ 'BINARY_LOCATION' => 'x86/Graphics-Magick.tar.gz',
+ 'dist' => {ZIP => "zip.exe", ZIPFLAGS=>"-r"},
+ 'clean' => {FILES => "Graphics-Magick.ppd Graphics-Magick.tar.gz PerlMagick.zip " },
+ ($Config{'archname'} =~ /-object$/i ? ('CAPI' => 'TRUE') : ()),
+);
+
+#
+# Add a targets for building ActiveState ppm distribution modules
+# Dylan Beattie <dylan@zepler.org>, April 2002
+#
+# Requires tar, gzip, and zip. This produces PerlMagick.zip
+# Get GNU tar and gzip from http://sourceware.cygnus.com/
+# Get Win32 command line PKZIP from http://www.pkware.com/
+# and rename PKZIP.EXE to ZIP.EXE and PKUNZIP.EXE to UNZIP.EXE
+# Make sure tar.exe, gzip.exe and zip.exe are in your system path
+#
+# 'nmake ppm' will include only the PerlMagick module
+# 'nmake ppm-full' also includes all GraphicsMagick DLLs and MGK files
+
+sub MY::postamble
+{
+ '
+Graphics-Magick.tar.gz: ppd pure_all #htmlifypods manifypods
+ if exist Graphics-Magick.tar.gz del Graphics-Magick.tar.gz
+ if exist Graphics-Magick.tar del Graphics-Magick.tar
+ $(TAR) $(TARFLAGS) Graphics-Magick.tar blib
+ $(COMPRESS) -q Graphics-Magick.tar
+
+release: Graphics-Magick.tar.gz
+
+ppm: ppd pure_all htmlifypods manifypods
+ if exist PerlMagick.zip del PerlMagick.zip
+ $(TAR) $(TARFLAGS) Graphics-Magick.tar blib
+ $(COMPRESS) -q Graphics-Magick.tar
+ if exist x86 del x86 /f /q
+ if exist x86 rd x86
+ md x86
+ copy Graphics-Magick.tar$(SUFFIX) x86
+ del Graphics-Magick.tar$(SUFFIX)
+ if exist ppm-readme.txt copy ppm-readme.txt readme
+ $(ZIP) $(ZIPFLAGS) PerlMagick.zip readme Graphics-Magick.ppd x86/Graphics-Magick.tar$(SUFFIX)
+ del x86\Graphics-Magick.tar$(SUFFIX)
+ rd x86
+
+ppm-full: ppd pure_all htmlifypods manifypods
+ if exist PerlMagick-full.zip del PerlMagick-full.zip
+ copy ..\VisualMagick\bin\*.dll blib\arch\auto\Image\Magick
+ copy ..\VisualMagick\bin\*.mgk blib\arch\auto\Image\Magick
+ $(TAR) $(TARFLAGS) Graphics-Magick.tar blib
+ $(COMPRESS) -q Graphics-Magick.tar
+ if exist x86 del x86 /f /q
+ if exist x86 rd x86
+ md x86
+ copy Graphics-Magick.tar$(SUFFIX) x86
+ del Graphics-Magick.tar$(SUFFIX)
+ if exist ppm-readme.txt copy ppm-readme.txt readme
+ $(ZIP) $(ZIPFLAGS) PerlMagick-full.zip readme Graphics-Magick.ppd x86/Graphics-Magick.tar$(SUFFIX)
+ del x86\Graphics-Magick.tar$(SUFFIX)
+ rd x86
+ '
+}
+
+#
+# Modify the MakeMaker test fragment
+#
+sub MY::test
+{
+ #
+ # List any GraphicsMagick features derived from add-on libraries
+ # or programs you would like to test.
+ #
+ # Valid choices are:
+ #
+ # Feature Formats Tested Prerequisites
+ # ======= ====================== ======================================
+ # bzlib BZip compression BZip library
+ # cgm CGM format 'ralcgm' program
+ # hdf HDF format HDF library
+ # jbig JBIG format JBIG library
+ # jpeg JPEG format JPEG library
+ # mpeg MPEG format 'mpeg2decode' & 'mpeg2encode' programs
+ # png PNG format PNG and Zlib libraries
+ # ps Postscript format 'gs' program and/or DPS library
+ # rad Radiance format 'ra_ppm' program
+ # tiff TIFF format TIFF library
+ # ttf TrueType font format FreeType library
+ # x X11 support X-windows libraries and server
+ # xfig Xfig format 'transfig' program
+ # zlib Zip compression Zlib library
+ #
+ my @DELEGATES = qw/ bzlib cgm hpgl jbig jpeg mpeg png ps tiff ttf wmf x xfig zlib/;
+
+ package MY; # so that "SUPER" works right
+ my $inherited = shift->SUPER::test(@_);
+ my $delegate_tests=
+ " t/setattribute.t" .
+ " t/getattribute.t" .
+ " t/filter.t" .
+ " t/read.t" .
+ " t/montage.t" .
+ " t/write.t" .
+ " t/jbig/read.t" .
+ " t/jbig/write.t" .
+ " t/jng/read.t" .
+ " t/jng/write.t" .
+ " t/jpeg/read.t" .
+ " t/jpeg/write.t" .
+ " t/png/read.t" .
+ " t/png/write.t" .
+ " t/ps/read.t" .
+ " t/ps/write.t" .
+ " t/tiff/read.t" .
+ " t/tiff/write.t" .
+ " t/ttf/read.t" .
+ " t/wmf/read.t" .
+ " t/zlib/read.t" .
+ " t/zlib/write.t";
+ if ( defined $ENV{'DISPLAY'} ) {
+ $delegate_tests .= " t/x/write.t t/x/read.t";
+ }
+ $inherited =~ s:^TEST_FILES =.*:TEST_FILES = ${delegate_tests}:m;
+ $inherited;
+}
diff --git a/PerlMagick/PerlMagickCheck.sh.in b/PerlMagick/PerlMagickCheck.sh.in
new file mode 100755
index 0000000..127d849
--- /dev/null
+++ b/PerlMagick/PerlMagickCheck.sh.in
@@ -0,0 +1,47 @@
+#!/bin/sh
+# Copyright (C) 2009 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+. ./common.shi
+
+echo '=== Environment ==='
+echo "LD_LIBRARY_PATH='${LD_LIBRARY_PATH}'"
+echo "MAGICK_CODER_MODULE_PATH='${MAGICK_CODER_MODULE_PATH}'"
+echo "MAGICK_CONFIGURE_PATH='${MAGICK_CONFIGURE_PATH}'"
+echo "MAGICK_FILTER_MODULE_PATH='${MAGICK_FILTER_MODULE_PATH}'"
+echo "MAKE='${MAKE}'"
+echo "MAKEFLAGS='${MAKEFLAGS}'"
+echo "MEMCHECK='${MEMCHECK}'"
+echo "PATH='${PATH}'"
+echo "SRCDIR='${SRCDIR}'"
+echo "srcdir='${srcdir}'"
+echo '==================='
+echo ''
+
+set -x
+
+SRCDIR=`dirname $0`
+SRCDIR=`cd $SRCDIR && pwd`
+TOPSRCDIR=`cd $srcdir && pwd`
+
+cd PerlMagick || exit 1
+
+if test -z "${MAKE}" ; then
+ MAKE=make
+fi
+
+if test -x PerlMagick -a -f Makefile.aperl ; then
+ # Static build test incantation
+ ${MAKE} -f Makefile.aperl CC='@CC@' TEST_VERBOSE=1 test
+elif test -f Makefile -a -f Magick.o ; then
+ # Shared build test incantation
+ ${MAKE} CC='@CC@' TEST_VERBOSE=1 test
+else
+ echo 'PerlMagick has not been built!'
+ exit 1
+fi
+
+
diff --git a/PerlMagick/README.txt b/PerlMagick/README.txt
new file mode 100644
index 0000000..1d032b8
--- /dev/null
+++ b/PerlMagick/README.txt
@@ -0,0 +1,139 @@
+# Copyright (C) 2003-2017 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1998,1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+===========================================================================
+
+Introduction
+
+ PerlMagick, is an objected-oriented Perl interface to GraphicsMagick.
+ Use the module to read, manipulate, or write an image or image
+ sequence from within a Perl script. This makes it suitable for Web
+ CGI scripts. You must have GraphicsMagick 1.2 or above installed on
+ your system for this module to work properly.
+
+ See
+
+ http://www.graphicsmagick.org/www/perl.html
+
+ for additional information about PerlMagick. See
+
+ http://www.graphicsmagick.org/
+
+ for instructions about installing GraphicsMagick.
+
+
+Installation
+
+ PerlMagick is configured by default by GraphicsMagick in order to
+ create a starting Makefile.PL. Additional edits to Makefile.PL
+ may be required. GraphicsMagick does not provide a seperate
+ distribution of PerlMagick. Please follow the applicable steps
+ described here in order to complete the installation of
+ PerlMagick.
+
+ Get the GraphicsMagick distribution and type the following:
+
+ gunzip -c GraphicsMagick-1.2.tar.gz | tar -xvf -
+ cd GraphicsMagick
+ ./configure --enable-shared
+ make
+ su root (if necessary)
+ make install
+ cd PerlMagick
+
+ If you used GraphicsMagick configure then Makefile.PL should already
+ be prepared for use. If not, or you want to change a setting, then
+ edit Makefile.PL and change LIBS and INC to include the appropriate
+ path information to the required libGraphicsMagick library. You will
+ also need library search paths (-L) to JPEG, PNG, TIFF, etc.
+ libraries if they were included with your installed version of
+ GraphicsMagick. If an extension library is built as a shared library
+ but not installed in the system's default library search path, you
+ may need to add run-path information (often -R or -rpath)
+ corresponding to the equivalent library search path option so that
+ the library can be located at run-time.
+
+ To create and install the dymamically-loaded version of
+ PerlMagick (the preferred way), execute
+
+ perl Makefile.PL
+ make
+ su root (if necessary)
+ make install
+
+ [ Note that the following procedure for building a static
+ PerlMagick seems to work only for perl 5.8.8 and earlier ]
+
+ To create and install a new 'perl' executable (replacing your
+ existing PERL interpreter!) with PerlMagick statically linked
+ (but other libraries linked statically or dynamically according
+ to system linker default), execute
+
+ perl Makefile.PL
+ make perl
+ make -f Makefile.aperl inst_perl
+
+ or to create and install a new PERL interpreter with a
+ different name than 'perl' (e.g. 'PerlMagick') and with
+ PerlMagick statically linked
+
+ perl Makefile.PL MAP_TARGET=PerlMagick
+ make PerlMagick
+ make -f Makefile.aperl inst_perl
+
+ See the ExtUtils::MakeMaker(3) manual page for more information on
+ building PERL extensions (like PerlMagick).
+
+ For Windows systems, type
+
+ perl Makefile.nt
+ nmake install
+
+ For Unix, you typically need to be root to install the software.
+ There are ways around this. Consult the Perl manual pages for more
+ information. You are now ready to utilize the PerlMagick routines
+ from within your Perl scripts.
+
+
+Testing PerlMagick
+
+ Before PerlMagick is installed, you may want to execute
+
+ make test
+
+ to verify that PERL can load the PerlMagick extension ok. Chances
+ are some of the tests will fail if you do not have the proper
+ delegates installed for formats like JPEG, TIFF, etc. If 'make
+ test' fails in some gruesome way (e.g. many tests fail), then it
+ is advised not to install PerlMagick until the problem is
+ resolved.
+
+ To see a number of PerlMagick demonstration scripts, type
+
+ cd demo
+ make
+
+
+Example Perl Magick Script
+
+ Here is an example script to get you started:
+
+ #!/usr/bin/perl
+ use Graphics::Magick;
+
+ $q = Graphics::Magick->new;
+ $x = $q->Read("model.gif", "logo.gif", "rose.gif");
+ warn "$x" if $x;
+
+ $x = $q->Crop(geom=>'100x100+100+100');
+ warn "$x" if $x;
+
+ $x = $q->Write("x.gif");
+ warn "$x" if $x;
+
+ The script reads three images, crops them, and writes a single
+ image as a GIF animation sequence.
diff --git a/PerlMagick/build_manifest.sh b/PerlMagick/build_manifest.sh
new file mode 100755
index 0000000..15fb5f8
--- /dev/null
+++ b/PerlMagick/build_manifest.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Create a PerlMagick MANIFEST file. This needs to be run in a clean source tree.
+rm -f MANIFEST
+perl -MExtUtils::Manifest=mkmanifest -e 'mkmanifest()'
+
+#find . -type f -print | egrep -v '(.#.*)|(CVS)|(core)|(.*_tmp\.*)|(perlmain\.*)|(^PerlMagick)|(~$)|(.*\.orig)|(.*\.cvsignore)|(.*\.gdbinit)|(demo/demo.jpg)|(Makefile.in)|(Makefile.old)' | sed -e 's:\./::' | sort > MANIFEST
diff --git a/PerlMagick/demo/Generic.ttf b/PerlMagick/demo/Generic.ttf
new file mode 100644
index 0000000..d7410f1
--- /dev/null
+++ b/PerlMagick/demo/Generic.ttf
Binary files differ
diff --git a/PerlMagick/demo/Makefile b/PerlMagick/demo/Makefile
new file mode 100644
index 0000000..ee81137
--- /dev/null
+++ b/PerlMagick/demo/Makefile
@@ -0,0 +1,13 @@
+all:
+ perl demo.pl
+ perl button.pl
+ perl shapes.pl
+ perl piddle.pl
+ perl tree.pl
+ perl steganography.pl
+ perl shadow_text.pl
+ perl annotate.pl
+ perl composite.pl
+
+clean:
+ /bin/rm -f demo.jpg button.gif model.png shadow.gif tree.gif
diff --git a/PerlMagick/demo/README b/PerlMagick/demo/README
new file mode 100644
index 0000000..ed08e90
--- /dev/null
+++ b/PerlMagick/demo/README
@@ -0,0 +1,6 @@
+This directory contains a number of PerlMagick demonstration scripts. Just
+type
+
+ make
+
+to exercise the various examples.
diff --git a/PerlMagick/demo/Turtle.pm b/PerlMagick/demo/Turtle.pm
new file mode 100644
index 0000000..93bc819
--- /dev/null
+++ b/PerlMagick/demo/Turtle.pm
@@ -0,0 +1,56 @@
+package Turtle;
+
+# Written by jreed@itis.com, adapted by John Cristy.
+
+sub new
+{
+ my $class = shift;
+ my $self = {};
+
+ @{$self}{qw(x y theta mirror)} = @_;
+ bless $self, $class;
+}
+
+sub forward
+{
+ my $self = shift;
+ my ($r, $what) = @_;
+ my ($newx, $newy)=($self->{x}+$r* sin($self->{theta}),
+ $self->{y}+$r*-cos($self->{theta}));
+ if ($what) {
+ &$what($self->{x}, $self->{y}, $newx, $newy); # motion
+ }
+ # According to the coderef passed in
+ ($self->{x}, $self->{y})=($newx, $newy); # change the old coords
+}
+
+sub turn
+{
+ my $self = shift;
+ my $dtheta = shift;
+
+ $self->{theta} += $dtheta*$self->{mirror};
+}
+
+sub state
+{
+ my $self = shift;
+
+ @{$self}{qw(x y theta mirror)};
+}
+
+sub setstate
+{
+ my $self = shift;
+
+ @{$self}{qw(x y theta mirror)} = @_;
+}
+
+sub mirror
+{
+ my $self = shift;
+
+ $self->{mirror} *= -1;
+}
+
+"Turtle.pm";
diff --git a/PerlMagick/demo/annotate.pl b/PerlMagick/demo/annotate.pl
new file mode 100644
index 0000000..e7e0e2d
--- /dev/null
+++ b/PerlMagick/demo/annotate.pl
@@ -0,0 +1,40 @@
+#!/usr/local/bin/perl
+
+use Graphics::Magick;
+
+#$font = '-adobe-helvetica-medium-r-normal--25-180-100-100-p-130-iso8729-1';
+#$font = 'Times';
+$font = 'Generic.ttf';
+
+$image = Graphics::Magick->new();
+$x = 100;
+$y = 100;
+for ($angle=0; $angle < 360; $angle+=30)
+{
+ my ($label);
+
+ print "angle $angle\n";
+ $label=Graphics::Magick->new(size=>"600x600",pointsize=>24,font=>$font);
+ $label->Read("xc:white");
+ $label->Draw(primitive=>'line',points=>"300,100 300,500",stroke=>'#600');
+ $label->Draw(primitive=>'line',points=>"100,300 500,300",stroke=>'#600');
+ $label->Draw(primitive=>'rectangle',points=>"100,100 500,500",fill=>'none',
+ stroke=>'#600');
+ $label->Annotate(text=>"North West",gravity=>"NorthWest",x=>$x,y=>$y,
+ undercolor=>'yellow',rotate=>$angle);
+ $label->Annotate(text=>"North",gravity=>"North",y=>$y,rotate=>$angle);
+ $label->Annotate(text=>"North East",gravity=>"NorthEast",x=>$x,y=>$y,
+ rotate=>$angle);
+ $label->Annotate(text=>"West",gravity=>"West",x=>$x,rotate=>$angle);
+ $label->Annotate(text=>"Center",gravity=>"Center",rotate=>$angle);
+ $label->Annotate(text=>"East",gravity=>"East",x=>$x,rotate=>$angle);
+ $label->Annotate(text=>"South West",gravity=>"SouthWest",x=>$x,y=>$y,
+ rotate=>$angle);
+ $label->Annotate(text=>"South",gravity=>"South",y=>$y,rotate=>$angle);
+ $label->Annotate(text=>"South East",gravity=>"SouthEast",x=>$x,y=>$y,
+ rotate=>$angle);
+ push(@$image,$label);
+}
+$image->Set(delay=>20);
+$image->Write("annotate.miff");
+$image->Animate();
diff --git a/PerlMagick/demo/button.pl b/PerlMagick/demo/button.pl
new file mode 100644
index 0000000..205a65d
--- /dev/null
+++ b/PerlMagick/demo/button.pl
@@ -0,0 +1,15 @@
+#!/usr/local/bin/perl
+#
+# Make simple beveled button.
+#
+use Graphics::Magick;
+
+$q=Graphics::Magick->new;
+$q->Set(size=>'30x106');
+$q->Read('gradient:#00f685-#0083f8');
+$q->Rotate(-90);
+$q->Raise('6x6');
+$q->Annotate(text=>'Push Me',font=>'Generic.ttf',fill=>'black',
+ gravity=>'Center',pointsize=>18);
+$q->Write('button.gif');
+$q->Write('win:');
diff --git a/PerlMagick/demo/composite.pl b/PerlMagick/demo/composite.pl
new file mode 100644
index 0000000..943013a
--- /dev/null
+++ b/PerlMagick/demo/composite.pl
@@ -0,0 +1,44 @@
+#!/usr/local/bin/perl
+
+use Graphics::Magick;
+
+#$font = '-adobe-helvetica-medium-r-normal--25-180-100-100-p-130-iso8729-1';
+#$font = 'Times';
+$font = 'Generic.ttf';
+
+$image = Graphics::Magick->new();
+$smile = Graphics::Magick->new();
+$smile->Read('smile.gif');
+$smile->Set(background=>'none');
+$x = 100;
+$y = 100;
+for ($angle=0; $angle < 360; $angle+=30)
+{
+ my ($thumbnail);
+
+ print "angle $angle\n";
+ $thumbnail=Graphics::Magick->new(size=>"600x600",pointsize=>24,font=>$font,
+ fill=>'black');
+ $thumbnail->Read("xc:white");
+ $thumbnail->Draw(primitive=>'line',points=>"300,100 300,500",stroke=>'#600');
+ $thumbnail->Draw(primitive=>'line',points=>"100,300 500,300",stroke=>'#600');
+ $thumbnail->Draw(primitive=>'rectangle',points=>"100,100 500,500",
+ fill=>'none',stroke=>'#600');
+ $thumbnail->Composite(image=>$smile,gravity=>"NorthWest",x=>$x,y=>$y,
+ rotate=>$angle);
+ $thumbnail->Composite(image=>$smile,gravity=>"North",y=>$y,rotate=>$angle);
+ $thumbnail->Composite(image=>$smile,gravity=>"NorthEast",x=>$x,y=>$y,
+ rotate=>$angle);
+ $thumbnail->Composite(image=>$smile,gravity=>"West",x=>$x,rotate=>$angle);
+ $thumbnail->Composite(image=>$smile,gravity=>"Center",rotate=>$angle);
+ $thumbnail->Composite(image=>$smile,gravity=>"East",x=>$x,rotate=>$angle);
+ $thumbnail->Composite(image=>$smile,gravity=>"SouthWest",x=>$x,y=>$y,
+ rotate=>$angle);
+ $thumbnail->Composite(image=>$smile,gravity=>"South",y=>$y,rotate=>$angle);
+ $thumbnail->Composite(image=>$smile,gravity=>"SouthEast",x=>$x,y=>$y,
+ rotate=>$angle);
+ push(@$image,$thumbnail);
+}
+$image->Set(delay=>20);
+$image->Write("composite.miff");
+$image->Animate();
diff --git a/PerlMagick/demo/demo.pl b/PerlMagick/demo/demo.pl
new file mode 100644
index 0000000..5da74c9
--- /dev/null
+++ b/PerlMagick/demo/demo.pl
@@ -0,0 +1,360 @@
+#!/usr/local/bin/perl
+#
+# Overall demo of the major PerlMagick methods.
+#
+use Graphics::Magick;
+
+#
+# Read model & smile image.
+#
+print "Read...\n";
+$null=Graphics::Magick->new;
+$null->Set(size=>'70x70');
+$x=$null->ReadImage('NULL:black');
+warn "$x" if "$x";
+
+$model=Graphics::Magick->new();
+$x=$model->ReadImage('model.miff');
+warn "$x" if "$x";
+$model->Label('Magick');
+$model->Set(bordercolor=>'black');
+$model->Set(background=>'black');
+
+$smile=Graphics::Magick->new;
+$x=$smile->ReadImage('smile.gif');
+warn "$x" if "$x";
+$smile->Label('Smile');
+$smile->Set(bordercolor=>'black');
+#
+# Create image stack.
+#
+print "Transform image...\n";
+$images=Graphics::Magick->new();
+$example=$null->Clone();
+push(@$images,$example);
+$example=$null->Clone();
+push(@$images,$example);
+$example=$null->Clone();
+push(@$images,$example);
+$example=$null->Clone();
+push(@$images,$example);
+$example=$null->Clone();
+push(@$images,$example);
+
+print "Add Noise...\n";
+$example=$model->Clone();
+$example->Label('Add Noise');
+$example->AddNoise("LaplacianNoise");
+push(@$images,$example);
+
+print "Annotate...\n";
+$example=$model->Clone();
+$example->Label('Annotate');
+$example->Annotate(text=>'Magick',geometry=>'+0+20',font=>'Generic.ttf',
+ fill=>'gold',gravity=>'North',pointsize=>14);
+push(@$images,$example);
+
+print "Blur...\n";
+$example=$model->Clone();
+$example->Label('Blur');
+$example->Blur('0.0x1.0');
+push(@$images,$example);
+
+print "Border...\n";
+$example=$model->Clone();
+$example->Label('Border');
+$example->Border(geometry=>'6x6',color=>'gold');
+push(@$images,$example);
+
+print "Channel...\n";
+$example=$model->Clone();
+$example->Label('Channel');
+$example->Channel();
+push(@$images,$example);
+
+print "Charcoal...\n";
+$example=$model->Clone();
+$example->Label('Charcoal');
+$example->Charcoal();
+push(@$images,$example);
+
+print "Composite...\n";
+$example=$model->Clone();
+$example->Label('Composite');
+$example->Composite(image=>$smile,compose=>'over',geometry=>'+35+65');
+push(@$images,$example);
+
+print "Contrast...\n";
+$example=$model->Clone();
+$example->Label('Contrast');
+$example->Contrast();
+push(@$images,$example);
+
+print "Convolve...\n";
+$example=$model->Clone();
+$example->Label('Convolve');
+$example->Convolve([1, 1, 1, 1, 4, 1, 1, 1, 1]);
+push(@$images,$example);
+
+print "Crop...\n";
+$example=$model->Clone();
+$example->Label('Crop');
+$example->Crop(geometry=>'80x80+25+50');
+push(@$images,$example);
+
+print "Despeckle...\n";
+$example=$model->Clone();
+$example->Label('Despeckle');
+$example->Despeckle();
+push(@$images,$example);
+
+print "Draw...\n";
+$example=$model->Clone();
+$example->Label('Draw');
+$example->Draw(fill=>'none',stroke=>'gold',primitive=>'circle',
+ points=>'60,90 60,120',strokewidth=>2);
+push(@$images,$example);
+
+print "Detect Edges...\n";
+$example=$model->Clone();
+$example->Label('Detect Edges');
+$example->Edge();
+push(@$images,$example);
+
+print "Emboss...\n";
+$example=$model->Clone();
+$example->Label('Emboss');
+$example->Emboss();
+
+print "Equalize...\n";
+push(@$images,$example);
+$example=$model->Clone();
+$example->Label('Equalize');
+$example->Equalize();
+push(@$images,$example);
+
+print "Implode...\n";
+$example=$model->Clone();
+$example->Label('Explode');
+$example->Set(background=>'#000000FF');
+$example->Implode(-1);
+push(@$images,$example);
+
+print "Flip...\n";
+$example=$model->Clone();
+$example->Label('Flip');
+$example->Flip();
+push(@$images,$example);
+
+print "Flop...\n";
+$example=$model->Clone();
+$example->Label('Flop');
+$example->Flop();
+push(@$images,$example);
+
+print "Frame...\n";
+$example=$model->Clone();
+$example->Label('Frame');
+$example->Frame('15x15+3+3');
+push(@$images,$example);
+
+print "Gamma...\n";
+$example=$model->Clone();
+$example->Label('Gamma');
+$example->Gamma(1.6);
+push(@$images,$example);
+
+print "Gaussian Blur...\n";
+$example=$model->Clone();
+$example->Label('Gaussian Blur');
+$example->GaussianBlur('0.0x1.5');
+push(@$images,$example);
+
+print "Gradient...\n";
+$gradient=Graphics::Magick->new;
+$gradient->Set(size=>'130x194');
+$x=$gradient->ReadImage('gradient:#20a0ff-#ffff00');
+warn "$x" if "$x";
+$gradient->Label('Gradient');
+push(@$images,$gradient);
+
+print "Grayscale...\n";
+$example=$model->Clone();
+$example->Label('Grayscale');
+$example->Quantize(colorspace=>'gray');
+push(@$images,$example);
+
+print "Implode...\n";
+$example=$model->Clone();
+$example->Label('Implode');
+$example->Implode(0.5);
+push(@$images,$example);
+
+print "Median Filter...\n";
+$example=$model->Clone();
+$example->Label('Median Filter');
+$example->MedianFilter();
+push(@$images,$example);
+
+print "Modulate...\n";
+$example=$model->Clone();
+$example->Label('Modulate');
+$example->Modulate(brightness=>110,saturation=>110,hue=>110);
+push(@$images,$example);
+$example=$model->Clone();
+
+print "Monochrome...\n";
+$example->Label('Monochrome');
+$example->Quantize(colorspace=>'gray',colors=>2,dither=>'false');
+push(@$images,$example);
+
+print "Negate...\n";
+$example=$model->Clone();
+$example->Label('Negate');
+$example->Negate();
+push(@$images,$example);
+
+print "Normalize...\n";
+$example=$model->Clone();
+$example->Label('Normalize');
+$example->Normalize();
+push(@$images,$example);
+
+print "Oil Paint...\n";
+$example=$model->Clone();
+$example->Label('Oil Paint');
+$example->OilPaint();
+push(@$images,$example);
+
+print "Plasma...\n";
+$plasma=Graphics::Magick->new;
+$plasma->Set(size=>'130x194');
+$x=$plasma->ReadImage('plasma:fractal');
+warn "$x" if "$x";
+$plasma->Label('Plasma');
+push(@$images,$plasma);
+
+print "Quantize...\n";
+$example=$model->Clone();
+$example->Label('Quantize');
+$example->Quantize();
+push(@$images,$example);
+
+print "Raise...\n";
+$example=$model->Clone();
+$example->Label('Raise');
+$example->Raise('10x10');
+push(@$images,$example);
+
+print "Reduce Noise...\n";
+$example=$model->Clone();
+$example->Label('Reduce Noise');
+$example->ReduceNoise();
+push(@$images,$example);
+
+print "Resize...\n";
+$example=$model->Clone();
+$example->Label('Resize');
+$example->Resize('50%');
+push(@$images,$example);
+
+print "Roll...\n";
+$example=$model->Clone();
+$example->Label('Roll');
+$example->Roll(geometry=>'+20+10');
+push(@$images,$example);
+
+print "Rotate...\n";
+$example=$model->Clone();
+$example->Label('Rotate');
+$example->Rotate(45);
+$example->Transparent(color=>'black');
+push(@$images,$example);
+
+print "Scale...\n";
+$example=$model->Clone();
+$example->Label('Scale');
+$example->Scale('60%');
+push(@$images,$example);
+
+print "Segment...\n";
+$example=$model->Clone();
+$example->Label('Segment');
+$example->Segment(cluster=>'0.5', smooth=>'0.25');
+push(@$images,$example);
+
+print "Shade...\n";
+$example=$model->Clone();
+$example->Label('Shade');
+$example->Shade(geometry=>'30x30',gray=>'true');
+push(@$images,$example);
+
+print "Sharpen...\n";
+$example=$model->Clone();
+$example->Label('Sharpen');
+$example->Sharpen('0.0x1.0');
+push(@$images,$example);
+
+print "Shave...\n";
+$example=$model->Clone();
+$example->Label('Shave');
+$example->Shave('10x10');
+push(@$images,$example);
+
+print "Shear...\n";
+$example=$model->Clone();
+$example->Label('Shear');
+$example->Shear('45x45');
+$example->Transparent(color=>'black');
+push(@$images,$example);
+
+print "Spread...\n";
+$example=$model->Clone();
+$example->Label('Spread');
+$example->Spread();
+push(@$images,$example);
+
+print "Solarize...\n";
+$example=$model->Clone();
+$example->Label('Solarize');
+$example->Solarize();
+push(@$images,$example);
+
+print "Swirl...\n";
+$example=$model->Clone();
+$example->Set(background=>'#000000FF');
+$example->Label('Swirl');
+$example->Swirl(90);
+push(@$images,$example);
+
+print "Unsharp Mask...\n";
+$example=$model->Clone();
+$example->Label('Unsharp Mask');
+$example->UnsharpMask('0.0x1.0');
+push(@$images,$example);
+
+print "Wave...\n";
+$example=$model->Clone();
+$example->Label('Wave');
+$example->Set(background=>'#000000FF');
+$example->Wave('25x150');
+push(@$images,$example);
+#
+# Create image montage.
+#
+print "Montage...\n";
+$montage=$images->Montage(geometry=>'130x194+10+5>',gravity=>'Center',
+ bordercolor=>'green',borderwidth=>1,tile=>'5x1000',compose=>'over',
+ background=>'#ffffff',font=>'Generic.ttf',pointsize=>18,fill=>'#600',
+ stroke=>'none');
+
+$logo=Graphics::Magick->new();
+$logo->Read('logo:');
+$logo->Zoom('40%');
+$montage->Composite(image=>$logo,gravity=>'North');
+
+print "Write...\n";
+$montage->Set(matte=>'false');
+$montage->Write('demo.jpg');
+print "Display...\n";
+$montage->Write('win:');
diff --git a/PerlMagick/demo/lsys.pl b/PerlMagick/demo/lsys.pl
new file mode 100644
index 0000000..9ea65d6
--- /dev/null
+++ b/PerlMagick/demo/lsys.pl
@@ -0,0 +1,83 @@
+#!/usr/local/bin/perl
+
+# Written by jreed@itis.com, adapted by John Cristy.
+
+use Graphics::Magick;
+use Turtle;
+
+sub flower
+{
+ my $flower = shift;
+ my ($width, $height) = $flower->Get('width', 'height');
+ my ($x, $y) = $turtle->state();
+ my ($geometry);
+
+ $geometry = '+' . int($x-$width/2) . '+' . int($y-$height/2);
+ $im->Composite(image=>$flower, compose=>'over', geometry=>$geometry);
+}
+
+sub lsys_init
+{
+ my ($imagesize) = @_;
+
+ %translate =
+ (
+ 'S' => sub{ # Step forward
+ $turtle->forward($changes->{"distance"},
+ $changes->{"motionsub"});
+ },
+ '-' => sub{ $turtle->turn(-$changes->{"dtheta"}); }, # counter-clockwise
+ '+' => sub{ $turtle->turn($changes->{"dtheta"}); }, # Turn clockwise
+ 'M' => sub{ $turtle->mirror(); }, # Mirror
+ '[' => sub{ push(@statestack, [$turtle->state()]); }, # Begin branch
+ ']' => sub{ $turtle->setstate(@{pop(@statestack)}); }, # End branch
+ '{' => sub{ @poly = (); $changes=\%polychanges; }, # Begin polygon
+ '}' => sub{ # End polygon
+ $im->Draw (primitive=>'Polygon', points=>join(' ',@poly),
+ fill=>'light green');
+ $changes = \%stemchanges;
+ },
+ 'f' => sub{ flower($pink_flower); }, # Flower
+ 'g' => sub{ flower($red_flower); }, # Flower
+ 'h' => sub{ flower($yellow_flower); } # Flower
+ );
+
+ # Create the main image
+ $im = new Graphics::Magick;
+ $im->Set(size=>$imagesize . 'x' . $imagesize);
+ $im->Read('xc:white');
+
+ # Create the flower images
+ $pink_flower = new Graphics::Magick;
+ $pink_flower->Read('pink_flower.gif');
+
+ $red_flower = new Graphics::Magick;
+ $red_flower->Read('red_flower.gif');
+
+ $yellow_flower = new Graphics::Magick;
+ $yellow_flower->Read('yellow_flower.gif');
+
+ # Turtle: the midpoint of the bottom edge of the image, pointing up.
+ $turtle=new Turtle($imagesize/2, $imagesize, 0, 1);
+}
+
+sub lsys_execute
+{
+ my ($string, $repetitions, $filename, %rule) = @_;
+
+ my ($command);
+
+ # Apply the %rule to $string, $repetitions times.
+ for (1..$repetitions)
+ {
+ $string =~ s/./defined ($rule{$&}) ? $rule{$&} : $&/eg;
+ }
+ foreach $command (split(//, $string))
+ {
+ if ($translate{$command}) { &{$translate{$command}}(); }
+ }
+ $im->Write($filename);
+ $im->Write('win:');
+}
+
+1;
diff --git a/PerlMagick/demo/model.gif b/PerlMagick/demo/model.gif
new file mode 100644
index 0000000..f58e4a8
--- /dev/null
+++ b/PerlMagick/demo/model.gif
Binary files differ
diff --git a/PerlMagick/demo/model.miff b/PerlMagick/demo/model.miff
new file mode 100644
index 0000000..aef5159
--- /dev/null
+++ b/PerlMagick/demo/model.miff
Binary files differ
diff --git a/PerlMagick/demo/piddle.pl b/PerlMagick/demo/piddle.pl
new file mode 100644
index 0000000..a40f783
--- /dev/null
+++ b/PerlMagick/demo/piddle.pl
@@ -0,0 +1,66 @@
+#!/usr/local/bin/perl
+# Piddle example using PerlMagick methods.
+
+use Graphics::Magick;
+
+#
+# Create white canvas.
+#
+$image=Graphics::Magick->new(size=>'300x300');
+$image->Read('xc:white');
+#
+# Draw blue grid
+#
+for ($i=0; $i < 300; $i+=10)
+{
+ $image->Draw(primitive=>'line',points=>"$i,0 $i,300",stroke=>"#ccf");
+ $image->Draw(primitive=>'line',points=>"0,$i 300,$i",stroke=>"#ccf");
+}
+#
+# Draw rounded rectangle.
+#
+$image->Draw(primitive=>'RoundRectangle',fill=>'blue',stroke=>'maroon',
+ strokewidth=>4,points=>'30,30 100,100 10,10');
+#
+# Draw curve.
+#
+$image->Draw(primitive=>'bezier',points=>'20,20, 100,50, 50,100, 160,160',
+ fill=>'none',stroke=>'black',strokewidth=>4);
+#
+# Draw line.
+#
+$image->Draw(primitive=>'line',points=>"10,200 20,190",stroke=>red);
+#
+# Draw arc within a circle.
+#
+$image->Draw(primitive=>'circle',stroke=>'none',fill=>'yellow',,
+ points=>"170,70 200,70");
+$image->Draw(primitive=>'Path',stroke=>'none',fill=>'blue',strokewidth=>4,
+ points=>'M170,70 v-30 a30,30 0 0,0 -30,30 z');
+$image->Draw(primitive=>'circle',stroke=>'black',fill=>'none',strokewidth=>4,
+ points=>"170,70 200,70");
+#
+# Draw pentogram.
+#
+$image->Draw(primitive=>'polygon',
+ points=>"160,120 130,190 210,145 110,145 190,190 160,120",stroke=>red,
+ fill=>LimeGreen,strokewidth=>3);
+#
+# Draw rectangle.
+#
+$image->Draw(primitive=>'line',points=>'200,260 200,200',stroke=>yellow,
+ strokewidth=>5);
+$image->Draw(primitive=>'line',points=>'200,200 260,200',stroke=>yellow,
+ strokewidth=>5);
+$image->Draw(primitive=>'line',points=>'260,200 260,260',stroke=>red,
+ strokewidth=>5);
+$image->Draw(primitive=>'line',points=>'200,260 260,260',stroke=>green,
+ strokewidth=>5);
+#
+# Draw text.
+#
+$image->Annotate(text=>'This is a test!',geometry=>'+30+140',
+ font=>'Generic.ttf',fill=>'green',pointsize=>24,rotate=>45.0);
+$image->Write('piddle.gif');
+$image->Write('piddle.mvg');
+$image->Write('win:');
diff --git a/PerlMagick/demo/pink_flower.gif b/PerlMagick/demo/pink_flower.gif
new file mode 100644
index 0000000..7222ff5
--- /dev/null
+++ b/PerlMagick/demo/pink_flower.gif
Binary files differ
diff --git a/PerlMagick/demo/red_flower.gif b/PerlMagick/demo/red_flower.gif
new file mode 100644
index 0000000..3e2aea5
--- /dev/null
+++ b/PerlMagick/demo/red_flower.gif
Binary files differ
diff --git a/PerlMagick/demo/shadow_text.pl b/PerlMagick/demo/shadow_text.pl
new file mode 100644
index 0000000..47342bb
--- /dev/null
+++ b/PerlMagick/demo/shadow_text.pl
@@ -0,0 +1,16 @@
+#!/usr/local/bin/perl
+#
+# Make simple text with a shadow.
+#
+use Graphics::Magick;
+
+$image=Graphics::Magick->new(size=>'500x120');
+$image->Read('xc:white');
+$image->Annotate(font=>'Generic.ttf',fill=>'rgb(100,100,100)',pointsize=>60,
+ text=>'Works like magick!',geometry=>'+30+90');
+$image->Blur('0x1');
+$image->Annotate(font=>'Generic.ttf',fill=>'red',stroke=>'blue',pointsize=>60,
+ text=>'Works like magick!',geometry=>'+26+86');
+$mask=$image->Clone();
+$image->Write('shadow.gif');
+$image->Write('win:');
diff --git a/PerlMagick/demo/shapes.pl b/PerlMagick/demo/shapes.pl
new file mode 100644
index 0000000..0650c57
--- /dev/null
+++ b/PerlMagick/demo/shapes.pl
@@ -0,0 +1,39 @@
+#!/usr/local/bin/perl
+# GD example using PerlMagick methods.
+
+use Graphics::Magick;
+
+#
+# Create a 300x300 white canvas.
+#
+$image=Graphics::Magick->new;
+$image->Set(size=>'300x300');
+$image->Read('xc:white');
+#
+# Draw shapes.
+#
+$tile=Graphics::Magick->new;
+$tile->Read('tile.gif');
+$image->Draw(primitive=>'Polygon',tile=>$tile,fill=>'none',
+ points=>'30,30 100,10 190,290 30,290');
+$image->Draw(stroke=>'red',primitive=>'Ellipse',stroke=>'black',fill=>'red',
+ strokewidth=>5,points=>'100,100 50,75 0,360');
+$image->Draw(primitive=>'Polygon',fill=>'none',stroke=>'black',strokewidth=>5,
+ points=>'30,30 100,10 190,290 30,290');
+$image->ColorFloodfill(geometry=>'+132+62',fill=>'blue',bordercolor=>'black');
+#
+# Draw text.
+#
+$image->Annotate(fill=>'red',geometry=>'+150+20',font=>'Generic.ttf',
+ pointsize=>18,text=>'Hello world!');
+$image->Annotate(fill=>'blue',geometry=>'+150+38',font=>'Generic.ttf',
+ pointsize=>14,text=>'Goodbye cruel world!');
+$image->Annotate(fill=>'black',geometry=>'+280+120',font=>'Generic.ttf',
+ pointsize=>14,text=>"I'm climbing the wall!",rotate=>90.0);
+#
+# Write image.
+#
+print "Write image...\n";
+$image->Write('shapes.gif');
+print "Display image...\n";
+$image->Write('win:');
diff --git a/PerlMagick/demo/smile.gif b/PerlMagick/demo/smile.gif
new file mode 100644
index 0000000..7dede2d
--- /dev/null
+++ b/PerlMagick/demo/smile.gif
Binary files differ
diff --git a/PerlMagick/demo/steganography.pl b/PerlMagick/demo/steganography.pl
new file mode 100644
index 0000000..d08ff16
--- /dev/null
+++ b/PerlMagick/demo/steganography.pl
@@ -0,0 +1,26 @@
+#!/usr/local/bin/perl
+
+use Graphics::Magick;
+
+#
+# Create watermark.
+#
+$watermark=Graphics::Magick->new;
+$watermark->ReadImage('smile.gif');
+($width, $height)=$watermark->Get('width','height');
+#
+# Hide watermark in image.
+#
+$image=Graphics::Magick->new;
+$image->ReadImage('model.gif');
+$image->SteganoImage(image=>$watermark,offset=>91);
+$image->Write('model.png');
+$image->Write('win:');
+#
+# Extract watermark from image.
+#
+$size="$width" . "x" . "$height" . "+91";
+$stegano=Graphics::Magick->new(size=>$size);
+$stegano->ReadImage('stegano:model.png');
+$stegano->Write('stegano.gif');
+$stegano->Write('win:');
diff --git a/PerlMagick/demo/tile.gif b/PerlMagick/demo/tile.gif
new file mode 100644
index 0000000..99c8776
--- /dev/null
+++ b/PerlMagick/demo/tile.gif
Binary files differ
diff --git a/PerlMagick/demo/tree.pl b/PerlMagick/demo/tree.pl
new file mode 100644
index 0000000..8216994
--- /dev/null
+++ b/PerlMagick/demo/tree.pl
@@ -0,0 +1,29 @@
+#!/usr/local/bin/perl
+require "lsys.pl";
+
+%rule = (
+ 'A' => 'S[---LMA][++++B]',
+ 'B' => 'S[++LBg][--Cg]',
+ 'C' => 'S[-----LB]GS[+MC]',
+ 'g' => '',
+ 'L' => '[{S+S+S+S+S+S}]'
+ );
+
+%stemchanges = (
+ distance => 18.5,
+ dtheta => 0.1,
+ motionsub => sub{
+ $im->Draw ( primitive=>'line', points=>join(' ',@_),
+ stroke=>'dark green', strokewidth=>1 );
+ }
+);
+
+%polychanges = (
+ distance => 3,
+ dtheta => 0.4,
+ motionsub => sub{ push( @poly, @_[0..1] ); }
+);
+
+$changes = \%stemchanges;
+lsys_init(400);
+lsys_execute('A', 10, "tree.gif", %rule);
diff --git a/PerlMagick/demo/yellow_flower.gif b/PerlMagick/demo/yellow_flower.gif
new file mode 100644
index 0000000..a3e2345
--- /dev/null
+++ b/PerlMagick/demo/yellow_flower.gif
Binary files differ
diff --git a/PerlMagick/t/MasterImage_70x46.ppm b/PerlMagick/t/MasterImage_70x46.ppm
new file mode 100644
index 0000000..920fe6c
--- /dev/null
+++ b/PerlMagick/t/MasterImage_70x46.ppm
@@ -0,0 +1,4 @@
+P6
+70 46
+255
+0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/blob.t b/PerlMagick/t/blob.t
new file mode 100644
index 0000000..363e273
--- /dev/null
+++ b/PerlMagick/t/blob.t
@@ -0,0 +1,34 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test image blobs.
+#
+BEGIN { $| = 1; $test=1, print "1..1\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+chdir 't' || die 'Cd failed';
+
+$image = new Graphics::Magick;
+$image->Read( 'input.miff' );
+@blob = $image->ImageToBlob();
+undef $image;
+
+$image=Graphics::Magick->new( magick=>'MIFF' );
+$image->BlobToImage( @blob );
+
+if ($image->Get('signature') ne
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f')
+ { print "not ok $test\n"; }
+else
+ { print "ok $test\n"; }
+
+1;
diff --git a/PerlMagick/t/bzlib/input.miff b/PerlMagick/t/bzlib/input.miff
new file mode 100644
index 0000000..7740ad5
--- /dev/null
+++ b/PerlMagick/t/bzlib/input.miff
@@ -0,0 +1,9 @@
+id=ImageMagick
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+background-color=gray74 border-color=gray74 matte-color=gray74
+{
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/bzlib/input.miff.bz2 b/PerlMagick/t/bzlib/input.miff.bz2
new file mode 100644
index 0000000..d5c5bb7
--- /dev/null
+++ b/PerlMagick/t/bzlib/input.miff.bz2
Binary files differ
diff --git a/PerlMagick/t/bzlib/read.t b/PerlMagick/t/bzlib/read.t
new file mode 100644
index 0000000..49581a5
--- /dev/null
+++ b/PerlMagick/t/bzlib/read.t
@@ -0,0 +1,37 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading an image which uses BZip compression
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..2\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/bzlib' || die 'Cd failed';
+
+#
+# Test reading BZip compressed MIFF
+#
+testRead( 'input.miff',
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+#
+# 2) Test reading BZip stream-compressed MIFF (.bz2 extension)
+#
+print("Reading BZip stream-compressed MIFF (.bz2 extension) ...\n");
+++$test;
+testRead( 'input.miff.bz2',
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
diff --git a/PerlMagick/t/bzlib/write.t b/PerlMagick/t/bzlib/write.t
new file mode 100644
index 0000000..1cac030
--- /dev/null
+++ b/PerlMagick/t/bzlib/write.t
@@ -0,0 +1,35 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing files using bzlib-based compression
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/bzlib' || die 'Cd failed';
+
+#
+# Test writing BZip-compressed MIFF
+#
+
+testReadWrite( 'input.miff',
+ 'output.miff',
+ q/compression=>'BZip'/,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+$test = 0; # Quench PERL compliaint
+
diff --git a/PerlMagick/t/cgm/input.cgm b/PerlMagick/t/cgm/input.cgm
new file mode 100644
index 0000000..6e7bfcd
--- /dev/null
+++ b/PerlMagick/t/cgm/input.cgm
@@ -0,0 +1 @@
+0 \XCGMF01\1 A1!XSAMMIE CGM File\1"@1*XA\1-Xroman \Xgreek \Xscript \Xold english \Xstick \1&H1)@@@@0"XPicture\2%@@gjLgjL2"A0#60A@ddddRRRRIIIIvvvv[[[[mmmmfw~~bEzL5"b`@5#F cp^dfQ`pAaD d`_dkV@tA cp^djR@tA cp^djR`pAaD d`_dj[@`[ cp^diX@`Z cp^diX`pAaC d`WdkBHW cpWdi_GW cpWdi_`p@aC d`WdkW@pU cpWdjT@pU cpWdjT`p@aC cWdlRa@p[ coVdkOaAp[ coVdkO`pAaC cWdk_@`S coVdj[@`T coVdj[`pAaD cRdlAER coQdj^ES coQdj^`pAaC cRdlS@pR coQdkP@pR coQdkP`pAaC c|UdnIb]qV clTdmFb]qV clTdmF`pAaC c|XdkWSbR clWdjTSbR clWdjT`pAaC d`_dgUtGdB cp^dfQtGdC d`^dgSAdA d`_dkTfO`^ dgNdlR`UqF dhCdkL\tU dgWdfW]qP dgJdeGvLbL cp]dfPAd@ cp^djP`W`R cqUdkBKqG cr@di[UtU cq[deFYqP cqRdcVpUbZ cp]dfP`pAaC cp^djP`pAaD cqUdkB`uYaP cr@di[`vCaQ cq[deF`u\aQ cqRdcV`uXaQ ciQdjHcEr] clVdgKq_pZ cjWdfQcGrM cm^ddDJa\ cnDdhTDrT cnDdhT[bS cmYdkGpQaL cmHdlSrN`P cjZdmCa]qC clWdl@sGH ciPdlHAr@ clSdjOdGsQ cpZdf^JrX cqDddFEbA cqIdfGQbQ cqHdhXWbE cqAdj]pSaF cpNdlCMpY cp[dkJpZ_ cpAdj[sPaT clQdlOBr@ clSdjOsBW clQdlOsAW cpAdj[sJaE cp[dkJvAaY cpNdlCsF`P cqAdj]sHJ cqHdhXsDT cqIdfGsAW cqDddFsFR cjZdmCSvR clWdl@QtU cp[dkJQtL cZdkRcVr] dcPdhUcR^ dgBdhGcFrL djHde[Ka[ djOdjJDrT djOdjJ\bT djCdl^pPaL diSdnJrNO dgEdnYsTqO dcQdmJsYG cXdmQBq_ c|YdkKdGsQ da@dgZfLrK dgLdeOEbA dgQdgPQbQ dgPdjAWbE dgIdlFpRaF dfWdmLuVqF daAdlFpZ_ d`GdkWsPaT c|WdmKBr@ c|YdkKcAG c|WdmKcAF d`GdkWcJaS daAdlFfDbS dfWdmLb\`^ dgIdlFbZ`X dgPdjAb_I dgQdgPcBF dgLdeOb\L dgEdnYSvR dcQdmJQtU daAdlFQtL ddEdpPqKq\ dbZdnTrC`tZ d`WecNpQaG d`FedUqHiD c~^emYEaJ cCeoCaM`[ d`Peo^`RrA daBem]aSzE dbUecXFpZ db[eb^Ip_ dcDea_a^}] deBdtBp]sR c~CdpCqLqT c|WdnOrC`tQ czTec@[aG czIedGqBiE cyGemLaQF czXemRaHyP c|@edBCp] c|CecEDpZ c|GebKa\prH c~CdpCe[c] dc^dt@q]m] dbAea]Z`^ daWeb[@`[ daWecVqKjE d`Lem[^bB c^eo]tE@ c{Yeo]qDqD czUenYqNqM cyGemLeWM czIedGe]N czTec@fCN c|WdnOfCE c~CdpCfBM dc^dt@aDB dbAea]aCB daWeb[aDC daWecV`^B d`Lem[`VB c^eo]`RA d`Lem[uTY c{Yeo]qArK czUenYdNJ db[eb^rD`P daWecVuWL daWeb[uTJ dbAea]uZN cg_dnRqKq] cfTdlUrC`tZ cdQeaOVaH cdKebWp[iE ccPek\`PaK cd@emGaM`[ ceMenBHrB ceUel@aEzF cfZeaZUp[ cfUe`_Ip^ cf^e`Aa^}] ch\drDp]sR cnBdn_qLqS clVdmLrC`tQ cjSea][aG ciFelHaByD ciFelHaQF cjWelNaHyP ck_eb^Cp] clBebADpY clFeaHa\prI cnBdn_tCcG ci_drFq^m] chAe`CY`_ cgXeaB@`Z cgXea\qLjE cfLelA]bB ce_enCcR`R ciQenUqCqE chNemP`XqH ccPek\eVL cjHecDu]] cjSea]vB^ clVdmLvBpW cnBdn_vC] ci_drFqCR chAe`CqCR cgXeaBqCS cgXea\p^R cfLelApWQ ce_enCpRQ cfLelAdKM ciQenUaFrG chNemPtNY cfUe`_rD`P cgXea\dGaB cgXeaBdJ`_ chAe`CdEaE c|WdnOppAqC cmOdmSpYW c}PdnWpYX c}PdnWppAqD cmZdpJ[rW c}[dqN[rW c}[dqNppAqD cmPdsZJsP c}Qdt^JsP c}Qdt^ppAqD cl_dwX`Qs^ c}@dx[`Qs] c}@dx[ppAqC clZdw]EU c|[dyAEV c|[dyAppAqD clWdxNCpQ c|XdyRCpQ c|XdyRppAqD cl[dx\T^ c|\dy_T] c|\dy_ppAqC clNd|NMsR c|Nd}QNsR c|Nd}Qpp@qC clHd|MFA c|Id}QE@ c|Id}QppAqD clFd|^BpQ c|Gd~ABpP c|Gd~AppAqC clJd}LT^ c|Kd~PT_ c|Kd~PppAqD ckZe`_`PsS c{[ebB`PsR c{[ebBppAqC ckWe`^CA c{XebBC@ c{XebBppAqD ckTeaPCpR c{UebTCpR c{UebTppAqD ckXeaYTY c{Yeb\TX c{Yeb\ppAqC ckCekQ`UyX c{DelU`UyY c{DelUppAqD cjUelYNqH czVem]NqH czVem]ppAqD ciLel]aIT cyMenAaIT cyMenAppAqD ciFelHF`U cyGemLF`U cyGemLppAqD cjHeb_qBiI czIedBqBiJ czIedBppAqC cjSea][aB czTec@[aB czTec@ppAqC clVdmLrC`tQ c|WdnOrC`tQ cyBeoWOqB ckGenOqTF czVeoQqTF czVeoQOqB ckLenXUY cz[eo[UZ cz[eo[OqC cjZev[`RxC czIew^`RxC czIew^OqC cjKew^OqC cyZey@OqB cyZey@OqB ciGevXaDaF cxVewZaDaF cxVewZOqB ciNeoBWgV cx]epEWgU cx]epEOqC ciSenUUM cyBeoWUN5#B ci^dcFp[iS ci^dcFNA cjLdcGp[iS ciQdlZ^Q cjLdcGH@ cjTdcGp[iS ciYdlZX@ cjTdcGTR cjPdcEp[iT ciUdlYDA cjPdcE\R cjDdcCp\iT ciHdlWMB cjDdcC^@ ciVdcCp\iS chZdlVNA ciVdcCX@ ciNdcCp[iS chSdlVG@ ciNdcCDA ciRdcDp\iS chVdlWSQ ciRdcDLB ciCdlY]R ciCdl[SaA ciCdl[`VA ciYdl\SaA ciVdm]pVQ ciYdl\M@ cjFdl\RaA cjDdm]^@ cjFdl\BQ cjHdl[Sa@ cjEdm[QB cjHdl[\S ci\dlXRaA ciZdmYKB ci\dlXpTR ciHdlVSaA ciEdmW`UB ciHdlVpUR chSdlTSaA chPdmU`UB chSdlT^@ chEdlTSaA chBdmUN@ chEdlTQB chDdlVTaA ch@dmWBR chDdlVKB chOdlXSaA chLdmY\R chOdlX`TC ci@dm\pTS ciFdm^R`V ciFdm^`YB ci_dn@R`V ci]dnVpYR ci_dn@`RA cjQdnAR`U cjOdnVpR@ cjQdnAGR cjXdm_R`V cjVdnUWA cjXdm_VR cjRdm]R`V cjPdnSFB cjRdm]pRS cj@dmZR`V ci^dnP`RC cj@dmZpXS ciHdmWS`V ciEdnM`YC ciHdmWpYQ chOdmVR`U chMdnK`XB chOdmVpSQ cg\dmUR`V cgZdnK`S@ cg\dmUWB cgUdmWR`U cgSdnLGQ cgUdmWGB cg\dmYR`V cgZdnOWS cg\dmY`RC chNdm\S`V chKdnRpQS chNdm\`XB ciDdnTpYR5#F biDdcG`pEaD byIdhL@tA biDdgH@tA biDdgH`pEaD byIdgQ@`[ biDdfM@`[ biDdfM`pEaD byBdgXGW bh]dfTGW bh]dfT`pEaD byBdhM@pU bh]dgI@pU bh]dgI`pEaD bx@diHaBp[ bg\dhDaAp[ bg\dhD`pDaD bx@dhT@`T bg\dgQ@`S bg\dgQ`pDaC bw\dhWDS bgWdgTES bgWdgT`pEaC bw\diI@pR bgWdhE@pQ bgWdhE`pEaD bt_dj_b]qV bd[di[b\qV bd[di[`pDaD buAdhMRbR bd]dgIRbR bd]dgI`pDaD byIddKtHdB biDdcGtGdB bx_ddH@dA bx_dhIfJ`^ bIdiG`VqF b_dhA\tV bSdcK]qP bFda[vGbM biUdcGAd@ biVdgG`Z`R bjPdgYIqG bjYdfRStU bjVda]YqP bjMd`MpXbZ biUdcGoJaA biVdgGoIaB bjPdgY`tYaN bjYdfR`uFaO bjVda]`t]aN bjMd`M`tYaN baWdf^cDr^ bd[dd@r@pZ bb[dcFcFrL bfAd`ZKa[ bfHdeIDrT bfHdeI[bS be]dg\pQaM beLdiIrOO bb]diXb@qC bd]dhUsHI baUdh^Br@ bdZdgEdHsQ biBdcTGrY biId`[FbA biOdb\RbR biMdeNVbE biGdgSpSaF bhTdhYOpY biCdh@p[_ bhHdgQsPaT bdXdiEBr@ bdZdgEsCW bdXdiEsCW bhHdgQsKaD biCdh@vFaX bhTdhYsH`P biGdgSsJI biMdeNsEU biOdb\sCW biId`[sHQ bb]diXRvR bd]dhURtU biCdh@QtL bxEdhGcVr\ b{[deKcT^ bOdd]cGrL cbVdbQJa[ cb\dg@DrT cb\dg@[bS cbQdiSpQaM cb@dk@rOO bQdkOsTqO b{]dj@sZG bxCdjGBr@ buBdhAdGsQ byIddPfNrK bWdbEFbA b]ddFRbQ b[dfWVbE bUdh\pSaF bBdjBuWqF byKdh\p[pP bxPdhLsPaT bu@dj@Bq_ buBdhAcCF bu@dj@cCG bxPdhLcMaT byKdh\fFbS bBdjBb^`^ bUdh\b\`W b[dfWcAI b]ddFcCF bWdbEb_L bQdkORvR b{]dj@RtU byKdh\RtL b|QdmFqKq\ b{FdkJrC`tZ byCe`DpQaG bxReaKqIiD bwIejOFaI bwOekXaM`\ bx\elT`SrA byOejSaRzE b{Ae`NFpZ b{GdTIp_ b{Pd~Ua^}] b}NdpXp]sR bvMdlYqLqT buAdkErB`tQ br_dV\aG brSe`]qBiE bqQejBaQF bsBejHaIyP btKe`XBp] btMd[EpZ btRdAa[prH bvMdlYe]c] b|JdpVq]m] bzMd~SZ`^ bzCdQ@`[ bzCe`LqKjE bxXejQ^bB bxJelStG@ btCelSqCqD bs@ekOqOqM bqQejBeXM brSe`]e_N br_dVfDN buAdkEfEE bvMdlYfDM b|JdpVaDB bzMd~SaCB bzCdQaDC bzCe`L`^B bxXejQ`WB bxJelS`RA bxXejQuVY btCelSqArK bs@ekOdOI b{GdTrD`P bzCe`LuXL bzCdQuVJ bzMd~Su[N b`DdkGqKq\ a~YdiKrC`tY a|Vd~DVaH a|PdLp[iE a{UehQ`PaK a|Eei\aM`[ a}RejWHrB a}ZehUaEzE a~_d~PVp[ a~Yd}UJp_ aCd|Va^}] baAdnYp]sR bfHdkUqKqT bd]djArC`tQ bbZd~R[aG baMeh^aByE baMeh^aQF bb^eiDaHyP bdFdTBp] bdHd~WEpZ bdMd}]a[prH bfHdkUtDcG bbDdn\q^m] b`Fd|YY`^ a]d}W@`[ a]d~RqLjE a~QehW]bA a~DejXcT`R baXekJqDqD b`TejF`YqH a{UehQeXM bbOdYu_] bbZd~RvD^ bd]djAvDpV bfHdkUvD^ bbDdn\qCS b`Fd|YqCS a]d}WqDR a]d~Rp^R a~QehWpWR a~DejXpRQ a~QehWdMM baXekJaFrF b`TejFtOZ a~Yd}UrCO a]d~RdIaB a]d}WdKa@ b`Fd|YdGaD buAdkEppDqD beVdjIpYX buZdkMpYX buZdkMppDqD bfAdm@[rW bvEdnD[rW bvEdnDppDqD beWdpPJsP bu\dqTIsP bu\dqTppEqD beGdtM`Ps] buKduQ`Qs] buKduQppDqD beAdtSFV buEduWFV buEduWppDqD bd^duDCpQ buCdvHBpQ buCdvHppEqD beBduQT] buGdvUT] buGdvUppEqD bdUdyDMsS btYdzGNsR btYdzGppDqC bdPdyCEA btTdzGE@ btTdzGppDqD bdNdySBpP btRdzWBpP btRdzWppDqD bdQdzAS^ btUd{ES^ btUd{EppDqD bdAd}T`PsS btEd~X`PsS btEd~XppDqD bc^d}SCA btBd~WCA btBd~WppDqD bc\d~FBpS bt@dJBpS bt@dJppDqD bc_d~NSX btDdRTX btDdRppEqD bcJehG`UyY bsNeiK`VyY bsNeiKppDqD bb\eiONqH bs@ejSNqH bs@ejSppDqD baSeiSaIT bqXejWaHT bqXejWppEqD baMeh^F`U bqRejBF`U bqRejBppEqD bbOdTqBiJ brSe`XqAiJ brSe`XppDqD bb[d~R\aB br_dV\aB br_dVppDqD bd]djArB`tQ buAdkErB`tQ bq@epHSqB bcBeo@qUF brTepBqTF brTepBRqB bcFeoITY brYepLUZ brYepLSqC bbUewM`QxD brGexO`RxC brGexORqB bbEexO`PqB bqXeyROqC bqXeyRSqC baAewIaDaF bpTexLaDaF bpTexLSqC baHeoSWgV bp[epVWgV bp[epVSqC baMeoFUM bq@epHUN5#N byKcRQ@ byJcRQ@ byIcR@Q byIcQBA byKcSQA byJcTQ@ byIcT@Q byIcSB@ byKcR@A byJcR@B byIcR@B byIcQ@B buFc{_qAs@ btEcx_FpT btKcxK`^cC buIc{NS`Q br_c{Zq@s@ bq_cxZEpT brDcxF`_cC bsCc{IT`Q buFc{_rGU buIc{NrFU btEcx_rFU btKcxKrGU bWdgZQ@ bVdgZQ@ bUdgZ@@ bUdgZB@ bWdg\Q@ bVdg\Q@ bUdg\@Q bUdg[BA bWdgZ@B bVdgZ@B bUdgZ@B bUdgZ@A c`Kc}RpUrA bVc{QDpR bZcz_`UbA c`Oc}@T`R bw^c|_pUrA bwIcz^DpR bwMczL`UbA bxBc|MT`R c`Kc}RxMpS c`Oc}@xMpS bVc{QxMpS bZcz_xMpS cjAdcE@@ cjAdcER@ ci_dcE@@ ci_dcEB@ cjAdcG@@ cjAdcGR@ ci_dcG@@ ci_dcGB@ cjAdcE@B cjAdcE@B ci_dcE@B ci_dcE@B clVdnVpXC ck^dnYuQ\ cfMdnM`XS cgEdnJeQL clSdpIpXC ck[dpLuQ\ cfJdp@`XS cgBdo]eQL clVdnVSaS ck^dnYSaS cfMdnMSaS cgEdnJSaS cjQdh\[A cjFdh]qJR ch\dh[KR ciGdhYaJC cjGdnS\A ci[dnTqJS chQdnQKQ ch\dnPaKC cjQdh\ZeW cjFdh][eW ch\dh[[eV ciGdhY[eW cjOdcEZeW cjOdcESA cjLdcF[eV cjAdh\D@ cjLdcF_Q ci]dcEZeW ciSdh\N@ ci]dcEZQ ciSdcD[eW ciHdh[KA ciSdcDD@ ciWdcD[eV ciLdhZTA ciWdcDN@ cjEdcD[eW ciZdh[^Q cjEdcDJA cjEdh\[Q bvKd|FQB bvJd|HQ@ bvId|H@R bvId|FB@ bvKd|H@A bvKd|IR@ bvId|I@Q bvId|HB@ bvKd|F@B bvJd|HAA bvId|H@A bvId|F@B bvIdnVgX`Q b~AdoGsKiI bzVdxPwWpQ br_dw_cJyI bw@dsLgW`Q b~Wds]sJiI b{Md}FwXpQ bsUd|UcKyI bvIdnV`WdV b~AdoG`VdV bzVdxP`WdV br_dw_`VdV brUdtMVE brOdtR[W brDdtKUpS bq_dsXApP br@dsHGU brGdsCIG brPdsJF`S bpEduNXF bo]duTpQT boLduPZpR boBdt^R_ bo@dtOJW boJdtHNF boXdtNL`Q bnNdwEZH bnDdwMpSS bmQdwJ]\ bmDdv^T_ bm@dvOLV bmLdvI`QA bm]dvJOM bmWdyL[J bmLdyVpTC blXdyYpPZ blHdyOS\ blEdyCKZ blPdxY`TR bmDdxW`PJ bnCd{Z[J bmXd|DpTH bmDd|L_T blUd|HS\ blRd{\KZ bl]d{R`SW bmPd{K`PD boOd~EXN boGd~SpQK bnVd~^\@ bnJd~^RY bnHd~UJ] bnRd~HO\ boAd}\MB bqXe`FWO bqQe`U]O bqDeaDWD bp]eaHQW bp\eaAI^ bqEe`SKpP bqPe`CIS btTeaST`P btPebCX`R btHebUQF btGeb[CU btJebVEpP btOebFEpR btTeaTCV bwXebHS`P bwUebX@`T bwUecLDF bwYecRES bw^ecOBpR bx@eb]ApR bxAebKUX bzWebAQ`P bzVebQG`S bz]ecDIG b{FecKFU b{LecFBpP b{NebVVpS b{HebC[W b}Hea@@O b}HeaOL`P b}Tea_NF b~BebEJV b~Lea_R_ b~JeaPZpR b~@e`^pPT b~_dHAN b@dVON bOe`D`QA c`@e`ELV c`Ld_TpP c`HdO]\ b[dCpSR bUd}ACL bXd}M`PI c`Hd}V`UQ c`]d}UJ[ caGd}JS[ caDd|_pPZ c`Td|UpTB bJdzSCK bMdz^OE b\d{C`SX c`Odz[KZ c`ZdzQS[ c`WdzF_T c`HdzBpSG b}]dxIAG b}^dxPMA b~KdxQO\ b~ZdxEK\ bEdwYSY bBdwP[@ b~WdwPpQJ b{TdvGQG b{SdvNIS b{\dvKKpP b|Gdu[I^ b|PduMQW b|OduFWD b|HduJ]O bxXdt[SE bxUdu@CV bxXdtZFpR bx^dtHDpQ byBdsWCU byEdsRQF byDdsXW`R brUdtMVE brOdtR[W brDdtKUpS bq_dsXApP br@dsHGU brGdsCIG brPdsJF`S brUdtMrPaA bpEduNqWaW bnNdwEpWbG bmWdyLLbN bnCd{ZaLbK boOd~EbIbA bqXe`Fb\aM btTeaScD`U bwXebHb_W bzWebAbQqA b}Hea@aWqX b~_dH`VrG bUd}A[rN bJdzSqMrJ b}]dxIrIrB b{TdvGr\qL bxXdt[vC^ brUdtM@@ brOdtRrRaB bo]duTqYaY bnDdwMpXbI bmLdyVLbN bmXd|DaObO boGd~SbJbB bqQe`Ub_aN btPebCcE`U bwUebXcAW bzVebQbRqB b}HeaOaXqY b@dV`XrI bXd}M[rO bMdz^qOrN b}^dxPrKrB b{SdvNr^qN bxUdu@vF^ brOdtR@@ brDdtKrXaE boLduPq[aZ bmQdwJpYbO blXdyYLbS bmDd|LaRbR bnVd~^bNbF bqDeaDcDaQ btHebUcM`W bwUecLcHX bz]ecDbWqE b}Tea_a[q[ bOe`D`YrN c`Hd}V\rS b\d{CqQrR b~KdxQrOrF b{\dvKsDqQ bxXdtZvT_ brDdtK@@ bq_dsXr]aF boBdt^q^b@ bmDdv^p\bQ blHdyOMbY blUd|HaUbV bnJd~^bSbJ bp]eaHcJaS btGeb[cR`W bwYecRcMW b{FecKb\qF b~BebEa^r@ c`@e`E`]rP c`]d}U^rZ c`Odz[qUrV b~ZdxErSrJ b|Gdu[sIqS bx^dtHv_pP bq_dsX@@ br@dsHs@aG bo@dtOr@b@ bm@dvOp[bT blEdyCMbY blRd{\aVbY bnHd~UbTbL bp\eaAcNaU btJebVcT`Y bw^ecOcNY b{LecFc@qG b~Lea_b@r@ c`Ld_`[rU caGd}J]rY c`ZdzQqUrX bEdwYrUrL b|PduMsNqV byBdsWwB_ br@dsH@@ brGdsCr]aE boJdtHq^bA bmLdvIp\bP blPdxYMbY bl]d{RaUbV bnRd~HbSbK bqEe`ScJaS btOebFcQ`W bx@eb]cNW b{NebVb\qF b~JeaPa^rA c`HdO`\rP caDd|_]rY c`WdzFqUrV bBdwPrSrJ b|OduFsJqT byEdsRv^_ brGdsC@@ brPdsJrXaD boXdtNq[a\ bm]dvJpYbM bmDdxWLbT bmPd{KaQbQ boAd}\bObG bqPe`CcDaQ btTeaTcM`W bxAebKcGX b{HebCbXqE b~@e`^a[q[ b[dC`YrN c`Td|U\rS c`HdzBqQrR b~WdwPrOrF b|HduJsDqR byDdsXvT^ brPdsJ@@ brVds]rRaB bpDdt_qXaX bnLdvWpXbJ bmTdyALbN bn@d{OaNbO boNd}^bKbB bqYe`@b^aN btWeaNcE`U bw\ebCcAW bz]ea\bSqB b}Pe`ZaXqY bHdA`XrJ c`@d|W[rN bUdzIqOrO b~FdwZrKrA b{[duYr^qO bx]dtJvG] brVds]@@ b{Hd|X]aD bQd|AtVa[ b^dz^tVaZ b^dz^]aC b}TdxSa]cN b~@dwPa^cN b~@dwP\aC b{GdyVbMqC b{SdxRbMqB b{SdxR\aD bwXdwWcOa_ bxDdvScOa_ bxDdvS\aD bwKduBMbU bwXds_LbT bwXds_]aC bsXdtZcSH btEdsWcSH btEdsW]aC btEdwO]rU btQdvK\rT btQdvK\aD bqFdy@b_qQ bqSdw\b^qQ bqSdw\]aD bnMdwRbYaN bnZdvNbYaN bnZdvN]aD blQdzWa\sE bl^dySa\sE bl^dyS]aD br[d}JvJrS bsGd|FvIrS bsGd|F\aD bz[d}\x@pR b{Hd|XxApR5#F cdUdiPQA cdTdiQRQ cdRdiPA@ cdSdiPB@ cdUdiRQ@ cdTdiRR@ cdRdiRAQ cdSdiQBA cdUdiP@B cdTdiQ@A cdRdiP@B cdSdiP@A ciDdi[qYT ceAdk^bJrG cfZdlBbJrG cfZdlBqYT ceNdiK]bS cgGdiO]bS cgGdiOqYT cgOdg[rAaP ciHdg_rAaP ciHdg_qYT cgKdiWDq\ ciDdi[Dq\ cf_dkOqYT cb^dlTbHqI cdWdlXbHqI cdWdlXqYT cbTdh^JcV cdMdiBJcV cdMdiBqYT ceLdi[rXp] cgDdi_rWp] cgDdi_qXT ceFdkKFqP cf_dkOEqP ciMdhAWG ciFdhHqKS cg[dhEHW chCdg^aJC ciMdiDWG ciFdiKqKR cg[diIHX chCdiAaJC ciMdhA@aC ciFdhH@aC cg[dhE@aD chCdg^@aC chJdePr]bH ceMdgX_rL cd^deLqYaW ccEdgCpYcY cbLdj\vAe[ b|KdpWRt] b|IdkZqE`R b{DdlLqCU bzAdlGp^`] byCdmDfFN bIdmR`^p^ c`GdlTaCF caJdlZaEpS cbOdlG`Sd_ ccBdqFfSuZ ciUdkL`YsY cjNdgSaYqW clGde\ObL clVdhHb]rH coSdf@wIpP ccCcwQwKdW b{Xc|HsRgL bxFdcTrMb[ buYdfOmI`] ccBdgLcPrY cfRddSkIvZ cq[c}Yb^uA ctYcxXpqVqG chJdePuG}_ coSdf@eF}H ceMdgXgI`P cd^deLgI`P ccEdgCgI`P ccEdgCwMz[ cjNdgSgMyZ cbLdj\gI`P b|KdpWfWO cbOdlGdCwT b|IdkZtCxF b|IdkZfFM b{DdlLfFN bzAdlGfFM byCdmDsJvU bIdmRcYvF coSdf@cDsA crWdb_eG}H cw^cuWsEcA ckNdbNuF}^ cfHctP`qVaG chJdePcDsB ckNdbNgI`Q ccCcwQcEsA boBcxR@@ boBcxRR@ bo@cxRA@ boAcxRA@ boBcxS@A boBcxTR@ bo@cxTAQ boAcxSA@ boBcxR@A boBcxR@B bo@cxR@B boAcxR@A ctYe~ObIsY cwBezVtLK crVe{As@aE coVe|FqQaZ cnEe~@fTO coVe|FFp^ co\e{H`SuG cpOevA`WwQ cqFenPMtS cqSei]`YtB crLee[`ZvD csFdWJuS csPdzDbZaZ cvJd{^dXaP c{Bd}NqStF cyOdyHtVaeG cxRenUbPpqG ctBenObHprQ cxRenUtPV ctBenOr\A crVe{AaL|R cwBezVaP|A csPdzDprAp] csFdWpq]qH crLee[pq]qH cqSei]pq]qH cqFenPpq]qH cpOevApq]qH co\e{Hpq]qH coVe|Fpq\qH cnEe~@pq]qG b|He|Yu_] bvIe|LaWq] bx@ezObBY bzBezFbGE b|IezKQbN b|He|YaRq[ b}Zez^Ep^ b|IezKaV[ b}_ez@`SuG b|IezKaD}D bzBezFaE}E bx@ezOaJ}T byJel[a]F b{GemAbFF b}MemGa\A bIemHpWgQ byJel[bFptA b{GemAbQpsG b}MemGbRpsI bIemHMtS bVehU`YtB c`OedS`ZvD caId~OFuH caOdyGqP`W b_dy^rGT b}XdyZrHq@ bz_dwD`QaV bz_dwD`~PbD crVe{ArZG bvIe|LdVqeH cm]ezKOqB c`BeyBqTG coQezEqTF coQezEOqC c`GeyLUZ coVezNUY coVezNOqB bUfaO`RxC coDfbQ`RxC coDfbQOqB bEfbR`PqC cnUfcTOqC cnUfcTPqB b~BfaKaCaG cmQfbNaDaF cmQfbNOqC b~IeyVWgU cmXezXWgV cmXezXOqB b~NeyIUM cm]ezKUM bzVdwX}Ip^ bnEdwPpXpV b{MdxNpWpV b{MdxN}Hp^ bnMdzYXsI b{Vd{VYsH b{Vd{V}Ip] bnAd~TLs[ b{IdRMs\ b{IdR}Hp^ bmNeb]`StI bzVecZ`StH bzVecZ}Hp] bmHec@FS bzPec^FT bzPec^}Hp^ bmDecRDpR bzMedPCpR bzMedP}Ip^ bmHedCTpQ bzQeeATpQ bzQeeA}Ip^ blXeh@`Ps] bz@eh]`Qs\ bz@eh]}Hp] blSeg^EB by\eh[DB by\eh[}Ip] blQehOBpQ byYeiMCpR byYeiM}Hp^ blTeiASpR by\ei^SpQ by\ei^}Hp] blAel]`Ss\ byIemZ`Ss\ byIemZ}Hp] bk^el[CB byGemXBB byGemX}Ip] bk[emNCpS byDenLCpT byDenL}Ip^ bk_emZT\ byGenXS\ byGenX}Hp^ bkBexU`]z[ bxJeyR`]zZ bxJeyR}Hp] bjSey]OqH bw[ezZOqH bw[ezZ}Hp] biKeyOaHN bvTezMaGM bvTezM}Ip^ biGexTD`[ bvOeyQE`\ bvOeyQ}Hp] bjOenNqHjF bwXeoLqIjE bwXeoL}Ip^ bj[emL\aB bxCenI[aC bxCenI}Hp] bmMdvZrR`vR bzVdwXrS`vQ ajQeyJcEsW amVeuScR`] aqHevPaNaO arVew_qQaZ aqEeyYvT_ arVew_Fp_ ar\ew@`SuG asOeqY`VwQ atEejHNtS atSeeU`XtB auKeaS`[vC avFd{PIuS avOdu]qTaO at[dwLtB`] apYdxIqStF aoFdtCtUaeG aoEeiRaTpqI arSei]bHprQ aoEeiRcNK arSei]aRK aqHevPaK|S amVeuSaO|A avOdu]`qYaR avFd{P`q]aH auKeaS`q]aH atSeeU`q]aH atEejH`q]aH asOeqY`q]aH ar\ew@`q]aH arVew_`q]aG aqEeyY`q]aH bcBe{Ae_M biAe{NaWq\ bjXeyRqOpQ biIeyArGU bgBex\t@bE bcBe{AaQq[ bdSeyFFp^ bgBex\rIpT bdYexH`SuG bgBex\aD}D biIeyAaD}E bjXeyRaJ}U blBek]qUQ bjMek\rGT bhFekXrDX bfBekPpVgQ blBek]bFptA bjMek\bQpsH bhFekXbRpsI bfBekPNtS bfPef]`XtB bgHeb[`[vC bhCd|XEuI bhHdwObPa@ bjXdxObFE bl^dxTaJpX bmVdvF`RaV bmVdvFp~PrC aqHevPaT`P biAe{NdUqeH bbXewMPqB at]evEqUF bdLewGqTF bdLewGOqB auBevNUY bdQewQUZ bdQewQOqC atPe~Q`RxC bc_eT`RxC bc_eTOqC at@eT`PqC bcPf`VOqB bcPf`VPqB ar]e~NaCaF bbLePaDaF bbLePOqB asDevXWgV bbSew[WgU bbSew[OqC asHevKTM bbXewMUN azGdpMa|YdG cv^dxVBtB azEdtPBtC azEdtPa|YdF cv^dw\@`Z azEdsU@`[ azEdsUa|YdG cvWdxAGU ay^dsZGU ay^dsZa|YdG cvWdxV@pU ay^dtP@pV ay^dtPa|YdF cuVdyKaApU ax]duDaApT ax]duDa|YdG cuVdxW@`T ax]dtP@`T ax]dtPa|YdG cuRdxYDR axXdtRER axXdtRa|ZdG cuQdyKApR axXduD@pR axXduDa|YdG crVdzNb[qC au\dvGb\qC au\dvGa|ZdG crYdw\SbR au_dsUSbR au_dsUa|ZdG cw@dtTtGcH azGdpMtHcH cu\dx@cVr\ cyRduDcR^ c}DdtVcGrM d`KdrIJa\ d`QdvYDrT d`QdvY\bS d`EdyLpPaL cUdzXrN`P c}Gd{HsTqO cySdyYsYG cuZdz@Br@ cr[dwYdGsP cwBdtIfLrL c}Ndq]EbA c}Sds^QbR c}RdvPWbE c}KdxUpRaF c|Ydy[uVqF cwCdxUpZpP cvIdxEsPaT crYdyYBr@ cr[dwYcAG crYdyYcAG cvIdxEcJaT cwCdxUfDbS c|Ydy[b\`] c}KdxUbZ`W c}RdvPb_I c}Sds^cBG c}Ndq]b]L c}Gd{HSvR cySdyYQtU cwCdxUQtL ar\dsGcEr^ avAdpIq_pZ atBdoOcGrM awIdmBJa\ awOdqRDrT awOdqR\bS awCdtEpPaM avSduRrNO atEdvAa]qC avBdt^sHI arZduGBr@ au^dsNdGsQ azEdo]JrY azOdmDEbA azTdoERbQ azRdqVVbE azLds[pSaG ayYduBMpY azFdtIpZ_ ayLdsZsPaS au\duMBq_ au^dsNsBW au\duMsBV ayLdsZsJaD azFdtIvAaX ayYduBsF`P azLds[sIJ azRdqVsCT azTdoEsAW azOdmDsFR atEdvASvR avBdt^QtU azFdtIQtL cvYdtD@dA cvYdxEfO`^ c}HdyC`VqF c}^dw]\tU c}RdsH]qP c}EdqXvLbL ay_do]AdA az@ds^`W`R azWdtPKqH a{BdsHUtT az]dnTYqP azTdmDpUbY ay_do]a|ZdG az@ds^a|YdG azWdtPbbQdS a{BdsHbb\dU az]dnTbbUdT azTdmDbbQdT5#A b}WcqMqHg^ b|OcyKX`[ b|GczFpZa[ by^c~XvSiU bsKdhMzHlQ biCdt^rXaB bfKdv@q_rE bdLds[rDv[ bbHdm@[yN ba]dcRRvY ba[c|YaCxQ bb^ctHbNtA b}WcqMr@C b{WcqPXg[ b{Kcy]qBaX bzIc{UqRbS bxWc~HvZiK bq]dgSqJqA bpSdfRgOx^ bxBc}TaYrH by[c{LZqE byQczGp[xB bxVcrEcApU bxVcrEsFaV byQczGrKaQ buPcs[aVg] bxBc}Tp\q\ bpSdfRrKtO bq]dgS{RnM bpSdfR|GmI bnHdbC|@j] beVcYsYcY beAcy^sFb[ bfRcqVsTbR bh^cmWsRbP b{Kcy]qPaO bwFc{Xx^fK b}WcqMxPf^ bjVcm[rUbR bnHdbCqCr^ boFcxDp^dA bnHc|EqCc@ bmEcEqObW bkVda\p_aP bjWdcLpX`[ bi_ddGpYL biFddSp\T bhJddOqHp\ bgBdcSp[r@ bfGdaSpQqZ beVcYpUu[ beAcy^aQxH bfRcqVbLs_ beAcy^SdO bd^c~MHa[ beFd`H`[a^ bfAdbFa@`] bgAdcC`WT bgXdb_`UpQ bhMdbN`XpW biEdaW`]qK bjBd`LaKrV bkMc}VaArY blNcz]bXrY bnHc|EqZqH bmEcEqXqO bkVda\qTqP bjWdcLqRqU bi_ddGqRqY biFddSqNqT bhJddOqIqL bgBdcSqAqM bfGdaSqAqK beVcYpXqL buGcxKp^dG btIc|Rp^c@ bsKcRqGbT brDdbFp[aM bqIdcSpVaB bpSddUpWF bo\dd[pZB boBdd]qF^ bm\ddOp\rQ bm@da^pSqZ blMd`DqBuX bkKczLpQxM bjZcq_TtD boFcxDfAG blNcz]g[aU bkMc}Vg^a\ bjBd`LhBaZ biEdaWhDa\ bhMdbNhFbG bgXdb_hDa\ bgAdcChAaZ bfAdbFg[bI beFd`HgZaV bd^c~MgOaW beAcy^fJN bfRcqVdHI bh^cmWaXD b{OcyKa@@ b{Mc|AqD\ by^c~XqGpP bsKdhMqNpZ bxWc~HpUpT bzIc{U^Y biCdt^qFpZ bg]dtDJvW bhGdmMCyM bhJdd@RvY bhHc}GWxT bhActS@tF bg]dtDsQY bhGdmMu_] bhJdd@vM^ bhHc}GvM^ bhActSuC[ bhAcpMrUV b{OcyKq^`\ buPcs[vJdI b{Mc|AqObW b|GczFp\Y b{Kcy]DpR boFcxDrXbY blNcz]bDuC bnRcuZ`Z`Z boLcvTVaP boFcxBrXbZ blNcz\bDuD bnRcuX`Z`\ boLcvTVaN blNcz]@Q bnRcuZ@R boLcvT@@ boFcxD@R eiYcvVUh@ eiTc~VT`[ eiPcQpWa\ egXddEuHiX ebPdm]x^lT dyRdzQSaH dyOd{YbNq[ d{]dy^bXvQ d~UdsM`QyL dFdjARvY dDdcHqRxW d}RczQrMtL eiYcvVaQK ekJcwApZgY ejLcLpPaZ ei\daFp]bS eh_dcYuAiP ec^dmIaJp[ eeHdlNdLyE eiTdcI`VrK ejJd`^KqB ejUc\bAw] elVcw_qLp^ elVcw_pPa\ ejUc\TaU elFcy[qUgV eiTdcI`]qX eeHdlNbKtE ec^dmIzOnP eeHdlNyKmP egSdhIx^kD ec@dfIsZcX ea\d`LrXb\ dMcw[q[bV d|^csQqYbT ejLcLRaR ejQdaQr^fX eiYcvVvCgD d{EcsMrUbR egSdhIaCrZ eiLc~LTdC eiHdbOpRc@ ehVdeOpYbY eg]dhHpRaQ egKdiYpR`\ efYdjUpQM efHdkBpUT eeSdj^q@p[ edSdjCqBrA ecQdhBpQqY ec@dfIqDu] ea\d`LrOxQ dMcw[rOtJ ea\d`LbDdT ed@de@`Va\ edVdf\aBa_ eeXdh[aG`] ef_diX`WT egVdiT`UpQ ehKdiC`QpX eh\dhK`UqK eiQdg@`]rW ejNddI`TrZ ekBdaOqVsC eiHdbOaZq@ ehVdeOaXqF eg]dhHaTqH egKdiYaQqN efYdjUaRqR efHdkBaNqN eeSdj^aLqF edSdjCaEqH ecQdhBaEqF ec@dfIa@qI ecVc}Z_dG ecGdbApWcA ebPdeBqAbU eaOdgWpWaM e`XdiDpSaB e`EdjFpSF dRdjLpWC d~[djOqB_ d}Ydj@pYrP d}@dgP_qZ d|QdeVp^uX d{Sc^^xL d{EcwR@tE eiLc~LuVpR ekBdaOw[`R ejNddIw^`Y eiQdg@xB`W eh\dhKxD`Y ehKdiCxFaC egVdiTxD`X ef_diXxD`W eeXdh[w_aE edVdf\wV`T ed@de@wO`V ea\d`LvI^ dMcw[tHY d|^csQqYT ejPc~Zp\T ehYdaMaCW egXddEaG\ ebPdm]aNpT eh_dcY`UpP ei\daFNX dyRdzQqFp[ dxLdyVIvV dxUds@DyM dxYdiSRvZ dxWdbYWxS dxPczF@tG dxLdyVcQH dxUds@f@M dxYdiSfMN dxWdbYfMO dxPczFeBK dxPcu_bUF ejPc~ZEaB elFcy[rZdQ ehYdaMqAbX eiPcQ`\U ejLcLDpR eiLc~LaVcC ekBdaOpQuI ejQc|Fp_`V eiRc|\VaP eiLc~JaVcC ekBdaMpQuI ejQc|Dp_`X eiRc|\VaN ekBdaO@R ejQc|F@R eiRc|\@@ eiLc~L@R bg\duFqFaD bfVdvJcDqI biZduAq^E bhXeu]pQ`P bhGevMbMpQ bjTeu\q\A bjTeu\pZq`[ bhXeu]p\q`W bhGevMqQq`C dw]dzWqEaD dvXd{[WqQ dvQdzJaLM deYezCpQ`Q deHezTp]pY ddKey[aNH ddKey[`rFpQ deYezC`rDpL deHezT`qPp~Y ddEcsMaLrM deQcq@Gp] deXcpCBpP deZcoSSS deWcoPGpU de^cn[@sK de^ckPRtR de\cf^qKrG ddQcdWRrZ ddOca]ZI ddEcbF@`qG cmXcrEaLrM coDcoXGp\ coKcn\BpQ coMcnKSS coJcnHGpU coQcmS@sK coQcjHRtR coOceVqKrG cnDccORrZ cnBc`UZI cmXc`^@`qG cbGcq]aMrP ccTcoMHp\ cc\cnQBpP cc^cnATT ccZcm]GpU cdAcmH@sK cdAci]RtR cc_ceKqKrG cbTccDRrZ cbRc`JZI cbHc`SQ`qJ by_cq[KrD bzJcoWpQp^ byYcnYEpP by^cnICS bzAcnFVpV by[cmP@sK by[cjEAtR by\ceSaMrA b{IccRBrZ b{Kc`XHK b{ScaCqT`pX by_cq[qQqO bxNcpLpTp[ bwZcoQSpP bwWcoAET bw\cn]pVpV bwFcnG@sJ bwFcj]EtR bwKcfKcRrT bz]ccWErZ b{Bc`]`QF b{ScaCqT`pX bsHcvWrTqI bpTcuNp]pX boWctVW^ boPctHNV bo^ctBp\pP boBcsR@sJ boBcpHCtU boEckSaHsO bpMchDaCrY bqPceKaXD bsHceO@`qH bq[cxCrOqO boLcvTpZpZ bnRcuZTpQ bnNcuI`PX bn^cuApZpR bnDctOMsW bnQcpXMt] bn^ck[aKsS bpIchHaCrY bqLceOaYD bsEceS@b\ bsEchOTcU bsAclDZd] brWcqA]cW brJctXWaJ brCcvBS`X br@cvZUaI cmXcrE`vMaH coDcoX`vMaH coKcn\`vMaG coMcnK`vMaH coJcnH`vMaH coQcmS`vMaH coQcjH`vMaH coOceV`vMaH cnDccO`vMaH cnBc`U`vMaH cmXc`^`vMaH cbGcq]kQH ccTcoMkPK cc\cnQkOK cc^cnAkOJ ccZcm]kPK cdAcmHkPK cdAci]kPK cc_ceKkPK cbTccDkPK cbRc`JkPK cbHc`SkPK by_cq[hHB bzJcoWiJZ byYcnYjCX by^cnIj@X bzAcnFiYY by[cmPjFX by[cjEjFX by\ceSjCX b{IccRgK^ b{Kc`XgG^ b{ScaCfUpP by_cq[@@ bxNcpLa\pU bwZcoQa_pX bwWcoAbGpX bw\cn]bEpW bwFcnGbUpW bwFcj]bUpX bwKcfKbQpX bz]ccWLU b{Bc`]IU b{ScaC@@ bsHcvWfWt\ bpTcuNgZuB boWctVhCuE boPctHhGuG bo^ctBg^uE boBcsRhDuK boBcpHhDuK boEckShFuH bpMchDjPtM bqPceKiRtN bsHceOhKtL bq[cxCaMqL boLcvTaHqF bnRcuZaEqD bnNcuIaBqA bn^cuAa@p_ bnDctO`^p] bnQcpX`QpP bn^ck[GX bpIchHDT bqLceODT bsEceSCT boLcvTbTF bnRcuZcQH bnDctOdFI bnQcpXdFI bsAclDtCY bsEchOr\W ddEcsMaLrM deQcq@Gp] deXcpCBpP deZcoSSS deWcoPGpU de^cn[@sK de^ckPRtR de\cf^qKrG ddQcdWRrZ ddOca]ZI ddEcbF@`qG dy_cuHaLrN d{KcrZGp\ d{Rcq^BpP d{TcqNTT d{PcqJHpU d{XcpU@sK d{XcmJRtR d{VchXqLrG dzJcfQRrZ dzHccWYI dy_cd@@`qH edQcvPaMrP ee^ct@Hp\ efFcsDApP efGcrTST efDcrPGpU efKcq[@sJ efKcnQQtS efJci^qLrG ed^cgWRrZ ed\cd]YI edSceFR`qJ ekXcwPaVrA emNcuOa@pZ enNctURpQ enLctD[S enActA`VpU enWcsL@sJ enWcpBUtS enRckOtDrM ejNciBVr[ ejHcfGp[H eiMcfObK`qA ekXcwPb@qF emXcvJ`^pX enVcuRD_ enZcuCYV enQct]aBpR eoSctK@sJ eoScqAYtS eoJclNt[sF ejOciHYr[ ejFcfMpYB eiMcfObK`qA ehEc|SbUp] ejZc{V`\pS ekVc{CG^ ek]czU^X ekOczM`\\ elKczA@sK elKcvVStT elHcrBqGsT ekAcnNqDr_ ei]ckOqXS ehEckL@`qG efWc}_b[qC eiRc|\`_pV ejQc|FJpP ej[c{V\Z ejOc{L`^^ ekMcz^MsW ekZcwGFt^ el@crIqCsW ej]cnRqCr_ eiZckSqYT ehAckO@b\ ehAcnKTcU eg]cr@Yd^ egTcv^^cV egFczTVaJ eg@c{^S`X ef]c|VVaI dy_cuHpuZq[ d{KcrZpuZqZ d{Rcq^puZq[ d{TcqNpuZq[ d{PcqJpuYqZ d{XcpUpuZqZ d{XcmJpuZqZ d{VchXpuZqZ dzJcfQpuYqZ dzHccWpuYqZ dy_cd@puZqZ edQcvPzRqH ee^ct@zSqF efFcsDzTqF efGcrTzSqF efDcrPzTqF efKcq[zSqF efKcnQzSqG efJci^zTqF ed^cgWzTqF ed\cd]zTqF edSceFzTqF ekXcwPwGq@ emNcuOwPqO enNctUxHqQ enLctDxEqP enActAw]qQ enWcsLxLqQ enWcpBxLqQ enRckOxHqQ ejNciBuPqK ejHcfGuLqJ eiMcfOtZqI ekXcwP@@ emXcvJZp[ enVcuRXp] enZcuC^p_ enQct]pPp\ eoSctKp\p_ eoScqAp\p_ eoJclNpXp_ ejOciHQV ejFcfMBV eiMcfO@@ ehEc|ScSuC ejZc{Vb^uL ekVc{Cc@uQ ek]czUb]uR ekOczMcBuP elKczAcHuV elKcvVcHuU elHcrBcBuT ekAcnNpRuF ei]ckOIuB ehEckLaHt] efWc}_aNqL eiRc|\aHqF ejQc|FaEqC ej[c{VaBqA ejOc{La@p_ ekMcz^`^p] ekZcwG`QpQ el@crIHW ej]cnRDT eiZckSCT ehAckODS eiRc|\rUV ejQc|FsQX ekMcz^tGZ ekZcwGtFY eg]cr@dCI ehAcnKb\G eiMc~JpqNq[ dw_c|OqLpW dvSc{XpXpT du[c{DpUvX duFctL`tNbN eiTcvZWgP ehUcApqNq[ dwGc}FqLpW du[c|OpXpT duCc{[pVvX dtMcuC`tObN eh\cwQWgP eiMc~JpX`W dw_c|OpX`W dvSc{XpX`W du[c{DpX`W duFctLpY`W eiTcvZpX`W b|Vcx_`rS`V coIcyUaXpP cqAcyEa@pP crAcxUbMvR ctNcrCpvNpP b~@cqSqJgL b{^cyV`rT`V cnRczLaWpQ cpIcy[a@_ cqIcyLbNvR csWcrZpvNpQ b}IcrIqKgM b|Vcx_pX`W coIcyUpW`W cqAcyEpX`V crAcxUpX`W ctNcrCpW`W b~@cqSpW`V du@cvTppDqK dd\cuIppSp] ctIctL`RqJ ct[csB`pG`^ deBct@o[aI dt]cuICaK dtVcv]ppDqK ddRcuRppSp] cs_ctU`RqJ ctQcsK`pG`^ ddXctIo[aI dtScuRCaK du@cvTZI ctIctLZI ct[csBZI dt]cuIZI ddRcuRFqI dd\cuIFqI d}RczPrNtJ d{DcvFvTqA dtPcuEaJh[ duZc~@gXsP dbGdt]rLtL c[dpQvUq@ cyFdoQaIh\ czOdxMgXsP d}RczPp{K`zM d{DcvFp{I`zK dtPcuEp{J`zL duZc~@p{K`zM bb^ctGbMs_ beKcpHfUT bl@cpDqKhU bjUcxYwWtR agRdnTbPtA ajBdjSfTS apVdjPqLhV aoJdsFwXtR bb^ctGp{L`zM beKcpHp{I`zK bl@cpDp{J`zL bjUcxYp{K`zM c{Ve{NUD c{Qe{RvIn[ cuHfjMpRaG ctVfkTCT ctYfkP`SqG cuLfjIfJ~[ czLe{DUD czGe{Hu^`pT ctIfk\EU ctNfkWe^ppS ctNfkWKW ctIfk\MX czLe{DaJJ czGe{HaJJ cuLfjITD ctIfk\qRa@ crWfl\qDY cqSflS`R{[ crEf`XdKq^ cvPe~Zp^R cuRe~XrNkF csDfi^`WL cs[fjJaMC cuHfjMp[\ ctMfjArZbR ctIfk\MX ctVfkTqW`T cr_flHqLK cqSflSaQrU csDfi^aIC ctIfk\^qR crWfl\HpT cr_flHaNrG ctVfkT`RqG crEf`XcMr@ ctMfjAbC{G ayOfgYqOaA ax@fhZq@Y aw@fhQpp]}B afCe{OLrF afOeyI`^B agMeyK`qAlQ axNfe\`SK ayAffGqNS awSffD^[ awEfeYUbX ayOfgYpV[ axYfgNqA`V awXfhDpXM aw@fhQaNrU axNfe\qIS ayOfgY^qR ax@fhZXpV awXfhDpSrK axYfgNqFqJ afCe{OaJrD awEfeYppV|P c{Ue{OaYqE c}NezJbLvF cZetDGsN d`AepVKqZ d`Len\bHwM dbTegOaExW dcYd~Xp_zJ dbZdtNpSO dbGdt]`YjT dc@dQqHh[ daXehLqJc^ d`NelJqAaT cMem^qAaA c~Len_qF`Y c}FeoXqQD c{Ueo\qCp] czRen_q^`W cxTeoVaVbR czJerHaZD c|DerLaDpX c}HeqTaIqE c~QepOaDqY cUenVb_wG dcYd~XpY`Y dbTegOp\`] cUenV`YrL c~QepO`\rQ c}HeqTaDrU c|DerLaBrT czJerHaKrL czRen_y@G c{Ueo\xTa\ c}FeoXxUbD c~Len_x[bD cMem^x\a_ d`NelJx_aZ daXehLxZpV dc@dQxRpX dbGdt]wFpT c{AdtIpSjP czNd~YqPh] cx^egVqOfN cwOenDp^aY cvQeo]q@aF cuQeqCq@`Y ctQeq\qPT csAeqXqOrR c{AdtIN[ dbZdtNwKpP dcYd~XxVpT dbTegOxVpS d`Len\xMpS d`AepVxKpR cZetDxHpR c{Ue{OtCw] c{Ue{OuEcK cZetDpsGoF c}NezJpsEoD c{Ue{OsTcO cxAe~^rZbA cuGf`_z^hO cjIfiNbJvD clSfcJJzA cl]eyIcXsG cpUevBg_vL cqReoFy@h\ cpUevBrJk\ cnKfa^qXaL clSfcJtZY cgYfcAppGpZ bwRfbG@zF bwRexA`uKaH bwRexA`XpW bxJewJ`pH`X chRexB@jF chRfbHpY`Y chRfbHppHpX bxJfaPpX`W bxJfaP@zF cg\fiKSvJ cg\fiKbMC cg\fiKlU|G cg\fiKjIxS crEf`XcBG crEf`XdKq^ cvPe~ZaQD cvPe~Zq_qV ctQe}DcAyR cwResRDsN cwVepDIq[ cw_enIa_wM cy^ef\aExX c{Cd~DLzF agUeuTq\qM aeYetGrPvP acIemW@sN acIejIHq[ acQehNaVwN aeGea@aExX afLdxHaVzC ahBdnEpPO agRdnTrCjN aeOdyBqOhZ ad@ea\qQc] abOeeYq@aU aaOegNp[aA a`TehOpW`Z `]eiIqCE `~ZeiNpUp\ `~EehRI`\ `~NeiNaHbQ `Vek_aEC a`[elB`]pX aaXekJ`WqG abOejC`YqZ acHehIa_wI afLdxHp]`Z aeGea@qG`\ acHehIpYrP abOejCq@rU aaXekJqDr[ a`[elBp^rY `Vek_p\rQ `~EehRgKaL `~ZeiNhFcA `]eiIhRcJ a`TehOh[cL aaOegNi@cF abOeeYh_cB ad@ea\h]`R aeOdyBh^N agRdnTgMM an_doApRjO anMdyPqPh^ al]ebNqOfM akNeh[p_aY ajOejTq@aG aiOek[q@`X ahOelSqOT ag@elOqPrQ an_doAO\ ahBdnEgL`P afLdxHhU`S aeGea@hU`S acQehNhM`S acIejIhK`R acIemWhH`R agUeuTc\wK agUeuTqFcU acIemW|HoU aeYetG|FoS agUeuTrWcQ ad^eyEq^bC ac@e{HyMhR `ySfcZrRvN `wAe}LpRzC `vOesIbQsJ `y@eo_eNvQ aePei^x_h\ `y@eo_p\l@ `xDe{_qCaM `wAe}LdVL `{We}XoTaM akKeE@zF akKet_pt\qV akKet_`XpW alCetHRqN `|QerZ@jE `|Qe|_pZ`Y `|Qe|_oRaO alCe~NpX`W alCe~N@zF `{ZfdBSvJ `{ZfdBrGX `{ZfdBlU|G `{ZfdBjIxS afCe{OsCW afCe{OLrF afOeyIqQT afOeyIb@qN ahOew[cByR akQenICsN akTej[JqZ ak^eiAa^wN am\eaSaExX aoAdx[MzF cxTeoVyRg^ coBewTrCaH cl_ex\sIF ciVeyBprFqF bwPew\pvEqO baKevMjFy[ cyYem^yTg_ cpEeu]rQaP cmTewMsVK ci^ewXpsGp] bvWev[pvEqO b`ReuL`YaA cx^ei]xRf^ cpLep[rUaS cmWerNsVK cjAerYpsOp[ bvReq^pvEqO b`MepOEd] cwHedUw_gH coIek]rAaU cmHemRsM`R ci[enDps@p] bv[emGpvEqO b`VekXYdW ctKdZxLg\ ck_egVqA`S cj^ehIrFM chXehVppZpW bw^eg_pvFqN baXefQqBeG cxTeoVqmCsD cyYem^qnFsF cx^ei]qnMsG cwHedUqmJsE ctKdZqjUr^ biVd|\w^iU ctKdZb]d[ cwHedUaVeH cx^ei]`[dA cyYem^qEaX bkQelRBqZ bkSejXqBtB bjQefVpSuF bi^eaPXtT coBewTaCqW cpEeu]GuB cpLep[qCt^ coIek]sJtG cl_ex\`UqO cmTewMCt_ cmWerN_t\ cmHemRrJuI ciVeyBHqJ ci^ewXCt_ cjAerYVtU ci[enDqCuN bwPew\pYqA bvWev[Ut] bvReq^ItW bv[emGaCuH czRen_q^`W cxTeoVaEqX cyYem^`YaA czRen]q^`W cxTeoTaEqX cyYem\`YaA czRen_@R cxTeoV@R cyYem^@R `~NeiNwAhC `wMeqQpTaK `vYer\bN`T `yGesP`rBaJ akIetZ`vBaS baKevMjFy[ `}LegQwBhE `vJeoVpUaT `uUeqJbP`Y `xEerC`rLaV ajQesY`vAaS b`ReuL`YaA `|CecOv@gD `vCejSpYaW `uJelJbP`Y `wZemC`rQaY ajKen\`vBaS b`MepOEd] `|Td~KuNgN `wFeeYqAaX `vEegQbK`^ `xPehO`rEaV ajUejE`vAaS b`VekXYdW `Ady]tQhE `zPebBQ`U `zOebWaK`T `{ZecKo^aR akXed]`v@aT baXefQqBeG `~NeiNamCcD `}LegQanGcG `|CecOanNcG `|Td~KamJcE `Ady]ajUb_ biVd|\w^iU `Ady]rMdN `|Td~KpQeD `|CecOaIdB `}LegQaBa] bkQelRBqZ bkSejXqBtB bjQefVpSuF bi^eaPXtT `wMeqQqCq[ `vJeoVWuC `vCejSaCtZ `wFeeYcJsW `vYer\qDqR `uUeqJ[u@ `uJelJ`[tY `vEegQdJtZ `yGesPqBqM `xEerC[u@ `wZemC`VtT `xPehOcJuD akIetZpXqA ajQesYVt] ajKen\JtW ajUejEaCuH `~EehRI`\ `~NeiNqBq] `}LegQ`YaA `~EehPI`\ `~NeiLqBq] `}LegO`YaA `~EehR@R `~NeiN@R `}LegQ@R beAdvMpRrM bdOdt@pPwC bc_dl]DyO bdCdcNVvZ bc]c|TAxM bc^ctGqoRhS `tLc|Z]iE `s_de_@fX `s_dlWpPj^ `sOdwU`Pf] `s_d~R`WaR `tVe`DapKyW bf\dv\`XqV bgTduF`^vS bhRdnSqF^ bgLdnELyK bgXddZUvZ bgSc~@sUyY `tLc|ZcJjQ `wVdgK@fW `wVdnBpYj\ `v]dx^aFN `xCdyLp^fK `wEdW[`_ `vZe`VapByZ `wEdWapOzQ `xCdyLapOzY `v]dx^apOzY `wVdnBapByH `wVdgKao]yK `s_de_ao^yK `s_dlWapDyI `s_d~RapPzR `[dtQadDwT `sOdwUeBqR `WdrCwIaQ `xNdsTCbO `xQdvCHa[ `xYdw^gIqR a`BdvLWq[ `[dtQTrN aaKdrVwJaQ `zAdtGAdF `zBdxMgKqQ aaMdv\RtF `xYdw^aIO a`BdvLaK`P `WdrCaT`S `xNdsTaS`S beAdvMa[O bdOdt@cEaF bc_dl]cMaH bdCdcNcUaL bc]c|TcVaL `s_de_cWaL `s_dlWcWaK `sOdwUcNaI `s_d~RcFaE `tVe`DbD`R `tVe`DbN^ `wDdVaE`xX `xIexNjQrF abZevHf@qH ahZeu@d]qE amWes[bQ`V apHetQsTaI alTeuZsJaA aiJev[v@aO acJexJ|QbS `vYez]D`S `v]e{PlXrQ acUex_fAqU aiVewJcHqA al^evIcJqX apHetQ`uWp}Y anRetZ`sXp}M baLdwBpsU`|Y bbJdwMp^[ be_dvXsU`U baLdwBdSZ anRetZpuMc_ `tVe`Da[`xW `v]e{PqNp{J `yEexYqGpyA `tVe`D`YB `uOe`FbO^ `w^dXpZR `vQex[HbB `xIexN`\K abZevH`PbB acJexJK`U aiVewJ\_ aiJev[pPq[ amWes[qCa_ alTeuZJO amWes[`[`_ `vQex[aX] `v]e{PbHrW anRetZaVY dyMd{^bLq_ d{Ydy_bSvT d~LdsK`PyM d~\di^QvZ d~[dcDqNxT d}MczPu@n_ dxMdiOaMiM dyZdr\@fX dyZdyTpQj^ dyIedRrTfN dvUek@q]aF dtXelFdUppH dvGd{TCqY dvJdy[CvV dvMdsEbAA dxNdsFByM dxPdiYQvY dxOdc@d^xP dxMdiOuAiI dsLdrX@fW dsLdyOSj_ dsIedNrAQ dqHedMTfO dqDej\Qa@ dqCek\eDppH dqDej\eFpqA dqHedMeEpqH dsIedNeEpqH dsLdyOeDV dsLdrXeCX dyZdr\eAX dyZdyTeBV dvUek@eDpqA dzSdYcY|N dyIedR`QrH dzWd}LpZbQ dy]d]SbM dyZebJ]aY dyMedC`YrQ dzFeaRMqY dzSdYDrM dw]d}JpYbQ dwDd[@dF dwDedA`YrQ dw]eaP@tF dyMedCrIR dzFeaRrIR dzWd}LrZR dy]d]rYR dyMd{^sFZ d{Ydy_uOT d~LdsKu^U d~\di^vLU d~[dcDvLT dyZdr\vNT dyZdyTvNU dyIedRv@T dvUek@uQT dtXelFsUZ dtXelFHpX du@ekN{J`v\ diVfbJaLsR dkBe~X`ZrA dk\e|W`UqY dlQez^qJC dkGe{ACa[ dkJe|\YaP dkAe~LpZbG djGf`SqWdH dhPfd[pSO dg]feJaWtF diTfaD`WrO djKe~UMqO djXe}FOrE dkGe{AlSpD dkAe{RlMp~P dyAd}C|P`}[ dwNd}BaSA dwZd{]\aE dyAd}CqGqF dkAe{Rr\fW dtXelF{J`vX dg]feJkOpyL dhEfbIkOpwD dtXelFqLX dsLek^HpY dsTekEaLI diNfb^p^a] diVfbJqQQ dkBe~Xp[a[ djGf`SpS`Q djKe~U`VY dkAe~L`[qU dlQez^qGa^ dkJe|\pRJ dlQez^qP`T diNfb^HpT dg]feJHsA dkAe{RFpQ djSekWa^qC dlQejTbWvJ doHedJ`Vz^ do^dyL@vW do^drUqNyP dnPdiE{UkH db[dtM`^jJ dcYd~WqDhW dbUegNrHgM d`Men[[aZ d`BepUWcN c[etCrLfF c}OezIqYaE c{Ve{NsQ_ cxEez_RqB cxCey]RvK cxAesRb@D czNenNa_wM c|MegAaExX c}Rd~IeIy\ dnPdiEvIjO dhGdsT@fX dhGdzLXj^ dg_eeJr@T de_eeFYfO deVekUTa@ dhGdsTgWp_ dg_eeJgIq@ djSekW~]oW dlQejTBoU doHedJ{IkK do^dyL}InB do^drU|ElB dhGdsTzUjU dhGdzL{ZlU de_eeF}^nL deRelU}MnJ c[etCaZr@ ddHelZrJbN da^eoHYb[ daUerC^aJ daGesMbJrO dcQep^NqI dc_eoUIr[ cEelNrJbO c|[en]@dF c|[esCbJrO cEepT@tF daGesMtLZ cEepTdLJ cEelNeCL c|[en]eCK czEepIIq[ czAesVDsM djSekWuA`^ dlQejTv[aA do^dyLwWa@ dcYd~WvG^ dbUegNvH] d`Men[u_] d`BepUu]\ c[etCuZ] c}OezIuL\ dg_eeJ}^nL deVekU}SnH djSekWpY`W diZelN{U`vG c~EfbUwWf[ cvNfiPdFzU czTe~[cHu_ c}\ex\rFbR c{Ve{NvJn[ cuLfjIpR`_ ctZfkHh]wV c}WfcR`_qK c~VfbGk]pvP diHekM|C`xZ c}EfdGxWgP ctNfkWe^ppS czLe{DbFrR c|RexRsIfF cyIe~XtPjU ctYfiMh@v[ c|YfbRkWpvN dhPelD`XpW c}WfcRpR`U ctZfkH\O cvNfiPqUS c~EfbUqLS diZelNqJZ djSekWqKZ cvNfiPqUS czTe~[qKS c}\ex\qJZ c{Ve{NqJZ cuLfjIaBpY c~EfbU`Q^ c}EfdG\qU avSee\qWqK at\edQrDvU arXd}\Wz_ arQdr]@vX arQdlEaGyI asXdb\{UkH ahCdnDqVjC afMdxGqEhX aeHe`_qVgN acRehMXa[ acJejH@cN acJemVbPfQ aeZetGa\aL agVeuScQA akGeuTRqB akEetRRvK akCenGq_T aiQehZa_wM akPeaMaDxX alTdxUtQzQ asXdb\cRkE awJdnA@fX awJdtYXj^ awBdWb@D ayBd[ZfP axXefKSa@ awJdnAtYq\ awBdWtJq[ avSee\~]oW at\edQBoV arXd}\{JkL arQdr]}InB arQdlE|DlB awJdnAzVjT awJdtY{ZlT ayBd[}_nL axUegK}NnI acJemVa[r@ agFefKrJbO ad\ehZIb\ aeEekVNaK aeSemAbJrN ag]ejS_qK agNeiHXr] alHefVrJbO ai^eiE@dF ai^emKbKrO alIej\QtF aeSemAdKJ alIej\tLY alHefVuB[ ai^eiEuB[ aiGejUJq[ aiDenCCsN avSee\bBaO at\edQc\aZ arQdr]dYa\ afMdxGfGN aeHe`_fHN acRehMe_M acJejHe]M acJemVeZM aeZetGeKK awBdW}^nL axXefK}SnG avSee\pY`X auZefTiO`wU aIe~Iv_f] axJfeF{E{X amEeyNsIvM ai\esArFbR agVeuS`pA`pN awWffAaFaB ax]fgCgSwY b`PeJpZqO aVe}[yCpw_ aw]eeXiC`zI ba@f`AwLgT ayTfgUppTprF ai@euObGrR akGer]cHfT anOeyQkPkY ay_feJfVv] b`Ue~MyPpw] awEefP`XpX b`PeJ`P`W ax]fgC`W`R axJfeFaUD aIe~IaLD auZefTaKT avSee\aJT axJfeFaUD amEeyNaJC ai\esAaKT agVeuSaJT awWffA`Sp[ aIe~IM^ ba@f`A[qT b|VcyG\`[ b|JczBrDdS bzFc~UvSiV bsSdhKzHlS biKdt^oJV bxUdtX`{MaG ctBdu_`yUbO dmWdxNkTbB dyKdzPh^|V ebIdmZeIyY egRddAa\tT eiNcMQp[ eiMc~RpqMq[ dx@c|WqLpW dvTc|@pYpT du[c{LpRsV duIcwVppOqP ddZcvFpqEpZ csUcuLqTcQ crAcx]q@`P cqAcyMqW`P coJcy]prTpV b|VcyDpsK`{W biKdt[oJp[ bxUdt@`{KaA ct@duA`yWbT dmWdwUkTbW dyKdzL`pBp{^ eiMc~NpqNqZ dw_c|TqKpX dvTc{\pYpS du[c{IpRsV duIcwSppOqQ ddZcvBpqEpZ csUcuHqTcQ crAcxYq@`P cqAcyIqW`P coJcyYprTpU b|VcyG@S biKdt^@S bxUdtX@pX ctBdu_Rp^ dmWdxN@pY dyKdzP@T eiMc~R@T dx@c|WQS dvTc|@@T du[c{L@S duIcwV@S ddZcvF@T csUcuL@T crAcx]@T cqAcyM@T coJcy]@T du[c{LpqPqT dvTc|@prLqW dx@c|WpsZq] eiNcMpr_qW egRddAprZpU ebIdmZpqDpQ dqEdmIpvG^ dtXdcLps]Y dvOc}VprUqG ddKcyXprJp[ ddHczIpsGp\ ddFczZpt\p] dcZc|Opr^qL d`[dcCps\rO cz^dl[pvGrT bsSdhK`qDa\ cl_d`TprYq_ cp\c{CptRqA cp\c{Cs]eQ dcZc|Or_fT dvOc}VqWeV cdWdjGhHyS d`[dcCu]iX dtXdcLsSi] cdWdjG|BjQ cz^dl[v\iD dqEdmIsNkE ddZcvF_cR ddKcyXS`Q ddHczIR`Q ddFczZ\aU cq^f`QQ@ cq]f`QR@ cq[f`QAQ cq\f`PBA cq^f`RQA cq]f`SRQ cq[f`RA@ cq\f`RB@ cq^f`Q@A cq]f`Q@B cq[f`Q@A cq\f`P@B cq^f`Q@F cq^f`WwDaL cjZfbCz]O b]fbRpvTpZ biIfaXpuRrH asWePyAq[ ajVe}UtLrF afJe{OtVc_ aaTeNtYdA `|[fcOpZ`V `|AfdEeP`W aaQfd\iYaJ akJffF`u_aZ baIfh@`vHaH bwQfiHjDC caUfiKf@B cgUfiM`YpV chNfhWdZtA cmHfdVdVs_ cjZfbCsJbY b]fbRrKbB biIfaXq[aV asWePrLbB ajVe}UsJbY agLf`NtYd@ aqKfaRtZd@ bgNfcNtZc\ b}RfdTtZd@ cgPfd\tZd@ cbVfh\qAO bxXfhTqG`T bbTfgJqK`V alQfeRqG`T abSfdNqBN cgUfiMTvC caUfiK@vJ bwQfiH@vW baIfh@CpqE akJffF@vW aaQfd\@vI cq^f`QwD`] cjZfaNz]H b]faVpvTqA biIf`UpuRrB asWe~SyAqS ajVe}@tLqX `{]e~BHW afJe{HzEhR cgYfiBjExQ cgXfcCAe_ cgQfcJGW caUfcAe\I bwQfbQjD`P bwJfbPGA bwJexK@jE baLev[`u^aP akQeuJ`u[aQ akQeO@zE akJeOG@ aaQe~SiY`\ `{]e~BeT`Q cjZfbC@pU b]fbR@p\ biIfaX@qC asWeP@p] ajVe}U@pU afJe{O@W `|AfdETvC `|EfcZ@u_ `|Ee}[o]aD alBe~_@zF alBetYakYcA bw[ewZ@jF bw[fb@o]aC cgYfiBrkTuH cmHfdVuXF cgPfd\y^X b}RfdTpvDqF bgNfcNpvCq\ aqKfaRy_qD agLf`NuXq@ chNfhWuXE cbVfh\y^X bxXfhTpvDqJ bbTfgJpvCqX alQfeRy^qD abSfdNuXp_ bwJfbP`QpP bwJexK`QpQ akQeuJ`QpQ akQeO`QpP5#H abIdtM@@ abIdtM@Q abIdtL@Q abIdtK@B abIdtM@@ abIdtM@Q abIdtL@Q abIdtK@B abIdtM@@ abIdtM@@ abIdtL@@ abIdtK@@ abUd~QB@ acVd|Op_bB acTd|Op_bB acTd|OB@ adOdyPpYb_ adMdyPpYb_ adMdyPB@ ae@duZpQcV ad^duZpQcV ad^duZB@ aeGdrAWcY aeEdrAWcY aeEdrAB@ aeCdnRDcO aeAdnRDcO aeAdnRB@ adTdkVOb\ adRdkUOb] adRdkUBA ac\di_`XaW ac[di_`WaV ac[di_A@ ab_diO`]`P ab]diO`^`P ab]diOB@ aa_djIa@pZ aa]djIa@pZ aa]djIB@ aa@dlK`_rB a`_dlK`^rB a`_dlKA@ a`GdoJ`Yr_ a`EdoJ`Zr_ a`EdoJB@ `VdsA`QsW `TdsA`QsW `TdsAB@ `OdvYGsX `MdvYGsX `MdvYB@ `SdzHTsO `RdzHUsO `RdzHA@ a`Bd}E_r] a`@d}E^r] a`@d}EB@ a`Zd~[pXqV a`Xd~[pXqV a`Xd~[B@ aaWdLp]pQ aaUdKp]pP aaUdKBA abWd~Qq@`[ abUd~Qq@`Z c|GdzTA@ c|HdzT@Q c|HdzSQ@ c|GdzS@A c|GdzTA@ c|HdzT@Q c|HdzSQ@ c|GdzS@A c|GdzT@@ c|HdzT@@ c|HdzS@@ c|GdzS@@ c{PeePQ@ cyXeeFaWJ cyZeeGaVI cyZeeGRQ cxJecVaNaP cxLecVaNaQ cxLecVR@ cwLe`_`^bW cwNe`_`^bW cwNe`_R@ cw@d}SLcL cwAd}SMcL cwAd}SQ@ cwHdy[XcX cwIdy[XcX cwIdy[Q@ cxBdvDpZcW cxCdvDpZcW cxCdvDQ@ cyMdsAqKcC cyNdsAqKcC cyNdsAQ@ c{AdpZqTbG c{CdpZqUbG c{CdpZR@ c|\doYq[aA c|]doYqZaA c|]doYQ@ c~RdpCqVZ c~SdpCqVZ c~SdpCQ@ d`@dqSqNqP d`BdqSqOqP d`BdqSR@ d`^dtJp^rW da@dtJp^rW da@dtJR@ daJdwV\sL daLdwV\sL daLdwVR@ daBd{MHsW daDd{NHsX daDd{NRQ d`IdE`YsX d`JdE`ZsW d`JdEQ@ c~^ebHaKsC c~_ebHaKsC c~_ebHQ@ c}IedOaUrG c}KedOaTrG c}KedOR@ c{OeePaZqA c{PeePa[qA ef@csB@@ ef@csB@R ef@cs@@@ ef@cs@@B ee_csAQA ee^csB@R ee^cs@AQ ee_cr_@B ef@csBQQ ef@csBR@ ef@cs@R@ ef@cs@QQ ef[dcP{WpZ ef[dcPqTaR eeGdeB{XpZ dyOddHaUqR eeGdeBqRpS ecUddO{VpZ dw_dcUaP`S ecUddOqGrW ebNdaX{WpY dvWd`_aHbV ebNdaXp[tO eaSc}I{WpZ du\c|O`[dP eaSc}IYuV eaJcwS{Vp[ duTcvXHeW eaJcwSIvI eaScqJ{WpZ du\cpPXfH eaScqJ`ZvA ebMckI{VpZ dvWcjOp[fA ebMckIaHuD ecUcfE{VpZ dw_ceKqHeD ecUcfEaRsR eeGcbS{WpZ dyPcaYqQcR eeGcbSaTqS ef[ca@{WpY d{Dc`GqTaR ef[ca@aQ`T ehLcaT{WpZ d|Uc`ZqQpS ehLcaTaHbV eiTcdJ{WpZ d}]ccPqHrV eiTcdJ`YdO ejMchY{VpY d~Wch@pZtP ejMchYJeW ejWcnP{WpZ d@cmVYuV ejWcnPZfI ejMctY{VpZ d~Wcs_IvI ejMctYpYfB eiTcz[{Wp[ d}]cz@`ZvA eiTcz[qHeC ehLc^{WpZ d|UcDaHuD ehLc^qQcR d{DdbVaQsR ef[csBQ@ efZcsB@Q efZcsAAQ ef[cs@@B ef[csBQ@ efZcsB@Q efZcsAAQ ef[cs@@B ef[csB@@ efZcsB@@ efZcsA@@ ef[cs@@@ egGc}FB@ ehGc{Dp^bB ehEc{Dp^bB ehEc{DB@ eiAcxEpZb_ eh_cxEpZb_ eh_cxEB@ eiQctOpPcV eiPctOpQcV eiPctOA@ eiXcpVWcY eiWcpVWcY eiWcpVA@ eiTcmGDcO eiRcmGEcO eiRcmGB@ eiFcjKNb\ eiDcjJNb] eiDcjJBA ehNchT`XaW ehLchT`XaV ehLchTB@ egPchD`^`P egOchD`]`P egOchDA@ efPch^a@pZ efOch^a@pZ efOch^A@ eeRck@`^rB eePck@`_rB eePck@B@ edXcn@`Zs@ edWcm_`Yr_ edWcm_AA edHcqV`PsV edFcqU`QsV edFcqUBA edAcuNGsX ec_cuNGsY ec_cuNB@ edEcx^TsP edCcx^TsP edCcx^B@ edSc{Z^r\ edRc{Z_r\ edRc{ZA@ eeKc}PpXqV eeJc}PpXqV eeJc}PA@ efIc~Ap^pQ efGc~Ap]pQ efGc~AB@ egIc}Fq@`[ egGc}Fq@`[ bvLcmQQ@ bvKcmQ@R bvKcmOA@ bvLcmO@B bvJcmQ@@ bvJcmQ@R bvJcmO@@ bvJcmO@B bvLcmQR@ bvKcmQQ@ bvKcmOQ@ bvLcmOR@ bwFc}_{WpZ bwFc}_qTaS buRcR{Wp[ bi[c~WaTqR buRcRqQpT btAc~^{WpZ bhJc~DaQ`S btAc~^qHrV brYc|H{WpZ bgBc{NaHbV brYc|HpZtP bq_cwX{WpZ bfHcv^`ZdP bq_cwXYuV bqVcrB{WpZ be_cqHIeV bqVcrBIvI bq_ckY{WpZ bfHcj_YfI bq_ckY`ZvA brYceX{WpZ bgBcd^pZfA brYceXaHuD btAc`T{WpZ bhJbZqHeD btAc`TaQsR buRb}B{WpZ bi[b|HqQcR buRb}BaTqR bwFb{P{WpZ bkObzVqTaR bwFb{PaQ`S bxWb|C{WpZ bm@b{IqQpS bxWb|CaHbV by_b~Y{WpZ bnHb}_qHrV by_b~Y`ZdP bzYccI{WpZ boBcbOpZtP bzYccIIeW b{Bci@{WpZ boKchFYuW b{Bci@YfH bzYcoH{WpZ boBcnNIvH bzYcoHpZfB by_cuJ{WpZ bnHctP`ZvB by_cuJqHeC bxWczM{WpZ bm@cySaHuC bxWczMqQcR bkOc}EaQsR bjKclW@@ bjKclW@R bjKclU@@ bjKclU@B bjKclW@@ bjKclW@R bjKclU@@ bjKclU@B bjKclW@@ bjKclW@@ bjKclU@@ bjKclU@@ bjXcvZA@ bkXctYp_bA bkVctYp^bA bkVctYB@ blQcqYpYc@ blOcqYpYc@ blOcqYB@ bmBcnCpQcV bm@cnCpQcV bm@cnCB@ bmIcjKWcX bmGcjJWcY bmGcjJBA bmEcf[DcP bmCcf[DcO bmCcf[B@ blVcc_Ob\ blTcc_Ob\ blTcc_B@ bk^cbI`XaV bk\cbH`XaW bk\cbHBA bkAcaX`]`Q bj_caX`]`P bj_caXB@ bjAcbSa@p[ bi_cbSa@p[ bi_cbSB@ biBcdU`_rB biAcdU`^rB biAcdUA@ bhIcgT`Yr_ bhGcgT`Zr_ bhGcgTB@ bgXckJ`QsV bgVckJ`QsV bgVckJB@ bgQcoCGsY bgOcoCGsY bgOcoCB@ bgVcrRUsO bgTcrRUsO bgTcrRB@ bhDcuN^r\ bhBcuN^r\ bhBcuNB@ bh\cwEpXqW bhZcwEpXqW bhZcwEB@ biYcwUp]pP biWcwUp]pP biWcwUB@ bjYcvZq@`[ bjXcvZqA`[ c|HdzT@A c|HdzU@R c|HdzS@@ c|HdzS@A c|GdzTQA c|FdzU@R c|FdzSAQ c|GdzR@B c|HdzTQ@ c|HdzUR@ c|HdzSR@ c|HdzSQQ c}BekC{WpZ c}BekCqTaR c{NelU{WpZ coWek[aTqR c{NelUqQpS cy]elB{WpZ cnFekHaQ`S cy]elBqHrW cxUeiK{WpZ cl^ehQaHbW cxUeiKpZtO cw[ed\{WpZ clDedB`ZdO cw[ed\YuW cwRdE{WpZ ck[d~KIeW cwRdEIvH cw[dx]{WpZ clDdxCYfH cw[dx]`ZvB cxUdr[{WpZ cl^drApZfB cxUdr[aHuD cy]dmW{WpY cnFdl^qHeC cy]dmWaQsQ c{NdjF{WpZ coWdiLqQcR c{NdjFaTqS c}BdhS{VpZ cqLdgYqUaS c}BdhSaQ`T c~SdiG{WpZ cr\dhMqPpT c~SdiGaHbV c[dk]{WpZ ctDdkCqHrV c[dk]`ZdO d`UdpL{VpZ ct_doRp[tO d`UdpLIeW d`^dvC{WpZ cuGduIXuW d`^dvCYfH d`Ud|K{VpZ ct_d{QHvH d`Ud|KpZfB c[ebM{WpZ ctDeaS`[vB c[ebMqHeD c~SegQ{WpZ cr\efWaHuD c~SegQqQcR cqKejIaQsR anRduH@@ anRduH@R anRduF@@ anRduF@B anPduH@@ anPduH@R anPduF@@ anPduF@B anRduHR@ anRduHR@ anRduFR@ anRduFR@ aoLeeV{WpZ aoLeeVqTaR amXegH{WpY abAefOaTqS amXegHqQpS alGefU{WpZ a`Pee[aQ`T alGefUqHrV aj_ec_{WpZ `HecEaHbV aj_ec_pZtP ajEdO{WpZ `~Nd~U`ZdP ajEdOYuV ai\dyY{WpZ `~Edx_IeV ai\dyYIvI ajEdsP{WpZ `~NdrVYfI ajEdsP`ZvA aj_dmO{WpZ `HdlUpZfA aj_dmOaHuD alGdhK{WpZ a`PdgQqHeD alGdhKaQsR amXddY{WpZ abAdc_qQcR amXddYaTqR aoLdcG{VpZ acVdbMqUaR aoLdcGaQ`S ap]dcZ{WpZ aeFdc@qPpS ap]dcZaHbW arEdfQ{WpZ afNdeWqHrW arEdfQ`ZdO ar_dk@{VpZ agIdjFp[tO ar_dk@IeW asHdpW{WpZ agQdo]XuW asHdpWYfH ar_dv_{VpZ agIdvEHvH ar_dv_pZfB arEd}A{WpZ afNd|G`[vB arEd}AqHeC ap]ebD{WpZ aeFeaJaHuC ap]ebDqQcR acUed\aQsR5#A chYewFqIbZ cgPez@qJa^ cfFe{^r_c^ ccGe\{[kO bwLfkKr_aX btMfmCqSW brZfl\`vZ`P ciTfmL`]`S cjQfm_b_qY cmPflFkZ{N cyJf`XbVsN c|@e}JaFqZ c}Fe{PaFrV c~LexZgLaJ deXezDqFbD ddRe|HqBaO dcPe}Wr@bP daPf`G}BkP ctNfkWqWaE crWfl\qDY a}NfjJ`\`S a~Jfj]b^qY baHfiDk\{N bmDe}VbUsO boYezGaFqY bp_exNaFrW brEeuWyMF bhXeu]p_bE bgYexBp_aN bfZeyPq\bQ bd^e|A{JkT ayTfgUqTaE ax@fhZq@Y aw@fhQfNaY ax@fhZfJbC ayTfgUgTaO bd^e|AhFaU bfZeyPh_`W bgYexBiFL brEeuW`vTaO bp_exN`vQaR boYezG`vMaW bmDe}V`vCbF baHfiD`vDbG a~Jfj]`vCbF a}NfjJ`uLbR btMfmC`vD`\ bwLfkK`vD`[ ccGe\`vC`\ cfFe{^`uZaL cgPez@`uVaP chYewF`uSaT c}Fe{PgL`X c|@e}JgPM cyJf`XhFpQ cmPflFf^_ cjQfm_hFqC ciTfmLg_pY deXezDptE`rO bhXeu]pqX`rT5#N cbTdsH}Zp^ btZdrJEU bt_drEmZ`_ cbYdsDUD cbTdsZ}Zp_ btZdr[ET bt_drWmZ`^ cbYdsUUE cbTdsH@`R btZdrJ@`Q bt_drE@`R cbYdsD@`Q5#B ef_c~Fr_^ ed@c}XJ`[ edJc~Sb^N egHcAYp[ ed@c}XxYw\ d{Gcu\nEbC eiLcw_rMfG egHcAbTuP ei\cyQpPqR edJc~SxRwE d{XcwNnDbC d{Gcu\`QaR emZdsN^qJ emLdrDuWcW egUdu[MaF ehBdwAeXsS ehBdwAqPrF efRdt[^qK efDdsPaQbK emLdrDpQwZ el[djJ`SaW emNdlALgM efDdsPpZwW eeJdkYgQqO efRdt[pUwK ee]dmPpSqW ee]dmPgQqO eeJdkYqOppG ec[c{RcEpS eg@cz_e[oK ee]dmPqYpqB edDc|NYp\ edDc|NcFpT egJc{ZfD`pG egJc{ZZp[ el\ei_iSsT evOefKpWrD euXedGyTcS elDegZ`XbE evOefKsKwK esDd@yDcM ej@ebMb\gR euXedGsJwG erNd}@`Vb@ elDegZrYwL eiKe`NiCsN ej@ebMpUq_ esDd@uO|F emUdrZvZW ef[drSSbZ efXduMcHm@ erNd}@uG{O emGdqQNaI eiKe`NsB|J efIdtDErV efNdqNfYC efXduM_qI ef[drS]qE ezYczVr^U ew[czQ`[pU exVcy\b^F e{TczBp[`T ew[czQy\vZ em_csWm^`Z e{]ctQqDfE e{TczBa[vV e}OcsLqRaE exVcy\yFwJ eoPcrRm_`Z em_csWaQqE exPdp[aIp_ eyYdo\vPaD esIdq@qE`\ erDdq\fLqA erDdq\pTrV eqPdoFaIq@ erYdnF`PbZ eyYdo\bNwN e|GdhNqVaI ezQdiWrAgD erYdnFbDwO et]dfWgJaW eqPdoFaWwG esGdg_aVqH esGdg_gJaX et]dfWc]\ exZcv[cB`W e{\cwRK`p\ esGdg_dXppP ew_cwO`[pT ew_cwOcB`X e{AcxGpP`qP e{AcxG`[pU em]ebMiXbJ ewUedWrCaT euRefKyXrJ ekZedAbCqT ewUedW`_xD exTd|SyHrF eoLdzMqOh@ euRefKaDxI evVd~Ba^qO ekZedAaTxE emNd{\iHbF eoLdzMq^aO exTd|SaE|W eyYdo\uSs\ etFdl@qMbF erYdnFsMlG evVd~BaZ}G exPdp[aIp_ emNd{\dB|V eqPdoFaPrJ es@dl\ePc_ erYdnFqIa@ etFdl@qF`\ eeSffHcDaV ejGfiMqPqO eiIfiSsDqV ejGfiMp^F ejGfiMqRa_ ehUfkLqYqX ef\fiTa[qV eeSffHsX`U ea[ff]eAbW ea[ff]aKqW ecFfeFbMaB ecFfeFpUC ebQfeIq\aZ e`UfgCaFV ehUfkLqDG egQfkSaXr@ egQfkSuArV ebPfh]cUq@ efEfg]rSqS ecRffJqBbS ebPfh]q[qZ ebQfeIaAaA ehUfkLq@dH egUfoTq_q_ eeVfmUaFtA eeVfmUv@sF dVfjObEsR dVfjOqEH d~QfjWaCrG dTfhP`TpV e`HfgZMpW dTfhPp^Y d~VfhGaR] egUfoTqHG efMfo[aDtH efMfo[v@sG e`MflTbCsW e`MflTq\q] d~QfjWaHqX dYfh_OqE d~VfhGaC`X egUfoTuWbJ ea^fq^NrM ebLfoQcJq\ ebLfoQsHsR dDfk_`RqP ea^fq^tItG d}UfmWaOqX d~QfjWp\c@ efMfo[sNaN eb_fqIqA`U dYfm^cFcK dYfm^`TqJ d}UfmWbDG d~VfhGUbP ef[fdDqHbD eeSffHpWJ ed\ffRaHrE efDfdM`WY eeSffHcDaV ehWfg^aHrE ei_feYsDqU ei_feYa]aW ek\fgPqMaP ejOfi@pPsG ejOfi@XM ejGfiMqPqO egMfeYqHbD efEfg]qIqK efDfdMaIaL egMfeYcDaV ejQfgOqHbD eiIfiSsDqV ejQfgOaKA ejOfi@BqQ ejGfiMp^F e`NefZrZbK d}TeiEMO d~AeiTbZrL e`[egH]^ d}TeiEsIsB dzKefCsIt[ dwBeaHbZrL dy\d~\dEdD d~Aec@bMcZ d~AeiTsLsF dzUefNsMt_ dwHeaObZrL dzBdCdIdH d~KecKbPc] d~KecKZ[ dzBdCVW dzUefNZ[ dwHeaOVW ehFesWpSaE egSet\[\ egHetPGqR egOer^`W`Y egSet\r^`] edUeuYcQrB egHetPsK`Q ec]euA`X`X egOer^sRbC ehFesWwR}J e`TefMsQbB d}CehOgRmJ ec]euAwG|_ d|VehBMM egOer^wG|^ e`Hef@sRbB e`Hef@LM eh_fdUXpW ehWfc^aRaR ejIfePE`Q ejNffAqOqL ejNffAc_qP enMfdQFq_ enSfbRuTbC enSfbRWpX enLfaZTbF enHfd@E`Q ejIfePbIA elRfeQrD`P elRfeQa[q@ enHfd@qVaQ ehWfc^UpR ehRfcLaWbD ehRfcLd@bE elRfeQaStH enEfaIuSbC enHfd@SrW enEfaIG`Q eh_fdUtUA edJeuT\qC ec^etQdTn[ edJeuTc[qN ehEetFfNnL ehEetF[qC egZesCfKnF ec^etQc\qN ec^etQbTqW efRerZG`R efYesLrObH ehEetFqLpZ efRerZaHI enLfcZqRaU elZfeOrIE ejQfeTqVqO eh[fdETrG ehWfa^eUa\ ehWfa^rEs@ efRe~^aWgL ehIffJNtL eh[fdEpRbE ejQfeTrH`V ehIffJcLaD ekUfgNqDqZ elZfeOqEa_ enLfcZrWcT ekUfgNaPY emEfgEaGsK enLfcZaKq\ eoWfa^rReG ehIffJqKqG ef^feC\vE emEfgEvGrB eoWfa^yEs@ dwCejQrSbR dtPemCaAaK duQenNbSrR dxDek\qAqK dtPemCr[qN dqUekUrZrY dn[eh\bSrR dqNefJcSb@ duAehJbBbG duQenNsBqW drOelWsDsF doKeiQbSrQ dq^eg@c]bL du[eiLbIbP du[eiLpZqB dq^eg@pPpV drOelWpZqB doKeiQpPpU d@epJIaX dIerB`]aF e`FesH`TpS e`ZerUqZrK dIerBsFaD d|CesFb]r\ e`FesHrIbJ d}]euRqZrL e`ZerUr]b] d@epJxLvM dvTei]r]b\ dsWelYhLfM d}]euRyGwQ dtVenAp_qH e`ZerUyGwP dwSekEr]b\ dwSekEp_qH egNeBH`W egVeYbC`Y eiYf`RVpP eiSf`BrEq@ eiSf`Bc@r_ elSe}Cp^rH ekUez[tGdG ekUez[H`X ek]e{S`\b@ elYe}SVpP eiYf`RbCp] ek\eUrIM ek\eU`WrR elYe}Sp]bB egVeYF`R eg\f`Ka]G eg\f`Kd@pV ek\eUGsP elCe|EtGdF elYe}SpVqN elCe|EVpR egNeBzT{H d|ZesZLaC d}Fet]jVkN d|ZesZb]r\ dWep^k^i] dWep^LaC e`CerAl@jD d}Fet]b]r\ d}Fet]aLsC d~ReqZVpR d~LeqHqRbR dWep^qKJ d~ReqZaQG elTe~TqRaU ekBf`IrIE ehYf`NqVqO egCe~_SrF eg@e|YeTa[ eg@e|Y^bE efRe~^aEeV egWfdTpWw[ egCe~_`TeU ehYf`NqBdF egWfdTcLaC ekCfeWrJuI ekBf`IAeN elTe~TqQgC ekCfeWbBaN emEfgEpQxQ elTe~TcCcJ eoWfa^rReG egWfdTpYO ef^feC\vE emEfgEvGrB eoWfa^yEs@ ejLesNqKaO eiAet]bZb\ ek[ewYgJbM esEezFIq[ esNexKqXrP eqVeu[wJrM eiAet]rVg@ efKe{]aOqT egZezIbRv[ egZezIgIbM eoCe|VbSv[ eoCe|Va\bW ep_eMbOwB ek[ewYrNgG eiMe@sBsC esEezFrOgG epVfaMwIrM ep_eMYb@ egZezIHb\ ehBe}EqSaX efOe~]Ts@ eoCe|VqLbK emWeAuUq\ ep_eMqHbR eoWfa_r@r^ eiMe@LcH eiYfbHsJsK epVfaMqIbV eoMfdCuTq[ eoWfa_ZbD ek_ekBaOqR emNeiPhNbY eu\elIa\bV ewXen_Za_ ewNep^xNrZ eo@enDsAsB emNeiPpYdE elUemUqGaJ ekNen_`Qs] eu\elIq\cY et@epBwKrM ewXen_rFcK euRerJqRrH ekNen_bQbR em_eqQaAsM em_eqQgKbN euJes_bDsA euJes_HqU ekNen_rSe] eh[et\aMqQ ejHesKbMuV ejHesKgRbO eqZeuZbFuX eqZeuZaYbS esSexMa_vC em_eqQrGfI ekXewZr]r^ ekXewZgRbP esJezJb@vK esJezJIq] exCel\q]rI evFejSy@F emFejYqSbL ekSemEcEbH enXeoMi@V ewXeoGKrK exCel\`Qw^ exTed^r@rM evTebQ^hB evTebQyUcH el_eeYiGdZ el_eeYGe@ el_eeYqWbQ ekHehJKd[ ewXeoG`Pw\ exHegKLrM exHegKyTcK enTejViDdQ enXeoMTtW enTejVsLrL exTed^rCuR evQdLqZq_ etWd}Ma]eD etWd}MvHbC enOdPhEcA el_eeYaPvI enOdPqZcF elUebVqMeT exHegKq_uJ evIebAHrU evIebAvGbF epBedGhFcD enTejVaNvO elUebVcMaQ evIebAqRtT enOdPaSdW5#C aoDcsZrO] alUcsMq]`W ajXctDbOM amGctQa]pW alUcsMw]wX adXckUkZa\ apRcmQqNfI amGctQTuV amCcn[cOqJ ajXctDyNwF aaJcl^kYa] adXckUsNaI arFdjDb\qC auBdiAtYb\ apIdk]rS`_ amVdl\dPrX amVdl\qNrO alHdjMb]qC aoEdiJaDbS auBdiAQw[ auAdaFsYaM aqHdbS`^gQ aoEdiJZwZ an[daPfFZ alHdjMqFwP akBdb]cYqM akBdb]fFZ an[daPrQppR alJcp^bST an]cpZfD`pL akBdb]pVpqI ajLcqTa^pV ajLcqTbTT am@cqPdH`qC am@cqPa]pV aDdvRaSyN b`WdmDdXqX beOdkLqSiN bc\dtZtXaX b`WdmDv[rI ay\dj[qQh^ axKdsYfYbY beOdkLwGrE a~HdiGtLaT bc\dtZwErT a|WdrFaQx_ axKdsYdLqS ay\dj[zCs_ aoYdf\r]d\ al\dkXaXa] anTdmUiWfD a~HdiG{RsM arVdeZr]aB a|WdrF{FuS aqQdlSrBqZ aoOdjYcGt_ anTdmUb]qB al\dkXbSp_ ajFctZrOpP agWctJa]pV aiTcsTbO`P alCctDq]`V agWctJxRwX `EclRkZbL aj_cn^pYe\ alCctDbJvO anMcmUsNaI aiTcsTwAxK abSckIkZbL `EclRcNqI awPdeAb\qB azLdc_rTeP awXdiOrS`_ auEdjNbKuM auEdjNrGqR ar^dh\b\qB auZdgZa^aU azLdc_sFwD awFc|[sYaM asMc~HdCfY auZdgZsLv_ arNd`[dXt@ ar^dh\tIvT anUdbHcYqM anUdbHdXt@ arNd`[yL~U aiBcrFb@qV akBcpPlDlK anUdbHwPK agEcr]a]pW agEcr]b@qV aiEcqGjHmA aiEcqGa]pW biHdrQbAyH bkIdiItXaX bfQdkArAiH bdPdtIdXqX bkIdiIvYrV bdPdfSq^hX bbRdoKfVcF bfQdkAvLr[ b`EdhFdKqS bdPdtIvIsJ a~Gdp_a^xY bbRdoKtKaT bdPdfS{UtA ax[dbRsPdX auKdgJbAa] awLdiGkFfD b`EdhFzGtQ au^dcUb]qC a~Gdp_yWvV atPdjIqXr@ arXdhIcFtT awLdiGr\aB auKdgJrS`_ a~^elZbYaX b`^eo^`YqL a~Aeo^rYqX b`^eo^r]@ b`^eo^q@a_ a^eq]`]qT b`[epI`\qW a~^elZrR`U a|LemOdObZ a|LemOXqZ a|DekUbZaE a|DekUr@Q azDekTqHaZ ax\emNcPA a^eq]sO@ a|Oeq]aRq_ a|Oeq]tOrZ ax@eoCcHp] a{HenFqSqT ayUelRqUbQ ax@eoC`\qU azDekT_`^ a^eq]WdI aWevF`_qZ b`VetLEtC b`VetLuJsL a{Leq@a@sQ a{Leq@sYB awSeqBaGrF axZen\WpW axSenEIpW axZen\qM\ awMenPaF[ aWevFs\@ a{[evF`TtI a{[evFuJsL avQerZaOsW avQerZaBqX awSeqBFqZ awYeoH`ZqC awMenPL`X aWevFtLbG a{KexMbLrH a}WevEb_qY a}WevEr[sT az\erQ`PqQ a{KexMtAtK awJetBcRqQ awSeqBYc@ a{[evFrAaN ayZewTaQ`Y avPetEcJcO avPetEAqK awJetBpZC awMenPFbR b`Aej[qBa\ a~_elWrTQ a|KelVaBq\ a}MejZbTA a~_elWbRbH baQen_aBq\ bbSemCrRrH bbSemCpQa[ bbBen^qEaH b`]epFaVsC b`]epFWL b`VepR`[qS a|KelGqBa\ a{IenCaBqM a}MejZqBaM a|KelGbRbH a~]enOqBa\ a}[epKrRrH a~]enOcEO b`]epFr@qW b`VepRr[W amSdsGqPa_ alCduFpXaT akKdvZaOq_ alZdt[`YqT alCduFtOqW agTdsOuJr] abJdpRaOq_ acYdnSeYbI aiRdp\dAbK akKdvZtIrB agBdtXuDsL aa^dqLaPq_ acNdoMeQbX ah_drEc[bV ah_drE`SqI acNdoMKpZ agBdtX`RqI aa^dqLLpZ ay@d|P`YK ayYd|[`UqO azNd{LTqY azJdySqJb] ayYd|[rNa\ awKd~WaUrG azNd{LqYO axUd{[qJb\ azJdySqUbH ay@d|P}BxM ak^dtCqUbG ajIdvJmBhM axUd{[}UwB ak@dtYpWaQ azJdyS}UwA alUdrRqUbG alUdrRpWaQ a|YekRrRX azGekJ`VaH az]elRaZF a|WelXBqF a|WelXaWrI a~NejO`XrE aFehJrMcH aFehJrRX a|TehB@bG a|TejIaZF az]elRa@] a{]elE`Z`S a{]elEbQqV a|TejIpWa\ azGekJq]W axJekCbSaO axJekCcSaB a{]elEqFtI azWeg\rMcG a|TejIq]rM azWeg\a]F a|YekRr\~C ay]d}OsZ] avCd}BbGnA ay]d}OaUrG a{Rd{HcTmB a{Rd{HsZ] awXdz[b_mA avCd}BaUrG avCd}Bb@rM axCdzUa_F azBdz[UbT a{Rd{HqP] axCdzU[F a}WekDqIaL a|NelPq\Y azRelGqLqY ayFejNRrG ayDehGdSb] ayDehGdVrZ a}ZeeMpYgO a}Ael\s]tU ayFejNc[bN azRelGbO`U a}Ael\bXaX aYenTuGrM a|NelPcKbD a}WekDbBcP aYenTcKG bcDen[uMsW a}WekDgRp_ beIejErEdV a}Ael\a@qH a~AekTWvG bcDen[uCsG beIejEwOtX aq^dvNbCpY atAduUHbK atIdx@rD`Y arEdxYWrK atAduUsOH apRdu]uJ`S akHdvPrC`Y aiEdwIdU[ amZdv^dDpP atIdx@sQY apXdwWuLR akLdwUrC`Y aiIdxNdWJ an@dxXdEA an@dxXVqZ aiIdxNTqE apXdwWVqZ akLdwUTqE a}LdvAaP`Z a~\dv[GbD aCdx_qIaF a}ZdzE^tD a~\dv[`\qW aXduDrL`] aCdx_aBJ b`EdyI]tE a}ZdzEbKp\ a}LdvA|Q`P ap[dvQbLp] asGduTlQpP b`EdyI|WqN asNdw[WrG a}ZdzE|WqN aqCdxWbKp\ aqCdxWXrF bjOecMqZaK bhUedX`Qa_ biFefWaJp^ bjPeeYQrL bjPeeYrN`] bhBefVqAr@ bgAedVcNqI bgAedVqZaK beGefAaQaS bfXegTaJp^ biFefWpYaG bhMeg^bCrE bhMeg^[qH bfXegTaUJ bhUedXqLaA bgIeeYa]`^ bgIeeYaDbE bhMeg^tRp\ bc[egBcNqI bfXegTr]pR bc[egBaLqA bjOecMyE}G baJdvFrWbA a~SdxGhVmR baJdvFrK`] a~_dwChBmS a~_dwCrXb@ a|GdyCgTm_ a~SdxGrL`\ a~SdxGqTpV a|_dwQaMqA a~LdvPb^Z a~_dwCpSpS a|_dwQpXaR biGef[qIaL bg^ehGq]Y bfAeg^qKqY bdVefERrG bdTec^dSb] bdTec^vZaO a}ZeeMb_fC b`YekPc[wR bdVefEs]eK bfAeg^uHcR b`YekPbYaX bcRemHbOuJ bg^ehGtLeA biGef[uUfM bcRemH^aS bcDen[fCx@ biGef[s^cJ beIejErEdV b`YekPrXD a~AekTWvG bcDen[uCsG beIejEwOtX bfPd{FvQ`W a_d{]sDb\ a|[d~Yf@cY bb[ebReTqI bhOeaId@rJ blOd~_u_sY a_d{]rJfN a}UebKgCpY bdXeaRaXvL bdXeaRe_cY bjWeeKaXvL bjWeeKtKbP bfLeg[bCvR a|[d~YrRfV azIeeOcLsD bb[ebRrSfV b`HeiHu_sY bfLeg[vDaM bdXeaR`Tb_ beLedQwT`[ a}XeeLSsA bjWeeKpXbC bi_egNtSr] bfLeg[qBbJ beJejEdUrW azIeeOUcH azDehWcTsK b`HeiHqQbM a~WekUtSr^ beJejEvSaP bbKdrTgApY biLdq[f^dH bpJdvCtIbO blAdxRvAaK bf@dy]v_tG aAduVcJsB biLdq[qSc^ bgYduYu[`U ba^dvNMsZ bpJdvCrPcL bmZdyOvAsV blAdxRqYb_ bjHd{QcRrB ba^dvNrYbR aEdy@TsJ aEdy@fAcV beFd|V`ZrY beFd|VeBqE ba^dvNrEeN aYd{\fYpX bfRd{DaGuK bfRd{DfFcY blXd~]aBuN blXd~]tDbL bhTeaIaTuX aEdy@rQeZ a|Td~ZcEr^ a|Td~ZfFcY bbZebSbLu] bbZebSeZqJ blKdvQdGrC bpRdtNwMqK biEdsCwDaR bbAdtUsFbH a~[dv]gMaK bfHdxHfCqW blKdvQNw\ blYdnUdLrE bqEdlPpSg^ bqEdlPwZaS biKdnCgGfK biKdnCVe@ biKdnCwRaU baYdoXHd] bfHdxHFwY bfNdpOfKqZ bfNdpOxAaU a~MdrDg[fD a~[dv]^tY a~MdrDcLrL blYdnUqWu] bkBdhXdJqX boLdg@aYeP boLdg@uBaB bjJdhBf[dN biKdnC`_vA bjJdhBwLbJ bb^djLqEeL bfNdpOqMuT beAdj[fArC beAdj[uFaC a[dk^fSdQ a~MdrDaNvF bb^djLsCaR beAdj[jKs[ bjJdhBzOc\0$0! \ No newline at end of file
diff --git a/PerlMagick/t/cgm/read.t b/PerlMagick/t/cgm/read.t
new file mode 100644
index 0000000..1d30dbe
--- /dev/null
+++ b/PerlMagick/t/cgm/read.t
@@ -0,0 +1,28 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading CGM files
+#
+# Written by Bob Friesenhahn
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+#
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/cgm' || die 'Cd failed';
+
+testReadCompare('CGM:input.cgm', '../reference/cgm/read.miff', q//, 0.0002, 0.5);
+
diff --git a/PerlMagick/t/composite.t b/PerlMagick/t/composite.t
new file mode 100644
index 0000000..3dfa587
--- /dev/null
+++ b/PerlMagick/t/composite.t
@@ -0,0 +1,261 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003, 2008 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test composition operators
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+#
+BEGIN { $| = 1; $test=1; print "1..20\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't' || die 'Cd failed';
+
+#
+# Add
+#
+# The result of composite image + image, with overflow wrapping around
+# (mod 256).
+#
+# Maxium error is ignored since operation depends on floating-point
+# sensitive threshold.
+#
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Add'/,
+ 'reference/composite/Add.miff',0.004,1.0);
+#
+# Atop
+#
+# The result is the same shape as image image, with composite image
+# obscuring image where the image shapes overlap. Note this differs
+# from over because the portion of composite image outside image's
+# shape does not appear in the result.
+#
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Atop'/,
+ 'reference/composite/Atop.miff',0.0025,0.005);
+
+#
+# Bumpmap
+#
+# The result image shaded by composite image.
+#
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Bumpmap'/,
+ 'reference/composite/Bumpmap.miff',0.0025,0.005);
+
+#
+# Clear
+#
+# The result is transparent where composite image obscures the image.
+#
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Clear'/,
+ 'reference/composite/Clear.miff',0.0025,0.005);
+
+#
+# Copy
+#
+# The resulting image is image replaced with composite image. The
+# matte information is ignored.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Copy'/,
+ 'reference/composite/Copy.miff',0.0025,0.005);
+
+#
+# CopyBlue
+#
+# The resulting image is the blue layer in image replaced with the
+# blue layer in composite image. The other layers are copied
+# untouched.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'CopyBlue'/,
+ 'reference/composite/CopyBlue.miff',0.0025,0.005);
+
+#
+# CopyGreen
+#
+# The resulting image is the green layer in image replaced with the
+# green layer in composite image. The other layers are copied
+# untouched.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'CopyGreen'/,
+ 'reference/composite/CopyGreen.miff',0.0025,0.005);
+
+#
+# CopyRed
+#
+# The resulting image is the red layer in image replaced with the red
+# layer in composite image. The other layers are copied untouched.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'CopyRed'/,
+ 'reference/composite/CopyRed.miff',0.0025,0.005);
+
+#
+# CopyOpacity
+#
+# The resulting image is the opacity layer in image replaced with the
+# opacity layer in composite image. The other layers are copied
+# untouched.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'CopyOpacity'/,
+ 'reference/composite/CopyOpacity.miff',0.0025,0.005);
+
+#
+# Difference
+#
+# The result of abs(composite image - image). This is useful for
+# comparing two very similar images.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Difference'/,
+ 'reference/composite/Difference.miff',0.0025,0.005);
+
+#
+# Dissolve
+#
+# The result is the same shape as image image, with composite image
+# obscuring image where the image shapes overlap. The composite image
+# opacity is modulated according to the opacity option. Note this
+# differs from over because the portion of composite image outside
+# image's shape does not appear in the result.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Dissolve', opacity => '25'/,
+ 'reference/composite/Dissolve.miff',0.003,0.007);
+
+#
+# In
+#
+# The result is composite image cut by the shape of image. None of
+# the image data of image will be in the result.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'In'/,
+ 'reference/composite/In.miff',0.0025,0.005);
+
+#
+# Minus
+#
+# The result of composite image - image, with underflow cropped to
+# zero. The matte channel is ignored (set to 255, full coverage).
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Minus'/,
+ 'reference/composite/Minus.miff',0.0025,0.005);
+
+#
+# Multiply
+#
+# The result of composite image * image. This is useful for the
+# creation of drop-shadows.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Multiply'/,
+ 'reference/composite/Multiply.miff',0.0025,0.005);
+
+#
+# Out
+#
+# The resulting image is composite image with the shape of image cut
+# out.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Out'/,
+ 'reference/composite/Out.miff',0.0025,0.005);
+
+#
+# Over
+#
+# The result will be the union of the two image shapes, with
+# opaque areas of composite image obscuring image in the
+# region of overlap.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Over'/,
+ 'reference/composite/Over.miff',0.0025,0.005);
+
+#
+# Plus
+#
+# The result is just the sum of the image data. Output values are
+# cropped to 255 (no overflow). This operation is independent of the
+# matte channels.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Plus'/,
+ 'reference/composite/Plus.miff',0.0025,0.005);
+
+#
+# Subtract
+#
+# The result of composite image - image, with underflow wrapping
+# around (mod 256). The add and subtract operators can be used to
+# perform reversible transformations.
+#
+# Maxium error is ignored since operation depends on floating-point
+# sensitive threshold.
+#
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Subtract'/,
+ 'reference/composite/Subtract.miff',0.006,1.0);
+
+#
+# Xor
+#
+# The result is the image data from both composite image and image
+# that is outside the overlap region. The overlap region will be
+# blank.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Xor'/,
+ 'reference/composite/Xor.miff',0.002,0.005);
+
+#
+# Divide
+#
+# The result of composite image / image.
+++$test;
+testCompositeCompare('gradient:white-black',q/size=>"100x80"/,
+ 'input_matte.miff', q//,
+ q/, gravity=>'Center', compose=>'Divide'/,
+ 'reference/composite/Divide.miff',0.0025,0.02);
+
+1;
diff --git a/PerlMagick/t/features.pl.in b/PerlMagick/t/features.pl.in
new file mode 100644
index 0000000..bb0ab4a
--- /dev/null
+++ b/PerlMagick/t/features.pl.in
@@ -0,0 +1,5 @@
+# Configuration-specific test suite definitions.
+#
+
+# Create a Perl list containing feature names
+@MAGICK_FEATURES=qw(@MAGICK_FEATURES@);
diff --git a/PerlMagick/t/filter.t b/PerlMagick/t/filter.t
new file mode 100644
index 0000000..acb1064
--- /dev/null
+++ b/PerlMagick/t/filter.t
@@ -0,0 +1,231 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 - 2008 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test image filters.
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1, print "1..49\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't' || die 'Cd failed';
+use FileHandle;
+autoflush STDOUT 1;
+autoflush STDERR 1;
+
+#$QuantumDepth=quantumDepth();
+$fuzz=int($MaxRGB*0.05);
+
+testFilterCompare('input.miff', q//, 'reference/filter/Blur.miff', 'Blur',
+ q/geometry=>"0.0x1.0"/, 0.003, 0.007);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Border.miff', 'Border',
+ q/geometry=>"10"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Channel.miff', 'Channel',
+ q/channel=>"Red"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Chop.miff', 'Chop',
+ q/geometry=>"10x10!"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', "fuzz=>$fuzz", 'reference/filter/ColorFloodfill.miff', 'ColorFloodfill',
+ q/geometry=>"+25+45"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', "fuzz=>$fuzz", 'reference/filter/Colorize.miff', 'Colorize',
+ q/fill=>"red", opacity=>50/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Contrast.miff', 'Contrast',
+ q/sharpen=>True/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//,
+ 'reference/filter/Convolve.miff', 'Convolve', q/coefficients=>[1, 2, 1, 2, 4, 2, 1, 2, 1]/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Crop.miff', 'Crop',
+ q/geometry=>"10x10!"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Despeckle.miff', 'Despeckle',
+ q//, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Edge.miff', 'Edge',
+ q/radius=>3/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Emboss.miff', 'Emboss',
+ q/geometry=>"2x1"/, 0.003, 0.15);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Equalize.miff', 'Equalize',
+ q//, 9e-06, 2e-05);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Flip.miff', 'Flip',
+ q//, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Flop.miff', 'Flop',
+ q//, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Frame.miff', 'Frame',
+ q/geometry=>"10x10+2+2"/, 0.0005, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Gamma.miff', 'Gamma',
+ q/gamma=>"2.2"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Implode.miff', 'Implode',
+ q/amount=>0.5/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Magnify.miff', 'Magnify',
+ q//, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/MatteFloodfill.miff', 'MatteFloodfill',
+ q/geometry=>"+25+45"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Minify.miff', 'Minify',
+ q//, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Modulate.miff', 'Modulate',
+ q/brightness=>60, saturation=>30, hue=>20/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/MotionBlur.miff', 'MotionBlur',
+ q/radius=>0,sigma=>7,angle=>30/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Negate.miff', 'Negate',
+ q/gray=>False/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Normalize.miff', 'Normalize',
+ q//, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/OilPaint.miff', 'OilPaint',
+ q/radius=>3/, 0.03, 0.7);
+
+++$test;
+testFilterCompare('input.miff', "fuzz=>$fuzz", 'reference/filter/Opaque.miff', 'Opaque',
+ q/color=>"#e23834", fill=>"green"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Quantize.miff', 'Quantize',
+ q/colors=>128/, 0.02, 0.16);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Raise.miff', 'Raise',
+ q/geometry=>"10x10"/, 0.003, 0.004);
+# Q:32 mean-error=0.000608108204635624, maximum-error=0.0117954632778599
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Resize.miff', 'Resize',
+ q/geometry=>"50%", filter=>"Box"/, 0.004, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Roll.miff', 'Roll',
+ q/geometry=>"+10+10"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Rotate10.miff', 'Rotate',
+ q/degrees=>10,color=>"green"/, 0.003, 0.007);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Rotate0.miff', 'Rotate',
+ q/degrees=>0/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Rotate90.miff', 'Rotate',
+ q/degrees=>90/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Rotate180.miff', 'Rotate',
+ q/degrees=>180/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Rotate270.miff', 'Rotate',
+ q/degrees=>270/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Sample.miff', 'Sample',
+ q/geometry=>"50%"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Scale.miff', 'Scale',
+ q/geometry=>"50%"/, 0.004, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Segment.miff', 'Segment',
+ q/geometry=>"1.0x1.5"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Shade.miff', 'Shade',
+ q/geometry=>"30x30",gray=>'true'/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Sharpen.miff', 'Sharpen',
+ q/geometry=>"0.0x1.0"/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Shave.miff', 'Shave',
+ q/geometry=>"10x10"/, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Shear.miff', 'Shear',
+ q/geometry=>10,color=>"yellow"/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Solarize.miff', 'Solarize',
+ 0.40*MaxRGB, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Swirl.miff', 'Swirl',
+ q/degrees=>60/, 0.003, 0.004);
+
+# Being just one pixel different spikes maximum error for the threshold
+# test, so check only mean error. This test is primarily influenced by
+# the pixel intensity macro.
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Threshold.miff', 'Threshold',
+ q/threshold=>"50%"/, 0.0013, 1);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Trim.miff', 'Trim',
+ q//, 0, 0);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/UnsharpMask.miff', 'UnsharpMask',
+ q/geometry=>"0.0x3.0+30+5"/, 0.003, 0.004);
+
+++$test;
+testFilterCompare('input.miff', q//, 'reference/filter/Wave.miff', 'Wave',
+ q/geometry=>"25x157"/, 0.003, 0.004);
+
+++$test;
+
+1;
diff --git a/PerlMagick/t/fpx/input_256.fpx b/PerlMagick/t/fpx/input_256.fpx
new file mode 100644
index 0000000..e2923be
--- /dev/null
+++ b/PerlMagick/t/fpx/input_256.fpx
Binary files differ
diff --git a/PerlMagick/t/fpx/input_bw.fpx b/PerlMagick/t/fpx/input_bw.fpx
new file mode 100644
index 0000000..c0ded84
--- /dev/null
+++ b/PerlMagick/t/fpx/input_bw.fpx
Binary files differ
diff --git a/PerlMagick/t/fpx/input_grayscale.fpx b/PerlMagick/t/fpx/input_grayscale.fpx
new file mode 100644
index 0000000..4a43e3b
--- /dev/null
+++ b/PerlMagick/t/fpx/input_grayscale.fpx
Binary files differ
diff --git a/PerlMagick/t/fpx/input_jpeg.fpx b/PerlMagick/t/fpx/input_jpeg.fpx
new file mode 100644
index 0000000..096eae8
--- /dev/null
+++ b/PerlMagick/t/fpx/input_jpeg.fpx
Binary files differ
diff --git a/PerlMagick/t/fpx/input_truecolor.fpx b/PerlMagick/t/fpx/input_truecolor.fpx
new file mode 100644
index 0000000..5fe6190
--- /dev/null
+++ b/PerlMagick/t/fpx/input_truecolor.fpx
Binary files differ
diff --git a/PerlMagick/t/fpx/read.t b/PerlMagick/t/fpx/read.t
new file mode 100644
index 0000000..eac1624
--- /dev/null
+++ b/PerlMagick/t/fpx/read.t
@@ -0,0 +1,63 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading FPX images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..5\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/fpx' || die 'Cd failed';
+
+#
+# 1) Test Black-and-white, bit_depth=1 FPX
+#
+print( "1-bit grayscale FPX ...\n" );
+testRead( 'input_bw.fpx',
+ '7267c8145131668953243274f49ea42706fd8227479f2daf8567515a4f7e9ee2' );
+
+#
+# 2) Test grayscale FPX
+#
+++$test;
+print( "8-bit grayscale FPX ...\n" );
+testRead( 'input_grayscale.fpx',
+ '7194ec7209e3cf8bd5eaa10f03a59f7de2bfbc58c027a33fd9e9293b9819669c' );
+
+#
+# 3) Test 256 color pseudocolor FPX
+#
+++$test;
+print( "8-bit indexed-color FPX ...\n" );
+testRead( 'input_256.fpx',
+ '3afebff726f7e0b3479ba548cf587b288d370f377c493c32d3b8e73d5545acd8' );
+
+#
+# 4) Test TrueColor FPX
+#
+++$test;
+print( "24-bit Truecolor FPX ...\n" );
+testRead( 'input_truecolor.fpx',
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+#
+# 5) Test JPEG FPX
+#
+++$test;
+print( "24-bit JPEG FPX ...\n" );
+testRead( 'input_jpeg.fpx',
+ '45a41e0ef7ad4b2ab890978457f1c51919139d6036bbf27f3e0adfb7732c0b48' );
+
diff --git a/PerlMagick/t/fpx/write.t b/PerlMagick/t/fpx/write.t
new file mode 100644
index 0000000..1a0e44e
--- /dev/null
+++ b/PerlMagick/t/fpx/write.t
@@ -0,0 +1,57 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing FPX images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..4\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/fpx' || die 'Cd failed';
+
+#
+# 1) Test Black-and-white, bit_depth=1 FPX
+#
+print( "1-bit grayscale FPX ...\n" );
+testReadWrite( 'input_bw.fpx', 'output_bw.fpx', q/quality=>95/,
+ '7267c8145131668953243274f49ea42706fd8227479f2daf8567515a4f7e9ee2');
+
+#
+# 2) Test grayscale image
+#
+++$test;
+print( "8-bit grayscale FPX ...\n" );
+testReadWrite( 'input_grayscale.fpx',
+ 'output_grayscale.fpx', '',
+ '7194ec7209e3cf8bd5eaa10f03a59f7de2bfbc58c027a33fd9e9293b9819669c');
+#
+# 3) Test pseudocolor image
+#
+++$test;
+print( "8-bit indexed-color FPX ...\n" );
+testReadWrite( 'input_256.fpx',
+ 'output_256.fpx',
+ q/quality=>54/,
+ '3afebff726f7e0b3479ba548cf587b288d370f377c493c32d3b8e73d5545acd8' );
+#
+# 4) Test truecolor image
+#
+++$test;
+print( "24-bit Truecolor FPX ...\n" );
+testReadWrite( 'input_truecolor.fpx',
+ 'output_truecolor.fpx',
+ q/quality=>55/,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
diff --git a/PerlMagick/t/getattribute.t b/PerlMagick/t/getattribute.t
new file mode 100644
index 0000000..2d29ba9
--- /dev/null
+++ b/PerlMagick/t/getattribute.t
@@ -0,0 +1,100 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test getting attributes.
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1, print "1..25\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't' || die 'Cd failed';
+
+testGetAttribute('input.miff','base-columns','70');
+
+++$test;
+testGetAttribute('input.miff','base-filename','input.miff');
+
+++$test;
+testGetAttribute('input.miff','base-rows','46');
+
+++$test;
+testGetAttribute('input.miff','class','DirectClass');
+
+++$test;
+testGetAttribute('input.miff','colors','3019');
+
+++$test;
+testGetAttribute('input.miff','columns','70');
+
+++$test;
+testGetAttribute('input.miff','directory',undef);
+
+++$test;
+testGetAttribute('input.miff','gamma','0');
+
+++$test;
+testGetAttribute('input.miff','geometry',undef);
+
+++$test;
+testGetAttribute('input.miff','height','46');
+
+++$test;
+# Returns undef
+testGetAttribute('input.miff','label',undef);
+
+++$test;
+testGetAttribute('input.miff','matte','0');
+
+++$test;
+testGetAttribute('input.miff','error','0');
+
+++$test;
+testGetAttribute('input.miff','montage',undef);
+
+++$test;
+testGetAttribute('input.miff','maximum-error','0');
+
+++$test;
+testGetAttribute('input.miff','mean-error','0');
+
+++$test;
+testGetAttribute('input.miff','rows','46');
+
+++$test;
+testGetAttribute('input.miff','signature',
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+++$test;
+testGetAttribute('input.miff','texture',undef);
+
+++$test;
+testGetAttribute('input.miff','type','TrueColor');
+
+++$test;
+testGetAttribute('input.miff','units','undefined units');
+
+++$test;
+testGetAttribute('input.miff','view',undef);
+
+++$test;
+testGetAttribute('input.miff','width','70');
+
+++$test;
+testGetAttribute('input.miff','x-resolution','0');
+
+++$test;
+testGetAttribute('input.miff','y-resolution','0');
+
+1;
diff --git a/PerlMagick/t/hdf/input_256.hdf b/PerlMagick/t/hdf/input_256.hdf
new file mode 100644
index 0000000..6b1a785
--- /dev/null
+++ b/PerlMagick/t/hdf/input_256.hdf
Binary files differ
diff --git a/PerlMagick/t/hdf/input_truecolor.hdf b/PerlMagick/t/hdf/input_truecolor.hdf
new file mode 100644
index 0000000..183e90f
--- /dev/null
+++ b/PerlMagick/t/hdf/input_truecolor.hdf
Binary files differ
diff --git a/PerlMagick/t/hdf/read.t b/PerlMagick/t/hdf/read.t
new file mode 100644
index 0000000..85dfc87
--- /dev/null
+++ b/PerlMagick/t/hdf/read.t
@@ -0,0 +1,36 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading HDF images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..2\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/hdf' || die 'Cd failed';
+
+#
+# 1) Test 256 color pseudocolor HDF
+#
+testRead( 'input_256.hdf',
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+#
+# 2) Test TrueColor HDF
+#
+++$test;
+testRead( 'input_truecolor.hdf',
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
diff --git a/PerlMagick/t/hdf/write.t b/PerlMagick/t/hdf/write.t
new file mode 100644
index 0000000..7642430
--- /dev/null
+++ b/PerlMagick/t/hdf/write.t
@@ -0,0 +1,40 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing HDF images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..2\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/hdf' || die 'Cd failed';
+
+#
+# 1) Test pseudocolor image
+#
+testReadWrite( 'input_256.hdf',
+ 'output_256.hdf',
+ q/quality=>54/,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+#
+# 2) Test truecolor image
+#
+++$test;
+testReadWrite( 'input_truecolor.hdf',
+ 'output_truecolor.hdf',
+ q/quality=>55/,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
diff --git a/PerlMagick/t/hpgl/input.hpgl b/PerlMagick/t/hpgl/input.hpgl
new file mode 100644
index 0000000..40ea84f
--- /dev/null
+++ b/PerlMagick/t/hpgl/input.hpgl
@@ -0,0 +1 @@
+IN;SP1;CA7;PU3598,4271;PD673,4271,673,7197,;PU3598,4259;PD660,4259,660,7197,;PU609,3975;PD609,3980,613,3988,618,3993,626,3997,643,3997,652,3993,656,3988,660,3980,660,3971,656,3962,648,3950,609,3907,;PU609,3975;PD613,3975,613,3980,618,3988,626,3993,643,3993,652,3988,656,3980,656,3971,652,3962,643,3950,605,3907,;PU609,3911;PD665,3911,665,3907,;PU605,3907;PD665,3907,;PU716,3997;PD703,3993,695,3980,691,3958,691,3945,695,3924,703,3911,716,3907,725,3907,738,3911,746,3924,751,3945,751,3958,746,3980,738,3993,725,3997,716,3997,;PU708,3993;PD699,3980,695,3958,695,3945,699,3924,708,3911,;PU703,3915;PD716,3911,725,3911,738,3915,;PU734,3911;PD742,3924,746,3945,746,3958,742,3980,734,3993,;PU738,3988;PD725,3993,716,3993,703,3988,;PU785,3920;PD781,3915,781,3911,785,3907,789,3907,794,3911,794,3915,789,3920,785,3920,;PU785,3915;PD785,3911,789,3911,789,3915,785,3915,;PU648,4259;PD648,4149,;PU660,4259;PD660,4149,;PU1627,3984;PD1627,3907,1631,3907,;PU1631,3997;PD1631,3907,;PU1631,3997;PD1584,3928,1648,3928,;PU1627,3984;PD1588,3928,;PU1588,3932;PD1648,3932,1648,3928,;PU1696,3997;PD1683,3993,1674,3980,1670,3958,1670,3945,1674,3924,1683,3911,1696,3907,1704,3907,1717,3911,1726,3924,1730,3945,1730,3958,1726,3980,1717,3993,1704,3997,1696,3997,;PU1687,3993;PD1678,3980,1674,3958,1674,3945,1678,3924,1687,3911,;PU1683,3915;PD1696,3911,1704,3911,1717,3915,;PU1713,3911;PD1721,3924,1726,3945,1726,3958,1721,3980,1713,3993,;PU1717,3988;PD1704,3993,1696,3993,1683,3988,;PU1764,3920;PD1760,3915,1760,3911,1764,3907,1769,3907,1773,3911,1773,3915,1769,3920,1764,3920,;PU1764,3915;PD1764,3911,1769,3911,1769,3915,1764,3915,;PU1628,4259;PD1628,4149,;PU1640,4259;PD1640,4149,;PU2610,3993;PD2615,3984,2619,3984,2615,3993,2602,3997,2593,3997,2580,3993,2572,3980,2567,3958,2567,3937,2572,3920,2580,3911,2593,3907,2597,3907,2610,3911,2619,3920,2623,3932,2623,3937,2619,3950,2610,3958,2597,3962,2593,3962,2580,3958,2572,3950,;PU2615,3988;PD2602,3993,2593,3993,2580,3988,;PU2585,3993;PD2576,3980,2572,3958,2572,3937,2576,3920,2589,3911,;PU2572,3928;PD2580,3915,2593,3911,2597,3911,2610,3915,2619,3928,;PU2602,3911;PD2615,3920,2619,3932,2619,3937,2615,3950,2602,3958,;PU2619,3941;PD2610,3954,2597,3958,2593,3958,2580,3954,2572,3941,;PU2589,3958;PD2576,3950,2572,3937,;PU2675,3997;PD2662,3993,2653,3980,2649,3958,2649,3945,2653,3924,2662,3911,2675,3907,2683,3907,2696,3911,2705,3924,2709,3945,2709,3958,2705,3980,2696,3993,2683,3997,2675,3997,;PU2666,3993;PD2658,3980,2653,3958,2653,3945,2658,3924,2666,3911,;PU2662,3915;PD2675,3911,2683,3911,2696,3915,;PU2692,3911;PD2701,3924,2705,3945,2705,3958,2701,3980,2692,3993,;PU2696,3988;PD2683,3993,2675,3993,2662,3988,;PU2744,3920;PD2739,3915,2739,3911,2744,3907,2748,3907,2752,3911,2752,3915,2748,3920,2744,3920,;PU2744,3915;PD2744,3911,2748,3911,2748,3915,2744,3915,;PU2607,4259;PD2607,4149,;PU2619,4259;PD2619,4149,;PU3564,3997;PD3551,3993,3547,3984,3547,3975,3551,3967,3555,3962,3564,3958,3581,3954,3590,3950,3594,3945,3598,3937,3598,3924,3594,3915,3581,3911,3564,3911,3551,3915,3547,3924,3547,3937,3551,3945,3555,3950,3564,3954,3581,3958,3590,3962,3594,3967,3598,3975,3598,3984,3594,3993,3581,3997,3564,3997,;PU3555,3993;PD3551,3984,3551,3975,3555,3967,3564,3962,3581,3958,3590,3954,3598,3945,3602,3937,3602,3924,3598,3915,3594,3911,3581,3907,3564,3907,3551,3911,3547,3915,3542,3924,3542,3937,3547,3945,3555,3954,3564,3958,3581,3962,3590,3967,3594,3975,3594,3984,3590,3993,;PU3594,3988;PD3581,3993,3564,3993,3551,3988,;PU3547,3920;PD3560,3911,;PU3585,3911;PD3598,3920,;PU3654,3997;PD3641,3993,3633,3980,3628,3958,3628,3945,3633,3924,3641,3911,3654,3907,3663,3907,3676,3911,3684,3924,3688,3945,3688,3958,3684,3980,3676,3993,3663,3997,3654,3997,;PU3645,3993;PD3637,3980,3633,3958,3633,3945,3637,3924,3645,3911,;PU3641,3915;PD3654,3911,3663,3911,3676,3915,;PU3671,3911;PD3680,3924,3684,3945,3684,3958,3680,3980,3671,3993,;PU3676,3988;PD3663,3993,3654,3993,3641,3988,;PU3723,3920;PD3718,3915,3718,3911,3723,3907,3727,3907,3731,3911,3731,3915,3727,3920,3723,3920,;PU3723,3915;PD3723,3911,3727,3911,3727,3915,3723,3915,;PU3586,4259;PD3586,4149,;PU3598,4259;PD3598,4149,;PU273,4294;PD261,4290,252,4277,248,4256,248,4243,252,4221,261,4208,273,4204,282,4204,295,4208,304,4221,308,4243,308,4256,304,4277,295,4290,282,4294,273,4294,;PU265,4290;PD256,4277,252,4256,252,4243,256,4221,265,4208,;PU261,4213;PD273,4208,282,4208,295,4213,;PU291,4208;PD299,4221,304,4243,304,4256,299,4277,291,4290,;PU295,4286;PD282,4290,273,4290,261,4286,;PU342,4217;PD338,4213,338,4208,342,4204,347,4204,351,4208,351,4213,347,4217,342,4217,;PU342,4213;PD342,4208,347,4208,347,4213,342,4213,;PU407,4294;PD394,4290,385,4277,381,4256,381,4243,385,4221,394,4208,407,4204,415,4204,428,4208,437,4221,441,4243,441,4256,437,4277,428,4290,415,4294,407,4294,;PU398,4290;PD389,4277,385,4256,385,4243,389,4221,398,4208,;PU394,4213;PD407,4208,415,4208,428,4213,;PU424,4208;PD432,4221,437,4243,437,4256,432,4277,424,4290,;PU428,4286;PD415,4290,407,4290,394,4286,;PU660,4271;PD550,4271,;PU660,4259;PD550,4259,;PU252,4860;PD252,4865,256,4873,261,4878,269,4882,286,4882,295,4878,299,4873,304,4865,304,4856,299,4848,291,4835,252,4792,;PU252,4860;PD256,4860,256,4865,261,4873,269,4878,286,4878,295,4873,299,4865,299,4856,295,4848,286,4835,248,4792,;PU252,4796;PD308,4796,308,4792,;PU248,4792;PD308,4792,;PU342,4805;PD338,4800,338,4796,342,4792,347,4792,351,4796,351,4800,347,4805,342,4805,;PU342,4800;PD342,4796,347,4796,347,4800,342,4800,;PU407,4882;PD394,4878,385,4865,381,4843,381,4830,385,4809,394,4796,407,4792,415,4792,428,4796,437,4809,441,4830,441,4843,437,4865,428,4878,415,4882,407,4882,;PU398,4878;PD389,4865,385,4843,385,4830,389,4809,398,4796,;PU394,4800;PD407,4796,415,4796,428,4800,;PU424,4796;PD432,4809,437,4830,437,4843,432,4865,424,4878,;PU428,4873;PD415,4878,407,4878,394,4873,;PU660,4859;PD550,4859,;PU660,4847;PD550,4847,;PU291,5457;PD291,5379,295,5379,;PU295,5469;PD295,5379,;PU295,5469;PD248,5401,312,5401,;PU291,5457;PD252,5401,;PU252,5405;PD312,5405,312,5401,;PU342,5392;PD338,5388,338,5384,342,5379,347,5379,351,5384,351,5388,347,5392,342,5392,;PU342,5388;PD342,5384,347,5384,347,5388,342,5388,;PU407,5469;PD394,5465,385,5452,381,5431,381,5418,385,5396,394,5384,407,5379,415,5379,428,5384,437,5396,441,5418,441,5431,437,5452,428,5465,415,5469,407,5469,;PU398,5465;PD389,5452,385,5431,385,5418,389,5396,398,5384,;PU394,5388;PD407,5384,415,5384,428,5388,;PU424,5384;PD432,5396,437,5418,437,5431,432,5452,424,5465,;PU428,5461;PD415,5465,407,5465,394,5461,;PU660,5446;PD550,5446,;PU660,5434;PD550,5434,;PU295,6053;PD299,6044,304,6044,299,6053,286,6057,278,6057,265,6053,256,6040,252,6018,252,5997,256,5980,265,5971,278,5967,282,5967,295,5971,304,5980,308,5993,308,5997,304,6010,295,6018,282,6023,278,6023,265,6018,256,6010,;PU299,6048;PD286,6053,278,6053,265,6048,;PU269,6053;PD261,6040,256,6018,256,5997,261,5980,273,5971,;PU256,5988;PD265,5975,278,5971,282,5971,295,5975,304,5988,;PU286,5971;PD299,5980,304,5993,304,5997,299,6010,286,6018,;PU304,6001;PD295,6014,282,6018,278,6018,265,6014,256,6001,;PU273,6018;PD261,6010,256,5997,;PU342,5980;PD338,5975,338,5971,342,5967,347,5967,351,5971,351,5975,347,5980,342,5980,;PU342,5975;PD342,5971,347,5971,347,5975,342,5975,;PU407,6057;PD394,6053,385,6040,381,6018,381,6005,385,5984,394,5971,407,5967,415,5967,428,5971,437,5984,441,6005,441,6018,437,6040,428,6053,415,6057,407,6057,;PU398,6053;PD389,6040,385,6018,385,6005,389,5984,398,5971,;PU394,5975;PD407,5971,415,5971,428,5975,;PU424,5971;PD432,5984,437,6005,437,6018,432,6040,424,6053,;PU428,6048;PD415,6053,407,6053,394,6048,;PU660,6034;PD550,6034,;PU660,6022;PD550,6022,;PU269,6645;PD256,6640,252,6632,252,6623,256,6614,261,6610,269,6606,286,6602,295,6597,299,6593,304,6584,304,6571,299,6563,286,6559,269,6559,256,6563,252,6571,252,6584,256,6593,261,6597,269,6602,286,6606,295,6610,299,6614,304,6623,304,6632,299,6640,286,6645,269,6645,;PU261,6640;PD256,6632,256,6623,261,6614,269,6610,286,6606,295,6602,304,6593,308,6584,308,6571,304,6563,299,6559,286,6554,269,6554,256,6559,252,6563,248,6571,248,6584,252,6593,261,6602,269,6606,286,6610,295,6614,299,6623,299,6632,295,6640,;PU299,6636;PD286,6640,269,6640,256,6636,;PU252,6567;PD265,6559,;PU291,6559;PD304,6567,;PU342,6567;PD338,6563,338,6559,342,6554,347,6554,351,6559,351,6563,347,6567,342,6567,;PU342,6563;PD342,6559,347,6559,347,6563,342,6563,;PU407,6645;PD394,6640,385,6627,381,6606,381,6593,385,6571,394,6559,407,6554,415,6554,428,6559,437,6571,441,6593,441,6606,437,6627,428,6640,415,6645,407,6645,;PU398,6640;PD389,6627,385,6606,385,6593,389,6571,398,6559,;PU394,6563;PD407,6559,415,6559,428,6563,;PU424,6559;PD432,6571,437,6593,437,6606,432,6627,424,6640,;PU428,6636;PD415,6640,407,6640,394,6636,;PU660,6621;PD550,6621,;PU660,6609;PD550,6609,;PU226,7215;PD235,7219,248,7232,248,7142,;PU226,7215;PD226,7211,235,7215,243,7223,243,7142,248,7142,;PU325,7232;PD312,7228,304,7215,299,7193,299,7181,304,7159,312,7146,325,7142,334,7142,347,7146,355,7159,359,7181,359,7193,355,7215,347,7228,334,7232,325,7232,;PU316,7228;PD308,7215,304,7193,304,7181,308,7159,316,7146,;PU312,7150;PD325,7146,334,7146,347,7150,;PU342,7146;PD351,7159,355,7181,355,7193,351,7215,342,7228,;PU347,7223;PD334,7228,325,7228,312,7223,;PU394,7155;PD389,7150,389,7146,394,7142,398,7142,402,7146,402,7150,398,7155,394,7155,;PU394,7150;PD394,7146,398,7146,398,7150,394,7150,;PU458,7232;PD445,7228,437,7215,432,7193,432,7181,437,7159,445,7146,458,7142,467,7142,480,7146,488,7159,493,7181,493,7193,488,7215,480,7228,467,7232,458,7232,;PU450,7228;PD441,7215,437,7193,437,7181,441,7159,450,7146,;PU445,7150;PD458,7146,467,7146,480,7150,;PU475,7146;PD484,7159,488,7181,488,7193,484,7215,475,7228,;PU480,7223;PD467,7228,458,7228,445,7223,;PU660,7209;PD550,7209,;PU660,7197;PD550,7197,;PU;SP2;PU660,4318;PD685,4321,709,4324,734,4328,758,4331,783,4335,807,4338,832,4342,856,4346,881,4350,905,4354,930,4358,954,4362,979,4366,1003,4371,1028,4375,1052,4380,1077,4385,1101,4390,1126,4395,1150,4401,1175,4406,1199,4412,1224,4418,1248,4424,1273,4430,1297,4436,1321,4443,1346,4450,1370,4457,1395,4464,1419,4472,1444,4480,1468,4488,1493,4496,1517,4505,1542,4514,1566,4523,1591,4533,1615,4543,1640,4553,1664,4563,1689,4574,1713,4586,1738,4597,1762,4609,1787,4621,1811,4634,1836,4647,1860,4660,1885,4674,1909,4688,1933,4702,1958,4717,1982,4732,2007,4747,2031,4763,2056,4779,2080,4796,2105,4812,2129,4829,2154,4847,2178,4864,2203,4882,2227,4900,2252,4918,2276,4936,2301,4955,2325,4973,2350,4992,2374,5011,2399,5030,2423,5049,2448,5068,2472,5087,2497,5106,2521,5125,2546,5144,2570,5163,2594,5182,2619,5201,2643,5220,2668,5239,2692,5258,2717,5277,2741,5296,2766,5315,2790,5334,2815,5353,2839,5372,2864,5392,2888,5411,2913,5431,2937,5451,2962,5472,2986,5494,3011,5515,3035,5538,3060,5562,3084,5586,3109,5612,3133,5639,3158,5668,3182,5698,3206,5730,3231,5764,3255,5799,3280,5838,3304,5878,3329,5921,3353,5966,3378,6013,3402,6063,3427,6116,3451,6170,3476,6226,3500,6284,3525,6344,3549,6404,3574,6465,3598,6526,;PU;SP3;PU660,4310;PD685,4314,709,4318,734,4321,758,4325,783,4329,807,4333,832,4337,856,4340,881,4344,905,4348,930,4351,954,4355,979,4358,1003,4362,1028,4365,1052,4369,1077,4372,1101,4376,1126,4379,1150,4383,1175,4386,1199,4390,1224,4394,1248,4397,1273,4401,1297,4404,1321,4408,1346,4412,1370,4415,1395,4419,1419,4423,1444,4427,1468,4431,1493,4434,1517,4439,1542,4443,1566,4447,1591,4451,1615,4455,1640,4460,1664,4465,1689,4469,1713,4474,1738,4479,1762,4484,1787,4489,1811,4495,1836,4500,1860,4506,1885,4512,1909,4518,1933,4524,1958,4530,1982,4537,2007,4544,2031,4551,2056,4558,2080,4565,2105,4572,2129,4580,2154,4588,2178,4596,2203,4604,2227,4613,2252,4621,2276,4630,2301,4639,2325,4648,2350,4657,2374,4667,2399,4676,2423,4686,2448,4696,2472,4706,2497,4716,2521,4727,2546,4737,2570,4748,2594,4758,2619,4769,2643,4780,2668,4791,2692,4803,2717,4814,2741,4826,2766,4838,2790,4850,2815,4863,2839,4876,2864,4889,2888,4903,2913,4917,2937,4932,2962,4947,2986,4963,3011,4980,3035,4997,3060,5016,3084,5036,3109,5057,3133,5079,3158,5103,3182,5128,3206,5156,3231,5185,3255,5216,3280,5249,3304,5284,3329,5322,3353,5362,3378,5404,3402,5448,3427,5494,3451,5543,3476,5592,3500,5644,3525,5696,3549,5749,3574,5803,3598,5857,;PU;SP2;PU4479,4259;PD4504,4325,4528,4326,4553,4327,4577,4329,4602,4331,4626,4332,4651,4334,4675,4336,4700,4338,4724,4340,4749,4342,4773,4345,4798,4347,4822,4350,4847,4352,4871,4355,4896,4358,4920,4361,4945,4364,4969,4368,4994,4371,5018,4375,5043,4378,5067,4382,5092,4386,5116,4390,5140,4395,5165,4399,5189,4404,5214,4409,5238,4414,5263,4419,5287,4424,5312,4430,5336,4436,5361,4441,5385,4447,5410,4454,5434,4460,5459,4466,5483,4473,5508,4480,5532,4486,5557,4493,5581,4500,5606,4508,5630,4515,5655,4522,5679,4529,5704,4536,5728,4543,5752,4550,5777,4557,5801,4564,5826,4571,5850,4577,5875,4584,5899,4590,5924,4596,5948,4601,5973,4607,5997,4612,6022,4616,6046,4620,6071,4624,6095,4628,6120,4631,6144,4633,6169,4636,6193,4637,6218,4639,6242,4640,6267,4641,6291,4641,6316,4641,6340,4641,6365,4641,6389,4640,6413,4639,6438,4639,6462,4638,6487,4637,6511,4637,6536,4637,6560,4637,6585,4638,6609,4640,6634,4642,6658,4645,6683,4649,6707,4655,6732,4661,6756,4670,6781,4680,6805,4692,6830,4706,6854,4722,6879,4741,6903,4763,6928,4787,6952,4815,6977,4846,7001,4880,7025,4916,7050,4956,7074,4999,7099,5044,7123,5091,7148,5139,7172,5187,7197,5235,7221,5282,7246,5326,7270,5366,7295,5402,7319,5432,7344,5456,7368,5473,7393,5482,7417,4259,;PU;SP3;PU4479,4259;PD4504,4337,4528,4336,4553,4336,4577,4335,4602,4334,4626,4334,4651,4333,4675,4333,4700,4332,4724,4332,4749,4331,4773,4331,4798,4330,4822,4330,4847,4330,4871,4330,4896,4330,4920,4329,4945,4329,4969,4329,4994,4330,5018,4330,5043,4330,5067,4330,5092,4331,5116,4331,5140,4332,5165,4333,5189,4333,5214,4334,5238,4335,5263,4337,5287,4338,5312,4339,5336,4341,5361,4342,5385,4344,5410,4346,5434,4348,5459,4350,5483,4352,5508,4354,5532,4357,5557,4360,5581,4362,5606,4365,5630,4368,5655,4371,5679,4375,5704,4378,5728,4381,5752,4385,5777,4388,5801,4392,5826,4396,5850,4399,5875,4403,5899,4407,5924,4411,5948,4414,5973,4418,5997,4422,6022,4426,6046,4429,6071,4433,6095,4436,6120,4440,6144,4443,6169,4446,6193,4449,6218,4452,6242,4455,6267,4458,6291,4461,6316,4464,6340,4467,6365,4470,6389,4472,6413,4475,6438,4478,6462,4482,6487,4485,6511,4488,6536,4492,6560,4497,6585,4502,6609,4507,6634,4513,6658,4520,6683,4528,6707,4537,6732,4548,6756,4559,6781,4572,6805,4587,6830,4604,6854,4623,6879,4644,6903,4667,6928,4693,6952,4721,6977,4752,7001,4786,7025,4822,7050,4861,7074,4902,7099,4944,7123,4989,7148,5033,7172,5078,7197,5122,7221,5164,7246,5204,7270,5239,7295,5270,7319,5295,7344,5315,7368,5327,7393,5333,7417,4259,;PU;SP1;LT4,2.5;PU4479,7197;PD4504,6779,4528,6744,4553,6709,4577,6673,4602,6636,4626,6598,4651,6559,4675,6520,4700,6481,4724,6442,4749,6402,4773,6363,4798,6324,4822,6285,4847,6246,4871,6208,4896,6170,4920,6133,4945,6097,4969,6062,4994,6027,5018,5994,5043,5962,5067,5931,5092,5901,5116,5873,5140,5846,5165,5820,5189,5796,5214,5774,5238,5752,5263,5732,5287,5714,5312,5698,5336,5682,5361,5668,5385,5655,5410,5645,5434,5634,5459,5626,5483,5619,5508,5613,5532,5608,5557,5605,5581,5602,5606,5600,5630,5600,5655,5600,5679,5601,5704,5604,5728,5607,5752,5610,5777,5615,5801,5620,5826,5626,5850,5632,5875,5640,5899,5647,5924,5655,5948,5664,5973,5673,5997,5683,6022,5693,6046,5703,6071,5714,6095,5725,6120,5737,6144,5749,6169,5762,6193,5774,6218,5788,6242,5802,6267,5816,6291,5831,6316,5846,6340,5861,6365,5878,6389,5894,6413,5911,6438,5929,6462,5947,6487,5966,6511,5985,6536,6005,6560,6025,6585,6046,6609,6068,6634,6090,6658,6112,6683,6134,6707,6157,6732,6179,6756,6202,6781,6224,6805,6245,6830,6266,6854,6286,6879,6304,6903,6322,6928,6338,6952,6353,6977,6367,7001,6379,7025,6389,7050,6398,7074,6406,7099,6413,7123,6418,7148,6422,7172,6425,7197,6427,7221,6429,7246,6429,7270,6429,7295,6428,7319,6426,7344,6424,7368,6422,7393,6418,7417,7197,;LT;PU7405,7197;PD7405,4271,4479,4271,;PU7417,7197;PD7417,4259,4479,4259,;PU4428,3975;PD4428,3980,4432,3988,4437,3993,4445,3997,4462,3997,4471,3993,4475,3988,4479,3980,4479,3971,4475,3962,4467,3950,4428,3907,;PU4428,3975;PD4432,3975,4432,3980,4437,3988,4445,3993,4462,3993,4471,3988,4475,3980,4475,3971,4471,3962,4462,3950,4424,3907,;PU4428,3911;PD4484,3911,4484,3907,;PU4424,3907;PD4484,3907,;PU4535,3997;PD4522,3993,4514,3980,4510,3958,4510,3945,4514,3924,4522,3911,4535,3907,4544,3907,4557,3911,4565,3924,4570,3945,4570,3958,4565,3980,4557,3993,4544,3997,4535,3997,;PU4527,3993;PD4518,3980,4514,3958,4514,3945,4518,3924,4527,3911,;PU4522,3915;PD4535,3911,4544,3911,4557,3915,;PU4553,3911;PD4561,3924,4565,3945,4565,3958,4561,3980,4553,3993,;PU4557,3988;PD4544,3993,4535,3993,4522,3988,;PU4604,3920;PD4600,3915,4600,3911,4604,3907,4608,3907,4613,3911,4613,3915,4608,3920,4604,3920,;PU4604,3915;PD4604,3911,4608,3911,4608,3915,4604,3915,;PU4467,4259;PD4467,4149,;PU4479,4259;PD4479,4149,;PU5446,3984;PD5446,3907,5450,3907,;PU5450,3997;PD5450,3907,;PU5450,3997;PD5403,3928,5467,3928,;PU5446,3984;PD5407,3928,;PU5407,3932;PD5467,3932,5467,3928,;PU5515,3997;PD5502,3993,5493,3980,5489,3958,5489,3945,5493,3924,5502,3911,5515,3907,5523,3907,5536,3911,5545,3924,5549,3945,5549,3958,5545,3980,5536,3993,5523,3997,5515,3997,;PU5506,3993;PD5497,3980,5493,3958,5493,3945,5497,3924,5506,3911,;PU5502,3915;PD5515,3911,5523,3911,5536,3915,;PU5532,3911;PD5540,3924,5545,3945,5545,3958,5540,3980,5532,3993,;PU5536,3988;PD5523,3993,5515,3993,5502,3988,;PU5583,3920;PD5579,3915,5579,3911,5583,3907,5588,3907,5592,3911,5592,3915,5588,3920,5583,3920,;PU5583,3915;PD5583,3911,5588,3911,5588,3915,5583,3915,;PU5447,4259;PD5447,4149,;PU5459,4259;PD5459,4149,;PU6429,3993;PD6434,3984,6438,3984,6434,3993,6421,3997,6412,3997,6399,3993,6391,3980,6386,3958,6386,3937,6391,3920,6399,3911,6412,3907,6416,3907,6429,3911,6438,3920,6442,3932,6442,3937,6438,3950,6429,3958,6416,3962,6412,3962,6399,3958,6391,3950,;PU6434,3988;PD6421,3993,6412,3993,6399,3988,;PU6404,3993;PD6395,3980,6391,3958,6391,3937,6395,3920,6408,3911,;PU6391,3928;PD6399,3915,6412,3911,6416,3911,6429,3915,6438,3928,;PU6421,3911;PD6434,3920,6438,3932,6438,3937,6434,3950,6421,3958,;PU6438,3941;PD6429,3954,6416,3958,6412,3958,6399,3954,6391,3941,;PU6408,3958;PD6395,3950,6391,3937,;PU6494,3997;PD6481,3993,6472,3980,6468,3958,6468,3945,6472,3924,6481,3911,6494,3907,6502,3907,6515,3911,6524,3924,6528,3945,6528,3958,6524,3980,6515,3993,6502,3997,6494,3997,;PU6485,3993;PD6477,3980,6472,3958,6472,3945,6477,3924,6485,3911,;PU6481,3915;PD6494,3911,6502,3911,6515,3915,;PU6511,3911;PD6520,3924,6524,3945,6524,3958,6520,3980,6511,3993,;PU6515,3988;PD6502,3993,6494,3993,6481,3988,;PU6563,3920;PD6558,3915,6558,3911,6563,3907,6567,3907,6571,3911,6571,3915,6567,3920,6563,3920,;PU6563,3915;PD6563,3911,6567,3911,6567,3915,6563,3915,;PU6426,4259;PD6426,4149,;PU6438,4259;PD6438,4149,;PU7383,3997;PD7370,3993,7366,3984,7366,3975,7370,3967,7374,3962,7383,3958,7400,3954,7409,3950,7413,3945,7417,3937,7417,3924,7413,3915,7400,3911,7383,3911,7370,3915,7366,3924,7366,3937,7370,3945,7374,3950,7383,3954,7400,3958,7409,3962,7413,3967,7417,3975,7417,3984,7413,3993,7400,3997,7383,3997,;PU7374,3993;PD7370,3984,7370,3975,7374,3967,7383,3962,7400,3958,7409,3954,7417,3945,7421,3937,7421,3924,7417,3915,7413,3911,7400,3907,7383,3907,7370,3911,7366,3915,7361,3924,7361,3937,7366,3945,7374,3954,7383,3958,7400,3962,7409,3967,7413,3975,7413,3984,7409,3993,;PU7413,3988;PD7400,3993,7383,3993,7370,3988,;PU7366,3920;PD7379,3911,;PU7404,3911;PD7417,3920,;PU7473,3997;PD7460,3993,7452,3980,7447,3958,7447,3945,7452,3924,7460,3911,7473,3907,7482,3907,7495,3911,7503,3924,7507,3945,7507,3958,7503,3980,7495,3993,7482,3997,7473,3997,;PU7464,3993;PD7456,3980,7452,3958,7452,3945,7456,3924,7464,3911,;PU7460,3915;PD7473,3911,7482,3911,7495,3915,;PU7490,3911;PD7499,3924,7503,3945,7503,3958,7499,3980,7490,3993,;PU7495,3988;PD7482,3993,7473,3993,7460,3988,;PU7542,3920;PD7537,3915,7537,3911,7542,3907,7546,3907,7550,3911,7550,3915,7546,3920,7542,3920,;PU7542,3915;PD7542,3911,7546,3911,7546,3915,7542,3915,;PU7405,4259;PD7405,4149,;PU7417,4259;PD7417,4149,;PU7417,4247;PD7527,4247,;PU7417,4259;PD7527,4259,;PU7417,4835;PD7527,4835,;PU7417,4847;PD7527,4847,;PU7417,5422;PD7527,5422,;PU7417,5434;PD7527,5434,;PU7417,6010;PD7527,6010,;PU7417,6022;PD7527,6022,;PU7417,6597;PD7527,6597,;PU7417,6609;PD7527,6609,;PU7417,7185;PD7527,7185,;PU7417,7197;PD7527,7197,;PU7417,4271;PD4492,4271,4492,7197,;PU7417,4259;PD4479,4259,4479,7197,;PU4428,3975;PD4428,3980,4432,3988,4437,3993,4445,3997,4462,3997,4471,3993,4475,3988,4479,3980,4479,3971,4475,3962,4467,3950,4428,3907,;PU4428,3975;PD4432,3975,4432,3980,4437,3988,4445,3993,4462,3993,4471,3988,4475,3980,4475,3971,4471,3962,4462,3950,4424,3907,;PU4428,3911;PD4484,3911,4484,3907,;PU4424,3907;PD4484,3907,;PU4535,3997;PD4522,3993,4514,3980,4510,3958,4510,3945,4514,3924,4522,3911,4535,3907,4544,3907,4557,3911,4565,3924,4570,3945,4570,3958,4565,3980,4557,3993,4544,3997,4535,3997,;PU4527,3993;PD4518,3980,4514,3958,4514,3945,4518,3924,4527,3911,;PU4522,3915;PD4535,3911,4544,3911,4557,3915,;PU4553,3911;PD4561,3924,4565,3945,4565,3958,4561,3980,4553,3993,;PU4557,3988;PD4544,3993,4535,3993,4522,3988,;PU4604,3920;PD4600,3915,4600,3911,4604,3907,4608,3907,4613,3911,4613,3915,4608,3920,4604,3920,;PU4604,3915;PD4604,3911,4608,3911,4608,3915,4604,3915,;PU4467,4259;PD4467,4149,;PU4479,4259;PD4479,4149,;PU5446,3984;PD5446,3907,5450,3907,;PU5450,3997;PD5450,3907,;PU5450,3997;PD5403,3928,5467,3928,;PU5446,3984;PD5407,3928,;PU5407,3932;PD5467,3932,5467,3928,;PU5515,3997;PD5502,3993,5493,3980,5489,3958,5489,3945,5493,3924,5502,3911,5515,3907,5523,3907,5536,3911,5545,3924,5549,3945,5549,3958,5545,3980,5536,3993,5523,3997,5515,3997,;PU5506,3993;PD5497,3980,5493,3958,5493,3945,5497,3924,5506,3911,;PU5502,3915;PD5515,3911,5523,3911,5536,3915,;PU5532,3911;PD5540,3924,5545,3945,5545,3958,5540,3980,5532,3993,;PU5536,3988;PD5523,3993,5515,3993,5502,3988,;PU5583,3920;PD5579,3915,5579,3911,5583,3907,5588,3907,5592,3911,5592,3915,5588,3920,5583,3920,;PU5583,3915;PD5583,3911,5588,3911,5588,3915,5583,3915,;PU5447,4259;PD5447,4149,;PU5459,4259;PD5459,4149,;PU6429,3993;PD6434,3984,6438,3984,6434,3993,6421,3997,6412,3997,6399,3993,6391,3980,6386,3958,6386,3937,6391,3920,6399,3911,6412,3907,6416,3907,6429,3911,6438,3920,6442,3932,6442,3937,6438,3950,6429,3958,6416,3962,6412,3962,6399,3958,6391,3950,;PU6434,3988;PD6421,3993,6412,3993,6399,3988,;PU6404,3993;PD6395,3980,6391,3958,6391,3937,6395,3920,6408,3911,;PU6391,3928;PD6399,3915,6412,3911,6416,3911,6429,3915,6438,3928,;PU6421,3911;PD6434,3920,6438,3932,6438,3937,6434,3950,6421,3958,;PU6438,3941;PD6429,3954,6416,3958,6412,3958,6399,3954,6391,3941,;PU6408,3958;PD6395,3950,6391,3937,;PU6494,3997;PD6481,3993,6472,3980,6468,3958,6468,3945,6472,3924,6481,3911,6494,3907,6502,3907,6515,3911,6524,3924,6528,3945,6528,3958,6524,3980,6515,3993,6502,3997,6494,3997,;PU6485,3993;PD6477,3980,6472,3958,6472,3945,6477,3924,6485,3911,;PU6481,3915;PD6494,3911,6502,3911,6515,3915,;PU6511,3911;PD6520,3924,6524,3945,6524,3958,6520,3980,6511,3993,;PU6515,3988;PD6502,3993,6494,3993,6481,3988,;PU6563,3920;PD6558,3915,6558,3911,6563,3907,6567,3907,6571,3911,6571,3915,6567,3920,6563,3920,;PU6563,3915;PD6563,3911,6567,3911,6567,3915,6563,3915,;PU6426,4259;PD6426,4149,;PU6438,4259;PD6438,4149,;PU7383,3997;PD7370,3993,7366,3984,7366,3975,7370,3967,7374,3962,7383,3958,7400,3954,7409,3950,7413,3945,7417,3937,7417,3924,7413,3915,7400,3911,7383,3911,7370,3915,7366,3924,7366,3937,7370,3945,7374,3950,7383,3954,7400,3958,7409,3962,7413,3967,7417,3975,7417,3984,7413,3993,7400,3997,7383,3997,;PU7374,3993;PD7370,3984,7370,3975,7374,3967,7383,3962,7400,3958,7409,3954,7417,3945,7421,3937,7421,3924,7417,3915,7413,3911,7400,3907,7383,3907,7370,3911,7366,3915,7361,3924,7361,3937,7366,3945,7374,3954,7383,3958,7400,3962,7409,3967,7413,3975,7413,3984,7409,3993,;PU7413,3988;PD7400,3993,7383,3993,7370,3988,;PU7366,3920;PD7379,3911,;PU7404,3911;PD7417,3920,;PU7473,3997;PD7460,3993,7452,3980,7447,3958,7447,3945,7452,3924,7460,3911,7473,3907,7482,3907,7495,3911,7503,3924,7507,3945,7507,3958,7503,3980,7495,3993,7482,3997,7473,3997,;PU7464,3993;PD7456,3980,7452,3958,7452,3945,7456,3924,7464,3911,;PU7460,3915;PD7473,3911,7482,3911,7495,3915,;PU7490,3911;PD7499,3924,7503,3945,7503,3958,7499,3980,7490,3993,;PU7495,3988;PD7482,3993,7473,3993,7460,3988,;PU7542,3920;PD7537,3915,7537,3911,7542,3907,7546,3907,7550,3911,7550,3915,7546,3920,7542,3920,;PU7542,3915;PD7542,3911,7546,3911,7546,3915,7542,3915,;PU7405,4259;PD7405,4149,;PU7417,4259;PD7417,4149,;PU4092,4294;PD4080,4290,4071,4277,4067,4256,4067,4243,4071,4221,4080,4208,4092,4204,4101,4204,4114,4208,4123,4221,4127,4243,4127,4256,4123,4277,4114,4290,4101,4294,4092,4294,;PU4084,4290;PD4075,4277,4071,4256,4071,4243,4075,4221,4084,4208,;PU4080,4213;PD4092,4208,4101,4208,4114,4213,;PU4110,4208;PD4118,4221,4123,4243,4123,4256,4118,4277,4110,4290,;PU4114,4286;PD4101,4290,4092,4290,4080,4286,;PU4161,4217;PD4157,4213,4157,4208,4161,4204,4166,4204,4170,4208,4170,4213,4166,4217,4161,4217,;PU4161,4213;PD4161,4208,4166,4208,4166,4213,4161,4213,;PU4226,4294;PD4213,4290,4204,4277,4200,4256,4200,4243,4204,4221,4213,4208,4226,4204,4234,4204,4247,4208,4256,4221,4260,4243,4260,4256,4256,4277,4247,4290,4234,4294,4226,4294,;PU4217,4290;PD4208,4277,4204,4256,4204,4243,4208,4221,4217,4208,;PU4213,4213;PD4226,4208,4234,4208,4247,4213,;PU4243,4208;PD4251,4221,4256,4243,4256,4256,4251,4277,4243,4290,;PU4247,4286;PD4234,4290,4226,4290,4213,4286,;PU4479,4271;PD4369,4271,;PU4479,4259;PD4369,4259,;PU4092,4882;PD4080,4878,4071,4865,4067,4843,4067,4830,4071,4809,4080,4796,4092,4792,4101,4792,4114,4796,4123,4809,4127,4830,4127,4843,4123,4865,4114,4878,4101,4882,4092,4882,;PU4084,4878;PD4075,4865,4071,4843,4071,4830,4075,4809,4084,4796,;PU4080,4800;PD4092,4796,4101,4796,4114,4800,;PU4110,4796;PD4118,4809,4123,4830,4123,4843,4118,4865,4110,4878,;PU4114,4873;PD4101,4878,4092,4878,4080,4873,;PU4161,4805;PD4157,4800,4157,4796,4161,4792,4166,4792,4170,4796,4170,4800,4166,4805,4161,4805,;PU4161,4800;PD4161,4796,4166,4796,4166,4800,4161,4800,;PU4204,4860;PD4204,4865,4208,4873,4213,4878,4221,4882,4239,4882,4247,4878,4251,4873,4256,4865,4256,4856,4251,4848,4243,4835,4204,4792,;PU4204,4860;PD4208,4860,4208,4865,4213,4873,4221,4878,4239,4878,4247,4873,4251,4865,4251,4856,4247,4848,4239,4835,4200,4792,;PU4204,4796;PD4260,4796,4260,4792,;PU4200,4792;PD4260,4792,;PU4479,4859;PD4369,4859,;PU4479,4847;PD4369,4847,;PU4092,5469;PD4080,5465,4071,5452,4067,5431,4067,5418,4071,5396,4080,5384,4092,5379,4101,5379,4114,5384,4123,5396,4127,5418,4127,5431,4123,5452,4114,5465,4101,5469,4092,5469,;PU4084,5465;PD4075,5452,4071,5431,4071,5418,4075,5396,4084,5384,;PU4080,5388;PD4092,5384,4101,5384,4114,5388,;PU4110,5384;PD4118,5396,4123,5418,4123,5431,4118,5452,4110,5465,;PU4114,5461;PD4101,5465,4092,5465,4080,5461,;PU4161,5392;PD4157,5388,4157,5384,4161,5379,4166,5379,4170,5384,4170,5388,4166,5392,4161,5392,;PU4161,5388;PD4161,5384,4166,5384,4166,5388,4161,5388,;PU4243,5457;PD4243,5379,4247,5379,;PU4247,5469;PD4247,5379,;PU4247,5469;PD4200,5401,4264,5401,;PU4243,5457;PD4204,5401,;PU4204,5405;PD4264,5405,4264,5401,;PU4479,5446;PD4369,5446,;PU4479,5434;PD4369,5434,;PU4092,6057;PD4080,6053,4071,6040,4067,6018,4067,6005,4071,5984,4080,5971,4092,5967,4101,5967,4114,5971,4123,5984,4127,6005,4127,6018,4123,6040,4114,6053,4101,6057,4092,6057,;PU4084,6053;PD4075,6040,4071,6018,4071,6005,4075,5984,4084,5971,;PU4080,5975;PD4092,5971,4101,5971,4114,5975,;PU4110,5971;PD4118,5984,4123,6005,4123,6018,4118,6040,4110,6053,;PU4114,6048;PD4101,6053,4092,6053,4080,6048,;PU4161,5980;PD4157,5975,4157,5971,4161,5967,4166,5967,4170,5971,4170,5975,4166,5980,4161,5980,;PU4161,5975;PD4161,5971,4166,5971,4166,5975,4161,5975,;PU4247,6053;PD4251,6044,4256,6044,4251,6053,4239,6057,4230,6057,4217,6053,4208,6040,4204,6018,4204,5997,4208,5980,4217,5971,4230,5967,4234,5967,4247,5971,4256,5980,4260,5993,4260,5997,4256,6010,4247,6018,4234,6023,4230,6023,4217,6018,4208,6010,;PU4251,6048;PD4239,6053,4230,6053,4217,6048,;PU4221,6053;PD4213,6040,4208,6018,4208,5997,4213,5980,4226,5971,;PU4208,5988;PD4217,5975,4230,5971,4234,5971,4247,5975,4256,5988,;PU4239,5971;PD4251,5980,4256,5993,4256,5997,4251,6010,4239,6018,;PU4256,6001;PD4247,6014,4234,6018,4230,6018,4217,6014,4208,6001,;PU4226,6018;PD4213,6010,4208,5997,;PU4479,6034;PD4369,6034,;PU4479,6022;PD4369,6022,;PU4092,6645;PD4080,6640,4071,6627,4067,6606,4067,6593,4071,6571,4080,6559,4092,6554,4101,6554,4114,6559,4123,6571,4127,6593,4127,6606,4123,6627,4114,6640,4101,6645,4092,6645,;PU4084,6640;PD4075,6627,4071,6606,4071,6593,4075,6571,4084,6559,;PU4080,6563;PD4092,6559,4101,6559,4114,6563,;PU4110,6559;PD4118,6571,4123,6593,4123,6606,4118,6627,4110,6640,;PU4114,6636;PD4101,6640,4092,6640,4080,6636,;PU4161,6567;PD4157,6563,4157,6559,4161,6554,4166,6554,4170,6559,4170,6563,4166,6567,4161,6567,;PU4161,6563;PD4161,6559,4166,6559,4166,6563,4161,6563,;PU4221,6645;PD4208,6640,4204,6632,4204,6623,4208,6614,4213,6610,4221,6606,4239,6602,4247,6597,4251,6593,4256,6584,4256,6571,4251,6563,4239,6559,4221,6559,4208,6563,4204,6571,4204,6584,4208,6593,4213,6597,4221,6602,4239,6606,4247,6610,4251,6614,4256,6623,4256,6632,4251,6640,4239,6645,4221,6645,;PU4213,6640;PD4208,6632,4208,6623,4213,6614,4221,6610,4239,6606,4247,6602,4256,6593,4260,6584,4260,6571,4256,6563,4251,6559,4239,6554,4221,6554,4208,6559,4204,6563,4200,6571,4200,6584,4204,6593,4213,6602,4221,6606,4239,6610,4247,6614,4251,6623,4251,6632,4247,6640,;PU4251,6636;PD4239,6640,4221,6640,4208,6636,;PU4204,6567;PD4217,6559,;PU4243,6559;PD4256,6567,;PU4479,6621;PD4369,6621,;PU4479,6609;PD4369,6609,;PU4080,7215;PD4088,7219,4101,7232,4101,7142,;PU4080,7215;PD4080,7211,4088,7215,4097,7223,4097,7142,4101,7142,;PU4161,7155;PD4157,7150,4157,7146,4161,7142,4166,7142,4170,7146,4170,7150,4166,7155,4161,7155,;PU4161,7150;PD4161,7146,4166,7146,4166,7150,4161,7150,;PU4226,7232;PD4213,7228,4204,7215,4200,7193,4200,7181,4204,7159,4213,7146,4226,7142,4234,7142,4247,7146,4256,7159,4260,7181,4260,7193,4256,7215,4247,7228,4234,7232,4226,7232,;PU4217,7228;PD4208,7215,4204,7193,4204,7181,4208,7159,4217,7146,;PU4213,7150;PD4226,7146,4234,7146,4247,7150,;PU4243,7146;PD4251,7159,4256,7181,4256,7193,4251,7215,4243,7228,;PU4247,7223;PD4234,7228,4226,7228,4213,7223,;PU4479,7209;PD4369,7209,;PU4479,7197;PD4369,7197,;PU4470,1967;PD4663,3607,;PU4458,1968;PD4651,3609,;PU4651,3621;PD4555,3621,;PU4651,3609;PD4555,3609,;PU4628,3428;PD4532,3428,;PU4628,3416;PD4532,3416,;PU4605,3228;PD4509,3228,;PU4605,3216;PD4509,3216,;PU4580,3021;PD4484,3021,;PU4580,3009;PD4484,3009,;PU4555,2805;PD4459,2805,;PU4555,2793;PD4459,2793,;PU4529,2581;PD4433,2581,;PU4529,2569;PD4433,2569,;PU4501,2348;PD4405,2348,;PU4501,2336;PD4405,2336,;PU4473,2106;PD4377,2106,;PU4473,2094;PD4377,2094,;PU4058,3651;PD4118,3651,4075,3561,;PU4058,3651;PD4058,3646,4114,3646,;PU4114,3651;PD4071,3561,4075,3561,;PU4191,3646;PD4196,3638,4200,3638,4196,3646,4183,3651,4174,3651,4161,3646,4153,3634,4148,3612,4148,3591,4153,3573,4161,3565,4174,3561,4179,3561,4191,3565,4200,3573,4204,3586,4204,3591,4200,3604,4191,3612,4179,3616,4174,3616,4161,3612,4153,3604,;PU4196,3642;PD4183,3646,4174,3646,4161,3642,;PU4166,3646;PD4157,3634,4153,3612,4153,3591,4157,3573,4170,3565,;PU4153,3582;PD4161,3569,4174,3565,4179,3565,4191,3569,4200,3582,;PU4183,3565;PD4196,3573,4200,3586,4200,3591,4196,3604,4183,3612,;PU4200,3595;PD4191,3608,4179,3612,4174,3612,4161,3608,4153,3595,;PU4170,3612;PD4157,3604,4153,3591,;PU3941,2590;PD3941,2594,3945,2603,3949,2607,3958,2611,3975,2611,3984,2607,3988,2603,3992,2594,3992,2585,3988,2577,3979,2564,3941,2521,;PU3941,2590;PD3945,2590,3945,2594,3949,2603,3958,2607,3975,2607,3984,2603,3988,2594,3988,2585,3984,2577,3975,2564,3936,2521,;PU3941,2525;PD3996,2525,3996,2521,;PU3936,2521;PD3996,2521,;PU4069,2607;PD4074,2598,4078,2598,4074,2607,4061,2611,4052,2611,4039,2607,4031,2594,4026,2573,4026,2551,4031,2534,4039,2525,4052,2521,4057,2521,4069,2525,4078,2534,4082,2547,4082,2551,4078,2564,4069,2573,4057,2577,4052,2577,4039,2573,4031,2564,;PU4074,2603;PD4061,2607,4052,2607,4039,2603,;PU4044,2607;PD4035,2594,4031,2573,4031,2551,4035,2534,4048,2525,;PU4031,2542;PD4039,2530,4052,2525,4057,2525,4069,2530,4078,2542,;PU4061,2525;PD4074,2534,4078,2547,4078,2551,4074,2564,4061,2573,;PU4078,2555;PD4069,2568,4057,2573,4052,2573,4039,2568,4031,2555,;PU4048,2573;PD4035,2564,4031,2551,;PU4532,420;PD4470,1969,;PU4520,419;PD4458,1968,;PU4004,1993;PD4013,1998,4026,2011,4026,1920,;PU4004,1993;PD4004,1989,4013,1993,4021,2002,4021,1920,4026,1920,;PU4086,1933;PD4082,1929,4082,1925,4086,1920,4090,1920,4094,1925,4094,1929,4090,1933,4086,1933,;PU4086,1929;PD4086,1925,4090,1925,4090,1929,4086,1929,;PU4150,2011;PD4137,2006,4129,1993,4125,1972,4125,1959,4129,1938,4137,1925,4150,1920,4159,1920,4172,1925,4180,1938,4185,1959,4185,1972,4180,1993,4172,2006,4159,2011,4150,2011,;PU4142,2006;PD4133,1993,4129,1972,4129,1959,4133,1938,4142,1925,;PU4137,1929;PD4150,1925,4159,1925,4172,1929,;PU4167,1925;PD4176,1938,4180,1959,4180,1972,4176,1993,4167,2006,;PU4172,2002;PD4159,2006,4150,2006,4137,2002,;PU4458,1981;PD4362,1981,;PU4458,1968;PD4362,1968,;PU4030,1690;PD4017,1685,4008,1673,4004,1651,4004,1638,4008,1617,4017,1604,4030,1599,4038,1599,4051,1604,4060,1617,4064,1638,4064,1651,4060,1673,4051,1685,4038,1690,4030,1690,;PU4021,1685;PD4013,1673,4008,1651,4008,1638,4013,1617,4021,1604,;PU4017,1608;PD4030,1604,4038,1604,4051,1608,;PU4047,1604;PD4056,1617,4060,1638,4060,1651,4056,1673,4047,1685,;PU4051,1681;PD4038,1685,4030,1685,4017,1681,;PU4099,1612;PD4094,1608,4094,1604,4099,1599,4103,1599,4107,1604,4107,1608,4103,1612,4099,1612,;PU4099,1608;PD4099,1604,4103,1604,4103,1608,4099,1608,;PU4159,1690;PD4146,1685,4142,1677,4142,1668,4146,1660,4150,1655,4159,1651,4176,1647,4185,1642,4189,1638,4193,1630,4193,1617,4189,1608,4176,1604,4159,1604,4146,1608,4142,1617,4142,1630,4146,1638,4150,1642,4159,1647,4176,1651,4185,1655,4189,1660,4193,1668,4193,1677,4189,1685,4176,1690,4159,1690,;PU4150,1685;PD4146,1677,4146,1668,4150,1660,4159,1655,4176,1651,4185,1647,4193,1638,4197,1630,4197,1617,4193,1608,4189,1604,4176,1599,4159,1599,4146,1604,4142,1608,4137,1617,4137,1630,4142,1638,4150,1647,4159,1651,4176,1655,4185,1660,4189,1668,4189,1677,4185,1685,;PU4189,1681;PD4176,1685,4159,1685,4146,1681,;PU4142,1612;PD4154,1604,;PU4180,1604;PD4193,1612,;PU4471,1660;PD4375,1660,;PU4471,1648;PD4375,1648,;PU4042,1374;PD4029,1370,4021,1357,4017,1336,4017,1323,4021,1301,4029,1289,4042,1284,4051,1284,4064,1289,4072,1301,4077,1323,4077,1336,4072,1357,4064,1370,4051,1374,4042,1374,;PU4034,1370;PD4025,1357,4021,1336,4021,1323,4025,1301,4034,1289,;PU4029,1293;PD4042,1289,4051,1289,4064,1293,;PU4060,1289;PD4068,1301,4072,1323,4072,1336,4068,1357,4060,1370,;PU4064,1366;PD4051,1370,4042,1370,4029,1366,;PU4111,1297;PD4107,1293,4107,1289,4111,1284,4115,1284,4120,1289,4120,1293,4115,1297,4111,1297,;PU4111,1293;PD4111,1289,4115,1289,4115,1293,4111,1293,;PU4197,1370;PD4201,1362,4206,1362,4201,1370,4188,1374,4180,1374,4167,1370,4158,1357,4154,1336,4154,1314,4158,1297,4167,1289,4180,1284,4184,1284,4197,1289,4206,1297,4210,1310,4210,1314,4206,1327,4197,1336,4184,1340,4180,1340,4167,1336,4158,1327,;PU4201,1366;PD4188,1370,4180,1370,4167,1366,;PU4171,1370;PD4163,1357,4158,1336,4158,1314,4163,1297,4176,1289,;PU4158,1306;PD4167,1293,4180,1289,4184,1289,4197,1293,4206,1306,;PU4188,1289;PD4201,1297,4206,1310,4206,1314,4201,1327,4188,1336,;PU4206,1319;PD4197,1332,4184,1336,4180,1336,4167,1332,4158,1319,;PU4176,1336;PD4163,1327,4158,1314,;PU4484,1344;PD4388,1344,;PU4484,1332;PD4388,1332,;PU4055,1065;PD4042,1060,4033,1048,4029,1026,4029,1013,4033,992,4042,979,4055,975,4063,975,4076,979,4085,992,4089,1013,4089,1026,4085,1048,4076,1060,4063,1065,4055,1065,;PU4046,1060;PD4037,1048,4033,1026,4033,1013,4037,992,4046,979,;PU4042,983;PD4055,979,4063,979,4076,983,;PU4072,979;PD4080,992,4085,1013,4085,1026,4080,1048,4072,1060,;PU4076,1056;PD4063,1060,4055,1060,4042,1056,;PU4123,987;PD4119,983,4119,979,4123,975,4128,975,4132,979,4132,983,4128,987,4123,987,;PU4123,983;PD4123,979,4128,979,4128,983,4123,983,;PU4205,1052;PD4205,975,4209,975,;PU4209,1065;PD4209,975,;PU4209,1065;PD4162,996,4226,996,;PU4205,1052;PD4166,996,;PU4166,1000;PD4226,1000,4226,996,;PU4496,1035;PD4400,1035,;PU4496,1023;PD4400,1023,;PU4067,760;PD4054,756,4045,743,4041,722,4041,709,4045,687,4054,675,4067,670,4075,670,4088,675,4097,687,4101,709,4101,722,4097,743,4088,756,4075,760,4067,760,;PU4058,756;PD4050,743,4045,722,4045,709,4050,687,4058,675,;PU4054,679;PD4067,675,4075,675,4088,679,;PU4084,675;PD4092,687,4097,709,4097,722,4092,743,4084,756,;PU4088,752;PD4075,756,4067,756,4054,752,;PU4135,683;PD4131,679,4131,675,4135,670,4140,670,4144,675,4144,679,4140,683,4135,683,;PU4135,679;PD4135,675,4140,675,4140,679,4135,679,;PU4178,739;PD4178,743,4183,752,4187,756,4196,760,4213,760,4221,756,4226,752,4230,743,4230,735,4226,726,4217,713,4178,670,;PU4178,739;PD4183,739,4183,743,4187,752,4196,756,4213,756,4221,752,4226,743,4226,735,4221,726,4213,713,4174,670,;PU4178,675;PD4234,675,4234,670,;PU4174,670;PD4234,670,;PU4508,730;PD4412,730,;PU4508,718;PD4412,718,;PU4079,461;PD4066,457,4057,444,4053,423,4053,410,4057,388,4066,375,4079,371,4087,371,4100,375,4109,388,4113,410,4113,423,4109,444,4100,457,4087,461,4079,461,;PU4070,457;PD4061,444,4057,423,4057,410,4061,388,4070,375,;PU4066,380;PD4079,375,4087,375,4100,380,;PU4096,375;PD4104,388,4109,410,4109,423,4104,444,4096,457,;PU4100,453;PD4087,457,4079,457,4066,453,;PU4147,384;PD4143,380,4143,375,4147,371,4152,371,4156,375,4156,380,4152,384,4147,384,;PU4147,380;PD4147,375,4152,375,4152,380,4147,380,;PU4212,461;PD4199,457,4190,444,4186,423,4186,410,4190,388,4199,375,4212,371,4220,371,4233,375,4242,388,4246,410,4246,423,4242,444,4233,457,4220,461,4212,461,;PU4203,457;PD4195,444,4190,423,4190,410,4195,388,4203,375,;PU4199,380;PD4212,375,4220,375,4233,380,;PU4229,375;PD4238,388,4242,410,4242,423,4238,444,4229,457,;PU4233,453;PD4220,457,4212,457,4199,453,;PU4520,431;PD4424,431,;PU4520,419;PD4424,419,;PU4520,407;PD7256,407,;PU4520,419;PD7256,419,;PU4508,419;PD4508,356,;PU4520,419;PD4520,356,;PU4873,419;PD4873,356,;PU4885,419;PD4885,356,;PU5237,419;PD5237,356,;PU5249,419;PD5249,356,;PU5602,419;PD5602,356,;PU5614,419;PD5614,356,;PU5967,419;PD5967,356,;PU5979,419;PD5979,356,;PU6332,419;PD6332,356,;PU6344,419;PD6344,356,;PU6697,419;PD6697,356,;PU6709,419;PD6709,356,;PU7062,419;PD7062,356,;PU7074,419;PD7074,356,;PU4490,195;PD4477,190,4468,177,4464,156,4464,143,4468,122,4477,109,4490,104,4498,104,4511,109,4520,122,4524,143,4524,156,4520,177,4511,190,4498,195,4490,195,;PU4481,190;PD4472,177,4468,156,4468,143,4472,122,4481,109,;PU4477,113;PD4490,109,4498,109,4511,113,;PU4507,109;PD4515,122,4520,143,4520,156,4515,177,4507,190,;PU4511,186;PD4498,190,4490,190,4477,186,;PU6262,195;PD6258,156,;PU6267,190;PD6262,160,;PU6262,195;PD6305,195,6305,190,;PU6267,190;PD6305,190,;PU6262,160;PD6275,165,6288,165,6301,160,6310,152,6314,139,6314,130,6310,117,6301,109,6288,104,6275,104,6262,109,6258,113,6254,122,6258,122,;PU6258,156;PD6262,156,6271,160,6288,160,6301,156,6310,143,;PU6292,160;PD6305,152,6310,139,6310,130,6305,117,6292,109,;PU6310,126;PD6301,113,6288,109,6275,109,6262,113,6258,122,;PU6271,109;PD6258,117,;PU6365,195;PD6353,190,6344,177,6340,156,6340,143,6344,122,6353,109,6365,104,6374,104,6387,109,6396,122,6400,143,6400,156,6396,177,6387,190,6374,195,6365,195,;PU6357,190;PD6348,177,6344,156,6344,143,6348,122,6357,109,;PU6353,113;PD6365,109,6374,109,6387,113,;PU6383,109;PD6391,122,6396,143,6396,156,6391,177,6383,190,;PU6387,186;PD6374,190,6365,190,6353,186,;PU4527,409;PD7086,2189,;PU4520,419;PD7079,2199,;PU651,1967;PD844,3607,;PU639,1968;PD832,3609,;PU639,1981;PD543,1981,;PU639,1968;PD543,1968,;PU670,2245;PD574,2245,;PU670,2233;PD574,2233,;PU700,2499;PD604,2499,;PU700,2487;PD604,2487,;PU729,2742;PD633,2742,;PU729,2730;PD633,2730,;PU756,2975;PD660,2975,;PU756,2963;PD660,2963,;PU782,3199;PD686,3199,;PU782,3187;PD686,3187,;PU808,3414;PD712,3414,;PU808,3402;PD712,3402,;PU832,3621;PD736,3621,;PU832,3609;PD736,3609,;PU85,1989;PD85,1993,90,2002,94,2006,103,2011,120,2011,128,2006,133,2002,137,1993,137,1985,133,1976,124,1963,85,1920,;PU85,1989;PD90,1989,90,1993,94,2002,103,2006,120,2006,128,2002,133,1993,133,1985,128,1976,120,1963,81,1920,;PU85,1925;PD141,1925,141,1920,;PU81,1920;PD141,1920,;PU193,2011;PD180,2006,171,1993,167,1972,167,1959,171,1938,180,1925,193,1920,201,1920,214,1925,223,1938,227,1959,227,1972,223,1993,214,2006,201,2011,193,2011,;PU184,2006;PD176,1993,171,1972,171,1959,176,1938,184,1925,;PU180,1929;PD193,1925,201,1925,214,1929,;PU210,1925;PD219,1938,223,1959,223,1972,219,1993,210,2006,;PU214,2002;PD201,2006,193,2006,180,2002,;PU262,1933;PD257,1929,257,1925,262,1920,266,1920,270,1925,270,1929,266,1933,262,1933,;PU262,1929;PD262,1925,266,1925,266,1929,262,1929,;PU326,2011;PD313,2006,305,1993,300,1972,300,1959,305,1938,313,1925,326,1920,335,1920,348,1925,356,1938,360,1959,360,1972,356,1993,348,2006,335,2011,326,2011,;PU317,2006;PD309,1993,305,1972,305,1959,309,1938,317,1925,;PU313,1929;PD326,1925,335,1925,348,1929,;PU343,1925;PD352,1938,356,1959,356,1972,352,1993,343,2006,;PU348,2002;PD335,2006,326,2006,313,2002,;PU185,2516;PD185,2439,189,2439,;PU189,2529;PD189,2439,;PU189,2529;PD142,2460,206,2460,;PU185,2516;PD146,2460,;PU146,2465;PD206,2465,206,2460,;PU254,2529;PD241,2525,232,2512,228,2490,228,2478,232,2456,241,2443,254,2439,262,2439,275,2443,284,2456,288,2478,288,2490,284,2512,275,2525,262,2529,254,2529,;PU245,2525;PD237,2512,232,2490,232,2478,237,2456,245,2443,;PU241,2447;PD254,2443,262,2443,275,2447,;PU271,2443;PD279,2456,284,2478,284,2490,279,2512,271,2525,;PU275,2520;PD262,2525,254,2525,241,2520,;PU322,2452;PD318,2447,318,2443,322,2439,327,2439,331,2443,331,2447,327,2452,322,2452,;PU322,2447;PD322,2443,327,2443,327,2447,322,2447,;PU387,2529;PD374,2525,365,2512,361,2490,361,2478,365,2456,374,2443,387,2439,395,2439,408,2443,417,2456,421,2478,421,2490,417,2512,408,2525,395,2529,387,2529,;PU378,2525;PD370,2512,365,2490,365,2478,370,2456,378,2443,;PU374,2447;PD387,2443,395,2443,408,2447,;PU404,2443;PD413,2456,417,2478,417,2490,413,2512,404,2525,;PU408,2520;PD395,2525,387,2525,374,2520,;PU245,3001;PD249,2992,254,2992,249,3001,237,3005,228,3005,215,3001,206,2988,202,2967,202,2945,206,2928,215,2919,228,2915,232,2915,245,2919,254,2928,258,2941,258,2945,254,2958,245,2967,232,2971,228,2971,215,2967,206,2958,;PU249,2997;PD237,3001,228,3001,215,2997,;PU219,3001;PD211,2988,206,2967,206,2945,211,2928,224,2919,;PU206,2936;PD215,2924,228,2919,232,2919,245,2924,254,2936,;PU237,2919;PD249,2928,254,2941,254,2945,249,2958,237,2967,;PU254,2949;PD245,2962,232,2967,228,2967,215,2962,206,2949,;PU224,2967;PD211,2958,206,2945,;PU310,3005;PD297,3001,288,2988,284,2967,284,2954,288,2932,297,2919,310,2915,318,2915,331,2919,340,2932,344,2954,344,2967,340,2988,331,3001,318,3005,310,3005,;PU301,3001;PD292,2988,288,2967,288,2954,292,2932,301,2919,;PU297,2924;PD310,2919,318,2919,331,2924,;PU327,2919;PD335,2932,340,2954,340,2967,335,2988,327,3001,;PU331,2997;PD318,3001,310,3001,297,2997,;PU378,2928;PD374,2924,374,2919,378,2915,383,2915,387,2919,387,2924,383,2928,378,2928,;PU378,2924;PD378,2919,383,2919,383,2924,378,2924,;PU443,3005;PD430,3001,421,2988,417,2967,417,2954,421,2932,430,2919,443,2915,451,2915,464,2919,473,2932,477,2954,477,2967,473,2988,464,3001,451,3005,443,3005,;PU434,3001;PD426,2988,421,2967,421,2954,426,2932,434,2919,;PU430,2924;PD443,2919,451,2919,464,2924,;PU460,2919;PD469,2932,473,2954,473,2967,469,2988,460,3001,;PU464,2997;PD451,3001,443,3001,430,2997,;PU271,3444;PD258,3440,254,3431,254,3423,258,3414,262,3410,271,3405,288,3401,297,3397,301,3392,305,3384,305,3371,301,3362,288,3358,271,3358,258,3362,254,3371,254,3384,258,3392,262,3397,271,3401,288,3405,297,3410,301,3414,305,3423,305,3431,301,3440,288,3444,271,3444,;PU262,3440;PD258,3431,258,3423,262,3414,271,3410,288,3405,297,3401,305,3392,310,3384,310,3371,305,3362,301,3358,288,3354,271,3354,258,3358,254,3362,249,3371,249,3384,254,3392,262,3401,271,3405,288,3410,297,3414,301,3423,301,3431,297,3440,;PU301,3435;PD288,3440,271,3440,258,3435,;PU254,3367;PD267,3358,;PU292,3358;PD305,3367,;PU361,3444;PD348,3440,340,3427,335,3405,335,3392,340,3371,348,3358,361,3354,370,3354,383,3358,391,3371,395,3392,395,3405,391,3427,383,3440,370,3444,361,3444,;PU352,3440;PD344,3427,340,3405,340,3392,344,3371,352,3358,;PU348,3362;PD361,3358,370,3358,383,3362,;PU378,3358;PD387,3371,391,3392,391,3405,387,3427,378,3440,;PU383,3435;PD370,3440,361,3440,348,3435,;PU430,3367;PD426,3362,426,3358,430,3354,434,3354,438,3358,438,3362,434,3367,430,3367,;PU430,3362;PD430,3358,434,3358,434,3362,430,3362,;PU494,3444;PD481,3440,473,3427,468,3405,468,3392,473,3371,481,3358,494,3354,503,3354,516,3358,524,3371,529,3392,529,3405,524,3427,516,3440,503,3444,494,3444,;PU486,3440;PD477,3427,473,3405,473,3392,477,3371,486,3358,;PU481,3362;PD494,3358,503,3358,516,3362,;PU511,3358;PD520,3371,524,3392,524,3405,520,3427,511,3440,;PU516,3435;PD503,3440,494,3440,481,3435,;PU3511,1970;PD3318,3610,;PU3499,1968;PD3306,3609,;PU3499,1956;PD3595,1956,;PU3499,1968;PD3595,1968,;PU3468,2221;PD3563,2221,;PU3468,2233;PD3563,2233,;PU3438,2475;PD3534,2475,;PU3438,2487;PD3534,2487,;PU3409,2718;PD3505,2718,;PU3409,2730;PD3505,2730,;PU3382,2951;PD3478,2951,;PU3382,2963;PD3478,2963,;PU3356,3175;PD3452,3175,;PU3356,3187;PD3452,3187,;PU3330,3390;PD3426,3390,;PU3330,3402;PD3426,3402,;PU3306,3597;PD3402,3597,;PU3306,3609;PD3402,3609,;PU713,420;PD651,1969,;PU701,419;PD639,1968,;PU185,1993;PD194,1998,207,2011,207,1920,;PU185,1993;PD185,1989,194,1993,202,2002,202,1920,207,1920,;PU267,1933;PD263,1929,263,1925,267,1920,271,1920,275,1925,275,1929,271,1933,267,1933,;PU267,1929;PD267,1925,271,1925,271,1929,267,1929,;PU331,2011;PD318,2006,310,1993,306,1972,306,1959,310,1938,318,1925,331,1920,340,1920,353,1925,361,1938,366,1959,366,1972,361,1993,353,2006,340,2011,331,2011,;PU323,2006;PD314,1993,310,1972,310,1959,314,1938,323,1925,;PU318,1929;PD331,1925,340,1925,353,1929,;PU348,1925;PD357,1938,361,1959,361,1972,357,1993,348,2006,;PU353,2002;PD340,2006,331,2006,318,2002,;PU639,1981;PD543,1981,;PU639,1968;PD543,1968,;PU211,1690;PD198,1685,189,1673,185,1651,185,1638,189,1617,198,1604,211,1599,219,1599,232,1604,241,1617,245,1638,245,1651,241,1673,232,1685,219,1690,211,1690,;PU202,1685;PD194,1673,189,1651,189,1638,194,1617,202,1604,;PU198,1608;PD211,1604,219,1604,232,1608,;PU228,1604;PD237,1617,241,1638,241,1651,237,1673,228,1685,;PU232,1681;PD219,1685,211,1685,198,1681,;PU280,1612;PD275,1608,275,1604,280,1599,284,1599,288,1604,288,1608,284,1612,280,1612,;PU280,1608;PD280,1604,284,1604,284,1608,280,1608,;PU340,1690;PD327,1685,323,1677,323,1668,327,1660,331,1655,340,1651,357,1647,366,1642,370,1638,374,1630,374,1617,370,1608,357,1604,340,1604,327,1608,323,1617,323,1630,327,1638,331,1642,340,1647,357,1651,366,1655,370,1660,374,1668,374,1677,370,1685,357,1690,340,1690,;PU331,1685;PD327,1677,327,1668,331,1660,340,1655,357,1651,366,1647,374,1638,378,1630,378,1617,374,1608,370,1604,357,1599,340,1599,327,1604,323,1608,318,1617,318,1630,323,1638,331,1647,340,1651,357,1655,366,1660,370,1668,370,1677,366,1685,;PU370,1681;PD357,1685,340,1685,327,1681,;PU323,1612;PD335,1604,;PU361,1604;PD374,1612,;PU652,1660;PD556,1660,;PU652,1648;PD556,1648,;PU223,1374;PD210,1370,202,1357,198,1336,198,1323,202,1301,210,1289,223,1284,232,1284,245,1289,253,1301,258,1323,258,1336,253,1357,245,1370,232,1374,223,1374,;PU215,1370;PD206,1357,202,1336,202,1323,206,1301,215,1289,;PU210,1293;PD223,1289,232,1289,245,1293,;PU241,1289;PD249,1301,253,1323,253,1336,249,1357,241,1370,;PU245,1366;PD232,1370,223,1370,210,1366,;PU292,1297;PD288,1293,288,1289,292,1284,296,1284,301,1289,301,1293,296,1297,292,1297,;PU292,1293;PD292,1289,296,1289,296,1293,292,1293,;PU378,1370;PD382,1362,387,1362,382,1370,369,1374,361,1374,348,1370,339,1357,335,1336,335,1314,339,1297,348,1289,361,1284,365,1284,378,1289,387,1297,391,1310,391,1314,387,1327,378,1336,365,1340,361,1340,348,1336,339,1327,;PU382,1366;PD369,1370,361,1370,348,1366,;PU352,1370;PD344,1357,339,1336,339,1314,344,1297,357,1289,;PU339,1306;PD348,1293,361,1289,365,1289,378,1293,387,1306,;PU369,1289;PD382,1297,387,1310,387,1314,382,1327,369,1336,;PU387,1319;PD378,1332,365,1336,361,1336,348,1332,339,1319,;PU357,1336;PD344,1327,339,1314,;PU665,1344;PD569,1344,;PU665,1332;PD569,1332,;PU236,1065;PD223,1060,214,1048,210,1026,210,1013,214,992,223,979,236,975,244,975,257,979,266,992,270,1013,270,1026,266,1048,257,1060,244,1065,236,1065,;PU227,1060;PD218,1048,214,1026,214,1013,218,992,227,979,;PU223,983;PD236,979,244,979,257,983,;PU253,979;PD261,992,266,1013,266,1026,261,1048,253,1060,;PU257,1056;PD244,1060,236,1060,223,1056,;PU304,987;PD300,983,300,979,304,975,309,975,313,979,313,983,309,987,304,987,;PU304,983;PD304,979,309,979,309,983,304,983,;PU386,1052;PD386,975,390,975,;PU390,1065;PD390,975,;PU390,1065;PD343,996,407,996,;PU386,1052;PD347,996,;PU347,1000;PD407,1000,407,996,;PU677,1035;PD581,1035,;PU677,1023;PD581,1023,;PU248,760;PD235,756,226,743,222,722,222,709,226,687,235,675,248,670,256,670,269,675,278,687,282,709,282,722,278,743,269,756,256,760,248,760,;PU239,756;PD231,743,226,722,226,709,231,687,239,675,;PU235,679;PD248,675,256,675,269,679,;PU265,675;PD273,687,278,709,278,722,273,743,265,756,;PU269,752;PD256,756,248,756,235,752,;PU316,683;PD312,679,312,675,316,670,321,670,325,675,325,679,321,683,316,683,;PU316,679;PD316,675,321,675,321,679,316,679,;PU359,739;PD359,743,364,752,368,756,377,760,394,760,402,756,407,752,411,743,411,735,407,726,398,713,359,670,;PU359,739;PD364,739,364,743,368,752,377,756,394,756,402,752,407,743,407,735,402,726,394,713,355,670,;PU359,675;PD415,675,415,670,;PU355,670;PD415,670,;PU689,730;PD593,730,;PU689,718;PD593,718,;PU260,461;PD247,457,238,444,234,423,234,410,238,388,247,375,260,371,268,371,281,375,290,388,294,410,294,423,290,444,281,457,268,461,260,461,;PU251,457;PD242,444,238,423,238,410,242,388,251,375,;PU247,380;PD260,375,268,375,281,380,;PU277,375;PD285,388,290,410,290,423,285,444,277,457,;PU281,453;PD268,457,260,457,247,453,;PU328,384;PD324,380,324,375,328,371,333,371,337,375,337,380,333,384,328,384,;PU328,380;PD328,375,333,375,333,380,328,380,;PU393,461;PD380,457,371,444,367,423,367,410,371,388,380,375,393,371,401,371,414,375,423,388,427,410,427,423,423,444,414,457,401,461,393,461,;PU384,457;PD376,444,371,423,371,410,376,388,384,375,;PU380,380;PD393,375,401,375,414,380,;PU410,375;PD419,388,423,410,423,423,419,444,410,457,;PU414,453;PD401,457,393,457,380,453,;PU701,431;PD605,431,;PU701,419;PD605,419,;PU3449,419;PD3511,1968,;PU3437,419;PD3499,1968,;PU3499,1956;PD3595,1956,;PU3499,1968;PD3595,1968,;PU3486,1636;PD3582,1636,;PU3486,1648;PD3582,1648,;PU3473,1320;PD3569,1320,;PU3473,1332;PD3569,1332,;PU3461,1011;PD3557,1011,;PU3461,1023;PD3557,1023,;PU3449,706;PD3545,706,;PU3449,718;PD3545,718,;PU3437,407;PD3533,407,;PU3437,419;PD3533,419,;PU701,407;PD3437,407,;PU701,419;PD3437,419,;PU689,419;PD689,356,;PU701,419;PD701,356,;PU1054,419;PD1054,356,;PU1066,419;PD1066,356,;PU1418,419;PD1418,356,;PU1430,419;PD1430,356,;PU1783,419;PD1783,356,;PU1795,419;PD1795,356,;PU2148,419;PD2148,356,;PU2160,419;PD2160,356,;PU2513,419;PD2513,356,;PU2525,419;PD2525,356,;PU2878,419;PD2878,356,;PU2890,419;PD2890,356,;PU3243,419;PD3243,356,;PU3255,419;PD3255,356,;PU671,195;PD658,190,649,177,645,156,645,143,649,122,658,109,671,104,679,104,692,109,701,122,705,143,705,156,701,177,692,190,679,195,671,195,;PU662,190;PD653,177,649,156,649,143,653,122,662,109,;PU658,113;PD671,109,679,109,692,113,;PU688,109;PD696,122,701,143,701,156,696,177,688,190,;PU692,186;PD679,190,671,190,658,186,;PU2443,195;PD2439,156,;PU2448,190;PD2443,160,;PU2443,195;PD2486,195,2486,190,;PU2448,190;PD2486,190,;PU2443,160;PD2456,165,2469,165,2482,160,2491,152,2495,139,2495,130,2491,117,2482,109,2469,104,2456,104,2443,109,2439,113,2435,122,2439,122,;PU2439,156;PD2443,156,2452,160,2469,160,2482,156,2491,143,;PU2473,160;PD2486,152,2491,139,2491,130,2486,117,2473,109,;PU2491,126;PD2482,113,2469,109,2456,109,2443,113,2439,122,;PU2452,109;PD2439,117,;PU2546,195;PD2534,190,2525,177,2521,156,2521,143,2525,122,2534,109,2546,104,2555,104,2568,109,2577,122,2581,143,2581,156,2577,177,2568,190,2555,195,2546,195,;PU2538,190;PD2529,177,2525,156,2525,143,2529,122,2538,109,;PU2534,113;PD2546,109,2555,109,2568,113,;PU2564,109;PD2572,122,2577,143,2577,156,2572,177,2564,190,;PU2568,186;PD2555,190,2546,190,2534,186,;PU866,2197;PD;PU878,2199;PD;PU3250,2192;PD;PU3260,2199;PD;PU;SP3;PU696,1968;PD735,1968,828,419,865,419,901,419,938,419,974,419,1011,419,1047,419,1040,1968,1097,1262,1143,931,1165,1528,1201,1591,1236,1730,1290,971,1334,683,1372,590,1409,588,1446,556,1483,560,1501,1733,1535,1968,1577,1719,1615,1716,1653,1715,1689,1850,1726,1951,1765,1838,1813,507,1849,520,1886,503,1922,544,1959,533,1995,730,2031,1564,2069,814,2106,821,2143,976,2180,1007,2217,890,2254,886,2295,1583,2333,1570,2370,1552,2408,1518,2448,1778,2484,1612,2522,1601,2561,1686,2592,1260,2629,1233,2668,1349,2690,441,2729,588,2774,1018,2811,983,2847,945,2884,943,2942,1797,2984,1967,3022,1961,3047,1496,3064,777,3101,788,3156,1377,3199,1536,3200,419,3236,419,3273,419,3309,419,3346,419,3382,419,3419,419,3518,1968,;PU731,2276;PD768,2276,858,752,894,752,930,752,965,752,1001,752,1036,752,1072,752,1066,2276,1120,1644,1162,1400,1186,1923,1222,1948,1256,2080,1308,1360,1349,1158,1387,1057,1423,1055,1459,1008,1495,1011,1515,2082,1549,2276,1590,1994,1627,1990,1663,1991,1698,2205,1735,2260,1773,2141,1819,806,1855,809,1891,791,1926,989,1962,881,1997,1038,2032,1850,2069,1071,2105,1087,2141,1178,2178,1379,2213,1247,2249,1240,2290,1939,2327,1946,2364,1943,2401,1985,2439,2167,2475,2028,2509,1821,2546,1850,2579,1598,2615,1560,2654,1689,2675,778,2715,1045,2757,1335,2792,1278,2825,1132,2861,1130,2917,1973,2961,2272,2998,2262,3026,1948,3043,1228,3080,1253,3132,1769,3176,2020,3173,752,3208,752,3244,752,3279,752,3315,752,3351,752,3386,752,3481,2276,;PU764,2569;PD800,2569,887,1069,922,1069,957,1069,991,1069,1026,1069,1061,1069,1096,1071,1090,2569,1139,2079,1179,1908,1205,2307,1241,2312,1275,2420,1323,1836,1361,1699,1398,1606,1434,1603,1470,1535,1505,1537,1528,2411,1562,2569,1602,2230,1638,2225,1674,2229,1707,2520,1743,2555,1780,2444,1825,1158,1860,1118,1895,1099,1928,1505,1964,1213,1999,1326,2033,1979,2069,1326,2104,1356,2139,1407,2176,1839,2210,1697,2246,1685,2285,2276,2321,2300,2357,2308,2394,2385,2431,2507,2466,2393,2496,1930,2532,1923,2566,1789,2600,1745,2638,1881,2661,1111,2704,1577,2743,1781,2777,1697,2805,1349,2840,1347,2892,2087,2939,2561,2974,2546,3005,2321,3023,1653,3060,1703,3106,2097,3152,2432,3147,1071,3181,1069,3216,1069,3251,1069,3286,1069,3320,1069,3355,1069,3446,2569,;PU796,2848;PD831,2848,914,1372,948,1372,982,1372,1016,1371,1050,1371,1084,1371,1118,1378,1114,2847,1157,2521,1195,2414,1224,2683,1259,2679,1293,2746,1335,2395,1372,2307,1408,2237,1443,2234,1479,2150,1514,2150,1540,2734,1574,2848,1613,2516,1648,2511,1683,2519,1716,2813,1751,2839,1787,2741,1829,1634,1865,1481,1899,1461,1930,2094,1967,1551,2001,1625,2034,2002,2069,1575,2103,1625,2137,1654,2174,2365,2208,2213,2243,2202,2280,2591,2315,2635,2350,2650,2386,2735,2422,2811,2457,2727,2483,1972,2517,1937,2551,1873,2585,1835,2621,1970,2647,1441,2694,2167,2731,2322,2764,2217,2787,1620,2821,1619,2869,2237,2918,2837,2953,2818,2984,2645,3005,2106,3041,2179,3084,2449,3128,2783,3122,1378,3156,1371,3190,1371,3224,1372,3257,1372,3291,1372,3325,1372,3413,2848,;PU825,3113;PD860,3113,940,1671,973,1671,1006,1671,1040,1670,1073,1670,1106,1670,1139,1679,1136,3113,1176,2915,1211,2854,1242,3027,1276,3021,1310,3048,1347,2922,1383,2865,1418,2822,1452,2820,1488,2747,1522,2747,1552,3047,1585,3112,1623,2896,1657,2895,1691,2902,1724,3090,1758,3110,1793,3021,1833,2249,1868,1953,1902,1932,1933,2642,1969,1919,2002,1967,2035,2091,2069,1841,2102,1903,2136,1923,2172,2820,2205,2662,2240,2653,2275,2883,2310,2941,2344,2956,2379,3038,2414,3084,2448,3030,2472,2095,2505,2039,2538,2011,2571,1991,2607,2113,2635,1774,2683,2677,2720,2798,2752,2696,2773,1999,2806,1999,2852,2575,2898,3104,2932,3088,2963,2964,2989,2619,3025,2692,3064,2871,3104,3082,3098,1677,3131,1668,3165,1668,3198,1671,3231,1671,3264,1671,3297,1671,3382,3113,;PU854,3367;PD888,3367,961,2077,994,2077,1026,2077,1059,2071,1092,2071,1124,2071,1157,2078,1158,3366,1194,3251,1229,3214,1260,3321,1294,3317,1327,3324,1362,3298,1396,3250,1430,3228,1464,3225,1498,3184,1532,3184,1563,3335,1597,3364,1631,3271,1665,3273,1699,3277,1732,3347,1765,3366,1800,3270,1836,2772,1871,2458,1904,2441,1935,3004,1971,2300,2003,2341,2036,2372,2069,2179,2102,2234,2134,2254,2170,3128,2203,2969,2236,2953,2270,3141,2304,3199,2338,3209,2372,3290,2406,3316,2439,3288,2463,2395,2496,2329,2528,2313,2561,2318,2595,2421,2624,2156,2671,3026,2706,3111,2738,3037,2761,2467,2794,2467,2838,3007,2879,3362,2912,3350,2944,3280,2974,3107,3009,3156,3045,3270,3080,3331,3079,2063,3111,2057,3144,2058,3177,2077,3209,2077,3242,2077,3275,2077,3351,3367,;PU;SP1;PU6024,1288;PD6024,1145,;PU6028,1288;PD6028,1145,6024,1145,;PU5999,1296;PD6053,1296,6053,1288,;PU5999,1296;PD5999,1288,6053,1288,;PU6078,1296;PD6078,1145,;PU6082,1288;PD6082,1152,;PU6078,1296;PD6128,1296,;PU6082,1288;PD6128,1288,6128,1296,;PU6082,1224;PD6107,1224,6107,1217,;PU6082,1217;PD6107,1217,;PU6082,1152;PD6128,1152,6128,1145,;PU6078,1145;PD6128,1145,;PU6158,1296;PD6158,1145,;PU6162,1260;PD6162,1145,6158,1145,;PU6162,1260;PD6191,1145,;PU6158,1296;PD6191,1167,;PU6224,1296;PD6191,1167,;PU6220,1260;PD6191,1145,;PU6220,1260;PD6220,1145,6224,1145,;PU6224,1296;PD6224,1145,;PU6258,1296;PD6258,1145,;PU6262,1288;PD6262,1145,6258,1145,;PU6258,1296;PD6295,1296,6304,1288,6308,1281,6312,1267,6312,1245,6308,1231,6304,1224,6295,1217,6262,1217,;PU6262,1288;PD6295,1288,6304,1281,6308,1267,6308,1245,6304,1231,6295,1224,6262,1224,;PU6341,1296;PD6341,1145,;PU6345,1288;PD6345,1152,;PU6341,1296;PD6391,1296,;PU6345,1288;PD6391,1288,6391,1296,;PU6345,1224;PD6371,1224,6371,1217,;PU6345,1217;PD6371,1217,;PU6345,1152;PD6391,1152,6391,1145,;PU6341,1145;PD6391,1145,;PU6421,1296;PD6421,1145,;PU6425,1288;PD6425,1145,6421,1145,;PU6421,1296;PD6454,1296,6467,1288,6471,1281,6475,1267,6475,1245,6471,1231,6467,1224,6454,1217,6425,1217,;PU6425,1288;PD6454,1288,6467,1281,6471,1267,6471,1245,6467,1231,6454,1224,6425,1224,;PU6446,1217;PD6471,1145,6475,1145,;PU6450,1217;PD6475,1145,;PU6529,1296;PD6496,1145,;PU6529,1274;PD6500,1145,6496,1145,;PU6529,1274;PD6558,1145,6563,1145,;PU6529,1296;PD6563,1145,;PU6508,1188;PD6550,1188,;PU6504,1181;PD6554,1181,;PU6604,1288;PD6604,1145,;PU6609,1288;PD6609,1145,6604,1145,;PU6579,1296;PD6634,1296,6634,1288,;PU6579,1296;PD6579,1288,6634,1288,;PU6659,1296;PD6659,1188,6663,1167,6671,1152,6684,1145,6692,1145,6705,1152,6713,1167,6717,1188,6717,1296,;PU6659,1296;PD6663,1296,6663,1188,6667,1167,6671,1160,6684,1152,6692,1152,6705,1160,6709,1167,6713,1188,6713,1296,6717,1296,;PU6751,1296;PD6751,1145,;PU6755,1288;PD6755,1145,6751,1145,;PU6751,1296;PD6784,1296,6796,1288,6801,1281,6805,1267,6805,1245,6801,1231,6796,1224,6784,1217,6755,1217,;PU6755,1288;PD6784,1288,6796,1281,6801,1267,6801,1245,6796,1231,6784,1224,6755,1224,;PU6776,1217;PD6801,1145,6805,1145,;PU6780,1217;PD6805,1145,;PU6834,1296;PD6834,1145,;PU6838,1288;PD6838,1152,;PU6834,1296;PD6884,1296,;PU6838,1288;PD6884,1288,6884,1296,;PU6838,1224;PD6863,1224,6863,1217,;PU6838,1217;PD6863,1217,;PU6838,1152;PD6884,1152,6884,1145,;PU6834,1145;PD6884,1145,;PU6947,1245;PD7018,1245,7018,1238,;PU6947,1245;PD6947,1238,7018,1238,;PU6947,1188;PD7018,1188,7018,1181,;PU6947,1188;PD6947,1181,7018,1181,;PU7168,1296;PD7156,1288,7151,1274,7151,1260,7156,1245,7160,1238,7168,1231,7185,1224,7193,1217,7197,1210,7201,1195,7201,1174,7197,1160,7185,1152,7168,1152,7156,1160,7151,1174,7151,1195,7156,1210,7160,1217,7168,1224,7185,1231,7193,1238,7197,1245,7201,1260,7201,1274,7197,1288,7185,1296,7168,1296,;PU7160,1288;PD7156,1274,7156,1260,7160,1245,7168,1238,7185,1231,7193,1224,7201,1210,7206,1195,7206,1174,7201,1160,7197,1152,7185,1145,7168,1145,7156,1152,7151,1160,7147,1174,7147,1195,7151,1210,7160,1224,7168,1231,7185,1238,7193,1245,7197,1260,7197,1274,7193,1288,;PU7197,1281;PD7185,1288,7168,1288,7156,1281,;PU7151,1167;PD7164,1152,;PU7189,1152;PD7201,1167,;PU7256,1296;PD7243,1288,7235,1267,7231,1231,7231,1210,7235,1174,7243,1152,7256,1145,7264,1145,7277,1152,7285,1174,7289,1210,7289,1231,7285,1267,7277,1288,7264,1296,7256,1296,;PU7247,1288;PD7239,1267,7235,1231,7235,1210,7239,1174,7247,1152,;PU7243,1160;PD7256,1152,7264,1152,7277,1160,;PU7272,1152;PD7281,1174,7285,1210,7285,1231,7281,1267,7272,1288,;PU7277,1281;PD7264,1288,7256,1288,7243,1281,;PU7323,1167;PD7318,1160,7318,1152,7323,1145,7327,1145,7331,1152,7331,1160,7327,1167,7323,1167,;PU7323,1160;PD7323,1152,7327,1152,7327,1160,7323,1160,;PU7385,1296;PD7373,1288,7364,1267,7360,1231,7360,1210,7364,1174,7373,1152,7385,1145,7394,1145,7406,1152,7414,1174,7419,1210,7419,1231,7414,1267,7406,1288,7394,1296,7385,1296,;PU7377,1288;PD7369,1267,7364,1231,7364,1210,7369,1174,7377,1152,;PU7373,1160;PD7385,1152,7394,1152,7406,1160,;PU7402,1152;PD7410,1174,7414,1210,7414,1231,7410,1267,7402,1288,;PU7406,1281;PD7394,1288,7385,1288,7373,1281,;PU7469,1296;PD7456,1288,7448,1267,7444,1231,7444,1210,7448,1174,7456,1152,7469,1145,7477,1145,7490,1152,7498,1174,7502,1210,7502,1231,7498,1267,7490,1288,7477,1296,7469,1296,;PU7460,1288;PD7452,1267,7448,1231,7448,1210,7452,1174,7460,1152,;PU7456,1160;PD7469,1152,7477,1152,7490,1160,;PU7485,1152;PD7494,1174,7498,1210,7498,1231,7494,1267,7485,1288,;PU7490,1281;PD7477,1288,7469,1288,7456,1281,;PU;SP3;PU4622,1093;PD4622,1093,4654,1069,4686,1044,4719,1019,4752,995,4785,971,4818,946,4851,918,4884,896,4917,870,4951,842,4984,816,5018,791,;PU4624,1118;PD4624,1118,4656,1093,4689,1069,4721,1044,4754,1019,4787,994,4820,971,4853,946,4886,921,4919,893,4953,868,4986,842,5020,816,;PU4638,1264;PD4638,1264,4670,1239,4702,1215,4734,1191,4767,1167,4799,1142,4832,1118,4864,1093,4897,1069,4930,1044,4963,1019,4996,997,5030,972,5063,947,5097,918,5131,893,;PU4650,1382;PD4650,1382,4681,1359,4713,1335,4745,1311,4777,1287,4809,1264,4842,1239,4874,1215,4907,1191,4939,1167,4972,1142,5005,1121,5038,1097,5071,1072,5104,1047,5138,1019,5171,994,5205,969,5234,946,;PU4665,1545;PD4665,1545,4697,1522,4728,1499,4760,1476,4791,1453,4823,1429,4855,1406,4887,1384,4919,1360,4952,1335,4984,1315,5016,1291,5049,1267,5082,1243,5115,1215,5148,1191,5181,1167,5214,1142,5247,1118,5281,1093,5314,1069,5348,1044,;PU4676,1659;PD4676,1659,4708,1637,4739,1614,4770,1591,4801,1568,4833,1545,4865,1522,4896,1499,4928,1476,4960,1453,4992,1429,5024,1406,5057,1382,5089,1359,5122,1335,5152,1410,5185,1413,5218,1389,5251,1365,5284,1341,5318,1317,5353,1167,5387,1142,5420,1118,5445,1099,;PU4681,1704;PD4681,1704,4712,1682,4743,1659,4774,1637,4805,1614,4837,1591,4868,1568,4900,1545,4932,1522,4964,1499,4995,1476,5028,1453,5060,1429,5092,1409,5125,1385,5137,1374,;PU5339,1226;PD5355,1215,5389,1191,5422,1167,5456,1142,5479,1124,;PU4692,1815;PD4692,1815,4722,1793,4753,1771,4784,1749,4815,1726,4846,1704,4877,1682,4909,1659,4940,1637,4972,1614,5004,1591,5035,1581,5067,1558,5099,1535,5131,1512,5164,1476,5196,1453,5229,1429,5261,1406,5294,1382,5327,1359,5360,1335,5393,1311,5427,1287,5460,1264,5493,1239,5527,1215,5561,1191,;PU4694,1837;PD4694,1837,4724,1815,4755,1793,4786,1771,4817,1749,4848,1733,4879,1710,4910,1688,4942,1665,4974,1637,5005,1614,5037,1591,5069,1568,5101,1545,5133,1522,5165,1499,5198,1476,5230,1453,5263,1429,5295,1406,5328,1382,5361,1359,5394,1335,5427,1311,5461,1287,5494,1264,5528,1239,5561,1215,5583,1199,;PU4696,1859;PD4696,1859,4726,1837,4757,1815,4788,1793,4819,1771,4850,1749,4881,1726,4912,1704,4944,1682,4975,1659,5007,1637,5039,1614,5070,1591,5102,1568,5134,1545,5167,1522,5199,1499,5231,1476,5264,1453,5296,1429,5329,1406,5362,1382,5395,1359,5428,1360,5461,1336,5495,1312,5528,1288,5562,1239,5596,1215,;PU4700,1903;PD4700,1903,4731,1881,4761,1859,4792,1837,4823,1815,4854,1793,4885,1771,4916,1749,4947,1726,4978,1704,5010,1682,5042,1659,5073,1637,5105,1614,5137,1591,5169,1568,5201,1545,5234,1522,5266,1505,5298,1483,5331,1460,5364,1436,5397,1406,5430,1382,5463,1359,5496,1335,5530,1311,5563,1287,5597,1264,5631,1239,;PU4717,2074;PD4717,2074,4747,2052,4777,2031,4807,2010,4838,1989,4868,1967,4899,1946,4930,1924,4960,1903,4991,1881,5022,1859,5054,1837,5085,1815,5116,1793,5148,1771,5179,1749,5211,1726,5243,1708,5275,1685,5307,1663,5339,1640,5372,1617,5404,1591,5437,1568,5469,1545,5502,1522,5535,1499,5568,1476,5601,1453,5634,1429,5668,1406,5701,1382,5735,1359,5769,1335,;PU4725,2157;PD4725,2157,4755,2137,4785,2116,4815,2095,4845,2074,4875,2052,4906,2031,4936,2010,4967,1989,4998,1967,5029,1946,5060,1924,5091,1903,5122,1882,5153,1860,5185,1837,5216,1815,5248,1793,5279,1771,5311,1749,5343,1726,5375,1704,5408,1682,5440,1659,5472,1637,5505,1614,5538,1591,5570,1568,5602,1664,5635,1641,5669,1618,5702,1595,5736,1572,5770,1429,5803,1406,5837,1382,;PU4729,2199;PD4729,2199,4759,2178,4789,2157,4819,2137,4849,2116,4879,2095,4909,2074,4940,2052,4970,2031,5001,2010,5031,2019,5062,1997,5093,1946,5125,1924,5156,1903,5187,1881,5218,1859,5250,1837,5282,1815,5313,1793,5345,1771,5377,1749,5409,1726,5441,1704,5474,1682,5506,1659,5539,1637,5571,1614,5582,1606,;PU5756,1485;PD5770,1476,5804,1453,5837,1429,5869,1406,;PU4729,2199;PD4729,2199,4759,2178,4789,2157,4819,2137,4849,2116,4879,2095,4909,2074,4940,2052,4970,2031,5001,2010,5031,2019,5062,1997,5093,1946,5125,1924,5156,1903,5187,1881,5218,1859,5250,1837,5282,1815,5313,1793,5345,1771,5377,1749,5409,1726,5441,1704,5474,1682,5506,1659,5539,1637,5571,1614,5578,1608,;PU5756,1485;PD5770,1476,5804,1453,5837,1429,5869,1406,;PU4761,2199;PD4761,2199,4775,2696,4805,2676,4836,2656,4866,2636,4897,2615,4928,2595,4959,2573,5002,2031,5023,2016,;PU5068,1985;PD5095,1967,5126,1946,5157,1924,5188,1903,5220,1881,5251,1859,5283,1837,5314,1815,5346,1793,5378,1771,5410,1749,5442,1726,5475,1704,5507,1682,5539,1659,5572,1637,5588,1624,;PU5749,1512;PD5770,1499,5804,1476,5837,1453,5871,1429,;PU4999,2077;PD5005,2074,5036,2052,5067,2031,5098,2010,5129,1989,5160,1967,5191,1946,5222,1924,5253,1903,5285,1881,5316,1859,5348,1837,5380,1815,5412,1793,5444,1771,5476,1749,5508,1726,5541,1704,5573,1682,5601,1661,;PU5708,1590;PD5737,1588,5771,1565,5804,1542,5837,1519,5871,1476,5905,1453,;PU4993,2147;PD5010,2137,5041,2116,5071,2095,5102,2074,5133,2052,5163,2031,5194,2010,5225,1989,5257,1967,5288,1946,5319,1924,5351,1903,5383,1881,5414,1859,5446,1838,5478,1816,5510,1794,5543,1772,5575,1749,5607,1726,5639,1764,5672,1759,5705,1736,5738,1705,5771,1683,5804,1660,5838,1568,5871,1545,5905,1522,5938,1499,5968,1478,;PU4989,2193;PD5013,2178,5043,2157,5074,2137,5104,2116,5135,2095,5166,2074,5197,2052,5228,2031,5259,2010,5290,1989,5321,1973,5353,1952,5384,1924,5416,1903,5448,1881,5480,1859,5512,1837,5544,1815,5576,1793,5608,1771,5631,1755,;PU5813,1636;PD5838,1637,5871,1614,5905,1591,5938,1545,5972,1522,6000,1502,;PU5110,2199;PD5110,2199,5140,2178,5171,2157,5202,2137,5232,2116,5263,2098,5294,2077,5325,2056,5357,2035,5388,2010,5419,1991,5451,1969,5483,1946,5514,1924,5546,1903,5578,1881,5610,1859,5643,1837,5675,1815,5707,1793,5740,1771,5771,2340,5804,2319,5838,2297,5871,2276,5905,2254,5939,2229,5971,1614,6005,1591,6038,1568,6065,1549,;PU5142,2199;PD5142,2199,5172,2178,5203,2157,5234,2137,5264,2116,5295,2095,5326,2074,5358,2052,5389,2031,5420,2010,5452,1989,5483,1967,5515,1946,5547,1924,5579,1903,5611,1881,5643,1859,5675,1837,5708,1815,5740,1793,5740,1793,;PU5969,1640;PD5971,1640,6005,1617,6038,1591,6072,1568,;PU5173,2199;PD5173,2199,5204,2178,5235,2157,5265,2137,5296,2116,5327,2095,5358,2074,5390,2052,5421,2031,5452,2018,5484,1997,5516,1975,5547,1946,5579,1924,5611,1903,5642,2138,5674,2210,5706,2189,5740,1847,5743,1842,;PU5969,1660;PD5971,1659,6004,1637,6038,1614,6071,1591,6098,1572,;PU5205,2199;PD5205,2199,5236,2178,5267,2157,5297,2137,5328,2116,5359,2095,5391,2074,5422,2052,5453,2031,5485,2010,5516,1989,5548,1967,5580,1946,5612,1924,5613,1922,;PU5967,1683;PD5971,1682,6004,1659,6038,1637,6071,1614,6105,1591,;PU5269,2199;PD5269,2199,5299,2178,5330,2157,5361,2137,5392,2116,5423,2095,5455,2074,5486,2052,5518,2031,5549,2010,5581,1989,5613,1967,5618,1963,;PU5736,1883;PD5741,1881,5745,1878,;PU5965,1729;PD5970,1726,6004,1756,6037,1734,6071,1711,6104,1639,6138,1614,;PU5364,2199;PD5364,2199,5395,2178,5426,2157,5457,2137,5488,2116,5520,2095,5551,2074,5583,2052,5614,2031,5626,2022,;PU5729,1957;PD5742,1950,5749,1943,;PU5954,1935;PD5970,1925,6003,1903,6037,1881,6070,1726,6103,1704,6136,1682,6170,1659,6195,1642,;PU5491,2199;PD5491,2199,5522,2178,5553,2157,5585,2137,5616,2116,5638,2116,;PU5718,2070;PD5743,2054,5754,2039,;PU6048,1827;PD6068,1815,6101,1793,6135,1771,6168,1749,6202,1726,6235,1704,6258,1688,;PU5523,2199;PD5523,2199,5554,2178,5585,2157,5617,2137,5639,2121,;PU6031,1884;PD6035,1885,6068,1863,6101,1841,6134,1819,6168,1797,6201,1749,6235,1726,6268,1704,;PU5650,2199;PD5650,2199,5663,2189,;PU5709,2158;PD5713,2157,5744,2137,5758,2126,;PU5951,2000;PD5969,1989,6001,1967,6034,1946,6067,1924,6099,1903,6132,1881,6166,1863,6199,1841,6232,1820,6266,1793,6299,1771,6333,1749,;PU5706,2181;PD5713,2178,5745,2157,5759,2146,;PU5949,2022;PD5969,2010,6001,1989,6034,1967,6066,1946,6099,1924,6132,1903,6165,1881,6198,1859,6231,1837,6265,1815,6298,1793,6332,1771,6353,1756,;PU5946,2087;PD5968,2074,6000,2052,6033,2031,6065,2010,6098,1989,6131,1967,6164,1946,6197,1924,6230,1903,6263,1887,6296,1866,6330,1844,6363,1815,6397,1793,;PU5940,2194;PD5967,2178,5999,2157,6032,2137,6064,2116,6096,2095,6129,2074,6161,2052,6194,2036,6227,2014,6260,1989,6293,1967,6326,1946,6359,1924,6392,1903,6426,1881,6459,1859,6478,1846,;PU5967,2199;PD5967,2199,5999,2178,6031,2157,6064,2137,6096,2116,6128,2095,6161,2086,6193,2065,6226,2044,6259,2010,6292,1989,6325,1985,6358,1963,6392,1942,6425,1903,6458,1881,6492,1859,;PU6031,2199;PD6031,2199,6063,2178,6095,2157,6127,2137,6160,2116,6192,2095,6225,2074,6258,2052,6290,2031,6323,2010,6357,1989,6390,1967,6423,1954,6457,1932,6490,1903,6524,1881,;PU6063,2199;PD6063,2199,6095,2178,6127,2157,6159,2137,6192,2116,6224,2095,6257,2074,6290,2052,6323,2057,6356,2038,6389,2017,6423,1995,6456,1974,6489,1924,6523,1903,6556,1881,;PU6094,2199;PD6094,2199,6127,2178,6159,2157,6191,2137,6224,2116,6257,2115,6289,2093,6322,2072,6355,2051,6374,2027,;PU6464,1960;PD6488,1946,6521,1924,6555,1903,;PU6348,2199;PD6348,2199,6381,2178,6414,2157,6447,2141,6480,2122,6513,2101,6546,2079,6579,2058,6612,2031,6646,2010,6680,1989,;PU881,3609;PD914,3609,963,3065,996,3065,1028,3064,1061,3057,1094,3054,1126,3055,1159,3054,1178,3605,1212,3572,1245,3551,1278,3583,1311,3580,1344,3587,1378,3508,1411,3477,1444,3469,1477,3464,1510,3450,1543,3451,1574,3593,1607,3607,1641,3567,1673,3569,1706,3570,1739,3579,1772,3609,1806,3486,1842,3008,1875,2896,1907,2889,1938,3178,1972,2765,2004,2788,2037,2900,2069,2810,2101,2841,2134,2871,2168,3460,2200,3285,2232,3260,2266,3366,2299,3423,2332,3424,2365,3504,2398,3489,2431,3482,2457,2903,2489,2838,2521,2793,2553,2814,2588,2951,2618,2798,2659,3363,2693,3436,2725,3397,2752,3063,2784,3063,2822,3332,2861,3608,2893,3579,2925,3538,2957,3506,2991,3535,3025,3565,3056,3513,3075,2997,3107,2995,3140,3008,3174,3056,3207,3061,3240,3066,3272,3066,3323,3609,;PU0,0;PG;SP; \ No newline at end of file
diff --git a/PerlMagick/t/hpgl/read.t b/PerlMagick/t/hpgl/read.t
new file mode 100644
index 0000000..6edd21c
--- /dev/null
+++ b/PerlMagick/t/hpgl/read.t
@@ -0,0 +1,37 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test Reading HP GL images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/hpgl' || die 'Cd failed';
+
+#
+# 1) Test reading HP GL
+#
+$image=Graphics::Magick->new;
+$x=$image->ReadImage('input.hpgl');
+if( "$x" ) {
+ print "ReadImage: $x\n";
+ print "not ok $test\n";
+} else {
+ print "ok $test\n";
+}
+
+undef $image;
diff --git a/PerlMagick/t/input.art b/PerlMagick/t/input.art
new file mode 100644
index 0000000..efb783e
--- /dev/null
+++ b/PerlMagick/t/input.art
Binary files differ
diff --git a/PerlMagick/t/input.avs b/PerlMagick/t/input.avs
new file mode 100644
index 0000000..a6f4574
--- /dev/null
+++ b/PerlMagick/t/input.avs
Binary files differ
diff --git a/PerlMagick/t/input.bie b/PerlMagick/t/input.bie
new file mode 100644
index 0000000..8c6a1d1
--- /dev/null
+++ b/PerlMagick/t/input.bie
Binary files differ
diff --git a/PerlMagick/t/input.bmp b/PerlMagick/t/input.bmp
new file mode 100644
index 0000000..a714ce3
--- /dev/null
+++ b/PerlMagick/t/input.bmp
Binary files differ
diff --git a/PerlMagick/t/input.bmp24 b/PerlMagick/t/input.bmp24
new file mode 100644
index 0000000..622864d
--- /dev/null
+++ b/PerlMagick/t/input.bmp24
Binary files differ
diff --git a/PerlMagick/t/input.dcx b/PerlMagick/t/input.dcx
new file mode 100644
index 0000000..15897a6
--- /dev/null
+++ b/PerlMagick/t/input.dcx
Binary files differ
diff --git a/PerlMagick/t/input.dib b/PerlMagick/t/input.dib
new file mode 100644
index 0000000..e201c88
--- /dev/null
+++ b/PerlMagick/t/input.dib
Binary files differ
diff --git a/PerlMagick/t/input.gif b/PerlMagick/t/input.gif
new file mode 100644
index 0000000..3b7da34
--- /dev/null
+++ b/PerlMagick/t/input.gif
Binary files differ
diff --git a/PerlMagick/t/input.gif87 b/PerlMagick/t/input.gif87
new file mode 100644
index 0000000..05c17b0
--- /dev/null
+++ b/PerlMagick/t/input.gif87
Binary files differ
diff --git a/PerlMagick/t/input.hrz b/PerlMagick/t/input.hrz
new file mode 100644
index 0000000..32502f1
--- /dev/null
+++ b/PerlMagick/t/input.hrz
@@ -0,0 +1,3361 @@
+           "!"$""$""#"!"!!" " #! $! # " " " !    ! !"""""""""######"""     !   ! "!  "#"!! ! !"!"! " ! ! ! " "!!#"!#""$##%##%$#%$#%%$&%%&&%&%%%%$&%$&$$&$$%%$&'&''&''&(('((&(('()(),+-(')))*,,-**+)))(())()('(**+,+,+*+*)**)*++*,,,--/..1--/---+*++)*-++,*)+)(-*)-+*-*+-++-**.+,.,,0..000/.//-//-089:=>?467/140132343333212202103215435433334445555677986885665457777774547869:86757869=<9==8=>8=?7<?6<?6<?6=?7=?6=?7=?7=?7=?8??9??;??<??;??:??:??:??<??=??>??????????????????????????          !!  " !#""$"!""!"!!"!!#! #!!$! #! " " " ! !   ! !$#$$$%$$%$#$ !    ! ! "! " #! $"!! !! !"!""!#! ! ! ! !!!#""$""$""$##%$$&$$&%$&%%&&&'&&'&%&&%'&%'&%'&%&%$&&%'&%&('(('()())()('(+*,'&())***+(()(())(*(()(()**+**++*,**+*)+***,,---.../--/--/.-/.-..---++,*)-+).,+-++-++-++-++.,,0..212001/.1446<=?:<=023236235344444433422320543554554454455566688799588566666888999676565776887786:>;8=;6;;7=>7=?6=?5=?5=?6>?5=?6>?7??8??9??;??<??<??<??:??:??:??;??=??>??????????????????????????   !       !!  !  ! #!!#! !! !!!"!!#!!$!!$!!$!!# " " ! !!    ! "!"%%&%%%"!" !    !!!" " " ! " ! ##"#"!"" "! " ! " ! """$##%##%$$&%$&%$&%%&&%'&&'&&'&%&&%''%('%(&%'&$&&%&%$%(&()(*)())(*)')+*+)))))***,'')'')'&)'')((*++,**+((*((***+++,++,-----.-,.,,.-,.//00/0.--,+*-+*.,+-,,-,,-,,-,,.-,0//211113//2468<>?4782354463564663444334124217546545545654545776986885875775667779:9889667788;;:9:8:<96866:97;=6<>6<?6=?6>?6>?6>?7??7??7??:??;??<??<??<??;??:??:??;??<??=??>??????????????????????? !! !     !  "   " "   !!!#!!$!!$!!$!!# " " " """    " ! ! !  ! ! !""!  ! #$#$"!#" "! " ! " !!!!#$$&%$&$$&$$&%$&%$&&%'%%&&%&%%%&$&&$''%''%''$&'%'&$&&%&'&'(')('(('))(*''()))+*,'')&&)&&*''*((***-**,()+((***-+*,,,,,,,---,,.-,/--///0//0/./-,,-,+.-,-,,-,,.--.----,0//323224.02:=><>?3583354566893663454344124115326545545653544665884874775776887779:988977:889:;::;98774456788;<6:<6;=7=?7=?7=?7>?8??8??9??:??;??<??<??<??<??:??:??:??<??=??>???????????????????????  " !!!! ! ! !    !!!   ! ! ! !!!#!!$!!#!!!!! ! ! ! !!!        !!      " $!"$"## !" !   ! !! #$"%'&)%$'&$'%$&%$&&%&%$&&%'&%'&%''%'&$&&%&&%&'%''%('%''&''&'(&()'))')))*)(*((*((*'')&')&'*''+('+('+('*('*+*,**+**+++,+*,+*-,+.-,...././/....--,+-++.+,.,,.,,/--.--0//113103547<>?6:</041032137895673443332223114216535545655664664775776776778988996999;<9:;898998;;88656558888;:4985<:4;=6=?6=?6>?8??8??8??:??;??<??=??<??<??:??:??;??=??>??>??>?>>?????????????????  " !! !!! ! !        ! ! ! "! "!!"!!"!!" ! ! ! ! !     ! ! ! !!    " # !" !"!    ! ""!$'%(%$'#"%%$%%$&%$&%$&&$&&$&&$'&$'&$&&%&&%&'%''%((&((&((&('%''&'(&(('((')''('')'')'')''*''*''+''*&&)'&)*),))+**+**+*)+**,+*,,+----.-..-..---,,-,,.+,.,--,-.,-/////00030/2<<><>?4792251031135674663452331111//2105436646655664664675776877878978987::9;<:;=99:877::9;996558887885984985;<6=?6=?7>?8??8??9??:??;??<??=??<??<??:??;??<??=??>??>??>?>>?????????????????  ! " !!"!!!!! !    !! " " "! "!!"!!"! " ! ! ! !   ! "!!!  !" " "!!    !!!"'%(&$'%#&%#%%#%%#%%#%&$&%#%&#&&$'&$&'%&&$&%#&&$'(&('&'(&('%'&$&'&''&'(&('&('&('&)('*''*'')''*'&*&%)&%(('*))+**,**,++,,+,,+,,+--,.-,--,----,,,-,-.,-.-..-.--.../0/0014326?>?79<3682362143252353452341120/00/.11/4425535546565675675667878878868:77:98:;:;<99:889988<:99777666766886887;=6=?6=?8??9??8??9??:??;??<??=??=??<??;??<??=??>??>??>??>?>>?????????????????  ! " "! "!!! ! ! !  !!" ! !!!! ! ! " ! ! !      ! !!" " " "!    !!"%#&&%($"%$"$%"$%"$&#%&#%%"%%#&&$'&$&&%&%$%%#%%$&'%'&$&'&'(&((&(&%&(%'(&((&((&)(')'&)''*&')''*&&)&%(&%)(&*''*((***+,,-,+,+*+,+--+.-,-,,---.,,---.-,..-/--.-,...0/01-.187:>>?68:1560022144362252353461120/100/2203314424436566685675667869968858:78;:8:;9:;99;779778;99:887566566676887:<6<?8>?9??:??9?>9??:??;??<??=??=??<??<??=??>??>??>??=??=?>>????????????????? !! "! !"!!! ! !  " ! ! ! ! ! ! "         !! !   ! " "!"! ! ! !   !!""## $$"$! !# "$#%#"$#"$%#%&#&&#%&$%&$%%$%&$&&%'%$'%$'$"%&$&(&((&((%''$((%)(&)(&)(')'&((')'&*('+('*&%(&%)'&)'')((*))+**,**,++-**,+*,,,.--..-/--.--.--/--.-./.././1//3,-1<<>66:2251021123243363353353452230011022133233223226657776786666769:88968978:;8::89:799678778:88;988666555566887:<7<?7>?9??:??9>>9=>;>?=??=??=??>??>??<??<??<??=??>?????????????????????????? !!!! !"!!! ! !" !  ! "   ! " ! !   " !!!! ! !!!    "#"!#!!"# "$"$"!#! "$"$&#%&#%'%&'%'&$&%$&%$&$#&$#&#"$%#%'%'(&('%&'$'(%((&)(&(('('&('&(''*)(+((+'&)'&*&%)(&*)'+('*((+((+)),**-**,**,+*,-,.--.--..-/../.././0./1./2348=>?558225//1112325336335335446445002112213223222222553778889677777::98978978::8::89:799789899888::9;::5555666987:;8=?8>?9??9??8<<9<<<??=??=??>??>??>??=??<??<??=??>??????????????????????????  !! !!   !    !     ! "!"!! !    ! !   ! "! "!!"#!#$"$#"$"!#$"$$"$# "&#%'%''%'&$&%$%$$&$#%$"%%#%'%'(&()&('$'(%((&()')('(('((')('*))+))+*)+&&(('*)'+(&*(&*(&*('+((+*),**,**,*)+++,,,-..//.0../-./.././1..2;<>6792253360/210322533633544644634533422322322333355477677777877888888978878889989:79978978989:7989::<<=7775556765887;=8=>8==8=<7;:9;::<=>??>??>??>?????=??<??<??=??>?????????????????????????? !! ! !  !        !   ! " !   !!  ! !" !    !! " !" "#!##"$#"$$"$$!$#!"%#$&$%%#%%#%$#%$#&%#&%#&%$&&$&'%'(&''$'(&()'))()('()((('(''))(**)+**,)(*)(**(**(*(')(&(('))(*))+**,**,**+**,++,.-.../../-./.././1225=>?66811433610410432533633533533433433533522433445477688777788877877877888999:88978989:89:7::8::99:778989:896556656888;<9==8=<9<;9<::;:;==>??>???????????=??<??<??=??>??????????????????????????   " !     !      ! " " ! ! !  !  " "  " #! ""!##!##!##!##!##!#$"$%#%%#&%#&$"&%#&%#&%#%&$%'%%'$%'$&'$%(&')'(('(*(**'*)&*)'*)')*()+*+*)+)(+)(*))+)()'%'(&'*'()()+*+**++++*++*++++,--..-0.,0..1..15788:>/062260/33151043263363353353343454453463453452335558877876766767875667889:;78977888989:8:;7:<69;678877<999647649:9:<;999:999998:9;>=<?>=??>?????>??=??=??>??>?????>??=??=????????????????????!" !! " ! !    ! !  !! ! ! !!  "! ! " ""!##!##!##!##!##!##!##!#$"$%#%$"%$"%$"&%#&%#%&$%'%%&$%&#%&#$'$&('(('()')*'**'*)'*)'))()*)*)(*((**(*+)++(*)&(($&*&(*()*)**)*********+**+++,.-/.,0.-1--0=>?79=./4337/.12151142152263363363363364464575684561123337777876766765555666779:;8897787777897:;7:<68;678877;888547549999:;88:87988:8:;;>?;??<??=??=??=??<??<??=??>?????>??>??>???????????????????? "  " # !! !   ! !!   !  !     !!  "! #"!##!##!##!##!##!##!##!##"$$"%$"%$"%$"&%#&%#%&$$(%&'%&&#%&#$&$%('(('()')*'**'*)'*)())())()(')'&))(**(*+(*+(*($&)%'+)*+)*+)*+*+***+*++++,+-.,/0-1.,0548<<>/05005/.2-,/2252352263263374474364465575586695682243346567766656666665567887786787787777897:;7:<8;>79:99:998866976999:;<::<86998:9:<:>>:??;??<??<??<??;??;??<??=????????>??>????????????????????!!!"!!  "    !   !  !!       ! "! ""!##!##!##!##!##!##!#$"$%#%$"%$"%$"&$"&%#%'%%(%&(%&'$&&#$&#%'&'('()')*'*+'+*'**(**)**)*)(*''*((*))++*+,*,*')%#$*()+)*+)*,*++*+++++*+-+-.,/-).0.2>=?99<--3115.-1.-02242363464474464464454465565696696693354455567766666666666568788897787788887998:;7;=6:=7;<7;;9;::;9:;:8899:;==>;:<98:;<=:>>9??:??;??;??;??:??;??<??=????????????????????????????????" !        ! !    !!!" !" !" "#!"#!"#!##!#$"$%"$$"$$"$$"$$"$$"$'%&(%&(%&'%%'%&&$%'&'('()'))'))(**(**(**(+*(++),*(+)'**)*++)--*0/.*)*)()+*++*+,+,-+,-+,,*,,+..-1:9;>>>==>/.50.3204-,.1121132353453444564454464466685675785784574475477578788896795676778887867868879999;;9;=8<=9>>8<=8<<8::==;:98988;;:::9:<<9=>9>?9??:??;??:??:??9??:??<??=??>??>??>??>????????????????????         ! " !#!""!"#!##!##"#$"$#"$#"#$"$$"$$"$&$%'$%&$%&#$%$%&$%'&'(&()'))'*)'*)'**(**(+*(+*(+*(+)'**)*,+*,+*,+*/./+*+**+*++,,,,,-,,----+*,324>>???>>>?/.30.20/2//022312323534534545644644644666857857857856855864776798999;89;568677777787887887998:;<9<=8<<:=>9=>7:;8::<<<8886554435559;:9==9>?:??;??<??;??;??:??;??<??=??>????????>???????????????????? !!   ! !"!""!""!##"##"##"#"!"! ""!##!$$"$%"%&#%&#%&#%%#%$#%'%'(&))'*)'*(&))'*)'**(++),,*,+),*)+*)**)*+*+*)),*++++++++++,,,,,,,,-,,--+.214?????>???//40-2.+.0.021222233433533444555744744755857957946856866875776787999;89<79;88:788778777665998:<;9<<9<<9<=9<>7:<79;9:;9896676567779<;;??9>>;??<??=??=??<??;??;??<??>???????????????????????????????? !"  !!!!!!!"!"""#""#""#!!" !!!"#!$$"%$!$%"$%"$%"$%#%&$&'%''%()'*(&*'%)(&*)'**(**(++)+*)**)+)(*)(*)()*(**(),*+-+,,+,,+,-,--,--+--,/-,0?>?;<<88;.-30-1.+-20143322222322322433555855855865956946846745766876787877988;9:=:;>89:6786677778879989;:9;;9;;:<=9<>7:<9;=:;<::;::;656898:<;:>=:?>;>?<>?=??>??<??<??<??=??>????????????????????????????????    " ! ! !! ""!#! ""!#"!#!!#! #! ###%%$&$"$$"$%"$$!#$$&#'(&*'&)'')'&)&%('%((&))'**(+*)*)(**(+)(+)(*)(*)(**(*+*+++,-,-.,./,//,/.+/,+1..2<=?==?336/.12.2/,/11255633421332522522544666866866766966966865775696798977978:8:=9;=79:6786687679879979:8:;9:::::;:;>8:>8:=:;=::;<:;645666899:==9>=;>?<??=??>??=??<??<?>=?>>????????>??>????????????????????   " "! "! #"!#!!#! #! #"!$""$%$&$"$$"$%"$%"$%!$&#&)'*((*''*('*'&)'%('&)(&))(*)(*(&((&))(+)(*))*)()*()*))+**-+,.,-/,./-/.,/+*-99;:;=015..20/31/20.0/./666456446336225225446667778667569568658657767:8898977967:8:<9;=79;7896786668878868879:89989:::<>9;>8:<9:;9::>=>7786669:;;>=;?>:??<??=??>??>??=??<?>=?>????????????>????????????????????   !! !  !!!"! !! !"!""!"! " !"!#"!$! "! "!!# "#"%#"%$$&%#%$"$%"$%"$&"$&$%(')((*'')'&*'&*(&)(&)('))'*'&'%#%'%')()(()))**))+)*+(),**-*+.+,/,.0./0.0,,.<=>89;..1003//2/.1/.0-,-11266735623622533544655667877866956866876776797898977978:79<79;68:78979:888876764775998::9::::<=9;>8:<9;;9::<==>>>667;;<<>>;?>:??;??=??>??>??>??=??>??????????????>??>??>??>??????????? !      "! "! !   "!!! ! !  "!#$#&"!#"!#$#%#"$#"%##%$#%%$&%"$$!#$!#%!"'$%'&''')&&(%%(%$'&$'(&))(*)'*&%'%$%'%'(&(('((((***+))*'',()-*+.+,/-.0.//-/658==?./1./0//00/1..0../.-.---56724523622533644644555777867:669769768867:89:9:88:89;79<68:68968979:899776865876:989989:99;<8:<8:;:<;:;;9::==>999;<<=>?;>>:??;??=??>????????>????????????????????>??>??>??>??>??>??  !!!!  "!!""! !  ! ""!""!#&%&)()'&(%$&$#%%$%"!#"!#" "#!#&$&%#&&#'&$''%(%#'$#'&%(((+'')%%&%&&&&('&(('))(**)*+)*+&'-()-*+,++.,-1/00.0<=>67;..4//3//1000//0../-,.,,.00122412413545745744655777857867867878977988:99;88;99=78<67;56979:8::788766766998;;:98999:8;;8;;:==9<<:=>79<=>?=<=;<;;>=9=<:?><??<??=??>?????????????????????????????>??=??=??>?????  ! !! "! !       ! !"!"#"$%%&%$&%$%%#%" ""!"%#%%$&&$&&%''%('%)%$(%$(&&(&&(%%'&&(''('&()(*+)++)*+)*,()-)*,)*,*,-+--,.546;<?237//4/.2/.00//../.-/-,.--.--.11211323545756745655756756867967967977978:89:89;:;>88=67;68;79;89:788878999<=<:;:88989:79:8:;;>>:==9<=9;==>?>>>::9<=<9=<:>=;?><>>=??>?????????????????????????????>??=??=??>?????   !! "! "! " !!          !%$&&%&&%'(&($"$('(&%&%$%%$&%$&&%''%(&%(%$'%%'$$'%%'&&(&&(&&'*)*,+,,*+-+,,*+,*+,*,,*,-+--,.;;<89=//30/3/.10.00.0../.-/--/../..0//022312345655756855745756877:67967978:78:89:;=>;=?:;?79=8:>79<79:889889:;;<>>;>=8:;79:78989:<=>:==9<=9:<::;>==:98<><<>=:>=;>=<>>=??>??>??????????????????????????>??=??=??>?????! !!   !!! "! " " !!        !$#%&$&#"##!#!!)())))(((%$%""#%$&&%'&%(&%(&%(%%(%%(%&(&%'&%'(')+*,,+,-+,,+,,+,-*,.+.,),/-0::=/05./2//20.11-01-0../-,.--/..0//0../00133433456867956845865866967:67:78;79;8::;==<>?:<?8:?7:>79=89;88:88:9:;;==:>=9<<699788889;<=;==:<=9:<;;;>=<;:9<<;;=<;>=;==<>>=??>??>??????????????????????????>??=??=??>????? !! !! "! ! ! " " ! ! " ""!"!!   !!!#"!#"!$!# "  $#$%$%$#$"!"$#$&%&&&&&&''&'&&'&%'&%(&&)&%(&&(((***+,,-,,-,+.-+/,*/*)-67:89;--/0/00/01/00/10/1//0--..-//.0..0/.0//12242354685695585484586797899::88:89;:9;::;<=?9<?9<>9<>9;=89<79<8:<8:;;<=:<<9;<79;77;99:;<<;=>:=?9<>=>?><<<:9;:9==<<>>;>><??<??=????????????????????????????????????????????"""!!!!!!"!!" ! " " !"!!" " !!!"!!!    !! ""!#"!#! " !! !" !" !   "!"'&&'&''&''&''&('&(&%'&&)&&(&&('')''(,,-,,--,..,0-,0.-1==?246.-//-/0./1/01/10.0/./../..//.0/.0/.1//11123463574585696595586696789:;89:88:979:9;<=?;=?<>?:<>9;=8:=79;9;=9;<:==:<<:<<89<77;9:;<=<;=>:=?;>?=>?===<;:<;;==<<>>;==<?><?>=????????????????????????????????????????????""#"!""!!"! ! " " # !"!!"!!#!!!!!"! !      !!!"! !  ! !"!""!"! #""(('*)))()(((''('&(''*''*'')(')(()++-,,-,,.-,0,+066:<>?,.0-,-/-.1..1..2/01/1/./../..//.0//10/10/1.-/23445646756867956856855878:9:;89:98:;;<;<==>?=??:<>8:=8:=79;:=><>?;>>:<<9<<78;88<99::;:;==:<?;>?<>?>????><<;=<<<>=;><;?=;>==?>??????????????????????????????????????????###"""#""#""#"!"! #!!$!"#!""!!$!!# !"!   !!   ! !" !" !! !! ! ! !! $$#***+*+***('(''*('*'')((*'')++,*+,++-,,/++/:;>247')+,+,.,,1..1..2/01/0/./.-/.-//.00/10/20.00./../3454675785785675684586699:;899889::;9<;=??<??:=>8:=7:=7:<;>?<??<??<?>:<=78;88<99;8989;<:<?;>?<??=?>>?><<;<<;<><;>=;><;><=?=??>???????????????????????????????????????##$$$$$#$$###""#!!#!!#""#""#""$""" !!    !!    ! ! !! ""!"#"#$#$(''-,,*)))((''(&')'(*(())()+)++),**-236:;=))-+*.,+.-+,/,-0..0/////../..//////00010010/10.00-/1/055566757946856966966988989998:98:899;==;>>9=?7;>6:=8<>;??:?>;?>:>>;??8;=79:::<9:;7::9<<;>>;??;??<?>==<><:==<=>=:=;<>=>????????????????????????????????????????????$$%%$%%$$$#$$##$""$""$""$##%##%$$! !!!!!!!!      ! !#!#$#$%$%#"#%$$,*+,++))*'()()*))*)())')*),++.::=458*)-,+/,+--+,/,,0-.0.././//////0/00/01111110011/10/00./32356745756867967:67:88999999:98;89:9;<9;=9=>7;>69>:=?9<>9<>9=>9=>;>?8;<89;:;=89;56879:;==<??;??<?>>>=<;9<<::;9:<;<>=>????????????????????????????????????????????$$%%$%$$$%$$%##$##$#"%##%$$%$$%$$ !!"#! " "!!!       "!"$#$$#$$#$%#%$#$&%&+++)*)())))))())'))'*..1:;=--1-,0--0,+-,*,/,-/--/--..././0/00/00/01011010011022011001/033544645756967:77:77988988:78:67:78;79;9<=9<>9<?:=?9;?8;>8;>9;>=??:=>8:;:<=:;=668789:<<<??;??;>=<=<==;;<:;<;;><=?>>?????>??>??>??>??>??>???????????????????????$$%%$%$$$%$$%##$##%##%$$%$$%##$## !" "# $! #!" !!!      #"#%#$$#$&$&%#%#"#$$#)*()+)))(('()'))(+335558)*-,,/-,0,+--+-.++/,-.,,.-./-.0/01/01/01011010/111221221110121255735656967:67:77878889:77;57;57;79;7:;<>>;=?8:=9;?8:>8:=9<==??;>>8;<9<=;<>77:98:9:;;>>;?>;?=<=<=>;<<:<><=?>=?>>?????>??>??>??>??=?>>??>????????????????????##$$$$%$$%$$$#"$#"%#"%#"&##&#$$!" !! ! !" !#" ##!! !  !    ! #!!$##$$%$$%##$##$###''')(()((*')+),78:*,.(),.,/.,.,+-,+--,--,-.,-.,-0-/1./1//10/1000/00/010211221321210254664766967;78<67:77979968868869979:79;9<=<??8;=:=?:=?8;=:<>>??>??:<<<=>=>>:;<89:;==:??9??:?>=>=?><><:>><=?><??<??=??>??=??<>><?><?>=??>????????????????????##$$#$%$$$##$#"$#"%#"%#"%"#%"$#!"  !!!! !"! ! ! ! !!!     ! ! """##$$$&$$%$$$$$%$#$&%&*(*)')/.0235'(*)*,,+-.-.,,-,+--,--+--+-.,-/,.0-.0/.0/.0///./0/021222321221211233477966967;79<67:56866778946668979:69:7;<:??8=>9=?9>?8<?:??=??>??;=><=>;==;<=8::<>>;??:??:>==>=?=<=;9<<;=?><??<??=??<>=;==:==;>><>>=??>????????????????????##$$##$##$##$#"$#"%#"%#"%"#$!#!!  !!!! !!!!     ! ! ! ""#$$%$$%##$$#%$#%$#%(&(('(667..0((*))+)))+*+,+,,+,-+--,--,-.+-.,./-.0..0/./..///00122232322232321211177779968:78;77:66965754622367879:68959:8<<8<>9=?9=?8=?:??<??=??<??<>>;=><>>:<<;??;>?;??;>=<=<>><==:<<:<=<=??<??<??;>=:<<:>=;??<?><?>=????????????????????$$$$#$$$$$##$#"$""$#"$"#$"## #  ! !!!!! " " " ! ! !      !!!###$"!##"$##%$#%$"$(()999))*'&(('))))((()))+++,*,-+--+--+./,./--0..0../.././0002112222222112212223428::57867:77:65864653554667879:69:69:8;<8;=9<?;>?:=?;>?<??;>>=??<>><??<??<??:>>;>?:>><>><=<>><==;<<;<<<=>?<??;?>;>>:==:>=;?>;?><?>>????????????????????$$$###$$#$##$##%##$########!!! ###"""! !!!!!!!! !! !! !!    !!!!#""$##%$#&##& #447/02%%'(')(&()'))'(*'),),+*+,*,,+-,,-/,,/,,/--/-----///11221220221221221342521255667878977876755766867879:79;79<69<9<?8;>8<>9=>:>?;>?;=?:=?:>?;??<??=??=??:==9<<:<<<>>;<<<=<<<:>?=;=<;><<?><>?<>>:==:=><?>=??>??>>>??????????????????$$####$##$##$##%##$########!!!"""###"""! !! !!!"!!"! !! !!      !!"##$$$%##%""$&&)88:'()##%'&((&((%')&()'(+)++*+,*+,*,-+,/++0,,0--0-..,-.,-1/02111002123233132134342137786787787787686687789:;8:<79<79=9<?8<>8;=9<>;>?<??;=>;>?;>?;??<??=??=??<>>9<<:<<<>>;==:<;==;>?=;=;:=;<?=;=<;><;><;>=<?><?>=??>????????????????????$$$$$$$$#%$$%##%##%$$$$$###!!!###$$$"""! " !! ""!"! "! "! ! !       !##$$#$$#% "657336""$$$&%$&&%&'%'(&'('')()+**+)*+)*,*+.**0,,0--/--.,-,+,0//2111003234233232134353346568797787897797797898:;79;8:=8;>8;>7:=7:<9=>:>?;>?>??>??<??<>?<??=??>??=?>9;:9;;:<<<>><>>>>=9::5767:98;:<>><>=;><;?>7<<8=>1578:<??????????????????%%%%%$%$$&%$%$$%$$%$$$$$###!!!"""$$$###"!#! "!!#"!#! "! "! ! !      ""#   ! !     """$$%##$""#%$&99:)*,"#$%%'&%'%$&'$&'&''&&(((+**+))+)),**.++/--0../-----...///2103214334334234343343233137788998:;78:7687789:;68:8:=8;>8;>6:<69;:=?:=><??>?>=?>=??;>?=??>??>??>?>7987999;;<??9;<8795688:<7:;69:9;=<>>;?>9>>.4527;-168;=??????????????????%&'&&&%%%%$%%$$%$$%$$$$$### !""###$#"#""$""$"!$""%"!%!!$! #! !  !     !!   !!    #""%%$""# "--0668$$&##$##%$$%%$%$$%%%%(&')('+*),*),**,)*-*+-+,//0../,+-.,.0.021142253353353343343333322466888:99:78967878989;78:9:=:;>8;>6:<8<=:=>;>?>????????>??=>==?>>??>??=??9;<9;;<>><>?:<=89;;<=>>>>??:<=8;<7<>6:;48:/59/7=,2869;>?>????>??>>>?>>?>%%&%%&&%&%%%%$$%$$%$$$$$!!! !""#""#!!"""$""$#"$""%"!$!!$! #! !  !         "!!#"""!   !!!! !$$%557++-""$##$#"$""###$$$%$$$&%&(('*)(+*),**,*+,*+.,-/./../,+,)(*.-.11132233233244344343243443521377999:9:;89:78989;89;9:=:;>8;>7;=8<=;>?<??>????????>??=>>=?>>??=??=??<>>79:9;;;===??>>><<<8878:8:><9?=7>=399:>>/58,28049457=>>>????????>??>??&&'%%&%%%$$$%$$&%$%$$$$$ !""#"""!!"#"$""#""$##$""$"!$"!$! "! !      " " " !    ''(446%%($$&##$""##"$###$$$%%%$$$((')('+*),++-+,-+,--.../-./.-/)(*-,-11032222243344344344344444511355799:9;;9::78989:9:;9;<9;=8;>9<>8<=<??<??>????????>??>?>=?>=??=?><>>;=>8:<9;=<>>>?>>><>==8873549=;8>:7=<0457:;37:.38249:;==?>>?????>??;<=8:;&&'&&&%$%$$$%$$&%$$$$##$ !""#"""######""#!!"""#"!#!!#"!#! "! !   !         667--/ !###%##$""$""##########$$$%%$'(&**),++-,-,,,+++,-.-./-./)(*-+,0//2001//3124235333324445464353358898:99::78889::;<9;<9;<9<>9=>9==<??<?>=?>??????>??>??>??=??=?>=?>:<=9:=;=?=??=?>>?==>=5565679;;8<979;357./2+/4(-4'*179<=?>>??=>?<<>68:57:&%%&%%%%$$$#%$$$$$$#$""# !!"""#""$""#"##!""!""!""""!!" !! !     ! ##%567$%& "!""!"#"###$$$%""# !  $$%&&&)()**+,,-,--+,,+,,../--.+*,--././../0/11/14234232124355465564457788999::9;:9;::;<9:<9:<9;=:=>9==<??>??>?>???????????????=>>=??:>>8;;9<<<??=??=??=?>>>>555666:<;8:98::9<=027.17),2)+089<=??7;>04;27<59=6:<$$#%$$%$$$$#%$$$$$$#$! "!!!"""#!"$!"#!""!"! !!!!!!"!!"!!! !!          !,-...0 !"!! !!!"""###%&&!""#"#&&&&%&('(-,-,--+,,,,-../++,,+--,-.-.-,-.-/0/021232222343554666743566789::;;;<<;;;;;<9:<88;8:<9<=:=><??>??>?>????????????>??>>>:<<7:;9<<;==<?>=??>?????;;:998<<;::99:98:936659:59<58;357<??9??4;=6;>16;8<?;??$$$$$$$##$##%$$$$$$#$ ! !!!#!"$!"#!"" ! ! !!!!!!"!!!! !      ! #"!  ! !345 !" ! "!!!!!"!!###'''&'&"!"&%&&&&'&'+++---++,++,-,-)(**)+.-..----.--...//00121223445657667556556889<<<<<<<<<::;88:88;8:<9;=;>?=??>????>???????????????<<<9;;:<<<>>;=<=>>>?>>?????==<==;==;;<;;==9<;1558==:??6:;6999>>4;;39;8=>9>?:??9>>$$#$$#$$#$$#%$$$$$#"#  !!!#!"$""#!""!" ! !!!!!!!!!!! ! ! !   "! "!!)))--/ ! "!!$$#%&%$$#"!"%%&&%&''())),,,++++++-,.(')*)+-,----.-.../.././/122334445657778657445768<<==<<<<<::;:9<:9<:;=:;=<??=???????>????????????>>>=>>;<<=??=>><=<=>=>?>>?>=??>?><>;=?<<?=9==9=>4787<<8==:??9=>8<<7;<368468:>>:?>9?>##"##"##"##"$$#$$"##"  ! !! "!!"""""""""!!!! !! !! ! !! !! !     "! 223&%' ! ! "! $##%$%##"%%%%$%('())***+,*,,)+201,*+*)),,,---////.0..///1002324445656777666333665;;<<>>;==8::88:9:;9::;<<>??>??>??>??>??>??>??>??>??>??>??>??=>>=>><>=<>==?>>??=>>=>><>=;==9;::==8==8>>8>>:??8<=8;<69;3792690576;;;??#""#""#"!#"!##"#""""!  "!!!!!"!""""#"#""#"!"!!"!!!! !    ! #""$$%../! ! "! $#"###$##%$$%%%&%&**+-,-,+,-*+0-.311-,+,,+--.000//0..00/10/1223546556666666555443;;<<=><>?:;<99;::;:;;;<<>??>??>??=>?=>?>??>??>??>??>??>??<===>><>=;=<<>==?>>?>>??=?>;<<:<;9;;9:;79:8;<;??:??8=>6;<15725847:7;=5:;8==#"!"!!"! "! "!!"! !   "!"!!!!!!"""""#"""""""!"!!"! !! ! !      ,,,$$$  ! $#!"" ##"%%%&&&'&'(()+*+,*++()-++0.-/.---,--.///../..0/.00/1112445556667666665444999<=><>>:;<9:;::<=>>=>><=>>??>??>??>??>??>??>??>??>??>??<=><==;=<;=<<>==?>=?>>??=??<==9;:9::8:;8:<69:69:8<=8==8=>6:=7;=57969:278399#"!"! " " " "  !!!!!!! !"!""!"!!""!""!"!!! !! !    
+   ! !+,+"""$$#  ! #" !!###%%%&%&'&''&'(((+))+((+((*((--+..---...///0//01120/1102334556556555666444344<=><>>:<=::<::<<==>??>??=>?>??=>>=>>=>?>??>??>??>??>??<<=788:<;;=<;=<<?=<?>:<<8::=?>=>>;<<8;;8<=;=>8:;9;<8;<5:;49<7;=79:03438929:$!!$!!" "! "!  !! ! #"#""""!"!!""!""!!!             )*+$%'" !$""" ! $#!" "$!"%"$&$&%$%&%$(''*)*)())))*))***++*-...//.//012023.01102223445445445556545444:;;;=>;=>:;=::<<<=>??<??<>?<>?<>><<===>???>?>>?>??>??>;;;:;:<>=:=<:>=;??;?>9<<8::99:6777888:;;>>;>>:>=9>>8=>28:28;48;48:479388287$!!$!!#! !! ! !! !!! " $"#"""!!"!!"!!""!!  !!  
+
+   335 !"#!!%$$"!"  ! %$"#" !" $"#$"$$#$%%%'&&'''('')(())))())()))),,,....//011012012113223435445445555767777688<>>;=>:<=::;<<=>??<??;>>;=><=>;<=>??>??>>>>>>==<<=;;;:<>=;==:=<:>=;??;??;>>8::677344677>??<>><??<??:??:??9>?9??:??9>>6<=289-45""!"" "" "! !  ! ! ! " !$"#"##!!"! !! "!  !!   
+ *)+))+ &$$$#$""#! ! #" "!" !! "!!"!"##$%%%((''&&&&&('')))))))()*))+++---..//00012012223224335445445556766887676=?><??<>>;;<<<==>?<>><>>;>><>><>><?>=?>9:::;:;;::;9<<;<=<;==;>=:>=;??;??<??8994555665668::899<>=<?>;?>:??59:2683785;96<;5;<39;!" !! "" "! "!  ! !" $!#!""!!"!!"! !   !!!  
+
+ 001!!$#$$#$#""! " !!" "! ! !"!#""#$%%(('&&&&&&'&&))))(()()***,++,,,..///0001113113113223445445666766776787;=<<?>=>>;<<<<=<=>=??<>?;=><>><??;?>=??>??>?>>>>=><<=<<>=<>=<?>;?>;??;??=??:;;233899899788899<?=;><<?>9==1460052468=<8>;6;:499!!!! "! !! ! !! !" !!!!! ! ! !! !!        
+
+     %%&+++! $#$$$$! !   " "! "! "!!"!!#"#&&&''&&&&%$%('()())(**(),**,,,/00.//011555445324435434545657777878878:;;<=><>?;<=:;<;==<>=;><;>><??=??>??>??>?????>??=>=<=;;=<<=<<>><>>=??<?>=??<=?56888:779889<>><?=:><8=;59:2461268;;8<::?<5:8276! ! "! !    !!"    ! !!       
+ 
+
+   002 ###### !! " " " "! #""###$$$''''''%%&&&'(&('&(*(),**,,,000/0001133455644544533455654677787877799:<>><>?:;<::<;;;:;::;;<==<>>=??>??>??>?????>??=>>=>==>>=>><>><??=??<?><?><??<=>778777899<>>;>=8=;6:96993673688<<6;:6;:/34258! " "! "     "" !!! ! !! ! !    
+
+
+    !001%$$$#"!  ! " ! ! #""%%%$#$%&%((((()((('&''&(*(*,*+.-./0//10010122445445334223445334766988777899=>><>>;=>::<778787;<;<==<>>=??>??>??>?????>??=>>=?>=??<??<>?<??=??<??<??=??79:9:::;::<::=<8<;9=<8;;8;;4772775::287167046158" # #! " !   """!" !  ! !!!   
+  
+  ++,""# $$"#" "!" " " "! #""$#$$$$''&((()))+*+*)*+*++)*,*+....///10010111456667455334234345666988888777<===??=>?89:8:::=;:=<;>=<>?=??>??>??>?????>??>>?=??=??=??;>>;>?<??;??:>?8;=68:<>>>??:=;8<96;:8<<8:;:<<<==6997<;4;:7=<2977><!!"!!!! !   !!!   "!!! ! !      
+
+ 
+   /.0#"!#"!! !!! " $""#"!%%$)'('&'('()))******++++++,,,///010/00000556889778445445667677888888777:::>??=>><=?:;=:<<;=>;>><>>=??>??>??>??>??>??>??>??>??<??:==:>>;??;??9==9;<79:=??:>>6::7;:7:98;:8;;;>><??7<;6;:8=<6<:1854:8"!"" "! "! !  ! ! !!  ! ! !!  ! !      
+
+  
+
+    ++-%$&  #!!#!!!! ! " %#"$#"$$#&%%'&&(''(''''')**+++,,,-..///111/00.//133799789355456578566677888988999>??=>><=>:<=9;<:<=;==<>?=>?>??>??>??>??>??>??>??>??<>>;>=<??;?>=??=??<>>:==<??:??7;:9<;7::7:9698:==:=<6992556985978<::><#" #" #" #"!"! !!!"!!" !  ! ! !   !!       
+
+  
+
+
+
+  001   "! $#""" ! !$"!#"!""!%$#&%%&%%'&&(()))*))*+++-...../00///.//012467688577678467466566888999888=>>=??<??;=>;=>:<<:<=<=?=>>>??>??>??>??>??=??=>>>??=??=??=?>=??>??=??<??<??;??;??8::9<;7::8::466476699277366465:;9<?<9>:""#" #" "" "!  ""!"#!"# !" "!!! ! ! !          
+ 
+
+
+
+
+
+
+
+
+
+       "'&(   $#"##!! !#! #"!""!#"!$#"$#"&%&(()))*())*++-.-./.000/0/../001445556556446//0233344888888666:;:=??<??<>><>>:<=:;=;<>=>?>??>??>??>??>??>??=??>??>??>??>??>??=??<??;?>;?>;?>=??7999;;:<<<>>9;;5768<<298598576;=:;>:9?:""!"" "" "" "!"#!"#"""!!!!! " "! !! !     
+   
+
+
+
+
+
+
+
+  
+ ++-  !!!#"!##"!! "! ##"""!##"##"$$$&&&(()))))(*++,-----,222111//0000345345346../0/0533433877888667667>>?=??=>><>><=><=>;<=<=>>>?>??>>>>?>>?>?????????>??>??>??=??<>?<??;??<??=??>??8897888::;>=7;:5988<;7<;7;96:79>9;?9;?9$####""" ""  ! !"""#""#!!""!!" ""!"" !!  !        
+
+
+
+   
+
+
+
+
+   ))* !! ##"%$###"""!##"##"$$#$$#'''((()))(()(')++,...--,000222112000456235224.-.211644654987877888778=>>>??=>>=>?<>><>?=>?<=>==>???>??>??????????????>??>??>??=??<??<??<??<??=??=>>7876766876:97;;7:;8;;6:97;97;88<8:=9<?:$#$###""!! ! !!!""#$##$""#"!##!##!"" !#""! ! !     
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+      *),   $$###"""!#"!#"!##"%%$&&&((((()(()''(***../--.--.333222010233123334///433654765876776998777;<;=?><>><>><=>;=>=>?>??>>????>?????????????????>??>??>??=??=??=??=??=??=?>=>=6666776885884878<<7::7;97:97:8;=;;=;<>;$#$$$$##"""! " !""####$##$""##"##!#$"#"!""!"!!!!! ! !    
+
+
+
+
+ 
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+    ((( !! %%$""!"! ""!!" %%$&&&&&&((((()((((((-----/,+-111333221333233445444544532764765998::9998;;;>??=>>=>?;<=;<=;<>>>?>?????>?????????????????>??>??>??=?>>??>??=??=?>;<;7760013362451547<:8<99<:9<:8;:8:9:<:<><=?=$##$##$##$#"!!" !"""$#$%##$##$#"$"######"#"!""!!"! ! " !     
+
+
+
+
+     
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+ !  $$#&&%!! "! $"!%$#&&%%&%'('(((((((()+++..-,,+..-442333333232444444333443644766988998898999>??<>=<>>;>>:<<<<==?>>?????????????????>??=??<??<??<??=??<??=??>?>??>:;;456/024453237769:88:78;98<9:=;<?=<?==?=>?>#"#$##%$#$#" "!"###%##%##$##%$#%"#####""""!!"!!" ! ! !   
+
+
+
+
+ 
+   
+
+
+
+
+
+
+
+
+
+
+
+
+
+   '''   (('%%$!!#!!&%$%%%''&'('((()()))))))//.--,//.332232222222344233121211322655887888988877=>==?><>>:==:<<=>?>??>?>>??????????????>??=??:=>:>>:>><??;??;>>=??>??789.01355788777;<;8978:88;99<:;><=?==?==?=>?>$##$##$#"#""!!""#$$$&$$%##%$#%$#%##$###"""""""!!"! ! !!    !    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+  ""#   $$")('"! #! %%$%%$((''''(((*)*))))))---..-..-110232233232333233111212223555877987;:9887===>??<?><?><>>=??>??=>>>?>???????????>>?><??:>>;??:??;??;??;??8<=6:<2561349<;7:87979:9897697;=;=?==?>>?=>?=>?>??>#"#$#"$#"#""!!#"#$$$&$%&$$%$$%$#%##$###""""!!"!!"! ! !!      !!     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+
+
+  
+
+
+
+
+
+
+
+
+   ((*   ! $$""! " %$#%%$(('&''(()++,***+++,,+//.,-+00/555454222232344222334334445555765:98986>==>??=??<??=??<??<>>>?>>??????????????=?><??:??;??:??;??;??9>>4:;5:<8<=/225966:7585797797<=;=?==?==?=>?=>?=??>??>$""##"#$#""#  "!###%$$&%%&%%&$$%$$%$#%##$#"#"""!"!!" ! !!     !      
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+    "!#    "!%#!"!!%$$&&%(('((')((,,+*****)***..----..-563453221221333223232232442754876=<:::8<<<???>??<>>;>>:==<?>>???????????>??=??<?>;?><??:>>;??:>>8>>9??49<2590360356776760210219;:<?><?><??=??=??>????????#"!#"!##"""" "!"##$$%&%%&%%&$$&$$%$#%##$#"#""!"! !!!   """   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+   
+
+
+
+
+
+
+
+
+
+   ""$ !!  "!&$#%$#$$#%$$''&)(((('**)*****)***--,---..-120342221221232222122121432654865::8::8;;;???>??<>>:==:==<?>>???????????>??<?><?><??;??9>?:>?269-1626;25958;/146793446767879;:=>=<>==?>=??=??>???????????!! "" ""!"!  !!""##$$%$$%%%&%%&$$%##$##$####"""! ! !   """    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+    
+
+
+
+
+
+
+
+
+
+
+
+
+  "!#    !!!! $"!%%$$$#$$#%%$(('('&)(()))***+++,,+.....-00/231120120221121121222433544876;:9998999>??>??:=<9<<:==<?>>??>?>??????>??=??<??;>>8=>9>?28;06:.28/3736:;=?578:;<899333898;<;=>>>?>>???????????????????? !!! "! "  !""####$$$$$$$%$%%$$$##$##$##$$""#! ""!!!!  !"!     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+         
+
+
+
+
+
+
+
+
+
+
+  !!#  !!! ##!%%#%%#%%#((&''&))(**)***++*++*...---./.010110110221120121444433756988:99::9888>?>=>>;==:==;=><>>>?>>?>???>??=??=??;>>9<=6:=39<06;-38-362898==:>=7;;9<==>>888;;:<<<=>=>?>????????????????????? !!  !"""##"##"$$"$$$##%#"%##$##$####"!#! " !!!           
+
+
+
+
+
+   
+
+
+
+
+
+
+ 
+
+  
+
+
+
+
+
+
+
+
+       
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ !"#   !!" # !&%%&%%%%%&&%'%&)(')*))*)****+*./.-.-,,+/0/110010121121343554445668778888998787>>=>?><==<>><=><=>=>?;>>;??<??<>>:;;7:;4:;4=>08;05:.172685;<8??8?>9>><??<=<9;9=>=>??>??>???????????????????????      !!"""!##"#$"##"""##"$##$##$#"#"!!" "!              
+
+
+
+
+
+
+
+
+
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+     
+   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  "   !!! ! " !&%$&&%$%$&%%'&&''&***)*)**)*+*./.-----,///010/0/01022122200/444878777777998776=>==>><===>>;==:;<;<=:==9==:>>9<<*,.156/574:<27:138//56:<7<=8>>:??;??>??==<;<:>?=??>>??????????????????????????    !!"!!"##"$$###"#####%##$###""""! " "!!!  !   !!!        
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+
+
+  
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   "      ! $$#&'&$%$&&%&&%'&&)*)*+****)*)---/0/./..../0//0/00/232333111342::9886787998787=>=>??=?>>??:<<666799;??9>>9>>:>?6;<38;.2503713701567;8<>8=>;??=??>???????=>?<??>??>??>??>?????????????????????!! ! !  ! """#####$"##"#####$##$"##"""#!!#! " !#!     !!!!      
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+  
+
+
+   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+     ! ! !!!$%$"#"$%$&&%'&&(((+,++++*+*..-00///.-.-/0/00/00/343333232331::7886777888776===>??<==;==9:;899:<<9==:>?8=?49;39<.37.2602636948:8=>9>>9=>=??>??????>>??=??<??=??=??>??>????????????????????? ! !!!    !!""#"#$""#""###$###$#"#"!"! "! #! # ! !         !  
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   
+  
+
+     
+
+
+
+
+ 
+ 
+ !##      !! !!!""!""!"""%$$&%%'&&'(&*+)*-++-+-/-/0./0./.-0/.10/110242332322443675887776776787:;;>??;<=9;<9;;9;;;>=3777;=8<?14802613714738:5;;8==:>>:?><?>=???????>>?>>?<??=>?=?????????????????????????????? !!!! "!  !"!!#""$""#""########"!"! #!!"! " " !"  !!! !!!!  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+      
+  
+
+      
+
+
+
+
+
+
+ "#
+     !  !! ""!$$#%$$'%%'&%''&*+)+-++-+-/-/0.00/10/0/.0/.1212321223324435547767766758889::=??;==:<<:<<:;<=??588588;?>8;;8;=47:1687<=:??:??;??<??=??>???????>>?>>?<??=??>??????????????????????????????!""!!!!  !!!#""#""#""#""#"""##""! " "! " " !!""!!!!!     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+      
+  
+
+     
+ 
+
+
+
+
+
+
+
+ %"% 
+ 
+  !! !! ""!%%$&%$'&%'%$(''++**,*+,*-.,//.00//..,++.-,221121032243443654765665897:::899=>>;<=:<=:<=:<<<>?;==355=??:=<9<<7;<5:;8=>9>>;>?<??=??>??????????>>?>>?<??=??>??????????????????????????????!!"! !!  !!!"!"#""#"##""#"""""!"! "! " " !!!!!! !!!       
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+      
+  
+
+    
+
+ 
+
+
+
+
+
+
+ 
+ &" 
+
+
+ 
+  "" ""!"" %%$&&$&%$('&)('++)*+**+),,+//.00.00/,+*+*)/0.131032132221533755776998898787<>>;==;==;>><>?>??>>?;;<<>?:<=7;<5::6;;9>>;??<??=??>?????????????>>?>:;9??<??>??????????????????????????????((('&&#"! !! #!!#""$""$""##"#"""!""!"!!" !!     ! !"!!!!     !   
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+ 
+    
+  
+ 
+
+ 
+
+
+
+
+
+
+
+
+
+ !'+!&    !! ##"##"%$#''&&%$''&(''+))+()*)),++..-/0.//-++)-,*00.230120232233456677687897888787;=<;==;==;=><>>=??=??=??<??:==9<=7:;7::;===??=??>?????????????????>>>:::????????????????????????????????????))*,,,,-,()'#$#!"" !# !$!"$""$""$#"$"!#"!""!!"" #" "! " !   ! ! ! !!!!  ! !   !! 
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+ 
+
+ 
+
+
+
+
+
+      
+
+   
+ 
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   ! ""!##"$$#''&%%$%%$&%%)(()''*((+**---./-,,*,,*/.,11/231121343566455566676787898686;<;:<;:=<<>>=?>=??=??<??<??<??<>?4778:;=??=??>??>????????????????????<<<???????????????????????????????????? ''&**(*,*(*)&((#%&"#$!"$""$""$""$"!""!!" """   ! ! !!!! !! !!!!!!" "  
+
+
+
+
+
+
+
+
+
+
+  
+
+
+
+ 
+
+
+  
+
+
+
+  
+
+        
+
+ 
+  
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+   ""!#"!$$#&&%%%$%%$%$$('')&')''+**--,./-..-,,+..-110232231243566456677687786787676<=<<><;=<<?>=?><?><??<??=??<??69:2459<<=??>??>??????????????????????????????????????????????????????????????"#"())*,,*,*)*)'((%&&"##""#" "" !! !!! !! !!! !!!! ! !!!"!"""" # #    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+    
+
+          
+ 
+
+
+ 
+ 
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+ ""!##"$$#&%$'&%''&&%%'&&'%%(&&,++,,+-.,--,/.-0/.3323322423432343445677877867869;9=>=<><:=;=?>=?><>><>><??;>>:=>79:689578=??>??>????????????????????>>>???>>>?????????????????????????????????!"#%'&)*+)++(*))+)')&%%$""! !  !!! !!!!!! ! !"!""""#"#"!! ""    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   
+ 
+
+
+    
+ 
+   
+ 
+ 
+ 
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+   "! "" ##"&&%&&%''&&&%%$#'%%'&&+**,,,--,.-,1//210332232343443333332554777766776998>>=<=<<>=<>=;>=<>><>><>?;>>;>?8<=7;;;>=>?>??>???????????????????????????????????????????????????????????????  !!#$#&&&''''())*+*%&%#""    !!! !!!!!! ! #"""""!!!!   "!  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+     
+
+
+    
+    
+
+
+
+
+
+
+
+
+
+
+ 
+
+     !!"" #"!&&$''&&&%&&$%%$&%$&%%***,-,..,/.-0/.210331342242232232221666776877776665==<===<>==>=<>==?><??<??<??:>>7<<8==<??=?>>?>??????????????????????????????????????????????????????????????? !!"!" ! !!$$$''&*+*)*(&'%#"#   ! !!! !!! "!!"!"  ! !  !# !  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+ 
+ 
+   
+
+
+
+    
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+       ""!#"!##"'&%&&$%%$&%$&%$'&&***,-,.-,0/-432320220242343332232222887777987877776<;;==<==<==<<>==??=??;??:>>8==6<<6<<9>==?>>?>???????????????????????????????????????????????????????????????   ! " " "   %%#&&$((('''%$$! ! !!!!!! ! !!! ! !! ! "# "  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+ 
+ 
+ 
+ 
+
+
+
+
+
+
+    
+
+
+
+   
+
+
+
+
+
+
+
+
+
+
+
+          ##"""!!! &&%%%#$$#&%$&%$*)(++*,-,-,*,+)21/32011/130353232232222777998:99988988=<<<<;<<<<<<<===??<??:>=8>=7==6==6>=9>==?>>?>???????????????????????????????????????????????????????????????!    ! !!! !! !! "!! "!!&&%'(''(&%%#"! "!" !!! !!! ! ! ! ! !! !! ! ! !!!"#     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    
+
+
+
+
+
+
+
+   
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
+
+    "" ""!"" &'%''&$$#%##'%$,*),++--,++*,,*320220231021343242231453787897888878886<=:=>>79:9<;;><9<;9==7<<8=>7=>7=>9==;>>>??>??>??>???????????????????????????????????????????????????????????!  !!!!!!!!!"!""!"" "  #$$')((((%$%$##!   ! ! ! ! ! ! ! ! !!!!!"  "!""!!    
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+  
+
+
+
+
+
+   
+ 
+
+
+
+
+
+
+
+      
+
+
+
+
+
+      ""!""!%%$'(&%$#$#"&$$+)(++*--,,++++)330320342020232121232565787787777888996>?<<>>8:;8;:7:95986::8<<7<=7<=7<=:>>=??>????????>???????????????????????????????????????????????????????????  ! !!!"!!""!"!!"!    !!"$##&&%&&$""!    ! ! ! ! !  ! !!!! !!     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+ 
+
+
+ 
+
+
+
+
+
+
+
+ 
+ 
+
+
+ 
+ 
+
+
+
+      ##!""!#"!&&%%$#$#"%##(&&+*)-.,,,+*)(420531110010242231232454787787676887::7>?<;<<68:6883773875997;;6::7<<8<<;>>>??>????????????????????????????????????????????????????????????????????!!!!! "! "! "!           "!$$"&&$##"        ! !!""!"      
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+
+
+  
+
+
+
+
+
+
+
+
+  
+
+
+ 
+
+
+
+
+
+
+ 
+ 
+  
+       $#!#"!$#"&%$$$#$#"&$$&%$**),,+,++.,+53175311/221343131232453786787776997;;7=>;9;;4683674993777<<8<<6::8<<9==<??>??????????????????????????????????????????????????????????????????????? !   !     !  "  "! %%#$$#""   !    " $#""! "! !     
+
+
+
+
+
+
+
+
+  
+
+
+
+
+
+
+
+ 
+
+  
+
+
+
+
+
+
+  
+
+
+
+
+ 
+ 
+ 
+
+  
+  
+        ## #" #"!&%$$#"%##&$#'%%,**++****,*)52/84231/2223432313424537967857859:8887<<<7:;59:579689689:==9==9==9<<;>>=??????????????????????????????????????????????????????????????????????????         ! ! "  !! "#"$$####"!!      ! %$##!!!     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+ 
+
+
+ 
+ 
+ 
+
+ 
+ 
+   !          #"$$""! %%$$$#%##&$#&%$))(**)++*+*)42/852320111121232231353675685785886876888:>=:>>8:;:;<:<<<??:>>:>=;>><?>=??????????????????????????????????????????????????????????????????????????    !      !  !     ! "#"%%$&$$%#"#!!!  !$"#!    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+ 
+  
+
+  
+    
+       ""$#!"! %%$##"$#"%$#%%$(('**)+++++)11.441220110121454232342564685674665865988;>=:>=;===>>=??=??<?>;>>;>=<?>=??????????????????????????????????????????????????????????????????????????     !  ! !!    !$"!$#"$#"$""#!!" !#!"!     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+   
+
+ 
+
+
+
+
+               ! "!#" "" ##""#"$$#%$#%%$)*(*+*++*,,*01-33/22/000111454354232353564343654644>=<=?><?><>=>>==>>=?><?><?>=?>=?>=?????????????????????????????????????????????????????????????????????????? !!!  ! !! ! ! !! $$$#""$!"!   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   
+
+ 
+                     ! "!#" "! #"!$#"$$"%%#''%**())(++),,)//,430321000132354344010443665543654776??>>>=<=<=>>>>>>??>??>??=??=??=??>??>???????????????????????????????????????????????????????????????????????    !        " ! "!"""!! "! $"#%$%$#$! !
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   
+
+
+
+           ! "!#" "! #"!#"!$#"%%#''&))''(&)*'++(//,652432/0/233455././//343554564432664??>=>=<=<>>>>??>??>??=??<?><?>=??>??>???????????????????????????????????????????????????????????????????????    !!      !! ! !! !$##" !  """"!!
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   
+
+
+
+       
+ 
+     ! "!! #"!$#"$#"$$#(('((''(&*+(,,*10-542331./.---,,,000232453554442432443??>??>===>>>??????>??=??<?><?>=??>??>???????????????????????????????????????????????????????????????????????   ! "" !!! ! !    ! ! !   !#""# !   
+
+
+
+
+
+  
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+               
+     !!!! #"!$#"$#"$$#))'(('(('++),,*00-763331---000111000000453575454553654>?=>>===<>>>???>??>??=??=??=??=??>??>??????????????????????????????????????????????????????????????????????? !! ""!!! ! " " " !      "# $       
+
+
+
+
+
+
+
+
+ 
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+ 
+                      !#"!$$"$$"%%#((&''%((&''%**(00-45244201//0/01001/341775776665665766>>>>>>=>>>>?>>?==>=??=??=??<=>=>>>??>???????????????????????????????????????????????????????????????????????  ! ""!""!""!"!!" " " " !  !" ! "# " "   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   
+
+
+
+                 
+      ! %%#%%#&&$''%&&$((&((',,*..+452341./.-/-/0.12.562895885775654765>>==>====>??>>?=>>;=>;>><??<>?=>>>?>>??????????????????????????????????????????????????????????????????????? ! ""!""!""!#!!" " " #!#!!     !" !      !!#! "  &    
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+ 
+
+                  
+          "! &&$%%#%%#''%''%(('**)++*,,*11/221/0/.0/120230673895885775664775>><==<==<>??>>>;==;>>;??<??<??<>>>?>>???????????????????????????????????????????????????????????????????????!  !! ""!""!"! "" "! #!#!!    !" " !!!!" "    !"$!!" !$    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+  
+
+
+
+                       !#" %%#%%#%%#&&$''%((&*))*))))(33201////122243342785896775553663886>><<=;==<>?><=><=><??;>>:>><??=??>??>??????????????????????????????????????????????????????????????????????? !" !   ! !"!"#!"! ! ! "! "! #"!" !     !"!!  ! !     !!! !"" #         
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   
+ 
+
+
+
+
+
+
+
+   
+
+
+                    ! "!&%"%$"%%#&'%((&((')))'''..-22000/010222232553886896665444565898>?><<<==<>?>>?>=??<??:?>9>=9>>;?>>??????????????????????????????????????????????????????????????????????????  !"#!"! !" !"!!"!!! "! !! "! #"!#"!#! !    !!!   !    !!!" ! "! "!$!!        
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+  
+
+
+
+
+  
+
+                       #!%$"%$"%%#&'%''&((&,,*,,)23/23//0-1201212315638867857765656769:9>>>===>?>???>?><>=;?>:>=:?>:>><?>>?????????????????????????????????????????????????????????????????????????? ! ! ""!""!!"!"#!""!!! " "!!#"!#"!#"!$"!"   !!      !!!!!" #!!#! " " ! $"!!     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+  
+
+
+
+
+                
+   ! #" $#"%$"&&$&&$''%*+(,,(++'12-11.01.231121231563785674675565564:;9>>=>>>==>>??=>=;>=;>=:==<??<>?<??>?????????????????????????????????????????????????????????????????????????? !!" ""!""!!#!!"!""!""!#!!""!#"!$#"#"!$"!#!  !!!!"   !!  !" #! $"!" " ""#"!!!    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+ 
+
+
+
+
+
+
+                 
+    #!%#"$#"%$#%%#''%)*&)*'**'((%/0,00./0.122222232563664674554565674;<:>>=;<<::;<<=:<;:=<:=<9=<<>?<>?=??>??????????????????????????????????????????????????????????????????????????   ! ! !"!!"! !! "#!""!"" "! !" #$"$$"##!## ""  !!!""!  !!"""# # $ # # " &#$%$"$"!"       
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    
+
+
+
+                 $! $#!$$!%$"&&#))&)(%))&*)(((&..+-.+./,230332554565575565453664553;;:<=<;;;9::;<=<==<==;>=;>=;>=<==??????????????????????????????????????????????????????????????????????????????   ! ! "!!!!! !!!""!""!""!#" #! $""$"!$"!%" $!"!!""#"!  !!"# #! $!!# $!!$""#"!$"!"     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+   
+
+
+
+                     # $#!$$"%$"('%)(&((&))'))())'..,--*/0-12/220443676575565665776665<<:<=<:;::;;<>>=>=<>=;>=;>=<>><>>??????????????????????????????????????????????????????????????????????????????   ! ! "!!!!"!!!!!""!"#!##!#"!$!!$"!$"!%"!%" $!"!!""""      " " #! #! " $!!$"#"!!"       
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+  
+ 
+ 
+                   !$"!##!#"!'&%)('((&)('*)(*)(-.+,,)01.120110675675686575675665766<=<==<<=<>??=>>=>><>>;>=;>=<?>=?>??????????????????????????????????????????????????????????????????????????????!   ! ! !"!!"!"!! ""!"#!$#"$"!$#"$""$"!$"!$" #!!! !!!! !!! ! " " "! " #!!'%&%$$%#$"  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+     
+                     "#" "! &%$))()('('&)('*))**(,,*,,)/0-/0-220776686575565675665999>>>===<=<>?>=>==>>=>><?><?><?>>???????????????????????????????????????????????????????????????????????????????? !! !! !!!!!!""!""!  """#""##"#$"$%#$$#%$"$" $" "!  !!"!"" ""!!   ! " #! #! '%%&%%(&&# " "!    
+
+
+
+
+ 
+
+
+
+
+
+ 
+
+
+    
+ 
+  
+  &                ""!!"! &&$**((('(''('((()++++++++*--,,,+231675675575575686665;:9?>?>>?<<==>><>=;>=;>=:>=;>=<?>=?>??????????????????????????????????????????????????????????????????????????????!! !! !!!""!""!""!""!  """###$$#$$"#$#$$#%$#%#"$#!"!  !!"!"" # # !! !!" #! #! &$%'&&(&&# #"!  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+
+
+
+
+
+     
+  !+.&)8 $6"(8"3-'               " ""!"! &&$))'((&'''('((((***((())(,,+,-+121786897676675676775;:9?>>===999<=<<=;;>=:=<:><:>==?>>????????????????????????????????????????????????????????????????????????????????!!!!!!""!"""""""""#"!!  ######$$#$%#$%$$$#%##%#"%#"#"!! !"""" # # # !!   !!!$""'&%'%%# ""!  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+  
+
+
+
+
+
+        
+538<>>:>>7=?3;?2:?3;?5=>2;=)07 !             !"!""!""!''%))'''&'&&('((((**)()'**(--+..,331564665775665665675::8>>=:::9:9;<:;;9;=<9;:9;::=<=???????????????????????????????????????????????????????????????????????????????????""!!!!"""""""""##"#"!!  ###$##$$#$%#$$$$$$%##&$#%$##"!!!!##" " # # "!!     #!!''%('%%"""#!  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+       8:?9>?6=>4>?2=?.8?.8?/9?/;?1<?3;?!-
+         ! !!!! ""!''%((&''%''&'''(('**)))(++)..,//,231443554775775665886:;8>><;;:::9;<:<<:<=<:<;;=<;==>?>?????????????????????????????????????????????????????????????????????????????????""""""""""#""""!"!"""!!!"""##"$$#%%#$$#$$#%$#&$"%$"$#!#!""""# $ #$$#""  !"# '$"(&$%#!#! " ! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+       ,.9#$&74;?7??7??7??2<=3=?0;?.9?.9?.;?1=?5>?!&3*             !"" &&#''$&&$''&(''*)()(')('-,+--,./-354342564774774885996<=:==<;<;::::::<<;:<;:<;;=<=?>>?>>????????????????????????????????????????????????????????????????????????????????""!""!"#""#""#"""!""!""! !! ""!$$#$$##$#$$#%$#&$#%$#$$"#""!""## ## $ ##"! ! !""%#!'$#%#"# " !  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+       
+   &*406?/7?-6?3<?6??7??5?>6??4??1=?.:?.:?.:?.8?3<?',:         !  ! !"" ''$''$''%'&%(('))'*)')('-,+..,./-243/0.331774774664775;<9;<:;<;:;;;<<;<;:=<9;:<>=>??>??>????????????????????????????????????????????????????????????????????????????????"#!"#"##"##"##""#""#"""!!! """$$$$$$#$$$$$$$#%$#$$###"#" "!! """# # #!# $ $#!   !!!!!# %"!%#"%""" "    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+       
+  
+  -08/7>+5?*5?,6?/9?4>?3>?3>?3??2>?0<?.9?-8?.9?0;?5??!$/         !! !!"## ''$&%$&%$''%))')(&*)'+*(/.,//-/1.243--,442774663552875997:;::;;:<<;=<:<;:<;9<;=?>>??>??>????????????????????????????????????????????????????????????????????????????????##!##!#$"##!#$"#$"##""#!!! """##$$$$#%%$$$$$$%$$$$##$#""!"!"!" ""# #"$"$!$!% #"!!  !"""""# $"!%#"" "        
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+ 
+ 
+   
+  
+   $)4.6?*5?+7?,7?.8?1;?0;?/:?/:?/;?.:?-8?-9?.;?0<>27=#       !"!!""### &&$&&%%%$))'))'))&+*(0/,0/-//,01.020110453451330442997::8;<;;<<<>=;>=:><:=;:<;;=<=?>>?>>????????????????????????????????????????????????????????????????????????????????""!""!"#!##!##"##"##"""""! !! ##"#$$$$#%$$%%$&%%%##%##$#"""" # #"$ $!%" %" #!#!#!$ # "!  # $ $! " "$!!%""" #         
+
+
+ 
+ 
+
+
+
+
+
+   
+
+
+
+
+ 
+
+
+ 
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+     
+   !(*6,5>*5?*6?-8?,7?,7?/:?,7?.9?/:?/;?/;?0<?1=?1=?4>?&+3         "! "!##!##!&&#&'%''&))())(++',+'00+12-00-..-..-775342120331443::9:;:;=;;=<<>=;=<;==:=<9;;:<<=?>>??>????????????????????????????????????????????????????????????????????????????????""!""!""""#"##"##"""!"""""!! $###$#$$$$$$%%$%$$%$$%##$#"$" #!# #"# # $!$!# " " "!" !   ""# # " # %""'%$%##"!       
+
+
+
+
+
+
+
+ 
+
+
+
+
+    
+
+
+
+
+
+
+
+
+
+           
+.*/>*1?*1?,2?-2?+0?-1?.1>.0>03?15?/4>28?18?18?07?/4>$       ! #" "! $#!$$!''$((&((&((&)('*)%++&..)//,..+..,00/665331332231332;;:;<::<:<=<=?>;=<:=<:=<9;::<;;=<>??>????????????????????????????????????????????????????????????????????????????????""""""""""""""""""""""""##!" ! ##"#$#%%$%$$%%$%$$%$$%##$""$"!$!$ # # ""# # "!" ! ! !     !"$ !$ !# # !$!"'%%'%$"!       
+
+
+
+
+
+
+
+    
+
+
+
+
+
+
+
+
+
+  
+    #%$&'( #!0"$4 $="'?$)?&+?(-?*.>+/>.2?/4?16?06>5;?6<?4:?08?+2? 1        ! #" #! $#!&%"('$)(%((%)(&)(&**%-,(--*--*,,*..+553120120120110231:;9:;9;<;=?>;=<8;:7997:97:98:99;:>?>>>>>>>???????????????????????????????????????????????????????????????????????????#########"""!!!!!!""""#"$#"#" "!!#$#$$$%%$&%%&%$&$$%##%"#%""%! $!# #!# "#"!!!" !""!  " "!$"% "$ !#!# !%##&$## "!!     
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+ 
+
+
+
+
+
+
+
+        !#  0((;,3?*3?+5?*5?)3?'2?'3?%2?'3?+7?-9?0<?2>?3;?*5?&1?&,<#        "!"! "! $#!'&"('$)(%)(%*)&*(&++%..).-+++),,*+,(11/01/231231332887::9:;9<=<=>=9;:6986986987:97989::;<<=>>>>>???????????????????????????????????????????????????????????????????????????######"##"""!!!"#"#$###""#"""!!! $#"%##%$$&$$&%%%$$$$$%#$%##%#!$" #!%! # " " ""!!"""" " !!!# #"#!!$"!# # %"!&##" !!!       
+
+
+
+
+
+
+ 
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+     &#%(,8*3?'2?'2?(3?'3?'3?&2?%3?'4?)5?)5?+6?+5?(3?&2?%1?'0?(      !" "!#" $$!&&#('$('%)(&*('*(&,,&./*..*++)--+..,//-01.22011/231886776888:;;6775675775785887::7:99<:<>;=?;>?=???????????????????????????????????????????????????????????????????????????######"#"####$#########""#"##" ! #""$"#%$$&%$%$$$$#$$#%$$%$#%$"%#!$" $! $! #!" # #"!!!"" " !!!# # # # $#"""$! '$$#! !      
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+ 
+
+
+
+
+
+
+     %   /2< *4<?,7?*5?'2?(4?(4?(5?'3?%3?%2?&2?'2?'2?&1?%1?$1?%1?(2?0       "!"!#" $$!&%"''$('%)'&)(&*('+,'..+,,*,,+,,*--+--+,-+/0.11/3424535657877887985774775885777999<:;=;=?<>?=??>???????????????????????????????????????????????????????????????????????????#$#"##"#####$$$###"#"#$"##"##" #!!%##%$$%$$%$$$$#$$#%$$%$#%$"%$!%#!$" $" #!" # # "!!!""" "  !"## "#" #"# '$#%""!     
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+     =:?:::789;=>:>?6;=7>?2=?/:?)4?)4?*6?*6?'3?%2?%2?%2?&2?&2?%1?%2?$1?$1?'1?.       "!!!#" %%"&&"''$('$('%)'%*('**(**(**)***+*),,*+,*,-+././/.2316767868:88:87987987:9688689:<;<>;<=:=><>?>??????????????????????????????????????????????????????????????????????????????#$#"##"#"####$$#$$#$##$"##"##"##"! $""%$$%$$%$$%$$%$$%%%%$#%$"%$!&$"$#!%#!$"# #!$!# !!!!"# " !!!# "!! # ""# $!!     
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+     759?>=<?>;?>9>>8??5??3>?4??0<?,7?*4?+7?,8?(4?%1?%1?%2?&3?&3?%2?$2?#2?$1?(2?,!      !!"!!## %%"'&#''$('%)(&(&%(&%('&(('('(('(**),+*,,+,-,./../.3325547877977:87:87:98;:9<;:<<;<;<>;<>:=><?????????????????????????????????????????????????????????????????????????????????"##"##"##"##"###$$#$$#$#"#""$""#"!!! #!!$""$#"%$#$$#$$#%$$%%%%%$%$$%$#%$#%$"%"# # $!#!!!!!""""!!" """ !!" " %""    
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+       <<>>?==??<??9??6??3??3<?3>?4??0<?,8?)5?*7?'3?%2?%1?%1?%2?&2?%2?%2?$2?#1?$0?6     !!!$#!&$"(&#(&#)(%('%&%#((&(('()()))***++*++*,-+-.,..,10/443786898998::99:88988:89<:9=;:>;;>;=?=>?>?????????????????????????????????????????????????????????????????????????????????"###$#"##"##"###$$#$$#$#"#"#$#"$"!! #! #"!$#"%$#$$#$$"%$#&$$%$$%$#&%$%$"&$"%# $"$!$!#!"!!!!!!"!!# #!#!" !!# " #    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
+   ;:>=>=>??>??;??6??2>?2<?2=?3??2>?+7?)5?(4?'3?%2?%1?%1?%1?%2?%2?%2?$1?#1?'3?!&9     !!!%# '%")'$)(%)(&('%('%**(++(*+(*+),,+--+-.*-.,//-2205428868969:7997:;9:<:9:8:<:;=;:=;<><=?==?<>?>?????????????????????????????????????????????????????????????????????????????????#$$#$$"##"###$##$$#$$#$#"#""$""#""" #!!$""$#"$##$#"##"%$#&$#&$#%#"&$#&$"'&#'%#&$!$" $"$"#!!!!! !!!!#!$" $! #!" ""# # !  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+       
+88<<>?=??>??;??6>?1=?1<?2=?3>?3>?+7?*6?'3?'3?%2?%2?%1?%1?%1?%2?%2?$1?#1?'3?$7    ! "!&$!(&#)'$)'$('%('$('%))')*'**(++)+,*--+-.*..,//-21/541985::69:6897:;8:;9:;8<>;;>;;<;=><=?<=><>?>?????????????????????????????????????????????????????????????????????????????????#$$#$$"##"###$$$%$#$$#$#"#"#$#"$"""!#!!%##$#"%$#$$#$$#%$#&$#&$#&$#&$"&$"&%"'%#&$"$# $" $" #"!! !!!!" " #!#!#!# !!"" " "
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        137:??9??;??9>?/8<.:?0;?1<?2=?3??,8?(4?'3?&3?&2?%2?%2?%2?$1?%1?%2?$1?#1?'3?2    !! ! $" '%!)&#(&#)'$('$('$)(&**())(**)+++,,,---..,//-0/.20.863:95::5::69:7:;79;79;8<>:;=:==<==<==;>?<>?>?????????????????????????????????????????????????????????????????????????????????$$#$$$$$$#$$#$$#$$"%$"$#"$#$$$$$$$## !! ##"$$"%$"%$"&$"&$!&$"&#!%#!%#"&#"&##&##&#"&#!%" %!%" "  !!"!!" #!"!#! "! #" "!!" $!# # ! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    
+ ')18>=9??8?=6=?/7?.8?0<?1=?-:?,:?)7?(5?(3?'2?%2?&3?&3?$1?$1?$0?%1?"2?"1?(2? $   ! ! !!$# '%!)&#(&#(&#('$('%**'**'*)'+*)-,+.-,.-+/.,0/.0.-632<:8:96::7:;8:;99:88:7;<9;=9:=9<>;=><=><??>??>?????????????????????????????????????????????????????????????????????????????????$$#$$$$$$$%$$%%#%%#%%"$#"$#$$$$$$$##"!" !! $#!$$"%$!%$!%#!&$"%#!#!#! $"!%""%#"%#"%# %" %" %" #!! !"!!"# #! "!$"!"!" " # # ### 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+     #9>?7>?5=?6??1;?.9?.9?/;?-9?,7?)5?)5?(2?(2?&2?&3?'4?&3?&2?%1?$1?#2?#2?&0?   !!! "!%$ (&")'$)'$(&$('$*)&++(++)--+.-,..,00.0/-11/21/32/:85<:7;97;:9<=;<<:<=:<>;:<9:<8:<9=?==?=>?=??>????????????????????????????????????????????????????????????????????????????????????#$"#$##$##$$#%%#%%$%%$%$$%$$%%$$$$$$$$$!! #"!$#!$#!%#!%#!%$!%#!$" #" $#!%#"$#"%$"%$!%# %" %"!$# #!!!"!""# $! " $" " !"# $ $$ $ !!  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+       38?/7?/8?4=?0;?-8?+6?,7?-8?-7?-7?,6?(2?(3?(5?)5?,6?(6%4.5?)2?$1?%3?%-=  !" ! #"&%"('#*(%)(%)'%)(%++(,+(++),,*//-00.01/22022032/751=;7<:6=;9;;:==<<=:<=:<=::<9:<9;>;>?>>?>>?>???????????????????????????????????????????????????????????????????????????????????????#$"#$##$##$$#%%#%%#%%$%$$%$$%$$$$$%$$$$##! #"!##!$# $# %#!$$!%$!%$"$#"$#!$#"#"!%$"$# %# $" %#!%#!$" # !"!"##$! # #! %"!# ##$ $ $ $ "   
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+     &)8/8?,5?.8?-8?,7?+6?+6?/8?.7?1:?2<?,7?)5?'4?)4=0 *+/:,4>+5?#3    !" ! $# '&")'#+(&*(&)(%*)&,+)..+..+--+,,*//-01/11/11/22/762=;7<:6=<9<<9<=:<=9=>;;=::<9:<:;=;>?>=?>>?????????????????????????????????????????????????????????????????????????????????????????%$#$$#$$##%$#%%#&%#%$$$$$%$$%%$$$$$$$$$### #" #" $" %#"$#!%#!&#"&$"%$"$$!#$"$##$"!&#!%" %"!%#"$#!$" $ """# ""# #!#!%#!$"# ### "# #!   
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+      /7=,5?,7?+7?+7?-6?,8?.9?2:?9>?;??;??5<=4=>!&2 ! *%%
+ "/ #       # !" #"%$!'&#((%+*'*)&)(%,+'.-*..,..--.--.,./-/0./0./0-443;;:<;::97:97<=:=?;>><=><;;:;<;=>=>?>????????????????????????????????????????????????????????????????????????????????????????????????$$"$%#$$##$##%$#%%#%$$$$$$$$$$#$##$$######!!#" $" $"!$#!%$"&$"&#"%$"$$!$$"#""$!!%"!%" %"!%#!%# $" $ ""## """ " "!$#!$$!" ""!! "# "   
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+       &,8/7?*4?*4?-6?4<?7>?9??;??>??>>>>??=??<?>$&. ((078::<=449
+
+     !!"" %#!'&#)(%))&*)&*)&**&,,(--*..,..--.---,./-/0.//--.+654??===;;:8;;8<=:=>;=><==<;<:;<:=>=>?>????????????????????????????????????????????????????????????????????????????????????????????????$%#%%$#%#"$##$$#%$#$$$$$$$$$$$#$##$$#$#"###" $"!$"!$"!%#!&#"&#"&#!%#!$#!$#"$"!$!!%"!&#!%#!%#!%" $!# "### "!#!" " #"!!! !" " ! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    $(-9.6?+4?/8?4>?9??<?>>?>??>??>???>>?>><+*1 
+
+ 999779    !#!#! $"!&%"('$**'*)'*)'*)&+*'-,(--*.-+--,--,--,..-00.//-..+885?>;<<9996<=:>?<??=??=>?=>>==>=<=<???????????????????????????????????????????????????????????????????????????????????????????????????"$"#%#"$""#"#$##$$$$$$$$#$$#$#######"###$$!" !!$" $"!#" $#!%#!&#!&"!%"!%#!$$"$"!$!!%"!&#"&#!&#!%" $" #!"### "!#!" !""""!"" " "   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+     "&5.7?2=?0;?7>?<??>????>???>??>??>>>558   '), 
+   !# $"$" %#!('$)(%+*(*)(*)'*)&,+(-,)--*--+--,-,,-,+..-0/.//-10.984>=9:;7896=>;>><>><>?==><>>==>===<???????????????????????????????????????????????????????????????????????????????????????????????????"""###"#""#"#######$##$##$#"##"##!"""""##"##!!  #"$" $" $" $"%# %# %#!%#"$##$#"$"!$"!%#"&#"%""%"!%" #!" "#$ #!!!  !""! !! ! ""!  
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+ !  
+
+-1<08?/9?5=?<??>????>??????>?????,*/ $ ""    !#"$$!$#"&%#)(%**%++&**&**',+(..)..)..*/.+/.,..+./,.0..0.01/663952=97:76;98>=;652>>;>?=>?>>?=?????????????????????????????????????????????????????????????????????????????????????????????????????????"#"##"##"##"##"#$##$#"##"##"##"##!""""""""##!!!! #"$" $" %# %# %# %#!%#"%$#%##%#"$"!%"!%#!&#"%"!%"!$! # " # # #! !" !""!    !"" 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+      
+)-;2:?7=>=??>??????????????>>?#" 
+     !$# %$"$#"&%#*)%*)%++&+*'+*'-,)//+//*/.+/.+..,/.+//-/0./0.330662963<9820/434766755?>=>>=>?>????????????????????????????????????????????????????????????????????????????????????????????????????????????##"##"#$"##"#$"#$##$##$$#$$#$#"##"#""#"""!"" "!#"$" $" %# %# %# %#!%#"$#"$#"%#"$"!$" %#!%" $! $!!$!!$! #!# " "!!!"" !!!   !!""   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  !
+    /3<<??=???????>??????>>>769><?      #"%$"&$"&$#&%#*)%+*&,+'+*&+*'--)//+/.*/.+/.,/.,./,/0-01/22/662=;7<:7=;9877112../*)+.-.223778?>??????????????????????????????????????????????????????????????????????????????????????????????????????????"#!"#!"#!"#!##!#$"#$""##"##"##"##"##"##""!"" "" ! " #!$"%#%" %" $#"$#"$#"%#"#! #! %"!%" $! # !%""%"!$"#!"    !!     ! !!"!  
+
+
+
+
+
+
+
+
+
+
+    
+
+
+
+
+ 
+
+
+
+  
+    
+ 55<????????>????????? ?>>   !  !$$!&%"'%#'&%&%"'&"+*&+*&+*'.-*0/+00+00,00,/.,.-+//-01.22/330984?<7?>9>=9>><>?>=>>>??<<=879667?>??????????????????????????????????????????????????????????????????????????????????????????????????????????#"""" ## $$!#$"#$"#$##$#!#""#""#""#""#""#"##!## "!  ! "!$" $" $" %" %" %" %" #!# $!&" %!&" &#"&#"&##$!!"  !"!!!!!  !"!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+       
+ 888;:;?=?>==98: 
+   !#"%$!&&#&&#''&&%$&%#,*'**%+,'01,/0,11.22/21./.,20/22000/10.983=;5<95>=9>?;??=>>>??>??>>?>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????#"!"" "" ## #$!#$"#$##$#"#""#""#""#"!#"!"!"#!##!!  ! " #!$" %# $!$"%# %" $!# # %"'#!&#!'$#&$#&##%""# !   !       
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+       
+ "!
+
+    " $#!'&#'&#''$%%#%$"(&$+)'+*',,(00,10-10-20-20.20.30/21.31/751?=6>;3=95><9==:>><>>=??????>?>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????"!!"" """# #$!#$"#$##$##$#"#""#""#"!"! "!!"!"" ""! #! #! " #!$"#!$!%" %" $!#!" $!&# &#!&$"%#"%##$""# "! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+            !%# %$!''$''$((%))&))''%%'%%)(&+,(11-1/-10-1/-20-20-1/,0-+30/974?=6>;4?=8?>;>><??>?????????>?>>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????"!!"" "" "##$!#$"#$##$##%$"#""#"!#"!"! ""! !!! "!"!"!#!#!$!$!$"%#$"$!" # $"%#!%$"%#"%##$""" !   
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   !       !%# '%#('$'&#((%**')*&,,)+)*)&()''./,00-//-00.10-10-32.43020/311642=<6=<6>=9??<??=??>?????????>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"#!"#!"#!"#"#$##$$#$#######"##!#" #" "! "" !! ! !!"! "# " "# $!#!$!#!$"#!#!# $!%" %#!%#"%$"$#!" !   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  $
+        !  !# ('#('$'&$''$**'+,',,)++(('%('%*)'-.+-.+//-/0-00.11/220320332775774;:7=<8>=:??=??>??>???>?>=>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????#$"##""#""#"#$$#%%#$$#$$#$$"$#!##!#" "! !! !!!!!"" #" "!!"" " ""# $!$"$"$"$" $!# #!$" $"!%#"%$#%$"!    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   !!"    " &$!*)%)(&''$('%**',,(,-*++(+)'+)'10-00-./---,--,--,//.100321432<;9<<8<;7=<9??=?>=>?=>?>>?>>?>>?>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"""""""#""###$$#%%"$$!$#!$#!##!$$!## "" ""!""!"!"" "!"! !" #!#!!" $"$" %" %" %# $" #!#!$" $#!%$"%$"$#"#" "  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+
+
+  ""#%&     !&$"(&#*)%*)&('%))&,,)-.*+,*++**('+)'0/-01-11/00////..-..-/.-210663;:7<;8=<9?>;?>=>>=>>=>>=>>>>?>>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????###"##"##"##"#$"$%!$$ $$!$$!$$!$$!#$!"# !! !! ! !!"!#""!  "!$" #!#"$"%# %#!&$!%# %# %# #"#" $#!$$"$$"%$"$#!"   ! "!!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+    
+
+
+
+          #"('%*)%+*&*)'*)'))&..+--),,+,+*+)(/.,10-11-12.01.00.22032021/310974<:7<;7=<9??<>>=>>=>>=>>=>>=>?>>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!#"!"""#####"""!#""$#!$$!$$!$$!#$!#"""! !! ! !! !! !!"!#" ! !" $"#" #" $"!%#"%$"&%#%$"%#"$#!$# $"!%""%#"$$#%$#%""$"!   !"!    
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+       ! $# '&#('#+(&.+(-+(-,)..*-,)--+++)..+11-00,12,12-02.01/221210320:85=>:<<9;;9;<:=>;==:<>:=?;>?<>?=??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!#"!#"######"""!#""##"$$"$%!#$!##!""""! " !! !! !!!!!!"" ## "!!$"$#!$$"$#"%$"%$#&%#&%#&%#$$"$#"%#"%#"%#"%%$%$$%##%#"!     !!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   
+      ! "!$# '&#('$(&#,*'.-*.-*-,*-,)++(,,)//,01-//+12-23.01.12/220431652>=:<<9;;8::9<<;;<:;<9<>;=?<??>>?=??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? #"!"""""""""""!#"!#""$#"$$!##!""!"!"" !"!"!"!!!!! !!"""!! "!## $%#%$#$$#%$#%%$%$#$#"$$#%#$&#$%##%##&%$%%%%$%%$$#"!!             !! ! 
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+ 
+
+
+
+ 
+
+
+         "!$# %$!'&#('$))&++(-,*,+)-,),+),,)00-//,/0,00,22.11.11/11/21.;96=;8<:7;:8::8;;:;;::;9:<9;<:;<;9:9==<??>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? #"!""!!!""""""!#""#""#"!#"!#"!"!""!""!" ! ! !   !!"!  !"$$"$$#$$###"$$#$$$$$#$#$%#$&#$%##%#"%$$%$$%$&%$$%#"#!"         !!  !!! !! 
+
+
+
+
+
+
+
+
+
+ 
+           #" %$!%$!&%"(($)*'+,),,**)'*)',+)//,00,//,/0,01-00-11/00/10-984?>9=<7=:7;97987:99;;;:<:9;98:9898999=>=>?>??>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!" !"!"#!!#!!#! " !" !! !! !"!!!!!"! ! ! ! !   !!  "!"! $#"%$$%%$%%%$$$%$$%$$%$#&$#&%$&%$%#"%$#&$$&$$'$$&$#&#!$!"      ! !!!!    !! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+              " #!'$!&$"&%#('%))&,+*+*)*)()(&--*0/,21.21.10-11.11.00.10.541;:6?>9==8==8>>:==:;;9<<;;<;:;;9::<=<;><<>=>?>??>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!" !"!!"!!" ! ! !!!!!! !! !! !! !! !       !#"!$$#%%$%%$%%$&%%&%%'&%&%$&%$'&%&%#%$#%$$'%%'&%'%$'%#'$"&#!"!!!!    
+
+
+
+
+
+
+
+
+
+
+
+
+           "" "!#!'%"%#!('%((&))&+*()('('&**(.-+/.+21.21.21.00.00.00.21/873=<7>=8>>9>>:?>;<<:>><>?=:::9:9;<;=?>;><=?>>?>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? " !#!!"! !  !   !!!!!! !! !! !! !! !       #"!%$#&&%&&%&&%&&%&&%'&%'&%''%'&%&%$%$#%$#&%$'%%'&$'&$'%#(%#%""! !      
+
+
+
+
+
+
+
+
+           "" ""!"!$# &%"('$)(&))')(&*)()('*)(0/.10-0/,10-00-0/.00.110220652<;7>=8?=9?>:==:>><>>=??><<;:;9;;:;<;<=<;><=?>>?>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? " !#!!"! !!" ""!#$!"# !"## "# "" !" ! " !" !! !    #" $$"&&$&&$&&%'&%''%''&''%''%&&$&&$$$#%$#$$$&%$('%'&$'&#(&#&%!#!      
+ 
+
+
+
+
+
+            ! !!##!$$!%$!)(%))'))')(&*)')(',+*//-0/,0/-0/-0/-0/.11/221220::7=<8>=8?=9?>;>>;>=<??=>>=<<;<=;>?==>=<=<=?>=?>>?>??>??>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????? "!!# !# !#"$ #$ ##!$#""# "$ !# "# ""! "!!" !"!""!  (($$&!&&"('#''$&'#&'$&&&'&&''&&&&&%%$$$%$#$""#"!&%$'&%&&%&&$%%###!     
+                "!"!" #!%$"%#"('%)('''&((''&%++)--+..+//,/0,10-1/.1/.10.33/651=<8<:8=;:<:9<;:=<:??<??==><;<:=><??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!"!"#!"$ "#"# "# "!#" "# !" !!"""!"" """"""#!&&"%$!&%"'&#''$&&$&&%'&&''&'&&&&&%%%%###!!"! #"!%$$&&%&&$%$#$#""! !! !!                 ! "! #" #!" "!%$"&%#&%$'&%((&++*--+--+--+..+//,0/-0.,/-+21.440<<7=<9;:8:98:98:98;:8>><??===<<<;>>=??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? !  !"""  !  "!  !#" ## #"!  !!$!&#!%#!&%#'&$'&$&&%&&&'&&&&%&&%%%$%###!!!  "! %%$%%$%$$%$#$#"! !! !!               #" #!#!#!$"!&%#&%#'&%''%**(++),,*,,*,,*,,+..,/.,0/,1/,31-;;7;;7<;8;;8::8::9;:9;;9=>;>><==;==<>?=??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????     ! "     ""&#!&$"%$"&$#'%%&&%&&%&&&&&%&&%%%%%$##! !! ! !! $$#%$$%$$%$#$#"!   !!!                " %#!$"!%#"$"!%#"'&$'&$''%''%++(,,)++)**),,+..-..-/.,1/+21,:83::57839:6996997::8::8;;8==;<<:==<>><??>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? " "    ""!!"!!"$ #$ &#"&##&%$&&$&&#&&$'&%&&%&%$%%$%$#$""!    !""!$$$$%$%%$%%$$#"   !!!!                  ## #$ (&$(&$)'%)(&**'))'()&((&++)++***)--,//.1..1/.1/-541<;8::6764663997;;9;<9<=:=?<>?=>>==>=>?>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????  ! " !!"! ! ! #!#!"!$$ #""!" !$!#$$ %#"&%#&%$&&$''%&&%&&$%%$&%%&%$%$#"! ! ! "! "!!##"%%%$$$$$$%$$$##   !! !!!    ""$$ &%#(&$*)'+*(++),,)*+(((&))',+***)--,00/20/0/,10-33/995:97875986::7<=:<<:<=:=>;=><==<>?=>?>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????  !""## ## "!!" ""!""!$$"$$"%$"##!#$ $##"# "#$$# %# %$#&%$&&$''%''%&&%&%$&&%&&%&&%%%$"! "!!$#""!!##"%%$&%%%%$$$##"!      !"# # "!  ! "!#"%$!'&#)(&,+)*)'++(**(-,*++)**(+*).-,00/00/00.340::6541552:97875986886<<:>?<>?<>?<=><==<>>=>?>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????  "#!"!""# $%!&&#%&!!#!#!"#"##"$$"%%###!#$ ###""!" # ##$ &##"$#!%$#&&#''%''&''&&&%''&''&''&''&&%$"! " #! #""#""###%%$%%%$$###""" !!   !   !"# # # # # !  ! "!#" $# )(%+*(,,),+)-,*,+)+*(*)'**'**(++*0/.//.00//0-9:6:;79:6764876;:8::7::7==:==;<<:=>;==;>>=??>>?>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????  !" !!# #"### #$!$$!$%"%&""# "#!##"#$##$"$$#$$###!"!# $ #" ! $ *%"$ &%"&&$'%$'$$(%%(&%('&'(&&(&'''&&&&&%%$##"!"!"! $#"##"$#"%%$%%$$##%$##"!!"!#!"   ! ! ! ! " # %!%# "    " $"!%#"((&*+(()&*+)++),-+,-+-.+**(,-*--+++*01000/220885::6;;6<<7774875<<::;89;8<>;<?<<=;=><>?=??>??>?????????=??;>=<>=>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? !!!"!"!##$ #$!#$"#$"##""#"#$##$"#$##$"##"#$"##"#$"$# #!# # # # " " "! '&#''%'&%&%$'%$(&%'&%&'%&'&&&&&&%&%$$$#$#"#"!"" #"!$$#%$#&&%&&%&&%&%$%$#!  !" "!" " ! !  "!"!$! $! %" #!"!  ! "! $"!%$"&&$**'))&**())'**(--+--+++)--*..,++*00/220773::7995;;6<<8:;7;;9::8:;8:<9;>;<><<><==<>?=??>??>?????????=>>;=<=>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????! ! ##!## ## $%!#$"#$##$#####$##$##$#$$##$###"$%#$%$##"#"!$" #" #"#"#!#!#"$!"!# /.,-.*'($%%"'&$&&$%&%&'&&&%&&%&&%&%$%$##"!""!""!$#"'&%'&%'&%&&&&%$&%$%#"!   !" !" ! " !"!"!"!"!$! %! $! $" $#""!!"!      " $"!%$#%%#&&#((&))&((&((&**(-,*-,*--*-.+-.,.-,0/-43/984<;7984::6;<7<=9;<9:;8<=:<>;<>;;=:;<:>>=??=??>??>?????????>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? "!## $$!$%!#$ #$!#$"#$"#$"#$"#$"#$"$$#$$#$$#$$#$$#$$#$#####"#""$!#$ ###"""$!$$ !+)(,.)()%$$!&&#''%&'&&'&&'&''&''&''&'&%%$##"!""!##"$$#%%$&%$%%$%$#%$#&$#$"!!  !!#! $" #! " ! ! ! " # $ $! $" $#!#! ""! !      #"!%"!$#"$$"&'%''$'&#'&$'&$('&*)(+*).-+..,,,*,,*..,430;95;94<:7<;7<<7;;7=>:9;89:8<=:<>;<>;;=;<><??>??>??>??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ! #"$$ ## "# ##"$$#$$#$%$#$##$$#%%#&%$&%%%$$$$$$#$%#$%$$%$$%##%"$%!$$ $##"#"#"$#"!! ''&(('''&&&$((&()&''&''&''&''''''''&&&%$$###"##"###$$$%%&%%% ! ##"%%#$#"!!!! ! %""%""$!!" !!!!"!#!#! #" $" $"!$"!# #" !!!       !""##!$$"##"%%#&&$((%''%((%((&))'+*(,+*/.,00../-..,..-00.885::6;;6<<7??:<<8::7786897>?;=>:=>;>>=??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"! !!""## "# ##!##""#""#"#%$#%$#%$#%%#&%$%%$%$$$$$$#$%#$%$$%$$&$#&#$%"$%"$# #"""#"##%$!#" #"!&%$'&%''&()'()'()''''''&'''((''''''&&&%%%$##"##"$$#%%%&&&&&%$%$$$#%%$%$#%#!$! " " " # %""%""#! #" #" #" $" #!"!#! $"!$! $! $! #!!!!!      ! ## $$"%%#&%$%%#&&$''%**'**'))'++)+*(--+//-10.21/22.00-10/11011/::8::6::6<<7;;79:6886997:;79:7>><>?=??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????$####!##!#$!"$!"#!"#!"#!"#!#%$$%%$%%#%%#&%$%%$$$%%$$%#$%#$%$$%$#%#"%##%#$$"##"$#!## ####$$!$$!$#"$#"%$#('&(('''&(('(('(('(('(('((''''&&&%%%###$##%##&$$'&&''&&'&''&&&%&%$%"!$! #!! ! "%!"(&&'%$%#"$" #!"!"!"!#! $! $"!%#"&"!%" #  !!    ! "!$#!%$"%$#&%$&%$%%$&&$&&$))'++(**'++)+*)-,+/.,0/-00-11-22/11/1101205529969:6:;69:69:67957759:7=><??>??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????###$$##$""#!"#""#""#"#$"#$##%$$%%%&&$&&$&&$%%$$$%%%%%$$%#$%##%#"%#"%#"$##$####$$"$$"## #$## $$ %#!#" " &%$)('(''(((((((((((((((((((((&&'%%%%%%%$$&$#'$$'%%'''&'&''&''&(&%'%#%"!"  ! $!!%""%$#(&%&$#%!!#!"!"!"!#! #! &#"&#"'#"%#!%#!!     !!#"$# &$"&$#%$#&%%%%$%%$&&$&&$''%--*,+)+*),,*.-+.-+.-,0/-20/21011011/23023/441774:;6;=79;6795674<=;??>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????$$$$####"##"##"##!#$"#$"##"#%$$%%%&&$&&#'&"&%"&%"&$#&$#&$#%%"%$"$$#$$#%$#$##$"%%"$$"$$!$$!$$ $$ &$"%"!#! &%$))(()(()(()))))(((())()(()(%)'&(''%%($$&$#%$"%$%&%&'&'''''''''&'&%&$$$"!$" $"!$" $" $##$##&%$$""#! #! $" $" $!$! $"!&#"&$#&$$&$#%#""! !      ## $$!$$!$%!%%"%$!&%"(&#('%'&%''%((%)*&-.*--)-,),+).-+/.,10-22.45/34022/230341330550552663896675786>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????##"##"##"$$#$$#$$#$$#$$#$$##%$$%$$&%$&&#''#'&"&%"&$#&$#&$#&%#%%#%%$%%$%$$%$$$#%%"%%"## $$!$$ $$!%$"%$"$"!$""('&()'()((((())())()()))'(('*(()(('&(&%&%$%%#%%$&%&&%&&&&&&&''&(('('&'&%&%#$#!#! $" $#"$""&$#$"!%"!'$#&$"%# $!$" $"!%#"%#"&$$%$#$#!#! " "            !!""## $$ &&"%%!$$!$$!%$!%$"&%"'&$('%'&%''%((%))&,-),,)-,),,)--)11,7708819:4451230220341451551451785==;==<>?>>?>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????#$##$""#"#$"$%#$%$$%#$%#$%$$%$#%$#%$#&&$((#''"&&"&%#&%#&%#&&$&&$&%%&&%&%$&%%%$%%#$$"%%"$$!$$!$$ $$!$# &$"'%#'&%''%))('(((((((('((()))))()(()((('(('&&%&&$%$$%%$%$$%$$'&%('&('&(('('&'&$%$"$#!%#!%#"$"!%"!&#"&#!'$"(%#&$"%# %#!%#!%#"%#"%#"%##%#"$#!%#!&" "             "!"" $$!$$!## $%!%&"$$!$$!$$!$$"%$#'%$'&$('%('%''%''%((%)*',,(-,),,(-,)--(66/9:3;<7562563774330451552886??=>>=>?>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!#!!#!!#!"#""$##$$$%$%%$%%$$%$#$$#%$#&&#''$'(#&'"&&$'&$'&#&&#&%$&%%&&$&%$%$%%$%%#%%"$$!$$!$$!$%!#$!$$ %$"&%"$#!$$"))('(('(''(''(('('())())()(()()*)'(''(&&&%%%%%%$&&%''%''%''&'(&''&''%'&$&%#&%"&$#'%#&#"(%#(%#(%"'$!'$"&$!%#!%#!%"!%""# %#"&%$'&$&#"'#"&$#        !   "!#" %#"$$#$#"$#"$#"$$"%%"$$!$$"$$"%$#&%$'&%(&%('%('%''%''%'(%()%++',,(,,).-+.-+985;;6;<7451774674452562885==;==;??>???>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? !!"# "#!"#!"$""%"#&"$&#$%##%$"&%!&%"&%$''$&&$&&$&&#'&#&&#%&#%%$&%$&$$&#%%#%%#%$"%$"%$!%$!%%!$%"$%"$%"%%#$$"$$"&&%''%'%#(%$)&&'&''()(()()))*)*+))*(()&()''(&&%$'%$'%$'&%''%''&''&'&&('&(&&)'&''%('%('$'&$(&$'%#&#"&#"'%$&$#$"!" # $!$" '$#(%$'$#'%#'%#%#!" !  !     !!     !!    ! " ! $$!&&#%&#%$"%$#%$#%$!%$!&%"&$"$#"$#"%$"&%"''$('$'&$'&&('&'&&'&%('&*)(,*(,+).-*//+11.11/997764330775554443898???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? !!"" "" !#!"#!"$""$"#%##%##&%$'&!&%"&%$&&%&&%&&$&&#&&$''$&&$&%$&%$%##%"$$"$$"$$"$$"$$!$$!$$!$%#$$#$$"$$#%%#$$#$$#'&$'$#&"!&##&&&'(((((()())(**)**())'((&((&'&%&$#&%$&$#%$#&%$'&%'&&('')('*)())')(&)(&)(&('%'%#&#"%""%#"$#"#! # %!!%" %"!'$#'$"'$#(%#(%#'%#&$"&$""! !   !! !!!!! ! !! !  !      ! "!#! " $#!&&$&'$%%#&%#&%$%$"&%"$# %$!%$"$#"$##%$"%%"&&"'&#('%''&('&('&('&)(&+*(,+).-*21-540430//-11/21.320442442887>?>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? !"" "" !"!!#!"#"!"!!#""%$#&%#'%$'&#%%$&&%&&%%&%&&$&&$&&$&&$&%$&%$%$$%#$%#$$##$"$$"$%#$$"##!$$"$$#%%#%%#%%$%%$%$#'%%(%$&"!%"!&%$(('))())((('(('(('(('''&''&''%&%$&%$&$#&$#%$#'&%('&)(')(')('))())'*)')(')'&'%$%"!$!!#! #"!#"!$!!%!!&#!&"!'$"&#"($#($#($#(%#'$#&$"(&$#!    !!!!!! ! ! ! !  !        !!"" "" ## ## %$"'&$(&$%$"&&$''$&'$'&$&%#&$#%#!&%"%$!$$!$$"$$#$##%$"%%!&&#((%''%('%((&))'++(,,)-,)/.+11-43/54033/22/11/21/431331564<<:>?>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!!!"!"!" !" !#!"""!!!!! $#"&$"&%$'&#%%$%%%&&%%&%&&$&&$&&$&'$&&$&%$%$$%#%%#$%$$%#$$#$%#$%#$%#$%#%%$%%$%%$%%$%%$&%$'$$($#($"'#!&%#((')(')('))())(((')((('&'&%''&''&&&$'%%(&%'%$'%$&%$)('))())())(*)(*)(*)((&&(&&&##$! " #! #"!%#"&""&"!&"!'#!&"!&"!&"!&"!'#"'$"'$"&$"(&$%#"   ! !!!!! ! ! ! !       !!! ! "!$#!%&#$$!%&#%%"'&$('%)(%((%((%'(%&&#&$"&#"'#"&$!'%"&%"$$"$$#%%$&%$&%#(($**&++(+*(+*(,+).-+/.+.-*0/,0/,21-43.54/77333011/320441775<<:>><??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"#"#!#!#"#!!# !" "! !!!#""%$#%&#&&#&%$&%%%%%&&$'&#'&"&&#'&$('$'&#&%#&$$&$$&$$&%$%%%%%%%$%%$$%"$$#$$#%%$%%%%&%%%%%%$%$$&$#&#"'$#)&%((&''&(('))())'()'(('''&''&('&''&''&('&)'%(&$'%$&%$(''(((((())(((((((('''&&&%%&%$%#"&$#&$"&$"&$"&$"&$"&#"%! $ &! &#!&#!&" &" &#!'&#('%'%##! ! !! !!!" !!!!    """""!! ! "!#"$#!""!##!$$!## #"$#!'&#%$"&&$&%$'&$((%((%(('''%&%$%$#&$#&$#&$"&%"''#%'"$%"%%#'&%(&%('%**&**&++'-.(01+/0+00+01-.-+0/-10-42/43/98366122-22.552;<8>?;??<??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"$ !# !# !# !" !" !" " "!!#""%$#&&#&&$&%$&%$&%%&&$'&#'&#'&$('$('$'&$'%#&%$&$%'%%'&$%&$%%$%$%&%$&#$&$#%##%#$&%$&%%&%%&%&&$&%$'%$(&%)&%((''''))()))))(()((('(('(('))(*)(**)+*)*)()(&('&'&%&%$&%$&&&'''((('''(''''&'&&)'')&&*&%*&%(%$'%"'%#'$#'$#$!# %! %"!&#"&# %"&# '%#'&$)'%)'%&$#"    !! !   !   !!"""" "" #" "" "" ##!#"!##"$$"&%"'&#%$!%$"('$&%"&%$&&$'&%('$''$('%&%#&%#'%#(&$'%$'%$)(&''$&'$%&$&&%('&('%)(&(($,,(..)12,12,22-22.11-00-10-20.1/-21.32/11-440995<=9>>;>>;??=??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!$"!$" # !# !!" $%# ! " !$"#%$$&%#&%$&%$&&#&%#'&#'&$'&$''$''$'&$'&$'&$'&$'%$'&$''#%&$&&$&&$%$$&$$&$#%#"$"! ! #%$$&$%&$%&$&%$&&$)(&(('&&&'''))())())())(*)())())(*)(**)**)**)++)((''&%%$#%$#&%%&%%&&%(('(''(((*)(*('*'&+('+('*(&(&$'&$&$"&$")&$'$"$!$!%"!%# %#&# '$"($#'&#(&$'%$(&%$""!"!           !  ! !! !"" ""!##!""!##!%%#%%###"##!$$!&%"&%"&%"('$''$'&$%%#&%$''$'&#('$('$*)&)(&**'*)'(&$'&$((%'(%'(&''&('&)(%)(%**&//*01+01+01,01,00,12.22.11-10-//,10.00-551<<8<=9;;8==;??>????????>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? $" $"# !#!"$!$%#%&# "!"$"$&$$'%#&$$&%$'&#'%"'&#'%$'&$('$('$'&$'&%'&%(&%(&%('$''$&'%'(&((%'&%&$$%#$$##$""#""""$%%#&$$&$$&$%&$&&$''%###%%&'''''(((())))))**)**)**)**)**)**))*)**)**(('&&%#%$"%##%##$$#%%%''')))**)**)*)(*)(+*(**'()%('%'&$(&$)'%)&%&#"%"!$" $#$#%" &"!'#"&$"'%#'%$(&%'%%'%$(#$$ !    !!! " !  ! !!    !! ##"##"##"""!##"#$"$$###"##!%$!&&"$#!'%#('$'&#$$"##!&%#))&*)&.,)+)'*)&('$((%))&)(%)(%()$()%()%((&('%+*',+(0/+11,22,12,01-/0,11-23/22.21-0/+00,11-44/:;6=>9<=8<<9>>=>>>?>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????%" %"!$!#%!#%!#%"#%"!" ! "$##%$$&%$&&$'%$'%$'%"'&#('$)(#('$('$''$''$((%((%((%('%''#''%((&((&'&%'%%&%&&%&&%%%$$%#&'&&'%%&#%&#%&$%&%%%%%#$$#%&')'()'(())(**)***++*+,+++***(**)*)*)())())((''&&%$%$#%##%##&%$(&&)('++**********))(()(((')('+)(*('*)()(&('%'$#%"!$" $# %" &!!'""'$#'$$'$$(%%(&%)'&*)&('%&$"!  ! ! !     "!"!"!!   !!"" ! "!$# $# $$!##""""!!!#""$##$#"$#!#" %$!&%"&%#'%$'%%'%%%$##"!%$"'&$+*',+(*)&(&%*('+*'+*&+*'*)')(&)(&((%)*%,-'++&-.*//,00-12.11-10-00,11-33023/01-11-33.44/782:;6<=9>?<??>??>????????????>?>=>==><>?=>=<??>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? %$!%#"$!#%!#%"#%"#$""#""#""$##%$$&%$&&$'%$'%#'&#(&#('$)(#('$('$(($((%((%((&((&('%('$''%((%((%'&&(&&'%&&%&&%&&%$&$%&%&&$%&#&&$&&$&&%&''$##$##%%%&'&(('((&**)++*++*+,*+,*++**+**)*)()((()(((((%%$&%$&%$&%$&%$(&&('&)('*))+*****))((('(('*)'+*)+*)+*()(''%$'$#&$#%$!%# $"%! &"!'""'#"'#")%$)&%*'%*(&)'%)'%'%#%#"#!" "!"!!   !!"""" """!"!"!!     !#!#! #  "!$# $$!$# $$!$#"!! """##"##"$#!$#!$#!%$"&%"'&$'&%'&%&%$%$"$#!%$"'&#**'*+'*+(+,*,,*,,),,(,+()(&)(&))&//,11,12,00,00-//,11.34/33.22.22/22/33022/23/440551560671;<7<=9>?=??>??>????????????=>>998<<:::8<<;????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? $#!%#"$"#$"#$"#$"#$""#!!" "#"#%$$&%$&&#&%$'&#'&"''"('#)(#('$((%((%((%(($''&(('('&(($(($((%((%('%'%&'%&&%&&%&&%%'%%&$%&$%&#&'$%&$%&%&'&&&%''%)(&('$'&$))&**)++*+,*++*++**+****)**))*)))))))))))()('('&&%$&%$'&%('&(('))'*)())(**)**)**)+*(,*)+*)+*(*)')(')'&'%#&%!&&"&$!%" &! '#!'"!'#"(%#)%$)&$)'%*'&)&%(%$'$#%#!$"#!#!" "!"!#" "" ## #" """!"!!     ! #" $$!$# " " %#!&%"%%"$$!$$!$$!##"$$#%$#%%#%%"$#!%$"'&#'&#('%('&'&%'&$&%"&%")(%*)&++'+-(--*,,*++),+(,+',+(,+)0/-22/33/22-44022.00-11.44155044.32/32/22/11.23/340552562662894=>:??<>?=??>??>?????>??????:;:998786786>>=??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"" #""#"##!##!"#"##""#!!"!!#""$##%$#%%"%%$'&#''#''#((#()$)($((%((%))%(($''&((((''((%(($((%)(%('%'%&'%''%'&%&&%&'%%&$%&$%&#&'$''%&'&&&&%'%&&#('#*(#'&")(%--*+,**+)*+*++*+++***)*+)******+++,+++*++***)(('(('''&''&((')(&)('+*(,+)+*(+*),*)+*(*)'*)(*)',*)+)'*)&(($''"(&#&$"%" &#!&# &$"'%"'%#'%#'$#'$#)&$&#!%" %"!&#!%# $"" "!#" $#!$$!## ## """!"  ! !  ! "!$# #$ $$!#$!" %#!&%"&%"&&#%%"$$!## %%#$$"%%#''%&&#%$"'&$)(%*)&)(&)(')(&*)&('%('$*)&*)&,,(-.*--*,+)*('.+*0-*0.+10-32043144155045133011/22034045/55.32/3305525515524527749:6;<7<=8=>:<<:>?=??>??>?????>???>>?899787:;9>><??=?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????## #!!" !"##!##"#$"#$""#"#$#"##"##$%&$'($'($'($((#((#()$(($)($((%((%((%'(%('&((&)(&)(%('$('$('%(&&'&&('&'&&'&&&&&&%%&#%%#&'%'(&'('&(&&'%&&$'&$('$(&$'%#))(+,,())()))*****)******+*+,+,,+,-,+,+++***)**)**)))((('((&*)'+*(+*(,+)+*(,+)-*(+(&+(&+(&+('+('+*(*)'+*')($(&#(%$'$#&$!&#!%#"%#"&#!&$!'$"'%"'$"%"!$! %""%""&#"$" $" $" $#!&%"$#!#" #" $# #" "!"!#"" ! !!!## ## $#!#!" %$!&%#'&$'&%&%$&&%%$$%%$$$#%%#%%#%%"&%$('%)(&+*&+*')(&+*(*)')(&)(%*(%,*'/,)/.*/.*0/+21-43/43/31.43065266355256234033/33/43.44.660660661772893782671793<=8<=9;<9<=:>?<<=;>>=???????????????<<<888:::??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!%$!$#!#!!"!#$"#$##%##%#"$"#%##%$"$$#%&$('$('$)'%)'$)'$)'$('$((%((%((%((%((%((&)(&)(&)(&)(&*)%)(%(&&('&'&%'&&'&&&%&&%%%$%%$%&%'(''(('(('(&''&((&('%'%#(&$&&%*++*+*)*))***+**++++++,+,-,,-,--,,-,,,+,,+,,+++******)**)+*)++)++),,*,,*++),*(,*(+)'+)'+(&*'%)(%+)&+)%*)%(&"&$!&$!'%"'$"%#"%"!%#!&$!&#!&$!&#!%" #!$" &#"%" &#!&$"%"!&$"'&$''$&&$%%#$$!$$!## #" "  !!!"#!" #!$" # %# (&$'&#'&$('%'&%&&$%$#%%$%$#%%#&%$%%#'&%)(&*)&+*&+*',+(+*(+*(()&'(%+*',*'/-*0/+00,10-44054043/44/55055165343232132022/33/5518829936608838947838949:5<>9<=9<=9<=9=>;>?=??>>?>>>>????????????;;;888???>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!%#!$" #" ""!$# $" $"!%#!%#"%$#&%#&%#'%#(%#(&$(&$)'%)'%)'%('%((%((%(($(($((%)(&)(&)(&)(&)(&)(%('%(&%'&%&%%&%&&%%&%&&$%&$%&$%&$&'&&(''('&'&&'&(('''&'&%'&%&%%%%%&&&())(**)+**,+,,,----.---,--,,-,-----,+++**)**)***++*++*++*++)++*++)++*+*),+*,*),)'+)&+(%*'$*'$*(%)'$'%"&%!&$ &$!'%"&$"&$"&$!&$ &# &" %" %# $" $" %"!%! &#"&"!&$"&$"&$"'&$''$('%%%"""## ((%))&*)&('#&$!#!# !" $# $" #!%"!&$"(&$('$('%('%('%&&$&%$&%$&%$&%$&%$%$#'&$+*'-,(-,(.-)..*.-+,,+++)+,*..+,+)1/,32.33/33/65265254055033.22.43021/200321330541773994883771874663784:;7<=9;<9:;7<=:>?<??>>?=>?>>>>>>>????????????>>>>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? %!!%"!$$ #$ $$#"#! $#!%#!&$"&$"&$"&$!&% %$#'&#''$('%((&((%(($(($''$((#(($)(%)(%)'%('%('%('&('%'&$%$#%$$%$%%%%&%&&$&&"&'#&'$&'$'(%')&&('&'''('(('((&'&%&%%&&&''')*))+**-,+-,,-,-.--.--.-,-,,,+------+++*********++*+,++,+++**+***)**)++*++*,+)-+),*'+($*&$)%#'#"(%$'%$(%#&$ &$&$ &$!&$!'%!&$ ($ '# '# &# %# ## %" '#"&"!'#"'$#&#"&#"&#"&$"(%$'$"'$#,)()*'')%*,'*,&*+&--*--**)%&&"%%"$$!$#!&%#*(&)'%*)&('%'&$''%'&%('$(&%('&('&(&&'%%*)'/.+11,22,10,10,00.--,,-+-.,//-/.+10-43/43/32/65165143000-12/00-32/32/21.430542552552773994994996886;;8;<9::89:7:<8>?<>?=;<:<=<???????????????????????????>>>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????$" %$!&& %&%%%$%$%$!%$"%$"%$"%#!%#$#$# %$"&&#('$)(%))$)($)(#((#(($)($(($)'#('%)(%)($('%)(%('%'&$&%%&%%&$&'$&'$%($&'$''$&'$''$'(%()'''&''')))'(''(&'('((()*)+,+,-,./--.-,----.,,-------,-,--,--,--,,,++++,,+,,+,,*,,+,++,*++*),*)-+*-+*-,*-,)-,)+*&)&%'#"&#"'%#&$"'%#'%"'$!&# &#&#&#'$!'% (&!(%!'$"&$"$#!$$"%#"%#!)%#(%"(%!'% &% (&")%#'$"'%$)('*(')(&**&*+&**%,+(,*'++(+*)('&'&%('&+*(++(**&++(*)&((&'&$''%))&+)'-+)+*((('()(-,)/.*10+20,0/+11.21//--,,+--,/.-/.,21.22.320/.,22021/21-10.21.11,33.44/44/662552552673784:;7<=8;;8;;8;<8:;8::8;<9=>;>?=>?=;;:<<;?>=?>>????????????????????????????????????????????????????????????<<<=<=???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? %" %#!'&!''%$ &%&$%$ %$!%#!%#!%# #"$# $# $# $$!&%#('$)($))$)(#('#(($(($((%((%''&((%((&)(&))&((&('&(''('&(%'(%&($&'#&&#'&#&%"&&#((%'(&''&''&''''(&'(&(('))(**),,+--,-.,,-+++++,+***+,,+,,,-,--,--,--,--+,,+,-+--+,,+,,+-,,,++-+*-,*-,+-,+-,+-,*-,*-,)*)(('&(&%)'%(%#(%#(%"'$"($!'$ %"%"&" &%!(&#(%"'$"&$"&%#&&$%$"(%#*'%*&$*'#)'#*)%,*'*'$)'$*(&'&$)&%+''+)'+*'+)&-*(,*(*)')(&'&%('&*)'**'))&**'*)'))&)(&('&)('*)',+(-+),+)++),,,.-*0/+10,00+11-0/,0.,-,++++--,//-//,21-21.21.0/-21/11.32/22.44/44.550995663663563451::7<<9==9==9<=8;<7:;7:;7;<8=>:=>;>?<??=??=>>=>>=????????????????????????????????????????????????????????????===111:;;>?>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? %# %$!&&!''"(( '& &% &%%%%$!%$"%%"%$"%$"%$!%$ %# %#"'&$)($))$))$)(#((#(($((&()&()&))&))&))&))&))&)(%('&)'')&')&&(%&'$&&#'%#&%"&&#''$''$''%''%&&&''%''%((&))'))'**(**(-.+,,*++)))(()')))***+++,-+--+--,,-+,-+,,+,,*,,),,+.-,-,+.-+.-+.,+.,+-,+,+*,*)+*)++*,,*++)*)&(&#(%#)%#(%$($"'$ &# &#!'$#'%#(%#&#!&#!*(&*)'''$*)&,)'+(&+'%*'%*'%)'$)($)($*)&++'+*'+(',)(-+)-+),*(,*(,*(+*'&%$'&%('&+*(*)&)(&**()(&)('('&'&%)'&*)',+(+*'*+(**()((.,*/.*00+/0*..*1/,0.,-+*,,+//.//-00,21.21/32/43054111.21/440661772983;:6663553774785<<9;;7=>9>?:;<7;<7;<7=>:>>;??<>?<>?<>?=??=??>??>??>?????????????????????????????????????????????????????????>??9;:<?><?>=????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!%%!&'!&'!&(!'("()!'(!&'&%&% %$!%%#&%$%$"%#"%$!%$!&$!&$"'&$))%))$)(#('#('$(($))$))%))&**$))%))&))&)(&)(&)''*'(*''*&&)%&'$&'#&'$''$&'#''$''%''%&'%&&$&'$((&)(')('*)'**(**'--*+,)*+(()'''''''*++,,*,-*--+,-*--+--+,-*--*--+.-,/.,.-+/-+/.,.-,.-+,+*+**+**++*--+--+,+)+*(+)&*(%)&%'#"&# &#!(%#)&%)'&)&%($#*&%*(&((%((%.-*/,*/,)-*',)&*(%*'$)($**&+,'--(,+'-+)+*'--),,',,',+'-,)((%&%#('&*)(++))(&+*(+*(*)'('&'&%'&&)'',*(++(*+()*'))(*()/,*/.*/0+./*..*1.,0.,-,*++)..-//-10-21.0/.22/54044011.653774763883882994994774896895996:;7<=9=>9>>;>>;>>;>?<??=>?<=><>><>?=??>??>??>????????????????????????????????????????????????????????????>>>:=<9=<:?><???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? &'!'( &(!')!'*"'*#(*"(( '''& &%!'&"&&#%%"$$"$$!%$#(&!'%"&%#''%(($(($''$((%)($))$*)$*)$*)%))$('$((%)(%)(&))'))'))()('(&&'%''%'(%''$''$('$((%'(&''&&'$&(#('%)(&))&()&**&))%)(%()'*+)()'%$#&%$)('+*(,+*,,+,,+,-+-/+..*.-*.-,.-,.--/.,/.,---..-..---,-,+,,+..,..,..,--+,,*++)++)*)''&#'%#)&#+'%,(%+('*&%*'%,)(+)(('')(&..*/.*/.+,+),+)+*()'&*)',+',+&,,(.-*-.),-(,+'*)'**(++)++('%$'%$)(&-+)-+))(%++(**())'((&''%(('++)*)'++),+*++*++)+,)-.*..*/0*/0*22-12-10-.,*.-+0/-0/-//,12./0-22/562562450783884772783894995995773896886::9:;9=>;>?;>?=??>??=??=>>=>><>?<>>;??=??>??>???????????????????????????????????????????????????????????????>??;==8=<;?>=???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? '( '( '(!')!'*#),"(*!() (( (( ''!''!&&"&%"&% $$ $#!%$$'&"&&"%%#&&#''$''$((%)(%*)%+*%+*$*)$)($''$''$('%('&)(&))&)(&('')''(&'(&'(%&'$&'$(($((%&&$''%''$&'#'&#('%((&)(&('$('$('$&&%(('**()(')(')(&((&**)++*+++,,+..+..+..+/.,..,..-//-0/..----,..-..-//.//-//-//-//-//-//-..,--+,,*-.+.-*-,),+(,*(+)(+('-*(,*(,*(+)(/.+..)//*/.*,+',,(*)&)(&*)'*)&+*&+*&,+(--(-,'*(%+(&*'&-+)('%'&%'&$+*(,,)+*'*)&**'**'))'((&''%**),,*-,)-,+,,+++*++)-.*//,00,01+11,44/33///-,+*--+0/-//-//,12.01-3406727838949959949948849949958848939:5::7==;>><>>=??=>?<>?<??=>?<??<==;==:;<9==;??>??>???????????????????????????????????????????????????????????????>??=??:==:=<=????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!()!() ')!()!(*"),!(+!)* )* )* () '( &'!'&!'% %$ $# $#$'&#&&!%%!%%"&&$''%((%))%*)%**%**%*)%((%'(&((%((%('&))&*)&))&)('*((*(')''(&&'%''%''$''#''"((#('$''$&&"'&#'%$(&%'%#'&#('$''%('%('%)(&+)'(&%&&%+++**+(((++*--+..,..,//-/0-00.//..../.......-//.//.//-//-00.00.//-//-..,--,--+//-00.00-//,--*-,+.-,/-+.,*/.+0.-/.,/.*//*-,(,+(+*'*)&+*'*)&*)&,+(,+(.-).-(.,(-*'-*(.+*-+))(&('&))'-,*,,)*)&+*'++(**'**())'*)(,,*.-+-,*--+,+*++*--+-.*//-00,..*/0+22.22./.,--+/.,/0-/0-/0,01-11-440673773884884883::5::6;;7::5;;7::5<=8>?;??=??=??=>><;<9=>;>?<>?<>><<;9==:>><??>??>??????????????????????????????????????????????????????????????????>??=??=?>=>>>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!))!)) ()!(*!(*!(+!), )+ )+ *+ )* () '("'&!&%!&%!&% %$!&%!%%!%%"%%#&&$((%))&))&**&+*&+*&**%))%((%''%((&)(&))&*)&*)&*)'*)')(')'')''(&'(&'($&&"&'!''!'&"(&#'&!'&"&#"'##'$$'&$))%)(&)(&)(&*(&(&$'%#$$#$$$%%&%%%%$$,,*--+-.,/0-01-00-./..........10/11000.00.//-00.00.//-..,..,/.-10/20/1//0/-0/-/.,///00/0/-10.20.20/1/-0/-0.,-,*,+**('.-,.-*-,),*)+*'-,)0/*/.)/.).,),)(-+*+*(((%''&++)//,--*,,)//+,,)**'**())'*)(--,--+--*--+,+*++*-.+--*00.00-//+00+11-23///-..,//-//,/0-/0-/0,22-5617847735636639:5::6995;;7=>9??:>>:>?<??=??>>><;<9::6;=9>?<??<??<>>;=<9>><??>??>?????????????????????????????????????????????????????????????????????>??>??>?????>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????")*!()!()!()!()!()!)+ )+!*,")*!(*!() (( '''&&%&$ &$!%#!$#!%$"&%"&&#''$)(%*)%**&+*&++&++%**$)(%((%((%(('))&))&))'**&))&))'))'(((((((''(&&(%''#'&"'%"'%#&%"%$!%"'#'$!('$)*&)*%)*%++&*)%('#'&"$&!"# #""%#$*)(,+'++'--*/0-..-//.//...-//-//-12/12/01.01-00-00.00/./.-.,./-12/22/2101001//1/.1/-0../.-1/.21020/21/330//-..,-,*)(&,,*+,*-,+.-,,+).,)/-*0.*0/*0/+-,(,+(+*('&%('&('%+*(..,--*/0,./+--*++(**()*(++)//,0/+.-*--+,,*++)..+//,11.11.00-11.00-00-00--.+/0,01,00,11.11.3306747847846739:5;<7<=8>?:>?<>?<??=>?>>>>==;=<9:96;:7=<9>>:??;??;??;??;??;??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????")*!()!()!()!()!() (*)*!)+")+#)+")*"))!(( '''& &%!&$!%$!%$"%$"%%"&%"&%#('%*)%*)&+*&++&+*%**%))&)(%)(%((%)(&))&*)&**&)*&))'))'))'(('(''(''(%''$&&#'&#'&#%%"%$ %"&"'$ (&#)(%))&**'*+())&('%&&#$% ## $#!(&%-*)+)&)(&))(--,------.../..00.00.11/01.01.01.12/01//0/.....-00/2202212223231/01//0/.0/./.-21010/210210220/0./.-+*(*)'..,+,)..,-,*,+)/.+0.+0/+//+/.+,,(,,))(&''%)('*)&-,*..+..+//,--*-,*+*))*(*+)..+//+0/+-,*-,***)++)//,01-11.12.01-23/01-11-00-..+01,12-22.23/442774885673895894:;6<<9>?<>?<>?=??>??>===;;:::7;:5;93=<5>>7=>8??:??;??<??=??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????")*!()")*!()!()!() (*!)+!)+#)+#)+"(*"()!()!()!(( '&!'&"&&"%$"%$"%$"&$"&$"&%$('%*)&+*&++&+*&**%**&*)%)(%)(%)(&))&*)&*)&**&**'*)'))')('(''('''%&'$&&#&&#%&#$$"$# %"'"(#(%!('#)(%)*'(+'(+''(%''$%& %% &$!'$!+(%)&$'&%***((()))+++///00/11.11.11/12/01//1./1.01//0/0013224323323323333340011000/.10/210332110210210/0...--,+*)'10--.*+,)-.+,-*--*..+//,/.+/.+--*-,*,,*)(&('%))&--)0/+..*..+/0,-.*-,++*)**)+,*//,11,/.).,)+)'*)(,+*--+01-22/33/22/33022/33011../*01,22-12-340673774885885:;7;<8=>9??=>?=>><??=>?=::8674895::6<;5>=6?>7>>7>>9??;??<??>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????")*")*")*!()!()!() () )+!(*#)+$)+#(*"()"(*!))!()!(("''"&&"%$#%#"%#"%$#&$#'$#'%$)(%**%**&**&+*&+*%*)%))%*)%*)%)(%)(%*)%**&**&*)'*)&)(&(''''&'%&&$%&"$&#$&$$%"%$!%"'")$)% (&!'&"')$'+%(+&'*%()$''!'& (% ($!)%"*&%('%&&%$%#**(*+),,)//,00-11.12/12/11//0/.0./0///011233353354245234244333244233022/330332221221000./.,,,++*.-+00-./+-.*,-)+,),,)..+//,0/-/.,,+*.-,*)(('%''%**'.-(//*--)/0,00--.*-,+++*++*-.,44021,0.*.+)+*(,*).-,//,22.22/33023/33023/33/00,-.)01+12,11,6727746748859:6=>:=>:=>:??<>?<>?;>>;:;78959:59:5::4;:4>=8??;??<>>=??>??>??>??>??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!(,")+"))"))!((!&(!()")*")*#)*#)*#)*$)+$*+#))"))"))"((!'&"%$$&%$&%#&$#&$"&$#'&#''$''%))&**&+*%+*&+*&*)&*)&*)&))&))'*)&*)&+*'+*&**&)('))&'(%''$%$%%#&&#&&"&%!%#%#&#'$(%(% (%!''"()$')%')%()&)*$)(#'&!&$'$ )%"*&$(%#&%$$$$&&%)(&,)'-*&0.+11/010/0./0./0//0.12045345345244254244244245345345244244243244332100//-,+)'+)(/.,//,..+./++,),-*,-+-.,/0-/1,-.,--,--+'(&(('))(++*,,),-*-.+00-//,-.+---,,,,.,.0-34022.22-10+,+'-,)0/-20.32/32032/32/430541431//-..+01-23.783;;7:;78869969:6<=9>?;>?:??<=>;::89:7::7:;6;;6:83:94;;6<<7==9>>;??=??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!)+!)*")*!()!((!(("))"**")*#)*$*+$*+$*+$)*#**"))!)(!('"''"&&%('$('#'&"'&"'&#('#('$('%((%))&+*%+*%+)%*)&*)&*)&*)&*)&*)'+*'+*&+*&*)&)(&((%('&(''(&()&))%''"&% &$&$&$'$ (&!)&!)%")&"(&"('#)($*)%**%()$((#'&!'&!(&"(%!(%"(&#%%"('$.,)-*&-*',*(..,+,+,.-,-,././/.332554553553452442553453564553563453553443331221..--,++*)*)'/.,/0,22///,++),+),+*-,*//,..+--*./,+,)()&))&*+(+,(,,)--*/0,//,-.+-.+-,,,,,-.,.0-23/22.44010,.-*.-+0/-0/,0/,22.22/32/43055266222012/561672893;<7:;7::79969:6<=9>?;??;>?;:;7;;8<<9::69:5:;5;;5;;6==8<<7<<7>>;??=??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!**!)*!)*!))!))")("*)#*+")*#*+$*+$*+$)*$)*#**"**"*)")("(("''#))#)("(("((!('!('"''#''%(($((%*)%**%+)&+*&+*&+*'+*&**'**'++',+&+*&*)&))&((&)('*()+(*+(*,'*+&('"&% %$%$&% (&!(&"(&"(&"(%!)&")'"+)%*)$))$))$*)$))$)(#(&")'"*)$*'")&"+'#)$".*(-+)--,*++,---.-./.22145445345345344254255355355345345345355444223101/-.,&&%,+*,-*//+01-/0-++*,+***(-,*//+.-*--*-.*-.+((&)*()*'/0*/0*,-*00-/0--.*..+-.+,,+,-+-.,.0-23022/4410/-..,/.-11/10-//+341330330672::5994552563884783994<<8:;7;;7;;7<<9==:>>;>?;=>9<=9??<==:=>9<=7;<6<>8<=7<=7==8==9>?;??=??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"+*!**!)*"*+"*)"*(#*)#*+#**$*+$*+$*+$)+$*+#)*#**#+*")(#)(#))"))"))"**"*)!))!)(")'#('$((#''$((%*)$*)%+)$*($)(%*)&+*'+*(,+',+'+*'+*'*)&))&))'*)(*)')'()&)*&)*$''!%%&% '&!(&"('#''#'&")&")'"+*$+*$+)%+)&+)%+)$)(#*)$*($)'$+($*'",'#+%#(#!,)')'&))()***++010010332332332331342553553442553553553453343343121120/0.&'%###//./0,/0+01,..,,,+,-,-.,/0,/0,,.*,-*+,))*('''(((**(12,12-//,00-12.00-//,./+--,-.,-/,/1.12012/44111/00.22122022/5515634516629:5:;59:4562552783883<<7=>9:;6<<8=>9<=9;<8=>;??<=>9>?;>?;>>:>>:=>8;=6;=6<>8<>8==9=>9??;??=??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"+*"**"**#**"**"**"++"++"*+#++$++$**$*)#*+#**$*)$*)$*)$)*#*)#**#**#*+"))")(")(#)("))#*)"('"''#((&))&))%((%)(%))'**(+,)+,)*+(*+(**'+*&+)')(%(&&('(*(()'()'))%((#'&"'&#'&#((#((#)'#)'#)(#*)$**%**%*+&**%+)$+)$+)$*)$,*%-,&0.).+'+($,)$)& +'$+'%(%%)()+,,.1057446233111/11/43255355255245245335335322302/02.010)(+# #-,-//.//,01,/0,,-+----.,./-/0...,,-*,-),,)((&((&(('++)01-12-01,12/12./0-./--.,-./-..01/01.01.11.23034133034123/341442442552663:;79:5893561562885896:;6<=7;<6<=9<<99:7::7<=:>?;>?;??<??=::7:;6;=6<=6<=7=>8==:=>;>>=??>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"+*"**#**#**#**"++"++"+,#++$,+$++#*)$**#)*$**$+*$*)$*)$**%+*$+*$++$*+#**#*)#)(#)(#*)#+*")(#)("''$)($)(%))&**&+*'++'++(,,),,)++)++(++'+*'*)%'&')'()()*(()''(%&($&'%&'$&(#(*$()#)($)($))$*)%*)%*)%*+&**%+*$,*$,*$+*%--'00)22+11+..(,,%,,$-+$+)#)&#*&%,))0//672670671662441330542553554554454354344/01/00.0.+,+$$%+**10/00.00-//+..*,,*--,--+/0-01.-.++,),-)+,))(&)(&+*(++(//,12-34/45101-/0-./---,,.-./-12/12.11.11.01.01-341452341451674663663773:;6::5894672663784996<=9;<7;;6::6::5;;6=<7>=9?>:??<>?<==;885:;7=>9=>9==9>?;??<??=??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"+*"+*$++#*+#++"++"++"*+#+,$,,$**$**$**$*+$+*$*)$*(%*)%**%**%**%**%*+%*+&+*%*)$))$*)#*)#*)$**"('$)(#(($((%*)&+*&++&++',,(,,),,),,(++&+)'*)&)'&(&(*()*(()''(&&(&&'&&(%'(%(+&(*%(($(($))%))%)($**%*+%++%,+$-+$,*%+)$,,&..'//)./)./)01*/0(--&.-&.,'41-0-+0-,43.45.44.550661;:6763775665443454132122000./.020&((!"$++*/0-12../+//+--*,-)--*-.+/0-/0--.*-.*./+,,)*)'+*'++'-,(.-*33/57134//0,/0...---,,.+/1-12.12-12.12.00-01-451451451451673773772894:;6:;59946736739:6;<8==:;;9<<9>=:==9<<7==8>=:?><>?===<<<:==:>><>?=>><>?<??=??=??>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!**"**#++$++#++"+*"++"++#++#++$**$**$*)#**%++%+)$*(%*)%+*&+*&**%)*%)+%*+&++%*)%))%**$+*#+*$+*$*)#)($))$))$))$*)&+*&,+'-,(,,(,,),,),,(,+(*)&('&('')'')'()')*'((&&'%&&%''&()'()&()%()%)*&**',,(*)&*+%++%,+$-+$-+%,+%.,'.-(.,(.-*..*/0+./)..*..*/.)10+21-10-11.22.22.550771;:4872552774:;99:7897564442230020 #$$%(.//00-44011.//,-.*-.*-.*-.*/0,./+-.*./*./*,+)+*',+(.-(/.*/.+0/+46/12,/0,00.-.-,--,/+02-12,12,12-22/00,23.4513403405627839:59:4;<6;<7;<6:;5885774;<8??;>?<??>??>??>??=>?;>?;??=???=====<??=??=??=??>>>>??>??>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"**#**#++$,+$,+#+*#,+",+",+#,*#+*#+)#+)#+*$,*%+*%**%+*%,*%+*&+*&**&**&+*&+*%**%*+%*+%*+%+*%+*%+*$,*#+*$++%++$+*$*(%+('-+'-+(-+(-+(-+),+',+&)(')()))''&(('))'**('(&&(%')&'*'')'()'*+'+-(+-(,-(+,(,-',,&,+%-,%-+&-*&.,'.,'--',-'./)--(..).-*-,)0.+10,10,20-21.21.32/551651883772550550::57955869><7<6696-.- !%%%,,*33.671552220//--.+-/*./*/0,./+-.*-.*-.*,,)--*--).-)/.*20,0/*34-23./0-./---,-.,/1*24-23.12.33/34/11,44166333022/672893;<6<=8:;6<=8>?:=>99:5894=>9??<??=????????>??>??>>>=??=??=??>??>??>??>??>??>??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"++"++#++$,,$--#,,"++!++"+,#+,#++#**#**#+*%,*&++&+*'-,&,+%,+&,+%,+%,+%,+%,+%++%++%++%+*&,+&,*&,*%,+%,+&,,&--%+*%+(&+)%+)',+(-+(-+'+*'*)'*)&('()()+*(+)&*''*')+)*,*(*()+()+)*+)**(+,),-(,-(+,(,-),-(,-'-,&-,&-,&,*%,*%,*%,+%,,&-.(-,(.-),,((($-.*/0,//+01-22/32/44044033/33.54065175176165111/5757:7353$$#*)(0/-55056/57045145346435213//1-01-./,./+-.*+,)-,)0/,-,)00,/0,12-23-24-24/12../-/0.23058157145034055156133.450773441440883:;5<=9>?;>>:>>:??;>?;:;7;;8>?;>?;??=???>?>??=??==><<=;??=??=??>??>??>??>??>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"++"++#,,$,-$,-#,,"++!++"+,#+,#++#**#+*$,+%,+%+*',+&++&,+&-,&-,%-+%,+%-+%-+&,+&,+&,+&,+&,*(-+',+%,+%,+&,,',,'-,',*&+)$*(%*)&+)(,+&+)&)(&)(&)((+)),*).+'.*',)'*()+))+)(*()+)+-++,*+,)+-(+,',-(+,(+,(,,',-'..&.-&,*$+)#+(#*)#**$.-(/.)/-),+'*)&,,(..*01,02-12/22034145255255155165176153.63/42/10.343+,*0/-;9632-76/77035.23/34313224302001.01.01.12/22//0-431=;954200-12.24025/24.34012.01.12/240570793683561894783551;;8<<9885885995>>9??=??=??=??=??=??=::8895;;8>>;??===<==;??<>?<<<9==;??>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"+,"+,#,,#,-"+,",,"++",+",+#,*$+*$+*$+*%,*&,+&+*'+*&++&++&,+'-,&-,&,+'-,'-,'-,',,',+&,+&,*&,*(-+&,+%++&,,',,(-,(,+&,)',*&+*&+*'+*&+)&*)%+)'+*(,+)-+(-*(-*)-+)-+'+)),*(+)(+)+-+,-++,)-.),-(+,(,-)+,)+,'*+%+,$--%,+$,*$,)$+)$*)$,+&.-(.,(,)&+)&+)&,,(..*/0,11.11/23045133045245156277265064/640430441--*32.:8464/75076056/21.110000///00/11/12/./,01.2202303315425534524513414625614516737858958959<4:<6:<7;<7=>:>?:??<??=>>=>>=>><==:??;??>??>??>??>>>>??>;;9::8<<9=>:=>;<<:=>;>>:=>:<<9>?<??>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!++"+,",,#,-#,-#+,#++#,+#-+#,+$,+#+*#+*&++&,+%,+&,+',+'+*',+',+'-,'-,'.,&.,'.,'-,'-,'-,'-,'-,'-,(--(.-(--',,'-,(--'-,&-+&-+&,+&,*&+*&+*&+*&+)',*),+),*),**-**-+*-,)-,)+**,*,-*+-*,-*-.+,-*+-*+,)+,(,,(++&+*%,+%-+$.+%.*&.+&-*%-+&.-'.,',*'-+'-+(,*'-+).,).-+11/11022023045156166256144/55066134/44122/77376265175177077000+//,00.00-12-01/11/23012.13.24.2403515615604504405533413424547867856838:49:3991<;5>>9??<??=??<??=??>??===:??<??>????????>??>>>><=:<<9==:>?<>><??=??=??<??<??=??>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ++!++!,+",,#,,#,,#,,$-,$,,$++%,,%,+$++$,+$,+$-+$-+&-+'.,',+(,,(-,(-,(--(--'-,'-,'.-'-,'.-(.-'-,(..)/.(.-(.-'--(--'.-&-,&-,'.-&-,&++&,+&,*&+*(,+(-+(,*(,*),)*-*)-+)-+)-++-+,.*+.*+.*,.*,.*,.*+.*+,(,-(,-'--&.-%.-$/-&.-&0.'/.'.-&0/(/.'.-'/.)0/)/.)/.).-(-,)--*12/33134145035135224113035135234122/23/77377377265144/782985::6>?;<=79:377145056135/34/35023/34067255144/44044043021.22/763551::5982;92=:3>;4?=7?=9>=:>><??=>>=??>>>=??=??>???????????>>>><=;>>;>?<??=??=??>??>??=??=??>?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????!++",+",,#,,#,,$,,$--%--%,,$,,%,-%,-%,-$,+#-+#.+$.,&/-(0.'-,(-,(--(--(--(--(--'.-(.-(.-(.-(.-(.-(.-(/.)/.(..(.-(.-'..'/.'.-&--'--'--&,+&,*',*',*'-*(,*(,*(+)),))-+)-,)-,*.++.++.*+.*+.*+.*,/+,.+,-),.),-(..(/.'/.&00(00)11*00)//'0/(0/(00)11*00)00*//*..)..)++'00,441451340240/1./1.13114124202013/6737748958837726617738849:5:;5;;5::366/45.44.33.23.34034/33.44033/440761772883883662;;6;;5<=6:93?=6?=6?<5?=7><8=<9>><??=>>>????????>??>???????????>??>??=??=>?=??>???????????>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"+*#+*#++$,+%,,%,,$,,$--$--$--$--%--%--%-,$.,$.,$.,'/-(0-&.,&.,'.-(.-'-,(-,(-,(.-(.-(/.(.-(.-(/.(/.(..(/.(/.)0/)0/'/.&.-&--&..'..'..'--'.,(.,'-+',*',)',)),)(+((,*(-+).,*.++/+,/+,/++/++/*+/*+.*+-*,-*,-*..*..)/.(00*/1*01+01+11+0/*00*/0*00+//*//*//*..*00+./),,(//,23/45123/01.01.13002//1.01.240452673783783783782560671882:;5::499487377233/33.11-23.44.44.773763:95:94993=>7<>7;=7<=7=?7<>5:;5??9??8??8??:>>;=>;??<??=??????>>??????????????????>?????>??>??>??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????$++$++#++#++$,,#++#,,#--$--%--%--%--%..$/-%.-%-,%+*(.-'.-'.-'.-'.-'.-'.-&-,&.,&/,'.-(,-*./(./(/.)/.)/.(.-*/.)/.)/.(/.(/.'.-'.-'.-)..)/.).-(--(-,(-+(,*(,*(-)'-(',)(,)(,*)-++.,+.++.+,.++.*+-)+-),,(,-)-/*-/*./*/0*00+/1,01,00,00,00,00+10)00)./*/0+./+./*0/*/.)//*01,01,00,11.11.11-23/02-.1+02-45/34.552774885874884662772994;:5<;5<;4:;3::3772671883;;5;<5:<5:<4:;4:;4<<5<<5;=5:;59:59:5;=7<=7:;5>?9>?:>?:>?:=>9>><???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????$++#++#++$,,$-,#,,#--$-.%-.&-.&--&.-&/.%/-&/-%-,%+*&-,&-,&-,&-,&-,&.-&.-&.,&.,&.,'.-(--)./)//(/.(.-)/.(.-)..).-(.-(.-(/.'.-'.-(.-)/.(..(.-(.-)/.(-,(-+(-+'.+&.*'-*(-*)-+*-+*,+*-++-++.+,.++.++.+,-),-*-/+-0+.0+/0+01,02,01,/0+00,00,00+12+01+/1,/2./0,./+/.*//*01,13.12.11-22.01,01+02,01+02+46.56.23-34.672772760671994994994::4<;5<<6;<4;;59:5;;7<=8<=7:;59:49:4:;5>>8>?9=>8:<77:58967969;7:<8:;7??;??<>>;>?<>><>>=???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????$,,#++#,+$-,$.-#-,#.-$--%--&.-'/.&.-&/-%.-'/-'.-&,+&-,%-,%-,%-,%-,&.-&.-&.-&.,&.+'.-'--)//)//(..(/.)/.(.-)..).-)--(--(/.(/.(..(/.(/.'.-'/.'..'.-(.-(.-(.-'.-'.-'.-(-,)-,*-,*-,+.,+.,*-+*-+*-**-*+,*+-*,/+,/+-/+./+/0,/1,/1,/1,01,01,11-12,02-/2..1./1./1-00-11-12-03-13-13-34/24.23-02+02*13+45.56/45.44/6717707707807929;3:;5:;4;<6==7>?8<>8:;7<=9;<8<=8;<7;;7>>:>?:>?9=>9=>99<79<89;88:7:<9;=9>>;??=??=??=??>>?=>>>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????$,,#++#,,$--$.-#-,$.-$.-&.-'/.'/.'/.'0.'/.&.-'.-'-,'.-&.-%.,%.,%.,&.-&.-&.-&.,'.,&.-&--(./)//)..'/.(/.(.-)/.)..*..*..*//)/.)/.(/.(/.'/.'/.'/.(//'/.(/.(/.(//(..(..)..).-(.,)-,*-,+.-*.,*.+*-+)-**+)*,)*-*+.*+.*,.*-/+-0+/1,/2,02,02,23.12-/2-.1..2//20.1/00-11.23/14.24.24.24.14.24.12-23-23-44.35/12-44066277188167/:<4;=5;<5<=6==7>?9<>8;=8785563785;=9>>:>>:>?;??;>?;=?:<>9<?9;>89<79<8:=9;>9>?<??<??<>?<??=??>??>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"+*"++#,,$--#--$/.$/-$.-&//&/.'//'/.'//'0.&/-&/-&/-%.-%.-&.-&.-&.-'.-&.-&.-&.-'.-'..'..(//'..(//)/.)..)/.(.-)..)/.*/.+/.*/.)/.)//(/.(/0(0/(0/(0.'0-'0.'0/'//)//)/.*0/*/.*/.*/.*/-*/-).,*/,*/,*/,+/+*-*+.*+-**-*+-)+-*-/,/0,01,12,03+03+03-/2-.2.-2//2//2.02-13-15.15-25.24.24/13/23.22,33,33,33-32.11-23/561662873883==7==8994<<7<<6<<4;>7;>89;66739:5>?:>>9==9>?;??<==:=>;;=9;>9:=89<8:=8:=9;>;=>;==;=><>?=??>??>??????????????????????????????????????????????????????????????>??<<<8??;??=??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????$,+$,+$,-$--$.-&/.&/-'0.'0.'0-'0.'0.&.,'/.'/.&/-&/-&.-&.-&-,&.-&.-'.-'.-&.-&.-&-,'.-'/-(/-'/-'/-)/-)/-).,(.,)/-)/-*/.+//*//*//)//(//(/0)00(0/(0.(0.(1/(0/(0/)11)10)10*10*0/*0/+0/*/.)/-*/-*/-+0-+/,,0-+/,+.+*-*+-+)+)+,*--+--)//+01,02,/2-/2./2./2//2/02.02.13.24.25.24.35024/13/23.23-44-44.44.43.661450561560772994:;6;;7773;;6==7;;4;=5:<58946739:5=>8=>8==8??:>?:>?:;<8:<8;>9;>9;=9;=99;8;=;:;8897>?=>?=??>??>????????????????????????????????????????????????????????????>>=>><995>>;??=???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????*..(.-%,,$--&.-(.-)/.)/.'/.&0-&/-&.-'/-'/.'/.'/-'.-&.-&.-'.-'.-'.-'/-&.-&.-&.-(/.'.-'/-'.,'/,'/,(.,(.,(-,(.-)/-)/.*/.*..*/.)/.)0/)00)00)0/)00)/0)00(00(0/)10(00(00)00*10*10*0/*//+00*//+0/+0/+0.+0.,0.,0.,0.,/.+.,+-,+,+++*,,*,,*,.++-*-0-.1-/1-/1,/2.03/03/23034/34/33/2411301304405506606606617726727936835617739:4:;3;<6:;4;<5<=4<<4<=6993884895<=8>>9>>9>?:??;>?;=>:9:6;<9<>;=?;>?<<><:<:8:8785775:;9>?=??>??>??????????????????????????????????????????????????????????????><=;887;<:??>??>????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????*-,)--$+*$,,#*)(--(,+',-%,,$.-$.-&..(..&.-%-,&-,%-,%-+%-+%,+%,+%-,&.,&.-&.-&.-%,.&-.%,-'.-'.-'.,&,,',-',-'--(-.(-.)--)--)--(.-)/.)0/(//*0/)/0(/0(/1(//'/.(/0)/0+12*00*00+00*/0+/1*/0)..*//+00+0/(-,+/.+/.,//+..,/.*.-),+)+*)+*)+)),**-++.,-/,..*./*./+.1-/1/12022/21.22/01/02/2314515505505505615635636855746857746748969:7::8<;9;;7:94:95985875::8;<9==:>>;<<9??=>><;<:675786563563786;<:9:8786675997<=;>?=??>??>????????????????????????????????????????????????????????????>?>>>=<=<<==>?>>?>???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? \ No newline at end of file
diff --git a/PerlMagick/t/input.ico b/PerlMagick/t/input.ico
new file mode 100644
index 0000000..f714eea
--- /dev/null
+++ b/PerlMagick/t/input.ico
Binary files differ
diff --git a/PerlMagick/t/input.im1 b/PerlMagick/t/input.im1
new file mode 100644
index 0000000..d1cecd5
--- /dev/null
+++ b/PerlMagick/t/input.im1
Binary files differ
diff --git a/PerlMagick/t/input.im24 b/PerlMagick/t/input.im24
new file mode 100644
index 0000000..9543824
--- /dev/null
+++ b/PerlMagick/t/input.im24
Binary files differ
diff --git a/PerlMagick/t/input.im8 b/PerlMagick/t/input.im8
new file mode 100644
index 0000000..234e19a
--- /dev/null
+++ b/PerlMagick/t/input.im8
Binary files differ
diff --git a/PerlMagick/t/input.mac b/PerlMagick/t/input.mac
new file mode 100644
index 0000000..2fc83a2
--- /dev/null
+++ b/PerlMagick/t/input.mac
Binary files differ
diff --git a/PerlMagick/t/input.miff b/PerlMagick/t/input.miff
new file mode 100644
index 0000000..7740ad5
--- /dev/null
+++ b/PerlMagick/t/input.miff
@@ -0,0 +1,9 @@
+id=ImageMagick
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+background-color=gray74 border-color=gray74 matte-color=gray74
+{
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/input.mtv b/PerlMagick/t/input.mtv
new file mode 100644
index 0000000..b687b5e
--- /dev/null
+++ b/PerlMagick/t/input.mtv
@@ -0,0 +1,2 @@
+70 46
+0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/input.p7 b/PerlMagick/t/input.p7
new file mode 100644
index 0000000..3c3a1eb
--- /dev/null
+++ b/PerlMagick/t/input.p7
Binary files differ
diff --git a/PerlMagick/t/input.pam b/PerlMagick/t/input.pam
new file mode 100644
index 0000000..6ac2712
--- /dev/null
+++ b/PerlMagick/t/input.pam
@@ -0,0 +1,8 @@
+P7
+WIDTH 70
+HEIGHT 46
+DEPTH 3
+MAXVAL 255
+TUPLTYPE RGB
+ENDHDR
+0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/input.pcx b/PerlMagick/t/input.pcx
new file mode 100644
index 0000000..c9c0092
--- /dev/null
+++ b/PerlMagick/t/input.pcx
Binary files differ
diff --git a/PerlMagick/t/input.pict b/PerlMagick/t/input.pict
new file mode 100644
index 0000000..0b9d7ad
--- /dev/null
+++ b/PerlMagick/t/input.pict
Binary files differ
diff --git a/PerlMagick/t/input.psd b/PerlMagick/t/input.psd
new file mode 100644
index 0000000..49973f4
--- /dev/null
+++ b/PerlMagick/t/input.psd
Binary files differ
diff --git a/PerlMagick/t/input.pxr b/PerlMagick/t/input.pxr
new file mode 100644
index 0000000..25b6cc5
--- /dev/null
+++ b/PerlMagick/t/input.pxr
Binary files differ
diff --git a/PerlMagick/t/input.rle b/PerlMagick/t/input.rle
new file mode 100644
index 0000000..fc9f7c6
--- /dev/null
+++ b/PerlMagick/t/input.rle
Binary files differ
diff --git a/PerlMagick/t/input.sct b/PerlMagick/t/input.sct
new file mode 100644
index 0000000..cc367a9
--- /dev/null
+++ b/PerlMagick/t/input.sct
Binary files differ
diff --git a/PerlMagick/t/input.sgi b/PerlMagick/t/input.sgi
new file mode 100644
index 0000000..6a65180
--- /dev/null
+++ b/PerlMagick/t/input.sgi
Binary files differ
diff --git a/PerlMagick/t/input.tga b/PerlMagick/t/input.tga
new file mode 100644
index 0000000..022ec4d
--- /dev/null
+++ b/PerlMagick/t/input.tga
Binary files differ
diff --git a/PerlMagick/t/input.tim b/PerlMagick/t/input.tim
new file mode 100644
index 0000000..2b007a5
--- /dev/null
+++ b/PerlMagick/t/input.tim
Binary files differ
diff --git a/PerlMagick/t/input.viff b/PerlMagick/t/input.viff
new file mode 100644
index 0000000..1d26d54
--- /dev/null
+++ b/PerlMagick/t/input.viff
Binary files differ
diff --git a/PerlMagick/t/input.wbmp b/PerlMagick/t/input.wbmp
new file mode 100644
index 0000000..58d6469
--- /dev/null
+++ b/PerlMagick/t/input.wbmp
Binary files differ
diff --git a/PerlMagick/t/input.xbm b/PerlMagick/t/input.xbm
new file mode 100644
index 0000000..68d87dc
--- /dev/null
+++ b/PerlMagick/t/input.xbm
@@ -0,0 +1,38 @@
+#define input_width 70
+#define input_height 46
+static char input_bits[] = {
+ 0xfe, 0xfe, 0xee, 0xae, 0xea, 0xaa, 0xfe, 0xae, 0x2a, 0xff, 0xff, 0xff,
+ 0xff, 0xfd, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xbb, 0xaa, 0xaa,
+ 0xfe, 0xbf, 0x3e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x7f, 0x37,
+ 0xff, 0xff, 0xef, 0xee, 0xee, 0xae, 0xee, 0xbf, 0x2a, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x5f, 0xfc, 0x7f, 0x34, 0xff, 0xff, 0xff, 0xbf, 0xaa, 0xab,
+ 0xea, 0xbf, 0x2a, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf5, 0x7f, 0x35,
+ 0xee, 0xee, 0xee, 0xaa, 0xea, 0xaa, 0xaa, 0xae, 0x2a, 0xff, 0xff, 0xff,
+ 0xff, 0xdf, 0xdd, 0xdd, 0x5d, 0x30, 0xbf, 0xfb, 0xfb, 0xab, 0xaa, 0xaa,
+ 0xaa, 0x2a, 0x28, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xf7, 0x77, 0x0f, 0x00,
+ 0xee, 0xea, 0xee, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a, 0x08, 0xff, 0xc5, 0xdf,
+ 0xdf, 0xdf, 0xff, 0xdd, 0x1d, 0x00, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0x2a, 0x00, 0xff, 0x11, 0xfd, 0xff, 0xff, 0xff, 0x5f, 0x15, 0x00,
+ 0xee, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0a, 0x00, 0xff, 0xdd, 0xfd,
+ 0xff, 0xfd, 0xff, 0x5f, 0x14, 0x04, 0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x2a, 0xff, 0xdf, 0xf7, 0xff, 0xf7, 0xfd, 0x7f, 0x7d, 0x15,
+ 0xee, 0xae, 0xaa, 0xaa, 0xea, 0xaa, 0xaa, 0xaa, 0x2a, 0xff, 0xdf, 0xdd,
+ 0xdf, 0xff, 0xdd, 0x5d, 0xdd, 0x05, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaa, 0x2a, 0x7f, 0x07, 0x7d, 0x7f, 0x7d, 0xff, 0x7f, 0x5f, 0x35,
+ 0xae, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0x2a, 0xdf, 0xc5, 0xc7,
+ 0xfd, 0xfd, 0xfd, 0xdd, 0xdf, 0x1d, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xaf, 0x2a, 0x7f, 0xd5, 0xf7, 0xff, 0xff, 0xff, 0xff, 0x67, 0x37,
+ 0xaf, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0x2a, 0xff, 0xfd, 0xdf,
+ 0xff, 0xdd, 0xdd, 0xdf, 0xfd, 0x1d, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xaa, 0xba, 0x2a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x35,
+ 0xaa, 0xea, 0xaa, 0xae, 0xea, 0xea, 0xaa, 0xae, 0x2a, 0xff, 0xfd, 0xfd,
+ 0xdd, 0xff, 0xfd, 0xff, 0xfd, 0x1d, 0xaa, 0xea, 0xaa, 0xaa, 0xba, 0xba,
+ 0xab, 0xba, 0x2a, 0xff, 0xff, 0xf7, 0xf7, 0xff, 0xff, 0xff, 0x7f, 0x35,
+ 0xaa, 0xaa, 0xae, 0xaa, 0xee, 0xee, 0xea, 0xee, 0x2a, 0xff, 0x0f, 0xff,
+ 0xdd, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xaa, 0x0a, 0x3a, 0xaa, 0xaa, 0xbb,
+ 0xfb, 0xbf, 0x2a, 0xff, 0x07, 0x1c, 0xfc, 0xff, 0xff, 0xff, 0x7f, 0x3f,
+ 0xaa, 0x8a, 0x08, 0xa8, 0xee, 0xee, 0xfe, 0xee, 0x2a, 0xfd, 0x01, 0x04,
+ 0xe0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xaa, 0x02, 0x02, 0xa0, 0xba, 0xba,
+ 0xfe, 0xff, 0x2b, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x3f,
+ 0xaa, 0x82, 0x00, 0x00, 0xe8, 0xee, 0xee, 0xee, 0x2f, 0xdf, 0x01, 0x00,
+ 0x00, 0xf0, 0xff, 0xff, 0xff, 0x3f, };
diff --git a/PerlMagick/t/input.xpm b/PerlMagick/t/input.xpm
new file mode 100644
index 0000000..b196f51
--- /dev/null
+++ b/PerlMagick/t/input.xpm
@@ -0,0 +1,308 @@
+/* XPM */
+static char *magick[] = {
+/* columns rows colors chars-per-pixel */
+"70 46 256 2",
+" c #2b2f1e",
+". c #2d2b2b",
+"X c #2a2927",
+"o c #2d2e31",
+"O c #2d322c",
+"+ c #2d362a",
+"@ c #2e3430",
+"# c #332d2b",
+"$ c #372c2a",
+"% c #312a30",
+"& c #33332d",
+"* c #333c2c",
+"= c #3a332d",
+"- c #3a3929",
+"; c #363b33",
+": c #3b3532",
+"> c #3b3b33",
+", c #363733",
+"< c #38354c",
+"1 c #38422b",
+"2 c #394435",
+"3 c #3c464c",
+"4 c #592b1f",
+"5 c #44392d",
+"6 c #453b33",
+"7 c #553b2e",
+"8 c #583b36",
+"9 c #4c2c29",
+"0 c #69362c",
+"q c #6a3a33",
+"w c #7c3a2d",
+"e c #75372c",
+"r c #793b32",
+"t c #602e24",
+"y c #433f4e",
+"u c #493e75",
+"i c #45472c",
+"p c #484637",
+"a c #485738",
+"s c #53442e",
+"d c #5c4d3c",
+"f c #574a38",
+"g c #58543b",
+"h c #43572d",
+"j c #4a6539",
+"k c #556a3c",
+"l c #654638",
+"z c #63553b",
+"x c #764337",
+"c c #79412d",
+"v c #607c3c",
+"b c #4d4b48",
+"n c #4b5844",
+"m c #594d45",
+"M c #5a5746",
+"N c #555155",
+"B c #5c5869",
+"V c #4e4d69",
+"C c #596847",
+"Z c #5a6853",
+"A c #597845",
+"S c #597350",
+"D c #655b48",
+"F c #685e55",
+"G c #77584a",
+"H c #73544d",
+"J c #6b5a6b",
+"K c #68654b",
+"L c #6a6354",
+"P c #696657",
+"I c #647b47",
+"U c #677857",
+"Y c #716655",
+"T c #757456",
+"R c #76634c",
+"E c #6a6667",
+"W c #7b7969",
+"Q c #6d6f73",
+"! c #58588f",
+"~ c #5c5ea3",
+"^ c #5d66af",
+"/ c #665c9e",
+"( c #727196",
+") c #7977a6",
+"_ c #6e73b2",
+"` c #7478cd",
+"' c #5d843e",
+"] c #5e8447",
+"[ c #65884a",
+"{ c #6b944b",
+"} c #6d9554",
+"| c #719b4d",
+" . c #739957",
+".. c #6e8759",
+"X. c #748967",
+"o. c #778575",
+"O. c #7b9b68",
+"+. c #779877",
+"@. c #6b8e68",
+"#. c #78a658",
+"$. c #7ca567",
+"%. c #7ea675",
+"&. c #7eb065",
+"*. c #7c8d84",
+"=. c #7f83b0",
+"-. c #7baf88",
+";. c #7d87cb",
+":. c #91341d",
+">. c #873b2b",
+",. c #853b34",
+"<. c #953c2b",
+"1. c #983d34",
+"2. c #a83a29",
+"3. c #aa3c31",
+"4. c #b83a2a",
+"5. c #b73b33",
+"6. c #b63d45",
+"7. c #884336",
+"8. c #9b402b",
+"9. c #984537",
+"0. c #8c402e",
+"q. c #a7412b",
+"w. c #a74435",
+"e. c #b94437",
+"r. c #864a44",
+"t. c #87574a",
+"y. c #994447",
+"u. c #95544c",
+"i. c #975855",
+"p. c #8a5956",
+"a. c #936b5a",
+"s. c #876652",
+"d. c #946c67",
+"f. c #a94845",
+"g. c #b3524c",
+"h. c #ba5d7b",
+"j. c #b16d59",
+"k. c #b0746d",
+"l. c #c43a2b",
+"z. c #cb3a2b",
+"x. c #c93727",
+"c. c #c73c33",
+"v. c #d7372a",
+"b. c #d83a35",
+"n. c #da2e27",
+"m. c #ff1b38",
+"M. c #e72d29",
+"N. c #ec2c37",
+"B. c #e5342b",
+"V. c #ec363a",
+"C. c #e73936",
+"Z. c #f7292b",
+"A. c #f92a37",
+"S. c #f3312d",
+"D. c #f63439",
+"F. c #da3d43",
+"G. c #c03e40",
+"H. c #e93d45",
+"J. c #fc2b48",
+"K. c #f83b43",
+"L. c #fa3b58",
+"P. c #f03654",
+"I. c #ff3b66",
+"U. c #fb3e71",
+"Y. c #c84239",
+"T. c #d6443c",
+"R. c #e4423b",
+"E. c #c64b47",
+"W. c #c94a57",
+"Q. c #d84644",
+"!. c #d54954",
+"~. c #d75348",
+"^. c #cc5754",
+"/. c #cc5969",
+"(. c #d6655b",
+"). c #d56f71",
+"_. c #e74546",
+"`. c #e95657",
+"'. c #f6454a",
+"]. c #f94956",
+"[. c #ec5055",
+"{. c #fb4667",
+"}. c #fe4877",
+"|. c #fb5668",
+" X c #fd5776",
+".X c #e75a64",
+"XX c #e8645c",
+"oX c #f8686b",
+"OX c #fa6774",
+"+X c #f9737a",
+"@X c #e96f6f",
+"#X c #847597",
+"$X c #8c7dae",
+"%X c #b37498",
+"&X c #837ec8",
+"*X c #fd7985",
+"=X c #e97b84",
+"-X c #c56995",
+";X c #82865e",
+":X c #879172",
+">X c #8aa877",
+",X c #97a57c",
+"<X c #89b06e",
+"1X c #a2917c",
+"2X c #a5b979",
+"3X c #f9827c",
+"4X c #989c95",
+"5X c #869188",
+"6X c #8785bc",
+"7X c #8483a9",
+"8X c #89a889",
+"9X c #93af92",
+"0X c #8fa5a3",
+"qX c #af84aa",
+"wX c #acad91",
+"eX c #b0b1b0",
+"rX c #8988c8",
+"tX c #8886d8",
+"yX c #969bdb",
+"uX c #9691cc",
+"iX c #8d8feb",
+"pX c #9ca2ea",
+"aX c #a09bd6",
+"sX c #a9a7d9",
+"dX c #a6abfa",
+"fX c #b4b9ff",
+"gX c #a8aff3",
+"hX c #9dc393",
+"jX c #aace93",
+"kX c #a8c9af",
+"lX c #bbc5c9",
+"zX c #c2879b",
+"xX c #cfae96",
+"cX c #c4bcb8",
+"vX c #c9b9a7",
+"bX c #ff858c",
+"nX c #ff9193",
+"mX c #e1aaa4",
+"MX c #d1ceb3",
+"NX c #ede9ac",
+"BX c #e8d4bc",
+"VX c #d8cac4",
+"CX c #d1d1ce",
+"ZX c #c1c4e7",
+"AX c #d2e5c6",
+"SX c #d9e2e8",
+"DX c #ebd9d0",
+"FX c #e9ebd9",
+"GX c #f1ead5",
+"HX c #e7e4e6",
+"JX c #f4e7e8",
+"KX c #fafae9",
+"LX c #fefefd",
+"PX c #fcfaf5",
+"IX c #f1f2f2",
+"UX c #e6d6f0",
+/* pixels */
+"# & & = = = $ $ = $ $ # # # # # # & & = - 6 s 6 p s x 8.5.E.Q.'.K.V.T.4.4.q.q.8.0.<.<.<.0.1.e.e.9.7 , % $ = # . O # $ 8 H d.$X/ V V Q 4XW N ",
+". O # # $ # # = & : $ # # # # # # & & = - 6 6 5 7 p l >.2.e.Q.H.K.K.T.q.q.4.8.8.>.<.<.<.<.1.5.c.9.5 , : & & & . @ % % 5 r i.$X^ u V B *.U N ",
+". . # # # # . . # # # # # # # # # # # & = 5 5 5 5 p f 0 >.9.e.Q.D.V.e.q.q.q.<.<.<.>.>.>.7.9.c.g.p.> : = & & O O @ @ # # 9 H 6X` u < < 3 n M ",
+"o o . . . . X X . . . . . # . # # # # # = = : 5 6 6 8 7 e <.w.e.Q.Q.q.8.1.1.<.>.>.>.>.,.7.9.e.j.:XZ 6 & O O . . # @ @ % # E uX;.( B Q *.*.Z ",
+"o o o . . . X X X . X X X . . . # . . . = : : = 5 5 6 6 0 ,.1.9.w.e.8.<.<.<.<.>.>.>.w r r.9.g.1X8XQ n 2 O . # # . . . % X K 4X0XkXkX9XhX8XZ ",
+"O O . & & # # . . . . . X X . . . . $ # = : = = $ = , % 9 0 7.0.<.9.1.<.>.0.>.>.e e w 7.r.u.:X9X9X+.U n : # X . % % % % X g >X>XhXhX%.8XX.M ",
+"O & & : , : # # % o % % # # # . % # $ 5 5 5 = $ : 9 9 9 $ 9 0 ,.,.r 7.7.0.>.>.e e e r 7.r.p.o.8X8X+.@.@.Z * X X X X . X X M O.O.%.%.%.+.@.n ",
+", , , > > 6 6 : : : = $ # & & , : 5 6 6 6 6 5 = 5 : 6 5 = 9 0 ,.r.7.,.c w w e e g.j.x H R T j.k.4X>X:X%.@.Z - X X X $ $ f P ..} .@.+.+.@.n ",
+"> > 2 < 6 6 p p 6 6 6 6 6 : = & : 6 6 s 6 6 6 > : 6 r.y.7.f.9.3.3.9.3.6.w.x w 6._.^.D C s.`.J.J.L.{..X@X)././.g.y.9 $ i z ......X.+.4X*.U n ",
+", : > 6 b 6 b p 6 6 6 6 6 5 : = - 6 7 s 7 6 5 > : x ].x.<.Y.3.5.e.2.5.c.D.R.T.C.n.Y.s.s.XXK._.'.J.J.J.L.U.U.}.}. X/.8 2 W 4X4X4XeXVXCXeXU Z ",
+"@ , , > p b p p p b 6 6 5 - > : > 6 p p i 5 6 ; 6 f.2.2.q.2.2.3.3.3.e.z.M.Z.S.B.n.l.E.~.'.H.4.Y._.K.L.L.I.U.}.{. X X/.d.VXUXUXJXPXPXIXCX5Xo.",
+"& . @ , > 6 p p N 7X) B y : $ & - 5 6 8 5 = & 9 ,.2.2.<.4.l.5.2.4.c.x.v.v.S.M.x.n.v.T.R.T.l.2.2.Q.'.'.].I.}.}.}. X{.=Xs.DXLXLXLXLXLXLXJXeXeX",
+": & # & > p f f B pXfXpXuX( b < > i p > 3 V n d 9.2.3.2.4.v.b.z.b.b.R.M.Z.Z.M.v.x.v.T.~.Y.4.4.Y.Q.Q._.{.{.{.}. X X|.OX!.mXLXLXLXPXLXPXDXGXHX",
+"p > - $ : 6 f f B yXfXfXfXgX&X/ V > > b ) qXh.W.4.2.4.l.b.C.v.C.C.v.R.S.Z.Z.B.x.x.x.v.~.T.4.4.Y.~.e.~.`..X|.}. X|.|.|.W.d.JXLXLXPXPXJXVXJXPX",
+"p p p = = > p s N rXdXdXfXdXpXtX_ ! p.W.[.!.b.C.c.4.c.b.b.v.b.v.v.x.x.v.D.S.v.C.S.B.T.R.T.v.l.4.Y.4.Y.E..XOX|. X+X X=Xd.d VXLXLXLXLXPXGXKXKX",
+"m f f p 5 6 p s N 6XpXdXdXgXgXdXpX%XF.H.C.c.T.H.C.Y.Y.4.x.v.B.B.x.x.x.x.v.B.S.N.S.B.x.T.Q.~.l.l.4.4.5.e.XXoXoX@X@XOX*X:Xi VXLXLXLXKXPXKXKXKX",
+"m d m f f p f f N $XyXiXpXyXrX6X-XH.C.H.F.c.Q.H.T.Y.4.4.x.B.B.B.v.4.c.V.x.x.x.v.z.x.z.b.V.[.T.l.4.2.2.4.~.@X.XoXOXoX|.X.C GXLXLXFXAXAXKXFXFX",
+"d d d d f f f f b J ( $XtX_ ^ J F.K._.'.Q.5.Y.c.Y.e.4.x.v.B.S.Z.A.N.A.Z.x.x.B.C.Y.x.x.B.B.v.v.T.4.2.2.2.e.@X+X+X+X|.I.,XO.MXAXkX9XhXjXAXFXVX",
+"d d d f f d m d m m B / rXqX%X6.z.C.K._.c.2.c.b.Y.4.Y.x.v.S.B.M.Z.A.m.N.H.N.A.N.B._.b.b.v.l.l.~.c.c.z.4.4..XbX*X+X{.].;X[ ..I ..$.<X<X>XeXcX",
+"d f f f d d d d z z m B ( zXOXP.H.Q._.Q.3.2.c.H.R.T.x.v.B.B.S.S.N.J.J.|.|.P.n.4.Y.[.T.x.4.2.2.Q.C.S.Z.C.4.(.bX*XOX{.L.k I X.O.%.<X<X<X<XwXMX",
+"f f f f d d d d d z l J 6XqXoX].P.H.b.c.2.4.b.n.v.R.T.v.V.D.m.Z.Z.N.P. X].c.<.:.3.c.Q.l.l.4.5.T.B.Z.Z.S.x.E.nX*X XI.F.h .>X>X$.$.$.&.<X9X4X",
+"z l l d d l d d B J E _ iXuXk.XX].K.b.Y.2.g.c.x.v.B.R.v.S.'.'.M.n.n.H.F.b.l.Q.!.E.[.T.T.b.K.J.C.n.S.A.S.x.e.nX+X{.I.f.j .O.O. .O.$.#.<X<XU ",
+"l d d d d z f B $X$X_ rXuXeXxXj.Y.'.V.b.5.e.(.5.n.M.b.B.Z.S.[.[.[.`.F.V.N.].+XOX_.b.b.T.B.A.D.B.v.S.A.S.v.5.bX XI.{.7 j .O.} .#.#.| <X<XU ",
+"d d d D z m F ( _ _ ` sXNXNXNXwXd.).].V.b.4.g.~.x.R.R.M.M.n.z.[.|.OX|.N.A.'.|.|.B.C.b.b.C.C.V.v.B.S.D.S.v.5.*X XI.g.- 2 U .{ { #.| { [ j h ",
+"f d m D d F ) _ ^ ` yXZXDXVXcX5XW a.@XoXR.R.l.Y.x._._.v.B.x.4.Y.c.|.`.b.'.H.V.D.S.S.B.b.V.V.C.v.v.S.S.S.n.Q.OXI.I.r.f i a [ [ { } [ ] ] A A ",
+"p p d d F ( ) ~ _ tXyXyXaXuXrXQ M G j.@X3XXXx.x.x.v.z.v.v.Y.Y.l.5.~.T.x.S.A.A.m.A.N.b.C.C.N.B.v.v.B.B.B.v.`.{.I.W.$ i - a I ' ' { { ] ] I A ",
+"& > p d E ( ! ~ ` tXrXrXtXrX6Xp.M G ^.@X3X3Xl.4.x.v.z.x.v.x.l.z.c.c.z.n.A.A.J.A.A.D.b.b.C.D.B.v.v.n.v.v.b.|.I.I.q X + g 2XX.' { } { { ] [ [ ",
+"O . , p B ! ~ ` iX` rXtXtXrX( H K D g.`.oXT.x.x.v.n.Y.l.T.z.x.x.v.b.b.V.J.N.N.D.V.C.b.C.V.D.C.x.x.x.x.l.[.{.I.f., % i 2XjX .' | } [ ] ] [ { ",
+"+ X O > b B / iXiX&XrXrXrX#XF D D D t.`.C.n.v.v.v.x.q.x.T.x.l.x.x.v.C.D.N._.`.R.B.b.C.V.C.V.b.l.4.4.4.4.|.L.W.i 9 :XjX,Xj v { ] ] { { { } ",
+"> > : 1 p n E 6XtX$X) ) Q F D D K G w.v.B.B.v.x.v.4.4.v.R.4.4.l.b.C.C.C.'.`.Y.b.b.C.V.V.V.C.T.2.2.2.:.Y.|.!.t.- h #.<X:Xa 1 I { ] { { } { #.",
+"d g b g M D D E ( J N N D D G K t.f.4.x.b.v.v.v.v.4.2.l.T.T.T.b.C.V.C.c.4.4.b.V.V.C.C.C.C.C.Y.2.8.:.:.^.g.i.t.v 2X| a > # i [ { { } { | #.} ",
+"D D D D D D D D F D D d p d M Z a.!.v.4.z.v.v.v.v.e.:.2.x.x.B.C.V.V.v.2.2.4.T.V.V.C.C.C.b.Y.2.:.0.:.c u.u.u.a.>Xj , = : 1 [ | | | | #.#.] ",
+"F F F F F F K F D K K D p 2 2 p g g._.l.l.v.z.v.v.4.:.<.4.b._.b.5.5.2.<.8.2.4.b.C.C.R.Y.3.<.>.>.w e >.9.u.i.t.h + ; p - - 1 [ .| | #.&.] ] ",
+"F K G F F F F F L F F F M p 2 1 1 u.`.'.z.z.z.c.T.Y.3.e.Q._.Q.3.0.7.w >.>.<.<.<.4.5.4.2.<.>.>.w e e 9.7.u.i.a.I a Z a - - 1 [ | } | &.[ ] ] ",
+"D K F K L Y L K K Y L L L g i - 7.E.!.oX~.T.Q.Q.Q._._._.'.R.b.1.0.,.,.r w w e w >.>.<.>.>.w e e 0 r 7.t.u.p.M j A h 1 > = - I .} #.} ] { ] ",
+"F L Y L F F L F L F L L F K D i x y.f.E.E.T.Y.Y.Q._.Q._.C.T.c.1.>.r ,.>.>.w w w r w e r e e e 0 0 x t.u.u.R C C a 1 - > * - k .#.} ] ] { ] ",
+"K F L K L L L K Y K R F Q 4XeXW 1 1 1 > l f.F.T.T.Q.Q.Q.Q.T.T.3.>.w >.>.w w w w e e e e e e 0 0 t r u.i.R D a * 2 2 2 * , = a } #.] ] ] ] ] ",
+"F K L F K L F L L F F d.CXLXLXDX1X2 1 - . 8 ).^.b.H.Q.H.Q.Y.T.c.>.w w w w w w w r e e e 0 e 0 0 t 0 u.G p 2 + @ + 1 2 1 O & i .} A A ] ] A ",
+"L L L L P L L L L P E lXLXLXLXKXFX,Xi - b 4XJXGX).5.c.F.F.T.b.E.<.,.w >.r w r r q 0 0 0 0 0 0 t 4 0 H 6 + * , , * + 2 2 & X i O.] j A A ] C ",
+"L K L K K L L L L P B eXIXLXKXKXKXDXT p 4XJXLXLXPXmXf.5.Y.Y.Q.5.,.w w ,.r w r r 0 0 0 0 0 0 0 0 q H , & * & * + + + + 1 2 + p @.A j j A ] 3 ",
+"L L P P P L P P K E 0XHXLXLXKXIXKXMXT Q CXLXLXLXLXLXDXj.2.c.Y.w.,.,.,.r e e e 0 0 0 0 0 0 0 0 l s.P O @ + + O O + + O O 2 2 2 n 2 A j S S 2 ",
+"L L Z L P L P F Z *.SXLXLXLXFXFXGXMXwXVXIXLXLXLXLXLXLXLXxXw.4.5.1.,.H q x q q 0 e q 0 q q l l g o.n O + * + O O O O O O O + 1 + 2 j j S S + ",
+"P L L P P P E P P Q lXLXLXPXFXFXGXVXJXLXLXLXLXLXLXPXLXLXLXBXj.1.<.w q r r x l c e 0 8 8 s g g g U 1 ; * ; + @ o O O O . O O + 2 2 1 2 S n + ",
+"Z L P P P P F P S Q lXLXLXPXKXAXAXFXPXLXLXPXLXLXLXLXLXLXLXLXKXvXa.x t 0 0 l 0 l l l f D i 1 i T C * ; ; ; ; ; @ , , O O X X O O 2 2 1 2 3 @ ",
+"L L P P P P E P P Q lXLXLXPXKXMXcXJXLXLXPXLXLXLXLXLXLXPXLXLXLXLXLXKXDXvXz s s z f p p C i 1 i K D i ; > ; 2 ; 3 ; 2 2 @ @ O o o + 2 2 2 2 + ",
+"Z P P P P P P P P *.CXLXKXFXAXvXcXHXPXLXLXLXLXLXPXLXLXLXPXJXLXLXLXLXKXDXR s s g f a a i a k K g g f p p ; 2 2 2 2 2 2 3 2 2 @ 1 j j 2 2 n * "
+};
diff --git a/PerlMagick/t/input.xwd b/PerlMagick/t/input.xwd
new file mode 100644
index 0000000..13a67c2
--- /dev/null
+++ b/PerlMagick/t/input.xwd
Binary files differ
diff --git a/PerlMagick/t/input1_4.wpg b/PerlMagick/t/input1_4.wpg
new file mode 100644
index 0000000..0746172
--- /dev/null
+++ b/PerlMagick/t/input1_4.wpg
Binary files differ
diff --git a/PerlMagick/t/input1_8_1.wpg b/PerlMagick/t/input1_8_1.wpg
new file mode 100644
index 0000000..651d8dd
--- /dev/null
+++ b/PerlMagick/t/input1_8_1.wpg
Binary files differ
diff --git a/PerlMagick/t/input2_4.wpg b/PerlMagick/t/input2_4.wpg
new file mode 100644
index 0000000..aa1eb96
--- /dev/null
+++ b/PerlMagick/t/input2_4.wpg
Binary files differ
diff --git a/PerlMagick/t/input2_8.wpg b/PerlMagick/t/input2_8.wpg
new file mode 100644
index 0000000..e9b508d
--- /dev/null
+++ b/PerlMagick/t/input2_8.wpg
Binary files differ
diff --git a/PerlMagick/t/input2_TC1.wpg b/PerlMagick/t/input2_TC1.wpg
new file mode 100644
index 0000000..6c25ac9
--- /dev/null
+++ b/PerlMagick/t/input2_TC1.wpg
Binary files differ
diff --git a/PerlMagick/t/input_1555.bmp b/PerlMagick/t/input_1555.bmp
new file mode 100644
index 0000000..80a17f8
--- /dev/null
+++ b/PerlMagick/t/input_1555.bmp
Binary files differ
diff --git a/PerlMagick/t/input_16.miff b/PerlMagick/t/input_16.miff
new file mode 100644
index 0000000..f71545c
--- /dev/null
+++ b/PerlMagick/t/input_16.miff
@@ -0,0 +1,9 @@
+id=ImageMagick
+class=DirectClass matte=False
+columns=70 rows=46 depth=16
+background-color=gray74 border-color=gray74 matte-color=gray74
+Comment={
+This is a comment.}
+Signature=eb4d6e084afe2835a1ad28ad7fc12ced
+
+:00//--2200..6622//8833..::33--9922--8800--9911..8800--8800--77//,,55--**44,,))55--**55--**11--''11..''4411**7744--9966//??:://FF??33JJBB44LLAA22NNBB22UUAA22ttDD44CC33AA55EE==DDGGCCFF==BB<<@@@@;;??//??--@@--AA++@@++??..==,,==++==**??..??33BB33DD66FF99RR:://::55337722117722//6611..3300,,////--00//--33,,--66++--PP7788IIGGbbnn||llppPPHHnnRRLLaauuww||zz||llYYVVSS//..,,00//--5500--7711--8811,,8800,,66//,,8811--8811--8811..77..,,44--**44,,**66//++66..++33//**3300**4411++6633--775500>>88--EE==22HH??11II>>..KK@@//MMDD33iiEE44@@..<<--GG<<DDGGBBEE<<AA<<@@AA;;??--??++??,,@@++??++>>..==,,==**;;**>>-->>33@@44DD88HH;;DD77,,9955559933116622//6622..1111----11..0000..55//..22**,,EE2211xxAA55YY\\}}ccllJJ>>kkKK@@\\]]^^gg~~llpp__YYWWSS,,,,,,,,--++00//,,11..++22,,((22--**00,,++22,,++22++++22,,++22,,++11,,++11,,))33--,,33--,,33//,,3311,,4400,,5522--775500::33,,>>66--@@66--CC88--HH;;//EEEE55UUDD44mm==++99((EE44HH==EE@@<<>>>>==AA00@@**??-->>--??,,>>))>>,,==--<<--;;..??//BB11@@88GGDDWWNN<<??55;;44119933..5533..1144//--44..,,4400//33//1122000000..33--++II..!!llMMNNkkqqHH====11XX5544HH>>FFFFIISSIIYYZZOO,,--//++--//..----//--))//**''--++((,,****,,****..++++..++++..++++//++++//----00,,,,00--..//--**22..,,22..++22--,,3300..8822//<<44//>>44//AA55--FF9911HH>>77QQ<<55__7700yy77--;;//AA33EE99EE@@HHAABB//@@,,>>--==//==--==++<<++<<,,<<..<<22CC77GG::EE@@gg__yyWWeeWWCCBB887755++//11**..11++--00,,--00////00..0022..//22..//--2244**,,ggccbb~~iippYY\\oo``pprr||__eeQQ,,//22++//22....00--..----++)),,**++++))++((''((****++,,**++,,**++**))))**(())--++,,..--..//,,++00,,++..**))//++++00----881111<<3322;;2211>>00..AA22//AA7733BB::66KK6622hh77//==00>>55AA33DD77GG<<??33??,,==++;;--<<--;;,,99))99**::..??77GG@@EE>>UURR{{rrppSSZZGG<<@@330011((--))''22,,++22,,++00,,**00--++00//++22**1100))((eeqqRRʳǰYYddJJ..00..////--//11..2211..3300--33//,,22--**--**++,,++,,**))--++((,,--'',,++(()),,**))----++//--,,..++**//++))44,,))66//**;;33..==4400;;11--;;//..>>//..>>33,,5599//9933,,OO,,''ii::--AA11@@11;;--BB22>>22<<//==..??//<<//99,,{{;;,,vv::**}};;00GG;;KKDDQQOOppwwyy\\{{ZZNN^^GG==::3322''((//''))--((++00((,,22((//11++0000**00++''[[ff@@vvvvɌÓ~~vvppOO[[DD2233--3344--5533..996611996611::22..8800--33..,,330000--..00//((//11))..//**,,11..**1100**0011..//000044//++;;11++AA55,,CC88//AA9900==55--;;00//<<11//EE11--RR))..FF**..7700))RR//((jj99..::779944??55BB66AA11>>--::++;;**vv>>))vv88,,ss99--{{@@44GG>>NNEEddVVzzqq{{vv||eeggddeePPffPP44==00**&&##..$$&&++****))++,,''++//''''--))$$""WW\\HH~~jj{{jj~~oooo}}tt~~{{oollLLVVDD778822778822999944<<::55@@==88BB::88AA9955==7733<<7755::554499000099////6611..6622..6633..664411997733??7722BB9900HH==11JJ>>44HH==44BB8800@@6611??6622<<9944CC5544AA5500<<66**EE55''cc66--==;;BBAACC;;>>66AA55~~:://yy;;//uu>>..zz44))PPLL[[VVppJJ99kkSS@@ss``IIzzXXff``zzrr~~vvxxooooXXiiMM??;;))33))""%%++!!++//&&::&&**CC))))TTNN::hhqqRRhhWWkk\\nncckkhhsstttttthhddNNXXCC88993399::44>>>>88AA??::DD??::FFAA<<EEAA::EE@@::GG??88EE==44DD;;11CC::33CC::33<<88009955//9944//<<7700BB<<00II==00OOAA22PP@@55KK<<44EE::11AA::11==<<33GG7700EEJJGGIICC::KKHHFF99??33CC55EE11@@22>>BBCCEEvvCC99yy::44<<HHEEGGUUPPppYYCC``jjHHllSSSSZZ((HH))KK@@VVMM__YYhhffnnjjrr__mmWWkkPPbbFFOORR..((>>33((GG@@--ee^^::ww\\nn\\mmYYssdd~~{{dd}}__SS__GG667711668811====88BB@@;;FFAA??HHCC>>HHCC>>JJDD<<MMBB77JJ==00HH<<--FF==//EE;;00AA9911<<7711::77..>>99,,EE<<//MM??//OOAA00OO>>11KK;;11DD:://>>==1177==00BB@@KK]]3355;;##??55;;00>>33DD77::((>>22>>8888??<<<<DD??77;;..''BB::ddOOccJJcc^^;;EEBBCCFFOO..EE,,HH00TT44\\::hh::ooAArrGGooZZxx[[ffaa==33HHCC//vvddӰgg{{eeWWggLL333300555511888833==<<66DDCC99GGGG>>JJII;;MMII66IIEE77MMHHJJHH@@99EE;;++CC99--??8800>>8833==7711>>9944@@==99IIAA66PP@@--HH??--KK8811CC774455==00@@??//II@@44++44!!AA&&::$$66''==22AA11@@22@@4488))11++++++00))66%%55!!99,,UUIIUUQQAAKK??AA;;..EE;;AADD>>HHAAQQ==VV>>hh>>qqEEwwJJnnWWxxYY]]nnnndd҅uunn1100--//..,,4433//889922>>??55GGDD;;OOKK88MMKK44XXWWWW||xx[[TTooFF??OO9944446622&&5522))::99..BB==--KK@@//PP@@//CC;;**::44))004400BB11--66<<;;//<<'';;%%>>,,==11;;1199**::++??2233**44,,88..11++//((55 44!!99,,??66CCAAAA>>>>3399((==--EE@@FFKKDDKKDDXXBBbbJJttKK}}MMzzTTttCCcc{{__TT::88116633--3300++7744,,<<;;22IIAA66VVJJ99TTHH::ddaarr䬬쏏nnmmLLIIXX@@??MM<<9999AA==((BBCC..88AA99::EEQQEEUUaaFFSSRRaaGG<<FF77==++AA--;;((66**8800::448822::33;;22??7711''--((--((22((77!!77""55((CC<<VVMM>>22::##::))@@77HHFFGGHHFFJJOO\\FF``JJnnRRzzXXzzUUqqSSgg``ppKKUU᪪DD@@55AA==33;;66--5522((::55//FF==77TTGG66WWFF77]]UUjjޫ||ff\\RRLLss77::CC::9977RRJJNNss]]{{KKPP<<''99##::**;;--<<33;;336611>>99<<7788//DD99??44))))++++22,,22%%<<((::**77--LLHHCC@@99$$99((>>22QQIIEE>>NNIIQQSSTTaaVVnnNNooUUxxWWooZZiiWWeeOOTTttnnOOII;;MMGG::FF@@55??9900==6600AA==88MMEE55SSDD..WWLLSS틋oozzaaeeNN__OOWWLL]]HHRR;;>>>>>>>>55>>//??22>>4499//33++77//88//33))33$$99"">>0088;;005522005544553377++>>//PPJJEEII==3388++<<--CC22==--HH==NNJJ\\aaffvvPPmmZZuurrxxbbpp{{uueeVVPPAAWWNN??VVMM??PPII::KKBB44FF<<11EE@@77LLGG55SSGG..VVNNQQ𮮭຺vvAANN<<??;;77@@11FF;;==AA99<<@@::EE9966((22++4411;;//77))44!!66!!77&&55))55++88..4422--55**0011))55$$LLAAHHIIMMKK88..::((;;'';;**<<//@@33^^VVnnmmggppggqqttrroouuzz||AAQQ33[[PPAA[[OOAAYYMM??TTJJ::TTGG99NNGG<<RRJJ99WWKK44XXQQTTԕ䙙씔؈Їii==PP@@::>>CC??FF>>;;GGFF>>AA??;;==11??00;;++::..993333//44..88**;;++;;66<<9999%%99!!33&&55//77++88&&==))>>55@@BBUUSSGG==99))::**<<--<<..::**VVGGmmjjaaggbbmmnnqqddllWWppuuiiXXnnEE[[NN>>ZZNN>>[[NN==XXMM<<ZZLL<<WWKK??XXLL<<ZZLL88UULLGGdd__uuwwxx{{{{ffmm||RRbb;;FF33??EE>>CCNNBBGG@@55CC;;4411BB55;;))99%%::%%88((44++1133,,33--11..88((>>((0000''88((;;22==44DD6666&&55))7755..//44**55**JJ>>>>1166**::++77&&HH>>qqrrss~~rr{{ss{{VVeeDDaa}}}}gg̮Ưʪǚպ[[LL<<[[LL<<\\LL<<YYII;;ZZKK;;[[LL>>^^MM<<^^PP<<[[NNAAYYLLII^^SSddmmeeě~~qq@@GG>>++@@99<<@@BBJJ<<7799((BB88;;88DD::77$$;;((88''44''99..44'',,$$))''%%2266''66<<DD11::00::++..8855GGGG6644;;6655**88&&88++QQGG<<339911::3388++88--kkkkzzrrMMdd??\\^^ggQQ||\\aa~~QQeeYYyyhhttyyŵ[[KK::[[KK::YYKK::YYII99[[KK::]]JJ<<^^KK<<^^OO;;^^OO;;__NN::__KKHHaaWWww||ww‡eeww44KK@@FFCC@@BBGGCC@@;;..88&&@@6688;;MMEEPPAA66((44**660011//1199--<<**<<--HH..WWQQcc\\mm88OO005577&&CC66SSNNCC@@99..77$$;;%%88))FFBB883333110000991144''\\WW||kk||HHaa>>UUYYaa77eeNNdd~~mmppooppooqqÿ\\KK77\\KK66\\KK66]]LL77]]LL99]]LL;;^^MM==]]PP==]]PP==aaMM::ccGG>>gg]]qquuqqKKUU??QQ==GG<<==>>44;;**>>//883333++99''MMAAAA33::..779922>>""// --!!++%%77;;VVccppNNSS::5566$$--::008866IIEE;;0088++88++88//JJ@@33....11--0022,,44%%MMEE{{YYtt??aa@@SSIIYY11pp[[ooqq||ff~~ffkk~~eenn^^MM::^^MM::^^MM::^^MM::^^MM::__LL77^^NN99VVNNAAaaXXYYoo``mmmmddppppxxꙙ͹vv||dd\\MMUU99AA7777BB22::++GG>>BB9966++66''44..DD77<<..0033DDNNCCGG//--,,((2233>>CC??CC778833..OOJJOOQQIIGGUUUUEEAABB::<<7722==77??>>::11**2200..2200..44%%HH<<qqFFhh<<ddAAGGNNbb<<rrZZyyccuu``vv__zzdd{{dd{{ZZhhvvllgg__OO==__OO??__OO>>__OO==__OO==``PP77\\LL99__[[aa}}||}}qqvv||ƚǺȶppRRLLAAHHJJ7799::2277..II??ffXX@@3322++11,,==1177))--))5555RRXXJJQQQQVVVV[[@@BB99??--77JJVVoozzffvvRRNN5533AA<<EE<<4400,,::55??663344**22//..22//--55))<<33bbww>>ccAAdd\\;;//LL__>>uu^^{{ccooWWrrXXxx^^yy[[wwVVaahhee||VV[[MM==__PP@@__RRBB``RRCC``RR@@\\OOBBccYYaawwwwww||ccjjzzzz֯ᶶ諫yyddllggWWZZ66::6633::11OOAAXXII11''>><<@@7700%%--''33**9955SSWWVVbbddooaagg//77((66FFSS^^ffTT[[7733664488228800::55;;;;665555++66**00--//4400//99..8822wwRRpp<<ddJJ[[==<<&&AAJJ00hh~~SSttXXhhLLmmQQssZZssTTllMMbbEENNjj44IIaa44TTHH88YYLL<<__RRBBbbVVDD``SS??ff]]bb{{yyttzz]]ffllvv·oojjeejjddyyuuggeeDDAA==55<<11BB22<<--GGFFIIFF7700660099++::&&==66::AA[[ggWW^^7733BBII??FF7799556655113300:://;;3366557788664466--77((11++335500//44**DDBBhhuu;;dd@@hhMMGGRRPP<<EEBB--OO__99iiLLeeDDggKKnnUUhhLL^^EEYY}}CCWWooBB[[ssDDDDBB66JJEE<<\\MM>>``SS>>ee__XXzzttsspp]]__iiiiߝޢ֠֞Εppgg}}^^VVRR||SSHHYYQQyyss||^^ZZ66--55##;;**::0077,,99//88//<<**@@11==447733PPLLKKBB66$$//00((::''??::##88..66::55<<5577553355440077))99&&66&&55--55))44''VV\\PPkk88ee@@XX9955##AABB337788!!QQZZ44ddyyNN__AAccDDllNNhhGGccIIccJJffIIbbDD4477--::::44OODD;;VVLL==ggeelllljjQQQQ[[]]yy{{Ή݌ш͈ҍȇ~~ZZjj\\[[LLppWWDDSSVVffkkzz;;--;;##;;))66++;;++66((::--88((::--:://::00??55::..11''//77++==**>>$$::&&9955==::66;;445544448866//77))88&&66$$99&&;;%%==44WWll77ccCCjjkk33==##//%%//44^^YY22ss``]]>>mmKKppQQkkHHiiMMeeJJffHHggGG**00&&++00++997755EECC==ZZ\\ii\\]][[ZZyy||օ낂ځʃҋۍ~~xxssWWRR``__HHdd__CCWWPPZZccnnjjKK@@77&&<<''88++11((>>++::((GG;;99++::))77((77((<<//;;0066;;11??--;;3366558877;;66558855::88778866;;884488**::))::''==!!<<&&KKMMBBgg66ggCCOO33664488++//DDNN))yy՚qq\\]]==rrNNooRRffEEggMMeeKKffGGkkJJ..22&&++..((0011++::==00LLOONNXXVVmmnnllꓓфǍΎwwllaa]]^^]]GGff]]IIjj\\EEYYCCRRQQ====00++77&&77&&55++55))==++<<++DD9988))::((99((44((22));;4488<<//::EEJJVVQQAA==88228844888888<<77<<5599;;6688))==**==**99##55))PP``==__II]]KK@@11--33%%JJ33''eeԌ||KKcc99``==llIIddGGeeCCkkOOiiOOffEEppPP@@>>00>>==44<<==22AAEE**LLMM::UUTTAAeeccggzzwwsszzyyoonn__WWllYYGGhh\\KKjj^^NN__OOKK<<55..00++44**88$$==$$99,,;;))77&&==55IIBB99''::))99--<<44;;77::888866HHIIZZXXCC==::7799228844668888>>66==77;;??77;;++;;'';;((66##IIDDUUhhMMXX]]OO3399""FFOO))uu__iijjIITT<<<<HH,,gg~~CCjjFFaaEEkkKKllPPooQQmmMMvvVVUUMM>>VVMM??VVNN??VVPP==\\RRCC``WWBBbbYYKKmmcckkwwjj||ppddmm]]WW[[WWUURR]]VVGGffZZFFnn__HHjjddOOZZOORRGG::,,44++77//77..66**99))::,,<<++55""99--<<44HH::BB99>>99<<<<6688;;88==2299**;;--<<5566::66::8866992299668888;;==@@88;;,,;;((88$$66''YYZZTTVVYYRRccKK``xx;;qqvvYYOO]];;;;==..2233++;;CC11ffGGooJJjjMMmmRRjjGGqqKKxxUUqqWWccZZKKee[[KKee[[KKdd[[LLee[[MMgg__JJhh__HHgg^^MMgg]]LLff\\II``ZZGGQQNN==LLHH77SSPP>>[[ZZFF____OOaaYYJJLL4400==))::**99++88**77**::++==//55??))77**99//449966<<66;;55<<664488&&99&&::))>>44998866778855<<33>>99>>>>@@;;88++::((::((77""~~::**RRJJTTII\\SSnn]]ssSSccBB''225588117766//99990099CC00ggKKwwQQppSSppOOooIIxxUUwwYY``JJhh__PPii``QQii``QQii``QQhh__PPkkbbTTjjbbSSii``PPiibbLLiibbHHhhbbKK``ZZFFLLJJ66@@EE44@@HH88CCJJ>>UUMM;;XXOODDFF::,,77%%88))::))::((99));;//669988**;;55@@EE>>;;6611::5599-->>**AA++<<''66))<<55==77??66DD99AA99883388**88''<<))}};;((ww33""AA33SSGGZZNNYYSSYYMMAAMM++''22%%77>><<KKMM@@==;;((77:://88@@--hhKKvvPPqqPPppJJyyVV}}bbbbII``LLii``QQii``QQii``QQjjaaRRjjaaQQkk__ZZkk____kkaaVVkkaaTTkkaaXXllaaRRkkbbNNZZVVDDDDFF88<<CC5555CC11??CC))ZZFF]]YYJJMM;;0099++<<00==11>>22@@::>>33CC33HHAAIIEEEEAA==//FF22CC11yyAA--::++<<,,==,,88**::..;;00??11<<..66**77,,<<,,;;**{{;;,,ss99**vv55((HH;;OOBBSSNNVVWWoo__ffvvIIGGVV44^^kkQQKKQQ55::;;##8888//88BB//iiLLwwPPppNNrrPP}}``ffNNbbJJbbMMii``QQii``QQhh__PPllccTTkkbbSSmmbbWWllbbUUllddOOllddPPllbbVVmmbbUUmmccTThhaaQQVVPP@@EEAA1188AA''KK@@>>@@NNOOiimmNNJJCC<<EE??HHCCIIFFGGKKLLKKIIHHAACCBBAA@@====00AA22<<11::33;;22~~;;11zz;;//zz;;++{{::++88,,88,,88((::**<<,,88++{{33((yy66,,pp44))vv==11QQ@@TTGGQQMM[[SSWWXX@@OOee==``vvFFCCWW--66@@**::<<227799//88@@--__yyAAxxQQppQQwwYYjjSS\\GGggJJaaIIii``QQjjaaRRllbbTTjjaaRRjjaaRRkkbbSSkkbbSSkkbbRRllccSSllccTTppbbRRppaaUUff__RRffaaPP__YYCCAA@@%%rrMM<<EECCBBCCOONNLLLLCCBB@@99EE;;DDEE@@EECCEEDDCCAA>>BB>>AA<<99//==//<<338822;;//;;..::--||::..||:://{{9911{{88//||99..zz::..xx99//uu88..rr66++oo44**ll22''vv@@66TTLLQQMMUUMMyyeeOOZZnnJJUUmmDDMM__::99CC((8899,,;;==3344;;008899))VVdd>>ttTTxx\\rr\\ZZCC__IIeeLL\\GGhhaaQQiibbRRjjddSSiibbRRiibbRRjjbbSSkkbbSSkkbbSSllccTTllccTTmmaaTTffZZPPssppii}}{{jj77>>++33<<((<<==//??;;..^^BB55HHEEAAEE>><<DDAADDDDDDDDFFDDFF??FF==DD>>==44==,,~~>>//99..::++::++::,,~~:://~~::00{{9900yy88//ww99//vv9900tt::..qq66--nn33++kk44))ee11%%ss==22RRNNYYRR__RR__\\HHEESS;;22??));;EE00BBJJ6699AA0044;;..4499557788,,LLWW33rrSS{{^^``IIZZ~~CCaaIIaaKKXX||GGhhbbRRiibbRRkkccSSiibbRRiibbRRjjbbSSkkbbSSllccTTllccTTkkbbRRee]]SS||ՠ||CCJJ2255??++::7722**00++ZZ??>>XXUU99::@@DDBBDDAABBCC??EE;;BB::BB88;;,,==,,<<++::++}}99--}}99//}}::00||::11ww::33ss88//pp66,,oo88--nn77++nn66//kk44,,gg33**``..$$pp88//UUQQzz\\OONNOO>>55@@11//55,,333300..33++44>>11;;KK8800>>..--22//5544++AAMM//ssYYnnTTTTuu??ZZ||EE__LL__IIWWwwHHhhccSShhccSShhccSShhccSShhccSSjjccSSllccTTmmddUUmmddUUllbbQQlljjee̝KKOO11==66))OOHHFFqqqq==::@@<<@@@@>>??BB==@@<<CC<<;;11==//~~<<,,::..{{99//||9900{{<<33zz<<44pp;;11kk88--ii77--hh88--hh88..kk7700ii66--aa00''YY++mm==44vvTTNNGG@@33..99))11<<..77::22668866228800--99**66DD2299HH661166,,,,--""@@JJ11zzmm^^MMQQoo<<VVssBB\\yyGGbbLLQQjjEEggddSSggddRRggddRRggddRRffddRRiiccRRllccUUmmddUUmmddSSjjaaQQddddddrrnnWWAAJJ<<޲OOAA8800AA<<BB==EE@@??;;<<33==33~~<<11~~::..||99//||9900zz9922vv8800jj88//hh88//ff77,,ee77--ee77,,ii6600ii7700ff66..hh;;22nnLLBB8888331144,,3377--5566++3377))//99++0099**..88**//88,,88AA22;;CC220011$$DDMM::oojjGGjj==LLkk<<LLii;;WWuuFFbbNNCCVV;;hheeVVhheeWWhheeWWhheeWWhheeWWiieeVVkkddZZnneeWWhhffQQnnllhhٸppssWWoo{{jjػjj^^88++@@66HH99EE66BB77??66;;22}}9922xx88//uu77..ss77..oo55++jj7700hh7700ff55//gg66//ii7700ll7711ll<<//ggFF44qq__nnkk[[))22((1177..0077--1166**0055,,//33--//33--//44....11,,..55..22??4433@@33@@MM::IIXX@@BBUU88MMgg@@GGbb99XXrrJJ]]xxTT44DD55hheeVVhheeVVhheeVVhheeVVhheeVVggeeUUkkdd[[nnddXXgghhPP}}~~ҷǣEE4499..<<99::;;@@==ppBB<<qq@@66qq??55oo??44jj<<22hh::11qq6622mm5511jj77//gg9911gg>>44ffFF99ccJJ55__MM55iiQQYYFF**11((0077,,1177--0066,,//33,,--22--..33----22,,,,00++,,33,,))44----88--22>>--22>>**66CC..DDVV;;HH]]==^^qqRRZZllSS,,88..hheeVVhheeVVhheeVViiffWWiiffWWjjeeVVllcc\\nnggZZhhiiQQlluuppԼkkSS??..66**88,,ooAA33rr==77ss??99ssAA;;oo??88nn==66qq9944ll::33dd==22^^>>22PP;;++UUPP99]]XX==]]]]??nnvv\\22@@++2277//2288..3399//2288--//55,,..33--..33--,,11++**//))++00++++33++**44,,--55,,77@@5599CC4433>>,,>>JJ44\\hhTTQQ]]OO++44--ggddUUhheeVViiffWWiiffWWiiffWWjjeeVVnncc\\llhhZZffllSShhwwooìuu]]yyHH11ee66""ee33))jj9900ll??44ii>>44hh>>22ccAA77__DD55YYGG55ee]]GGEEFF//99CC''EEII++ppppRR\\``GG2299''77==5577==3377>>4488>>3388<<5577;;6666;;55227711..33--,,11++((..((**..**,,11,,//22//==DD====JJ8811??((BBPP<<EEPPDD//9900ddddSSggddUUhhggWWiieeWWhhffWWkkeeVVnndd\\llhhZZddkkRRddwwooҶƿѽhhSS;;XXDD,,]]KK22\\LL44VVOO::QQNN77MMOO88^^ggKK@@LL00==EE**GGJJ++iiggJJ``YYDDFFFF55::??55::>>5588>>4499??5599@@88;;AA;;::>>99::@@::99==8877;;66006622,,11,,++//..))--..))33))66JJ2299LL3388II11;;KK88//;;..\\ggOO__iiRRggkkWWiihhXXllffXXllggYYkkff[[hhggYYeellYY||ɾmmggKKRRKK--UUOO22SSOO33PPNN44LLOO66HHOO55EENN..LLSS00]]ee@@aaeeFFVVVV==WWTT<<UURR99MMII66CCBB55<<??5588AA5588CC5599AA7799AA66::BB77;;CC88<<EE<<;;EE::99@@5555==6666DD//GG``55GGbb<<::MM88@@RR::HH\\AA44BB11 \ No newline at end of file
diff --git a/PerlMagick/t/input_16.pct b/PerlMagick/t/input_16.pct
new file mode 100644
index 0000000..03288dd
--- /dev/null
+++ b/PerlMagick/t/input_16.pct
Binary files differ
diff --git a/PerlMagick/t/input_16.tga b/PerlMagick/t/input_16.tga
new file mode 100644
index 0000000..ba4117f
--- /dev/null
+++ b/PerlMagick/t/input_16.tga
Binary files differ
diff --git a/PerlMagick/t/input_16rle.tga b/PerlMagick/t/input_16rle.tga
new file mode 100644
index 0000000..5479681
--- /dev/null
+++ b/PerlMagick/t/input_16rle.tga
Binary files differ
diff --git a/PerlMagick/t/input_24.tga b/PerlMagick/t/input_24.tga
new file mode 100644
index 0000000..c5b2094
--- /dev/null
+++ b/PerlMagick/t/input_24.tga
Binary files differ
diff --git a/PerlMagick/t/input_24rle.tga b/PerlMagick/t/input_24rle.tga
new file mode 100644
index 0000000..04e4b91
--- /dev/null
+++ b/PerlMagick/t/input_24rle.tga
Binary files differ
diff --git a/PerlMagick/t/input_32.pct b/PerlMagick/t/input_32.pct
new file mode 100644
index 0000000..087e4b9
--- /dev/null
+++ b/PerlMagick/t/input_32.pct
Binary files differ
diff --git a/PerlMagick/t/input_32.tga b/PerlMagick/t/input_32.tga
new file mode 100644
index 0000000..5672454
--- /dev/null
+++ b/PerlMagick/t/input_32.tga
Binary files differ
diff --git a/PerlMagick/t/input_32rle.tga b/PerlMagick/t/input_32rle.tga
new file mode 100644
index 0000000..38bdd9a
--- /dev/null
+++ b/PerlMagick/t/input_32rle.tga
Binary files differ
diff --git a/PerlMagick/t/input_4444.bmp b/PerlMagick/t/input_4444.bmp
new file mode 100644
index 0000000..bfdb746
--- /dev/null
+++ b/PerlMagick/t/input_4444.bmp
Binary files differ
diff --git a/PerlMagick/t/input_565.bmp b/PerlMagick/t/input_565.bmp
new file mode 100644
index 0000000..f22dbe5
--- /dev/null
+++ b/PerlMagick/t/input_565.bmp
Binary files differ
diff --git a/PerlMagick/t/input_64.pam b/PerlMagick/t/input_64.pam
new file mode 100644
index 0000000..993ff25
--- /dev/null
+++ b/PerlMagick/t/input_64.pam
@@ -0,0 +1,248 @@
+P7
+WIDTH 70
+HEIGHT 46
+DEPTH 3
+MAXVAL 64
+TUPLTYPE RGB
+ENDHDR
+         
+
+
+          ' - 18;><6. - + ) & % $ % % % & , /%      !'#*)%'$                    # * /7;?>4, , + ) & $ $ $ $ $ & / 2%       %"++ " 
+
+          !
+( 07>;. ) * ) ' $
+$ # # " " ' 11"    #"/2   
+
+
+         % ) /87* ' ( ' % # " " ! ! "'/-$# ''4 "4(!&#$ 
+
+
+
+
+
+
+
+
+
+         " % & ,/( % % % $ " "
+!  "&,)$#+# 
+
+
+
+
+%('$))*3-)2,$.&&/&!(!
+
+
+
+
+
+
+
+         
+ ! $ % & % % " " # !    ""%% $*#"+$&
+
+
+
+
+
+
+
+$)#+(2#'1%!, "+!$    
+
+         
+  
+
+ !"  !" ! " ! 
+   """%,"!,#(%" 
+
+
+
+
+
+
+  $' ) )) ("                           
+ "$!!     
+.+ .0)(!$( #& (%
+
+ 
+
+ 
+
+!$'&'%"                   #'"+)* * ) + +( 081$:@
+@
+><975551&
+
+ !""$ &#)$ &                   ;3 ' 0 + - .)
+. 4<85;7
+1%"8>8=@ @ @ @ @@@@@2  '(%$(&&('.-+432535,,,              *, ) *
+* (
+* + , 0 3
+: > =
+8 6 2 18@8, 1;??@@??>?@ 3"52088;:6<=8>?=>?===:<545!#!      !)( 
+
+     
+  #, )
+( - 2 . + - 1 1 6 7 < <
+5 7 5 4782 ,
+, 5=>@@@@@@=9""<52@@@@=@@>@@@@@@?@>?=:;00.-/,    ()9+-@'(;$$1$
+ %* , ,
+0 5 5 4 5 6 8;
+=
+>
+;
+54 4
+67/ - .
+256;?>??>?>@58+)@@@?@@??@@?=@?>@<=;77<:7;;9  
+ $&8+.@-0@.0@**< 1("'+ ,/2-
+* - 0 5 8 7 9:7 9= ?
+
+? 9 4 2
+4 5 94/ 0
+2 518:<???@@?3(?88?@@?@@@>>@?=?<<742>=8>?<     !$0*,?,-@--@*+>'(;##6."!3<75:4 / 2 5 6 7 7 8 6
+4 3 7 @> 7 8 < 9 6 974 1 / 0 / 24:@??<=< %811@?@?@@@?@?@>@@?;:7?>8??:    !#/))>))@)+@)+<,+>(,@(+8/#8<93 4;832/
+2 7 8 8
+5 12
+4
+6 9 : ; > 9
+3 6782 0
+/
+. - / 9>><;?@#"& 710@@@@@@?@@<@<@@>@@<@>9??;  +%&5%&9&);%(6"$4"!01%:9:816:61 0 . 3 9 8 9 4 / 2:2 14
+5 4 2
+2
+7 :;72
+. , + , 4<:<?@>"<95@@@@@@9>:1;29<5?>:=:6=:7'! /""3.*7@ :<7. 24 2 /
+0 0 5
+9 > @ ? = ?
+>
+ 5
+3
+9 : 40
+3
+9 9 6 4 5. * * *
+/<> ??@>&('33,592,3+%.$$/"*2'45/<85731'" 1' -+)-2 :?:0*
+274/ 1
+2
+7
+< 9
+< =
+
+> @=
+;; @ = 8 :6 75 1
+1 72 3 4 0 - :@ "?!@ @>!""! #(".#.%+ 0-*1--'1"'=@ 94<7- )
+4;:61
+4 9 < = ? = < > >@<5 .
+3963 1 * +
+58 = ? 9 0
+6@"#?!??=  # ' +"+",!.!+-.&100 "--"*>@=:72 * - 4 8 7
+:5 5 ;> ? @ > < >@<3 ( " + 162 2 - 0 89 ? ? < 2 1@$$@"@@5 %!*!+) ) * ,"-'."&)&*!#;&!3.:?=81 * /13 8
+9 87 < @=: 8
+8 8673 553:758= =:7 = > = 3 /@%%? @@'&(('(**"-"+!( -."2''2/,.2.&-2<:5 / /30 7 9 8 9
+<
+< <;;;5;; =@@:6 778 ? @ : 7 < ? = 5
+- @"$>@= $(&'()* + ('.-6,+798.>=);:+.-$(6>;7 / /54
+:98 :
+7 4 <=@?> >
+>?>8 : 7 6 9 :: 6 9 = ? > 7 . ?!@@0
+  %%&''&#  (-,0&'801:6666521./!""&9@=7 1 2 4 998 9 3 /
+24=;8 >;:> < < 8 8 : ;: 7 8
+< = = 7 4?@@  "$$%$"$*(/#"8''8)(6('6(&4%"0.;@ <2 0 3 5 4 7 7 1 1 1 0 653 ; >
+?
+@@ = 8 8 ; < 9 7
+7
+9
+< ;
+6
+;@@3   !#$#"!     $#)4""7##4"!3" 5#!2"!+ 4:<! @ 1 / 2
+6 3 3
+6 2
+1 2 3 4 2 6
+> @ ? @ @
+< 78 ; < 9 5
+6
+7 6
+5 6 @@?   (-!#!%%$#!!"
+  "'6!";!!7 !3!!5#!7#"1 ",;=62
+2
+6 5
+1 0
+74 2
+2
+4
+6 7 <> < : = <8 7 9<>9 4 3
+3
+10
+:@@*   
+)..5'$!&%#"""$
+
+  (%$;%$> 4!!2##4$!0 %":;7 7
+5
+8 2
+/ 1 71
+1
+3
+4
+6
+: <; ;<;8 8 9:;< 70
+/ / , .
+@?3 
+"&*5#$+ %#"$$$'    ! .$#5 ,) )  )6 9 9 6 3 6 .
+-
+6 :-
+/
+2 6 9;:=:378 9 ;;;;6. *
+)
+& 0?5!  
+'%)"'  %##$&&)"+, 3 8 8 6 5
+5 . * 1 6 556:<91 . / 6 ;::9 :::3* &
+# !
+3/( '.&   &%%%(+(&45 .
+3 7 5 5 5 / & +
+0 4 : :;< 6 +
+*
+-
+6 <=; 9 872* %
+#
+   *%$&$(
+      !'&&&**# .<2 1 5
+4
+4
+5
+/ $%/ 7 <5/ . ) ' ( )
+.
+5 ;;83- & #
+!
+
+ " %$&"
+ 
+  !''')*#"  
+&:<4 2 4 5 5 4- . 7;4( $ !  ! " # & ) . 0 . ( $ !    
+%#&'$     !'')*$#" 
+!06>8456898:;93( # !       " $ %
+"   
+ 
+ !"'#     '(*%!$! ',035436889993'   " !             
+"%%
+   
+&)&!"# )(&-,) 
+   )567887556, !  ! !            
+  %$  
+      %)! !!! 444???@@@=75($   3 488776470#                  &      %& !/11@@@@@@@@@@@<;=3'*  
+(&&=<:?8660356571%               
+   
+          '"!*-.<???@???<>?;@@;970&&$=:9@??@@@@@>8-(+- 334-$                    
+       # (*,9:;@@@@@?>?<>?=@@<76.232@@?@@??@@@@@@@@<86/, 12*" !              !
+
+         69:@@@@@@??>9:89;6<<655.-,(332==<@@@@@?@@?@@?@?@@@@?@>2)$) / .&            
+   
+       135@@@@@@??=:;7:<5;:4752<88@?@@@@@@?@@?@@?@@?@??>@@?@@@@@:5/-' $             
+      /23?@@@@?@@=<>8791760:88@=?@?@@@?@@?@@?@@?@@??@?@?@@>@@@@@@@@@;71+(  
+       
+  
+      
+
+  
+  146@@@@@?@@==>845.20-<:<@@@@@?@@?@@?@@?@@?@@?@?@?@?>@=?@?@@@@@@@@@@@@>=99624/*            
+
+
+     #"256=??>?<<<777220,20.:8:@?@?@@?@@@@@@@?@??@?>@??@??@@??>=>;:@??@@??@@@@?@@<::3                \ No newline at end of file
diff --git a/PerlMagick/t/input_70x46.cmyk b/PerlMagick/t/input_70x46.cmyk
new file mode 100644
index 0000000..544445b
--- /dev/null
+++ b/PerlMagick/t/input_70x46.cmyk
Binary files differ
diff --git a/PerlMagick/t/input_70x46.gray b/PerlMagick/t/input_70x46.gray
new file mode 100644
index 0000000..2ba6d24
--- /dev/null
+++ b/PerlMagick/t/input_70x46.gray
@@ -0,0 +1 @@
+/0234323221/.//-.146:?BBCEP[bjrvtrla_^[WUTTTVXae\?63320./..>YutNPvyV./122102220..00/01358>@?ADMTYhqtutk_^]ZWTSSRTWcj\964220//0,7PjpFF^lW,,..-.-------../1025477:=CGIM]jqsqb[\ZXTSRQPSZfkd<54321111/.4VxG96CNX,,--++**+++,--.-...03567;@ABIS\grr^XXWURPPPOU_g}_A4//../00.-ds]k`...-+*)'***)(+-,-+,-354369;;DRVYbhZUTTRPNMMQY\ozU=/)--,-.-*i]/.000/.++))))*,-++.0463235635FRUSYVTRSRMLJMX\emV:*))*+-,'^T2236632/0-*++./0/037::63465218FOOPTTQOOLIHPY^lx\8&'***'%X}P778:=<:88621223478:>@?:8899868BRYURRMLLGnrSXcw}`:+(,,0MjuyR89=??AA@@><;;8547<?CC?<;;:Z`Vg`\_^^_^QLdsu]cskly~t^85?[zz{rX66<@BCCDD?=><:769=ACA>;;9T}`Td[_dWaiomnm`goktq{nnquzz|FBvϰr_247;BEGHDIA<:9989=BB?<:9=cWS\XS\__dbghigcau~zo[itw{y||tω{/.27=CJHW}YB5118<AB;425O\XV_d_Y\d]cgigbceipoeZ]ozz}}{j쾷7303:BKIcqK@9;@=CQNM[Z_[]efdfhmggihbbbo}a[^gqrx~u?=615?HIYïfR:9L}|p]W\ahkfonhrsghf_cedxm]_evjy~tIG@97=EEP}g`t~uhphaeigdfhc`aksldglhj{rg_`fals{PNNIC=@FGPqqmgnrkij\^ejga^_acjifge_tsxa`^^^cHQPNKIGJKSqoqpeqqkcc^dkfgd_coa_`ccadkrra]\[[y~bPOONNMMMNc{q`lquwpbibg_^_dglkkjif_blol]`jdcaq`WYVi}ھNNNLMNPQPOXmcequtbWhkl\aadmfeee_eqjngiwfjc_`yedf^[yw}p{MMMKMNNQQPP]|sqmvo]Vinzv^aiiklhjoqa[j}nc^XXoiklk[vYrMMMNNOPQQPNbvpkeY_eegzjfmnddacvdSE[asda[_ufkjj^o|mOOOOOOOPNZeh{qhfYih`fgqji}xeaenmh_uvoqlklppckjj`hz]WxQQQQQQN\|ozlg]ieceliflzlnf}~enqfkrjejkib^{zCUpORTTTQ\zp᱂lf`m{_pocddekg|hjhflnkdhilkg]zo9Dr}v[TINTWT`}~k{Ӻjwxkbgfuvhic]fgixrkoljjkklkfgiljdmz}[N@Uwy|{skbfAEOT_ywerlW^t`[cgchhbed_xr`ghiegijllkhfghkjcxl4?5Rmqw}ytrqo49FMfoWdfY\xb^bdd`gabcchcalljgimikklhdfdffjw~D*/Vo|ytsw--7B\aa{^\]pt`cead_qcb`bhimnhinnihlnojcccaaz~wb4/Fŀpwwvw}/,0:MYr}cZ]]d~qbfcg_aco_ab`bmohwsiijmmmj^``ZZzrA/8Wnxu||z=<;@JRdysb\]_fdddfedf^Zjw[^bilnl{kiijlnlmk]YXPlvf4GMAp~wz~MNNOSWZfohYUV[`cfk[`hgdef_T`iolkommd\`imkkkllnhYTOK{slhiT:1>q~~Z\\[\^_^^\YLGNX]orc_dgedfaO\^ejkmmeXW\jonmmmlhXSPJLjfjxZ,657=sv_```_cb`aaaYHACFMswb^deed_NQ]itj]^WXZY[hpqqi[SOOLETeijeE-;J97;swu```aabbbbbbbUC?<>i{ebfhii_dsxnYYTONQRRX_c^TPOMLHF\`gkwlMdL76<tzvu``_cbdccdccdaO@;ZewxlnruvxxtriXUPNNMLLKMPQONKGHDL^bfhTYiL::7;jqzs`acaabbbccdd_`X=V^bpqmikpprsqqjUOOOONMLLKKKKJIFDBObdfhcaU<7;76[nsynabcbbbbbccc\py97;:Hcmlqrrrooo^PONNMMMMKJJJIFCC?KehgZL8?E<776Oqlsskabcbbbbccb^E97-FzjpponmofQNNMKLLLKHFGFECA;GgcL;2209D703EdkpqhbbbbbccddcjJ6IdhlkmmhSOMMKLMMIEDEEED=7J]@378753=A3+Ds`djr^bbbbbbdddadlEi\jjnaSPNLKLKIEECCCDECGU724444433<>/H~Z\[fqMdddddddfdlnuZfl`UQOLJHGEEDBCEFHMtj.4332111/29:FPLZUek=dddddceed~ϯ__`VROMLLHFGEEEINOO|T-3431/0/.0/388<MSgc3dddeeddgeq~YOKMLMOLJIHGF?NVYp94564200.,-/01<>8CbW0cdeeedeggqTA@FKIIJJJ\C<Dl[4:::::9840.+,.0AD8IK4bceddefgfpοVGMNNLKaE?EdXD<;;<<><=;93.-+.ACAD5`cgffffegeIMMKKIGL^`SRPH@<<>==>?A@<9=SUDIR; \ No newline at end of file
diff --git a/PerlMagick/t/input_70x46.rgb b/PerlMagick/t/input_70x46.rgb
new file mode 100644
index 0000000..b778d9f
--- /dev/null
+++ b/PerlMagick/t/input_70x46.rgb
@@ -0,0 +1 @@
+0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/input_70x46.rgba b/PerlMagick/t/input_70x46.rgba
new file mode 100644
index 0000000..00f5443
--- /dev/null
+++ b/PerlMagick/t/input_70x46.rgba
@@ -0,0 +1 @@
+0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nndun10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:darnmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Uj|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLSozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮ʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdme~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxv|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzzydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iipg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S||CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQljeKO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/input_70x46.uyvy b/PerlMagick/t/input_70x46.uyvy
new file mode 100644
index 0000000..96e7387
--- /dev/null
+++ b/PerlMagick/t/input_70x46.uyvy
@@ -0,0 +1 @@
+~/0|23{43}23}22}1/}./|/-{.1{46x:?vBBuCElP[fbjervctrclac_^e[WiUTgTTiVXdaeq\?~63}32~0.~/.}.>xYu~tNP~v~zyV~./|12|21|02|22}0.|.0|0/|01|35y8>v@?uADmMTfYheqtbutck_b^]eZWiTShSRjTWdcjr\9~64}22~0/~/0},7sPj{pFF^}zlW,,}..|-.~--~--~--}-.}./}10|25z47x7:w=CqGIiM]ejqasqcb[e\ZfXTiSRkQPiSZgfkwd<|54}32~1|1~1~1~/.w4VyxG96|C{N}X,~,~--}++**+++,--~.-}..~.0|35z67y;@vABmISf\gcrre^XgXWiURjPPmPOlU_lg}x~_zA4|/~/.~.~/00.~-dwsz]kvyz`.}..-+*)'***)(+-,~-+,-}35|43{69{;;oDRkVYgbhhZUhTTjRPkNMoMQoY\powvzxU~=|/)~--~,-.-x*iwzoupux]/.~00}0/~.++))))*,-~++|.0|46|32{35{63t5FkRUiSYjVTkRSlRMmLJoMXr\etvqumvV|:*))*+-,t'^kxkpoouxT|22|36|63}2/0-*+~+.}/0~/0z37y::{63{46|52x18rFOpOPlTTkQOkOLoIHpPYr^ltoumsnxy\y8~&'***~'z%Xmvkqppv}xP}77}8:|=<|:8~86~21}22}34|78x:>x@?z:8|89|98w68rBRqYUoRRoMLnLGmnrqSXocwo}q~qxtt`x:+|(},|,0sMjlusmmspuywR}89}=?|?A{A@z@>y<;z;8|54y7<v?CxC?y<;z;:tZ`oVgh`\f_^k^_q^QpLdhsup]ckskkllyprt~tv^8v5?m[zmzu{ruyvurxX|66}<@}BC{CDwD?v=>y<:{76w9=uACwA>x;;w9Tj}`dTdf[_edWdaidomdnmb`gmokfteq{innpquwzzvقs|tFBxv~z{́ρvrx_~24|7;zBEvGH|DIxA<y:9{98|9=vBBw?<{:9q=cdWSa\XgS\e__adb]ghZig]cafu~ezoe[idtwi{yv||wՂuώutʂ݆z{{~/.|27z=CtJHW}}YB5y11x8<tABw;4|25mO\cXVb_dd_Yc\da]c]giZgb\cedipcoecZ]eozgz}s}لyԇr{sjzڇ~{|73{03z:BuKIc{v|qK@y9;y@~=CxQ{NMg[Zb_[a]ecfdafh^mg[giZhb]bbco}ba[c^ggqrgxӃp~փv΋oцmuy~}~yy?=z61{5?uHIY{t¢y}fR~:9L}v|pa]Wb\a`hkafo_nh]rs\gh_f_^cebdxbm]a_efvjey~mΊtҋmэltx}}|wwIGy@9{7=tEEP}vxw}xgw`tl~uehpchaaei_gd_fh]c`]ak`slbdg^lhaj{ergb_`bfaflslǕqЌmÎq{yPˀ~{tvNNwICy=@sFGP}xuvgqqamgcnrekicj\b^e]jg\a^__a^cjaif^ge`_tfsxaa`a^^d^cfÖlőjsvHˀ}{{uvQPvNKwIGtJKSxuyyqcoqhpeeqqckcbc^`dk_fg`d_cco\a_``c_ca_dkdrς`rac]\e[[eylĎiȓr~rbwruvuPOuONvNMtMMNc{|{q`flqduwgpbdibbg_^^_]dg_lkakjdif^_b^lo`l]``j`dcaaqe`WdYViin›kˉo}n{txnopyxuNNuNLuMNsPQyPOXmc_eqdutfbWchkal\_aa\dm[fe_eef_eeqj`ngciwbfj_c_b`ycedbf^h[nm΄mykwy}mpr{hnjsytMMuMKtMNtNQsQPP]|lsfqmevod]Vcinazv`^a_iicklihjooڄlqca[cj}cnc`^XeXo_ik]lke[€moπlvYlrzkqfqfnwrMMrMNsNOtPQsQPNbǵivpdkedY_aee]gz`jfcmn`dddaclvӓedeSEg[acsdba[c_u^fk]jjc^onp|omOirhpgqcntxsOOsOOrOOuPNZeh}{{neqbhffYich`]fg^qjci}axeaaegnmdh_huvhoŁcqlcklbpp^ck^jjb`horzq]Wgqgpgp`opuxtQQtQQrQQzN\}|vhdozblgf]iee_ce\li^flhzh˃flnff}mɕc~ebnqafkarj^ej^kicb^pr{zsCUiteqdq`olupuORuTTuTQ\zwpz`܆fᅱldlcf`dm{a_p^oc^ddeék͓ekfg|h΅ahjahfaln`kd\hi_lkcg]pʉszot9Djrvd}pdpcpvk[vTuINtTWyT`}z~kt{y|ׁӀxjwh`xkbbgbfuavh_icb]fkgʉeiexrako^lj_jkakl_kf[gi_ljbdmpzs}[tN@kUxwbyp|eq{gsqklbwfyAEtOT_yw{ery{~lwW^jtfÈ``[_cg_ch_hbcedf_x`r`bghgiecgi`jl`lk^hfZgh[kjcc΃qxul4v?5nR{mcqqwd}syhttrhqvo|49wFMf~oWzdxz}fuY\lxi_b^_bd_d`_gabbcbch`cacllfjgdimaikakl^hd[fd[ffgjϋtw~|D*p/Vkxborcs|gyttesuw}-}-}7B\|aaywx}{^r\]lpdt]`c^ea_d_`qc_b`_bhaimenhainbnibhlano`jc]cc\aalz~uwb4/iF|itbprdrwgwsvcwr}{/~,{0:M~Yr{yz}xcZs]]id~aqb\fc_g_`acao__ab_`b`moehwbs`iicjmbmmaj^a``bZZmzurAx/8funvWbnscxruf|r|azpy=<v;@vJRd~}y~sbt\]s_fddd^df[ed_f^bZjaw[a^bailanld{΄dki`ijclnclmbk]cYXgPlnvsf4kGwgztM|Acpu~dwrzd~r`owMNvNOtSW|ZfohYUuV[r`cnfkc[`_hg^de`f_bT`aioblkbombmdc\`bimbkk`klblnehYfTOlK{osljhicvtT}:z1~>dqud~q_~p`mvZ\v\[u\^s_^t^\uYLvGNvX]norbc_^dg^ed`fabO\a^ecjkcmmceXbW\`jo`nm`mmelhfXShPJlLjpfjnxtZ{,|65y7~=dstbq_pcnvv_`v``v_cvb`raasaYvHAzC}FpMsbwb^^d]eead_cNQb]ietjg]^fWXdZYc[h^pqbqih[SiOOkLEmTeqijqeE}-{;wJ9y7~;dst_pbpfwpuv``v`axabzbbxbbubbwUCy?{<o>ie{`eb`fhbiie_dbsxgnYjYTkONjQRhRXd_ce^TkPOlMLnHFn\`rgkowlsM{dsL7y6~<ctu_odpzgvquv``v_cwbduccvdcvcdvaOu@;mZeiwœdxlenrfuvexxctrgiXmUPpNNoMLmLKkMPiQOlNKnGHpDLo^brfhqT|YlixLx:}:y7~;dju`ngoqfzrsv`avcavabvbbvccvddw_`rX=pV^mbphqmdikgpperscqqgjUnOOnOOmNMnLLpKKoKKpJIpFDpBOrbdqfhpcwarU{<z7;y7~6i[xepgnqsgyqnvabvcbvbbvbbvccwc\{pxyw9}7x;:qHcfmleqrfrrcoofo^lPOlNNlMMoMMpKJpJJpIFqCCq?KrehtgZvLz8w?|Ey<}7|7~6iOxeqqhlrsjsrkvabvcbvbbvbcvcbz^|sEy9~7|-FnzejpfpodnmcofkQNkNMnKLoLLqKHqFGqFErCAr;GsgcxL};}2~2{0}9yDy7}03mEwgqdjkspkqshwbbwbbvbcvcdudcj~{m~tJ6}IxkdfhlekmemhlSOmMMoKLpMMqIErDErEErD=r7Jw]@y3{7}87{5|3y=yAz3+qDxjsr`kdujmru^vbbvbbvbbvddudad|{ysvlE|ugi\ejjgnanSPnNLoKLqKIsEErCCsCDsECtGU|72z44y4}4z4|3z3|<x>~/vHx~nZs\m[tfpqvMwddxddwddxdfydl|{sun}u~~r㙀dZfel`oUQpOLpJHqGEsEDtBCtEFqHMutj|.|4{3}3|2~1}1}1}/}2{9z:wFzPrLwZpUuevkw=wddwddwdcyeeyd~}~y~sy~k_f_`qVRsOMrLLsHFtGEsEEtINpOOv|T{-}3|4}3}1}/}0}/}.}0}/{3x8{8v<zMsSxgycy3wddwdewedydgye~q|}u~t~}xg~YlOKrMLtMOtLJtIHsGFs?NqVYup|9|4}5{6}4|2}0}0}.},}-}/{0|1|<y>{8wC{b|W{0wcdweewedyegyg|q{|s~yՄ~~slTpA@rFKrIItJJsJ\sC<qDlv[~4|:}:{:}:}:~9}8}4}0}.~+},~.}0{A{Dw8zI|K{4wbcwedwdeyfgyfzp{{s}~}}~{sډpVGpMNsNLsK~asE}?qEduXD{<~;|;}<}<}>~<}=~;~9~3}.-}+y.yAvCxAzDz5u`|cvgfwffxfe{g{{yu؄}~~|toeIpMMsKKrI~GnL^r`SrRPwH@{<}<{>{={=|>|?|A{@|<z9{=oSuUwDxIwRy; \ No newline at end of file
diff --git a/PerlMagick/t/input_70x46.yuv b/PerlMagick/t/input_70x46.yuv
new file mode 100644
index 0000000..d9f16e0
--- /dev/null
+++ b/PerlMagick/t/input_70x46.yuv
@@ -0,0 +1 @@
+/0234323221/.//-.146:?BBCEP[bjrvtrla_^[WUTTTVXae\?63320./..>YutNPvyV./122102220..00/01358>@?ADMTYhqtutk_^]ZWTSSRTWcj\964220//0,7PjpFF^lW,,..-.-------../1025477:=CGIM]jqsqb[\ZXTSRQPSZfkd<54321111/.4VxG96CNX,,--++**+++,--.-...03567;@ABIS\grr^XXWURPPPOU_g}_A4//../00.-ds]k`...-+*)'***)(+-,-+,-354369;;DRVYbhZUTTRPNMMQY\ozU=/)--,-.-*i]/.000/.++))))*,-++.0463235635FRUSYVTRSRMLJMX\emV:*))*+-,'^T2236632/0-*++./0/037::63465218FOOPTTQOOLIHPY^lx\8&'***'%X}P778:=<:88621223478:>@?:8899868BRYURRMLLGnrSXcw}`:+(,,0MjuyR89=??AA@@><;;8547<?CC?<;;:Z`Vg`\_^^_^QLdsu]cskly~t^85?[zz{rX66<@BCCDD?=><:769=ACA>;;9T}`Td[_dWaiomnm`goktq{nnquzz|FBvϰr_247;BEGHDIA<:9989=BB?<:9=cWS\XS\__dbghigcau~zo[itw{y||tω{/.27=CJHW}YB5118<AB;425O\XV_d_Y\d]cgigbceipoeZ]ozz}}{j쾷7303:BKIcqK@9;@=CQNM[Z_[]efdfhmggihbbbo}a[^gqrx~u?=615?HIYïfR:9L}|p]W\ahkfonhrsghf_cedxm]_evjy~tIG@97=EEP}g`t~uhphaeigdfhc`aksldglhj{rg_`fals{PNNIC=@FGPqqmgnrkij\^ejga^_acjifge_tsxa`^^^cHQPNKIGJKSqoqpeqqkcc^dkfgd_coa_`ccadkrra]\[[y~bPOONNMMMNc{q`lquwpbibg_^_dglkkjif_blol]`jdcaq`WYVi}ھNNNLMNPQPOXmcequtbWhkl\aadmfeee_eqjngiwfjc_`yedf^[yw}p{MMMKMNNQQPP]|sqmvo]Vinzv^aiiklhjoqa[j}nc^XXoiklk[vYrMMMNNOPQQPNbvpkeY_eegzjfmnddacvdSE[asda[_ufkjj^o|mOOOOOOOPNZeh{qhfYih`fgqji}xeaenmh_uvoqlklppckjj`hz]WxQQQQQQN\|ozlg]ieceliflzlnf}~enqfkrjejkib^{zCUpORTTTQ\zp᱂lf`m{_pocddekg|hjhflnkdhilkg]zo9Dr}v[TINTWT`}~k{Ӻjwxkbgfuvhic]fgixrkoljjkklkfgiljdmz}[N@Uwy|{skbfAEOT_ywerlW^t`[cgchhbed_xr`ghiegijllkhfghkjcxl4?5Rmqw}ytrqo49FMfoWdfY\xb^bdd`gabcchcalljgimikklhdfdffjw~D*/Vo|ytsw--7B\aa{^\]pt`cead_qcb`bhimnhinnihlnojcccaaz~wb4/Fŀpwwvw}/,0:MYr}cZ]]d~qbfcg_aco_ab`bmohwsiijmmmj^``ZZzrA/8Wnxu||z=<;@JRdysb\]_fdddfedf^Zjw[^bilnl{kiijlnlmk]YXPlvf4GMAp~wz~MNNOSWZfohYUV[`cfk[`hgdef_T`iolkommd\`imkkkllnhYTOK{slhiT:1>q~~Z\\[\^_^^\YLGNX]orc_dgedfaO\^ejkmmeXW\jonmmmlhXSPJLjfjxZ,657=sv_```_cb`aaaYHACFMswb^deed_NQ]itj]^WXZY[hpqqi[SOOLETeijeE-;J97;swu```aabbbbbbbUC?<>i{ebfhii_dsxnYYTONQRRX_c^TPOMLHF\`gkwlMdL76<tzvu``_cbdccdccdaO@;ZewxlnruvxxtriXUPNNMLLKMPQONKGHDL^bfhTYiL::7;jqzs`acaabbbccdd_`X=V^bpqmikpprsqqjUOOOONMLLKKKKJIFDBObdfhcaU<7;76[nsynabcbbbbbccc\py97;:Hcmlqrrrooo^PONNMMMMKJJJIFCC?KehgZL8?E<776Oqlsskabcbbbbccb^E97-FzjpponmofQNNMKLLLKHFGFECA;GgcL;2209D703EdkpqhbbbbbccddcjJ6IdhlkmmhSOMMKLMMIEDEEED=7J]@378753=A3+Ds`djr^bbbbbbdddadlEi\jjnaSPNLKLKIEECCCDECGU724444433<>/H~Z\[fqMdddddddfdlnuZfl`UQOLJHGEEDBCEFHMtj.4332111/29:FPLZUek=dddddceed~ϯ__`VROMLLHFGEEEINOO|T-3431/0/.0/388<MSgc3dddeeddgeq~YOKMLMOLJIHGF?NVYp94564200.,-/01<>8CbW0cdeeedeggqTA@FKIIJJJ\C<Dl[4:::::9840.+,.0AD8IK4bceddefgfpοVGMNNLKaE?EdXD<;;<<><=;93.-+.ACAD5`cgffffegeIMMKKIGL^`SRPH@<<>==>?A@<9=SUDIR;~}{}}}}}{{ywuofgcdcdihhel~}}~ux~|~~~}~}|{ywujfacefikkes}}~~t|~~~}{|slgihjjnqouw{~~}~zwv}}|}|{yz}{{rpnkkopqsurx}~olnu}}|{{yz|{wwy{vpiggqrfqmkkprtwxlnoyu~}zxx{x||yu|wfafed^[Zgefdhtztuz|||{uukcbcba[[[cebgenwqms|xwy{vlhcb``^\`b_^hbbekqmow}rvvvvahgdba`_f]_`^dabfcliqozuuuuutw_agdc_][\hfbbc_bccennojnjgvsrsutvhjedc[`baamfdgead_^_mqpijgbmtttsleceg`^]hhgdmdc`b^__oqtkff_iuus|l`c_d_`jjec^^a`[`^msuoafem{yxlka___bbbafdc`_[[at{ujcdfgz}|tmb[]aa___ec`ccba`jtzimddfawwvwwqre_^^cabcacbc_bdfkooaq|hd`]vvvwssuyud_^^dbeghec_`hiklpq{y{ha`evvvwtwvwpieeefcflpomlhlnpnqtkv{hafdvvvvvw{zwytidfddkmloppprqrtvwx~ochiwwwvv}nq}{nffdlloprrrrrwy|}y{ujljwxxyu{xr~yecnopqsttqt|||}~|xtprwwwztxr}gjqtttstqt|||}}}|zw{wwxzt~ux}}upptttqt{|}~~|vy˺~ܽ™|~}~{~s~zootvllv}yqou͍ĴvuvuӸݺж|v{yy˾Λ~uxwuƿԿyuv˿xv{~˾tupoxϸѶ˷rqrmv}x{´Ϻݑvqrot}uxۂ{qqpw{xz|zrstv~~|yzֿ~{vuqsqκưy{xqqm}ͯµν{wqppƥx|woor~ʤz|}}}prr~ͬ{}z~}put{}|}~~~z{xuuz}~~}}}}|||{{~x~|~}}~~}~{xy \ No newline at end of file
diff --git a/PerlMagick/t/input_888.bmp b/PerlMagick/t/input_888.bmp
new file mode 100644
index 0000000..a729cdd
--- /dev/null
+++ b/PerlMagick/t/input_888.bmp
Binary files differ
diff --git a/PerlMagick/t/input_8888.bmp b/PerlMagick/t/input_8888.bmp
new file mode 100644
index 0000000..4921324
--- /dev/null
+++ b/PerlMagick/t/input_8888.bmp
Binary files differ
diff --git a/PerlMagick/t/input_888flip.bmp b/PerlMagick/t/input_888flip.bmp
new file mode 100644
index 0000000..a729cdd
--- /dev/null
+++ b/PerlMagick/t/input_888flip.bmp
Binary files differ
diff --git a/PerlMagick/t/input_complex_lsb_double_V4.mat b/PerlMagick/t/input_complex_lsb_double_V4.mat
new file mode 100644
index 0000000..421c7f3
--- /dev/null
+++ b/PerlMagick/t/input_complex_lsb_double_V4.mat
Binary files differ
diff --git a/PerlMagick/t/input_gray.cin b/PerlMagick/t/input_gray.cin
new file mode 100644
index 0000000..782863e
--- /dev/null
+++ b/PerlMagick/t/input_gray.cin
Binary files differ
diff --git a/PerlMagick/t/input_gray.rla b/PerlMagick/t/input_gray.rla
new file mode 100644
index 0000000..20e3325
--- /dev/null
+++ b/PerlMagick/t/input_gray.rla
Binary files differ
diff --git a/PerlMagick/t/input_gray.rle b/PerlMagick/t/input_gray.rle
new file mode 100644
index 0000000..56a9068
--- /dev/null
+++ b/PerlMagick/t/input_gray.rle
Binary files differ
diff --git a/PerlMagick/t/input_gray_01bit.palm b/PerlMagick/t/input_gray_01bit.palm
new file mode 100644
index 0000000..5f8e529
--- /dev/null
+++ b/PerlMagick/t/input_gray_01bit.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_01bit_rle.palm b/PerlMagick/t/input_gray_01bit_rle.palm
new file mode 100644
index 0000000..fcde24e
--- /dev/null
+++ b/PerlMagick/t/input_gray_01bit_rle.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_01bit_scan.palm b/PerlMagick/t/input_gray_01bit_scan.palm
new file mode 100644
index 0000000..9bb5ab9
--- /dev/null
+++ b/PerlMagick/t/input_gray_01bit_scan.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_02bit.palm b/PerlMagick/t/input_gray_02bit.palm
new file mode 100644
index 0000000..424e43b
--- /dev/null
+++ b/PerlMagick/t/input_gray_02bit.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_02bit_rle.palm b/PerlMagick/t/input_gray_02bit_rle.palm
new file mode 100644
index 0000000..acb02a2
--- /dev/null
+++ b/PerlMagick/t/input_gray_02bit_rle.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_02bit_scan.palm b/PerlMagick/t/input_gray_02bit_scan.palm
new file mode 100644
index 0000000..7a35949
--- /dev/null
+++ b/PerlMagick/t/input_gray_02bit_scan.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_04bit.palm b/PerlMagick/t/input_gray_04bit.palm
new file mode 100644
index 0000000..c235582
--- /dev/null
+++ b/PerlMagick/t/input_gray_04bit.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_04bit_rle.palm b/PerlMagick/t/input_gray_04bit_rle.palm
new file mode 100644
index 0000000..c42efc5
--- /dev/null
+++ b/PerlMagick/t/input_gray_04bit_rle.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_04bit_scan.palm b/PerlMagick/t/input_gray_04bit_scan.palm
new file mode 100644
index 0000000..13418d5
--- /dev/null
+++ b/PerlMagick/t/input_gray_04bit_scan.palm
Binary files differ
diff --git a/PerlMagick/t/input_gray_08bit.fits b/PerlMagick/t/input_gray_08bit.fits
new file mode 100644
index 0000000..8a78f21
--- /dev/null
+++ b/PerlMagick/t/input_gray_08bit.fits
Binary files differ
diff --git a/PerlMagick/t/input_gray_16bit.fits b/PerlMagick/t/input_gray_16bit.fits
new file mode 100644
index 0000000..56f9f7f
--- /dev/null
+++ b/PerlMagick/t/input_gray_16bit.fits
Binary files differ
diff --git a/PerlMagick/t/input_gray_32bit.fits b/PerlMagick/t/input_gray_32bit.fits
new file mode 100644
index 0000000..29d58ba
--- /dev/null
+++ b/PerlMagick/t/input_gray_32bit.fits
Binary files differ
diff --git a/PerlMagick/t/input_gray_lsb_08bit.mat b/PerlMagick/t/input_gray_lsb_08bit.mat
new file mode 100644
index 0000000..78ea147
--- /dev/null
+++ b/PerlMagick/t/input_gray_lsb_08bit.mat
Binary files differ
diff --git a/PerlMagick/t/input_gray_lsb_16bit.mat b/PerlMagick/t/input_gray_lsb_16bit.mat
new file mode 100644
index 0000000..1376af6
--- /dev/null
+++ b/PerlMagick/t/input_gray_lsb_16bit.mat
Binary files differ
diff --git a/PerlMagick/t/input_gray_lsb_32bit.mat b/PerlMagick/t/input_gray_lsb_32bit.mat
new file mode 100644
index 0000000..849c74a
--- /dev/null
+++ b/PerlMagick/t/input_gray_lsb_32bit.mat
Binary files differ
diff --git a/PerlMagick/t/input_gray_lsb_double.fits b/PerlMagick/t/input_gray_lsb_double.fits
new file mode 100644
index 0000000..f444392
--- /dev/null
+++ b/PerlMagick/t/input_gray_lsb_double.fits
Binary files differ
diff --git a/PerlMagick/t/input_gray_lsb_double.mat b/PerlMagick/t/input_gray_lsb_double.mat
new file mode 100644
index 0000000..7686dc2
--- /dev/null
+++ b/PerlMagick/t/input_gray_lsb_double.mat
Binary files differ
diff --git a/PerlMagick/t/input_gray_lsb_double_V4.mat b/PerlMagick/t/input_gray_lsb_double_V4.mat
new file mode 100644
index 0000000..c95ac08
--- /dev/null
+++ b/PerlMagick/t/input_gray_lsb_double_V4.mat
Binary files differ
diff --git a/PerlMagick/t/input_gray_lsb_float.mat b/PerlMagick/t/input_gray_lsb_float.mat
new file mode 100644
index 0000000..7b5375d
--- /dev/null
+++ b/PerlMagick/t/input_gray_lsb_float.mat
Binary files differ
diff --git a/PerlMagick/t/input_gray_msb_08bit.mat b/PerlMagick/t/input_gray_msb_08bit.mat
new file mode 100644
index 0000000..1517e38
--- /dev/null
+++ b/PerlMagick/t/input_gray_msb_08bit.mat
Binary files differ
diff --git a/PerlMagick/t/input_gray_msb_16bit.fits b/PerlMagick/t/input_gray_msb_16bit.fits
new file mode 100644
index 0000000..56f9f7f
--- /dev/null
+++ b/PerlMagick/t/input_gray_msb_16bit.fits
Binary files differ
diff --git a/PerlMagick/t/input_gray_msb_32bit.fits b/PerlMagick/t/input_gray_msb_32bit.fits
new file mode 100644
index 0000000..29d58ba
--- /dev/null
+++ b/PerlMagick/t/input_gray_msb_32bit.fits
Binary files differ
diff --git a/PerlMagick/t/input_gray_msb_64bit.fits b/PerlMagick/t/input_gray_msb_64bit.fits
new file mode 100644
index 0000000..009ac0d
--- /dev/null
+++ b/PerlMagick/t/input_gray_msb_64bit.fits
Binary files differ
diff --git a/PerlMagick/t/input_gray_msb_double.fits b/PerlMagick/t/input_gray_msb_double.fits
new file mode 100644
index 0000000..0810b1d
--- /dev/null
+++ b/PerlMagick/t/input_gray_msb_double.fits
Binary files differ
diff --git a/PerlMagick/t/input_gray_msb_float.fits b/PerlMagick/t/input_gray_msb_float.fits
new file mode 100644
index 0000000..1f94243
--- /dev/null
+++ b/PerlMagick/t/input_gray_msb_float.fits
Binary files differ
diff --git a/PerlMagick/t/input_jnx.jnx b/PerlMagick/t/input_jnx.jnx
new file mode 100644
index 0000000..6f5a9a3
--- /dev/null
+++ b/PerlMagick/t/input_jnx.jnx
Binary files differ
diff --git a/PerlMagick/t/input_logical_lsb_08bit.mat b/PerlMagick/t/input_logical_lsb_08bit.mat
new file mode 100644
index 0000000..86e8779
--- /dev/null
+++ b/PerlMagick/t/input_logical_lsb_08bit.mat
Binary files differ
diff --git a/PerlMagick/t/input_matte.miff b/PerlMagick/t/input_matte.miff
new file mode 100644
index 0000000..74c82ac
--- /dev/null
+++ b/PerlMagick/t/input_matte.miff
Binary files differ
diff --git a/PerlMagick/t/input_p1.pbm b/PerlMagick/t/input_p1.pbm
new file mode 100644
index 0000000..59fa992
--- /dev/null
+++ b/PerlMagick/t/input_p1.pbm
@@ -0,0 +1,92 @@
+P1
+70 46
+0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1
+0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1
+0 1 0 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
+1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1
+0 1 0 1 0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0
+1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1
+0 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0
+1 1 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 0 1
+1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1
+1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1
+1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0
+0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0
+0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 0 0 0 0
+0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0
+0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0
+0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1
+1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 0 1 0 1 0 0 1 1 1
+0 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0
+1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 1 1 0 1 0 1 0 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 1 1
+1 0 0 0 0 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 0 1 1 1 0 1 0 0 0
+1 1 1 1 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0
+1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1
+1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1
+1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 0
+1 0 1 1 1 1 1 0 1 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1
+1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1
+0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1
+0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 0
+1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0
+1 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1
+0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1
+0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1
+1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1
+0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
+1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1
+1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 0 1 0 1 0 1
+0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1
+0 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 1 1 1 1 0
+0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 0
+0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1
+0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 1
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1
+0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 \ No newline at end of file
diff --git a/PerlMagick/t/input_p2.pgm b/PerlMagick/t/input_p2.pgm
new file mode 100644
index 0000000..6f4ca33
--- /dev/null
+++ b/PerlMagick/t/input_p2.pgm
@@ -0,0 +1,272 @@
+P2
+70 46
+255
+ 47 48 51 52 52 52 50 51 50 50 49 47
+ 46 47 47 46 46 49 52 54 58 64 67 67
+ 68 69 81 91 98 106 115 118 117 115 108 97
+ 95 94 92 88 86 84 84 85 87 89 97 102
+ 92 64 54 51 51 50 48 47 47 46 47 63
+ 90 117 134 117 79 80 119 151 122 87 46 47
+ 49 50 51 50 49 51 51 51 48 47 46 49
+ 48 48 48 49 51 53 57 62 64 63 65 69
+ 78 85 90 104 114 117 118 116 107 95 95 94
+ 91 87 85 84 84 82 85 88 99 106 93 58
+ 54 53 51 51 49 47 48 49 45 56 80 107
+ 133 113 71 70 95 131 109 87 44 44 47 47
+ 45 46 45 46 45 46 46 45 45 47 47 48
+ 49 49 50 53 52 55 56 58 62 67 71 73
+ 77 94 107 114 116 114 99 92 93 91 88 84
+ 84 83 82 81 83 91 102 108 101 61 54 52
+ 51 51 49 49 49 49 48 47 53 86 142 121
+ 72 57 55 68 79 88 45 45 45 45 43 43
+ 43 43 44 44 44 44 46 45 46 45 47 47
+ 46 49 51 54 54 56 60 64 65 66 74 84
+ 93 103 114 115 94 89 89 88 85 83 81 81
+ 80 80 86 95 103 125 138 95 65 52 48 47
+ 47 47 47 49 49 46 45 100 162 141 115 93
+ 107 143 136 97 46 46 46 46 43 43 42 39
+ 42 43 43 41 41 44 45 45 45 43 44 46
+ 51 54 53 52 54 58 60 60 69 82 87 89
+ 99 104 90 86 85 84 83 80 78 77 77 81
+ 89 93 111 148 158 123 86 61 48 42 46 46
+ 45 46 47 45 43 106 157 158 189 186 167 172
+ 149 94 47 47 48 49 49 48 46 43 43 42
+ 41 41 41 42 45 45 44 44 46 49 53 54
+ 52 50 51 53 55 52 54 71 83 86 83 90
+ 86 85 82 83 82 78 76 74 77 88 92 101
+ 132 158 159 137 110 87 58 42 42 42 43 44
+ 45 44 39 94 152 155 182 178 157 157 131 85
+ 50 51 51 54 54 52 50 47 49 46 43 44
+ 44 46 48 48 48 48 51 56 58 58 54 51
+ 52 55 54 51 49 57 70 79 79 81 84 85
+ 81 80 79 76 73 73 80 90 94 109 135 155
+ 159 142 128 121 93 57 39 39 42 43 42 40
+ 37 88 135 140 146 147 147 146 126 81 55 55
+ 56 58 61 60 59 56 56 54 51 50 50 51
+ 51 52 55 57 59 63 64 63 58 56 56 57
+ 57 56 54 56 66 83 89 86 82 82 77 76
+ 77 72 111 115 83 88 99 120 125 142 158 151
+ 144 145 132 97 58 43 40 45 44 49 78 107
+ 118 128 135 133 139 135 121 83 56 57 61 63
+ 64 66 65 65 65 62 61 60 60 56 54 53
+ 56 60 63 67 68 64 60 59 59 59 91 96
+ 86 103 96 92 96 95 94 95 94 81 76 101
+ 116 117 93 99 116 128 108 109 122 128 132 138
+ 139 131 127 116 95 56 53 64 92 123 123 123
+ 130 141 153 141 114 89 54 55 60 64 66 68
+ 68 69 68 63 62 62 61 58 56 55 57 61
+ 65 67 66 63 60 60 58 84 125 97 85 101
+ 92 96 101 88 97 105 112 109 110 109 97 104
+ 111 107 135 116 113 123 111 110 114 117 122 123
+ 127 131 143 124 71 66 119 156 153 157 180 204
+ 207 177 115 95 51 53 55 60 66 70 72 72
+ 69 74 66 60 59 57 57 56 58 61 66 67
+ 64 61 58 57 61 100 88 83 92 89 84 92
+ 95 96 101 99 103 105 106 103 99 98 117 126
+ 123 111 92 106 116 120 123 122 124 124 129 130
+ 140 143 128 116 202 225 222 234 247 247 236 208
+ 137 123 48 46 51 56 62 68 74 73 87 134
+ 126 89 67 53 50 50 56 61 65 67 59 53
+ 50 54 80 92 89 87 96 101 95 90 92 101
+ 93 100 104 106 104 98 99 102 105 112 112 102
+ 90 93 111 122 122 126 126 133 135 135 138 123
+ 156 106 219 255 249 251 255 254 251 236 191 183
+ 56 51 48 52 58 66 76 74 100 170 185 168
+ 149 113 76 65 58 60 64 61 67 82 79 78
+ 92 91 95 92 94 102 103 100 103 105 110 103
+ 104 105 104 99 98 98 111 125 98 92 94 103
+ 113 114 120 132 126 132 137 139 138 135 145 117
+ 186 255 254 253 251 251 245 224 231 235 64 61
+ 54 50 54 63 73 73 90 158 188 195 196 175
+ 133 103 82 58 57 77 125 146 124 113 93 88
+ 92 97 104 108 103 111 110 104 114 116 104 105
+ 102 95 100 101 101 121 109 93 95 102 119 106
+ 121 126 132 139 133 139 140 141 138 116 129 232
+ 254 254 250 251 242 210 242 249 73 71 65 58
+ 55 62 70 70 80 145 180 186 188 180 168 149
+ 126 104 96 117 127 117 104 112 104 98 102 106
+ 104 100 103 105 99 97 98 107 116 108 100 104
+ 108 105 107 123 115 104 96 97 102 97 109 116
+ 134 149 135 141 153 143 158 124 80 204 254 254
+ 253 254 254 232 246 250 79 78 73 67 62 64
+ 70 72 81 142 173 174 180 178 182 180 174 141
+ 113 114 109 104 110 114 107 105 107 92 94 102
+ 106 104 97 94 96 97 100 106 106 103 104 102
+ 96 117 116 120 98 96 95 94 94 99 133 151
+ 147 145 152 154 164 143 73 203 255 254 254 248
+ 254 253 247 249 82 81 79 75 73 72 74 76
+ 83 132 157 159 168 162 149 140 138 114 112 113
+ 112 101 114 113 108 100 100 95 101 107 102 104
+ 100 95 100 111 98 95 96 100 99 97 101 108
+ 114 130 115 98 94 93 92 91 121 148 138 142
+ 152 147 138 127 99 231 255 255 240 220 232 247
+ 232 234 80 80 80 78 78 77 78 78 78 99
+ 124 135 143 130 113 96 108 113 117 119 113 98
+ 105 99 104 96 94 96 101 104 108 108 107 106
+ 106 103 96 99 109 111 108 93 96 106 101 99
+ 97 114 97 87 89 86 106 150 156 156 157 138
+ 125 154 140 200 219 190 169 168 185 208 226 208
+ 79 79 79 76 78 79 80 82 80 80 88 110
+ 137 141 136 100 101 113 118 117 99 88 105 107
+ 108 92 98 97 100 110 103 101 102 102 95 102
+ 114 106 111 103 106 119 103 107 100 96 96 121
+ 101 100 102 95 92 144 168 162 158 133 122 128
+ 119 126 112 123 143 160 165 160 183 186 78 78
+ 77 76 78 78 79 81 81 81 81 94 125 155
+ 146 115 114 109 118 112 93 86 105 110 122 118
+ 94 97 105 105 108 108 105 106 111 133 142 113
+ 98 92 106 125 111 99 94 89 89 112 105 108
+ 108 108 92 129 171 163 152 128 119 90 114 132
+ 142 151 154 157 160 152 178 192 78 78 78 79
+ 79 79 80 82 82 81 78 98 137 152 155 130
+ 119 113 108 102 90 96 101 101 103 122 107 102
+ 109 110 101 100 98 99 118 147 127 101 84 70
+ 91 97 115 100 97 92 96 117 103 108 107 106
+ 95 112 177 164 142 124 110 80 131 150 152 146
+ 145 149 152 157 169 158 80 80 80 80 80 79
+ 80 79 91 102 104 123 148 146 139 139 131 113
+ 105 103 89 105 104 97 103 104 113 106 106 125
+ 121 101 98 102 111 110 104 96 118 119 111 129
+ 113 109 108 109 113 112 99 107 107 106 96 105
+ 180 157 129 123 93 88 132 142 139 138 142 146
+ 146 157 154 120 82 82 82 82 82 82 79 93
+ 128 132 124 138 160 179 184 128 111 122 108 103
+ 93 106 131 101 99 102 109 105 103 109 130 123
+ 128 131 109 111 103 126 155 150 126 101 111 113
+ 103 108 115 107 101 106 108 106 99 94 172 145
+ 124 123 67 86 131 141 132 135 139 142 143 150
+ 143 113 79 83 84 84 84 81 93 123 129 112
+ 132 178 221 235 226 178 130 139 135 108 103 96
+ 110 123 95 113 111 99 101 100 101 130 135 148
+ 144 107 103 124 142 134 105 106 105 102 108 110
+ 107 101 104 106 108 107 104 94 160 137 123 112
+ 58 68 115 132 125 130 136 136 130 118 91 85
+ 74 78 84 88 85 96 126 127 108 124 163 199
+ 215 211 187 134 107 119 152 148 120 108 99 104
+ 103 118 118 105 105 99 94 102 104 138 132 105
+ 121 115 108 111 108 107 107 107 107 109 107 102
+ 104 105 109 106 101 110 149 122 125 92 78 65
+ 86 119 121 124 130 124 115 108 99 102 65 69
+ 80 84 96 121 119 102 114 147 164 167 163 159
+ 147 108 88 94 116 155 166 137 97 92 100 103
+ 99 105 104 99 101 101 96 121 114 97 103 104
+ 105 101 103 106 107 108 108 107 104 102 104 105
+ 108 107 99 132 135 121 109 52 64 53 83 110
+ 113 120 126 122 117 114 113 112 53 57 70 77
+ 102 111 87 101 132 147 147 142 140 143 136 103
+ 90 92 120 141 164 166 99 95 99 101 101 97
+ 103 97 98 99 100 105 99 97 108 108 106 104
+ 105 110 105 107 107 109 105 101 102 101 102 102
+ 106 139 120 127 69 42 48 86 168 128 112 127
+ 130 124 122 116 116 119 45 46 55 67 93 97
+ 98 133 146 140 140 139 143 143 124 95 93 93
+ 112 135 149 116 97 99 102 97 100 96 114 100
+ 99 97 98 105 105 110 110 104 106 111 111 105
+ 104 108 110 112 106 100 100 100 98 97 122 127
+ 120 98 53 47 71 172 197 129 112 132 129 119
+ 120 119 119 126 47 44 48 59 78 89 114 154
+ 157 137 140 148 142 125 100 91 93 94 101 126
+ 113 99 102 100 103 96 97 99 112 96 97 98
+ 97 99 110 112 105 120 131 115 106 105 107 109
+ 110 109 107 95 96 96 90 90 134 122 114 66
+ 48 57 141 191 157 87 110 127 120 117 124 125
+ 122 134 61 60 59 65 75 82 100 136 150 130
+ 122 128 116 99 93 94 96 103 100 101 101 103
+ 101 100 103 95 91 106 119 91 94 98 105 109
+ 110 109 124 133 108 105 106 107 108 111 109 110
+ 107 94 89 88 81 108 137 118 102 53 72 137
+ 152 144 78 65 112 127 119 123 127 130 131 142
+ 78 78 79 80 83 87 90 103 112 105 89 85
+ 86 91 97 99 103 108 91 96 105 104 101 101
+ 103 95 85 97 105 112 109 107 111 109 109 100
+ 93 96 105 109 108 108 108 108 109 111 105 90
+ 85 79 76 124 115 109 105 106 167 135 85 59
+ 50 63 113 130 126 128 127 135 145 137 91 92
+ 92 92 92 95 95 95 94 93 90 77 71 79
+ 88 93 112 115 99 95 100 104 101 101 103 97
+ 80 92 95 101 107 108 109 109 102 89 88 93
+ 107 111 110 109 110 110 109 104 88 83 81 75
+ 77 106 102 106 120 150 90 44 54 54 56 62
+ 116 136 133 132 131 143 143 119 96 97 97 97
+ 96 99 99 97 98 97 97 90 72 66 68 71
+ 77 115 119 99 95 100 101 101 101 96 78 81
+ 94 106 117 106 93 95 87 88 91 89 91 104
+ 113 113 113 105 92 83 79 79 77 69 85 101
+ 105 107 102 70 45 60 75 57 56 59 116 137
+ 134 134 142 147 120 117 97 97 97 98 98 98
+ 99 99 99 99 99 98 85 68 63 61 63 106
+ 134 124 102 98 102 104 105 106 95 100 115 121
+ 110 89 89 84 79 79 81 83 83 88 95 100
+ 95 85 80 80 77 76 73 71 93 96 103 107
+ 119 108 78 100 76 56 55 61 117 137 134 138
+ 148 123 119 118 97 97 96 100 99 100 100 100
+ 100 100 100 100 97 80 64 59 91 101 119 148
+ 121 109 111 114 117 118 120 120 117 115 106 89
+ 85 81 78 78 78 76 76 76 78 81 82 80
+ 79 76 71 73 69 77 95 98 102 105 85 90
+ 106 76 59 58 55 59 107 137 135 144 129 113
+ 123 115 97 98 99 98 98 99 99 99 100 100
+ 100 100 96 97 88 61 86 95 98 113 114 110
+ 106 108 113 112 114 115 113 113 106 86 79 79
+ 79 80 78 77 76 76 76 75 76 76 75 73
+ 71 69 66 79 99 101 103 104 100 97 85 61
+ 55 59 56 55 91 132 143 134 111 116 122 111
+ 97 98 100 98 98 99 99 99 100 100 99 92
+ 112 160 175 122 58 55 59 59 73 99 110 108
+ 113 114 114 114 112 111 112 94 80 79 78 79
+ 78 77 77 77 76 74 74 74 74 71 68 67
+ 63 76 102 105 103 91 76 57 64 69 61 55
+ 55 54 80 131 144 114 109 115 116 107 98 98
+ 100 98 98 99 99 100 100 99 94 129 208 251
+ 255 227 147 69 58 55 46 71 150 123 106 113
+ 113 112 110 109 111 102 82 79 79 78 76 76
+ 77 77 75 73 70 71 70 70 68 66 60 72
+ 104 99 77 59 50 51 49 58 68 56 48 51
+ 70 132 132 101 108 113 113 104 99 99 99 99
+ 99 99 100 101 101 99 106 193 255 255 255 253
+ 236 159 74 55 74 154 240 231 143 100 105 108
+ 108 109 110 104 84 80 78 77 76 76 78 78
+ 74 70 69 69 69 70 68 62 55 74 93 65
+ 52 55 56 55 53 52 62 65 51 43 68 140
+ 116 96 101 107 114 94 99 99 99 99 99 99
+ 100 101 101 98 100 176 248 253 250 249 253 219
+ 109 70 150 234 253 255 254 189 105 92 106 107
+ 110 98 84 80 78 77 76 76 76 74 70 69
+ 68 68 68 69 69 67 71 85 55 50 53 52
+ 52 52 53 51 52 61 63 47 72 127 90 92
+ 91 103 114 77 100 100 100 100 100 100 101 102
+ 100 108 166 230 255 255 249 249 253 214 111 117
+ 203 254 255 254 255 255 227 129 90 102 108 97
+ 85 81 79 77 74 73 72 69 69 69 67 68
+ 69 70 73 78 116 106 46 52 52 51 50 49
+ 49 50 48 50 58 59 71 81 76 91 85 102
+ 108 62 100 100 100 100 100 100 101 102 101 127
+ 224 255 255 252 230 230 238 207 175 204 242 255
+ 255 254 254 254 255 253 171 95 95 96 86 82
+ 79 78 77 76 73 71 71 69 69 70 73 78
+ 79 80 124 84 46 52 52 51 49 48 49 48
+ 46 48 48 51 56 56 61 78 83 104 100 51
+ 100 100 100 101 101 101 101 104 102 114 203 255
+ 255 250 234 233 230 213 229 252 255 255 254 254
+ 254 253 253 254 255 215 126 89 80 76 77 76
+ 78 79 77 75 73 72 71 70 63 79 86 90
+ 113 57 53 53 54 53 50 49 49 47 45 46
+ 48 48 50 60 62 57 68 98 88 49 99 100
+ 101 101 101 101 101 104 103 114 195 253 255 254
+ 242 222 213 225 249 254 255 254 254 254 254 253
+ 254 251 254 255 252 199 127 84 66 65 71 75
+ 74 73 74 74 74 93 67 61 68 109 92 53
+ 58 58 59 59 58 57 57 53 49 47 44 44
+ 47 49 65 68 56 74 75 53 98 99 101 101
+ 101 101 102 104 102 112 205 255 255 254 243 207
+ 192 234 255 254 254 254 254 254 254 254 253 252
+ 254 254 255 255 255 243 218 192 87 71 78 78
+ 79 76 76 97 69 64 70 100 89 68 60 60
+ 59 60 61 63 60 62 59 57 52 47 46 44
+ 47 65 67 65 68 54 97 99 104 102 102 103
+ 102 102 104 133 208 249 248 236 217 193 192 227
+ 252 254 254 254 254 253 253 253 254 254 249 239
+ 251 254 254 255 253 228 102 74 77 77 76 75
+ 74 72 77 94 96 83 82 80 72 65 61 61
+ 62 61 61 62 63 65 65 61 58 61 84 86
+ 69 74 83 60
diff --git a/PerlMagick/t/input_p3.ppm b/PerlMagick/t/input_p3.ppm
new file mode 100644
index 0000000..d131158
--- /dev/null
+++ b/PerlMagick/t/input_p3.ppm
@@ -0,0 +1,809 @@
+P3
+70 46
+255
+ 48 47 45 50 48 46 54 50 47 56 51 46
+ 58 51 45 57 50 45 56 48 45 57 49 46
+ 56 48 45 56 48 45 55 47 44 53 45 42
+ 52 44 41 53 45 42 53 45 42 49 45 39
+ 49 46 39 52 49 42 55 52 45 57 54 47
+ 63 58 47 70 63 51 74 66 52 76 65 50
+ 78 66 50 85 65 50 116 68 52 154 67 51
+ 180 65 53 197 69 61 224 68 71 237 67 70
+ 246 61 66 241 60 64 214 64 59 184 63 47
+ 178 63 45 173 64 45 163 65 43 152 64 43
+ 146 63 46 145 61 44 146 61 43 147 61 42
+ 149 63 46 153 63 51 177 66 51 187 68 54
+ 149 70 57 82 58 47 58 53 51 55 50 49
+ 55 50 47 54 49 46 51 48 44 47 47 45
+ 48 47 45 51 44 45 54 43 45 80 55 56
+ 130 73 71 157 98 110 140 124 166 108 112 165
+ 80 72 110 82 76 97 117 119 124 149 154 144
+ 122 124 108 89 86 83 47 46 44 48 47 45
+ 53 48 45 55 49 45 56 49 44 56 48 44
+ 54 47 44 56 49 45 56 49 45 56 49 46
+ 55 46 44 52 45 42 52 44 42 54 47 43
+ 54 46 43 51 47 42 51 48 42 52 49 43
+ 54 51 45 55 53 48 62 56 45 69 61 50
+ 72 63 49 73 62 46 75 64 47 77 68 51
+ 105 69 52 140 64 46 166 60 45 186 71 60
+ 220 68 71 235 66 69 252 60 65 247 60 64
+ 209 65 59 177 63 45 176 63 43 173 63 44
+ 162 64 43 151 63 43 145 62 46 144 61 44
+ 145 61 42 144 59 42 145 62 45 152 62 51
+ 186 64 52 200 68 56 147 72 59 68 55 44
+ 57 53 53 57 51 49 54 50 47 54 50 46
+ 49 49 45 45 49 46 48 48 46 53 47 46
+ 50 42 44 69 50 49 120 65 53 148 89 92
+ 134 125 171 99 108 172 74 62 107 75 64 92
+ 93 94 103 128 134 126 108 112 95 89 87 83
+ 44 44 44 44 45 43 48 47 44 49 46 43
+ 50 44 40 50 45 42 48 44 43 50 44 43
+ 50 43 43 50 44 43 50 44 43 49 44 43
+ 49 44 41 51 45 44 51 45 44 51 47 44
+ 51 49 44 52 48 44 53 50 45 55 53 48
+ 58 51 44 62 54 45 64 54 45 67 56 45
+ 72 59 47 69 69 53 85 68 52 109 61 43
+ 132 57 40 159 69 52 192 72 61 220 69 64
+ 246 60 62 236 62 61 185 65 48 165 64 42
+ 169 63 45 165 62 45 155 63 44 145 62 41
+ 142 62 44 140 61 45 139 60 45 137 59 46
+ 137 63 47 155 66 49 195 64 56 195 71 68
+ 137 87 78 60 63 53 59 52 49 57 51 46
+ 53 51 46 49 52 47 45 52 46 44 52 48
+ 47 51 47 49 50 48 48 48 46 51 45 43
+ 73 46 33 108 77 78 138 135 189 107 113 198
+ 72 61 127 61 49 88 53 52 72 62 70 70
+ 73 83 73 89 90 79 44 45 47 43 45 47
+ 46 45 45 47 45 41 47 42 39 45 43 40
+ 44 42 42 44 42 42 46 43 43 46 43 43
+ 46 43 43 47 43 43 47 45 45 48 44 44
+ 48 45 46 47 45 42 50 46 44 50 46 43
+ 50 45 44 51 48 46 56 50 47 60 52 47
+ 62 52 47 65 53 45 70 57 49 72 62 55
+ 81 60 53 95 55 48 121 55 45 147 59 47
+ 163 65 51 188 69 57 222 69 64 218 72 65
+ 167 66 47 155 64 44 158 62 45 156 61 47
+ 148 61 45 140 61 43 136 60 43 135 60 44
+ 133 60 46 130 60 50 134 67 55 157 71 58
+ 186 69 64 180 103 95 143 138 121 87 101 87
+ 67 66 56 55 53 43 47 49 42 46 49 43
+ 45 48 44 45 48 47 47 48 46 48 50 46
+ 47 50 46 47 45 50 52 42 44 103 99 98
+ 154 157 206 126 135 208 105 112 158 89 92 111
+ 96 112 114 130 150 140 124 143 129 95 101 81
+ 44 47 50 43 47 50 46 46 48 45 46 45
+ 45 43 41 44 42 43 43 41 43 40 39 40
+ 42 42 43 44 42 43 44 42 43 42 41 41
+ 42 40 41 45 43 44 46 45 46 47 44 43
+ 48 44 43 46 42 41 47 43 43 48 45 45
+ 56 49 49 60 51 50 59 50 49 62 48 46
+ 65 50 47 65 55 51 66 58 54 75 54 50
+ 104 55 47 137 61 48 149 62 53 152 65 51
+ 175 68 55 186 71 60 158 63 51 146 63 44
+ 148 61 43 149 59 45 142 60 45 135 59 44
+ 135 57 41 130 57 42 127 58 46 127 63 55
+ 134 71 64 151 69 62 174 85 82 163 145 123
+ 140 171 140 114 129 112 83 90 71 60 64 51
+ 48 49 40 45 41 39 50 44 43 50 44 43
+ 48 44 42 48 45 43 48 47 43 50 42 49
+ 48 41 40 101 113 82 149 161 156 143 165 163
+ 166 202 179 164 199 176 143 182 151 153 186 152
+ 133 161 132 89 100 74 46 48 46 47 47 45
+ 47 49 46 50 49 46 51 48 45 51 47 44
+ 50 45 42 45 42 43 44 43 44 42 41 45
+ 43 40 44 45 39 44 43 40 41 44 42 41
+ 45 45 43 47 45 44 46 43 42 47 43 41
+ 52 44 41 54 47 42 59 51 46 61 52 48
+ 59 49 45 59 47 46 62 47 46 62 51 44
+ 53 57 47 57 51 44 79 44 39 105 58 45
+ 131 65 49 142 64 49 146 59 45 152 66 50
+ 148 62 50 147 60 47 137 61 46 137 63 47
+ 139 60 47 132 57 44 123 59 44 118 58 42
+ 125 59 48 134 71 59 135 75 68 149 81 79
+ 147 129 112 144 169 139 137 173 142 119 150 121
+ 92 123 90 78 94 71 61 58 51 50 39 40
+ 47 39 41 45 40 43 48 40 44 50 40 47
+ 49 43 48 48 42 48 43 39 31 91 102 64
+ 145 162 118 140 170 118 160 201 140 157 195 147
+ 132 175 126 135 173 130 118 142 112 79 91 68
+ 50 51 45 51 52 45 53 51 46 57 54 49
+ 57 54 49 58 50 46 56 48 45 51 46 44
+ 51 48 48 45 46 48 47 40 47 49 41 46
+ 47 42 44 49 46 42 49 48 42 48 49 46
+ 47 48 48 52 47 43 59 49 43 65 53 44
+ 67 56 47 65 57 48 61 53 45 59 48 47
+ 60 49 47 69 49 45 82 41 46 70 42 46
+ 55 48 41 82 47 40 106 57 46 131 58 55
+ 134 57 52 127 63 53 132 66 54 137 65 49
+ 133 62 45 136 58 43 133 59 42 118 62 41
+ 118 56 44 115 57 45 123 64 52 137 71 62
+ 136 78 69 134 100 86 122 146 113 123 175 136
+ 131 177 140 118 158 124 101 146 103 100 135 101
+ 80 102 80 52 61 48 42 38 35 46 36 38
+ 43 42 42 41 43 44 39 43 47 39 39 45
+ 41 36 34 87 92 72 126 145 106 123 156 106
+ 126 163 111 127 165 111 125 165 116 126 161 123
+ 111 137 108 76 86 68 55 56 50 55 56 50
+ 57 57 52 60 58 53 64 61 56 66 58 56
+ 65 57 53 61 55 51 60 55 53 58 53 52
+ 57 48 48 57 47 47 54 49 46 54 50 46
+ 54 51 46 54 52 49 57 55 51 63 55 50
+ 66 57 48 72 61 49 74 62 52 72 61 52
+ 66 56 48 64 54 49 63 54 50 60 57 52
+ 67 53 52 65 53 48 60 54 42 69 53 39
+ 99 54 45 135 61 59 144 66 65 132 67 59
+ 132 62 54 127 65 53 126 58 47 121 59 47
+ 117 62 46 122 52 41 185 80 76 172 91 86
+ 112 74 57 107 83 64 115 96 73 127 122 88
+ 182 102 96 191 122 114 162 161 133 143 160 126
+ 139 151 118 128 158 120 111 147 111 88 105 77
+ 63 59 41 51 41 34 37 43 33 43 47 38
+ 58 38 42 67 41 41 84 78 58 104 113 82
+ 104 131 87 107 145 92 110 154 99 107 152 104
+ 115 156 116 116 149 116 104 134 100 78 88 67
+ 56 57 51 57 58 52 62 62 56 65 63 58
+ 68 63 58 70 65 60 69 65 58 69 64 58
+ 71 63 56 69 61 52 68 59 49 67 58 51
+ 67 58 51 60 56 48 57 53 47 57 52 47
+ 60 55 48 66 60 48 73 61 48 79 65 50
+ 80 64 53 75 60 52 69 58 49 65 58 49
+ 61 60 51 71 55 48 139 69 74 154 71 73
+ 134 67 58 171 75 72 162 70 57 166 63 51
+ 168 67 53 162 69 49 170 64 50 172 62 66
+ 158 67 69 118 67 57 121 58 52 191 60 72
+ 225 69 71 195 85 80 112 89 67 96 106 72
+ 144 108 83 232 83 90 255 40 72 255 41 75
+ 249 64 86 240 77 95 228 89 104 219 102 110
+ 212 106 114 210 95 109 212 87 107 194 80 98
+ 150 70 79 82 46 40 62 51 40 71 64 45
+ 101 94 58 119 131 92 110 135 92 109 137 89
+ 115 143 100 126 152 123 140 162 142 128 150 129
+ 100 125 95 83 95 71 54 55 49 54 56 49
+ 61 61 56 66 64 59 70 65 63 72 67 62
+ 72 67 62 74 68 60 77 66 55 74 61 48
+ 72 60 45 70 61 47 69 59 48 65 57 49
+ 60 55 49 58 55 46 62 57 44 69 60 47
+ 77 63 47 79 65 48 79 62 49 75 59 49
+ 68 58 47 62 61 49 55 61 48 128 66 64
+ 237 75 93 203 51 53 155 59 35 193 63 53
+ 172 59 48 179 62 51 183 68 55 165 58 40
+ 185 62 50 209 62 56 239 56 63 225 60 60
+ 212 68 63 235 55 59 218 46 39 196 66 58
+ 146 100 79 136 99 74 222 99 94 247 59 69
+ 224 66 67 245 70 79 254 46 69 255 44 72
+ 255 48 84 255 52 92 255 58 104 255 58 111
+ 255 65 114 255 71 111 255 90 120 198 91 102
+ 97 61 51 72 67 47 127 118 100 154 159 149
+ 145 158 152 152 160 154 182 181 173 209 203 198
+ 212 204 211 176 177 177 103 123 101 87 103 76
+ 51 51 48 53 53 49 56 56 51 61 60 54
+ 68 67 57 71 71 62 74 73 59 77 73 54
+ 73 69 55 77 72 74 72 64 57 69 59 43
+ 67 57 45 63 56 48 62 56 51 61 55 49
+ 62 57 52 64 61 57 73 65 54 80 64 45
+ 72 63 45 75 56 49 67 55 52 53 61 48
+ 64 63 47 166 73 64 175 52 43 164 52 33
+ 166 65 38 169 58 36 160 54 39 169 61 50
+ 172 65 49 176 64 50 191 64 52 204 56 41
+ 232 49 43 249 43 43 243 48 41 225 54 37
+ 216 53 33 199 57 44 197 85 73 224 85 81
+ 254 65 75 223 63 65 174 59 46 196 69 59
+ 236 65 68 252 62 72 253 65 81 255 61 86
+ 254 62 104 251 62 113 252 69 119 249 74 110
+ 253 87 120 255 89 127 205 93 110 135 110 100
+ 211 200 193 224 224 234 230 214 240 245 225 249
+ 253 243 249 253 244 243 245 231 240 211 206 210
+ 133 141 131 117 129 110 49 48 45 47 46 44
+ 52 51 47 56 57 50 62 63 53 71 68 59
+ 79 75 56 77 75 52 88 87 87 128 131 165
+ 124 120 160 91 84 111 70 63 79 57 52 52
+ 54 50 38 53 50 41 58 57 46 66 61 45
+ 75 64 47 80 64 47 67 59 42 58 52 41
+ 48 52 48 66 49 45 138 54 60 174 59 47
+ 164 60 39 161 59 37 181 62 44 199 61 49
+ 184 59 49 173 57 42 179 58 43 195 63 50
+ 196 51 42 214 52 44 220 56 46 241 49 43
+ 240 47 40 212 53 32 218 52 33 212 57 44
+ 208 63 54 219 67 65 222 65 62 199 62 51
+ 174 57 40 175 61 45 213 69 64 243 70 75
+ 247 68 75 254 68 88 254 66 98 255 74 116
+ 255 75 125 254 77 122 254 84 116 243 67 99
+ 228 123 136 137 95 84 241 211 201 255 255 255
+ 255 245 255 255 248 255 255 255 254 255 254 251
+ 255 249 253 242 233 236 192 191 184 181 186 176
+ 58 56 49 54 51 45 51 48 43 55 52 44
+ 60 59 50 73 65 54 86 74 57 84 72 58
+ 100 97 114 158 165 228 172 178 255 157 161 236
+ 143 143 197 110 109 142 76 73 88 64 63 77
+ 60 57 57 65 61 40 66 67 46 56 65 57
+ 58 69 81 69 85 97 70 83 82 97 71 60
+ 148 70 55 168 61 43 174 65 45 176 59 40
+ 191 54 42 212 56 48 210 58 52 206 56 50
+ 211 58 51 215 59 50 223 63 55 235 49 39
+ 244 45 40 249 45 40 235 50 40 210 55 33
+ 207 55 34 209 53 40 217 67 60 221 86 77
+ 186 62 50 179 58 35 185 58 41 198 64 55
+ 210 72 70 216 71 72 237 70 74 251 79 92
+ 248 70 96 253 74 110 252 82 122 247 88 122
+ 253 85 113 249 83 103 255 96 112 213 75 85
+ 225 170 164 255 255 254 252 255 255 253 253 254
+ 254 250 245 255 250 249 254 240 244 234 220 219
+ 239 230 219 235 237 228 68 64 53 65 61 51
+ 59 54 45 53 50 40 58 53 47 70 61 55
+ 84 71 54 87 70 55 93 85 106 144 153 222
+ 171 184 255 181 190 255 185 190 255 167 167 239
+ 128 124 194 102 92 158 82 76 115 55 58 67
+ 58 57 55 82 74 78 134 115 155 170 129 174
+ 186 93 123 200 75 80 179 60 39 169 57 35
+ 179 58 42 193 59 45 212 60 51 225 59 51
+ 219 54 49 229 62 57 230 60 55 220 56 47
+ 227 68 57 244 63 52 251 41 41 250 43 43
+ 227 50 44 207 50 37 201 60 40 208 58 42
+ 212 55 45 228 76 72 209 67 64 187 57 36
+ 191 57 40 199 62 50 211 81 73 196 69 62
+ 224 78 73 231 81 83 240 84 97 253 86 110
+ 251 78 111 253 85 120 255 87 111 255 90 105
+ 252 87 101 202 79 84 161 116 110 250 225 224
+ 252 255 255 250 255 255 254 249 247 255 250 245
+ 250 239 240 220 206 201 249 242 224 249 251 238
+ 79 73 59 77 71 58 70 64 53 63 57 48
+ 61 54 48 65 61 56 77 69 53 83 68 46
+ 87 76 83 132 142 193 166 174 251 176 178 255
+ 178 180 255 169 172 249 156 160 237 139 141 216
+ 111 122 182 97 101 135 133 78 95 203 79 87
+ 239 76 93 220 72 82 210 59 62 230 62 62
+ 206 62 53 188 62 47 198 63 50 212 62 52
+ 217 57 47 219 51 43 218 55 47 222 56 47
+ 217 51 41 209 51 36 202 57 34 219 62 48
+ 254 56 59 247 48 53 219 50 48 223 53 52
+ 239 53 51 226 55 43 217 62 47 227 80 74
+ 220 69 73 208 61 51 194 56 43 188 60 45
+ 192 67 50 188 61 45 199 72 61 206 78 74
+ 230 92 97 254 102 118 253 80 109 250 90 117
+ 241 114 120 243 98 112 238 123 128 146 117 101
+ 86 80 65 224 195 196 255 253 255 253 254 255
+ 255 252 254 253 255 248 255 255 250 237 231 220
+ 250 248 222 251 252 233 87 78 63 86 77 63
+ 80 73 58 75 66 52 70 60 49 69 64 55
+ 76 71 53 83 71 46 86 78 81 131 139 189
+ 163 164 246 164 164 255 164 173 255 164 173 240
+ 174 173 246 160 175 254 161 171 224 186 118 141
+ 222 65 78 239 60 63 229 59 55 202 64 49
+ 209 70 59 237 61 65 224 57 60 204 64 58
+ 199 69 57 187 54 40 200 50 43 220 52 49
+ 222 59 47 223 55 41 211 52 33 196 54 33
+ 198 55 38 206 53 41 214 53 43 228 56 46
+ 233 52 50 235 45 53 247 42 48 228 49 41
+ 203 53 36 217 76 65 218 72 73 223 77 75
+ 199 56 46 193 58 40 187 59 39 183 59 42
+ 180 60 47 187 64 51 226 94 86 247 110 109
+ 246 103 112 241 103 113 237 116 114 251 111 117
+ 255 122 139 136 151 124 65 81 51 221 196 192
+ 255 255 255 255 254 255 251 255 254 238 255 240
+ 255 255 249 255 254 241 254 248 226 253 250 234
+ 91 80 65 91 79 65 89 77 63 84 74 58
+ 84 71 57 78 71 60 82 74 57 87 75 52
+ 88 81 84 127 128 170 148 151 212 149 151 228
+ 153 162 236 148 159 216 136 144 208 135 133 190
+ 197 105 149 230 61 80 226 64 58 231 62 67
+ 225 63 70 195 62 59 214 71 70 232 62 65
+ 215 63 59 196 61 49 192 63 48 185 59 43
+ 205 58 46 228 57 51 224 51 47 228 52 46
+ 209 56 42 186 59 43 198 59 54 233 60 57
+ 201 57 37 194 57 33 207 51 38 212 53 47
+ 207 55 43 200 56 38 201 61 41 219 62 53
+ 232 64 66 237 85 83 221 71 61 199 57 41
+ 183 58 42 175 60 45 172 60 46 175 58 42
+ 209 86 71 240 109 106 233 97 103 241 98 109
+ 250 110 113 255 100 108 248 87 112 117 136 105
+ 88 110 69 241 229 212 255 255 255 255 255 255
+ 226 249 230 197 235 200 226 239 213 253 248 230
+ 244 230 214 242 232 221 91 78 62 90 78 62
+ 91 78 61 88 77 60 90 76 60 87 75 63
+ 88 76 60 90 76 56 85 76 71 100 95 117
+ 119 120 154 130 128 186 137 134 205 123 123 182
+ 102 109 166 124 82 98 220 59 70 255 51 63
+ 233 69 62 238 67 78 220 66 71 182 64 53
+ 198 67 59 209 52 49 198 66 53 189 59 41
+ 190 57 37 193 58 37 212 56 40 229 52 43
+ 247 49 51 255 44 51 251 45 49 243 46 56
+ 251 40 62 246 40 48 211 48 39 205 56 40
+ 228 59 50 232 61 52 208 68 54 192 54 38
+ 202 53 41 227 55 53 229 46 47 214 52 42
+ 206 53 42 212 74 62 184 62 49 169 54 42
+ 168 58 43 166 55 38 188 72 62 238 113 114
+ 247 115 126 250 114 123 253 115 123 254 86 101
+ 249 68 97 152 160 125 125 154 103 203 204 174
+ 212 226 198 175 202 170 149 184 142 143 188 134
+ 168 199 154 206 213 186 238 222 212 221 203 197
+ 91 76 60 91 76 60 92 76 60 89 73 59
+ 90 75 59 91 76 62 94 77 60 94 80 60
+ 91 78 65 89 76 73 94 83 100 109 101 155
+ 135 127 196 155 126 180 171 113 163 181 64 71
+ 201 62 43 232 64 57 252 60 64 233 66 74
+ 191 60 55 166 57 40 199 66 56 221 59 56
+ 207 68 58 186 55 36 196 59 40 201 56 39
+ 218 52 39 238 57 46 227 52 39 238 44 36
+ 245 41 39 248 37 50 255 22 54 243 39 54
+ 237 60 68 237 49 58 254 48 58 243 43 46
+ 223 56 53 232 71 71 217 54 52 221 59 54
+ 213 53 42 196 56 38 195 56 43 219 81 71
+ 201 60 51 205 57 49 208 58 51 191 56 43
+ 179 56 45 231 107 107 255 129 137 253 122 131
+ 255 114 127 255 77 100 249 63 92 130 134 94
+ 103 135 81 124 133 92 97 126 81 101 141 89
+ 121 161 104 134 182 116 141 185 121 148 172 127
+ 192 181 166 197 181 179 91 75 58 91 75 58
+ 89 75 58 89 73 57 91 75 58 93 74 60
+ 94 75 60 94 79 59 94 79 59 95 78 58
+ 95 75 72 97 87 119 124 119 155 194 135 155
+ 245 101 119 255 52 75 228 64 70 209 67 64
+ 239 66 71 218 67 64 178 59 46 164 56 38
+ 206 64 54 236 56 59 232 77 69 214 80 65
+ 194 54 40 207 52 42 228 54 48 238 49 47
+ 242 49 57 250 45 60 245 42 60 240 45 72
+ 249 46 87 248 81 99 254 92 109 238 56 79
+ 213 48 53 184 55 38 204 67 54 226 83 78
+ 215 67 64 203 57 46 194 55 36 167 59 37
+ 172 56 41 211 70 66 222 56 51 242 51 49
+ 250 48 48 229 57 49 190 52 39 217 92 87
+ 255 135 139 252 124 132 252 107 124 251 72 97
+ 243 62 85 89 97 55 101 128 78 129 139 100
+ 126 157 109 127 171 112 136 171 111 135 177 112
+ 130 185 111 133 170 113 181 182 153 195 191 190
+ 92 75 55 92 75 54 92 75 54 93 76 55
+ 93 76 57 93 76 59 94 77 61 93 80 61
+ 93 80 61 97 77 58 99 71 62 103 93 113
+ 127 134 181 179 135 166 246 117 113 255 75 85
+ 243 63 81 231 61 71 219 60 61 199 62 52
+ 169 59 42 180 62 47 209 56 51 222 51 43
+ 219 57 39 233 77 65 210 65 51 211 58 46
+ 236 55 57 247 50 62 252 34 47 255 32 45
+ 246 33 43 238 37 55 247 59 86 255 99 112
+ 241 78 83 203 58 53 161 54 36 135 45 24
+ 173 58 48 194 56 54 216 73 69 201 59 48
+ 199 56 43 180 56 43 193 56 47 222 74 64
+ 226 51 46 252 46 49 250 45 48 240 50 44
+ 201 52 37 197 77 69 255 143 144 255 123 136
+ 255 89 116 255 63 97 210 64 83 73 89 49
+ 112 149 91 133 166 111 131 170 113 124 165 102
+ 126 163 102 127 168 107 126 176 101 134 178 110
+ 156 182 137 150 164 151 94 77 58 94 77 58
+ 94 77 58 94 77 58 94 77 58 95 76 55
+ 94 78 57 86 78 65 97 88 89 111 96 109
+ 109 100 112 112 120 168 131 140 234 153 131 205
+ 185 118 124 232 100 92 253 77 85 242 57 65
+ 222 55 55 195 66 50 169 58 43 189 71 62
+ 197 66 57 202 54 43 222 54 39 227 52 46
+ 224 68 55 220 60 46 240 48 51 255 68 78
+ 245 67 71 230 47 45 225 44 40 222 50 51
+ 223 62 67 217 63 67 220 55 56 202 51 46
+ 210 79 74 212 79 81 202 73 71 233 85 85
+ 218 69 65 212 66 58 222 60 55 243 50 61
+ 245 55 63 232 62 58 220 49 42 243 50 48
+ 248 46 50 243 48 46 205 52 37 186 72 60
+ 255 147 149 253 113 129 255 70 104 255 60 100
+ 157 65 71 78 98 60 114 150 90 121 161 99
+ 117 159 96 118 157 95 122 161 100 123 166 100
+ 123 169 90 135 179 104 137 170 118 108 130 103
+ 95 79 61 95 79 63 95 79 62 95 79 61
+ 95 79 61 96 80 55 92 76 57 95 91 97
+ 125 124 160 129 125 178 113 118 184 124 134 198
+ 154 155 199 186 175 183 200 182 150 178 112 82
+ 198 76 65 240 72 74 232 55 57 213 58 50
+ 187 55 46 186 73 63 205 102 88 193 64 51
+ 218 50 43 228 49 44 225 61 49 228 55 41
+ 240 45 41 240 53 53 241 82 88 234 74 81
+ 235 81 86 236 86 91 213 64 66 234 57 63
+ 235 45 55 242 74 86 255 111 122 255 102 118
+ 231 82 78 215 53 51 220 65 60 220 69 60
+ 224 52 48 252 44 58 255 53 63 231 54 51
+ 221 52 42 240 50 47 251 46 50 245 47 45
+ 211 53 41 178 60 51 254 136 143 248 98 119
+ 255 62 99 244 65 100 92 59 47 76 95 62
+ 117 145 94 123 158 99 111 151 87 114 154 88
+ 120 158 94 121 163 91 119 166 86 128 171 97
+ 128 159 104 101 124 86 91 77 61 95 80 64
+ 95 82 66 96 82 67 96 82 64 92 79 66
+ 99 89 97 119 119 154 119 124 185 99 106 180
+ 122 122 214 175 172 219 228 225 182 248 242 164
+ 235 232 171 184 181 145 160 121 100 214 108 103
+ 246 87 90 234 54 58 218 54 51 189 58 49
+ 187 79 65 211 88 73 208 49 39 232 62 60
+ 226 64 55 224 48 37 233 45 39 219 51 42
+ 207 57 53 238 83 87 245 86 98 255 100 111
+ 251 97 103 246 47 55 246 40 54 247 70 83
+ 250 94 102 247 84 91 223 55 51 230 54 52
+ 221 56 50 214 56 48 228 58 53 231 59 59
+ 232 54 53 216 53 43 226 54 42 243 48 45
+ 250 47 52 246 48 47 218 57 46 185 56 50
+ 252 119 130 255 82 112 255 60 100 193 74 91
+ 61 60 38 65 74 48 104 126 83 116 148 88
+ 104 146 76 109 150 81 115 155 90 115 157 84
+ 108 151 77 98 138 69 78 106 52 73 97 52
+ 84 72 56 89 76 60 95 82 66 98 86 68
+ 96 83 63 102 93 98 123 121 158 116 122 180
+ 93 102 175 108 118 193 152 157 223 193 196 231
+ 216 215 215 216 211 200 194 183 188 131 135 136
+ 111 106 101 153 106 100 227 121 117 255 103 101
+ 244 68 65 221 61 53 194 60 49 199 66 50
+ 209 60 45 227 71 70 226 73 70 224 55 48
+ 227 54 48 203 57 43 186 58 38 201 61 54
+ 208 58 65 243 91 103 235 87 94 224 55 51
+ 246 66 73 234 63 70 230 55 57 247 53 54
+ 239 53 49 238 51 48 225 58 47 223 59 51
+ 232 54 53 234 55 56 233 54 52 219 54 45
+ 224 55 40 239 49 43 244 51 53 244 48 47
+ 219 52 42 209 68 66 250 104 117 255 59 100
+ 254 64 104 128 77 71 82 80 60 69 66 45
+ 79 95 57 105 135 76 101 142 68 103 145 75
+ 110 149 85 104 143 76 94 135 69 89 125 67
+ 87 111 66 91 115 68 68 66 54 74 69 60
+ 92 77 62 96 83 62 101 95 88 122 116 145
+ 115 112 167 93 95 161 105 105 187 139 136 223
+ 157 157 222 162 161 214 160 155 214 158 150 206
+ 149 137 193 112 103 125 94 86 82 124 83 72
+ 184 89 81 236 121 115 255 128 124 239 94 90
+ 201 54 45 190 53 35 202 59 42 213 58 48
+ 207 55 44 220 57 47 220 56 47 197 60 42
+ 194 64 49 197 61 52 193 55 51 217 80 76
+ 210 75 66 204 54 36 235 47 48 248 40 58
+ 252 39 63 255 31 58 255 35 56 243 46 54
+ 223 58 53 224 60 53 234 55 53 238 51 53
+ 228 52 48 219 55 41 220 57 38 229 54 38
+ 239 53 45 237 53 41 215 52 39 237 86 92
+ 255 80 107 255 56 101 205 64 88 57 53 35
+ 65 66 51 55 56 33 81 90 52 100 121 78
+ 95 132 65 99 140 68 108 144 78 104 141 71
+ 99 134 73 99 130 74 102 127 73 98 127 68
+ 52 55 45 58 58 52 79 68 59 86 76 61
+ 103 101 108 108 106 145 81 81 138 91 93 165
+ 121 123 206 137 137 221 140 139 209 136 133 205
+ 136 129 210 141 133 200 135 130 173 126 90 106
+ 92 91 76 112 87 68 207 83 86 231 102 107
+ 239 133 127 254 129 122 197 59 45 187 59 35
+ 198 59 41 214 54 43 204 59 43 203 54 40
+ 214 58 45 200 56 40 197 58 45 200 58 47
+ 202 58 48 206 63 53 200 58 46 214 49 39
+ 249 47 55 255 43 61 250 42 62 254 36 58
+ 255 38 57 240 53 61 218 58 54 223 59 52
+ 235 53 52 241 52 56 226 54 47 213 55 41
+ 217 56 38 218 54 36 215 57 38 212 59 37
+ 215 61 52 254 87 108 255 55 99 252 67 106
+ 107 51 61 35 47 37 47 52 29 94 89 50
+ 160 179 130 115 141 96 93 131 62 109 147 75
+ 112 149 81 107 143 72 105 139 77 101 132 74
+ 102 131 72 103 137 71 42 48 38 43 48 43
+ 57 55 53 69 67 61 90 92 105 92 93 135
+ 91 90 156 121 124 214 133 136 235 130 130 218
+ 129 133 202 131 130 210 139 130 219 141 134 194
+ 126 120 137 115 87 82 96 95 72 100 95 67
+ 174 87 80 236 90 99 243 110 106 217 75 64
+ 201 55 38 200 60 39 214 56 43 213 49 40
+ 197 62 43 191 58 40 219 71 59 206 57 43
+ 201 58 41 200 55 40 206 55 40 215 60 47
+ 218 59 48 238 54 59 249 49 63 238 45 59
+ 233 51 54 245 53 56 240 55 59 225 54 53
+ 219 56 53 227 58 56 239 55 56 246 54 59
+ 226 56 52 207 56 42 204 58 41 205 58 39
+ 194 61 33 193 60 38 233 75 77 255 66 103
+ 255 54 103 167 67 79 51 54 52 56 43 47
+ 68 78 41 165 185 121 182 213 154 113 144 92
+ 93 132 61 114 152 78 111 148 82 102 138 69
+ 103 137 77 101 136 75 102 137 71 107 145 74
+ 46 50 38 43 46 40 48 49 43 58 61 48
+ 76 79 78 88 86 109 110 108 159 146 143 234
+ 147 144 246 129 127 209 132 132 199 141 141 206
+ 142 133 191 129 119 147 108 97 93 94 93 71
+ 102 93 73 106 92 69 136 89 67 230 82 81
+ 235 61 61 220 48 43 219 55 38 211 55 38
+ 225 53 43 200 53 41 189 61 43 197 60 43
+ 218 68 57 194 56 41 196 58 40 202 57 40
+ 207 52 40 216 50 41 231 59 52 241 56 60
+ 236 47 58 236 69 74 239 86 81 234 65 61
+ 225 56 50 223 56 52 226 56 56 232 56 60
+ 237 55 60 239 53 57 220 59 54 192 56 41
+ 186 61 42 186 61 42 177 57 35 182 53 41
+ 255 80 96 253 61 95 203 73 93 75 64 49
+ 45 51 37 74 51 39 134 152 101 168 212 140
+ 143 170 124 75 99 57 96 127 61 108 148 73
+ 100 140 71 101 135 67 107 142 79 105 144 79
+ 102 143 69 112 155 80 64 62 48 62 61 52
+ 60 61 50 65 69 42 76 77 58 85 84 65
+ 101 99 103 132 129 183 145 140 212 127 122 175
+ 119 115 165 127 122 164 121 111 127 110 95 87
+ 108 89 71 104 92 75 106 94 78 127 95 79
+ 165 75 60 216 53 46 227 48 43 226 52 42
+ 215 56 36 202 61 36 215 57 44 185 59 41
+ 181 55 38 215 61 53 231 73 66 179 57 39
+ 186 58 41 199 57 45 214 60 52 227 59 55
+ 234 58 56 233 56 54 244 72 73 233 90 88
+ 205 67 61 218 58 55 223 57 50 228 56 52
+ 234 54 56 236 56 62 235 54 61 236 55 59
+ 214 63 55 182 59 43 167 59 39 164 59 40
+ 150 54 35 192 73 68 252 85 104 210 77 88
+ 130 93 79 51 57 34 70 79 41 117 156 95
+ 146 165 105 136 155 106 73 84 60 60 72 44
+ 103 126 67 106 148 70 97 140 69 107 140 75
+ 108 145 80 111 150 81 109 153 77 118 165 86
+ 85 77 62 86 77 63 86 78 63 86 80 61
+ 92 82 67 96 87 66 98 89 75 109 99 107
+ 119 106 124 112 100 109 93 87 91 87 85 82
+ 93 86 71 102 90 70 110 95 72 106 100 79
+ 136 90 79 173 82 71 174 58 44 203 52 43
+ 225 55 47 222 55 46 215 54 42 211 57 41
+ 213 58 44 184 60 43 167 53 34 194 57 45
+ 215 60 52 211 72 58 212 66 57 216 62 57
+ 231 60 60 238 54 56 229 59 56 197 61 50
+ 183 57 42 189 59 45 214 60 53 237 54 58
+ 232 54 58 230 56 54 229 57 50 230 57 54
+ 232 56 56 231 59 61 203 64 56 167 59 44
+ 153 59 40 141 56 36 132 54 39 204 89 90
+ 188 84 86 158 89 82 128 99 75 96 120 59
+ 157 182 113 118 152 89 79 93 59 59 61 46
+ 50 51 43 59 67 49 102 127 71 111 151 74
+ 106 146 77 109 147 82 106 148 71 113 158 75
+ 120 170 85 113 159 87 99 90 75 101 91 75
+ 101 91 75 100 91 76 101 91 77 103 95 74
+ 104 95 72 103 94 77 103 93 76 102 92 73
+ 96 90 71 81 78 61 76 72 55 83 80 62
+ 91 90 70 95 95 79 150 97 89 209 74 76
+ 211 52 48 183 61 41 205 58 42 218 57 43
+ 213 56 42 213 55 42 213 58 43 188 61 47
+ 151 53 30 170 63 41 193 55 42 209 57 47
+ 233 52 57 232 54 60 237 54 59 239 53 60
+ 214 54 52 173 56 38 167 57 38 181 58 41
+ 215 62 52 238 57 56 242 54 55 235 56 53
+ 229 60 51 224 62 57 218 62 62 201 64 59
+ 169 56 43 149 58 40 141 58 40 129 55 34
+ 126 58 42 166 82 74 149 84 73 143 92 83
+ 150 110 93 142 161 115 83 99 66 39 50 30
+ 53 56 49 55 54 47 57 57 48 57 67 48
+ 103 130 75 119 156 81 112 153 83 112 152 79
+ 111 153 73 120 166 85 119 166 89 96 139 74
+ 104 95 80 105 96 81 105 96 81 105 96 81
+ 104 95 80 107 98 84 106 98 83 105 96 80
+ 105 98 76 105 98 72 104 98 75 96 90 70
+ 76 74 54 64 69 52 64 72 56 67 74 62
+ 85 77 59 182 88 79 239 68 70 200 58 44
+ 195 55 37 210 56 41 209 58 41 209 58 40
+ 210 57 41 187 59 47 145 54 30 148 57 31
+ 187 56 42 218 59 53 238 64 69 211 62 59
+ 187 54 49 183 58 53 162 57 45 157 62 42
+ 159 65 43 165 60 39 183 54 41 211 60 53
+ 236 61 55 235 63 54 223 68 57 202 65 57
+ 178 56 51 152 56 42 140 56 39 132 60 41
+ 125 59 40 119 51 34 137 65 51 148 83 71
+ 145 90 78 150 89 83 137 89 77 65 77 43
+ 39 50 37 55 62 60 75 77 64 61 59 40
+ 55 58 47 56 64 45 104 130 75 118 157 80
+ 113 155 80 112 157 74 121 164 86 125 168 98
+ 98 140 73 96 136 76 105 96 81 105 96 81
+ 105 96 81 106 97 82 106 97 81 107 95 90
+ 107 95 95 107 97 86 107 97 84 107 97 88
+ 108 97 82 107 98 78 90 86 68 68 70 56
+ 60 67 53 53 67 49 63 67 41 150 90 70
+ 230 93 89 240 74 77 207 59 48 200 57 43
+ 206 60 48 210 61 49 212 62 50 206 64 58
+ 178 62 51 184 67 51 219 72 65 234 73 69
+ 209 69 65 160 61 47 142 70 50 132 67 49
+ 121 65 45 133 58 43 137 60 44 141 61 44
+ 150 56 42 163 58 46 185 59 48 192 63 49
+ 182 60 46 161 54 42 144 55 44 132 60 44
+ 127 59 42 123 59 44 115 57 42 118 53 40
+ 146 72 59 141 79 66 153 83 78 156 86 87
+ 145 111 95 102 118 73 71 86 52 94 107 81
+ 75 81 53 58 59 35 56 56 47 56 66 47
+ 105 131 76 119 157 80 112 156 78 114 162 80
+ 125 169 96 102 142 78 98 138 74 98 136 77
+ 105 96 81 105 96 81 104 95 80 108 99 84
+ 107 98 83 109 98 87 108 98 85 108 100 79
+ 108 100 80 108 98 86 109 98 85 109 99 84
+ 104 97 81 86 80 64 69 65 49 56 65 39
+ 132 75 64 192 62 64 216 78 79 247 105 109
+ 222 78 74 209 67 60 211 69 63 216 72 67
+ 222 73 70 228 71 75 224 76 75 231 73 72
+ 237 65 67 229 66 65 204 64 61 159 61 48
+ 138 65 50 133 60 49 129 58 51 127 59 50
+ 126 59 49 122 59 47 122 59 43 123 58 43
+ 134 56 44 143 56 44 148 56 40 137 58 42
+ 128 60 44 127 56 43 123 51 40 121 54 44
+ 112 52 41 118 61 49 133 81 64 137 84 71
+ 154 81 77 140 91 83 87 88 64 79 101 61
+ 96 118 70 67 87 45 54 64 42 58 60 50
+ 55 57 47 56 64 45 95 121 65 120 157 81
+ 112 158 81 119 168 89 106 149 83 92 132 71
+ 103 142 74 97 133 73 105 96 81 106 97 82
+ 108 98 84 106 97 82 106 97 82 107 98 83
+ 107 98 83 107 98 82 108 99 83 108 99 84
+ 112 98 82 112 97 85 102 95 82 102 97 80
+ 95 89 67 65 64 37 114 77 60 156 69 67
+ 174 66 67 193 79 78 203 76 76 210 67 66
+ 207 64 57 203 69 59 217 68 69 224 64 69
+ 225 67 69 226 68 67 227 65 62 226 66 62
+ 205 65 60 157 57 47 128 61 47 128 60 51
+ 136 56 50 133 59 47 129 59 46 127 58 45
+ 124 58 46 124 58 47 123 57 49 123 56 47
+ 124 57 46 122 58 46 120 57 47 117 56 46
+ 114 54 43 111 52 42 108 50 39 118 64 54
+ 136 84 76 148 81 77 147 85 77 121 101 79
+ 90 110 74 85 109 68 77 95 58 57 67 40
+ 56 57 44 59 61 51 52 59 48 56 57 41
+ 86 100 62 116 150 84 120 164 92 114 153 92
+ 90 130 67 95 135 73 101 141 76 92 128 71
+ 104 97 81 105 98 82 106 100 83 105 98 82
+ 105 98 82 106 98 83 107 98 83 107 98 83
+ 108 99 84 108 99 84 109 97 84 102 90 80
+ 115 112 105 163 160 152 180 175 165 125 123 106
+ 55 62 43 51 60 40 60 61 47 63 59 46
+ 94 66 53 165 72 69 213 65 69 217 62 60
+ 221 68 65 222 68 68 222 68 68 218 70 68
+ 213 70 63 212 70 61 216 68 62 176 61 52
+ 132 61 44 126 62 47 133 57 46 133 58 43
+ 129 58 43 127 58 44 126 58 47 126 58 48
+ 123 57 48 121 56 47 119 57 47 118 57 48
+ 116 58 46 113 54 45 110 51 43 107 52 41
+ 101 49 37 115 61 50 149 82 78 145 89 82
+ 127 95 82 95 92 72 69 83 59 50 63 41
+ 59 69 48 66 74 54 57 65 48 52 59 46
+ 52 57 53 55 56 44 76 87 51 114 149 83
+ 123 165 94 96 131 73 90 126 67 97 133 73
+ 97 133 75 88 124 71 104 98 82 105 98 82
+ 107 99 83 105 98 82 105 98 82 106 98 83
+ 107 98 83 108 99 84 108 99 84 107 98 82
+ 101 93 83 132 129 124 207 209 209 250 251 253
+ 255 255 255 244 221 213 160 145 124 67 74 50
+ 53 63 43 58 55 50 42 48 43 90 63 62
+ 205 127 127 206 88 85 222 57 58 225 64 68
+ 221 66 68 221 65 66 214 67 63 208 69 59
+ 221 66 58 191 66 56 141 59 44 127 61 44
+ 129 60 43 129 58 43 125 57 45 125 57 47
+ 125 58 48 124 58 49 119 58 51 115 56 47
+ 112 54 44 111 56 45 110 55 43 110 54 47
+ 107 52 44 103 51 42 96 46 36 112 56 47
+ 150 85 81 122 92 79 78 79 62 53 64 49
+ 47 53 44 51 51 48 46 51 43 52 62 49
+ 59 75 56 48 62 46 45 50 47 53 52 43
+ 65 77 47 115 149 89 110 152 84 84 117 63
+ 90 124 69 95 129 76 95 130 73 87 119 72
+ 104 99 83 104 99 83 104 99 83 104 99 83
+ 104 99 83 106 99 83 108 99 84 109 100 85
+ 109 100 85 108 98 81 108 106 101 188 195 197
+ 255 255 255 255 255 255 255 255 254 255 255 239
+ 234 243 204 157 167 127 75 79 49 61 54 41
+ 79 72 70 158 153 151 242 240 231 250 224 214
+ 214 113 113 193 61 58 202 64 60 212 64 64
+ 214 62 63 212 66 61 218 64 60 194 67 60
+ 146 59 49 129 61 47 126 60 44 127 58 46
+ 123 57 47 124 57 48 123 60 51 122 60 52
+ 112 59 49 107 56 45 105 55 45 104 56 45
+ 104 56 46 107 55 48 105 54 45 97 48 39
+ 89 43 31 109 61 52 118 84 78 71 64 51
+ 46 57 41 49 60 46 55 58 50 54 56 54
+ 50 56 48 45 57 42 54 68 50 57 72 54
+ 49 54 44 44 45 34 64 74 49 122 155 109
+ 94 134 77 81 111 60 86 115 66 92 121 71
+ 98 130 76 81 106 69 103 100 83 103 100 82
+ 103 100 82 103 100 82 102 100 82 105 99 82
+ 108 99 85 109 100 85 109 100 83 106 97 81
+ 100 100 100 167 179 185 239 251 252 250 255 252
+ 250 252 238 248 252 237 255 255 237 228 219 192
+ 114 110 87 65 74 60 150 151 142 243 230 229
+ 255 252 251 255 255 255 255 255 247 222 178 158
+ 172 79 65 181 56 48 205 65 60 205 66 61
+ 209 69 64 181 63 59 143 60 51 129 61 51
+ 126 60 49 126 58 46 124 57 47 124 57 48
+ 122 57 50 118 56 48 106 56 47 104 56 47
+ 102 55 44 101 55 45 101 55 44 105 54 48
+ 105 55 48 102 54 46 104 59 50 110 76 66
+ 56 56 51 49 52 44 51 55 45 53 54 43
+ 51 55 41 47 57 43 48 57 42 46 56 42
+ 47 56 44 56 65 50 59 67 50 48 49 36
+ 68 77 58 111 139 106 71 106 61 76 107 60
+ 76 105 59 87 117 70 98 129 78 67 86 59
+ 104 101 86 104 101 87 104 101 87 104 101 87
+ 104 101 87 105 101 86 107 100 90 110 101 87
+ 104 102 81 110 108 104 160 167 175 226 231 235
+ 255 255 255 255 255 252 248 251 241 248 250 243
+ 255 255 239 218 217 184 112 115 87 111 123 106
+ 200 205 201 255 254 252 255 255 253 253 255 254
+ 255 255 255 255 255 255 240 223 216 187 106 94
+ 176 56 43 196 64 54 199 72 57 168 69 54
+ 135 66 55 128 63 54 130 59 50 125 57 50
+ 120 56 47 117 55 46 115 55 46 111 53 43
+ 106 55 48 104 55 48 102 53 47 103 54 47
+ 105 55 48 108 55 49 108 60 47 103 70 52
+ 130 113 95 110 107 91 41 50 40 49 55 46
+ 48 55 45 49 54 42 48 53 44 47 51 45
+ 47 51 45 47 52 46 46 49 44 46 53 46
+ 50 63 52 51 64 51 64 77 58 73 88 64
+ 66 85 56 77 103 64 71 98 57 88 114 74
+ 93 120 84 52 68 53 104 101 86 104 101 86
+ 104 101 86 104 101 86 104 101 86 103 101 85
+ 107 100 91 110 100 88 103 104 80 125 128 126
+ 217 226 232 255 255 255 255 255 255 253 252 247
+ 229 232 222 227 234 215 240 241 217 211 210 183
+ 180 176 159 205 204 199 242 242 241 255 255 255
+ 255 255 253 254 254 252 254 254 252 255 253 255
+ 255 255 255 251 255 247 199 163 142 163 69 52
+ 189 57 46 182 60 57 152 58 59 127 64 61
+ 112 66 60 113 64 54 113 63 53 111 63 52
+ 106 60 50 104 58 49 113 54 50 109 53 49
+ 106 55 47 103 57 49 103 62 52 102 70 57
+ 99 74 53 95 77 53 127 127 105 81 89 70
+ 42 49 40 48 55 44 49 55 45 48 54 44
+ 47 51 44 45 50 45 46 51 45 45 50 44
+ 44 48 43 44 51 44 41 52 45 45 56 45
+ 50 62 45 50 62 42 54 67 46 68 86 59
+ 72 93 61 94 113 82 90 108 83 44 56 46
+ 104 101 86 104 101 86 104 101 86 105 102 87
+ 105 102 87 106 101 86 108 99 92 110 103 90
+ 104 105 81 108 117 112 195 205 213 254 255 255
+ 255 255 254 250 251 242 233 237 220 231 239 210
+ 234 232 206 221 212 199 239 224 225 255 250 255
+ 255 255 255 255 255 253 254 254 252 254 254 252
+ 254 254 252 255 253 250 249 255 255 250 255 255
+ 255 255 255 232 212 188 180 107 83 157 63 46
+ 145 54 42 127 56 44 111 65 51 114 61 55
+ 115 63 57 115 65 59 111 63 56 110 61 54
+ 113 57 52 108 58 51 100 61 50 94 62 50
+ 80 59 43 85 80 57 93 88 61 93 93 63
+ 110 118 92 50 64 43 50 55 47 50 56 46
+ 51 57 47 50 56 45 47 53 44 46 51 45
+ 46 51 45 44 49 43 42 47 41 43 48 43
+ 43 51 43 42 52 44 45 53 44 55 64 53
+ 57 67 52 51 62 44 62 74 52 92 104 84
+ 81 93 79 43 52 45 103 100 85 104 101 86
+ 105 102 87 105 102 87 105 102 87 106 101 86
+ 110 99 92 108 104 90 102 108 83 104 119 111
+ 186 198 205 251 254 255 255 255 253 255 255 242
+ 240 247 225 221 227 195 218 215 193 233 222 222
+ 255 245 250 255 253 255 255 255 252 254 254 252
+ 254 254 252 254 254 252 254 254 252 250 255 253
+ 255 253 255 255 248 255 255 254 254 255 255 255
+ 255 254 235 218 195 172 160 117 93 121 72 49
+ 101 54 34 101 51 41 106 57 48 108 63 52
+ 105 62 52 104 62 50 99 65 55 95 68 53
+ 89 71 53 101 93 71 69 70 47 57 67 39
+ 69 73 43 112 112 82 92 96 71 50 57 39
+ 55 61 53 55 61 51 55 62 52 56 62 51
+ 56 60 53 55 59 54 54 59 53 50 55 49
+ 46 51 45 44 49 43 40 46 40 42 46 42
+ 44 49 44 47 50 47 61 68 61 61 74 56
+ 49 63 40 66 80 60 69 80 68 47 57 48
+ 100 100 83 103 100 85 104 103 87 105 101 87
+ 104 102 87 107 101 86 110 100 92 108 104 90
+ 100 107 82 100 119 111 195 208 217 254 255 255
+ 255 255 252 255 255 242 242 247 224 209 210 182
+ 198 191 179 240 230 238 255 255 255 254 255 252
+ 254 255 250 254 254 252 254 254 252 254 254 252
+ 254 254 252 254 253 255 251 255 252 249 255 245
+ 253 255 250 255 254 255 255 255 255 255 255 255
+ 255 255 254 248 244 228 229 216 200 209 189 167
+ 104 83 59 88 68 44 93 75 50 92 76 52
+ 86 79 58 81 78 55 77 79 56 94 103 75
+ 64 76 48 61 69 42 71 74 43 105 103 74
+ 96 89 68 70 70 53 58 63 53 58 62 53
+ 56 62 52 57 63 53 57 64 56 59 65 59
+ 58 62 57 58 64 58 57 61 56 55 59 54
+ 48 54 50 44 49 44 43 47 46 41 45 46
+ 41 51 41 54 74 50 57 76 51 56 73 49
+ 59 75 56 47 59 46 92 103 79 95 105 82
+ 103 107 87 105 104 88 108 102 88 108 103 89
+ 107 102 91 104 103 89 101 108 89 124 138 134
+ 200 210 217 245 250 250 247 250 240 238 238 220
+ 221 218 198 201 192 174 201 190 182 233 224 230
+ 254 250 255 253 254 254 253 254 254 254 254 254
+ 255 254 252 255 253 251 255 253 249 255 252 252
+ 255 253 253 254 254 252 252 248 244 246 236 232
+ 254 250 251 254 255 253 253 255 255 255 255 252
+ 255 255 238 233 230 205 109 103 75 82 75 45
+ 85 79 50 83 79 51 80 78 52 76 79 54
+ 72 79 53 69 78 46 76 83 48 93 101 64
+ 97 101 70 86 86 61 87 84 60 85 82 57
+ 77 73 54 67 66 53 60 63 53 56 65 53
+ 56 67 53 57 65 55 57 65 54 58 66 55
+ 59 67 56 60 69 60 59 69 58 57 64 53
+ 53 61 54 54 68 47 71 96 53 71 98 60
+ 58 77 56 64 82 58 72 92 65 52 66 49
+
diff --git a/PerlMagick/t/input_p4.pbm b/PerlMagick/t/input_p4.pbm
new file mode 100644
index 0000000..c1cac18
--- /dev/null
+++ b/PerlMagick/t/input_p4.pbm
Binary files differ
diff --git a/PerlMagick/t/input_p5.pgm b/PerlMagick/t/input_p5.pgm
new file mode 100644
index 0000000..a21671b
--- /dev/null
+++ b/PerlMagick/t/input_p5.pgm
@@ -0,0 +1,4 @@
+P5
+70 46
+255
+/0344423221/.//..146:@CCDEQ[bjsvusla_^\XVTTUWYaf\@63320//./?ZuuOPwzW./123213330/.10001359>@?AENUZhruvtk__^[WUTTRUXcj]:65331/01-8PkqGF_mW,,//-.-.-..--//01125478:>CGIM^krtrc\][XTTSRQS[fle=643311110/5VyH97DOX----++++,,,,.-.-//.13668<@ABJT]grs^YYXUSQQPPV_g}_A40////11.-ds]ka....++*'*++)),---+,.36546:<<ERWYchZVUTSPNMMQY]o{V=0*..-./-+j^//0110.++*)))*--,,.1564235746GSVSZVURSRNLJMX\enW:***+,-,'^U2336642/1.+,,.000038::63476319FOOQTUQPOLIIPZ^my]9''*+*(%X~Q778:=<;88632233479;?@?:8899868BSYVRRMLMHosSXcx}a:+(-,1NkvyS89=?@BAAA>=<<8658<?CD@<;;;[`Vg`\`_^_^QLetu]ctlmzt_85@\{{{rY67<@BDDED?>>=:879=ACB?<<:T}aUe\`eXaipmnmahoktq{onruz{|GBwϱs_357<BFHHEJB<;998:=BC@=:9=dXS\YT\_`ecgijgcbu~{o\jtx{z||tЉ{0.38>DJIW~YC5228=AC;526P\YW`e_Z\e]dhjhbcfippfZ]ozz~~{j쿷8304:BLJdqLA:<@=CRON\[_\^fgdginghihcbbo}b\^gqrx~u@=626?IIZįgR:9M}|q]X\ahlgonhrthif_deeym]_fwjy~tIGA:7>FFP~h`uuhphbfjhdgicabktldhlik{sh`afamt|PONIC>@FHQqrmhnrkik\^fjha^`adjjghf`utxb`_^^cIRQOKIHJLSrpqperqldd_ekfhd_dob_`dcaelrsb^]\[ycPPPNNMNNNc|q`lquwqbich`^`ehllkjjg`cmol]`jecaraWYVj}۾OOOLNOPRPPXndeqvucXikl\badngeff_frjogjwgkd``yedf_\zw~p{NNMLNNOQQQQ^}srmvp]Vinzv^aiillijoqb\j}oc^YYpilll\wZrNNNOOOPRRQNbwqlfZ`eegzkfmnedbcveTF[asda\`uglkj_p|nPPPPPPOPO[fh{qigYihaghqjj}yebfonh`vwoqmlmqpckkj`i{]XxRRRRRRO]|ozlg]jecfmigm{mog~~eoqglskejljc^|{CVqOSTTTQ]{pⲂlg`n{_qocedekg|ijiflnkehjlkh^{p:Ds}v[UJNTXU`~l|ӻkwxlchgvviic^fhiyslolkkkkmkfhimjenz}\NAVwy||slcfAEPT`ywfrlX^ta\dgcihcee`yraghiegjkllkhfhilkcym4@5Snqx~zurqp59FMfoWegZ\xc_ceeagabcdicalljhinikkmiefeffjxE*0Vp|zttw-.7C]ab|_]]ptacfad`rdcabiinnhjooihlnpjdddbazxb5/GŁpwxww~/,0;NYr}d[]^e~qcfdg`acp`abacnpixsjikmnmk_``ZZzrB09Wnxu|}z=<;AKRdztc]^`gdeegedg_[jw[^bimnm|lijklomnk^YXQlvf5HNApw{NNOPSWZgpiYUV[acgl[`iheeg_Uaipmkommd]`imllllmoiZUOL|smijU;2?q~[\\\\___^]ZMGOX]psc_dheegaP\_eklmmfYX]konmnnmhXSQKMjfjxZ,668>tw`aaa`ccabaaZHBDGMswc_deee`NQ^juj]_WX[Y[hqqqi\SOOMEUeikfF-<K98;txuaaabbbcccccbUD?=?j|fbfhij_dsynYYTOOQSSX_d_UPPMLIG]`gkwlNdL87=u{wvaa`dcdddddddaP@;[ewymoruvxxusjYUQNNNLLLNQRPOLGIEM_bfiUZjL;:7;kq{sabcbbcccdddd`aX=V_bqrnjlqprsqqjVOOOPNMLLLKLLKIGEBOceghdaU=7;87[otzoabdbbcccddc\pz:7;;Icnlqrrrpop^PONONMMMLJJJJGDC?Lfig[L9@E=776Prmstkbbdbbccddc^E:7.G{jqqpnmofROONLLMMKIFGFFDB<HhcM;231:D803FelqqhccccccdeecjJ7JdillmnhTPNMLLNNJFEEEFD>7J]A478754>A3+Dt`ekr^ccccccdeebdmFi\jknbTPNMLLLJFEDDDEECGU725444534=?/HZ\[grMddddddefdlouZflaUQOMJIHEEECDEFINtj.443211202:;GQL[Ufl>ddddddefeϯ__`VRONMLIGGEEFINOP|T.4431010.00388=NShd3dddeeeehfr~YPLMLNOMKIHGF?OVZq95565211/-.002<>9DbX1cdeeeeehgrTBAGKJIJJJ]C=Dm\5::;;:9951/,,/1AD8JK5bceeeefhfpWGNNOLLaE@FdYD<<;<=?<>;94/.,/ACAD6achffgffhfJMMLKJHM^`SRPHA==>==>?AA=:=TVEJS< \ No newline at end of file
diff --git a/PerlMagick/t/input_p6.ppm b/PerlMagick/t/input_p6.ppm
new file mode 100644
index 0000000..920fe6c
--- /dev/null
+++ b/PerlMagick/t/input_p6.ppm
@@ -0,0 +1,4 @@
+P6
+70 46
+255
+0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/input_p7.p7 b/PerlMagick/t/input_p7.p7
new file mode 100644
index 0000000..3c3a1eb
--- /dev/null
+++ b/PerlMagick/t/input_p7.p7
Binary files differ
diff --git a/PerlMagick/t/input_rgb.cin b/PerlMagick/t/input_rgb.cin
new file mode 100644
index 0000000..1483f53
--- /dev/null
+++ b/PerlMagick/t/input_rgb.cin
Binary files differ
diff --git a/PerlMagick/t/input_rgb.rla b/PerlMagick/t/input_rgb.rla
new file mode 100644
index 0000000..38f3374
--- /dev/null
+++ b/PerlMagick/t/input_rgb.rla
Binary files differ
diff --git a/PerlMagick/t/input_rgb.txt b/PerlMagick/t/input_rgb.txt
new file mode 100644
index 0000000..b11006a
--- /dev/null
+++ b/PerlMagick/t/input_rgb.txt
@@ -0,0 +1,240 @@
+0,0: (255,255,255) #FFFFFF
+1,0: (255,255,255) #FFFFFF
+2,0: (255,255,255) #FFFFFF
+3,0: (255,255,255) #FFFFFF
+4,0: (255,255,255) #FFFFFF
+5,0: (255,255,255) #FFFFFF
+6,0: ( 0, 0, 0) #000000
+7,0: ( 0, 0, 0) #000000
+8,0: ( 0, 0, 0) #000000
+9,0: ( 0, 0, 0) #000000
+10,0: (255,255,255) #FFFFFF
+11,0: (255,255,255) #FFFFFF
+12,0: (255,255,255) #FFFFFF
+13,0: (255,255,255) #FFFFFF
+14,0: (255,255,255) #FFFFFF
+0,1: (255,255,255) #FFFFFF
+1,1: (255,255,255) #FFFFFF
+2,1: (255,255,255) #FFFFFF
+3,1: (255,255,255) #FFFFFF
+4,1: (255,255,255) #FFFFFF
+5,1: (255,255,255) #FFFFFF
+6,1: (255,255,255) #FFFFFF
+7,1: (255,255, 0) #FFFF00
+8,1: (255,255, 0) #FFFF00
+9,1: (255,255,255) #FFFFFF
+10,1: (255,255,255) #FFFFFF
+11,1: (255,255,255) #FFFFFF
+12,1: (255,255,255) #FFFFFF
+13,1: (255,255,255) #FFFFFF
+14,1: (255,255,255) #FFFFFF
+0,2: (255,255,255) #FFFFFF
+1,2: (255,255,255) #FFFFFF
+2,2: (255,255,255) #FFFFFF
+3,2: (255,255,255) #FFFFFF
+4,2: (255,255,255) #FFFFFF
+5,2: ( 0, 0, 0) #000000
+6,2: (255,255, 0) #FFFF00
+7,2: (255,255, 0) #FFFF00
+8,2: (255,255, 0) #FFFF00
+9,2: (255,255, 0) #FFFF00
+10,2: ( 0, 0, 0) #000000
+11,2: (255,255,255) #FFFFFF
+12,2: (255,255,255) #FFFFFF
+13,2: (255,255,255) #FFFFFF
+14,2: (255,255,255) #FFFFFF
+0,3: (255,255,255) #FFFFFF
+1,3: (255,255,255) #FFFFFF
+2,3: (255,255,255) #FFFFFF
+3,3: (255,255,255) #FFFFFF
+4,3: (255,255,255) #FFFFFF
+5,3: ( 0,255,255) #00FFFF
+6,3: (255,255, 0) #FFFF00
+7,3: (255,255, 0) #FFFF00
+8,3: (255,255, 0) #FFFF00
+9,3: (255,255, 0) #FFFF00
+10,3: ( 0,255,255) #00FFFF
+11,3: (255,255,255) #FFFFFF
+12,3: (255,255,255) #FFFFFF
+13,3: (255,255,255) #FFFFFF
+14,3: (255,255,255) #FFFFFF
+0,4: (255,255,255) #FFFFFF
+1,4: (255,255,255) #FFFFFF
+2,4: (255,255,255) #FFFFFF
+3,4: (255,255,255) #FFFFFF
+4,4: ( 0,255,255) #00FFFF
+5,4: ( 0,255,255) #00FFFF
+6,4: ( 0, 0, 0) #000000
+7,4: (255,255, 0) #FFFF00
+8,4: (255,255, 0) #FFFF00
+9,4: ( 0, 0, 0) #000000
+10,4: ( 0,255,255) #00FFFF
+11,4: ( 0,255,255) #00FFFF
+12,4: (255,255,255) #FFFFFF
+13,4: (255,255,255) #FFFFFF
+14,4: (255,255,255) #FFFFFF
+0,5: (255,255,255) #FFFFFF
+1,5: (255,255,255) #FFFFFF
+2,5: (255,255,255) #FFFFFF
+3,5: ( 0,255,255) #00FFFF
+4,5: ( 0,255,255) #00FFFF
+5,5: (192,192,192) #C0C0C0
+6,5: ( 0, 0,128) #000080
+7,5: (255,255, 0) #FFFF00
+8,5: (255,255, 0) #FFFF00
+9,5: ( 0, 0,128) #000080
+10,5: (192,192,192) #C0C0C0
+11,5: ( 0,255,255) #00FFFF
+12,5: ( 0,255,255) #00FFFF
+13,5: (255,255,255) #FFFFFF
+14,5: (255,255,255) #FFFFFF
+0,6: (255,255,255) #FFFFFF
+1,6: (255,255,255) #FFFFFF
+2,6: (255,255,255) #FFFFFF
+3,6: ( 0,255,255) #00FFFF
+4,6: (192,192,192) #C0C0C0
+5,6: ( 0, 0,128) #000080
+6,6: ( 0, 0,128) #000080
+7,6: (255,255,255) #FFFFFF
+8,6: (255,255,255) #FFFFFF
+9,6: ( 0, 0,128) #000080
+10,6: ( 0, 0,128) #000080
+11,6: (192,192,192) #C0C0C0
+12,6: ( 0,255,255) #00FFFF
+13,6: (255,255,255) #FFFFFF
+14,6: (255,255,255) #FFFFFF
+0,7: (255,255,255) #FFFFFF
+1,7: (255,255,255) #FFFFFF
+2,7: (255,255,255) #FFFFFF
+3,7: ( 0,255,255) #00FFFF
+4,7: (192,192,192) #C0C0C0
+5,7: ( 0, 0, 0) #000000
+6,7: ( 0, 0, 0) #000000
+7,7: (255,255, 0) #FFFF00
+8,7: (255,255, 0) #FFFF00
+9,7: ( 0, 0, 0) #000000
+10,7: ( 0, 0, 0) #000000
+11,7: (192,192,192) #C0C0C0
+12,7: ( 0,255,255) #00FFFF
+13,7: (255,255,255) #FFFFFF
+14,7: (255,255,255) #FFFFFF
+0,8: (255,255,255) #FFFFFF
+1,8: (255,255,255) #FFFFFF
+2,8: ( 0, 0, 0) #000000
+3,8: (255,255,255) #FFFFFF
+4,8: (255,255,255) #FFFFFF
+5,8: (255,255, 0) #FFFF00
+6,8: ( 0, 0, 0) #000000
+7,8: (255,255, 0) #FFFF00
+8,8: (255,255, 0) #FFFF00
+9,8: ( 0, 0, 0) #000000
+10,8: (255,255, 0) #FFFF00
+11,8: (255,255,255) #FFFFFF
+12,8: (255,255,255) #FFFFFF
+13,8: ( 0, 0, 0) #000000
+14,8: (255,255,255) #FFFFFF
+0,9: ( 0, 0, 0) #000000
+1,9: (255,255,255) #FFFFFF
+2,9: (255,255, 0) #FFFF00
+3,9: (255,255, 0) #FFFF00
+4,9: (255,255, 0) #FFFF00
+5,9: (255,255, 0) #FFFF00
+6,9: (128,128, 0) #808000
+7,9: ( 0, 0, 0) #000000
+8,9: ( 0, 0, 0) #000000
+9,9: (128,128, 0) #808000
+10,9: (255,255, 0) #FFFF00
+11,9: (255,255, 0) #FFFF00
+12,9: (255,255, 0) #FFFF00
+13,9: (255,255, 0) #FFFF00
+14,9: (255,255,255) #FFFFFF
+0,10: ( 0, 0, 0) #000000
+1,10: (255,255, 0) #FFFF00
+2,10: (255,255, 0) #FFFF00
+3,10: (255,255, 0) #FFFF00
+4,10: (255,255, 0) #FFFF00
+5,10: (255,255, 0) #FFFF00
+6,10: ( 0, 0, 0) #000000
+7,10: (192,192,192) #C0C0C0
+8,10: ( 0, 0,128) #000080
+9,10: ( 0, 0, 0) #000000
+10,10: (255,255, 0) #FFFF00
+11,10: (255,255, 0) #FFFF00
+12,10: (255,255, 0) #FFFF00
+13,10: (255,255, 0) #FFFF00
+14,10: (255,255, 0) #FFFF00
+0,11: (255,255,255) #FFFFFF
+1,11: (255,255, 0) #FFFF00
+2,11: (255,255, 0) #FFFF00
+3,11: (255,255, 0) #FFFF00
+4,11: (255,255, 0) #FFFF00
+5,11: (255,255, 0) #FFFF00
+6,11: (192,192,192) #C0C0C0
+7,11: (192,192,192) #C0C0C0
+8,11: (192,192,192) #C0C0C0
+9,11: (192,192,192) #C0C0C0
+10,11: (255,255, 0) #FFFF00
+11,11: (255,255, 0) #FFFF00
+12,11: (255,255, 0) #FFFF00
+13,11: (255,255, 0) #FFFF00
+14,11: (255,255, 0) #FFFF00
+0,12: (255,255,255) #FFFFFF
+1,12: ( 0, 0, 0) #000000
+2,12: (255,255, 0) #FFFF00
+3,12: (255,255, 0) #FFFF00
+4,12: (255,255, 0) #FFFF00
+5,12: (192,192,192) #C0C0C0
+6,12: (192,192,192) #C0C0C0
+7,12: (192,192,192) #C0C0C0
+8,12: ( 0,255,255) #00FFFF
+9,12: ( 0,255,255) #00FFFF
+10,12: ( 0,255,255) #00FFFF
+11,12: (255,255, 0) #FFFF00
+12,12: (255,255, 0) #FFFF00
+13,12: (255,255, 0) #FFFF00
+14,12: ( 0, 0, 0) #000000
+0,13: (255,255,255) #FFFFFF
+1,13: (255,255,255) #FFFFFF
+2,13: ( 0, 0, 0) #000000
+3,13: (255,255, 0) #FFFF00
+4,13: ( 0, 0, 0) #000000
+5,13: (192,192,192) #C0C0C0
+6,13: (192,192,192) #C0C0C0
+7,13: (192,192,192) #C0C0C0
+8,13: ( 0,255,255) #00FFFF
+9,13: (255,255,255) #FFFFFF
+10,13: (255,255,255) #FFFFFF
+11,13: ( 0, 0, 0) #000000
+12,13: (255,255, 0) #FFFF00
+13,13: ( 0, 0, 0) #000000
+14,13: (255,255,255) #FFFFFF
+0,14: (255,255,255) #FFFFFF
+1,14: (255,255,255) #FFFFFF
+2,14: (255,255,255) #FFFFFF
+3,14: ( 0, 0, 0) #000000
+4,14: (255,255,255) #FFFFFF
+5,14: (192,192,192) #C0C0C0
+6,14: (192,192,192) #C0C0C0
+7,14: (192,192,192) #C0C0C0
+8,14: (255,255,255) #FFFFFF
+9,14: (255,255,255) #FFFFFF
+10,14: (255,255,255) #FFFFFF
+11,14: (255,255,255) #FFFFFF
+12,14: ( 0, 0, 0) #000000
+13,14: (255,255,255) #FFFFFF
+14,14: (255,255,255) #FFFFFF
+0,15: (255,255,255) #FFFFFF
+1,15: (255,255,255) #FFFFFF
+2,15: (255,255,255) #FFFFFF
+3,15: (255,255,255) #FFFFFF
+4,15: (255,255,255) #FFFFFF
+5,15: (255,255,255) #FFFFFF
+6,15: (255,255,255) #FFFFFF
+7,15: (255,255,255) #FFFFFF
+8,15: (255,255,255) #FFFFFF
+9,15: (255,255,255) #FFFFFF
+10,15: (255,255,255) #FFFFFF
+11,15: (255,255,255) #FFFFFF
+12,15: (255,255,255) #FFFFFF
+13,15: (255,255,255) #FFFFFF
+14,15: (255,255,255) #FFFFFF
diff --git a/PerlMagick/t/input_rgb_08bit.palm b/PerlMagick/t/input_rgb_08bit.palm
new file mode 100644
index 0000000..d9fcbab
--- /dev/null
+++ b/PerlMagick/t/input_rgb_08bit.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_08bit_cmap.palm b/PerlMagick/t/input_rgb_08bit_cmap.palm
new file mode 100644
index 0000000..c938cb9
--- /dev/null
+++ b/PerlMagick/t/input_rgb_08bit_cmap.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_08bit_rle.palm b/PerlMagick/t/input_rgb_08bit_rle.palm
new file mode 100644
index 0000000..3a3d628
--- /dev/null
+++ b/PerlMagick/t/input_rgb_08bit_rle.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_08bit_scan.palm b/PerlMagick/t/input_rgb_08bit_scan.palm
new file mode 100644
index 0000000..205099f
--- /dev/null
+++ b/PerlMagick/t/input_rgb_08bit_scan.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_08bit_trans.palm b/PerlMagick/t/input_rgb_08bit_trans.palm
new file mode 100644
index 0000000..e32dc9c
--- /dev/null
+++ b/PerlMagick/t/input_rgb_08bit_trans.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_16bit.palm b/PerlMagick/t/input_rgb_16bit.palm
new file mode 100644
index 0000000..c9e75d7
--- /dev/null
+++ b/PerlMagick/t/input_rgb_16bit.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_16bit_rle.palm b/PerlMagick/t/input_rgb_16bit_rle.palm
new file mode 100644
index 0000000..60416c9
--- /dev/null
+++ b/PerlMagick/t/input_rgb_16bit_rle.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_16bit_scan.palm b/PerlMagick/t/input_rgb_16bit_scan.palm
new file mode 100644
index 0000000..57b8d5b
--- /dev/null
+++ b/PerlMagick/t/input_rgb_16bit_scan.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_16bit_trans.palm b/PerlMagick/t/input_rgb_16bit_trans.palm
new file mode 100644
index 0000000..3e9c24f
--- /dev/null
+++ b/PerlMagick/t/input_rgb_16bit_trans.palm
Binary files differ
diff --git a/PerlMagick/t/input_rgb_lsb_08bit.mat b/PerlMagick/t/input_rgb_lsb_08bit.mat
new file mode 100644
index 0000000..03d9a02
--- /dev/null
+++ b/PerlMagick/t/input_rgb_lsb_08bit.mat
Binary files differ
diff --git a/PerlMagick/t/jbig/input.jbig b/PerlMagick/t/jbig/input.jbig
new file mode 100644
index 0000000..b9252b3
--- /dev/null
+++ b/PerlMagick/t/jbig/input.jbig
Binary files differ
diff --git a/PerlMagick/t/jbig/read.t b/PerlMagick/t/jbig/read.t
new file mode 100644
index 0000000..9b12a11
--- /dev/null
+++ b/PerlMagick/t/jbig/read.t
@@ -0,0 +1,25 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test read image method on JBIG image
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/jbig' || die 'Cd failed';
+
+testRead( 'input.jbig',
+ 'cfa3fbe44a1f62cee0d91a5263be1e30ba9a45d35b029826a405fde94d0bc435');
diff --git a/PerlMagick/t/jbig/write.t b/PerlMagick/t/jbig/write.t
new file mode 100644
index 0000000..cbca7ee
--- /dev/null
+++ b/PerlMagick/t/jbig/write.t
@@ -0,0 +1,30 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test write image method on JBIG image
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not \n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/jbig' || die 'Cd failed';
+
+testReadWrite( 'input.jbig',
+ 'output.jbig',
+ '',
+ 'cfa3fbe44a1f62cee0d91a5263be1e30ba9a45d35b029826a405fde94d0bc435' );
+
+$test=0; # Keep perl from complaining
diff --git a/PerlMagick/t/jng/input_gray.jng b/PerlMagick/t/jng/input_gray.jng
new file mode 100644
index 0000000..6267b96
--- /dev/null
+++ b/PerlMagick/t/jng/input_gray.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_gray_idat.jng b/PerlMagick/t/jng/input_gray_idat.jng
new file mode 100644
index 0000000..1376669
--- /dev/null
+++ b/PerlMagick/t/jng/input_gray_idat.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_gray_jdaa.jng b/PerlMagick/t/jng/input_gray_jdaa.jng
new file mode 100644
index 0000000..66e9223
--- /dev/null
+++ b/PerlMagick/t/jng/input_gray_jdaa.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_gray_prog.jng b/PerlMagick/t/jng/input_gray_prog.jng
new file mode 100644
index 0000000..def56e5
--- /dev/null
+++ b/PerlMagick/t/jng/input_gray_prog.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_gray_prog_idat.jng b/PerlMagick/t/jng/input_gray_prog_idat.jng
new file mode 100644
index 0000000..634a009
--- /dev/null
+++ b/PerlMagick/t/jng/input_gray_prog_idat.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_gray_prog_jdaa.jng b/PerlMagick/t/jng/input_gray_prog_jdaa.jng
new file mode 100644
index 0000000..75ba3f6
--- /dev/null
+++ b/PerlMagick/t/jng/input_gray_prog_jdaa.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_idat.jng b/PerlMagick/t/jng/input_idat.jng
new file mode 100644
index 0000000..2b037b9
--- /dev/null
+++ b/PerlMagick/t/jng/input_idat.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_jdaa.jng b/PerlMagick/t/jng/input_jdaa.jng
new file mode 100644
index 0000000..deffc4c
--- /dev/null
+++ b/PerlMagick/t/jng/input_jdaa.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_prog.jng b/PerlMagick/t/jng/input_prog.jng
new file mode 100644
index 0000000..afe6ab3
--- /dev/null
+++ b/PerlMagick/t/jng/input_prog.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_prog_idat.jng b/PerlMagick/t/jng/input_prog_idat.jng
new file mode 100644
index 0000000..d3790de
--- /dev/null
+++ b/PerlMagick/t/jng/input_prog_idat.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_prog_jdaa.jng b/PerlMagick/t/jng/input_prog_jdaa.jng
new file mode 100644
index 0000000..ddaeebd
--- /dev/null
+++ b/PerlMagick/t/jng/input_prog_jdaa.jng
Binary files differ
diff --git a/PerlMagick/t/jng/input_rose.jng b/PerlMagick/t/jng/input_rose.jng
new file mode 100644
index 0000000..518aeb7
--- /dev/null
+++ b/PerlMagick/t/jng/input_rose.jng
Binary files differ
diff --git a/PerlMagick/t/jng/read.t b/PerlMagick/t/jng/read.t
new file mode 100644
index 0000000..322ce8a
--- /dev/null
+++ b/PerlMagick/t/jng/read.t
@@ -0,0 +1,75 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test read image method on non-interlaced JPEG.
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..11\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/jng' || die 'Cd failed';
+
+#
+# 1) Gray
+#
+testReadCompare('input_gray.jng', '../reference/jng/read_gray.miff', q//, 0, 0);
+#
+# 2) Gray with IDAT encoding
+#
+++$test;
+testReadCompare('input_gray_idat.jng', '../reference/jng/read_gray_idat.miff', q//, 0, 0);
+#
+# 3) Gray with JDAA encoding
+#
+++$test;
+testReadCompare('input_gray_jdaa.jng', '../reference/jng/read_gray_jdaa.miff', q//, 0, 0);
+#
+# 4) Gray Progressive
+#
+++$test;
+testReadCompare('input_gray_prog.jng', '../reference/jng/read_gray_prog.miff', q//, 0, 0);
+#
+# 5) Gray progressive with IDAT encoding
+#
+++$test;
+testReadCompare('input_gray_prog_idat.jng', '../reference/jng/read_gray_prog_idat.miff', q//, 0, 0);
+#
+# 6) Gray progressive with JDAA encoding
+#
+++$test;
+testReadCompare('input_gray_prog_jdaa.jng', '../reference/jng/read_gray_prog_jdaa.miff', q//, 0, 0);
+#
+# 7) Color with JDAA encoding
+#
+++$test;
+testReadCompare('input_idat.jng', '../reference/jng/read_idat.miff', q//, 0.009, 0.13);
+#
+# 8) Color with JDAA encoding
+#
+++$test;
+testReadCompare('input_jdaa.jng', '../reference/jng/read_jdaa.miff', q//, 0.009, 0.13);
+#
+# 9) Color progressive
+#
+++$test;
+testReadCompare('input_prog.jng', '../reference/jng/read_prog.miff', q//, 0.009, 0.13);
+#
+# 10) Color progressive with IDAT encoding
+#
+++$test;
+testReadCompare('input_prog_idat.jng', '../reference/jng/read_prog_idat.miff', q//, 0.009, 0.13);
+#
+# 11) Color progressive with JDAA encoding
+#
+++$test;
+testReadCompare('input_prog_jdaa.jng', '../reference/jng/read_prog_jdaa.miff', q//, 0.009, 0.13);
diff --git a/PerlMagick/t/jng/write.t b/PerlMagick/t/jng/write.t
new file mode 100644
index 0000000..7fe983d
--- /dev/null
+++ b/PerlMagick/t/jng/write.t
@@ -0,0 +1,55 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003-2009 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading JPEG images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..11\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/jng' || die 'Cd failed';
+
+# 1
+testReadWriteCompare( 'input_gray_idat.jng', 'gray_idat_tmp.jng', '../reference/jng/write_gray_idat.miff', q//, q//, 1.0e-04, 0.008);
+++$test;
+# 2
+testReadWriteCompare( 'input_gray_jdaa.jng', 'gray_jdaa_tmp.jng', '../reference/jng/write_gray_jdaa.miff', q//, q//, 1.0e-04, 0.008);
+++$test;
+# 3
+testReadWriteCompare( 'input_gray.jng', 'gray_tmp.jng', '../reference/jng/write_gray.miff', q//, q//, 1.0e-04, 0.008);
+++$test;
+# 4
+testReadWriteCompare( 'input_gray_prog_idat.jng', 'gray_prog_idat_tmp.jng', '../reference/jng/write_gray_prog_idat.miff', q//, q//, 1.0e-04, 0.008);
+++$test;
+# 5
+testReadWriteCompare( 'input_gray_prog_jdaa.jng', 'gray_prog_jdaa_tmp.jng', '../reference/jng/write_gray_prog_jdaa.miff', q//, q//, 1.0e-04, 0.008);
+++$test;
+# 6
+testReadWriteCompare( 'input_gray_prog.jng', 'gray_prog_tmp.jng', '../reference/jng/write_gray_prog.miff', q//, q//, 0.012, 0.145);
+++$test;
+# 7
+testReadWriteCompare( 'input_idat.jng', 'idat_tmp.jng', '../reference/jng/write_idat.miff', q//, q//, 0.012, 0.145);
+++$test;
+# 8
+testReadWriteCompare( 'input_jdaa.jng', 'jdaa_tmp.jng', '../reference/jng/write_jdaa.miff', q//, q//, 0.012, 0.145);
+++$test;
+# 9
+testReadWriteCompare( 'input_prog_idat.jng', 'prog_idat_tmp.jng', '../reference/jng/write_prog_idat.miff', q//, q//, 0.012, 0.145);
+++$test;
+# 10
+testReadWriteCompare( 'input_prog_jdaa.jng', 'prog_jdaa_tmp.jng', '../reference/jng/write_prog_jdaa.miff', q//, q//, 0.012, 0.145);
+++$test;
+# 11
+testReadWriteCompare( 'input_prog.jng', 'prog_tmp.jng', '../reference/jng/write_prog.miff', q//, q//, 0.012, 0.145);
+
diff --git a/PerlMagick/t/jp2/input.jp2 b/PerlMagick/t/jp2/input.jp2
new file mode 100644
index 0000000..383586e
--- /dev/null
+++ b/PerlMagick/t/jp2/input.jp2
Binary files differ
diff --git a/PerlMagick/t/jp2/input.jpc b/PerlMagick/t/jp2/input.jpc
new file mode 100644
index 0000000..383586e
--- /dev/null
+++ b/PerlMagick/t/jp2/input.jpc
Binary files differ
diff --git a/PerlMagick/t/jp2/input.pgx b/PerlMagick/t/jp2/input.pgx
new file mode 100644
index 0000000..d94a1fc
--- /dev/null
+++ b/PerlMagick/t/jp2/input.pgx
@@ -0,0 +1,2 @@
+PG ML + 8 70 46
+/0344423221/.//..146:@CCDEQ[bjsvusla_^\XVTTUWYaf\@63320//./?ZuuOPwzW./123213330/.10001359>@?AENUZhruvtk__^[WUTTRUXcj]:65331/01-8PkqGF_mW,,//-.-.-..--//01125478:>CGIM^krtrc\][XTTSRQS[fle=643311110/5VyH97DOX----++++,,,,.-.-//.13668<@ABJT]grs^YYXUSQQPPV_g}_A40////11.-ds]ka....++*'*++)),---+,.36546:<<ERWYchZVUTSPNMMQY]o{V=0*..-./-+j^//0110.++*)))*--,,.1564235746GSVSZVURSRNLJMX\enW:***+,-,'^U2336642/1.+,,.000038::63476319FOOQTUQPOLIIPZ^my]9''*+*(%X~Q778:=<;88632233479;?@?:8899868BSYVRRMLMHosSXcx}a:+(-,1NkvyS89=?@BAAA>=<<8658<?CD@<;;;[`Vg`\`_^_^QLetu]ctlmzt_85@\{{{rY67<@BDDED?>>=:879=ACB?<<:T}aUe\`eXaipmnmahoktq{onruz{|GBwϱs_357<BFHHEJB<;998:=BC@=:9=dXS\YT\_`ecgijgcbu~{o\jtx{z||tЉ{0.38>DJIW~YC5228=AC;526P\YW`e_Z\e]dhjhbcfippfZ]ozz~~{j쿷8304:BLJdqLA:<@=CRON\[_\^fgdginghihcbbo}b\^gqrx~u@=626?IIZįgR:9M}|q]X\ahlgonhrthif_deeym]_fwjy~tIGA:7>FFP~h`uuhphbfjhdgicabktldhlik{sh`afamt|PONIC>@FHQqrmhnrkik\^fjha^`adjjghf`utxb`_^^cIRQOKIHJLSrpqperqldd_ekfhd_dob_`dcaelrsb^]\[ycPPPNNMNNNc|q`lquwqbich`^`ehllkjjg`cmol]`jecaraWYVj}۾OOOLNOPRPPXndeqvucXikl\badngeff_frjogjwgkd``yedf_\zw~p{NNMLNNOQQQQ^}srmvp]Vinzv^aiillijoqb\j}oc^YYpilll\wZrNNNOOOPRRQNbwqlfZ`eegzkfmnedbcveTF[asda\`uglkj_p|nPPPPPPOPO[fh{qigYihaghqjj}yebfonh`vwoqmlmqpckkj`i{]XxRRRRRRO]|ozlg]jecfmigm{mog~~eoqglskejljc^|{CVqOSTTTQ]{pⲂlg`n{_qocedekg|ijiflnkehjlkh^{p:Ds}v[UJNTXU`~l|ӻkwxlchgvviic^fhiyslolkkkkmkfhimjenz}\NAVwy||slcfAEPT`ywfrlX^ta\dgcihcee`yraghiegjkllkhfhilkcym4@5Snqx~zurqp59FMfoWegZ\xc_ceeagabcdicalljhinikkmiefeffjxE*0Vp|zttw-.7C]ab|_]]ptacfad`rdcabiinnhjooihlnpjdddbazxb5/GŁpwxww~/,0;NYr}d[]^e~qcfdg`acp`abacnpixsjikmnmk_``ZZzrB09Wnxu|}z=<;AKRdztc]^`gdeegedg_[jw[^bimnm|lijklomnk^YXQlvf5HNApw{NNOPSWZgpiYUV[acgl[`iheeg_Uaipmkommd]`imllllmoiZUOL|smijU;2?q~[\\\\___^]ZMGOX]psc_dheegaP\_eklmmfYX]konmnnmhXSQKMjfjxZ,668>tw`aaa`ccabaaZHBDGMswc_deee`NQ^juj]_WX[Y[hqqqi\SOOMEUeikfF-<K98;txuaaabbbcccccbUD?=?j|fbfhij_dsynYYTOOQSSX_d_UPPMLIG]`gkwlNdL87=u{wvaa`dcdddddddaP@;[ewymoruvxxusjYUQNNNLLLNQRPOLGIEM_bfiUZjL;:7;kq{sabcbbcccdddd`aX=V_bqrnjlqprsqqjVOOOPNMLLLKLLKIGEBOceghdaU=7;87[otzoabdbbcccddc\pz:7;;Icnlqrrrpop^PONONMMMLJJJJGDC?Lfig[L9@E=776Prmstkbbdbbccddc^E:7.G{jqqpnmofROONLLMMKIFGFFDB<HhcM;231:D803FelqqhccccccdeecjJ7JdillmnhTPNMLLNNJFEEEFD>7J]A478754>A3+Dt`ekr^ccccccdeebdmFi\jknbTPNMLLLJFEDDDEECGU725444534=?/HZ\[grMddddddefdlouZflaUQOMJIHEEECDEFINtj.443211202:;GQL[Ufl>ddddddefeϯ__`VRONMLIGGEEFINOP|T.4431010.00388=NShd3dddeeeehfr~YPLMLNOMKIHGF?OVZq95565211/-.002<>9DbX1cdeeeeehgrTBAGKJIJJJ]C=Dm\5::;;:9951/,,/1AD8JK5bceeeefhfpWGNNOLLaE@FdYD<<;<=?<>;94/.,/ACAD6achffgffhfJMMLKJHM^`SRPHA==>==>?AA=:=TVEJS< \ No newline at end of file
diff --git a/PerlMagick/t/jp2/read.t b/PerlMagick/t/jp2/read.t
new file mode 100644
index 0000000..159b4e7
--- /dev/null
+++ b/PerlMagick/t/jp2/read.t
@@ -0,0 +1,40 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test read image method on non-interlaced JPEG.
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..3\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/jp2' || die 'Cd failed';
+
+#
+# 1) JPEG-2000 JP2 File Format Syntax (ISO/IEC 15444-1)
+#
+print( "JPEG-2000 JP2 File Format Syntax ...\n" );
+testReadCompare('input.jp2', '../reference/jp2/read_jp2.miff', q//, 0, 0);
+
+#
+# 2) JPEG-2000 Code Stream Syntax (ISO/IEC 15444-1)
+#
+++$test;
+print( " ...\n" );
+testReadCompare('input.jpc', '../reference/jp2/read_jpc.miff', q//, 0, 0);
+
+#
+# 3) JPEG-2000 VM Format
+#
+++$test;
+print( " ...\n" );
+testReadCompare('input.pgx', '../reference/jp2/read_pgx.miff', q//, 0, 0);
diff --git a/PerlMagick/t/jpeg/input.jpg b/PerlMagick/t/jpeg/input.jpg
new file mode 100644
index 0000000..e8fdb0b
--- /dev/null
+++ b/PerlMagick/t/jpeg/input.jpg
Binary files differ
diff --git a/PerlMagick/t/jpeg/input.sfw b/PerlMagick/t/jpeg/input.sfw
new file mode 100644
index 0000000..4ae666d
--- /dev/null
+++ b/PerlMagick/t/jpeg/input.sfw
Binary files differ
diff --git a/PerlMagick/t/jpeg/input_plane.jpg b/PerlMagick/t/jpeg/input_plane.jpg
new file mode 100644
index 0000000..f8aaa5c
--- /dev/null
+++ b/PerlMagick/t/jpeg/input_plane.jpg
Binary files differ
diff --git a/PerlMagick/t/jpeg/read.t b/PerlMagick/t/jpeg/read.t
new file mode 100644
index 0000000..3a21fe3
--- /dev/null
+++ b/PerlMagick/t/jpeg/read.t
@@ -0,0 +1,42 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 - 2012 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test read image method on non-interlaced JPEG.
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..3\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/jpeg' || die 'Cd failed';
+
+#
+# 1) Test non-interlaced image read
+#
+print( "Non-interlaced JPEG ...\n" );
+testReadCompare('input.jpg', '../reference/jpeg/read_non_interlaced.miff', q//, 0, 0);
+
+#
+# 2) Test plane-interlaced image read
+#
+++$test;
+print( "Plane-interlaced JPEG ...\n" );
+testReadCompare('input_plane.jpg', '../reference/jpeg/read_plane_interlaced.miff', q//, 0, 0);
+
+#
+# 3) Test Seattle FilmWorks image file ...\n");
+#
+print("Seattle FilmWorks image file ...\n");
+++$test;
+testReadCompare('input.sfw', '../reference/jpeg/read_sfw.miff', q//, 0.003, 0.1);
diff --git a/PerlMagick/t/jpeg/write.t b/PerlMagick/t/jpeg/write.t
new file mode 100644
index 0000000..170f1b0
--- /dev/null
+++ b/PerlMagick/t/jpeg/write.t
@@ -0,0 +1,41 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003-2009 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading JPEG images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..2\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/jpeg' || die 'Cd failed';
+
+#
+# 1) Test with non-interlaced image
+#
+print( "Non-interlaced JPEG ...\n" );
+testReadWriteCompare( 'input.jpg', 'output_tmp.jpg',
+ '../reference/jpeg/write_non_interlaced.miff',
+ q//, q//, 0.015, 0.16);
+
+#
+# 2) Test with plane-interlaced image
+#
+++$test;
+print( "Plane-interlaced JPEG ...\n" );
+testReadWriteCompare( 'input.jpg', 'output_plane_tmp.jpg',
+ '../reference/jpeg/write_plane_interlaced.miff',
+ q//, q//, 0.015, 0.16);
+
diff --git a/PerlMagick/t/montage.t b/PerlMagick/t/montage.t
new file mode 100644
index 0000000..626d37b
--- /dev/null
+++ b/PerlMagick/t/montage.t
@@ -0,0 +1,198 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test montage method.
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1, print "1..19\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't' || die 'Cd failed';
+
+#
+# 1) Test montage defaults (except no label that requires an exact font)
+#
+testMontage( q//,
+ q/background=>'#696e7e', label=>''/,
+ '7b63f3d3f0bad2fec1c5df948683df21a542df04a944b7cba46f897e4284af8a');
+
+#
+# 2) Test Center gravity
+# Image should be centered in frame
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'Center'/,
+ '6b8c66a9fd27feea291c60456bdf4193b877ab532cb8437906fe48493e511477');
+
+#
+# 3) Test NorthWest gravity
+# Image should be at top-left in frame
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'NorthWest'/,
+ 'a193d8a3adb7e22eb0242deea786e90257b30c86ceb84fcf8e906282dc27af18');
+
+#
+# 4) Test North gravity
+# Image should be at top-center of frame
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'North'/,
+ '53988447fa24f34bba94325431b3466bb5d95899e3e96bbc4958e413fac1bc07');
+
+#
+# 5) Test NorthEast gravity
+# Image should be at top-right of frame
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'NorthEast'/,
+ '476bca9ee76273dea0f5119e6285a5723c16218a64e9a86b82109d6fb1243b33');
+
+#
+# 6) Test West gravity
+# Image should be at left-center of frame
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'West'/,
+ '93d6763f385881aeb84e4feb92b7d9c77ea23cdbaf141df7a228a985130f77ec');
+
+#
+# 7) Test East gravity
+# Image should be at right-center of frame.
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'East'/,
+ 'afbaee72c580f31ad02d1fdec55ccb8b8165f18299b6a377c574bea9f9f362b5');
+
+#
+# 8) Test SouthWest gravity
+# Image should be at bottom-left of frame
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'SouthWest'/,
+ '6792c62fea5c93e7a74a76f96e09b6ffd3284ef750009d4524f47c62a59004b5');
+
+#
+# 9) Test South gravity
+# Image should be at bottom of frame
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'South'/,
+ '03e2fcb8b0e447dbe294598bc8f267385133244a010e66c849a6cc9560035e90');
+
+#
+# 10) Test SouthEast gravity
+# Image should be at bottom-right of frame.
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', geometry=>'90x80+5+5>', gravity=>'SouthEast'/,
+ '8851434def5ece352fc5fe830871ea2a7f6608fe50eef6abaf4e4b0bccacd360');
+
+#
+# 11) Test Framed Montage
+#
+# Image border color 'bordercolor' controls frame background color
+# Image matte color 'mattecolor' controls frame color
+# Image pen color 'pen' controls label text foreground color
+++$test;
+testMontage( q/bordercolor=>'blue', mattecolor=>'red'/,
+ q/background=>'#696e7e', label=>'', tile=>'4x4', geometry=>'90x80+3+3>', frame=>'8x10',
+ borderwidth=>'0', gravity=>'Center', background=>'gray'/,
+ '780481bfe04c2057b838c7d20e96b73a3efd576e3693856a7a17c2bd0d0c27d1');
+
+#
+# 12) Test Framed Montage with drop-shadows
+#
+++$test;
+testMontage( q/bordercolor=>'blue', mattecolor=>'red'/,
+ q/background=>'#696e7e', label=>'', tile=>'4x4', geometry=>'90x80+6+6>', frame=>'8x10',
+ borderwidth=>'0', gravity=>'Center', shadow=>'True',background=>'gray'/,
+ '9930e5bd7619a6164b4c776c5039458d5168a7657fa9eee45ee481025dced058',
+ 'f92f684e98c399a1a4e678b0a1e179d2950b7601c9f8ab9879d154bdbba6828a',
+ '024421d78413b961b96b484de658537d423d2558cdb2762cb280930d24072cb9');
+
+#
+# 13) Test Framed Montage with drop-shadows and background texture
+#
+++$test;
+testMontage( q/bordercolor=>'blue', mattecolor=>'red'/,
+ q/background=>'#696e7e', label=>'', tile=>'4x4', geometry=>'90x80+6+6>', frame=>'8x10',
+ borderwidth=>'0', gravity=>'Center', shadow=>'True', texture=>'granite:'/,
+ 'f2efb22f7fc25e2e7e9117461926d8e51cec9aa95a35ec090b7c142a77eaaf23',
+ '4257bf6d7d61ff70a9b9e3bec940bffce7e7982714c0f8ff6ee799ddb0b5c8f1',
+ '05fa6878a42bea4555d2fa51be5aefbc21d4524b4eba1dade86366ce6ab7f51e');
+
+#
+# 14) Test Un-bordered, Un-framed Montage
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', tile=>'4x4', geometry=>'90x80+6+6>', mode=>'Unframe',
+ borderwidth=>'0', gravity=>'Center', background=>'gray'/,
+ '87ff711946f98edc0b38d8685a01339f47aa80bebdbfc0787b31350db79c8ebb');
+
+#
+# 15) Test Bordered, Un-framed Montage (mode=>'Unframe')
+#
+++$test;
+testMontage( q/bordercolor=>'red'/,
+ q/background=>'#696e7e', label=>'', tile=>'4x4', geometry=>'90x80+6+6>', mode=>'Unframe',
+ borderwidth=>'5', gravity=>'Center', background=>'gray'/,
+ 'a3ea40117f37ff2a68772aaa1dd7c41cc81bd21179cbd19d193ebfb5381fed92');
+
+#
+# 16) Test Bordered, Un-framed Montage (mode=>'UnFrame')
+#
+++$test;
+testMontage( q/bordercolor=>'red'/,
+ q/label=>'', tile=>'4x4', geometry=>'90x80+6+6>', mode=>'UnFrame',
+ borderwidth=>'5', gravity=>'Center', background=>'gray'/,
+ 'a3ea40117f37ff2a68772aaa1dd7c41cc81bd21179cbd19d193ebfb5381fed92');
+
+#
+# 17) Test Un-bordered, Un-framed Montage with 16x1 tile
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', tile=>'16x1', geometry=>'90x80+0+0>', mode=>'Unframe',
+ borderwidth=>'0', gravity=>'Center', background=>'gray'/,
+ 'fe71f67323d14c1689216cf96b9977dd208f137592dd9708da001a41225e079a');
+
+#
+# 18) Test concatenated thumbnail Montage (concatenated via special Concatenate mode)
+# Thumbnails should be compacted tightly together in a grid
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', tile=>'4x4', geometry=>'90x80>', mode=>'Concatenate'/,
+ '94f72cf702e54c52eda26f461fa7bdd541cbddfdca74d2619b12f1c308b0c37d');
+#
+# 19) Test concatenated thumbnail Montage (concatentated by setting params to zero)
+# Thumbnails should be compacted tightly together in a grid
+#
+++$test;
+testMontage( q//,
+ q/background=>'#696e7e', label=>'', tile=>'4x4', geometry=>'+0+0', mode=>'Unframe', shadow=>'False',
+ borderwidth=>'0', background=>'gray'/,
+ '94f72cf702e54c52eda26f461fa7bdd541cbddfdca74d2619b12f1c308b0c37d');
diff --git a/PerlMagick/t/mpeg/input.m2v b/PerlMagick/t/mpeg/input.m2v
new file mode 100644
index 0000000..04b4a45
--- /dev/null
+++ b/PerlMagick/t/mpeg/input.m2v
Binary files differ
diff --git a/PerlMagick/t/mpeg/input.mpg b/PerlMagick/t/mpeg/input.mpg
new file mode 100644
index 0000000..7a66614
--- /dev/null
+++ b/PerlMagick/t/mpeg/input.mpg
Binary files differ
diff --git a/PerlMagick/t/mpeg/read.t b/PerlMagick/t/mpeg/read.t
new file mode 100644
index 0000000..790baf9
--- /dev/null
+++ b/PerlMagick/t/mpeg/read.t
@@ -0,0 +1,38 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading MPEG files
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+#
+BEGIN { $| = 1; $test=1; print "1..2\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/mpeg' || die 'Cd failed';
+
+#
+# Motion Picture Experts Group file interchange format (version 2)
+#
+testRead( 'input.m2v',
+ 'cf2a93e2a86b504e856ca9fee80d44243e1fc823b0bde9a0c1af5c3e428f7e44' );
+
+#
+# Motion Picture Experts Group file interchange format
+#
+++$test;
+testRead( 'input.mpg',
+ '8b4bbc158420f790837e6996821b198df2c33631d1e1b71af4f30aaf3bb8a3c0' );
+
+1;
diff --git a/PerlMagick/t/palm_std_colormap.palm b/PerlMagick/t/palm_std_colormap.palm
new file mode 100644
index 0000000..c832419
--- /dev/null
+++ b/PerlMagick/t/palm_std_colormap.palm
Binary files differ
diff --git a/PerlMagick/t/ping.t b/PerlMagick/t/ping.t
new file mode 100644
index 0000000..0d50f70
--- /dev/null
+++ b/PerlMagick/t/ping.t
@@ -0,0 +1,56 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 - 2009 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test Ping
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+#
+BEGIN { $| = 1; $test=1; print "1..2\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't' || die 'Cd failed';
+
+my ($image, $width, $height, $size, $format, $status, @blob);
+
+print("Ping \"logo:\" ...\n");
+$image=Graphics::Magick->new;
+($width, $height, $size, $format)=$image->Ping('logo:');
+print " width=$width, height=$height, size=$size, format=$format\n";
+if (($width == 654) && ($height == 418) && ($size == 22077) && ($format eq "GIF")) {
+ print "ok $test\n";
+ } else {
+ print "not ok $test\n";
+ }
+undef $image;
+++$test;
+
+print("Ping blob ...\n");
+$image=Graphics::Magick->new;
+$status=$image->Read('logo:');
+warn "$status" if "$status";
+@blob=$image->ImageToBlob();
+undef $image;
+$image=Graphics::Magick->new;
+($width, $height, $size, $format)=$image->Ping(blob=>@blob);
+undef @blob;
+undef $image;
+print " width=$width, height=$height, size=$size, format=$format\n";
+if (($width == 654) && ($height == 418) && ($size == 22077) && ($format eq "GIF")) {
+ print "ok $test\n";
+ } else {
+ print "not ok $test\n";
+ }
+
+1;
diff --git a/PerlMagick/t/png/input.mng b/PerlMagick/t/png/input.mng
new file mode 100644
index 0000000..2694fc5
--- /dev/null
+++ b/PerlMagick/t/png/input.mng
Binary files differ
diff --git a/PerlMagick/t/png/input_16.png b/PerlMagick/t/png/input_16.png
new file mode 100644
index 0000000..06223a6
--- /dev/null
+++ b/PerlMagick/t/png/input_16.png
Binary files differ
diff --git a/PerlMagick/t/png/input_256.png b/PerlMagick/t/png/input_256.png
new file mode 100644
index 0000000..c674581
--- /dev/null
+++ b/PerlMagick/t/png/input_256.png
Binary files differ
diff --git a/PerlMagick/t/png/input_bw.png b/PerlMagick/t/png/input_bw.png
new file mode 100644
index 0000000..0020f80
--- /dev/null
+++ b/PerlMagick/t/png/input_bw.png
Binary files differ
diff --git a/PerlMagick/t/png/input_mono.png b/PerlMagick/t/png/input_mono.png
new file mode 100644
index 0000000..1b83ba9
--- /dev/null
+++ b/PerlMagick/t/png/input_mono.png
Binary files differ
diff --git a/PerlMagick/t/png/input_truecolor.png b/PerlMagick/t/png/input_truecolor.png
new file mode 100644
index 0000000..2cd0813
--- /dev/null
+++ b/PerlMagick/t/png/input_truecolor.png
Binary files differ
diff --git a/PerlMagick/t/png/read-16.t b/PerlMagick/t/png/read-16.t
new file mode 100644
index 0000000..9b209e8
--- /dev/null
+++ b/PerlMagick/t/png/read-16.t
@@ -0,0 +1,58 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading PNG images when 16bit support is enabled
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..5\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/png' || die 'Cd failed';
+
+#
+# 1) Test Monochrome PNG
+#
+testRead( 'input_mono.png',
+ '19da3123692c66d023074dd1e272119ab2357b9a34855a393ad18c88af01ae86' );
+
+#
+# 2) Test 256 color pseudocolor PNG
+#
+++$test;
+testRead( 'input_256.png',
+ 'd1340caccc7351834f1ca9693489ee780ac326a0d6bb660cd550c5c28711b2fe' );
+
+#
+# 3) Test TrueColor PNG
+#
+++$test;
+testRead( 'input_truecolor.png',
+ 'b84c31bbe78d84d0432c7414b25c58599484aa2c7174af8332509966d07f265b' );
+
+#
+# 4) Test Multiple-image Network Graphics
+#
+++$test;
+testRead( 'input.mng',
+ 'eb089161ebc5ab3964cdec1b72628c4d1c29ebd78f333a3d4a0d47c614fb3897' );
+
+#
+# 5) Test 16-bit Portable Network Graphics
+#
+++$test;
+testRead( 'input_16.png',
+ 'a6c3f3ce8772cd6aa973ae1f3ebd94ee65292112d3f1e8e86171bf4d931bd181',
+ 'c87cc12715f3e0619d6fe871bd8132f88facffb3d38dd8869cb262ec6b9c4cef');
diff --git a/PerlMagick/t/png/read.t b/PerlMagick/t/png/read.t
new file mode 100644
index 0000000..f776d36
--- /dev/null
+++ b/PerlMagick/t/png/read.t
@@ -0,0 +1,71 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading PNG images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..6\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/png' || die 'Cd failed';
+
+#
+# 1) Test Black-and-white, bit_depth=1 PNG
+#
+print( "1-bit grayscale PNG ...\n" );
+testRead( 'input_bw.png',
+ '552ee0b3b9159ceedc4ce30125e9db38d2045d53b941844a72ac5f5f38335454' );
+
+#
+# 2) Test Monochrome PNG
+#
+++$test;
+print( "8-bit grayscale PNG ...\n" );
+testRead( 'input_mono.png',
+ '19da3123692c66d023074dd1e272119ab2357b9a34855a393ad18c88af01ae86' );
+
+#
+# 3) Test 16-bit Portable Network Graphics
+#
+++$test;
+print( "16-bit grayscale PNG ...\n" );
+testRead( 'input_16.png',
+ 'a6c3f3ce8772cd6aa973ae1f3ebd94ee65292112d3f1e8e86171bf4d931bd181',
+ 'c87cc12715f3e0619d6fe871bd8132f88facffb3d38dd8869cb262ec6b9c4cef' );
+#
+# 4) Test 256 color pseudocolor PNG
+#
+++$test;
+print( "8-bit indexed-color PNG ...\n" );
+testRead( 'input_256.png',
+ 'd1340caccc7351834f1ca9693489ee780ac326a0d6bb660cd550c5c28711b2fe' );
+
+#
+# 5) Test TrueColor PNG
+#
+++$test;
+print( "24-bit Truecolor PNG ...\n" );
+testRead( 'input_truecolor.png',
+ 'b84c31bbe78d84d0432c7414b25c58599484aa2c7174af8332509966d07f265b' );
+
+#
+# 6) Test Multiple-image Network Graphics
+#
+++$test;
+print( "MNG with 24-bit Truecolor PNGs...\n" );
+testRead( 'input.mng',
+ 'eb089161ebc5ab3964cdec1b72628c4d1c29ebd78f333a3d4a0d47c614fb3897' );
+
diff --git a/PerlMagick/t/png/write-16.t b/PerlMagick/t/png/write-16.t
new file mode 100644
index 0000000..24cbba1
--- /dev/null
+++ b/PerlMagick/t/png/write-16.t
@@ -0,0 +1,69 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing PNG images when 16bit support is enabled
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..5\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/png' || die 'Cd failed';
+
+#
+# 1) Test pseudocolor image
+#
+testReadWrite( 'input_256.png',
+ 'output_256.png',
+ q/quality=>54/,
+ 'd1340caccc7351834f1ca9693489ee780ac326a0d6bb660cd550c5c28711b2fe' );
+
+#
+# 2) Test truecolor image
+#
+++$test;
+testReadWrite( 'input_truecolor.png',
+ 'output_truecolor.png',
+ q/quality=>55/,
+ 'b84c31bbe78d84d0432c7414b25c58599484aa2c7174af8332509966d07f265b' );
+
+#
+# 3) Test monochrome image
+#
+++$test;
+testReadWrite( 'input_mono.png',
+ 'output_mono.png', '',
+ '19da3123692c66d023074dd1e272119ab2357b9a34855a393ad18c88af01ae86' );
+
+#
+# 4) Test Multiple-image Network Graphics
+#
+++$test;
+testReadWrite( 'input.mng',
+ 'output.mng',
+ q/quality=>55/,
+ 'eb089161ebc5ab3964cdec1b72628c4d1c29ebd78f333a3d4a0d47c614fb3897' );
+
+#
+# 5) Test 16-bit Portable Network Graphics
+#
+++$test;
+testReadWrite( 'input_16.png',
+ 'output_16.png',
+ q/quality=>55/,
+ 'a6c3f3ce8772cd6aa973ae1f3ebd94ee65292112d3f1e8e86171bf4d931bd181',
+ 'c87cc12715f3e0619d6fe871bd8132f88facffb3d38dd8869cb262ec6b9c4cef');
+
+
diff --git a/PerlMagick/t/png/write.t b/PerlMagick/t/png/write.t
new file mode 100644
index 0000000..06454c6
--- /dev/null
+++ b/PerlMagick/t/png/write.t
@@ -0,0 +1,76 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing PNG images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..6\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/png' || die 'Cd failed';
+
+#
+# 1) Test Black-and-white, bit_depth=1 PNG
+#
+print( "1-bit grayscale PNG ...\n" );
+testReadWrite( 'input_bw.png', 'output_bw.png', q/quality=>95/,
+ '552ee0b3b9159ceedc4ce30125e9db38d2045d53b941844a72ac5f5f38335454');
+
+#
+# 2) Test monochrome image
+#
+++$test;
+print( "8-bit grayscale PNG ...\n" );
+testReadWrite( 'input_mono.png',
+ 'output_mono.png', '',
+ '19da3123692c66d023074dd1e272119ab2357b9a34855a393ad18c88af01ae86');
+#
+# 3) Test 16-bit Portable Network Graphics
+#
+++$test;
+print( "16-bit grayscale PNG ...\n" );
+testReadWrite( 'input_16.png',
+ 'output_16.png',
+ q/quality=>55/,
+ 'a6c3f3ce8772cd6aa973ae1f3ebd94ee65292112d3f1e8e86171bf4d931bd181',
+ 'c87cc12715f3e0619d6fe871bd8132f88facffb3d38dd8869cb262ec6b9c4cef' );
+#
+# 4) Test pseudocolor image
+#
+++$test;
+print( "8-bit indexed-color PNG ...\n" );
+testReadWrite( 'input_256.png',
+ 'output_256.png',
+ q/quality=>54/,
+ 'd1340caccc7351834f1ca9693489ee780ac326a0d6bb660cd550c5c28711b2fe' );
+#
+# 5) Test truecolor image
+#
+++$test;
+print( "24-bit Truecolor PNG ...\n" );
+testReadWrite( 'input_truecolor.png',
+ 'output_truecolor.png',
+ q/quality=>55/,
+ 'b84c31bbe78d84d0432c7414b25c58599484aa2c7174af8332509966d07f265b' );
+#
+# 6) Test Multiple-image Network Graphics
+#
+++$test;
+print( "MNG with 24-bit Truecolor PNGs ...\n" );
+testReadWrite( 'input.mng',
+ 'output.mng',
+ q/quality=>55/,
+ 'eb089161ebc5ab3964cdec1b72628c4d1c29ebd78f333a3d4a0d47c614fb3897' );
diff --git a/PerlMagick/t/ps/input.eps b/PerlMagick/t/ps/input.eps
new file mode 100644
index 0000000..48ba981
--- /dev/null
+++ b/PerlMagick/t/ps/input.eps
@@ -0,0 +1,132 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: congrats.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 0-beta2
+%%CreationDate: Thu Sep 3 18:27:20 1998
+%%For: bfriesen@scooby (Bob Friesenhahn)
+%%Orientation: Portrait
+%%BoundingBox: 0 0 497 317
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize Letter
+%%EndSetup
+%%Magnification: 1.00
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-53.0 352.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 5902 m 0 0 l 9202 0 l 9202 5902 l cp clip
+ 0.06000 0.06000 sc
+% Polyline
+7.500 slw
+n 1005 600 m 900 600 900 5745 105 arcto 4 {pop} repeat
+ 900 5850 9045 5850 105 arcto 4 {pop} repeat
+ 9150 5850 9150 705 105 arcto 4 {pop} repeat
+ 9150 600 1005 600 105 arcto 4 {pop} repeat
+ cp gs col0 s gr
+% Polyline
+30.000 slw
+n 5415 3735 m 5115 3735 l gs col0 s gr
+% Polyline
+n 4335 3720 m 4035 3720 l gs col0 s gr
+/Helvetica-Bold ff 480.00 scf sf
+5025 1950 m
+gs 1 -1 sc (You can display an image!) dup sw pop 2 div neg 0 rm col4 sh gr
+/Helvetica-Bold ff 480.00 scf sf
+5025 1275 m
+gs 1 -1 sc (CONGRATULATIONS!) dup sw pop 2 div neg 0 rm col4 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1500 3375 m
+gs 1 -1 sc (2\) Use CNTRL-Q key combination) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+4575 3825 m
+gs 1 -1 sc (or) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1875 4350 m
+gs 1 -1 sc (Depress right mouse button to bring) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1875 4875 m
+gs 1 -1 sc (up menu and select 'Quit' to continue) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1875 5325 m
+gs 1 -1 sc (tests.) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1500 2775 m
+gs 1 -1 sc (1\) Move mouse cursor into this window.) col0 sh gr
+$F2psEnd
+rs
diff --git a/PerlMagick/t/ps/input.miff b/PerlMagick/t/ps/input.miff
new file mode 100644
index 0000000..7740ad5
--- /dev/null
+++ b/PerlMagick/t/ps/input.miff
@@ -0,0 +1,9 @@
+id=ImageMagick
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+background-color=gray74 border-color=gray74 matte-color=gray74
+{
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/ps/input.ps b/PerlMagick/t/ps/input.ps
new file mode 100644
index 0000000..98bd9eb
--- /dev/null
+++ b/PerlMagick/t/ps/input.ps
@@ -0,0 +1,134 @@
+%!PS-Adobe-2.0
+%%Title: congrats.ps
+%%Creator: fig2dev Version 3.2 Patchlevel 0-beta2
+%%CreationDate: Thu Sep 3 18:27:58 1998
+%%For: bfriesen@scooby (Bob Friesenhahn)
+%%Orientation: Portrait
+%%BoundingBox: 57 237 554 554
+%%Pages: 1
+%%BeginSetup
+%%IncludeFeature: *PageSize Letter
+%%EndSetup
+%%Magnification: 1.00
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+4.5 589.5 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 5902 m 0 0 l 9202 0 l 9202 5902 l cp clip
+ 0.06000 0.06000 sc
+%%Page: 1 1
+% Polyline
+7.500 slw
+n 1005 600 m 900 600 900 5745 105 arcto 4 {pop} repeat
+ 900 5850 9045 5850 105 arcto 4 {pop} repeat
+ 9150 5850 9150 705 105 arcto 4 {pop} repeat
+ 9150 600 1005 600 105 arcto 4 {pop} repeat
+ cp gs col0 s gr
+% Polyline
+30.000 slw
+n 5415 3735 m 5115 3735 l gs col0 s gr
+% Polyline
+n 4335 3720 m 4035 3720 l gs col0 s gr
+/Helvetica-Bold ff 480.00 scf sf
+5025 1950 m
+gs 1 -1 sc (You can display an image!) dup sw pop 2 div neg 0 rm col4 sh gr
+/Helvetica-Bold ff 480.00 scf sf
+5025 1275 m
+gs 1 -1 sc (CONGRATULATIONS!) dup sw pop 2 div neg 0 rm col4 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1500 3375 m
+gs 1 -1 sc (2\) Use CNTRL-Q key combination) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+4575 3825 m
+gs 1 -1 sc (or) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1875 4350 m
+gs 1 -1 sc (Depress right mouse button to bring) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1875 4875 m
+gs 1 -1 sc (up menu and select 'Quit' to continue) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1875 5325 m
+gs 1 -1 sc (tests.) col0 sh gr
+/Helvetica-Bold ff 360.00 scf sf
+1500 2775 m
+gs 1 -1 sc (1\) Move mouse cursor into this window.) col0 sh gr
+$F2psEnd
+rs
+showpage
diff --git a/PerlMagick/t/ps/read.t b/PerlMagick/t/ps/read.t
new file mode 100644
index 0000000..8db4222
--- /dev/null
+++ b/PerlMagick/t/ps/read.t
@@ -0,0 +1,81 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test Reading Postscript images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..3\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/ps' || die 'Cd failed';
+
+#
+# 1) Test reading Postscript
+#
+$image=Graphics::Magick->new;
+$x=$image->ReadImage('input.ps');
+if( "$x" ) {
+ print "ReadImage: $x\n";
+ print "not ok $test\n";
+} else {
+ print "ok $test\n";
+}
+undef $image;
+
+
+#
+# 2) Test reading Encapsulated Postscript
+#
+++$test;
+$image=Graphics::Magick->new;
+$x=$image->ReadImage('input.eps');
+if( "$x" ) {
+ print "ReadImage: $x\n";
+ print "not ok $test\n";
+} else {
+ print "ok $test\n";
+}
+undef $image;
+
+#
+# 3) Test rendering using a Postscript font
+#
+++$test;
+$font = 'helvetica';
+
+$image=Graphics::Magick->new;
+$x=$image->Set(font=>"$font", pen=>'#0000FF', dither=>'False');
+if( "$x" ) {
+ print "$x\n";
+ print "not ok $test\n";
+} else {
+ $x=$image->ReadImage('label:The quick brown fox jumps over the lazy dog.');
+ if ( "$x" ) {
+ print "ReadImage: $x\n";
+ # If server can't be accessed, ImageMagick returns this warning
+ # Warning 305: Unable to open X server
+ $x =~ /(\d+)/;
+ my $errorCode = $1;
+ if ( $errorCode > 0 ) {
+ print "not ok $test\n";
+ } else {
+ print "ok $test\n";
+ }
+ } else {
+ print "ok $test\n";
+ }
+}
+undef $image;
diff --git a/PerlMagick/t/ps/write.t b/PerlMagick/t/ps/write.t
new file mode 100644
index 0000000..aeb7b07
--- /dev/null
+++ b/PerlMagick/t/ps/write.t
@@ -0,0 +1,38 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing Postscript images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..2\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/ps' || die 'Cd failed';
+
+#
+# 1) Test Postscript
+#
+testReadWriteNoVerify( 'input.miff',
+ 'output.ps',
+ q// );
+#
+# 2) Test Encapsulated Postscript
+#
+++$test;
+testReadWriteNoVerify( 'input.miff',
+ 'output.eps',
+ q// );
+
diff --git a/PerlMagick/t/rad/input.rad b/PerlMagick/t/rad/input.rad
new file mode 100644
index 0000000..135f7e3
--- /dev/null
+++ b/PerlMagick/t/rad/input.rad
Binary files differ
diff --git a/PerlMagick/t/rad/read.t b/PerlMagick/t/rad/read.t
new file mode 100644
index 0000000..e8b7dac
--- /dev/null
+++ b/PerlMagick/t/rad/read.t
@@ -0,0 +1,26 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading Radiance file format
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+#
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/rad' || die 'Cd failed';
+
+testRead( 'RAD:input.rad',
+ '1277e217f62ef66d77b8afb79ff0b9e4204a47ccd7663057f27a5255ebb0640c');
diff --git a/PerlMagick/t/rad/write.t b/PerlMagick/t/rad/write.t
new file mode 100644
index 0000000..6127a49
--- /dev/null
+++ b/PerlMagick/t/rad/write.t
@@ -0,0 +1,33 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing Radiance file format
+#
+# Currently supported tests are for formats that ImageMagick
+# knows how to both read and write.
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/rad' || die 'Cd failed';
+
+testReadWrite( 'RAD:input.rad',
+ 'MIFF:output.rad',
+ q//,
+ '1277e217f62ef66d77b8afb79ff0b9e4204a47ccd7663057f27a5255ebb0640c');
+
+1;
diff --git a/PerlMagick/t/read.t b/PerlMagick/t/read.t
new file mode 100644
index 0000000..cd4a273
--- /dev/null
+++ b/PerlMagick/t/read.t
@@ -0,0 +1,355 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 - 2016 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading formats supported directly by GraphicsMagick
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+#
+BEGIN { $| = 1; $test=1; print "TAP version 13\n1..78\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't' || die 'Cd failed';
+
+print("AVS X image file ...\n");
+testReadCompare('input.avs', 'reference/read/input_avs.miff', q//, 0, 0);
+
+print("Microsoft Windows bitmap image file ...\n");
+++$test;
+testReadCompare('input.bmp', 'reference/read/input_bmp.miff', q//, 0, 0);
+
+print("Microsoft Windows 24-bit bitmap image file ...\n");
+++$test;
+testReadCompare('input.bmp24', 'reference/read/input_bmp24.miff', q//, 0, 0);
+
+print("Cineon Gray image file ...\n");
+++$test;
+testReadCompare('input_gray.cin', 'reference/read/input_gray_cin.miff', q//, 0, 0);
+
+print("Cineon RGB image file ...\n");
+++$test;
+testReadCompare('input_rgb.cin', 'reference/read/input_rgb_cin.miff', q//, 0, 0);
+
+print("ZSoft IBM PC multi-page Paintbrush file ...\n");
+++$test;
+testReadCompare('input.dcx', 'reference/read/input_dcx.miff', q//, 0, 0);
+
+print("Microsoft Windows bitmap image file ...\n");
+++$test;
+testReadCompare('input.dib', 'reference/read/input_dib.miff', q//, 0, 0);
+
+print("Flexible Image Transport System 8-bit ...\n");
+++$test;
+testReadCompare('input_gray_08bit.fits', 'reference/read/input_gray_08bit_fits.miff', q//, 0, 0);
+
+print("Flexible Image Transport System LSB 16-bit ...\n");
+++$test;
+testReadCompare('input_gray_16bit.fits', 'reference/read/input_gray_16bit_fits.miff', q//, 0.002, 0.004);
+
+print("Flexible Image Transport System LSB 32-bit ...\n");
+++$test;
+testReadCompare('input_gray_32bit.fits', 'reference/read/input_gray_32bit_fits.miff', q//, 0.002, 0.004);
+
+print("Flexible Image Transport System LSB double ...\n");
+++$test;
+testReadCompare('input_gray_lsb_double.fits', 'reference/read/input_gray_lsb_double_fits.miff', q//, 0.002, 0.004);
+
+print("Flexible Image Transport System MSB 16-bit ...\n");
+++$test;
+testReadCompare('input_gray_msb_16bit.fits', 'reference/read/input_gray_msb_16bit_fits.miff', q//, 0.002, 0.004);
+
+print("Flexible Image Transport System MSB 32-bit ...\n");
+++$test;
+testReadCompare('input_gray_msb_32bit.fits', 'reference/read/input_gray_msb_32bit_fits.miff', q//, 0.002, 0.004);
+
+print("Flexible Image Transport System MSB 64-bit ...\n");
+++$test;
+testReadCompare('input_gray_msb_64bit.fits', 'reference/read/input_gray_msb_64bit_fits.miff', q//, 0.002, 0.004);
+
+print("Flexible Image Transport System MSB float ...\n");
+++$test;
+testReadCompare('input_gray_msb_float.fits', 'reference/read/input_gray_msb_float_fits.miff', q//, 0.002, 0.004);
+
+print("Flexible Image Transport System MSB double ...\n");
+++$test;
+testReadCompare('input_gray_msb_double.fits', 'reference/read/input_gray_msb_double_fits.miff', q//, 0.002, 0.004);
+
+print("CompuServe graphics interchange format ...\n");
+++$test;
+testReadCompare('input.gif', 'reference/read/input_gif.miff', q//, 0, 0);
+
+print("CompuServe graphics interchange format (1987) ...\n");
+++$test;
+testReadCompare('input.gif87', 'reference/read/input_gif87.miff', q//, 0, 0);
+
+print("Gradient (gradual passing from one shade to another) ...\n");
+++$test;
+testReadCompare('gradient:red-blue', 'reference/read/gradient.miff',
+ q/size=>"70x46"/, 0.003, 0.004);
+
+print("GRANITE (granite texture) ...\n");
+++$test;
+testReadCompare('granite:', 'reference/read/granite.miff', q/size=>"70x46"/, 0, 0);
+
+print("HRZ Slow scan TV ...\n");
+++$test;
+testReadCompare('input.hrz', 'reference/read/input_hrz.miff', q//, 0, 0);
+
+print("MacPaint ...\n");
+++$test;
+testReadCompare('input.mac', 'reference/read/input_mac.bmp', q//, 0, 0);
+
+print("MAT (MatLab logical 8-bit LSB integer) ...\n");
+++$test;
+testReadCompare('input_logical_lsb_08bit.mat', 'reference/read/input_logical_lsb_08bit_mat.miff', q//, 0, 0);
+
+print("MAT (MatLab gray 8-bit LSB integer) ...\n");
+++$test;
+testReadCompare('input_gray_lsb_08bit.mat', 'reference/read/input_gray_lsb_08bit_mat.miff', q//, 0, 0);
+
+print("MAT (MatLab gray 8-bit MSB integer) ...\n");
+++$test;
+testReadCompare('input_gray_msb_08bit.mat', 'reference/read/input_gray_msb_08bit_mat.miff', q//, 0, 0);
+
+print("MAT (MatLab gray 16-bit LSB integer) ...\n");
+++$test;
+testReadCompare('input_gray_lsb_16bit.mat', 'reference/read/input_gray_lsb_16bit_mat.miff', q//, 0, 0);
+
+print("MAT (MatLab gray 32-bit LSB integer) ...\n");
+++$test;
+testReadCompare('input_gray_lsb_32bit.mat', 'reference/read/input_gray_lsb_32bit_mat.miff', q//, 0, 0);
+
+print("MAT (MatLab gray 32-bit LSB float) ...\n");
+++$test;
+testReadCompare('input_gray_lsb_float.mat', 'reference/read/input_gray_lsb_float_mat.miff', q//, 0.002, 0.004);
+
+print("MAT (MatLab gray 64-bit LSB double) ...\n");
+++$test;
+testReadCompare('input_gray_lsb_double.mat', 'reference/read/input_gray_lsb_double_mat.miff', q//, 0.002, 0.004);
+
+print("MAT (MatLab RGB 8-bit LSB integer) ...\n");
+++$test;
+testReadCompare('input_rgb_lsb_08bit.mat', 'reference/read/input_rgb_lsb_08bit_mat.miff', q//, 0, 0);
+
+print("MAT (MatLab V4 gray 64-bit LSB double) ...\n");
+++$test;
+testReadCompare('input_gray_lsb_double_V4.mat', 'reference/read/input_gray_lsb_double_V4_mat.miff', q//, 0.002, 0.004);
+
+print("Microsoft icon ...\n");
+++$test;
+testReadCompare('input.ico', 'reference/read/input_ico.miff', q//, 0, 0);
+
+print("Magick image file format ...\n");
+++$test;
+testReadCompare('input.miff', 'reference/read/input_miff.miff', q//, 0, 0);
+
+print("MTV Raytracing image format ...\n");
+++$test;
+testReadCompare('input.mtv', 'reference/read/input_mtv.miff', q//, 0, 0);
+
+print("Xv's visual schnauzer format. ...\n");
+++$test;
+testReadCompare('input_p7.p7', 'reference/read/input_p7.miff', q//,
+ 0.002, 0.004);
+
+print("NULL (white image) ...\n");
+++$test;
+testReadCompare('NULL:white', 'reference/read/input_null_white.miff', q/size=>"70x46"/, 0, 0);
+
+print("NULL (black image) ...\n");
+++$test;
+testReadCompare('NULL:black', 'reference/read/input_null_black.miff', q/size=>"70x46"/, 0, 0);
+
+print("NULL (DarkOrange image) ...\n");
+++$test;
+testReadCompare('NULL:DarkOrange', 'reference/read/input_null_DarkOrange.miff', q/size=>"70x46"/, 0, 0);
+
+print("Portable bitmap format (black and white), ASCII format ...\n");
+++$test;
+testReadCompare('input_p1.pbm', 'reference/read/input_pbm_p1.miff', q//, 0, 0);
+
+print("Portable bitmap format (black and white), binary format ...\n");
+++$test;
+testReadCompare('input_p4.pbm', 'reference/read/input_pbm_p4.miff', q//, 0, 0);
+
+print("ZSoft IBM PC Paintbrush file ...\n");
+++$test;
+testReadCompare('input.pcx', 'reference/read/input_pcx.miff', q//, 0, 0);
+
+print("Portable graymap format (gray scale), ASCII format ...\n");
+++$test;
+testReadCompare('input_p2.pgm', 'reference/read/input_pgm_p2.miff', q//, 0, 0);
+
+print("Portable graymap format (gray scale), binary format ...\n");
+++$test;
+testReadCompare('input_p5.pgm', 'reference/read/input_pgm_p5.miff', q//, 0, 0);
+
+print("Apple Macintosh QuickDraw/PICT file ...\n");
+++$test;
+testReadCompare('input.pict', 'reference/read/input_pict.miff', q//, 0, 0);
+
+print("Alias/Wavefront RLA image format (gray scale) ...\n");
+++$test;
+testReadCompare('input_gray.rla', 'reference/read/input_gray_rla.miff', q//, 0, 0);
+
+print("Alias/Wavefront RLA image format (RGB) ...\n");
+++$test;
+testReadCompare('input_rgb.rla', 'reference/read/input_rgb_rla.miff', q//, 0, 0);
+
+print("Utah Raster Toolkit (URT) RLE image format (gray scale) ...\n");
+++$test;
+testReadCompare('input_gray.rle', 'reference/read/input_gray_rle.miff', q//, 0, 0);
+
+print("Utah Raster Toolkit (URT) RLE image format (RGB) ...\n");
+++$test;
+testReadCompare('input.rle', 'reference/read/input_rle.miff', q//, 0, 0);
+
+print("Portable pixmap format (color), ASCII format ...\n");
+++$test;
+testReadCompare('input_p3.ppm', 'reference/read/input_ppm_p3.miff', q//, 0, 0);
+
+print("Portable pixmap format (color), binary format ...\n");
+++$test;
+testReadCompare('input_p6.ppm', 'reference/read/input_ppm_p6.miff', q//, 0, 0);
+
+print("Adobe Photoshop bitmap file ...\n");
+++$test;
+if (featureSupported("PSD")) {
+ testReadCompare('input.psd', 'reference/read/input_psd.miff', q//, 0, 0);
+} else {
+ print "ok $test # skip PSD not supported\n";
+}
+
+print("Irix RGB image file ...\n");
+++$test;
+testReadCompare('input.sgi', 'reference/read/input_sgi.miff', q//, 0, 0);
+
+print("SUN 1-bit Rasterfile ...\n");
+++$test;
+testReadCompare('input.im1', 'reference/read/input_im1.miff', q//, 0, 0);
+
+print("SUN 8-bit Rasterfile ...\n");
+++$test;
+testReadCompare('input.im8', 'reference/read/input_im8.miff', q//, 0, 0);
+
+print("SUN TrueColor Rasterfile ...\n");
+++$test;
+testReadCompare('sun:input.im24', 'reference/read/input_im24.miff', q//, 0, 0);
+
+print("Topol Type 1 ...\n");
+++$test;
+testReadCompare('topol:topol_1.ras', 'reference/read/topol_1.miff', q//, 0, 0);
+
+print("Topol Type 2 ...\n");
+++$test;
+testReadCompare('topol:topol_2.ras', 'reference/read/topol_2.miff', q//, 0, 0);
+
+print("Topol Type 3 ...\n");
+++$test;
+testReadCompare('topol:topol_3.ras', 'reference/read/topol_3.miff', q//, 0, 0);
+
+print("Topol Type 4 ...\n");
+++$test;
+testReadCompare('topol:topol_4.ras', 'reference/read/topol_4.miff', q//, 0, 0);
+
+print("Topol Type 5 ...\n");
+++$test;
+testReadCompare('topol:topol_5.ras', 'reference/read/topol_5.miff', q//, 0, 0);
+
+print("Topol Type 7 ...\n");
+++$test;
+testReadCompare('topol:topol_7.ras', 'reference/read/topol_7.miff', q//, 0, 0);
+
+print("Truevision Targa image file ...\n");
+++$test;
+testReadCompare('input.tga', 'reference/read/input_tga.miff', q//, 0, 0);
+
+print("PSX TIM file ...\n");
+++$test;
+testReadCompare('input.tim', 'reference/read/input_tim.miff', q//, 0, 0);
+
+print("Khoros Visualization image file ...\n");
+++$test;
+testReadCompare('input.viff', 'reference/read/input_viff.miff', q//, 0, 0);
+
+print("WBMP (Wireless Bitmap (level 0) image) ...\n");
+++$test;
+testReadCompare('input.wbmp', 'reference/read/input_wbmp.miff', q//, 0, 0);
+
+print("WPG (Word Perfect Graphics image, 4 bit depth WPG level 1) ...\n");
+++$test;
+testReadCompare('input1_4.wpg', 'reference/read/input1_4_wpg.miff', q//, 0, 0);
+
+print("WPG (Word Perfect Graphics image, 8 bit depth WPG level 1) ...\n");
+++$test;
+testReadCompare('input1_8_1.wpg', 'reference/read/input1_8_1_wpg.miff', q//, 0, 0);
+
+print("WPG (Word Perfect Graphics image, 1 bit depth + 24 bit depth WPG level 2) ...\n");
+++$test;
+testReadCompare('input2_TC1.wpg', 'reference/read/input2_TC1_wpg.miff', q//, 0, 0);
+
+print("WPG (Word Perfect Graphics image, 8 bit depth WPG level 2) ...\n");
+++$test;
+testReadCompare('input2_8.wpg', 'reference/read/input2_8_wpg.miff', q//, 0, 0);
+
+print("X Windows system bitmap (black and white only) ...\n");
+++$test;
+testReadCompare('input.xbm', 'reference/read/input_xbm.miff', q//, 0, 0);
+
+print("XC: Constant image of X server color ...\n");
+++$test;
+testReadCompare('xc:black', 'reference/read/input_xc_black.miff', q/size=>"70x46",, depth=>8/, 0, 0);
+
+print("X Windows system pixmap file (color) ...\n");
+++$test;
+testReadCompare('input.xpm', 'reference/read/input_xpm.miff', q//, 0, 0);
+# Q:32 mean-error=0.23551931713272, maximum-error=0.989543041912839
+
+#print("X Windows system window dump file (color) ...\n");
+#++$test;
+#testReadCompare('input.xwd', 'reference/read/input_xwd.miff', q//, 0, 0);
+
+print("TILE (Tile image with a texture) ...\n");
+# This is an internal generated format
+# We will tile using the default image and a MIFF file
+#
+++$test;
+testReadCompare('TILE:input.miff', 'reference/read/input_tile.miff',
+ q/size=>"140x92", depth=>8/, 0, 0);
+
+print("CMYK format ...\n");
+++$test;
+testReadCompare('input_70x46.cmyk', 'reference/read/input_cmyk.miff',
+ q/size=>"70x46", depth=>8/, 0, 0);
+
+print("GRAY format ...\n");
+++$test;
+testReadCompare('input_70x46.gray', 'reference/read/input_gray.miff',
+ q/size=>"70x46", depth=>8/, 0, 0);
+
+print("RGB format ...\n");
+++$test;
+testReadCompare('input_70x46.rgb', 'reference/read/input_rgb.miff',
+ q/size=>"70x46", depth=>8/, 0, 0);
+
+print("RGBA format ...\n");
+++$test;
+testReadCompare('input_70x46.rgba', 'reference/read/input_rgba.miff',
+ q/size=>"70x46", depth=>8/, 0, 0);
+
+print("UYVY format ...\n");
+++$test;
+testReadCompare('input_70x46.uyvy', 'reference/read/input_uyvy.miff',
+ q/size=>"70x46", depth=>8/, 0.006, 0.008);
+
diff --git a/PerlMagick/t/reference/cgm/read.miff b/PerlMagick/t/reference/cgm/read.miff
new file mode 100644
index 0000000..237a868
--- /dev/null
+++ b/PerlMagick/t/reference/cgm/read.miff
@@ -0,0 +1,582 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=553 rows=553 depth=8
+comment={ Image generated by AFPL Ghostscript (device=pnmraw)
+}
+
+: mmff 
+
+
+
+BB
+
+XX
+
+
+
+
+
+ 
+
+&&
+
+
+
+
+
+``wwwwwwwwffDDDDDD33
+
+oowwwwwwUUDDDD33
+
+
+
+%%wwwwff
+
+
+
+
+
+77ffwwwwwwww
+
+MM
+
+
+
+
+
+
+
+ppwwwwwwwwww
+
+
+!$
+
+RR
+
+JJDD@@
+
+
+
+33ww
+
+
+
+
+0033
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+""ffUU
+
+
+
+
+
+
+DD2
+
+
+
+
+
+
+
+
+
+
+##FFDD
+33333
+
+wwGG
+
+
+
+
+
+"&p24oALqAXG``wwwUUDD&&q
+
+00ppffpp
+
+
+f
+
+ 0088PPXX}} 
+
+ffDDDD``ww**
+
+RR``>>33))ff
+
+
+
+DDff""ww``
+
+R'
+0X
+
+VV33))ffpp 
+
+wwUU""
+
+UU""
+
+00ff
+
+UU[[
+
+ 88888888XXXXAX
+
+00
+
+
+
+2uDDHH
+wwKf
+fwwD 44**
+
+
+
+bbpp??2XDw
+"H888 
+
+
+
+..
+
+--
+
+
+
+>>
+
+
+
+@@ffwwwwRRffww
+
+ff
+333D
+f0
+"
+
+``
+
+$$
+
+
+X?&
+
+DDDDUU@@
+
+
+
+22Uff--
+
+
+
+
+www w.D
+
+
+Kq3#w7
+
+-m
+
+
+
+
+
+
+
+
+
+
+
+
+ff""
+
+ 8888HHqq88 **DDw.
+
+
+
+
+
+K D
+&&
+
+ffHHqi
+
+
+
+ww
+
+w
+
+DD
+o
+3333""
+
+
+
+
+
+
+ 8 92
+Lt8
+
+
+
+
+
+ 
+ 
+R0
+
+ff3&3
+
+
+
+
+ /9SFG_(FA(: ɀfjExSvPL΀gx
+
+
+
+
+
+"
+
+
+
+UUXX
+$DD2D
+
+
+X
+
+DDLOB
+8ͦnEN Eff
+
+
+L”v33
+ 
+
+mm
+ RpLP-M
+
+
+
+? G( aFhNjEjEjEb7LLLLLLd9T+Lmm
+
+
+(
+P
+
+6
+
+DfKU
+
+LC2
+
+'':.DDDD
+"8
+
+
+(U"
+
+
+HHDDwwffDDww
+
+
+
+ppXX
+
+DDwwqqww
+
+
+D
+D3
+
+
+
+
+h
+#ff
+DD
+DDD0w8w8wH}Haɠ]0f<|X\XI*LLLV&Dw5%ww8wD D
+
+fK
+
+77ff
+"
+
+
+
+ 
+"
+j'jj'jB2B555!888d
+
+``wwDD
+
+L1%
+
+
+ 
+<<<555666* ww2e666633
+DwwwUDD3
+8 `
+ȡ^^^ᯯ
+L
+
+fw-D
+
+X*ppUU`F3
+G 33
+
+
+ ?Ej'jB?X8 
+ӳ
+A
+
+
+F
+555555
+
+(8XLL
+
+b
+ XXXpH2 }
+d)
+晙2D
+
+ @@ww
+
+pp
+
+
+
+@
+
+w
+
+
+G" ""@د
+l O
+
+Z
+DD
+
+
+
+
+
+
+"N8$
+
+
+
+
+  "{&&M%(HYYccwwwwwwwwwwwwffDDDDDDDDDDDD
+zL
+0U
+
+
+
+wwff((DDwwwwww33ww
+33LE,䞑ЬɠɠɈnyA} w3TLG)>
+
+
+
+
+
+
+
+
+
+NKLvx
+  R5ff
+w
+
+
+M
+
+
+
+33
+u 
+D wRD
+
+``DD
+
+
+33""37 
+L
+
+%%DDDDDD
+!
+
+
+
+
+ppww00wwwwwwwwww
+
+
+)w
+
+
+ DRw
+
+
+
+
+h
+3" '
+wKwD1
+
+
+^"H.F9g
+
+Dp"'
+D-f 
+
+
+7"
+YY*H
+
+
+4
+D "
+
+ffUUwwUU
+
+
+
+
+DDww88
+0DD
+`R
+
+
+
+
+
+ kk
+D@hPP
+
+
+""
+w8DD
+3
+
+PPݣw8p
+
+00UUffDDww
+
+pZ-7oJX*LLLLLLg<CBBtLtLh>i?pGg<LLLLJY
+""UUwwf`UUU&2#ob ^KƳS.L
+
+
+
+
+
+ hh w*Z
+
+
+) fXD[3 [֩fwwwD;
+JLLLLLQ"]8jE70( pVɠc\P<Folwwww- L
+
+
+
+
+
+
+
+``
+D
+D23
+Dfͽ_桡kkkkkk[[[@@@"DD33pUU
+L"
+
+``
+
+
+$$
+# I6( 777FLLLLM̌Z 
+
+
+MMww
+J;64!!3555YYYf3w"ff""
+
+DD33
+KߎC
+/>[[
+
+00DD((33
+WLLLLL|X|XLf<ɠɠɠl_|Z$
+
+
+{R
+
+XX
+
+
+
+ww
+7
+YL|XLtLY+wwffDD
+mI(!!
+#?%
+;
+
+
+
+
+
+
+
+
+
+
+``
+
+A.Z.
+
+mmff
+
+ff
+DD33
+
+))ffff
+
+ 00SSAASS}}XXhhwwDDDD33
+
+  @@SS}}XXhhwwDDDD33
+
+ @@SSAAAASSXXXXXXwwffDDDDDDDD
+
+
+
+@@ww33))ww
+
+
+ww33
+
+
diff --git a/PerlMagick/t/reference/composite/Add.miff b/PerlMagick/t/reference/composite/Add.miff
new file mode 100644
index 0000000..441896f
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Add.miff
Binary files differ
diff --git a/PerlMagick/t/reference/composite/Atop.miff b/PerlMagick/t/reference/composite/Atop.miff
new file mode 100644
index 0000000..17c8881
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Atop.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:21/642<85@;7D>8E>:F?<IB@JCALFCNGENGEOIFRKITNLSPLUSNZXR^\Wa_Zhd]ojbsndvoeyrgsiwmwnxq}x~~΃}~Ýþý10.431;63?95B<7D<9D>;HB>JD@LFCMECLGDOHGRLITNLTQMVTOYWR]ZV_^ZfbZmh`pjaslavodysivltjtk}v|~}|~ʂ{|~ś...01/652963<73>97>;:B=<D>>FA@HCBIEDLHEOJIQMLSPNUTPXUR[YU^]Yb]Yga[jc]ng`sjcssi~tjqgqgzp}w}{{|}}xw{}~./1/13433751941974:99<::@>>B@@DBBGDDIHHLIINLMPNLTQOVSQWTSZXW`\Zd_[ha^ld_phcsmi{njlhoislxp|u}{́}vvy|}~.14.25446565753867979878<<=@??B@ACBBECDIGHLKLNLKQNNRONTQQWUU_ZZc]\e_^i_^lb`nhepkiwkhmirkupxq{ty|w~uvz{}~020220463986<96>:8?;8<:;>=>>=AA>AD@DDBCGFEJJINLKOMLROMWQO[VR`[Wc]Zd]Zf^]i__kd`gickhczecohulvnun{rzt{u}vyz{}~45/670:83@=8A>:D=9D=:A=;CAA@ABD>DGAEGCEKHEMLGNNLOPPUQN[TPbYSe]We_Yd_Yd]\f_^na_w^arackgb|gcoirprpwr{u|t|t|u~vx{}894:;5>>9BA<HE@KDBLDAJDAKFEJFEKDDMEELHFNKHPNJRPNVTQ\VR`YSf^Uh`Yia[f_Zf`\ga_gebmddmfclibsjblgrqvuxtwsztxszu}v{v9:4<=7BB=GE@KFBOJEOKEQLGTMGSMETMDUNHVOIROIROJSOKWTN]YPd[Rj`Ul`Yj_Zg`Zfa[ed^mc^mppqojustlqjumwmvowy{||xzw}‚ȁƃČ7829;4AA<GEAMHFPLGQMHUOHYOFWLAWM@WOCWOFVOISOJSQJXTJ_XNf\Pi_Sj^Ui^We_WcbZ`d[hgozbdiZmglfoitmpgtnurtwww}zxzvs}ăą441884<<8BA<KJ@OOGSREWSBTQEYUWWPJUM@UMCTNHTOKUPLWSPZXUb\Ti]Pd^Qh[Vc[Y\aXedZkf`ZbVk[h\h_mgqhrksmqiolnnrovowo{uƂ21.21/874=>8EF<NKCWSBWU@a``gaxWQ^NJJMJ@NLESSJ[WKc[Ng\P`ZN[WOUXUcXU]aaZdWeWh]ibidialdoikfmiplolpmtkumys|y|{~;9286074/<:2CB9PH>]RC\REkixڪߒxw^[gVU`TRRYVF[\MU\VX`haluclkve^f\aVeYcXb[d`gcgdjflgokjeigkioksitlup|y}x}u~yEA6C?5>:1:7.A<6ME?[O@_PBe^pթﱸ߆rkd_}QSZUTRgadrgj_Q^P`VbYd_e`c`ifjgidpkojffiimkoiulunuq}|{zs|v{OI<OI<IC9D>5C=7HD@TM?[M:_U\쬮즨曞ێyorbodjcobhZ\]]^X`VbZb\a[_Zb^d`c^e]i^mfkmikkjnnpormvp~|{|zvyu|wzzWN@WOARL=OF9KB8KG?SN>ZO9^WY碢졨ީ➩枦α~XbUXVS[P`Y[^Z\`\d]\T[W^\c\b[bXeZg^gahckgjjililmjqj{wzz}|wtys{u|w}z}[PA\PC[OBWN?XL?SMCXQB]S>_Y\ʔ֘۔ʊÊsSaVRVZX]XV`_[]]Z]U_V^T_X`\][_\c[f]gdhgh_j_hbkhmhngrjspuv~}zvvqxszu{w|x[N>[O?]P@[P@]PA[PE]RD`SA\TPjfy{{ot`lOXKTYTYaY]YQ\WSQ^UZOZN\O\S[V[\Z][]]b\g]ab^h`jflhpklemhnnmmpmrnzvwsvrxtyt~|[L<\M=]N?[L?]O@_QDbSDcVEaVJ`URe\jrlwQVQBSNQTW]TQSGZTWU^WWKZNZOYQ]V[TXTXWW^Qa[bfjcgchcdihqqkjnlmipiplzwtrtrvtwsxu[K:\L;ZM=[L=^O?`OBbQCcUCcVEeVEeTRh_z~zm{GYRVUSUYWURIQEXQTUb]e\VMVPXUWUX\W_W`Zh[pnwt|dobdf_lgtrnmkglengnitsqoppqqtrtq~~}}\K7]L7]M9_O;_P>`PAaRDaVEbWFfUDhPIldtyuX`P^OWPQRKQETJRNOJTIb[[SXQXYV]NUNUPVT]`nu{lncabZ`Wfbgfomjfjekflispmkmnnopornyw~z{~}y^M:^N;_O<`O=`P?bP=aS@[THe]^reppisszוy}keZ`LRKKTIOEZSWQPIQHQM\TXPRT_e_aUTUSYZ`cbd_`^\ljmnkjqqkikhjhgkjlmljhlklmmmplusw~v~xy{~x}_O=_P@`Q@`Q@aRAbT=_Q?b_d}|}sw|s\XPVWJLNHLFZSneVMNINKWOTKOMUUfjbfgjjm`a]`Y]gmx}u|mkbagejfecchgjhhifihikkjmjpnz~szu{zusx{v~{|~{~|}}~~[M=_QA`SDaTFbTD^RGe\cwww|flzzȧϬۜҡzjplacJMKIOH^TdZLEUTWRNHNJRMWUfhhopvorW[T[djoskn`^`_b`c`ecffeefcgcffghihlimk{~tzpxtwrrotuqz}w|xzw{y|z|~z|~z{}z{|{||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{TH8YM=`SDcWFaUCg_d{ytz`hnvϵqnjniyvlkTRPJPHUJRHYY\ZQMRNTLVKXUX[jphlYW_b_b\]\\][]\a\b_aabccbdaeaecffffhfmlvxmunv{rqssprqntvqw{tw{tx{ux{vx{vxzwxywxyxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDB6KF=]N@aT@f`Zytsp`ajjЗΛƘŖqj{d^Z{\Ta[xt}zfcKEK?PEPJOHQKRLUJXOWRUSb`a\WNTUR[S^P\S\Y\_]`^___``_b^d^d_dbebfcopntjslpkkhmnkmmiqrmtvqtxptxruxsuwsuwtuvtvvuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu47-;;5PE=WN?gflljTT]_xzÆΈ„~{`laaUq^P\^jmˀ|}xMDN>OCLEPGNFQJQHSLTNUOXSVPSNSVRZS[QZS[Z]][^[]\]__\`[a\a\c^d_fdmqfpiqrgiegehiepoiy|usvqqumrvosvpruprtqrsqssrssrssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr*0&,1,;97GE?[]i]^]\xz˂~†ȇ{vr\YdcQgcN^X`golVOI>N@LCHBQEODXQPHRHQIRJUNUPTVRYQXUVVXXZXXZY\[[\\^]\^Z`Z`[bZb]ggencn{gidedfddijdx{qy}uptmnrjpsmpsmoqmoqnopnopoppoppppppoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.2&,/)23-<?3NQPYWmnl܎~|À}ulc`a`OhaQk`O^NYYKKC?H=I>IBIBODOEUNNFPFPGNHNJTPSUOUZ]c`ZXWTWVXXYZY[Y[\Z\W^X_Y^X^[fjbjeifc``b_gb`qtku|qquohkfkohlpilojlnjlnklnklmllmllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkk@>0>=5=>4CF-MN=VUDecg~|xuq{wvn{maZk\Nh_RjaTzbVSHD?A=D=H:L<JBLAJ@OJVRMCOEOHQMQORQQPZZbbXVUTURUTUVWYWYXY[Y[V|[U{\Vv[Va`diceogd^_[cd]lshpsinqjefcdebileimfilfikgikhikhijiijiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhUM>VM?VN@VQ?\SE`XEbZMlcjuiyndl^Y\YXU_YLf\Ll`NidT]TWOF;B<E?F?F=H>J@LAH<KDMIUMRMPNPPMNQORMQJRLSPQSRTTSURUTVVWXZW{XTvYSrYSoYUcc|bbscblf`ej]qvhiodbe_``^__^ab`ficgkdfjdgiefhdfhefhffffffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeecZKe[Ke[Kd[Me[Nf_Lg_Jf^Of^Oe]L`[KTQCPM?VTE]\L``Sa[PR@=H9F;F<F<F=H?KBF8M@IAKEIKJNKNKOLKNEOFPHSNQQPQRPTPUSVVWU{UPsVPpWQlVPkXSu_\p_]ma_ofblpf`c]XZW[\[\\[]]\^_]cf`ehadgbdfbdfbdebcdccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbg_Ph`Qh`Qh`Qg_QjbUibTh`QhbNhbKgbN`[JON=FJ<GM@IOEXQDZSKME:C6D:F;G;G<IAF7H9H@KGNQMLJGLJLF~OE~QGOFMGPMQOSOUQTQ~RPtRMoSMlTNiUOgSNkWTn]Yl_[m^]i^\Z\UUWUYZY\][[ZXZ[Y[\Zad^bf^ad_ad^ac_ab``a_``_````````````______________________________________________________________________________h_Qh_Qh_Qi`Ri`Qj_Zi^^i`Vi`Ui`Xj`ShaPZWHIJ?CH=>I;FI5[L]ZOQE=D:G>H@IAKGJCMCQLQOOMKDwQFqOFkOEqLDrMFsNFwLF{NIOJQKPKwNJpOKkQLhQLgRMdRMdQMlWSjYVlZYl[[ha]_bYY[U]_[Z[VWXTXXVXYW^a[_c[^b[^a\^`]]^\]^\\]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[h_Qh_Qg^PkbTjaSkaWjaUjcPjbQiaVjaUjaUe`RWREIF9?F2zNFEFQRehQOJELHNKOMNPQQPOKLLKKJJCtMDpJEnJFlKFkKFiKFhLEhLEmKFpLGqLFlNHhOIgNIeMIdNKaNKbQNfWSfXUjWVeZXYYTW\T[_VUYRTURUUSUUTUVTZ]W\`Y[_Y[_YZ\YY[YZ[YYZYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXh_Qi`RkaTi`Rh`RiaSiaSiaRiaSiaTl`Rl_Uc]Sc_Q]XGFE0kOBIHGHQPOOIHGBKDJKHKJLKKJHKHJH~FAmIAlIDpGDnICkICiICgJDgJEfJGeJFeKGdLGcLHaLH`LH^KH]KH`PMdVTgUTfVT_ZUW\TV[SUXQQSNQQORRQRSQSSQVXTY\VY\WX[WVXUVXVVWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUg`QhaRicShaRgaRhaSi`Sh`SiaThaTi_TcYPmketre>C4;B3BC8EB8[G>KIGJEDIGJJJJKJKGLFKGGBnG>jH@mF@lG?iG@hHAgHCfHDdHDcHEbIEaIF_JF^IF\HF[IFYIE]MJfSRdUS^VSVUQPSNLOJNPLPRNOPMNOMOPOPPNRSPVYSVZTTVRSURSUSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRgaRhaRjbRgaRgaRh`Rh`RiaShaSg_Rb[R{yuоrFK9<C5@>:596WDDppUSABFHGIGHHFJDHDHCqE=iF=iF=hE>fE?eEAdFBcFCaGD^FC]FB\GC[GB[GDYGDXGDUFBZIFdQP[SPPPLJLIIJHJJIIJIKMJLOLKMKKLKMLKNPLSVQRVPPROPROPRPPQPPPPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOgbRgbRgbRfbRfaRgaRiaSiaTiaTh_Pgea̯sKN8A<3NIHddCAEBEEDEGDFCHDrC>hE=fD<fD>cC?cD@bEAaFB\EAYD@XD@WEAWEBXECVEBSDAQB?VHFYOMKIFEHDFIEHIGHHHHIGGIGIKHJLIIJHIIGKLJQTPNQMMOKMOLMNLMNMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLfcRfcQfcQebQdbQfaQi`TiaTiaRe^P```ǾgdSCJ@zMD?:EBEBGDDBoB>gC>dC=dB<bB=aB>`B?]B?WB>VC?UB>TC?TC?UCATCASCASEBTJGEECCDBDEBEEBEEBDFCEFCEFDEGEGHFHIFFFEIJHMPMILHJLIJKIJKIJKIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHgdUgdVgdVfcVfcVfbUgaXjbUdbPigcȶegSdm`\U>6C=G?}F=iD>eC>eA<b@<^@;\?;[@;X?;V@=T@=S@=S@>SA>TA?SC?QFAYTNRQM>A>AB@AC@AC@ACAABABCABCBBCBCDCDEDDFDFGEGHFFGEGHFFHEGHFGGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEgdUgdUfdUfcUecUdbSgaYi`VccNuxvƾŶɶ|p{D;>7?>q>?cB@ZC@ZB=YA=XA<U@<T?;W><U><S?;Q?<QA>PD@NF?LG?VVOGJD<><>@=?@>?@>?@>?@??@??@??@?@A@?A@@B@ACAACABCACDCCDCDEDDDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBgdUgdUfcUgdVfcUgbTh`YicWcdOfniʼɲ·YKt@6l;4a<6XA:Y?<Y@=XA>V@=T?<U=;R>;N?;L?;F>8HF>JH?JJ@NQI<@:<>;<>;=><=><<><<=<==<<=<<=<=>==>==>=>?>?@??@??@?@@?AAA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????fcTgdUgdVgdUfcUfbTi_YgcWafPbohѿzs[N]C7Q:/Q83S;7S>9Q>9P>8M?;K@:HA:LIA@@8<?5@A7NNDGH@:<6;=;;=:;=;<=;<=;<<;<=;;<;:;::;::;::;:;;;;<;====><<=<======<=<======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ccRfcTfeVfcUecUgaTi`YgcV_eO^ohоû{pPF:H?3JB6IB7FC:CB9AB9HK@<A6;>4>?5II?FC===8:;8:;89;8:;9:;9:;::;::;:::99:98998888888888989;99:99:99:9999999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888[fN^hQeiVfeVhcVhcVfbXcbU_eUs{˽¿QNAD@2EB5CA5BA6?A6>@6<@3?A4DG:EF<AA9A@8@?7=<6::68967967967977967977977977877866766868:6797686776777666666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Bumpmap.miff b/PerlMagick/t/reference/composite/Bumpmap.miff
new file mode 100644
index 0000000..79157b0
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Bumpmap.miff
@@ -0,0 +1,119 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:$$$%%%'''((()))((('''(((''''''&&&$$$$$$$$$$$$###$$$&&&(((***---111444444555666>>>GGGLLLSSSYYY\\\[[[YYYTTTLLLJJJIIIGGGDDDCCCAAAAAAAAACCCEEELLLOOOGGG111***(((''''''%%%$$$$$$###$$$000EEE[[[gggZZZ===>>>\\\uuu^^^CCC###$$$%%%&&&'''&&&%%%'''''''''%%%$$$###%%%%%%$$$%%%%%%'''(((+++///111000222444;;;AAAEEEPPPWWWYYYZZZYYYRRRIIIHHHHHHEEEBBBAAA@@@@@@???AAACCCLLLQQQGGG,,,)))(((&&&&&&%%%$$$$$$%%%"""***===QQQeeeVVV666555HHHdddSSSBBB!!!!!!######"""###"""""""""""""""""""""######$$$%%%$$$&&&(((''')))***+++...222555777:::GGGPPPUUUWWWVVVJJJEEEFFFDDDBBB??????>>>======>>>DDDMMMQQQLLL---((('''&&&&&&%%%%%%%%%%%%######'''AAAjjj[[[666***)))222;;;BBB!!!!!!!!!!!!  !!!"""!!!"""!!!###""""""$$$&&&(((((())),,,///000111666>>>DDDLLLTTTUUUEEEBBBAAAAAA???===<<<;;;;;;;;;???FFFLLL\\\fffFFF000&&&######""""""###$$$$$$"""!!!JJJwwwhhhUUUEEEOOOiiidddGGG"""!!!!!!!!! !!! !!! !!!%%%'''&&&&&&'''***++++++222<<<???AAAHHHLLLAAA>>>>>>===<<<:::999888888;;;AAACCCQQQkkksssYYY>>>,,,"""!!!!!! !!!""" MMMrrrsssyyy}}}lllDDD"""!!!"""######"""!!! !!!"""&&&'''%%%$$$$$$&&&'''%%%&&&222;;;===;;;@@@>>><<<:::;;;:::777666555777???BBBHHH___qqqqqqbbbNNN>>>))) CCClllnnnoooppp]]]<<<###$$$$$$&&&&&&$$$###!!!"""  !!!"""!!!"""$$$'''))))))&&&$$$$$$&&&&&&###"""(((111888888999;;;;;;999888777555333333888???BBBLLL___mmmpppdddYYYTTTAAA(((>>>^^^bbbfffggggggfffXXX888&&&&&&'''(((***))))))''''''%%%###""""""######$$$&&&'''(((+++,,,+++(((''''''''''''&&&%%%'''...999===;;;888888555444555111LLLOOO999<<<DDDRRRVVVbbbmmmhhhcccddd[[[BBB(((!!!555IIIQQQXXX\\\[[[```]]]SSS888&&&'''***++++++---,,,,,,,,,***)))((((((&&&$$$$$$&&&)))+++......+++)))(((((((((===AAA:::FFFAAA>>>AAA@@@@@@@@@@@@777333DDDNNNOOO???CCCNNNWWWIIIIIIRRRVVVYYY]]]^^^XXXUUUNNN@@@&&&###+++>>>SSSSSSSSSWWW___ggg___MMM<<<$$$$$$(((+++,,,------...---***))))))((('''%%%$$$&&&)))+++---+++***((((((&&&888TTT@@@888CCC===@@@CCC:::AAAFFFJJJIIIIIIIII@@@EEEJJJGGGZZZMMMKKKRRRIIIIIILLLNNNQQQQQQTTTVVV___RRR///,,,NNNhhhfffhhhwwwuuuLLL???!!!"""$$$'''+++...//////---000+++'''&&&%%%%%%$$$&&&(((++++++)))(((&&&%%%(((AAA999666<<<:::777<<<>>>>>>BBB@@@CCCDDDEEECCCAAA@@@LLLRRRPPPHHH<<<EEELLLNNNPPPOOOQQQQQQTTTUUU[[[]]]SSSKKKYYYPPP $$$'''+++//////888VVVQQQ999+++""" $$$'''***+++&&&!!! """333;;;999888===AAA===999;;;AAA<<<@@@BBBDDDBBB??????AAACCCHHHGGGAAA999;;;GGGNNNNNNPPPPPPUUUVVVVVVXXXOOOcccDDDyyyuuu### !!!%%%)))000...???kkkuuujjj^^^GGG///)))$$$%%%(((&&&***333111111999999<<<:::;;;@@@@@@???AAABBBEEEAAAAAABBBAAA>>>======EEENNN===999;;;@@@GGGHHHKKKRRROOORRRVVVWWWWWWTTT[[[IIIttt'''&&&!!!!!!'''------777bbbuuuyyyyyylllRRR???333$$$###///MMMZZZMMMFFF999666999<<<@@@BBB???DDDDDD@@@FFFGGG@@@@@@???;;;===>>>>>>JJJCCC999:::>>>IIIAAAJJJMMMQQQUUURRRUUUVVVVVVTTTGGGOOO,,,+++'''###!!!%%%******000XXXmmmqqqrrrmmmfffZZZLLL???:::GGGMMMGGG???DDD???;;;===@@@>>><<<>>>???<<<:::;;;AAAFFFAAA<<<>>>AAA???@@@JJJEEE>>>999:::===:::AAAEEEPPPZZZQQQUUU\\\VVV___JJJ000zzz///...+++((($$$&&&******000TTTggghhhkkkjjjlllkkkgggTTTCCCCCCAAA===AAACCC???>>>???666777<<<???===999777888999;;;???>>><<<===<<<888EEEDDDGGG999999888777777:::NNNYYYVVVUUUYYYZZZ```TTT***www//////...+++******+++,,,000MMM[[[]]]aaa^^^VVVQQQPPPBBBAAAAAAAAA;;;BBBAAA>>>::::::777:::>>>;;;<<<:::777:::@@@888777777999999888:::>>>BBBKKKBBB888666555555444FFFUUUPPPRRRXXXUUUOOOIII999~~~---------,,,,,,,,,,,,,,,,,,888FFFMMMQQQJJJ@@@777===@@@BBBDDD@@@777<<<888;;;666555666999;;;======<<<<<<<<<:::666888===???===555666<<<999888777@@@666111222000;;;UUUXXXXXXXXXNNNFFFVVVNNNqqq{{{kkk______hhhuuuuuu,,,,,,,,,***+++,,,,,,---,,,,,,111===LLLNNNLLL777888???AAAAAA777000:::;;;<<<333666666777===999888888888555888???;;;===999:::BBB888;;;777555555CCC888777888444222OOO\\\YYYWWWIIICCCFFFAAAEEE>>>DDDNNNXXXZZZXXXdddfff*********)))******+++,,,,,,,,,,,,333DDDTTTOOO>>>>>>;;;@@@===222///999<<<BBB@@@333444999999::::::888999<<<HHHMMM===555111999CCC<<<555333000000<<<888:::::::::111EEE\\\XXXRRREEE@@@000===GGGLLLQQQSSSTTTVVVRRR```ggg)))))))))************+++++++++)))444IIIQQQRRREEE???<<<999666///222555555777AAA888666::::::555555333444>>>NNNCCC555,,,$$$000333===555333000222>>>666999888888222;;;]]]VVVJJJAAA:::***EEEOOOPPPLLLLLLNNNPPPRRRYYYSSS))))))))))))))))))))))))///555666@@@MMMLLLHHHHHHDDD:::666555...666666222555555:::777666@@@>>>444222444999888666111<<<===999BBB:::888777888::::::333777777666111666\\\PPPBBB???000---DDDIIIGGGGGGIIIJJJKKKPPPOOO===))))))))))))))))))(((///AAACCC???FFFQQQ[[[]]]AAA888>>>666444///555BBB333222333777555444777AAA>>>@@@BBB777777444???NNNKKK???333777999333666999555333555666555111///VVVIII>>>===!!!+++AAAFFFBBBCCCFFFGGGGGGKKKHHH888'''))))))***)))(((...===@@@777AAAXXXmmmtttpppXXX@@@DDDBBB555222///666<<<///777777111111111222@@@BBBHHHFFF555222===EEEAAA333444333222555666444111333444555444333...NNNCCC<<<666!!!888@@@===???BBBBBB???999,,,)))|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{###%%%(((***)))...======444;;;NNN```hhhfffZZZ@@@333999IIIGGG:::444///222111888999222222///---111111BBB???222:::777333555333333333333333444333111111222444333000444GGG:::;;;+++%%%)))999999;;;>>>;;;666333///000yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx %%%'''---999888000555EEEMMMNNNLLLJJJEEE222))),,,666HHHMMM@@@---+++...000...111000...//////,,,888555---000000111///000111111222222222000///000000222111...===???888222&&&333444777:::888666555444333vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu ###///333(((...<<<CCCCCCAAA@@@AAA>>>///)))***777@@@KKKKKK---+++---...---,,,///,,,,,,------///---,,,111111000//////222///000000111///---...---......000???666999&&&LLL:::222999:::888777444444555ssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)))++++++;;;AAA>>>>>>>>>??????777***))))))222<<<BBB333+++,,,---+++,,,***222,,,+++***+++......000000......111111......///000111///,,,,,,,,,+++***666777444+++KKKVVV888111:::888444444444444777ppppppoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo!!!&&&111CCCDDD;;;<<<@@@===666+++'''((((((+++666000***,,,+++,,,)))******000))))))***)))***///000---333888111---------...///...---((())))))&&&&&&999444000<<<QQQCCC%%%///666333222555555444999lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkk"""***999???666333666000)))''''''(((+++*********+++******+++'''&&&,,,222&&&'''))),,,---...---333777,,,,,,,,,,,,---...------,,,'''%%%$$$!!!---999111***999???;;; ...444111222444666666:::iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhh """###$$$***---***$$$"""###%%%'''((())),,,%%%'''******)))))))))&&&"""'''***---,,,+++---,,,,,,(((%%%'''***,,,+++++++++++++++,,,***$$$""" 111...+++******CCC666"""---444222333222666:::777ffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee$$$$$$$$$$$$$$$%%%%%%%%%%%%$$$###"""$$$,,,---'''%%%'''(((((('''(((&&&$$$%%%'''******++++++(((###"""$$$)))++++++***++++++***(((""" )))((()))...:::###---555333333333777777...ccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb%%%%%%%%%%%%$$$&&&%%%%%%%%%%%%%%%""",,,---%%%$$$&&&&&&&&&&&&$$$###(((,,,(((###$$$!!!!!!"""!!!"""'''***++++++'''""" &&&'''(((&&&+++333222222555777---,,,````````````______________________________________________________________________________$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'''111---%%%$$$%%%&&&''''''###%%%***,,,(((  ###$$$"""!!!###%%%'''+++'''$$$***111000222555,,,+++***\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[["""""""""$$$###$$$######$$$######$$$""" $$$***444+++&&&'''((()))*********)))(((%%%!!!"""$$$%%%%%%%%%000///222---'''+++(((YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXX!!!"""""""""""""""""""""""""""""""""!!!!!! """''''''%%%$$$%%%&&&&&&''''''&&&'''$$$!!!"""######"""!!!---000---%%%''')))%%%VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU !!! !!!!!!!!!!!!!!!!!!%%%555:::(((!!!$$$###%%%%%%%%%%%%%%%$$$%%%!!!"""!!!***///%%%###%%%%%%###SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR  )))CCCPPPQQQHHH///000'''"""$$$$$$######"""###  ))))))!!!###### PPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO ;;;NNNNNNNNNNNNHHH111///IIIFFF,,, !!!!!!!!!!!! ***""" """LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL444IIIKKKJJJIIIJJJ@@@ ,,,EEEJJJKKKJJJ777  $$$ IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHH///AAAHHHHHHFFFFFFGGG<<<!!!999GGGHHHGGGHHHHHH@@@$$$   FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"""<<<EEEEEEDDD>>>>>>@@@888///777AAADDDDDDDDDDDDDDDDDDDDD...!!!  CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB444BBBBBB@@@<<<<<<;;;777;;;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA777   @@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????000>>>>>>>>>;;;666444777===>>>>>>>>>>>>>>>>>>>>>>>>===>>>>>>===000 
+
+
+
+
+
+   ======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<000;;;;;;;;;888000,,,666;;;;;;;;;;;;;;;;;;;;;::::::::::::;;;;;;;;;;;;888222,,,  
+
+
+
+
+
+
+
+
+
+
+
+ 999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888...777666444///******222777888777888777777777777777777666444777777777777777111   666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Clear.miff b/PerlMagick/t/reference/composite/Clear.miff
new file mode 100644
index 0000000..a83a709
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Clear.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuutttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeedddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa````````````````````````````````````````````````````````````````````````````````````````````````_____________________________________________________________________________________________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>================================================================================================<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Copy.miff b/PerlMagick/t/reference/composite/Copy.miff
new file mode 100644
index 0000000..433e0c9
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Copy.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤䟟D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPA陙WN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3ꖖ[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnEݓ[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպŏ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbDvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgGssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJppppppoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpPlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkk@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvViiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeecZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`L````````````______________________________________________________________________________i`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[i`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjELLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHheVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEheVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBheVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/CopyBlue.miff b/PerlMagick/t/reference/composite/CopyBlue.miff
new file mode 100644
index 0000000..de33204
--- /dev/null
+++ b/PerlMagick/t/reference/composite/CopyBlue.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:-./.---.--,*)**''*-//34222435=GFB@;/--++.,+*.3369/31/.,----8GnƦƥna|ƐlS,---,,,--.,**++**+-0-21./34.-<GEA@;-+,++.,**-348;,51/.-...,15\ëìk\g~_S,+,+(*++++++),,,,,-0,---/54+(4=@>=0*--,),--./18DN51../.0/0.+!NƿXHFIO//-)'(**++++-,.*,+,.///-1750-/39@A/,-/-++,.27:@_yW8+*+,/...2,bμмorQ220-)++(+++)),.++)+-121./362/0537<3,+--,)*.7@>R{pG3('++*++1(RJ.-..-,*+,-,,))+,*))*.0-..,/,'-11-22/.//,,*0;DOpyZG3()+,/00@vv~pD--.11.-,00/.,**.0++,/0-//-..)(.74561-+*),-4>EVq|geP0#&*,/-"Hjjoot{lD22458853540/...1320144012440*'-;A;65//.)LV9@IX`r~vxoM)"!&*):RW\chttdC348::<::841330//0002541130JI:H93512BE94HGPCHSZHKV_hnrmkbO((-:\\Yd{_G118;?>><70-/011.,//011/10@]5#5037(28?<?;':OJ^ECOEHT\horoxf3/dƩөeL01369>;67J9+-031496--140/@+!&$'2124)++)%!,IQKA.;DHQVhqwnxndꦦҦn-,/25;84WoO4&).-//*)0-</'%,11*+2*,.+( !,6A>3(-@KKXbt}ztcTɣ죣1-+,269:r䡡졡šXM9(.9QaR<7+-(*042327'(((!"(<M2#)7FHJ\`nzzqgpU۟۟䟟53-(/767jޞžsC7N{P'#*-33197/94)+,%(*-H@$(2I>ISanoxoieTnɜ;:50085.S훛؛_W]R>>5/24/+//)$"0;5043+/JI3+-2-=JavmuxpeAęܙޙ陙??:4175.QN?71;A<:9(+1/)!!&)+.250)$AIK.('*/3Vmpqru|3▖ꖖAA?:9<94TԔ䔔씔ؔДP:CF;FA;10+.3/.*+69%!&/+&)5BS=)*-.*GjgmqlpiEԓ擓ȓՓ擓֓ݓ>>=<<?<8Gu͑bF?>NG5;15)%%(+3318>0'(246&)5/**>1*+&>r~{{ea}gƐԏŏ<<<;;><<AIdĎG+9@J7(88:$(''.'$'266D::.5G46*&+G313+-kd\^Q\QYhty:::9:<<;;:HwwKF@G@.&6;EA(*0/9<<HWcmO5&6N@.$%)B3101'W|aU7Ndmpopoq76679;===:>qqUQG=4*/3+'A3.9>/-+7VpS5$06E0++/@.10,%EtaS1[oqffken:::::79AYmpꄄ̈́|\UA72+>9+'.7.3NG-(3CC8.JQGUA:7=?:*02.%<hdG<Zc`_ddZhvg=?>==79aƁǁRAJ92.?X3+,1))5XQV[B?7VzvN3<<0:?3*/2-)3wcd/>^cWX^[VahV=~~@~~B~~C~~@~~B~~a~~~~~~~~~~~~~~~~~~~~d~~g~~Z~~:~~3~~1~~A~~I~~'~~<~~7~~%~~'~~*~~5~~W~~b}}o}}g}}7}}6}}S}}f}}[}}3}}4}}2}}0}}5}};}}5}}+}}*}}-}}4}}/}}.}}2}}}}p}}d}}[}}&}}0}}S}}X}}L}}Q||Z||T||M||E||4||4|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{{{8{{<{{B{{D{{?{{b{{{{{{{{{{{{{{{{{{{{{{e{{d{{u{{e{{A{{5{{1{{2{{-{{F{{Fzz0zz0zz+zz&zz6zzAzzgzz^zz3zzIzzFzz9zz6zz1zz0zz/zz3zz5zz8zz4zz-zz(zz+zz5zz/zz*zzBzzuzzdzzhzzGyy<yy-yy9yyLyyDyyKyyUyyLyyEyyCyyByyDyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx6xx<xx>xx>xxXxxxxxxxxxxxxxxxxxxxxxx}xxRxxHxxQxxsxx|wwZww-ww#ww*ww0ww,ww/ww/ww*ww1ww4ww3wwLwwBww$ww0ww:ww?ww:ww8ww6ww5ww5ww5ww5ww0ww)ww&ww&ww-ww)vv'vv\vvkvvevvXvv#vv3vv!vv4vvNvvAvvDvvNvvGvvIvvJvvIvvDvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu-uu4uu;uu=uuluuuuuuuuuuuuuuuuuuuuttjttLttDttVttkttttztt-tt#tt)tt+tt+tt(tt-tt(tt-tt/tt0tt5tt.tt'tt7tt=tt>tt:tt9tt=tt6tt4tt4tt8ss/ss)ss&ss$ss&ss%ss4sslsscssjss=ss%ssss2ssss`ss>ssKssQssHssMssJssHssGssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr&rr+rr5rr=rrirrrrrrrrqqqqqqqqqqqqqqRqqHqqCqqPqqcqqjqq@qq&qq'qq+qq(qq+qq(qq;qq+qq)qq(qq(qq/qq0qq;qq?qq;qq6qq8pp;pp5pp5pp8pp8pp;pp4pp*pp)pp'pp!pp&ppMppgppgppOpp4pp/pp)ppypppp\pp=ppNppRppEppMppKppGppJppppppoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo&oo(oo+nn0nnNnnmnnnnnnnnnnnnnnnnnn]nnGnnInnEnnCnnQnn=nn+nn&nn&nn+nn)nn+nn+nn9nn)nn(nn(nn(nn)nn4mm<mm:mmJmmQmm=mm2mm4mm8mm<mm<mm9mm6mm)mm*mm*mm#mm)mm`mm_mm]mm1mm%mm'mmemmmm|mm9mm=mmImmGmmCllOllOllEllPlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkkkk0kk4kk2kk*kk:kkAkkgkkkkkkkkkkkkkkWkkGkkKkkNkkOkk<kk.kk+kk*kk$kk$kk,kk)kk&kk5kkBjj'jj)jj-jj4jj7jj8jj6jjIjjXjj=jj7jj2jj4jj8jj>jj=jj;jj7jj+jj'jj(jj#jjDjjhjjXjjOjj"jj)jj_jjijjjii<ii,iiCiiFiiEiiKiiPiiQiiMiiViiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhhh>hh?hh?hh=hhChhBhhKhhkhh|hhmhh[hhRhhGhhFhhHhhOhhOhhGhh,hh+hh/hh.hh*gg)gg,gg+gg"gg-gg4gg:gg9gg9gg<gg8gg8gg2gg*gg-gg5gg:gg:gg6gg2gg6gg8gg=gg8gg,gg(gg$gg'ggZggVggRffKff;ffqffYff;ff.ff+ff1ffGffJffMffRffGffKffUffWffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeKeeKeeKeeLeeMeeJeeHeeMeeLeeIeeGee=ee7ee>eeFeeOeeYddLdd0dd)dd*dd+dd*dd*dd+dd/dddd)dd*dd/dd9dd<dd;dd<dd4dd&dd&dd)dd4dd8dd7dd5dd3dd9dd>dd;dd+dd(cc(cc"cc*ccJccIccScc]ccsccBcccc1cc/cc0cc0ccKccQccSccOccIccUccYccJccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbPbbQbbQbbQbbPbbTbbSbbPbbLbbHbbKaaFaa6aa4aa8aa>aa;aaOaaFaa,aa%aa)aa)aa(aa)aa/aaaaaa*aa5aaEaa;aa1aa5aa-aa*aa+aa'aa)aa5aa7aa6``9``9``3``*``'``)``(``"``3``G``N``S``M``+``%``<``@``(``/``-``K``P``P``J``V``b``I``L````````````________________________________________________________________________________Q__Q__Q__R__Q^^Z^^_^^V^^T^^X^^R^^N^^D^^8^^5^^1^^)^^F^^Y^^M^^0^^+^^0^^1^^2^^:^^3^^3^^A^^E^^A^^/^^2^^1^^-^^+^^,]],]]*]].]]0]]1]].]]*]],]],]]*]],]]*]](]];]]B]]N]]W]]_]]I]]4]]Q]]5]]#]]/]]/]]L]]P]]N]]P]]`]]N\\J\\M\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[[[Q[[Q[[P[[T[[S[[W[[U[[O[[P[[V[[U[[T[[Q[[@[[1[['[[@[[@[[O[[m[[J[[<[[?[[C[[F[[K[[K[[H[[C[[A[[=ZZ0ZZ2ZZ1ZZ3ZZ2ZZ1ZZ/ZZ+ZZ+ZZ,ZZ,ZZ(ZZ*ZZ,ZZ+ZZ(ZZ,ZZ)ZZ1ZZ@ZZGZZMZZSZZ@ZZ=ZZFZZ-ZZ*ZZ2ZZ/ZZ-YYAYYQYYQYYYYYSYYGYYJYYIYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXXXQXXRXXTXXRXXRXXSXXSXXRXXSXXTXXRXXUXXRXXPXXCXX%XX<XXCXXCXXNXXLXXBXX9XX;XXEWWEWWEWWCWW>WW>WW<WW/WW/WW3WW2WW/WW.WW-WW.WW/WW1WW/WW.WW.WW/WW.WW+WW*WW'WW6WWLWWMWWMWWOWWJWWDVV:VV(VV,VV3VV0VV)VV>VVTVV\VV\VVCVVIVVLVVGVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUQUURUUSUURUURUUSUUSUUSUUTUUTUUTUUPUUiUUUUUUjUU+UU(UU/TT.TT5TTETTETT<TTATTDTTDTTDTT?TT=TT>TT4TT,TT/TT.TT+TT+TT,TT/TT0TT0TT/TT/TT0TT.TT-TT+TT)TT%TT2SSNSSRSSRSSHSS;SS)SS0SS6SS0SS.SS5SS,SS3SSSSS^SSISSCSSISSKSSGSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSRRRRRRRRSRRSRRTRRTRRRRRSRR|RRQQQQQQQQ|QQ2QQ+QQ2QQ+QQ>QQQQUQQ:QQDQQDQQBQQ?QQ;QQ:QQ8QQ,QQ,QQ+QQ+QQ-QQ/QQ0QQ1QQ3QQ/QQ,QQ-PP+PP/PP,PP*PP$PP/PPQPPOPP>PP1PP,PP0PP+PP1PP8PP.PP/PP+PP/PPYPPTPP?PPEPPLPPIPPHPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOSOOSOOSOOSOOSOOSOOTNNUNNUNNQNNeNNNNNNNNNNNNNNNN1NN)NNFNNNNNNNNqNN:NN<NN@NN?NN=NN<NN<NN1NN/NN,NN.NN/NN0NN3MM4MM1MM-MM-MM-MM.MM0MM-MM'MMMM4MMNMM3MM)MM.MM2MM6MM0MM*MM2MM6MM,MM"MM1MMmMMMMM<MMBMMGMMLMMELLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLSKKRKKRKKRKKRKKRKKUKKUKKSKKQKKdKKKKKKKKKKKKKKKKWKK<KKKKKKKKKKKKKKAKK0KK<KK=KK@KK;KK3JJ3JJ1JJ.JJ/JJ0JJ2JJ0JJ/JJ/JJ,JJ-JJ,JJ0JJ0JJ.JJ2JJBJJ3JJ,JJ-JJ+JJ)JJ+JJ*JJ*JJ,JJ2JJ2JJ$JJ:JJjII=II<II;IIFIINII;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHHHVHHWHHWHHWHHWHHVHHZHHWHHQHHhHHHHHHHHHHHHHHHHHHWHHjHHHHHHHHHHHHHHGG^GG+GG6GG9GG6GG7GG6GG2GG2GG/GG.GG.GG+GG0GG0GG/GG/GG0GG1GG/GG4GG_GG[GG(GG.GG-GG*GG,GG-GG-GG.FF,FF.FF4FF3FF:FF@FF8FF@FF9FFJFFTFF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEVEEVEEVEEVEEVEEUEE[EEXEEPEE~EEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDDDDD4DD.DD9DD;DD=DD<DD6DD5DD4DD2DD1DD2DD1DD/DD1DD4DD9DD5DD5DDiDDFDD(DD,CC-CC,CC,CC-CC-CC,CC+CC,CC-CC-CC-CC*CC.CC;CC=CCRCCSCC.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBVBBVBBVBBWBBWBBVBB\BBZBBQBBpBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAA.AA*AA,AA3AA7AA9AA;AA8AA6AA4AA3AA2AA2AA+AA9@@=@@?@@\@@+@@/@@.@@/@@-@@,@@-@@-@@+@@)@@+@@+@@,@@,@@5@@4@@,@@4@@T@@O@@-@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????????????????????????????????????????U??V??W??W??W??V??\??Z??S>>o>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>1>>">>)>>0>>4>>4>>2==7==5==5==G==/=='==+==R==G=='==5==3==4==3==5==6==5==1==-==+==(==*==,==/=====8==(==<==D==0======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<S<<U<<W;;W;;W;;V;;\;;Z;;R;;o;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::;::,::2::4:::::7::8::K::0::*::+::J::D::5::5::5::4::5::8::;::9:::::8::6::2::,::.::.::)::299399199899.99999999999999999999999999999999999999999999999999999999999999999999999999999999988888888888O88R88W88X88X88Y88[88Y88Y88888888888888888888888888888888888888887777777777777777K77-77277377477677577.77077@77F77=77<77977677577577577577777677777877<66:66566666/66566<66866:66A661666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/CopyGreen.miff b/PerlMagick/t/reference/composite/CopyGreen.miff
new file mode 100644
index 0000000..bc3219a
--- /dev/null
+++ b/PerlMagick/t/reference/composite/CopyGreen.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:/023320100/-,---.146:?BABADCAEDC=<@??@A@?===??BDF:52210//,+7Ib|pHLwƚ|V./0110/111.-,/./01358=?>@DE@<GDB<<A???@?>==;>>@DH75322110/*2AY}l>@^ÆpW,-/.,-,,+,,,,--/10253668;ED=9EHE<>A@?>?>>=<;?B@GW?433444320-.Mq=14FSZ----*+**++++-,--..-024459><77;AEEHB@>===<<<<CGEgeB51100022-*cp\pe//..+*)'***)(+-,,*+-132027:67=>ADG??=;<;99:?GEUZ@1),,,-/*)qʹǹd0/110/-*+)('(*--++,/341//393,:A@;B><=?<9;:;GKQ{^:''(((+*'fɶö[3436620.0.()*.010/15895011)*0/9:9?BA>:;>89@GNdf=&$*++'$\V889:=:97750/1234779=>=866955656=BC>A:;>4P[JS`zfzi;)+/&)NqX9:>??AA@?=;::8547<=A@<::<7EGCKF?CE@>CC:<EUYjlS()@MYfj_WPF.3@^}_78=@ACCDB=<=;9779<?A>;:==BK3;?;>D:>>8<D7.Bdcc;BF.,04::AGZ[=Cv˩̩{g358<CGIIEH@;98879=A@?87=?I44A:6=A@@81+0659UUA?;EA>A=>>EJWY]nȦদ֦ᦦ禦Φ0.39?DKKWxT?4229=@@;4416;<;>=;9:?3481/549?CA>9=EFDDBJKMTC{_ӣ飣8304;AJHamI?9=CAEUSGF=A;68:8:;?1--2775CV>::@HGFOFJRXUS`Kܟ柟ퟟ@=625=GFU|\L:9Js]K<9:;<;6><8D?)+22<:7LC99>QENQTVNUWZWOt᜜ΜIG@96=EDLzeNOLH;>>>?>9378339>802557>PE=8<C=HN\fPZrb{uPÙ癙NMIB<@GGNvA<;@F=9@E624;74675584-*15LHM8:;;<@^nggtozQĖPOMJGGJKQi=@>?>G>?=?;:9348;;<993578=>@UG9:<<:VmabndWn哓듓擓蓓NNNMLKLLL_x{mR;3ECB@C4B;9:841,-.((08;=D657.45J>6:7HqsrsVD̐␐ʐǐՐޏˏLLLIKLMPNLSe~q@>@<B<9B;D7;8494,)%'<10+8G6;588Q<9:88kzrM?~KKKIKJKOONKWwe4@CBC;8@8MP64611-*-.Q\807CSC97;8F83094\|kH>aKKKLLLMPPMG]uK?=<>;>839MA:72" !%;cN:6-:8I;888J3.-24M{Y?@YMMMMMLNNX`dxvdM97B:GB664D<0DC/,2>?73OOIUEB<27>12.04HqF<AbOOOOOPL[|}vpLH7:7If@21=7-5RJQV@9-JofR5AE4,5642./5<b>A;_|M~P~~R~~R~~R~~O~~Y~~w~~|~~j~~z~~~~~~~~~~~~y~~l~~W~~6~~6~~:~~O~~X~~1~~>~~@~~0~~-~~3~~9~~S~~V~}d}}a}}/}}(}}F}}^}}T}}7}}6}}8}}8}}:}};}}6}}5}}6}}0}}/}}0}}9}}8}}w}}R}}<}}J}}<}}J}}~}}}}}}}|||||||||j||a||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{{H{{L{{R{{V{{S{{]{{y{{z{{f{{v{{{{{{{{{{{{{{j{{j{{y{{g{{D{{={{<{{B{{<{{G{{I{z7zz6zz9zz:zz=zz:zz[zzWzz7zzBzz?zz7zz5zz5zz3zz:zz;zz6zz7zz6zz6zz7zz1zz3zz0zz4zzDzzhzz;zz@zzMzyPyyByy_yyyyyyyyyyyyyy}yyoyysyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxBxxExxMxxSxx_xxtxxpxx_xxixxxxxxxxxxxxxxgxxVxxSxxYxxyxxxw^ww6ww5ww;ww:ww7ww9ww8ww<ww@ww=ww7wwPwwKww6ww/ww(ww'wwww#ww.ww:ww<ww7ww3ww4ww7ww9ww6ww5ww5wv4vvVvvPvv8vv@vv5vvBvv8vvZvvyvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu7uu:uuDuuLuueuujuuQuu]uu{uuuuuuuuuuuuutZtt[ttWttSttftttttt;tt;tt;tt6tt;tt6tt:tt8tt:tt:tt:tt?tt:tt1tt/tt+tt*tt$tt&tt5tt:tt;tt5tt4ts6ss7ss8ss6ss9ss;ss=ssWss7ssCss3ss/ss4ssYsssssssssssssssssssssssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr0rr0rr7rrCrr\rr]rrZrr|rrrqqqqqqqqqqqxqqWqq_qq_qqWqqZqqnqqKqq7qq<qq8qq1qq>qq:qqGqq9qq:qq7qq7qq<qq;qq6qq1qq-qq3qq5qp7pp6pp8pp:pp7pp6pp8pp8pp:pp:pp=pp<ppKppBpp6ppCpp6pp+ppNpppppppppppppppppppppppppppppooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo2oo.oo1on=nnOnnVnnlnnnnnnnnnnnnnnwnnann]nn]nn\nnYnnRnn=nn0nn7nn7nn5nn5nn=nn<nnDnn8nn:nn9nn4nn2nn;nm8mm/mmEmmVmmAmm8mm8mm8mm8mm7mm5mm;mm8mm=mm=mm9mm5mmPmm=mmImm@mm3mm3mmmmmmmmcmmmmmmmmmlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkkk>kk=kk=kkEkkMkkTkkckkkkkkzkkskkzkkokk_kkYkk\kk^kk_kkKkk5kk0kk4kk8kk=kk9kk;kk7kk=kkIkj9jj:jj9jj<jj;jj:jj8jjHjjZjjCjj:jj9jj8jj6jj8jj6jj7jj?jj;jj;jj;jj6jjIjjUjjMjj]jj9jjOjjjjjjjiTiiHii~iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhhMhhMhhNhhPhhRhhWhhYhhchhjhhdhhWhhUhhVhhZhh_hhdhhZhhRhh:hh4hh7hh7hh6hg9gg:gg<gg5gg9gg<ggHggBgg>gg<gg6gg;gg=gg9gg;gg<gg6gg6gg8gg9gg9gg8gg;gg@gg;gg;gg8gg6ggYggTggYgfcffxffffff]ff=ff3ffCfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeZee[ee[ee[ee[ee_ee_ee^ee]ee\eeZeeNeeHeePeeZee_eeaedJdd4dd=dd:dd9dd8dd7dd:dd=dd5dd?dd7dd9dd4dd6dd6dd5dd6dd8dd9dd:dd>dd9dd6dd8dd<dd>dd>dd@dd8dd:dc:cc7cc:ccRccTcc\ccnccccccc2cc8cc6cc9ccCcccccccccccccccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_bb`bb`bb`bb_bbbbbbbb`bbbbbbbbbbaZaaJaaEaaHaaJaaMaaXaaDaa:aa7aa8aa:aa:aa9aa;aa6aa9aa8aa;aa@aa>aa6aa:aa9aa>aaAaa<aa6aa<aa=aa?a`D``A``8``8``8``<``;``3``A``S``Z``Y``Y``M``2``>``M``;``:``@`````````````````````````````_______________________________________________________________________________`__`__`__a__a_^_^^_^^a^^a^^a^^a^^b^^V^^F^^C^^C^^C^^Z^^]^^J^^;^^9^^<^^=^^>^^@^^>^^C^^H^^I^^E^^=^^F^^C^^A^^:^^<^]=]]8]]:]];]]?]]<]]6]]7]]<]];]];]]9]]5]]H]]O]]S]]V]]o]]v]]V]]k]]Q]];]]8]]B]]]]]]]]]]]]]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[[`[[`[[_[[c[[b[[b[[b[[d[[d[[b[[b[[c[[a[[P[[A[[A[[K[[>[[N[[i[[N[[C[[E[[H[[I[[G[[L[[I[[A[[B[[@[Z=ZZAZZ<ZZ:ZZ;ZZ;ZZ;ZZ;ZZ:ZZ8ZZ8ZZ8ZZ:ZZ<ZZ8ZZ3ZZ6ZZ4ZZ=ZZQZZTZZQZZ[ZZXZZeZZvZZWZZ@ZZ<ZZ9ZZ@ZYyYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXX`XXaXXbXXaXXaXXbXXbXXbXXcXXcXXbXXaXX_XXaXXYXX@XXMXXEXXBXXOXXLXXCXX@XXEXXDXW@WWCWWDWWAWWBWWAWW9WW=WW<WW8WW;WW;WW:WW:WW:WW9WW8WW9WW:WW9WW8WW6WW4WW2WW@WWTWWQWWUWWeWWnWWmWV_VVCVV9VV=VV;VV9VVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUaUUbUUdUUbUUbUUbUUbUUbUUcUUcUUaUUZUUpUUUUUU{UU>UU<UU=UT;TTBTTHTTATT>TTDTTDTTDTTFTTFTTFTTDTT=TT=TT>TT9TT:TT:TT:TT:TT:TT9TT8TT9TT9TT:TT6TT3TT4TT1TT=TSRSSYSS_SS\SSSSS?SSESSJSSASS;SS9SS8SSWSSSSSSSS~SSSSSS|SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRbRRbRRcRRbRRbRRbRRbRRcRRcRRbRR]RRRRRQQQQQQQQQJQQ?QQ7QQ0QQ?QQQQXQQ9QQ@QQBQQAQQCQQEQQBQQBQQ;QQ=QQ<QQ:QQ9QQ9QQ:QQ:QQ:QQ8QQ6QQ8QP7PP6PP4PP3PP.PP8PPUPP\PPOPP@PP5PP3PP3PP>PPKPP>PP2PP4PPMPPPPPPuPP|PPPPPPwPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOcOOcOOcOOcOOcOOcOOcONdNNdNNbNNjNNNNNNNNNNNNNNNNONN6NNHNNNNNNNNqNN=NN@NN@NN>NNBNN@NNCNN;NN=NN<NN:NN9NN9NN<NM<MM;MM8MM7MM8MM8MM7MM6MM0MM+MM=MMTMM@MM9MM<MM:MM8MM8MM9MMDMMHMM6MM-MMJMMMMMMoMMsMMyMMMMjMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLdLKdKKdKKdKKdKKcKKcKKdKKdKKaKKdKKKKKKKKKKKKKKKKnKKJKKKKKKKKKKKKKKOKK8KKAKKBKKEKK?KK<KJ=JJ<JJ:JJ9JJ9JJ9JJ8JJ8JJ8JJ7JJ7JJ7JJ6JJ7JJ6JJ;JJLJJ8JJ4JJ7JJ6JJ7JJ9JJ9JJ8JJ8JJAJJCJJ1JJMJJJIjIIkIIiIIuIIIIVIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHHeHHeHHeHHeHHeHHeHHdHHeHHfHHlHHHHHHHHHHHHHHHHHHsHH{HHHHHHHHHHHHHHHGjGG8GG@GGHGGEGGBGG?GG;GG9GG8GG7GG7GG5GG7GG7GG5GG6GG7GG7GG<GGFGGqGGkGG2GG7GG7GG6GG5GG3GG3GG4GF1FF5FF?FF@FFMFFXFFUFFgFFbFFrFFxFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEeEEeEEeEEeEEeEEeEEdEEdEEhEEEEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDDDDEDD9DD<DD:DD@DDBDD@DD?DD?DD<DD:DD6DD5DD7DD9DD>DDFDDJDDMDDDDYDD1DD7DC7CC6CC3CC2CC3CC2CC0CC3CC4CC8CC>CC>CCCCCVCC]CCqCClCC8CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBeBBeBBeBBfBBfBBeBBcBBgBBiBBuBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAA?AA6AA8AAAAA=AA?AAAAA?AA=AA9AA:AA=AA>AA;AAPA@X@@]@@v@@@@@7@@8@@9@@8@@5@@3@@3@@1@@/@@0@@3@@4@@5@@@@@C@@>@@J@@h@@]@@4@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????????????????????????????????????????d??e??f??f??f??e??c??h??l?>w>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>u>>H>>6>>3>>9>>?>>>>>>>=A==D==G==]==F==C==I==p==`==9========>==>==<==;==;==7==3==1==.==.==1==2==D==J==?==P==P==9=======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<d<<d<<g<;e;;f;;e;;d;;h;;k;;w;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::S::D::K::L::O::N::O::g::L::E::J::g::Y::F::?::>::>::?::@::A::>::@::=::;::6::1::/::-::3::J:9L99I99K99;99999999999999999999999999999999999999999999999999999999999999999999999999999999998888888888g88i88k88h88f88g88f88g88l88888888888888888888888888888888888888888777777777777777g77K77O77O77N77O77O77N77S77e77e77V77T77R77I77B77?77A77C77A77A77B77C77E76E66@66=66D66`66b66M66R66\66B6666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/CopyOpacity.miff b/PerlMagick/t/reference/composite/CopyOpacity.miff
new file mode 100644
index 0000000..71edfc7
--- /dev/null
+++ b/PerlMagick/t/reference/composite/CopyOpacity.miff
Binary files differ
diff --git a/PerlMagick/t/reference/composite/CopyRed.miff b/PerlMagick/t/reference/composite/CopyRed.miff
new file mode 100644
index 0000000..68420b1
--- /dev/null
+++ b/PerlMagick/t/reference/composite/CopyRed.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:0268:989887545511479?FJLNUtǚǴǸDzǭǣǘǒǑǒƓƕƙƱƻƕR:7763/036PƂƝƌlPRuƕzY/0578868887446633467>EHIKMiČĦĺıİĭâ×ÑÐÑÐÑØúÓD99661-052ExÔÆcJK]ÀlY,,012202222113333457:>@CHEUm<;951-,/103IlkH=5>IY,+.//-,,...//00/22238<>AFHQ_y޽ڽWC7/.--/0//4g~iY`|_,+.--,+(*,,**-./0./08<;>AABKhrS<0-2200020eY.//2332-,*+-+,-/./46;=;;>>59Oi{v}w\N=2/-0210+[vO23599:833-/1/110/4;ACA=;<ERF7Rjvvs{z{vedP4*.+)'')W~{~}~oL779<@BA=<:9966669?BHJHB@?<CA<Ec~yuzpksoX?3%+:CThhknksthN89>ADFEEGEDCC<99<BIOPKEA=Gvy᭭íp`譭䭭ۭԭҭԭ­R>Gewnms~dS66=BFHHJMJHFEA<:>EMOOKD>7˪Ѫ着᪪Ԫ몪ڪĪުપƩaHѩԩgW358=DGJMIMHEC?>=>@IPHKC5@̧觧᧧اǧŧ১ߧĦ즦ͦӦদ榦Ӧu1/48>GOMX|[F965:BKPC:0BǤäĤ֤ܤԤڣԣУۣޣǣգ䣣:637<IVTdnL@<AB8:EFaԡҡΡӡסߡ렠렠ҠϠѠ٠ݠƠҠؠՠᠠ꟟럟DA;5:FTW]fR7:RȞԞ᝝۝坝杝ܝ㝝㝝ϝɝНԝ䝝ѝǝӝĝ睝ʝܜOMF?=AMSWoa˛ܛқ暚ΚƚԚٚۚښޚٚњʚۚۚߚ⚚ٚ㚚ܚКšǚΚ暚V홙WVPKFELSVޗ嗗ʗї헗̗ǗȗܗޗߗӗėƗΗ֗䗗闗뗗䗗˗ٗڗߗǗ▖햖Aݖ[[YTTNRWXŔ攔└甔ᔔÔ֔蔔הĔ͔䔔䔔єƔ锔ɔ”ϔԔϔȔɓۓ蓓퓓ݓǓѓ铓uXⓓœⓓ򓓓[Z[XZWXZUdw{f|ܑ鑑ܑƑёƑԑ呑ӑ͐䐐萐Аʐ㐐吐֐ΐԐ}ːԐΐݏ[[\YZ[^^[Y^mɎ莎鎎ǎݎώĎɎڎ㎎퍍퍍ߍ荍ٍݍՍčÍۍɍ͍Ѝ獍g|aeyŌ[[YY[]^^^__a|‹䋋ыڋ΋싋苋֊Šϊ䊊Պ̊⊊׊ˊŠӊފ劊يYe~É\\\]]]^]]acg爈ۈLJчއۇ采҇Ӈ쇇ˇ‡؇ɇLJއ⇇Ɇņ҆Ip|~~^^^^^_^Vaomp脄ބÄńʄބ㄄܄愄ᄄބ߄ل܄ʄ҄Ԅʄ鄄ڄԄރ胃܃̓Nryuvz{{l_____`\_}q|ȁƁ聁Ձ́ځ䁁၁䁁ꁁ끁쁁Ձꁁ끁瀀׀܀܀瀀݀Ӏ\Lu{orxywe[_~~_~~`~~`~~\~~c~~w~~w~~c~~z~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}=}}A}}h}}t}}h}}m}}s||s||l||b||N||I|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{T{{Y{{_{{b{{`{{f{{{{{t{{]{{l{{{{{{{{{{{{{{o{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzRyyEyyOyyiyyeyygyynyyhyy^yyYyyWyy[yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDxxJxx\xx`xxexxzxxsxx]xxixxxxxxxxxxxxxxpxx^xx|xxxxxxxxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwvvvvvvvvvv9vvAvv7vvQvvdvv_vvcvvlvvhvvcvvcvvfvvbvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu4uu:uuOuuVuuguuluuQuu[uuyuuuuuuuuuuuuuu~tt\ttpttttttttttttttttttttttttttttttttttttttttttttttttttttttttttsssssssssssssssssssskss#ss/ss^sssssss]ssmsspsskssissessfssgssssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr*rr+rr9rrErrZrr\rr[rryrrrrqqqqqqqqqq~qqsqq`qqdqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpppppppppppppppppppppppppppppppp3pp8ppDppppppqpp]pprppoppfppgppeppfppkppppppppoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.oo+oo0oo:nnLnnXnnnnnnnnnnnnnnnnnnnlnn^nnfnnjnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmKmm-mmJmmmmmmmmKmm`mmlmmdmmemmkllillfllplllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkk@kk>kk<kkAkkLkkUkkekkkkkkkkwkkkkykknkklkkhkkjkkkkkkkkkkkkkkkkkkkkkkkkkkjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj3jjFjjujjjjjjIii<iigiijiiaiikiiliioiimiiviiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhUhhVhhVhhVhh\hh`hhbhhmhhwhhphh]hhWhh]hhfhhnhhjhhhhhhhhhhhhhhhhggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggff`ffffvffOff;ff2ff;fffffoffjffmffjffqffxffqffffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeceeeeeeeedeeeeegeeheegeegeefee`eeQeeLeeSee[ee_eeeeddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcccc~ccccccccccccScc'cc5cc7cc9cc9ccgccwccpccpccoccxccwcc`ccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbhbbibbibbibbhbbkbbjbbibbibbibbhbb`aaLaa@aa@aaCaaUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa````````````}``w````````````A``'``7``K``=``7``8``h``v``q``p``y``}``b`````````````````______________________________________________________________________________i__i__i__j__j__k^^k^^k^^k^^k^^l^^k^^Z^^D^^<^^5^^?^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^y^^^^^^]]]]]]]]]]]]]]]]]]]]{]]s]]v]]]]]]]]]]]]f]]G]]^]]K]]:]]8]]8]]i]]w]]p]]r]]}]]f]]b\\b\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[i[[i[[h[[l[[k[[m[[l[[l[[l[[l[[m[[m[[h[[V[[E[[8[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZZZZZZZZZZ~ZZzZZzZZ{ZZZZZZZZZZZZZZ{ZZyZZpZZvZZZZZZZZZZWZZOZZ`ZZCZZ6ZZ:ZZ7ZZ8ZZ_YYxYYpYYwYYjYY\YYgYYaYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXiXXjXXlXXjXXjXXkXXkXXkXXlXXlXXpXXpXXfXXfXX_XXAXXrXXXXXXXXXXXXXXXXXXWWWWWWWWWWWWWWWWWWWWWWWWWW|WW|WW{WW{WW|WWzWWxWWuWWrWWoWWlWWvWWWWWWWWyWWZWWUWWMVV9VV8VV;VV4VV8VVVVVtVVxVVrVVZVV_VVeVV\VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUhUUiUUjUUiUUiUUjUUkUUkUUlUUlUUmUUfUUsUUUUUU}UU7UU3UU<UU?TT^TTTTTTTTTTTTTTTTTTTTTTTTTT~TTTTTTTTTT~TT~TT{TTyTTwTTvTTtTTqTTnTTkTTeTTsTTSSSSSS_SSESS2SS;SSBSS9SS4SS4SS7SSLSSrSS{SS`SSZSSaSSaSSXSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRhRRiRRkRRiRRiRRjRRkRRlRRlRRkRReRRRRRRQQQQQQQQCQQ5QQ:QQ*QQZQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ}QQ}QQ}QQ|QQwQQsQQpQQoQQnPPnPPkPPgPP`PPpPPPPzPPNPP5PP/PP3PP.PP4PP;PP0PP-PP5PPAPPsPPnPPTPPZPP_PP_PPWPPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOhOOhOOhOOhOOhOOjOOlOOmNNmNNlNNlNNNNNNNNNNNNNNNNKNN=NNONNNNNNNNNNNNNNNNNNNNNNNNNNNN~NNNN{NN|NN{NNzMMpMMkMMiMMhMMhMMkMMiMMaMMYMMmMMvMMGMM.MM1MM7MM6MM2MM-MM6MM9MM1MM,MM@MMzMM^MMQMMVMM\MMbMMQMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLgLLgKKgKKgKKfKKiKKlKKmKKmKKjKKdKKKKKKKKKKKKKKKKrKKAKKKKKKKKKKKKKKKKKKKKKKKKKKKKJJ~JJ~JJ|JJ|JJzJJvJJjJJhJJfJJeJJeJJiJJiJJfJJhJJnJJ8JJ1JJ3JJ5JJ3JJ/JJ0JJ.JJ/JJ8JJ;JJ0JJDJJoJJGIILIILIIWIIbIICIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHhHHhHHhHHhHHhHHiHHkHHnHHhHHnHHHHHHHHHHHHHHHHHHpHHoHHHHHHHHHHHHHHHHGGGGGGGGGGGGGGGG}GGxGGuGGsGGoGGjGGhGGfGGgGGiGGlGGlGGgGGGGnGG)GG1GG0GG1GG0GG/GG/GG/GG.FF.FF2FF3FF@FFIFFBFFMFFGFFXFF]FF4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEhEEhEEhEEhEEhEEgEEkEEnEEgEE}EEEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDDDDDDDDDDDDDpDDqDDqDDoDDjDDhDDqDDmDDjDDgDDgDDfDDcDD_DDDDQDD*DD0DD1CC0CC/CC-CC.CC-CC,CC,CC)CC-CC2CC2CC6CCDCCHCC^CCZCC,CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBhBBhBBhBBiBBiBBjBBlBBnBBhBBlBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAArAAsAAsAAoAAnAAqAAlAAdAA^AAPAAUAA]@@]@@n@@2@@2@@2@@3@@2@@/@@.@@.@@,@@*@@+@@+@@*@@-@@7@@9@@3@@>@@\@@Q@@+@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????g??h??i??i??i??j??n??l??f??h>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>y>>e>>e>>j>>l>>i>>h>>c==_==Y==e==E==9==E==p==\==2==7==7==7==8==8==7==6==2==.==,==(==*==,==/========1==B==E==/========<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<d<<g<<h<<i;;h;;k;;n;;l;;d;;d;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::h::X::]::\::V::Q::M::^::@::=::G::i::`::F::::::::8::9::9::;::::::::9::7::0::,::+::)::)::6::999899;99/99999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888\88_88g88i88l88l88k88h88e88|888888888888888888888888888888888888888877777777777777m77R77U77S77P77L77H77E77L77]77a77V77W77U77M77C77<77877877977977:77;77<77;66966566666G66G66:66@66H66466666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Difference.miff b/PerlMagick/t/reference/composite/Difference.miff
new file mode 100644
index 0000000..3f55440
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Difference.miff
@@ -0,0 +1,108 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+page=100x80+0+0
+
+:șk^WfowvknsxŖpcZdozyhnqu|sfVgwsdpqu|wjcXjjjrsv{}lgh]Zkstv{{njjimovxy~ymmrrquuy|~{z|{{{y{vy}u|~w~{}~}ygdmnsuy||jkx}wv|wv|ssyqswotxnswptzqu{pw}szu|w~w~}yuvzXQ_LSSTZXZcwxjzpzvu{wu{qqvmosjopinrjosiovhq{kvnxqxr{w}{~|w~r}r|sw}Zj|qWOULRVU\jzuq|wpqwvvyttxrrwnouijsggoefscgxhkxfjhkrxnwqyu{w{x}y|xz}rxnzu{tz~>yDEEHNMQU_gv~xuqq~r{tuxwxzstxpoukjscfn]ar`bvXXX74<?Y_Hkqdw{{z}{~xyswmvkvu{|yK}B?CMZSOU_alp|}qvuu{~wqshjqmpvqsxnpxjks^fpT_nWbnJM>O"'gY--:IJ0eh\ppfsvvqtqpyrxxqhrg^rijaryBt}?zEyI}Sabafiov{zpqsx{oosy[_j_cmfjsloxhms^flR^nQ`mMTA"L#.j-4j26k%%_9<=OW$`dFuslttvcif@M19E<F_KQliEwAzIzSz`zi|gn|~p~lq{zvnnru}wqtx~{MSaPVcX^h`enbin_chV]kQ_rOXR*!6 'h+-m/0m)+i!$a/.RF>9RO6:bUNb\ieY]ibWsqfrrWrxMs}Vt|_u{dyf}g{k|ifd~n|~~ru}xv{|~zwtsww|~BKZDM[KR`QZgW`jY]eSXhNYoMTQ' 5 !f##o%-o'.d10j(4q+2[@@.\h_iljcnqQkvWhpkoldrpXosWmtQwZz~gy{jv}kyf{`{b{g}m~u}xzypwz~x}|{|}utttuy}}~;FU<HV?KXEO^FR`MT^KRaGRfHNK'''LZ&b%S)#N,.AHD#bgY`ejehdahcNik\deiki_knTnuSmvPpz^rymswkwznx{ev}[u~bvyuvxfyezl}o}o}m}o|w||||vwz|uqpqt~~z{~}}~~8ET:EU:GW>IY>KZBMXBM[AN`GOS;@--,%':"$K..9A;.1RE[d\vkbf^dkaY_c_FelRdi[oqUfoQlwSnzVnzcpymsxxut}yu|yvxyt}|q{}ykz~iw~uvzwvzntzi{n|y||zv~txy|p}mopw~vvwuywzy~|}~~5CS6DT6EU:IW:HW;IU9IX;GY?JUBMO?H93:"&E%):45.=\WN_mg^cvb_i^YLdg<frTahdgi\bhPkwWiu[lvgowsmsnpxtuzyxy{ztryzswqmxwsxs|{ytvwxppsxyvwytz~ozpzysvt{~v|x}u~sttpotrwu{~zy{~}1AR2BS6CS7FU6EU6GT6GU7EW9FW9HY:KN:C(%)%G'p;-xbQdZVWY[nZW_[]Daj<dpZ_foecmY^bXaVir`kqmknsnovoj{rjytjwse|s^|bZ^Vxpfmurbrzknsuhjrpqntylv}du}gw|utuyyz{{}}}{}t}|tulkpour}x||{|xzy~|}~~->R.?S0@T0@T1AS3BR3BQ5AR7BR4EV4LS2:* ==2s+/zMFqXJiZRa\[S[b?^jH]g]beffkebnoW^a_hcdkrgfyjc|tm~vnzupvtk{i[VPyb`hlnVowMs|^nshpqrjlmqumrwgsxmtwworywxyxzyy{uz}vuvkkmkvp{u}|y{ywvzvzyx|z{}}}~~~(9K):L+;M,<N-=O.?R0>Q8?K087%2'(0&'!3j*SD'"j7={JDsZTd\\RU`@[fOSYVX^Z`hhaklcgkZbi`huhf~]Wy^\qjkolonjiodblecojiglnk`cmbajefwaaqijpkntnp|rn}qnypqvtw}uuwv~wwuvzqsujjlivoxqryxwtzttwuwwwxyxyzz{{{}}}~#3E%5D&6F'7H)8I)8O.=N-0+*;"AN+,PF=DRD+B*BRGPsKJmYW`W]NZaOOV]<FUW_faembel[cn`hvfivbbwSOsXTtUSuTRj`_uebvkfy^YOJTMu^`oklrgirfjtno~qlokxopups{rs~sr}ttusvmrteg~lhtm~tnqvxurwpqsqtttuwuvxwxyxzzz{|{}|}~~$2B"0@#0?#1?%2C*6B%.&&B)#?]=:aigDzu6pm=HF*7"2a-1y><pWTeXZRV\QHRbCMa^eqVXmV\magrcgj`ed^`vPNzPIJD}LI{fb{jd{]W}SP{YVqfhughqgjohkuhjvhhwkkrloulp{op}pn|pquormpq}cb~lf~qjspmsswsruolroqrrrussusuuuwwwxyyxz{z{||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{(4D$1A ,<*;".@%! *?)!<L+/gNPnbaab^UQHL!$%&*.5+0l"%02yKMiQVWRY[OYcT]nMNnMOmY]oZ^bZbYZebY]f[XyKEuNKp_az[Wu]Zsba{ccwdfwegrchrdgufgvgfvhirhktinxlmzlkzmmsmoqjj{c`|ne{mfelmlmpopsomrmlpoorppsqrssstutvvuwwwxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx57C05>.<)=&
+ 5%#1I i11h65b62b5/\/&R!(069!9BN6<u"%(&w79]SYVT`_Q\fSYcU\kU[lV[_U_^S\`V[^Z\lMOhQVf]eua`{d\}f[~i^~h_ydaq`bq`cuccwedsegpeiqektglwhjvilqjmvbaze_zkbpjelmplknnnqkjojhmlkommpnoppprqqssrsttuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuA>H<<B)3<#-;"++$"7\!!i%$_# \$a)#Y&"D!/"./:!3Aa85r+'x-),'[LVUM]]NZhRYbPYbS\iRYaT]`S[bTZcUZfSXcW]k\a|]Y~`X|aX}dZ}d\w^[n]^p]`u`awa`qadmbfobhodiocindjodfy_Zxg^we]_igmkmkknefljlfehgihlikljmmlmnnoooopqqqrrrssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrHBLHCH;=?028 0e!xi![! c)!j+&V!*.2():&*?J17w0*|#&j=E_LW_IWiMUhRX^KV[NYlGNePXbPZbS[fS[kQXlSXvVT|YRv\UtZXyYXvYXpZ[nZ\q[[u\\w]\p^_j^cj_dj_eg_gh`fr]]waXwdYdb`ffffhhecigj`jnfbfeffifiigjiijkjkllmmnnnoooppppppooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooA=IEBG@?E75A'$%
+ 6+(y-*c""[++a-&U$2!$%&7 '6):/,=u34xCCmMPmITgIUqKRaLTZHS_ITlEL^MV`MWdNXgRXkSXsPSxRPuWRuMKvGItQSpVXoVXpWWrXWtYWt[YmY[d[`cZ`c[aa]cc_bvYUu_Wi]X]`cdcf`df_b\elabf`dafbcfbffefgfghgihijjjkkllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkk,.</0810;.*C$#5/!N-)hH@!@#%$3#0#/)$0F4?lEJtILsGNkERbBSkFNXEQVHSkEJu?CVIT[JSbKRkJNqLNuMNtOPyHGsAAfLOlQRnRUpSUrUTsURrVTrWUjUW`W\\X^\X^X[`dWXtTPiXUXUX_^c\ZbX_X_bX^aZ_^abad_`b_ccbddceedfefgfghhhiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhh+*+.)+$ !#!-//*0#+M*2N=GdBIsAFqAHlCKiBLkBKXALNFR_ELlDIi=FjBGlEHtGGwKJrIKbIN\LS_LRjLOtONrPNpPQpQSpQRpRRoRQfQTZTYVUZSV\RX\fOObQQ[RSUPVSUZ]bUW]VYW]^]___`_^`[^_]a_^b``baacbcdcdedefeffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee    ! $  "%(!$2&)7"$3-'= j-,k>AW8Gg;Gp=Gl>Hl@Hl?H\=FECQQ>K_DKiCIvGDuFCwGDxHEkIJVHQTIR[IQjHLtKKuMLrMNoLPmLNjMMdMOYQUSQWQRWOSYOSXZNPWNQVNPXOOW[RSPW\Z^ZZ[[[\[[]\[]Y\[[_[\_\]`^^a_`b`ababbbccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb      #"'#%5.*7/(5-(1 &4W&/.e7Aa:Gk:Ej:Ej:Fk<F\<CB?ND>N\@Hn?By=:j?@]DF[CEPDJNBLPBLSEN\HNhFJrGIqGKlFJdHK[LNRMRNMSMMSKNTJQVQNRTJMTJMVKMTLOSPWYVYVUUTSUWWZXXYYXZVYXY\XZ]ZZ][\^[]_\]^^___````````````______________________________________________________________________________
+     &'&1/)45*8.+?A)|)&k4<f6@j5=l5=m6=i59W7>[5?p37x36i79N<DE8C@;D;<GBAHEAHHAILDJSDI\DI_DI[FKSIMMIMJHNIIOHJOGKPIMQRIMQHKTHIVIHTLHKONOLSLNNPOTTTWUUVVUWTWTVZUWZVX[WY\XZ[ZZ[[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[       '$'4/(=4"*b,+s!!#&w#&m,1n,0q+.t+-x.+u+,x./{43v45g68N9@C8@A;A?=@?=B@>C>?D?@GAAHFBHKCHMDJIDJGDJGFKFIMGILEJMGHKMCHNCGSEFPEFFFKIIMIMLNJRQOSQPRRRSSRTPSRTWRTXSUYSVXUVXWWXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXX  
+   !""%&;(*H$%V'&dk""o)*m,1i*0r++v/+v.,v./v12u13h35M8=>6>>8=C;>B:@A;AA<B@=BA>BA?BB@DC@ECAECBFBCGBEHBFIBGKFDGL?BPABPACJEDDHFEIHGGKLJOMMOMMOONPPOQMNOQTNRUPRUQRTSSUSTUTUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU       '%OLF\XP10"+%4.'6((2'*3&/Q"%r(%t+,v(*v))u**r*+n*/m,1o.1X27@3<>4<B7=B7?A8?@9?A:?A:?@<?@=A@=AA>AA?C@AD@BE@CF?DHDBEN<=M>>IA?BABDAFIFKHFJGFJJIKKJLLKLLLNKJNNQKOSMNQNOQPPRPQRQRSRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
+    740uww~xNC3,*#2')-3/3&&n88nw,+y(&u('t*)o)+k)/r+0`,2E19>1:@2;@4<?5;?6;@7;@7;>8;=:==;?=;?=<A>=@>?B=@C<BEB@CM;:F>;=<ADADFDFFFFGFHGEGFCGIGIJIJIIKIGKLOILOJKMLLNLMOMNONOOOPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO ! # ## $"hnorNU7*"'0OKJ{ts11e')j&(p''p)(n'*q),b)-H.3?.5>/7?17>27?37?27?37;4996;98<:8<:9<<:<<;>:>A9@D@;>C97:<?B?CA?BA@BBABCBDECEDADDBEFEGGGHFEGJMHHKFHJIIKIJKJKLKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL 
+  $%&$Xbg~j0-JKEx\PX"](-k$'j$'l#&\(*G*/?*0>,1?.4>/4>04>04<2583683774985986::79;8:;8;<8;?57::<=<>=<>==@>>A@>A@?BA@BB@BA@BB@CDCEBBCFIFDFDEGEEGFGHGHIHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHH  !!#%( $"*($U[b~e02/8,ospytb0)[&.f"(g'U!)C$*?&+@).>+.<,1;-2:.2904703703724825935;36;37:06C>8=<7;9;:8::9;;:=<;==<===>>=>?>??>?@>?@>@??@@A@ABBBDBBDCDEDEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"# # $!$!$"("+"%&9<:{{fdaTutqiSGS&b$*]#%L%$?"$7"%8$)8&*8',6)-5*.:-/8.08.17.17-18,07.2602AA:36086875875887998::9::9;;:;<;<=;==<=><>><>>=??>??@?@A@ABABBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB%"&#&#'%(%)%+#.')*-40wz~t|pb]3&O(I$*?#*7 '9"%9"%:"%8$'8&)9)+7),5(-3)-.+11/,42,44,:=51-4213314324436646657767878989:9::9:;9:;:;;:;;;<<<=<==>?>??????@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????'$)&*'*'+(,'0& .+)/+82r|ur}qeXQ:-<"$2",2$)5"&6!%5!&5"(3$&2&(0((52))*,))0+,/::035-.,2.,..-0/.00.10/1112213434545656767878878888888999:9::;:;;;<<<======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<''+(,+-),+0*2)"1-!*0*;4|lxri}tsldh^S4*,#&/'$/($-*"+*$*+$15*'+(&)+*++65,41+,,**++*+,,,-,---.-./..///0/000111323434545655656676677788888999999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888#.&0.20/ 3- 3/"2.$0/"-3#ANJ|}vh|sm~xtrf63&)&"+( +)!*)!)*!(*"'*%*-%13&24)//'/.'/.'-,(++(*+)*,**-++-+,.,-.,./-/0//1/010010122352463353454565666666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Dissolve.miff b/PerlMagick/t/reference/composite/Dissolve.miff
new file mode 100644
index 0000000..40e8ce1
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Dissolve.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:ȢijǴʵ̵͵̵ɶŶķķø¸ºº»żżýŠ²Dzɲ˲ʲų¸ùİǯư­}}}}}~~}~z~z~z~{{|||}{~|}~~~~{w{w|x{x|x|y|y~y~y~y}}z~|~}}}~~}|z|y~|}}}{}|~}}}~~}~~}yt}yt}yt~zu~zu~zv~zw~{w~|w{wzx|~z}y{zzzxzw{xzyyx{x~||z{z{|{}y{y{y{z}}~}~|}{~~{wr{wr{ws{ws|xs|xs|xszxv}{{}~~|z{vxvvxuwtzxywwuwuwvzxywwx{|{{xxxxyy{|{|{{zz~}~~}}}}}}}}|}}~~~}|}}}~~~~}yuqyuqyuqyuqyvqzvpyuqzyz~~xwuvwsttstrwv|zvttstsvtvtttvvz{yzz{{|xyxxwxz|~~|{yyzz{zyyyzz{zzzzzzz{{{{{|{~}}~}}~}vrnwsowtpwtpwtpvspxvx}}}~xz}}}y{zwwqrqqrqvswuqptstsrprqsqtsxxxzz|z{tusuwxz{yyvuvvvvwvwwwwwwwvxwwwwxxxyxyx|}{|z|z{zzyz{z|}{|}{|}{|}||}||}||}||}||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{qnkspltqmurnurmvtu{{y{tvxz|}}xxwxvzzwwqppopnqnpnrrsrpopoqoqnrqrsvxvwrqststsssssrsstststtttttttutttuuuuuuvvyyvxwyzxwxxwwwwxywyzxyzxyzxyzyyzyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxkkhmliqnjrojsrpxw~wvrruu|{~}{vtysqpxqorpxwyxsrlklinknlmlnlnlolomononrqqpomnnnpnqmpnpopqpqqqqqqqqqp~rprqrq~rq|rr}uu~tv}su{tutsstttttsuutvvuvwuvwuvwuvvuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuueecffeligmkgqqssr{mmyoovvyyyyyxxwyxxwvorpomsoknorswvvujhkgkhjhkikhkikiljljlkml~lkljllkmknkmkmmn~nn~nn~nn~nn}nn{om{om{onzonzpnypo{rs{przqsspqpppppprrquutstrrsrstrstrssrssrssrssssssssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr`a_`b`dccgfellpmmvll{stvvuuuvuuwuwutsvrlknnionh|lkmoppjigdhehfge~if}hfki~ig}ig}ig}ig~jh~jhijikij~jjjj~jk|jj{kk{kk|kk|klzlkxlkwlkwlkvmkumkxnnxmpxmpsnnmmmmmmnomrsprsqpqoopnpqoppoppoppoppoppopppppppppoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo^_\^_]_`^bc`fggiinnnyvvvvrrssuuusrpvnkkkkflkgmkfsjfiieecbdbebdc|eczfc{fd~gfzfdzfdzfd{fd{fe}gf~gg}fg|ii|kj{hhyhgyhgyhhyhiyhixhivihtihsihsihrihrihvklujlrklkjjjjikjjnnloqnnomllklmkmmllmllmllmllmllmlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkka`]``^``]ab\dd`ffajijqp|sronznmwonwnlokhgkgdjhekheoifueb~a``_a_}b_zc_|b`wc`vc`{db}educavdawdbydczddzddzdd{ffyhhufeveevedveeweevefvefuefsffpfeofenfemfeohgshjphikihggfhhfjlikljkkjhihhhhijhijiijiijiijiijiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhca^da^db^db^ec_fd_geaigikhljgiededdcedageaifahgcnecudau_]y^]}_^|_]z_]y`]y`^t`^q_\u`^xa`wcawbawaaxaayaawaasb`qa`qb`sbaubbubbtbbsbbsbbsbbrccocclcbjcbicbicbmffleejfehfefgdijggifefeeeddedeeefgefgffgffgffgffgfffffffffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeedb^eb^eb_eb_eb_ec_ec^ec_ec_ec_db^``\__[a`]cb^cc`ndby_`y[[s]Zw]Zy]Zw]Zw]Zw][r^\l]Yo^[r][t^\w]^v^^v^^v^_r^^m^\l_\m_]q_^s__s__q__p`_o``n``l``i`_g`_g`_f`_ea_hbbfbbfcbfdcefdbcb`a`aaaaaabbabbbcdbcdccdccdccdccccccccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbca]ca^ca^ca^ca]db^cb^ca^cb]cb\cb]a`\]]X[\X[\Y[]Z_]Zq_^{\\tZXrZVuZWtZXt[XsZXo[YhZVi[Wn[Yr[Zu\]p\\m[Zl\[i\Zh\Zh]Zi\Zj\Zm]\o]\o]\m^]j]]h]\e]\d][c]\b]\b]\c^]d_^c`_c`_b`_^_]]^]^^^_____^__^__^`a_`a_`a_`a_`a``````````````````````______________________________________________________________________________a_[a_[a_[a_[a_[a^]a^^a_\a_\a_]a_\a_[]\YYYVWYVVYUXYTi]Yw^]xZ[rXVpWUqXVqXVqYWpYXkYWkZWpZYr[ZnZZgYWdZXcZXaZWbYWcYXcZXdYXeYXgZYgZYfZYdYXbZYaZY`ZY`ZY_ZY_ZYa\[`\[a\\a]]`^]]^\\][]]\\\[[[[[[[\\[]^\]^\]^\]^\]^]]]\]]\\]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[_\Y_\Y^\Y_]Y_]Y_]Z_]Z_]X_]Y_]Z_\Z_]Z^\YZYUWVSTVQcXVnUVrXYw]^rXXoWUoWVpXWpXWpWXoXXpXXpWWoWWjWVdVUaWU`VU_VU_VU_WU^WU^WU^WU_WU_WU`WU_WU]WV]WV]WV\WV\WV\XW]YX]YY^YY]ZYZZXYZXZ[YYZXXYXXXXXXXXYXZZYZ[YZ[YZ[YZZYYZYYZYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXX\ZV\ZW]ZW\ZW\ZW\ZW\ZW\ZW\ZW\ZW]ZW]ZW[YW[ZVYXTSSN]VRdTThTTkVVlUUmTTlSRkTSmTTmTTmTTlTTlTTkTThTSaSR]TR\TR]SR]TR\TR\TR[TR[TS[TS[TS[TSZTSZTSYTSYTSYTSXTSYUTZVV[VVZVVYWVWXVVXVVWUUVTUUUUUUUUUUUUVWVWXVWXVWWVVWVVWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUZXTZXTZYTZXTZXTZXTZXTZXTZXUZXUZWTXVT[ZYddbhge\\YOPMNPLPPNQPMVQObRRjQRjQPjRQjRRjRRhRRgRQgRQgRQaQPZQOYQOZPOZQOYQOYQOYQPXQPXQPXQPWQPWQPWQPVQPVQPUQPUQPVRQXSSXTSVTSTTSSSRRRQRSRRSRRRRRRRRRRRRRSSRTUSTUSSTSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRWVRWVRXVRWVRWURWURWURWURWURWURVTR\[Zkllstttttqmk`^YOPKLNJMLLJKJSNNfYYfRRhMMhNOgOOfOOeONcONeON`OMYNLWNLWNLWNLVNLVNMVNMUNMUNMTNMTNMSNMSNMSNMSNMRNMRNMSONUQPSQPPPOOONNONOONNONOOOOPOOOOOOOOOOOPOQRPPQPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOUTPUTPUSPUSPTSPUSOUSPUSPUSPUSOUTSeggsssrrrqqqqqmlnf]_WMNIKJGNMM\[[jjhkfedTT`KKaLKbLLbKLaLKbLK^LKWKJTKJTKITKJSKJSKJSKJRKKQKJPKJPKJPKJPKJPKKPKJOKJNJJOLKPNMMLKKLKKLKLLKLLLLLKKLKLLLLMLLLLLLKLMLNOMMNMMMLMMLMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLRQMRQMRQMRQMRQMRQMSQMSQMSQMRPLPPP^abmoonponnkmmknnjhfaRQMIKHXXWhffiiiiiihhgb[XZKI[HG^IH]II^JIYIHTHGRIGQIGQHGPHGPHGPHGOHGNHGMHGMHGMHGMHGMHHMHHLHHLIHMJIIIHHHHHIHIIHHIHHIHHIHHIHIIHIIIIIIIIHIJIJKJIJIIJIIJIJJIIJIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHPOLPOLPOLPOLPOLPOKPNLQNKOOJPPO[\^hijnnnmmlkkijkikkhcc]OPJOQN^__hggggfffffffeeeb_^YMKWECYFEYGEUGEPGEOFEOFDNEEMEDLEDLEDKEDKEEJEEJEEJEEJEEJEEJFEIGEKJIJIHEEEEFEEFEEFEEFEEFEEFEEFEEFEFFFFFFFFFFGFFGFFGFFGFFGFFGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEENMINMIMMIMMIMLIMLIMLJNLILMGQRQdfhlllkkkjjieecceaefa__ZYXU]]\ccceeedddcccccbbbbaaa`a`XRORDBUCATCCOCCLCCJDCJCBICBICBHCBHCBIBBHBBHBBGCBGCBGDCFDBFDBHHFEEDBBBBCBBCBBCBBBBBBBBCBBCBBBBBCBBCBBCBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBKKGKJGKJGKJGKJGKJFKIHLJGJJEKML]_aiiihhhggecd`bc^ba\_]Za__dcdcccbbbaaaaa````___^__]^^]]]YVSQGCNA>L?>I@>GA?G@@GA@GA@F@@F@?F@?E@?D@?C@?B@?BB@CB@CC@DEC?@??@??@??@??@??@?????@???????????@??@??@?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????IHDIHDIHDIHDHHDIGDIGEIHEGHCGKIY[]fggfffeecbc_]^X\\W^\\b`aaaa`````___^^^^]]]\]\\\\[Z[[ZZZZZYYVSPMKEBE?<C=:B<;C=<C><B><B><A>=A>=@>=A@>>><=>;>><AA?@@><=<=====<=====<=========<=<<<<<<<<<<<<<<<<<<<========<===============<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<FFAFEBFFBFEBFEBFEAGECFEBDF@DHFX[]dddddccc`_`\XYSVTR][]___^^^]^]]]]\\\[[[[[ZZZZYYYXYWXXWWWWVVVVVVUUUSSQPOLMKH@=:>;9><9><:=<:=<:<<:>><;<9:;9;;9>>;=<;;;:::::::::::::::::::::::::::::::9:99999999999999:99:99:99:9999999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888AD>BD?DD@DD@DC@DC@DC@CC?BC?GJIWYZ`aa_`^]]YYXTTSOTRPYWY\\][\\[[[ZZZZYYYYXXXWWWWWVVVVVUTTSRQTSSSSSRRRRRQQQOMMJ>=::96;:7::7::79:79978969:6:;8:;8997997997887877777777777777777777777777777776676676776776676676666666666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Divide.miff b/PerlMagick/t/reference/composite/Divide.miff
new file mode 100644
index 0000000..dc40ea9
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Divide.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:=;9?=:D?;GA:IA9H?9G=9H>:G=9G=9F;8C95B84C95C95>91>:1B>5FB9IE<PJ<YPA^TBaS@cT@lS@WBUASCXNWZUYNTLRRKP<P9R9S7R7P:N8N7N6Q;QAUAWEZIiJ<JDAF@?F@<E?;A=8<<9=<9A89E79gFH^[~Ջg\ia|ƹrnj<;8><:D>:G?:H?8H>9F=9H?:H?:H?;G;9C:6C96F=7F;7B=6B>6C?7FB:GD>PH:YOA]Q?^P;aS=dXBYCS;N:\NX\UYNTNSTLQ:Q7R9S8R8Q<O9O6M6Q:QBSDXI^MXG9JEEJB@FA=FA<@@::@<>><E=<A69ZA@UEtx߁`QbSxyz|trm::::;8?>:@<8B:4B;7?:8B:8B88B:8B:8@:8@:6C;:C;:C>:C@:D?:FB;HF?LC:QG;TG;XI;_M>[[FpYDP8K4[D_P[UORRQV?U7S;R;S:R6R:Q;O;N=S>WAUJ^ZsgOSFNEAKC=FC=AE>;E=:E?>C>AB???=C;9`=+fg`QQAuFE`R]]anavxi;<?9<?=<<?<7?84<95;88;88=99=99=99?99?<<@;;@<=?<8C=;C=9C<;D@=KC?PE?SE?WG<]LAaSJmPGJ@J<O?WD]L]VaWY?V;S<R?R<R:P:P;P>PCZJ_N]VuuZYKJG:?B8>B:<@;<@??A>AC>?C>?=CF8;x|˽m<@D:@D>>A=>==:7<9::7:65699:<9:<9:977967=:<>=>@<:A<:>97@::A==LCCREDPDCUA?YD@YKEZOJfJDK@SAUHYE]KaRVEV<S:P=R=P<N8N9O?VKaW^Utpƨ꿜r|aRXFBC7>85D<;D<;B<9B>;B@;D9CB87qѷݵzf?B?AA>AC?EC?FB>FA<E>:>:;<;<:8>;7<>6<;78=:9>>;A>=@;:A;9H=9KA:RG@UHBRD>RA@VA@VG=IOAOG=n=6P>ZDYDR>[EVESAU@WASAO=R=P:RBbRi_qnʹ¿Ʀҩ~mcUQGF68A69?8<C8=F8AD<CC:C<6+Y͸Ɯn_FG?GI?JG@PLEPLEQF@NC?HA>HDD?ADB8BE:AB;>EA;ED;DEABDDIB<SE<\K>^OB\PDVK?SDBUEBaE?t:Ac;AMD:tB8PARMPIYK]L\EW?R<S;X:O>Q@[JeXobzϠǨᰏϒqqJVD;61A36=;;:=>7=B77@:30{fΗޗ螴랲륳寞Ùlz`NPGOPHRRJVSL\WP_SP]RLWOIVOLSLJREERCCMFBMHBMIBMJFROIZOH_REgWFjYJgWJ_PE\MFZMHVRJ`LJ]LEVM<cL8M@WU_]aUYN^LTDUDYBK;sn|kRx\iڪ䭠Ԡo[U;I;15>/>D7T7<a;;yqTv~҅ݗ㩩٩ÑqaRSJSULZZR_\Uc\Uf_We_Ue]Uh\ReYLcVGbUJbUJWRFSMDSLDWPF`WFjYFs_Iu]MmWLeUG_UGYWJhPFelhkbUnjgT\KbNeH^I[abebTULXjeh}ubjԟzz:j<n^~qugtxC:[K;i^BUˆȈ˃Ԕҽ޿{iPRIPSIZZSb_Wh`]kc\kc\neYrbRnZGkYChZFfWG`UIYRIVRD\UAfYFr]Fu`Gu\IpXIfWF][IR[Hc`pLOX4^OXH]LfRW<]K]TT^ZZf^RXE:cWۖv̔oXgcdivEgBlH~NWWbk\LleFrMMHPPJUUM\[QgeVkk^pnYtnQnhStmpmaVhYAeVD_UH^UM]SJ^WOa]WocRzaDm`DrUJfSOP]Ia`GoaOAO2c:X6R;]LcJaLaOU>JAAAI>R8P2WCo{cr`cZFiZch_nc|]__iqϨɳƨKJEHGDPNHVXM_aQmi[zsVwsPlazXPPSM;RM?ZXGf^EtcI|cIh[AZP?JPJfLES][I]<[9`D^L[LXAZBaMOAPDWGLBI>R1Q3YDbThee``OY>_Fkdmujujgsuxh֔[XMUPFPKCWRE_]OsfUuZr[xsecy_ZZf`?hjHXfZ[mmnp_nW`DfG]?UBXL[RXO[P]OcWN>G?G?O?W4W6T?j_zbO\7\AfWroqrou}ouwmgUhbR_WHUP@]UKpbXrWpXzX]l][Xw}عy`>[8]C_H`R_RWOd\aYZLn\fTBBEEQGQ<a@^DYI{tlg\:\@dQvpd~v~xa~t_siWg]NdXNjd\~qWoK}ڀ}vaffffWfMhRfV^MTG[M\MTCT;^8fO\aOWROWVWT[GfMzrxeT\GcJnReJwezèliiza}nWudRsk\wXwMmejc\lRvcgm`elat`[CTHWRcO\EW7[7\@YEYH^MWTKYFQREY<my{~^MaCdBdGfOlVnVook~cyayf~aXincjslxjezxjoleiTlReJcObWWPYO`HeJe]gbb?b8WA[P^J`AiGk[or{ibGdHhNhOdH{붘wlljhhnib|ڐg{Ynymut|p]ug[Vt]gHdAfAbF[KVYMYOVPbFmFTTDcFhXl\x__C]Ha]QS\J]JmmV_JfLaCmxkkkiiokktõroMrfkrvkbfGvdidzhb@iGdF]FfR]FOAJFBZ'aFalzXhVhMSe_a^ja_KeDeMl\gXh\eMeQq哷jjjhjnnllj_uzuyzulTfEucfl~xcI`McXZVZiSnMnSUgXaeF{c{viUeBmDgKyg^^ZXXiZ`HsfgeegjnrrrltvrpruboOuXi``QkIzz`mVgk^u@X<U>QEgomdfDU-mZifoZiQiQiXx`VV\U[_SbFwy]oooooim|Ըпn}jj`pSwnhShKdXjsX\bZVUM`bwyjlbX}ptkavkzxp_Qa]Ya]YeHtt~tȃw{ywwkoݢlprblZ|ɭ~dbU`Vx`lQXQhh~p|Xliewwg_Wsi}kegSc][c]YiQwe{Ƿu]{z¥¥ȴmumguccN}yoaJ[NgUsk_pQnphnjrfravlxxnllWnUa[_ja_t]rfz|zMajj|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{t|Ī˲Ǭ~m|eg|]rdpdwYyOpyrjrwnpnfjdyb{jpnruplp^rSfYjndblW{~^x鋿yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrã̰ɻǶs`qK~Z|fu^zdxdZioumsMdfU|SB|Kxbs|qquqmqofuWzQsQq`qWpTy{rKnvyGpvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuqwb~~qȧbLZv^^vWb{WbgitekUgx^\OS}tvrtrr{whyZ|TwO~TRsyqMhRhs@nssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr]kU`k`{vĹ֢֗Ĵ|UX~anZaZa\|Z|Zjlynesyw~}zxx}zv_]XKVztzvak]ppppppooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooirWbi[npboפש՟ΛocXXzcz_cc_\\x\s_xmɽty{~_bbQ{_ٯriwVw[lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkkr{wdȚԩ۲~mrf{dUUhaZ~]bl}x}g]`T߾zQb̑jiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhмҼҿĕɤաڷҮܫɮkispfeljTo{go{lcY`蓓s}kzffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeĚɜzhkmkkmwLhkw``hmfgWlӾؼdM~y{{ccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb¢ʛsakkik{NQnvnqfkogljZܼ̬rgb̪j|w````````````______________________________________________________________________________鸸otðƻztwxs~~sxxsxsmšشޑ_\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[mҳɻyy||qw|yq|tƽwYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXX¼k߭¿Ǫ~{rvyVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUxȠԿԹμ|p}ӓ㥯ǓSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR蝦Ƈٹ϶ϰrŨ̜ŜﲙŒPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOǰǽǙďĦƬâfʬӨƘ᥼pLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLḼүΨǞġĥĬˬĔĐ߬欥|IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHɚӳ̳ɨťťŬŬŬůרťš役FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEլٷʻƷΰշΥѫͧ§«§ūի뫾կCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBӤ۬ۻ߷߳ӯ˳˳ë˫ϯӯϳ@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????ދѨռ̷̳======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ʴʴ999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/In.miff b/PerlMagick/t/reference/composite/In.miff
new file mode 100644
index 0000000..433e0c9
--- /dev/null
+++ b/PerlMagick/t/reference/composite/In.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤䟟D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPA陙WN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3ꖖ[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnEݓ[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպŏ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbDvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgGssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJppppppoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpPlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkk@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvViiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeecZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`L````````````______________________________________________________________________________i`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[i`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjELLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHheVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEheVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBheVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Minus.miff b/PerlMagick/t/reference/composite/Minus.miff
new file mode 100644
index 0000000..f414e14
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Minus.miff
@@ -0,0 +1,121 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:șk^WJGFK\nsxŖpcZID?E[nqu|sfVI?Gdpqu|wjcXHMjrsv{}lgh]Zkstv{{njjimovxy~ymmrrquuy|~{z|{{{y{vy}u|~w~{}~}ygdmnsuy||ckttwv|wv|ssyqswotxnswptzqu{pw}szu|w~w~}yuvzXQ_LSSTZXZcwx[P_z]Y]bhoty}vu{wu{qqvmosjopinrjosiovhq{kvnxqxr{w}{~|w~r}r|sw}Z|q0O<JIIUMD:CLEO[qw[T`]]aehknrvyvvyttxrrwnouijsggoefscgxhkxfjhkrxnwqyu{w{x}y|xz}rxnzu{tz~>y;EEFNKLLGD95;FMWZSLZmi_^adilptwztuxwxzstxpoukjscfn]ar`bvXXX74<?Y_Hkqdw{{z}{~xyswmvkvu{|yK}6?C92=EE?A<;59HIOSRT_jlc^_aehlpsyhjqmpvqsxnpxjks^fpT_nWbnJM>
+
+hp
+i[
+VPb`)ln?owMs|>ns8pq3jl;qu?rwHsxFtw@orAwx=yxBzyGy{Uz}YuvNggRmkVvpY{ud|y{ywrzvsyxtz{w}}z~~{~(9K):L+;M,<N-=O.?R0>Q8?K087%2'(0&'!
+
+S\ V[Z\MO QV]ea`d\f[i^ h_da`b"`c!cc$ed+eg0ei3ek4gl4hj8ilAjm?ba>e_BkbOjelmplknnnqkjojgmlhomjpnkppmrqpssqstsuvuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuA>H<<B)3<#-;
+
+
+
+,=
+!#!-//*
+" %(!$2&)7"$3-'
+LPLNMMMO+QU4QW8RW>SY@SX7NP>NQBNPBKOFBKSPW\Z^ZZ[[[\[[]\[]XU[XT[ZW\[Y^][__]``_abbbccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+  &'&1/)45*8.+?
+
+  "%&;*
+.5 /7172737273749!6;$8<&8<'9<(:<*;>.>A2@D-;>,57:<?B?CA?BA@BBABCBDECEDADDBEFEGGGHFEGA>BEBFGEIHGIIHJJIKLKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+,1 .4/40404253637"49$59%6:%79'8:)8;*8;*47::<=<>=<>==@>>A@>A@?BA@BB@BA@BB@CDCEBAC?<@DADDBEEDFFEGGFHIHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHH
+", $)
+"& %!&"("&!(!("$$,)&0&$/#! '.,2.,..-0/-00.10/1112213434545656767878878888878989:9::::;:;<<<======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Multiply.miff b/PerlMagick/t/reference/composite/Multiply.miff
new file mode 100644
index 0000000..23fc01e
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Multiply.miff
@@ -0,0 +1,99 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+page=100x80+0+0
+
+:('&,+)1.,51.940:52<64?97@;9C=;D?=E@>GB@IDBLGELIFNLHRPLVTQYWT_\Vea[ie]lf_oiatjcngogpktqvwxywyyz}{yz|~'&%*)(0,*4/,72.930:53=96?:8B=;C=<C?=FA?IDBKFELIGNLHQOLTSOWVS]ZTb^XfaZhc[kf]njb}meldlftotuuwuwwy{y}vwz|~$$$''&++(.,*2-+30.521843:66=98?;:@==C@>FBBHEDJHFLKHOMKRPNUTQYUR]YT`[Vd^Yhb\iiarjciaibqjtousstvvys{s}vyz|#$&%'()((,+(.+)/.,100322755977;99>;;@??C@@ECDGFDJHGMKIOLKRPOVSRZVT^YVa[Xe_[hd`oebveagckfoisnusxuxqyrzt|w~yz|~#%'$')))**+*,+).,-/.////334756978:99<;<@??CBCECCHFEIGGLJJOMMURRYTT[VV^XWaZYd_]fcalcazebjdlipjrmvrupvowqyt{v}xz|$%$&&%(*(-,*/-+1/-30.200333546758;7:;9:>=<AA@DCBFDDIGFMIGPMJUQOXSQYTR[VU^WWa\X^`\b`]n_]yfakemgmgqkrnsnupxsyuzv}x~z~&&"()$,*'1/+20-50-61/520755567949<7:=:;@><BB>CDBEFFJHEPJGUOJXRNXUPYUQYTS[VVbYWiWYfZ[b_\n`]yfbihjhnkrmsmtntowqzszv|y}))%*+'..*21-641943:53:64;87<98=88@::@=;B@=DB@FECIHFNJHQMHVQKYSNZUPYTQZUS[WU\[Ya[Zb][b_[ga[uc`hglknknkqmqmsovqur}|))%+,(00,42/851;85<95>;7A<8A=7C>8D?;E@<DA=DB?FC@IGCNKESMGXQJZSMZSOYTPYUQYXT_XU}`bcc~c_hghcgbjemfmhnorrsprquyyz~|}&'#()%//,42/854;85<96?<7C=6C;4D=4D?7E@:EA<DA>EC?IG@NJCTMEWPHXPJXQLWRMVUPUWRu[ZahYZ^Ta]b^d`idgajfljlnnnsqprpnxu|}}##!''$++'//+55/994<<4@>3?=5C@BB>:B=4C>7C?;DA>EB?HECJIGQMGVNESOGWNKTONPTNWWP\YVRXP^T^U^Yb^e`gbhdhcgeggkinipksp|y~}{}||}z!!"! ''$+,(12,861><1?>1GFF^`s^[qMIXC@H?<<><6@?:ED?JG@PKCTLDPLDNKFKLKTMKtQTTPWNXP[T]X^Z_Ya\d`b_ebgdgeiglfniqntrwvxxywzv|y&%!&$ %$!*(#/.)83-A:1B;3LJTmqvynphhXXiHGNDDKDBBHF<JKAGKGJOTPW]RXW_TPvVP~TLWOWPVRYV[Y]Z_]a^dbb_badchekemgnksqywurvqxt{y~~,)#,)#*'!(& -*&50-?8.B90GBNdhszy}{~rr`^UPpLJ\BCGEEDQNOiaszh|ZgUWPH|QHSMUOWTXVXV][^\^[d`da__bbfdgdlgminkutsssnuqwu}{|{~2.&2/'/,%-*$.*&1/,:5->6*B<@[`{mqstuvqrlmeeX]ySUeeMTNROVOSKLNNOLQKSNTPTQTQWTYVYV[V_Xb^bbaccbeeggifmisqqrrorpurxuxv|z~~50'61)40'3.&2,&20+85+=6)@<=Y]vjjkklplqrqlsmry[eEKEFFDICNILMLMPNTOPKPNSRVRWRXRYS\V\Y^[a^aaaccdfdiepmppsrpnrotpurwuzx~60'81)81)71(81)62,:6->7+@<>UUj`bbbdich^b_^x{RfAICADFFI}GFLLKLLKMI~PK{OJQMRPRPTRVRYT[Y]\]X_Y_\a`daeahdjhllrrpnomqosqusvt|z5.%6/&81'82(:2*:3-<6->7-=86FCNPQaVVq[Y{UUpMPjXEL=A;@DAEIFHtFB{IFED|KGyKDzLE|MFNINLOPPRQSSVTZUWYW]Y_]a_eac_dbffffigkipnpnpnrptqvu}~4,#5-$7/&7/'91(;3,>5,?8.?82?97C=EKG`XTtbUmjPfn;>w<4?<>@BFuB@lB;yGCFE}KGvHAzJD|KELGNKOKNLNNOSMVSWZ]Y\Z][\`_eecbedechdhfnmlkmlonqorpzz~~~|~|3*!4,"4-$6.%80':1*<2+=6,?7.@8.A87C?MPN^pV_IQ5?<>x?=?A}A@m@;i@9yEACDLI}OJvGB{HEKIJJLNMQMRPWQ]]aaeY_YZz\X~_\dccbb_~c_zea{fcjjihjjkknmomvu||||{}y{y{}~z}2)3+ 5,!6-#7/%90(:2*;5,<6.?6-B51E@IPShgUbNL=B:A~;>z<<s>:h>8lA;w@?|@=|D=LHyIEzIEIJIMFJGKILLQSZ_b[\zWVqWSlWRu[Yz\\ba|`^|a_yb`|dbigfegghijjljqpzzyzvyuxwxyzw}{~2)3*!4,"5-#7.%8/%91'73-=99D=CDAFGJ_PT|ZQphLO|FC>B8;x99o>8e<7mC@qC?s@<zA<|B@{IDzHCEFLOMO}IH|JI{MM|QSzST{SSwSRz[Zz]]x\\``|^]|_^~`__aacdd~cbeefghh~jh|nmxxuwrurv|tuvxuy|x{}z{~z}~|~}~1) 2*"4,#5-$6.&80$7/'98:HHXKI`EGcJNjXXkfadleXdI>l=8|<=y78s:7j:7jB>qMIlA=u><x?=xD@yD@}BA}FF}PR{OQ|RS|UVvPQ|PQ|OQ~WY`c_c|\[yXWz[Zz^\{\[\^_a}a`|b`cbdeee|hfxjistprmqorspostrwyuxzwxzwz{x{|z|}{}~|~}.'1*"2,%4-&5/&5/)948CCRDF`<?_GGn^\ptsa|z[wv^dbT[LDoHF{ABw78q87g;8gC>pGBo<9wAAuDAu@=xA?tDAqGFyOP{QU~VY}WX|LN|KN|TW}Z\|Y[wUTyVUwWVvYWy[Zz\\z]]x^]y_]{`_|aa|bbyedufe}np}lo}knxmonnlopnsuruwsuwtwxuxywyzxz{yz{z{|{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||)$-'1+$4.&4.%736BAQ@B\7;Z>CbRTobcqlkkljfd_aMNNFDBVECqLJ{FEw;:p:8g;8i?9m>9rCBrEDrA?sB@mD@hF@mHFoHJxRUvRTtLKyOQvPRvPPyQQxRQxSStUStWUvWWvYYvZZt[Zu][x]]y__y``vbaueeyjlzgkzhlokjmmkmmkopmqsprtqsuruvtuwuvwvwxwxyxzzzzzzzzzzzzzzzyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy! %#.(!1,"52/><H<;R45Q::\IHkQQkSShSQhSPePLaD@H>;:J;7_?<rJHxNLsDBg85d93h<7k=:j>:n@=nA>hC>hEAiFDhFEoMLmMKlJEsIIuILvJOwIOwLPuPQqSRrUTsUUtVVsWWrYWr[Xs\Zu]\u^]r`^udewehwdhsfhgfehhgiihlmjnomoqnprorsqstrttstutuutvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuu'"+'!43676F--D23P?@aFFhHHcGFbHFdKHaIHWG:@<;6D;5e;<mBDpMLuMKc84`92d;5i:7g=9f=9j?<f@<fB?fC@gDBhFDgGDkFDsGHtGKsIMtIMtKNqOPmQPoRQqRRrTTpVTnWUoXVoYWo[Yo]Zp^]tbdt`dtbfgbcbcbdeciifnollnkkmjmolnomopnpqoqqprrqrsrsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrr#" -.3//A0/J=>bBCjBBdBD^DCaGDeIF\DBHA86<;3><3W;9l=@nDCf:7b50b82f84e74a<7`<7hA>d>;c@;d@=eB>hDAiECmEFpEHnFImHIoJKnLMlMLkNNlPPnQQpRSmTSjUSjVTkXUiYVjZXo]]q]aq]bi`a___a``bcajkglnjhjghjgjlikljlmkmmlnnmoonopopppppppppppppppppppppppppppppppppppppppppppppppppppooooooooooooooooooooooooooooooooooooooo&'',+465IECgFEl@?^AAZFF]GCXC?I<97981<92>:2I:3f88h33d0/c3.a50f52_73\:5_;6e>;_=9`>:a?;c?<e@>iCBkDDjCEjIJkMLjJJiJIhKJiLLjNNkOOlPPiQQeRPeTReUSdUSeVUmZ\mY]h\^]\[\\[_^]dfbgjffhedecfgdgifhigijhjkikkjllkmmlmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmllllllllllllllllllllllllllllllllllllllllllllllllllllll !%%*)"102=<QCA\=;O;:L?=L=:@:52:4.:60;72C94O3/_.,c.,c0-`2-\5.`51X72X73a:7e><X;6[<8^=;b?=e@?gAAfBAiFFgKKbGFdGFeHGfIHhJJhKLgLMgMNdON`PN_QO_RP^SQcVVjXZfYZ_[ZXYW[\Y`c^cd`cda``_`a_cdbdfcefdfgeghfhhgiiijjijjjjjjjjjjjjjjjjjjiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii$ %!&#'%*& -)!.+&3/27396150.//.-2/*62+94-970C51O30P-)Y,*_.,_/-]0-\2.]40V51R50Y74^97^=9^<:_=<c==d=>c@?\A?ZA>\C@`CBdDDcEEcFFcHGcIHdJJdKL`ML\NLZOLYOMYPObUU`VV^WW\YWZ\W_a\]_[[\Z[[Z\\[]^]`b_bc`bdacdcdecefdffeggfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff(%)%*& +'",(#.+#/,#/,&0-'0-'/-'+*%+)$.-'21+44/E53W/0X*)P.(W.)[/+Z0,Z0-Z2.T41K3-Q71V63Z75`89`9;a:;a;<\<<T=:S?;V@=]B@aBBbCCaDD`FE_GF_HH]JIYJHWKIVLJUMKVNM[RQZSRZUT[WV[\YWXVUUTWWWXXXYYY[[Z^_]_`^_`^_`^`a_ababbaccbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbb(%)& *'!+(#,(#.*%.+&.+&/-&0.%1/'/-'))"'(#(*%*,(0.(M2/]-.S+'R+'V-)V/*V0+W0,Q2/H2,H3-R41Y64]89X98S87S:9O;8O=9P>:Q>;U?<ZA@^BA^CB\ECYFDVEESGERGERIGRJHRJHUMKVPNVQPXRRWSRRSPQRQSTTUUTUUTVVUWWVZ[Y[]Z\][\^[]^]^_^__^``_`````````````````````````````````````````````````````````_________________________________($(%)& *'"+(",(&-)).*'/+'/,)0-(1.(,+&''#%(#$(#()"B1+X31[./R+(P+(R-*S.+T0-S10L2/N40V65Z76T76K64H95F:6E:7H:7I<9J=:M=;O><S?>UA?SB@QB@OCBNECNFDNGENGFOHGSKJSMKTMMUNOTQPQSOPQORSRRSQRRQSSSTUTWXVXZWYZXZ[Y[[Z[\[\\[]]\]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\&#'$'$)&!*'"+($,($-*#-+%.+'/,(0-(/-(+)$'%!$&9*'J'(Q,-Y45S.-P,+P.-R/.S10U12T33V43W33V44Q54H52E74D75D76D87E:8E:8F;9F<:I=;K><L?=K@>JB@KB@JB@KCBJDCLFENIGOJIQKJPLLMMKMOLOQMNOMNONOOOPPPQRQTUSVWTVWUWXVWXWXXXYYXZZYZZZZZZZZZZZZZZZZZZZZZZZZYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY%"&#($'$(% )'"*'"+(#,)$,)%.*%/*'-+'-,',*$%%3)%>('C((I,,K,,M++M+*L-+O..Q./R00R11R10R21N32E20@41A53C54C75C85C86D97D:8D:9E;:E<;F=<F>=F?>G@?GA@GA@IDCLGFMGGNHHLJIJLIKMJKLJKKJLLKMMLMNMOONQQPSTRSUSTUSTUTUUUVVVWWWWWWWWWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV#!$"&$%#&$'% (%!)&"*'#+($,($*'$/.,<;9A@=33."$"$%%"'&#/(%@+*K*+M**N,,N--N..N0/M0/M1/N21F10?2/?31@31@41@52@64A75A76B87B98B:9C;:C<;C=<D=<D>=D?>FA@JDDJEEIGFGGFFGFFGEGHGIIHIJIJJIKKKLLLNNMPQOPRPQQPPQPQQQRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRR" #!$!$"%#&#'$ (%!(&!)&"(&#10/EFFQQQRRROIG;72$& "$ $#"!#"-''G66G..K))L+,K,-K--J.-H/-K/-F0.>0-<1.=1/=20=31>42>53?64?66?76?86@98@:8A::A;:A<;A<;D>>HBAFCBCCBBBABCBDDCDDDEFEGGFGHGGGGHHHIJILMKLMLLMLMNMNNNOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOO ! " "!#"$"&#'$ '%!(% ((&>?@OOOOOOOOOOOKJLC8:1&' #"('&:99LLJMHFF22B('D*)F**G++F,,H-,D.-<.,:/-:0-;0.;1/;20<32<43;53;54<65<76=86>88?98>98>:9A=<B???>=>?>?@?@@?@@@AAABBACCCDEDDEDEEEGGFIJIIJIIJIJKJKKKLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL  ! !!#!$"%#&#&#%%%69:HKKKLKKKHJKHLLHEC=,,'"$!553IFFKJJKKKKKIE=9<+(>'&B*)B+*C,+?,+9,+8-+8.,8.-8/-90/910910821932942:54:54;66<76<87<88>;:::9:::;;:<<;==<=>=>?>?@?@@@ABABCBBBBDDDFGFFFEGGFGHGHHHIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  ! "!$!#"%%$235ABCHHHHHGFGEFGEHHE@@9*+%+-)=>=HHGHHHHHHHHHHHHEBA<.,;'$>)'?+(:+)6+*5,*6,*6,+6-,6.,6.-6/.60/610610721822933953965<;9;;96768878989:9:::;;;<<<======>>>?@?@@@ABABBBCCBDDCDEDEEEFFFFFFGGGGGGGGGGGGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF!"!!'''<>@EEEEEEEDC?@>?A=BB=<<6652;;:CCBEEEEEEEEDEEDEEEEEEDED<637(%;'%:('6((3*)1+*2+*2+*2,+2,+2-,4--4.-4/.50/510631642652998675444565666777887888999:::;;:;<;<<<===>>>??>@@?AAAABABCBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBB  !#"579BBBBBBAA?=>;=?9>=8;:7?<<BABBBBBBBBBABBABBABBAABBABBBBB?;87,)3&$2%$0&%.(&/((0))0**0+*1+*2,+2,,1-,1.-1/-21/3204416641212323334434545556667777778889999:9:;::::;;;<<<==<=>=>?>??????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????" 034>???????<<=98:3873;99?=>?????>??>??>??????=>>>>>>=>>>>>>>>>;9631,)-'$+%#+%$-'&-('-)(.)(.*).+*.,+0/---+-.+//,330220/0.010111221232333444444444555555666777787888999::::::;;;<<<<<<===================================================<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 034<<<<<;<<::;644/20.989<<<;;:;;:;;;;;;;;;;;;;;;:;;:;:;;:;;;;;;;;;;;;::8865631*(%)'$*(%*)&**(**(++)--++,)+,*,-*00-0/...--.-...././0/000111111222232333343444555555666777887888999999::::::::::::::::::::::::::::::::::::999999999999999999999999999999999999999999999999999999 "!.0278888655222./-*/-,434878888888888888887887888888888877765878888888888886653)(%&%"'&$''$('%((&()&()&))'++(+,)++),+*,,*,,+,,+,,,----.-...//.///000111111222222333443454555565666676777777777777777777666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000////////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................---------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++************************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#############################################################################################""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Out.miff b/PerlMagick/t/reference/composite/Out.miff
new file mode 100644
index 0000000..591ab02
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Out.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:YVSYWSYZO_eQYdJO[DLVDNXCS_GWgLun䟟~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuutttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeedddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa````````````````````````````````````````````````````````````````````````````````````````````````_____________________________________________________________________________________________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>================================================================================================<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Over.miff b/PerlMagick/t/reference/composite/Over.miff
new file mode 100644
index 0000000..17c8881
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Over.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:21/642<85@;7D>8E>:F?<IB@JCALFCNGENGEOIFRKITNLSPLUSNZXR^\Wa_Zhd]ojbsndvoeyrgsiwmwnxq}x~~΃}~Ýþý10.431;63?95B<7D<9D>;HB>JD@LFCMECLGDOHGRLITNLTQMVTOYWR]ZV_^ZfbZmh`pjaslavodysivltjtk}v|~}|~ʂ{|~ś...01/652963<73>97>;:B=<D>>FA@HCBIEDLHEOJIQMLSPNUTPXUR[YU^]Yb]Yga[jc]ng`sjcssi~tjqgqgzp}w}{{|}}xw{}~./1/13433751941974:99<::@>>B@@DBBGDDIHHLIINLMPNLTQOVSQWTSZXW`\Zd_[ha^ld_phcsmi{njlhoislxp|u}{́}vvy|}~.14.25446565753867979878<<=@??B@ACBBECDIGHLKLNLKQNNRONTQQWUU_ZZc]\e_^i_^lb`nhepkiwkhmirkupxq{ty|w~uvz{}~020220463986<96>:8?;8<:;>=>>=AA>AD@DDBCGFEJJINLKOMLROMWQO[VR`[Wc]Zd]Zf^]i__kd`gickhczecohulvnun{rzt{u}vyz{}~45/670:83@=8A>:D=9D=:A=;CAA@ABD>DGAEGCEKHEMLGNNLOPPUQN[TPbYSe]We_Yd_Yd]\f_^na_w^arackgb|gcoirprpwr{u|t|t|u~vx{}894:;5>>9BA<HE@KDBLDAJDAKFEJFEKDDMEELHFNKHPNJRPNVTQ\VR`YSf^Uh`Yia[f_Zf`\ga_gebmddmfclibsjblgrqvuxtwsztxszu}v{v9:4<=7BB=GE@KFBOJEOKEQLGTMGSMETMDUNHVOIROIROJSOKWTN]YPd[Rj`Ul`Yj_Zg`Zfa[ed^mc^mppqojustlqjumwmvowy{||xzw}‚ȁƃČ7829;4AA<GEAMHFPLGQMHUOHYOFWLAWM@WOCWOFVOISOJSQJXTJ_XNf\Pi_Sj^Ui^We_WcbZ`d[hgozbdiZmglfoitmpgtnurtwww}zxzvs}ăą441884<<8BA<KJ@OOGSREWSBTQEYUWWPJUM@UMCTNHTOKUPLWSPZXUb\Ti]Pd^Qh[Vc[Y\aXedZkf`ZbVk[h\h_mgqhrksmqiolnnrovowo{uƂ21.21/874=>8EF<NKCWSBWU@a``gaxWQ^NJJMJ@NLESSJ[WKc[Ng\P`ZN[WOUXUcXU]aaZdWeWh]ibidialdoikfmiplolpmtkumys|y|{~;9286074/<:2CB9PH>]RC\REkixڪߒxw^[gVU`TRRYVF[\MU\VX`haluclkve^f\aVeYcXb[d`gcgdjflgokjeigkioksitlup|y}x}u~yEA6C?5>:1:7.A<6ME?[O@_PBe^pթﱸ߆rkd_}QSZUTRgadrgj_Q^P`VbYd_e`c`ifjgidpkojffiimkoiulunuq}|{zs|v{OI<OI<IC9D>5C=7HD@TM?[M:_U\쬮즨曞ێyorbodjcobhZ\]]^X`VbZb\a[_Zb^d`c^e]i^mfkmikkjnnpormvp~|{|zvyu|wzzWN@WOARL=OF9KB8KG?SN>ZO9^WY碢졨ީ➩枦α~XbUXVS[P`Y[^Z\`\d]\T[W^\c\b[bXeZg^gahckgjjililmjqj{wzz}|wtys{u|w}z}[PA\PC[OBWN?XL?SMCXQB]S>_Y\ʔ֘۔ʊÊsSaVRVZX]XV`_[]]Z]U_V^T_X`\][_\c[f]gdhgh_j_hbkhmhngrjspuv~}zvvqxszu{w|x[N>[O?]P@[P@]PA[PE]RD`SA\TPjfy{{ot`lOXKTYTYaY]YQ\WSQ^UZOZN\O\S[V[\Z][]]b\g]ab^h`jflhpklemhnnmmpmrnzvwsvrxtyt~|[L<\M=]N?[L?]O@_QDbSDcVEaVJ`URe\jrlwQVQBSNQTW]TQSGZTWU^WWKZNZOYQ]V[TXTXWW^Qa[bfjcgchcdihqqkjnlmipiplzwtrtrvtwsxu[K:\L;ZM=[L=^O?`OBbQCcUCcVEeVEeTRh_z~zm{GYRVUSUYWURIQEXQTUb]e\VMVPXUWUX\W_W`Zh[pnwt|dobdf_lgtrnmkglengnitsqoppqqtrtq~~}}\K7]L7]M9_O;_P>`PAaRDaVEbWFfUDhPIldtyuX`P^OWPQRKQETJRNOJTIb[[SXQXYV]NUNUPVT]`nu{lncabZ`Wfbgfomjfjekflispmkmnnopornyw~z{~}y^M:^N;_O<`O=`P?bP=aS@[THe]^reppisszוy}keZ`LRKKTIOEZSWQPIQHQM\TXPRT_e_aUTUSYZ`cbd_`^\ljmnkjqqkikhjhgkjlmljhlklmmmplusw~v~xy{~x}_O=_P@`Q@`Q@aRAbT=_Q?b_d}|}sw|s\XPVWJLNHLFZSneVMNINKWOTKOMUUfjbfgjjm`a]`Y]gmx}u|mkbagejfecchgjhhifihikkjmjpnz~szu{zusx{v~{|~{~|}}~~[M=_QA`SDaTFbTD^RGe\cwww|flzzȧϬۜҡzjplacJMKIOH^TdZLEUTWRNHNJRMWUfhhopvorW[T[djoskn`^`_b`c`ecffeefcgcffghihlimk{~tzpxtwrrotuqz}w|xzw{y|z|~z|~z{}z{|{||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{TH8YM=`SDcWFaUCg_d{ytz`hnvϵqnjniyvlkTRPJPHUJRHYY\ZQMRNTLVKXUX[jphlYW_b_b\]\\][]\a\b_aabccbdaeaecffffhfmlvxmunv{rqssprqntvqw{tw{tx{ux{vx{vxzwxywxyxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxDB6KF=]N@aT@f`Zytsp`ajjЗΛƘŖqj{d^Z{\Ta[xt}zfcKEK?PEPJOHQKRLUJXOWRUSb`a\WNTUR[S^P\S\Y\_]`^___``_b^d^d_dbebfcopntjslpkkhmnkmmiqrmtvqtxptxruxsuwsuwtuvtvvuvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu47-;;5PE=WN?gflljTT]_xzÆΈ„~{`laaUq^P\^jmˀ|}xMDN>OCLEPGNFQJQHSLTNUOXSVPSNSVRZS[QZS[Z]][^[]\]__\`[a\a\c^d_fdmqfpiqrgiegehiepoiy|usvqqumrvosvpruprtqrsqssrssrssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr*0&,1,;97GE?[]i]^]\xz˂~†ȇ{vr\YdcQgcN^X`golVOI>N@LCHBQEODXQPHRHQIRJUNUPTVRYQXUVVXXZXXZY\[[\\^]\^Z`Z`[bZb]ggencn{gidedfddijdx{qy}uptmnrjpsmpsmoqmoqnopnopoppoppppppoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.2&,/)23-<?3NQPYWmnl܎~|À}ulc`a`OhaQk`O^NYYKKC?H=I>IBIBODOEUNNFPFPGNHNJTPSUOUZ]c`ZXWTWVXXYZY[Y[\Z\W^X_Y^X^[fjbjeifc``b_gb`qtku|qquohkfkohlpilojlnjlnklnklmllmllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkk@>0>=5=>4CF-MN=VUDecg~|xuq{wvn{maZk\Nh_RjaTzbVSHD?A=D=H:L<JBLAJ@OJVRMCOEOHQMQORQQPZZbbXVUTURUTUVWYWYXY[Y[V|[U{\Vv[Va`diceogd^_[cd]lshpsinqjefcdebileimfilfikgikhikhijiijiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhUM>VM?VN@VQ?\SE`XEbZMlcjuiyndl^Y\YXU_YLf\Ll`NidT]TWOF;B<E?F?F=H>J@LAH<KDMIUMRMPNPPMNQORMQJRLSPQSRTTSURUTVVWXZW{XTvYSrYSoYUcc|bbscblf`ej]qvhiodbe_``^__^ab`ficgkdfjdgiefhdfhefhffffffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeecZKe[Ke[Kd[Me[Nf_Lg_Jf^Of^Oe]L`[KTQCPM?VTE]\L``Sa[PR@=H9F;F<F<F=H?KBF8M@IAKEIKJNKNKOLKNEOFPHSNQQPQRPTPUSVVWU{UPsVPpWQlVPkXSu_\p_]ma_ofblpf`c]XZW[\[\\[]]\^_]cf`ehadgbdfbdfbdebcdccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbg_Ph`Qh`Qh`Qg_QjbUibTh`QhbNhbKgbN`[JON=FJ<GM@IOEXQDZSKME:C6D:F;G;G<IAF7H9H@KGNQMLJGLJLF~OE~QGOFMGPMQOSOUQTQ~RPtRMoSMlTNiUOgSNkWTn]Yl_[m^]i^\Z\UUWUYZY\][[ZXZ[Y[\Zad^bf^ad_ad^ac_ab``a_``_````````````______________________________________________________________________________h_Qh_Qh_Qi`Ri`Qj_Zi^^i`Vi`Ui`Xj`ShaPZWHIJ?CH=>I;FI5[L]ZOQE=D:G>H@IAKGJCMCQLQOOMKDwQFqOFkOEqLDrMFsNFwLF{NIOJQKPKwNJpOKkQLhQLgRMdRMdQMlWSjYVlZYl[[ha]_bYY[U]_[Z[VWXTXXVXYW^a[_c[^b[^a\^`]]^\]^\\]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[h_Qh_Qg^PkbTjaSkaWjaUjcPjbQiaVjaUjaUe`RWREIF9?F2zNFEFQRehQOJELHNKOMNPQQPOKLLKKJJCtMDpJEnJFlKFkKFiKFhLEhLEmKFpLGqLFlNHhOIgNIeMIdNKaNKbQNfWSfXUjWVeZXYYTW\T[_VUYRTURUUSUUTUVTZ]W\`Y[_Y[_YZ\YY[YZ[YYZYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXh_Qi`RkaTi`Rh`RiaSiaSiaRiaSiaTl`Rl_Uc]Sc_Q]XGFE0kOBIHGHQPOOIHGBKDJKHKJLKKJHKHJH~FAmIAlIDpGDnICkICiICgJDgJEfJGeJFeKGdLGcLHaLH`LH^KH]KH`PMdVTgUTfVT_ZUW\TV[SUXQQSNQQORRQRSQSSQVXTY\VY\WX[WVXUVXVVWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUg`QhaRicShaRgaRhaSi`Sh`SiaThaTi_TcYPmketre>C4;B3BC8EB8[G>KIGJEDIGJJJJKJKGLFKGGBnG>jH@mF@lG?iG@hHAgHCfHDdHDcHEbIEaIF_JF^IF\HF[IFYIE]MJfSRdUS^VSVUQPSNLOJNPLPRNOPMNOMOPOPPNRSPVYSVZTTVRSURSUSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRgaRhaRjbRgaRgaRh`Rh`RiaShaSg_Rb[R{yuоrFK9<C5@>:596WDDppUSABFHGIGHHFJDHDHCqE=iF=iF=hE>fE?eEAdFBcFCaGD^FC]FB\GC[GB[GDYGDXGDUFBZIFdQP[SPPPLJLIIJHJJIIJIKMJLOLKMKKLKMLKNPLSVQRVPPROPROPRPPQPPPPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOgbRgbRgbRfbRfaRgaRiaSiaTiaTh_Pgea̯sKN8A<3NIHddCAEBEEDEGDFCHDrC>hE=fD<fD>cC?cD@bEAaFB\EAYD@XD@WEAWEBXECVEBSDAQB?VHFYOMKIFEHDFIEHIGHHHHIGGIGIKHJLIIJHIIGKLJQTPNQMMOKMOLMNLMNMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLfcRfcQfcQebQdbQfaQi`TiaTiaRe^P```ǾgdSCJ@zMD?:EBEBGDDBoB>gC>dC=dB<bB=aB>`B?]B?WB>VC?UB>TC?TC?UCATCASCASEBTJGEECCDBDEBEEBEEBDFCEFCEFDEGEGHFHIFFFEIJHMPMILHJLIJKIJKIJKIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHgdUgdVgdVfcVfcVfbUgaXjbUdbPigcȶegSdm`\U>6C=G?}F=iD>eC>eA<b@<^@;\?;[@;X?;V@=T@=S@=S@>SA>TA?SC?QFAYTNRQM>A>AB@AC@AC@ACAABABCABCBBCBCDCDEDDFDFGEGHFFGEGHFFHEGHFGGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEgdUgdUfdUfcUecUdbSgaYi`VccNuxvƾŶɶ|p{D;>7?>q>?cB@ZC@ZB=YA=XA<U@<T?;W><U><S?;Q?<QA>PD@NF?LG?VVOGJD<><>@=?@>?@>?@>?@??@??@??@?@A@?A@@B@ACAACABCACDCCDCDEDDDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBgdUgdUfcUgdVfcUgbTh`YicWcdOfniʼɲ·YKt@6l;4a<6XA:Y?<Y@=XA>V@=T?<U=;R>;N?;L?;F>8HF>JH?JJ@NQI<@:<>;<>;=><=><<><<=<==<<=<<=<=>==>==>=>?>?@??@??@?@@?AAA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????fcTgdUgdVgdUfcUfbTi_YgcWafPbohѿzs[N]C7Q:/Q83S;7S>9Q>9P>8M?;K@:HA:LIA@@8<?5@A7NNDGH@:<6;=;;=:;=;<=;<=;<<;<=;;<;:;::;::;::;:;;;;<;====><<=<======<=<======<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ccRfcTfeVfcUecUgaTi`YgcV_eO^ohоû{pPF:H?3JB6IB7FC:CB9AB9HK@<A6;>4>?5II?FC===8:;8:;89;8:;9:;9:;::;::;:::99:98998888888888989;99:99:99:9999999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888[fN^hQeiVfeVhcVhcVfbXcbU_eUs{˽¿QNAD@2EB5CA5BA6?A6>@6<@3?A4DG:EF<AA9A@8@?7=<6::68967967967977967977977977877866766868:6797686776777666666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Plus.miff b/PerlMagick/t/reference/composite/Plus.miff
new file mode 100644
index 0000000..0e75c04
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Plus.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:ÿ¿½ǿڿӽȹͿȿܸٺ˹ƻͽȼŽ»ຶ伹︻츽趽ݵصַҶƵɼǺȾſû»ľ蹵ݶ۷丷鷹綸嵺᳻޴ڳֲӳͯǶ¾οǼɼĹ㷲޴ݳߴ߶޴᳴ᴸܱڱֲѱϰˮɯķ´ﲯ赴ݱܱܰݵձڲٲױױӮЮͭɬūý¸鳴⯫ڬխԮϫЭϮҰԱЫ̬ǯêĹǿº嫥糯山䱰ةԩϨ̨ȧǧήϰ˭ǫì©ÿ直ꪥ䪣⫣嫧竫屰ݫӥ˥ƥ¤ǨˬŨħ¨Ŀ画筧ަߥ楤㡡ڢբӨȣǪũç륣몪ᢡ࣡ڠѠΠӧʟȝƝ¦ũпν頢٢ড嫩ݤ֟ОÞÜ͠ΛЙΗƙ§ҾѽммϽξοϾνʺļ墟ϟϟ՝ۣҝΛŚǙ̖͞Д˓ƔѾоϽμͻʷ˸ʿ잞ᛙ⧥ߦآ⦦ٟӜԙؕՖ͗ǒʒǐÐоϿνͼ˻˴ƵƼ졢ﭴᣡזךӚѓؐՒʑĐƏō˻ͽ;̾˺ǻ颥۔ړԓΒϒΒʏŽŽËÊ~~}}}}|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{óƶʻͼɶ㛐霘陝蕓旛ᓔ摒ސڏґΐ΍̍Ȍ~~||~|{{zyzyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx´dzԶ随囓㙔ޔ衟᝘ے獎ꉒ舓愐↎ىΎˍ̋ʉÈ}~{}}||}{{|yz{yxxwvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuƽֺǻȶ甋㕍┎ߕّ݌늎ꈐ䇏⃍߄։ɊȊɇȆ~~}}y{z{|x{}z}z|yz|wxyvvwuuutttsssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr˵뗌唉蒊⒈ߏߎᐉߏ勎舏߅ڈۈՈ̆ƆƆȄƃ~}|yz|~zzzzxx{}w~{z~vz}wx{vvxtuwtstrrrqpqpppppppooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooĻҰ폈㔈咈ݎ܎ݍ݊ވ⋈剋ބۍٔӊ̅Ȅƃłāzzy}w{x{}|zwuwtzvt}~vytwzsw{stxrsuqrtqprononmnmlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkkĸʲ䢗ۍ퐋ҌӋ؊݋ቇሇ݆ߍ֔LjɃȂǁ~}|}x|v{vyt}||~~{tuqwyq{{~yturqrotwqswpqtoprnoqmmolklkjjjiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhɾƷЭ饝蒈܎Ј}݊狆⑉ߍމ㇇ツۅȅ{|Ȃ~~~}}z}{{{{||zzuyswqvq~~||{z}wzs||vsvpoommmlmnlqtnqtmnrlmoklnjjliijhgggffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeǾȾƽĻĺļûׯ萂܋…wˊ}օ}݅聄ゅいဃ~wvwŀ{}|{{{y{x{yzzzxvrvpuptmtoywxvyw|x{svpjlillkkkjkkjjkinqknrkloijmhikggiffgeddcccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbǾŽûļ»꣜{~}||؇ttЂz߃煈Ճ~{|~xuu}sys{xzxzw{wyvustosntnsmojrnvswtuttqnpihjgjkklmkiifghfgheknhkogilfgjefhddfcbca`a`````````````______________________________________________________________________________ǾƽĻĻ¹}Ϣ|~ᇃ̈́~·}߈戆ԅxxwuzszszrwpwqvrwquormqmrmqkpkojmiqmrorqqq}vrrulkmgnpkijfffbddcdebhkehkdeicdgbcea`b__`^]^]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[Ļººy늋쉄ꊅ닇늈숊抉燆聃߁}|u}uztxtwswrvpunsmrmqlpjpjpjnikgkh}jg}lhpl~pmnm{ommmhjofmqgfibcdabcaaa``a_dgaehabf`ae__a^]^\\][ZZZYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXu͌؈㑐莎醅~߆億瀄䁂၀~|~{|ywqxqwrtqtnsmrlqlqlolnjnimhlhkg}iezgdxfcyjg}nl~lk|ljtoikoghmefibac^``^_`^]^]]][`a]ad^`c]^`\[]ZZ[YXYXWWWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUضu{swvzdž恃~| ~~z}x{wvqultmqkqipiohnimilhkgjfif~id|gdyebvdasc_ueb~kjzkiskhjiecfa^`\_a]_a]]^[[\ZZ[ZZZX[]Y^a[]a[Y\XXYVWXVUVUTTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRwxq{yvosp}|ݨیvwz}z{yyywysvrupqiqhogmflfkgkfjfifgd}fb{fbye`wdaub_ra^n_\qa^{hgqiedd`]`\[\Z[[ZYZYY[YZ]YWZWVWVWVUWXU[^XY\WUXTTVSSUSRSQPQPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO̮rzul٘usvsuusstqrpsomhnfldjdidhdiehd}fbyd`wc_uc^tb^sa^q_\m]Zi[Wm_\nec`^[Y[WY[XYZXXYXWXVUWTVXUVXUTTSRRQTURX[WTXSRTQQRPPQOOPNMNMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLܟzvٽ|smhqnqnromkkfkeicgafaeada~c_wb^ua^s`\q_[o^Zo][m]Zk\Yj\Yj`]ZZXWXVWXUWWTUVSTVSSURRTQRSQRTQRSPPPNQRPTWSOROOQMNOMMNLLLKJJJIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHҚκiamgphmekehdead`b^~a]{`\x^Zt^[r^[o\Zn\Yn[YmZXk[Wh^XojdhgbRURTUSSURRTQQRPQQPPQOOPONONMOMMONMNMMOMMOMLMKKMKJLIJKIHIHGGGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEǺۻlbe^edddfd}fc|d_{b^xa\t_[r]Yt[YqZXnZVkYVj[Wh\Xe]Vc]Ukkd\^XOQOPROPROOPNNOMMNMLMLKLKKKKJKJIKJIJIIJHHIGHIGHIGGHFGGFEFECDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBɽ~pdZ^X^Xyb[z_\x_\v_\s]Zq\XqYWmYVhYTeXT^VP_]U`_U__Uce]OSMNPNNOMMOLLNKKLJJKJIJIHIHGHGGGGFGFEGFEFEEFEEEDCDCCDCCDCBBB@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????ö}p}dWqYOpWRqYUp[VmZUkYShYUeYSaZRdaYWWOQUKUVLbbXZ[SLNIMNLLMKKMJJLIJKIIJHHIGFGFEFEDDCCCCBCBBBBABABBBAB@?@??@???>=========<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ĽmbWdZOe\Qc\Q_\S\ZQYZP^bWRVLPSIRSI\\RXVOOOJJLIJKHHJGHIGGHGFHFEFEDFDCDCBCB@AA?@?>??>>>=>==?==><<<;;;;:::999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888li[^[L^[N\ZNYXMVXMTVLRUISVIX[NXYOSSKRQJPOHMKFIIEFGDDFCCFCCDBBCAACA@B@@A@?@?>>=<==<=;<>;;=;9;9999898777666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/composite/Subtract.miff b/PerlMagick/t/reference/composite/Subtract.miff
new file mode 100644
index 0000000..31f25e4
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Subtract.miff
Binary files differ
diff --git a/PerlMagick/t/reference/composite/Xor.miff b/PerlMagick/t/reference/composite/Xor.miff
new file mode 100644
index 0000000..a83a709
--- /dev/null
+++ b/PerlMagick/t/reference/composite/Xor.miff
@@ -0,0 +1,101 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=100 rows=80 depth=8
+
+:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuutttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiihhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeedddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa````````````````````````````````````````````````````````````````````````````````````````````````_____________________________________________________________________________________________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????????????????????????????????????????????????????????????????????>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>================================================================================================<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/////////////////////////////////////////////////////////////////////////////////////////////.............................................................................................------------------------------------------------------------------------------------------------,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*********************************************************************************************)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((('''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$################################################################################################"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
diff --git a/PerlMagick/t/reference/filter/Blur.miff b/PerlMagick/t/reference/filter/Blur.miff
new file mode 100644
index 0000000..efecd07
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Blur.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:10.20.41.71-81-81-80-80-80-70-6/,5-+5-*5.+4.*3/)30*41+74-:7.>90D=1H?2J@2OA1[B3qC3B2B6C<CBAC?B>>?8?2?.@-@,@,?,>,=+>,?.@2B5D7B7_=4D72:4172/42.21.10.1/.4/.>01T98qIK]mkldZU~YUnhgpsvrprifg^//-1/-30-50,50,5/,5/,6/,6/,5/,5.,4-+4-*4-+4.+3/*30+41+63-95.=7/A:0E<0H=0L@1UB2iB2@1@3B9C?BA?@?=@6?0?-?,?,?,>,=,=,=->/@3C8G<G<]@8C8394162/32.11.01.00.3/.:0/K64fDE{[j{kkeYTTOm]]igkhfkbacZ..-..-0.,2.+2.*2-*2-+2-+2-,2-,2-+1,+2,+2-+2.,2.+2/+30,51-73.;5.>7/A8/D:/H=1O?3]@2s>0>0@5C;B>A>@;@4@/?->->,>,=,=-<->/@2C6H>RGUJ^LBD?8:7153.12-/2./1.01.10.50.@31V@@o[hyqoo__VVrY^haifbka_fY-./-....-/-+/,*/,*.+*.++.++/++/++/++/++0,,0-,1-,1.+2.+3/,51.92/<4/>5/A6/E91I;2R<2c:0y;/>2A6B9B;B9A3@/>-=-=,=,<,<-</?2C7H>UJfZn_dbSKNA=>455.11,/0,/0-00-00.2/.811J@?f`f{~|s~kwk{xntl{keq_-/0-////./.-0-+/,*.+*-*+,*+-*,-*+-*+-*+.+,/-,/-,0-+1-+2.+50-92/;3/=3/?3/A50C71I81T70g7/~;0>3A5B7B6A3?/=-=-<-<,;,;-=0A7G>RHfYmsmzeUbODK=9;121,0-+/,,0-,0--0-.400C@;be\}~urhx`01/01/11/21.30.3/-2-,0,,.,--+--*-.*,.*+.,+/-,/.,0.,2.+5/+91-<3.=4/=3/=2/?2/A4/D4/I3.W4-k8.<0>3?4@5@3>0=.<.<-;,;-=/@3E;ND^Rwex}uqaw]QaKCJ<8812.+0**/*+/+,/+-3/.A@7]ePyn|rmdv\34/44054075195194182/61/4002//2,/2,.2-,1.,20,20.31.71-;3-?5.A7/A70?5/>3/?3/C30G30I2/P3-_6-t:0<4>6@6@4?2=0</<-=/?3B6F9L?VHeWzhx}vvihv\Y`MJH<?619-,4,+1+,2,-61.DC7]eKr`}muyzyulg_qW671772983<:5>:6?96?84=84<63:4292191/82.62.63.64/850=6/A8/E:0G;1E:2B81@70B71L74X75]74`81k:1|;2=5?7@7@6?5>4=2<2>5C<J@OAUD\LbVh`sj~qqmyhl^wVOkCA_89Q34D1/?1-C91RP>dlPp_vg{o~w{xujf^pV782994<;5?=8B>9D>:D?9D>8D=6C;4A92@71>70<60:5/:6/<80A:0G<0J>1K>2H<2D:1B:1J;3a<8z=<=9=5>4>4?5A5A5?5>8=8=7<6=9C>LCVE\I\NUQOSQXX]]baech_gUaJZDS@Iq=?[<7XI<gcOw~dryqmbsZ672893;;5?>8C@:FB<HC;ID:JC;JB<I@9F=5C;3?81<70<70>90C<1I>1L?0K>1H;1D:1E;2U=4z?:><=6=1>1>2?2@3?2>3<5:7:6:5:4=6H=TEYKTLJIBFAHAMCSFZIaJhIkIkJhLbKWMMz_Tq¸q~j550661983=<6B@9GD;JG;MI>RNIWRUWPUQILJBBC<9>94=82?:1C<2H?1K?1I>1F;2D:3K;3e=4>6=4;.<,<-</<0>1>1<09060405.6+9,A4L?OGJFC@?;?>?D?K@RA[BeDnHrMrQoUj]evr¿54/540760;92@>5GC8MH;SNE_\amlrpjf^YmQLWFBG@==@<7B=3F?3IA5IA;IA=L?;\=7y=4=1<-;+;+;-:/;0<0<1:/6-3,1+2)4&7'=/D:H@D>?6>3@7B@CHDODYEdGnKuOuSrXoco~ѭƿ:8196086/:70?;3GA6OG;XQKifuƌ€om\ZuOL_GDLEA?IB;QFCZLQcNVmJN~D@@5=.<,;+;-:/:1:2;1;1:06.2,0*2(4&7';-A7E=B9>1=/@5D>FFHMJWKbMmPtSuVrYn`mvyץC?5@<3>90<8/@:2G?5OE9YOKjfyᣧꞠߎ{zig[WuWMZaHLtKRSaVeOYGF@6=/<-;-:/80919290:/:/8/3.0-2+4*7*:-@5E=C:>2=/@3D:F@IGNRR`TkUrXs\r^nblopĔLF9JC7F@5B<2C<3G?5NE8WMFgbs⦫蒔ׅ|q]wN[JTNYNXIOCB?8>2=0;/9/7/708/7,8*9,8.5/3/2/3.5-8.>3D=D>@7=1>0A3B6F>MJV[[i\p_rdsgrlpsmͽTL=RI<OG9KB6IA6JB6OF8VMDe_k}~֟陚ޗʟza|MZELDHDECB@>>9>5=1;/8.7/6.6,6)6)7+8.6-5-4/3/4.7-<0B:E@C=?5=/=->/A5J@WSaecneqirlsqrzm}üYN?XL>UK<SH:QF9PG9SI:WNCb\bus֔ܓ֓ƞ|hTgFOAE@AA>A=?;>7>3<.:,8-6.5.4-4,4-40506-6,6-5/6.8-:/>6@<A;@6>1<.;-=0E8TLbbhojrirgpmn}m|[N>ZM>YL=WK<WJ;WJ;XK<ZNA_VUicuwsŽubPbENAE@C@??:?9>8>5=/;+9*7+5-3.0.//.3.61553616071:1;0:0:3:4<3>4@3=1:.;.@4OGbamsnwit`leh|htçȩɢˠϧҴ[L<ZL<ZL<ZK;ZK;[K<[L=\N>]QHaVZj`vvmxxhSgEL@C@A?@>:>5>5>7?5?0;+8*6,4.1/-/+2*9-?4B9A8;5572<5?7<5928.9-=1@5=4918/<2JB`^qvr|guYi\_r]cr|~}[L:[L:[K:[K:[K:\L;]M<]N>^PB`QLeXbqeuwgP^DJ@B@@?;=5<1=3=6@6A4=/9-6032/3,2*6,?4I?PBM<B7682>6B<@:<39-9,<1>6;4625080D<]Yrus}cuSeTWiQyW{c~j~lnpu\L9\L9\L9\L9]L:]L;]N=^PB`SIdUSh\gsjz}nX`HN@E>>>7=2>2=3<3>3@3>2:1644818-5,71@;KDQDL?A=9>7A:C>B<>6:080:4<683312/5/@8XSoro|\rMaOQfLsUxa{f|g~hhkt]M;]M:^M;^M;^M;^N<_QCaVQf]clbspj|yɀhfRREG?==6>3A6B7=3:0;1<191758<9>7=7=:B?H@H@EBDHGIGGDEAB=>8:576878561200/3.=6TOjohxTmH\MLveIoTu^waxazb{b~bhoq]N=^N=^O=_O>_P>`RCbWRg`lmjsp|{ƝɀqcZPNFD@:?7D:G<B7;1:1:17/61:9@ACGFKHNEK=D<CEKPUPSHHB??:=8966867635/2/0/3/;5OLbi^rMgEVKFhaDh~PpYrZsZu[vZvYuZqZkY[M=\N>^P?_RAaTFcXSg`lljpqwzŢ˼òrg`ZTRJGD?E<G;D7>4<4;37/5.93?<FGLRPVJP>D;CBKJRHN@A;9;6:5866665605-2.1/3/;6KJXdTlHaEPsI?[Z=`tHiPmRnSpUpSmPhMbJ]xGTI;WK=\O@_SEcYRh`ilhmnps|őҩԼqke_`\ZWSNKCE9A3>2=5=5907-9.=4A=HINPJK>@8>:C;E9A595584948575626-5+4,3.5/<7HLPaJeCYCG`G9RT8ZjAdJhKiMkOjNfJaG]{D\wCHC7ME9UK>]SId\]idzjhklruΒ՞֦՘w~fc`Xb\ebc_VOF:=/<-;0;19/9-:-</=5A<FBC?;8481=/=-;.82675957564616,7)6)6+8/>;GPI`C^>Oq?<RF4TX9`oFfLfJhJjLhKeIcHaFa~F;;1@=5JD;UOI^ZcdafelmwxȃӌԐҒ̐{xjus_Y\Q^WebgcZRG9<,9*9,:,:-;-;-;-:/<3>6=67427/;.<-:.83776867665607+8(8'9);0AAEUC^>V;DX>6QP7enHsWpUhLiJjKiKgJeJeHfH35,770?=6JHEVU__^}ggtt~҄Ԇψʉ||pqdeo]Q[KYP[XZUOFB3:*8)8*:+<-=/<-:+9+9-:093664:5>6>5;486787877876829,9):';)>4CHEXBY>Lh=<RH8_fEy\esXhKiIjJiJhKgKhJiJ57,67/<<3EE=PPR\[nji{ỹȁ~z|rshmm`Wo]LYHSGMGGA@6;,9)8)8*;+=/>1=.:+9+9-819499;>?B?@<;978687897:8893:-:);(<,A:GNHWGQ}FBZK:Z^Ao|S~cw_hOcFgGhIiJiLjMkLmMA@4B@4DB6JH:RPF]YZjfyxsy|wwsuptlqfimaXn^Ox[KUFK?A9;38.8)9(9)9*:*</>2>1</:0929496;8?<C?A>=:978687898:99;4;.;);)>0FAMQQUTLnYA^c@drIm}Rk|U_oKWjA^yBfGhIjKkMmNoOpQRL>RM?SM?VP@ZTE`ZNha^phstk~piyjdoe`ec\Yc[Pf[Lo\LYKPDD9<18-7+8)9):*9):);-=1=3=4;6979795;3=3?6>8;8979696:8:9;8<2;-:);)@3JDSPYSbOplIdrH^pGYfEPZ@HQ:L[:\uBhIkLmMnNqPqQoR`WH`WH`XHaYIbZJe]Mh_RjaYlb\iaYc]S\WLWSDVRBZUDgWGUIMDC:<19,9+8*9+:+:*:(:*</<4<8;9989692;.<-<.;2:596;5<6<7<7;4;/;+:(;*B4MCUM]QfQnlKZgDMZ=FN8@D4>D2IU8\uCkLoNpOqPrRoRkPf]Nf^Ng^Ng^Oh^Pi_Qi`Ri`RjaQh`Pd]L^XFTQ@MM<LM<WN>xPBNDHAA8<0;-:,;-<.<.<,<,=2>7=:<9<6;3;0<,<+;,:.:2;3<4=4<4;2:/:,:*:)<+C6NBUL\PbNebFOY=EO9AF5=@0<B0HT7]uCmLqPrQsSpSkPfNi`Qi`Qi`QjaRj`SkaUkaUkaSkaRjaQh`Od\KYUDNN=HI8OH7pK;NDMHIDC:?4>3?4@6@7@6A6A:A<@<?7>3=2=/<-<,;,:-:/;0<0<0;/:.9,9+~9*z:+~>/F9ODUL[PxaL`aCO[<GR9BI4=@/<A0GS6\tBmLrQrRpSkQfMdLi`Qi`Qi`RjaSkaSkaUkbUkbTlbSlbSkaSi`Qb\MZVFRO>VK8rI:KBMJNKHDC=B:B<C>C@D@D@C?B>A;?5>2=1<0;/;.;-:-:.:.:.:-:-9-8+{7+w7+u9,{@3I>QGVL\MlaIZbBO^;FS6?G1;?/;@0EP5ZoAkLqRoSkQeMcKbJiaRiaRjaRjbSjaSkbTkbTkbSlcSlcTmcUoeXqk^sn`niYi]KpP@I?HBIEHDFBEAEADBDDDDDBD@B>@:>4=1<0;0:/;.:.:.:.9/9.9-9-{9-w8,t6+q5+q8-yA6LBSJWLq[I]]DO[=HV7AL2;C08>09>0BK4Vh?iLpSkQeMaJaJ`IibRibRjbRjbRibRjbSkbSkbSlcTmcUqg[|ukvwhWhQBfF:mC:E@LIQOOMIHEEDDDBD@C=A:?5=1</;.:-:-:.}:/|:/z90y9/w8.v9.t8.q7-n5,l4*n7,w@7LDSIqUH]SBKP<AL6=H3;E19A06=06<0>F2Qb=eKkQeM`I_I_I]IibRibRicRibRibRjbSkbSlcTlcUnfXxrhpnXVQ?QF:fNHeawtsp_]NMFECAC?C=B:@6>1</<-:-:-}:/|:0z:1v91s9/q8.o8.n8.m6-k4,h4*i6,q?6vJBlNCXL?GG9=B47>16=06@06A15>14;/;C1M\<a|KeO^I[}F]~H]}IZzHhcShcShcShcShcSjcSkcTldTldVpj^yŮ}ijTZXKtkeҰ孩⏋njUQHDC>B=B;@8>3<0</:.}:.|90z:1w:1r90n8.l7-k7-j8.j7.i6-f6,g90hA7bE<SE:CA59=15:/39/29.2</4?04>04;/:A0JX=[tK]}KWxDWvCZxFZwHVrGhdThdThdThdThdTidTkdUleUngYvrh˶qxykÿञ}v^WLEE>C;A9?5=3<1}:0{90y90w90s90n80k8/i7.h7.h8.i80i:0h>3gE9`G<OB8?<27:/38-27-17-07-08-2;.3</4</9A1ES<QgGRnEOm@RnAVrFVpGOgDheUheUheUheUheUidVkdWlfWpl^yǰᶯҍj`SIH>B9?7>5}=4z<2w:1u:1s90p80m70j7/h7/g8/g:0g=2hA4iK;hTDYOBCA759/27-16,16,05-/5,/5,/6-08.1:/5@1=J7EV=G\=I`<Nf@SkFQhGH\AheVheVheVheVheVieWkeXlgYrqcӿõƿ֠zm]PLAC:@7z?6u>5s=4q<3o<2m:2l91j81g91d;1b>2aC4cK8fVAc\HQQA<A539.17-16-05-/4-.3-.3,-3,-4--6.0;/5@1:F4=M6BT9I]?PcFM^FBQ?heVheVheVifWifWjeXkeYlhZqseܳˏpbZNNB|H<uD:qA7n?5l>4k=4i<3f=3c@4^B4XD3VI4[Q9`[B[\EHN<9?34:/39/38/27/16005//4.-3-,3,,3,-5-08.4=18D3=J5CR;IXBGUC=I<geUgeVhfVifWifWkeXlfYkiZoseʾѭ|mm^]OuM@kD7gB4eB5bC5_E6\H7WL7OJ3ML2TS8[[AVXAFJ9;@37=26<26<26;35:4493382160/4.-3--3-.5.2906@39G4=L6AP;@M=9E8eeTffUhgVigWjfWkfXlfYji[ougнx~eQgN:_H4]H4ZJ6VK7TO8QR8LP4KP3RU8YZ?VV?JK9@C5;?49>48>58?68>68>77<56;54:3171050/6/2:06C29I4;L5=M8<K88F6bgSdgTghVigWjfXkfYkgZjj\pwjĹx`eV=ZM4WM4TM5QO7NP7NS6LT5PV7VY;YZ?WU>NM9FF6?B6<@5:@59A79A79@89@79@88?76=54:33:15@19J3<P5=P7=O8=M89H6 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Border.miff b/PerlMagick/t/reference/filter/Border.miff
new file mode 100644
index 0000000..f1f9e27
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Border.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=90 rows=66 depth=8
+page=90x66+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤佽D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPA齽WN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3꽽[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnEݽ[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮ƯʪǚպŽ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Channel.miff b/PerlMagick/t/reference/filter/Channel.miff
new file mode 100644
index 0000000..e30a527
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Channel.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:000222666888:::999888999888888777555444555555111111444777999???FFFJJJLLLNNNUUUtttָRRR:::777777666333///000333666PPPlllPPPRRRuuuzzzYYY///000555777888888666888888888777444444666666333333444666777>>>EEEHHHIIIKKKMMMiiiѱȓDDD999999666666111---000555222EEExxxcccJJJKKK]]]lllYYY,,,,,,000111222222000222222222222111111333333333333444555777:::>>>@@@CCCHHHEEEUUUmmm칹É<<<;;;999555111---,,,///111000333IIIlllkkkHHH===555>>>IIIYYY,,,+++...//////---,,,,,,.........//////000000///222222222333888<<<>>>AAAFFFHHHQQQ___yyyڧWWWCCC777///...------///000//////444ggg~~~iiiYYY```|||___,,,+++...------,,,+++(((***,,,,,,******---...///000...///000888<<<;;;>>>AAAAAABBBKKKhhhrrrSSS<<<000---222222000000000222000eeeYYY...//////222333333222---,,,***+++---+++,,,---///...///444666;;;===;;;;;;>>>>>>555999OOOiii{{{vvv}}}www\\\NNN===222///---000222111000+++[[[vvvOOO222333555999999:::888333333---///111///111111000///444;;;AAACCCAAA===;;;<<<EEERRRFFF777RRRjjjvvvvvvsss{{{zzz{{{vvveeedddPPP444***...+++)))'''''')))WWW~~~{{{~~~}}}~~~oooLLL777777999<<<@@@BBBAAA===<<<:::999999666666666666999???BBBHHHJJJHHHBBB@@@???<<<CCCAAA<<<EEEccc~~~yyyuuuzzzpppkkksssoooXXX???333%%%+++:::CCCTTThhhhhhkkknnnkkksssttthhhNNN888999>>>AAADDDFFFEEEEEEGGGEEEDDDCCCCCC<<<999999<<<BBBIIIOOOPPPKKKEEEAAA===GGGvvvyyyppp```–RRR>>>GGGeeewwwnnnmmmsss~~~dddSSS666666===BBBFFFHHHHHHJJJMMMJJJHHHFFFEEEAAA<<<:::>>>EEEMMMOOOOOOKKKDDD>>>777˛ĒaaaHHH԰gggWWW333555888===DDDGGGJJJMMMIIIMMMHHHEEECCC???>>>===>>>@@@IIIPPPHHHKKKCCC555@@@͇߮Ӆuuu111///444888>>>GGGOOOMMMXXX|||[[[FFF999666555:::BBBKKKPPPCCC:::000BBBǸǮ䉉:::666333777<<<IIIVVVTTTdddnnnLLL@@@<<<AAABBB888:::EEEFFFaaaݺDDDAAA;;;555:::FFFTTTWWW]]]fffRRR777:::RRRȳѻʡOOOMMMFFF???===AAAMMMSSSWWWoooaaaμ¼VVVWWWVVVPPPKKKFFFEEELLLSSSVVVǻAAA[[[[[[YYYTTTTTTNNNRRRWWWXXXѺǷuuuXXX[[[ZZZ[[[XXXZZZWWWXXXZZZUUUdddwww{{{fff|||ܶƽԸ}}}ԯ[[[[[[\\\YYYZZZ[[[^^^^^^[[[YYY^^^mmm鿿Ϻпggg|||aaaeeeyyy[[[[[[YYYYYY[[[]]]^^^^^^^^^______aaa|||ڲո§徾YYYeee~~~\\\\\\\\\]]]]]]]]]^^^]]]]]]aaacccgggǩˡǴIIIppp|||~~~~~~^^^^^^^^^^^^^^^___^^^VVVaaaooommmpppéͺNNNrrryyyuuuvvvzzz{{{{{{lll_______________```\\\___}}}qqq|||ȲջӲ\\\LLLuuu{{{ooorrrxxxyyywwweee[[[______``````\\\cccwwwwwwccczzz븸ڽڹ===AAAhhhttthhhmmmsssssslllbbbNNNIIITTTYYY___bbb```fff{{{ttt]]]lllƒooo˺RRREEEOOOiiieeegggnnnhhh^^^YYYWWW[[[DDDJJJ\\\```eeezzzsss]]]iiippp^^^|||ɾ999AAA777QQQddd___ccclllhhhccccccfffbbb444:::OOOVVVggglllQQQ[[[yyy~~~\\\pppŻkkk###///^^^sss]]]mmmpppkkkiiieeefffggg***+++999EEEZZZ\\\[[[yyy~~~sss```dddſ333888DDDqqq]]]rrrooofffgggeeefffkkk...+++000:::LLLXXXnnnlll^^^fffjjjȽKKK---JJJKKK```llldddeeekkkiiifffppp@@@>>><<<AAALLLUUUeeewwwyyynnnlllhhhjjj׹糳ֶ҂333FFFuuuIII<<<gggjjjaaakkklllooommmvvvUUUVVVVVVVVV\\\```bbbmmmwwwppp]]]WWW]]]fffnnnjjjոŷ˧̼```vvvOOO;;;222;;;fffooojjjmmmjjjqqqxxxqqqccceeeeeedddeeeggghhhggggggfff```QQQLLLSSS[[[___ӷռ֭ɩ~~~SSS'''555777999999gggwwwppppppoooxxxwww```hhhiiiiiiiiihhhkkkjjjiiiiiiiiihhh```LLL@@@@@@CCCUUUһӻʲ}}}wwwAAA'''777KKK===777888hhhvvvqqqpppyyy}}}bbb```iiiiiiiiijjjjjjkkkkkkkkkkkkkkklllkkkZZZDDD<<<555???βѠyyy{{{sssvvvfffGGG^^^KKK:::888888iiiwwwppprrr}}}fffbbbbbbiiiiiihhhlllkkkmmmllllllllllllmmmmmmhhhVVVEEE888̟~~~zzzzzz{{{{{{yyypppvvvWWWOOO```CCC666:::777888___xxxpppwwwjjj\\\gggaaaiiijjjllljjjjjjkkkkkkkkkllllllppppppffffff___AAArrr͝||||||{{{{{{|||zzzxxxuuurrrooolllvvvyyyZZZUUUMMM999888;;;444888VVVtttxxxrrrZZZ___eee\\\hhhiiijjjiiiiiijjjkkkkkkllllllmmmfffsss}}}777333<<<???^^^ذ~~~~~~~~~{{{yyywwwvvvtttqqqnnnkkkeeesss___EEE222;;;BBB999444444777LLLrrr{{{```ZZZaaaaaaXXXhhhiiikkkiiiiiijjjkkkllllllkkkeeeCCC555:::***ZZZݿ}}}}}}}}}|||wwwssspppooonnnnnnkkkggg```pppzzzNNN555///333...444;;;000---555AAAsssnnnTTTZZZ______WWWhhhhhhhhhhhhhhhjjjlllmmmmmmllllllꝝKKK===OOO’~~~{{{|||{{{zzzpppkkkiiihhhhhhkkkiiiaaaYYYmmmvvvGGG...111777666222---666999111,,,@@@zzz^^^QQQVVV\\\bbbQQQggggggggggggfffiiilllmmmmmmjjjdddrrrAAAެѵ~~~~~~||||||zzzvvvjjjhhhfffeeeeeeiiiiiifffhhhnnn888111333555333///000...///888;;;000DDDoooGGGLLLLLLWWWbbbCCChhhhhhhhhhhhhhhiiikkknnnhhhnnnpppooo𻻻Ǩ}}}xxxuuusssooojjjhhhfffgggiiillllllgggnnn)))111000111000/////////......222333@@@IIIBBBMMMGGGXXX]]]444hhhhhhhhhhhhhhhgggkkknnnggg}}}Ӵǣpppqqqqqqooojjjhhhqqqmmmjjjggggggfffccc___QQQ***000111000///---...---,,,,,,)))---222222666DDDHHH^^^ZZZ,,,hhhhhhhhhiiiiiijjjlllnnnhhhlll贴ooorrrssssssooonnnqqqlllddd^^^PPPUUU]]]]]]nnn222222222333222///......,,,***++++++***---777999333>>>\\\QQQ+++ggghhhiiiiiiiiijjjnnnlllfffhhhڠyyyeeeeeejjjllliiihhhccc___YYYeeeEEE999EEEppp\\\222777777777888888777666222...,,,(((***,,,///======111BBBEEE///dddggghhhiiihhhkkknnnlllddddddhhhXXX]]]\\\VVVQQQMMM^^^@@@===GGGiii```FFF::::::888999999;;;::::::999777000,,,+++))))))666999888;;;///\\\___gggiiillllllkkkhhheee|||mmmRRRUUUSSSPPPLLLHHHEEELLL]]]aaaVVVWWWUUUMMMCCC<<<888888999999:::;;;<<<;;;999555666GGGGGG:::@@@HHH444 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Chop.miff b/PerlMagick/t/reference/filter/Chop.miff
new file mode 100644
index 0000000..2bd3d71
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Chop.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=60 rows=36 depth=8
+page=60x36+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:H@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤䫸|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtn틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPA飤vAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3ꔗԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnEwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿcG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~enmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlgqv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|Vzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbDш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgGʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpPwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvV]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqW`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`JhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`LlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|Ge]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;ٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.ԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-ìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/ColorFloodfill.miff b/PerlMagick/t/reference/filter/ColorFloodfill.miff
new file mode 100644
index 0000000..e05b152
--- /dev/null
+++ b/PerlMagick/t/reference/filter/ColorFloodfill.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾ
diff --git a/PerlMagick/t/reference/filter/Colorize.miff b/PerlMagick/t/reference/filter/Colorize.miff
new file mode 100644
index 0000000..ac41134
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Colorize.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:! ! "! ""#!#!    !"#$#17>S8R$7&0;>MH>6+) "" #"#!"    "$ ,.>U6V5 ./3C?8/+)"""$"   ! #"+'&'C^8c?,$##)$-' "" $ ! !#" 3/E<2+!11NgCh8O.789KFG@2( "## "*)H=UF@8-# 8)PNRQeYcX[K]LPB2%  !#%"('@8TEVGK<=-/#3 Q;U;dFaIW?VAG8-"!  #'"2+I8WDXFO>I3C23(.$H5N5Q7R7R:P=D6+"! ! (&-+%) 0$=,30=9PBP?K;O<I74&'8)A+H.M1L4N:J:C2,!     "%#$!%$#!" !!"!$"#*(,!5$6))-$% +&/,43759/6+5(1#' /A.C.D,G2L=QGK@>//#  !!"! ! %.""!2'1%1/"!!#'"$*.47 9#7-<-3!;2OJOLPMZVecfiXX=23&!#$$"$%   $     *$*( % " "$ (+48";%7+<,?.772d`pukxp|y|zysxgiFA@7"%%++AR<P*7'  ! " #%"%",!1%:%>&=*:!1=D/*idz|}|~tv_\]X %$09RrYPvGb6G$,&! "(*0))## !+& $##$#%'.#0%7)=,=*8)308%*UR~}z}|xznmsmvr ##*5Lo\__Sw>a.O&9!%'9M@W.=%("&$! ($"'$()*0+7'7*<+7-4+2'*:7pp|{}zwxgdyp}w$# ""&)G`W}YZV|PvFl=[2C'/'+&.$)(%"$!$'%.03;(6-:9<18=@:2( ab~~|}sn|o~t'&$! ##'(E^R{RVVxV{WUp;F ' #  "& $$&% /+763838:97:=EK>(b`x|x|q}u( ' &%##%%(*@UKjKrQvOlHhB_4J( !###  !*)#+#6503167826+8D47"rj|sudwj|ssktn'''&&%&&&#/:<M@]Cf=[6S)1#"!'!# !!"%$899?9=9=+2"0P>M3fWqceU\G^CcMj]ojeb&&&$%&&(' &$)22M?b?Z8Q #  !%!" "##(#55@D=A9?&2.C/C(B.?(F,P4[:\<V?ZSZY%%%$%%%'''%$+;;MCM2;% #! !#!  &"( $+(1.6'!)'! #!.+CE>B5>$0*0@'E2N6U8U7X8\7U8[L__%%%&&&&((&#.8CZCS:8%*(#& +18') $"% &"GH=D,:0 ),J-S7U8R3Q3T5X2Y7[DRK&&&&&&'' ,,0628<TFuAf;>2.&* !#!""'!#!!'%'($#**" !$IJ8@#42 #1K-P1O0N/P2S2T-Y4U;A3'''''(&-0>P>Y;\CcMcW[[K8)& $%$3, ),%((++- !%+7=3;)' "DG1;1 2/H/O1K+M,O/Q-S+U0O4>+&( )!)!) '!,0;M>\5Z=kVmp[yRtUZH<263+-' ,$ )++12703#)/3*-;A)82%-%?)J,I&K(M-N*K&E"50$&)!+").1<O=Z3W;`Nobskkid[^CD5252<:32" !##$# -3+/!$#"!4:2 4&#(!/C&G"H%J*G&C">!7!9"!"&)/,:H8S/P4]DoNoPkMkKgD`3>+))$,(<9@>/- (&%!+.(52 ,!-<'B F"H'F#C$A%?$?""&265H(E.R=gDnEhBf@iBdAV-5-&+")+35B?@=+61!5,YAF0AI%J(G$E&B%A$D#!.4.C-N>kDuAmBeAiAmCa<D+)/$/!+(-175% #%&!33!''\<jMH.BL'J)E"D&D%D#H%''+66OGuH{?hBcFgB_;I0..#.$.",!)(""%+( (0/$. L2jFU>1?J$F#C!G'H'G"M("&* 13@[Fj=W9R=R7?/+,#.%/'/'%$!$$-,!$"*4&,.''N/R4M5*$?!J#F"F%H(K(L&R+&&'()!+!,%155>26+-*)+#-#/$2'-')#$! ,-*+,)1%<[8L,.!?#K%I&I)J#O%U*O+-%-%-%-&-&/%/$/&.&.$-#'$(-#/'0,%& )%*$.)7.P91!!A%N(L)L'L$S*S,E%/(0(0(0(/(1*1)0(1&1$1%-#%"$%&,'"# " "  )#-',),&&&  A%N(M(N%R+T1F$D&0(0(0(0)0(/-//0+0*0,0)1'+"#!!!-#.,%& !$ $"" #! $'!)'++7/;$+5((!A&N(N'Q(T0G'E%D&0(0(/(1*1)1+1*2'2(1+1*1*0((  %  ''46'%!"$!$##%&%$$ !!  ( *#(&-), 2;#+  < N(O(T,J)B#G%B$0(0)1*0)0)1)1)1)1)1*1)0*/)0(,! &"!!!''&&!! """ "!""! !  *&(&*&2'7%6"/!2K*R.L.A!C$F&@#0(1)2)1)1)1)1)1)1*1*0*-(84PLWR=5!$" "" """"#"##")',)/).$)"% +J)R/A$?!B$B%>#1)1)1)1)1)1)1)1*1*1).)@>hh}~njH>%??,* "!" !!"!!*(.'' %&J,L*:>"@&A$;$1)1)1)1)1)1)1*2*2*1(52abwyfS?'$#LKxspk88  ! !*' "$%M6C&79!<#A&5"2)2)2)2)2)1)1*2*2)0(22Y\}~~~w~vvm`7+%KGsr~}{YO'  !" &! !&E5554:#@'+2+2+2+2+2+2+2-2+3(64SWsu~}x}ywl\9+=5fd~~ol5/ $"!#8/5- &, *3 19%<*"2+2+2+2+2+2*2-2,4(@?qt~{toukxli[XOfcyx~~~~{QG" ! #%&?4,#!+.8)6)2+2+2+3+3+2+1.3-4(:8fj}yvnwitgjcpp}~~~~~}j^5)  (,.;.  !%4*.'2*2+3+3+3+2+1.4-6);7cf~y{pqak`ooz}~~~~~~~~|uaV:.$ "#.##!$8)0#"%(("2)2*3+2+3+2+2.4-5);7hl~y{pi[_Ysw~}~~~~~~z}zrld^S)"%&'''3%&"%3%,"#   %&$%3'4)5+4,3,3,3-3,6,ECil}}}xwnmc`W_[ps}~~}~|~~~~~|zvt}}~~wsf3%%'''''')2 2#+*)$! !  !!"" "01&). ! \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Contrast.miff b/PerlMagick/t/reference/filter/Contrast.miff
new file mode 100644
index 0000000..c158c37
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Contrast.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:#" $#!(%#)&"+&!*%!)#!*$")#!)#!(" &!% &!&!# #!%#(&!*(#0,$71(:4)<3'>4(E5(e;-?0?4F>MPORKOHLD?=.<+=+=(;':*7(7'7&:*;0@1C5A5A.%,(&)%$)%#($"%# "" #" % !'!A,-yDBbnosHAcHCUsuzwyiNLI"!#" '#!($!)$ )# '" )$!)$!)$"(" % % '"'!%"%#&#(%!)'$.*"5/'81&90$;2%=6(Y;,~:*9*F;LOMPKPJMD><+<)<*<(:'8*7(7&5&8):/?3D8C74*!+((+&%(%#(%"## #!##!'""$ 5'&j9/WZfoA6]@6NUV_eiYNLI "" #!$$ "$ $$ $ # #%! %! %" %# &# '$!)'$+&!.("0)"3+"8.$66)E7*\3$t2#A1H=LGIKIH?/<'<+:*:)8%8(~7)}6({5){9*>.@8IFSJ.0),'%*&"'%"$&"!&! &#"%"$$###!% 7"aEFuzA7s2(G*)9288>F>NOE " !! ! ! !!!!" " # !! $! $!$ %#!)%#-'#/'#1("6,&91,A0+N-(i0'6+>0D8LGNH>-;):*9,8)~7'y5&x5'v5)t6-z=2C7E@kczO\O44,('"#!# " #""#!#$!"$!"!$% `\[֍jqRUgZik~UZI "$"$!!# !  ! !!" !# *%%-'&,&%/$#1&$2*'3-*;+'W.'{7+:1</B5F;;09(8'6)6)x5'x2$r2%p3(r81|A;A;URpnGM=.1'"#$ $ "" ""$#"]hKн¥OXA!#!"" "#!$$!%#!%" $    " !!% '",&".'$,$!,#"/##.&!'*#*& ="X1&u:,:-6)=.9.7+{7){9*}6*u2'k3&e2$n4*{A6~F?NLqy{WtUDQ=.,'#! "$!#"""OY8z|ЛˡvpDN:$%!%&!'%"+(%+(%+%")#!%! %## !#!!#!!#!#"##!"##&",$ 1(!3+$2+%.(",$#-%#5%"@ $5 #(#@%Y0'v42y3/q8/w<1|;,v7(y4&v4%e5#f0&c1'm9.B9I@`R{rydfbcH[H'.$ !KO>}j|krsxnk@I9)*%)*%++'.,(2/,4-,2,).*'.*(,('*$$*##($"(%"(%"('$+)&0*&2,%80&:1)90)2+%1)%0)&.+(4)(2(%,(4(R-%|86>=x=6w81q:/o3)i3)e5(i-#QM\WbA2^I8hWBxtSjdÃ{x|ooO^E/,$!*2E@0_hKc}SiZnckhvwvveaBK9*+&+,'00+31-62.84073.73.82,60)4-&4-'4-'-*$*'#*'#-)$2.%90%?4(@3+;0)5-&2,%..'7+%AEDFz=5JGC6<1@3A.=0<@@Bh;2k3.<HNPYTdO<U^@hPah3Q4UOc\mgut{w~jwatTfCK@$.&71#VP2r~XjYiVqc~`w[HR>()$(*%//+42.843:62:62<70>5,:0&8.#6/$5-%2,%-)%+)".+!5.$<1%?3&?1';.&4,$/.%).$u<:Yj356 >48.<1C66%=1@:BICCID@D.'B:`L]FplHRJKU]:P8S=_BgJtJzRZ}pbmQ3+84${ra߼cvaN\D%%#''$**&/.)65-992<;/>:+:7,@<>93-4-!3+"0*$/+'.*%/,(20,:3+?2#81#;,&4+((.$10$G>2)0=#6"2$:0>/>0?37)6055718'5!8+XL`]R[FH8,E;LONWR`MdNuM|V[|lofvkb߇sl## "!&%"*+%00)96/@=-=<)NMM|TMf:4A+'''$&$+*"2.";2%?3%3, *&#&#2%"~178-8$6"<*=1906(8)>12)5-;1835/4 4!9,A8JHHE>36&:+JEUYSZVhSp]^`iQo莙[PŽ+*%(%!%#(& --&:3+G=/E;0^[kmmA?L44?.,,0-23#,3,/8B<JT;FES<3A39)>+8&5)91<682<5=4D=6,50617-6!6!5(HA_W=17!8(@7NLNOSWbnVn]}fkjfxwR\轸52)2/',(!&$+'#70+D:,H:-UMae[KEi+-4,+*F?BubOT9%5!8(:,>5@894EAC>;2K@I?3355601%;':*7-WSGD7#7'>2WPF?XS^`epka~jmp}lxUYwq@;0>9/72*0+$.)$30,=7*B6%KBHǿv^b}JZU][jQZ>AGG?6=.>2@6;15-91;24*2$8!A3GJ;?53:9><:/@1[UMQ>47*:,B1;,I>SPkp~d}ov񑕑tdHC7IA5H@5A;/;4)6/&62+<9*B9%JCFûIUGJB>@1I>HL?BB<E94'1*74>29+3!4 6%5)5+=3;93;394-4#RGPQWU7-8'9&9(:-?2jc|{4A)MD7MC7KA5E=0E:/@:1C</G=*MGI۪鰷ߘ֒rFXGAGLGN>;NMHKC?<0>/9*:.?973938*9*;6EB8$7 2&607+7%<(B9JLdcMC8(8(9+9,7([M~rwu|ksgNb=MB4LB4MB3I@2K@2I?5I?2K?.HA<^Znz{ӄhotM\AKALOHPZIN>4C;52B59(7$8$8(8/<>8?8<7A2G080'7(@8D;F84%4(=;344*5*NB<03(7)3#H>kxTo}g־׾Ժ‘ϩL@2L@2M@2J=1K?1M@4OA3OD3MB7MA?TKZmeʢv?F=*HBKOMT;65%B8@=F<5#:'7&4'@67*1)1/-:;.=GN9B=F36=:SS97@;5*7%7*YO<391;47*6+}}auNi~[bMwY[vLbV{j|L?0L?0J>0J=/L?0N>3O?3OC2OC2PB1SA?[QozȔzBXIOGDOSIF9,4#A7ADXPUG5'4*;597:B8F3D5O9`csrBX165$D7^ZIF9.5#7"5'KG<7<:<<?72&gbYpK`KR.^xIboutvwvM>.L>-L>-N?.N@0N@2PA4OD4OD4RA1U=5`Wj^gL]FPBC>48(<-945-:(WLB4:.@B=I+7)5(1*<Hb{^b:52!s&8.86PL;07*6)7.QG72:=8;943$OGoPoDW;H(nYsv~hhoitOA1OA1OA1OA1OA1P@.OA0HA7WOPhZfg^jt|ӽsl`gDL<<A17)G>B95*7(83I=?19;V_RU42.+67EJEI<=3.UQWYMKddKHE>A<<FCJGC3,;98<973$G;XwLq>DCT3pXzdu`v_{e}f|[m|idQC4QC6QC5QC4QC4QC.M@0VRXy}˩żqSNCVX?A<46-H?m`?23,50A6:-40??chW]`dfjEGBH3=Yd~_[86GBKB847DCM=:6,:79=865):1wOpOoK0&AQ5s\{cmUpWx^y[wVci_uQMA3QD7RF9SG:RF7NC8ZQXzzhnzeytjm>B9690OA^P1'GEF=1&1+4+:6cfhs|w|9A0>Vbszgm<8=;<6:2@;DD>=6,9-96:?:9;071gLqM]-,3:&bvNqVdIjOrYqShJ\ACZ,=Q+E;.J@2RF9UK;RG6^UZ}{_hu~ŬɅid_jd狇~}ROA:;0B2<-QPSP;4;58+8%=6=Cnxgm<8QWIP>@AB=:;8>3?8>=@A><8/9*82>?995+IGKqQuvGBCB152"BP0cH_@bHkScIX~@Qr=Mc;Rg=54*<80NA4RG5\VP{uwt]_pp䱱崳ޱݭ֠ldySLIrLB[Sok5-3":);17,<2;2;)?0=462YUPG5#671B1H(B-A7??:A:?=<>958*:'9)<5;/4'fld|GqC[)&23''(CJ+\pHWz<]@hKbC]}D\yE^vDZu>&(!,,'@70H?3a_eljMM[]Ӝ✛זӗؚΏxUePOBdN=[^w|:,9":(6+:+5';.7'9,9/:0@69.1':B7H4G.C1C?F>:@9=<>B:37)8&6$9&;%@7lFoTw[,4!!$NJ)q^Ux9hHmOeDdI^{E_zCaC""+*(751ST`YZZYۛߏГ؛~xjPLTS?WS:WPksQF6%;&8+1(=*8'L@9+9(6'6(>1>3@D=J4B:=@CAE<;<9A?ABBG>:8*9)9&; :%XZSuErAM&(')"5< ܬnZUy8oLlO`AbI_G`CfG!# "#,.$@CBQOdpn֑͝ՙŃydZVQQ=ZRA^Q=S>_^GG2-7&7&8.4(;*;*I>7(9'8'4(2)B;CG6AQVeaKG=7=9??@D@E?B?;7(;);)6!3'drMlNa;2& $8'eڝ@T0Ws7gF^C^}>fLeL`AmN1/$//(-.&14 =>/GF6^\`چ{wwm|eWP`O?]RC_UFwYJH:704/7-8$<#:-9(4$@8SL6%8(8,?7B>CA@>WXigE?>;=6>:>@AG?E@DB:9)7$7%1 JEizT_zWJ$)6= t_lk<E2.7"^s=eC[AeGhMlOjKuVG@4H@5HA5HC3OF9SK9VNBf]dsgxj^gSNQLJHPJ=ZO>cUA`ZGUKQF7*3+;3:16*9):,:*1 8,?7K=E<B=EE@AB?<27(:,?8?C>B?=?8@=@@DFA98)6%}2 t/"abWYWQw\FVk5xtXBN2,."$%-4&^uAkGfJjOeDnIxUpVWOBYQBYQBYQCZQD[TB\T@\TE\SDZQASN>C@2=:,EB3NM<TTF_WPR51;'9*:,8*7*:+<./;'6)9/<@>D?D?E975$5#8'A7CBAB@=B9D?DDA<5)5$~4$o/n3%QIQFYPl\wHV9"'*%)(#**$,3%`yFtOmQmMkFwUwY[F^UH_WI_WI_WI^UHaYM`YK_WH^XD]W@]WCSN==;+26)39,6<2F@1YPQS9+5$8):):(9):.036)?9LQA>50945*9'<(8$4'>7F@G?J?B:613&}2#t5$l3#d+|;.ODVKWQTI3<!#*0.>?4-+)+#*0"ayFsNnNmHxVd]E[H_WI_WI_WI`XJ`XIcWScXXbYOaXMbYQbXK`XFMI:67,/4))4&/2VCkhY[;08*<0>2@4B<<1A2OHUQIE9,@.v<,i8'v3&{6'7(3&6+9/>0:,2'2(u5'o4%k3&b1$e-"C7J>QLUVm]]lC:F*UaI<A+*+))#+2$b{GtNmLpObaK]F]I_WI_WI^UHcZMaYKdZPcZNbZGb[HcZOdZNd[M^WIHC652&*0yE;>@WXWTF?ICNJRORUVUUTMOKKB?9-};-w6,s4.q4,o4+k4)j3%k2%w2'3(3$z4%p5'o1&j,"i/&^,#g5+zK;OCOKWPIJ6DW4Wk?6F$(0,-&)*#*0"Vm;vOnOwYgQV{BbF[|D_WI`XJcYM`XJ`XJaYKaYKaYJbZLcZMgZKgYN\UJ[WHRM:0/eD5B@ABRQQQHGB;F=KLHMLNMLIFJFC>5,q6*r5-{3-w5*r4)p3(l3(m3)l2+l1)l2(j3(h2)e0(a.%^,#Z* h8/OHNJRJp]IQcCKa<AP1+2)* -.'',$)*JV5qRx\q[Sx>YD`HUvB^WI_YJ`[K_YJ_YJ`YKaYKaYKcZMcZMdYM[QHnkdywg). %,-.#/,#N7,FCFJCAKHLLLLMKKDJAIC;2u6'o7)v3)v3&q3&o3'o3)o3*l2*i1)g1)f1*d2(`.&]+$Y+"R(d5+OKVOwYMSP?9D1%/-5%4;++2%',"'+(() >G*oQ|_YzDRs=[|D[}FQrA^XJ_YJaZK_YJ_YJ`YKaYKcZMcZMaYJ[TK|壕5:'(/ ,)&"L54Ӎ`]?@HLJLHIHDH>H@A75(o5'q5&q3&m2'n2)n3*m3+h3-c0(_.%^0&].$^.(Z,%U*#M%`0(SOqUI@A3(1%"' %%#!%'/%/<-$/#!$"&&3<%qWkRKh8Rq?YxGXyDOlB^ZK^ZK^ZK^ZK^ZK`ZKcZMd\Nd\NbYJed_ޢ<?'-(B<;ڀ=:B>EECDFAEAC<6-r6*n4&p3(l2)m2*m5-l5.`3*Z/&X.&W/&W/'[/)X-&O' E!^4-lMH72("*%-"),&)*)%*$!**5'-9+$' 2:&{oY~IGa5Mg;TnA\zGH^=]ZK]ZJ]ZJ]ZJ\ZJ_ZJc[Nd\Nc[L`XI]]]jfQ4<0²M@6.C>D?ID>:7/s6.o5+o3(m2)m2*k2,f1*Y/(W/'U.%T.%T.$Y.(Y.(U-&X2*aC:**&$& %(!''%(#* #*")#) +2&-4'""7>/ni>\5B]4B[3Oj?\yI7G1_\N_\O_\O_\O_\O`\Nc\Se]P^\IhfbhkQkwgoc5)@6H9B4{<2s80t5-n2,h1)e/(c/'^-$Z.)X.(U,'V-'Y.(\/*\3(W;,}m[fcT$$)"#(!$'#' "%!"%!"&"!# "'"&0('1'4>/=J66F.CZ8<S0PgCWpN(5)_\N_\N_\N_\N_\N]\Mc\Te\Q]^H}~ȽίA18-;878s:7b:5b8/b7.`6-Z3*X1)a/+]-*Y.(W0)W5,W<1S>-O@,{{fEL<##( $(!#' "% !$!!%! $ " % % !)!%."%.)3#8G1=O4VhKRbL )"_\N_\N_\N`]O`]Oa\Nd\Uf_S^_IhqlϵlU;+1&o1'`8,d50e72e94a71_5/b1-\2,T3*N3)?."FB/OJ4OO6hoW%0 %)#%)"&*#%)!"' !%!!%! #!"%% !' *1),4(&.!1:)S^LGRE&!][M_\N`]O`]O`]Oa\Nf\Ud`S]bLdrkоu]j?+R,S*"Z0)]6-Y5,X4*T7.O9,I:,YR>56$+258!ggKPS>$)*/)*.'*/(+/'+.(*-))-(%)$!%! # ! # "$"1611;-$/6A1:C9#*$ZZK][M_^O`\O_]Ob\Of]Ud`S[aJ_rjʸZH3G7#M>)L?+GA0B?->@-T\C2<&.4 79!^\BSM;77*-0),0)+/(,0),2,.3.-0,-2-,/+*-)#(% # !! %*:'-<(,9&/<-#,"R\GV_J^bP`_Pc^Qc_Rc^T_^Q]cR}̾b]CA;$E@(C@)@?*=@+:?+6=$=B&QW7UY=HH3HF2FC/>:+43).0)+2),4),3+,2*-3+.4,070/7.,1))/))4$;P,=T3/>-4C/=N7(3& \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Convolve.miff b/PerlMagick/t/reference/filter/Convolve.miff
new file mode 100644
index 0000000..0892c06
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Convolve.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.51.82.92-91-81-81-80-80-7/,5-*5-*5-*4-*2.(2/(41*74-:6/?:0E>2I@3KA2NA1YB2sC3B3B5D=DDBE>B=??9?1?-@,@+@,?-=,=+=+>.?2A4D6C6[<2>5283172/51.20-00-1/-3--;./T77zIIaorkhVQxXRippv~uwl`_X/.,0/-30-61-70,60,6/,6/-7/-6/-5.,4-*4-*5-+4.+3/*30*41+63-95.=8/C;0F=0I>0K@0SC3iC2@0@1C:EBBC>A>>?7@/?,?,@+?+>,=,=+=,>.?2A6E:E:U=4<6283162/42.12./1.00.2/.7..J41kB>\gqigRL|NFc\[fjokgk`\]U---..-0.,2.+2-*2-*1-+2-+2-,2-,2,+2,+2,+3-,3.,2/+30+40,51-73.;5.?7.B8.D9.G=0LA3[A3q=.<.A4D<C?@?@<A4@-?,>->,>+=,=,<-=.?1A4E;OGUKUI@>:484/43.13./2..2//2/11/2/.;/-S:6rZexnpVRJFfOQ^Zc`^f\\_T,-/,./..-/-+/,).+)-**-**.++.++.++.++/++0,,0-,1-,1.+2.+2.,40.82/<4/>4/A5.D91H<4P<4`90x9.=1B5C9D=D;B3@->-=-=-=+<+<,<.>2B6E;PGh]vg`dVFI>:9023+/0+.0,.0./0.01.00.2--B96gafqzgqgwvpxm~makX,/0-/0././.,/-*.+*-**+)*+*+,*+,*+,)*,**-++.,,/-,0,+0,*1,+4/-81/;30<2/>2/A40B72E83P60g6.;0?3A5C7C8A3>.=-=-<-;,:+:+<0A7F=MFcYs}njT_MAF855-0-*0,*0,,0,,0--0-.0+-=:4chZyvboW/0//0.11.21.30-3/,1-+.++-+,,*-,)--(+-)*-+*.-+/-,/-+1,*4-*80,;3.=40<2/<0.>1.@3/@4/D2.S2+j8-=1>2?3@4@3>/=.=-<-;,}:+{:,~>2D:KC[Q{itu_y]N_I?E941-/))/(*/)+/*-/+..),97/]dKosm[iQ24.34/540751951:4081/50.3001.01+/1*-1,,1.+10,11.20.61-;2,?5-B8/A80>5/=2/>2/B2/D1/B0-E1*U4*n9/<4=6?6@4?1=/<-;,<->2A5}D7J=UHhWl|zokc~_RdN?F830*.(',)),++.*-1*,=;1[bHua~lrv~xzvjeVdN671782993<:5?;6@:6?95=84<74:5392191081/62.63.640851=60B9/G;0I<2F;2B81?61?61F63S66V74U80a9/v;2=7@9A7@6?6>4~=1;0=5F@MD~O@tUB_LeVhaumvuqnxdo\O`B<S43D1.8.*7,*?4-PK9clMm[p`sfvoywvtfbUdL7829:4<<6@>9C?;E@;E?:E?9E=6D;3B91A81?81<70:5/96/=80B:0H=0L?2M?3J<3E:1@:1C:3]<9?A?=?6A7@6@6B6A4@5?:?<?8=8<<DBOGYF|aIbPURFQGUQ\Yb_gekdlYfL]FUBJi::N6/NB2d`Gu~_wizmxj~eXgN671893<<6A?:DA<GC=HD<ID:JB8I@6G=2E<0C:0@91<70<70>90D<1J?1N@0M>1J;1D:1><1K>3~A=@B=8>/?1>2?3A2@0>2<7:9:8;795:4G<XG_NWPGJ=D<G9J:O>WC`EiFoGoLnPiMZ}HFlXJnŽÿyvbqY330551883==6CA:GE<JG;LH:PKDUOQSLNLC@D<7?82<60;7/>91C=3J?2M@/J=.E9/@81A:1^>4@8<49+<(<*:-</?0>0<08/503/4-5)6'?2MBQJII@?>8@<>C<I=P=Z>fApEtLtStWp[dtnŚ{32.32.54/992@?6GD9MI9QM?^\`rrvthcWRdIDK?;:;84=92B=0G@0H@2D?5@=8?<7P;5y<5=1<+;';*;-:/:.</<19/5,2+0*1'4#6$;-D;HCC>=3<.@5C@DHDODXDdGpKxPwQsWqao|z׸Ľ97075/63-86.>;2HA6QG8VMDifwݓЄnlWTmIEWB?D@>5B@3GE@PNUYS_bMSwEA?4=-=*;*:-:0:2:2;2<2;16-0*/)1'5$7$9+A8G@B8<,;+@5FAGGIMJWKbLnPvSwTqWl[hkoڦD?5A<3<8/:6-=81F?5PE6WJBhcwť햗}{fcTStKHTSDElLS[p`yUcHG@3=+<,<.:/8082:392:0=1901..-1+5)8)9,@6GAD<<.;+@4F=G@JGOSSaTmSsWu[q]m^hbdNH:KE8F@4A;1@92E>5MD5TH<c]jﭱ䇊wwv_|MZJTP]P\HOAB>6>1>0;08/7/8/8/6+7(:*:.512120304.7,>2G@FC?7;.=/A2B5F<NJY]^l[q^sfsitotmd|q˻VM>TK=PG:KB5H?5HB6MF5SI:a[c䣦隚ޠfKWBGACB?B>?>=:?6?3;.6-6/7.6+6'7&8)8-7.6-3/111/4*<.D<HEFB?5;,<+=-?2H=YTehcnfqlrmvvzxhkļZO@YN?WL=TI:QG9PG:RI8VK<_Y]vvǔޕ⑘ٌ˘jPcCH?C?@A<A=?==8>3=.:+8,6/504-4+6-62506*7(6,606.7):,>6A?D@A7=/<,;,;,A3UJfdiojqkqepkq|hsƱ[N>[N>ZM=XL<XK<WK=XL;YM=\SPhbuvtȈs]zHW?E?BAE@A@:?9>9>4<-;(:(8*6-2././/-3+7.43/6-6082;1;/9/8283:2>3A5>2:.9,=/MDfeqwqzkuZk^g~gqʯɪŝǘ͢Ӷ[L<[L<ZL<ZK;ZK<[L=\M<\N=\OC^SSe\prjy{gK\??>=@BAC>9=2>5>8A7?/:)7(6*5-2.-.+1'8'>1B:B7=3552=6A;<7816,7(=0C9?6807/9.F=cbx~xjxShT^tZz_ltttxʾ[K:[K:[K9ZK9[K:]K<^M<^O<]O=^MAaPUk`}w}f|IW?D@A@A?<<2;.<3=7C9D6=.7,5/32.2*2(5)?3NDXIV<E335,>5D@A=;28)8(=0A9;641305-?5]Yz}zewMeKSfJlRxazgzhknp|\L8\L8\L8\L9]L9]L:]M<]O?_QCcQHeUXmf|m{S[DN?E>>>6=/=0;390>2C6@3:0654:.8)2'2-=<PLZIP>>92;/@7E@D?>59.8.;4>77310002,;0XQy{v[sFbGNvcEkS|e~j}hhhhr^M:^M:^M:^M:^M:^M9]N=^TKf]`maonfuv©d`LO?D;:<2>1C8D:;07,;0>2:065:@;A59478>>GAH=A@@JHLJHFFCD@@995578::6501//01-8-TLuxnPnA]GIidEkVybxbxazb{a~aiqzq^N=_O>_O>_O>_O<_O=`SJf`jpmtrxyžǦƂk_TLKBA;6<3F<NBD88.70;07,3.::CFGKJOLQFK:@6>FNYaY_KKA>?:>886495:634-1//01.6-NHkrbxIi@WF@Z`@iTt\rYrYv\w[wXx[q[e~U[M=]O?_QA`RA`RBbUMh`jnmptsw̧Դġteb]UUFE=9B9K>G:<3<6=56-2*6/@<IKQYXaPV;B6@EORZNS@?95:4;48568666/4+2.012/6/JG_jUqEdDQfF:NV9`vJmSlQmRqVpTlNfJ]{EWoBSI:WL=]P@`TCcXMiaiolnpkqw|ǒز¸pig`eb^[QMF?B6@2>2@9?9916-8,<0@;GKSYOQ>>7=:D;E7>364282938576636-6)3,2/3.82JJTfIjA\EGTF6HL2Ve>dIgIiLlPjNdI^EZvAXr@EB6LE:WL=^SEf^]mhkjghnqѕ٢اӥʗ|ro`]\Sb]limiZSB7:*;,<1;29/9-:,<.<2?;HEF?:336/<+<(9*71685:47555517+7'6(5+6+=6JRKfAc<Oc<8C@-KN2]jCfKdGgHkLiKdIbHb~Gb~E79/><4JC9VOGb^ffdbaghwx̅׌ՎҏюĆzueri[RXJ[Viitpc[F8:'9)8+9+:,;-;,;,:.;1?5=350/5,;*;):+93886957655617*8'8&9&;+B?H[Ce=[7CB5-AE,fmF~asZeHiImMjKgJfJfHgG.2)24-;:4IGCVVa]]dduuǂ݄مЇϊˇ}qoa_g\Kx[HYP]]_\QH?09'7)7*:*=->0<-9*8*8+:.92562;4>6>5;486787987868729,:(:&:%>/DID_@_=MW67?;/Zb@fvu]eGjIlLiJhKgKgIjJ14)24,67/@B9MONZYlljˊބЂÆ~~srfhh^Qh]Iv[GUGMHDA;28(8'7)7*:*>0@3<.9)8*7+8/948::ABFDD><9685888:7;7994:-;);';'@7HRG^ESmA<E@0SW<xYrib|L`AhGhHgIiLiMjKnN@>2@>3A@3FF5ON@ZWRjfv}x~xwswrvmqedl_Rj]Ls]LWGK=>6615+7'9'9*9)9*=1@5>0<-;/929496;8A?HDEA=:9585878:7;9:<5<-;):'<-GCOXQYRJ\T9Vd<j}My[s[YhIN_;]x?hFgHiKlMmNoOrSSM>TM?TN>VP?ZTB_XGf_Wphqul~pgvf`ja\_aZSdZJg]Io_M[OPFA68-6,7+8)9):+:)9';->3?4=5;7:99996;2>2@5>798778595:8:;;:<4<,:(9&>1LHUUZTdNotJkMe{LXgDKR<?D3EQ6^wBlJlMlMnMqOsSpTaXIbYIbYJbYJd[Kf]Kg_Ni`TjaVh_RaZLXSDRO>TQ>XVDdZJXMMG?8:-9*8+8*9*:+:)9%9';-;4;::;897882:,;);+;19697:6<6=8<9<5;/;*:'8&@2NEVO\RjTruPYjEFT:?E4;<08;.DO6_xEpNpPoNrOtSpShOg^Oh_Oh_Ph_Ph_Qi`Rj`Si`Qi`Nh`Me^J]XDQO<HJ9FK;MM>oPBPGHC?5:,9*:+:+;-;-:(;(=/>8><<9;5;4;/<+=*;*:-:2;5=5?5=5;3:/:*:)9(~9)B4OCVM[ScQaaDDP8>G7AD5==.9;-DP6`yEqOrOrPuTsViPbLi`Qi`Qi`QjaRjaSkaWkaWkaTkbRkbRkaQf^LYUDJK;@E5BE3cI8PERNKHB9=1=2?3@6@8@6A6C;C?B=?6?2?1=/<-<-;,:,:.;0=1</:.9-9+9*|9*w8*{;-F8PDTMZS|bN]bAL[;JV<EK5=?-8;-CO5_xDqNsPsSsVkRdLbKi`Qi`QjaRjaRkbTlaVlbVlbSlcSlbTmbTkaRc\LVRBHI6KE0qG7ICPOSSKHC<B:D=EAEDFCEBDAC@A;?4?1>1<1;0;/;.:,:-9.9-9,9+:,~8,z7+v6*s7+y?3K?RGUM\OldJZiCRe=HV5>F/:=.8;.AK3[rApNtTqUjQdLbJaJi`QjaRjbRjbSjbSkbSkbSkcRlcSmcTmbTlaTleXoi[gcQ\T?jH9D<FCLIJGEAC>D?DCDFEFEDCAB>@:=3=0<1:1:/;.~:.}:.}:.~9/8.9-}:-y9.v7-s5+p4)o6+xA6NETLXNu^L[aDN`=IY7@L0:@.8<07;0?E1Vh=mOtWmSbK`IaJ^HiaQibRjcSjbRjbRjbSkbSkbSlcTlbTmbVulb~sg]KVF6W@4`?6uA;FCKIHECBBCCDDBD?D=B:>4=/<.;.:-:,:-~:/|:0z90x8/w8.u9.s8.q7-n5+j3)j4*w?6OHWOvXK]VDHQ;>J4<G1<E19A15<0490;@/P_:jNqVeM]G_H_J[~HhbRibRicSicRibRjbSkbSlcTlcTkbTrkaƹ`eLCG3=;0OA;][ywomRQCDBBBAC?C=B;@6=0<-;,:,~9-}:/}:0{:1w:1s8/p8.o8-n8-m6.k4,f2(e2(s>5NFrSHVM?AF78>24903:/6@17C24?127.6;-LZ:fPiR]GZ{E^I]IXxHhcShcShcShcShcSjcSlcTmdTlcTkcVywpӹ|]_HHH;d_Z¾캶ወ`\HD@>@=B=B<@9=3</<.~:.}9/|90{:2x:2r:1m8.j7-i7-i7.j7.i5-d3)d4*j?6fH@QE:<?14;.49/37018.1;.4A15A239-59+JW<bS`NTuAUtB[zG[yIToEhdThdThdTgdThdSidTldUmdUldUni^{{cdgWާsjOGA;A;C<A9>5=2<0}:/{9/z90x90t90m80i8/g7.g7-h7.i7/i8/h;1jD9cI>KA889038,37,37,17-07,/8,1:.5>15</6=.GT>XoNSqGMk>Pm?XuFWrHJaAheUheUheVheVheUidVkdWleVlhXzzs˱ýὶ͇}\PG<C8A8?7>6}=4z;2x:1u90r9/o7/l70i70g6/g7/h90i;2h?2kK;p\L]VH<?506,17,16+05+/5,/4,.4,.4-08/1;04?1>K8FW>F[<G`;Mg?VpISjI@R<heVheVheVheVheVieWkdYleWmk\ҼѠn^N@A7=6>7w?7t>6s=5q=4n<3m92m82k71h80e:1c=2cD5cJ6hXBjfQRWF6=106,17-16,/4,.3-.3--2,,1,,3,,6./:/4?08D2<J4AR7J^?UiKO`I8F8heVheVheVifWifWjeXleZlfXkl\ݸȈwbSK>@4q>2o=3p>6o?7m>6l<4l;4i<3d?4^A4WC2TI3YR9c`E^bJEM;4;/39/39/39/17/05//4/.3-,1++1+*2++4,/7-4<18B3;G3CQ:N]GIUF5@6gdUheVhfWifWifWkeXleZkgYhm[}ұ|r`bR~UGqG:iA4hA4fB5cC6^D6\J8YO:LJ3EH.PR6`aDY\CBG67=16<36=26<36;46;459427205/.3-,2,+1+-2-1616?48E3;I4BP<@L=4?4ceSefUhgVifWjfWkeXleZjhYho^˾˹{cN`I3]H2\J4XK6SL7SQ:RU;JQ4FM0QU7]]BYW@IJ7?B4;?59?49?59@79?89>88>77<65:4181/5/.4/07/5B29K4:L4<M7<K84A3_gQbhSfiVihXkfXlfYkfZihYjqbʸĭz`ZQ5VM1UN4QN5MO6KP6JR4MU4SZ9Y]>ZZ?XU=QN9IG6AB5<@59A59B69A7:A7:A8:B9:B98@76=43;26C1=Q3@V7=Q8?Q9?P97F4 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Crop.miff b/PerlMagick/t/reference/filter/Crop.miff
new file mode 100644
index 0000000..4ca67a8
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Crop.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=10 rows=10 depth=8
+page=10x10+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-/.,0/-50-71-81,80,6/,81-81-81.,,,,-+0/,1.+2,(2-*0,+2,+2++2,+,-/+-/.--/-)/*'-+(,**,**.++.++,/2+/2..0-.--+),*++)+('(**+,*+.0.//-/1.21.30-3/,2-*-*+,+,*)-23-34-53.961961:2.80-3.,300-.0782782994<:5@=8B:8A95=73<75:548939:4>>8A?:D?:FA<EA:E@:G?8E=4671681==8B@;FA?HC>HC>JD<MB7J=0 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Despeckle.miff b/PerlMagick/t/reference/filter/Despeckle.miff
new file mode 100644
index 0000000..6386d1e
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Despeckle.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:*)'.,*0.,3.+3.+3-*4-*4-+3-*3-+3,*2,(2+(2+(2,(2,(2-(3/(51+63-95.@9.C:/G</I>0M>0l?1@0@1A7B>@?<?=;=5=,=+=+>*=*=*<*;*;*=,>/@2B5?5J6173051/40-2/,0/,/.,/-,0-,2,,H10zA?ZfodkMDiNEamotrtdTQN-,*/.-2/-3/-3/,4.,4.,3.+4.,4-,3-+3,*3,*3-*3-*3.*4/*50+62-84.<6/B90F<0H>1K>1M?2i@2@2A2B;B?C?@??>?9?/?-?,>,?,>,=,=,=,>/@2B5D7C7D:5:5173052.31.10.00.10.1/.310E1/tA5Y\qgpOEnODeYZdtzthl[UWR+,+-.-//-1/,2.,2-+1-+2-,2-,2-,2,+1,+2,+2-+2.,2/+3/,40,51-73/:4/>60B70F:1H=2K>3U?3m>1?2B4C;B?B>@=@1@/?.>.?->,>,=-=->.@1B5D9FBSJCB7;6384053.12.02.01/00/10/10.3/0I2/pQRlrODI@cEAUJRTU[SVWN+,,-....-0.-1.+0-+1-+0,+/,+0++/++/++/++0,,0-,1.,2.,2/,3/-51.92/<40>40A61D91F;3O<2_:1y<1>1B5B9B=A9A1@/>.>.=-=-=,=-=.>1A6E:GBc[qWaSBB694/23.12-01.0/-0/.0./2./2..4//gc^‚kr]`v`ps~x}W_O+---/.//.0/,1.,1.,0-+/-+/,,.+,.+,.*,/+,/,,0--1-,1.,2.,30-51.:2/=30?50?50@61B72C81O70g90=0?3A5A7B7A2?/>/=.<.<-<-<-=/?5F<HBURwrpS^I>@433-10-1.,0--0--1-.1-/2-.3-.emR~YcJ,.-00/11/21.30-3/,1.,0-,/-,.,-/+-/+-/+,0,-1--1/-1/-20-40-91.=4/?50?5/?50@51A50C60D60P6/i:0>1?4@7A4A3?1>/=/<.;.;-<.>1E;JAROovy`^Q_I<=22.,1-,0,,0,-0,-0,.0,-3-.\fDqwvpO[E/0-34/540751940:2.80-4/-20/0./0,/1,.1-.2.-20-11.21.51.;2.@5/B70@60@61@51@51B51E51F50D6/R7/j;1>5@5A5@4@2>0=/</<.</~>0~D8K?QEdVo{|ikceQdO8=02-+0,,0,+/,-/,-2-.4-.[`Hye}k~ot~w|volNYD34.661872::4>;6A:7@95=84<74:5191080/71.62.63/73/84/>6/A90G;1H;1E;2A82A71A72B72F62I61H7/M:0k=3?6@6@5A5@5?2=1=0=0HDOFvN?vSD{`JnTf\zo}xqlolXdP?=-3-+/-,/--:.-B-.TN9hqRp]sauiwn}wvuhdOYD560772::4><7B=8C?8EA9F@8G=6E;4D:1B90@80;60:50:60>71A:1G<1I=1I=2H;2D:2B92A:3E;3>>?A>4>8@4@4A5A4@5?8>8>9<8>@DCQGwUFp_JbOWS6L6NAVM_Yhfldl[mOkJbFOR3-C4.JB2e^;s]r`tavi~{|}g~cS_G45/782;;5@=8C?8FB:GC:ID9JB9I?7F=3E;1B:1?81=71>71?:1C;1I>1J>1I=1I<2D;2B<2B<3>:?M>4>-?2>2?3?3@3?2>6<9;9<988:.E>\I]K]Q@IBE@I7K:N<X@`BmDlIoJqSrTfaB4PG7vcϬliWgL22.550883==6DA9FC:JE:LG:MH9LGFJ@9F>3D;2@92?82?91?:1C=2I?2I?1J>1F<2C<3A<3D=4>7=0=,>.=-=0=2>2>1=2907/5.5,7*8*;.OESJBHBB@5A?@H@KAQBYCgDoIrLsSsUvYjneĽωqj22.760871::3>?6HD9LG:OI:VSSy{|x[ToG?OA;4@:2?:2A=2B>2F?2I@2E?2C=3@<4E=5>6>0=-=-=,</<0<1<2=2907/4-4,4*6)7)9,B:CABA@5A2@3BDEIDLDYEbIqKtQtUvSnmxcbü64.871992<82>;4HA7PG9UJ:`]nܢ쏏nmLIXB?MA>9D?3C@3DA9DEPES]FONeC8?4>.=.<-;.;/;1;2;1;1:15.4-3,5*5)7*9,A9F@A6@/?/A3ECEGFJIYJaLoRtVuUrYpZlZa᪤>:0A=3=82=:3@:3F?6SF7UI9]Ujަ|f\RLsB@CCA;RGQgqQoDH?0>/=.;/;/:0:0:2:1:1:/:/3.4-4,6+7+9-;0EBC@?/>/@1E>FBIILSPaToVqWsYrZnZh[]unIC5MG8F@5A;3C=5HA6NF7UI9XOToveaIWGSHUHRCB@?@7>2<0<0:/9/91809.9+:,8.704050606.8/;0EBFC>3?0>0?1A1G=NJX`^oWqZrjrftrutib[MQH9UK<PI:KB6IA6LE7RI9VK9XOSպnCQCGB@BAA@@<?:>5=1;/9/807/7/7+8+8,806060605/708/:/E@FDDB>0>0>/>0>1D7\Vdlfpjqjtntu{tQ^CUK<WK<XL<UJ;SI:SJ:UJ:XM;[PR{|Е䖠蔟؉ЍiBOBEAEAB@?A<?;?9>2</:-9.7.606.5-6-73616/7/6/61809.;/;2@@FDB7=/>/=0=0>1VGgljoktmshs_s|idzQWK<YL<ZL<ZK<YK<XK<YL<[N>]OGc[qwxɆvtVfAJAAAE@B?C@:@:@:?7>.<,:,8-7.5/2///.3.6.55/7.719291;0;0;1;1;/</A5=1<0;0;0H>kmnxp{mvZjNfngȪ¯ʪǚպXJ:[L;[L<[L<ZK<[L=\M=]N>_O@_PIdWhqi{oAKA;@E@A@D?9?3?8@7>8=-;,:,8,6.3/.0-2-7&9.:8@768373:1?=;2;1;.;.;.A7=2:19091;0kkwv~p{NfJc]pZ}`qareotyYJ9[K;\K;\K;\L<]L<^M=^N>^O?`QAbRIf[w{iwAP@F@A@D@>?3>3?3=7C8B7;-9,7/4011,3,6,@.QK[Pa9G758/>5C>@><2;.:-:/>6:261417/90\W{{k|JdGYeaCkUya|g~ijnquZJ9\L:]L:]L;]L;^M<^M=_O>_P@aRCeSFkautuMUAO@E???5?3?3=5=3<2C7=2908156,3+5-5.9;QSaJO;99.:(A8A>C><5:19/:3<76231404/60MEzYtFcGSY]ApZ|g|g}h}hiip[K9]M;^M<^M<^N<_N=_O=_PAaXYn`modttzڞļv|dXLR?E?:?4?4?8@5;2;3;2;1:173<D<C05/56;>D=C=<::JJLKIGJH=:?9:89898764130304/50H<qGhFcEGZ`Dr[t]waxazb{b~agole[K:]M=_N=_O=_O>`P=`P@aZ`rtuvsx|ŝżİtZQMLL?<?6?8C:VH@4:2;1:1819/95IMJPNRPW=B=?8>GP_kZjLJ;:?9<8:88877534/3/303/51=4|bwGeEc\F8T_@pWs[rYsYv\x[yZ}`zdaxRZK;]M<^N>`P?`Q@aQBc[arsqvovzzҫվܪsdjcWZ?<@:A9G:L><2=4;39/9/9/;5MQPZV_U]8?8=BOV^PW99:8:6;79786755/4.4.3.4070<4kwRnDeE[KF5MJ7g~OpTlPmRqVqTlMeJZuAMe7PF8[L=^O?_Q@bRBd]`qqpqiqpw׹ľxkeh`micaDAA9@7>2>0=8=8;0:.:0;/<6BET]SZ:<:@9@7>6:688696969585726.5,5,5.6.70DB\mCf@dEGLG6HF3R_9hKiKlNkPkLfKaH^vEVp>@>5NE:ZM=`R@d]Xojnjfhmnו؜֠Ӟʑwk}k_V|^Q^YqkwrZV?1=-<,<.</;.;/:.;/<1<4HEG>93570<.;,:,85786:68684817,7+6*7+7.9/M\Ke?e?XA;.CD1CD.V^8gJkMiKkLiLhJeIcG_zD26,;;5MD;YM>a`jeb``acz}҈׊֋ӌыȇz`jj^Pp]N]Tfgvpwr=-;+;,;+<,<.;-;/;.;/;1<3;3632:0;-<+:-87797979686819+8*8*8):+=4Kd@c?ck:=3:.;;-ZY3xmYhJjJjLjKiKgJfHcE-1(26-;:5ID<ZZi___ax{ӆᆆ׈ъЉΈ~vp_Rk^Mk]L\NZ_gfG>;+;+:*;+<+<-=/<.;.:-;.;1:3795<2=3;5:798888988897949+:*:):)<)FMBa@c=O;:3<:/HN/xNJq\fEjJjKjLiLiKhKfG.2(37/8:2@B5NPJZ[jjhᇅ憆тˇˈ~vo`Yk_Nl^Ml\KYJRM==:,;+:*:*;*;+=,=1<.;-;-:.:2969:7<ABJF::989788998999:6;+;*;);(=*J[G]EYKA4<;0I<0eǀuSkAdBhHjKkLkMjMjLiJ;9.?=3@A5EI6RQ@\WGfbj}z{w|wyom_Wk^Mm_Nl]L[KO@<1:.:,9+:*:+:*<+=1=5=/<-;.:4:6:6:6@AKH?::9:89798999::9<7<+;*;(<)IDQ[QXWP?E0KO0t[beIT<DP8fChHlKlMlMmOoOkMPH9VM?VN?WQ@]VFd[Hh_Nkcisfxpdmd^[_[R]WHf[Hk]Lk\L\LRK=1;/:-9,9+:+;+;+<+=,=0>5<5;7;7:6;6<5=/=2<8;7:8:7:8:9;9;8;6<+<);)=*QQSTWT_QdpBepUO];=?3=@4?H6fFkJmNnNnOqOoOoO_UFd[Ke[Ke[Lf\Mh_NjaPkaRkbRi`Pa\NYVEVS@SP?[YF_[KXKNG>1;.:-:,:,:+;,;+<*<+>-=4=9<9;7;7;4<.</<.<3;6;6;7<6<6;8;6;,;+;)<*<+SJUQYQfSeScA5@.<?3=?3=>1<C3gInMoOoPqPqQqQbLd[Kf\Mg^Oh^Oi`Pj`Rj`SjaRjaPi`Oi_M_YFRO>HM<FJ:FK=YNBSHHG=0;-;-;,;,<,=-=*>*>0>9>:>9<7<4</</=.<.;/;2<5<4<4<4<3;-;,;*};+;*A3RGVNZR[RMY75@1<B8AE6=>1;?1<B1hKoMpQrQrRsUdMaJf\Mh_Pi`QjaRkaRkaTkbTkbSkbSkaRj`Qi`N[VDGI:EJ:DI7EH5OFTMJJ=1</<0=1>2@6@5B5C>B>@<?6>3=1=0</<.<.</;/;0<0;0<0:.:-9,|:,z:+{;.H;RFTMYPeO^hDHX8R_BDJ4;?0;>0;B1gJpOrPrRsUfNcLaIg^Oi`QjaRjaSkbTlbTlbTlcTlcTlbTlbSlaRh`PZTCEH7DH4H=GAKJY]JIC=C=C>CBCCDDEAD@C>B=@3?2>2<0</;/;.;.:/;/:/;/:.:.}8-z9,x7,v9-x=1P@SJUMZM^^EWeCThBEW4<@1:>1:>0;@1_yAqOsRrTjQcLbJ_Hg^OiaRjbRjbSkaSkbTlbTkcTlcTmcTmbTlbTlaShaQ_YDHH3rG<G>EAJIHFD@D@DCECEDEDECE@D>B<@3>2=1<0;0;/:/~:/~:/}9/{:/|9.z:.x9.u8-r6,p7,s7-v>3QITLVLy\JYdFRd@I[6=E1;?19>09>0:=2Vd>qQqTpSbKaJ`I\Gg_PhaRjbSjbRjbSjbSkbSkbSlcTmcTmcUmbUspi}{jDG4AD6AD4@A3`D9DCEDECEDDDECEBE?D>B<?4>2=0<0;/:/:/}:0|:0z:0y9/w9.v9/s8.p7-n6,l6,m7,t=3SKTK{VK[VFES;8C2;E2:A28?17>17=19=1LW3oRpSbK_J_I]HX|Ff`PhbRicSibRibRkbSkcTlcTlcTmcUmcU}xў|CJ4?A3AA4:@4`ED{{XUDDDCDBDAD?C=B;A8>1=1</;/~:/}:0};0{;1x:0t9/p8/o8.n8.m7-k6-j6,j7-p<2QIzTKNO>6@15<14:14:06?15?16>16<07;1BM2lQlR]}I\|G]H\}GVwFfaPgcShcSicSicSjcSlcTmdUmdUldUnhd̝|IN4BA4OHEqqEBDAD@C=C=B;A9?3=0<0~;0}:0|:0{;1y:1s:0m80l8.k8.k8/k7.k7.i7-i8.k<3pKFG@45<04:/39038/28/29/4>04=05:06;0BL2l_^MUsCXvE\{GZzGQjEebRgdShdThdTidTjdTkdUldUmeVmgWokhټsrZMOD޲OBC<C=B<C;A9?6>3<1~;1|:1z;1x:1t91m91l9/j7/j8/i8/j80j8/j9/j<3jH><<44:/39.38/27.17.16.06.07.3;/4<06<0BM8c^Ll?Nk?RoBYuGYvHCV;ebRheUheUheUieUjeVkeVleWmfWnjgٹw{`wnؿj^B;C;B9A8@8>5~=4{<2x<2u;2s:2n:2m91k80j90h80h90h91h<1iF4teSjcS4:029/28/27.17-15-/5-/6-05./5.1;/4?2<H4CS9FX<Kf>Nj?XoHVoJ4D5fcSheVheVheVieVjeWkeXlfXmhZy|zٽȣE9B9A9?7?7w?5t>4s=3r=4o;3n:3l92k91h91f:1f<2eC4dI5gQ9soYQYF3:029028/28.26.06-/6-05..4-/4..5./8/4?19C2;E5DV:Ka=VjKUhJ-9/fcTgeUheVifWifWjeWkfYlgZli[mxpԼkSA7@7~@5s@4r?3p?5p?5m>5k=4j;3h;3d<2b>2XC4UK4aQ8`]?ejP7@27<139039039/17.17.16//4./4..4-.5..5./7/5@29C3:E7AM9TaJMYJ-8/ecSgeUhfVifWjfWjeXkfYkhZkk[lwoìu]H4q?2o?5o@6l@5iA5g@4cA4_D4]G5ZQ;JK3HL3LM2ddF^]A;@38?38=26<26<36<45;45:4271/5./5..4..6//500608B5:G5;J7@O:>M<.90`cPfdTgfUhfVifWjfWkfXjhYkkZkxpּǼ͹kO7`H5]I3[I4VI4RI5QL5VW<HM2HL1LO3^]AZU@IF6<?49>39=47=46<56<55<45<45<45;4071/50/500700;/;K5>N6<M6:J60;0X`K_dPedSgdUhdUidVhdWieXhhXt~f_CUI0UI0SI1PI3LJ3IK4GL0GL/QW4V[:TR9RP7MJ4D@39=26<26<36<45<45<45<45;43:2181.6/.6..:-:T/<T39K4:J59L2-:+ \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Edge.miff b/PerlMagick/t/reference/filter/Edge.miff
new file mode 100644
index 0000000..ba57357
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Edge.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Emboss.miff b/PerlMagick/t/reference/filter/Emboss.miff
new file mode 100644
index 0000000..32a1a59
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Emboss.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Equalize.miff b/PerlMagick/t/reference/filter/Equalize.miff
new file mode 100644
index 0000000..933a82e
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Equalize.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Flip.miff b/PerlMagick/t/reference/filter/Flip.miff
new file mode 100644
index 0000000..43d6181
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Flip.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5gdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;hcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|Gi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\Gi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`LcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`JUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqW@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvV.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgGDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbDTH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sD[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnEWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3OI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAD@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtn:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Flop.miff b/PerlMagick/t/reference/filter/Flop.miff
new file mode 100644
index 0000000..56be0a3
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Flop.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:YVSz|luw|RLaPHnlp|bnIGP786+-3,-0/-//-30,61.72/721:53R:/F9D6B3?3?.=*=+=,?.@+A+@-?-?/@;<@=BCFDGE=A5C3tD4UA2NB2LA2JB4F?3?:/96/74-41*1.'1-'5-*5-*4,)5-*7/,80-80-91.80-92-:3-83.62/20.0/-YWSlp_~]^gK@\J>kcl}Y\xA5E212*,5/.00.-1.11-62.62/931955D7,H;D8@4>3>-;*=*=,>.?+@+?,?+?-A;<@<ABEDGG<<-@.iE4MD3K@/I>.H?1E=2>8-75063-41+30*3/*6.+6/+4,*4-*7.,81.81-81-6/,80,81,71-50-0/-/.,YZOISI>FF54H=1XH=kqƊlMNI.!3-+00.120/3/,40-4.14/53.93.;41<?5WNGD@8B1?/;.<-=->,>)?,>-?-@*A0>=<>E@H=E49(m=+UD4EE5H;/C8-@6->6-:3,75052-40,31,3/,3-,3-,1,)1,+2,+2,+2++2,+0,+2-*2,(1.+0/,,-+,,,_eQ|`prY\oip~Кgcb4*,/-2/2.02./0.-0/-0,.1+/1*75+CB8WeWyg_E@G:C7<2<.<,<+=+=-=/>-@,B/HAE@E9A3;/y7-_70Q<5H>7F91A5->4/<4/82/30.2-,2.+2.,/-*0-.0,,/--/++.++.++.++,**,**-+(/*'/-).--+-/,-/YdJǰʳeqR0)(2*10/+0-+0,*2,+2,+-)'01(<@3SZGrp{URE>G@?7:.9*9);,<-;-=+?,?3G<D7A3>5=0h7/K62B:6A73A2/>0.;21<328110--/++.*)0,+/,+.-.-+,*()*)),*+,*+**+('(+)+,*+-+)-.-..0+/2,/2O[Dvp~ÓɌvv[f@+'0*01+02(/0(,-(+/')2'(=:3N^G\{ZwypQOKDG;};0v:*{;,9,</?/=.</>2B2;-@1A1i:-O,'93,59/>3,>/.;/.;1-=40;3.6/*4,)/+).+*/-,--+,*)+()-',+(,*)-,+,-*+2-*3/,30-21./1.//-.0.LVDol~{}to~o{j~jW\H)$"''-'+/)+,+**.$&*&#4=0PfPdeegv|{zqdVNEG>{@4s9-v8,v>);*:+>-A1B6?594:7j9.R/(70)F*.R).E1-<1/;0/=5-A90C8/A5,;1+4/+/0001.10*1.*/*,1)./(/-.03003.,80-:2.96196153.34-23-NXChdttstkhnck\hWhqRTN:C)):&*+/&%+!3)"?;)XiMooxv~zrf`zXs`IkS@pJ9[VPLz4)u>.y;/~:/A5>6C;BA=;c6-E5'<6*A50C54<94?62@61B80H=4J>4H=1B90?7297364163.62.61.9//900:54<75=73A95B:8@=8<:5994782782S_Gd}_~{sdmYn\w\e^:G@->3(R.(FOPbWk_mjrfnYhM_@V)K(HSZlS`jHpYCUPEG<Hy:4vC9CE>B@2E1C5?3F9KHC:GIEJG70=<3A:1E:1K<4P@5OA2I=0B<0<7094/95/<80C:3C:3D;1E=4G?8E@:EA:FA<D?:A?:>>89:4893WgLg{eƶvdHC/a=3[fZxGoAr:o:h4\0T,H.EFOBC;Ec^cJdOB:.'7;D?<<8?>8>2:(D7>3;0?5;#35K]B@7=0>=1D:/K;1O>1OA0M?/E</>9,:7.<71A91E;0F=/H<-J=0MB7JD<HC>HC>FA?B@;==8681671unnd]nYWxJnEw>q>h=VAQ>HADE;;.?AAKUQUI9,5!6%0)++1+8)@4@2A1=26':$A&4!4+I@@?/5=0C74K81H?-P@-IA6@=9>94=71>83?80C9-E;+H@9MHJIE7MI6JI;GG>DC9=<6883551330ɉ_T{CcTtMzK}JtBbDXDKFKE@=-9(>3A>CA?69,4!5 /(1+8.4,3*?2:+9*;1=1>,;%<';/6<B1-040:4)C;*P@/K@/B=-:9.52)62&944F?O[To|xXWWMK4OK8GD;>?589243//.,10-᪤KU`pSgUqXzRzJnF`O\FJGHHF@7:):#>2VMC<5(7"7!2(-(-(1'?7;2:382:4806*;(A-=+F7aG<FSREUa:EQ8A9BC.A=(<99@?MLIXnmŝ쬲darTH:VJ9IA6<;274,30+63-:81tnOTWeZiWoUxNoVnTaQSNIE>QI>29(9$C@LH7-:*<(2%2,++))?4D98/<7>961;3<3;-:*9#<'KP]{sRJN:977:CRLsf\|§ﹾ]UjWF7TG6F=7:5/52(;6-A=3D@5VPAue{bprxZuPmfv\aNJH==-C2<-8+=3EIPJ>/7+535420058;>09"3$3)8/7/3+9/>4?2>/>5>>;>HRL]OWN_aeoz؜WLSSD.ME5A=8=60?90F@5MG:OI;AQ3|zoutrgqgpnm^V@3</;*;':(8.MKHILA5$1)*0-5428.5+5)7&6!4!7);/412+6(E9@:9<=AF;@1;7<?ANv࠯VNQSG.LG5E@7F<1KB4PI:VM?WN?XnEuiWpdlnqbmagmjVG:*<.<-:*9)G=US@B>5=)8&7+5/3&9!9%<9;6;+8*4.3/93:.;+?0=1?;>AGF>;?F>C@:=PiДؙ앗䔗XQTWK4RJ9NG<TG9TJ:YM?[OA[PAպǚʪ̮}g}DaVes{r{s~qrH>7&:+6*>1J>5*4*./755)6&D6=4;28(0'(0(>.8-1,3134+8(:%9%;)B541C;@5BGCNE>3?;F|Rbfm{{͂wxd_uULGZL8XL<WK?ZL<XM<[N=ZN>[N>ŵytyheYa~Q|\gQ^?\Mdrzkk8-8+:391<3QG8+8&5*;664GG85+.0:1:<D'66%2)',$4'9.4'8';(7$D:;8B89(<7BJ<@@9>+@Gq~me^SdYLI[NA^P<^M<[L>ZK;YI;\L<[L<[L<ÿqopop~mdeNYa7>UHak||\W4'91003183FB8);%7$9.C@SNC67&058O\mQc.W-H*<-<191/604*6(PAME8;@68&;.C@BGC@@F4Kew‡|waWw_KH_N:^O;^O;^K<]J<[K:YI9YK:[K:[K:n~ek~f|fqop[IY1@S?aYt{ME4%2,-0.13.J@8/8+8+;0IE86:0-6$:5NScp;V%7!+ -"/2>79:.A3MA9'3+83>/;*>4<==G?QKUuqg]qcG>aM:]P=]P=^M=]L;]L9]L7\K6\K6\K7lgvh{Z{dzdv_u`ycrZNb<AG<dFhqH<4%0..2201*>:7?2=<7B:EAUUIGOQOJ3.78?C>C23,(/-CGDN03<.D74.6'6+B9G>:+B2779AMUd\v|̓pxmdpo`maXYVNA^N9_L7^M:^M:^M:^M:^M:e|VhawVy[x^rXoW{cu^L_>\;/Ad>cbw<35)/-.22/4*635?,:40E<A<53RNfvozJV-79?@BV[QVJQRX55-)7)=11,2+@3fXI?7.:279HJLApRȶ|qv}}|_[a\L9`P7_O=_O=_O>_O?_O=Ia4Nj4bElMsTsZmQhLtXh~SAJ0=<&J[<dRpw829.0//40-6*5+65;;:580826473T[^fFS(6/7agdoVbSW953*-'0%@7><1'XIOA:1636:WZlgydᶯzzcjw|wwcYa\OB`R@`RC_RB_P@[M=[sDWoBY}C^EhLnUgKeDiLO_9EB-RP<MG@h;dhuDB4*0/351+7(6-647865;3:/30515679?FBI73W^[g:A=6:&9+6070IFGF<-B2<1=5DAgeyujdoje·瘝lv]ftz{yf]b`S?bVD_RBYL<TH8bDfIcJcIhGlNcD_AdyNQZ478!AB395#@X8ePkV\4'5)5-6&9&7)403575<5:5.6#8:'?(:/06$KBPL73=4@1<*8/9/7,:0;*5#6-^Z|ysYQ|SH^VRpg}Π֢֝ދii]_spzte_X`S>\M>JE<DB6gGfHeJiMkHpQmK]>s`^Y2/4#/%k3=Cj7cWl=4;%9&6$8&7)6/4854;4:65=&9$:*>+=/71':.?5:0:/:-8(:-6(;+6+;);#;-zfkSVpWD\[L~ZjȈ҈͌щy{[]QQljgelVL=OD;::447-kJfGeKgMfEoRrN]=q\՚yDN)8+/364CO6gBgKM<&=!:':)8*846;78:885657;5836-;1?6;;0</7(7(:)9+G;:(>+1(8+<'7&K@njZcWPd_C`_HsWR~x‹ۃҁʂڅy|[Z\]Z\iEC=975+0+*0&pPfEiOkOeCdGlI`=Kc9|ԌeJ3'-3%K@1I]=_P`5)9#=*=*8);6597<8<888482A=VQEJ/:8<;42)4(9(:(8)D9<+=+5)5+7&7&0+==RQYCj\Ef]I^]Gla]w΄ǁѓnlXVmLON:=001++.(.2&vVmMoQlPkKaEjFg~C<H,IT<jiu_FO)39"]OMXUhID6#;(;';+?77;6=8>688492:7C=ZXHI86:8;7<49-:)9'IB=57&;)9,=$8$4*0+5.K<_Oj^Nh\KlYGn_WyozwszԄecgUTALM:AE*<=2>=4@>0qWxUqKjGmRjMoJfG;C123+;=.O];vYq`x;cKYRTVYZ6'8$;(;,@8;=889692866:6:<5;-9*=2;868<<>9B9H:<49-5"<+:,9)6*7.7/4+:,RGZOjdOn_HfZF]VGWUR]W[pdmwj|mckbYK`WB\RCVP=VN?VM?UM>`JwYxUoIpOpSwQgK9C099076/581'2ScBsn]\STIRJ~:*7":(:(8+@;>>>9<3856798>4:)9&8&645<6;6<499/7*?)5=/:+7*8*9+:*=)40JLaY__O[ZFSP>LH7QN=`ZGf\Ig]Lg^Mh_Hg_Je[Md[Le[Ke[KcZK`LbI}byVpJqPvPhK8@-7:/=;(KM@7><'2%AM+YMYSZNSGA3w3"};(<)8'8*83A9D9?6=7<56)<'A+>*9-:561>;@E;58*96;/9):(:)8)7%:,DFXOUM;CJ>@H8@E4LJ6`ZFhbKibHibLi`PjbSkbTh_Pi`Qi`Qi`Qh_PbMbJfN}`rPpNwPiL8B/88/:;#KQ5^kQGV4fvIo_VWSNOBH;v5(s9*{;,;*<,7,6*<.?1;0:.8*=,<,:+yA-C1F2=/EAIEHAC3>3@:>2=1<09+;0JM]YZF?C)5C1<C5DF8ZVDkbNlaRkaXkaTkaVk__k_ZjaQjaRi`Qi`Qi`QaIgJ\GjSwYpQxQ_yA8@-79/:<26@*CW-`vFOe=WX@[SQMTGQ@v=1p4)y6,{3(8+<,:*8(8,8,{:+z;+z;/~;1;2:3<1A2=0@=BAACIHLKGKIFHCE?C<NJimNO>@K@8A'EA1VP@haQmcTmbUlbVldPldOlbUmbWkbSlcTh_Pi`Qi`Q\GeL_IZCr\x\tTVd>89)4;0;=389,9C(M_:UmDZnJyeOUMQMTLv@6l2'o4*r6+u8.x9/z:.|9.{8/{91|:/|:.:-;.;/82<3=/9/A<B>A>DCCE@EDEE;@9CBLLONBCECrM<A@%_YCfaPf_RpaUpbRlcTlcSkbRkbSkbSjaRjaRlbTjaRi`QX|GaKaIZ~C`I{^rSLW378,4954;.9A0BJ6;E02?)ES;_\H_RYRRNs=2e1%k4)n3+q6-t:.v90w9/y8/{90~:0~:/:,:+:+9.~>/=,=4D>F=F?FDDDDDDA><AEHE^B5?;.<=/3<(7>+}{jspifZPmaTlcTlcTkbSkbSjbSibRibRjdSibRhaQWwH_I_LZ|ETu?nTsYAM/54+-2/0>.;K84>1.3+330/5,5@1NO>z\OUQp8/`.$g3*k4,n6/n7+o8-p6,s8/w:3|:1}:0}9/}9-:+<+=,;,B8B:E;C?ABBD@D9:XUZ?>*0+:725?+CJ2|ф|e]SkbRlcTlcTkbSjbSibRibRkcSibRhbRQjEbL\yGVsBQo<^Mzm@J1,-"16,9H66D2-9*2806867:21<..9)G@3vTNm=4Y+a0'i6-k70h8.h8-i7-k8-p;1z<4{<3|90{9/:.~<,=/;1C<@<B=>?@@@<=:qq瞙OHF=6)KO1ljelbQmdUmdUlcTjcShcShcShcShcShcSCV;bNWuFLi;Lk<Gj=ojDM:01$;C28A2/8,.8*09*/9+37)56+37-14,883nLBh;2f6.i70i60e7,e7-f7,h8/j8/v80z92|90|9/~:.~<1=3<3?;E@B=A<80OA޲喗AJ<rnWdddjaQmdSmdUlcUicRfdRgdRgdRgdRgdS4D5]xTXrJGb9Mg@BU8IX@@M:3@32?4.5..1,/4./3-/3-05,16*07-17.)2(nk[q_gF4l</l71i70g6/f5/h70j70o5+s7.u7.x8/}92;2?6B7E6H9@68+j^o{jpsWٸ렧nlhhfQneWkdZieVheWheWheWheWheV,8.ZlS^qRH]=DV;6C.2>*2>--8-)4-,3,,0+-2,.3--2-/3,06,17-07,*1(QYFi_M5cJ5fF9g>4g91j7/m51q62h:1j<2o?4q?5q@6pB<@=:;<99.E4ǣǴҷ}~ghPndXkd[geUheVheVheVheVheV+4-Q]O\hT>J43>,9C47@5-5,*4,+3++0+*/),1+.3-.3-/5,28-39/28.27/2@+nv\]]?]X=UP9P;+^>2d=2l:3q94n=6o?8sA;s?9r=7oA38,6*?.kSԼluphiQngZlc\jeVifWifWheVheVheV/90EPDBP<1?(=J8=D=/2/,1,*.*(.(,1+.3-2716;57;68<58>37>47=37=529'\`GppREI+9C'EF/e]GYG5_D5cA7h>2i>4l?4j90e3)e6"yH1u]ìhwoflSlhZnc\jeVifWifWifWheVgdU/;.;K88I19L36J2)3))-.+/.,1,0627;69=8:@::>9;A;9@89?58>4:>5:?5FF5`YDigJGJ+=E*@L0^gKMO8QN7VO:\L4]K2XD,hS;ѽƿҶdwodkRlhZnd\keVhfWieWhgWgdUddS4B1H\A@R::M8Gb<G`56D/5=69@5;E:<E<;C8:B79A69A78C58A5<?5CB5MI6UR9WT<VV=aeF]e@LS0EN.HO5LO6PN4SO3UO2RK-mgKɾ|elYhgYkf[lgYlfXihXgkW_iR\gO \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Frame.miff b/PerlMagick/t/reference/filter/Frame.miff
new file mode 100644
index 0000000..d73fe43
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Frame.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=90 rows=66 depth=8
+page=90x66+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:dddݽddddddݽddddddݽddddddݽddddddݽddddddݽddddddݽRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRddddddݽdddRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRݽddddddݽdddddd0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVSݽddddddݽdddddd/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWSݽddddddݽdddddd,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZOݽddddddݽdddddd,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQݽddddddݽdddddd,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJݽddddddݽdddddd.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[Dݽddddddݽdddddd23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVDݽddddddݽdddddd782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXCݽddddddݽdddddd8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_Gݽddddddݽdddddd671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgLݽddddddݽdddddd330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅unݽddddddݽdddddd10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_Tݽddddddݽdddddd:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤ݽddddddݽddddddD@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnݽddddddݽddddddOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAݽddddddݽddddddWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3ݽddddddݽdddddd[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnEݽddddddݽdddddd[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպݽddddddݽdddddd[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵݽddddddݽdddddd[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿݽddddddݽdddddd\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~enݽddddddݽdddddd^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlgݽddddddݽdddddd_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|Vݽddddddݽdddddd[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4ݽddddddݽddddddTH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDݽddddddݽddddddDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbDݽddddddݽdddddd47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgGݽddddddݽdddddd*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJݽddddddݽdddddd.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpPݽddddddݽdddddd@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVݽddddddݽddddddUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWݽddddddݽddddddcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jݽddddddݽddddddh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Lݽddddddݽddddddi`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMݽddddddݽddddddi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIݽddddddݽddddddi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GݽddddddݽddddddhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GݽddddddݽddddddhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHݽddddddݽddddddhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEݽddddddݽddddddgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;ݽddddddݽddddddheVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5ݽddddddݽddddddheVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.ݽddddddݽddddddheVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-ݽddddddݽddddddgdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ݽddddddݽddddddddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.ݽddddddݽdddddd\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1ݽddddddݽdddݽddddddݽҽddddddݽddddddݽddddddݽddddddݽddddddݽddddddݽddddddRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRdddRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Gamma.miff b/PerlMagick/t/reference/filter/Gamma.miff
new file mode 100644
index 0000000..e570be1
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Gamma.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:wvsywu}yvzuzsyswsxuwsws~vr|sp{ro|sp|spxslxul{xp~{s}vvz{yyy{ʊzو|⌅눃ۇv؇sՈsЈqɈqŇuŅrŅqƅpLJuʇz؉z݋}Ǎv|z~yx~yv}xuzwrvvswvszrs}qs~̥·ѬіĶvurwvs|ws~xsxrwr}vrxsxsxu~ur{sp{rp}vq}uqzvpzwp{xq}zs~|wsyxuvz{ˆuфs܎舃؇sׇqՇrψqȇqņuąrŅpăpņsɆz܈{䋀Ə~r||zx}yv}yuxxssxuwwu|vuypryx|ǞԥՑrrrrsqwvrxuqyrmyspwrqyrqyqqyrqyrqxrqxrozsrzsrzvrzxr{wr|ys~|wzr}s}ssv|{qm͌{܈wшpӇsцsˇrņoÆr…ssuvˉxሀᎋ|{xzu|zux{vs{ur{wvzvxywwwuzsqudޫ㏅x|{rsvqsvussvsovplsqmrpprppuqquqquqqvqqvsswrrwsuvspyuryuqysrzwuyv{v{v|sx~|~w~sƃvЈzތ폈҉vˈr͆s˅vDžs…qqruy~̎܌٨~|qvxpuxqswrswvvwuwyuvyuvsy{pr繾誯͞·Ļrvyqvyuuwsussqorpqqoqmlmppqrpqrpqpoopmosqrusuvrqwrqupovqqwssxxzyyxwuyv~z}}y~vwdž|Ɉz֋~܎͇zŇrDžqǃsÄsropu~Ȍ֚ŷ°zwxmsolyrqyrqwrpwsqwvqypxwomɽνuwuvvsvxuyxuzwszvryspspqrqrposqmrslrqmorpossqvsruqpvqo{ro}vpzu{wxsvuvuzr|vzrrlsxÈxŃsɉydžyƄvuvvrrpwǗƻôȵzylmvlosmqwmrymvxqwwpwqlaϳԳƽֹջïyzsz{s|zu}x}xyuwszurzwwsuwvmvxouvprxupxwpwxuvww{vqxq|rvw|swvxvxsoupu~wovmu~{|}xsqpors{Űֿ³ͷŨ{wpkguhkqppoqrlqvllsohfū˫ЮѮѲη~y~y{||~z~||{wwvv}xu}yu}zu}{x~z~ywx{{w}x}y{|{|w}p|l}sĉ}|vvu{oܖ՟ڨ߶νιȳ͵ƮozofjqdqvkkpooŠʥɩ˲Dzz{{xzzw|v{v~wwwy|{xxz~wʎԒύчzҊ|όxԈyՆ͊{߄ᚖĬmo꫰颭ꜫᖥȍumzmsĦɷúȻ}~x}x~wsvwx~x~urvvwxxvx~wz|˃g|Ճwنzۋ~тm܆y膀ꋇ~ul≂Ŧ異urw{㟨zvبzzw||xz}}~qswz~x{}ssx~{|wvѐ{q{dшkӂh}lӅyՈx׈y߈{oxqqqwo}j|dr⚐փu⌃桮¼xwsvur{zvy|{ѷΟ{{}yk|yousvvp{ow{wxs}փvЄl΃jچrxۃxՁpقqyzp{ruxqvm|c{dr}튈zցmօsꌈׂx}zszwq~{ry}⮭ÓmuǍ~҅qֈs׃m}pw{yzy~xlsmsmym~d~f|m슄܆yقg܂o~鏍쎏꒚|z}s|ym|v~}~ᨠ͘~~Իܡ䒖لlӁgقpszz}x~v{ooqqyryjmp~s芈݁h߁my闐⌆啙β|w}w|u쮶ڤ啜郆|ކvy{vzq~vvzozhfww|yw|{|z~qvzqބsyޅs㏅甑Ų{x~|uܳ~x荃戂㌁}myq{xv~o{d}d~k|o|qu{ys|pwxo|h쓈폐um݃lۃpلv݈zȷz{辽ᆃ뎍뇃xw܃quzzv{up܃q}jdzk|v~qko|oۂpքsՄuւp蛎ʻ混ڨѷzڈ|㊃{x|ރo߁jjm{qxzrzsxummwwlmy{}}k|o~|uv{p|pꑆۆx}p҂q~kޏθʨ޾⟓˾˹԰ڈq߄~сm㉀狂~hml{lu{lrholjyS}l}xwqu|}{}|pkq헎zxz߀qـsžΩڲܵչٟ{芈튈؃uЀk}떈}m{p}wxvxspsuw|~k}늈u~h҃jՀo鍉zzxwwx{l제~̭ԯԮدܮ԰ߠ~}}~پ턅{Ӄpنvzzqlzu~yfvcsdqj~|}hsWՂw}쐌wqـqvzuuxswyr{jⓌ鈙xǟѮ԰ѨШҫקخȢ~Ҽʼܳ~~yӂqގ≁}q}l{u~uwzvsrmyz쇊~zu镑ꕗ后팈ꉂ~y~xpywuywu{j܏̈ȞΥ̢ͣΦѦӞ٩Գ~λذ۷د㓈~y~uܐ樝zyqxrx~oso||ꈉs~|z{wr|}z{pyvuyvs|o؄zvŢͥȜʝ͢ПћԤͩʴܥٶε묨}}zނxݕ靐xl~wjslzp|v~m}~z}{yw|}||q}pwsv{wvu܀ykwǝœȗ˞̙ȓ{{Ͳ١֬޼ʫ|xys~w}wq܂k}肈~z~|}|xzwvz}|~}{}s~mxqz|wv{p苉sËŒǚē}űҡΪ௨۞}s|gpw~rvvpx{~z얓钉}hvwmlagu}||~|z|{w~ok}k|s|o{l戝|gz~d{‹ĔŽ{~s{ŗѵ追濻½侻չ癛s݃go}qq}msmsvw|uxlv~qphk|}{|{{}v~ok}hkj{~zgvjv{^yٻ£ƒǗďpwkqwq~|˵뽿弻¾ṵ֜쒈~klqxmq߂m펃qo~m~mvw}xsz}|~}||~}{poldk}Ҋz}{qvoܵʰĠɔǘőuykqumwxqw载ý߻Ƭwq~k~k|q|oޅqq틁omm{myo{vy{~|}o܅p܅p؁g|o吡xszjzlɧԷǐŽÕĕČ˖w{yp깶ִѹеђ|uwq{phhr܃o~k|فl܂os{~}抅~y{}}~~ڃq҃lЃm}g铝zfoˢѪ˫rǍŒ’Ŗȗʓћ՘ւr{q~v~u}porۄq|fs{鏂ꉁ솁}yہpރs|}}}y}刀҃rʃm€h}l枞ޙ͞ڰɞuyzqxȑœƘǎ͒Ԛ͜~Ȥ葓{wۅopqp~pqޅv|`ԇo~pv{}}|}{Հkҁkڂo{}~|z톆䈃Ӏqǂm‚m~fpјǙĠȮαly`|x~}vww˗ʙɕʐњў}{ڝr~joomo݃v}`ǁa݀p|醃}xۂ|ρs̆p͈qфl}o|~}刁؀zɀp€lomzfzǙŞȞqlyj~m~vs̖˖̑Лҥ||xoȞwqwxy爂؆zۊz폈茈΅vÍyxsqr…rȀpЂu܃wxڄu}p~rrprp|mŏ•ʙ˛Ů{|gvv̖˔ϖӣÔxl씕芄錇쏊戅ͅwyxzyxvqqrĀrǀmprqzm}r{oxʗŸs}py~vs̗͗ҞǙÑjˌ։哓銉爁匃싌戄́vvzyvusuvxvuuvu}q{pyl}Ǘƚmrz{woșРʠ“Ѹ~qzmvu|яꈌ솄퍋ꍇꍅ싆ׅ{rvuqqrvwwvvwu}szq{oxjyǘŞyow}w{u{|~rzǙѢŷy|q~ypwq湹睚늇范߉ƒrrqqsvwxzv}rs~q}v{rzpuhvȚ|xv|rzzwuzq{xwusyv|{qvǞəҹx}o배刄ꈈ놇ꉅ툄ኄŃxvruvwz{xs~ssu~w}swlqa{zuoxu~y}}ywsp}y}x}rrsfx˭మՕڀw戄扅茈ڇĄzzxuvwywvv~r~s~r}w~w}uyzx{rz~s|}qz~ovqwpupvryywxhۯݫ׀q}㏁Ҍ}~}yyv~u~u|q~w~w|v}v~w~xv{oymx~uw~sx}pw|rvzsvzsv{uuxru|uy{zz{|Ќ{ށuڄɂ}|{yx}y|x~vx{||pxmw~rx~sw}rvzrsysuzssyrrwqrzro{sssysyp}uru٫̇u}prz~}{zyyqyqy~vyuzvysv|ruzsuzsrxqpvoqwqqzqp{rs|r~|{zr{q{sβx}fzow{{y~||vlqyl~|~z~{z|~}}|y~xuzsrxqmumpuprxrvyvxmvwҩry{~wpq|||{|~}w}yrxrqvuosuozo}yzxvu歨syz{}|uw}||||~}~||}}v|{x \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Implode.miff b/PerlMagick/t/reference/filter/Implode.miff
new file mode 100644
index 0000000..e0168ea
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Implode.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4n=+9(E4H>E@<>>=A1@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q=5`80y7,<0B5E:C?F@B/@,>-=/=-=+<+<,<.<2C6F9FAf^wVdVCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>1.A3/B83E:6O72j7/<0?4B5D:G>@2?,=,<.<-<,:*:+;/?7F>G?XSyn}lQXE;?201(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)3,)5/*:2.=40;2.<0.>0.?4.;81?5/U1+s:.?2@2@2D7?3>-=,=.<.:,:*|:+<1E;JDTO}mssYtUKXC;822'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./0/3/+90+>3+A6.@70=5.;1.<0/@1-C1.@0-D.)[4*v=/>2;/A2?3=/=.>.<-:+x:,w:-?4H>PHh[wrvbc]z\JZH38.+&$.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.540762<61?7/D:/G;1F;2B80>4/=30@30I/0H-/=/+H0(b6,}:5:5>5B6A1>-:+<*x<*};0{?4|E8MA]Mu_ry|qsob~`MXA;6'1)"&+",.&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3B:3<8095/94/;60?91E;0J>1M?3K>4F;2B81?72>83D85F63>5-B5(Y6+|;6?>B:?6A4;/|;.x<,=2QLRHnN<pZElRfZ_brn}rzozp{qpl\aNZHT~?DM/(?3(HA-e^;w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91=71:6/<7.A:.G=/M?0O@2N>3I;2D:1@;1@;2Y;8CFB>}B9B8?5A9D7@4?<?:w?4;4?APMVHh_D}iN]X4M+J9QBWI^NdQjLmHoHnMmUjOTZ=1MH4xeӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MGHIA:F<.D:-A9/>82=71=80@:2E=3L@1O@/M>0J;1D:/>=1==2z@>GR=;A4D<@4A5B0@2>@@B@9<<<@GBYHxeIfWFM=DCN0F.H3R6Y;e<nAsGqPsXxYr\czo҅un10-/.,43/892>?5GD;OK8MK4WUSxzxu`YrLDR@9<:5/94+:6.=:2A=5JA4P@.I?-K90D839<1<>0E>BH4.=%=2<1A5=-=0>89??==<2-=4]K_LTU=B?8DA=E=IAQ>W?fBqGxKvRuOp]unsw:8163-30+74,<;2IA6UJ9TH:a]iƢ똛߅nlTQaA>@:89;92A<,H@.N@/H=,@8+:5/;60Q:2A8;05#@&:&8+?2@1?2:.312/6,4#:-UJON@E=6=/B9DEDKDPD[DfJtN|RzTtOi^q[ewxD@5A=3;6-52(:5/F=7SF6VF7\R_䋊fcRMpEAQ?<6A@,?B2<B>>EH?FG??;^8497;,;&=)=,9-<.?0<06*2,/*4$4!;/E>CA?7;+=.D>GHFJJUI^IgNrSxWxVpWiZiR[iiͩOI;MG:F@5?90=60A=7LD5RD0VJJrtߪ|xd`MKk8:@><9MILg`}rhjW`qH@F7=,?*:(;.;29,</8.4+4,0)5!6#;0IBC:;':)@7KGFDKJPUR_VkRoSsZuaq_mlujd{_SWN?VM?PI:KB4F<1E?6KF5QG0UKCkkѤ닑s}aesN_LTXkhbQ_B6;'=+;*8.9282:3=41'.(1(7!7%=3PI@79%;,E:I?F<LGRR\eduTn[skumtnx|uS\B[PA[OAYM?TJ:TG9OG;QI9UJ5WNDfbtޚ띣힥桤ꛦ߯[nDNDJEMEH<>?==/<+<.<2:2;6;6>4;0+)2+6%:)9.JG?79+;-A1=-B5E;TMecknfofppqmqiwsxuiSgAƳ[N>ZN>[N=XM<ZL<WK>WL=YL9XL?ZSVkh}~ҎՈ~Ã}pZ}CS@?=A=>?5E9?@;:?4?3;14,807/9+?2/12.608+F;HID>8-;);(;,</?0WJidehdliqns`jRhqnn}gͰڿȦɟּ[L<[L<\L<YI;ZK;[L=]M=^N<\O>ZND[PRbZkmg{uƊ}s^JU;C5A@?BDAH@AA=DD>?=8B76(3.:/5(5#;-4322.14'J>HHIC=/:*;,;-:*A2UNqst~t~s}iuPdC_uf}au]mweobtfnv{ŵ[K:[K:YK:YI9[K:\J;^K<^M<^O;^O<^N=^MHaSejbyw`<H>5?5><?BBJ??>2B963A7<-<,:.616*8%7.8)214*=)<:C?:0H;=07-:/8*:.WRsv{r\pG`@WdHexIoVczi|mnoppuÿ\K7\K6\K6]L7]L9]L:^L<^N=]P=]P=`N;bJ=cNPg_wz{jqFV>L@FBBBFCB>7:,<-?8?9=-:'9&5+0150568%;26&722,7(F;B:8241508.7*UNxxwdyMhA[DNYY5cLxbnp}i~giigq^M:^M:^M:^M:^M:_L8^M8\N<XOD`WUj\cm_hldvns}͐ѩw|ccQWDQ<F;>=8>1;+=.:362F;K<6)5+4()-'33785>;8+:%8+G@4//1-00-3);.PHh|Ll@e?VIEMa:iRv_ydvav`yc{d{a~]julg_O=_O?_O>_O=_O=`P9^N8]PEb^fyw{yxsxzŽȣķêmcPLFEG<?96=29-D:KA@56)6,B5902>&4Te3&96@8:44<:<722,10.2/.3):.PIqUp@d@d>F\G6Ob@mXxaw_pWrXv\y]xYyYb~ge|V[M=_P@_RB`RC`RA^PA_TPibqwww{jpmqƒ׫̝ydofbaOR6:6492E9SDJ=6/?93(/(@>/7?>7381:8875/6*3+0//30/7.80HGw\uHk>bI\oA:>A)DN3auMoVpTiMmQqWsWpQiK_CNi4Ia4TH8YL<_RBbUDaT@dYUpjyyqw`hhqϠ༾ǽywzle`c\ibmhnjd`VQB:8*9(:.8,8,8(8,58.94=;565335-8(7'4*402-3*>9NRaqGi=dA`HF`L>LJ6DC-MY6]uDgIeEgJlRkPdI]EY{CWoB[sDDB6JE<[M>_R>d\Rrl}vqki_`ijՓޛڝԛ՚їɑ~nl]eaXMsVFUP_`qq~{s>/;%9*4)<*D8:(6,89OL8386896:728)8'6$9&:&:,CAUeFf@g<_;LM5-89)>?,>>$U]9aqGd~L_AcDiKjKfHcIcJfIbD47-::4NC;UK=c`bjh^]VWcez|хډՉχωԋ̊zz^gi[Qb^Gp]EWOY]_`PJ:/8&6(6*:)@7<+;198;3F>87848<6<889/;*<);%<$@0JNFd<g<`AUZ6;90/04&@F'lnBqunX]>jIoOmMjJhLeJfHgG*0&+0+875DB<VW`[\}\\ij~݇냃ۂ΃̇ьЉ~upfed[Jd]Ih]Fw[DUDHE753+7%<$9,:)8)<3@8:;6:9*:*987792889<?7;+;(;(8$;0KVE_A_DWjA;@8/92+I@2`nBrʼn}hR^?lIpPkLfGgMeKfGkJ.2&+.(01+9<0ILIUTdec~|萍ˁyxlxo`Yi\Lg]Kk^N~^ON?<14-5-6,7*9*;,7#>)8-8=8886<)<(:287;5>8=<=7</;)9&7&E<QUSaOWZQOB1<A'IS2eoHbwvp_I_7]z=hEhHdFgFkOiNfEpP@>0>=4<=2AE+KL8TS@`^Zur{tqlplnhuka]j\Mm]HkaLx_OWLMC8-8*9,9,8*8*9*<.79%<6@?=2>1<+=*7+<4?6B9;7<28*:(9'8$=/VSTSXS_MniBdxBYv[sVp~TalLBJ6<G.\p>iEgFeGkLlPoQmMvVUM>VM?VN?VP=\RC`WBbYIi_^qeorfok`b^XUVSLUQCXR@]WCa\Ha`O`VRPA@:2;*8(8):):*;.</?-F=HD@5E2@0:-<-9*:.>1=/9.9-9););(z5#<-LATJXNbVw_fmSUi@HX9AG49:.45,9@0Wj@kInLkNmPkGqKxUqWcZKe[Ke[Kd[Le[Mg_Kh_Ig^Lg^Mg]Ke]H`ZGVR@NJ8JJ8JM;JO?NOAbO?WMKJB<<09+:-<0?3B=D>F?CBB?=1@2;2;2};0z;,~:+9-9+8*9,:+}:+x:+v7(;-I<SHYOYS[O^^?BO55@04;0=?698-89/9?/Qd>mMuQpRpNpJxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbTi`QiaNibLibLg`K`ZFQN;DG7?E6;E6>E1`L5[JYWQTC;?5B:F@IFGJIIEDB@A=:/=192;/;.|:-|:.9/8-9+;,~8,{3(y7,q6*w:.L=PCRLUUe[ukNN\9>K4JSEKO<??*9:,8=.L\:lMuPqOqKyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk_^kaWkaTkaVlaUlbQg_M[VFKJ;AB39B,`G5F?HHX[\]JGC>C<F@DEAEDDC@C>B<;0=/:0:-:,~:.}:/{91z8/z9.y:/v8.t6,s5*o3)t;0L?SFRKVP}[NcbFXkATf=RbAGP5>A+9:+8</GV8kLvPpNrQ}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldPldPlbUmbUnbTkbSc\MYSBNJ6@A'uL<EADDLLLKFEB?A=C@CDDDEDF?F=B;>1=-;-:+:,~:.~:0{90y8/w9/v9/t9.q6,o4*k3(o7-~H?SMRMXNxcOYfFSiAVk@FW1:E+8=.9;17;.@L1b}CwQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTobSoaTkaVpk]zueso[\VATD3Y?2Y>4S>3`B5GBJMGFA?BCCDCCD?D;B9>2<,<+:+}9-}9/}:0y:2u80r7-q8.p8,o6.l3+i3)g2'x@6SNXQ\Qk_KS_CGZ:FW7AM1:@,9;/8<25:/<?,Xh?tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTlaTj^T{votXXD;B-9=-;80:5/kED}}c`DE?AAAAAA>B<B;>4</<,:-|9/|:0{;2v;2p9/m7-l8-l7,m6/k5,g3*`.$o8.QLZPhVHPO?AI77@05=-:C1=F48A04;/4848:,MY4rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRf^S|ƲrV^B>@.=92YTQcbEAA=>=@>B=B<=5=1~</:.|9/|91z;2t:2l9/i7-h7-h8-j7/j6.d2)\-"h7-zLFjOELH99B23;/26/24006-5@29I60=/.2/55+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQljeʧ{}^JJ7YXOĹ|lC9=6A<D>B<>5=4<1~:/{9/z90x81r8/i8/g7.f7,e7-g7.i70g6.d5,h>4aE>LA98:.19+3:.69148318..:+6D29G516,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddȍpX_MǿǀvG<>4F9E7B7?6;2}92x8/u7.s7.n6,i70g7/f6.g7/i70k80i<0lH:rVIYLB26.15-37,46+27*/8+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhܾmwNj{PA?2?7=:?;u@:t>5s=3p=2l:1k80n61k60h7/g91h<3i?4gD2lT@zr_XZK+3)17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ӹǐ}XG@582<4pA7r>7r?7q@8l=5l;3p73l82g:0c;1_?2aJ9aN7cX?twaHP>,2)07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupΟn[M=~>.l=-m92p=6p@8m?7l=5l<5h=4a@3^E6N?-QN6ZW;aaChpV2?+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoоlWXE|PDj?2h@2gA4fA3aD7\F5XI6c]FDF/:C'GK,ooQ[_F39(7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿhU<WE,\K2[L4UO:QN7MO8\eI@L0>F+HK,igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Magnify.miff b/PerlMagick/t/reference/filter/Magnify.miff
new file mode 100644
index 0000000..1b38d56
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Magnify.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=140 rows=92 depth=8
+page=140x92+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-10.20.41/62/73/83.93.:3-:3-92-91-80-91.91.91.80-80-80-80-7/,6.+5-*5-*4,)5-*5-*5-*5-*3-)1-'1.'1.'30)41*63,74-85.96/<8/?:/C=1F?3HA4JB4KB3LA2MB2NB2RB2UA2eC3tD4D4C3B4A5C9E=EBDGDGCF@D=B=A<@>>@;@5?/?.?-@-@-A,A+A+@+@-?.>-=,=,=+=+=*>,?.?1?3A3B3C5D6E8F9t@4R:/F81:5394272172072/72/61.51-30,10-//-0/-0/-2.-3,-5,-6+-C13P78i@@IGV[bno||vlp^\PHnQJhRLadbouw|~z|lji`YVSYVS0/-0/-10.30.61.72.82.82-92-92-91-80-70-80-91.81-81-81-81.80-7/,6.+5-*4-*4,*5-*6.+6.+6.+4.*2.)2/)2/)30*41+52,74-75.860;7/?9.B<0F>3G?3IA3J@1K@0L@0MA1OB2QC3`D3oE4C2B1@1?1B7F=EBDGCFCF@D=B<A<@>>A;@5?.?-?,?,@-@,A+@+@+?-?.>-=,=+=+=*<*=,?.?0?3@3A4C5D7F9G:p@4K9.B71:5494383172072/62/62.41-21-00-.0./0.00.2/.4..4,-4+-?01K55d=9}E>QR^em}xuhnZYMCmNEfOF_\Xhikrz}|vsvfff\YWSYWS/.,0/-0/-30-50-61-71-81-81,81,80,70,6/,70-81-81-81-81.81.80-7.,6.+4-*4-*4,*5.+6/+6/+6.+5/+3/*30*30*41+41+52,63-74/750;7/>8-B;0E=2G>2H?1I?0I>.J?/K@/LB1MD3[E4iE4{C1@.>.<-B5G<FBDGCFBE?C<A<A<@?>A;@4?-?,?+?,?,@,@+@+?+?->.>-=,=+=*<*;*=,>->0>3?4@4B6D8F:H;l@4D7,?6195594393183062/62/62.42.11-/1.-1./1.00.30.5/.4--2*,<./E21_:3xA5MIY\k}uuclWUJ>kK?dK@\TOb]^gors~v{olp_cdYYWSYWS.-,..,..,0/,30-30,40,5/+5/*5/+5/+4.+3.,4.,5/,5.,5.,5.,5/-5.,5-,4-+3-+3,*3,*4-+5.,5.,5.,4.+3/+30+31+41+41,52,63-64/750:5.<6-?8.B:0C:/D;/E;.F;.H<.J>/IA2IE4TE4_E4nB0}?-=,;+@1F8F=FBEBDC@A<@=?=??:A6@1@,?,?,?,?-?,@,?+?*>,>->-=-=,=,<,;,=-?.?0@2@4@6C:F>KAPEgE;@;1=82:53:4193073/63/53/43/13./3..3.-3/.2/02/11/31/2/.1--7..<0.N4-a8+pE@SUkxxgoXVI>uG;hD9ZGAYIIXTX]_fb]d[[bTZ]SYYQYYQ,,,,-,,-+..,0/,1/,1.+2-*2,(2-)2-*1-+0,+1,+2,+2,+2++2,+2,+2,+2,+2,+1,+1,*1,)2-+3-,3-,3-,3.,3/,30,31,41,40,51-52-64/75094.:3,<5->6-?6-@6-B7-C8-F:.H;/G@2EE5ME5UD4aA0m=+y;*9(?.E4G9H=G?E@A?<>=>>=@7A0A-@*@,?-?->-?-?,?+>)>+>,>-=-=-<-<.;.=/?/A0B1A5@8D>GDOIWNcKB<?5<:3;41:4093.73.53.34/14//4/-4.-4/,40.40/3/03012011/00.2/-3-+>.&I.![>8lMN{j{|kqZWH=C7l=1X93P54H:=G>FFDMHISIQWLYZOYZO,-.,--,---.-/.-0.+0.*0,)1+(0,(0,)/,*.++/++/++0++0++0++0,+0,+0,+0,+0,+0,+0-+1-,2-,2--2--1.,1.+2/,30,3/,3/,3/,40-41.53/73.93.;4.=5.>5.?5.A6.B7-E8/G:0G>3GB6MA5S@5]=1f:.r9,8+<.@2B5E8E:E=C>A?B?C?B7B0A-@+?,?->.>.>->->+>*=+=,=,=-<-<.</<0>2A3C4E6D9C<MGWRd[qdkaUJRFDG=?;5<8184-53,22,12-03-.2--2--2.-20.2//2/02/12/02/01.0/.1-/8-+?,'TB?jXX~uƃu|giYWROyKGdKL`KR]U`c`niapgcqe_h[\`P\`P,-/,-/+-/--..--/-+/-)/,(/*'.+(-+(-+),**,**,**-++.++.++.++.++.++/++/++/,,/--0--0,,0--0-.0-,/-*1.+2.,2.,2.+2.,2-,3/-30.61/82/:3/<4/=4/>4/@5.A5-D7/F91G<4H>7M=6Q<5X:3_70l7/y7-9.;/>1A3C6E9E=E@GAHAE8B/A.@,?->->.=/=.=-=,=+=+<+<,<,<-<.<0<2@5C7E9G:F=E@VPg_ylysxhWeWMTHCB8=<275+33+/1*/1+.1+.1,-0,-0.-0/.0//0.01.02.02./2./00/-22,/4*,NGGgcbΌ~t|ipafY\o]fq`prq|nzi_eQ_eQ,.1,.1+.1-.0../..-..+.,*.+(-+)-+*,**,*++)**))+**,++-++-++-++-++-*+-**-*+-++.+,/,,/,-/-./-,/-+0-+1-,1-+0,*0,+1,,1--2/.50/820:30<41<30=30>3/@3.B4/D60D83E;5G;5J;6O93U71c70q7.:/<0>2@4A5C6D9E<F=H?D8A1@/@,?,>,=-<.<.=-<,<,;+;*;+;+;-;.<1>5A8E<F<F<JCMIe[|mxysesdXaRKN@BD7:;/56,01)//).-)/.*0.,0.,0.-0.-0.,0/,00-00-01-0./1,21+.2**LJBfjZ{xn~h\eN\eN,/2,/2+/2-/1..0../-.---+-+)-+*,*+,*++)+*(*('())***++*+,*+,*+,*++***))*))*(),*+-+,.,-.-./--/,+0,+0,+/+*.*)/+*/++0,,0--4//811:22<32<32;21=10>0.@1/A2/A51A73B95B:6G84K62Z71h7/y:0=0>3>5@4A3C5D7F:G<C8?3?0?,>,=+<,;-<-<-<-;,:+9)9*9*:,:.=3?7C<G@F?E>MHURsg{~rpcn\SZGHM=<@369.01(/-(-)'0+)2,+2,+2,+1,+0,*0-+0-+0.+0/+1-.2*11*-0)(KM=eqR}wʳɲǰogYdJYdJ-00-/0-/0.///0//0.00.0/,0.+0-+0-,/,+/++-**+)*+*+++,+*,+*,+),,),,)+,(++(*+(),)*-++-,,.--.-,/-,/,+/,+/+*/+)0+*2,*2-+3.,60.:20;30=41<30;2/<1/=0.>0.@1/@3/@50>71<:3?71B5/O3-\2+j7-y</>1@3@3A2@2@2B5E7B5?3>0>.=-=-=-=.=.<.;-:,:+:+:*|:*}:-~;/?4C9F>IBJDKG[Tkaruuf{cXkQN]GEO=>B576.3/+0((0))1**0*+0*+0*+0*+1*,1+-1,-1-.1,/1*1/)*.($GJ6`lIziʠǡŢ~zi|aT`GT`G.0./0.//-/0./1.11.21.31.30-30-3/,3.+2-*0,+-*+-+,,+,+*-*)-+)-+(,,(,-',,(++(),)),*)-,*--+.-,/-,/,+.+*/+*/+)2,)4,)5.*6/*91,;3.<4/=40<3/;1-;0.;/.=/.>/.>1->3,:6.59/76.93,D0*O,'\3*i:-v>/A1A1@1>/;-?0B2@2>2=1</=/=.>/?/>/</;.9,:,{;,y;+v:*z;-};0A6G;I@KDNJQOi`p~wyjj\{ZUmQN^GFL==:381.2'(1')/').(*-(+/(,0(,1(.2(/2*01+01+00*0.)(+'CG0[f@v[vvvɌƐÓ~yvpcuZO[DO[D02.12-12-22.22.43/64063/63/62.71-60,5/,3-,0,,0--0...-.,,/,*.-(..(-/(-.),-)+.+*/,*/-*//+//,0/-/.-/.-0-,2-*5.*8/*:0+<2+=4-?6/?6/?70>5/<3-<1.;0/<0/=0/?1.B2-C2.D1/B0.@/-A.+C.(P1)^5+j9-w=0=2=4<2:1=2A4@4@4?2?0>/>.=-=-<-<-<,}<+{;+y:,w:,u:,x</|>2B7G=JAMETL[Srbq}~w{lnaa]}[YsVPaLGPB=A732,0,)-'&-&'.&).(*.)+.),.*.-*/,+0,*/,)/+'(*&!BC2YaDp}Zpppw~}y|{vsn`rYNYDNYD23-34-34-44.53.750961961961:40:2.91.80-6/-3.,3/.3000/0-.0.+0/(/0)/1).0*-/*,0,+1.*1/*10*11,01.01//0020.4/+80+;1+>3,A5,B7.C8/B90A90?7/=5-<3.;0/<1/<1/A1.E1-L-.R).L*.F*.?-,70)E0)R/(^4+j9.w:3:7:694<5?5A6B6B4A1@/>-<,:+;+;*~=*v>)v;+v8,u9-s9-w=1{@4D9G>KBNEYNdV{dzq{}{}v|nregefdeZw[PfPBR@4=0/2**&#,%%.$&-'(+***++)+,(+.'+/').''-(&()$"@@5W\HkwY~j}j{j}m~ooo~r}t~x~{wtol^pXLVDLVD560560560660761972;83<94=:5=84>63=52=51:408308318436324224/14,05,/5,/4-.3.-3/-40,41,42,32.330431442730:3/<4.?5.B7.E9/F:0G;2F;2E;2B90@7/?5/>30>30>41?41A51F21K/1G/0D0/?1,:3*C3)L2(Y5+g8.v:3<9=:>;?9A8A7@6A5A3?1<.;.;-<-}=,{;+x9)?3D<G?JBH<vE7xI;zM?|RC~WGcOoWv`|is}}}vxouoroig`}`ShOFS?=B251&3,%1'$,)%(+&),'*-)-++1)-3(,5(+:1-?9.OP>`gMixWsasbscufvivjulwpxtyvyxrplh\oVMWDMWD782782782893994;:5<:5><7@=8A<8B:8B:7A95?84=73=74<75;65:54:329009009//80/61.62.62.63.63.640641862973<73?72A81B90E;1H=1I>3J>4I>4H=4E;2B80A71@61@62?62>83<94@74C54B52A50?6-<6*A6)E5'T6*c6-u:4=;@>BAC>C;A9>6@6A5>2~:/|;/y;/w=/u>.x9,z4)B;PLVQ[VSHpJ9nO=kS@oZEs`IymQzXp\f`pizr|~zvwxxtood~^XiMLR;?;)92&3)",*"%+!(-$+/&3+(:&*?(*C))L<2TN:^`FhqRhzUhWjZk\m`ncmfkhonstttttnlhd[oTNXCNXC893893893::5<<6=<7?=8@=8B>9C>:D>:D=9C=8B<7A<7A;7B;7A:5@94?72?61>51>51=51=61;5095/85/84/84/840961;72>81A:1C:1F;0I=1L?2L?3M?5K>4J=4G;2D91B91A81?92>93@92B82T;9g=?j>>n>=g=7a=2m>5x@8}?5>3>5>7@9C;C9D6B5?4?8@<?;?:?7x?4w>3w<1:589AAKJQNXSUIpR>kXAf_DtbIfNfTgYWWGTLYR_afqntnwowoxo}qsrqqgd]WTIJCF{=Bl;=^98N40?/'=.(<-)A1*E5+QE3]V:fhIpzWmXkZlZl[n_qdskurzy}~z{pnfb[oSQ\EQ\E8939:49:4<<6>>8@?9A?:C?:D?:E@;FA<FA;EA:EA:E@:F@9G?8F>6E=4E<3D;1D;2C:3C:3C:3@92<80;7095/95/94/;60<70?:0B<0F=0I=0L?1OA2PA4P@5N>5K<4H;3E:1C:1A:1?;2=<3B:2G70i>=EJFJGIEBC:GAKHIAF9C6?3A4C5D3E1C2@2?:>BADCEC?vC9x?7y:4;><HAHEGMLUPWJpYChbF`jHxkNlS`WSZ>Q(H)J)K5Q@VG[M_SdYh`kfnhpjrep_m[lWkTgPbKYFOt:<R.(H1(>3(C:+G@-VO4e^:nqKw\s\n\n[mYp_sdyp~{rpd}_\nSS_GS_G782792893;;5>>8@?9B@;C@<E@=FA=GB=GB=GB<GB<HB;IA9JA8I?5H=2G<1F</E<0E<1D;1D;2A:1?91=70;60:6/:6/;7.=8.@:/D<0G=0K>0M@0OA1O@2P?3M=3K<3H;1E:0B;1@<1=<1:=2O=5d=8BFHTCI=?>7?/B7E?C:A5@4?3A5D6B1@-?/?2?8>=>@>B?>@;?:?:<>:B:<:7C>LEUG_I{cItgIgQhYWTGP>K5F6I8M7M7N:Q=TAYE^IbMePiRmOnMnLnLoLlLiNfPdJUEGn>:P8.L=.HB.]V?rjO}~dyyzzz~f|b]pVUcJUcJ671681681:;5==8@?:B@;DA=FA?GB?HC>HC>HC>ID=JD<LC:MB7L@4J=0I=/H<-G=.F=/F<0E;0C:1A91?81<71;70:7.<8->9,B;.E</I>/M?/N@0OA0O@1O>1M=1K;1H;0D:/A<0>=1;=17=0\@8B@GOK]?I357,;#=,?5=3;0=2>3A5D7?0:(<->2>5>8;<8?:><<@>D?>=7;31.'81B:SEdOdMcJcTc^OR;E?DBCDIFO:J.E-G,H.N0T2X4\7b:h:l:o>qArDqGoQtZx[o[fLMa=3U@1HC/d]Jvd}¿°g{e_qYWgLWgL551561671893;;6=<7@>9B@:EB<FD=HE>HF=IF=JF;LG9KE8KD7KC:LC=J@8H>3G=0F<-E;.D:/B90@91?81=82<71<70=80>90@;2C=4G>3K@3M@1PA/N@/L?/K<0K:1G91D92?;1:=1;>0<>0gB8F@CB@D:84+9(>%=)=-;,9,;/>3@3C4@1=->0?3=2;18355444474:482704*2$8,>3M@]L\M\NWQRUHL=C>>?9B?FE?E8E6F5H7M9S9V9Y:a<h<l<p@rCuFrIoQsYxYuZsTbMQSMhYJ|n¼œvtn|ift]ft]330441551772883;:5=<6A@8DC9FE<GG>IH=JI;LI9MI6KG7IE7KGAMHJKDBH@9G>2E;+D:,C9-A9/?80?82>83>82=71>83>94?;7@=9E?8IA6MA2P@-L@-H?-J</K81G83C74<:25=0;>0@?/sD8I@?64+4&4!;$A&>%:$8&6':-=2?2A1A2@2@3@4</8)5*1+.+++.*0)3'6%6#5!7'9,G;UIUMUQKNAK@F?A=8;.@5E;C@AD@F>H@MAQ?T=V>_>h>m>qBtEwHsJnQsWxX|Y[w]nfindҬ}yunun22/22/22/440661883;;4>>6AA7DC:GF=JH;MJ:MJ7MJ5OL>QNG\Z_gfxdarb\mYR]PHMJBFE<>@98<62;6/:5-:5-95-;7/<91?;2A=3F?3JA3M@0P@.K?-F=,D:,C6->60:62;60<7/P92e;6>7B8=08)8&8#<&@)>*<+:+9,:-;.<.>.?0@2=1:/8-6+5,5-1,.+/*0)3&6#5"5!7'9,B6J@KDLIGGAE@??:<3:+>0A4B;CBCFBJBLCNBSAW@^@eBlDsFvHzJwLtQuVvRtNq]vl{ilg\10-0/-/.,21.43/661892;<4>?5CB8GD;KH:OK8NK6MK4SQFXWWlm~~~|xlf[ToQJ_F?O@:B94483-62&62(52)86,:9.>;.B=-G?.K@/N@/P@/J>-C;*?8*:4)54-04093/B1-f456<96;/<+<'<&;%=)>,>/=1<1;1:.9*:+:+=/?29.3*4+4,6-8.5-1+0*/(2$5 5!4!7'9,<1?6A<CAB@A>@9>3<.9(;+=-A7E@FFFKEKDKDRDXC]BbFkJtKyK}L|MzQwTtLlCc_v{mn_T64/42.31-31-42-64.87/::1==4C@6HC9MG9SK9RJ8QJ7WSN^\ewxŒʔЈ|{sqkg_\vTQaJGPA>?>;=;9;;97;94>;/B=+D?-GB/EA1DA4A@9?@>?BA@EE=DC;DAF@;R<5p=7>:=3<-=,?*=(;';):+:.;1;2;3:09.9/:/<1=2;1916-3*3*3+1*/*0)1(3$6!6!6"6&7*<2A9G@MGF@@8>2<+;*:)<-?2C;GCGFGJFJEKGRJZG^DaGiJqLvO|Q{SzTvUsPlKe\qn|ahUŮ鿷:8186/63-52,30+52,74,:8/<;2C>4IA6PF8VJ9UI:TH:\UVdar䥬얘ُ~nm][sLIXFDS@?M><C<99?;1A=(B@+BC.=B48A99CE:EQ@MYEUaFTZFSRTMGaG<{G:F7B1=+?,A->+;(9)6*7-8092:4938293:3;3;2=5?78/1'/(-(-(-(0(2(5%7!7"7"6%5(<2C<MEVMJ@>2<+:#:&:)=0@7D?HFHGGHGIFJKSO\K^F`HgJnNtRzUzXzWvUqTlSgZl`pVcKU{}᪤?<3=:2<8096.73,73+63*96-;81A<4H?7ND7UI8UH8VG9[QSa[n|}ᡪ줧◘Ћxvfc]XSNvMHfGCVB?F<<6==4>>3BB;EFDSQ]`\vldxk|bwXgQVIFE;A/>+;'<)>,<+;+:-9/90:29283:4;6;5;5:3:1>4B8=38.2++),),*/*2*3'5#7$:%9'8):/=5G@QKIBA9=.:$:&:)</?5F>MHIEFCHFJJMQPXO\MaOgPnPqPuSwWyVuVpVlWhYi\kT`MUnoD@5C?4A=3>:0;6-84+52(84,:5/@93F=7MB7TG6VG7WF7ZNQ]Ujwwޞ﫸ـ|slf\\TRLsEC[7:C9:=:97FBCRJNl_uszo]{TfKPD<<';%9#:':*;,;-<0<3<3;39261:5>9=8<7:38/>4D9B7?44/))**++/,2,2)2%7'<(;):*9,7-B;LHHDC@>29$9&9(<->2H>QIKDE>JDNIPNQSSZTaUhVnRoNoRtUxVtWoYlZiYgWeS]OTbatnΫJE8HC7GB7D?4A;1=8/:6,;6.<60@94D=8JB7QF6SF4UE3XKIZQ_rrЙ橳掎؃yumlacVY}LPeVJX`DKwHOMSVg`|b~eXnL]HREGA;=.<,<)<,=.=/=1<1;1907/707092;492807-6*:,?.?0?28212/1.00/2.3-4-6-9.9,9+:,;.D<NIIGDE@8;,:+9*;-=0D7J>F:A6F<KCMIPOTXXa[j^rWpOnSrXw^uetap^mdpisfhb]bZ|bXOI;NH;MG:JD8F@5C=3?90>80=60?:4A=8GA7ME5PE2SD.UHAWLSnmަ픗㋍}ozhpaesZsN_O[OWNZL]JXHRBH;>=>>>>:>5>2>/?1?2?3>4<29/6-3+5-7/8/8/6,3)3'3$6#9"<)>0;68;48051320425454536/7+;->/G=PJKJEIA>=3;/8+:,<-@0C2@0=-C5H=KDNJUV\aalfv[rPmUqZufwrxjtbpox{xsuetcSVPASL=RK=RJ=NG:KE8HA5E>2C;1B91B<4C?8HB6MF5PF2SF.UI@WMRmmܥ돘ۈˋn[pHWGQFKEKDJDFDBB?A=?>>@=<<9=7?5A5B6>2:.8.6-5.4.6/9/8.8,6)4%4$5#6#8$9(:-807352424131231503022.4*7*:*D8NFJGGIFDE??68-:,;+=,?->,<,?1B6E:G?RM]\dgjrcp\o^qasjtsuntisr|{€{qlkULQ:~WN?WN?VM?SK=PI:NF7KB4I?3F<1F>4E@7ID6LG5PG2SG.UK@VNQmmڣ஑v\nAN?G<?<;;7>4@1C6F;B>=A;?9<=;@:C:E9>16(4*2+3.4180;/9,7)6%4!5!6!7$7&6(5)5*5+7-8.604214-5,3*0.-1)3'5$A3LAJEHIKJMKC=8.9+:(;(;';);*<-</>1@3OE^Vfbnmkogpgqgqnrtrrtouuzĉ|etXAQ3zYO@YO@YN@WM>UK=RI:PF7ND6MB5KC7JD:LF8OI7RI4UI1VLBWPSlk̜圞띞휦䜢䛟㗜ᔚޣ̳rZoMYAD?C=A=@=?>:?6C;GABA>A=><<=9?6@5B5=/9*7+6-6/72717/6-6,6)6&7&9&9*9.90918-7(8(9(6*4,2/12101.3+5(7'9'?1E;E@DFKJQOHB@6=/:):););*<,<-</=/=/L?ZOd]nlildldmeokpqrmqjqiwi~|xsfxWM`<[PA[PA[OAZN@YM?WL=TJ:TI:TG9QG;NG<PI;RJ9UK7WK4XNDXQTliԕܕ䗝虢엡┟؎ԈЈLJwiSs=P?E@:??>C?E?F?A>;CAGFCD>A?>?;>6=1>1?0=.;+;-:.:193613/4/4.6,8*:+;+;1;6<8<9;/9%9#9!6$3&4+5/6-7+8)8&;(=)>/>5?<@BKKUSNHG=@39):*:*;,<-<.<.;,:*H9VGbYmjgiagbjbmhonqiodl^nWppmuig{WXnE[O@[O@[O@ZN?ZN>XM=VL;WK;WJ;UI<SI>TJ<UK;WK8YL6XMBWONd_orp||Ìώ֑݌҈w|ul_RnE[8H=BC<BBAIAHAG@??8B<EA?=99=9A8>3<-<,<+;);(:*9+8-7/402111011/3.4052362:27253-5&7%9%8(7,8/92;1>1:+7&8(9):/;59779><E?A9>4@4B4?1<.;-9,:,;-:*9(D5OC_Xonmpjsjsjtmuqvgo]iUiNiqnsyekVǼٺֱԧׯ۸[N>[N>ZN>[N>[N=ZN=XM<YM<ZL<YL>WK?XL>XL<YL:ZL8XL@ULG]V^d_unlwx}|ĉ͂{{qtfmq`|RbGT;F7C3?<?E>DFCNCKBGA>@5B8C;<641;3B5?/;):'9%:%:%9'8(6*4+3/13/3,3-2-1.5.8+;(>(7(0,,0'4(8(:-;2<3=4A5D6=.6&6(5)6/7532./1-4*5*5*@4J>D8>1:.6*8+:+9)7&@2H>]Xqrrxs~s}r{s{s{epVeMcDaro}r}g̮׺ָʪǚΪպ[M=[M=[M=[M=\M=ZL<YK<YK<ZL<ZL=YL?ZL=[M<\M;\N:ZN?XMD[QR_V_e^okfqlxs{Ɋ}vo\}IUCG=9;::<=>A?BFCLAF??>7=/@4C:=785=6C8>/9':':':&9&8'6(6*7-5-3-/,,,,,+,*1*5$8:#7(3/46653515466544193>6>6?7:36/7296512-4*6(6)7+B7NCE:=2:08.9.:/9,8)</@6WRnotyzxvt~s}bqReJbB_jfner\q~{|}ŭʽŽ[L<[L<[L<\L<\L<[K<YI;ZJ;ZK;[L=[L>]M=^M<^O<^P<]O?[NAZMEYLI\PW^Sdf\mezrđ~xqYu@G?9>+?2@9>=<@?EBJ?A<7;09(>0B8?8;8@9D:>/7$9&;(:(8'6'4'7+9.7+4'0&,$+&)''-%2466'62=<D7?1:1:0:.4+.2285@>GG?>6495;6805*7(8&8)8+E9QGG=<3;291:2:39/8+8,8-RLkkvz~zvr`rMdF`?\c]^uXgQrW|\oWa~QcUeYoayhntwy|õŵŵ[L;[L;[L;[L;[L;ZJ;YI:ZJ:[K;[K<\K=]L=^L<^N<^P<]O=]O>\N@\MB]NL_OVcWpg^tm{wkSk:I=A?9@;B=@@?DADCE?<<3:-9'=/A7=8::A=I@F9D3>-9(7(6)6*5,5-5/4/3000-0+1*2)7)=&B"G/J<MDSLY@O5E2>08111*70>6E@MKEB=:;6:28-6'8&:&9(8*B7LEC<:382616152709.7,6*MFdatv{uo~]pKcE^?YYRntKj|MfPrX`w`p_qbreyhlorstvxĺĺ[K:[K:[K:ZK:YK:YJ:YI9ZJ:[K:\K;]J<^K<^K<^M<^O;^O;^O;_O;_N:_MA_KH`Q`aWwog|w‡vewMa4K:I@FBCC@CDBGCDC@?7;.:*8&<.@6<98;C@MEOCPAC56(5)4*5-60401/1419/;-<,<*<,B-H.P.W@]QcWh\mJ^8O4B054.7&=.C6KBSNKGC@>79.8)7$9%;%:'8)?6FB?;836231210051917,4'H?\Wrq|tk|ZoHaC[>UPFYa7_qCeNsYdi~moppopppopqÿÿ\K9\K8\K8[K8[K8[K8[K8\K9\L:]K;]K<^L<^L=^N<^P<^P<^P<_O;`N:aK?aICcR\dZtql~zmtVb@P@N@L@H@D@C?B@>A:>3;,;+;+<0<59463<5C6I<OAE7<.9-7,70754627.5*4(4'5&4&4':)@/K5WG`ZjXeU`GQ9B673-3&28)?3B;FBFBFC@9:/9+8(9(:(9*8,@7HA?961311101/02/6/5*4&D:UNpn|obxSmDaA[?TNDQ]4^tDkUw_jlom~kkklnljmp\K7\K7\K6\K6\K6]L7]L7]L8]L9]L:]L;^M<^M=^O=]P=]P=]P=_O<aM:bJ<cG>eRXg]qsr~uq`cKUES?Q>L=G=B<==9>4=/;*=->/;1836/3+6)9'C4MAG:A3>1:.94795<2>*7"/!. -!,!+#1%70G;VOccpYbNSDD:58-6$2-4$:09386A>IEB;;0:.8+8+8+8-8/A8J@?73.10.1.1-00.2,3)4%A5MEnk{j~YtLk?a@Z@SMBIY1]wFp[{eopql|f}f~fikh~ejn|]L9]L8]L8]L8]L8]L8^M9^M9^M:^L9^L9^M:^N;\N=ZO?\RE_TKdUOhWThVUhVWj`rlkvzДŦ}vwghXYOVFSAL;D:?::=7@3=/;+?1C7@6=6915+6)8'</A8B6C5?2;.72467>;F7A3;-4(-'+'*)/,54A=MGSQZJPCF=<72=4C7@6>5@8B<DAGFGDGCC<?5<3:183546687>:D=;52,1.01/1.1//1-3)4%?3KAnjvcyPnGh>c?XAMOBL^7^zIq[xbi~i|i{fyc{d|e}f}h}d}`eku^M:^M:^M:^M:^M:^M:^M:^M:^M:_M9_L7_M8^N9ZN=VNA\SMaXYh\co`mnbomdponpxzɃꎈܙͩ}v|mld\YYMUCK9A8<77=5B2>/:+A5G>E<B9<26+6)6'5+4.<3D7@3<.6103:ADNDKCG9:/-.+,(/.238;>C?C?C;>78533.A<OJONOQLLIGONUUMKEAD>B:?9<77:2=5>7?;=>:821*2-2001.2/00.2*4%>1H<niq\uFhAf<d?VAGvRBNb<`|KrZv_ycwbu`v`v_xbzd{d{d{_{Zahov{olglg_N<_N<_N=_N<_N<_N<_N<_N<_N<_N9`N7^N8]M9\QE[UQe_goj}tlxotnomsvvȏٜͪµǀpjW[QMKGHAF<?78;5>2;/9-@6H?NDTIH<;/8,4)3+3-:1A4=0:,4-/.68=BDIKPDG=?>???ACDGBE?C>B<A7<288=?BOR_b]c[dTWNKIGEDDAC?C=D;>78448/<3=6?8;:7603*2-2001.2/00.2*5';/B8he|j|VqBf@e?d>P}>;eO<Ma=`zMt\w`zcv_r\s\t\w^yaz`z`z\yX~^ejowgi_i__O=_O>_O?_O?_O>_O>_O=_O=_O=`P:`P7^N8\L9^TM_[anl}|}}yzqvw~|ƋǚǪȶtpR^JLAJFHJ@B7996:2907.@7I?XLfXSF@39/2+2,1,7/=1:-7)2)-)1/55DGRXNUJQNTQVTYV[KO@B=A9?3;-7<GJV]hozkxfv\bRNDA53;8A<C<E<=64005,:1=5?69635/4*3-2/01.2/0/-2+5)9.<3baubwPm>c@dAd>J\;/TM7L_>axNu^xa{cu]oWqXrXu[x^y]y[xYwV|\aehs_e|Ve|V]N=^O>_P@_P@_Q@_Q@`Q@`Q?`Q?_P>^P=_QE`SMe^eki~ssz|vxrttvvxdž̖ѪȿǶѮЧϡDZr{bcS^VZYQQGJ@@867371<4B8NB[MSEL>?42)5/84;4?49.4'0(-(1,40=;FGJMOTQXT\Xa]eW]QUBH4;/9+79FHUWbgpbl]iQUEA=:6495=7>7?6;473574;5:6:656/5-5*3,1.01/3/10.3-7,9/:3]^m~ZtLl=dAbF`AEM<+JH1GU7[nHoYs[x^rXlRnSpUsXv\vZvXtUrRqRqSlQgN_zJWoEWoE[M=]O?_P@_QA_RB`RC`RC`RB`R@^QA\OB`TRcYamh~wwwzw|mscjorzz֕ٯϞ{ydsflgbaWZGJ6:676382:1E9OATEXIE81'82><?:@78.0%/&-'0)3*6095FFSWU]Vb]idockagHO/7,7(67EFSR]^fYaT[FG7374647382818093:5;8;;9865605+6+6*3,0-01/4020/5/9.9082XZweyRpGj<dC`J[CA=<&?C+AJ0UdBh~SnVtXnRhLkOmQpVsZsWsTpQlMgIbEXz=Nj4Lf4Ia4Ia4XK;ZL<\N>^P@_RB`SCaTDaSB`S@aTIaVRh`ioirqvypujqiqhpx~ˉۡ޸߾ٵдyrenekfjghh[\OPFE=:<7<3A6F9I;M>B47*=6CAD@E?<54+3+2,4+6+8,:.A:HGHLHRT^`k^g\cHL354:5@<FCMGNKPHLEI==625252719191:29385979:8765606,6+7)4+1,1015120/3.7,:3>:W[p|[sGjBh>fE\LQtIAHF1EF0CF/OZ:\oFe~LoRkMgHhKjNmSqXoTnPiMeIaG^DXx@Sm;Rk<Rj<Rj<TH8WJ:YL<\O?_RBaTCbVDaUB`S?cXQf]bqk{yxztzip]fenlvИ߭·yywojejejdrmyupmgeVSDAA;=5=3<1?2B2?0<-B:GFHFIF@;7070608.9+:):&<.=6<<:AKT[gYcW^GI73=>BIAH?F;@7968565451413070:/;1;3946577787664616-7+7(4*1+2035220/2-4*<6DBV\huRm;d>f@hGXMGiOBRP<LI5EB-JQ3O_9\sCiLgHeDfHgKkPnUkQhLcI^E\DY}CXvCWoBYqC[sD[sDLE7OG:RI<XL>^P@_RAaUAbWFcYLiacpiztowupqimfjchos|Ћכߦ߲߷ۼ׼ѻ˳Ŭzwplog`\y_Y_Vd]icmhplieb_XSNHC;9/:-<+<+<,>3A;@:@9<48080709-;+<+=,=0=5;89:GJVZSUQPD>7,849=6>4@1>/<-:*8+6,5.41353:2;3<49575665754526/7+7)8'6(4)4-413/3,3*4)A<MOU`\pKj:e=b@`AK]A5SE6JI8DC/>='GM/P]7[nBgMdHbCdEeHiMmRkNhJdHaG_G^G^{F_wF_xE_yD_yDDB6GD9JE<SI=\M>^P>`S>cYKe_Xpjuztwrsphh]_cdiizy͋ߔߝޠڢ֡֠֟ҞΚȕxpg}g_h^VRmUM|SHVMYQibys}x|ok^ZJD6-6(5#8';*;-:09.7,8.9/9/8/:-<*>.@1?3=4:473D@PLNGKBA36$3*/0,5(:(='?#=:!9#8)7.646:5;5<5:575553543406-7)8(9&8&6&6*5-5+5)5(4'EBV\SdPkDh8e<_@X;>95#=<+AB3<=*78!DI+QZ4[jAdyNbH_AaCcDhIlNjKhGfHcIcJcJeJfIdGbDbD<=2?>5B@8LD:VI=XL=[P>aYPfbbmizsokhba__\^ghqr~}ъޏەؕՕҕӔԕЖ˒swatj]a]YOjWKvUFVMVTcapoyv~ytpjTL9-8(8#:&;*:,8.9-9,8,8,8-9.:,:)<,=/<0<2:292@9HAE<C8;/4&1-/4,8*<)=)?%<":#9%9+92:68:6;5<59565564743506,7)8(9&7&6%7'7*8(8'8*9.HIWdMfDgAg>h<Y:Ke67.2$37&8;(AB)KI*bhBy[rYlWeK^@cDhHkLnPlLjHhIfKeKdJeIfIeGeFeF47-791::4E?8OD;SH<VL=_YUgeljhlj_^QQVW[]jly{΁։݋׌ъψ͈Јҋ͍Ȋn~Zjm[[\[LfYHpWDUMSV]afkvu}z^T;-;(;#;&;)9*6+9+;+9*6(8+:-9+8(9+:-:.:/:0:0=3?5=2:.6+1'0//7-:+=+>*>'<$:%:&9.;5=8::6;5;484545648546/7,7)8(8&7%6$8%9&:&;%<-=4JPWlGh7c=gCj;Tk3=G11#/%)2!/4GG(^Y2Zqs`hO]>eEmKoNpQnMkHjKiMgLeJfIfHgHgGgG/4*14-350;94D>8IC;NH=WTTaakbb{dd]]VV`ajmuw݂܆܆ՇΆφЈӊ׋΍ň}~k}yY^k[T^]Jd\Gj[DXKUS[]`gmnzupif]PC9*:'<%;(:*7*4*8*=+:*8(<.A4=/9*9*:+9+9,9,9,;/>2<1;/7041260;.<,<-;/:.:-9.:/:2:697796:6;68666685:66727.8*8)9(9'8&:%;$;%<&@3DAHUMjBg7e=aC]<KO59>11.-*47':A#^e<VrĎvr^hN]>fEpMpOpRlLiGhJhMgLeKfIfHhHiIiI*0&+0)+0+240975?=9EC=PPSZ\i[]x\]\\[Zjky|ᅈ넅もڂҁʂ΃҇׋یύ†~xyhnsWRj[M`_Hb_Fd_C[JWPYZZcdgnj]UK@A37&:'<':)8+5*1(8*>+<*:(A2G;@39+:*:)9)7(7(7(:,</<0;0966;4=1?/=-;093647586:7;7865758597:898787:6;78848/8*9*:):(:'<$=!=$<&D:KMGZBg<g6g=[COm=B3646128+/>=,DN)uQyNJ՚{q\gM]=hFrNqPoRkLfEgIgMfLeKfIfGiIkJkJ,1&,0(+/*02-540::3@@7IKISV\WXkZZz_^ecut茌めւσɅ̈Њύ͊~vumsoc`iZMf\Kc^Ie^Fg^D[GXJWRVZVWVTJE>6:.7&8&:'8)7+5*3)8*>+<*;*@2F:?29*9):)9(8(7(6(6*7,9/;2977<4<0=5@9C?CED@?;;998776758687989:8:7:6:6:88:59/8*:*<*<)<);%;":%9(C?NWG]@c@c@bAQyB@U;605-92,A/+SQ9esGeǃÇk^zK^~D_=gDoLlLjMhHfDgIiNhNgMgJfFjJnMnM.2&-0'+.(.0*01+57.:=0CF?LONRS^XVmcanl~ŒꓐӯljˍΎǎ~wwlxla]e_R^]Gb]Hf]Ih]Gj\Ey[DYCVJRQHG==740+4)7&7&7&6)5+5*5)9*=+=+<+@2D9>18)9):(:(9(7(4(3)2)7/;4:88<4;/::BEJNNVQLGA==882838486888:8<8<7<6;5988;6:08);*=*=*=*;'9#7&5)CEP`G`=_C^I]EGK@1<:+-3%<3&J3'hfFeyԌ|m[Kc9Vq;`=fClIhHdGeEeChIkOjOiOhJfEkKpPpP78+67-56.56.67/:<.>A-EH9LNDQRNWUW`^mjhzxяے剅Ӏ}|~|z~sxkurddl]Rh]Nc]If]Jh^Ln^Ku^JXER@K@D@=:744/2+5(8%9%:%9(7,8*8)9):);,=0B7G>@39(9(:):*9+9,8.7/7093;69889:=<BFIPQNLMGEA>:;692838486788;8=7=7=6;6::8=7;0:*;)<)<)<):&8#;-?7IMSdL`E\LYSVsH@?=*<?(:A'MT5`hCvUgq{ll\XjGDV3Tj9d@gDkHgGcFeGhGjKlPlPlPkMjInNsSsS@>0?>2>=4==3<=2?A.AE*GI2LM:QQ>UTA]\TecgurƑԈz{wws{wz|uyotgkn_Wm\OlYGj[Ih\Ki]Mj^Nu_O_OUFK<@55.3-0+2+4*6'8$;$=$;(9,:+;)9(7&:.=5C<IBA59':(:):+9-;1<4<6;7;8:89786@@HIQQZXOKC=?::7:592938476687;8>7>6=7<7;;9?7=1;+;);';(;(9&6#@4IDOVUhQ`MXUT]O[K939"=D&FO)^vDu_dijjixSIT<CN4<H,Rc8g~CiEjFfFaEfHkKlNlPnQoQnOmMrRvVvVKF7JE8JE:JE9IF9JH6LK4PM9TP?WS@[VB_ZMd^Ynhuyr~w{~uxoqjjekf~kh{keokcck`Yj]Ol\Km\Hk^Ji`Mq^Ny\OZMYKN@C4<05-4-4-5-6,6*7'9';':):,;+<*9'6$9+;1?6C;B6A1?1>1=2<3<6<8:898:8;8;6;4>7A:F>KCE>@9<989878686858585889:8:7;8;9<<:@8=2;,;*;(:':&8&6%D:QOSWU_TZSUZQ`Me\>JY/^n>rMtUv\sWqRiwOblLPX@>D4=E1<F/Qb:gEjGmHiIfIiLlOlMkLnMpNqPsQsTtWtWUM>VM?VM?VN?VN?VO>VP=YQ@\RC^UC`WBaXGbYKh^[mckrgtwj|tgupdmg^d]W[ZVWWURZVM]VGbXGfZFj]Gn_HlbLjdOy_OZOVKRGF::,7,4+6-7/7/7.7,6*8*9):+:,;,<+9'5"7(9-;1<4B7H:E:B9@9>9=;<<9:6898;8<5=2;.9*:,;-<1<5986:6:6:7886949294969788:;;=>;@8>2;,;*;(:&8$7&6'HAYZWXTVWTYR^OcKpnC`x;VqevYc{JO];EM5;=.78-23+7;.;C1Qa<fGkIoJmLjMlPmRlMjGnIqKuPxUuVqWqW\TE]TE^TE^TE^UE]UE]VE_VFaWHbYGd[Fd\He\Jh^Sja\mb`oddmb`k`[e\V_YQYULTRHTPCUO?YRA]UBaYEe]Ge_KebOz`R^TVONJC<7.8,9*9+9-8-8-8+7*8*8*9+:,;,=-9'5 9&<+;-:/=2A5>7;9;::;:;9<7;6:7896:1;,:*9(:*;+<0=5:7897969778694;3;5<8;9;;<<><=7<2;.;*;);(9&8#8&8)G=VRUQTPWQ[SbSiT{VwWxXxZcyKOe<HX9BK6>B29:/78.66.8=/:C1Pb=gImKsNpOmPnPoQnLmHqLuPvTxWpTiQiQcZKd[Ke[Ke[Ke[Ke[Ld[Le[Me[Mf]Lg_Jh_Ih_Hh_Kg^Mg^Mg]Lg]Kf\Ic[H`ZGYTBQN=OK:LH7PL;SP>WUB[ZF]]K__O{`TaYVSJL?>409-=)<*:*:+9+9+8*8*7*9+:+<-=/9'5:$?);*7*8-9/74495;6<6<6;6<5<68647-8&9&9&:(:)</>4<69888677685:4<3=6>9><>>?=@;<38+9*:(:(:(9%7"9&~:*F:RJSJTIXN\SeXn]hsq[ScB=K0'2.5(58167076/8809909>09C0Pc>gKoNwQtRpSpQpOpLoItOxUxWwYlR`J`Jf]Nf]Ng^Ng^Ng^Ng^Ng^Og]Og]Oh_OiaOiaNiaNi`Nh_Oh_Mh`Lh_Jh_If_Id^I^YEYTBRO<LI7KJ8JK9LN<NQ?OSCQUGcVHvWJTLQNGD<;<3<+:)9(9)9*9*9*9)9)9*:*;-</9'69!<$:'8*9.:2:9:?:=:<8966778985819,;(<(=)<(;(;+:/:3;7:7:7;6<6>6@6@8@9=9;9<6<3:.8):););(;(8%|5"9(>/H<SIUJWLYO[S_TdU|mRhwORaA=K46A0/8-8=3@C9=>2:9,99.8:08>/9B/Pb=hKoNwQtQqRpOpMrNtPwV{\tVmQfN`K`Kh_Pi`Qi`Qi`Qi`Qi`Qi`Qi`Qh_PjaRkbTkbTjbSjaRi`PiaNibLibJibHibJhbKd^I`ZFVR>LJ6FH5@E4@G6@H8BI;CJ>LL=UM;SEXONKDF?9:,9)7%8'8)9):):):(:)9):,;/9'6899%8*:0;5>=@E?@>;:66183:5:19-<,>*@+A+?)<'9(6)9/<5=6=7>7?6B8D9C9A9=6838/8*8)8':(<)<)};(z7%w3":+A3J=SGWKZNZQYSYPYMeS<AM+4@('2%/817><AF>KM@DD4=;(:;,7:/8=.8@-Pa<hKoNvPtPqPqMpJuPyV{\}bpVbIaK`L`Li`Qi`Qi`Qi`Qi`Qi`QjaRi`Qi`Qj`TkaWkaXkaYjaVjaSjaRjbPjbPjbPjbOjbOh`Lf^J\WDSP=KK:BF6@F6>F7=F7<G8CG5JH2xQ>YKUMQPIFB=>49+9*9*:+;-;-<-<-<.=1>5</:)<)>)?/@6A9B=B@CC@<>5>3>2>2?3>0=-=,<+=+?,>+=*:*7*9.;2<3<4>4?4@4@4>3<2:1809-:+:*:);*<+|;*x:)w7'w4%<.E7K>QETIWNWRXU^VdVpcHTb:ES37D-AL:KUGKRAKO;CE0<;&::*89/8=/8A.Pb=iLpNwPtPqOqNqMvT{[vZrXjQbJbKaMaMi`Qi`Qi`Qi`Qi`QjaRjaRjaRjaQk`Vk_Zk_]k__k`[kaVkaUkaTkaVkaXlaUlaRlbPkbNc\IZVDON>DF8@E7<C59C35C1:C-?C)kO8ZF\P]YTSJMC?;0:.9+;.<0=1=1>2>2?6@:?7>3A3C3F:HAICIEGCEAA8=/B1F2E2C1B/yA->,:+;,<,=,=,;+8*9,:.;/;0=1?1>0<.9,6*7+7,:,<,<+;*};+{;,w:+s9*u7)v5(?2H;L?OBQHSNUSVWc[o_|sTfvIWf?GV4SaC^kQU^CKQ5CF,:;#9:)88/8=/8B/Qc>iLpNwPtOpNqOrPxX}`rWfNdLbJbLbMbMi`Qi`Qi`Qi`Qi`QjaRkbSkbSkbRkaUlaYlaYlaZlbVlcSlcRlcRlbUlbWlbUmbTlbRlcQg_Na\KWSCMK<GG8AB3<B07B,LE0bG5J<LCQLVTXYZ]OME=A8>4?6A8B9C:C;D<D?DCDAE?F>F>E@EBECFCDAC?@7=0@1D2B2@1?1}>0</;/;/</<.<.;,:+:,:-:-:.;.</;-:+9+8*9+:,:,:,9*}7)|8+z9,v8+r7*t8+v9-C5M>OARERIRNUQYU^RtdPgiI[nCWj@Tf=Rd>Qa?IU7AI0=B-:<+9:-89/8=/8A.N`:d~GnLxQtPpPrRuUtWtZjRaKcJeJcKbKbKi`Qi`Qi`Qi`Qh_PjaRlcTlcTkbSlbUmbWmbVlbUlcRldOldPldPlcSlbVmbVmbUmcUmcTkbShaQ_YIVP@NI9EA1?A,8A'^F4K@E@>@FHNO\^im\\NJICC<D>E?GAHCIEIFHIGKJKLKKJIHEFACBBBAA?@=?7=0?1A2?2<1;2:3;3;2;2~;1|;0z;/z;-z;+{;+{:+9,8,8,8,8*8(9):*;+<,:,8+}6*{3(z5*y6,u5+p4)s9-v=1~G9Q@SDTGSJQMVP[SrZJWX@S_?Oe=XnB`vFRg:CW-=L,6@*8>.:<29;179/8=.8@-L]7_yAlIxQtQpQtUwYqVjScM\GbIgJdJaIaIi`Qi`QjaRjaRjaRkaSkbSkbSkbSkbTlbUlbUlbTlcRlcQlcQldRlcSlcUmbTobTobTobUkaSg`Rc\M^YHXSARM:GG0=A&\F2{L>G@BBEEHIRS\^UTMKHEC?C>C<E>G?GBGFEGDHFHHHGGGFDCAAB@B@A>A=>6;0=0?1>1<2;293:2;1;0;0~;/};.|;-{;-{:-|:-~9.9/8.8.8,9+9,:,:-|;.{9-z8-x6+w5*u5*t5+q4*n3(r9.v?4~I=SFSHSJSLSMZO`QnbKYcEUfCRiATj@Wk@J\5>M+;E+7=+9=/;=38;16:07;-8=+IV5[o@hIvSuUtWtYu[kSbK`J^HbJfKbJ_H_Hi`QjaRjaRkbSlbTkbSjaRjaRjaRkbSkbSkbSkbSkbSkbRlcSlcSlcTlcTncSpbRpbTpaUk`Tf_Rf`QfaPc]J_YCPM4A@%ZG1rM<I@ECDCBCIIONNMLLHGCBB>@9C:E;E@DEBE@EBECEDDDCCAA>B>B>B=A<=69/;/=/=1<3:382:1;/;/;.;.:-~:.|:.|:/|:/|:0{91{90{8/|9/|9.{:.z:.y:/x9/w9/u8.t7-r6+q5+o4*n3)l2'q9/v@6JATLSMQMSMUM]NyeOjjMZnJXnGUmDQf?M_:CQ19C(9>*89,:;0;=38<24;06:-89)GO4Vd>e}ItTvXx\u\r\fPZC]F_IbKeLaJ\G\GiaQiaRjbRjbSkcTjbSjbRjbRjbRjbSkbSkbSkbSkbSkbSlcSlcTlcTlcTmbTobSm`Sk^SlcXmh^ytittttq^_^HZR>UF4^C5hA6n@7u@9{B<E>F?GAFBFDCAA?A=B<C?DCCDBECEDEDDEDDAD?D>D>C=C=?7;2<0=.=/=1;190:/;-;-;-:-:-~:.}:/}:/}:0|:0{91{90z8/z9/z9/y9/x:/w:/v:/u8.s7.r6,p5+o4*m4*k3(i2&o8-u?4IASMTNUPXPZP{]NlaL^aGPaCJ[=DV7DT6DR5AL2>G/;B/9=.8=/8<16;24:369/89+DK2Q^9bzFsTvXz]qXiSbKZC]F`IbJcL_IZ~GZ~GhaQibRibRjcSjdSjcSibRibRibRjbSjbSkbSkbSkbSkbSlcTlcTlcTlcTmbTmaTj^RfZPme]spi}{jZ]K7>+5=*3<(8=,<=/></?;.O?2^B5E=HEEEAE@A><A?DADCDDDDDDEDFDFBF?F>F=E>D>A9=4=0=,>.~>/</9.:-:+:+:+:,:,:.~:/~:0~:0}:0{90z90y8/x9/w9/w90v90u:/t:.s8.q6-p5,n3+m4*k4)h3'e1%l7,s=2H@RNVPYR\R_Ro^M_\HRXBES;<I22?)7B-;E0?H3BJ6>F39A07>/4;.4:249569178,BH0LW3_vCrSwY{^nT`I]FZ~C^FaIaJaK]IX|GX|GhbRibRibRjcSkdSjcSibRibRibRjbSjbSkbSkbSkbSlcTlcTlcTlcTlcSjaSi_Tof]unf¹zlhTSU@;C-:A-9>-;</=90@90D90b>9DBRR`bVUKIEC?>@ABDCDCDCDDCDAE?E>F<D<C<A9@6>1<,=->.<-;-:,:+:,:,:-~:.~:/~:0}:0}:1{:1y:2x90v8/u8.t8.s8.s9/r9.q9-p7-p6.n5-m4,k4+i4*f2'c0%j5+r;1G@TPWP[QvYLgWHXSBJN=BI8:D46?039-4;-5<.8@1;D4;E4:F46A12=.19016236/66,>D.GR1]tDsVtXuYgOZ|DZ}DZ}D]G`K`J`J\IXzHXzHhbRibRibRjcSkcSjcSibRibRibRjbSjbSkbSkbSlcTlcTlcTlcTlcSkbRh`Se]Suoh|ʷ|rnWCJ2<E/5?+8;/:7224/*0+B85Z?>__ljXUIH9:=?@DADBDBCABBAC?D=E;D;B:B9B8?2;,<,=,=,<+;+:+:,}9-}9.}9/}:0}:0}:1|:1z:2w:3u91s8/r7.p6,p7-o8-o8,n7+n7-n6/m5.k4,i4+g3*d1'`.$h3*p8/G@UQYPz\OdVGNO>BH85@12;//5,14.33013..3+19.4>18E5;K86E30>./8/-2/13-54+;A-AM/ZqDsYqWnTaJTu?WyBZ|E]I_L_K_I[}IWwHWwHhcShcSicSicSjcSicSicSicSicSicSjcSkcSlcTlcTmdUmdUmdUlcSlbRjcWid\~¤~pyYX`C@G.>?.<7.<93=<9\TR|lkำ⪤䜖yvUVJJ??@@A@AAAAA@A?B>D<B<A;B;C:?4;/<.=.=-<,;,:-~:-|9.|9/}90|:1|;2|;2{;3w;2t;2q90o8.n7-m7-l7-l8-k8-k8-l7.m70k6.j5-g3+d2)`/%]-"f4*o;2zHAUPsQHaNAOI:>D49A23>03;/38/47156326006.09.1<.5B19H57E45C22<0/4.02*11'9>+AL0\rJwcnZfQ\GSr>UuAXxD[zG^}J_JaKZyITqGTqGhcShcShcShcShcShcShcShcShcSicSjcSkcTlcTmdUmdUmdUmdUmcSlbQlf[ljeͦt{XKO1DC-=6)F?8OHFwqoſ詤qqWV=:?;@<@>@@?@>?@>B=A=@<B<C<?7;1<0=/=.~<,;-:.}:/{9/|90|90|;2{<3{<4z<4u<3p;1n:/k8-j8-i7-i8-h8-h8.h8.j8/k70j7/i6-e3*a0'].#Y+c4*m=4rIAvTN_JAG@3;=..9)0;,1<.4;07:279468648328009--9*2?.6D28F49H65?116,/2',-"6<*@J1]sOzml]^MX{EQo<Tq?VsBYvE\yG_~JbLZvIQjEQjEhdShdShdShdShdShdShdSgdSgdShcSjcSkcTlcUmdUmdUmdUmdTlcSkbQjd[hgeݾr__DOO;?@3YXNspj븴ݘxl`UH?B;<8>;@>A=B=B>C>B=A<>7<2<2=1=0~</~;.:.}:/|9/|90|90{:1{;3y:2x:2s:1m:0k9/j8.i8-h7-g7-g8-g8-g8-h7/j70j7/i7/f5-d3+b3*a3)g<2nE;bE>WFAJ@8<:069-18+29,39-49-59.49/39129/19-/9,.9*0;-3>/6A29E47A26=/26)./#8=,BL6[oQuldXSxEQsAOm<Pn=Qn?UsCZwG^|JbMVqGJ`@J`@gdSgdSgdRgdRgdRgdRgdRgdRfdRhdRicRkcTlcUmdUmdUmdTmdSlcRjaQgc[dddrnWZ\JAJ<lqeſ޲ŁpOAD980=6A<B=B=D?E@B>?;>7<3=3=3=2~<1~;0~:.}:/|9/|90|90{91z92x91v80p80j8/i8/h8/g8.f7,f7-e7-e7-e7,g7.i60i70i70h7/f6.g90h;2kD:nLBSB;88356014,26-37-47,56+47*37)18*/9+09+09*/9*.8*/8+/8,4=/8A2:B2;C26:+01$:?/DM:ZlRoj[{TGj=Jk=Lk<Lj<Li;RoAWuF]{JbNSlECV;CV;heUheUheUheUheUheUheUgeUgeUhdTidTjdVldXmdWneVleTkeRkfWlg]wvsڼqqWejUXcS޸ΗtjQGG==4?7A:D;G=D;B9A7?5?5>5=3<2;1~:0|90z9/y8/y8/x80w80u7/s7.n7/j80i80h80g7/f6.f6.f7.g7.g7.i7/k71k80k:0i<0g>1nJ=uVIrYLn\OOH>15.15-16-16-27-27,36+26+26+06+/6,/6,06,/6,/6,/5,/5,18.3;05>27A34=/29,:C3BM:O_H\rUPiHE`;Id<Mi>Kg<Jf:QmAXtH\xM`}QNeE<M8<M8heVheWheWheWheWheWheWheWheWieWieVjeXkdZmeYneWkfThfQki]nlhٸpsWpwao{j֥j^QE8+<1@6D8H9G8E6D7B7A7?6=4;2:2}92{91x8/w8/u7.t7.s7.q6-o5+m6.j70i70h70g60f5/g6/g6/h70i70k71l71l:0l</jA2gF4u\Jq_xn]nk[LOB)2(-5+17.17.07-17,16*16+05,04-/3-/3-/3-/4./4./3-.1,.3-.5.0:12?43@43@3:G7@M:ES=IX@FW<BU8H^<Mg@Je=Gb9PjBXrJ[uO]xTI^E4D54D5heVheVheWheWheWheWheWheWheWheVheVjeXkd[mdYneXkfThgQoobvvsָ{»۵ˑn]XIC5B4A4A6A8?8>9?9@:|?8y?7x>6w=4v<3u<2s;2r;1p:1o:0m9/l8.m70n71l61k61i60h6/h70g80h91h;2i=4i?5hA4hC2eF3cJ5raLxdpmZ`bQEJ<*2(-4+17-17-17-17,16+05,04,/3-.3-.3-/3-.3-.3-.2,-1,-2,-4--7/.:1/;00<05A29F4;H4>K5=L4<L3BU8I_>H_<H`;QiE[rN[rQ\rTFXC0>20>2heVheVheVheVheVheVheVheVheVheVgeUieXkd[mdZndXkfTghPrtg}~ҷǣtaE4?19.;4<9;::;=<@=xA=pB<qA9q@6q@6q?5p?5o?4m>3j<2i;2h:1m82q62o62m51l60j7/i80g91g<3g>4gB7fF9eH7cJ5aL5_M5ofOihlXQYF>E7*1(-4*07,17-17-17-06,05,/3,.3--2-.3-.3-.3--2,-1,,0+,2,,3,+4-)4-+6--8-0;-2>-2>,2>*4A,6C.=M5DV;FZ<H]=SgH^qR\oSZlSCRA,8.,8.heVheVheVheVheVheVifWifWifWieVieVjdYld\meZnfYkgUhiQnrdu{wӿԯƍxo\RAH:>4;383:4<5w?6pB8q@7r?7r?7r?7r@7q@8o?6m>5l=4k<4n:3q83o83m82j91g:1e;1c<2_<1\=0]D4^K9_N9`Q9_S:^U:jhNw{c\dNBM98@2.4,06,18-28.28.28-17-06,/4,.3-.3-.3-.3--2,-2,,1++0*+1+,2,+3,*4,+5,,6-.8-0:-2<.5?06A08C1:G2<J4?O6CT9P`F]mSYiRVeQAM?,6.,6.heVheVheVheVheVifWifWifWifWjfWjeVkdYlc\me[ngZkhVhiQjoalupԼΠkSUA?.;,6*7+8,w=0oA3q?5r=7s>8s?9s@:sA;q@:o?8o>7n=6p;5q94o:4l:3h<3d=2a>2^>2W=/P;+SF2UP9YT;]X=][>]]?fjNnv\P[D2@+2<-27/28/28.39/39/39.28-17-/5,/4-.3-.3-.3--2,,1++0**/)+0*+0++2++3++4,*4,,5,-5,2;17@58B59C46A03>,9D0>J4MYD\hTWcRQ]O>I>+4-+4-heVheVheVheVifWifWifWifWifWjfWjeVldYmc\me[mhZjiVgkRipajvpϾڵ˛mkXVDK9|@/s>-j<+k:-l80m:2o<5o>6p@8n?7l?6l>5k>4k=5j=6h>5f?4bA4_B4`H8bN=VG5KA-IE/GJ0LM2QQ4\\>ggIfiMekRLT=2=)3;.5:25:15;15;15<25;15;04:0491381372271271160/4..3-,1+,1+,1++1**1**1**1++2,-3,06/3927>5;D9:D58D28D08E.CP;O\HMYIKWJ<G<-7/-7/gdUheVheVifWifWifWifWifWifWjfWjeVldYnc\mf[lhZijWflSgrahwoìu]_GyH1o?*e6"e5&e3)h6-j90k<2l?4k?4i>4i>3h>2f@5cA7aC6_D5\F5YG5_R>e]GUR;EF/?E+9C'?F)EI+[]?ppRfhM\`GGM729'5;.7=57=47=37>47>48>48>38=48<58<67;67;66;549327105/.3--2,,1+*0*(.().)*.*+0+,1,.2./2/6;6=D==G;=J87E01?(:H2BP<DP@EPD:E:/90/90fdTgdUheVhfVigWifWifWifWifWjfWkeVldYnd\mf[lhZijVelSfqafwo۽ӻ˺кĬuoxh_OiF6fD3bB0cC2cE3cE3bE3_G6]H9ZI7XI6VJ6SK7ZW@bbIRV<CI0?G,;D)AG*FJ+Y[=mlNedJ^]FMN:<@.:?29>59>59>48>48>48>49?49>59>79>89>99=88=77<66<65:4483372261/4/,2-,1,+0++0,,0-,0.,0/0613<36C4:J57H15F.9I2=M7?M:@N>8D7/://:/ddSfdTgdUhfVhgWifWieWifWhfWjfWkeVmeYnd\mf[lhZhjVdkRdqadwoҶɵƿ˸ѽqhS;`L4XD,[H/]K2]L3\L4YN7VO:TO9QN7OO8MO8V[B^gKOZ>@L0?I-=E*BH+GJ+XY;igJe`G`YDSP=FF5@C5:?5:?5:>59>58>49?59?59@79@8:A:;A;;@::>9:?::@::?99=88<77;6494062.4/,1,,0-+/.*..)-.)0,)3)0?.6J28K39L39K28I1:J5;K85C3/;./;.ddSfdTgdUhfVhgWifWieWifWhfWjfWkeVmeYnd\mf[lhZhjVdkRdqadwoҶɵƿ˸ѽqhS;`L4XD,[H/]K2]L3\L4YN7VO:TO9QN7OO8MO8V[B^gKOZ>@L0?I-=E*BH+GJ+XY;igJe`G`YDSP=FF5@C5:?5:?5:>59>58>49?59?59@79@8:A:;A;;@::>9:?::@::?99=88<77;6494062.4/,1,,0-+/.*..)-.)0,)3)0?.6J28K39L39K28I1:J5;K85C3/;./;.\gO^hQ_iRcjUgkWhjXihXkgXlfXlgYlgYlgZkf[jgZhgYgjYelYq{p|ͺɿɾͫmgK`Y<RK-TM0UO2TO3SO3RO4PN4NO5LO6JO6HO5GO2EN.IQ/LS0U\8]e@_eCaeF\^BVV=WU=WT<VS;UR9QN8MI6HF6CB5@A5<?5:@58A58B58C59B69A79A79A6:B7:B7;C8;C8<D:<E<<E;;E::C89@57?65=66A36D/?R2G`5Ga9Gb<AX::M8=P9@R:DW>H\A>O94B14B1\gO^hQ_iRcjUgkWhjXihXkgXlfXlgYlgYlgZkf[jgZhgYgjYelYq{p|ͺɿɾͫmgK`Y<RK-TM0UO2TO3SO3RO4PN4NO5LO6JO6HO5GO2EN.IQ/LS0U\8]e@_eCaeF\^BVV=WU=WT<VS;UR9QN8MI6HF6CB5@A5<?5:@58A58B58C59B69A79A79A6:B7:B7;C8;C8<D:<E<<E;;E::C89@57?65=66A36D/?R2G`5Ga9Gb<AX::M8=P9@R:DW>H\A>O94B14B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/MatteFloodfill.miff b/PerlMagick/t/reference/filter/MatteFloodfill.miff
new file mode 100644
index 0000000..f0e355c
--- /dev/null
+++ b/PerlMagick/t/reference/filter/MatteFloodfill.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=True
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nndun10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:darnmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Uj|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLSozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮ʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdme~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxv|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzzydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iipg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S||CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQljeKO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾ
diff --git a/PerlMagick/t/reference/filter/Minify.miff b/PerlMagick/t/reference/filter/Minify.miff
new file mode 100644
index 0000000..4c582c7
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Minify.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=35 rows=23 depth=8
+page=35x23+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-41.82-91-80-7/,5-*4-*2.(52+=8/G?2MA2hC3B5D@@D><?0@,?,=,>-A3C6O9272041-0/-8./hABib]fdr{}u.--0/-4/+4.+4.,4-,3-+3-+3/+41,:5.B:/H=0ZA3?0C:A@?9?.?,>,=,>/B6LBL?873/12./1.3/.Q96|ga_SQfcic,./-../-+.+*-*+-*+-*+/,,0-+1-+61.<3/A5/H:3d8/>2C8B5>-=-<+<.B7SI{j[cS9;1/.+/.-0..:52rvzxtu12/22/53/50.1../+./*,0.+1/-6/,=4.>5/>2/A3/I2,k8.>4@4>/<-<.@4LAo_pnQbL76/.)).*-74/jwY{vq681994?<8B<8@:5>62<4084/950B90J=2E:1A81`:9q;6=3?6@6>7=4A<PC]J[WeerknhOSv;AM41QI:p~]znsp550883A?9HE;LG=OGDF>8>71=80F>1L>0D:0M<3?9=0=/>1>194738/K=SKAB=D>QBbFpNoR\~sС75064/<:2KE8\XXvtVRdB>CC>4JEARGIw?8=-;*:/;1;14,0(5$?3E></B;FKG]KrRtZlӓID8C>4?90JA5_W[ԪonlO]O[R_B==.:/808/:-6/1.5,<1E>=0@4F>RWXo]seozuXN?TK<ND7NF7[SP閛ޣRcADA>>;>29-6/5+6,7-5-4/9,B=B:<-=.NEejirntp[M=ZM=YK<YL<\PDibv{vN_@B@?>7?7=,8)3..0+84;64:3<481<1?49.C9jlny[geȭ\K9\K9\K:]L;^O?bRQznsJR?A>5<1>5@37015)32EES:;<4C>;0:0<63091igk|LZztOzd}il^M;^N<^N<^PAg_iqlf^CD<4E:=2;071;>?CBI=CILMLB><768620/4._^[tEOhtKv^v^z]{cVJ;\O?aTEh`knpɷƿv_[NJF<@4=56.;3IJPU;@BL>C8495655,2.50PWKfDBT`=iMmQkN`G>=2JD9_WTgeno՚ԕtfj^UkhQF:*:.:.;-<4B;55-;+95685637)7(<4G\=SP@2cnHjNiJgJcH04)77/LLKbb~~΄φ|rj_RYJSOB68(9*>0;,8+917;;A89778985:+;'BAEZo>=[aBhiNiHhKiKJF8JF9RN>c^\yrsmlfrj_Tu]MM@:07*9)9)=0=2:496=7B<:8869:;7;+<,LLXQejDfwLWcFUi=jJlLpPd[Ld[Le\Mh_Pj`Sf^NWSBOO>lSEIA;/9+:,:);,=8;9:3;+;-:5<5<5;0:(>.RIbR^eECL7:=/Rd=pOrQoRi`Qi`QjaSkaVkbSlbRb[KKK:[G6NHJE@6A9B<C<B=?4=1<.;,:/;/:-8+w8*C6SJ~_NUa?DN5:=.Pa<qPpSfMiaQjbRjbSkbSlcSmbTxpfwrbQvE;E@GDECDEDBB<>2;/:.~:.|9/|8.x9.r6,m5*G>WL]XCDR6<E06;0IU7mQeM_IhcRicSicSkcSlcTrkaŲhkTSMCᄁNLB?B<?4<.:-|:0w:1o8.l8-k6-f4*oD;VI=:?239/4?04</BL5bOYzD\{HhdUhdUhdTjdVleWᨨ஧aYD;@7=3z:1v90o80i7/g8/h;0kJ<RG<48-27,06-/7-2;/<G6MdCMh>UnGheVheVheVkeXli[ʂtNB{?5q=4o=4l:3h;2_?2]J5c^GBH928.17./4.-2,,3,09.8D3CS:L\FeeTgfVifWkeYjk\ؿfVdE4_F5YK8PO6MQ4Z[AAE59>37=47<54:3060.4.3=2:J4>M: \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Modulate.miff b/PerlMagick/t/reference/filter/Modulate.miff
new file mode 100644
index 0000000..c5e9456
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Modulate.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:     "##&%$($#(%$)&%,-.849G:AQAIZEUjEWrCXuCWrBNb9@R7=O6<M38I15D15C04B/4B/3B16D49F9?P<CT6:F$$* ! &(+7;BGNRR\RRXL4:3262IIH[XZFDG334  "#"%#"&"!&#"'%$)*+4/3@4:J>FUEThDWpBZyCXvAL_7=N6<N5;M38H05D05B/4A/3A/3A04B49F;CS@HZ6:F $!!!!"#%.1:BGLU_SRYJ07/,1,;<:OMN?=@334  "" $"!&%#&'&,()4+/<6:I@HXDQgCWuCTo:@R38I5;K4:J26F.2A/3A/3@/3@/3?/3?48G?GXCL[;>F$"$ ! #57:_jY[hO5>2&-&%'#(('0./324 ! "#""&%%(&&+')/+/916C6<J>EUDQhDPf5;K26F38G38G15C.2@-1>.1>.2>/3=25@8<I@HVJO[OMQ:78%$&<<=kwadrVOTJ<>:A@=VRRRNO858 !" ! " !#""$##%#$((+2/4@49E49F:AP>FU5;H04B04C16D/4A.1>,0=,/<-0;04=59B8=HDKUSQZbY\JGH2/2#!$=8=_\[_\Ywfguefh[^k_e[TW726! " ! "!   "'(*2/2=15B05B38F37D16C/3?/3?04@-1=+.9),7-1;36A7:C>CKKJQaX]bX[TNPC=@4/2!!#4.5YOY\PZq[ko^iaT[aU[OJM2.1!!  #! $! #!! ! !$!%)"$!#((+316?05?/3=14?03@-1=-1>,0=)+7*-7*-6.1;59B7;D>?FQKO`SUcVYWOQNFIJCF956" !2/3OHNSJQXMTYMUZOUYQULGJ0-/   ! !"!#$#%$$&""$!!#!!# !"   !!!#!!$#"&$$($#'!!$!!#!!#!!""#% !# #&)038A8=F37@15?/3=-0;,/9+-7*-8DKYEKU./80/765<@=DJP]QWfYU\ZRYTMTWOTQJM948! #*(-=8=E=DLBIQGMQHLUMPSLOICF0-0! !! "$#$%$&%%'&&(&%'%%'%%'##&"!%""%""% !  !!!$#"'%$)&%*$$(""%!!$"!#""&8>E<BK37@@GR8=K7=K8>M5:I7=M<EP;BL/2:.2:@KWEUkFO_22:828??JI\t>[s>\sC_xG`wK_tN_rP_oL\kJ\jFT^;BI!#(!" %/,4F?FH@GH?GMEKVOS]XZVQSE?B404  ##$%%&'')'')'')'')&&*#"'!!&"!%"!%!!$ " !"!%##($#)$$)##(!!$! "" "48?G^u?JZ.3D=EV7>M9AQ<CS28I:BSAK^BVoCRhCNbBTl=I]@HY=?J99ELZrBYuDSjE\x?[u?[u@_v@axBezBgzCi}DiHmJWc(*1#!&CBG^[]]ZY_\]jilwv~z~jjjEAC837 !""#&%&(')(')'%)&%(,--&%( $ $ #!!# "!!#$$%%$(#")"!&##("#%" !! #<BN6=M/5G26I27I17G7>L7=M8?O<DU;DX?Mf?Sp>Ol=H`:D[;DWDL^HWoC]|CSh6=N@HYDWpC\zC_{B`{Ce{CgyDj|Fg|HlHoK[hCDJssxx~~{~SQRIFI !#"$'&((&+'$)445X\SRXP9=8),) !! !##"'$#) # #29A7>N27H05G7>P=FX:BR5;L6=O<EW:CU>I]?Ja?Ol>Nj9BY;E\>G\@J]DQgCQg>FX4;L6=NCOcEZwD[yDa}Dd|EkEnFlGkDavTj~>?Gouwxzyxqosojn !! "%$()(.)(->A>t`~Zt^dp\KNH/2/*+)###"" $%#$+,(44//.-,,259E4:K6<M5;M8AS?I]@J^?I[?J^?K`ANf>Lg>Ol>Qo>Lg9BY9AX;EZBNdGSl;BS39M7>Q?HYEPcESgEYsGbEbzEhGlIkHiHeJiFVgcnzy|xx~|$#&""$  $$'(',((-7;7n\Z^_ua\jUHQE8=6%&$"""./0MUNUa[JX^EQ`5;N17I6=O:BU?J^@Me?LaBQjBPi?KaBOhAQq>Sq?Sq?Ld:DY:BW<EZ>H\FUnCNa5<P8@S=FXFPeAJZFTlHZsI`zHhFhHlHiHgHeGSbLOWvyx~}wvxw)(+('*$#& # "$#%&%)%#*022ckX}[|\|\y]s]hz[YaOFIB:ADGTbG_vFViBN`CTl?I\:AS=EX@J_?J`>J_?K`?Kb=H^:DY8@V?JaAXy@Uq?La@OeARm>Kc?I`FUnETh?I\:BU9AS<CU9@SAI[FPbK^vKkGhIjPhLfSiFFN-+/r|zzyxx~uy,+/++/)'+%$(""&%$&&%)%#*022aiWu\vX~Xz_w_XvbR`dDUhCVqBPi>FYAK_CVpBQgAK\@HZ7?Q;EW@Mb?Kb>Ia9CY6>S8AU;EY=H]?Le@Pi?Ri?So>Kc9BWDOfFThGUl<EW8@T6>Q7>P8?P;CTJWqNeMgMfQdNiOsUPT*%*qwzytxuqw-,1-,1,+0)(-((-((+)',('-233X^Tkz^n]u]o|^guZ_jXOdgCXlBPhCUlCTi@IXEReCUmBNc<EW;CU8?Q=FZ@Og?Mc?Me<FZ8?R?HYBRl9AV6=S:DY>J]<FZ9AV:BWALcDUnI[wCOf:BV7>P6=N6=M5<MENcNbM`yLeNgKgIhKFJ928|vxo{xuzu{,+1,+0,+0+*/+*0++/+*/*)/..0>B>QVN\gVbrYZcTQWJ:@BBSe@ZwCSnEZrDSg;BR@IZ?J\>FX8?R6>R7>S<F[>Le@Tq?Vu?Ur@Tn>Xq>Sm<FZ;DX@NgAOj@I]7?S:DWAPg?Of=H\<EYCMb:AR4;K4:K28I@GVPePlOkNlHeDbzXRYRHPsjyswhph[ciXbsan~owxtw++0++0++0**/+*/,+1,+1,+1-,1/02586JRH\lVUcWO\X?IT;CWBQkBYyDWo>FV28I@HYAOeAK^5<P9AU9BW=G]?Nk=Jb=Lg>Pl=Tn:Ul>SkCWo@Tk@Xv?RmAOeFWp@MaANd=G\8@T:BUEQi>GY>HZ?I\9AT7?OOa{QqPnMnFeCaxFAHF<DF@GB:@J@FUJRbQ\dS__T^hfqlou**0**0*)/))/**0++1++1,+1,+1,+1014;A;PVNYglLi@]xDUkCNaDXsCQf7>O17H@I\BTmEToDMd8AT<FZ@Nf@Qk@Un?Wr?Vn?Wl?^rGc~IhBYn?L^5=P@H[HVoCPd=FY7?S27I4;LDOc@Md@Rn@Ts@Ng7@RJVlRpPnMmEc}C]t0*1B9AJDKUKR\NW[NY^O[bP\[OXf`irsu*)/)(/)(/*)0+*0++1,,1,+1,+1,+2-.4<@<]dUXecOdE`D\tCVlBPe>GY4:K8?P?J]>Ja=G^DRo?I]>H\BSm@Wr=To<Tp=Qk=RhB^uJiG\x?IZ06F&*:7>N>HWEQf=FX;CW7>O;DUDPh?Md?Us?Tr?Ok9BVCL\TqOqHkCd|CSa-&-MCKYMW[OXVJSUJSYLU[KW^NZfYd`\^+*1+*1+*1+*1+*1*)1+*1,+/788=???A?UZNmV[rXR[dKZwF`BWqAPe<DW4;K@GW@HY;EX=H`?MeAMf?Ja@SmD^~DZw?Nf=Kb@NcCShCReAOd<GXFQeGUgDO_I[uDQfALaANe@VoBWrBRl>J`@Ro?Tq@Rn9CX>EUTsNoDfBd{:BK3,2MCKTHQRGOQFOTIQVISUFR]LZ\PZHCF-,2--2-,2-,2-,2+*1**0898TYQXbTYbPalUhsajond_sEGWBJ\FYuBRk?J_9BS@GVJRf<DV>J_?Me@Le>Jc>OjASoH^zFZrH\uI^xCPcBUl?RiF]wMlKkHWr@L`BOfBOf?Md?WsAZxAPi>J`@Ql?Us?Ro<F[9APRrKjCd|Dau&'.2,1LCKRHPMBKOCLQFOSFPSDPXIUTJRB<A,+0.-2..3/.4.-3.-2899QVN[dRS]KbuUqg|j}\|cc\iHITOZpI`ASk@Ma;CTAGWFOe;EYCSlAOg=I`>Lf>I_@J\I]xIb~KiKe@Up>TmE^yJdH`~@NdAPh@Mc?J^AOhCSkAQj>I^>Jc?Qn@Us@Sp?J`:CSOnGjBd{DQ\ '"'C;BLAKI<FL?IODMOBMK>ID8B4+31)0('-+*/..30/5.-3:;;RXPYaQQYH[eOo_~nzvnstQPP??AGJQSb|KdDWuAMd<DV=EX=G[EUmETl?Md@Me;DX6=Q?IZAN_Jc~J^w@NeDZwDWoBRiAUs@Qm@Ql?Ld@MdAQjBSlAQj>J`=Ia?OjATp@Ro>I_CObLjBdzCf|7:A+)-" $1*1E:CF8DH<FL@JH<FC7A?4=918;3:$#&('),,1.,288:MQLRZNKRFVaNg~Ynam~cj}aev_]lZBFB44668?ELZQbPiJ]{<EX6=Q;CX?I^=FZ?Ka?Ka:BV<DV>FX<FVGTiDNb9BW@Qj>Vo>Xq<Wp=Wq@TnANeANeAQkASm@Nf=H_=G^=Ic?Ok>Mi<G\I^xFhAdyCS_$"$-'.@8?A5?E8CI=GF9DD9BB8AA7@@5?! "((++*.>?>JOHAG=LTF`pTh}Zev[brY`tW_oYXaU>CD31422:HUfNazTfOg;CV5<P:BV=H]<DY:CX>H]:BV;DV<EX=FY?I\<EX<G\@Vr?Yt?Wq=Wq>WrAUoAMb@MeARkATo?Md=G\<F]<F]<E\;DZ@K`HhAdyDf|*04+'/cVcKCJ@4>I<GK?IG:FF;EC9BB8AD8C!!!'&(;<9DH@HPDbuTkWeyWboWctXbzW^lYLOL8:>3052/5DIUK`yNbCNe9BV9AV=H]<G[:BV8?SBMe<EY:CW:BV;DY?I_?J`ATn@Xs?TkARjAUrBUoAOfANcBQhBToAVsAOf<EZ;DX:CX6<S7?SGYrCf}Aey=GO & 'cSd|`xKBJ@4>L>JK?ID8CF;DE:CD8CH;F! "/..:=8OUKkZmWasWanXfu\]jXMSM;;>2/432731878CHYrCTn>K`=G^;EZ>Kc:CW8@S:BVBMc9AT9AU:CW;EY=H]AOiBUp@SjEXrHZxCSn@Ne@NeBQhBSkBTnATnANd8@S7>Q7>Q39L6>PFdCbzETa$#(%PGPx[r^S\3+1>2>I<GF9CC6AH=FI=FF9DM@K" #"!#" "#$)'*-+/<=<[eVex[W`RRYOT[QFIG99=32943865:9:B:?M>J_>Ld>Kc;D[8@V>H^7>Q5<O@LaDSn5<N7>Q;DW@K`APhBRlAQkFZxJ[vBL^ANc@MdAOgASkBUmATlBTmALa7>P28I28H-2BBKZHfGVf:;C&!'QFNVKWSJS-)-% %?5?H:FE8BF;EI>GL?IL>IRDP+*.++/,+/+*..-20.3326>??CGD?A@5762230/321653:75:;=F@ER6=M;EX?Ld?Kb=H]<F[>G]7?Q06H:CU@K`AK`AL`ANbCSlATnBQi=EW7>P9AS@L`ATmASjAQi@NgAQiBRkCSk@I[4:J04D,0?+/<JUfGP\AEO98B;0;`PaNCL1+1!!$!$@6@J=II=GK?HI;GM>KTEQPCM326327327437438428428548438327104*),'%)+*-0.2436BEMFRd?J]6=P;DY>H_=G\=G\=G\:AS+0A49K9AT>H[ASjASjATmAUn@L`3:K28I6=O@K`BSnATpAQl@NhBPgCQeAJ[4;K/3C-1?(+9+.:@EP<?I>AIDENXNX4/4    $!$B9BN@MMAKL?JK=ISDPSFQF:C65976:76:76:65987;87;65:6494285381/4'%)&#&(%(*()*).EKXEXs;DW7@T<F[<EZ;DZ<E[:BS*.?+/@8@R@MbDWqBM`:CS;DS4:I16F27G27I6>P@K^BRmAPlBNf@J[9BP06D-1?,/<*-9&)614@;>I=@I@DL;=F'!'$#"+)+  ""B9BN@MM@KM>KRDPWITF:CE:B76:76:76:76;76:::=<<>88<87;99<77;65:/-1&%'%#%$!#"#;=IKZuFZv>H[;DW>GZ?H]?I^AK]9@P;ARDPgEUqCNa4:H14B/2>+-9-0=.2?/3@05C4:I:AR;CU8?Q29H/5A-0=+.:+.9)+6(,66:E7:E?CLBHODDM=5=,&,;6:*&+ $ #C9BN@MM?KPAMWHTH<EE:CE;C76:76:65987<87;99=98<75;76;98<98<98<75:,+/#"%!"58AAJXGUiMfFTkBL`CNbDPfESjFWnGVmFVpDWqDTlBL]4:H04@/3>/3=.2<.1;,/9*-9+.9-2>/4A/4B-1>,/;+/;)-8+.8(+4,/857A8;D>CL>@H.+04-3=4<+$+""" "  ""=3<NAMOALTFQL@IB7@G;EC8A76:76;87<76;76;87;87;86;87<87<88=99>6596590.3!/09;AK>FRFO]FQbDPbAK^AJ\ERfDTiETkETkCRjCRjAL^39G-1</3=05@.2>-1<,0;,/:,0:-1:,0:,0:,/9,/9+.7),5(+4&)2.19:=E=BJ=AJ98@:499171+1"#"!#!!4-4L@KSFQODLA5>D9AG;DA7>75:76:87;76:76:87;87;87;87<87<88<559BAC^]`fejEDG!!  !" "()0>DOCQcBOdDRhESiESiERgCNcBMbCOd9AP-0=-0;.2>-0=,/;,/;-0;-1;-0:,/9+/8,/8*-7)-6(+4&)2$&/,.7>BJ>BJ;<C204-(,! %!%(%(# #! ! ,&-L@JTGRB8@?5=C8AD9A?6=76:76:87;76:76:87;87;87<87<86;669LLN~}|tzSQY'#'"! !+-0WaqITfBPfDTjDShDRhCOcAK_BNe>FV/3@,/;,/;,/;,/:-0;-1;-1;-19*.7),5),5(+4)-5(+3&)1"%-*-6?CL89@+),#!"" ")&'" (#(MBKMAJ;19?5=B9@B8@>5;86:86:86:86:86:87;87<98<98<76;>>?vuqztp\S]($) ,,.\\^pwR_r?HWAK\CPcCPcBNbBOd@IX27C-1<,/:-0;,0:-1:.1;.2;+-6(+3(*2'*2(*2),4(*2$&.!)+.579>$#&! ! !!!! %"$'$&'#'TKQD:A8/6;29>5<C9A81686:76976976975976:98<98<87<76:<<<mmf}xx|{syo<:?)')XWYywad=CQ9AQAL^BL^CNa=ES27B/3=.1;,0;,0:-1:-1:,/8)+3(+2')1')1&(1),3),3'*1),3129 !$!#%"$*'*LGJ6.36.45-3<4:C:A.),97;98;98;98;98;98;::=:9=85:@@Afgbytzm>:?FCE{xxyzzy|JP_6=N>GX@HZ8>M26@04=/3=.2;,/9+.7*-7(+4),3)+3(+2(+2),3*-4)+4**3A@G<;>#!!$!"*')0+/-(,6/42+0<5:@:>%#$97;97;97;97;97;87:::=:9=859LLL~{ywnebiyw{zzw\]q7;J:BS<ES7=G27>/28-/7,/7,.6*,4)+3+/7*.5)+3)+2*,3,-4*)2*)0FDH1.1"!! $ #.)-1+0=8<<7:97;97;97;98;98;98;;;=;:>86:DCCtzz~vuxuxzxxxqlFHX38G/4A,0;+-6-18.19/29-07,/6,07+-5)*2'(/""(*(-.+1/,2A=A"!   $"#%"$!!($':7952487:97;98;98;98;98;;;>;:=;7<DBB{{pyzuzq{rwzyxzxzsjhFFR-.9"$/%(0),3+-5*,4)+3*,2))0('.316$!%""$ &;8=304#!"#!"#!##!##!""!""!" '&')%(! ,(+-+, 75887:98;98;98;98<;;>;:=:6;CA@szyuyxm~nlvyxzywxzz{wsif{.-5%$,('/)(/*).)&+)&+838(#(#$$ &6380/4%#&$"$#"##!#$"#%#$&%%$#$%$$$##"!"'#%($''"%)&'!949:6:;8<:8;:9=;9=;:=:9;=9=PNMv}}tmjwnnxxyyxyzzzytu74:&#)(%,(%+(%*)&*)%*'"()$*4.5516-*.,*/+(-'%)$#%$"$$"$%#$%#$%#$%#%&$%(&''%&$"$#!"$!#1)/3,1*&(,(+2-0$!# \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/MotionBlur.miff b/PerlMagick/t/reference/filter/MotionBlur.miff
new file mode 100644
index 0000000..06a9559
--- /dev/null
+++ b/PerlMagick/t/reference/filter/MotionBlur.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+
+:60-71-70,70,70,7/+6/+6/+6/+6/*70*80+91+<3+?5,C7-I9/P;0Y=2b?3l@4vA5A6A6A7A8A9A:@;@:?9?6>3>0?.?-?-?->-=.=.=/<0<1|<2r<3c:3U83G63>53?55A78D:=G<AJ>DPBIZHQfPZoXds`qsdwmcvgctfeohgigfdfe`ca\\ZUYVS50,60,70,7/,7/+6/+6/+6/+6/+6/+70+81+:2+<4,?5-C7.H9/P;0X=2a>3k?3u@4A5A6A6A6A7@9@:@:?9?6>2>0?.>,>,>->-=.=.</<0<1~<2t;4d93T84E63=53?66A88C:=F=AJ?EOBJXHQdOXkV`o^mobtjaudata_mb_d`_^__[_^Y[YTYVS3/,4.+4.+4.*4.*4-*4-*4-*4-*4.*6/+71+92,<4-?5.C7/H80O:0W;1_;1h<1r=3|?4@5@5@5@6@6@6@7@7?4>0?.?,>,>->->-=-</<0<1<2=4r>7a<7R;8C86<53>65@88B<=E>BI@EMCJTHN[LR_R[c[kf_ue_ya^yXVkRPZONQPPNTTOWWPYWQ1-,1-*2-*1,*1,*1,*1,*1-*2-*3.+4/,60-82-:3.=4.A5.G6/M7/T80[91e:2n<3w=4=5=5=5=5>4>4?4A4A2A0@/>->-=-=-=.<.<0=1>3>6zC<oICaJDUICHD>><7=85>97A;=D=AG?CJBFMELOIRWS_a_tec~ggde|[_n[ae`fbbh`bg]^aV[]Q0-,0-+/,+/+*.+*.+*.+*/,*0-+1-+2.,4/,60-92-<2-?2-C3-J4/Q60X82a93i93p94x94:4;4<3=3?2@2A2@0@0?.=-=,<-<-<.;.<1>5}@9{E?uQInZPc[QWYMKOEBC<?;6?87@9:B:=C;?D>DGBLMIVWVb``odirluurzw}|~vtkxefo]^fTZ_N/.+0-+0-+0,+0,*/,*/,+.,+/,,0,,1-,3.,5/,70,:0,=1,C2-J4.P6/V60\61b62i72o82u81|90;0<0>/?/?0>.=-=.<.<.<.<.</<1~?6|C;{JCxWNqdWkj\ajZWdTNYKGLACA;A:8>69=6<>8AB=HHBQLJVTVZ]c^hud{t|w{sqiet\`kVYbOU]J2/,2/,3/,3/,2.,1-,0-,0,-0,-1,-2-,4.,5/,70,:1-?3.D4.K5/P6/T70X71]61c60j60p50s6/w7.{:.:.;/<0<1=0>/=.<-<-</>1{@6|F={NExYNrfWko\dt^]s]WmXScQMXIGMABC==<=;8>=8C@>HCEKGKKU^Tgtarizozotipei}``qW[hRV`LRZH53/53/6206206206105005//5/.5/-5/,60-71.:3.?4/C60H70L81P91S81V81Z81`61d61c80e9/j9.p9-x:/;1=3?4>3=0</=/~<0@6H?NEXMx`QmhSnmWtoZvo\tl[mlZckXZdSQYKLPGGIEAAB>>>@A?IJCX[MhoYp`qcoclajag`bx[\mTXfOS_IQZF852963:63:64:64;63;52;40;4/;4/;4/;4/<5/?5/B6/E80J:0M:1P:1S91V81W71X91b:3m<4w=5?8@8A7A6@2>0>1>3>5>7A<JERLYNcQwlU|kVbUZUUTOQOQRRPRLP~KQ|LSwLRqLMiPJe\KfkPjwVl~Xn\m_kakdj~dew__mWXeOS_IQ\F973;85=96>97?:6@94@92@80@8/?7/?7/?7/@7/A8/D9/G:/K;0M;0P90Q90P:1P:0^;3y?:>9>9@9=2>0>2=/=1>3=4?8CAGEMEUI^KdNdU]TVQQPKLHLDM>L<N<R@WEYKYW[bZiVwrWq|]rfzr{{tmue_jVUbKS`H:84<95>;6A=6C>5C>4C=4C<4B;3B:2A80A8/A8/C90E:2G;2J;2L;1L:0L:/O;1\<4w?9?8=2>0<-<+=-<.=1>3>4?9@:A:E;M<UAXGWLRNNMLJHGDEAE@J>N?T?XCZM_Yd`cf`qeu{smwecnZamX:73<94?<5C?4D@3GB8LHDPLLRLRQKRJCGD;:A82@8/B9/F:/I;/I;.K:/P;1\;3v;7:4:/<.=,<,<.<0=1=2<4=5=6=5B5I8J:K>JAGBHEFCB?@>>@?E@KARAVF[PcVe\gbjoo|v{{<92>:1A<2E?4HB8PJF\W^b^ofc|ifc_uZUbPKRJBBF=7E<3F<1H=4PA<_BAqB@B;A3?.>,<-</;0:0:3;5;5;3=2@3@3@5A7@8B;D?D>D>A<><?CAIBNFUK[P`Tf[kbopx|ʄ֜ٱտ¿@<1A<2D>5JC<QIGYQYc^qjhrqxyvuokf`y[SgOHTHAGK?C[EJrMUPXPUJFA7=/;+:.;0:2:394:4=4>2>2>4<492;4=5?7A:?9?:@??ABEDJIQNWO[Vd\jftn{v烎⍔ڞְм¹÷÷ķɻʼF@6IB;LEBQKKWPV]Xfhf{rqyy}xtplccZZsbUj{TeR_MSFFA;>4<1<1<1<19181928/8-:-:-:0:294:5<7;5;4?9@<A?ACADCEFHIMMRSY_gfrm{x쀋鐗ךǡDzýPHARJFTMNWRV]X_c`lnnyw}{|uxuwsiZhIM?:=3=3<3=5=6;391817/6-8,7)7)8,7.80:283738495=9?<BADEEEECECIHMNWYafkrw~탈芎ᗘΠǶżXOKYQQ\UW_Z]e`gjgxtqzw~}~}u`{N^CG=9>7>:=:>9>7<3909/9.8-6+6*7,7.80:1:18/7.8/:1<4?8A=DADBFCHEGDJHONWVeepqz|円≋ݐ˛ͻ\SO_WUc\]g`gkdqnh}rntrvvz|~wgRjDO?>>=>=?<?==8<3:09.:,8*6)5)5-4.303433313/5.90=2?5?7>8=9>:>9@<E@HDMIQLXTecsr}刋≌܌НΫŸ۾_UQcYXg^bkakmesngyoiolrm|njaTlITDE?;?<?<>9<5:1<1;/:,9*6(6*5,3,3.1/,.,.023576:796:8<9>;=8<4?8E=F@KEPJRMYUdbrr}~䆉䉍䑔أ̪ķ›ɣϭеκbVSeYZg\`i^fkbkkcpkdsnbuy`y^w[qVhOXJNBG>A@>>7<3<2:0<0=1;0:/8.4-3/11.2,5-85>=F?G?C;<<9?9>7?7@6@5A6E;F?IDLJQOWUa_oo{{爊ꏒ␐əęśÞŧǰǹcUPdWUfZZg\]g\ah]en]gxXcVcYg[fZeU`NUFI?@=9<3;0;0:/;/:.8-9/8242/3+3)3+62==F@I?DA><5;1;1;2=4?5A6A7D=E?GDKINNTR]Zpn}}䄆㈉̀|ont}cTMcVPdWSdXVfXYkW\xW_Xc_nc|b`yZnQ[HGA<=6;1<2>2;/:/9/7.603426072:5<9><A<?;::6<6>8@:E?E>C;B:@;A>A@ABFEHGKKSQ^[pnwuuvutphzfnruz~aSIbTLdUNeTPjUVx[bbrhmnnp{jh^UQED:>6=5<2?4@5>4;46211/2366::?BHFKCEA?<:<;CCHIONKID@A:=8<;=>=>??DCFEKJTQZXfdfeffnkrd|bfgmswz}~`RFaSIdSMlWXzamilos~ʌӏz҆hx^hWXLJAC<A:>6=5;4:686444487;<?ACDGHHIDGCGEIHKIKFDB?>;:78698<:?;@=C@FDJIOMRP[[]\cbnfo\vZz\t]{dknopo}kvercpaoa_QEdTLl\^yhxnnpzÖ̘͔ƒzpib]WQSLNGHAC<;472:696:8>>?=?<@<?<DCFIDIJOIKCB==:986647596:6;7>:A<B?DBEDHFMLXX[Za^h]jV}rUo|ToVrYw_{bybu`o\jXhWh}Wh|Wi}W`SMj]aui}{n~ns|m_jY\SOOHQIPIKED>;593:4;6>9?8?8@;A>DEFFFDDA:94517/7/636668595:6>9?:@;A=B>GBPLVTXX^Z`S}cNhgG^qFf}NiPnUnWjRgQfQfQf~Qf}Pe}Oe}O_W^iauqgujtvmdz^gUSQKTMUOSOMGJBC9:0<2=4=4=5>8?;A=D?A;:46324.6-8/81847668685:5=8>8=7@:C;IAPMQRUWWS{UHg[CYc>bwJmSpUoVhOfLgNfNeLdLdKdKdKWSg_[wjdxp{tqkbp^]ZRULUMVNNHE<A6<1;0<0<1=4>5?7B:?6:16/4326080918477675757596:5<7=7?7B9E;IDMMMPOOOHhQA\\>evLuZtYuYpUgMfJgLeKdIdJeIeIfIQPc][rkgyt~zuogtac]VYLWKTIJ?@6;29.8-9-<0=3>4>4>3;07-5.321517499<<<=:<785858686:6<6?7@8C9D>FEFIIJNElO?c[AetJtYy]rXnShMbFdFeIdIeHgJgJhJiKYXecarmjuq}vxxyumfoa^\RZNXJQDG<=38.7+8*9,;-=0=1>2;0:08/5/4356478:@@A??<<89585867696<7>7?8@9?9B?EEHFQGvWDkbClyNqVuZnTe}Jb{G]zB`CeGgIgJiKkMlMmNnOeaklfupi}tkyn|o|lzhyzbjx]YzZOZMZJWGPBE9=29.7+8+:-:.;-;.;/:-9-9296987889=;?;=7:3838486768594;5>7>8>9>9>8D@IBRE_IxmJ}W|[rTf}KUj?Pc;Vl>[wAbFiJjKkLmMnNoPoQnQlenogtriytkyuiutfkpa^m]RnYJrWGuWG{VEQBM@G<A7=3:/9,:+:+:-;-:+9*9,9/8466689<==;6818/8083848594:4<5>7>8=7=7>6A8H;P>`HuR\[fuKRc?GV6GV6M`;Xo@_|EfJmMnMpOqQoPmQkOhNnflpgmqglqfgnb]k^Sk]Lk\InZGrXFvTCzL=G9C7A7@5@3>1;.9+:*:+9*9*:,8.7085;:=<<9929/:/:0:19192:3=5>6>6=5;4<4?4A3}E5P<cGtTzYqmKVV:HN5DP6GU8M]<Re=ZsBbGhJpMrPsSpRlQiPfMfNmdbnd`mb\k_Vj^Qj]Ok\Nl\MpZJuUFwO@|I<C6A2C4C5C5B7@5<0:,;-</;/;2;7>;A>@;=5=1=/=0<0:/9/:1;1=3>3;1:/;0<1?3}A2zD3Q<aHkPeNnWC_U>XW?W`BSb>P`;Sd>Sh<\vBdGjKrPsTnRjOhOeMeMeMkaXj`Uj_Sj_Pj^Nk_Nl]Mo[KrXIvRFxM@zJ;~F6C3C5C9D=C<D;D:@6?6?:@=B@CCB@?:=5>3=1<0:0:1:1;1<1<1;/9,8,;.=/=/}@1zC3N;[E[FwSBnQAeTB^ZAY`@Rc=Oa9Oa9Nb:Rh=\wCdGjLoQmQhOfNdLcKdKcKi`Si_Qi_Pi_Oj_Nj^Mm\MpYJrUGtSExPA|N=L;I;D8D:F>B<B;B;A;@<A?CBBA?=?9?6>4=2:1:0:1:1;0<0;/9-8-9-;.</}<0z>2{D5|K:|O=wM=tL?tQDlVEc[C_dCVe>M_9K\9L]9Na:Sh=[tCaHfLjPhPeNdLaJaJaJ`Ji`Qi`Ph`Oi_Oi^Nj\Nl[LpYKqUGtUG\NaVbW`UUJF;@4@5@7A:B?CBAAA?A=A;B9@7>4=3<2;0;.;.:.9-9-9-:.}:.z:/y;0y>2yB5yE7uE7qD8tI>sNAoVDj^G\^BPY;HU7ES6GV7K\9Nb=Qf>VnB]zGcKdLeLcL`I_I_I^I]HiaQiaPi`Pi^Oj]Ok\MjZKmYJy]PkawĐzqe[OI<?5?:DCHGIHIGB?@;@:@9?7>5=2<0<.;-:,9,9-9.}:/z9/w9/v:/u=1u?3u@4r@5o@5nC8qK>oUBeXBWT>FL6>H3?I4@M5DS7FY:J^=Lb=Ph?YuE^}G_HbJ_I]H\H\I[HZ}HhaQiaQi`Qj_Pj^Oj]Mn]NzdX{r˪̧vuc_OLBPJc`okrnkeWQE?>9>8>7>5=2<1;/:-9-~9.}:/{90x:0t:/r:/q;0p<1o<2o=4n?5kA5lH9iO>YM:JH5@C2;A1;D3=H4@L6BR9DV9GZ:J^;Ne=WqEYwF\|H^K[}GZ|FZzGYzHXxGVuGhbQhaQiaQi_Pj_PqdUoc~vðıª~qpfofxrˌۖݓ׉woaXLB?6>5>5=3<2;0:/}:/{:/z90w9/s9/p8/n9/l:0l:1m<3l>4jA5iF9cJ;RE6C?1<>17=07>/:C2;G2<J2?O5BR7DV7H[9Od?VoFTpDVtFWxGUvDWwEUsETqERnDNiBhbShbSibSneXxmaxlzø̹ǯʜԢ᭩㬧ٜҎ}wiaTJC7=1>2>2<1~;1{:1x90u8/q7.n7.l8.j8/k91k:2k<3k@5fD7aI:UJ;HG8CE8:@34</5>/6@/9D1;G3<H4?M5CS9EX<J`@MeBKe?OiAPlARoCTpENiCMeBI`@D[=hcTjdUpi[zrg{qxȿϾɵíŬвٷό滶⳯௪٢ϔņ}th_QH<<3;3;5z;4t;3p;1n:0l:0k90j80k80l92k=4hA6bE6YH8VO>ML<CF7?E76>02;-4<.5=/7A19D2;F4<J6?P9@S:@T8BV8DY9G^;I`=MdBNeDH]@FZ?@S;;N7jeWpk^xsfyo{ʺǶĵǽߴ۱Ӫǚ{qg\QE@5|;0u:0q;1n;2m;3m:3m93k92k;2j>5cA5ZF6TJ8QM:OQ>DJ7=D39B23;.3:.3:.5=/7@17B28D49G59G3:I3;K4=O6@R8CU;DV<GX?EV?AP<?N;9H75D3nj\tpd|ynyغԱҬɟymgWQBrA4k:/j9/k91k:2j;2g>3cB5_H9VK8PN9KM8HL7DK6?E3>D48>14;/5<15<17>39B68C57B37B26C16D18E3;H6=J8>K9?M:@N;<K87E47E55B43@2pmaxvju}ùھѴ̱ƫwpc]PrN?dC3_E4\I6XN9TR=LP9GM6FM6EK5CG3AD3AD6<@37=27=27>48@58A68A57A47A48B59D68A57A58C67D56D36E37F44B23A12?11=0tuf||nu}ѼɳĮ¬plZo[F[L6VM5TQ9OQ9IO6FM3GN4IO5KO8IL9EH6BE5@C4=A4;@48@57@47@47@48A59C69C7:D8:D88C58F3:K5:K49K59I66D45C34A22?0 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Negate.miff b/PerlMagick/t/reference/filter/Negate.miff
new file mode 100644
index 0000000..e8ae447
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Negate.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Normalize.miff b/PerlMagick/t/reference/filter/Normalize.miff
new file mode 100644
index 0000000..5c0e306
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Normalize.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/OilPaint.miff b/PerlMagick/t/reference/filter/OilPaint.miff
new file mode 100644
index 0000000..636adb5
--- /dev/null
+++ b/PerlMagick/t/reference/filter/OilPaint.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-0/-0/-81,91.81-81.81.81.81.81.5-*3/,3/,2.+2-,3/,2-,2-,2-,LA2LA2LA2LA2_70_70EE5EE5H=BEHAHAHAHA<@HAB/B/>)>)>)>)>)>->->->-H;H;53.53.53.53.53.-0/-0//-2/-2/-2/-2/-2/-2xA5xA5bnISIISIYVSYVSYVS0/-0/-..081,91.81-81.81.81.81.81.5-*3/,2.,2.+2-,2-,2-,2-,2-,LA2LA2LA2LA2_70_70EE5EE5H=BEHAHAHAHA<@HAB/B/;-;-;->)>)>->->-E>E>E>53.53.53.53.01(01(0/+0/+0/+0/+0/+0/+0/+xA5xA5bnISIISIYVSYVSYVS.0.//-//-2-*81-81-81.81.81.81.0,,.-./-,/-,2.+4,)4,)4,)/-,4,);3.>/.=40>/._70_70EE5EE5H=BEHAHAHAHA<@HAB/</</;-;->)>)>->->-KDKDE>53.53.53.53.01(01(01(0/+0/+0/+0/+0/+0/+xA5xA5vISIISIYVSYVSYVS//-//-//-2-*2-*80-80-,+,80--.0-.0-.0-.0/-,1.*1.*1.*4,)4/+4,);0/;0/;0/;0/E1-;0/;0/K62R).BEHAHAHAHAA1A1A1A1A1;-;->)>)>->-KDKDKD75+53.14/14/14/01(01(01(0/+0/+0/+0/+0/+0/+xA5xA5K@\YdJYdJYVS//-//-//-2-*2-*-.--.0,+,-.0-.0-.0-.0-.0/-,/-,1.*1.*4/+4/+4/+;0/;0/;0/;0/E1-<6*E5'<6*R).E5'BABAA5A1A1A1A1A1A1~:/</</{@4{@4{@414/01(01(01(01(/0.1+01+0'+/1+00/+K@\K@\K@\YdJYdJYWS+-/+-///-2-*2-*-.--.0,+,-.0-.0-.0-.0-.0/-,/-,1.*1.*4,)4/+<70;0/;0/;0/;0/E1-<6*E5'<6*R).E5'E5'>6A5A1A1A1A1A1A1~:/{@4{@4{@4{@4{@401(01(01(12001(0/+1+01+0'+/1+00/+~{~{~{S_GS_GS_G//-//-//-2-*2-*,+,,+,,+,/(//*,/*,/*,-.0/-,/-,/-,/-,/-,/-,4,);0/;0/;0/;0/>=1>=1>=1<6*R).E5'E5'>6A5A1A1A1A1A1y:4~:/y:4};0};0{@4};001(01(01(01('+/1+01+01+0'+/1+01+0~{~{YdJYdJ_eQ330330//-2-*2-*300,*+/(/-',+()+()+()+()+()/*,/*,/-,/-,H?-C74;0/;0/;0/;0/>=1>=1E5'<6*R).E5'@2>6A5@2A1A1A1A1y:4~:/y:4};0};0};0};0-(+-(+)+,'+/1+01+0'+/'+/1+0YdJYdJYdJ43/43/43/43/30-300300IE7-',+()+()+()+()>94/*,>94<71<71H?-C74C74C74C74C74;0/;0/E5'E5'R).;1;1;1;1;1@2@2y:4y:4y:4y:4y:4y:44!4!A>E@DKDKDK+**)+,'+/'+/'+/'+/'+/:&*''-''-O[DO[D:81:81:8143/74,<75:54IE7IE761.62.62.62.<99<99<99<99<71H?-C74C74C74C74C74>=1>=1E5'E5'A-A-;1;1;1;1@2-(-(-(-(-(y:44!4!4!C<C<E@E@HFDKDKDKDKJn>q'+/'+/'+/'+/'+/'+/}t}t}tLVDLVD:81:81:81:81A=3<75F=7IE7IE7IE762.62.62.<99<99:97:97:97H?-H?-A=(C;*C;*C;*>=1>=1E5';(A-A-;1;1;1;1))))))))))))-(<(<(<(C<C<E@E@HFDKDKDKDKTaVnVnJnWoWoNXCNXC:81=60F=7F=7A=8F@5F=7IE7IE7IE7IE7E;+E;+<99<99:97:97:97:EQB=-A=(C;*C;*C;*>=1>=1>=1;(A-A-;13+3+;1))))54545454-(5(5(C<C<C<E@E@HFDKDKDKDKVnVnVnJnWoWoS_GS_G:81=60=60=60KB4KB4KB4F<1IE7IE7IE7IE7<99<99:97:97:97:97:97A=(K@/C;*C;*;(;(;(;(A-A-3+3+3+7)7)))54*0*0*042*0*0C<C<C<E@</</</DKDKDKDK>q>qVnWoWo:81=60=60=60F<1TG9TG9TG9TG6TG6WF7>83<99<99:97:97:97>CGF>A>A>A?F;(;(93936(6(8*8*8*4.4.))54*0*0*0427+7+7+1)C<G=</</</</</^VagagagagWoWoXM<ZL<ZL<ZL<F<1TG9F<1F<1ZL8TG6WF7]Uj3?3?3?3?3?3?3?>A>ABG;(:%93:%:%8(8(8((04.4.))54*0*0*08(./4*./1)5*5*5*</</</</^VagagagagVe}g\L<\L<[L>[L>[L>[L>ZK;ZK;[NA[NA[NA[NA@9@9@9@9@9@9@9>A>ABG8'B8;84'4'4'4'4'4'4'4.66+.+.+.;6./5*./8+8+5*5*8+8+8+8+8+WoWoVeVeVe}g\L<\L<]J<^K<^K<^K<^K<_KH_KH_KH_KH_KH@F@F@F@F@F@F@9>A>ABG4*4*;84*4*-<-<-<-<4'6667+7+7+C6./9.9.8+8+5*5*5*5*8+8+4'4'MdVeVeVeVeVe]L7]L9]L9]L9]L9]L9]L9aM:aM:aM:aM:aM:@F@F@F@F@F@F@9>A>A3+@660;8"/ - - - --<-<6!+67+D6D6C6C69.C68+8+8+8+5*4%4%4%4'4'4'rrrrr]L7]L9]L9]L9VNAVNAVNA^N9^N9^N9]P=aM:aM:9A9A9A9A9A9A9A>A>AG>G>03;86( - - - -232323,(3.3.863.C69.9.9.8+8+207$8+4%4%4%4'4'4'{Ha{{h\K6\K6\K6\L9\L9\L9\L9\L9^N9^N9]P=aM:aM:9A9A9A9A9A9A9A@31,1,1,7)4.-) - - - -2323233.3.3.865)C69.9.9.8+1*,:.22/2/2/2/2/4'4'dlHar{ycoWoWzdy[wVwVwVwVwV[M=\K6[M=\L9\L9\L9\L9\L9^N9^N9]P=aM:aM:|9A9A9A9A9A9AI?I?1,I?7)7)4.3*3*3*3*3*95952323-H3.64EA64646464641*65650/0/2/0/0/0.<3<dHa<d<dtXtXtXy[wVwVwVwVwV\K6\K6\K6YL<YL<\OB\OB\OB^N9^N9]P=aM:aM:|9A9A9A9A9A83@3@31,1,1,6060<-3*,(959595952323239?30:/:/:/:/646464646464640/0/0/0/;d;d;d;d;dtXtXtXy[wVwVwVwVwVŵŵ\K6\K6\M>\M>\OB\OB\OB\OB\OB^N9]P=||ƕpg}pg}I?@3@31,1,1,606060606060=4@1@1=4,(OQ5630:5:5:575753535355-5-5-5)5-5-5);d;d;d;d;dtXtXtXtXwVwVwVhhÿÿ\M>\M>\M>\M>\OB\OB\OB\OB\OB^N9݉݉||d\pg}pg}pg}\[L@3@31,1,1,:-:-7,;+;+=4=4:.@1:./0?5+=$:*>*>544854545454545-5)5)5)5)5);d;d;d;d;d<dtXtXtXwVwVwVwVwV\M>\M>\M>\M>\OB`S>\OB\OB녈녈녈뉉||d\pg}pg}pg}d_C7&<-1(1(1(:-9+9+>+9+9+9+9+@1-;-;-;3636858554:854545454545-845)5)5)5)KMKM;d;d;d<dAdpQpQgMgMfGfGfGfGfG_O=_O=\OB\OB\OB`S>\OB\OB녈뎅뎅j\Ej\Ej\Ej\Ej\Ej\E0+1(7&7&7&7&9+>+9+2)2)2)2)/:/:/:8284/:8484:854545454545-;6;%=4=4=_=_=_=_;d;d-3%tXpQpQgMgMfGfGfGfGfG\M>`S>`S>`S>`S>`S>`S>녈녈뎅뎅h\Kh\Kh\Kh\Kh\Kj\E=$=$9,=$1(7&7&>+>+9-9-9-9-9-/:/:/:92929292926=6=846=?76=IDID;%]O=4=_=_=_=_-3%-3%-3%cDaEaEaEaEaEaEaEfGfG+0+UM>UM>`S>`S>`S>녈녈녈뎅뎅h\Kh\Kh\Kh\Kh\K6*6*6*6*6*<+5+7&<+9-9-9-9-9-9-/:<5<5<5<5<5<5<58892928888?7;%;%;%]O=_=_=_=_-3%-3%-3%-3%cDaEaEaEaEaEaEaEfGfG+0+UM>UM>e[Me[Me[M녈녈녈뎅뎅__O__O__O__O__O:*7*7*7*7*7*7*7&<+9-9-9-9-9-9-5<5<5<<5<5<5<5<5>9>>>>>>>>>>@;TITITITITI39"-3%-3%-3%-3%-3%8+/q\aEaEaEaEaEaEfGfG+0+UM>UM>e[Me[Me[MibHhbKhbKhbK__O__O__O__O8)8)8)9)9)9)9)9)9);/9-9-9-9-9-9-5<5<5<<5<5<5A9A9>9>9>9>>>>>>;%TITITITITITI-3%-3%-3%-3%-3%8+/q\mRjGjGbIbIbIbIbIi`Qi`Qi`Qi`Qi`QjaQjaQlaRkbNkbNkbNkbNkbN__O__O__O__O8)8)8)9)9)9)C3:(>3>3>39-9-9-5<5<5<5<5<<5<5<5A9A9>9>9>9>9>9<,<,:':'YSYSScBYS=_-3%:;#:;#:;#:;#:;#:;#jGjGbIbIbIbMbMi`Qi`Qi`Qi`Qi`QkbSkbSkbSkbNkbNkbNkbNkbN__O__O__O__O:*8)8)8)9)9)9)<0:(>3>3>3@=9-5<5<5<5<5<5<<5<5<5A9>9>9>9>9>9>9<,<,v=1v=1YSYSScBYSQM:<279/79/79/79/79/79/jGjGjGjGbMbMbMi`Qi`Qi`Qi`QkbRkbRkbRkbRkbRkbRkbRkbNkbN`ZFZOZOfaP:*8)8)8)9)9)9)C3:(@:@=@=@=@=5<;/;/=0;/5<:.:.92z:.>>>9>>>>>>:*<,<,v=1v=1UMUMUMUMUM:<24;04;04;04;04;04;0jGjGjGjGbMbMbMi`Qi`Qi`QkbSkbSkbSkbSkbSkbSkbSmaTmaTmaT`ZFZVD:,faP4+BC>@>@9)9)9)C3:(DD@=@=D>D>D>~>/~>/~>/~>/:+~:0~:0~:0{90{90{90{90v90:*:*<,<,v=1v=1YRYRYRYR`vF:<2495495495495495495495aIaKaKaKbMbMi`Qi`Qi`QkbSkbSkbSkbRkbRkbRkbRlcTlcTmaTpaUDF8DF8DF8>@BC>@>@9)9)9)C3DDDDB:B:B:B:~>/<+<+<+<+<+:+:+~:0w:3w:3w:3w:3v90:*:*v=1v=1NO>NO>NO>NO>YSYSNO>0>.0>.0>.0>.0>.0>.0>.495nTaKnTaKbMbMi`Qi`QhcShcShcShcShcShcSkbRkbRlbQlbQlbQpaUDF8>@BC>@>@;0@DDDDDDDDDB:B:B:B:=/<+<+<+{<3z<4z<4z<4|90|90w:3w:3w:3v90:*k70n7+<,NO>NO>NO>RNRNYRNO>6866866860>.0>.0>.0>.495^M^M^M^MbMbMgdRfdRicRicRicRicRicRicRicRlbQlbQlbQlbQddd<=/>@>@>@rnWrnW@DDDDDDDDDB:B:B:B:=/~<1~<1~<1{<3z<4z<4z<4z92z92z92w:3i70i70f6.f6.f6.i60f6.YRYR/9+09*09*09*6866866860>.0>.0>.0>.495nT^M^M^MaKaKgdRfdRicRicRicRicRicRicRlbQlbQlbQlbQlbQddd<=/<=/AErnW@DDDDDDDDDB:B:B:B:;2~<1~<1~<1{<3z<4z<4z<4z92z92z92i70i70g6/g6/g6/f6.i60f6.YR17.17.17.17.16*6866866860>.0>.0>.0>.495nT^M^M^MaKaKgdRfdRicRicRicRicRicRicRghPghPghPlbQ5?+5?+BDFDB:B:B:B:pB<pB<pB<pB<q@6q@6q@6q@6z92g91g91g91g91g91g6/g6/f6.f6.f6.06,17-17-17-17-06,686686686-8--8-0>.0>.nTnT^M^M^M]xT]xTheVfdRicRicRicRlc\icRlc\lc\lc\ghP5?+B:B:B:6*~<1s?9s?9s?9s?9s?9s?9z92g91g91g91g91g91g6/g6/f6.f6.f6.28-28-28-28-28-06,06,.3-*4,-8--8--8-0>.nTnTnTnT]xT]xT]xTheVheVjeVjeVjeVjeVjeVjeVjeVlc\ghP@<@<6*oA3s?9l?4o?8o?8o?8o?8l?4g91g91g91g91g91g91g91i70i7029'29'29'29'28-271271271.3-.3-.3--8-/2//2/1?(1?(1?(1?(DV;DV;WwHieWhfWhfWhfWhfWhfWhfWhfWjeVlc\ghP6*6*s?9l?4l?4]K2]K2QN7j7/g91@L0@L0GJ+GJ+GJ+GJ+GJ+FF529'29'29'29'28-271271271+3++3+062062)3))3)1?(1?(1?(1?(DV;DV;QjEieWhfWhfWhfWhfWhfWhfWhfWjeVlc\r=7r=7o?8SO3SO3SO3LO6g91@L0@L0GJ+GJ+EF/EF/GJ+29'29'29'29'29'28-271271271+3++3++3++3+)3))3)1?(1?(1?(1?(DV;DV;CV;ieWhfWhfWhfWhfWhfWhfWhfWjeVhgYUO2SO3SO3SO3HO5HO5@L0@L0GJ+GJ+GJ+GJ+GJ+29'29'8A58A58A58A58A58A5.3-+3+.3-.3-,1,)3))3)1?(1?(1?(:M8:M84B14B1ieWhfWhfWhfWkf[kf[kf[kf[kf[hgYelYɾɾɾɾUO2UO2SO3HO5HO5LS0LO6LO6GJ+GJ+GJ+LS0]e@<?58A58A58A58A58A58A59A69A69A6.3-,1,)3)<E<9@59@5:M8:M84B14B14B1\gO\gOlgYkf[kf[kf[kf[kf[kf[elYelYɾɾɾɾUO2RK-LO6HO5HO5LS0LO6LO6LO6EN.EN.LS0]e@<?58A58A58A58A58A58A59A69A69A69A69@5<E<<E<9@59@5:M8:M84B14B14B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Opaque.miff b/PerlMagick/t/reference/filter/Opaque.miff
new file mode 100644
index 0000000..4afb2e6
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Opaque.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Quantize.miff b/PerlMagick/t/reference/filter/Quantize.miff
new file mode 100644
index 0000000..4ce2584
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Quantize.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Raise.miff b/PerlMagick/t/reference/filter/Raise.miff
new file mode 100644
index 0000000..9eb6cf5
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Raise.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:ɛך陗ٙ֙әΚșřĘŘŘƙə՚ۜƝ˫¹ϱϢĸdca™ϗڝ윝暗ՙՙә͙ǙĘĘĘėĘȘڙ᜕ŞƧҬӟB@=aaaaba̜ݞ윙ٚϙљϘʙĘؘʚߙߝܰ6=6BC:abdabdcbbŗΚۜ휙랚Кʙ˘ʘƘ˜˝ڜ׮庿毳˧`oh\j`FK<adfadfccdbcbƘȚԜڝ˙řƘƗ×ǜԥĹ´jprqcwbBJ7cdcddbdecfecgdbÙŗȚƘŗƢż÷ǸͶҶtmb]d`WiS:C2fgbggbhgckiekielfcų¶˹Ůİʰ]yR^zR]zV]w[RfP8@2ijfijfkkgmlhpnjrljqkhĚ٢Өخݸ;̺Ƕ˷ŲOlDQrIOqMUtVVoVMcJ:A1jkgklgoojqolsoluqmtqltplɝҟ͝ϙЛ͜ҙӘ˛ݗߥı뮲谴窱覰ޢǝQdDQfBUjJ]q[hxi_o`J]F=F4iieijennjrpluqovrovroxsmzri㓔ʗޙӗ֘؜ϖ٘昕蜙됌ߚŬਮrvoluqqwrL[K@L8ggdhhejjgnmisrkuuoxwlzwiwtizvxH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nndciaW`Qedbdcaggdjkfoohusl{xjzxg|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_Tljeigbgdaigamlfwqixkvlꬲ쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU~zsphqnglibhf^lhduniuiui櫸|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTwVQ{wlzuluphokdnidqnjzth~scy~Ц틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ue@;0{ozo|wlxrgumetpiyuh~uc{}ͣvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|0<&|q{qzoxluk{um~xkxg}ԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiAQ3{o{o{nzmymxoymyjyuwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}]rL~oijc}rymymymwlxlyozm|m{qyw^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^Ld<\cDH]<KiBZwMcViZn^{xlxlxlwkxlxmxm{l{l{l_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7K_:`gJ]tQ^SeRdS`Rc~Trxixixiyiykylzn|n|nzlcG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1SoCc{Ra~T\zL]yL^}O]KcQtfozpzlzlzlzlzlyi{k{qmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<ToCZwIWvGWtFZwJ[{J[}CdMf~WP`L{n{o{o{n{n|iykqv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>WlF[uIRp@TrAYuFZyCX{@_H_vMK\@zn|p~r~r~p{rʊzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0M]=VnAMl8Qo<UsCUt>Pp9If3:N&6H&vjym~rs~odžÑИ·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-:F*Nd8Ki2Ll7Qo?Mj8Fd3B]1@R1CU2srixtmzo~ǫ睝ޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!<C&JZ:Fb0Ih2Pk:Mi4Ic6I`7L^6I^2gibllg{slyn}}ڧ匋ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2w`UiGEa.Qm7So<Oj5Ng9Kb7La5Lf4`d]adakihtrnदぅʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)yrTkDEb-Tq:Rn=Lf3Lf9Ke7Lf4Ol7cf]ac^dealndy{{ﮬ܄ǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌj~\7I*G^-Pn6Jh4Kd1Oi:Nk:Lj3Ss;podongmnfqt`yzlqɭޟwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ij6>,,5 L]1Nn4Hh3Oh7Pl;Ro<Qr9Wz@zozo{o|n~rrx]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.%& +1$L^4Rp7Nl9Qm=Nn4Tu7Y~?Tv@xxxyzxvzyw`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/**#*1#L`7Xt<Sr=Sq:Rr6Y{?X{BGg7|}}}|~|yvhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;((+#)/!M`7Wt;Ts;St7Zz@]}IIh6Ge8}}}~}laRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#))#)1#Na8Xt;St:Tx;]}GLi:If7Ie9}}|~{|mbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<2(*#)/!FZ0Yt<Su<X}BNo=Db4Li7Hc6}~~~~~~~pbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=3&+#)*@J.Vo>YzDTrDC`1Fd6Ki8D_4}~~~:3,60*=;8VUP_]WBA8!  !2#W&%q"%s! u$"v$$v$$s%$q%!p% r$!] F C!FFDCCCA@?>=<:95= O+)M/+C2+21&%,!%#'"'*')*!9A&Uo>\{FHb6C^2Hc6Hc8B\5~~~~94+51,FDBnoouqUMB#'!0!!mCCm/-vw"$u#$u"#q#!n%u#e#KC D DBBBB?=;;::973;O-+A1*)*!"!(!'' 09#VoBRq??W/C\3G`9Ga6AY6:5-94+985dgh|lSXC(* *&%TQPzwqq<<f k" p""q!!p# s" g# MD C CABA A ;9877983/: >,)&" $&07%[sQFd9<S-@V1EZ5Ia9<O3~~~~~:5-:5,83+555X_b~}}ytf<:."' OPKzyv^T[*"`m" m# o%"`!L D C CBBA>876558867:(#"#$)ShO5O-9P-9N,AW4I`:2@,950:5.76+:97UX]xz|ssa;=.;A8jmjvrc82]h"i&Y%G#D!EB@>=;8767899 7%E<2:90!"")'/"1?*9M05I*BU7EY?'3'75-950:5/77*BDCsx{y{vx|rspoa_]TmliiVKV%d` PC" ;# <"<!;!8 7<:877!6%4'2)CC8+/%!!#3@,6E-FT=CP>!*"86.85.941:7078+9>;gmq{}tzo|{mupiww{pd_9,S!MC;"< =!=";!: <95 2!*-*1/ 11!:>1""#!.7'EM?<E; '"86.86.85.:4197069,7?;bimwuxgsrf{vv|sg[U>1@&5589!8!7!4"2$/&51&%%#%';;+13&  !!  $ '!1<-3<3#*$77.85.76.95.:5197059+5?;gnswoo`ie_z~yyrjodX7,/$1(1(.*+))*27("( %&'87'3/$%%!!!!""!" '(',8*#,"|28+79.87/96/97/96077/59/BIGjos~~tusijf\je`{wz}{~{zm:7(+(-*,**)(*&*%)(,15"35%.. ., -+)'## !"#""## % %" $&3&4 )"+&1"'1% \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Resize.miff b/PerlMagick/t/reference/filter/Resize.miff
new file mode 100644
index 0000000..cb117ce
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Resize.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=35 rows=23 depth=8
+page=35x23+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-61-81,70-80-5-+4-*3-)30)74.B;0I@1NA1C2B6CF<@?4?,@+=-<*>0B5o?383261.00-2.-?/0QQxuMDey}|ff\+,-/-+0+(.+*0++0++0,+1-,2/+41-;3-@5-F=3\=1<.D:A?@->-=+<,;.B4LFjaT;7002,,2./1.0/.TB?QNyU`c_hZ-////./-+,)*+*++(++)).,,.+)2,*;20;0.?2/>70j6,@2B4>0=-;-~9*>4JDrN\F3.*0)*0*,0+/FI6Ǡh{`45/872=73:305224,/3.,32-630A7.E;1>4/?40G/0B2(u93?9@4;-z:*G>wI:cOrunRgO2+%)+'2(+OO=saujxu\oU782?>9FA<GB;H>4E;0A91:5/@:.M?0M=2B:0N<4BIB6?3A1>7>><=B>zbIWT6I9PHaOmKkJUK<-}}cy]oU21.882DC9LJ7[Y_YQ\@9894,>;2M@0D9,:60>67&=)9->07,1+2%6&KD??=/BEARBkIwQsikꛡ=:163+A;3UG8{}\XA?EAA;kc~PV>+<+9094:2<2+)3&8'G?=.<.IEMPNgSvVlT_޿RJ<HA4B;4OE1mlFPCE?>=6>14-8-4#8(52221-C7ED9+=,D:cf^pms{~ZN?XL<TI<VK8d_nÌ|uEZAB???<>2;)7-103/176%8.:+9/=;?3:,9*_Xjsfopm۲ְ[K;YJ:[K;^M;\M?bVo~Rk@:@D:,=8F97(5-/0)7/I@N00E@;67&A7826/LE\pYQrWpanv]L8]L8]L9[N=cUOi`qfg@K<6>080</>17>-4)/FS<;@5D@B<72=:1.//?2FhOAxaze|fe^N>_P@^P=e]evwǶǰ^U??<4SE4.9-0+JMX`BG9Eal=:=656543,/08/l~AaIH0s[mSuYqR_yINF9_R@i`bopos¦޻Вx_XlgWS:,>3<48-=0GIC=6>,:.3:3555.5'3.@;Jj@JCC/[nAcEjM_F^xD04,HB:bb{`a܆΋}j|d\FZ]oh:'6):)<.9+;/70.;-92995577-8&;$HU<`>01]e<vfElLfKgH56,9<-QQMzwҁ}rg\Mn]JJ?4/8%7*;,?29)7/97EIE@837:6;;0<(;,K_rG?LT5qWjGgCeFkOnN\SD]UDbXGg^Rma_YULXR@d_KUN7,8,7);,8%=1:97:919):677;5<;;-9%F=WQzUcxJ=B27</lKmPpLpSh_Pi`Qj`Sj`VjaPg_LJJ9=F7xP>IF8*;,<1<(A9@<>2<+=*9-=3=28-:)w7'J=WQpbH@L9CE07=.oMpNvYaKi`QjaRkaSkbRlcSnbTb\LGF0F?RSHED=EFGFA@=6=1:1~:.{:,8.9+{9-u4*r8-RHYOUfBJ[58<.6;-hItX_IbIhaQibRibRkbSkbSof\SU@:;.a>8UU@@CCE=A9<,:+~9,}:0w80s8.p7-j3*j5*WPXRB6>07@06A135.\sCgN]G[~HgcRgcRhcRlcTlbRݾNO;ݗA;@=A<<1~;.{9/y:2k8/g7,h7.f4,g;1I@818+38//8+5A125)[oPPr@UrBVpFheVheVheVldYnna͘˷XH@5>9x=5s;1m8/l60g6/h<3eF3pmZ-4*06,.3,.3--2,.:0;H4BU8QhDEXBgdUheVieVme[hp`ʚJ9j9-o>6k>5g>4`G8HE.[[>KS=4:15;037105/+0+)0*/6/9C5CP;<F<afRhgWjfWkfZjvh_R7XM2PN6NT9IR2Y[>TQ;AB59?49A79@89@84;3/70;O3:M59I6 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Roll.miff b/PerlMagick/t/reference/filter/Roll.miff
new file mode 100644
index 0000000..5fc82de
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Roll.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:49578,LW3rS{^`IZ~CaIaKX|GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.-2/54+AM/sYnTTu?Z|E_L_IWwHhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.16,,-"@J1zm^MQo<VsB\yGbLQjEhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H6;C201$DM:ojGj=Lk<Li;WuFbNCV;gdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A22?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,+3+*4,-5,7@59C43>,>J4\hTQ]O+4-heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0+(.(*.*,1,/2/=D==J81?(BP<EPD/90gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+062,1,+/.)-.)3)6J29L38I1;K8/;.ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6;E:9@55=66D/G`5Gb<:M8@R:H\A4B1\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<IGbn|lpPHnRLauw|z|lYVS0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78xA5Y\}clJ>kK@\]^g~lp_YWS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21I.!lMNkqH==1X54H>FFISIYZO,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+4*,gcb~ipY\o`pr|_eQ,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-20)(eqRʳǰYdJ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*1+'[f@vvɌÓ~vpO[D.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0)$"W\H~j{j~oo}t~{olLVD23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-TN:hqRhWk\nckhsttthdNXC782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))e^:w\n\mYsd~{d}_S_G8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-vdӰg{eWgL671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/҅un330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T᪤:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKUtnD@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTVPAOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueAQ3WN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|XnE[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpui}g̮Ưʪǚպ[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}gQ|\a~QeYyhtyŵ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^eNd~mpopoqÿ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7p[oq|f~fk~en\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1rZycu`v_zd{d{Zhvlg^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<u^{coWrXx^y[wVahe|V_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>h~StXhLmQsZsTlMbENj4Ia4[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0O_9iLeDgKnUhL^EY}CWoB[sDTH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-QZ4dyN_AcDlNhGcIcJfIbDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!s`]>mKpQkHiMeJfHgG47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2՚q\]=rNoRfEgMeKfGkJ*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y|Kc9`=lIdGeCkOiOfEpP.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌIT<<H,g~CjFaEkKlPoQmMvV@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ij23+;C1fGoJjMmRjGqKxUqWUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.9909C0gKwQpSpOoIxUwY`JcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/7:/8@-hKvPqPpJyV}bbI`Lh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(88/8B/iLwPpNrP}`fNbJbMi`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#79/8@-_yAxQpQwYjS\GgJaIi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<24;089)Vd>tTx\r\ZC_IeL\Gi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=3 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Rotate0.miff b/PerlMagick/t/reference/filter/Rotate0.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Rotate0.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Rotate10.miff b/PerlMagick/t/reference/filter/Rotate10.miff
new file mode 100644
index 0000000..676af0b
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Rotate10.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Rotate180.miff b/PerlMagick/t/reference/filter/Rotate180.miff
new file mode 100644
index 0000000..b946255
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Rotate180.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:4B1H\A@R::M8Gb<G`56D/5=69@5;E:<E<;C8:B79A69A78C58A5<?5CB5MI6UR9WT<VV=aeF]e@LS0EN.HO5LO6PN4SO3UO2RK-mgKɾ|elYhgYkf[lgYlfXihXgkW_iR\gO/;.;K88I19L36J2)3))-.+/.,1,0627;69=8:@::>9;A;9@89?58>4:>5:?5FF5`YDigJGJ+=E*@L0^gKMO8QN7VO:\L4]K2XD,hS;ѽƿҶdwodkRlhZnd\keVhfWieWhgWgdUddS/90EPDBP<1?(=J8=D=/2/,1,*.*(.(,1+.3-2716;57;68<58>37>47=37=529'\`GppREI+9C'EF/e]GYG5_D5cA7h>2i>4l?4j90e3)e6"yH1u]ìhwoflSlhZnc\jeVifWifWifWheVgdU+4-Q]O\hT>J43>,9C47@5-5,*4,+3++0+*/),1+.3-.3-/5,28-39/28.27/2@+nv\]]?]X=UP9P;+^>2d=2l:3q94n=6o?8sA;s?9r=7oA38,6*?.kSԼluphiQngZlc\jeVifWifWheVheVheV,8.ZlS^qRH]=DV;6C.2>*2>--8-)4-,3,,0+-2,.3--2-/3,06,17-07,*1(QYFi_M5cJ5fF9g>4g91j7/m51q62h:1j<2o?4q?5q@6pB<@=:;<99.E4ǣǴҷ}~ghPndXkd[geUheVheVheVheVheV4D5]xTXrJGb9Mg@BU8IX@@M:3@32?4.5..1,/4./3-/3-05,16*07-17.)2(nk[q_gF4l</l71i70g6/f5/h70j70o5+s7.u7.x8/}92;2?6B7E6H9@68+j^o{jpsWٸ렧nlhhfQneWkdZieVheWheWheWheWheVCV;bNWuFLi;Lk<Gj=ojDM:01$;C28A2/8,.8*09*/9+37)56+37-14,883nLBh;2f6.i70i60e7,e7-f7,h8/j8/v80z92|90|9/~:.~<1=3<3?;E@B=A<80OA޲喗AJ<rnWdddjaQmdSmdUlcUicRfdRgdRgdRgdRgdSQjEbL\yGVsBQo<^Mzm@J1,-"16,9H66D2-9*2806867:21<..9)G@3vTNm=4Y+a0'i6-k70h8.h8-i7-k8-p;1z<4{<3|90{9/:.~<,=/;1C<@<B=>?@@@<=:qq瞙OHF=6)KO1ljelbQmdUmdUlcTjcShcShcShcShcShcSWwH_I_LZ|ETu?nTsYAM/54+-2/0>.;K84>1.3+330/5,5@1NO>z\OUQp8/`.$g3*k4,n6/n7+o8-p6,s8/w:3|:1}:0}9/}9-:+<+=,;,B8B:E;C?ABBD@D9:XUZ?>*0+:725?+CJ2|ф|e]SkbRlcTlcTkbSjbSibRibRkcSibRhbRX|GaKaIZ~C`I{^rSLW378,4954;.9A0BJ6;E02?)ES;_\H_RYRRNs=2e1%k4)n3+q6-t:.v90w9/y8/{90~:0~:/:,:+:+9.~>/=,=4D>F=F?FDDDDDDA><AEHE^B5?;.<=/3<(7>+}{jspifZPmaTlcTlcTkbSkbSjbSibRibRjdSibRhaQ\GeL_IZCr\x\tTVd>89)4;0;=389,9C(M_:UmDZnJyeOUMQMTLv@6l2'o4*r6+u8.x9/z:.|9.{8/{91|:/|:.:-;.;/82<3=/9/A<B>A>DCCE@EDEE;@9CBLLONBCECrM<A@%_YCfaPf_RpaUpbRlcTlcSkbRkbSkbSjaRjaRlbTjaRi`QaIgJ\GjSwYpQxQ_yA8@-79/:<26@*CW-`vFOe=WX@[SQMTGQ@v=1p4)y6,{3(8+<,:*8(8,8,{:+z;+z;/~;1;2:3<1A2=0@=BAACIHLKGKIFHCE?C<NJimNO>@K@8A'EA1VP@haQmcTmbUlbVldPldOlbUmbWkbSlcTh_Pi`Qi`QbMbJfN}`rPpNwPiL8B/88/:;#KQ5^kQGV4fvIo_VWSNOBH;v5(s9*{;,;*<,7,6*<.?1;0:.8*=,<,:+yA-C1F2=/EAIEHAC3>3@:>2=1<09+;0JM]YZF?C)5C1<C5DF8ZVDkbNlaRkaXkaTkaVk__k_ZjaQjaRi`Qi`Qi`Q`LbI}byVpJqPvPhK8@-7:/=;(KM@7><'2%AM+YMYSZNSGA3w3"};(<)8'8*83A9D9?6=7<56)<'A+>*9-:561>;@E;58*96;/9):(:)8)7%:,DFXOUM;CJ>@H8@E4LJ6`ZFhbKibHibLi`PjbSkbTh_Pi`Qi`Qi`Qh_P`JwYxUoIpOpSwQgK9C099076/581'2ScBsn]\STIRJ~:*7":(:(8+@;>>>9<3856798>4:)9&8&645<6;6<499/7*?)5=/:+7*8*9+:*=)40JLaY__O[ZFSP>LH7QN=`ZGf\Ig]Lg^Mh_Hg_Je[Md[Le[Ke[KcZKqWxUqKjGmRjMoJfG;C123+;=.O];vYq`x;cKYRTVYZ6'8$;(;,@8;=889692866:6:<5;-9*=2;868<<>9B9H:<49-5"<+:,9)6*7.7/4+:,RGZOjdOn_HfZF]VGWUR]W[pdmwj|mckbYK`WB\RCVP=VN?VM?UM>vVmMoQlPkKaEjFg~C<H,IT<jiu_FO)39"]OMXUhID6#;(;';+?77;6=8>688492:7C=ZXHI86:8;7<49-:)9'IB=57&;)9,=$8$4*0+5.K<_Oj^Nh\KlYGn_WyozwszԄecgUTALM:AE*<=2>=4@>0pPfEiOkOeCdGlI`=Kc9|ԌeJ3'-3%K@1I]=_P`5)9#=*=*8);6597<8<888482A=VQEJ/:8<;42)4(9(:(8)D9<+=+5)5+7&7&0+==RQYCj\Ef]I^]Gla]w΄ǁѓnlXVmLON:=001++.(.2&kJfGeKgMfEoRrN]=q\՚yDN)8+/364CO6gBgKM<&=!:':)8*846;78:885657;5836-;1?6;;0</7(7(:)9+G;:(>+1(8+<'7&K@njZcWPd_C`_HsWR~x‹ۃҁʂڅy|[Z\]Z\iEC=975+0+*0&gGfHeJiMkHpQmK]>s`^Y2/4#/%k3=Cj7cWl=4;%9&6$8&7)6/4854;4:65=&9$:*>+=/71':.?5:0:/:-8(:-6(;+6+;);#;-zfkSVpWD\[L~ZjȈ҈͌щy{[]QQljgelVL=OD;::447-bDfIcJcIhGlNcD_AdyNQZ478!AB395#@X8ePkV\4'5)5-6&9&7)403575<5:5.6#8:'?(:/06$KBPL73=4@1<*8/9/7,:0;*5#6-^Z|ysYQ|SH^VRpg}Π֢֝ދii]_spzte_X`S>\M>JE<DB6[sDWoBY}C^EhLnUgKeDiLO_9EB-RP<MG@h;dhuDB4*0/351+7(6-647865;3:/30515679?FBI73W^[g:A=6:&9+6070IFGF<-B2<1=5DAgeyujdoje·瘝lv]ftz{yf]b`S?bVD_RBYL<TH8Ia4Nj4bElMsTsZmQhLtXh~SAJ0=<&J[<dRpw829.0//40-6*5+65;;:580826473T[^fFS(6/7agdoVbSW953*-'0%@7><1'XIOA:1636:WZlgydᶯzzcjw|wwcYa\OB`R@`RC_RB_P@[M=e|VhawVy[x^rXoW{cu^L_>\;/Ad>cbw<35)/-.22/4*635?,:40E<A<53RNfvozJV-79?@BV[QVJQRX55-)7)=11,2+@3fXI?7.:279HJLApRȶ|qv}}|_[a\L9`P7_O=_O=_O>_O?_O=lgvh{Z{dzdv_u`ycrZNb<AG<dFhqH<4%0..2201*>:7?2=<7B:EAUUIGOQOJ3.78?C>C23,(/-CGDN03<.D74.6'6+B9G>:+B2779AMUd\v|̓pxmdpo`maXYVNA^N9_L7^M:^M:^M:^M:^M:n~ek~f|fqop[IY1@S?aYt{ME4%2,-0.13.J@8/8+8+;0IE86:0-6$:5NScp;V%7!+ -"/2>79:.A3MA9'3+83>/;*>4<==G?QKUuqg]qcG>aM:]P=]P=^M=]L;]L9]L7\K6\K6\K7ÿqopop~mdeNYa7>UHak||\W4'91003183FB8);%7$9.C@SNC67&058O\mQc.W-H*<-<191/604*6(PAME8;@68&;.C@BGC@@F4Kew‡|waWw_KH_N:^O;^O;^K<]J<[K:YI9YK:[K:[K:ŵytyheYa~Q|\gQ^?\Mdrzkk8-8+:391<3QG8+8&5*;664GG85+.0:1:<D'66%2)',$4'9.4'8';(7$D:;8B89(<7BJ<@@9>+@Gq~me^SdYLI[NA^P<^M<[L>ZK;YI;\L<[L<[L<պǚʪ̮}g}DaVes{r{s~qrH>7&:+6*>1J>5*4*./755)6&D6=4;28(0'(0(>.8-1,3134+8(:%9%;)B541C;@5BGCNE>3?;F|Rbfm{{͂wxd_uULGZL8XL<WK?ZL<XM<[N=ZN>[N>XnEuiWpdlnqbmagmjVG:*<.<-:*9)G=US@B>5=)8&7+5/3&9!9%<9;6;+8*4.3/93:.;+?0=1?;>AGF>;?F>C@:=PiДؙ앗䔗XQTWK4RJ9NG<TG9TJ:YM?[OA[PAAQ3|zoutrgqgpnm^V@3</;*;':(8.MKHILA5$1)*0-5428.5+5)7&6!4!7);/412+6(E9@:9<=AF;@1;7<?ANv࠯VNQSG.LG5E@7F<1KB4PI:VM?WN?VPAue{bprxZuPmfv\aNJH==-C2<-8+=3EIPJ>/7+535420058;>09"3$3)8/7/3+9/>4?2>/>5>>;>HRL]OWN_aeoz؜WLSSD.ME5A=8=60?90F@5MG:OI;tnOTWeZiWoUxNoVnTaQSNIE>QI>29(9$C@LH7-:*<(2%2,++))?4D98/<7>961;3<3;-:*9#<'KP]{sRJN:977:CRLsf\|§ﹾ]UjWF7TG6F=7:5/52(;6-A=3D@5᪤KU`pSgUqXzRzJnF`O\FJGHHF@7:):#>2VMC<5(7"7!2(-(-(1'?7;2:382:4806*;(A-=+F7aG<FSREUa:EQ8A9BC.A=(<99@?MLIXnmŝ쬲darTH:VJ9IA6<;274,30+63-:81ɉ_T{CcTtMzK}JtBbDXDKFKE@=-9(>3A>CA?69,4!5 /(1+8.4,3*?2:+9*;1=1>,;%<';/6<B1-040:4)C;*P@/K@/B=-:9.52)62&944F?O[To|xXWWMK4OK8GD;>?589243//.,10-unnd]nYWxJnEw>q>h=VAQ>HADE;;.?AAKUQUI9,5!6%0)++1+8)@4@2A1=26':$A&4!4+I@@?/5=0C74K81H?-P@-IA6@=9>94=71>83?80C9-E;+H@9MHJIE7MI6JI;GG>DC9=<6883551330WgLg{eƶvdHC/a=3[fZxGoAr:o:h4\0T,H.EFOBC;Ec^cJdOB:.'7;D?<<8?>8>2:(D7>3;0?5;#35K]B@7=0>=1D:/K;1O>1OA0M?/E</>9,:7.<71A91E;0F=/H<-J=0MB7JD<HC>HC>FA?B@;==8681671S_Gd}_~{sdmYn\w\e^:G@->3(R.(FOPbWk_mjrfnYhM_@V)K(HSZlS`jHpYCUPEG<Hy:4vC9CE>B@2E1C5?3F9KHC:GIEJG70=<3A:1E:1K<4P@5OA2I=0B<0<7094/95/<80C:3C:3D;1E=4G?8E@:EA:FA<D?:A?:>>89:4893NXChdttstkhnck\hWhqRTN:C)):&*+/&%+!3)"?;)XiMooxv~zrf`zXs`IkS@pJ9[VPLz4)u>.y;/~:/A5>6C;BA=;c6-E5'<6*A50C54<94?62@61B80H=4J>4H=1B90?7297364163.62.61.9//900:54<75=73A95B:8@=8<:5994782782LVDol~{}to~o{j~jW\H)$"''-'+/)+,+**.$&*&#4=0PfPdeegv|{zqdVNEG>{@4s9-v8,v>);*:+>-A1B6?594:7j9.R/(70)F*.R).E1-<1/;0/=5-A90C8/A5,;1+4/+/0001.10*1.*/*,1)./(/-.03003.,80-:2.96196153.34-23-O[Dvp~ÓɌvv[f@+'0*01+02(/0(,-(+/')2'(=:3N^G\{ZwypQOKDG;};0v:*{;,9,</?/=.</>2B2;-@1A1i:-O,'93,59/>3,>/.;/.;1-=40;3.6/*4,)/+).+*/-,--+,*)+()-',+(,*)-,+,-*+2-*3/,30-21./1.//-.0.YdJǰʳeqR0)(2*10/+0-+0,*2,+2,+-)'01(<@3SZGrp{URE>G@?7:.9*9);,<-;-=+?,?3G<D7A3>5=0h7/K62B:6A73A2/>0.;21<328110--/++.*)0,+/,+.-.-+,*()*)),*+,*+**+('(+)+,*+-+)-.-..0+/2,/2_eQ|`prY\oip~Кgcb4*,/-2/2.02./0.-0/-0,.1+/1*75+CB8WeWyg_E@G:C7<2<.<,<+=+=-=/>-@,B/HAE@E9A3;/y7-_70Q<5H>7F91A5->4/<4/82/30.2-,2.+2.,/-*0-.0,,/--/++.++.++.++,**,**-+(/*'/-).--+-/,-/YZOISI>FF54H=1XH=kqƊlMNI.!3-+00.120/3/,40-4.14/53.93.;41<?5WNGD@8B1?/;.<-=->,>)?,>-?-@*A0>=<>E@H=E49(m=+UD4EE5H;/C8-@6->6-:3,75052-40,31,3/,3-,3-,1,)1,+2,+2,+2++2,+0,+2-*2,(1.+0/,,-+,,,YWSlp_~]^gK@\J>kcl}Y\xA5E212*,5/.00.-1.11-62.62/931955D7,H;D8@4>3>-;*=*=,>.?+@+?,?+?-A;<@<ABEDGG<<-@.iE4MD3K@/I>.H?1E=2>8-75063-41+30*3/*6.+6/+4,*4-*7.,81.81-81-6/,80,81,71-50-0/-/.,YVSz|luw|RLaPHnlp|bnIGP786+-3,-0/-//-30,61.72/721:53R:/F9D6B3?3?.=*=+=,?.@+A+@-?-?/@;<@=BCFDGE=A5C3tD4UA2NB2LA2JB4F?3?:/96/74-41*1.'1-'5-*5-*4,)5-*7/,80-80-91.80-92-:3-83.62/20.0/- \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Rotate270.miff b/PerlMagick/t/reference/filter/Rotate270.miff
new file mode 100644
index 0000000..5b5fe70
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Rotate270.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=46 rows=70 depth=8
+
+:YVSYWSYZO_eQYdJO[DLVDNXCS_GWgLunŵÿlge|VIa4[sDbDgGkJpPvVqW`J`LbMaI\GX|GWwHQjECV;4D5,8.+4-/90/;.4B1z|llp_ISI|vpolhdd}_g{evhNj4WoBfIfHfGfEmMxUwYbIbJgJeLaK_IbLbN]xTZlSQ]OEPD;K8H\A~>FF~{ttպqnhabEY}CcJeJeKiOoQqKxU}bfN\G_IaI_L\yGWuFXrJ^qR\hTBP<8I1@R:uw|]^g54H`pr~}tstըǚyo~e{ZwVlM^EcIiMgMkOlPjGoIyV}`jSZCZ~CZ|EVsBLi;Gb9H]=>J41?(9L3:M8RLaK@\=1XY\oǰÓokh~{ȏtpk{dy[sThLhGkHfEeCkKmRpOpJrPwYr\`ITu?Qo<Lk<Mg@DV;3>,=J86J2Gb<PHnJ>kH=ipʳɌ~oncsd數yho~fzdx^sZnUlNpQoRdGaEjMpSqPpNpQx\{^nT^MGj=BU86C.9C4=D=)3)G`5lpclkq~Џv{jk\mYʪeYp|fv_rXmQgKcDmKrNlIjFoJwQvPwPxQtTrSsYzmojIX@2>*7@5/2/)-.6D/|}Εv~jhWn\a~Q~mqu`oWhLeD_A]>]=`=g~CfGgKhKiL_yAVd>LW3AM/@J1DM:@M:2>--5,,1,+/.5=6bnY\lMNgcbeqR[f@W\HhqRw\̮|\doyc{ctXiLdyNs`q\Kc9<H,;C19C08@-8B/8@-89)78,54+,-"01$3@3-8-*4,*.*,1,9@5IGxA5I.!4*,0)(+')$"TN:e^:vd᪤tnVPAAQ3XnE}ggQeNp[rZu^h~SO_9QZ4՚|IT<23+9907:/88/79/4;0495-2/16,;C22?4)4-+3+(.(062;E:P78E213-+/-22*10*0''-C))G@-HC/nd_TKUOTue|ui}^Ya7IY1Nb<L_>AJ0EB-78!^Y2yԌj;=.76/=;(:;#:<2;=34;.0>.9H68A2.5.,3,+0+,1+7;6<E<6+-2*,00./2.0/+1+0'+/:&*>3(a=3]n{`pWe{zWpDa?\>U@SAG\;/=<&RP<AB3/4DN)eiO];581KM@KQ56@*89,9A0;K86D2/8,.1,,0+*/).3-9=8;C83,-5/.12002.0-+2(/)+,+/&R.([fYCcSgZibpoudlVeMdHa?a<dAdJ[MG95##/%8+/J3'u_vY'27><^kQCW-9C(BJ64>1-9*.8*/4.-2,,1+271:@::B70/-00./3//0.0,*0(,+**%+!FOZxWxTtUqWorxtrnqs{rk|YtFh>c<d@h@Xk3=364-3%FO)qScB'2%GV4`vFM_:;E0.3+28009*/3-.3-.3-6;5:>99A6//--1.,40-0/2,+-(+.$&3)"PbGoJnMzXzUxZugqbmr{z|{qbwRp;d8eCjCOK@139"`x;sAM+fvIOe=UmD2?)330686/9+/3--2-.3-7;6;A;9A730,11--4.-0,2,+/')*&#?;)WkArEwK}RzNoPmgpags~whuPk7c6gI]]OcKn]YMo_WX@ZnJES;/5,7:237)05,/3,/5,8<59@88C561.62.14/.1+-)'2'(4=0XiM_m:o>qJtJnVnfvnmmjqrkk\WMEH<<382DBV\WlBg=_MXYR\SYSVW[SyeO_\H5@11<.56+16*06,28-8>39?58A572/62/53./1*01(=:3PfPoojr:h>hBbF`Ta\a^VVGH>8-4'4%4%5)9.4*4'=4KMP`UhTVTIZNSNQMUM_RNO>.9)37-07-17-39/7>48>4<?572193193.75+<@3N^Gdexfn4\=VDXO\QSNJ@3:*7&8+912,0./-0/0/5);%<&5)IDYZRJSGOBTGQMYRz\OG@314,17.07,28.7=3:>5CB5:53955;41CB8SZG\{ZegvYh0TAQDKFJNIH=</<.:+:300-0.2.2/4355-9&=!9#6#6'~:*A3H;Q@TLRNUQvTN883)2(*1(27/7=5:?5MI6R:/D7,<?5WeWrpwyv|~M_,H>HFKGHE>=-;*<-6*9131.1202/0-1+6&6$:'=*;(8$7"w3"v5(v=1v@6s=2p8/m=4nLBnk[QYF2@+29'FF5UR9F9H;WNy@V.EADE@HFQIC2;':*>1<3833.1*4*6*7(9&8&:)=*;';(:(};(s9*p4)l2'e1%`.$Y+h;2q_inv\\`G`YDWT<D6D8GDg_{{zr)KFOE;=-@7>2<-:(9)J>QGFBJ@>:635+6-7)7)8*8);+;,:(<){;,y6,o4*k4)g3*a0'f6.gF4_M5]]?ppRigJVV=B3@4@8E@URpzqf`(HBC;.9(:)9(8+8.G=5*8+8)8/7?5?6564406/84;6?7@88+8';*{3(r6+n3+k4,i6-i70l</cJ5]X=EI+GJ+aeF?3>3B1G:E>QOdVzXSZ;E?A>3:#9$=3MKUS4*8&;%8+2=,:;;7835486;597;;=@;8*<,8+u8.q6-n6/k70i60l71fF9UP99C'=E*]e@?.>-?/C7G@KDNEs`IlSc^AKA>>2C@EIHI@B./5*7$8+<740:5657554787<6=88>>837,<,x9/t:.n7+h8.e7,i70g>4P;+EF/@L0LS0=*;*;.<2?7G;G>kS@`jHcJUQCAVMLHPJLA>575;69.;0B:E<80;3<5;4:88<8>96>9A96*:*z:.v90o8-h8-e7-g6/g91^>2e]G^gKEN.=+=*<-<.:.};0{@4pJ9pYCdOUI?6C<7->/5$=)5)64C@IEEAA<82:/:5:685886892<3D9<.8(|9.w9/p6,i7-f7,f5/j7/d=2YG5MO8HO5=,=,=-<,9*v:*s9-[VUPB:9,9,5(:*7+1)8&6&GGSN86UU536430.65=6584848685?6?18,{8/y8/s8/k8-h8/h70m51l:3_D5QN7LO6?.>.>,<+9){;,v8,PLEG.'5!4!7"<(53*07+D685C6:0IGRN7351#8&97;82926:67=7;08,{91{90w:3p;1j8/j70q62q94cA7VO:PN4@+?+>)=+;,9,v>)z4)<H7;6%5 7!2%54-55/=4+.7&-OQfvT[56:$:58A=:76:98<5:.{:+|:/~:0|:1z<4v80o5+h:1n=6h>2\L4SO3A+@+?,=-<-</;*u>.y:4D?0)/(2(2,20423&;20:056$OJoz^f79'?*>36VQC=<5>46)8*z;+|:.~:/}:0{<3z92s7.j<2o?8i>4]K2UO2@-?,>-=/;-?/:+y;/vC9<<++1+-(++058.9!8(1:8O:53.JVFS?F(:+=-;EJZX;-:)<'=,z;/:-:,}9/|90|90u7.o?4sA;l?4XD,RK-?-?+?->-=+=.>-~:/CE8?1+8.-())8;5+9%0'<D\mNS78-7(6BI/0/71?/:HI9*9&A+<,~;1;.:+}9-{9/|9/x8/q?5s?9j90hS;mgK?/?-@*@,?,</A1A5>B>88)4,1'?4>05)<9(0'6Qccp?C9?/7736$1'6;8<86=28&>*:+;2;/:+:+:.~:.}92q@6r=7e3)ѽ@;A;A0B/?3>2B6>6@2>2@43*?7D99"7&;6(>6.W;V>C@BagW^KB:.;0;4:8;8649-yA-:3829.<+~<,~<1;2pB<oA3e6"<@<@>=HAG<B2?5C;E1:(@2?2;28/3$6!;+.8%2-H%723V[do[gPL?5</2);7685<:5C1<1<3~>/=,=/=3?6@=8,yH1=B<A<>E@D7;-94BAC5D7A1:+:3<73)4!8*-1)'*<!+,(QVVb:A73:07(4(<4<<6;61F2A2=/=,;,;1<3B7:;6*u]CFBEE@E9A3@1:7=;?3>3=29*82>98/7)4.,3,$-< -/-JQSW=6=4:/7(9(9->96<>;=/=09/=4B8C<?;E6<9?.ìDGDGH=A3>5A1j9.c6-F9;06';1:4617/;/3/134'19"/CGRX95:&@1:-:):(:)B949@EEA@=A<D>B:@<E@H99.kSE=G<E4;/=0i:-R/(E5'KH?5:$=180;33+41934+9.1/2>DN553*9+<*8(9+8)9'H:9/;5IEBAB>F=E;B=B=@6E4ԼA5<-9(y7-h7/O,'70)<6*C:;#A&>,6*<39/2+:.8(4'607903-)-'608/:-G;D9IB<47*8*HAACA>F?C?>?A<8+ǣC3@.m=+_70K6293,F*.A50GI354!;%;(;->46(;+:%8'4*:.<.7)0%709/6(:(<+=59-?)9C3IHDCFDAB@@80j^tD4iE4UD4Q<5B:659/R).C54EJK]4+<'A-:*?2E9?09%;(6(A3D7=1@7IF7,;+>+=+7&5"56>3LKCEDDBD@<OAUA2MD3EE5H>7A73>3,E1-<94G70B@I@;/=+9#>/@:=1;)7$PAMA4.1,><GF:06+1(5);)<+=/;/@:GK@EDD@D=:޲NB2K@/H;/F91A2/>/.<1/?62=<37=0@?/6<F7<'>59<?;B5D:ME9'6'2+1'<-;*;)8+5+9,:,:+9)>2IFDEDA9:qqLA2I>.C8-A5->0.;/.;0/@61A:1>=15=0B1-aG<KP>>=A>A41;88;3+6+@3XIB25#;#<'7&=$9)7*:(=1HCE;><XUJB4H?1@6->4/;21;1-=5-B80E:1D:/C74040FSR]{;>F;GFC;B8@683B9fXOA<16-;-7&7&8$6*8*:)<0E?@9AEF?3E=2>6-<4/<32=40A90H=4K<4K;1K81:4)EUaHR@1>;@59(8&>/G>I?:1=5^ZzK@0+4*7.9+8)9+C<CBHEZ?>?:/>8-:3,82/811;3.C8/J>4P@5O>1H?-C;*:EQsL];7?FBG<7;.;*:+7.63DA|nj==0+7/:*7%;0NJLL^B5*0+OHF96/75075030.0--6/*A5,H=1OA2OA0P@-P@/8A9RJNOW<?>CCNBJC@>4B2:26:geysfkZcRQ5.4+=):,JMimON?;.:72=6)AJ<o{j74-63-52-2-,/++4,);1+B90I=0M?/IA6K@/BC.:97N_AN@:E><@BG<=7779WZyuYQSVWPYCK<:,40DF]YNOBC<=/5?+KO1rnWpsW41*41+40,2.+.*)/+)4/+?72B<0E</@=9B=-A=(7:Caev=P3?@9C@=G9AHJlgjd|SHpWDd_Cj\E_ORGJLXOZF>@EC3<(CJ2ٸҷ1.'30*31,2.,0,+.+*/00973<70>9,>94:9.<99RLsozi;F>+@F?QMULAydoje^VR\[L`_Hf]Ij^NZOaYUM;?C)K@rM<7>+|ƿɾ1-'3/*3/,/-*/,+/-,01.64194/:7.=7152)@?Mf\ؠ|Rb@G4KKUd\pRpg}~ZjsWR^]Gh\KjdO__OCJ>5C18A'A@%}{jҶ5-*6.+3-,0-..-.--+10*63.95/<71>8362&LIX|œfmqewuqv|ȶ·~xla]lYGn_H[ZF@H8<C5EA1_YC5-*6/+3-,0,,-+,,*)1.*62.<80A91?80944nm𤋮{{~‡ͺȞ΍ȍwn_WfZFSP>@E4DF8VP@faP4,)4,*1,)/--*()+()/*,61.C:3E;0C9-F?OŹ쉆͇|wꚛנֈҋێyo]VGLH7LJ6ZVDhaQf_Rspi5-*4-*1,+/++*))-',1).9//C:3F=/E;+[To쵾䂀meaWwg]qpx|Ư碡ֈ̓ҍzWURQN=`ZFkbNmcTpaUfZP|ŧ7/,7.,2,+.++,*++(,/(/900D;1H<-H@9|xwx^Sd_KHcG>mdpqvzz֘ߝތсʄws]W[`ZGhbKlaRmbUpbRmaTe]Sljedddպ80-81.2,+.++,*+*)--.0:54E=4J=0MHJ䐙ބd_uYLI_N:aM:o`m}cjlv߉݂ځzpdmf\IibHkaXlbVlcTlcTkbRlbQjaQnlh}~luphwodwo|80-81-2++.++**+,+,300<75G?8MB7IE7XWWdar]UjWLSVNQXQTULG[NA^O;]P=aXY}|w|]fiiy{΅듐wj|g]LibLkaTldPlcSlcTlcTmdUmdShfQghPhiQflSdkRelY91.81-2,+,**('(-*+3.,=73E@:JD<MI6MK4TH:WF7SD.SG.WK4ZL8^P<^O;]P=VNA_[awwtz]_[]y|֒ꄁmckg^Mi`PkaVldOkbRkbSlcTmdUmdUneWndXngZlhZlhZhgY80-6/,0,+,**+)+2-*80-A95EA:HC>JI;OK8VJ9TG6ME5LG5RJ9XL<^M<^K<^M=^N9\L9cYa{yspQQ[ZnlecgbYKh_HjbSk__lbUkbSkbSkbSlcTlcUkdZkd[lc\nc\nd\kf[92-80,2-*-+(,*+3/,:2.B:8FA<HC>GG>GD;IA6F=7A=8E@7NG<WK?[L>]J<]L;_L7`P7\OBf]bztlj\]XVmUTA`WBg_JkbTk_ZmbWkbSjbSjbSjcSicRieVgeUjeVjeVkeVlgY:3-81,2,(/*'-+)30-961@=8D?:FA?DC9>?5<;2:5/=60F<1TG9ZL<ZK;[K:]L9^M:_O=`R@`S?e_XgelZ\iLONLM:\RCe[Mh_PjaQkbSjaRibRibRhcSfdRheWheVifWifWhfWlfX83.71-1.+/-)-.-21.961<:5A?:B@;=<689274,52(?90KB4TJ:XM<YI;YI9]L7^M:_O=`RCbVD`S>VL=EC=:=0AE*VP=d[Li`QjaRlcTjaRibRibRhcSgdRheWheVifWifWieWihX62/50-0/,.--..0/1.53.994>>8==888343/30+;6-F@5PI:YM?[N=\L<YK:\K6^M:_O>_RB_RB\M>OD;97501+<=2VN?e[Ki`Qi`Qh_PlbTjdSkcShcSgdRheWheVheVifWhgWgkW20.0/-,-++-/+/2//-34-7829:4681551/.,63-A=3MG:VM?[OAZN>[L<[K:\K6^M:_O?_P@YL<JE<::4+0++.(>=4VM?e[Ki`Qi`Qi`QjaRibRibRhcSgdRheWheVheVheVgdU_iR0/-/.,,,,,-/,/2.0.23-78289367133010-:81D@5OI;WN?[PA[N>[L<[K:\K7^M:_O=[M=TH8DB647-*0&.2&@>0UM>cZKh_Pi`Qi`Qi`QhaQhbRhcSgdSheVheVheVgdUddS\gO \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Rotate90.miff b/PerlMagick/t/reference/filter/Rotate90.miff
new file mode 100644
index 0000000..399f7b4
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Rotate90.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=46 rows=70 depth=8
+
+:\gOddSgdUheVheVheVgdShcShbRhaQi`Qi`Qi`Qh_PcZKUM>@>0.2&*0&47-DB6TH8[M=_O=^M:\K7[K:[L<[N>[PAWN?OI;D@5:8110-33067189378223-.0.,/2,-/,,,/.,0/-_iRgdUheVheVheVheWgdRhcSibRibRjaRi`Qi`Qi`Qe[KVM?>=4+.(+0+::4JE<YL<_P@_O?^M:\K6[K:[L<ZN>[OAVM?MG:A=363-/.,5516819:478234-//-+/2+-/,-+0/-20.gkWhgWifWheVheVheWgdRhcSkcSjdSlbTh_Pi`Qi`Qe[KVN?<=201+975OD;\M>_RB_RB_O>^M:\K6YK:\L<[N=YM?PI:F@5;6-30+43/883==8>>899453./1...0.--0/,50-62/ihXieWifWifWheVheWgdRhcSibRibRjaRlcTjaRi`Qd[LVP=AE*:=0EC=VL=`S>bVD`RC_O=^M:]L7YI9YI;XM<TJ:KB4?9052(74,892=<6B@;A?:<:596121.-.-/-)1.+71-83.lfXhfWifWifWheVheWfdRhcSibRibRjaRkbSjaQh_Pe[M\RCLM:LONZ\igele_X`S?`R@_O=^M:]L9[K:ZK;ZL<TG9F<1=60:5/<;2>?5DC9FA?D?:@=896130--+)/*'2,(81,:3-lgYkeVjeVjeVgeUieVicRjcSjbSjbSkbSmbWk_ZkbTg_J`WBUTAXVm\]ljztf]b\OB`P7_L7]L;]J<[L>WK?NG<E@7A=8F=7IA6GD;GG>HC>FA<B:8:2.3/,,*+-+(2-*80,92-kf[nd\nc\lc\kd[kdZlcUlcTkbSkbSkbSlbUk__jbSh_HbYKecgnl[ZQQsp{ycYa\L9^N9^M=^K<^M<XL<RJ9LG5ME5TG6VJ9OK8JI;HC>EA:A9580-2-*+)+,**0,+6/,80-hgYlhZlhZngZndXneWmdUmdUlcTkbSkbRldOkaVi`Pg^Mmcky|[]]_tzww_[aVNA]P=^O;^P<ZL8WK4SG.SD.WF7TH:MK4MI6JD<E@:=733.,-*+('(,**2,+81-91.elYdkRflShiQghPhfQmdSmdUlcTlcTlcSldPkaTibLg]Lwj|ԓy{ii]fw|}|aXY]P=^O;[NAULGXQTVNQWLS]UjdarXWWIE7MB7G?8<75300,+,**+.++2++81-80-|dwohwolup}~nlhjaQlbQkbRlcTlcTlbVkaXibHf\Ipdmzтډ݋lvcj}o`maM:_N:YLId_uޞ䀃MHJJ=0E=4:54-.0*)-,*+.++2,+81.80-ٺ蠧dddljee]SmaTpbRmbUlaRhbK`ZG]W[wsǁʌѝޘzzqvmdpcG>_KH^Sdwxԣ|xH@9H<-D;1900/(/+(,,*+.++2,+7.,7/,맳ń|fZPpaUmcTkbN`ZFQN=WURz΃҈͢篬|pxg]qaWwme䤤[ToE;+F=/C:39//1).-',*))/++1,+4-*5-*spif_RhaQZVDLJ6LH7]VGyoۈҠᶚǃ|wĉ͙줭F?OC9-E;0C:361./*,+()*()/--1,)4,*4,)faPVP@DF8@E4SP>fZFn_WwȞ򤺯ͳ‡~{{ؤnm944?80A91<8062.1.*,*)-+,0,,3-,6/+5-*_YCEA1<C5@H8[ZFn_HlYGla]~x·ȶv|uqewqfmЮ|LIX62&>83<7195/63.10*--+.-.0-.3-,6.+5-*Ҷ}{jA@%8A'5C1CJ>__OjdOh\K^]GsWR~Zjpg}pRd\KU4K@G|Rbf\@?M52)=71:7.94/64101./-,/,+/-*3/,3/*1-'ɾƿ̠|7>+rM<K@?C)UM;aYZOj^Nf]I`_H\[L^VRojeydLAMU?Q@F>+;FiozRLs<99:9.>94>9,<70973/00.+*0,+2.,31,30*1.'ҷٸCJ23<(EC>@ZFXOJLRG_Oj\Ed_CpWD|SHjdlgHJ9A=GC@@93?=Pvae7:CA=(B=-@=9E</B<0?724/+/+).*)2.+40,41+41*ᴰpsWrnWKO15?+<=/BCNO]YDF40:,K<YCWPSVYQyuWZ7977<=BG<@E>@:ANN_:97BC.K@/IA6M?/I=0B90;1+4,)/++2-,52-63-74-o{jAJ<=6):72?;.ONimJM:,=)4+5.RQZcfkysge6::2B2>4C@BJCN>C<?OWRJN8A9P@/P@-OA0OA2H=1A5,6/*0--30.75075096/ɖOHF*0+^B5LLNJ;07%:*7/0+==nj|DA637.:+;*;.<7BG?F;7L]s:EQC;*H?-O>1P@5J>4C8/;3.81182/:3,>8-?:/垙Z?>HECBC<9+8)9+7.4*0+K@z^Z=5:1I?G>>/8&9(@5>;@1HREUa:4)K81K;1K<4H=4A90=40<32<4/>6-E=2F?3AE@9E?<0:)8*6*8$7&7&;-6-<1OAfXB983@6B8C;GFF;;>]{FSR040C74D:/E:1B80=5-;1-;21>4/@6-H?1JB4XU><E;HC=1:(7*9)=$7&<';#5#B2XI@36+3+8;;841>A=A>>KPaG<B1-5=0>=1A:1@61;0/;/.>0.A5-C8-I>.LA2qq9:DADEIF>29):+:,9,5+8+;);*<-1'2+6'9'MED:B5?;9<>5<'F76<@?/7=0=<3?62<1/>/.A2/F91H;/K@/NB2޲=:@DDD@EGK@:;/=/<+;)5)1(6+:0GF><1,4.MAPA7$;)=1@:>/9#=+;/I@B@G70<94E1->3,A73H>7EE5MD3UA2جOA@<BDDDCELK>3655"7&=+>+;+7,IF@7=1D7A36(;(9%?0E9?2:*A-<'4+K]EJC54R).59/B:6Q<5UD4iE4tD4j^80@@ABFDDCIHC39?)9-=5<+:(6(9/700%7)<.:.4*8':%;+6(>4;-;(;%4!35GIA50F*.93,K62_70m=+@.C3ǣ8+A<>?C?F?A>ACHA8*7*<4IBD9G;:-8/60-'-)0379604'8(:.2+9/<36*>,A&;#C:<6*70)O,'h7/y7-9(<-A5ԼE4@6B=B=E;F=B>BAIE;59/H:9'8)9+8(<*9+3*55DN2>1/9.4+93413+;380=1:$?5KHE5'R/(i:-=0;/E4G<E=kS9.H9E@@<B:D>A<@=EA@E49B9:):(:):-@1:&95RXCG"/194'133/;/7/61:4;16';0F9c6-j9.A1>5A3H=DGDGì?.<9E6?;C<B8=49/=0=/>;6<>99-9(7(:/=4=6SWJQ/- --<,$,34.7)8/>9829*=2>3?3=;:7@1A3E9E@BECFu]6*:;B7<3;1;,=,=/A2F2616;<<<44(7(:073:AVbQV,(!+*<)'-18*4!3)<7:3:+A1D7C5BA94;-D7E@<><A=ByH18,@=?6=3=/=,~>/<3<1C1:55<68;72)</?5PL[gdoV[23%7-H%2.8;+6!3$8/;2?2@2:(E1C;?5B2G<HA>=<@<@e6"oA3pB<;2~<1~<,<+9.82:3yA-9-64;8:8;4;0:.KBW^ag@B>C;V.W6(>;67&9"D9?73*@4>2@2>6B6>2?3B/A0A;@;ѽe3)r=7q@6}92~:.:.:+:+;/;2:+>*8&=2868<6;1'6$73/79??CcpQc'6(0<95)>0?41'4,8)>8>BA5A1</?,@,@*?-?/mgKhS;j90s?9q?5x8/|9/{9/}9-:+;.~;1<,A+9&9*HI/:1?/7/0BI(6-778NS\m<D0'9%5+8;))-(8.1+8?CE~:/>-=.=+>-?-?+?-RK-XD,l?4sA;o?4u7.|90|90}9/:,:-z;/=,<':);-ZXEJ-;+=(:?FFSJV3.:58O1:8(9!8.05++-(1+++<<vC9y;/:+?/;-=/>-?,@-UO2]K2i>4o?8j<2s7.z92{<3}:0~:/|:.z;+8*6)>4<5C=VQ36*>'?79^fozOJ6$050:;23&42202,2(/(0)D?y:4u>.;*</<-=-?,@+A+SO3\L4h>2n=6h:1o5+v80z<4|:1~:0|:/{:+:.<5986::7A=58$::56T[fvOQ-7&+.=45/-5542%7!5 6%7;<Hz4)v>)9,;,=+>)?+@+PN4VO:cA7q94q62j70j8/p;1w:3{90{918,;0=7676:92827;&9#85173RNIG:0C685D67+*053<(7"4!5!.'EGPLv8,{;,9)<+>,>.?.LO6QN7_D5l:3m51h70h8/k8-s8/y8/{8/8,?1?685868484655=.6306453UU86SNGG6&8&1)7+:*5(9,9,B:UP[Vs9-v:*9*<,=-=,=,HO5MO8YG5d=2j7/f5/f7,i7-p6,w9/|9.8(<.D9<392688885:6:5:/82A<EAIEC@645)=)5$>/7-C<?6UIdOpYCpJ9{@4};0:.<.<-=*=+EN.^gKe]G^>2g91g6/e7-h8-o8-v90z:.:*6*A9>9968>8<:8;4<5;380E<B:;09.;675>5LAPJLHVMCAUQcJ`jHkS@G>G;?7<2;.;*=*LS0@L0EF/P;+g>4i70e7,h8.n7+t:.x9/<,7,83>>886=7<78547565:540<78+7$5*./@BHIEIC@>2A>AKc^lSs`INEKDG@C7?/>-?.]e@=E*9C'UP9fF9l71i60k70n6/q6-u8.8+<,8*@;;=7;596;483578;;,:2=8+;%8&4*USMK=39$:#>3?A;ESZzXdVQOE>G:B1>3?3aeFGJ+EI+]X=cJ5l</i70i6-k4,n3+r6+{3(;*8'8+@8?7;6846/4064655?7?8/8)8+5*G=8.8+9(:)9(;.BC(Hf`zqpURE@@8@4B3VV=igJppR]]?_M5gF4f6.a0'g3*k4)o4*y6,{;,<):(;,;+8)8*7)7)6-5+63>:J@FBQGJ>9):(<->2@7=-E;FO)Kzr{{g_GDD8D6WT<`YD\`Gnv\iq_h;2Y+`.$e1%l2'p4)s9*};(:(;(;'=*:)8&9&7(6*4*1*3.83<3>1:*;'C2QIHFE@AD.E@VyWNH;F9UR9FF529'2@+QYFnk[nLBm=4p8/s=2v@6v=1v5(w3"7"8$;(=*:'6$6&1+0-2/20.131916*<-;*=-E>GHFK>H,HM_~v|wyrpWeW<?5D7,R:/MI6:?57=527/*1()2(883vTNUQRNTLQ@H;A3~:*6'6#9#=!9&5-35/4.2.2-000:3:+<.</H=NIFJDKAQ0TYhveg\{ZSZGCB8;41955:53CB5:>57=328.07,17.14,G@3z\OYRQMTGOBSGRJYZID5)<&;%5)0/0//-0.2,918+7&:*@3NJQSO\DX=V4\fnxdeN^G<@375+93.931721<?58>47>439/17-07-37-.9)NO>_RUMQMSNZNTITVUhP`KM=44'4*9.5)4%4%4'8-H>VG^V\aTaF`Bb>h:hjrooPfP=:301(/1*53.62/72/8A59?58>328-06,16*56+1<.5@1_\HyeO[SVWYS\SYRMX=_BgWlV\DB82<3H<ME\WkkqrmjnmfvVnJnJt>q:o_mXiM4=02'(-)'.1+14/62.61.8C59@88<5/5,/3,05,37)7:2/5,ES;ZnJWX@o_YMn]cK]OI]6g7cPkhuws~aggpPmNoRzK}EwArWk?;)*&#/')2,+-0,-4.11-30,9A7;A;7;6.3--2-/3-/9+6863302?)UmDOe=fvIAM+s`x;39"K@1COCj8e;dRpbwq{|zr{bmgqZuUxXzMzJnGoPb3)".$&-(+2,+-0/,40-1.//-9A6:>96;5.3-.3-/3-09*280.3+;E0M_:`vFGV4'2%ScBqFO)-3%364k3=@X@h<d>cFhYtk|rs{nqtrrxWoUqTtWxZxFO%+!+**0(,0,*/0./3/00.0/-:B7:@:271,1+-2,/4..8*-9*4>1BJ69C(CW-^kQ7><'2vYu_J3'8+/#/%95#MGJ[Ad<d?aHaMdVedloubpZiSgCcY[fR.(+/&)+,2(/0-+02.1205/.3,-;C89=8.3-*/),0+.1,/8,6D2;K89A089,6@*KQ5KM@581O];ieDN)/4AB3RP<=<&\;/AG@S>U?\DaWpz{We`p{]na=3>3(:&*'+/1+00/+/2.00.2*,6+-<E<7;6,1++0+,3,.5.8A29H60>.4;.;=3:<2:;#=;(76/;=.jԌy^Y278!EB-AJ0L_>Nb<IY1Ya7^}ui|ueOTKU_TndHC/G@-C))''-0*02*1/-23-+E21P78;E:062(.(+3+)4-2?4;C216,-2/4954;079/88/7:/99023+IT<|՚QZ4O_9h~Su^rZp[eNgQ}gXnEAQ3VPAtn᪤vde^:TN:)$"+'0)(4*,I.!xA5IG9@5,1,*.**4,-8-3@301$,-"54+78,89)8@-8B/8@-9C0;C1<H,Kc9q\s`dyNiLtX{cycod|\̮ꚟw\hqRW\H[f@eqRgcblMNY\bn5=6+/.,1,-5,2>-@M:DM:@J1AM/LW3Vd>_yAiLhKgKfGg~C`=]=]>_AeDhLoWu`q~ma~Q𑞘n\hW~jvΊ}|6D/)-./2/7@52>*IX@ojzmsYrStTxQwPvPwQoJjFlIrNmKcDgKmQrXv_|fpeYʪmYk\{jv~kqcllpG`5)3)=D=9C46C.BU8Gj=^MnT{^x\pQpNqPpSjMaEdGoRpQlNnUsZx^zd~foyhsdnc~oɌʳipH=J>kPHnGb<6J2=J83>,DV;Mg@Lk<Qo<Tu?`Ir\wYrPpJpOmRkKeCfEkHhGhLsTy[{dkpt~{khoÓǰY\o=1XK@\RLa:M89L31?(>J4H]=Gb9Li;VsBZ|EZ~CZCjS}`yVoIjGlPkOgMiMcI^ElMwV{Z~eoyǚӌst}t~`pr54H]^guw|@R:8I1BP<\hT^qRXrJWuF\yG_LaI_I\GfN}bxUqKoQiOeKeJcJY}CbEahnqպҰtt~{>FF~H\A;K8EPDQ]OZlS]xTbNbL_IaKeLgJbJbIwYxUmMfEfGfHfIWoBNj4hvg{ed}_hdolvp|ISIlp_z|l4B1/;./90+4-,8.4D5CV;QjEWwHX|G\GaIbM`L`JqWvVpPkJgGbD[sDIa4e|Vlgÿŵ䵺unWgLS_GNXCLVDO[DYdJ_eQYZOYWSYVS \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Sample.miff b/PerlMagick/t/reference/filter/Sample.miff
new file mode 100644
index 0000000..86803b7
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Sample.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=35 rows=23 depth=8
+page=35x23+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-62/:3-80-80-7/,4,)5-*1.'74-?:/JB4NB2tD4A5DG=B@;?-A+?.=+?.B3F9:5372/30,0/-6+-IG|PHnuw|z|l,,,0/,2,(0,+2++2,+1,)3-,31,52-:3,@6-H;/UD49(H=<>A0?-?,>,<-?/@8WN;4153.-4./3/00.I.!H=54HISI,/2..0-+)+)+**+,*+*().-.0,+/++811;21A2/B:6h7/>5D7?3=+<-9):.G@URSZG01(2,+0,*0/+0)(ʳ23-53.96180-300/(//*,10*/00;1+C8/=5-<1/R).70)j9.94B6>-;*v8,{@4NEzqegPfP*&#+**'+/)$"~j~o}tol893>>8D?:EA:G?8D;1C:395/<70I=0P@5E:1=<3EJC:F9C5@2CEy:4EGpYClS(H@VYhjrWkFO>3(e^:n\sdd}_330883DC9JI;IE7H@9C9->83>94IA6H?-C74@?/4+A&6'A1@41+0)5!UIAK;.ADAQ>hEwWx]n:8130+<;2VJ9darLIX<99BC.:EQFSRF7A-6*:4:3?7-(2(7"C<>2:)HFFJF`RzUq`p᪤OI;F@5=60ME5WLSozN_L];>>5?29/7/3)9"8;2053>/EI8+C2H=\aPmrx{VPA[PAYM?TG9RJ9XQTԙ숐i@:?FGF?;?0:.3/8*;69%3&7+=)@BG=:*<.VGagnqWpXnE[L<\L<ZK;^M<[NA^Sdīq>+<@<7B8D:;(4'4')'6<D0:85645*8+<3:38-r?\gQa~Qyhy\K7\K6]L9^M=]P=cG>uq?Q<=;*839'A379"/!+;VNS6$:0IE8+8/3.-04%Yt@Sp[q~f~e_O=_O>_O=\L9}|qvȶLA797.fX2+=1-)RXQV@B-7ozRNA<405?4*.25)>c\;/u^oWx^wVhTH8_RB`S?{y]f·ojeyuDA<1<-IF60:&:AW^BI7951:/65647(354*hu@hRP<O_9eDnU^EWoB47-OD;gelQQy{Όш҇\[LSV;-;);+:-:-:0:./7*>&9:6546/8&9&=47ck3=/4]>pQiMfH.2&01+LONnlǎla]f]IYC==7&5+=+D9:(4(;4/:VQ82887<;6=*9#P`I]-3%e|`=dGkOfEUM>VN?\RCbYKwj|]W[]VGn_HZO:,7/6*:,5"<4B9<<;89*<56:9288@8;(6'TVcKqO];23+fGjMjGxUh_Pi`Qh_PjbSibLhbKLJ6@H8UM;DF7%:)9)68*@E619-A+6)=7D9838'};(A3ZNYM'2%KM@7:/hKqPyVbIi`Qh_PkbSlbUldPmbUhaQEA1K@NONJE?IFLKAC@=A2:3~;1z;+8,8(<,{3(p4)Q@QMWX@`vF6@*79/_yApQjSgJhaQjdSibRkbSlcTmaTspi7>+<=/^B5AEDADDF?D>=,9.:+~:/{90w9/t:.n3+e1%RN_RES;;E09A0495LW3{^Z~CaKhcShcShcSlcTmdUljeKO1OHFqq@<>?@<;1~<,{9/{<3p;1i7-h8.i6-Y+vTN.9)7:22806D216,@J1^MVsBbLheVheWheWkdZhfQpsWذ8+H9B7;2x8/s7.j70f5/i70l</q_)2(07-05,/3-.1,2?4@M:BU8Gb9]xTheVheVifWlc\hiQkS6*oA3s?9o?8q94d=2P;+]X=nv\27/39//5,.3-*/)+3+-5,9C4>J4Q]OddShgWhfWnd\dkRƿhS;]K2VO:MO8@L0GJ+`YD:?58>49@8:>99=8062+/.)3)9L3;K8 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Scale.miff b/PerlMagick/t/reference/filter/Scale.miff
new file mode 100644
index 0000000..d5740df
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Scale.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=35 rows=23 depth=8
+page=35x23+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-72.92-80-81-6.+5-*4.*30*75.B<0J@1OB2C2B7CF<A@5?,@+>-=*?0C5p@494362/00-2/.?01QRxuNEfz}|ff\,--0.+0,(/++0++0,+1-,1.,3/,41.;4.A6.G>3]=1<.E:B?A->.>+=,</C4MGkaU<8112--2.02/0/.TB?ROyU`c_h[-/0/0.0-+-**+*,,)+,)*.-,/+*2-+;30<1/@3/?71j7-@3B5>0=-;-:*?4JDrN]G3/+0*+1*,1,/GJ6ǡi|a560972=84:406325,/3/-32.730B7.F;2?5/?41G/0C3)v:3?9A5;.{;+G?xI;cOsuoShO3,%),'3(,OP>sbvjyv\oV792@?9FA=GB<I?5E<0A:1:6/@:/M@0M=3B;1O=5CIB7@4B1?8?><>C>{cIWT6I:QIbOnLlJUL=.}~dz]pV22/883DC:MJ7\Z_YR]@98:5-?;2M@0D:,;60>78&>*:-?08-1,3&7'KD@?>0CFBSBlJwRtil뜢=:273+A<4UH8|}]XB?FBB;ldQV>+<+90:4:3=3,)3'9'G@=.</IEMQOgSwVlT`RK=HA5B<4PF2mmGQDF?>=7>25.8.4$9(52232.D8FD:,>,E:dg^qnt€{~[O@XM=UI<WK8d_oÌ|uE[BB@??=>3;)8-1140277%8/:+:/><@4;-:*_Xjsgoqnֱܳ[L;ZJ;[K<^N<\N@cWpSk@;AD:-=8F97(5-00)7/J@O11E@;68&B78270MF]pYRrXqbov]L8]L8^L9\N=dUOj`rghAL=7?191</?27>-4)/GS=<@6DAC<83>:1.//?3GhOBxb{f}fe^O>_Q@_P>e^evxǶDZ^V@@<4SE5/9.1,JMXaBH9Fbl=:>757653,/19/m~AbJH1s[nSvZqR_zJOG:_RAiacpqosæ߼ѓy_YmhXS:->3<49-=0GJD>6>-:.4;3666/6(3/A<KjAKDC/[nBdEkN_G_xE14-IC;bb{`a܆ϋ~k}d\G[]pi:'7*:*=/9+;/70.<.:2::6687.9';%HU=a>11^e<vfElLgLhH67-:<.QRNzxӂ~sh]Nn^KK@4/9%8*;,@3:*7/98FIEA838;6;;0<);-L`sH@MT5qXjGgDeGlPnN]TE]UEbYGh^Smb`YULYRAe_KVO8,8-8*;,9&=2;:7;:1:*:777;5<<;.9&G=WQ{VcyK>B28=/mKnPqLpTi`Qi`Qj`TjaVjbPh`LKK:=F7xQ>IF9*;-=1<)A9@<>2=,>+9.>4>39-;*w7'K>WRpcHAL:CE08=/pNqNvZbKi`QkaSkbTlcRlcSobTc\MGG0G@RSHEE>EGGGB@>6>1:2~;/{:-8.9,{9-u5*r9.SHZOUfCJ\59=/7;-hItY`JbJibRjcSjbSkbSlcTof]¹SU@;</b>9VU@ACDE>A9=-:,:-}:0x90s8.p7-k4+j5+WPXSB6?08@16A136/]tDgO]G\IhdShdShcSmdUlcSݾOO;ݘB;A=B=<2~;.|90y:2k9/g7-h7/f5-g<2J@829,49//9,6A226)[oQQsAUsCVqGheVheWheVmdYoobΘ˸XIA6?9x>6s;2m9/l61h70i=4eF3pmZ-4+17,/3-.3--2,/;0;H4BU8QiEFXCheVifWjfWme[ipa˛K9k:-o>6l>5h>5`H8IE/\\>LT=5:15;1381160,1+*1*06/:D5CP;<G<bfRhhWkfXkf[jvh`R8XM3QO7NU:JR3Z[>UQ<AB59?59A8:@8:@94;3070;P3;M6:I6 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Segment.miff b/PerlMagick/t/reference/filter/Segment.miff
new file mode 100644
index 0000000..932bb49
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Segment.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Shade.miff b/PerlMagick/t/reference/filter/Shade.miff
new file mode 100644
index 0000000..89120d7
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Shade.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Sharpen.miff b/PerlMagick/t/reference/filter/Sharpen.miff
new file mode 100644
index 0000000..91d396b
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Sharpen.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Shave.miff b/PerlMagick/t/reference/filter/Shave.miff
new file mode 100644
index 0000000..62676e3
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Shave.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=50 rows=26 depth=8
+page=50x26+10+10
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:H@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOT틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{uevAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|ԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1mdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>zz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-ޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2ʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)yǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ij]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/hbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(laRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#mbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<2pbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=3 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Shear.miff b/PerlMagick/t/reference/filter/Shear.miff
new file mode 100644
index 0000000..f7a6685
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Shear.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Solarize.miff b/PerlMagick/t/reference/filter/Solarize.miff
new file mode 100644
index 0000000..5589985
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Solarize.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Swirl.miff b/PerlMagick/t/reference/filter/Swirl.miff
new file mode 100644
index 0000000..fd4756f
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Swirl.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A:?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/FE5WC3p=+;*F6G>C@<>?:A/@+?->-?+>*>,=-<-;.?/B2@9GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/B6.F:2J>6U;4h7/9.>1C6E<F@E7A-?-=.=.=,<+<+<-<0>4D8G<LFmcvVcVCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++1--911<32<20?1.B51C95I84_70;0>4A4D7G<@4?-=+;-<-;,9*9*:->4E=G@PJqel{hPXE;@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*0+)4,)70+;3/<3/;0.=/.?2.980<4-S.(p;.@2?1>/A3=1</>.>/;.:,y:,w:,~=2G<KDTO{jlmYuVLYE<:32((/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01.0//5/+<2+@5-A8/>5.;1.<0/C1-I-.A-,H0)d6,|;3:4>4A5A2>.;+;+y<)<0?5{B6}G;OB\Lr\osplj`~`K^I5</,'$.%&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641962>60D9/G<2F<3@7/>40>51D31E10=3+G3(d7-<:@=A9?6?3|:/x</z;.=8PMWOoQ=g\C}dLhWTVP[bgxp}qqtqtakVGV;2B.*0.&/.&;'*C*)TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C93A92;7084/:50>91E;0K?1M?5I<3B91?82@82`<=l><f=3@7?5A8D5A3?>BDC:<6;C>?JEYHxcIgQZUBK8F;M6L7O=VE_MfSmQnPnOiM`DL[4/B5*IB.f_<w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F<0D:1>81:6/<7.B;/K>/OA1N>3H;2A;1<<2_;7EM@;D;B7?3C5>,>4<<:>><=94/5*F:\LYOLQ@E=8A8C@=E;H=P<U;_=j=qBtGpRtZsS]lD<XP>nӰg{eWgL330551883=<6DC9GG>JI;MI6IE8LFFH?5E;,B9/>81<71>90C<3L@1N@/L<1E:0==1K?4EJ:=;%=0:.@3@0?2;.3-,+/)5$5!8*C8GBDB@<=19(=-C:FEEKDLDWB_EkHvJ{LvSvQt\vgmz҅un10-/.,43/892>?5GD;OK8MK5ZY[xxid~OGR@9:;5.:5.=92B>6L@2K?-J90B849>0zE9805!?&9':.>/@28.5,5-0*2%5!6$9-D=TLA5;(:&<.A9JFGEGHKOO[I`JjNtSzVyUrOh`sdjz:8163-30+74,<;2IA6VJ9UJ>ji~ٔxvYVk@==851<:/E>.N@/E<+<5+840c75>4:'<'=.;19+;.;16-1).(1(5$8$9(9-A:IFB=:)9);-B5G:@4H?MIRUXc[oRoRsVvWoXiYhS]mnܷD@5A=3;6-52(:5/F=7TG6XH>jfꫳ熆XUoB@O>:3B@,?A5=BE@HIJA;?9<,=):)90:392:2?69/+)++2,3*8.8+=.J@JHFED=8-:*;)<)<+>0A5OG`^kq^o\qfuovbpszlhbXOI;MG:F@5?90=60B=8OE5UF7fayஷ{]UDBR<<5EECa]vo_qLJB1=*<+9.9294<791A4=224033114/02)6%D9DAJJPLF<<-;+;,;-<-:+G8\Pmjdjdmjpprmux}aiOzWN?VM?PI:KB4F<1E@7MG4TH6datةxxW[VDMzLRmeKS<(:';-;280927/4&9$:/616021115+8&:):3542.5*6*G;E9;08-:.8*</MEpqs|pzoxks]iTl~kbvQ[PA[OAYM?TJ:SF8MF;QI7VK:ebsϡyQdMUKYCJ?@>2>/>38/5-8.4&5"7&7,8'7$5+;2@29,7/94816(9&8)B8E?935141608-9.`]{~wkyPdC_qnʾ[N>ZN>[N=XM<YK<UJ>VK:XL<a\hܚ횤⛞㞞ߵM\>A?=C;>?;9A6;/3,608,5&9':4955&9)943185GDEB?:9-8(9(8+;1I?9300.1./3-4'I@rpwgyJb@ZhRnSrWiyƗӷ[L<[L<\L<YI;ZK;ZL>\M<[N<ZQQkhш}vVwBG>B>>B;@A<<@6=.7,724/5-5//:(142360:2->/C:@=FCB:>5:54;5>9<:52+2//2//2)</^WvXsDd@WR?_tEsYfwgwglsxŵ[K:[K:YK:YI9[K:]K=^L<^O<[NB[OTjb{~uoO^>N=@AF@F@;A@?;=/=,:+7.22-2,2%8!6;GCS5C3)->6JHOND@C<?732/:4<645-3,00.10-5)>4pNm?e?T|PA\vFwaon~jknmrÿ\K7\K6\K6\L7]L9]K;^L<^O<^O;_M@aSeunsDM=4<=BFAF?4@9:3=-9%9&6)4-.**''7$JPcVb?><3LGW^VYGC649481929699656-6*2+02015.80^aj|Ml@c?NaJ8ZqGu]xbwbxb|e}h~cn^M:^M:^M:^M:^M:^L9^N<\P?^P?aL;cORniqBW?<A<?C@A:.@5:7A59&9'5'7.2.,4+>-HA\Zd?B77OVju^hKO624170:1:46556517*7'3*322-7/KKdvEi@bGPC?*M\<r[x`pXtZyaz`zYgulg_O=_O?_O>_O=_N<_N7]N:ZRLdZ^l]ej]hqqYa@MADAEC?;-;,=8E?H97(5*5/03*6$1#00>?F=B2:2>ANHP=@17+6+646;5:555446,8'7%6)6)5(OQVk<e@c|KEOM8DF/_sIrUhMnSu\vXtT{]|de|U[M=_P@_RB`RB`Q?^O=_RJebo}|}wppwࣀnpQV@L<A>8<.<,;462D7I;;.824;-9+3*+0.CFDFCH/75;@G4@)>#<#9-:79:58558637*9'8%:%<+HLIf@g<WX7/CB2>=(NZ6gKeEhLpWnQhKaEOj5Ia4TH8YL<_RBbUD`S?bWTmfyvwv{invxɏΥĸáhVKN:@:6?0>0A7916)=0A6>162;ACJEIEJQWZccm\dKL6*0/,9*>+:0:5885987969919*;(<"<&HLEh;b<PB10.4"HG*fpIeyN`CdElPhJ`F[~DXpC[sDDB6JE<\M>`S?d\Qqj|wtos`his׮ܦ}dRNL:<;39.F<RG?35*3,=2;-2*0.:8CCLNLPAINTQNE:3(06-<38:;8684898<6::79)=*;'7&IO@b>`}?C52299*foCuiaEhHnOiHeJcJfIbD47-::4OD;WM=fbepmec^`hiԔܪ˽zqedbIL7693F<XII<2)85>66+/&1*6+9)<.=593?8>3:/6;0=@GQL=883778=6=::=0;(;(:*JOI^MYH?/33'TK7bʼnobEmJoQjHiMeJfHgG*0&+0+:75FD=[\gaaXXcduwʄ؍דӘԜҟɖvr{mc^g`xtdbGD=7@5F9D5;0EDHE=8708/;+=-</:/9,:-:/976<GJLH;885858689:<?5;*9&6&RSS\YQ==(CM+m|Oo{fT[z>kHkMfEhMeKfGkJ.2&+.(01+;=1MPQXWqdc}}І胄҅·ҊьÈ{`taZUpUIVNgazurnVQ:17(9(;-9/8,8,8,:,9*:*9)7(4(4-:797EAD<:86:86:3;9=<;1:)9%8'WUVS_Nbk<}Wu[{[hvRER6Yn;iFdFfEkNjOfEpP@>0>=4<=2AD*KM<UTJect䈅ڂ̆ʊΌʊyw`ch[Pc\GXIVXdj~zzaV;*;$;(7*7*<+:(C5@39):(9*:0;7:8<49*;,<57886>4>:=79+;(8%:)RIVLcV^wYZsDGP79;.9?/Wk>kGeHkLlOoQmMvVUM>VM?VN?UP<ZQB^VBb[Prk~zyyszv|wzn}pcad^Oc]Hf]Hm]EXIWW[\VQB88(9&9)6*4);+<+?2E:9(;+<2<98:879,9&;):0;6=6C9?78.8(<)z8&<-RFYN]StqQIX<+5%68187/8>/WlAoLmNmQkHqKxUqWcZKe[Ke[Kd[Le[Lf^Ig^Ih_Tmb_nbbf]][VV[WTd\Si\Nl\Jj]Jj]Mn^N|_NRAE;<8522+6'9%:&8,:*9'9*=3@8F8@9::7;6;74;*@*<(8,;2>3>18-:,;*{;+u7)A4PCVP]U_\=/;(:@=EF8::,8>/YnBsOqRpOpJxUwY`Jh_Pi`Qi`Qi`Qh_PkbSjbRi`Ph`Mh_Je^I]XEQN<MI8VQ?_ZEd_Kt`PZPQH@37,5,6.6.6+8)9):,<,8&7$<+8,9/8;;=85:4<.<+=,<,9+:.;/:+9+:,}6)x7+t8,I:QETPaWlrLHW4VaJFI19:*8>.[qCtOqPpKyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk_^kaVkaSjaRjaOg`L]XDLK7@E4CJ9IN@[SEVKPM><:/;)9)9+8*8*8*:*<.8$8 9#9->:BC>4D2B1|?/;/;/};-{:+8-8-9+:-{8,w4*r4*t;/QCSIVOhZGQd>ZoBGW5=B-9:-8>/]sDuOpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldPldQlbUlbUlbRg_NYUEGH9>C57C2=D/aL6YJSPGC>49*8*:,;,<-</>6=0@1F;GCEBA:>0@2;2:2;0~;.|:-|:/{91{8/z:.w9/t7-p5+l3(t>4TLSM^N`jJTkBOa:;F+9=/8;08=-Xm=vPqQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTnbSobTkaSd]NYTCKG5<A(kH8E@EERR`cQOE=@8B;E=F@FEGIKJIHBCB@A=<4</<292:/;-:,}:/}:0z80x9/v90s9.p5,l4*f1%w@6TO[Qk^KL[@AQ4BN3;A.9<05;179+R_;sSx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTi]Rmf\~zox}xgXU>_J7|E<C@EENMLLFEB=B:E=DEAEBEDDDAC>D=B<<2=-=/:-:+:,~:.}:0y:2u8/q7-p8-o7-l4-h3*d1&D=YPeVGFK:8A23;-:B1;E35>/39378-KU3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRf^S|xqɪebN<D.9>-<;/E;0a@6GDKMFEB@BACDCDDCE@E=D<A8>1<,<+;+~9-}9/|;1{;2r:1m7-k7-j8-l7/i5,a/&e4*}MFbMA=D33=/36015/1:.8G52A0.3/44+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQljdеnvVAG.<9.;94ZQN~{ܣއTTCD@@AA@@A>C<A;B:;0=/~<,~:.{9/|:1z;3r:1k9/h7-f7-g7-j60f5-b3)kA8[HB<;/19+4:.592380.9+4B09G617,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddɤ[[EIL?|zsż䪣thH>;6?<B=C>A<=6=3<2~;/|9/{90y91t7/j8/h7/f6-f7.i7/j80g<0qNBfRG36/16-36,36*08+08*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhǗzkr\ǿʆ|NC<2B8G9D7A6>5;2|92w8/t8/p7.m6.j70h60g6/h91j;3i@1jP=yp^MQC-5+07-16+05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ֻɛSC=1<6;:><vA<qA8q?5p?5l=3i;2p72m61i80e:1c?4cI8aN6mfNagR6>2/6+17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupز`J>.6+~9-oA3r=7s?9rA:n?7n<5n:4h<3a?3X?0PF1WS:]\?inS>J529/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoļ_Gp@*e5%h7-k<2j?4h?3e@5`C6[F5aVANM6<D)CH*jjL^aH5;)7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿįnV\H0\I1\L4WN9RN7MO8\dHCN2>F+GJ+hfI`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾuoSTM/UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Threshold.miff b/PerlMagick/t/reference/filter/Threshold.miff
new file mode 100644
index 0000000..504ef28
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Threshold.miff
Binary files differ
diff --git a/PerlMagick/t/reference/filter/Trim.miff b/PerlMagick/t/reference/filter/Trim.miff
new file mode 100644
index 0000000..44ad902
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Trim.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/UnsharpMask.miff b/PerlMagick/t/reference/filter/UnsharpMask.miff
new file mode 100644
index 0000000..44ad902
--- /dev/null
+++ b/PerlMagick/t/reference/filter/UnsharpMask.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/filter/Wave.miff b/PerlMagick/t/reference/filter/Wave.miff
new file mode 100644
index 0000000..8f76678
--- /dev/null
+++ b/PerlMagick/t/reference/filter/Wave.miff
@@ -0,0 +1,9 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=96 depth=8
+page=70x96+0+0
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20./.,0/-62/,,,0/-62/83.,-/,-+50-83.:3-,/2+-/0/,71-:3-92-.0.+/2.--1.+81,92-80-23-//-..0/-)2,(80,80-91.78234-/1.-.-/*'2-*6/,91.80-89378253.21.-+)-+(0,+71-80-80-usp6719:499496130-,*+,**1,+70-80-7/,|YWS330681>>8<:59613/,+)+,**1++70-7/,5-*|zorbYWS10-551==8A?:@=8:2.2-*('(-++1,+6-,5-*4,)okiuw|orbYYP:81/.,883B@;D?:B:880-.*+**+.++1,+3-*4,)6.+\VTQJ`uw|PYM]bPD@563-43/=<6FA?FA<A954/--,-,*+-++0,+3,*6.+6.+B?9NEmQJ`]^gEMLrv[dLOI;A=330+892DC9HC>EA:>84411+*.,)+-**0,+4.,6.+3/*1.'hnNEmI>[55H{R]FWN?MG:;6-74,>?5GG>HC>E@:=85//1,(-+(*-++1,,4-,3/*1.'41*ywtlw}hnI>qA7[`qrytMWD[PAVM?F@552(<;2GD;JI;JD;H?8<742*/.(-*().+,1--3/,30*41*63-WUPHEZ^}gnRLdkxpmMWC[N>[OAPI:?90:5/IA6OK8MI6LB7F=3<304+.-)*,**/-./-*31,41+63-750?:/]UVK55HEZ^t{{Ƭ~|ifR]F[L<ZN>YM?KB4=60F=7VJ9NK5KG;K?5E;0<302--/,*--,/,+2.,3/,52-750?:/F>3jdZ3,-3*,K55r>2pNPȆʨ}tuue`VeK[K:[L<[N=TJ:F<1A=8TG6TH:ZX[WS[H=0D;2<5040,0/*/-,0,+1-*3/,750>8-F>3I@2LA2~vKKI0/-3,-3*,>0/F-"ha`|nstf{dmze\K7[K:\L<XM<TG9E@7ME5WF6c_qVOTF<.D:295/52-01..+*.*)0,+41.:3,B:0I@2LA2LA0ZF8`\Z30,-1.0/-5/.1.-1-.3*+eoTpyknk}^M:\K6YK:YI;ZL<NG<LG5SD.\Tg㈇MDCD:/?9184/5410000,*2,*1.-82/=5.B8.H=.LA0MD3oD4J;z]ZY72/62.30,-1.01.120/1.0,2/)'\gBntcocϴ_O=^M:\K6YI9ZK;WK?RJ9SG/WLS٬roD<<@80;6094/97371-8/*5/+811<40?5.C8-I=/MD3oD4@.?1E=ikΒy_J@:5483172/62.02-,30/2/02.00,1*1+'W]Go]l[y[M=_O?^M:]L7[K:[L>XL<WK4VNQgc<62=82:7.<70@81?5.>4,;3.<31<30A4-G:0EE5`E4@.?1E=DGCF=BY\xv}jbM@D6G:F7,:5483162/33/-3.-1//.,0-+1,/,)//*%foQlZwTH8_P@_O>^M:]L9]J<^M<ZL8XPRWUh84*=71>9-C<0F;0F;0C8/?60;1.>0.C50H>7SA4o=+;+G;DGCF=B<@A;?.?-@-A+@+?.=,=+<*?.>3@4D6G:F7,:5493/43-/2,./,1-,0*+2(/*+/3(+VP:u[þDB6YL<_RB_O=^M:]L;^K<^P<VLFzzFBJ63*>94D<2K>/M@2J>4D;2<4-;/.?0.A73K;5`708*D4G@CC<A<@A;?.?-@-A+@+?.=,=+<*?.>3@4E:PE=>4=8384,/1*-+(1++.)+.)+)+,5'+E2+ia@47-JE<_RB`RC_O=_L7^M=^O;[N@b[mşqm?=I:9/A=6K@3OA0P@5I=4A7/<1/=0/>3,<:3L62q7.;/C6E><>>>A5?,?+?,@+?+>.=,=*;+>.A2@8MIqdT`SGI<;=123*0((.'(.%')*&-/&=/)GA.q*0&::4\M>bVD`R@`P7^N9\P=^O;ZLFqn՟aX=:=B=,J@2P@.O>1K<3D91@61>41E1-B2/:3,\2+=0?4D7E@F@B/@+?->-?,>)>,=-<-;/A3E7E?odo~mVcLIUAAB836./+$2(#S64W0+W:0bUE̻.2&+0+OD;`S>`S?\OC\M;WOD^QA_N:^Q]{wޛ⩩TOw></FB.P@/H?-K:1D:0A:1>93<94L.1E*.C.(g9-@2A2D7G=@1@,>-=/=-=+<+<,<.=3E;F=TP~vx_^^{\VnVM[DaA8HUN`[gT]h]ٿɽļ@>0+.(975VL=e_Xg^cd[da]fe]bdQD`JEi`Ɇœ۝r}BFV>>3>A7B<,E6.C83==1:=1G70b<>A4093)Q/(r;/>3;-C4>2>-=,;-<-;,9)9*:.A8IBMI}mv|pkxspbcRmIlYxX~rWTأ俨ǚUM>>=401+EC=gelzt{yww||rezfOKcYu{}pwƣyj`DKLHI>HU>@>5516<0<>/~B?HRFH`<2M7)e7-;895@4@4>0=.>/</9,{;,v:*}<1G<LD^T|q~rvqapEnBsInVvDchwMUoh̎yrxtcZKVM?<=2:=0Z\iljqnrxty{ynijf}~p}Xmff|GVNUqkf~@JIE3/f:6I@AG46?/JGA5>8B@B:@6A2=-:+;*v>)w8,v;0yB5J?VGrWjbjjomWcNbBa;h=pFxLxTsSgZh_[SP?׍sonzg~[h_Pe[KVN?AE*LON\]RQ]__felswt}͹hBJ;D:K@D@EK[lZplG>>9<07)4">$?4>3?3C5E3?4@:<4y<0u>.z4)PL[VpL;hYBeN`Y.J/L7M0K5S:X?gFsM|VzVpZiqxnDU5ٌ}jo~eikQh=i`Qi`Qe[KVP=LM:XVl\[^`kkryǂ؎͍ڤps5K>-7=C<>B;8EFDOJNA/=+>*;%@):%8*>3D7<*?2>>ADB9|:4<HEGTOu[EkhIhXCL@CFK8D<HBOBWCbJpQwVxbscpzt]tJϲxqdl~j{ZbXu>Vn@i`Qi`Qi`Qd[L\RCUTAnl{~{}ҋߙߵ߻vyHT@GA;@?BK?F?5C<>>=.9#>,;(:+=19.</A1?0?3<37;::C>7;.'A9bN_LTU>B<0C8CBEKEKL[I`RnNoYvsvnuaxqzdetd~k}e{cwVeHUn?`|Di`Qi`Qi`Qi`Qe[M`WBebe應숈ܙ۶լĤa[@QAB?DBKBF?9GC=A;9>.<-;-9.80:39-:+?29/7*2,,+0)6%5!9,RFPMAE>89)>/GCGHHJPVUaatUndrrrclIepgQcpycybxZlMZ~Cc|HfFhaQjaRh_PjaRh_Pg_JbYK~؉ϙӿڥoSMT<E?BCB<6=0D>=?<;@:B5>4;1:272:4:3<2:13*6-1+/(5 4!9,@7HD@9;(:)@6MHE?LFOM\_lpfncnpuVe@]qwNfPnzft\w]qS^EbIfHjIhbRibRlbTlcTjaQkbTh_Ilchȁ~˂ɆϕԷŷOC=C9:?7;.9'B952A8=1B56)6-3+70<5<690B86,,(-(2(7!7"5(A:SL@89$9(>1J=>/E9D:]Smkeloxs}Md>WR^5p[zdqZpUrYhKcIeJfGoNhcSibRjdSjaRkbSk_ZjbTg^Muhv|vщ֔ˢxdRR78A2;*:)A7;8C8;)<+;+6,41:/8-3)4&>,?3,-,,2,2%<(:*8-MIDD<.8+<,?,;*</<-SEppvxo~Ha?TK]6r[{cjPjNmShGiMeKfEtTgdShcSkcSibRjaRmbWk_^i`Qg^Lnbfpl΍ŋrk~nidkfGJ<2:+A5:479I@7$:&:%9+925/6+4!5"8$;-78142054537+=-OGFIHC8.:(:)<-;-8'E;mm|dy?aAJMa=s]uYfGeHmOjHgMiOlKrWheVgdRhcSibRibRkbSlbUkaUibMg]I^XVqm{}{|\l^VRd\hh787.H>?73+C6O@9(8'6(4+22108*:)9/8/6*8-42-5*01)6%H>DFRPF<<-<.7*:-8*7,a]{Qo<do=6GV8ezOjMaBhGpQfEkOnQvSeNheVheWgdRhcSibRjbSkbSldOkaSibKb\HUSKldfviqqhjtWU\[LyTGic\[74C:\O7,7'MA;-4*5+8.3+,.-1151:567%9"3&5/7+8&<)<589?87,K@=290729/4'RKsCfAdF<)CG/O^8e{N^?oLlOfDlPqLwX`KheVheVheWgdRhcSjbSkbSkbRldPkaXibMVR@UP@i\Ml[Ma\H`_HmYDVTupHD;3UGB54)5/B5:.641023,,)('3:(23-7*;2=4D67(5+851-7'8+OF:341/04-4%J?ey=cJZLJ6?>(\f?q^]=oLcFkLjGwTfLaMgdUheVheVheWfdRjcSkbSkbSlcSlbVlaSd]ILI7[TAm]Hg\Kf]If^DUSjm|ICA5VG1)1,A4<.463?'2(7*;+C#H6FCM2<0:+.85HG86:46':%8)GB50/1-11-4&@6Uq>f}LEFF6GF(q\_=kHdGmRoI|abJaJddSheVheVheVheWicRlcTlcTlcTlcTnbTlbPRO<HJ8`[GjcOl^Np]HXI]e~kf8.A07*=;>47)/.CL9@%-!+';5VWhYh8L047&C6QMDA:/7'9)8.H?2,20.2/-6*92t@f@a85#48#{OϖOh=e~AlHlOpNyVhPfJ]H\gOgdUifWifWheVieVlcUmdUlcTlcTobSnbT`[JBF6HM<``OZP[MR?TUkgmd:-6#;+GFD=0%-(54MS8:.*/4=LV`IM947%-:0:8HD=3:0477><93*2/.30.8-@=bs9e;M$/%>G&ās>K-fFsMpRpK}`]HeLY}G_iRhgWifWifWgeUkdZmdUmdUkbRk`Tm_Sg`QNL==D6FM@`WPHB4<6<<A88(;#;);1A;7/1+3*A@MSQWNR?B=B5852PLOQIGSSD@C;84.;5?615*0-040/4)PTJiAiT499+/sT~FP:;D0gJwQqOsQjS_IbKWxHgkWieWifWjeVkd[neWldSlbQg`Xph_lg\_ZIBB27D3TL:NM7.4,0+2+7&;'9*6+9,9/709+:+KKUaakRV5<,7JVnyfvRN53@:A9726;665+7)1+434+6)Wg7dCT15.L8*hhtQ34,9C0hKvPpOvYZCaI_ISnFihYhfWjeVlc\ndXhfQkcUjheyXR>8A(CD*YM<;;)7/5,8%8&6+1(<+6(9.<*>.=5:@]i\b26-:ER]eT[736482918589646,8'5'6+9&@9Hi:e]A77>'u_brH9:.9908@-iLwPrToYZ~C_LaKG\>mgZkeVnc\ngZghPqpltuwҜ@@%K@RDQP;+:*8-7(=%7,5)>+:(@48(<.<273RRPO7.>D=E69565130:0;46546407)8&6$:%<&LQ?aNZ8:%jyGrV<C498,7:/8B/b|EvRy]^HZ|E\zHbN8I7nj\nd\lhZhiQz~{vtbnL;@AUTFE7&9*7*9):,;):)<+F:9+:*9-:0C:B74%/1(:'?:#8.6:5<565476/7)9(:'<"7(QaHZ^NWl6^(3EG<<;&88/8@-Yk?sTw[Tt?VsBXuF^zS.;0ok`lhZflSkup>C0C<HIbf<28*9)7*:+<+6$=4F=8):(8(7(=0;/3./9+=*>$:&95=:6;5665:848*<*=*8#C<UeUTfOhAO69@=KP8:;)79/8:)O[7rViRPn<Li;XrJ[nS+5-oobdkSgwo쥗7@+t?9UUNJ=1;.:)9*=/5 9-C;:(:)9*4)4*;27;1>/=47587;6585997:5:;69)<(;(6$TTTT[SiYP]94A+]jO<E-:<24;178,EP0vbW~HLj=Gb9]qQS`P.8/qwfi{s\cG8>-]@5KKC>C;>3<.;/5?):/G9@4;1<494:68:4=GKUPA=8284888=7<6:?7;+;(8$7(TOUJZS^Q_nCQc;CV-7;+8<138454+@K0ulFd<Le?H]=\iTGSF/:/@G.;81[A4ECA;HBD<@:9'9 7*9/89;:<<78;8:5EBWTC=:79284678<7;:<@8;+:(7"<-SHYNWVjXTh?XmA9C)9?/2<..3/-.#CL7]sV>P5BS9>J4ER>=L:3@0ھ__D<6+,1-EBABD;FEGJD=B2@5<6<A9<6;5;86;.9);-<56:6:8692:7;;><9,:(;(x3"C5PCSNYTX]BTkCFT6AI6:H64B128-01$AM:>L67C04@.1?(9J2EY?׸qqW@E8SMJta`noA?DC@EHHIGEBHECB>7719780:';':)>4986785=4?9;9;08'<*x:)v5'K<SFRMbPUhG9H.6>.4>17F49E4:B23>17C14?/:C7<J79L3?Q9ӻ|dp_fb>=DDCEDCAABAB>=/F2A2=-=*@+<(6)<5=7?6C7>580;+;*{:,q6)v<0RCRKWNg_J@L835/05--9*1;.4<01>3.9./8,3927?78M3;N9ԸVV@DCDFDC>B>A<<0A2>1}=0:.<-=,8*:.;0?1;-7*9,9+{4(w6,n3(v@5SMWQv\NBI816-57518..8*.3,-4-)4-*4,,2,,0/2@-XoN¯ƿ뺶=:AAABE?F=C=:1=/<392;1;0{;/z;+{:+8,8,8):+|;-x8-s6+n4*h1&s=2SO[PHK:2=/69009-07+/4.-0+,2,+2+*/*+0-/8.j{]ȾݭF>@@A?E;C;?5=,~>090;.;-:-|:.|:/{91{8/{9.y:/v9/r7-n3+j4)b/$p9/UPVH;/9*48,27*/4-/3--2,+/*+0+)/),1,283u}qɍ81?>B=A;B9;,=-;,:+:+:,~:/~:0{90y8/v9/t9/q9-o6.k4,f2)\,!m<3eLF77.27-26*05,-2-.3-,1+-2,1501838>4g[=4B<C?B<;1=.<,:,}9-}9/}:0|:1w:3s8/o6,m8-k7,l70i6-b1(a3)nJ@46016-07-06+/3,.3-1602716:59?8MULm\@6G;A9<3=2~</:.{9/|90{<3z<4p;1k8-i7-g8-g8-j60i70f9/uWIngX)2(07-17-17-17.5948<7:@::A8qvqƨP>>1B7B7?5;2~:/{9/{90z92v80j8/h8/f7,f7.g7.k71l</eG4xdU[I,3*18-4:06<18=6:@::?8@H=\H=5::@;x?7y<3w90t8/s7.o5+j70h70g5/g70h:2hA6dI4_P7vzb6C.3916<27>49?49A79A8otmѼmZ9,:0oA7q?6q?6o?5j<2h:1q62m51i8/d:1]=0[M9^W<aaCekQ2:'8>59>49>48@5W_Tɤ{dzD0j;*m92q>7rA:o?8n=6q94k;3b?2`G8K@-CG-GJ-onP^\EDD3?B5@A5TVNμ}eVj>2j@3i>4h>2cA7^E5WH5c`HCI/<D)GJ+edG[V@SQ9li\̵iW>WE,]K2\L4VO:QN7LO8W`CEO0RZ8_bCjjV~yc]W<XR6SO3QO6SV>Z`JgmVo \ No newline at end of file
diff --git a/PerlMagick/t/reference/jng/read_gray.miff b/PerlMagick/t/reference/jng/read_gray.miff
new file mode 100644
index 0000000..2e4a9ec
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_gray.miff
@@ -0,0 +1,10 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+rendering-intent=perceptual
+gamma=0.45455
+red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
+white-point=0.3127,0.329
+
+:...///111333555555444444222222111111000...,,,,,,111222444999>>>BBBCCCCCC@@@HHHPPPXXXcccoootttrrrvvvtttnnneeeaaaaaa]]]XXXXXXVVVVVVWWWWWWXXXbbbmmm[[[@@@333555222111333///)))...)))???^^^uuusssPPPVVVxxxuuuTTT...///111333333333222222111111111111000///......111000111555999<<<======BBBGGGLLLQQQ\\\jjjrrrtttuuurrrjjj```]]]___^^^[[[YYYTTTRRRSSSTTTWWW___ggg\\\@@@111555666666555---333333,,,777IIIiiiuuuAAABBB___oooUUU---...000111111000///...////////////////////////111000///111555777888888AAADDDEEEHHHQQQaaammmqqqvvvqqqfffZZZWWWZZZ[[[YYYTTTOOOLLLOOOTTT[[[eeeooogggFFF222333444555444+++222111...000333^^^zzzHHH777:::UUUNNNHHH,,,---...///...---+++***++++++++++++,,,,,,---...000///...000333666777777;;;>>>??????GGGVVVccciiirrrnnncccXXXSSSUUUUUURRRRRROOOOOORRRUUU]]]mmm|||^^^BBB777......222000+++,,,222333---bbbtttjjjnnn~~~eee,,,---......---,,,***)))(((((((((((((((***+++,,,---,,,,,,...222555666666444888::::::???KKKWWW\\\eeeddd^^^VVVTTTUUURRRNNNOOOQQQTTTUUUVVV___uuu{{{[[[DDD---'''///444------222111+++eeelll///000111111000///---,,,******)))((()))***,,,---++++++,,,///333555555444000666888666999CCCMMMRRRVVVXXXWWWTTTTTTVVVTTTNNNEEEHHHNNNTTTZZZjjjnnnVVV777''')))+++...---'''%%%&&&ZZZxxxPPP333444555666666555333222111///...------...000222000111333666999999666444333777888444444===HHHNNNQQQSSSSSSQQQRRRTTTQQQLLLQQQNNNNNNUUUaaasssuuuXXX>>>...###)))+++"""&&&111WWWTTT777888999::::::999888777666555333111111222444666777888;;;>>>@@@>>>:::666777:::999222111;;;GGGNNNUUUVVVSSSOOONNNOOOLLLGGGsssfff[[[[[[eeeqqq~~~]]]>>>'''%%%///***777JJJaaa}}}|||yyyRRR888;;;??????>>>@@@DDDHHHAAAAAA<<<<<<;;;///---===555666>>>FFFFFF===:::>>>222FFF]]]eee___XXXZZZ``````^^^```bbbZZZQQQUUUbbbrrrrrraaaaaawwwyyyooowww{{{|||xxxaaa888444666\\\xxxrrrUUU444777<<<???AAACCCEEEGGG;;;>>>;;;>>>HHHCCC888888HHHDDDBBBCCCBBB>>>:::999>>>UUUeeeaaa[[[___aaa^^^``````bbbfffgggfffiiiooo```iiihhhqqq~~~ooorrrkkkpppvvv{{{}}}~~~jjj[[[KKK}}}Ǭqqq[[[111222666<<<CCCFFFGGGGGGHHHPPPEEE555666999666666///999BBBEEEDDDBBB>>>;;;FFF\\\cccUUURRR___aaaVVV[[[^^^```ccciiippppppkkk^^^jjjrrr{{{rrrbbbdddppptttxxxyyyyyy|||}}}lllԋ111000111777???FFFHHHHHH]]]|||{{{ZZZBBB999555666222@@@HHHCCC999555333111MMMXXX[[[SSSTTT^^^```XXX[[[bbbdddaaadddjjjggg]]]dddiiipppuuuooo```[[[bbbxxx{{{}}}~~~~~~vvv888333000222999BBBHHHJJJcccrrrSSS===AAA>>>:::<<<FFFQQQTTTPPPYYYWWWYYY```ddddddeeehhhdddnnnqqqjjjfffhhheee]]]bbbaaaiiipppggg\\\aaajjjppprrrwww|||sssAAA<<<666333777>>>FFFKKK^^^¬aaaMMM<<<888RRRwww~~~oooaaaYYY[[[hhhlllggghhhpppgggnnnqqqnnnjjjiiigggeeehhh```lllxxxlll```bbbdddoooooosss{{{rrrJJJFFFAAA;;;999===DDDIIIXXXjjj```ssspppfffeeeaaaaaadddeeeeeegggkkkdddaaaccciiillljjjhhhhhhpppbbbnnnssseeebbb\\\nnnkkklllvvvxxxUUUOOOMMMIIIBBB======BBBHHHTTTxxxsssjjj^^^fff{{{iiimmmiii```^^^fffjjjgggdddZZZYYYeeennnlllhhhiiinnnZZZggg|||tttkkklllddd^^^ZZZ\\\lllIIIIIIOOOPPPJJJHHHJJJKKKGGG[[[rrrooorrrllllllqqqpppjjjkkkfff```cccllljjjbbbfff]]]fffpppeeeYYY___gggiiiZZZcccsssvvv{{{vvv]]]aaa___TTT```mmmzzzgggQQQTTTSSSMMMLLLPPPQQQNNNHHHeeevvvrrrUUUrrroooxxxzzzjjjbbbfffggghhh___ZZZ^^^eeehhhiiijjjrrrfffeeegggbbbfffooopppeee^^^```bbbaaagggllliii``````UUU^^^hhh©PPPPPPMMMJJJLLLQQQRRRPPPKKKWWWXXXpppiiidddiiixxxyyyeee\\\ffflllqqqaaaZZZdddkkkhhhhhhnnnggg```ccchhhiiippppppdddqqqyyyttthhhaaa^^^gggwwwdddeee\\\___aaa~~~|||uuu}}}||||||KKKJJJHHHIIIMMMQQQQQQPPPUUUWWWNNNbbbzzzooommmrrrlll[[[ZZZhhhoooyyynnngggiiimmmkkkgggeeehhhfffwwwwwwfffSSSaaauuurrrddd```VVVXXXooohhhlllgggddd]]]}}}}}}qqq[[[mmmNNNMMMNNNPPPQQQPPPOOONNNGGGRRRRRRkkktttlllcccXXX\\\eeecccmmmrrrooofffhhhppplll___hhhdddwww~~~eeeVVVMMMZZZllljjjbbbfff```___rrrgggmmmmmmjjj^^^sss}}}oooYYYQQQPPPQQQSSSPPPKKKLLLOOO]]]fffbbbwwwzzzoooiiiccc^^^fffkkkccc___ooorrrfffhhhyyyzzzllleee___hhhoooeeeaaakkksssxxxzzzsssmmmpppooopppwwwbbbiiinnnlll```mmmzzz]]]WWW}}}OOOOOOQQQRRROOOLLLTTT^^^xxxuuurrrssslllbbbiiitttqqqaaammmqqqiiihhhttt|||{{{{{{|||{{{nnnggg}}}}}}rrrnnnkkkfffiiikkkeeeeeehhhllllll```fffrrrBBBJJJwwwPPPPPPSSSVVVTTTVVVeeevvvyyy߱ttt^^^aaasssxxxhhhkkklllgggbbbdddppp{{{mmmbbbmmm```gggnnnhhhmmmrrrccckkkjjjmmmjjj___```uuuvvv999;;;xxxxxx{{{\\\QQQMMMQQQUUUQQQSSSjjj}}}{{{eee|||ٶiiisss|||mmmZZZlllnnnrrrsssmmmgggddddddeeejjjooovvvqqqeeennnhhhlllmmmkkkkkknnnlllgggiiigggjjjggggggkkkwwwQQQVVV555^^^ooozzzyyyrrrhhhfffiii<<<FFFPPPYYYfffqqqrrroooyyymmm___^^^fff___cccfffhhhfffbbbbbbeeeggg\\\zzzrrr```lllnnnhhhrrriiilllmmmkkkkkkllljjjdddccceeeppplllccc{{{lll??????111WWWhhhfff{{{~~~}}}wwwooonnnrrr222>>>BBBRRRkkkiii^^^fffjjjZZZRRRqqqkkkZZZbbbcccdddeeeeeeeeegggiii]]]qqqhhhYYYeeejjjeeellljjjmmmmmmjjjkkklllhhhbbb```dddnnniiibbbxxx{{{FFF---hhhxxx{{{yyyttttttxxx///888111>>>______```ggg___[[[ppp{{{cccccceeedddeeeiiiiiieeeccccccaaaooojjjbbblllqqqlllllljjjllllllkkkmmmnnnjjjbbbaaadddaaa___ppprrrfffCCC)))KKK}}}zzz}}}{{{wwwuuuwww{{{...444+++444TTT\\\ooo~~~hhhUUUcccbbbjjjzzzuuu``````iiiccc___aaahhhjjjddd^^^]]]^^^iiilllmmmwww}}}yyytttjjjllllllllloooqqqlllcccbbbcccVVV```nnnAAA###JJJPPPnnn~~~yyywwwwww{{{999===888===NNNSSSeee|||wwwrrr___YYY[[[bbbbbb[[[iiilllaaafffeeeddd]]]]]]gggmmmiiiddddddfffkkkoooqqqssswwwuuunnnkkklllkkklllpppqqqjjj```^^^ZZZUUUkkkooojjj777MMMyyyZZZ???vvvxxxzzzyyy|||NNNOOOPPPRRRRRRQQQYYYfffmmmbbb___]]]RRRSSS```fffgggiiiXXXbbbiiifffnnnaaajjj]]]YYYccclllkkkjjjmmmsssooommmiiibbbfffkkkgggmmmlllkkkjjjnnnnnndddYYYZZZHHHVVVrrrwwwllloooccclll<<<$$$444xxx~~~]]]YYY___ddd______ccc___ccc]]]VVVHHHBBBSSS```XXXnnnvvvaaabbbcccaaaqqqbbbmmm[[[RRRZZZcccdddgggmmmsssiiieee^^^UUU___mmmooonnnmmmjjjiiikkkjjj___SSSXXX999UUUqqqWWWoooxxx```)))...777:::>>>ppp`````````aaaaaabbbbbbbbbXXXhhh___UUUIIICCCLLLBBBKKKzzz___YYYkkkmmmaaammmWWWNNNUUU^^^kkkpppiii```]]]YYYWWWWWWZZZ___bbbrrrrrrnnnfff\\\TTTQQQPPPMMMKKKQQQaaaooolll[[[KKK"""EEEHHH>>>,,,@@@{{{qqqppp``````aaaaaaaaabbbbbbbbbnnnkkk```gggVVV777:::@@@FFFXXXeee^^^kkkeeeccc^^^dddlllmmmqqqooobbbYYYWWWSSSQQQPPPRRRUUUWWWaaaaaa___ZZZSSSNNNMMMMMM@@@JJJZZZggglllllllllmmmWWWYYYFFF>>>222<<<rrrzzzttt```aaaaaaaaabbbbbbbbbbbb[[[___^^^ooogggIIIAAA;;;ZZZbbbyyyhhhooovvv|||zzz~~~|||vvvtttiiiRRRSSSRRROOOMMMKKKKKKLLLLLLPPPPPPPPPNNNKKKIIIIIIJJJEEERRR___ccc___[[[[[[]]]kkkSSS777:::888:::ggg}}}qqqvvvaaaaaaaaabbbbbbbbbcccccc___pppddd\\\```dddZZZ333QQQbbbfffiiivvvtttkkkppptttnnnmmmjjjllluuuoooWWWQQQPPPOOONNNLLLLLLKKKKKKKKKKKKKKKJJJIIIHHHHHHHHHFFFQQQ___iiimmmlllddd[[[TTTBBB333:::;;;888ZZZqqqlllyyysssaaaaaabbbbbbbbbcccccccccgggrrr[[[UUUvvvBBB333999CCCHHH\\\lllbbbmmmnnnsssrrrmmmsssrrrbbbOOOOOOOOOOOONNNNNNMMMLLLNNNMMMKKKJJJIIIGGGFFFEEE???PPPbbbjjjhhh___PPPBBB???BBBBBB===888333LLLqqqllltttooonnnbbbbbbbbbbbbcccccccccddd```^^^[[[描===444===###TTTmmmooo{{{}}}pppkkklllgggNNNNNNMMMMMMMMMMMMLLLLLLNNNLLLIIIHHHGGGEEEBBB@@@888QQQddd]]]III888...'''///>>>EEE666000111GGGdddiiizzzlllgggbbbbbbbbbcccccccccddddddkkkaaaoooUUU>>>MMMۍooo```ccceeeiiinnnkkkPPPOOONNNLLLKKKJJJJJJJJJJJJGGGEEEDDDEEEEEEBBB@@@777KKKVVVKKK===:::>>>>>>***333<<<000444444CCCrrr___aaaqqqnnn^^^bbbbbbbbbccccccdddddddddeeeZZZeeeiii333nnn^^^hhhppplll___TTTSSSPPPMMMJJJJJJIIIJJJFFFDDDBBBCCCFFFGGGEEEBBBMMMMMMBBB111+++222555000666444;;;777AAA:::<<<]]]___XXXdddqqqUUUdddeeeeeeeeeddddddfffhhhbbbuuuyyysssۃUUUdddrrreee[[[NNNHHHIIIQQQLLLGGGAAABBB@@@DDDKKKJJJCCCFFFQQQXXX666333888555111333333000111555888===FFFPPPHHHTTTWWWlllfff@@@ccceeefffeeeddddddfffhhhhhhбiiiOOO___NNNQQQYYYXXXLLLCCCHHHOOOCCCFFFCCC>>>EEESSSTTTLLLwwwRRR444111666333///000111......000222555<<<EEE@@@MMMPPPccc^^^888cccdddfffeeeddddddfffggg]]]yyyɇ\\\\\\LLLDDDKKKGGGLLLJJJEEEIIIIIIFFFAAADDDMMMTTTVVVgggIII111000666444111333222...---...---,,,111777888EEEGGGZZZXXX555bbbdddffffffeeedddeeeggg]]]kkkvvvWWW???HHHAAATTTTTTKKKOOOHHHMMMUUUHHH888GGGhhhYYYBBB222444:::999888:::777333222222...***,,,111444???===OOOQQQ555bbbdddfffgggfffeeeeeefffnnnwwwظ```JJJFFFLLLMMMIIIPPPXXXMMM===JJJfffVVVFFF:::;;;>>><<<<<<>>>===;;;::::::666000///333<<<BBB999GGGJJJ555aaadddggggggfffeeeeeeffflllgggFFFHHHYYYHHHNNNMMMHHHNNN[[[]]]TTTZZZOOOEEEAAA@@@<<<;;;<<<@@@???@@@BBB>>>888666999OOORRRCCCJJJNNN;;; \ No newline at end of file
diff --git a/PerlMagick/t/reference/jng/read_gray_idat.miff b/PerlMagick/t/reference/jng/read_gray_idat.miff
new file mode 100644
index 0000000..782ff6d
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_gray_idat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/read_gray_jdaa.miff b/PerlMagick/t/reference/jng/read_gray_jdaa.miff
new file mode 100644
index 0000000..a2e8f24
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_gray_jdaa.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/read_gray_prog.miff b/PerlMagick/t/reference/jng/read_gray_prog.miff
new file mode 100644
index 0000000..2e4a9ec
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_gray_prog.miff
@@ -0,0 +1,10 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+rendering-intent=perceptual
+gamma=0.45455
+red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
+white-point=0.3127,0.329
+
+:...///111333555555444444222222111111000...,,,,,,111222444999>>>BBBCCCCCC@@@HHHPPPXXXcccoootttrrrvvvtttnnneeeaaaaaa]]]XXXXXXVVVVVVWWWWWWXXXbbbmmm[[[@@@333555222111333///)))...)))???^^^uuusssPPPVVVxxxuuuTTT...///111333333333222222111111111111000///......111000111555999<<<======BBBGGGLLLQQQ\\\jjjrrrtttuuurrrjjj```]]]___^^^[[[YYYTTTRRRSSSTTTWWW___ggg\\\@@@111555666666555---333333,,,777IIIiiiuuuAAABBB___oooUUU---...000111111000///...////////////////////////111000///111555777888888AAADDDEEEHHHQQQaaammmqqqvvvqqqfffZZZWWWZZZ[[[YYYTTTOOOLLLOOOTTT[[[eeeooogggFFF222333444555444+++222111...000333^^^zzzHHH777:::UUUNNNHHH,,,---...///...---+++***++++++++++++,,,,,,---...000///...000333666777777;;;>>>??????GGGVVVccciiirrrnnncccXXXSSSUUUUUURRRRRROOOOOORRRUUU]]]mmm|||^^^BBB777......222000+++,,,222333---bbbtttjjjnnn~~~eee,,,---......---,,,***)))(((((((((((((((***+++,,,---,,,,,,...222555666666444888::::::???KKKWWW\\\eeeddd^^^VVVTTTUUURRRNNNOOOQQQTTTUUUVVV___uuu{{{[[[DDD---'''///444------222111+++eeelll///000111111000///---,,,******)))((()))***,,,---++++++,,,///333555555444000666888666999CCCMMMRRRVVVXXXWWWTTTTTTVVVTTTNNNEEEHHHNNNTTTZZZjjjnnnVVV777''')))+++...---'''%%%&&&ZZZxxxPPP333444555666666555333222111///...------...000222000111333666999999666444333777888444444===HHHNNNQQQSSSSSSQQQRRRTTTQQQLLLQQQNNNNNNUUUaaasssuuuXXX>>>...###)))+++"""&&&111WWWTTT777888999::::::999888777666555333111111222444666777888;;;>>>@@@>>>:::666777:::999222111;;;GGGNNNUUUVVVSSSOOONNNOOOLLLGGGsssfff[[[[[[eeeqqq~~~]]]>>>'''%%%///***777JJJaaa}}}|||yyyRRR888;;;??????>>>@@@DDDHHHAAAAAA<<<<<<;;;///---===555666>>>FFFFFF===:::>>>222FFF]]]eee___XXXZZZ``````^^^```bbbZZZQQQUUUbbbrrrrrraaaaaawwwyyyooowww{{{|||xxxaaa888444666\\\xxxrrrUUU444777<<<???AAACCCEEEGGG;;;>>>;;;>>>HHHCCC888888HHHDDDBBBCCCBBB>>>:::999>>>UUUeeeaaa[[[___aaa^^^``````bbbfffgggfffiiiooo```iiihhhqqq~~~ooorrrkkkpppvvv{{{}}}~~~jjj[[[KKK}}}Ǭqqq[[[111222666<<<CCCFFFGGGGGGHHHPPPEEE555666999666666///999BBBEEEDDDBBB>>>;;;FFF\\\cccUUURRR___aaaVVV[[[^^^```ccciiippppppkkk^^^jjjrrr{{{rrrbbbdddppptttxxxyyyyyy|||}}}lllԋ111000111777???FFFHHHHHH]]]|||{{{ZZZBBB999555666222@@@HHHCCC999555333111MMMXXX[[[SSSTTT^^^```XXX[[[bbbdddaaadddjjjggg]]]dddiiipppuuuooo```[[[bbbxxx{{{}}}~~~~~~vvv888333000222999BBBHHHJJJcccrrrSSS===AAA>>>:::<<<FFFQQQTTTPPPYYYWWWYYY```ddddddeeehhhdddnnnqqqjjjfffhhheee]]]bbbaaaiiipppggg\\\aaajjjppprrrwww|||sssAAA<<<666333777>>>FFFKKK^^^¬aaaMMM<<<888RRRwww~~~oooaaaYYY[[[hhhlllggghhhpppgggnnnqqqnnnjjjiiigggeeehhh```lllxxxlll```bbbdddoooooosss{{{rrrJJJFFFAAA;;;999===DDDIIIXXXjjj```ssspppfffeeeaaaaaadddeeeeeegggkkkdddaaaccciiillljjjhhhhhhpppbbbnnnssseeebbb\\\nnnkkklllvvvxxxUUUOOOMMMIIIBBB======BBBHHHTTTxxxsssjjj^^^fff{{{iiimmmiii```^^^fffjjjgggdddZZZYYYeeennnlllhhhiiinnnZZZggg|||tttkkklllddd^^^ZZZ\\\lllIIIIIIOOOPPPJJJHHHJJJKKKGGG[[[rrrooorrrllllllqqqpppjjjkkkfff```cccllljjjbbbfff]]]fffpppeeeYYY___gggiiiZZZcccsssvvv{{{vvv]]]aaa___TTT```mmmzzzgggQQQTTTSSSMMMLLLPPPQQQNNNHHHeeevvvrrrUUUrrroooxxxzzzjjjbbbfffggghhh___ZZZ^^^eeehhhiiijjjrrrfffeeegggbbbfffooopppeee^^^```bbbaaagggllliii``````UUU^^^hhh©PPPPPPMMMJJJLLLQQQRRRPPPKKKWWWXXXpppiiidddiiixxxyyyeee\\\ffflllqqqaaaZZZdddkkkhhhhhhnnnggg```ccchhhiiippppppdddqqqyyyttthhhaaa^^^gggwwwdddeee\\\___aaa~~~|||uuu}}}||||||KKKJJJHHHIIIMMMQQQQQQPPPUUUWWWNNNbbbzzzooommmrrrlll[[[ZZZhhhoooyyynnngggiiimmmkkkgggeeehhhfffwwwwwwfffSSSaaauuurrrddd```VVVXXXooohhhlllgggddd]]]}}}}}}qqq[[[mmmNNNMMMNNNPPPQQQPPPOOONNNGGGRRRRRRkkktttlllcccXXX\\\eeecccmmmrrrooofffhhhppplll___hhhdddwww~~~eeeVVVMMMZZZllljjjbbbfff```___rrrgggmmmmmmjjj^^^sss}}}oooYYYQQQPPPQQQSSSPPPKKKLLLOOO]]]fffbbbwwwzzzoooiiiccc^^^fffkkkccc___ooorrrfffhhhyyyzzzllleee___hhhoooeeeaaakkksssxxxzzzsssmmmpppooopppwwwbbbiiinnnlll```mmmzzz]]]WWW}}}OOOOOOQQQRRROOOLLLTTT^^^xxxuuurrrssslllbbbiiitttqqqaaammmqqqiiihhhttt|||{{{{{{|||{{{nnnggg}}}}}}rrrnnnkkkfffiiikkkeeeeeehhhllllll```fffrrrBBBJJJwwwPPPPPPSSSVVVTTTVVVeeevvvyyy߱ttt^^^aaasssxxxhhhkkklllgggbbbdddppp{{{mmmbbbmmm```gggnnnhhhmmmrrrccckkkjjjmmmjjj___```uuuvvv999;;;xxxxxx{{{\\\QQQMMMQQQUUUQQQSSSjjj}}}{{{eee|||ٶiiisss|||mmmZZZlllnnnrrrsssmmmgggddddddeeejjjooovvvqqqeeennnhhhlllmmmkkkkkknnnlllgggiiigggjjjggggggkkkwwwQQQVVV555^^^ooozzzyyyrrrhhhfffiii<<<FFFPPPYYYfffqqqrrroooyyymmm___^^^fff___cccfffhhhfffbbbbbbeeeggg\\\zzzrrr```lllnnnhhhrrriiilllmmmkkkkkkllljjjdddccceeeppplllccc{{{lll??????111WWWhhhfff{{{~~~}}}wwwooonnnrrr222>>>BBBRRRkkkiii^^^fffjjjZZZRRRqqqkkkZZZbbbcccdddeeeeeeeeegggiii]]]qqqhhhYYYeeejjjeeellljjjmmmmmmjjjkkklllhhhbbb```dddnnniiibbbxxx{{{FFF---hhhxxx{{{yyyttttttxxx///888111>>>______```ggg___[[[ppp{{{cccccceeedddeeeiiiiiieeeccccccaaaooojjjbbblllqqqlllllljjjllllllkkkmmmnnnjjjbbbaaadddaaa___ppprrrfffCCC)))KKK}}}zzz}}}{{{wwwuuuwww{{{...444+++444TTT\\\ooo~~~hhhUUUcccbbbjjjzzzuuu``````iiiccc___aaahhhjjjddd^^^]]]^^^iiilllmmmwww}}}yyytttjjjllllllllloooqqqlllcccbbbcccVVV```nnnAAA###JJJPPPnnn~~~yyywwwwww{{{999===888===NNNSSSeee|||wwwrrr___YYY[[[bbbbbb[[[iiilllaaafffeeeddd]]]]]]gggmmmiiiddddddfffkkkoooqqqssswwwuuunnnkkklllkkklllpppqqqjjj```^^^ZZZUUUkkkooojjj777MMMyyyZZZ???vvvxxxzzzyyy|||NNNOOOPPPRRRRRRQQQYYYfffmmmbbb___]]]RRRSSS```fffgggiiiXXXbbbiiifffnnnaaajjj]]]YYYccclllkkkjjjmmmsssooommmiiibbbfffkkkgggmmmlllkkkjjjnnnnnndddYYYZZZHHHVVVrrrwwwllloooccclll<<<$$$444xxx~~~]]]YYY___ddd______ccc___ccc]]]VVVHHHBBBSSS```XXXnnnvvvaaabbbcccaaaqqqbbbmmm[[[RRRZZZcccdddgggmmmsssiiieee^^^UUU___mmmooonnnmmmjjjiiikkkjjj___SSSXXX999UUUqqqWWWoooxxx```)))...777:::>>>ppp`````````aaaaaabbbbbbbbbXXXhhh___UUUIIICCCLLLBBBKKKzzz___YYYkkkmmmaaammmWWWNNNUUU^^^kkkpppiii```]]]YYYWWWWWWZZZ___bbbrrrrrrnnnfff\\\TTTQQQPPPMMMKKKQQQaaaooolll[[[KKK"""EEEHHH>>>,,,@@@{{{qqqppp``````aaaaaaaaabbbbbbbbbnnnkkk```gggVVV777:::@@@FFFXXXeee^^^kkkeeeccc^^^dddlllmmmqqqooobbbYYYWWWSSSQQQPPPRRRUUUWWWaaaaaa___ZZZSSSNNNMMMMMM@@@JJJZZZggglllllllllmmmWWWYYYFFF>>>222<<<rrrzzzttt```aaaaaaaaabbbbbbbbbbbb[[[___^^^ooogggIIIAAA;;;ZZZbbbyyyhhhooovvv|||zzz~~~|||vvvtttiiiRRRSSSRRROOOMMMKKKKKKLLLLLLPPPPPPPPPNNNKKKIIIIIIJJJEEERRR___ccc___[[[[[[]]]kkkSSS777:::888:::ggg}}}qqqvvvaaaaaaaaabbbbbbbbbcccccc___pppddd\\\```dddZZZ333QQQbbbfffiiivvvtttkkkppptttnnnmmmjjjllluuuoooWWWQQQPPPOOONNNLLLLLLKKKKKKKKKKKKKKKJJJIIIHHHHHHHHHFFFQQQ___iiimmmlllddd[[[TTTBBB333:::;;;888ZZZqqqlllyyysssaaaaaabbbbbbbbbcccccccccgggrrr[[[UUUvvvBBB333999CCCHHH\\\lllbbbmmmnnnsssrrrmmmsssrrrbbbOOOOOOOOOOOONNNNNNMMMLLLNNNMMMKKKJJJIIIGGGFFFEEE???PPPbbbjjjhhh___PPPBBB???BBBBBB===888333LLLqqqllltttooonnnbbbbbbbbbbbbcccccccccddd```^^^[[[描===444===###TTTmmmooo{{{}}}pppkkklllgggNNNNNNMMMMMMMMMMMMLLLLLLNNNLLLIIIHHHGGGEEEBBB@@@888QQQddd]]]III888...'''///>>>EEE666000111GGGdddiiizzzlllgggbbbbbbbbbcccccccccddddddkkkaaaoooUUU>>>MMMۍooo```ccceeeiiinnnkkkPPPOOONNNLLLKKKJJJJJJJJJJJJGGGEEEDDDEEEEEEBBB@@@777KKKVVVKKK===:::>>>>>>***333<<<000444444CCCrrr___aaaqqqnnn^^^bbbbbbbbbccccccdddddddddeeeZZZeeeiii333nnn^^^hhhppplll___TTTSSSPPPMMMJJJJJJIIIJJJFFFDDDBBBCCCFFFGGGEEEBBBMMMMMMBBB111+++222555000666444;;;777AAA:::<<<]]]___XXXdddqqqUUUdddeeeeeeeeeddddddfffhhhbbbuuuyyysssۃUUUdddrrreee[[[NNNHHHIIIQQQLLLGGGAAABBB@@@DDDKKKJJJCCCFFFQQQXXX666333888555111333333000111555888===FFFPPPHHHTTTWWWlllfff@@@ccceeefffeeeddddddfffhhhhhhбiiiOOO___NNNQQQYYYXXXLLLCCCHHHOOOCCCFFFCCC>>>EEESSSTTTLLLwwwRRR444111666333///000111......000222555<<<EEE@@@MMMPPPccc^^^888cccdddfffeeeddddddfffggg]]]yyyɇ\\\\\\LLLDDDKKKGGGLLLJJJEEEIIIIIIFFFAAADDDMMMTTTVVVgggIII111000666444111333222...---...---,,,111777888EEEGGGZZZXXX555bbbdddffffffeeedddeeeggg]]]kkkvvvWWW???HHHAAATTTTTTKKKOOOHHHMMMUUUHHH888GGGhhhYYYBBB222444:::999888:::777333222222...***,,,111444???===OOOQQQ555bbbdddfffgggfffeeeeeefffnnnwwwظ```JJJFFFLLLMMMIIIPPPXXXMMM===JJJfffVVVFFF:::;;;>>><<<<<<>>>===;;;::::::666000///333<<<BBB999GGGJJJ555aaadddggggggfffeeeeeeffflllgggFFFHHHYYYHHHNNNMMMHHHNNN[[[]]]TTTZZZOOOEEEAAA@@@<<<;;;<<<@@@???@@@BBB>>>888666999OOORRRCCCJJJNNN;;; \ No newline at end of file
diff --git a/PerlMagick/t/reference/jng/read_gray_prog_idat.miff b/PerlMagick/t/reference/jng/read_gray_prog_idat.miff
new file mode 100644
index 0000000..782ff6d
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_gray_prog_idat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/read_gray_prog_jdaa.miff b/PerlMagick/t/reference/jng/read_gray_prog_jdaa.miff
new file mode 100644
index 0000000..a2e8f24
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_gray_prog_jdaa.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/read_idat.miff b/PerlMagick/t/reference/jng/read_idat.miff
new file mode 100644
index 0000000..1db9f7d
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_idat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/read_jdaa.miff b/PerlMagick/t/reference/jng/read_jdaa.miff
new file mode 100644
index 0000000..a7056db
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_jdaa.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/read_prog.miff b/PerlMagick/t/reference/jng/read_prog.miff
new file mode 100644
index 0000000..50d04a8
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_prog.miff
@@ -0,0 +1,10 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+rendering-intent=perceptual
+gamma=0.45455
+red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
+white-point=0.3127,0.329
+
+:5,#6-&7/,91/;25;2382283/64(42#32 10.///#00&5-+>*5?+7;08999:A9<G7CF5KC.Y<*n;*=0@7D?ICLIKGG>A8>1=.C/H2G/B)B+@)?(?)<&=(F0UDKIX67E+.B009/-50*63*3/#2*:-$9&"P:=pXhmy}lPNdNTdrusuPS\5,#5.&7/,91/90190160061-52)42%31"1/ //#00&10+7./<+5=)49,38439:4<>3@>/E<+U;*d9(z8*9/<6C=IDKGGBB9<38,>.F3G4D0G3B.>+>*=+?-G5TE~OIT87?+*?10:5176166,0.";5)=3)8)$E24XDPwav~|o@AS;AMX_ilqwOTX3,"2.%4/)50-5//4..3--2-*30+2/(1.%0-&0,)2.-3.25/3;,3;*0:)/;,/?10?40@6-B6*M;-V9)e7'x6(7-=7E@IFKIC@:64-7.?3B5A4>28,4*7+;0@4K?[N]RQC:90)63,36/27017-*-"44(51&5,%9.,</6fZh|wEIR/9;1;<PYXJSP@ID0,!0-$2-'2/*2-*1++/)).((/+(.*'-)&-)(.*+/*01,32-33/.5-+6**;+,@..C11?40>5,B<0E<+P;(_9&u7(;0D;HCKGFC>95/5/;3<4:2:3708.:1<4D:TJi]|kb_NBD64:.(2)'2*,6-,4)+-"/,#62)81+1++cafoyxanedqhxx]i[/,#..$1.'/.)0,)/+(-)(,(',(),(),&*+%),%,-&./'2,+0'1(&1#--%5,'=--?11<42581/;/1?.9A*F>'Z:%t;(A2F:F=E<B7<1;1>4=4~:1~>5@7C:E;E<ODeZoxhUaK<J9#3(,%(3-.80+.%..$52)22(+,&bgccr[0/*11)21,21,10+0/+0,)/+*.*+-(,-&-,%,-&..'//(0,,,!2"!3)/!3/&=/.?03933162'7-'<-0?,9;%L6c4 }8(>0=.A2A4=1=2@6?6|<3p4*q8-t>4yE:}K@\Pwizo_y\G`J(@2.%.)%.)-0)..&+)&&&)W_TȴpgEX:33344256167167156043.32.4013/03-11+/1+/2,.3--01))6")926%<5-C54D47=28726/3218079,=4#L-_,z2#;+=*B.B2>/;.=2=1~:/}=3w;0s=1wF8RDeV}nopelZg@fQ,H<!4.&!*+&1,&*#-'45'W[M|}{~|xnH]<76;88:997:;5:;39;0991872:6595673460261.61+73*56&6;%7<%><-E<3K;;L7<G3<C/8B17F35K2.O*"Y"j$-"9*@-C0@/9*4)3)2*0(\URHI=L@UIcXqfo|p{zukWYP5<<#="G'(@$ G5)RL<bfUwqqp{vxvn~voeF[<97B=<B????@:>@5?A4DD:GG?BA=BA?=<:?;8>;420#0/A?*=5"@4$I;.SB;T@?O49P/8Y1<T$0n4@FPKPBD:8<8D9I8?.=0C993'"+)A=LHPID=H?`X_XRLTPSSSYYh]s\{X{TwTt>Xw$4WU.'j]MwipomsqpzogN`F62@87?=;<?@:AC6BD6EE9GG=<;7?=><:=?=>IHCDE79;%<:#RF6OA4L@4M@7M>9O77R/5Y*2i*5<IHSAJ;>=<?:<2E4<*;-B8?95386FB95C>C;KC^WZUMIKN3?1H8V>bAkDrIwOxbMc<Du@<|nν̻o|hUbN4.<41::67>>6CD4GH8HI;GG?HHHPOUECN54<6689:459*69&20!<:-CD6FF:GE9J@7P72Z.-q12BFFK7:32>9?54&=+8&6&:/<5;8;8>95.B8K?THYPLE<8<<=C=H@TB]BeEjKqTvidw^f][߽Ƈxs6.94-450-:8,BA/GH6II=IHD]\d{zzxWXm?AP69@265381/5+?B7GJ?CE8=9-@2%H,!S$|91?:>95.4*=3=/5%;(<'9)6*4-5.2,/&5(?1L=TEM@;20+33HIIOKXJ^IcKiPpVtYqcrjqabù>5:91/6/%63"><'ED0II?KILc`uᦥъloMRh7=I;CE;@::;5B;3SB8fJ>sI;yA2G8A1>.A1C1A0A2E4B.I4G7>16-5+1)0$5%9&F5P@F88.61<9B@DFHPKYNaRjTmWoUg`kouYZܬI==B92<5%94=9 CA,JG@KJR]Zy{~[^}MKYC8>G14kGIhgupi`XJK9?*='D0E3=/=2G9@0F4E8>4714-3+5)?19(F6QBB96175:9C?DBFIMTSaVgUgTe]i]esvVXzySF@MC7H@+B<"?;B@+HE@KIWWRzᔍwZnJ^Xjft]fKMA;A3=*:':)7)2+.-534,5+2-3011/0/.2.D;7*D8SID@5617.3D?C>B@JMW^^i[fVamucg}[[vBD[JBYI<VD6O@-H<&H=+JC9JGNPQo裡©ӓoVmMa@Q2>:=OK=2C3@05&.$1+./)+-,%%"$,-4433203/:4*$;5RMIG=?8>255/5+7/E@XXfkhldhtwgitqa<6^E>fKDhHIcA@^@8\E7VI6IJ:S__s˙ꜛ阍٣βz_|CT@MHQBG>>DAIAB8;05)6+8.8/5.1-+/ ',1:;2/)$1,94:6*'21BCGFNKJH3/8/@21!@1OHmjYYferqqnmgk^ogR_M?bNEfHJc@Da?=aG:YN2OO3@N=WjpgvȌr`9^F]8DDMMP@@60;2@6;13*,#.&4+90;2636>'3,34550:3F>F?83/,/01231;7C<B98-=/6"?.G<lglgsqpq^^pi~qϰ˶ŬÚմQW;RT>UMBWF>ZG9^M9ZT4TU5HO=QY[UTstfyzoHd5I2?DNKN::2+<2F:C7:00'/(5.949744,4$.*046:7C>E>92E?LGFB:64/3,>5NE90</9,</9.f^|{{xT[_\ter|Zmewfxal{ƭFW3GT6JM8PJ:XM;[Q8YT4UT6VWEXVWTGapV}n{yXg@P8F?I>B//1*A6H<M@F9;25/618534*/-4-5?ESTSQGC82&6/JCF@814.+#-%D:;/<0>7<4/%\Tx~gwN]QSN=jtQkdypoͭDY2EV2IR7QP;UO9VN7TO2RN5KG;XOR\J`^{u__S]BN<D57-+4,?3</G9F8?57/6467/3(-17/5BHWZLN45'# 0'C9A79-<35+2*D96(6+;9;8/&RJq~PhKbNSL;czp}pzkutyNZ6NX6RU:XS?WO<TI7SJ9TNBa[[jbmj[rlŠϊkcQTBK=C8741@7E9;-;,@3@49186=>;?9?4:057>>D4:03<=GCMEQGK>E8E;C8A9F=0 1%44673/IEj}QmIb>BzK9gm^k_aUvgyi{nvul_[T:\Q;aQAbPB^LBZHD]QQf\dyrãęqcTQOOONC?92C9NAF87*@3A69062?=EGGKLNOSIQ:C1:IOdhjiQJI?F9C4:/;0921'02$,-/467;@xayLiG\}))eB,dv_l`lbo^o\yhsteeUbL>aK=dLBfMHcKKaNTk]nxovtyz}~ΦldlciaOG6-<2J@J=6*A5A64*.'84AAFFXZcgYa5?'4FQ[bMO>;5+>2E7;/=4>8-%7#7&*(,25</;iXsIdTbd)!M8}{RvX\NPEp\jTpZhSJm5>a+bEAeIEiMIcIHaLStcuvzt^^vz絲\P`PrshWNC;-#<3?5D9E9A5:/8.8184=>[_MV5A<K9G.78<66>7A8?4<2<5621)7$5#3..34?9LgJfWj>BiL:D?^Y1~VL9`SbMgNbFX|>Uw;Xy@M47W??_JGfTRnajukrkkgrqԗ䚠ޜϣǑtjruXJQ;m\ylxnc[7/.%3(7+</;-9+:/<2=644KP=F(41>4?+67<66;9>8=4:48331/(5"8$?67:-9I^RpOiPY[5,IE,17bY2fm:K}4YIfLkMeH_@^}AbE9.2D;<FA;URKjkoeg|XY^_}{χێچƂ~~m`qlTHrH0_L{m{le:4' 1'5(9+=,>.?1A4A834BG4<"+,70:*41747::;885868521/(5"<(C6:7,8ZpC]Sfk85/<[iEVgN[HkOnMiJdDeEjJ0.388803(:B3Xc]WamX]wxׅԌ͑Ívq`ptXM~P9]KqalcOH2*1'6(8'=,B0D2@2=2:211;?5:-17=<C5;6;47698986::;9752+9(?+;,61>G^oEWGOU>0 /DY8Ȥ~RjQgTkOlKhIgHiJnO.-2352'0-;"LZIR`agmΝۉċ~urdskTZXNQBSE[OMG3-0'9-8&6":'B/D5<04-0,-,67:;<;FFKLFH@D385:6:89<=@>=9709*>,4$;3^bV^NRj1*&& ?W5}láxWY1]{EhUgMfIfIjMpQtU=6=>=87<%9D$GU;KXN^ex{qxjw~rtla[bYTiPKTILB?6G@C>4,8-8);'68!A.E8>6634375=;B?D@D@FCAA:<595:497:>>C??88.8)7'5&MAllPOXOL3ET3ndzsWW5EM&dPdSfMeIiMoUvZx\\GPZKHWQ7UW2QY4NVAVY`eb}uog]cXfb[U[V@ZY:_`AmYATKMI75<9?;:1B57%E-: 6?)B6=8799<A@A>D>>77.70;7558;5:3;4:=>B><45)8+);,YKZTVLhSdgHxlojMG="$(0@jXm\lWhQlSs[v\qYnU[gTPj^HkfFccA`bJdc^`]f^Wg_Wd`XURM:ED%TT.ce@oZ?YPWV>>;9855.F8:&I0:16!;.7248:>B??8?6:/0$7-F?GC>>;=8<9;@=E:?15'<1>3[O@6^Pu[~YoK. 7170?I&1FgVubu^oWpXt^r\gRn\Zl]Vk_QjbMicMidNicSicW`YOoi]e_OZUANI3HD+QO8X>-~71^_ac9:**94=36&F18 ,.:.B;=?>>;7>5<1:/;.=2>7?8IFHFFCA;=19&:$;'5+3-<5OE_TaSjXDOM4!* =H(BI*=G%(63ElXxcoWv^{epZaMZFk^Vk^Ul`Tl`RjaPkcPkcNkcLvpZrlVfaKlgS[VC<6&@:*S;/k,'76\\`_<:51D>A64&8';)B3I>KCCA@=;5?4=0;.:,:.:191>9>8>7<0:)9#|<!y=%r,"~5/GAWP`UdW{hWtnX[]EV_B@M/:I(,=4F j|Tgt\tZv\kUcM\Ii_Uj`Vj`TjaRkbQkcPjcPjdNc\If_Lc^Jto\lfVNH:FB6J8,UKULlcunVQ>:>;@<HELGMGLFOGMF@72*8.:/:,8*7)6)4*2)0*1)3*3(4%7!v: s;$u2)?9MHUL|TJpTHhXHc^JkoXR\A3@$3B#/@4E!csOk{aqUjMdJaJ^Hj`Vj`Vj`TkaUkbSjcQkdRkdRf_Mwr_jdTb\Le_ShdX^ZQ>0%kG9RCRDSG^VYSHEEFCH@E:=76A<KCE87)6+:.;,:+:+9*6+3)/'0(1)2(5%z7$r:#o;&q5+{@:PH]TdZ~fZobR_\IPS>@J1/<".= /@ 2C#UdCzd}bkM^@]A`H]Ej`Tj`TjbUjbUjcSkdTkdTjdTmgWxrda[OYUIzvm}tU;*I)P+a6%s;.LCRO>A@HAL?H;C@@H@F:A25(9-:-=.>.=-;/:/7-6-6,6+{7*s8(l7%h7(e1&tB;VM`W}aVm[OWP@ED2:?+@I4>J41?&,: /=#HU9u_|`eEX}:]AbH]DkaUjbUjbUjbUkdTjdTjdTkeWe_Qa]Q`\QܩW>(I3P:%8 qE:|kmEMFQJVIQEFA;B5H93'8,:,;.}>/|>1|>1}=1}:1|90z7.v6,s7,l7)f5'a3&X,#nF>}[QrVKXD9B6*2/ '),3#:E4AN:.;')7 ,:!CP6}jt[_@Wv:bFfLZxBjcSicSicSjdTjdVjdVkeWieYnj_d`Wsnhԣy_P;G<*VM<ӽrvSZ:@8=>=@;B7J=5,:0:/;0{;/x<1v>1v>1r9.p7,n5,l6,l7/i7.e5+_3*R-$aC9jODZF;H:/A9.??3=A3)1",9(5B1,9(0;*.:&?H3vd~OSp:Sp:a}Jb~NPl<icSicSicSjdTjdVieYieYieZhd[\YRifavn[96%ᦨVW?>HEJD?5;/:2>6<3;2z<1v<1r>1q?4h8,e6,d5+f7/h91i:2f71^6.cE;^H;P>2<.#2*53'57,-3'2<1)5'0<02>0=H8/:)3<+sWmFIc6Mg:_xN^tNF_8heRifSifUifUheVhdXjf[kh_a^Wrql͸~{jxviʭrj;2D:NDF;@8:4{5-w4,|=4x?4o=2e6,c9-_7-a;0hB9h=6a6/g73kD=ymbTG?3'91$:8,46+-3).6+,6-)5)*6,.:.2<17?2@F:FR>=P2I_;MbAavW]pT6J/gdQifSjgVifWhdXgeYif]iiakjeĻ٩UH6*F;8/@8I@E<u:2m7-n>4oE9^:.^>1X:/V6+^<3oHAtICeC:rfYRB93%42%68+14)*1)*4+)5+'3)'3)+5,/6.08-8>4>F78G0BV;EW?YkUTeR.?,feQgfRihVhfWgeXeeYgg]hh`ba\|}wij|mM>K@u?5p7.s:1n70r@7l@5_9,\?1[A2W@0S<,X>1dF;oMCmQFqeWMJ942#23%6:,28,.5-.8/*5-'2*'1))3*+2*)0(.3,4</2A.<N8<M:O`NN\M,:-edPgfTigXghZffZee[ff^gh`\]Wjkeſټl`vNBc7,j;1d4*wH>qI=_>/_H8UD2XK8`S@WF4G4#\B3zdVaZHEF445%58':>07=15=25?60:2,7/,6.-7/,3+)0(+0)/7,/=,6G42C0CTBFTG,:-cdRefTghXhi[gg[eg\ef^fg_kldsvmýѯ{UJgA6_=1\@2]L8RJ3WS:][BSO6E=&VG2pcP\ZEIK6<=+<?.>B4;A59A69C:7A95?74>65?73:3.5./4-2:/6E29K5.@*:K8>O?*;+bcQefThiYhi[fh[eg\ef^fg_kne|ɺû~\P`>2`@3gP@WH3UQ8QQ7HL1PP4^]Ac\BYS;_]HPR=EH5AE4?C49?17?49A6;E=9C;:D<;E=:A:4;44927?2IXEI[C8J4?P=BSA1B2 \ No newline at end of file
diff --git a/PerlMagick/t/reference/jng/read_prog_idat.miff b/PerlMagick/t/reference/jng/read_prog_idat.miff
new file mode 100644
index 0000000..1db9f7d
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_prog_idat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/read_prog_jdaa.miff b/PerlMagick/t/reference/jng/read_prog_jdaa.miff
new file mode 100644
index 0000000..a7056db
--- /dev/null
+++ b/PerlMagick/t/reference/jng/read_prog_jdaa.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/write_gray.miff b/PerlMagick/t/reference/jng/write_gray.miff
new file mode 100644
index 0000000..aeee172
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_gray.miff
@@ -0,0 +1,10 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+rendering-intent=perceptual
+gamma=0.45455
+red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
+white-point=0.3127,0.329
+
+:...///111333555555444444222222111111000...,,,,,,111222444999>>>BBBCCCCCC@@@HHHPPPXXXcccoootttrrrvvvtttnnneeeaaaaaa]]]XXXXXXVVVVVVWWWWWWXXXbbbmmm[[[@@@333555222111333///)))...)))???^^^uuusssSSSTTTwwwvvvOOO...///111333333333222222111111111111000///......111000111555999<<<======BBBGGGLLLQQQ\\\jjjrrrtttuuurrrjjj```]]]___^^^[[[YYYTTTRRRSSSTTTWWW___ggg\\\@@@111555666666555---333333,,,777IIIiiiuuu@@@???___uuuVVV---...000111111000///...////////////////////////111000///111555777888888AAADDDEEEHHHQQQaaammmqqqvvvqqqfffZZZWWWZZZ[[[YYYTTTOOOLLLOOOTTT[[[eeeooogggFFF222333444555444+++222111...000333^^^zzzLLL999:::UUUIII:::,,,---...///...---+++***++++++++++++,,,,,,---...000///...000333666777777;;;>>>??????GGGVVVccciiirrrnnncccXXXSSSUUUUUURRRRRROOOOOORRRUUU]]]mmm|||^^^BBB777......222000+++,,,222333---bbbsssiiimmmkkk,,,---......---,,,***)))(((((((((((((((***+++,,,---,,,,,,...222555666666444888::::::???KKKWWW\\\eeeddd^^^VVVTTTUUURRRNNNOOOQQQTTTUUUVVV___uuu{{{[[[DDD---'''///444------222111+++eeeuuu///000111111000///---,,,******)))((()))***,,,---++++++,,,///333555555444000666888666999CCCMMMRRRVVVXXXWWWTTTTTTVVVTTTNNNEEEHHHNNNTTTZZZjjjnnnVVV777''')))+++...---'''%%%&&&ZZZúoooJJJ333444555666666555333222111///...------...000222000111333666999999666444333777888444444===HHHNNNQQQSSSSSSQQQRRRTTTQQQLLLQQQNNNNNNUUUaaasssuuuXXX>>>...###)))+++"""&&&111WWW^^^777888999::::::999888777666555333111111222444666777888;;;>>>@@@>>>:::666777:::999222111;;;GGGNNNUUUVVVSSSOOONNNOOOLLLGGGsssfff[[[[[[eeeqqq~~~]]]>>>'''%%%///***777JJJaaa}}}|||wwwSSS888;;;??????>>>@@@DDDHHHAAAAAA<<<<<<;;;///---===555666>>>FFFFFF===:::>>>222FFF]]]eee___XXXZZZ``````^^^```bbbZZZQQQUUUbbbrrrrrraaaaaawwwyyyooowww{{{|||xxxbbb999555777]]]yyypppRRR444777<<<???AAACCCEEEGGG;;;>>>;;;>>>HHHCCC888888HHHDDDBBBCCCBBB>>>:::999>>>UUUeeeaaa[[[___aaa^^^``````bbbfffgggfffiiiooo```iiihhhqqq~~~ooorrrkkkpppvvv{{{}}}~~~kkk\\\LLL~~~ǬqqqZZZ111222666<<<CCCFFFGGGGGGHHHPPPEEE555666999666666///999BBBEEEDDDBBB>>>;;;FFF\\\cccUUURRR___aaaVVV[[[^^^```ccciiippppppkkk^^^jjjrrr{{{rrrbbbdddppptttxxxyyyyyy|||~~~mmmԌ111000111777???FFFHHHHHH]]]|||{{{ZZZBBB999555666222@@@HHHCCC999555333111MMMXXX[[[SSSTTT^^^```XXX[[[bbbdddaaadddjjjggg]]]dddiiipppuuuooo```[[[bbbxxx{{{}}}~~~~~~vvv888333000222999BBBHHHJJJcccrrrSSS===AAA>>>:::<<<FFFQQQTTTPPPYYYWWWYYY```ddddddeeehhhdddnnnqqqjjjfffhhheee]]]bbbaaaiiipppggg\\\aaajjjppprrrwww|||sssAAA<<<666333777>>>FFFKKK^^^¬aaaMMM<<<888RRRwww~~~oooaaaYYY[[[hhhlllggghhhpppgggnnnqqqnnnjjjiiigggeeehhh```lllxxxlll```bbbdddoooooosss{{{rrrJJJFFFAAA;;;999===DDDIIIXXXjjj```ssspppfffeeeaaaaaadddeeeeeegggkkkdddaaaccciiillljjjhhhhhhpppbbbnnnssseeebbb\\\nnnkkklllvvvwwwTTTOOOMMMIIIBBB======BBBHHHTTTxxxsssjjj^^^fff{{{iiimmmiii```^^^fffjjjgggdddZZZYYYeeennnlllhhhiiinnnZZZggg|||tttkkklllddd^^^ZZZ\\\lllGGGIIIOOOPPPJJJHHHJJJKKKGGG[[[rrrooorrrllllllqqqpppjjjkkkfff```cccllljjjbbbfff]]]fffpppeeeYYY___gggiiiZZZcccsssvvv{{{vvv]]]aaa___TTT```mmmzzzgggQQQTTTSSSMMMLLLPPPQQQNNNHHHeeevvvrrrUUUrrroooxxxzzzjjjbbbfffggghhh___ZZZ^^^eeehhhiiijjjrrrfffeeegggbbbfffooopppeee^^^```bbbaaagggllliii``````UUU^^^hhh¨PPPPPPMMMJJJLLLQQQRRRPPPKKKWWWXXXpppiiidddiiixxxyyyeee\\\ffflllqqqaaaZZZdddkkkhhhhhhnnnggg```ccchhhiiippppppdddqqqyyyttthhhaaa^^^gggwwwdddeee\\\___aaa~~~|||uuu}}}||||||KKKJJJHHHIIIMMMQQQQQQPPPUUUWWWNNNbbbzzzooommmrrrlll[[[ZZZhhhoooyyynnngggiiimmmkkkgggeeehhhfffwwwwwwfffSSSaaauuurrrddd```VVVXXXooohhhlllgggddd]]]}}}}}}qqq[[[mmmNNNMMMNNNPPPQQQPPPOOONNNGGGRRRRRRkkktttlllcccXXX\\\eeecccmmmrrrooofffhhhppplll___hhhdddwww~~~eeeVVVMMMZZZllljjjbbbfff```___rrrgggmmmmmmjjj^^^sss}}}oooYYYQQQPPPQQQSSSPPPKKKLLLOOO]]]fffbbbwwwzzzoooiiiccc^^^fffkkkccc___ooorrrfffhhhyyyzzzllleee___hhhoooeeeaaakkksssxxxzzzsssmmmpppooopppwwwbbbiiinnnlll```mmmzzz]]]WWWOOOOOOQQQRRROOOLLLTTT^^^xxxuuurrrssslllbbbiiitttqqqaaammmqqqiiihhhttt|||{{{{{{|||{{{nnnggg}}}}}}rrrnnnkkkfffiiikkkeeeeeehhhllllll```fffrrrBBBJJJzzzPPPPPPSSSVVVTTTVVVeeevvvyyy߱ttt^^^aaasssxxxhhhkkklllgggbbbdddppp{{{mmmbbbmmm```gggnnnhhhmmmrrrccckkkjjjmmmjjj___```uuuvvv999;;;xxxxxx{{{[[[OOOMMMQQQUUUQQQSSSjjj}}}{{{eee|||ٶiiisss|||mmmZZZlllnnnrrrsssmmmgggddddddeeejjjooovvvqqqeeennnhhhlllmmmkkkkkknnnlllgggiiigggjjjggggggkkkwwwQQQVVV555^^^ooo{{{zzzrrrgggeeekkk<<<FFFPPPYYYfffqqqrrroooyyymmm___^^^fff___cccfffhhhfffbbbbbbeeeggg\\\zzzrrr```lllnnnhhhrrriiilllmmmkkkkkkllljjjdddccceeeppplllccc{{{lll??????111WWWhhhfff{{{~~~wwwooonnnsss222>>>BBBRRRkkkiii^^^fffjjjZZZRRRqqqkkkZZZbbbcccdddeeeeeeeeegggiii]]]qqqhhhYYYeeejjjeeellljjjmmmmmmjjjkkklllhhhbbb```dddnnniiibbbxxx{{{FFF---hhhxxx{{{~~~yyyttttttxxx///888111>>>______```ggg___[[[ppp{{{cccccceeedddeeeiiiiiieeeccccccaaaooojjjbbblllqqqlllllljjjllllllkkkmmmnnnjjjbbbaaadddaaa___ppprrrfffCCC)))KKK}}}zzz|||zzzxxxvvvwwwyyy...444+++444TTT\\\ooo~~~hhhUUUcccbbbjjjzzzuuu``````iiiccc___aaahhhjjjddd^^^]]]^^^iiilllmmmwww}}}yyytttjjjllllllllloooqqqlllcccbbbcccVVV```nnnAAA###JJJPPPnnn~~~xxxwwwxxx{{{999===888===NNNSSSeee|||wwwrrr___YYY[[[bbbbbb[[[iiilllaaafffeeeddd]]]]]]gggmmmiiiddddddfffkkkoooqqqssswwwuuunnnkkklllkkklllpppqqqjjj```^^^ZZZUUUkkkooojjj777MMMyyyZZZ???vvvxxxzzzyyy|||NNNOOOPPPRRRRRRQQQYYYfffmmmbbb___]]]RRRSSS```fffgggiiiXXXbbbiiifffnnnaaajjj]]]YYYccclllkkkjjjmmmsssooommmiiibbbfffkkkgggmmmlllkkkjjjnnnnnndddYYYZZZHHHVVVrrrwwwllloooccclll<<<$$$444xxx~~~]]]YYY___ddd______ccc___ccc]]]VVVHHHBBBSSS```XXXnnnvvvaaabbbcccaaaqqqbbbmmm[[[RRRZZZcccdddgggmmmsssiiieee^^^UUU___mmmooonnnmmmjjjiiikkkjjj___SSSXXX999UUUqqqWWWoooxxx```)))...777:::>>>ppp`````````aaaaaabbbbbbbbbXXXhhh___UUUIIICCCLLLBBBKKKzzz___YYYkkkmmmaaammmWWWNNNUUU^^^kkkpppiii```]]]YYYWWWWWWZZZ___bbbrrrrrrnnnfff\\\TTTQQQPPPMMMKKKQQQaaaooolll[[[KKK"""EEEHHH>>>,,,@@@{{{qqqnnn``````aaaaaaaaabbbbbbbbbnnnkkk```gggVVV777:::@@@FFFXXXeee^^^kkkeeeccc^^^dddlllmmmqqqooobbbYYYWWWSSSQQQPPPRRRUUUWWWaaaaaa___ZZZSSSNNNMMMMMM@@@JJJZZZggglllllllllmmmWWWYYYFFF>>>222<<<rrr{{{uuu```aaaaaaaaabbbbbbbbbbbb[[[___^^^ooogggIIIAAA;;;ZZZbbbyyyhhhooovvv|||zzz~~~|||vvvtttiiiRRRSSSRRROOOMMMKKKKKKLLLLLLPPPPPPPPPNNNKKKIIIIIIJJJEEERRR___ccc___[[[[[[]]]kkkSSS777:::888:::ggg~~~rrryyyaaaaaaaaabbbbbbbbbcccccc___pppddd\\\```dddZZZ333QQQbbbfffiiivvvtttkkkppptttnnnmmmjjjllluuuoooWWWQQQPPPOOONNNLLLLLLKKKKKKKKKKKKKKKJJJIIIHHHHHHHHHFFFQQQ___iiimmmlllddd[[[TTTBBB333:::;;;888ZZZqqqmmmzzzuuuaaaaaabbbbbbbbbcccccccccgggrrr[[[UUUvvvBBB333999CCCHHH\\\lllbbbmmmnnnsssrrrmmmsssrrrbbbOOOOOOOOOOOONNNNNNMMMLLLNNNMMMKKKJJJIIIGGGFFFEEE???PPPbbbjjjhhh___PPPBBB???BBBBBB===888333LLLrrrllltttooonnnbbbbbbbbbbbbcccccccccddd```^^^[[[描===444===###TTTmmmooo{{{}}}pppkkklllgggNNNNNNMMMMMMMMMMMMLLLLLLNNNLLLIIIHHHGGGEEEBBB@@@888QQQddd]]]III888...'''///>>>EEE666000111GGGeeehhhyyyjjjgggbbbbbbbbbcccccccccddddddkkkaaaoooUUU>>>MMMۍooo```ccceeeiiinnnkkkPPPOOONNNLLLKKKJJJJJJJJJJJJGGGEEEDDDEEEEEEBBB@@@777KKKVVVKKK===:::>>>>>>***333<<<000444444CCCttt```aaapppnnn___bbbbbbbbbccccccdddddddddeeeZZZeeeiii333nnn^^^hhhppplll___TTTSSSPPPMMMJJJJJJIIIJJJFFFDDDBBBCCCFFFGGGEEEBBBMMMMMMBBB111+++222555000666444;;;777AAA:::<<<^^^___XXXdddsssYYYdddeeeeeeeeeddddddfffhhheeerrrzzztttՀVVVhhhtttddd^^^PPPHHHIIIQQQMMMHHHAAABBB@@@DDDKKKJJJCCCFFFQQQXXX777333888555111333///---///444888===FFFPPPGGGSSSUUUiiieeeAAAccceeefffeeeddddddfffhhhkkkвkkkPPP^^^PPPRRRYYYXXXMMMDDDIIIOOOCCCFFFCCC>>>EEESSSTTTLLLvvvRRR444111777333///111000------000222555<<<DDDCCCPPPRRRfffaaa===cccdddfffeeeddddddfffggg```vvvȆ[[[[[[LLLEEELLLIIIMMMKKKEEEIIIIIIFFFAAADDDMMMTTTVVVeeeGGG000000777555222555333///......---,,,000666999FFFGGG[[[YYY777bbbdddffffffeeedddeeeggg___gggsssVVVAAAIIIBBBTTTTTTKKKOOOHHHMMMUUUHHH888GGGhhhWWWAAA111333:::::::::<<<888444222222...***,,,111222===;;;NNNPPP555bbbdddfffgggfffeeeeeefffpppsssٹ___HHHGGGNNNMMMIIIPPPXXXMMM===JJJfffUUUEEE999;;;>>>======???===:::999999555000111555;;;BBB:::HHHLLL666aaadddggggggfffeeeeeefffooodddDDDIII]]]HHHNNNMMMHHHNNN[[[]]]TTT[[[OOOEEEAAA@@@<<<;;;<<<@@@>>>>>>???<<<666666999LLLPPPAAAIIIMMM::: \ No newline at end of file
diff --git a/PerlMagick/t/reference/jng/write_gray_idat.miff b/PerlMagick/t/reference/jng/write_gray_idat.miff
new file mode 100644
index 0000000..a87c734
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_gray_idat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/write_gray_jdaa.miff b/PerlMagick/t/reference/jng/write_gray_jdaa.miff
new file mode 100644
index 0000000..03704ad
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_gray_jdaa.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/write_gray_prog.miff b/PerlMagick/t/reference/jng/write_gray_prog.miff
new file mode 100644
index 0000000..aeee172
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_gray_prog.miff
@@ -0,0 +1,10 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+rendering-intent=perceptual
+gamma=0.45455
+red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
+white-point=0.3127,0.329
+
+:...///111333555555444444222222111111000...,,,,,,111222444999>>>BBBCCCCCC@@@HHHPPPXXXcccoootttrrrvvvtttnnneeeaaaaaa]]]XXXXXXVVVVVVWWWWWWXXXbbbmmm[[[@@@333555222111333///)))...)))???^^^uuusssSSSTTTwwwvvvOOO...///111333333333222222111111111111000///......111000111555999<<<======BBBGGGLLLQQQ\\\jjjrrrtttuuurrrjjj```]]]___^^^[[[YYYTTTRRRSSSTTTWWW___ggg\\\@@@111555666666555---333333,,,777IIIiiiuuu@@@???___uuuVVV---...000111111000///...////////////////////////111000///111555777888888AAADDDEEEHHHQQQaaammmqqqvvvqqqfffZZZWWWZZZ[[[YYYTTTOOOLLLOOOTTT[[[eeeooogggFFF222333444555444+++222111...000333^^^zzzLLL999:::UUUIII:::,,,---...///...---+++***++++++++++++,,,,,,---...000///...000333666777777;;;>>>??????GGGVVVccciiirrrnnncccXXXSSSUUUUUURRRRRROOOOOORRRUUU]]]mmm|||^^^BBB777......222000+++,,,222333---bbbsssiiimmmkkk,,,---......---,,,***)))(((((((((((((((***+++,,,---,,,,,,...222555666666444888::::::???KKKWWW\\\eeeddd^^^VVVTTTUUURRRNNNOOOQQQTTTUUUVVV___uuu{{{[[[DDD---'''///444------222111+++eeeuuu///000111111000///---,,,******)))((()))***,,,---++++++,,,///333555555444000666888666999CCCMMMRRRVVVXXXWWWTTTTTTVVVTTTNNNEEEHHHNNNTTTZZZjjjnnnVVV777''')))+++...---'''%%%&&&ZZZúoooJJJ333444555666666555333222111///...------...000222000111333666999999666444333777888444444===HHHNNNQQQSSSSSSQQQRRRTTTQQQLLLQQQNNNNNNUUUaaasssuuuXXX>>>...###)))+++"""&&&111WWW^^^777888999::::::999888777666555333111111222444666777888;;;>>>@@@>>>:::666777:::999222111;;;GGGNNNUUUVVVSSSOOONNNOOOLLLGGGsssfff[[[[[[eeeqqq~~~]]]>>>'''%%%///***777JJJaaa}}}|||wwwSSS888;;;??????>>>@@@DDDHHHAAAAAA<<<<<<;;;///---===555666>>>FFFFFF===:::>>>222FFF]]]eee___XXXZZZ``````^^^```bbbZZZQQQUUUbbbrrrrrraaaaaawwwyyyooowww{{{|||xxxbbb999555777]]]yyypppRRR444777<<<???AAACCCEEEGGG;;;>>>;;;>>>HHHCCC888888HHHDDDBBBCCCBBB>>>:::999>>>UUUeeeaaa[[[___aaa^^^``````bbbfffgggfffiiiooo```iiihhhqqq~~~ooorrrkkkpppvvv{{{}}}~~~kkk\\\LLL~~~ǬqqqZZZ111222666<<<CCCFFFGGGGGGHHHPPPEEE555666999666666///999BBBEEEDDDBBB>>>;;;FFF\\\cccUUURRR___aaaVVV[[[^^^```ccciiippppppkkk^^^jjjrrr{{{rrrbbbdddppptttxxxyyyyyy|||~~~mmmԌ111000111777???FFFHHHHHH]]]|||{{{ZZZBBB999555666222@@@HHHCCC999555333111MMMXXX[[[SSSTTT^^^```XXX[[[bbbdddaaadddjjjggg]]]dddiiipppuuuooo```[[[bbbxxx{{{}}}~~~~~~vvv888333000222999BBBHHHJJJcccrrrSSS===AAA>>>:::<<<FFFQQQTTTPPPYYYWWWYYY```ddddddeeehhhdddnnnqqqjjjfffhhheee]]]bbbaaaiiipppggg\\\aaajjjppprrrwww|||sssAAA<<<666333777>>>FFFKKK^^^¬aaaMMM<<<888RRRwww~~~oooaaaYYY[[[hhhlllggghhhpppgggnnnqqqnnnjjjiiigggeeehhh```lllxxxlll```bbbdddoooooosss{{{rrrJJJFFFAAA;;;999===DDDIIIXXXjjj```ssspppfffeeeaaaaaadddeeeeeegggkkkdddaaaccciiillljjjhhhhhhpppbbbnnnssseeebbb\\\nnnkkklllvvvwwwTTTOOOMMMIIIBBB======BBBHHHTTTxxxsssjjj^^^fff{{{iiimmmiii```^^^fffjjjgggdddZZZYYYeeennnlllhhhiiinnnZZZggg|||tttkkklllddd^^^ZZZ\\\lllGGGIIIOOOPPPJJJHHHJJJKKKGGG[[[rrrooorrrllllllqqqpppjjjkkkfff```cccllljjjbbbfff]]]fffpppeeeYYY___gggiiiZZZcccsssvvv{{{vvv]]]aaa___TTT```mmmzzzgggQQQTTTSSSMMMLLLPPPQQQNNNHHHeeevvvrrrUUUrrroooxxxzzzjjjbbbfffggghhh___ZZZ^^^eeehhhiiijjjrrrfffeeegggbbbfffooopppeee^^^```bbbaaagggllliii``````UUU^^^hhh¨PPPPPPMMMJJJLLLQQQRRRPPPKKKWWWXXXpppiiidddiiixxxyyyeee\\\ffflllqqqaaaZZZdddkkkhhhhhhnnnggg```ccchhhiiippppppdddqqqyyyttthhhaaa^^^gggwwwdddeee\\\___aaa~~~|||uuu}}}||||||KKKJJJHHHIIIMMMQQQQQQPPPUUUWWWNNNbbbzzzooommmrrrlll[[[ZZZhhhoooyyynnngggiiimmmkkkgggeeehhhfffwwwwwwfffSSSaaauuurrrddd```VVVXXXooohhhlllgggddd]]]}}}}}}qqq[[[mmmNNNMMMNNNPPPQQQPPPOOONNNGGGRRRRRRkkktttlllcccXXX\\\eeecccmmmrrrooofffhhhppplll___hhhdddwww~~~eeeVVVMMMZZZllljjjbbbfff```___rrrgggmmmmmmjjj^^^sss}}}oooYYYQQQPPPQQQSSSPPPKKKLLLOOO]]]fffbbbwwwzzzoooiiiccc^^^fffkkkccc___ooorrrfffhhhyyyzzzllleee___hhhoooeeeaaakkksssxxxzzzsssmmmpppooopppwwwbbbiiinnnlll```mmmzzz]]]WWWOOOOOOQQQRRROOOLLLTTT^^^xxxuuurrrssslllbbbiiitttqqqaaammmqqqiiihhhttt|||{{{{{{|||{{{nnnggg}}}}}}rrrnnnkkkfffiiikkkeeeeeehhhllllll```fffrrrBBBJJJzzzPPPPPPSSSVVVTTTVVVeeevvvyyy߱ttt^^^aaasssxxxhhhkkklllgggbbbdddppp{{{mmmbbbmmm```gggnnnhhhmmmrrrccckkkjjjmmmjjj___```uuuvvv999;;;xxxxxx{{{[[[OOOMMMQQQUUUQQQSSSjjj}}}{{{eee|||ٶiiisss|||mmmZZZlllnnnrrrsssmmmgggddddddeeejjjooovvvqqqeeennnhhhlllmmmkkkkkknnnlllgggiiigggjjjggggggkkkwwwQQQVVV555^^^ooo{{{zzzrrrgggeeekkk<<<FFFPPPYYYfffqqqrrroooyyymmm___^^^fff___cccfffhhhfffbbbbbbeeeggg\\\zzzrrr```lllnnnhhhrrriiilllmmmkkkkkkllljjjdddccceeeppplllccc{{{lll??????111WWWhhhfff{{{~~~wwwooonnnsss222>>>BBBRRRkkkiii^^^fffjjjZZZRRRqqqkkkZZZbbbcccdddeeeeeeeeegggiii]]]qqqhhhYYYeeejjjeeellljjjmmmmmmjjjkkklllhhhbbb```dddnnniiibbbxxx{{{FFF---hhhxxx{{{~~~yyyttttttxxx///888111>>>______```ggg___[[[ppp{{{cccccceeedddeeeiiiiiieeeccccccaaaooojjjbbblllqqqlllllljjjllllllkkkmmmnnnjjjbbbaaadddaaa___ppprrrfffCCC)))KKK}}}zzz|||zzzxxxvvvwwwyyy...444+++444TTT\\\ooo~~~hhhUUUcccbbbjjjzzzuuu``````iiiccc___aaahhhjjjddd^^^]]]^^^iiilllmmmwww}}}yyytttjjjllllllllloooqqqlllcccbbbcccVVV```nnnAAA###JJJPPPnnn~~~xxxwwwxxx{{{999===888===NNNSSSeee|||wwwrrr___YYY[[[bbbbbb[[[iiilllaaafffeeeddd]]]]]]gggmmmiiiddddddfffkkkoooqqqssswwwuuunnnkkklllkkklllpppqqqjjj```^^^ZZZUUUkkkooojjj777MMMyyyZZZ???vvvxxxzzzyyy|||NNNOOOPPPRRRRRRQQQYYYfffmmmbbb___]]]RRRSSS```fffgggiiiXXXbbbiiifffnnnaaajjj]]]YYYccclllkkkjjjmmmsssooommmiiibbbfffkkkgggmmmlllkkkjjjnnnnnndddYYYZZZHHHVVVrrrwwwllloooccclll<<<$$$444xxx~~~]]]YYY___ddd______ccc___ccc]]]VVVHHHBBBSSS```XXXnnnvvvaaabbbcccaaaqqqbbbmmm[[[RRRZZZcccdddgggmmmsssiiieee^^^UUU___mmmooonnnmmmjjjiiikkkjjj___SSSXXX999UUUqqqWWWoooxxx```)))...777:::>>>ppp`````````aaaaaabbbbbbbbbXXXhhh___UUUIIICCCLLLBBBKKKzzz___YYYkkkmmmaaammmWWWNNNUUU^^^kkkpppiii```]]]YYYWWWWWWZZZ___bbbrrrrrrnnnfff\\\TTTQQQPPPMMMKKKQQQaaaooolll[[[KKK"""EEEHHH>>>,,,@@@{{{qqqnnn``````aaaaaaaaabbbbbbbbbnnnkkk```gggVVV777:::@@@FFFXXXeee^^^kkkeeeccc^^^dddlllmmmqqqooobbbYYYWWWSSSQQQPPPRRRUUUWWWaaaaaa___ZZZSSSNNNMMMMMM@@@JJJZZZggglllllllllmmmWWWYYYFFF>>>222<<<rrr{{{uuu```aaaaaaaaabbbbbbbbbbbb[[[___^^^ooogggIIIAAA;;;ZZZbbbyyyhhhooovvv|||zzz~~~|||vvvtttiiiRRRSSSRRROOOMMMKKKKKKLLLLLLPPPPPPPPPNNNKKKIIIIIIJJJEEERRR___ccc___[[[[[[]]]kkkSSS777:::888:::ggg~~~rrryyyaaaaaaaaabbbbbbbbbcccccc___pppddd\\\```dddZZZ333QQQbbbfffiiivvvtttkkkppptttnnnmmmjjjllluuuoooWWWQQQPPPOOONNNLLLLLLKKKKKKKKKKKKKKKJJJIIIHHHHHHHHHFFFQQQ___iiimmmlllddd[[[TTTBBB333:::;;;888ZZZqqqmmmzzzuuuaaaaaabbbbbbbbbcccccccccgggrrr[[[UUUvvvBBB333999CCCHHH\\\lllbbbmmmnnnsssrrrmmmsssrrrbbbOOOOOOOOOOOONNNNNNMMMLLLNNNMMMKKKJJJIIIGGGFFFEEE???PPPbbbjjjhhh___PPPBBB???BBBBBB===888333LLLrrrllltttooonnnbbbbbbbbbbbbcccccccccddd```^^^[[[描===444===###TTTmmmooo{{{}}}pppkkklllgggNNNNNNMMMMMMMMMMMMLLLLLLNNNLLLIIIHHHGGGEEEBBB@@@888QQQddd]]]III888...'''///>>>EEE666000111GGGeeehhhyyyjjjgggbbbbbbbbbcccccccccddddddkkkaaaoooUUU>>>MMMۍooo```ccceeeiiinnnkkkPPPOOONNNLLLKKKJJJJJJJJJJJJGGGEEEDDDEEEEEEBBB@@@777KKKVVVKKK===:::>>>>>>***333<<<000444444CCCttt```aaapppnnn___bbbbbbbbbccccccdddddddddeeeZZZeeeiii333nnn^^^hhhppplll___TTTSSSPPPMMMJJJJJJIIIJJJFFFDDDBBBCCCFFFGGGEEEBBBMMMMMMBBB111+++222555000666444;;;777AAA:::<<<^^^___XXXdddsssYYYdddeeeeeeeeeddddddfffhhheeerrrzzztttՀVVVhhhtttddd^^^PPPHHHIIIQQQMMMHHHAAABBB@@@DDDKKKJJJCCCFFFQQQXXX777333888555111333///---///444888===FFFPPPGGGSSSUUUiiieeeAAAccceeefffeeeddddddfffhhhkkkвkkkPPP^^^PPPRRRYYYXXXMMMDDDIIIOOOCCCFFFCCC>>>EEESSSTTTLLLvvvRRR444111777333///111000------000222555<<<DDDCCCPPPRRRfffaaa===cccdddfffeeeddddddfffggg```vvvȆ[[[[[[LLLEEELLLIIIMMMKKKEEEIIIIIIFFFAAADDDMMMTTTVVVeeeGGG000000777555222555333///......---,,,000666999FFFGGG[[[YYY777bbbdddffffffeeedddeeeggg___gggsssVVVAAAIIIBBBTTTTTTKKKOOOHHHMMMUUUHHH888GGGhhhWWWAAA111333:::::::::<<<888444222222...***,,,111222===;;;NNNPPP555bbbdddfffgggfffeeeeeefffpppsssٹ___HHHGGGNNNMMMIIIPPPXXXMMM===JJJfffUUUEEE999;;;>>>======???===:::999999555000111555;;;BBB:::HHHLLL666aaadddggggggfffeeeeeefffooodddDDDIII]]]HHHNNNMMMHHHNNN[[[]]]TTT[[[OOOEEEAAA@@@<<<;;;<<<@@@>>>>>>???<<<666666999LLLPPPAAAIIIMMM::: \ No newline at end of file
diff --git a/PerlMagick/t/reference/jng/write_gray_prog_idat.miff b/PerlMagick/t/reference/jng/write_gray_prog_idat.miff
new file mode 100644
index 0000000..a87c734
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_gray_prog_idat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/write_gray_prog_jdaa.miff b/PerlMagick/t/reference/jng/write_gray_prog_jdaa.miff
new file mode 100644
index 0000000..03704ad
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_gray_prog_jdaa.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/write_idat.miff b/PerlMagick/t/reference/jng/write_idat.miff
new file mode 100644
index 0000000..383ecdd
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_idat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/write_jdaa.miff b/PerlMagick/t/reference/jng/write_jdaa.miff
new file mode 100644
index 0000000..119f225
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_jdaa.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/write_prog.miff b/PerlMagick/t/reference/jng/write_prog.miff
new file mode 100644
index 0000000..16881d5
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_prog.miff
@@ -0,0 +1,10 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+page=70x46+0+0
+rendering-intent=perceptual
+gamma=0.45455
+red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
+white-point=0.3127,0.329
+
+:5,#6-&7/,91/;25;2382283/64(42#32 10.///#00&5-+@(5A)7>.8<89;@9>F7CF5KC.Y<*n;*=0A7E?ICMIMGJ>E8A1?.D/H2G/A)B+@)?(@)>&@(J0WD~MIX67D+.@0061-12*25*.2#,-40$5("L<=oXhmz}lTQfNQ`qtswHLX5,#5.&7/,91/90190160061-52)42%31"1/ //#00&10+7./?)5?'4;,3;23:94<>3@>/G;+U;*d9(x9*:/=6D=JDLGJBE9?3;,?.F3G4C0G3B.>+?*?+B-J5VEMIX67C)*@00<4167147,,0"57)86)4+$@44UEPtcvzp@?O9=HY]hrvPT]3,"2.%4/)50-5//4..3--2-*30+2/(1.%0-&0,)2.-3.27.3<+3=*0<)/<,/@00A30B5-C5*N;-V9)e7'v7(8->7F@KFMIE@=66-8.>3A5@4<26,4*8+<0B4M?[NYR_<:F*)@.,:2/65036-(."26(13&1.%41,726`]hxzINT19;2:<PXZDML1:90,!0-$2-'2/*2-*1++/)).((/+(.*'-)&-)(.*+/*01,33,34..6,+8**=*,A-.D01A30?5,B<0E<+P;(^9&s8(<0D;ICLGHC?96/5/93<49293707.:1=4E:VJi]xkoYNO>6>5./.)-/*/4--3)+-"--#62)61+0,+cafnwt`kceph|~amc/,#..$1.'/.)0,)/+(-)(,(',(),(),&*+%),%,-&./'2-+0)0((0#/,%6+'?--@01=32671/;/1?.8B*E?'Y:%s<(B2F:G=E<B7<191<4<481<5?7C:D;F<ODfZo{hX`K>I9%2(,%)2-160/,%4+$</)<-(6&&o`cjyf0/*11)21,21,10+0/+0,)/+*.*+-(,-&-,%,-&..'//(0,,,#1"#2,.!6-&>..@03;23352'7-'<-.?,8<%K7`6 |9(?0<.A2A4=1<2>6=6:3s3*s7-v=4zD:}K@\Pwi~oax\I_J*>2-%"-)(-)1.)4+&2%0!1$cXTʶ~fx^=O533344256167167156043.32.4013/03-11+/1+/2,.3--11)*6"+745%=4-D44F37>18826/321806:,<5#I.\-w4#;+<*A.A2>/:.<2;18/<3z:0v<1zD8RDdV|npslggK`Q3D<'2.%!+*&0-&($*(35'T\M||{~y~zrPdH76;88:997:;5:;39;0991872:6595673460261.61+73*75&7:%9;%A;-H;3N:;L7<H3<C/8B17F35J2.M+"V$h&~/":*?-C0@/8*3)2)1*.([UPHH=J@UIbXpfo|p{vuoTYR4<<#<"E)(;' C7)MN<]iUrqopspxxq}vmeEY=97B=<B????@:>@5?A4DD:GG?BA=BA?=<:?;8>;420#0/C>*?4"C3$L:.U@;W??O49P/8Y1<T$0n4@GPLPBD<8=8D9H8=.=0C983%"*)?=JHNIC=G?^X^XRLTPVSXY]hasa{\{WwWt?Wu$3XX-'pZM}zgulspqn~plM_I62@87?=;<?@:AC6BD6EE9GG=<;7?=><:=?=>IHCDE79;%<:#SF6R@4O>4P?7O=9O77R/5[)2i*5<IHSBJ;>><@:<2D4:*:-A8>95376EB95B>B;KC]WYULIKN8?8H?VEbGkIrNwRxdOc=Dv?<znν̻n|kUcR4.<41::67>>6CD4GH8HI;GG?HHHPOUECN54<6689:459*69&30!?9-EC6HF:HD9L?7R62Z.-q12BFGK8:42?9@54&<+6&4&:/<5;8;8>95.B8K?SHYPJE;8:<<C=H@TC]DeHjOqXvliwcfb[ɇyx6.94-450-:8,BA/GH6II=IHD]\d{zzxWXm?AP69@26538123+@B7HJ?DD8=9-@2%I+!S$|91@:>95.5*=3?/6%:(:'8)6*4-5.3,/&6(@1L=TEL@:2/+23HIHOJXK^KcMiSpZt^qirpqfb¼>5:91/6/%63"><'ED0II?KILc`uᦥъloMRh7=I>BE=?:=:5D93TB8gI>tH;yA2G8A1>.A1C1A0B2F4B.H4G7>16-6+2)1$7%:&G5Q@F87.51<9D@IFLPOYRaVjXm\oXfckpuZZݫI==B92<5%94=9 CA,JG@KJR]Zy{~]^}PIYF7>J/4mFIhgtpi`XJK9?*='D0F3>/>2G9@0E4E8?4816-6+8)B1;(H6RBC96165:9E?HBJIQTWaZgYgWe^h^ervTXwySF@MC7H@+B<"?;B@+HE@KIWWRzᔍwYnI^Wjet]fKMA;A3=*;';)8)2+/-533,4+2-4031202.6.G;:*F8UIE@6607.3C?C>C@KMX^^i\fXanucg|Y[z?C[JBYI<UE6O@-H<&H=+JC9JGNPQo裡©єpWmNa@Q2>:=OK=2B3?05&.$1+./)+-,%%"$--6453406/<4,$<5SMIG=?7>054/3+4/C@XXfkhldhtwhitqf96]F>dKDgIIaB@^@8\E7VI6IJ:S__s˚Ꝛ降٤ΰ{d|ITEMLQEG?>EAHAA8:04)4+7.7/3./-*/ '-1;;2/*$1,94:6+'31CCGFMKJH3/90?3-"<1QHpjXXddsstpsho_vcR^N?aOEeHJaADa?=aG:YN2OO3@N=WjpgvȎq_:^K]?DJMRPC@80<2?6:11**#,&2+7092435>'3,34540:3E>E?73/,/01221;7C<B99.=01";.J<oflfqpor`_vj~q˰ʵƮÝ׳OX;QU>TNBUG>YG9]N9ZT4TU5HO=QY[UTsvfwxnId:I8?INON=:4+<2D:A780/'-(3.848734+4$.*046:7C>D>92D?LGFB:64/3,=5NE:1:/6,:/;.h]{zzwSZc\vexyZte{gydsϨCY3EV6IN8NK:VN;YR8YT4UT6UXEXVWTGaqU}myxYgCP=FDIBB2/3*A6H<L@D9;24/517524*/-4-5?ESTSQGC72%6/JCF@814.*#-%D:<0;0<7;41%]Sy}gvO\QRN=msQqdzrt|×ҦAZ2CW2HR7OQ;TO9UO7SO2PN5JH;XOR]J`]{t~}__U]FN@D87.+5,?3;/F9E8>56/5467/3(-17/5BHWZLN45'# 0'C9A79-<35+2*D97)7,>:<8/&RJs}QgK`MSJ;c~qsrztuK[6MX6QU:VT?VO<RJ7RK9TNB`\[jbmlZrkʼnЉkcSTEK@C9751@7E9;-;,@3@49196>><?:?5:057>?D4:03<=GCMEQGL>E8F;C8A9F=0!3&84972/GDm|SlIa;BH9hn_s`kXzkzk}ntrl\ZT:ZR;_RAaQB]LBXID]QQd]d{qŢřqcUQPOPNE?92C9NAF87*A3B6:072A=FGIKMNOSJQ;C1:IOdhkiQJI?G9D4;/;0921'1 3$3.55579@zexQjI]&*n=,dt_t`vas`o^|iptccR`M>_L=cMBeNHaLKaNTj]nxovt{z~ХldlciaPG6-<2J@K=7*A5B66*0'94CAHFXZdgZa5?(4FQ\bOO?;6+?2E7</=4?8.%7$9'2)324<+:l\rNeVcp%"X4z}RtWeMZCt`lVq[gQFn09a#aEAcJEgNIbJHaLStcuvzt^^vz緱[P_P~rrhWNC;-#=3A5E9G9C5</9.:194>>[_NV7A=K:G/79<76?7B8@4=2<5621)6$7#:.333?6LiOf[j?BsG:O:]Z1{VV9kSjQiO_GT{<Sw9X|>K57U@?^KGdURnajukqkihrqԗ䛟ޝϥǔujrxVJP;l\ylxnd[8//%4(9+=/=-;+;/>2?644LP>F*43>4?-67<66<9@8=4;4:341/(5":$E6<:-9G^UpSiTYZ5,R@,93aY2em:Ty4cIkOkOeH\?[~>`C8/2B<<EB;RSKhloeg|WY^_}{χێڈƂ~}n`qoSHtG0_L{m{me;4) 3'7(;+>,@.@1C4B844CG5<$+-72:,42767;:=8:5969541/(5"<(G6=7,8YpE]Vfg:559bfEVnNdHmOlMiHcBcBhG./3598-5(7D3Wd]UamV]wxׅԎ͑Ïut_puWM~P9]KqalcPH4*3'8(:'>,C0E2A2=2;221=?6:.18==C7;7;57899996;:<9853+9(?+=,71?G_oFWIOR?0/GX8Ǥ|RoQmTjNiJhGeFiHjK+/2062%1,<"J[IQaaenΝۉċ~ttcsmTZWNQBSE\OOG5-3'<-:&8";'C/D5<04-0,.,77;;>;HFMLHHBD587:8:99==B>?9909*>,2$;3_bY^PRh1*$' >X5zlġx[W1ayEiUfLeIfGiKoPqS:8==>85=%7E$FV;IYN]ex{qxjwqtna[eWTkOKSILB@6G@E>7,;-;)>'8:!B.E8=6533385>;D?E@E@HCDA<<796:698:@>D?A8;.8)7'2&KAolTOZOM2ET3ldzs]T5LI&ePcQeNcIfJoSuYw[YHPWLHVR7SW2OY4MVAUZ`cc}uog]cXfcZU\V@]X:b^ApWATKMI85>9A;<1F5;%H-< 8?)A6;8597<B@C>E>A78.:0=785:;7:5;6:?>C>>47)9+(6,UK^T[LhSgfHwldoM@A"*%8<jXj\lViPjRrZv\sYkV[fTPi^HjgFbcA`bJdc^`]f^Wg_Wd`XUSL:GD%VT.dd@qY?ZRWX>?<;977.I8<&L0;26!:054288>B?@8@6;/1$9-H?HC>><=8<:;A=F:?16'=1:3XOB6cPu[~ZnK/ -603EF&8BgVpbv`pXmWr\q[iQl]Zl]Vk_QjbMicMidNicSicW`YOoi]e_OZUANI3HD+SN8X>-}83`abe;<,+;7?58'I4:#,/8.><:?:>:7>5:19/:.<2>7>8HFGFFC@;<19&9$;'5+3-:5NE`TcSjXDQM4#) ;I(?J*<G%*64DlXxcmWv`{gq]bNZDk^Vk^Ul`Tl`RjaPkcPkcNkcLvpZrlVfaKlgS[VC<6&@:*S;/h-'87^^ab=>75F?B87)9*<.B6G@HF@A=>:5=4;09.9,9.8171<9=8<7;09)8#~;!|;%t+"~5/GAWP`UdW{hWtnX[]EV_B@M/:I(,=4F j|Tgt]t^w_lXcM\Hi_Uj`Vj`TjaRkbQkcPjcPjdNc\If_Lc^Jto\lfVNH:FB6J8,VMVMmgvqWS?<?=A>JGNKNKLGMIKG>:2*709/8,7*6)4)2*1)/*0)1*1(3%5!w9 v9$u2)?9MHUL|TJpTHhXHc^JkoXR\A3@$3B#/@4E!csOk{bqWkPdLbI^Fj`Vj`Vj`TkaUkbSjcQkdRkdRf_Mwr_jdTb\Le_ShdX^ZQ>0'iG;SDSFTI_XZUIGFHDIAH:A6:@>LED:6+5+9.9,9+9+7*6+3)/'/(0)1(4%{7$s9#q:&q5+{@:PH]TdZ~fZobR_\IPS>@J1/<".= /@ 2C#UdCzf~dkO^B^D`F^Dj`Tj`TjbUjbUjcSkdTkdTjdTmgWxrda[OYUIzvm}tU;,I(O,`6&q;/LERQ>C@JAM?L<DABIAH;B25*8-:-<.=.=-;/:/7-6-5,5+{7*u7(l7%h7(e1&tB;VM`W}aVm[OWP@ED2:?+@I4>J41?&,: /=#HU9ua}cfJX|<]CcI^DkaUjbUjbUjbUkdTjdTjdTkeWe_Qa]Q`\QܩW>*I3P9'8 qE<|kmDMFRKWKSGHC=E8J;3'7,9,:.=/|>1|>1}=1}:1|90z7.v6,s7,l7)f5'a3&X,#nF>}[QrVKXD9B6*2/ '),3#:E4AN:.;')7 ,:!CP6}lv^`DWv;aGfL\{BjcSicSicSjdTjdVjdVkeWieYnj_d`WsnhԤy`O=H;*XL>ӺrvSY;A9<@?D<F:M@6,:0:/:0{;/x<1v>1v>1r9.p7,n5,l6,l7/i7.e5+_3*R-$aC9jODZF;H:/A9.??3=A3)1",9(5B1,9(0;*.:&?H3vhSTp=Rn;a}Lb~MRn=icSicSicSjdTjdVieYieYieZhd[\YRifaxm[;5%ަVV@>LFOED6>2:2>6<3;2z<1v<1s=1q?4h8,e6,d5+f7/h91i:2f71^6.cE;^H;P>2<.#2*53'57,-3'2<1)5'0<02>0=H8/:)3<+sZnKJc9Of<^wO_uNIb:heRifSifUifUheVhdXjf[kh_eb[poj˷~{jzvjƨti>3J<SEH;A7:4~5.y4-}>5y?4p<1c4*e9.`8.c;1iA9h=6a4.f62kB<ymbTG?3'91$:8,46+,2(.6+.8/*6**6,.:.1;06>1?E9EP?=M2G\=J]?^rV[nR7K/gdQifSjgVifWhdXgeYif]iiapoj¸өWE<)K<7.?8G@F=y:3o6-n<3nB7_9._=1\:0W5+`;3pGAtGBgB:rfXQA93%42%68+25*+2**4++7-(4*'3)+5,.5-08-8>4?G8;J5EW?GYC[mWWiS3E/feQgfRihVhfWgeXeeYgg]hh`fe`z{uíjSAJ>x=5r6.v:2q60u>7o=4a7+_=1]@2X>/U;,Z<1hF<sMDqPGqcVLI831"23%6:,28,/6./90*5-'2*'1)(2)*1))0(/4-5=23A0<M;=N<QbPN_O->.edPgfTigXghZffZee[ff^gh`]^Xef`ýӾi\yJ@f4+n91h1*{F>uF<c;/cF8XA1[H7dQ@ZE4M3$aA4~dW`WFCD234$47&:>08>27?47A80:2,7/+5-,6.,3+)0(,1*19.-;,5F42C3CTDDUE):*cdRefTghXhi[gg[eg\ef^fg_kldnqhǾ̺ժQIl=5e:1b>2bH7XG3[P:cXBXL6J;&ZE2sbP\WCGI4<=+<?.>B4;A5:B7:D;8B:5?74>64>6292.5./4-3;07E4:K80A/<M;?P>+<*bcQefThiYhi[fh[eg\ef^fg_nqhy˺ŷƃWNf:1e=3nNA]F4\P:WO8NJ1UN4cY@hXA[O9a\HQS>EH5AE4?C49?17?49A6=G?:D<:D<;E=9@93:34926>3HVEGXE6G4=N;@Q?.?- \ No newline at end of file
diff --git a/PerlMagick/t/reference/jng/write_prog_idat.miff b/PerlMagick/t/reference/jng/write_prog_idat.miff
new file mode 100644
index 0000000..383ecdd
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_prog_idat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jng/write_prog_jdaa.miff b/PerlMagick/t/reference/jng/write_prog_jdaa.miff
new file mode 100644
index 0000000..119f225
--- /dev/null
+++ b/PerlMagick/t/reference/jng/write_prog_jdaa.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jp2/read_jp2.miff b/PerlMagick/t/reference/jp2/read_jp2.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/jp2/read_jp2.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/jp2/read_jpc.miff b/PerlMagick/t/reference/jp2/read_jpc.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/jp2/read_jpc.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/jp2/read_pgx.miff b/PerlMagick/t/reference/jp2/read_pgx.miff
new file mode 100644
index 0000000..d058df8
--- /dev/null
+++ b/PerlMagick/t/reference/jp2/read_pgx.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:///000333444444444222333222222111///...//////......111444666:::@@@CCCCCCDDDEEEQQQ[[[bbbjjjsssvvvuuussslllaaa___^^^\\\XXXVVVTTTTTTUUUWWWYYYaaafff\\\@@@666333333222000//////...///???ZZZuuuuuuOOOPPPwwwzzzWWW...///111222333222111333333333000///...111000000000111333555999>>>@@@???AAAEEENNNUUUZZZhhhrrruuuvvvtttkkk______^^^[[[WWWUUUTTTTTTRRRUUUXXXcccjjj]]]:::666555333333111///000111---888PPPkkkqqqGGGFFF___mmmWWW,,,,,,//////---...---...---......------//////000111111222555444777888:::>>>CCCGGGIIIMMM^^^kkkrrrtttrrrccc\\\]]][[[XXXTTTTTTSSSRRRQQQSSS[[[fffllleee===666444333333111111111111000///555VVVyyyHHH999777DDDOOOXXX------------++++++++++++,,,,,,,,,,,,...---...---//////...111333666666888<<<@@@AAABBBJJJTTT]]]gggrrrsss^^^YYYYYYXXXUUUSSSQQQQQQPPPPPPVVV___ggg}}}___AAA444000////////////111111...---dddsss]]]kkkaaa............++++++***'''***++++++)))))),,,---------+++,,,...333666555444666:::<<<<<<EEERRRWWWYYYccchhhZZZVVVUUUTTTSSSPPPNNNMMMMMMQQQYYY]]]ooo{{{VVV===000***......---...///---+++jjj^^^//////000111111000...++++++***)))))))))***------,,,,,,...111555666444222333555777444666GGGSSSVVVSSSZZZVVVUUURRRSSSRRRNNNLLLJJJMMMXXX\\\eeennnWWW:::*********+++,,,---,,,'''^^^UUU222333333666666444222///111...+++,,,,,,...000000000000333888::::::666333444777666333111999FFFOOOOOOQQQTTTUUUQQQPPPOOOLLLIIIIIIPPPZZZ^^^mmmyyy]]]999''''''***+++***(((%%%XXX~~~QQQ777777888:::===<<<;;;888888666333222222333333444777999;;;???@@@???:::888888999999888666888BBBSSSYYYVVVRRRRRRMMMLLLMMMHHHooosssSSSXXXcccxxx}}}aaa:::+++(((---,,,111NNNkkkvvvyyySSS888999===???@@@BBBAAAAAAAAA>>>===<<<<<<888666555888<<<???CCCDDD@@@<<<;;;;;;;;;[[[```VVVggg```\\\```___^^^___^^^QQQLLLeeetttuuu]]]ccctttlllmmmzzzttt___888555@@@\\\{{{{{{{{{rrrYYY666777<<<@@@BBBDDDDDDEEEDDD???>>>>>>===:::888777999===AAACCCBBB???<<<<<<:::TTT}}}aaaUUUeee\\\```eeeXXXaaaiiipppmmmnnnmmmaaahhhoookkktttqqq{{{ooonnnrrruuuzzz{{{|||GGGBBBwwwϱsss___333555777<<<BBBFFFHHHHHHEEEJJJBBB<<<;;;999999888:::===BBBCCC@@@===:::999===dddXXXSSS\\\YYYTTT\\\___```eeecccgggiiijjjgggcccbbbuuu~~~{{{ooo\\\jjjtttxxx{{{zzz||||||tttЉ{{{000...333888>>>DDDJJJIIIWWW~~~YYYCCC555222222888===AAACCC;;;555222666PPP\\\YYYWWW```eee___ZZZ\\\eee]]]dddhhhjjjhhhbbbcccfffiiippppppfffZZZ]]]ooozzzzzz~~~~~~{{{jjj쿿888333000444:::BBBLLLJJJdddqqqLLLAAA:::<<<@@@===CCCRRROOONNN\\\[[[___\\\^^^fffgggdddgggiiinnnggghhhiiihhhcccbbbbbbooo}}}bbb\\\^^^gggqqqrrrxxx~~~uuu@@@===666222666???IIIIIIZZZįgggRRR:::999MMM}}}|||qqq]]]XXX\\\aaahhhlllgggooonnnhhhrrrttthhhiiifff___dddeeeeeeyyymmm]]]___fffwwwjjjyyy~~~tttIIIGGGAAA:::777>>>FFFFFFPPP~~~hhh```uuuuuuhhhppphhhbbbfffjjjhhhdddgggiiicccaaabbbkkktttllldddhhhllliiikkk{{{ssshhh```aaafffaaammmttt|||PPPOOONNNIIICCC>>>@@@FFFHHHQQQqqqrrrmmmhhhnnnrrrkkkiiikkk\\\^^^fffjjjhhhaaa^^^```aaadddjjjjjjggghhhfff```uuutttxxxbbb```___^^^^^^cccIIIRRRQQQOOOKKKIIIHHHJJJLLLSSSrrrpppqqqpppeeerrrqqqllldddddd___eeekkkfffhhhddd___dddooobbb___```dddcccaaaeeelllrrrsssbbb^^^]]]\\\[[[yyycccPPPPPPPPPNNNNNNMMMNNNNNNNNNccc|||qqq```lllqqquuuwwwqqqbbbiiiccchhh```^^^```eeehhhllllllkkkjjjjjjggg```cccmmmooolll]]]```jjjeeecccaaarrraaaWWWYYYVVVjjj}}}۾OOOOOOOOOLLLNNNOOOPPPRRRPPPPPPXXXnnndddeeeqqqvvvuuucccXXXiiikkklll\\\bbbaaadddnnngggeeeffffff___fffrrrjjjooogggjjjwwwgggkkkddd``````yyyeeedddfff___\\\zzzwww~~~ppp{{{NNNNNNMMMLLLNNNNNNOOOQQQQQQQQQQQQ^^^}}}sssrrrmmmvvvppp]]]VVViiinnnzzzvvv^^^aaaiiiiiilllllliiijjjoooqqqbbb\\\jjj}}}oooccc^^^YYYYYYpppiiilllllllll\\\wwwZZZrrrNNNNNNNNNOOOOOOOOOPPPRRRRRRQQQNNNbbbwwwqqqlllfffZZZ```eeeeeegggzzzkkkfffmmmnnneeedddbbbcccvvveeeTTTFFF[[[aaasssdddaaa\\\```uuuggglllkkkjjj___ppp|||nnnPPPPPPPPPPPPPPPPPPOOOPPPOOO[[[fffhhh{{{qqqiiigggYYYiiihhhaaaggghhhqqqjjjjjj}}}yyyeeebbbfffooonnnhhh```vvvwwwoooqqqmmmlllmmmqqqpppccckkkkkkjjj```iii{{{]]]XXXxxxRRRRRRRRRRRRRRRRRROOO]]]|||ooozzzlllggg]]]jjjeeecccfffmmmiiigggmmm{{{mmmoooggg~~~~~~eeeoooqqqggglllssskkkeeejjjllljjjccc^^^|||{{{CCCVVVqqqOOOSSSTTTTTTTTTQQQ]]]{{{pppⲲlllggg```nnn{{{___qqqoooccceeedddeeekkkggg|||iiijjjiiiffflllnnnkkkeeehhhjjjlllkkkhhh^^^{{{ppp:::DDDsss}}}vvv[[[UUUJJJNNNTTTXXXUUU```~~~lll|||ӻkkkwwwxxxlllccchhhgggvvvvvviiiiiiccc^^^fffhhhiiiyyyssslllooolllkkkkkkkkkkkkmmmkkkfffhhhiiimmmjjjeeennnzzz}}}\\\NNNAAAVVVwwwyyy||||||ssslllcccfffAAAEEEPPPTTT```yyywwwfffrrrlllXXX^^^tttaaa\\\dddgggccciiihhhccceeeeee```yyyrrraaaggghhhiiieeegggjjjkkkllllllkkkhhhfffhhhiiilllkkkcccyyymmm444@@@555SSSnnnqqqxxx~~~zzzuuurrrqqqppp555999FFFMMMfffoooWWWeeegggZZZ\\\xxxccc___ccceeeeeeaaagggaaabbbcccdddiiicccaaalllllljjjhhhiiinnniiikkkkkkmmmiiieeefffeeeffffffjjjxxxEEE***000VVVppp|||zzzttttttwww---...777CCC]]]aaabbb|||___]]]]]]ppptttaaacccfffaaaddd```rrrdddcccaaabbbiiiiiinnnnnnhhhjjjooooooiiihhhlllnnnpppjjjdddddddddbbbaaazzzxxxbbb555///GGGŁpppwwwxxxwwwwww~~~///,,,000;;;NNNYYYrrr}}}ddd[[[]]]^^^eee~~~qqqcccfffdddggg```aaacccppp```aaabbbaaacccnnnpppiiixxxsssjjjiiikkkmmmnnnmmmkkk___``````ZZZZZZzzzrrrBBB000999WWWnnnxxxuuu|||}}}zzz===<<<;;;AAAKKKRRRdddzzztttccc]]]^^^```gggdddeeeeeegggeeedddggg___[[[jjjwww[[[^^^bbbiiimmmnnnmmm|||llliiijjjkkklllooommmnnnkkk^^^YYYXXXQQQlllvvvfff555HHHNNNAAApppwww{{{NNNNNNOOOPPPSSSWWWZZZgggpppiiiYYYUUUVVV[[[aaacccggglll[[[```iiihhheeeeeeggg___UUUaaaiiipppmmmkkkooommmmmmddd]]]```iiimmmllllllllllllmmmoooiiiZZZUUUOOOLLL|||sssmmmiiijjjUUU;;;222???qqq~~~[[[\\\\\\\\\\\\_________^^^]]]ZZZMMMGGGOOOXXX]]]pppsssccc___dddhhheeeeeegggaaaPPP\\\___eeekkklllmmmmmmfffYYYXXX]]]kkkooonnnmmmnnnnnnmmmhhhXXXSSSQQQKKKMMMjjjfffjjjxxxZZZ,,,666666888>>>tttwww```aaaaaaaaa```ccccccaaabbbaaaaaaZZZHHHBBBDDDGGGMMMssswwwccc___dddeeeeeeeee```NNNQQQ^^^jjjuuujjj]]]___WWWXXX[[[YYY[[[hhhqqqqqqqqqiii\\\SSSOOOOOOMMMEEEUUUeeeiiikkkfffFFF---<<<KKK999888;;;tttxxxuuuaaaaaaaaabbbbbbbbbcccccccccccccccbbbUUUDDD???===???jjj|||fffbbbfffhhhiiijjj___dddsssyyynnnYYYYYYTTTOOOOOOQQQSSSSSSXXX___ddd___UUUPPPPPPMMMLLLIIIGGG]]]```gggkkkwwwlllNNNdddLLL888777===uuu{{{wwwvvvaaaaaa```dddcccdddddddddddddddddddddaaaPPP@@@;;;[[[eeewwwyyymmmooorrruuuvvvxxxxxxuuusssjjjYYYUUUQQQNNNNNNNNNLLLLLLLLLNNNQQQRRRPPPOOOLLLGGGIIIEEEMMM___bbbfffiiiUUUZZZjjjLLL;;;:::777;;;kkkqqq{{{sssaaabbbcccbbbbbbcccccccccdddddddddddd```aaaXXX===VVV___bbbqqqrrrnnnjjjlllqqqppprrrsssqqqqqqjjjVVVOOOOOOOOOPPPNNNMMMLLLLLLLLLKKKLLLLLLKKKIIIGGGEEEBBBOOOccceeeggghhhdddaaaUUU===777;;;888777[[[oootttzzzoooaaabbbdddbbbbbbcccccccccddddddccc\\\pppzzz:::777;;;;;;IIIcccnnnlllqqqrrrrrrrrrpppoooppp^^^PPPOOONNNOOONNNMMMMMMMMMLLLJJJJJJJJJJJJGGGDDDCCC???LLLfffiiiggg[[[LLL999@@@EEE===777777666PPPrrrmmmssstttkkkbbbbbbdddbbbbbbccccccddddddccc^^^㓓EEE:::777...GGG{{{jjjqqqqqqpppnnnmmmooofffRRROOOOOONNNLLLLLLMMMMMMKKKIIIFFFGGGFFFFFFDDDBBB<<<HHHhhhcccMMM;;;222333111:::DDD888000333FFFeeelllqqqqqqhhhccccccccccccccccccdddeeeeeecccjjj쟟JJJ777JJJ珏dddiiillllllmmmnnnhhhTTTPPPNNNMMMLLLLLLNNNNNNJJJFFFEEEEEEEEEFFFDDD>>>777JJJ]]]AAA444777888777555444>>>AAA333+++DDDttt```eeekkkrrr^^^ccccccccccccccccccdddeeeeeebbbdddmmmFFFiii\\\jjjkkknnnbbbTTTPPPNNNMMMLLLLLLLLLJJJFFFEEEDDDDDDDDDEEEEEECCCGGGUUU777222555444444444555333444===???///HHHZZZ\\\[[[gggrrrMMMddddddddddddddddddeeefffdddlllooouuuぁZZZffflllaaaUUUQQQOOOMMMJJJIIIHHHEEEEEEEEECCCDDDEEEFFFIIINNNtttjjj...444444333222111111222000222:::;;;GGGQQQLLL[[[UUUffflll>>>ddddddddddddddddddeeefffeeeϯ______```VVVRRROOONNNMMMLLLIIIGGGGGGEEEEEEFFFIIINNNOOOPPP|||TTT...444444333111000111000...000000333888888===NNNSSShhhddd333dddddddddeeeeeeeeeeeehhhfffrrr~~~YYYPPPLLLMMMLLLNNNOOOMMMKKKIIIHHHGGGFFF???OOOVVVZZZqqq999555555666555222111111///---...000000222<<<>>>999DDDbbbXXX111cccdddeeeeeeeeeeeeeeehhhgggrrrTTTBBBAAAGGGKKKJJJIIIJJJJJJJJJ]]]CCC===DDDmmm\\\555::::::;;;;;;:::999999555111///,,,,,,///111AAADDD888JJJKKK555bbbccceeeeeeeeeeeefffhhhfffpppWWWGGGNNNNNNOOOLLLLLLaaaEEE@@@FFFdddYYYDDD<<<<<<;;;<<<===???<<<>>>;;;999444///...,,,///AAACCCAAADDD666aaaccchhhffffffgggffffffhhhfffJJJMMMMMMLLLKKKJJJHHHMMM^^^```SSSRRRPPPHHHAAA======>>>======>>>???AAAAAA===:::===TTTVVVEEEJJJSSS<<< \ No newline at end of file
diff --git a/PerlMagick/t/reference/jpeg/read_non_interlaced.miff b/PerlMagick/t/reference/jpeg/read_non_interlaced.miff
new file mode 100644
index 0000000..2cba3e5
--- /dev/null
+++ b/PerlMagick/t/reference/jpeg/read_non_interlaced.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:1.'2/(41*72,94.;4.:3-;2-;0*9.(8-'6+%5*$6+%7,&7,&42#53'74-=84D=7HA7JC3JC0JA2VC2pG3H6G:EABG@K8D=@?7?0@.B0?*:">19-9-@,D)D*C2C=FFV8.-8(+;18/0B)/@-/0/*-*%./4-'1V75O?f_|`tXIhZNbyuvvxjTTL./)0/*21,63.63.72.61-61-80-7/,6.+4,)4,)5-*6.+7/,42&30'41,940?74B;3D</D=-JB7TB4hC1C1D5D<DEEK=A?=@3=,>+C0C0@,L7A29-:,=+?.A5C>HIX7003(/91<36A06653"3):4(354-,2G13l<:Zf|epF9nB:a^[lorgSUH,.+-/,/1.11/21/10.2.-1-,3/.2.-1-,0,+0,+2.-3/.40/41*30+2.+50-;31=60?6-?7,D=5K=4Y<.m:)9*=0A<GCD?F9C1=(<)A/C2C/C2:,6(8+=.?2B=FGYWW@833)24/:14;25,846+=1!23-,037.3H*2tRkpqEA|01_17OOY[IUIBK8)-,*.-+/..0/-/.---++++)*-+.,*-+),+),,*--+./-00.13/,2.-1-,4/,91/<41>50>5.@85E82N8-\6)s5&:-A5G>H:I7F/?'<(=-@/?.8.8+<+{B.~E1H9PGXVt^`R<G96924,*4+.,54!827) 0,)/553465+,k]lkv\k~_pw|tt]kT)-,*.-+/.-/.,.-,,,****()))+))+((*'')((*))+++-,,.0,-/+*/+(2-)80-;4.=4/=4/@53B73J92S8-c7*|:,B4G9@1E1F.A+<)=/=/;-;.>0B5C6F7Q@lVkimMeO=J90-&/##6+/7266*,2,0235/4.+.#ei[Ƭcr[.0-/1.02/11/10.0/-0,+/+*,*-+),*(+)'**(++),,*--+..*+.*'/,'3/&92(;4,<3.;2-<-*?1.B5/G4-P2(c3'|:.?37,?0C0A/>.>2=0<,e;%o:(8/85>=[Mipv\{\I`F3<++'6#%="+3,42+2,&()&&*UbFvԔNj{~lgGVA34.54/65096196194072.61-40/3/.2.-0,+0,+1-,2.-3/.3/.41,63*:6*?9+?9-=4+;2-?*%@/(?2,=0*C,&S,%k4-~;373?7D9~@3<0;/;.|:*<1w<.s>0~B7MDdXrwsjf^JcE8C26+'5)*/2),.2""52+Q_Hyiu[vb|myqusKZG:70;81<92>93>93?82>71>50;63:5283061.61.61.72/830:63;81></B?.FA.D>.A9.=4-J3+H5.B71>3/@.*Q/-j95|A=>AEB}F?z@5}906,~6(u6%NWQJoYA^cCohNk]qmzx{y{hgLiM>@35!" )&6.,<#&I06RGM[f^mkh[mfqoknu}loJWE9;.=>6@?;B>=A=>C==GB?JEAK>8K?1F;)F:,C845,-0-&>?1R'1G.2A>5BL1CM(=B"9=/:@@,C9Z>;:=>=E7G5@484K8E6D8G?C<968=?J@GP>of=kpGfSMV5P(IHXP]Zgbnbp^mViRe@KY5)3-N2tXCraeiomxtt|oP]I66,983=<8B>=D@?FA>HC=LE=B92E=0B;+E=0NG?IB<<8,;:%EL:AH8CD4MB.T>)R8'I5,C54@7.|FDLOA?<-B.F5C;C0=.:1<8=<:<:>;D36B8X?dL\VLTAM?G&C,K5U;`>e?kAmBo\X`iNC`H<}pȿrxlVaP21,43/:65@<;FA>JF=MG;LF6IHDQPLHDC843952=90<6(<7#$96>&L@0Z=5\;4V;4H<0></^/%D@IG811 <)D3<2<%8&1%/(2.84602+1.=5NCTOKO?D@9I55D7H9Q9Z8_<iCpHxS^}fnddʍzs51.3/,40-;63C>8LF:NI6OH5\\fyzxxWWsA@R:7>933<34:0&M<2YB:P><<87/83)9,&9#<)=.5--!3%@/=2/(=&?*9)/"-#4'5 /0':0H?KG>A219(I)PDQKNSI\GbJkQsW{CrTufvah;8163.4/+61-@91IA4OH5QK3_axĵሉonTMlA6XI;JH9>A839>8;JMGUXXSPdI@K5;(0 4(?2@7:541=4D:C970.+2*6#6- 5'C3K?A84+:'I0G8E?DJDVFbJlPuSyMaSfbqRW⧩EA5?;095,92*>5,F>1OG4SK6[[sʻzaV9Po6<H@5/_NFouwbsITF3<+:*?3=44/51@<26;;><68,4,22.6*8+:)E1P=I:8*7(B0F7C<CCHQNbQkQoNnbbV]enQNzqMJ7IF5F@4A:0@7.F<0MD5SK8WWc㑉jqczMKWQdmZoBR1::4;4?5=36/1*6->51*4&7(7/26+4,233<29/A5OBNB=06';*L8H7I<RL^_cl_lYiyv_fw|bW\O<RP9RM9NH8IA6D<1F<2LB6QH9TTR맫wNV=@3>*;68K?6<>@?;816/;2<-8%>:<B%>52502532+,&40HFOJD;=.A.:+6':,J@`[lojsco|bor7O5PN5XS=XS@RK;PF:TH<VH;UE8b\F{җޕŏzipHN8A=F=E<B?C=AC?B6A+B)?*9,4-1-::+,3/@6:&11&20E60#4+E?F@GAD;2'C0D01>)SDrm[devwx[g\bz\YkEXR<ZS@YQ>UI9TG7XK;[K<YI9RCHh^onԈԄuckCwEY7H;FGJBA=9>9=7;79-8#8"8'6,3011=C,6*4051.8/>9;890.&.(4/4.;1D7G8;.=-1 =)K;qkkro~qvI[[dy|iپ׻ǵ˚ر\P@[P>YL;UH5XI6^M9`O;_N:VFFdP\`NtmgĜkBP.B.:?@KED:=2>9>;B<>3:(7$6*5214.4'407'A/@<B>;0+C?GDC@;7816,D5ZI5.5-3);-=.jbzzD]IX~[fU{^b^zbxlxzƻ[K>ZJ;XG5XG3\L5_O8`O;_N:bU3kS7bG>f]p|{owE1@G;:A8E4<+819<2=KDH<A0:,5-23+3%/%/#52NFfJcBN72&93KFFB9550+$0&I=412163900$_U{hyEf?OiR2`MhZqgk|dsovû\J@[I;ZI7\L5\L5\K7ZJ:YI:QH'dO2dLBofypG?SUDB>1;(8'<179'0B;D9A29,4014,5%/,4*5=QSjJ^7@.),7+H>C;72951/0.B@3//05651,UJyRhDiHPfQ2zdpkpi}_c}_l`ND_M?_N:_P9ZN8UH7UH?XKEcXfn_viYvoñ[jIR;@515)=-L<L>9/5.=2?39.52:==C:?4:/5;?BI8A6<GFVLPCTHKB?:?=>?=@AF2+,,.02//%KAqQnBeFB]W7j_\kVxP`|YwYiwuk`PC_O@_S=_S=ZO=UKA\RQg\b~}nq»šugNSFI@@8590M?XFM81*=3@47-2.=<IIMLHWOSPLA<55LSjus}LDE=@99430778:.07*/+)*/.8.B:c{Jj:XZ=-IT2hid{bz]~^sSvX~ewem^^NA[N=\Q;\T=YR@ZSKi`eyq~vsq{nš韮wrgjaYV??--=8NCL=1,>5?31')#51EBNHOfai_W:/(&DO\pQj860-63952.;8=;*(>+6-().+=4:3q{VqAc>Z<@%5M+yvWh`u[YDbnPiKbHKl5F\5SN8YQ>bRB_N:]QAmhnyyqu[[xxݵ~glXi^{|hmOOA;/%B4A<F@FA>;5532:2@36A\aVV>@>I6E)54:(527989482:4906)8+<--%))63F>v8eWn?A]Q;5D'Q^@a\~1e6kKjNcM[yGXsF\vG?>)LF6XO@cWImd]qo|kmdhmqʂКןѡϩ̘rjyd^N}QHdcmoond[?/9'6.:1<3812-3-<0D243QMHD/01=.>%50=+637989472727.3(4%<,<+;050NTWs8iKgi.2GB,%:PaA`oFWw4^9lNkOeM_}I_{HcJ25"??3FB9VQKljmffTYX^v}ׁيڅςyȏLjzl_}aXGtE;TQonzpcF36 4+7,9-9.7.8.?0F2:,L?>4%&)3(:!3(8.558987362635.1(4!>+A-D042Qi<d<hy1I/ 0;RnFybnSbEmQkOfLaGdGiJ,3#7:112->>>^^fY]zVZrv́}ليۋӌ}unbla`KwRBVNgbh`RD;):(7,9+=,@0>0:,;*@*8%D5:2+,2:6A0=2=055787747687733+9"?+5"=+?EIj;_ARY:?-(D[/yӣoVoSpRkOiMeIdFfFkH-1#36-++)352QUXXZohjޖ퀂ρƒϏtqgfd]C_hMz[GQGTOIA2(/#8,6*5&;(B/A19+6%7$,"5-7376CCKKHHCF337587778:<<<78.>#?,(82Ub?\MZI=-#%FU.x\͑oIb+_|<pHeKcGcEgFmJqL<:-@=4983>>4NPCSSSdbxwsqm~wzpjafc[D_[.icIUE?6A<>60%4(0&8-6&9&C0E6>29-;-0/55;:?<F<KAG@>:54858677:=?>@8<.>&<+,#DDcoBMaV#CBT*uXmkI^38R"d@k>dHcEgFnLtQvUUM@VNCVPDXS?VU7US<_XRlbm{nj_mc[YcZU\RP]TMd\Id]@ZKQJ4153:16*?.0 @57(8$A.E7?6=5@8<B:===?7<,?/=33176958665;;?<>4;);+6":,URZZVJrU_gB~~ajpL>B+()A!iMsFlNiJlJsPtUqVhZMcWKg^OleIgb:gb:mcJi\SfVVeYKdZ?VL1I@1XMIh]YeZTVRVV5:214+6$F08D;6)2 9(<17285=;;A4:668-4 9(>78:97:6856699=:=/8%;2j0xE0_UH:|iK{ZsUl>#+83 4/,=BE,A2dSyQuWqRqOvSrSgNk_Qk_Qk_Ql`Rl`RmaSmaSmaS\YJnhXf]N]QCMF6DB5KOA?G:bB+cWZX3..E,H2:)>99)67!;3:><?==82:0=*?&@%>(=+;.@7B8D:A5<19-8-;.7-{9-{A3OCZQ\NqU=NO-,7J,<J1@B74-'>=)kOpLjNu[z`pXcK\Fk_Qk_Ql`Rl`Rl`RmaSmaSmaSwp^rkYj^NpdV]TE;8);=/>E5FI*J9YYRU2//$<15-91?0D3D8A?ABB=C696:3;0<,;*:*9+8-8-;/=0</:+7)8)|:*t+"x8,J<UIXP^P}iPitRRbGObF?M4AC8:2/=>,gMtQoStWtYmQcK_Hk_Ql`Rl`Rl`RmaSmaSmaSmaSh]Kj_Mj]Mym_pgXPJ<FD5=@/sSDJGT]ZfHL@6J:Q@QMWNTLJHCGCDA5<$=:<6:491~807.7/704&5)8*9*8)z9't9's:'r4'A6MCOHLD{OBb\BPhFdrYN^C2@)9<1;62=>.`vHxZuXoTiLdJaH`HjaRjaRjaRkbSkbSkbSlcTlcTk^K|o^pcSfZNh^RjdV_\K76$uF@LMCHDHVSVKI?J@@FBE<=46:;FEE<=*y@5{?5<493:2}:1z<1v<0z7.{9-z:.x:-w9,t9)r9(r9(l8*{A5MDVP]VeWchQJgHJVB<L2-<%28*:72;<.Rg>pVx[jM]B]C`H_FibRibRjcSjcSjcSkdTkdTkdTsdQ|o_dXL\SJ|umoEG175 A4!V;*p:.CA@J)=2E<GAEA<C=FAB?:7y@-}>-;-;.;.<-|>/x@/v=6v=6v;3u:2u9/s7,r4)q3&a3$vB5QI[U_Ug^OIVB3M47@/=K4<K44<-43.68-FW5kVw]cIV}>]DbK^JjcSjcSjcSjcSkdTkdTkdTleUi\KfZLaZR֗y:C(&=!0G-'&wGC}fx:JDMPNSIMAB:;:7<<';':'9):,;,=-}>-t=8s<5s:3r71r7/p4,o0'l-$W-tD8VOvTJQH94=,'4#!,,2$9F2>P8/:*01,34,AQ4tcpY\GTw?`NfSZwIicSicSicSjdTjdTjdTkeUkeUthZg^UrnkӣUZF6D3GQFrnVP=5;0B5C8A<BA;.;-;-<,};-};/~:191o;0m9.k7,k7,l7/k6.h3+e0(V,m>4rLCVH;6C1,C1:B7E;9,/$,9%2D,,9(57236/;K1|m`NPp?PpA`}Qa}TPjCicSicSicSjdTjdTkeUkeUkeUmcW`YQggefr\74+ުQD6,B8L@F;@5=7?6?5w>3t>4v;5|8778h9)f6(e5'f8+h9/g;0d8/`5,mA6mA6Z:/43!6=+270?),891*5$-?'1?.BD?4700>'viQpDEd8Kg>]yQ[uPF^<pbUlcTheTefVefVhfYlfZoe\_hMoui͸{|ltwlԿmq33>7P>H/GA<7t74n95sB=o?5l;,i6#a82a6/e82o>7m;4f4+i7.sA8yl\cQ28,(/'9?;062$+$07/.6+,4)-5*19,4<-7?0?H7HQ@;T7HaCLfCbzX^sT8L3nbTkdTheTefVfgWhfYlfZne\dmR}ҿƽۢM?.<,:4=7GCFEt=:k4-p:.yA4i40j73d5/]2)`<0iL<iP<]H3rzeRYG06*,1*4;4.5.'.'-4,,3+*1)*1)-5*/7,08+7?0>F75L2AX<FZ>ZoPUhL/A+kdTjdTgfTfgWfgWigZlfZmd[ZdKw}sȷxoDAI@z:1p3.u;7n95s>8r;4l6,o53k84d90W:,RA-UO5V[=U^?hkVEI804&05.271070180-7,-3/*0,)0)+2++2*)0(-5*4<10B*<N6=O5Q`IO^I-:)feSgfThgUhfWigXjfZlfZle[XdLfme㳳h[vJ=_5)g?5`8.rJ@pH>f>4iC8`>2_H8`T>MK27>BP-brN]_J=>,35(9<33816=5;E<3=2286/53.40/51,3,)0)*1)/6./>)8G24C.ER@HSC.8-bgSdgTfgUigXjgXjfZieYieZes\nxpпúǶp^JYG3UC/XG3YN:QK5TT:X_@JS4<C"IN.fiJ^\GCB0=>0AC87<59@8?I>7B49?=7=;6<87=93:3.5..5-2916F,;J30?,=J9BM?.8-^gR`hSehUjhYmgYlfZieYhdY_nYy~ǾmiNLH+MI,[Z<IO3LU8HU7AP/GU2Z_?a^?ZS6b]GRM:HF9EE;=@78@58C55A3=C?;A=<C<=D=:A94;33;07?4GZ<I[A8J4AO>ESD4@2 \ No newline at end of file
diff --git a/PerlMagick/t/reference/jpeg/read_plane_interlaced.miff b/PerlMagick/t/reference/jpeg/read_plane_interlaced.miff
new file mode 100644
index 0000000..2cba3e5
--- /dev/null
+++ b/PerlMagick/t/reference/jpeg/read_plane_interlaced.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:1.'2/(41*72,94.;4.:3-;2-;0*9.(8-'6+%5*$6+%7,&7,&42#53'74-=84D=7HA7JC3JC0JA2VC2pG3H6G:EABG@K8D=@?7?0@.B0?*:">19-9-@,D)D*C2C=FFV8.-8(+;18/0B)/@-/0/*-*%./4-'1V75O?f_|`tXIhZNbyuvvxjTTL./)0/*21,63.63.72.61-61-80-7/,6.+4,)4,)5-*6.+7/,42&30'41,940?74B;3D</D=-JB7TB4hC1C1D5D<DEEK=A?=@3=,>+C0C0@,L7A29-:,=+?.A5C>HIX7003(/91<36A06653"3):4(354-,2G13l<:Zf|epF9nB:a^[lorgSUH,.+-/,/1.11/21/10.2.-1-,3/.2.-1-,0,+0,+2.-3/.40/41*30+2.+50-;31=60?6-?7,D=5K=4Y<.m:)9*=0A<GCD?F9C1=(<)A/C2C/C2:,6(8+=.?2B=FGYWW@833)24/:14;25,846+=1!23-,037.3H*2tRkpqEA|01_17OOY[IUIBK8)-,*.-+/..0/-/.---++++)*-+.,*-+),+),,*--+./-00.13/,2.-1-,4/,91/<41>50>5.@85E82N8-\6)s5&:-A5G>H:I7F/?'<(=-@/?.8.8+<+{B.~E1H9PGXVt^`R<G96924,*4+.,54!827) 0,)/553465+,k]lkv\k~_pw|tt]kT)-,*.-+/.-/.,.-,,,****()))+))+((*'')((*))+++-,,.0,-/+*/+(2-)80-;4.=4/=4/@53B73J92S8-c7*|:,B4G9@1E1F.A+<)=/=/;-;.>0B5C6F7Q@lVkimMeO=J90-&/##6+/7266*,2,0235/4.+.#ei[Ƭcr[.0-/1.02/11/10.0/-0,+/+*,*-+),*(+)'**(++),,*--+..*+.*'/,'3/&92(;4,<3.;2-<-*?1.B5/G4-P2(c3'|:.?37,?0C0A/>.>2=0<,e;%o:(8/85>=[Mipv\{\I`F3<++'6#%="+3,42+2,&()&&*UbFvԔNj{~lgGVA34.54/65096196194072.61-40/3/.2.-0,+0,+1-,2.-3/.3/.41,63*:6*?9+?9-=4+;2-?*%@/(?2,=0*C,&S,%k4-~;373?7D9~@3<0;/;.|:*<1w<.s>0~B7MDdXrwsjf^JcE8C26+'5)*/2),.2""52+Q_Hyiu[vb|myqusKZG:70;81<92>93>93?82>71>50;63:5283061.61.61.72/830:63;81></B?.FA.D>.A9.=4-J3+H5.B71>3/@.*Q/-j95|A=>AEB}F?z@5}906,~6(u6%NWQJoYA^cCohNk]qmzx{y{hgLiM>@35!" )&6.,<#&I06RGM[f^mkh[mfqoknu}loJWE9;.=>6@?;B>=A=>C==GB?JEAK>8K?1F;)F:,C845,-0-&>?1R'1G.2A>5BL1CM(=B"9=/:@@,C9Z>;:=>=E7G5@484K8E6D8G?C<968=?J@GP>of=kpGfSMV5P(IHXP]Zgbnbp^mViRe@KY5)3-N2tXCraeiomxtt|oP]I66,983=<8B>=D@?FA>HC=LE=B92E=0B;+E=0NG?IB<<8,;:%EL:AH8CD4MB.T>)R8'I5,C54@7.|FDLOA?<-B.F5C;C0=.:1<8=<:<:>;D36B8X?dL\VLTAM?G&C,K5U;`>e?kAmBo\X`iNC`H<}pȿrxlVaP21,43/:65@<;FA>JF=MG;LF6IHDQPLHDC843952=90<6(<7#$96>&L@0Z=5\;4V;4H<0></^/%D@IG811 <)D3<2<%8&1%/(2.84602+1.=5NCTOKO?D@9I55D7H9Q9Z8_<iCpHxS^}fnddʍzs51.3/,40-;63C>8LF:NI6OH5\\fyzxxWWsA@R:7>933<34:0&M<2YB:P><<87/83)9,&9#<)=.5--!3%@/=2/(=&?*9)/"-#4'5 /0':0H?KG>A219(I)PDQKNSI\GbJkQsW{CrTufvah;8163.4/+61-@91IA4OH5QK3_axĵሉonTMlA6XI;JH9>A839>8;JMGUXXSPdI@K5;(0 4(?2@7:541=4D:C970.+2*6#6- 5'C3K?A84+:'I0G8E?DJDVFbJlPuSyMaSfbqRW⧩EA5?;095,92*>5,F>1OG4SK6[[sʻzaV9Po6<H@5/_NFouwbsITF3<+:*?3=44/51@<26;;><68,4,22.6*8+:)E1P=I:8*7(B0F7C<CCHQNbQkQoNnbbV]enQNzqMJ7IF5F@4A:0@7.F<0MD5SK8WWc㑉jqczMKWQdmZoBR1::4;4?5=36/1*6->51*4&7(7/26+4,233<29/A5OBNB=06';*L8H7I<RL^_cl_lYiyv_fw|bW\O<RP9RM9NH8IA6D<1F<2LB6QH9TTR맫wNV=@3>*;68K?6<>@?;816/;2<-8%>:<B%>52502532+,&40HFOJD;=.A.:+6':,J@`[lojsco|bor7O5PN5XS=XS@RK;PF:TH<VH;UE8b\F{җޕŏzipHN8A=F=E<B?C=AC?B6A+B)?*9,4-1-::+,3/@6:&11&20E60#4+E?F@GAD;2'C0D01>)SDrm[devwx[g\bz\YkEXR<ZS@YQ>UI9TG7XK;[K<YI9RCHh^onԈԄuckCwEY7H;FGJBA=9>9=7;79-8#8"8'6,3011=C,6*4051.8/>9;890.&.(4/4.;1D7G8;.=-1 =)K;qkkro~qvI[[dy|iپ׻ǵ˚ر\P@[P>YL;UH5XI6^M9`O;_N:VFFdP\`NtmgĜkBP.B.:?@KED:=2>9>;B<>3:(7$6*5214.4'407'A/@<B>;0+C?GDC@;7816,D5ZI5.5-3);-=.jbzzD]IX~[fU{^b^zbxlxzƻ[K>ZJ;XG5XG3\L5_O8`O;_N:bU3kS7bG>f]p|{owE1@G;:A8E4<+819<2=KDH<A0:,5-23+3%/%/#52NFfJcBN72&93KFFB9550+$0&I=412163900$_U{hyEf?OiR2`MhZqgk|dsovû\J@[I;ZI7\L5\L5\K7ZJ:YI:QH'dO2dLBofypG?SUDB>1;(8'<179'0B;D9A29,4014,5%/,4*5=QSjJ^7@.),7+H>C;72951/0.B@3//05651,UJyRhDiHPfQ2zdpkpi}_c}_l`ND_M?_N:_P9ZN8UH7UH?XKEcXfn_viYvoñ[jIR;@515)=-L<L>9/5.=2?39.52:==C:?4:/5;?BI8A6<GFVLPCTHKB?:?=>?=@AF2+,,.02//%KAqQnBeFB]W7j_\kVxP`|YwYiwuk`PC_O@_S=_S=ZO=UKA\RQg\b~}nq»šugNSFI@@8590M?XFM81*=3@47-2.=<IIMLHWOSPLA<55LSjus}LDE=@99430778:.07*/+)*/.8.B:c{Jj:XZ=-IT2hid{bz]~^sSvX~ewem^^NA[N=\Q;\T=YR@ZSKi`eyq~vsq{nš韮wrgjaYV??--=8NCL=1,>5?31')#51EBNHOfai_W:/(&DO\pQj860-63952.;8=;*(>+6-().+=4:3q{VqAc>Z<@%5M+yvWh`u[YDbnPiKbHKl5F\5SN8YQ>bRB_N:]QAmhnyyqu[[xxݵ~glXi^{|hmOOA;/%B4A<F@FA>;5532:2@36A\aVV>@>I6E)54:(527989482:4906)8+<--%))63F>v8eWn?A]Q;5D'Q^@a\~1e6kKjNcM[yGXsF\vG?>)LF6XO@cWImd]qo|kmdhmqʂКןѡϩ̘rjyd^N}QHdcmoond[?/9'6.:1<3812-3-<0D243QMHD/01=.>%50=+637989472727.3(4%<,<+;050NTWs8iKgi.2GB,%:PaA`oFWw4^9lNkOeM_}I_{HcJ25"??3FB9VQKljmffTYX^v}ׁيڅςyȏLjzl_}aXGtE;TQonzpcF36 4+7,9-9.7.8.?0F2:,L?>4%&)3(:!3(8.558987362635.1(4!>+A-D042Qi<d<hy1I/ 0;RnFybnSbEmQkOfLaGdGiJ,3#7:112->>>^^fY]zVZrv́}ليۋӌ}unbla`KwRBVNgbh`RD;):(7,9+=,@0>0:,;*@*8%D5:2+,2:6A0=2=055787747687733+9"?+5"=+?EIj;_ARY:?-(D[/yӣoVoSpRkOiMeIdFfFkH-1#36-++)352QUXXZohjޖ퀂ρƒϏtqgfd]C_hMz[GQGTOIA2(/#8,6*5&;(B/A19+6%7$,"5-7376CCKKHHCF337587778:<<<78.>#?,(82Ub?\MZI=-#%FU.x\͑oIb+_|<pHeKcGcEgFmJqL<:-@=4983>>4NPCSSSdbxwsqm~wzpjafc[D_[.icIUE?6A<>60%4(0&8-6&9&C0E6>29-;-0/55;:?<F<KAG@>:54858677:=?>@8<.>&<+,#DDcoBMaV#CBT*uXmkI^38R"d@k>dHcEgFnLtQvUUM@VNCVPDXS?VU7US<_XRlbm{nj_mc[YcZU\RP]TMd\Id]@ZKQJ4153:16*?.0 @57(8$A.E7?6=5@8<B:===?7<,?/=33176958665;;?<>4;);+6":,URZZVJrU_gB~~ajpL>B+()A!iMsFlNiJlJsPtUqVhZMcWKg^OleIgb:gb:mcJi\SfVVeYKdZ?VL1I@1XMIh]YeZTVRVV5:214+6$F08D;6)2 9(<17285=;;A4:668-4 9(>78:97:6856699=:=/8%;2j0xE0_UH:|iK{ZsUl>#+83 4/,=BE,A2dSyQuWqRqOvSrSgNk_Qk_Qk_Ql`Rl`RmaSmaSmaS\YJnhXf]N]QCMF6DB5KOA?G:bB+cWZX3..E,H2:)>99)67!;3:><?==82:0=*?&@%>(=+;.@7B8D:A5<19-8-;.7-{9-{A3OCZQ\NqU=NO-,7J,<J1@B74-'>=)kOpLjNu[z`pXcK\Fk_Qk_Ql`Rl`Rl`RmaSmaSmaSwp^rkYj^NpdV]TE;8);=/>E5FI*J9YYRU2//$<15-91?0D3D8A?ABB=C696:3;0<,;*:*9+8-8-;/=0</:+7)8)|:*t+"x8,J<UIXP^P}iPitRRbGObF?M4AC8:2/=>,gMtQoStWtYmQcK_Hk_Ql`Rl`Rl`RmaSmaSmaSmaSh]Kj_Mj]Mym_pgXPJ<FD5=@/sSDJGT]ZfHL@6J:Q@QMWNTLJHCGCDA5<$=:<6:491~807.7/704&5)8*9*8)z9't9's:'r4'A6MCOHLD{OBb\BPhFdrYN^C2@)9<1;62=>.`vHxZuXoTiLdJaH`HjaRjaRjaRkbSkbSkbSlcTlcTk^K|o^pcSfZNh^RjdV_\K76$uF@LMCHDHVSVKI?J@@FBE<=46:;FEE<=*y@5{?5<493:2}:1z<1v<0z7.{9-z:.x:-w9,t9)r9(r9(l8*{A5MDVP]VeWchQJgHJVB<L2-<%28*:72;<.Rg>pVx[jM]B]C`H_FibRibRjcSjcSjcSkdTkdTkdTsdQ|o_dXL\SJ|umoEG175 A4!V;*p:.CA@J)=2E<GAEA<C=FAB?:7y@-}>-;-;.;.<-|>/x@/v=6v=6v;3u:2u9/s7,r4)q3&a3$vB5QI[U_Ug^OIVB3M47@/=K4<K44<-43.68-FW5kVw]cIV}>]DbK^JjcSjcSjcSjcSkdTkdTkdTleUi\KfZLaZR֗y:C(&=!0G-'&wGC}fx:JDMPNSIMAB:;:7<<';':'9):,;,=-}>-t=8s<5s:3r71r7/p4,o0'l-$W-tD8VOvTJQH94=,'4#!,,2$9F2>P8/:*01,34,AQ4tcpY\GTw?`NfSZwIicSicSicSjdTjdTjdTkeUkeUthZg^UrnkӣUZF6D3GQFrnVP=5;0B5C8A<BA;.;-;-<,};-};/~:191o;0m9.k7,k7,l7/k6.h3+e0(V,m>4rLCVH;6C1,C1:B7E;9,/$,9%2D,,9(57236/;K1|m`NPp?PpA`}Qa}TPjCicSicSicSjdTjdTkeUkeUkeUmcW`YQggefr\74+ުQD6,B8L@F;@5=7?6?5w>3t>4v;5|8778h9)f6(e5'f8+h9/g;0d8/`5,mA6mA6Z:/43!6=+270?),891*5$-?'1?.BD?4700>'viQpDEd8Kg>]yQ[uPF^<pbUlcTheTefVefVhfYlfZoe\_hMoui͸{|ltwlԿmq33>7P>H/GA<7t74n95sB=o?5l;,i6#a82a6/e82o>7m;4f4+i7.sA8yl\cQ28,(/'9?;062$+$07/.6+,4)-5*19,4<-7?0?H7HQ@;T7HaCLfCbzX^sT8L3nbTkdTheTefVfgWhfYlfZne\dmR}ҿƽۢM?.<,:4=7GCFEt=:k4-p:.yA4i40j73d5/]2)`<0iL<iP<]H3rzeRYG06*,1*4;4.5.'.'-4,,3+*1)*1)-5*/7,08+7?0>F75L2AX<FZ>ZoPUhL/A+kdTjdTgfTfgWfgWigZlfZmd[ZdKw}sȷxoDAI@z:1p3.u;7n95s>8r;4l6,o53k84d90W:,RA-UO5V[=U^?hkVEI804&05.271070180-7,-3/*0,)0)+2++2*)0(-5*4<10B*<N6=O5Q`IO^I-:)feSgfThgUhfWigXjfZlfZle[XdLfme㳳h[vJ=_5)g?5`8.rJ@pH>f>4iC8`>2_H8`T>MK27>BP-brN]_J=>,35(9<33816=5;E<3=2286/53.40/51,3,)0)*1)/6./>)8G24C.ER@HSC.8-bgSdgTfgUigXjgXjfZieYieZes\nxpпúǶp^JYG3UC/XG3YN:QK5TT:X_@JS4<C"IN.fiJ^\GCB0=>0AC87<59@8?I>7B49?=7=;6<87=93:3.5..5-2916F,;J30?,=J9BM?.8-^gR`hSehUjhYmgYlfZieYhdY_nYy~ǾmiNLH+MI,[Z<IO3LU8HU7AP/GU2Z_?a^?ZS6b]GRM:HF9EE;=@78@58C55A3=C?;A=<C<=D=:A94;33;07?4GZ<I[A8J4AO>ESD4@2 \ No newline at end of file
diff --git a/PerlMagick/t/reference/jpeg/read_sfw.miff b/PerlMagick/t/reference/jpeg/read_sfw.miff
new file mode 100644
index 0000000..329f156
--- /dev/null
+++ b/PerlMagick/t/reference/jpeg/read_sfw.miff
Binary files differ
diff --git a/PerlMagick/t/reference/jpeg/write_non_interlaced.miff b/PerlMagick/t/reference/jpeg/write_non_interlaced.miff
new file mode 100644
index 0000000..f6cd523
--- /dev/null
+++ b/PerlMagick/t/reference/jpeg/write_non_interlaced.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+Resolution=72x72 units=pixels-per-inch
+
+:2."3/$50,71192992:81882672/50*40%2."0.!1/"2/&5.(?*/A*2?.4@59>>>>D@;HA<H<?E7OF5mH8H;F>DAAAAAE=D9>1:-=-A0>,8&<+;):(;);&=(H0VDLHY55I),G-.@,->,*@.,=*$<#C'$@ %U5@tRjiviZMkSNdvqxtMJU2."3/$50,7117077086/660460050,40'2.%1.%2/&30)7/,;,/;+.;,/=15=79<<::?99A6CE8NE4dE3C6B9C=DAFDGAD9=38,:-A2B3>/B3=.:+<*=+@-H5VE{PIR95?,(?1.=31<41;4.4+$?0)B/+<&(G08XASua|}|nB=T<;K\[ivu}STY0.1/"30)40-4/33.42-41,24.23--2-*1,)1,)3--4.05/140-4/,7++;,/@03?35>64<71A?3H?0U>,i;+:,>2C<GAKFE@<65-6.>4A6@5;25,3*6+;0B4M?^NybRGH:15'/7,-9/-:0-9/%/$25*24)2/*40/43;^]mt{GMY18>2:=PXZFLL1:7-. .."//'0/+1-.0+1.)/-(.0)0/)-.(,.(*/)-0*.2+22-1-2,.1*4,):,,B,/E/2D22A30A8/C:+K:(Y8%p7&<-C7G?LGGB?97071=5?6>5:3808.;1>4F:VJl]kXdN:I6,>.!5)!5*'8.(5+&0%*0&25.350*/2\el~iyy]lgbqj{~^na,.!-/$./'./*.-+-+,+).,'--&--&..$--#,.$-/%.1'0-+.&2(%1#--%6+)C*-G-0H.1D1-B5-B8,H;*Q:(b9'v=,D6I;G<F<C7?2>2B6C6z@4wA5yC7|F:}G;G<QDgZowfUaK=J9%2(,%+1-352/.*2-)91.61-,,*bgjd|f.1(/2)03,12,01,//-.,--+..)/.'//%..$-/%.0&/2'//+,$0$#1 +.#5.&@.,D/.F..C.+<.%@2'E5&K4$U1!b4$w<,C2>.A2B4@2A3E7zE7rB4e:*g=-lB4rH:yM@]Pxiofv[L]J/<2!*%(*).*+6,-8*)3$!0"-%"\[Y̻¬a{`8R505116027158158156043/3124/33.43,31+/3*/4+.6,-4/+-3%+6%06(68+=90@70>3-?0)=,$B.#I.#K+O(Y+j7&x?,=,A.B2?.>.~@1yA0r?.rC3lA0kA1rH8TDeV|nznpjfeM_Q7B<...) #7$(=$'58 @-)bTQ~}wsMfH48;59:6;77<59<38;2891873:6595682460280.80-92*:3):8+8:,8?/:C2:E4;B2;<.=5*H4+P2(W/'Y)Z$b)q7)A0@/A0?/8)4'5'4'|2%bUWHL=N@UIaXof}o|pyvusRYY1<D%E"O")G N/,YF@i`W~uvtut}|vs{xkfCZ>69B:=B>@?>A:=@5>B4CE8FH=BA<BA=?;:?;8?:43/#1.D=+?3'=5*=A2>M:8P:/G/3@,A@.M5)e:3B?JFKGJBH?D8G8@3=3>55/,&0+=6SLKBH?NEWRZWUSMMRSVZ\g`r]{Y{TwSs<Vq#3RQ.*f\Rs~mkrktqsrlN]H44@77?;=<>A:@D5AE4DG6FH;<;6?>:<:;A=<KHAFD7;:&?8&WC:Q@8EC6<I73M4/I02A*?:'Q1$F?TPHH;9=8D>E;@4;.9/<4;697<9B=>8>8D<PHVRUTNOEK4?6G=UCcElGrKvPxcMb>GmA>~r}ʽrzkXaP1/<32:775=?4BE2FI4GJ7FH;HIDPPREDJ63:756:9478*<6(@($J2.I@7DH9<K6:I2>A,I8&^0#G@OL<;,+20<8707*5(2'4+93?=>;;660>4I?TKRLGD;<6:=D?HCUD^DeGjLrTvhdv^g]]ټǍt5/;1/421,89+@B,FJ1HK8HJ?]]_|z{xYWlA@P88B457:52@,-Q99UC?KA8@8+?3%E.P&|<2>796.,/,8562+$4&9(6)0'1,7240,%3(<0J=RFI?81/-00GIIOKYK_IcKiOnUtXqbuit_d<5<62131%54 ==#CF+IJ8JKEcanܧ͋onOQh=;IH=CL89L23T21e98x@?A=:4GA911)6/>7>7926.>-G3D5;/4-5.2,,#2$9(D5N?F97.50;9@A@FEOHZKbNiQmTnQh\mkxT]⧭G>??:496%75;:BB&HI9KKK][q½|}]^}MKVD8:N.3x@I^kiu^eNQC@;2;.C4A47+7.D9A/H4D6>3715/2,2(;/<,D5N?G=7151>;B>BADHKURbUgShQe[k\ipyR[u{PGBKE9FA-?> ==AA%FG9KJOWTs밬ፑ{mij{S\[lbzVoCW:F;=?6E3D0<(5%5'>1<-9+4+4/5301,-/,>7<0B7ODLE;71277F?E<FAON\_bi^g[bryhj䂃^_mCEXKBVJ<SF5MA+G=$F>'HE6IIIPRk맨ⷢalRc?W.E3HJX=?F>G6?*:(<+7)1%90.&&#/.4803,0./300+;4OGSOBB77:9907+;0IA^Ykkmmhh{ynk듏zsV=6]G:dLBgJFaB?]@:[E8SK8HJ=Q^dpϗ뚛똍٣ά}hyKPBKGQBK=D@FDHBA>6</<,9-7.7+6,41))039=,1 &&-059;)*42JHMIOLJF6282>21!?0PHnj]Zjg{vojrhrbcaL_N:bO@fHFaABa?>aF=YM7MO:>MFViwevĎɋr`;\KY;BAJIP@@6476;9:55-2%3%1*4/9091>@/4/416,306;@>A37+-//8695>8D@E?4.8.5#@0H>mhlfrots^[rimͭʵęհ׺SW6UT8XL>XF<ZF;_L=\R7US<HNDSWbUSzvevxnIb9G5=ALFO::2/96A=C<=37*4'2-53736205(0+22859>@?@64DAJFFB>9833.<9OK3-7-8-?2;1h_{zxx~X]_Zqar}[ldubzbiwũHW0JT2ML7RI8YL;^O<\R7XR<XULZU\VEgsTkxwXeDM;B<G:B0/2,?8E=MEI<B4;/403410+-,6,7>GRVRSGE84&!:3MFIB;34.'"($>:7/8/<7=61'\Tx|drUbOPyH7oyVmessm~~|ɨGX.IU/MP5UO9YL9[L9XL6VJ:NE@ZMW`Gd\~r||^_VYDL9B07-+5.<580F>H;E7<13114.0'+,7+7@JX\OP97,%&5)G<C98/82/,,+>96,6,;996-$RJuLcRgNRyF5is~v~jsquQY2RV5WS8\Q=\L<WG8VH=VKEdY_n_roXuj~ƈ҈kcUREG;?4641@9B<80;2B6F6>3538;:=6</:*65?@F:<85D=NENCSGKA@7@:@:>=D>2#2&22440,HCoPkLd>ByJ8krao_iZxf{f}kvwsc^R8_P9bQ?cPB_KB[HD_PSf\g{qšęreXPRKLJ@>94D;KDB<60B8I9>23/::DCDIFPJSIQ>C9<RQlhpkOGF?A;:44.:3:80)3!3$,,/365<@{d{OlF[++kE0d|auepbp_p[{gsyhl[bL>aK=dL@eNFaLK_NTi^ovputxz}~ʨqbnaf_LG6-<4HCFA60C8G8:,+$3/A=EETZ`g[a:?/4OQbbRO=:3185:53,<6>9,!8$9&-).28=0;jYsOjO]h,$W?%|wO|YjWRCq^kUoYgRKl7?_-^FBbKEdPI_LH]NSpeu}xuvZ`r{밳Ž`McL}opgYOF<)'86<7D9K:E4905-7/92;<Z]PT:?BI?E/55:1559685472<5;26):$<(0)045?5GlIe[n?CjK9F=bY2XP9_OgOiQaGWy=Vu<[yCG78PBAZMG`VTidjpnkndjlt|֐哣ᕣҜ̊mmul[IR8jZwkynd\33('0*7-A/@-7+7+=0?561MMBD-07=6>+31;,607363472:3:17&9"?);1:;/:EYWuNiS\_4-IA*15eY3jl;N|4YFiOlOeH^}A^{AcF224=?>AD;NUMdno_k{Q]Wbv΀ۇ{}edtcXFnK-\Jyl|mf65#".)5)>+B,=.=.A2D781HD:9'(/50:&1)6*7/8262374<3;/7&9!B-@2<8.9VlGbQep87!0;^hEWgN[FkOnMiHdDdDiK+042;:*6*4E5Rf]QcmR`q{Հԇϋƈ|xkbsk[KzS6ZImbmdOI/.-)3+8*A,G0B2=0=0>18/E><90/7=:A0;/:+5/71544:6?7>39):$E/8'82@IXjH[EMY=1$-GX8Ǥ~RhQfThLkJhGgFiHlK+.5064%0,;$I\IQa`dpʛڇĈupd|gV`x[MT?OEXROH5/-(5/5)7#@'G/C39/5+4+2*<5?:=:DFHKAG;C05275777>:C<?7:,9&D01 =5_dQZQVj-()# BU5láxT[1Z}EfTdJfEfEjInNqQ?5@A;;8;(:C&HU9MWL_eu}pxjvp{n_deV]hPPVIM><6CAE?5/6/4*8*7!>#G.D6<4627293?7C>A>?>AA>@7:667786:7@;D<=57-5&<+2#ODnoJK[SM.GP1rd{tTX5?N%^PbSeKeEfHoPtVvX`DS`GK]N;ZT4XU4TS>\W]iay{ml[}hVfgWW`RE`UCfZJpVGVJOE439:@<;3@73&B0;!<D*B5;678;:B=A8@:94/*2-8361>:=9=8<7@;@;71/'3(-7([N\WOHjWfbE|kqlOF?#))BcXj]kUiLjMrUtYqTrR]mPRp[JrcFi`Ag_Hja\f[ccUfeUbeUUWI>K@*ZP7h`KsVFYQWT;<9::68/D97'G3:6;!:.31359=?;;4822+' 0)B:G?D<C;@8?7A9@85/,%7,$;-_RC8ZMv^zXiG, 9372;I&+FcYseu]pSmRrWqVhLo\Xn]Vn^Qm`OlaMkcPkbSjbW`UOof]f\RZREMF6H@3SK@[:3/0V\]a9:/)>6B5;)J4< 12;.@<<A;B65954/2-2.52:5<8JFJEICC;:/1&."0%2(4)</OA_QaQlWBQM4#) =H*BH,=F''61E k[wdmRvY{^qVbGZ?k^Uk^Ul`Tl`RjaRkbQkcPkcNwp]rkYf`PlfX[UI=6,A:4V95z.0:=^`a`=94-A7>/=*=)@*C3G=HB?A;=85:4603.2,3.5171>9@8A7=07)3#1!3#y)~5,H<XKaQeS{iUtnX[]EV_D@M1:I*,=4E#j{Y}jtZtWuZlQcG^Di_Uj`Vj`TjaRkbSkbQjcPjcPe^Lg`Ne_Ouoanh\PI?GB<J91xPDPFf_olUSA>FAKCOHQILGGEIEID@55);.</9,6*3)3)3*4)5*7)9*9(6%6!~6 }6$w1%?6NCVH|UFpUDhYFc^JkoXR\C3@&3B%/?"4E%crSo{aqTjNdJbI_Fj`Vj`Vj`TkaUkbSjcQkdRkdQg`NwqakeWb\Pf_UhdY_ZT<2(dO<~YFTERH\VTQDBBC@E=C5;24>;LCI8>*<+~?.>,<+:+9*8+7)5'7(~9){:(w:%t:$r:#r9&q6({A6QF]PeV~gWobQ_\IPS@@J2/;#.<"/?$2B%UdGzh}fiO]D]F_I]Gj`Tj`TjbUjbUjcSkdRkdRjeRlfVwqa`ZLYUIzvk~sRA-E/G3Y:%o;-HAHL2>4E7I:F<BD@L@J:F3;(z?-z?-}@.~?.=-=/=/};-{<-w<,t<+p=*k<(g:%f9&c2$tB7VKaU}aUm[MWP@ED2:>-@I6>J61?(,:#/=$HT<sd{gcLV|?[FaN\KkaUjbUjbUjbUkdTjdTjdTkeUd^N`]N_[O؛yH<"95E>$6 yG>~gt;N?RHWMRJFF:D3I59'{>,{>,|=.}>/=1=1}=1z<1w;0s;.n:,k<,e:)a7'\5&W-!nF<}[QrVJXE7B6(2/ '),3#:E4AN<.;')6",:#CO9}nta[HTwA^McSY{IjbUicUicUjdVjdVjdVkeWifWnk\d`Tsoc٠]W?F>+XK;nwP[9B8?A?C;D5L:9,<0;/908/818191z5.u5,p4,n5,l7/h8.d5+^3*R-$aC8jODZF;H:/A9.??3=A3)1",9(5B1,9(0;+.9(?H7xeUPr@Oo>^~O_~ROnDicUicUicUjdVjdVifWifWieYieY][Njh\tlY<3$ᥧTX=@IHMGD7?0<2?6<38271617184v1,q0,m0+m3/l71j92f71^6.cE;^H=P>2<.#2*53'57,-3'2<1)5'0<02>0=H:/:*3;,~uWoKHe9Kg>\xO[wQGc=ifUheTheVheVhdXieYjfZjh\geYtthʶ{lvlɳrl<6F>RHH=E<<5~5.60>8:4z50o.*r3.m2.m61p=9l;6a4.c82iD<wlgYNB6*80%;9-13((.$08-.8/*6**6,.:.1;06>1?E9EQ=<Q0E_8Ic>^xSZsS6O/heTheTheVheVieYhfYig[hh\jj^{ú֠MC.&A8;2A8I@I?z>6p5-r92u@8g5.h91b70[3+`;3lJAlKB`E:sfYQD<6*64(46+/2)*1)+5,+7-(4*'3)+5,.6+08-8>2=H79L0BZ8G\=\qRXlP3G,gfTgfTgeVhfWhfYgg[gg]gg]``V{|tunKCK@l@3f:-lB4g?3jD7fB4]=.\?1[A2V?/P=,RA1\L<dTDcWGpiYGD564'88,03(/5+4;3,6-*5-'2*'1((2)*2')1&/5)5>-1A';P1=P4QcIN`H,>&feSgfThfWfgYgg[gg]gg]fg__`XkldûⳫj^lO?W:*_D3W=,gP>cQ=YH4XK8PE1SM7[V@MK4=;$LL4mlWa`N9:*56(=?225*6<2@G?2<30:2,7/+5,,6-,4))1&,2&19*-;$4F,4D*ET=GVA+:%deSefTfgWghZgg[fh]ef^ef`lmgsvoǾǽɿƷk^KSH4NF1TN8RP7MM3RU:Y]BLR6<B&HN2djP]^L=>.=>0DF969.:@6DKC4>58B:5?74>54>52:/.6+/5)3;,7E.<L24B+@M9DQ?.;)cdRdeSfgWhi[gi\fh]ef`de_eha~zϻƸŻldOID.NI3__GLO4PV:NT8EN1IT4U`@VaAMV9_bOIJ:DF8EI:;>3:@4>E=5<4=G?:D<:D;;E<9A63;04:.6>/IU?JX?:G3AN:DQ@2?. \ No newline at end of file
diff --git a/PerlMagick/t/reference/jpeg/write_plane_interlaced.miff b/PerlMagick/t/reference/jpeg/write_plane_interlaced.miff
new file mode 100644
index 0000000..f6cd523
--- /dev/null
+++ b/PerlMagick/t/reference/jpeg/write_plane_interlaced.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+Resolution=72x72 units=pixels-per-inch
+
+:2."3/$50,71192992:81882672/50*40%2."0.!1/"2/&5.(?*/A*2?.4@59>>>>D@;HA<H<?E7OF5mH8H;F>DAAAAAE=D9>1:-=-A0>,8&<+;):(;);&=(H0VDLHY55I),G-.@,->,*@.,=*$<#C'$@ %U5@tRjiviZMkSNdvqxtMJU2."3/$50,7117077086/660460050,40'2.%1.%2/&30)7/,;,/;+.;,/=15=79<<::?99A6CE8NE4dE3C6B9C=DAFDGAD9=38,:-A2B3>/B3=.:+<*=+@-H5VE{PIR95?,(?1.=31<41;4.4+$?0)B/+<&(G08XASua|}|nB=T<;K\[ivu}STY0.1/"30)40-4/33.42-41,24.23--2-*1,)1,)3--4.05/140-4/,7++;,/@03?35>64<71A?3H?0U>,i;+:,>2C<GAKFE@<65-6.>4A6@5;25,3*6+;0B4M?^NybRGH:15'/7,-9/-:0-9/%/$25*24)2/*40/43;^]mt{GMY18>2:=PXZFLL1:7-. .."//'0/+1-.0+1.)/-(.0)0/)-.(,.(*/)-0*.2+22-1-2,.1*4,):,,B,/E/2D22A30A8/C:+K:(Y8%p7&<-C7G?LGGB?97071=5?6>5:3808.;1>4F:VJl]kXdN:I6,>.!5)!5*'8.(5+&0%*0&25.350*/2\el~iyy]lgbqj{~^na,.!-/$./'./*.-+-+,+).,'--&--&..$--#,.$-/%.1'0-+.&2(%1#--%6+)C*-G-0H.1D1-B5-B8,H;*Q:(b9'v=,D6I;G<F<C7?2>2B6C6z@4wA5yC7|F:}G;G<QDgZowfUaK=J9%2(,%+1-352/.*2-)91.61-,,*bgjd|f.1(/2)03,12,01,//-.,--+..)/.'//%..$-/%.0&/2'//+,$0$#1 +.#5.&@.,D/.F..C.+<.%@2'E5&K4$U1!b4$w<,C2>.A2B4@2A3E7zE7rB4e:*g=-lB4rH:yM@]Pxiofv[L]J/<2!*%(*).*+6,-8*)3$!0"-%"\[Y̻¬a{`8R505116027158158156043/3124/33.43,31+/3*/4+.6,-4/+-3%+6%06(68+=90@70>3-?0)=,$B.#I.#K+O(Y+j7&x?,=,A.B2?.>.~@1yA0r?.rC3lA0kA1rH8TDeV|nznpjfeM_Q7B<...) #7$(=$'58 @-)bTQ~}wsMfH48;59:6;77<59<38;2891873:6595682460280.80-92*:3):8+8:,8?/:C2:E4;B2;<.=5*H4+P2(W/'Y)Z$b)q7)A0@/A0?/8)4'5'4'|2%bUWHL=N@UIaXof}o|pyvusRYY1<D%E"O")G N/,YF@i`W~uvtut}|vs{xkfCZ>69B:=B>@?>A:=@5>B4CE8FH=BA<BA=?;:?;8?:43/#1.D=+?3'=5*=A2>M:8P:/G/3@,A@.M5)e:3B?JFKGJBH?D8G8@3=3>55/,&0+=6SLKBH?NEWRZWUSMMRSVZ\g`r]{Y{TwSs<Vq#3RQ.*f\Rs~mkrktqsrlN]H44@77?;=<>A:@D5AE4DG6FH;<;6?>:<:;A=<KHAFD7;:&?8&WC:Q@8EC6<I73M4/I02A*?:'Q1$F?TPHH;9=8D>E;@4;.9/<4;697<9B=>8>8D<PHVRUTNOEK4?6G=UCcElGrKvPxcMb>GmA>~r}ʽrzkXaP1/<32:775=?4BE2FI4GJ7FH;HIDPPREDJ63:756:9478*<6(@($J2.I@7DH9<K6:I2>A,I8&^0#G@OL<;,+20<8707*5(2'4+93?=>;;660>4I?TKRLGD;<6:=D?HCUD^DeGjLrTvhdv^g]]ټǍt5/;1/421,89+@B,FJ1HK8HJ?]]_|z{xYWlA@P88B457:52@,-Q99UC?KA8@8+?3%E.P&|<2>796.,/,8562+$4&9(6)0'1,7240,%3(<0J=RFI?81/-00GIIOKYK_IcKiOnUtXqbuit_d<5<62131%54 ==#CF+IJ8JKEcanܧ͋onOQh=;IH=CL89L23T21e98x@?A=:4GA911)6/>7>7926.>-G3D5;/4-5.2,,#2$9(D5N?F97.50;9@A@FEOHZKbNiQmTnQh\mkxT]⧭G>??:496%75;:BB&HI9KKK][q½|}]^}MKVD8:N.3x@I^kiu^eNQC@;2;.C4A47+7.D9A/H4D6>3715/2,2(;/<,D5N?G=7151>;B>BADHKURbUgShQe[k\ipyR[u{PGBKE9FA-?> ==AA%FG9KJOWTs밬ፑ{mij{S\[lbzVoCW:F;=?6E3D0<(5%5'>1<-9+4+4/5301,-/,>7<0B7ODLE;71277F?E<FAON\_bi^g[bryhj䂃^_mCEXKBVJ<SF5MA+G=$F>'HE6IIIPRk맨ⷢalRc?W.E3HJX=?F>G6?*:(<+7)1%90.&&#/.4803,0./300+;4OGSOBB77:9907+;0IA^Ykkmmhh{ynk듏zsV=6]G:dLBgJFaB?]@:[E8SK8HJ=Q^dpϗ뚛똍٣ά}hyKPBKGQBK=D@FDHBA>6</<,9-7.7+6,41))039=,1 &&-059;)*42JHMIOLJF6282>21!?0PHnj]Zjg{vojrhrbcaL_N:bO@fHFaABa?>aF=YM7MO:>MFViwevĎɋr`;\KY;BAJIP@@6476;9:55-2%3%1*4/9091>@/4/416,306;@>A37+-//8695>8D@E?4.8.5#@0H>mhlfrots^[rimͭʵęհ׺SW6UT8XL>XF<ZF;_L=\R7US<HNDSWbUSzvevxnIb9G5=ALFO::2/96A=C<=37*4'2-53736205(0+22859>@?@64DAJFFB>9833.<9OK3-7-8-?2;1h_{zxx~X]_Zqar}[ldubzbiwũHW0JT2ML7RI8YL;^O<\R7XR<XULZU\VEgsTkxwXeDM;B<G:B0/2,?8E=MEI<B4;/403410+-,6,7>GRVRSGE84&!:3MFIB;34.'"($>:7/8/<7=61'\Tx|drUbOPyH7oyVmessm~~|ɨGX.IU/MP5UO9YL9[L9XL6VJ:NE@ZMW`Gd\~r||^_VYDL9B07-+5.<580F>H;E7<13114.0'+,7+7@JX\OP97,%&5)G<C98/82/,,+>96,6,;996-$RJuLcRgNRyF5is~v~jsquQY2RV5WS8\Q=\L<WG8VH=VKEdY_n_roXuj~ƈ҈kcUREG;?4641@9B<80;2B6F6>3538;:=6</:*65?@F:<85D=NENCSGKA@7@:@:>=D>2#2&22440,HCoPkLd>ByJ8krao_iZxf{f}kvwsc^R8_P9bQ?cPB_KB[HD_PSf\g{qšęreXPRKLJ@>94D;KDB<60B8I9>23/::DCDIFPJSIQ>C9<RQlhpkOGF?A;:44.:3:80)3!3$,,/365<@{d{OlF[++kE0d|auepbp_p[{gsyhl[bL>aK=dL@eNFaLK_NTi^ovputxz}~ʨqbnaf_LG6-<4HCFA60C8G8:,+$3/A=EETZ`g[a:?/4OQbbRO=:3185:53,<6>9,!8$9&-).28=0;jYsOjO]h,$W?%|wO|YjWRCq^kUoYgRKl7?_-^FBbKEdPI_LH]NSpeu}xuvZ`r{밳Ž`McL}opgYOF<)'86<7D9K:E4905-7/92;<Z]PT:?BI?E/55:1559685472<5;26):$<(0)045?5GlIe[n?CjK9F=bY2XP9_OgOiQaGWy=Vu<[yCG78PBAZMG`VTidjpnkndjlt|֐哣ᕣҜ̊mmul[IR8jZwkynd\33('0*7-A/@-7+7+=0?561MMBD-07=6>+31;,607363472:3:17&9"?);1:;/:EYWuNiS\_4-IA*15eY3jl;N|4YFiOlOeH^}A^{AcF224=?>AD;NUMdno_k{Q]Wbv΀ۇ{}edtcXFnK-\Jyl|mf65#".)5)>+B,=.=.A2D781HD:9'(/50:&1)6*7/8262374<3;/7&9!B-@2<8.9VlGbQep87!0;^hEWgN[FkOnMiHdDdDiK+042;:*6*4E5Rf]QcmR`q{Հԇϋƈ|xkbsk[KzS6ZImbmdOI/.-)3+8*A,G0B2=0=0>18/E><90/7=:A0;/:+5/71544:6?7>39):$E/8'82@IXjH[EMY=1$-GX8Ǥ~RhQfThLkJhGgFiHlK+.5064%0,;$I\IQa`dpʛڇĈupd|gV`x[MT?OEXROH5/-(5/5)7#@'G/C39/5+4+2*<5?:=:DFHKAG;C05275777>:C<?7:,9&D01 =5_dQZQVj-()# BU5láxT[1Z}EfTdJfEfEjInNqQ?5@A;;8;(:C&HU9MWL_eu}pxjvp{n_deV]hPPVIM><6CAE?5/6/4*8*7!>#G.D6<4627293?7C>A>?>AA>@7:667786:7@;D<=57-5&<+2#ODnoJK[SM.GP1rd{tTX5?N%^PbSeKeEfHoPtVvX`DS`GK]N;ZT4XU4TS>\W]iay{ml[}hVfgWW`RE`UCfZJpVGVJOE439:@<;3@73&B0;!<D*B5;678;:B=A8@:94/*2-8361>:=9=8<7@;@;71/'3(-7([N\WOHjWfbE|kqlOF?#))BcXj]kUiLjMrUtYqTrR]mPRp[JrcFi`Ag_Hja\f[ccUfeUbeUUWI>K@*ZP7h`KsVFYQWT;<9::68/D97'G3:6;!:.31359=?;;4822+' 0)B:G?D<C;@8?7A9@85/,%7,$;-_RC8ZMv^zXiG, 9372;I&+FcYseu]pSmRrWqVhLo\Xn]Vn^Qm`OlaMkcPkbSjbW`UOof]f\RZREMF6H@3SK@[:3/0V\]a9:/)>6B5;)J4< 12;.@<<A;B65954/2-2.52:5<8JFJEICC;:/1&."0%2(4)</OA_QaQlWBQM4#) =H*BH,=F''61E k[wdmRvY{^qVbGZ?k^Uk^Ul`Tl`RjaRkbQkcPkcNwp]rkYf`PlfX[UI=6,A:4V95z.0:=^`a`=94-A7>/=*=)@*C3G=HB?A;=85:4603.2,3.5171>9@8A7=07)3#1!3#y)~5,H<XKaQeS{iUtnX[]EV_D@M1:I*,=4E#j{Y}jtZtWuZlQcG^Di_Uj`Vj`TjaRkbSkbQjcPjcPe^Lg`Ne_Ouoanh\PI?GB<J91xPDPFf_olUSA>FAKCOHQILGGEIEID@55);.</9,6*3)3)3*4)5*7)9*9(6%6!~6 }6$w1%?6NCVH|UFpUDhYFc^JkoXR\C3@&3B%/?"4E%crSo{aqTjNdJbI_Fj`Vj`Vj`TkaUkbSjcQkdRkdQg`NwqakeWb\Pf_UhdY_ZT<2(dO<~YFTERH\VTQDBBC@E=C5;24>;LCI8>*<+~?.>,<+:+9*8+7)5'7(~9){:(w:%t:$r:#r9&q6({A6QF]PeV~gWobQ_\IPS@@J2/;#.<"/?$2B%UdGzh}fiO]D]F_I]Gj`Tj`TjbUjbUjcSkdRkdRjeRlfVwqa`ZLYUIzvk~sRA-E/G3Y:%o;-HAHL2>4E7I:F<BD@L@J:F3;(z?-z?-}@.~?.=-=/=/};-{<-w<,t<+p=*k<(g:%f9&c2$tB7VKaU}aUm[MWP@ED2:>-@I6>J61?(,:#/=$HT<sd{gcLV|?[FaN\KkaUjbUjbUjbUkdTjdTjdTkeUd^N`]N_[O؛yH<"95E>$6 yG>~gt;N?RHWMRJFF:D3I59'{>,{>,|=.}>/=1=1}=1z<1w;0s;.n:,k<,e:)a7'\5&W-!nF<}[QrVJXE7B6(2/ '),3#:E4AN<.;')6",:#CO9}nta[HTwA^McSY{IjbUicUicUjdVjdVjdVkeWifWnk\d`Tsoc٠]W?F>+XK;nwP[9B8?A?C;D5L:9,<0;/908/818191z5.u5,p4,n5,l7/h8.d5+^3*R-$aC8jODZF;H:/A9.??3=A3)1",9(5B1,9(0;+.9(?H7xeUPr@Oo>^~O_~ROnDicUicUicUjdVjdVifWifWieYieY][Njh\tlY<3$ᥧTX=@IHMGD7?0<2?6<38271617184v1,q0,m0+m3/l71j92f71^6.cE;^H=P>2<.#2*53'57,-3'2<1)5'0<02>0=H:/:*3;,~uWoKHe9Kg>\xO[wQGc=ifUheTheVheVhdXieYjfZjh\geYtthʶ{lvlɳrl<6F>RHH=E<<5~5.60>8:4z50o.*r3.m2.m61p=9l;6a4.c82iD<wlgYNB6*80%;9-13((.$08-.8/*6**6,.:.1;06>1?E9EQ=<Q0E_8Ic>^xSZsS6O/heTheTheVheVieYhfYig[hh\jj^{ú֠MC.&A8;2A8I@I?z>6p5-r92u@8g5.h91b70[3+`;3lJAlKB`E:sfYQD<6*64(46+/2)*1)+5,+7-(4*'3)+5,.6+08-8>2=H79L0BZ8G\=\qRXlP3G,gfTgfTgeVhfWhfYgg[gg]gg]``V{|tunKCK@l@3f:-lB4g?3jD7fB4]=.\?1[A2V?/P=,RA1\L<dTDcWGpiYGD564'88,03(/5+4;3,6-*5-'2*'1((2)*2')1&/5)5>-1A';P1=P4QcIN`H,>&feSgfThfWfgYgg[gg]gg]fg__`XkldûⳫj^lO?W:*_D3W=,gP>cQ=YH4XK8PE1SM7[V@MK4=;$LL4mlWa`N9:*56(=?225*6<2@G?2<30:2,7/+5,,6-,4))1&,2&19*-;$4F,4D*ET=GVA+:%deSefTfgWghZgg[fh]ef^ef`lmgsvoǾǽɿƷk^KSH4NF1TN8RP7MM3RU:Y]BLR6<B&HN2djP]^L=>.=>0DF969.:@6DKC4>58B:5?74>54>52:/.6+/5)3;,7E.<L24B+@M9DQ?.;)cdRdeSfgWhi[gi\fh]ef`de_eha~zϻƸŻldOID.NI3__GLO4PV:NT8EN1IT4U`@VaAMV9_bOIJ:DF8EI:;>3:@4>E=5<4=G?:D<:D;;E<9A63;04:.6>/IU?JX?:G3AN:DQ@2?. \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/gradient.miff b/PerlMagick/t/reference/read/gradient.miff
new file mode 100644
index 0000000..dc1a215
--- /dev/null
+++ b/PerlMagick/t/reference/read/gradient.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/granite.miff b/PerlMagick/t/reference/read/granite.miff
new file mode 100644
index 0000000..8b88f71
--- /dev/null
+++ b/PerlMagick/t/reference/read/granite.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input1_4_wpg.miff b/PerlMagick/t/reference/read/input1_4_wpg.miff
new file mode 100644
index 0000000..256d548
--- /dev/null
+++ b/PerlMagick/t/reference/read/input1_4_wpg.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input1_8_1_wpg.miff b/PerlMagick/t/reference/read/input1_8_1_wpg.miff
new file mode 100644
index 0000000..5060307
--- /dev/null
+++ b/PerlMagick/t/reference/read/input1_8_1_wpg.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input2_8_wpg.miff b/PerlMagick/t/reference/read/input2_8_wpg.miff
new file mode 100644
index 0000000..dda37e5
--- /dev/null
+++ b/PerlMagick/t/reference/read/input2_8_wpg.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input2_TC1_wpg.miff b/PerlMagick/t/reference/read/input2_TC1_wpg.miff
new file mode 100644
index 0000000..06dbcad
--- /dev/null
+++ b/PerlMagick/t/reference/read/input2_TC1_wpg.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_avs.miff b/PerlMagick/t/reference/read/input_avs.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_avs.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_bmp.miff b/PerlMagick/t/reference/read/input_bmp.miff
new file mode 100644
index 0000000..3ad94fa
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_bmp.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_bmp24.miff b/PerlMagick/t/reference/read/input_bmp24.miff
new file mode 100644
index 0000000..7d19e4f
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_bmp24.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+Resolution=29.25x29.25 units=pixels-per-centimeter
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_cmyk.miff b/PerlMagick/t/reference/read/input_cmyk.miff
new file mode 100644
index 0000000..8b3a942
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_cmyk.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_dcx.miff b/PerlMagick/t/reference/read/input_dcx.miff
new file mode 100644
index 0000000..9354d5d
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_dcx.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+Resolution=70x46 units=pixels-per-inch
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_dib.miff b/PerlMagick/t/reference/read/input_dib.miff
new file mode 100644
index 0000000..7d19e4f
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_dib.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+Resolution=29.25x29.25 units=pixels-per-centimeter
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_gif.miff b/PerlMagick/t/reference/read/input_gif.miff
new file mode 100644
index 0000000..ea84fd1
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gif.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gif87.miff b/PerlMagick/t/reference/read/input_gif87.miff
new file mode 100644
index 0000000..ea84fd1
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gif87.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray.miff b/PerlMagick/t/reference/read/input_gray.miff
new file mode 100644
index 0000000..d4308cb
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_08bit_fits.miff b/PerlMagick/t/reference/read/input_gray_08bit_fits.miff
new file mode 100644
index 0000000..718bece
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_08bit_fits.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_16bit_fits.miff b/PerlMagick/t/reference/read/input_gray_16bit_fits.miff
new file mode 100644
index 0000000..01b6f7e
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_16bit_fits.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_32bit_fits.miff b/PerlMagick/t/reference/read/input_gray_32bit_fits.miff
new file mode 100644
index 0000000..01ed0cc
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_32bit_fits.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_cin.miff b/PerlMagick/t/reference/read/input_gray_cin.miff
new file mode 100644
index 0000000..afecdae
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_cin.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=16
+colorspace=cineonlog
+
+:......//////222222333333333333333333111111222222111111111111000000......------............------------000000333333555555999999??????BBBBBBAAAAAACCCCCCDDDDDDOOOOOOZZZZZZaaaaaaiiiiiirrrrrruuuuuuttttttqqqqqqkkkkkk``````^^^^^^]]]]]][[[[[[WWWWWWUUUUUUSSSSSSSSSSSSSSSSSSVVVVVVWWWWWW``````eeeeee[[[[[[??????555555222222222222111111000000............------......>>>>>>YYYYYYttttttssssssMMMMMMOOOOOOuuuuuuxxxxxxUUUUUU------......000000111111222222111111000000222222222222222222000000......------000000//////////////////000000222222444444888888======????????????@@@@@@DDDDDDMMMMMMSSSSSSYYYYYYggggggppppppttttttuuuuuussssssjjjjjj^^^^^^]]]]]]]]]]]]ZZZZZZVVVVVVTTTTTTSSSSSSSSSSSSQQQQQQTTTTTTVVVVVVbbbbbbiiiiii\\\\\\999999555555444444222222222222000000////////////000000,,,,,,777777OOOOOOjjjjjjooooooEEEEEEEEEEEE]]]]]]llllllVVVVVV++++++,,,,,,............,,,,,,------,,,,,,------,,,,,,------------,,,,,,,,,,,,............//////000000000000111111444444333333666666777777999999======BBBBBBFFFFFFHHHHHHLLLLLL]]]]]]iiiiiippppppssssssqqqqqqbbbbbb[[[[[[[[[[[[ZZZZZZWWWWWWSSSSSSSSSSSSRRRRRRQQQQQQPPPPPPRRRRRRYYYYYYeeeeeejjjjjjdddddd<<<<<<555555333333222222222222000000000000000000111111//////......444444UUUUUUwwwwwwFFFFFF888888666666BBBBBBNNNNNNWWWWWW,,,,,,,,,,,,,,,,,,,,,,,,************************++++++++++++++++++++++++------,,,,,,------,,,,,,............------000000333333555555555555777777;;;;;;??????@@@@@@AAAAAAHHHHHHSSSSSS[[[[[[ffffffqqqqqqrrrrrr]]]]]]XXXXXXXXXXXXWWWWWWTTTTTTQQQQQQPPPPPPOOOOOOOOOOOOOOOOOOTTTTTT^^^^^^ffffff||||||^^^^^^@@@@@@444444////////////............//////000000000000------,,,,,,ccccccrrrrrr\\\\\\jjjjjj``````------------------------************))))))''''''))))))************((((((((((((++++++,,,,,,,,,,,,,,,,,,******++++++------222222555555444444333333555555999999;;;;;;;;;;;;DDDDDDQQQQQQVVVVVVXXXXXXaaaaaaggggggYYYYYYTTTTTTTTTTTTSSSSSSRRRRRROOOOOOMMMMMMLLLLLLLLLLLLPPPPPPXXXXXX[[[[[[nnnnnnyyyyyyTTTTTT<<<<<<//////))))))------------,,,,,,------......,,,,,,******iiiiii\\\\\\............//////000000000000//////------************))))))((((((((((((((((((******,,,,,,------++++++++++++------000000444444555555333333222222222222555555666666333333555555EEEEEERRRRRRTTTTTTRRRRRRYYYYYYUUUUUUSSSSSSQQQQQQRRRRRRQQQQQQMMMMMMKKKKKKIIIIIILLLLLLWWWWWW[[[[[[ddddddmmmmmmUUUUUU999999))))))))))))))))))******++++++,,,,,,,,,,,,&&&&&&]]]]]]TTTTTT111111222222222222555555555555333333111111......000000------******++++++++++++......////////////////////////222222777777999999999999666666222222333333666666555555222222000000888888EEEEEENNNNNNNNNNNNPPPPPPSSSSSSTTTTTTPPPPPPNNNNNNNNNNNNKKKKKKHHHHHHHHHHHHOOOOOOXXXXXX]]]]]]kkkkkk~~~~~~wwwwww\\\\\\888888&&&&&&&&&&&&))))))******))))))''''''$$$$$$WWWWWW}}}}}}PPPPPP666666666666777777999999<<<<<<;;;;;;::::::777777777777555555222222111111111111222222222222333333666666888888::::::>>>>>>??????>>>>>>999999777777777777888888888888777777666666777777AAAAAARRRRRRXXXXXXTTTTTTQQQQQQQQQQQQLLLLLLKKKKKKKKKKKKGGGGGGnnnnnnqqqqqqRRRRRRWWWWWWbbbbbbvvvvvv||||||______999999******'''''',,,,,,,,,,,,000000LLLLLLiiiiiiuuuuuu~~~~~~xxxxxxQQQQQQ777777888888<<<<<<>>>>>>??????AAAAAA@@@@@@@@@@@@@@@@@@======<<<<<<;;;;;;;;;;;;777777555555444444777777;;;;;;>>>>>>BBBBBBBBBBBB??????;;;;;;::::::::::::::::::YYYYYY______UUUUUUffffff______[[[[[[^^^^^^]]]]]]]]]]]]^^^^^^]]]]]]PPPPPPKKKKKKccccccsssssstttttt\\\\\\bbbbbbsssssskkkkkkllllllxxxxxx~~~~~~}}}}}}ssssss^^^^^^777777444444??????[[[[[[zzzzzzyyyyyyzzzzzzqqqqqqWWWWWW555555666666;;;;;;??????AAAAAACCCCCCCCCCCCDDDDDDCCCCCC>>>>>>============<<<<<<::::::777777666666888888<<<<<<@@@@@@BBBBBB@@@@@@>>>>>>;;;;;;;;;;;;999999SSSSSS||||||______TTTTTTddddddZZZZZZ______ddddddWWWWWW``````hhhhhhnnnnnnllllllmmmmmmllllll______ggggggnnnnnnjjjjjjssssssppppppzzzzzzmmmmmmmmmmmmqqqqqqttttttyyyyyyyyyyyy~~~~~~{{{{{{EEEEEEAAAAAAuuuuuuͯqqqqqq^^^^^^222222444444666666;;;;;;AAAAAAEEEEEEFFFFFFGGGGGGCCCCCCHHHHHH@@@@@@;;;;;;::::::888888888888777777999999<<<<<<AAAAAAAAAAAA??????<<<<<<999999888888======ccccccWWWWWWRRRRRR[[[[[[XXXXXXSSSSSS[[[[[[^^^^^^______ccccccaaaaaaffffffgggggghhhhhhffffffbbbbbbaaaaaatttttt}}}}}}yyyyyynnnnnn[[[[[[iiiiiisssssswwwwwwzzzzzzxxxxxx{{{{{{{{{{{{ssssssΈzzzzzz//////------222222777777======CCCCCCIIIIIIHHHHHHVVVVVV||||||XXXXXXBBBBBB555555111111111111777777<<<<<<@@@@@@BBBBBB;;;;;;444444111111555555OOOOOO[[[[[[XXXXXXVVVVVV^^^^^^dddddd^^^^^^YYYYYY[[[[[[dddddd\\\\\\bbbbbbggggggiiiiiiggggggaaaaaabbbbbbeeeeeehhhhhhoooooonnnnnnddddddYYYYYY\\\\\\nnnnnnyyyyyyyyyyyy}}}}}}||||||zzzzzziiiiii꽽777777222222//////333333999999AAAAAAJJJJJJIIIIIIbbbbbbooooooJJJJJJ@@@@@@999999;;;;;;??????<<<<<<BBBBBBPPPPPPNNNNNNLLLLLLZZZZZZZZZZZZ^^^^^^[[[[[[\\\\\\eeeeeeffffffccccccffffffggggggmmmmmmffffffgggggghhhhhhggggggbbbbbbaaaaaaaaaaaannnnnn||||||``````ZZZZZZ]]]]]]ffffffppppppqqqqqqwwwwww}}}}}}tttttt??????<<<<<<666666111111555555>>>>>>HHHHHHHHHHHHXXXXXXeeeeeeQQQQQQ999999888888LLLLLL||||||{{{{{{pppppp\\\\\\WWWWWW[[[[[[``````ggggggjjjjjjffffffnnnnnnmmmmmmggggggqqqqqqssssssgggggghhhhhheeeeee^^^^^^ccccccddddddddddddxxxxxxllllll\\\\\\^^^^^^ddddddvvvvvviiiiiixxxxxx}}}}}}ssssssHHHHHHFFFFFF@@@@@@999999666666======DDDDDDEEEEEEOOOOOO||||||ffffff______tttttt}}}}}}ttttttggggggooooooggggggaaaaaaeeeeeehhhhhhffffffccccccffffffggggggbbbbbb______aaaaaajjjjjjrrrrrrkkkkkkccccccffffffkkkkkkhhhhhhiiiiiizzzzzzqqqqqqgggggg____________eeeeee``````kkkkkksssssszzzzzzOOOOOONNNNNNMMMMMMHHHHHHBBBBBB======@@@@@@EEEEEEGGGGGGOOOOOOppppppqqqqqqllllllffffffmmmmmmqqqqqqjjjjjjhhhhhhiiiiii[[[[[[]]]]]]eeeeeeiiiiiiffffff``````]]]]]]______``````cccccciiiiiiiiiiiieeeeeeggggggdddddd______ttttttrrrrrrwwwwww``````______^^^^^^]]]]]]]]]]]]bbbbbbHHHHHHPPPPPPPPPPPPNNNNNNJJJJJJHHHHHHGGGGGGIIIIIIKKKKKKRRRRRRppppppooooooppppppooooooddddddppppppppppppkkkkkkcccccccccccc^^^^^^ccccccjjjjjjeeeeeeggggggcccccc^^^^^^ccccccnnnnnnaaaaaa^^^^^^______ccccccbbbbbb``````cccccckkkkkkqqqqqqqqqqqq``````\\\\\\[[[[[[[[[[[[ZZZZZZxxxxxx}}}}}}bbbbbbOOOOOOOOOOOOOOOOOOMMMMMMMMMMMMLLLLLLMMMMMMMMMMMMMMMMMMbbbbbbzzzzzzpppppp______kkkkkkppppppttttttvvvvvvooooooaaaaaahhhhhhaaaaaagggggg______]]]]]]______ddddddggggggkkkkkkkkkkkkjjjjjjiiiiiihhhhhheeeeee______bbbbbbkkkkkknnnnnnkkkkkk\\\\\\______iiiiiiddddddbbbbbb``````qqqqqq``````VVVVVVXXXXXXUUUUUUhhhhhh||||||ؼMMMMMMMMMMMMNNNNNNKKKKKKLLLLLLNNNNNNOOOOOOQQQQQQOOOOOONNNNNNWWWWWWllllllbbbbbbddddddppppppuuuuuuttttttaaaaaaVVVVVVggggggjjjjjjkkkkkk[[[[[[aaaaaa``````ccccccmmmmmmffffffddddddeeeeeedddddd^^^^^^ddddddqqqqqqiiiiiimmmmmmffffffhhhhhhvvvvvveeeeeejjjjjjbbbbbb____________xxxxxxddddddcccccceeeeee^^^^^^ZZZZZZyyyyyyvvvvvv||||||oooooozzzzzzMMMMMMMMMMMMLLLLLLKKKKKKMMMMMMMMMMMMNNNNNNPPPPPPPPPPPPPPPPPPOOOOOO\\\\\\{{{{{{rrrrrrpppppplllllluuuuuuoooooo\\\\\\UUUUUUhhhhhhmmmmmmyyyyyyuuuuuu]]]]]]``````hhhhhhhhhhhhjjjjjjkkkkkkggggggiiiiiinnnnnnppppppaaaaaaZZZZZZiiiiii||||||nnnnnnbbbbbb]]]]]]XXXXXXXXXXXXnnnnnnhhhhhhkkkkkkkkkkkkjjjjjj[[[[[[uuuuuuYYYYYYqqqqqqMMMMMMLLLLLLLLLLLLMMMMMMNNNNNNNNNNNNOOOOOOPPPPPPPPPPPPPPPPPPMMMMMMaaaaaavvvvvvppppppjjjjjjeeeeeeYYYYYY^^^^^^ddddddddddddffffffyyyyyyjjjjjjeeeeeellllllmmmmmmccccccccccccaaaaaabbbbbbuuuuuu~~~~~~ddddddSSSSSSDDDDDDZZZZZZ``````rrrrrrcccccc``````ZZZZZZ______ttttttffffffkkkkkkiiiiiiiiiiii^^^^^^oooooo{{{{{{llllllNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONNNNNNOOOOOONNNNNNYYYYYYeeeeeeggggggyyyyyypppppphhhhhhffffffXXXXXXhhhhhhgggggg``````eeeeeeffffffppppppiiiiiiiiiiii||||||wwwwwwdddddd``````ddddddmmmmmmllllllgggggg^^^^^^ttttttvvvvvvnnnnnnppppppkkkkkkkkkkkklllllloooooooooooobbbbbbjjjjjjjjjjjjiiiiii______ggggggyyyyyy\\\\\\VVVVVVwwwwwwQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQMMMMMM[[[[[[zzzzzznnnnnnyyyyyykkkkkkffffff\\\\\\hhhhhhddddddbbbbbbeeeeeekkkkkkhhhhhhffffffllllllyyyyyy~~~~~~kkkkkkmmmmmmffffff||||||}}}}}}ddddddnnnnnnppppppffffffkkkkkkqqqqqqiiiiiiddddddiiiiiikkkkkkiiiiiibbbbbb]]]]]]zzzzzzyyyyyyBBBBBBTTTTTTooooooNNNNNNQQQQQQSSSSSSSSSSSSSSSSSSPPPPPP\\\\\\yyyyyyooooooరkkkkkkeeeeee______llllllzzzzzz^^^^^^oooooonnnnnnbbbbbbccccccccccccddddddjjjjjjffffff{{{{{{hhhhhhiiiiiiggggggeeeeeekkkkkkmmmmmmjjjjjjccccccggggggiiiiiikkkkkkjjjjjjgggggg]]]]]]yyyyyynnnnnn999999CCCCCCqqqqqq||||||uuuuuuZZZZZZTTTTTTIIIIIIMMMMMMSSSSSSVVVVVVSSSSSS______||||||}}}}}}jjjjjjzzzzzzѹjjjjjjvvvvvvwwwwwwkkkkkkbbbbbbggggggffffffttttttuuuuuuhhhhhhhhhhhhbbbbbb]]]]]]eeeeeeffffffhhhhhhwwwwwwrrrrrrjjjjjjnnnnnnkkkkkkiiiiiiiiiiiijjjjjjjjjjjjkkkkkkjjjjjjeeeeeegggggghhhhhhlllllliiiiiiddddddmmmmmmyyyyyy||||||ZZZZZZMMMMMM@@@@@@UUUUUUvvvvvvxxxxxx{{{{{{zzzzzzrrrrrrjjjjjjaaaaaaeeeeee@@@@@@DDDDDDOOOOOOSSSSSS______xxxxxxuuuuuuddddddqqqqqqkkkkkkWWWWWW]]]]]]ssssss``````[[[[[[ccccccffffffbbbbbbggggggggggggbbbbbbddddddcccccc______wwwwwwqqqqqq``````ffffffgggggghhhhhhddddddffffffiiiiiijjjjjjkkkkkkkkkkkkjjjjjjggggggeeeeeeffffffggggggjjjjjjiiiiiibbbbbbwwwwwwllllll333333??????444444RRRRRRmmmmmmppppppvvvvvv||||||yyyyyyssssssqqqqqqppppppnnnnnn444444888888EEEEEELLLLLLeeeeeemmmmmmVVVVVVcccccceeeeeeXXXXXX[[[[[[wwwwwwaaaaaa]]]]]]aaaaaacccccccccccc``````ffffff``````aaaaaabbbbbbccccccggggggbbbbbb``````kkkkkkkkkkkkiiiiiiffffffhhhhhhmmmmmmhhhhhhjjjjjjjjjjjjllllllggggggcccccceeeeeeddddddeeeeeeeeeeeeiiiiiivvvvvv}}}}}}DDDDDD))))))//////UUUUUUoooooo~~~~~~{{{{{{yyyyyyssssssrrrrrrvvvvvv,,,,,,------666666BBBBBB[[[[[[````````````zzzzzz]]]]]][[[[[[\\\\\\oooooossssss``````bbbbbbeeeeee``````cccccc______qqqqqqccccccbbbbbb______aaaaaahhhhhhhhhhhhllllllmmmmmmggggggiiiiiimmmmmmnnnnnnhhhhhhggggggkkkkkkmmmmmmooooooiiiiiibbbbbbcccccccccccc````````````yyyyyy}}}}}}vvvvvvaaaaaa444444......FFFFFFoooooovvvvvvwwwwwwuuuuuuvvvvvv||||||//////,,,,,,//////::::::MMMMMMXXXXXXqqqqqq||||||bbbbbbZZZZZZ\\\\\\\\\\\\cccccc}}}}}}ppppppbbbbbbeeeeeeccccccffffff^^^^^^``````bbbbbbnnnnnn^^^^^^``````aaaaaa``````aaaaaalllllloooooohhhhhhvvvvvvrrrrrriiiiiihhhhhhjjjjjjllllllmmmmmmlllllliiiiii^^^^^^____________YYYYYYYYYYYYyyyyyyqqqqqq@@@@@@//////888888VVVVVVmmmmmm~~~~~~wwwwwwtttttt{{{{{{||||||yyyyyy<<<<<<;;;;;;;;;;;;@@@@@@IIIIIIQQQQQQccccccxxxxxxrrrrrraaaaaa[[[[[[\\\\\\^^^^^^eeeeeeccccccddddddddddddffffffddddddccccccffffff]]]]]]ZZZZZZiiiiiivvvvvvZZZZZZ]]]]]]aaaaaahhhhhhllllllmmmmmmkkkkkkzzzzzzjjjjjjhhhhhhiiiiiijjjjjjkkkkkkmmmmmmlllllllllllljjjjjj]]]]]]XXXXXXWWWWWWOOOOOOkkkkkkuuuuuueeeeee444444GGGGGGMMMMMM@@@@@@oooooo}}}}}}vvvvvvyyyyyy}}}}}}LLLLLLMMMMMMMMMMMMNNNNNNRRRRRRVVVVVVYYYYYYeeeeeennnnnnggggggXXXXXXTTTTTTUUUUUUZZZZZZ``````bbbbbbeeeeeekkkkkkZZZZZZ______hhhhhhggggggddddddddddddffffff^^^^^^TTTTTT______hhhhhhooooookkkkkkjjjjjjnnnnnnllllllllllllcccccc\\\\\\______hhhhhhlllllljjjjjjkkkkkkjjjjjjkkkkkkkkkkkkmmmmmmggggggXXXXXXTTTTTTNNNNNNJJJJJJzzzzzzrrrrrrllllllhhhhhhiiiiiiTTTTTT::::::111111>>>>>>pppppp}}}}}}}}}}}}ZZZZZZ[[[[[[[[[[[[[[[[[[[[[[[[^^^^^^^^^^^^]]]]]]]]]]]]\\\\\\XXXXXXLLLLLLFFFFFFNNNNNNWWWWWW\\\\\\ooooooqqqqqqbbbbbb^^^^^^ccccccffffffddddddddddddeeeeee``````OOOOOO[[[[[[^^^^^^ddddddiiiiiikkkkkkllllllllllllddddddXXXXXXWWWWWW\\\\\\iiiiiinnnnnnmmmmmmllllllllllllmmmmmmkkkkkkggggggWWWWWWRRRRRRPPPPPPJJJJJJKKKKKKiiiiiieeeeeeiiiiiiwwwwwwYYYYYY,,,,,,555555555555777777======rrrrrruuuuuu______``````````````````______bbbbbbaaaaaa````````````````````````XXXXXXGGGGGG@@@@@@CCCCCCEEEEEELLLLLLrrrrrrvvvvvvbbbbbb^^^^^^ccccccdddddddddddddddddd______MMMMMMPPPPPP\\\\\\iiiiiissssssiiiiii\\\\\\^^^^^^VVVVVVWWWWWWYYYYYYXXXXXXZZZZZZggggggoooooopppppppppppphhhhhh[[[[[[RRRRRRNNNNNNNNNNNNKKKKKKDDDDDDTTTTTTddddddhhhhhhiiiiiieeeeeeDDDDDD,,,,,,;;;;;;JJJJJJ999999777777;;;;;;sssssswwwwwwtttttt``````````````````aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbaaaaaaaaaaaaTTTTTTCCCCCC>>>>>><<<<<<>>>>>>hhhhhh{{{{{{eeeeeeaaaaaaeeeeeegggggghhhhhhiiiiii^^^^^^ccccccrrrrrrwwwwwwmmmmmmXXXXXXXXXXXXSSSSSSNNNNNNNNNNNNPPPPPPRRRRRRQQQQQQWWWWWW^^^^^^cccccc^^^^^^SSSSSSOOOOOOOOOOOOLLLLLLKKKKKKGGGGGGFFFFFF[[[[[[______ffffffjjjjjjvvvvvvkkkkkkLLLLLLccccccKKKKKK777777666666<<<<<<ttttttyyyyyyuuuuuuuuuuuu````````````______ccccccbbbbbbccccccbbbbbbccccccccccccbbbbbbbbbbbbcccccc``````OOOOOO??????::::::ZZZZZZddddddvvvvvvwwwwwwkkkkkknnnnnnqqqqqqttttttuuuuuuwwwwwwwwwwwwssssssqqqqqqhhhhhhXXXXXXTTTTTTOOOOOOMMMMMMMMMMMMMMMMMMKKKKKKKKKKKKKKKKKKMMMMMMOOOOOOQQQQQQOOOOOOMMMMMMKKKKKKFFFFFFHHHHHHDDDDDDKKKKKK]]]]]]aaaaaaeeeeeeggggggTTTTTTYYYYYYiiiiiiKKKKKK::::::999999666666;;;;;;jjjjjjppppppyyyyyyrrrrrr``````aaaaaabbbbbbaaaaaaaaaaaabbbbbbbbbbbbbbbbbbcccccccccccccccccccccccc^^^^^^______WWWWWW<<<<<<UUUUUU^^^^^^aaaaaappppppqqqqqqlllllliiiiiikkkkkkooooooooooooqqqqqqrrrrrrppppppppppppiiiiiiUUUUUUNNNNNNNNNNNNNNNNNNOOOOOOMMMMMMLLLLLLKKKKKKKKKKKKKKKKKKJJJJJJKKKKKKKKKKKKJJJJJJHHHHHHFFFFFFCCCCCCAAAAAANNNNNNaaaaaacccccceeeeeeggggggcccccc``````TTTTTT<<<<<<666666::::::777777666666ZZZZZZnnnnnnssssssxxxxxxmmmmmm``````aaaaaaccccccaaaaaaaaaaaaaaaaaabbbbbbbbbbbbccccccccccccbbbbbb[[[[[[ooooooxxxxxx999999666666::::::::::::HHHHHHbbbbbbllllllkkkkkkppppppqqqqqqqqqqqqqqqqqqoooooonnnnnnnnnnnn]]]]]]OOOOOONNNNNNMMMMMMNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLKKKKKKIIIIIIIIIIIIIIIIIIIIIIIIEEEEEECCCCCCBBBBBB>>>>>>KKKKKKddddddhhhhhhffffffYYYYYYKKKKKK888888??????DDDDDD<<<<<<777777666666555555NNNNNNqqqqqqkkkkkkrrrrrrrrrrrrjjjjjjaaaaaaaaaaaabbbbbbaaaaaaaaaaaaaaaaaabbbbbbccccccccccccbbbbbb]]]]]]ᑑDDDDDD999999666666------FFFFFFzzzzzziiiiiioooooooooooonnnnnnmmmmmmllllllnnnnnneeeeeeQQQQQQNNNNNNNNNNNNLLLLLLKKKKKKKKKKKKLLLLLLLLLLLLJJJJJJGGGGGGEEEEEEFFFFFFEEEEEEEEEEEEBBBBBB@@@@@@;;;;;;GGGGGGggggggbbbbbbLLLLLL::::::111111222222000000999999CCCCCC777777//////222222EEEEEEddddddjjjjjjppppppppppppggggggaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbccccccddddddddddddbbbbbbiiiiiiꞞIIIIII666666IIIIII䍍cccccchhhhhhkkkkkkjjjjjjllllllllllllggggggSSSSSSOOOOOOMMMMMMLLLLLLJJJJJJKKKKKKMMMMMMLLLLLLIIIIIIEEEEEEDDDDDDDDDDDDDDDDDDEEEEEECCCCCC======777777IIIIII\\\\\\@@@@@@333333666666777777666666444444333333======@@@@@@222222++++++CCCCCCrrrrrr______ddddddiiiiiiqqqqqq]]]]]]bbbbbbbbbbbbbbbbbbbbbbbbaaaaaabbbbbbccccccddddddccccccaaaaaacccccckkkkkkDDDDDDhhhhhh[[[[[[iiiiiijjjjjjmmmmmmaaaaaaSSSSSSOOOOOOMMMMMMLLLLLLKKKKKKKKKKKKJJJJJJHHHHHHEEEEEEDDDDDDCCCCCCBBBBBBBBBBBBCCCCCCDDDDDDBBBBBBFFFFFFTTTTTT666666111111444444444444333333444444444444333333333333<<<<<<>>>>>>......GGGGGG}}}}}}YYYYYY[[[[[[ZZZZZZeeeeeeqqqqqqLLLLLLccccccccccccccccccccccccccccccccccccddddddeeeeeecccccckkkkkknnnnnnttttttYYYYYYeeeeeekkkkkk``````TTTTTTPPPPPPNNNNNNKKKKKKIIIIIIGGGGGGGGGGGGDDDDDDDDDDDDDDDDDDBBBBBBCCCCCCDDDDDDEEEEEEHHHHHHMMMMMMssssssiiiiii------333333333333222222222222000000000000111111//////111111999999::::::FFFFFFPPPPPPKKKKKKZZZZZZTTTTTTddddddkkkkkk======ccccccccccccccccccccccccccccccbbbbbbdddddddddddddddddd}}}}}}ͭ^^^^^^^^^^^^______UUUUUUQQQQQQNNNNNNLLLLLLLLLLLLKKKKKKGGGGGGFFFFFFFFFFFFDDDDDDDDDDDDEEEEEEHHHHHHMMMMMMNNNNNNNNNNNN{{{{{{SSSSSS------333333333333222222000000//////000000//////------////////////333333888888777777<<<<<<LLLLLLRRRRRRffffffbbbbbb222222ccccccccccccccccccddddddddddddccccccddddddffffffeeeeeepppppp}}}}}}XXXXXXOOOOOOKKKKKKLLLLLLKKKKKKMMMMMMNNNNNNKKKKKKJJJJJJHHHHHHGGGGGGFFFFFFEEEEEE??????NNNNNNUUUUUUXXXXXXoooooo999999444444444444555555444444111111000000000000......,,,,,,------////////////111111;;;;;;======888888CCCCCCaaaaaaWWWWWW000000bbbbbbccccccddddddddddddddddddccccccddddddffffffffffffpppppp~~~~~~SSSSSSAAAAAA@@@@@@EEEEEEJJJJJJIIIIIIHHHHHHIIIIIIIIIIIIIIIIII\\\\\\BBBBBB<<<<<<CCCCCCkkkkkk[[[[[[444444999999999999::::::::::::999999888888888888444444000000......++++++++++++......000000@@@@@@CCCCCC777777HHHHHHJJJJJJ444444aaaaaabbbbbbddddddccccccddddddddddddeeeeeeffffffeeeeeeoooooo̾ؿUUUUUUFFFFFFLLLLLLMMMMMMMMMMMMKKKKKKKKKKKK``````DDDDDD??????DDDDDDccccccWWWWWWCCCCCC;;;;;;;;;;;;::::::;;;;;;<<<<<<>>>>>>;;;;;;======::::::888888333333......------++++++......@@@@@@BBBBBB@@@@@@CCCCCC555555``````bbbbbbffffffeeeeeeeeeeeeffffffeeeeeeddddddffffffֿddddddIIIIIILLLLLLLLLLLLJJJJJJJJJJJJIIIIIIFFFFFFLLLLLL]]]]]]______RRRRRRQQQQQQOOOOOOGGGGGG@@@@@@<<<<<<<<<<<<============<<<<<<======>>>>>>@@@@@@@@@@@@<<<<<<999999<<<<<<RRRRRRTTTTTTDDDDDDIIIIIIRRRRRR;;;;;;
diff --git a/PerlMagick/t/reference/read/input_gray_lsb_08bit_mat.miff b/PerlMagick/t/reference/read/input_gray_lsb_08bit_mat.miff
new file mode 100644
index 0000000..85c140b
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_lsb_08bit_mat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_lsb_16bit_mat.miff b/PerlMagick/t/reference/read/input_gray_lsb_16bit_mat.miff
new file mode 100644
index 0000000..0750f3b
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_lsb_16bit_mat.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=63 rows=61 depth=8
+page=63x61+0+0
+
+:yyyJJJSSSXXXXXXXXX```hhhnnnsssuuusssuuuvvvvvvvvvvvvxxxxxxyyytttxxxtttxxxuuuxxxsssssssssqqqpppkkk___ggg[[[hhhlllmmmjjjnnnmmmooonnnhhhsssFFFNNNSSSSSSSSS^^^hhhmmmooorrrrrrssstttuuuttttttssstttuuuqqqtttrrruuussssssrrrpppoooppppppiii```ZZZ~~~􋋋___hhhjjjiiillllllnnnrrrXXXuuuGGGLLLVVVRRRQQQ]]]fffjjjnnnrrrrrrrrrtttssstttssssssrrrrrrsssssspppxxxvvvtttrrrqqqmmmpppnnnllldddWWWmmmbbbdddiiilllmmmrrrwwwTTTsssAAALLLSSSSSSRRR[[[fffjjjnnnpppnnnqqqqqqqqqqqqrrruuullljjjmmmmmmmmmpppssstttoooooommmmmmnnnkkkdddYYYiii```iiijjjmmmtttPPPrrrCCCLLLSSSQQQQQQ[[[ccchhhlllnnnlllnnnoooooooooooopppjjjhhhjjjjjjiiimmmqqqsssnnnooolllkkkmmmjjjdddZZZeeerrr```jjjrrrQQQooo???LLLQQQSSSQQQ[[[dddiiijjjkkkllllllllloooooonnnnnnllloootttxxxlllkkknnnlllooommmlllkkkiiiaaa]]]bbbYYYfffQQQ###rrr@@@IIIRRRQQQQQQ\\\eeehhhkkkkkknnnnnnlllmmmnnnpppeeennnnnnllljjjfff```ZZZ```MMM!!! {{{jjjrrr:::FFFMMMNNNRRRZZZbbbfffgggjjjjjjlllrrrrrr|||زnnnhhhgggeeeaaaZZZUUU```OOObbbppp666CCCLLLNNNQQQUUU^^^aaafffggghhhuuu___jjjkkkyyyyyyρYYY^^^^^^YYYTTT\\\UUU qqq888eeeooo444CCCOOONNNOOOVVV^^^```cccfffhhhlllZZZbbbnnnttt{{{ⱱVVVXXXTTTSSSZZZooommmDDD!!!'''HHH===fffmmm666CCCLLLPPPOOOVVV]]]aaaeeeggghhhXXX___eeeiiimmmwww}}}GGGMMMMMMZZZfff<<<vvv^^^///>>>]]]@@@???eeekkk888FFFJJJPPPOOOVVV^^^bbbfffiiiYYY\\\cccccceeeqqq}}}@@@HHHWWWnnnRRR||| (((HHHCCCCCCAAAbbbmmm999FFFNNNMMMQQQVVV```bbbhhhbbb]]]]]]bbbeeeoooxxx򘘘666RRRlll)))kkk333 !!!555~~~CCCFFFCCCeeeooo999CCCJJJOOONNNVVV^^^```QQQZZZ]]]```jjjvvvuuukkkJJJmmm ;;;xxx]]] !!!tttFFFCCC???```ooo777AAAGGGMMMQQQUUU[[[]]]RRRYYY[[[cccppp{{{zzz{{{lll>>>ooo"""FFF((("""!!! ZZZDDDEEEDDD^^^mmm333>>>KKKLLLNNNRRR[[[OOOZZZ\\\iiimmmnnntttfff}}}lllnnnbbb  :::JJJLLLJJJ___qqq666BBBLLLOOOOOOVVVZZZrrrOOOSSS```eeehhhtttggg嘘hhhkkk|||NNNMMMJJJbbbttt777DDDMMMNNNMMMTTTSSSmmmQQQQQQYYYcccggggggѐMMMKKKLLLLLLKKKcccvvv777CCCJJJLLLLLLPPPIII|||XXXSSSZZZdddfffƿ222JJJJJJJJJcccwww999EEEKKKKKKKKKOOOJJJӐnnnQQQXXX___{{{xxxÿ߮ư bbbJJJIIIIIIeeeyyy999FFFLLLJJJLLLMMMLLLΛ|||VVVXXXyyyyyyqqq躺___???LLLJJJMMMfff{{{666DDDIIIJJJJJJKKKRRRܫeeekkktttlll}}}xxxxxxzzzۋiii qqqNNNNNNOOOjjj{{{555BBBKKKLLLJJJJJJHHH⾾nnnffffffzzzwwwrrrxxxxxxrrr]]]CCCdddQQQTTT222---rrr߯iiiMMMvvv555RRRNNNNNNjjj|||777CCCIIIKKKLLLIII>>>vvvxxx\\\ssstttooouuuyyymmmoooXXXDDD+++[[[HHHPPP999qqq޹ZZZLLLrrrmmm"""eeeUUUQQQNNNhhh|||777AAAIIIKKKKKKKKKHHHҘtttmmmppphhhnnnqqqnnnbbb;;;000===777JJJ666888yyyױhhhooorrr +++VVVSSSMMMbbb~~~555???HHHIIIHHHMMMQQQ\\\ݷlllpppiiimmmllloooFFF<<<///888333'''999OOOiiiľο@@@ZZZuuu]]]"""RRRVVVRRRIII\\\555===HHHIIIKKKOOOWWWMMMooobbbkkkkkkhhhNNN000AAA!!!999'''&&&555]]]¼oooDDDbbbAAA###%%%rrrUUUSSSIII[[[555AAAKKKMMMJJJQQQ[[[UUU]]]eeegggkkk>>>...000000,,,KKK cccʭܔ$$$:::%%%!!!)))CCCTTTQQQKKK]]]:::@@@MMMPPPLLLVVVddd\\\yyy^^^iiiccc555---"""&&&CCCCCCqqq漼000--- %%%(((mmmSSSNNNHHHYYY;;;EEENNNQQQOOOVVV___aaaaaa~~~kkkqqq===---***'''###444///bbbLLLttt444"""((( ,,,OOOLLLGGGYYY;;;BBBOOOQQQOOOVVV___gggqqqXXXvvvTTT666777222'''+++(((EEE|||SSSZZZLLL,,,...UUUOOOQQQIIIUUU:::DDDOOONNNMMMSSS______EEEaaa222555JJJ$$$&&&777,,,{{{sssiii@@@kkkǖ```DDDFFFaaa+++&&&!!!qqqLLLKKKDDDPPP:::???LLLJJJGGGfffzzz>>>444LLLKKK)))111===mmmִ:::###777444hhhց555%%%###;;;ppp+++***LLLHHH===JJJ:::CCCKKKNNNBBBpppxxx999...000---eee000888ZZZ!!!???777VVVXXXsss999EEEmmm555yyy222NNNPPPJJJ<<<GGG???IIIVVVGGGOOO888<<<666444HHHqqq111{{{nnnuuummmbbbfffmmmwwwKKK###333444 oooNNNEEE666???>>>JJJVVVkkkyyyGGG***+++aaa<<<...PPPbbbBBBMMMYYYlllrrriiiّpppTTT444---)))&&&DDD;;;---<<<===HHHdddxxxhhhIII...[[[ZZZ(((MMMWWWUUU###'''WWWTTTnnn}}}jjj㤤|||hhh???###???888333+++999>>>KKKXXX\\\OOO@@@<<<___999$$$ccc>>>RRR%%%\\\lllkkk衡jjj777### ^^^888666&&&666888[[[qqqRRR^^^DDDGGGjjjFFF%%%555---PPPzzz,,,WWWkkk|||pppdddꛛiii'''&&&<<<{{{:::555 ///999WWWccc@@@RRR===JJJkkkHHHAAAYYYBBB^^^JJJ:::TTThhhvvvvvvllllll{{{䙙~~~___(((vvvPPP---;;;555&&&>>>EEEIIIZZZ;;;UUU@@@<<<]]]sss###(((HHH444EEEVVVfffsssyyydddPPP___www===)))ddd^^^NNN444444,,,YYY>>>FFFbbb222999@@@@@@```rrrAAAVVV!!!AAArrrooo&&&PPPYYYeeeppp}}}{{{nnn!!!!!!666%%%MMMhhhnnn111---'''^^^===JJJkkk777KKK+++555HHHSSSjjjCCC000}}}ccc:::###RRRYYYhhhnnnxxx{{{ʾJJJ%%%666$$$666www&&&)))'''\\\>>>YYYaaa...888///HHHJJJBBBeeeKKKdddTTT$$$&&&IIIKKKhhhkkkvvv{{{eeeiiiqqqmmmuuuvvvwww""")))777)))&&&!!!%%%,,,bbb^^^IIIddd666999fffKKKVVVJJJrrrzzz$$$!!!???AAA```dddpppqqqZZZ]]]uuu|||MMM$$$<<<------[[[777cccEEEMMM###999zzz```NNNooo~~~---###"""!!!(((%%%666333PPP]]]jjjvvv{{{mmmhhheeennnsss  ###>>>000%%%<<<^^^777ZZZ===999***###yyyxxxeeecccZZZBBB"""!!! !!!%%%###+++777QQQeeetttzzz~~~==="""$$$$$$AAA333$$$999aaa888HHH)))???...fff@@@xxxxxxmmmRRR'''"""''' """$$$&&&%%%)))NNNiiizzz $$$))) ---GGG999(((***WWW___hhh(((111***sssKKKWWWkkkvvv888000!!!'''&&&///333III^^^ooo;;;(((&&&000KKKBBB///qqqxxxxxx᧧CCC???!!!!!!;;;^^^KKK555***333OOOjjj^^^jjjjjjZZZ000...&&&$$$""")))WWWjjjnnnxxxأGGG000III===666xxxqqqhhhbbbgggrrruuulll䦦...$$$bbb666%%%ggg>>>HHH***PPP+++YYYcccKKKmmm___SSS&&&&&& $$$"""---'''VVVeeemmmxxx|||}}}≉'''@@@555999tttdddUUUeeeMMM駧111444@@@iii%%%,,,:::111999<<<555AAAddd\\\hhh<<<)))$$$!!!)))(((==='''WWWeeerrryyy|||윜)))000AAA~~~ssswwwoooBBBAAAFFFVVV;;;)))nnn"""'''CCC000BBBBBBVVVwwwLLL\\\ $$$***!!!KKK---RRRnnnttt{{{|||fffGGG}}}===KKKYYYOOO###aaa&&&"""EEE$$$+++000OOOSSSppp111vvv!!!***$$$"""PPP333TTTmmmuuuyyy|||NNNwwwfffIIIYYYRRRNNN """OOO!!!EEE888$$$444XXXnnnyyyggg%%%&&& 444bbb:::YYYqqqwwwvvvyyyIIIXXX|||LLLLLL]]]KKKYYY ///RRR$$$---555%%% 222===cccaaaOOOCCCAAA"""KKKiii;;;```qqq|||wwwuuu|||񏏏eee|||}}}TTTRRRSSSNNNUUUkkk:::|||TTT,,,"""*** """$$$===IIIrrrdddIII"""&&&/// +++ZZZkkk:::jjjyyy{{{zzzvvvyyyqqqaaaPPPMMMCCCUUUNNN[[[KKKvvvaaa$$$&&&)))(((""",,,555AAADDD===yyy)))@@@aaaVVVFFFsss{{{{{{xxxxxx~~~XXXnnnRRRHHH???PPPLLLPPP OOO[[[pppTTT###$$$((('''(((&&&:::tttAAAHHH000***VVVaaa///dddttt{{{}}}}}}yyyvvv|||CCC???>>>EEEVVVnnn333BBBHHHOOONNNTTT222ZZZrrrqqqRRR !!!(((+++###NNN~~~[[[BBB___===BBBsssxxxzzz|||}}}xxxzzz~~~TTTXXXEEE,,,gggش...222AAAUUUBBBXXXJJJKKKwwwÆqqqSSS &&&...***+++...222[[[OOO222NNN777666gggsssyyyzzz{{{}}}{{{{{{OOO^^^UUUEEE444lll॥999+++888UUU<<<III___EEE \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_gray_lsb_32bit_mat.miff b/PerlMagick/t/reference/read/input_gray_lsb_32bit_mat.miff
new file mode 100644
index 0000000..84812a6
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_lsb_32bit_mat.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=46 rows=71 depth=8
+
+:wwwxxxrrrmmmZZZWWWyyywww|||}}}xxx~~~^^^oooiiinnnccceeepppeeeyyyⷷ{{{RRRěiii```ooo}}}|||{{{pppkkk¦~~~̷tttfffثSSSsssmmmvvvfffiiiiiinnnlllfff```www|||ȩKKKgggrrrmmmhhhyyyxxxgggeeepppsss|||}}}jjjwwwccckkkϱ㼼{{{vvvKKK~~~}}}\\\gggggg|||ݼttt{{{XXXUUUzzzoooiiiyyyIJyyy|||lll(((||||||틋LLL~~~sssppp999{{{}}}zzzFFF%%%|||}}}zzzwww|||FFF|||~~~{{{ttt|||444 555yyy{{{000{{{~~~]]]AAA###|||}}}NNN%%%JJJ---ooozzz|||ȥrrr***NNNDDD{{{nnn|||{{{zzzչۚBBB)))nnnxxxvvv|||uuu___RRRcccjjjyyy񚚚fff###oooxxxzzznnnuuukkkmmmvvv|||ޗ,,,iii{{{jjjvvvnnnvvvyyywwwᬬѰ:::|||{{{lllyyyܑ@@@|||{{{ƭ@@@zzz{{{汱}}}999|||{{{ooo~~~Ӊ|||~~~𠠠***}}}yyytttuuuvvvpppŔmmm{{{xxxyyy孭eeepppjjjkkkffffffzzz{{{}}}{{{vvvʎ;;;dddeeemmmJJJXXXxxx}}}~~~www|||ttt֑jjj٠RRR###@@@zzz]]]KKKiiiyyy~~~vvvuuusssIIIuuuɶjjjsss]]]RRRHHHrrrvvv|||qqquuuppphhhvvvssskkk"""hhhRRRUUUHHHzzz}}}{{{}}}iiippp{{{pppkkkϗ^^^~~~|||IIIUUUlllWWWVVVUUUIII}}}{{{___gggvvv~~~{{{kkk|||ZZZgggpppsss***TTT|||yyy\\\XXXXXXTTTKKKUUU```iiinnnrrrssslll]]]uuu|||yyyrrrkkkKKKooodddmmmAAAppp[[[XXXZZZPPPWWW333BBBAAAEEETTTcccWWWqqq~~~dddǒIIIfffVVVmmm~~~ppp|||YYYVVVUUUMMMjjj;;;DDDNNNbbbvvvwww^^^{{{wwwaaaTTToooSSSgggrrr\\\[[[XXXIIIsss{{{NNNaaarrrvvvzzzgggXXXIIIMMM{{{pppjjjxxxʎooo^^^bbbvvv}}}yyybbbccc```MMMsssHHHKKKsss{{{222999---oooyyyyyyָTTT\\\cccMMM```}}}|||```___]]]OOOvvv###fffsss'''FFF{{{ÙmmmwwwiiiFFFZZZmmmxxxddd[[[\\\XXX~~~RRR+++wwwuuuvvvvvvEEEPPPųjjjNNNbbb```nnnddd^^^]]]RRR---DDD~~~wwwsss<<<qqq|||nnn)))TTT\\\iii{{{aaa\\\PPPGGG ooowwwvvvxxxpppkkkyyyuuuuuu```gggsssxxxyyyxxxjjjppp{{{yyy}}}^^^UUUGGGGGGWWW&&&rrrqqqvvvxxxpppppprrruuu{{{xxx|||zzz}}}555[[[WWWnnn^^^TTTCCCJJJ888888yyymmmrrrwwwpppmmmpppppptttuuu|||mmmQQQfffkkkyyy²QQQJJJ666TTTuuu&&&GGGrrrlllqqqpppuuusssuuuvvvyyyyyyrrrxxxyyy띝RRRjjjgggpppۧBBBUUU777QQQ``` RRRllltttxxxyyyxxxxxxuuuuuu~~~wwwsssVVV```\\\gggسLLLVVV ^^^}}}ZZZ%%%VVVlllxxx}}}{{{vvvuuuzzz~~~uuupppXXXNNNSSS___lllyyyHHHLLLpppzzzZZZ)))VVVfffooo{{{xxxuuuvvvwwwgggooo}}}\\\GGGQQQZZZdddlllpppCCC>>>,,,www{{{WWW###UUUfffeeekkkxxx|||yyyuuusssqqqaaajjjuuu{{{}}}~~~}}}VVVHHHTTTVVV^^^gggsssbbb:::333|||{{{VVVJJJfffbbb^^^dddllliiiggggggaaaaaaeeeqqq|||{{{tttyyyrrrZZZPPPVVVTTT```fffnnnxxxkkkZZZ<<<WWW<<<iiiccc\\\```jjjbbb^^^```___```ffftttxxxrrrzzzlll^^^\\\^^^ZZZaaafffllltttwww~~~qqq]]]YYYMMM---[[[hhhccc```pppiii^^^fffkkkdddgggooo{{{zzzzzzyyycccUUUYYY]]]]]]bbbeeeqqqvvvsssvvvzzzUUU000QQQDDD&&&LLL```fffaaaooojjjZZZlllssseee^^^gggvvvxxx}}}{{{```RRRWWW```dddggghhhmmmpppoooooowww555'''UUU888 !!!999SSS]]]jjjjjjnnn[[[hhhooodddZZZbbbssszzz{{{vvvaaaXXXZZZ___ddddddhhhllljjjmmmooovvvJJJ???fff|||---""")))PPPSSSfffaaapppcccaaaqqqooofff___kkkvvvzzzrrr]]]ZZZZZZ]]]YYY]]]dddjjjmmmpppsss~~~EEE888rrrsss"""""""""%%%BBBUUUaaacccdddpppZZZjjjtttooo^^^ccclllyyy}}}dddWWWWWWeee___```___ccckkkrrruuu<<<>>>eee""""""$$$777TTTbbbdddfffsss``````oooooo```\\\lllyyyhhhUUUTTTaaagggmmmiiihhhlllpppttt~~~'''999~~~III#########000QQQccceeeiiisssbbbXXXiiinnndddXXXdddtttvvv]]]WWWYYY[[[fffmmmppprrrsssrrrsssQQQ^^^|||***###%%%&&&000PPPaaadddiiippp^^^XXXbbbpppfffYYYdddpppkkkWWWSSS[[[]]]eeejjjpppuuuuuuuuuuuu^^^rrrzzzqqq###))),,,,,,DDDXXX]]]cccpppZZZ^^^eeeooobbbYYYaaaooommmWWWWWWZZZ\\\eeejjjlllmmmlllrrrrrr|||[[[vvv}}}PPP&&&'''---222...;;;XXX```___ppp```]]]fffpppiiiaaaiiiqqqfffZZZ^^^XXX[[[]]]aaagggooonnnooopppVVV{{{uuu~~~666###...///111222555555MMM______oooaaaZZZhhhppplllfffgggpppjjjRRRSSSPPPSSSQQQZZZfffiiimmmnnnwww[[[|||sss!!!///333555666555555000???QQQ]]]ooofffVVVddduuuuuufffiiillloooUUUMMMNNNQQQYYY\\\aaaggggggmmmuuuyyycccvvvsssbbb!!!444555777888555666000888KKKYYYllliiiVVV]]]qqquuugggjjjnnnhhhSSSNNNPPPTTT[[[[[[dddllllllooovvv{{{^^^hhhpppzzz555***888888888666444333222///AAATTTjjjpppWWWUUUfffiiidddjjjjjj___OOOAAAGGGMMMRRRTTT]]]fffpppgggddd222KKK[[[cccjjjpppuuu!!!444888;;;<<<;;;555333222...444LLLhhhxxx]]]TTT\\\]]]```jjjmmm]]]???999BBB???AAAEEEHHHQQQNNNqqqddd222 $$$!!!"""%%%***111333333111---777QQQrrr^^^MMMRRRXXX[[[dddaaa666***555999333,,,***AAAպ|||iiiJJJ---###,,,000,,,444MMMCCC<<<KKKVVV\\\[[[666(((...---'''######VVVTTTDDDgggGGG((("""%%%###))),,,&&&555PPPQQQ555
diff --git a/PerlMagick/t/reference/read/input_gray_lsb_double_V4_mat.miff b/PerlMagick/t/reference/read/input_gray_lsb_double_V4_mat.miff
new file mode 100644
index 0000000..a161af1
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_lsb_double_V4_mat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_lsb_double_fits.miff b/PerlMagick/t/reference/read/input_gray_lsb_double_fits.miff
new file mode 100644
index 0000000..a936134
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_lsb_double_fits.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_lsb_double_mat.miff b/PerlMagick/t/reference/read/input_gray_lsb_double_mat.miff
new file mode 100644
index 0000000..b6e5e7c
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_lsb_double_mat.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=46 rows=71 depth=8
+page=46x71+0+0
+
+:wwwxxxrrrmmmZZZWWWyyywww|||}}}xxx~~~^^^oooiiinnnccceeepppeeeyyyⷷ{{{RRRěiii```ooo}}}|||{{{pppkkk¦~~~̷tttfffثSSSsssmmmvvvfffiiiiiinnnlllfff```www|||ȩKKKgggrrrmmmhhhyyyxxxgggeeepppsss|||}}}jjjwwwccckkkϱ㼼{{{vvvKKK~~~}}}\\\gggggg|||ݼttt{{{XXXUUUzzzoooiiiyyyIJyyy|||lll(((||||||틋LLL~~~sssppp999{{{}}}zzzFFF%%%|||}}}zzzwww|||FFF|||~~~{{{ttt|||444 555yyy{{{000{{{~~~]]]AAA###|||}}}NNN%%%JJJ---ooozzz|||ȥrrr***NNNDDD{{{nnn|||{{{zzzչۚBBB)))nnnxxxvvv|||uuu___RRRcccjjjyyy񚚚fff###oooxxxzzznnnuuukkkmmmvvv|||ޗ,,,iii{{{jjjvvvnnnvvvyyywwwᬬѰ:::|||{{{lllyyyܑ@@@|||{{{ƭ@@@zzz{{{汱}}}999|||{{{ooo~~~Ӊ|||~~~𠠠***}}}yyytttuuuvvvpppŔmmm{{{xxxyyy孭eeepppjjjkkkffffffzzz{{{}}}{{{vvvʎ;;;dddeeemmmJJJXXXxxx}}}~~~www|||ttt֑jjj٠SSS###@@@zzz]]]KKKiiiyyy~~~vvvuuusssIIIuuuɶjjjsss]]]RRRHHHrrrvvv|||qqquuuppphhhvvvssskkk"""hhhRRRUUUHHHzzz}}}{{{}}}iiippp{{{pppkkkϗ^^^~~~|||IIIUUUlllWWWVVVUUUIII}}}{{{___gggvvv~~~{{{kkk|||ZZZgggpppsss***TTT|||yyy\\\XXXXXXTTTKKKUUU```iiinnnrrrssslll]]]uuu|||yyyrrrkkkKKKooodddmmmAAAppp[[[XXXZZZPPPWWW333BBBAAAEEETTTcccWWWqqq~~~dddǒIIIfffVVVmmm~~~ppp|||YYYVVVUUUMMMjjj;;;DDDNNNbbbvvvwww^^^{{{wwwaaaTTToooSSSgggrrr\\\[[[XXXIIIsss{{{NNNaaarrrvvvzzzgggXXXIIIMMM{{{pppjjjxxxʎooo^^^bbbvvv}}}yyybbbccc```MMMsssHHHKKKsss{{{222999---oooyyyyyyָTTT\\\cccMMM```}}}|||```___]]]OOOvvv###fffsss'''FFF{{{ÙmmmwwwiiiFFFZZZmmmxxxddd[[[\\\XXX~~~RRR+++wwwuuuvvvvvvEEEPPPųjjjNNNbbb```nnnddd^^^]]]RRR---DDD~~~wwwsss<<<qqq|||nnn)))TTT\\\iii{{{aaa\\\PPPGGG ooowwwvvvxxxpppkkkyyyuuuuuu```gggsssxxxyyyxxxjjjppp{{{yyy}}}^^^UUUGGGGGGWWW&&&rrrqqqvvvxxxpppppprrruuu{{{xxx|||zzz}}}555[[[WWWnnn^^^TTTCCCJJJ888888yyymmmrrrwwwpppmmmpppppptttuuu|||mmmQQQfffkkkyyy²QQQJJJ666TTTuuu&&&GGGrrrlllqqqpppuuusssuuuvvvyyyyyyrrrxxxyyy띝RRRjjjgggpppۧBBBUUU777QQQ``` RRRllltttxxxyyyxxxxxxuuuuuu~~~wwwsssVVV```\\\gggسLLLVVV ^^^}}}ZZZ%%%VVVlllxxx}}}{{{vvvuuuzzz~~~uuupppXXXNNNSSS___lllyyyHHHLLLpppzzzZZZ)))VVVfffooo{{{xxxuuuvvvwwwgggooo}}}\\\GGGQQQZZZdddlllpppCCC>>>,,,www{{{WWW###UUUfffeeekkkxxx|||yyyuuusssqqqaaajjjuuu{{{}}}~~~}}}VVVHHHTTTVVV^^^gggsssbbb:::333|||{{{VVVJJJfffbbb^^^dddllliiiggggggaaaaaaeeeqqq|||{{{tttyyyrrrZZZPPPVVVTTT```fffnnnxxxkkkZZZ<<<WWW<<<iiiccc\\\```jjjbbb^^^```___```ffftttxxxrrrzzzlll^^^\\\^^^ZZZaaafffllltttwww~~~qqq]]]YYYMMM---[[[hhhccc```pppiii^^^fffkkkdddgggooo{{{zzzzzzyyycccUUUYYY]]]]]]bbbeeeqqqvvvsssvvvzzzUUU000QQQDDD&&&LLL```fffaaaooojjjZZZlllssseee^^^gggvvvxxx}}}{{{```RRRWWW```dddggghhhmmmpppoooooowww555'''UUU888 !!!999SSS]]]jjjjjjnnn[[[hhhooodddZZZbbbssszzz{{{vvvaaaYYYZZZ___ddddddhhhllljjjmmmooovvvJJJ???fff|||---""")))PPPSSSfffaaapppcccaaaqqqooofff___kkkvvvzzzrrr]]]ZZZZZZ]]]YYY]]]dddjjjmmmpppsss~~~EEE888rrrsss"""""""""%%%BBBUUUaaacccdddpppZZZjjjtttooo^^^ccclllyyy}}}dddWWWWWWeee___```___ccckkkrrruuu<<<>>>eee""""""$$$777TTTbbbdddfffsss``````oooooo```\\\lllyyyhhhUUUTTTaaagggmmmiiihhhlllpppttt~~~'''999~~~III#########000QQQccceeeiiisssbbbXXXiiinnndddXXXdddtttvvv]]]WWWYYY[[[fffmmmppprrrsssrrrsssQQQ^^^|||***###%%%&&&000PPPaaadddiiippp^^^XXXbbbpppfffYYYdddpppkkkWWWSSS[[[]]]eeejjjpppuuuuuuuuuuuu^^^rrrzzzqqq###))),,,,,,DDDXXX]]]cccpppZZZ^^^eeeooobbbYYYaaaooommmWWWWWWZZZ\\\eeejjjlllmmmlllrrrrrr|||[[[vvv}}}PPP&&&'''---222...;;;XXX```___ppp```]]]fffpppiiiaaaiiiqqqfffZZZ^^^XXX[[[]]]aaagggooonnnooopppVVV{{{uuu~~~666###...///111222555555MMM______oooaaaZZZhhhppplllfffgggpppjjjRRRSSSPPPSSSQQQZZZfffiiimmmnnnwww[[[|||sss!!!///333555666555555000???QQQ]]]ooofffVVVddduuuuuufffiiillloooUUUMMMNNNQQQYYY\\\aaaggggggmmmuuuyyycccvvvsssbbb!!!444555777888555666000888KKKYYYllliiiVVV]]]qqquuugggjjjnnnhhhSSSNNNPPPTTT[[[[[[dddllllllooovvv{{{^^^hhhpppzzz555***888888888666444333222///AAATTTjjjpppWWWUUUfffiiidddjjjjjj___OOOAAAGGGMMMRRRTTT]]]fffpppgggddd222KKK[[[cccjjjpppuuu!!!444888;;;<<<;;;555333222...444LLLhhhxxx]]]TTT\\\]]]```jjjmmm]]]???999BBB???AAAEEEHHHQQQNNNqqqddd222 $$$!!!"""%%%***111333333111---777QQQrrr^^^MMMRRRXXX[[[dddaaa666***555999333,,,***AAAպ|||iiiJJJ---###,,,000,,,444MMMCCC<<<KKKVVV\\\[[[666(((...---'''######VVVTTTDDDgggGGG((("""%%%###))),,,&&&555PPPQQQ555
diff --git a/PerlMagick/t/reference/read/input_gray_lsb_float_mat.miff b/PerlMagick/t/reference/read/input_gray_lsb_float_mat.miff
new file mode 100644
index 0000000..a192787
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_lsb_float_mat.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=45 rows=71 depth=8
+page=45x71+0+0
+
+:wwwxxxrrrmmmZZZWWWyyywww|||}}}xxx~~~^^^oooiiinnnccceeepppyyyⷷ{{{RRRěiii```}}}|||{{{pppkkk¦~~~̷tttfffثSSSmmmvvvfffiiiiiinnnlllfff```www|||ȩKKKgggmmmhhhyyyxxxgggeeepppsss|||}}}jjjwwwccckkkϱ㼼{{{vvvKKK~~~}}}\\\gggggg|||ݼttt{{{XXXUUUzzzoooiiiyyyIJyyy|||lll(((||||||틋LLL~~~sssppp999{{{}}}zzzFFF%%%|||}}}zzzwww|||FFF|||~~~{{{ttt|||444 555yyy{{{000{{{~~~]]]###|||}}}NNN%%%---ooozzz|||ȥrrr***DDD{{{nnn|||{{{zzzչۚBBBnnnxxxvvv|||uuu___RRRcccjjjyyy񚚚fffoooxxxzzznnnuuukkkmmmvvv|||ޗiii{{{jjjvvvnnnvvvyyywwwᬬѰ|||{{{lllyyyܑ|||{{{ƭzzz{{{汱}}}|||{{{ooo~~~Ӊ|||~~~𠠠}}}yyytttuuuvvvpppŔmmm{{{xxxyyy孭eeepppjjjkkkffffffzzz{{{}}}{{{vvvʎ;;;dddeeemmmJJJXXXxxx}}}~~~www|||ttt֑jjj٠SSS@@@zzz]]]KKKiiiyyy~~~vvvuuusssIIIuuuɶjjjsss]]]RRRHHHrrrvvv|||qqquuuppphhhvvvssskkkhhhRRRUUUHHHzzz}}}{{{}}}iiippp{{{pppkkkϗ^^^~~~|||IIIlllWWWVVVUUUIII}}}{{{___gggvvv~~~{{{kkk|||ZZZgggpppsss***TTT|||\\\XXXXXXTTTKKKUUU```iiinnnrrrssslll]]]uuu|||yyyrrrkkkKKKooodddmmmAAAppp[[[XXXZZZPPPWWW333BBBAAAEEETTTcccWWWqqq~~~dddǒIIIfffVVVmmm~~~ppp|||YYYVVVUUUMMMjjj;;;DDDNNNbbbvvvwww^^^{{{wwwaaaTTToooSSSgggrrr\\\[[[XXXIIIsss{{{NNNaaarrrvvvzzzgggXXXIIIMMM{{{pppjjjxxxʎooo^^^bbbvvv}}}yyybbbccc```MMMsssHHHKKKsss{{{222999---oooyyyyyyָTTT\\\cccMMM```}}}```___]]]OOOvvv###fffsss'''FFF{{{ÙmmmwwwiiiFFFZZZmmmxxxddd[[[\\\XXX~~~RRR+++wwwuuuvvvvvvEEEPPPųjjjNNNbbb```nnnddd^^^]]]RRR---DDD~~~wwwsss<<<qqq|||nnn)))TTT\\\iii{{{aaa\\\PPPGGG ooowwwvvvxxxpppkkkyyyuuuuuu```gggsssxxxyyyxxxjjjppp{{{yyy}}}^^^UUUGGGGGGWWW&&&rrrqqqvvvxxxpppppprrruuu{{{xxx|||zzz}}}555[[[WWWnnn^^^TTTCCCJJJ888888yyymmmrrrwwwpppmmmpppppptttuuu|||mmmQQQfffkkkyyy²QQQJJJ666TTTuuu&&&GGGrrrlllqqqpppuuusssuuuvvvyyyyyyrrrxxxyyy띝RRRjjjgggpppBBBUUU777QQQ``` RRRllltttxxxyyyxxxxxxuuuuuu~~~wwwsssVVV```\\\gggسLLLVVV ^^^}}}ZZZ%%%VVVlllxxx}}}{{{vvvuuuzzz~~~uuupppXXXNNNSSS___lllyyyHHHLLLpppzzzZZZ)))VVVfffooo{{{xxxuuuvvvwwwgggooo}}}\\\GGGQQQZZZdddlllpppCCC>>>,,,www{{{WWW###UUUfffeeekkkxxx|||yyyuuusssqqqaaajjjuuu{{{}}}~~~}}}VVVHHHTTTVVV^^^gggsssbbb:::333|||{{{VVVJJJfffbbb^^^dddllliiiggggggaaaaaaeeeqqq|||{{{tttyyyrrrZZZPPPVVVTTT```fffnnnxxxkkkZZZ<<<WWW<<<iiiccc\\\```jjjbbb^^^```___```ffftttxxxrrrzzzlll^^^\\\^^^ZZZaaafffllltttwwwqqq]]]YYYMMM---[[[hhhccc```pppiii^^^fffkkkdddgggooo{{{zzzzzzyyycccUUUYYY]]]]]]bbbeeeqqqvvvsssvvvUUU000QQQDDD&&&LLL```fffaaaooojjjZZZlllssseee^^^gggvvvxxx}}}{{{```RRRWWW```dddggghhhmmmpppoooooo555'''UUU888 !!!999SSS]]]jjjjjjnnn[[[hhhooodddZZZbbbssszzz{{{vvvaaaYYYZZZ___ddddddhhhllljjjmmmoooJJJ???fff|||---""")))PPPSSSfffaaapppcccaaaqqqooofff___kkkvvvzzzrrr]]]ZZZZZZ]]]YYY]]]dddjjjmmmpppsssEEE888rrrsss"""""""""%%%BBBUUUaaacccdddpppZZZjjjtttooo^^^ccclllyyy}}}dddWWWWWWeee___```___ccckkkrrruuu<<<>>>eee""""""$$$777TTTbbbdddfffsss``````oooooo```\\\lllyyyhhhUUUTTTaaagggmmmiiihhhlllpppttt'''999~~~III#########000QQQccceeeiiisssbbbXXXiiinnndddXXXdddtttvvv]]]WWWYYY[[[fffmmmppprrrsssrrrsssQQQ^^^|||***###%%%&&&000PPPaaadddiiippp^^^XXXbbbpppfffYYYdddpppkkkWWWSSS[[[]]]eeejjjpppuuuuuuuuuuuu^^^rrrzzzqqq###))),,,,,,DDDXXX]]]cccpppZZZ^^^eeeooobbbYYYaaaooommmWWWWWWZZZ\\\eeejjjlllmmmlllrrrrrr[[[vvv}}}PPP&&&'''---222...;;;XXX```___ppp```]]]fffpppiiiaaaiiiqqqfffZZZ^^^XXX[[[]]]aaagggooonnnooopppVVV{{{uuu~~~666###...///111222555555MMM______oooaaaZZZhhhppplllfffgggpppjjjRRRSSSPPPSSSQQQZZZfffiiimmmnnnwww[[[|||sss!!!///333555666555555000???QQQ]]]ooofffVVVddduuuuuufffiiillloooUUUMMMNNNQQQYYY\\\aaaggggggmmmuuucccvvvsssbbb!!!444555777888555666000888KKKYYYllliiiVVV]]]qqquuugggjjjnnnhhhSSSNNNPPPTTT[[[[[[dddllllllooovvv^^^hhhpppzzz555***888888888666444333222///AAATTTjjjpppWWWUUUfffiiidddjjjjjj___OOOAAAGGGMMMRRRTTT]]]fffpppgggdddKKK[[[cccjjjpppuuu!!!444888;;;<<<;;;555333222...444LLLhhhxxx]]]TTT\\\]]]```jjjmmm]]]???999BBB???AAAEEEHHHQQQNNNqqq222 $$$!!!"""%%%***111333333111---777QQQrrr^^^MMMRRRXXX[[[dddaaa666***555999333,,,***AAAժ|||iiiJJJ---###,,,000,,,444MMMCCC<<<KKKVVV\\\[[[666(((...---'''######VVVTTTgggGGG((("""%%%###))),,,&&&555PPPQQQ555
diff --git a/PerlMagick/t/reference/read/input_gray_msb_08bit_mat.miff b/PerlMagick/t/reference/read/input_gray_msb_08bit_mat.miff
new file mode 100644
index 0000000..ba32d95
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_msb_08bit_mat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_msb_16bit_fits.miff b/PerlMagick/t/reference/read/input_gray_msb_16bit_fits.miff
new file mode 100644
index 0000000..01b6f7e
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_msb_16bit_fits.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_msb_32bit_fits.miff b/PerlMagick/t/reference/read/input_gray_msb_32bit_fits.miff
new file mode 100644
index 0000000..01ed0cc
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_msb_32bit_fits.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_msb_64bit_fits.miff b/PerlMagick/t/reference/read/input_gray_msb_64bit_fits.miff
new file mode 100644
index 0000000..4791d20
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_msb_64bit_fits.miff
@@ -0,0 +1,14 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=46 rows=71 depth=8
+
+:JJJKKKGGGDDDeeebbb888777KKK]]]rrrwwwxxxtttrrrnnn```JJJYYYcccNNNNNNSSSVVVWWWTTTKKKOOOcccmmmuuutttuuuuuuvvv;;;EEEkkk^^^AAAEEE>>>???FFF???UUUWWWUUUPPPPPPnnnrrraaaKKKaaa}}}rrrTTTeeepppQQQMMMRRRRRRSSSUUUVVVQQQccc~~~}}}333ccc{{{aaaVVVVVVSSSBBB<<<EEENNNNNNQQQRRRMMMFFFWWW```CCCbbbyyyhhhdddfffgggYYYeee\\\OOOPPPSSSTTTUUUVVVUUUWWWWWWQQQYYY~~~rrrHHH@@@kkkkkkYYY]]]]]]]]]444HHHDDDJJJ???AAAAAAEEECCC@@@<<<eeeYYYJJJPPPQQQPPPQQQSSSMMMQQQSSSTTTTTTUUUWWWWWWWWWWWWWWWTTTPPPooo}}}iiiPPP///AAAWWW^^^^^^qqqccckkktttcccGGGDDDSSSAAALLLKKKAAA???FFFHHH]]]MMMVVVXXXXXXVVVQQQQQQRRRRRRTTTSSSSSSUUUVVVVVVVVVVVVUUUTTTTTTNNN]]]hhhBBBJJJ>>>CCCTTTPPPqqqooouuuuuuYYYMMMJJJPPPRRRSSSXXX///XXXWWWRRRSSSUUUTTTRRRPPPPPPOOOOOOSSSSSSSSSSSSQQQTTTWWWXXXWWWTTTTTTYYYVVVNNN:::YYY@@@@@@MMMVVVWWWuuuxxxuuufffIIIMMMRRRSSSXXXZZZ777555fffTTTRRRSSSTTTTTTRRRRRRMMMUUUWWWPPPTTTTTTWWWVVVPPPSSSVVVWWWVVVTTTSSSRRRRRRWWWQQQEEEBBBLLLZZZdddqqq{{{oooiiiLLLPPPMMM|||DDDVVV___RRRRRRRRRTTTSSSRRRQQQPPPrrrdddMMMRRRVVV\\\[[[SSSQQQTTTTTTVVVTTTPPPOOOQQQQQQTTTZZZQQQNNNUUU```oooxxxuuulllllllllOOOQQQuuuWWW///YYYTTTTTTSSSRRRRRROOOTTTRRRcccwwwOOOSSSSSSRRRWWWVVVRRRRRRTTTVVVVVVWWWVVVVVVTTTRRRSSSSSSVVVUUU\\\]]]```^^^aaafffiiikkkHHHVVVyyyFFF ###RRRMMMWWWTTTSSSRRRPPPNNNTTTSSSppp___LLLWWWVVVUUURRRQQQRRRSSSTTTVVVWWWXXXYYYXXXWWWTTTSSSUUUTTTSSSXXXaaaXXX\\\]]]bbbccceeeccc[[[,,,RRRNNN]]]YYYTTTSSSQQQNNNLLLJJJWWWlllNNNRRRVVVWWW\\\VVVRRRSSSVVVTTTTTTTTTWWWYYYWWWWWWUUUTTTTTTUUUWWWUUUZZZ^^^[[[\\\bbbccceeejjj,,,
+
+
+MMMZZZTTT\\\UUUTTTSSSRRROOOMMMHHHddd[[[MMMRRRTTTVVVYYYYYYVVVUUUWWWWWWWWWVVVVVVXXXYYYXXXVVVUUUUUUVVVWWWZZZVVV___ZZZWWW^^^ccchhh !!!fffVVVSSSOOOQQQSSSTTTQQQLLLMMMZZZkkkPPPTTTSSSTTTWWWZZZZZZUUUUUUWWWXXXYYYXXXWWWWWWZZZYYYXXXVVVVVVVVVVVVZZZ\\\XXXZZZVVVZZZdddTTT ]]]WWWSSSPPPPPPPPPSSSRRRQQQMMMPPPdddgggOOOUUUTTTTTTVVVYYYaaaeeeTTTWWWXXXXXXYYYXXXWWWWWWWWWYYYXXXWWWWWWVVVYYY[[[\\\UUUYYYOOO:::(((eee^^^MMMSSSRRRQQQQQQRRRQQQNNNOOOOOOooo___RRRVVVTTTVVVWWW[[[bbbuuu```QQQVVVWWWWWWXXXUUUWWWVVVXXXYYYYYYYYY\\\[[[[[[ZZZVVVZZZ111...EEEhhhLLLNNNSSSRRRQQQPPPRRRQQQPPPPPPTTT}}}gggQQQXXXVVVYYYWWW\\\ZZZ^^^jjjRRRUUUWWWWWWXXXWWWVVVWWW]]]jjj\\\]]]jjjqqq___[[[^^^WWWGGG111+++aaaVVVQQQMMMTTTRRRQQQQQQPPPEEENNNMMMZZZ~~~zzzLLLUUUVVVWWWXXXZZZ]]]WWWbbbaaaQQQWWWWWWYYYYYYWWWXXX^^^ttt```eeewwwWWW\\\)))EEE___KKKSSSJJJQQQQQQMMMIII;;;333>>>BBBTTTqqqmmmXXXKKKTTTXXXWWWYYY^^^eeeZZZeeeQQQSSSVVVYYYZZZWWWXXX]]]```iiiwww]]]\\\@@@VVVWWWEEEQQQVVVKKKMMM```PPPEEEIIICCCDDDJJJhhh```iiiXXXNNNWWWWWWYYY[[[lllbbb[[[SSSQQQUUUWWWYYYWWWXXXeee______]]]\\\[[[PPP\\\VVVAAAMMMdddBBBXXXkkkJJJEEEQQQJJJLLLUUUqqqvvvlllnnn]]]JJJYYYWWW[[[vvvnnnWWWVVVQQQVVVWWWXXXXXXYYYjjjlllnnn^^^ZZZXXXXXXZZZ[[[$$$bbbWWWMMMUUU```MMM^^^TTTDDDLLLTTTWWWWWW]]]bbb___```bbbjjjOOOUUUXXX^^^[[[UUUQQQTTTVVVWWWTTTXXXfffrrriiibbbddd]]]```WWW]]]ooo[[[___(((___RRRXXXUUUVVVZZZSSSNNNMMMQQQVVVZZZbbbhhh___ttt|||lllrrrWWWUUUZZZ```fffQQQOOOQQQTTTVVVTTTVVV\\\]]]```aaaZZZ\\\ZZZTTTccckkkddd(((\\\QQQSSSRRRZZZSSSLLLVVVMMMTTT[[[___llljjjeeeooonnnTTTYYYZZZ```uuuQQQNNNPPPQQQRRRUUUWWWYYY\\\\\\ZZZZZZZZZXXXRRRrrrrrr___$$$YYYQQQMMMMMMUUUOOOFFFYYYQQQTTT\\\hhhxxxjjjcccrrroooeeehhhOOOXXXYYY]]]VVVNNNOOOQQQQQQTTTUUUYYY\\\[[[ZZZYYYVVVYYYRRRdddPPPUUUNNNLLLIIIIIIJJJFFFTTTTTTSSSZZZbbbmmmfff\\\___cccccckkkSSSRRRXXXZZZppp{{{\\\QQQDDDMMMKKKLLLUUUWWWYYY[[[WWWSSSXXXWWWqqqlll\\\???PPPFFFBBBCCC@@@@@@LLLMMMNNNPPPZZZ\\\]]]ccc___aaaeeeccckkkTTTMMMWWWXXXaaadddhhhbbbXXXPPPRRR___\\\JJJQQQRRRSSSVVVXXXVVVeee~~~YYYZZZ%%% >>>???TTTDDD...777RRRKKKNNNOOOWWWZZZZZZfffpppiiibbbbbbjjjPPPJJJWWWVVVZZZ^^^aaaaaaZZZMMMIIIkkk[[[BBBTTTUUUVVVWWWWWWyyydddYYYQQQ444(((MMMSSS:::///BBBRRRLLLOOOPPPTTTXXXZZZgggttthhhcccccciiiJJJIIIUUUUUUYYYYYY\\\```\\\HHH...III~~~rrrBBBVVVWWWWWWYYYccctttqqq[[[VVVTTT```HHHVVV:::333---GGGSSSJJJMMMPPPTTTWWWZZZeeeiiicccfffeeehhhGGGIIIQQQRRRVVVWWW[[[]]]]]]___FFFAAAnnnJJJHHHSSSTTTWWW___aaa[[[YYY]]]CCCVVVQQQAAA333555---LLLWWWNNNMMMNNNSSSVVV]]]fffhhhffffffffffffAAAFFFMMMQQQUUUXXX[[[^^^aaaXXXFFFCCCZZZ^^^;;;OOOPPPRRRTTTSSSSSS___MMM...555CCC666666555...VVV\\\UUUNNNMMMOOOVVV]]]cccgggeeeeeecccddd;;;AAAJJJPPPWWWYYY\\\WWWOOORRRMMMCCCMMMwwwqqq888@@@FFFPPPQQQ\\\[[[HHH444NNNLLL999777777444///YYY^^^UUUUUUSSSRRRVVV]]]bbbdddeeefffdddccc555<<<BBBEEEGGGHHHCCC:::IIIMMMZZZLLLGGGnnn{{{CCC///EEE>>>DDDXXX]]]TTT(((FFFSSSRRR999777888222777\\\\\\VVVUUUTTTUUUYYY```bbbddddddeeegggZZZ ))))))+++444>>>666GGGRRROOOZZZPPP???aaa}}}\\\...@@@555DDDNNNTTT]]]]]]FFFMMMTTT888666555000BBBbbb[[[UUUUUUTTTXXX]]]bbbdddeeedddggghhhRRR%%%***111===JJJJJJ;;;RRRMMMJJJiiiYYY===QQQxxxuuu444EEE444@@@GGGVVVdddfff\\\PPPWWW999999777...HHH```XXXTTTVVVWWWZZZ^^^ccceeeffffffgggiiiMMM111===GGGJJJLLLQQQ@@@777...000MMMFFFCCCKKKttt~~~YYYEEE;;;===JJJYYYUUUNNNSSSLLLQQQ===>>><<<000HHH___YYYVVVVVVZZZ\\\```ccceeegggfffhhheee---///HHHMMM[[[WWWVVVfffTTT$$$FFFLLLLLLooosss444QQQ:::QQQ>>>000<<<OOONNNNNN<<<;;;:::222JJJ\\\WWWVVVWWW[[[]]]```cccfffffffffmmmSSS@@@HHHSSSZZZ^^^fffnnn^^^WWW,,,PPPMMMQQQmmmzzz```DDDJJJBBB,,,888DDDKKKRRRYYY???999999777OOOYYYVVVWWWXXX[[[^^^bbbeeeffffffeeennn333JJJIIIJJJJJJTTT___\\\+++WWWUUU222SSSSSSSSSfff{{{ppp___QQQ___BBB111===<<<EEEQQQXXX???;;;:::333OOO\\\XXXYYYZZZ\\\aaaeeeccceeeffffffhhh***TTTOOOJJJHHHPPPUUUeee^^^%%%GGGNNNSSSPPP```lllttt___EEEbbbSSS555:::BBBMMMTTT]]]<<<999222,,,QQQ]]]WWWYYYZZZ]]]ccceeebbbfffeeehhhTTTEEEWWWSSSJJJJJJKKKFFFCCCLLLTTTPPPIIIIIIYYYWWW<<<@@@HHHKKKLLLKKKBBBFFFMMMLLLNNNSSSbbb;;;555,,,,,,UUU^^^XXXXXXZZZ^^^cccdddcccfffbbbbbb666VVVYYYGGGGGGJJJKKKFFFFFFGGGIIIMMMKKKNNNLLLXXXNNN!!!999666EEERRRSSSSSSRRRSSSQQQSSSccc;;;555***...WWW[[[UUUWWWZZZ^^^dddbbbbbbeee```YYY######QQQLLLDDDGGGJJJFFFDDDFFFFFFIIIIIIPPPNNNUUUggglllDDD222@@@CCCLLLTTT^^^kkksssyyyooobbb222..."""444XXXYYYUUUWWW[[[___cccccceeebbbYYYIII,,,GGGDDDGGGFFFIIIHHHIIIJJJLLLLLLGGGKKKLLLbbbbbb333CCC@@@FFFWWWfffiii)))555"""333WWWYYYVVVYYY[[[___bbbdddfff^^^SSS<<<333CCCIIIKKKLLLKKKKKKIIIIIIOOOOOOJJJHHHWWWttt|||666<<<999@@@PPPccc{{{ppp___///666;;;UUUVVVVVVZZZ\\\___aaa^^^]]]YYYNNN888555CCCKKKNNNRRRMMMJJJIIILLLNNNIIIFFFPPPcccqqqsssxxx777111444;;;DDDLLLZZZhhhggg]]]\\\---///FFFTTTXXXWWW[[[]]]______\\\]]]UUULLL888555@@@EEEMMMRRRPPPKKKIIIJJJJJJAAAEEENNNTTTWWW[[[cccaaa999,,,333888>>>CCCFFFPPPZZZ^^^ZZZ***'''JJJXXXZZZXXX\\\]]]___^^^ZZZZZZQQQMMM777555@@@???CCCKKKMMMKKKIIIHHHGGG===BBBIIIMMMNNNOOOQQQNNN555---555555;;;@@@HHHPPPWWWYYYVVV===$$$ NNNYYYZZZYYY[[[\\\___]]]YYYZZZPPPMMM666...@@@===;;;>>>DDDBBBAAAAAA======???GGGNNNMMMIIILLLGGG888222666555<<<@@@EEEKKKOOOTTTTTTCCC888&&&SSSVVVWWWYYY\\\]]]^^^ZZZ\\\ZZZQQQPPP666%%%AAA>>>:::<<<BBB===;;;<<<;;;<<<@@@IIIOOOKKKGGGLLLCCC;;;:::;;;888===@@@DDDIIIJJJPPPOOOGGG:::888OOOWWWYYYYYY\\\]]]]]]WWWXXXXXXPPPOOO000999AAA>>><<<FFFAAA;;;@@@CCC???@@@FFFMMMLLLLLLLLL>>>555777::::::===???GGGJJJHHHJJJLLL555333RRRWWWZZZZZZ]]]___]]]VVVVVVVVVPPPPPP+++///<<<@@@===EEEBBB888CCCHHH???;;;@@@JJJKKKNNNMMM<<<333666<<<>>>AAAAAADDDFFFFFFFFFJJJ!!!555TTTWWWYYYZZZ]]]^^^^^^VVVXXXXXXQQQPPP######444:::BBBBBBEEE999AAAFFF???888===HHHLLLMMMJJJ===777888;;;>>>???AAACCCBBBDDDEEEJJJ...(((@@@RRRVVVYYY\\\^^^^^^]]]TTTZZZ\\\SSSNNN222444@@@===FFF>>>===GGGEEE@@@;;;CCCJJJLLLGGG:::888888:::888:::>>>BBBDDDFFFHHHOOO+++###GGGPPPVVVYYY[[[^^^___ZZZWWW^^^[[[VVVHHH)))555===>>>???FFF888CCCHHHEEE;;;>>>DDDLLLNNN???777777???;;;<<<;;;>>>CCCGGGIIIOOO%%%&&&RRROOOTTTWWW]]]^^^cccfffaaaeeeZZZZZZ???"""555===>>>@@@HHH<<<<<<FFFEEE<<<:::CCCLLLPPPAAA555555===@@@DDDBBBAAACCCFFFIIIOOO###XXXOOOUUUXXX\\\]]]^^^ZZZ[[[```[[[]]]...333>>>???BBBHHH===777AAAEEE>>>777???IIIJJJ:::777888999@@@DDDFFFGGGHHHGGGHHHPPP333;;;ZZZNNNUUUWWWZZZ]]]___YYYZZZ___]]]XXX222===???AAAFFF;;;777===FFF@@@888>>>FFFCCC666444999:::???CCCFFFIIIIIIIIIIIIQQQ;;;GGGUUULLLUUUVVV[[[^^^]]]ZZZ^^^```aaaGGG+++777:::>>>FFF888;;;???EEE===888===FFFDDD777777888:::???CCCDDDDDDDDDGGGGGGMMM999JJJNNNOOOSSSWWW]]]___]]][[[``````eee222%%%777<<<;;;FFF<<<:::@@@FFFAAA===AAAGGG@@@888;;;777999:::===AAAEEEEEEEEEFFFQQQ666MMMIIINNNQQQXXX^^^___\\\___bbbaaabbb"""!!!!!!000;;;;;;EEE===888AAAFFFDDD@@@AAAFFFBBB333444222444333888@@@BBBDDDEEEJJJQQQ999MMMHHHSSSSSSXXX^^^aaa\\\aaabbbeeeUUU !!!"""!!!!!!(((222:::EEE@@@555???IIIIII@@@AAADDDEEE555000111222888:::===@@@AAADDDIIILLL>>>JJJHHHQQQRRRYYY]]]aaa]]]``````kkk=== !!!"""###!!!"""###///888DDDBBB666:::GGGIIIAAACCCEEEAAA444111222555999999???CCCDDDEEEJJJMMM;;;AAAFFFLLLOOOXXX___aaa___cccdddeee!!!#########""" )))444BBBFFF777555@@@BBB>>>BBBBBB;;;111))),,,000444444:::@@@FFF@@@???///999>>>CCCFFFSSS\\\\\\___bbbiiiIII ###%%%%%%%%%!!!  ///AAAKKK:::555::::::<<<BBBDDD:::(((###)))'''(((+++---333111GGGPPP>>>```cccbbbbbb]]]\\\^^^YYYZZZ]]][[[ """222GGG;;;000444777999>>>==="""!!!### (((tttjjjjjjkkkkkkkkkkkkkkkjjjiiiiii```TTTWWWSSSNNNAAA... 000***%%%///666:::999"""666555***iiiiiiiiiiiikkkhhhiiiiiijjjiiijjjnnnnnnppprrrtttqqqhhhTTTAAA,,,!!!222333!!! 
+
+
+
+
+
+$$$CCCSSSiiiiiiiiihhhlllsssmmmlllpppzzz@@@%%%333999999AAAEEEHHHPPPPPPNNNLLLHHHDDD<<<444222999KKKMMMHHHMMMjjjjjjjjjlllttttttuuu{{{ttttttzzz~~~eeeNNNFFF222777BBBLLLOOOMMMMMMNNNOOOQQQOOONNNPPPVVV```ggguuu[[[GGGccccccbbbhhhooorrrllliiinnnllleee\\\[[[___bbbhhhpppsssuuutttoookkkkkkkkkooottttttgggSSS:::>>>JJJKKKJJJIIIHHHEEECCCDDDIIIOOO[[[bbbYYYbbbBBB \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_gray_msb_double_fits.miff b/PerlMagick/t/reference/read/input_gray_msb_double_fits.miff
new file mode 100644
index 0000000..f4bb433
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_msb_double_fits.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_msb_float_fits.miff b/PerlMagick/t/reference/read/input_gray_msb_float_fits.miff
new file mode 100644
index 0000000..1fdd586
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_msb_float_fits.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_gray_rla.miff b/PerlMagick/t/reference/read/input_gray_rla.miff
new file mode 100644
index 0000000..0d76e93
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_rla.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=True
+columns=70 rows=46 depth=8
+comment={A Wavefront file converted from an rle file.}
+
+:///000333444444444222333222222111///...//////......111444666:::@@@CCCCCCDDDEEEQQQ[[[bbbjjjsssvvvuuussslllaaa___^^^\\\XXXVVVTTTTTTUUUWWWYYYaaafff\\\@@@666333333222000//////...///???ZZZuuuuuuOOOPPPwwwzzzWWW...///111222333222111333333333000///...111000000000111333555999>>>@@@???AAAEEENNNUUUZZZhhhrrruuuvvvtttkkk______^^^[[[WWWUUUTTTTTTRRRUUUXXXcccjjj]]]:::666555333333111///000111---888PPPkkkqqqGGGFFF___mmmWWW,,,,,,//////---...---...---......------//////000111111222555444777888:::>>>CCCGGGIIIMMM^^^kkkrrrtttrrrccc\\\]]][[[XXXTTTTTTSSSRRRQQQSSS[[[fffllleee===666444333333111111111111000///555VVVyyyHHH999777DDDOOOXXX------------++++++++++++,,,,,,,,,,,,...---...---//////...111333666666888<<<@@@AAABBBJJJTTT]]]gggrrrsss^^^YYYYYYXXXUUUSSSQQQQQQPPPPPPVVV___ggg}}}___AAA444000////////////111111...---dddsss]]]kkkaaa............++++++***'''***++++++)))))),,,---------+++,,,...333666555444666:::<<<<<<EEERRRWWWYYYccchhhZZZVVVUUUTTTSSSPPPNNNMMMMMMQQQYYY]]]ooo{{{VVV===000***......---...///---+++jjj^^^//////000111111000...++++++***)))))))))***------,,,,,,...111555666444222333555777444666GGGSSSVVVSSSZZZVVVUUURRRSSSRRRNNNLLLJJJMMMXXX\\\eeennnWWW:::*********+++,,,---,,,'''^^^UUU222333333666666444222///111...+++,,,,,,...000000000000333888::::::666333444777666333111999FFFOOOOOOQQQTTTUUUQQQPPPOOOLLLIIIIIIPPPZZZ^^^mmmyyy]]]999''''''***+++***(((%%%XXX~~~QQQ777777888:::===<<<;;;888888666333222222333333444777999;;;???@@@???:::888888999999888666888BBBSSSYYYVVVRRRRRRMMMLLLMMMHHHooosssSSSXXXcccxxx}}}aaa:::+++(((---,,,111NNNkkkvvvyyySSS888999===???@@@BBBAAAAAAAAA>>>===<<<<<<888666555888<<<???CCCDDD@@@<<<;;;;;;;;;[[[```VVVggg```\\\```___^^^___^^^QQQLLLeeetttuuu]]]ccctttlllmmmzzzttt___888555@@@\\\{{{{{{{{{rrrYYY666777<<<@@@BBBDDDDDDEEEDDD???>>>>>>===:::888777999===AAACCCBBB???<<<<<<:::TTT}}}aaaUUUeee\\\```eeeXXXaaaiiipppmmmnnnmmmaaahhhoookkktttqqq{{{ooonnnrrruuuzzz{{{|||GGGBBBwwwsss___333555777<<<BBBFFFHHHHHHEEEJJJBBB<<<;;;999999888:::===BBBCCC@@@===:::999===dddXXXSSS\\\YYYTTT\\\___```eeecccgggiiijjjgggcccbbbuuu~~~{{{ooo\\\jjjtttxxx{{{zzz||||||ttt{{{000...333888>>>DDDJJJIIIWWW~~~YYYCCC555222222888===AAACCC;;;555222666PPP\\\YYYWWW```eee___ZZZ\\\eee]]]dddhhhjjjhhhbbbcccfffiiippppppfffZZZ]]]ooozzzzzz~~~~~~{{{jjj888333000444:::BBBLLLJJJdddqqqLLLAAA:::<<<@@@===CCCRRROOONNN\\\[[[___\\\^^^fffgggdddgggiiinnnggghhhiiihhhcccbbbbbbooo}}}bbb\\\^^^gggqqqrrrxxx~~~uuu@@@===666222666???IIIIIIZZZgggRRR:::999MMM}}}|||qqq]]]XXX\\\aaahhhlllgggooonnnhhhrrrttthhhiiifff___dddeeeeeeyyymmm]]]___fffwwwjjjyyy~~~tttIIIGGGAAA:::777>>>FFFFFFPPP~~~hhh```uuuuuuhhhppphhhbbbfffjjjhhhdddgggiiicccaaabbbkkktttllldddhhhllliiikkk{{{ssshhh```aaafffaaammmttt|||PPPOOONNNIIICCC>>>@@@FFFHHHQQQqqqrrrmmmhhhnnnrrrkkkiiikkk\\\^^^fffjjjhhhaaa^^^```aaadddjjjjjjggghhhfff```uuutttxxxbbb```___^^^^^^cccIIIRRRQQQOOOKKKIIIHHHJJJLLLSSSrrrpppqqqpppeeerrrqqqllldddddd___eeekkkfffhhhddd___dddooobbb___```dddcccaaaeeelllrrrsssbbb^^^]]]\\\[[[yyycccPPPPPPPPPNNNNNNMMMNNNNNNNNNccc|||qqq```lllqqquuuwwwqqqbbbiiiccchhh```^^^```eeehhhllllllkkkjjjjjjggg```cccmmmooolll]]]```jjjeeecccaaarrraaaWWWYYYVVVjjj}}}OOOOOOOOOLLLNNNOOOPPPRRRPPPPPPXXXnnndddeeeqqqvvvuuucccXXXiiikkklll\\\bbbaaadddnnngggeeeffffff___fffrrrjjjooogggjjjwwwgggkkkddd``````yyyeeedddfff___\\\zzzwww~~~ppp{{{NNNNNNMMMLLLNNNNNNOOOQQQQQQQQQQQQ^^^}}}sssrrrmmmvvvppp]]]VVViiinnnzzzvvv^^^aaaiiiiiilllllliiijjjoooqqqbbb\\\jjj}}}oooccc^^^YYYYYYpppiiilllllllll\\\wwwZZZrrrNNNNNNNNNOOOOOOOOOPPPRRRRRRQQQNNNbbbwwwqqqlllfffZZZ```eeeeeegggzzzkkkfffmmmnnneeedddbbbcccvvveeeTTTFFF[[[aaasssdddaaa\\\```uuuggglllkkkjjj___ppp|||nnnPPPPPPPPPPPPPPPPPPOOOPPPOOO[[[fffhhh{{{qqqiiigggYYYiiihhhaaaggghhhqqqjjjjjj}}}yyyeeebbbfffooonnnhhh```vvvwwwoooqqqmmmlllmmmqqqpppccckkkkkkjjj```iii{{{]]]XXXxxxRRRRRRRRRRRRRRRRRROOO]]]|||ooozzzlllggg]]]jjjeeecccfffmmmiiigggmmm{{{mmmoooggg~~~~~~eeeoooqqqggglllssskkkeeejjjllljjjccc^^^|||{{{CCCVVVqqqOOOSSSTTTTTTTTTQQQ]]]{{{ppplllggg```nnn{{{___qqqoooccceeedddeeekkkggg|||iiijjjiiiffflllnnnkkkeeehhhjjjlllkkkhhh^^^{{{ppp:::DDDsss}}}vvv[[[UUUJJJNNNTTTXXXUUU```~~~lll|||kkkwwwxxxlllccchhhgggvvvvvviiiiiiccc^^^fffhhhiiiyyyssslllooolllkkkkkkkkkkkkmmmkkkfffhhhiiimmmjjjeeennnzzz}}}\\\NNNAAAVVVwwwyyy||||||ssslllcccfffAAAEEEPPPTTT```yyywwwfffrrrlllXXX^^^tttaaa\\\dddgggccciiihhhccceeeeee```yyyrrraaaggghhhiiieeegggjjjkkkllllllkkkhhhfffhhhiiilllkkkcccyyymmm444@@@555SSSnnnqqqxxx~~~zzzuuurrrqqqppp555999FFFMMMfffoooWWWeeegggZZZ\\\xxxccc___ccceeeeeeaaagggaaabbbcccdddiiicccaaalllllljjjhhhiiinnniiikkkkkkmmmiiieeefffeeeffffffjjjxxxEEE***000VVVppp|||zzzttttttwww---...777CCC]]]aaabbb|||___]]]]]]ppptttaaacccfffaaaddd```rrrdddcccaaabbbiiiiiinnnnnnhhhjjjooooooiiihhhlllnnnpppjjjdddddddddbbbaaazzzxxxbbb555///GGGpppwwwxxxwwwwww~~~///,,,000;;;NNNYYYrrr}}}ddd[[[]]]^^^eee~~~qqqcccfffdddggg```aaacccppp```aaabbbaaacccnnnpppiiixxxsssjjjiiikkkmmmnnnmmmkkk___``````ZZZZZZzzzrrrBBB000999WWWnnnxxxuuu|||}}}zzz===<<<;;;AAAKKKRRRdddzzztttccc]]]^^^```gggdddeeeeeegggeeedddggg___[[[jjjwww[[[^^^bbbiiimmmnnnmmm|||llliiijjjkkklllooommmnnnkkk^^^YYYXXXQQQlllvvvfff555HHHNNNAAApppwww{{{NNNNNNOOOPPPSSSWWWZZZgggpppiiiYYYUUUVVV[[[aaacccggglll[[[```iiihhheeeeeeggg___UUUaaaiiipppmmmkkkooommmmmmddd]]]```iiimmmllllllllllllmmmoooiiiZZZUUUOOOLLL|||sssmmmiiijjjUUU;;;222???qqq~~~[[[\\\\\\\\\\\\_________^^^]]]ZZZMMMGGGOOOXXX]]]pppsssccc___dddhhheeeeeegggaaaPPP\\\___eeekkklllmmmmmmfffYYYXXX]]]kkkooonnnmmmnnnnnnmmmhhhXXXSSSQQQKKKMMMjjjfffjjjxxxZZZ,,,666666888>>>tttwww```aaaaaaaaa```ccccccaaabbbaaaaaaZZZHHHBBBDDDGGGMMMssswwwccc___dddeeeeeeeee```NNNQQQ^^^jjjuuujjj]]]___WWWXXX[[[YYY[[[hhhqqqqqqqqqiii\\\SSSOOOOOOMMMEEEUUUeeeiiikkkfffFFF---<<<KKK999888;;;tttxxxuuuaaaaaaaaabbbbbbbbbcccccccccccccccbbbUUUDDD???===???jjj|||fffbbbfffhhhiiijjj___dddsssyyynnnYYYYYYTTTOOOOOOQQQSSSSSSXXX___ddd___UUUPPPPPPMMMLLLIIIGGG]]]```gggkkkwwwlllNNNdddLLL888777===uuu{{{wwwvvvaaaaaa```dddcccdddddddddddddddddddddaaaPPP@@@;;;[[[eeewwwyyymmmooorrruuuvvvxxxxxxuuusssjjjYYYUUUQQQNNNNNNNNNLLLLLLLLLNNNQQQRRRPPPOOOLLLGGGIIIEEEMMM___bbbfffiiiUUUZZZjjjLLL;;;:::777;;;kkkqqq{{{sssaaabbbcccbbbbbbcccccccccdddddddddddd```aaaXXX===VVV___bbbqqqrrrnnnjjjlllqqqppprrrsssqqqqqqjjjVVVOOOOOOOOOPPPNNNMMMLLLLLLLLLKKKLLLLLLKKKIIIGGGEEEBBBOOOccceeeggghhhdddaaaUUU===777;;;888777[[[oootttzzzoooaaabbbdddbbbbbbcccccccccddddddccc\\\pppzzz:::777;;;;;;IIIcccnnnlllqqqrrrrrrrrrpppoooppp^^^PPPOOONNNOOONNNMMMMMMMMMLLLJJJJJJJJJJJJGGGDDDCCC???LLLfffiiiggg[[[LLL999@@@EEE===777777666PPPrrrmmmssstttkkkbbbbbbdddbbbbbbccccccddddddccc^^^EEE:::777...GGG{{{jjjqqqqqqpppnnnmmmooofffRRROOOOOONNNLLLLLLMMMMMMKKKIIIFFFGGGFFFFFFDDDBBB<<<HHHhhhcccMMM;;;222333111:::DDD888000333FFFeeelllqqqqqqhhhccccccccccccccccccdddeeeeeecccjjjJJJ777JJJdddiiillllllmmmnnnhhhTTTPPPNNNMMMLLLLLLNNNNNNJJJFFFEEEEEEEEEFFFDDD>>>777JJJ]]]AAA444777888777555444>>>AAA333+++DDDttt```eeekkkrrr^^^ccccccccccccccccccdddeeeeeebbbdddmmmFFFiii\\\jjjkkknnnbbbTTTPPPNNNMMMLLLLLLLLLJJJFFFEEEDDDDDDDDDEEEEEECCCGGGUUU777222555444444444555333444===???///HHHZZZ\\\[[[gggrrrMMMddddddddddddddddddeeefffdddlllooouuuZZZffflllaaaUUUQQQOOOMMMJJJIIIHHHEEEEEEEEECCCDDDEEEFFFIIINNNtttjjj...444444333222111111222000222:::;;;GGGQQQLLL[[[UUUffflll>>>ddddddddddddddddddeeefffeee______```VVVRRROOONNNMMMLLLIIIGGGGGGEEEEEEFFFIIINNNOOOPPP|||TTT...444444333111000111000...000000333888888===NNNSSShhhddd333dddddddddeeeeeeeeeeeehhhfffrrr~~~YYYPPPLLLMMMLLLNNNOOOMMMKKKIIIHHHGGGFFF???OOOVVVZZZqqq999555555666555222111111///---...000000222<<<>>>999DDDbbbXXX111cccdddeeeeeeeeeeeeeeehhhgggrrrTTTBBBAAAGGGKKKJJJIIIJJJJJJJJJ]]]CCC===DDDmmm\\\555::::::;;;;;;:::999999555111///,,,,,,///111AAADDD888JJJKKK555bbbccceeeeeeeeeeeefffhhhfffpppWWWGGGNNNNNNOOOLLLLLLaaaEEE@@@FFFdddYYYDDD<<<<<<;;;<<<===???<<<>>>;;;999444///...,,,///AAACCCAAADDD666aaaccchhhffffffgggffffffhhhfffJJJMMMMMMLLLKKKJJJHHHMMM^^^```SSSRRRPPPHHHAAA======>>>======>>>???AAAAAA===:::===TTTVVVEEEJJJSSS<<< \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_gray_rle.miff b/PerlMagick/t/reference/read/input_gray_rle.miff
new file mode 100644
index 0000000..030271e
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_gray_rle.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_hrz.miff b/PerlMagick/t/reference/read/input_hrz.miff
new file mode 100644
index 0000000..5a53d0d
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_hrz.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=256 rows=240 depth=8
+
+:llppppppptptxxx||||||||||xx|ttxxx|x||x|x||tx|x||||||txtptxppxpt|pp|pppppl|pt|t|xt|x|xx|||xxxtxxxx|xx||xxx|xt|xtxttttpttpttpttpttttxtxxtxxttxttxpxtp|tp|tt|ppxppxppxtpxtpxpptlptlltlpxpp|tttttp|ppxpptpptppphdhl`htlp|tx||||||t|xt||x|xx|||xx|xt|xt|xt||x|x||xxxx|x||xxlpXXttt|x||Ĵܼlpppptppttttxtxxx||||||||||||||xx|||||x||x||||||txxppxpp|tt|pp|plpptptxxpxxt||x||x||x||||||xx|ttxttxttxxt|xt|xtxxtxttxtpttpttpttptttxxtx|xx|xx|xxxt|xp|tt|tt|tt|ppxppxtpxtpxpp|plxplxpl|pptttt|tt|ttxtpxpptpltldlh\dthptlpxx|xx|xx||x|t|xtxxt||x||xxt|xx|xt|xt|xt|tt||x|x||||||||ptX\tppx||ļlptptxptxptxttxttxtxxxxx||||||||||||||||||||tx|ppxllttttplppttt|tltxt|xxxxtt|x||x|||||xxtx|ttxttxxx|xx|xx|xtxttxtpxtpttpttptttxxpxxtx|xx|xx|t|xt|tttttttp|pp|pp|tl|pp|pl|pl|pl|pp|tp|tpxttxttxttxpptlltlhlpdhx|tx|xt|xt|xt|xt||x||t|xtxxtx|t||xxt|ttxttxxtxtpxtp|xxxx|||||||||||x\`tpl|||̼hlthptlpxppxtt|tt|txxtxxtxttxxxx||||||||||tx|ppxhhtpppplttpx|lttlttpxxtxxtt|x|xxxx||||||||xtx|ttxttxttxxx|xx|xtxtt|tpxtpxtpxtpxtt|xtxxtxxttxttxtxxt|tttttttppp|pl|tl|tl|tlxtpxtpxtpttpttptttttpxttxppxplxlhpthp||||||||tpxtt|xt|tpxtt|xt||x||x||t|xt|xpxxtxxt|ttxtpxtpxtpxtp|xx|x||xxxx|||x|x|||\`lhh||||||иlltlltlltpptptxttxtxxtt|px|pt|xx|||||||x|xxttxhlpppptptt|ppxlltlpxppxppxtpxt|xtxxxx||||||xxxx|xxxttxptxptxppxtpxppxtpxpptppxppxppxxpx|t|xt|tpxttxttxtt|tptptppppl|tptp|tp|tpxtpttppplpppppptppxpl|plll|plxttx||xpxtpttptllpplttpttptxpxxt|xt|xxxt|ppxpptttxxx|xtxtttppttptttxxt||t||t|x|t||t|x|xxt|xx|||hd|ddxxxx|xxhhtlltlltllplptpptttxptxpt|pt|xx||||||x||ttxppxtxxtt|tpxlltlltlttlpxttxtpttxttxxt|xx|x||||||x|x|xxxtxxttxpptplttptpptpptpltpltpltppttptxtxtpxtpxttxtt|tt|tppp|pp|pp|pl|pl|tp|tp|tpxtpttppplpplppptppxplxpp|llxxt||xxpxthptlpplpppttptplptlttpttpxxtxxt|xt|xt|tpxplttpx|x|xtxtpxtptppttpxtpxxt|txxxx|x|t|x|xxlh`\ttt|xx|t|x|ļhhthhpllpllpllppptpttttxtx|txxx|||||||txtltxptxx||tpptplxlptlptltphpxpttppttttttxtx|x||x|||||||||x|x|xtxxttttttttpptplpplpplpplpllpplpplptpttpttpxtpxtpxtpxttxtt|tp|pp|pp|tp|pp|pp|tl|tl|tlxtptplppllplppptppxtp|pp||xxt|tpxplpphpphplhpplptptplpplttpttpxxtxxtx|t|xt|xpxtlttptxt|xtxtpxtltplptlttptxp||txx|t|t|t|t|t|xt|tl\Xpxt||||x|x|t|x|x|ļhhthhphlphhphhlllppptptxpx|tx|x|||||x||pxxht|pxx|x|phhphhthpxltxlxthttlptpppphpllpppttxxx|xxt|x|||x||xt|xtx|tt|ttxttppppppplpphlpllplplhlphlplltlpxpxtpxtptpptpptppxttxppxppxppxppxppxplxtl|tl|tlxtltplppllplppltppxtp|xx|||pppllpldlphpphplhpllpplttlttlttpttpxxpxxpx|p|xpxxpxxpxxpxxpxxp|xpxtltphptlptlpxpxxx|x|t||t||ttx||x||t\Xpxp||||xxxt||t|x|Ĵdlpdlphlpdhphlpllphlplptpt|tt||xx|xxt|tpxpltt|xxxllthlphpphptlpthlthlthhplhpllplltppxpt|tx|x|x||||||t|pxpt|ptxttxttxptxptxpttlplhhlhlplllhhlhhlhhplltlptpttptpptppxppxtpxtt|tp|ppxtp|pl|pl|lltplxplxpptpltplptlxplxxx||xtxthlthhphlphlphlphlphlplptpttpttpttlptlptlptptxp|xpxpxp|xpxtpttpxtltpltphpplptltxpt|tx|x||t||t|t|tx||d`ppl|x|txt||txxļ̰dlpdlphhphhlhhpllphlphptlpxppx|tx||||xttxpp|tp|x|||ppthhphhlhlphltllthlthlthhplhpllpllplltlpxptxt||x||||||x|t||pt|pt|ppxppxptxptxpttppplplhhlhhhddlhhlhhlhhpllpllxtpttppppppppptppxtt|tt|tp|tp|pl|pl|plxtp|plxplxpltplttpx|x|||x|tppphlphlphlphllhllhlphlplpplptpttptplpplpplpplttlxtlxtl|tl|tpxtlttpttltplpplpplptlpxpt|tx|x||t||txxxx|x|hdthdx|||||xxt|xpxl|p|ĸԼdhlhhlhhlhhllhpllpllphptlpxppxxt|x||||xxxt|ppxllttxxttxllthhphhhhllhllhhlhhphhphhlhhlhhpllpllplptptxtx|x||||||||||x|x|xtxxptxlp|lpxlp|ptxpttppplpllllhlhdhhddhdhhddhddlhhplhtpltppppllllllpppttt|xt|tt|tp|tp|pl|pl|tp|pl|plxplttpxxx||tptphpphpphpphlphllhllhlphlplptlptlpxtxtptplpplpplpplptlttlxtl|xp|xp|xpxxpttpptlptlpplptlptppxtt|x|xxx|||xxtx|xlhx\Xl|x|x|x|||xt|tp|tp|pxĸhhlhhlhhlhhllhpplpllplptpt|tt|xt||t||||xx|tpxpl|ppxxxtxllthhphhlhhhhlhhlhddhddlddlddlhdlhhlhhlhhphlplptpxxtxxxxxxtxtt|x|||t||t|ttxtpt|ptlp|hpxlptlptlppllllllllhdhhddhdhhddhddlhhphllhllhpllphhplltppttp|xtxttp|tp|pl|tppl|tptp|plxxtxx|pptpltthpthpplplhplhllhllhlphlplptptxtxxtxtptplpplpplppllplpxp||t|t|t|txttxpttpptlppllplltlpxtt|x|xxxxx|x|t||xxtXPdxt|x|x||xx|ttxt|t|xdhlhhphhphhlhhplltpptpptttxttxttxxt|||||x|x|xt|xtxppxpltt|||ptthpphpphllhlhdlhdlhdhddhhdhhhlhhlhhlhhllhlllpllpppttptxptxtxxtx|x||||ttxxtxxtxxptxltxhtxlltllthhtlhplhlhdlddhdhhdhh`hd`hh`hh`lldpldlldlldllhplhtlhxtp|xt|x|xxxtpxppxpp|ttxtxp|xxlxthtphtphtphtphplhllhllhpldtphtthtxpxxpt|txtlptlptltthpxlttlpxptt|t|xt|x||t|xpxtlttlttlttltxpt|txxxxxtx|x|||TPhtp|t|t||||txxpxxpx|t||xĸhhlhhphlphhphlplltpptpptttxttxxxxxxxxx||xt|xtxttxtpxplxppxt||tlpphpphplhllhhhhlhhld`d``dd`dd`hhdlhhllhllhllhpplpplpplpplptptxtxxptxpttttxxxxpttpttlpthpxlltlltlhtlhphhlhhlddhddhdhh`hh`hh`hh`hh`hh`hldhldhldlldpldtpl|xp|xxxt|tt|tp|xx|x|tphttlpthpphpphtlhplhlhhhlhllhlldpldpthtxltxpp|txxpttlptlttltxpttlpxptt|xxxx|t|xpxtpttlttlttlttptxt||t|txxx|t|x||xx|xXTllhx|xt||||||xxxtxxpxxpxxt||Ĵܼhhlhhlhhlhlpllplltpptpptttxxxxxxxxxxxxtxtpxtpxtp|ttxplxx|xxtthlphpldlldhhhhhhhhdh``d`\d`\h``hhdhhdhldllhllhlphpphpplpplptlptlptlptptxtt|xxxpttpptlltllthlthlthltllphllhhlddhddhddhddhddh`hd`dh`hhddlddlddldhldlldpphxtp||t||t|tp||xx|t|phlphlphlphlphplhphhlhhhhhhhhhldlldlphptltxptxpp|tt|pttlpthpxltxlttlp|pxt|xxxx|x||t|xpxtpttltxptxtx|t|txp|txx|t|x||xx|x`\tddp|x|txxx|xxxxptxptxpxxtxxt||ĸԼȴhhphhlhhpllplltlltlltpptttxxxx||x||txxpttptpltpltpl|tpxx|xxlltlpphpldlldhhddhdddddddhd`hd`hd`lh`hh`hldlldlpdlphpphpphlplpplpplpplptptxpptpptpltplpllpllphlphltlptlpphllhlldhhd`hddhddhdhh`dd`d``dd``hd`hddl`hl`ll`ppdttl|xp|xx|txpx|ttltphlthhphhplllhllhphhldhdhhdhhdldhldlphlphlxpp|tt|tt|txxltthptlttltxpt|tx|t|xxxx|t|xpxxpxtpttltxptxtx|t|t|t|txx|t||||hdxTT`tt|xtxtttt|pptlptlptlttptxt||||Ըĸdlxdhthlthlpllllllplpplpttttxxx|xxxxxtptttxpt|pp|lp|tpxt|plxppplllhlldlldhhdhhdhd`dd`dd`dd`dd`dd`dh`dldhlddlhdplhplhplhphhpllplltlptlltlpphpthpphlthltlhthlthlthlphlldhhdhhhlddhd``hddh``d`\d`\d``d`dddhd`hddhhhllhpphttl|xp|xxt|x|t|xlpthpplpllllllllllhlhhlhhhhdhhdhldhldhlhllhllhlpppttxxtxxtxtptxltxltxltxpx|px|t|t|t||pxxt|xtxxtxxpxxpxtpxtpttpxxpx|t||t||t|x|xx|xx|xx||xx|TT`tp||lxlt|pttltphpphtphttlxxtxt||дhlxhlthlthlpppppppppppptttttxttxtxxxxtptpttpptlpxlpttxx|plxphtpltplpllldlldhh`dhddd`dd\`d`dd`dd`dd\`h`dhddlddlhdphdphhphhlhhphhphlplpthlthpthpthptdltdlthhphhphhphlphlldhh`hddhd`dhddh`dh``d`\d``d``d`dhdhhdhddhhdlldllhtplxtl|xp||x||txthlthlphllhlllllllhdhhdhhdhhdhlhllhlldhldhlhllhlhhlllltptxpxxpxtptxltxltxltxltxltxpx|t||t|xpxtpxtptxtxxt|xtxxpxtlttpxxpxxpxxpxxpx|t||tx|xx|x|x|xxxTTdlhtxpx|lt|pttltpltphpphtpltxt|xt|xxx|||ȼhpxhlxhlthlppppptpppppptpttpttxxxxxxxttxptxttxppxpptt|ppthhphdlhdllhllplhpldhhddd``d```\\`\\`\`d`dd\`d``h`dlddlhdlhdphdphhpdhphhthlphlphlpdlpdppdppdlpdlphhpdhpdhphlpdlldhd`d``d```d`dd``h``h``h``d\`d`dhdhhdlhdlhdhhdllhpplxtp||t|xpxtptthppdlpdllhlhhllhlhdhh`dhdhhdhlhlphlphlldhldhlhlhhlhhlplptlttlttltxltxltxltxlttltthpxlt|px|pxtptplttpxxt|xtxxpxtpttpxxpxxpxtpxtpxxpx|tx|t|xt||t|||||TP`h`pxt|xptxpttptpltplpplppltttxxx|xx||x|||ȸhp|hlxlpxlptppttttxtxttxttxtxxtxxtttxtp|ptxtttttttpxt|llthdlh`hh`dhdlllllplhlhddhd`hd`d```\\d`\d`dd\`d\`h`dlddlhdld`pddphhthhthlxlpphlhhlhdllhtldtldllhllhhlddlddphhpdhl`hd`d``d\\`d``d``h``h``h``h\`h\`h`dhdhhdhhdhldlphttl|xp|tpxpltphlpdhpdlpdllhlhhhhdhldhh`dh`hldhphlphpphlldhldhlhllhllhllhpplpplttltxltxpxxltxlttlttltxltxpxxpxtpxtpttptxpxxpxtpxtpxtpxtpxxpxtpxtpxxpx|t||t|xt|tp||x||d`p\\htpxtttxttxpttltplpllplppppttx|txxxx|||||츴ĸlpxlpxlltpptpptttxxttxxt|xtxxtxxxxtxxtxttx|txxptxlp|pptlllhdhhdhhdhh`hhddd`hhdhhhdddd``ddhddh``dd`d`\dd\dd`hhdhlhdld`pd`tddxhhxllphhlhhhdhhdhhdhhdhhdhldhldhlddl`dp`dldhlddd`d````\`d\`d`dh`dh`dd`dd`dd`dd`dd`dh`dhdhhhlllptpttptplpphplhllhllhllhlldhhdhldhhddhddhdhlhhlhhlhlphllhhhdhhhhhhhlllpllphlthlthpxpxxpxtptplttpxtlttltxlxxpxtptplptlttptxptxptxlttlttltpltppttpxplxxp||txp|xp|xt|xllxPP\tt|tpxxptxlpxlttltpltpptppttpxtpxxtxx|x|ĸؼȸȼltxlptlptppttttttxxxt|xt||xxxxxxxxtxxtxxttxttxlpxllxplphhlhdhhdhddhd`hd`dd`hd`hhdhddhddhddhddd`dhddd`dd`hh`hhdhlhdlhdlhdphdphhphhlhhhhhldhhdhhdhhdhhdhhdhhdhhddl`dl`dl`dh`d````\``\``\`d`dd\`d`d``dd`dd`dd`dd`dh`dhdhhhlllpllphhlldlldlldhldhldhldhhdhhdhhddhddhdhlhhlhhlhhlhhphlphhldhlhhhhhlhllhhphlpdlthlxlttptpltplptpttltxptxpx|pxtptplptlttptxpxxltxlttlttltpltpltpptplxtl|xp|xpxtlxxpx|t|pp|HLTtt|ttxxptxptxltthtpltpptttxtpxtpxxp||x|xxt||xԸļptxpttpptptttttxxtxxt|x|xxxxxxxxxxtxxttxpp|ll|ll|plthdlhdlhdhddhd`hd`d``hd`hd`hd`hddhddhddh`dd``d``d`hhdhhdhhdhlhhphhphhphhphhhhhhhhldhldhhdhhdhddhddhdddd`dh`dl`dhddd`d```d\``\``\`d`d`````d`dd`dddddd`dd`dd`dlhlllphhlhdhd`hhdhhdhhdhhdhhdhhdhhdhhdhhddhddlhhlhhlhhlhhldhpdhpdhpdhlddhdhlhhlhhphhthlthlthptlttptplptpttptxptxptxpttlttlttlttlttlttltxlttlttltpltpltpltplxtl|xp|xpxxpxxpxxpxpt|DHPtt||xx|||xx|xt|tpt|츸̼ȼļtxxpttpttttttttxxt||x|||xxxxxxxxxxx|tt|pp|ppplplthdpddlddlddhd`ld`h``ld`lh`ld`hd`lddlddh``hd`hddhdhhdhhdhhdhphlthhtdltdltdlpdllhlpdhldhhdhddd`dd``d`ddd`dh`dh`dhdddddd`dh\dd\dd`dd`d``d``d`dd`dddddddd``dhdhllphhpddhddhd`dd`dh`hhdhhdhhdhhdhhdhhdhhddhddhdhhdhhdhlhhlhhpdhphlpdhlddhddldhlhhphlthpxhptlttptttxtpptpptppxppxppxlptpxtp|tlxtlxxlxxlxxlxtlttlttltpltpltppxtl|xp|xp||t|xx||LLXtp||x|tx|ptxtx|||||||x||hdlphtĸĸxx|ptttttxtxxxt|xx|||x|xt|tt|tt|tp|plxlh|plxlhthdthdphdld`lddhddhddhhdlh\hh`hddhhdhddhd`hhdhhdlhhldhl`hldhthpxhlxhlxhltdhpdhlhlldlhdhd`hd`h``d`\d\``````d``dd``d``d``dd`dd`dd`dd`dd`d`\``d````d`dh`dh\dhdhplpddl``h``h`\d\\d``d`dd`ddddddddh`dh`dh`dh`dldhldlldlphpthpphlphltltpdll`hldlldlphptlptlptlptpptpttpxtpttlttltxltxlttpttpttpttpttpttpttpxpltpltpltpltplttpxxpx|t|||||||TThXXpplxlhhphdh`dd\`d\dh`hldhhdhlhlplpxpxxpxphplhtphxxļ츸м̼||xx|xtxxtx|xx|||||x|xt|tttp|pl|plxlhxlhthdphdlddld`lddlhdlhdhhhlhdldhldlhdlhdhhddhddlddldhlhhldlphlthpthlthlxhltdlldhhdhldhhdhh`h`\``\`\\`\\\\\\`````d``dd`hd`dd`dd`dd`dh`dd`dd`d`d````d\`d\`h`hhdhhdl``d``d``d`\`\\``\d`````d``dd`dd`dh`dh``lddphhthptlpxlttltphlphlthpldlh`hl`lldlphpplptlptpptlltlptpttlttlttlptltxpxxtxxpxtltpltplttltplpplttltlhllhplhpplpxtt|xxtpptpt|xx|||x||XXhPLdd\lh`dlddh`d`XddXdh`lhdplhplhtplttp|tp|tp|tl|tlxp|xt||x|||ܼмȼ|||xx|tx|txxx||||xtxt|plxpl|plxlhxlhtlhthdlddld`lddlhdlhhlhhldlldlldpldlldhhddlddlddldhlhhlhllhlphpthlthlthlphlldhhddh`dh`dd`dd```\`\\\\X\\X\`\``\dd\dd`hd`hd`dh`dh`dd`dd`d`\``d`\\\`\\h`dthpldlhdl``d`\`\\`\\`\\``\`\\````d`dd`dh\dh\dl``pddthhthlthltlptlppllphllhplhlldlldpldlphpphpplptlptlptlptlttlttltplptltxpxtpxtpxphtpltplttlttlttlpphph`hphpxpx|txxpttppplptppxtxxxxttt`\hD@X`\l`\`d``h`h`Xd`Xdhdlhdphhplhtppxtp|tptptptptp|xt||x||||||̼||x|xxxx|||||txt|tp|pl|pl|plxplxlhtldphdlhdlhdlhhlhhlhhpdhpdlphppdhpddld`ld`lddldhldhlhllhlphlphlphlthlphhhdhdddd\`d\``\\`\\`\\\\\`\`\X``\`d\hd\hd\hd\hd`dh`dhdhd`d`\``\`\`\XXX`\\h`dxltldlddhd`d```\\\\\\\X\`\````d`dh`dh`dh\dl\dl``thdthhthhxhlthltllplplhllhlhdlhdlhdlldlphpphpplptlptllphltltxlttlttltpptppttlxtpxtlxtlxtpxtp|xpxxptxltxlptxtx|tttpltllplpplptptttxpplhdpLH\\Xhddhddhhdld\d`\`dddddhddhllppptpptppxppxtt|ttxt||t||x|x||||ԸȼĴĴ||||xxttttttxxxx|tpxpltltphplhpplppppllllllphpphlthlphhtlhph`ph`phdphhpdhphlphpphpphplhllhdhd`h``h`dd\`d\``\``\````\\``\`d\dd\d`\dd`d``d``d`````d``d`\``\``X\\XX\TX`X`lhlldhhdh`\`\\`\\`\\\\X\\\\`\\`\\d``hddl``h\`p`dpddlddphhthltlpthpthpplllhlldlhdlhdlldplhllhllhpphpphpphpplpplptpttlptlptpttpttlxtlxtpxxt||x|xtx|x|ttxtptxtxxtttttppplhpllpllpllpllppptpltlhtD@PTTdd`ld``d`d`\`\X```dd`hddhhhllhtpltplttpxtpxttxttxttxxt||x||x|x|||x|촴ļļ|xxttttttxtxt|xxtxptphpplptpttttpppppppptplplllplhplhlldph`phdphdlddphhphpphpphpphhlhdhd`h`dd\``\``\`\\`\\\\\`\\``\``\d`\dd\dd`dd`d``d``````````\``X\\X\\T\\X\ldhphld\`h`d`X`\X`\X`\X\\\\`\\``\``\d``h``h``l``tdhpddpddlddphlthpthpphpphplhllhlhdlhdlhdlldlhdlhdhhdllhllhpplpplptpttlpplpplptlttpxxpxxt||x||t|plplhllhpllppppplplllplphhllhpllplhllhpllpphplhpD@PPP`d`l`\`d\d`\d`X``\d``d``hddllltpltpltppttpttpttpttptttxxt||x||||||||ظļļļ||xxtttpttxtxp|t|txt|tt|tt|txxttxtxxttxtttpppllpplpllplhpldtldphdlddphhphlpllpllphhlhdh``d`d`X``X\\X\\\`\\\\\`\\`\\``\d`\dd\dd\dd\d``d```````\`\\\\X\\T\\T``X`|ttplhd``d\d\X`\X`\X`\\\`\``\``````\``\d\\h``l`dtdhtdhp`dp`dpdhphlplpphpplpplpplphdhhdhhdhhdhhdhh`hhdhlhlplpplpplptpttlpplpplptlp|tx|x|xtxxpxlhld`hd`hd`ld`hhdlhhllhlplphhlhdlllplhllhllhlphpplxPP`LL\``hd`dd`dd\d`\d``dd`hd`hhhllhplhtlhppltppttptpptppttpxttxxx||||x|x|x|||x||txĸĸȼļļĸ||pptptpxpxpxp|pxtxtxttt|tt|xx|tx|ttxpp|ppxlptlltlltldtldpldphdphdphhphlpllplhlhdh``d\d`Xd\X\\X\\\\`\````\\`\\``\d`\dd`dd\dd\dd`d```\\`\\`\X\\X\\TXXP`d\dplhplhplh`Xd\Xd\X`\\`\\``\````d```````\d\\h``l`dpddtdhtdhpdhpdhlhlphllhplhplhpplphdhhddhddh`hh`hhdhhdhldllhpplpplptpttlptlpplptptxttxttlhhldhhdhhdhd`hd`lddlddlhhlplttptlhlddhlhllhplhllhllhplhtTTdDDP`\hd`dd`dd`hd`d``d``d``dddlhdplhpllppltpltppttptppttpxttxttxxt||x||t|xtxxtx|x||||||||ܜĸĸȼļ|tt|t|txtxtxtxtxptttt|tx|t|xx|xxxxtpxtpxppxppxpttpttpptllthlthhphhplhplhphhlhhlddhddh```\\`X\`X\\X\`\\`\\````\``\`d``hddd``d````\``\`\\`\\`X`\X`\P\\X\d```\\h`dhddd\`\X\\\``\``\``\`d\`d\`\\\`\\`\Xh\\l`\td`thdxhhxllthlldlldlldpldplhllhlhdhh`hh`lh`hh`hhdhhdlhdlhhlhhllllplptlpxltxpttptpllldhldhh`dh`dh`dd`hd`lh`ll`lldlpltppthhl``dhdllhllhplhplhplhlTT\HDTXTh``dd``d`dd`d`\``\```dddhddlhdplhpllpllpllplpllllllpppppptppxxt|xx|ttxtptxtx|xxxxx||||||ļxx|x|xxt|txtxtxpxttxt||x||||xx|xt|tt|ptxppxptttttpptlptllthhthhpllpllphhlhhhddhddh``h``d\``\\`X\`\\`\\`\``\``\`d``hddd``d```\\\\\`\\`\``X\\T\\T\\X\`\\`X\d\`d``d\``\``\```dd`dd\`d\\d\\`\Xd`\h`\h\\l`\pddtlhxplxllpdhldhl`lldllhllhhlhdhd`d``d`dh`hhdhhdlhdlhdlhhlhhllllplptlptlpphplhlldlhdhhdhhdhhdhh`hd`lh`lh`ll`lh`hllppptllpddhd`dhhllhllhllhlhhl\X`HDTTTh``d``\d\``\``\`\\``````dddlhhplhpllpllpllplllllllllllpplpppttpxxtxttxtttxtxxtxxtxxx|xx|xx|||||ਤļ||||||||x|t|txpxtxxx|x||xxtxxt|tt|ttxppxpttttxttxppxllxlltllpllpllplllhhhddh``d``h``d\`d\``\\`\\\\\\\\`\\`\`d``hddd``d`d````\``\``\``X\`X\d\``X\\XX`X\d\``\\`\\\\\\\\```d``d`\d\\d\\h`\l``ld`l``l``pddthhtlhphdl`dl`hl`hldllhllhhhd`d`\d``d`dh`hhdlhdlhdlddlhhlhllllpplptlpldhldhlhllhlhdllhllhlhdlhdlddlhdlhdll`hh`hlhlllplhpddh`\`ddhlhlhhllhlhhl``hHDXTPd``d``\d``d```\\`\\````ddddlhhlhhllllllllllllllhllhllhllhlllppltppptpttpttttttxttxxx|xx|xt|xt||x||x|Ĵļxx||||xt|txtxxx|x|||xttxtp|tt|ttxppxttxtxxttxppxlpxlpxlltllpllplllhhhddd```\\d``d\\d\``\``\\\\\\\\`\\`\`d``hddd``hddd`d``d`\`\X\\X\d\`h`d`\\\XX`\\d\``\\`\\`\```````d`\`\\d\Xh\\l`\pd`thdthhl`dpdhtlhlhdlddl`dl`hl\hl`lhdlldld`dd`dd`hh`lhdlhdlhdlhdlddlhhlllpllplhlldhl`hhdhlhlhhlhhllhphdlhdlddld`hd`hh`hl`hhdhhhhhhhlhlddhddhd`hlhlhhllhphhlddlHDXHH\X\```X`\\`\\\\X\\X\`\```ddhddhddhlllllllllpllphlphlphlphpplpplpppltppppppptpptxt|xt|xt|xx|xx||x|xxtx||नļļ|||||x|xxxxx|xxxtxxttxtxxpxxpxxpt|pt|tp|tpxppxppxpltlltlhpldlhdld`h``d\\h\`d`\hd`d`\`\\`\``\``\d``dd`dhddd`d``dh`hhddd```X\`X\d\`d```\X\XTd\Xd`\`\\`\\d\\d\\d\\`\\d\\h``hd`pd`thdthlthhpddpd`phdlddhddh`dhddldhhdhhdhhdhd`dd``hd`hd`h`hh`hhdhh`hldlphplhld``d``h`dd`dhdhldlhhhhdhhhlhdhhdhdddddhd`hddhhdhhdlhdhhhlhhlddhd`d``dhdlhdllhphhhhhhLL\D@TTX`\\\````\\\X\\X\\\``\d``dd`dhdhhhhhhllhllhpphtthpthptlptlpplppppppppptpptpptttx|x|t|xt|xt|xx|xx||x|t|訰ĸļ|||||xxxx||||||||x|xttxttxtxxpxxpxxptxppxpp|tpxppxppxpltlhplhlhdhd`h``h``d\\h\`d`\hd`hddd`\`\``\`d\dd`dd``h``d``d`dhdhhddh`dd\`d\``\\\XX`XT`\X`\Xd\\`\\`\\`\\d\\d\\d\\d``h`dphhthhthhthlpdlpddpddd`\h``h``d``h`dhdhhdhd`dhdhlhhhddhddhd`h`dd`dh`dhdhldllhlhddd```\``\`d`dhdhhdld`dhdhddhhdhddhdddhdhddhddhddhhdhddhhdlhdlhdlhdhhdhhhlhdlhdlhddhdhPL\D@TTT`\\\`\\`\\\X\\X\\\``\d`\`d`dddhhdhhdhhhllhpplttlttltxpttptplltpptppplpppptptxtx||t|ttxttxxx|xx|xx|xԜ||||||x||||||||||xxxxtxttxtxxpxxpxxptxppxplxppxppxppxpltlhlhdhd`h`\h``h``h\`h\`d`\d``hd`hddd``d``h`dh`dh``h`\h``h`dh`dh`dd``d``d\`\XXXTT\XP`XT`\X`\X`\\`X\`\\d\`d\`d\`d`dhddphlthhthlphlpdll`dld`d\Xd``d``d``h`dhdhhdhhdhhdhlhhhddhd`d``d``d\`d\`d`dh`dh`dd``d``d```\`d\dd\dd`dd`dddhhdhddhd`ddddhdhhdlddhd`hddhd`hddhhdlhhlhhlhhlhhlhdllhllhhh`dTP`D@TPP\\\\`\\`\`\X\\X\\X`\X`\\```dddhhdhhdhhhlhhlplptlptlpxtttttpplxtpxtptpptpptptxptxpttpttpttttxxxxxxxtx|x|ܸx|||||||||xxxxtxxtxtxxpx|t|xptxlpxplxppxppxppxplphhlhdhd`hd`h``l``h``h\`d`\hd`lhdlhhhddhddldhl``h`\h`\ld`l`dh`dd\``\\d```\\XTTXTT\XT\XT`XT`\X`XX`X\`\`d\`d\`d\dh`dhdhldlphhphlphpldlh`dd\`d`\`\\d\\d``h`dhdhh`hldllhllhhd`dd``d`\`\\d\``X\\XX`\\d\\`\\`\\`\\`\``X``X``\``\````dddddhd`ddddhdhhhlhdlddhhdhddhhhllhllhlhhlhdhhdhhdlphpphlldh\TdD@TPLX\X\`\\`\`\X\XX\XX\XT\\X\```dddhhhhhllhllllllppllplltppptlllhtpltplxppxppxppxppxpttpptpptttxxtxxxxxx|x||||||䤤|||||||||xx|xxxxxxttxttxtpxtptphtllxppxplxlltlhph`ld\h`\h`\l``l``h``h`dh``lhdplhtppphll\hp`ll\dhX`h\dl`dl`dd\\d\`d\`h```XX\TTXTPXTX\X\\X\`X\`\``X\`\`d\dh`dl`hl`hl`hl`hlddphdphdlddh``d\\dXX`XTdX\h``h`dh`hldlldlhddhd`d`\d\`d\`\\``\`\\\\X\\\\`\``\`\X\XTXXTXXTX\X\\X\`\``\`ddhd`hd`hd`hd`hhdhhdhd`hhdhhdlldlphllhlhhlhhhd`dphltlhplhllp``dD@HPHX`Xd`\``\``\`XX\XTXXX\\X\d`dh`hhdlldlldllhllhllllphllhlphlphllhhplltllxpptpptpptpttpptttttpttpxtpxxpxxx||xxxx|x||x||ܼȔ|||||||||xx|xxxxxxxt|xt|xtxtpxplxpp|tp|ppxllthdpd`ld\h`\h`\h``h``h``l`dh`dhddppltplpllpdlp`ll\hh\dh\dh`dd```\\`\`d``d\\`XX\XTXTTXTTXTX\X\`X\`\``X\`\`d\`h`dl`hpdhpdhp`hlddlddlddld`d\\d\XdXX`XXd\\h`dhddhdhhdhldhldhh``d\\`\\`X`\X\\X\\X\\X\\\\\X\\X\XTXTPTTPTXTX\X\\X\\\\```d`dd`dd`hd`hhddd`dd`dh`hhdhhdlldlldllhlhhlhhlh`dphlphhplllllddhHDLHDP\Xd\\\XX\XXXXXX\X\\\\`\`d`dhdhldlplpplpppplhlhhhphllhllhlphhlhhpllplltllpllplltptxttxttxttxtp|ttxxtx|x||x|xx|xx|x||蜠ļ|||||||xx|xx||||xx|xt|ttxtpxtp|tttt|ttxllthdpd`ld\hd`h``h`\d\\d\`h`dd`hdddhlhhlhlhdh`dl`hl`hh`hhdhhddd```\``\d\\`XTXXXXXXXXXXXPTXTX\TXd\`h`d`\``\\d\\h``l`dpddpdhp`dphdphdlddh`\`XX`XX`TXdX\d\`h`dhddhddd`dh`hh`dd`\`\X`X\`X\XX\XXXXX\\X\\\\XXXXTXTPTTPTTPTXTX\TX\X\\\\`````````d`dd`hd```\\`\`d`dhdhhdhldlldhhdhhhhhhhhdhphlplpplllhdh`dLDLD@P`\hd`d``d`\`d`dhdhlhlplpplllhltpptptxpttttxxxplpplptlptlpphlphhphhpllpllpllplltlpxppxppxppxtpxtpxxpxxx||xxxx|xxx|x؈||||||xx|xx|||||x|xtxtptplxpltttt|tpxpltlhph`ld`hd`hd`d``d``d``d`dd`hddh`d`dd`dd`d\`l`hl`hh`hhdhhdd```````\dXX\XTXTTXXTXXTXXTXXTX\X\`\`d`d`\``\\d\\d\\h\\l`dl`dl``ld`ld`h``h`\`XT\TT`TXdX`h\dh``h`dhd`d``d\d`\\`\X`\X`X\`X`XX\XXX\X\\\`\\\XTXTPTPLPPLPTPTXTXXTX\XX`\X\\X``\d`dd`d``dd``d`\d``d``hddhdhldhldhhdhhhhdddd`d`X\llpllhphdpddLDL@<Phdtpptllphdhhdhlllllppllplltppxttxtt|xx|||xptpllphhtpptpptlltlltlptlpxlp|pt|tp|tpxtptxtxxtxxx|x|||褨|||x|xx|xx||x|x|xxtpxppxppxpp|tp|tpxpltlhphdld`ld`hd`dd`d`dh`hh\dh\hd`d``d``d``````hddldhlddlhdd`\```\\`\\\TTTTTTXTTXPTXPTXTTXTT\XX`\\`\````d``d\\d\\d`\hd`hd`hddld`h`\d\\d\X`XT`XT\XX`\`d`dd`dd``d\`d\``\`\X\`X\d`d`X\`X\\\X\XX\X\\X\XT\PPTPLPPLLPLLPPPTPPTTTXTT`\X`\X`\\`\``\`d\dh\dd\dd\dd`dd``d``hddhdddddddd```\XX\TXlhhphdthdxllTPT<8D\Xdlllllhlhdlhdl`dl\dh`hhdhphhtphxpltt|x||||x|||||xtx|xxxtttplttptlpphpplptpptttxxtxxttxtttpxxt|xx||x||||x|xx|xx|x|xxxxtpxppxppxpl|tp|ppxpltlhphdphdld`hd`dd`hdhldhl`hh`hd`h``d``d`d`dd`hddlhhplhlhd``\``\```XXXTPPTPTXPTXPT\PT\PT\TX`X\`\\`\````d``d\`d\`d``h`dhddlddld`h``d\X`TT`XX`XX`T\d\dh\hd\hh\hd\d\T\\X\`\``\``X\\X\\X\\\XXXXXTXTPTPPTPLTPLPLLLPLLPLPPPPTPTTTTXTTXTT\XX`\\`\``\`d\dd\dd\dd`dd``d``dd`h````````\\\\XXphhtlppll|tpxxXTX<8HDDPXXXXXTXXTXTPXPPTLPPLPTPP\XT`\Xhddldhl``pddpddlddphh|tt|||xttxtpxttplppllpllpplttpxxt||xxxtxtt|xx|x|x|||ܬ|||||x|xx|xx|xxxxt|ppxll|ppxpl|plxplxllthhpddpd`ld`hd`dd`hdhldlldll`lhdh``d``dddddddldhplltplhd```\````\`\XXXTTXTT\TT`TX`X\`TX`X\`X\`X\`\\d``d``d\`d\`h`dhdhh`dd\`h``h\``X\\TX`X\`X\`T\`T`dXdd\dh\hdXd\T\\X\`\`\X\\TX\X\\X\XXTTTTTPTPLPLLPLLPLLPLLLLLLPLLPLPPPPTPTTPPXTPXTT`\\`X\`\`d\dd\dd\`d`dd`dd``d``d\``\\\\\\\\hddtlpplplhhd`\\TTLHP<<L88HPPTPPPPPLLLLPLPPLTPPTPPPTTP\XX`X\d\dh\dh\`h``lddl`dd``h`dphlxpp|||||xtptplphhphhtllxpp|xtxx|tt|xx|xxx||||||xxxؔ옘xx|||x|xxxx|xxxtt|pp|ll|ll|llxll|llxllpddl``ld`ld\hd`hhdhhhphlthpldlhdh``d`dddddhhdlhhtlpplhhd`d`\d``\\\\TX\TXXPT\PT`TXdX\dX\`TXdX\dX\`\\d\`d`dd\dd\dh`hh`dd\d`\`d\`h\`dX\`X\`X\`X\`X\`X\dX\h\`dX`dX\`X\`\`\X\XTXXTX\X\\X\TTPPPPPPPLLPLLPLLPLLPLLLLLLPLLPLLPPPTPPTPLTPPXTT\X\\X\`X`dXddX`d\``\``\``\``\\`\\`\\\\\hhhd``h`d\X`XTXXTTTLPLLT48H44DHHLLLLLLLHLLHLLHLPLPPPPPTTPXTX\X\`Xd`\`d\`d`ddddd`ddddd`dh`dl`dthltllxplxtxtl|tpxtxplxlpxlpxll|pp|tt|tt|xx|xx||||x||||ܴļܸȬРМ蘔x|||x||x||xxxp|xpxtpxtl|tp|plxllxllxllxhhpddp``pddhd`hd`lddphhphlplpphlldhhdhldhldhldhphpphllddl``lddd``XTXXT\\T\\X\\X\\X\`X\`X\dX``X\`X\`\`d`dhddh`dh`dh`dh`dd``d\``T\dX`dX\`X\\XX\XX`XX`TX`XX`\\\X\\XX\\\\XX\TT\PT\PTXPPTPPTPTPLPPLPPLPLLPLHLLLLLLLLLLLLLLLLLLLLLLLLLPPLTTPXTT\XX\XX`\\`\\`\\`X\`X\`X\d\``X\`\\d`````XXXTTTTTTTPLTLLTLLLLP8<D08D<@LHLLHHDHHDHHDDHHHHLLLPTTTXXXXXXXXX\X\`\\`\```d`\``\d``dd``d`dhddhddhddhdhplhxtp|x|xt|xt|xt|xt|xtxtp|xtxttxtt||xxxܐ|ļܸܤȤ𐐌xx||||x|x|x|x|xp|tpxtlxplxlhxlhxlhxlhxlhthdpd`pd`ld`hd`hd`lddpllpllplpphllhlldhlhllhlphlphpphlpddl``phh`\`\X\\X`\X``\``\``\\`\\`\\d\`d\``\``\`d`dhddhddhddhddldhhddd`dd\`\TX`X\dX\`XX`XX`TX`X\`X\\XX\XX\XXXXXTPPXPPXPTXLPTLLPLLTLPTLPPLLPHLLLLLLLLLLLLLLLLLLLLLLHHHHHHLHHPLHPLLTPPXTT\XX`X\`\\d\`d``d```X\`X\\TX\XXXTTTTTTTTPPPPPPPLHPLHPHLLHL8<D04@4<DDDHDD@DD@DDDDDHHHHLLLPPTTTXTTXTTXTTTXXX\XX\\\\\`\\``\``\`hddhddhddhddhddhd`tll|xt|xtxxxx|x|xxtt|xxxttxtx|x|||tptx|xxxttx|xx|||||||x|xt|tl|tp|tpxplxlhxhh|hh|hdxhdthdpd`ld`lh`hd`hd`hhdpllpllplpplpphllhlldhlhlplpplpphlpddpddpdh`\\\X``X`d\dhdhd``d```\\`\``\``\`d\`d\`h`dh`dhddhddhddlhhldhd`dd\`\TX\TX`X\`XX`XX`TX`X\`X\\XX`\\`\\XXXTTTTPPTLPPLLLLLLLLPHLPLLPLLPLLLLLLLHLLLLLLLLLLHLLHHHHHHDHLDDLHHPHHPLLXPP\TT\XX`X\`\\d``d``\TX\TXXPTXTTPPPPLPLLLHLHLLLLHDLHDPHHLHL<<D04D48D@DHDDDDD@DDDDDHDDHHHLLLPPPTPPTTTTTTPXXT\XX\\\`\\`\``\``\`d``hddhddhddhddh``lhdplhplhtpltpltpl|||xttxttxtx||Ԁ|x|xtptxx|||||||x|xxt|tp|tl|pl|pl|lhxhh|hdxhdxh`th`ph`lh\hh`hhdhhdhhdllhlllplpplpphllhlldhldhplpplplhlpddpddl```\\\X``\`hdhphlhdhhddhdd``````d`dd`dh\dh\dh`dh`dh`dh`dhddhdd`\``\`h`d\TT\TXdXXdXXdX\`X\\TX\XX`X\`\\TTTPTPTPPPLLPLLLHLHLLPLHPHHPLHPLHLLHLLHLHHLHHLHHLDHLDHLDHLDHLDDPDHPHHPHHXPP\PP\TX\XX`X\`X\\XXXPTXPTTLPTPPPLPPLLLLLLLLLLLLHDLHDPHHLHP<@H04D04D@@HD@@D@@@@D@@DDDDHHHHHLLLPPPPPPTTTPTTPXXTXXT\\\\\\`\\`\``\\hddhddhddhdhd`\h``hd`lddphhplhtplxxtxttxtt|txxptptxxx|||||||x|xxx||xxxt|p||p|xl|pl|ppxll|lhxldxh\td\td`pd`phdlddhdddhhhhhlhllhhpllpllpllplpphllhhphlthlthlpdhthhxppl`dh\``X\d`dhdlplpplpphhphhhdlhdhd`dd`dh`dl`dd````````d``d``d\`d\``\\d``\XXTPP`TXd\\dXX`XX\XXXXXXXXTTXTPTTPPPLPLHLLHHPLLPLLLLHLLHLHHLHHLHHLLHHDDHDDHDDHDDHDDHDDHDDHDHLDHLHHPLLTPLXTP\TT\XTXTTTPPTPPPLLPLLLHLPLLLHHLHHLHHPLLHLDHHHHHHHHHHHH@@D04@04D8<D@@@@@@<<D<@H@@DDDDHHHHHHLLLPPPPTPTTTTTXXTXXX\X\XX\\\\\\\X``X``\hd`ldhhd`hd`h``h``hddldhphhplhttp|xt|x||xxx|̘tpt|t||xxxt|tpt||xİxxx|xx|tttp|xp|xl|tl|pl|pp|pl|phxldxh`td`pd\pd`lddlddhhhhhhhhhlhhlhhplltlppllplllhhphltlltlpthlphhxpp|ptphhlddd\`d`dldlphltlpphlphllhllhphdhh`dh`dlddd````````d``d\`d``h```\\`\\`\\d\\`XX`XXdX\\TT`\\\\\TTXTPTTPTPLPPLLLHLLHHPLLPLLLLHLLHLHHHHHHHDHHDHDDHDDHDDD@DD@DHDDHDDHDHLDHPHHTLLXPPXTPTPPTPPPLLPLHLHHLHHLHDLHHLHLLHHHHHHHHLHLLLHLLHHHHDDDDDH@@@,0<,4D8<@@@@<<<<<@<<D<@@@@@DDDDDDHHHLLLLPLPPPTPTTPXTPTTTTTXTXXX\\X\\X``\d``hddhd`hd`hddhddhddldhlhhplhtplxtp|xt|xtxxtx|x||x|||tttpppxxtĴ􌈄xtx|xxpppp|tp|tl|thxpl|pp|pp|phxldxh`xhdthdpddl`dhdhlhhhhhhhhlhhphltlptlpplllhhldhlhhtlptllphltlltppphhphhlhhphlhdlhdhphltlptllphllhlplllhllddld`lddhd````\\\\X\`\`d``h```\\`\X`\\d``d\\`XX`TTdX\pll\\\TTXPPTPLPLHHLHHLHHLHLPLLPLLLLHLLHLHHHHDDDDHDDDDDHDDD@DD@@D@DHDDHDDHDHLDHPHLTLLXPPXPLTLLPLLPLHLHHLHHLHDHDDHDHHHHHHHHHHHHHHHHLLHHHHDDDDDDDDH@@@,08,4@48<<@<<@<<<@8<@<<@@@@DDDDDDDDDHHHLLHPPLTLPTLTTLTTTPTXPXXT\\X\\\\\\`\\h``hd`hd`hhdhhdhhhhdhhdhlhhpllplltppxtt||xxxxtxxtt|txx||||ttppppxxt䌈||||xxx||xxttpp|pt|tp|thxph|pptp|plxldxhdxddtddpddl`dh`dhdhhdhlhhphltlptlptlpplllhhhdhldhtllthlphltpptpph``hddlhhtptplpldllhlphlthlphhlhhlhhlhhlhdlddld`h`````\\\\X\d\`h`dd\```\`\\`XX`XX`XX`XXd\\tlld``XXXXXXTPTPHLHDHHDDLHHPLLPLLLHLLLHLLHLHHHHHDDDHDDHDDD@DD@@D@@HDDHDDHDHHDHLHHPLLTPPTPLTLHPLHPLHLHHHDDLHDLHDHHDDDDDDDDHHDHHDDDDHDHHDDDDDDDDDDDDD<<@(,8,4<448<<8<<8<<<88<<<<<<<@@@DDDDDDHHHHHDPLLTLPTLTTPTXTTXXTTXPTTT\X\\X\\XXd`\``\dd`hhdlhhhhhhdhhdhhdhlhhlhllhhplp|xttxtt|t|x|||||tttp||x萄|||||||xxx||||xxxxxxttp|pl|pltlhtld|ph|th|ph|llxllthhphdpddld`ld`h``dd`lhdphhtllxlptllplhhhdhhhhhhlhlpdltllxppphld``d`dlhltpttptplplhlldhlhllhlhhhhdhldhlhlldhl`dh`dd\``\`d\`d`dd`dd\``\``X\\X\XTX\XT\XXd``h``\XXXTTTTPPPLHHHHDHLDHLHLLHHLHLLHHLHLLHLLHLLDHHDHHDDH@DD@HD@DD@DHDDLHDLHHLHDPLHPLLPLLLLLLLPLHPLHLLDLLDHHDHHDDHDDDD@DDDHDDHHDDDDDD@DDDDD@DD@@@<@@@@@D008,,<40D84@88484484888<<<<<<<@@@D@DDDDHDDPLLPHHPLLTLLXTTXPTXTTXTXXTX\TXXTT\XX`\\dd`dddhhdhhdhhdhddhddlhhhhhhhlddhxx||x|xt||xx|||tp|tt||̸ܐ|x||xtt||||||x|xtxx|xxxxt|pl|phtlhth`tl`|ph|phxllxlltlhthhphdphdphdlddhddhddhddphhtlltllllhhhdhhdlhhlhll`hthl|ttl`d`\\d`dlhltlttpttptlhlldhlhllhlldhldhldhldhldhh`hhdhh`dd`dd`dd`dd`dd\``\``\`\XXXTT\XT\XX`\\\XXXPPTPPPLLLLHHHDHDDLHHLHHLHHLHHLHHLDHLDHLDHHDDHDDHDDHDDD@DD@@D@@HDDHDDLHHLLHPLLLLLLHHHHLHHLLHPLHLHDLHDHHDHHDDDD@DD@DDDDDDDD@DD@D@@@@@@@@@D<@@<<<<<<@008((8,,@44@88888488<8<8<<<<<<<<<D@@HDDHDDLHHPLLPLLPLLTPPTLPXTT\XXXTTXTTXTTXTTXXX`\\d``dd`dd`dddhddlhhlhhhdhlhlpptԀxx||tx|||||x|ttԈ||xxtt|x|||||t|xtxx|xxxtp|tp|plxlhxldxldxpdxphxpltpltplplhphdlddlhdlhdhhdhddh``lddlddphhlhdhhdhhhhhhldhldh|lpttl`dh\`h`dphlplptptxtxplplhlhdhldhldlldhldhhdhh`dhdhhdhhdhh`dh`dh`dd`dd`d`\``X\XTTXTT\XT`\X\XXXPPTPPTPPLLHHHHHHHLHDLHDLHHLHDLHDLHDLDDLDDLDDHD@HD@HD@HDDD@@D@@HDDHDDHDHLHLLLHLLHHHHHHHHHHLHLLHPHHLHDHHDHDDDDDDDD@DD@D@@D@@@@@@@<@<<@@@@@<@@<<<8@@@<<@04<$(8,,@8<H<@<<@<<<@<@<DD@HHDLLHPLLPLLPLLPHHPLLTLLTPPTPPTPPXTT\XX\XT\XX\XXXTTXXT\XX`\\``\\\X``\d``hddhdhhhl\X\lptttxxttxx|||||섈xtxpp|xx|x|||||xt|x|x|xxxtt|plxlhxhhxldxpdxpdxph|tptpltplplhplhlh`lhdhhdlhdlhdhddhddlddlddhd`hhdhhhlhlhdhpdlptxllpdhldhpdhphlthpplptpttptlhlhdhh`dpdlpdlldhh`dd`dhdhhdhh`dh`dh`dh`dh`dd`d`\`\TXTPTXTT\XT\XXXPPTPPTPPPLLLHHHDDHHDLHDLHDLHDHD@LHDHD@HD@HD@HD@HD@H@<HD@HD@D@<D@@LHHLHHHDLLHPHLHHHHDDDDDDHDHLDLHHLHHLDDHDDHDDDDDD@D@@@<@<<@<<@@<<<<<<8@@@@@@DH@DD@HHHDDH88@$(8(,@<<H@D@<@<<<@<@8DD@HHDHH@LLDPLHTPLTLLXTT\TT\XX\TT\TT\XT`\X`\Xd`\dd``\X\XXXXX\\X\\XXXT\\X`\\d``hddhhhd`d||hltxx|xpt|tt|||||x||䄄||xxptpp|x|x||x|||t|x|x|xxttt|tpxlhtl`xldxlhxlhxplttttpttppxllthhlddhh`hhdhhdlddldhpdhldhh`hd`dhdhlhdlhdhddplltxxhlpddthhtllxpptllphptlpthpphpl`hpdlpdllhlhdhddhddhddhddlddhd`dhd`h``d\dd\d\XXXPPXLL\PP\TTXTTPTPPPLLLHHDDHDDLHDLDDLHDLHHLHHLHDHDDHDDD@@HDDHDDD@@D@@D@@D@@D<<H@@HDDHDDHHDLLHLLHHHHDDDDDHDDHDDHDDHDDHDDHDDHDDD@@@@@@@<@<<<<<<@<<@@<@@<HD@LHDPLHLLH\\XPTLD@D($4$(@00@<8<<448488844848<8<<8<<8<@<HD<HD<LDDPHHTPLXPPTPPXTP\XT`\X`\X`\X\XT\XT\XT\XX\XT\XT\XX\\X```dddTTXdddlplppppppppp|xt||xx|x؄||||xxtlxtp||||x||||||||||t|x|x|xxt|tt|ppxlhtl`xldxhhxlhxpltppttptpptllthhphdhh`hhdhhdlhhpdhphlphlhdhd`hhdhlhdlhdlhdxtt|ptl`dlddphhxppxpttlpplpphpphpphppdlpdllhllhlhhllhllhphhlddhddhdddhddd``d`dd\d\XXTLLTLL\PT\TTTTTPTPLLLHHDDD@HDDLHHLDDHDDLHHLHHLHDHDDD@@D@@D@@HD@D@@D@@D@@D@@H@@HDDHDDHDDHHDHHHLLHHHHHHHDDHD@HDDHDDHDDDDDDDDHDDD@@D@<D<8D<8@@<DD@DHDHLHLPLLTPLXTPPPLPTLDD@848($4 (<(,<4044004440444848888<88<8<<<@@<D@<H@@HD@H@@H@DHDDLHHXTP\XT\XT\XT`\X`\X`\X`\X`\X\XT\XT\XX\\\``d``h|||hhdhlhlllpplppltpp|xx|||x|||||||||xtlhxtp||xxxx||||x||||x|t|xxxxt|tpxpltlhthdxhdxhhxlhtphtplttptpltlltlhph`hh\hh`hhdlhhpdhpdlpdlh`hhdllhhlhdlhdlhdtpptllh``lddphhxppxtttpppltlhpphpphpphpphplhlhdlllppltllphhlddhddhhdhhddd``d\``X`TPTPLLXLP\PT\TXTPTPPPLLHDDDDD@HDDLHDLDDLHHHDDHDDHDDD@@D@@D@@D@@D@@D@<D@<D@<D@@H@@HDDHDDDD@DDDHHDLLHHHHHHHDDH@@D@@D@@D@@D@@@@@DDDDDDD@<@<<D@@HHDLLHLLLPPLPXTPPLHHD@@@<884440444((8(<$,80040,,,00044044044488488888<<8@<<D@<D@@@<@@<@D@DD@@HDDPLLPLLPLLTPP\XX`\X`\\hd``\X\XTTTPXXXTTX``d``\dd`dddllhppltpp|tt|xxxxt||tx||||xxtlhxxt|||xxx|x||||||||||x|x|xxt|tt|tpxplthhphdxhdxlhxlhtlhpphppltplxplxlhph`hh\hh`hhdlddpdhthlphlhdlhdllhllhhhd`lhdlhhlddlddlddtpptpptppppppptpptllpphpphpphpphphdlpltxtxtpxllpddhhdlhhhhddd```X`\T\PLPTLT\PX\TX\T\XTXPPPHHDDD@DD@HDDHDDHDDHDDHDDHDDHD@D@@D@@D@@D@@D@@D@<D@<D@<D@@D@@D@@HD@D@@DDDHHDHHHHHHHHHDDD@@D@@D@@D@@@<<@@@@DDDDDD@@@DDDHHLHHHPPLLLHLHDHD@D@<<<888404,00,,,,$(4$8 (4,,0,,,,00004,00044448044448888<<8<<<<<<<<@<<@@<@@<@D@DD@DHDHLHLLHLPLHTPL`\Xd`\`\X\XT\\XXXXDDHXXX```\`\``\dddplltplxtt|xt||x|xx|x|||xtp||||x|x|xx|||||x|t|xtxtltlhtldthdthhthhthhtlltlltlhplltplxplxpptlllhdhdddddhddhhhlhllhhhdhldlldhphdphdphdlhdlddld`ld`tplxtptpppllplpplpplpllphllllplhlldhlhlplptptplpldlhdhhdhd`d`\`\XXXPPTLLXLPXTT\XX\XTTTPLHLD@@HD@HD@HD@D@@D@DDDHHDDHD@D@@D@@H@DD@@@<<@<<@<@@<<D@DH@@H@DH@DL@DH@DH<DL@HLDLHDLHDHHDHDHH@D@<@@<<@<<<@@@@@DDDDDDDDDDHDDLLHLLLHHD@<<<88<84<848404000,,0,0((8 $0 $0$,,,0,,,(,,0,00,0,,40,00048448848<88<<8<<8<8<<<<8<<<<@@@@@@DDDDHDDHHHLLHTPLXTP\TT\TX\X\\\`d`hHDH\X\h`hd```\X``\d`\hhdttp||x||x||x|xx|||||xt||||||x|x|x||||x||xxttt|plxlhxhdth`thhthhthhtlhtlltlllplppltpltplpllhlddddd``d`dhdhhhhhhhhdhlhlphlthhthhxplphhlddlddldhplltppxtttppplpplptptpppllpllllhlldhhdhlhlphlplplhlh`hd\d`X\\X\\TXXPPXLPXPP\TT\XXXTTTPPLHHD@DHD@HD@HD@D@@D@DDDHDDDD@@D@<D@@H<DD@@@<<@<<@<@@<@HDDHDDH@DH@DH@DD<DD<DH@HHDLHDLHDHHDHDDD@@@<<<<<<<<@@@DDDDDDHHHHLHHLHHHHH<<8@@<<88888844844844844844004((4 $, $0$,0,0,,0,(,0(,0,0,,0,,00,04448448884884888<8<<<<<<<<@<@@@@@@DD@HDDDDDHHHLHDLHDPLLTPPXTX\\`LHP\X\`X`dd`dd```\d`\``\plh||x|||x|xt|x|ļxtpxxx|||x|||||x|x||xxxtppxlhxhdth`phhphhplhplhplltplpplpplttptplpplllhhhhdddd``dddhdddddhdhphpthlxhhxlhtpthhh\`h`dldhlhlplltpptpttlptlpplpplpplplhllhlhdhhdhh`dldhlhlldlh`h`X`\TX\TX\TXXPPTLLXPP\TT\XXXTTPLLLHHHDDHD@HD@HD@HDDD@DD@D@@@D@<@<<D<@D<DD@@@<<@<<@<<@<<D@DHDDD@@D@@D<@@<@D<DD@HHDLHDLHDHDDDD@@@<<<<<<<<<<@@@DHHHLLLLHLLDDD@@<<88888884848448044044048444000,4((0 $, $,$,0,,0,,,(,0(,,(,,,0,(,0,0400444444044048488888<8<8<<8@@<@@<@@<D@@DDH<@@DD@HHDLHHLHPLHPTTXlhpd`d`X`\T\\XXhhddd`dd`dd`dd`xxt||x|x|tt|||興|tplxxx||x|x|x|xt|xtxtltlhtldph`phdphhplhplhpllppltplxpl|ppxppxpltplppllhlddddddd`dd``hddpdlxhpxhh|llxlll``d\`d\`ldhhdhhdhlhlplptlptlpthplhlphllhlldhhdhd`dd`dhdhldhhdhh`h`X`\X\\XXXTTXPPXPP\PT\XX\XXXTTLLHHDHHDDHDDHD@HD@HDDDDH@@D@<<@<<@<8D<@D<DD@@@<<@<<D@@@<@D@DDDDD@@D@@@<@@<@D@DD@HDDLDDLHDH@@D@<<<88<<<@@@HHHLLLPPPLLLD@@D8<<44<888884844848488084044044044040,4(,0 $($,$(0(,0,,,((,(,,(,((0,(,,,040040440400404844884884848<4<<8<<8@<8@@<@@D<@@@@@DDDHHHLHPDDHTPX`\`d`h`X`\XX\\X``\dd`dd```\``\||x||x|xtxx|||ؼ興||xppptx|||||||||x||x|xtxtlxphtldthdtddthdthhthltlltlpxlpxplxplxtpxttttxpptptppppdhd``````hddlhhplhtpl|ttxpph\`h\`h\`h`dhddhddhddhdhpdlthpppppppplllhhldlhdlh`hd`hh`lhdlh`hd`d`\\\XT\XTXTTTPXXTXXTT\XT\XTXTPLHLHHLHDHHDHHDDDDDDD@@@<@@<<<<@<<@<<@<<D@<D<@D<@D@@D@DD@DD@@D@DD<DD@<@@<@@<@@@DDHDDDDDHD@D<<@88<<<<@@@PLLPPPHDHD@@@<@@<<<888448888884444404084,48084044,00,00,,(,0$,$0$0$(0(,,((,((,,(0,(0,,0,,00004400000004444448844444448888888888888<@<<@<<@DDDD@DHDP,(4``hPLTXTX\X\d`d`\X\XT`\Xdd```\``\d`\lhd||||||||ļظ䐌||xtptxxx|||||x|xpxplxphtldth`thdthdthhthhtlltllxlpxplxplxtpxxtxtxtttlppppplhhhddd`dhddhhdlhhpll|tttllh\`l`dh`dh`dh`dhddhddd\`h\dldlpppppplllldhlhlhdlhdhh`hd`hd`hhdhh`hd`\\XX\XTXTTTPXXTX\XX\XTXXPTPPLHLHDLHDHDDHDDDDDDD@@@@<<@<<<<<<<<<<@<<D<<D<@D<@D@@HDDDDDD@DD@DD<@@<<@<8<<<@@@@@DD@D@@D<<<<8<<8<@@DLLLTTTLHH<8<8888488448448448848844444404080,40,00,00,0,,,,((((,$, ,$,$(,(,,((,,(,,,0,,0,,00,00004444444444444444488888884448884444448<88<8<<<<<@D@L<8Htp|408XTXTPTXTT`\\dd`d`\``\``\\\X``\``\hhdtpp|x||||и萌||||xt|||||||x|xt|tlxphtldtldxldxlhxlhtlhtlltpltllxll|tpxtpxxtxtxttxlllllllhhlhhh`dh`dhhdlhdlhhtpplddd\\h``l`dh`dh`dhddhddd\`l\hldlllppppplllhhlhllhlhdhhdhh`hd`dh`hd`dd```\X\XTXTTTPX\TX`\\\XTTTLPLHLHLHDHHDHDDDDDDD@@@@@@@<<<<<<<<<<<<8@<8@<<D<<D<@D@DHDDDDDD@D@<@@<@@<<<<8<<8<<@<<D@<@<8<888<8<D@DLLLPPPHDH<<<8488488484444404404448848444000,4,,0,(0,(0,,,,(,(((((($( ,$,$(,((((((((,,,,,,,,,,,,0,,0004444448448448888888<<<<<<8888888844848888<<<<D<8H0,<ddh@@DPLPTPPXTP\XX``\hhddd```\\\X`\X`\X``\hhdttp||||||||м쐌|x|xtx||xxt|tp|pl|lhxldxldxlhxphxphxplxppxppxplxplxtpxttttxtptplppppplllhhldhldhlhhlhdlhhtllh``d\\d\\h``lddldhhddd`dd\dh\dldlllpllplllphhphllhlldhhdhldhhdhd`dd`d`\\\XX\XTXTTTPX\X\d``\XTTPLLHDLHLHDHDDHDDDD@D@@@@@<@@<<<<<<8<<8<<8@<8@<<D<<D<@H@DHDDDDD@@@@<@@<@@<8<<8<<8<<@<<@88<848888@@@LLLLLL@@@<<<8884444444040000004404408448000(,,,4,,0,,0,,0,,,(,,(,((,, (,$,$,$(($($$$$(($(((((((((,,,,,00,4004004004008448888888<<<<<<<<<<<<48888<88@<8D84<TPX@@DHHHLLLPLLTPLXPPTTP``\pplhhd\\X\\X`\X``\dd`llhxxxxxx|||||xxxtxx|ptl|tpttdtt`xphxphxplxplxtpxtp|txxltxptxptxtxtptplptpttptphllhlldhhdhphhlhdplhtpph`\hX\l\dl\dh``lddlddhd`d``h`dhddldhlhhldhphllhhlhhpllplllhhlhhd`d\\`\\`\X\XX\TTTXTX\\\\\X\XTPPHPHHLDHLDDHDDHDDHD@D@@D@<@<<<<<<<<<<<<<8<<8@<8@<<HDDHDDHDDHDDD@@@<<<<<<<8<88<8<<8<88<88<848<8<HDDPHHH@@<<888884884844840000,00,40,4004040,0,(0000,,,,,,,,,,,,,,,((,((, $, ,$0 $0 (, ($$(($((((((((,(,,(00,40,40,40,00000040440444888<<<<<<<<<<<88@<8D@<H((0llt88<DDHHDHLHLPHLTPLXTPXTPlhdlhhlhh`\\`\Xd`\``\lhhppp|x||||x|xؼxtxxt||x|ptl|plxpdxp`xph|phxpl|tp|xt|tt|txxptxptxtxxtxtpttpttpttptplpplplhllhllhhtllxtttplld`l``l`dl`dl`dlddlddld`h``h`dhddhddhddldhphllhhlhltppplpplllhld`d\\\\X\XXXXTXTTXXXX\X\\XXXTPPLHLHHLDHLDHHDDHDDD@@D@@@<<@<<@<<<<<@<<@<<@@<D@<HD@HDDHD@HDDD@@D@<@<8<<8<8888888888<88<88<<8<@<@HDD@<<<4484044440440840400,00,00,0,,,,,0,,0,00,0,,,,,,,,,,,,,,,((((,,$(, $( ,$, $,(( ($$($$(($(((((,((,(0,,00,0,,00,00,0000,400444444848888888<8<<@<<@<8@004888<<@D@DDDHHDHHHHLHHTPLXTP\XTd`\lhdhd``\X``\hhd`\\lhhppp||||x|||tpp|x|||t|ptl|pl|pd|p`thtl|tlxtxxtx|txxtxxtxttxttxttttttxtxtptplpplpplpphlphlxtt|xtplhld`l\Xl``h``l``lddpddpddh`dh`dhddhddhddhddldhlhhlhlplptppplpplld`d\X\XX\XTXTTTXTX\X\\X\\XTTPLPLHLHHLHHLHHLHDHDDD@@D@<@<<@<<@<<@8<@<<@<<D@<HD@HDDHD@D@@D@@D@<@<<<<8<8888884884884888<88<<<<@<<<8<<88<4440040000000400400,00,000,00,,,,,,,,,,,(((((((,,,(((((((((((($(( $( ($($((( ($ $$$($$((((((((,(,,,0,,0,,,0,,00,00,,40044444444444888884888<<@88@|||888@<@@@D@@DDDDDDDHHDPHHTLL\XTd\Xh``phdhd`dd\hh`lldhhdppl|xxx|x|xpll|x||txltlllpdp`thtltpxtx|t||x||txxtxtttpptppttpttpttpttlpplpphllhlldhxtt|xxlhdld\l`Xld`hd`lddlddpdhtdll`dh`dhddh`dhddhddhddhdhlhhlhhpllpllpllhhh``d`\`\X\TPTXTX\X\`X\\TTPLHPLHLHHHHLLHHLHHHDDD@@@<<@<<@<<@8<@8<@8<D<<D@<H@@D@@D@@D@@D@@@<<@<8<88888884848848888<8@<<@<8<888<8884484040,0000000,00,00,,,,,(,0(,0,,,(,,(,((,(((((((,,,((((((((($$$$($ $( $$($(($ $$ $$$$$$($((((((,(,,,,,,,,,,,,,0,(,0,,00,0004004044488884888@84@88DLLPHDLD@DD<DD@D@@DDDDHHDPDHTHLXPL`TTd\Xld\lh`dd\hh`pphhhdhhdppl||x|x||plpx|tttpplphld|ph|tltpttx|x||x||x||t|xtxxpttpttppxpttpttpptpptplplhlhdldlxptxthd\h`Xh`\plhlhdldhpdlphlthhphdldhhddhddh`dhddldhldhhdhldhlhllhllhlldhh``d\`\X\XTXXTXXXXXTTTPPPLLLLHLHHLHHLLHHHHHDDHD@D@@@<<@88@<<D<<D<<D8<D@@DD@D@DD@@D@@D@@@<<@<<<88<88<88848844<8<@<<<888888448448444044040,00,0,,0,,0,,0,,0(,,((,,((($$(($$,$$(((((((((((($(($(((($(((,$, ,$,$($$$$($$($(($$($(($(,(,,(,,(,,(,,(,,,,0,,00,0000444444484888<84<0,4ddl84<D@HDDHDDD@@D@@@@@@DD@DDDLLHLLDPPD`\Td``hhdlhdhd`llhllhhhdlhh|xt|xx|ppp||||xxtxp|tl|ph|ph|ld|lhplttx|xt||t|xt|xtxtpttpptpptptxpttpptllpllplhphhphl|pttllh`Xd`Xh`\lhdlhdldhldhpdhphhtllpllhddhddldhhddhddhdhldhhdhldhldhhdhh`dd\`d\``\\XXX\XX\\\TTPPPLLLHLHHLHHHHDHHHHHDHDDHD@D@@@<<@88@<<D<<D<<D<<H@@DD@D@@D@@D@@@<<<8<<8<<88<88<88848848<88<8<4444444044444440000,00,,,(,,,,,,,,,,(,,((((((,((($$(($$($$(($(($$$(((($(($$(($$($ $($, ,$, $,$$$$($(($(($(,((,(,,(,,,,,,,,,,,,,,,,,,,00,0000000444444844<88@$$,HHP44<<<@@@@DDDDDD@@@@@@DD@DDDHHHLLHLLHXTP`\Xdd\lhdhhdhhdpplllhhddtpp||xx|ttt|||xxtxp|tl|tl|ph|ldxlhplttx|xx|xt|xt|xtxtptplpplltpptpttpppllpllplhplhtlp|ttphdh`\h`\h``h``lddpdhldhldhhd`lhdplllhhldhlhhldhhddh`dhdhhdhhdhh`dhdhh`dd\`d\`\X\\XX`\\\\\XTPPLLPHHPLHLHHLHDHHDHHDHDDD@@D@@@<<@88@<<D<<D<<D<<H@@DD@D@@D@@D@@@<@@<<@<<<88<88848848<88<88<88484444444444000,0,0,,,((,((,,,,,,(((((((($(($,((,$$($((($$($$($$$($$,$$(($ ($ ($ $$ , , 0$$0$$$$($$($$($(((((((((,,,,,,,,,,,,,,,,,,(00,00,00000000404448008\\d40844<4488<4@@<@@<DD@DD@@@@@DDDDDHHLLLLTPL\XT`\Xdd\hhdhhdllhttphdhhdd|||||x||xtt||||xtttpplplph|ldxphtpttx|||xxt|xtxxtxtlppllpllplltpptpppllphhlhdlhdxplxtpldhd\ld`pdhlddl`dl`dl`hldhhddhd`ldhphlldhlhhldhhddhdhh`dh`dhdhhdhldhh`dd\``\\\XX\XX```\\\XTTTLLPLLTLLPLLPHHHHDHDDHDDD@@D@@D<<@<<@<<D<<D<<H<@H@@DD@D@@D@@@<@@<<<8<@<<<88<88848<88@<<<88844484444044044,0,(,,,,(,((,,(,,(,,(((((($(($,($0((,$(,$(($($( $($$$,$$,$$(($ ,( ,( ($($$, 0$ 4$ 4$$$ $ $ $$ $ $$ (((((,((,((,,(,,,0,,0(,0,00,00,0000000444<,,4PPX40888@888<<4<@8<@8@@@DDDDDD@D@@@DHDLLHPPLL\TP\\T``\lldllhllhppllhlhdhlll||||x|tp||tttx|pxltlphphpd|phxpl|pp|tt|x|||||x|xxpxplpphllhlpllplttltplpphlpdlphlxpp|xxxpph`dlddldhphhphhlddhddh`dhdlhdhh`lh`hhdll`hl`hpdhpdll`hh`dhdhlhlhhh`\`\X\`\`\XX\XX`\\\XXXTPPLLPLLPLLPLLLHHHHDDD@D@D@@@@<@@@<<<8<@8@@8D@<D@<H@@H@@D@@@<@@<<@8<<88<88848888888888<8<8888448488444000,0,,,,,,,(,,(,,,,,,((($(, $, $, (( ,($,( ,( (( , $($( ,, 0, 0((,,,((($((($$( , 0 $0 $ $ $$$ ($ $$($(($((((((((,,((,($,0(,0(,0,04,04004448LHP88@88@44<888884<84<<8<<8D@<HHDDDDDDDDDHHHHLLHTTLXXPXXT``Xhh`hhdllhplhlhhhhhtxx|x|t|||||ttt|||xxptltlphphphlh|pl|pp|ttxxxxx||x||x|xptplpplllhhpllplptlptlptlpthlxlp|ttxppthhl`dlddpdhphhphhldhhddd`dhddd`hh`hldlldlldhpdhpdhpdhpdhpdlhdhhdhhdh`\`\X\\X\\XX`\\`\\XTPTPPTPLTPLPLLPLLLHHHD@DD@D@@@<@@<@@<<@<8@<8@<8D@<HD@HDDH@D@@@@<<@<<<8<<888888488488488488888888448044000,,,,,,,,(((,(,0,,,(((($(( (( $, $,((,( ,(,((($( (((,(00(40(0,,,((($$($$, , , 0 0 ( $ $ $ $$$$(($(($(((((((((,((,($,0(,0(,0,,0,,0,,4,00`hlx<HP08D04<88<884<88<<8<<8@@<DD@HHDHHHDDHHHHHHHPPHTTLXTPXXTd`\hhdllhtplpllhhhlpp|||𨰸ؼ༼||||xttp|||xxpxptlplplplpl|plppttxx||||x||xxxtttpppllplhpllpllpllplltlltllxlptxxlppddl`dlddpdhpdhldhldhldhd`dhddd`dl`hldll`dl`dp`dp`dpdhpdlthlpdhldhh`d`\`\X\XTX\X\`\\`\XTPLTPPTPPTPLPLLPLLLHHHD@HD@D@@D<@@<@@<<@<8@<<D<<D@@HDDHDHD@D@<@<<<<<<<888888488448448448448448444444000,,,,,,(,,,,(((,((0,(,((($ (($(($$( $, (( ,( ,( ,( (( ,,$,,(0,,,(,((,((($$($ ($ ( ( ( , 0 ($$$ $ $ $$$($((((((((((((((,((,($,0(,0(,0(,0,,0,,0000x|hth|,8D44<448844888<88<<<<<<@@@DDDHHHHHHHHHHHDLLDTTLXXPXXT``Xhh`plhtplxtplhdllhxxx|||||xttp|||xt|xxp|lhplplplppppttxxxxx||||xxxtptpppllplhplhpllpllplhtllxppxppttttpdhl`dp`dpdhpdlldlldhlhhhddhd`d``l`dpdhl`dh\\l\`p`dpdhtdlpdlldhl`hldhd`d`\`XTX`\\`\\\XXTPPTPPTPPPLLPLLPLLLHHLHDHD@H@DD<@D<@D<<D<8D<<D<@D@DD@DD@D@@D<@<<<<<<<8888884884448448444444444444444000,0,,,,(,,,,,,,,((0,(,($(($,,$,,($($$($(((,((,((,((,((0(,0((,,((($$(($$($$($ $ ( $ $ ( $($($$$$$ $$$$(($(($($(($(($(($,($,($,0(,0(,0,,00040,0\XXTX\(4DHXl(0D40<848848888<8<<8<<8<<<<@@@DDDHHHLLLHHDLLDPPHXTPXXT\\Xdd`ppltpltplpplhlhttpܸ|||tttl||xtxp|ldphtltltlxpxpxt|xxx||xxxtxxpttppplpplplhpllpllphhtllxlp|pttp|pplddl``phhphllhhlhdddddhddhdhddhddhddl`dl``hXXhXXt``pddphhphlphllhlh`h`\``\\\XT`\X`\\\XXTPPTPLTPLPPLLLPPLPLDLLDLLDHH@@D<<@<<@<8D<<H<@H<@H@DDDDDDD@@@<<8<<8<<8888844444444444440000400400400,,,((((((((((((,,(,, ,( (( ,((,(,,(((($(($(($,($,($,,(,,(,,(,($($$($$($$$$$$$$$$ $ $$ ( , , ( $( $$ $ $ $ $ $$$$$$((($(($,, ,,$,0(,0,,,,,,44<$(4<<D44DX`p$,<00<4480444888488888<<8@@<<@@@DDDDLLLHHDHHHLPHTTPXXT\\Xd`\plhtplllhllhhhdllhxxt|xpplhx|x|x|tplphplpltptpxtxt|x|x|x||x|xx|xxttppplpllpllpllpllthltllxlltt|plthhl``h``pdhphllhhlhddhddhdhhdhhdhddhdhl`dh``l\`h\\p``pddpddpddldhlhhhdhd```\XXTT\XX`\\XTTTPPXPPPPLLLLLLLLLLLDHLDHLDHH@@D<<D<<D<<D<<D<@D<@D@DD@D@@@@@@<<8<<8<8888444444444444444040040000,,,,,,(((((((,,((((((((( ,( ,($,((,$(($((($(($(($,,(,,(,,((($(( $$ $$ $$ $$$$$$$$$ $  $ ( , , ( $( $$ $ $ $ $ $$ $$$(($$(($,,$,((,(,,,,,0,,4 `htdTltP\hDPX(480084040444848448888<<8@<<<@@@@DDDHHHHLHLLHHLDPPLTTPXXT`\\hd`tpllhdllhplhlhdppl|||plhhddttx|||xtxttptppppptpxtxxxxxxxxxx||xxxxxxxxttttpppptppplpplptlltllxlltp|plpddh``l``phhphlphlpllllhhhdhhhhhdlddl`hh`hh`dh`dh``l`dpddpddpddlddldhhddd``\XXXTT\XX\XXXTTXPPTPPPLLLLHLLLLHDLDDLDDHDDH@DD@@D<<D<<D@<D@@D@@D@DD@@@<@@<<@<8<<888484444440444444044044444400,,,((($(($(((((((((((((($,($,((,(,($(($$,($(($,($,,(,,(,($($ $( $$ $$ $$ $$$$$$$$$ $  $ ( , , ( $( $$ $ $ $ $ $( $$ (($$(($,($,(,,,,,0((8 84@Xh|d,HT(4@ ,0(44,040040444444448448888<<<<@<<@@@@@DDHLHHLHHHDLLHPPLTTP`\Xhd`plhlhdphhtpllhhplh|xxplhpllxx|||||xt|xtxtttttttttttxxxxx|xx||||x|xxxxtxtttxtxxtxtltplptlltllxlhtptpthhh``pddthltlpphhpllllhhlhhhdhhdldhldlh`hh`hd\`h`dh`dpd`phdphhphhlddh``d``\XTXTT\XX\XXTPPXPPTLPPLLLLHLPHLH@LH@LDDHDDH@DD@@D@<D@<D@<D@DD@DD@@D@@@<<@<<@<8<<88848444444044444404404444400,,,(((($(($(($(($(($((((($,((,(,,(,,$,,((,($(($,,(,,((($$$ ($ $( $ $ $$$$$$ $$$$ $ $$ ( , , ( $( $$ $ $ $ ($($$ (( $($$,($,((,0(,8$(D4@`\tLh,H((@4(<408(00,44,000444444448448888<<8<@8<@<@@<@@@HDDLDHLDHLDPPLTTPXTPhd`lhdplhphhtpltlltllxtppplplp||x||x|xxxxxtxxx|||t|x||||x||x||x||x||xxxxxtpttpttpttlpxlptllttxpxlll`dpdhtlltlltllpllphhplllhhlddldhldhhddh`dd``h`dh`dlddlhdphdlhdlhdhd`d\\\T\\X\`X\\T\XPXTPTPPPPLLPLHPLHLD@LD@HD@HD@H@<D@<D@<H@<HD@LD@H@@H@<D<<@<<@<8@<<@<8<44804800<004,,40,44004000,,,(,(((($$$$($$($$(($(,$(, (( (($,(((($(( ,, ,,(,,((($(($($$($$$$$$$$$$($$($ ( $ $ $ $ ( , 0(,$( $( $$ $($$( $( (($$($$,($,,$,(,0,((0DLXd$<T,,80,84,44,4000,4,,40040044444444888<88<<@<@<@@<@@@DD@DHDHHDHHDLLLPPTPPTdd`hh`lhdlh`pldtphplhtpp|||x|x||||t|x||||||||x||||||||ttttpttlpxlpthl|ppxxtpxplpddldhtlltlltllphhphhphhphhlddhddhddhddh`dh`dh`dd``hd`hddlddlddlddh``d\\\X\`X\`X\\TXXTTTPTPPPPLLPLHPLHLD@LD@H@<H@<D@<D@<D@<HD@HD@LD@H@@D@<@<<@<8<<88<88884844404404004,,400000000,,,,((,(((((($$,$$,$$(($(($(, (((((( (( ((,, ,,$(($$$ (($($$($$$$$$$$$$( ( $ $ $ $ $ $ ( ($0$, $, ( $$ $( $$ (($(($(($((((((,,((($4,0,,8@L\\p|$,<,,4,,40,40,0000,00,400400440440444448888<<<<<<@<@@@@D@DH@HH@HHDLLLLLLLLLTTPd`\hh`pldpldpphtpltppļllp|||||||x||t||x|||t|x|||||||||xxxxxx|xxxtxtltplptlptll|tt||txlllddthlxlpplhplhphhlhhlhhlhhlhhh``hddh`dh`dh`dh`dd``hddhddhddhddh``d\`d\\`X\d\\`\\\XX\TX\TTTPPPLLPLLPLHPHDLD@H@<H@<D@<D@<D@<D@<H@@H@@D@<@@<<<8<<8<<88<84844404408444004,0400000,00,,,,((,(((((,$$,$$,$$,($,($(( $$$$((((,, ,,$(( ($ $$ (($($$($$$$ $$ $( ( $$ $ $$ $ $ $ $ $$($($,$$,$ ($ $$$$$$ $$$(($((((($(($,(((($00,0$,,$,DLPHPT,,0(,0,,0,,0,,0,00(04,40040044044040444844888888<<<@@<@@<@D@DH@HHDLLLLLLLLLPPL``Xlh`lldll`pldxtptpp|tlhph`hd\lldx|tttxt|xxxt|xt|xx||t|x||||||||x||xx|x|xtxtpttlptlpxlpxthhpdhtlpxpttllpllphhlhhlddlddlddhddhddh`dd``d``h`dh`dhdhhdhhddh`dd\`d\`d\\`\Xd`\d\\\XX\XT\TTTPPTPLTPLPLHPHDLD@H@<D@<D@<D@<D@<H@<HD@D@<@@<@<8<<8<<8<<8888840400800<004,,8,04040,0,,0,,0,(,0(,,((,$$0$$,$$0($,($($$(($(( ((,,$,,((($(( ($ (($(($($$($$ $ $$$$ $( $( $$ $ $ $$ $ $$ $$$$$$ $, ($ (( $($$$$ ($ (($,($($(($(,$,0($($0,,0,0\dd(0,0,,(,,(,0,,0,,0,00(04(44040044044000000444448888<<<@@<@@<@D<DD@HHDLLLHHLLLLPPLXXThh`lh`xtlpldxtptpp|xxtl`tldthhpdhh\htlx|xx|txt|p|ptpp|pl|tp|x|x|x|x|xxxx|||||xx|ttxplxpp|pp|x|x|pptlhtplxtpxppxllphdpddpdhldhldhldhldhhddh`dh`dd``h`dh``l`dl`dhddhdhd`d`X\`X\d``d``\X\XTTXTXTTPTPLPPHPLDLH@HH<HD<H@8H@<H@<H@<H@<LD@L@@D@@@<<<<88<88<84844404008008008004004000,,0(,0(,,((,((,((,($,($,($(( (( ,($,($,($,($,((,($,($(($(( (( ($$($($ ,$$$$$$$$$ $$ ($ ($$($($ $$ $$ $$$($, $($$$$ ($ ($($ (($(($((((,(,,((,,(,,,,HLLPTP(($0,,0,,0,,0,00,0004004,0000,04,44,04,,4,,840444848<8<@8<@<@D<@D@DDDHHHLLHLLHPPLTTPd``hddtpppllplltppttlļtpdtldxlhthlphptpxxxxt||x||xxxptxlp|ltltt|||x|x|x|||||||xx|tt|pptt|xxtxpltllxtpxttxptxpptllthhphhldhldhldhhddhddhddhddhddhddh``h``hddhdhhdhd`d\X\`X\d``d``\XXXTXTTTTTPTPPPLLLHDHD@HD<H@<H@<H@<D@<D<<D@<H@@H@@D@@@<<<<<8<88840404408008004,,4004000,0,,,,(,,(,,((,((,((,($,($,((,($,($,($,($,($,((,($($$($$(($(($(($$$$$$($ ($$ $$ $$ $$ $ ( $($($ $$ $$ $$$($, $, $$ $ ( $($$(($(($,,(,,((,(,,,,,,(,404000`dd8<8,,,,((0,,0,,0,00,00,4,,4,04,0004,44,440080,840444848<48@8<@8<D<@D@DDDHHDHHHLLHLLLPPPd`\lhdllhtplplhxtpttl|tthxth|tlxpptpppptxxx|xx|||x|t||lxxlt|pxx||x|x|xxxx||||||xx|pp|x|xtxpltplxtpxtt|tt|ppxplxlltlllhhldhldhhddhddhddldhldhldhhd`h``hddhddddd``dXTX`\\d\``\\\XXXXXTTTTPTTPPPLLLHDHD@HD@D@<D@<D@@HD@HDDH@DH@DDD@D@@@@<<<<<888840404408008004,,400444000,(,((((((((((((,((,($,($0,(,($,($,($,($,($,((,($($$($ $($$(($$($$$$$$$$$($ ($ ($ $$ $$ $( (($($ $$ $$ $$$( $,$(,$$( $ $( $( $$$(((((,((,(,,(,,(,,004,(0HHP`dh,000000,,0,,0,,0,00,0,,0,,0,,4,0400000,04,080,840440844848<88@8<@8@@<DD@HHDHHHHHHLLHPPL`\Tlh`hh`tplplhxtpxxp|xxl|xlxtxttppttp||x||||||||xxxxt||||x|x|x|x||||||xxt||||x|ppxpp|xt|tt|xx|pp|ppxpltllphhldhldhldhhddh`dhddlhhhddhd`d``hddhdhddd``dXTX`X\d\``\\\XXXXXTTTTPTTPTPLPLHHHDDHD@D@<D@<D@@DDDHDDHDHDDDDD@@@@@@<<<8<888844444408008,04,,40000,,,,,,,(,(((((((((((((,($,($,((,($,($,($,($,($,($,($,($($ $($$(( $( $($$$$( ($ ($ ($ ($ (( (( (($($ $$ $$ $$$( $,((,$$($$ $$ $$ $$$($(,(,,(,((,((,((,((,0,8TT\48<,040000,00,,0,,0,00,0,,0,,0,,4,,800400004,,4,,840840844848<48<8<@8@@<DD@HHDHHDHHDLLHPPL\XPhh`lh`xtltphtpl|xtxļļtpxt|txttpppl||||x|xttpllplhxpp|ttx||||||||||xxxxxx|||ppxpt|txtxtt|ppxptxpttlplhlhhhlhhphhpddlddl`dpddh``h\`d```dd`dddddh`dXPT\XX`\\`\\`\\\XXXTTPPPPPPPLLLLHDD@DD@D@<D@@D@DH@DHDHHD@HD@D@@@@<8<888488484440084040040,40,40,00,00,,,(,,(,($(($(($,($,((,((,((0((0$,,($,($,($,($,($($$($$($($$$$ $$$ $$ $$ ($$($$($$,((($$($$($$$$ $$ $ ($$( (,$(,,,,((,((,$$0($4$$0((0((0((0((0((0((484DTT\,(0,,00,4,(4,,,,0,,,0,,0(,0,,0,,4,,4,04,00,40,440844444444808848<8<<<<@<<D<@D@HHDHHHLLLPLPXPTd``llhllhxtlpld||xxxpxtxt||t||xttpppl||xxxttxtpxtpxplxhlxhpxtx|||x||||||||xxxxxt||xtpxppxppxpptlplhllhhphhphhpddpddl`dh``h\\dX\`\`````dddddd\`XPT\XX`\\`\\\XX\XXXTTTPTTPPPLLLHHDD@D@<D@<D@@D@@H@DHDHHDDHD@D@@@<<8<88848448448448404000,,40,40,0,,,,(,,(,,(,($(($($ ,,$0,(0,(,((0((0$(,($,($(( ,($,($,((($(($($$$$$ $$ ($ $$ ($$,$$,($($$(($($$$$ $$ $$ $($ (($($,((,$(((,,04804<44D44D@@L@DL<<H44@88D44@PT`DDP((0((0,(0,(4,,0,,,,,0,00,00,,0,,0,,4,04,00,00,400844888848848848<8<<<<@<<D<@D@DHDHHHLLHPLLXTPd`\llhlldxxptph||txxtxxp|xt||t||xxxtplh|xx||xxxtxtp|tpxtl|llptx|||||||||||||||||xxxxxx|x||||xtp|tttpptpptlpphlldhphlphhphhphhphhh``d\\`\\`\\d``dddhdd\X\TPP\XX`\\\X\\XXXTTXTTXPTXPTTLLLHHH@@HD@DD<HD@H@DHDHHDHLHDHD@H<@@<<888844844<448444000,,0,,4000,,,,(,,(,,(,,(,,((($(($,,$,($,($0($0((0$$,($(( ($ ($$,($,((($$($$($$($ (( ($ (( ,$$,($,($($$(($$( $$ $$$$$$$($ (((, (0048DHHHLL@DH@DL@DTHHXPT`PP\PT`\`lTXdTT`X\lHLXHHX88D((4((0,,0,,0,,0,,0000000,00,,4,040000000004448888848848848<8<<<<<<<@@@D@DDDHHDLLHPLHXPLd`\hl`lld|xltpd|t||x|x|xp|xpxxpxxt|xtphhxtt||||||x|xt|xtxt|ptpxt|x|x||x||x|xx|xt|||||||||||||||x|xx|x||||xxxx|xxtpptpptlpphlpdhphlpllphhplllhhhddd```\``\`d``h`dhdd\XXTPPXTX`\\\X\\XXXTTXTX\TXXPTTLPPHHHD@LD@HD@HDDHDDHDHLHHLHDHD@H<@@<<<88844<44<0480040040,40,4000,,,,(,,(,,(,,(,,(,,(,,$,,$,,$,($0,(0($0$$,( ($ ($ ($$,($($$$$ $$ (($,($(( (((( ,$ ,$ ,( (( $$ $( $($($($$$$(($(, (0 (08<@DLL<DD8<@<@H@HTDHXLP\PTdX\llp|lp|\dpPXdLP`PThPP`@@L44<,,0,,0,,0(,,,0,000,00,,4,040000,04008044444444808848<8<<<<<@<@@@D@DD@HHDLLDLHDTPH`\Thh\ll`|pxth|xp|x|xļ|xt|xt|xt||t|xthd`pphxxt|||||||||xt|xp||l|l|tl|xp|x||||||xtx|ttxx||x|x|||||xx||xt|xt|xt|xxtttlllplplhlpdhthlthltllxlptllpdhh``d``d\`h`dhddd```\\TLP\PT\X\\X\\XX\TX`TXXTTXPPTLLPHHLDDLDDLD@LHDLHDLHDHHHHDDDDD@@<@<8@44<448444404404,,4,,8,,8,00,,,((0,(0,(0,(0,(0,(,,((, ,, ,,$0,(0((0$$,$(,((($$($ ($$($$$ $$(( (( ,( ,( ,( ,$ ,$ ,((($( ($ (, (, ((,444@@ ,0(404<<<L<@P8<P88H88D4<<<DHPPdLLdd`xdhx`dpTX\HLXLL\XPd`XhDHTHPT<@D,04,,0,04004,00(0,,0,0004004008044444844844848<4<@8<@8<@<@@@DD@HHDHHHLLHLLHXTPld`pd`xph|tltpl|x|tȼļ|xt|xt||t||t|xhd`dd`pplxxt|xtxx|x||x||||x|xt|xp|pxl|tl|xp|t|x||||||tx|ttxttxtt|xxxxxxxx|||xx||xx|xt|tt|tt|tttpppppppplhllhhthltlltllxpptllpdhh``d\`d``ldhldhh`d`X\XPP\TX`\\\XX\XX\TX`TX\TTXPPTPPPLLLHHLDDLDDLHDLHDLHDHDHHDD@@D@@<@<<@48<488444444000,,4,,8008000,,,((0,(0,(0,(0,(0,(0,(,((,,(,,(0((0($0( ,$$($(,($(( ($$($$($$($ (( ($ ,( ,($,($0$$0$ ($($$( $$$(,,088<@LPTLTX (0 (4<@H@DP8<H<<LPP\lpxx||@<@80@@8LXPd``httxtx``h`XdLHTHPTDLPLPX<DH048,04,,4,04,00,00,00000404844444444484484884<<8<@8<@<@@@DD@DDDHHDHHDLLHXTPhd\phdpld|xlplh|x|t|ȼ|x|x|x|x|d`\XXTdh`plhxppttxx|xt|x|xtxtp|tl|tlxph|ph|th|xpxt|x|||||xxxxx|x||txxxxxxx|||||||||tttxtx|tt|ttxpttllllllllllllhlphltlltllxppxppphhl`dh`dh`dldhldhhdd`X\\PT`TX`\\\\\\XX\XX`TX\TTXTTXPPTLLLHHLHHLDDLHDLHDLHDHDHDDD@@@@<@@8<@8<<4884444400000,40080040,,,,,,(0,(0,(0,(0,(0,(0,(0(,0(,0((0((,($,( ,$$($(,($,($($$($$,$(,($($ (($,($,($,($0((,$$($ ($ $$ ($(0,4@<HHDLLLPTT\,,8$(88<HDHLPT\PT\<@D,,8 0,04,4<0<\Td808,,,(,0@@HXT`TT`\hlDPTHPX@HP<@H04<,08,,4004004,,00,00044044444444444848848<8<@8<@<@@@DD@DD@HDDHHDHLHPPL\XTlh`hd\xtltpl|xpt|ĸxx|x||txd`\``Xdh`hd`xll|pp|pp|pp|tpxtpxplxlhxphxphxpdxthxth|xp|x||||xxxx|||x|x|||||xxxxxx|xt|x|txtx|px|pt|pt|ptxlpplllllllllhlphlthltllxlptllpdhh``d``d``hddlhhhdd`X\`TXd\`hddddd\\\\XX`TX\TTXTTXTTTLLPHHPHHPHDPHHLHDLHDHDHDDD@@@<<@@8<@4<<4884840404000,00,4,,,,(,,(,,(0,(0,(0,(0,(0,(0((0,(0,(0((,((,((,$(,$(,((($$(( ($$($$,((($$($$,($,($,($,$$0((,$$,$ ,$$,((0,0<4@@8H84@<<D@<H,(8,(<HHTDHL488$(($((,,4(,4,04004848@<DLHL44840800<0,<0,<00<HT\\dlP\d4<D8@H4<D04@0080,4,,40040040040040444444444848848<8<@8<@<@@@DD@DDDHHDHHHHPHPTL\XTlh`hd\txlttp||ttxĴ̼ȼx||||||||lhdtlhxtpxttxx|xtxxpp|pp|pp|pp|tpxplxlhxphxldxlhthdtlh|xp||tx|xxxxx|||||xxtxxtttpttpxttxttxxt||||||tx|tx|pt|pp|pp|llthhphhphhlhhlhllhltlttltpdhh`dh\`d``d``h`dhddhdd`\\\XX`X\d``d\``\\\XX\TX\TT`XXXXTPPLTPLTLHTHLTHLPHDLHDHDDD@@@<@<<<<888848444404000000,40,40,40,00,,,,,,,,,,(0,(0,(0,(0($0,,0,,0(,,$$,((,((,($,($,($(($,($4((4((,($0($0($,$$(($$($,$(($$,$$,((4,4D@LPH`D@P8<<<<D,,@ $8((80,80,4,(00,0,0,,0,,40,40,40044HHL<<@40840<40<40<00800800<48@LPXLH\84H44H48H04@0,8,,8,,80080040004040440840840884<88<<<@<@D<@D<DD@DHDHHHLPHPPLXXPdd`lldtphxtpxtptxxx|||xtpplhxxt||||||||xxxt|tp|pp|tp|tpxphxphxhdthdpd`pd`|tl|tpxtxtxtxx||xtxtpxtpxtpxttxttttpppl||x|xxxttxppxpl|ppxplphhlhhlhhlhhhhhlhhlhhhd`d\\`XX`\\d\`hddldhldhd\``X\`\\h`dd```\\`\\`X\`XX`XXXXTTTPTPLTLHTHLTHLPHDLHDHD@D@@<<<<<8<888844404000000000,00,4,,0,,,,,(,,(,,,,,,0,(0,(0,(0($,((,,(,($(($,((,((,($,($,($,($0($0((0((,($0($0($,($(($$( $$$$(((((,,0<<DHHT<<L\\h@DD8<D04H $8$(8((4,(40,40,0,0,,0,,0,04444488<HHL004448004004004004044044,4<04@LL`LH`88L8<L88D44<,,8,,8,,4,04,004040440840840884888<<<@<@D<@D<DD<DHDDHHHLHHLHTTPdd\lldpphxtpttlxxȼԸ||x||x||x|x|ttlhhxxt||||||xxxttxttpxphxphxlhxlhthdp``xlh|pl|tpttttxx||||||x|xt|ttxtpxtpxtptpptlltllxpp||||xxxtptplpllpllplllhhhdhhhlhdhddd`\`\XX`XX\XX`\\h`dhddhddd\``X\`\\h`dd```X\`\\`\\dX\`XX\XXTTPTPLTLHTLLTLLTLHLH@HH@D@<<<<<8888888444040040000,0,0000,,0,,,,,(,,(,,,,,,0,(0,(0,(0($(, ,,$(($(($(((((((((,($,($0($0((0((0($,($0($0($,($(($$( ( $($,,0448D@HD@HLHPPTT<D@PX`,0H$8 (4,(4,(40(00,0000,40000444888@@D<<@448408040000,40,00,40,40,4<,0<84DHHXPP\8@D@DL8<D,0<(,8(,4,04040404044084,840844888<8<<<@@8@D<@D<DD@DHHHLHLLHXXPdd`pphtphxxttpltt||ĸ|||||x||xtxxttpll||x|||xttxt|tp|pl|tl|pl|plxhdtd`td`|pl|plttxtx|xx||xxxxt|xt|tpxppxpp|tt|ppthhxlp||xltthlphltpp|x||xttppllpllhdd`X`\\h``lhhpTPXLHPXPX\TX\XX`\\h`dh`d`\\\XX`X\d``d\`\XX`\\d\\dX\`XX`\X\XTXTPXPLXPLXPLXPHPL@LH@D@<<<888888888844444044000,00,000,,,,,(,,$,,(,,,,,,0,(0,(0,(0,$(,,, (, (($(((((((((,($0($0$$4((0((,($,($0($0($,$$(($$($(,$(,(448LDPH<LH8D```DH@dlh$,4$(@$8 (4,,40,40,44,0000,40440804<88D@D448448048048048048,44,44,480880480084488<<X`X<DD8<D04@,4<(08,04044404044084,440844888<8<<8@@8@D8@D<DD@DHDHLHLPHTTPdd\lldpphxtptpl|px|xĴ||x||x|||||||||xtttpl|x|||txp|xl|tl|ph|thxpdxpd|tlxtxx|xx|x|||xtttpp|||x|xt|xt|xt|tpxplxtpxtp|tpxhhxhhxx|lpxllthlpdhldhlhltpp|xx||xtthdhLHP@@XH@TddlX\d84DL@TTTTTTT`\\h``d``\\\XXX\XXd```\\`\\d```\\`\X`\X`\X\XT\TT\TT\XTXXPTPLPLHHD@D@<@<8<8484484440084084040040040,0,,0,(0,(,,(,,(0,(4,(0,(,($,,$(, (, (($(($,$(,$,(((,((,((,((,($0($0($0($,($,($,($(($(((,(,0,4D8HL@T@8DLHL\`\T\\ $,((4$$4 (4$08,,00,0,,,000040040444888@@@<<@84844844808404404404804804844<44<44<44848<<<DLLT84H48L8<H,44,0000<004044,44,400848848<<8<<<@@@@@DD@DD@DH@HLHLPLXTTd``lhdtldxpltpl||t||||ļļ|||||x||x|||xxttpl||x|txp|tp|tltl|th|th|pxx||x|||||x||xxxtxxt||t|xt|xt|tpxplxplxtp|tt|pp|pp|ll|||x|pp|ppxlpxppthlldhh`dd`dlhhxxx||txtdllPP`XXtdlDL\84@LPLTTT`XXd``d``\`\\XX\XX`\\\XX\X\d```\\`XX`XX`XX\XT\XTXTP\XTd`\PPHLLDD@<@@8@<884484484440040040040040040,0,,0,(0,(,,(,,(0,(4,(0,(,($,,(,,$(( (( (($($$($((((,((,($,($,($,($0( 0($,($,($,,(,(((((,,,@<DH@PH<P@8DXX\TTT048008$(4$(4$(4(08,,00,0000000444444444<<<DDD88<84844844848404404804804804844844844844<048004HHTLLh8@\8DT4<@(04,08004048,44,4408488488<8<<<<@@@@DD@DD@DD@HLHLLLTTT`\\lhdph`xphxtl||t||x||t|x|ĸȸ|xxxxxxxt||x|xxtpl|||x|txpxtxpxlxh|ptx|t||t||t||x|||xxtxtptplxtpxplxplxtpxxttxx|ppxx||tp|tp|tptllplhphhlddh`dd`d```XXXdhd|\\lPPpp|\hx448HLHTPPXTT`XXd``\`\\\\`\\`\\\XX\XX`\``\\\XT\XT\XT`XX`\X\XT``X\XTPLHHH@D@<@<8<848448448404004004004004004000,,0,(0,(,,(,,(0,(4,(0,(,($,,((,$(($($ (($($$($$(($,($,($,($,( ,( ,$ ,($,($,((,($(($((((,,LHP<8HH@T@<HPPT@@@,,0,,4(,4$$4$(4,,8,00000040444448848884<<<DDD88884844844848448404848804804844844844844888<448(,4HH\DLh@H\<DL08<,08008048,48,4408488848<8<<8<<@@@@D@DD@DH@HLHLLLTTT\XXlhdlh\tldxth||px|pxxp|xļļxxtxxx|xx||x||xtpp|x|||x|txp|tttttlxh|ltt|p|txtxx|||x|x|xt|xxt|tp|tp|xtxx|ppxhhxxx|pl|tpxtptplplhphhpdhh`dd``d``PTP8<@D@PLH\``txT`h88@<<<HDDTPP\XX`\\\\XXXX\XX`\\\XX\XX`\\\X\\XT\XT\XT\XT`\X\XT`\X`\XLLDLHDD@<@<8<848448448404004004004008404000,,0,(0,(,,(,,(0,(4,(0,(,($,,((($(($(($(($,($,($(($,($,($,( ,( ,(,$,( ,($0,(,((((((((044DDL<8DLHXXXdLPP,,,0,0008(,4$(4((80,8,0,040444444848<4<888@@@<<<44884884<88<484484488488488048444444444488444044444004TXlDH\@DP8<D40<008048,48,4804888848<48<8<<<@<@@@DDDHHDHLHHLLTPPXTTld`ph`tpdtpdx|pxxpttl|xļxttxxtx|t|x|ttp|x|||ttpxptptppltpxt|p|t|x|xxx|x|xxx|||xttp\\|dd|x||pptttt|tptplthhthhpddld`d``TTXHHTDDXLL`hplp@<L<8H@<8840400H@@XPPXTXXTX\XXXXXXXXXXX\\\`\\`TX`TX\TT`TT`XX`TT\XTXTPPLHHD@@<<<88<8488084084040040040440440040,00,,,(,,,,,(0,$0($0($0($,,$(,$((((((,((,($,($,($(( ,(0, 0, 0, 0($,$ ,( ,( ,,$,,((((((,DDHHHL84<LHPXX\0044,44,4,04$,8 (<((800004,0400404848888<<<<<@D@88888<88<88@88<8<888848444844844844844844844844844844800848<T\\8<D<<L84H00<048044484044488888<<8<<8@@<@@@DDDDHDHLHLLLTTTTTThh`ll`pl`tplxxpttptplxx|xt||x|x|xtp||x|t|tltptptlpltptlxp|t||||||t|t|t|x|||||||ppllxxxxxtxttt|tpxlltllxllthhlhdhdd\\`XT\ddp`dllpxPTX<<@HDHL@DH@@D8@804<08H@HXPTXXXXXXXXXXXX`\`\X\\X\\XX\TX\TTd\\`XT\XTXTPLHHHD@@<<@<8<8484484084040,4000,040440040,00,,,(,,,,,,0,(0($0($0($,,$(,(((((($,($,($,($,$ (( ,(,, 0, 0( 0($,$$,( ,($,,$,,(,,,88<TPXD@DTPTHDL4044044,4404,04$,8$(<(,800004,440484884888<<<@@D<<D88<88<8<88<88<88<<8<<48848848<48<44844844844844844840844<048DPLTd`0<<<DL04<048044484044488888<<<<<<@@<@@<@D@DD@HLDHLHPPPXTTdd\lh`tldxtlxxpppltpl|t|̼̼|xx||x|xxtx|tx|tltlxlxlxltlthxlxt||x||||||x|txtxtxx||||||tt|xxt|xxttt|tpxplxllxllthhphdhhd```\\`TTXTTT\\\LPLLHHHD@PHHPLLPHLPHPH@H@8@@8@@@DLLPPLPHDHPPT\X\XTX\TX\XT\XTd`\\XT\XTTPLLHDHD@@<8@<8<8484484484040040,0,,40440040,00,,,(,,,,,,0,(0((0((0((,(((,(((((($,($,($,($,$ ,( ,(,,0, 0( 0($0$$,($,($,,(,,,,,0HHLD<H<8@XT\H@H400400804404,04$,8$,<,,<000440880884<<8<<<@@@HHL88@8<@8<<<<<<<<<<<<<@<<@88<88<88@88@48<44844844844844888<44<048 ,(P\\HTT@HP<@H04804448404448888<<<<<<<@@<@@<@D<DD@DHDHLHPPPXXT``Xhh\tldxxpttpllhttptȴĸĸ|xt||x|||xx|t|xltlxlxlxltlxlxlxp|xt||||||xtxptpttxt|x||tt|x|x||xxtttp|pl|lpxlltllplhlhhhhhddh\\`TTXLPPPPPPLLTLLPPLPTLTTPTTPPTPLPLLLPD@H@@D@<D@<DD@HLHLTPTXTTXTTXXT\\XXXT\XTTPLLHDHD@@<8@<8<8884884484040040,00,40440040,00,,,(,,,,,,0,,0((0$(0((,(((,(((((($(($,($,($,($,( ,, ,(0, 0( ,$ 0($,($,((,(,,,,((0LLT@8DPDT`XdPHL800800804404,04$,8$,@00<440880884884@<<D@@HDHTTT`d`@@@<<@<<@<<@<<@<<@<<@88@88@88@88@88<48<44844844888<88<44<088088$(444D@<T88D04804448404448888<<<@<<<@@<@D<DD<DH@DHDHLHPPPXXT\\TddXtldxtlppllphxtp|xt|x|xx||pxlxpxpxpxpxptttt|xp|xt|tt|pttptppptptt|x||||xt|tpxtp|ppxlpxlpphhldhlddhhdhh`\\XXTTXTPXTPXTPXTT\XX\XX\XX\\XTTTTTLXTLXTPTPPPLPPHPH@HDDHPPTPPPXXXTTTXTX\TTXPPPHHLHD@84<80<84844440040440440400804804400000,0,(,,00,4,(0,(0,(,(,,(,((,(((($$(($,,(,($0$$0( 0( 0( 0( ,(0( 0( ,($,((0,,,,0408LLT84@LLXX\`<@@444800840004((@((@,,8444844<88<88<8<@<@@<@@@DDDDTTTTXX<@D<@D8@D<@D<@H<<D<<D<8@@8D<8@88@48<04<04<44<44<44844448804<48@<<HLLTDLP4<<,4408808408448888<<<<<@<@D8DD<DH@LHLLHLPPLXTP\\Xd``pldtphtldtld|tlxp|x|xtt|xptltlxpxpxpxptptl|tp|xt|xt|tp|tp|pl|lllltpxt|x|||tt|ttxtp|ttxppxppphllhhlddhhdhhd``\`X\\XX\XT`XT`XXd\\d``d``dd`\XX\XT`XT`XT\XT\XXXPTPHLL@HH<DLDLLDLHHLDDHD@DHDDHDDHD@<88<84<84844444440440440400804804400000,,,,,,00,4,(0,(0,(,(,,(,((,((((($(($,,(,($0($0( 0( 0( 0( ,$ 0($0($0,(,,(0,0,,0HHL@@H84@hhpddl,,0400440444,08((@((@,,4844<48<84<84<<<<<@@<H@@L@@HHHHPPTPTX@DH@DH@DHDDH@@D@<D<<@@<@<<@8<@48@44<44<44<44<44844848808804<<<DTP`PT\@DL0480480880884888<8<<8<@<@@<DD<DH@HHLLLHPPHTTP\\Xdd`pldtphtldtldxp|ȼxt|x||tt|xpplpltltpxpxpxptltp|tp|xp|xt|tp|pl|lhllpptpx||xxttxx|xt|ttxpptpppllllhhhhhhdhhd````\``X\`X\`XXdXXd\\h``lddlhdd`\`\X`\X`\X`XX`\X`XX\TTXHPL@DD8<@<@D@D@@D<<<@<@D@DD@@<888848448448440404404404004044444000,0,,,,,,4004,,0,(0,(,((,(((((((((($(,(,,(,($0($0( 0( 0( 0($,$ 0$$,((,,(,,(,,0(,0\`h<@H<@HdhpLLT408844440044(0<(,D(,@044<44@48@<8@<8@<@@<D@@LDDPDDPD@LHDTTP`DDTDDTDDTHDLDDLD@H@@H@@D<<D8<D8<@48@48@48<44<44<44848408408888DPL`LL\HHX88D44<4484484848<8<<8<@<@@<DD@DHDHHHHLDLPDTTLX\Tdh`pldtpdtpdtldxp|tĸx|||tt|tltltltlxp|tt|pxptptp|xpxtl|tp|plxlh|lh|plxplx||txxx|xx|xx|ttxttppllllhhhhhdhhhddhh`hd`dd\`h``h\`h\\l``lddlddd``d`\d\X`\Xd\Xd`\d`\`\XXXPTTLPPHHHDLLHLLDLLL@<D@<@@<@8888444004004400004404404004044444000000,,0004004,,0,,0,(,,(,,((((,(((($,,(,,(0,(0($0( 0( 0($0($,$$0$(,(((,$(,(,,,048X\d48@X`hTX`408808844440,04$,@(,D,0@484<84@48D<@@<D@@D@<HDDLHHPLH\LD`HD`XPlPHhLHhLH`LHXHDTDDTD@P@@P<<L<@D8<D88@88@48@44<44<44848408048844@HD\PLdTPd84H44@44<4488848<4<<8<@<@@<DD@DHDDHHHLDLPDTXLX\Pdh`pldpldtphtldtp|t|x||xxltltltlxp|t|tx|x|t|txptp|plxphtlhtlhthdtlhxtxtx||x|x||xx|xxxttttpppphlhhhhphlphlldhhddd``d``d`dd`dhddhddlddlddd`Xd\Td\Xd\\h``h``h```\\\XXTPPPLLPLLPLLPPLHD@@<<8884040,40040004080480440800804444040000000,00004044000,,0,(0,(0,(0,(,,$,( 0, 0,$0($0$(0((0($0($,$$,$ 0$$0($0,(,,(,,0@@HD@P@8L\`pPT`008848848444(,<(,D,0@88@<<<<88@<<@@@@DD@DD<@HHHTPH\H8`8(X0$T80h\T0$p0 p@,hH8dH<XH@\HD\@DPD@L@<D<<@88@48@44@04@44@44<48<04<44D@@PLPdPTlDDX44D44<4444848<88<8<@<<D@@D@DHDHHDHHDHPHPTLXXPhd\tpdxpdxldxldtp|x|x|x|xptltltlxp|t|tx|xxtxptpxplxpltlhtldthdthd|tp|t|t|||x|xxxx|xxxttxttttpllllllpllplllhhhddh`dh`dd`hhdhhddlhhlhhllhhd`h`Xd\\d\`h``h``h`\`\\\XXXTTTPLTLLTLLTTPPLHDD@@@@88844800400000000400404444044040,00,00,00,40,4444000,,,((,((,((,,$,($,( ,( 0($0($0$(,($,($,($,$ ( ,$ 0($0,(,((((,LLT40@H@THP\HLX408848848004(,8,0D8<LPPXLLT<8<@<DDDHDHHDHHHHPHDXH@\H<XXlp؈|hh<<0044XDDPHDTHDT@@L<<D<<@8<<48<48<44<48<48<48<48D48HPXlLTdDH\,4@08<0844848<88<8<@<<D@@D@DHDHHDHHDHPHPTLXXPhd\tpdtpdxldxldxp|||||ttltlxpxp|txx||xtxptpxtlxplxpltlhxlhxlh|tl|t|t|x|x||||||xxxtxt|ttxpptptplplhlpllplllhhh`dh`dh`dhhlhhlhdhhhhhhhllhhddh\`d\`d\`h`dh``h`\d\\`XX\TXXPPTPPTLLTPPPPLHD@DD@@@<<88440,0,,00,,000404444044040040000000,4004044000,,,((,((,($,($,($,( ,( ,( 0($0$(,($,($,($($ ($ ,$ 0($0((,(($(,LLT40@D@PDHTHLT448448848008,,804@@@PTTdHHT<<H@@HDDLDHLDHPHH\PHp(T4@ lH@H@`D@T@<L<<D8<@8<@48<08<08808808<48@04@T\hHT`LT`08@08<4884848<88<8<@<<D@@D@DHDHHDHHDHPHPTLX\Thh`pp`tpdxldxph|t|||||txpxp|t|txx|x|xxpxpxpxxpxtpxtlthdxhdxhh|pl|tp|txtxxxx|x|||xxptp|tpxpptptpltphpphlphlldhhddhddhdhhhlllldhhhhhhhhllhhddd\`dX`d\dh`dh``h`\d\\`XX`XX\PTXPPXLPTPLTPLHD@DD@@@<<<844004,,0,,,0,,40044040,40,40,40,40,40044040,00,,0,(,((,($,($,($,( ,( ,( 0($,$((($(($(($(( ($ ,($0,(,($,(($$(TT\84D<8H@HP8<@448404448008,,488@DDTHH\<8L<<LDDPDDLDHLDHTD@d8,l4 |x,(xLDtH@dD@X@@P<<H8<D4<@08<0<80<84<@4<D08@HLXHLXPT`<<H44<8884888<88<8<@<<D@@D@DHDHHDHHDHPHPTLXXPhh\lp`tpdtph|tlx||||xxpxt|x|txx|t|x|x|txpxpxp|xp|tpxplxlhxhhxlh|tp|xt|t|xxx||xxxp|xpxpptlltlptltplptlpxpptpllhddddddhhhllllllppllpllpllpllh`hd`dd``d``d``hd`d\\`XX`XX\TTTLLXLPTPLTPHLHDHD@D@<@<<88444,04,04000,0400000040,40,4,,4,,0,,(,,(,,(,,,,(,,(,,((,($(( (((((((($((,((((($(($($ ($$(($(((,,,((($$(PPX88HLH\LP`88D848844448008,,<04@48<044<@@<<DD@PHDT@DT@Dd@Hdp88`D@X<DP8DL8@@4<<0<848844<48<48@4<@@LTLP`PPd<8L44@08<48888<88<<<@@@DDDDDHHHHDLLHPLLTTT\XThd\lh`tlhxplxplxx|||txt|x|t|tx|txx|txtxpxp|tl|plxlhxhhxll|lhtp|x|x|x||x|||xxtt|tt|tpxppxpttptplptlptppplllhhdddd`ddhlhhllllpllpllpllpllhddd```\`d``d``hddd\\`XX`XX\TTXLPTLLTPLTPLLHDHD@D@@D@<<8488044,44000,440440444004004,,4,,,,,(,,$(,$(((,(,,(,,((,($(( (( (( $$ ($$((((($(($(($($ ($$(($((,((0((0$TP\<8DDDPPTd40<848844448008,,@(,@,0<48<88@@@L<<HDDTDH\8@\ $dLH|DDh<DX<@L8@D4<<48<48<48@48@08@@HTPThLLh@@X44D04<88<88<8<<<<@<@@@@DDHDHHDLLHPLLTTP\XThd\ll`tphxtl|tpxxx̼|xt|t|t|txx|xx|xxp|ptlpl|pl|ll|hhllpptt|xxxxx||xx|tt|tpxpptpptpptppplltlptlptplplhdddd`ddhlhhhlhlpllpllplhlhhd``d```\`d\`d``h`dd\``XX`XX`XXXPPTLLTPLTPLLHDHDDHD@D@<@<4880840440440844444444444004000,,,,,(,0$,,$(($,((,((,($,( (( (( ($$(($(($,($(( (($(($($ ($$(($(,,((,,(0$PPX44<<8D\\l,,8448844448008(,<$,@(0@48D@DLHLT8<H@@PLLd@Dd84lLHlDLP@HH@@H8<D48@08@08@48@48D@HTTXlHLdPTl04D44<88<88<<<<<<@<@@@@DDHDHHDLLHPLLTPP\XThd\ll`tpdxthxpxx|ĸ̴||||tp|txt|||||||txttptppl|ll|hlllpp|x||||||x|tx|pt|ttxpttpptpptplpllphptlltplplhhhhddhddhddhlhlpllpllplhphhd``d`\`\\d\`d\dh`dd\`dX\dX\`XX\TTXPPTPPTPPLHDLHDHD@HD<@<4<84840840840844844884444444004,0,,0(04(00(,,$(($,($,( ,((( (($($$($$(( (($((( (($($ ($$(($(,((,(((,$ (PLX<8H44Dhhx,(4448844448008(,@$,D(,D,0D<@PTXd<DH<DLhhDDl<иHDLDpHLXDDT@@P<@H4<D0<D4<D48D84D@DPTXhDL`dl04@44888<8<<<<<<@@@@DDDDDHHHHDLLHPLLTPP\XThd\lh\tldxth|pxxxĸ|x||tp|pxpxxxxxxxxptlpl|ll|plxtxx||x|||ttptpxtxxpttlpppppllplltpltpptppplhlhhhhhdddhddhhhlhllhlllhhddd```\\d``d``d`dd\`dX\`XX`XXXTTTTPTPPXPTPHLPHHLHDH@@D@<@88<44804<44@8<@8<<488488444000,(00(44(04 (, ,,$,,((($,($(( $$ $$ $$ (( (( ($ (($($ (($($ (($(((((($(( $(HHT80H,$Dd`x,,844448040040400<(,@,,D04L<<TLP`DHT@@`dhPPt PذPPtTLhHLX<HL<@H4<D4<D4<D48D48@@DLTThPTh`dl,4804@48D8<@8<@<@<@@<DD@DDHHHLHHPPLTTPT\XXlh`lh\tpdxtl|t|ȴ|xp|xt|t|ttx||xtxxx|t|txt|tp|tpxt|xxx||||xttptpt|ptxpppllplllllplhtpltpptppplllhhlhhhddhddlhhllllllplhlhdlhdd`\d``d``d\`d\``X\`XX`XXXTTXTPTPPTPPPLLPHHLHDHD@D@<@<8<84844844<88<8<<8884484484040,40,44,04(,0(,,(,,(,((,($($ ($$($$($$($$($$$$ $$ $$ $$ (($(($(($((((,, $LLX80L0$H``t,,844844440444844<04<04<48D\`pXXh<<LD@`PPhTPp( T|xX\TPxLPd<HP<DL8@H4<D08@4<@4<D@DLLLd@DXX\h,4848D48D8<@8<@<@<@@<DD@DDDHHHHHLPLPTPT\\Tlh\lh\pl`xtht|x|xtx|txtx||t|txxxx|x|x|x||t|x||x|||xxttttt|ppxpppllpplllhlhhtpltpptpppllpllldhldhphlpllpllpllplhlhdlhd`\\d``d```\``\\\XX\XX`XX\TTXTPTPPTPPPLLLHHLHDHD@DD<@<8<84884844<88<8<<88<8484484440040044,04,00,,,,,,(,,(,($,$$($$( ($$($$($$$$ $$ $$ $$ (($(($((((,((,, HLX40H4(H``p,,8008004444848<8<8<<<@DHHLhhtXXl@@T\\d4,PЀtHLLTpDHX@DP8@H4<D4<@4<<08<<@LHH`@@\dhx,0<04@48D8<@8<@<@<@@<DD@DDDHHHLLLPPTXTT`\Tlh\pl`tpd|xlx|t|x|||x|x|xxtxt|xx|x|||||xxx|xtx|||||xtttttttxtptpltplplllhhtpptpppllplhlhhldhlddldhplltlptlptlllhdhd``\\d```\`\X\\\\\XX\TT`XX\TT\PPTPPPPPPPPHHHHHDDD@DD<@@8<<8888844888<8<<84<848448444044,000,040000,,,,,,,,(,($($$,$(($$,$(,$(,$(($$(($($ (($($ (($,((((((,, LLX80H8,L``l008008008848888<8<<<@@@DHHPPP`D@\@<\\dptx40\x@HLPpHH\<DP8<H4<D48@4<<4<<@DPHH`88T`dt,0<48D48D8<@8<@<@<@@<DD@HHDHLHLLLTTTXXT`\Tlh\pl`tpd|p|ļļ||x||xt|p|pxptp|t|x||||x|x|||||||||txtxttt|tpxppxplxllxhhthhxlllhhlhdhhdhddphlplltpptlptlppllplld``\\\```d``\XX`\X\XX\XT\XX\XTXTTTPPPLPTPLPLHHDDHDDD@D@<<@<8<<4<80<84<848848848444444000004404404400,0,,,,((0,$,($($$$$$($(($ ((((,, (( (($($$$$$((,$(,((0 ,DDL448HLLHLL044444444448888<<4<<<@@PD@TLHTLDdH<p\`x||HDlXXPTDTLT|HH\@DT<@P4<H4<H4<H4<D@LTDD\D@\LHX40@88H4<@8@<<@<@D<@D@DDDDDHHHLLPPTTPXXP\\Thd\lh`xtl|tx|ĸļ||xtp|pxptpxpxt|||||t|t|x||||xx|||xxttt|tp|pp|tpxpptllthhthhxllplhlhdhddhddldhhddldhphltlptppplllhh`\X`\\d```\\\XX`\X\XX\XT\XTXTTTPTTPPTPLPLHHD@HDDD@DD@@@<8@<4<<4<88<88<84884844444404400000440440000,,,,((0,(,($($$$$$($$(( (( ((,, (( (( ($ $$$((($($$(($$(@@D4484444<<48804444888888<<<<<<@@@HHDPLD`8,dXL $d04p,0hldtLPxLPd@DT<@P4<H48H48D4<DLTXDHXHH`HHX48@88D48D8<D<@@<@@@DDDDHDDLHHLLPPPPPXXP``Thd\lh`xtl|t||ļ|||xxppp|ptltlxpxt|xxt|p|t|x|xx|x|||x|||tttt|tp|pp|ppxpptlhtlhtlhtlltlhlhdlddhddhddldhldhpllxptxpptlltllh`\d\Xd`\d`\`\\`\\\XX\XX\XX\XXXTTTPPTPLPLHHDDHDDD@DD@@@<<@<4@<4@<8@<<<<8<8484444044440000004044000,,,(,((0(,,($($$$$$$$$(($(( (( ,($(($(( (( (( (( (( $($((,0080044480888<@04848<88<<<@<<D@<DD@HLH\H<hH@pXlLPLLd@DX<@P8<L48H48D4<DX``@HTPXh8DH08<88@4<D8<D<@@<@@@DDDDLHHLHLLLPPPPPXXTdd\hh\lldxxlx||||x|xpppptlthtlxpxtxt|p|t|tx|t|ttx|x||xxtttt|tp|ppxpltlhtlhtlltllxpltlhpddlddlddldhldhldhplltlpxpltlhtlhld`d\Xh`\h`\`\\`\\`\X`\X\XX\XXXTTTPPTPLTPLLHDHDDH@DD@@@<<@<4@<4@<8@<8@<8<<888444044440400000444000,,,(,((0(,,((($$$$$$$$,($,, (( ,($(($($ (( (( (( (($$((((044@00<008048<<D48<88@88@<<D<<D@@DD@LH@d DH\DDLHl@DX<@P8@L4<H48D4<DPXXX`hT`l8DD4<888<4<@8@<<@<<D<@D@DHHHHLLPPPPPTTT\\Thh`lh`lpdxxpx|||||ttxtxltltltlxpxp|p|t|t|tx|x|xx|txt||xllpp|plxlltlhtlhtlhplhphhlhdphhplhlhdhd`h``hddlddhddllhpllllhplhlhhlddd\Xh\\h\\`\\\XX`\\\XX\XX\XXXTTTPPTPPTPPLHHD@@HD@HD@D@<@<8D<<@<8@<8<<4<<088088,44,44(40,4,,80040,0,,,,,,,(,((($(( (( (,((,($,($,,((,$$( $( $( $, (($((,$$0,,<88H00<,,8LLT04<48<48<8<@8@D<DL@DPHD`$dx00|HH`DDX<@P8<H8<D8<D08<TdhPhpLdl0<H88D8<D<<@<<@@@@@D@DDDHHDHLDPPHTTP\\T``\dd`hh`tph||pxx|||t||xx|ptltlxpxpxpxp|t|t|t|||x|pxt||pl|pl|ppxplxlltlhtlhplhlhdlhdplhplhphhlhdlddhddlhhhddhhdllhllhplhplhldd`\Xd\\d\X`\\`\\`\\\XX\XX\XXXTTXPPTLLTLLPHHH@@H@@H@@D@<@<8D<<@<8@<8<<4<<488484044,40,40,4,,4000,,0,,,,,,,(,((,$(($(($(,($,($,($(,$(($$( $( $( $( (($((,$$0,,8DDP,,8((<HH\00@48D48<8<<8@@@DHD@TLDd88<xLLX@DX<@P8<H8<H48@DLTL\dD\hH`l,8D88D8<D8<@<<@@@@DDDDHDHHDLLHTPLXXP`\Xd`\dd`lhdxpl|txxx|xt||xxptpxpxpxpxp|t|t|t||t|t|||xt|tp|tpxpptplplhplhlhdlhdhd`hd`phhlhdlhdl`dd``lddhdddd`hhdllhlphppllhh``\`\X`XX`\\`\\`\\\XX\XX\XX\TTXPTTLLTLLPLLLDDH@@H@@D@<@<8D<<@<8@<8<<4<8488044044,00,0,,0,,4,,0,,0,,,,,,,(,,(,((($(,((($$,( (($(($(($$( $( $( $( (((((,$(,((4HHP00800DPPd00@04@44<48<8<<<<D@@PH@d,(Px8@pLP\@DX<<P8<L8<H48DDHTHPd@T`@Td04H<8H<<@<<@<<@@@DDHDDHDHLHPPLXTPXTP`\Xhd`hd`plh|tp|xxxxļxtp|xtxptpxtxt|t|txx|||x|p|p|x|x|t|tpxpltlhlhdlhdhhdhd`d`\d`\hd`hd`hd`hd`h\`d\\d```\\`\\``\dd`dhdhldllh``\\XT\XX\XX`\X\XX\XX\XX\XX\TT\PPXLPTHLTLLLDDH@@HD@D@<D@<D<<@<8@<8<<8<<888444040000,4,,4,,4000,,0,,,,,,,(0,(,((,((,((($ (((($(($(($$( $( $( $( (((((,$(,((0<@@448008PPX48<04<04848<4<<8@D<@PDDd@\p8<xPPd@D\<<P8<P8<L48H`dpPTl@Th4DT48L88D<8@<<@<<@@DDDDDDHDLLHTTL\TP\XTd`\hd`lhdtlhtt||xxx||xxltltpxp|t|x|||x|pt|||||xplxpltlhphdpldpldlhdhd`h`dhdhhdhdd`h\\h\\d\Xd\X`\X`\\d`\dd\dh`hhhhhd\TX\TX\XT\XTXTTXTT\XX\XX\PT\PTXLPXLPTLLTHHL@@HD@DD<@D<@@<D@8@<8<88@<<@<<84484040040,4,,4,,4,,4,(4,(0((0,,,((,($($$,($,( (( (($(( (( (( (( (($(((,,,((,,,,448<<@40@PPX<@D08804888<<8@88D8@H@DP($X4D@HpHLh@@X8@P4@H4@H@DL\\lDPlLTl48H8<D8<@8<@<<<@@<@D@DHDDLHHPLPXP\XT`\Td`Xhd`ph`|plxxxtxx||||tphtlxp|t|t|x|||xxx||||||tt|tp|ppxplxphxphpldlhdhdhhdhhddhhdhd`h`\hd`lddh``d\\d`\d`\dd`dddlhhd\\`TX\XX\XT\XTXTT\XT\XX\TX\PTXPTXPPTLLTLHLDDHD@HD@@@<@@<D@<D<8@<<@<<D@<<8844040040040,40,0,,0,(0,(0,(,,(,(((($($$(($(( (( (( (( $( (( (( (($(($(((((,((,,,0<<D84D<<D<@D04844<44<<8@88D8@H@DL@8hPThDH|HHh@@X8<P4@L08DLTdLTd<Lh8D\08H8<D8<@8<@8@<@@@@D@DHDHLHLPLTXT\\Td`Xhd\hd\pld|tlxt|xxxļļȼ|xtltpxp|t|t|x||x|t|x||||xxttttxplxlhxldtldlhdlhdhddhddhh`hhddd`hddphhlddh``h``hddhhhdddllhlhdd\\\XX\XX\XTXTTXTT\XT\TTXTPXPPXPLTLHTPHPHDHD@HD@@D@@@@D@<D<<D<<D<<D<<<<844400000040,40,00,0,(0,(0,(,,(,,((($(($(($(( $( $( (( $( $( (( (($(($(($,,,((,((0<8D84D88D48D,0<00<44<<88<8D<<L@DHLHh0,l|tиhHL|LLl@@\8<P88L4<LX`tHTlDPp<D\48H8<D8<@8<@8@<<D@@HDDHDHLHLPLTXP\XP`\Xh`\lh`xph|tpxx|x|ļȼ|xxpxp|t|x|x|x|||||||||||ttttxlh|pltldpl`lh`lhdhdddd`dd`dh`dd`dd`hhdlhdlddh``hdhlllllhlhhplhh\\\XX\XX\XXXTTXTTXTT\XT\TTXTPTPLTPHTPHTLHHDDD@@DDD@@@D@@D<<D8<@88D<<@<<<<848404000,00,00,,,(,,(,,((,(,,((,($($(($(( $$ $$ $( $( $( (( (($(( (($,,,($,($040<LHT<8H<@P@DT00<44<<44<8D<<L@@DHD`40t`|$x dLHt8@HLpHLd@@`<8T84P<@XLXp@Tl@Lh0<T48H8<D8<@8<@8@@<D@@HDDHDHHHLLLTTPXXP`\Xhd\phdxtl|tp|x|xļļļȼ|xxpxp|t||x|x||||xxt|x||||||tptp|phtldpldlldlhdhh`hh`hd`hd`lhdhddd`dddhhhlhhlhdhh`dldhphhphhlhhlhd`\X\XTX\TTXTTXP\XT\XT\XPXTPTPLTPHPLHTPHLHHD@@D@@@@@@@<<<<<88844@<<@@<<<848404004,00,0,,0,,0,00,,0,(,,$,,$(,$(,$$( $( $$$($$($$($ (( (,$,,((($(($(($,(,0,4DHP<@L4<H\dp4<H,0884@84@8<@<<DDD\@@hDH|$$|ltPX
diff --git a/PerlMagick/t/reference/read/input_ico.miff b/PerlMagick/t/reference/read/input_ico.miff
new file mode 100644
index 0000000..657e024
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_ico.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_im1.miff b/PerlMagick/t/reference/read/input_im1.miff
new file mode 100644
index 0000000..b2dfc57
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_im1.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_im24.miff b/PerlMagick/t/reference/read/input_im24.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_im24.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_im8.miff b/PerlMagick/t/reference/read/input_im8.miff
new file mode 100644
index 0000000..1b6a588
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_im8.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_logical_lsb_08bit_mat.miff b/PerlMagick/t/reference/read/input_logical_lsb_08bit_mat.miff
new file mode 100644
index 0000000..47948f1
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_logical_lsb_08bit_mat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_mac.bmp b/PerlMagick/t/reference/read/input_mac.bmp
new file mode 100644
index 0000000..a098474
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_mac.bmp
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_miff.miff b/PerlMagick/t/reference/read/input_miff.miff
new file mode 100644
index 0000000..44ad902
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_miff.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+comment={
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_mtv.miff b/PerlMagick/t/reference/read/input_mtv.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_mtv.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_null_DarkOrange.miff b/PerlMagick/t/reference/read/input_null_DarkOrange.miff
new file mode 100644
index 0000000..ab9c57e
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_null_DarkOrange.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_null_black.miff b/PerlMagick/t/reference/read/input_null_black.miff
new file mode 100644
index 0000000..a4aae46
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_null_black.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_null_white.miff b/PerlMagick/t/reference/read/input_null_white.miff
new file mode 100644
index 0000000..5994501
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_null_white.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_p7.miff b/PerlMagick/t/reference/read/input_p7.miff
new file mode 100644
index 0000000..1ea350c
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_p7.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_pbm_p1.miff b/PerlMagick/t/reference/read/input_pbm_p1.miff
new file mode 100644
index 0000000..8f4ba29
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_pbm_p1.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_pbm_p4.miff b/PerlMagick/t/reference/read/input_pbm_p4.miff
new file mode 100644
index 0000000..8f4ba29
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_pbm_p4.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_pcx.miff b/PerlMagick/t/reference/read/input_pcx.miff
new file mode 100644
index 0000000..9354d5d
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_pcx.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+Resolution=70x46 units=pixels-per-inch
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_pgm_p2.miff b/PerlMagick/t/reference/read/input_pgm_p2.miff
new file mode 100644
index 0000000..5ca323f
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_pgm_p2.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_pgm_p5.miff b/PerlMagick/t/reference/read/input_pgm_p5.miff
new file mode 100644
index 0000000..5ca323f
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_pgm_p5.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_pict.miff b/PerlMagick/t/reference/read/input_pict.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_pict.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_ppm_p3.miff b/PerlMagick/t/reference/read/input_ppm_p3.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_ppm_p3.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_ppm_p6.miff b/PerlMagick/t/reference/read/input_ppm_p6.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_ppm_p6.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_psd.miff b/PerlMagick/t/reference/read/input_psd.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_psd.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_rgb.miff b/PerlMagick/t/reference/read/input_rgb.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_rgb.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_rgb_cin.miff b/PerlMagick/t/reference/read/input_rgb_cin.miff
new file mode 100644
index 0000000..11bdfba
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_rgb_cin.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=16
+colorspace=cineonlog
+
+://..,,11//--5511..7722--9922,,8811,,77//,,8800--77//,,77//,,66..++44,,))33++((44,,))44,,))00,,&&00--&&3300))6633,,8855..>>99..EE>>22IIAA33KK@@11MMAA11TT@@11ssCC33BB22@@44DD<<CCFFBBEE<<AA;;????::>>..>>,,??,,@@**??**>>--<<++<<**<<))>>-->>22AA22CC55EE88QQ99..9944226611006611..5500--22//++....,,//..,,22++,,55**,,OO6677HHFFaamm{{kkooOOGGmmQQKK``ttvv{{yy{{kkXXUURR..--++//..,,44//,,6600,,7700++77//++55..++7700,,7700,,7700--66--++33,,))33++))55..**55--**22..))22//))3300**5522,,6644//==77,,DD<<11GG>>00HH==--JJ??..LLCC22hhDD33??--;;,,FF;;CCFFAADD;;@@;;??@@::>>,,>>**>>++??**>>**==--<<++<<))::))==,,==22??33CC77GG::CC66++8844448822005511..5511--0000,,,,00--////--44..--11))++DD1100ww@@44XX[[||bbkkII==jjJJ??[[\\]]ff}}kkoo^^XXVVRR++++++++,,**//..++00--**11++''11,,))//++**11++**11****11++**11++**00++**00++((22,,++22,,++22..++2200++33//++4411,,6644//9922++==55,,??55,,BB77,,GG::..DDDD44TTCC33ll<<**88''DD33GG<<DD??;;====<<@@//??))>>,,==,,>>++==((==++<<,,;;,,::-->>..AA00??77FFCCVVMM;;>>44::33008822--4422--0033..,,33--++33//..22..0011//////--22,,**HH-- kkLLMMjjppGG<<~~<<00WW4433GG==EEEEHHRRHHXXYYNN++,,..**,,..--,,,,..,,((..))&&,,**''++))))++))))--****--****--****..****..,,,,//++++//,,--..,,))11--++11--**11,,++22//--7711..;;33..==33..@@44,,EE8800GG==66PP;;44^^66//xx66,,::..@@22DD88DD??GG@@AA..??++==,,<<..<<,,<<**;;**;;++;;--;;11BB66FF99DD??ff^^xxVVddVVBBAA776644**..00))--00**,,//++,,//....//--//11--..11--..,,1133))++ffbbaa}}hhooXX[[nn__ooqq{{^^ddPP++..11**..11----//,,--,,,,**((++))****((**''&&''))))**++))**++))**))(((())''((,,**++--,,--..++**//++**--))((..****//,,,,770000;;2211::1100==//--@@11..@@6622AA9955JJ5511gg66..<<//==44@@22CC66FF;;>>22>>++<<**::,,;;,,::++88((88))~~99--~~>>66FF??DD==TTQQzzqqooRRYYFF;;??22//00'',,((&&11++**11++**//++))//,,**//..**11))00//((''ddppQQȱŮXXccII--//--....,,..00--1100--22//,,22..++11,,)),,))**++**++))((,,**''++,,&&++**''((++))((,,,,**..,,++--**))..**((33++((55..))::22--<<33//::00,,::..--==..--==22++4488..8822++NN++&&hh99,,@@00??00::,,AA11==11;;..<<-->>..;;..88++zz::++uu99))||:://FF::JJCCPPNNoovvxx[[zzYYMM]]FF<<992211&&''..&&((,,''**//''++11''..00**////))//**&&ZZee??uuuuNJ}}uuooNNZZCC1122,,2233,,4422--8855008855009911--77//,,22--++22////,,--//..''..00((--..))++00--))00//))//00--..////33..**::00**@@44++BB77..@@88//<<44,,:://..;;00..DD00,,QQ((--EE))--66//((QQ..''ii88--99668833~~>>44AA55@@00==,,99**::))uu==((uu77++rr88,,zz??33FF==MMDDccUUyyppzzuu{{ddffccddOOeeOO33<<//))%%""--##%%**))))((**++&&**..&&&&,,((##!!VV[[GG}}iizzii}}nn~~nn||ss}}zznnkkKKUUCC667711667711888833;;9944??<<77AA9977@@8844<<6622;;664499443388////88....5500--5511--5522--553300886622>>6611AA88//GG<<00II==33GG<<33AA77//??5500>>5511;;8833BB4433@@44//;;55))DD44&&bb55,,<<::AA@@BB::==55~~@@44}}99..xx::..tt==--yy33((OOKKZZUUooII88jjRR??rr__HH~~yyWWee__yyqq}}uuwwnnnnWWhhLL>>::((22((!!$$** **..%%99%%))BB((((SSMM99ggppQQggVVjj[[mmbbjjggrrssssssggccMMWWBB778822889933====77@@>>99CC>>99EE@@;;DD@@99DD??99FF>>77DD<<33CC::00BB9922BB9922;;77//8844..8833..;;66//AA;;//HH<<//NN@@11OO??44JJ;;33DD9900@@9900<<;;22FF66//DDIIFFHHBB99JJGGEE88>>22BB44DD00??11==AABBDDuuBB88xx9933;;GGDDFFTTOOooXXBB__iiGGkkRRRRYY''GG((JJ??UULL^^XXggeemmiiqq^^llVVjjOOaaEENNQQ--''==22''FF??,,dd]]99vv[[mm[[llXXrrcc}}zzcc||^^RR^^FF556600557700<<<<77AA??::EE@@>>GGBB==GGBB==IICC;;LLAA66II<<//GG;;,,EE<<..DD:://@@8800;;66009966--==88++DD;;..LL>>..NN@@//NN==00JJ::00CC99..==<<0066<<//AA??JJ\\2244::"">>44:://==22CC6699''==11==7777>>;;;;CC>>66::--&&AA99ccNNbbIIbb]]::DDAABBEENN--DD++GG//SS33[[99gg99nn@@qqFFnnYYwwZZee``<<22GGBB..~~uuccѮffzzddVVffKK2222//444400777722<<;;55CCBB88FFFF==IIHH::LLHH55HHDD66LLGGIIGG??88DD::**BB88,,>>77//==7722<<6600==8833??<<88HH@@55OO??,,GG>>,,JJ7700BB663344<<//??>>..HH??33**33 @@%%99##55&&<<11@@00??11??3377((00******//((55$$44 88++TTHHTTPP@@JJ>>@@::--DD::@@CC==GG@@PP<<UU==gg==ppDDvvIImmVVwwXX~~\\mmmmccƿЃttmm00//,,..--++3322..778811==>>44FFCC::NNJJ77LLJJ33WWVVVV{{wwZZSSnnEE>>NN8833335511%%4411((9988--AA<<,,JJ??..OO??..BB::))9933((//33//AA00,,55;;::..;;&&::$$==++<<00::0088))99**>>1122))33++77--00**..''4433 88++>>55BB@@@@====2288''<<,,DD??EEJJCCJJCCWWAAaaIIssJJ||LLyySSssBBbbzz^^SS꾾9977005522,,22//**6633++;;::11HH@@55UUII88SSGG99cc``qq⪪ꍍmmllKKHHWW??>>LL;;8888@@<<''AABB--77@@8899DDPPDDTT``EERRQQ``FF;;EE66<<**@@,,::''55))77//993377119922::11>>6600&&,,'',,''11''66 66!!44''BB;;UULL==1199""99((??66GGEEFFGGEEIINN[[EE__IImmQQyyWWyyTTppRRff__ooJJTTߨCC??44@@<<22::55,,4411''9944..EE<<66SSFF55VVEE66\\TTiiܩ{{ee[[QQKKrr6699BB998866QQIIMMrr\\zzJJOO;;&&88""99))::,,;;22::225500==88;;6677..CC88>>33((((****11++11$$;;''99))66,,KKGGBB??88##88''==11PPHHDD==MMHHPPRRSS``UUmmMMnnTTwwVVnnYYhhVVddNNSSssmmNNHH::LLFF99EE??44>>88//<<55//@@<<77LLDD44RRCC--VVKKRR뉉nnyy``ddMM^^NNVVKK\\GGQQ::========44==..>>11==3388..22**66..77..22((22##88!!==//77:://4411//4433442266**==..OOIIDDHH<<2277**;;,,BB11<<,,GG<<MMII[[``eeuuOOllYYttqqwwaaoozzttddUUOO@@VVMM>>UULL>>OOHH99JJAA33EE;;00DD??66KKFF44RRFF--UUMMPP޸uu@@MM;;>>::66??00EE::<<@@88;;??99DD8855''11**3300::..66((33 55 66%%44((44**77--3311,,44))//00((44##KK@@GGHHLLJJ77--99''::&&::));;..??22]]UUmmllffooffppssqqnnttyy{{@@PP22¾ZZOO@@ZZNN@@XXLL>>SSII99SSFF88MMFF;;QQII88VVJJ33WWPPSS~~ғ◗꒒ֆ΅hh<<OO??99==BB>>EE==::FFEE==@@>>::<<00>>//::**99--882222..33--77))::**::55;;8888$$88 22%%44..66**77%%<<((==44??AATTRRFF<<88((99));;,,;;--99))UUFFllii``ffaallmmppcckkVVootthhWWmmDDZZMM==YYMM==ZZMM<<WWLL;;YYKK;;VVJJ>>WWKK;;YYKK77TTKKFFcc^^ttvvwwzzzzeell{{QQaa::EE22>>DD==BBMMAAFF??44BB::3300AA44::((88$$99$$77''33**0022++22,,00--77''==''////&&77''::11<<33CC5555%%44((6644--..33))44))II====0055))99**66%%GG==ppqqrr}}qqzzrrzzUUddCC``||||ffʬĭȨŘӸZZKK;;ZZKK;;[[KK;;XXHH::YYJJ::ZZKK==]]LL;;]]OO;;ZZMM@@XXKKHH]]RRcclldd~~™}}pp??FF==**??88;;??AAII;;6688''AA77::77CC9966##::''77&&33&&88--33&&++##((&&$$1155&&55;;CC0099//99**--7744FFFF5533::5544))77%%77**PPFF;;228800992277**77,,jjjjyyqq~~LLcc>>[[]]ffPP{{[[``}}PPddXXxxggssxx~~óZZJJ99ZZJJ99XXJJ99XXHH88ZZJJ99\\II;;]]JJ;;]]NN::]]NN::^^MM99^^JJGG``VVvv{{vvddvv33JJ??EEBB??AAFFBB??::--77%%??5577::LLDDOO@@55''33))55//00..0088,,;;));;,,GG--VVPPbb[[ll77NN//4466%%BB55RRMMBB??88--66##::$$77((EEAA77222200////880033&&[[VV{{jj{{GG``==TTXX``66ddMMcc}}ll~~oonnoonnpp[[JJ66[[JJ55[[JJ55\\KK66\\KK88\\KK::]]LL<<\\OO<<\\OO<<``LL99bbFF==ff\\pp~~ttppJJTT>>PP<<FF;;<<==33::))==..772222**88&&LL@@@@2299--668811==!!..,, **$$66::UUbbooMMRR994455##,,99//7755HHDD:://77**77**77..II??22----00,,//11++33$$LLDDzzXXss>>``??RRHHXX00ooZZnnpp{{ee}}ee~~jj}}ddmm]]LL99]]LL99]]LL99]]LL99]]LL99^^KK66]]MM88UUMM@@``WWXXnn__llllccooooww藗˷uu{{cc[[LLTT88@@6666AA1199**FF==AA8855**55&&33--CC66;;--//22CCMMBBFF..,,++''1122==BB>>BB667722--NNIINNPPHHFFTTTTDD@@AA99;;6611<<66>>==9900))11//--11//--33$$GG;;ppEEgg;;cc@@FFMMaa;;qqYYxxbbtt__uu^^yycczzcczzYYgguukkff^^NN<<^^NN>>^^NN==^^NN<<^^NN<<__OO66[[KK88^^ZZ``||{{||ppuu{{ĘŸƴooQQKK@@GGII6688991166--HH>>eeWW??2211**00++<<0066((,,((4444QQWWIIPPPPUUUUZZ??AA88>>,,66IIUUnnyyeeuuQQMM4422@@;;DD;;33//++9944>>552233))11..--11..,,44((;;22aavv==bb@@cc[[::..KK^^==tt]]zzbbnnVVqqWWww]]xxZZvvUU``ggdd{{UUZZLL<<^^OO??^^QQAA__QQBB__QQ??[[NNAAbbXX``vvvvvv{{bbiiyyyyԭߴ橩xxcckkffVVYY559955229900NN@@WWHH00&&==;;??66//$$,,&&22))8844RRVVUUaaccnn``ff..66''55EERR]]eeSSZZ66225533771177//9944::::554444**55))//,,..33//..88--7711vvQQoo;;ccIIZZ<<;;%%@@II//gg}}RRssWWggKKllPPrrYYrrSSkkLLaaDDMMii33HH``33SSGG77XXKK;;^^QQAAaaUUCC__RR>>ee\\aazzxxssyy\\eekkuuݿnniiddiiccxxttffddCC@@<<44;;00AA11;;,,FFEEHHEE66//55//88**99%%<<5599@@ZZffVV]]6622AAHH>>EE66884455440022//99..::2255446677553355,,66''00**2244//..33))CCAAggtt::cc??ggLLFFQQOO;;DDAA,,NN^^88hhKKddCCffJJmmTTggKK]]DDXX||BBVVnnAAZZrrCCCCAA55IIDD;;[[LL==__RR==dd^^WWyyssrroo\\^^hhhhݛܠԞԜ̓ooff||]]UUQQ{{RRGGXXPPxxrr{{]]YY55,,44""::))99//66++88..77..;;))??00<<336622OOKKJJAA55##..//''99&&>>99""77--559944;;446644224433//66((88%%55%%44,,44((33&&UU[[OOjj77dd??WW8844""@@AA226677 PPYY33ccxxMM^^@@bbCCkkMMggFFbbHHbbIIee~~HHaa~~CC3366,,999933NNCC::UUKK<<ffddkkkkiiPPPPZZ\\xxzżۊφˆЋƅ}}YYii[[ZZKKooVVCCRRUUeejj탃~~yy::,,::""::((55**::**55''99,,77''99,,99..99//>>4499--00&&..66**<<))==##99%%8844<<9955::334433337755..66((77%%55##88%%::$$<<33VVkk66bbBBiijj22<<""..$$..33]]XX11rr__\\==llJJooPPjjGGhhLLddIIeeGGffFF))//%%**//**886644DDBB<<YY[[hh[[\\ZZYYxx{{ԃ退ȁЉً}}wwrrVVQQ__^^GGcc^^BBVVOOYYbbmmiiJJ??66%%;;&&77**00''==**99''FF::88**99((66''66'';;..:://55::00>>,,::2255447766::554477449977667755::773377))99((99&&<< ;;%%JJLLAAff55ffBBNN22553377**..CCMM((xxӘpp[[\\<<qqMMnnQQeeDDffLLddJJeeFFjjII--11%%**--''//00**99<<//KKNNMMWWUUllmmkk葑~~ςŋ̌vvkk``\\]]\\FFee\\HHii[[DDXXBBQQPP<<<<//**66%%66%%44**44((<<**;;**CC8877((99''88''33''11((::3377;;..99DDIIUUPP@@<<77117733777777;;66;;4488::5577((<<))<<))88""44((OO__<<^^HH\\JJ??00,,22$$II22&&ddҊ{{JJbb88__~~<<kkHHccFFddBBjjNNhhNNeeDDooOO??==//==<<33;;<<11@@DD))KKLL99TTSS@@ddbbff~~yyvvrr~~yyxxnn~~mm^^VVkkXXFFgg[[JJii]]MM~~^^NNJJ;;44--//**33))77##<<##88++::((66%%<<44HHAA88&&99((88,,;;33::6699777755GGHHYYWWBB<<996688117733557777==55<<66::>>66::**::&&::''55""HHCCTTggLLWW\\NN2288!!EENN((tt^^hhiiHHSS;;;;GG++ff}}BBiiEE``DDjjJJkkOOnnPPllLLuuUUTTLL==UULL>>UUMM>>UUOO<<[[QQBB__VVAAaaXXJJllbbjjvvii{{ooccll\\VVZZVVTTQQ\\UUFFeeYYEEmm^^GGiiccNNYYNNQQFF99++33**66..66--55))88((99++;;**44!!88,,;;33GG99AA88==88;;;;5577::77<<1188))::,,;;44559955997755881188557777::<<??77::++::''77##55&&XXYYSSUUXXQQbbJJ__ww::ppuuXXNN\\::::<<--1122**::BB00ee~~FFnnIIiiLLllQQiiFFppJJwwTTppVVbbYYJJddZZJJddZZJJccZZKKddZZLLff^^IIgg^^GGff]]LLff\\KKee[[HH__YYFFPPMM<<KKGG66RROO==ZZYYEE^^^^NN``XXIIKK33//<<((99))88**77))66))99**<<..44>>((66))88..338855;;55::44;;553377%%88%%99((==33887755667744;;22==88====??::77**99''99''66!!}}99))QQIISSHH[[RRmm\\rrRRbbAA&&114477006655..8888//88BB//ffJJvvPPooRRooNNnnHHwwTTvvXX__IIgg^^OOhh__PPhh__PPhh__PPgg^^OOjjaaSSiiaaRRhh__OOhhaaKKhhaaGGggaaJJ__YYEEKKII55??DD33??GG77BBII==TTLL::WWNNCCEE99++66$$77((99((99''88((::..558877))::44??DD==::5500994488,,==))@@**;;&&55((;;44<<66>>55CC88@@88772277))77&&;;((||::''vv22!!@@22RRFFYYMMXXRRXXLL@@LL**&&11$$66==;;JJLL??<<::''6699..77??,,ggJJuuOOppOOooIIxxUU||aaaaHH__KKhh__PPhh__PPhh__PPii``QQii``PPjj^^YYjj^^^^jj``UUjj``SSjj``WWkk``QQjjaaMMYYUUCCCCEE77;;BB4444BB00>>BB((YYEE\\XXIILL:://88**;;//<<00==11??99==22BB22GG@@HHDDDD@@<<..EE11BB00xx@@,,99**;;++<<++77))99--:://>>00;;--55))66++;;++~~::))zz::++rr88))uu44''GG::NNAARRMMUUVVnn^^eeuuHHFFUU33]]jjPPJJPP4499::""7777..77AA..hhKKvvOOooMMqqOO||__eeMMaaIIaaLLhh__PPhh__PPgg^^OOkkbbSSjjaaRRllaaVVkkaaTTkkccNNkkccOOkkaaUUllaaTTllbbSSgg``PPUUOO??DD@@0077@@&&JJ??==??MMNNhhllMMIIBB;;DD>>GGBBHHEEFFJJKKJJHHGG@@BBAA@@??<<<<//@@11;;009922~~::11}}::00yy::..yy::**zz99**77++77++77''99));;++~~77**zz22''xx55++oo33((uu<<00PP??SSFFPPLLZZRRVVWW??NNdd<<__uuEEBBVV,,55??))99;;116688..77??,,^^xx@@wwPPooPPvvXXiiRR[[FFffII``HHhh__PPii``QQkkaaSSii``QQii``QQjjaaRRjjaaRRjjaaQQkkbbRRkkbbSSooaaQQoo``TTee^^QQee``OO^^XXBB@@??$$qqLL;;DDBBAABBNNMMKKKKBBAA??88DD::CCDD??DDBBDDCCBB@@==AA==@@;;88..<<..;;227711::..::--~~99,,{{99--{{99..zz8800zz77..{{88--yy99--ww88..tt77--qq55**nn33))kk11&&uu??55SSKKPPLLTTLLxxddNNYYmmIITTllCCLL^^9988BB''7788++::<<2233:://7788((UUcc==ssSSww[[qq[[YYBB^^HHddKK[[FFgg``PPhhaaQQiiccRRhhaaQQhhaaQQiiaaRRjjaaRRjjaaRRkkbbSSkkbbSSll``SSeeYYOOrroohh||zzii66==**22;;'';;<<..>>::--]]AA44GGDD@@DD==;;CC@@CCCCCCCCEECCEE>>EE<<CC==<<33<<++}}==..88--99**99**~~99++}}99..}}99//zz88//xx77..vv88..uu88//ss99--pp55,,mm22**jj33((dd00$$rr<<11QQMMXXQQ~~^^QQ^^[[GGDDRR::11>>((::DD//AAII5588@@//33::--3388446677++KKVV22qqRRzz]]__HHYY}}BB``HH``JJWW{{FFggaaQQhhaaQQjjbbRRhhaaQQhhaaQQiiaaRRjjaaRRkkbbSSkkbbSSjjaaQQdd\\RR{{Ӟ{{BBII1144>>**996611))//**YY>>==~~~~WWTT8899??CCAACC@@AABB>>DD::AA99AA77::++~~<<++;;**99**||88,,||88..||99//{{9900vv9922rr77..oo55++nn77,,mm66**mm55..jj33++ff22))__--##oo77..TTPPyy[[NNMMNN==44??00..44++2222//--22**33==00::JJ77//==--,,11..4433**@@LL..rrXXmmSSSStt>>YY{{DD^^KK^^HHVVvvGGggbbRRggbbRRggbbRRggbbRRggbbRRiibbRRkkbbSSllccTTllccTTkkaaPPkkiiddʛ~~JJNN00<<55((NNGGEEpppp<<99??;;????==>>AA<<??;;BB;;::00<<..}};;++~~99--zz88..{{88//zz;;22yy;;33oo::00jj77,,hh66,,gg77,,gg77--jj66//hh55,,``//&&XX**ll<<33uuSSMMFF??22--88((00;;--6699115577551177//,,88))55CC1188GG550055++++,,!!??II00yyll]]LLPPnn;;UUrrAA[[xxFFaaKKPPiiDDffccRRffccQQffccQQffccQQeeccQQhhbbQQkkbbTTllccTTllccRRii``PPccccccپqqmmVV@@II;;ܰNN@@77//@@;;AA<<DD??>>::;;22<<22}};;00}}99--{{88..{{88//yy8811uu77//ii77..gg77..ee66++dd66,,dd66++hh55//hh66//ee55--gg::11mmKKAA7777220033++2266,,4455**2266((..88**//88))--77))..77++77@@11::BB11//00##CCLL99nniiFFii<<KKjj;;KKhh::VVttEEaaMMBBUU::ggddUUggddVVggddVVggddVVggddVVhhddUUjjccYYmmddVVggeePPmmkkgg׶oorrVVnnzziiֹii]]77**??55GG88DD55AA66>>55::11||8811ww77..tt66--rr66--nn44**ii66//gg66//ee44..ff55..hh66//kk6600kk;;..ffEE33pp^^mmjjZZ((11''0066--//66,,0055))//44++..22,,..22,,..33----00++--44--11>>3322??22??LL99HHWW??AATT77LLff??FFaa88WWqqII\\wwSS33CC44ggddUUggddUUggddUUggddUUggddUUffddTTjjccZZmmccWWffggOO||}}еšDD3388--;;8899::~~??<<ooAA;;pp??55pp>>44nn>>33ii;;11gg9900pp5511ll4400ii66..ff8800ff==33eeEE88bbII44^^LL44~~~~hhPPXXEE))00''//66++0066,,//55++..22++,,11,,--22,,,,11++++//**++22++((33,,,,77,,11==,,11==))55BB--CCUU::GG\\<<]]ppQQYYkkRR++77--ggddUUggddUUggddUUhheeVVhheeVViiddUUkkbb[[mmffYYgghhPPkkttooҺjjRR>>--55))~~77++nn@@22qq<<66rr>>88rr@@::nn>>77mm<<55pp8833kk9922cc<<11]]==11OO::**TTOO88\\WW<<\\\\>>mmuu[[11??**1166..1177--2288..1177,,..44++--22,,--22,,++00**))..((**//****22**))33++,,44++66??4488BB3322==++==II33[[ggSSPP\\NN**33,,ffccTTggddUUhheeVVhheeVVhheeVViiddUUmmbb[[kkggYYeekkRRggvvnnտtt\\xxGG00dd55!!dd22((ii88//kk>>33hh==33gg==11bb@@66^^CC44XXFF44dd\\FFDDEE..88BB&&DDHH**ooooQQ[[__FF1188&&66<<4466<<2266==3377==2277;;4466::5555::44116600--22,,++00**''--''))--))++00++..11..<<CC<<<<II7700>>''AAOO;;DDOOCC..88//ccccRRffccTTggffVVhhddVVggeeVVjjddUUmmcc[[kkggYYccjjQQccvvnnдĽϻggRR::WWCC++\\JJ11[[KK33UUNN99PPMM66LLNN77]]ffJJ??KK//<<DD))FFII**hhffII__XXCCEEEE4499>>4499==4477==3388>>4488??77::@@::99==8899??9988<<7766::55//5511++00++**..--((,,--((22((55II1188KK2277HH00::JJ77..::--[[ffNN^^hhQQffjjVVhhggWWkkeeWWkkffXXjjeeZZggffXXddkkXX{{ǾǼllffJJQQJJ,,TTNN11RRNN22OOMM33KKNN55GGNN44DDMM--KKRR//\\dd??``ddEEUUUU<<VVSS;;TTQQ88LLHH55BBAA44;;>>4477@@4477BB4488@@6688@@5599AA66::BB77;;DD;;::DD9988??4444<<5555CC..FF__44FFaa;;99LL77??QQ99GG[[@@33AA00
diff --git a/PerlMagick/t/reference/read/input_rgb_lsb_08bit_mat.miff b/PerlMagick/t/reference/read/input_rgb_lsb_08bit_mat.miff
new file mode 100644
index 0000000..1efc2bd
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_rgb_lsb_08bit_mat.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_rgb_rla.miff b/PerlMagick/t/reference/read/input_rgb_rla.miff
new file mode 100644
index 0000000..ba564a0
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_rgb_rla.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=True
+columns=70 rows=46 depth=8
+comment={A Wavefront file converted from an rle file.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nndun10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:darnmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Uj|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLSozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮ʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdme~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxv|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzzydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iipg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S||CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQljeKO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_rgba.miff b/PerlMagick/t/reference/read/input_rgba.miff
new file mode 100644
index 0000000..7bb7a7d
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_rgba.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=True
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nndun10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:darnmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Uj|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLSozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮ʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdme~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxv|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzzydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iipg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S||CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQljeKO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_rle.miff b/PerlMagick/t/reference/read/input_rle.miff
new file mode 100644
index 0000000..0f63e7a
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_rle.miff
@@ -0,0 +1,7 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+comment={HISTORY=rawtorle -w 70 -h 46 -n 3 -o input.rle /tmp/magickAj4Oj_ on Tue Sep 22 21:12:43 1998
+ }
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_sgi.miff b/PerlMagick/t/reference/read/input_sgi.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_sgi.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_tga.miff b/PerlMagick/t/reference/read/input_tga.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_tga.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_tile.miff b/PerlMagick/t/reference/read/input_tile.miff
new file mode 100644
index 0000000..17d6463
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_tile.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=140 rows=92 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnD@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3WN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDTH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvV@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`JcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Lh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\Gi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;gdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B10/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnD@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3WN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDTH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvV@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`JcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Lh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\Gi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;gdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_tim.miff b/PerlMagick/t/reference/read/input_tim.miff
new file mode 100644
index 0000000..9c33894
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_tim.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_uyvy.miff b/PerlMagick/t/reference/read/input_uyvy.miff
new file mode 100644
index 0000000..e816cbd
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_uyvy.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:00-11.62-73.95-84,81/92081/81/70.5.,4-+5.,4/*2-(2/'52*85-:7/?<.DA3JB2JB2PA1RC3?.J9@6H>CDGH>B<@F:;/A-@,C-?)@.?->*>*?/A1A1E5OCd2&:6473173062/11.//,10-0/,:*+J:;IMeisnOJfQLhuxtz{pWXM//,00-51,62-72-61,50+72-72-72-50-3.+3.)50+50+4/*21+32,54.760=9-C?3H@0G?/IB/LE2v?-}F4;-J<BCEF=B<AG9;-@+?*B,?)?->,=*<)=/@2@3G:|REY/":6484262/62/01./0-10-21.5))@44xA;[UkkJ@cJ@c[`_mncXYN,,,,,,//+//+1-(2.)1-+1-+2-+2-+1-+1-+1-*2.+2.+3/,32.21-43-760:4+=7.?7+B:.C>/ID5`A.bC08&H6D<KC>><<E0>)@.>,B,>(?,>+<.;->,E3A<FAv_VN7.:5094/34023/-4/-4/03/03/10-0/,H.&jPHprI@r;2d27@?DMKRGU\Q+-/+-/..+..+-,(-,(+**+**-++-++-++.,,/--/--0/,/.+2.+2.+0/,21.83.:50>5-?6.D90I>5W:1X;25)?3>0I;H@H@E0?*>.=-@.=+=+=+=0</A3K=LEb[}^cSCC866+.1*.1*-/.-/./0-01.001../2-+idbفlrV\|_rl|YfU+02+02../--.,+++***)*('(**+**++***)))(),+,.---,,1-+/+).,,/--830:52<2/;1.?4/B72F94F94r4(B6>3A6C8I>C1>,=+=+=-;+;+:*|<1@5F=I@aUynlTYI<A110*+*$2-+2-+.-*/.+0../--*-il]ʳǰSfK///...01.01.21-10,0/,-,),+,*)*+),+),+)),**-,,.---,)-,)3.)50+:3/<51;1.:0-<1,>3.78/45,R+"c<3?/B2<,B2?1=/?/@0>09+z<,x:*{=1H<KETNqvyax[JaD?:5/*%-()-()/)+0*,1,00+/'+^bKtxǒďyqJ]B23-23-54.871:6173.72/4/,101.-..)-/*.-,)0/,/0,01-00-11.;2*?6.B9/B9/<6/93,?2-A4/L+0I(-A-%H4,q6/z?8<5=6C2C2>.<,~?,{<)t:-s9,|@6I?SGaUqtu|gj`cTcQ0?-+&$,'%******)+.&(+&'YZOzflop~y}xsmFX@784784995;;7A=8@<7?:5=83<86:6481070/62/62/540651;72<83B:.F>2I?4H>3B91@7/<83=94B64A53?5(A7*m2+}B;E@A<A6A6{=1z<0x=.s8)TNXRjM:oR?odGx[iayq~vwuqQlM@;.1,%+#)/';''?++OQ8lnUdSn]mflevvrrngG\@8959:6>>:@@<C?:EA<EB:DA9F@7D>5D;1C:0@<2=9/95084/<8,A=1J>/NB3OA7K=3D;1C:0A;2@:1DGJM?:PKF7B3F3E2?;@<KE>802HJMJOLe_CkeIZPg](H)IDWJ]]jboisakZkPaNN`((=5%G?/]a;|ZlZm[sj~uh{`NaF671671==9AA=FB?GC@GD<HE=MC6H>1F<-G=.B<1@:/;80:7/?:+C>/M@/OB1M?3J<0@=/@=/M3+hNFNX1;5$E4;/?3F69);1C9;?9=?>>=5-<4fObKZ[GH@CJM.G.G0W4[;l;lCoFrdyRgVC3R?/xyjҲhzbUgO330552882<<6CD9FG<KI7LJ8HD?MIDIA5D<0@:/?9.>:2=91;:4?>8KA2KA2J>1G;.<<3;;2_2$XJ7'3#@'<#5)>2A1A1=/;-.+/,5(3&9'7%RI[RFL;A9-G;>DAGAT?R?l?lHsItXzZ|mnab҄vr00-//,33-882??4EE:NM7LK5TWf}yYUtFAF94952&52&<:,@>0LA.MB/A<-:5&72-:503/@<>&<$<,A1=/7)9*A21(7.4+6-5&0!6%8'>9E@F=<3;(>+@AKLCPFSBhIoM{N|TsEdΆUU98254.22)55,>;1FC9VK9TI7^`ͬ쑑mmKJW@?L=:.?<0?C5<@29FPGT^SOGRNFB1A0@,<(4(<0;492:1<3<36--'/)8'2!7&7&G=UK?.9(:,C5HGIHENPYFdKiUyW{WnSjdqHU̲C@4A>2:7-52(:6.D@8TG6UH7TUƭ}c^QPf98N;99NLLrZlN`>(8"9)>.;1>461?:>58/B6C7*)+*6-/&;)=+81LEG:7*9*?0RJF>OKTPSdYjOrUxXkZm^gIRxtOJ;MH9EA5>:.;80A>6PE2PE2MNj뉎s{]eERYfO\FS9:ABB6;/=0A48.5+7-9/6'3$7%A/9<253164925.?5PFGD<9:,;-D3?.H@OGZcjsTnYsoxenЉgb]LEVN>VN>OJ;ID5C=2F@5NG1OH2MNhȜ>G>GA8;2A<E@>=<;F88*0+72;.8+7#4 6&8(4);024/1/--+7(L=IGNL:,9+;);)<.A3^Xpjhpgoqrst̓zMJ8ͻZPAYO@WM>TJ;QI;OG9SJ7TK8SPfڕܙ䔞ߌʄ_~Gf?=A?EG:<DCDCB9:1@0;+7->44-5.>-9(71C=;#9!3)6,:*8(:+A2CBSRJ;9*=+<*;-;-VKpeahelmqhlvrkgbgK[P>ZO=XO=WN<YM>XL=XM:XM:RMRgbgwv|zyjhYz5@:ECEEGIF;8?982C4;,:$;%5(8+03/2/6.5*9'64%7(<2?5F57&3)=32-1,8,H<?26);)8&GBtos}s}oz[feaց}mѪǴǫžٵZM<ZM<[L<YJ:YL;ZM<\O;]P<YNEXMDZTsoilGc:,F8@E?DA66+>6A9F76':(:(3&</2&1%',',3#9:C3<27+0:7HE73;79*5&9-RF<3;2>36+72lg|l}Sd`Yg`oTuZ^Pi[vewzķZK:ZK:YL;WJ9ZK:[L;[L;^O>^O<]N;YKXfXeq^p?QDE@AGH@A>-7&;7@<QEMA5'8*4040091:+A-C5SJhZl=O8/2)C8VKE<:1='7!4*KA5072605/6-[R~f|Nd_TB7k}P|a{ktmqtlò\L6\L6\L6]M7[L9\M:\O=]P>^O<]N;ZINn]bmqSWAO;I@;:59)?/6060;+N>@3</5;6<#-#-"1$3BT_qRQ769%+71=7KA<2<.6(7-MC0,511.1.9,J=UsDb\Q~>3q\nn|h}fjfk^M:^M:^M:^M:^N8^N8[P>YN<bW[mbfefxy܍nlnlLT;C>5<3:-J=A69.5*6+E7>017EKCC00.,20?D>C:81/OLPMFFXXH?C:798:;=;=/)711010;-C5xFj?cxUDrO>qZzcvau`yd|g|[fj^^O>^O>^O>^O>^P:^P:VMEd[S}|px~şدxWE?PJ;964;1G=cUE71*3,=.:+/,52RYJQRVVZ<@>B1:HQn{huRL93B;E>.136:=251+6001./;07,hwAd@cKD.]V@s[}epUsXx[{^xW^mb~N[N=^Q@_TB_TB_TB\Q?]Zm{xv|ek}}絹o`xiTV:<<46.M=[K/*@;@54)1*1*87TSWcdp[a7=.;CP^dV\5375:381:7<9:43-4*5+03/2>54+qZoHe=Z9=&DH1fMw^hMlQrWsXlOaDOi8Hb1TI7YN<_TAbWD]RIi^Uvzw{\glwпμ|e^rksookHA;4=/B4:3IBHA:3<06*8*A3:D\fVV;;DJ>D569:6240:1;26677924-4'6)230181A:`{E`Xh6FRQ;DC-Ka2mTdFgIoThM`IX}AWo@[sDEB6IF:[N<`SAa^g{xrq`_jjܟآۢԝϔngiRIpYPWO}uyb\9)4$9*=.6*;/>/8)@3?283QLJ;8),4-5&?";)5+7;3=575648.6,8&9'7+6*61VQLn=_XZf "@B/68%M[4hvO^?dElMhIeKcIeHc~F45/9:4OE8VL?edznmPQ]^y{͈܌ЇˉˌΓq_ydYGg\JSVhk}~>):%8):+;+7'<.6(;/<0:0?58,6*.:.:)>&;,90=:4<646579.5*9&7$;&;&:@[a:dAkS??9%%33ZZ<v]]<mLqPkJjOeJeEiI*0**0*984DC?XZt]_yYZ}~ɇ恃́͋͋͆w{iZ^a`EbaFNNddneMD9$<'8+4'?+:&H::,:)8'7)=/74;83@-:2479:;5685<9697:=36,;';'=#=#FXJ\He3P8343./BP՞qY^=rQoQeGfMeLeEkK.2(+/%02):<3LMWXYcmjה~لōΏ~wheW_\Nh]Hh]HJ=dW></-9(6%:.2&=*?,F:6*:(;)3'5)96;83:BIUPE@929278:;7:7:@54)=+=+8'8'MfAZ^`q-/7/#@8,~`Β~Kd9];nLfFcCjPjPeEpP??2>>1<>+AC0LM:TUBca|~zxsz{psj_bh[Ii\Jq[JxbQ@4@42*4,<%;$>-6%3'C7PB4&8)<-;4>7:987MKVT@;>992:37:9<7:8;D86*='<&2&NB\kIXreQ@3<T$~fneIS:=G.b>pLeGhJlNpRmLwVUM?VN@TO>UP?\S@`WD`YUleawkwpdp[YYWUU^WDc\IiaIldLTHYM6);.8/7.8*9+@/9(2!>-?4E:A9@8;<9:A:818*<.86<:888894:599;;E:6+=(8#0)`Y[WTPnmConDtzTQZA7@'04(=A5cAtRkNmPiErNxZpRbZJd\Ld\Lc[Kd]Jf_Lg`Jf_Ig^Ke\I^\GQO:KI7RP>Z[H_`MTQWT<08,:*=-9+8*?/:*5B)5)<058697;7;>31&8$=):3?89786=6=6B>>:=,8'<'6!9*WHWL[PzZxUaG'37716606:,<@2dCyXqQpPnJzVw]^Dg_Oh`Ph`Ph`Pg_OkcSjbRh`PicJicJgcL_[DIK8BD1@G:CJ=r@3fYJD5/6$<*;);)=/8*7:4*@6EF;<8394<+=,?*>)4)A6?6@7H>@6<24*;(;(|;)u4"B4SEZP[QtdLTD,(1*6?8LM<;<+6:,:>0dCyXpLqMy[~`bK`Ih`Ph`Ph`PiaQiaUjbVjaYjaYjbVjbVkbPkbPWXGEF5:D47A1T:"eMYWOM=.:+=/?1@6@6?1D6G@LELD7/H4C/~?,}>+<,=-7)=/;/?3>04&:-9,}<+|;*t9*r7(J>NBTPXTy[unPHT8_kOMP78;"59+;?1fBzVoLtQ~ceJcLbKh`Ph`Pg_OkcSjbTldVkdQkdQldTkcSlbSmcTgbQUP?AD.<?)@:KENPjlOHC<E@IDHIIJKJKJCBA@G?6.A5<0;4;4|<1{;0z<,y;+7*:-;*9(=,}:)y5)z6*m5*u=2QBUFVOXQP[;U`@_uGBX*7?.7?.6:,:>0\z:{YoPxYjV[GhNaGh`PiaQkcSiaQiaQjbRjbRjbRkcSkcSpbTpbTdaQebR]\ABA&F<NDABOPJHFDA9C;BFBFDDEEC?C?H@3+=1=1;1;1<.;-{;.{;.z91z91z:/z:/v:0u9/q6,o4*j4(wA5SKUM]M_OXnIVlGP]>7D%79.;=26:,59+Qh4z]y`qX[D`IfO[DgbQhcRidShcRhcRhcRjbRjbRkcSkcSlbUe[Ntqi}{m6>+4<)=>/<=.s8/SJAA@@DCEDFFFFG=G=JC92?.>-;,;,<+<+};1};1z91y80v:0v:0r:/o7,l4*l4*d2&p>2UNXQveTiXGES<1?(;D1AJ79@14;,692581E\(y\}b^CZ~CaJaNY|FgbQhcRidShcRhcRhcRjbRkcSkcSjbRb_Uxݘ~JH08<.6:,5+(NDAzx^\:<@BCDBCE>D=H=?4>.;+=+<*{9-|:.{;0{;0v;2s8/n8-o9.n8-m7,j5,h3*`.$l:0[RWNIQ@8@/14/14/-4)6=2<K9/>,01-340:Q%xcpYQv:Z{F_K`NWxEgdTgdTgdTgdTgdRheSkcSldTleRkdQikj˞NM7:9#MIFmlBA?<C@@=B?E?@:?1;-};-};-z:/{;0y=3y=3n<0j8,f9-g:.i9.i9.h8-a1&X, k?3lZOO=2.8(2<,89578419./7,5D29H635*+-":N+raNNq;VrA\xGdRPk>fdRfdRfdRfdRgdRgdRldTldTleRibO`fhlo\EH5̹J?=2B<B<ID<7?5<2}=0{;.{9/|:0y:2w80g90g90d8,d8,e7.f8/g90e7.d=4rKB78223-46+46+18)18)08+/7*/7*8@3=B2.3#>P8tnIi<Kk>Li;WtFe}WAY3hfVhfVhfXhfXhfVhfVjeXlgZffYnnakt\r{c̤ti7*C6M>A2C9?5<5~92v:0t8.p8.n6,i80h7/d6/e70i82j93f?/kD4|ubrkX*1)07/07,07,14-03,.4..4.,2,/5/2?23@3?M8IWBAW5OeCGa;WqK`t[2F-hfVhfVhfVhfVhfVgeUkeZkeZdfY~sӺڛO<<3=4A==9qC:oA8nA5nA5i<3g:1o84m62g90g90d@6iE;aL5aL5|lTWD*1&07,17/06..4.,2,-3-,2,+1+-3-*3,.703>,3>,5C,FT=I\>]pR[jX+:(hfVhfVhfVigWigWhfVjdYmg\dhZptf˻hTC/9-5)qA6p@5q@:sB<n@9l>7n;6m:5a?2`>1J?*YN9[Z=^]@lv^5?'17/2803:/18-/5--3+-3-+1+)/)*0**3,+4--4,8?79C33=->I5]hTR[R+4+geUhfVigWigWigWhfVkeZmg\ck\mufDzv]vK2e5'd4&h;/m@4g@2g@2`D7`D7UJ5g\GCG.<@'FI+nqSZ_K38$7=57=57>37>39<78;65;5171-3-+1+(.))/*+1,-3.<F:?I=1?*BP;FOF/8/deTefUigWhfVifVjgWlf[mg\_l[iveҹž;fT<WE-\L3]M4TP9RN7JP6`fLBK0<E*II,hhK][FIG2;?5:>48>69?79?9;A;9?::@;:=98;7061+1,*/.(-,&5#9H69K37I1=J;.;,\fN_iQhjWgiVkhXkhXjhZigYbl`~®ȾmhIQL-SP3SP3MO6MO6HO2FM0LR.^d@beIUX<WV;UT9LJ:DB29@59@59C78B69A6:B7;B:=D<<D98@54>08B4E`7Gb9:L6?Q;JZD3C- \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/input_viff.miff b/PerlMagick/t/reference/read/input_viff.miff
new file mode 100644
index 0000000..7c05d7b
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_viff.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_wbmp.miff b/PerlMagick/t/reference/read/input_wbmp.miff
new file mode 100644
index 0000000..28f5028
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_wbmp.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_xbm.miff b/PerlMagick/t/reference/read/input_xbm.miff
new file mode 100644
index 0000000..5385a15
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_xbm.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_xc_black.miff b/PerlMagick/t/reference/read/input_xc_black.miff
new file mode 100644
index 0000000..a4aae46
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_xc_black.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_xpm.miff b/PerlMagick/t/reference/read/input_xpm.miff
new file mode 100644
index 0000000..1b6a588
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_xpm.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/input_xwd.miff b/PerlMagick/t/reference/read/input_xwd.miff
new file mode 100644
index 0000000..6dfa563
--- /dev/null
+++ b/PerlMagick/t/reference/read/input_xwd.miff
@@ -0,0 +1,6 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+comment=input.xwd
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/topol_1.miff b/PerlMagick/t/reference/read/topol_1.miff
new file mode 100644
index 0000000..36cce1b
--- /dev/null
+++ b/PerlMagick/t/reference/read/topol_1.miff
@@ -0,0 +1,8 @@
+id=ImageMagick version=1.0
+class=PseudoClass colors=256 matte=False
+columns=114 rows=87 depth=8
+
+:
+
+
+  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~Ƽp___dkpps~~pͿs____¿ɺ˿ykk_VVVZdddpy~Zd~v____ƿƿǷg__ZQLQVVVZkydVZs~syºvg___ºͺpZZ_ZQLQQQQVZdp~ºsVLQ_gdsɺ~g__Zƺ~_VQQLGG@@GLQZdpsvgQQQLQZpͺDZs_VVZ¼ǿkVLLQLQVVLGQZdkpvƿ~VLGGGGGQg¿ɮsgdd_ZVZp_QLGGGQ_dZLLLQ_ks±v_LGGGGGLVpǼǨysg_Z___dsdVLGG@:GQVQ@@LQZgy߿~QLG@@:@GLZs¼ƿvkp~~yº¿y_VLG@:@@@@@GQVVZkɿkVL@@@@@GLZv¼DZ¼s¼ɨvZLGG@:::::GV_gdZg¥sVVQG@@@GGQg¿¼ƿkƿ¿pZQGG@@:@@GLV_d__gyyk_gZQQQQVQsǿƼgºvZQG@GG@:@GLQVZ_dk¼_ZL_psy±Ʒd~¿ƿv_QLLG@@@GG@GLLpv¿«¼¿¿p¿sgdd_VLGGLQQZpº¼ƺv~p~ɼ¿k_ZgspdɿºǼ¿Ƽyvdsss¿ǿººZg~¿ƺǿѺԿ~yQZp¿´ƺǴsLZkƿʹ˿º¿ƴVkvvƿƴͿ~yQdyvpƿɷ˺GQZZ_v¼¼˱˱ƺɺ@GGGVvƺ˴ǼѴ:::GZy´ǿǼͱԫƴ:::L_sǼͼǼɼɴƷ::GL_y˿·ƴ´vkv_ǫƴ::@Ld~ƴǿvk_ZkϿkǺ˼L@GQdsºƺ¿sdVQZk˷˿ƫdLQ_gkvs_VQQZgvº˺ǷƷ~gVZddsǿ¼sZLGLQV_ky˿pZV_d_~_LGGGQVZgy·v¿kgVV_dgpƼǿpVL@@GLQ_ks¿Ǽ¿QLLQV_v¿ƿºdLG@@@GLVdp~˿ǿǷG@:GVg˿¼vV@@@:@GGGZks~kɼǷG@@GQksd˿ɼdVL@4.4:@LZgsҼQ@GQV_d__dsǼkgL@:44..:GLV_pƨgv·VVQLQVVQZdgdyǿgLkǺkZG:4....:@LLQdsͿvyk_ZZQGQdsvy˼kL@sϼdL::4.####:GLLVgp~ysp~ypZskpkZLGL_pvp_sɺdLQpV@4...###..:GQ_gpܱkLZpϴ~gZLG_dg_QLLZksyspvƷkZVsƱ~ZQG:4.##4@GQ_p~ǎpLGZ~Ϻ~~vdVL::QZZQGGGQZkssv´kQVkydQ@:4.##.4:GZ~_dyy͡vvpZdg_Q@:44QLG4.4LZdv~yys_QLps_L@:4..##.4@LgƺspǴsQVZ_ZG4...LG:44:Qddp~yvyƼpVVZkǺ~gVG@G@4.####..4:QksdVVZZV@4.##ZG:::@Q_dgvyv¿¼´_VQQV_ƺpV@::::4.....##4@Ldy·sZQQVVVL4..##dL44@QVVZdpvyƿǿydVQVVZkQG@::::44:44:GG_p~ټvdQLGLV_ZG4.#dQ:@QZVLGQZdksy~sdQs®vZQLLG@:@GGL_kyǿpZLG@:@GV__L4#ZL:@LLGGGGGQdy~·~sggdZQLQV_pvV@:4.4:GQZ_V@4##L@::@@@@@::G_v~~~vppyǿɼvkdG.....4@GQVQ:.##VQ@::::::4:@Q_pvsk¼ƿ®~ypV@4.##4:@QVL:.ZQ:4444444:@LVgsv~ǼϿyp_G4..##444GVQ:#LG:4...444:@LVdksy¼ϿpZL@4##.4GZV:4.@:4....444:@Vddddkv¿ɴ˺kQ:..@QQLLG44......4::4:GV_ZV_kyͼѡ_:#..4GQVdsdG4...##.4@GGGLLL_sǿººZ44@LLQ_py~d@.....####:LQQLGGVsvvǺƱ~Q:4##@QZZZssV:4...##:LZ_d_VVdvyyǿƼsZ@4.#.:GVZZvs_Q..##:@L_dVQ_gdpk@:4.#..4:L_gy~y..####.4GV__VZZQvsG...##:44@L_p4.#.4@LVQLQZgDZk@##........#4Qg4##.@GQQGQ_vɮ·gG4..4:@GG:4#4Qd:.###4:LQQ_d¿¼ϮvgVLV_Z_psgG#.L_~:.###4@GGVsƿ¿®ɼ~sssvpdVG4#:Lg@4##4::L_¼~ykL4#.4Lp@4####..:GZǿͺysgL.#.4GpǼ@4##.4:@Qd¼ǫv_L:##.4G_vG4####.4:::GQ~ƱѷkL.##.4GZvL4...##..:@@GLs±Ƿɴ~L:##.4@Z¼Q:4....4@LGL_ºɥZ:##.:LZd¿dL:..4@GQ~¿~ǺҺpQG:444:@LVdvsdLGLLQgϱƼ¿ٿ~s_Zdgp~ykk~~k_kpZdҿysy~~kZksk~¼y±DZ~~vVL_vsǼƱyyͿ~gG@QsppyL@:GdƴsgǼҿs_VQLgv~ys¿º~vsvy~vvɺ__p˺yv~~DZsdvɴy˴~ɴ®vdpk~±sVdy_@sǼyss~vd_dyy˷vgpvsgd__s~_ZdgdZVZ_sºgQQVVQLVZVy·ƱpZVZVVVLVdsѴͺ \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/topol_2.miff b/PerlMagick/t/reference/read/topol_2.miff
new file mode 100644
index 0000000..3abae46
--- /dev/null
+++ b/PerlMagick/t/reference/read/topol_2.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/topol_3.miff b/PerlMagick/t/reference/read/topol_3.miff
new file mode 100644
index 0000000..af08ae1
--- /dev/null
+++ b/PerlMagick/t/reference/read/topol_3.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=PseudoClass colors=16 matte=False
+columns=32 rows=32 depth=8
+
+:222FFFZZZnnn \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/topol_4.miff b/PerlMagick/t/reference/read/topol_4.miff
new file mode 100644
index 0000000..d5aff47
--- /dev/null
+++ b/PerlMagick/t/reference/read/topol_4.miff
Binary files differ
diff --git a/PerlMagick/t/reference/read/topol_5.miff b/PerlMagick/t/reference/read/topol_5.miff
new file mode 100644
index 0000000..89e0212
--- /dev/null
+++ b/PerlMagick/t/reference/read/topol_5.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=68 rows=44 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FF,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttt8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰ330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhty[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoq\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zh_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVa[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbETH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJ47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJ*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeK.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiO@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bi`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\Gi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_LhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFheVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJheVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRheVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTgdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP< \ No newline at end of file
diff --git a/PerlMagick/t/reference/read/topol_7.miff b/PerlMagick/t/reference/read/topol_7.miff
new file mode 100644
index 0000000..b25b712
--- /dev/null
+++ b/PerlMagick/t/reference/read/topol_7.miff
Binary files differ
diff --git a/PerlMagick/t/reference/ttf/annotate.miff b/PerlMagick/t/reference/ttf/annotate.miff
new file mode 100644
index 0000000..1e4be1c
--- /dev/null
+++ b/PerlMagick/t/reference/ttf/annotate.miff
Binary files differ
diff --git a/PerlMagick/t/reference/ttf/label.miff b/PerlMagick/t/reference/ttf/label.miff
new file mode 100644
index 0000000..25baa28
--- /dev/null
+++ b/PerlMagick/t/reference/ttf/label.miff
Binary files differ
diff --git a/PerlMagick/t/reference/ttf/read.miff b/PerlMagick/t/reference/ttf/read.miff
new file mode 100644
index 0000000..0d59ca0
--- /dev/null
+++ b/PerlMagick/t/reference/ttf/read.miff
Binary files differ
diff --git a/PerlMagick/t/reference/wmf/clock.miff b/PerlMagick/t/reference/wmf/clock.miff
new file mode 100644
index 0000000..b5ca6d5
--- /dev/null
+++ b/PerlMagick/t/reference/wmf/clock.miff
Binary files differ
diff --git a/PerlMagick/t/reference/wmf/fjftest.miff b/PerlMagick/t/reference/wmf/fjftest.miff
new file mode 100644
index 0000000..c607eeb
--- /dev/null
+++ b/PerlMagick/t/reference/wmf/fjftest.miff
Binary files differ
diff --git a/PerlMagick/t/reference/wmf/ski.miff b/PerlMagick/t/reference/wmf/ski.miff
new file mode 100644
index 0000000..be164a3
--- /dev/null
+++ b/PerlMagick/t/reference/wmf/ski.miff
Binary files differ
diff --git a/PerlMagick/t/reference/wmf/wizard.miff b/PerlMagick/t/reference/wmf/wizard.miff
new file mode 100644
index 0000000..e52e977
--- /dev/null
+++ b/PerlMagick/t/reference/wmf/wizard.miff
Binary files differ
diff --git a/PerlMagick/t/reference/write/output_p7.miff b/PerlMagick/t/reference/write/output_p7.miff
new file mode 100644
index 0000000..3bdd095
--- /dev/null
+++ b/PerlMagick/t/reference/write/output_p7.miff
Binary files differ
diff --git a/PerlMagick/t/setattribute.t b/PerlMagick/t/setattribute.t
new file mode 100644
index 0000000..5bcc252
--- /dev/null
+++ b/PerlMagick/t/setattribute.t
@@ -0,0 +1,240 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test setting & getting attributes.
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1, print "1..71\n"; }
+END {print "not ok 1\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't' || die 'Cd failed';
+
+# Determine if QuantumMagick is defined
+$image=Graphics::Magick->new;
+my $depth = $image->Get('depth');
+
+testSetAttribute('input.miff','adjoin','True');
+
+++$test;
+testSetAttribute('input.miff','adjoin','False');
+
+++$test;
+testSetAttribute('input.miff','antialias','True');
+
+++$test;
+testSetAttribute('input.miff','antialias','False');
+
+++$test;
+testSetAttribute('input.miff','compression','None');
+
+++$test;
+testSetAttribute('input.miff','compression','JPEG');
+
+++$test;
+testSetAttribute('input.miff','compression','LZW');
+
+++$test;
+testSetAttribute('input.miff','compression','RLE');
+
+++$test;
+testSetAttribute('input.miff','compression','Zip');
+
+++$test;
+testSetAttribute('input.miff','density','72x72');
+
+++$test;
+testSetAttribute('input.miff','dispose','Undefined');
+
+++$test;
+testSetAttribute('input.miff','dispose','None');
+
+++$test;
+testSetAttribute('input.miff','dispose','Background');
+
+++$test;
+testSetAttribute('input.miff','dispose','Previous');
+
+++$test;
+testSetAttribute('input.miff','delay',100);
+
+++$test;
+testSetAttribute('input.miff','dither','True');
+
+++$test;
+testSetAttribute('input.miff','dither','False');
+
+++$test;
+testSetAttribute('input.miff','display','bogus:0.0');
+
+++$test;
+testSetAttribute('input.miff','filename','bogus.jpg');
+
+++$test;
+testSetAttribute('input.miff','font',q/-*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-*/);
+
+++$test;
+testSetAttribute('input.miff','iterations',10);
+
+++$test;
+testSetAttribute('input.miff','interlace','None');
+
+++$test;
+testSetAttribute('input.miff','interlace','Line');
+
+++$test;
+testSetAttribute('input.miff','interlace','Plane');
+
+++$test;
+testSetAttribute('input.miff','interlace','Partition');
+
+++$test;
+testSetAttribute('input.miff','loop',100);
+
+++$test;
+testSetAttribute('input.miff','magick','TIFF');
+
+++$test;
+testSetAttribute('input.miff','monochrome','True');
+
+++$test;
+testSetAttribute('input.miff','monochrome','False');
+
+++$test;
+testSetAttribute('input.miff','page','595x842>+0+0');
+
+++$test;
+testSetAttribute('input.miff','pointsize',12);
+
+++$test;
+testSetAttribute('input.miff','preview','Rotate');
+
+++$test;
+testSetAttribute('input.miff','preview','Shear');
+
+++$test;
+testSetAttribute('input.miff','preview','Roll');
+
+++$test;
+testSetAttribute('input.miff','preview','Hue');
+
+++$test;
+testSetAttribute('input.miff','preview','Saturation');
+
+++$test;
+testSetAttribute('input.miff','preview','Brightness');
+
+++$test;
+testSetAttribute('input.miff','preview','JPEG');
+
+++$test;
+testSetAttribute('input.miff','preview','Spiff');
+
+++$test;
+testSetAttribute('input.miff','preview','Dull');
+
+++$test;
+testSetAttribute('input.miff','preview','Grayscale');
+
+++$test;
+testSetAttribute('input.miff','preview','Quantize');
+
+++$test;
+testSetAttribute('input.miff','preview','Despeckle');
+
+++$test;
+testSetAttribute('input.miff','preview','ReduceNoise');
+
+++$test;
+testSetAttribute('input.miff','preview','AddNoise');
+
+++$test;
+testSetAttribute('input.miff','preview','Sharpen');
+
+++$test;
+testSetAttribute('input.miff','preview','Blur');
+
+++$test;
+testSetAttribute('input.miff','preview','Threshold');
+
+++$test;
+testSetAttribute('input.miff','preview','EdgeDetect');
+
+++$test;
+testSetAttribute('input.miff','preview','Spread');
+
+++$test;
+testSetAttribute('input.miff','preview','Solarize');
+
+++$test;
+testSetAttribute('input.miff','preview','Shade');
+
+++$test;
+testSetAttribute('input.miff','preview','Raise');
+
+++$test;
+testSetAttribute('input.miff','preview','Segment');
+
+++$test;
+testSetAttribute('input.miff','preview','Solarize');
+
+++$test;
+testSetAttribute('input.miff','preview','Swirl');
+
+++$test;
+testSetAttribute('input.miff','preview','Implode');
+
+++$test;
+testSetAttribute('input.miff','preview','Wave');
+
+++$test;
+testSetAttribute('input.miff','preview','OilPaint');
+
+++$test;
+testSetAttribute('input.miff','preview','Charcoal');
+
+++$test;
+testSetAttribute('input.miff','quality',25);
+
+++$test;
+testSetAttribute('input.miff','scene',5);
+
+++$test;
+testSetAttribute('input.miff','subimage',9);
+
+++$test;
+testSetAttribute('input.miff','subrange',16);
+
+++$test;
+testSetAttribute('input.miff','server','mymachine:0.0');
+
+++$test;
+testSetAttribute('input.miff','size','25x25');
+
+++$test;
+testSetAttribute('input.miff','size','25x25');
+
+# I have no idea what this does
+++$test;
+testSetAttribute('input.miff','tile','some value');
+
+++$test;
+testSetAttribute('input.miff','texture','granite:');
+
+++$test;
+testSetAttribute('input.miff','verbose','True');
+
+++$test;
+testSetAttribute('input.miff','verbose','False');
+
diff --git a/PerlMagick/t/subroutines.pl b/PerlMagick/t/subroutines.pl
new file mode 100644
index 0000000..af54073
--- /dev/null
+++ b/PerlMagick/t/subroutines.pl
@@ -0,0 +1,1300 @@
+# Copyright (C) 2003-2016 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Common subroutines to support tests
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+require 't/features.pl';
+
+# Function which returns true if named feature is supported.
+sub featureSupported {
+ my ($feature) = @_;
+
+ #return ($feature ~~ @MAGICK_FEATURES);
+ #return (any {$_ eq $feature} @MAGICK_FEATURES)
+ return (grep {$_ eq $feature} @MAGICK_FEATURES)
+}
+
+#
+# Retrieve quantum depth
+#
+sub quantumDepth ( ) {
+ my($depth,$image);
+ $image=Graphics::Magick->new;
+ $depth=$image->Get('depth');
+ undef $image;
+ return $depth;
+}
+
+#
+# Establish some global constants (MaxRGB, OpaqueOpacity, & QuantumDepth)
+#
+$QuantumDepth=quantumDepth();
+$OpaqueOpacity=0;
+if ($QuantumDepth == 8)
+ {
+ $MaxRGB=255;
+ }
+elsif ($QuantumDepth == 16)
+ {
+ $MaxRGB=65535;
+ }
+elsif ($QuantumDepth == 32)
+ {
+ $MaxRGB=4294967295;
+ }
+
+#
+# Test composite method using comparison with a reference image
+#
+# Usage: testFilterCompare( background image name, background read options,
+# composite image name, composite read options,
+# composite options,reference image
+# normalized_mean_error,
+# normalized_maximum_error );
+sub testCompositeCompare {
+ my ($background_name,
+ $background_read_options,
+ $composite_name,
+ $composite_read_options,
+ $composite_options,
+ $refimage_name,
+ $normalized_mean_error_max,
+ $normalized_maximum_error_max) = @_;
+ my ($background,
+ $composite,
+ $errorinfo,
+ $normalized_maximum_error,
+ $normalized_mean_error,
+ $refimage,
+ $status);
+
+ $errorinfo='';
+ $status='';
+
+ # Create images
+ $background=Graphics::Magick->new;
+ $composite=Graphics::Magick->new;
+ $refimage=Graphics::Magick->new;
+
+ # Read background image
+ if ( "$background_read_options" ne "" ) {
+ print("Set($background_read_options) ...\n");
+ eval "\$status=\$background->Set($background_read_options);";
+ if ("$status")
+ {
+ $errorinfo = "Set($background_read_options): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ }
+ $status=$background->ReadImage($background_name);
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($background_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ # Read composite image
+ if ( "$composite_read_options" ne "" ) {
+ print("Set($composite_read_options) ...\n");
+ eval "\$status=\$composite->Set($composite_read_options);";
+ if ("$status")
+ {
+ $errorinfo = "Set($composite_read_options): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ }
+ $status=$composite->ReadImage($composite_name);
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($composite_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ # Do composition
+ print("Composite\($composite_options\) ...\n");
+ eval "\$status=\$background->Composite(image=>\$composite, $composite_options);";
+ if ("$status")
+ {
+ $errorinfo = "Composite ($composite_options): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ $background->set(depth=>8);
+# if ("$composite_options" =~ /Multiply/) {
+# $background->write(filename=>"$refimage_name", compression=>'None');
+# $background->Display();
+# }
+
+ $status=$refimage->ReadImage("$refimage_name");
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($refimage_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ $status=$background->Compare($refimage);
+ if ("$status")
+ {
+ $errorinfo = "Compare($refimage_name): $status";
+ print(" Computed: ", $background->Get('columns'), "x", $background->Get('rows'), "\n");
+ print(" Reference: ", $refimage->Get('columns'), "x", $refimage->Get('rows'), "\n");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ $normalized_mean_error=0;
+ $normalized_mean_error=$background->GetAttribute('mean-error');
+ if ( !defined($normalized_mean_error) )
+ {
+ $errorinfo = "GetAttribute('mean-error') returned undefined value!";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ $normalized_maximum_error=0;
+ $normalized_maximum_error=$background->GetAttribute('maximum-error');
+ if ( ! defined($normalized_maximum_error) )
+ {
+ $errorinfo = "GetAttribute('maximum-error') returned undefined value!";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ if ( ($normalized_mean_error > $normalized_mean_error_max) ||
+ ($normalized_maximum_error > $normalized_maximum_error_max) )
+ {
+ print(" mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
+ print "not ok $test\n";
+ defined $ENV{'PERL_DEBUG'} && $background->Display();
+ undef $background;
+ undef $composite;
+ undef $refimage;
+ return 1
+ }
+
+ undef $background;
+ undef $composite;
+ undef $refimage;
+ print "ok $test\n";
+ return 0;
+
+ COMPARE_RUNTIME_ERROR:
+ defined $ENV{'PERL_DEBUG'} && $composite->Display();
+ undef $background;
+ undef $composite;
+ undef $refimage;
+ print(" $errorinfo\n");
+ print "not ok $test\n";
+ return 1
+}
+
+#
+# Test reading a file in which several signatures are possible,
+# depending on available image depth.
+#
+# Usage: testRead( read filename, expected ref_8 [, expected ref_16] [, expected ref_32] );
+#
+sub testRead {
+ my( $infile, $ref_8, $ref_16, $ref_32 ) = @_;
+
+ my($image,$magick,$success,$depth,$ref_signature);
+
+ $failure=0;
+
+ if ( !defined( $ref_16 ) )
+ {
+ $ref_16 = $ref_8;
+ }
+ if ( !defined( $ref_32 ) )
+ {
+ $ref_32 = $ref_16;
+ }
+
+ $depth=quantumDepth();
+ if ($depth == 32)
+ {
+ $ref_signature=$ref_32;
+ }
+ elsif ($depth == 16)
+ {
+ $ref_signature=$ref_16;
+ }
+ else
+ {
+ $ref_signature=$ref_8;
+ }
+
+ $magick='';
+
+ #
+ # Test reading from file
+ #
+ {
+ my($image, $signature, $status);
+
+ print( " testing reading from file \"", $infile, "\" ...\n");
+ $image=Graphics::Magick->new;
+ $image->Set(size=>'512x512');
+ $status=$image->ReadImage("$infile");
+ if( "$status" && !($status =~ /Exception ((315)|(350))/)) {
+ print "ReadImage $infile: $status\n";
+ ++$failure;
+ } else {
+ if( "$status" ) {
+ print "ReadImage $infile: $status\n";
+ }
+ undef $status;
+ $magick=$image->Get('magick');
+ $signature=$image->Get('signature');
+
+ if ( $signature ne $ref_signature ) {
+ print "ReadImage()\n";
+ print "Image: $infile, signatures do not match.\n";
+ print " Computed: $signature\n";
+ print " Expected: $ref_signature\n";
+ print " Depth: $depth\n";
+ ++$failure;
+ defined $ENV{'PERL_DEBUG'} && $image->Display();
+ }
+ }
+ undef $image;
+ }
+
+ #
+ # Test reading from blob
+ #
+ if (!($infile =~ /\.bz2$/) && !($infile =~ /\.gz$/) && !($infile =~ /\.Z$/))
+ {
+ my(@blob, $blob_length, $image, $signature, $status);
+
+ if( open( FILE, "< $infile"))
+ {
+ print( " testing reading from BLOB with magick \"", $magick, "\"...\n");
+ binmode( FILE );
+ $blob_length = read( FILE, $blob, 10000000 );
+ close( FILE );
+ if( defined( $blob ) ) {
+ $image=Graphics::Magick->new(magick=>$magick);
+ $status=$image->BlobToImage( $blob );
+ undef $blob;
+ if( "$status" && !($status =~ /Exception ((315)|(350))/)) {
+ print "BlobToImage $infile: $status\n";
+ ++$failure;
+ } else {
+ if( "$status" ) {
+ print "ReadImage $infile: $status\n";
+ }
+ $signature=$image->Get('signature');
+ if ( $signature ne $ref_signature ) {
+ print "BlobToImage()\n";
+ print "Image: $infile, signatures do not match.\n";
+ print " Computed: $signature\n";
+ print " Expected: $ref_signature\n";
+ print " Depth: $depth\n";
+ defined $ENV{'PERL_DEBUG'} && $image->Display();
+ ++$failure;
+ }
+ }
+ }
+ }
+ undef $image;
+ }
+
+ #
+ # Display test status
+ #
+ if ( $failure != 0 ) {
+ print "not ok $test\n";
+ } else {
+ print "ok $test\n";
+ }
+}
+
+
+#
+# Test reading a file, and compare with a reference file
+#
+sub testReadCompare {
+ my( $srcimage_name,$refimage_name, $read_options,
+ $normalized_mean_error_max, $normalized_maximum_error_max) = @_;
+ my($srcimage, $refimage, $normalized_mean_error, $normalized_maximum_error);
+
+ $errorinfo='';
+
+ # Create images
+ $srcimage=Graphics::Magick->new;
+ $refimage=Graphics::Magick->new;
+
+ if ( "$read_options" ne "" ) {
+ eval "\$status=\$srcimage->Set($read_options);";
+ if ("$status")
+ {
+ $errorinfo = "Set($read_options): $status";
+ warn("$errorinfo");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ }
+
+ $status=$srcimage->ReadImage("$srcimage_name");
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($srcimage_name): $status";
+ warn("$errorinfo");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+# if ("$srcimage_name" eq "CGM:input.cgm") {
+# $srcimage->write(filename=>"$refimage_name", compression=>'None');
+# }
+
+ #print("writing file $refimage_name\n");
+ #$srcimage->Quantize(colors=>256);
+ #$status=$srcimage->write(filename=>"$refimage_name", compression=>'rle');
+ #warn "$status" if $status;
+
+ $status=$refimage->ReadImage("$refimage_name");
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($refimage_name): $status";
+ warn("$errorinfo");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ $srcimage->set(depth=>8);
+
+ # FIXME: The following statement should not be needed.
+# $status=$refimage->Set(type=>'TrueColor');
+# if ("$status")
+# {
+# $errorinfo = "Set(type=>'TrueColor'): $status";
+# goto COMPARE_RUNTIME_ERROR;
+# }
+
+ # Verify that $srcimage and $refimage contain the same number of frames.
+ if ( $#srcimage != $#refimage )
+ {
+ $errorinfo = "Source and reference images contain different number of frames ($#srcimage != $#refimage)";
+ warn("$errorinfo");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ # Compare each frame in the sequence.
+ for ($index = 0; $srcimage->[$index] && $refimage->[$index]; $index++)
+ {
+ $status=$srcimage->[$index]->Compare($refimage->[$index]);
+ if ("$status")
+ {
+ $errorinfo = "Compare($refimage_name)->[$index]: $status";
+ warn("$errorinfo");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ }
+
+ $normalized_mean_error=0;
+ $normalized_mean_error=$srcimage->GetAttribute('mean-error');
+ if ( !defined($normalized_mean_error) )
+ {
+ $errorinfo = "GetAttribute('mean-error') returned undefined value!";
+ warn("$errorinfo");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ $normalized_maximum_error=0;
+ $normalized_maximum_error=$srcimage->GetAttribute('maximum-error');
+ if ( ! defined($normalized_maximum_error) )
+ {
+ $errorinfo = "GetAttribute('maximum-error') returned undefined value!";
+ warn("$errorinfo");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ if ( ($normalized_mean_error > $normalized_mean_error_max) ||
+ ($normalized_maximum_error > $normalized_maximum_error_max) )
+ {
+ print("mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
+ defined $ENV{'PERL_DEBUG'} && $srcimage->Display();
+ print "not ok $test\n";
+ return 1
+ }
+
+ undef $srcimage;
+ undef $refimage;
+ print "ok $test\n";
+ return 0;
+
+ COMPARE_RUNTIME_ERROR:
+ $srcimage->Display();
+ $refimage->Display();
+ undef $srcimage;
+ undef $refimage;
+ print "not ok $test\n";
+ return 1
+}
+
+#
+# Test reading a file which requires a file size to read (GRAY, RGB, CMYK)
+# or supports multiple resolutions (JBIG, JPEG, PCD)
+#
+# Usage: testRead( read filename, size, depth, expected ref_8 [, expected ref_16] );
+#
+sub testReadSized {
+ my( $infile, $size, $depth, $ref_8, $ref_16, $ref_32 ) = @_;
+
+ my($image,$ref_signature);
+
+ if ( !defined( $ref_16 ) )
+ {
+ $ref_16 = $ref_8;
+ }
+ if ( !defined( $ref_32 ) )
+ {
+ $ref_32 = $ref_16;
+ }
+
+ $depth=quantumDepth();
+ if ($depth == 32)
+ {
+ $ref_signature=$ref_32;
+ }
+ elsif ($depth == 16)
+ {
+ $ref_signature=$ref_16;
+ }
+ else
+ {
+ $ref_signature=$ref_8;
+ }
+
+ $image=Graphics::Magick->new;
+
+ # Set size attribute
+ $status=$image->SetAttribute(size=>"$size");
+ warn "$status" if "$status";
+
+ # If depth is not zero, then set it
+ if ( $depth != 0 ) {
+ $status=$image->SetAttribute(depth=>"$depth");
+ warn "$status" if "$status";
+ }
+
+ $status=$image->ReadImage("$infile");
+ if( "$status" ) {
+ print "ReadImage $infile: $status";
+ print "not ok $test\n";
+ } else {
+ $signature=$image->Get('signature');
+ if ( $signature ne $ref_signature ) {
+ print "ReadImage()\n";
+ print "Image: $infile, signatures do not match.\n";
+ print " Computed: $signature\n";
+ print " Expected: $ref_signature\n";
+ print " Depth: $depth\n";
+ print "not ok $test\n";
+ defined $ENV{'PERL_DEBUG'} && $image->Display();
+ } else {
+ print "ok $test\n";
+ }
+ }
+}
+
+#
+# Test writing a file by first reading a source image, writing to a new image,
+# reading the written image, and comparing with expected REF_8.
+#
+# Usage: testReadWrite( read filename, write filename, write options,
+# expected ref_8 [, expected ref_16] );
+#
+# .e.g
+#
+# testReadWrite( 'input.jpg', 'output.jpg', q/quality=>80, interlace=>'None'/,
+# 'dc0a144a0b9480cd1e93757a30f01ae3' );
+#
+# If the REF_8 of the written image is not what is expected, the written
+# image is preserved. Otherwise, the written image is removed.
+#
+sub testReadWrite {
+ my( $infile, $outfile, $writeoptions, $ref_8, $ref_16, $ref_32 ) = @_;
+
+ my($image);
+
+ if ( !defined( $ref_16 ) )
+ {
+ $ref_16 = $ref_8;
+ }
+ if ( !defined( $ref_32 ) )
+ {
+ $ref_32 = $ref_16;
+ }
+
+ $depth=quantumDepth();
+ if ($depth == 32)
+ {
+ $ref_signature=$ref_32;
+ }
+ elsif ($depth == 16)
+ {
+ $ref_signature=$ref_16;
+ }
+ else
+ {
+ $ref_signature=$ref_8;
+ }
+
+ $image=Graphics::Magick->new;
+ $status=$image->ReadImage("$infile");
+ $signature=$image->Get('signature');
+ if( "$status" ) {
+ print "ReadImage $infile: $status\n";
+ print "not ok $test\n";
+ } else {
+ # Write image to file
+ my $options = 'filename=>"$outfile", ' . "$writeoptions";
+ #print "Using options: $options\n";
+ eval "\$status=\$image->WriteImage( $options ) ;";
+ if( $@ ) {
+ print "$@\n";
+ print "not ok $test\n";
+ exit 1;
+ }
+ if( "$status" ) {
+ print "WriteImage $outfile: $status\n";
+ print "not ok $test\n";
+ } else {
+ my($image);
+
+ # Read image just written
+ $image=Graphics::Magick->new;
+ $status=$image->ReadImage("$outfile");
+ if( "$status" ) {
+ print "ReadImage $outfile: $status\n";
+ print "not ok $test\n";
+ } else {
+ # Check signature
+ $signature=$image->Get('signature');
+ if ( $signature ne $ref_signature ) {
+ print "ReadImage()\n";
+ print "Image: $infile, signatures do not match.\n";
+ print " Computed: $signature\n";
+ print " Expected: $ref_signature\n";
+ print " Depth: $depth\n";
+ print "not ok $test\n";
+ defined $ENV{'PERL_DEBUG'} && $image->Display();
+ } else {
+ print "ok $test\n";
+ ($file = $outfile) =~ s/.*://g;
+ #unlink "$file";
+ }
+ }
+ }
+ }
+}
+
+#
+# Test reading a file, and compare with a reference file
+#
+sub testReadWriteCompare {
+ my( $srcimage_name, $outimage_name, $refimage_name,
+ $read_options, $write_options,
+ $normalized_mean_error_max, $normalized_maximum_error_max) = @_;
+ my($srcimage, $refimage, $normalized_mean_error,
+ $normalized_maximum_error);
+
+ $errorinfo='';
+
+ $image=Graphics::Magick->new;
+ $refimage=Graphics::Magick->new;
+
+ #
+ # Read the initial image
+ #
+ $status=$image->ReadImage($srcimage_name);
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($srcimage_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ #
+ # Write image to output file
+ #
+ if ( "$write_options" ne "" ) {
+ eval "\$status=\$image->Set($write_options);";
+ if ("$status")
+ {
+ $errorinfo = "Set($write_options): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ }
+ $image->Set(filename=>"$outimage_name");
+
+ $status=$image->WriteImage( );
+ if ("$status")
+ {
+ $errorinfo = "WriteImage ($outimage_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ undef $image;
+ $image=Graphics::Magick->new;
+
+ #
+ # Read image from output file
+ #
+ if ( "$read_options" ne "" ) {
+ eval "\$status=\$image->Set($read_options);";
+ if ("$status")
+ {
+ $errorinfo = "Set($read_options): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ }
+
+ $image->ReadImage("$outimage_name");
+ if ("$status")
+ {
+ $errorinfo = "WriteImage ($outimage_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+# eval "\$status=\$image->Set($write_options);";
+# if ("$outimage_name" eq "P7:output_p7.p7")
+# {
+# $status=$image->write(filename=>"$refimage_name", compression=>'None');
+# warn "$status" if $status;
+# }
+
+ #
+ # Read reference image
+ #
+ $status=$refimage->ReadImage("$refimage_name");
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($refimage_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ #
+ # Compare output file with reference image
+ #
+
+ $image->set(depth=>8);
+
+ # FIXME: The following statement should not be needed.
+# $status=$refimage->Set(type=>'TrueColor');
+# if ("$status")
+# {
+# $errorinfo = "Set(type=>'TrueColor'): $status";
+# goto COMPARE_RUNTIME_ERROR;
+# }
+
+ $status=$image->Compare($refimage);
+ if ("$status")
+ {
+ $errorinfo = "Compare($refimage_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ $normalized_mean_error=0;
+ $normalized_mean_error=$image->GetAttribute('mean-error');
+ if ( !defined($normalized_mean_error) )
+ {
+ $errorinfo = "GetAttribute('mean-error') returned undefined value!";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ $normalized_maximum_error=0;
+ $normalized_maximum_error=$image->GetAttribute('maximum-error');
+ if ( ! defined($normalized_maximum_error) )
+ {
+ $errorinfo = "GetAttribute('maximum-error') returned undefined value!";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ if ( ($normalized_mean_error > $normalized_mean_error_max) ||
+ ($normalized_maximum_error > $normalized_maximum_error_max) )
+ {
+ print("mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
+ print "not ok $test\n";
+ defined $ENV{'PERL_DEBUG'} && $image->Display();
+ return 1
+ }
+
+ print "ok $test\n";
+ undef $image;
+ undef $refimage;
+ return 0;
+
+ COMPARE_RUNTIME_ERROR:
+ warn("$errorinfo");
+ print "not ok $test\n";
+ undef $image;
+ undef $refimage;
+ return 1
+}
+
+#
+# Test writing a file by first reading a source image, writing to a
+# new image, and reading the written image. Depends on detecting
+# reported errors by ImageMagick
+#
+# Usage: testReadWrite( read filename, write filename, write options);
+#
+# .e.g
+#
+# testReadWrite( 'input.jpg', 'output.jpg', q/quality=>80, 'interlace'=>'None'/ );
+#
+# If the read of the written image is not what is expected, the
+# written image is preserved. Otherwise, the written image is
+# removed.
+#
+sub testReadWriteNoVerify {
+ my( $infile, $outfile, $writeoptions) = @_;
+
+ my($image, $images);
+
+ $image=Graphics::Magick->new;
+ $status=$image->ReadImage("$infile");
+ if( "$status" ) {
+ print "$status\n";
+ print "ReadImage $infile: not ok $test\n";
+ } else {
+ # Write image to file
+ my $options = 'filename=>"$outfile", ' . $writeoptions;
+ #print "Using options: $options\n";
+ eval "\$status=\$image->WriteImage( $options ) ;";
+ if( $@ ) {
+ print "$@";
+ print "not ok $test\n";
+ exit 1;
+ }
+ if( "$status" ) {
+ print "WriteImage $outfile: $status\n";
+ print "not ok $test\n";
+ } else {
+ my($image);
+
+ # Read image just written
+ $image=Graphics::Magick->new;
+ $status=$image->ReadImage("$outfile");
+ if( "$status" ) {
+ print "ReadImage $outfile: $status\n";
+ print "not ok $test\n";
+ } else {
+ print "ok $test\n";
+ unlink $outfile;
+ }
+ }
+ }
+}
+
+#
+# Test writing a file by first reading a source image, writing to a new image,
+# reading the written image, and comparing with expected REF_8.
+#
+# Usage: testReadWriteSized( read filename,
+# write filename,
+# read filename size,
+# read filename depth,
+# write options,
+# expected ref_8 [,expected ref_16] );
+#
+# .e.g
+#
+# testReadWriteSized( 'input.jpg', 'output.jpg', '70x46', 8, q/quality=>80,
+# 'interlace'=>'None'/, 'dc0a144a0b9480cd1e93757a30f01ae3' );
+#
+# If the REF_8 of the written image is not what is expected, the written
+# image is preserved. Otherwise, the written image is removed. A depth of 0 is
+# ignored.
+#
+sub testReadWriteSized {
+ my( $infile, $outfile, $size, $readdepth, $writeoptions, $ref_8, $ref_16,
+ $ref_32 ) = @_;
+
+ my($image,$depth,$ref_signature);
+
+ if ( !defined( $ref_16 ) )
+ {
+ $ref_16 = $ref_8;
+ }
+ if ( !defined( $ref_32 ) )
+ {
+ $ref_32 = $ref_16;
+ }
+
+ $depth=quantumDepth();
+ if ($depth == 32)
+ {
+ $ref_signature=$ref_32;
+ }
+ elsif ($depth == 16)
+ {
+ $ref_signature=$ref_16;
+ }
+ else
+ {
+ $ref_signature=$ref_8;
+ }
+
+ $image=Graphics::Magick->new;
+
+ #$image->SetAttribute(debug=>'transform');
+
+ # Set size attribute
+ $status=$image->SetAttribute(size=>"$size");
+ warn "$status" if "$status";
+
+ # If read depth is not zero, then set it
+ if ( $readdepth != 0 ) {
+ $status=$image->SetAttribute(depth=>$readdepth);
+ warn "$status" if "$status";
+ }
+
+ $status=$image->ReadImage("$infile");
+ if( "$status" ) {
+ print "ReadImage $infile: $status\n";
+ print "not ok $test\n";
+ } else {
+ # Write image to file
+ my $options = 'filename=>"$outfile", ' . "$writeoptions";
+ #print "Using options: $options\n";
+ eval "\$status=\$image->WriteImage( $options ) ;";
+ if( $@ ) {
+ print "$@\n";
+ print "not ok $test\n";
+ exit 1;
+ }
+ if( "$status" ) {
+ print "WriteImage $outfile: $status\n";
+ print "not ok $test\n";
+ } else {
+ my($image);
+
+ $image=Graphics::Magick->new;
+
+ if ( $readdepth != 0 ) {
+ $status=$image->SetAttribute(depth=>$readdepth);
+ warn "$status" if "$status";
+ }
+ # Set image size attribute
+ $status=$image->SetAttribute(size=>"$size");
+ warn "$status" if "$status";
+
+ # Read image just written
+ $status=$image->ReadImage("$outfile");
+ if( "$status" ) {
+ print "ReadImage $outfile: $status\n";
+ print "not ok $test\n";
+ } else {
+ # Check signature
+ $signature=$image->Get('signature');
+
+ if ( $signature ne $ref_signature ) {
+ print "ReadImage()\n";
+ print "Image: $infile, signatures do not match.\n";
+ print " Computed: $signature\n";
+ print " Expected: $ref_signature\n";
+ print " Depth: $depth\n";
+ print "not ok $test\n";
+ defined $ENV{'PERL_DEBUG'} && $image->Display();
+ } else {
+ print "ok $test\n";
+ #$image->Display();
+ ($file = $outfile) =~ s/.*://g;
+ unlink "$file";
+ }
+ }
+ }
+ }
+}
+
+#
+# Test SetAttribute method
+#
+# Usage: testSetAttribute( name, attribute);
+#
+sub testSetAttribute {
+ my( $srcimage, $name, $attribute ) = @_;
+
+ my($image);
+
+ # Create temporary image
+ $image=Graphics::Magick->new;
+
+ $status=$image->ReadImage("$srcimage");
+ warn "Readimage: $status" if "$status";
+
+ # Set image option
+ print "Image Option : $name=>$attribute\n";
+ eval "\$status = \$image->Set('$name'=>'$attribute') ;";
+ warn "SetImage: $status" if "$status";
+
+ # Convert input values to expected output values
+ $expected=$attribute;
+ if ($attribute eq 'True' || $attribute eq 'true') {
+ $expected = 1;
+ } elsif ($attribute eq 'False' || $attribute eq 'false') {
+ $expected = 0;
+ }
+
+
+ $value=$image->GetAttribute($name);
+
+ if( defined( $value ) ) {
+ if ("$expected" eq "$value") {
+ print "ok $test\n";
+ } else {
+ print "Expected ($expected), Got ($value)\n";
+ print "not ok $test\n";
+ }
+ } else {
+ print "GetAttribute returned undefined value!\n";
+ print "not ok $test\n";
+ }
+}
+
+#
+# Test GetAttribute method
+#
+# Usage: testGetAttribute( name, expected);
+#
+sub testGetAttribute {
+ my( $srcimage, $name, $expected ) = @_;
+
+ my($image);
+
+ # Create temporary image
+ $image=Graphics::Magick->new;
+
+ $status=$image->ReadImage("$srcimage");
+ warn "Readimage: $status" if "$status";
+
+ $value=$image->GetAttribute($name);
+
+ if( !defined( $expected ) && !defined( $value ) ) {
+ # Undefined value is expected
+ print "ok $test\n";
+ } elsif ( !defined( $value ) ) {
+ print "Expected ($expected), Got (undefined)\n";
+ print "not ok $test\n";
+ } else {
+ if ("$expected" eq "$value") {
+ print "ok $test\n";
+ } else {
+ print "Expected ($expected), Got ($value)\n";
+ print "not ok $test\n";
+ }
+ }
+}
+
+#
+# Test MontageImage method
+#
+# Usage: testMontage( input image attributes, montage options, expected REF_8
+# [, expected REF_16] );
+#
+sub testMontage {
+ my( $imageOptions, $montageOptions, $ref_8, $ref_16, $ref_32 ) = @_;
+
+ my($image,$depth,$ref_signature);
+
+ if ( !defined( $ref_16 ) )
+ {
+ $ref_16 = $ref_8;
+ }
+ if ( !defined( $ref_32 ) )
+ {
+ $ref_32 = $ref_16;
+ }
+
+ $depth=quantumDepth();
+ if ($depth == 32)
+ {
+ $ref_signature=$ref_32;
+ }
+ elsif ($depth == 16)
+ {
+ $ref_signature=$ref_16;
+ }
+ else
+ {
+ $ref_signature=$ref_8;
+ }
+
+ # Create image for image list
+ $images=Graphics::Magick->new;
+
+ # Create temporary image
+ $image=Graphics::Magick->new;
+
+ my @colors = ( '#000000', '#008000', '#C0C0C0', '#00FF00',
+ '#808080', '#808000', '#FFFFFF', '#FFFF00',
+ '#800000', '#000080', '#FF0000', '#0000FF',
+ '#800080', '#008080', '#FF00FF', '#00FFFF' );
+
+ my $color;
+ foreach $color ( @colors ) {
+
+ # Generate image
+ $image->Set(size=>'50x50');
+ #print("\$image->ReadImage(xc:$color);\n");
+ $status=$image->ReadImage("xc:$color");
+ if ("$status") {
+ warn "Readimage: $status" if "$status";
+ } else {
+ # Add image to list
+ push( @$images, @$image);
+ }
+ undef @$image;
+ }
+
+ # Set image options
+ if ("$imageOptions" ne "") {
+ print("\$images->Set($imageOptions)\n");
+ eval "\$status = \$images->Set($imageOptions) ;";
+ warn "SetImage: $status" if "$status";
+ }
+
+ #print "Border color : ", $images->Get('bordercolor'), "\n";
+ #print "Matte color : ", $images->Get('mattecolor'), "\n";
+ #print "Pen color : ", $images->Get('pen'), "\n";
+
+ # Do montage
+ #print "Montage Options: $montageOptions\n";
+ print("\$montage=\$images->Montage( $montageOptions )\n");
+ eval "\$montage=\$images->Montage( $montageOptions ) ;";
+ if( $@ ) {
+ print "$@";
+ print "not ok $test\n";
+ return 1;
+ }
+
+ if( ! ref($montage) ) {
+ print "not ok $test\n";
+ } else {
+ # Check REF_8 signature
+ # $montage->Display();
+ $signature=$montage->GetAttribute('signature');
+ if ( defined( $signature ) ) {
+ if ( $signature ne $ref_signature ) {
+ print "ReadImage()\n";
+ print "Test $test, signatures do not match.\n";
+ print " Computed: $signature\n";
+ print " Expected: $ref_signature\n";
+ print " Depth: $depth\n";
+ $status = $montage->Write("test_${test}_out.miff");
+ warn "Write: $status" if "$status";
+
+ print "not ok $test\n";
+ } else {
+ # Check montage directory
+ my $directory = $montage->Get('directory');
+ my $expected = join( "\n", @colors ) . "\n";
+ if ( !defined($directory) ) {
+ print "ok $test\n";
+ } elsif ( $directory ne $expected) {
+ print("Invalid montage directory:\n\"$directory\"\n");
+ print("Expected:\n\"$expected\"\n");
+ print "not ok $test\n";
+ } else {
+ # Check montage geometry
+ $montage_geom=$montage->Get('montage');
+ if( !defined($montage_geom) ) {
+ print("Montage geometry not defined!\n");
+ print "not ok $test\n";
+ } elsif ( $montage_geom !~ /^\d+x\d+\+\d+\+\d+$/ ) {
+ print("Montage geometry not in correct format: \"$montage_geom\"\n");
+ print "not ok $test\n";
+ } else {
+ print "ok $test\n";
+ }
+ }
+ }
+ } else {
+ warn "GetAttribute returned undefined value!";
+ print "not ok $test\n";
+ }
+ }
+}
+
+#
+# Test filter method using signature compare
+#
+# Usage: testFilterSignature( input image attributes, filter, options, expected REF_8
+# [, expected REF_16] );
+#
+sub testFilterSignature {
+ my( $srcimage, $filter, $filter_options, $ref_8, $ref_16, $ref_32 ) = @_;
+
+ my($image,$depth,$ref_signature);
+
+# print( $filter, " ...\n" );
+
+ if ( !defined( $ref_16 ) )
+ {
+ $ref_16 = $ref_8;
+ }
+ if ( !defined( $ref_32 ) )
+ {
+ $ref_32 = $ref_16;
+ }
+
+ $depth=quantumDepth();
+ if ($depth == 32)
+ {
+ $ref_signature=$ref_32;
+ }
+ elsif ($depth == 16)
+ {
+ $ref_signature=$ref_16;
+ }
+ else
+ {
+ $ref_signature=$ref_8;
+ }
+
+ # Create temporary image
+ $image=Graphics::Magick->new;
+
+ $status=$image->ReadImage("$srcimage");
+ warn "Readimage: $status" if "$status";
+
+ print("$filter\($filter_options\) ...\n");
+ $image->$filter($filter_options);
+#$image->write(filename=>"reference/filter/$filter.miff", compression=>'None');
+
+ $signature=$image->GetAttribute('signature');
+ if ( defined( $signature ) ) {
+ if ( $signature ne $ref_signature ) {
+ print "Test $test, signatures do not match.\n";
+ print " Computed: $signature\n";
+ print " Expected: $ref_signature\n";
+ print " Depth: $depth\n";
+ defined $ENV{'PERL_DEBUG'} && $image->Display();
+ print "not ok $test\n";
+ } else {
+ print "ok $test\n";
+ }
+ } else {
+ warn "GetAttribute returned undefined value!";
+ print "not ok $test\n";
+ }
+}
+
+#
+# Test filter method using comparison with reference image
+#
+# Usage: testFilterCompare( input image, input image options, reference image, filter, filter options,
+# normalized_mean_error,
+# normalized_maximum_error );
+sub testFilterCompare {
+ my ($srcimage_name, $src_read_options, $refimage_name, $filter,
+ $filter_options, $normalized_mean_error_max,
+ $normalized_maximum_error_max) = @_;
+ my($srcimage, $refimage, $normalized_mean_error,
+ $normalized_maximum_error);
+ my($status,$errorinfo);
+
+ $errorinfo='';
+ $status='';
+
+ #print( $filter, " ...\n" );
+
+ # Create images
+ $srcimage=Graphics::Magick->new;
+ $refimage=Graphics::Magick->new;
+
+ if ( "$src_read_options" ne "" ) {
+ print("Set($src_read_options) ...\n");
+ eval "\$status=\$srcimage->Set($src_read_options);";
+ if ("$status")
+ {
+ $errorinfo = "Set($src_read_options): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ }
+
+ $status=$srcimage->ReadImage($srcimage_name);
+ #eval "\$status=\$srcimage->ReadImage($srcimage_name);";
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($srcimage_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ print("$filter\($filter_options\) ...\n");
+ eval "\$status=\$srcimage->$filter($filter_options);";
+ if ("$status")
+ {
+ $errorinfo = "$filter ($filter_options): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ $srcimage->set(depth=>8);
+# if ("$filter" eq "Shear") {
+# $srcimage->Display();
+# $srcimage->write(filename=>"$refimage_name", compression=>'None');
+# }
+
+ $status=$refimage->ReadImage("$refimage_name");
+ if ("$status")
+ {
+ $errorinfo = "Readimage ($refimage_name): $status";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ # FIXME: The following statement should not be needed.
+# $status=$refimage->Set(type=>'TrueColor');
+# if ("$status")
+# {
+# $errorinfo = "Set(type=>'TrueColor'): $status";
+# goto COMPARE_RUNTIME_ERROR;
+# }
+
+ $status=$srcimage->Compare($refimage);
+ if ("$status")
+ {
+ $errorinfo = "Compare($refimage_name): $status";
+ print(" Computed: ", $srcimage->Get('columns'), "x", $srcimage->Get('rows'), "\n");
+ print(" Reference: ", $refimage->Get('columns'), "x", $refimage->Get('rows'), "\n");
+ goto COMPARE_RUNTIME_ERROR;
+ }
+
+ $normalized_mean_error=0;
+ $normalized_mean_error=$srcimage->GetAttribute('mean-error');
+ if ( !defined($normalized_mean_error) )
+ {
+ $errorinfo = "GetAttribute('mean-error') returned undefined value!";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ $normalized_maximum_error=0;
+ $normalized_maximum_error=$srcimage->GetAttribute('maximum-error');
+ if ( ! defined($normalized_maximum_error) )
+ {
+ $errorinfo = "GetAttribute('maximum-error') returned undefined value!";
+ goto COMPARE_RUNTIME_ERROR;
+ }
+ if ( ($normalized_mean_error > $normalized_mean_error_max) ||
+ ($normalized_maximum_error > $normalized_maximum_error_max) )
+ {
+ print(" mean-error=$normalized_mean_error, maximum-error=$normalized_maximum_error\n");
+ print "not ok $test\n";
+ defined $ENV{'PERL_DEBUG'} && $srcimage->Display();
+ undef $srcimage;
+ undef $refimage;
+ return 1
+ }
+
+ undef $srcimage;
+ undef $refimage;
+ print "ok $test\n";
+ return 0;
+
+ COMPARE_RUNTIME_ERROR:
+ undef $srcimage;
+ undef $refimage;
+ print(" $errorinfo\n");
+ print "not ok $test\n";
+ return 1
+}
+1;
diff --git a/PerlMagick/t/tiff/input_gray_01bit_minwhite.cals b/PerlMagick/t/tiff/input_gray_01bit_minwhite.cals
new file mode 100644
index 0000000..ea55f5a
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_01bit_minwhite.cals
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_01bit_minwhite.tiff b/PerlMagick/t/tiff/input_gray_01bit_minwhite.tiff
new file mode 100644
index 0000000..d822ef6
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_01bit_minwhite.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_04bit.tiff b/PerlMagick/t/tiff/input_gray_04bit.tiff
new file mode 100644
index 0000000..4f1ccfa
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_04bit.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_04bit_matte.tiff b/PerlMagick/t/tiff/input_gray_04bit_matte.tiff
new file mode 100644
index 0000000..f2c0c3b
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_04bit_matte.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_08bit.tiff b/PerlMagick/t/tiff/input_gray_08bit.tiff
new file mode 100644
index 0000000..9dd3afc
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_08bit.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_08bit_matte.tiff b/PerlMagick/t/tiff/input_gray_08bit_matte.tiff
new file mode 100644
index 0000000..8f9be96
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_08bit_matte.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_10bit.tiff b/PerlMagick/t/tiff/input_gray_10bit.tiff
new file mode 100644
index 0000000..b37aeb2
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_10bit.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_12bit.tiff b/PerlMagick/t/tiff/input_gray_12bit.tiff
new file mode 100644
index 0000000..24ce6a4
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_12bit.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_14bit.tiff b/PerlMagick/t/tiff/input_gray_14bit.tiff
new file mode 100644
index 0000000..49a4e2d
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_14bit.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_16bit.tiff b/PerlMagick/t/tiff/input_gray_16bit.tiff
new file mode 100644
index 0000000..825f300
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_16bit.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_gray_32bit.tiff b/PerlMagick/t/tiff/input_gray_32bit.tiff
new file mode 100644
index 0000000..3b39e71
--- /dev/null
+++ b/PerlMagick/t/tiff/input_gray_32bit.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_palette_16.tiff b/PerlMagick/t/tiff/input_palette_16.tiff
new file mode 100644
index 0000000..b5f5e37
--- /dev/null
+++ b/PerlMagick/t/tiff/input_palette_16.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_palette_16_matte.tiff b/PerlMagick/t/tiff/input_palette_16_matte.tiff
new file mode 100644
index 0000000..016b87f
--- /dev/null
+++ b/PerlMagick/t/tiff/input_palette_16_matte.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_palette_256.tiff b/PerlMagick/t/tiff/input_palette_256.tiff
new file mode 100644
index 0000000..401e5bc
--- /dev/null
+++ b/PerlMagick/t/tiff/input_palette_256.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_palette_256_matte.tiff b/PerlMagick/t/tiff/input_palette_256_matte.tiff
new file mode 100644
index 0000000..6cefedd
--- /dev/null
+++ b/PerlMagick/t/tiff/input_palette_256_matte.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_palette_256_planar_contig.tiff b/PerlMagick/t/tiff/input_palette_256_planar_contig.tiff
new file mode 100644
index 0000000..401e5bc
--- /dev/null
+++ b/PerlMagick/t/tiff/input_palette_256_planar_contig.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_palette_256_planar_separate.tiff b/PerlMagick/t/tiff/input_palette_256_planar_separate.tiff
new file mode 100644
index 0000000..a283050
--- /dev/null
+++ b/PerlMagick/t/tiff/input_palette_256_planar_separate.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_08.tiff b/PerlMagick/t/tiff/input_truecolor_08.tiff
new file mode 100644
index 0000000..6bf9bf9
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_08.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_08_matte.tiff b/PerlMagick/t/tiff/input_truecolor_08_matte.tiff
new file mode 100644
index 0000000..a725939
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_08_matte.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_08_planar.tiff b/PerlMagick/t/tiff/input_truecolor_08_planar.tiff
new file mode 100644
index 0000000..4841459
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_08_planar.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_08_stripped.tiff b/PerlMagick/t/tiff/input_truecolor_08_stripped.tiff
new file mode 100644
index 0000000..0b25676
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_08_stripped.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_08_tiled32x32.tiff b/PerlMagick/t/tiff/input_truecolor_08_tiled32x32.tiff
new file mode 100644
index 0000000..382d5a7
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_08_tiled32x32.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_10.tiff b/PerlMagick/t/tiff/input_truecolor_10.tiff
new file mode 100644
index 0000000..757f12e
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_10.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_12.tiff b/PerlMagick/t/tiff/input_truecolor_12.tiff
new file mode 100644
index 0000000..017019c
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_12.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_14.tiff b/PerlMagick/t/tiff/input_truecolor_14.tiff
new file mode 100644
index 0000000..454607c
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_14.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_16.tiff b/PerlMagick/t/tiff/input_truecolor_16.tiff
new file mode 100644
index 0000000..6772f74
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_16.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/input_truecolor_32.tiff b/PerlMagick/t/tiff/input_truecolor_32.tiff
new file mode 100644
index 0000000..78cc359
--- /dev/null
+++ b/PerlMagick/t/tiff/input_truecolor_32.tiff
Binary files differ
diff --git a/PerlMagick/t/tiff/read.t b/PerlMagick/t/tiff/read.t
new file mode 100644
index 0000000..63f18e0
--- /dev/null
+++ b/PerlMagick/t/tiff/read.t
@@ -0,0 +1,256 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003, 2004, 2005 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading TIFF images
+#
+# Written by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..27\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/tiff' || die 'Cd failed';
+
+#
+# 1) Test Reading Monochrome
+#
+print("Monochrome (min-is-white) ...\n");
+testRead ( 'input_gray_01bit_minwhite.tiff',
+ '2b48bcf7d93cc31a8deb3026d872f1bb0a300b0f4e177423e5301adc638179e4' );
+
+#
+# 2) Test reading PseudoColor (16 color)
+#
+++$test;
+print("PseudoColor (16 color)...\n");
+testRead( 'input_palette_16.tiff',
+ 'a0313f6235a3158655412e1480c2f37549d89a5cacf40abc854811af1b757159' );
+
+#
+# 3) Test reading PseudoColor (16 color + matte channel)
+#
+++$test;
+print("PseudoColor (16 color + matte channel) ...\n");
+testRead( 'input_palette_16_matte.tiff',
+ '631c0997280217f3f430336513f1e51fe03e04f552d49a848449a438c100aa20' );
+
+#
+# 4) Test reading PseudoColor (256 color)
+#
+++$test;
+print("PseudoColor (256 color) ...\n");
+testRead( 'input_palette_256.tiff',
+ 'a570df6d4c214d08bccaaee856f617883fee4f96494af6ef5e25c76d86ea0e0a' );
+
+#
+# 5) Test reading PseudoColor (256 color + matte channel)
+#
+++$test;
+print("PseudoColor (256 color + matte channel) ...\n");
+testRead( 'input_palette_256_matte.tiff',
+ 'a3f865320dc8b7953850babbd22d468d821c0103cc14063d6459159506a910d6' );
+
+#
+# 6) Test reading PseudoColor using contiguous planar packing
+#
+++$test;
+print("PseudoColor (256 color) contiguous planes ...\n");
+testRead( 'input_palette_256_planar_contig.tiff',
+ 'a570df6d4c214d08bccaaee856f617883fee4f96494af6ef5e25c76d86ea0e0a' );
+
+#
+# 7) Test reading PseudoColor using seperate planes
+#
+++$test;
+print("PseudoColor (256 color) seperate planes ...\n");
+testRead( 'input_palette_256_planar_separate.tiff',
+ 'a570df6d4c214d08bccaaee856f617883fee4f96494af6ef5e25c76d86ea0e0a' );
+
+#
+# 8) Test Reading TrueColor (8-bit)
+#
+++$test;
+print("TrueColor (8-bit) image ...\n");
+testRead( 'input_truecolor_08.tiff',
+ '326599218925e7aa27c735d482332744cccf41f460a1ba2d276a2d172f2b3de0' );
+
+#
+# 9) Test Reading TrueColor (8-bit + matte channel)
+#
+++$test;
+print("TrueColor (8-bit) image with alpha channel ...\n");
+testRead( 'input_truecolor_08_matte.tiff',
+ 'e4f197c0de1bd1e9c43c3659953a4af81dda6d56433840c6ce508e3a2bb757e4' );
+
+#
+# 10) Test Reading TrueColor (10-bit)
+#
+++$test;
+print("TrueColor (10-bit) image ...\n");
+testRead( 'input_truecolor_10.tiff',
+ 'e70080518fa43632e7896300d6614a4d1c39ad02efd3d6ab8c70a35f63364193',
+ 'f38f0d191bce9aebd4e99229dfbe07e82fc68d8b95d9049abb53c532f471f5e0',
+ '59178f8b7f9df6dd59b2965161100db5b11fd4d46d0a790c7393c82f8b6a4f84' );
+
+#
+# 11) Test Reading TrueColor (12-bit)
+#
+++$test;
+print("TrueColor (12-bit) image ...\n");
+testRead( 'input_truecolor_12.tiff',
+ 'e70080518fa43632e7896300d6614a4d1c39ad02efd3d6ab8c70a35f63364193',
+ 'db9e9a4bc0b315f4dea136fbfd90181909cefb9bbdafd7f47d9c267b54f9197c',
+ '56ff48dbfbe3602198010130717523664d83068cd41cf27422414bd4385abda0' );
+
+#
+# 12) Test Reading TrueColor (14-bit)
+#
+++$test;
+print("TrueColor (14-bit) image ...\n");
+testRead( 'input_truecolor_14.tiff',
+ 'e70080518fa43632e7896300d6614a4d1c39ad02efd3d6ab8c70a35f63364193',
+ '8a897778184d453e5e681943e286f6cd34c8d5004a00132e81613debcd333f8f',
+ '412b3f0188113505c79dc226eef901b25e5f66d8bae28eb832e48c89eb139e81' );
+
+#
+# 13) Test Reading TrueColor (16-bit)
+#
+++$test;
+print("TrueColor (16-bit) image ...\n");
+testRead( 'input_truecolor_16.tiff',
+ '1030dc73bdc72c846831d10b661539e7a9e9c24a170f24ffdffaeae1a8aa769d',
+ '72fd047e4f5942b4edc96e8b16444580e9eb1f265017dd6bb11795a842e58d58' );
+
+#
+# 14) Test Reading TrueColor (32-bit)
+#
+++$test;
+print("TrueColor (32-bit) image ...\n");
+testRead( 'input_truecolor_32.tiff',
+ '2f32110a0c8e1c360420e49e02bea23de84e5772581326185b38629b69fc5d2a',
+ '845c70b06bea5c43360fe50b8e6e70009631bb761ce5e96e970a8587fee60cb5',
+ '8fa932366715755135be018e7da7b4417b2628f582a1ba5b371a80a840f5b791');
+
+#
+# 15) Test Reading 8-bit TrueColor Tiled (32x32 tiles)
+#
+++$test;
+print("TrueColor (8-bit) tiled image, 32x32 tiles ...\n");
+testRead( 'input_truecolor_08_tiled32x32.tiff',
+ '326599218925e7aa27c735d482332744cccf41f460a1ba2d276a2d172f2b3de0' );
+
+#
+# 16) Test Reading 8-bit TrueColor Planar
+#
+++$test;
+print("TrueColor (8-bit) planar image ...\n");
+testRead( 'input_truecolor_08_planar.tiff',
+ '326599218925e7aa27c735d482332744cccf41f460a1ba2d276a2d172f2b3de0' );
+
+#
+# 17) Test Reading 8-bit TrueColor Stripped (8 rows per strip)
+#
+++$test;
+print("TrueColor (8-bit) stripped image, 8 rows per strip ...\n");
+testRead( 'input_truecolor_08_stripped.tiff',
+ '326599218925e7aa27c735d482332744cccf41f460a1ba2d276a2d172f2b3de0' );
+
+#
+# 18) Test Reading Grayscale 4-bit
+#
+++$test;
+print("Grayscale (4-bit) ...\n");
+testRead( 'input_gray_04bit.tiff',
+ '45c0655a417852480336d5e12d7bb16b9647d911b11589e9d000a05dd1813570');
+
+#
+# 19) Test Reading Grayscale 4-bit + matte
+#
+++$test;
+print("Grayscale (4-bit + matte) ...\n");
+testRead( 'input_gray_04bit_matte.tiff',
+ '1e4ca36f33b13d8799bcda20108d20c1a2da913c27eb7872d95a6928cb8b0b48');
+
+#
+# 20) Test Reading Grayscale 8-bit
+#
+++$test;
+print("Grayscale (8-bit) ...\n");
+testRead( 'input_gray_08bit.tiff',
+ '00f6147d547f5a654369a5b41d18f0b44b38f9cc753c773f384808b9a18cac92');
+
+#
+# 21) Test Reading Grayscale 8-bit + matte
+#
+++$test;
+print("Grayscale (8-bit + matte) ...\n");
+testRead( 'input_gray_08bit_matte.tiff',
+ '70e1e096e53af6a312ec6aa54890a59b35d3c6932dfc052d6b355f62733635be');
+
+#
+# 22) Test Reading Grayscale 10-bit
+#
+++$test;
+print("Grayscale (10-bit) ...\n");
+testRead( 'input_gray_10bit.tiff',
+ 'c52de8e70c226c7872e1384e119532791ea9955a01485ae68bbc1236d3f9f9ee',
+ 'b278e43185a407d0419768dc57f2e714597cdb8f3b6c80278a6307af68a0a5f1',
+ 'b5be0d42f6e491343f86744af8fcd4b51ef70373fad69593046a27ad2d805788');
+
+#
+# 23) Test Reading Grayscale 12-bit
+#
+++$test;
+print("Grayscale (12-bit) ...\n");
+testRead( 'input_gray_12bit.tiff',
+ 'c52de8e70c226c7872e1384e119532791ea9955a01485ae68bbc1236d3f9f9ee',
+ 'df4cf35c2408487c2727ed288908d563ecb758260d09ce8605839394db930505',
+ '4d382632a407732017ec16d6cbcb92a81cdb56150e9aedce1b987ac9b68d5948');
+
+#
+# 24) Test Reading Grayscale 14-bit
+#
+++$test;
+print("Grayscale (14-bit) ...\n");
+testRead( 'input_gray_14bit.tiff',
+ 'c52de8e70c226c7872e1384e119532791ea9955a01485ae68bbc1236d3f9f9ee',
+ 'a8ecb9b559640e7db2505543cd85c7a614460bed067cf197e3d2116246b1fd05',
+ 'e61921b0de711a9a109cb97920a4487852f0aea9fdb255c357b8290be408ebaa');
+
+#
+# 25) Test Reading Grayscale 16-bit
+#
+++$test;
+print("Grayscale (16-bit) ...\n");
+testRead( 'input_gray_16bit.tiff',
+ '00f6147d547f5a654369a5b41d18f0b44b38f9cc753c773f384808b9a18cac92',
+ '1db9216ffb84dab419b4924e6aba945e922f728c0dca8ce24c3d7f4c47c604b9' );
+
+#
+# 26) Test Reading Grayscale 32-bit
+#
+++$test;
+print("Grayscale (32-bit) ...\n");
+testRead( 'input_gray_32bit.tiff',
+ '3317287375433c8a85db4e5f922d6cf8f5597e337cfed3da3d7c090638296f50',
+ 'e42d156f5c3278c3083409b6d2995b37efca165e1c437b2e25f4c67b4248a574',
+ 'b82c3738aadf26ee25b28d17eeb9cb185d6c7794d7e676692a2cacd90642973e');
+
+#
+# 27) Test Reading CALS Type 1 (Group4-based)
+#
+++$test;
+print("CALS Type 1...\n");
+testRead ( 'input_gray_01bit_minwhite.cals',
+ '2b48bcf7d93cc31a8deb3026d872f1bb0a300b0f4e177423e5301adc638179e4' );
diff --git a/PerlMagick/t/tiff/write.t b/PerlMagick/t/tiff/write.t
new file mode 100644
index 0000000..96e0e9c
--- /dev/null
+++ b/PerlMagick/t/tiff/write.t
@@ -0,0 +1,132 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing TIFF images
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..11\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/tiff' || die 'Cd failed';
+
+#
+# 1) Test 4-bit pseudocolor image
+#
+print("PsuedoColor image (4 bits/sample) ...\n");
+testReadWrite( 'input_palette_16.tiff',
+ 'output_palette_16.tiff',
+ q//,
+ 'a0313f6235a3158655412e1480c2f37549d89a5cacf40abc854811af1b757159');
+
+#
+# 2) Test 8-bit pseudocolor image
+#
+++$test;
+print("PsuedoColor image (8 bits/sample) ...\n");
+testReadWrite( 'input_palette_256.tiff',
+ 'output_palette_256.tiff',
+ q//,
+ 'a570df6d4c214d08bccaaee856f617883fee4f96494af6ef5e25c76d86ea0e0a');
+
+#
+# 3) Test 4-bit pseudocolor + matte channel image
+#
+++$test;
+print("PsuedoColor image (4 bits/sample + matte channel) ...\n");
+testReadWrite( 'input_palette_16_matte.tiff',
+ 'output_palette_16_matte.tiff',
+ q//,
+ '631c0997280217f3f430336513f1e51fe03e04f552d49a848449a438c100aa20');
+
+#
+# 4) Test 8-bit pseudocolor + matte channel image
+#
+++$test;
+print("PsuedoColor image (8 bits/sample + matte channel) ...\n");
+testReadWrite( 'input_palette_256_matte.tiff',
+ 'output_palette_256_matte.tiff',
+ q//,
+ 'a3f865320dc8b7953850babbd22d468d821c0103cc14063d6459159506a910d6');
+
+#
+# 5) Test truecolor image
+#
+++$test;
+print("TrueColor image (8 bits/sample) ...\n");
+testReadWrite( 'input_truecolor_08.tiff',
+ 'output_truecolor_08.tiff',
+ q/quality=>55/,
+ '326599218925e7aa27c735d482332744cccf41f460a1ba2d276a2d172f2b3de0' );
+
+#
+# 6) Test monochrome image
+#
+++$test;
+print("Gray image (1 bit per sample) ...\n");
+testReadWrite( 'input_gray_01bit_minwhite.tiff',
+ 'output_gray_01bit_minwhite.tiff',
+ q//,
+ '2b48bcf7d93cc31a8deb3026d872f1bb0a300b0f4e177423e5301adc638179e4' );
+
+#
+# 7) Test gray 4 bit image
+#
+++$test;
+print("Gray image (4 bits per sample) ...\n");
+testReadWrite( 'input_gray_04bit.tiff',
+ 'output_gray_04bit.tiff',
+ q//,
+ '45c0655a417852480336d5e12d7bb16b9647d911b11589e9d000a05dd1813570' );
+
+#
+# 8) Test gray 8 bit image
+#
+++$test;
+print("Gray image (8 bits per sample) ...\n");
+testReadWrite( 'input_gray_08bit.tiff',
+ 'output_gray_08bit.tiff',
+ q//,
+ '00f6147d547f5a654369a5b41d18f0b44b38f9cc753c773f384808b9a18cac92' );
+
+#
+# 9) Test gray 4 bit image (with matte channel)
+#
+++$test;
+print("Gray image (4 bits per sample + matte channel) ...\n");
+testReadWrite( 'input_gray_04bit_matte.tiff',
+ 'output_gray_04bit_matte.tiff',
+ q//,
+ '1e4ca36f33b13d8799bcda20108d20c1a2da913c27eb7872d95a6928cb8b0b48' );
+
+#
+# 10) Test gray 8 bit image (with matte channel)
+#
+++$test;
+print("Gray image (8 bits per sample + matte channel) ...\n");
+testReadWrite( 'input_gray_08bit_matte.tiff',
+ 'output_gray_08bit_matte.tiff',
+ q//,
+ '70e1e096e53af6a312ec6aa54890a59b35d3c6932dfc052d6b355f62733635be' );
+
+#
+# 11) CALS Type 1
+#
+++$test;
+print("CALS Type 1 ...\n");
+testReadWrite( 'input_gray_01bit_minwhite.cals',
+ 'output_gray_01bit_minwhite.cals',
+ q//,
+ '2b48bcf7d93cc31a8deb3026d872f1bb0a300b0f4e177423e5301adc638179e4' );
diff --git a/PerlMagick/t/topol_1.mez b/PerlMagick/t/topol_1.mez
new file mode 100644
index 0000000..d747a3c
--- /dev/null
+++ b/PerlMagick/t/topol_1.mez
@@ -0,0 +1,2 @@
+
+  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ \ No newline at end of file
diff --git a/PerlMagick/t/topol_1.ras b/PerlMagick/t/topol_1.ras
new file mode 100644
index 0000000..f537cdb
--- /dev/null
+++ b/PerlMagick/t/topol_1.ras
Binary files differ
diff --git a/PerlMagick/t/topol_2.mez b/PerlMagick/t/topol_2.mez
new file mode 100644
index 0000000..30eabaf
--- /dev/null
+++ b/PerlMagick/t/topol_2.mez
@@ -0,0 +1,2 @@
+
+  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ \ No newline at end of file
diff --git a/PerlMagick/t/topol_2.pal b/PerlMagick/t/topol_2.pal
new file mode 100644
index 0000000..b6f29fd
--- /dev/null
+++ b/PerlMagick/t/topol_2.pal
Binary files differ
diff --git a/PerlMagick/t/topol_2.ras b/PerlMagick/t/topol_2.ras
new file mode 100644
index 0000000..4363600
--- /dev/null
+++ b/PerlMagick/t/topol_2.ras
Binary files differ
diff --git a/PerlMagick/t/topol_3.mez b/PerlMagick/t/topol_3.mez
new file mode 100644
index 0000000..e9d847c
--- /dev/null
+++ b/PerlMagick/t/topol_3.mez
@@ -0,0 +1 @@
+2FZn \ No newline at end of file
diff --git a/PerlMagick/t/topol_3.ras b/PerlMagick/t/topol_3.ras
new file mode 100644
index 0000000..f8e78a2
--- /dev/null
+++ b/PerlMagick/t/topol_3.ras
Binary files differ
diff --git a/PerlMagick/t/topol_4.mez b/PerlMagick/t/topol_4.mez
new file mode 100644
index 0000000..a3c0a26
--- /dev/null
+++ b/PerlMagick/t/topol_4.mez
@@ -0,0 +1,2 @@
+
+  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ \ No newline at end of file
diff --git a/PerlMagick/t/topol_4.pal b/PerlMagick/t/topol_4.pal
new file mode 100644
index 0000000..a8bb635
--- /dev/null
+++ b/PerlMagick/t/topol_4.pal
Binary files differ
diff --git a/PerlMagick/t/topol_4.ras b/PerlMagick/t/topol_4.ras
new file mode 100644
index 0000000..7fad102
--- /dev/null
+++ b/PerlMagick/t/topol_4.ras
Binary files differ
diff --git a/PerlMagick/t/topol_5.ras b/PerlMagick/t/topol_5.ras
new file mode 100644
index 0000000..76ad86b
--- /dev/null
+++ b/PerlMagick/t/topol_5.ras
Binary files differ
diff --git a/PerlMagick/t/topol_7.mez b/PerlMagick/t/topol_7.mez
new file mode 100644
index 0000000..0aaa0f1
--- /dev/null
+++ b/PerlMagick/t/topol_7.mez
@@ -0,0 +1,2 @@
+
+  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ \ No newline at end of file
diff --git a/PerlMagick/t/topol_7.ras b/PerlMagick/t/topol_7.ras
new file mode 100644
index 0000000..fe0ded4
--- /dev/null
+++ b/PerlMagick/t/topol_7.ras
Binary files differ
diff --git a/PerlMagick/t/ttf/input.ttf b/PerlMagick/t/ttf/input.ttf
new file mode 100644
index 0000000..d7410f1
--- /dev/null
+++ b/PerlMagick/t/ttf/input.ttf
Binary files differ
diff --git a/PerlMagick/t/ttf/read.t b/PerlMagick/t/ttf/read.t
new file mode 100644
index 0000000..c1c2332
--- /dev/null
+++ b/PerlMagick/t/ttf/read.t
@@ -0,0 +1,59 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test read image method on TrueType font
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us
+#
+
+BEGIN { $| = 1; $test=1; print "1..3\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/ttf' || die 'Cd failed';
+
+#
+# 1) Test default ImageMagick read operation on font
+#
+print("Default GraphicsMagick read ...\n");
+testReadCompare('input.ttf', '../reference/ttf/read.miff',
+ q/size=>'512x512', depth=>8/,
+ 0.16, 1.0);
+
+#
+# 2) Test drawing text using font
+#
+++$test;
+print("Draw text using label: ...\n");
+testReadCompare(q!label:The quick brown fox jumps over the lazy dog.!,
+ q!../reference/ttf/label.miff!,
+ q!font=>'input.ttf', fill=>'#0000FF', pointsize=>14, size=>'245x16', depth=>8!,
+ 0.16, 1.0);
+
+#
+# 3) Test drawing text using annotate
+#
+++$test;
+print("Draw text using annotate ...\n");
+testFilterCompare('xc:#FFFFFF',
+ q!size=>'250x20', depth=>8!,
+ q!../reference/ttf/annotate.miff!,
+ 'Annotate',
+ q!text=>'The quick brown fox jumps over the lazy dog.',
+ gravity=>'NorthWest',
+ geometry=>'+6+14',
+ font=>'input.ttf',
+ fill=>'#FF0000',
+ pointsize=>14!,
+ 0.17, 1.0);
+1;
diff --git a/PerlMagick/t/wmf/clock.wmf b/PerlMagick/t/wmf/clock.wmf
new file mode 100644
index 0000000..dead7d9
--- /dev/null
+++ b/PerlMagick/t/wmf/clock.wmf
Binary files differ
diff --git a/PerlMagick/t/wmf/fjftest.wmf b/PerlMagick/t/wmf/fjftest.wmf
new file mode 100644
index 0000000..e8ab6af
--- /dev/null
+++ b/PerlMagick/t/wmf/fjftest.wmf
Binary files differ
diff --git a/PerlMagick/t/wmf/read.t b/PerlMagick/t/wmf/read.t
new file mode 100644
index 0000000..3f36734
--- /dev/null
+++ b/PerlMagick/t/wmf/read.t
@@ -0,0 +1,36 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading WMF files
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+#
+BEGIN { $| = 1; $test=1; print "1..4\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/wmf' || die 'Cd failed';
+
+testReadCompare('wizard.wmf', '../reference/wmf/wizard.miff',
+ q//, 0.003, 0.9);
+++$test;
+testReadCompare('clock.wmf', '../reference/wmf/clock.miff',
+ q//, 0.002, 0.9);
+++$test;
+testReadCompare('ski.wmf', '../reference/wmf/ski.miff',
+ q//, 0.021, 0.9);
+++$test;
+testReadCompare('fjftest.wmf', '../reference/wmf/fjftest.miff',
+ q//, 0.004, 0.5);
+
diff --git a/PerlMagick/t/wmf/ski.wmf b/PerlMagick/t/wmf/ski.wmf
new file mode 100644
index 0000000..796fdfc
--- /dev/null
+++ b/PerlMagick/t/wmf/ski.wmf
Binary files differ
diff --git a/PerlMagick/t/wmf/wizard.wmf b/PerlMagick/t/wmf/wizard.wmf
new file mode 100644
index 0000000..6d898e4
--- /dev/null
+++ b/PerlMagick/t/wmf/wizard.wmf
Binary files differ
diff --git a/PerlMagick/t/write.t b/PerlMagick/t/write.t
new file mode 100644
index 0000000..c91e792
--- /dev/null
+++ b/PerlMagick/t/write.t
@@ -0,0 +1,278 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing formats supported directly by GraphicsMagick
+#
+# Currently supported tests are for formats that GraphicsMagick
+# knows how to both read and write.
+#
+# Whenever a new test is added/removed, be sure to update the
+# 1..n ouput.
+
+BEGIN { $| = 1; $test=1; print "TAP version 13\n1..33\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't' || die 'Cd failed';
+
+print("AVS X image file ...\n");
+testReadWrite( 'AVS:input.avs',
+ 'AVS:output.avs',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Microsoft Windows bitmap image file ...\n");
+++$test;
+testReadWrite( 'BMP:input.bmp',
+ 'BMP:output.bmp',
+ q//,
+ '5083e062c7e4d3d462944bc1e89c4f491bf1f0241352e0a93988c8854c261fdb');
+
+print("Microsoft Windows 24-bit bitmap image file ...\n");
+++$test;
+testReadWrite( 'BMP:input.bmp24',
+ 'BMP:output.bmp24',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+
+print("ZSoft IBM PC multi-page Paintbrush file ...\n");
+++$test;
+testReadWrite( 'DCX:input.dcx',
+ 'DCX:output.dcx',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Microsoft Windows 3.X DIB file ...\n");
+++$test;
+testReadWrite( 'DIB:input.dib',
+ 'DIB:output.dib',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Flexible Image Transport System ...\n");
+++$test;
+testReadWrite( 'FITS:input_gray_08bit.fits',
+ 'FITS:output.fits',
+ q//,
+ '863a70f43cb481512e805babd7e09360ef6e5c7fe75725712242b367f0d0ef28' );
+
+print("CompuServe graphics interchange format ...\n");
+++$test;
+testReadWrite( 'GIF:input.gif',
+ 'GIF:output.gif',
+ q//,
+ 'f84cb6b5817ea2f6f313c2bdd90c94af0d0e7fb144528994050b355f8d5e6a94');
+
+print("CompuServe graphics interchange format (1987) ...\n");
+++$test;
+testReadWrite( 'GIF87:input.gif87',
+ 'GIF87:output.gif87',
+ q//,
+ 'f84cb6b5817ea2f6f313c2bdd90c94af0d0e7fb144528994050b355f8d5e6a94');
+
+print("Magick image file format ...\n");
+++$test;
+testReadWrite( 'MIFF:input.miff',
+ 'MIFF:output.miff',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("MTV Raytracing image format ...\n");
+++$test;
+testReadWrite( 'MTV:input.mtv',
+ 'MTV:output.mtv',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Xv's visual schnauzer format ...\n");
+++$test;
+testReadWriteCompare( 'input.miff', 'P7:output_p7.p7', 'reference/write/output_p7.miff',
+ q/depth=>8/, q/dither=>0, depth=>8/, 0.002, 0.004);
+
+print("Portable bitmap format (black and white), ASCII format ...\n");
+++$test;
+testReadWrite( 'PBM:input_p1.pbm',
+ 'PBM:output_p1.pbm',
+ q/compression=>'None'/,
+ '2b48bcf7d93cc31a8deb3026d872f1bb0a300b0f4e177423e5301adc638179e4');
+
+print("Portable bitmap format (black and white), binary format ...\n");
+++$test;
+testReadWrite( 'PBM:input_p4.pbm',
+ 'PBM:output_p4.pbm',
+ q//,
+ '2b48bcf7d93cc31a8deb3026d872f1bb0a300b0f4e177423e5301adc638179e4');
+
+print("ZSoft IBM PC Paintbrush file ...\n");
+++$test;
+testReadWrite( 'PCX:input.pcx',
+ 'PCX:output.pcx',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Portable graymap format (gray scale), ASCII format ...\n");
+++$test;
+testReadWrite( 'PGM:input_p2.pgm',
+ 'PGM:output_p2.pgm',
+ q/compression=>'None'/,
+ '04c5604964838e47aba7a355efee266a4d0f1b90f672ff56863440e5e5a29761');
+
+print("Apple Macintosh QuickDraw/PICT file ...\n");
+++$test;
+testReadWrite( 'PICT:input.pict',
+ 'PICT:output.pict',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Portable pixmap format (color), ASCII format ...\n");
+++$test;
+testReadWrite( 'PPM:input_p3.ppm',
+ 'PPM:output_p3.ppm',
+ q/compression=>'None'/,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Portable graymap format (gray scale), binary format ...\n");
+++$test;
+testReadWrite( 'PGM:input_p5.pgm',
+ 'PGM:output_p5.pgm',
+ q//,
+ '04c5604964838e47aba7a355efee266a4d0f1b90f672ff56863440e5e5a29761');
+
+print("Portable pixmap format (color), binary format ...\n");
+++$test;
+testReadWrite( 'PPM:input_p6.ppm',
+ 'PPM:output_p6.ppm',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Adobe Photoshop bitmap file ...\n");
+++$test;
+if (featureSupported("PSD")) {
+ testReadWrite( 'PSD:input.psd',
+ 'PSD:output.psd',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+} else {
+ print "ok $test # skip PSD not supported\n";
+}
+
+print("Irix RGB image file ...\n");
+++$test;
+testReadWrite( 'SGI:input.sgi',
+ 'SGI:output.sgi',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("SUN 1-bit Rasterfile ...\n");
+++$test;
+testReadWrite( 'SUN:input.im1',
+ 'SUN:output.im1',
+ q//,
+ '615fa1d8bae486118b3733c1dba4e2a225fc1f4f8ff9441bcb7c3293753e4da1');
+
+print("SUN 8-bit Rasterfile ...\n");
+++$test;
+testReadWrite( 'SUN:input.im8',
+ 'SUN:output.im8',
+ q//,
+ 'f84cb6b5817ea2f6f313c2bdd90c94af0d0e7fb144528994050b355f8d5e6a94');
+
+print("SUN True-Color Rasterfile ...\n");
+++$test;
+testReadWrite( 'SUN:input.im24',
+ 'SUN:output.im24',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Truevision Targa image file ...\n");
+++$test;
+testReadWrite( 'TGA:input.tga',
+ 'TGA:output.tga',
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("Khoros Visualization image file ...\n");
+++$test;
+testReadWrite( 'VIFF:input.viff',
+ 'VIFF:output.viff',
+ q//,
+ '9c01e510e4aa7c369895db51389ae917a0d4f9004ffb4edf81e5e2302cab98a3');
+
+print("WBMP (Wireless Bitmap (level 0) image) ...\n");
+++$test;
+testReadWrite( 'WBMP:input.wbmp',
+ 'WBMP:output.wbmp',
+ q//,
+ 'ccde39dba836a36bbc076e7e6f20f06b034dab0eb2613b350b17c2759533b2ca');
+
+print("X Windows system bitmap (black and white only) ...\n");
+++$test;
+testReadWrite( 'XBM:input.xbm',
+ 'XBM:output.xbm',
+ q//,
+ '86cf46ab9d620aa85eba722d777cc97e30df51916b2380df3cbc2685614d1222');
+
+print("X Windows system pixmap file (color) ...\n");
+++$test;
+testReadWrite( 'XPM:input.xpm',
+ 'XPM:output.xpm',
+ q//,
+ 'f84cb6b5817ea2f6f313c2bdd90c94af0d0e7fb144528994050b355f8d5e6a94');
+
+
+#print("X Windows system window dump file (color) ...\n");
+#++$test;
+#testReadWrite( 'XWD:input.xwd',
+# 'XWD:output.xwd',
+# q//,
+# '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f');
+
+print("CMYK format ...\n");
+++$test;
+testReadWriteSized( 'CMYK:input_70x46.cmyk',
+ 'CMYK:output_70x46.cmyk',
+ '70x46',
+ 8,
+ q//,
+ '1a1b99a35b962941e2a1cfc01e34907539f6d6ddc4a8df09fc024ef58e16d4e2');
+
+print("GRAY format ...\n");
+++$test;
+testReadWriteSized( 'GRAY:input_70x46.gray',
+ 'GRAY:output_70x46.gray',
+ '70x46',
+ 8,
+ q//,
+ '0e54b24352da9f7d0966c9b882988b9124b6b7fd7493ff266f4c03382b94a42a' );
+
+print("RGB format ...\n");
+++$test;
+testReadWriteSized( 'RGB:input_70x46.rgb',
+ 'RGB:output_70x46.rgb',
+ '70x46',
+ 8,
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+
+print("RGBA format ...\n");
+++$test;
+testReadWriteSized( 'RGBA:input_70x46.rgba',
+ 'RGBA:output_70x46.rgba',
+ '70x46',
+ 8,
+ q//,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+1;
diff --git a/PerlMagick/t/x/congrats.fig b/PerlMagick/t/x/congrats.fig
new file mode 100644
index 0000000..7ee1ad9
--- /dev/null
+++ b/PerlMagick/t/x/congrats.fig
@@ -0,0 +1,18 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+Letter
+100.00
+Single
+0
+1200 2
+6 2100 1575 8100 2775
+4 1 4 0 0 18 32 0.0000 4 450 6000 5100 2625 You can display an image!\001
+4 1 4 0 0 18 32 0.0000 4 345 5010 5100 1950 CONGRATULATIONS!\001
+-6
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 9150 5850 9150 600 900 600 900 5850 9150 5850
+4 1 0 0 0 18 24 0.0000 4 330 3420 5100 3450 Please Stand By . . .\001
+4 1 0 0 0 18 24 0.0000 4 330 5775 5100 4125 In eight seconds this window will\001
+4 1 0 0 0 18 24 0.0000 4 330 4395 5100 4530 automatically disappear.\001
diff --git a/PerlMagick/t/x/congrats.miff b/PerlMagick/t/x/congrats.miff
new file mode 100644
index 0000000..97ff942
--- /dev/null
+++ b/PerlMagick/t/x/congrats.miff
@@ -0,0 +1,11 @@
+id=ImageMagick
+class=DirectClass matte=False
+columns=496 rows=316 depth=8
+Resolution=75.0855x74.9556 units=undefined
+page=496x316+58+238
+iterations=0
+comment={ Image generated by GNU Ghostscript (device=pnmraw)
+}
+signature=3cbcbf0c9d6e06d351746a29fe6c04da2fa3c3622fe0806d33f0e6171a06c5b3
+
+:wwwfffwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwfffwwwUUUUUUwwwwwwUUUUUUwwwwwwffffffwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwDD
diff --git a/PerlMagick/t/x/read.t b/PerlMagick/t/x/read.t
new file mode 100644
index 0000000..5c0f7c8
--- /dev/null
+++ b/PerlMagick/t/x/read.t
@@ -0,0 +1,67 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test accessing X11 server
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/x' || die 'Cd failed';
+
+#
+# 1) Test rendering text using common X11 font
+#
+if ( defined($ENV{'DISPLAY'}) && ($ENV{'DISPLAY'} ne '') ) {
+
+ $font = '-*-courier-bold-r-normal--14-100-100-100-m-90-iso8859-1';
+
+ # Ensure that Ghostscript is out of the picture
+ $SAVEDPATH=$ENV{'PATH'};
+ $ENV{'PATH'}='';
+
+ $image=Graphics::Magick->new;
+ $x=$image->Set(font=>"$font", pen=>'#0000FF', dither=>'False');
+ if( "$x" ) {
+ print "$x\n";
+ print "not ok $test\n";
+ } else {
+ $x=$image->ReadImage('label:The quick brown fox jumps over the lazy dog.');
+ if( "$x" ) {
+ print "ReadImage: $x\n";
+ # If server can't be accessed, ImageMagick returns this warning
+ # Warning 305: Unable to open X server
+ $x =~ /(\d+)/;
+ my $errorCode = $1;
+ if ( $errorCode > 0 ) {
+ print "not ok $test\n";
+ } else {
+ print "ok $test\n";
+ }
+ } else {
+ #$image->Display();
+ print "ok $test\n";
+ }
+ }
+ undef $image;
+
+ $ENV{'PATH'}=$SAVEDPATH;
+} else {
+ print "ok $test\n";
+}
+
+$test = 0; # Quench PERL compliaint
+
diff --git a/PerlMagick/t/x/write.t b/PerlMagick/t/x/write.t
new file mode 100644
index 0000000..0a81a66
--- /dev/null
+++ b/PerlMagick/t/x/write.t
@@ -0,0 +1,47 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test accessing X11 server
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/x' || die 'Cd failed';
+
+#
+# 1) Test reading and displaying an image
+#
+if ( defined($ENV{'DISPLAY'}) && ($ENV{'DISPLAY'} ne '') ) {
+ $image=Graphics::Magick->new;
+ $x=$image->ReadImage('congrats.miff');
+ if( "$x" ) {
+ print "not ok $test\n";
+ } else {
+ $x = $image->Display(delay=>800);
+ if( "$x" ) {
+ print "not ok $test\n";
+ } else {
+ print "ok $test\n";
+ }
+ }
+ undef $image;
+} else {
+ print "ok $test\n";
+}
+
+$test = 0; # Quench PERL compliaint
+
diff --git a/PerlMagick/t/xfig/input.fig b/PerlMagick/t/xfig/input.fig
new file mode 100644
index 0000000..8bfa2a8
--- /dev/null
+++ b/PerlMagick/t/xfig/input.fig
@@ -0,0 +1,69 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+0
+1200 2
+2 2 0 0 7 0 0 0 44 0.000 0 0 -1 0 0 5
+ 900 1200 1500 1200 1500 1800 900 1800 900 1200
+2 2 0 0 7 1 0 0 45 0.000 0 0 -1 0 0 5
+ 1500 1200 2100 1200 2100 1800 1500 1800 1500 1200
+2 2 0 0 7 3 0 0 47 0.000 0 0 -1 0 0 5
+ 2700 1200 3300 1200 3300 1800 2700 1800 2700 1200
+2 2 0 0 7 2 0 0 46 0.000 0 0 -1 0 0 5
+ 2100 1200 2700 1200 2700 1800 2100 1800 2100 1200
+2 2 0 0 7 4 0 0 49 0.000 0 0 -1 0 0 5
+ 3300 1200 3900 1200 3900 1800 3300 1800 3300 1200
+2 2 0 0 7 5 0 0 43 0.000 0 0 -1 0 0 5
+ 900 1800 1500 1800 1500 2400 900 2400 900 1800
+2 2 0 0 7 6 0 0 43 0.000 0 0 -1 0 0 5
+ 1500 1800 2100 1800 2100 2400 1500 2400 1500 1800
+2 2 0 0 7 7 0 0 14 0.000 0 0 -1 0 0 5
+ 2100 1800 2700 1800 2700 2400 2100 2400 2100 1800
+2 2 0 0 7 8 0 0 58 0.000 0 0 -1 0 0 5
+ 2700 1800 3300 1800 3300 2400 2700 2400 2700 1800
+2 2 0 0 7 9 0 0 59 0.000 0 0 -1 0 0 5
+ 3300 1800 3900 1800 3900 2400 3300 2400 3300 1800
+2 2 0 0 7 10 0 0 57 0.000 0 0 -1 0 0 5
+ 900 2400 1500 2400 1500 3000 900 3000 900 2400
+2 2 0 0 7 11 0 0 43 0.000 0 0 -1 0 0 5
+ 1500 2400 2100 2400 2100 3000 1500 3000 1500 2400
+2 2 0 0 7 12 0 0 61 0.000 0 0 -1 0 0 5
+ 2100 2400 2700 2400 2700 3000 2100 3000 2100 2400
+2 2 0 0 7 13 0 0 62 0.000 0 0 -1 0 0 5
+ 2700 2400 3300 2400 3300 3000 2700 3000 2700 2400
+2 2 0 0 7 14 0 0 44 0.000 0 0 -1 0 0 5
+ 3300 2400 3900 2400 3900 3000 3300 3000 3300 2400
+2 2 0 0 7 15 0 0 54 0.000 0 0 -1 0 0 5
+ 900 3000 1500 3000 1500 3600 900 3600 900 3000
+2 2 0 0 7 16 0 0 43 0.000 0 0 -1 0 0 5
+ 1500 3000 2100 3000 2100 3600 1500 3600 1500 3000
+2 2 0 0 7 17 0 0 46 0.000 0 0 -1 0 0 5
+ 2100 3000 2700 3000 2700 3600 2100 3600 2100 3000
+2 2 0 0 7 18 0 0 50 0.000 0 0 -1 0 0 5
+ 2700 3000 3300 3000 3300 3600 2700 3600 2700 3000
+2 2 0 0 7 19 0 0 44 0.000 0 0 -1 0 0 5
+ 3300 3000 3900 3000 3900 3600 3300 3600 3300 3000
+2 2 0 0 7 21 0 0 53 0.000 0 0 -1 0 0 5
+ 900 3600 1500 3600 1500 4200 900 4200 900 3600
+2 2 0 0 7 22 0 0 43 0.000 0 0 -1 0 0 5
+ 1500 3600 2100 3600 2100 4200 1500 4200 1500 3600
+2 2 0 0 7 24 0 0 56 0.000 0 0 -1 0 0 5
+ 2100 3600 2700 3600 2700 4200 2100 4200 2100 3600
+2 2 0 0 7 25 0 0 41 0.000 0 0 -1 0 0 5
+ 2700 3600 3300 3600 3300 4200 2700 4200 2700 3600
+2 2 0 0 7 26 0 0 49 0.000 0 0 -1 0 0 5
+ 3300 3600 3900 3600 3900 4200 3300 4200 3300 3600
+2 2 0 0 7 27 0 0 50 0.000 0 0 -1 0 0 5
+ 900 4200 1500 4200 1500 4800 900 4800 900 4200
+2 2 0 0 7 28 0 0 61 0.000 0 0 -1 0 0 5
+ 1500 4200 2100 4200 2100 4800 1500 4800 1500 4200
+2 2 0 0 7 30 0 0 48 0.000 0 0 -1 0 0 5
+ 2100 4200 2700 4200 2700 4800 2100 4800 2100 4200
+2 2 0 0 7 31 0 0 62 0.000 0 0 -1 0 0 5
+ 2700 4200 3300 4200 3300 4800 2700 4800 2700 4200
+2 2 0 0 7 -1 0 0 20 0.000 0 0 -1 0 0 5
+ 3300 4200 3900 4200 3900 4800 3300 4800 3300 4200
diff --git a/PerlMagick/t/xfig/read.t b/PerlMagick/t/xfig/read.t
new file mode 100644
index 0000000..f116d80
--- /dev/null
+++ b/PerlMagick/t/xfig/read.t
@@ -0,0 +1,36 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test Reading Xfig files
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/xfig' || die 'Cd failed';
+
+#
+# 1) Test reading Xfig
+#
+$image=Graphics::Magick->new;
+$x=$image->ReadImage('input.fig');
+if( "$x" ) {
+ print "ReadImage: $x\n";
+ print "not ok $test\n";
+} else {
+ print "ok $test\n";
+}
+undef $image;
diff --git a/PerlMagick/t/zlib/input.miff b/PerlMagick/t/zlib/input.miff
new file mode 100644
index 0000000..7740ad5
--- /dev/null
+++ b/PerlMagick/t/zlib/input.miff
@@ -0,0 +1,9 @@
+id=ImageMagick
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+signature=eb4d6e084afe2835a1ad28ad7fc12ced
+background-color=gray74 border-color=gray74 matte-color=gray74
+{
+This is a comment.}
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/PerlMagick/t/zlib/input.miff.gz b/PerlMagick/t/zlib/input.miff.gz
new file mode 100644
index 0000000..aac75ca
--- /dev/null
+++ b/PerlMagick/t/zlib/input.miff.gz
Binary files differ
diff --git a/PerlMagick/t/zlib/input_gray_lsb_08bit_zip.mat b/PerlMagick/t/zlib/input_gray_lsb_08bit_zip.mat
new file mode 100644
index 0000000..36c69f6
--- /dev/null
+++ b/PerlMagick/t/zlib/input_gray_lsb_08bit_zip.mat
Binary files differ
diff --git a/PerlMagick/t/zlib/read.t b/PerlMagick/t/zlib/read.t
new file mode 100644
index 0000000..6890844
--- /dev/null
+++ b/PerlMagick/t/zlib/read.t
@@ -0,0 +1,46 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003, 2008 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test reading an image which uses Zip compression
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+
+BEGIN { $| = 1; $test=1; print "1..3\n"; }
+END {print "not ok $test\n" unless $loaded;}
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/zlib' || die 'Cd failed';
+
+#
+# 1) Test reading Zip compressed MIFF
+#
+print("Reading Zip compressed MIFF ...\n");
+testRead( 'input.miff',
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+#
+# 2) Test reading Zip compressed MAT
+#
+print("Reading Zip compressed MAT ...\n");
+++$test;
+testRead( 'input_gray_lsb_08bit_zip.mat',
+ 'cd0e75dd75bce03537c17bf067e19e97d1e28feb18a5ba54dddaf3309097c255' );
+
+#
+# 3) Test reading Zip stream-compressed MIFF (.gz extension)
+#
+print("Reading Zip stream-compressed MIFF (.gz extension) ...\n");
+++$test;
+testRead( 'input.miff.gz',
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
diff --git a/PerlMagick/t/zlib/write.t b/PerlMagick/t/zlib/write.t
new file mode 100644
index 0000000..0445a4e
--- /dev/null
+++ b/PerlMagick/t/zlib/write.t
@@ -0,0 +1,35 @@
+#!/usr/local/bin/perl
+# Copyright (C) 2003 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1991-1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+#
+# Test writing files using zlib-based compression
+#
+# Contributed by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+#
+BEGIN { $| = 1; $test=1; print "1..1\n"; }
+END {print "not ok $test\n" unless $loaded;}
+
+use Graphics::Magick;
+$loaded=1;
+
+require 't/subroutines.pl';
+
+chdir 't/zlib' || die 'Cd failed';
+
+#
+# 1) Test writing Zip-compressed MIFF
+#
+
+testReadWrite( 'input.miff',
+ 'output.miff',
+ q/compression=>'Zip'/,
+ '8b19185a62241bd7b79ecf3f619711f4ebbedd73eaeca0366f05778762b6614f' );
+
+$test = 0; # Quench PERL compliaint
+
diff --git a/PerlMagick/typemap b/PerlMagick/typemap
new file mode 100644
index 0000000..f55b334
--- /dev/null
+++ b/PerlMagick/typemap
@@ -0,0 +1 @@
+Graphics::Magick T_PTROBJ
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..ca0d9fb
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,352 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=========================
+Installing GraphicsMagick
+=========================
+
+.. contents::
+ :local:
+
+Executive Summary
+-----------------
+
+GraphicsMagick provides a comprehensive collection of utilities,
+programming interfaces, and GUIs, to support file format conversion,
+image processing, and 2D vector rendering.
+
+GraphicsMagick is originally based on ImageMagick from ImageMagick Studio
+(which was originally written by John Cristy at Dupont). The goal of
+GraphicsMagick is to provide the highest quality product possible while
+encouraging open and active participation from all interested developers.
+The GraphicsMagick usage license is designed to allow it to be used for
+any application, including proprietary or GPLed applications. Please see
+the file `Copyright.txt <Copyright.html>`_ for the GraphicsMagick licence.
+
+Availability
+------------
+
+The master ftp site for GraphicsMagick distributions is
+ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/. Bandwidth on this
+site is very limited, so it is recommended to download from SourceForge
+at http://sourceforge.net/projects/graphicsmagick/files/ if
+possible.
+
+GraphicsMagick is a continual work in progress. The very latest code
+is available via the Mercurial distributed source control management
+tool (https://www.mercurial-scm.org/). GraphicsMagick may be retrieved
+via the following command:
+
+ hg clone http://hg.code.sf.net/p/graphicsmagick/code/ GM
+
+Mercurial provides a complete stand-alone repository which contains
+the full history of the GraphicsMagick project. You may use the
+cloned repository for your own purposes related to GraphicsMagick
+(e.g. manage local GraphicsMagick changes), and can easily pull
+GraphicsMagick updates from the main repository whenever you like.
+
+Documentation
+-------------
+
+ Open the file index.html in a web browser, or refer to the gm(1) manual
+ page. Also read the GraphicsMagick frequently asked questions in the
+ file `www/FAQ.html <FAQ.html>`_.
+
+Installation
+------------
+
+ GraphicsMagick may be compiled from source code for virtually any
+ modern Unix system (including Linux and MacOS X) and Microsoft Windows.
+ Installation instructions may be found in the following files (or their
+ HTML equivalents):
+
+ * Unix / Linux / \*BSD / MacOS-X / Cygwin / MinGW:
+
+ `Installation on Unix-like systems <INSTALL-unix.html>`_
+
+ * Microsoft Windows (Via "setup" style installer or from source code):
+
+ `Installation on Microsoft Windows <INSTALL-windows.html>`_
+
+Add-On Libraries & Programs
+---------------------------
+
+To further enhance the capabilities of GraphicsMagick, you may want to
+get these programs or libraries. Note that these packages are already
+integrated into the GraphicsMagick Mercurial repository for use when
+building under Microsoft Windows:
+
+* GraphicsMagick requires the BZLIB library from
+
+ http://www.bzip.org/
+
+ to read and write BZip compressed MIFF images.
+
+* GraphicsMagick requires 'ralcgm' from
+
+ http://www.agocg.ac.uk/train/cgm/ralcgm.htm
+
+ to read the Computer Graphics Metafile (CGM) image format. You also
+ need Ghostscript and Ghostscript Fonts (see below).
+
+* GraphicsMagick requires 'dcraw' from
+
+ http://www.cybercom.net/~dcoffin/dcraw/
+
+ to read raw images from digital cameras. Dcraw is invoked
+ automatically when used to read files using a common RAW file format
+ extension.
+
+* GraphicsMagick requires 'fig2dev' provided in the transfig package
+ from
+
+ http://www.xfig.org/
+
+ to read the Fig image format. Ghostscript and Ghostscript Fonts (see
+ below) are also required.
+
+* GraphicsMagick requires the FreeType software, version 2.0 or above,
+ available as
+
+ http://www.freetype.org/
+
+ to annotate with TrueType and Postscript Type 1 fonts.
+
+* GraphicsMagick requires Ghostscript software (version 9.04
+ recommended) available from
+
+ http://pages.cs.wisc.edu/~ghost/
+
+ or
+
+ http://sourceforge.net/projects/ghostscript/
+
+ to read the Postscript or the Portable Document Format (PDF).
+
+ Ghostscript Fonts are available from
+
+ https://sourceforge.net/projects/gs-fonts/
+
+ Ghostscript is available for use under both free (GPL) and
+ commercial licenses. We are not lawyers so we can not provide
+ advice as to when the commercial license from Artifex is required.
+ Please make sure that you are aware of Ghostscript licencing and
+ usage terms if you plan to use it in some sort of commercial
+ situation.
+
+ Ghostscript (release 7.0 and later) may optionally install a library
+ (libgs) under Linux. If this library is installed, GraphicsMagick may
+ be configured to use it. We do **NOT** recommend using this library
+ under Unix type systems. The Ghostscript library does not support
+ concurrency since only one instance of the interpreter is available.
+ Unix systems will obtain better performance from executing Ghostscript as
+ an external process since then multiple interpreters may execute at
+ once on multiple CPU cores.
+
+ If the Ghostscript library is used, then please be aware that
+ Ghostscript provides its own modified version of libjpeg and
+ libJasper while GraphicsMagick will be using these libraries as
+ provided with the system. If Ghostscript is not using the same
+ libraries, then identically named symbols may be used from the wrong
+ code, causing confusion or a program crash. If conflicts cause JPEG
+ to fail (JPEG returns an error regarding expected structure sizes),
+ it may be necessary to use Ghostscript's copy of libjpeg for
+ GraphicsMagick, and all delegate libraries which depend on libjpeg,
+ or convince Ghostscript to build against an unmodified installed
+ JPEG library (and lose compatibility with some Postscript files).
+
+* GraphicsMagick requires hp2xx available from
+
+ http://www.gnu.org/software/hp2xx/hp2xx.html
+
+ to read the HP-GL image format. Note that HPGL is a plotter file
+ format. HP printers usually accept PCL format rather than HPGL
+ format. Ghostscript (see above) is also required.
+
+* GraphicsMagick requires the lcms library (2.0 or later) available
+ from
+
+ http://www.littlecms.com/
+
+ to perform ICC CMS color management.
+
+* GraphicsMagick requires Graphviz available from
+
+ http://www.graphviz.org/
+
+ to read Graphvis 'dot' digraph files (with extension dot).
+ Ghostscript (see above) is also required.
+
+* GraphicsMagick requires html2ps available from
+
+ http://user.it.uu.se/~jan/html2ps.html
+
+ to rasterize HTML files. Ghostscript (see above) is also required.
+
+* GraphicsMagick requires the JBIG-Kit software available via
+ HTTP from
+
+ http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+
+ to read and write the JBIG image format.
+
+* GraphicsMagick requires the WebP library version 0.1.99 (or later)
+ available via HTTPS from
+
+ https://developers.google.com/speed/webp/
+
+ to read and write the WebP image format.
+
+* GraphicsMagick requires the Independent JPEG Group's software
+ available from
+
+ http://www.ijg.org/
+
+ to read and write the JPEG v1 image format.
+
+ Apply this JPEG patch to Independent JPEG Group's (6b release!)
+ source distribution if you want to read lossless jpeg-encoded DICOM
+ (medical) images:
+
+ ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/delegates/ljpeg-6b.tar.gz
+
+ Use of lossless JPEG is not encouraged. Unless you have a requirement
+ to read lossless jpeg-encoded DICOM images, please disregard the patch.
+
+* GraphicsMagick requires the JasPer Project's JasPer library version
+ 1.701.0 (or later) available via http from
+
+ http://www.ece.uvic.ca/~mdadams/jasper/
+
+ to read and write the JPEG-2000 format. Please note that JasPer 1.900.1
+ may have a problem when used with GraphicsMagick's modules build. To
+ solve this problem, edit the file src/libjasper/base/jas_init.c and
+ comment out the line which invokes atexit().
+
+* On Unix-type systems, Windows/MinGW, and Windows/Cygwin,
+ GraphicsMagick requires libltdl from libtool in order to support
+ building GraphicsMagick with dynamically loadable modules. Libtool
+ is available via anonymous FTP from
+
+ ftp://ftp.gnu.org/pub/gnu/libtool/
+
+* GraphicsMagick requires the MPEG utilities from the MPEG Software
+ Simulation Group, which are available via anonymous FTP as
+
+ ftp://ftp.GraphicsMagick.org/pub/GraphicsMagick/delegates/mpeg2vidcodec_v12.tar.gz
+
+ to read or write the MPEG image format.
+
+* GraphicsMagick requires the LIBPNG library, version 1.0 or above, from
+
+ http://www.libpng.org/pub/png/pngcode.html
+
+ to read or write the PNG, MNG, or JNG image formats. LIBPNG depends
+ upon the ZLIB library (see below).
+
+* GraphicsMagick requires Sam Leffler's TIFF software available via
+ HTTP at
+
+ http://www.simplesystems.org/libtiff/
+
+ to read the TIFF image format. It in turn optionally requires the
+ JPEG and ZLIB libraries. Libtiff 3.8.2 or later is recommended.
+
+* GraphicsMagick may optionally use the TRIO library from
+
+ http://sourceforge.net/projects/ctrio/
+
+ to substitute for the vsnprintf function when the operating system
+ does not provide one. Older operating systems (e.g. Solaris 2.5)
+ may not provide a vsnprintf function. If vsnprintf (or the TRIO
+ replacement) is not used, then vsprintf is used instead, which
+ decreases the security of GraphicsMagick due to possible buffer
+ overrun exploits.
+
+* GraphicsMagick may optionally use the umem memory allocation library
+ which is included in Sun's Solaris operating system or available from
+
+ https://labs.omniti.com/trac/portableumem
+
+ to provide enhanced versions of the standard memory allocation
+ facilities. Use of umem may improve performance for multi-threaded
+ programs and provides access to debugging features that detect memory
+ leaks, buffer overruns, multiple frees, use of uninitialized data, use
+ of freed data, and many other common programming errors.
+
+* GraphicsMagick requires libwmflite from libwmf 0.2.5 (or later) from
+
+ http://sourceforge.net/projects/wvware/
+
+ to render files in the Windows Meta File (WMF) metafile format
+ (16-bit WMF files only, not 32-bit "EMF"). This is the format
+ commonly used for Windows clipart (available on CD at your local
+ computer or technical book store). WMF support requires the FreeType
+ 2 library in order to render TrueType and Postscript fonts.
+
+ While GraphicsMagick uses the libwmflite (parser) component of the
+ libwmf package which does not depend on any special libraries, the
+ libwmf package as a whole depends on FreeType 2 and either the
+ xmlsoft libxml, or expat libraries. Since GraphicsMagick already uses
+ libxml (for reading SVG and to retrieve files via HTTP or FTP), it is
+ recommended that the options '--without-expat --with-xml' be supplied
+ to libwmf's configure script. If the other features of libwmf are
+ not needed, then the '--disable-heavy' option may be used to only
+ build libwmflite.
+
+ GraphicsMagick's WMF renderer provides some of the finest WMF
+ rendering available due its use of antialiased drawing algorithms.
+ You may select a background color or texture image to render on. For
+ example, "-background '#ffffffff'" renders on a transparent
+ background while "-texture plasma:fractal" renders on a fractal image.
+
+ A free set of Microsoft Windows fonts may be retrieved from
+ http://sourceforge.net/projects/corefonts/. Note that the license
+ for these fonts requires that they be distributed in the original
+ .exe form, but the Linux folks have found ways to deal with that on
+ non-Windows systems.
+
+* GraphicsMagick requires an X server for the 'display', 'animate', and
+ 'import' functions to work properly. Unix systems usually provide an X
+ server as part of their standard installation. For MacOS-X, X11 is a
+ system install time option.
+
+ A free X server for Microsoft Windows is included as part of
+ Cygwin and may be selected from the Cygwin installer. Cygwin is
+ available from
+
+ http://www.cygwin.com/
+
+ There is a nearly free X server available for Windows and Macintosh at
+
+ http://www.microimages.com/downloads/mix/
+
+* GraphicsMagick requires libxml2 available from
+
+ http://xmlsoft.org/
+
+ to read the SVG image format and to retrieve files from over a
+ network via FTP and HTTP.
+
+* GraphicsMagick requires the liblzma library from XZ Utils available from
+
+ http://www.tukaani.org/xz/
+
+ to support TIFF with LZMA compression and future LZMA-compression
+ features (yet to be developed). The utilities from this package are
+ also necessary in order to decompress GraphicsMagick packages
+ distributed with ".xz" or ".lzma" extensions.
+
+* GraphicsMagick requires the ZLIB library from
+
+ http://www.zlib.net/
+
+ to read or write the PNG or Zip compressed MIFF images.
+
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..72a7e5f
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,54 @@
+.. -*- mode: rst -*-
+
+Items large and small which remain to be worked on.
+See website for "wish list".
+--------------------------------------------------------------------
+
+Short Term
+==========
+
+* -random-threshold needs to have gamma 2.2 pre-applied to the pixels
+ for correct appearance.
+
+* Fix browser interoperability issues reported for PNG8.
+
+* AddCompare, and Distortion wrapper functions to
+ the Wand API.
+
+* ctime(), localtime(), and strerror(), all have reentrant
+ forms and are (perhaps) not thread safe under FreeBSD.
+
+ ctime() -> ctime_r(const time_t *clock, char *buf, int buflen)
+ localtime() -> struct tm *localtime_r(const time_t *clock, struct tm *res);
+ strerror() -> strerror_r(int errnum, char *strerrbuf, size_t buflen)
+
+ The ctime() function is equivalent to asctime(localtime(clock)).
+
+Longer Term
+============
+
+* Fix Scitex RGB reader to handle files written by Photoshop.
+
+* Fix PerlMagick BLOB reading (disable header magic checking if
+ already specified).
+
+* Implement DrawableFillPattern and DrawableStrokePattern drawable
+ objects in order to allow setting the fill and stroke patterns.
+
+* Improve performance of Cineon coder.
+
+To Investigate
+==============
+
+* Fix polyline renderering (improperly closes shape) when line is very thick.
+
+* Look into problem reported by Rick Mabry, "Shear produces artifacts
+ for a 0 y-shear (e.g. 60x0)."
+
+* It appears that SyncImagePixels() silently fails if the region
+ includes parts outside of the underlying image. The API supports
+ requesting areas outside of the image, but then the underlying image
+ is not updated. This was first noted with -lat when the image is
+ entirely disk-based.
+
+
diff --git a/TclMagick/AUTHORS b/TclMagick/AUTHORS
new file mode 100644
index 0000000..dfe97d2
--- /dev/null
+++ b/TclMagick/AUTHORS
@@ -0,0 +1,2 @@
+Rolf Schroedter
+David N. Welton \ No newline at end of file
diff --git a/TclMagick/COPYING b/TclMagick/COPYING
new file mode 100644
index 0000000..3e2c921
--- /dev/null
+++ b/TclMagick/COPYING
@@ -0,0 +1 @@
+See the LICENSE file.
diff --git a/TclMagick/ChangeLog b/TclMagick/ChangeLog
new file mode 100644
index 0000000..d513d73
--- /dev/null
+++ b/TclMagick/ChangeLog
@@ -0,0 +1,700 @@
+2017-06-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * generic/TclMagick.c (magickCmd): Resolve SourceForge patch #51
+ "TclMagick: memory access error; possible segfault".
+ (newMagickObj): Fix formatting of pointer value so it is 64-bit
+ safe. Resolves SourceForge patch #50 "TclMagick: 64-bit
+ portability issue".
+
+2017-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * unix/m4/tcl.m4: Update tcl.m4 to TEA 3.10. File supplied by
+ Massimo Manghi.
+
+2017-01-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (AM_DISTCHECK_CONFIGURE_FLAGS): Applied patch by
+ Massimo Manghi to set AM_DISTCHECK_CONFIGURE_FLAGS so that 'make
+ distcheck' remembers configuration options, and also to uninstall
+ pkgIndex.tcl.
+
+2016-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * generic/Makefile.am: Applied patch by Massimo Manghi (plus some
+ fixes by me) to add a 'libttkcommon' shared library to contain
+ codde common to the TclMagick/TkMagick loadable modules, and
+ particularly to allow TkMagick to access TclMagick functions
+ without depending on dlopen() with RTLD_GLOBAL behavior.
+
+2016-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac, Makefile.am: Applied patches by Massimo Manghi to
+ use TEA tcl.m4 version 3.9.
+
+2012-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * generic/TclMagick.c (wandObjCmd): Added support for RandomNoise.
+
+2011-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * tests/test-wand.tcl (SeparateImageChannel): Fix
+ SeparateImageChannel test to handle CMYK properly.
+ (GetSetVirtualPixelMethod): Restore image pixel method to default.
+
+ * pkgIndex.tcl: Tcl package version is 0.46.
+
+ * configure.ac: Next TclMagick release will identify itself as
+ "TclMagick 0.46".
+
+ * generic/TclMagick.c (wandObjCmd): Implementation of
+ virtualpixelmethod was completely wrong. Implementation was
+ cut-and-pasted from image resolution units implementation but not
+ properly updated to deal with VirtualPixelMethod instead.
+
+2011-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * generic/TclMagick.c (wandObjCmd): Allow compiling with earlier
+ than GraphicsMagick 1.3.13 by mapping out compression enumerations
+ added by 1.3.13.
+
+2010-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * generic/TkMagick.c (MagickToPhoto): GraphicsMagick 1.3.8
+ introduced a fix for inverted alpha so the map string is now the
+ same as ImageMagick.
+
+2008-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * configure.ac: Search for GraphicsMagickWand-config and
+ MagickWand-config in the PATH by default.
+
+2008-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Apply useful Automake
+ options. In particular add 'foreign' so that our INSTALL
+ documentation does not get overwritten.
+ * genconf.sh: Update to be more similar to GraphicsMagick 'bootstrap'.
+ * configure.ac: Put m4 files in unix/m4 and configure support
+ scripts in unix/config.
+
+2008-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * pkgIndex.tcl: Tcl package version is 0.45.
+ * configure.ac: Check for the availability of
+ MagickSetImageFormat().
+ * generic/TclMagick.c (wandObjCmd): Added ability to set image
+ format.
+ * tcl.m4: Update to TEA version 3.6
+
+2005-02-02 David N. Welton <davidw@dedasys.com>
+
+ * generic/TkMagick.c: Woops, use Tcl_AppendResult instead of
+ Tcl_AddErrorInfo.
+
+2005-01-22 David N. Welton <davidw@dedasys.com>
+
+ * configure.ac: Bumped version number.
+
+2005-01-17 David N. Welton <davidw@dedasys.com>
+
+ * debian/rules: Added debian directory to aid in creation of
+ TclMagick .deb package.
+
+2005-01-12 David N. Welton <davidw@dedasys.com>
+
+ * Makefile.am (EXTRA_DIST): Added pkgIndex.tcl so that it gets
+ distributed.
+ (install-data-local): Change pkgIndex.tcl install location.
+
+ * generic/Makefile.am (libdir): Make the version part of the
+ install directory.
+
+ * pkgIndex.tcl: Moved the Tk and TclMagick requires here for
+ TkMagick.
+
+ * generic/TclMagick.c (Tclmagick_Init): Use VERSION instead of
+ hard coded version.
+
+ * generic/TkMagick.c: Added stubs ifdef's.
+ (Tkmagick_Init): Use VERSION instead of hard-coded version.
+
+2005-01-11 David N. Welton <davidw@dedasys.com>
+
+ * ltmain.sh: I'm not terribly happy about including this, but not
+ having it causes problems, and there is an exception to the GPL,
+ so I guess it's ok.
+
+ * generic/Makefile.am: Install libraries to package directory.
+
+ * pkgIndex.tcl: Use the packages in the current directory.
+
+ * genconf.sh: Slightly improved script to work with different
+ versions of autotools.
+
+2005-01-08 David N. Welton <davidw@dedasys.com>
+
+ * generic/TclMagick.c: Added patch from George Peter Staplin
+ dealing with UTF/External encoding issues. There may be more work
+ to be done.
+
+ * generic/TkMagick.c (PhotoToMagick): Swapped A and O letters to
+ make alpha channel work here. Argh! Thanks to David Zolli for
+ writing code to point this out.
+
+ * configure.ac: Bumped version number.
+
+2004-12-21 David N. Welton <davidw@dedasys.com>
+
+ * generic/TclMagick.c (wandObjCmd): Return errors on failure for
+ image compare methods.
+
+2004-12-20 David N. Welton <davidw@dedasys.com>
+
+ * generic/TclMagick.c (myMagickError): Use package name function
+ to generate error messages.
+ (wandObjCmd): Fixed bug that was causing AnnotateImage to not
+ function properly.
+
+2004-12-19 David N. Welton <davidw@dedasys.com>
+
+ * INSTALL: Updated install instructions.
+
+ * genconf.sh: Shell script that may be used to generate the config
+ stuff.
+
+2004-12-18 David N. Welton <davidw@dedasys.com>
+
+ * tests/test-bmp-compare.tcl: New tests, thanks to Sheila Miguez.
+
+ * images/*.bmp: Added some bitmap images from Sheila for the
+ comparison test.
+
+2004-12-16 David N. Welton <davidw@dedasys.com>
+
+ * generic/TkMagick.c (MagickToPhoto): Added ifdef'ed
+ Tk_PhotoPutBlock to make things work with Tk 8.5. Thanks to
+ George Staplin for reporting the problem.
+
+ * configure.ac: Bumped version number.
+
+ * generic/Makefile.am (libTkMagick_la_CPPFLAGS): Added
+ TK_XINCLUDES. Thanks to George Staplin for reporting the problem.
+
+ * generic/TclMagick.c (magickCmd): Only free the memory if
+ necessary. Thanks to David Zolli for reporting the problem.
+
+ * generic/TclMagick.c: Fixed a few more, similar free'ing errors.
+
+2004-11-06 David N. Welton <davidw@dedasys.com>
+
+ * generic/TkMagick.c: phototomagick's error message had the photo
+ and wand arguments backwards. Thanks to Sheila Miguez for
+ catching this. Also, make sure we have a wand before attempting
+ to use it.
+
+2004-09-20 David N. Welton <davidw@dedasys.com>
+
+ * doc/index.html: Update outdated information on
+ graphics/imagemagick requirements.
+
+ * configure.ac: New version: 0.42.
+
+ * Makefile.am: Fiddled to get pkgIndex.tcl installed right.
+
+ * tests/tkmagick.tcl (saveimage): Add image save proc and binding
+ to test transformation of Tk images to magick want images.
+
+ * generic/TkMagick.c (MagickToPhoto): Change map depending on
+ Graphics or ImageMagick.
+ (PhotoToMagick): Make sure map is null terminated, switch type
+ depending on Graphics or ImageMagick.
+
+ * INSTALL: Added hint to try auto* stuff if configure is not
+ present.
+
+2004-06-28 Rolf Schroedter <rolf.schroedter@dlr.de>
+ * INSTALL: Added windows compilation instructions
+
+2004-06-28 Rolf Schroedter <rolf.schroedter@dlr.de>
+ * tests/test-wand.tcl: Fixed FxImage, FxImageChannel tests
+
+2004-06-27 Rolf Schroedter <rolf.schroedter@dlr.de>
+ * TclMagick.dsp: Fixed Windows VC++ project file,
+ moved CORE_RL_*.lib from file panel to library bindings
+
+2004-05-20 David N. Welton <davidw@dedasys.com>
+
+ * Makefile.am (EXTRA_DIST): Add license file, tests and images
+ dirs to distribution file.
+
+ * configure.ac: Bumped version number to 0.41 because of auto*
+ changes.
+
+2004-04-02 David N. Welton <davidw@dedasys.com>
+
+ * pkgIndex.tcl: Fixed pkgIndex.tcl, thanks to Arjen Markus.
+
+2004-03-25 David N. Welton <davidw@dedasys.com>
+
+ * images/tclmagick*.png: Added a couple of "logos", that will have
+ to suffice untill someone artistic has a go at it.
+
+2004-03-19 David N. Welton <davidw@dedasys.com>
+
+ * doc/index.html: Added CVS login command to CVS instructions.
+ Added information about GM/IM version dependencies.
+
+2004-03-16 David N. Welton <davidw@dedasys.com>
+
+ * doc/index.html: Add license link.
+
+ * doc/license.txt: Added license to be displayed on the web. This
+ needs to be kept in sync with the main LICENSE file.
+
+2004-03-12 David N. Welton <davidw@dedasys.com>
+
+ * doc/index.html: Fixed up HTML pages some.
+
+2004-03-11 David N. Welton <davidw@dedasys.com>
+
+ * Makefile.am (install-data-local): Added installation
+ instructions for documentation, LICENSE file.
+
+2004-03-10 David N. Welton <davidw@dedasys.com>
+
+ * Makefile.am: Added target to install the pkgIndex.tcl file.
+
+2004-03-07 David N. Welton <davidw@dedasys.com>
+
+ * doc/TclMagick.html: Added some credits/copyright notices.
+
+ * doc/TkMagick.html: Added brief TkMagick.html page to document
+ the TkMagick extension.
+
+ * generic/TkMagick.c (MagickToPhoto): Add alpha channel mapping.
+
+ * generic/Makefile.am (libTkMagick_la_CFLAGS): Added GM_LDFLAGS to
+ LDFLAGS for TkMagick compile, added TCL_INCLUDES to CFLAGS for
+ TclMagick.
+
+ * configure.ac: Bumped version here too.
+
+2004-02-27 Rolf Schroedter <rolf.schroedter@dlr.de>
+ * TclMagick version 0.4
+
+ * Fixed ClipImage and ClipPathImage tests
+
+ * [magick library] list now includes -maxrgb
+
+2004-02-25 Rolf Schroedter <rolf.schroedter@dlr.de>
+ * New API
+ magick library -maxrgb
+
+ * generic/TclMagick.c:
+ Emtpy borderPix argument allowed for ColorFloodfillImage
+
+ * test/test-wand.tcl
+ Fixed tests for ColorFloodfillImage, MapImage, TextureImage
+
+2004-02-15 David N. Welton <davidw@dedasys.com>
+
+ * doc/TclMagick.html: Fixed a few phrases, indented code according
+ to emacs' desires.
+
+2004-02-14 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * API changes
+ wandName FxImage expr ?newName?
+ wandName FxImageChannel channelType expr ?newName?
+
+ * Added a few words to documentation
+
+2004-02-08 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * API renamed:
+ wandName ChannelImage --> wandName SeparateImageChannel
+
+ * API changes:
+ wandName FxImageChannel channelType expr
+
+ * new API:
+ wandName FxImage expr
+
+2004-02-08 David N. Welton <davidw@dedasys.com>
+
+ * generic/Makefile.am: Added magick libraries to libraries
+ variables.
+
+ * generic/TclMagick.c: Changed format types from int to long int
+ to make compiler happy.
+
+ * INSTALL: Added a bit to the install text.
+
+ * configure.ac: Created some code to grab
+ --with-magick=/path/to/GraphisMagickWand-config script and use
+ that to get information about includes, ldflags and such needed to
+ compile against Image or GraphicsMagick.
+
+2004-01-29 David N. Welton <davidw@dedasys.com>
+
+ * generic/Makefile.am: Add correct instructions to build
+ libTkMagick shared library. Requires automake 1.5 or greater.
+
+2004-01-25 David N. Welton <davidw@dedasys.com>
+
+ * tcl.m4: Moved to top level directory.
+
+ * AUTHORS NEWS README INSTALL COPYING: Added to make automake
+ happy.
+
+ * configure.ac: Added this in the top level directory as it
+ doesn't seem that it will be very happy in unix/.
+
+ * generic/Makefile.am: Tentative addition of Makefile.am governing
+ the building of libTclMagick.so.
+
+2004-01-16 David N. Welton <davidw@dedasys.com>
+
+ * tests/test-*.tcl: Added "multiplatform" startup code for tests.
+
+2004-01-15 David N. Welton <davidw@dedasys.com>
+
+ * generic/TclMagick.h: Added findMagickObj and myMagickError to .h
+ file, and made then non-static in the .c file. They are used in
+ TkMagick.c.
+
+2004-01-09 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * API changes:
+ wandName AnnotateImage draw ?x y ? ?angle? text
+ * New API's:
+ magick version # returns TclMagick version
+ magick library ?-option? # Returns Magick library attributes
+
+2004-01-09 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * generic/TclMagick.c: Fixed types casts of (int *).
+
+2004-01-09 David N. Welton <davidw@dedasys.com>
+
+ * unix/configure.ac: Added code to fetch GraphicsMagickWand-config
+ --libs information.
+
+ * unix/Makefile.in (SHLIB_LD_FLAGS): Added @LDFLAGS@ so that the
+ GraphicsMagickWand-config information is passed on to the
+ makefile.
+
+2004-01-08 David N. Welton <davidw@dedasys.com>
+
+ * generic/TclMagick.c: Fixed types of a large number of variables.
+
+2004-01-08 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Fixed DRAW incompatibility between to Wand color settings:
+ Now the call is [$draw XXXcolor ?pix?]
+ * Updated DRAW documentation
+
+
+2004-01-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ * unix/INSTALL: Added simple installation instructions.
+
+2004-01-08 David N. Welton <davidw@dedasys.com>
+
+ * generic/TclMagick.c (drawObjCmd): Sub-switches need 'default'
+ case to avoid warnings caused by options not handled.
+ * generic/TclMagick.c: Cast a few enum's to ints when used as
+ arguments to Tcl_NewIntObj.
+
+2004-01-07 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Fixes for a few GCC warnings:
+
+2004-01-07 David N. Welton <davidw@dedasys.com>
+
+ * unix/configure.ac: Use configure.ac instead of configure.in.
+
+ * ChangeLog: Undid CRLF line-end formatting.
+
+ * unix/configure.in: Updated configure system from latest Tcl
+ sample extension. Added a few things to configure.in to pick up
+ flags from GraphicsMagickWand-config, which must be in the PATH.
+
+2004-01-07 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * API rename: CloneImage --> GetImage
+ * Added API's
+ SetFillPatternURL url
+ SetStrokePatternURL url
+
+2004-01-06 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Added missing tests for new API's
+ * A few problems reported to ImageMagick
+
+2004-01-05 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Review of ImageMagick-API completeness
+ * API renamed: wandName GetNumberOfImages ==> GetNumberImages
+ * Two cloning methods: CloneMagickWand & MagickCloneImage
+ * Optional argument for [magick fonts|formats ?pattern?]
+
+2003-12-30 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * PixelWand: Added support for colors cyan,magenta,yellow,black
+ incl. test-pixel.tcl
+
+ * struct PointInfo (DrawBezier/Polygon/Polyline)
+ may in future contain Z-component, initialize it properly
+
+ * Updated docs of Set(Get)Fill(Stroke,TextUnder)Color subcommands
+
+2003-12-29 David N. Welton <davidw@dedasys.com>
+
+ * Redid directory trees. Hopefully for the last time this
+ evening:-)
+
+2003-12-29 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Minor header file changes in ImageMagick
+
+ * API changes:
+ wandName SetOption format key value
+
+ * New API's:
+ wandName ProfileImage name ?profile?
+ wandName RemoveProfile name
+
+2003-12-27 David N. Welton <davidw@dedasys.com>
+
+ * doc/: Moved files over from www directory as doc/ is proper for
+ a Tcl package.
+
+ * src/TclMagick.c: Removed USE_TCL_STUBS - it should not be hard
+ coded in the file, but passed on the command line or in some other
+ fashion.
+
+ * src/: Added src directory for sources to correspond with a
+ regular Tcl package layout.
+
+2003-12-26 David N. Welton <davidw@dedasys.com>
+
+ * source/TclMagick.c: Removed funny ^M characters. I hope this
+ isn't a problem with CVS.
+ (magickCmd): Make listlen a long instead of an int.
+
+2003-12-23 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * New API's:
+ pixelName SetQuantumColor ?{r g b o}?
+
+ * Test script updated
+ New PixelWand color naming: "rgb(10%,20%,30%)"
+ Updated changed API's
+
+2003-12-22 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * General remarks:
+ MagickGetImageHistogram not implemented: returns array of PixelWand objects ???
+
+ * API changes:
+ Added channelType="index"
+ Added colorspace="LAB"
+ "wandName CloneWand" renamed to "wandName CloneImage"
+ wandName CompareImages refName metric
+ "wandName fx" renamed to "wandName fxchannel"
+ "wandName Get/SetImagePixels" renamed to "wandName Get/SetPixels"
+ "wandName gamma" renamed to "wandName gammaimage"
+ wandName profile name ?profile?
+
+ * API's removed:
+ wandName SetFuzzyColorDistance
+
+ * New API's:
+ magick resourcelimit resource ?limit?
+ magick fonts pattern
+ magick formats pattern
+
+ wandName CompareImageChannels refName chan metric
+ wandName Get/SetBackgroundColor bgPix
+ wandName Get/SetBluePrimary ?x y?
+ wandName Get/SetGreenPrimary ?x y?
+ wandName Get/SetRedPrimary ?x y?
+ wandName Get/SetBorderColor ?pixel?
+ wandName Get/SetChannelDepth channelType ?depth?
+ wandName GetChannelExtrema channelType
+ wandName GetChannelMean channelType
+ wandName Get/SetColormapColor index ?pixel?
+ wandName GetColors
+ wandName Get/SetColorspace ?colorspaceType?
+ wandName Get/SetCompose ?opType?
+ wandName Get/SetCompression ?compressType?
+ wandName Get/SetDelay ?delay?
+ wandName Get/SetDepth ?depth?
+ wandName GetExtrema
+ wandName Get/SetDispose ?disposeType?
+ wandName GetFormat
+ wandName Get/SetGamma ?gamma?
+ wandName GetWidth/Height
+ wandName Get/SetIndex ?index?
+ wandName GetSetInterlaceScheme ?interlaceType?
+ wandName Get/SetIterations ?num?
+ wandName Get/SetMatteColor ?pixel?
+ wandName Get/SetProfile
+ wandName Get/SetRenderingIntent ?renderType?
+ wandName SetScene ?num?
+ wandName GetImageSize
+ wandName Get/SetImageType ?type?
+ wandName Get/SetImageUnits ?unitType?
+ wandName Get/SetVirtualPixelMethod ?methodType?
+ wandName Get/SetWhitePoint ?x y?
+ wandName GetX/YResolution
+ wandName Get/SetSamplingFactors ?factors?
+ wandName PingImage filename
+ wandName QueryFontMetrics draw text
+ wandName QueryFonts pattern
+ wandName ReadImageBlob data
+ wandName SetOption format options
+ wandName SetResolution x y
+ wandName SetPassphrase phrase
+ wandName TintImage tintPixel opacityPixel
+ wandName ThresholdImageChannel channelType threshold
+ wandName TransformImage crop geometry ?newName?
+
+
+2003-12-17 David N. Welton <davidw@dedasys.com>
+
+ * source/TclMagick.h: Updated to latest working TclMagick.h.
+
+ * source/TkMagick.c: Added TkMagick.c, a bridge between TclMagick
+ and Tk.
+
+ * source/TclMagick.c: Updated to latest file from work done by
+ Rolf and myself.
+
+2003-12-16 David N. Welton <davidw@dedasys.com>
+
+ * LICENSE: Added BSD style license with Rolf's name in it.
+
+ * README: Added README file.
+
+ * ChangeLog: started adding TclMagick code to GraphicsMagick CVS.
+
+2003-12-04 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Removed subcommands:
+ wandName seek
+
+ * API changes:
+ wandName CompositeImage compWand opType ?x y?
+ wandName GammaImage level
+
+ * New API's:
+ wandName AddImage name
+ wandName AppendImages ?stack? ?newName?
+ wandName AverageImages ?newName?
+ wandName ClipImage pathname ?inside?
+ wandname fxImageChannel fxWand channelType expr
+ wandName GammaImageChannel channelType level
+ wandName HasNextImage
+ wandName HasPreviousImage
+ wandName LevelImageChannel channelType ?black? ?gamma? ?white?
+ wandName MontageImage draw tileGeom thumbGeom mode frameGeom ?newName?
+ wandName MorphImages num ?newName?
+ wandName MosaicImages ?newName?
+
+2003-12-01 David N. Welton <davidw@dedasys.com>
+
+ * src/TclMagick.c (wandObjCmd): Added Image width/height commands.
+
+2003-07-02 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * API changes:
+ wandName RotateImage background degrees
+ wandName WriteImages filename ?adjoin?
+ wandName CompareImage
+ returns {flag pixelMeanError normMeanError normMaxError}
+ flag: 1=equal, 0=different
+ wandName ContrastImage ?sharpen?
+ bool sharpen (default=1)
+
+ drawName path elliptic rx ry rotation large sweep x y
+ double rx ry rotation x y
+ bool large sweep
+
+ * New API's:
+ wandName GammaImage levelPix
+ wandName GetImageSignature
+ wandName ImplodeImage ?amount?
+ wandName LabelImage str
+ wandName LevelImage black gamma white
+ wandName MagnifyImage
+ wandName MapImage mapName ?dither?
+ wandName MatteFloodfillImage opacity ?fuzz? ?borderPix? ?x y?
+ wandName MedianFilterImage ?radius?
+ wandName MinifyImage
+ wandName ModulateImage ?brightness? ?saturation? ?hue?
+ wandName MotionBlurImage ?radius? ?sigma? ?angle?
+ wandName NegateImage ?gray?
+ wandName NormalizeImage
+ wandName OilPaintImage ?radius?
+ wandName OpaqueImage targetPix fillPix ?fuzz?
+ wandName ProfileImage name ?profile?
+ wandName QuantizeImage(s) numColors colorspaceType treedepth dither measureError
+ wandName RaiseImage width height ?x y? ?raise?
+ wandName ReduceNoiseImage ?radius?
+ wandName ResampleImage xRes ?yRes? ?filterType? ?blur?
+ wandName RollImage xOfs yOfs
+ wandName SampleImage x y
+ wandName ScaleImage x y
+ wandName SharpenImage ?radius? ?sigma?
+ wandName ShaveImage x y
+ wandName ShearImage background xShear ?yShear?
+ wandName SolarizeImage ?threshold?
+ wandName SpreadImage ?radius?
+ wandName SteganoImage watermark ?offset? ?newName?
+ wandName StereoImage anotherWand ?newName?
+ wandName StripImage
+ wandName SwirlImage ?degrees?
+ wandName TextureImage textWand ?newName?
+ wandName ThresholdImage threshold
+ wandName TransparentImage targetPix ?opacity? ?fuzz?
+ wandName TrimImage ?fuzz?
+ wandName UnsharpMaskImage ?radius? ?sigma? ?amount? ?threshold?
+ wandName WaveImage amplitude wavelength
+ wandName WhiteThresholdImage thresholdPixel
+
+2003-06-25 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * API change:
+ wandName ColorFloodfillImage fillPix ?fuzz? ?borderPix? ?x y?
+
+2003-06-24 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Changed magick objects creation to have a single 'magick' command:
+ magick create type ?name? # type="wand","drawing","pixel"
+ magick delete name ?name? ... # Delete TclMagick objects
+ magick names ?type? # Return all TclMagick objects (of type)
+ magick type name # Return the type of the object
+ magick types # Return valid type names
+ * Replaced Tcl_Alloc(),Tcl_Free() by ckalloc(),ckfree
+
+2003-06-24 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Added MagickDescribeImage() API
+
+ * Free string results for MagickDescribeImage(), MagickGetFilename(),
+ MagickGetImageFilename()
+
+ * Always use Tcl_Free(), not free()
+
+2003-06-24 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Pre-Release 0.1
+
+ * TclMagick officially announced
+
+2003-05-26 Rolf Schroedter <rolf.schroedter@dlr.de>
+
+ * Created
+
diff --git a/TclMagick/INSTALL b/TclMagick/INSTALL
new file mode 100644
index 0000000..1fe6b7e
--- /dev/null
+++ b/TclMagick/INSTALL
@@ -0,0 +1,85 @@
+ TclMagick
+ =========
+
+TclMagick install instructions.
+
+===============
+Unix platforms:
+===============
+
+Installing TclMagick in a separate directory from ImageMagick or
+GraphicsMagick.
+
+0) If there is no configure script (you are fetching from CVS, for
+ instance), try running the genconf.sh script. It runs aclocal,
+ autoconf, and automake --add-missing, in that order. Be sure to
+ use recent versions of the autotools (1.8 works for me, 1.4
+ doesn't).
+
+1) Run the ./configure script. The following arguments are
+ recommended:
+
+./configure \
+ --with-tcl=/usr/lib/tcl8.4/ \
+ --with-tk=/usr/lib/tk8.4/ \
+ --with-magick=/usr/local/bin/GraphicsMagickWand-config \
+
+Others that might very well be helpful are --enable-shared.
+
+The --with-tcl option tells the configure script where to find Tcl - or
+more accurately, the tclConfig.sh file that configure uses to find
+important information about how to compile Tcl extensions. If this option
+is not specified, the file may (but might not) be found automatically.
+
+The --with-tk option tells the configure script where to find Tk, - or
+more accurately, the tkConfig.sh file that configure uses to find
+important information about how to compile Tcl/Tk extensions. If this
+option is not specified, the file may (but might not) be found
+automatically.
+
+The --with-magick option is used to tell the configure script where to
+get information about the GraphicsMagick or ImageMagick install. If the
+--with-magick option is not specified, then the PATH is searched for
+GraphicsMagickWand-config (default for GraphicsMagick), and if that is
+not found, then the PATH is searched for MagickWand-config (default for
+ImageMagick).
+
+2) Run make - this should build the libraries.
+
+
+=================
+Windows platform:
+=================
+
+* ImageMagick(IM) or GraphicsMagick(GM) should be installed on your system:
+ - Check the "Install development headers and library ..." option.
+ - After installation the computer needs a restart to update the PATH environment.
+ - Windows also needs Ghostscript installed for fond rendering.
+
+* Unzip the TclMagick sources
+
+* Compile TclMagick using MS Visual C++ 6.0
+ - Open the VC++ workspace in the TclMagick\win directory
+ - Change the include path and library path to your IM/GM directory:
+ Project settings - All configurations - C/C++ - preprocessor
+ Project settings - All configurations - Linker - input
+ - Compile the project, the compiled DLL's are in
+ Debug\TclMagick.dll
+ Release\TclMagick.dll
+
+* Run the test-suite
+ - Change to the TclMagick\tests directory
+ - By default the debug version is used: Debug\TclMagick.dll
+ - Run the three test-*.tcl scripts
+ Resulting images are written to the TclMagick\tmp directory
+
+* Use TclMagick
+ As a library package:
+ - Copy the pkgIndex.tcl and TclMagick.dll files to your Tcl-library
+ - Load the library with
+ package require TclMagick
+ By directly loadind the DLL:
+ - Copy the TclMagick.dll to your desired destination
+ - Load the library with
+ load TclMagick.dll
+
diff --git a/TclMagick/LICENSE b/TclMagick/LICENSE
new file mode 100644
index 0000000..1cd0d1d
--- /dev/null
+++ b/TclMagick/LICENSE
@@ -0,0 +1,39 @@
+This software is copyrighted 2004 by Rolf Schrdter
+<Rolf.Schroedter@dlr.de> and David N. Welton <davidw@dedasys.com>. The
+following terms apply to all files associated with the software unless
+explicitly disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+GOVERNMENT USE: If you are acquiring this software on behalf of the
+U.S. government, the Government shall have only "Restricted Rights"
+in the software and related documentation as defined in the Federal
+Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+are acquiring the software on behalf of the Department of Defense, the
+software shall be classified as "Commercial Computer Software" and the
+Government shall have only "Restricted Rights" as defined in Clause
+252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
+authors grant the U.S. Government and others acting in its behalf
+permission to use and distribute the software in accordance with the
+terms specified in this license.
diff --git a/TclMagick/Makefile.am b/TclMagick/Makefile.am
new file mode 100644
index 0000000..5abcdab
--- /dev/null
+++ b/TclMagick/Makefile.am
@@ -0,0 +1,13 @@
+AUTOMAKE_OPTIONS = 1.11 dist-zip dist-bzip2 foreign
+ACLOCAL_AMFLAGS = -I unix/m4
+AM_DISTCHECK_CONFIGURE_FLAGS = --with-tcl=${TCL_BIN_DIR} --with-tk=${TK_BIN_DIR} --with-magick=${wand_config} --exec-prefix=${prefix}
+
+EXTRA_DIST=LICENSE tests images doc pkgIndex.tcl
+SUBDIRS = generic
+
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)@libdir@/TclMagick@VERSION@
+ $(INSTALL_DATA) $(top_srcdir)/pkgIndex.tcl $(DESTDIR)@libdir@/TclMagick@VERSION@
+
+uninstall-local:
+ rm -v $(DESTDIR)@libdir@/TclMagick@VERSION@/pkgIndex.tcl
diff --git a/TclMagick/Makefile.in b/TclMagick/Makefile.in
new file mode 100644
index 0000000..9648337
--- /dev/null
+++ b/TclMagick/Makefile.in
@@ -0,0 +1,820 @@
+# Makefile.in generated by automake 1.11.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \
+ ChangeLog INSTALL NEWS unix/config/config.guess \
+ unix/config/config.sub unix/config/depcomp \
+ unix/config/install-sh unix/config/ltmain.sh \
+ unix/config/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/unix/m4/libtool.m4 \
+ $(top_srcdir)/unix/m4/ltoptions.m4 \
+ $(top_srcdir)/unix/m4/ltsugar.m4 \
+ $(top_srcdir)/unix/m4/ltversion.m4 \
+ $(top_srcdir)/unix/m4/lt~obsolete.m4 \
+ $(top_srcdir)/unix/m4/tcl.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d "$(distdir)" \
+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr "$(distdir)"; }; }
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CELIB_DIR = @CELIB_DIR@
+CFLAGS = @CFLAGS@
+CFLAGS_DEBUG = @CFLAGS_DEBUG@
+CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+CLEANFILES = @CLEANFILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH = @CYGPATH@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GM_CPPFLAGS = @GM_CPPFLAGS@
+GM_LDFLAGS = @GM_LDFLAGS@
+GM_LIBS = @GM_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
+INSTALL_LIBRARY = @INSTALL_LIBRARY@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LD_LIBRARY_PATH_VAR = @LD_LIBRARY_PATH_VAR@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKE_LIB = @MAKE_LIB@
+MAKE_SHARED_LIB = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB = @MAKE_STUB_LIB@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CFLAGS = @PKG_CFLAGS@
+PKG_HEADERS = @PKG_HEADERS@
+PKG_INCLUDES = @PKG_INCLUDES@
+PKG_LIBS = @PKG_LIBS@
+PKG_LIB_FILE = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+PRACTCL_CFLAGS = @PRACTCL_CFLAGS@
+PRACTCL_NAME_LIBRARY = @PRACTCL_NAME_LIBRARY@
+PRACTCL_SHARED_LIB = @PRACTCL_SHARED_LIB@
+PRACTCL_STATIC_LIB = @PRACTCL_STATIC_LIB@
+PRACTCL_STUB_LIB = @PRACTCL_STUB_LIB@
+PRACTCL_TOOLSET = @PRACTCL_TOOLSET@
+PRACTCL_VC_MANIFEST_EMBED_DLL = @PRACTCL_VC_MANIFEST_EMBED_DLL@
+PRACTCL_VC_MANIFEST_EMBED_EXE = @PRACTCL_VC_MANIFEST_EMBED_EXE@
+PRACTCL_WINDOWINGSYSTEM = @PRACTCL_WINDOWINGSYSTEM@
+RANLIB = @RANLIB@
+RANLIB_STUB = @RANLIB_STUB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHARED_BUILD = @SHARED_BUILD@
+SHELL = @SHELL@
+SHLIB_CFLAGS = @SHLIB_CFLAGS@
+SHLIB_LD = @SHLIB_LD@
+SHLIB_LD_LIBS = @SHLIB_LD_LIBS@
+SHLIB_SUFFIX = @SHLIB_SUFFIX@
+STLIB_LD = @STLIB_LD@
+STRIP = @STRIP@
+STUBS_BUILD = @STUBS_BUILD@
+TCLSH_PROG = @TCLSH_PROG@
+TCL_BIN_DIR = @TCL_BIN_DIR@
+TCL_DEFS = @TCL_DEFS@
+TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@
+TCL_INCLUDES = @TCL_INCLUDES@
+TCL_LD_FLAGS = @TCL_LD_FLAGS@
+TCL_LIBS = @TCL_LIBS@
+TCL_LIB_FILE = @TCL_LIB_FILE@
+TCL_LIB_FLAG = @TCL_LIB_FLAG@
+TCL_LIB_SPEC = @TCL_LIB_SPEC@
+TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@
+TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@
+TCL_SRC_DIR = @TCL_SRC_DIR@
+TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@
+TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@
+TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
+TCL_THREADS = @TCL_THREADS@
+TCL_VERSION = @TCL_VERSION@
+TEA_TK_EXTENSION = @TEA_TK_EXTENSION@
+TK_BIN_DIR = @TK_BIN_DIR@
+TK_INCLUDES = @TK_INCLUDES@
+TK_LIBS = @TK_LIBS@
+TK_LIB_FILE = @TK_LIB_FILE@
+TK_LIB_FLAG = @TK_LIB_FLAG@
+TK_LIB_SPEC = @TK_LIB_SPEC@
+TK_SRC_DIR = @TK_SRC_DIR@
+TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@
+TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@
+TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@
+TK_VERSION = @TK_VERSION@
+TK_XINCLUDES = @TK_XINCLUDES@
+VC_MANIFEST_EMBED_DLL = @VC_MANIFEST_EMBED_DLL@
+VC_MANIFEST_EMBED_EXE = @VC_MANIFEST_EMBED_EXE@
+VERSION = @VERSION@
+WISH_PROG = @WISH_PROG@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wand_config = @wand_config@
+AUTOMAKE_OPTIONS = 1.11 dist-zip dist-bzip2 foreign
+ACLOCAL_AMFLAGS = -I unix/m4
+AM_DISTCHECK_CONFIGURE_FLAGS = --with-tcl=${TCL_BIN_DIR} --with-tk=${TK_BIN_DIR} --with-magick=${wand_config} --exec-prefix=${prefix}
+EXTRA_DIST = LICENSE tests images doc pkgIndex.tcl
+SUBDIRS = generic
+all: all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-data-local
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-local
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am am--refresh check check-am clean clean-generic \
+ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
+ dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \
+ distcheck distclean distclean-generic distclean-libtool \
+ distclean-tags distcleancheck distdir distuninstallcheck dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-data-local install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-local
+
+
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)@libdir@/TclMagick@VERSION@
+ $(INSTALL_DATA) $(top_srcdir)/pkgIndex.tcl $(DESTDIR)@libdir@/TclMagick@VERSION@
+
+uninstall-local:
+ rm -v $(DESTDIR)@libdir@/TclMagick@VERSION@/pkgIndex.tcl
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/TclMagick/NEWS b/TclMagick/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TclMagick/NEWS
diff --git a/TclMagick/README b/TclMagick/README
new file mode 100644
index 0000000..30180d1
--- /dev/null
+++ b/TclMagick/README
@@ -0,0 +1,9 @@
+ TclMagick
+ =========
+
+A Tcl binding for the ImageMagick image manipulation library.
+
+Originally by Rolf Schroedter <Rolf.Schroedter@dlr.de>
+
+Updates, new commands and Tk connector by David N. Welton
+<davidw@dedasys.com>
diff --git a/TclMagick/aclocal.m4 b/TclMagick/aclocal.m4
new file mode 100644
index 0000000..13b205a
--- /dev/null
+++ b/TclMagick/aclocal.m4
@@ -0,0 +1,1043 @@
+# generated automatically by aclocal 1.11.2 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+# Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
+# Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11.2], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.2])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
+# 2010, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
+# Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
+# 2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
+# Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
+# Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# (`yes' being less verbose, `no' or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules],
+[ --enable-silent-rules less verbose build output (undo: `make V=1')
+ --disable-silent-rules verbose build output (undo: `make V=0')])
+case $enable_silent_rules in
+yes) AM_DEFAULT_VERBOSITY=0;;
+no) AM_DEFAULT_VERBOSITY=1;;
+*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([unix/m4/libtool.m4])
+m4_include([unix/m4/ltoptions.m4])
+m4_include([unix/m4/ltsugar.m4])
+m4_include([unix/m4/ltversion.m4])
+m4_include([unix/m4/lt~obsolete.m4])
+m4_include([unix/m4/tcl.m4])
diff --git a/TclMagick/configure b/TclMagick/configure
new file mode 100755
index 0000000..2d16312
--- /dev/null
+++ b/TclMagick/configure
@@ -0,0 +1,19760 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for TclMagick 0.46.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='TclMagick'
+PACKAGE_TARNAME='tclmagick'
+PACKAGE_VERSION='0.46'
+PACKAGE_STRING='TclMagick 0.46'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+WISH_PROG
+TCLSH_PROG
+PRACTCL_NAME_LIBRARY
+PRACTCL_VC_MANIFEST_EMBED_EXE
+PRACTCL_VC_MANIFEST_EMBED_DLL
+PRACTCL_STUB_LIB
+PRACTCL_STATIC_LIB
+PRACTCL_SHARED_LIB
+PRACTCL_TOOLSET
+PRACTCL_CFLAGS
+VC_MANIFEST_EMBED_EXE
+VC_MANIFEST_EMBED_DLL
+RANLIB_STUB
+MAKE_STUB_LIB
+MAKE_STATIC_LIB
+MAKE_SHARED_LIB
+MAKE_LIB
+LD_LIBRARY_PATH_VAR
+SHLIB_CFLAGS
+SHLIB_LD_LIBS
+SHLIB_SUFFIX
+SHLIB_LD
+STLIB_LD
+CFLAGS_WARNING
+CFLAGS_OPTIMIZE
+CFLAGS_DEBUG
+RC
+CELIB_DIR
+STUBS_BUILD
+SHARED_BUILD
+TCL_THREADS
+TK_INCLUDES
+TCL_INCLUDES
+MATH_LIBS
+INSTALL_LIBRARY
+INSTALL_DATA_DIR
+INSTALL
+PRACTCL_WINDOWINGSYSTEM
+TK_XINCLUDES
+TK_LIBS
+TK_STUB_LIB_SPEC
+TK_STUB_LIB_FLAG
+TK_STUB_LIB_FILE
+TK_LIB_SPEC
+TK_LIB_FLAG
+TK_LIB_FILE
+TK_SRC_DIR
+TK_BIN_DIR
+TK_VERSION
+TCL_SHLIB_LD_LIBS
+TCL_LD_FLAGS
+TCL_EXTRA_CFLAGS
+TCL_DEFS
+TCL_LIBS
+CLEANFILES
+TCL_STUB_LIB_SPEC
+TCL_STUB_LIB_FLAG
+TCL_STUB_LIB_FILE
+TCL_LIB_SPEC
+TCL_LIB_FLAG
+TCL_LIB_FILE
+TCL_SRC_DIR
+TCL_BIN_DIR
+TCL_PATCH_LEVEL
+TCL_VERSION
+PKG_CFLAGS
+PKG_LIBS
+PKG_INCLUDES
+PKG_HEADERS
+PKG_TCL_SOURCES
+PKG_STUB_OBJECTS
+PKG_STUB_SOURCES
+PKG_STUB_LIB_FILE
+PKG_LIB_FILE
+CYGPATH
+TEA_TK_EXTENSION
+GM_LIBS
+GM_LDFLAGS
+GM_CPPFLAGS
+wand_config
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+enable_silent_rules
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_magick
+with_tcl
+with_tk
+with_tclinclude
+with_tkinclude
+enable_threads
+enable_stubs
+enable_64bit
+enable_64bit_vis
+enable_rpath
+enable_wince
+with_celib
+with_tclsh
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures TclMagick 0.46 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/tclmagick]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of TclMagick 0.46:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --enable-silent-rules less verbose build output (undo: `make V=1')
+ --disable-silent-rules verbose build output (undo: `make V=0')
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-threads build with threads
+ --enable-shared build and link with shared libraries (default: on)
+ --enable-stubs build and link with stub libraries. Always true for
+ shared builds (default: on)
+ --enable-64bit enable 64bit support (default: off)
+ --enable-64bit-vis enable 64bit Sparc VIS support (default: off)
+ --disable-rpath disable rpath support (default: on)
+ --enable-wince enable Win/CE support (where applicable)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot=DIR Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).
+ --with-magick location of Graphics/MagickWand-config script
+ --with-tcl directory containing tcl configuration
+ (tclConfig.sh)
+ --with-tk directory containing tk configuration (tkConfig.sh)
+ --with-tclinclude directory containing the public Tcl header files
+ --with-tkinclude directory containing the public Tk header files
+ --with-celib=DIR use Windows/CE support library from DIR
+ --with-tclsh Specify a local tcl shell to use for dynamic code
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+TclMagick configure 0.46
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by TclMagick $as_me 0.46, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Specify directory where m4 macros may be found.
+
+
+# Directory where autotools helper scripts lives.
+ac_aux_dir=
+for ac_dir in unix/config "$srcdir"/unix/config; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in unix/config \"$srcdir\"/unix/config" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+am__api_version='1.11'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='tclmagick'
+ VERSION='0.46'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+# Add configure option --enable-maintainer-mode which enables dependency
+# checking and generation useful to package maintainers. This is made an
+# option to avoid confusing end users.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+# Enable support for silent build rules
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in
+yes) AM_DEFAULT_VERBOSITY=0;;
+no) AM_DEFAULT_VERBOSITY=1;;
+*) AM_DEFAULT_VERBOSITY=1;;
+esac
+AM_BACKSLASH='\'
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_="/usr/lib:/lib"
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
+$as_echo_n "checking for library containing strerror... " >&6; }
+if ${ac_cv_search_strerror+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strerror ();
+int
+main ()
+{
+return strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' cposix; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_strerror=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_strerror+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_strerror+:} false; then :
+
+else
+ ac_cv_search_strerror=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5
+$as_echo "$ac_cv_search_strerror" >&6; }
+ac_res=$ac_cv_search_strerror
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+
+
+
+# Check whether --with-magick was given.
+if test "${with_magick+set}" = set; then :
+ withval=$with_magick; with_magick=${withval}
+fi
+
+
+GM_CPPFLAGS=''
+GM_LDFLAGS=''
+GM_LIBS=''
+wand_config=''
+if test x"${with_magick}" != x
+then
+ if test -x "${with_magick}"
+ then
+ wand_config=${with_magick}
+ else
+ as_fn_error $? "${with_magick} is not an executable file" "$LINENO" 5
+ fi
+fi
+if test x"${wand_config}" = x
+then
+ for ac_prog in GraphicsMagickWand-config MagickWand-config
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_wand_config+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $wand_config in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_wand_config="$wand_config" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_wand_config="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+wand_config=$ac_cv_path_wand_config
+if test -n "$wand_config"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $wand_config" >&5
+$as_echo "$wand_config" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$wand_config" && break
+done
+
+fi
+if test x"${wand_config}" = x
+then
+ as_fn_error $? "Please specify the Graphics/ImageMagick-config script with --with-magick!" "$LINENO" 5
+fi
+
+PATH=$PATH:`dirname ${wand_config}`
+export PATH
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Graphics/ImageMagick Wand configuration script" >&5
+$as_echo_n "checking for Graphics/ImageMagick Wand configuration script... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${wand_config}" >&5
+$as_echo "${wand_config}" >&6; }
+GM_CPPFLAGS=`${wand_config} --cppflags`
+
+GM_LDFLAGS=`${wand_config} --ldflags`
+
+GM_LIBS=`${wand_config} --libs`
+
+
+CPPFLAGS_SAVE=$CPPFLAGS
+LDFLAGS_SAVE=$LDFLAGS
+LIBS_SAVE=$LIBS
+CPPFLAGS="$CPPFLAGS $GM_CPPFLAGS"
+LDFLAGS="$LDFLAGS $GM_LDFLAGS"
+LIBS="$GM_LIBS $LIBS"
+for ac_func in MagickSetImageFormat
+do :
+ ac_fn_c_check_func "$LINENO" "MagickSetImageFormat" "ac_cv_func_MagickSetImageFormat"
+if test "x$ac_cv_func_MagickSetImageFormat" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MAGICKSETIMAGEFORMAT 1
+_ACEOF
+
+fi
+done
+
+CPPFLAGS=$CPPFLAGS_SAVE
+LDFLAGS=$LDFLAGS_SAVE
+LIBS=$LIBS_SAVE
+
+
+ # TEA extensions pass this us the version of TEA they think they
+ # are compatible with.
+ TEA_VERSION="3.10"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
+$as_echo_n "checking for correct TEA configuration... " >&6; }
+ if test x"${PACKAGE_NAME}" = x ; then
+ as_fn_error $? "
+The PACKAGE_NAME variable must be defined by your TEA configure.ac" "$LINENO" 5
+ fi
+ if test x"3.10" = x ; then
+ as_fn_error $? "
+TEA version not specified." "$LINENO" 5
+ elif test "3.10" != "${TEA_VERSION}" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: warning: requested TEA version \"3.10\", have \"${TEA_VERSION}\"" >&5
+$as_echo "warning: requested TEA version \"3.10\", have \"${TEA_VERSION}\"" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (TEA ${TEA_VERSION})" >&5
+$as_echo "ok (TEA ${TEA_VERSION})" >&6; }
+ fi
+
+ # If the user did not set CFLAGS, set it now to keep macros
+ # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
+ if test "${CFLAGS+set}" != "set" ; then
+ CFLAGS=""
+ fi
+ TEA_TK_EXTENSION=0
+
+ case "`uname -s`" in
+ *win32*|*WIN32*|*MINGW32_*)
+ # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CYGPATH+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CYGPATH"; then
+ ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CYGPATH="cygpath -m"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
+$as_echo "$CYGPATH" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ EXEEXT=".exe"
+ TEA_PLATFORM="windows"
+ ;;
+ *CYGWIN_*)
+ EXEEXT=".exe"
+ # CYGPATH and TEA_PLATFORM are determined later in LOAD_TCLCONFIG
+ ;;
+ *)
+ CYGPATH=echo
+ # Maybe we are cross-compiling....
+ case ${host_alias} in
+ *mingw32*)
+ EXEEXT=".exe"
+ TEA_PLATFORM="windows"
+ ;;
+ *)
+ EXEEXT=""
+ TEA_PLATFORM="unix"
+ ;;
+ esac
+ ;;
+ esac
+
+ # Check if exec_prefix is set. If not use fall back to prefix.
+ # Note when adjusted, so that TEA_PREFIX can correct for this.
+ # This is needed for recursive configures, since autoconf propagates
+ # $prefix, but not $exec_prefix (doh!).
+ if test x$exec_prefix = xNONE ; then
+ exec_prefix_default=yes
+ exec_prefix=$prefix
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&5
+$as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+
+
+
+
+ # This package name must be replaced statically for AC_SUBST to work
+
+ # Substitute STUB_LIB_FILE in case package creates a stub library too.
+
+
+ # We AC_SUBST these here to ensure they are subst'ed,
+ # in case the user doesn't call TEA_ADD_...
+
+
+
+
+
+
+
+
+
+
+
+ #
+ # Ok, lets find the tcl configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tcl
+ #
+
+ if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+
+# Check whether --with-tcl was given.
+if test "${with_tcl+set}" = set; then :
+ withval=$with_tcl; with_tclconfig="${withval}"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
+$as_echo_n "checking for Tcl configuration... " >&6; }
+ if ${ac_cv_c_tclconfig+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ # First check to see if --with-tcl was specified.
+ if test x"${with_tclconfig}" != x ; then
+ case "${with_tclconfig}" in
+ */tclConfig.sh )
+ if test -f "${with_tclconfig}"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
+$as_echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
+ with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+ else
+ as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+ `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
+ `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+ `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
+ `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+ `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
+ `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ ; do
+ if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/lib/tcl8.5 2>/dev/null` \
+ ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+fi
+
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCL_BIN_DIR="# no Tcl configs found"
+ as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
+ else
+ no_tcl=
+ TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
+ fi
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }
+
+ if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
+$as_echo "loading" >&6; }
+ . "${TCL_BIN_DIR}/tclConfig.sh"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
+$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+ eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+ # If the TCL_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TCL_LIB_SPEC will be set to the value
+ # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+ # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+ TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+ TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tcl.framework installed in an arbitrary location.
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+ for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+ TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+ TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+ TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+ eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+ eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+ eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking platform" >&5
+$as_echo_n "checking platform... " >&6; }
+ hold_cc=$CC; CC="$TCL_CC"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ #ifdef _WIN32
+ #error win32
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ TEA_PLATFORM="unix"
+ CYGPATH=echo
+
+else
+
+ TEA_PLATFORM="windows"
+ # Extract the first word of "cygpath", so it can be a program name with args.
+set dummy cygpath; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CYGPATH+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CYGPATH"; then
+ ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CYGPATH="cygpath -m"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
+fi
+fi
+CYGPATH=$ac_cv_prog_CYGPATH
+if test -n "$CYGPATH"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
+$as_echo "$CYGPATH" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CC=$hold_cc
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEA_PLATFORM" >&5
+$as_echo "$TEA_PLATFORM" >&6; }
+
+ # The BUILD_$pkg is to define the correct extern storage class
+ # handling when making this package
+
+cat >>confdefs.h <<_ACEOF
+#define BUILD_${PACKAGE_NAME} /**/
+_ACEOF
+
+ # Do this here as we have fully defined TEA_PLATFORM now
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ EXEEXT=".exe"
+ CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
+ fi
+
+ # TEA specific:
+
+
+
+
+
+
+
+
+
+ #
+ # Ok, lets find the tk configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tk
+ #
+
+ if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ TEA_TK_EXTENSION=0
+
+# Check whether --with-tk was given.
+if test "${with_tk+set}" = set; then :
+ withval=$with_tk; with_tkconfig="${withval}"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk configuration" >&5
+$as_echo_n "checking for Tk configuration... " >&6; }
+ if ${ac_cv_c_tkconfig+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ case "${with_tkconfig}" in
+ */tkConfig.sh )
+ if test -f "${with_tkconfig}"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5
+$as_echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;}
+ with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+ else
+ as_fn_error $? "${with_tkconfig} directory doesn't contain tkConfig.sh" "$LINENO" 5
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \
+ `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \
+ `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \
+ `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \
+ `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \
+ `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \
+ `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ ; do
+ if test -f "$i/Tk.framework/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+fi
+
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TK_BIN_DIR="# no Tk configs found"
+ as_fn_error $? "Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh" "$LINENO" 5
+ else
+ no_tk=
+ TEA_TK_EXTENSION=1
+ TK_BIN_DIR="${ac_cv_c_tkconfig}"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TK_BIN_DIR}/tkConfig.sh" >&5
+$as_echo "found ${TK_BIN_DIR}/tkConfig.sh" >&6; }
+ fi
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5
+$as_echo_n "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... " >&6; }
+
+ if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
+$as_echo "loading" >&6; }
+ . "${TK_BIN_DIR}/tkConfig.sh"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5
+$as_echo "could not find ${TK_BIN_DIR}/tkConfig.sh" >&6; }
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+ eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+ # If the TK_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TK_LIB_SPEC will be set to the value
+ # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+ # instead of TK_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+ TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+ TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tk.framework installed in an arbitrary location.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+ for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+ TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+ TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+ TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+ eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+ eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+ eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+ # TEA specific: Ensure windowingsystem is defined
+ case ${TK_DEFS} in
+ *PLATFORM_SDL*)
+ TEA_WINDOWINGSYSTEM="x11"
+ PRACTCL_WINDOWINGSYSTEM="sdl"
+ TEA_USE_SDL=yes
+ ;;
+ esac
+ if test "${TEA_USE_SDL}" = "yes" ; then
+ true
+ elif test "${TEA_PLATFORM}" = "unix" ; then
+ case ${TK_DEFS} in
+ *MAC_OSX_TK*)
+
+$as_echo "#define MAC_OSX_TK 1" >>confdefs.h
+
+ TEA_WINDOWINGSYSTEM="aqua"
+ PRACTCL_WINDOWINGSYSTEM="cocoa"
+ TEA_USE_HITHEME=no;
+ if test "${TK_VERSION}" = "8.5" ; then
+ if test "${TK_PATCH_LEVEL}" > ".17" ; then
+ TEA_USE_HITHEME=yes;
+ fi
+ elif test "${TK_VERSION}" = "8.6" ; then
+ if test "${TK_PATCH_LEVEL}" > ".3" ; then
+ TEA_USE_HITHEME=yes;
+ fi
+ elif test "${TK_VERSION}" > "8.6" ; then
+ TEA_USE_HITHEME=yes;
+ fi
+ ;;
+ *)
+ TEA_WINDOWINGSYSTEM="x11"
+ PRACTCL_WINDOWINGSYSTEM="x11"
+ ;;
+ esac
+ elif test "${TEA_PLATFORM}" = "windows" ; then
+ TEA_WINDOWINGSYSTEM="win32"
+ PRACTCL_WINDOWINGSYSTEM="windows"
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # TEA specific:
+
+
+ # Practcl
+
+
+
+
+ if test "${prefix}" = "NONE"; then
+ prefix_default=yes
+ if test x"${TCL_PREFIX}" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
+$as_echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
+ prefix=${TCL_PREFIX}
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: --prefix defaulting to /usr/local" >&5
+$as_echo "$as_me: --prefix defaulting to /usr/local" >&6;}
+ prefix=/usr/local
+ fi
+ fi
+ if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+ -o x"${exec_prefix_default}" = x"yes" ; then
+ if test x"${TCL_EXEC_PREFIX}" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
+$as_echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
+ exec_prefix=${TCL_EXEC_PREFIX}
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: --exec-prefix defaulting to ${prefix}" >&5
+$as_echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;}
+ exec_prefix=$prefix
+ fi
+ fi
+
+
+
+ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+ # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL}'
+ INSTALL_SCRIPT='${INSTALL}'
+ INSTALL_LIBRARY='${INSTALL_DATA}'
+
+
+
+
+
+
+
+
+ #--------------------------------------------------------------------
+ # Checks to see if the make program sets the $MAKE variable.
+ #--------------------------------------------------------------------
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+ #--------------------------------------------------------------------
+ # Find ranlib
+ #--------------------------------------------------------------------
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+ #--------------------------------------------------------------------
+ # Determines the correct binary file extension (.o, .obj, .exe etc.)
+ #--------------------------------------------------------------------
+
+
+
+
+
+ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+
+
+ #------------------------------------------------------------------------
+ # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+ # It makes compiling go faster. (This is only a performance feature.)
+ #------------------------------------------------------------------------
+
+ if test -z "$no_pipe" -a -n "$GCC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5
+$as_echo_n "checking if the compiler understands -pipe... " >&6; }
+if ${tcl_cv_cc_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_cc_pipe=yes
+else
+ tcl_cv_cc_pipe=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5
+$as_echo "$tcl_cv_cc_pipe" >&6; }
+ if test $tcl_cv_cc_pipe = yes; then
+ CFLAGS="$CFLAGS -pipe"
+ fi
+ fi
+
+ #--------------------------------------------------------------------
+ # Common compiler flag setup
+ #--------------------------------------------------------------------
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+ if test "${TEA_PLATFORM}" = "unix" ; then
+
+ #--------------------------------------------------------------------
+ # On a few very rare systems, all of the libm.a stuff is
+ # already in libc.a. Set compiler flags accordingly.
+ # Also, Linux requires the "ieee" library for math to work
+ # right (and it must appear before "-lm").
+ #--------------------------------------------------------------------
+
+ ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin"
+if test "x$ac_cv_func_sin" = xyes; then :
+ MATH_LIBS=""
+else
+ MATH_LIBS="-lm"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5
+$as_echo_n "checking for main in -lieee... " >&6; }
+if ${ac_cv_lib_ieee_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lieee $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ieee_main=yes
+else
+ ac_cv_lib_ieee_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5
+$as_echo "$ac_cv_lib_ieee_main" >&6; }
+if test "x$ac_cv_lib_ieee_main" = xyes; then :
+ MATH_LIBS="-lieee $MATH_LIBS"
+fi
+
+
+ #--------------------------------------------------------------------
+ # Interactive UNIX requires -linet instead of -lsocket, plus it
+ # needs net/errno.h to define the socket-related error codes.
+ #--------------------------------------------------------------------
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -linet" >&5
+$as_echo_n "checking for main in -linet... " >&6; }
+if ${ac_cv_lib_inet_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_inet_main=yes
+else
+ ac_cv_lib_inet_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_main" >&5
+$as_echo "$ac_cv_lib_inet_main" >&6; }
+if test "x$ac_cv_lib_inet_main" = xyes; then :
+ LIBS="$LIBS -linet"
+fi
+
+ ac_fn_c_check_header_mongrel "$LINENO" "net/errno.h" "ac_cv_header_net_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_net_errno_h" = xyes; then :
+
+
+$as_echo "#define HAVE_NET_ERRNO_H 1" >>confdefs.h
+
+fi
+
+
+
+ #--------------------------------------------------------------------
+ # Check for the existence of the -lsocket and -lnsl libraries.
+ # The order here is important, so that they end up in the right
+ # order in the command line generated by make. Here are some
+ # special considerations:
+ # 1. Use "connect" and "accept" to check for -lsocket, and
+ # "gethostbyname" to check for -lnsl.
+ # 2. Use each function name only once: can't redo a check because
+ # autoconf caches the results of the last check and won't redo it.
+ # 3. Use -lnsl and -lsocket only if they supply procedures that
+ # aren't already present in the normal libraries. This is because
+ # IRIX 5.2 has libraries, but they aren't needed and they're
+ # bogus: they goof up name resolution if used.
+ # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+ # To get around this problem, check for both libraries together
+ # if -lsocket doesn't work by itself.
+ #--------------------------------------------------------------------
+
+ tcl_checkBoth=0
+ ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
+if test "x$ac_cv_func_connect" = xyes; then :
+ tcl_checkSocket=0
+else
+ tcl_checkSocket=1
+fi
+
+ if test "$tcl_checkSocket" = 1; then
+ ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt"
+if test "x$ac_cv_func_setsockopt" = xyes; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5
+$as_echo_n "checking for setsockopt in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_setsockopt=yes
+else
+ ac_cv_lib_socket_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5
+$as_echo "$ac_cv_lib_socket_setsockopt" >&6; }
+if test "x$ac_cv_lib_socket_setsockopt" = xyes; then :
+ LIBS="$LIBS -lsocket"
+else
+ tcl_checkBoth=1
+fi
+
+fi
+
+ fi
+ if test "$tcl_checkBoth" = 1; then
+ tk_oldLibs=$LIBS
+ LIBS="$LIBS -lsocket -lnsl"
+ ac_fn_c_check_func "$LINENO" "accept" "ac_cv_func_accept"
+if test "x$ac_cv_func_accept" = xyes; then :
+ tcl_checkNsl=0
+else
+ LIBS=$tk_oldLibs
+fi
+
+ fi
+ ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_gethostbyname=yes
+else
+ ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
+ LIBS="$LIBS -lnsl"
+fi
+
+fi
+
+
+ # TEA specific: Don't perform the eval of the libraries here because
+ # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+ TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dirent.h" >&5
+$as_echo_n "checking dirent.h... " >&6; }
+if ${tcl_cv_dirent_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+
+#ifndef _POSIX_SOURCE
+# ifdef __Lynx__
+ /*
+ * Generate compilation error to make the test fail: Lynx headers
+ * are only valid if really in the POSIX environment.
+ */
+
+ missing_procedure();
+# endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_dirent_h=yes
+else
+ tcl_cv_dirent_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_dirent_h" >&5
+$as_echo "$tcl_cv_dirent_h" >&6; }
+
+ if test $tcl_cv_dirent_h = no; then
+
+$as_echo "#define NO_DIRENT_H 1" >>confdefs.h
+
+ fi
+
+ # TEA specific:
+ ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_errno_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_ERRNO_H 1" >>confdefs.h
+
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_FLOAT_H 1" >>confdefs.h
+
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "values.h" "ac_cv_header_values_h" "$ac_includes_default"
+if test "x$ac_cv_header_values_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_VALUES_H 1" >>confdefs.h
+
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes; then :
+
+$as_echo "#define HAVE_LIMITS_H 1" >>confdefs.h
+
+else
+
+$as_echo "#define NO_LIMITS_H 1" >>confdefs.h
+
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+ tcl_ok=1
+else
+ tcl_ok=0
+fi
+
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "strtol" >/dev/null 2>&1; then :
+
+else
+ tcl_ok=0
+fi
+rm -f conftest*
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "strtoul" >/dev/null 2>&1; then :
+
+else
+ tcl_ok=0
+fi
+rm -f conftest*
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "strtod" >/dev/null 2>&1; then :
+
+else
+ tcl_ok=0
+fi
+rm -f conftest*
+
+ if test $tcl_ok = 0; then
+
+$as_echo "#define NO_STDLIB_H 1" >>confdefs.h
+
+ fi
+ ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes; then :
+ tcl_ok=1
+else
+ tcl_ok=0
+fi
+
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "strstr" >/dev/null 2>&1; then :
+
+else
+ tcl_ok=0
+fi
+rm -f conftest*
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "strerror" >/dev/null 2>&1; then :
+
+else
+ tcl_ok=0
+fi
+rm -f conftest*
+
+
+ # See also memmove check below for a place where NO_STRING_H can be
+ # set and why.
+
+ if test $tcl_ok = 0; then
+
+$as_echo "#define NO_STRING_H 1" >>confdefs.h
+
+ fi
+
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_wait_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+
+else
+
+$as_echo "#define NO_DLFCN_H 1" >>confdefs.h
+
+fi
+
+
+
+ # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+ for ac_header in sys/param.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_param_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_PARAM_H 1
+_ACEOF
+
+fi
+
+done
+
+
+ # Let the user call this, because if it triggers, they will
+ # need a compat/strtod.c that is correct. Users can also
+ # use Tcl_GetDouble(FromObj) instead.
+ #TEA_BUGGY_STRTOD
+ fi
+
+
+
+ vars=""
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ as_fn_error $? "could not find header file '${srcdir}/$i'" "$LINENO" 5
+ fi
+ PKG_HEADERS="$PKG_HEADERS $i"
+ done
+
+
+
+ vars=""
+ for i in $vars; do
+ PKG_INCLUDES="$PKG_INCLUDES $i"
+ done
+
+
+
+ vars=""
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ case $i in
+ *.lib)
+ # Convert foo.lib to -lfoo for GCC
+ i=-l`echo "$i" | sed -e 's/\.[^.]*$//' -e 's/\.lib.*//'`
+ ;;
+ esac
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+
+
+
+ PKG_CFLAGS="$PKG_CFLAGS "
+
+
+
+ vars=""
+ for i in $vars; do
+ # check for existence - allows for generic/win/unix VPATH
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ as_fn_error $? "could not find stub source file '$i'" "$LINENO" 5
+ fi
+ PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
+ fi
+ PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+ done
+
+
+
+
+ vars=""
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ as_fn_error $? "could not find tcl source file '${srcdir}/$i'" "$LINENO" 5
+ fi
+ PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+ done
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl public headers" >&5
+$as_echo_n "checking for Tcl public headers... " >&6; }
+
+
+# Check whether --with-tclinclude was given.
+if test "${with_tclinclude+set}" = set; then :
+ withval=$with_tclinclude; with_tclinclude=${withval}
+fi
+
+
+ if ${ac_cv_c_tclh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ # Use the value from --with-tclinclude, if it was given
+
+ if test x"${with_tclinclude}" != x ; then
+ if test -f "${with_tclinclude}/tcl.h" ; then
+ ac_cv_c_tclh=${with_tclinclude}
+ else
+ as_fn_error $? "${with_tclinclude} directory does not contain tcl.h" "$LINENO" 5
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers directory
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tcl is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TCL_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tcl.h" ; then
+ ac_cv_c_tclh=$i
+ break
+ fi
+ done
+ fi
+
+fi
+
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tclh}" = x ; then
+ as_fn_error $? "tcl.h not found. Please specify its location with --with-tclinclude" "$LINENO" 5
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tclh}" >&5
+$as_echo "${ac_cv_c_tclh}" >&6; }
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+ TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk public headers" >&5
+$as_echo_n "checking for Tk public headers... " >&6; }
+
+
+# Check whether --with-tkinclude was given.
+if test "${with_tkinclude+set}" = set; then :
+ withval=$with_tkinclude; with_tkinclude=${withval}
+fi
+
+
+ if ${ac_cv_c_tkh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ # Use the value from --with-tkinclude, if it was given
+
+ if test x"${with_tkinclude}" != x ; then
+ if test -f "${with_tkinclude}/tk.h" ; then
+ ac_cv_c_tkh=${with_tkinclude}
+ else
+ as_fn_error $? "${with_tkinclude} directory does not contain tk.h" "$LINENO" 5
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers directory.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tk is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tk's --prefix location,
+ # relative to directory of tkConfig.sh, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TK_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tk.h" ; then
+ ac_cv_c_tkh=$i
+ break
+ fi
+ done
+ fi
+
+fi
+
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tkh}" = x ; then
+ as_fn_error $? "tk.h not found. Please specify its location with --with-tkinclude" "$LINENO" 5
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tkh}" >&5
+$as_echo "${ac_cv_c_tkh}" >&6; }
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+ TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+
+
+ if test "${PRACTCL_WINDOWINGSYSTEM}" != "x11"; then
+ # On Windows and Aqua, we need the X compat headers
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11 header files" >&5
+$as_echo_n "checking for X11 header files... " >&6; }
+ if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+ INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+ TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${INCLUDE_DIR_NATIVE}" >&5
+$as_echo "${INCLUDE_DIR_NATIVE}" >&6; }
+ fi
+
+
+
+ # Check whether --enable-threads was given.
+if test "${enable_threads+set}" = set; then :
+ enableval=$enable_threads; tcl_ok=$enableval
+else
+ tcl_ok=yes
+fi
+
+
+ if test "${enable_threads+set}" = set; then
+ enableval="$enable_threads"
+ tcl_ok=$enableval
+ else
+ tcl_ok=yes
+ fi
+
+ if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+ TCL_THREADS=1
+
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ # We are always OK on Windows, so check what this platform wants:
+
+ # USE_THREAD_ALLOC tells us to try the special thread-based
+ # allocator that significantly reduces lock contention
+
+$as_echo "#define USE_THREAD_ALLOC 1" >>confdefs.h
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+ if test "`uname -s`" = "SunOS" ; then
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ fi
+
+$as_echo "#define _THREAD_SAFE 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+ ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then :
+ tcl_ok=yes
+else
+ tcl_ok=no
+fi
+
+ if test "$tcl_ok" = "no"; then
+ # Check a little harder for __pthread_mutex_init in the same
+ # library, as some systems hide it there until pthread.h is
+ # defined. We could alternatively do an AC_TRY_COMPILE with
+ # pthread.h, but that will work with libpthread really doesn't
+ # exist, like AIX 4.2. [Bug: 4359]
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for __pthread_mutex_init in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread___pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __pthread_mutex_init ();
+int
+main ()
+{
+return __pthread_mutex_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread___pthread_mutex_init=yes
+else
+ ac_cv_lib_pthread___pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread___pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread___pthread_mutex_init" = xyes; then :
+ tcl_ok=yes
+else
+ tcl_ok=no
+fi
+
+ fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthread"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthreads" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthreads... " >&6; }
+if ${ac_cv_lib_pthreads_pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthreads_pthread_mutex_init=yes
+else
+ ac_cv_lib_pthreads_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_mutex_init" = xyes; then :
+ tcl_ok=yes
+else
+ tcl_ok=no
+fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthreads"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc" >&5
+$as_echo_n "checking for pthread_mutex_init in -lc... " >&6; }
+if ${ac_cv_lib_c_pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_c_pthread_mutex_init=yes
+else
+ ac_cv_lib_c_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_c_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_c_pthread_mutex_init" = xyes; then :
+ tcl_ok=yes
+else
+ tcl_ok=no
+fi
+
+ if test "$tcl_ok" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc_r" >&5
+$as_echo_n "checking for pthread_mutex_init in -lc_r... " >&6; }
+if ${ac_cv_lib_c_r_pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc_r $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_c_r_pthread_mutex_init=yes
+else
+ ac_cv_lib_c_r_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_c_r_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_c_r_pthread_mutex_init" = xyes; then :
+ tcl_ok=yes
+else
+ tcl_ok=no
+fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -pthread"
+ else
+ TCL_THREADS=0
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5
+$as_echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;}
+ fi
+ fi
+ fi
+ fi
+ fi
+ else
+ TCL_THREADS=0
+ fi
+ # Do checking message here to not mess up interleaved configure output
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5
+$as_echo_n "checking for building with threads... " >&6; }
+ if test "${TCL_THREADS}" = 1; then
+
+$as_echo "#define TCL_THREADS 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (default)" >&5
+$as_echo "yes (default)" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ # TCL_THREADS sanity checking. See if our request for building with
+ # threads is the same as the way Tcl was built. If not, warn the user.
+ case ${TCL_DEFS} in
+ *THREADS=1*)
+ if test "${TCL_THREADS}" = "0"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+ that IS thread-enabled. It is recommended to use --enable-threads." >&5
+$as_echo "$as_me: WARNING:
+ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+ that IS thread-enabled. It is recommended to use --enable-threads." >&2;}
+ fi
+ ;;
+ *)
+ if test "${TCL_THREADS}" = "1"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+ --enable-threads requested, but building against a Tcl that is NOT
+ thread-enabled. This is an OK configuration that will also run in
+ a thread-enabled core." >&5
+$as_echo "$as_me: WARNING:
+ --enable-threads requested, but building against a Tcl that is NOT
+ thread-enabled. This is an OK configuration that will also run in
+ a thread-enabled core." >&2;}
+ fi
+ ;;
+ esac
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
+$as_echo_n "checking how to build libraries... " >&6; }
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; shared_ok=$enableval
+else
+ shared_ok=yes
+fi
+
+
+ if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ shared_ok=$enableval
+ else
+ shared_ok=yes
+ fi
+
+ # Check whether --enable-stubs was given.
+if test "${enable_stubs+set}" = set; then :
+ enableval=$enable_stubs; stubs_ok=$enableval
+else
+ stubs_ok=yes
+fi
+
+
+ if test "${enable_stubs+set}" = set; then
+ enableval="$enable_stubs"
+ stubs_ok=$enableval
+ else
+ stubs_ok=yes
+ fi
+
+ # Stubs are always enabled for shared builds
+ if test "$shared_ok" = "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
+$as_echo "shared" >&6; }
+ SHARED_BUILD=1
+ STUBS_BUILD=1
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
+ SHARED_BUILD=0
+
+$as_echo "#define STATIC_BUILD 1" >>confdefs.h
+
+ if test "$stubs_ok" = "yes" ; then
+ STUBS_BUILD=1
+ else
+ STUBS_BUILD=0
+ fi
+ fi
+ if test "${STUBS_BUILD}" = "1" ; then
+
+$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
+
+
+$as_echo "#define USE_TCLOO_STUBS 1" >>confdefs.h
+
+ if test "${TEA_WINDOWINGSYSTEM}" != ""; then
+
+$as_echo "#define USE_TK_STUBS 1" >>confdefs.h
+
+ fi
+ fi
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+
+
+ # Step 0.a: Enable 64 bit support?
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
+$as_echo_n "checking if 64bit support is requested... " >&6; }
+ # Check whether --enable-64bit was given.
+if test "${enable_64bit+set}" = set; then :
+ enableval=$enable_64bit; do64bit=$enableval
+else
+ do64bit=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
+$as_echo "$do64bit" >&6; }
+
+ # Step 0.b: Enable Solaris 64 bit VIS support?
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5
+$as_echo_n "checking if 64bit Sparc VIS support is requested... " >&6; }
+ # Check whether --enable-64bit-vis was given.
+if test "${enable_64bit_vis+set}" = set; then :
+ enableval=$enable_64bit_vis; do64bitVIS=$enableval
+else
+ do64bitVIS=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5
+$as_echo "$do64bitVIS" >&6; }
+ # Force 64bit on with VIS
+ if test "$do64bitVIS" = "yes"; then :
+ do64bit=yes
+fi
+
+ # Step 0.c: Check if visibility support is available. Do this here so
+ # that platform specific alternatives can be used below if this fails.
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5
+$as_echo_n "checking if compiler supports visibility \"hidden\"... " >&6; }
+if ${tcl_cv_cc_visibility_hidden+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ extern __attribute__((__visibility__("hidden"))) void f(void);
+ void f(void) {}
+int
+main ()
+{
+f();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_cc_visibility_hidden=yes
+else
+ tcl_cv_cc_visibility_hidden=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5
+$as_echo "$tcl_cv_cc_visibility_hidden" >&6; }
+ if test $tcl_cv_cc_visibility_hidden = yes; then :
+
+
+$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h
+
+
+$as_echo "#define HAVE_HIDDEN 1" >>confdefs.h
+
+
+fi
+
+ # Step 0.d: Disable -rpath support?
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5
+$as_echo_n "checking if rpath support is requested... " >&6; }
+ # Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+ enableval=$enable_rpath; doRpath=$enableval
+else
+ doRpath=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5
+$as_echo "$doRpath" >&6; }
+
+ # TEA specific: Cross-compiling options for Windows/CE builds?
+
+ if test "${TEA_PLATFORM}" = windows; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Windows/CE build is requested" >&5
+$as_echo_n "checking if Windows/CE build is requested... " >&6; }
+ # Check whether --enable-wince was given.
+if test "${enable_wince+set}" = set; then :
+ enableval=$enable_wince; doWince=$enableval
+else
+ doWince=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doWince" >&5
+$as_echo "$doWince" >&6; }
+
+fi
+
+ # Set the variable "system" to hold the name and version number
+ # for the system.
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5
+$as_echo_n "checking system version... " >&6; }
+if ${tcl_cv_sys_version+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ # TEA specific:
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ tcl_cv_sys_version=windows
+ else
+ tcl_cv_sys_version=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5
+$as_echo "$as_me: WARNING: can't find uname command" >&2;}
+ tcl_cv_sys_version=unknown
+ else
+ if test "`uname -s`" = "AIX" ; then
+ tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5
+$as_echo "$tcl_cv_sys_version" >&6; }
+ system=$tcl_cv_sys_version
+
+
+ # Require ranlib early so we can override it in special cases below.
+
+
+
+ # Set configuration options based on system name and version.
+ # This is similar to Tcl's unix/tcl.m4 except that we've added a
+ # "windows" case and removed some core-only vars.
+
+ do64bit_ok=no
+ # default to '{$LIBS}' and set to "" on per-platform necessary basis
+ SHLIB_LD_LIBS='${LIBS}'
+ # When ld needs options to work in 64-bit mode, put them in
+ # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+ # is disabled by the user. [Bug 1016796]
+ LDFLAGS_ARCH=""
+ UNSHARED_LIB_SUFFIX=""
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+ ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+ TCL_LIB_VERSIONS_OK=ok
+ CFLAGS_DEBUG=-g
+ if test "$GCC" = yes; then :
+
+ CFLAGS_OPTIMIZE=-O2
+ CFLAGS_WARNING="-Wall"
+
+else
+
+ CFLAGS_OPTIMIZE=-O
+ CFLAGS_WARNING=""
+
+fi
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+ STLIB_LD='${AR} cr'
+ LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+ if test "x$SHLIB_VERSION" = x; then :
+ SHLIB_VERSION=""
+else
+ SHLIB_VERSION=".$SHLIB_VERSION"
+fi
+ case $system in
+ # TEA specific:
+ windows)
+ # This is a 2-stage check to make sure we have the 64-bit SDK
+ # We have to know where the SDK is installed.
+ # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+ # MACHINE is IX86 for LINK, but this is used by the manifest,
+ # which requires x86|amd64|ia64.
+ MACHINE="X86"
+ if test "$do64bit" != "no" ; then
+ if test "x${MSSDK}x" = "xx" ; then
+ MSSDK="C:/Progra~1/Microsoft Platform SDK"
+ fi
+ MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'`
+ PATH64=""
+ case "$do64bit" in
+ amd64|x64|yes)
+ MACHINE="AMD64" ; # default to AMD64 64-bit build
+ PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+ ;;
+ ia64)
+ MACHINE="IA64"
+ PATH64="${MSSDK}/Bin/Win64"
+ ;;
+ esac
+ if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
+$as_echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ensure latest Platform SDK is installed" >&5
+$as_echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
+ do64bit="no"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using 64-bit $MACHINE mode" >&5
+$as_echo " Using 64-bit $MACHINE mode" >&6; }
+ do64bit_ok="yes"
+ fi
+ fi
+
+ if test "$doWince" != "no" ; then
+ if test "$do64bit" != "no" ; then
+ as_fn_error $? "Windows/CE and 64-bit builds incompatible" "$LINENO" 5
+ fi
+ if test "$GCC" = "yes" ; then
+ as_fn_error $? "Windows/CE and GCC builds incompatible" "$LINENO" 5
+ fi
+
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-celib
+
+ if test x"${no_celib}" = x ; then
+ # we reset no_celib in case something fails here
+ no_celib=true
+
+# Check whether --with-celib was given.
+if test "${with_celib+set}" = set; then :
+ withval=$with_celib; with_celibconfig=${withval}
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows/CE celib directory" >&5
+$as_echo_n "checking for Windows/CE celib directory... " >&6; }
+ if ${ac_cv_c_celibconfig+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ # First check to see if --with-celibconfig was specified.
+ if test x"${with_celibconfig}" != x ; then
+ if test -d "${with_celibconfig}/inc" ; then
+ ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+ else
+ as_fn_error $? "${with_celibconfig} directory doesn't contain inc directory" "$LINENO" 5
+ fi
+ fi
+
+ # then check for a celib library
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ for i in \
+ ../celib-palm-3.0 \
+ ../celib \
+ ../../celib-palm-3.0 \
+ ../../celib \
+ `ls -dr ../celib-*3.[0-9]* 2>/dev/null` \
+ ${srcdir}/../celib-palm-3.0 \
+ ${srcdir}/../celib \
+ `ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \
+ ; do
+ if test -d "$i/inc" ; then
+ ac_cv_c_celibconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+
+fi
+
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ as_fn_error $? "Cannot find celib support library directory" "$LINENO" 5
+ else
+ no_celib=
+ CELIB_DIR=${ac_cv_c_celibconfig}
+ CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $CELIB_DIR" >&5
+$as_echo "found $CELIB_DIR" >&6; }
+ fi
+ fi
+
+ # Set defaults for common evc4/PPC2003 setup
+ # Currently Tcl requires 300+, possibly 420+ for sockets
+ CEVERSION=420; # could be 211 300 301 400 420 ...
+ TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
+ ARCH=ARM; # could be ARM MIPS X86EM ...
+ PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+ if test "$doWince" != "yes"; then
+ # If !yes then the user specified something
+ # Reset ARCH to allow user to skip specifying it
+ ARCH=
+ eval `echo $doWince | awk -F, '{ \
+ if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
+ if ($1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+ if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
+ if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
+ if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
+ }'`
+ if test "x${ARCH}" = "x" ; then
+ ARCH=$TARGETCPU;
+ fi
+ fi
+ OSVERSION=WCE$CEVERSION;
+ if test "x${WCEROOT}" = "x" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+ if test ! -d "${WCEROOT}" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+ fi
+ fi
+ if test "x${SDKROOT}" = "x" ; then
+ SDKROOT="C:/Program Files/Windows CE Tools"
+ if test ! -d "${SDKROOT}" ; then
+ SDKROOT="C:/Windows CE Tools"
+ fi
+ fi
+ WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+ SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+ if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+ as_fn_error $? "could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" "$LINENO" 5
+ doWince="no"
+ else
+ # We could PATH_NOSPACE these, but that's not important,
+ # as long as we quote them when used.
+ CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+ if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+ CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+ fi
+ CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+ fi
+ fi
+
+ if test "$GCC" != "yes" ; then
+ if test "${SHARED_BUILD}" = "0" ; then
+ runtime=-MT
+ else
+ runtime=-MD
+ fi
+ case "x`echo \${VisualStudioVersion}`" in
+ x1[4-9]*)
+ lflags="${lflags} -nodefaultlib:libucrt.lib"
+
+ vars="ucrt.lib"
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ case $i in
+ *.lib)
+ # Convert foo.lib to -lfoo for GCC
+ i=-l`echo "$i" | sed -e 's/\.[^.]*$//' -e 's/\.lib.*//'`
+ ;;
+ esac
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+
+
+ ;;
+ *)
+ ;;
+ esac
+
+ if test "$do64bit" != "no" ; then
+ # All this magic is necessary for the Win64 SDK RC1 - hobbs
+ CC="\"${PATH64}/cl.exe\""
+ CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+ RC="\"${MSSDK}/bin/rc.exe\""
+ lflags="${lflags} -nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+ LINKBIN="\"${PATH64}/link.exe\""
+ CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+ CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+ # Avoid 'unresolved external symbol __security_cookie'
+ # errors, c.f. http://support.microsoft.com/?id=894573
+
+ vars="bufferoverflowU.lib"
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ case $i in
+ *.lib)
+ # Convert foo.lib to -lfoo for GCC
+ i=-l`echo "$i" | sed -e 's/\.[^.]*$//' -e 's/\.lib.*//'`
+ ;;
+ esac
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+
+
+ elif test "$doWince" != "no" ; then
+ CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+ if test "${TARGETCPU}" = "X86"; then
+ CC="\"${CEBINROOT}/cl.exe\""
+ else
+ CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+ fi
+ CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+ RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+ arch=`echo ${ARCH} | awk '{print tolower($0)}'`
+ defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # Static CE builds require static celib as well
+ defs="${defs} _DLL"
+ fi
+ for i in $defs ; do
+
+cat >>confdefs.h <<_ACEOF
+#define $i 1
+_ACEOF
+
+ done
+
+cat >>confdefs.h <<_ACEOF
+#define _WIN32_WCE $CEVERSION
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNDER_CE $CEVERSION
+_ACEOF
+
+ CFLAGS_DEBUG="-nologo -Zi -Od"
+ CFLAGS_OPTIMIZE="-nologo -Ox"
+ lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+ lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+ LINKBIN="\"${CEBINROOT}/link.exe\""
+
+ else
+ RC="rc"
+ lflags="${lflags} -nologo"
+ LINKBIN="link"
+ CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+ CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+ fi
+ fi
+
+ if test "$GCC" = "yes"; then
+ # mingw gcc mode
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
+set dummy ${ac_tool_prefix}windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RC"; then
+ ac_cv_prog_RC="$RC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RC="${ac_tool_prefix}windres"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RC=$ac_cv_prog_RC
+if test -n "$RC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
+$as_echo "$RC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RC"; then
+ ac_ct_RC=$RC
+ # Extract the first word of "windres", so it can be a program name with args.
+set dummy windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RC"; then
+ ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RC="windres"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RC=$ac_cv_prog_ac_ct_RC
+if test -n "$ac_ct_RC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
+$as_echo "$ac_ct_RC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RC" = x; then
+ RC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RC=$ac_ct_RC
+ fi
+else
+ RC="$ac_cv_prog_RC"
+fi
+
+ CFLAGS_DEBUG="-g"
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+ SHLIB_LD='${CC} -shared'
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ PRACTCL_UNSHARED_LIB_SUFFIX='.a'
+
+ LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+ LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
+$as_echo_n "checking for cross-compile version of gcc... " >&6; }
+if ${ac_cv_cross+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #ifdef _WIN32
+ #error cross-compiler
+ #endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_cross=yes
+else
+ ac_cv_cross=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
+$as_echo "$ac_cv_cross" >&6; }
+ if test "$ac_cv_cross" = "yes"; then
+ case "$do64bit" in
+ amd64|x64|yes)
+ CC="x86_64-w64-mingw32-gcc"
+ LD="x86_64-w64-mingw32-ld"
+ AR="x86_64-w64-mingw32-ar"
+ RANLIB="x86_64-w64-mingw32-ranlib"
+ RC="x86_64-w64-mingw32-windres"
+ ;;
+ *)
+ CC="i686-w64-mingw32-gcc"
+ LD="i686-w64-mingw32-ld"
+ AR="i686-w64-mingw32-ar"
+ RANLIB="i686-w64-mingw32-ranlib"
+ RC="i686-w64-mingw32-windres"
+ ;;
+ esac
+ fi
+
+ else
+ SHLIB_LD="${LINKBIN} -dll ${lflags}"
+ # link -lib only works when -lib is the first arg
+ STLIB_LD="${LINKBIN} -lib ${lflags}"
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+ PATHTYPE=-w
+ # For information on what debugtype is most useful, see:
+ # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+ # and also
+ # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+ # This essentially turns it all on.
+ LDFLAGS_DEBUG="-debug -debugtype:cv"
+ LDFLAGS_OPTIMIZE="-release"
+ if test "$doWince" != "no" ; then
+ LDFLAGS_CONSOLE="-link ${lflags}"
+ LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+ else
+ LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+ LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+ fi
+ fi
+
+ SHLIB_SUFFIX=".dll"
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ AIX-*)
+ if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then :
+
+ # AIX requires the _r compiler when gcc isn't being used
+ case "${CC}" in
+ *_r|*_r\ *)
+ # ok ...
+ ;;
+ *)
+ # Make sure only first arg gets _r
+ CC=`echo "$CC" | sed -e 's/^\([^ ]*\)/\1_r/'`
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5
+$as_echo "Using $CC for compiling with threads" >&6; }
+
+fi
+ LIBS="$LIBS -lc"
+ SHLIB_CFLAGS=""
+ SHLIB_SUFFIX=".so"
+
+ LD_LIBRARY_PATH_VAR="LIBPATH"
+
+ # Check to enable 64-bit flags for compiler/linker
+ if test "$do64bit" = yes; then :
+
+ if test "$GCC" = yes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+
+else
+
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -q64"
+ LDFLAGS_ARCH="-q64"
+ RANLIB="${RANLIB} -X64"
+ AR="${AR} -X64"
+ SHLIB_LD_FLAGS="-b64"
+
+fi
+
+fi
+
+ if test "`uname -m`" = ia64; then :
+
+ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ if test "$GCC" = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+
+else
+
+ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+
+fi
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+
+else
+
+ if test "$GCC" = yes; then :
+
+ SHLIB_LD='${CC} -shared -Wl,-bexpall'
+
+else
+
+ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+ LDFLAGS="$LDFLAGS -brtl"
+
+fi
+ SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+ CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+fi
+ ;;
+ BeOS*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD='${CC} -nostart'
+ SHLIB_SUFFIX=".so"
+
+ #-----------------------------------------------------------
+ # Check for inet_ntoa in -lbind, for BeOS (which also needs
+ # -lsocket, even if the network functions are in -lnet which
+ # is always linked to, for compatibility.
+ #-----------------------------------------------------------
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5
+$as_echo_n "checking for inet_ntoa in -lbind... " >&6; }
+if ${ac_cv_lib_bind_inet_ntoa+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbind $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntoa ();
+int
+main ()
+{
+return inet_ntoa ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_bind_inet_ntoa=yes
+else
+ ac_cv_lib_bind_inet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5
+$as_echo "$ac_cv_lib_bind_inet_ntoa" >&6; }
+if test "x$ac_cv_lib_bind_inet_ntoa" = xyes; then :
+ LIBS="$LIBS -lbind -lsocket"
+fi
+
+ ;;
+ BSD/OS-4.*)
+ SHLIB_CFLAGS="-export-dynamic -fPIC"
+ SHLIB_LD='${CC} -shared'
+ SHLIB_SUFFIX=".so"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ CYGWIN_*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD='${CC} -shared'
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$@.a"
+ SHLIB_SUFFIX=".dll"
+ EXEEXT=".exe"
+ do64bit_ok=yes
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ Haiku*)
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+ SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5
+$as_echo_n "checking for inet_ntoa in -lnetwork... " >&6; }
+if ${ac_cv_lib_network_inet_ntoa+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetwork $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntoa ();
+int
+main ()
+{
+return inet_ntoa ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_network_inet_ntoa=yes
+else
+ ac_cv_lib_network_inet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5
+$as_echo "$ac_cv_lib_network_inet_ntoa" >&6; }
+if test "x$ac_cv_lib_network_inet_ntoa" = xyes; then :
+ LIBS="$LIBS -lnetwork"
+fi
+
+ ;;
+ HP-UX-*.11.*)
+ # Use updated header definitions where possible
+
+$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h
+
+ # TEA specific: Needed by Tcl, but not most extensions
+ #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+ #LIBS="$LIBS -lxnet" # Use the XOPEN network library
+
+ if test "`uname -m`" = ia64; then :
+
+ SHLIB_SUFFIX=".so"
+ # Use newer C++ library for C++ extensions
+ #if test "$GCC" != "yes" ; then
+ # CPPFLAGS="-AA"
+ #fi
+
+else
+
+ SHLIB_SUFFIX=".sl"
+
+fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ tcl_ok=yes
+else
+ tcl_ok=no
+fi
+
+ if test "$tcl_ok" = yes; then :
+
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+ LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+
+fi
+ if test "$GCC" = yes; then :
+
+ SHLIB_LD='${CC} -shared'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+else
+
+ CFLAGS="$CFLAGS -z"
+ # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+ #CFLAGS="$CFLAGS +DAportable"
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+
+fi
+
+ # Check to enable 64-bit flags for compiler/linker
+ if test "$do64bit" = "yes"; then :
+
+ if test "$GCC" = yes; then :
+
+ case `${CC} -dumpmachine` in
+ hppa64*)
+ # 64-bit gcc in use. Fix flags for GNU ld.
+ do64bit_ok=yes
+ SHLIB_LD='${CC} -shared'
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+ ;;
+ esac
+
+else
+
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS +DD64"
+ LDFLAGS_ARCH="+DD64"
+
+fi
+
+fi ;;
+ IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+ if test "$GCC" = yes; then :
+
+ CFLAGS="$CFLAGS -mabi=n32"
+ LDFLAGS="$LDFLAGS -mabi=n32"
+
+else
+
+ case $system in
+ IRIX-6.3)
+ # Use to build 6.2 compatible binaries on 6.3.
+ CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+ ;;
+ *)
+ CFLAGS="$CFLAGS -n32"
+ ;;
+ esac
+ LDFLAGS="$LDFLAGS -n32"
+
+fi
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+
+ # Check to enable 64-bit flags for compiler/linker
+
+ if test "$do64bit" = yes; then :
+
+ if test "$GCC" = yes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
+
+else
+
+ do64bit_ok=yes
+ SHLIB_LD="ld -64 -shared -rdata_shared"
+ CFLAGS="$CFLAGS -64"
+ LDFLAGS_ARCH="-64"
+
+fi
+
+fi
+ ;;
+ Linux*|GNU*|NetBSD-Debian)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+
+ # TEA specific:
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ if test "`uname -m`" = "alpha"; then :
+ CFLAGS="$CFLAGS -mieee"
+fi
+ if test $do64bit = yes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5
+$as_echo_n "checking if compiler accepts -m64 flag... " >&6; }
+if ${tcl_cv_cc_m64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -m64"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_cc_m64=yes
+else
+ tcl_cv_cc_m64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5
+$as_echo "$tcl_cv_cc_m64" >&6; }
+ if test $tcl_cv_cc_m64 = yes; then :
+
+ CFLAGS="$CFLAGS -m64"
+ do64bit_ok=yes
+
+fi
+
+fi
+
+ # The combo of gcc + glibc has a bug related to inlining of
+ # functions like strtod(). The -fno-builtin flag should address
+ # this problem but it does not work. The -fno-inline flag is kind
+ # of overkill but it works. Disable inlining only when one of the
+ # files in compat/*.c is being linked in.
+
+ if test x"${USE_COMPAT}" != x; then :
+ CFLAGS="$CFLAGS -fno-inline"
+fi
+ ;;
+ Lynx*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+ CFLAGS_OPTIMIZE=-02
+ SHLIB_LD='${CC} -shared'
+ LD_FLAGS="-Wl,--export-dynamic"
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+ ;;
+ OpenBSD-*)
+ arch=`arch -s`
+ case "$arch" in
+ vax)
+ SHLIB_SUFFIX=""
+ SHARED_LIB_SUFFIX=""
+ LDFLAGS=""
+ ;;
+ *)
+ case "$arch" in
+ alpha|sparc64)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ *)
+ SHLIB_CFLAGS="-fpic"
+ ;;
+ esac
+ SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+ SHLIB_SUFFIX=".so"
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
+ ;;
+ esac
+ case "$arch" in
+ vax)
+ CFLAGS_OPTIMIZE="-O1"
+ ;;
+ *)
+ CFLAGS_OPTIMIZE="-O2"
+ ;;
+ esac
+ if test "${TCL_THREADS}" = "1"; then :
+
+ # On OpenBSD: Compile with -pthread
+ # Don't link with -lpthread
+ LIBS=`echo $LIBS | sed s/-lpthread//`
+ CFLAGS="$CFLAGS -pthread"
+
+fi
+ # OpenBSD doesn't do version numbers with dots.
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ NetBSD-*)
+ # NetBSD has ELF and can use 'cc -shared' to build shared libs
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+ SHLIB_SUFFIX=".so"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ if test "${TCL_THREADS}" = "1"; then :
+
+ # The -pthread needs to go in the CFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+
+fi
+ ;;
+ FreeBSD-*)
+ # This configuration from FreeBSD Ports.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="${CC} -shared"
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@"
+ SHLIB_SUFFIX=".so"
+ LDFLAGS=""
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+fi
+ if test "${TCL_THREADS}" = "1"; then :
+
+ # The -pthread needs to go in the LDFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
+fi
+ case $system in
+ FreeBSD-3.*)
+ # Version numbers are dot-stripped by system policy.
+ TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ esac
+ ;;
+ Darwin-*)
+ CFLAGS_OPTIMIZE="-Os"
+ SHLIB_CFLAGS="-fno-common"
+ # To avoid discrepancies between what headers configure sees during
+ # preprocessing tests and compiling tests, move any -isysroot and
+ # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+ CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+ if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
+ CFLAGS="`echo " ${CFLAGS}" | \
+ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+ if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
+ if test $do64bit = yes; then :
+
+ case `arch` in
+ ppc)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5
+$as_echo_n "checking if compiler accepts -arch ppc64 flag... " >&6; }
+if ${tcl_cv_cc_arch_ppc64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_cc_arch_ppc64=yes
+else
+ tcl_cv_cc_arch_ppc64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5
+$as_echo "$tcl_cv_cc_arch_ppc64" >&6; }
+ if test $tcl_cv_cc_arch_ppc64 = yes; then :
+
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ do64bit_ok=yes
+
+fi;;
+ i386)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5
+$as_echo_n "checking if compiler accepts -arch x86_64 flag... " >&6; }
+if ${tcl_cv_cc_arch_x86_64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch x86_64"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_cc_arch_x86_64=yes
+else
+ tcl_cv_cc_arch_x86_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS=$hold_cflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5
+$as_echo "$tcl_cv_cc_arch_x86_64" >&6; }
+ if test $tcl_cv_cc_arch_x86_64 = yes; then :
+
+ CFLAGS="$CFLAGS -arch x86_64"
+ do64bit_ok=yes
+
+fi;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+$as_echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
+ esac
+
+else
+
+ # Check for combined 32-bit and 64-bit fat build
+ if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then :
+
+ fat_32_64=yes
+fi
+
+fi
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5
+$as_echo_n "checking if ld accepts -single_module flag... " >&6; }
+if ${tcl_cv_ld_single_module+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+int i;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_ld_single_module=yes
+else
+ tcl_cv_ld_single_module=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5
+$as_echo "$tcl_cv_ld_single_module" >&6; }
+ if test $tcl_cv_ld_single_module = yes; then :
+
+ SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+
+fi
+ # TEA specific: link shlib with current and compatibility version flags
+ vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([0-9]\{1,5\}\)\(\(\.[0-9]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+ SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+ SHLIB_SUFFIX=".dylib"
+ # Don't use -prebind when building for Mac OS X 10.4 or later only:
+ if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then :
+
+ LDFLAGS="$LDFLAGS -prebind"
+fi
+ LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
+$as_echo_n "checking if ld accepts -search_paths_first flag... " >&6; }
+if ${tcl_cv_ld_search_paths_first+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+int i;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_ld_search_paths_first=yes
+else
+ tcl_cv_ld_search_paths_first=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5
+$as_echo "$tcl_cv_ld_search_paths_first" >&6; }
+ if test $tcl_cv_ld_search_paths_first = yes; then :
+
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+
+fi
+ if test "$tcl_cv_cc_visibility_hidden" != yes; then :
+
+
+$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h
+
+ tcl_cv_cc_visibility_hidden=yes
+
+fi
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+ # TEA specific: for combined 32 & 64 bit fat builds of Tk
+ # extensions, verify that 64-bit build is possible.
+ if test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"; then :
+
+ if test "${TEA_WINDOWINGSYSTEM}" = x11; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit X11" >&5
+$as_echo_n "checking for 64-bit X11... " >&6; }
+if ${tcl_cv_lib_x11_64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+ LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_lib_x11_64=yes
+else
+ tcl_cv_lib_x11_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_x11_64" >&5
+$as_echo "$tcl_cv_lib_x11_64" >&6; }
+
+fi
+ if test "${TEA_WINDOWINGSYSTEM}" = aqua; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit Tk" >&5
+$as_echo_n "checking for 64-bit Tk... " >&6; }
+if ${tcl_cv_lib_tk_64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+ LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <tk.h>
+int
+main ()
+{
+Tk_InitStubs(NULL, "", 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_lib_tk_64=yes
+else
+ tcl_cv_lib_tk_64=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_tk_64" >&5
+$as_echo "$tcl_cv_lib_tk_64" >&6; }
+
+fi
+ # remove 64-bit arch flags from CFLAGS et al. if configuration
+ # does not support 64-bit.
+ if test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Removing 64-bit architectures from compiler & linker flags" >&5
+$as_echo "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;}
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+ done
+fi
+
+fi
+ ;;
+ OS/390-*)
+ CFLAGS_OPTIMIZE="" # Optimizer is buggy
+
+$as_echo "#define _OE_SOCKETS 1" >>confdefs.h
+
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ if test "$SHARED_BUILD" = 1; then :
+
+ SHLIB_LD='ld -shared -expect_unresolved "*"'
+
+else
+
+ SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+
+fi
+ SHLIB_SUFFIX=".so"
+ if test $doRpath = yes; then :
+
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
+fi
+ if test "$GCC" = yes; then :
+ CFLAGS="$CFLAGS -mieee"
+else
+
+ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
+fi
+ # see pthread_intro(3) for pthread support on osf1, k.furukawa
+ if test "${TCL_THREADS}" = 1; then :
+
+ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+ CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+ LIBS=`echo $LIBS | sed s/-lpthreads//`
+ if test "$GCC" = yes; then :
+
+ LIBS="$LIBS -lpthread -lmach -lexc"
+
+else
+
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+
+fi
+
+fi
+ ;;
+ QNX-6*)
+ # QNX RTP
+ # This may work for all QNX, but it was only reported for v6.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SCO_SV-3.2*)
+ if test "$GCC" = yes; then :
+
+ SHLIB_CFLAGS="-fPIC -melf"
+ LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+
+else
+
+ SHLIB_CFLAGS="-Kpic -belf"
+ LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+
+fi
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SunOS-5.[0-6])
+ # Careful to not let 5.10+ fall into this case
+
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_SUFFIX=".so"
+ if test "$GCC" = yes; then :
+
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+else
+
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+
+fi
+ ;;
+ SunOS-5*)
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+
+$as_echo "#define _REENTRANT 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+
+ SHLIB_CFLAGS="-KPIC"
+
+ # Check to enable 64-bit flags for compiler/linker
+ if test "$do64bit" = yes; then :
+
+ arch=`isainfo`
+ if test "$arch" = "sparcv9 sparc"; then :
+
+ if test "$GCC" = yes; then :
+
+ if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
+
+else
+
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64 -mcpu=v9"
+ LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+ SHLIB_CFLAGS="-fPIC"
+
+fi
+
+else
+
+ do64bit_ok=yes
+ if test "$do64bitVIS" = yes; then :
+
+ CFLAGS="$CFLAGS -xarch=v9a"
+ LDFLAGS_ARCH="-xarch=v9a"
+
+else
+
+ CFLAGS="$CFLAGS -xarch=v9"
+ LDFLAGS_ARCH="-xarch=v9"
+
+fi
+ # Solaris 64 uses this as well
+ #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+
+fi
+
+else
+ if test "$arch" = "amd64 i386"; then :
+
+ if test "$GCC" = yes; then :
+
+ case $system in
+ SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
+ esac
+
+else
+
+ do64bit_ok=yes
+ case $system in
+ SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ CFLAGS="$CFLAGS -xarch=amd64"
+ LDFLAGS="$LDFLAGS -xarch=amd64";;
+ esac
+
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+fi
+fi
+
+fi
+
+ SHLIB_SUFFIX=".so"
+ if test "$GCC" = yes; then :
+
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ if test "$do64bit_ok" = yes; then :
+
+ if test "$arch" = "sparcv9 sparc"; then :
+
+ # We need to specify -static-libgcc or we need to
+ # add the path to the sparv9 libgcc.
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+ # for finding sparcv9 libgcc, get the regular libgcc
+ # path, remove so name and append 'sparcv9'
+ #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+ #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+
+else
+ if test "$arch" = "amd64 i386"; then :
+
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+
+fi
+fi
+
+fi
+
+else
+
+ case $system in
+ SunOS-5.[1-9][0-9]*)
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+ *)
+ SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+ esac
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+
+fi
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5
+$as_echo_n "checking for ld accepts -Bexport flag... " >&6; }
+if ${tcl_cv_ld_Bexport+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+int i;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ tcl_cv_ld_Bexport=yes
+else
+ tcl_cv_ld_Bexport=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$hold_ldflags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5
+$as_echo "$tcl_cv_ld_Bexport" >&6; }
+ if test $tcl_cv_ld_Bexport = yes; then :
+
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+
+fi
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ esac
+
+ if test "$do64bit" = yes -a "$do64bit_ok" = no; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+$as_echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+
+fi
+
+
+
+ # Add in the arch flags late to ensure it wasn't removed.
+ # Not necessary in TEA, but this is aligned with core
+ LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+ # If we're running gcc, then change the C flags for compiling shared
+ # libraries to the right flags for gcc, instead of those for the
+ # standard manufacturer compiler.
+
+ if test "$GCC" = yes; then :
+
+ case $system in
+ AIX-*) ;;
+ BSD/OS*) ;;
+ CYGWIN_*|MINGW32_*) ;;
+ IRIX*) ;;
+ NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ Darwin-*) ;;
+ SCO_SV-3.2*) ;;
+ windows) ;;
+ *) SHLIB_CFLAGS="-fPIC" ;;
+ esac
+fi
+
+ if test "$tcl_cv_cc_visibility_hidden" != yes; then :
+
+
+$as_echo "#define MODULE_SCOPE extern" >>confdefs.h
+
+
+fi
+
+ if test "$SHARED_LIB_SUFFIX" = ""; then :
+
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+
+fi
+ if test "$UNSHARED_LIB_SUFFIX" = ""; then :
+
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+
+fi
+
+ if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
+$as_echo_n "checking for SEH support in compiler... " >&6; }
+if ${tcl_cv_seh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ tcl_cv_seh=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+ int main(int argc, char** argv) {
+ int a, b = 0;
+ __try {
+ a = 666 / b;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ return 0;
+ }
+ return 1;
+ }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ tcl_cv_seh=yes
+else
+ tcl_cv_seh=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
+$as_echo "$tcl_cv_seh" >&6; }
+ if test "$tcl_cv_seh" = "no" ; then
+
+$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h
+
+ fi
+
+ #
+ # Check to see if the excpt.h include file provided contains the
+ # definition for EXCEPTION_DISPOSITION; if not, which is the case
+ # with Cygwin's version as of 2002-04-10, define it to be int,
+ # sufficient for getting the current code to work.
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
+$as_echo_n "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
+if ${tcl_cv_eh_disposition+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+
+int
+main ()
+{
+
+ EXCEPTION_DISPOSITION x;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_eh_disposition=yes
+else
+ tcl_cv_eh_disposition=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
+$as_echo "$tcl_cv_eh_disposition" >&6; }
+ if test "$tcl_cv_eh_disposition" = "no" ; then
+
+$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h
+
+ fi
+
+ # Check to see if winnt.h defines CHAR, SHORT, and LONG
+ # even if VOID has already been #defined. The win32api
+ # used by mingw and cygwin is known to do this.
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5
+$as_echo_n "checking for winnt.h that ignores VOID define... " >&6; }
+if ${tcl_cv_winnt_ignore_void+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+int
+main ()
+{
+
+ CHAR c;
+ SHORT s;
+ LONG l;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_winnt_ignore_void=yes
+else
+ tcl_cv_winnt_ignore_void=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_winnt_ignore_void" >&5
+$as_echo "$tcl_cv_winnt_ignore_void" >&6; }
+ if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+
+$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h
+
+ fi
+ fi
+
+ # See if the compiler supports casting to a union type.
+ # This is used to stop gcc from printing a compiler
+ # warning when initializing a union member.
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
+$as_echo_n "checking for cast to union support... " >&6; }
+if ${tcl_cv_cast_to_union+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ union foo { int i; double d; };
+ union foo f = (union foo) (int) 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_cast_to_union=yes
+else
+ tcl_cv_cast_to_union=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
+$as_echo "$tcl_cv_cast_to_union" >&6; }
+ if test "$tcl_cv_cast_to_union" = "yes"; then
+
+$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
+
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # These must be called after we do the basic CFLAGS checks and
+ # verify any possible 64-bit or similar switches are necessary
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5
+$as_echo_n "checking for required early compiler flags... " >&6; }
+ tcl_flags=""
+
+ if ${tcl_cv_flag__isoc99_source+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_flag__isoc99_source=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _ISOC99_SOURCE 1
+#include <stdlib.h>
+int
+main ()
+{
+char *p = (char *)strtoll; char *q = (char *)strtoull;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_flag__isoc99_source=yes
+else
+ tcl_cv_flag__isoc99_source=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
+
+$as_echo "#define _ISOC99_SOURCE 1" >>confdefs.h
+
+ tcl_flags="$tcl_flags _ISOC99_SOURCE"
+ fi
+
+
+ if ${tcl_cv_flag__largefile64_source+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_flag__largefile64_source=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGEFILE64_SOURCE 1
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 buf; int i = stat64("/", &buf);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_flag__largefile64_source=yes
+else
+ tcl_cv_flag__largefile64_source=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
+
+$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h
+
+ tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
+ fi
+
+
+ if ${tcl_cv_flag__largefile_source64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_flag__largefile_source64=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGEFILE_SOURCE64 1
+#include <sys/stat.h>
+int
+main ()
+{
+char *p = (char *)open64;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_flag__largefile_source64=yes
+else
+ tcl_cv_flag__largefile_source64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
+
+$as_echo "#define _LARGEFILE_SOURCE64 1" >>confdefs.h
+
+ tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
+ fi
+
+ if test "x${tcl_flags}" = "x" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
+$as_echo "${tcl_flags}" >&6; }
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5
+$as_echo_n "checking for 64-bit integer type... " >&6; }
+ if ${tcl_cv_type_64bit+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ tcl_cv_type_64bit=none
+ # See if the compiler knows natively about __int64
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+__int64 value = (__int64) 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_type_64bit=__int64
+else
+ tcl_type_64bit="long long"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ # See if we should use long anyway Note that we substitute in the
+ # type that is our current guess for a 64-bit type inside this check
+ # program, so it should be modified only carefully...
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+switch (0) {
+ case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+ }
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_type_64bit=${tcl_type_64bit}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test "${tcl_cv_type_64bit}" = none ; then
+
+$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using long" >&5
+$as_echo "using long" >&6; }
+ elif test "${tcl_cv_type_64bit}" = "__int64" \
+ -a "${TEA_PLATFORM}" = "windows" ; then
+ # TEA specific: We actually want to use the default tcl.h checks in
+ # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Tcl header defaults" >&5
+$as_echo "using Tcl header defaults" >&6; }
+ else
+
+cat >>confdefs.h <<_ACEOF
+#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_cv_type_64bit}" >&5
+$as_echo "${tcl_cv_type_64bit}" >&6; }
+
+ # Now check for auxiliary declarations
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5
+$as_echo_n "checking for struct dirent64... " >&6; }
+if ${tcl_cv_struct_dirent64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <dirent.h>
+int
+main ()
+{
+struct dirent64 p;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_struct_dirent64=yes
+else
+ tcl_cv_struct_dirent64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
+$as_echo "$tcl_cv_struct_dirent64" >&6; }
+ if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+
+$as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
+
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
+$as_echo_n "checking for struct stat64... " >&6; }
+if ${tcl_cv_struct_stat64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/stat.h>
+int
+main ()
+{
+struct stat64 p;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_struct_stat64=yes
+else
+ tcl_cv_struct_stat64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5
+$as_echo "$tcl_cv_struct_stat64" >&6; }
+ if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+
+$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h
+
+ fi
+
+ for ac_func in open64 lseek64
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5
+$as_echo_n "checking for off64_t... " >&6; }
+ if ${tcl_cv_type_off64_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+int
+main ()
+{
+off64_t offset;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_type_off64_t=yes
+else
+ tcl_cv_type_off64_t=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+ test "x${ac_cv_func_lseek64}" = "xyes" && \
+ test "x${ac_cv_func_open64}" = "xyes" ; then
+
+$as_echo "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ fi
+
+
+
+$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
+
+$as_echo "#define USE_TK_STUBS 1" >>confdefs.h
+
+
+
+ PRACTCL_TOOLSET="gcc"
+ PRACTCL_VC_MANIFEST_EMBED_DLL=:
+ PRACTCL_VC_MANIFEST_EMBED_EXE=:
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+ PRACTCL_TOOLSET="msvc"
+ PRACTCL_STATIC_LIB="%STLIB_LD% -out:%OUTFILE% %LIBRARY_OBJECTS%"
+ PRACTCL_SHARED_LIB="%SHLIB_LD% %SHLIB_LD_LIBS% %LDFLAGS_DEFAULT% -out:%OUTFILE% %LIBRARY_OBJECTS%"
+ MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "manifest needed" >/dev/null 2>&1; then :
+
+ # Could do a CHECK_PROG for mt, but should always be with MSVC8+
+ PRACTCL_VC_MANIFEST_EMBED_DLL="mt.exe -nologo -manifest %OUTFILE%.manifest -outputresource:%OUTFILE%\;2"
+ PRACTCL_VC_MANIFEST_EMBED_EXE="mt.exe -nologo -manifest %OUTFILE%.manifest -outputresource:%OUTFILE%\;1"
+ VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;2 ; fi"
+ VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;1 ; fi"
+ MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
+
+ CLEANFILES="$CLEANFILES *.manifest"
+
+
+fi
+rm -f conftest*
+
+ PRACTCL_STUB_LIB="%STLIB_LD% -nodefaultlib -out:%OUTFILE% %LIBRARY_OBJECTS%"
+ MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\$@ \$(PKG_STUB_OBJECTS)"
+ else
+ MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+ MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)"
+
+ PRACTCL_STATIC_LIB="%STLIB_LD% %OUTFILE% %LIBRARY_OBJECTS%"
+ PRACTCL_SHARED_LIB="%SHLIB_LD% -o %OUTFILE% %LIBRARY_OBJECTS% %SHLIB_LD_LIBS%"
+ PRACTCL_STUB_LIB="%STLIB_LD% %OUTFILE% %LIBRARY_OBJECTS%"
+ fi
+
+ if test "${SHARED_BUILD}" = "1" ; then
+ MAKE_LIB="${MAKE_SHARED_LIB} "
+ else
+ MAKE_LIB="${MAKE_STATIC_LIB} "
+ fi
+
+ #--------------------------------------------------------------------
+ # Shared libraries and static libraries have different names.
+ # Use the double eval to make sure any variables in the suffix is
+ # substituted. (@@@ Might not be necessary anymore)
+ #--------------------------------------------------------------------
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ PRACTCL_NAME_LIBRARY="%LIBRARY_PREFIX%%LIBRARY_NAME%%LIBRARY_VERSION_NODOTS%"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # We force the unresolved linking of symbols that are really in
+ # the private libraries of Tcl and Tk.
+ if test x"${TK_BIN_DIR}" != x ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+ fi
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+ if test "$GCC" = "yes"; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
+ fi
+ eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+ else
+ eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+ if test "$GCC" = "yes"; then
+ PKG_LIB_FILE=lib${PKG_LIB_FILE}
+ fi
+ fi
+ # Some packages build their own stubs libraries
+ eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+ if test "$GCC" = "yes"; then
+ PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+ fi
+ # These aren't needed on Windows (either MSVC or gcc)
+ RANLIB=:
+ RANLIB_STUB=:
+ else
+ PRACTCL_NAME_LIBRARY="lib%LIBRARY_PREFIX%%LIBRARY_NAME%%LIBRARY_VERSION%"
+ RANLIB_STUB="${RANLIB}"
+ if test "${SHARED_BUILD}" = "1" ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+ if test x"${TK_BIN_DIR}" != x ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+ fi
+ eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+ RANLIB=:
+ else
+ eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+ fi
+ # Some packages build their own stubs libraries
+ eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+ fi
+
+ # Store the raw CFLAGS before we add the trimmings
+ PRACTCL_CFLAGS=${CFLAGS}
+ # These are escaped so that only CFLAGS is picked up at configure time.
+ # The other values will be substituted at make time.
+ CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+ if test "${SHARED_BUILD}" = "1" ; then
+ CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
+$as_echo_n "checking for tclsh... " >&6; }
+
+
+# Check whether --with-tclsh was given.
+if test "${with_tclsh+set}" = set; then :
+ withval=$with_tclsh; with_tclsh=${withval}
+fi
+
+ # Use the value from --with-tclsh, if it was given
+ TCLSH_PROG=0
+ if test x"${with_tclsh}" != x ; then
+ if test -f "${with_tclsh}" ; then
+ TCLSH_PROG=${with_tclsh}
+ else
+ if test -f "${with_tclsh}/tcl8.6" ; then
+ TCLSH_PROG="${with_tclsh}/tcl8.6"
+ else
+ if test -f "${with_tclsh}/tclsh86.exe" ; then
+ TCLSH_PROG="${with_tclsh}/tclsh86.exe"
+ else
+ as_fn_error $? "${with_tclsh} does not point to a valid Tcl executable" "$LINENO" 5
+ fi
+ fi
+ fi
+ else
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ # tclConfig.sh is in Tcl build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" ; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+ elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}" ; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}"
+ elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}" ; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}"
+ elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}" ; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}"
+ fi
+ else
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+ fi
+ else
+ # tclConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+ else
+ TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+ fi
+ list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${TCLSH_PROG}" ; then
+ REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+ fi
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${TCLSH_PROG}" >&5
+$as_echo "${TCLSH_PROG}" >&6; }
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wish" >&5
+$as_echo_n "checking for wish... " >&6; }
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ # tkConfig.sh is in Tk build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" ; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}s${EXEEXT}" ; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}$s{EXEEXT}"
+ elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}" ; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}"
+ elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}" ; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}"
+ fi
+ else
+ WISH_PROG="${TK_BIN_DIR}/wish"
+ fi
+ else
+ # tkConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ else
+ WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+ fi
+ list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${WISH_PROG}" ; then
+ REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${WISH_PROG}" >&5
+$as_echo "${WISH_PROG}" >&6; }
+
+
+
+
+ac_config_files="$ac_config_files Makefile generic/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by TclMagick $as_me 0.46, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+TclMagick config.status 0.46
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "generic/Makefile") CONFIG_FILES="$CONFIG_FILES generic/Makefile" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ if test x"$xsi_shell" = xyes; then
+ sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\ case ${1} in\
+\ */*) func_dirname_result="${1%/*}${2}" ;;\
+\ * ) func_dirname_result="${3}" ;;\
+\ esac\
+\ func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\ # positional parameters, so assign one to ordinary parameter first.\
+\ func_stripname_result=${3}\
+\ func_stripname_result=${func_stripname_result#"${1}"}\
+\ func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\ func_split_long_opt_name=${1%%=*}\
+\ func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\ func_split_short_opt_arg=${1#??}\
+\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\ case ${1} in\
+\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\ *) func_lo2o_result=${1} ;;\
+\ esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+ func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+ func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+ func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+ eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\ func_quote_for_eval "${2}"\
+\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/TclMagick/configure.ac b/TclMagick/configure.ac
new file mode 100644
index 0000000..fa5bfb2
--- /dev/null
+++ b/TclMagick/configure.ac
@@ -0,0 +1,120 @@
+#!/bin/bash -norc
+dnl This file is an input file used by the GNU "autoconf" program to
+dnl generate the file "configure", which is run during Tcl installation
+dnl to configure the system for the local environment.
+#
+AC_INIT(TclMagick, 0.46)
+
+# Specify directory where m4 macros may be found.
+AC_CONFIG_MACRO_DIR([unix/m4])
+
+# Directory where autotools helper scripts lives.
+AC_CONFIG_AUX_DIR([unix/config])
+
+AM_INIT_AUTOMAKE
+
+# Add configure option --enable-maintainer-mode which enables dependency
+# checking and generation useful to package maintainers. This is made an
+# option to avoid confusing end users.
+AM_MAINTAINER_MODE
+
+# Enable support for silent build rules
+AM_SILENT_RULES
+
+AC_PROG_CC
+AC_PROG_LIBTOOL
+AC_ISC_POSIX
+AC_HEADER_STDC([])
+
+
+dnl Allow the user to specify the GraphicsMagick or ImageMagick config
+dnl script to use.
+AC_ARG_WITH(magick, [ --with-magick location of Graphics/MagickWand-config script], with_magick=${withval})
+
+dnl First check to see if --with-magick-config was specified.
+GM_CPPFLAGS=''
+GM_LDFLAGS=''
+GM_LIBS=''
+wand_config=''
+if test x"${with_magick}" != x
+then
+ if test -x "${with_magick}"
+ then
+ wand_config=${with_magick}
+ else
+ AC_MSG_ERROR([${with_magick} is not an executable file])
+ fi
+fi
+if test x"${wand_config}" = x
+then
+ AC_PATH_PROGS(wand_config,[GraphicsMagickWand-config MagickWand-config],,)
+fi
+if test x"${wand_config}" = x
+then
+ AC_MSG_ERROR([Please specify the Graphics/ImageMagick-config script with --with-magick!])
+fi
+
+dnl It actually calls another script, so the PATH needs to be set.
+PATH=$PATH:`dirname ${wand_config}`
+export PATH
+AC_MSG_CHECKING([for Graphics/ImageMagick Wand configuration script])
+AC_MSG_RESULT(${wand_config})
+GM_CPPFLAGS=`${wand_config} --cppflags`
+AC_SUBST(GM_CPPFLAGS)
+GM_LDFLAGS=`${wand_config} --ldflags`
+AC_SUBST(GM_LDFLAGS)
+GM_LIBS=`${wand_config} --libs`
+AC_SUBST(GM_LIBS)
+
+CPPFLAGS_SAVE=$CPPFLAGS
+LDFLAGS_SAVE=$LDFLAGS
+LIBS_SAVE=$LIBS
+CPPFLAGS="$CPPFLAGS $GM_CPPFLAGS"
+LDFLAGS="$LDFLAGS $GM_LDFLAGS"
+LIBS="$GM_LIBS $LIBS"
+AC_CHECK_FUNCS([MagickSetImageFormat])
+CPPFLAGS=$CPPFLAGS_SAVE
+LDFLAGS=$LDFLAGS_SAVE
+LIBS=$LIBS_SAVE
+
+TEA_INIT([3.10])
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+TEA_PATH_TKCONFIG
+TEA_LOAD_TKCONFIG
+
+TEA_PREFIX
+
+TEA_SETUP_COMPILER
+
+TEA_ADD_HEADERS([])
+TEA_ADD_INCLUDES([])
+TEA_ADD_LIBS([])
+TEA_ADD_CFLAGS([])
+TEA_ADD_STUB_SOURCES([])
+TEA_ADD_TCL_SOURCES([])
+
+TEA_PUBLIC_TCL_HEADERS
+TEA_PUBLIC_TK_HEADERS
+
+TEA_ENABLE_THREADS
+
+TEA_ENABLE_SHARED
+
+TEA_CONFIG_CFLAGS
+
+AC_DEFINE(USE_TCL_STUBS)
+AC_DEFINE(USE_TK_STUBS)
+
+TEA_MAKE_LIB
+
+TEA_PROG_TCLSH
+TEA_PROG_WISH
+
+
+AC_OUTPUT([
+Makefile
+generic/Makefile
+])
diff --git a/TclMagick/debian/README.Debian b/TclMagick/debian/README.Debian
new file mode 100644
index 0000000..a958b65
--- /dev/null
+++ b/TclMagick/debian/README.Debian
@@ -0,0 +1,24 @@
+tclmagick for Debian
+--------------------
+
+If, at some point in the future, GraphicsMagick were to be packaged,
+this could depend on that instead.
+
+ -- David N. Welton <davidw@debian.org>, Sun Sep 19 20:45:49 2004
+
+How to build and test a Debian package
+--------------------------------------
+
+Build the package:
+
+ dpkg-buildpackage -us -uc -b -rfakeroot
+ sudo dpkg -i ~/usrc/tclmagick_0.45-1_i386.deb
+
+Test the package:
+
+ cd ~/usrc/TclMagick/tests/
+ tclsh test-bmp-compare.tcl
+ tclsh test-draw.tcl
+ tclsh test-pixel.tcl
+ tclsh test-wand.tcl
+ tclsh tkmagick.tcl
diff --git a/TclMagick/debian/changelog b/TclMagick/debian/changelog
new file mode 100644
index 0000000..b32b77f
--- /dev/null
+++ b/TclMagick/debian/changelog
@@ -0,0 +1,39 @@
+tclmagick (0.45-1) unstable; urgency=low
+
+ * New upstream version.
+ * tclmagick_0.44-1(hppa/unstable): FTBFS: cannot find install-sh
+
+ -- David N. Welton <davidw@debian.org> Sat, 22 Jan 2005 22:31:58 +0100
+
+tclmagick (0.44-2) unstable; urgency=low
+
+ * Use release tarball to generate .deb with.
+
+ -- David N. Welton <davidw@debian.org> Sat, 22 Jan 2005 12:15:49 +0100
+
+tclmagick (0.44-1) unstable; urgency=low
+
+ * New version.
+
+ -- David N. Welton <davidw@debian.org> Mon, 17 Jan 2005 23:08:03 +0100
+
+tclmagick (0.42-1.1) unstable; urgency=low
+
+ * NMU
+ * Add dependency on tk8.4-dev (Closes: #274668)
+ * Remove NEWS file from package, it's empty.
+
+ -- Baruch Even <baruch@debian.org> Tue, 4 Jan 2005 01:08:19 +0000
+
+tclmagick (0.42-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- David N. Welton <davidw@debian.org> Tue, 21 Sep 2004 11:09:38 +0200
+
+tclmagick (0.41-1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- David N. Welton <davidw@debian.org> Sun, 19 Sep 2004 20:31:33 +0200
+
diff --git a/TclMagick/debian/compat b/TclMagick/debian/compat
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/TclMagick/debian/compat
@@ -0,0 +1 @@
+4
diff --git a/TclMagick/debian/control b/TclMagick/debian/control
new file mode 100644
index 0000000..672f0ea
--- /dev/null
+++ b/TclMagick/debian/control
@@ -0,0 +1,15 @@
+Source: tclmagick
+Section: graphics
+Priority: optional
+Maintainer: David N. Welton <davidw@debian.org>
+Build-Depends: debhelper (>= 4.0.0), fakeroot, libmagick9-dev, tcl8.4-dev, tk8.4-dev
+Standards-Version: 3.6.0
+
+Package: tclmagick
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Tcl bindings for ImageMagick
+ TclMagick is a Tcl extension that works with both the GraphicsMagick
+ and ImageMagick image manipulation libraries. TkMagick is a small,
+ simple extension that lets you pass images back and forth between Tk
+ and the TclMagick extension.
diff --git a/TclMagick/debian/copyright b/TclMagick/debian/copyright
new file mode 100644
index 0000000..3ca8c40
--- /dev/null
+++ b/TclMagick/debian/copyright
@@ -0,0 +1,49 @@
+This package was debianized by David N. Welton <davidw@debian.org> on
+Sun, 19 Sep 2004 20:31:33 +0200.
+
+It was downloaded from http://tclmagick.sf.net
+
+Upstream Authors: Rolf Schrdter <Rolf.Schroedter@dlr.de>, David
+Welton <davidw@dedasys.com>
+
+Copyright:
+
+This software is copyrighted 2004 by Rolf Schrdter
+<Rolf.Schroedter@dlr.de> and David N. Welton <davidw@dedasys.com>. The
+following terms apply to all files associated with the software unless
+explicitly disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+GOVERNMENT USE: If you are acquiring this software on behalf of the
+U.S. government, the Government shall have only "Restricted Rights"
+in the software and related documentation as defined in the Federal
+Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+are acquiring the software on behalf of the Department of Defense, the
+software shall be classified as "Commercial Computer Software" and the
+Government shall have only "Restricted Rights" as defined in Clause
+252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
+authors grant the U.S. Government and others acting in its behalf
+permission to use and distribute the software in accordance with the
+terms specified in this license.
diff --git a/TclMagick/debian/dirs b/TclMagick/debian/dirs
new file mode 100644
index 0000000..ca882bb
--- /dev/null
+++ b/TclMagick/debian/dirs
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
diff --git a/TclMagick/debian/docs b/TclMagick/debian/docs
new file mode 100644
index 0000000..e845566
--- /dev/null
+++ b/TclMagick/debian/docs
@@ -0,0 +1 @@
+README
diff --git a/TclMagick/debian/rules b/TclMagick/debian/rules
new file mode 100755
index 0000000..8492073
--- /dev/null
+++ b/TclMagick/debian/rules
@@ -0,0 +1,110 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+#
+# Tcl version. Using 8.4 but 8.5 already available
+#
+TCLVERSION=8.4
+
+#
+# GraphicsMagick/ImageMagick Wand library selection.
+
+# GraphicsMagick
+#WAND=GraphicsMagickWand
+
+# ImageMagick
+WAND=Wand
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+ INSTALL_PROGRAM += -s
+endif
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # Add here commands to configure the package.
+
+ ./configure --with-tcl=/usr/lib/tcl${TCLVERSION}/ --with-tk=/usr/lib/tk${TCLVERSION}/ --with-magick=/usr/bin/${WAND}-config --enable-threads --with-tclinclude=/usr/include/tcl${TCLVERSION}/ --with-tkinclude=/usr/include/tcl${TCLVERSION}/
+ touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp
+ dh_testdir
+
+ # Add here commands to compile the package.
+ $(MAKE)
+ #/usr/bin/docbook-to-man debian/tclmagick.sgml > tclmagick.1
+
+ touch build-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+
+ # Add here commands to clean up after the build process.
+ -$(MAKE) clean
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/tclmagick.
+ $(MAKE) install DESTDIR=$(CURDIR)/debian/tclmagick
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs ChangeLog
+ dh_installdocs doc/*
+ dh_installexamples
+# dh_install
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+# dh_perl
+# dh_python
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/TclMagick/doc/TclMagick.html b/TclMagick/doc/TclMagick.html
new file mode 100644
index 0000000..e48d04b
--- /dev/null
+++ b/TclMagick/doc/TclMagick.html
@@ -0,0 +1,4002 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+ <head>
+ <title>TclMagick</title>
+ <meta http-equiv="Content-Type" content="text/html;
+ charset=iso-8859-1">
+ <link rel="stylesheet" href="style.css">
+ <!-- $Id$ -->
+ </head>
+
+ <body>
+
+ <table>
+ <tbody>
+ <tr>
+ <td style="background-color: #ff6666; padding: 1ex; font-weight: bold;"><a href="index.html">Main</a></td>
+ <td style="background-color: #66ff66; padding: 1ex; font-weight: bold;"><a href="TclMagick.html">TclMagick</a></td>
+ <td style="background-color: #6666ff; padding: 1ex; font-weight: bold;"><a href="TkMagick.html">TkMagick</a></td>
+ <td width="100%"></td>
+ <td>
+ <a href="http://sourceforge.net/projects/tclmagick">
+ <img src="http://sourceforge.net/sflogo.php?group_id=96922&amp;type=2" width="125" height="37" border="0"
+ alt="SourceForge.net Logo"></a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+
+ <h2>A Tcl interface to ImageMagick & GraphicsMagick</h2>
+ <p>
+ TclMagick is a Tcl wrapper for ImageMagick's high-level Wand
+ interface. It lets you convert and manipulate a large variety
+ of image formats, and importantly, does not require the Tk
+ toolkit or an active windowing system!
+ </p>
+ <p>
+ There is also a <a href="TkMagick.html">TkMagick</a> module, which exists to bridge
+ TclMagick and Tk. It lets you use make Tk images from data
+ loaded with TclMagick, and vice versa.
+ </p>
+ <p>
+ <a href="http://www.imagemagick.org"
+ target="http://www.imagemagick.org">http://www.imagemagick.org</a><br>
+ <a href="http://www.graphicsmagick.org"
+ target="http://www.graphicsmagick.org">http://www.graphicsmagick.org</a>
+ </p>
+ <p>
+ TclMagick doesn't add any intelligence to ImageMagick, except
+ some Tclification with optional command arguments. The wrapping
+ of ImageMagick's Wand-API should be mostly obvious, so there is
+ no need for extensive, separate TclMagick documentation. For a
+ more detailed description of methods refer to the <a
+ href="http://www.imagemagick.org/www/api.html"
+ target="http://www.imagemagick.org/www/api.html">Wand-API
+ documentation</a>.
+ </p>
+ <p>
+ There are three different ImageMagick object types: MagickWand,
+ DrawingWand and PixelWand. In TclMagick these objects are
+ called <i>wand</i>, <i>drawing</i> and <i>pixel</i>. They are
+ created and deleted with the <i>magick</i> command similar to
+ Tcl's <i>image</i>command. Wand-API methods are then called as
+ subcommands of the created TclMagick object.<br>
+
+ If an ImageMagick-API allows a NULL object argument, it can be
+ specified as an empty string {} or "".
+ </p>
+ <h2>General design:</h2>
+
+ <p>
+ There is one main command: <b>magick</b> - Create/delete Magick
+ &quot;wand&quot;, &quot;drawing&quot;, and &quot;pixel&quot;
+ objects
+ </p>
+ <p>
+ Creating a Magick object creates a command of the same name:
+ <code><i>magickName</i> subcmd ?args?</code>
+ </p>
+ <p>
+ Deleting the Magick object also deletes the associated command.
+ </p>
+ </pre>
+ <h2>"magick" command</h2>
+ <table width="669" border="1">
+ <tr>
+ <th colspan="2" scope="col"><div align="left">magick subcmd ?args?</div></th>
+ </tr>
+ <tr>
+ <td scope="col"><div align="left">magick create type ?name?</div></td>
+ <td width="278" scope="col"><div align="left"># Create a TclMagick object of type</div></td>
+ </tr>
+ <tr>
+ <td width="305"><div align="left">
+ <ul>
+ <li>type=&quot;wand&quot;, &quot;drawing&quot;, &quot;pixel&quot;</li>
+ <li>returns: object name</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div> <div align="left">magick delete name ?name? ... </div></td>
+ <td><div align="left"># Delete TclMagick objects</div></td>
+ </tr>
+ <tr>
+ <td>magick names ?type?</td>
+ <td># Return all TclMagick objects (of type)</td>
+ </tr>
+ <tr>
+ <td>magick type name</td>
+ <td># Return the type of the object</td>
+ </tr>
+ <tr>
+ <td>magick types</td>
+ <td># Return valid type names</td>
+ </tr>
+ <tr>
+ <td>magick resourcelimit resource ?limit?</td>
+ <td>MagickGet/SetResourceLimits</td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>resource=&quot;undefined&quot;, &quot;area&quot;, &quot;disk&quot;, &quot;file&quot;, &quot;map&quot;, &quot;memory&quot;</li>
+ <li>unsigned limit</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">magick fonts ?pattern? <br>
+ </div></td>
+ <td><div align="left">MagickQueryFonts</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string pattern (default="*")</li>
+ <li>returns stringList (all matching fonts)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">magick formats ?pattern? <br>
+ </div></td>
+ <td><div align="left">MagickQueryFormats</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string pattern (default="*")</li>
+ <li>returns stringList (all matching image formats)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td>magick library<br>
+ magick library -copyright<br>
+ magick library -date<br>
+ magick library -maxrgb<br>
+ magick library -name<br>
+ magick library -quantumdepth<br>
+ magick library -url<br>
+ magick library -version<br>
+ magick library -versionstr</td>
+ <td># Returns all options <br>
+ MagickGetCopyright<br>
+ MagickGetReleaseDate<br>
+ MagickGetQuantumDepth<br>
+ MagickGetPackageName<br>
+ MagickGetQuantumDepth<br>
+ MagickGetHomeURL<br>
+ MagickGetVersion<br>
+ MagickGetVersion</td>
+ </tr>
+ <tr>
+ <td><ul>
+ <li>Without -option the return is a list of all -option value ... pairs</li>
+ <li> -quantumdepth returns an integer</li>
+ <li>-version returns a string like &quot;5.5.8&quot;</li>
+ <li>-versionstr returns the complete MagickGetVersion()</li>
+ <li>all others return a string </li>
+ </ul></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>magick version </td>
+ <td><p># Return TclMagick version</p> </td>
+ </tr>
+ <tr>
+ <td><ul>
+ <li>return string version </li>
+ </ul></td>
+ <td>&nbsp;</td>
+ </tr>
+ </table>
+ <h2>MagickWand object subcommands </h2>
+ <table width="800" border="1">
+ <tr>
+ <th scope="col"><div align="left"></div> <div align="left">
+ <div align="left"></div>
+ <div align="left">wandName subcmd ?args?</div>
+ </div></th>
+ <th width="246" scope="col"><div align="left">ImageMagick API </div></th>
+ </tr>
+ <tr>
+ <td><div align="left"></div> <div align="left">wandName adaptivethreshold ?width? ?height? ?ofs?<br>
+ wandName AdaptiveThresholdImage ?width? ?height? ?ofs? <br>
+ </div></td>
+ <td><div align="left">MagickAdaptiveThresholdImage<br>
+ MagickAdaptiveThresholdImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td width="538"><div align="left">
+ <ul>
+ <li>integer width,height,ofs<br>
+ (default: width=2, height=width, ofs=0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div> <div align="left">wandName add wandName <br>
+ wandName AddImage wandName <br>
+ </div></td>
+ <td><div align="left">MagickAddImage<br>
+ MagickAddImage <br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>MagickWand wandName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div> <div align="left">wandName addnoise ?noiseType? <br>
+ wandName AddNoiseImage ?noiseType? <br>
+ </div></td>
+ <td><div align="left">MagickAddNoiseImage<br>
+ MagickAddNoiseImage </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string noiseType
+ = &quot;uniform&quot;, &quot;gaussian&quot;, &quot;multiplicativegaussian&quot;, &quot;impulse&quot;, &quot;laplacian&quot;, &quot;poisson&quot;<br>
+ (default: noisetype=&quot;uniform&quot;)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div> <div align="left">wandName affinetransform draw <br>
+ wandName AffineTransformImage draw <br>
+ </div></td>
+ <td><div align="left">MagickAffineTransformImage<br>
+ MagickAffineTransformImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>DrawingWand draw</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName annotate draw ?x y? ?angle? text<br>
+ wandName AnnotateImage draw ?x y? ?angle? text<br>
+ </div></td>
+ <td><div align="left">MagickAnnotateImage<br>
+ MagickAnnotateImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>DrawingWand draw</li>
+ <li>double x, y (default=0.0)</li>
+ <li>double angle (default=0.0) </li>
+ <li>string text </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div> <div align="left">wandName append ?stack? ?newName? <br>
+ wandName AppendImages ?stack? ?newName? <br>
+ </div></td>
+ <td><div align="left">MagickAppendImages<br>
+ MagickAppendImages </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>bool stack (default=0)</li>
+ <li> string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div> <div align="left">wandName average ?newName? <br>
+ wandName AverageImages ?newName? <br>
+ </div></td>
+ <td><div align="left">MagickAverageImages<br>
+ MagickAverageImages <br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName blackthreshold thresholdPixel <br>
+ wandName BlackThresholdImage thresholdPixel<br>
+ </div></td>
+ <td><div align="left">MagickBlackThresholdImage<br>
+ MagickBlackThresholdImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand thresholdPixel</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName blur ?radius? ?sigma? <br>
+ wandName BlurImage ?radius? ?sigma?<br>
+ </div></td>
+ <td><div align="left">MagickBlurImage<br>
+ MagickBlurImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius,sigma<br>
+ (default: radius=0.0, sigma=1.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName border borderPixel ?width? ?height? <br>
+ wandName BorderImage borderPixel ?width? ?height?<br>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand borderPixel</li>
+ <li>integer width,height<br>
+ (default: width=1, height=width)</li>
+ </ul>
+ </div></td>
+ <td><div align="left">MagickBorderImage<br>
+ MagickBorderImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName charcoal ?radius? ?sigma? <br>
+ wandName CharcoalImage ?radius? ?sigma? <br>
+ </div></td>
+ <td><div align="left">MagickCharcoalImage<br>
+ MagickCharcoalImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius,sigma (default: radius=0.0, sigma=1.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName chop width height ?x y? <br>
+ wandName ChopImage width height ?x y? <br>
+ </div></td>
+ <td><div align="left">MagickChopImage<br>
+ MagickChopImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>integer width,height,x,y (default: x=y=0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"><br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName clip <br>
+ wandName ClipImage <br>
+ </div></td>
+ <td><div align="left">MagickClipImage<br>
+ MagickClipImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName clippath pathname ?inside? <br>
+ wandName ClipPathImage pathname ?inside?<br>
+ </div></td>
+ <td><div align="left">MagickClipPathImage<br>
+ MagickClipPathImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string pathname</li>
+ <li>bool inside (default=0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName clone ?newName? <br>
+ wandName CloneWand ?newName? <br>
+ </div></td>
+ <td><div align="left">CloneMagickWand<br>
+ CloneMagickWand<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName coalesce ?newName? <br>
+ wandName CoalesceImages ?newName?<br>
+ </div></td>
+ <td><div align="left">MagickCoalesceImages<br>
+ MagickCoalesceImages<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul><li>string newNam</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName colorfloodfill fillPix ?fuzz? ?borderPix? ?x y? <br>
+ wandName ColorFloodfillImage fillPix ?fuzz? ?borderPix? ?x y?<br>
+ </div></td>
+ <td><div align="left">MagickColorFloodfillImage<br>
+ MagickColorFloodfillImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand fillPix,borderPix
+ (default: borderPix=""=>NULL)</li>
+ <li>double fuzz (default=0.0)</li>
+ <li>integer x,y
+ (default: x=y=0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName colorize fillPix opacityPix <br>
+ wandName ColorizeImage fillPix opacityPix<br>
+ </div></td>
+ <td><div align="left">MagickColorizeImage<br>
+ MagickColorizeImage<br>
+ <br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand fillPix,opacityPix</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName comment str <br>
+ wandName CommentImage str<br>
+ </div></td>
+ <td><div align="left">MagickCommentImage<br>
+ MagickCommentImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string str</li>
+ </ul>
+
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName compare refName <br>
+ wandName CompareImages refName metric <br>
+ </div></td>
+ <td><div align="left">MagickCompareImages<br>
+ MagickCompareImages<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>MagickWand refName</li>
+ <li> string metricType =<br>
+ &quot;meanabsoluteerror&quot;, &quot;meansquarederror&quot;, &quot;peakabsoluteerror&quot;, &quot;peaksignaltonoiseratio&quot;, &quot;rootmeansquarederror&quot;</li>
+ <li> returns double distortion </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName comparechannels refName chan metric <br>
+ wandName CompareImageChannels refName chan metric<br>
+ </div></td>
+ <td><div align="left">MagickCompareImageChannels<br>
+ MagickCompareImageChannels<br>
+ <br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>MagickWand refName</li>
+ <li>string channelType = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;, &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ <li> string metricType =&quot;meanabsoluteerror&quot;, &quot;meansquarederror&quot;, &quot;peakabsoluteerror&quot;, &quot;peaksignaltonoiseratio&quot;, &quot;rootmeansquarederror&quot;</li>
+ <li> returns double distortion</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName composite compWand opType ?x y? <br>
+ wandName CompositeImage compWand opType ?x y?<br>
+ </div></td>
+ <td><div align="left">MagickCompositeImage<br>
+ MagickCompositeImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string opType
+ = &quot;undefined&quot;, &quot;over&quot;, &quot;in&quot;, &quot;out&quot;, &quot;atop&quot;, &quot;xor&quot;, &quot;plus&quot;, &quot;minus&quot;, &quot;add&quot;, &quot;subtract&quot;, &quot;difference&quot;, &quot;multiply&quot;, &quot;bumpmap&quot;, &quot;copy&quot;, &quot;copyred&quot;, &quot;copygreen&quot;, &quot;copyblue&quot;, &quot;copyopacity&quot;, &quot;clear&quot;, &quot;dissolve&quot;, &quot;displace&quot;, &quot;modulate&quot;, &quot;threshold&quot;, &quot;no&quot;, &quot;darken&quot;, &quot;lighten&quot;, &quot;hue&quot;, &quot;saturate&quot;, &quot;colorize&quot;, &quot;luminize&quot;, &quot;screen&quot;, &quot;overlay&quot;, &quot;copycyan&quot;, &quot;copymagenta&quot;, &quot;copyyellow&quot;, &quot;copyblack&quot;, &quot;replace&quot;</li>
+ <li>MagickWand compWand</li>
+ <li>integer x,y (default: x=y=0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName contrast ?sharpen? <br>
+ wandName ContrastImage ?sharpen? <br>
+ </div></td>
+ <td><div align="left">MagickContrastImage<br>
+ MagickContrastImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul><li>bool sharpen
+ (default: sharpen=yes)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName convolve order kernelData <br>
+ wandName ConvolveImage order kernelData <br>
+ </div></td>
+ <td><div align="left">MagickConvolveImage<br>
+ MagickConvolveImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>integer order=odd</li>
+ <li> kernelData = list of doubles with (order x order) elements</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName crop width height ?x y? <br>
+ wandName CropImage width height ?x y?<br>
+ </div></td>
+ <td><div align="left">MagickCropImage<br>
+ MagickCropImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>integer width,height,x,y
+ (default: x=y=0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName cyclecolormap ?displace? <br>
+ wandName CycleColormapImage ?displace? <br>
+ </div></td>
+ <td><div align="left">MagickCycleColormapImage<br>
+ MagickCycleColormapImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>integer displace
+ (default: displace=1)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName deconstruct ?newName? <br>
+ wandName DeconstructImages ?newName?<br>
+ </div></td>
+ <td><div align="left">MagickDeconstructImages<br>
+ MagickDeconstructImages<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName describe <br>
+ wandName DescribeImage<br>
+ </div></td>
+ <td><div align="left">MagickDescribeImage<br>
+ MagickDescribeImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName despeckle <br>
+ wandName DespeckleImage <br>
+ </div></td>
+ <td><div align="left">MagickDespeckleImage<br>
+ MagickDespeckleImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName draw draw <br>
+ wandName DrawImage draw<br>
+ </div></td>
+ <td><div align="left">MagickDrawImage<br>
+ MagickDrawImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>DrawingWand draw</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName edge ?radius? <br>
+ wandName EdgeImage ?radius?<br>
+ </div></td>
+ <td><div align="left">MagickEdgeImage<br>
+ MagickEdgeImage<br>
+ <br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius (default: radius=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName emboss ?radius? ?sigma? <br>
+ wandName EmbossImage ?radius? ?sigma?<br>
+ </div></td>
+ <td><div align="left">MagickEmbossImage<br>
+ MagickEmbossImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius,sigma (default: radius=0.0, sigma=1.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName enhance <br>
+ wandName EnhanceImage<br>
+ </div></td>
+ <td><div align="left">MagickEnhanceImage<br>
+ MagickEnhanceImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName equalize <br>
+ wandName EqualizeImage <br>
+ </div></td>
+ <td><div align="left">MagickEqualizeImage<br>
+ MagickEqualizeImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName flatten ?newName? <br>
+ wandName FlattenImages ?newName?<br>
+ </div></td>
+ <td><div align="left">MagickFlattenImages<br>
+ MagickFlattenImages<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName flip <br>
+ wandName FlipImage<br>
+ </div></td>
+ <td><div align="left">MagickFlipImage<br>
+ MagickFlipImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName flop <br>
+ wandName FlopImage <br>
+ </div></td>
+ <td><div align="left">MagickFlopImage<br>
+ MagickFlopImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName frame framePix ?width? ?height? ?inner? ?outer? <br>
+ wandName FrameImage framePix ?width? ?height? ?inner? ?outer?<br>
+ </div> </td>
+ <td><div align="left">MagickFrameImage<br>
+ MagickFrameImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand framePix</li>
+ <li> integer witdh,height,innerBevel,outerBevel<br>
+ (default: width=1, height=width, inner=0, outer=inner)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandname fx expr ?newName?<br>
+ wandname fxImage expr ?newName?<br>
+ </div></td>
+ <td><div align="left">MagickFxImage<br>
+ MagickFxImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li> string expr</li>
+ <li> string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandname fxchannel channelType expr ?newName?<br>
+ wandname fxImageChannel channelType expr ?newName?<br>
+ </div></td>
+ <td><div align="left">MagickFxImageChannel<br>
+ MagickFxImageChannel<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string channelType = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;, &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ <li> string expr</li>
+ <li> string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName gamma level <br>
+ wandName GammaImage level<br>
+ </div></td>
+ <td><div align="left">MagickGammaImage<br>
+ MagickGammaImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double level</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName gammachannel channelType level <br>
+ wandName GammaImageChannel channelType level<br>
+ </div></td>
+ <td><div align="left">MagickGammaImageChannel<br>
+ MagickGammaImageChannel<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string channelType
+ = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;, &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ <li>double level</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName filename ?name? <br>
+ wandName GetFilename <br>
+ wandName SetFilename name<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetFilename<br>
+ MagickGetFilename<br>
+ MagickSetFilename<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string name</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName backgroundcolor ?pixel? <br>
+ wandName GetBackgroundColor ?pixel?<br>
+ wandName SetBackgroundColor pixel <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetBackgroundColor<br>
+ MagickGetImageBackgroundColor<br>
+ MagickSetImageBackgroundColor<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand pixel</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName blueprimary ?x y? <br>
+ wandName GetBluePrimary <br>
+ wandName SetBluePrimary x y<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetBluePrimary<br>
+ MagickGetBluePrimary<br>
+ MagickSetBluePrimary<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName bordercolor ?pixel? <br>
+ wandName GetBorderColor ?pixel? <br>
+ wandName SetBorderColor pixel <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetBorderColor<br>
+ MagickGetImageBorderColor<br>
+ MagickSetImageBorderColor<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand pixel</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName channeldepth channelType depth <br>
+ wandName GetChannelDepth channelType <br>
+ wandName SetChannelDepth channelType depth<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageChannelDepth<br>
+ MagickGetImageChannelDepth<br>
+ MagickSetImageChannelDepth<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string channelType
+ = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;, &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ <li> int depth </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName channelextrema channelType <br>
+ wandName GetChannelExtrema channelType<br>
+ </div></td>
+ <td><div align="left">MagickGetImageChannelExtrema<br>
+ MagickGetImageChannelExtrema<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li> string channelType
+ = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;, &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ <li> returns intList {min max} </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName channelmean channelType <br>
+ wandName GetChannelMean channelType<br>
+ </div></td>
+ <td><div align="left">MagickGetImageChannelMean<br>
+ MagickGetImageChannelMean<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string channelType
+ = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;, &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ <li>returns doubleList {mean deviation}</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName colormapcolor index ?pixel? <br>
+ wandName GetColormapColor index ?pixel?<br>
+ wandName SetColormapColor index pixel <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetColormapColor<br>
+ MagickGetImageColormapColor<br>
+ MagickSetImageColormapColor<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int index</li>
+ <li> PixelWand pixel</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName colors <br>
+ wandName GetColors<br>
+ </div></td>
+ <td><div align="left">MagickGetImageColors<br>
+ MagickGetImageColors<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns int numColors</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName colorspace ?colorspaceType?<br>
+ wandName GetColorspace <br>
+ wandName SetColorspace colorspaceType<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageColorspace<br>
+ MagickGetImageColorspace<br>
+ MagickSetImageColorspace<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string colorspaceType (default=&quot;RGB&quot;) =&quot;undefined&quot;, &quot;RGB&quot;, &quot;GRAY&quot;, &quot;transparent&quot;, &quot;OHTA&quot;, &quot;LAB&quot;, &quot;XYZ&quot;, &quot;YCbCr&quot;, &quot;YCC&quot;, &quot;YIQ&quot;, &quot;YPbPr&quot;, &quot;YUV&quot;, &quot;CMYK&quot;, &quot;sRGB&quot;, &quot;HSL&quot;, &quot;HWB&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName compose ?opType?<br>
+ wandName GetCompose <br>
+ wandName SetCompose opType<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageCompose<br>
+ MagickGetImageCompose<br>
+ MagickSetImageCompose<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string opType
+ = &quot;undefined&quot;, &quot;over&quot;, &quot;in&quot;, &quot;out&quot;, &quot;atop&quot;, &quot;xor&quot;, &quot;plus&quot;, &quot;minus&quot;, &quot;add&quot;, &quot;subtract&quot;, &quot;difference&quot;, &quot;multiply&quot;, &quot;bumpmap&quot;, &quot;copy&quot;, &quot;copyred&quot;, &quot;copygreen&quot;, &quot;copyblue&quot;, &quot;copyopacity&quot;, &quot;clear&quot;, &quot;dissolve&quot;, &quot;displace&quot;, &quot;modulate&quot;, &quot;threshold&quot;, &quot;no&quot;, &quot;darken&quot;, &quot;lighten&quot;, &quot;hue&quot;, &quot;saturate&quot;, &quot;colorize&quot;, &quot;luminize&quot;, &quot;screen&quot;, &quot;overlay&quot;, &quot;copycyan&quot;, &quot;copymagenta&quot;, &quot;copyyellow&quot;, &quot;copyblack&quot;, &quot;replace&quot;
+ </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName compression ?compressType?<br>
+ wandName GetCompression <br>
+ wandName SetCompression compressType<br>
+ </div></td>
+ <td><div align="left"> MagickGet/SetImageCompression<br>
+ MagickGetImageCompression<br>
+ MagickSetImageCompression<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string compressType =&quot;undefined&quot;, &quot;none&quot;, &quot;bzip&quot;, &quot;fax&quot;, &quot;group4&quot;, &quot;jpeg&quot;, &quot;jpeg-ls&quot;, &quot;lzw&quot;, &quot;rle&quot;, &quot;zip&quot;
+ </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName delay ?delay? <br>
+ wandName GetDelay <br>
+ wandName SetDelay delay <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageDelay<br>
+ MagickGetImageDelay<br>
+ MagickSetImageDelay<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int delay (1/100 sec)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName depth ?depth? <br>
+ wandName GetDepth <br>
+ wandName SetDepth depth <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageDepth<br>
+ MagickGetImageDepth<br>
+ MagickSetImageDepth<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int depth (bits)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName dispose ?disposeType? <br>
+ wandName GetDispose <br>
+ wandName SetDispose disposeType <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageDispose<br>
+ MagickGetImageDispose<br>
+ MagickSetImageDispose<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string disposeType = &quot;undefined&quot;, &quot;none&quot;, &quot;background&quot;, &quot;previous&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName extrema <br>
+ wandName GetExtrema <br>
+ </div></td>
+ <td><div align="left"> MagickGetImageExtrema<br>
+ MagickGetImageExtrema<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns intList {min max}</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName format <br>
+ wandName GetFormat <br>
+ </div></td>
+ <td><div align="left">MagickGetImageFormat<br>
+ MagickGetImageFormat<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns string format</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName gamma ?gamma? <br>
+ wandName GetGamma <br>
+ wandName SetGamma gamma<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageGamma<br>
+ MagickGetImageGamma<br>
+ MagickSetImageGamma<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double gamma</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName greenprimary ?x y? <br>
+ wandName GetGreenPrimary <br>
+ wandName SetGreenPrimary x y<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetGreenPrimary<br>
+ MagickGetGreenPrimary<br>
+ MagickSetGreenPrimary<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName heigth <br>
+ wandName GetHeight <br>
+ </div></td>
+ <td><div align="left">MagickGetImageHeight<br>
+ MagickGetImageHeight<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns int height</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName index ?index? <br>
+ wandName GetIndex <br>
+ wandName SetIndex index <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageIndex<br>
+ MagickGetImageIndex<br>
+ MagickSetImageIndex<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int index</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName interlace ?interlaceType? <br>
+ wandName GetInterlaceScheme <br>
+ wandName SetInterlaceScheme interlaceType<br>
+ </div></td>
+ <td><div align="left"> MagickGet/SetImageInterlaceScheme<br>
+ MagickGetImageInterlaceScheme<br>
+ MagickSetImageInterlaceScheme<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string interlaceType = &quot;undefined&quot;, &quot;none&quot;, &quot;line&quot;, &quot;plane&quot;, &quot;partition&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName iterations ?num?<br>
+ wandName GetIterations <br>
+ wandName SetIterations num<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageIterations<br>
+ MagickGetImageIterations<br>
+ MagickSetImageIterations<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int num</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName mattecolor ?pixel? <br>
+ wandName GetMatteColor ?pixel? <br>
+ wandName SetMatteColor pixel <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetMatteColor<br>
+ MagickGetImageMatteColor<br>
+ MagickSetImageMatteColor<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand pixel</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>wandName getimage ?newName?<br>
+ wandName GetImage ?newName?<br>
+ wandName setimage name<br>
+ wandName SetImage name</p>
+ </div></td>
+ <td><div align="left">
+ <p>MagickGetImage<br>
+ MagickGetImage<br>
+ MagickSetImage<br>
+ MagickSetImage </p>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string newName</li>
+ <li>MagickWand name</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName imagefilename ?name? <br>
+ wandName GetImageFilename <br>
+ wandName SetImageFilename name<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageFilename<br>
+ MagickGetImageFilename<br>
+ MagickSetImageFilename<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string name</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName pixels x0 y0 cols rows map storageType ?data? <br>
+ wandName GetPixels x0 .. storageType <br>
+ wandName SetPixels x0 .. storageType data <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImagePixels<br>
+ MagickGetImagePixels<br>
+ MagickSetImagePixels<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>storageType =&quot;char&quot;, &quot;short&quot;, &quot;integer&quot;, &quot;long&quot;, &quot;float&quot;, &quot;double&quot;
+ </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName ProfileImage name ?profile?<br>
+ wandName RemoveProfile name <br>
+ </div></td>
+ <td><div align="left">MagickProfileImage<br>
+ MagickRemoveImageProfile<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string name=&quot;*&quot;,&quot;icc&quot;,&quot;icm&quot;,&quot;cptc&quot;,&quot;8bim&quot;,genericProfiles</li>
+ <li> binary profile</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName profile name ?profile? <br>
+ wandName GetProfile name <br>
+ wandName SetProfile name profile<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageProfile<br>
+ MagickGetImageProfile<br>
+ MagickSetImageProfile<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string name=&quot;*&quot;,&quot;icc&quot;,&quot;icm&quot;,&quot;cptc&quot;,&quot;8bim&quot;,genericProfiles</li>
+ <li> binary profile</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName redprimary ?x y? <br>
+ wandName GetRedPrimary <br>
+ wandName SetRedPrimary x y<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetRedPrimary<br>
+ MagickGetRedPrimary<br>
+ MagickSetRedPrimary<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName rendering ?renderType? <br>
+ wandName GetRenderingIntent <br>
+ wandName SetRenderingIntent renderType<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageRenderingIntent<br>
+ MagickGetImageRenderingIntent<br>
+ MagickSetImageRenderingIntent<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string renderType = &quot;undefined&quot;, &quot;saturation&quot;, &quot;perceptual&quot;, &quot;absolute&quot;, &quot;relative&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName resolution ?x? ?y? <br>
+ wandName GetResolution <br>
+ wandName SetResolution x ?y?<br>
+ </div></td>
+ <td><div align="left">MagickSetImageResolution<br>
+ MagickGetImageResolution<br>
+ MagickSetImageResolution<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x,y (default y=x)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName scene ?num?<br>
+ wandName GetScene <br>
+ wandName SetScene num<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageScene<br>
+ MagickGetImageScene<br>
+ MagickSetImageScene<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int num</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName imagesize<br>
+ wandName GetImageSize </div></td>
+ <td><div align="left">
+ <p>MagickGetImageSize<br>
+ MagickGetImageSize<br>
+ </p>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns wideInt size</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName signature <br>
+ wandName GetSignature<br>
+ </div></td>
+ <td><div align="left">MagickGetImageSignature<br>
+ MagickGetImageSignature<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns string signature</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName imagetype ?type?<br>
+ wandName GetImageType <br>
+ wandName SetImageType type<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageType<br>
+ MagickGetImageType<br>
+ MagickSetImageType<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string type =&quot;undefined&quot;,&quot;bilevel&quot;,&quot;grayscale&quot;,<br>
+ &quot;grayscalematte&quot;,&quot;palette&quot;,&quot;palettematte&quot;,<br>
+ &quot;truecolor&quot;,&quot;truecolormatte&quot;,&quot;colorseparation&quot;,<br>
+ &quot;colorseparationmatte&quot;,&quot;optimize&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName imageunits ?unitType? <br>
+ wandName GetImageUnits <br>
+ wandName SetImageUnits unitType<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageUnits<br>
+ MagickGetImageUnits<br>
+ MagickSetImageUnits<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string unitType = &quot;undefined&quot;, &quot;ppi&quot;, &quot;ppcm&quot;,</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName virtualpixelmethod ?methodType?<br>
+ wandName GetVirtualPixelMethod <br>
+ wandName SetVirtualPixelMethod methodType<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetImageVirtualPixelMethod<br>
+ MagickGetImageVirtualPixelMethod<br>
+ MagickSetImageVirtualPixelMethod<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string methodType =&quot;undefined&quot;, &quot;constant&quot;, &quot;edge&quot;,
+ &quot;mirror&quot;, &quot;tile&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName whitepoint ?x y? <br>
+ wandName GetWhitePoint <br>
+ wandName SetWhitePoint x y <br>
+ </div></td>
+ <td><div align="left">MagickGet/SetWhitePoint<br>
+ MagickGetWhitePoint<br>
+ MagickSetWhitePoint<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName width <br>
+ wandName GetWidth<br>
+ </div></td>
+ <td><div align="left">MagickGetImageWidth<br>
+ MagickGetImageWidth<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns int width</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName number <br>
+ wandName GetNumberImages <br>
+ </div></td>
+ <td><div align="left">MagickGetNumberImages<br>
+ MagickGetNumberImages</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns int number </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName samplingfactors ?factors? <br>
+ wandName GetSamplingFactors <br>
+ wandName SetSamplingFactors factors<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetSamplingFactors<br>
+ MagickGetSamplingFactors<br>
+ MagickSetSamplingFactors<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>doubleList factors</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName size ?x y? <br>
+ wandName GetSize <br>
+ wandName SetSize x y<br>
+ </div></td>
+ <td><div align="left">MagickGet/SetSize<br>
+ MagickGetSize<br>
+ MagickSetSize<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int x,y</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName hasnext <br>
+ wandName HasNextImage<br>
+ </div></td>
+ <td><div align="left">MagickHasNextImage<br>
+ MagickHasNextImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns boolean </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName hasprevious <br>
+ wandName HasPreviousImage<br>
+ </div></td>
+ <td><div align="left">MagickHasPreviousImage<br>
+ MagickHasPreviousImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>returns boolean </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName implode ?amount? <br>
+ wandName ImplodeImage ?amount?<br>
+ </div></td>
+ <td><div align="left">MagickImplodeImage<br>
+ MagickImplodeImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double amount (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName label str <br>
+ wandName LabelImage str<br>
+ </div></td>
+ <td><div align="left">MagickLabelImage<br>
+ MagickLabelImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string str</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName level ?black? ?gamma? ?white? <br>
+ wandName LevelImage ?black? ?gamma? ?white?<br>
+ </div></td>
+ <td><div align="left">MagickLevelImage<br>
+ MagickLevelImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double black,gamma,white<br>
+ (default: black=0.0, gama=1.0, white=MaxRGB)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName levelchannel channelType ?black? ?gamma? ?white? <br>
+ wandName LevelImageChannel channelType ?black? ?gamma? ?white?<br>
+ </div></td>
+ <td><div align="left"> MagickLevelImageChannel<br>
+ MagickLevelImageChannel</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string channelType
+ = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;,
+ &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ <li> double black,gamma,white<br>
+ (default: black=0.0, gama=1.0, white=MaxRGB)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName magnify <br>
+ wandName MagnifyImage<br>
+ </div></td>
+ <td><div align="left">MagnifyImage<br>
+ MagnifyImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName map mapName ?dither? <br>
+ wandName MapImage mapName ?dither?<br>
+ </div></td>
+ <td><div align="left">MagickMapImage<br>
+ MagickMapImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>MagickWand mapName</li>
+ <li>bool dither (default=no)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName mattefloodfill opacity ?fuzz? ?borderPix? ?x y? <br>
+ wandName MatteFloodfillImage opacity ?fuzz? ?borderPix? ?x y?<br>
+ </div></td>
+ <td><div align="left">MagickMatteFloodfillImage<br>
+ MagickMatteFloodfillImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int opacity</li>
+ <li> double fuzz (default=0.0)</li>
+ <li> PixelWand borderPix
+ (default: borderPix=none)</li>
+ <li> integer x,y
+ (default: x=y=0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName medianfilter ?radius? <br>
+ wandName MedianFilterImage ?radius?<br>
+ </div></td>
+ <td><div align="left">MagickMedianFilterImage<br>
+ MagickMedianFilterImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius
+ (default: radius=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName minify <br>
+ wandName MinifyImage <br>
+ </div></td>
+ <td><div align="left">MagickMinifyImage<br>
+ MagickMinifyImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName modulate ?brightness? ?saturation? ?hue? <br>
+ wandName ModulateImage ?brightness? ?saturation? ?hue?<br>
+ </div></td>
+ <td><div align="left">MagickModulateImage<br>
+ MagickModulateImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double brightness,saturation,hue (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName montage draw tileGeom thumbGeom mode frameGeom ?newName? <br>
+ wandName MontageImage draw tileGeom thumbGeom mode frameGeom ?newName?<br>
+ </div></td>
+ <td><div align="left">MagickMontageImage<br>
+ MagickMontageImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>DrawingWand draw</li>
+ <li> string tileGeom, thumbGeom, frameGeom</li>
+ <li> string mode
+ = &quot;frame&quot;, &quot;unframe&quot;, &quot;concatenate&quot;
+ </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName morph num ?newName? <br>
+ wandName MorphImages num ?newName?<br>
+ </div></td>
+ <td><div align="left"> MagickMorphImages<br>
+ MagickMorphImages
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li> integer num</li>
+ <li> string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName mosaic ?newName? <br>
+ wandName MosaicImages ?newName?<br>
+ </div></td>
+ <td><div align="left">MagickMosaicImages<br>
+ MagickMosaicImages</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName motionblur ?radius? ?sigma? ?angle? <br>
+ wandName MotionBlurImage ?radius? ?sigma? ?angle?<br>
+ </div></td>
+ <td><div align="left">MagickMotionBlurImage<br>
+ MagickMotionBlurImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius,sigma,angle (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName negate ?gray? <br>
+ wandName NegateImage ?gray?<br>
+ </div></td>
+ <td><div align="left">MagickNegateImage<br>
+ MagickNegateImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>bool gray (default=no)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName next ?offset? <br>
+ wandName NextImage ?offset?<br>
+ </div></td>
+ <td><div align="left">MagickNextImage<br>
+ MagickNextImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int offset (default = 1)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName normalize <br>
+ wandName NormalizeImage <br>
+ </div></td>
+ <td><div align="left">MagickNormalizeImage<br>
+ MagickNormalizeImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName oilpaint ?radius? <br>
+ wandName OilPaintImage ?radius?<br>
+ </div></td>
+ <td><div align="left">MagickOilPaintImage<br>
+ MagickOilPaintImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius
+ (default: radius=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName opaque targetPix fillPix ?fuzz? <br>
+ wandName OpaqueImage targetPix fillPix ?fuzz?<br>
+ </div></td>
+ <td><div align="left">MagickOpaqueImage<br>
+ MagickOpaqueImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand targetPix,fillPix</li>
+ <li> double fuzz (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName ping filename <br>
+ wandName PingImage filename <br>
+ </div></td>
+ <td><div align="left">MagickPingImage<br>
+ MagickPingImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string filename</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName preview previewType ?newName? <br>
+ wandName PreviewImages previewType ?newName?<br>
+ </div></td>
+ <td><div align="left"> MagickPreviewImages<br>
+ MagickPreviewImages</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li> integer previewType =&quot;undefined&quot;, &quot;rotate&quot;, &quot;shear&quot;, &quot;roll&quot;,
+ &quot;hue&quot;, &quot;saturation&quot;, &quot;brightness&quot;, &quot;gamma&quot;,
+ &quot;spiff&quot;, &quot;dull&quot;, &quot;grayscale&quot;, &quot;quantize&quot;,
+ &quot;despeckle&quot;, &quot;reducenoise&quot;, &quot;addnoise&quot;, &quot;sharpen&quot;,
+ &quot;blur&quot;, &quot;threshold&quot;, &quot;edgedetect&quot;, &quot;spread&quot;,<br>
+ &quot;solarize&quot;, &quot;shade&quot;, &quot;raise&quot;, &quot;segment&quot;,
+ &quot;swirl&quot;, &quot;implode&quot;, &quot;wave&quot;, &quot;oilpaint&quot;,<br>
+ &quot;charcoal&quot;, &quot;jpeg&quot;,</li>
+ <li>string newName </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName previous ?offset? <br>
+ wandName PreviousImage ?offset?<br>
+ </div></td>
+ <td><div align="left">MagickPreviousImage<br>
+ MagickPreviousImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int offset (default = 1) </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName quantize numColors ?colorspaceType? ?treedepth? ?dither? ?measureError?<br>
+ wandName QuantizeImage numColors colorspaceType treedepth dither measureError<br>
+ wandName QuantizeImages numColors colorspaceType treedepth dither measureError<br>
+ </div>
+ <div align="left"></div></td>
+ <td><div align="left">MagickQuantizeImage<br>
+ MagickQuantizeImage<br>
+ MagickQuantizeImages </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int numColors</li>
+ <li> string colorspaceType (default=&quot;RGB&quot;) =&quot;undefined&quot;,&quot;RGB&quot;,&quot;GRAY&quot;,&quot;transparent&quot;,&quot;OHTA&quot;,
+ &quot;LAB&quot;,&quot;XYZ&quot;,&quot;YCbCr&quot;,&quot;YCC&quot;,&quot;YIQ&quot;,&quot;YPbPr&quot;,&quot;YUV&quot;,
+ &quot;CMYK&quot;,&quot;sRGB&quot;,&quot;HSL&quot;,&quot;HWB&quot;</li>
+ <li>int treedepth</li>
+ <li> bool dither, measureError (default=no) </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName queryfontmetrics draw text<br>
+ wandName QueryFontMetrics draw text<br>
+ </div></td>
+ <td><div align="left">MagickQueryFontMetrics<br>
+ MagickQueryFontMetrics</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li> DrawingWand draw</li>
+ <li> string text</li>
+ <li> returns intList(7)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName raise width height ?x y? ?raise? <br>
+ wandName RaiseImage width height ?x y? ?raise?</div></td>
+ <td><div align="left">MagickRaiseImage<br>
+ MagickRaiseImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int width,height</li>
+ <li> int x,y (default=0)</li>
+ <li> bool raise (default=no)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName read filename <br>
+ wandName ReadImage filename </div></td>
+ <td><div align="left">MagickReadImage<br>
+ MagickReadImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string filename</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName readblob data <br>
+ wandName ReadImageBlob data</div></td>
+ <td><div align="left">MagickReadImageBlob<br>
+ MagickReadImageBlob</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>binary data</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName reducenoise ?radius? <br>
+ wandName ReduceNoiseImage ?radius?</div></td>
+ <td><div align="left">MagickReduceNoiseImage<br>
+ MagickReduceNoiseImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius
+ (default: radius=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName remove <br>
+ wandName RemoveImage</div></td>
+ <td><div align="left">MagickRemoveImage<br>
+ MagickRemoveImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName resetiterator <br>
+ wandName ResetIterator </div></td>
+ <td><div align="left">MagickResetIterator<br>
+ MagickResetIterator<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName resample xRes ?yRes? ?filterType? ?blur? <br>
+ wandName ResampleImage xRes ?yRes? ?filterType? ?blur?</div></td>
+ <td><div align="left">MagickResampleImage<br>
+ MagickResampleImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double xRes, yRes, blur (default: yRes=xRes, blur=0.0)</li>
+ <li> filter = &quot;undefined&quot;, &quot;point&quot;, &quot;box&quot;, &quot;triangle&quot;, &quot;hermite&quot;,
+ &quot;hanning&quot;, &quot;hamming&quot;, &quot;blackman&quot;, &quot;gaussian&quot;, &quot;quadratic&quot;,
+ &quot;cubic&quot;, &quot;catrom&quot;, &quot;mitchell&quot;, &quot;lanczos&quot;, &quot;bessel&quot;,
+ &quot;sinc&quot;
+ (default=&quot;undefined&quot;)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName resize x y ?filterType? ?blur? <br>
+ wandName ResizeImage x y ?filterType? ?blur?</div></td>
+ <td><div align="left">MagickResizeImage<br>
+ MagickResizeImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int x, y </li>
+ <li> filter = &quot;undefined&quot;, &quot;point&quot;, &quot;box&quot;, &quot;triangle&quot;, &quot;hermite&quot;,<br>
+ &quot;hanning&quot;, &quot;hamming&quot;, &quot;blackman&quot;, &quot;gaussian&quot;, &quot;quadratic&quot;,<br>
+ &quot;cubic&quot;, &quot;catrom&quot;, &quot;mitchell&quot;, &quot;lanczos&quot;, &quot;bessel&quot;,<br>
+ &quot;sinc&quot;
+ (default=&quot;undefined&quot;)</li>
+ <li>double blur (default =0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName roll xOfs yOfs <br>
+ wandName RollImage xOfs yOfs</div></td>
+ <td><div align="left"> MagickRollImage<br>
+ MagickRollImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int xOfs,yOfs</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName rotate background degrees <br>
+ wandName RotateImage background degrees</div></td>
+ <td><div align="left">MagickRotateImage<br>
+ MagickRotateImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand background</li>
+ <li>double degrees </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName sample x y <br>
+ wandName SampleImage x y</div></td>
+ <td><div align="left">MagickSampleImage<br>
+ MagickSampleImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int x,y</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div>
+ <div align="left">wandName separate channelType <br>
+ wandName SeparateImageChannel channelType<br>
+ </div></td>
+ <td><div align="left">MagickSeparateImageChannel<br>
+ MagickSeparateImageChannel<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul><li>string channelType
+ = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;, &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName scale x y <br>
+ wandName ScaleImage x y</div></td>
+ <td><div align="left">MagickScaleImage<br>
+ MagickScaleImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int x,y</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName setoption format key value<br>
+ wandName SetOption format key value</div></td>
+ <td><div align="left">MagickSetImageOption<br>
+ MagickSetImageOption</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string format, key, value</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName passphrase phrase <br>
+ wandName SetPassphrase phrase</div></td>
+ <td><div align="left">MagickSetPassphrase<br>
+ MagickSetPassphrase</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string phrase</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName sharpen ?radius? ?sigma? <br>
+ wandName SharpenImage ?radius? ?sigma?
+ </div></td>
+ <td><div align="left">MagickSharpenImage<br>
+ MagickSharpenImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius,sigma
+ (default: radius=0.0, sigma=1.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName shave x y <br>
+ wandName ShaveImage x y</div></td>
+ <td><div align="left">MagickShaveImage<br>
+ MagickShaveImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int x,y</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName shear background xShear ?yShear? <br>
+ wandName ShearImage background xShear ?yShear?</div></td>
+ <td><div align="left">MagickShearImage<br>
+ MagickShearImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand borderPixel</li>
+ <li> double xShear, yShear (default: yShear=xShear)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName solarize ?threshold? <br>
+ wandName SolarizeImage ?threshold?</div></td>
+ <td><div align="left">MagickSolarizeImage<br>
+ MagickSolarizeImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double threshold (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName spread ?radius? <br>
+ wandName SpreadImage ?radius?</div></td>
+ <td><div align="left">MagickSpreadImage<br>
+ MagickSpreadImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName stegano watermark ?offset? ?newName? <br>
+ wandName SteganoImage watermark ?offset? ?newName?</div></td>
+ <td><div align="left">MagickSteganoImage<br>
+ MagickSteganoImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>MagickWand watermark</li>
+ <li> int offset (default=0)</li>
+ <li> string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName stereo anotherWand ?newName? <br>
+ wandName StereoImage anotherWand ?newName?</div></td>
+ <td><div align="left">MagickStereoImage<br>
+ MagickStereoImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>MagickWand anotherWand</li>
+ <li> string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName strip <br>
+ wandName StripImage</div></td>
+ <td><div align="left">MagickStripImage<br>
+ MagickStripImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"> wandName swirl ?degrees? <br>
+ wandName SwirlImage ?degrees? </div></td>
+ <td><div align="left">MagickSwirlImage<br>
+ MagickSwirlImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double degrees (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName texture textWand ?newName? <br>
+ wandName TextureImage textWand ?newName?</div></td>
+ <td><div align="left">MagickTextureImage<br>
+ MagickTextureImage<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>MagickWand textWand</li>
+ <li> string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName threshold threshold <br>
+ wandName ThresholdImage threshold</div></td>
+ <td><div align="left">MagickThresholdImage<br>
+ MagickThresholdImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double threshold</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName thresholdchannel channelType threshold <br>
+ wandName ThresholdImageChannel channelType threshold</div></td>
+ <td><div align="left">MagickThresholdImageChannel<br>
+ MagickThresholdImageChannel</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string channelType
+ = &quot;undefined&quot;, &quot;red&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;,
+ &quot;blue&quot;, &quot;yellow, &quot;opacity, &quot;black, &quot;matte&quot;, &quot;index&quot;</li>
+ <li> double threshold</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName tint tintPixel opacityPixel <br>
+ wandName TintImage tintPixel opacityPixel<br>
+ </div></td>
+ <td><div align="left">MagickTintImage<br>
+ MagickTintImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand tintPixel, opacityPixel</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName transform crop geometry ?newName? <br>
+ wandName TransformImage crop geometry ?newName?</div></td>
+ <td><div align="left">MagickTransformImage<br>
+ MagickTransformImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string crop, geometry</li>
+ <li> string newName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName transparent targetPix ?opacity? ?fuzz? <br>
+ wandName TransparentImage targetPix ?opacity? ?fuzz?</div></td>
+ <td><div align="left">MagickTransparentImage<br>
+ MagickTransparentImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand targetPix</li>
+ <li> int opacity (default=0)</li>
+ <li> double fuzz (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName trim ?fuzz? <br>
+ wandName TrimImage ?fuzz?</div></td>
+ <td><div align="left">MagickTrimImage<br>
+ MagickTrimImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double fuzz (default=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName unsharpmask ?radius? ?sigma? ?amount? ?threshold? <br>
+ wandName UnsharpMaskImage ?radius? ?sigma? ?amount? ?threshold?</div></td>
+ <td><div align="left">MagickUnsharpMaskImage<br>
+ MagickUnsharpMaskImage </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double radius,sigma,amount,threshold<br>
+ (default: radius=0.0,sigma=1.0,amount=0.0,threshold=0.0)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName wave amplitude wavelength <br>
+ wandName WaveImage amplitude wavelength</div></td>
+ <td><div align="left">MagickWaveImage<br>
+ MagickWaveImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double amplitude,wavelength</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName whitethreshold thresholdPixel <br>
+ wandName WhiteThresholdImage thresholdPixel</div></td>
+ <td><div align="left">MagickWhiteThresholdImage<br>
+ MagickWhiteThresholdImage</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>PixelWand thresholdPixel</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">wandName write filename <br>
+ wandName WriteImage filename <br>
+ wandName WriteImages filename ?adjoin?</div></td>
+ <td><div align="left">
+ <p>MagickWriteImage<br>
+ MagickWriteImage<br>
+ MagickWriteImages</p>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string filename</li>
+ <li> bool adjoin (default=no)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ </table>
+
+ <p>&nbsp;</p>
+ <table width="798" border="1">
+ <tr>
+ <th width="312" scope="col"><div align="left">Not implemented MagickWand API's</div></th>
+ <th width="428" scope="col"><div align="left">Comment</div></th>
+ </tr>
+ <tr>
+ <td><div align="left">MagickAnimateImages</div></td>
+ <td><div align="left">Image display, depends on X</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">MagickDisplayImage</div></td>
+ <td><div align="left">Image display, depends on X</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">MagickDisplayImages</div></td>
+ <td><div align="left">Image display, depends on X</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">MagickGetImageHistogram</div></td>
+ <td><div align="left">Creates &amp; Returns array of PixelWand objects, how to implement ???</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">MagickReadImageFile</div></td>
+ <td><div align="left">Could be implemented via TclChannel</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">MagickWriteImageFile</div></td>
+ <td><div align="left">Could be implemented via TclChannel</div></td>
+ </tr>
+ </table>
+ <h2>PixelWand object subcommands</h2>
+ <table width="800" border="1">
+ <tr>
+ <th scope="col"><div align="left"></div>
+ <div align="left">
+ <div align="left"></div>
+ <div align="left">pixelName subcmd ?args?</div>
+ </div></th>
+ <th scope="col"><div align="left">ImageMagick API </div></th>
+ </tr>
+ <tr>
+ <td scope="col"><div align="left">pixelName set ?-quant? color val color val ...<br>
+ pixelName get ?-quant? color color ... <br>
+ </div></td>
+ <td scope="col"><div align="left">PixelSetXXX<br>
+ PixelGetXXX</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>color = &quot;black&quot;, &quot;blue&quot;, &quot;cyan&quot;, &quot;green&quot;, &quot;magenta&quot;, &quot;opacity&quot;, &quot;red&quot;, &quot;yellow&quot; </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName color <br>
+ pixelName color string <br>
+ pixelName GetColor <br>
+ pixelName SetColor string <br>
+ pixelName GetColorAsString
+ </div></td>
+ <td><div align="left">PixelGetColorAsString<br>
+ PixelSetColor <br>
+ PixelGetColorAsString<br>
+ PixelSetColor<br>
+ PixelGetColorAsString
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string string </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName GetBlack<br>
+ pixelName GetBlackQuantum<br>
+ pixelName SetBlack val<br>
+ pixelName SetBlackQuantum val </div></td>
+ <td><div align="left">PixelGetBlack<br>
+ PixelGetBlackQuantum<br>
+ PixelSetBlack<br>
+ PixelSetBlackQuantum </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName GetBlue<br>
+ pixelName GetBlueQuantum<br>
+ pixelName SetBlue val<br>
+ pixelName SetBlueQuantum val
+ </div></td>
+ <td><div align="left">PixelGetBlue<br>
+ PixelGetBlueQuantum<br>
+ PixelSetBlue<br>
+ PixelSetBlueQuantum
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName GetCyan<br>
+ pixelName GetCyanQuantum<br>
+ pixelName SetCyan val<br>
+ pixelName SetCyanQuantum val </div></td>
+ <td><div align="left">PixelGetCyan<br>
+ PixelGetCyanQuantum<br>
+ PixelSetCyan<br>
+ PixelSetCyanQuantum </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName GetGreen<br>
+ pixelName GetGreenQuantum<br>
+ pixelName SetGreen val<br>
+ pixelName SetGreenQuantum val </div></td>
+ <td><div align="left">PixelGetGreen<br>
+ PixelGetGreenQuantum<br>
+ PixelSetGreen<br>
+ PixelSetGreenQuantum </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName GetMagenta<br>
+ pixelName GetMagentaQuantum<br>
+ pixelName SetMagenta val<br>
+ pixelName SetMagentaQuantum val </div></td>
+ <td><div align="left">PixelGetMagenta<br>
+ PixelGetMagentaQuantum<br>
+ PixelSetMagenta<br>
+ PixelSetMagentaQuantum </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName GetOpacity<br>
+ pixelName GetOpacityQuantum<br>
+ pixelName SetOpacity val<br>
+ pixelName SetOpacityQuantum val </div></td>
+ <td><div align="left">PixelGetOpacity<br>
+ PixelGetOpacityQuantum<br>
+ PixelSetOpacity<br>
+ PixelSetOpacityQuantum </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName GetRed<br>
+ pixelName GetRedQuantum<br>
+ pixelName SetRed val<br>
+ pixelName SetRedQuantum val </div></td>
+ <td><div align="left">PixelGetRed<br>
+ PixelGetRedQuantum<br>
+ PixelSetRed<br>
+ PixelSetRedQuantum </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName GetYellow<br>
+ pixelName GetYellowQuantum<br>
+ pixelName SetYellow val<br>
+ pixelName SetYellowQuantum val </div></td>
+ <td><div align="left">PixelGetYellow<br>
+ PixelGetYellowQuantum<br>
+ PixelSetYellow<br>
+ PixelSetYellowQuantum </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">pixelName colorcount ?cnt? <br>
+ pixelName GetColorCount<br>
+ pixelName SetColorCount ?cnt?</div></td>
+ <td><div align="left">
+ <p>PixelGet/SetColorCount<br>
+ PixelGetColorCount<br>
+ PixelSetColorCount
+ </p>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>unsigned cnt </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left"></div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ </table>
+ <h2>DrawingWand object subcommands </h2>
+ <table width="829" border="1">
+ <tr>
+ <th width="442" scope="col"><div align="left">drawName subcmd ?args?</div></th>
+ <th width="329" scope="col"><div align="left">ImageMagick API </div></th>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName affine sx rx ry sy tx ty<br>
+ drawName Affine sx rx ry sy tx ty</p>
+ </div></td>
+ <td><div align="left">DrawAffine<br>
+ DrawAffine<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double sx, rx, ry, sy, tx, ty </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName annotation x y text <br>
+ drawName Annotation x y text <br>
+ </p>
+ </div></td>
+ <td><div align="left">DrawAnnotation<br>
+ DrawAnnotation</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y</li>
+ <li>string text </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName arc sx sy ex ey sd ed<br>
+ drawName Arc sx sy ex ey sd ed</p>
+ </div></td>
+ <td><div align="left">DrawArc<br>
+ DrawArc</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double arc, sx, sy, ex. ey. sd, ed </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName bezier x y x y ...<br>
+ drawName Bezier x y x y ...</p>
+ </div></td>
+ <td><div align="left">DrawBezier<br>
+ DrawBezier</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName circle ox oy px py<br>
+ drawName Circle ox oy px py<br>
+ </p>
+ </div></td>
+ <td><div align="left">DrawCircle<br>
+ DrawCircle</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double oy, oy, px, py </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName clippath ?name? <br>
+ drawName GetClipPath <br>
+ drawName SetClipPath name</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetClipPath<br>
+ DrawGetClipPath<br>
+ DrawSetClipPath</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string name </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName cliprule ?rule?<br>
+ drawName GetClipRule <br>
+ drawName SetClipRule rule</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetClipRule<br>
+ DrawGetClipRule<br>
+ DrawSetClipRule</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>rule = &quot;undefined&quot;, &quot;evenodd&quot;, &quot;nonzero&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName clipunits ?unit? <br>
+ drawName GetClipUnits <br>
+ drawName SetClipUnits unit</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetClipUnits<br>
+ DrawGetClipUnits<br>
+ DrawSetClipUnits</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>units = &quot;userspace&quot;, &quot;userspaceonuse&quot;, &quot;objectboundingbox&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName color x y paintMethod <br>
+ drawName Color x y paintMethod </p>
+ </div></td>
+ <td><div align="left">DrawColor<br>
+ DrawColor</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y</li>
+ <li>paintMethod = &quot;point&quot;, &quot;replace&quot;, &quot;floodfill&quot;, &quot;filltoborder&quot;, &quot;reset&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName comment text<br>
+ drawName comment text</p>
+ </div></td>
+ <td><div align="left">DrawComment<br>
+ DrawComment</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string text </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName ellipse ox oy rx ry start end<br>
+ drawName Ellipse ox oy rx ry start end</p>
+ </div></td>
+ <td><div align="left">DrawEllipse<br>
+ DrawEllipse</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double ox, oy, rx, ry, start, end </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p> drawName fillcolor ?pixelName?<br>
+ drawName GetFillColor <br>
+ drawName SetFillColor pixelName</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetFillColor<br>
+ DrawGetFillColor<br>
+ DrawSetFillColor<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string pixelName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName fillopacity ?value? <br>
+ drawName GetFillOpacity <br>
+ drawName SetFillOpacity value </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetFillOpacity<br>
+ DrawGetFillOpacity<br>
+ DrawSetFillOpacity</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td>drawName fillpatternurl url <br>
+ drawName SetFillPatternURL url </td>
+ <td>DrawSetFillPatternURL<br>
+ DrawSetFillPatternURL</td>
+ </tr>
+ <tr>
+ <td><ul>
+ <li>string url (e.g. &quot;#pattern_id&quot; from [push pattern]) </li>
+ </ul></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName fillrule ?rule? <br>
+ drawName GetFillRule <br>
+ drawName SetFillRule rule </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetFillRule<br>
+ DrawGetFillRule<br>
+ DrawSetFillRule</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>rule = &quot;undefined&quot;, &quot;evenodd&quot;, &quot;nonzero&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName font ?fontname? <br>
+ drawName GetFont <br>
+ drawName SetFont fontname </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetFont<br>
+ DrawGetFont<br>
+ DrawSetFont</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string fontname </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName fontfamily ?name? <br>
+ drawName GetFontFamily <br>
+ drawName SetFontFamily name </p>
+ </div></td>
+ <td><div align="left"> DrawGet/SetFontFamily<br>
+ DrawGetFontFamily<br>
+ DrawSetFontFamily</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string name </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName fontsize ?value? <br>
+ drawName GetFontSize <br>
+ drawName SetFontSize value </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetFontSize<br>
+ DrawGetFontSize<br>
+ DrawSetFontSize</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName fontstretch ?stretchType? <br>
+ drawName GetFontStretch <br>
+ drawName SetFontStretch stretchType</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetFontStretch<br>
+ DrawGetFontStretch<br>
+ DrawSetFontStretch</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>stretchType = &quot;normal&quot;, &quot;ultracondensed&quot;, &quot;extracondensed&quot;, &quot;condensed&quot;, &quot;semicondensed&quot;, &quot;semiexpanded&quot;, &quot;expanded&quot;, &quot;extraexpanded&quot;, &quot;ultraexpanded&quot;, &quot;any&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName fontstyle ?style? <br>
+ drawName GetFontStyle <br>
+ drawName SetFontStyle style </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetFontStyle<br>
+ DrawGetFontStyle<br>
+ DrawSetFontStyle</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>style = &quot;normal&quot;, &quot;italic&quot;, &quot;oblique&quot;, &quot;any&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName fontweight ?value? <br>
+ drawName GetFontWeight <br>
+ drawName SetFontWeight value </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetFontWeight<br>
+ DrawGetFontWeight<br>
+ DrawSetFontWeight</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>unsigned value </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName gravity ?gravityType <br>
+ drawName GetGravity <br>
+ drawName SetGravity gravityType </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetGravity<br>
+ DrawGetGravity<br>
+ DrawSetGravity</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>gravityType = &quot;forget&quot;, &quot;northwest&quot;, &quot;north&quot;, &quot;northeast&quot;, &quot;west&quot;, &quot;center&quot;, &quot;east&quot;, &quot;southwest&quot;, &quot;south&quot;, &quot;southeast&quot;, &quot;static&quot;
+ </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName line sx sy ex ey<br>
+ drawName Line sx sy ex ey</p>
+ </div></td>
+ <td><div align="left">DrawLine<br>
+ DrawLine</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double sx, sy, ex, ey </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName matte x y paintMethod <br>
+ drawName Matte x y paintMethod </p>
+ </div></td>
+ <td><div align="left">DrawMatte<br>
+ DrawMatte</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x,y </li>
+ <li>paintMethod = &quot;point&quot;, &quot;replace&quot;, &quot;floodfill&quot;, &quot;filltoborder&quot;, &quot;reset&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName point x y <br>
+ drawName Point x y </p>
+ </div></td>
+ <td><div align="left">DrawPoint<br>
+ DrawPoint</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName polygon x y x y ... <br>
+ drawName Polygon x y x y ... </p>
+ </div></td>
+ <td><div align="left">DrawPolygon<br>
+ DrawPolygon</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName polyline x y x y ...<br>
+ drawName Polyline x y x y ...</p>
+ </div></td>
+ <td><div align="left">DrawPolyline<br>
+ DrawPolyline</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName path opt|cmd ?args? opt|cmd ?args? ... </p>
+ </div></td>
+ <td><div align="left">DrawPathXXX</div></td>
+ </tr>
+ <tr>
+ <td><ul>
+ <li>opt ?args? = <br>
+ -relative bool (Switch relative/absolute mode)<br>
+ -smooth bool (Smooth bezier, x1,y1 taken from previous curve)<br>
+ -scale double (Scale all positions by a factor)</li>
+ </ul></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td><ul>
+ <li>cmd ?args? =<br>
+ # &quot;comment in a single argument&quot;<br>
+ start <br>
+ finish <br>
+ close <br>
+ move x y <br>
+ line x y <br>
+ horizontal x <br>
+ vertical y <br>
+ -smooth 0 quadratic x1 y1 x y <br>
+ -smooth 1 quadratic x y <br>
+ -smooth 0 cubic x1 y1 x2 y2 x y <br>
+ -smooth 1 cubic x2 y2 x y <br>
+ elliptic rx ry rotation large sweep x y </li>
+ </ul></td>
+ <td><br>
+ <br>
+ DrawPathStart<br>
+ DrawPathFinish <br>
+ DrawPathClose<br>
+ DrawPathMoveToAbs/Rel <br>
+ DrawPathLineLineToAbs/Rel<br>
+ DrawPathLineLineToHorizontalAbs/Rel <br>
+ DrawPathLineLineToVerticalAbs/Rel<br>
+ DrawPathCurveToQuadraticBezierAbs/Rel <br>
+ DrawPathCurveToQuadraticBezierSmoothAbs/Rel<br>
+ DrawPathCurveToAbs/Rel <br>
+ DrawPathCurveToSmoothAbs/Rel<br>
+ DrawPathEllipticArcAbs/Rel </td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul><li>double x, y, rx, ry , rotation</li>
+ <li>int large, sweep </li>
+ </ul>
+ </div></td>
+ <td><div align="left"><br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName path cmdList</p>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>If 'drawName path' is called with a single argument then it's intepreted <br>
+ as a list of path options&quot;, &quot;commands with its arguments.</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName push what ?args? <br>
+ drawName pop what </p>
+ </div></td>
+ <td><div align="left">DrawPushXXX<br>
+ DrawPopXXX</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>what = &quot;clippath &quot;, &quot; defs &quot;, &quot;graphiccontext&quot;, &quot;pattern&quot;</li>
+ <li> args = see below<br>
+ </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName PushClipPath id <br>
+ drawName PopClipPath <br>
+ drawName PushDefs <br>
+ drawName PopDefs <br>
+ drawName PushGraphicContext <br>
+ drawName PopGraphicContext <br>
+ drawName PushPattern id x y width height<br>
+ drawName PopPattern </p>
+ </div></td>
+ <td><div align="left">DrawPushClipPath<br>
+ DrawPopClipPath<br>
+ DrawPushDefs<br>
+ DrawPopDefs<br>
+ DrawPushGraphicContext<br>
+ DrawPopGraphicContext<br>
+ DrawPushPattern<br>
+ DrawPopPattern</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string id</li>
+ <li>double x, y, width, height </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName rectangle x1 y1 x2 y2 <br>
+ drawName Rectangle x1 y1 x2 y2 </p>
+ </div></td>
+ <td><div align="left">DrawRectangle<br>
+ DrawRectangle</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x1, y1, x2, y2 </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName render <br>
+ drawName Render </p>
+ </div></td>
+ <td><div align="left">DrawRender<br>
+ DrawRender</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>&lt;none&gt;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName rotate degrees <br>
+ drawName Rotate degrees </p>
+ </div></td>
+ <td><div align="left">DrawRotate<br>
+ DrawRotate</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double degrees </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName round x1 y1 x2 y2 rx ry <br>
+ drawName RoundRectangle x1 y1 x2 y2 rx ry</p>
+ </div></td>
+ <td><div align="left"> DrawRoundRectangle<br>
+ DrawRoundRectangle<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x1, y1, x2, y2, rx, ry </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName scale x ?y? <br>
+ drawName Scale x ?y? </p>
+ </div></td>
+ <td><div align="left">DrawScale<br>
+ DrawScale</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y (default: y=x)</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName skewx degrees<br>
+ drawName SkewX degrees<br>
+ drawName skewy degrees<br>
+ drawName SkewY degrees</p>
+ </div></td>
+ <td><div align="left">DrawSkewX<br>
+ DrawSkewX<br>
+ DrawSkewY<br>
+ DrawSkewY</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double degrees</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokecolor ?pixelName?<br>
+ drawName GetStrokeColor <br>
+ drawName SetStrokeColor pixelName<br>
+ </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetStrokeColor<br>
+ DrawGetStrokeColor<br>
+ DrawSetStrokeColor<br>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string pixelName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokeantialias ?flag?<br>
+ drawName GetStrokeAntialias <br>
+ drawName SetStrokeAntialias flag</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetStrokeAntialias<br>
+ DrawGetStrokeAntialias<br>
+ DrawSetStrokeAntialias</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int flag </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokedasharray <br>
+ drawName strokedasharray {} <br>
+ drawName strokedasharray val val ... <br>
+ drawName GetStrokeDasharray <br>
+ drawName SetStrokeDashArray <br>
+ drawName SetStrokeDashArray val val ...</p>
+ </div></td>
+ <td><div align="left">DrawGetStrokeDashArray<br>
+ DrawSetStrokeDashArray<br>
+ DrawSetStrokeDashArray<br>
+ DrawGetStrokeDashArray<br>
+ DrawSetStrokeDashArray<br>
+ DrawSetStrokeDashArray</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double val </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokedashoffset ?val? <br>
+ drawName GetStrokeDashOffset <br>
+ drawName SetStrokeDashOffset val</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetStrokeDashOffset<br>
+ DrawGetStrokeDashOffset<br>
+ DrawSetStrokeDashOffset</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double val </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokelinecap ?linecapType? <br>
+ drawName GetStrokeLineCap <br>
+ drawName SetStrokeLineCap linecapType</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetStrokeLineCap<br>
+ DrawGetStrokeLineCap<br>
+ DrawSetStrokeLineCap</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>linecapType = &quot;undefined&quot;, &quot;butt&quot;, &quot;round&quot;, &quot;square&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokelinejoin ?linejoinType? <br>
+ drawName GetStrokeLineJoin <br>
+ drawName SetStrokeLineJoin linejoinType</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetStrokeLineJoin<br>
+ DrawGetStrokeLineJoin<br>
+ DrawSetStrokeLineJoin</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>linejoinType = &quot;undefined&quot;, &quot;miter&quot;, &quot;round&quot;, &quot;bevel&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokemiterlimit ?val? <br>
+ drawName GetStrokeMiterLimit <br>
+ drawName SetStrokeMiterLimit val</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetStrokeMiterLimit<br>
+ DrawGetStrokeMiterLimit<br>
+ DrawSetStrokeMiterLimit</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>unsigned val </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokeopacity ?val? <br>
+ drawName GetStrokeOpacity <br>
+ drawName SetStrokeOpacity val</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetStrokeOpacity<br>
+ DrawGetStrokeOpacity<br>
+ DrawSetStrokeOpacity</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double val </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td>drawName strokepatternurl url <br>
+ drawName SetStrokePatternURL url </td>
+ <td>DrawSetStrokePatternURL<br>
+ DrawSetStrokePatternURL</td>
+ </tr>
+ <tr>
+ <td><ul>
+ <li>string url (e.g. &quot;#pattern_id&quot; from [push pattern]) </li>
+ </ul></td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName strokewidth ?val? <br>
+ drawName GetStrokeWidth <br>
+ drawName SetStrokeWidth val</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetStrokeWidth<br>
+ DrawGetStrokeWidth<br>
+ DrawSetStrokeWidth</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double val</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName textantialias ?flag? <br>
+ drawName GetTextAntialias <br>
+ drawName SetTextAntialias flag </p>
+ </div></td>
+ <td><div align="left">DrawGet/SetTextAntialias<br>
+ DrawGetTextAntialias<br>
+ DrawSetTextAntialias</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>int flag </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName textdecoration ?decorationType? <br>
+ drawName GeTextDecoration <br>
+ drawName SetTextDecoration decorationType</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetTextDecoration<br>
+ DrawGetTextDecoration<br>
+ DrawSetTextDecoration</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string decorationType = &quot;none&quot;, &quot;underline&quot;, &quot;overline&quot;, &quot;linethrough&quot;</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName textencoding ?string <br>
+ drawName GetTextEncoding <br>
+ drawName SetTextEncoding string</p>
+ </div></td>
+ <td><div align="left"> DrawGet/SetTextEncoding<br>
+ DrawGetTextEncoding<br>
+ DrawSetTextEncoding</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string string </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName textundercolor ?pixelName?<br>
+ drawName GetTextUnderColor <br>
+ drawName SetTextUnderColor pixelName</p>
+ </div></td>
+ <td><div align="left">DrawGet/SetTextUnderColor<br>
+ DrawGetTextUnderColor<br>
+ DrawSetTextUnderColor</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>string pixelName</li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName translate x y <br>
+ drawName Translate x y</p>
+ </div></td>
+ <td><div align="left">DrawTranslate<br>
+ DrawTranslate</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>double x, y </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <p>drawName viewbox x1 y1 x2 y2 <br>
+ drawName SetViewbox x1 y1 x2 y2</p>
+ </div></td>
+ <td><div align="left">DrawSetViewbox<br>
+ DrawSetViewbox</div></td>
+ </tr>
+ <tr>
+ <td><div align="left">
+ <ul>
+ <li>unsigned x1, y1, x2, y2 </li>
+ </ul>
+ </div></td>
+ <td><div align="left"></div></td>
+ </tr>
+ </table>
+ <p>&nbsp;</p>
+ <table width="798" border="1">
+ <tr>
+ <th width="312" scope="col"><div align="left">Not implemented MagickWand API's</div></th>
+ <th width="428" scope="col"><div align="left">Comment</div></th>
+ </tr>
+ <tr>
+ <td><div align="left">DrawAllocateWand</div></td>
+ <td><div align="left">For legacy application only, outside Wand-API </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">DrawComposite</div></td>
+ <td><div align="left">For legacy application only, outside Wand-API </div></td>
+ </tr>
+ <tr>
+ <td><div align="left">DrawSetStopColor</div></td>
+ <td><div align="left">???</div></td>
+ </tr>
+ </table>
+ <p>&nbsp; </p>
+ <hr>
+ <small>Copyright 2004 Rolf Schr&ouml;dter and David N. Welton</small>
+ </body>
+</html>
diff --git a/TclMagick/doc/TkMagick.html b/TclMagick/doc/TkMagick.html
new file mode 100644
index 0000000..45d75c0
--- /dev/null
+++ b/TclMagick/doc/TkMagick.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+ <head>
+ <title>TkMagick</title>
+ <meta http-equiv="Content-Type" content="text/html;
+ charset=iso-8859-1">
+ <link rel="stylesheet" href="style.css">
+ <!-- $Id$ -->
+ </head>
+ <body>
+
+ <table>
+ <tbody>
+ <tr>
+ <td style="background-color: #ff6666; padding: 1ex; font-weight: bold;"><a href="index.html">Main</a></td>
+ <td style="background-color: #66ff66; padding: 1ex; font-weight: bold;"><a href="TclMagick.html">TclMagick</a></td>
+ <td style="background-color: #6666ff; padding: 1ex; font-weight: bold;"><a href="TkMagick.html">TkMagick</a></td>
+ <td width="100%"></td>
+ <td>
+ <a href="http://sourceforge.net/projects/tclmagick">
+ <img src="http://sourceforge.net/sflogo.php?group_id=96922&amp;type=2" width="125" height="37" border="0"
+ alt="SourceForge.net Logo"></a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h2>TkMagick - glue between TclMagick and Tk's Images</h2>
+ <p>
+ TkMagick is a small, simple extension that lets you pass images
+ back and forth between Tk and the TclMagick extension.
+ </p>
+ <p>
+ It has only two commands:
+ </p>
+ <ul>
+ <li><b>magicktophoto</b> <i>magick_wand</i> <i>tk_image</i><br>
+ This command takes a pre-existing magick wand and tk photo
+ image and replaces the tk image's data with the magick wand's
+ data.
+ </li>
+ <li><b>phototomagick</b> <i>tk_image</i> <i>magick_wand</i><br>
+ This command takes a pre-existing tk photo image and magick
+ wand as arguments, and replaces the magick wand's image with
+ that contained in the tk image.
+ </li>
+ </ul>
+ <h3>Example:</h3>
+ <pre>
+proc magickimage {filename} {
+ set magimg [magick create wand]
+ set tkimg [image create photo]
+ $magimg ReadImage $filename
+ magicktophoto $magimg $tkimg
+ magick delete $magimg
+ return $tkimg
+}
+
+set poolphoto [magickimage [file join $dirname .. images pool.jpg]]
+label .im
+.im configure -image $poolphoto
+pack .im
+bind . &lt;q&gt; exit
+ </pre>
+
+ <small>Copyright 2004 Rolf Schr&ouml;dter and David
+ N. Welton</small>
+
+ </body>
+</html> \ No newline at end of file
diff --git a/TclMagick/doc/index.html b/TclMagick/doc/index.html
new file mode 100644
index 0000000..36a8a1f
--- /dev/null
+++ b/TclMagick/doc/index.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+ <head>
+ <title>TclMagick</title>
+ <link rel="stylesheet" href="style.css">
+ </head>
+ <body>
+
+ <table width="100%">
+ <tbody>
+ <tr>
+ <td style="background-color: #ff6666; padding: 1ex; font-weight: bold;"><a href="index.html">Main</a></td>
+ <td style="background-color: #66ff66; padding: 1ex; font-weight: bold;"><a href="TclMagick.html">TclMagick</a></td>
+ <td style="background-color: #6666ff; padding: 1ex; font-weight: bold;"><a href="TkMagick.html">TkMagick</a></td>
+ <td width="100%"></td>
+ <td>
+ <a href="http://sourceforge.net/projects/tclmagick">
+ <img
+ src="http://sourceforge.net/sflogo.php?group_id=96922&amp;type=2"
+ width="125" height="37" border="0"
+ alt="SourceForge.net Logo"></a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h2>Tcl and Tk Interfaces to GraphicsMagick and
+ ImageMagick</h2>
+
+ <p>
+ <em>TclMagick</em> is a <a href="http://www.tcl.tk">Tcl</a> extension
+ that works with both the <a
+ href="http://www.graphicsmagick.org/">GraphicsMagick</a> and <a
+ href="http://www.imagemagick.org/">ImageMagick</a> image
+ manipulation libraries.<br>
+ <em>TkMagick</em> is a small, simple extension that lets you pass images back and forth between Tk and the <em>TclMagick</em> extension. </p>
+ <h3>Requirements</h3>
+ <p><em>TclMagick</em> runs with pure Tcl, no Tk is required. It needs an installed <a
+ href="http://www.imagemagick.org/">ImageMagick</a> or <a
+ href="http://www.graphicsmagick.org/">GraphicsMagick</a> library.
+ The Windows version also requires <a
+ href="http://sourceforge.net/projects/ghostscript/">Ghostscript</a>
+ for standard postscript fonts.<br>
+ <em>TkMagick</em> needs Tk, of course. To run Tcl and Tk
+ Magick, you need either GraphicsMagick 1.1 (or greater) or a
+ recent ImageMagick 6 release.
+ </p>
+
+
+ <h3>Download</h3>
+ <p>
+ <em>TclMagick</em> and <em>TkMagick</em> source code binary snapshots can be downloaded from <a
+ href="http://sourceforge.net/projects/tclmagick/files/">sourceforge</a>.</p>
+ <p>
+ Anonymous CVS is available from:
+ </p>
+ <blockquote><code>
+ cvs -d:pserver:anonymous@cvs.graphicsmagick.org:/GraphicsMagick login<br>
+ cvs -d:pserver:anonymous@cvs.graphicsmagick.org:/GraphicsMagick co TclMagick</code>
+ </blockquote>
+ <p>
+ Using the password <i>anonymous</i>.
+ </p>
+ <h3>Documentation</h3>
+ <ul>
+ <li><a href="TclMagick.html">TclMagick</a></li>
+ <li><a href="TkMagick.html">TkMagick</a></li>
+ </ul>
+
+ <h3>Mailing List</h3>
+ <p>
+ If the documentation doesn't answer your questions, feel free to
+ write us on the mailing list. Information at: <a
+ href="http://lists.sourceforge.net/lists/listinfo/graphicsmagick-tclmagick">http://lists.sourceforge.net/lists/listinfo/graphicsmagick-tclmagick</a>
+ </p>
+
+ <h3>Credits</h3>
+
+ <p>
+ <em>TclMagick</em> and <em>TkMagick</em> were written by <a
+ href="http://www.rolf-schroedter.de/">Rolf Schr&ouml;dter</a>,
+ and <a href="http://www.welton.it/davidw/">David Welton</a>.<br>
+ Thanks also to the GraphicsMagick and ImageMagick projects for
+ their hard work.</p>
+
+ <h3>License</h3>
+
+ <p>
+ TclMagick is distributed under a fairly liberal license, similar
+ to that of Tcl itself . <a href="license.txt">TclMagick
+ License</a>.
+ </p>
+
+ <small>Copyright 2004 Rolf Schr&ouml;dter and David N. Welton</small>
+
+ </body>
+</html> \ No newline at end of file
diff --git a/TclMagick/doc/license.txt b/TclMagick/doc/license.txt
new file mode 100644
index 0000000..1cd0d1d
--- /dev/null
+++ b/TclMagick/doc/license.txt
@@ -0,0 +1,39 @@
+This software is copyrighted 2004 by Rolf Schrdter
+<Rolf.Schroedter@dlr.de> and David N. Welton <davidw@dedasys.com>. The
+following terms apply to all files associated with the software unless
+explicitly disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+GOVERNMENT USE: If you are acquiring this software on behalf of the
+U.S. government, the Government shall have only "Restricted Rights"
+in the software and related documentation as defined in the Federal
+Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+are acquiring the software on behalf of the Department of Defense, the
+software shall be classified as "Commercial Computer Software" and the
+Government shall have only "Restricted Rights" as defined in Clause
+252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
+authors grant the U.S. Government and others acting in its behalf
+permission to use and distribute the software in accordance with the
+terms specified in this license.
diff --git a/TclMagick/doc/style.css b/TclMagick/doc/style.css
new file mode 100644
index 0000000..7a847a6
--- /dev/null
+++ b/TclMagick/doc/style.css
@@ -0,0 +1,10 @@
+body {
+ font-family: Arial, sans-serif;
+ font-style: normal;
+ color: #000000;
+ background-color: #FFFFFF;
+}
+
+h2 {
+ text-align: center;
+}
diff --git a/TclMagick/genconf.sh b/TclMagick/genconf.sh
new file mode 100755
index 0000000..e6675d2
--- /dev/null
+++ b/TclMagick/genconf.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Execute this script to update the build environment if the version of
+# Automake or Autoconf is changed.
+#
+
+libtoolize --verbose --copy --force
+aclocal -I unix/m4
+#autoheader
+autoconf
+automake --verbose --add-missing --copy --force-missing
+
diff --git a/TclMagick/generic/Makefile.am b/TclMagick/generic/Makefile.am
new file mode 100644
index 0000000..576b52d
--- /dev/null
+++ b/TclMagick/generic/Makefile.am
@@ -0,0 +1,25 @@
+# Makefile for creating libTclMagick and libTkMagick
+
+# Copyright David N. Welton <davidw@dedasys.com>, 2004, with many
+# thanks to Bob Friesenhahn for all the help.
+
+# AM_CFLAGS = @TCL_INCLUDES@ @GM_CPPFLAGS@
+
+# Put this in its own package directory.
+lib_magickdir = @libdir@/TclMagick@VERSION@
+lib_magick_LTLIBRARIES = libttkcommon.la libTclMagick.la libTkMagick.la
+
+libttkcommon_la_SOURCES = libttkcommon.c libttkcommon.h
+libttkcommon_la_LDFLAGS = @GM_LDFLAGS@ -no-undefined
+libttkcommon_la_LIBADD = @TCL_STUB_LIB_SPEC@ @TCL_LIBS@ @TCL_LIBS@ @GM_LIBS@
+libttkcommon_la_CPPFLAGS = @TCL_INCLUDES@ @GM_CPPFLAGS@
+
+libTclMagick_la_SOURCES = TclMagick.c TclMagick.h libttkcommon.h
+libTclMagick_la_LDFLAGS = @GM_LDFLAGS@ -L$(lib_magickdir) -no-undefined -module
+libTclMagick_la_LIBADD = @TCL_STUB_LIB_SPEC@ @TCL_LIBS@ @TCL_LIBS@ @GM_LIBS@ libttkcommon.la
+libTclMagick_la_CPPFLAGS = @TCL_INCLUDES@ @GM_CPPFLAGS@
+
+libTkMagick_la_SOURCES = TkMagick.c TclMagick.h libttkcommon.h
+libTkMagick_la_LDFLAGS = @GM_LDFLAGS@ -L$(lib_magickdir) -no-undefined -module
+libTkMagick_la_LIBADD = @TCL_STUB_LIB_SPEC@ @TK_STUB_LIB_SPEC@ @TCL_LIBS@ @TK_LIBS@ @GM_LIBS@ libttkcommon.la
+libTkMagick_la_CPPFLAGS = @TCL_INCLUDES@ @GM_CPPFLAGS@ @TK_INCLUDES@ @TK_XINCLUDES@
diff --git a/TclMagick/generic/Makefile.in b/TclMagick/generic/Makefile.in
new file mode 100644
index 0000000..38b2282
--- /dev/null
+++ b/TclMagick/generic/Makefile.in
@@ -0,0 +1,694 @@
+# Makefile.in generated by automake 1.11.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for creating libTclMagick and libTkMagick
+
+# Copyright David N. Welton <davidw@dedasys.com>, 2004, with many
+# thanks to Bob Friesenhahn for all the help.
+
+# AM_CFLAGS = @TCL_INCLUDES@ @GM_CPPFLAGS@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = generic
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/unix/m4/libtool.m4 \
+ $(top_srcdir)/unix/m4/ltoptions.m4 \
+ $(top_srcdir)/unix/m4/ltsugar.m4 \
+ $(top_srcdir)/unix/m4/ltversion.m4 \
+ $(top_srcdir)/unix/m4/lt~obsolete.m4 \
+ $(top_srcdir)/unix/m4/tcl.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(lib_magickdir)"
+LTLIBRARIES = $(lib_magick_LTLIBRARIES)
+libTclMagick_la_DEPENDENCIES = libttkcommon.la
+am_libTclMagick_la_OBJECTS = libTclMagick_la-TclMagick.lo
+libTclMagick_la_OBJECTS = $(am_libTclMagick_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libTclMagick_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libTclMagick_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+libTkMagick_la_DEPENDENCIES = libttkcommon.la
+am_libTkMagick_la_OBJECTS = libTkMagick_la-TkMagick.lo
+libTkMagick_la_OBJECTS = $(am_libTkMagick_la_OBJECTS)
+libTkMagick_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libTkMagick_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+libttkcommon_la_DEPENDENCIES =
+am_libttkcommon_la_OBJECTS = libttkcommon_la-libttkcommon.lo
+libttkcommon_la_OBJECTS = $(am_libttkcommon_la_OBJECTS)
+libttkcommon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libttkcommon_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/unix/config/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libTclMagick_la_SOURCES) $(libTkMagick_la_SOURCES) \
+ $(libttkcommon_la_SOURCES)
+DIST_SOURCES = $(libTclMagick_la_SOURCES) $(libTkMagick_la_SOURCES) \
+ $(libttkcommon_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CELIB_DIR = @CELIB_DIR@
+CFLAGS = @CFLAGS@
+CFLAGS_DEBUG = @CFLAGS_DEBUG@
+CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+CLEANFILES = @CLEANFILES@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH = @CYGPATH@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GM_CPPFLAGS = @GM_CPPFLAGS@
+GM_LDFLAGS = @GM_LDFLAGS@
+GM_LIBS = @GM_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
+INSTALL_LIBRARY = @INSTALL_LIBRARY@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LD_LIBRARY_PATH_VAR = @LD_LIBRARY_PATH_VAR@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKE_LIB = @MAKE_LIB@
+MAKE_SHARED_LIB = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB = @MAKE_STUB_LIB@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MATH_LIBS = @MATH_LIBS@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CFLAGS = @PKG_CFLAGS@
+PKG_HEADERS = @PKG_HEADERS@
+PKG_INCLUDES = @PKG_INCLUDES@
+PKG_LIBS = @PKG_LIBS@
+PKG_LIB_FILE = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+PRACTCL_CFLAGS = @PRACTCL_CFLAGS@
+PRACTCL_NAME_LIBRARY = @PRACTCL_NAME_LIBRARY@
+PRACTCL_SHARED_LIB = @PRACTCL_SHARED_LIB@
+PRACTCL_STATIC_LIB = @PRACTCL_STATIC_LIB@
+PRACTCL_STUB_LIB = @PRACTCL_STUB_LIB@
+PRACTCL_TOOLSET = @PRACTCL_TOOLSET@
+PRACTCL_VC_MANIFEST_EMBED_DLL = @PRACTCL_VC_MANIFEST_EMBED_DLL@
+PRACTCL_VC_MANIFEST_EMBED_EXE = @PRACTCL_VC_MANIFEST_EMBED_EXE@
+PRACTCL_WINDOWINGSYSTEM = @PRACTCL_WINDOWINGSYSTEM@
+RANLIB = @RANLIB@
+RANLIB_STUB = @RANLIB_STUB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHARED_BUILD = @SHARED_BUILD@
+SHELL = @SHELL@
+SHLIB_CFLAGS = @SHLIB_CFLAGS@
+SHLIB_LD = @SHLIB_LD@
+SHLIB_LD_LIBS = @SHLIB_LD_LIBS@
+SHLIB_SUFFIX = @SHLIB_SUFFIX@
+STLIB_LD = @STLIB_LD@
+STRIP = @STRIP@
+STUBS_BUILD = @STUBS_BUILD@
+TCLSH_PROG = @TCLSH_PROG@
+TCL_BIN_DIR = @TCL_BIN_DIR@
+TCL_DEFS = @TCL_DEFS@
+TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@
+TCL_INCLUDES = @TCL_INCLUDES@
+TCL_LD_FLAGS = @TCL_LD_FLAGS@
+TCL_LIBS = @TCL_LIBS@
+TCL_LIB_FILE = @TCL_LIB_FILE@
+TCL_LIB_FLAG = @TCL_LIB_FLAG@
+TCL_LIB_SPEC = @TCL_LIB_SPEC@
+TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@
+TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@
+TCL_SRC_DIR = @TCL_SRC_DIR@
+TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@
+TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@
+TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
+TCL_THREADS = @TCL_THREADS@
+TCL_VERSION = @TCL_VERSION@
+TEA_TK_EXTENSION = @TEA_TK_EXTENSION@
+TK_BIN_DIR = @TK_BIN_DIR@
+TK_INCLUDES = @TK_INCLUDES@
+TK_LIBS = @TK_LIBS@
+TK_LIB_FILE = @TK_LIB_FILE@
+TK_LIB_FLAG = @TK_LIB_FLAG@
+TK_LIB_SPEC = @TK_LIB_SPEC@
+TK_SRC_DIR = @TK_SRC_DIR@
+TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@
+TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@
+TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@
+TK_VERSION = @TK_VERSION@
+TK_XINCLUDES = @TK_XINCLUDES@
+VC_MANIFEST_EMBED_DLL = @VC_MANIFEST_EMBED_DLL@
+VC_MANIFEST_EMBED_EXE = @VC_MANIFEST_EMBED_EXE@
+VERSION = @VERSION@
+WISH_PROG = @WISH_PROG@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wand_config = @wand_config@
+
+# Put this in its own package directory.
+lib_magickdir = @libdir@/TclMagick@VERSION@
+lib_magick_LTLIBRARIES = libttkcommon.la libTclMagick.la libTkMagick.la
+libttkcommon_la_SOURCES = libttkcommon.c libttkcommon.h
+libttkcommon_la_LDFLAGS = @GM_LDFLAGS@ -no-undefined
+libttkcommon_la_LIBADD = @TCL_STUB_LIB_SPEC@ @TCL_LIBS@ @TCL_LIBS@ @GM_LIBS@
+libttkcommon_la_CPPFLAGS = @TCL_INCLUDES@ @GM_CPPFLAGS@
+libTclMagick_la_SOURCES = TclMagick.c TclMagick.h libttkcommon.h
+libTclMagick_la_LDFLAGS = @GM_LDFLAGS@ -L$(lib_magickdir) -no-undefined -module
+libTclMagick_la_LIBADD = @TCL_STUB_LIB_SPEC@ @TCL_LIBS@ @TCL_LIBS@ @GM_LIBS@ libttkcommon.la
+libTclMagick_la_CPPFLAGS = @TCL_INCLUDES@ @GM_CPPFLAGS@
+libTkMagick_la_SOURCES = TkMagick.c TclMagick.h libttkcommon.h
+libTkMagick_la_LDFLAGS = @GM_LDFLAGS@ -L$(lib_magickdir) -no-undefined -module
+libTkMagick_la_LIBADD = @TCL_STUB_LIB_SPEC@ @TK_STUB_LIB_SPEC@ @TCL_LIBS@ @TK_LIBS@ @GM_LIBS@ libttkcommon.la
+libTkMagick_la_CPPFLAGS = @TCL_INCLUDES@ @GM_CPPFLAGS@ @TK_INCLUDES@ @TK_XINCLUDES@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign generic/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign generic/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-lib_magickLTLIBRARIES: $(lib_magick_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(lib_magickdir)" || $(MKDIR_P) "$(DESTDIR)$(lib_magickdir)"
+ @list='$(lib_magick_LTLIBRARIES)'; test -n "$(lib_magickdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(lib_magickdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(lib_magickdir)"; \
+ }
+
+uninstall-lib_magickLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_magick_LTLIBRARIES)'; test -n "$(lib_magickdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(lib_magickdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(lib_magickdir)/$$f"; \
+ done
+
+clean-lib_magickLTLIBRARIES:
+ -test -z "$(lib_magick_LTLIBRARIES)" || rm -f $(lib_magick_LTLIBRARIES)
+ @list='$(lib_magick_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libTclMagick.la: $(libTclMagick_la_OBJECTS) $(libTclMagick_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libTclMagick_la_LINK) -rpath $(lib_magickdir) $(libTclMagick_la_OBJECTS) $(libTclMagick_la_LIBADD) $(LIBS)
+libTkMagick.la: $(libTkMagick_la_OBJECTS) $(libTkMagick_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libTkMagick_la_LINK) -rpath $(lib_magickdir) $(libTkMagick_la_OBJECTS) $(libTkMagick_la_LIBADD) $(LIBS)
+libttkcommon.la: $(libttkcommon_la_OBJECTS) $(libttkcommon_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libttkcommon_la_LINK) -rpath $(lib_magickdir) $(libttkcommon_la_OBJECTS) $(libttkcommon_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libTclMagick_la-TclMagick.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libTkMagick_la-TkMagick.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libttkcommon_la-libttkcommon.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libTclMagick_la-TclMagick.lo: TclMagick.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libTclMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libTclMagick_la-TclMagick.lo -MD -MP -MF $(DEPDIR)/libTclMagick_la-TclMagick.Tpo -c -o libTclMagick_la-TclMagick.lo `test -f 'TclMagick.c' || echo '$(srcdir)/'`TclMagick.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libTclMagick_la-TclMagick.Tpo $(DEPDIR)/libTclMagick_la-TclMagick.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='TclMagick.c' object='libTclMagick_la-TclMagick.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libTclMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libTclMagick_la-TclMagick.lo `test -f 'TclMagick.c' || echo '$(srcdir)/'`TclMagick.c
+
+libTkMagick_la-TkMagick.lo: TkMagick.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libTkMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libTkMagick_la-TkMagick.lo -MD -MP -MF $(DEPDIR)/libTkMagick_la-TkMagick.Tpo -c -o libTkMagick_la-TkMagick.lo `test -f 'TkMagick.c' || echo '$(srcdir)/'`TkMagick.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libTkMagick_la-TkMagick.Tpo $(DEPDIR)/libTkMagick_la-TkMagick.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='TkMagick.c' object='libTkMagick_la-TkMagick.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libTkMagick_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libTkMagick_la-TkMagick.lo `test -f 'TkMagick.c' || echo '$(srcdir)/'`TkMagick.c
+
+libttkcommon_la-libttkcommon.lo: libttkcommon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libttkcommon_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libttkcommon_la-libttkcommon.lo -MD -MP -MF $(DEPDIR)/libttkcommon_la-libttkcommon.Tpo -c -o libttkcommon_la-libttkcommon.lo `test -f 'libttkcommon.c' || echo '$(srcdir)/'`libttkcommon.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libttkcommon_la-libttkcommon.Tpo $(DEPDIR)/libttkcommon_la-libttkcommon.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libttkcommon.c' object='libttkcommon_la-libttkcommon.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libttkcommon_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libttkcommon_la-libttkcommon.lo `test -f 'libttkcommon.c' || echo '$(srcdir)/'`libttkcommon.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(lib_magickdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-lib_magickLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-lib_magickLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-lib_magickLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-lib_magickLTLIBRARIES clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-lib_magickLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-lib_magickLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/TclMagick/generic/TclMagick.c b/TclMagick/generic/TclMagick.c
new file mode 100644
index 0000000..ae1fce3
--- /dev/null
+++ b/TclMagick/generic/TclMagick.c
@@ -0,0 +1,8179 @@
+/**********************************************************************
+ * Tcl Image Magick - a Tcl-only wrapper of imageMagick's Wand-API
+ **********************************************************************
+ * For a brief command description see "doc/TclMagick.txt"
+ *
+ * For a list of changes see "ChangeLog"
+ **********************************************************************/
+
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "libttkcommon.h"
+#include "TclMagick.h"
+#include <wand/magick_wand.h>
+
+static char *getMagickObjName(TclMagickObj *mPtr);
+static TclMagickObj *newMagickObj(Tcl_Interp *interp, int type, void *wandPtr, char *name);
+
+/**********************************************************************/
+/* Workaround for bugs: */
+
+#define MAGICK_NEW /* new interfaces */
+#ifdef MAGICK_NEW
+
+#endif
+
+/* Debug TclMagick */
+#define MAGICK_DEBUG
+/**********************************************************************/
+
+extern TMHT TM;
+extern CONST char* objTypeNames[];
+static Tcl_ObjCmdProc magickCmd;
+static Tcl_CmdDeleteProc magickObjDeleteCmd;
+static Tcl_ObjCmdProc wandObjCmd;
+static Tcl_ObjCmdProc pixelObjCmd;
+static Tcl_ObjCmdProc drawObjCmd;
+
+/*----------------------------------------------------------------------
+ * Return the name of a TclMagickObj
+ *----------------------------------------------------------------------
+ */
+static char *getMagickObjName(TclMagickObj *mPtr)
+{
+ if( mPtr == NULL ) {
+ return (char *)NULL;
+ } else {
+ return (char *)Tcl_GetHashKey(&TM.hashTable, mPtr->hashPtr);
+ }
+}
+
+/*----------------------------------------------------------------------
+ * Delete TclMagick objects
+ *----------------------------------------------------------------------
+ */
+static void deleteMagickObj(TclMagickObj *mPtr)
+{
+ /*
+ * Delete the Tcl command deletes also the object itself
+ * by calling magickObjDeleteCmd()
+ */
+ if( mPtr->magickCmd != NULL ) {
+ Tcl_DeleteCommandFromToken(mPtr->interp, mPtr->magickCmd);
+ mPtr->magickCmd = NULL;
+ }
+}
+static void magickObjDeleteCmd(ClientData clientData)
+{
+ TclMagickObj *mPtr = (TclMagickObj *)clientData;
+
+ if( mPtr == NULL ) {
+ return;
+ }
+ /*
+ * Called before the Tcl command is deleted
+ */
+ if( mPtr->wandPtr != NULL ) {
+ switch(mPtr->type) {
+ case TM_TYPE_WAND:
+ DestroyMagickWand(mPtr->wandPtr);
+ mPtr->wandPtr=(MagickWand *) NULL;;
+ break;
+ case TM_TYPE_DRAWING:
+ DestroyDrawingWand(mPtr->wandPtr);
+ mPtr->wandPtr=(DrawingWand *) NULL;
+ break;
+ case TM_TYPE_PIXEL:
+ DestroyPixelWand(mPtr->wandPtr);
+ mPtr->wandPtr=(PixelWand *) NULL;
+ break;
+ }
+ }
+ if( mPtr->hashPtr != NULL ) {
+ Tcl_DeleteHashEntry(mPtr->hashPtr);
+ mPtr->hashPtr=(Tcl_HashEntry *) NULL;
+ }
+ ckfree((char *)mPtr);
+}
+
+/*----------------------------------------------------------------------
+ * Create TclMagick objects
+ *----------------------------------------------------------------------
+ */
+static TclMagickObj *newMagickObj(Tcl_Interp *interp, int type, void *wandPtr, char *name)
+{
+ int isNew;
+ char idString[16 + TCL_INTEGER_SPACE];
+ TclMagickObj *mPtr;
+ Tcl_HashEntry *hPtr;
+
+ /*
+ * Create the TclMagick object
+ */
+ mPtr = (TclMagickObj *)ckalloc(sizeof(TclMagickObj));
+ if( mPtr == NULL ) {
+ return NULL;
+ }
+
+ /*
+ * if no wandPtr is specified create one
+ */
+ if( wandPtr == NULL ) {
+ switch(type) {
+ case TM_TYPE_WAND:
+ wandPtr = NewMagickWand();
+ break;
+ case TM_TYPE_DRAWING:
+ wandPtr = NewDrawingWand();
+ break;
+ case TM_TYPE_PIXEL:
+ wandPtr = NewPixelWand();
+ break;
+ }
+ }
+
+ /*
+ * if no creation ?name? is specified
+ * create one from the MagickWand address
+ */
+ if( name == NULL ) {
+ sprintf(idString, "magick%p", wandPtr );
+ name = idString;
+ }
+
+ /*
+ * Create the hash table entry
+ * Delete already existing object
+ */
+ hPtr = Tcl_CreateHashEntry( &TM.hashTable, name, &isNew );
+ if( ! isNew ) {
+ deleteMagickObj(Tcl_GetHashValue(hPtr));
+ hPtr = Tcl_CreateHashEntry( &TM.hashTable, name, &isNew );
+ }
+ Tcl_SetHashValue(hPtr, mPtr);
+
+ /*
+ * Initialize MagickObj fields
+ * and create the Tcl command
+ */
+ mPtr->type = type;
+ mPtr->interp = interp;
+ mPtr->hashPtr = hPtr;
+ mPtr->wandPtr = wandPtr;
+ switch(type) {
+ case TM_TYPE_WAND:
+ mPtr->magickCmd = Tcl_CreateObjCommand(interp, name, wandObjCmd, (ClientData)mPtr, magickObjDeleteCmd);
+ break;
+ case TM_TYPE_DRAWING:
+ mPtr->magickCmd = Tcl_CreateObjCommand(interp, name, drawObjCmd, (ClientData)mPtr, magickObjDeleteCmd);
+ break;
+ case TM_TYPE_PIXEL:
+ mPtr->magickCmd = Tcl_CreateObjCommand(interp, name, pixelObjCmd,(ClientData)mPtr, magickObjDeleteCmd);
+ break;
+ }
+
+ return mPtr;
+}
+static char *newWandObj(Tcl_Interp *interp, MagickWand *wandPtr, char *name)
+{
+ TclMagickObj *mPtr = newMagickObj(interp, TM_TYPE_WAND, wandPtr, name);
+ return getMagickObjName(mPtr);
+}
+
+#if 0 /* Currently not referenced, avoid gcc warnings */
+static char *newDrawingObj(Tcl_Interp *interp, DrawingWand *wandPtr, char *name)
+{
+ TclMagickObj *mPtr = newMagickObj(interp, TM_TYPE_DRAWING, wandPtr, name);
+ return getMagickObjName(mPtr);
+}
+#endif
+
+static char *newPixelObj(Tcl_Interp *interp, PixelWand *wandPtr, char *name)
+{
+ TclMagickObj *mPtr = newMagickObj(interp, TM_TYPE_PIXEL, wandPtr, name);
+ return getMagickObjName(mPtr);
+}
+
+/*----------------------------------------------------------------------
+ * Check whether an empty object name is specified
+ * - Should we extend this to use "none" alternatively to "" ?
+ * This reads better, but disallows "none" as an object name
+ *----------------------------------------------------------------------
+ */
+static int noWandObj(const char *name)
+{
+ return (strlen(name) == 0);
+}
+
+
+ /*----------------------------------------------------------------------
+ * Find TclMagick objects
+ *----------------------------------------------------------------------
+ */
+TclMagickObj *findMagickObj(Tcl_Interp *interp, int type, char *name)
+{
+ Tcl_HashEntry *hPtr = Tcl_FindHashEntry( &TM.hashTable, name );
+ TclMagickObj *mPtr;
+
+ if( hPtr == NULL ) {
+ Tcl_AppendResult(interp, "Magick object '", name, "' not found", NULL);
+ return (TclMagickObj *)NULL;
+ } else {
+ mPtr = (TclMagickObj *)Tcl_GetHashValue(hPtr);
+ if( (type != TM_TYPE_ANY) && (mPtr->type != type) ) {
+ Tcl_AppendResult(interp, "Magick object '", name, "' is not a ", objTypeNames[type], " object", NULL);
+ return (TclMagickObj *)NULL;
+ }
+ return mPtr;
+ }
+}
+
+/*----------------------------------------------------------------------
+ * encoding functions
+ *----------------------------------------------------------------------
+ */
+static void SetResultAsExternalString(Tcl_Interp *interp, char *ext) {
+ Tcl_DString extrep;
+ Tcl_ExternalToUtfDString(NULL, ext, -1, &extrep);
+ Tcl_DStringResult(interp, &extrep);
+ Tcl_DStringFree(&extrep);
+}
+
+
+/*----------------------------------------------------------------------
+ * magick command
+ *----------------------------------------------------------------------
+ *
+ * magick create type ?name?
+ * magick delete name name ...
+ * magick names ?type?
+ * magick type name
+ * magick types
+ * magick resourcelimit resource ?limit?
+ * magick fonts pattern
+ * magick formats pattern
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int magickCmd(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* Interpreter containing image */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] ) /* List of arguments */
+{
+ int index, stat, result;
+
+ static CONST char *subCmds[] = {
+ "create", "delete", "names", "type", "types",
+ "resourcelimit", "fonts", "formats", "version", "library",
+ (char *) NULL};
+ enum subIndex {
+ TM_CREATE, TM_DELETE, TM_NAMES, TM_TYPE, TM_TYPES,
+ TM_RESOURCE, TM_FONTS, TM_FORMATS, TM_VERSION, TM_LIBRARY
+ };
+ static CONST char *resourceNames[] = {
+ "undefined", "area", "disk",
+ "file", "map", "memory",
+ "pixels", "threads", "width",
+ "height",
+ (char *) NULL
+ };
+ static ResourceType resourceTypes[] = {
+ UndefinedResource, AreaResource, DiskResource,
+ FileResource, MapResource, MemoryResource,
+ PixelsResource, ThreadsResource, WidthResource,
+ HeightResource
+ };
+
+ (void) clientData; /* Unused */
+
+ if( objc < 2 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "subcmd ?args?" );
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[1], subCmds, "subcmd", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch ((enum subIndex)index) {
+
+
+ case TM_CREATE: /* magick create type ?name? */
+ {
+ char *name;
+ int type;
+ TclMagickObj *mPtr;
+
+ if( (objc < 3) || (objc > 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "type ?name?");
+ return TCL_ERROR;
+ }
+ /*
+ * Get type parameter
+ * If no creation ?name? is specified, set name=NULL
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], objTypeNames, "type", 0, &type) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( objc > 3 ) {
+ name = Tcl_GetString(objv[3]);
+ } else {
+ name = NULL;
+ }
+ mPtr = newMagickObj(interp, type, NULL, name);
+ name = getMagickObjName(mPtr);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_DELETE: /* magick delete name name ...*/
+ {
+ int i;
+ char *name;
+ TclMagickObj *mPtr;
+
+ for (i = 2; i < objc; i++) {
+ name = Tcl_GetString(objv[i]);
+ mPtr = findMagickObj(interp, TM_TYPE_ANY, name);
+ if (mPtr == NULL) {
+ return TCL_ERROR;
+ }
+ deleteMagickObj(mPtr);
+ }
+ break;
+ }
+
+ case TM_NAMES: /* magick names ?type? */
+ {
+ int type = TM_TYPE_ANY;
+ TclMagickObj *mPtr;
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch search;
+
+ if( objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?type?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ if (Tcl_GetIndexFromObj(interp, objv[2], objTypeNames, "type", 0, &type) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+ hPtr = Tcl_FirstHashEntry(&TM.hashTable, &search);
+ for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ mPtr = Tcl_GetHashValue(hPtr);
+ if( (type == TM_TYPE_ANY) || (type == mPtr->type) ) {
+ Tcl_AppendElement(interp, getMagickObjName(mPtr));
+ }
+ }
+ break;
+ }
+
+ case TM_TYPE: /* magick type name */
+ {
+ char *name;
+ TclMagickObj *mPtr;
+
+ if( objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ mPtr = findMagickObj(interp, TM_TYPE_ANY, name);
+ if (mPtr == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_SetResult(interp, (char *)objTypeNames[mPtr->type], TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_TYPES: /* magick types */
+ {
+ int type;
+
+ if( objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ for ( type = 0; type < TM_TYPE_ANY; type++ ) {
+ Tcl_AppendElement(interp, objTypeNames[type]);
+ }
+ break;
+ }
+
+ case TM_RESOURCE: /* resourcelimit resourceType ?limit? */
+ {
+ long limit;
+ int resourceIdx;
+
+ if( (objc != 3) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "resourceType ?limit?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], resourceNames,
+ "resourceType", 0, &resourceIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ /*
+ * Set channel depth
+ */
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], &limit)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickSetResourceLimit(resourceTypes[resourceIdx], (unsigned long) limit);
+ if (!result) {
+ return myMagickError(interp, NULL);
+ }
+ } else {
+ /*
+ * Get channel depth
+ */
+ limit = MagickGetResourceLimit(resourceTypes[resourceIdx]);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((long)limit));
+ }
+ break;
+ }
+
+ case TM_FONTS: /* fonts pattern */
+ {
+ unsigned long i;
+ unsigned long listLen = 0;
+ Tcl_Obj *listPtr;
+ char *pattern = "*";
+ char **fonts;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ pattern = Tcl_GetString(objv[2]);
+ }
+
+ fonts = MagickQueryFonts(pattern, &listLen);
+ if( (fonts != NULL) && (listLen > 0) ) {
+ listPtr = Tcl_NewListObj(0, NULL);
+ for( i=0; i < listLen; i++ ) {
+ Tcl_ListObjAppendElement(interp, listPtr,
+ Tcl_NewStringObj(fonts[i], (int)strlen(fonts[i])) );
+ }
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ if (fonts != NULL)
+ MagickRelinquishMemory(fonts); /* Free TclMagick resource */
+
+ break;
+ }
+
+ case TM_FORMATS: /* formats pattern */
+ {
+ unsigned long i;
+ unsigned long listLen = 0;
+ Tcl_Obj *listPtr;
+ char *pattern = "*";
+ char **fonts;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ pattern = Tcl_GetString(objv[2]);
+ }
+
+ fonts = MagickQueryFormats(pattern, &listLen);
+ if( (fonts != NULL) && (listLen > 0) ) {
+ listPtr = Tcl_NewListObj(0, NULL);
+ for( i=0; i < listLen; i++ ) {
+ Tcl_ListObjAppendElement(interp, listPtr,
+ Tcl_NewStringObj(fonts[i], (int)strlen(fonts[i])) );
+ }
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ if (fonts != NULL)
+ MagickRelinquishMemory(fonts); /* Free TclMagick resource */
+
+ break;
+ }
+
+ case TM_VERSION: /* magick version */
+ {
+ if( objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ Tcl_SetResult(interp, VERSION, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_LIBRARY: /* magick library ?-option? */
+ {
+ static CONST char *options[] = {
+ "-copyright", "-date", "-name", "-quantumdepth",
+ "-url", "-version", "-versionstr", "-maxrgb",
+ (char *) NULL
+ };
+ char buf[40];
+ const char *str;
+ unsigned long depth=0, version=0, maxrgb=0;
+
+ if( objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-option?");
+ return TCL_ERROR;
+ }
+ /*
+ * If called without parameters, return a list of
+ * -option value -option value ...
+ */
+ if( objc == 2 ) {
+ Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);
+
+ str = MagickGetCopyright();
+ Tcl_ListObjAppendElement(
+ interp, listPtr,
+ Tcl_NewStringObj(options[0], -1));
+ Tcl_ListObjAppendElement(
+ interp, listPtr, Tcl_NewStringObj(str, -1));
+
+ str = MagickGetReleaseDate();
+ Tcl_ListObjAppendElement(
+ interp, listPtr,
+ Tcl_NewStringObj(options[1], -1));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(str, -1));
+
+ str = MagickGetPackageName();
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(options[2], -1));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(str, -1));
+
+ str = MagickGetQuantumDepth(&depth);
+ maxrgb = (1 << depth) - 1;
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(options[3], -1));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj((signed long)depth));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(options[7], -1));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj((signed long)maxrgb));
+
+ str = MagickGetHomeURL();
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(options[4], -1));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(str, -1));
+
+ str = MagickGetVersion(&version);
+ sprintf( buf, "%ld.%ld.%ld", version >> 8, (version >> 4) & 0x0F, version & 0x0F);
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(options[5], -1));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(buf, -1));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(options[6], -1));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(str, -1));
+
+
+ Tcl_SetObjResult(interp, listPtr);
+ } else {
+ int idx;
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], options, "-option", 0, &idx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch( idx ) {
+ case 0: /* -copyright */
+ str = MagickGetCopyright();
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(str, -1));
+ break;
+ case 1: /* -date */
+ str = MagickGetReleaseDate();
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(str, -1));
+ break;
+ case 2: /* -name */
+ str = MagickGetPackageName();
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(str, -1));
+ break;
+ case 3: /* -quantumdepth */
+ MagickGetQuantumDepth(&depth);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((signed long)depth));
+ break;
+ case 4: /* -url */
+ str = MagickGetHomeURL();
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(str, -1));
+ break;
+ case 5: /* -version */
+ MagickGetVersion(&version);
+ sprintf( buf, "%ld.%ld.%ld", version >> 8, (version >> 4) & 0x0F, version & 0x0F);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
+ break;
+ case 6: /* -versionstr */
+ str = MagickGetVersion(&version);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(str, -1));
+ break;
+ case 7: /* -maxrgb */
+ MagickGetQuantumDepth(&depth);
+ maxrgb = (1 << depth) - 1;
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((signed long)maxrgb));
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ break;
+ }
+
+ } /* switch(index) */
+
+ return(TCL_OK);
+}
+
+
+/*----------------------------------------------------------------------
+ * MagickWand object command
+ *----------------------------------------------------------------------
+ *
+ * MagickWand subcmd ?args?
+ *
+ *----------------------------------------------------------------------
+ */
+static int wandObjCmd(
+ ClientData clientData, /* MagickWand pointer */
+ Tcl_Interp *interp, /* Interpreter containing image */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] ) /* List of arguments */
+{
+ static CONST char *subCmds[] = {
+ "adaptivethreshold","AdaptiveThresholdImage",
+ "add", "AddImage",
+ "addnoise", "AddNoiseImage",
+ "affinetransform", "AffineTransformImage",
+ "annotate", "AnnotateImage",
+ "append", "AppendImages",
+ "average", "AverageImages",
+ "blackthreshold", "BlackThresholdImage",
+ "blur", "BlurImage",
+ "border", "BorderImage",
+ "charcoal", "CharcoalImage",
+ "chop", "ChopImage",
+ "clip", "ClipImage",
+ "clippath", "ClipPathImage",
+ "clone", "CloneWand",
+ "coalesce", "CoalesceImages",
+ "colorfloodfill", "ColorFloodfillImage",
+ "colorize", "ColorizeImage",
+ "comment", "CommentImage",
+ "comparechannels", "CompareImageChannels",
+ "compare", "CompareImages",
+ "composite", "CompositeImage",
+ "contrast", "ContrastImage",
+ "convolve", "ConvolveImage",
+ "crop", "CropImage",
+ "cyclecolormap", "CycleColormapImage",
+ "deconstruct", "DeconstructImages",
+ "describe", "DescribeImage",
+ "despeckle", "DespeckleImage",
+ "draw", "DrawImage",
+ "edge", "EdgeImage",
+ "emboss", "EmbossImage",
+ "enhance", "EnhanceImage",
+ "equalize", "EqualizeImage",
+ "flatten", "FlattenImages",
+ "flip", "FlipImage",
+ "flop", "FlopImage",
+ "frame", "FrameImage",
+ "fx", "FxImage",
+ "fxchannel", "FxImageChannel",
+ "gammaimage", "GammaImage",
+ "gammachannel", "GammaImageChannel",
+ "filename", "GetFilename", "SetFilename",
+ "backgroundcolor", "GetBackgroundColor", "SetBackgroundColor",
+ "blueprimary", "GetBluePrimary", "SetBluePrimary",
+ "bordercolor", "GetBorderColor", "SetBorderColor",
+ "channeldepth", "GetChannelDepth", "SetChannelDepth",
+ "channelextrema", "GetChannelExtrema",
+ "channelmean", "GetChannelMean",
+ "colormapcolor", "GetColormapColor", "SetColormapColor",
+ "colors", "GetColors",
+ "colorspace", "GetColorspace", "SetColorspace",
+ "compose", "GetCompose", "SetCompose",
+ "compression", "GetCompression", "SetCompression",
+ "delay", "GetDelay", "SetDelay",
+ "depth", "GetDepth", "SetDepth",
+ "dispose", "GetDispose", "SetDispose",
+ "extrema", "GetExtrema",
+ "format", "GetFormat", "SetFormat",
+ "getimage", "GetImage",
+ "imagefilename", "GetImageFilename", "SetImageFilename",
+ "gamma", "GetGamma", "SetGamma",
+ "greenprimary", "GetGreenPrimary", "SetGreenPrimary",
+ "height", "GetHeight",
+ "index", "GetIndex", "SetIndex",
+ "interlace", "GetInterlaceScheme", "SetInterlaceScheme",
+ "iterations", "GetIterations", "SetIterations",
+ "mattecolor", "GetMatteColor", "SetMatteColor",
+ "pixels", "GetPixels", "SetPixels",
+ "profile", "GetProfile", "SetProfile",
+ "ProfileImage", "RemoveProfile",
+ "redprimary", "GetRedPrimary", "SetRedPrimary",
+ "renderingintent", "GetRenderingIntent", "SetRenderingIntent",
+ "resolution", "GetResolution", "SetResolution",
+ "scene", "GetScene", "SetScene",
+ "signature", "GetSignature",
+ "imagesize", "GetImageSize",
+ "imagetype", "GetImageType", "SetImageType",
+ "imageunits", "GetImageUnits", "SetImageUnits",
+ "virtualpixelmethod","GetVirtualPixelMethod","SetVirtualPixelMethod",
+ "whitepoint", "GetWhitePoint", "SetWhitePoint",
+ "width", "GetWidth",
+ "number", "GetNumberImages",
+ "samplingfactors", "GetSamplingFactors", "SetSamplingFactors",
+ "size", "GetSize", "SetSize",
+ "hasnext", "HasNext",
+ "hasprevious", "HasPrevious",
+ "implode", "ImplodeImage",
+ "label", "LabelImage",
+ "level", "LevelImage",
+ "levelchannel", "LevelImageChannel",
+ "magnify", "MagnifyImage",
+ "map", "MapImage",
+ "mattefloodfill", "MatteFloodfillImage",
+ "medianfilter", "MedianFilterImage",
+ "minify", "MinifyImage",
+ "modulate", "ModulateImage",
+ "montage", "MontageImage",
+ "morph", "MorphImages",
+ "mosaic", "MosaicImages",
+ "motionblur", "MotionBlurImage",
+ "negate", "NegateImage",
+ "negatechannel", "NegateImageChannel",
+ "next", "NextImage",
+ "normalize", "NormalizeImage",
+ "oilpaint", "OilPaintImage",
+ "opaque", "OpaqueImage",
+ "ping", "PingImage",
+ "preview", "PreviewImages",
+ "previous", "PreviousImage",
+ "quantize", "QuantizeImage", "QuantizeImages",
+ "queryfontmetrics", "QueryFontMetrics",
+ "raise", "RaiseImage",
+ "read", "ReadImage",
+ "readblob", "ReadImageBlob",
+ "reducenoise", "ReduceNoiseImage",
+ "remove", "RemoveImage",
+ "resetiterator", "ResetIterator",
+ "resample", "ResampleImage",
+ "resize", "ResizeImage",
+ "roll", "RollImage",
+ "rotate", "RotateImage",
+ "sample", "SampleImage",
+ "scale", "ScaleImage",
+ "separate", "SeparateImageChannel",
+ "setimage", "SetImage",
+ "setoption", "SetOption",
+ "passphrase", "SetPassphrase",
+ "sharpen", "SharpenImage",
+ "shave", "ShaveImage",
+ "shear", "ShearImage",
+ "solarize", "SolarizeImage",
+ "spread", "SpreadImage",
+ "stegano", "SteganoImage",
+ "stereo", "StereoImage",
+ "strip", "StripImage",
+ "swirl", "SwirlImage",
+ "texture", "TextureImage",
+ "threshold", "ThresholdImage",
+ "thresholdchannel", "ThresholdImageChannel",
+ "tint", "TintImage",
+ "transform", "TransformImage",
+ "transparent", "TransparentImage",
+ "trim", "TrimImage",
+ "unsharpmask", "UnsharpMaskImage",
+ "wave", "WaveImage",
+ "whitethreshold", "WhiteThresholdImage",
+ "write", "WriteImage", "WriteImages",
+ "writeblob", "WriteImageBlob",
+ (char *) NULL
+ };
+ enum subIndex {
+ TM_ADAPTIVE, TM_ADAPTIVE_THRESHOLD_IMAGE,
+ TM_ADD, TM_ADD_IMAGE,
+ TM_ADDNOISE, TM_ADD_NOISE_IMAGE,
+ TM_AFFINE_TRANSFORM,TM_AFFINE_TRANSFORM_IMAGE,
+ TM_ANNOTATE, TM_ANNOTATE_IMAGE,
+ TM_APPEND, TM_APPEND_IMAGES,
+ TM_AVERAGE, TM_AVERAGE_IMAGES,
+ TM_BLACK_THRESHOLD, TM_BLACK_THRESHOLD_IMAGE,
+ TM_BLUR, TM_BLUR_IMAGE,
+ TM_BORDER, TM_BORDER_IMAGE,
+ TM_CHARCOAL, TM_CHARCOAL_IMAGE,
+ TM_CHOP, TM_CHOP_IMAGE,
+ TM_CLIP, TM_CLIP_IMAGE,
+ TM_CLIP_PATH, TM_CLIP_PATH_IMAGE,
+ TM_CLONE, TM_CLONE_WAND,
+ TM_COALESCE, TM_COALESCE_IMAGES,
+ TM_COLOR_FLOODFILL, TM_COLOR_FLOODFILL_IMAGE,
+ TM_COLORIZE, TM_COLORIZE_IMAGE,
+ TM_COMMENT, TM_COMMENT_IMAGE,
+ TM_COMPARE_CHANNELS,TM_COMPARE_IMAGE_CHANNELS,
+ TM_COMPARE, TM_COMPARE_IMAGES,
+ TM_COMPOSITE, TM_COMPOSITE_IMAGE,
+ TM_CONTRAST, TM_CONTRAST_IMAGE,
+ TM_CONVOLVE, TM_CONVOLVE_IMAGE,
+ TM_CROP, TM_CROP_IMAGE,
+ TM_CYCLE_COLORMAP, TM_CYCLE_COLORMAP_IMAGE,
+ TM_DECONSTRUCT, TM_DECONSTRUCT_IMAGES,
+ TM_DESCRIBE, TM_DESCRIBE_IMAGE,
+ TM_DESPECKLE, TM_DESPECKLE_IMAGE,
+ TM_DRAW, TM_DRAW_IMAGE,
+ TM_EDGE, TM_EDGE_IMAGE,
+ TM_EMBOSS, TM_EMBOSS_IMAGE,
+ TM_ENHANCE, TM_ENHANCE_IMAGE,
+ TM_EQUALIZE, TM_EQUALIZE_IMAGE,
+ TM_FLATTEN, TM_FLATTEN_IMAGES,
+ TM_FLIP, TM_FLIP_IMAGE,
+ TM_FLOP, TM_FLOP_IMAGE,
+ TM_FRAME, TM_FRAME_IMAGE,
+ TM_FX, TM_FX_IMAGE,
+ TM_FX_CHANNEL, TM_FX_IMAGE_CHANNEL,
+ TM_GAMMAIMAGE, TM_GAMMA_IMAGE,
+ TM_GAMMACHANNEL, TM_GAMMA_IMAGE_CHANNEL,
+ TM_FILENAME, TM_GET_FILENAME, TM_SET_FILENAME,
+ TM_BACKGROUND_COLOR,TM_GET_BACKGROUND_COLOR, TM_SET_BACKGROUND_COLOR,
+ TM_BLUE_PRIMARY, TM_GET_BLUE_PRIMARY, TM_SET_BLUE_PRIMARY,
+ TM_BORDER_COLOR, TM_GET_BORDER_COLOR, TM_SET_BORDER_COLOR,
+ TM_CHANNEL_DEPTH, TM_GET_CHANNEL_DEPTH, TM_SET_CHANNEL_DEPTH,
+ TM_CHANNEL_EXTREMA, TM_GET_CHANNEL_EXTREMA,
+ TM_CHANNEL_MEAN, TM_GET_CHANNEL_MEAN,
+ TM_COLORMAP_COLOR, TM_GET_COLORMAP_COLOR, TM_SET_COLORMAP_COLOR,
+ TM_COLORS, TM_GET_COLORS,
+ TM_COLORSPACE, TM_GET_COLORSPACE, TM_SET_COLORSPACE,
+ TM_COMPOSE, TM_GET_COMPOSE, TM_SET_COMPOSE,
+ TM_COMPRESSION, TM_GET_COMPRESSION, TM_SET_COMPRESSION,
+ TM_DELAY, TM_GET_DELAY, TM_SET_DELAY,
+ TM_DEPTH, TM_GET_DEPTH, TM_SET_DEPTH,
+ TM_DISPOSE, TM_GET_DISPOSE, TM_SET_DISPOSE,
+ TM_EXTREMA, TM_GET_EXTREMA,
+ TM_FORMAT, TM_GET_FORMAT, TM_SET_FORMAT,
+ TM_GETIMAGE, TM_GET_IMAGE,
+ TM_IMAGE_FILENAME, TM_GET_IMAGE_FILENAME, TM_SET_IMAGE_FILENAME,
+ TM_GAMMA, TM_GET_GAMMA, TM_SET_GAMMA,
+ TM_GREEN_PRIMARY, TM_GET_GREEN_PRIMARY, TM_SET_GREEN_PRIMARY,
+ TM_HEIGHT, TM_GET_HEIGHT,
+ TM_INDEX, TM_GET_INDEX, TM_SET_INDEX,
+ TM_INTERLACE, TM_GET_INTERLACE, TM_SET_INTERLACE,
+ TM_ITERATIONS, TM_GET_ITERATIONS, TM_SET_ITERATIONS,
+ TM_MATTE_COLOR, TM_GET_MATTE_COLOR, TM_SET_MATTE_COLOR,
+ TM_PIXELS, TM_GET_PIXELS, TM_SET_PIXELS,
+ TM_PROFILE, TM_GET_PROFILE, TM_SET_PROFILE,
+ TM_PROFILE_IMAGE, TM_REMOVE_PROFILE,
+ TM_RED_PRIMARY, TM_GET_RED_PRIMARY, TM_SET_RED_PRIMARY,
+ TM_RENDERING, TM_GET_RENDERING, TM_SET_RENDERING,
+ TM_RESOLUTION, TM_GET_RESOLUTION, TM_SET_RESOLUTION,
+ TM_SCENE, TM_GET_SCENE, TM_SET_SCENE,
+ TM_SIGNATURE, TM_GET_SIGNATURE,
+ TM_IMAGE_SIZE, TM_GET_IMAGE_SIZE,
+ TM_IMAGE_TYPE, TM_GET_IMAGE_TYPE, TM_SET_IMAGE_TYPE,
+ TM_IMAGE_UNITS, TM_GET_IMAGE_UNITS, TM_SET_IMAGE_UNITS,
+ TM_VIRTUALPIXEL, TM_GET_VIRTUALPIXEL, TM_SET_VIRTUALPIXEL,
+ TM_WHITE_POINT, TM_GET_WHITE_POINT, TM_SET_WHITE_POINT,
+ TM_WIDTH, TM_GET_WIDTH,
+ TM_NUMBER, TM_GET_NUMBER_IMAGES,
+ TM_SAMPLING_FACTORS,TM_GET_SAMPLING_FACTORS, TM_SET_SAMPLING_FACTORS,
+ TM_SIZE, TM_GET_SIZE, TM_SET_SIZE,
+ TM_HASNEXT, TM_HAS_NEXT_IMAGE,
+ TM_HASPREVIOUS, TM_HAS_PREVIOUS_IMAGE,
+ TM_IMPLODE, TM_IMPLODE_IMAGE,
+ TM_LABEL, TM_LABEL_IMAGE,
+ TM_LEVEL, TM_LEVEL_IMAGE,
+ TM_LEVEL_CHANNEL, TM_LEVEL_IMAGE_CHANNEL,
+ TM_MAGNIFY, TM_MAGNIFY_IMAGE,
+ TM_MAP, TM_MAP_IMAGE,
+ TM_MATTE_FLOODFILL, TM_MATTE_FLOODFILL_IMAGE,
+ TM_MEDIANFILTER, TM_MEDIANFILTER_IMAGE,
+ TM_MINIFY, TM_MINIFY_IMAGE,
+ TM_MODULATE, TM_MODULATE_IMAGE,
+ TM_MONTAGE, TM_MONTAGE_IMAGE,
+ TM_MORPH, TM_MORPH_IMAGES,
+ TM_MOSAIC, TM_MOSAIC_IMAGES,
+ TM_MOTIONBLUR, TM_MOTIONBLUR_IMAGE,
+ TM_NEGATE, TM_NEGATE_IMAGE,
+ TM_NEGATE_CHANNEL, TM_NEGATE_IMAGE_CHANNEL,
+ TM_NEXT, TM_NEXT_IMAGE,
+ TM_NORMALIZE, TM_NORMALIZE_IMAGE,
+ TM_OILPAINT, TM_OILPAINT_IMAGE,
+ TM_OPAQUE, TM_OPAQUE_IMAGE,
+ TM_PING, TM_PING_IMAGE,
+ TM_PREVIEW, TM_PREVIEW_IMAGES,
+ TM_PREVIOUS, TM_PREVIOUS_IMAGE,
+ TM_QUANTIZE, TM_QUANTIZE_IMAGE, TM_QUANTIZE_IMAGES,
+ TM_QUERYFONTMETRICS,TM_QUERY_FONT_METRICS,
+ TM_RAISE, TM_RAISE_IMAGE,
+ TM_READ, TM_READ_IMAGE,
+ TM_READ_BLOB, TM_READ_IMAGE_BLOB,
+ TM_REDUCENOISE, TM_REDUCENOISE_IMAGE,
+ TM_REMOVE, TM_REMOVE_IMAGE,
+ TM_RESETITERATOR, TM_RESET_ITERATOR,
+ TM_RESAMPLE, TM_RESAMPLE_IMAGE,
+ TM_RESIZE, TM_RESIZE_IMAGE,
+ TM_ROLL, TM_ROLL_IMAGE,
+ TM_ROTATE, TM_ROTATE_IMAGE,
+ TM_SAMPLE, TM_SAMPLE_IMAGE,
+ TM_SCALE, TM_SCALE_IMAGE,
+ TM_SEPARATE, TM_SEPARATE_CHANNEL,
+ TM_SETIMAGE, TM_SET_IMAGE,
+ TM_SETOPTION, TM_SET_OPTION,
+ TM_PASSPHRASE, TM_SET_PASSPHRASE,
+ TM_SHARPEN, TM_SHARPEN_IMAGE,
+ TM_SHAVE, TM_SHAVE_IMAGE,
+ TM_SHEAR, TM_SHEAR_IMAGE,
+ TM_SOLARIZE, TM_SOLARIZE_IMAGE,
+ TM_SPREAD, TM_SPREAD_IMAGE,
+ TM_STEGANO, TM_STEGANO_IMAGE,
+ TM_STEREO, TM_STEREO_IMAGE,
+ TM_STRIP, TM_STRIP_IMAGE,
+ TM_SWIRL, TM_SWIRL_IMAGE,
+ TM_TEXTURE, TM_TEXTURE_IMAGE,
+ TM_THRESHOLD, TM_THRESHOLD_IMAGE,
+ TM_THRESHOLDCHANNEL,TM_THRESHOLD_IMAGE_CHANNEL,
+ TM_TINT, TM_TINT_IMAGE,
+ TM_TRANSFORM, TM_TRANSFORM_IMAGE,
+ TM_TRANSPARENT, TM_TRANSPARENT_IMAGE,
+ TM_TRIM, TM_TRIM_IMAGE,
+ TM_UNSHARPMASK, TM_UNSHARPMASK_IMAGE,
+ TM_WAVE, TM_WAVE_IMAGE,
+ TM_WHITE_THRESHOLD, TM_WHITE_THRESHOLD_IMAGE,
+ TM_WRITE, TM_WRITE_IMAGE, TM_WRITE_IMAGES,
+ TM_WRITE_BLOB, TM_WRITE_IMAGE_BLOB,
+ TM_END_OF_TABLE
+ };
+ static CONST char *filterNames[] = {
+ "undefined", "point", "box", "triangle", "hermite",
+ "hanning", "hamming", "blackman", "gaussian", "quadratic",
+ "cubic", "catrom", "mitchell", "lanczos", "bessel",
+ "sinc",
+ (char *) NULL
+ };
+ static FilterTypes filterTypes[] = {
+ UndefinedFilter, PointFilter, BoxFilter, TriangleFilter, HermiteFilter,
+ HanningFilter, HammingFilter, BlackmanFilter, GaussianFilter, QuadraticFilter,
+ CubicFilter, CatromFilter, MitchellFilter, LanczosFilter, BesselFilter,
+ SincFilter
+ };
+ static CONST char *chanNames[] = {
+ "undefined", "red", "cyan", "green", "magenta",
+ "blue", "yellow", "opacity", "black", "matte",
+ "index",
+ (char *) NULL
+ };
+ static ChannelType chanTypes[] = {
+ UndefinedChannel, RedChannel, CyanChannel, GreenChannel, MagentaChannel,
+ BlueChannel, YellowChannel, OpacityChannel, BlackChannel, MatteChannel,
+ IndexChannel
+ };
+ static CONST char *metricNames[] = {
+ "meanabsoluteerror", "meansquarederror", "peakabsoluteerror",
+ "peaksignaltonoiseratio", "rootmeansquarederror",
+ (char *) NULL
+ };
+ static ChannelType metricTypes[] = {
+ MeanAbsoluteErrorMetric, MeanSquaredErrorMetric, PeakAbsoluteErrorMetric,
+ PeakSignalToNoiseRatioMetric, RootMeanSquaredErrorMetric
+ };
+ static CONST char *csNames[] = {
+ "undefined", "RGB", "GRAY", "transparent",
+ "OHTA", "LAB", "XYZ", "YCbCr",
+ "YCC", "YIQ", "YPbPr", "YUV",
+ "CMYK", "sRGB", "HSL", "HWB",
+ (char *) NULL
+ };
+ static ColorspaceType csTypes[] = {
+ UndefinedColorspace, RGBColorspace, GRAYColorspace, TransparentColorspace,
+ OHTAColorspace, LABColorspace, XYZColorspace, YCbCrColorspace,
+ YCCColorspace, YIQColorspace, YPbPrColorspace, YUVColorspace,
+ CMYKColorspace, sRGBColorspace, HSLColorspace, HWBColorspace
+ };
+ static CONST char *opNames[] = {
+ "undefined", "over", "in", "out",
+ "atop", "xor", "plus", "minus",
+ "add", "subtract", "difference", "multiply",
+ "bumpmap", "copy", "copyred", "copygreen",
+ "copyblue", "copyopacity", "clear", "dissolve"
+ "displace", "modulate", "threshold", "no",
+ "darken", "lighten", "hue", "saturate",
+ "colorize", "luminize", "screen", "overlay",
+ "copycyan", "copymagenta", "copyyellow", "copyblack",
+ "divide", "hardlight", "exclusion", "colordodge",
+ "colorburn", "softlight", "linearburn", "lineardodge",
+ "linearlight","vividlight", "pinlight", "hardmix",
+ (char *) NULL
+ };
+ static CompositeOperator opTypes[] = {
+ UndefinedCompositeOp, OverCompositeOp, InCompositeOp, OutCompositeOp,
+ AtopCompositeOp, XorCompositeOp, PlusCompositeOp, MinusCompositeOp,
+ AddCompositeOp, SubtractCompositeOp, DifferenceCompositeOp, MultiplyCompositeOp,
+ BumpmapCompositeOp, CopyCompositeOp, CopyRedCompositeOp, CopyGreenCompositeOp,
+ CopyBlueCompositeOp, CopyOpacityCompositeOp, ClearCompositeOp, DissolveCompositeOp,
+ DisplaceCompositeOp, ModulateCompositeOp, ThresholdCompositeOp, NoCompositeOp,
+ DarkenCompositeOp, LightenCompositeOp, HueCompositeOp, SaturateCompositeOp,
+ ColorizeCompositeOp, LuminizeCompositeOp, ScreenCompositeOp, OverlayCompositeOp,
+ CopyCyanCompositeOp, CopyMagentaCompositeOp, CopyYellowCompositeOp, CopyBlackCompositeOp,
+ DivideCompositeOp, HardLightCompositeOp, ExclusionCompositeOp, ColorDodgeCompositeOp,
+ ColorBurnCompositeOp, SoftLightCompositeOp, LinearBurnCompositeOp, LinearDodgeCompositeOp,
+ LinearLightCompositeOp,VividLightCompositeOp, PinLightCompositeOp, HardMixCompositeOp
+ };
+ static CONST char *compressNames[] = {
+ "undefined", "none", "bzip",
+ "fax", "group4", "jpeg",
+ "jpeg-ls", "lzw", "rle",
+ "zip"
+#if MagickLibInterfaceNewest > 9
+ /* These enumerations are introduced by GraphicsMagick 1.3.13 */
+ , "lzma", "jpeg2000", "jbig1", "jbig2"
+#endif /* MagickLibInterfaceNewest > 9 */
+ ,(char *) NULL
+ };
+ static CompressionType compressTypes[] = {
+ UndefinedCompression, NoCompression, BZipCompression,
+ FaxCompression, Group4Compression, JPEGCompression,
+ LosslessJPEGCompression, LZWCompression, RLECompression,
+ ZipCompression
+#if MagickLibInterfaceNewest > 9
+ /* These enumerations are introduced by GraphicsMagick 1.3.13 */
+ ,LZMACompression, JPEG2000Compression,
+ JBIG1Compression, JBIG2Compression
+#endif /* MagickLibInterfaceNewest > 9 */
+ };
+ static CONST char *disposeNames[] = {
+ "undefined", "none", "background", "previous",
+ (char *) NULL
+ };
+ static DisposeType disposeTypes[] = {
+ UndefinedDispose, NoneDispose, BackgroundDispose, PreviousDispose
+ };
+ static CONST char *interlaceNames[] = {
+ "undefined", "none", "line", "plane", "partition",
+ (char *) NULL
+ };
+ static InterlaceType interlaceTypes[] = {
+ UndefinedInterlace, NoInterlace, LineInterlace, PlaneInterlace, PartitionInterlace,
+ };
+ static CONST char *renderNames[] = {
+ "undefined", "saturation", "perceptual", "absolute", "relative",
+ (char *) NULL
+ };
+ static RenderingIntent renderTypes[] = {
+ UndefinedIntent, SaturationIntent, PerceptualIntent, AbsoluteIntent, RelativeIntent
+ };
+ static CONST char *typeNames[] = {
+ "undefined", "bilevel", "grayscale",
+ "grayscalematte", "palette", "palettematte",
+ "truecolor", "truecolormatte", "colorseparation",
+ "colorseparationmatte", "optimize",
+ (char *) NULL
+ };
+ static ImageType typeTypes[] = {
+ UndefinedType, BilevelType, GrayscaleType,
+ GrayscaleMatteType, PaletteType, PaletteMatteType,
+ TrueColorType, TrueColorMatteType, ColorSeparationType,
+ ColorSeparationMatteType, OptimizeType
+ };
+ static CONST char *unitNames[] = {
+ "undefined", "ppi", "ppcm",
+ (char *) NULL
+ };
+ static ResolutionType unitTypes[] = {
+ UndefinedResolution, PixelsPerInchResolution, PixelsPerCentimeterResolution
+ };
+ static CONST char *methodNames[] = {
+ "undefined", "constant", "edge",
+ "mirror", "tile",
+ (char *) NULL
+ };
+ static VirtualPixelMethod methodTypes[] = {
+ UndefinedVirtualPixelMethod, ConstantVirtualPixelMethod, EdgeVirtualPixelMethod,
+ MirrorVirtualPixelMethod, TileVirtualPixelMethod
+ };
+ static CONST char *previewNames[] = {
+ "undefined", "rotate", "shear", "roll",
+ "hue", "saturation", "brightness", "gamma",
+ "spiff", "dull", "grayscale", "quantize",
+ "despeckle", "reducenoise", "addnoise", "sharpen",
+ "blur", "threshold", "edgedetect", "spread",
+ "solarize", "shade", "raise", "segment",
+ "swirl", "implode", "wave", "oilpaint",
+ "charcoal", "jpeg",
+ (char *) NULL
+ };
+ static PreviewType previewTypes[] = {
+ UndefinedPreview, RotatePreview, ShearPreview, RollPreview,
+ HuePreview, SaturationPreview, BrightnessPreview, GammaPreview,
+ SpiffPreview, DullPreview, GrayscalePreview, QuantizePreview,
+ DespecklePreview, ReduceNoisePreview, AddNoisePreview, SharpenPreview,
+ BlurPreview, ThresholdPreview, EdgeDetectPreview, SpreadPreview,
+ SolarizePreview, ShadePreview, RaisePreview, SegmentPreview,
+ SwirlPreview, ImplodePreview, WavePreview, OilPaintPreview,
+ CharcoalDrawingPreview, JPEGPreview
+ };
+
+ int index, stat, result=TCL_OK;
+ TclMagickObj *magickPtr = (TclMagickObj *) clientData;
+ MagickWand *wandPtr = (MagickWand *) magickPtr->wandPtr;
+
+#ifdef MAGICK_DEBUG
+ /*
+ * Verify subCmds table size
+ * No idea how to do this at compile-time
+ */
+ if( sizeof(subCmds)/sizeof(subCmds[0]) != TM_END_OF_TABLE + 1 ) {
+ Tcl_Panic("magickObjCmd: Invalid subCmds[] table");
+ }
+#endif
+
+ if( objc < 2 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "subcmd ?args?" );
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[1], subCmds, "subcmd", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum subIndex)index) {
+
+ case TM_ADAPTIVE: /* adaptive ?width? ?height? ?ofs? */
+ case TM_ADAPTIVE_THRESHOLD_IMAGE: /* AdaptiveThresholdImage ?width? ?height? ?ofs? */
+ {
+ unsigned long width=1, height=1;
+ long ofs=0;
+
+ if( (objc > 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?width? ?height? ?ofs?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &width)) != TCL_OK) ) {
+ return stat;
+ }
+ height = width; /* default */
+ if( (objc > 3) && ((stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &height)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetLongFromObj(interp, objv[4], &ofs)) != TCL_OK) ) {
+ return stat;
+ }
+
+ result = MagickAdaptiveThresholdImage(wandPtr, width, height, ofs);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_ADD: /* add name */
+ case TM_ADD_IMAGE: /* AddImage name */
+ {
+ MagickWand *addWand;
+ char *name;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (addWand = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ result = MagickAddImage( wandPtr, addWand );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+
+ break;
+ }
+
+ case TM_ADDNOISE: /* addnoise ?noiseType? */
+ case TM_ADD_NOISE_IMAGE: /* AddNoiseImage ?noiseType? */
+ {
+ static CONST char *noiseNames[] = {
+ "uniform", "gaussian", "multiplicativegaussian", "impulse", "laplacian", "poisson", "random",
+ (char *) NULL
+ };
+ static NoiseType noiseTypes[] = {
+ UniformNoise, GaussianNoise, MultiplicativeGaussianNoise, ImpulseNoise, LaplacianNoise, PoissonNoise, RandomNoise
+ };
+ int noiseIdx=0;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?noiseType=uniform?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && (Tcl_GetIndexFromObj(interp, objv[2], noiseNames, "noiseType", 0, &noiseIdx) != TCL_OK) ) {
+ return TCL_ERROR;
+ }
+ result = MagickAddNoiseImage(wandPtr, noiseTypes[noiseIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_AFFINE_TRANSFORM: /* affinetransform draw */
+ case TM_AFFINE_TRANSFORM_IMAGE: /* AffineTransformImage draw */
+ {
+ char *name;
+ DrawingWand *drawPtr;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "draw");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (drawPtr = findDrawingWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+
+ result = MagickAffineTransformImage(wandPtr, drawPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_ANNOTATE: /* annotate draw ?x y? ?angle? txt */
+ case TM_ANNOTATE_IMAGE: /* AnnotateImage draw ?x y? ?angle? txt */
+ {
+ char *name;
+ DrawingWand *drawPtr;
+ double x=0.0, y=0.0, angle=0.0;
+ char *txt="";
+
+ if( (objc < 4) || (objc > 7) || (objc == 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "draw ?x=0.0 y=0.0? ?angle=0.0? txt");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (drawPtr = findDrawingWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( objc >= 6 ) { /* we have parameters x y */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &y)) != TCL_OK ) {
+ return stat;
+ }
+ }
+ if( objc == 7 ) { /* we have parameter angle */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &angle)) != TCL_OK ) {
+ return stat;
+ }
+ }
+ txt = Tcl_GetString(objv[objc-1]);
+
+ result = MagickAnnotateImage(wandPtr, drawPtr, x, y, angle, txt);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_APPEND: /* append ?stack=0? ?newName? */
+ case TM_APPEND_IMAGES: /* AppendImages ?stack=0? ?newName? */
+ {
+ int stack=0;
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( objc > 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?stack=0? ?newName?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetBooleanFromObj(interp, objv[2], &stack)) != TCL_OK) ) {
+ return stat;
+ }
+ if( objc > 3 ) {
+ name = Tcl_GetString(objv[3]);
+ }
+ newWand = MagickAppendImages(wandPtr, stack);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_AVERAGE: /* average ?newName? */
+ case TM_AVERAGE_IMAGES: /* AverageImages ?newName? */
+ {
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ name = Tcl_GetString(objv[2]);
+ }
+ newWand = MagickAverageImages(wandPtr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+
+ case TM_BLACK_THRESHOLD: /* blackthreshold thresholdPixel */
+ case TM_BLACK_THRESHOLD_IMAGE: /* BlackThresholdImage thresholdPixel */
+ {
+ char *name;
+ PixelWand *threshPtr;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "thresholdPixel");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (threshPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+
+ result = MagickBlackThresholdImage(wandPtr, threshPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_BLUR: /* blur ?radius? ?sigma? */
+ case TM_BLUR_IMAGE: /* BlurImage ?radius? ?sigma? */
+ {
+ double radius=0.0, sigma=1.0;
+
+ if( objc > 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0? ?sigma=1.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &sigma)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickBlurImage(wandPtr, radius, sigma);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_BORDER: /* border borderPixel ?width? ?height? */
+ case TM_BORDER_IMAGE: /* BorderImage borderPixel ?width? ?height? */
+ {
+ unsigned long width=1, height=1;
+ char *name;
+ PixelWand *borderPtr;
+
+ if( (objc < 3) || (objc > 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "borderPixel ?width=1? ?height=width?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (borderPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &width)) != TCL_OK) ) {
+ return stat;
+ }
+ height = width; /* default */
+ if( (objc > 4) && ((stat = Tcl_GetLongFromObj(interp, objv[4], (long int *) &height)) != TCL_OK) ) {
+ return stat;
+ }
+
+ result = MagickBorderImage(wandPtr, borderPtr, width, height);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_CHARCOAL: /* charcoal ?radius? ?sigma? */
+ case TM_CHARCOAL_IMAGE: /* CharcoalImage ?radius? ?sigma? */
+ {
+ double radius=0.0, sigma=1.0;
+
+ if( objc > 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0? ?sigma=1.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &sigma)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickCharcoalImage(wandPtr, radius, sigma);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_CHOP: /* chop width height ?x y? */
+ case TM_CHOP_IMAGE: /* ChopImage width height ?x y? */
+ {
+ unsigned long width, height;
+ long x=0, y=0;
+
+ if( (objc < 4) || (objc > 6) || (objc == 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "width height ?x=0 y=0?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &width)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &height)) != TCL_OK ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetLongFromObj(interp, objv[4], &x)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetLongFromObj(interp, objv[5], &y)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickChopImage(wandPtr, width, height, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_CLIP: /* clip */
+ case TM_CLIP_IMAGE: /* ClipImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickClipImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+
+ case TM_CLIP_PATH: /* clip pathname ?inside=0? */
+ case TM_CLIP_PATH_IMAGE: /* ClipImage pathname ?inside=0? */
+ {
+ int inside=0;
+ char *pathname=NULL;
+
+ if( (objc < 3) || (objc > 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pathname ?inside=0?");
+ return TCL_ERROR;
+ }
+ pathname = Tcl_GetString(objv[2]);
+ if( (objc > 3) && ((stat = Tcl_GetBooleanFromObj(interp, objv[3], &inside)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickClipPathImage(wandPtr, pathname, inside );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_CLONE: /* clone ?newName? */
+ case TM_CLONE_WAND: /* CloneWand ?newName? */
+ {
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ name = Tcl_GetString(objv[2]);
+ }
+ newWand = CloneMagickWand(wandPtr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_COALESCE: /* coalesce ?newName? */
+ case TM_COALESCE_IMAGES: /* CoalesceImages ?newName? */
+ {
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ name = Tcl_GetString(objv[2]);
+ }
+ newWand = MagickCoalesceImages(wandPtr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_COLOR_FLOODFILL: /* colorfloodfill fillPixel ?fuzz? ?borderPix? ?x y? */
+ case TM_COLOR_FLOODFILL_IMAGE: /* ColorFloodfillImage ?fuzz? ?borderPix? ?x y? */
+ /* - empty borderPix is allowed */
+ {
+ int x=0, y=0;
+ double fuzz=0.0;
+ char *name;
+ PixelWand *fillPtr, *borderPtr = NULL;
+
+ if( (objc < 3) || (objc > 7) || (objc == 6) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "fillPixel ?fuzz=0.0? ?borderPix=fillPix? ?x=0 y=0?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (fillPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &fuzz)) != TCL_OK) ) {
+ return stat;
+ }
+ if( objc > 4 ) {
+ name = Tcl_GetString(objv[4]);
+ if( noWandObj(name) ) {
+ borderPtr = NULL;
+ } else if( (borderPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ }
+ if( (objc > 5) && ((stat = Tcl_GetIntFromObj(interp, objv[5], &x)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 6) && ((stat = Tcl_GetIntFromObj(interp, objv[6], &y)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickColorFloodfillImage(wandPtr, fillPtr, fuzz, borderPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_COLORIZE: /* colorize fillPixel opacityPixel */
+ case TM_COLORIZE_IMAGE: /* ColorizeImage fillPixel opacityPixel */
+ {
+ char *name;
+ PixelWand *fillPtr, *opacityPtr;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "fillPixel opacityPixel");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (fillPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[3]);
+ if( (opacityPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+
+ result = MagickColorizeImage(wandPtr, fillPtr, opacityPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_COMMENT: /* comment str */
+ case TM_COMMENT_IMAGE: /* CommentImage str */
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "str");
+ return TCL_ERROR;
+ }
+ result = MagickCommentImage(wandPtr, Tcl_GetString(objv[2]));
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+
+ break;
+ }
+
+ case TM_COMPARE_CHANNELS: /* comparechannels refName chan metric */
+ case TM_COMPARE_IMAGE_CHANNELS: /* CompareImageChannels refName chan metric */
+ {
+ MagickWand *refWand, *newWand;
+ int metricIdx, chanIdx;
+ char *name;
+ double value;
+
+ if( objc != 5 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "refName");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (refWand = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[3], chanNames,
+ "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[4], metricNames,
+ "metricType", 0, &metricIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ newWand = MagickCompareImageChannels( wandPtr, refWand, chanTypes[chanIdx],
+ metricTypes[metricIdx], &value );
+ if (newWand != NULL) {
+ DestroyMagickWand(newWand);
+ } else {
+ myMagickError(interp, wandPtr);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value));
+
+ break;
+ }
+
+ case TM_COMPARE: /* compare refName metric */
+ case TM_COMPARE_IMAGES: /* CompareImages refName metric */
+ {
+ MagickWand *refWand, *newWand;
+ int metricIdx;
+ char *name;
+ double value;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "refName metric");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (refWand = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[3], metricNames,
+ "metricType", 0, &metricIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ newWand = MagickCompareImages( wandPtr, refWand, metricTypes[metricIdx], &value );
+ if (newWand != NULL) {
+ DestroyMagickWand(newWand);
+ } else {
+ myMagickError(interp, wandPtr);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value));
+
+ break;
+ }
+
+ case TM_COMPOSITE: /* composite compWand opType ?x y? */
+ case TM_COMPOSITE_IMAGE: /* CompositeImage compWand opType ?x y? */
+ {
+ int opIdx;
+
+ char *name;
+ MagickWand *compPtr;
+ int x=0;
+ int y=0;
+
+ if( (objc < 4) || (objc > 6) || (objc == 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "opType compWand ?x=0 y=0?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (compPtr = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[3], opNames, "opType", 0, &opIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetIntFromObj(interp, objv[4], &x)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetIntFromObj(interp, objv[5], &y)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickCompositeImage(wandPtr, compPtr, opTypes[opIdx], x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+
+ break;
+ }
+
+ case TM_CONTRAST: /* contrast ?sharpen? */
+ case TM_CONTRAST_IMAGE: /* ContrastImage ?sharpen? */
+ {
+ int sharpen=1;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?sharpen=yes?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetBooleanFromObj(interp, objv[2], &sharpen)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickContrastImage(wandPtr, sharpen);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_CONVOLVE: /* convolve order kernelList */
+ case TM_CONVOLVE_IMAGE: /* ConvolveImage order kernelList */
+ {
+ int i, listLen;
+ unsigned long order;
+ double *kernel;
+ Tcl_Obj **listPtr;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "order kernelList");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &order)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_ListObjGetElements(interp, objv[3], &listLen, &listPtr)) != TCL_OK) {
+ return stat;
+ }
+ if( (unsigned long)listLen != order * order ) {
+ Tcl_AppendResult(
+ interp,
+ "ConvolveImage: Invalid kernelList length, should be = (order x order)", NULL);
+ return TCL_ERROR;
+ }
+ kernel = (double *)ckalloc(listLen * sizeof(double));
+ if( kernel == NULL ) {
+ Tcl_AppendResult(interp, "TclMagick: out of memory", NULL);
+ return TCL_ERROR;
+ }
+ for( i=0; i < listLen; i++ ) {
+ if( (stat = Tcl_GetDoubleFromObj(interp, listPtr[i], &kernel[i])) != TCL_OK) {
+ ckfree((char *)kernel);
+ return stat;
+ }
+ }
+
+ result = MagickConvolveImage(wandPtr, order, kernel);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_CROP: /* crop width height ?x y? */
+ case TM_CROP_IMAGE: /* CropImage width height ?x y? */
+ {
+ unsigned long width, height;
+ long x=0, y=0;
+
+ if( (objc < 4) || (objc > 6) || (objc == 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "width height ?x=0 y=0?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &width)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &height)) != TCL_OK ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetLongFromObj(interp, objv[4], &x)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetLongFromObj(interp, objv[5], &y)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickCropImage(wandPtr, width, height, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_CYCLE_COLORMAP: /* cyclecolormap ?displace? */
+ case TM_CYCLE_COLORMAP_IMAGE: /* CycleColormapImage ?displace? */
+ {
+ int displace=1;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?displace=1?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetIntFromObj(interp, objv[2], &displace)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickCycleColormapImage(wandPtr, displace);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_DECONSTRUCT: /* deconstruct ?newName? */
+ case TM_DECONSTRUCT_IMAGES: /* DeconstructImage ?newName? */
+ {
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ name = Tcl_GetString(objv[2]);
+ }
+ newWand = MagickDeconstructImages(wandPtr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_DESCRIBE: /* describe */
+ case TM_DESCRIBE_IMAGE: /* DescribeImage */
+ {
+ char *txt;
+
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ txt = MagickDescribeImage(wandPtr);
+ if(txt != NULL) {
+ Tcl_SetResult(interp, txt, TCL_VOLATILE);
+ MagickRelinquishMemory(txt); /* Free TclMagick resource */
+ }
+ break;
+ }
+
+ case TM_DESPECKLE: /* despeckle */
+ case TM_DESPECKLE_IMAGE: /* DespeckleImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickDespeckleImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_DRAW: /* draw draw */
+ case TM_DRAW_IMAGE: /* DrawImage draw */
+ {
+ char *name;
+ DrawingWand *drawPtr;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "draw");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (drawPtr = findDrawingWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ result = MagickDrawImage(wandPtr, drawPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_EDGE: /* edge ?radius? */
+ case TM_EDGE_IMAGE: /* EdgeImage ?radius? */
+ {
+ double radius=0.0;
+
+ if( objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickEdgeImage(wandPtr, radius);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_EMBOSS: /* emboss ?radius? ?sigma? */
+ case TM_EMBOSS_IMAGE: /* EmbossImage ?radius? ?sigma? */
+ {
+ double radius=0.0, sigma=1.0;
+
+ if( objc > 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0? ?sigma=1.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &sigma)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickEmbossImage(wandPtr, radius, sigma);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_ENHANCE: /* enhance */
+ case TM_ENHANCE_IMAGE: /* EnhanceImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickEnhanceImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_EQUALIZE: /* equalize */
+ case TM_EQUALIZE_IMAGE: /* EqualizeImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickEqualizeImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_FLATTEN: /* flatten ?newName? */
+ case TM_FLATTEN_IMAGES: /* FlattenImages ?newName? */
+ {
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ name = Tcl_GetString(objv[2]);
+ }
+ newWand = MagickFlattenImages(wandPtr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_FLIP: /* flip */
+ case TM_FLIP_IMAGE: /* FlipImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickFlipImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+
+ case TM_FLOP: /* flop */
+ case TM_FLOP_IMAGE: /* FlopImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickFlopImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_FRAME: /* frame framePixel ?width? ?height? ?inner? ?outer? */
+ case TM_FRAME_IMAGE: /* FrameImage framePixel ?width? ?height? ?inner? ?outer? */
+ {
+ unsigned long width=1, height=1;
+ long inner=0, outer=0;
+ char *name;
+ PixelWand *framePtr;
+
+ if( (objc < 3) || (objc > 7) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "framePixel ?width=1? ?height=width? ?inner=0? ?outer=inner?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (framePtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &width)) != TCL_OK) ) {
+ return stat;
+ }
+ height = width; /* default */
+ if( (objc > 4) && ((stat = Tcl_GetLongFromObj(interp, objv[4], (long int *) &height)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetLongFromObj(interp, objv[5], &inner)) != TCL_OK) ) {
+ return stat;
+ }
+ outer = inner; /* default */
+ if( (objc > 6) && ((stat = Tcl_GetLongFromObj(interp, objv[6], &outer)) != TCL_OK) ) {
+ return stat;
+ }
+
+ result = MagickFrameImage(wandPtr, framePtr, width, height, inner, outer);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_FX: /* fx expr ?newName? */
+ case TM_FX_IMAGE: /* fxImage expr ?newName? */
+ {
+ char *expr;
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( (objc != 3) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "expr ?newName?");
+ return TCL_ERROR;
+ }
+ expr = Tcl_GetString(objv[2]);
+
+ if( objc > 3 ) {
+ name = Tcl_GetString(objv[3]);
+ }
+ newWand = MagickFxImage(wandPtr, expr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_FX_CHANNEL: /* fxchannel channelType expr ?newName? */
+ case TM_FX_IMAGE_CHANNEL: /* fxImageChannel channelType expr ?newName? */
+ {
+ int chanIdx;
+ char *expr;
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( (objc != 4) && (objc != 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channelType expr ?newName?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ expr = Tcl_GetString(objv[3]);
+
+ if( objc > 4 ) {
+ name = Tcl_GetString(objv[4]);
+ }
+ newWand = MagickFxImageChannel(wandPtr, chanTypes[chanIdx], expr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_GAMMAIMAGE: /* gammaimage level */
+ case TM_GAMMA_IMAGE: /* GammaImage level */
+ {
+ double gamma;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "level");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &gamma) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickGammaImage(wandPtr, gamma);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_GAMMACHANNEL: /* gamma channelType level */
+ case TM_GAMMA_IMAGE_CHANNEL: /* GammaImage channelType level */
+ {
+ int chanIdx;
+ double gamma;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channelType level");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetDoubleFromObj(interp, objv[3], &gamma) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickGammaImageChannel(wandPtr, chanTypes[chanIdx], gamma);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_FILENAME: /* filename ?filename? */
+ case TM_GET_FILENAME: /* GetFilename */
+ case TM_SET_FILENAME: /* SetFilename filename */
+ {
+ char *filename;
+
+ if( ((enum subIndex)index == TM_FILENAME) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?filename?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_FILENAME) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_FILENAME) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "filename");
+ return TCL_ERROR;
+ }
+ if (objc > 2) { /* Set filename */
+ Tcl_DString extrep;
+
+ filename = Tcl_UtfToExternalDString (NULL, Tcl_GetString(objv[2]), -1, &extrep);
+ MagickSetFilename(wandPtr, filename);
+
+ Tcl_DStringFree (&extrep);
+ } else { /* Get filename */
+ filename = (char *)MagickGetFilename(wandPtr);
+ if(filename != NULL) {
+ SetResultAsExternalString(interp, filename);
+ MagickRelinquishMemory(filename); /* Free TclMagick resource */
+ }
+ }
+ break;
+ }
+
+ case TM_BACKGROUND_COLOR: /* backgroundcolor ?pixel? */
+ case TM_GET_BACKGROUND_COLOR: /* GetBackgroundColor ?pixel? */
+ case TM_SET_BACKGROUND_COLOR: /* SetBackgroundColor pixel */
+ {
+ char *name = NULL;
+ PixelWand *pixPtr = NULL;
+
+ if( ((enum subIndex)index == TM_SET_BACKGROUND_COLOR) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pixel");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index != TM_SET_BACKGROUND_COLOR) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?pixel?");
+ return TCL_ERROR;
+ }
+ if (objc > 2) { /* Set color / Get color with new name */
+ name = Tcl_GetString(objv[2]);
+ pixPtr = findPixelWand(interp, name);
+ }
+ /*
+ * SET color requires existing pixel object
+ */
+ if( ((enum subIndex)index == TM_SET_BACKGROUND_COLOR) && (pixPtr == NULL) ) {
+ return TCL_ERROR;
+ }
+ /*
+ * GET color if GET_COLOR or pixel object doesn't exists
+ * otherwise SET color
+ */
+ if( ((enum subIndex)index == TM_GET_BACKGROUND_COLOR) || (pixPtr == NULL) ) {
+ if( pixPtr == NULL ) {
+ pixPtr = NewPixelWand();
+ name = newPixelObj(interp, pixPtr, name );
+ }
+ result = MagickGetImageBackgroundColor( wandPtr, pixPtr );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+ } else {
+ result = MagickSetImageBackgroundColor( wandPtr, pixPtr );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ }
+ break;
+ }
+
+ case TM_BLUE_PRIMARY: /* blueprimary ?x y? */
+ case TM_GET_BLUE_PRIMARY: /* GetBluePrimary */
+ case TM_SET_BLUE_PRIMARY: /* SetBluePrimary x y */
+ {
+ double x, y;
+
+ if( ((enum subIndex)index == TM_BLUE_PRIMARY) && (objc != 2) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?x y?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_BLUE_PRIMARY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_BLUE_PRIMARY) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ /*
+ * Set primary = x y
+ */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickSetImageBluePrimary(wandPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get primary={x y}
+ */
+ Tcl_Obj *listPtr;
+
+ result = MagickGetImageBluePrimary(wandPtr, &x, &y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(x));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(y));
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ break;
+ }
+
+ case TM_BORDER_COLOR: /* bordercolor ?pixel? */
+ case TM_GET_BORDER_COLOR: /* GetBorderColor ?pixel? */
+ case TM_SET_BORDER_COLOR: /* SetBorderColor pixel */
+ {
+ char *name = NULL;
+ PixelWand *pixPtr = NULL;
+
+ if( ((enum subIndex)index == TM_SET_BORDER_COLOR) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pixel");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index != TM_SET_BORDER_COLOR) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?pixel?");
+ return TCL_ERROR;
+ }
+ if (objc > 2) { /* Set color / Get color with new name */
+ name = Tcl_GetString(objv[2]);
+ pixPtr = findPixelWand(interp, name);
+ }
+ /*
+ * SET color requires existing pixel object
+ */
+ if( ((enum subIndex)index == TM_SET_BORDER_COLOR) && (pixPtr == NULL) ) {
+ return TCL_ERROR;
+ }
+ /*
+ * GET color if GET_COLOR or pixel object doesn't exists
+ * otherwise SET color
+ */
+ if( ((enum subIndex)index == TM_GET_BORDER_COLOR) || (pixPtr == NULL) ) {
+ if( pixPtr == NULL ) {
+ pixPtr = NewPixelWand();
+ name = newPixelObj(interp, pixPtr, name );
+ }
+ result = MagickGetImageBorderColor( wandPtr, pixPtr );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+ } else {
+ result = MagickSetImageBorderColor( wandPtr, pixPtr );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ }
+ break;
+ }
+
+ case TM_CHANNEL_DEPTH: /* channeldepth channel ?depth? */
+ case TM_GET_CHANNEL_DEPTH: /* GetChannelDepth channel */
+ case TM_SET_CHANNEL_DEPTH: /* SetChannelDepth channel depth */
+ {
+ unsigned long depth;
+ int chanIdx;
+
+ if( ((enum subIndex)index == TM_CHANNEL_DEPTH) && (objc != 3) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channel ?depth?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_CHANNEL_DEPTH) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channel");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_CHANNEL_DEPTH) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channel depth");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ /*
+ * Set channel depth
+ */
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &depth)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickSetImageChannelDepth(wandPtr, chanTypes[chanIdx], depth);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get channel depth
+ */
+ depth = MagickGetImageChannelDepth(wandPtr, chanTypes[chanIdx]);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((long)depth));
+ }
+ break;
+ }
+
+ case TM_CHANNEL_EXTREMA: /* channelextrema channelType */
+ case TM_GET_CHANNEL_EXTREMA: /* GetChannelExtrema channelType */
+ {
+ unsigned long min, max;
+ int chanIdx;
+ Tcl_Obj *listPtr;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channelType" );
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickGetImageChannelExtrema(wandPtr, chanTypes[chanIdx], &min, &max);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj(min));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj(max));
+ Tcl_SetObjResult(interp, listPtr);
+
+ break;
+ }
+
+ case TM_CHANNEL_MEAN: /* channelmean channelType */
+ case TM_GET_CHANNEL_MEAN: /* GetChannelMean channelType */
+ {
+ double mean, deviation;
+ int chanIdx;
+ Tcl_Obj *listPtr;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channelType" );
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickGetImageChannelMean(wandPtr, chanTypes[chanIdx], &mean, &deviation);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(mean));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(deviation));
+ Tcl_SetObjResult(interp, listPtr);
+
+ break;
+ }
+
+ case TM_COLORMAP_COLOR: /* colormapcolor index ?pixel? */
+ case TM_GET_COLORMAP_COLOR: /* GetColormapColor index ?pixel? */
+ case TM_SET_COLORMAP_COLOR: /* SetColormapColor index pixel */
+ {
+ char *name = NULL;
+ unsigned long idx;
+ PixelWand *pixPtr = NULL;
+
+ if( ((enum subIndex)index == TM_SET_COLORMAP_COLOR) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index pixel");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index != TM_SET_COLORMAP_COLOR) && ((objc < 3) || (objc > 4)) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index ?pixel?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetLongFromObj(interp, objv[2], (long int *) &idx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (objc > 3) { /* Set color / Get color with new name */
+ name = Tcl_GetString(objv[3]);
+ pixPtr = findPixelWand(interp, name);
+ }
+ /*
+ * SET color requires existing pixel object
+ */
+ if( ((enum subIndex)index == TM_SET_COLORMAP_COLOR) && (pixPtr == NULL) ) {
+ return TCL_ERROR;
+ }
+ /*
+ * GET color if GET_COLOR or pixel object doesn't exists
+ * otherwise SET color
+ */
+ if( ((enum subIndex)index == TM_GET_COLORMAP_COLOR) || (pixPtr == NULL) ) {
+ if( pixPtr == NULL ) {
+ pixPtr = NewPixelWand();
+ name = newPixelObj(interp, pixPtr, name );
+ }
+ result = MagickGetImageColormapColor( wandPtr, idx, pixPtr );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+ } else {
+ result = MagickSetImageColormapColor( wandPtr, idx, pixPtr );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ }
+ break;
+ }
+
+ case TM_COLORS: /* colors */
+ case TM_GET_COLORS: /* GetColors */
+ {
+ long colors;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ colors = MagickGetImageColors(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(colors));
+ break;
+ }
+
+ case TM_COLORSPACE: /* colorspace ?colorspaceType? */
+ case TM_GET_COLORSPACE: /* GetColorspace */
+ case TM_SET_COLORSPACE: /* SetColorspace colorspaceType */
+ {
+ int csIdx;
+ ColorspaceType cs;
+
+ if( ((enum subIndex)index == TM_COLORSPACE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?colorspaceType?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_COLORSPACE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_COLORSPACE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "colorspaceType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set colorspace
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], csNames, "csType", 0, &csIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageColorspace(wandPtr, csTypes[csIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get colorspace
+ */
+ cs = MagickGetImageColorspace(wandPtr);
+ for (csIdx = 0; (size_t) csIdx < sizeof(csTypes)/sizeof(csTypes[0]); csIdx++) {
+ if( csTypes[csIdx] == cs ) {
+ Tcl_SetResult(interp, (char *)csNames[csIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)cs));
+ }
+ break;
+ }
+
+ case TM_COMPOSE: /* compose ?opType? */
+ case TM_GET_COMPOSE: /* GetCompose */
+ case TM_SET_COMPOSE: /* SetCompose opType */
+ {
+ int opIdx;
+ CompositeOperator op;
+
+ if( ((enum subIndex)index == TM_COMPOSE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?opType?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_COMPOSE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_COMPOSE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "opType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set compose operator
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], opNames, "opType", 0, &opIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageColorspace(wandPtr, opTypes[opIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get compose operator
+ */
+ op = MagickGetImageColorspace(wandPtr);
+ for (opIdx = 0; (size_t) opIdx < sizeof(opTypes)/sizeof(opTypes[0]); opIdx++) {
+ if( opTypes[opIdx] == op ) {
+ Tcl_SetResult(interp, (char *)opNames[opIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)op));
+ }
+ break;
+ }
+
+ case TM_COMPRESSION: /* compression ?compressionType? */
+ case TM_GET_COMPRESSION: /* GetCompression */
+ case TM_SET_COMPRESSION: /* SetCompression compressionType */
+ {
+ int csIdx;
+ CompressionType cs;
+
+ if( ((enum subIndex)index == TM_COMPRESSION) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?compressionType?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_COMPRESSION) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_COMPRESSION) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "compressionType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set compression
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], compressNames, "compressType", 0, &csIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageCompression(wandPtr, compressTypes[csIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get compression
+ */
+ cs = MagickGetImageCompression(wandPtr);
+ for (csIdx = 0; (size_t) csIdx < sizeof(compressTypes)/sizeof(compressTypes[0]); csIdx++) {
+ if( compressTypes[csIdx] == cs ) {
+ Tcl_SetResult(interp, (char *)compressNames[csIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)cs));
+ }
+ break;
+ }
+
+ case TM_DELAY: /* delay ?delay? */
+ case TM_GET_DELAY: /* GetDelay */
+ case TM_SET_DELAY: /* SetDelay delay */
+ {
+ unsigned long delay;
+
+ if( ((enum subIndex)index == TM_DELAY) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?delay?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_DELAY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_DELAY) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "delay");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set delay
+ */
+ if (Tcl_GetLongFromObj(interp, objv[2], (long int *) &delay) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageDelay(wandPtr, delay);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get delay
+ */
+ delay = MagickGetImageDelay(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((long)delay));
+ }
+ break;
+ }
+
+ case TM_DEPTH: /* depth ?depth? */
+ case TM_GET_DEPTH: /* GetDepth */
+ case TM_SET_DEPTH: /* SetDepth depth */
+ {
+ unsigned long depth;
+
+ if( ((enum subIndex)index == TM_DEPTH) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?depth?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_DEPTH) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_DEPTH) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "depth");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set depth
+ */
+ if (Tcl_GetLongFromObj(interp, objv[2], (long int *) &depth) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageDepth(wandPtr, depth);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get depth
+ */
+ depth = MagickGetImageDepth(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((long)depth));
+ }
+ break;
+ }
+
+ case TM_DISPOSE: /* dispose ?disposeType? */
+ case TM_GET_DISPOSE: /* GetDispose */
+ case TM_SET_DISPOSE: /* SetDispose disposeType */
+ {
+ int disposeIdx;
+ DisposeType dispose;
+
+ if( ((enum subIndex)index == TM_DISPOSE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?disposeType?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_DISPOSE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_DISPOSE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "disposeType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set dispose
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], disposeNames, "disposeType", 0, &disposeIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageDispose(wandPtr, disposeTypes[disposeIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get dispose
+ */
+ dispose = MagickGetImageDispose(wandPtr);
+ for (disposeIdx = 0; (size_t) disposeIdx < sizeof(disposeTypes)/sizeof(disposeTypes[0]); disposeIdx++) {
+ if( disposeTypes[disposeIdx] == dispose ) {
+ Tcl_SetResult(interp, (char *)disposeNames[disposeIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)dispose));
+ }
+ break;
+ }
+
+ case TM_EXTREMA: /* extrema */
+ case TM_GET_EXTREMA: /* GetExtrema */
+ {
+ unsigned long min, max;
+ Tcl_Obj *listPtr;
+
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL );
+ return TCL_ERROR;
+ }
+ result = MagickGetImageExtrema(wandPtr, &min, &max);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj(min));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj(max));
+ Tcl_SetObjResult(interp, listPtr);
+
+ break;
+ }
+
+ case TM_FORMAT: /* format */
+ case TM_GET_FORMAT: /* GetImageFormat */
+ case TM_SET_FORMAT: /* SetImageFormat */
+ {
+ char *fmt;
+
+ if( ((enum subIndex)index == TM_FORMAT) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?format?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_FORMAT) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_FORMAT) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "format");
+ return TCL_ERROR;
+ }
+ if (objc > 2) { /* Set format */
+#if defined(HAVE_MAGICKSETIMAGEFORMAT)
+ Tcl_DString extrep;
+
+ fmt = Tcl_UtfToExternalDString (NULL, Tcl_GetString(objv[2]), -1, &extrep);
+ MagickSetImageFormat(wandPtr, fmt);
+ Tcl_DStringFree (&extrep);
+#else
+ char msg[1024];
+ sprintf(msg, "%.500s: MagickSetImageFormat() is not implemented!", MagickGetPackageName());
+ Tcl_AppendResult(interp, msg, NULL);
+ return TCL_ERROR;
+#endif /* HAVE_MAGICKSETIMAGEFORMAT */
+ } else { /* Get format */
+ fmt = (char *)MagickGetImageFormat(wandPtr);
+ if (fmt != NULL) {
+ Tcl_SetResult(interp, fmt, TCL_VOLATILE);
+ MagickRelinquishMemory(fmt); /* Free TclMagick resource */
+ }
+ }
+ break;
+ }
+
+ case TM_GETIMAGE: /* getimage ?newName? */
+ case TM_GET_IMAGE: /* GetImage ?newName? */
+ {
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ name = Tcl_GetString(objv[2]);
+ }
+ newWand = MagickGetImage(wandPtr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_IMAGE_FILENAME: /* imagefilename ?filename? */
+ case TM_GET_IMAGE_FILENAME: /* GetImageFilename */
+ case TM_SET_IMAGE_FILENAME: /* SetImageFilename filename */
+ {
+ char *filename;
+
+ if( ((enum subIndex)index == TM_IMAGE_FILENAME) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?filename?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_IMAGE_FILENAME) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_IMAGE_FILENAME) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "filename");
+ return TCL_ERROR;
+ }
+ if (objc > 2) { /* Set filename */
+ Tcl_DString extrep;
+ filename = Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[2]), -1, &extrep);
+ result = MagickSetImageFilename(wandPtr, filename);
+ Tcl_DStringFree(&extrep);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else { /* Get filename */
+ filename = (char *)MagickGetImageFilename(wandPtr);
+ if(filename != NULL) {
+ SetResultAsExternalString(interp, filename);
+ MagickRelinquishMemory(filename); /* Free TclMagick resource */
+ }
+ }
+ break;
+ }
+
+ case TM_GAMMA: /* gamma ?gamma? */
+ case TM_GET_GAMMA: /* GetGamma */
+ case TM_SET_GAMMA: /* SetGamma gamma */
+ {
+ double gamma;
+
+ if( ((enum subIndex)index == TM_GAMMA) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?gamma?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_GAMMA) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_GAMMA) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "gamma");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set gamma
+ */
+ if (Tcl_GetDoubleFromObj(interp, objv[2], &gamma) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageGamma(wandPtr, gamma);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get gamma
+ */
+ gamma = MagickGetImageGamma(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(gamma));
+ }
+ break;
+ }
+
+ case TM_GREEN_PRIMARY: /* greenprimary ?x y? */
+ case TM_GET_GREEN_PRIMARY: /* GetGreenPrimary */
+ case TM_SET_GREEN_PRIMARY: /* SetGreenPrimary x y */
+ {
+ double x, y;
+
+ if( ((enum subIndex)index == TM_GREEN_PRIMARY) && (objc != 2) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?x y?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_GREEN_PRIMARY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_GREEN_PRIMARY) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ /*
+ * Set primary = x y
+ */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickSetImageGreenPrimary(wandPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get primary={x y}
+ */
+ Tcl_Obj *listPtr;
+
+ result = MagickGetImageGreenPrimary(wandPtr, &x, &y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(x));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(y));
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ break;
+ }
+
+ case TM_HEIGHT: /* height */
+ case TM_GET_HEIGHT: /* GetHeight */
+ {
+ int value;
+
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ value = MagickGetImageHeight(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(value));
+
+ break;
+ }
+
+ case TM_INDEX: /* index ?index? */
+ case TM_GET_INDEX: /* GetIndex */
+ case TM_SET_INDEX: /* SetIndex index */
+ {
+ long idx;
+
+ if( ((enum subIndex)index == TM_INDEX) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?index?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_INDEX) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_INDEX) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "index");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set index
+ */
+ if (Tcl_GetLongFromObj(interp, objv[2], &idx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageIndex(wandPtr, (long) idx);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get depth
+ */
+ idx = MagickGetImageIndex(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((long)idx));
+ }
+ break;
+ }
+
+ case TM_INTERLACE: /* interlace ?interlaceType? */
+ case TM_GET_INTERLACE: /* GetInterlace */
+ case TM_SET_INTERLACE: /* SetInterlace interlaceType */
+ {
+ int interlaceIdx;
+ InterlaceType interlace;
+
+ if( ((enum subIndex)index == TM_INTERLACE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?interlaceType?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_INTERLACE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_INTERLACE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "interlaceType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set interlace
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], interlaceNames,
+ "interlaceType", 0, &interlaceIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageInterlaceScheme(wandPtr, interlaceTypes[interlaceIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get interlace
+ */
+ interlace = MagickGetImageInterlaceScheme(wandPtr);
+ for (interlaceIdx = 0;
+ (size_t) interlaceIdx < sizeof(interlaceTypes)/sizeof(interlaceTypes[0]);
+ interlaceIdx++) {
+ if( interlaceTypes[interlaceIdx] == interlace ) {
+ Tcl_SetResult(interp, (char *)interlaceNames[interlaceIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)interlace));
+ }
+ break;
+ }
+
+ case TM_ITERATIONS: /* iterations ?num? */
+ case TM_GET_ITERATIONS: /* GetIterations */
+ case TM_SET_ITERATIONS: /* SetIterations num */
+ {
+ unsigned long num;
+
+ if( (index == TM_ITERATIONS) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?num?");
+ return TCL_ERROR;
+ }
+ if( (index == TM_GET_ITERATIONS) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( (index == TM_SET_ITERATIONS) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "num");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set iterations
+ */
+ if (Tcl_GetLongFromObj(interp, objv[2], (long int *) &num) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageIterations(wandPtr, num);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get depth
+ */
+ num = MagickGetImageIterations(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((long)num));
+ }
+ break;
+ }
+
+ case TM_MATTE_COLOR: /* mattecolor ?pixel? */
+ case TM_GET_MATTE_COLOR: /* GetMatteColor ?pixel? */
+ case TM_SET_MATTE_COLOR: /* SetMatteColor pixel */
+ {
+ char *name = NULL;
+ PixelWand *pixPtr = NULL;
+
+ if( ((enum subIndex)index == TM_SET_MATTE_COLOR) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pixel");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index != TM_SET_MATTE_COLOR) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?pixel?");
+ return TCL_ERROR;
+ }
+ if (objc > 2) { /* Set color / Get color with new name */
+ name = Tcl_GetString(objv[2]);
+ pixPtr = findPixelWand(interp, name);
+ }
+ /*
+ * SET color requires existing pixel object
+ */
+ if( ((enum subIndex)index == TM_SET_MATTE_COLOR) && (pixPtr == NULL) ) {
+ return TCL_ERROR;
+ }
+ /*
+ * GET color if GET_COLOR or pixel object doesn't exists
+ * otherwise SET color
+ */
+ if( ((enum subIndex)index == TM_GET_MATTE_COLOR) || (pixPtr == NULL) ) {
+ if( pixPtr == NULL ) {
+ pixPtr = NewPixelWand();
+ name = newPixelObj(interp, pixPtr, name );
+ }
+ result = MagickGetImageMatteColor( wandPtr, pixPtr );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+ } else {
+ result = MagickSetImageMatteColor( wandPtr, pixPtr );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ }
+ break;
+ }
+
+ case TM_PIXELS: /* pixels x0 y0 cols rows map storageType ?data? */
+ case TM_GET_PIXELS: /* GetPixels x0 y0 cols rows map storageType */
+ case TM_SET_PIXELS: /* GetPixels x0 y0 cols rows map storageType data */
+ {
+ static CONST char *storNames[] = {
+ "char", "short", "integer", "long", "float", "double",
+ (char *) NULL
+ };
+ static StorageType storTypes[] = {
+ CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel, DoublePixel
+ };
+ static size_t storSize[] = {
+ sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(float), sizeof(double)
+ };
+ unsigned long cols, rows, size;
+ long x0, y0;
+ int storIdx, len;
+ char *map;
+ unsigned char *pixels;
+
+ if( ((enum subIndex)index == TM_PIXELS) && ((objc < 8) || (objc > 9)) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x0 y0 cols rows map storageType ?data?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_PIXELS) && (objc != 8) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x0 y0 cols rows map storageType");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_PIXELS) && (objc != 9) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x0 y0 cols rows map storageType data");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], &x0)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], &y0)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[4], (long int *) &cols)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[5], (long int *) &rows)) != TCL_OK ) {
+ return stat;
+ }
+ map = Tcl_GetString(objv[6]);
+ if (Tcl_GetIndexFromObj(interp, objv[7], storNames, "storageType", 0, &storIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ size = cols * rows * storSize[storIdx] * strlen(map);
+
+ if( objc == 8 ) {
+ /*
+ * GetImagePixels: Allocate memory for storage
+ */
+ pixels = (unsigned char *) ckalloc(size);
+ if( pixels == NULL ) {
+ Tcl_AppendResult(interp, "TclMagick: out of memory", NULL);
+ return TCL_ERROR;
+ }
+
+ result = MagickGetImagePixels(wandPtr, x0, y0, cols, rows, map,
+ storTypes[storIdx], pixels);
+ if (!result) {
+ ckfree((char *) pixels);
+ return myMagickError(interp, wandPtr);
+ }
+
+ /*
+ * Return ByteArray object
+ */
+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pixels, (int)size));
+ ckfree((char *) pixels);
+ } else {
+ pixels = Tcl_GetByteArrayFromObj( objv[8], &len);
+ if( (unsigned long)len < size ) {
+ Tcl_AppendResult(interp, "TclMagick: not enough data bytes", NULL);
+ return TCL_ERROR;
+ }
+ result = MagickSetImagePixels(wandPtr, x0, y0, cols, rows, map,
+ storTypes[storIdx], pixels);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ }
+ break;
+ }
+
+ case TM_PROFILE_IMAGE: /* ProfileImage name ?profile? */
+ {
+ char *name;
+ unsigned char *profile = NULL;
+ int length = 0;
+
+ if( (objc != 3) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name ?profile?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+
+ if( objc > 3 ) {
+ profile = Tcl_GetByteArrayFromObj(objv[3], &length);
+ }
+ result = MagickProfileImage(wandPtr, name, profile, (unsigned long)length);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_REMOVE_PROFILE: /* RemoveProfile name */
+ {
+ char *name;
+ unsigned char *profile;
+ unsigned long length;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+
+ profile = MagickRemoveImageProfile(wandPtr, (const char*)name, &length);
+ if(profile != NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(profile, (long)length));
+ MagickRelinquishMemory(profile); /* Free TclMagick resource */
+ }
+ break;
+ }
+
+ case TM_PROFILE: /* profile name ?profile? */
+ case TM_GET_PROFILE: /* GetProfile name */
+ case TM_SET_PROFILE: /* SetProfile name profile */
+ {
+ char *name;
+ unsigned char *profile;
+
+ if( ((enum subIndex)index == TM_PROFILE) && (objc != 3) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name ?profile?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_PROFILE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_PROFILE) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name profile");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+
+ if( objc == 4 ) {
+ int length;
+ /*
+ * Set/Add image profile
+ */
+ profile = Tcl_GetByteArrayFromObj(objv[3], &length);
+ result = MagickSetImageProfile(wandPtr, (const char*)name, profile, (unsigned long)length);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ unsigned long length;
+
+ profile = MagickGetImageProfile(wandPtr, name, &length);
+ if(profile != NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(profile, (long)length));
+ MagickRelinquishMemory(profile); /* Free TclMagick resource */
+ }
+ }
+ break;
+ }
+
+ case TM_RED_PRIMARY: /* redprimary ?x y? */
+ case TM_GET_RED_PRIMARY: /* GetRedPrimary */
+ case TM_SET_RED_PRIMARY: /* SetRedPrimary x y */
+ {
+ double x, y;
+
+ if( ((enum subIndex)index == TM_RED_PRIMARY) && (objc != 2) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?x y?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_RED_PRIMARY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_RED_PRIMARY) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ /*
+ * Set primary = x y
+ */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickSetImageRedPrimary(wandPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get primary={x y}
+ */
+ Tcl_Obj *listPtr;
+
+ result = MagickGetImageRedPrimary(wandPtr, &x, &y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(x));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(y));
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ break;
+ }
+
+ case TM_RENDERING: /* rendering ?renderType? */
+ case TM_GET_RENDERING: /* GetRenderingIntent */
+ case TM_SET_RENDERING: /* SetRenderingIntent renderType */
+ {
+ int renderIdx;
+ RenderingIntent render;
+
+ if( ((enum subIndex)index == TM_RENDERING) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?renderType?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_RENDERING) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_RENDERING) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "renderType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set render
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], renderNames, "renderType", 0, &renderIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageRenderingIntent(wandPtr, renderTypes[renderIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get render
+ */
+ render = MagickGetImageRenderingIntent(wandPtr);
+ for (renderIdx = 0; (size_t) renderIdx < sizeof(renderTypes)/sizeof(renderTypes[0]); renderIdx++) {
+ if( renderTypes[renderIdx] == render ) {
+ Tcl_SetResult(interp, (char *)renderNames[renderIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)render));
+ }
+ break;
+ }
+
+ case TM_RESOLUTION: /* resolution ?x? ?y? */
+ case TM_GET_RESOLUTION: /* GetResolution */
+ case TM_SET_RESOLUTION: /* SetResolution x ?y? */
+ {
+ double x, y;
+
+ if( ((enum subIndex)index == TM_RESOLUTION) && (objc > 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?x? ?y?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_RESOLUTION) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_RESOLUTION) && (objc != 3) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x ?y?");
+ return TCL_ERROR;
+ }
+ if (objc >= 3) {
+ /*
+ * Set resolution = x y, default: y=x
+ */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ y = x;
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickSetImageResolution(wandPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get resolution={x y}
+ */
+ Tcl_Obj *listPtr;
+
+ result = MagickGetImageResolution(wandPtr, &x, &y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(x));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(y));
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ break;
+ }
+
+ case TM_SCENE: /* scene ?num? */
+ case TM_GET_SCENE: /* GetScene */
+ case TM_SET_SCENE: /* SetScene num */
+ {
+ unsigned long num;
+
+ if( (index == TM_SCENE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?num?");
+ return TCL_ERROR;
+ }
+ if( (index == TM_GET_SCENE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( (index == TM_SET_SCENE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "num");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set scene number
+ */
+ if (Tcl_GetLongFromObj(interp, objv[2], (long int *) &num) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageScene(wandPtr, num);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get scene number
+ */
+ num = MagickGetImageScene(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((long)num));
+ }
+ break;
+ }
+
+ case TM_SIGNATURE: /* signature */
+ case TM_GET_SIGNATURE: /* GetSignature */
+ {
+ char *signature;
+
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ signature = (char *)MagickGetImageSignature(wandPtr);
+ if(signature != NULL) {
+ Tcl_SetResult(interp, signature, TCL_VOLATILE);
+ MagickRelinquishMemory(signature); /* Free TclMagick resource */
+ }
+ break;
+ }
+
+ case TM_IMAGE_SIZE: /* imagesize */
+ case TM_GET_IMAGE_SIZE: /* GetImageSize */
+ {
+ Tcl_WideInt size;
+
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ /*
+ * Get image size={xSize ySize}
+ */
+ size = MagickGetImageSize(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(size));
+
+ break;
+ }
+
+ case TM_IMAGE_TYPE: /* imagetype ?type? */
+ case TM_GET_IMAGE_TYPE: /* GetImageType */
+ case TM_SET_IMAGE_TYPE: /* SetImageType type */
+ {
+ int typeIdx;
+ ImageType type;
+
+ if( ((enum subIndex)index == TM_IMAGE_TYPE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?type?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_IMAGE_TYPE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_IMAGE_TYPE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "type");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set image type
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], typeNames,
+ "typeType", 0, &typeIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageType(wandPtr, typeTypes[typeIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get image type
+ */
+ type = MagickGetImageType(wandPtr);
+ for (typeIdx = 0; (size_t) typeIdx < sizeof(typeTypes)/sizeof(typeTypes[0]); typeIdx++) {
+ if( typeTypes[typeIdx] == type ) {
+ Tcl_SetResult(interp, (char *)typeNames[typeIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)type));
+ }
+ break;
+ }
+
+ case TM_IMAGE_UNITS: /* imageunits ?unitType? */
+ case TM_GET_IMAGE_UNITS: /* GetImageUnits */
+ case TM_SET_IMAGE_UNITS: /* SetImageUnits unitType */
+ {
+ int unitIdx;
+ ResolutionType unit;
+
+ if( ((enum subIndex)index == TM_IMAGE_UNITS) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?unitType?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_IMAGE_UNITS) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_IMAGE_UNITS) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "unitType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set image unit
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], unitNames, "unitType", 0, &unitIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageUnits(wandPtr, unitTypes[unitIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get image type
+ */
+ unit = MagickGetImageUnits(wandPtr);
+ for (unitIdx = 0; (size_t) unitIdx < sizeof(unitTypes)/sizeof(unitTypes[0]); unitIdx++) {
+ if( unitTypes[unitIdx] == unit ) {
+ Tcl_SetResult(interp, (char *)unitNames[unitIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)unit));
+ }
+ break;
+ }
+
+ case TM_VIRTUALPIXEL: /* virtualpixelmethod ?methodType? */
+ case TM_GET_VIRTUALPIXEL: /* GetVirtualPixelMethod */
+ case TM_SET_VIRTUALPIXEL: /* SetVirtualPixelMethod methodType */
+ {
+ int methodIdx;
+ VirtualPixelMethod method;
+
+ if( ((enum subIndex)index == TM_IMAGE_UNITS) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?methodType?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_VIRTUALPIXEL) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_VIRTUALPIXEL) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "methodType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set image virtual pixel method
+ */
+ if (Tcl_GetIndexFromObj(interp, objv[2], methodNames, "methodType", 0, &methodIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImageVirtualPixelMethod(wandPtr, methodTypes[methodIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get image virtual pixel method
+ */
+ method = MagickGetImageVirtualPixelMethod(wandPtr);
+ for (methodIdx = 0; (size_t) methodIdx < sizeof(methodTypes)/sizeof(methodTypes[0]); methodIdx++) {
+ if( methodTypes[methodIdx] == method ) {
+ Tcl_SetResult(interp, (char *)methodNames[methodIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)method));
+ }
+ break;
+ }
+
+ case TM_WHITE_POINT: /* whitepoint ?x y? */
+ case TM_GET_WHITE_POINT: /* GetWhitePoint */
+ case TM_SET_WHITE_POINT: /* SetWhitePoint x y */
+ {
+ double x, y;
+
+ if( ((enum subIndex)index == TM_WHITE_POINT) && (objc != 2) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?x y?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_WHITE_POINT) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_WHITE_POINT) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ /*
+ * Set primary = x y
+ */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickSetImageWhitePoint(wandPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get primary={x y}
+ */
+ Tcl_Obj *listPtr;
+
+ result = MagickGetImageWhitePoint(wandPtr, &x, &y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(x));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(y));
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ break;
+ }
+
+ case TM_WIDTH: /* width */
+ case TM_GET_WIDTH: /* GetWidth */
+ {
+ int value;
+
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ value = MagickGetImageWidth(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(value));
+
+ break;
+ }
+
+ case TM_NUMBER: /* number */
+ case TM_GET_NUMBER_IMAGES: /* GetNumberImages */
+ {
+ long num;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ num = MagickGetNumberImages(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(num));
+ break;
+ }
+
+ case TM_SAMPLING_FACTORS: /* samplingfactors ?factorList? */
+ case TM_GET_SAMPLING_FACTORS: /* GetSamplingFactors */
+ case TM_SET_SAMPLING_FACTORS: /* GetSamplingFactors factorList */
+ {
+ double *factors;
+
+ if( ((enum subIndex)index == TM_SAMPLING_FACTORS) && (objc != 2) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?factorList?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_SAMPLING_FACTORS) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_SAMPLING_FACTORS) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "factorList");
+ return TCL_ERROR;
+ }
+ if (objc == 3) {
+ /*
+ * Set sampling factors
+ */
+ Tcl_Obj **listPtr;
+ int i, listLen = 0;
+
+ if( (stat = Tcl_ListObjGetElements(interp, objv[2], &listLen, &listPtr)) != TCL_OK) {
+ return stat;
+ }
+ factors = (double *)ckalloc(listLen * sizeof(double));
+ if( factors == NULL ) {
+ Tcl_AppendResult(interp, "TclMagick: out of memory", NULL);
+ return TCL_ERROR;
+ }
+ for( i=0; i < listLen; i++ ) {
+ if( (stat = Tcl_GetDoubleFromObj(interp, listPtr[i], &factors[i])) != TCL_OK) {
+ ckfree((char *)factors);
+ return stat;
+ }
+ }
+ result = MagickSetSamplingFactors(wandPtr, (unsigned long)listLen, factors);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ } else {
+ /*
+ * Get size={xSize ySize}
+ */
+ Tcl_Obj *listPtr = NULL;
+ unsigned long i, uLen;
+
+ factors = MagickGetSamplingFactors(wandPtr, &uLen);
+ if( (factors != NULL) && (uLen > 0) ) {
+ listPtr = Tcl_NewListObj(0, NULL);
+ for( i=0; i < uLen; i++ ) {
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(factors[i]));
+ }
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ if (factors != NULL)
+ MagickRelinquishMemory(factors); /* Free TclMagick resource */
+ }
+ break;
+ }
+
+ case TM_SIZE: /* size ?x y? */
+ case TM_GET_SIZE: /* size */
+ case TM_SET_SIZE: /* size x y */
+ {
+ unsigned long x, y;
+
+ if( ((enum subIndex)index == TM_SIZE) && (objc != 2) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?xSize ySize?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_SIZE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_SIZE) && (objc != 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "xSize ySize");
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ /*
+ * Set size = x y
+ */
+
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &y)) != TCL_OK ) {
+ return stat;
+ }
+ MagickSetSize(wandPtr, x, y);
+ } else {
+ /*
+ * Get size={xSize ySize}
+ */
+ Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);
+
+ result = MagickGetSize(wandPtr, &x, &y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj((long)x));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj((long)y));
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ break;
+ }
+
+ case TM_HASNEXT:
+ case TM_HAS_NEXT_IMAGE:
+ {
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "");
+ return TCL_ERROR;
+ }
+ result = MagickHasNextImage(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
+ break;
+ }
+
+ case TM_HASPREVIOUS:
+ case TM_HAS_PREVIOUS_IMAGE:
+ {
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "");
+ return TCL_ERROR;
+ }
+ result = MagickHasPreviousImage(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
+ break;
+ }
+
+ case TM_IMPLODE: /* implode ?amount=0.0? */
+ case TM_IMPLODE_IMAGE: /* ImplodeImage ?amount? */
+ {
+ double amount=0.0;
+
+ if( objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?amount=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &amount)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickImplodeImage(wandPtr, amount);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_LABEL: /* label str */
+ case TM_LABEL_IMAGE: /* LabelImage str */
+ {
+ Tcl_DString extrep;
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "str");
+ return TCL_ERROR;
+ }
+ result = MagickLabelImage(wandPtr,
+ Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[2]), -1, &extrep));
+
+ Tcl_DStringFree(&extrep);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+
+ break;
+ }
+
+ case TM_LEVEL: /* level ?black=0.0? ?gamma=1.0? ?white=MaxRGB? */
+ case TM_LEVEL_IMAGE: /* LevelImage ?black? ?gamma=1.0? ?white=MaxRGB? */
+ {
+ double black=0.0, white=MaxRGB, gamma=1.0;
+
+ if( objc > 5 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?black=0.0? ?gamma=1.0? ?white=MaxRGB? ");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &black)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &gamma)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetDoubleFromObj(interp, objv[4], &white)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickLevelImage(wandPtr, black, gamma, white);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_LEVEL_CHANNEL: /* levelchannel channelType ?black=0.0? ?gamma=1.0? ?white=MaxRGB? */
+ case TM_LEVEL_IMAGE_CHANNEL: /* LevelImageChannel channelType ?black? ?gamma=1.0? ?white=MaxRGB? */
+ {
+ int chanIdx;
+ double black=0.0, white=MaxRGB, gamma=1.0;
+
+ if( objc > 6 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channelType ?black=0.0? ?gamma=1.0? ?white=MaxRGB? ");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &black)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetDoubleFromObj(interp, objv[4], &gamma)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetDoubleFromObj(interp, objv[5], &white)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickLevelImageChannel(wandPtr, chanTypes[chanIdx], black, gamma, white);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_MAGNIFY: /* magnify */
+ case TM_MAGNIFY_IMAGE: /* MagnifyImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickMagnifyImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+
+ break;
+ }
+
+ case TM_MAP: /* map mapName ?dither=false? */
+ case TM_MAP_IMAGE: /* MapImage mapName ?dither? */
+ {
+ MagickWand *mapWand;
+ char *name;
+ int dither=0;
+
+ if( objc > 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "mapName ?dither=no?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (mapWand = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetBooleanFromObj(interp, objv[3], &dither)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickMapImage( wandPtr, mapWand, dither );
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+
+ break;
+ }
+
+ case TM_MATTE_FLOODFILL: /* mattefloodfill opacity ?fuzz=0.0? ?borderPix=none? ?x=0 y=0? */
+ case TM_MATTE_FLOODFILL_IMAGE: /* MatteFloodfillImage opacity ?fuzz? ?borderPix? ?x y? */
+ {
+ unsigned int opacity;
+ long x = 0, y = 0;
+ double fuzz = 0.0;
+ char *name;
+ PixelWand *borderPtr=NULL;
+
+ if( (objc < 3) || (objc > 7) || (objc == 6) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "opacity ?fuzz=0.0? ?borderPix=none? ?x=0 y=0?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], (int *) &opacity)) != TCL_OK ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &fuzz)) != TCL_OK) ) {
+ return stat;
+ }
+ if( objc > 4 ) {
+ name = Tcl_GetString(objv[4]);
+ if( (borderPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ }
+ if( (objc > 5) && ((stat = Tcl_GetLongFromObj(interp, objv[5], &x)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 6) && ((stat = Tcl_GetLongFromObj(interp, objv[6], &y)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickMatteFloodfillImage(wandPtr, (Quantum)(opacity), fuzz, borderPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_MEDIANFILTER: /* medianfilter ?radius? */
+ case TM_MEDIANFILTER_IMAGE: /* MedianFilterImage ?radius? */
+ {
+ double radius=0.0;
+
+ if( objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickMedianFilterImage(wandPtr, radius);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_MINIFY: /* minify */
+ case TM_MINIFY_IMAGE: /* MinifyImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickMinifyImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+
+ break;
+ }
+
+ case TM_MODULATE: /* modulate ?brightness=0.0? ?saturation=0.0? ?hue=0.0? */
+ case TM_MODULATE_IMAGE: /* ModulateImage ?brightness? ?saturation? ?hue? */
+ {
+ double brightness=0.0, saturation=0.0, hue=0.0;
+
+ if( objc > 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?brightness=0.0? ?saturation=0.0? ?hue=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &brightness)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &saturation)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetDoubleFromObj(interp, objv[4], &hue)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickModulateImage(wandPtr, brightness, saturation, hue);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_MONTAGE: /* montage draw tileGeom thumbGeom mode frameGeom ?newName? */
+ case TM_MONTAGE_IMAGE: /* MontageImage draw tileGeom thumbGeom mode frameGeom ?newName? */
+ {
+ static CONST char *modeNames[] = {
+ "frame", "unframe", "concatenate",
+ (char *) NULL
+ };
+ static CompositeOperator modeTypes[] = {
+ FrameMode, UnframeMode, ConcatenateMode
+ };
+ char *name, *newName=NULL;
+ DrawingWand *drawPtr;
+ MagickWand *newWand;
+ int modeIdx;
+ char *tileGeom, *thumbGeom, *frameGeom;
+
+ if( (objc < 7) || (objc > 8) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "draw tileGeom thumbGeom mode frameGeom ?newName?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (drawPtr = findDrawingWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ tileGeom = Tcl_GetString(objv[3]);
+ thumbGeom = Tcl_GetString(objv[4]);
+ if (Tcl_GetIndexFromObj(interp, objv[5], modeNames, "mode", 0, &modeIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ frameGeom = Tcl_GetString(objv[6]);
+ if( objc > 7 ) {
+ newName = Tcl_GetString(objv[7]);
+ }
+ newWand = MagickMontageImage(wandPtr, drawPtr, tileGeom, thumbGeom,
+ modeTypes[modeIdx], frameGeom);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ newName = newWandObj(interp, newWand, newName);
+ Tcl_SetResult(interp, newName, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_MORPH: /* morph num ?newName? */
+ case TM_MORPH_IMAGES: /* MorphImages num ?newName? */
+ {
+ unsigned long num;
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( (objc < 3) || (objc > 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "num ?newName?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &num)) != TCL_OK ) {
+ return stat;
+ }
+ if( objc > 3 ) {
+ name = Tcl_GetString(objv[3]);
+ }
+ newWand = MagickMorphImages(wandPtr, num);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_MOSAIC: /* mosaic ?newName? */
+ case TM_MOSAIC_IMAGES: /* MosaicImages ?newName? */
+ {
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?newName?");
+ return TCL_ERROR;
+ }
+ if( objc > 2 ) {
+ name = Tcl_GetString(objv[2]);
+ }
+ newWand = MagickMosaicImages(wandPtr);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_MOTIONBLUR: /* motionblur ?radius=0.0? ?sigma=0.0? ?angle=0.0? */
+ case TM_MOTIONBLUR_IMAGE: /* MotionBlurImage ?radius? ?sigma? ?angle? */
+ {
+ double radius=0.0, sigma=0.0, angle=0.0;
+
+ if( objc > 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0? ?sigma=0.0? ?angle=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &sigma)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetDoubleFromObj(interp, objv[4], &angle)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickMotionBlurImage(wandPtr, radius, sigma, angle);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_NEGATE: /* negate ?gray=false? */
+ case TM_NEGATE_IMAGE: /* NegateImage ?gray=false? */
+ {
+ int gray=0;
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?gray=no?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetBooleanFromObj(interp, objv[2], &gray)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickNegateImage(wandPtr, gray);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_NEGATE_CHANNEL: /* negatechannel channelType ?gray=false? */
+ case TM_NEGATE_IMAGE_CHANNEL: /* NegateImageChannel channelType ?gray=false? */
+ {
+ int gray=0;
+ int chanIdx;
+
+ if( (objc < 3) || (objc > 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channelType ?gray=no?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetBooleanFromObj(interp, objv[3], &gray)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickNegateImageChannel(wandPtr, chanTypes[chanIdx], gray);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_NEXT: /* next ?offset=1? */
+ case TM_NEXT_IMAGE: /* NextImage ?offset=1? */
+ {
+ int i, ofs=1;
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?offset=1?");
+ return TCL_ERROR;
+ } else if (objc == 3) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &ofs)) != TCL_OK ) {
+ return stat;
+ }
+ }
+ for( i=0; i<ofs; i++) {
+ result = MagickNextImage(wandPtr);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
+ break;
+ }
+
+ case TM_NORMALIZE: /* normalize */
+ case TM_NORMALIZE_IMAGE: /* NormalizeImage */
+ {
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickNormalizeImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_OILPAINT: /* oilpaint ?radius? */
+ case TM_OILPAINT_IMAGE: /* OilPaintImage ?radius? */
+ {
+ double radius=0.0;
+
+ if( objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickOilPaintImage(wandPtr, radius);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_OPAQUE: /* opaque targetPix fillPix ?fuzz=0.0? */
+ case TM_OPAQUE_IMAGE: /* OpaqueImage targetPix fillPix ?fuzz=0.0? */
+ {
+ double fuzz=0.0;
+ char *name;
+ PixelWand *targetPtr, *fillPtr;
+
+ if( (objc < 4) || (objc > 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "targetPix fillPix ?fuzz=0.0?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (targetPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[3]);
+ if( (fillPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetDoubleFromObj(interp, objv[4], &fuzz)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickOpaqueImage(wandPtr, targetPtr, fillPtr, fuzz);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_PING: /* ping filename */
+ case TM_PING_IMAGE: /* PingImage filename */
+ {
+ char *filename;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "filename");
+ return TCL_ERROR;
+ }
+ filename = Tcl_GetString(objv[2]);
+ result = MagickPingImage(wandPtr, filename);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_PREVIEW: /* preview previewType ?newName? */
+ case TM_PREVIEW_IMAGES: /* PreviewImages previewType ?newName? */
+ {
+ int previewIdx;
+ MagickWand *newWand;
+ char *name=NULL;
+
+ if( (objc < 3) || (objc > 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "previewType ?newName?");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], previewNames, "previewType", 0, &previewIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( objc > 3 ) {
+ name = Tcl_GetString(objv[3]);
+ }
+ newWand = MagickPreviewImages(wandPtr, previewTypes[previewIdx]);
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ name = newWandObj(interp, newWand, name);
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_PREVIOUS: /* previous ?offset=1? */
+ case TM_PREVIOUS_IMAGE: /* PreviousImage ?offset=1? */
+ {
+ int i, ofs=1;
+
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?offset?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetIntFromObj(interp, objv[2], &ofs)) != TCL_OK) ) {
+ return stat;
+ }
+ for( i=0; i<ofs; i++) {
+ result = MagickPreviousImage(wandPtr);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
+ break;
+ }
+
+ case TM_QUANTIZE: /* quantize numColors ?colorspaceType? ?treedepth? ?dither? ?measureError? */
+ case TM_QUANTIZE_IMAGE: /* QuantizeImage numColors ?colorspaceType? ?treedepth? ?dither? ?measureError? */
+ case TM_QUANTIZE_IMAGES: /* QuantizeImage numColors ?colorspaceType? ?treedepth? ?dither? ?measureError? */
+ {
+ unsigned long numColors, treeDepth=0;
+ int dither=0, measureError=0;
+ int csIdx=RGBColorspace;
+
+ if( (objc < 3) || (objc > 7) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "numColors ?colorspaceType=RGB? ?treedepth=0? ?dither=no? ?measureError=no?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &numColors)) != TCL_OK ) {
+ return stat;
+ }
+ if( (objc > 3) && (Tcl_GetIndexFromObj(interp, objv[3], csNames, "colorspaceType", 0, &csIdx) != TCL_OK) ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetLongFromObj(interp, objv[4], (long int *) &treeDepth)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetBooleanFromObj(interp, objv[5], &dither)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 6) && ((stat = Tcl_GetBooleanFromObj(interp, objv[6], &measureError)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (enum subIndex)index == TM_QUANTIZE_IMAGES ) {
+ result = MagickQuantizeImages(wandPtr, numColors, csTypes[csIdx], treeDepth, dither, measureError);
+ } else {
+ result = MagickQuantizeImage(wandPtr, numColors, csTypes[csIdx], treeDepth, dither, measureError);
+ }
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_QUERYFONTMETRICS: /* queryfontmetrics draw text */
+ case TM_QUERY_FONT_METRICS: /* QueryFontMetrics draw text */
+ {
+ double *metrics;
+ int i;
+ Tcl_Obj *listPtr;
+ char *name, *text;
+ DrawingWand *drawPtr;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "draw text");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (drawPtr = findDrawingWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ text = Tcl_GetString(objv[3]);
+
+ metrics = MagickQueryFontMetrics(wandPtr, drawPtr, text);
+ if( (metrics != NULL) ) {
+ listPtr = Tcl_NewListObj(0, NULL);
+ for( i=0; i < 7; i++ ) {
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(metrics[i]));
+ }
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ if (metrics != NULL)
+ MagickRelinquishMemory(metrics); /* Free TclMagick resource */
+
+ break;
+ }
+
+ case TM_RAISE: /* raise width height ?x y? ?raise? */
+ case TM_RAISE_IMAGE: /* RaiseImage width height ?x y? ?raise? */
+ {
+ unsigned long width, height;
+ long x=0, y=0;
+ int raise=0;
+
+ if( (objc < 4) || (objc > 7) || (objc == 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "width height ?x y? ?raise=no?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &width)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &height)) != TCL_OK ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetLongFromObj(interp, objv[4], &x)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetLongFromObj(interp, objv[5], &y)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 6) && ((stat = Tcl_GetBooleanFromObj(interp, objv[6], &raise)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickRaiseImage(wandPtr, width, height, x, y, raise);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_READ: /* read filename */
+ case TM_READ_IMAGE: /* ReadImage filename */
+ {
+ char *filename;
+ Tcl_DString extrep;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "filename");
+ return TCL_ERROR;
+ }
+ filename = Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[2]), -1, &extrep);
+ result = MagickReadImage(wandPtr, filename);
+ Tcl_DStringFree(&extrep);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_READ_BLOB: /* readblob data */
+ case TM_READ_IMAGE_BLOB: /* ReadImageBlob data */
+ {
+ unsigned char *data;
+ int length;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "data");
+ return TCL_ERROR;
+ }
+ data = Tcl_GetByteArrayFromObj(objv[2], &length);
+ result = MagickReadImageBlob(wandPtr, data, (size_t)length);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_REDUCENOISE: /* reducenoise ?radius? */
+ case TM_REDUCENOISE_IMAGE: /* ReduceNoiseImage ?radius? */
+ {
+ double radius=0.0;
+
+ if( objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickReduceNoiseImage(wandPtr, radius);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_REMOVE: /* remove */
+ case TM_REMOVE_IMAGE: /* RemoveImage */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickRemoveImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_RESETITERATOR: /* resetiterator */
+ case TM_RESET_ITERATOR: /* ResetIterator */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ MagickResetIterator(wandPtr);
+ break;
+ }
+
+ case TM_RESAMPLE: /* resample xRes ?yRes? ?filter? ?blur=1.0? */
+ case TM_RESAMPLE_IMAGE: /* ResampleImage xRes ?yRes? ?filter? ?blur=1.0? */
+ {
+ int filterIdx=0;
+ double xRes, yRes, blur=1.0;
+
+ if( (objc < 3) || (objc > 6) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "xRes ?yRes=xRes? ?filterType=undefined? ?blur=1.0?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &xRes)) != TCL_OK ) {
+ return stat;
+ }
+ yRes = xRes; /* default */
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &yRes)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 4) && (Tcl_GetIndexFromObj(interp, objv[4], filterNames, "filterType",
+ 0, &filterIdx) != TCL_OK) ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetDoubleFromObj(interp, objv[5], &blur)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickResampleImage(wandPtr, xRes, yRes, filterTypes[filterIdx], blur);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_RESIZE: /* resize x y ?filter? ?blur=1.0? */
+ case TM_RESIZE_IMAGE: /* ResizeImage x y ?filter? ?blur=1.0? */
+ {
+ int filterIdx=0;
+ unsigned long x, y;
+ double blur=1.0;
+
+ if( (objc < 4) || (objc > 6) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y ?filterType=undefined? ?blur=1.0?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &y)) != TCL_OK ) {
+ return stat;
+ }
+ if( (objc > 4) && (Tcl_GetIndexFromObj(interp, objv[4], filterNames, "filterType", 0, &filterIdx) != TCL_OK) ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetDoubleFromObj(interp, objv[5], &blur)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickResizeImage(wandPtr, x, y, filterTypes[filterIdx], blur);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_ROLL: /* roll xOfs yOfs */
+ case TM_ROLL_IMAGE: /* RollImage xOfs yOfs */
+ {
+ int xOfs, yOfs;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "xOfs yOfs");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &xOfs)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetIntFromObj(interp, objv[3], &yOfs)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickRollImage(wandPtr, xOfs, yOfs);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_ROTATE: /* rotate background degrees */
+ case TM_ROTATE_IMAGE: /* RotateImage background degrees */
+ {
+ double degrees;
+ PixelWand *bgPtr;
+ char *name;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "background degrees");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (bgPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &degrees)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickRotateImage(wandPtr, bgPtr, degrees);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SAMPLE: /* sample x y */
+ case TM_SAMPLE_IMAGE: /* SampleImage x y */
+ {
+ unsigned long x, y;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &y)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickSampleImage(wandPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SCALE: /* scale x y */
+ case TM_SCALE_IMAGE: /* ScaleImage x y */
+ {
+ unsigned long x, y;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &y)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickScaleImage(wandPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SEPARATE: /* separate channelType */
+ case TM_SEPARATE_CHANNEL: /* SeparateImageChannel channelType */
+ {
+ int chanIdx;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channelType");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = MagickSeparateImageChannel(wandPtr, chanTypes[chanIdx]);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SETIMAGE: /* setimage name */
+ case TM_SET_IMAGE: /* SetImage name */
+ {
+ char *name = NULL;
+ MagickWand *setWand;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "setwand");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (setWand = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ result = MagickSetImage(wandPtr, setWand);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SETOPTION: /* setoption format key value */
+ case TM_SET_OPTION: /* SetOption format key value */
+ {
+ char *format, *key, *value;
+
+ if (objc != 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "format key value");
+ return TCL_ERROR;
+ }
+ format = Tcl_GetString(objv[2]);
+ key = Tcl_GetString(objv[3]);
+ value = Tcl_GetString(objv[4]);
+ result = MagickSetImageOption(wandPtr, format, key, value);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_PASSPHRASE: /* passphrase phrase */
+ case TM_SET_PASSPHRASE: /* SetPassphrase phrase */
+ {
+ char *phrase;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "phrase");
+ return TCL_ERROR;
+ }
+ phrase = Tcl_GetString(objv[2]);
+ result = MagickSetPassphrase(wandPtr, phrase);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SHARPEN: /* sharpen ?radius? ?sigma? */
+ case TM_SHARPEN_IMAGE: /* SharpenImage ?radius? ?sigma? */
+ {
+ double radius=0.0, sigma=1.0;
+
+ if( objc > 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0? ?sigma=1.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &sigma)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickSharpenImage(wandPtr, radius, sigma);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SHAVE: /* shave x y */
+ case TM_SHAVE_IMAGE: /* ShaveImage x y */
+ {
+ unsigned long x, y;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &y)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickShaveImage(wandPtr, x, y);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SHEAR: /* shear background xShear ?yShear? */
+ case TM_SHEAR_IMAGE: /* ShearImage background xShear ?yShear? */
+ {
+ double xShear, yShear;
+ PixelWand *bgPtr;
+ char *name;
+
+ if( (objc < 4) || (objc > 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "background xShear ?yShear=xShear?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (bgPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &xShear)) != TCL_OK ) {
+ return stat;
+ }
+ yShear = xShear; /* default */
+ if( (objc > 4) && ((stat = Tcl_GetDoubleFromObj(interp, objv[4], &yShear)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickShearImage(wandPtr, bgPtr, xShear, yShear);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SOLARIZE: /* solarize ?threshold? */
+ case TM_SOLARIZE_IMAGE: /* SolarizeImage ?threshold? */
+ {
+ double threshold=0.0;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?threshold=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &threshold)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickSolarizeImage(wandPtr, threshold);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SPREAD: /* spread ?radius? */
+ case TM_SPREAD_IMAGE: /* SpreadImage ?radius? */
+ {
+ double radius=0.0;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickSpreadImage(wandPtr, radius);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_STEGANO: /* stegano watermark ?offset=0? ?newName? */
+ case TM_STEGANO_IMAGE: /* SteganoImage watermark ?offset=0? ?newName? */
+ {
+ MagickWand *watermarkPtr, *newWand;
+ char *name, *newName=NULL;
+ int offset=0;
+
+ if( objc > 5 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "watermark ?offset=0?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (watermarkPtr = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetIntFromObj(interp, objv[3], &offset)) != TCL_OK) ) {
+ return stat;
+ }
+ if( objc > 4 ) {
+ newName = Tcl_GetString(objv[4]);
+ }
+ newWand = MagickSteganoImage( wandPtr, watermarkPtr, offset );
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ newName = newWandObj(interp, newWand, newName);
+ Tcl_SetResult(interp, newName, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_STEREO: /* stereo anotherWand ?newName? */
+ case TM_STEREO_IMAGE: /* StereoImage anotherwand ?newName? */
+ {
+ MagickWand *anotherPtr, *newWand;
+ char *name, *newName=NULL;
+
+ if( objc > 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "anotherWand ?newName?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (anotherPtr = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( objc > 3 ) {
+ newName = Tcl_GetString(objv[3]);
+ }
+ newWand = MagickStereoImage( wandPtr, anotherPtr );
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ newName = newWandObj(interp, newWand, newName);
+ Tcl_SetResult(interp, newName, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_STRIP: /* strip */
+ case TM_STRIP_IMAGE: /* StripImage */
+ {
+ if( objc > 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ result = MagickStripImage(wandPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_SWIRL: /* swirl ?degrees? */
+ case TM_SWIRL_IMAGE: /* SwirlImage ?degrees? */
+ {
+ double degrees=0.0;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?degrees=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &degrees)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickSwirlImage(wandPtr, degrees);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_TEXTURE: /* texture textWand ?newName? */
+ case TM_TEXTURE_IMAGE: /* TextureImage textWand ?newName? */
+ {
+ MagickWand *textPtr, *newWand;
+ char *name, *newName=NULL;
+
+ if( objc > 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "textWand ?newName?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (textPtr = findMagickWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( objc > 3 ) {
+ newName = Tcl_GetString(objv[3]);
+ }
+ newWand = MagickTextureImage( wandPtr, textPtr );
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ newName = newWandObj(interp, newWand, newName);
+ Tcl_SetResult(interp, newName, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_THRESHOLD: /* threshold threshold */
+ case TM_THRESHOLD_IMAGE: /* ThresholdImage threshold */
+ {
+ double threshold=0.0;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "threshold");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &threshold)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickThresholdImage(wandPtr, threshold);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_THRESHOLDCHANNEL: /* thresholdchannel channelType threshold */
+ case TM_THRESHOLD_IMAGE_CHANNEL: /* ThresholdImageChannel channelType threshold */
+ {
+ int chanIdx;
+ double threshold=0.0;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "channelType threshold");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[2], chanNames, "channelType", 0, &chanIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &threshold)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickThresholdImageChannel(wandPtr, chanTypes[chanIdx], threshold);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_TINT: /* tint tintPixel opacityPixel */
+ case TM_TINT_IMAGE: /* TintImage tintPixel opacityPixel */
+ {
+ char *name;
+ PixelWand *tintPtr, *opacityPtr;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "tintPixel opacityPixel");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (tintPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[3]);
+ if( (opacityPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+
+ result = MagickTintImage(wandPtr, tintPtr, opacityPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_TRANSFORM: /* transform crop geometry ?newName? */
+ case TM_TRANSFORM_IMAGE: /* TransformImage crop geometry ?newName? */
+ {
+ MagickWand *newWand;
+ char *crop, *geometry, *newName=NULL;
+
+ if( (objc < 4) || (objc > 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "crop geometry ?newName?");
+ return TCL_ERROR;
+ }
+ crop = Tcl_GetString(objv[2]);
+ geometry = Tcl_GetString(objv[3]);
+ if( objc > 4 ) {
+ newName = Tcl_GetString(objv[4]);
+ }
+ newWand = MagickTransformImage( wandPtr, crop, geometry );
+ if (newWand == NULL) {
+ return myMagickError(interp, wandPtr);
+ }
+ newName = newWandObj(interp, newWand, newName);
+ Tcl_SetResult(interp, newName, TCL_VOLATILE);
+
+ break;
+ }
+
+ case TM_TRANSPARENT: /* transparent targetPix ?opacity? ?fuzz=0.0? */
+ case TM_TRANSPARENT_IMAGE: /* TransparentImage targetPix ?opacity? ?fuzz=0.0? */
+ {
+ double fuzz=0.0;
+ unsigned opacity=0;
+ char *name;
+ PixelWand *targetPtr;
+
+ if( (objc < 3) || (objc > 5) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "targetPix ?opacity=0? ?fuzz=0.0?");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (targetPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetIntFromObj(interp, objv[3], (int *) &opacity)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetDoubleFromObj(interp, objv[4], &fuzz)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickTransparentImage(wandPtr, targetPtr, (const Quantum)opacity, fuzz);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_TRIM: /* trim ?fuzz=0.0? */
+ case TM_TRIM_IMAGE: /* TrimImage ?fuzz=0.0? */
+ {
+ double fuzz=0.0;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?fuzz=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &fuzz)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickTrimImage(wandPtr, fuzz);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_UNSHARPMASK: /* unsharpmask ?radius? ?sigma? ?amount? ?threshold? */
+ case TM_UNSHARPMASK_IMAGE: /* UnsharpMaskImage ?radius? ?sigma? ?amount? ?threshold? */
+ {
+ double radius=0.0, sigma=1.0, amount=0.0, threshold=0.0;
+
+ if( objc > 6 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?radius=0.0? ?sigma=1.0? ?amount=0.0? ?threshold=0.0?");
+ return TCL_ERROR;
+ }
+ if( (objc > 2) && ((stat = Tcl_GetDoubleFromObj(interp, objv[2], &radius)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &sigma)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 4) && ((stat = Tcl_GetDoubleFromObj(interp, objv[4], &amount)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (objc > 5) && ((stat = Tcl_GetDoubleFromObj(interp, objv[5], &threshold)) != TCL_OK) ) {
+ return stat;
+ }
+ result = MagickUnsharpMaskImage(wandPtr, radius, sigma, amount, threshold);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_WAVE: /* wave amplitude wavelength */
+ case TM_WAVE_IMAGE: /* WaveImage amplitude wavelength */
+ {
+ double amplitude, wavelength;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "amplitude wavelength");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &amplitude)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &wavelength)) != TCL_OK ) {
+ return stat;
+ }
+ result = MagickWaveImage(wandPtr, amplitude, wavelength);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_WHITE_THRESHOLD: /* whitethreshold thresholdPixel */
+ case TM_WHITE_THRESHOLD_IMAGE: /* WhiteThresholdImage thresholdPixel */
+ {
+ char *name;
+ PixelWand *threshPtr;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "thresholdPixel");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (threshPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+
+ result = MagickWhiteThresholdImage(wandPtr, threshPtr);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_WRITE: /* write filename */
+ case TM_WRITE_IMAGE: /* WriteImage filename */
+ case TM_WRITE_IMAGES: /* WriteImages filename ?adjoin? */
+ {
+ char *filename;
+ int adjoin=0;
+ Tcl_DString extrep;
+
+ if( ((enum subIndex)index == TM_WRITE_IMAGES) && ((objc < 3) || (objc > 4)) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "filename ?adjoin=no?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index != TM_WRITE_IMAGES) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "filename");
+ return TCL_ERROR;
+ }
+ filename = Tcl_UtfToExternalDString(NULL, Tcl_GetString(objv[2]), -1, &extrep);
+ if( (objc > 3) && ((stat = Tcl_GetBooleanFromObj(interp, objv[3], &adjoin)) != TCL_OK) ) {
+ return stat;
+ }
+ if( (enum subIndex) index == TM_WRITE_IMAGES ) {
+ result = MagickWriteImages(wandPtr, filename, adjoin);
+ } else {
+ result = MagickWriteImage(wandPtr, filename);
+ }
+ Tcl_DStringFree(&extrep);
+ if (!result) {
+ return myMagickError(interp, wandPtr);
+ }
+ break;
+ }
+
+ case TM_WRITE_BLOB: /* writeblob */
+ case TM_WRITE_IMAGE_BLOB: /* WriteImageBlob */
+ {
+ unsigned char *data;
+ size_t length;
+
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ data = MagickWriteImageBlob(wandPtr, &length);
+ if(data != NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(data, length));
+ MagickRelinquishMemory(data); /* Free TclMagick resource */
+ }
+ break;
+ }
+
+ /*
+ * All subcommands should be matched
+ * A DEFAULT or TM_END_OF_TABLE would be a serious fault
+ */
+ case TM_END_OF_TABLE:
+ default:
+ {
+ Tcl_AppendResult(interp, "TclMagick wandObjCmd: Unmatched subcommand table entry", NULL);
+ return TCL_ERROR;
+ }
+
+ } /* switch(index) */
+
+ return(TCL_OK);
+}
+
+
+
+/*----------------------------------------------------------------------
+ * PixelWand object command
+ *----------------------------------------------------------------------
+ *
+ * PixelWand subcmd ?args?
+ *
+ *----------------------------------------------------------------------
+ */
+static int pixelObjCmd(
+ ClientData clientData, /* PixelWand pointer */
+ Tcl_Interp *interp, /* Interpreter containing image */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] ) /* List of arguments */
+{
+ static CONST char *subCmds[] = {
+ "set", "get", "color",
+ "SetBlack", "GetBlack", "SetBlackQuantum", "GetBlackQuantum",
+ "SetBlue", "GetBlue", "SetBlueQuantum", "GetBlueQuantum",
+ "SetCyan", "GetCyan", "SetCyanQuantum", "GetCyanQuantum",
+ "SetGreen", "GetGreen", "SetGreenQuantum", "GetGreenQuantum",
+ "SetMagenta", "GetMagenta", "SetMagentaQuantum", "GetMagentaQuantum",
+ "SetOpacity", "GetOpacity", "SetOpacityQuantum", "GetOpacityQuantum",
+ "SetRed", "GetRed", "SetRedQuantum", "GetRedQuantum",
+ "SetYellow", "GetYellow", "SetYellowQuantum", "GetYellowQuantum",
+ "SetColor", "GetColor", "GetColorAsString",
+ "SetQuantumColor", "GetQuantumColor", "quantumcolor",
+ (char *) NULL
+ };
+ enum subIndex {
+ TM_SET, TM_GET, TM_COLOR,
+ TM_SET_BLACK, TM_GET_BLACK, TM_SET_BLACK_QUANTUM, TM_GET_BLACK_QUANTUM,
+ TM_SET_BLUE, TM_GET_BLUE, TM_SET_BLUE_QUANTUM, TM_GET_BLUE_QUANTUM,
+ TM_SET_CYAN, TM_GET_CYAN, TM_SET_CYAN_QUANTUM, TM_GET_CYAN_QUANTUM,
+ TM_SET_GREEN, TM_GET_GREEN, TM_SET_GREEN_QUANTUM, TM_GET_GREEN_QUANTUM,
+ TM_SET_MAGENTA, TM_GET_MAGENTA, TM_SET_MAGENTA_QUANTUM, TM_GET_MAGENTA_QUANTUM,
+ TM_SET_OPACITY, TM_GET_OPACITY, TM_SET_OPACITY_QUANTUM, TM_GET_OPACITY_QUANTUM,
+ TM_SET_RED, TM_GET_RED, TM_SET_RED_QUANTUM, TM_GET_RED_QUANTUM,
+ TM_SET_YELLOW, TM_GET_YELLOW, TM_SET_YELLOW_QUANTUM, TM_GET_YELLOW_QUANTUM,
+ TM_SET_COLOR, TM_GET_COLOR, TM_GET_COLOR_AS_STRING,
+ TM_SET_QUANTUM, TM_GET_QUANTUM, TM_QUANTUM,
+ TM_END_OF_TABLE
+ };
+ static CONST char *colors[] = {
+ "black", "blue", "cyan", "green",
+ "magenta", "opacity", "red", "yellow",
+ (char *) NULL };
+
+ int index, stat, result, quantFlag=0;
+ int quantVal;
+ double normVal;
+ TclMagickObj *magickPtr = (TclMagickObj *) clientData;
+ PixelWand *wandPtr = (PixelWand *) magickPtr->wandPtr;
+
+#ifdef MAGICK_DEBUG
+ /*
+ * Verify subCmds table size
+ * No idea how to do this at compile-time
+ */
+ if( sizeof(subCmds)/sizeof(subCmds[0]) != TM_END_OF_TABLE + 1 ) {
+ Tcl_Panic("pixelObjCmd: Invalid subCmds[] table");
+ }
+#endif
+
+ if( objc < 2 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "subcmd ?args?" );
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[1], subCmds, "subcmd", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum subIndex)index) {
+
+ case TM_SET: /* set ?-quant*um? color val color val ... */
+ {
+ int color;
+
+ if( objc < 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-quant*? color value color value ...");
+ return TCL_ERROR;
+ }
+ if( strncmp(Tcl_GetString(objv[2]), "-quant", 6) == 0 ) {
+ quantFlag = 1;
+ objv += 3, objc -= 3;
+ } else {
+ quantFlag = 0;
+ objv += 2, objc -= 2;
+ }
+ while( objc > 0 ) {
+ if (Tcl_GetIndexFromObj(interp, objv[0], colors, "color", 0, &color) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( objc == 1 ) {
+ Tcl_AppendResult(interp, "Magick: Missing value for color ", objv[0], NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[1], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ switch(color) {
+ case 0: PixelSetBlackQuantum(wandPtr, (Quantum)quantVal); break;
+ case 1: PixelSetBlueQuantum(wandPtr, (Quantum)quantVal); break;
+ case 2: PixelSetCyanQuantum(wandPtr, (Quantum)quantVal); break;
+ case 3: PixelSetGreenQuantum(wandPtr, (Quantum)quantVal); break;
+ case 4: PixelSetMagentaQuantum(wandPtr, (Quantum)quantVal); break;
+ case 5: PixelSetOpacityQuantum(wandPtr, (Quantum)quantVal); break;
+ case 6: PixelSetRedQuantum(wandPtr, (Quantum)quantVal); break;
+ case 7: PixelSetYellowQuantum(wandPtr, (Quantum)quantVal); break;
+ }
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[1], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ switch(color) {
+ case 0: PixelSetBlack(wandPtr, normVal); break;
+ case 1: PixelSetBlue(wandPtr, normVal); break;
+ case 2: PixelSetCyan(wandPtr, normVal); break;
+ case 3: PixelSetGreen(wandPtr, normVal); break;
+ case 4: PixelSetMagenta(wandPtr, normVal); break;
+ case 5: PixelSetOpacity(wandPtr, normVal); break;
+ case 6: PixelSetRed(wandPtr, normVal); break;
+ case 7: PixelSetYellow(wandPtr, normVal); break;
+ }
+ }
+ objv += 2, objc -= 2;
+ }
+ break;
+ }
+
+ case TM_GET: /* get -quantum color color ... */
+ {
+ Tcl_Obj *listPtr;
+ int color;
+
+ if( objc < 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-quant*? color color ...");
+ return TCL_ERROR;
+ }
+ if( strncmp(Tcl_GetString(objv[2]), "-quant", 6) == 0 ) {
+ quantFlag = 1;
+ objv += 3, objc -= 3;
+ } else {
+ quantFlag = 0;
+ objv += 2, objc -= 2;
+ }
+ listPtr = Tcl_NewListObj(0, NULL);
+ while( objc > 0 ) {
+ if (Tcl_GetIndexFromObj(interp, objv[0], colors, "color", 0, &color) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ switch(color) {
+ case 0: quantVal = PixelGetBlackQuantum(wandPtr); break;
+ case 1: quantVal = PixelGetBlueQuantum(wandPtr); break;
+ case 2: quantVal = PixelGetCyanQuantum(wandPtr); break;
+ case 3: quantVal = PixelGetGreenQuantum(wandPtr); break;
+ case 4: quantVal = PixelGetMagentaQuantum(wandPtr); break;
+ case 5: quantVal = PixelGetOpacityQuantum(wandPtr); break;
+ case 6: quantVal = PixelGetRedQuantum(wandPtr); break;
+ case 7: quantVal = PixelGetYellowQuantum(wandPtr); break;
+ }
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(quantVal));
+ } else {
+ switch(color) {
+ case 0: normVal = PixelGetBlack(wandPtr); break;
+ case 1: normVal = PixelGetBlue(wandPtr); break;
+ case 2: normVal = PixelGetCyan(wandPtr); break;
+ case 3: normVal = PixelGetGreen(wandPtr); break;
+ case 4: normVal = PixelGetMagenta(wandPtr); break;
+ case 5: normVal = PixelGetOpacity(wandPtr); break;
+ case 6: normVal = PixelGetRed(wandPtr); break;
+ case 7: normVal = PixelGetYellow(wandPtr); break;
+ }
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(normVal));
+ }
+ objv += 1, objc -= 1;
+ }
+ Tcl_SetObjResult(interp, listPtr);
+
+ break;
+ }
+
+ case TM_COLOR: /* color ?string? */
+ case TM_SET_COLOR: /* SetColor string */
+ case TM_GET_COLOR: /* GetColor */
+ case TM_GET_COLOR_AS_STRING: /* GetColorAsString */
+ {
+ char *color;
+
+ if( ((enum subIndex)index == TM_COLOR) && (objc != 2) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?string?");
+ return TCL_ERROR;
+ } else if ( ((enum subIndex)index == TM_SET_COLOR) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "string");
+ return TCL_ERROR;
+ } else if ( ((enum subIndex)index == TM_GET_COLOR) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if ( ((enum subIndex)index == TM_GET_COLOR_AS_STRING) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( objc == 3 ) { /* Set color */
+ color = Tcl_GetString(objv[2]);
+ result = PixelSetColor(wandPtr, color);
+ if( !result ) {
+ Tcl_AppendResult(interp, "Magick: Invalid color ", color, NULL);
+ return TCL_ERROR;
+ }
+ } else {
+ color = PixelGetColorAsString(wandPtr);
+ Tcl_SetResult(interp, color, TCL_VOLATILE);
+ MagickRelinquishMemory(color); /* Free TclMagick resource */
+ }
+
+ break;
+ }
+
+ case TM_SET_BLACK_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_SET_BLACK:
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetBlackQuantum(wandPtr, (Quantum)quantVal);
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetBlack(wandPtr, normVal);
+ }
+ break;
+ }
+
+ case TM_SET_BLUE_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_SET_BLUE:
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetBlueQuantum(wandPtr, (Quantum)quantVal);
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetBlue(wandPtr, normVal);
+ }
+ break;
+ }
+
+ case TM_SET_CYAN_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_SET_CYAN:
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetCyanQuantum(wandPtr, (Quantum)quantVal);
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetCyan(wandPtr, normVal);
+ }
+ break;
+ }
+
+ case TM_SET_GREEN_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_SET_GREEN:
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetGreenQuantum(wandPtr, (Quantum)quantVal);
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetGreen(wandPtr, normVal);
+ }
+ break;
+ }
+
+ case TM_SET_MAGENTA_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_SET_MAGENTA:
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetMagentaQuantum(wandPtr, (Quantum)quantVal);
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetMagenta(wandPtr, normVal);
+ }
+ break;
+ }
+
+ case TM_SET_OPACITY_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_SET_OPACITY:
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetOpacityQuantum(wandPtr, (Quantum)quantVal);
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetOpacity(wandPtr, normVal);
+ }
+ break;
+ }
+
+ case TM_SET_RED_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_SET_RED:
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetRedQuantum(wandPtr, (Quantum)quantVal);
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetRed(wandPtr, normVal);
+ }
+ break;
+ }
+
+ case TM_SET_YELLOW_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_SET_YELLOW:
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &quantVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetYellowQuantum(wandPtr, (Quantum)quantVal);
+ } else {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &normVal)) != TCL_OK ) {
+ return stat;
+ }
+ PixelSetYellow(wandPtr, normVal);
+ }
+ break;
+ }
+
+ case TM_GET_BLACK_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_GET_BLACK:
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ quantVal = PixelGetBlackQuantum(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(quantVal));
+ } else {
+ normVal = PixelGetBlack(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(normVal));
+ }
+ break;
+ }
+
+ case TM_GET_BLUE_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_GET_BLUE:
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ quantVal = PixelGetBlueQuantum(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(quantVal));
+ } else {
+ normVal = PixelGetBlue(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(normVal));
+ }
+ break;
+ }
+
+ case TM_GET_CYAN_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_GET_CYAN:
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ quantVal = PixelGetCyanQuantum(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(quantVal));
+ } else {
+ normVal = PixelGetCyan(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(normVal));
+ }
+ break;
+ }
+
+ case TM_GET_GREEN_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_GET_GREEN:
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ quantVal = PixelGetGreenQuantum(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(quantVal));
+ } else {
+ normVal = PixelGetGreen(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(normVal));
+ }
+ break;
+ }
+
+ case TM_GET_MAGENTA_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_GET_MAGENTA:
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ quantVal = PixelGetMagentaQuantum(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(quantVal));
+ } else {
+ normVal = PixelGetMagenta(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(normVal));
+ }
+ break;
+ }
+
+ case TM_GET_OPACITY_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_GET_OPACITY:
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ quantVal = PixelGetOpacityQuantum(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(quantVal));
+ } else {
+ normVal = PixelGetOpacity(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(normVal));
+ }
+ break;
+ }
+
+ case TM_GET_RED_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_GET_RED:
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ quantVal = PixelGetRedQuantum(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(quantVal));
+ } else {
+ normVal = PixelGetRed(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(normVal));
+ }
+ break;
+ }
+
+ case TM_GET_YELLOW_QUANTUM:
+ {
+ quantFlag = 1; /* and continue ... */
+ }
+ case TM_GET_YELLOW:
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( quantFlag ) {
+ quantVal = PixelGetYellowQuantum(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(quantVal));
+ } else {
+ normVal = PixelGetYellow(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(normVal));
+ }
+ break;
+ }
+
+ case TM_QUANTUM: /* quantum ?{r g b o}? */
+ case TM_GET_QUANTUM: /* GetQuantum */
+ case TM_SET_QUANTUM: /* SetQuantum {r g b o} */
+ {
+ PixelPacket color;
+
+ if( ((enum subIndex)index == TM_QUANTUM) && (objc != 2) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?{r g b o}?");
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_GET_QUANTUM) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ if( ((enum subIndex)index == TM_SET_QUANTUM) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "{r g b o}");
+ return TCL_ERROR;
+ }
+ if( objc == 3 ) {
+ /*
+ * Set quantum values
+ */
+ Tcl_Obj **listPtr;
+ unsigned long quant[4];
+ int i, listLen;
+
+ if( (stat = Tcl_ListObjGetElements(interp, objv[2], &listLen, &listPtr)) != TCL_OK ) {
+ return stat;
+ }
+ if( listLen != 4 ) {
+ Tcl_AppendResult(interp, "PixelWand SetQuantum: List of 4 colors {r g b o} required", NULL);
+ return TCL_ERROR;
+ }
+ for( i=0; i < 4; i++ ) {
+ if( (stat = Tcl_GetLongFromObj(interp, listPtr[i], (long int *) &quant[i])) != TCL_OK) {
+ return stat;
+ }
+ }
+ color.red = (Quantum) quant[0];
+ color.green = (Quantum) quant[1];
+ color.blue = (Quantum) quant[2];
+ color.opacity = (Quantum) quant[3];
+
+ PixelSetQuantumColor(wandPtr, &color);
+ } else {
+ /*
+ * Get quantum values
+ */
+ Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);;
+
+ PixelGetQuantumColor(wandPtr, &color);
+
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj(color.red));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj(color.green));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj(color.blue));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewLongObj(color.opacity));
+
+ Tcl_SetObjResult(interp, listPtr);
+ }
+ break;
+ }
+ /*
+ * All subcommands should be matched
+ * A DEFAULT or TM_END_OF_TABLE would be a serious fault
+ */
+ case TM_END_OF_TABLE:
+ default:
+ {
+ Tcl_AppendResult(interp, "TclMagick pixelObjCmd: Unmatched subcommand table entry", NULL);
+ return TCL_ERROR;
+ }
+
+ } /* switch(index) */
+
+ return(TCL_OK);
+}
+
+
+/*----------------------------------------------------------------------
+ * DrawingWand object command
+ *----------------------------------------------------------------------
+ *
+ * DrawWand subcmd ?args?
+ *
+ *----------------------------------------------------------------------
+ */
+static int drawObjCmd(
+ ClientData clientData, /* DrawingWand pointer */
+ Tcl_Interp *interp, /* Interpreter containing image */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] ) /* List of arguments */
+{
+ static CONST char *subCmds[] = {
+ "affine", "Affine",
+ "annotation", "Annotation",
+ "arc", "Arc",
+ "bezier", "Bezier",
+ "circle", "Circle",
+ "clippath", "GetClipPath", "SetClipPath",
+ "cliprule", "GetClipRule", "SetClipRule",
+ "clipunits", "GetClipUnits", "SetClipUnits",
+ "color", "Color",
+ "comment", "Comment",
+ "ellipse", "Ellipse",
+ "fillcolor", "GetFillColor", "SetFillColor",
+ "fillopacity", "GetFillOpacity", "SetFillOpacity",
+ "fillpatternurl", "SetFillPatternURL",
+ "fillrule", "GetFillRule", "SetFillRule",
+ "font", "GetFont", "SetFont",
+ "fontfamily", "GetFontFamily", "SetFontFamily",
+ "fontsize", "GetFontSize", "SetFontSize",
+ "fontstretch", "GetFontStretch", "SetFontStretch",
+ "fontstyle", "GetFontStyle", "SetFontStyle",
+ "fontweight", "GetFontWeight", "SetFontWeight",
+ "gravity", "GetGravity", "SetGravity",
+ "line", "Line",
+ "matte", "Matte",
+ "point", "Point",
+ "polygon", "Polygon",
+ "polyline", "Polyline",
+ "path",
+ "push", "pop",
+ "PushClipPath", "PopClipPath",
+ "PushDefs", "PopDefs",
+ "PushGraphicContext","PopGraphicContext",
+ "PushPattern", "PopPattern",
+ "rectangle", "Rectangle",
+ "render", "Render",
+ "rotate", "Rotate",
+ "round", "RoundRectangle",
+ "scale", "Scale",
+ "skewx", "SkewX",
+ "skewy", "SkewY",
+ "strokecolor", "GetStrokeColor", "SetStrokeColor",
+ "strokeantialias", "GetStrokeAntialias", "SetStrokeAntialias",
+ "strokedasharray", "GetStrokeDashArray", "SetStrokeDashArray",
+ "strokedashoffset", "GetStrokeDashOffset", "SetStrokeDashOffset",
+ "strokelinecap", "GetStrokeLineCap", "SetStrokeLineCap",
+ "strokelinejoin", "GetStrokeLineJoin", "SetStrokeLineJoin",
+ "strokemiterlimit", "GetStrokeMiterLimit", "SetStrokeMiterLimit",
+ "strokeopacity", "GetStrokeOpacity", "SetStrokeOpacity",
+ "strokepatternurl", "SetStrokePatternURL",
+ "strokewidth", "GetStrokeWidth", "SetStrokeWidth",
+ "textantialias", "GetTextAntialias", "SetTextAntialias",
+ "textdecoration", "GetTextDecoration", "SetTextDecoration",
+ "textencoding", "GetTextEncoding", "SetTextEncoding",
+ "textundercolor", "GetTextUnderColor", "SetTextUnderColor",
+ "translate", "Translate",
+ "viewbox", "SetViewbox",
+ (char *) NULL
+ };
+ enum subIndex {
+ TM_AFFINE, TM_AAFFINE,
+ TM_ANNOTATION, TM_AANNOTATION,
+ TM_ARC, TM_AARC,
+ TM_BEZIER, TM_BBEZIER,
+ TM_CIRCLE, TM_CCIRCLE,
+ TM_CLIPPATH, TM_GET_CLIPPATH, TM_SET_CLIPPATH,
+ TM_CLIPRULE, TM_GET_CLIPRULE, TM_SET_CLIPRULE,
+ TM_CLIPUNITS, TM_GET_CLIPUNITS, TM_SET_CLIPUNITS,
+ TM_COLOR, TM_CCOLOR,
+ TM_COMMENT, TM_CCOMMENT,
+ TM_ELLIPSE, TM_EELLIPSE,
+ TM_FILLCOLOR, TM_GET_FILLCOLOR, TM_SET_FILLCOLOR,
+ TM_FILLOPACITY, TM_GET_FILLOPACITY, TM_SET_FILLOPACITY,
+ TM_FILLPATTERNURL, TM_SET_FILLPATTERNURL,
+ TM_FILLRULE, TM_GET_FILLRULE, TM_SET_FILLRULE,
+ TM_FONT, TM_GET_FONT, TM_SET_FONT,
+ TM_FONTFAMILY, TM_GET_FONTFAMILY, TM_SET_FONTFAMILY,
+ TM_FONTSIZE, TM_GET_FONTSIZE, TM_SET_FONTSIZE,
+ TM_FONTSTRETCH, TM_GET_FONTSTRETCH, TM_SET_FONTSTRETCH,
+ TM_FONTSTYLE, TM_GET_FONTSTYLE, TM_SET_FONTSTYLE,
+ TM_FONTWEIGHT, TM_GET_FONTWEIGHT, TM_SET_FONTWEIGHT,
+ TM_GRAVITY, TM_GET_GRAVITY, TM_SET_GRAVITY,
+ TM_LINE, TM_LLINE,
+ TM_MATTE, TM_MMATTE,
+ TM_POINT, TM_PPOINT,
+ TM_POLYGON, TM_PPOLYGON,
+ TM_POLYLINE, TM_PPOLYLINE,
+ TM_PATH,
+ TM_PUSH, TM_POP,
+ TM_PUSH_CLIPPATH, TM_POP_CLIPPATH,
+ TM_PUSH_DEFS, TM_POP_DEFS,
+ TM_PUSH_GRAPHIC_CTX,TM_POP_GRAPHIC_CTX,
+ TM_PUSH_PATTERN, TM_POP_PATTERN,
+ TM_RECTANGLE, TM_RRECTANGLE,
+ TM_RENDER, TM_RRENDER,
+ TM_ROTATE, TM_RROTATE,
+ TM_ROUND, TM_ROUND_RECTANGLE,
+ TM_SCALE, TM_SSCALE,
+ TM_SKEWX, TM_SKEW_X,
+ TM_SKEWY, TM_SKEW_Y,
+ TM_STROKE_COLOR, TM_GET_STROKE_COLOR, TM_SET_STROKE_COLOR,
+ TM_STROKE_ANTIALIAS,TM_GET_STROKE_ANTIALIAS, TM_SET_STROKE_ANTIALIAS,
+ TM_STROKE_DASHARRAY,TM_GET_STROKE_DASHARRAY, TM_SET_STROKE_DASHARRAY,
+ TM_STROKE_DASHOFFS, TM_GET_STROKE_DASHOFFS, TM_SET_STROKE_DASHOFFS,
+ TM_STROKE_LINECAP, TM_GET_STROKE_LINECAP, TM_SET_STROKE_LINECAP,
+ TM_STROKE_LINEJOIN, TM_GET_STROKE_LINEJOIN, TM_SET_STROKE_LINEJOIN,
+ TM_STROKE_MITERLIM, TM_GET_STROKE_MITERLIM, TM_SET_STROKE_MITERLIM,
+ TM_STROKE_OPACITY, TM_GET_STROKE_OPACITY, TM_SET_STROKE_OPACITY,
+ TM_STROKE_PATTERNURL, TM_SET_STROKE_PATTERNURL,
+ TM_STROKE_WIDTH, TM_GET_STROKE_WIDTH, TM_SET_STROKE_WIDTH,
+ TM_TEXT_ANTIALIAS, TM_GET_TEXT_ANTIALIAS, TM_SET_TEXT_ANTIALIAS,
+ TM_TEXT_DECORATION, TM_GET_TEXT_DECORATION, TM_SET_TEXT_DECORATION,
+ TM_TEXT_ENCODING, TM_GET_TEXT_ENCODING, TM_SET_TEXT_ENCODING,
+ TM_TEXT_UNDERCOLOR, TM_GET_TEXT_UNDERCOLOR, TM_SET_TEXT_UNDERCOLOR,
+ TM_TRANSLATE, TM_TTRANSLATE,
+ TM_VIEWBOX, TM_SET_VIEWBOX,
+ TM_END_OF_TABLE
+ };
+ static CONST char *pushCmdNames[] = {
+ "clippath", "defs", "graphiccontext", "pattern",
+ (char *) NULL
+ };
+ enum pushCmdIndex {
+ TM_PUSH_CMD_CLIP, TM_PUSH_CMD_DEFS, TM_PUSH_CMD_GRAPH, TM_PUSH_CMD_PAT,
+ };
+ static CONST char *fillRuleNames[] = {
+ "undefined","evenodd","nonzero",
+ (char *) NULL
+ };
+ static FillRule fillRules[] = {
+ UndefinedRule, EvenOddRule, NonZeroRule
+ };
+ static CONST char *paintMethodNames[] = {
+ "point", "replace", "floodfill", "filltoborder", "reset",
+ (char *) NULL
+ };
+ static PaintMethod paintMethods[] = {
+ PointMethod, ReplaceMethod, FloodfillMethod, FillToBorderMethod, ResetMethod
+ };
+ int index, stat;
+ TclMagickObj *magickPtr = (TclMagickObj *) clientData;
+ DrawingWand *wandPtr = (DrawingWand *) magickPtr->wandPtr;
+
+#ifdef MAGICK_DEBUG
+ /*
+ * Verify subCmds table size
+ * No idea how to do this at compile-time
+ */
+ if( sizeof(subCmds)/sizeof(subCmds[0]) != TM_END_OF_TABLE + 1 ) {
+ Tcl_Panic("magickObjCmd: Invalid subCmds[] table");
+ }
+#endif
+
+ if( objc < 2 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "subcmd ?args?" );
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[1], subCmds, "subcmd", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch ((enum subIndex)index) {
+
+ case TM_AFFINE: /* affine sx rx ry sy tx ty */
+ case TM_AAFFINE: /* Affine sx rx ry sy tx ty */
+ {
+ AffineMatrix A;
+
+ if( objc != 8 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "sx rx ry sy tx ty");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &A.sx)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &A.rx)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &A.ry)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &A.sy)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[6], &A.tx)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[7], &A.ty)) != TCL_OK ) {
+ return stat;
+ }
+ DrawAffine(wandPtr, &A);
+ break;
+ }
+
+ case TM_ANNOTATION: /* annotation x y text */
+ case TM_AANNOTATION: /* Annotation x y text */
+ {
+ double x, y;
+ unsigned char *text;
+
+ if( objc != 5 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y text");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ text = (unsigned char *) Tcl_GetString(objv[4]);
+ DrawAnnotation(wandPtr, x, y, text);
+ break;
+ }
+
+ case TM_ARC: /* arc sx sy ex ey sd ed */
+ case TM_AARC: /* Arc sx sy ex ey sd ed */
+ {
+ double sx, sy, ex, ey, sd, ed;
+
+ if( objc != 8 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "sx sy ex ey sd ed");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &sx)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &sy)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &ex)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &ey)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[6], &sd)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[7], &ed)) != TCL_OK ) {
+ return stat;
+ }
+ DrawArc(wandPtr, sx, sy, ex, ey, sd, ed);
+ break;
+ }
+
+ case TM_BEZIER: /* bezier x y x y ... */
+ case TM_BBEZIER: /* Bezier x y x y ... */
+ case TM_POLYGON: /* polygon x y x y ... */
+ case TM_PPOLYGON: /* Polygon x y x y ... */
+ case TM_POLYLINE: /* polyline x y x y ... */
+ case TM_PPOLYLINE: /* Polyline x y x y ... */
+ {
+ PointInfo *coordinates;
+ unsigned long i, num;
+
+ if( (objc-2) % 2 != 0 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y x y ...");
+ return TCL_ERROR;
+ }
+ num = (objc-2)/2; /* number of coordinates */
+ coordinates = (PointInfo *)ckalloc(num*sizeof(coordinates[0]));
+ if( coordinates == NULL ) {
+ Tcl_AppendResult(interp, "TclMagick: out of memory", NULL);
+ return TCL_ERROR;
+ }
+ memset( coordinates, 0, num*sizeof(coordinates[0]) );
+
+ objc -= 2, objv += 2;
+ for( i=0; i<num; i++) {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[0], &coordinates[i].x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[1], &coordinates[i].y)) != TCL_OK ) {
+ return stat;
+ }
+ objc -= 2, objv +=2;
+ }
+ switch ((enum subIndex)index) {
+ case TM_BEZIER: case TM_BBEZIER:
+ DrawBezier(wandPtr, num, coordinates);
+ break;
+ case TM_POLYGON: case TM_PPOLYGON:
+ DrawPolygon(wandPtr, num, coordinates);
+ break;
+ case TM_POLYLINE: case TM_PPOLYLINE:
+ DrawPolyline(wandPtr, num, coordinates);
+ break;
+ default:
+ break;
+ }
+
+ ckfree((char *)coordinates);
+ break;
+ }
+
+ case TM_CIRCLE: /* circle ox oy px py */
+ case TM_CCIRCLE: /* Circle ox oy px py */
+ {
+ double ox, oy, px, py;
+
+ if( objc != 6 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "ox oy px py");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &ox)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &oy)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &px)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &py)) != TCL_OK ) {
+ return stat;
+ }
+ DrawCircle(wandPtr, ox, oy, px, py);
+ break;
+ }
+
+ case TM_COLOR: /* color x y paintMethod */
+ case TM_CCOLOR: /* Color x y paintMethod */
+ {
+ double x, y;
+ int paintIdx;
+
+ if( objc != 5 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y paintMethod");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[4], paintMethodNames, "paintMethod", 0, &paintIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawColor(wandPtr, x, y, paintMethods[paintIdx]);
+ break;
+ }
+
+ case TM_COMMENT: /* comment text */
+ case TM_CCOMMENT: /* Comment text */
+ {
+ char *text;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "text");
+ return TCL_ERROR;
+ }
+ text = Tcl_GetString(objv[2]);
+ DrawComment(wandPtr, text);
+ break;
+ }
+
+ case TM_ELLIPSE: /* ellipse ox oyo rx ry start end */
+ case TM_EELLIPSE: /* Ellipse ox oyo rx ry start end */
+ {
+ double ox, oy, rx, ry, start, end;
+
+ if( objc != 8 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "ox oy rx ry start end");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &ox)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &oy)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &rx)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &ry)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[6], &start)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[7], &end)) != TCL_OK ) {
+ return stat;
+ }
+ DrawEllipse(wandPtr, ox, oy, rx, ry, start, end);
+ break;
+ }
+
+ case TM_CLIPPATH: /* clippath ?name? */
+ case TM_GET_CLIPPATH: /* GetClipPath */
+ case TM_SET_CLIPPATH: /* SetClipPath name */
+ {
+ char *name;
+
+ if( ((enum subIndex)index == TM_CLIPPATH) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?name?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_CLIPPATH) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_CLIPPATH) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set name */
+ name = Tcl_GetString(objv[2]);
+ DrawSetClipPath(wandPtr, name);
+ } else { /* Get name */
+ name = (char *)DrawGetClipPath(wandPtr);
+ if(name != NULL) {
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+ MagickRelinquishMemory(name);
+ }
+ }
+ break;
+ }
+
+ case TM_CLIPRULE: /* cliprule ?rule? */
+ case TM_GET_CLIPRULE: /* GetClipRule */
+ case TM_SET_CLIPRULE: /* SetClipRule rule */
+ {
+ int ruleIdx;
+ FillRule rule;
+
+ if( ((enum subIndex)index == TM_CLIPRULE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?rule?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_CLIPRULE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_CLIPRULE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "rule");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set rule */
+ if (Tcl_GetIndexFromObj(interp, objv[2], fillRuleNames, "fillRule", 0, &ruleIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetClipRule(wandPtr, fillRules[ruleIdx]);
+ } else { /* Get rule */
+ rule = DrawGetClipRule(wandPtr);
+ for (ruleIdx = 0; (size_t) ruleIdx < sizeof(fillRules)/sizeof(fillRules[0]); ruleIdx++) {
+ if( fillRules[ruleIdx] == rule ) {
+ Tcl_SetResult(interp, (char *)fillRuleNames[ruleIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)rule));
+ }
+ break;
+ }
+
+ case TM_CLIPUNITS: /* clipunits ?unit? */
+ case TM_GET_CLIPUNITS: /* GetClipUnits */
+ case TM_SET_CLIPUNITS: /* SetClipunits unit */
+ {
+ static CONST char *unitNames[] = {
+ "userspace", "userspaceonuse", "objectboundingbox",
+ (char *) NULL
+ };
+ static ClipPathUnits unitTypes[] = {
+ UserSpace, UserSpaceOnUse, ObjectBoundingBox
+ };
+ int unitIdx;
+ ClipPathUnits unit;
+
+ if( ((enum subIndex)index == TM_CLIPUNITS) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?unit?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_CLIPUNITS) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_CLIPUNITS) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "unit");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set rule */
+ if (Tcl_GetIndexFromObj(interp, objv[2], unitNames, "unit", 0, &unitIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetClipUnits(wandPtr, unitTypes[unitIdx]);
+ } else { /* Get rule */
+ unit = DrawGetClipUnits(wandPtr);
+ for (unitIdx = 0; (size_t) unitIdx < sizeof(unitTypes)/sizeof(unitTypes[0]); unitIdx++) {
+ if( unitTypes[unitIdx] == unit ) {
+ Tcl_SetResult(interp, (char *)unitNames[unitIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)unit));
+ }
+ break;
+ }
+
+ case TM_FILLCOLOR: /* fillcolor ?pixel? */
+ case TM_STROKE_COLOR: /* strokecolor ?pixel? */
+ case TM_TEXT_UNDERCOLOR: /* textundercolor ?pixel? */
+ {
+ PixelWand *pixelPtr = NULL;
+ char *name = NULL;
+
+ if( objc > 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?pixelName?");
+ return TCL_ERROR;
+ }
+ if (objc > 2) { /* Set color / Get color with new name */
+ name = Tcl_GetString(objv[2]);
+ pixelPtr = findPixelWand(interp, name);
+ }
+ /*
+ * GET color if pixel object doesn't exists
+ * otherwise SET color
+ */
+ if( pixelPtr == NULL ) {
+ pixelPtr = NewPixelWand();
+ name = newPixelObj(interp, pixelPtr, name );
+
+ switch ((enum subIndex)index) {
+ case TM_FILLCOLOR:
+ DrawGetFillColor(wandPtr, pixelPtr);
+ break;
+ case TM_STROKE_COLOR:
+ DrawGetStrokeColor(wandPtr, pixelPtr);
+ break;
+ case TM_TEXT_UNDERCOLOR:
+ DrawGetTextUnderColor(wandPtr, pixelPtr);
+ break;
+ default:
+ break;
+ }
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+
+ } else {
+ switch ((enum subIndex)index) {
+ case TM_FILLCOLOR:
+ DrawSetFillColor(wandPtr, pixelPtr);
+ break;
+ case TM_STROKE_COLOR:
+ DrawSetStrokeColor(wandPtr, pixelPtr);
+ break;
+ case TM_TEXT_UNDERCOLOR:
+ DrawSetTextUnderColor(wandPtr, pixelPtr);
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+
+ case TM_GET_FILLCOLOR: /* GetFillColor pixel */
+ case TM_GET_STROKE_COLOR: /* GetStrokeColor pixel */
+ case TM_GET_TEXT_UNDERCOLOR: /* GetTextUnderColor pixel */
+ {
+ PixelWand *pixelPtr;
+ char *name;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pixelName");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (pixelPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ switch ((enum subIndex)index) {
+ case TM_GET_FILLCOLOR:
+ DrawGetFillColor(wandPtr, pixelPtr);
+ break;
+ case TM_GET_STROKE_COLOR:
+ DrawGetStrokeColor(wandPtr, pixelPtr);
+ break;
+ case TM_GET_TEXT_UNDERCOLOR:
+ DrawGetTextUnderColor(wandPtr, pixelPtr);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ case TM_SET_FILLCOLOR: /* SetFillColor pixel */
+ case TM_SET_STROKE_COLOR: /* SetStrokeColor pixel */
+ case TM_SET_TEXT_UNDERCOLOR: /* SetTextUnderColor pixel */
+ {
+ PixelWand *pixelPtr;
+ char *name;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "pixelName");
+ return TCL_ERROR;
+ }
+ name = Tcl_GetString(objv[2]);
+ if( (pixelPtr = findPixelWand(interp, name)) == NULL ) {
+ return TCL_ERROR;
+ }
+ switch ((enum subIndex)index) {
+ case TM_SET_FILLCOLOR:
+ DrawSetFillColor(wandPtr, pixelPtr);
+ break;
+ case TM_SET_STROKE_COLOR:
+ DrawSetStrokeColor(wandPtr, pixelPtr);
+ break;
+ case TM_SET_TEXT_UNDERCOLOR:
+ DrawSetTextUnderColor(wandPtr, pixelPtr);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ case TM_FILLOPACITY: /* fillopacity ?value? */
+ case TM_GET_FILLOPACITY: /* GetFillOpacity */
+ case TM_SET_FILLOPACITY: /* SetFillOpacity value */
+ {
+ double value;
+
+ if( ((enum subIndex)index == TM_FILLOPACITY) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?value?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_FILLOPACITY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_FILLOPACITY) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set fill opacity */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &value)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetFillOpacity(wandPtr, value);
+ } else { /* Get fill opacity */
+ value = DrawGetFillOpacity(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value));
+ }
+ break;
+ }
+
+ case TM_FILLPATTERNURL: /* fillpatternurl url */
+ case TM_SET_FILLPATTERNURL: /* SetFillPatternURL url */
+ {
+ char *url;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "url");
+ return TCL_ERROR;
+ }
+ url = Tcl_GetString(objv[2]);
+ DrawSetFillPatternURL(wandPtr, url);
+ break;
+ }
+
+ case TM_FILLRULE: /* fillrule ?rule? */
+ case TM_GET_FILLRULE: /* GetFillRule */
+ case TM_SET_FILLRULE: /* SetFillRule rule */
+ {
+ int ruleIdx;
+ FillRule rule;
+
+ if( ((enum subIndex)index == TM_FILLRULE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?rule?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_FILLRULE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_FILLRULE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "rule");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set rule */
+ if (Tcl_GetIndexFromObj(interp, objv[2], fillRuleNames, "fillRule", 0, &ruleIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetFillRule(wandPtr, fillRules[ruleIdx]);
+ } else { /* Get rule */
+ rule = DrawGetFillRule(wandPtr);
+ for (ruleIdx = 0; (size_t) ruleIdx < sizeof(fillRules)/sizeof(fillRules[0]); ruleIdx++) {
+ if( fillRules[ruleIdx] == rule ) {
+ Tcl_SetResult(interp, (char *)fillRuleNames[ruleIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)rule));
+ }
+ break;
+ }
+
+ case TM_FONT: /* font ?fontname? */
+ case TM_GET_FONT: /* GetFont */
+ case TM_SET_FONT: /* SetFont fontname */
+ {
+ char *fontname;
+
+ if( ((enum subIndex)index == TM_FONT) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?fontname?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_FONT) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_FONT) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "fontname");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set font */
+ fontname = Tcl_GetString(objv[2]);
+ DrawSetFont(wandPtr, fontname);
+ } else { /* Get font */
+ fontname = DrawGetFont(wandPtr);
+ if(fontname != NULL) {
+ Tcl_SetResult(interp, fontname, TCL_VOLATILE);
+ MagickRelinquishMemory(fontname); /* Free TclMagick resource */
+ }
+ }
+ break;
+ }
+
+ case TM_FONTFAMILY: /* fontfamily ?name? */
+ case TM_GET_FONTFAMILY: /* GetFontFamily */
+ case TM_SET_FONTFAMILY: /* SetFontFamily name */
+ {
+ char *name;
+
+ if( ((enum subIndex)index == TM_FONTFAMILY) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?name?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_FONTFAMILY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_FONTFAMILY) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set font family */
+ name = Tcl_GetString(objv[2]);
+ DrawSetFontFamily(wandPtr, name);
+ } else { /* Get font family */
+ name = DrawGetFontFamily(wandPtr);
+ if(name != NULL) {
+ Tcl_SetResult(interp, name, TCL_VOLATILE);
+ MagickRelinquishMemory(name); /* Free TclMagick resource */
+ }
+ }
+ break;
+ }
+
+ case TM_FONTSIZE: /* fontsize ?value? */
+ case TM_GET_FONTSIZE: /* GetFontSize */
+ case TM_SET_FONTSIZE: /* SetFontSize value */
+ {
+ double value;
+
+ if( ((enum subIndex)index == TM_FONTSIZE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?value?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_FONTSIZE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_FONTSIZE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set font size */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &value)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetFontSize(wandPtr, value);
+ } else { /* Get font size */
+ value = DrawGetFontSize(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(value));
+ }
+ break;
+ }
+
+ case TM_FONTSTRETCH: /* fontstretch ?stretchType? */
+ case TM_GET_FONTSTRETCH: /* GetFontStretch */
+ case TM_SET_FONTSTRETCH: /* SetFontStretch stretchType */
+ {
+ static CONST char *stretchNames[] = {
+ "normal", "ultracondensed", "extracondensed", "condensed",
+ "semicondensed", "semiexpanded", "expanded", "extraexpanded",
+ "ultraexpanded", "any",
+ (char *) NULL
+ };
+ static StretchType stretchTypes[] = {
+ NormalStretch, UltraCondensedStretch, ExtraCondensedStretch, CondensedStretch,
+ SemiCondensedStretch, SemiExpandedStretch, ExpandedStretch, ExtraExpandedStretch,
+ UltraExpandedStretch, AnyStretch
+
+ };
+ int stretchIdx;
+ StretchType stretch;
+
+ if( ((enum subIndex)index == TM_FONTSTRETCH) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?stretchType?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_FONTSTRETCH) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_FONTSTRETCH) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "stretchType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set font stretch */
+ if (Tcl_GetIndexFromObj(interp, objv[2], stretchNames, "stretchType", 0, &stretchIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetFontStretch(wandPtr, stretchTypes[stretchIdx]);
+ } else { /* Get font stretch */
+ stretch = DrawGetFontStretch(wandPtr);
+ for (stretchIdx = 0; (size_t) stretchIdx < sizeof(stretchTypes)/sizeof(stretchTypes[0]); stretchIdx++) {
+ if( stretchTypes[stretchIdx] == stretch ) {
+ Tcl_SetResult(interp, (char *)stretchNames[stretchIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)stretch));
+ }
+ break;
+ }
+
+ case TM_FONTSTYLE: /* fontstyle ?style? */
+ case TM_GET_FONTSTYLE: /* GetFontStyle */
+ case TM_SET_FONTSTYLE: /* SetFontStyle style */
+ {
+ static CONST char *styleNames[] = {
+ "normal", "italic", "oblique", "any",
+ (char *) NULL
+ };
+ static StyleType styleTypes[] = {
+ NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle
+ };
+ int styleIdx;
+ StyleType style;
+
+ if( ((enum subIndex)index == TM_FONTSTYLE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?styleType?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_FONTSTYLE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_FONTSTYLE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "styleType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set font style */
+ if (Tcl_GetIndexFromObj(interp, objv[2], styleNames, "styleType", 0, &styleIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetFontStyle(wandPtr, styleTypes[styleIdx]);
+ } else { /* Get font style */
+ style = DrawGetFontStyle(wandPtr);
+ for (styleIdx = 0; (size_t) styleIdx < sizeof(styleTypes)/sizeof(styleTypes[0]); styleIdx++) {
+ if( styleTypes[styleIdx] == style ) {
+ Tcl_SetResult(interp, (char *)styleNames[styleIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)style));
+ }
+ break;
+ }
+
+ case TM_FONTWEIGHT: /* fontweight ?value? */
+ case TM_GET_FONTWEIGHT: /* GetFontWeight */
+ case TM_SET_FONTWEIGHT: /* SetFontWeight value */
+ {
+ unsigned value;
+
+ if( ((enum subIndex)index == TM_FONTSTYLE) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?value?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_FONTSTYLE) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_FONTSTYLE) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "value");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set font weight */
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], (int *) &value)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetFontWeight(wandPtr, value);
+ } else { /* Get font weight */
+ value = DrawGetFontWeight(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)value));
+ }
+ break;
+ }
+
+ case TM_GRAVITY: /* gravity ?gravityType? */
+ case TM_GET_GRAVITY: /* gravity */
+ case TM_SET_GRAVITY: /* gravity gravityType */
+ {
+ static CONST char *gravNames[] = {
+ "forget", "northwest", "north", "northeast", "west",
+ "center", "east", "southwest","south", "southeast",
+ "static",
+ (char *) NULL
+ };
+ static GravityType gravTypes[] = {
+ ForgetGravity, NorthWestGravity, NorthGravity, NorthEastGravity, WestGravity,
+ CenterGravity, EastGravity, SouthWestGravity, SouthGravity, SouthEastGravity,
+ StaticGravity
+ };
+ int gravIdx;
+ GravityType grav;
+
+ if( ((enum subIndex)index == TM_GRAVITY) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?gravityType?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_GRAVITY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_GRAVITY) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "gravityType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set gravity */
+ if (Tcl_GetIndexFromObj(interp, objv[2], gravNames, "gravityType", 0, &gravIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetGravity(wandPtr, gravTypes[gravIdx]);
+ } else { /* Get gravity */
+ grav = DrawGetGravity(wandPtr);
+ for (gravIdx = 0; (size_t) gravIdx < sizeof(gravTypes)/sizeof(gravTypes[0]); gravIdx++) {
+ if( gravTypes[gravIdx] == grav ) {
+ Tcl_SetResult(interp, (char *)gravNames[gravIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)grav));
+ }
+ break;
+ }
+
+ case TM_LINE: /* line sx sy ex ey */
+ case TM_LLINE: /* Line sx sy ex ey */
+ {
+ double sx, sy, ex, ey;
+
+ if( objc != 6 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "sx sy ex ey");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &sx)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &sy)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &ex)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &ey)) != TCL_OK ) {
+ return stat;
+ }
+ DrawLine(wandPtr, sx, sy, ex, ey);
+ break;
+ }
+
+ case TM_MATTE: /* matte x y paintMethod */
+ case TM_MMATTE: /* Matte x y paintMethod */
+ {
+ double x, y;
+ int paintIdx=0;
+
+ if( objc != 5 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y paintMethod");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[4], paintMethodNames, "paintMethod", 0, &paintIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawMatte(wandPtr, x, y, paintMethods[paintIdx]);
+ break;
+ }
+
+ case TM_POINT: /* point x y */
+ case TM_PPOINT: /* Point x y */
+ {
+ double x, y;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ DrawPoint(wandPtr, x, y);
+ break;
+ }
+
+ case TM_RECTANGLE: /* rectangle x1 y1 x2 y2 */
+ case TM_RRECTANGLE: /* Rectangle x1 y1 x2 y2 */
+ {
+ double x1, y1, x2, y2;
+
+ if( objc != 6 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x1 y1 x2 y2");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x1)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y1)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &x2)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &y2)) != TCL_OK ) {
+ return stat;
+ }
+ DrawRectangle(wandPtr, x1, y1, x2, y2);
+ break;
+ }
+
+ case TM_RENDER: /* render */
+ case TM_RRENDER: /* Render */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ /*
+ FIXME: DrawRender() is deprecated. Use MagickDrawImage() instead.
+ Note that TM_DRAW or TM_DRAW_IMAGE already draw on the image. so "render" is not needed.
+ */
+ DrawRender(wandPtr);
+ break;
+ }
+
+ case TM_ROTATE: /* rotate degrees */
+ case TM_RROTATE: /* Rotate degrees */
+ {
+ double degrees;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "degrees");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &degrees)) != TCL_OK ) {
+ return stat;
+ }
+ DrawRotate(wandPtr, degrees);
+ break;
+ }
+
+ case TM_ROUND: /* round x1 y1 x2 y2 rx ry */
+ case TM_ROUND_RECTANGLE:/* RoundRectangle x1 y1 x2 y2 rx ry */
+ {
+ double x1, y1, x2, y2, rx, ry;
+
+ if( objc != 8 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x1 y1 x2 y2 rx ry");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x1)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y1)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &x2)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &y2)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[6], &rx)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[7], &ry)) != TCL_OK ) {
+ return stat;
+ }
+ DrawRoundRectangle(wandPtr, x1, y1, x2, y2, rx, ry);
+ break;
+ }
+
+ case TM_SCALE: /* scale x y */
+ case TM_SSCALE: /* Scale x y */
+ {
+ double x, y;
+
+ if( (objc < 3) || (objc > 4) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x ?y?");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ y = x; /* default */
+ if( (objc > 3) && ((stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK) ) {
+ return stat;
+ }
+ DrawScale(wandPtr, x, y);
+ break;
+ }
+
+ case TM_SKEWX: /* skewx degrees */
+ case TM_SKEW_X: /* SkewX degrees */
+ {
+ double degrees;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "degrees");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &degrees)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSkewX(wandPtr, degrees);
+ break;
+ }
+
+ case TM_SKEWY: /* skewy degrees */
+ case TM_SKEW_Y: /* SkewY degrees */
+ {
+ double degrees;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "degrees");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &degrees)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSkewY(wandPtr, degrees);
+ break;
+ }
+
+ case TM_STROKE_ANTIALIAS: /* strokeantialias ?flag? */
+ case TM_GET_STROKE_ANTIALIAS: /* GetStrokeAntialias */
+ case TM_SET_STROKE_ANTIALIAS: /* SetStrokeAntialias flag */
+ {
+ int flag;
+
+ if( ((enum subIndex)index == TM_STROKE_ANTIALIAS) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?flag?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_STROKE_ANTIALIAS) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_STROKE_ANTIALIAS) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "flag");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set antialias flag */
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &flag)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetStrokeAntialias(wandPtr, flag);
+ } else { /* Get antialias flag */
+ flag = DrawGetStrokeAntialias(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)flag));
+ }
+ break;
+ }
+
+ case TM_STROKE_DASHARRAY: /* strokedasharray {} | val val ... */
+ case TM_GET_STROKE_DASHARRAY: /* GetStrokeDashArray */
+ case TM_SET_STROKE_DASHARRAY: /* SetStrokeDashArray {} | val val ... */
+ {
+ unsigned long i, num;
+ double *arr;
+
+ if( ((enum subIndex)index == TM_GET_STROKE_DASHARRAY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_STROKE_DASHARRAY) && (objc < 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "{} | val val ...");
+ return TCL_ERROR;
+ }
+ if (objc == 2) { /* Get dash array */
+ Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);
+
+ arr = DrawGetStrokeDashArray(wandPtr, &num);
+ while ( num > 0 ) {
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewDoubleObj(*arr));
+ ++arr;
+ }
+ Tcl_SetObjResult(interp, listPtr);
+ } else { /* Set dash array */
+ char *str = Tcl_GetString(objv[2]);
+
+ if( strlen(str) == 0 ) { /* SetStrokeDashArray {} : Remove existing dash array */
+ DrawSetStrokeDashArray(wandPtr, 0, NULL);
+ } else {
+ num = objc-2;
+ arr = (double *)ckalloc(num * sizeof(*arr));
+ if( arr == NULL ) {
+ Tcl_AppendResult(interp, "TclMagick: out of memory", NULL);
+ return TCL_ERROR;
+ }
+ for( i=0; i<num; i++ ) {
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[i+2], &arr[i])) != TCL_OK ) {
+ return stat;
+ }
+ }
+ DrawSetStrokeDashArray(wandPtr, num, arr);
+ ckfree((char *)arr);
+ }
+ }
+ break;
+ }
+
+ case TM_STROKE_DASHOFFS: /* strokedashoffset ?val? */
+ case TM_GET_STROKE_DASHOFFS: /* strokedashoffset */
+ case TM_SET_STROKE_DASHOFFS: /* strokedashoffset val */
+ {
+ double val;
+
+ if( ((enum subIndex)index == TM_STROKE_DASHOFFS) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?val?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_STROKE_DASHOFFS) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_STROKE_DASHOFFS) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "val");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set stroke dash offset */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &val)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetStrokeDashOffset(wandPtr, val);
+ } else { /* Get stroke dash offset */
+ val = DrawGetStrokeDashOffset(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val));
+ }
+ break;
+ }
+
+ case TM_STROKE_LINECAP: /* strokelinecap ?linecapType? */
+ case TM_GET_STROKE_LINECAP: /* GetStrokeLineCap */
+ case TM_SET_STROKE_LINECAP: /* SetStrokeLineCap linecapType */
+ {
+ static CONST char *capNames[] = {
+ "undefined", "butt", "round", "square",
+ (char *) NULL
+ };
+ static LineCap capTypes[] = {
+ UndefinedCap, ButtCap, RoundCap, SquareCap
+ };
+ int capIdx;
+ LineCap cap;
+
+ if( ((enum subIndex)index == TM_STROKE_LINECAP) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?linecapType?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_STROKE_LINECAP) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_STROKE_LINECAP) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "linecapType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set font style */
+ if (Tcl_GetIndexFromObj(interp, objv[2], capNames, "linecapType", 0, &capIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetStrokeLineCap(wandPtr, capTypes[capIdx]);
+ } else { /* Get font style */
+ cap = DrawGetStrokeLineCap(wandPtr);
+ for (capIdx = 0; (size_t) capIdx < sizeof(capTypes)/sizeof(capTypes[0]); capIdx++) {
+ if( capTypes[capIdx] == cap ) {
+ Tcl_SetResult(interp, (char *)capNames[capIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)cap));
+ }
+ break;
+ }
+
+ case TM_STROKE_LINEJOIN: /* strokelinejoin ?linejoinType? */
+ case TM_GET_STROKE_LINEJOIN: /* GetStrokeLineJoin */
+ case TM_SET_STROKE_LINEJOIN: /* SetStrokeLineJoin linejoinType */
+ {
+ static CONST char *joinNames[] = {
+ "undefined", "miter", "round", "bevel",
+ (char *) NULL
+ };
+ static LineJoin joinTypes[] = {
+ UndefinedJoin, MiterJoin, RoundJoin, BevelJoin
+
+ };
+ int joinIdx;
+ LineJoin join;
+
+ if( ((enum subIndex)index == TM_STROKE_LINEJOIN) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?linejoinType?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_STROKE_LINEJOIN) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_STROKE_LINEJOIN) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "linejoinType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set font style */
+ if (Tcl_GetIndexFromObj(interp, objv[2], joinNames, "linejoinType", 0, &joinIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetStrokeLineCap(wandPtr, joinTypes[joinIdx]);
+ } else { /* Get font style */
+ join = DrawGetStrokeLineCap(wandPtr);
+ for (joinIdx = 0; (size_t) joinIdx < sizeof(joinTypes)/sizeof(joinTypes[0]); joinIdx++) {
+ if( joinTypes[joinIdx] == join ) {
+ Tcl_SetResult(interp, (char *)joinNames[joinIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)join));
+ }
+ break;
+ }
+
+ case TM_STROKE_MITERLIM: /* strokemiterlimit ?val? */
+ case TM_GET_STROKE_MITERLIM: /* strokemiterlimit */
+ case TM_SET_STROKE_MITERLIM: /* strokemiterlimit val */
+ {
+ unsigned val;
+
+ if( ((enum subIndex)index == TM_STROKE_MITERLIM) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?val?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_STROKE_MITERLIM) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_STROKE_MITERLIM) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "val");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set stroke miterlimit */
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], (int *) &val)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetStrokeMiterLimit(wandPtr, val);
+ } else { /* Get stroke miterlimit */
+ val = DrawGetStrokeMiterLimit(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)val));
+ }
+ break;
+ }
+
+ case TM_STROKE_OPACITY: /* strokeopacity ?val? */
+ case TM_GET_STROKE_OPACITY: /* strokeopacity */
+ case TM_SET_STROKE_OPACITY: /* strokeopacity val */
+ {
+ double val;
+
+ if( ((enum subIndex)index == TM_STROKE_OPACITY) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?val?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_STROKE_OPACITY) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_STROKE_OPACITY) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "val");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set stroke opacity */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &val)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetStrokeOpacity(wandPtr, val);
+ } else { /* Get stroke opacity */
+ val = DrawGetStrokeOpacity(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val));
+ }
+ break;
+ }
+
+ case TM_STROKE_PATTERNURL: /* strokepatternurl url */
+ case TM_SET_STROKE_PATTERNURL: /* SetStrokePatternURL url */
+ {
+ char *url;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "url");
+ return TCL_ERROR;
+ }
+ url = Tcl_GetString(objv[2]);
+ DrawSetStrokePatternURL(wandPtr, url);
+ break;
+ }
+
+ case TM_STROKE_WIDTH: /* strokewidth ?val? */
+ case TM_GET_STROKE_WIDTH: /* strokewidth */
+ case TM_SET_STROKE_WIDTH: /* strokewidth val */
+ {
+ double val;
+
+ if( ((enum subIndex)index == TM_STROKE_WIDTH) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?val?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_STROKE_WIDTH) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_STROKE_WIDTH) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "val");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set stroke width */
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &val)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetStrokeWidth(wandPtr, val);
+ } else { /* Get stroke width */
+ val = DrawGetStrokeWidth(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val));
+ }
+ break;
+ }
+
+ case TM_TEXT_ANTIALIAS: /* textantialias ?flag? */
+ case TM_GET_TEXT_ANTIALIAS: /* GetTextAntialias */
+ case TM_SET_TEXT_ANTIALIAS: /* SetTextAntialias flag */
+ {
+ int flag;
+
+ if( ((enum subIndex)index == TM_TEXT_ANTIALIAS) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?flag?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_TEXT_ANTIALIAS) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_TEXT_ANTIALIAS) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "flag");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set antialias flag */
+ if( (stat = Tcl_GetIntFromObj(interp, objv[2], &flag)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetTextAntialias(wandPtr, flag);
+ } else { /* Get antialias flag */
+ flag = DrawGetTextAntialias(wandPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(flag));
+ }
+ break;
+ }
+
+ case TM_TEXT_DECORATION: /* textdecoration ?decorationType? */
+ case TM_GET_TEXT_DECORATION: /* GetTextDecoration */
+ case TM_SET_TEXT_DECORATION: /* SetTextDecoration decorationType */
+ {
+ static CONST char *decoNames[] = {
+ "none", "underline", "overline", "linethrough",
+ (char *) NULL
+ };
+ static DecorationType decoTypes[] = {
+ NoDecoration, UnderlineDecoration, OverlineDecoration, LineThroughDecoration
+ };
+ int decoIdx;
+ DecorationType deco;
+
+ if( ((enum subIndex)index == TM_TEXT_DECORATION) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?decorationType?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_TEXT_DECORATION) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_TEXT_DECORATION) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "decorationType");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set antialias flag */
+ if (Tcl_GetIndexFromObj(interp, objv[2], decoNames, "decorationType", 0, &decoIdx) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ DrawSetTextDecoration(wandPtr, decoTypes[decoIdx]);
+ } else { /* Get antialias flag */
+ deco = DrawGetTextDecoration(wandPtr);
+ for (decoIdx = 0; (size_t) decoIdx < sizeof(decoTypes)/sizeof(decoTypes[0]); decoIdx++) {
+ if( decoTypes[decoIdx] == deco ) {
+ Tcl_SetResult(interp, (char *)decoNames[decoIdx], TCL_VOLATILE);
+ return TCL_OK;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj((int)deco));
+ }
+ break;
+ }
+
+ case TM_TEXT_ENCODING: /* textencoding ?string? */
+ case TM_GET_TEXT_ENCODING: /* GetTextEncoding */
+ case TM_SET_TEXT_ENCODING: /* SetTextEncoding string */
+ {
+ char *str;
+
+ if( ((enum subIndex)index == TM_TEXT_ENCODING) && (objc > 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?string?");
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_GET_TEXT_ENCODING) && (objc != 2) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ } else if( ((enum subIndex)index == TM_SET_TEXT_ENCODING) && (objc != 3) ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "string");
+ return TCL_ERROR;
+ }
+ if (objc == 3) { /* Set antialias flag */
+ str = Tcl_GetString(objv[2]);
+ DrawSetTextEncoding(wandPtr, str);
+ } else { /* Get antialias flag */
+ str = DrawGetTextEncoding(wandPtr);
+ Tcl_SetResult(interp, str, TCL_VOLATILE);
+ MagickRelinquishMemory(str);
+ }
+ break;
+ }
+
+ case TM_TRANSLATE: /* translate x y */
+ case TM_TTRANSLATE: /* Translate x y */
+ {
+ double x, y;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x y");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[2], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &y)) != TCL_OK ) {
+ return stat;
+ }
+ DrawTranslate(wandPtr, x, y);
+ break;
+ }
+
+ case TM_VIEWBOX: /* viewbox x1 y1 x2 y2 */
+ case TM_SET_VIEWBOX: /* SetViewbox x1 y1 x2 y2 */
+ {
+ unsigned long x1, y1, x2, y2;
+
+ if( objc != 6 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "x1 y1 x2 y2");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[2], (long int *) &x1)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[3], (long int *) &y1)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[4], (long int *) &x2)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetLongFromObj(interp, objv[5], (long int *) &y2)) != TCL_OK ) {
+ return stat;
+ }
+ DrawSetViewbox(wandPtr, x1, y1, x2, y2);
+ break;
+ }
+
+ /****************************************************************
+ * PUSH & POP COMMANDS
+ ****************************************************************/
+ case TM_PUSH_CLIPPATH: /* PushClipPath id */
+ {
+ char *id;
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "id");
+ return TCL_ERROR;
+ }
+ id = Tcl_GetString(objv[2]);
+ DrawPushClipPath(wandPtr, id);
+ break;
+ }
+
+ case TM_PUSH_DEFS: /* PushDefs */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ DrawPushDefs(wandPtr);
+ break;
+ }
+
+ case TM_PUSH_GRAPHIC_CTX: /* PushGraphicContext */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ DrawPushGraphicContext(wandPtr);
+ break;
+ }
+
+ case TM_PUSH_PATTERN: /* PushPattern id x y width height */
+ {
+ char *id;
+ double x, y, width, height;
+
+ if( objc != 7 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "id x y width height");
+ return TCL_ERROR;
+ }
+ id = Tcl_GetString(objv[3]);
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[3], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &y)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &width)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[6], &height)) != TCL_OK ) {
+ return stat;
+ }
+ DrawPushPattern(wandPtr, id, x, y, width, height);
+ break;
+ }
+
+ case TM_POP_CLIPPATH: /* PopClipPath */
+ case TM_POP_DEFS: /* PopDefs */
+ case TM_POP_GRAPHIC_CTX: /* PopGraphicContext */
+ case TM_POP_PATTERN: /* PopPattern */
+ {
+ if( objc != 2 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ switch((enum subIndex)index) {
+ case TM_POP_CLIPPATH: DrawPopClipPath(wandPtr); break;
+ case TM_POP_DEFS: DrawPopDefs(wandPtr); break;
+ case TM_POP_GRAPHIC_CTX: DrawPopGraphicContext(wandPtr); break;
+ case TM_POP_PATTERN: DrawPopPattern(wandPtr); break;
+ default: break;
+ }
+ break;
+ }
+
+ case TM_PUSH: /* push what ?args? */
+ {
+ int what;
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], pushCmdNames, "what", 0, &what) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch((enum pushCmdIndex)what) {
+ case TM_PUSH_CMD_CLIP: /* clippath */
+ {
+ char *id;
+
+ if( objc != 4 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "id");
+ return TCL_ERROR;
+ }
+ id = Tcl_GetString(objv[3]);
+ DrawPushClipPath(wandPtr, id);
+ break;
+ }
+ case TM_PUSH_CMD_DEFS: /* defs */
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ DrawPushDefs(wandPtr);
+ }
+ case TM_PUSH_CMD_GRAPH: /* graphiccontext */
+ {
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ DrawPushGraphicContext(wandPtr);
+ break;
+ }
+ case TM_PUSH_CMD_PAT: /* pattern */
+ {
+ char *id;
+ double x, y, width, height;
+
+ if( objc != 8 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, "id x y width height");
+ return TCL_ERROR;
+ }
+ id = Tcl_GetString(objv[3]);
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[4], &x)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[5], &y)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[6], &width)) != TCL_OK ) {
+ return stat;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, objv[7], &height)) != TCL_OK ) {
+ return stat;
+ }
+ DrawPushPattern(wandPtr, id, x, y, width, height);
+ break;
+ }
+ } /* switch(what) */
+ break;
+ }
+
+ case TM_POP: /* pop what */
+ {
+ int what;
+
+ if (Tcl_GetIndexFromObj(interp, objv[2], pushCmdNames, "what", 0, &what) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ switch((enum pushCmdIndex)what) {
+ case TM_PUSH_CMD_CLIP: DrawPopClipPath(wandPtr); break;
+ case TM_PUSH_CMD_DEFS: DrawPopDefs(wandPtr); break;
+ case TM_PUSH_CMD_GRAPH: DrawPopGraphicContext(wandPtr); break;
+ case TM_PUSH_CMD_PAT: DrawPopPattern(wandPtr); break;
+ } /* switch(what) */
+ break;
+ }
+
+ /****************************************************************
+ * PATH COMMANDS
+ ****************************************************************/
+ case TM_PATH: /* path -opt|cmd ?args? -opt|cmd ?args? */
+ {
+ static CONST char *pathCmdNames[] = {
+ "#", "-relative", "-smooth",
+ "close", "cubic", "elliptic",
+ "finish", "horizontal", "line",
+ "move", "quadratic", "start",
+ "vertical",
+ (char *) NULL
+ };
+ enum pathCmdIndex {
+ TM_PATH_COMMENT, TM_PATH_OPT_RELATIVE, TM_PATH_OPT_SMOOTH,
+ TM_PATH_CMD_CLOSE, TM_PATH_CMD_CUBIC, TM_PATH_CMD_ELLIPTIC,
+ TM_PATH_CMD_FINISH, TM_PATH_CMD_HORIZONTAL, TM_PATH_CMD_LINE,
+ TM_PATH_CMD_MOVE, TM_PATH_CMD_QUADRATIC, TM_PATH_CMD_START,
+ TM_PATH_CMD_VERTICAL,
+ };
+ int cmd, stat;
+ int relFlag=0, smoothFlag=0;
+ int argc;
+ Tcl_Obj **argv;
+
+ /*
+ * Two ways of calling '$draw path' command:
+ * 1. With many arguments:
+ * $draw path start -relative on \
+ * move 10 10 \
+ * line 10 20 \
+ * line 10 -20 \
+ * close finish
+ * 2. With a single argument list
+ * $draw path {
+ * start -relative on
+ * move 10 10
+ * line 10 20
+ * line 10 -20
+ * close finish
+ * }
+ */
+ if( objc == 3 ) {
+ /*
+ * Single argument list
+ */
+ if( (stat = Tcl_ListObjGetElements(interp, objv[2], &argc, &argv) != TCL_OK) ) {
+ return stat;
+ }
+ } else {
+ argc = objc-2;
+ argv = (Tcl_Obj **)(objv+2);
+ }
+ while( argc > 0 ) {
+ if (Tcl_GetIndexFromObj(interp, argv[0], pathCmdNames, "option/command", 0, &cmd) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch((enum pathCmdIndex)cmd) {
+
+ case TM_PATH_COMMENT: /* # comment */
+ argc -= 2, argv += 2;
+ break;
+
+ case TM_PATH_OPT_RELATIVE: /* -relative boolean */
+ if( argc < 2 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "boolean");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetBooleanFromObj(interp, argv[1], &relFlag)) != TCL_OK) {
+ return stat;
+ }
+ argc -= 2, argv += 2;
+ break;
+
+ case TM_PATH_OPT_SMOOTH: /* -smooth boolean */
+ if( argc < 2 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "boolean");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetBooleanFromObj(interp, argv[1], &smoothFlag)) != TCL_OK) {
+ return stat;
+ }
+ argc -= 2, argv += 2;
+ break;
+
+ case TM_PATH_CMD_CLOSE: /* close */
+ DrawPathClose(wandPtr);
+ argc -= 1, argv += 1;
+ break;
+
+ case TM_PATH_CMD_CUBIC: /* cubic ?x1 y1? x2 y2 x y */
+ {
+ double x1, y1, x2, y2, x, y;
+
+ if( smoothFlag ) {
+ /*
+ * -smooth 1 cubic x2 y2 x y
+ */
+ if( argc < 5 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "x2 y2 x y");
+ return TCL_ERROR;
+ }
+ if( ((stat = Tcl_GetDoubleFromObj(interp, argv[1], &x2)) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[2], &y2)) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[3], &x )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[4], &y )) != TCL_OK) )
+ {
+ Tcl_AppendResult(interp, "Smooth cubic bezier curve arguments: x2 y2 x y", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathCurveToSmoothRelative(wandPtr, x2, y2, x, y)
+ : DrawPathCurveToSmoothAbsolute(wandPtr, x2, y2, x, y);
+
+ argc -= 5, argv += 5;
+ } else {
+ /*
+ * -smooth 0 cubic x1 y1 x2 y2 x y
+ */
+ if( argc < 7 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "x1 y1 x2 y2 x y");
+ return TCL_ERROR;
+ }
+ if( ((stat = Tcl_GetDoubleFromObj(interp, argv[1], &x1)) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[2], &y1)) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[3], &x2)) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[4], &y2)) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[5], &x )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[6], &y )) != TCL_OK) )
+ {
+ Tcl_AppendResult(interp, "Cubic bezier curve arguments: x1 y1 x2 y2 x y", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathCurveToRelative(wandPtr, x1, y1, x2, y2, x, y)
+ : DrawPathCurveToAbsolute(wandPtr, x1, y1, x2, y2, x, y);
+
+ argc -= 7, argv += 7;
+ }
+ break;
+ }
+
+ case TM_PATH_CMD_ELLIPTIC: /* elliptic rx ry rotation large sweep x y */
+ {
+ double rx, ry, rot, x, y;
+ int large, sweep;
+
+ if( argc < 8 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "rx ry rotation large sweep x y");
+ return TCL_ERROR;
+ }
+ if( ((stat = Tcl_GetDoubleFromObj(interp, argv[1], &rx )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[2], &ry )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[3], &rot)) != TCL_OK)
+ || ((stat = Tcl_GetBooleanFromObj(interp, argv[4], &large )) != TCL_OK)
+ || ((stat = Tcl_GetBooleanFromObj(interp, argv[5], &sweep )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[6], &x )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[7], &y )) != TCL_OK) )
+ {
+ Tcl_AppendResult(interp, "Elliptic arc arguments: rx ry rotation large sweep x y", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathEllipticArcRelative(wandPtr, rx, ry, rot, large, sweep, x, y)
+ : DrawPathEllipticArcAbsolute(wandPtr, rx, ry, rot, large, sweep, x, y);
+
+ argc -= 8, argv += 8;
+ break;
+ }
+
+ case TM_PATH_CMD_FINISH: /* finish */
+ DrawPathFinish(wandPtr);
+ argc -= 1, argv += 1;
+ break;
+
+ case TM_PATH_CMD_HORIZONTAL: /* horizontal x */
+ {
+ double x;
+
+ if( argc < 2 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "x");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, argv[1], &x)) != TCL_OK) {
+ Tcl_AppendResult(interp, "Horizonal line argument: x", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathLineToHorizontalRelative(wandPtr, x)
+ : DrawPathLineToHorizontalAbsolute(wandPtr, x);
+
+ argc -= 2, argv += 2;
+ break;
+ }
+
+ case TM_PATH_CMD_LINE: /* line x y */
+ {
+ double x, y;
+
+ if( argc < 3 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "x y");
+ return TCL_ERROR;
+ }
+ if( ((stat = Tcl_GetDoubleFromObj(interp, argv[1], &x )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[2], &y )) != TCL_OK) )
+ {
+ Tcl_AppendResult(interp, "Line arguments: x y", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathLineToRelative(wandPtr, x, y)
+ : DrawPathLineToAbsolute(wandPtr, x, y);
+
+ argc -= 3, argv += 3;
+ break;
+ }
+
+ case TM_PATH_CMD_MOVE: /* move {x y} */
+ {
+ double x, y;
+
+ if( argc < 3 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "x y");
+ return TCL_ERROR;
+ }
+ if( ((stat = Tcl_GetDoubleFromObj(interp, argv[1], &x )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[2], &y )) != TCL_OK) )
+ {
+ Tcl_AppendResult(interp, "Line arguments: x y", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathMoveToRelative(wandPtr, x, y)
+ : DrawPathMoveToAbsolute(wandPtr, x, y);
+
+ argc -= 3, argv += 3;
+ break;
+ }
+
+ case TM_PATH_CMD_QUADRATIC: /* quadratic ?x1 y1? x y */
+ {
+ double x1, y1, x, y;
+
+ if( smoothFlag ) {
+ /*
+ * -smooth 1 quadratic x y
+ */
+ if( argc < 3 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "x y");
+ return TCL_ERROR;
+ }
+ if( ((stat = Tcl_GetDoubleFromObj(interp, argv[1], &x )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[2], &y )) != TCL_OK) )
+ {
+ Tcl_AppendResult(interp, "Smooth quadratic bezier curve arguments: x y", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathCurveToQuadraticBezierSmoothRelative(wandPtr, x, y)
+ : DrawPathCurveToQuadraticBezierSmoothAbsolute(wandPtr, x, y);
+
+ argc -= 3, argv += 3;
+ } else {
+ /*
+ * -smooth 0 quadratic x1 y1 x y
+ */
+ if( argc < 5 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "x2 y2 x y");
+ return TCL_ERROR;
+ }
+ if( ((stat = Tcl_GetDoubleFromObj(interp, argv[1], &x1)) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[2], &y1)) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[3], &x )) != TCL_OK)
+ || ((stat = Tcl_GetDoubleFromObj(interp, argv[4], &y )) != TCL_OK) )
+ {
+ Tcl_AppendResult(interp, "Quadratic bezier curve arguments: x1 y1 x y", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathCurveToQuadraticBezierRelative(wandPtr, x1, y1, x, y)
+ : DrawPathCurveToQuadraticBezierAbsolute(wandPtr, x1, y1, x, y);
+
+ argc -= 5, argv += 5;
+ }
+ break;
+ }
+
+ case TM_PATH_CMD_START: /* start */
+ DrawPathStart(wandPtr);
+ argc -= 1, argv += 1;
+ break;
+
+ case TM_PATH_CMD_VERTICAL: /* vertical {y} */
+ {
+ double y;
+
+ if( argc < 2 ) {
+ Tcl_WrongNumArgs(interp, 1, argv, "y");
+ return TCL_ERROR;
+ }
+ if( (stat = Tcl_GetDoubleFromObj(interp, argv[1], &y)) != TCL_OK) {
+ Tcl_AppendResult(interp, "Horizonal line argument: y", NULL);
+ return stat;
+ }
+ relFlag
+ ? DrawPathLineToVerticalRelative(wandPtr, y)
+ : DrawPathLineToVerticalAbsolute(wandPtr, y);
+
+ argc -= 2, argv += 2;
+ break;
+ }
+
+ } /* switch( path-cmd) */
+ }
+ break; /* path */
+ }
+
+ /*
+ * All subcommands should be matched
+ * A DEFAULT or TM_END_OF_TABLE would be a serious fault
+ */
+ case TM_END_OF_TABLE:
+ default:
+ {
+ Tcl_AppendResult(interp, "TclMagick drawObjCmd: Unmatched subcommand table entry", NULL);
+ return TCL_ERROR;
+ }
+ } /* switch(index) */
+
+ return(TCL_OK);
+}
+
+/*----------------------------------------------------------------------
+ *
+ * Tclmagick_Init --
+ *
+ * Initialize TclMagick module, called from [load TclMagick.dll]
+ * Results:
+ * TCL_OK
+ * TCL_ERROR
+ *
+ * Side effects:
+ * Installs exit handler
+ *----------------------------------------------------------------------
+ */
+static void tmExitHandler(
+ ClientData data ) // Tcl Interpreter which is exiting
+{
+ (void) data;
+ if ( TM.initialized ) {
+ DestroyMagick();
+ TM.initialized = 0;
+ }
+}
+
+EXPORT(int, Tclmagick_Init)(Tcl_Interp *interp)
+{
+#ifdef USE_TCL_STUBS
+ if (Tcl_InitStubs(interp, "8", 0) == NULL) {
+ return TCL_ERROR;
+ }
+#endif
+ /*
+ * Initialize global variables
+ */
+ if ( ! TM.initialized ) {
+ memset(&TM, 0, sizeof(TM));
+
+ /*
+ * Create Exit handler, hash table
+ */
+ Tcl_CreateExitHandler(tmExitHandler,(int *) interp);
+ Tcl_InitHashTable(&TM.hashTable, TCL_STRING_KEYS);
+ InitializeMagick(Tcl_GetString(Tcl_FSGetCwd(interp)));
+
+ TM.initialized = 1;
+ }
+ /*
+ * Create commands per interpreter
+ */
+ Tcl_CreateObjCommand(interp, "magick", magickCmd, NULL, NULL);
+
+ if ( Tcl_PkgProvide(interp,"TclMagick", VERSION) != TCL_OK ) {
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+}
+
+EXPORT(int, Tclmagick_SafeInit)(Tcl_Interp *interp)
+{
+ return Tclmagick_Init(interp);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/TclMagick/generic/TclMagick.h b/TclMagick/generic/TclMagick.h
new file mode 100644
index 0000000..2abbe96
--- /dev/null
+++ b/TclMagick/generic/TclMagick.h
@@ -0,0 +1,63 @@
+/*
+ * TclMagick definitions
+ */
+/* $Id$ */
+
+#ifndef _TCLMAGICK_H_
+#define _TCLMAGICK_H_
+
+#include <string.h>
+#include <tcl.h>
+#include <wand/magick_wand.h>
+
+#define DEBUG 1
+
+enum objTypes {
+ TM_TYPE_WAND, TM_TYPE_DRAWING, TM_TYPE_PIXEL, TM_TYPE_ANY
+};
+
+typedef struct {
+ int type;
+ void *wandPtr; /* MagickWand, DrawingWand or PixelWand
+ * pointer */
+ Tcl_Command magickCmd; /* Token for magick command, used to
+ * delete it */
+ Tcl_Interp *interp; /* Tcl interpreter owing the object */
+ Tcl_HashEntry *hashPtr; /* Hash entry for this structure, used
+ * to delete it */
+} TclMagickObj;
+
+#ifdef __WIN32__
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+
+/*
+ * VC++ has an alternate entry point called DllMain, so we need to rename
+ * our entry point.
+ */
+
+# if defined(_MSC_VER)
+# define EXPORT(a,b) __declspec(dllexport) a b
+# define DllEntryPoint DllMain
+# else
+# if defined(__BORLANDC__)
+# define EXPORT(a,b) a _export b
+# else
+# define EXPORT(a,b) a b
+# endif
+# endif
+#else
+# define EXPORT(a,b) a b
+#endif
+
+
+#endif
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/TclMagick/generic/TclMagickAppInit.c b/TclMagick/generic/TclMagickAppInit.c
new file mode 100644
index 0000000..8b1e80c
--- /dev/null
+++ b/TclMagick/generic/TclMagickAppInit.c
@@ -0,0 +1,183 @@
+/*
+ * tclAppInit.c --
+ *
+ * Provides a default version of the main program and Tcl_AppInit
+ * procedure for Tcl applications (without Tk).
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id$
+ */
+
+#include "tcl.h"
+
+#define TCL_LOCAL_APPINIT TclMagick_AppInit
+
+#ifdef TCL_TEST
+
+#include "tclInt.h"
+
+extern int Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+extern int Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
+extern int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+extern int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+#ifdef TCL_THREADS
+extern int TclThread_Init _ANSI_ARGS_((Tcl_Interp *interp));
+#endif
+
+#endif /* TCL_TEST */
+
+#ifdef TCL_XT_TEST
+extern void XtToolkitInitialize _ANSI_ARGS_((void));
+extern int Tclxttest_Init _ANSI_ARGS_((Tcl_Interp *interp));
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * main --
+ *
+ * This is the main program for the application.
+ *
+ * Results:
+ * None: Tcl_Main never returns here, so this procedure never
+ * returns either.
+ *
+ * Side effects:
+ * Whatever the application does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+main(argc, argv)
+ int argc; /* Number of command-line arguments. */
+ char **argv; /* Values of command-line arguments. */
+{
+ /*
+ * The following #if block allows you to change the AppInit
+ * function by using a #define of TCL_LOCAL_APPINIT instead
+ * of rewriting this entire file. The #if checks for that
+ * #define and uses Tcl_AppInit if it doesn't exist.
+ */
+
+#ifndef TCL_LOCAL_APPINIT
+#define TCL_LOCAL_APPINIT Tcl_AppInit
+#endif
+ extern int TCL_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
+
+ /*
+ * The following #if block allows you to change how Tcl finds the startup
+ * script, prime the library or encoding paths, fiddle with the argv,
+ * etc., without needing to rewrite Tcl_Main()
+ */
+
+#ifdef TCL_LOCAL_MAIN_HOOK
+ extern int TCL_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
+#endif
+
+#ifdef TCL_XT_TEST
+ XtToolkitInitialize();
+#endif
+
+#ifdef TCL_LOCAL_MAIN_HOOK
+ TCL_LOCAL_MAIN_HOOK(&argc, &argv);
+#endif
+
+ Tcl_Main(argc, argv, TCL_LOCAL_APPINIT);
+
+ return 0; /* Needed only to prevent compiler warning. */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclMagick_AppInit --
+ *
+ * This procedure performs application-specific initialization.
+ * Most applications, especially those that incorporate additional
+ * packages, will have their own version of this procedure.
+ *
+ * Results:
+ * Returns a standard Tcl completion code, and leaves an error
+ * message in the interp's result if an error occurs.
+ *
+ * Side effects:
+ * Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclMagick_AppInit(interp)
+ Tcl_Interp *interp; /* Interpreter for application. */
+{
+ if (Tcl_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+
+#ifdef TCL_TEST
+#ifdef TCL_XT_TEST
+ if (Tclxttest_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+#endif
+ if (Tcltest_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
+ (Tcl_PackageInitProc *) NULL);
+ if (TclObjTest_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+#ifdef TCL_THREADS
+ if (TclThread_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+#endif
+ if (Procbodytest_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init,
+ Procbodytest_SafeInit);
+#endif /* TCL_TEST */
+
+ /*
+ * Call the init procedures for included packages. Each call should
+ * look like this:
+ *
+ * if (Mod_Init(interp) == TCL_ERROR) {
+ * return TCL_ERROR;
+ * }
+ *
+ * where "Mod" is the name of the module.
+ */
+
+ if (Tclmagick_Init(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Call Tcl_CreateCommand for application-specific commands, if
+ * they weren't already created by the init procedures called above.
+ */
+
+ /*
+ * Specify a user-specific startup file to invoke if the application
+ * is run interactively. Typically the startup file is "~/.apprc"
+ * where "app" is the name of the application. If this line is deleted
+ * then no user-specific startup file will be run under any conditions.
+ */
+
+#ifdef DJGPP
+ Tcl_SetVar(interp, "tcl_rcFileName", "~/tclsh.rc", TCL_GLOBAL_ONLY);
+#else
+ Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY);
+#endif
+ return TCL_OK;
+}
diff --git a/TclMagick/generic/TkMagick.c b/TclMagick/generic/TkMagick.c
new file mode 100644
index 0000000..ac8dcb3
--- /dev/null
+++ b/TclMagick/generic/TkMagick.c
@@ -0,0 +1,259 @@
+/* TkMagick.c -- Glue to make combine TclMagick and Tk. */
+
+/* Copyright 2003, 2004 David N. Welton <davidw@dedasys.com> */
+
+/* $Id$ */
+
+#include <tk.h>
+#include "libttkcommon.h"
+#include "TclMagick.h"
+#include <string.h>
+#include <wand/magick_wand.h>
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MagickToPhoto --
+ *
+ * Implements "magicktophoto". Takes the name of a "magick wand"
+ * and a Tk image as arguments. Both must already exist,
+ * although they don't necessarily have to contain anything.
+ *
+ * Results:
+ * A normal Tcl result.
+ *
+ * Side Effects:
+ * Sets the image photo size.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int MagickToPhoto(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* Interpreter containing image */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] ) /* List of arguments */
+{
+ MagickWand *wand;
+ TclMagickObj *tclmagick;
+ Tk_PhotoHandle photohandle;
+ Tk_PhotoImageBlock magickblock;
+ char *magickname = NULL;
+ char *photoname = NULL;
+ char *map = NULL;
+
+ (void) clientData; /* Unused */
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "magickwand image" );
+ return TCL_ERROR;
+ }
+
+ magickname = Tcl_GetStringFromObj(objv[1], NULL);
+ tclmagick = findMagickObj(interp, TM_TYPE_WAND, magickname);
+ if (tclmagick == NULL) {
+ return TCL_ERROR;
+ }
+ wand = tclmagick->wandPtr;
+
+ photoname = Tcl_GetStringFromObj(objv[2], NULL);
+ photohandle = Tk_FindPhoto(interp, photoname);
+ if (photohandle == NULL) {
+ Tcl_AppendResult(interp, "Not a photo image.", NULL);
+ return TCL_ERROR;
+ }
+
+ /* pixelSize corresponds to "RGB" format below. */
+ magickblock.pixelSize = 4;
+ magickblock.width = MagickGetImageWidth (wand);
+ magickblock.height = MagickGetImageHeight (wand);
+ magickblock.pixelPtr = (unsigned char *) ckalloc((unsigned)magickblock.height *
+ (unsigned)magickblock.width *
+ magickblock.pixelSize);
+ magickblock.pitch = magickblock.width * magickblock.pixelSize;
+ magickblock.offset[0] = 0;
+ magickblock.offset[1] = 1;
+ magickblock.offset[2] = 2;
+ magickblock.offset[3] = 3;
+
+ /* RGB corresponds to pixelSize above. */
+ map = "RGBA";
+#if 0
+ /*
+ Prior to GraphicsMagick 1.3.8, ImageMagick and GraphicsMagick
+ required a different map.
+ */
+ if (strcmp(MagickPackageName, "ImageMagick") == 0) {
+ map = "RGBA";
+ } else {
+ map = "RGBO";
+ }
+#endif
+
+ if (MagickGetImagePixels (
+ wand, 0, 0, (unsigned)magickblock.width, (unsigned)magickblock.height,
+ map, CharPixel, magickblock.pixelPtr) == False) {
+ return myMagickError(interp, wand);
+ }
+
+#if TCL_MAJOR_VERSION <= 8 && TCL_MINOR_VERSION <= 4
+ Tk_PhotoPutBlock(photohandle, &magickblock, 0, 0,
+ magickblock.width, magickblock.height,
+ TK_PHOTO_COMPOSITE_SET);
+#else
+ if (Tk_PhotoPutBlock(interp, photohandle, &magickblock,
+ 0, 0, magickblock.width, magickblock.height,
+ TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
+ ckfree((char *) magickblock.pixelPtr);
+ return TCL_ERROR;
+ }
+#endif /* TCL_MAJOR_VERSION <= 8 && TCL_MINOR_VERSION <= 4 */
+
+ ckfree((char *) magickblock.pixelPtr);
+ return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * PhotoToMagick --
+ *
+ * Implements "phototomagick". Takes a Tk image and a "magick
+ * wand" as arguments. Transfers the contents of the Tk image to
+ * the magick wand.
+ *
+ * Results:
+ * Normal Tcl result.
+ *
+ * Side Effects:
+ *
+ * Erases the image that was previously in the magick wand, or
+ * creates a new one.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int PhotoToMagick(
+ ClientData clientData, /* Unused */
+ Tcl_Interp *interp, /* Interpreter containing image */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] ) /* List of arguments */
+{
+ MagickWand *wand;
+ TclMagickObj *tclmagick;
+ Tk_PhotoHandle photohandle;
+ Tk_PhotoImageBlock photoblock;
+ char *magickname = NULL;
+ char *photoname = NULL;
+ int result = 0;
+ char map[5] = { 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+ (void) clientData; /* Unused */
+
+ if( objc != 3 ) {
+ Tcl_WrongNumArgs( interp, 1, objv, "image magickwand" );
+ return TCL_ERROR;
+ }
+
+ photoname = Tcl_GetStringFromObj(objv[1], NULL);
+ photohandle = Tk_FindPhoto(
+ interp, photoname);
+ if (photohandle == NULL) {
+ Tcl_AppendResult(interp, "Not a photo image.", NULL);
+ return TCL_ERROR;
+ }
+ Tk_PhotoGetImage(photohandle, &photoblock);
+
+ magickname = Tcl_GetStringFromObj(objv[2], NULL);
+ tclmagick = findMagickObj(interp, TM_TYPE_WAND, magickname);
+ if (tclmagick == NULL) {
+ return TCL_ERROR;
+ }
+ wand = tclmagick->wandPtr;
+ MagickSetSize (wand, (unsigned)photoblock.width, (unsigned)photoblock.height);
+ result = MagickReadImage(wand, "xc:white");
+ if (!result) {
+ return myMagickError(interp, wand);
+ }
+
+ /* This could be improved some, but I don't know how Tk deals with
+ 'unusual' pixelSize's. */
+ switch (photoblock.pixelSize) {
+ case 3:
+ map[photoblock.offset[0]] = 'R';
+ map[photoblock.offset[1]] = 'G';
+ map[photoblock.offset[2]] = 'B';
+ break;
+ case 4:
+ map[photoblock.offset[0]] = 'R';
+ map[photoblock.offset[1]] = 'G';
+ map[photoblock.offset[2]] = 'B';
+ if (strcmp(MagickPackageName, "ImageMagick") == 0) {
+ map[photoblock.offset[3]] = 'A';
+ } else {
+ map[photoblock.offset[3]] = 'O';
+ }
+ break;
+ default:
+ Tcl_AppendResult(interp, "Unsupported pixelSize in Tk image.", NULL);
+ return TCL_ERROR;
+ };
+
+ if (MagickSetImagePixels (wand, 0, 0, (unsigned)photoblock.width,
+ (unsigned)photoblock.height,
+ map, CharPixel, photoblock.pixelPtr) == False) {
+ return myMagickError(interp, wand);
+ }
+
+ return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Tkmagick_Init --
+ *
+ * Initialize this module.
+ *
+ * Results:
+ * Normal Tcl results.
+ *
+ * Side Effects:
+ *
+ * Requires TclMagick module, creates magicktophoto and
+ * phototomagick commands.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+EXPORT(int, Tkmagick_Init)(Tcl_Interp *interp)
+{
+#ifdef USE_TCL_STUBS
+ if (Tcl_InitStubs(interp, "8", 0) == NULL) {
+ return TCL_ERROR;
+ }
+#endif
+#ifdef USE_TK_STUBS
+ if (Tk_InitStubs(interp, "8", 0) == NULL) {
+ return TCL_ERROR;
+ }
+#endif
+
+ Tcl_CreateObjCommand(interp, "magicktophoto", MagickToPhoto, NULL, NULL);
+ Tcl_CreateObjCommand(interp, "phototomagick", PhotoToMagick, NULL, NULL);
+
+ if ( Tcl_PkgProvide(interp,"TkMagick", VERSION) != TCL_OK ) {
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/TclMagick/generic/libttkcommon.c b/TclMagick/generic/libttkcommon.c
new file mode 100644
index 0000000..b0a3475
--- /dev/null
+++ b/TclMagick/generic/libttkcommon.c
@@ -0,0 +1,89 @@
+/*
+ * tcltkcommon.c: data and functions shared by TclMagick.c TkMagick.c
+ */
+
+#include "libttkcommon.h"
+#include "TclMagick.h"
+
+TMHT TM = {0};
+
+CONST char *objTypeNames[] = {
+ "wand", "drawing", "pixel", (char *) NULL
+};
+
+TclMagickObj* findMagickObj(Tcl_Interp *interp, int type, char *name)
+{
+ Tcl_HashEntry *hPtr = Tcl_FindHashEntry( &TM.hashTable, name );
+ TclMagickObj *mPtr;
+
+ if( hPtr == NULL ) {
+ Tcl_AppendResult(interp, "Magick object '", name, "' not found", NULL);
+ return (TclMagickObj *)NULL;
+ } else {
+ mPtr = (TclMagickObj *)Tcl_GetHashValue(hPtr);
+ if( (type != TM_TYPE_ANY) && (mPtr->type != type) ) {
+ Tcl_AppendResult(interp,"Magick object '",name,"' is not a ",objTypeNames[type]," object",NULL);
+ return (TclMagickObj *)NULL;
+ }
+ return mPtr;
+ }
+}
+
+MagickWand *findMagickWand(Tcl_Interp *interp, char *name)
+{
+ TclMagickObj *mPtr = findMagickObj(interp, TM_TYPE_WAND, name);
+ if( mPtr == NULL ) {
+ return (MagickWand *)NULL;
+ }
+ return (MagickWand *)mPtr->wandPtr;
+}
+
+DrawingWand *findDrawingWand(Tcl_Interp *interp, char *name)
+{
+ TclMagickObj *mPtr = findMagickObj(interp, TM_TYPE_DRAWING, name);
+ if( mPtr == NULL ) {
+ return (DrawingWand *)NULL;
+ }
+ return (DrawingWand *)mPtr->wandPtr;
+}
+
+PixelWand *findPixelWand(Tcl_Interp *interp, char *name)
+{
+ TclMagickObj *mPtr = findMagickObj(interp, TM_TYPE_PIXEL, name);
+ if( mPtr == NULL ) {
+ return (PixelWand *)NULL;
+ }
+ return (PixelWand *)mPtr->wandPtr;
+}
+
+/*----------------------------------------------------------------------
+ * Return Magick error description as a TCL result
+ * Used by both TclMagick and TkMagick.
+ *----------------------------------------------------------------------
+ */
+int myMagickError(Tcl_Interp *interp, MagickWand *wandPtr )
+{
+ char *description;
+
+ ExceptionType severity;
+ char msg[40];
+
+ description = MagickGetException(wandPtr, &severity);
+ if( (description == NULL) || (strlen(description) == 0) ) {
+ Tcl_AppendResult(interp, MagickGetPackageName(), ": Unknown error", NULL);
+ } else {
+ sprintf(msg, "%s: #%d:", MagickGetPackageName(), severity); /* FIXME, not used! */
+ Tcl_AppendResult(interp, description, NULL);
+ }
+ if( description != NULL ) {
+ MagickRelinquishMemory(description);
+ }
+ /*
+ * if(severity < ErrorException) --> warning
+ * return TCL_OK ???
+ */
+ return TCL_ERROR;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
diff --git a/TclMagick/generic/libttkcommon.h b/TclMagick/generic/libttkcommon.h
new file mode 100644
index 0000000..1b70197
--- /dev/null
+++ b/TclMagick/generic/libttkcommon.h
@@ -0,0 +1,20 @@
+
+#ifndef _ttkcommon_h_
+#define _ttkcommon_h_
+
+#include "TclMagick.h"
+
+struct TMHT {
+ int initialized; /* Whether module has been initialized */
+ Tcl_HashTable hashTable; /* HasTable for MagickWand objects */
+};
+typedef struct TMHT TMHT;
+
+EXPORT(TclMagickObj, *findMagickObj)(Tcl_Interp *interp, int type, char *name);
+EXPORT(MagickWand, *findMagickWand)(Tcl_Interp *interp, char *name);
+EXPORT(DrawingWand, *findDrawingWand)(Tcl_Interp *interp, char *name);
+EXPORT(PixelWand, *findPixelWand)(Tcl_Interp *interp, char *name);
+EXPORT(int, myMagickError)(Tcl_Interp *interp,MagickWand *wandPtr);
+#endif
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
diff --git a/TclMagick/generic/pkgIndex.tcl b/TclMagick/generic/pkgIndex.tcl
new file mode 100644
index 0000000..c94640b
--- /dev/null
+++ b/TclMagick/generic/pkgIndex.tcl
@@ -0,0 +1 @@
+package ifneeded TclMagick 0.46 [list load [file join $dir TclMagick[info sharedlibextension]]]
diff --git a/TclMagick/images/clippath.tif b/TclMagick/images/clippath.tif
new file mode 100644
index 0000000..bb95160
--- /dev/null
+++ b/TclMagick/images/clippath.tif
Binary files differ
diff --git a/TclMagick/images/map6colors.gif b/TclMagick/images/map6colors.gif
new file mode 100644
index 0000000..8093e6f
--- /dev/null
+++ b/TclMagick/images/map6colors.gif
Binary files differ
diff --git a/TclMagick/images/pool.jpg b/TclMagick/images/pool.jpg
new file mode 100644
index 0000000..b533aba
--- /dev/null
+++ b/TclMagick/images/pool.jpg
Binary files differ
diff --git a/TclMagick/images/sequence.miff b/TclMagick/images/sequence.miff
new file mode 100644
index 0000000..165bdd5
--- /dev/null
+++ b/TclMagick/images/sequence.miff
Binary files differ
diff --git a/TclMagick/images/tclmagick-big-diff.bmp b/TclMagick/images/tclmagick-big-diff.bmp
new file mode 100644
index 0000000..d158d6b
--- /dev/null
+++ b/TclMagick/images/tclmagick-big-diff.bmp
Binary files differ
diff --git a/TclMagick/images/tclmagick-small-copy.bmp b/TclMagick/images/tclmagick-small-copy.bmp
new file mode 100644
index 0000000..6ea94f5
--- /dev/null
+++ b/TclMagick/images/tclmagick-small-copy.bmp
Binary files differ
diff --git a/TclMagick/images/tclmagick-small-diff.bmp b/TclMagick/images/tclmagick-small-diff.bmp
new file mode 100644
index 0000000..0632ee7
--- /dev/null
+++ b/TclMagick/images/tclmagick-small-diff.bmp
Binary files differ
diff --git a/TclMagick/images/tclmagick-small.bmp b/TclMagick/images/tclmagick-small.bmp
new file mode 100644
index 0000000..6ea94f5
--- /dev/null
+++ b/TclMagick/images/tclmagick-small.bmp
Binary files differ
diff --git a/TclMagick/images/tclmagick-small.png b/TclMagick/images/tclmagick-small.png
new file mode 100644
index 0000000..1637bcc
--- /dev/null
+++ b/TclMagick/images/tclmagick-small.png
Binary files differ
diff --git a/TclMagick/images/tclmagick.png b/TclMagick/images/tclmagick.png
new file mode 100644
index 0000000..9bb88c8
--- /dev/null
+++ b/TclMagick/images/tclmagick.png
Binary files differ
diff --git a/TclMagick/pkgIndex.tcl b/TclMagick/pkgIndex.tcl
new file mode 100644
index 0000000..0c4f7b5
--- /dev/null
+++ b/TclMagick/pkgIndex.tcl
@@ -0,0 +1,9 @@
+# Hand-written package index file.
+
+package ifneeded TclMagick 0.46 \
+ [list load [file join $dir libTclMagick[info sharedlibextension]]]
+
+package ifneeded TkMagick 0.46 "
+ package require Tk
+ package require TclMagick
+ load [file join $dir libTkMagick[info sharedlibextension]]"
diff --git a/TclMagick/tests/test-bmp-compare.tcl b/TclMagick/tests/test-bmp-compare.tcl
new file mode 100644
index 0000000..1055a19
--- /dev/null
+++ b/TclMagick/tests/test-bmp-compare.tcl
@@ -0,0 +1,129 @@
+###########################################################
+# MagickWand compare test
+# - The purpose is to test the correctness of TclMagick,
+# not to produce meaningful output
+#
+###########################################################
+
+
+############################################
+# Load debugging version
+# or require TclMagick package from library
+#
+if { $tcl_platform(platform) == "unix" } {
+ set auto_path [linsert $auto_path 0 [file join .. unix]]
+ package require TclMagick
+} else {
+ set dll [file join .. win debug tclMagick.dll]
+ if {[file exists $dll]} {
+ load $dll
+ }
+ package require TclMagick
+}
+
+##########################################
+# Global options
+#
+set imgdir [file join .. images]
+set base [file join $imgdir tclmagick-small.bmp]
+set basecopy [file join $imgdir tclmagick-small-copy.bmp]
+set bigdiff [file join $imgdir tclmagick-big-diff.bmp]
+set onepixeldiff [file join $imgdir tclmagick-small-diff.bmp]
+set epsilon 3.0e-5
+
+proc runTest {} {
+
+ foreach cmd {comparePass compareFail compareOnePixelDiff} {
+ if {[$cmd]} {
+ set result PASS
+ } else {
+ set result FAIL
+ }
+ puts "$result $cmd"
+ }
+}
+
+proc compareImages {img1 img2} {
+ puts "Comparing $img1 and $img2"
+
+ set cmpCmd {
+ set wand1 [magick create wand]
+ set wand2 [magick create wand]
+
+ $wand1 ReadImage $img1
+ $wand2 ReadImage $img2
+
+ set result [$wand1 CompareImages $wand2 meansquarederror]
+
+ puts "Images compared at $result using meansquarederror"
+
+ magick delete $wand1
+ magick delete $wand2
+ }
+
+ if {[catch {eval $cmpCmd} err]} {
+ # get stack trace
+ set localinfo $::errorInfo
+
+ # free any left over wands
+ foreach item [magick names] {
+ magick delete $item
+ }
+
+ set m "Failed to compare images. error: $err"
+ puts $m
+
+ error $m $localinfo
+ }
+
+ return $result
+}
+
+proc comparePass {} {
+ puts "Checking for equal images to pass comparison"
+
+ set result [compareImages $::base $::basecopy]
+
+ # result should be 0.0 from an equal comparison
+ return [string eq $result 0.0]
+}
+
+proc compareFail {} {
+ puts "Checking for vastly different images to fail comparison\
+ at epsilon $::epsilon"
+
+ set result [compareImages $::base $::bigdiff]
+
+ if {[fequal $result 0]} {
+ return 0
+ } else {
+ return 1
+ }
+}
+
+proc compareOnePixelDiff {} {
+
+ puts "Checking epsilon $::epsilon difference in image comparison with\
+ only one pixel difference"
+
+ set result [compareImages $::base $::onepixeldiff]
+
+ if {[fequal $result 0]} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+# from Tclers' Wiki
+proc fequal {x y} {
+ global epsilon
+
+ if {[expr abs($y) < $epsilon]} {
+ return [expr abs($x) < $epsilon]
+ }
+ return [expr (abs($x - $y) / double($y)) < $epsilon]
+}
+
+runTest
+#console show \ No newline at end of file
diff --git a/TclMagick/tests/test-draw.tcl b/TclMagick/tests/test-draw.tcl
new file mode 100644
index 0000000..c3b5332
--- /dev/null
+++ b/TclMagick/tests/test-draw.tcl
@@ -0,0 +1,265 @@
+###########################################################
+# DrawingWand test
+# - The purpose is to test the correctness of TclMagick,
+# not to produce meaningful output
+#
+###########################################################
+
+
+############################################
+# Load debugging version
+# or require TclMagick package from library
+#
+
+if { $tcl_platform(platform) == "unix" } {
+ set auto_path [linsert $auto_path 0 [file join .. unix]]
+ package require TclMagick
+} else {
+ set dll [file join .. win debug tclMagick.dll]
+ if {[file exists $dll]} {
+ load $dll
+ }
+ package require TclMagick
+}
+puts [info script]
+
+
+##########################################
+# Global options
+#
+set IMG "xc:white"
+set TMP [file join .. tmp]
+set FONT "Ariel" ;# undefine FONT if none available
+
+##########################################
+# Check which tests should be performed
+#
+set TestFunctions {
+ DrawTest img 1
+ PathTest img 1
+}
+
+############################################
+# Command debugging
+#
+catch {
+ wm withdraw .
+ console show
+ console eval {wm protocol . WM_DELETE_WINDOW exit}
+}
+proc debug {args} {
+ foreach cmdMask $args {
+ foreach cmd [info commands $cmdMask] {
+ trace add execution $cmd leave debugLeave
+ }
+ }
+}
+proc debugLeave {cmdstr code result op} {
+ puts [format " %s ==>{%s}" [string range $cmdstr 0 50] [string range $result 0 50]]
+ update
+}
+
+##########################################
+# Single image tests
+#
+proc DrawTest {img} {
+ set wand [$img clone imgX]
+ set draw [magick create draw draw0]
+ debug $draw $wand
+
+ [magick create pixel pix0] SetColor "lightblue"
+ [magick create pixel pix1] SetColor "blue"
+ [magick create pixel pix2] SetColor "red"
+ [magick create pixel pix3] SetColor "yellow"
+ [magick create pixel pix4] SetColor "brown"
+ [magick create pixel pix5] SetColor "lightgreen"
+ [magick create pixel pix6] SetColor "green"
+ [magick create pixel pix7] SetColor "lightgray"
+ [magick create pixel pix8] SetColor "black"
+
+ $draw PushGraphicContext
+ $draw SetStrokeWidth 1.0
+ $draw SetStrokeColor pix1
+ $draw SetFillColor pix1
+ $draw SetFontSize 24
+ $draw Annotation 5 30 "Created by TclMagick:"
+ $draw PopGraphicContext
+ $draw PushGraphicContext
+ $draw SetStrokeWidth 1.0
+ $draw SetStrokeColor pix8
+ $draw SetFillColor pix2
+ $draw Arc 50 50 100 100 45 -45
+ $draw PopGraphicContext
+ $draw PushGraphicContext
+ $draw SetStrokeWidth 1.0
+ $draw SetStrokeColor pix1
+ $draw SetFillColor pix3
+ $draw Bezier 110 110 140 10 170 120 150 150 110 110
+ $draw PopGraphicContext
+ $draw PushGraphicContext
+ $draw SetStrokeWidth 1.0
+ $draw SetStrokeColor pix4
+ $draw SetFillColor pix7
+ $draw Circle 100 200 50 200
+ $draw PopGraphicContext
+ $draw PushGraphicContext
+ $draw SetStrokeColor pix8
+ $draw SetFillColor pix6
+ $draw SetFillOpacity 0.7
+ $draw Ellipse 250 100 50 25 0 360
+ $draw PopGraphicContext
+ $draw PushGraphicContext
+ $draw SetStrokeWidth 1.0
+ $draw SetStrokeColor pix2
+ $draw SetFillColor pix2
+ $draw Point 200 200
+ $draw PopGraphicContext
+ $draw PushGraphicContext
+ $draw SetFillColor pix0
+ $draw Color 0 0 replace
+ $draw PopGraphicContext
+
+ $wand DrawImage $draw
+ $wand WriteImage "$::TMP/y-Draw-%0d.bmp"
+
+ magick delete pix0 pix1 pix2 pix3 pix4 pix5 pix6 pix7 pix8
+ magick delete $draw $wand
+}
+
+##########################################
+#
+#
+proc DLR_logo {draw color x y scale} {
+
+ $draw PushGraphicContext
+
+ $draw SetStrokeColor $color
+ $draw SetFillColor $color
+ $draw SetStrokeWidth 0.0
+
+ $draw Scale $scale
+ $draw path start move [expr {$x+72.5}] [expr {$y+0.0}]
+ $draw path {
+ # "Diagonal part of the DLR bird"
+ -relative on
+ line -45 +45 vertical +31 line +45 -45 vertical -31
+ line -5 +12
+ line -35 +35 vertical +17 line +35 -35 vertical -17
+ close
+ finish
+ }
+ $draw path start move [expr {$x+1.0}] [expr {$y+49.0}]
+ $draw path {
+ # "Horizontal part of the DLR bird"
+ -relative on
+ horizontal +76 line +22 -22 horizontal -76 line -22 +22
+ line +12 -5
+ horizontal +62 line +12 -12 horizontal -62 line -12 +12
+ close
+ finish
+ }
+ if {[info exists ::FONT]} {
+ # Use specified FONT
+ #
+ $draw SetFontFamily $::FONT
+ $draw SetFontSize 20
+ $draw Annotation [expr {$x+55.0}] [expr {$y+82.0}] "DLR"
+ } else {
+ # Draw the letters manually
+ #
+ $draw path start move [expr {$x+55.0}] [expr {$y+82.0}]
+ $draw path {
+ # "Letter D"
+ -relative on
+ vertical -18 horizontal +6
+ quadratic +7 +0 +7 +9
+ quadratic +0 +9 -7 +9
+ horizontal -6
+ line +2.5 -2.5
+ vertical -13 horizontal +3
+ quadratic +5 +0 +5 +6.5
+ quadratic +0 +6.5 -5 +6.5
+ horizontal -3
+ line -2.5 +2.5
+ close
+
+ # "Letter L"
+ move +17 +0
+ vertical -18 horizontal +2.5
+ vertical +15 horizontal +7
+ vertical +3 horizontal -10
+ close
+
+ # "Letter R"
+ move +12.5 +0
+ vertical -18 horizontal +5
+ quadratic +5 +0 +5 +5
+ quadratic +0 +5 -4 +5
+ line +5 +8 horizontal -2.5 line -5 -8
+ horizontal -1 vertical +8 horizontal -2.5
+ line +2.5 -10.5
+ vertical -5 horizontal +2
+ quadratic +3 +0 +3 +2.5
+ quadratic +0 +2.5 -3 +2.5
+ horizontal -2
+ line -2.5 +10.5
+ close
+ finish
+ }
+ }
+ $draw PopGraphicContext
+}
+proc PathTest {img} {
+ set wand [$img clone imgX]
+ set draw [magick create draw draw0]
+ debug $draw $wand
+
+ [magick create pixel pix0] SetColor "gray"
+ [magick create pixel pix1] SetColor "black"
+
+ DLR_logo $draw pix0 0 2 4
+ DLR_logo $draw pix1 1 1.5 4
+
+ $wand DrawImage $draw
+ $wand WriteImage "$::TMP/y-Path-%0d.bmp"
+
+ magick delete $draw $wand
+}
+
+##########################################
+# Main test loop
+#
+
+debug magick
+
+if { ! [file isdirectory $TMP]} {
+ file mkdir $TMP
+}
+
+set img [magick create wand img0]
+debug $img
+
+$img ReadImage $IMG
+$img ResizeImage 400 340
+
+magick names
+
+set ERRORS 0
+foreach {func var flag} $TestFunctions {
+ if {$flag} {
+ puts [format "%s:" $func $var]
+ set err [catch {$func [set $var]} result]
+ if {$err} {
+ incr ERRORS
+ puts stderr [format "error: %s" $result]
+ }
+ } else {
+ puts [format "--- skip: %s ---" $func]
+ }
+}
+
+puts "##### DRAW TEST READY #####"
+if {!$ERRORS} {
+ after 3000 exit
+}
+
diff --git a/TclMagick/tests/test-pixel.tcl b/TclMagick/tests/test-pixel.tcl
new file mode 100644
index 0000000..3e880e9
--- /dev/null
+++ b/TclMagick/tests/test-pixel.tcl
@@ -0,0 +1,138 @@
+###########################################################
+# PixelWand test
+# - The purpose is to test the correctness of TclMagick,
+# not to produce meaningful output
+#
+###########################################################
+
+
+############################################
+# Load debugging version
+# or require TclMagick package from library
+#
+if { $tcl_platform(platform) == "unix" } {
+ set auto_path [linsert $auto_path 0 [file join .. unix]]
+ package require TclMagick
+} else {
+ set dll [file join .. win debug tclMagick.dll]
+ if {[file exists $dll]} {
+ load $dll
+ }
+ package require TclMagick
+}
+puts [info script]
+
+############################################
+# Command debugging
+#
+catch {
+ wm withdraw .
+ console show
+ console eval {wm protocol . WM_DELETE_WINDOW exit}
+}
+proc debug {args} {
+ foreach cmdMask $args {
+ foreach cmd [info commands $cmdMask] {
+ trace add execution $cmd leave debugLeave
+ }
+ }
+}
+proc debugLeave {cmdstr code result op} {
+ puts [format " %s ==>{%s}" [string range $cmdstr 0 50] [string range $result 0 50]]
+ update
+}
+
+
+##########################################
+# Show pixel colors
+#
+proc ShowPixel {pix {all 1}} {
+ puts "----------"
+ if {$all} {
+ $pix color
+ $pix get -quant red green blue opacity
+ $pix get red green blue opacity
+ $pix get -quant cyan magenta yellow black
+ $pix get cyan magenta yellow black
+ $pix GetQuantumColor
+ } else {
+ $pix GetColorAsString
+ }
+ puts "----------"
+}
+
+##########################################
+# Single image tests
+#
+proc TestPixel {} {
+ set pix [magick create pixel pix0]
+ debug $pix
+
+ $pix SetColor rgb(10%)
+ ShowPixel $pix
+
+ $pix SetColor rgb(20%,30%)
+ ShowPixel $pix
+
+ $pix SetColor rgb(30%,40%,50%)
+ ShowPixel $pix
+
+ $pix SetColor rgb(80%,,20%)
+ ShowPixel $pix
+
+ $pix SetColor rgb(30,40,50)
+ ShowPixel $pix
+
+ $pix color #99B2FF
+ ShowPixel $pix
+
+ $pix set red 0.1 green 0.2 blue 0.3 opacity 0.4
+ ShowPixel $pix
+
+ $pix set -quant red 10000 green 20000 blue 30000 opacity 40000
+ ShowPixel $pix
+
+ $pix set cyan 0.1 magenta 0.2 yellow 0.3 black 0.4
+ ShowPixel $pix
+
+ $pix set -quant cyan 10000 magenta 20000 yellow 30000 black 40000
+ ShowPixel $pix
+
+ $pix SetRed 0.9
+ $pix SetGreen 0.8
+ $pix SetBlue 0.7
+ $pix SetOpacity 0.6
+ ShowPixel $pix
+
+ $pix SetRedQuantum 12345
+ $pix SetGreenQuantum 23456
+ $pix SetBlueQuantum 34567
+ $pix SetOpacityQuantum 45678
+ ShowPixel $pix
+
+ $pix SetCyan 0.9
+ $pix SetMagenta 0.8
+ $pix SetYellow 0.7
+ $pix SetBlack 0.6
+ ShowPixel $pix
+
+ $pix SetCyanQuantum 12345
+ $pix SetMagentaQuantum 23456
+ $pix SetYellowQuantum 34567
+ $pix SetBlackQuantum 45678
+ ShowPixel $pix
+
+ $pix SetQuantumColor {100 150 200 250}
+ ShowPixel $pix
+
+ magick delete $pix
+}
+
+
+##########################################
+# Main test loop
+#
+
+debug magick
+
+TestPixel
diff --git a/TclMagick/tests/test-wand.tcl b/TclMagick/tests/test-wand.tcl
new file mode 100644
index 0000000..6def7e0
--- /dev/null
+++ b/TclMagick/tests/test-wand.tcl
@@ -0,0 +1,1539 @@
+###########################################################
+# MagickWand test
+# - The purpose is to test the correctness of TclMagick,
+# not to produce meaningful output
+#
+###########################################################
+
+
+############################################
+# Load debugging version
+# or require TclMagick package from library
+#
+if { $tcl_platform(platform) == "unix" } {
+ set auto_path [linsert $auto_path 0 [file join .. unix]]
+ package require TclMagick
+} else {
+ set dll [file join .. win debug tclMagick.dll]
+ if {[file exists $dll]} {
+ load $dll
+ }
+ package require TclMagick
+}
+puts [info script]
+
+
+##########################################
+# Global options
+#
+set IMG "logo:"
+set SEQ "../images/sequence.miff"
+set MAP "../images/map6colors.gif"
+set CLIP "../images/clippath.tif"
+set TMP "../tmp"
+
+##########################################
+# Check which tests should be performed
+#
+# ImageMagick only: FxImage, FxImageChannel, PreviewImages, TintImage
+set TestFunctions {
+ AdaptiveThresholdImage img 1
+ AddImage seq 1
+ AddNoiseImage img 1
+ AffineTransformImage img 1
+ ???-how-to-AnnotateImage img 0
+ AppendImages seq 1
+ AverageImages seq 1
+ BlackThresholdImage img 1
+ BlurImage img 1
+ BorderImage img 1
+ CharcoalImage img 1
+ ChopImage img 1
+ ClipImage img 1
+ ClipPathImage img 1
+ CoalesceImages seq 1
+ ColorFloodfillImage img 1
+ ColorizeImage img 1
+ CommentImage img 1
+ CompareImages img 1
+ CompareImageChannels img 1
+ CompositeImage img 1
+ ContrastImage img 1
+ ConvolveImage img 1
+ CropImage img 1
+ CycleColormapImage img 1
+ DeconstructImages seq 1
+ DescribeImage img 1
+ DespeckleImage img 1
+ DrawImage img 1
+ EdgeImage img 1
+ EmbossImage img 1
+ EnhanceImage img 1
+ EqualizeImage img 1
+ FlattenImage seq 1
+ FlipImage img 1
+ FlopImage img 1
+ FrameImage img 1
+ FxImage img 0
+ FxImageChannel img 0
+ GammaImage img 1
+ GammaImageChannel img 1
+
+ GetSetImage seq 1
+ GetSetFilename img 1
+ GetSetBackgroundColor img 1
+ GetSetBluePrimary img 1
+ GetSetBorderColor img 1
+ GetSetChannelDepth img 1
+ GetChannelExtrema img 1
+ GetChannelMean img 1
+ GetSetColormapColor img 1
+ GetColors img 1
+ GetSetColorspace img 1
+ GetSetCompose img 1
+ GetSetCompression img 1
+ GetSetDelay seq 1
+ GetSetDepth img 1
+ GetSetDispose img 1
+ GetExtrema img 1
+ GetFormat img 1
+ GetSetGamma img 1
+ GetSetGreenPrimary img 1
+ GetHeight img 1
+ GetSetIndex seq 1
+ GetSetInterlaceScheme img 1
+ GetSetIterations img 1
+ GetSetMatteColor img 1
+ GetSetImageFilename img 1
+ GetSetPixels img 1
+ GetSetRemoveProfile img 1
+ GetSetRedPrimary img 1
+ GetSetRendering img 1
+ GetSetResolution img 1
+ GetSetScene seq 1
+ GetImageSize img 1
+ GetSignature img 1
+ GetSetImageType img 1
+ GetSetImageUnits img 1
+ GetSetVirtualPixelMethod img 1
+ GetSetWhitePoint img 1
+ GetWidth img 1
+ GetNumberImages seq 1
+ GetSetSamplingFactors img 1
+ GetSetSize img 1
+ ImplodeImage img 0
+ LabelImage img 1
+ LevelImage img 1
+ LevelImageChannel img 1
+ MagnifyImage img 1
+ MapImage img 1
+ MatteFloodfillImage img 1
+ MedianFilterImage img 1
+ MinifyImage img 1
+ ModulateImage img 1
+ MontageImage seq 1
+ MorphImages seq 1
+ MosaicImages seq 1
+ MotionBlurImage img 1
+ NegateImage img 1
+ NormalizeImage img 1
+
+ NextPrevious seq 1
+
+ OilPaintImage img 1
+ OpaqueImage img 1
+ PingImage SEQ 1
+ PreviewImages img 0
+ QuantizeImage img 1
+ QueryFontMetrics img 1
+ RaiseImage img 1
+ ReadImageBlob SEQ 1
+ ReduceNoiseImage img 1
+ RemoveImage seq 1
+ ResampleImage img 1
+ ResizeImage img 1
+ RollImage img 1
+ RotateImage img 1
+ SampleImage img 1
+ ScaleImage img 1
+ SeparateImageChannel img 1
+
+ SetOption img 1
+ SetPassphrase img 1
+
+ SharpenImage img 1
+ ShaveImage img 1
+ ShearImage img 1
+ SolarizeImage img 1
+ SpreadImage img 1
+ SteganoImage img 1
+ StereoImage img 1
+ StripImage img 1
+ SwirlImage img 1
+ TextureImage img 1
+ ThresholdImage img 1
+ ThresholdImageChannel img 1
+ TintImage img 0
+ TransformImage img 1
+ TransparentImage img 1
+ TrimImage img 1
+ UnsharpMaskImage img 1
+ WaveImage img 1
+ WhiteThresholdImage img 1
+}
+
+############################################
+# Command debugging
+#
+catch {
+ wm withdraw .
+ console show
+ console eval {wm protocol . WM_DELETE_WINDOW exit}
+}
+proc debug {args} {
+ foreach cmdMask $args {
+ foreach cmd [info commands $cmdMask] {
+ trace add execution $cmd leave debugLeave
+ }
+ }
+}
+proc debugLeave {cmdstr code result op} {
+ puts [format " %s ==>{%s}" [string range $cmdstr 0 50] [string range $result 0 50]]
+ update
+}
+
+##########################################
+# Single image tests
+#
+proc AdaptiveThresholdImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand AdaptiveThresholdImage 5 5 0
+ $wand WriteImage "$::TMP/x-Adaptive.jpg"
+ magick delete $wand
+}
+proc AddImage {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand SetIndex 3
+ set x [$wand GetImage imgX]
+ $wand SetIndex 0
+ $wand AddImage $x
+ $wand WriteImages "$::TMP/x-Add.gif" 1
+
+ magick delete $wand $x
+}
+proc AddNoiseImage {img} {
+ foreach noise {impulse poisson} { ;# uniform gaussian multiplicativegaussian impulse laplacian poisson
+ set wand [$img clone imgX]
+ debug $wand
+ $wand AddNoiseImage $noise
+ $wand WriteImage "$::TMP/x-AddNoise-$noise.jpg"
+ magick delete $wand
+ }
+}
+proc AffineTransformImage {img} {
+ set wand [$img clone imgX]
+ set draw [magick create drawing]
+ debug $wand $draw
+
+ $draw Rotate 10
+ $draw Affine 1.0 3.0 3.0 2.0 2.0 2.0
+ $wand AffineTransformImage $draw
+ $wand WriteImage "$::TMP/x-Affine.jpg"
+
+ magick delete $draw $wand
+}
+proc AnnotateImage {img} {
+ set wand [$img clone imgX]
+ set draw [magick create drawing]
+ debug $wand $draw
+
+ [magick create pixel pix] SetColor "blue"
+ $draw push graph
+ $draw SetStrokeWidth 1
+ $draw SetStrokeColor pix
+ $draw SetFillColor pix
+ $draw SetFontSize 18
+ $draw pop graph
+
+ $wand AnnotateImage $draw 20 50 0 "Hello world"
+ $wand WriteImage "$::TMP/x-Annotate.jpg"
+
+ magick delete $draw $wand pix
+}
+proc AppendImages {seq} {
+ set wand [$seq AppendImages 0 seqX]
+ debug $wand
+ $wand WriteImages "$::TMP/x-Append.gif" 1
+ magick delete $wand
+}
+proc AverageImages {seq} {
+ set wand [$seq AverageImages seqX]
+ debug $wand
+ $wand WriteImage "$::TMP/x-Average.jpg"
+ magick delete $wand
+}
+proc BlackThresholdImage {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel]
+ debug $wand $pix
+
+ $pix set red 0.5 green 0.5 blue 0.5
+ $pix GetColor
+ $wand BlackThresholdImage $pix
+ $wand WriteImage "$::TMP/x-BlackThreshold.jpg"
+
+ magick delete $pix $wand
+}
+proc BlurImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand BlurImage 2 3
+ $wand WriteImage "$::TMP/x-Blur.jpg"
+ magick delete $wand
+}
+proc BorderImage {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel]
+ debug $wand $pix
+
+ $pix set red 1.0 green 1.0 blue 0.0
+ $pix GetColor
+ $wand BorderImage $pix 4 6
+ $wand WriteImage "$::TMP/x-Border.jpg"
+
+ magick delete $pix $wand
+}
+proc CharcoalImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand CharcoalImage 2.0 1.0
+ $wand WriteImage "$::TMP/x-Charcoal.jpg"
+ magick delete $wand
+}
+proc ChopImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ChopImage 100 60 350 200
+ $wand WriteImage "$::TMP/x-Chop.jpg"
+ magick delete $wand
+}
+proc ClipImage {img} {
+ set wand [magick create wand]
+ debug $wand
+
+ $wand ReadImage $::CLIP
+ $wand ClipImage
+ $wand GammaImage 5.0
+
+ $wand WriteImage "$::TMP/x-Clip-Gamma.jpg"
+ magick delete $wand
+}
+proc ClipPathImage {img} {
+ set wand [magick create wand]
+ debug $wand
+
+ $wand ReadImage $::CLIP
+ $wand ClipPathImage "#1" 0
+ $wand SolarizeImage 3
+
+ $wand WriteImage "$::TMP/x-ClipPath-Solarize.jpg"
+ magick delete $wand
+}
+proc CoalesceImages {img} {
+ set new [$img CoalesceImages]
+ $new WriteImages "$::TMP/x-Coalesce.gif" 1
+ magick delete $new
+}
+proc ColorFloodfillImage {img} {
+ set wand [$img clone imgX]
+ set fill [magick create pixel]
+ set border [magick create pixel]
+ debug $wand $fill $border
+
+ $fill SetColor "lightgreen"
+ $border SetColor "black"
+
+ set max [magick library -maxrgb]
+ $wand ColorFloodfillImage $fill [expr {0.01 * $max}] {} 0 0
+ $wand WriteImage "$::TMP/x-ColorFloodfill-1.jpg"
+
+ $fill SetColor "lightblue"
+ $wand ColorFloodfillImage $fill [expr {0.01 * $max}] $border 0 0
+ $wand WriteImage "$::TMP/x-ColorFloodfill-2.jpg"
+
+ magick delete $fill $border $wand
+}
+proc ColorizeImage {img} {
+ set wand [$img clone imgX]
+ set fill [magick create pixel]
+ set opacity [magick create pixel]
+ debug $wand $fill $opacity
+
+ $fill color rgb(70%,0,0)
+ $opacity SetColor rgb(0,0,0)
+ $wand ColorizeImage $fill $opacity
+
+ $wand WriteImage "$::TMP/x-Colorize.jpg"
+ magick delete $fill $opacity $wand
+}
+proc CommentImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand CommentImage "This is a comment"
+ $wand WriteImage "$::TMP/x-Comment.jpg"
+ magick delete $wand
+}
+proc CompareImages {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand CompareImages $img peakabsoluteerror
+ $wand BlurImage 1.0 1.0
+ $wand CompareImages $img meansquarederror
+ magick delete $wand
+}
+proc CompareImageChannels {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand BlurImage 1.0 1.0
+ $wand CompareImageChannels $img red peakabsoluteerror
+ $wand CompareImageChannels $img blue peakabsoluteerror
+ magick delete $wand
+}
+proc CompositeImage {img} {
+ set wand [$img clone imgX]
+ set bg [magick create pixel]
+ debug $wand $bg
+
+ $bg SetColor rgb(50%,50%,50%)
+ $wand rotate $bg 90
+ $wand CompositeImage $img add 0 0
+ $wand WriteImage "$::TMP/x-Composite.jpg"
+
+ magick delete $wand $bg
+}
+proc ContrastImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ContrastImage 1
+ $wand WriteImage "$::TMP/x-Contrast.jpg"
+ magick delete $wand
+}
+proc ConvolveImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ConvolveImage 3 {0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1}
+ $wand WriteImage "$::TMP/x-Convolve.jpg"
+ magick delete $wand
+}
+proc CropImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand CropImage 100 60 350 200
+ $wand WriteImage "$::TMP/x-Crop.jpg"
+ magick delete $wand
+}
+proc CycleColormapImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand CycleColormapImage 10
+ $wand WriteImage "$::TMP/x-CycleColormap.jpg"
+ magick delete $wand
+}
+proc DeconstructImages {seq} {
+ set wand [$seq DeconstructImages seqX]
+ debug $wand
+ $wand WriteImage "$::TMP/x-Deconstruct-%d.jpg"
+ magick delete $wand
+}
+proc DescribeImage {img} {
+ set txt [$img DescribeImage]
+ set f [open "$::TMP/x-Describe.txt" w]
+ puts $f $txt
+ close $f
+}
+proc DespeckleImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand Despeckle
+ $wand WriteImage "$::TMP/x-Despeckle.jpg"
+ magick delete $wand
+}
+proc DrawImage {img} {
+ set wand [$img clone imgX]
+ set draw [magick create draw drawX]
+ debug $wand $draw
+
+ [magick create pixel whitePix] SetColor "white"
+ [magick create pixel bluePix] SetColor "blue"
+ [magick create pixel redPix] SetColor "red"
+
+ $draw push graph
+ $draw Rotate -45
+ $draw push graph
+ $draw SetStrokeWidth 2
+ $draw SetFillColor whitePix
+ $draw SetStrokeColor bluePix
+ $draw Rectangle -200 280 +90 310
+ $draw pop graph
+
+ $draw push graph
+ $draw SetStrokeWidth 0.5
+ $draw SetStrokeColor bluePix
+ $draw SetFillColor bluePix
+ $draw SetFontSize 18
+ $draw Annotation -197 300 "Tcl/Tk + ImageMagick = TclMagick"
+ $draw pop graph
+ $draw pop graph
+
+ $draw push graph
+ $draw SetStrokeWidth 0.5
+ $draw SetStrokeColor redPix
+ $draw SetFillColor redPix
+ $draw SetFontSize 14
+ $draw Annotation 10 400 "Image %wx%h (%xx%y dpi) format=%m size=%b"
+ $draw pop graph
+
+ $wand DrawImage $draw
+ $wand WriteImage "$::TMP/x-Draw.jpg"
+
+ magick delete whitePix bluePix redPix
+ magick delete $draw $wand
+}
+proc EdgeImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand EdgeImage 4.0
+ $wand WriteImage "$::TMP/x-Edge.jpg"
+ magick delete $wand
+}
+proc EmbossImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand EmbossImage 2.0 5.0
+ $wand WriteImage "$::TMP/x-Emboss.jpg"
+ magick delete $wand
+}
+proc EnhanceImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand AddNoiseImage impulse
+ $wand EnhanceImage
+ $wand WriteImage "$::TMP/x-Enhance.jpg"
+ magick delete $wand
+}
+proc EqualizeImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand EqualizeImage
+ $wand WriteImage "$::TMP/x-Equalize.jpg"
+ magick delete $wand
+}
+proc FlattenImage {seq} {
+ set wand [$seq FlattenImage]
+ debug $wand
+ $wand WriteImage "$::TMP/x-Flatten.jpg"
+ magick delete $wand
+}
+proc FlipImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand FlipImage
+ $wand WriteImage "$::TMP/x-Flip.jpg"
+ magick delete $wand
+}
+proc FlopImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand FlopImage
+ $wand WriteImage "$::TMP/x-Flop.jpg"
+ magick delete $wand
+}
+proc FrameImage {img} {
+ set wand [$img clone imgX]
+ set frm [magick create pixel]
+ debug $wand $frm
+
+ $frm set red 1.0 green 1.0 blue 0
+ $frm GetColor
+ $wand FrameImage $frm 8 8 3 3
+
+ $wand WriteImage "$::TMP/x-Frame.jpg"
+ magick delete $frm $wand
+}
+proc FxImage {img} {
+ set wand [$img FxImage "r/2"]
+ $wand WriteImage "$::TMP/x-Fx.jpg"
+ magick delete $wand
+}
+proc FxImageChannel {img} {
+ set wand [$img FxImageChannel blue "b/4"]
+ $wand WriteImage "$::TMP/x-FxChannel.jpg"
+ magick delete $wand
+}
+proc GammaImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GammaImage 2.0
+
+ $wand WriteImage "$::TMP/x-Gamma.jpg"
+ magick delete $wand
+}
+proc GammaImageChannel {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GammaImageChannel blue 2.0
+
+ $wand WriteImage "$::TMP/x-GammaChannel.jpg"
+ magick delete $wand
+}
+proc GetSetImage {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand SetIndex 2
+ set new [$wand GetImage imgX]
+ $wand SetIndex 1
+ while {[$wand HasNext]} {
+ $wand SetImage $new
+ $wand NextImage
+ }
+ $wand WriteImages "$::TMP/x-SetImage.gif" 1
+
+ magick delete $wand $new
+}
+proc GetSetFilename {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $img GetFilename
+ $wand filename "foo.jpg"
+ $wand filename
+ $wand SetFilename "bar.jpg"
+ $wand GetFilename
+
+ magick delete $wand
+}
+proc GetSetBackgroundColor {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel pixX]
+ debug $wand $pix
+
+ $pix set red 0.0 green 0.5 blue 0.5
+ $wand SetBackgroundColor $pix
+ $pix set red 0 green 0 blue 0
+ $wand GetBackgroundColor $pix
+ $pix GetColor
+
+ magick delete $pix $wand
+}
+proc GetSetBluePrimary {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetBluePrimary
+ $wand SetBluePrimary 100 50
+ $wand GetBluePrimary
+
+ magick delete $wand
+}
+proc GetSetBorderColor {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel pixX]
+ debug $wand $pix
+
+ $pix set red 0.0 green 0.5 blue 0.5
+ $wand SetBorderColor $pix
+ $pix set red 0 green 0 blue 0
+ $wand GetBorderColor $pix
+ $pix GetColor
+
+ magick delete $pix $wand
+}
+proc GetSetChannelDepth {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetChannelDepth red
+ $wand SetChannelDepth red 16
+ $wand GetChannelDepth red
+
+ magick delete $wand
+}
+proc GetChannelExtrema {img} {
+ $img GetChannelExtrema blue
+}
+proc GetChannelMean {img} {
+ $img GetChannelMean blue
+}
+proc GetSetColormapColor {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel pixX]
+ debug $wand $pix
+
+ $pix set red 0 green 0.5 blue 0.7
+ $wand SetColormapColor 0 $pix
+ $pix GetColor
+ $pix set red 0 green 0 blue 0
+ $wand GetColormapColor 0 $pix
+ $pix GetColor
+
+ magick delete $pix $wand
+}
+proc GetColors {img} {
+ $img GetColors
+}
+proc GetSetColorspace {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetColorspace
+ $wand SetColorspace "RGB"
+ $wand GetColorspace
+
+ magick delete $wand
+}
+proc GetSetCompose {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetCompose
+ $wand SetCompose "xor"
+ $wand GetCompose
+
+ magick delete $wand
+}
+proc GetSetCompression {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetCompression
+ $wand SetCompression "zip"
+ $wand GetCompression
+
+ magick delete $wand
+}
+proc GetSetDelay {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand GetDelay
+ $wand SetDelay 123
+ $wand GetDelay
+
+ magick delete $wand
+}
+proc GetSetDepth {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetDepth
+ $wand SetDepth 16
+ $wand GetDepth
+
+ magick delete $wand
+}
+proc GetSetDispose {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetDispose
+ $wand SetDispose "background"
+ $wand GetDispose
+
+ magick delete $wand
+}
+proc GetExtrema {img} {
+ $img GetExtrema
+}
+proc GetFormat {img} {
+ $img GetFormat
+}
+proc GetSetGamma {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetGamma
+ $wand SetGamma 2.5
+ $wand GetGamma
+
+ magick delete $wand
+}
+proc GetSetGreenPrimary {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetGreenPrimary
+ $wand SetGreenPrimary 100 50
+ $wand GetGreenPrimary
+
+ magick delete $wand
+}
+proc GetHeight {img} {
+ $img GetHeight
+}
+proc GetSetIndex {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand GetIndex
+ $wand SetIndex 3
+ $wand GetIndex
+
+ magick delete $wand
+}
+proc GetSetInterlaceScheme {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetInterlaceScheme
+ $wand SetInterlaceScheme "plane"
+ $wand GetInterlaceScheme
+
+ magick delete $wand
+}
+proc GetSetIterations {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetIterations
+ $wand SetIterations 3
+ $wand GetIterations
+
+ magick delete $wand
+}
+proc GetSetMatteColor {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel pixX]
+ debug $wand $pix
+
+ $pix set red 0 green 0.5 blue 0.7
+ $wand SetMatteColor $pix
+ $pix GetColor
+ $pix set red 0 green 0 blue 0
+ $wand GetMatteColor $pix
+ $pix GetColor
+
+ magick delete $pix $wand
+}
+proc GetSetImageFilename {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetImageFilename
+ $wand SetImageFilename "foo"
+ $wand GetImageFilename
+
+ magick delete $wand
+}
+proc GetSetPixels {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ set pixelList {
+ 0 0 0
+ 0 0 255
+ 0 255 0
+ 0 255 255
+ 255 255 255
+ 255 0 0
+ 255 0 255
+ 255 255 0
+ 128 128 128
+ }
+ set pix1 [binary format c* $pixelList]
+
+ $wand SetPixels 0 0 3 3 "RGB" char $pix1
+ set pix2 [$wand GetPixels 0 0 3 3 "RGB" char]
+ if {! [string equal $pix1 $pix2]} {
+ error "Get pixels do not match set pixels"
+ }
+ set data [$wand GetPixels 10 5 10 5 "RGB" char]
+ puts [format "image pixels: %d bytes, expected: %d bytes" [string length $data] 150]
+ $wand SetPixels 10 5 10 5 "RGB" char [binary format x150]
+
+ $wand WriteImage "$::TMP/x-Pixels.jpg"
+ magick delete $wand
+}
+proc GetSetRemoveProfile {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand SetProfile "icc" "foo"
+ $wand SetProfile "8bim" "bar"
+ $wand GetProfile "icc"
+ $wand GetProfile "8bim"
+ $wand RemoveProfile "icc"
+ $wand GetProfile "icc"
+
+ magick delete $wand
+}
+proc GetSetRemoveSetProfile {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SetProfile ICC HALLO
+ $wand WriteImage "$::TMP/x-Profile.jpg"
+ magick delete $wand
+}
+proc GetSetRedPrimary {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetRedPrimary
+ $wand SetRedPrimary 100 50
+ $wand GetRedPrimary
+
+ magick delete $wand
+}
+proc GetSetRendering {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetRendering
+ $wand SetRendering "perceptual"
+ $wand GetRendering
+
+ magick delete $wand
+}
+proc GetSetResolution {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetResolution
+ $wand SetResolution 360 720
+ $wand GetResolution
+
+ magick delete $wand
+}
+proc GetSetScene {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand GetScene
+ $wand SetScene 3
+ $wand GetScene
+
+ magick delete $wand
+}
+proc GetImageSize {img} {
+ $img GetImageSize
+}
+proc GetSignature {img} {
+ $img GetSignature
+}
+proc GetSetImageType {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand GetImageType
+ $wand SetImageType grayscale
+ $wand GetImageType
+
+ magick delete $wand
+}
+proc GetSetImageUnits {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand GetImageUnits
+ $wand SetImageUnits "ppcm"
+ $wand GetImageUnits
+
+ magick delete $wand
+}
+proc GetSetVirtualPixelMethod {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand GetVirtualPixelMethod
+ $wand SetVirtualPixelMethod "mirror"
+ $wand GetVirtualPixelMethod
+ $wand SetVirtualPixelMethod "undefined"
+
+ magick delete $wand
+}
+proc GetWidth {img} {
+ $img GetWidth
+}
+proc GetNumberImages {seq} {
+ $seq GetNumberImages
+}
+proc GetSetSamplingFactors {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetSamplingFactors
+ $wand SetSamplingFactors {1 2 3 4 5}
+ $wand GetSamplingFactors
+
+ magick delete $wand
+}
+proc GetSetSize {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $img GetSize
+ $wand size 100 200
+ $wand size
+ $wand SetSize 300 400
+ $wand GetSize
+
+ magick delete $wand
+}
+proc GetSetWhitePoint {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand GetWhitePoint
+ $wand SetWhitePoint 100 50
+ $wand GetWhitePoint
+
+ magick delete $wand
+}
+proc ImplodeImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ImplodeImage 1.0
+ $wand WriteImage "$::TMP/x-Implode.jpg"
+ magick delete $wand
+}
+proc LabelImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand LabelImage "This is my label"
+ $wand WriteImage "$::TMP/x-Label.jpg"
+ magick delete $wand
+}
+proc LevelImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand LevelImage 10000 2.0 50000
+ $wand WriteImage "$::TMP/x-Level.jpg"
+ magick delete $wand
+}
+proc LevelImageChannel {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand LevelImageChannel blue 10000 2.0 50000
+ $wand WriteImage "$::TMP/x-LevelChannel.jpg"
+ magick delete $wand
+}
+proc MagnifyImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand MagnifyImage
+ $wand WriteImage "$::TMP/x-Magnify.jpg"
+ magick delete $wand
+}
+proc MapImage {img} {
+ set wand [$img clone imgX]
+ set map [magick create wand]
+ debug $wand $map
+
+ $map ReadImage $::MAP
+ $wand MapImage $map
+ $wand WriteImage "$::TMP/x-Map.jpg"
+ magick delete $wand $map
+}
+proc MatteFloodfillImage {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel]
+ debug $wand $pix
+
+ $pix color rgb(50%,50%,50%)
+# $pix set red 0.5 green 0.5 blue 0.5
+ $pix GetColor
+ $wand MatteFloodfillImage 30000 10.0 $pix
+ $wand WriteImage "$::TMP/x-MatteFlood.gif"
+ magick delete $wand $pix
+}
+proc MedianFilterImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand MedianFilterImage 3
+ $wand WriteImage "$::TMP/x-Median.jpg"
+ magick delete $wand
+}
+proc MinifyImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand MinifyImage
+ $wand WriteImage "$::TMP/x-Minify.jpg"
+ magick delete $wand
+}
+proc ModulateImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ModulateImage +90 +50 -30
+ $wand WriteImage "$::TMP/x-Modulate.jpg"
+ magick delete $wand
+}
+proc MontageImage {seq} {
+ set wand [$seq clone seqX]
+ set draw [magick create drawing drawX]
+ debug $wand $draw
+
+ set x [$wand MontageImage $draw "40x40" "400x400" frame "4x4" imgX]
+ $x WriteImage "$::TMP/x-Montage.jpg"
+
+ magick delete $wand $draw $x
+}
+proc MorphImages {seq} {
+ $seq GetNumberImages
+ set wand [$seq MorphImages 5 seqY]
+ debug $wand
+ $wand GetNumberImages
+ $wand WriteImages "$::TMP/x-Morph.gif" 1
+ magick delete $wand
+}
+proc MosaicImages {seq} {
+ set wand [$seq MosaicImages imgX]
+ debug $wand
+ $wand WriteImage "$::TMP/x-Mosaic.gif"
+ magick delete $wand
+}
+proc MotionBlurImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand MotionBlurImage 0 5 45
+ $wand WriteImage "$::TMP/x-MotionBlur.jpg"
+ magick delete $wand
+}
+proc NegateImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand NegateImage no
+ $wand WriteImage "$::TMP/x-Negate.jpg"
+ magick delete $wand
+}
+proc NormalizeImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand NormalizeImage
+ $wand WriteImage "$::TMP/x-Normalize.jpg"
+ magick delete $wand
+}
+proc NextPrevious {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ set max [$wand GetNumberImages]
+ for {set i 0} {$i < $max} {incr i} {
+ $wand SetIndex $i
+ $wand HasPrevious
+ $wand HasNext
+ }
+ $wand ResetIterator
+ $wand GetIndex
+
+ magick delete $wand
+}
+proc OilPaintImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand OilPaintImage 3
+ $wand WriteImage "$::TMP/x-OilPaint.jpg"
+ magick delete $wand
+}
+proc OpaqueImage {img} {
+ set wand [$img clone imgX]
+ set pix1 [magick create pixel pix1]
+ set pix2 [magick create pixel pix2]
+ debug $wand $pix1 $pix2
+
+ $pix1 color rgb(100%,100%,100%)
+ $pix2 color rgb(0,100%,100%)
+ $wand OpaqueImage $pix1 $pix2 10
+ $wand WriteImage "$::TMP/x-Opaque.jpg"
+
+ magick delete $wand $pix1 $pix2
+}
+proc PingImage {filename} {
+ set wand [magick create wand imgX]
+ debug $wand
+
+ $wand PingImage $filename
+ $wand GetFormat
+ $wand GetHeight
+ $wand GetWidth
+ $wand GetImageSize
+
+ magick delete $wand
+}
+proc PreviewImages {img} {
+ set wand [$img PreviewImages grayscale imgX]
+ debug $wand
+ $wand GetNumberImages
+ $wand WriteImage "$::TMP/x-Preview.jpg"
+ magick delete $wand
+}
+proc QueryFontMetrics {img} {
+ set draw [magick create draw drawX]
+ debug $draw
+ $img QueryFontMetrics $draw "Hello world"
+ magick delete $draw
+}
+proc QuantizeImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand QuantizeImage 10 GRAY 1 no no
+ $wand WriteImage "$::TMP/x-Quantize.jpg"
+ magick delete $wand
+}
+proc RaiseImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand RaiseImage 100 100 100 100 yes
+ $wand WriteImage "$::TMP/x-Raise.jpg"
+ magick delete $wand
+}
+proc ReadImageBlob {filename} {
+ set wand [magick create wand imgX]
+ debug $wand
+
+ set f [open $filename r]
+ fconfigure $f -translation binary
+ set data [read $f]
+ close $f
+
+ $wand ReadImageBlob $data
+ $wand GetNumberImages
+
+ magick delete $wand
+}
+proc ReduceNoiseImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand AddNoise impulse
+ $wand ReduceNoiseImage 1
+ $wand WriteImage "$::TMP/x-ReduceNoise.jpg"
+ magick delete $wand
+}
+proc RemoveImage {seq} {
+ set wand [$seq clone seqX]
+ debug $wand
+
+ $wand GetNumberImages
+ $wand SetIndex 1
+ while {[$wand HasNext]} {
+ $wand RemoveImage
+ }
+ $wand GetNumberImages
+ $wand WriteImages "$::TMP/x-Remove.gif" 1
+
+ magick delete $wand
+}
+proc ResampleImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ResampleImage 150 150 triangle 2.0
+ $wand WriteImage "$::TMP/x-Resample.jpg"
+ magick delete $wand
+}
+proc ResizeImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+
+ $wand ResizeImage 100 200 triangle
+ $wand WriteImage "$::TMP/x-Resize.jpg"
+ magick delete $wand
+}
+proc RollImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand TrimImage
+ $wand RollImage -60 -30
+ $wand WriteImage "$::TMP/x-Roll.jpg"
+ magick delete $wand
+}
+proc RotateImage {img} {
+ set wand [$img clone imgX]
+ set bg [magick create pixel]
+ debug $wand $bg
+
+ $bg color rgb(50%,50%,50%)
+ $wand RotateImage $bg -45
+ $wand WriteImage "$::TMP/x-Rotate.jpg"
+
+ magick delete $wand $bg
+}
+proc SampleImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SampleImage 200 300
+ $wand WriteImage "$::TMP/x-Sample.jpg"
+ magick delete $wand
+}
+proc ScaleImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ScaleImage 300 200
+ $wand WriteImage "$::TMP/x-Scale.jpg"
+ magick delete $wand
+}
+proc SeparateImageChannel {img} {
+ # Test RGB space
+ foreach chan {red green blue} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SeparateImageChannel $chan
+ $wand WriteImage "$::TMP/x-Separate-$chan.jpg"
+ magick delete $wand
+ }
+ # Test CMYK space
+ foreach chan {cyan magenta yellow black} {
+ set wand [$img clone imgX]
+ $wand SetColorspace "CMYK"
+ debug $wand
+ $wand SeparateImageChannel $chan
+ $wand WriteImage "$::TMP/x-Separate-$chan.jpg"
+ magick delete $wand
+ }
+}
+proc SetOption {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SetOption "jpeg" "perserve" "yes"
+ $wand WriteImage "$::TMP/x-SetOption.jpg"
+ magick delete $wand
+}
+proc SetPassphrase {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SetPassphrase "foo"
+ $wand WriteImage "$::TMP/x-Passphrase.jpg"
+ magick delete $wand
+}
+proc SharpenImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SharpenImage 4.0 2.0
+ $wand WriteImage "$::TMP/x-Sharpen.jpg"
+ magick delete $wand
+}
+proc ShaveImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ShaveImage 50 30
+ $wand WriteImage "$::TMP/x-Shave.jpg"
+ magick delete $wand
+}
+proc ShearImage {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel pix1]
+ debug $wand $pix
+
+ $pix color rgb(50%,50%,50%)
+ $wand ShearImage $pix 30 20
+ $wand WriteImage "$::TMP/x-Shear.jpg"
+ magick delete $wand $pix
+}
+proc SolarizeImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SolarizeImage 10
+ $wand WriteImage "$::TMP/x-Solarize.jpg"
+ magick delete $wand
+}
+proc SpreadImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SpreadImage 3
+ $wand WriteImage "$::TMP/x-Spread.jpg"
+ magick delete $wand
+}
+proc SteganoImage {img} {
+ set wand [$img clone imgX]
+ set water [$img clone imgY]
+ debug $wand $water
+
+ $water resize 50 50
+ set new [$wand SteganoImage $water]
+ $new WriteImage "$::TMP/x-Stegano.jpg"
+
+ magick delete $wand $water $new
+}
+proc StereoImage {img} {
+ set wand [$img clone imgX]
+ set another [$img clone imgY]
+ debug $wand $another
+
+ $another RollImage 5 5
+ set new [$wand StereoImage $another]
+ $new WriteImage "$::TMP/x-Stereo.jpg"
+
+ magick delete $wand $another $new
+}
+proc StripImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand StripImage
+ set txt [$wand DescribeImage]
+ $wand WriteImage "$::TMP/x-Strip.jpg"
+ magick delete $wand
+}
+proc SwirlImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand SwirlImage 45
+ $wand WriteImage "$::TMP/x-Swirl.jpg"
+ magick delete $wand
+}
+proc TextureImage {img} {
+ set wand [$img clone imgX]
+ set text [magick create wand]
+ debug $wand $text
+
+ $text ReadImage "xc:gray"
+ $text ResizeImage 500 500
+ $wand ResizeImage 110 110 triangle
+
+ set new [$text TextureImage $wand]
+ $new WriteImage "$::TMP/x-Texture.jpg"
+
+ magick delete $wand $text $new
+}
+proc ThresholdImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ThresholdImage 30000
+ $wand WriteImage "$::TMP/x-Threshold.jpg"
+ magick delete $wand
+}
+proc ThresholdImageChannel {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand ThresholdImageChannel blue 3000
+ $wand WriteImage "$::TMP/x-ThresholdChannel.jpg"
+ magick delete $wand
+}
+proc TintImage {img} {
+ set wand [$img clone imgX]
+ set pix1 [magick create pixel pix1]
+ set pix2 [magick create pixel pix2]
+ debug $wand $pix1 $pix2
+
+ $pix1 color "blue"
+ $pix2 color "black"
+ $wand TintImage $pix1 $pix2
+ $wand WriteImage "$::TMP/x-Tint.jpg"
+
+ magick delete $wand $pix1 $pix2
+}
+proc TransformImage {img} {
+ set wand [$img TransformImage "200x300+250+100" "600x600"]
+ debug $wand
+ $wand WriteImage "$::TMP/x-Transform.gif"
+ magick delete $wand
+}
+proc TransparentImage {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel]
+ debug $wand $pix
+
+ $pix color "blue"
+ $wand TransparentImage $pix 40000 100
+ $wand WriteImage "$::TMP/x-Transparent.gif"
+
+ magick delete $wand $pix
+}
+proc TrimImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand TrimImage 10
+ $wand WriteImage "$::TMP/x-Trim.jpg"
+ magick delete $wand
+}
+proc UnsharpMaskImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand UnsharpMaskImage 0 3 50 10
+ $wand WriteImage "$::TMP/x-Unsharp.jpg"
+ magick delete $wand
+}
+proc WaveImage {img} {
+ set wand [$img clone imgX]
+ debug $wand
+ $wand WaveImage 4 10
+ $wand WriteImage "$::TMP/x-Wave.jpg"
+ magick delete $wand
+}
+proc WhiteThresholdImage {img} {
+ set wand [$img clone imgX]
+ set pix [magick create pixel]
+ debug $wand $pix
+
+ $pix color "white"
+ $wand WhiteThresholdImage $pix
+ $wand WriteImage "$::TMP/x-WhiteThreshold.jpg"
+
+ magick delete $wand $pix
+}
+
+##########################################
+# Prepare tests
+#
+
+if {! [file isdirectory $::TMP] } {
+ file mkdir $::TMP
+}
+debug magick
+
+magick fonts
+magick formats
+
+set img [magick create wand img0]
+set seq [magick create wand img1]
+debug $img $seq
+
+$img ReadImage $IMG
+$img WriteImage "$::TMP/x-0.jpg"
+
+$seq ReadImage $SEQ
+magick names
+
+
+##########################################
+# Main test loop
+#
+
+set ERRORS 0
+set TESTED 0
+set SKIPPED 0
+
+foreach {func var flag} $TestFunctions {
+ if {$flag} {
+ incr TESTED
+ puts [format "%s:" $func $var]
+ set num1 [llength [magick names]]
+
+ set err [catch {$func [set $var]} result]
+ if {$err} {
+ incr ERRORS
+ puts stderr $result
+ }
+ # Check for unfree'd resources
+ #
+ set num2 [llength [magick names]]
+ if {! $err && ($num2 > $num1)} {
+ puts stderr "Check resources (magick names) !!!"
+ set err 1
+ }
+ if {$err} {
+ update ; after 5000
+ }
+ } else {
+ incr SKIPPED
+ }
+}
+
+puts "*********** READY **************"
+if {$SKIPPED} {
+ puts [format "tested=%d errors=%d skipped=%d" $TESTED $ERRORS $SKIPPED]
+}
+if {!$ERRORS} {
+# after 3000 exit
+}
diff --git a/TclMagick/tests/tkmagick.tcl b/TclMagick/tests/tkmagick.tcl
new file mode 100644
index 0000000..a85703b
--- /dev/null
+++ b/TclMagick/tests/tkmagick.tcl
@@ -0,0 +1,40 @@
+# tkmagick.tcl -- Test the TkMagick functions.
+
+# $Id$
+
+package require Tk
+
+set dirname [file dirname [info script]]
+
+# load [file join $dirname .. generic .libs libTclMagick[info sharedlibextension]]
+# load [file join $dirname .. generic .libs libTkMagick[info sharedlibextension]]
+package require TkMagick
+
+# magickimage --
+#
+# Takes a file name, and returns the name of an image that can
+# be used with Tk.
+
+proc magickimage {filename} {
+ set magimg [magick create wand]
+ set tkimg [image create photo]
+ $magimg ReadImage $filename
+ magicktophoto $magimg $tkimg
+ magick delete $magimg
+ return $tkimg
+}
+
+proc saveimage {} {
+ global poolphoto
+ set magimg [magick create wand]
+ phototomagick $poolphoto $magimg
+ $magimg WriteImage tmp.jpg
+ magick delete $magimg
+}
+
+set poolphoto [magickimage [file join $dirname .. images pool.jpg]]
+label .im
+.im configure -image $poolphoto
+pack .im
+bind . <q> exit
+bind . <s> saveimage \ No newline at end of file
diff --git a/TclMagick/unix/Makefile.in b/TclMagick/unix/Makefile.in
new file mode 100644
index 0000000..562d28b
--- /dev/null
+++ b/TclMagick/unix/Makefile.in
@@ -0,0 +1,430 @@
+# Makefile.in --
+#
+# This file is a Makefile for Sample TEA Extension. If it has the name
+# "Makefile.in" then it is a template for a Makefile; to generate the
+# actual Makefile, run "./configure", which is a configuration script
+# generated by the "autoconf" program (constructs like "@foo@" will get
+# replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+# Copyright (c) 2002-2003 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id$
+
+#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@
+
+#========================================================================
+# Nothing of the variables below this line should need to be changed.
+# Please check the TARGETS section below to make sure the make targets
+# are correct.
+#========================================================================
+
+#========================================================================
+# The names of the source files is defined in the configure script.
+# The object files are used for linking into the final library.
+# This will be used when a dist target is added to the Makefile.
+# It is not important to specify the directory, as long as it is the
+# $(srcdir) or in the generic, win or unix subdirectory.
+#========================================================================
+
+PKG_SOURCES = @PKG_SOURCES@
+PKG_OBJECTS = @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+#========================================================================
+# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
+# this package that need to be installed, if any.
+#========================================================================
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+
+#========================================================================
+# This is a list of public header files to be installed, if any.
+#========================================================================
+
+PKG_HEADERS = @PKG_HEADERS@
+
+#========================================================================
+# "PKG_LIB_FILE" refers to the library (dynamic or static as per
+# configuration options) composed of the named objects.
+#========================================================================
+
+PKG_LIB_FILE = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES = $(PKG_LIB_FILE)
+BINARIES = $(lib_BINARIES)
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+libdir = @libdir@
+datadir = @datadir@
+mandir = @mandir@
+includedir = @includedir@
+
+DESTDIR =
+
+PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION)
+pkgdatadir = $(datadir)/$(PKG_DIR)
+pkglibdir = $(libdir)/$(PKG_DIR)
+pkgincludedir = $(includedir)/$(PKG_DIR)
+
+top_builddir = .
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+CC = @CC@
+CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+CLEANFILES = @CLEANFILES@
+EXEEXT = @EXEEXT@
+LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
+MAKE_LIB = @MAKE_LIB@
+MAKE_SHARED_LIB = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB = @MAKE_STUB_LIB@
+OBJEXT = @OBJEXT@
+RANLIB = @RANLIB@
+RANLIB_STUB = @RANLIB_STUB@
+SHLIB_CFLAGS = @SHLIB_CFLAGS@
+SHLIB_LD = @SHLIB_LD@
+SHLIB_LD_FLAGS = @SHLIB_LD_FLAGS@ @LDFLAGS@
+SHLIB_LD_LIBS = @SHLIB_LD_LIBS@
+STLIB_LD = @STLIB_LD@
+TCL_DEFS = @TCL_DEFS@
+TCL_BIN_DIR = @TCL_BIN_DIR@
+TCL_SRC_DIR = @TCL_SRC_DIR@
+# This is necessary for packages that use private Tcl headers
+#TCL_TOP_DIR_NATIVE = @TCL_TOP_DIR_NATIVE@
+# Not used, but retained for reference of what libs Tcl required
+TCL_LIBS = @TCL_LIBS@
+
+#========================================================================
+# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
+# package without installing. The other environment variables allow us
+# to test against an uninstalled Tcl. Add special env vars that you
+# require for testing here (like TCLX_LIBRARY).
+#========================================================================
+
+EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
+TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
+ @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+ PATH="$(EXTRA_PATH):$(PATH)" \
+ TCLLIBPATH="$(top_builddir)"
+TCLSH_PROG = @TCLSH_PROG@
+TCLSH = $(TCLSH_ENV) $(TCLSH_PROG)
+SHARED_BUILD = @SHARED_BUILD@
+
+INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@
+
+EXTRA_CFLAGS = @EXTRA_CFLAGS@ @PKG_CFLAGS@
+
+# TCL_DEFS is not strictly need here, but if you remove it, then you
+# must make sure that configure.in checks for the necessary components
+# that your library may use. TCL_DEFS can actually be a problem if
+# you do not compile with a similar machine setup as the Tcl core was
+# compiled with.
+#DEFS = $(TCL_DEFS) @DEFS@ $(EXTRA_CFLAGS)
+DEFS = @DEFS@ $(EXTRA_CFLAGS)
+
+CONFIG_CLEAN_FILES = Makefile
+
+CPPFLAGS = @CPPFLAGS@
+LIBS = @PKG_LIBS@ @LIBS@
+AR = ar
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+#========================================================================
+# Start of user-definable TARGETS section
+#========================================================================
+
+#========================================================================
+# TEA TARGETS. Please note that the "libraries:" target refers to platform
+# independent files, and the "binaries:" target inclues executable programs and
+# platform-dependent libraries. Modify these targets so that they install
+# the various pieces of your package. The make and install rules
+# for the BINARIES that you specified above have already been done.
+#========================================================================
+
+all: binaries libraries doc
+
+#========================================================================
+# The binaries target builds executable programs, Windows .dll's, unix
+# shared/static libraries, and any other platform-dependent files.
+# The list of targets to build for "binaries:" is specified at the top
+# of the Makefile, in the "BINARIES" variable.
+#========================================================================
+
+binaries: $(BINARIES) pkgIndex.tcl
+
+libraries:
+
+doc:
+ @echo "If you have documentation to create, place the commands to"
+ @echo "build the docs in the 'doc:' target. For example:"
+ @echo " xml2nroff sample.xml > sample.n"
+ @echo " xml2html sample.xml > sample.html"
+
+install: all install-binaries install-libraries install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+ if test "x$(SHARED_BUILD)" = "x1"; then \
+ $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
+ fi
+
+#========================================================================
+# This rule installs platform-independent files, such as header files.
+#========================================================================
+
+install-libraries: libraries
+ @mkdir -p $(DESTDIR)$(includedir)
+ @echo "Installing header files in $(DESTDIR)$(includedir)"
+ @for i in $(PKG_HEADERS) ; do \
+ echo "Installing $(srcdir)/$$i" ; \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+ done;
+
+#========================================================================
+# Install documentation. Unix manpages should go in the $(mandir)
+# directory.
+#========================================================================
+
+install-doc: doc
+ @mkdir -p $(DESTDIR)$(mandir)/mann
+ @echo "Installing documentation in $(DESTDIR)$(mandir)"
+ @for i in $(srcdir)/doc/*.n; do \
+ echo "Installing $$i"; \
+ rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
+ done
+
+test: binaries libraries
+ $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+shell: binaries libraries
+ @$(TCLSH) $(SCRIPT)
+
+gdb:
+ $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+#========================================================================
+# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
+# mentioned above. That will ensure that this target is built when you
+# run "make binaries".
+#
+# The $(PKG_OBJECTS) objects are created and linked into the final
+# library. In most cases these object files will correspond to the
+# source files above.
+#========================================================================
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+ -rm -f $(PKG_LIB_FILE)
+ ${MAKE_LIB}
+ $(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+ -rm -f $(PKG_STUB_LIB_FILE)
+ ${MAKE_STUB_LIB}
+ $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#========================================================================
+# We need to enumerate the list of .c to .o lines here.
+#
+# In the following lines, $(srcdir) refers to the toplevel directory
+# containing your extension. If your sources are in a subdirectory,
+# you will have to modify the paths to reflect this:
+#
+# sample.$(OBJEXT): $(srcdir)/generic/sample.c
+# $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
+#
+# Setting the VPATH variable to a list of paths will cause the makefile
+# to look into these paths when resolving .c to .obj dependencies.
+# As necessary, add $(srcdir):$(srcdir)/compat:....
+#========================================================================
+
+VPATH = $(srcdir):$(srcdir)/../generic:$(srcdir)/unix:$(srcdir)/win
+
+.c.@OBJEXT@:
+ $(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#========================================================================
+# Create the pkgIndex.tcl file.
+# It is usually easiest to let Tcl do this for you with pkg_mkIndex, but
+# you may find that you need to customize the package. If so, either
+# modify the -hand version, or create a pkgIndex.tcl.in file and have
+# the configure script output the pkgIndex.tcl by editing configure.in.
+#========================================================================
+
+pkgIndex.tcl:
+ ( echo pkg_mkIndex . $(PKG_LIB_FILE) \; exit; ) | $(TCLSH)
+
+pkgIndex.tcl-hand:
+ (echo 'package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
+ [list load [file join $$dir $(PKG_LIB_FILE)]]'\
+ ) > pkgIndex.tcl
+
+#========================================================================
+# Distribution creation
+# You may need to tweak this target to make it work correctly.
+#========================================================================
+
+#COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS = gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT = /tmp/dist
+DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
+
+dist-clean:
+ rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
+
+dist: dist-clean
+ mkdir -p $(DIST_DIR)
+ cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
+ $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
+ $(DIST_DIR)/
+ chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
+ chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
+
+ cp -p $(srcdir)/*.[ch] $(DIST_DIR)/
+
+ mkdir $(DIST_DIR)/tclconfig
+ cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
+ $(DIST_DIR)/tclconfig/
+ chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
+ chmod +x $(DIST_DIR)/tclconfig/install-sh
+
+ list='demos doc generic library mac tests unix win'; \
+ for p in $$list; do \
+ if test -d $(srcdir)/$$p ; then \
+ mkdir $(DIST_DIR)/$$p; \
+ cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
+ fi; \
+ done
+
+ (cd $(DIST_ROOT); $(COMPRESS);)
+
+#========================================================================
+# End of user-definable section
+#========================================================================
+
+#========================================================================
+# Don't modify the file to clean here. Instead, set the "CLEANFILES"
+# variable in configure.in
+#========================================================================
+
+clean:
+ -test -z "$(BINARIES)" || rm -f $(BINARIES)
+ -rm -f *.$(OBJEXT) core *.core
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+ -rm -f *.tab.c
+ -rm -f $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log config.status
+
+#========================================================================
+# Install binary object libraries. On Windows this includes both .dll and
+# .lib files. Because the .lib files are not explicitly listed anywhere,
+# we need to deduce their existence from the .dll file of the same name.
+# Library files go into the lib directory.
+# In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh shell)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-lib-binaries:
+ @mkdir -p $(DESTDIR)$(pkglibdir)
+ @list='$(lib_BINARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+ stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
+ if test "x$$stub" = "xstub"; then \
+ echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
+ $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
+ else \
+ echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
+ $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
+ fi; \
+ ext=`echo $$p|sed -e "s/.*\.//"`; \
+ if test "x$$ext" = "xdll"; then \
+ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+ if test -f $$lib; then \
+ echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
+ $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+ fi; \
+ fi; \
+ fi; \
+ done
+ @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ destp=`basename $$p`; \
+ echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
+ fi; \
+ done
+
+#========================================================================
+# Install binary executables (e.g. .exe files and dependent .dll files)
+# This is for files that must go in the bin directory (located next to
+# wish and tclsh), like dependent .dll files on Windows.
+#
+# You should not have to modify this target, except to define bin_BINARIES
+# above if necessary.
+#========================================================================
+
+install-bin-binaries:
+ @mkdir -p $(DESTDIR)$(bindir)
+ @list='$(bin_BINARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
+ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+ fi; \
+ done
+
+.SUFFIXES: .c .$(OBJEXT)
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+ list='$(lib_BINARIES)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+ done
+ list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+ p=`basename $$p`; \
+ rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+ done
+ list='$(bin_BINARIES)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/$$p; \
+ done
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/TclMagick/unix/config/config.guess b/TclMagick/unix/config/config.guess
new file mode 100755
index 0000000..8152efd
--- /dev/null
+++ b/TclMagick/unix/config/config.guess
@@ -0,0 +1,1522 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
+
+timestamp='2011-11-11'
+
+# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
+ hexagon:Linux:*:*)
+ echo hexagon-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-gnu
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/TclMagick/unix/config/config.sub b/TclMagick/unix/config/config.sub
new file mode 100755
index 0000000..e76eaf4
--- /dev/null
+++ b/TclMagick/unix/config/config.sub
@@ -0,0 +1,1771 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
+
+timestamp='2011-11-11'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | open8 \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i386-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/TclMagick/unix/config/depcomp b/TclMagick/unix/config/depcomp
new file mode 100755
index 0000000..bd0ac08
--- /dev/null
+++ b/TclMagick/unix/config/depcomp
@@ -0,0 +1,688 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2011-12-04.11; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
+
+# 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, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> "$depfile"
+ echo >> "$depfile"
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add `dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mechanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test "$stat" = 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/ \1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/ /
+ G
+ p
+}' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/TclMagick/unix/config/install-sh b/TclMagick/unix/config/install-sh
new file mode 100755
index 0000000..a9244eb
--- /dev/null
+++ b/TclMagick/unix/config/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-01-19.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# 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.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for `test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # 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 $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/TclMagick/unix/config/ltmain.sh b/TclMagick/unix/config/ltmain.sh
new file mode 100644
index 0000000..63ae69d
--- /dev/null
+++ b/TclMagick/unix/config/ltmain.sh
@@ -0,0 +1,9655 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --no-quiet, --no-silent
+# print informational messages (default)
+# --no-warn don't display warning messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print more informational messages than default
+# --no-verbose don't print the extra informational messages
+# --version print version information
+# -h, --help, --help-all print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE. When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.4.2
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.2
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+ s@/\./@/@g
+ t dotsl
+ s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+# value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test "$func_normal_abspath_tpath" = / ; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result" ; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+# value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=${func_dirname_result}
+ if test "x$func_relative_path_tlibdir" = x ; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test "x$func_stripname_result" != x ; then
+ func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+ fi
+
+ # Normalisation. If bindir is libdir, return empty string,
+ # else relative path ending with a slash; either way, target
+ # file name can be directly appended.
+ if test ! -z "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result/"
+ func_relative_path_result=$func_stripname_result
+ fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "$1" | $SED \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $opt_debug
+
+ $SED -n '/(C)/!b go
+ :more
+ /\./!{
+ N
+ s/\n# / /
+ b more
+ }
+ :go
+ /^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/^# *.*--help/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ echo
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+ $opt_debug
+
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+ p
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
+ ret=$?
+ if test -z "$1"; then
+ exit $ret
+ fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $opt_debug
+
+ func_error "missing argument for $1."
+ exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
+
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+ # this just eases exit handling
+ while test $# -gt 0; do
+ opt="$1"
+ shift
+ case $opt in
+ --debug|-x) opt_debug='set -x'
+ func_echo "enabling shell trace mode"
+ $opt_debug
+ ;;
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+ shift
+ ;;
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=:
+ ;;
+ --features)
+ opt_features=:
+func_features
+ ;;
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
+ opt_silent=false
+func_append preserve_args " $opt"
+ ;;
+ --no-warning|--no-warn)
+ opt_warning=false
+func_append preserve_args " $opt"
+ ;;
+ --no-verbose)
+ opt_verbose=false
+func_append preserve_args " $opt"
+ ;;
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
+
+ # Separate optargs to long options:
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # Validate options:
+
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
+ fi
+
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
+
+
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case "$lt_sysroot:$1" in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result="=$func_stripname_result"
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $opt_debug
+ func_convert_core_file_wine_to_w32_result="$1"
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $opt_debug
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=""
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $opt_debug
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $opt_debug
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " \`$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result="$1"
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $opt_debug
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " \`$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result="$3"
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $opt_debug
+ case $4 in
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $opt_debug
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $opt_debug
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $opt_debug
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $opt_debug
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_path_result="$1"
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result="$func_cygpath_result"
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_append_quoted lastarg "$arg"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test "$opt_help" = :; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | sed -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ sed '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "\`$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument \`$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test "x$prev" = x-m && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=""
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname" ; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename="$func_basename_result"
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename" ; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $opt_debug
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $opt_debug
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ if test "$lock_old_archive_extraction" = yes; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test "$lock_old_archive_extraction" = yes; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+# define _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (strcmp (argv[i], debug_opt) == 0)
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $opt_debug
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir="$arg"
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps ; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test "$prefer_static_libs" = yes ||
+ test "$prefer_static_libs,$installed" = "built,no"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$lt_sysroot$libdir"
+ absdir="$lt_sysroot$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ case "$host" in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ echo
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$opt_mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$absdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$opt_mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps ; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|qnx|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ func_append libobjs " $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$opt_mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test "$want_nocaseglob" = yes; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Remove ${wl} instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd1 in $cmds; do
+ IFS="$save_ifs"
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test "$try_normal_branch" = yes \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=${output_objdir}/${output_la}.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$opt_mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ func_append oldobjs " $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ func_resolve_sysroot "$deplib"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test "x$bindir" != x ;
+ then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=yes ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ odir="$objdir"
+ else
+ odir="$dir/$objdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$opt_mode" = uninstall && odir="$dir"
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test "$opt_mode" = clean; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case "$opt_mode" in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$opt_mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ func_append rmfiles " $odir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/TclMagick/unix/config/missing b/TclMagick/unix/config/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/TclMagick/unix/config/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ autom4te touch the output file, or create a stub one
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program). This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+ lex*|yacc*)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar*)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case $f in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te*)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison*|yacc*)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if test $# -ne 1; then
+ eval LASTARG="\${$#}"
+ case $LASTARG in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f y.tab.h; then
+ echo >y.tab.h
+ fi
+ if test ! -f y.tab.c; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex*|flex*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if test $# -ne 1; then
+ eval LASTARG="\${$#}"
+ case $LASTARG in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f lex.yy.c; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit $?
+ fi
+ ;;
+
+ makeinfo*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '
+ /^@setfilename/{
+ s/.* \([^ ]*\) *$/\1/
+ p
+ q
+ }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ tar*)
+ shift
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case $firstarg in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case $firstarg in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/TclMagick/unix/m4/acinclude.m4 b/TclMagick/unix/m4/acinclude.m4
new file mode 100644
index 0000000..53e412a
--- /dev/null
+++ b/TclMagick/unix/m4/acinclude.m4
@@ -0,0 +1,9 @@
+#
+# Include the TEA standard macro set
+#
+
+builtin(include,tcl.m4)
+
+#
+# Add here whatever m4 macros you want to define for your package
+#
diff --git a/TclMagick/unix/m4/libtool.m4 b/TclMagick/unix/m4/libtool.m4
new file mode 100644
index 0000000..44e0ecf
--- /dev/null
+++ b/TclMagick/unix/m4/libtool.m4
@@ -0,0 +1,7982 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_REPLACE_SHELLFNS
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case "$ECHO" in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[ --with-sysroot[=DIR] Search for dependent libraries within DIR
+ (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+ if test "$GCC" = yes; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([${with_sysroot}])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD="${LD-ld}_sol2"
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -eq 0; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test "$ac_status" -ne 0; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='${libname}.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec="$LIB"
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test "$GCC" != yes; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh
+ # decide which to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS="$save_LDFLAGS"])
+ if test "$lt_cv_irix_exported_symbol" = yes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+ else
+ $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile="$lt_outputfile.exe"
+ lt_tool_outputfile="$lt_tool_outputfile.exe"
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case ${prev}${p} in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test "$pre_test_object_deps_done" = no; then
+ case ${prev} in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+ CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,b/c, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+ func_split_long_opt_name=${1%%=*}
+ func_split_long_opt_arg=${1#*=}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+ _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac])
+
+ _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
+
+ _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
+
+ _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+ _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
+
+ _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+ func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+ eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+ # Save a `func_append' function call where possible by direct use of '+='
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+else
+ # Save a `func_append' function call even when '+=' is not available
+ sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+ && mv -f "$cfgfile.tmp" "$cfgfile" \
+ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+ test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+ AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/TclMagick/unix/m4/ltoptions.m4 b/TclMagick/unix/m4/ltoptions.m4
new file mode 100644
index 0000000..5d9acd8
--- /dev/null
+++ b/TclMagick/unix/m4/ltoptions.m4
@@ -0,0 +1,384 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for lt_pkg in $withval; do
+ IFS="$lt_save_ifs"
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/TclMagick/unix/m4/ltsugar.m4 b/TclMagick/unix/m4/ltsugar.m4
new file mode 100644
index 0000000..9000a05
--- /dev/null
+++ b/TclMagick/unix/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/TclMagick/unix/m4/ltversion.m4 b/TclMagick/unix/m4/ltversion.m4
new file mode 100644
index 0000000..07a8602
--- /dev/null
+++ b/TclMagick/unix/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/TclMagick/unix/m4/lt~obsolete.m4 b/TclMagick/unix/m4/lt~obsolete.m4
new file mode 100644
index 0000000..c573da9
--- /dev/null
+++ b/TclMagick/unix/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/TclMagick/unix/m4/tcl.m4 b/TclMagick/unix/m4/tcl.m4
new file mode 100644
index 0000000..b07ec54
--- /dev/null
+++ b/TclMagick/unix/m4/tcl.m4
@@ -0,0 +1,4456 @@
+# tcl.m4 --
+#
+# This file provides a set of autoconf macros to help TEA-enable
+# a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+AC_PREREQ(2.57)
+
+dnl TEA extensions pass us the version of TEA they think they
+dnl are compatible with (must be set in TEA_INIT below)
+dnl TEA_VERSION="3.10"
+
+# Possible values for key variables defined:
+#
+# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
+# PRACTCL_WINDOWINGSYSTEM - windows cocoa hitheme x11 sdl
+# TEA_PLATFORM - windows unix
+# TEA_TK_EXTENSION - True if this is a Tk extension
+# TEACUP_OS - windows macosx linux generic
+# TEACUP_TOOLSET - Toolset in use (gcc,mingw,msvc,llvm)
+# TEACUP_PROFILE - win32
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+# Locate the tclConfig.sh file and perform a sanity check on
+# the Tcl compile flags
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tcl=...
+#
+# Defines the following vars:
+# TCL_BIN_DIR Full path to the directory containing
+# the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+ #
+ # Ok, lets find the tcl configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tcl
+ #
+
+ if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tcl,
+ AC_HELP_STRING([--with-tcl],
+ [directory containing tcl configuration (tclConfig.sh)]),
+ with_tclconfig="${withval}")
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tcl was specified.
+ if test x"${with_tclconfig}" != x ; then
+ case "${with_tclconfig}" in
+ */tclConfig.sh )
+ if test -f "${with_tclconfig}"; then
+ AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+ with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ ; do
+ if test -f "$i/Tcl.framework/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/lib/tcl8.5 2>/dev/null` \
+ ; do
+ if test -f "$i/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tcl \
+ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCL_BIN_DIR="# no Tcl configs found"
+ AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
+ else
+ no_tcl=
+ TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+ AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+# Locate the tkConfig.sh file
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tk=...
+#
+# Defines the following vars:
+# TK_BIN_DIR Full path to the directory containing
+# the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+ #
+ # Ok, lets find the tk configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tk
+ #
+
+ if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ TEA_TK_EXTENSION=0
+ AC_ARG_WITH(tk,
+ AC_HELP_STRING([--with-tk],
+ [directory containing tk configuration (tkConfig.sh)]),
+ with_tkconfig="${withval}")
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ case "${with_tkconfig}" in
+ */tkConfig.sh )
+ if test -f "${with_tkconfig}"; then
+ AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+ with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ ; do
+ if test -f "$i/Tk.framework/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TK_BIN_DIR="# no Tk configs found"
+ AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
+ else
+ no_tk=
+ TEA_TK_EXTENSION=1
+ TK_BIN_DIR="${ac_cv_c_tkconfig}"
+ AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+# Load the tclConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TCL_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_BIN_DIR
+# TCL_SRC_DIR
+# TCL_LIB_FILE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+ if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TCL_BIN_DIR}/tclConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+ eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+ # If the TCL_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TCL_LIB_SPEC will be set to the value
+ # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+ # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+ TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+ TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tcl.framework installed in an arbitrary location.
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+ for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+ TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+ TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+ TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+ eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+ eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+ eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_PATCH_LEVEL)
+ AC_SUBST(TCL_BIN_DIR)
+ AC_SUBST(TCL_SRC_DIR)
+
+ AC_SUBST(TCL_LIB_FILE)
+ AC_SUBST(TCL_LIB_FLAG)
+ AC_SUBST(TCL_LIB_SPEC)
+
+ AC_SUBST(TCL_STUB_LIB_FILE)
+ AC_SUBST(TCL_STUB_LIB_FLAG)
+ AC_SUBST(TCL_STUB_LIB_SPEC)
+
+ AC_MSG_CHECKING([platform])
+ hold_cc=$CC; CC="$TCL_CC"
+ AC_TRY_COMPILE(,[
+ #ifdef _WIN32
+ #error win32
+ #endif
+ ], [
+ TEA_PLATFORM="unix"
+ CYGPATH=echo
+ ], [
+ TEA_PLATFORM="windows"
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
+ )
+ CC=$hold_cc
+ AC_MSG_RESULT($TEA_PLATFORM)
+
+ # The BUILD_$pkg is to define the correct extern storage class
+ # handling when making this package
+ AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
+ [Building extension source?])
+ # Do this here as we have fully defined TEA_PLATFORM now
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ EXEEXT=".exe"
+ CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
+ fi
+
+ # TEA specific:
+ AC_SUBST(CLEANFILES)
+ AC_SUBST(TCL_LIBS)
+ AC_SUBST(TCL_DEFS)
+ AC_SUBST(TCL_EXTRA_CFLAGS)
+ AC_SUBST(TCL_LD_FLAGS)
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+# Load the tkConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TK_BIN_DIR
+#
+# Results:
+#
+# Sets the following vars that should be in tkConfig.sh:
+# TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+ if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TK_BIN_DIR}/tkConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+ eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+ # If the TK_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TK_LIB_SPEC will be set to the value
+ # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+ # instead of TK_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+ TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+ TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tk.framework installed in an arbitrary location.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+ for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+ TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+ TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+ TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+ eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+ eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+ eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+ # TEA specific: Ensure windowingsystem is defined
+ case ${TK_DEFS} in
+ *PLATFORM_SDL*)
+ TEA_WINDOWINGSYSTEM="x11"
+ PRACTCL_WINDOWINGSYSTEM="sdl"
+ TEA_USE_SDL=yes
+ ;;
+ esac
+ if test "${TEA_USE_SDL}" = "yes" ; then
+ true
+ elif test "${TEA_PLATFORM}" = "unix" ; then
+ case ${TK_DEFS} in
+ *MAC_OSX_TK*)
+ AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X Cocoa?])
+ TEA_WINDOWINGSYSTEM="aqua"
+ PRACTCL_WINDOWINGSYSTEM="cocoa"
+ TEA_USE_HITHEME=no;
+ if test "${TK_VERSION}" = "8.5" ; then
+ if test "${TK_PATCH_LEVEL}" > ".17" ; then
+ TEA_USE_HITHEME=yes;
+ fi
+ elif test "${TK_VERSION}" = "8.6" ; then
+ if test "${TK_PATCH_LEVEL}" > ".3" ; then
+ TEA_USE_HITHEME=yes;
+ fi
+ elif test "${TK_VERSION}" > "8.6" ; then
+ TEA_USE_HITHEME=yes;
+ fi
+ ;;
+ *)
+ TEA_WINDOWINGSYSTEM="x11"
+ PRACTCL_WINDOWINGSYSTEM="x11"
+ ;;
+ esac
+ elif test "${TEA_PLATFORM}" = "windows" ; then
+ TEA_WINDOWINGSYSTEM="win32"
+ PRACTCL_WINDOWINGSYSTEM="windows"
+ fi
+
+ AC_SUBST(TK_VERSION)
+ AC_SUBST(TK_BIN_DIR)
+ AC_SUBST(TK_SRC_DIR)
+
+ AC_SUBST(TK_LIB_FILE)
+ AC_SUBST(TK_LIB_FLAG)
+ AC_SUBST(TK_LIB_SPEC)
+
+ AC_SUBST(TK_STUB_LIB_FILE)
+ AC_SUBST(TK_STUB_LIB_FLAG)
+ AC_SUBST(TK_STUB_LIB_SPEC)
+
+ # TEA specific:
+ AC_SUBST(TK_LIBS)
+ AC_SUBST(TK_XINCLUDES)
+ # Practcl
+ AC_SUBST(PRACTCL_WINDOWINGSYSTEM)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+# Determine the fully qualified path name of the tclsh executable
+# in the Tcl build directory or the tclsh installed in a bin
+# directory. This macro will correctly determine the name
+# of the tclsh executable even if tclsh has not yet been
+# built in the build directory. The tclsh found is always
+# associated with a tclConfig.sh file. This tclsh should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+ AC_MSG_CHECKING([for tclsh])
+
+ AC_ARG_WITH(tclsh, [ --with-tclsh Specify a local tcl shell to use for dynamic code], with_tclsh=${withval})
+ # Use the value from --with-tclsh, if it was given
+ TCLSH_PROG=0
+ if test x"${with_tclsh}" != x ; then
+ if test -f "${with_tclsh}" ; then
+ TCLSH_PROG=${with_tclsh}
+ else
+ if test -f "${with_tclsh}/tcl8.6" ; then
+ TCLSH_PROG="${with_tclsh}/tcl8.6"
+ else
+ if test -f "${with_tclsh}/tclsh86.exe" ; then
+ TCLSH_PROG="${with_tclsh}/tclsh86.exe"
+ else
+ AC_MSG_ERROR([${with_tclsh} does not point to a valid Tcl executable])
+ fi
+ fi
+ fi
+ else
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ # tclConfig.sh is in Tcl build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" ; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+ elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}" ; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}"
+ elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}" ; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}"
+ elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}" ; then
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}"
+ fi
+ else
+ TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+ fi
+ else
+ # tclConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
+ else
+ TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
+ fi
+ list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${TCLSH_PROG}" ; then
+ REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+ fi
+ fi
+ AC_MSG_RESULT([${TCLSH_PROG}])
+ AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+# Determine the fully qualified path name of the wish executable
+# in the Tk build directory or the wish installed in a bin
+# directory. This macro will correctly determine the name
+# of the wish executable even if wish has not yet been
+# built in the build directory. The wish found is always
+# associated with a tkConfig.sh file. This wish should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+ AC_MSG_CHECKING([for wish])
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ # tkConfig.sh is in Tk build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" ; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}s${EXEEXT}" ; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}$s{EXEEXT}"
+ elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}" ; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}"
+ elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}" ; then
+ WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}"
+ fi
+ else
+ WISH_PROG="${TK_BIN_DIR}/wish"
+ fi
+ else
+ # tkConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ else
+ WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+ fi
+ list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${WISH_PROG}" ; then
+ REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+ fi
+ AC_MSG_RESULT([${WISH_PROG}])
+ AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+# Allows the building of shared libraries
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-shared=yes|no
+# --enable-stubs=yes|no
+#
+# Defines the following vars:
+# STATIC_BUILD Used for building import/export libraries
+# on Windows.
+#
+# Sets the following vars:
+# SHARED_BUILD Value of 1 or 0
+# STUBS_BUILD Value if 1 or 0
+# USE_TCL_STUBS Value true: if SHARED_BUILD or --enable-stubs
+# USE_TCLOO_STUBS Value true: if SHARED_BUILD or --enable-stubs
+# USE_TK_STUBS Value true: if SHARED_BUILD or --enable-stubs
+# AND TEA_WINDOWING_SYSTEM != ""
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ENABLE_SHARED], [
+ AC_MSG_CHECKING([how to build libraries])
+ AC_ARG_ENABLE(shared,
+ AC_HELP_STRING([--enable-shared],
+ [build and link with shared libraries (default: on)]),
+ [shared_ok=$enableval], [shared_ok=yes])
+
+ if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ shared_ok=$enableval
+ else
+ shared_ok=yes
+ fi
+
+ AC_ARG_ENABLE(stubs,
+ AC_HELP_STRING([--enable-stubs],
+ [build and link with stub libraries. Always true for shared builds (default: on)]),
+ [stubs_ok=$enableval], [stubs_ok=yes])
+
+ if test "${enable_stubs+set}" = set; then
+ enableval="$enable_stubs"
+ stubs_ok=$enableval
+ else
+ stubs_ok=yes
+ fi
+
+ # Stubs are always enabled for shared builds
+ if test "$shared_ok" = "yes" ; then
+ AC_MSG_RESULT([shared])
+ SHARED_BUILD=1
+ STUBS_BUILD=1
+ else
+ AC_MSG_RESULT([static])
+ SHARED_BUILD=0
+ AC_DEFINE(STATIC_BUILD, 1, [This a static build])
+ if test "$stubs_ok" = "yes" ; then
+ STUBS_BUILD=1
+ else
+ STUBS_BUILD=0
+ fi
+ fi
+ if test "${STUBS_BUILD}" = "1" ; then
+ AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
+ AC_DEFINE(USE_TCLOO_STUBS, 1, [Use TclOO stubs])
+ if test "${TEA_WINDOWINGSYSTEM}" != ""; then
+ AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
+ fi
+ fi
+
+ AC_SUBST(SHARED_BUILD)
+ AC_SUBST(STUBS_BUILD)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+# Specify if thread support should be enabled. If "yes" is specified
+# as an arg (optional), threads are enabled by default, "no" means
+# threads are disabled. "yes" is the default.
+#
+# TCL_THREADS is checked so that if you are compiling an extension
+# against a threaded core, your extension must be compiled threaded
+# as well.
+#
+# Note that it is legal to have a thread enabled extension run in a
+# threaded or non-threaded Tcl core, but a non-threaded extension may
+# only run in a non-threaded Tcl core.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-threads
+#
+# Sets the following vars:
+# THREADS_LIBS Thread library(s)
+#
+# Defines the following vars:
+# TCL_THREADS
+# _REENTRANT
+# _THREAD_SAFE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+ AC_ARG_ENABLE(threads,
+ AC_HELP_STRING([--enable-threads],
+ [build with threads]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+
+ if test "${enable_threads+set}" = set; then
+ enableval="$enable_threads"
+ tcl_ok=$enableval
+ else
+ tcl_ok=yes
+ fi
+
+ if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+ TCL_THREADS=1
+
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ # We are always OK on Windows, so check what this platform wants:
+
+ # USE_THREAD_ALLOC tells us to try the special thread-based
+ # allocator that significantly reduces lock contention
+ AC_DEFINE(USE_THREAD_ALLOC, 1,
+ [Do we want to use the threaded memory allocator?])
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ if test "`uname -s`" = "SunOS" ; then
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+ fi
+ AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+ AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ # Check a little harder for __pthread_mutex_init in the same
+ # library, as some systems hide it there until pthread.h is
+ # defined. We could alternatively do an AC_TRY_COMPILE with
+ # pthread.h, but that will work with libpthread really doesn't
+ # exist, like AIX 4.2. [Bug: 4359]
+ AC_CHECK_LIB(pthread, __pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthread"
+ else
+ AC_CHECK_LIB(pthreads, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthreads"
+ else
+ AC_CHECK_LIB(c, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ AC_CHECK_LIB(c_r, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -pthread"
+ else
+ TCL_THREADS=0
+ AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+ fi
+ fi
+ fi
+ fi
+ fi
+ else
+ TCL_THREADS=0
+ fi
+ # Do checking message here to not mess up interleaved configure output
+ AC_MSG_CHECKING([for building with threads])
+ if test "${TCL_THREADS}" = 1; then
+ AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+ AC_MSG_RESULT([yes (default)])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ # TCL_THREADS sanity checking. See if our request for building with
+ # threads is the same as the way Tcl was built. If not, warn the user.
+ case ${TCL_DEFS} in
+ *THREADS=1*)
+ if test "${TCL_THREADS}" = "0"; then
+ AC_MSG_WARN([
+ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+ that IS thread-enabled. It is recommended to use --enable-threads.])
+ fi
+ ;;
+ *)
+ if test "${TCL_THREADS}" = "1"; then
+ AC_MSG_WARN([
+ --enable-threads requested, but building against a Tcl that is NOT
+ thread-enabled. This is an OK configuration that will also run in
+ a thread-enabled core.])
+ fi
+ ;;
+ esac
+ AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+# Specify if debugging symbols should be used.
+# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+# none
+#
+# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+# Requires the following vars to be set in the Makefile:
+# CFLAGS_DEFAULT
+# LDFLAGS_DEFAULT
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-symbols
+#
+# Defines the following vars:
+# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
+# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
+# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+# Sets to $(LDFLAGS_OPTIMIZE) if false
+# DBGX Formerly used as debug library extension;
+# always blank now.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_CONFIG_CFLAGS])
+ AC_MSG_CHECKING([for build with symbols])
+ AC_ARG_ENABLE(symbols,
+ AC_HELP_STRING([--enable-symbols],
+ [build with debugging symbols (default: off)]),
+ [tcl_ok=$enableval], [tcl_ok=no])
+ DBGX=""
+ if test "$tcl_ok" = "no"; then
+ CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
+ LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+ AC_MSG_RESULT([no])
+ else
+ CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+ LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+ if test "$tcl_ok" = "yes"; then
+ AC_MSG_RESULT([yes (standard debugging)])
+ fi
+ fi
+ # TEA specific:
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ LDFLAGS_DEFAULT="${LDFLAGS}"
+ fi
+ AC_SUBST(CFLAGS_DEFAULT)
+ AC_SUBST(LDFLAGS_DEFAULT)
+ AC_SUBST(TCL_DBGX)
+
+ if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+ AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+ fi
+
+ if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+ if test "$tcl_ok" = "all"; then
+ AC_MSG_RESULT([enabled symbols mem debugging])
+ else
+ AC_MSG_RESULT([enabled $tcl_ok debugging])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+# Allows use of modern nl_langinfo check for better l10n.
+# This is only relevant for Unix.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-langinfo=yes|no (default is yes)
+#
+# Defines the following vars:
+# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+ AC_ARG_ENABLE(langinfo,
+ AC_HELP_STRING([--enable-langinfo],
+ [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+ [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+ HAVE_LANGINFO=0
+ if test "$langinfo_ok" = "yes"; then
+ AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+ fi
+ AC_MSG_CHECKING([whether to use nl_langinfo])
+ if test "$langinfo_ok" = "yes"; then
+ AC_CACHE_VAL(tcl_cv_langinfo_h, [
+ AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+ [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+ AC_MSG_RESULT([$tcl_cv_langinfo_h])
+ if test $tcl_cv_langinfo_h = yes; then
+ AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+ fi
+ else
+ AC_MSG_RESULT([$langinfo_ok])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+# Determine what the system is (some things cannot be easily checked
+# on a feature-driven basis, alas). This can usually be done via the
+# "uname" command.
+#
+# Arguments:
+# none
+#
+# Results:
+# Defines the following var:
+#
+# system - System/platform/version identification code.
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+ # TEA specific:
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ tcl_cv_sys_version=windows
+ else
+ tcl_cv_sys_version=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ AC_MSG_WARN([can't find uname command])
+ tcl_cv_sys_version=unknown
+ else
+ if test "`uname -s`" = "AIX" ; then
+ tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+ fi
+ ])
+ system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+# Try to determine the proper flags to pass to the compiler
+# for building shared libraries and other such nonsense.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substitutes the following vars:
+#
+# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
+# LDFLAGS - Flags to pass to the compiler when linking object
+# files into an executable application binary such
+# as tclsh.
+# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile. Could
+# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile.
+# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
+# of a shared library (may request position-independent
+# code, among other things).
+# SHLIB_LD - Base command to use for combining object files
+# into a shared library.
+# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+# creating shared libraries. This symbol typically
+# goes at the end of the "ld" commands that build
+# shared libraries. The value of the symbol defaults to
+# "${LIBS}" if all of the dependent libraries should
+# be specified when creating a shared library. If
+# dependent libraries should not be specified (as on
+# SunOS 4.x, where they cause the link to fail, or in
+# general if Tcl and Tk aren't themselves shared
+# libraries), then this symbol has an empty string
+# as its value.
+# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
+# extensions. An empty string means we don't know how
+# to use shared libraries on this platform.
+# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
+# in a static or shared library name, using the $PACKAGE_VERSION variable
+# to put the version in the right place. This is used
+# by platforms that need non-standard library names.
+# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
+# to have a version after the .so, and ${PACKAGE_VERSION}.a
+# on AIX, since a shared library needs to have
+# a .a extension whereas shared objects for loadable
+# extensions have a .so extension. Defaults to
+# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
+# CFLAGS_DEBUG -
+# Flags used when running the compiler in debug mode
+# CFLAGS_OPTIMIZE -
+# Flags used when running the compiler in optimize mode
+# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+
+ # Step 0.a: Enable 64 bit support?
+
+ AC_MSG_CHECKING([if 64bit support is requested])
+ AC_ARG_ENABLE(64bit,
+ AC_HELP_STRING([--enable-64bit],
+ [enable 64bit support (default: off)]),
+ [do64bit=$enableval], [do64bit=no])
+ AC_MSG_RESULT([$do64bit])
+
+ # Step 0.b: Enable Solaris 64 bit VIS support?
+
+ AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+ AC_ARG_ENABLE(64bit-vis,
+ AC_HELP_STRING([--enable-64bit-vis],
+ [enable 64bit Sparc VIS support (default: off)]),
+ [do64bitVIS=$enableval], [do64bitVIS=no])
+ AC_MSG_RESULT([$do64bitVIS])
+ # Force 64bit on with VIS
+ AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+ # Step 0.c: Check if visibility support is available. Do this here so
+ # that platform specific alternatives can be used below if this fails.
+
+ AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+ tcl_cv_cc_visibility_hidden, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+ AC_TRY_LINK([
+ extern __attribute__((__visibility__("hidden"))) void f(void);
+ void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+ tcl_cv_cc_visibility_hidden=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+ AC_DEFINE(MODULE_SCOPE,
+ [extern __attribute__((__visibility__("hidden")))],
+ [Compiler support for module scope symbols])
+ AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
+ ])
+
+ # Step 0.d: Disable -rpath support?
+
+ AC_MSG_CHECKING([if rpath support is requested])
+ AC_ARG_ENABLE(rpath,
+ AC_HELP_STRING([--disable-rpath],
+ [disable rpath support (default: on)]),
+ [doRpath=$enableval], [doRpath=yes])
+ AC_MSG_RESULT([$doRpath])
+
+ # TEA specific: Cross-compiling options for Windows/CE builds?
+
+ AS_IF([test "${TEA_PLATFORM}" = windows], [
+ AC_MSG_CHECKING([if Windows/CE build is requested])
+ AC_ARG_ENABLE(wince,
+ AC_HELP_STRING([--enable-wince],
+ [enable Win/CE support (where applicable)]),
+ [doWince=$enableval], [doWince=no])
+ AC_MSG_RESULT([$doWince])
+ ])
+
+ # Set the variable "system" to hold the name and version number
+ # for the system.
+
+ TEA_CONFIG_SYSTEM
+
+ # Require ranlib early so we can override it in special cases below.
+
+ AC_REQUIRE([AC_PROG_RANLIB])
+
+ # Set configuration options based on system name and version.
+ # This is similar to Tcl's unix/tcl.m4 except that we've added a
+ # "windows" case and removed some core-only vars.
+
+ do64bit_ok=no
+ # default to '{$LIBS}' and set to "" on per-platform necessary basis
+ SHLIB_LD_LIBS='${LIBS}'
+ # When ld needs options to work in 64-bit mode, put them in
+ # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
+ # is disabled by the user. [Bug 1016796]
+ LDFLAGS_ARCH=""
+ UNSHARED_LIB_SUFFIX=""
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
+ ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
+ TCL_LIB_VERSIONS_OK=ok
+ CFLAGS_DEBUG=-g
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS_OPTIMIZE=-O2
+ CFLAGS_WARNING="-Wall"
+ ], [
+ CFLAGS_OPTIMIZE=-O
+ CFLAGS_WARNING=""
+ ])
+ AC_CHECK_TOOL(AR, ar)
+ STLIB_LD='${AR} cr'
+ LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+ AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
+ case $system in
+ # TEA specific:
+ windows)
+ # This is a 2-stage check to make sure we have the 64-bit SDK
+ # We have to know where the SDK is installed.
+ # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
+ # MACHINE is IX86 for LINK, but this is used by the manifest,
+ # which requires x86|amd64|ia64.
+ MACHINE="X86"
+ if test "$do64bit" != "no" ; then
+ if test "x${MSSDK}x" = "xx" ; then
+ MSSDK="C:/Progra~1/Microsoft Platform SDK"
+ fi
+ MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'`
+ PATH64=""
+ case "$do64bit" in
+ amd64|x64|yes)
+ MACHINE="AMD64" ; # default to AMD64 64-bit build
+ PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
+ ;;
+ ia64)
+ MACHINE="IA64"
+ PATH64="${MSSDK}/Bin/Win64"
+ ;;
+ esac
+ if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
+ AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+ AC_MSG_WARN([Ensure latest Platform SDK is installed])
+ do64bit="no"
+ else
+ AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
+ do64bit_ok="yes"
+ fi
+ fi
+
+ if test "$doWince" != "no" ; then
+ if test "$do64bit" != "no" ; then
+ AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+ fi
+ if test "$GCC" = "yes" ; then
+ AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+ fi
+ TEA_PATH_CELIB
+ # Set defaults for common evc4/PPC2003 setup
+ # Currently Tcl requires 300+, possibly 420+ for sockets
+ CEVERSION=420; # could be 211 300 301 400 420 ...
+ TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
+ ARCH=ARM; # could be ARM MIPS X86EM ...
+ PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+ if test "$doWince" != "yes"; then
+ # If !yes then the user specified something
+ # Reset ARCH to allow user to skip specifying it
+ ARCH=
+ eval `echo $doWince | awk -F, '{ \
+ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+ }'`
+ if test "x${ARCH}" = "x" ; then
+ ARCH=$TARGETCPU;
+ fi
+ fi
+ OSVERSION=WCE$CEVERSION;
+ if test "x${WCEROOT}" = "x" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+ if test ! -d "${WCEROOT}" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+ fi
+ fi
+ if test "x${SDKROOT}" = "x" ; then
+ SDKROOT="C:/Program Files/Windows CE Tools"
+ if test ! -d "${SDKROOT}" ; then
+ SDKROOT="C:/Windows CE Tools"
+ fi
+ fi
+ WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+ SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+ if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+ AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+ doWince="no"
+ else
+ # We could PATH_NOSPACE these, but that's not important,
+ # as long as we quote them when used.
+ CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+ if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+ CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+ fi
+ CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+ fi
+ fi
+
+ if test "$GCC" != "yes" ; then
+ if test "${SHARED_BUILD}" = "0" ; then
+ runtime=-MT
+ else
+ runtime=-MD
+ fi
+ case "x`echo \${VisualStudioVersion}`" in
+ x1[[4-9]]*)
+ lflags="${lflags} -nodefaultlib:libucrt.lib"
+ TEA_ADD_LIBS([ucrt.lib])
+ ;;
+ *)
+ ;;
+ esac
+
+ if test "$do64bit" != "no" ; then
+ # All this magic is necessary for the Win64 SDK RC1 - hobbs
+ CC="\"${PATH64}/cl.exe\""
+ CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
+ RC="\"${MSSDK}/bin/rc.exe\""
+ lflags="${lflags} -nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
+ LINKBIN="\"${PATH64}/link.exe\""
+ CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
+ CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+ # Avoid 'unresolved external symbol __security_cookie'
+ # errors, c.f. http://support.microsoft.com/?id=894573
+ TEA_ADD_LIBS([bufferoverflowU.lib])
+ elif test "$doWince" != "no" ; then
+ CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+ if test "${TARGETCPU}" = "X86"; then
+ CC="\"${CEBINROOT}/cl.exe\""
+ else
+ CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+ fi
+ CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+ RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+ arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+ defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # Static CE builds require static celib as well
+ defs="${defs} _DLL"
+ fi
+ for i in $defs ; do
+ AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+ done
+ AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+ AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+ CFLAGS_DEBUG="-nologo -Zi -Od"
+ CFLAGS_OPTIMIZE="-nologo -Ox"
+ lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+ lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+ LINKBIN="\"${CEBINROOT}/link.exe\""
+ AC_SUBST(CELIB_DIR)
+ else
+ RC="rc"
+ lflags="${lflags} -nologo"
+ LINKBIN="link"
+ CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
+ CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
+ fi
+ fi
+
+ if test "$GCC" = "yes"; then
+ # mingw gcc mode
+ AC_CHECK_TOOL(RC, windres)
+ CFLAGS_DEBUG="-g"
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+ SHLIB_LD='${CC} -shared'
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ PRACTCL_UNSHARED_LIB_SUFFIX='.a'
+
+ LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+ LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+
+ AC_CACHE_CHECK(for cross-compile version of gcc,
+ ac_cv_cross,
+ AC_TRY_COMPILE([
+ #ifdef _WIN32
+ #error cross-compiler
+ #endif
+ ], [],
+ ac_cv_cross=yes,
+ ac_cv_cross=no)
+ )
+ if test "$ac_cv_cross" = "yes"; then
+ case "$do64bit" in
+ amd64|x64|yes)
+ CC="x86_64-w64-mingw32-gcc"
+ LD="x86_64-w64-mingw32-ld"
+ AR="x86_64-w64-mingw32-ar"
+ RANLIB="x86_64-w64-mingw32-ranlib"
+ RC="x86_64-w64-mingw32-windres"
+ ;;
+ *)
+ CC="i686-w64-mingw32-gcc"
+ LD="i686-w64-mingw32-ld"
+ AR="i686-w64-mingw32-ar"
+ RANLIB="i686-w64-mingw32-ranlib"
+ RC="i686-w64-mingw32-windres"
+ ;;
+ esac
+ fi
+
+ else
+ SHLIB_LD="${LINKBIN} -dll ${lflags}"
+ # link -lib only works when -lib is the first arg
+ STLIB_LD="${LINKBIN} -lib ${lflags}"
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
+ PATHTYPE=-w
+ # For information on what debugtype is most useful, see:
+ # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+ # and also
+ # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
+ # This essentially turns it all on.
+ LDFLAGS_DEBUG="-debug -debugtype:cv"
+ LDFLAGS_OPTIMIZE="-release"
+ if test "$doWince" != "no" ; then
+ LDFLAGS_CONSOLE="-link ${lflags}"
+ LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
+ else
+ LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
+ LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
+ fi
+ fi
+
+ SHLIB_SUFFIX=".dll"
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
+
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ AIX-*)
+ AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+ # AIX requires the _r compiler when gcc isn't being used
+ case "${CC}" in
+ *_r|*_r\ *)
+ # ok ...
+ ;;
+ *)
+ # Make sure only first arg gets _r
+ CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
+ ;;
+ esac
+ AC_MSG_RESULT([Using $CC for compiling with threads])
+ ])
+ LIBS="$LIBS -lc"
+ SHLIB_CFLAGS=""
+ SHLIB_SUFFIX=".so"
+
+ LD_LIBRARY_PATH_VAR="LIBPATH"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -q64"
+ LDFLAGS_ARCH="-q64"
+ RANLIB="${RANLIB} -X64"
+ AR="${AR} -X64"
+ SHLIB_LD_FLAGS="-b64"
+ ])
+ ])
+
+ AS_IF([test "`uname -m`" = ia64], [
+ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ AS_IF([test "$GCC" = yes], [
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ ], [
+ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+ ])
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ], [
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared -Wl,-bexpall'
+ ], [
+ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+ LDFLAGS="$LDFLAGS -brtl"
+ ])
+ SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+ CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ BeOS*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD='${CC} -nostart'
+ SHLIB_SUFFIX=".so"
+
+ #-----------------------------------------------------------
+ # Check for inet_ntoa in -lbind, for BeOS (which also needs
+ # -lsocket, even if the network functions are in -lnet which
+ # is always linked to, for compatibility.
+ #-----------------------------------------------------------
+ AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+ ;;
+ BSD/OS-4.*)
+ SHLIB_CFLAGS="-export-dynamic -fPIC"
+ SHLIB_LD='${CC} -shared'
+ SHLIB_SUFFIX=".so"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ CYGWIN_*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD='${CC} -shared'
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a"
+ SHLIB_SUFFIX=".dll"
+ EXEEXT=".exe"
+ do64bit_ok=yes
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ Haiku*)
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+ SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
+ AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
+ ;;
+ HP-UX-*.11.*)
+ # Use updated header definitions where possible
+ AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+ # TEA specific: Needed by Tcl, but not most extensions
+ #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+ #LIBS="$LIBS -lxnet" # Use the XOPEN network library
+
+ AS_IF([test "`uname -m`" = ia64], [
+ SHLIB_SUFFIX=".so"
+ # Use newer C++ library for C++ extensions
+ #if test "$GCC" != "yes" ; then
+ # CPPFLAGS="-AA"
+ #fi
+ ], [
+ SHLIB_SUFFIX=".sl"
+ ])
+ AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+ AS_IF([test "$tcl_ok" = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+ LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+ ])
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ CFLAGS="$CFLAGS -z"
+ # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+ #CFLAGS="$CFLAGS +DAportable"
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ ])
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = "yes"], [
+ AS_IF([test "$GCC" = yes], [
+ case `${CC} -dumpmachine` in
+ hppa64*)
+ # 64-bit gcc in use. Fix flags for GNU ld.
+ do64bit_ok=yes
+ SHLIB_LD='${CC} -shared'
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ;;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ;;
+ esac
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS +DD64"
+ LDFLAGS_ARCH="+DD64"
+ ])
+ ]) ;;
+ IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS="$CFLAGS -mabi=n32"
+ LDFLAGS="$LDFLAGS -mabi=n32"
+ ], [
+ case $system in
+ IRIX-6.3)
+ # Use to build 6.2 compatible binaries on 6.3.
+ CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+ ;;
+ *)
+ CFLAGS="$CFLAGS -n32"
+ ;;
+ esac
+ LDFLAGS="$LDFLAGS -n32"
+ ])
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+ # Check to enable 64-bit flags for compiler/linker
+
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported by gcc])
+ ], [
+ do64bit_ok=yes
+ SHLIB_LD="ld -64 -shared -rdata_shared"
+ CFLAGS="$CFLAGS -64"
+ LDFLAGS_ARCH="-64"
+ ])
+ ])
+ ;;
+ Linux*|GNU*|NetBSD-Debian)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+
+ # TEA specific:
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+ AS_IF([test $do64bit = yes], [
+ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -m64"
+ AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_m64 = yes], [
+ CFLAGS="$CFLAGS -m64"
+ do64bit_ok=yes
+ ])
+ ])
+
+ # The combo of gcc + glibc has a bug related to inlining of
+ # functions like strtod(). The -fno-builtin flag should address
+ # this problem but it does not work. The -fno-inline flag is kind
+ # of overkill but it works. Disable inlining only when one of the
+ # files in compat/*.c is being linked in.
+
+ AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+ ;;
+ Lynx*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+ CFLAGS_OPTIMIZE=-02
+ SHLIB_LD='${CC} -shared'
+ LD_FLAGS="-Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ ;;
+ OpenBSD-*)
+ arch=`arch -s`
+ case "$arch" in
+ vax)
+ SHLIB_SUFFIX=""
+ SHARED_LIB_SUFFIX=""
+ LDFLAGS=""
+ ;;
+ *)
+ case "$arch" in
+ alpha|sparc64)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ *)
+ SHLIB_CFLAGS="-fpic"
+ ;;
+ esac
+ SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
+ ;;
+ esac
+ case "$arch" in
+ vax)
+ CFLAGS_OPTIMIZE="-O1"
+ ;;
+ *)
+ CFLAGS_OPTIMIZE="-O2"
+ ;;
+ esac
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # On OpenBSD: Compile with -pthread
+ # Don't link with -lpthread
+ LIBS=`echo $LIBS | sed s/-lpthread//`
+ CFLAGS="$CFLAGS -pthread"
+ ])
+ # OpenBSD doesn't do version numbers with dots.
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ NetBSD-*)
+ # NetBSD has ELF and can use 'cc -shared' to build shared libs
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
+ SHLIB_SUFFIX=".so"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the CFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ;;
+ FreeBSD-*)
+ # This configuration from FreeBSD Ports.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="${CC} -shared"
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
+ SHLIB_SUFFIX=".so"
+ LDFLAGS=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the LDFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
+ case $system in
+ FreeBSD-3.*)
+ # Version numbers are dot-stripped by system policy.
+ TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
+ TCL_LIB_VERSIONS_OK=nodots
+ ;;
+ esac
+ ;;
+ Darwin-*)
+ CFLAGS_OPTIMIZE="-Os"
+ SHLIB_CFLAGS="-fno-common"
+ # To avoid discrepancies between what headers configure sees during
+ # preprocessing tests and compiling tests, move any -isysroot and
+ # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
+ CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
+ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+ if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
+ CFLAGS="`echo " ${CFLAGS}" | \
+ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
+ if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
+ AS_IF([test $do64bit = yes], [
+ case `arch` in
+ ppc)
+ AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+ tcl_cv_cc_arch_ppc64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+ tcl_cv_cc_arch_ppc64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ do64bit_ok=yes
+ ]);;
+ i386)
+ AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+ tcl_cv_cc_arch_x86_64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch x86_64"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+ tcl_cv_cc_arch_x86_64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+ CFLAGS="$CFLAGS -arch x86_64"
+ do64bit_ok=yes
+ ]);;
+ *)
+ AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+ esac
+ ], [
+ # Check for combined 32-bit and 64-bit fat build
+ AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+ fat_32_64=yes])
+ ])
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_single_module = yes], [
+ SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+ ])
+ # TEA specific: link shlib with current and compatibility version flags
+ vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
+ SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
+ SHLIB_SUFFIX=".dylib"
+ # Don't use -prebind when building for Mac OS X 10.4 or later only:
+ AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+ LDFLAGS="$LDFLAGS -prebind"])
+ LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+ AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+ tcl_cv_ld_search_paths_first, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+ tcl_cv_ld_search_paths_first=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ ])
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+ [Compiler support for module scope symbols])
+ tcl_cv_cc_visibility_hidden=yes
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+ # TEA specific: for combined 32 & 64 bit fat builds of Tk
+ # extensions, verify that 64-bit build is possible.
+ AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+ LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+ AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
+ tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
+ AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+ LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+ AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
+ tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ # remove 64-bit arch flags from CFLAGS et al. if configuration
+ # does not support 64-bit.
+ AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
+ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+ done])
+ ])
+ ;;
+ OS/390-*)
+ CFLAGS_OPTIMIZE="" # Optimizer is buggy
+ AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
+ [Should OS/390 do the right thing with sockets?])
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ AS_IF([test "$SHARED_BUILD" = 1], [
+ SHLIB_LD='ld -shared -expect_unresolved "*"'
+ ], [
+ SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+ ])
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+ # see pthread_intro(3) for pthread support on osf1, k.furukawa
+ AS_IF([test "${TCL_THREADS}" = 1], [
+ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+ CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+ LIBS=`echo $LIBS | sed s/-lpthreads//`
+ AS_IF([test "$GCC" = yes], [
+ LIBS="$LIBS -lpthread -lmach -lexc"
+ ], [
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ])
+ ;;
+ QNX-6*)
+ # QNX RTP
+ # This may work for all QNX, but it was only reported for v6.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SCO_SV-3.2*)
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_CFLAGS="-fPIC -melf"
+ LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+ ], [
+ SHLIB_CFLAGS="-Kpic -belf"
+ LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+ ])
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SunOS-5.[[0-6]])
+ # Careful to not let 5.10+ fall into this case
+
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ SunOS-5*)
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ arch=`isainfo`
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ AS_IF([test "$GCC" = yes], [
+ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64 -mcpu=v9"
+ LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+ SHLIB_CFLAGS="-fPIC"
+ ])
+ ], [
+ do64bit_ok=yes
+ AS_IF([test "$do64bitVIS" = yes], [
+ CFLAGS="$CFLAGS -xarch=v9a"
+ LDFLAGS_ARCH="-xarch=v9a"
+ ], [
+ CFLAGS="$CFLAGS -xarch=v9"
+ LDFLAGS_ARCH="-xarch=v9"
+ ])
+ # Solaris 64 uses this as well
+ #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+ ])
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+ esac
+ ], [
+ do64bit_ok=yes
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ CFLAGS="$CFLAGS -xarch=amd64"
+ LDFLAGS="$LDFLAGS -xarch=amd64";;
+ esac
+ ])
+ ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+ ])
+
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "$do64bit_ok" = yes], [
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ # We need to specify -static-libgcc or we need to
+ # add the path to the sparv9 libgcc.
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+ # for finding sparcv9 libgcc, get the regular libgcc
+ # path, remove so name and append 'sparcv9'
+ #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+ #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+ ])])
+ ])
+ ], [
+ case $system in
+ SunOS-5.[[1-9]][[0-9]]*)
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+ *)
+ SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+ esac
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ])
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_Bexport = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ esac
+
+ AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+ ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+ AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+ # Add in the arch flags late to ensure it wasn't removed.
+ # Not necessary in TEA, but this is aligned with core
+ LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
+
+ # If we're running gcc, then change the C flags for compiling shared
+ # libraries to the right flags for gcc, instead of those for the
+ # standard manufacturer compiler.
+
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ AIX-*) ;;
+ BSD/OS*) ;;
+ CYGWIN_*|MINGW32_*) ;;
+ IRIX*) ;;
+ NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ Darwin-*) ;;
+ SCO_SV-3.2*) ;;
+ windows) ;;
+ *) SHLIB_CFLAGS="-fPIC" ;;
+ esac])
+
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [extern],
+ [No Compiler support for module scope symbols])
+ ])
+
+ AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
+ ])
+ AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
+ ])
+
+ if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+ AC_CACHE_CHECK(for SEH support in compiler,
+ tcl_cv_seh,
+ AC_TRY_RUN([
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+ int main(int argc, char** argv) {
+ int a, b = 0;
+ __try {
+ a = 666 / b;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ return 0;
+ }
+ return 1;
+ }
+ ],
+ tcl_cv_seh=yes,
+ tcl_cv_seh=no,
+ tcl_cv_seh=no)
+ )
+ if test "$tcl_cv_seh" = "no" ; then
+ AC_DEFINE(HAVE_NO_SEH, 1,
+ [Defined when mingw does not support SEH])
+ fi
+
+ #
+ # Check to see if the excpt.h include file provided contains the
+ # definition for EXCEPTION_DISPOSITION; if not, which is the case
+ # with Cygwin's version as of 2002-04-10, define it to be int,
+ # sufficient for getting the current code to work.
+ #
+ AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
+ tcl_cv_eh_disposition,
+ AC_TRY_COMPILE([
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+ ],[
+ EXCEPTION_DISPOSITION x;
+ ],
+ tcl_cv_eh_disposition=yes,
+ tcl_cv_eh_disposition=no)
+ )
+ if test "$tcl_cv_eh_disposition" = "no" ; then
+ AC_DEFINE(EXCEPTION_DISPOSITION, int,
+ [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
+ fi
+
+ # Check to see if winnt.h defines CHAR, SHORT, and LONG
+ # even if VOID has already been #defined. The win32api
+ # used by mingw and cygwin is known to do this.
+
+ AC_CACHE_CHECK(for winnt.h that ignores VOID define,
+ tcl_cv_winnt_ignore_void,
+ AC_TRY_COMPILE([
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+ ], [
+ CHAR c;
+ SHORT s;
+ LONG l;
+ ],
+ tcl_cv_winnt_ignore_void=yes,
+ tcl_cv_winnt_ignore_void=no)
+ )
+ if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+ AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
+ [Defined when cygwin/mingw ignores VOID define in winnt.h])
+ fi
+ fi
+
+ # See if the compiler supports casting to a union type.
+ # This is used to stop gcc from printing a compiler
+ # warning when initializing a union member.
+
+ AC_CACHE_CHECK(for cast to union support,
+ tcl_cv_cast_to_union,
+ AC_TRY_COMPILE([],
+ [
+ union foo { int i; double d; };
+ union foo f = (union foo) (int) 0;
+ ],
+ tcl_cv_cast_to_union=yes,
+ tcl_cv_cast_to_union=no)
+ )
+ if test "$tcl_cv_cast_to_union" = "yes"; then
+ AC_DEFINE(HAVE_CAST_TO_UNION, 1,
+ [Defined when compiler supports casting to union type.])
+ fi
+
+ AC_SUBST(CFLAGS_DEBUG)
+ AC_SUBST(CFLAGS_OPTIMIZE)
+ AC_SUBST(CFLAGS_WARNING)
+
+ AC_SUBST(STLIB_LD)
+ AC_SUBST(SHLIB_LD)
+ AC_SUBST(SHLIB_SUFFIX)
+
+ AC_SUBST(SHLIB_LD_LIBS)
+ AC_SUBST(SHLIB_CFLAGS)
+
+ AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+ # These must be called after we do the basic CFLAGS checks and
+ # verify any possible 64-bit or similar switches are necessary
+ TEA_TCL_EARLY_FLAGS
+ TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+# Determine which interface to use to talk to the serial port.
+# Note that #include lines must begin in leftmost column for
+# some compilers to recognize them as preprocessor directives,
+# and some build environments have stdin not pointing at a
+# pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines only one of the following vars:
+# HAVE_SYS_MODEM_H
+# USE_TERMIOS
+# USE_TERMIO
+# USE_SGTTY
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+ AC_CHECK_HEADERS(sys/modem.h)
+ AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+ AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+ }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+ fi])
+ case $tcl_cv_api_serial in
+ termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+ termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+ sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_MISSING_POSIX_HEADERS
+#
+# Supply substitutes for missing POSIX header files. Special
+# notes:
+# - stdlib.h doesn't define strtol, strtoul, or
+# strtod in some versions of SunOS
+# - some versions of string.h don't declare procedures such
+# as strstr
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# NO_DIRENT_H
+# NO_ERRNO_H
+# NO_VALUES_H
+# HAVE_LIMITS_H or NO_LIMITS_H
+# NO_STDLIB_H
+# NO_STRING_H
+# NO_SYS_WAIT_H
+# NO_DLFCN_H
+# HAVE_SYS_PARAM_H
+#
+# HAVE_STRING_H ?
+#
+# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
+# CHECK on limits.h
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
+ AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
+ AC_TRY_LINK([#include <sys/types.h>
+#include <dirent.h>], [
+#ifndef _POSIX_SOURCE
+# ifdef __Lynx__
+ /*
+ * Generate compilation error to make the test fail: Lynx headers
+ * are only valid if really in the POSIX environment.
+ */
+
+ missing_procedure();
+# endif
+#endif
+DIR *d;
+struct dirent *entryPtr;
+char *p;
+d = opendir("foobar");
+entryPtr = readdir(d);
+p = entryPtr->d_name;
+closedir(d);
+], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
+
+ if test $tcl_cv_dirent_h = no; then
+ AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
+ fi
+
+ # TEA specific:
+ AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
+ AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
+ AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
+ AC_CHECK_HEADER(limits.h,
+ [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
+ [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
+ AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
+ AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
+ AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
+ AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
+ if test $tcl_ok = 0; then
+ AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
+ fi
+ AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+ AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
+ AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
+
+ # See also memmove check below for a place where NO_STRING_H can be
+ # set and why.
+
+ if test $tcl_ok = 0; then
+ AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
+ fi
+
+ AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
+ AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
+
+ # OS/390 lacks sys/param.h (and doesn't need it, by chance).
+ AC_HAVE_HEADERS(sys/param.h)
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+# Locate the X11 header files and the X11 library archive. Try
+# the ac_path_x macro first, but if it doesn't find the X stuff
+# (e.g. because there's no xmkmf program) then check through
+# a list of possible directories. Under some conditions the
+# autoconf macro will return an include directory that contains
+# no include files, so double-check its result just to be safe.
+#
+# This should be called after TEA_CONFIG_CFLAGS as setting the
+# LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets the following vars:
+# XINCLUDES
+# XLIBSW
+# PKG_LIBS (appends to)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+ if test "${PRACTCL_WINDOWINGSYSTEM}" = "x11" ; then
+ TEA_PATH_UNIX_X
+ fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+ AC_PATH_X
+ not_really_there=""
+ if test "$no_x" = ""; then
+ if test "$x_includes" = ""; then
+ AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
+ else
+ if test ! -r $x_includes/X11/Xlib.h; then
+ not_really_there="yes"
+ fi
+ fi
+ fi
+ if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+ AC_MSG_CHECKING([for X11 header files])
+ found_xincludes="no"
+ AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
+ if test "$found_xincludes" = "no"; then
+ dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+ for i in $dirs ; do
+ if test -r $i/X11/Xlib.h; then
+ AC_MSG_RESULT([$i])
+ XINCLUDES=" -I$i"
+ found_xincludes="yes"
+ break
+ fi
+ done
+ fi
+ else
+ if test "$x_includes" != ""; then
+ XINCLUDES="-I$x_includes"
+ found_xincludes="yes"
+ fi
+ fi
+ if test "$found_xincludes" = "no"; then
+ AC_MSG_RESULT([couldn't find any!])
+ fi
+
+ if test "$no_x" = yes; then
+ AC_MSG_CHECKING([for X11 libraries])
+ XLIBSW=nope
+ dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+ for i in $dirs ; do
+ if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+ AC_MSG_RESULT([$i])
+ XLIBSW="-L$i -lX11"
+ x_libraries="$i"
+ break
+ fi
+ done
+ else
+ if test "$x_libraries" = ""; then
+ XLIBSW=-lX11
+ else
+ XLIBSW="-L$x_libraries -lX11"
+ fi
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_MSG_RESULT([could not find any! Using -lX11.])
+ XLIBSW=-lX11
+ fi
+ # TEA specific:
+ if test x"${XLIBSW}" != x ; then
+ PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+# The statements below check for systems where POSIX-style
+# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+# On these systems (mostly older ones), use the old BSD-style
+# FIONBIO approach instead.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# HAVE_SYS_IOCTL_H
+# HAVE_SYS_FILIO_H
+# USE_FIONBIO
+# O_NONBLOCK
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+ AC_CHECK_HEADERS(sys/ioctl.h)
+ AC_CHECK_HEADERS(sys/filio.h)
+ TEA_CONFIG_SYSTEM
+ AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+ case $system in
+ OSF*)
+ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+ AC_MSG_RESULT([FIONBIO])
+ ;;
+ *)
+ AC_MSG_RESULT([O_NONBLOCK])
+ ;;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANDLER
+#
+# Checks how the system deals with time.h, what time structures
+# are used on the system, and what fields the structures have.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# USE_DELTA_FOR_TZ
+# HAVE_TM_GMTOFF
+# HAVE_TM_TZADJ
+# HAVE_TIMEZONE_VAR
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+ AC_CHECK_HEADERS(sys/time.h)
+ AC_HEADER_TIME
+ AC_STRUCT_TIMEZONE
+
+ AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+ AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+ tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+ if test $tcl_cv_member_tm_tzadj = yes ; then
+ AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+ fi
+
+ AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+ tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+ if test $tcl_cv_member_tm_gmtoff = yes ; then
+ AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+ fi
+
+ #
+ # Its important to include time.h in this check, as some systems
+ # (like convex) have timezone functions, etc.
+ #
+ AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern long timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+ if test $tcl_cv_timezone_long = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ else
+ #
+ # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+ #
+ AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern time_t timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+ if test $tcl_cv_timezone_time = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+# Under Solaris 2.4, strtod returns the wrong value for the
+# terminating character under some conditions. Check for this
+# and if the problem exists use a substitute procedure
+# "fixstrtod" (provided by Tcl) that corrects the error.
+# Also, on Compaq's Tru64 Unix 5.0,
+# strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Might defines some of the following vars:
+# strtod (=fixstrtod)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+ if test "$tcl_strtod" = 1; then
+ AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+ AC_TRY_RUN([
+ extern double strtod();
+ int main() {
+ char *infString="Inf", *nanString="NaN", *spaceString=" ";
+ char *term;
+ double value;
+ value = strtod(infString, &term);
+ if ((term != infString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(nanString, &term);
+ if ((term != nanString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(spaceString, &term);
+ if (term == (spaceString+1)) {
+ exit(1);
+ }
+ exit(0);
+ }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+ tcl_cv_strtod_buggy=buggy)])
+ if test "$tcl_cv_strtod_buggy" = buggy; then
+ AC_LIBOBJ([fixstrtod])
+ USE_COMPAT=1
+ AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_LINK_LIBS
+#
+# Search for the libraries needed to link the Tcl shell.
+# Things like the math library (-lm) and socket stuff (-lsocket vs.
+# -lnsl) are dealt with here.
+#
+# Arguments:
+# Requires the following vars to be set in the Makefile:
+# DL_LIBS (not in TEA, only needed in core)
+# LIBS
+# MATH_LIBS
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_LIBS
+# MATH_LIBS
+#
+# Might append to the following vars:
+# LIBS
+#
+# Might define the following vars:
+# HAVE_NET_ERRNO_H
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_LINK_LIBS], [
+ #--------------------------------------------------------------------
+ # On a few very rare systems, all of the libm.a stuff is
+ # already in libc.a. Set compiler flags accordingly.
+ # Also, Linux requires the "ieee" library for math to work
+ # right (and it must appear before "-lm").
+ #--------------------------------------------------------------------
+
+ AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
+ AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
+
+ #--------------------------------------------------------------------
+ # Interactive UNIX requires -linet instead of -lsocket, plus it
+ # needs net/errno.h to define the socket-related error codes.
+ #--------------------------------------------------------------------
+
+ AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
+ AC_CHECK_HEADER(net/errno.h, [
+ AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
+
+ #--------------------------------------------------------------------
+ # Check for the existence of the -lsocket and -lnsl libraries.
+ # The order here is important, so that they end up in the right
+ # order in the command line generated by make. Here are some
+ # special considerations:
+ # 1. Use "connect" and "accept" to check for -lsocket, and
+ # "gethostbyname" to check for -lnsl.
+ # 2. Use each function name only once: can't redo a check because
+ # autoconf caches the results of the last check and won't redo it.
+ # 3. Use -lnsl and -lsocket only if they supply procedures that
+ # aren't already present in the normal libraries. This is because
+ # IRIX 5.2 has libraries, but they aren't needed and they're
+ # bogus: they goof up name resolution if used.
+ # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
+ # To get around this problem, check for both libraries together
+ # if -lsocket doesn't work by itself.
+ #--------------------------------------------------------------------
+
+ tcl_checkBoth=0
+ AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
+ if test "$tcl_checkSocket" = 1; then
+ AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
+ LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
+ fi
+ if test "$tcl_checkBoth" = 1; then
+ tk_oldLibs=$LIBS
+ LIBS="$LIBS -lsocket -lnsl"
+ AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
+ fi
+ AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
+ [LIBS="$LIBS -lnsl"])])
+
+ # TEA specific: Don't perform the eval of the libraries here because
+ # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
+
+ TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
+ AC_SUBST(TCL_LIBS)
+ AC_SUBST(MATH_LIBS)
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+# Check for what flags are needed to be passed so the correct OS
+# features are available.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# _ISOC99_SOURCE
+# _LARGEFILE64_SOURCE
+# _LARGEFILE_SOURCE64
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+ AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+ AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+ if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+ AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+ tcl_flags="$tcl_flags $1"
+ fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+ AC_MSG_CHECKING([for required early compiler flags])
+ tcl_flags=""
+ TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+ [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+ [struct stat64 buf; int i = stat64("/", &buf);])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+ [char *p = (char *)open64;])
+ if test "x${tcl_flags}" = "x" ; then
+ AC_MSG_RESULT([none])
+ else
+ AC_MSG_RESULT([${tcl_flags}])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+# Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# TCL_WIDE_INT_IS_LONG
+# TCL_WIDE_INT_TYPE
+# HAVE_STRUCT_DIRENT64
+# HAVE_STRUCT_STAT64
+# HAVE_TYPE_OFF64_T
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+ AC_MSG_CHECKING([for 64-bit integer type])
+ AC_CACHE_VAL(tcl_cv_type_64bit,[
+ tcl_cv_type_64bit=none
+ # See if the compiler knows natively about __int64
+ AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+ tcl_type_64bit=__int64, tcl_type_64bit="long long")
+ # See if we should use long anyway Note that we substitute in the
+ # type that is our current guess for a 64-bit type inside this check
+ # program, so it should be modified only carefully...
+ AC_TRY_COMPILE(,[switch (0) {
+ case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
+ }],tcl_cv_type_64bit=${tcl_type_64bit})])
+ if test "${tcl_cv_type_64bit}" = none ; then
+ AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+ AC_MSG_RESULT([using long])
+ elif test "${tcl_cv_type_64bit}" = "__int64" \
+ -a "${TEA_PLATFORM}" = "windows" ; then
+ # TEA specific: We actually want to use the default tcl.h checks in
+ # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+ AC_MSG_RESULT([using Tcl header defaults])
+ else
+ AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+ [What type should be used to define wide integers?])
+ AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+ # Now check for auxiliary declarations
+ AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+ AC_TRY_COMPILE([#include <sys/types.h>
+#include <dirent.h>],[struct dirent64 p;],
+ tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+ if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+ fi
+
+ AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+ AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+ tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+ if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+ fi
+
+ AC_CHECK_FUNCS(open64 lseek64)
+ AC_MSG_CHECKING([for off64_t])
+ AC_CACHE_VAL(tcl_cv_type_off64_t,[
+ AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+ tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+ dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+ dnl functions lseek64 and open64 are defined.
+ if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+ test "x${ac_cv_func_lseek64}" = "xyes" && \
+ test "x${ac_cv_func_open64}" = "xyes" ; then
+ AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+# Init various Tcl Extension Architecture (TEA) variables.
+# This should be the first called TEA_* macro.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substs the following vars:
+# CYGPATH
+# EXEEXT
+# Defines only:
+# TEA_VERSION
+# TEA_INITED
+# TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+# Select the executable extension based on the host type. This
+# is a lightweight replacement for AC_EXEEXT that doesn't require
+# a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+ # TEA extensions pass this us the version of TEA they think they
+ # are compatible with.
+ TEA_VERSION="3.10"
+ AC_MSG_CHECKING([for correct TEA configuration])
+ if test x"${PACKAGE_NAME}" = x ; then
+ AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.ac])
+ fi
+ if test x"$1" = x ; then
+ AC_MSG_ERROR([
+TEA version not specified.])
+ elif test "$1" != "${TEA_VERSION}" ; then
+ AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
+ else
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+ fi
+
+ # If the user did not set CFLAGS, set it now to keep macros
+ # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
+ if test "${CFLAGS+set}" != "set" ; then
+ CFLAGS=""
+ fi
+ TEA_TK_EXTENSION=0
+ AC_SUBST(TEA_TK_EXTENSION)
+ case "`uname -s`" in
+ *win32*|*WIN32*|*MINGW32_*)
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
+ EXEEXT=".exe"
+ TEA_PLATFORM="windows"
+ ;;
+ *CYGWIN_*)
+ EXEEXT=".exe"
+ # CYGPATH and TEA_PLATFORM are determined later in LOAD_TCLCONFIG
+ ;;
+ *)
+ CYGPATH=echo
+ # Maybe we are cross-compiling....
+ case ${host_alias} in
+ *mingw32*)
+ EXEEXT=".exe"
+ TEA_PLATFORM="windows"
+ ;;
+ *)
+ EXEEXT=""
+ TEA_PLATFORM="unix"
+ ;;
+ esac
+ ;;
+ esac
+
+ # Check if exec_prefix is set. If not use fall back to prefix.
+ # Note when adjusted, so that TEA_PREFIX can correct for this.
+ # This is needed for recursive configures, since autoconf propagates
+ # $prefix, but not $exec_prefix (doh!).
+ if test x$exec_prefix = xNONE ; then
+ exec_prefix_default=yes
+ exec_prefix=$prefix
+ fi
+
+ AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
+
+ AC_SUBST(EXEEXT)
+ AC_SUBST(CYGPATH)
+
+ # This package name must be replaced statically for AC_SUBST to work
+ AC_SUBST(PKG_LIB_FILE)
+ # Substitute STUB_LIB_FILE in case package creates a stub library too.
+ AC_SUBST(PKG_STUB_LIB_FILE)
+
+ # We AC_SUBST these here to ensure they are subst'ed,
+ # in case the user doesn't call TEA_ADD_...
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+ AC_SUBST(PKG_TCL_SOURCES)
+ AC_SUBST(PKG_HEADERS)
+ AC_SUBST(PKG_INCLUDES)
+ AC_SUBST(PKG_LIBS)
+ AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_SOURCES
+# PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ case $i in
+ [\$]*)
+ # allow $-var names
+ PKG_SOURCES="$PKG_SOURCES $i"
+ PKG_OBJECTS="$PKG_OBJECTS $i"
+ ;;
+ *)
+ # check for existence - allows for generic/win/unix VPATH
+ # To add more dirs here (like 'src'), you have to update VPATH
+ # in Makefile.in as well
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find source file '$i'])
+ fi
+ PKG_SOURCES="$PKG_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_OBJECTS="$PKG_OBJECTS $j"
+ ;;
+ esac
+ done
+ AC_SUBST(PKG_SOURCES)
+ AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_STUB_SOURCES
+# PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence - allows for generic/win/unix VPATH
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find stub source file '$i'])
+ fi
+ PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+ done
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+# Specify one or more Tcl source files. These should be platform
+# independent runtime files.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+ fi
+ PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+ done
+ AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+# Specify one or more source headers. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+ fi
+ PKG_HEADERS="$PKG_HEADERS $i"
+ done
+ AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+# Specify one or more include dirs. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+ vars="$@"
+ for i in $vars; do
+ PKG_INCLUDES="$PKG_INCLUDES $i"
+ done
+ AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+# Specify one or more libraries. Users should check for
+# the right platform before adding to their list. For Windows,
+# libraries provided in "foo.lib" format will be converted to
+# "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+ vars="$@"
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ case $i in
+ *.lib)
+ # Convert foo.lib to -lfoo for GCC
+ i=-l`echo "$i" | sed -e 's/\.[[^.]]*$//' -e 's/\.lib.*//'`
+ ;;
+ esac
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+ AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+# Specify one or more CFLAGS. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+ PKG_CFLAGS="$PKG_CFLAGS $@"
+ AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CLEANFILES --
+#
+# Specify one or more CLEANFILES.
+#
+# Arguments:
+# one or more file names to clean target
+#
+# Results:
+#
+# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CLEANFILES], [
+ CLEANFILES="$CLEANFILES $@"
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+# Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# If --prefix or --exec-prefix was not specified, $prefix and
+# $exec_prefix will be set to the values given to Tcl when it was
+# configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+ if test "${prefix}" = "NONE"; then
+ prefix_default=yes
+ if test x"${TCL_PREFIX}" != x; then
+ AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+ prefix=${TCL_PREFIX}
+ else
+ AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+ prefix=/usr/local
+ fi
+ fi
+ if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+ -o x"${exec_prefix_default}" = x"yes" ; then
+ if test x"${TCL_EXEC_PREFIX}" != x; then
+ AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+ exec_prefix=${TCL_EXEC_PREFIX}
+ else
+ AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+ exec_prefix=$prefix
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+# Do compiler checks the way we want. This is just a replacement
+# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+ # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+ AC_PROG_CC
+ AC_PROG_CPP
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL}'
+ INSTALL_SCRIPT='${INSTALL}'
+ INSTALL_LIBRARY='${INSTALL_DATA}'
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+
+ #--------------------------------------------------------------------
+ # Checks to see if the make program sets the $MAKE variable.
+ #--------------------------------------------------------------------
+
+ AC_PROG_MAKE_SET
+
+ #--------------------------------------------------------------------
+ # Find ranlib
+ #--------------------------------------------------------------------
+
+ AC_CHECK_TOOL(RANLIB, ranlib)
+
+ #--------------------------------------------------------------------
+ # Determines the correct binary file extension (.o, .obj, .exe etc.)
+ #--------------------------------------------------------------------
+
+ AC_OBJEXT
+ AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+# Do compiler checks that use the compiler. This must go after
+# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+ AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+ #------------------------------------------------------------------------
+ # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+ # It makes compiling go faster. (This is only a performance feature.)
+ #------------------------------------------------------------------------
+
+ if test -z "$no_pipe" -a -n "$GCC"; then
+ AC_CACHE_CHECK([if the compiler understands -pipe],
+ tcl_cv_cc_pipe, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+ AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+ CFLAGS=$hold_cflags])
+ if test $tcl_cv_cc_pipe = yes; then
+ CFLAGS="$CFLAGS -pipe"
+ fi
+ fi
+
+ #--------------------------------------------------------------------
+ # Common compiler flag setup
+ #--------------------------------------------------------------------
+
+ AC_C_BIGENDIAN
+ if test "${TEA_PLATFORM}" = "unix" ; then
+ TEA_TCL_LINK_LIBS
+ TEA_MISSING_POSIX_HEADERS
+ # Let the user call this, because if it triggers, they will
+ # need a compat/strtod.c that is correct. Users can also
+ # use Tcl_GetDouble(FromObj) instead.
+ #TEA_BUGGY_STRTOD
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+# Generate a line that can be used to build a shared/unshared library
+# in a platform independent manner.
+#
+# Arguments:
+# none
+#
+# Requires:
+#
+# Results:
+#
+# Defines the following vars:
+# CFLAGS - Done late here to note disturb other AC macros
+# MAKE_LIB - Command to execute to build the Tcl library;
+# differs depending on whether or not Tcl is being
+# compiled as a shared library.
+# MAKE_SHARED_LIB Makefile rule for building a shared library
+# MAKE_STATIC_LIB Makefile rule for building a static library
+# MAKE_STUB_LIB Makefile rule for building a stub library
+# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
+# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
+#
+# PRACTCL_TOOLSET What toolset is in use (gcc or msvc)
+# PRACTCL_SHARED_LIB Template rule for building a shared library
+# PRACTCL_STATIC_LIB Template rule for building a static library
+# PRACTCL_STUB_LIB Template rule for building a stub library
+# PRACTCL_VC_MANIFEST_EMBED_DLL Template rule for embedded VC manifest in DLL
+# PRACTCL_VC_MANIFEST_EMBED_EXE Template rule for embedded VC manifest in EXE
+# PRACTCL_NAME_LIBRARY Template rule for naming libraries
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+ PRACTCL_TOOLSET="gcc"
+ PRACTCL_VC_MANIFEST_EMBED_DLL=:
+ PRACTCL_VC_MANIFEST_EMBED_EXE=:
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+ PRACTCL_TOOLSET="msvc"
+ PRACTCL_STATIC_LIB="%STLIB_LD% -out:%OUTFILE% %LIBRARY_OBJECTS%"
+ PRACTCL_SHARED_LIB="%SHLIB_LD% %SHLIB_LD_LIBS% %LDFLAGS_DEFAULT% -out:%OUTFILE% %LIBRARY_OBJECTS%"
+ MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+ AC_EGREP_CPP([manifest needed], [
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+ ], [
+ # Could do a CHECK_PROG for mt, but should always be with MSVC8+
+ PRACTCL_VC_MANIFEST_EMBED_DLL="mt.exe -nologo -manifest %OUTFILE%.manifest -outputresource:%OUTFILE%\;2"
+ PRACTCL_VC_MANIFEST_EMBED_EXE="mt.exe -nologo -manifest %OUTFILE%.manifest -outputresource:%OUTFILE%\;1"
+ VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi"
+ VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi"
+ MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
+ TEA_ADD_CLEANFILES([*.manifest])
+ ])
+ PRACTCL_STUB_LIB="%STLIB_LD% -nodefaultlib -out:%OUTFILE% %LIBRARY_OBJECTS%"
+ MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@ \$(PKG_STUB_OBJECTS)"
+ else
+ MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
+ MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
+
+ PRACTCL_STATIC_LIB="%STLIB_LD% %OUTFILE% %LIBRARY_OBJECTS%"
+ PRACTCL_SHARED_LIB="%SHLIB_LD% -o %OUTFILE% %LIBRARY_OBJECTS% %SHLIB_LD_LIBS%"
+ PRACTCL_STUB_LIB="%STLIB_LD% %OUTFILE% %LIBRARY_OBJECTS%"
+ fi
+
+ if test "${SHARED_BUILD}" = "1" ; then
+ MAKE_LIB="${MAKE_SHARED_LIB} "
+ else
+ MAKE_LIB="${MAKE_STATIC_LIB} "
+ fi
+
+ #--------------------------------------------------------------------
+ # Shared libraries and static libraries have different names.
+ # Use the double eval to make sure any variables in the suffix is
+ # substituted. (@@@ Might not be necessary anymore)
+ #--------------------------------------------------------------------
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ PRACTCL_NAME_LIBRARY="%LIBRARY_PREFIX%%LIBRARY_NAME%%LIBRARY_VERSION_NODOTS%"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # We force the unresolved linking of symbols that are really in
+ # the private libraries of Tcl and Tk.
+ if test x"${TK_BIN_DIR}" != x ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
+ fi
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
+ if test "$GCC" = "yes"; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
+ fi
+ eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+ else
+ eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+ if test "$GCC" = "yes"; then
+ PKG_LIB_FILE=lib${PKG_LIB_FILE}
+ fi
+ fi
+ # Some packages build their own stubs libraries
+ eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+ if test "$GCC" = "yes"; then
+ PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
+ fi
+ # These aren't needed on Windows (either MSVC or gcc)
+ RANLIB=:
+ RANLIB_STUB=:
+ else
+ PRACTCL_NAME_LIBRARY="lib%LIBRARY_PREFIX%%LIBRARY_NAME%%LIBRARY_VERSION%"
+ RANLIB_STUB="${RANLIB}"
+ if test "${SHARED_BUILD}" = "1" ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
+ if test x"${TK_BIN_DIR}" != x ; then
+ SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
+ fi
+ eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
+ RANLIB=:
+ else
+ eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+ fi
+ # Some packages build their own stubs libraries
+ eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+ fi
+
+ # Store the raw CFLAGS before we add the trimmings
+ PRACTCL_CFLAGS=${CFLAGS}
+ # These are escaped so that only CFLAGS is picked up at configure time.
+ # The other values will be substituted at make time.
+ CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
+ if test "${SHARED_BUILD}" = "1" ; then
+ CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
+ fi
+
+ AC_SUBST(MAKE_LIB)
+ AC_SUBST(MAKE_SHARED_LIB)
+ AC_SUBST(MAKE_STATIC_LIB)
+ AC_SUBST(MAKE_STUB_LIB)
+ AC_SUBST(RANLIB_STUB)
+ AC_SUBST(VC_MANIFEST_EMBED_DLL)
+ AC_SUBST(VC_MANIFEST_EMBED_EXE)
+ AC_SUBST(PRACTCL_CFLAGS)
+ AC_SUBST(PRACTCL_TOOLSET)
+ AC_SUBST(PRACTCL_SHARED_LIB)
+ AC_SUBST(PRACTCL_STATIC_LIB)
+ AC_SUBST(PRACTCL_STUB_LIB)
+ AC_SUBST(PRACTCL_VC_MANIFEST_EMBED_DLL)
+ AC_SUBST(PRACTCL_VC_MANIFEST_EMBED_EXE)
+ AC_SUBST(PRACTCL_NAME_LIBRARY)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+# Compute the name of an existing object library located in libdir
+# from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+# basename The base name of the library without version
+# numbers, extensions, or "lib" prefixes.
+# extra_dir Extra directory in which to search for the
+# library. This location is used first, then
+# $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+# TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+# Defines the following vars:
+# ${basename}_LIB_NAME The computed library name.
+# ${basename}_LIB_SPEC The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+ AC_MSG_CHECKING([for $1 library])
+
+ # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+ tea_lib_name_dir="${exec_prefix}/lib"
+
+ # Or in a user-specified location.
+
+ if test x"$2" != x ; then
+ tea_extra_lib_dir=$2
+ else
+ tea_extra_lib_dir=NONE
+ fi
+
+ for i in \
+ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+ if test -f "$i" ; then
+ tea_lib_name_dir=`dirname $i`
+ $1_LIB_NAME=`basename $i`
+ $1_LIB_PATH_NAME=$i
+ break
+ fi
+ done
+
+ if test "${TEA_PLATFORM}" = "windows"; then
+ $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+ else
+ # Strip off the leading "lib" and trailing ".a" or ".so"
+
+ tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+ $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+ fi
+
+ if test "x${$1_LIB_NAME}" = x ; then
+ AC_MSG_ERROR([not found])
+ else
+ AC_MSG_RESULT([${$1_LIB_SPEC}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+# Locate the private Tcl include files
+#
+# Arguments:
+#
+# Requires:
+# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_TOP_DIR_NATIVE
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+ AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+ AC_MSG_CHECKING([for Tcl private include files])
+
+ TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+ TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+ # Check to see if tcl<Plat>Port.h isn't already with the public headers
+ # Don't look for tclInt.h because that resides with tcl.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+ else
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TCL_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -d "${TCL_BIN_DIR}/Headers" -a \
+ -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+ TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+ else
+ TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TCL_INCLUDES}"
+ else
+ if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+ fi
+ result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+ AC_SUBST(TCL_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+# Locate the installed public Tcl header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tclinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+ AC_MSG_CHECKING([for Tcl public headers])
+
+ AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tclh, [
+ # Use the value from --with-tclinclude, if it was given
+
+ if test x"${with_tclinclude}" != x ; then
+ if test -f "${with_tclinclude}/tcl.h" ; then
+ ac_cv_c_tclh=${with_tclinclude}
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers directory
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tcl is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TCL_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tcl.h" ; then
+ ac_cv_c_tclh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tclh}" = x ; then
+ AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tclh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+ TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+# Locate the private Tk include files
+#
+# Arguments:
+#
+# Requires:
+# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+ AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+ AC_MSG_CHECKING([for Tk private include files])
+
+ TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+ TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+ # Check to see if tk<Plat>Port.h isn't already with the public headers
+ # Don't look for tkInt.h because that resides with tk.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tkh}/tkWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+ TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+ else
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TK_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+ # Detect and add ttk subdir
+ if test -d "${TK_SRC_DIR}/generic/ttk"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+ fi
+ case ${PRACTCL_WINDOWINGSYSTEM} in
+ cocoa)
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+ ;;
+ hitheme)
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+ ;;
+ sdl)
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+ ;;
+ x11)
+ ;;
+ *)
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+ ;;
+ esac
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -d "${TK_BIN_DIR}/Headers" -a \
+ -d "${TK_BIN_DIR}/PrivateHeaders"; then
+ TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+ else
+ TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TK_INCLUDES}"
+ else
+ if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+ fi
+ result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TK_TOP_DIR_NATIVE)
+ AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+ AC_SUBST(TK_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+# Locate the installed public Tk header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tkinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+ AC_MSG_CHECKING([for Tk public headers])
+
+ AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tkh, [
+ # Use the value from --with-tkinclude, if it was given
+
+ if test x"${with_tkinclude}" != x ; then
+ if test -f "${with_tkinclude}/tk.h" ; then
+ ac_cv_c_tkh=${with_tkinclude}
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers directory.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tk is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tk's --prefix location,
+ # relative to directory of tkConfig.sh, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TK_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tk.h" ; then
+ ac_cv_c_tkh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tkh}" = x ; then
+ AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tkh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+ TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TK_INCLUDES)
+
+ if test "${PRACTCL_WINDOWINGSYSTEM}" != "x11"; then
+ # On Windows and Aqua, we need the X compat headers
+ AC_MSG_CHECKING([for X11 header files])
+ if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+ INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+ TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+ AC_SUBST(TK_XINCLUDES)
+ fi
+ AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+# Locate the ${1}Config.sh file and perform a sanity check on
+# the ${1} compile flags. These are used by packages like
+# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-$1=...
+#
+# Defines the following vars:
+# $1_BIN_DIR Full path to the directory containing
+# the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+ #
+ # Ok, lets find the $1 configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-$1
+ #
+
+ if test x"${no_$1}" = x ; then
+ # we reset no_$1 in case something fails here
+ no_$1=true
+ AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+ AC_MSG_CHECKING([for $1 configuration])
+ AC_CACHE_VAL(ac_cv_c_$1config,[
+
+ # First check to see if --with-$1 was specified.
+ if test x"${with_$1config}" != x ; then
+ case ${with_$1config} in
+ */$1Config.sh )
+ if test -f ${with_$1config}; then
+ AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+ with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+ fi;;
+ esac
+ if test -f "${with_$1config}/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+ else
+ AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+ fi
+ fi
+
+ # then check for a private $1 installation
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in \
+ ../$1 \
+ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../$1 \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../../$1 \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../$1 \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ if test -f "$i/unix/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_$1config}" = x ; then
+ $1_BIN_DIR="# no $1 configs found"
+ AC_MSG_WARN([Cannot find $1 configuration definitions])
+ exit 0
+ else
+ no_$1=
+ $1_BIN_DIR=${ac_cv_c_$1config}
+ AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+# Load the $1Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# $1_SRC_DIR
+# $1_LIB_FILE
+# $1_LIB_SPEC
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+ if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${$1_BIN_DIR}/$1Config.sh"
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+
+ #
+ # If the $1_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable $1_LIB_SPEC will be set to the value
+ # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+ # instead of $1_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ #
+
+ if test -f "${$1_BIN_DIR}/Makefile" ; then
+ AC_MSG_WARN([Found Makefile - using build library specs for $1])
+ $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+ $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+ $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+ $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
+ $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
+ fi
+
+ AC_SUBST($1_VERSION)
+ AC_SUBST($1_BIN_DIR)
+ AC_SUBST($1_SRC_DIR)
+
+ AC_SUBST($1_LIB_FILE)
+ AC_SUBST($1_LIB_SPEC)
+
+ AC_SUBST($1_STUB_LIB_FILE)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ # Allow the caller to prevent this auto-check by specifying any 2nd arg
+ AS_IF([test "x$2" = x], [
+ # Check both upper and lower-case variants
+ # If a dev wanted non-stubs libs, this function could take an option
+ # to not use _STUB in the paths below
+ AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
+ [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
+ [TEA_LOAD_CONFIG_LIB($1_STUB)])
+ ])
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG_LIB --
+#
+# Helper function to load correct library from another extension's
+# ${PACKAGE}Config.sh.
+#
+# Results:
+# Adds to LIBS the appropriate extension library
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
+ AC_MSG_CHECKING([For $1 library for LIBS])
+ # This simplifies the use of stub libraries by automatically adding
+ # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
+ # but this is called before CONFIG_CFLAGS. More importantly, this adds
+ # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
+ if test "x${$1_LIB_SPEC}" != "x" ; then
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
+ TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
+ AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
+ else
+ TEA_ADD_LIBS([${$1_LIB_SPEC}])
+ AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
+ fi
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_EXPORT_CONFIG --
+#
+# Define the data to insert into the ${PACKAGE}Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1
+#
+# Results:
+# Substitutes the following vars:
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_EXPORT_CONFIG], [
+ #--------------------------------------------------------------------
+ # These are for $1Config.sh
+ #--------------------------------------------------------------------
+
+ # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
+ eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
+ if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
+ else
+ eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ fi
+ $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
+ $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
+ $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
+ $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
+
+ AC_SUBST($1_BUILD_LIB_SPEC)
+ AC_SUBST($1_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_PATH)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ AC_SUBST(MAJOR_VERSION)
+ AC_SUBST(MINOR_VERSION)
+ AC_SUBST(PATCHLEVEL)
+])
+
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+# Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-celib=...
+#
+# Defines the following vars:
+# CELIB_DIR Full path to the directory containing
+# the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-celib
+
+ if test x"${no_celib}" = x ; then
+ # we reset no_celib in case something fails here
+ no_celib=true
+ AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
+ AC_MSG_CHECKING([for Windows/CE celib directory])
+ AC_CACHE_VAL(ac_cv_c_celibconfig,[
+ # First check to see if --with-celibconfig was specified.
+ if test x"${with_celibconfig}" != x ; then
+ if test -d "${with_celibconfig}/inc" ; then
+ ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+ fi
+ fi
+
+ # then check for a celib library
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ for i in \
+ ../celib-palm-3.0 \
+ ../celib \
+ ../../celib-palm-3.0 \
+ ../../celib \
+ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../celib-palm-3.0 \
+ ${srcdir}/../celib \
+ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -d "$i/inc" ; then
+ ac_cv_c_celibconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ AC_MSG_ERROR([Cannot find celib support library directory])
+ else
+ no_celib=
+ CELIB_DIR=${ac_cv_c_celibconfig}
+ CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+ AC_MSG_RESULT([found $CELIB_DIR])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_TEAPOT
+#
+# Try to determine the canonical name for this package's binary
+# target
+#
+# Arguments:
+# none
+AC_DEFUN([TEA_CONFIG_TEAPOT], [
+ AC_REQUIRE([TEA_INIT])
+ AC_REQUIRE([TEA_CONFIG_SYSTEM])
+ TEACUP_OS=$system
+ TEACUP_ARCH="unknown"
+ TEACUP_TOOLSET="gcc"
+ TEACUP_PROFILE="unknown"
+ arch="unknown"
+ case ${host_alias} in
+ *mingw32*)
+ arch="ix86"
+ TEACUP_PROFILE="win32-ix86"
+ ;;
+ *mingw64*)
+ arch="x86_64"
+ TEACUP_PROFILE="win32-x86_64"
+ ;;
+ esac
+ if test "${arch}" = "unknown" ; then
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ if test "$GCC" = "yes" ; then
+ TEACUP_TOOLSET="gcc"
+ else
+ TEACUP_TOOLSET="msvc"
+ fi
+ if test "$do64bit" != "no" ; then
+ case "$do64bit" in
+ amd64|x64|yes)
+ arch="x86_64"
+ TEACUP_PROFILE="win32-x86_64"
+ ;;
+ ia64)
+ arch="ia64"
+ TEACUP_PROFILE="win32-ia64"
+ ;;
+ esac
+ else
+ arch="ix86"
+ TEACUP_PROFILE="win32-ix86"
+ fi
+ else
+ case $system in
+ Linux*)
+ TEACUP_OS="linux"
+ arch=`uname -m`
+ TEACUP_PROFILE="linux-glibc2.3-$arch"
+ ;;
+ GNU*)
+ TEACUP_OS="gnu"
+ arch=`uname -m`
+ ;;
+ NetBSD-Debian)
+ TEACUP_OS="netbsd-debian"
+ arch=`uname -m`
+ ;;
+ OpenBSD-*)
+ TEACUP_OS="openbsd"
+ arch=`arch -s`
+ ;;
+ Darwin*)
+ TEACUP_OS="macosx"
+ TEACUP_PROFILE="macosx-universal"
+ arch=`uname -m`
+ if test $arch = "x86_64"; then
+ TEACUP_PROFILE="macosx10.5-i386-x86_84"
+ fi
+ ;;
+ OpenBSD*)
+ TEACUP_OS="openbsd"
+ arch=`arch -s`
+ ;;
+ esac
+ fi
+ fi
+ TEACUP_ARCH=$arch
+ if test "$TEACUP_PROFILE" = "unknown"; then
+ if test $arch = "unknown"; then
+ arch=`uname -m`
+ fi
+ case $arch in
+ i*86)
+ arch="ix86"
+ ;;
+ amd64)
+ arch="x86_64"
+ ;;
+ esac
+ TEACUP_PROFILE="$TEACUP_OS-$arch"
+ fi
+ TEA_SYSTEM=$system
+ AC_SUBST(TEA_SYSTEM)
+ AC_SUBST(TEA_PLATFORM)
+ AC_SUBST(TEA_WINDOWINGSYSTEM)
+ AC_SUBST(TEACUP_OS)
+ AC_SUBST(TEACUP_ARCH)
+ AC_SUBST(TEACUP_TOOLSET)
+ AC_SUBST(TEACUP_PROFILE)
+])
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/TclMagick/win/TclMagick.dsp b/TclMagick/win/TclMagick.dsp
new file mode 100644
index 0000000..2a7456b
--- /dev/null
+++ b/TclMagick/win/TclMagick.dsp
@@ -0,0 +1,120 @@
+# Microsoft Developer Studio Project File - Name="TclMagick" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=TCLMAGICK - WIN32 DEBUG
+!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "TclMagick.mak".
+!MESSAGE
+!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "TclMagick.mak" CFG="TCLMAGICK - WIN32 DEBUG"
+!MESSAGE
+!MESSAGE Fr die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "TclMagick - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "TclMagick - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "TclMagick"
+# PROP Scc_LocalPath "."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "TclMagick - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCLMAGICK_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "c:\tcl\include" /I "c:\opt\GraphicsMagick\include" /D "NDEBUG" /D "_USRDLL" /D VERSION=\"0.44\" /D "TCLMAGICK_EXPORTS" /D "USE_TCL_STUBS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 msvcrt.lib tclstub84.lib CORE_RL_magick_.lib CORE_RL_wand_.lib kernel32.lib /nologo /dll /incremental:yes /machine:I386 /nodefaultlib /libpath:"c:\tcl\lib" /libpath:"c:\opt\GraphicsMagick\lib"
+
+!ELSEIF "$(CFG)" == "TclMagick - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TCLMAGICK_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MD /W3 /Gm /GX /Zi /Od /I "c:\tcl\include" /I "c:\opt\GraphicsMagick\include" /D "_LIB" /D "NeedFunctionPrototypes" /D "_DEBUG" /D VERSION=\"0.44\" /D "TCLMAGICK_EXPORTS" /D "USE_TCL_STUBS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 msvcrt.lib tclstub84.lib CORE_RL_magick_.lib CORE_RL_wand_.lib kernel32.lib /nologo /dll /incremental:no /debug /machine:I386 /nodefaultlib /pdbtype:sept /libpath:"c:\tcl\lib" /libpath:"c:\opt\GraphicsMagick\lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "TclMagick - Win32 Release"
+# Name "TclMagick - Win32 Debug"
+# Begin Group "Quellcodedateien"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\generic\TclMagick.c
+# End Source File
+# End Group
+# Begin Group "Header-Dateien"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\generic\TclMagick.h
+# End Source File
+# End Group
+# Begin Group "Ressourcendateien"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Group "Dokumentation"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\ChangeLog
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/TclMagick/win/TclMagick.dsw b/TclMagick/win/TclMagick.dsw
new file mode 100644
index 0000000..4ecc9bd
--- /dev/null
+++ b/TclMagick/win/TclMagick.dsw
@@ -0,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELSCHT WERDEN!
+
+###############################################################################
+
+Project: "TclMagick"=.\TclMagick.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "TkMagick"=.\TkMagick.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/TclMagick/win/TkMagick.dsp b/TclMagick/win/TkMagick.dsp
new file mode 100644
index 0000000..28e88ce
--- /dev/null
+++ b/TclMagick/win/TkMagick.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="TkMagick" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=TkMagick - Win32 Debug
+!MESSAGE Dies ist kein gltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fhren Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "TkMagick.mak".
+!MESSAGE
+!MESSAGE Sie knnen beim Ausfhren von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "TkMagick.mak" CFG="TkMagick - Win32 Debug"
+!MESSAGE
+!MESSAGE Fr die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "TkMagick - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "TkMagick - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "TkMagick - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TKMAGICK_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "c:\tcl\include" /I "c:\opt\GraphicsMagick\include" /D "NDEBUG" /D VERSION=\"0.44\" /D "USE_TCL_STUBS" /D "USE_TK_STUBS" /D "TKMAGICK_EXPORTS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 msvcrt.lib tkstub84.lib tclstub84.lib CORE_RL_magick_.lib CORE_RL_wand_.lib kernel32.lib /nologo /dll /machine:I386 /nodefaultlib /libpath:"c:\tcl\lib" /libpath:"c:\opt\GraphicsMagick\lib"
+
+!ELSEIF "$(CFG)" == "TkMagick - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "TkMagick___Win32_Debug"
+# PROP BASE Intermediate_Dir "TkMagick___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TKMAGICK_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "c:\tcl\include" /I "c:\opt\GraphicsMagick\include" /D "_DEBUG" /D VERSION=\"0.44\" /D "USE_TCL_STUBS" /D "USE_TK_STUBS" /D "TKMAGICK_EXPORTS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x407 /d "_DEBUG"
+# ADD RSC /l 0x407 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 msvcrt.lib tkstub84.lib tclstub84.lib CORE_RL_magick_.lib CORE_RL_wand_.lib kernel32.lib /nologo /dll /debug /machine:I386 /nodefaultlib /pdbtype:sept /libpath:"c:\tcl\lib" /libpath:"c:\opt\GraphicsMagick\lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "TkMagick - Win32 Release"
+# Name "TkMagick - Win32 Debug"
+# Begin Group "Quellcodedateien"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\generic\TkMagick.c
+# End Source File
+# End Group
+# Begin Group "Header-Dateien"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Ressourcendateien"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\Debug\TclMagick.lib
+# End Source File
+# End Target
+# End Project
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..d169320
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,708 @@
+dnl @synopsis AC_CHECK_CC_OPT(flag, cachevarname)
+dnl
+dnl AC_CHECK_CC_OPT(-fvomit-frame,vomitframe)
+dnl would show a message as like
+dnl "checking wether gcc accepts -fvomit-frame ... no"
+dnl and sets the shell-variable $vomitframe to either "-fvomit-frame"
+dnl or (in this case) just a simple "". In many cases you would then call
+dnl AC_SUBST(_fvomit_frame_,$vomitframe) to create a substitution that
+dnl could be fed as "CFLAGS = @_funsigned_char_@ @_fvomit_frame_@
+dnl
+dnl in consequence this function is much more general than their
+dnl specific counterparts like ac_cxx_rtti.m4 that will test for
+dnl -fno-rtti -fno-exceptions
+dnl
+dml @author Guido Draheim <guidod@gmx.de>
+
+AC_DEFUN([AC_CHECK_CC_OPT],
+[AC_CACHE_CHECK(whether ${CC-cc} accepts [$1], [$2],
+[AC_SUBST($2)
+echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -c $1 conftest.c 2>&1`"; then
+ $2="$1"
+else
+ $2=""
+fi
+rm -f conftest*
+])])
+
+dnl @synopsis AC_C_LONG_LONG
+dnl
+dnl Provides a test for the existance of the long long int type and
+dnl defines HAVE_LONG_LONG if it is found.
+dnl
+dnl @author Caolan McNamara <caolan@skynet.ie>
+dnl
+AC_DEFUN([AC_C_LONG_LONG],
+[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long,
+[if test "$GCC" = yes; then
+ ac_cv_c_long_long=yes
+ else
+ AC_TRY_COMPILE(,[long long int i;],
+ ac_cv_c_long_long=yes,
+ ac_cv_c_long_long=no)
+ fi])
+ if test $ac_cv_c_long_long = yes; then
+ AC_DEFINE(HAVE_LONG_LONG)
+ fi
+])
+
+# RSSH_CHECK_SUNPROC_CC([ACTION-IF-YES], [ACTION-IF-NOT])
+# ------------------------------------------------------
+# check : are we using SUN C++ compiler.
+# Corresponding cache value: rssh_cv_check_sunpro_cc is set to yes or no
+#
+#@author Ruslan Shevchenko <Ruslan@Shevchenko.Kiev.UA>, 1998, 2000
+#@version $Id$
+#
+# RSSH_CHECK_SUNPRO_CC([ACTION-IF-YES],[ACTION-IF-NOT])
+#
+AC_DEFUN([RSSH_CHECK_SUNPRO_CC],
+[AC_CACHE_CHECK([whether using Sun C++ compiler],
+ [rssh_cv_check_sunpro_cc],
+
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([],
+[#ifndef __SUNPRO_CC
+# include "error: this is not Sun C++ Compiler."
+#endif
+],
+ rssh_cv_check_sunpro_cc=yes,
+ rssh_cv_check_sunpro_cc=no)
+AC_LANG_RESTORE])
+if test ${rssh_cv_check_sunpro_cc} = yes
+then
+ $2
+ :
+else
+ $3
+ :
+fi
+])# RSSH_CHECK_SUNPROC_CC
+
+# RSSH_CHECK_SUNPROC_C([ACTION-IF-YES], [ACTION-IF-NOT])
+# ------------------------------------------------------
+# check : are we using SUN C compiler.
+# Corresponding cache value: rssh_cv_check_sunpro_c is set to yes or no
+#
+#@author Ruslan Shevchenko <Ruslan@Shevchenko.Kiev.UA>, 1998, 2000
+#@version $Id$
+#
+# RSSH_CHECK_SUNPRO_C([ACTION-IF-YES],[ACTION-IF-NOT])
+#
+AC_DEFUN([RSSH_CHECK_SUNPRO_C],
+[AC_CACHE_CHECK([whether using Sun C compiler],
+ [rssh_cv_check_sunpro_c],
+
+[AC_LANG_SAVE
+ AC_LANG_C
+ AC_TRY_COMPILE([],
+[#ifndef __SUNPRO_C
+# include "error: this is not Sun C Compiler."
+#endif
+],
+ rssh_cv_check_sunpro_c=yes,
+ rssh_cv_check_sunpro_c=no)
+AC_LANG_RESTORE])
+if test ${rssh_cv_check_sunpro_c} = yes
+then
+ $2
+ :
+else
+ $3
+ :
+fi
+])# RSSH_CHECK_SUNPRO_C
+
+
+dnl @synopsis AC_CXX_BOOL
+dnl
+dnl If the compiler recognizes bool as a separate built-in type,
+dnl define HAVE_BOOL. Note that a typedef is not a separate
+dnl type since you cannot overload a function such that it accepts either
+dnl the basic type or the typedef.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_BOOL],
+[AC_CACHE_CHECK(whether the compiler recognizes bool as a built-in type,
+ac_cv_cxx_bool,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([int f(int x){return 1;}
+int f(char x){return 1;}
+int f(bool x){return 1;}
+],[bool b = true; return f(b);],
+ ac_cv_cxx_bool=yes, ac_cv_cxx_bool=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_bool" = yes; then
+ AC_DEFINE(HAVE_BOOL,,[define if bool is a built-in type])
+fi
+])
+
+
+dnl @synopsis AC_CXX_CONST_CAST
+dnl
+dnl If the compiler supports const_cast<>, define HAVE_CONST_CAST.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_CONST_CAST],
+[AC_CACHE_CHECK(whether the compiler supports const_cast<>,
+ac_cv_cxx_const_cast,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE(,[int x = 0;
+const int& y = x;
+int& z = const_cast<int&>(y);
+return z;],
+ ac_cv_cxx_const_cast=yes, ac_cv_cxx_const_cast=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_const_cast" = yes; then
+ AC_DEFINE(HAVE_CONST_CAST,,[define if the compiler supports const_cast<>])
+fi
+])
+
+
+dnl @synopsis AC_CXX_DEFAULT_TEMPLATE_PARAMETERS
+dnl
+dnl If the compiler supports default template parameters,
+dnl define HAVE_DEFAULT_TEMPLATE_PARAMETERS.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_DEFAULT_TEMPLATE_PARAMETERS],
+[AC_CACHE_CHECK(whether the compiler supports default template parameters,
+ac_cv_cxx_default_template_parameters,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([template<class T = double, int N = 10> class A {public: int f() {return 0;}};
+],[A<float> a; return a.f();],
+ ac_cv_cxx_default_template_parameters=yes, ac_cv_cxx_default_template_parameters=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_default_template_parameters" = yes; then
+ AC_DEFINE(HAVE_DEFAULT_TEMPLATE_PARAMETERS,,
+ [define if the compiler supports default template parameters])
+fi
+rm -rf SunWS_cache
+])
+
+
+dnl @synopsis AC_CXX_EXCEPTIONS
+dnl
+dnl If the C++ compiler supports exceptions handling (try,
+dnl throw and catch), define HAVE_EXCEPTIONS.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_EXCEPTIONS],
+[AC_CACHE_CHECK(whether the compiler supports exceptions,
+ac_cv_cxx_exceptions,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE(,[try { throw 1; } catch (int i) { return i; }],
+ ac_cv_cxx_exceptions=yes, ac_cv_cxx_exceptions=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_exceptions" = yes; then
+ AC_DEFINE(HAVE_EXCEPTIONS,,[define if the compiler supports exceptions])
+fi
+])
+
+dnl @synopsis AC_CXX_EXPLICIT
+dnl
+dnl If the compiler can be asked to prevent using implicitly one argument
+dnl constructors as converting constructors with the explicit
+dnl keyword, define HAVE_EXPLICIT.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_EXPLICIT],
+[AC_CACHE_CHECK(whether the compiler supports the explicit keyword,
+ac_cv_cxx_explicit,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([class A{public:explicit A(double){}};],
+[double c = 5.0;A x(c);return 0;],
+ ac_cv_cxx_explicit=yes, ac_cv_cxx_explicit=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_explicit" = yes; then
+ AC_DEFINE(HAVE_EXPLICIT,,[define if the compiler supports the explicit keyword])
+fi
+])
+
+
+dnl @synopsis AC_CXX_HAVE_STD
+dnl
+dnl If the compiler supports ISO C++ standard library (i.e., can include the
+dnl files iostream, map, and iomanip), define HAVE_STD.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_HAVE_STD],
+[AC_CACHE_CHECK(whether the compiler supports ISO C++ standard library,
+ac_cv_cxx_have_std,
+[AC_REQUIRE([AC_CXX_NAMESPACES])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <iostream>
+#include <map>
+#include <iomanip>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif],[return 0;],
+ ac_cv_cxx_have_std=yes, ac_cv_cxx_have_std=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_std" = yes; then
+ AC_DEFINE(HAVE_STD,,[define if the compiler supports ISO C++ standard library])
+fi
+])
+
+
+dnl @synopsis AC_CXX_HAVE_STL
+dnl
+dnl If the compiler supports the Standard Template Library, define HAVE_STL.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_HAVE_STL],
+[AC_CACHE_CHECK(whether the compiler supports Standard Template Library,
+ac_cv_cxx_have_stl,
+[AC_REQUIRE([AC_CXX_NAMESPACES])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <list>
+#include <deque>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif],[list<int> x; x.push_back(5);
+list<int>::iterator iter = x.begin(); if (iter != x.end()) ++iter; return 0;],
+ ac_cv_cxx_have_stl=yes, ac_cv_cxx_have_stl=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_stl" = yes; then
+ AC_DEFINE(HAVE_STL,,[define if the compiler supports Standard Template Library])
+fi
+rm -rf SunWS_cache
+])
+
+dnl @synopsis AC_CXX_IOS_BINARY
+dnl
+dnl If the compiler supports ios::binary
+dnl
+dnl @author The Written Word, Inc.
+dnl
+AC_DEFUN([AC_CXX_IOS_BINARY],
+[AC_CACHE_CHECK(whether the compiler supports ios::binary,
+ac_cv_cxx_ios_binary,
+[AC_LANG_PUSH(C++)
+ AC_TRY_COMPILE([#include <fstream>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif],[
+ifstream in( "/dev/null", ios::binary );],
+ ac_cv_cxx_ios_binary=yes, ac_cv_cxx_ios_binary=no)
+ AC_LANG_POP(C++)
+])
+if test "$ac_cv_cxx_ios_binary" = no; then
+ AC_DEFINE(MISSING_STD_IOS_BINARY,,[define if the compiler lacks ios::binary])
+fi
+rm -rf SunWS_cache
+])
+
+dnl @synopsis AC_CXX_MEMBER_TEMPLATES_OUTSIDE_CLASS
+dnl
+dnl If the compiler supports member templates outside the class declaration,
+dnl define HAVE_MEMBER_TEMPLATES_OUTSIDE_CLASS.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_MEMBER_TEMPLATES_OUTSIDE_CLASS],
+[AC_CACHE_CHECK(whether the compiler supports member templates outside the class declaration,
+ac_cv_cxx_member_templates_outside_class,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+#template<class T, int N> class A
+{ public :
+ template<int N2> A<T,N> operator=(const A<T,N2>& z);
+};
+template<class T, int N> template<int N2>
+A<T,N> A<T,N>::operator=(const A<T,N2>& z){ return A<T,N>(); }],[
+A<double,4> x; A<double,7> y; x = y; return 0;],
+ ac_cv_cxx_member_templates_outside_class=yes, ac_cv_cxx_member_templates_outside_class=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_member_templates_outside_class" = yes; then
+ AC_DEFINE(HAVE_MEMBER_TEMPLATES_OUTSIDE_CLASS,,
+ [define if the compiler supports member templates outside the class declaration])
+fi
+rm -rf SunWS_cache
+])
+
+
+dnl @synopsis AC_CXX_MUTABLE
+dnl
+dnl If the compiler allows modifying class data members flagged with
+dnl the mutable keyword even in const objects (for example in the
+dnl body of a const member function), define HAVE_MUTABLE.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_MUTABLE],
+[AC_CACHE_CHECK(whether the compiler supports the mutable keyword,
+ac_cv_cxx_mutable,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([class A { mutable int i;
+ public:
+ int f (int n) const { i = n; return i; }
+ };
+],[A a; return a.f (1);],
+ ac_cv_cxx_mutable=yes, ac_cv_cxx_mutable=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_mutable" = yes; then
+ AC_DEFINE(HAVE_MUTABLE,,[define if the compiler supports the mutable keyword])
+fi
+])
+
+
+
+dnl @synopsis AC_CXX_NAMESPACES
+dnl
+dnl If the compiler can prevent names clashes using namespaces, define
+dnl HAVE_NAMESPACES.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_NAMESPACES],
+[AC_CACHE_CHECK(whether the compiler implements namespaces,
+ac_cv_cxx_namespaces,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}],
+ [using namespace Outer::Inner; return i;],
+ ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_namespaces" = yes; then
+ AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
+fi
+])
+
+
+dnl @synopsis AC_CXX_NEW_FOR_SCOPING
+dnl
+dnl If the compiler accepts the new for scoping rules (the scope of a
+dnl variable declared inside the parentheses is restricted to the
+dnl for-body), define HAVE_NEW_FOR_SCOPING.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_NEW_FOR_SCOPING],
+[AC_CACHE_CHECK(whether the compiler accepts the new for scoping rules,
+ac_cv_cxx_new_for_scoping,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE(,[ int z = 0;
+ for (int i = 0; i < 10; ++i)
+ z = z + i;
+ for (int i = 0; i < 10; ++i)
+ z = z - i;
+ return z;],
+ ac_cv_cxx_new_for_scoping=yes, ac_cv_cxx_new_for_scoping=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_new_for_scoping" = yes; then
+ AC_DEFINE(HAVE_NEW_FOR_SCOPING,,[define if the compiler accepts the new for scoping rules])
+fi
+])
+
+dnl @synopsis AC_CXX_STATIC_CAST
+dnl
+dnl If the compiler supports static_cast<>, define HAVE_STATIC_CAST.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_STATIC_CAST],
+[AC_CACHE_CHECK(whether the compiler supports static_cast<>,
+ac_cv_cxx_static_cast,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <typeinfo>
+class Base { public : Base () {} virtual void f () = 0; };
+class Derived : public Base { public : Derived () {} virtual void f () {} };
+int g (Derived&) { return 0; }],[
+Derived d; Base& b = d; Derived& s = static_cast<Derived&> (b); return g (s);],
+ ac_cv_cxx_static_cast=yes, ac_cv_cxx_static_cast=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_static_cast" = yes; then
+ AC_DEFINE(HAVE_STATIC_CAST,,
+ [define if the compiler supports static_cast<>])
+fi
+])
+
+
+dnl @synopsis AC_CXX_TEMPLATES
+dnl
+dnl If the compiler supports basic templates, define HAVE_TEMPLATES.
+dnl
+dnl @author Luc Maisonobe
+dnl
+AC_DEFUN([AC_CXX_TEMPLATES],
+[AC_CACHE_CHECK(whether the compiler supports basic templates,
+ac_cv_cxx_templates,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([template<class T> class A {public:A(){}};
+template<class T> void f(const A<T>& ){}],[
+A<double> d; A<int> i; f(d); f(i); return 0;],
+ ac_cv_cxx_templates=yes, ac_cv_cxx_templates=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_templates" = yes; then
+ AC_DEFINE(HAVE_TEMPLATES,,[define if the compiler supports basic templates])
+fi
+rm -rf SunWS_cache
+])
+
+#
+# Macro to test for pthread library
+# Written by Bob Friesenhahn based on test in ACX_PTHREAD
+# MAGICK_CHECK_PTHREAD_LIB(LIBRARY,
+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+AC_DEFUN([MAGICK_CHECK_PTHREAD_LIB], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+magick_pthread_lib_ok=no
+
+LIB=-l$1
+save_LIBS="$LIBS"
+LIBS="$LIBS $LIB"
+
+AC_MSG_CHECKING([for the pthreads library $LIB])
+AC_TRY_LINK([#include <pthread.h>],
+ [ pthread_t th;
+ pthread_join(th, 0);
+ pthread_attr_init(0);
+ pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0);
+ pthread_cleanup_pop(0); ],
+ [magick_pthread_lib_ok=yes])
+
+AC_MSG_RESULT(${magick_pthread_lib_ok})
+if test "$magick_pthread_lib_ok" = yes
+then
+ $2
+ :
+else
+ $3
+ :
+fi
+
+LIBS="$save_LIBS"
+
+AC_LANG_RESTORE
+])dnl MAGICK_CHECK_PTHREAD_LIB
+
+
+# GM_FUNC_MMAP_FILEIO
+# ------------
+AC_DEFUN([GM_FUNC_MMAP_FILEIO],
+[AC_CHECK_HEADERS(stdlib.h unistd.h)
+AC_CHECK_FUNCS(getpagesize)
+AC_CACHE_CHECK(for working mmap file i/o, gm_cv_func_mmap_fileio,
+[AC_RUN_IFELSE([AC_LANG_SOURCE([AC_INCLUDES_DEFAULT]
+[[/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/*
+ This test is derived from GNU Autoconf's similar macro.
+ The purpose of this test is to verify that files may be memory
+ mapped, and that memory mapping and file I/O are coherent.
+
+ The test creates a test file, memory maps the file, updates
+ the file using the memory map, and then reads the file using
+ file I/O to verify that the file contains the updates.
+*/
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !STDC_HEADERS && !HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#if !HAVE_GETPAGESIZE
+/* Assume that all systems that can run configure have sys/param.h. */
+# if !HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int
+main ()
+{
+ char *data = NULL, *data2 = NULL, *data3 = NULL;
+ int i, pagesize;
+ int fd = -1;
+ int exit_status = 0;
+
+ pagesize = getpagesize ();
+
+ /* First, make a file with some known garbage in it. */
+ data = (char *) malloc (pagesize);
+ if (!data)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand ();
+ umask (0);
+ fd = creat ("conftest.mmap", 0600);
+ if (fd < 0)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ if (write (fd, data, pagesize) != pagesize)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ close (fd);
+ fd = -1;
+
+ /* Mmap the file as read/write/shared and verify that we see the
+ same garbage. */
+ fd = open ("conftest.mmap", O_RDWR);
+ if (fd < 0)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ data2 = mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0L);
+ if (data2 == 0)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ {
+ exit_status = 1;
+ goto quit;
+ }
+
+ /* Finally, make sure that changes to the mapped area
+ percolate back to the file as seen by read(). */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = (char *) malloc (pagesize);
+ if (!data3)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ if (read (fd, data3, pagesize) != pagesize)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ for (i = 0; i < pagesize; ++i)
+ if (*(data2 + i) != *(data3 + i))
+ {
+ exit_status = 1;
+ goto quit;
+ }
+quit:
+ if (fd != -1)
+ close (fd);
+ if (data)
+ free (data);
+ if (data2)
+ (void) munmap (data2, pagesize);
+ if (data3)
+ free (data3);
+ exit (exit_status);
+}]])],
+ [gm_cv_func_mmap_fileio=yes],
+ [gm_cv_func_mmap_fileio=no],
+ [gm_cv_func_mmap_fileio=no])])
+if test $gm_cv_func_mmap_fileio = yes; then
+ AC_DEFINE(HAVE_MMAP_FILEIO, 1,
+ [Define to 1 if you have a `mmap' system call which handles coherent file I/O.])
+fi
+rm -f conftest.mmap
+])# GM_FUNC_MMAP_FILEIO
+
+dnl Available from the GNU Autoconf Macro Archive at:
+dnl http://www.gnu.org/software/ac-archive/htmldoc/ac_prog_perl_version.html
+dnl
+AC_DEFUN([AC_PROG_PERL_VERSION],[dnl
+# Make sure we have perl
+if test -z "$PERL"; then
+AC_CHECK_PROG(PERL,perl,perl)
+fi
+
+# Check if version of Perl is sufficient
+ac_perl_version="$1"
+
+if test "x$PERL" != "x"; then
+ AC_MSG_CHECKING(for perl version greater than or equal to $ac_perl_version)
+ # NB: It would be nice to log the error if there is one, but we cannot rely
+ # on autoconf internals
+ $PERL -e "use $ac_perl_version;" > /dev/null 2>&1
+ if test $? -ne 0; then
+ AC_MSG_RESULT(no);
+ $3
+ else
+ AC_MSG_RESULT(ok);
+ $2
+ fi
+else
+ AC_MSG_WARN(could not find perl)
+fi
+])dnl # AC_PROG_PERL_VERSION
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..90df929
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1294 @@
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
+
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.15'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.15], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.15])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/acx_pthread.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([acinclude.m4])
diff --git a/coders/Makefile.am b/coders/Makefile.am
new file mode 100644
index 0000000..66da577
--- /dev/null
+++ b/coders/Makefile.am
@@ -0,0 +1,865 @@
+# Copyright (C) 2004-2016 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building GraphicsMagick coder modules
+#
+#
+
+# Where coder modules get installed
+codersdir = $(MagickCoderModulesPath)
+
+if HasDPS
+MAGICK_DPS_MODULES = coders/dps.la
+MAGICK_DPS_SRCS = coders/dps.c
+endif
+
+if HasFPX
+MAGICK_FPX_MODULES = coders/fpx.la
+MAGICK_FPX_SRCS = coders/fpx.c
+endif
+
+if HasWINGDI32
+MAGICK_GDI32_MODULES = coders/clipboard.la coders/emf.la
+MAGICK_GDI32_SRCS = coders/clipboard.c coders/emf.c
+endif
+
+if HasJBIG
+MAGICK_JBIG_MODULES = coders/jbig.la
+MAGICK_JBIG_SRCS = coders/jbig.c
+endif
+
+if HasJPEG
+MAGICK_JPEG_MODULES = coders/jnx.la coders/jpeg.la
+MAGICK_JPEG_SRCS = coders/jnx.c coders/jpeg.c
+endif
+
+if HasJP2
+MAGICK_JP2_MODULES = coders/jp2.la
+MAGICK_JP2_SRCS = coders/jp2.c
+endif
+
+if HasPNG
+MAGICK_PNG_MODULES = coders/png.la
+MAGICK_PNG_SRCS = coders/png.c
+endif
+
+if HasTIFF
+MAGICK_TIFF_MODULES = coders/ept.la coders/tiff.la
+MAGICK_TIFF_SRCS = coders/ept.c coders/tiff.c
+endif
+
+if HasX11
+MAGICK_X11_CODER_MODULES = coders/x.la coders/xwd.la
+MAGICK_X11_CODER_SRCS = coders/x.c coders/xwd.c
+endif
+
+if HasWEBP
+MAGICK_WEBP_MODULES = coders/webp.la
+MAGICK_WEBP_SRCS = coders/webp.c
+endif
+
+if ENABLE_BROKEN_CODERS
+MAGICK_BROKEN_MODULES = coders/psd.la
+MAGICK_BROKEN_SRCS = coders/psd.c
+endif
+
+MAGICK_CODER_CPPFLAGS = \
+ $(MODULECOMMONCPPFLAGS) \
+ $(MODULE_EXTRA_CPPFLAGS)
+
+MAGICK_CODER_SRCS = \
+ $(MAGICK_PNG_SRCS) \
+ coders/art.c \
+ coders/avs.c \
+ coders/bmp.c \
+ coders/cals.c \
+ coders/caption.c \
+ coders/cineon.c \
+ coders/cmyk.c \
+ coders/cut.c \
+ coders/dcm.c \
+ coders/dcraw.c \
+ coders/dib.c \
+ coders/dpx.c \
+ coders/fax.c \
+ coders/fits.c \
+ coders/gif.c \
+ coders/gradient.c \
+ coders/gray.c \
+ coders/histogram.c \
+ coders/hrz.c \
+ coders/html.c \
+ coders/icon.c \
+ coders/identity.c \
+ coders/info.c \
+ coders/label.c \
+ coders/locale.c \
+ coders/logo.c \
+ coders/mac.c \
+ coders/map.c \
+ coders/mat.c \
+ coders/matte.c \
+ coders/meta.c \
+ coders/miff.c \
+ coders/mono.c \
+ coders/mpc.c \
+ coders/mpeg.c \
+ coders/mpr.c \
+ coders/msl.c \
+ coders/mtv.c \
+ coders/mvg.c \
+ coders/null.c \
+ coders/otb.c \
+ coders/palm.c \
+ coders/pcd.c \
+ coders/pcl.c \
+ coders/pcx.c \
+ coders/pdb.c \
+ coders/pdf.c \
+ coders/pict.c \
+ coders/pix.c \
+ coders/plasma.c \
+ coders/pnm.c \
+ coders/preview.c \
+ coders/ps.c \
+ coders/ps2.c \
+ coders/ps3.c \
+ coders/pwp.c \
+ coders/rgb.c \
+ coders/rla.c \
+ coders/rle.c \
+ coders/sct.c \
+ coders/sfw.c \
+ coders/sgi.c \
+ coders/stegano.c \
+ coders/sun.c \
+ coders/svg.c \
+ coders/tga.c \
+ coders/tile.c \
+ coders/tim.c \
+ coders/topol.c \
+ coders/ttf.c \
+ coders/txt.c \
+ coders/uil.c \
+ coders/url.c \
+ coders/uyvy.c \
+ coders/vicar.c \
+ coders/vid.c \
+ coders/viff.c \
+ coders/wbmp.c \
+ coders/wmf.c \
+ coders/wpg.c \
+ coders/xbm.c \
+ coders/xc.c \
+ coders/xcf.c \
+ coders/xpm.c \
+ coders/yuv.c \
+ $(MAGICK_BROKEN_SRCS) \
+ $(MAGICK_DPS_SRCS) \
+ $(MAGICK_GDI32_SRCS) \
+ $(MAGICK_FPX_SRCS) \
+ $(MAGICK_JBIG_SRCS) \
+ $(MAGICK_JPEG_SRCS) \
+ $(MAGICK_JP2_SRCS) \
+ $(MAGICK_TIFF_SRCS) \
+ $(MAGICK_X11_CODER_SRCS) \
+ $(MAGICK_WEBP_SRCS)
+
+if WITH_MODULES
+coders_LTLIBRARIES = \
+ coders/art.la \
+ coders/avs.la \
+ coders/bmp.la \
+ coders/cals.la \
+ coders/caption.la \
+ coders/cineon.la \
+ coders/cmyk.la \
+ coders/cut.la \
+ coders/dcm.la \
+ coders/dcraw.la \
+ coders/dib.la \
+ coders/dpx.la \
+ coders/fax.la \
+ coders/fits.la \
+ coders/gif.la \
+ coders/gradient.la \
+ coders/gray.la \
+ coders/histogram.la \
+ coders/hrz.la \
+ coders/html.la \
+ coders/icon.la \
+ coders/identity.la \
+ coders/info.la \
+ coders/label.la \
+ coders/locale.la \
+ coders/logo.la \
+ coders/mac.la \
+ coders/map.la \
+ coders/mat.la \
+ coders/matte.la \
+ coders/meta.la \
+ coders/miff.la \
+ coders/mono.la \
+ coders/mpc.la \
+ coders/mpeg.la \
+ coders/mpr.la \
+ coders/msl.la \
+ coders/mtv.la \
+ coders/mvg.la \
+ coders/null.la \
+ coders/otb.la \
+ coders/palm.la \
+ coders/pcd.la \
+ coders/pcl.la \
+ coders/pcx.la \
+ coders/pdb.la \
+ coders/pdf.la \
+ coders/pict.la \
+ coders/pix.la \
+ coders/plasma.la \
+ coders/pnm.la \
+ coders/preview.la \
+ coders/ps.la \
+ coders/ps2.la \
+ coders/ps3.la \
+ coders/pwp.la \
+ coders/rgb.la \
+ coders/rla.la \
+ coders/rle.la \
+ coders/sct.la \
+ coders/sfw.la \
+ coders/sgi.la \
+ coders/stegano.la \
+ coders/sun.la \
+ coders/svg.la \
+ coders/tga.la \
+ coders/tile.la \
+ coders/tim.la \
+ coders/topol.la \
+ coders/ttf.la \
+ coders/txt.la \
+ coders/uil.la \
+ coders/url.la \
+ coders/uyvy.la \
+ coders/vicar.la \
+ coders/vid.la \
+ coders/viff.la \
+ coders/wbmp.la \
+ coders/wmf.la \
+ coders/wpg.la \
+ coders/xbm.la \
+ coders/xc.la \
+ coders/xcf.la \
+ coders/xpm.la \
+ coders/yuv.la \
+ $(MAGICK_BROKEN_MODULES) \
+ $(MAGICK_DPS_MODULES) $(MAGICK_FPX_MODULES) $(MAGICK_GDI32_MODULES) \
+ $(MAGICK_JBIG_MODULES) $(MAGICK_JPEG_MODULES) $(MAGICK_JP2_MODULES) \
+ $(MAGICK_PNG_MODULES) $(MAGICK_TIFF_MODULES) $(MAGICK_X11_CODER_MODULES) \
+ $(MAGICK_WEBP_MODULES)
+else
+coders_LTLIBRARIES =
+endif # WITH_MODULES
+
+# ART coder module
+coders_art_la_SOURCES = coders/art.c
+coders_art_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_art_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_art_la_LIBADD = $(LIBMAGICK)
+
+# AVS coder module
+coders_avs_la_SOURCES = coders/avs.c
+coders_avs_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_avs_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_avs_la_LIBADD = $(LIBMAGICK)
+
+# BMP coder module
+coders_bmp_la_SOURCES = coders/bmp.c
+coders_bmp_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_bmp_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_bmp_la_LIBADD = $(LIBMAGICK)
+
+# CALS coder module
+coders_cals_la_SOURCES = coders/cals.c
+coders_cals_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_cals_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_cals_la_LIBADD = $(LIBMAGICK)
+
+# CAPTION coder module
+coders_caption_la_SOURCES = coders/caption.c
+coders_caption_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_caption_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_caption_la_LIBADD = $(LIBMAGICK)
+
+# CINEON coder module
+coders_cineon_la_SOURCES = coders/cineon.c
+coders_cineon_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_cineon_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_cineon_la_LIBADD = $(LIBMAGICK)
+
+# CLIPBOARD coder module
+coders_clipboard_la_SOURCES= coders/clipboard.c
+coders_clipboard_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_clipboard_la_LDFLAGS= $(MODULECOMMONFLAGS)
+coders_clipboard_la_LIBADD = $(LIBMAGICK) $(LIB_GDI32)
+
+# CMYK coder module
+coders_cmyk_la_SOURCES = coders/cmyk.c
+coders_cmyk_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_cmyk_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_cmyk_la_LIBADD = $(LIBMAGICK)
+
+# CUT coder module
+coders_cut_la_SOURCES = coders/cut.c
+coders_cut_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_cut_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_cut_la_LIBADD = $(LIBMAGICK)
+
+# DCM coder module
+coders_dcm_la_SOURCES = coders/dcm.c
+coders_dcm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dcm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dcm_la_LIBADD = $(LIBMAGICK)
+
+# DCRAW coder module
+coders_dcraw_la_SOURCES = coders/dcraw.c
+coders_dcraw_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dcraw_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dcraw_la_LIBADD = $(LIBMAGICK)
+
+# DIB coder module
+coders_dib_la_SOURCES = coders/dib.c
+coders_dib_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dib_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dib_la_LIBADD = $(LIBMAGICK)
+
+# DPS coder module
+coders_dps_la_SOURCES = coders/dps.c
+coders_dps_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dps_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dps_la_LIBADD = $(LIBMAGICK) $(LIB_DPS) $(LIB_XEXT) $(LIB_X11)
+
+# DPX coder module
+coders_dpx_la_SOURCES = coders/dpx.c
+coders_dpx_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_dpx_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_dpx_la_LIBADD = $(LIBMAGICK)
+
+# EMF coder module
+coders_emf_la_SOURCES = coders/emf.c
+coders_emf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_emf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_emf_la_LIBADD = $(LIBMAGICK) $(LIB_GDI32)
+
+# EPT coder module
+coders_ept_la_SOURCES = coders/ept.c
+coders_epd_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ept_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ept_la_LIBADD = $(LIBMAGICK) $(LIB_GS) $(LIB_MATH)
+
+# FAX coder module
+coders_fax_la_SOURCES = coders/fax.c
+coders_fax_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_fax_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_fax_la_LIBADD = $(LIBMAGICK)
+
+# FITS coder module
+coders_fits_la_SOURCES = coders/fits.c
+coders_fits_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_fits_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_fits_la_LIBADD = $(LIBMAGICK) $(LIB_MATH)
+
+# FPX coder module
+coders_fpx_la_SOURCES = coders/fpx.c
+coders_fpx_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_fpx_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_fpx_la_LIBADD = $(LIBMAGICK) $(LIB_FPX)
+
+# GIF coder module
+coders_gif_la_SOURCES = coders/gif.c
+coders_gif_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_gif_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_gif_la_LIBADD = $(LIBMAGICK)
+
+# GRAY coder module
+coders_gray_la_SOURCES = coders/gray.c
+coders_gray_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_gray_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_gray_la_LIBADD = $(LIBMAGICK)
+
+# GRADIENT coder module
+coders_gradient_la_SOURCES = coders/gradient.c
+coders_gradient_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_gradient_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_gradient_la_LIBADD = $(LIBMAGICK)
+
+# HISTOGRAM coder module
+coders_histogram_la_SOURCES = coders/histogram.c
+coders_histogram_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_histogram_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_histogram_la_LIBADD = $(LIBMAGICK)
+
+# HRZ coder module
+coders_hrz_la_SOURCES = coders/hrz.c
+coders_hrz_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_hrz_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_hrz_la_LIBADD = $(LIBMAGICK)
+
+# HTML coder module
+coders_html_la_SOURCES = coders/html.c
+coders_html_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_html_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_html_la_LIBADD = $(LIBMAGICK)
+
+# ICON coder module
+coders_icon_la_SOURCES = coders/icon.c
+coders_icon_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_icon_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_icon_la_LIBADD = $(LIBMAGICK)
+
+# Identity coder module
+coders_identity_la_SOURCES = coders/identity.c
+coders_identity_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_identity_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_identity_la_LIBADD = $(LIBMAGICK)
+
+# Info coder module
+coders_info_la_SOURCES = coders/info.c
+coders_info_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_info_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_info_la_LIBADD = $(LIBMAGICK)
+
+# JBIG coder module
+coders_jbig_la_SOURCES = coders/jbig.c
+coders_jbig_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_jbig_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_jbig_la_LIBADD = $(LIBMAGICK) $(LIB_JBIG)
+
+# JNX coder module
+coders_jnx_la_SOURCES = coders/jnx.c
+coders_jnx_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_jnx_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_jnx_la_LIBADD = $(LIBMAGICK) $(LIB_JPEG)
+
+# JPEG coder module
+coders_jpeg_la_SOURCES = coders/jpeg.c
+coders_jpeg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_jpeg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_jpeg_la_LIBADD = $(LIBMAGICK) $(LIB_JPEG)
+
+# JPEG 2000 coder module
+coders_jp2_la_SOURCES = coders/jp2.c
+coders_jp2_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_jp2_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_jp2_la_LIBADD = $(LIBMAGICK) $(LIB_JP2) $(LIB_JPEG) $(LIB_MATH)
+
+# LABEL coder module
+coders_label_la_SOURCES = coders/label.c
+coders_label_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_label_la_LDFLAGS = $(MODULECOMMONFLAGS) $(LIB_MATH)
+coders_label_la_LIBADD = $(LIBMAGICK)
+
+# LOCALE coder module
+coders_locale_la_SOURCES = coders/locale.c
+coders_locale_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_locale_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_locale_la_LIBADD = $(LIBMAGICK)
+
+# LOGO coder module
+coders_logo_la_SOURCES = coders/logo.c
+coders_logo_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_logo_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_logo_la_LIBADD = $(LIBMAGICK)
+
+# MAC coder module
+coders_mac_la_SOURCES = coders/mac.c
+coders_mac_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mac_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mac_la_LIBADD = $(LIBMAGICK)
+
+# MAP coder module
+coders_map_la_SOURCES = coders/map.c
+coders_map_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_map_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_map_la_LIBADD = $(LIBMAGICK)
+
+# MAT coder module
+coders_mat_la_SOURCES = coders/mat.c
+coders_mat_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mat_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mat_la_LIBADD = $(LIBMAGICK) $(LIB_ZLIB) $(LIB_MATH)
+
+# MATTE coder module
+coders_matte_la_SOURCES = coders/matte.c
+coders_matte_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_matte_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_matte_la_LIBADD = $(LIBMAGICK)
+
+# META coder module
+coders_meta_la_SOURCES = coders/meta.c
+coders_meta_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_meta_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_meta_la_LIBADD = $(LIBMAGICK)
+
+# MIFF coder module
+coders_miff_la_SOURCES = coders/miff.c
+coders_miff_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_miff_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_miff_la_LIBADD = $(LIBMAGICK) $(LIB_ZLIB) $(LIB_BZLIB)
+
+# MONO coder module
+coders_mono_la_SOURCES = coders/mono.c
+coders_mono_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mono_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mono_la_LIBADD = $(LIBMAGICK)
+
+# MPC coder module
+coders_mpc_la_SOURCES = coders/mpc.c
+coders_mpc_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mpc_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mpc_la_LIBADD = $(LIBMAGICK)
+
+# MPEG coder module
+coders_mpeg_la_SOURCES = coders/mpeg.c
+coders_mpeg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mpeg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mpeg_la_LIBADD = $(LIBMAGICK)
+
+# MPR coder module
+coders_mpr_la_SOURCES = coders/mpr.c
+coders_mpr_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mpr_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mpr_la_LIBADD = $(LIBMAGICK)
+
+# MSL coder module
+coders_msl_la_SOURCES = coders/msl.c
+coders_msl_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_msl_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_msl_la_LIBADD = $(LIBMAGICK) $(LIB_XML) $(LIB_XML_DEPS)
+
+# MTV coder module
+coders_mtv_la_SOURCES = coders/mtv.c
+coders_mtv_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mtv_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mtv_la_LIBADD = $(LIBMAGICK)
+
+# MVG coder module
+coders_mvg_la_SOURCES = coders/mvg.c
+coders_mvg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_mvg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_mvg_la_LIBADD = $(LIBMAGICK)
+
+# NULL coder module
+coders_null_la_SOURCES = coders/null.c
+coders_null_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_null_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_null_la_LIBADD = $(LIBMAGICK)
+
+# OTB coder module
+coders_otb_la_SOURCES = coders/otb.c
+coders_otb_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_otb_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_otb_la_LIBADD = $(LIBMAGICK)
+
+# PALM coder module
+coders_palm_la_SOURCES = coders/palm.c
+coders_palm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_palm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_palm_la_LIBADD = $(LIBMAGICK)
+
+# PCD coder module
+coders_pcd_la_SOURCES = coders/pcd.c
+coders_pcd_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pcd_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pcd_la_LIBADD = $(LIBMAGICK)
+
+# PCL coder module
+coders_pcl_la_SOURCES = coders/pcl.c
+coders_pcl_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pcl_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pcl_la_LIBADD = $(LIBMAGICK)
+
+# PCX coder module
+coders_pcx_la_SOURCES = coders/pcx.c
+coders_pcx_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pcx_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pcx_la_LIBADD = $(LIBMAGICK)
+
+# PDB coder module
+coders_pdb_la_SOURCES = coders/pdb.c
+coders_pdb_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pdb_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pdb_la_LIBADD = $(LIBMAGICK)
+
+# PDF coder module
+coders_pdf_la_SOURCES = coders/pdf.c
+coders_pdf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pdf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pdf_la_LIBADD = $(LIBMAGICK) $(LIB_ZLIB) $(LIB_GS)
+
+# PICT coder module
+coders_pict_la_SOURCES = coders/pict.c
+coders_pict_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pict_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pict_la_LIBADD = $(LIBMAGICK)
+
+# PIX coder module
+coders_pix_la_SOURCES = coders/pix.c
+coders_pix_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pix_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pix_la_LIBADD = $(LIBMAGICK)
+
+# PNG coder module
+coders_png_la_SOURCES = coders/png.c
+coders_png_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_png_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_png_la_LIBADD = $(LIBMAGICK) $(LIB_PNG) $(LIB_JPEG) $(LIB_ZLIB) $(LIB_MATH)
+
+# PLASMA coder module
+coders_plasma_la_SOURCES = coders/plasma.c
+coders_plasma_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_plasma_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_plasma_la_LIBADD = $(LIBMAGICK)
+
+# PNM coder module
+coders_pnm_la_SOURCES = coders/pnm.c
+coders_pnm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pnm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pnm_la_LIBADD = $(LIBMAGICK)
+
+# PREVIEW coder module
+coders_preview_la_SOURCES = coders/preview.c
+coders_preview_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_preview_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_preview_la_LIBADD = $(LIBMAGICK)
+
+# PS coder module
+coders_ps_la_SOURCES = coders/ps.c
+coders_ps_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ps_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ps_la_LIBADD = $(LIBMAGICK) $(LIB_GS) $(LIB_MATH)
+
+# PS2 coder module
+coders_ps2_la_SOURCES = coders/ps2.c
+coders_ps2_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ps2_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ps2_la_LIBADD = $(LIBMAGICK) $(LIB_TIFF) $(LIB_JBIG) $(LIB_JPEG) $(LIB_LZMA) $(LIB_ZLIB) $(LIB_MATH)
+
+# PS3 coder module
+coders_ps3_la_SOURCES = coders/ps3.c
+coders_ps3_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ps3_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ps3_la_LIBADD = $(LIBMAGICK) $(LIB_TIFF) $(LIB_JBIG) $(LIB_JPEG) $(LIB_LZMA) $(LIB_ZLIB) $(LIB_MATH)
+
+# PSD coder module
+coders_psd_la_SOURCES = coders/psd.c
+coders_psd_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_psd_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_psd_la_LIBADD = $(LIBMAGICK)
+
+# PWP coder module
+coders_pwp_la_SOURCES = coders/pwp.c
+coders_pwp_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_pwp_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_pwp_la_LIBADD = $(LIBMAGICK)
+
+# RGB coder module
+coders_rgb_la_SOURCES = coders/rgb.c
+coders_rgb_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_rgb_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_rgb_la_LIBADD = $(LIBMAGICK)
+
+# RLA coder module
+coders_rla_la_SOURCES = coders/rla.c
+coders_rla_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_rla_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_rla_la_LIBADD = $(LIBMAGICK)
+
+# RLE coder module
+coders_rle_la_SOURCES = coders/rle.c
+coders_rle_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_rle_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_rle_la_LIBADD = $(LIBMAGICK)
+
+# SCT coder module
+coders_sct_la_SOURCES = coders/sct.c
+coders_sct_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_sct_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_sct_la_LIBADD = $(LIBMAGICK)
+
+# SFW coder module
+coders_sfw_la_SOURCES = coders/sfw.c
+coders_sfw_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_sfw_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_sfw_la_LIBADD = $(LIBMAGICK)
+
+# SGI coder module
+coders_sgi_la_SOURCES = coders/sgi.c
+coders_sgi_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_sgi_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_sgi_la_LIBADD = $(LIBMAGICK)
+
+# STEGANO coder module
+coders_stegano_la_SOURCES = coders/stegano.c
+coders_stegano_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_stegano_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_stegano_la_LIBADD = $(LIBMAGICK)
+
+# SUN coder module
+coders_sun_la_SOURCES = coders/sun.c
+coders_sun_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_sun_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_sun_la_LIBADD = $(LIBMAGICK)
+
+# SVG coder module
+coders_svg_la_SOURCES = coders/svg.c
+coders_svg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_svg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_svg_la_LIBADD = $(LIBMAGICK) $(LIB_XML) $(LIB_XML_DEPS)
+
+# TGA coder module
+coders_tga_la_SOURCES = coders/tga.c
+coders_tga_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_tga_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_tga_la_LIBADD = $(LIBMAGICK)
+
+# TIFF coder module
+coders_tiff_la_SOURCES = coders/tiff.c
+coders_tiff_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_tiff_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_tiff_la_LIBADD = $(LIBMAGICK) $(LIB_TIFF) $(LIB_JBIG) $(LIB_JPEG) $(LIB_LZMA) $(LIB_ZLIB) $(LIB_MATH)
+
+# TILE coder module
+coders_tile_la_SOURCES = coders/tile.c
+coders_tile_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_tile_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_tile_la_LIBADD = $(LIBMAGICK)
+
+# TIM coder module
+coders_tim_la_SOURCES = coders/tim.c
+coders_tim_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_tim_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_tim_la_LIBADD = $(LIBMAGICK)
+
+# TOPOL coder module
+coders_topol_la_SOURCES = coders/topol.c
+coders_topol_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_topol_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_topol_la_LIBADD = $(LIBMAGICK)
+
+# TTF coder module
+coders_ttf_la_SOURCES = coders/ttf.c
+coders_ttf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_ttf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_ttf_la_LIBADD = $(LIBMAGICK)
+
+# TXT coder module
+coders_txt_la_SOURCES = coders/txt.c
+coders_txt_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_txt_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_txt_la_LIBADD = $(LIBMAGICK) $(LIB_MATH)
+
+# UIL coder module
+coders_uil_la_SOURCES = coders/uil.c
+coders_uil_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_uil_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_uil_la_LIBADD = $(LIBMAGICK)
+
+# URL coder module
+coders_url_la_SOURCES = coders/url.c
+coders_url_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_url_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_url_la_LIBADD = $(LIBMAGICK) $(LIB_XML) $(LIB_XML_DEPS)
+
+# UYVY coder module
+coders_uyvy_la_SOURCES = coders/uyvy.c
+coders_uyvy_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_uyvy_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_uyvy_la_LIBADD = $(LIBMAGICK)
+
+# VICAR coder module
+coders_vicar_la_SOURCES = coders/vicar.c
+coders_vicar_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_vicar_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_vicar_la_LIBADD = $(LIBMAGICK)
+
+# VID coder module
+coders_vid_la_SOURCES = coders/vid.c
+coders_vid_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_vid_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_vid_la_LIBADD = $(LIBMAGICK)
+
+# VIFF coder module
+coders_viff_la_SOURCES = coders/viff.c
+coders_viff_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_viff_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_viff_la_LIBADD = $(LIBMAGICK)
+
+# WBMP coder module
+coders_wbmp_la_SOURCES = coders/wbmp.c
+coders_wbmp_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_wbmp_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_wbmp_la_LIBADD = $(LIBMAGICK)
+
+# WMF coder module
+coders_wmf_la_SOURCES = coders/wmf.c
+coders_wmf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_wmf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_wmf_la_LIBADD = $(LIBMAGICK) $(LIB_WMF) $(LIB_WMF_DEPS) $(LIB_MATH)
+
+# WPG coder module
+coders_wpg_la_SOURCES = coders/wpg.c
+coders_wpg_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_wpg_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_wpg_la_LIBADD = $(LIBMAGICK)
+
+# X coder module
+coders_x_la_SOURCES = coders/x.c
+coders_x_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_x_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_x_la_LIBADD = $(LIBMAGICK) $(LIB_X11)
+
+# XBM coder module
+coders_xbm_la_SOURCES = coders/xbm.c
+coders_xbm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xbm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xbm_la_LIBADD = $(LIBMAGICK)
+
+# XC coder module
+coders_xc_la_SOURCES = coders/xc.c
+coders_xc_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xc_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xc_la_LIBADD = $(LIBMAGICK)
+
+# XCF coder module
+coders_xcf_la_SOURCES = coders/xcf.c
+coders_xcf_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xcf_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xcf_la_LIBADD = $(LIBMAGICK)
+
+# XPM coder module
+coders_xpm_la_SOURCES = coders/xpm.c
+coders_xpm_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xpm_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xpm_la_LIBADD = $(LIBMAGICK)
+
+# XWD coder module
+coders_xwd_la_SOURCES = coders/xwd.c
+coders_xwd_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_xwd_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_xwd_la_LIBADD = $(LIBMAGICK) $(LIB_X11)
+
+# YUV coder module
+coders_yuv_la_SOURCES = coders/yuv.c
+coders_yuv_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_yuv_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_yuv_la_LIBADD = $(LIBMAGICK)
+
+# WEBP coder module
+coders_webp_la_SOURCES = coders/webp.c
+coders_webp_la_CPPFLAGS = $(MAGICK_CODER_CPPFLAGS)
+coders_webp_la_LDFLAGS = $(MODULECOMMONFLAGS)
+coders_webp_la_LIBADD = $(LIBMAGICK) $(LIB_WEBP)
diff --git a/coders/art.c b/coders/art.c
new file mode 100644
index 0000000..43d2774
--- /dev/null
+++ b/coders/art.c
@@ -0,0 +1,317 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% AAA RRRR TTTTT %
+% A A R R T %
+% AAAAA RRRR T %
+% A A R R T %
+% A A R R T %
+% %
+% %
+% Read/Write PFS: 1st Publisher Image Format. %
+% %
+% %
+% Software Design %
+% Jaroslav Fojtik %
+% January 2001 - 2007 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d A R T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadARTImage reads an ART X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadARTImage method is:
+%
+% Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadARTImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image *image;
+ unsigned int i;
+ unsigned int width,height,dummy;
+ long ldblk;
+ unsigned char *BImgBuff=NULL;
+ unsigned char Padding;
+ unsigned int status;
+ const PixelPacket *q;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read ART image.
+ */
+ dummy=ReadBlobLSBShort(image);
+ width=ReadBlobLSBShort(image);
+ dummy=ReadBlobLSBShort(image);
+ height=ReadBlobLSBShort(image);
+
+ ldblk=(long) ((width+7) / 8);
+ Padding=(unsigned char) ((-ldblk) & 0x01);
+
+ image->columns=width;
+ image->rows=height;
+ if(GetBlobSize(image)!=(magick_off_t) (8+((long)ldblk+Padding)*image->rows))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ image->depth=1;
+ image->colors=1l << image->depth;
+
+ /* printf("ART header checked OK %d,%d\n",image->colors,image->depth); */
+
+ if (!AllocateImageColormap(image,image->colors)) goto NoMemory;
+
+ /* If ping is true, then only set image size and colors without reading any image data. */
+ if (image_info->ping) goto DONE_READING;
+
+ BImgBuff=MagickAllocateMemory(unsigned char *,((size_t) ldblk)); /*Ldblk was set in the check phase*/
+ if (BImgBuff==NULL)
+ NoMemory:
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ for (i=0; i < height; i++)
+ {
+ if (ReadBlob(image,(size_t)ldblk,(char *)BImgBuff) != (size_t)ldblk)
+ break;
+ if (ReadBlob(image,Padding,(char *)&dummy) != Padding)
+ break;
+
+ q=SetImagePixelsEx(image,0,i,image->columns,1,exception);
+ if (q == (PixelPacket *)NULL) break;
+ (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0);
+ if (!SyncImagePixelsEx(image,exception)) break;
+ }
+ MagickFreeMemory(BImgBuff);
+
+ if (i != height)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ DONE_READING:
+ CloseBlob(image);
+ return(image);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e A R T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Function WriteARTImage writes an ART image to a file.
+%
+% The format of the WriteARTImage method is:
+%
+% unsigned int WriteARTImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Function WriteARTImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+*/
+static MagickPassFail WriteARTImage(const ImageInfo *image_info,Image *image)
+{
+ long y;
+ unsigned dummy = 0;
+ size_t DataSize;
+ unsigned int status;
+ unsigned char Padding;
+ int logging;
+ unsigned char *pixels;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ART");
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ DataSize = (long)((image->columns+7) / 8);
+ Padding = (unsigned char)((-(long) DataSize) & 0x01);
+
+ pixels=MagickAllocateMemory(unsigned char *,(size_t) (DataSize));
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ /*
+ Write ART hader.
+ */
+ (void) WriteBlobLSBShort(image,0);
+ (void) WriteBlobLSBShort(image,image->columns);
+ (void) WriteBlobLSBShort(image,0);
+ (void) WriteBlobLSBShort(image,image->rows);
+
+ /*
+ Store image data.
+ */
+ for(y=0; y<(long)image->rows; y++)
+ {
+ if (AcquireImagePixels(image,0,y,image->columns,1,&image->exception)
+ == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (ExportImagePixelArea(image,GrayQuantum,1,pixels,0,0) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (WriteBlob(image,DataSize,pixels) != DataSize)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (WriteBlob(image,Padding,(char *)&dummy) != Padding)
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+
+ CloseBlob(image);
+ MagickFreeMemory(pixels);
+
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return ART");
+
+ return(status);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r A R T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterARTImage adds attributes for the ART image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterARTImage method is:
+%
+% RegisterARTImage(void)
+%
+*/
+ModuleExport void RegisterARTImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("ART");
+ entry->decoder = (DecoderHandler)ReadARTImage;
+ entry->encoder = (EncoderHandler)WriteARTImage;
+ entry->description="PFS: 1st Publisher";
+ entry->module="ART";
+ entry->adjoin=False;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r A R T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterARTImage removes format registrations made by the
+% ART module from the list of supported formats.
+%
+% The format of the UnregisterARTImage method is:
+%
+% UnregisterARTImage(void)
+%
+*/
+ModuleExport void UnregisterARTImage(void)
+{
+ (void) UnregisterMagickInfo("ART");
+}
diff --git a/coders/avs.c b/coders/avs.c
new file mode 100644
index 0000000..32bf2b2
--- /dev/null
+++ b/coders/avs.c
@@ -0,0 +1,425 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% AAA V V SSSSS %
+% A A V V SS %
+% AAAAA V V SSS %
+% A A V V SS %
+% A A V SSSSS %
+% %
+% %
+% Read/Write AVS X Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteAVSImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d A V S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadAVSImage reads an AVS X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image. Note that these files often have the extension
+% 'X' which conflicts with our X11 support coder.
+%
+% The format of the ReadAVSImage method is:
+%
+% Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadAVSImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define AVS_WIDTH_LIMIT 65536UL /* Artificially limit width to 64K pixels */
+#define AVS_HEIGHT_LIMIT 65536UL /* Artificially limit height to 64K pixels */
+static Image *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ status;
+
+ unsigned long
+ height,
+ width;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read AVS image.
+ */
+ width=ReadBlobMSBLong(image);
+ height=ReadBlobMSBLong(image);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "AVS dimensions %ldx%ld",width,height);
+
+ /*
+ Impose a maximum width and height limit in order to avoid
+ incredibly huge allocations.
+ */
+ if ((width > AVS_WIDTH_LIMIT) || (height > AVS_HEIGHT_LIMIT))
+ ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
+
+ do
+ {
+ /*
+ Convert AVS raster image to pixel packets.
+ */
+ size_t
+ row_bytes;
+
+ image->columns=width;
+ image->rows=height;
+ image->depth=8;
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ pixels=MagickAllocateArray(unsigned char *,image->columns,4);
+ if (pixels == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ row_bytes=4*image->columns;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (ReadBlob(image,row_bytes,pixels) != row_bytes)
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ status=MagickFail;
+ }
+ p=pixels;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p++));
+ q->red=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->blue=ScaleCharToQuantum(*p++);
+ image->matte|=(q->opacity != OpaqueOpacity);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (MagickFail == status)
+ break;
+ }
+ MagickFreeMemory(pixels);
+
+ if (MagickFail == status)
+ break;
+
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ width=ReadBlobMSBLong(image);
+ height=ReadBlobMSBLong(image);
+ if (!(EOFBlob(image)) && (width <= AVS_WIDTH_LIMIT) &&
+ (height <= AVS_HEIGHT_LIMIT))
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,image->filename);
+ if (status == MagickFail)
+ break;
+ }
+ } while (!(EOFBlob(image)));
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+
+ if (MagickFail == status)
+ {
+ DestroyImageList(image);
+ image=(Image *) NULL;
+ }
+
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r A V S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterAVSImage adds attributes for the AVS image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterAVSImage method is:
+%
+% RegisterAVSImage(void)
+%
+*/
+ModuleExport void RegisterAVSImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("AVS");
+ entry->decoder=(DecoderHandler) ReadAVSImage;
+ entry->encoder=(EncoderHandler) WriteAVSImage;
+ entry->description="AVS X image";
+ entry->module="AVS";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r A V S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterAVSImage removes format registrations made by the
+% AVS module from the list of supported formats.
+%
+% The format of the UnregisterAVSImage method is:
+%
+% UnregisterAVSImage(void)
+%
+*/
+ModuleExport void UnregisterAVSImage(void)
+{
+ (void) UnregisterMagickInfo("AVS");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e A V S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteAVSImage writes an image to a file in AVS X image format.
+%
+% The format of the WriteAVSImage method is:
+%
+% unsigned int WriteAVSImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteAVSImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteAVSImage(const ImageInfo *image_info,Image *image)
+{
+ register const PixelPacket
+ *p;
+
+ register long
+ x,
+ y;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ status;
+
+ unsigned long
+ scene;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ scene=0;
+ do
+ {
+ /*
+ Write AVS header.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ (void) WriteBlobMSBLong(image,image->columns);
+ (void) WriteBlobMSBLong(image,image->rows);
+ /*
+ Allocate memory for pixels.
+ */
+ pixels=MagickAllocateMemory(unsigned char *,image->columns*sizeof(PixelPacket));
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Convert MIFF to AVS raster pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (PixelPacket *) NULL)
+ break;
+ q=pixels;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(
+ MaxRGB-(image->matte ? p->opacity : OpaqueOpacity));
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ p++;
+ }
+ (void) WriteBlob(image,q-pixels,(char *) pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(pixels);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/bmp.c b/coders/bmp.c
new file mode 100644
index 0000000..2f4f207
--- /dev/null
+++ b/coders/bmp.c
@@ -0,0 +1,2096 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% BBBB M M PPPP %
+% B B MM MM P P %
+% BBBB M M M PPPP %
+% B B M M P %
+% BBBB M M P %
+% %
+% %
+% Read/Write Microsoft Windows Bitmap Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% Glenn Randers-Pehrson %
+% December 2001 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+ Macro definitions (from Windows wingdi.h).
+*/
+
+#undef BI_JPEG
+#define BI_JPEG 4
+#undef BI_PNG
+#define BI_PNG 5
+#if !defined(MSWINDOWS) || defined(__MINGW32__)
+#undef BI_RGB
+#define BI_RGB 0
+#undef BI_RLE8
+#define BI_RLE8 1
+#undef BI_RLE4
+#define BI_RLE4 2
+#undef BI_BITFIELDS
+#define BI_BITFIELDS 3
+
+#undef LCS_CALIBRATED_RBG
+#define LCS_CALIBRATED_RBG 0
+#undef LCS_sRGB
+#define LCS_sRGB 1
+#undef LCS_WINDOWS_COLOR_SPACE
+#define LCS_WINDOWS_COLOR_SPACE 2
+#undef PROFILE_LINKED
+#define PROFILE_LINKED 3
+#undef PROFILE_EMBEDDED
+#define PROFILE_EMBEDDED 4
+
+#undef LCS_GM_BUSINESS
+#define LCS_GM_BUSINESS 1 /* Saturation */
+#undef LCS_GM_GRAPHICS
+#define LCS_GM_GRAPHICS 2 /* Relative */
+#undef LCS_GM_IMAGES
+#define LCS_GM_IMAGES 4 /* Perceptual */
+#undef LCS_GM_ABS_COLORIMETRIC
+#define LCS_GM_ABS_COLORIMETRIC 8 /* Absolute */
+#endif
+
+/*
+ Typedef declarations.
+*/
+typedef struct _BMPInfo
+{
+ unsigned long
+ file_size,
+ ba_offset,
+ offset_bits,
+ size;
+
+ long
+ width,
+ height;
+
+ unsigned short
+ planes,
+ bits_per_pixel;
+
+ unsigned long
+ compression,
+ image_size,
+ x_pixels,
+ y_pixels,
+ number_colors,
+ red_mask,
+ green_mask,
+ blue_mask,
+ alpha_mask,
+ colors_important;
+
+ long
+ colorspace;
+
+ PrimaryInfo
+ red_primary,
+ green_primary,
+ blue_primary,
+ gamma_scale;
+} BMPInfo;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteBMPImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DecodeImage unpacks the packed image pixels into runlength-encoded
+% pixel packets.
+%
+% The format of the DecodeImage method is:
+%
+% MagickPassFail DecodeImage(Image *image,const unsigned long compression,
+% unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method DecodeImage returns MagickPass if all the pixels are
+% uncompressed without error, otherwise MagickFail.
+%
+% o image: The address of a structure of type Image.
+%
+% o compression: Zero means uncompressed. A value of 1 means the
+% compressed pixels are runlength encoded for a 256-color bitmap.
+% A value of 2 means a 16-color bitmap. A value of 3 means bitfields
+% encoding.
+%
+% o pixels: The address of a byte (8 bits) array of pixel data created by
+% the decoding process.
+%
+%
+*/
+static MagickPassFail DecodeImage(Image *image,const unsigned long compression,
+ unsigned char *pixels)
+{
+ long
+ byte,
+ count,
+ y;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *end;
+
+ assert(image != (Image *) NULL);
+ assert(pixels != (unsigned char *) NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Decoding RLE pixels");
+ (void) memset(pixels,0,image->columns*image->rows);
+ byte=0;
+ x=0;
+ q=pixels;
+ end=pixels + (size_t) image->columns*image->rows;
+ for (y=0; y < (long) image->rows; )
+ {
+ if (q < pixels || q >= end)
+ break;
+ count=ReadBlobByte(image);
+ if (count == EOF)
+ return MagickFail;
+ if (count != 0)
+ {
+ count=Min(count, end - q);
+ /*
+ Encoded mode.
+ */
+ byte=ReadBlobByte(image);
+ if (byte == EOF)
+ return MagickFail;
+ if (compression == BI_RLE8)
+ {
+ for ( i=count; i != 0; --i )
+ {
+ *q++=(unsigned char) byte;
+ }
+ }
+ else
+ {
+ for ( i=0; i < count; i++ )
+ {
+ *q++=(unsigned char)
+ ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
+ }
+ }
+ x+=count;
+ }
+ else
+ {
+ /*
+ Escape mode.
+ */
+ count=ReadBlobByte(image);
+ if (count == EOF)
+ return MagickFail;
+ if (count == 0x01)
+ return(MagickPass);
+ switch ((int) count)
+ {
+ case 0x00:
+ {
+ /*
+ End of line.
+ */
+ x=0;
+ y++;
+ q=pixels+y*image->columns;
+ break;
+ }
+ case 0x02:
+ {
+ /*
+ Delta mode.
+ */
+ byte=ReadBlobByte(image);
+ if (byte == EOF)
+ return MagickFail;
+ x+=byte;
+ byte=ReadBlobByte(image);
+ if (byte == EOF)
+ return MagickFail;
+ y+=byte;
+ q=pixels+y*image->columns+x;
+ break;
+ }
+ default:
+ {
+ /*
+ Absolute mode.
+ */
+ count=Min(count, end - q);
+ if (compression == BI_RLE8)
+ for (i=count; i != 0; --i)
+ {
+ byte=ReadBlobByte(image);
+ if (byte == EOF)
+ return MagickFail;
+ *q++=byte;
+ }
+ else
+ for (i=0; i < count; i++)
+ {
+ if ((i & 0x01) == 0)
+ {
+ byte=ReadBlobByte(image);
+ if (byte == EOF)
+ return MagickFail;
+ }
+ *q++=(unsigned char)
+ ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
+ }
+ x+=count;
+ /*
+ Read pad byte.
+ */
+ if (compression == BI_RLE8)
+ {
+ if (count & 0x01)
+ (void) ReadBlobByte(image);
+ }
+ else
+ if (((count & 0x03) == 1) || ((count & 0x03) == 2))
+ (void) ReadBlobByte(image);
+ break;
+ }
+ }
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) ReadBlobByte(image); /* end of line */
+ (void) ReadBlobByte(image);
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method EncodeImage compresses pixels using a runlength encoded format.
+%
+% The format of the EncodeImage method is:
+%
+% static unsigned int EncodeImage(Image *image,
+% const unsigned long bytes_per_line,const unsigned char *pixels,
+% unsigned char *compressed_pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method EncodeImage returns the number of bytes in the
+% runlength encoded compress_pixels array.
+%
+% o image: A pointer to an Image structure.
+%
+% o bytes_per_line: The number of bytes in a scanline of compressed pixels
+%
+% o pixels: The address of a byte (8 bits) array of pixel data created by
+% the compression process.
+%
+% o compressed_pixels: The address of a byte (8 bits) array of compressed
+% pixel data.
+%
+%
+*/
+static size_t EncodeImage(Image *image,const unsigned long bytes_per_line,
+ const unsigned char *pixels,unsigned char *compressed_pixels)
+{
+ long
+ y;
+
+ register const unsigned char
+ *p;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ /*
+ Runlength encode pixels.
+ */
+ assert(image != (Image *) NULL);
+ assert(pixels != (const unsigned char *) NULL);
+ assert(compressed_pixels != (unsigned char *) NULL);
+ p=pixels;
+ q=compressed_pixels;
+ i=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ for (x=0; x < (long) bytes_per_line; x+=i)
+ {
+ /*
+ Determine runlength.
+ */
+ for (i=1; ((x+i) < (long) bytes_per_line); i++)
+ if ((i == 255) || (*(p+i) != *p))
+ break;
+ *q++=(unsigned char) i;
+ *q++=(*p);
+ p+=i;
+ }
+ /*
+ End of line.
+ */
+ *q++=0x00;
+ *q++=0x00;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ /*
+ End of bitmap.
+ */
+ *q++=0;
+ *q++=0x01;
+ return(q-compressed_pixels);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s B M P %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsBMP returns True if the image format type, identified by the
+% magick string, is BMP.
+%
+% The format of the IsBMP method is:
+%
+% unsigned int IsBMP(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsBMP returns True if the image format type is BMP.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsBMP(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if ((LocaleNCompare((char *) magick,"BA",2) == 0) ||
+ (LocaleNCompare((char *) magick,"BM",2) == 0) ||
+ (LocaleNCompare((char *) magick,"IC",2) == 0) ||
+ (LocaleNCompare((char *) magick,"PI",2) == 0) ||
+ (LocaleNCompare((char *) magick,"CI",2) == 0) ||
+ (LocaleNCompare((char *) magick,"CP",2) == 0))
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d B M P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBMPImage reads a Microsoft Windows bitmap image file, Version
+% 2, 3 (for Windows or NT), or 4, and returns it. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% The format of the ReadBMPImage method is:
+%
+% image=ReadBMPImage(image_info)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadBMPImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowBMPReaderException(code_,reason_,image_) \
+do { \
+ MagickFreeMemory(bmp_colormap); \
+ MagickFreeMemory(pixels); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+
+static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ BMPInfo
+ bmp_info;
+
+ Image
+ *image;
+
+ int
+ logging;
+
+ long
+ y;
+
+ unsigned long
+ blue,
+ green,
+ opacity,
+ red;
+
+ ExtendedSignedIntegralType
+ start_position;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ size_t
+ count,
+ length;
+
+ unsigned char
+ *bmp_colormap,
+ magick[12],
+ *pixels;
+
+ unsigned int
+ status;
+
+ unsigned long
+ bytes_per_line;
+
+ magick_off_t
+ file_size;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ bmp_colormap=(unsigned char *) NULL;
+ pixels=(unsigned char *) NULL;
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowBMPReaderException(FileOpenError,UnableToOpenFile,image);
+ file_size=GetBlobSize(image);
+ /*
+ Determine if this is a BMP file.
+ */
+ (void) memset(&bmp_info,0,sizeof(BMPInfo));
+ bmp_info.ba_offset=0;
+ start_position=0;
+ count=ReadBlob(image,2,(char *) magick);
+ do
+ {
+ PixelPacket
+ quantum_bits,
+ shift;
+
+ unsigned long
+ profile_data,
+ profile_size;
+
+ /*
+ Verify BMP identifier.
+ */
+ if (bmp_info.ba_offset == 0)
+ start_position=TellBlob(image)-2;
+ bmp_info.ba_offset=0;
+ while (LocaleNCompare((char *) magick,"BA",2) == 0)
+ {
+ bmp_info.file_size=ReadBlobLSBLong(image);
+ bmp_info.ba_offset=ReadBlobLSBLong(image);
+ bmp_info.offset_bits=ReadBlobLSBLong(image);
+ if ((count=ReadBlob(image,2,(char *) magick)) != 2)
+ break;
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Magick: %c%c",
+ magick[0],magick[1]);
+ if ((count != 2) || ((LocaleNCompare((char *) magick,"BM",2) != 0) &&
+ (LocaleNCompare((char *) magick,"CI",2) != 0)))
+ ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
+ bmp_info.file_size=ReadBlobLSBLong(image);
+ (void) ReadBlobLSBLong(image);
+ bmp_info.offset_bits=ReadBlobLSBLong(image);
+ bmp_info.size=ReadBlobLSBLong(image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " BMP size: %lu, File size: %" MAGICK_OFF_F "u",
+ bmp_info.size, GetBlobSize(image));
+ if (bmp_info.size == 12)
+ {
+ /*
+ Windows 2.X or OS/2 BMP image file.
+ */
+ bmp_info.width=(magick_int16_t) ReadBlobLSBShort(image);
+ bmp_info.height=(magick_int16_t) ReadBlobLSBShort(image);
+ bmp_info.planes=ReadBlobLSBShort(image);
+ bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
+ bmp_info.x_pixels=0;
+ bmp_info.y_pixels=0;
+ bmp_info.number_colors=0;
+ bmp_info.compression=BI_RGB;
+ bmp_info.image_size=0;
+ bmp_info.alpha_mask=0;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Format: Windows 2.X or OS/2 Bitmap");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Geometry: %ldx%ld",bmp_info.width,bmp_info.height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Planes: %d",bmp_info.planes);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Bits per pixel: %d",bmp_info.bits_per_pixel);
+ }
+ }
+ else
+ {
+ /*
+ Microsoft Windows 3.X or later BMP image file.
+ */
+ if (bmp_info.size < 40)
+ ThrowBMPReaderException(CorruptImageError,NonOS2HeaderSizeError,
+ image);
+
+ /*
+ BMP v3 defines width and hight as signed LONG (32 bit) values. If
+ height is a positive number, then the image is a "bottom-up"
+ bitmap with origin in the lower-left corner. If height is a
+ negative number, then the image is a "top-down" bitmap with the
+ origin in the upper-left corner. The meaning of negative values
+ is not defined for width.
+ */
+ bmp_info.width=(magick_int32_t) ReadBlobLSBLong(image);
+ bmp_info.height=(magick_int32_t) ReadBlobLSBLong(image);
+ bmp_info.planes=ReadBlobLSBShort(image);
+ bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
+ bmp_info.compression=ReadBlobLSBLong(image);
+ bmp_info.image_size=ReadBlobLSBLong(image);
+ bmp_info.x_pixels=ReadBlobLSBLong(image);
+ bmp_info.y_pixels=ReadBlobLSBLong(image);
+ bmp_info.number_colors=ReadBlobLSBLong(image);
+ bmp_info.colors_important=ReadBlobLSBLong(image);
+ profile_data=0;
+ profile_size=0;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Format: MS Windows bitmap 3.X");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Geometry: %ldx%ld",bmp_info.width,bmp_info.height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Planes: %d",bmp_info.planes);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Bits per pixel: %d",bmp_info.bits_per_pixel);
+ switch ((int) bmp_info.compression)
+ {
+ case BI_RGB:
+ {
+ /* uncompressed */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression: BI_RGB");
+ break;
+ }
+ case BI_RLE4:
+ {
+ /* 4 bit RLE */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression: BI_RLE4");
+ break;
+ }
+ case BI_RLE8:
+ {
+ /* 8 bit RLE */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression: BI_RLE8");
+ break;
+ }
+ case BI_BITFIELDS:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression: BI_BITFIELDS");
+ break;
+ }
+ case BI_PNG:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression: BI_PNG");
+ break;
+ }
+ case BI_JPEG:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression: BI_JPEG");
+ break;
+ }
+ default:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression: UNKNOWN (%lu)",bmp_info.compression);
+ }
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Number of colors: %lu",bmp_info.number_colors);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Important colors: %lu",bmp_info.colors_important);
+ }
+
+ bmp_info.red_mask=ReadBlobLSBLong(image);
+ bmp_info.green_mask=ReadBlobLSBLong(image);
+ bmp_info.blue_mask=ReadBlobLSBLong(image);
+
+ if (bmp_info.size > 40)
+ {
+ double
+ sum;
+
+ /*
+ Read color management information.
+ */
+ bmp_info.alpha_mask=ReadBlobLSBLong(image);
+ bmp_info.colorspace=(long) ReadBlobLSBLong(image);
+ /*
+ Decode 2^30 fixed point formatted CIE primaries.
+ */
+ bmp_info.red_primary.x=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+ bmp_info.red_primary.y=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+ bmp_info.red_primary.z=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+ bmp_info.green_primary.x=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+ bmp_info.green_primary.y=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+ bmp_info.green_primary.z=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+ bmp_info.blue_primary.x=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+ bmp_info.blue_primary.y=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+ bmp_info.blue_primary.z=(double)
+ ReadBlobLSBLong(image)/0x3ffffff;
+
+ sum=bmp_info.red_primary.x+bmp_info.red_primary.y+
+ bmp_info.red_primary.z;
+ bmp_info.red_primary.x/=sum;
+ bmp_info.red_primary.y/=sum;
+ image->chromaticity.red_primary.x=bmp_info.red_primary.x;
+ image->chromaticity.red_primary.y=bmp_info.red_primary.y;
+
+ sum=bmp_info.green_primary.x+bmp_info.green_primary.y+
+ bmp_info.green_primary.z;
+ bmp_info.green_primary.x/=sum;
+ bmp_info.green_primary.y/=sum;
+ image->chromaticity.green_primary.x=bmp_info.green_primary.x;
+ image->chromaticity.green_primary.y=bmp_info.green_primary.y;
+
+ sum=bmp_info.blue_primary.x+bmp_info.blue_primary.y+
+ bmp_info.blue_primary.z;
+ bmp_info.blue_primary.x/=sum;
+ bmp_info.blue_primary.y/=sum;
+ image->chromaticity.blue_primary.x=bmp_info.blue_primary.x;
+ image->chromaticity.blue_primary.y=bmp_info.blue_primary.y;
+
+ /*
+ Decode 16^16 fixed point formatted gamma_scales.
+ */
+ bmp_info.gamma_scale.x=(double) ReadBlobLSBLong(image)/0xffff;
+ bmp_info.gamma_scale.y=(double) ReadBlobLSBLong(image)/0xffff;
+ bmp_info.gamma_scale.z=(double) ReadBlobLSBLong(image)/0xffff;
+ /*
+ Compute a single gamma from the BMP 3-channel gamma.
+ */
+ image->gamma=(bmp_info.gamma_scale.x+bmp_info.gamma_scale.y+
+ bmp_info.gamma_scale.z)/3.0;
+ }
+ if (bmp_info.size > 108)
+ {
+ unsigned long
+ intent;
+
+ /*
+ Read BMP Version 5 color management information.
+ */
+ intent=ReadBlobLSBLong(image);
+ switch ((int) intent)
+ {
+ case LCS_GM_BUSINESS:
+ {
+ image->rendering_intent=SaturationIntent;
+ break;
+ }
+ case LCS_GM_GRAPHICS:
+ {
+ image->rendering_intent=RelativeIntent;
+ break;
+ }
+ case LCS_GM_IMAGES:
+ {
+ image->rendering_intent=PerceptualIntent;
+ break;
+ }
+ case LCS_GM_ABS_COLORIMETRIC:
+ {
+ image->rendering_intent=AbsoluteIntent;
+ break;
+ }
+ }
+ profile_data=ReadBlobLSBLong(image);
+ profile_size=ReadBlobLSBLong(image);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Profile: size %lu data %lu",
+ profile_size,profile_data);
+ (void) ReadBlobLSBLong(image); /* Reserved byte */
+ }
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File size: Claimed=%lu, Actual=%"
+ MAGICK_OFF_F "d",
+ bmp_info.file_size, file_size);
+ if ((magick_off_t) bmp_info.file_size > file_size)
+ {
+ ThrowException(exception,CorruptImageWarning,
+ LengthAndFilesizeDoNotMatch,image->filename);
+ }
+ if (logging && (magick_off_t) bmp_info.file_size < file_size)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Discarding all data beyond bmp_info.file_size");
+ if (bmp_info.width <= 0)
+ ThrowBMPReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+ if (bmp_info.height == 0)
+ ThrowBMPReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+ if ((bmp_info.height < 0) && (bmp_info.compression !=0))
+ ThrowBMPReaderException(CorruptImageError,CompressionNotValid,image);
+ if (bmp_info.planes != 1)
+ ThrowBMPReaderException(CorruptImageError,StaticPlanesValueNotEqualToOne,
+ image);
+ if ((bmp_info.bits_per_pixel != 1) && (bmp_info.bits_per_pixel != 4) &&
+ (bmp_info.bits_per_pixel != 8) && (bmp_info.bits_per_pixel != 16) &&
+ (bmp_info.bits_per_pixel != 24) && (bmp_info.bits_per_pixel != 32))
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedBitsPerPixel,image);
+ if (bmp_info.bits_per_pixel < 16)
+ {
+ if (bmp_info.number_colors > (1UL << bmp_info.bits_per_pixel))
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedNumberOfColors,image);
+ }
+ if (bmp_info.compression > 3)
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedImageCompression,image);
+ if ((bmp_info.compression == 1) && (bmp_info.bits_per_pixel != 8))
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedBitsPerPixel,image);
+ if ((bmp_info.compression == 2) && (bmp_info.bits_per_pixel != 4))
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedBitsPerPixel,image);
+ if ((bmp_info.compression == 3) && (bmp_info.bits_per_pixel < 16))
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedBitsPerPixel,image);
+ switch ((unsigned int) bmp_info.compression)
+ {
+ case BI_RGB:
+ case BI_RLE8:
+ case BI_RLE4:
+ case BI_BITFIELDS:
+ break;
+ case BI_JPEG:
+ ThrowBMPReaderException(CoderError,JPEGCompressionNotSupported,image)
+ case BI_PNG:
+ ThrowBMPReaderException(CoderError,PNGCompressionNotSupported,image)
+ default:
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedImageCompression,
+ image)
+ }
+ image->columns=bmp_info.width;
+ image->rows=AbsoluteValue(bmp_info.height);
+ image->depth=8;
+ /*
+ Image has alpha channel if alpha mask is specified, or is
+ uncompressed and 32-bits per pixel
+ */
+ image->matte=((bmp_info.alpha_mask != 0)
+ || ((bmp_info.compression == BI_RGB)
+ && (bmp_info.bits_per_pixel == 32)));
+ if (bmp_info.bits_per_pixel < 16)
+ {
+ if (bmp_info.number_colors == 0)
+ image->colors=1L << bmp_info.bits_per_pixel;
+ else
+ image->colors=bmp_info.number_colors;
+ image->storage_class=PseudoClass;
+ }
+ if (image->storage_class == PseudoClass)
+ {
+ unsigned int
+ packet_size;
+
+ /*
+ Read BMP raster colormap.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading colormap of %u colors",image->colors);
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowBMPReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ bmp_colormap=MagickAllocateArray(unsigned char *,4,image->colors);
+ if (bmp_colormap == (unsigned char *) NULL)
+ ThrowBMPReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if ((bmp_info.size == 12) || (bmp_info.size == 64))
+ packet_size=3;
+ else
+ packet_size=4;
+ if (SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET) == -1)
+ ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (ReadBlob(image,packet_size*image->colors,(char *) bmp_colormap)
+ != packet_size*image->colors)
+ ThrowBMPReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ p=bmp_colormap;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ if (packet_size == 4)
+ p++;
+ }
+ MagickFreeMemory(bmp_colormap);
+ }
+
+ if (image_info->ping)
+ if ((image_info->subrange == 0) ||
+ ((image_info->subrange != 0) &&
+ (image->scene >= (image_info->subimage+image_info->subrange-1))))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowBMPReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Read image data.
+ */
+ if (SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET) == -1)
+ ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image)
+ if (bmp_info.compression == BI_RLE4)
+ bmp_info.bits_per_pixel<<=1;
+ bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Bytes per line: %" MAGICK_SIZE_T_F "u",
+ (MAGICK_SIZE_T) bytes_per_line);
+
+ length=bytes_per_line*image->rows;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Expected total raster length: %" MAGICK_SIZE_T_F "u",
+ (MAGICK_SIZE_T) length);
+ if (length/image->rows != bytes_per_line)
+ ThrowBMPReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ /*
+ Check that file data is reasonable given claims by file header.
+ We do this before allocating raster memory to avoid DOS.
+ */
+ if ((bmp_info.compression == BI_RGB) ||
+ (bmp_info.compression == BI_BITFIELDS))
+ {
+ /*
+ Not compressed.
+ */
+ if (length >= (size_t) file_size)
+ ThrowBMPReaderException(CorruptImageError,InsufficientImageDataInFile,
+ image);
+ }
+ else if ((bmp_info.compression == BI_RLE4) ||
+ (bmp_info.compression == BI_RLE8))
+ {
+ /* RLE Compressed. Assume a maximum compression ratio. */
+ if ((file_size == 0) || (((double) length/file_size) > 254.0))
+ ThrowBMPReaderException(CorruptImageError,InsufficientImageDataInFile,
+ image);
+ }
+
+ pixels=MagickAllocateArray(unsigned char *,
+ Max(bytes_per_line,image->columns+1),
+ image->rows);
+ if (pixels == (unsigned char *) NULL)
+ ThrowBMPReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if ((bmp_info.compression == BI_RGB) ||
+ (bmp_info.compression == BI_BITFIELDS))
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading pixels (%" MAGICK_SIZE_T_F "u bytes)",
+ (MAGICK_SIZE_T) length);
+ (void) ReadBlob(image,length,(char *) pixels);
+ }
+ else
+ {
+ /*
+ Convert run-length encoded raster pixels.
+ */
+ status=DecodeImage(image,bmp_info.compression,pixels);
+ if (status == MagickFail)
+ ThrowBMPReaderException(CorruptImageError,UnableToRunlengthDecodeImage,
+ image);
+ }
+ /*
+ Initialize image structure.
+ */
+ image->units=PixelsPerCentimeterResolution;
+ image->x_resolution=bmp_info.x_pixels/100.0;
+ image->y_resolution=bmp_info.y_pixels/100.0;
+ /*
+ Convert BMP raster image to pixel packets.
+ */
+ if (bmp_info.compression == BI_RGB)
+ {
+ bmp_info.alpha_mask=(image->matte ? 0xff000000L : 0);
+ bmp_info.red_mask=0x00ff0000L;
+ bmp_info.green_mask=0x0000ff00L;
+ bmp_info.blue_mask=0x000000ffL;
+ if (bmp_info.bits_per_pixel == 16)
+ {
+ /*
+ RGB555.
+ */
+ bmp_info.red_mask=0x00007c00L;
+ bmp_info.green_mask=0x000003e0L;
+ bmp_info.blue_mask=0x0000001fL;
+ }
+ }
+ if ((bmp_info.bits_per_pixel == 16) || (bmp_info.bits_per_pixel == 32))
+ {
+ register unsigned long
+ sample;
+
+ /*
+ Get shift and quantum bits info from bitfield masks.
+ */
+ (void) memset(&shift,0,sizeof(PixelPacket));
+ (void) memset(&quantum_bits,0,sizeof(PixelPacket));
+ if (bmp_info.red_mask != 0)
+ while (((bmp_info.red_mask << shift.red) & 0x80000000UL) == 0)
+ shift.red++;
+ if (bmp_info.green_mask != 0)
+ while (((bmp_info.green_mask << shift.green) & 0x80000000UL) == 0)
+ shift.green++;
+ if (bmp_info.blue_mask != 0)
+ while (((bmp_info.blue_mask << shift.blue) & 0x80000000UL) == 0)
+ shift.blue++;
+ if (bmp_info.alpha_mask != 0)
+ while (((bmp_info.alpha_mask << shift.opacity) & 0x80000000UL) == 0)
+ shift.opacity++;
+ sample=shift.red;
+ while (((bmp_info.red_mask << sample) & 0x80000000UL) != 0)
+ sample++;
+ quantum_bits.red=(Quantum) (sample-shift.red);
+ sample=shift.green;
+ while (((bmp_info.green_mask << sample) & 0x80000000UL) != 0)
+ sample++;
+ quantum_bits.green=(Quantum) (sample-shift.green);
+ sample=shift.blue;
+ while (((bmp_info.blue_mask << sample) & 0x80000000UL) != 0)
+ sample++;
+ quantum_bits.blue=(Quantum) (sample-shift.blue);
+ sample=shift.opacity;
+ while (((bmp_info.alpha_mask << sample) & 0x80000000UL) != 0)
+ sample++;
+ quantum_bits.opacity=(Quantum) (sample-shift.opacity);
+ }
+ switch (bmp_info.bits_per_pixel)
+ {
+ case 1:
+ {
+ /*
+ Convert bitmap scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (ImportImagePixelArea(image,IndexQuantum,bmp_info.bits_per_pixel,p,0,0)
+ == MagickFail)
+ break;
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+ /*
+ Convert PseudoColor scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (ImportImagePixelArea(image,IndexQuantum,bmp_info.bits_per_pixel,p,0,0)
+ == MagickFail)
+ break;
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 8:
+ {
+ /*
+ Convert PseudoColor scanline.
+ */
+ if ((bmp_info.compression == BI_RLE8) ||
+ (bmp_info.compression == BI_RLE4))
+ bytes_per_line=image->columns;
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (ImportImagePixelArea(image,IndexQuantum,bmp_info.bits_per_pixel,p,0,0)
+ == MagickFail)
+ break;
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ unsigned long
+ pixel;
+
+ /*
+ Convert bitfield encoded 16-bit PseudoColor scanline.
+ */
+ if (bmp_info.compression != BI_RGB &&
+ bmp_info.compression != BI_BITFIELDS)
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedImageCompression,image)
+ bytes_per_line=2*(image->columns+image->columns%2);
+ image->storage_class=DirectClass;
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=(*p++);
+ pixel|=(*p++) << 8;
+ red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
+ if (quantum_bits.red == 8)
+ red|=(red >> 8);
+ green=((pixel & bmp_info.green_mask) << shift.green) >> 16;
+ if (quantum_bits.green == 8)
+ green|=(green >> 8);
+ blue=((pixel & bmp_info.blue_mask) << shift.blue) >> 16;
+ if (quantum_bits.blue == 8)
+ blue|=(blue >> 8);
+ if (image->matte != False)
+ {
+ opacity=((pixel & bmp_info.alpha_mask) << shift.opacity) >> 16;
+ if (quantum_bits.opacity == 8)
+ opacity|=(opacity >> 8);
+ q->opacity=MaxRGB-ScaleShortToQuantum(opacity);
+ }
+ q->red=ScaleShortToQuantum(red);
+ q->green=ScaleShortToQuantum(green);
+ q->blue=ScaleShortToQuantum(blue);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 24:
+ {
+ /*
+ Convert DirectColor scanline.
+ */
+ bytes_per_line=4*((image->columns*24+31)/32);
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->blue=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->red=ScaleCharToQuantum(*p++);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 32:
+ {
+ /*
+ Convert bitfield encoded DirectColor scanline.
+ */
+ if ((bmp_info.compression != BI_RGB) &&
+ (bmp_info.compression != BI_BITFIELDS))
+ ThrowBMPReaderException(CorruptImageError,UnrecognizedImageCompression,image)
+ bytes_per_line=4*(image->columns);
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ unsigned long
+ pixel;
+
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel =(*p++);
+ pixel|=(*p++ << 8);
+ pixel|=(*p++ << 16);
+ pixel|=(unsigned long) (*p++ << 24);
+ red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
+ if (quantum_bits.red == 8)
+ red|=(red >> 8);
+ green=((pixel & bmp_info.green_mask) << shift.green) >> 16;
+ if (quantum_bits.green == 8)
+ green|=(green >> 8);
+ blue=((pixel & bmp_info.blue_mask) << shift.blue) >> 16;
+ if (quantum_bits.blue == 8)
+ blue|=(blue >> 8);
+ if (image->matte != False)
+ {
+ opacity=((pixel & bmp_info.alpha_mask) << shift.opacity) >> 16;
+ if (quantum_bits.opacity == 8)
+ opacity|=(opacity >> 8);
+ q->opacity=MaxRGB-ScaleShortToQuantum(opacity);
+ }
+ q->red=ScaleShortToQuantum(red);
+ q->green=ScaleShortToQuantum(green);
+ q->blue=ScaleShortToQuantum(blue);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image)
+ }
+ MagickFreeMemory(pixels);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ if (bmp_info.height < 0)
+ {
+ Image
+ *flipped_image;
+
+ /*
+ Correct image orientation.
+ */
+ flipped_image=FlipImage(image,exception);
+ if (flipped_image == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ DestroyBlob(flipped_image);
+ flipped_image->blob=ReferenceBlob(image->blob);
+ ReplaceImageInList(&image,flipped_image);
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ *magick='\0';
+ if (bmp_info.ba_offset != 0)
+ if (SeekBlob(image,bmp_info.ba_offset,SEEK_SET) == -1)
+ ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image)
+ (void) ReadBlob(image,2,(char *) magick);
+ if (IsBMP(magick,2))
+ {
+ /*
+ Acquire next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ }
+ } while (IsBMP(magick,2));
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r B M P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterBMPImage adds attributes for the BMP image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterBMPImage method is:
+%
+% RegisterBMPImage(void)
+%
+*/
+ModuleExport void RegisterBMPImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("BMP");
+ entry->decoder=(DecoderHandler) ReadBMPImage;
+ entry->encoder=(EncoderHandler) WriteBMPImage;
+ entry->magick=(MagickHandler) IsBMP;
+ entry->description="Microsoft Windows bitmap image";
+ entry->module="BMP";
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("BMP2");
+ entry->encoder=(EncoderHandler) WriteBMPImage;
+ entry->magick=(MagickHandler) IsBMP;
+ entry->description="Microsoft Windows bitmap image v2";
+ entry->module="BMP";
+ entry->adjoin=False;
+ entry->coder_class=PrimaryCoderClass;
+ entry->seekable_stream=True;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("BMP3");
+ entry->encoder=(EncoderHandler) WriteBMPImage;
+ entry->magick=(MagickHandler) IsBMP;
+ entry->description="Microsoft Windows bitmap image v3";
+ entry->module="BMP";
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r B M P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterBMPImage removes format registrations made by the
+% BMP module from the list of supported formats.
+%
+% The format of the UnregisterBMPImage method is:
+%
+% UnregisterBMPImage(void)
+%
+*/
+ModuleExport void UnregisterBMPImage(void)
+{
+ (void) UnregisterMagickInfo("BMP");
+ (void) UnregisterMagickInfo("BMP2");
+ (void) UnregisterMagickInfo("BMP3");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e B M P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBMPImage writes an image in Microsoft Windows bitmap encoded
+% image format, version 3 for Windows or (if the image has a matte channel)
+% version 4.
+%
+% The format of the WriteBMPImage method is:
+%
+% unsigned int WriteBMPImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteBMPImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteBMPImage(const ImageInfo *image_info,Image *image)
+{
+ BMPInfo
+ bmp_info;
+
+ int
+ logging;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *bmp_data,
+ *pixels;
+
+ unsigned int
+ have_color_info,
+ status;
+
+ unsigned long
+ bytes_per_line,
+ scene,
+ type;
+
+/* const unsigned char */
+/* *color_profile=0; */
+
+ size_t
+ color_profile_length=0;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ type=4;
+ if (LocaleCompare(image_info->magick,"BMP2") == 0)
+ type=2;
+ else
+ if (LocaleCompare(image_info->magick,"BMP3") == 0)
+ type=3;
+ scene=0;
+
+ /*
+ Retrieve color profile from Image (if any)
+ FIXME: is color profile support writing not properly implemented?
+ */
+ /* color_profile= */ (void) GetImageProfile(image,"ICM",&color_profile_length);
+
+ do
+ {
+ /*
+ Initialize BMP raster file header.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ (void) memset(&bmp_info,0,sizeof(BMPInfo));
+ bmp_info.file_size=14+12;
+ if (type > 2)
+ bmp_info.file_size+=28;
+ bmp_info.offset_bits=bmp_info.file_size;
+ bmp_info.compression=BI_RGB;
+ if ((image->storage_class != DirectClass) && (image->colors > 256))
+ (void) SetImageType(image,TrueColorType);
+ if (image->storage_class != DirectClass)
+ {
+ /*
+ Colormapped BMP raster.
+ */
+ bmp_info.bits_per_pixel=8;
+ if (image->colors <= 2)
+ bmp_info.bits_per_pixel=1;
+ else if (image->colors <= 16)
+ bmp_info.bits_per_pixel=4;
+ else if (image->colors <= 256)
+ bmp_info.bits_per_pixel=8;
+ bmp_info.number_colors=1 << bmp_info.bits_per_pixel;
+ if (image->matte)
+ (void) SetImageType(image,TrueColorMatteType);
+ else
+ if (bmp_info.number_colors < image->colors)
+ (void) SetImageType(image,TrueColorType);
+ else
+ {
+ bmp_info.file_size+=3*(1 << bmp_info.bits_per_pixel);
+ bmp_info.offset_bits+=3*(1 << bmp_info.bits_per_pixel);
+ if (type > 2)
+ {
+ bmp_info.file_size+=(1 << bmp_info.bits_per_pixel);
+ bmp_info.offset_bits+=(1 << bmp_info.bits_per_pixel);
+ }
+ }
+ }
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Full color BMP raster.
+ */
+ bmp_info.number_colors=0;
+ bmp_info.bits_per_pixel=((type > 3) && image->matte) ? 32 : 24;
+ bmp_info.compression=
+ (type > 3) && image->matte ? BI_BITFIELDS : BI_RGB;
+ }
+ bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
+ bmp_info.ba_offset=0;
+ have_color_info=(int) ((image->rendering_intent != UndefinedIntent) ||
+ (color_profile_length != 0) || (image->gamma != 0.0));
+ if (type == 2)
+ bmp_info.size=12;
+ else
+ if ((type == 3) || (!image->matte && !have_color_info))
+ {
+ type=3;
+ bmp_info.size=40;
+ }
+ else
+ {
+ int
+ extra_size;
+
+ bmp_info.size=108;
+ extra_size=68;
+ if ((image->rendering_intent != UndefinedIntent) ||
+ (color_profile_length != 0))
+ {
+ bmp_info.size=124;
+ extra_size+=16;
+ }
+ bmp_info.file_size+=extra_size;
+ bmp_info.offset_bits+=extra_size;
+ }
+ /*
+ Verify and enforce that image dimensions do not exceed limit
+ imposed by file format.
+ */
+ if (type == 2)
+ {
+ bmp_info.width=(magick_int16_t) image->columns;
+ bmp_info.height=(magick_int16_t) image->rows;
+ }
+ else
+ {
+ bmp_info.width=(magick_int32_t) image->columns;
+ bmp_info.height=(magick_int32_t) image->rows;
+ }
+ if (((unsigned long) bmp_info.width != image->columns) ||
+ ((unsigned long) bmp_info.height != image->rows))
+ {
+ ThrowWriterException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
+ }
+
+ bmp_info.planes=1;
+ bmp_info.image_size=bytes_per_line*image->rows;
+ bmp_info.file_size+=bmp_info.image_size;
+ bmp_info.x_pixels=75*39;
+ bmp_info.y_pixels=75*39;
+ if (image->units == PixelsPerInchResolution)
+ {
+ bmp_info.x_pixels=(unsigned long) (100.0*image->x_resolution/2.54);
+ bmp_info.y_pixels=(unsigned long) (100.0*image->y_resolution/2.54);
+ }
+ if (image->units == PixelsPerCentimeterResolution)
+ {
+ bmp_info.x_pixels=(unsigned long) (100.0*image->x_resolution);
+ bmp_info.y_pixels=(unsigned long) (100.0*image->y_resolution);
+ }
+ bmp_info.colors_important=bmp_info.number_colors;
+ /*
+ Convert MIFF to BMP raster pixels.
+ */
+ pixels=MagickAllocateMemory(unsigned char *,bmp_info.image_size);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ switch (bmp_info.bits_per_pixel)
+ {
+ case 1:
+ {
+ ExportPixelAreaOptions
+ export_options;
+
+ /*
+ Convert PseudoClass image to a BMP monochrome image.
+ */
+ ExportPixelAreaOptionsInit(&export_options);
+ export_options.pad_bytes=(bytes_per_line - ((image->columns+7)/8));
+ export_options.pad_value=0x00;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels+(image->rows-y-1)*bytes_per_line;
+ if (ExportImagePixelArea(image,IndexQuantum,1,q,&export_options,0)
+ == MagickFail)
+ {
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case 4:
+ {
+ ExportPixelAreaOptions
+ export_options;
+
+ /*
+ Convert PseudoClass image to a BMP monochrome image.
+ */
+ ExportPixelAreaOptionsInit(&export_options);
+ export_options.pad_bytes=(bytes_per_line - ((image->columns+1)/2));
+ export_options.pad_value=0x00;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels+(image->rows-y-1)*bytes_per_line;
+ if (ExportImagePixelArea(image,IndexQuantum,4,q,&export_options,0)
+ == MagickFail)
+ {
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case 8:
+ {
+ ExportPixelAreaOptions
+ export_options;
+
+ /*
+ Convert PseudoClass packet to BMP pixel.
+ */
+ ExportPixelAreaOptionsInit(&export_options);
+ export_options.pad_bytes=(bytes_per_line - image->columns);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels+(image->rows-y-1)*bytes_per_line;
+ if (ExportImagePixelArea(image,IndexQuantum,8,q,&export_options,0)
+ == MagickFail)
+ {
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case 24:
+ case 32:
+ {
+ /*
+ Convert DirectClass packet to BMP BGR888 or BGRA8888 pixel.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels+(image->rows-y-1)*bytes_per_line;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(p->blue);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->red);
+ if (bmp_info.bits_per_pixel == 32)
+ *q++=ScaleQuantumToChar(MaxRGB-p->opacity);
+ p++;
+ }
+ if (bmp_info.bits_per_pixel == 24)
+ {
+ /* initialize padding bytes */
+ for (x=3*image->columns; x < (long) bytes_per_line; x++)
+ *q++=0x00;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ }
+ if ((type > 2) && (bmp_info.bits_per_pixel == 8))
+ if (image_info->compression != NoCompression)
+ {
+ size_t
+ length;
+
+ /*
+ Convert run-length encoded raster pixels.
+ */
+ length=2*(bytes_per_line+2)*(image->rows+2)+2;
+ bmp_data=MagickAllocateMemory(unsigned char *,length);
+ if (bmp_data == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(pixels);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image)
+ }
+ bmp_info.file_size-=bmp_info.image_size;
+ bmp_info.image_size=(unsigned long) EncodeImage(image,bytes_per_line,pixels,
+ bmp_data);
+ bmp_info.file_size+=bmp_info.image_size;
+ MagickFreeMemory(pixels);
+ pixels=bmp_data;
+ bmp_info.compression=BI_RLE8;
+ }
+ /*
+ Write BMP for Windows, all versions, 14-byte header.
+ */
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing BMP version %ld datastream",type);
+ if (image->storage_class == DirectClass)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Storage class=DirectClass");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Storage class=PseudoClass");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Image depth=%u",image->depth);
+ if (image->matte)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Matte=True");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Matte=False");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " BMP bits_per_pixel=%d",bmp_info.bits_per_pixel);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " BMP file_size=%lu bytes",bmp_info.file_size);
+ switch ((int) bmp_info.compression)
+ {
+ case BI_RGB:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression=BI_RGB");
+ break;
+ }
+ case BI_RLE8:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression=BI_RLE8");
+ break;
+ }
+ case BI_BITFIELDS:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression=BI_BITFIELDS");
+ break;
+ }
+ default:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression=UNKNOWN (%lu)",bmp_info.compression);
+ break;
+ }
+ }
+ if (bmp_info.number_colors == 0)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Number_colors=unspecified");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Number_colors=%lu",bmp_info.number_colors);
+ }
+ (void) WriteBlob(image,2,"BM");
+ (void) WriteBlobLSBLong(image,bmp_info.file_size);
+ (void) WriteBlobLSBLong(image,bmp_info.ba_offset); /* always 0 */
+ (void) WriteBlobLSBLong(image,bmp_info.offset_bits);
+ if (type == 2)
+ {
+ /*
+ Write 12-byte version 2 bitmap header.
+ */
+ (void) WriteBlobLSBLong(image,bmp_info.size);
+ (void) WriteBlobLSBShort(image,bmp_info.width);
+ (void) WriteBlobLSBShort(image,bmp_info.height);
+ (void) WriteBlobLSBShort(image,bmp_info.planes);
+ (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
+ }
+ else
+ {
+ /*
+ Write 40-byte version 3+ bitmap header.
+ */
+ (void) WriteBlobLSBLong(image,bmp_info.size);
+ (void) WriteBlobLSBLong(image,bmp_info.width);
+ (void) WriteBlobLSBLong(image,bmp_info.height);
+ (void) WriteBlobLSBShort(image,bmp_info.planes);
+ (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
+ (void) WriteBlobLSBLong(image,bmp_info.compression);
+ (void) WriteBlobLSBLong(image,bmp_info.image_size);
+ (void) WriteBlobLSBLong(image,bmp_info.x_pixels);
+ (void) WriteBlobLSBLong(image,bmp_info.y_pixels);
+ (void) WriteBlobLSBLong(image,bmp_info.number_colors);
+ (void) WriteBlobLSBLong(image,bmp_info.colors_important);
+ }
+ if ((type > 3) && (image->matte || have_color_info))
+ {
+ /*
+ Write the rest of the 108-byte BMP Version 4 header.
+ */
+ (void) WriteBlobLSBLong(image,0x00ff0000L); /* Red mask */
+ (void) WriteBlobLSBLong(image,0x0000ff00L); /* Green mask */
+ (void) WriteBlobLSBLong(image,0x000000ffL); /* Blue mask */
+ (void) WriteBlobLSBLong(image,0xff000000UL); /* Alpha mask */
+ (void) WriteBlobLSBLong(image,0x00000001L); /* CSType==Calib. RGB */
+ (void) WriteBlobLSBLong(image,
+ (long) image->chromaticity.red_primary.x*0x3ffffff);
+ (void) WriteBlobLSBLong(image,
+ (long) image->chromaticity.red_primary.y*0x3ffffff);
+ (void) WriteBlobLSBLong(image,
+ (long) (1.000f-(image->chromaticity.red_primary.x
+ +image->chromaticity.red_primary.y)*0x3ffffff));
+ (void) WriteBlobLSBLong(image,
+ (long) image->chromaticity.green_primary.x*0x3ffffff);
+ (void) WriteBlobLSBLong(image,
+ (long) image->chromaticity.green_primary.y*0x3ffffff);
+ (void) WriteBlobLSBLong(image,
+ (long) (1.000f-(image->chromaticity.green_primary.x
+ +image->chromaticity.green_primary.y)*0x3ffffff));
+ (void) WriteBlobLSBLong(image,
+ (long) image->chromaticity.blue_primary.x*0x3ffffff);
+ (void) WriteBlobLSBLong(image,
+ (long) image->chromaticity.blue_primary.y*0x3ffffff);
+ (void) WriteBlobLSBLong(image,
+ (long) (1.000f-(image->chromaticity.blue_primary.x
+ +image->chromaticity.blue_primary.y)*0x3ffffff));
+
+ (void) WriteBlobLSBLong(image,(long) bmp_info.gamma_scale.x*0xffff);
+ (void) WriteBlobLSBLong(image,(long) bmp_info.gamma_scale.y*0xffff);
+ (void) WriteBlobLSBLong(image,(long) bmp_info.gamma_scale.z*0xffff);
+ if ((image->rendering_intent != UndefinedIntent) ||
+ (color_profile_length != 0))
+ {
+ long
+ intent;
+
+ switch ((int) image->rendering_intent)
+ {
+ case SaturationIntent:
+ {
+ intent=LCS_GM_BUSINESS;
+ break;
+ }
+ case RelativeIntent:
+ {
+ intent=LCS_GM_GRAPHICS;
+ break;
+ }
+ case PerceptualIntent:
+ {
+ intent=LCS_GM_IMAGES;
+ break;
+ }
+ case AbsoluteIntent:
+ {
+ intent=LCS_GM_ABS_COLORIMETRIC;
+ break;
+ }
+ default:
+ {
+ intent=0;
+ break;
+ }
+ }
+ (void) WriteBlobLSBLong(image,intent);
+ (void) WriteBlobLSBLong(image,0x0); /* dummy profile data */
+ (void) WriteBlobLSBLong(image,0x0); /* dummy profile length */
+ (void) WriteBlobLSBLong(image,0x0); /* reserved */
+ }
+ }
+ if (image->storage_class == PseudoClass)
+ {
+ unsigned char
+ *bmp_colormap;
+
+ /*
+ Dump colormap to file.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Colormap: %u entries",image->colors);
+ bmp_colormap=MagickAllocateArray(unsigned char *,4,
+ (size_t) (1L << bmp_info.bits_per_pixel));
+ if (bmp_colormap == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(pixels);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ q=bmp_colormap;
+ for (i=0; i < (long) Min(image->colors,bmp_info.number_colors); i++)
+ {
+ *q++=ScaleQuantumToChar(image->colormap[i].blue);
+ *q++=ScaleQuantumToChar(image->colormap[i].green);
+ *q++=ScaleQuantumToChar(image->colormap[i].red);
+ if (type > 2)
+ *q++=(Quantum) 0x0;
+ }
+ for ( ; i < (1L << bmp_info.bits_per_pixel); i++)
+ {
+ *q++=(Quantum) 0x0;
+ *q++=(Quantum) 0x0;
+ *q++=(Quantum) 0x0;
+ if (type > 2)
+ *q++=(Quantum) 0x0;
+ }
+ if (type <= 2)
+ (void) WriteBlob(image,3*(1L << bmp_info.bits_per_pixel),
+ (char *) bmp_colormap);
+ else
+ (void) WriteBlob(image,4*(1L << bmp_info.bits_per_pixel),
+ (char *) bmp_colormap);
+ MagickFreeMemory(bmp_colormap);
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Pixels: %lu bytes",bmp_info.image_size);
+ (void) WriteBlob(image,bmp_info.image_size,(char *) pixels);
+ MagickFreeMemory(pixels);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ return(True);
+}
diff --git a/coders/cals.c b/coders/cals.c
new file mode 100644
index 0000000..74df0fa
--- /dev/null
+++ b/coders/cals.c
@@ -0,0 +1,621 @@
+/*
+% Copyright (C) 2009 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC AAA L SSSSS %
+% C A A L SS %
+% C AAAAA L SSS %
+% C A A L SS %
+% CCCC A A LLLLL SSSSS %
+% %
+% %
+% Read/Write CALS (CALS type 1) format %
+% %
+% %
+% Software Design %
+% John Sergeant %
+% May 2009 %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/compress.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+/*
+ Write an unsigned long to file with Intel/LSB ordering
+*/
+static void CALS_WriteIntelULong(FILE *file,unsigned long ul)
+{
+ fputc((unsigned char)ul,file);
+ fputc((unsigned char)(ul >> 8),file);
+ fputc((unsigned char)(ul >> 16),file);
+ fputc((unsigned char)(ul >> 24),file);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s C A L S %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsCALS returns MagickTrue if the image format type, identified by the
+% magick string, is CAL.
+%
+% The format of the IsCALS method is:
+%
+% unsigned int IsCALS(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsCALS returns MagickTrue if the image format type is CAL.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static MagickBool IsCALS(const unsigned char *magick,const size_t length)
+{
+ if (length < 132)
+ return(MagickFalse);
+ if (LocaleNCompare((char *) (magick),"version: MIL-STD-1840",21) == 0)
+ return(MagickTrue);
+ if (LocaleNCompare((char *) (magick),"srcdocid:",9) == 0)
+ return(MagickTrue);
+ if (LocaleNCompare((char *) (magick),"rorient:",8) == 0)
+ return(MagickTrue);
+ return(MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d C A L S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadCALSImage reads a CALS type 1 image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadCALSImage method is:
+%
+% Image *ReadCALSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadCALSImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadCALSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ char
+ record[129];
+
+ unsigned long
+ status,
+ width,
+ height,
+ rtype,
+ orient,
+ density;
+
+ char
+ filename[MaxTextExtent];
+
+ FILE
+ *file;
+
+ unsigned long
+ byte_count_pos,
+ strip_off_pos,
+ flen;
+
+ int
+ c;
+
+ ImageInfo
+ *clone_info;
+
+ MagickPassFail
+ file_write_status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Scan CAL header, record by record, looking for mandatory fields
+ */
+ rtype = 1;
+ width = height = 0;
+ orient = 1;
+ density = 200;
+ record[128]=0;
+ for (y = 0; y < 16; y++)
+ {
+ if (ReadBlob(image,128,(char *) record) != 128)
+ break;
+ if (LocaleNCompare(record,"rtype:",6) == 0)
+ { /* rtype */
+ if (sscanf(record+6,"%ld",&rtype) != 1)
+ {
+ rtype = 0;
+ break;
+ }
+ }
+ else
+ if (LocaleNCompare(record,"rorient:",8) == 0)
+ { /* rorient */
+ unsigned long
+ pel_path_rot,
+ line_rot;
+
+ pel_path_rot = line_rot = 0;
+ if (sscanf(record+8,"%ld,%ld",&pel_path_rot,&line_rot) != 2)
+ {
+ orient = 0;
+ break;
+ }
+ switch (pel_path_rot)
+ {
+ case 90:
+ orient = 5;
+ break;
+ case 180:
+ orient = 3;
+ break;
+ case 270:
+ orient = 7;
+ break;
+ default:
+ orient = 1;
+ }
+ if (line_rot == 90) orient++;
+ }
+ else
+ if (LocaleNCompare(record,"rpelcnt:",8) == 0)
+ { /* replcnt */
+ if (sscanf(record+8,"%ld,%ld",&width,&height) != 2)
+ {
+ width = 0;
+ height = 0;
+ break;
+ }
+ }
+ else
+ if (LocaleNCompare(record,"rdensty:",8) == 0)
+ { /* rdensty */
+ if (sscanf(record+8,"%ld",&density) != 1)
+ {
+ density = 0;
+ break;
+ }
+ if (!density) density = 200;
+ }
+ }
+ if ((!width) || (!height) || (rtype != 1) || (!orient) || (!density) )
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Dimensions %lux%lu",width,height);
+
+ /* Create TIFF wrapper to handle file data using TIFF library */
+ file=AcquireTemporaryFileStream(filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ ThrowReaderTemporaryFileException(filename);
+ file_write_status=MagickFail;
+ do
+ {
+ /* Intel TIFF with IFD at offset 8 - IFD has 14 records */
+ fwrite("\111\111\052\000\010\000\000\000\016\000",1,10,file);
+ /* New sub image - normal type */
+ fwrite("\376\000\003\000\001\000\000\000\000\000\000\000",1,12,file);
+ /* Image width */
+ fwrite("\000\001\004\000\001\000\000\000",1,8,file);
+ CALS_WriteIntelULong(file,width);
+ /* Image height */
+ fwrite("\001\001\004\000\001\000\000\000",1,8,file);
+ CALS_WriteIntelULong(file,height);
+ /* 1 bit per sample */
+ fwrite("\002\001\003\000\001\000\000\000\001\000\000\000",1,12,file);
+ /* CCITT Group 4 compression */
+ fwrite("\003\001\003\000\001\000\000\000\004\000\000\000",1,12,file);
+ /* Photometric interpretation MAX BLACK */
+ fwrite("\006\001\003\000\001\000\000\000\000\000\000\000",1,12,file);
+ /* Strip offset */
+ fwrite("\021\001\003\000\001\000\000\000",1,8,file);
+ strip_off_pos = 10 + (12 * 14) + 4 + 8;
+ CALS_WriteIntelULong(file,strip_off_pos);
+ /* Orientation */
+ fwrite("\022\001\003\000\001\000\000\000",1,8,file);
+ CALS_WriteIntelULong(file,orient);
+ /* 1 sample per pixel */
+ fwrite("\025\001\003\000\001\000\000\000\001\000\000\000",1,12,file);
+ /* Rows per strip (same as height) */
+ fwrite("\026\001\004\000\001\000\000\000",1,8,file);
+ CALS_WriteIntelULong(file,height);
+ /* Strip byte count */
+ fwrite("\027\001\004\000\001\000\000\000\000\000\000\000",1,12,file);
+ byte_count_pos = ftell(file)-4;
+ /* X resolution */
+ fwrite("\032\001\005\000\001\000\000\000",1,8,file);
+ CALS_WriteIntelULong(file,strip_off_pos-8);
+ /* Y resolution */
+ fwrite("\033\001\005\000\001\000\000\000",1,8,file);
+ CALS_WriteIntelULong(file,strip_off_pos-8);
+ /* Resolution unit is inch */
+ fwrite("\050\001\003\000\001\000\000\000\002\000\000\000",1,12,file);
+ /* Offset to next IFD ie end of images */
+ fwrite("\000\000\000\000",1,4,file);
+ /* Write X/Y resolution as rational data */
+ CALS_WriteIntelULong(file,density);
+ CALS_WriteIntelULong(file,1);
+
+ /* Copy image stream data */
+ flen = 0;
+ c=ReadBlobByte(image);
+ while (c != EOF)
+ {
+ flen++;
+ (void) fputc(c,file);
+ c=ReadBlobByte(image);
+ }
+
+ /* Return to correct location and output strip byte count */
+ if (fseek(file,byte_count_pos,SEEK_SET) != 0)
+ break;
+ CALS_WriteIntelULong(file,flen);
+ fflush(file);
+ if (ferror(file))
+ break;
+ file_write_status=MagickPass;
+ } while (0);
+ (void) fclose(file);
+ if (file_write_status != MagickPass)
+ {
+ (void) LiberateTemporaryFile(filename);
+ ThrowReaderException(CoderError,UnableToWriteTemporaryFile,image);
+ }
+ DestroyImage(image);
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ FormatString(clone_info->filename,"tiff:%.1024s",filename);
+ image=ReadImage(clone_info,exception);
+ (void) LiberateTemporaryFile(filename);
+ DestroyImageInfo(clone_info);
+ if (image != (Image *) NULL)
+ {
+ (void) strlcpy(image->filename,image_info->filename,
+ sizeof(image->filename));
+ (void) strlcpy(image->magick_filename,image_info->filename,
+ sizeof(image->magick_filename));
+ (void) strlcpy(image->magick,"CALS",sizeof(image->magick));
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e C A L S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteCALSImage writes an image in the CALS type I image format
+%
+% The format of the WriteCALSImage method is:
+%
+% unsigned int WriteCALSImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteCALSImage return MagickTrue if the image is written.
+% MagickFail is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+%
+*/
+static void WriteCALSRecord(Image *image,const char *data)
+{
+ int
+ i;
+
+ const char
+ *p;
+
+ char
+ pad[128];
+
+ i = 0;
+ if (data)
+ {
+ /* Limit output to 128 chars */
+ p=data;
+ while ((i < 128) && (p[i])) i++;
+ WriteBlob(image,i,data);
+ }
+ if (i < 128)
+ {
+ /* Pad record to 128 characters using trailing spaces */
+ i=128-i;
+ memset(pad,' ',i);
+ WriteBlob(image,i,pad);
+ }
+}
+
+static MagickPassFail WriteCALSImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[MaxTextExtent];
+
+ int
+ i;
+
+ long
+ sans;
+
+ unsigned long
+ density;
+
+ int
+ orx,
+ ory;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Validate input image
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ /*
+ Open output image file.
+ */
+ if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Create standard header
+ */
+ WriteCALSRecord(image,"srcdocid: NONE");
+ WriteCALSRecord(image,"dstdocid: NONE");
+ WriteCALSRecord(image,"txtfilid: NONE");
+ WriteCALSRecord(image,"figid: NONE");
+ WriteCALSRecord(image,"srcgph: NONE");
+ WriteCALSRecord(image,"docls: NONE");
+ WriteCALSRecord(image,"rtype: 1");
+ /* orientation based on input or default of upright */
+ switch (image->orientation)
+ {
+ case TopRightOrientation:
+ orx=180;
+ ory=270;
+ break;
+ case BottomRightOrientation:
+ orx=180;
+ ory=90;
+ break;
+ case BottomLeftOrientation:
+ orx=0;
+ ory=90;
+ break;
+ case LeftTopOrientation:
+ orx=270;
+ ory=0;
+ break;
+ case RightTopOrientation:
+ orx=270;
+ ory=180;
+ break;
+ case RightBottomOrientation:
+ orx=90;
+ ory=180;
+ break;
+ case LeftBottomOrientation:
+ orx=90;
+ ory=0;
+ break;
+ default:
+ orx=0;
+ ory=270;
+ }
+ FormatString(buffer,"rorient: %03d,%03d",orx,ory);
+ WriteCALSRecord(image,buffer);
+ /* pixel counts based on columns/rows of input */
+ FormatString(buffer,"rpelcnt: %06ld,%06ld",image->columns,image->rows);
+ WriteCALSRecord(image,buffer);
+ /* density based on input density or default of 200 */
+ density=200;
+ if (image_info->density != (char *) NULL)
+ (void) GetGeometry(image_info->density,&sans,&sans,&density,&density);
+ FormatString(buffer,"rdensty: %04ld",density);
+ WriteCALSRecord(image,buffer);
+ WriteCALSRecord(image,"notes: NONE");
+
+ /*
+ Pad header to make 16 records / 2048 bytes
+ */
+ memset(buffer,' ',128);
+ for (i = 0; i < 5; i++)
+ if (WriteBlob(image,128,buffer) != 128)
+ status=MagickFail;
+
+ /*
+ Encode data to Group 4
+ */
+ if (MagickFail != status)
+ {
+ unsigned char
+ *blob;
+
+ size_t
+ blob_length;
+
+ blob=ImageToHuffman2DBlob(image,image_info,&blob_length,&image->exception);
+ if (blob == (unsigned char *) NULL)
+ status=MagickFail;
+
+ if (MagickFail != status)
+ {
+ if (WriteBlob(image,blob_length,blob) != blob_length)
+ status=MagickFail;
+ }
+ MagickFreeMemory(blob);
+ }
+
+ /*
+ Close output file and return image
+ */
+ CloseBlob(image);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r C A L S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterCALSImage adds attributes for the CALS image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterCALSImage method is:
+%
+% RegisterCALSImage(void)
+%
+*/
+ModuleExport void RegisterCALSImage(void)
+{
+ MagickInfo
+ *entry;
+
+ const char
+ *description = "Continuous Acquisition and Life-cycle Support Type 1 image",
+ *module = "CALS",
+ *note = "Specified in MIL-R-28002 and MIL-PRF-28002";
+
+ entry=SetMagickInfo("CAL");
+ entry->decoder=(DecoderHandler) ReadCALSImage;
+ entry->encoder=(EncoderHandler) WriteCALSImage;
+ entry->magick=(MagickHandler) IsCALS;
+ entry->adjoin=MagickFalse;
+ entry->seekable_stream=MagickTrue;
+ entry->description=description;
+ entry->note=note;
+ entry->module=module;
+ entry->stealth=MagickTrue;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("CALS");
+ entry->decoder=(DecoderHandler) ReadCALSImage;
+ entry->encoder=(EncoderHandler) WriteCALSImage;
+ entry->magick=(MagickHandler) IsCALS;
+ entry->adjoin=MagickFalse;
+ entry->seekable_stream=MagickTrue;
+ entry->description=description;
+ entry->note=note;
+ entry->module=module;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r C A L S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterCALSImage removes format registrations made by the
+% CAL module from the list of supported formats.
+%
+% The format of the UnregisterCALSImage method is:
+%
+% UnregisterCALSImage(void)
+%
+*/
+ModuleExport void UnregisterCALSImage(void)
+{
+ (void) UnregisterMagickInfo("CAL");
+ (void) UnregisterMagickInfo("CALS");
+}
diff --git a/coders/caption.c b/coders/caption.c
new file mode 100644
index 0000000..5f69335
--- /dev/null
+++ b/coders/caption.c
@@ -0,0 +1,245 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC AAA PPPP TTTTT IIIII OOO N N %
+% C A A P P T I O O NN N %
+% C AAAAA PPPP T I O O N N N %
+% C A A P T I O O N NN %
+% CCCC A A P T IIIII OOO N N %
+% %
+% %
+% Read Text Caption. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% February 2002 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/magick.h"
+#include "magick/render.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d C A P T I O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadCAPTIONImage reads a CAPTION image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadCAPTIONImage method is:
+%
+% Image *ReadCAPTIONImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadCAPTIONImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadCAPTIONImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ char
+ *caption,
+ geometry[MaxTextExtent];
+
+ DrawInfo
+ *draw_info;
+
+ Image
+ *image;
+
+ register char
+ *p,
+ *q;
+
+ register long
+ i;
+
+ TypeMetric
+ metrics;
+
+ unsigned int
+ status;
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if (image->columns == 0)
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+ if (*image_info->filename != '@')
+ caption=AllocateString(image_info->filename);
+ else
+ {
+ unsigned long
+ length;
+
+ /*
+ Read caption from file.
+ */
+ (void) strlcpy(image->filename,image_info->filename+1,MaxTextExtent);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ length=MaxTextExtent;
+ caption=MagickAllocateMemory(char *,length);
+ p=caption;
+ if (caption != (char *) NULL)
+ while (ReadBlobString(image,p) != (char *) NULL)
+ {
+ p+=strlen(p);
+ if ((p-caption+MaxTextExtent+1) < (long) length)
+ continue;
+ length<<=1;
+ MagickReallocMemory(char *,caption,length);
+ if (caption == (char *) NULL)
+ break;
+ p=caption+strlen(caption);
+ }
+ if (caption == (char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ CloseBlob(image);
+ }
+ /*
+ Format caption.
+ */
+ draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
+ draw_info->fill=image_info->pen;
+ draw_info->text=AllocateString(caption);
+ p=caption;
+ q=draw_info->text;
+ for (i=0; *p != '\0'; p++)
+ {
+ *q++=(*p);
+ *q='\0';
+ status=GetTypeMetrics(image,draw_info,&metrics);
+ if (status == False)
+ {
+ DestroyDrawInfo(draw_info);
+ MagickFreeMemory(caption);
+ ThrowReaderException(TypeError,UnableToGetTypeMetrics,image);
+ }
+ if ((metrics.width+metrics.max_advance/2) < image->columns)
+ continue;
+ for (p--; !isspace((int) *p) && (p > caption); p--);
+ *p++='\n';
+ q=draw_info->text;
+ i++;
+ }
+ if (image->rows == 0)
+ image->rows=(unsigned long) ((i+1)*(metrics.ascent-metrics.descent));
+ (void) SetImage(image,OpaqueOpacity);
+ /*
+ Draw caption.
+ */
+ (void) CloneString(&draw_info->text,caption);
+ FormatString(geometry,"+%g+%g",metrics.max_advance/4,metrics.ascent);
+ draw_info->geometry=AllocateString(geometry);
+ (void) AnnotateImage(image,draw_info);
+ DestroyDrawInfo(draw_info);
+ MagickFreeMemory(caption);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r C A P T I O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterCAPTIONImage adds attributes for the CAPTION image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterCAPTIONImage method is:
+%
+% RegisterCAPTIONImage(void)
+%
+*/
+ModuleExport void RegisterCAPTIONImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("CAPTION");
+ entry->decoder=(DecoderHandler) ReadCAPTIONImage;
+ entry->adjoin=False;
+ entry->description="Image caption";
+ entry->module="CAPTION";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r C A P T I O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterCAPTIONImage removes format registrations made by the
+% CAPTION module from the list of supported formats.
+%
+% The format of the UnregisterCAPTIONImage method is:
+%
+% UnregisterCAPTIONImage(void)
+%
+*/
+ModuleExport void UnregisterCAPTIONImage(void)
+{
+ (void) UnregisterMagickInfo("CAPTION");
+}
diff --git a/coders/cineon.c b/coders/cineon.c
new file mode 100644
index 0000000..4bfd21a
--- /dev/null
+++ b/coders/cineon.c
@@ -0,0 +1,1490 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC IIIII N N EEEEE OOO N N %
+% C I NN N E O O NN N %
+% C I N N N EEEE O O N N N %
+% C I N NN E O O N NN %
+% CCCC IIIII N N EEEEE OOO N N %
+% %
+% %
+% Read/Write Kodak Cineon Image Format. %
+% Cineon Image Format is similar to SMTPE DPX %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% May 2007 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Cineon image file format draft is available at
+% http://www.cineon.com/ff_draft.php.
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/bit_stream.h"
+#include "magick/colorspace.h"
+#include "magick/enum_strings.h"
+#include "magick/pixel_cache.h"
+#include "magick/magick_endian.h"
+#include "magick/error.h"
+#include "magick/list.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/profile.h"
+#include "magick/utility.h"
+
+/*
+ Forward declaractions.
+*/
+static unsigned int
+ WriteCINEONImage(const ImageInfo *,Image *);
+
+typedef char ASCII;
+typedef magick_uint8_t U8;
+typedef magick_uint32_t U32;
+typedef magick_int32_t S32;
+typedef union _R32_u
+{
+ magick_uint32_t u;
+ float f;
+} R32;
+
+#define SET_UNDEFINED_U8(value) (value=0xFFU)
+#define SET_UNDEFINED_U32(value) (value=0xFFFFFFFFU)
+#define SET_UNDEFINED_S32(value) (value=0x80000000)
+
+#define SET_UNDEFINED_R32(value) (value.u=0x7F800000U);
+#define SET_UNDEFINED_ASCII(value) ((void) memset(value,0,sizeof(value)))
+
+#define IS_UNDEFINED_U8(value) (value == ((U8) 0xFFU))
+#define IS_UNDEFINED_U32(value) (value == ((U32) 0xFFFFFFFFU))
+#define IS_UNDEFINED_S32(value) (value == ((S32) 0x80000000))
+#define IS_UNDEFINED_R32(value) (value.u == ((U32) 0x7F800000U))
+#define IS_UNDEFINED_ASCII(value) (!(value[0] > 0))
+
+typedef struct _CineonFileInfo
+{
+ U32 magic; /* Magick number (0x802A5FD7) */
+ U32 image_data_offset; /* Offset to image data in bytes */
+ U32 generic_section_length; /* Generic section header length in bytes */
+ U32 industry_section_length; /* Industry specific header length in bytes */
+ U32 user_defined_length; /* User defined header length in bytes */
+ U32 file_size; /* Total image file size in bytes */
+ ASCII header_format_version[8]; /* Version number of header format */
+ ASCII image_filename[100]; /* Image filename */
+ ASCII creation_date[12]; /* Creation date: yyyy:mm:dd */
+ ASCII creation_time[12]; /* Creation time: hh:mm:ssLTZ */
+ ASCII reserved[36]; /* Reserved for future use */
+} CineonFileInfo;
+
+typedef struct _CineonImageChannel
+{
+ U8 designator_byte_0; /* 0 = universal metric */
+ U8 designator_byte_1; /* */
+ U8 bits_per_sample; /* Bit depth */
+ U8 unused;
+ U32 pixels_per_line; /* Pixels per line (columns) */
+ U32 lines_per_image; /* Lines per image (rows) */
+ R32 reference_low_data_code; /* Reference low data code value */
+ R32 reference_low_quantity; /* Low quantity represented */
+ R32 reference_high_data_code; /* Reference high data code value */
+ R32 reference_high_quantity; /* Reference high quantity represented */
+} DPXImageChannel;
+
+typedef struct _CineonImageInfo
+{
+ U8 orientation; /* Image orientation */
+ U8 channels; /* Number of image channels (1-8) */
+ U8 pad[2]; /* Unused (2 byte space for word allignment */
+ DPXImageChannel channel_info[8]; /* Description of channels */
+ R32 white_point[2]; /* White point (color temperature) - x,y pair */
+ R32 red_primary_chromaticity[2]; /* Red primary chromaticity - x,y pair */
+ R32 green_primary_chromaticity[2]; /* Green primary chromaticity - x,y pair */
+ R32 blue_primary_chromaticity[2]; /* Blue primary chromaticity - x,y pair */
+ ASCII label_text[200]; /* Label text */
+ ASCII reserved[28]; /* Reserved for future use */
+ /* Image Data Format Information */
+ U8 data_interleave; /* Data interleave */
+ U8 packing; /* Packing method */
+ U8 sign; /* Data sign: 0=unsigned, 1=signed */
+ U8 sense; /* Image sense: 0=positive, 1=negative */
+ U32 eol_pad; /* End of line padding */
+ U32 eoc_pad; /* End of channel padding */
+ ASCII reserved2[20]; /* Reserved for future use */
+} CineonImageInfo;
+
+typedef struct _CineonImageOriginationInfo
+{
+ S32 x_offset; /* X offset */
+ S32 y_offset; /* Y offset */
+ ASCII source_image_filename[100];/* Source image filename */
+ ASCII creation_date[12]; /* Creation date: yyyy:mm:dd */
+ ASCII creation_time[12]; /* Creation time: hh:mm:ssLTZ */
+ ASCII input_device[64]; /* Input device */
+ ASCII input_device_model[32]; /* Input device model number */
+ ASCII input_device_serial[32]; /* Input device serial number */
+ R32 input_device_pitch_x; /* Input device pitch for X (samples/mm) */
+ R32 input_device_pitch_y; /* Input device pitch for Y (samples/mm) */
+ R32 gamma; /* Image gamma of capture device */
+ ASCII reserved[40]; /* Reserved for future use */
+} CineonImageOriginationInfo;
+
+typedef struct _CineonFilmInfo
+{
+ U8 film_mfg_id_code; /* Film mfg. ID code (2 digits from film edge code) */
+ U8 film_type; /* Film type (2 digits from film edge code) */
+ U8 perfs_offset; /* Offset in perfs (2 digits from film edge code) */
+ U8 unused; /* Unused, for word allignment */
+ U32 prefix; /* Prefix (6 digits from film edge code) */
+ U32 count; /* Count (4 digits from film edge code) */
+ ASCII format[32]; /* Format -- e.g. Academy */
+ U32 frame_position; /* Frame position in sequence */
+ R32 frame_rate; /* Frame rate of original (frames/s) */
+ ASCII frame_id[32]; /* Frame identification - e.g. keyframe */
+ ASCII slate_info[200]; /* Slate information */
+ ASCII reserved[740]; /* Reserved for future use */
+} CineonFilmInfo;
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s C I N E O N %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsCINEON() returns True if the image format type, identified by the magick
+% string, is CINEON.
+%
+% The format of the IsCINEON method is:
+%
+% unsigned int IsCINEON(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsCINEON(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (memcmp(magick,"\200\052\137\327",4) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d C I N E O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadCINEONImage() reads an CINEON X image file and returns it. It allocates
+% the memory necessary for the new Image structure and returns a point to the
+% new image.
+%
+% The format of the ReadCINEONImage method is:
+%
+% Image *ReadCINEONImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define LogSetImageAttribute(name,value) \
+{ \
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), \
+ "Attribute \"%s\" set to \"%s\"", \
+ name,value); \
+}
+/*
+ Null terminate ASCII fields which provide space for a terminating
+ NULL.
+*/
+#define NULLTerminateASCIIField(field) \
+{ \
+ field[sizeof(field)-1]='\0'; \
+}
+/*
+ Can't use strlcpy() since strlcpy() only handles NULL terminated
+ strings. This is not so necessary due to use of
+ NULLTerminateASCIIField() above.
+*/
+#define StringToAttribute(image,name,member) \
+{ \
+ char \
+ buffer_[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_ASCII(member)) \
+ { \
+ (void) strncpy(buffer_,member,Min(sizeof(member),MaxTextExtent)); \
+ buffer_[Min(sizeof(member),MaxTextExtent-1)]='\0'; \
+ (void) SetImageAttribute(image,name,buffer_); \
+ LogSetImageAttribute(name,buffer_); \
+ } \
+}
+#define U8ToAttribute(image,name,member) \
+{ \
+ char \
+ buffer[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_U8(member)) \
+ { \
+ FormatString(buffer,"%u",(unsigned int) member); \
+ (void) SetImageAttribute(image,name,buffer); \
+ LogSetImageAttribute(name,buffer); \
+ } \
+}
+#define U32ToAttribute(image,name,member) \
+{ \
+ char \
+ buffer[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_U32(member)) \
+ { \
+ FormatString(buffer,"%u",member); \
+ (void) SetImageAttribute(image,name,buffer); \
+ LogSetImageAttribute(name,buffer); \
+ } \
+}
+#define R32ToAttribute(image,name,member) \
+{ \
+ char \
+ buffer[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_R32(member)) \
+ { \
+ FormatString(buffer,"%g",member.f); \
+ (void) SetImageAttribute(image,name,buffer); \
+ LogSetImageAttribute(name,buffer); \
+ } \
+}
+#define S32ToAttribute(image,name,member) \
+{ \
+ char \
+ buffer[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_S32(member)) \
+ { \
+ FormatString(buffer,"%d",member); \
+ (void) SetImageAttribute(image,name,buffer); \
+ LogSetImageAttribute(name,buffer); \
+ } \
+}
+static void SwabCineonFileInfo(CineonFileInfo *file_info)
+{
+ MagickSwabUInt32(&file_info->magic);
+ MagickSwabUInt32(&file_info->image_data_offset);
+ MagickSwabUInt32(&file_info->generic_section_length);
+ MagickSwabUInt32(&file_info->industry_section_length);
+ MagickSwabUInt32(&file_info->user_defined_length);
+ MagickSwabUInt32(&file_info->file_size);
+}
+
+static void SwabCineonImageInfo(CineonImageInfo *image_info)
+{
+ size_t
+ i;
+
+ for (i=0 ;
+ i < Min((size_t) image_info->channels,
+ (sizeof(image_info->channel_info) /
+ sizeof(image_info->channel_info[0])));
+ i++)
+ {
+ MagickSwabUInt32(&image_info->channel_info[i].pixels_per_line);
+ MagickSwabUInt32(&image_info->channel_info[i].lines_per_image);
+ MagickSwabFloat(&image_info->channel_info[i].reference_low_data_code.f);
+ MagickSwabFloat(&image_info->channel_info[i].reference_low_quantity.f);
+ MagickSwabFloat(&image_info->channel_info[i].reference_high_data_code.f);
+ MagickSwabFloat(&image_info->channel_info[i].reference_high_quantity.f);
+ }
+
+ MagickSwabFloat(&image_info->white_point[0].f);
+ MagickSwabFloat(&image_info->white_point[1].f);
+ MagickSwabFloat(&image_info->red_primary_chromaticity[0].f);
+ MagickSwabFloat(&image_info->red_primary_chromaticity[1].f);
+ MagickSwabFloat(&image_info->green_primary_chromaticity[0].f);
+ MagickSwabFloat(&image_info->green_primary_chromaticity[1].f);
+ MagickSwabFloat(&image_info->blue_primary_chromaticity[0].f);
+ MagickSwabFloat(&image_info->blue_primary_chromaticity[1].f);
+ MagickSwabUInt32(&image_info->eol_pad);
+ MagickSwabUInt32(&image_info->eoc_pad);
+}
+
+static void SwabCineonImageOriginationInfo(CineonImageOriginationInfo *image_info)
+{
+ MagickSwabUInt32((U32 *) &image_info->x_offset);
+ MagickSwabUInt32((U32 *) &image_info->y_offset);
+ MagickSwabFloat(&image_info->input_device_pitch_x.f);
+ MagickSwabFloat(&image_info->input_device_pitch_y.f);
+ MagickSwabFloat(&image_info->gamma.f);
+}
+
+static void SwabCineonFilmInfo(CineonFilmInfo *mp_info)
+{
+ MagickSwabUInt32(&mp_info->prefix);
+ MagickSwabUInt32(&mp_info->count);
+ MagickSwabUInt32(&mp_info->frame_position);
+ MagickSwabFloat(&mp_info->frame_rate.f);
+}
+
+static OrientationType
+CineonOrientationToOrientationType(const unsigned int orientation)
+{
+ OrientationType
+ orientation_type = UndefinedOrientation;
+
+ switch (orientation)
+ {
+ case 0:
+ orientation_type=TopLeftOrientation;
+ break;
+ case 1:
+ orientation_type=TopRightOrientation;
+ break;
+ case 2:
+ orientation_type=BottomLeftOrientation;
+ break;
+ case 3:
+ orientation_type=BottomRightOrientation;
+ break;
+ case 4:
+ orientation_type=LeftTopOrientation;
+ break;
+ case 5:
+ orientation_type=RightTopOrientation;
+ break;
+ case 6:
+ orientation_type=LeftBottomOrientation;
+ break;
+ case 7:
+ orientation_type=RightBottomOrientation;
+ break;
+ }
+
+ return orientation_type;
+}
+
+static U8 OrientationTypeToCineonOrientation(const OrientationType orientation_type)
+{
+ U8
+ orientation = 0U;
+
+ switch (orientation_type)
+ {
+ case UndefinedOrientation:
+ case TopLeftOrientation:
+ orientation=0U;
+ break;
+ case TopRightOrientation:
+ orientation=1U;
+ break;
+ case BottomLeftOrientation:
+ orientation=2U;
+ break;
+ case BottomRightOrientation:
+ orientation=3U;
+ break;
+ case LeftTopOrientation:
+ orientation=4U;
+ break;
+ case RightTopOrientation:
+ orientation=5U;
+ break;
+ case LeftBottomOrientation:
+ orientation=6U;
+ break;
+ case RightBottomOrientation:
+ orientation=7U;
+ break;
+ }
+ return orientation;
+}
+
+static Image *ReadCINEONImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ CineonFileInfo
+ cin_file_info;
+
+ CineonImageInfo
+ cin_image_info;
+
+ CineonImageOriginationInfo
+ cin_source_info;
+
+ CineonFilmInfo
+ cin_mp_info;
+
+ Image
+ *image;
+
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ size_t
+ offset;
+
+ unsigned int
+ channel,
+ max_bits_per_sample,
+ max_lines_per_image,
+ max_pixels_per_line,
+ number_of_channels;
+
+ MagickPassFail
+ status;
+
+ MagickBool
+ swab=MagickFalse;
+
+ unsigned long
+ pixels_offset;
+
+ unsigned char
+ *scandata;
+
+ void
+ *scanline;
+
+ const char *
+ definition_value;
+
+ BitStreamReadHandle
+ bit_stream;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+#if !defined(WORDS_BIGENDIAN)
+ swab=MagickTrue;
+#endif /* !defined(WORDS_BIGENDIAN) */
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ /*
+ Read CINEON image.
+ */
+ offset=(ReadBlob(image,sizeof(cin_file_info),&cin_file_info));
+ if (offset != sizeof(cin_file_info))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (swab)
+ SwabCineonFileInfo(&cin_file_info);
+ NULLTerminateASCIIField(cin_file_info.header_format_version);
+ NULLTerminateASCIIField(cin_file_info.image_filename);
+ NULLTerminateASCIIField(cin_file_info.creation_date);
+ NULLTerminateASCIIField(cin_file_info.creation_time);
+ NULLTerminateASCIIField(cin_file_info.reserved);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File magic 0x%04X",cin_file_info.magic);
+
+ if (cin_file_info.magic != 0x802A5FD7U)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image offset %u, Generic length %u, Industry length %u, User length %u, File size %u",
+ cin_file_info.image_data_offset,
+ cin_file_info.generic_section_length,
+ cin_file_info.industry_section_length,
+ cin_file_info.user_defined_length,
+ cin_file_info.file_size);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Header format version \"%s\"", cin_file_info.header_format_version);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image file name \"%s\"", cin_file_info.image_filename);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Creation date \"%s\"", cin_file_info.creation_date);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Creation time \"%s\"", cin_file_info.creation_time);
+ /*
+ Place arbitary limit on user defined length.
+ */
+ if (cin_file_info.user_defined_length > 16777216U)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ StringToAttribute(image,"document",cin_file_info.image_filename);
+ StringToAttribute(image,"DPX:file.filename",cin_file_info.image_filename);
+ {
+ char
+ creation_datetime[26]; /* 12+1+12+1 */
+
+ (void) strlcpy(creation_datetime,cin_file_info.creation_date,
+ Min(sizeof(creation_datetime),sizeof(cin_file_info.creation_date)));
+ if (creation_datetime[0]!='\0')
+ (void) strlcat(creation_datetime,":",sizeof(creation_datetime));
+ (void) strlcat(creation_datetime,cin_file_info.creation_time,
+ Min(sizeof(creation_datetime),sizeof(creation_datetime)));
+ StringToAttribute(image,"timestamp",creation_datetime);
+ StringToAttribute(image,"DPX:file.creation.datetime",creation_datetime);
+ }
+
+ /*
+ Obtain offset to pixels.
+ */
+ pixels_offset=cin_file_info.image_data_offset & 0xffffffff;
+ if (pixels_offset < 712)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ /*
+ Read image information header.
+ */
+ offset += ReadBlob(image,sizeof(cin_image_info),&cin_image_info);
+ if (offset != (size_t) 712L)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (cin_image_info.channels >
+ (sizeof(cin_image_info.channel_info)/sizeof(cin_image_info.channel_info[0])))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (swab)
+ SwabCineonImageInfo(&cin_image_info);
+ NULLTerminateASCIIField(cin_image_info.label_text);
+ NULLTerminateASCIIField(cin_image_info.reserved);
+ NULLTerminateASCIIField(cin_image_info.reserved2);
+ number_of_channels=cin_image_info.channels;
+ if (number_of_channels >
+ (sizeof(cin_image_info.channel_info)/sizeof(cin_image_info.channel_info[0])))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ U8ToAttribute(image,"DPX:image.orientation",cin_image_info.orientation);
+ image->orientation=CineonOrientationToOrientationType(cin_image_info.orientation);
+ max_bits_per_sample=0;
+ max_pixels_per_line=0;
+ max_lines_per_image=0;
+ for (channel=0; channel < number_of_channels; channel++)
+ {
+ max_bits_per_sample=Max(max_bits_per_sample,
+ cin_image_info.channel_info[channel].bits_per_sample);
+ max_pixels_per_line=Max(max_pixels_per_line,
+ cin_image_info.channel_info[channel].pixels_per_line);
+ max_lines_per_image=Max(max_lines_per_image,
+ cin_image_info.channel_info[channel].lines_per_image);
+ }
+
+ image->depth=max_bits_per_sample;
+ image->columns=max_pixels_per_line;
+ image->rows=max_lines_per_image;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Columns %ld, Rows %ld, Channels %u",
+ image->columns, image->rows,
+ (unsigned int) cin_image_info.channels);
+ if (!IS_UNDEFINED_R32(cin_image_info.white_point[0]))
+ image->chromaticity.white_point.x = cin_image_info.white_point[0].f;
+ if (!IS_UNDEFINED_R32(cin_image_info.white_point[1]))
+ image->chromaticity.white_point.y = cin_image_info.white_point[1].f;
+ if (!IS_UNDEFINED_R32(cin_image_info.red_primary_chromaticity[0]))
+ image->chromaticity.red_primary.x = cin_image_info.red_primary_chromaticity[0].f;
+ if (!IS_UNDEFINED_R32(cin_image_info.red_primary_chromaticity[1]))
+ image->chromaticity.red_primary.y = cin_image_info.red_primary_chromaticity[1].f;
+ if (!IS_UNDEFINED_R32(cin_image_info.green_primary_chromaticity[0]))
+ image->chromaticity.green_primary.x = cin_image_info.green_primary_chromaticity[0].f;
+ if (!IS_UNDEFINED_R32(cin_image_info.green_primary_chromaticity[1]))
+ image->chromaticity.green_primary.y = cin_image_info.green_primary_chromaticity[1].f;
+ if (!IS_UNDEFINED_R32(cin_image_info.blue_primary_chromaticity[0]))
+ image->chromaticity.blue_primary.x = cin_image_info.blue_primary_chromaticity[0].f;
+ if (!IS_UNDEFINED_R32(cin_image_info.blue_primary_chromaticity[1]))
+ image->chromaticity.blue_primary.y = cin_image_info.blue_primary_chromaticity[1].f;
+ StringToAttribute(image,"DPX:file.project.name",cin_image_info.label_text);
+
+ /*
+ Read image origination header.
+ */
+ offset += ReadBlob(image,sizeof(cin_source_info),&cin_source_info);
+ if (offset != (size_t) 1024L)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (swab)
+ SwabCineonImageOriginationInfo(&cin_source_info);
+ NULLTerminateASCIIField(cin_source_info.source_image_filename);
+ NULLTerminateASCIIField(cin_source_info.creation_date);
+ NULLTerminateASCIIField(cin_source_info.creation_time);
+ NULLTerminateASCIIField(cin_source_info.input_device);
+ NULLTerminateASCIIField(cin_source_info.input_device_model);
+ NULLTerminateASCIIField(cin_source_info.input_device_serial);
+ S32ToAttribute(image,"DPX:source.x-offset",cin_source_info.x_offset);
+ S32ToAttribute(image,"DPX:source.y-offset",cin_source_info.y_offset);
+ StringToAttribute(image,"DPX:source.filename",cin_source_info.source_image_filename);
+ {
+ char
+ source_creation_datetime[MaxTextExtent];
+
+ source_creation_datetime[0]='\0';
+ (void) strlcat(source_creation_datetime,cin_file_info.creation_date,sizeof(cin_file_info.creation_date)+1);
+ if (source_creation_datetime[0]!='\0')
+ (void) strlcat(source_creation_datetime,":",sizeof(source_creation_datetime));
+ (void) strlcat(source_creation_datetime,cin_file_info.creation_time,sizeof(source_creation_datetime));
+ StringToAttribute(image,"DPX:source.creation.datetime",source_creation_datetime);
+ }
+ StringToAttribute(image,"DPX:source.device.name",cin_source_info.input_device);
+ StringToAttribute(image,"DPX:source.device.model",cin_source_info.input_device_model);
+ StringToAttribute(image,"DPX:source.device.serialnumber",cin_source_info.input_device_serial);
+ R32ToAttribute(image,"DPX:source.device.pitch.x",cin_source_info.input_device_pitch_x);
+ R32ToAttribute(image,"DPX:source.device.pitch.y",cin_source_info.input_device_pitch_y);
+ R32ToAttribute(image,"DPX:source.device.gamma",cin_source_info.gamma);
+
+ if ((pixels_offset >= 1024) && (cin_file_info.industry_section_length > 0))
+ {
+ /*
+ Read Motion-picture film information header.
+ */
+ offset += ReadBlob(image,sizeof(cin_mp_info),&cin_mp_info);
+ if (offset != (size_t) 2048L)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (swab)
+ SwabCineonFilmInfo(&cin_mp_info);
+ NULLTerminateASCIIField(cin_mp_info.format);
+ NULLTerminateASCIIField(cin_mp_info.frame_id);
+ NULLTerminateASCIIField(cin_mp_info.slate_info);
+ NULLTerminateASCIIField(cin_mp_info.reserved);
+ U8ToAttribute(image,"DPX:mp.film.manufacturer.id",cin_mp_info.film_mfg_id_code);
+ U8ToAttribute(image,"DPX:mp.film.type",cin_mp_info.film_type);
+ U8ToAttribute(image,"DPX:mp.perfs.offset",cin_mp_info.perfs_offset);
+ U32ToAttribute(image,"DPX:mp.prefix",cin_mp_info.prefix);
+ U32ToAttribute(image,"DPX:mp.count",cin_mp_info.count);
+ StringToAttribute(image,"DPX:mp.format",cin_mp_info.format);
+ U32ToAttribute(image,"DPX:mp.frame.position",cin_mp_info.frame_position);
+ R32ToAttribute(image,"DPX:mp.frame.rate",cin_mp_info.frame_rate);
+ StringToAttribute(image,"DPX:mp.frame.id",cin_mp_info.frame_id);
+ StringToAttribute(image,"DPX:mp.slate.info",cin_mp_info.slate_info);
+ }
+
+ if ((pixels_offset >= 2048) && (cin_file_info.user_defined_length > 0))
+ {
+ unsigned char
+ *user_data;
+
+ const size_t
+ block_size = 65536UL;
+
+ size_t
+ read_size,
+ user_data_length;
+
+ user_data_length=0UL;
+ user_data=(unsigned char *) NULL;
+ while (user_data_length < cin_file_info.user_defined_length)
+ {
+ read_size=Min(block_size,cin_file_info.user_defined_length-user_data_length);
+ MagickReallocMemory(unsigned char *,user_data,user_data_length+read_size);
+ if (user_data == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (ReadBlob(image,read_size,user_data+user_data_length) != read_size)
+ {
+ MagickFreeMemory(user_data);
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ user_data_length += read_size;
+ offset += read_size;
+ }
+ if (!SetImageProfile(image,"CINEONUSERDATA",user_data,user_data_length))
+ {
+ MagickFreeMemory(user_data);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ MagickFreeMemory(user_data);
+ }
+
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Read remainder of header.
+ */
+ for ( ; offset < pixels_offset ; offset++ )
+ if (ReadBlobByte(image) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading Cineon pixels starting at offset %ld",(long) TellBlob(image));
+
+ /*
+ Convert CINEON raster image to pixel packets.
+ */
+ {
+ size_t
+ scandata_bytes;
+
+ unsigned int
+ scale_to_short=0;
+
+ switch (number_of_channels)
+ {
+ case 1:
+ {
+ scandata_bytes=4;
+ scale_to_short=64;
+ scandata=MagickAllocateMemory(unsigned char *,scandata_bytes);
+ scanline=scandata;
+ MagickBitStreamInitializeRead(&bit_stream,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ /*
+ Packed 10 bit samples with 2 bit pad at end of 32-bit word.
+ */
+ scanline=scandata;
+ i=3;
+ for (x=(long) image->columns; x > 0; x--, i++)
+ {
+ if (i > 2)
+ {
+ scanline=scandata;
+ if (ReadBlobZC(image,scandata_bytes,&scanline) !=
+ scandata_bytes)
+ break;
+ MagickBitStreamInitializeRead(&bit_stream,scanline);
+ i=0;
+ }
+ q->red=q->green=q->blue=
+ ScaleShortToQuantum(MagickBitStreamMSBRead(&bit_stream,10)*scale_to_short);
+ q->opacity=0U;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(scandata);
+ break;
+ }
+ case 3:
+ {
+ scandata_bytes=image->columns*4;
+ scale_to_short=64;
+ scandata=MagickAllocateMemory(unsigned char *,scandata_bytes);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ magick_uint32_t red;
+ magick_uint32_t green;
+ magick_uint32_t blue;
+
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ scanline=scandata;
+ if (ReadBlobZC(image,scandata_bytes,&scanline) != scandata_bytes)
+ break;
+ MagickBitStreamInitializeRead(&bit_stream,scanline);
+ for (x=0 ; x < (long) image->columns; x++)
+ {
+ /*
+ Packed 10 bit samples with 2 bit pad at end of 32-bit word.
+ */
+ red = MagickBitStreamMSBRead(&bit_stream,10);
+ green = MagickBitStreamMSBRead(&bit_stream,10);
+ blue = MagickBitStreamMSBRead(&bit_stream,10);
+ (void) MagickBitStreamMSBRead(&bit_stream,2);
+
+ q->red = ScaleShortToQuantum(red*scale_to_short);
+ q->green = ScaleShortToQuantum(green*scale_to_short);
+ q->blue = ScaleShortToQuantum(blue*scale_to_short);
+ q->opacity = 0U;
+
+/* printf("i:%u,%u,%u --> %u,%u,%u\n", red, green, blue, */
+/* (unsigned int)q->red, (unsigned int)q->green, (unsigned int)q->blue); */
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(scandata);
+ break;
+ }
+ default:
+ ThrowReaderException(CorruptImageError,ImageTypeNotSupported,image);
+ }
+ }
+ image->depth=Min(image->depth,QuantumDepth);
+ image->colorspace=CineonLogRGBColorspace;
+
+ if ((definition_value=AccessDefinition(image_info,"cineon","colorspace")))
+ {
+ ColorspaceType
+ colorspace;
+
+ colorspace=StringToColorspaceType(definition_value);
+ if (colorspace != UndefinedColorspace)
+ {
+ image->colorspace=colorspace;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Explicitly set colorspace to %s",
+ ColorspaceTypeToString(image->colorspace));
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Unrecognized source colorspace \"%s\"\n",
+ definition_value);
+ ThrowException(&image->exception,OptionError,UnrecognizedColorspace,
+ definition_value);
+ }
+ }
+
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ CloseBlob(image);
+ return(GetFirstImageInList(image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r C I N E O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterCINEONImage adds attributes for the CINEON image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterCINEONImage method is:
+%
+% RegisterCINEONImage(void)
+%
+*/
+ModuleExport void RegisterCINEONImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("CIN");
+ entry->decoder=(DecoderHandler) ReadCINEONImage;
+ entry->encoder=(EncoderHandler) WriteCINEONImage;
+ entry->magick=(MagickHandler) IsCINEON;
+ entry->description="Cineon Image File";
+ entry->module="CINEON";
+ entry->adjoin=MagickFalse;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r C I N E O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterCINEONImage removes format registrations made by the
+% CINEON module from the list of supported formats.
+%
+% The format of the UnregisterCINEONImage method is:
+%
+% UnregisterCINEONImage(void)
+%
+*/
+ModuleExport void UnregisterCINEONImage(void)
+{
+ (void) UnregisterMagickInfo("CIN");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e C I N E O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteCINEONImage() writes an image in CINEON encoded image format.
+%
+% The format of the WriteCINEONImage method is:
+%
+% unsigned int WriteCINEONImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+%
+*/
+
+#define AttributeToU8(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute; \
+\
+ const char \
+ *definition_value; \
+\
+ if ((definition_value=AccessDefinition(image_info,"dpx",key+4))) \
+ member=(U8) strtol(definition_value, (char **) NULL, 10); \
+ else if ((attribute=GetImageAttribute(image,key))) \
+ member=(U8) strtol(attribute->value, (char **) NULL, 10); \
+ else \
+ SET_UNDEFINED_U8(member); \
+}
+
+#define AttributeToU32(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute; \
+\
+ const char \
+ *definition_value; \
+\
+ if ((definition_value=AccessDefinition(image_info,"dpx",key+4))) \
+ member=(U32) strtol(definition_value, (char **) NULL, 10); \
+ else if ((attribute=GetImageAttribute(image,key))) \
+ member=(U32) strtol(attribute->value, (char **) NULL, 10); \
+ else \
+ SET_UNDEFINED_U32(member); \
+}
+
+#define AttributeToS32(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute; \
+\
+ const char \
+ *definition_value; \
+\
+ if ((definition_value=AccessDefinition(image_info,"dpx",key+4))) \
+ member=(S32) strtol(definition_value, (char **) NULL, 10); \
+ else if ((attribute=GetImageAttribute(image,key))) \
+ member=(S32) strtol(attribute->value, (char **) NULL, 10); \
+ else \
+ SET_UNDEFINED_S32(member); \
+}
+
+#define AttributeToR32(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute; \
+\
+ const char \
+ *definition_value; \
+\
+ if ((definition_value=AccessDefinition(image_info,"dpx",key+4))) \
+ member.f=strtod(definition_value, (char **) NULL); \
+ else if ((attribute=GetImageAttribute(image,key))) \
+ member.f=strtod(attribute->value, (char **) NULL); \
+ else \
+ SET_UNDEFINED_R32(member); \
+}
+
+/*
+ Header string values are not required to be null terminated, but any
+ unused space should be filled with nulls.
+*/
+#define AttributeToString(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute; \
+\
+ const char \
+ *definition_value; \
+\
+ SET_UNDEFINED_ASCII(member); \
+ if ((definition_value=AccessDefinition(image_info,"dpx",key+4))) \
+ (void) memcpy(member,definition_value,Min(sizeof(member),strlen(definition_value))); \
+ else if ((attribute=GetImageAttribute(image,key)) && (attribute->value)) \
+ (void) memcpy(member,attribute->value,Min(sizeof(member),strlen(attribute->value))); \
+}
+
+static void GenerateCineonTimeStamp(char *date_str, size_t date_str_length, char*time_str, size_t time_str_length)
+{
+ char timestamp[MaxTextExtent];
+
+ time_t
+ current_time;
+
+ const struct tm
+ *t;
+
+ current_time=time((time_t *) NULL);
+ t=localtime(&current_time);
+
+ (void) memset(timestamp,0,sizeof(timestamp));
+ (void) strftime(timestamp,MaxTextExtent,"%Y:%m:%d:%H:%M:%S%Z",t);
+ timestamp[MaxTextExtent-1]='\0';
+ (void) memset(date_str,0,date_str_length);
+ (void) strlcpy(date_str,timestamp,11);
+ (void) memset(time_str,0,time_str_length);
+ (void) strlcpy(time_str,timestamp+11,15);
+}
+
+
+static unsigned int WriteCINEONImage(const ImageInfo *image_info,Image *image)
+{
+ CineonFileInfo
+ cin_file_info;
+
+ CineonImageInfo
+ cin_image_info;
+
+ CineonImageOriginationInfo
+ cin_source_info;
+
+ CineonFilmInfo
+ cin_mp_info;
+
+ const unsigned char
+ *user_data;
+
+ size_t
+ user_data_length=0,
+ offset=0;
+
+ size_t
+ written=0;
+
+ MagickBool
+ swab=MagickFalse;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ unsigned int
+ status;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ /*
+ Cineon files are written in Cineon Log color space.
+ */
+ if (image->colorspace != CineonLogRGBColorspace)
+ (void) TransformColorspace(image,CineonLogRGBColorspace);
+
+#if !defined(WORDS_BIGENDIAN)
+ swab=MagickTrue;
+#endif /* !defined(WORDS_BIGENDIAN) */
+
+ /*
+ File information header
+ */
+ (void) memset(&cin_file_info,0,sizeof(cin_file_info));
+
+ /* Magick number (0x802A5FD7) */
+ cin_file_info.magic = 0x802A5FD7;
+ /* Generic section header length in bytes */
+ cin_file_info.generic_section_length = sizeof(cin_file_info)+sizeof(cin_image_info)+sizeof(cin_source_info);
+ /* Industry specific header length in bytes */
+ cin_file_info.industry_section_length = sizeof(cin_mp_info);
+ /* User defined header length in bytes */
+ cin_file_info.user_defined_length = 0;
+ user_data=GetImageProfile(image,"CINEONUSERDATA",&user_data_length);
+ if (user_data && user_data_length)
+ cin_file_info.user_defined_length = (U32) user_data_length;
+ /* Offset to image data in bytes */
+ cin_file_info.image_data_offset =
+ cin_file_info.generic_section_length +
+ cin_file_info.industry_section_length +
+ cin_file_info.user_defined_length;
+ /* Total image file size in bytes */
+ cin_file_info.file_size =
+ cin_file_info.generic_section_length +
+ cin_file_info.industry_section_length +
+ cin_file_info.user_defined_length +
+ image->rows*image->columns*4;
+ /* Version number of header format */
+ (void) strlcpy(cin_file_info.header_format_version,"V4.5",sizeof(cin_file_info.header_format_version));
+ /* Image filename */
+ (void) strlcpy(cin_file_info.image_filename,image->filename,sizeof(cin_file_info.image_filename));
+ /* Creation date "yyyy:mm:dd", and time "hh:mm:ssLTZ" */
+ GenerateCineonTimeStamp(cin_file_info.creation_date,sizeof(cin_file_info.creation_date),
+ cin_file_info.creation_time,sizeof(cin_file_info.creation_time));
+
+ /*
+ Image information header
+ */
+ (void) memset(&cin_image_info,0,sizeof(cin_image_info));
+ /* Image orientation */
+ cin_image_info.orientation = OrientationTypeToCineonOrientation(image->orientation);
+ /* Number of image channels (1-8) */
+ cin_image_info.channels = 3; /* RGB */
+
+ /* Channel 0 (Red) */
+ cin_image_info.channel_info[0].designator_byte_0 = 0; /* 0 = universal metric */
+ cin_image_info.channel_info[0].designator_byte_1 = 1; /* Red, Printing Density */
+ /* Bit depth */
+ cin_image_info.channel_info[0].bits_per_sample = 10;
+ /* Pixels per line (columns) */
+ cin_image_info.channel_info[0].pixels_per_line = image->columns;
+ /* Lines per image (rows) */
+ cin_image_info.channel_info[0].lines_per_image = image->rows;
+ /* Reference low data code value */
+ cin_image_info.channel_info[0].reference_low_data_code.f = 0;
+ /* Low quantity represented */
+ cin_image_info.channel_info[0].reference_low_quantity.f = 0.00;
+ /* Reference high data code value */
+ cin_image_info.channel_info[0].reference_high_data_code.f = 1023;
+ /* Reference high quantity represented */
+ cin_image_info.channel_info[0].reference_high_quantity.f = 2.048F;
+
+ /* Channel 1 (Green) */
+ cin_image_info.channel_info[1] = cin_image_info.channel_info[0];
+ cin_image_info.channel_info[1].designator_byte_1 = 2; /* Green, Printing Density */
+
+ /* Channel 2 (Blue) */
+ cin_image_info.channel_info[2] = cin_image_info.channel_info[0];
+ cin_image_info.channel_info[2].designator_byte_1 = 3; /* Blue, Printing Density */
+
+ /* White point (color temperature) - x,y pair */
+ SET_UNDEFINED_R32(cin_image_info.white_point[0]);
+ SET_UNDEFINED_R32(cin_image_info.white_point[1]);
+ if ( image->chromaticity.white_point.x != 0.0 && image->chromaticity.white_point.y != 0.0 )
+ {
+ cin_image_info.white_point[0].f = image->chromaticity.white_point.x;
+ cin_image_info.white_point[1].f = image->chromaticity.white_point.y;
+ }
+ /* Red primary chromaticity - x,y pair */
+ SET_UNDEFINED_R32(cin_image_info.red_primary_chromaticity[0]);
+ SET_UNDEFINED_R32(cin_image_info.red_primary_chromaticity[1]);
+ if ( image->chromaticity.red_primary.x != 0.0 && image->chromaticity.red_primary.y != 0.0)
+ {
+ cin_image_info.red_primary_chromaticity[0].f = image->chromaticity.red_primary.x;
+ cin_image_info.red_primary_chromaticity[1].f = image->chromaticity.red_primary.y;
+ }
+ /* Green primary chromaticity - x,y pair */
+ SET_UNDEFINED_R32(cin_image_info.green_primary_chromaticity[0]);
+ SET_UNDEFINED_R32(cin_image_info.green_primary_chromaticity[1]);
+ if ( image->chromaticity.green_primary.x != 0.0 && image->chromaticity.green_primary.y != 0.0 )
+ {
+ cin_image_info.green_primary_chromaticity[0].f = image->chromaticity.green_primary.x;
+ cin_image_info.green_primary_chromaticity[1].f = image->chromaticity.green_primary.y;
+ }
+ /* Blue primary chromaticity - x,y pair */
+ SET_UNDEFINED_R32(cin_image_info.blue_primary_chromaticity[0]);
+ SET_UNDEFINED_R32(cin_image_info.blue_primary_chromaticity[1]);
+ if ( image->chromaticity.blue_primary.x != 0.0 && image->chromaticity.blue_primary.y != 0.0 )
+ {
+ cin_image_info.blue_primary_chromaticity[0].f = image->chromaticity.blue_primary.x;
+ cin_image_info.blue_primary_chromaticity[1].f = image->chromaticity.blue_primary.y;
+ }
+ /* Label text */
+ AttributeToString(image_info,image,"DPX:file.project.name",cin_image_info.label_text);
+ /* Data interleave */
+ cin_image_info.data_interleave = 0; /* rgbrgbrgb ... */
+ /* Packing method */
+ cin_image_info.packing = 5; /* longword (32-bit) boundaries - left justified */
+ /* Data sign: 0=unsigned, 1=signed */
+ cin_image_info.sign = 0;
+ /* Image sense: 0=positive, 1=negative */
+ cin_image_info.sense = 0;
+ /* End of line padding */
+ cin_image_info.eol_pad = 0;
+ /* End of channel padding */
+ cin_image_info.eoc_pad = 0;
+
+ /*
+ Image origination header.
+ */
+ (void) memset(&cin_source_info,0,sizeof(cin_source_info));
+ AttributeToS32(image_info,image,"DPX:source.x-offset",cin_source_info.x_offset); /* X offset */
+ AttributeToS32(image_info,image,"DPX:source.y-offset",cin_source_info.y_offset); /* Y offset */
+ /* Source image filename */
+ AttributeToString(image_info,image,"DPX:source.filename",cin_source_info.source_image_filename);
+ {
+ /*
+ DPX stores creation date and time in the format
+ "yyyy:mm:dd:hh:mm:ssLTZ" but Cineon wants date and time to be split into
+ yyyy:mm:dd & hh:mm:ssLTZ
+ */
+ ASCII date_and_time[25];
+ AttributeToString(image_info,image,"DPX:source.creation.datetime",date_and_time);
+ SET_UNDEFINED_ASCII(cin_source_info.creation_date);
+ SET_UNDEFINED_ASCII(cin_source_info.creation_time);
+
+ if (!IS_UNDEFINED_ASCII(date_and_time))
+ {
+ /* Creation date: yyyy:mm:dd */
+ (void) strlcpy(cin_source_info.creation_date,date_and_time,11);
+ /* Creation time: hh:mm:ssLTZ */
+ (void) strlcpy(cin_source_info.creation_time,date_and_time+11,sizeof(cin_source_info.creation_time));
+ }
+ }
+ /* Input device */
+ AttributeToString(image_info,image,"DPX:source.device.name",cin_source_info.input_device);
+ /* Input device model number */
+ AttributeToString(image_info,image,"DPX:source.device.model",cin_source_info.input_device_model);
+ /* Input device serial number */
+ AttributeToString(image_info,image,"DPX:source.device.serialnumber",cin_source_info.input_device_serial);
+ /* Input device pitch for X (samples/mm) */
+ AttributeToR32(image_info,image,"DPX:source.device.pitch.x",cin_source_info.input_device_pitch_x);
+ /* Input device pitch for Y (samples/mm) */
+ AttributeToR32(image_info,image,"DPX:source.device.pitch.y",cin_source_info.input_device_pitch_y);
+ /* Image gamma of capture device */
+ AttributeToR32(image_info,image,"DPX:source.device.gamma",cin_source_info.gamma);
+
+ /*
+ Film/Frame Information
+ */
+ (void) memset(&cin_mp_info,0,sizeof(cin_mp_info));
+ /* Film mfg. ID code (2 digits from film edge code) */
+ AttributeToU8(image_info,image,"DPX:mp.film.manufacturer.id",cin_mp_info.film_mfg_id_code);
+ /* Film type (2 digits from film edge code) */
+ AttributeToU8(image_info,image,"DPX:mp.film.type",cin_mp_info.film_type);
+ /* Offset in perfs (2 digits from film edge code) */
+ AttributeToU8(image_info,image,"DPX:mp.perfs.offset",cin_mp_info.perfs_offset);
+ /* Prefix (6 digits from film edge code) */
+ AttributeToU32(image_info,image,"DPX:mp.prefix",cin_mp_info.prefix);
+ /* Count (4 digits from film edge code) */
+ AttributeToU32(image_info,image,"DPX:mp.count",cin_mp_info.count);
+ /* Format -- e.g. Academy */
+ AttributeToString(image_info,image,"DPX:mp.format",cin_mp_info.format);
+ /* Frame position in sequence */
+ AttributeToU32(image_info,image,"DPX:mp.frame.position",cin_mp_info.frame_position);
+ /* Frame rate of original (frames/s) */
+ AttributeToR32(image_info,image,"DPX:mp.frame.rate",cin_mp_info.frame_rate);
+ /* Frame identification - e.g. keyframe */
+ AttributeToString(image_info,image,"DPX:mp.frame.id",cin_mp_info.frame_id);
+ /* Slate information */
+ AttributeToString(image_info,image,"DPX:mp.slate.info",cin_mp_info.slate_info);
+
+ /*
+ Open output image file.
+ */
+
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ return (status);
+
+ if (swab)
+ {
+ /*
+ Swap byte order.
+ */
+ SwabCineonFileInfo(&cin_file_info);
+ SwabCineonImageInfo(&cin_image_info);
+ SwabCineonImageOriginationInfo(&cin_source_info);
+ SwabCineonFilmInfo(&cin_mp_info);
+ }
+
+ written = WriteBlob(image,sizeof(cin_file_info),&cin_file_info);
+ if (written != sizeof(cin_file_info))
+ {
+ CloseBlob(image);
+ return (MagickFail);
+ }
+ offset += written;
+
+ written = WriteBlob(image,sizeof(cin_image_info),&cin_image_info);
+ if (written != sizeof(cin_image_info))
+ {
+ CloseBlob(image);
+ return (MagickFail);
+ }
+ offset += written;
+
+ written = WriteBlob(image,sizeof(cin_source_info),&cin_source_info);
+ if (written != sizeof(cin_source_info))
+ {
+ CloseBlob(image);
+ return (MagickFail);
+ }
+ offset += written;
+
+ written = WriteBlob(image,sizeof(cin_mp_info),&cin_mp_info);
+ if (written != sizeof(cin_mp_info))
+ {
+ CloseBlob(image);
+ return (MagickFail);
+ }
+ offset += written;
+
+ if (swab)
+ {
+ /*
+ Swap byte order back to original.
+ */
+ SwabCineonFileInfo(&cin_file_info);
+ SwabCineonImageInfo(&cin_image_info);
+ SwabCineonImageOriginationInfo(&cin_source_info);
+ SwabCineonFilmInfo(&cin_mp_info);
+ }
+
+ if (user_data)
+ {
+ written = WriteBlob(image,user_data_length,user_data);
+ if (written != user_data_length)
+ {
+ CloseBlob(image);
+ return (MagickFail);
+ }
+ offset += written;
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing Cineon pixels starting at offset %ld",(long) TellBlob(image));
+
+ /*
+ Convert pixel packets to CINEON raster image.
+ */
+ {
+ unsigned char
+ *scanline;
+
+ size_t
+ scanline_bytes;
+
+ BitStreamWriteHandle
+ bit_stream;
+
+ unsigned int
+ red,
+ green,
+ blue;
+
+ unsigned int
+ bits_per_sample,
+ scale_from_short;
+
+ bits_per_sample = cin_image_info.channel_info[0].bits_per_sample;
+ scale_from_short=(65535U / (65535U >> (16-bits_per_sample)));
+
+ scanline_bytes=image->columns*4;
+ scanline=MagickAllocateMemory(unsigned char *,scanline_bytes);
+ if (scanline == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) memset(scanline,0,scanline_bytes);
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+
+ MagickBitStreamInitializeWrite(&bit_stream,scanline);
+
+ for (x=0; x < (long) image->columns; x++)
+ {
+ red = ScaleQuantumToShort(p->red)/scale_from_short;
+ green = ScaleQuantumToShort(p->green)/scale_from_short;
+ blue = ScaleQuantumToShort(p->blue)/scale_from_short;
+
+/* printf("o:%u,%u,%u --> %u,%u,%u\n",(unsigned int)p->red, (unsigned int) p->green, (unsigned int) p->blue, */
+/* red, green, blue); */
+
+ MagickBitStreamMSBWrite(&bit_stream,10,red);
+ MagickBitStreamMSBWrite(&bit_stream,10,green);
+ MagickBitStreamMSBWrite(&bit_stream,10,blue);
+ MagickBitStreamMSBWrite(&bit_stream,2,0);
+ p++;
+ }
+ written = WriteBlob(image,scanline_bytes,scanline);
+ if (written != scanline_bytes)
+ {
+ status = MagickFail;
+ break;
+ }
+ offset += written;
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(scanline);
+ }
+
+ if ((magick_off_t) cin_file_info.file_size != TellBlob(image))
+ {
+ (void) printf("### File length %u, TellBlob says %u\n",
+ cin_file_info.file_size,
+ (unsigned int) TellBlob(image));
+ }
+
+ CloseBlob(image);
+ return(status);
+}
diff --git a/coders/clipboard.c b/coders/clipboard.c
new file mode 100644
index 0000000..2999481
--- /dev/null
+++ b/coders/clipboard.c
@@ -0,0 +1,328 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% %
+% %
+% Read/Write Windows Clipboard. %
+% %
+% %
+% Software Design %
+% Leonard Rosenthol %
+% May 2002 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+
+#include "magick/studio.h"
+#include "magick/nt_feature.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+#if defined(HasWINGDI32)
+# if defined(__CYGWIN__)
+# include <windows.h>
+# else
+ /* All MinGW needs ... */
+# include <wingdi.h>
+# endif
+#endif
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d C L I P B O A R D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadCLIPBOARDImage reads an image from the system clipboard and
+% returns it. It allocates the memory necessary for the new Image structure
+% and returns a pointer to the new image.
+%
+% The format of the ReadCLIPBOARDImage method is:
+%
+% Image *ReadCLIPBOARDImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadCLIPBOARDImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#if defined(HasWINGDI32)
+static Image *ReadCLIPBOARDImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+
+ {
+ HBITMAP
+ bitmapH;
+
+ OpenClipboard( NULL );
+ bitmapH = GetClipboardData( CF_BITMAP );
+ CloseClipboard();
+
+ if ( bitmapH != NULL )
+ {
+ BITMAPINFO
+ DIBinfo;
+
+ BITMAP
+ bitmap;
+
+ HBITMAP
+ hBitmap,
+ hOldBitmap;
+
+ HDC
+ hDC,
+ hMemDC;
+
+ RGBQUAD
+ *pBits,
+ *ppBits;
+
+ /* create an offscreen DC for the source */
+ hMemDC = CreateCompatibleDC( NULL );
+ hOldBitmap = SelectObject( hMemDC, bitmapH );
+ GetObject( bitmapH, sizeof( BITMAP ), (LPSTR) &bitmap );
+ if ((image->columns == 0) || (image->rows == 0))
+ {
+ image->rows=bitmap.bmHeight;
+ image->columns=bitmap.bmWidth;
+ }
+
+ /*
+ Initialize the bitmap header info.
+ Create a temp DC for the DIB to go into
+ */
+ (void) memset(&DIBinfo,0,sizeof(BITMAPINFO));
+ DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ DIBinfo.bmiHeader.biWidth=image->columns;
+ DIBinfo.bmiHeader.biHeight=(-1)*image->rows;
+ DIBinfo.bmiHeader.biPlanes=1;
+ DIBinfo.bmiHeader.biBitCount=32;
+ DIBinfo.bmiHeader.biCompression=BI_RGB;
+ hDC=GetDC(NULL);
+ if (!hDC)
+ ThrowReaderException(CoderError,UnableToCreateADC,image);
+ hBitmap= CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits,NULL,0);
+ ReleaseDC(NULL,hDC);
+ if (!hBitmap)
+ ThrowReaderException(CoderError,UnableToCreateBitmap,image);
+
+ /* create an offscreen DC */
+ hDC=CreateCompatibleDC(NULL);
+ if (!hDC)
+ {
+ DeleteObject(hBitmap);
+ ThrowReaderException(CoderError,UnableToCreateADC,image);
+ }
+ hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap);
+ if (!hOldBitmap)
+ {
+ DeleteDC(hDC);
+ DeleteObject(hBitmap);
+ ThrowReaderException(CoderError,UnableToCreateBitmap,image);
+ }
+
+ /* bitblt from the memory to the DIB-based one */
+ BitBlt( hDC, 0, 0, image->columns, image->rows, hMemDC, 0, 0, SRCCOPY );
+
+ /* finally copy the pixels! */
+ pBits=ppBits;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red = ScaleCharToQuantum(pBits->rgbRed);
+ q->green = ScaleCharToQuantum(pBits->rgbGreen);
+ q->blue = ScaleCharToQuantum(pBits->rgbBlue);
+ q->opacity = OpaqueOpacity;
+ pBits++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ } else
+ ThrowReaderException(CoderError,NoBitmapOnClipboard,image);
+ }
+
+ CloseBlob(image);
+ return(image);
+}
+#endif /* HasWINGDI32 */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e C L I P B O A R D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteCLIPBOARDImage writes an image to the system clipboard.
+%
+% The format of the WriteCLIPBOARDImage method is:
+%
+% unsigned int WriteCLIPBOARDImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteCLIPBOARDImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+#if defined(HasWINGDI32)
+static unsigned int WriteCLIPBOARDImage(const ImageInfo *image_info,Image *image)
+{
+ /*
+ Allocate memory for pixels.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ {
+ HBITMAP
+ bitmapH;
+
+ OpenClipboard( NULL );
+ EmptyClipboard();
+
+ bitmapH = ImageToHBITMAP(image);
+ SetClipboardData(CF_BITMAP, bitmapH);
+
+ CloseClipboard();
+
+ return(True);
+ }
+
+ return(False);
+}
+#endif /* HasWINGDI32 */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r C L I P B O A R D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterCLIPBOARDImage adds attributes for the clipboard "image format" to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterCLIPBOARDImage method is:
+%
+% RegisterCLIPBOARDImage(void)
+%
+*/
+ModuleExport void RegisterCLIPBOARDImage(void)
+{
+#if defined(HasWINGDI32)
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("CLIPBOARD");
+ entry->decoder=(DecoderHandler) ReadCLIPBOARDImage;
+ entry->encoder=(EncoderHandler) WriteCLIPBOARDImage;
+ entry->adjoin = False;
+ entry->description="Windows System Clipboard";
+ entry->module="CLIPBOARD";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r C L I P B O A R D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterCLIPBOARDImage removes format registrations made by the
+% RGB module from the list of supported formats.
+%
+% The format of the UnregisterCLIPBOARDImage method is:
+%
+% UnregisterCLIPBOARDImage(void)
+%
+*/
+ModuleExport void UnregisterCLIPBOARDImage(void)
+{
+#if defined(HasWINGDI32)
+ (void) UnregisterMagickInfo("CLIPBOARD");
+#endif
+}
+
diff --git a/coders/cmyk.c b/coders/cmyk.c
new file mode 100644
index 0000000..9edbf33
--- /dev/null
+++ b/coders/cmyk.c
@@ -0,0 +1,892 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC M M Y Y K K %
+% C MM MM Y Y K K %
+% C M M M Y KKK %
+% C M M Y K K %
+% CCCC M M Y K K %
+% %
+% %
+% Read/Write RAW CMYK Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/pixel_cache.h"
+#include "magick/constitute.h"
+#include "magick/blob.h"
+#include "magick/enum_strings.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteCMYKImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d C M Y K I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadCMYKImage reads an image of raw cyan, magenta, yellow, and black
+% samples and returns it. It allocates the memory necessary for the new
+% Image structure and returns a pointer to the new image.
+%
+% The format of the ReadCMYKImage method is:
+%
+% Image *ReadCMYKImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadCMYKImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadCMYKImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ size_t
+ count;
+
+ unsigned char
+ *scanline;
+
+ unsigned int
+ status;
+
+ unsigned int
+ packet_size,
+ quantum_size;
+
+ ImportPixelAreaOptions
+ import_options;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+ if (image_info->interlace != PartitionInterlace)
+ {
+ /*
+ Open image file.
+ */
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ for (i=0; i < image->offset; i++)
+ {
+ if (EOF == ReadBlobByte(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ }
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Tile %lux%lu%+ld%+ld",
+ image->tile_info.width,image->tile_info.height,
+ image->tile_info.x,image->tile_info.y);
+
+ /*
+ Allocate memory for a scanline.
+ */
+
+ if (image->depth <= 8)
+ quantum_size=8;
+ else if (image->depth <= 16)
+ quantum_size=16;
+ else
+ quantum_size=32;
+
+ packet_size=(quantum_size*4)/8;
+ if (LocaleCompare(image_info->magick,"CMYKA") == 0)
+ {
+ image->matte=True;
+ packet_size=(quantum_size*5)/8;
+ }
+ scanline=MagickAllocateArray(unsigned char *,
+ packet_size,image->tile_info.width);
+ if (scanline == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize import options.
+ */
+ ImportPixelAreaOptionsInit(&import_options);
+ if (image_info->endian != UndefinedEndian)
+ import_options.endian=image_info->endian;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Depth %u bits, Endian %s, Interlace %s",
+ quantum_size,
+ EndianTypeToString(import_options.endian),
+ InterlaceTypeToString(image_info->interlace));
+ /*
+ Support starting at intermediate image frame.
+ */
+ if (image_info->subrange != 0)
+ while (image->scene < image_info->subimage)
+ {
+ /*
+ Skip to next image.
+ */
+ image->scene++;
+ for (y=0; y < (long) image->rows; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ }
+ x=(long) (packet_size*image->tile_info.x);
+ do
+ {
+ /*
+ Convert raster image to pixel packets.
+ */
+ image->colorspace=CMYKColorspace;
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ switch (image_info->interlace)
+ {
+ case NoInterlace:
+ default:
+ {
+ /*
+ No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
+ */
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (!image->matte)
+ (void) ImportImagePixelArea(image,CMYKQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ else
+ (void) ImportImagePixelArea(image,CMYKAQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ break;
+ }
+ case LineInterlace:
+ {
+ /*
+ Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
+ */
+ packet_size=(quantum_size)/8;
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,CyanQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ (void) ImportImagePixelArea(image,MagentaQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ (void) ImportImagePixelArea(image,YellowQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ (void) ImportImagePixelArea(image,BlackQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (image->matte)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,
+ scanline);
+ (void) ImportImagePixelArea(image,AlphaQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ break;
+ }
+ case PlaneInterlace:
+ case PartitionInterlace:
+ {
+ unsigned long
+ span;
+
+ /*
+ Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
+ */
+ if (image_info->interlace == PartitionInterlace)
+ {
+ AppendImageFormat("C",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ packet_size=(quantum_size)/8;
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ i=0;
+ span=image->rows*(image->matte ? 5 : 4);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,CyanQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("M",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,MagentaQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("Y",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,YellowQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("K",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,BlackQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (image->matte)
+ {
+ /*
+ Read matte channel.
+ */
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("A",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,
+ scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,
+ scanline);
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,AlphaQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,
+ scanline);
+ }
+ if (image_info->interlace == PartitionInterlace)
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ break;
+ }
+ }
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (image_info->interlace == PartitionInterlace)
+ break;
+ count=ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (count != 0)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ }
+ } while (count != 0);
+ MagickFreeMemory(scanline);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r C M Y K I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterCMYKImage adds attributes for the CMYK image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterCMYKImage method is:
+%
+% RegisterCMYKImage(void)
+%
+*/
+ModuleExport void RegisterCMYKImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("CMYK");
+ entry->decoder=(DecoderHandler) ReadCMYKImage;
+ entry->encoder=(EncoderHandler) WriteCMYKImage;
+ entry->raw=True;
+ entry->description="Raw cyan, magenta, yellow, and black samples";
+ entry->module="CMYK";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("CMYKA");
+ entry->decoder=(DecoderHandler) ReadCMYKImage;
+ entry->encoder=(EncoderHandler) WriteCMYKImage;
+ entry->raw=True;
+ entry->description="Raw cyan, magenta, yellow, black, and opacity samples";
+ entry->module="CMYK";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r C M Y K I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterCMYKImage removes format registrations made by the
+% CMYK module from the list of supported formats.
+%
+% The format of the UnregisterCMYKImage method is:
+%
+% UnregisterCMYKImage(void)
+%
+*/
+ModuleExport void UnregisterCMYKImage(void)
+{
+ (void) UnregisterMagickInfo("CMYK");
+ (void) UnregisterMagickInfo("CMYKA");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e C M Y K I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteCMYKImage writes an image to a file in red, green, and blue
+% rasterfile format.
+%
+% The format of the WriteCMYKImage method is:
+%
+% unsigned int WriteCMYKImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteCMYKImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteCMYKImage(const ImageInfo *image_info,Image *image)
+{
+ int
+ y;
+
+ register const PixelPacket
+ *p;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ packet_size,
+ quantum_size,
+ scene,
+ status;
+
+ ExportPixelAreaOptions
+ export_options;
+
+ ExportPixelAreaInfo
+ export_info;
+
+ if (image->depth <= 8)
+ quantum_size=8;
+ else if (image->depth <= 16)
+ quantum_size=16;
+ else
+ quantum_size=32;
+
+
+ /*
+ Allocate memory for pixels.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ packet_size=(quantum_size*4)/8;
+ if (LocaleCompare(image_info->magick,"CMYKA") == 0)
+ packet_size=(quantum_size*5)/8;
+ pixels=MagickAllocateArray(unsigned char *,packet_size,image->columns);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (image_info->interlace != PartitionInterlace)
+ {
+ /*
+ Open output image file.
+ */
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ scene=0;
+ do
+ {
+ /*
+ Convert MIFF to CMYK raster pixels.
+ */
+ (void) TransformColorspace(image,CMYKColorspace);
+ if (LocaleCompare(image_info->magick,"CMYKA") == 0)
+ if (!image->matte)
+ SetImageOpacity(image,OpaqueOpacity);
+ /*
+ Initialize export options.
+ */
+ ExportPixelAreaOptionsInit(&export_options);
+ if (image->endian != UndefinedEndian)
+ export_options.endian=image->endian;
+ else if (image_info->endian != UndefinedEndian)
+ export_options.endian=image_info->endian;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image depth %u bits, Endian %s",quantum_size,
+ EndianTypeToString(export_options.endian));
+ switch (image_info->interlace)
+ {
+ case NoInterlace:
+ default:
+ {
+ /*
+ No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if (LocaleCompare(image_info->magick,"CMYKA") != 0)
+ {
+ (void) ExportImagePixelArea(image,CMYKQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ else
+ {
+ (void) ExportImagePixelArea(image,CMYKAQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case LineInterlace:
+ {
+ /*
+ Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,CyanQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ (void) ExportImagePixelArea(image,MagentaQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ (void) ExportImagePixelArea(image,YellowQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ (void) ExportImagePixelArea(image,BlackQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ if (LocaleCompare(image_info->magick,"CMYKA") == 0)
+ {
+ (void) ExportImagePixelArea(image,AlphaQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case PlaneInterlace:
+ case PartitionInterlace:
+ {
+ /*
+ Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
+ */
+ if (image_info->interlace == PartitionInterlace)
+ {
+ AppendImageFormat("C",image->filename);
+ status=
+ OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,CyanQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("M",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ if (!MagickMonitorFormatted(100,400,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,MagentaQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("Y",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ if (!MagickMonitorFormatted(200,400,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,YellowQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("K",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ if (!MagickMonitorFormatted(200,400,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,BlackQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (LocaleCompare(image_info->magick,"CMYKA") == 0)
+ {
+ if (!MagickMonitorFormatted(300,400,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("A",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,AlphaQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ }
+ if (image_info->interlace == PartitionInterlace)
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ (void) MagickMonitorFormatted(400,400,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows);
+ break;
+ }
+ }
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ MagickFreeMemory(pixels);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/cut.c b/coders/cut.c
new file mode 100644
index 0000000..71fece5
--- /dev/null
+++ b/coders/cut.c
@@ -0,0 +1,649 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% CCC U U TTTTT %
+% C U U T %
+% C U U T %
+% C U U T %
+% CCC UUU T %
+% %
+% %
+% Read DR Halo Image Format. %
+% %
+% %
+% Software Design %
+% Jaroslav Fojtik %
+% June 2000 - 2007 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+typedef struct
+{
+ unsigned Width;
+ unsigned Height;
+ unsigned Reserved;
+}CUTHeader; /*Dr Halo*/
+typedef struct
+{
+ char FileId[2];
+ unsigned Version;
+ unsigned Size;
+ char FileType;
+ char SubType;
+ unsigned BoardID;
+ unsigned GraphicsMode;
+ unsigned MaxIndex;
+ unsigned MaxRed;
+ unsigned MaxGreen;
+ unsigned MaxBlue;
+ char PaletteId[20];
+}CUTPalHeader;
+
+
+static void InsertRow(unsigned char *p,long y,Image *image)
+{
+ int bit; long x;
+ register PixelPacket *q;
+ IndexPacket index;
+ register IndexPacket *indexes;
+
+
+ switch (image->depth)
+ {
+ case 1: /* Convert bitmap scanline. */
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < ((long) image->columns-7); x+=8)
+ {
+ for (bit=0; bit < 8; bit++)
+ {
+ index=((*p) & (0x80U >> bit) ? 0x01U : 0x00U);
+ indexes[x+bit]=index;
+ *q++=image->colormap[index];
+ }
+ p++;
+ }
+ if ((image->columns % 8) != 0)
+ {
+ for (bit=0; bit < (long) (image->columns % 8); bit++)
+ {
+ index=((*p) & (0x80 >> bit) ? 0x01U : 0x00U);
+ indexes[x+bit]=index;
+ *q++=image->colormap[index];
+ }
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ ProgressMonitor(LoadImageText,image->rows-y-1,image->rows);*/
+ break;
+ }
+ case 2: /* Convert PseudoColor scanline. */
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < ((long) image->columns-1); x+=2)
+ {
+ index=(IndexPacket) ((*p >> 6U) & 0x3U);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) ((*p >> 4U) & 0x3U);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) ((*p >> 2U) & 0x3U);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) ((*p) & 0x3U);
+ VerifyColormapIndex(image,index);
+ indexes[x+1]=index;
+ *q++=image->colormap[index];
+ p++;
+ }
+ if ((image->columns % 4) != 0)
+ {
+ index=(IndexPacket) ((*p >> 6U) & 0x3U);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ if ((image->columns % 4) >= 1)
+
+ {
+ index=(IndexPacket) ((*p >> 4U) & 0x3U);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ if ((image->columns % 4) >= 2U)
+
+ {
+ index=(IndexPacket) ((*p >> 2U) & 0x3U);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ }
+ }
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ ProgressMonitor(LoadImageText,image->rows-y-1,image->rows);*/
+ break;
+ }
+
+ case 4: /* Convert PseudoColor scanline. */
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < ((long) image->columns-1); x+=2)
+ {
+ index=(IndexPacket) ((*p >> 4U) & 0xfU);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) ((*p) & 0xfU);
+ VerifyColormapIndex(image,index);
+ indexes[x+1]=index;
+ *q++=image->colormap[index];
+ p++;
+ }
+ if ((image->columns % 2) != 0)
+ {
+ index=(IndexPacket) ((*p >> 4U) & 0xfU);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ ProgressMonitor(LoadImageText,image->rows-y-1,image->rows);*/
+ break;
+ }
+ case 8: /* Convert PseudoColor scanline. */
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL) break;
+ indexes=AccessMutableIndexes(image);
+
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=(IndexPacket) (*p);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ ProgressMonitor(LoadImageText,image->rows-y-1,image->rows);*/
+ }
+ break;
+
+ }
+}
+
+static unsigned int GetCutColors(Image *image)
+{
+ int
+ x,
+ y;
+
+ PixelPacket
+ *q;
+
+ Quantum
+ MaxColor,
+ ScaleCharToQuantum16;
+
+ /* Compute the number of colors in Grayed R[i]=G[i]=B[i] image */
+ ScaleCharToQuantum16=ScaleCharToQuantum(16);
+ MaxColor=0;
+ for (y=0; y < (long)image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ for (x=(long)image->columns; x > 0; x--)
+ {
+ if (MaxColor < q->red)
+ MaxColor=q->red;
+ if (MaxColor >= ScaleCharToQuantum16)
+ return(255);
+ q++;
+ }
+ }
+ if (MaxColor < ScaleCharToQuantum(2))
+ MaxColor=2;
+ else if (MaxColor < ScaleCharToQuantum(16))
+ MaxColor=16;
+ return (MaxColor);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d C U T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadCUTImage reads an CUT X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadCUTImage method is:
+%
+% Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadCUTImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image *image,*palette;
+ ImageInfo *clone_info;
+ unsigned int status;
+ unsigned long EncodedByte;
+ unsigned char RunCount,RunValue,RunCountMasked;
+ CUTHeader Header;
+ CUTPalHeader PalHeader;
+ long i,j;
+ long ldblk;
+ unsigned char *BImgBuff=NULL,*ptrB;
+ PixelPacket *q;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read CUT image.
+ */
+ palette=NULL;
+ clone_info=NULL;
+ Header.Width=ReadBlobLSBShort(image);
+ Header.Height=ReadBlobLSBShort(image);
+ Header.Reserved=ReadBlobLSBShort(image);
+
+ if (Header.Width==0 || Header.Height==0 || Header.Reserved!=0 ||
+ (Header.Width > INT_MAX) || (Header.Height > INT_MAX) )
+ CUT_KO: ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ /*---This code checks first line of image---*/
+ EncodedByte=ReadBlobLSBShort(image);
+ RunCount=ReadBlobByte(image);
+ RunCountMasked=RunCount & 0x7F;
+ ldblk=0;
+ while (RunCountMasked != 0) /*end of line?*/
+ {
+ i=1;
+ if (RunCount<0x80) i=RunCountMasked;
+ (void) SeekBlob(image,TellBlob(image)+i,SEEK_SET);
+ if (EOFBlob(image)) goto CUT_KO; /*wrong data*/
+ EncodedByte-=i+1;
+ ldblk+=RunCountMasked;
+
+ RunCount=ReadBlobByte(image);
+ if (EOFBlob(image)) goto CUT_KO; /*wrong data: unexpected eof in line*/
+ RunCountMasked=RunCount & 0x7F;
+ }
+ if (EncodedByte!=1) goto CUT_KO; /*wrong data: size incorrect*/
+ i=0; /*guess a number of bit planes*/
+ if (ldblk==(int) Header.Width) i=8;
+ if (2*ldblk==(int) Header.Width) i=4;
+ if (8*ldblk==(int) Header.Width) i=1;
+ if (i==0) goto CUT_KO; /*wrong data: incorrect bit planes*/
+
+ image->columns=Header.Width;
+ image->rows=Header.Height;
+ image->depth=i;
+ image->colors=1l >> i;
+
+ /* If ping is true, then only set image size and colors without reading any image data. */
+ if (image_info->ping) goto Finish;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /* ----- Do something with palette ----- */
+ if ((clone_info=CloneImageInfo(image_info)) == NULL) goto NoPalette;
+
+
+ i=(long) strlen(clone_info->filename);
+ j=i;
+ while (--i>0)
+ {
+ if (clone_info->filename[i]=='.')
+ {
+ break;
+ }
+ if (clone_info->filename[i]=='/' || clone_info->filename[i]=='\\' ||
+ clone_info->filename[i]==':' )
+ {
+ i=j;
+ break;
+ }
+ }
+
+ (void) strcpy(clone_info->filename+i,".PAL");
+ if ((clone_info->file=fopen(clone_info->filename,"rb"))==NULL)
+ {
+ (void) strcpy(clone_info->filename+i,".pal");
+ if ((clone_info->file=fopen(clone_info->filename,"rb"))==NULL)
+ {
+ clone_info->filename[i]=0;
+ if ((clone_info->file=fopen(clone_info->filename,"rb"))==NULL)
+ {
+ DestroyImageInfo(clone_info);
+ clone_info=NULL;
+ goto NoPalette;
+ }
+ }
+ }
+
+ if ( (palette=AllocateImage(clone_info))==NULL ) goto NoPalette;
+ status=OpenBlob(clone_info,palette,ReadBinaryBlobMode,exception);
+ if (status == False)
+ {
+ ErasePalette:
+ DestroyImage(palette);
+ palette=NULL;
+ goto NoPalette;
+ }
+
+
+ if (palette!=NULL)
+ {
+ (void) ReadBlob(palette,2,PalHeader.FileId);
+ if (strncmp(PalHeader.FileId,"AH",2)) goto ErasePalette;
+ PalHeader.Version=ReadBlobLSBShort(palette);
+ PalHeader.Size=ReadBlobLSBShort(palette);
+ PalHeader.FileType=ReadBlobByte(palette);
+ PalHeader.SubType=ReadBlobByte(palette);
+ PalHeader.BoardID=ReadBlobLSBShort(palette);
+ PalHeader.GraphicsMode=ReadBlobLSBShort(palette);
+ PalHeader.MaxIndex=ReadBlobLSBShort(palette);
+ PalHeader.MaxRed=ReadBlobLSBShort(palette);
+ PalHeader.MaxGreen=ReadBlobLSBShort(palette);
+ PalHeader.MaxBlue=ReadBlobLSBShort(palette);
+ (void) ReadBlob(palette,20,PalHeader.PaletteId);
+
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ if (PalHeader.MaxIndex<1) goto ErasePalette;
+ image->colors=PalHeader.MaxIndex+1;
+ if (!AllocateImageColormap(image,image->colors)) goto NoMemory;
+
+ if (PalHeader.MaxRed==0) PalHeader.MaxRed=MaxRGB; /*avoid division by 0*/
+ if (PalHeader.MaxGreen==0) PalHeader.MaxGreen=MaxRGB;
+ if (PalHeader.MaxBlue==0) PalHeader.MaxBlue=MaxRGB;
+
+ for (i=0;i<=(int) PalHeader.MaxIndex;i++)
+ {
+ /*this may be wrong- I don't know why is palette such strange*/
+ j=(long) TellBlob(palette);
+ if ((j % 512)>512-6)
+ {
+ j=((j / 512)+1)*512;
+ (void) SeekBlob(palette,j,SEEK_SET);
+ }
+ image->colormap[i].red=ReadBlobLSBShort(palette);
+ if (MaxRGB!=PalHeader.MaxRed)
+ {
+ image->colormap[i].red=(Quantum)
+ (((double)image->colormap[i].red*MaxRGB+(PalHeader.MaxRed>>1))/PalHeader.MaxRed+0.5);
+ }
+ image->colormap[i].green=ReadBlobLSBShort(palette);
+ if (MaxRGB!=PalHeader.MaxGreen)
+ {
+ image->colormap[i].green=(Quantum)
+ (((double)image->colormap[i].green*MaxRGB+(PalHeader.MaxGreen>>1))/PalHeader.MaxGreen+0.5);
+ }
+ image->colormap[i].blue=ReadBlobLSBShort(palette);
+ if (MaxRGB!=PalHeader.MaxBlue)
+ {
+ image->colormap[i].blue=(Quantum)
+ (((double)image->colormap[i].blue*MaxRGB+(PalHeader.MaxBlue>>1))/PalHeader.MaxBlue+0.5);
+ }
+
+ }
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+
+
+
+ NoPalette:
+ if (palette==NULL)
+ {
+
+ image->colors=256;
+ if (!AllocateImageColormap(image,image->colors))
+ {
+ NoMemory:
+ if (clone_info != NULL)
+ DestroyImageInfo(clone_info);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+
+ for (i=0; i < (long)image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(i);
+ image->colormap[i].green=ScaleCharToQuantum(i);
+ image->colormap[i].blue=ScaleCharToQuantum(i);
+ }
+ }
+
+
+ /* ----- Load RLE compressed raster ----- */
+ BImgBuff=MagickAllocateMemory(unsigned char *,(size_t) (ldblk)); /*Ldblk was set in the check phase*/
+ if (BImgBuff==NULL) goto NoMemory;
+
+ (void) SeekBlob(image,6 /*sizeof(Header)*/,SEEK_SET);
+ for (i=0;i<(int) Header.Height;i++)
+ {
+ EncodedByte=ReadBlobLSBShort(image);
+
+ ptrB=BImgBuff;
+ j=ldblk;
+
+ RunCount=ReadBlobByte(image);
+ RunCountMasked=RunCount & 0x7F;
+
+ while (RunCountMasked!=0)
+ {
+ if (RunCountMasked>j)
+ { /*Wrong Data*/
+ RunCountMasked=(unsigned char) j;
+ if (j==0)
+ {
+ break;
+ }
+ }
+
+ if (RunCount>0x80)
+ {
+ RunValue=ReadBlobByte(image);
+ (void) memset(ptrB,RunValue,RunCountMasked);
+ }
+ else {
+ (void) ReadBlob(image,RunCountMasked,ptrB);
+ }
+
+ ptrB+=RunCountMasked;
+ j-=RunCountMasked;
+
+ if (EOFBlob(image)) goto Finish; /* wrong data: unexpected eof in line */
+ RunCount=ReadBlobByte(image);
+ RunCountMasked=RunCount & 0x7F;
+ }
+
+ InsertRow(BImgBuff,i,image);
+ }
+
+
+ /*detect monochrome image*/
+
+ if (palette==NULL)
+ { /*attempt to detect binary (black&white) images*/
+ if ((image->storage_class == PseudoClass) && IsGrayImage(image,&image->exception))
+ {
+ if (GetCutColors(image)==2)
+ {
+ for (i=0; i < (long)image->colors; i++)
+ {
+ register Quantum
+ sample;
+ sample=ScaleCharToQuantum(i);
+ if (image->colormap[i].red!=sample) goto Finish;
+ if (image->colormap[i].green!=sample) goto Finish;
+ if (image->colormap[i].blue!=sample) goto Finish;
+ }
+
+ image->colormap[1].red=image->colormap[1].green=image->colormap[1].blue=MaxRGB;
+ for (i=0; i < (long)image->rows; i++)
+ {
+ q=SetImagePixels(image,0,i,image->columns,1);
+ for (j=0; j < (long)image->columns; j++)
+ {
+ if (q->red==ScaleCharToQuantum(1))
+ {
+ q->red=q->green=q->blue=MaxRGB;
+ }
+ q++;
+ }
+ if (!SyncImagePixels(image)) goto Finish;
+ }
+ }
+ }
+ }
+
+ Finish:
+ if (BImgBuff!=NULL) MagickFreeMemory(BImgBuff);
+ if (palette!=NULL) DestroyImage(palette);
+ if (clone_info!=NULL) DestroyImageInfo(clone_info);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r C U T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterCUTImage adds attributes for the CUT image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterCUTImage method is:
+%
+% RegisterCUTImage(void)
+%
+*/
+ModuleExport void RegisterCUTImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("CUT");
+ entry->decoder=(DecoderHandler) ReadCUTImage;
+ entry->seekable_stream=True;
+ entry->description="DR Halo";
+ entry->module="CUT";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r C U T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterCUTImage removes format registrations made by the
+% CUT module from the list of supported formats.
+%
+% The format of the UnregisterCUTImage method is:
+%
+% UnregisterCUTImage(void)
+%
+*/
+ModuleExport void UnregisterCUTImage(void)
+{
+ (void) UnregisterMagickInfo("CUT");
+}
diff --git a/coders/dcm.c b/coders/dcm.c
new file mode 100644
index 0000000..f77a3fe
--- /dev/null
+++ b/coders/dcm.c
@@ -0,0 +1,4949 @@
+/*
+% Copyright (C) 2003-2009 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD CCCC M M %
+% D D C MM MM %
+% D D C M M M %
+% D D C M M %
+% DDDD CCCC M M %
+% %
+% %
+% Read DICOM Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/enhance.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+#define USE_GRAYMAP
+#define GRAYSCALE_USES_PALETTE
+*/
+
+/* Defines for "best guess" fixes */
+#define NEW_IMPLICIT_LOGIC
+#define IGNORE_WINDOW_FOR_UNSPECIFIED_SCALE_TYPE
+
+/*
+ Function types for reading MSB/LSB shorts/longs
+*/
+typedef magick_uint16_t (DicomReadShortFunc)(Image *);
+typedef magick_uint32_t (DicomReadLongFunc)(Image *);
+
+/*
+ DCM enums
+*/
+typedef enum
+{
+ DCM_TS_IMPL_LITTLE,
+ DCM_TS_EXPL_LITTLE,
+ DCM_TS_EXPL_BIG,
+ DCM_TS_JPEG,
+ DCM_TS_JPEG_LS,
+ DCM_TS_JPEG_2000,
+ DCM_TS_RLE
+} Dicom_TS;
+
+typedef enum
+{
+ DCM_MSB_LITTLE,
+ DCM_MSB_BIG_PENDING,
+ DCM_MSB_BIG
+} Dicom_MSB;
+
+typedef enum
+{
+ DCM_PI_MONOCHROME1,
+ DCM_PI_MONOCHROME2,
+ DCM_PI_PALETTE_COLOR,
+ DCM_PI_RGB,
+ DCM_PI_OTHER
+} Dicom_PI;
+
+typedef enum
+{
+ DCM_RT_OPTICAL_DENSITY,
+ DCM_RT_HOUNSFIELD,
+ DCM_RT_UNSPECIFIED,
+ DCM_RT_UNKNOWN
+} Dicom_RT;
+
+typedef enum
+{
+ DCM_RS_NONE,
+ DCM_RS_PRE,
+ DCM_RS_POST
+} Dicom_RS;
+
+/*
+ Dicom medical image declarations.
+*/
+typedef struct _DicomStream
+{
+ /*
+ Values representing nature of image
+ */
+ unsigned long
+ rows,
+ columns;
+
+ unsigned int
+ number_scenes,
+ samples_per_pixel,
+ bits_allocated,
+ significant_bits,
+ bytes_per_pixel,
+ max_value_in,
+ max_value_out,
+ high_bit,
+ pixel_representation,
+ interlace;
+
+ Dicom_MSB
+ msb_state;
+
+ Dicom_PI
+ phot_interp;
+
+ double
+ window_center,
+ window_width,
+ rescale_intercept,
+ rescale_slope;
+
+ Dicom_TS
+ transfer_syntax;
+
+ Dicom_RT
+ rescale_type;
+
+ Dicom_RS
+ rescaling;
+
+ /*
+ Array to store offset table for fragments within image
+ */
+ magick_uint32_t
+ offset_ct;
+ magick_uint32_t *
+ offset_arr;
+
+ /*
+ Variables used to handle fragments and RLE compression
+ */
+ magick_uint32_t
+ frag_bytes;
+
+ magick_uint32_t
+ rle_seg_ct,
+ rle_seg_offsets[15];
+
+ int
+ rle_rep_ct,
+ rle_rep_char;
+
+ /*
+ Max and minimum sample values within image used for post rescale mapping
+ */
+ int
+ upper_lim,
+ lower_lim;
+
+ Quantum
+ *rescale_map;
+
+#if defined(USE_GRAYMAP)
+ unsigned short
+ *graymap;
+#endif
+
+ /*
+ Values representing last read element
+ */
+ unsigned short
+ group,
+ element;
+
+ int
+ index,
+ datum;
+
+ size_t
+ quantum,
+ length;
+
+ unsigned char *
+ data;
+
+ /*
+ Remaining fields for internal use by DCM_ReadElement and to read data
+ */
+ DicomReadShortFunc *
+ funcReadShort;
+
+ DicomReadLongFunc *
+ funcReadLong;
+
+ int
+ explicit_file;
+
+ unsigned int
+ verbose;
+} DicomStream;
+
+/*
+ Function type for parsing DICOM elements
+*/
+typedef MagickPassFail (DicomElemParseFunc)(Image *Image,DicomStream *dcm,ExceptionInfo *exception);
+
+/*
+ Forward declaration for parser functions
+*/
+static DicomElemParseFunc funcDCM_TransferSyntax;
+static DicomElemParseFunc funcDCM_StudyDate;
+static DicomElemParseFunc funcDCM_PatientName;
+static DicomElemParseFunc funcDCM_TriggerTime;
+static DicomElemParseFunc funcDCM_FieldOfView;
+static DicomElemParseFunc funcDCM_SeriesNumber;
+static DicomElemParseFunc funcDCM_ImagePosition;
+static DicomElemParseFunc funcDCM_ImageOrientation;
+static DicomElemParseFunc funcDCM_SliceLocation;
+static DicomElemParseFunc funcDCM_SamplesPerPixel;
+static DicomElemParseFunc funcDCM_PhotometricInterpretation;
+static DicomElemParseFunc funcDCM_PlanarConfiguration;
+static DicomElemParseFunc funcDCM_NumberOfFrames;
+static DicomElemParseFunc funcDCM_Rows;
+static DicomElemParseFunc funcDCM_Columns;
+static DicomElemParseFunc funcDCM_BitsAllocated;
+static DicomElemParseFunc funcDCM_BitsStored;
+static DicomElemParseFunc funcDCM_HighBit;
+static DicomElemParseFunc funcDCM_PixelRepresentation;
+static DicomElemParseFunc funcDCM_WindowCenter;
+static DicomElemParseFunc funcDCM_WindowWidth;
+static DicomElemParseFunc funcDCM_RescaleIntercept;
+static DicomElemParseFunc funcDCM_RescaleSlope;
+static DicomElemParseFunc funcDCM_RescaleType;
+static DicomElemParseFunc funcDCM_PaletteDescriptor;
+static DicomElemParseFunc funcDCM_LUT;
+static DicomElemParseFunc funcDCM_Palette;
+
+/*
+ Type for holding information on DICOM elements
+*/
+typedef struct _DicomInfo
+{
+ const unsigned short
+ group,
+ element;
+
+ const char
+ *vr,
+ *description;
+
+ DicomElemParseFunc
+ * const pfunc;
+} DicomInfo;
+
+/*
+ Array holding information on DICOM elements
+*/
+static const DicomInfo
+ dicom_info[]=
+ {
+ { 0x0000, 0x0000, "UL", "Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0001, "UL", "Command Length to End", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0002, "UI", "Affected SOP Class UID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0003, "UI", "Requested SOP Class UID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0010, "LO", "Command Recognition Code", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0100, "US", "Command Field", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0110, "US", "Message ID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0120, "US", "Message ID Being Responded To", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0200, "AE", "Initiator", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0300, "AE", "Receiver", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0400, "AE", "Find Location", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0600, "AE", "Move Destination", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0700, "US", "Priority", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0800, "US", "Data Set Type", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0850, "US", "Number of Matches", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0860, "US", "Response Sequence Number", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0900, "US", "Status", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0901, "AT", "Offending Element", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0902, "LO", "Exception Comment", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x0903, "US", "Exception ID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1000, "UI", "Affected SOP Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1001, "UI", "Requested SOP Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1002, "US", "Event Type ID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1005, "AT", "Attribute Identifier List", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1008, "US", "Action Type ID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1020, "US", "Number of Remaining Suboperations", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1021, "US", "Number of Completed Suboperations", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1022, "US", "Number of Failed Suboperations", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1023, "US", "Number of Warning Suboperations", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1030, "AE", "Move Originator Application Entity Title", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x1031, "US", "Move Originator Message ID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x4000, "LO", "Dialog Receiver", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x4010, "LO", "Terminal Type", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5010, "SH", "Message Set ID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5020, "SH", "End Message Set", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5110, "LO", "Display Format", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5120, "LO", "Page Position ID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5130, "LO", "Text Format ID", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5140, "LO", "Normal Reverse", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5150, "LO", "Add Gray Scale", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5160, "LO", "Borders", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5170, "IS", "Copies", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5180, "LO", "OldMagnificationType", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x5190, "LO", "Erase", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x51a0, "LO", "Print", (DicomElemParseFunc *) NULL },
+ { 0x0000, 0x51b0, "US", "Overlays", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0000, "UL", "Meta Element Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0001, "OB", "File Meta Information Version", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0002, "UI", "Media Storage SOP Class UID", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0003, "UI", "Media Storage SOP Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0010, "UI", "Transfer Syntax UID", (DicomElemParseFunc *) funcDCM_TransferSyntax },
+ { 0x0002, 0x0012, "UI", "Implementation Class UID", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0013, "SH", "Implementation Version Name", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0016, "AE", "Source Application Entity Title", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0100, "UI", "Private Information Creator UID", (DicomElemParseFunc *) NULL },
+ { 0x0002, 0x0102, "OB", "Private Information", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0000, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0008, "US", "ISI Command Field", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0011, "US", "Attach ID Application Code", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0012, "UL", "Attach ID Message Count", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0013, "DA", "Attach ID Date", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0014, "TM", "Attach ID Time", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0020, "US", "Message Type", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0030, "DA", "Max Waiting Date", (DicomElemParseFunc *) NULL },
+ { 0x0003, 0x0031, "TM", "Max Waiting Time", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x0000, "UL", "File Set Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1130, "CS", "File Set ID", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1141, "CS", "File Set Descriptor File ID", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1142, "CS", "File Set Descriptor File Specific Character Set", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1200, "UL", "Root Directory Entity First Directory Record Offset", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1202, "UL", "Root Directory Entity Last Directory Record Offset", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1212, "US", "File Set Consistency Flag", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1220, "SQ", "Directory Record Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1400, "UL", "Next Directory Record Offset", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1410, "US", "Record In Use Flag", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1420, "UL", "Referenced Lower Level Directory Entity Offset", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1430, "CS", "Directory Record Type", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1432, "UI", "Private Record UID", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1500, "CS", "Referenced File ID", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1504, "UL", "MRDR Directory Record Offset", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1510, "UI", "Referenced SOP Class UID In File", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1511, "UI", "Referenced SOP Instance UID In File", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1512, "UI", "Referenced Transfer Syntax UID In File", (DicomElemParseFunc *) NULL },
+ { 0x0004, 0x1600, "UL", "Number of References", (DicomElemParseFunc *) NULL },
+ { 0x0005, 0x0000, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0006, 0x0000, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0000, "UL", "Identifying Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0001, "UL", "Length to End", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0005, "CS", "Specific Character Set", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0008, "CS", "Image Type", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0010, "LO", "Recognition Code", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0012, "DA", "Instance Creation Date", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0013, "TM", "Instance Creation Time", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0014, "UI", "Instance Creator UID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0016, "UI", "SOP Class UID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0018, "UI", "SOP Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0020, "DA", "Study Date", (DicomElemParseFunc *) funcDCM_StudyDate },
+ { 0x0008, 0x0021, "DA", "Series Date", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0022, "DA", "Acquisition Date", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0023, "DA", "Image Date", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0024, "DA", "Overlay Date", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0025, "DA", "Curve Date", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0030, "TM", "Study Time", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0031, "TM", "Series Time", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0032, "TM", "Acquisition Time", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0033, "TM", "Image Time", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0034, "TM", "Overlay Time", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0035, "TM", "Curve Time", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0040, "xs", "Old Data Set Type", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0041, "xs", "Old Data Set Subtype", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0042, "CS", "Nuclear Medicine Series Type", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0050, "SH", "Accession Number", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0052, "CS", "Query/Retrieve Level", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0054, "AE", "Retrieve AE Title", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0058, "UI", "Failed SOP Instance UID List", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0060, "CS", "Modality", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0062, "SQ", "Modality Subtype", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0064, "CS", "Conversion Type", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0068, "CS", "Presentation Intent Type", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0070, "LO", "Manufacturer", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0080, "LO", "Institution Name", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0081, "ST", "Institution Address", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0082, "SQ", "Institution Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0090, "PN", "Referring Physician's Name", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0092, "ST", "Referring Physician's Address", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0094, "SH", "Referring Physician's Telephone Numbers", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0100, "SH", "Code Value", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0102, "SH", "Coding Scheme Designator", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0103, "SH", "Coding Scheme Version", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0104, "LO", "Code Meaning", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0105, "CS", "Mapping Resource", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x0106, "DT", "Context Group Version", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x010b, "CS", "Code Set Extension Flag", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x010c, "UI", "Private Coding Scheme Creator UID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x010d, "UI", "Code Set Extension Creator UID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x010f, "CS", "Context Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1000, "LT", "Network ID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1010, "SH", "Station Name", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1030, "LO", "Study Description", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1032, "SQ", "Procedure Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x103e, "LO", "Series Description", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1040, "LO", "Institutional Department Name", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1048, "PN", "Physician of Record", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1050, "PN", "Performing Physician's Name", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1060, "PN", "Name of Physician(s) Reading Study", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1070, "PN", "Operator's Name", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1080, "LO", "Admitting Diagnosis Description", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1084, "SQ", "Admitting Diagnosis Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1090, "LO", "Manufacturer's Model Name", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1100, "SQ", "Referenced Results Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1110, "SQ", "Referenced Study Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1111, "SQ", "Referenced Study Component Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1115, "SQ", "Referenced Series Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1120, "SQ", "Referenced Patient Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1125, "SQ", "Referenced Visit Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1130, "SQ", "Referenced Overlay Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1140, "SQ", "Referenced Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1145, "SQ", "Referenced Curve Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1148, "SQ", "Referenced Previous Waveform", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x114a, "SQ", "Referenced Simultaneous Waveforms", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x114c, "SQ", "Referenced Subsequent Waveform", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1150, "UI", "Referenced SOP Class UID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1155, "UI", "Referenced SOP Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1160, "IS", "Referenced Frame Number", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1195, "UI", "Transaction UID", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1197, "US", "Failure Reason", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1198, "SQ", "Failed SOP Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x1199, "SQ", "Referenced SOP Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2110, "CS", "Old Lossy Image Compression", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2111, "ST", "Derivation Description", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2112, "SQ", "Source Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2120, "SH", "Stage Name", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2122, "IS", "Stage Number", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2124, "IS", "Number of Stages", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2128, "IS", "View Number", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2129, "IS", "Number of Event Timers", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x212a, "IS", "Number of Views in Stage", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2130, "DS", "Event Elapsed Time(s)", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2132, "LO", "Event Timer Name(s)", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2142, "IS", "Start Trim", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2143, "IS", "Stop Trim", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2144, "IS", "Recommended Display Frame Rate", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2200, "CS", "Transducer Position", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2204, "CS", "Transducer Orientation", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2208, "CS", "Anatomic Structure", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2218, "SQ", "Anatomic Region Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2220, "SQ", "Anatomic Region Modifier Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2228, "SQ", "Primary Anatomic Structure Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2230, "SQ", "Primary Anatomic Structure Modifier Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2240, "SQ", "Transducer Position Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2242, "SQ", "Transducer Position Modifier Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2244, "SQ", "Transducer Orientation Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2246, "SQ", "Transducer Orientation Modifier Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2251, "SQ", "Anatomic Structure Space Or Region Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2253, "SQ", "Anatomic Portal Of Entrance Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2255, "SQ", "Anatomic Approach Direction Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2256, "ST", "Anatomic Perspective Description", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2257, "SQ", "Anatomic Perspective Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2258, "ST", "Anatomic Location Of Examining Instrument Description", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x2259, "SQ", "Anatomic Location Of Examining Instrument Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x225a, "SQ", "Anatomic Structure Space Or Region Modifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x225c, "SQ", "OnAxis Background Anatomic Structure Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0008, 0x4000, "LT", "Identifying Comments", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0000, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0001, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0002, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0003, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0004, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0005, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0006, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0007, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0008, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0009, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x000a, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x000b, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x000c, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x000d, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x000e, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x000f, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0011, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0012, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0013, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0014, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0015, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0016, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0017, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0018, "LT", "Data Set Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x001a, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x001e, "UI", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0020, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0021, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0022, "SH", "User Orientation", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0023, "SL", "Initiation Type", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0024, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0025, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0026, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0027, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0029, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x002a, "SL", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x002c, "LO", "Series Comments", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x002d, "SL", "Track Beat Average", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x002e, "FD", "Distance Prescribed", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x002f, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0030, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0031, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0032, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0034, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0035, "SL", "Gantry Locus Type", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0037, "SL", "Starting Heart Rate", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0038, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0039, "SL", "RR Window Offset", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x003a, "SL", "Percent Cycle Imaged", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x003e, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x003f, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0040, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0041, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0042, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0043, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0050, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0051, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0060, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0061, "LT", "Series Unique Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0070, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0080, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x0091, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00e2, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00e3, "UI", "Equipment UID", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00e6, "SH", "Genesis Version Now", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00e7, "UL", "Exam Record Checksum", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00e8, "UL", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00e9, "SL", "Actual Series Data Time Stamp", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00f2, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00f3, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00f4, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00f5, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00f6, "LT", "PDM Data Object Type Extension", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00f8, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x00fb, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x1002, "OB", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x1003, "OB", "?", (DicomElemParseFunc *) NULL },
+ { 0x0009, 0x1010, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x0000, "UL", "Patient Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x0010, "PN", "Patient's Name", (DicomElemParseFunc *) funcDCM_PatientName },
+ { 0x0010, 0x0020, "LO", "Patient's ID", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x0021, "LO", "Issuer of Patient's ID", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x0030, "DA", "Patient's Birth Date", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x0032, "TM", "Patient's Birth Time", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x0040, "CS", "Patient's Sex", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x0050, "SQ", "Patient's Insurance Plan Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1000, "LO", "Other Patient's ID's", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1001, "PN", "Other Patient's Names", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1005, "PN", "Patient's Birth Name", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1010, "AS", "Patient's Age", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1020, "DS", "Patient's Size", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1030, "DS", "Patient's Weight", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1040, "LO", "Patient's Address", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1050, "LT", "Insurance Plan Identification", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1060, "PN", "Patient's Mother's Birth Name", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1080, "LO", "Military Rank", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1081, "LO", "Branch of Service", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x1090, "LO", "Medical Record Locator", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x2000, "LO", "Medical Alerts", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x2110, "LO", "Contrast Allergies", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x2150, "LO", "Country of Residence", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x2152, "LO", "Region of Residence", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x2154, "SH", "Patients Telephone Numbers", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x2160, "SH", "Ethnic Group", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x2180, "SH", "Occupation", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x21a0, "CS", "Smoking Status", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x21b0, "LT", "Additional Patient History", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x21c0, "US", "Pregnancy Status", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x21d0, "DA", "Last Menstrual Date", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x21f0, "LO", "Patients Religious Preference", (DicomElemParseFunc *) NULL },
+ { 0x0010, 0x4000, "LT", "Patient Comments", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0001, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0002, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0003, "LT", "Patient UID", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0004, "LT", "Patient ID", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x000a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x000b, "SL", "Effective Series Duration", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x000c, "SL", "Num Beats", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x000d, "LO", "Radio Nuclide Name", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0011, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0012, "LO", "Dataset Name", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0013, "LO", "Dataset Type", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0015, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0016, "SL", "Energy Number", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0017, "SL", "RR Interval Window Number", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0018, "SL", "MG Bin Number", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0019, "FD", "Radius Of Rotation", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x001a, "SL", "Detector Count Zone", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x001b, "SL", "Num Energy Windows", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x001c, "SL", "Energy Offset", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x001d, "SL", "Energy Range", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x001f, "SL", "Image Orientation", (DicomElemParseFunc *) funcDCM_ImageOrientation },
+ { 0x0011, 0x0020, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0021, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0022, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0023, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0024, "SL", "FOV Mask Y Cutoff Angle", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0025, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0026, "SL", "Table Orientation", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0027, "SL", "ROI Top Left", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0028, "SL", "ROI Bottom Right", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0030, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0031, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0032, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0033, "LO", "Energy Correct Name", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0034, "LO", "Spatial Correct Name", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0035, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0036, "LO", "Uniformity Correct Name", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0037, "LO", "Acquisition Specific Correct Name", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0038, "SL", "Byte Order", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x003a, "SL", "Picture Format", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x003b, "FD", "Pixel Scale", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x003c, "FD", "Pixel Offset", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x003e, "SL", "FOV Shape", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x003f, "SL", "Dataset Flags", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0040, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0041, "LT", "Medical Alerts", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0042, "LT", "Contrast Allergies", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0044, "FD", "Threshold Center", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0045, "FD", "Threshold Width", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0046, "SL", "Interpolation Type", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0055, "FD", "Period", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x0056, "FD", "ElapsedTime", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00a1, "DA", "Patient Registration Date", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00a2, "TM", "Patient Registration Time", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00b0, "LT", "Patient Last Name", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00b2, "LT", "Patient First Name", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00b4, "LT", "Patient Hospital Status", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00bc, "TM", "Current Location Time", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00c0, "LT", "Patient Insurance Status", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00d0, "LT", "Patient Billing Type", (DicomElemParseFunc *) NULL },
+ { 0x0011, 0x00d2, "LT", "Patient Billing Address", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0000, "LT", "Modifying Physician", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0011, "SL", "?", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0012, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0016, "SL", "AutoTrack Peak", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0017, "SL", "AutoTrack Width", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0018, "FD", "Transmission Scan Time", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0019, "FD", "Transmission Mask Width", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x001a, "FD", "Copper Attenuator Thickness", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x001c, "FD", "?", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x001d, "FD", "?", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x001e, "FD", "Tomo View Offset", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0020, "LT", "Patient Name", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0022, "LT", "Patient Id", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0026, "LT", "Study Comments", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0030, "DA", "Patient Birthdate", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0031, "DS", "Patient Weight", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0032, "LT", "Patients Maiden Name", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0033, "LT", "Referring Physician", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0034, "LT", "Admitting Diagnosis", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0035, "LT", "Patient Sex", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0040, "LT", "Procedure Description", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0042, "LT", "Patient Rest Direction", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0044, "LT", "Patient Position", (DicomElemParseFunc *) NULL },
+ { 0x0013, 0x0046, "LT", "View Direction", (DicomElemParseFunc *) NULL },
+ { 0x0015, 0x0001, "DS", "Stenosis Calibration Ratio", (DicomElemParseFunc *) NULL },
+ { 0x0015, 0x0002, "DS", "Stenosis Magnification", (DicomElemParseFunc *) NULL },
+ { 0x0015, 0x0003, "DS", "Cardiac Calibration Ratio", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0000, "UL", "Acquisition Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0010, "LO", "Contrast/Bolus Agent", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0012, "SQ", "Contrast/Bolus Agent Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0014, "SQ", "Contrast/Bolus Administration Route Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0015, "CS", "Body Part Examined", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0020, "CS", "Scanning Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0021, "CS", "Sequence Variant", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0022, "CS", "Scan Options", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0023, "CS", "MR Acquisition Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0024, "SH", "Sequence Name", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0025, "CS", "Angio Flag", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0026, "SQ", "Intervention Drug Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0027, "TM", "Intervention Drug Stop Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0028, "DS", "Intervention Drug Dose", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0029, "SQ", "Intervention Drug Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x002a, "SQ", "Additional Drug Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0030, "LO", "Radionuclide", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0031, "LO", "Radiopharmaceutical", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0032, "DS", "Energy Window Centerline", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0033, "DS", "Energy Window Total Width", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0034, "LO", "Intervention Drug Name", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0035, "TM", "Intervention Drug Start Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0036, "SQ", "Intervention Therapy Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0037, "CS", "Therapy Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0038, "CS", "Intervention Status", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0039, "CS", "Therapy Description", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0040, "IS", "Cine Rate", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0050, "DS", "Slice Thickness", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0060, "DS", "KVP", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0070, "IS", "Counts Accumulated", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0071, "CS", "Acquisition Termination Condition", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0072, "DS", "Effective Series Duration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0073, "CS", "Acquisition Start Condition", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0074, "IS", "Acquisition Start Condition Data", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0075, "IS", "Acquisition Termination Condition Data", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0080, "DS", "Repetition Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0081, "DS", "Echo Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0082, "DS", "Inversion Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0083, "DS", "Number of Averages", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0084, "DS", "Imaging Frequency", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0085, "SH", "Imaged Nucleus", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0086, "IS", "Echo Number(s)", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0087, "DS", "Magnetic Field Strength", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0088, "DS", "Spacing Between Slices", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0089, "IS", "Number of Phase Encoding Steps", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0090, "DS", "Data Collection Diameter", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0091, "IS", "Echo Train Length", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0093, "DS", "Percent Sampling", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0094, "DS", "Percent Phase Field of View", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x0095, "DS", "Pixel Bandwidth", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1000, "LO", "Device Serial Number", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1004, "LO", "Plate ID", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1010, "LO", "Secondary Capture Device ID", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1012, "DA", "Date of Secondary Capture", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1014, "TM", "Time of Secondary Capture", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1016, "LO", "Secondary Capture Device Manufacturer", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1018, "LO", "Secondary Capture Device Manufacturer Model Name", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1019, "LO", "Secondary Capture Device Software Version(s)", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1020, "LO", "Software Version(s)", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1022, "SH", "Video Image Format Acquired", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1023, "LO", "Digital Image Format Acquired", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1030, "LO", "Protocol Name", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1040, "LO", "Contrast/Bolus Route", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1041, "DS", "Contrast/Bolus Volume", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1042, "TM", "Contrast/Bolus Start Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1043, "TM", "Contrast/Bolus Stop Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1044, "DS", "Contrast/Bolus Total Dose", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1045, "IS", "Syringe Counts", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1046, "DS", "Contrast Flow Rate", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1047, "DS", "Contrast Flow Duration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1048, "CS", "Contrast/Bolus Ingredient", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1049, "DS", "Contrast/Bolus Ingredient Concentration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1050, "DS", "Spatial Resolution", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1060, "DS", "Trigger Time", (DicomElemParseFunc *) funcDCM_TriggerTime },
+ { 0x0018, 0x1061, "LO", "Trigger Source or Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1062, "IS", "Nominal Interval", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1063, "DS", "Frame Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1064, "LO", "Framing Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1065, "DS", "Frame Time Vector", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1066, "DS", "Frame Delay", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1067, "DS", "Image Trigger Delay", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1068, "DS", "Group Time Offset", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1069, "DS", "Trigger Time Offset", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x106a, "CS", "Synchronization Trigger", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x106b, "UI", "Synchronization Frame of Reference", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x106e, "UL", "Trigger Sample Position", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1070, "LO", "Radiopharmaceutical Route", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1071, "DS", "Radiopharmaceutical Volume", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1072, "TM", "Radiopharmaceutical Start Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1073, "TM", "Radiopharmaceutical Stop Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1074, "DS", "Radionuclide Total Dose", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1075, "DS", "Radionuclide Half Life", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1076, "DS", "Radionuclide Positron Fraction", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1077, "DS", "Radiopharmaceutical Specific Activity", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1080, "CS", "Beat Rejection Flag", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1081, "IS", "Low R-R Value", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1082, "IS", "High R-R Value", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1083, "IS", "Intervals Acquired", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1084, "IS", "Intervals Rejected", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1085, "LO", "PVC Rejection", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1086, "IS", "Skip Beats", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1088, "IS", "Heart Rate", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1090, "IS", "Cardiac Number of Images", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1094, "IS", "Trigger Window", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1100, "DS", "Reconstruction Diameter", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1110, "DS", "Distance Source to Detector", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1111, "DS", "Distance Source to Patient", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1114, "DS", "Estimated Radiographic Magnification Factor", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1120, "DS", "Gantry/Detector Tilt", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1121, "DS", "Gantry/Detector Slew", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1130, "DS", "Table Height", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1131, "DS", "Table Traverse", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1134, "CS", "Table Motion", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1135, "DS", "Table Vertical Increment", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1136, "DS", "Table Lateral Increment", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1137, "DS", "Table Longitudinal Increment", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1138, "DS", "Table Angle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x113a, "CS", "Table Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1140, "CS", "Rotation Direction", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1141, "DS", "Angular Position", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1142, "DS", "Radial Position", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1143, "DS", "Scan Arc", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1144, "DS", "Angular Step", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1145, "DS", "Center of Rotation Offset", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1146, "DS", "Rotation Offset", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1147, "CS", "Field of View Shape", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1149, "IS", "Field of View Dimension(s)", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1150, "IS", "Exposure Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1151, "IS", "X-ray Tube Current", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1152, "IS", "Exposure", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1153, "IS", "Exposure in uAs", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1154, "DS", "AveragePulseWidth", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1155, "CS", "RadiationSetting", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1156, "CS", "Rectification Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x115a, "CS", "RadiationMode", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x115e, "DS", "ImageAreaDoseProduct", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1160, "SH", "Filter Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1161, "LO", "TypeOfFilters", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1162, "DS", "IntensifierSize", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1164, "DS", "ImagerPixelSpacing", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1166, "CS", "Grid", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1170, "IS", "Generator Power", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1180, "SH", "Collimator/Grid Name", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1181, "CS", "Collimator Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1182, "IS", "Focal Distance", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1183, "DS", "X Focus Center", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1184, "DS", "Y Focus Center", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1190, "DS", "Focal Spot(s)", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1191, "CS", "Anode Target Material", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x11a0, "DS", "Body Part Thickness", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x11a2, "DS", "Compression Force", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1200, "DA", "Date of Last Calibration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1201, "TM", "Time of Last Calibration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1210, "SH", "Convolution Kernel", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1240, "IS", "Upper/Lower Pixel Values", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1242, "IS", "Actual Frame Duration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1243, "IS", "Count Rate", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1244, "US", "Preferred Playback Sequencing", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1250, "SH", "Receiving Coil", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1251, "SH", "Transmitting Coil", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1260, "SH", "Plate Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1261, "LO", "Phosphor Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1300, "DS", "Scan Velocity", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1301, "CS", "Whole Body Technique", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1302, "IS", "Scan Length", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1310, "US", "Acquisition Matrix", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1312, "CS", "Phase Encoding Direction", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1314, "DS", "Flip Angle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1315, "CS", "Variable Flip Angle Flag", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1316, "DS", "SAR", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1318, "DS", "dB/dt", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1400, "LO", "Acquisition Device Processing Description", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1401, "LO", "Acquisition Device Processing Code", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1402, "CS", "Cassette Orientation", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1403, "CS", "Cassette Size", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1404, "US", "Exposures on Plate", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1405, "IS", "Relative X-ray Exposure", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1450, "DS", "Column Angulation", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1460, "DS", "Tomo Layer Height", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1470, "DS", "Tomo Angle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1480, "DS", "Tomo Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1490, "CS", "Tomo Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1491, "CS", "Tomo Class", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1495, "IS", "Number of Tomosynthesis Source Images", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1500, "CS", "PositionerMotion", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1508, "CS", "Positioner Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1510, "DS", "PositionerPrimaryAngle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1511, "DS", "PositionerSecondaryAngle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1520, "DS", "PositionerPrimaryAngleIncrement", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1521, "DS", "PositionerSecondaryAngleIncrement", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1530, "DS", "DetectorPrimaryAngle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1531, "DS", "DetectorSecondaryAngle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1600, "CS", "Shutter Shape", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1602, "IS", "Shutter Left Vertical Edge", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1604, "IS", "Shutter Right Vertical Edge", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1606, "IS", "Shutter Upper Horizontal Edge", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1608, "IS", "Shutter Lower Horizonta lEdge", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1610, "IS", "Center of Circular Shutter", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1612, "IS", "Radius of Circular Shutter", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1620, "IS", "Vertices of Polygonal Shutter", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1622, "US", "Shutter Presentation Value", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1623, "US", "Shutter Overlay Group", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1700, "CS", "Collimator Shape", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1702, "IS", "Collimator Left Vertical Edge", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1704, "IS", "Collimator Right Vertical Edge", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1706, "IS", "Collimator Upper Horizontal Edge", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1708, "IS", "Collimator Lower Horizontal Edge", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1710, "IS", "Center of Circular Collimator", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1712, "IS", "Radius of Circular Collimator", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1720, "IS", "Vertices of Polygonal Collimator", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1800, "CS", "Acquisition Time Synchronized", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1801, "SH", "Time Source", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x1802, "CS", "Time Distribution Protocol", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x4000, "LT", "Acquisition Comments", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5000, "SH", "Output Power", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5010, "LO", "Transducer Data", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5012, "DS", "Focus Depth", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5020, "LO", "Processing Function", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5021, "LO", "Postprocessing Function", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5022, "DS", "Mechanical Index", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5024, "DS", "Thermal Index", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5026, "DS", "Cranial Thermal Index", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5027, "DS", "Soft Tissue Thermal Index", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5028, "DS", "Soft Tissue-Focus Thermal Index", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5029, "DS", "Soft Tissue-Surface Thermal Index", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5030, "DS", "Dynamic Range", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5040, "DS", "Total Gain", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5050, "IS", "Depth of Scan Field", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5100, "CS", "Patient Position", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5101, "CS", "View Position", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5104, "SQ", "Projection Eponymous Name Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5210, "DS", "Image Transformation Matrix", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x5212, "DS", "Image Translation Vector", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6000, "DS", "Sensitivity", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6011, "IS", "Sequence of Ultrasound Regions", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6012, "US", "Region Spatial Format", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6014, "US", "Region Data Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6016, "UL", "Region Flags", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6018, "UL", "Region Location Min X0", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x601a, "UL", "Region Location Min Y0", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x601c, "UL", "Region Location Max X1", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x601e, "UL", "Region Location Max Y1", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6020, "SL", "Reference Pixel X0", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6022, "SL", "Reference Pixel Y0", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6024, "US", "Physical Units X Direction", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6026, "US", "Physical Units Y Direction", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6028, "FD", "Reference Pixel Physical Value X", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x602a, "US", "Reference Pixel Physical Value Y", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x602c, "US", "Physical Delta X", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x602e, "US", "Physical Delta Y", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6030, "UL", "Transducer Frequency", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6031, "CS", "Transducer Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6032, "UL", "Pulse Repetition Frequency", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6034, "FD", "Doppler Correction Angle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6036, "FD", "Steering Angle", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6038, "UL", "Doppler Sample Volume X Position", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x603a, "UL", "Doppler Sample Volume Y Position", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x603c, "UL", "TM-Line Position X0", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x603e, "UL", "TM-Line Position Y0", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6040, "UL", "TM-Line Position X1", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6042, "UL", "TM-Line Position Y1", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6044, "US", "Pixel Component Organization", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6046, "UL", "Pixel Component Mask", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6048, "UL", "Pixel Component Range Start", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x604a, "UL", "Pixel Component Range Stop", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x604c, "US", "Pixel Component Physical Units", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x604e, "US", "Pixel Component Data Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6050, "UL", "Number of Table Break Points", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6052, "UL", "Table of X Break Points", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6054, "FD", "Table of Y Break Points", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6056, "UL", "Number of Table Entries", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x6058, "UL", "Table of Pixel Values", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x605a, "FL", "Table of Parameter Values", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7000, "CS", "Detector Conditions Nominal Flag", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7001, "DS", "Detector Temperature", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7004, "CS", "Detector Type", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7005, "CS", "Detector Configuration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7006, "LT", "Detector Description", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7008, "LT", "Detector Mode", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x700a, "SH", "Detector ID", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x700c, "DA", "Date of Last Detector Calibration ", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x700e, "TM", "Time of Last Detector Calibration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7010, "IS", "Exposures on Detector Since Last Calibration", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7011, "IS", "Exposures on Detector Since Manufactured", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7012, "DS", "Detector Time Since Last Exposure", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7014, "DS", "Detector Active Time", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7016, "DS", "Detector Activation Offset From Exposure", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x701a, "DS", "Detector Binning", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7020, "DS", "Detector Element Physical Size", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7022, "DS", "Detector Element Spacing", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7024, "CS", "Detector Active Shape", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7026, "DS", "Detector Active Dimensions", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7028, "DS", "Detector Active Origin", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7030, "DS", "Field of View Origin", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7032, "DS", "Field of View Rotation", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7034, "CS", "Field of View Horizontal Flip", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7040, "LT", "Grid Absorbing Material", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7041, "LT", "Grid Spacing Material", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7042, "DS", "Grid Thickness", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7044, "DS", "Grid Pitch", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7046, "IS", "Grid Aspect Ratio", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7048, "DS", "Grid Period", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x704c, "DS", "Grid Focal Distance", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7050, "LT", "Filter Material", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7052, "DS", "Filter Thickness Minimum", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7054, "DS", "Filter Thickness Maximum", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7060, "CS", "Exposure Control Mode", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7062, "LT", "Exposure Control Mode Description", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7064, "CS", "Exposure Status", (DicomElemParseFunc *) NULL },
+ { 0x0018, 0x7065, "DS", "Phototimer Setting", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0000, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0001, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0002, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0003, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0004, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0005, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0006, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0007, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0008, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0009, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x000a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x000b, "DS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x000c, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x000d, "TM", "Time", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x000e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x000f, "DS", "Horizontal Frame Of Reference", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0011, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0012, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0013, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0014, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0015, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0016, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0017, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0018, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0019, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x001a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x001b, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x001c, "CS", "Dose", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x001d, "IS", "Side Mark", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x001e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x001f, "DS", "Exposure Duration", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0020, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0021, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0022, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0023, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0024, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0025, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0026, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0027, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0028, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0029, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x002a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x002b, "DS", "Xray Off Position", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x002c, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x002d, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x002e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x002f, "DS", "Trigger Frequency", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0030, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0031, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0032, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0033, "UN", "ECG 2 Offset 2", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0034, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0036, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0038, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0039, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x003a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x003b, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x003c, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x003e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x003f, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0040, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0041, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0042, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0043, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0044, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0045, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0046, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0047, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0048, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0049, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x004a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x004b, "SL", "Data Size For Scan Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x004c, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x004e, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0050, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0051, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0052, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0053, "LT", "Barcode", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0054, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0055, "DS", "Receiver Reference Gain", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0056, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0057, "SS", "CT Water Number", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0058, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x005a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x005c, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x005d, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x005e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x005f, "SL", "Increment Between Channels", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0060, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0061, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0062, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0063, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0064, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0065, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0066, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0067, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0068, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0069, "UL", "Convolution Mode", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x006a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x006b, "SS", "Field Of View In Detector Cells", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x006c, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x006e, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0070, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0071, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0072, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0073, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0074, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0075, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0076, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0077, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0078, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x007a, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x007c, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x007d, "DS", "Second Echo", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x007e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x007f, "DS", "Table Delta", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0080, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0081, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0082, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0083, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0084, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0085, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0086, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0087, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0088, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x008a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x008b, "SS", "Actual Receive Gain Digital", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x008c, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x008d, "DS", "Delay After Trigger", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x008e, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x008f, "SS", "Swap Phase Frequency", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0090, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0091, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0092, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0093, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0094, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0095, "SS", "Analog Receiver Gain", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0096, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0097, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0098, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x0099, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x009a, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x009b, "SS", "Pulse Sequence Mode", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x009c, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x009d, "DT", "Pulse Sequence Date", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x009e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x009f, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a0, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a1, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a2, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a3, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a4, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a5, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a6, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a7, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a8, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00a9, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00aa, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00ab, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00ac, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00ad, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00ae, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00af, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b0, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b1, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b2, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b3, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b4, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b5, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b6, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b7, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b8, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00b9, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00ba, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00bb, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00bc, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00bd, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00be, "DS", "Projection Angle", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c0, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c1, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c2, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c3, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c4, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c5, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c6, "SS", "SAT Location H", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c7, "SS", "SAT Location F", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c8, "SS", "SAT Thickness R L", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00c9, "SS", "SAT Thickness A P", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00ca, "SS", "SAT Thickness H F", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00cb, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00cc, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00cd, "SS", "Thickness Disclaimer", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00ce, "SS", "Prescan Type", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00cf, "SS", "Prescan Status", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d0, "SH", "Raw Data Type", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d1, "DS", "Flow Sensitivity", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d2, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d3, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d4, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d5, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d6, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d7, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d8, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00d9, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00da, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00db, "DS", "Back Projector Coefficient", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00dc, "SS", "Primary Speed Correction Used", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00dd, "SS", "Overrange Correction Used", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00de, "DS", "Dynamic Z Alpha Value", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00df, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e0, "DS", "User Data", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e1, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e2, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e3, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e4, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e5, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e6, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e8, "DS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00e9, "DS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00eb, "DS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00ec, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00f0, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00f1, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00f2, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00f3, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00f4, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x00f9, "DS", "Transmission Gain", (DicomElemParseFunc *) NULL },
+ { 0x0019, 0x1015, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0000, "UL", "Relationship Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x000d, "UI", "Study Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x000e, "UI", "Series Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0010, "SH", "Study ID", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0011, "IS", "Series Number", (DicomElemParseFunc *) funcDCM_SeriesNumber },
+ { 0x0020, 0x0012, "IS", "Acquisition Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0013, "IS", "Instance (formerly Image) Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0014, "IS", "Isotope Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0015, "IS", "Phase Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0016, "IS", "Interval Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0017, "IS", "Time Slot Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0018, "IS", "Angle Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0020, "CS", "Patient Orientation", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0022, "IS", "Overlay Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0024, "IS", "Curve Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0026, "IS", "LUT Number", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0030, "DS", "Image Position", (DicomElemParseFunc *) funcDCM_ImagePosition },
+ { 0x0020, 0x0032, "DS", "Image Position (Patient)", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0035, "DS", "Image Orientation", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0037, "DS", "Image Orientation (Patient)", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0050, "DS", "Location", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0052, "UI", "Frame of Reference UID", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0060, "CS", "Laterality", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0062, "CS", "Image Laterality", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0070, "LT", "Image Geometry Type", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0080, "LO", "Masking Image", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0100, "IS", "Temporal Position Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0105, "IS", "Number of Temporal Positions", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x0110, "DS", "Temporal Resolution", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1000, "IS", "Series in Study", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1001, "DS", "Acquisitions in Series", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1002, "IS", "Images in Acquisition", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1003, "IS", "Images in Series", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1004, "IS", "Acquisitions in Study", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1005, "IS", "Images in Study", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1020, "LO", "Reference", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1040, "LO", "Position Reference Indicator", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1041, "DS", "Slice Location", (DicomElemParseFunc *) funcDCM_SliceLocation },
+ { 0x0020, 0x1070, "IS", "Other Study Numbers", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1200, "IS", "Number of Patient Related Studies", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1202, "IS", "Number of Patient Related Series", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1204, "IS", "Number of Patient Related Images", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1206, "IS", "Number of Study Related Series", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x1208, "IS", "Number of Study Related Series", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x3100, "LO", "Source Image IDs", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x3401, "LO", "Modifying Device ID", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x3402, "LO", "Modified Image ID", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x3403, "xs", "Modified Image Date", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x3404, "LO", "Modifying Device Manufacturer", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x3405, "xs", "Modified Image Time", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x3406, "xs", "Modified Image Description", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x4000, "LT", "Image Comments", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x5000, "AT", "Original Image Identification", (DicomElemParseFunc *) NULL },
+ { 0x0020, 0x5002, "LO", "Original Image Identification Nomenclature", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0000, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0001, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0002, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0003, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0004, "DS", "VOI Position", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0005, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0006, "IS", "CSI Matrix Size Original", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0007, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0008, "DS", "Spatial Grid Shift", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0009, "DS", "Signal Limits Minimum", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0011, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0012, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0013, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0014, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0015, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0016, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0017, "DS", "EPI Operation Mode Flag", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0018, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0019, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0020, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0021, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0022, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0024, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0025, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0026, "IS", "Image Pixel Offset", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0030, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0031, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0032, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0034, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0035, "SS", "Series From Which Prescribed", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0036, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0037, "SS", "Screen Format", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0039, "DS", "Slab Thickness", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0040, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0041, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0042, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0043, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0044, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0045, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0046, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0047, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0048, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0049, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x004a, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x004e, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x004f, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0050, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0051, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0052, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0053, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0054, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0055, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0056, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0057, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0058, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0059, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x005a, "SL", "Integer Slop", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x005b, "DS", "Float Slop", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x005c, "DS", "Float Slop", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x005d, "DS", "Float Slop", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x005e, "DS", "Float Slop", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x005f, "DS", "Float Slop", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0060, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0061, "DS", "Image Normal", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0062, "IS", "Reference Type Code", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0063, "DS", "Image Distance", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0065, "US", "Image Positioning History Mask", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x006a, "DS", "Image Row", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x006b, "DS", "Image Column", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0070, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0071, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0072, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0073, "DS", "Second Repetition Time", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0075, "DS", "Light Brightness", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0076, "DS", "Light Contrast", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x007a, "IS", "Overlay Threshold", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x007b, "IS", "Surface Threshold", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x007c, "IS", "Grey Scale Threshold", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0080, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0081, "DS", "Auto Window Level Alpha", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0082, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0083, "DS", "Auto Window Level Window", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0084, "DS", "Auto Window Level Level", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0090, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0091, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0092, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0093, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0094, "DS", "EPI Change Value of X Component", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0095, "DS", "EPI Change Value of Y Component", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x0096, "DS", "EPI Change Value of Z Component", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x00a0, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x00a1, "DS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x00a2, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x00a3, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x00a4, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x00a7, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x00b0, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0021, 0x00c0, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0000, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0001, "SL", "Number Of Series In Study", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0002, "SL", "Number Of Unarchived Series", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0020, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0030, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0040, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0050, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0060, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0070, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0074, "SL", "Number Of Updates To Info", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x007d, "SS", "Indicates If Study Has Complete Info", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0080, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x0090, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0023, 0x00ff, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0000, "UL", "Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0006, "SS", "Last Pulse Sequence Used", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0007, "SL", "Images In Series", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0010, "SS", "Landmark Counter", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0011, "SS", "Number Of Acquisitions", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0014, "SL", "Indicates Number Of Updates To Info", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0017, "SL", "Series Complete Flag", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0018, "SL", "Number Of Images Archived", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x0019, "SL", "Last Image Number Used", (DicomElemParseFunc *) NULL },
+ { 0x0025, 0x001a, "SH", "Primary Receiver Suite And Host", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0000, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0006, "SL", "Image Archive Flag", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0010, "SS", "Scout Type", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0011, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0012, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0013, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0014, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0015, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0016, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x001c, "SL", "Vma Mamp", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x001d, "SS", "Vma Phase", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x001e, "SL", "Vma Mod", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x001f, "SL", "Vma Clip", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0020, "SS", "Smart Scan On Off Flag", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0030, "SH", "Foreign Image Revision", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0031, "SS", "Imaging Mode", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0032, "SS", "Pulse Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0033, "SL", "Imaging Options", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0035, "SS", "Plane Type", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0036, "SL", "Oblique Plane", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0040, "SH", "RAS Letter Of Image Location", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0041, "FL", "Image Location", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0042, "FL", "Center R Coord Of Plane Image", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0043, "FL", "Center A Coord Of Plane Image", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0044, "FL", "Center S Coord Of Plane Image", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0045, "FL", "Normal R Coord", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0046, "FL", "Normal A Coord", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0047, "FL", "Normal S Coord", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0048, "FL", "R Coord Of Top Right Corner", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0049, "FL", "A Coord Of Top Right Corner", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x004a, "FL", "S Coord Of Top Right Corner", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x004b, "FL", "R Coord Of Bottom Right Corner", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x004c, "FL", "A Coord Of Bottom Right Corner", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x004d, "FL", "S Coord Of Bottom Right Corner", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0050, "FL", "Table Start Location", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0051, "FL", "Table End Location", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0052, "SH", "RAS Letter For Side Of Image", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0053, "SH", "RAS Letter For Anterior Posterior", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0054, "SH", "RAS Letter For Scout Start Loc", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0055, "SH", "RAS Letter For Scout End Loc", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0060, "FL", "Image Dimension X", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0061, "FL", "Image Dimension Y", (DicomElemParseFunc *) NULL },
+ { 0x0027, 0x0062, "FL", "Number Of Excitations", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0000, "UL", "Image Presentation Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0002, "US", "Samples per Pixel", (DicomElemParseFunc *) funcDCM_SamplesPerPixel },
+ { 0x0028, 0x0004, "CS", "Photometric Interpretation", (DicomElemParseFunc *) funcDCM_PhotometricInterpretation },
+ { 0x0028, 0x0005, "US", "Image Dimensions", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0006, "US", "Planar Configuration", (DicomElemParseFunc *) funcDCM_PlanarConfiguration },
+ { 0x0028, 0x0008, "IS", "Number of Frames", (DicomElemParseFunc *) funcDCM_NumberOfFrames },
+ { 0x0028, 0x0009, "AT", "Frame Increment Pointer", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0010, "US", "Rows", (DicomElemParseFunc *) funcDCM_Rows },
+ { 0x0028, 0x0011, "US", "Columns", (DicomElemParseFunc *) funcDCM_Columns },
+ { 0x0028, 0x0012, "US", "Planes", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0014, "US", "Ultrasound Color Data Present", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0030, "DS", "Pixel Spacing", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0031, "DS", "Zoom Factor", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0032, "DS", "Zoom Center", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0034, "IS", "Pixel Aspect Ratio", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0040, "LO", "Image Format", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0050, "LT", "Manipulated Image", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0051, "CS", "Corrected Image", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x005f, "LO", "Compression Recognition Code", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0060, "LO", "Compression Code", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0061, "SH", "Compression Originator", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0062, "SH", "Compression Label", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0063, "SH", "Compression Description", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0065, "LO", "Compression Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0066, "AT", "Compression Step Pointers", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0068, "US", "Repeat Interval", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0069, "US", "Bits Grouped", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0070, "US", "Perimeter Table", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0071, "xs", "Perimeter Value", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0080, "US", "Predictor Rows", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0081, "US", "Predictor Columns", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0082, "US", "Predictor Constants", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0090, "LO", "Blocked Pixels", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0091, "US", "Block Rows", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0092, "US", "Block Columns", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0093, "US", "Row Overlap", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0094, "US", "Column Overlap", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0100, "US", "Bits Allocated", (DicomElemParseFunc *) funcDCM_BitsAllocated },
+ { 0x0028, 0x0101, "US", "Bits Stored", (DicomElemParseFunc *) funcDCM_BitsStored },
+ { 0x0028, 0x0102, "US", "High Bit", (DicomElemParseFunc *) funcDCM_HighBit },
+ { 0x0028, 0x0103, "US", "Pixel Representation", (DicomElemParseFunc *) funcDCM_PixelRepresentation },
+ { 0x0028, 0x0104, "xs", "Smallest Valid Pixel Value", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0105, "xs", "Largest Valid Pixel Value", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0106, "xs", "Smallest Image Pixel Value", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0107, "xs", "Largest Image Pixel Value", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0108, "xs", "Smallest Pixel Value in Series", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0109, "xs", "Largest Pixel Value in Series", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0110, "xs", "Smallest Pixel Value in Plane", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0111, "xs", "Largest Pixel Value in Plane", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0120, "xs", "Pixel Padding Value", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0121, "xs", "Pixel Padding Range Limit", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0200, "xs", "Image Location", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0300, "CS", "Quality Control Image", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0301, "CS", "Burned In Annotation", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0400, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0401, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0402, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0403, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0404, "AT", "Details of Coefficients", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0700, "LO", "DCT Label", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0701, "LO", "Data Block Description", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0702, "AT", "Data Block", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0710, "US", "Normalization Factor Format", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0720, "US", "Zonal Map Number Format", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0721, "AT", "Zonal Map Location", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0722, "US", "Zonal Map Format", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0730, "US", "Adaptive Map Format", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0740, "US", "Code Number Format", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0800, "LO", "Code Label", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0802, "US", "Number of Tables", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0803, "AT", "Code Table Location", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0804, "US", "Bits For Code Word", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x0808, "AT", "Image Data Location", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1040, "CS", "Pixel Intensity Relationship", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1041, "SS", "Pixel Intensity Relationship Sign", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1050, "DS", "Window Center", (DicomElemParseFunc *) funcDCM_WindowCenter },
+ { 0x0028, 0x1051, "DS", "Window Width", (DicomElemParseFunc *) funcDCM_WindowWidth },
+ { 0x0028, 0x1052, "DS", "Rescale Intercept", (DicomElemParseFunc *) funcDCM_RescaleIntercept },
+ { 0x0028, 0x1053, "DS", "Rescale Slope", (DicomElemParseFunc *) funcDCM_RescaleSlope },
+ { 0x0028, 0x1054, "LO", "Rescale Type", (DicomElemParseFunc *) funcDCM_RescaleType },
+ { 0x0028, 0x1055, "LO", "Window Center & Width Explanation", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1080, "LO", "Gray Scale", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1090, "CS", "Recommended Viewing Mode", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1100, "xs", "Gray Lookup Table Descriptor", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1101, "xs", "Red Palette Color Lookup Table Descriptor", (DicomElemParseFunc *) funcDCM_PaletteDescriptor },
+ { 0x0028, 0x1102, "xs", "Green Palette Color Lookup Table Descriptor", (DicomElemParseFunc *) funcDCM_PaletteDescriptor },
+ { 0x0028, 0x1103, "xs", "Blue Palette Color Lookup Table Descriptor", (DicomElemParseFunc *) funcDCM_PaletteDescriptor },
+ { 0x0028, 0x1111, "OW", "Large Red Palette Color Lookup Table Descriptor", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1112, "OW", "Large Green Palette Color Lookup Table Descriptor", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1113, "OW", "Large Blue Palette Color Lookup Table Descriptor", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1199, "UI", "Palette Color Lookup Table UID", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1200, "xs", "Gray Lookup Table Data", (DicomElemParseFunc *) funcDCM_LUT },
+ { 0x0028, 0x1201, "OW", "Red Palette Color Lookup Table Data", (DicomElemParseFunc *) funcDCM_Palette },
+ { 0x0028, 0x1202, "OW", "Green Palette Color Lookup Table Data", (DicomElemParseFunc *) funcDCM_Palette },
+ { 0x0028, 0x1203, "OW", "Blue Palette Color Lookup Table Data", (DicomElemParseFunc *) funcDCM_Palette },
+ { 0x0028, 0x1211, "OW", "Large Red Palette Color Lookup Table Data", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1212, "OW", "Large Green Palette Color Lookup Table Data", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1213, "OW", "Large Blue Palette Color Lookup Table Data", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1214, "UI", "Large Palette Color Lookup Table UID", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1221, "OW", "Segmented Red Palette Color Lookup Table Data", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1222, "OW", "Segmented Green Palette Color Lookup Table Data", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1223, "OW", "Segmented Blue Palette Color Lookup Table Data", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x1300, "CS", "Implant Present", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x2110, "CS", "Lossy Image Compression", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x2112, "DS", "Lossy Image Compression Ratio", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x3000, "SQ", "Modality LUT Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x3002, "US", "LUT Descriptor", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x3003, "LO", "LUT Explanation", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x3004, "LO", "Modality LUT Type", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x3006, "US", "LUT Data", (DicomElemParseFunc *) funcDCM_LUT },
+ { 0x0028, 0x3010, "xs", "VOI LUT Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x4000, "LT", "Image Presentation Comments", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x5000, "SQ", "Biplane Acquisition Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6010, "US", "Representative Frame Number", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6020, "US", "Frame Numbers of Interest", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6022, "LO", "Frame of Interest Description", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6030, "US", "Mask Pointer", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6040, "US", "R Wave Pointer", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6100, "SQ", "Mask Subtraction Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6101, "CS", "Mask Operation", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6102, "US", "Applicable Frame Range", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6110, "US", "Mask Frame Numbers", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6112, "US", "Contrast Frame Averaging", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6114, "FL", "Mask Sub-Pixel Shift", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6120, "SS", "TID Offset", (DicomElemParseFunc *) NULL },
+ { 0x0028, 0x6190, "ST", "Mask Operation Explanation", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0000, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0001, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0002, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0003, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0004, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0005, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0006, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0007, "SL", "Lower Range Of Pixels", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0008, "SH", "Lower Range Of Pixels", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0009, "SH", "Lower Range Of Pixels", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x000a, "SS", "Lower Range Of Pixels", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x000c, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x000e, "CS", "Zoom Enable Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x000f, "CS", "Zoom Select Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0011, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0013, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0015, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0016, "SL", "Lower Range Of Pixels", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0017, "SL", "Lower Range Of Pixels", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0018, "SL", "Upper Range Of Pixels", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x001a, "SL", "Length Of Total Info In Bytes", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x001e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x001f, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0020, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0022, "IS", "Pixel Quality Value", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0025, "LT", "Processed Pixel Data Quality", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0026, "SS", "Version Of Info Structure", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0030, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0031, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0032, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0033, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0034, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0035, "SL", "Advantage Comp Underflow", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0038, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0040, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0041, "DS", "Magnifying Glass Rectangle", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0043, "DS", "Magnifying Glass Factor", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0044, "US", "Magnifying Glass Function", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x004e, "CS", "Magnifying Glass Enable Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x004f, "CS", "Magnifying Glass Select Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0050, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0051, "LT", "Exposure Code", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0052, "LT", "Sort Code", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0053, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0060, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0061, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0067, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0070, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0071, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0072, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0077, "CS", "Window Select Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0078, "LT", "ECG Display Printing ID", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0079, "CS", "ECG Display Printing", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x007e, "CS", "ECG Display Printing Enable Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x007f, "CS", "ECG Display Printing Select Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0080, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0081, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0082, "IS", "View Zoom", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0083, "IS", "View Transform", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x008e, "CS", "Physiological Display Enable Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x008f, "CS", "Physiological Display Select Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0090, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x0099, "LT", "Shutter Type", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00a0, "US", "Rows of Rectangular Shutter", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00a1, "US", "Columns of Rectangular Shutter", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00a2, "US", "Origin of Rectangular Shutter", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00b0, "US", "Radius of Circular Shutter", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00b2, "US", "Origin of Circular Shutter", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00c0, "LT", "Functional Shutter ID", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00c1, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00c3, "IS", "Scan Resolution", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00c4, "IS", "Field of View", (DicomElemParseFunc *) funcDCM_FieldOfView },
+ { 0x0029, 0x00c5, "LT", "Field Of Shutter Rectangle", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00ce, "CS", "Shutter Enable Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00cf, "CS", "Shutter Select Status", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00d0, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00d1, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x0029, 0x00d5, "LT", "Slice Thickness", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x0010, "LT", "Request UID", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x0012, "LT", "Examination Reason", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x0030, "DA", "Requested Date", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x0032, "TM", "Worklist Request Start Time", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x0033, "TM", "Worklist Request End Time", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x0045, "LT", "Requesting Physician", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x004a, "TM", "Requested Time", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x0050, "LT", "Requested Physician", (DicomElemParseFunc *) NULL },
+ { 0x0031, 0x0080, "LT", "Requested Location", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x0000, "UL", "Study Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x000a, "CS", "Study Status ID", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x000c, "CS", "Study Priority ID", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x0012, "LO", "Study ID Issuer", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x0032, "DA", "Study Verified Date", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x0033, "TM", "Study Verified Time", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x0034, "DA", "Study Read Date", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x0035, "TM", "Study Read Time", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1000, "DA", "Scheduled Study Start Date", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1001, "TM", "Scheduled Study Start Time", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1010, "DA", "Scheduled Study Stop Date", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1011, "TM", "Scheduled Study Stop Time", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1020, "LO", "Scheduled Study Location", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1021, "AE", "Scheduled Study Location AE Title(s)", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1030, "LO", "Reason for Study", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1032, "PN", "Requesting Physician", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1033, "LO", "Requesting Service", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1040, "DA", "Study Arrival Date", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1041, "TM", "Study Arrival Time", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1050, "DA", "Study Completion Date", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1051, "TM", "Study Completion Time", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1055, "CS", "Study Component Status ID", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1060, "LO", "Requested Procedure Description", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1064, "SQ", "Requested Procedure Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x1070, "LO", "Requested Contrast Agent", (DicomElemParseFunc *) NULL },
+ { 0x0032, 0x4000, "LT", "Study Comments", (DicomElemParseFunc *) NULL },
+ { 0x0033, 0x0001, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0033, 0x0002, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0033, 0x0005, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0033, 0x0006, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x0033, 0x0010, "LT", "Patient Study UID", (DicomElemParseFunc *) NULL },
+ { 0x0037, 0x0010, "LO", "ReferringDepartment", (DicomElemParseFunc *) NULL },
+ { 0x0037, 0x0020, "US", "ScreenNumber", (DicomElemParseFunc *) NULL },
+ { 0x0037, 0x0040, "SH", "LeftOrientation", (DicomElemParseFunc *) NULL },
+ { 0x0037, 0x0042, "SH", "RightOrientation", (DicomElemParseFunc *) NULL },
+ { 0x0037, 0x0050, "CS", "Inversion", (DicomElemParseFunc *) NULL },
+ { 0x0037, 0x0060, "US", "DSA", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0000, "UL", "Visit Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0004, "SQ", "Referenced Patient Alias Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0008, "CS", "Visit Status ID", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0010, "LO", "Admission ID", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0011, "LO", "Issuer of Admission ID", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0016, "LO", "Route of Admissions", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x001a, "DA", "Scheduled Admission Date", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x001b, "TM", "Scheduled Admission Time", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x001c, "DA", "Scheduled Discharge Date", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x001d, "TM", "Scheduled Discharge Time", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x001e, "LO", "Scheduled Patient Institution Residence", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0020, "DA", "Admitting Date", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0021, "TM", "Admitting Time", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0030, "DA", "Discharge Date", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0032, "TM", "Discharge Time", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0040, "LO", "Discharge Diagnosis Description", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0044, "SQ", "Discharge Diagnosis Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0050, "LO", "Special Needs", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0300, "LO", "Current Patient Location", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0400, "LO", "Patient's Institution Residence", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x0500, "LO", "Patient State", (DicomElemParseFunc *) NULL },
+ { 0x0038, 0x4000, "LT", "Visit Comments", (DicomElemParseFunc *) NULL },
+ { 0x0039, 0x0080, "IS", "Private Entity Number", (DicomElemParseFunc *) NULL },
+ { 0x0039, 0x0085, "DA", "Private Entity Date", (DicomElemParseFunc *) NULL },
+ { 0x0039, 0x0090, "TM", "Private Entity Time", (DicomElemParseFunc *) NULL },
+ { 0x0039, 0x0095, "LO", "Private Entity Launch Command", (DicomElemParseFunc *) NULL },
+ { 0x0039, 0x00aa, "CS", "Private Entity Type", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0002, "SQ", "Waveform Sequence", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0005, "US", "Waveform Number of Channels", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0010, "UL", "Waveform Number of Samples", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x001a, "DS", "Sampling Frequency", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0020, "SH", "Group Label", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0103, "CS", "Waveform Sample Value Representation", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0122, "OB", "Waveform Padding Value", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0200, "SQ", "Channel Definition", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0202, "IS", "Waveform Channel Number", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0203, "SH", "Channel Label", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0205, "CS", "Channel Status", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0208, "SQ", "Channel Source", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0209, "SQ", "Channel Source Modifiers", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x020a, "SQ", "Differential Channel Source", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x020b, "SQ", "Differential Channel Source Modifiers", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0210, "DS", "Channel Sensitivity", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0211, "SQ", "Channel Sensitivity Units", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0212, "DS", "Channel Sensitivity Correction Factor", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0213, "DS", "Channel Baseline", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0214, "DS", "Channel Time Skew", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0215, "DS", "Channel Sample Skew", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0216, "OB", "Channel Minimum Value", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0217, "OB", "Channel Maximum Value", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0218, "DS", "Channel Offset", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x021a, "US", "Bits Per Sample", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0220, "DS", "Filter Low Frequency", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0221, "DS", "Filter High Frequency", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0222, "DS", "Notch Filter Frequency", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x0223, "DS", "Notch Filter Bandwidth", (DicomElemParseFunc *) NULL },
+ { 0x003a, 0x1000, "OB", "Waveform Data", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0001, "AE", "Scheduled Station AE Title", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0002, "DA", "Scheduled Procedure Step Start Date", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0003, "TM", "Scheduled Procedure Step Start Time", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0004, "DA", "Scheduled Procedure Step End Date", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0005, "TM", "Scheduled Procedure Step End Time", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0006, "PN", "Scheduled Performing Physician Name", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0007, "LO", "Scheduled Procedure Step Description", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0008, "SQ", "Scheduled Action Item Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0009, "SH", "Scheduled Procedure Step ID", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0010, "SH", "Scheduled Station Name", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0011, "SH", "Scheduled Procedure Step Location", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0012, "LO", "Pre-Medication", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0020, "CS", "Scheduled Procedure Step Status", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0100, "SQ", "Scheduled Procedure Step Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0302, "US", "Entrance Dose", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0303, "US", "Exposed Area", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0306, "DS", "Distance Source to Entrance", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0307, "DS", "Distance Source to Support", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0310, "ST", "Comments On Radiation Dose", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0312, "DS", "X-Ray Output", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0314, "DS", "Half Value Layer", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0316, "DS", "Organ Dose", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0318, "CS", "Organ Exposed", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0400, "LT", "Comments On Scheduled Procedure Step", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x050a, "LO", "Specimen Accession Number", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0550, "SQ", "Specimen Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0551, "LO", "Specimen Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0552, "SQ", "Specimen Description Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0553, "ST", "Specimen Description", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0555, "SQ", "Acquisition Context Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x0556, "ST", "Acquisition Context Description", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x059a, "SQ", "Specimen Type Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x06fa, "LO", "Slide Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x071a, "SQ", "Image Center Point Coordinates Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x072a, "DS", "X Offset In Slide Coordinate System", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x073a, "DS", "Y Offset In Slide Coordinate System", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x074a, "DS", "Z Offset In Slide Coordinate System", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x08d8, "SQ", "Pixel Spacing Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x08da, "SQ", "Coordinate System Axis Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x08ea, "SQ", "Measurement Units Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x09f8, "SQ", "Vital Stain Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1001, "SH", "Requested Procedure ID", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1002, "LO", "Reason For Requested Procedure", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1003, "SH", "Requested Procedure Priority", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1004, "LO", "Patient Transport Arrangements", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1005, "LO", "Requested Procedure Location", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1006, "SH", "Placer Order Number of Procedure", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1007, "SH", "Filler Order Number of Procedure", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1008, "LO", "Confidentiality Code", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1009, "SH", "Reporting Priority", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1010, "PN", "Names of Intended Recipients of Results", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x1400, "LT", "Requested Procedure Comments", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2001, "LO", "Reason For Imaging Service Request", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2004, "DA", "Issue Date of Imaging Service Request", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2005, "TM", "Issue Time of Imaging Service Request", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2006, "SH", "Placer Order Number of Imaging Service Request", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2007, "SH", "Filler Order Number of Imaging Service Request", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2008, "PN", "Order Entered By", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2009, "SH", "Order Enterer Location", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2010, "SH", "Order Callback Phone Number", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x2400, "LT", "Imaging Service Request Comments", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0x3001, "LO", "Confidentiality Constraint On Patient Data", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa007, "CS", "Findings Flag", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa020, "SQ", "Findings Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa021, "UI", "Findings Group UID", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa022, "UI", "Referenced Findings Group UID", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa023, "DA", "Findings Group Recording Date", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa024, "TM", "Findings Group Recording Time", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa026, "SQ", "Findings Source Category Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa027, "LO", "Documenting Organization", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa028, "SQ", "Documenting Organization Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa032, "LO", "History Reliability Qualifier Description", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa043, "SQ", "Concept Name Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa047, "LO", "Measurement Precision Description", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa057, "CS", "Urgency or Priority Alerts", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa060, "LO", "Sequencing Indicator", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa066, "SQ", "Document Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa067, "PN", "Document Author", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa068, "SQ", "Document Author Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa070, "SQ", "Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa073, "LO", "Object String Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa074, "OB", "Object Binary Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa075, "PN", "Documenting Observer", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa076, "SQ", "Documenting Observer Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa078, "SQ", "Observation Subject Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa080, "SQ", "Person Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa085, "SQ", "Procedure Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa088, "LO", "Object Directory String Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa089, "OB", "Object Directory Binary Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa090, "CS", "History Reliability Qualifier", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa0a0, "CS", "Referenced Type of Data", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa0b0, "US", "Referenced Waveform Channels", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa110, "DA", "Date of Document or Verbal Transaction", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa112, "TM", "Time of Document Creation or Verbal Transaction", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa121, "DA", "Date", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa122, "TM", "Time", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa123, "PN", "Person Name", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa124, "SQ", "Referenced Person Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa125, "CS", "Report Status ID", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa130, "CS", "Temporal Range Type", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa132, "UL", "Referenced Sample Offsets", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa136, "US", "Referenced Frame Numbers", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa138, "DS", "Referenced Time Offsets", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa13a, "DT", "Referenced Datetime", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa160, "UT", "Text Value", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa167, "SQ", "Observation Category Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa168, "SQ", "Concept Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa16a, "ST", "Bibliographic Citation", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa170, "CS", "Observation Class", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa171, "UI", "Observation UID", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa172, "UI", "Referenced Observation UID", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa173, "CS", "Referenced Observation Class", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa174, "CS", "Referenced Object Observation Class", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa180, "US", "Annotation Group Number", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa192, "DA", "Observation Date", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa193, "TM", "Observation Time", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa194, "CS", "Measurement Automation", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa195, "SQ", "Concept Name Code Sequence Modifier", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa224, "ST", "Identification Description", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa290, "CS", "Coordinates Set Geometric Type", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa296, "SQ", "Algorithm Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa297, "ST", "Algorithm Description", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa29a, "SL", "Pixel Coordinates Set", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa300, "SQ", "Measured Value Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa307, "PN", "Current Observer", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa30a, "DS", "Numeric Value", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa313, "SQ", "Referenced Accession Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa33a, "ST", "Report Status Comment", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa340, "SQ", "Procedure Context Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa352, "PN", "Verbal Source", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa353, "ST", "Address", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa354, "LO", "Telephone Number", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa358, "SQ", "Verbal Source Identifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa380, "SQ", "Report Detail Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa402, "UI", "Observation Subject UID", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa403, "CS", "Observation Subject Class", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa404, "SQ", "Observation Subject Type Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa600, "CS", "Observation Subject Context Flag", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa601, "CS", "Observer Context Flag", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa603, "CS", "Procedure Context Flag", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa730, "SQ", "Observations Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa731, "SQ", "Relationship Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa732, "SQ", "Relationship Type Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa744, "SQ", "Language Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xa992, "ST", "Uniform Resource Locator", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xb020, "SQ", "Annotation Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0040, 0xdb73, "SQ", "Relationship Type Code Sequence Modifier", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0000, "LT", "Papyrus Comments", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0011, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0012, "UL", "Pixel Offset", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0013, "SQ", "Image Identifier Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0014, "SQ", "External File Reference Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0015, "US", "Number of Images", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0020, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0021, "UI", "Referenced SOP Class UID", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0022, "UI", "Referenced SOP Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0030, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0031, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0032, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0034, "DA", "Modified Date", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0036, "TM", "Modified Time", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0040, "LT", "Owner Name", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0041, "UI", "Referenced Image SOP Class UID", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0042, "UI", "Referenced Image SOP Instance UID", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0050, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0060, "UL", "Number of Images", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x0062, "UL", "Number of Other", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x00a0, "LT", "External Folder Element DSID", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x00a1, "US", "External Folder Element Data Set Type", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x00a2, "LT", "External Folder Element File Location", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x00a3, "UL", "External Folder Element Length", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x00b0, "LT", "Internal Folder Element DSID", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x00b1, "US", "Internal Folder Element Data Set Type", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x00b2, "UL", "Internal Offset To Data Set", (DicomElemParseFunc *) NULL },
+ { 0x0041, 0x00b3, "UL", "Internal Offset To Image", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0001, "SS", "Bitmap Of Prescan Options", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0002, "SS", "Gradient Offset In X", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0003, "SS", "Gradient Offset In Y", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0004, "SS", "Gradient Offset In Z", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0005, "SS", "Image Is Original Or Unoriginal", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0006, "SS", "Number Of EPI Shots", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0007, "SS", "Views Per Segment", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0008, "SS", "Respiratory Rate In BPM", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0009, "SS", "Respiratory Trigger Point", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x000a, "SS", "Type Of Receiver Used", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x000b, "DS", "Peak Rate Of Change Of Gradient Field", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x000c, "DS", "Limits In Units Of Percent", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x000d, "DS", "PSD Estimated Limit", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x000e, "DS", "PSD Estimated Limit In Tesla Per Second", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x000f, "DS", "SAR Avg Head", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0010, "US", "Window Value", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0011, "US", "Total Input Views", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0012, "SS", "Xray Chain", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0013, "SS", "Recon Kernel Parameters", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0014, "SS", "Calibration Parameters", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0015, "SS", "Total Output Views", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0016, "SS", "Number Of Overranges", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0017, "DS", "IBH Image Scale Factors", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0018, "DS", "BBH Coefficients", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0019, "SS", "Number Of BBH Chains To Blend", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x001a, "SL", "Starting Channel Number", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x001b, "SS", "PPScan Parameters", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x001c, "SS", "GE Image Integrity", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x001d, "SS", "Level Value", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x001e, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x001f, "SL", "Max Overranges In A View", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0020, "DS", "Avg Overranges All Views", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0021, "SS", "Corrected Afterglow Terms", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0025, "SS", "Reference Channels", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0026, "US", "No Views Ref Channels Blocked", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0027, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0028, "OB", "Unique Image Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0029, "OB", "Histogram Tables", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x002a, "OB", "User Defined Data", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x002b, "SS", "Private Scan Options", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x002c, "SS", "Effective Echo Spacing", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x002d, "SH", "String Slop Field 1", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x002e, "SH", "String Slop Field 2", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x002f, "SS", "Raw Data Type", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0030, "SS", "Raw Data Type", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0031, "DS", "RA Coord Of Target Recon Centre", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0032, "SS", "Raw Data Type", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0033, "FL", "Neg Scan Spacing", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0034, "IS", "Offset Frequency", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0035, "UL", "User Usage Tag", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0036, "UL", "User Fill Map MSW", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0037, "UL", "User Fill Map LSW", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0038, "FL", "User 25 To User 48", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0039, "IS", "Slop Integer 6 To Slop Integer 9", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0040, "FL", "Trigger On Position", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0041, "FL", "Degree Of Rotation", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0042, "SL", "DAS Trigger Source", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0043, "SL", "DAS Fpa Gain", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0044, "SL", "DAS Output Source", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0045, "SL", "DAS Ad Input", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0046, "SL", "DAS Cal Mode", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0047, "SL", "DAS Cal Frequency", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0048, "SL", "DAS Reg Xm", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x0049, "SL", "DAS Auto Zero", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x004a, "SS", "Starting Channel Of View", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x004b, "SL", "DAS Xm Pattern", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x004c, "SS", "TGGC Trigger Mode", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x004d, "FL", "Start Scan To Xray On Delay", (DicomElemParseFunc *) NULL },
+ { 0x0043, 0x004e, "FL", "Duration Of Xray On", (DicomElemParseFunc *) NULL },
+ { 0x0044, 0x0000, "UI", "?", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0004, "CS", "AES", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0006, "DS", "Angulation", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0009, "DS", "Real Magnification Factor", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x000b, "CS", "Senograph Type", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x000c, "DS", "Integration Time", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x000d, "DS", "ROI Origin X and Y", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0011, "DS", "Receptor Size cm X and Y", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0012, "IS", "Receptor Size Pixels X and Y", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0013, "ST", "Screen", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0014, "DS", "Pixel Pitch Microns", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0015, "IS", "Pixel Depth Bits", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0016, "IS", "Binning Factor X and Y", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x001b, "CS", "Clinical View", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x001d, "DS", "Mean Of Raw Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x001e, "DS", "Mean Of Offset Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x001f, "DS", "Mean Of Corrected Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0020, "DS", "Mean Of Region Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0021, "DS", "Mean Of Log Region Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0022, "DS", "Standard Deviation Of Raw Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0023, "DS", "Standard Deviation Of Corrected Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0024, "DS", "Standard Deviation Of Region Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0025, "DS", "Standard Deviation Of Log Region Gray Levels", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0026, "OB", "MAO Buffer", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0027, "IS", "Set Number", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0028, "CS", "WindowingType (LINEAR or GAMMA)", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0029, "DS", "WindowingParameters", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x002a, "IS", "Crosshair Cursor X Coordinates", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x002b, "IS", "Crosshair Cursor Y Coordinates", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x0039, "US", "Vignette Rows", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x003a, "US", "Vignette Columns", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x003b, "US", "Vignette Bits Allocated", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x003c, "US", "Vignette Bits Stored", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x003d, "US", "Vignette High Bit", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x003e, "US", "Vignette Pixel Representation", (DicomElemParseFunc *) NULL },
+ { 0x0045, 0x003f, "OB", "Vignette Pixel Data", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0001, "SQ", "Reconstruction Parameters Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0050, "UL", "Volume Voxel Count", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0051, "UL", "Volume Segment Count", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0053, "US", "Volume Slice Size", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0054, "US", "Volume Slice Count", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0055, "SL", "Volume Threshold Value", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0057, "DS", "Volume Voxel Ratio", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0058, "DS", "Volume Voxel Size", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0059, "US", "Volume Z Position Size", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0060, "DS", "Volume Base Line", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0061, "DS", "Volume Center Point", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0063, "SL", "Volume Skew Base", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0064, "DS", "Volume Registration Transform Rotation Matrix", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0065, "DS", "Volume Registration Transform Translation Vector", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0070, "DS", "KVP List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0071, "IS", "XRay Tube Current List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0072, "IS", "Exposure List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0080, "LO", "Acquisition DLX Identifier", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0085, "SQ", "Acquisition DLX 2D Series Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0089, "DS", "Contrast Agent Volume List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x008a, "US", "Number Of Injections", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x008b, "US", "Frame Count", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0096, "IS", "Used Frames", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0091, "LO", "XA 3D Reconstruction Algorithm Name", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0092, "CS", "XA 3D Reconstruction Algorithm Version", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0093, "DA", "DLX Calibration Date", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0094, "TM", "DLX Calibration Time", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0095, "CS", "DLX Calibration Status", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0098, "US", "Transform Count", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x0099, "SQ", "Transform Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x009a, "DS", "Transform Rotation Matrix", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x009b, "DS", "Transform Translation Vector", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x009c, "LO", "Transform Label", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00b1, "US", "Wireframe Count", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00b2, "US", "Location System", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00b0, "SQ", "Wireframe List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00b5, "LO", "Wireframe Name", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00b6, "LO", "Wireframe Group Name", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00b7, "LO", "Wireframe Color", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00b8, "SL", "Wireframe Attributes", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00b9, "SL", "Wireframe Point Count", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00ba, "SL", "Wireframe Timestamp", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00bb, "SQ", "Wireframe Point List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00bc, "DS", "Wireframe Points Coordinates", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00c0, "DS", "Volume Upper Left High Corner RAS", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00c1, "DS", "Volume Slice To RAS Rotation Matrix", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00c2, "DS", "Volume Upper Left High Corner TLOC", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00d1, "OB", "Volume Segment List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00d2, "OB", "Volume Gradient List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00d3, "OB", "Volume Density List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00d4, "OB", "Volume Z Position List", (DicomElemParseFunc *) NULL },
+ { 0x0047, 0x00d5, "OB", "Volume Original Index List", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0000, "UL", "Calibration Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0004, "CS", "Calibration Object", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0010, "SQ", "DeviceSequence", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0014, "DS", "DeviceLength", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0016, "DS", "DeviceDiameter", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0017, "CS", "DeviceDiameterUnits", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0018, "DS", "DeviceVolume", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0019, "DS", "InterMarkerDistance", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0020, "LO", "DeviceDescription", (DicomElemParseFunc *) NULL },
+ { 0x0050, 0x0030, "SQ", "CodedInterventionDeviceSequence", (DicomElemParseFunc *) NULL },
+ { 0x0051, 0x0010, "xs", "Image Text", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0000, "UL", "Nuclear Acquisition Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0010, "US", "Energy Window Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0011, "US", "Number of Energy Windows", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0012, "SQ", "Energy Window Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0013, "SQ", "Energy Window Range Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0014, "DS", "Energy Window Lower Limit", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0015, "DS", "Energy Window Upper Limit", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0016, "SQ", "Radiopharmaceutical Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0017, "IS", "Residual Syringe Counts", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0018, "SH", "Energy Window Name", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0020, "US", "Detector Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0021, "US", "Number of Detectors", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0022, "SQ", "Detector Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0030, "US", "Phase Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0031, "US", "Number of Phases", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0032, "SQ", "Phase Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0033, "US", "Number of Frames In Phase", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0036, "IS", "Phase Delay", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0038, "IS", "Pause Between Frames", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0050, "US", "Rotation Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0051, "US", "Number of Rotations", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0052, "SQ", "Rotation Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0053, "US", "Number of Frames In Rotation", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0060, "US", "R-R Interval Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0061, "US", "Number of R-R Intervals", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0062, "SQ", "Gated Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0063, "SQ", "Data Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0070, "US", "Time Slot Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0071, "US", "Number of Time Slots", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0072, "SQ", "Time Slot Information Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0073, "DS", "Time Slot Time", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0080, "US", "Slice Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0081, "US", "Number of Slices", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0090, "US", "Angular View Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0100, "US", "Time Slice Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0101, "US", "Number Of Time Slices", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0200, "DS", "Start Angle", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0202, "CS", "Type of Detector Motion", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0210, "IS", "Trigger Vector", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0211, "US", "Number of Triggers in Phase", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0220, "SQ", "View Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0222, "SQ", "View Modifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0300, "SQ", "Radionuclide Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0302, "SQ", "Radiopharmaceutical Route Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0304, "SQ", "Radiopharmaceutical Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0306, "SQ", "Calibration Data Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0308, "US", "Energy Window Number", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0400, "SH", "Image ID", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0410, "SQ", "Patient Orientation Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0412, "SQ", "Patient Orientation Modifier Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x0414, "SQ", "Patient Gantry Relationship Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1000, "CS", "Positron Emission Tomography Series Type", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1001, "CS", "Positron Emission Tomography Units", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1002, "CS", "Counts Source", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1004, "CS", "Reprojection Method", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1100, "CS", "Randoms Correction Method", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1101, "LO", "Attenuation Correction Method", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1102, "CS", "Decay Correction", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1103, "LO", "Reconstruction Method", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1104, "LO", "Detector Lines of Response Used", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1105, "LO", "Scatter Correction Method", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1200, "DS", "Axial Acceptance", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1201, "IS", "Axial Mash", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1202, "IS", "Transverse Mash", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1203, "DS", "Detector Element Size", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1210, "DS", "Coincidence Window Width", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1220, "CS", "Secondary Counts Type", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1300, "DS", "Frame Reference Time", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1310, "IS", "Primary Prompts Counts Accumulated", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1311, "IS", "Secondary Counts Accumulated", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1320, "DS", "Slice Sensitivity Factor", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1321, "DS", "Decay Factor", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1322, "DS", "Dose Calibration Factor", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1323, "DS", "Scatter Fraction Factor", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1324, "DS", "Dead Time Factor", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1330, "US", "Image Index", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1400, "CS", "Counts Included", (DicomElemParseFunc *) NULL },
+ { 0x0054, 0x1401, "CS", "Dead Time Correction Flag", (DicomElemParseFunc *) NULL },
+ { 0x0055, 0x0046, "LT", "Current Ward", (DicomElemParseFunc *) NULL },
+ { 0x0058, 0x0000, "SQ", "?", (DicomElemParseFunc *) NULL },
+ { 0x0060, 0x3000, "SQ", "Histogram Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0060, 0x3002, "US", "Histogram Number of Bins", (DicomElemParseFunc *) NULL },
+ { 0x0060, 0x3004, "xs", "Histogram First Bin Value", (DicomElemParseFunc *) NULL },
+ { 0x0060, 0x3006, "xs", "Histogram Last Bin Value", (DicomElemParseFunc *) NULL },
+ { 0x0060, 0x3008, "US", "Histogram Bin Width", (DicomElemParseFunc *) NULL },
+ { 0x0060, 0x3010, "LO", "Histogram Explanation", (DicomElemParseFunc *) NULL },
+ { 0x0060, 0x3020, "UL", "Histogram Data", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0001, "SQ", "Graphic Annotation Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0002, "CS", "Graphic Layer", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0003, "CS", "Bounding Box Annotation Units", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0004, "CS", "Anchor Point Annotation Units", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0005, "CS", "Graphic Annotation Units", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0006, "ST", "Unformatted Text Value", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0008, "SQ", "Text Object Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0009, "SQ", "Graphic Object Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0010, "FL", "Bounding Box TLHC", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0011, "FL", "Bounding Box BRHC", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0014, "FL", "Anchor Point", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0015, "CS", "Anchor Point Visibility", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0020, "US", "Graphic Dimensions", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0021, "US", "Number Of Graphic Points", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0022, "FL", "Graphic Data", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0023, "CS", "Graphic Type", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0024, "CS", "Graphic Filled", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0040, "IS", "Image Rotation", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0041, "CS", "Image Horizontal Flip", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0050, "US", "Displayed Area TLHC", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0051, "US", "Displayed Area BRHC", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0060, "SQ", "Graphic Layer Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0062, "IS", "Graphic Layer Order", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0066, "US", "Graphic Layer Recommended Display Value", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0068, "LO", "Graphic Layer Description", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0080, "CS", "Presentation Label", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0081, "LO", "Presentation Description", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0082, "DA", "Presentation Creation Date", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0083, "TM", "Presentation Creation Time", (DicomElemParseFunc *) NULL },
+ { 0x0070, 0x0084, "PN", "Presentation Creator's Name", (DicomElemParseFunc *) NULL },
+ { 0x0087, 0x0010, "CS", "Media Type", (DicomElemParseFunc *) NULL },
+ { 0x0087, 0x0020, "CS", "Media Location", (DicomElemParseFunc *) NULL },
+ { 0x0087, 0x0050, "IS", "Estimated Retrieve Time", (DicomElemParseFunc *) NULL },
+ { 0x0088, 0x0000, "UL", "Storage Group Length", (DicomElemParseFunc *) NULL },
+ { 0x0088, 0x0130, "SH", "Storage Media FileSet ID", (DicomElemParseFunc *) NULL },
+ { 0x0088, 0x0140, "UI", "Storage Media FileSet UID", (DicomElemParseFunc *) NULL },
+ { 0x0088, 0x0200, "SQ", "Icon Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x0088, 0x0904, "LO", "Topic Title", (DicomElemParseFunc *) NULL },
+ { 0x0088, 0x0906, "ST", "Topic Subject", (DicomElemParseFunc *) NULL },
+ { 0x0088, 0x0910, "LO", "Topic Author", (DicomElemParseFunc *) NULL },
+ { 0x0088, 0x0912, "LO", "Topic Key Words", (DicomElemParseFunc *) NULL },
+ { 0x0095, 0x0001, "LT", "Examination Folder ID", (DicomElemParseFunc *) NULL },
+ { 0x0095, 0x0004, "UL", "Folder Reported Status", (DicomElemParseFunc *) NULL },
+ { 0x0095, 0x0005, "LT", "Folder Reporting Radiologist", (DicomElemParseFunc *) NULL },
+ { 0x0095, 0x0007, "LT", "SIENET ISA PLA", (DicomElemParseFunc *) NULL },
+ { 0x0099, 0x0002, "UL", "Data Object Attributes", (DicomElemParseFunc *) NULL },
+ { 0x00e1, 0x0001, "US", "Data Dictionary Version", (DicomElemParseFunc *) NULL },
+ { 0x00e1, 0x0014, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x00e1, 0x0022, "DS", "?", (DicomElemParseFunc *) NULL },
+ { 0x00e1, 0x0023, "DS", "?", (DicomElemParseFunc *) NULL },
+ { 0x00e1, 0x0024, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x00e1, 0x0025, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x00e1, 0x0040, "SH", "Offset From CT MR Images", (DicomElemParseFunc *) NULL },
+ { 0x0193, 0x0002, "DS", "RIS Key", (DicomElemParseFunc *) NULL },
+ { 0x0307, 0x0001, "UN", "RIS Worklist IMGEF", (DicomElemParseFunc *) NULL },
+ { 0x0309, 0x0001, "UN", "RIS Report IMGEF", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0000, "SH", "Implementation Version", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0020, "DS", "Relative Table Position", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0021, "DS", "Relative Table Height", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0030, "SH", "Surview Direction", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0031, "DS", "Surview Length", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0050, "SH", "Image View Type", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0070, "DS", "Batch Number", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0071, "DS", "Batch Size", (DicomElemParseFunc *) NULL },
+ { 0x0601, 0x0072, "DS", "Batch Slice Number", (DicomElemParseFunc *) NULL },
+ { 0x1000, 0x0000, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x1000, 0x0001, "US", "Run Length Triplet", (DicomElemParseFunc *) NULL },
+ { 0x1000, 0x0002, "US", "Huffman Table Size", (DicomElemParseFunc *) NULL },
+ { 0x1000, 0x0003, "US", "Huffman Table Triplet", (DicomElemParseFunc *) NULL },
+ { 0x1000, 0x0004, "US", "Shift Table Size", (DicomElemParseFunc *) NULL },
+ { 0x1000, 0x0005, "US", "Shift Table Triplet", (DicomElemParseFunc *) NULL },
+ { 0x1010, 0x0000, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x1369, 0x0000, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x2000, 0x0000, "UL", "Film Session Group Length", (DicomElemParseFunc *) NULL },
+ { 0x2000, 0x0010, "IS", "Number of Copies", (DicomElemParseFunc *) NULL },
+ { 0x2000, 0x0020, "CS", "Print Priority", (DicomElemParseFunc *) NULL },
+ { 0x2000, 0x0030, "CS", "Medium Type", (DicomElemParseFunc *) NULL },
+ { 0x2000, 0x0040, "CS", "Film Destination", (DicomElemParseFunc *) NULL },
+ { 0x2000, 0x0050, "LO", "Film Session Label", (DicomElemParseFunc *) NULL },
+ { 0x2000, 0x0060, "IS", "Memory Allocation", (DicomElemParseFunc *) NULL },
+ { 0x2000, 0x0500, "SQ", "Referenced Film Box Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0000, "UL", "Film Box Group Length", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0010, "ST", "Image Display Format", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0030, "CS", "Annotation Display Format ID", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0040, "CS", "Film Orientation", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0050, "CS", "Film Size ID", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0060, "CS", "Magnification Type", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0080, "CS", "Smoothing Type", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0100, "CS", "Border Density", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0110, "CS", "Empty Image Density", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0120, "US", "Min Density", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0130, "US", "Max Density", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0140, "CS", "Trim", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0150, "ST", "Configuration Information", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0500, "SQ", "Referenced Film Session Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0510, "SQ", "Referenced Image Box Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2010, 0x0520, "SQ", "Referenced Basic Annotation Box Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2020, 0x0000, "UL", "Image Box Group Length", (DicomElemParseFunc *) NULL },
+ { 0x2020, 0x0010, "US", "Image Box Position", (DicomElemParseFunc *) NULL },
+ { 0x2020, 0x0020, "CS", "Polarity", (DicomElemParseFunc *) NULL },
+ { 0x2020, 0x0030, "DS", "Requested Image Size", (DicomElemParseFunc *) NULL },
+ { 0x2020, 0x0110, "SQ", "Preformatted Grayscale Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2020, 0x0111, "SQ", "Preformatted Color Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2020, 0x0130, "SQ", "Referenced Image Overlay Box Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2020, 0x0140, "SQ", "Referenced VOI LUT Box Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2030, 0x0000, "UL", "Annotation Group Length", (DicomElemParseFunc *) NULL },
+ { 0x2030, 0x0010, "US", "Annotation Position", (DicomElemParseFunc *) NULL },
+ { 0x2030, 0x0020, "LO", "Text String", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0000, "UL", "Overlay Box Group Length", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0010, "SQ", "Referenced Overlay Plane Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0011, "US", "Referenced Overlay Plane Groups", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0060, "CS", "Overlay Magnification Type", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0070, "CS", "Overlay Smoothing Type", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0080, "CS", "Overlay Foreground Density", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0090, "CS", "Overlay Mode", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0100, "CS", "Threshold Density", (DicomElemParseFunc *) NULL },
+ { 0x2040, 0x0500, "SQ", "Referenced Overlay Image Box Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2050, 0x0010, "SQ", "Presentation LUT Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2050, 0x0020, "CS", "Presentation LUT Shape", (DicomElemParseFunc *) NULL },
+ { 0x2100, 0x0000, "UL", "Print Job Group Length", (DicomElemParseFunc *) NULL },
+ { 0x2100, 0x0020, "CS", "Execution Status", (DicomElemParseFunc *) NULL },
+ { 0x2100, 0x0030, "CS", "Execution Status Info", (DicomElemParseFunc *) NULL },
+ { 0x2100, 0x0040, "DA", "Creation Date", (DicomElemParseFunc *) NULL },
+ { 0x2100, 0x0050, "TM", "Creation Time", (DicomElemParseFunc *) NULL },
+ { 0x2100, 0x0070, "AE", "Originator", (DicomElemParseFunc *) NULL },
+ { 0x2100, 0x0500, "SQ", "Referenced Print Job Sequence", (DicomElemParseFunc *) NULL },
+ { 0x2110, 0x0000, "UL", "Printer Group Length", (DicomElemParseFunc *) NULL },
+ { 0x2110, 0x0010, "CS", "Printer Status", (DicomElemParseFunc *) NULL },
+ { 0x2110, 0x0020, "CS", "Printer Status Info", (DicomElemParseFunc *) NULL },
+ { 0x2110, 0x0030, "LO", "Printer Name", (DicomElemParseFunc *) NULL },
+ { 0x2110, 0x0099, "SH", "Print Queue ID", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0002, "SH", "RT Image Label", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0003, "LO", "RT Image Name", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0004, "ST", "RT Image Description", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x000a, "CS", "Reported Values Origin", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x000c, "CS", "RT Image Plane", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x000e, "DS", "X-Ray Image Receptor Angle", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0010, "DS", "RTImageOrientation", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0011, "DS", "Image Plane Pixel Spacing", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0012, "DS", "RT Image Position", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0020, "SH", "Radiation Machine Name", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0022, "DS", "Radiation Machine SAD", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0024, "DS", "Radiation Machine SSD", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0026, "DS", "RT Image SID", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0028, "DS", "Source to Reference Object Distance", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0029, "IS", "Fraction Number", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0030, "SQ", "Exposure Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3002, 0x0032, "DS", "Meterset Exposure", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0001, "CS", "DVH Type", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0002, "CS", "Dose Units", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0004, "CS", "Dose Type", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0006, "LO", "Dose Comment", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0008, "DS", "Normalization Point", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x000a, "CS", "Dose Summation Type", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x000c, "DS", "GridFrame Offset Vector", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x000e, "DS", "Dose Grid Scaling", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0010, "SQ", "RT Dose ROI Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0012, "DS", "Dose Value", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0040, "DS", "DVH Normalization Point", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0042, "DS", "DVH Normalization Dose Value", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0050, "SQ", "DVH Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0052, "DS", "DVH Dose Scaling", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0054, "CS", "DVH Volume Units", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0056, "IS", "DVH Number of Bins", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0058, "DS", "DVH Data", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0060, "SQ", "DVH Referenced ROI Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0062, "CS", "DVH ROI Contribution Type", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0070, "DS", "DVH Minimum Dose", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0072, "DS", "DVH Maximum Dose", (DicomElemParseFunc *) NULL },
+ { 0x3004, 0x0074, "DS", "DVH Mean Dose", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0002, "SH", "Structure Set Label", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0004, "LO", "Structure Set Name", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0006, "ST", "Structure Set Description", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0008, "DA", "Structure Set Date", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0009, "TM", "Structure Set Time", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0010, "SQ", "Referenced Frame of Reference Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0012, "SQ", "RT Referenced Study Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0014, "SQ", "RT Referenced Series Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0016, "SQ", "Contour Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0020, "SQ", "Structure Set ROI Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0022, "IS", "ROI Number", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0024, "UI", "Referenced Frame of Reference UID", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0026, "LO", "ROI Name", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0028, "ST", "ROI Description", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x002a, "IS", "ROI Display Color", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x002c, "DS", "ROI Volume", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0030, "SQ", "RT Related ROI Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0033, "CS", "RT ROI Relationship", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0036, "CS", "ROI Generation Algorithm", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0038, "LO", "ROI Generation Description", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0039, "SQ", "ROI Contour Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0040, "SQ", "Contour Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0042, "CS", "Contour Geometric Type", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0044, "DS", "Contour SlabT hickness", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0045, "DS", "Contour Offset Vector", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0046, "IS", "Number of Contour Points", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0050, "DS", "Contour Data", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0080, "SQ", "RT ROI Observations Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0082, "IS", "Observation Number", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0084, "IS", "Referenced ROI Number", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0085, "SH", "ROI Observation Label", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0086, "SQ", "RT ROI Identification Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x0088, "ST", "ROI Observation Description", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00a0, "SQ", "Related RT ROI Observations Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00a4, "CS", "RT ROI Interpreted Type", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00a6, "PN", "ROI Interpreter", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00b0, "SQ", "ROI Physical Properties Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00b2, "CS", "ROI Physical Property", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00b4, "DS", "ROI Physical Property Value", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00c0, "SQ", "Frame of Reference Relationship Sequence", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00c2, "UI", "Related Frame of Reference UID", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00c4, "CS", "Frame of Reference Transformation Type", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00c6, "DS", "Frame of Reference Transformation Matrix", (DicomElemParseFunc *) NULL },
+ { 0x3006, 0x00c8, "LO", "Frame of Reference Transformation Comment", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0002, "SH", "RT Plan Label", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0003, "LO", "RT Plan Name", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0004, "ST", "RT Plan Description", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0006, "DA", "RT Plan Date", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0007, "TM", "RT Plan Time", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0009, "LO", "Treatment Protocols", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x000a, "CS", "Treatment Intent", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x000b, "LO", "Treatment Sites", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x000c, "CS", "RT Plan Geometry", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x000e, "ST", "Prescription Description", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0010, "SQ", "Dose ReferenceSequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0012, "IS", "Dose ReferenceNumber", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0014, "CS", "Dose Reference Structure Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0016, "LO", "Dose ReferenceDescription", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0018, "DS", "Dose Reference Point Coordinates", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x001a, "DS", "Nominal Prior Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0020, "CS", "Dose Reference Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0021, "DS", "Constraint Weight", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0022, "DS", "Delivery Warning Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0023, "DS", "Delivery Maximum Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0025, "DS", "Target Minimum Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0026, "DS", "Target Prescription Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0027, "DS", "Target Maximum Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0028, "DS", "Target Underdose Volume Fraction", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x002a, "DS", "Organ at Risk Full-volume Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x002b, "DS", "Organ at Risk Limit Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x002c, "DS", "Organ at Risk Maximum Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x002d, "DS", "Organ at Risk Overdose Volume Fraction", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0040, "SQ", "Tolerance Table Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0042, "IS", "Tolerance Table Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0043, "SH", "Tolerance Table Label", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0044, "DS", "Gantry Angle Tolerance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0046, "DS", "Beam Limiting Device Angle Tolerance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0048, "SQ", "Beam Limiting Device Tolerance Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x004a, "DS", "Beam Limiting Device Position Tolerance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x004c, "DS", "Patient Support Angle Tolerance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x004e, "DS", "Table Top Eccentric Angle Tolerance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0051, "DS", "Table Top Vertical Position Tolerance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0052, "DS", "Table Top Longitudinal Position Tolerance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0053, "DS", "Table Top Lateral Position Tolerance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0055, "CS", "RT Plan Relationship", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0070, "SQ", "Fraction Group Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0071, "IS", "Fraction Group Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0078, "IS", "Number of Fractions Planned", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0079, "IS", "Number of Fractions Per Day", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x007a, "IS", "Repeat Fraction Cycle Length", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x007b, "LT", "Fraction Pattern", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0080, "IS", "Number of Beams", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0082, "DS", "Beam Dose Specification Point", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0084, "DS", "Beam Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0086, "DS", "Beam Meterset", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00a0, "IS", "Number of Brachy Application Setups", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00a2, "DS", "Brachy Application Setup Dose Specification Point", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00a4, "DS", "Brachy Application Setup Dose", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00b0, "SQ", "Beam Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00b2, "SH", "Treatment Machine Name ", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00b3, "CS", "Primary Dosimeter Unit", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00b4, "DS", "Source-Axis Distance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00b6, "SQ", "Beam Limiting Device Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00b8, "CS", "RT Beam Limiting Device Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00ba, "DS", "Source to Beam Limiting Device Distance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00bc, "IS", "Number of Leaf/Jaw Pairs", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00be, "DS", "Leaf Position Boundaries", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00c0, "IS", "Beam Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00c2, "LO", "Beam Name", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00c3, "ST", "Beam Description", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00c4, "CS", "Beam Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00c6, "CS", "Radiation Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00c8, "IS", "Reference Image Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00ca, "SQ", "Planned Verification Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00cc, "LO", "Imaging Device Specific Acquisition Parameters", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00ce, "CS", "Treatment Delivery Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00d0, "IS", "Number of Wedges", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00d1, "SQ", "Wedge Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00d2, "IS", "Wedge Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00d3, "CS", "Wedge Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00d4, "SH", "Wedge ID", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00d5, "IS", "Wedge Angle", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00d6, "DS", "Wedge Factor", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00d8, "DS", "Wedge Orientation", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00da, "DS", "Source to Wedge Tray Distance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e0, "IS", "Number of Compensators", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e1, "SH", "Material ID", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e2, "DS", "Total Compensator Tray Factor", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e3, "SQ", "Compensator Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e4, "IS", "Compensator Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e5, "SH", "Compensator ID", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e6, "DS", "Source to Compensator Tray Distance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e7, "IS", "Compensator Rows", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e8, "IS", "Compensator Columns", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00e9, "DS", "Compensator Pixel Spacing", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00ea, "DS", "Compensator Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00eb, "DS", "Compensator Transmission Data", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00ec, "DS", "Compensator Thickness Data", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00ed, "IS", "Number of Boli", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00f0, "IS", "Number of Blocks", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00f2, "DS", "Total Block Tray Factor", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00f4, "SQ", "Block Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00f5, "SH", "Block Tray ID", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00f6, "DS", "Source to Block Tray Distance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00f8, "CS", "Block Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00fa, "CS", "Block Divergence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00fc, "IS", "Block Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x00fe, "LO", "Block Name", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0100, "DS", "Block Thickness", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0102, "DS", "Block Transmission", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0104, "IS", "Block Number of Points", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0106, "DS", "Block Data", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0107, "SQ", "Applicator Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0108, "SH", "Applicator ID", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0109, "CS", "Applicator Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x010a, "LO", "Applicator Description", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x010c, "DS", "Cumulative Dose Reference Coefficient", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x010e, "DS", "Final Cumulative Meterset Weight", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0110, "IS", "Number of Control Points", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0111, "SQ", "Control Point Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0112, "IS", "Control Point Index", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0114, "DS", "Nominal Beam Energy", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0115, "DS", "Dose Rate Set", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0116, "SQ", "Wedge Position Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0118, "CS", "Wedge Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x011a, "SQ", "Beam Limiting Device Position Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x011c, "DS", "Leaf Jaw Positions", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x011e, "DS", "Gantry Angle", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x011f, "CS", "Gantry Rotation Direction", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0120, "DS", "Beam Limiting Device Angle", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0121, "CS", "Beam Limiting Device Rotation Direction", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0122, "DS", "Patient Support Angle", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0123, "CS", "Patient Support Rotation Direction", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0124, "DS", "Table Top Eccentric Axis Distance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0125, "DS", "Table Top Eccentric Angle", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0126, "CS", "Table Top Eccentric Rotation Direction", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0128, "DS", "Table Top Vertical Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0129, "DS", "Table Top Longitudinal Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x012a, "DS", "Table Top Lateral Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x012c, "DS", "Isocenter Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x012e, "DS", "Surface Entry Point", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0130, "DS", "Source to Surface Distance", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0134, "DS", "Cumulative Meterset Weight", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0180, "SQ", "Patient Setup Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0182, "IS", "Patient Setup Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0184, "LO", "Patient Additional Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0190, "SQ", "Fixation Device Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0192, "CS", "Fixation Device Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0194, "SH", "Fixation Device Label", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0196, "ST", "Fixation Device Description", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0198, "SH", "Fixation Device Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01a0, "SQ", "Shielding Device Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01a2, "CS", "Shielding Device Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01a4, "SH", "Shielding Device Label", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01a6, "ST", "Shielding Device Description", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01a8, "SH", "Shielding Device Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01b0, "CS", "Setup Technique", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01b2, "ST", "Setup TechniqueDescription", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01b4, "SQ", "Setup Device Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01b6, "CS", "Setup Device Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01b8, "SH", "Setup Device Label", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01ba, "ST", "Setup Device Description", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01bc, "DS", "Setup Device Parameter", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01d0, "ST", "Setup ReferenceDescription", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01d2, "DS", "Table Top Vertical Setup Displacement", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01d4, "DS", "Table Top Longitudinal Setup Displacement", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x01d6, "DS", "Table Top Lateral Setup Displacement", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0200, "CS", "Brachy Treatment Technique", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0202, "CS", "Brachy Treatment Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0206, "SQ", "Treatment Machine Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0210, "SQ", "Source Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0212, "IS", "Source Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0214, "CS", "Source Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0216, "LO", "Source Manufacturer", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0218, "DS", "Active Source Diameter", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x021a, "DS", "Active Source Length", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0222, "DS", "Source Encapsulation Nominal Thickness", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0224, "DS", "Source Encapsulation Nominal Transmission", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0226, "LO", "Source IsotopeName", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0228, "DS", "Source Isotope Half Life", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x022a, "DS", "Reference Air Kerma Rate", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x022c, "DA", "Air Kerma Rate Reference Date", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x022e, "TM", "Air Kerma Rate Reference Time", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0230, "SQ", "Application Setup Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0232, "CS", "Application Setup Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0234, "IS", "Application Setup Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0236, "LO", "Application Setup Name", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0238, "LO", "Application Setup Manufacturer", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0240, "IS", "Template Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0242, "SH", "Template Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0244, "LO", "Template Name", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0250, "DS", "Total Reference Air Kerma", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0260, "SQ", "Brachy Accessory Device Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0262, "IS", "Brachy Accessory Device Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0263, "SH", "Brachy Accessory Device ID", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0264, "CS", "Brachy Accessory Device Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0266, "LO", "Brachy Accessory Device Name", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x026a, "DS", "Brachy Accessory Device Nominal Thickness", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x026c, "DS", "Brachy Accessory Device Nominal Transmission", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0280, "SQ", "Channel Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0282, "IS", "Channel Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0284, "DS", "Channel Length", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0286, "DS", "Channel Total Time", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0288, "CS", "Source Movement Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x028a, "IS", "Number of Pulses", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x028c, "DS", "Pulse Repetition Interval", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0290, "IS", "Source Applicator Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0291, "SH", "Source Applicator ID", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0292, "CS", "Source Applicator Type", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0294, "LO", "Source Applicator Name", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0296, "DS", "Source Applicator Length", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x0298, "LO", "Source Applicator Manufacturer", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x029c, "DS", "Source Applicator Wall Nominal Thickness", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x029e, "DS", "Source Applicator Wall Nominal Transmission", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02a0, "DS", "Source Applicator Step Size", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02a2, "IS", "Transfer Tube Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02a4, "DS", "Transfer Tube Length", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02b0, "SQ", "Channel Shield Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02b2, "IS", "Channel Shield Number", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02b3, "SH", "Channel Shield ID", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02b4, "LO", "Channel Shield Name", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02b8, "DS", "Channel Shield Nominal Thickness", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02ba, "DS", "Channel Shield Nominal Transmission", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02c8, "DS", "Final Cumulative Time Weight", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02d0, "SQ", "Brachy Control Point Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02d2, "DS", "Control Point Relative Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02d4, "DS", "Control Point 3D Position", (DicomElemParseFunc *) NULL },
+ { 0x300a, 0x02d6, "DS", "Cumulative Time Weight", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0002, "SQ", "Referenced RT Plan Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0004, "SQ", "Referenced Beam Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0006, "IS", "Referenced Beam Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0007, "IS", "Referenced Reference Image Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0008, "DS", "Start Cumulative Meterset Weight", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0009, "DS", "End Cumulative Meterset Weight", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x000a, "SQ", "Referenced Brachy Application Setup Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x000c, "IS", "Referenced Brachy Application Setup Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x000e, "IS", "Referenced Source Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0020, "SQ", "Referenced Fraction Group Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0022, "IS", "Referenced Fraction Group Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0040, "SQ", "Referenced Verification Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0042, "SQ", "Referenced Reference Image Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0050, "SQ", "Referenced Dose Reference Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0051, "IS", "Referenced Dose Reference Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0055, "SQ", "Brachy Referenced Dose Reference Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0060, "SQ", "Referenced Structure Set Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x006a, "IS", "Referenced Patient Setup Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x0080, "SQ", "Referenced Dose Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x00a0, "IS", "Referenced Tolerance Table Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x00b0, "SQ", "Referenced Bolus Sequence", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x00c0, "IS", "Referenced Wedge Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x00d0, "IS", "Referenced Compensato rNumber", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x00e0, "IS", "Referenced Block Number", (DicomElemParseFunc *) NULL },
+ { 0x300c, 0x00f0, "IS", "Referenced Control Point", (DicomElemParseFunc *) NULL },
+ { 0x300e, 0x0002, "CS", "Approval Status", (DicomElemParseFunc *) NULL },
+ { 0x300e, 0x0004, "DA", "Review Date", (DicomElemParseFunc *) NULL },
+ { 0x300e, 0x0005, "TM", "Review Time", (DicomElemParseFunc *) NULL },
+ { 0x300e, 0x0008, "PN", "Reviewer Name", (DicomElemParseFunc *) NULL },
+ { 0x4000, 0x0000, "UL", "Text Group Length", (DicomElemParseFunc *) NULL },
+ { 0x4000, 0x0010, "LT", "Text Arbitrary", (DicomElemParseFunc *) NULL },
+ { 0x4000, 0x4000, "LT", "Text Comments", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0000, "UL", "Results Group Length", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0040, "SH", "Results ID", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0042, "LO", "Results ID Issuer", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0050, "SQ", "Referenced Interpretation Sequence", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x00ff, "CS", "Report Production Status", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0100, "DA", "Interpretation Recorded Date", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0101, "TM", "Interpretation Recorded Time", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0102, "PN", "Interpretation Recorder", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0103, "LO", "Reference to Recorded Sound", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0108, "DA", "Interpretation Transcription Date", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0109, "TM", "Interpretation Transcription Time", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x010a, "PN", "Interpretation Transcriber", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x010b, "ST", "Interpretation Text", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x010c, "PN", "Interpretation Author", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0111, "SQ", "Interpretation Approver Sequence", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0112, "DA", "Interpretation Approval Date", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0113, "TM", "Interpretation Approval Time", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0114, "PN", "Physician Approving Interpretation", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0115, "LT", "Interpretation Diagnosis Description", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0117, "SQ", "InterpretationDiagnosis Code Sequence", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0118, "SQ", "Results Distribution List Sequence", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0119, "PN", "Distribution Name", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x011a, "LO", "Distribution Address", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0200, "SH", "Interpretation ID", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0202, "LO", "Interpretation ID Issuer", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0210, "CS", "Interpretation Type ID", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0212, "CS", "Interpretation Status ID", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x0300, "ST", "Impressions", (DicomElemParseFunc *) NULL },
+ { 0x4008, 0x4000, "ST", "Results Comments", (DicomElemParseFunc *) NULL },
+ { 0x4009, 0x0001, "LT", "Report ID", (DicomElemParseFunc *) NULL },
+ { 0x4009, 0x0020, "LT", "Report Status", (DicomElemParseFunc *) NULL },
+ { 0x4009, 0x0030, "DA", "Report Creation Date", (DicomElemParseFunc *) NULL },
+ { 0x4009, 0x0070, "LT", "Report Approving Physician", (DicomElemParseFunc *) NULL },
+ { 0x4009, 0x00e0, "LT", "Report Text", (DicomElemParseFunc *) NULL },
+ { 0x4009, 0x00e1, "LT", "Report Author", (DicomElemParseFunc *) NULL },
+ { 0x4009, 0x00e3, "LT", "Reporting Radiologist", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0000, "UL", "Curve Group Length", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0005, "US", "Curve Dimensions", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0010, "US", "Number of Points", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0020, "CS", "Type of Data", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0022, "LO", "Curve Description", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0030, "SH", "Axis Units", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0040, "SH", "Axis Labels", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0103, "US", "Data Value Representation", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0104, "US", "Minimum Coordinate Value", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0105, "US", "Maximum Coordinate Value", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0106, "SH", "Curve Range", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0110, "US", "Curve Data Descriptor", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0112, "US", "Coordinate Start Value", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x0114, "US", "Coordinate Step Value", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x1001, "CS", "Curve Activation Layer", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x2000, "US", "Audio Type", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x2002, "US", "Audio Sample Format", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x2004, "US", "Number of Channels", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x2006, "UL", "Number of Samples", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x2008, "UL", "Sample Rate", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x200a, "UL", "Total Time", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x200c, "xs", "Audio Sample Data", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x200e, "LT", "Audio Comments", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x2500, "LO", "Curve Label", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x2600, "SQ", "CurveReferenced Overlay Sequence", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x2610, "US", "CurveReferenced Overlay Group", (DicomElemParseFunc *) NULL },
+ { 0x5000, 0x3000, "OW", "Curve Data", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0000, "UL", "Overlay Group Length", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0001, "US", "Gray Palette Color Lookup Table Descriptor", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0002, "US", "Gray Palette Color Lookup Table Data", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0010, "US", "Overlay Rows", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0011, "US", "Overlay Columns", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0012, "US", "Overlay Planes", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0015, "IS", "Number of Frames in Overlay", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0022, "LO", "Overlay Description", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0040, "CS", "Overlay Type", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0045, "CS", "Overlay Subtype", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0050, "SS", "Overlay Origin", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0051, "US", "Image Frame Origin", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0052, "US", "Plane Origin", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0060, "LO", "Overlay Compression Code", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0061, "SH", "Overlay Compression Originator", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0062, "SH", "Overlay Compression Label", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0063, "SH", "Overlay Compression Description", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0066, "AT", "Overlay Compression Step Pointers", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0068, "US", "Overlay Repeat Interval", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0069, "US", "Overlay Bits Grouped", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0100, "US", "Overlay Bits Allocated", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0102, "US", "Overlay Bit Position", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0110, "LO", "Overlay Format", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0200, "xs", "Overlay Location", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0800, "LO", "Overlay Code Label", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0802, "US", "Overlay Number of Tables", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0803, "AT", "Overlay Code Table Location", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x0804, "US", "Overlay Bits For Code Word", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1001, "CS", "Overlay Activation Layer", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1100, "US", "Overlay Descriptor - Gray", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1101, "US", "Overlay Descriptor - Red", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1102, "US", "Overlay Descriptor - Green", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1103, "US", "Overlay Descriptor - Blue", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1200, "US", "Overlays - Gray", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1201, "US", "Overlays - Red", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1202, "US", "Overlays - Green", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1203, "US", "Overlays - Blue", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1301, "IS", "ROI Area", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1302, "DS", "ROI Mean", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1303, "DS", "ROI Standard Deviation", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x1500, "LO", "Overlay Label", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x3000, "OW", "Overlay Data", (DicomElemParseFunc *) NULL },
+ { 0x6000, 0x4000, "LT", "Overlay Comments", (DicomElemParseFunc *) NULL },
+ { 0x6001, 0x0000, "UN", "?", (DicomElemParseFunc *) NULL },
+ { 0x6001, 0x0010, "LO", "?", (DicomElemParseFunc *) NULL },
+ { 0x6001, 0x1010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x6001, 0x1030, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x6021, 0x0000, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x6021, 0x0010, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x7001, 0x0010, "LT", "Dummy", (DicomElemParseFunc *) NULL },
+ { 0x7003, 0x0010, "LT", "Info", (DicomElemParseFunc *) NULL },
+ { 0x7005, 0x0010, "LT", "Dummy", (DicomElemParseFunc *) NULL },
+ { 0x7000, 0x0004, "ST", "TextAnnotation", (DicomElemParseFunc *) NULL },
+ { 0x7000, 0x0005, "IS", "Box", (DicomElemParseFunc *) NULL },
+ { 0x7000, 0x0007, "IS", "ArrowEnd", (DicomElemParseFunc *) NULL },
+ { 0x7fe0, 0x0000, "UL", "Pixel Data Group Length", (DicomElemParseFunc *) NULL },
+ { 0x7fe0, 0x0010, "xs", "Pixel Data", (DicomElemParseFunc *) NULL },
+ { 0x7fe0, 0x0020, "OW", "Coefficients SDVN", (DicomElemParseFunc *) NULL },
+ { 0x7fe0, 0x0030, "OW", "Coefficients SDHN", (DicomElemParseFunc *) NULL },
+ { 0x7fe0, 0x0040, "OW", "Coefficients SDDN", (DicomElemParseFunc *) NULL },
+ { 0x7fe1, 0x0010, "xs", "Pixel Data", (DicomElemParseFunc *) NULL },
+ { 0x7f00, 0x0000, "UL", "Variable Pixel Data Group Length", (DicomElemParseFunc *) NULL },
+ { 0x7f00, 0x0010, "xs", "Variable Pixel Data", (DicomElemParseFunc *) NULL },
+ { 0x7f00, 0x0011, "US", "Variable Next Data Group", (DicomElemParseFunc *) NULL },
+ { 0x7f00, 0x0020, "OW", "Variable Coefficients SDVN", (DicomElemParseFunc *) NULL },
+ { 0x7f00, 0x0030, "OW", "Variable Coefficients SDHN", (DicomElemParseFunc *) NULL },
+ { 0x7f00, 0x0040, "OW", "Variable Coefficients SDDN", (DicomElemParseFunc *) NULL },
+ { 0x7fe1, 0x0000, "OB", "Binary Data", (DicomElemParseFunc *) NULL },
+ { 0x7fe3, 0x0000, "LT", "Image Graphics Format Code", (DicomElemParseFunc *) NULL },
+ { 0x7fe3, 0x0010, "OB", "Image Graphics", (DicomElemParseFunc *) NULL },
+ { 0x7fe3, 0x0020, "OB", "Image Graphics Dummy", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0001, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0002, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0003, "xs", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0004, "IS", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0005, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0007, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0008, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0009, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x000a, "LT", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x000b, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x000c, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x000d, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0x7ff1, 0x0010, "US", "?", (DicomElemParseFunc *) NULL },
+ { 0xfffc, 0xfffc, "OB", "Data Set Trailing Padding", (DicomElemParseFunc *) NULL },
+ { 0xfffe, 0xe000, "!!", "Item", (DicomElemParseFunc *) NULL },
+ { 0xfffe, 0xe00d, "!!", "Item Delimitation Item", (DicomElemParseFunc *) NULL },
+ { 0xfffe, 0xe0dd, "!!", "Sequence Delimitation Item", (DicomElemParseFunc *) NULL },
+ { 0xffff, 0xffff, "xs", "", (DicomElemParseFunc *) NULL }
+ };
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s D C M %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsDCM returns True if the image format type, identified by the
+% magick string, is DCM.
+%
+% The format of the ReadDCMImage method is:
+%
+% unsigned int IsDCM(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsDCM returns True if the image format type is DCM.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static MagickPassFail IsDCM(const unsigned char *magick,const size_t length)
+{
+ if (length < 132)
+ return(False);
+ if (LocaleNCompare((char *) (magick+128),"DICM",4) == 0)
+ return(True);
+ return(False);
+}
+
+static MagickPassFail DCM_InitDCM(DicomStream *dcm,int verbose)
+{
+ dcm->columns=0;
+ dcm->rows=0;
+ dcm->samples_per_pixel=1;
+ dcm->bits_allocated=8;
+ dcm->significant_bits=0;
+ dcm->high_bit=0;
+ dcm->bytes_per_pixel=1;
+ dcm->max_value_in=255;
+ dcm->max_value_out=255;
+ dcm->pixel_representation=0;
+ dcm->transfer_syntax=DCM_TS_IMPL_LITTLE;
+ dcm->interlace=0;
+ dcm->msb_state=DCM_MSB_LITTLE;
+ dcm->phot_interp=DCM_PI_MONOCHROME2;
+ dcm->window_center=0;
+ dcm->window_width=0;
+ dcm->rescale_intercept=0;
+ dcm->rescale_slope=1;
+ dcm->number_scenes=1;
+ dcm->data=NULL;
+ dcm->upper_lim=0;
+ dcm->lower_lim=0;
+ dcm->rescale_map=NULL;
+ dcm->rescale_type=DCM_RT_HOUNSFIELD;
+ dcm->rescaling=DCM_RS_NONE;
+ dcm->offset_ct=0;
+ dcm->offset_arr=NULL;
+ dcm->frag_bytes=0;
+ dcm->rle_rep_ct=0;
+#if defined(USE_GRAYMAP)
+ dcm->graymap=(unsigned short *) NULL;
+#endif
+ dcm->funcReadShort=ReadBlobLSBShort;
+ dcm->funcReadLong=ReadBlobLSBLong;
+ dcm->explicit_file=False;
+ dcm->verbose=verbose;
+
+ return MagickPass;
+}
+
+/*
+ Parse functions for DICOM elements
+*/
+static MagickPassFail funcDCM_TransferSyntax(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ char
+ *p;
+
+ int
+ type,
+ subtype;
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ p=(char *) dcm->data;
+ if (strncmp(p,"1.2.840.10008.1.2",17) == 0)
+ {
+ if (*(p+17) == 0)
+ {
+ dcm->transfer_syntax = DCM_TS_IMPL_LITTLE;
+ return MagickPass;
+ }
+ type=0;
+ subtype=0;
+ /* Subtype is not always provided, but insist on type */
+ if (sscanf(p+17,".%d.%d",&type,&subtype) < 1)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+ switch (type)
+ {
+ case 1:
+ dcm->transfer_syntax = DCM_TS_EXPL_LITTLE;
+ break;
+ case 2:
+ dcm->transfer_syntax = DCM_TS_EXPL_BIG;
+ dcm->msb_state=DCM_MSB_BIG_PENDING;
+ break;
+ case 4:
+ if ((subtype >= 80) && (subtype <= 81))
+ dcm->transfer_syntax = DCM_TS_JPEG_LS;
+ else
+ if ((subtype >= 90) && (subtype <= 93))
+ dcm->transfer_syntax = DCM_TS_JPEG_2000;
+ else
+ dcm->transfer_syntax = DCM_TS_JPEG;
+ break;
+ case 5:
+ dcm->transfer_syntax = DCM_TS_RLE;
+ break;
+ }
+ }
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_StudyDate(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+
+ (void) SetImageAttribute(image,"StudyDate",(char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_PatientName(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+
+ (void) SetImageAttribute(image,"PatientName",(char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_TriggerTime(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+
+ (void) SetImageAttribute(image,"TriggerTime",(char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_FieldOfView(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+
+ (void) SetImageAttribute(image,"FieldOfView",(char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_SeriesNumber(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+ (void) SetImageAttribute(image,"SeriesNumber",(char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_ImagePosition(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+ (void) SetImageAttribute(image,"ImagePosition",(char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_ImageOrientation(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+ (void) SetImageAttribute(image,"ImageOrientation",(char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_SliceLocation(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+ (void) SetImageAttribute(image,"SliceLocation",(char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_SamplesPerPixel(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+ dcm->samples_per_pixel=dcm->datum;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_PhotometricInterpretation(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ char photometric[MaxTextExtent];
+ int i;
+
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ for (i=0; i < (long) Min(dcm->length, MaxTextExtent-1); i++)
+ photometric[i]=dcm->data[i];
+ photometric[i]='\0';
+
+ if (strncmp(photometric,"MONOCHROME1",11) == 0)
+ dcm->phot_interp = DCM_PI_MONOCHROME1;
+ else
+ if (strncmp(photometric,"MONOCHROME2",11) == 0)
+ dcm->phot_interp = DCM_PI_MONOCHROME2;
+ else
+ if (strncmp(photometric,"PALETTE COLOR",13) == 0)
+ dcm->phot_interp = DCM_PI_PALETTE_COLOR;
+ else
+ if (strncmp(photometric,"RGB",3) == 0)
+ dcm->phot_interp = DCM_PI_RGB;
+ else
+ dcm->phot_interp = DCM_PI_OTHER;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_PlanarConfiguration(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ dcm->interlace=dcm->datum;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_NumberOfFrames(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ dcm->number_scenes=MagickAtoI((char *) dcm->data);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_Rows(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ dcm->rows=dcm->datum;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_Columns(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ dcm->columns=dcm->datum;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_BitsAllocated(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ dcm->bits_allocated=dcm->datum;
+ dcm->bytes_per_pixel=1;
+ if (dcm->datum > 8)
+ dcm->bytes_per_pixel=2;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_BitsStored(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+
+ dcm->significant_bits=dcm->datum;
+ dcm->bytes_per_pixel=1;
+ if (dcm->significant_bits > 8)
+ dcm->bytes_per_pixel=2;
+ dcm->max_value_in=(1 << dcm->significant_bits)-1;
+ dcm->max_value_out=dcm->max_value_in;
+ image->depth=Min(dcm->significant_bits,QuantumDepth);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_HighBit(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ dcm->high_bit=dcm->datum;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_PixelRepresentation(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ dcm->pixel_representation=dcm->datum;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_WindowCenter(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ char
+ *p;
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ p = strrchr((char *) dcm->data,'\\');
+ if (p)
+ p++;
+ else
+ p=(char *) dcm->data;
+ dcm->window_center=MagickAtoF(p);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_WindowWidth(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ char
+ *p;
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ p = strrchr((char *) dcm->data,'\\');
+ if (p)
+ p++;
+ else
+ p=(char *) dcm->data;
+ dcm->window_width=MagickAtoF(p);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_RescaleIntercept(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ char
+ *p;
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ p = strrchr((char *) dcm->data,'\\');
+ if (p)
+ p++;
+ else
+ p=(char *) dcm->data;
+ dcm->rescale_intercept=MagickAtoF(p);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_RescaleSlope(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ char
+ *p;
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ p = strrchr((char *) dcm->data,'\\');
+ if (p)
+ p++;
+ else
+ p=(char *) dcm->data;
+ dcm->rescale_slope=MagickAtoF(p);
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_RescaleType(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ if (strncmp((char *) dcm->data,"OD",2) == 0)
+ dcm->rescale_type=DCM_RT_OPTICAL_DENSITY;
+ else if (strncmp((char *) dcm->data,"HU",2) == 0)
+ dcm->rescale_type=DCM_RT_HOUNSFIELD;
+ else if (strncmp((char *) dcm->data,"US",2) == 0)
+ dcm->rescale_type=DCM_RT_UNSPECIFIED;
+ else
+ dcm->rescale_type=DCM_RT_UNKNOWN;
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_PaletteDescriptor(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ /*
+ Palette descriptor tables
+ element = 1101/2/3 = for red/green/blue palette
+ val 0 = # of entries in LUT (0 for 65535)
+ val 1 = min pix value in palette (ie pix <= val1 -> palette[0])
+ val 2 = # bits in LUT (8 or 16)
+ NB Required by specification to be the same for each color
+
+ #1 - check the same each time
+ #2 - use scale_remap to map vals <= (val1) to first entry
+ and vals >= (val1 + palette size) to last entry
+ #3 - if (val2) == 8, use UINT8 values instead of UINT16
+ #4 - Check for UINT8 values packed into low bits of UINT16
+ entries as per spec
+ */
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(dcm);
+ ARG_NOT_USED(exception);
+
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_LUT(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+#if defined(USE_GRAYMAP)
+ /*
+ 1200 = grey, LUT data 3006 = LUT data
+ */
+ unsigned long
+ colors;
+
+ register unsigned long
+ i;
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ colors=dcm->length/dcm->bytes_per_pixel;
+ dcm->datum=(long) colors;
+ dcm->graymap=MagickAllocateArray(unsigned short *,colors,sizeof(unsigned short));
+ if (dcm->graymap == (unsigned short *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image->filename);
+ return MagickFail;
+ }
+ for (i=0; i < (long) colors; i++)
+ if (dcm->bytes_per_pixel == 1)
+ dcm->graymap[i]=dcm->data[i];
+ else
+ dcm->graymap[i]=(unsigned short) ((short *) dcm->data)[i];
+#else
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(dcm);
+ ARG_NOT_USED(exception);
+#endif
+ return MagickPass;
+}
+
+static MagickPassFail funcDCM_Palette(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ register long
+ i;
+
+ unsigned char
+ *p;
+
+ unsigned short
+ index;
+
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ /*
+ Initialize colormap (entries are always 16 bit)
+ 1201/2/3 = red/green/blue palette
+ */
+ if (image->colormap == (PixelPacket *) NULL)
+ {
+ /*
+ Allocate color map first time in
+ */
+ if (!AllocateImageColormap(image,(const unsigned long) dcm->length))
+ {
+ ThrowException(exception,ResourceLimitError,UnableToCreateColormap,image->filename);
+ return MagickFail;
+ }
+ }
+
+ /*
+ Check that palette size matches previous one(s)
+ */
+ if (dcm->length != image->colors)
+ {
+ ThrowException(exception,ResourceLimitError,UnableToCreateColormap,image->filename);
+ return MagickFail;
+ }
+
+ p=dcm->data;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ if (dcm->msb_state == DCM_MSB_BIG)
+ index=(*p << 8) | *(p+1);
+ else
+ index=*p | (*(p+1) << 8);
+ if (dcm->element == 0x1201)
+ image->colormap[i].red=ScaleShortToQuantum(index);
+ else if (dcm->element == 0x1202)
+ image->colormap[i].green=ScaleShortToQuantum(index);
+ else
+ image->colormap[i].blue=ScaleShortToQuantum(index);
+ p+=2;
+ }
+ return MagickPass;
+}
+
+static magick_uint8_t DCM_RLE_ReadByte(Image *image, DicomStream *dcm)
+{
+ if (dcm->rle_rep_ct == 0)
+ {
+ int
+ rep_ct,
+ rep_char;
+
+ /* We need to read the next command pair */
+ if (dcm->frag_bytes <= 2)
+ dcm->frag_bytes = 0;
+ else
+ dcm->frag_bytes -= 2;
+
+ rep_ct=ReadBlobByte(image);
+ rep_char=ReadBlobByte(image);
+ if (rep_ct == 128)
+ {
+ /* Illegal value */
+ return 0;
+ }
+ else
+ if (rep_ct < 128)
+ {
+ /* (rep_ct+1) literal bytes */
+ dcm->rle_rep_ct=rep_ct;
+ dcm->rle_rep_char=-1;
+ return (magick_uint8_t)rep_char;
+ }
+ else
+ {
+ /* (257-rep_ct) repeated bytes */
+ dcm->rle_rep_ct=256-rep_ct;
+ dcm->rle_rep_char=rep_char;
+ return (magick_uint8_t)rep_char;
+ }
+ }
+
+ dcm->rle_rep_ct--;
+ if (dcm->rle_rep_char >= 0)
+ return dcm->rle_rep_char;
+
+ if (dcm->frag_bytes > 0)
+ dcm->frag_bytes--;
+ return ReadBlobByte(image);
+}
+
+static magick_uint16_t DCM_RLE_ReadShort(Image *image, DicomStream *dcm)
+{
+ return (DCM_RLE_ReadByte(image,dcm) << 4) | DCM_RLE_ReadByte(image,dcm);
+}
+
+static MagickPassFail DCM_ReadElement(Image *image, DicomStream *dcm,ExceptionInfo *exception)
+{
+ unsigned int
+ use_explicit;
+
+ char
+ explicit_vr[MaxTextExtent],
+ implicit_vr[MaxTextExtent];
+
+ register long
+ i;
+
+ /*
+ Read group and element IDs
+ */
+ image->offset=(long) TellBlob(image);
+ dcm->group=dcm->funcReadShort(image);
+ if ((dcm->msb_state == DCM_MSB_BIG_PENDING) && (dcm->group != 2))
+ {
+ dcm->group = (dcm->group << 8) | (dcm->group >> 8);
+ dcm->funcReadShort=ReadBlobMSBShort;
+ dcm->funcReadLong=ReadBlobMSBLong;
+ dcm->msb_state=DCM_MSB_BIG;
+ }
+ dcm->element=dcm->funcReadShort(image);
+ dcm->data=(unsigned char *) NULL;
+ dcm->quantum=0;
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ /*
+ Find corresponding VR for this group and element.
+ */
+ for (i=0; dicom_info[i].group < 0xffffU; i++)
+ if ((dcm->group == dicom_info[i].group) &&
+ (dcm->element == dicom_info[i].element))
+ break;
+ dcm->index=i;
+
+ /*
+ Check for "explicitness", but meta-file headers always explicit.
+ */
+ if (ReadBlob(image,2,(char *) explicit_vr) != 2)
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ explicit_vr[2]='\0';
+ (void) strlcpy(implicit_vr,dicom_info[dcm->index].vr,MaxTextExtent);
+
+#if defined(NEW_IMPLICIT_LOGIC)
+ use_explicit=False;
+ if (isupper((int) *explicit_vr) && isupper((int) *(explicit_vr+1)))
+ {
+ /* Explicit VR looks to be valid */
+ if (strcmp(explicit_vr,implicit_vr) == 0)
+ {
+ /* Explicit VR matches implicit VR so assume that it is explicit */
+ use_explicit=True;
+ }
+ else if ((dcm->group & 1) || strcmp(implicit_vr,"xs") == 0)
+ {
+ /*
+ We *must* use explicit type under two conditions
+ 1) group is odd and therefore private
+ 2) element vr is set as "xs" ie is not of a fixed type
+ */
+ use_explicit=True;
+ strcpy(implicit_vr,explicit_vr);
+ }
+ }
+ if ((!use_explicit) || (strcmp(implicit_vr,"!!") == 0))
+ {
+ /* Use implicit logic */
+ (void) SeekBlob(image,(ExtendedSignedIntegralType) -2,SEEK_CUR);
+ dcm->quantum=4;
+ }
+ else
+ {
+ /* Use explicit logic */
+ dcm->quantum=2;
+ if ((strcmp(explicit_vr,"OB") == 0) ||
+ (strcmp(explicit_vr,"OW") == 0) ||
+ (strcmp(explicit_vr,"OF") == 0) ||
+ (strcmp(explicit_vr,"SQ") == 0) ||
+ (strcmp(explicit_vr,"UN") == 0) ||
+ (strcmp(explicit_vr,"UT") == 0))
+ {
+ (void) dcm->funcReadShort(image);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ dcm->quantum=4;
+ }
+ }
+#else
+ if (!dcm->explicit_file && (dcm->group != 0x0002))
+ dcm->explicit_file=isupper((int) *explicit_vr) && isupper((int) *(explicit_vr+1));
+ use_explicit=((dcm->group == 0x0002) || dcm->explicit_file);
+ if (use_explicit && (strcmp(implicit_vr,"xs") == 0))
+ (void) strlcpy(implicit_vr,explicit_vr,MaxTextExtent);
+ if (!use_explicit || (strcmp(implicit_vr,"!!") == 0))
+ {
+ (void) SeekBlob(image,(ExtendedSignedIntegralType) -2,SEEK_CUR);
+ dcm->quantum=4;
+ }
+ else
+ {
+ /*
+ Assume explicit type.
+ */
+ dcm->quantum=2;
+ if ((strcmp(explicit_vr,"OB") == 0) ||
+ (strcmp(explicit_vr,"UN") == 0) ||
+ (strcmp(explicit_vr,"OW") == 0) || (strcmp(explicit_vr,"SQ") == 0))
+ {
+ (void) dcm->funcReadShort(image)
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ dcm->quantum=4;
+ }
+ }
+#endif
+
+ dcm->datum=0;
+ if (dcm->quantum == 4)
+ {
+ dcm->datum=(long) dcm->funcReadLong(image);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ }
+ else if (dcm->quantum == 2)
+ {
+ dcm->datum=(long) dcm->funcReadShort(image);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ }
+ dcm->quantum=0;
+ dcm->length=1;
+ if (dcm->datum != 0)
+ {
+ if ((strcmp(implicit_vr,"SS") == 0) ||
+ (strcmp(implicit_vr,"US") == 0) ||
+ (strcmp(implicit_vr,"OW") == 0))
+ dcm->quantum=2;
+ else if ((strcmp(implicit_vr,"UL") == 0) ||
+ (strcmp(implicit_vr,"SL") == 0) ||
+ (strcmp(implicit_vr,"FL") == 0) ||
+ (strcmp(implicit_vr,"OF") == 0))
+ dcm->quantum=4;
+ else if (strcmp(implicit_vr,"FD") == 0)
+ dcm->quantum=8;
+ else
+ dcm->quantum=1;
+
+ if (dcm->datum != -1)
+ {
+ dcm->length=(size_t) dcm->datum/dcm->quantum;
+ }
+ else
+ {
+ /*
+ Sequence and item of undefined length.
+ */
+ dcm->quantum=0;
+ dcm->length=0;
+ }
+ }
+ /*
+ Display Dicom info.
+ */
+ if (dcm->verbose)
+ {
+ if (!use_explicit)
+ explicit_vr[0]='\0';
+ (void) fprintf(stdout,"0x%04lX %4lu %.1024s-%.1024s (0x%04x,0x%04x)",
+ image->offset,(unsigned long) dcm->length,implicit_vr,explicit_vr,
+ dcm->group,dcm->element);
+ if (dicom_info[dcm->index].description != (char *) NULL)
+ (void) fprintf(stdout," %.1024s",dicom_info[dcm->index].description);
+ (void) fprintf(stdout,": ");
+ }
+ if ((dcm->group == 0x7FE0) && (dcm->element == 0x0010))
+ {
+ if (dcm->verbose)
+ (void) fprintf(stdout,"\n");
+ return MagickPass;
+ }
+ /*
+ Allocate array and read data into it
+ */
+ if ((dcm->length == 1) && (dcm->quantum == 1))
+ {
+ if ((dcm->datum=ReadBlobByte(image)) == EOF)
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ }
+ else if ((dcm->length == 1) && (dcm->quantum == 2))
+ {
+ dcm->datum=dcm->funcReadShort(image);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ }
+ else if ((dcm->length == 1) && (dcm->quantum == 4))
+ {
+ dcm->datum=(long) dcm->funcReadLong(image);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ }
+ else if ((dcm->quantum != 0) && (dcm->length != 0))
+ {
+ size_t
+ size;
+
+ if (dcm->length > ((~0UL)/dcm->quantum))
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+ dcm->data=MagickAllocateArray(unsigned char *,(dcm->length+1),dcm->quantum);
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image->filename);
+ return MagickFail;
+ }
+ size=dcm->quantum*dcm->length;
+ if (ReadBlob(image,size,(char *) dcm->data) != size)
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ dcm->data[size]=0;
+ }
+
+ if (dcm->verbose)
+ {
+ /*
+ Display data
+ */
+ if (dcm->data == (unsigned char *) NULL)
+ {
+ (void) fprintf(stdout,"%d\n",dcm->datum);
+ }
+ else
+ {
+ for (i=0; i < (long) Max(dcm->length,4); i++)
+ if (!isprint(dcm->data[i]))
+ break;
+ if ((i != (long) dcm->length) && (dcm->length <= 4))
+ {
+ long
+ j,
+ bin_datum;
+
+ bin_datum=0;
+ for (j=(long) dcm->length-1; j >= 0; j--)
+ bin_datum=256*bin_datum+dcm->data[j];
+ (void) fprintf(stdout,"%lu\n",bin_datum);
+ }
+ else
+ {
+ for (i=0; i < (long) dcm->length; i++)
+ if (isprint(dcm->data[i]))
+ (void) fprintf(stdout,"%c",dcm->data[i]);
+ else
+ (void) fprintf(stdout,"%c",'.');
+ (void) fprintf(stdout,"\n");
+ }
+ }
+ }
+ return MagickPass;
+}
+
+static MagickPassFail DCM_SetupColormap(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ if ((image->previous) && (image->previous->colormap != (PixelPacket*)NULL))
+ {
+ size_t
+ length;
+
+ /*
+ Clone colormap from previous image
+ */
+ image->storage_class=PseudoClass;
+ image->colors=image->previous->colors;
+ length=image->colors*sizeof(PixelPacket);
+ image->colormap=MagickAllocateMemory(PixelPacket *,length);
+ if (image->colormap == (PixelPacket *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image->filename);
+ return MagickFail;
+ }
+ (void) memcpy(image->colormap,image->previous->colormap,length);
+ }
+ else
+ {
+ /*
+ Create new colormap
+ */
+ if (AllocateImageColormap(image,dcm->max_value_out+1) == MagickFail)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image->filename);
+ return MagickFail;
+ }
+ }
+ return MagickPass;
+}
+
+static MagickPassFail DCM_SetupRescaleMap(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ /*
+ rescale_map maps input sample range -> output colormap range combining rescale
+ and window transforms, palette scaling and palette inversion (for MONOCHROME1)
+ as well as allowing for pixel_representation of 1 which causes input samples to
+ be treated as signed
+ */
+ double
+ win_center,
+ win_width,
+ Xr,
+ Xw_min,
+ Xw_max;
+
+ unsigned long
+ i;
+
+ if (dcm->rescaling == DCM_RS_NONE)
+ return MagickPass;
+
+ if (dcm->rescale_map == (Quantum *) NULL)
+ {
+ dcm->rescale_map=MagickAllocateArray(Quantum *,dcm->max_value_in+1,sizeof(Quantum));
+ if (dcm->rescale_map == NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image->filename);
+ return MagickFail;
+ }
+ }
+
+ if (dcm->window_width == 0)
+ { /* zero window width */
+ if (dcm->upper_lim > dcm->lower_lim)
+ {
+ /* Use known range within image */
+ win_width=(dcm->upper_lim-dcm->lower_lim+1)*dcm->rescale_slope;
+ win_center=((dcm->upper_lim+dcm->lower_lim)/2)*dcm->rescale_slope+dcm->rescale_intercept;
+ }
+ else
+ {
+ /* Use full sample range and hope for the best */
+ win_width=(dcm->max_value_in+1)*dcm->rescale_slope;
+ if (dcm->pixel_representation == 1)
+ win_center=dcm->rescale_intercept;
+ else
+ win_center=win_width/2 + dcm->rescale_intercept;
+ }
+ }
+ else
+ {
+ win_width=dcm->window_width;
+ win_center=dcm->window_center;
+ }
+ Xw_min = win_center - 0.5 - ((win_width-1)/2);
+ Xw_max = win_center - 0.5 + ((win_width-1)/2);
+ for (i=0; i < (dcm->max_value_in+1); i++)
+ {
+ if ((dcm->pixel_representation == 1) && (i >= (1U << (dcm->significant_bits-1))))
+ Xr = -((dcm->max_value_in+1-i) * dcm->rescale_slope) + dcm->rescale_intercept;
+ else
+ Xr = (i * dcm->rescale_slope) + dcm->rescale_intercept;
+ if (Xr <= Xw_min)
+ dcm->rescale_map[i]=0;
+ else if (Xr >= Xw_max)
+ dcm->rescale_map[i]=dcm->max_value_out;
+ else
+ dcm->rescale_map[i]=(Quantum)(((Xr-Xw_min)/(win_width-1))*dcm->max_value_out+0.5);
+ }
+ if (dcm->phot_interp == DCM_PI_MONOCHROME1)
+ for (i=0; i < (dcm->max_value_in+1); i++)
+ dcm->rescale_map[i]=dcm->max_value_out-dcm->rescale_map[i];
+ return MagickPass;
+}
+
+void DCM_SetRescaling(DicomStream *dcm,int avoid_scaling)
+{
+ /*
+ If avoid_scaling is True then scaling will only be applied where necessary ie
+ input bit depth exceeds quantum size.
+
+ ### TODO : Should this throw an error rather than setting DCM_RS_PRE?
+ */
+ dcm->rescaling=DCM_RS_NONE;
+ dcm->max_value_out=dcm->max_value_in;
+
+ if (dcm->phot_interp == DCM_PI_PALETTE_COLOR)
+ {
+ if (dcm->max_value_in >= MaxColormapSize)
+ {
+ dcm->max_value_out=MaxColormapSize-1;
+ dcm->rescaling=DCM_RS_PRE;
+ }
+ return;
+ }
+
+ if ((dcm->phot_interp == DCM_PI_MONOCHROME1) ||
+ (dcm->phot_interp == DCM_PI_MONOCHROME2))
+ {
+ if ((dcm->transfer_syntax == DCM_TS_JPEG) ||
+ (dcm->transfer_syntax == DCM_TS_JPEG_LS) ||
+ (dcm->transfer_syntax == DCM_TS_JPEG_2000))
+ {
+ /* Encapsulated non-native grayscale images are post rescaled by default */
+ if (!avoid_scaling)
+ dcm->rescaling=DCM_RS_POST;
+ }
+#if defined(GRAYSCALE_USES_PALETTE)
+ else if (dcm->max_value_in >= MaxColormapSize)
+ {
+ dcm->max_value_out=MaxColormapSize-1;
+ dcm->rescaling=DCM_RS_PRE;
+ }
+#else
+ else if (dcm->max_value_in > MaxRGB)
+ {
+ dcm->max_value_out=MaxRGB;
+ dcm->rescaling=DCM_RS_PRE;
+ }
+#endif
+ else if (!avoid_scaling)
+ {
+#if !defined(GRAYSCALE_USES_PALETTE)
+ dcm->max_value_out=MaxRGB;
+#endif
+ dcm->rescaling=DCM_RS_POST;
+ }
+ return;
+ }
+
+ if (avoid_scaling || (dcm->max_value_in == MaxRGB))
+ return;
+
+ dcm->max_value_out=MaxRGB;
+ dcm->rescaling=DCM_RS_PRE;
+}
+
+static MagickPassFail DCM_PostRescaleImage(Image *image,DicomStream *dcm,unsigned long ScanLimits,ExceptionInfo *exception)
+{
+ unsigned long
+ y,
+ x;
+
+ register PixelPacket
+ *q;
+
+ if (ScanLimits)
+ {
+ /*
+ Causes rescan for upper/lower limits - used for encapsulated images
+ */
+ unsigned int
+ l;
+
+ for (y=0; y < image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ return MagickFail;
+
+ if (image->storage_class == PseudoClass)
+ {
+ register IndexPacket
+ *indexes;
+
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < image->columns; x++)
+ {
+ l=indexes[x];
+ if (dcm->pixel_representation == 1)
+ if (l > ((dcm->max_value_in >> 1)))
+ l = dcm->max_value_in-l+1;
+ if (l < (unsigned int) dcm->lower_lim)
+ dcm->lower_lim = l;
+ if (l > (unsigned int) dcm->upper_lim)
+ dcm->upper_lim = l;
+ }
+ }
+ else
+ {
+ for (x=0; x < image->columns; x++)
+ {
+ l=q->green;
+ if (dcm->pixel_representation == 1)
+ if (l > (dcm->max_value_in >> 1))
+ l = dcm->max_value_in-l+1;
+ if (l < (unsigned int) dcm->lower_lim)
+ dcm->lower_lim = l;
+ if (l > (unsigned int) dcm->upper_lim)
+ dcm->upper_lim = l;
+ q++;
+ }
+ }
+ }
+
+ if (image->storage_class == PseudoClass)
+ {
+ /* Handle compressed range by reallocating palette */
+ if (!AllocateImageColormap(image,dcm->upper_lim+1))
+ {
+ ThrowException(exception,ResourceLimitError,UnableToCreateColormap,image->filename);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ }
+
+ DCM_SetupRescaleMap(image,dcm,exception);
+ for (y=0; y < image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ return MagickFail;
+
+ if (image->storage_class == PseudoClass)
+ {
+ register IndexPacket
+ *indexes;
+
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < image->columns; x++)
+ indexes[x]=dcm->rescale_map[indexes[x]];
+ }
+ else
+ {
+ for (x=0; x < image->columns; x++)
+ {
+ q->red=dcm->rescale_map[q->red];
+ q->green=dcm->rescale_map[q->green];
+ q->blue=dcm->rescale_map[q->blue];
+ q++;
+ }
+ }
+ if (!SyncImagePixels(image))
+ return MagickFail;
+ /*
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename))
+ return MagickFail;
+ */
+ }
+ return MagickPass;
+}
+
+static MagickPassFail DCM_ReadPaletteImage(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register IndexPacket
+ *indexes;
+
+ unsigned short
+ index;
+
+ unsigned char
+ byte;
+
+ byte=0;
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ return MagickFail;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (dcm->bytes_per_pixel == 1)
+ {
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ index=DCM_RLE_ReadByte(image,dcm);
+ else
+ index=ReadBlobByte(image);
+ }
+ else
+ if (dcm->bits_allocated != 12)
+ {
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ index=DCM_RLE_ReadShort(image,dcm);
+ else
+ index=dcm->funcReadShort(image);
+ }
+ else
+ {
+ if (x & 0x01)
+ {
+ /* ### TODO - Check whether logic needs altering if msb_state != DCM_MSB_LITTLE */
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ index=DCM_RLE_ReadByte(image,dcm);
+ else
+ index=ReadBlobByte(image);
+ index=(index << 4) | byte;
+ }
+ else
+ {
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ index=DCM_RLE_ReadByte(image,dcm);
+ else
+ index=dcm->funcReadShort(image);
+ byte=index >> 12;
+ index&=0xfff;
+ }
+ }
+ index&=dcm->max_value_in;
+ if (dcm->rescaling == DCM_RS_PRE)
+ {
+ /*
+ ### TODO - must read as Direct Class so look up
+ red/green/blue values in palette table, processed via
+ rescale_map
+ */
+ }
+ else
+ {
+#if defined(USE_GRAYMAP)
+ if (dcm->graymap != (unsigned short *) NULL)
+ index=dcm->graymap[index];
+#endif
+ index=(IndexPacket) (index);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ }
+
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ }
+ if (!SyncImagePixels(image))
+ return MagickFail;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ return MagickFail;
+ }
+ return MagickPass;
+}
+
+static MagickPassFail DCM_ReadGrayscaleImage(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+#if defined(GRAYSCALE_USES_PALETTE)
+ register IndexPacket
+ *indexes;
+#endif
+
+ unsigned short
+ index;
+
+ unsigned char
+ byte;
+
+ dcm->lower_lim = dcm->max_value_in;
+ dcm->upper_lim = -(dcm->lower_lim);
+ byte=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ return MagickFail;
+#if defined(GRAYSCALE_USES_PALETTE)
+ indexes=AccessMutableIndexes(image);
+#endif
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (dcm->bytes_per_pixel == 1)
+ {
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ index=DCM_RLE_ReadByte(image,dcm);
+ else
+ index=ReadBlobByte(image);
+ }
+ else
+ if (dcm->bits_allocated != 12)
+ {
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ index=DCM_RLE_ReadShort(image,dcm);
+ else
+ index=dcm->funcReadShort(image);
+ }
+ else
+ {
+ if (x & 0x01)
+ {
+ /* ### TODO - Check whether logic needs altering if msb_state != DCM_MSB_LITTLE */
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ index=DCM_RLE_ReadByte(image,dcm);
+ else
+ index=ReadBlobByte(image);
+ index=(index << 4) | byte;
+ }
+ else
+ {
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ index=DCM_RLE_ReadShort(image,dcm);
+ else
+ index=dcm->funcReadShort(image);
+ byte=index >> 12;
+ index&=0xfff;
+ }
+ }
+ index&=dcm->max_value_in;
+ if (dcm->rescaling == DCM_RS_POST)
+ {
+ unsigned int
+ l;
+
+ l = index;
+ if (dcm->pixel_representation == 1)
+ if (l > (dcm->max_value_in >> 1))
+ l = dcm->max_value_in-l+1;
+ if ((int) l < dcm->lower_lim)
+ dcm->lower_lim = l;
+ if ((int) l > dcm->upper_lim)
+ dcm->upper_lim = l;
+ }
+#if defined(GRAYSCALE_USES_PALETTE)
+ if (dcm->rescaling == DCM_RS_PRE)
+ indexes[x]=dcm->rescale_map[index];
+ else
+ indexes[x]=index;
+#else
+ if (dcm->rescaling == DCM_RS_PRE)
+ index=dcm->rescale_map[index];
+ q->red=index;
+ q->green=index;
+ q->blue=index;
+ q++;
+#endif
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ }
+ if (!SyncImagePixels(image))
+ return MagickFail;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ return MagickFail;
+ }
+ return MagickPass;
+}
+
+static MagickPassFail DCM_ReadPlanarRGBImage(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ unsigned long
+ plane,
+ y,
+ x;
+
+ register PixelPacket
+ *q;
+
+ for (plane=0; plane < dcm->samples_per_pixel; plane++)
+ {
+ for (y=0; y < image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ return MagickFail;
+
+ for (x=0; x < image->columns; x++)
+ {
+ switch ((int) plane)
+ {
+ case 0:
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ q->red=ScaleCharToQuantum(DCM_RLE_ReadByte(image,dcm));
+ else
+ q->red=ScaleCharToQuantum(ReadBlobByte(image));
+ break;
+ case 1:
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ q->green=ScaleCharToQuantum(DCM_RLE_ReadByte(image,dcm));
+ else
+ q->green=ScaleCharToQuantum(ReadBlobByte(image));
+ break;
+ case 2:
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ q->blue=ScaleCharToQuantum(DCM_RLE_ReadByte(image,dcm));
+ else
+ q->blue=ScaleCharToQuantum(ReadBlobByte(image));
+ break;
+ case 3:
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ q->opacity=ScaleCharToQuantum((Quantum)(MaxRGB-ScaleCharToQuantum(DCM_RLE_ReadByte(image,dcm))));
+ else
+ q->opacity=ScaleCharToQuantum((Quantum)(MaxRGB-ScaleCharToQuantum(ReadBlobByte(image))));
+ break;
+ }
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ return MagickFail;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ return MagickFail;
+ }
+ }
+ return MagickPass;
+}
+
+static MagickPassFail DCM_ReadRGBImage(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ unsigned long
+ y,
+ x;
+
+ register PixelPacket
+ *q;
+
+ Quantum
+ blue,
+ green,
+ red;
+
+ red=0;
+ green=0;
+ blue=0;
+
+ for (y=0; y < image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ return MagickFail;
+
+ for (x=0; x < image->columns; x++)
+ {
+ if (dcm->bytes_per_pixel == 1)
+ {
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ {
+ red=DCM_RLE_ReadByte(image,dcm);
+ green=DCM_RLE_ReadByte(image,dcm);
+ blue=DCM_RLE_ReadByte(image,dcm);
+
+ }
+ else
+ {
+ red=ReadBlobByte(image);
+ green=ReadBlobByte(image);
+ blue=ReadBlobByte(image);
+ }
+ }
+ else
+ {
+ if (dcm->transfer_syntax == DCM_TS_RLE)
+ {
+ red=DCM_RLE_ReadShort(image,dcm);
+ green=DCM_RLE_ReadShort(image,dcm);
+ blue=DCM_RLE_ReadShort(image,dcm);
+ }
+ else
+ {
+ red=dcm->funcReadShort(image);
+ green=dcm->funcReadShort(image);
+ blue=dcm->funcReadShort(image);
+ }
+ }
+ red&=dcm->max_value_in;
+ green&=dcm->max_value_in;
+ blue&=dcm->max_value_in;
+ if (dcm->rescaling == DCM_RS_PRE)
+ {
+ red=dcm->rescale_map[red];
+ green=dcm->rescale_map[green];
+ blue=dcm->rescale_map[blue];
+ }
+
+ q->red=(Quantum) red;
+ q->green=(Quantum) green;
+ q->blue=(Quantum) blue;
+ q++;
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+ return MagickFail;
+ }
+ }
+ if (!SyncImagePixels(image))
+ return MagickFail;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ return MagickFail;
+ }
+ return MagickPass;
+}
+
+static MagickPassFail DCM_ReadOffsetTable(Image *image,DicomStream *dcm,ExceptionInfo *exception)
+{
+ magick_uint32_t
+ base_offset,
+ tag,
+ length,
+ i;
+
+ tag=(dcm->funcReadShort(image) << 16) | dcm->funcReadShort(image);
+ length=dcm->funcReadLong(image);
+ if (tag != 0xFFFEE000)
+ return MagickFail;
+
+ dcm->offset_ct=length >> 2;
+ if (dcm->offset_ct == 0)
+ return MagickPass;
+
+ if (dcm->offset_ct != dcm->number_scenes)
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ return MagickFail;
+ }
+
+ dcm->offset_arr=MagickAllocateArray(magick_uint32_t *,dcm->offset_ct,sizeof(magick_uint32_t));
+ if (dcm->offset_arr == (magick_uint32_t *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image->filename);
+ return MagickFail;
+ }
+
+ for (i=0; i < dcm->offset_ct; i++)
+ {
+ dcm->offset_arr[i]=dcm->funcReadLong(image);
+ if (EOFBlob(image))
+ return MagickFail;
+ }
+ base_offset=(magick_uint32_t)TellBlob(image);
+ for (i=0; i < dcm->offset_ct; i++)
+ dcm->offset_arr[i]+=base_offset;
+
+ /*
+ Seek first fragment of first frame if necessary (although it shouldn't be...)
+ */
+ if (TellBlob(image) != dcm->offset_arr[0])
+ SeekBlob(image,dcm->offset_arr[0],SEEK_SET);
+ return MagickPass;
+}
+
+static MagickPassFail DCM_ReadNonNativeImages(Image **image,const ImageInfo *image_info,DicomStream *dcm,ExceptionInfo *exception)
+{
+ char
+ filename[MaxTextExtent];
+
+ FILE
+ *file;
+
+ int
+ c;
+
+ Image
+ *image_list,
+ *next_image;
+
+ ImageInfo
+ *clone_info;
+
+ magick_uint32_t
+ scene,
+ tag,
+ status,
+ length,
+ i;
+
+ image_list=(Image *)NULL;
+
+ /*
+ Read offset table
+ */
+ if (DCM_ReadOffsetTable(*image,dcm,exception) == MagickFail)
+ return MagickFail;
+
+ status=MagickPass;
+ for (scene=0; scene < dcm->number_scenes; scene++)
+ {
+ /*
+ Use temporary file to hold extracted data stream
+ */
+ file=AcquireTemporaryFileStream(filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ {
+ ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,filename);
+ return MagickFail;
+ }
+
+ status=MagickPass;
+ do
+ {
+ /*
+ Read fragment tag
+ */
+ tag=(dcm->funcReadShort(*image) << 16) | dcm->funcReadShort(*image);
+ length=dcm->funcReadLong(*image);
+ if (EOFBlob(*image))
+ {
+ status=MagickFail;
+ break;
+ }
+
+ if (tag == 0xFFFEE0DD)
+ {
+ /* Sequence delimiter tag */
+ break;
+ }
+ else
+ if (tag != 0xFFFEE000)
+ {
+ status=MagickFail;
+ break;
+ }
+
+ /*
+ Copy this fragment to the temporary file
+ */
+ while (length > 0)
+ {
+ c=ReadBlobByte(*image);
+ if (c == EOF)
+ {
+ status=MagickFail;
+ break;
+ }
+ (void) fputc(c,file);
+ length--;
+ }
+
+ if (dcm->offset_ct == 0)
+ {
+ /*
+ Assume one fragment per frame so break loop unless we are in the last frame
+ */
+ if (scene < dcm->number_scenes-1)
+ break;
+ }
+ else
+ {
+ /* Look for end of multi-fragment frames by checking for against offset table */
+ length=TellBlob(*image);
+ for (i=0; i < dcm->offset_ct; i++)
+ if (length == dcm->offset_arr[i])
+ {
+ break;
+ }
+ }
+ } while (status == MagickPass);
+
+ (void) fclose(file);
+ if (status == MagickPass)
+ {
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ if (dcm->transfer_syntax == DCM_TS_JPEG_2000)
+ FormatString(clone_info->filename,"jp2:%.1024s",filename);
+ else
+ FormatString(clone_info->filename,"jpeg:%.1024s",filename);
+ next_image=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ if (next_image == (Image*)NULL)
+ {
+ status=MagickFail;
+ }
+ else
+ if (dcm->rescaling == DCM_RS_POST)
+ {
+ /*
+ ### TODO: ???
+ We cannot guarantee integrity of input data since libjpeg may already have
+ downsampled 12- or 16-bit jpegs. Best guess at the moment is to recalculate
+ scaling using the image depth (unless avoid-scaling is in force)
+ */
+ /* Allow for libjpeg having changed depth of image */
+ dcm->significant_bits=next_image->depth;
+ dcm->bytes_per_pixel=1;
+ if (dcm->significant_bits > 8)
+ dcm->bytes_per_pixel=2;
+ dcm->max_value_in=(1 << dcm->significant_bits)-1;
+ dcm->max_value_out=dcm->max_value_in;
+ status=DCM_PostRescaleImage(next_image,dcm,True,exception);
+ }
+ if (status == MagickPass)
+ {
+ strcpy(next_image->filename,(*image)->filename);
+ next_image->scene=scene;
+ if (image_list == (Image*)NULL)
+ image_list=next_image;
+ else
+ AppendImageToList(&image_list,next_image);
+ }
+ }
+ (void) LiberateTemporaryFile(filename);
+ }
+ DestroyImage(*image);
+ *image=image_list;
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d D C M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadDCMImage reads a Digital Imaging and Communications in Medicine
+% (DICOM) file and returns it. It It allocates the memory necessary for the
+% new Image structure and returns a pointer to the new image.
+%
+% The format of the ReadDCMImage method is:
+%
+% Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadDCMImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ magick[MaxTextExtent];
+
+ Image
+ *image;
+
+ int
+ scene;
+
+ size_t
+ count;
+
+ unsigned long
+ status;
+
+ DicomStream
+ dcm;
+
+ /*
+ Open image file
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Read DCM preamble
+ */
+ if ((count=ReadBlob(image,128,(char *) magick)) != 128)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if ((count=ReadBlob(image,4,(char *) magick)) != 4)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "magick: \"%.4s\"",magick);
+ if (LocaleNCompare((char *) magick,"DICM",4) != 0)
+ (void) SeekBlob(image,0L,SEEK_SET);
+
+ /*
+ Loop to read DCM image header one element at a time
+ */
+ (void) DCM_InitDCM(&dcm,image_info->verbose);
+ status=DCM_ReadElement(image,&dcm,exception);
+ while ((status == MagickPass) && ((dcm.group != 0x7FE0) || (dcm.element != 0x0010)))
+ {
+ DicomElemParseFunc
+ *pfunc;
+
+ pfunc=dicom_info[dcm.index].pfunc;
+ if (pfunc != (DicomElemParseFunc *)NULL)
+ status=pfunc(image,&dcm,exception);
+ MagickFreeMemory(dcm.data);
+ dcm.data = NULL;
+ if (status == MagickPass)
+ status=DCM_ReadElement(image,&dcm,exception);
+ }
+#if defined(IGNORE_WINDOW_FOR_UNSPECIFIED_SCALE_TYPE)
+ if (dcm.rescale_type == DCM_RT_UNSPECIFIED)
+ {
+ dcm.window_width=0;
+ dcm.rescale_slope=1;
+ dcm.rescale_intercept=0;
+ }
+#endif
+ DCM_SetRescaling(&dcm,(AccessDefinition(image_info,"dcm","avoid-scaling") != NULL));
+ /*
+ Now process the image data
+ */
+ if (status == MagickFail)
+ ;
+ else
+ if ((dcm.columns == 0) || (dcm.rows == 0))
+ {
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+ status=MagickFail;
+ }
+ else if ((dcm.transfer_syntax != DCM_TS_IMPL_LITTLE) &&
+ (dcm.transfer_syntax != DCM_TS_EXPL_LITTLE) &&
+ (dcm.transfer_syntax != DCM_TS_EXPL_BIG) &&
+ (dcm.transfer_syntax != DCM_TS_RLE))
+ {
+ status=DCM_ReadNonNativeImages(&image,image_info,&dcm,exception);
+ dcm.number_scenes=0;
+ }
+ else if (dcm.rescaling != DCM_RS_POST)
+ {
+ status=DCM_SetupRescaleMap(image,&dcm,exception);
+ }
+
+ if (dcm.transfer_syntax == DCM_TS_RLE)
+ status=DCM_ReadOffsetTable(image,&dcm,exception);
+
+ /* Loop to process all scenes in image */
+ if (status == MagickFail) dcm.number_scenes = 0;
+ for (scene=0; scene < (long) dcm.number_scenes; scene++)
+ {
+ if (dcm.transfer_syntax == DCM_TS_RLE)
+ {
+ magick_uint32_t
+ tag,
+ length;
+
+ /*
+ Discard any remaining bytes from last fragment
+ */
+ if (dcm.frag_bytes)
+ SeekBlob(image,dcm.frag_bytes,SEEK_CUR);
+
+ /*
+ Read fragment tag
+ */
+ tag=(dcm.funcReadShort(image) << 16) | dcm.funcReadShort(image);
+ length=dcm.funcReadLong(image);
+ if ((tag != 0xFFFEE000) || (length <= 64) || EOFBlob(image))
+ {
+ status=MagickFail;
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ break;
+ }
+
+ /*
+ Set up decompression state
+ */
+ dcm.frag_bytes=length;
+ dcm.rle_rep_ct=0;
+
+ /*
+ Read RLE segment table
+ */
+ dcm.rle_seg_ct=dcm.funcReadLong(image);
+ for (length=0; length < 15; length++)
+ dcm.rle_seg_offsets[length]=dcm.funcReadLong(image);
+ dcm.frag_bytes-=64;
+ if (EOFBlob(image))
+ {
+ status=MagickFail;
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ break;
+ }
+ if (dcm.rle_seg_ct > 1)
+ {
+ fprintf(stdout,"Multiple RLE segments in frame are not supported\n");
+ status=MagickFail;
+ break;
+ }
+ }
+
+ /*
+ Initialize image structure.
+ */
+ image->columns=dcm.columns;
+ image->rows=dcm.rows;
+ image->interlace=(dcm.interlace==1)?PlaneInterlace:NoInterlace;
+#if defined(GRAYSCALE_USES_PALETTE)
+ if ((image->colormap == (PixelPacket *) NULL) && (dcm.samples_per_pixel == 1))
+#else
+ if ((image->colormap == (PixelPacket *) NULL) && (dcm.phot_interp == DCM_PI_PALETTE_COLOR))
+#endif
+ {
+ status=DCM_SetupColormap(image,&dcm,exception);
+ if (status == MagickFail)
+ break;
+ }
+ if (image_info->ping)
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Process image according to type
+ */
+ if (dcm.samples_per_pixel == 1)
+ {
+ if (dcm.phot_interp == DCM_PI_PALETTE_COLOR)
+ status=DCM_ReadPaletteImage(image,&dcm,exception);
+ else
+ status=DCM_ReadGrayscaleImage(image,&dcm,exception);
+ }
+ else
+ {
+ if (image->interlace == PlaneInterlace)
+ status=DCM_ReadPlanarRGBImage(image,&dcm,exception);
+ else
+ status=DCM_ReadRGBImage(image,&dcm,exception);
+ }
+ if (status != MagickPass)
+ break;
+
+ if ((dcm.rescaling == DCM_RS_PRE) &&
+ ((dcm.phot_interp == DCM_PI_MONOCHROME1) ||
+ (dcm.phot_interp == DCM_PI_MONOCHROME2)))
+ {
+ NormalizeImage(image);
+ }
+ else
+ if (dcm.rescaling == DCM_RS_POST)
+ {
+ status = DCM_PostRescaleImage(image,&dcm,False,exception);
+ if (status != MagickPass)
+ break;
+ }
+
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (scene < (long) (dcm.number_scenes-1))
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename);
+ if (status == MagickFail)
+ break;
+ }
+ }
+
+ /*
+ Free allocated resources
+ */
+
+ if (dcm.offset_arr != NULL)
+ MagickFreeMemory(dcm.offset_arr);
+ if (dcm.data != NULL)
+ MagickFreeMemory(dcm.data);
+#if defined(USE_GRAYMAP)
+ if (dcm.graymap != (unsigned short *) NULL)
+ MagickFreeMemory(dcm.graymap);
+#endif
+ if (dcm.rescale_map != (Quantum *) NULL)
+ MagickFreeMemory(dcm.rescale_map);
+ if (status == MagickPass)
+ {
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+ }
+ else
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r D C M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterDCMImage adds attributes for the DCM image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterDCMImage method is:
+%
+% RegisterDCMImage(void)
+%
+*/
+ModuleExport void RegisterDCMImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("DCM");
+ entry->decoder=(DecoderHandler) ReadDCMImage;
+ entry->magick=(MagickHandler) IsDCM;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Digital Imaging and Communications in Medicine image";
+ entry->note="See http://medical.nema.org/ for information on DICOM.";
+ entry->module="DCM";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r D C M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterDCMImage removes format registrations made by the
+% DCM module from the list of supported formats.
+%
+% The format of the UnregisterDCMImage method is:
+%
+% UnregisterDCMImage(void)
+%
+*/
+ModuleExport void UnregisterDCMImage(void)
+{
+ (void) UnregisterMagickInfo("DCM");
+}
+/*
+ ### TODO :
+ #1 Fixes on palette support:
+ - Handle palette images where # of entries > MaxColormapSize - create image
+ as Direct class, store the original palette (scaled to MaxRGB) and then map
+ input values via modified palette to output RGB values.
+ - Honour palette/LUT descriptors (ie values <= min value map to first
+ entry, value = (min_value + 1) maps to second entry, and so on, whilst
+ values >= (min value + palette/LUT size) map to last entry.
+ #2 Use ImportImagePixelArea?
+ #3 Handling of encapsulated JPEGs which downsample to 8 bit via
+ libjpeg. These lose accuracy before we can rescale to handle the
+ issues of PR=1 + window center/width + rescale slope/intercept on
+ MONOCHROME1 or 2. Worst case : CT-MONO2-16-chest. Currently images
+ are post-rescaled based on sample range. For PseudoClass grayscales
+ this is done by colormap manipulation only.
+ #4 JPEG/JPEG-LS/JPEG 2000: Check that multi frame handling in DCM_ReadEncapImages
+ is ok
+ #5 Support LUTs?
+ #6 Pixel Padding value/range - make transparent or allow use to specify a color?
+*/
diff --git a/coders/dcraw.c b/coders/dcraw.c
new file mode 100644
index 0000000..30c3dde
--- /dev/null
+++ b/coders/dcraw.c
@@ -0,0 +1,192 @@
+/*
+% Copyright (C) 2008 - 2012 GraphicsMagick Group
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD CCCC RRRR AAA W W %
+% D D C R R A A W W %
+% D D C RRRR AAAAA W W %
+% D D C R R A A W W W %
+% DDDD CCCC R R A A W W %
+% %
+% %
+% Read DCRAW Image Formats %
+% %
+% Bob Friesenhahn %
+% July, 2008 %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d D C R A W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadDCRAWImage reads a raw digital camera image using the dcraw
+% delegate definition. This is just a simple proxy to redirect requests
+% for camera raw formats to use dcraw.
+%
+% The format of the ReadDCRAWImage method is:
+%
+% Image *ReadDCRAWImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadDCRAWImage returns a pointer to the image after
+% creating it. A null image is returned if there is a memory shortage
+% or if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadDCRAWImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ clone_info=CloneImageInfo(image_info);
+ if (clone_info == (ImageInfo *) NULL)
+ return NULL;
+
+ (void) strlcpy(clone_info->filename,"DCRAW:",MaxTextExtent);
+ (void) strlcat(clone_info->filename,image_info->filename,MaxTextExtent);
+ (void) strlcpy(clone_info->magick,"DCRAW",MaxTextExtent);
+
+ image=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r D C R A W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterDCRAWImage adds attributes for formats supported by 'dcraw'
+% to the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% See http://en.wikipedia.org/wiki/RAW_image_format for a description of
+% RAW camera formats.
+%
+% The format of the RegisterDCRAWImage method is:
+%
+% RegisterDCRAWImage(void)
+%
+*/
+static const struct
+{
+ const char *id;
+ const char *description;
+} dcraw_formats[] =
+ {
+ { "3FR", "Hasselblad Photo RAW" }, /* Hasselblad CFV/H3D39II */
+ { "ARW", "Sony Alpha DSLR RAW" }, /* Sony DSLR-A100 */
+ { "CR2", "Canon Photo RAW" }, /* Canon EOS 400D, etc. */
+ { "CRW", "Canon Photo RAW" }, /* Canon EOS-10, etc. */
+ { "DCR", "Kodak Photo RAW" }, /* Kodak DSC Pro *, DSC 660C */
+ { "DNG", "Adobe Digital Negative" }, /* http://www.adobe.com/products/dng/ */
+ { "ERF", "Epson RAW Format" }, /* Epson RD1 */
+ { "K25", "Kodak Photo RAW" }, /* Kodak DC25 */
+ { "KDC", "Kodak Photo RAW" }, /* Kodak DC40/50/120, P850 */
+ { "MEF", "Mamiya Photo RAW"}, /* Mamiya camera */
+ { "MRW", "Minolta Photo RAW" }, /* Minolta DiMAGE*, Dynax *, Maxxum * */
+ { "NEF", "Nikon Electronic Format" }, /* Nikon D1, etc. */
+ { "ORF", "Olympus Photo RAW" }, /* Olympus C5050Z, etc. */
+ { "PEF", "Pentax Electronic File" }, /* Pentax istDS, etc. */
+ { "RAF", "Fuji Photo RAW" }, /* Fuji FinePix * */
+ { "SR2", "Sony Photo RAW" }, /* Sony R1 */
+ { "SRF", "Sony Photo RAW" }, /* Sony DSC-F828, Sony DSC-R1 */
+ { "X3F", "Foveon X3 (Sigma/Polaroid) RAW" }, /* Sigma SD9/SD10/SD14 / Polaroid X530 */
+ { NULL, NULL }
+ };
+ModuleExport void RegisterDCRAWImage(void)
+{
+ unsigned int
+ i;
+
+ MagickInfo
+ *entry;
+
+ for (i=0; dcraw_formats[i].id != NULL; i++)
+ {
+ entry=SetMagickInfo(dcraw_formats[i].id);
+ entry->decoder=(DecoderHandler) ReadDCRAWImage;
+ entry->description=dcraw_formats[i].description;
+ entry->extension_treatment=ObeyExtensionTreatment;
+ entry->module="DCRAW";
+ (void) RegisterMagickInfo(entry);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r N U L L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterDCRAWImage removes format registrations made by the
+% DCRAW module from the list of supported formats.
+%
+% The format of the UnregisterDCRAWImage method is:
+%
+% UnregisterDCRAWImage(void)
+%
+*/
+ModuleExport void UnregisterDCRAWImage(void)
+{
+ unsigned int
+ i;
+
+ for (i=0; dcraw_formats[i].id != NULL; i++)
+ (void) UnregisterMagickInfo(dcraw_formats[i].id);
+}
diff --git a/coders/dib.c b/coders/dib.c
new file mode 100644
index 0000000..55befac
--- /dev/null
+++ b/coders/dib.c
@@ -0,0 +1,1427 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD IIIII BBBB %
+% D D I B B %
+% D D I BBBB %
+% D D I B B %
+% DDDD IIIII BBBB %
+% %
+% %
+% Read/Write Windows DIB Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/render.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+ Typedef declarations.
+*/
+typedef struct _DIBInfo
+{
+ magick_uint32_t
+ header_size;
+
+ magick_int32_t
+ width,
+ height;
+
+ magick_uint16_t
+ planes,
+ bits_per_pixel;
+
+ magick_uint32_t
+ compression, /* 0=uncompressed, 1=8bit RLE, 2=4bit RLE, 3=RGB masked */
+ image_size,
+ x_pixels,
+ y_pixels,
+ number_colors,
+ colors_important;
+
+ magick_uint16_t
+ red_mask,
+ green_mask,
+ blue_mask,
+ alpha_mask;
+
+ long
+ colorspace;
+
+ PointInfo
+ red_primary,
+ green_primary,
+ blue_primary,
+ gamma_scale;
+} DIBInfo;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteDIBImage(const ImageInfo *,Image *);
+
+static void LogDIBInfo(const DIBInfo *dib_info)
+{
+ /*
+ Dump 40-byte version 3+ bitmap header.
+ BMP version 4 has same members, but is 108 bytes.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "DIB Header:\n"
+ " Header Size: %u\n"
+ " Width: %d\n"
+ " Height: %d\n"
+ " Planes: %u\n"
+ " Bits Per Pixel: %u\n"
+ " Compression: %u\n"
+ " Size Of Bitmap: %u\n"
+ " Horzontal Resolution: %u\n"
+ " Vertical Resolution: %u\n"
+ " Colors Used: %u\n"
+ " Colors Important: %u",
+ (unsigned int) dib_info->header_size,
+ (signed int) dib_info->width,
+ (signed int) dib_info->height,
+ (unsigned int) dib_info->planes,
+ (unsigned int) dib_info->bits_per_pixel,
+ (unsigned int) dib_info->compression,
+ (unsigned int) dib_info->image_size,
+ (unsigned int) dib_info->x_pixels,
+ (unsigned int) dib_info->y_pixels,
+ (unsigned int) dib_info->number_colors,
+ (unsigned int) dib_info->colors_important
+ );
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DecodeImage unpacks the packed image pixels into runlength-encoded
+% pixel packets.
+%
+% The format of the DecodeImage method is:
+%
+% unsigned int DecodeImage(Image *image,const unsigned long compression,
+% unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method DecodeImage returns True if all the pixels are
+% uncompressed without error, otherwise False.
+%
+% o image: The address of a structure of type Image.
+%
+% o compression: A value of 1 means the compressed pixels are runlength
+% encoded for a 256-color bitmap. A value of 2 means a 16-color bitmap.
+%
+% o pixels: The address of a byte (8 bits) array of pixel data created by
+% the decoding process.
+%
+%
+*/
+static unsigned int DecodeImage(Image *image,const unsigned long compression,
+ unsigned char *pixels)
+{
+ long
+ byte,
+ count,
+ y;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *end;
+
+ assert(image != (Image *) NULL);
+ assert(pixels != (unsigned char *) NULL);
+ (void) memset(pixels,0,image->columns*image->rows);
+ byte=0;
+ x=0;
+ q=pixels;
+ end=pixels + (size_t) image->columns*image->rows;
+ for (y=0; y < (long) image->rows; )
+ {
+ if (q < pixels || q >= end)
+ break;
+ count=ReadBlobByte(image);
+ if (count == EOF)
+ break;
+ if (count != 0)
+ {
+ count=Min(count, end - q);
+ /*
+ Encoded mode.
+ */
+ byte=ReadBlobByte(image);
+ for (i=0; i < count; i++)
+ {
+ if (compression == 1)
+ *q++=(unsigned char) byte;
+ else
+ *q++=(unsigned char)
+ ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
+ x++;
+ }
+ }
+ else
+ {
+ /*
+ Escape mode.
+ */
+ count=ReadBlobByte(image);
+ if (count == 0x01)
+ return(True);
+ switch ((int) count)
+ {
+ case 0x00:
+ {
+ /*
+ End of line.
+ */
+ x=0;
+ y++;
+ q=pixels+y*image->columns;
+ break;
+ }
+ case 0x02:
+ {
+ /*
+ Delta mode.
+ */
+ x+=ReadBlobByte(image);
+ y+=ReadBlobByte(image);
+ q=pixels+y*image->columns+x;
+ break;
+ }
+ default:
+ {
+ /*
+ Absolute mode.
+ */
+ count=Min(count, end - q);
+ for (i=0; i < count; i++)
+ {
+ if (compression == 1)
+ *q++=ReadBlobByte(image);
+ else
+ {
+ if ((i & 0x01) == 0)
+ byte=ReadBlobByte(image);
+ *q++=(unsigned char)
+ ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
+ }
+ x++;
+ }
+ /*
+ Read pad byte.
+ */
+ if (compression == 1)
+ {
+ if (count & 0x01)
+ (void) ReadBlobByte(image);
+ }
+ else
+ if (((count & 0x03) == 1) || ((count & 0x03) == 2))
+ (void) ReadBlobByte(image);
+ break;
+ }
+ }
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) ReadBlobByte(image); /* end of line */
+ (void) ReadBlobByte(image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method EncodeImage compresses pixels using a runlength encoded format.
+%
+% The format of the EncodeImage method is:
+%
+% static unsigned int EncodeImage(Image *image,
+% const unsigned long bytes_per_line,const unsigned char *pixels,
+% unsigned char *compressed_pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method EncodeImage returns the number of bytes in the
+% runlength encoded compress_pixels array.
+%
+% o image: A pointer to an Image structure.
+%
+% o bytes_per_line: The number of bytes in a scanline of compressed pixels
+%
+% o pixels: The address of a byte (8 bits) array of pixel data created by
+% the compression process.
+%
+% o compressed_pixels: The address of a byte (8 bits) array of compressed
+% pixel data.
+%
+%
+*/
+static size_t EncodeImage(Image *image,const unsigned long bytes_per_line,
+ const unsigned char *pixels,unsigned char *compressed_pixels)
+{
+ long
+ y;
+
+ register const unsigned char
+ *p;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ /*
+ Runlength encode pixels.
+ */
+ assert(image != (Image *) NULL);
+ assert(pixels != (const unsigned char *) NULL);
+ assert(compressed_pixels != (unsigned char *) NULL);
+ p=pixels;
+ q=compressed_pixels;
+ i=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ for (x=0; x < (long) bytes_per_line; x+=i)
+ {
+ /*
+ Determine runlength.
+ */
+ for (i=1; ((x+i) < (long) bytes_per_line); i++)
+ if ((*(p+i) != *p) || (i == 255U))
+ break;
+ *q++=(unsigned char) i;
+ *q++=(*p);
+ p+=i;
+ }
+ /*
+ End of line.
+ */
+ *q++=0x00;
+ *q++=0x00;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ /*
+ End of bitmap.
+ */
+ *q++=0;
+ *q++=0x01;
+ return(q-compressed_pixels);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s D I B %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsDIB returns True if the image format type, identified by the
+% magick string, is DIB.
+%
+% The format of the IsDIB method is:
+%
+% unsigned int IsDIB(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsDIB returns True if the image format type is DIB.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsDIB(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if( (*magick == 40) && (*(magick+1)==0))
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d D I B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadDIBImage reads a Microsoft Windows bitmap image file and
+% returns it. It allocates the memory necessary for the new Image structure
+% and returns a pointer to the new image.
+%
+% The format of the ReadDIBImage method is:
+%
+% image=ReadDIBImage(image_info)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadDIBImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadDIBImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ DIBInfo
+ dib_info;
+
+ Image
+ *image;
+
+ IndexPacket
+ index;
+
+ long
+ bit,
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ size_t
+ count,
+ length;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ status;
+
+ size_t
+ bytes_per_line;
+
+ magick_off_t
+ file_size;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ file_size=GetBlobSize(image);
+ /*
+ Determine if this is a DIB file.
+ */
+ (void) memset(&dib_info,0,sizeof(DIBInfo));
+ dib_info.header_size=ReadBlobLSBLong(image);
+ if (dib_info.header_size!=40)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Microsoft Windows 3.X DIB image file.
+ */
+
+ /*
+ BMP v3 defines width and hight as signed LONG (32 bit) values. If
+ height is a positive number, then the image is a "bottom-up"
+ bitmap with origin in the lower-left corner. If height is a
+ negative number, then the image is a "top-down" bitmap with the
+ origin in the upper-left corner. The meaning of negative values
+ is not defined for width.
+ */
+ dib_info.width=ReadBlobLSBSignedLong(image);
+ dib_info.height=ReadBlobLSBSignedLong(image);
+ dib_info.planes=ReadBlobLSBShort(image);
+ dib_info.bits_per_pixel=ReadBlobLSBShort(image);
+ dib_info.compression=ReadBlobLSBLong(image);
+ dib_info.image_size=ReadBlobLSBLong(image);
+ dib_info.x_pixels=ReadBlobLSBLong(image);
+ dib_info.y_pixels=ReadBlobLSBLong(image);
+ dib_info.number_colors=ReadBlobLSBLong(image);
+ dib_info.colors_important=ReadBlobLSBLong(image);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ LogDIBInfo(&dib_info);
+ if (dib_info.planes != 1)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if ((dib_info.bits_per_pixel != 1) &&
+ (dib_info.bits_per_pixel != 4) &&
+ (dib_info.bits_per_pixel != 8) &&
+ (dib_info.bits_per_pixel != 16) &&
+ (dib_info.bits_per_pixel != 24) &&
+ (dib_info.bits_per_pixel != 32))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if ((dib_info.compression == 3) && ((dib_info.bits_per_pixel == 16) ||
+ (dib_info.bits_per_pixel == 32)))
+ {
+ dib_info.red_mask=ReadBlobLSBShort(image);
+ dib_info.green_mask=ReadBlobLSBShort(image);
+ dib_info.blue_mask=ReadBlobLSBShort(image);
+ }
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (dib_info.width <= 0)
+ ThrowReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+ if (dib_info.height == 0)
+ ThrowReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+ image->matte=dib_info.bits_per_pixel == 32;
+ image->columns=AbsoluteValue(dib_info.width);
+ image->rows=AbsoluteValue(dib_info.height);
+ image->depth=8;
+ if (dib_info.number_colors > 256)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (dib_info.colors_important > 256)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if ((dib_info.image_size != 0U) && (dib_info.image_size > file_size))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if ((dib_info.number_colors != 0) || (dib_info.bits_per_pixel < 16))
+ {
+ image->storage_class=PseudoClass;
+ image->colors=dib_info.number_colors;
+ if (image->colors == 0)
+ image->colors=1L << dib_info.bits_per_pixel;
+ }
+ if (image_info->size)
+ {
+ int
+ flags;
+
+ RectangleInfo
+ geometry;
+
+ flags=GetGeometry(image_info->size,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ if ((flags & WidthValue) && (geometry.width != 0)
+ && (geometry.width < image->columns))
+ image->columns=geometry.width;
+ if ((flags & HeightValue) && (geometry.height != 0)
+ && (geometry.height < image->rows))
+ image->rows=geometry.height;
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ if (image->storage_class == PseudoClass)
+ {
+ unsigned char
+ *dib_colormap;
+
+ unsigned int
+ packet_size;
+
+ /*
+ Read DIB raster colormap.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ dib_colormap=MagickAllocateArray(unsigned char *,image->colors,4);
+ if (dib_colormap == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ packet_size=4;
+ if ((count=ReadBlob(image,packet_size*image->colors,(char *) dib_colormap))
+ != packet_size*image->colors)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Read %" MAGICK_SIZE_T_F "u bytes from blob"
+ " (expected %" MAGICK_SIZE_T_F "u bytes)",
+ (MAGICK_SIZE_T) count,
+ (MAGICK_SIZE_T) packet_size*image->colors);
+ MagickFreeMemory(dib_colormap);
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ p=dib_colormap;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ if (packet_size == 4)
+ p++;
+ }
+ MagickFreeMemory(dib_colormap);
+ }
+ /*
+ Read image data.
+ */
+ if (dib_info.compression == 2)
+ dib_info.bits_per_pixel<<=1;
+
+ /*
+ Below emulates:
+ bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
+ */
+ bytes_per_line=MagickArraySize(image->columns,dib_info.bits_per_pixel);
+ if (bytes_per_line)
+ bytes_per_line += 31;
+ bytes_per_line /= 32;
+ bytes_per_line=MagickArraySize(4,bytes_per_line);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%" MAGICK_SIZE_T_F "u bytes per line",
+ (MAGICK_SIZE_T) bytes_per_line);
+ /*
+ Validate that file data size is suitable for claimed dimensions.
+ */
+ {
+ size_t
+ maximum_image_size;
+
+ maximum_image_size=MagickArraySize(bytes_per_line,image->rows);
+ if ((maximum_image_size == 0) ||
+ (maximum_image_size >
+ ((size_t) file_size * ((dib_info.compression == 1 ? 256 :
+ dib_info.compression == 2 ? 8 : 1)))))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+
+ /*
+ FIXME: Need to add support for compression=3 images. Size
+ calculations are wrong and there is no support for applying the
+ masks.
+ */
+ length=MagickArraySize(bytes_per_line,image->rows);
+ if (length == 0)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ pixels=MagickAllocateArray(unsigned char *,
+ image->rows,
+ Max(bytes_per_line,image->columns+1));
+ if (pixels == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if ((dib_info.compression == 0) || (dib_info.compression == 3))
+ {
+ if ((count=ReadBlob(image,length,(char *) pixels)) != length)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Read %" MAGICK_SIZE_T_F "u bytes from blob"
+ " (expected %" MAGICK_SIZE_T_F "u bytes)",
+ (MAGICK_SIZE_T) count,
+ (MAGICK_SIZE_T) length);
+ MagickFreeMemory(pixels);
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ }
+ else
+ {
+ /*
+ Convert run-length encoded raster pixels.
+ DecodeImage expects that pixels array is rows*columns bytes.
+ */
+ status=DecodeImage(image,dib_info.compression,pixels);
+ if (status == False)
+ {
+ MagickFreeMemory(pixels);
+ ThrowReaderException(CorruptImageError,UnableToRunlengthDecodeImage,
+ image);
+ }
+ }
+ /*
+ Initialize image structure.
+ */
+ image->units=PixelsPerCentimeterResolution;
+ image->x_resolution=dib_info.x_pixels/100.0;
+ image->y_resolution=dib_info.y_pixels/100.0;
+ /*
+ Convert DIB raster image to pixel packets.
+ */
+ switch (dib_info.bits_per_pixel)
+ {
+ case 1:
+ {
+ /*
+ Convert bitmap scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < ((long) image->columns-7); x+=8)
+ {
+ for (bit=0; bit < 8; bit++)
+ {
+ index=((*p) & (0x80 >> bit) ? 0x01 : 0x00);
+ VerifyColormapIndex(image,index);
+ indexes[x+bit]=index;
+ *q++=image->colormap[index];
+ }
+ p++;
+ }
+ if ((image->columns % 8) != 0)
+ {
+ for (bit=0; bit < (long) (image->columns % 8); bit++)
+ {
+ index=((*p) & (0x80 >> bit) ? 0x01 : 0x00);
+ VerifyColormapIndex(image,index);
+ indexes[x+bit]=index;
+ *q++=image->colormap[index];
+ }
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+ /*
+ Convert PseudoColor scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < ((long) image->columns-1); x+=2)
+ {
+ index=(IndexPacket) ((*p >> 4) & 0xf);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) (*p & 0xf);
+ VerifyColormapIndex(image,index);
+ indexes[x+1]=index;
+ *q++=image->colormap[index];
+ p++;
+ }
+ if ((image->columns % 2) != 0)
+ {
+ index=(IndexPacket) ((*p >> 4) & 0xf);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 8:
+ {
+ /*
+ Convert PseudoColor scanline.
+ */
+ if ((dib_info.compression == 1) || (dib_info.compression == 2))
+ bytes_per_line=image->columns;
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=(IndexPacket) (*p);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q=image->colormap[index];
+ p++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ unsigned short
+ word;
+
+ /*
+ Convert PseudoColor scanline.
+ */
+ image->storage_class=DirectClass;
+ if (dib_info.compression == 1)
+ bytes_per_line=2*image->columns;
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ word=(*p++);
+ word|=(*p++ << 8);
+ if (dib_info.red_mask == 0)
+ {
+ q->red=ScaleCharToQuantum(ScaleColor5to8((word >> 10) & 0x1f));
+ q->green=ScaleCharToQuantum(ScaleColor5to8((word >> 5) & 0x1f));
+ q->blue=ScaleCharToQuantum(ScaleColor5to8(word & 0x1f));
+ }
+ else
+ {
+ q->red=ScaleCharToQuantum(ScaleColor5to8((word >> 11) & 0x1f));
+ q->green=ScaleCharToQuantum(ScaleColor6to8((word >> 5) & 0x3f));
+ q->blue=ScaleCharToQuantum(ScaleColor5to8(word & 0x1f));
+ }
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 24:
+ case 32:
+ {
+ /*
+ Convert DirectColor scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=pixels+(image->rows-y-1)*bytes_per_line;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->blue=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->red=ScaleCharToQuantum(*p++);
+ if (image->matte)
+ q->opacity=ScaleCharToQuantum(*p++);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ MagickFreeMemory(pixels);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+ MagickFreeMemory(pixels);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ if (strcmp(image_info->magick,"ICODIB") == 0)
+ {
+ /*
+ Handle ICO mask.
+ */
+ char
+ byte;
+
+ image->storage_class=DirectClass;
+ image->matte=True;
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < ((long) image->columns-7); x+=8)
+ {
+ byte=0;
+ (void) ReadBlob(image,sizeof(byte),&byte);
+ for (bit=0; bit < 8; bit++)
+ q[x+bit].opacity=(Quantum)
+ (byte & (0x80 >> bit) ? TransparentOpacity : OpaqueOpacity);
+ }
+ if ((image->columns % 8) != 0)
+ {
+ byte=0;
+ (void) ReadBlob(image,sizeof(byte),&byte);
+ for (bit=0; bit < (long) (image->columns % 8); bit++)
+ q[x+bit].opacity=(Quantum)
+ (byte & (0x80 >> bit) ? TransparentOpacity : OpaqueOpacity);
+ }
+ if (image->columns % 32)
+ for (x=0; x < (long) ((32-(image->columns % 32))/8); x++)
+ {
+ byte=0;
+ (void) ReadBlob(image,sizeof(byte),&byte);
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(image->rows-y-1,image->rows,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ }
+ if (dib_info.height < 0)
+ {
+ Image
+ *flipped_image;
+
+ /*
+ Correct image orientation.
+ */
+ flipped_image=FlipImage(image,exception);
+ if (flipped_image == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ DestroyBlob(flipped_image);
+ flipped_image->blob=ReferenceBlob(image->blob);
+ DestroyImage(image);
+ image=flipped_image;
+ }
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r D I B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterDIBImage adds attributes for the DIB image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterDIBImage method is:
+%
+% RegisterDIBImage(void)
+%
+*/
+ModuleExport void RegisterDIBImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("DIB");
+ entry->decoder=(DecoderHandler) ReadDIBImage;
+ entry->encoder=(EncoderHandler) WriteDIBImage;
+ entry->magick=(MagickHandler) IsDIB;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Microsoft Windows 3.X Packed Device-Independent Bitmap";
+ entry->module="DIB";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("ICODIB");
+ entry->decoder=(DecoderHandler) ReadDIBImage;
+ /* entry->encoder=(EncoderHandler) WriteDIBImage; */
+ entry->magick=(MagickHandler) IsDIB;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->raw=True; /* Requires size to work correctly. */
+ entry->description="Microsoft Windows 3.X Packed Device-Independent Bitmap + Mask";
+ entry->module="DIB";
+ (void) RegisterMagickInfo(entry);
+
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r D I B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterDIBImage removes format registrations made by the
+% DIB module from the list of supported formats.
+%
+% The format of the UnregisterDIBImage method is:
+%
+% UnregisterDIBImage(void)
+%
+*/
+ModuleExport void UnregisterDIBImage(void)
+{
+ (void) UnregisterMagickInfo("ICODIB");
+ (void) UnregisterMagickInfo("DIB");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e D I B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteDIBImage writes an image in Microsoft Windows bitmap encoded
+% image format.
+%
+% The format of the WriteDIBImage method is:
+%
+% unsigned int WriteDIBImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteDIBImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteDIBImage(const ImageInfo *image_info,Image *image)
+{
+ DIBInfo
+ dib_info;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *dib_data,
+ *pixels;
+
+ unsigned int
+ status;
+
+ unsigned long
+ bytes_per_line;
+
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Ensure that image is in an RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+ /*
+ Initialize DIB raster file header.
+ */
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Full color DIB raster.
+ */
+ dib_info.number_colors=0;
+ dib_info.bits_per_pixel=image->matte ? 32 : 24;
+ }
+ else
+ {
+ /*
+ Colormapped DIB raster.
+ */
+ dib_info.bits_per_pixel=8;
+ if (characteristics.monochrome)
+ dib_info.bits_per_pixel=1;
+ dib_info.number_colors=1 << dib_info.bits_per_pixel;
+ }
+ bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
+ dib_info.header_size=40;
+ dib_info.width=(long) image->columns;
+ dib_info.height=(long) image->rows;
+ dib_info.planes=1;
+ dib_info.compression=0;
+ dib_info.image_size=bytes_per_line*image->rows;
+ dib_info.x_pixels=75*39;
+ dib_info.y_pixels=75*39;
+ if (image->units == PixelsPerInchResolution)
+ {
+ dib_info.x_pixels=(unsigned long) (100.0*image->x_resolution/2.54);
+ dib_info.y_pixels=(unsigned long) (100.0*image->y_resolution/2.54);
+ }
+ if (image->units == PixelsPerCentimeterResolution)
+ {
+ dib_info.x_pixels=(unsigned long) (100.0*image->x_resolution);
+ dib_info.y_pixels=(unsigned long) (100.0*image->y_resolution);
+ }
+ dib_info.colors_important=dib_info.number_colors;
+ /*
+ Convert MIFF to DIB raster pixels.
+ */
+ pixels=MagickAllocateMemory(unsigned char *,dib_info.image_size);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ switch (dib_info.bits_per_pixel)
+ {
+ case 1:
+ {
+ register unsigned char
+ bit,
+ byte;
+
+ /*
+ Convert PseudoClass image to a DIB monochrome image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ q=pixels+(image->rows-y-1)*bytes_per_line;
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte<<=1;
+ byte|=indexes[x] ? 0x01 : 0x00;
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ p++;
+ }
+ if (bit != 0)
+ *q++=byte << (8-bit);
+ /* initialize padding bytes */
+ for (x=(long) (image->columns+7)/8; x < (long) bytes_per_line; x++)
+ *q++=0x00;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case 8:
+ {
+ /*
+ Convert PseudoClass packet to DIB pixel.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ q=pixels+(image->rows-y-1)*bytes_per_line;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=indexes[x];
+ p++;
+ }
+ /* initialize padding bytes */
+ for (; x < (long) bytes_per_line; x++)
+ *q++=0x00;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case 24:
+ case 32:
+ {
+ /*
+ Convert DirectClass packet to DIB RGB pixel.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels+(image->rows-y-1)*bytes_per_line;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(p->blue);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->red);
+ if (image->matte)
+ *q++=ScaleQuantumToChar(p->opacity);
+ p++;
+ }
+ /* initialize padding bytes */
+ if (dib_info.bits_per_pixel == 24)
+ {
+ /* initialize padding bytes */
+ for (x=3*image->columns; x < (long) bytes_per_line; x++)
+ *q++=0x00;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ }
+ if (dib_info.bits_per_pixel == 8)
+ if (image_info->compression != NoCompression)
+ {
+ size_t
+ length;
+
+ /*
+ Convert run-length encoded raster pixels.
+ */
+ length=2*(bytes_per_line+2)*(image->rows+2)+2;
+ dib_data=MagickAllocateMemory(unsigned char *,length);
+ if (dib_data == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(pixels);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image)
+ }
+ dib_info.image_size=(unsigned long)
+ EncodeImage(image,bytes_per_line,pixels,dib_data);
+ MagickFreeMemory(pixels);
+ pixels=dib_data;
+ dib_info.compression=1;
+ }
+ /*
+ Write DIB header.
+ */
+ (void) WriteBlobLSBLong(image,dib_info.header_size);
+ (void) WriteBlobLSBLong(image,dib_info.width);
+ (void) WriteBlobLSBLong(image,dib_info.height);
+ (void) WriteBlobLSBShort(image,dib_info.planes);
+ (void) WriteBlobLSBShort(image,dib_info.bits_per_pixel);
+ (void) WriteBlobLSBLong(image,dib_info.compression);
+ (void) WriteBlobLSBLong(image,dib_info.image_size);
+ (void) WriteBlobLSBLong(image,dib_info.x_pixels);
+ (void) WriteBlobLSBLong(image,dib_info.y_pixels);
+ (void) WriteBlobLSBLong(image,dib_info.number_colors);
+ (void) WriteBlobLSBLong(image,dib_info.colors_important);
+ if (image->storage_class == PseudoClass)
+ {
+ unsigned char
+ *dib_colormap;
+
+ /*
+ Dump colormap to file.
+ */
+ dib_colormap=MagickAllocateArray(unsigned char *,
+ (size_t) (1U << dib_info.bits_per_pixel),4);
+ if (dib_colormap == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(pixels);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ q=dib_colormap;
+ for (i=0; i < (long) Min(image->colors,dib_info.number_colors); i++)
+ {
+ *q++=ScaleQuantumToChar(image->colormap[i].blue);
+ *q++=ScaleQuantumToChar(image->colormap[i].green);
+ *q++=ScaleQuantumToChar(image->colormap[i].red);
+ *q++=(Quantum) 0x0;
+ }
+ for ( ; i < (1L << dib_info.bits_per_pixel); i++)
+ {
+ *q++=(Quantum) 0x0;
+ *q++=(Quantum) 0x0;
+ *q++=(Quantum) 0x0;
+ *q++=(Quantum) 0x0;
+ }
+ (void) WriteBlob(image,4*(1 << dib_info.bits_per_pixel),
+ (char *) dib_colormap);
+ MagickFreeMemory(dib_colormap);
+ }
+ (void) WriteBlob(image,dib_info.image_size,(char *) pixels);
+ MagickFreeMemory(pixels);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/dps.c b/coders/dps.c
new file mode 100644
index 0000000..6165f03
--- /dev/null
+++ b/coders/dps.c
@@ -0,0 +1,598 @@
+/*
+% Copyright (C) 2003, 2004 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD PPPP SSSSS %
+% D D P P SS %
+% D D PPPP SSS %
+% D D P SS %
+% DDDD P SSSSS %
+% %
+% %
+% Read Postscript Using the Display Postscript System. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+#include "magick/xwindow.h"
+#if defined(HasDPS)
+# include <DPS/dpsXclient.h>
+# include <DPS/dpsXpreview.h>
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d D P S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadDPSImage reads a Adobe Postscript image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadDPSImage method is:
+%
+% Image *ReadDPSImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadDPSImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadDPSImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ const char
+ *client_name;
+
+ Display
+ *display;
+
+ float
+ pixels_per_point;
+
+ Image
+ *image;
+
+ int
+ sans,
+ status;
+
+ long
+ x,
+ y;
+
+ Pixmap
+ pixmap;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i;
+
+ register PixelPacket
+ *q;
+
+ register unsigned long
+ pixel;
+
+ Screen
+ *screen;
+
+ XColor
+ *colors;
+
+ XImage
+ *dps_image;
+
+ XRectangle
+ page,
+ bits_per_pixel;
+
+ MagickXResourceInfo
+ resource_info;
+
+ XrmDatabase
+ resource_database;
+
+ XStandardColormap
+ *map_info;
+
+ XVisualInfo
+ *visual_info;
+
+ /*
+ Open X server connection.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ display=XOpenDisplay(image_info->server_name);
+ if (display == (Display *) NULL)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "failed to open X11 display!");
+ return((Image *) NULL);
+ }
+ /*
+ Set our forgiving error handler.
+ */
+ (void) XSetErrorHandler(MagickXError);
+ /*
+ Open image file.
+ */
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"failed to open blob!");
+ return((Image *) NULL);
+ }
+ /*
+ Get user defaults from X resource database.
+ */
+ client_name=GetClientName();
+ resource_database=MagickXGetResourceDatabase(display,client_name);
+ MagickXGetResourceInfo(resource_database,client_name,&resource_info);
+ /*
+ Allocate standard colormap.
+ */
+ map_info=XAllocStandardColormap();
+ visual_info=(XVisualInfo *) NULL;
+ if (map_info == (XStandardColormap *) NULL)
+ ThrowReaderException(XServerError,UnableToCreateStandardColormap,
+ image)
+ else
+ {
+ /*
+ Initialize visual info.
+ */
+ (void) CloneString(&resource_info.visual_type,"default");
+ visual_info=MagickXBestVisualInfo(display,map_info,&resource_info);
+ map_info->colormap=(Colormap) NULL;
+ }
+ if ((map_info == (XStandardColormap *) NULL) ||
+ (visual_info == (XVisualInfo *) NULL))
+ {
+ DestroyImage(image);
+ MagickXFreeResources(display,visual_info,map_info,(MagickXPixelInfo *) NULL,
+ (XFontStruct *) NULL,&resource_info,(MagickXWindowInfo *) NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "failed to initialize visual info!");
+ return((Image *) NULL);
+ }
+ /*
+ Create a pixmap the appropriate size for the image.
+ */
+ screen=ScreenOfDisplay(display,visual_info->screen);
+ pixels_per_point=XDPSPixelsPerPoint(screen);
+ if ((image->x_resolution != 0.0) && (image->y_resolution != 0.0))
+ pixels_per_point=Min(image->x_resolution,image->y_resolution)/72.0;
+ status=XDPSCreatePixmapForEPSF((DPSContext) NULL,screen,GetBlobFileHandle(image),
+ visual_info->depth,pixels_per_point,&pixmap,&bits_per_pixel,&page);
+ if ((status == dps_status_failure) || (status == dps_status_no_extension))
+ {
+ DestroyImage(image);
+ MagickXFreeResources(display,visual_info,map_info,(MagickXPixelInfo *) NULL,
+ (XFontStruct *) NULL,&resource_info,(MagickXWindowInfo *) NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "failed to create pixmap for image!");
+ return((Image *) NULL);
+ }
+ /*
+ Rasterize the file into the pixmap.
+ */
+ status=XDPSImageFileIntoDrawable((DPSContext) NULL,screen,pixmap,
+ GetBlobFileHandle(image),bits_per_pixel.height,visual_info->depth,&page,-page.x,
+ -page.y,pixels_per_point,True,False,True,&sans);
+ if (status != dps_status_success)
+ {
+ DestroyImage(image);
+ MagickXFreeResources(display,visual_info,map_info,(MagickXPixelInfo *) NULL,
+ (XFontStruct *) NULL,&resource_info,(MagickXWindowInfo *) NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "failed to rasterize EPS into pixmap!");
+ return((Image *) NULL);
+ }
+ /*
+ Initialize DPS X image.
+ */
+ dps_image=XGetImage(display,pixmap,0,0,bits_per_pixel.width,
+ bits_per_pixel.height,AllPlanes,ZPixmap);
+ (void) XFreePixmap(display,pixmap);
+ if (dps_image == (XImage *) NULL)
+ {
+ DestroyImage(image);
+ MagickXFreeResources(display,visual_info,map_info,(MagickXPixelInfo *) NULL,
+ (XFontStruct *) NULL,&resource_info,(MagickXWindowInfo *) NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "failed initialize DPS X image!");
+ return((Image *) NULL);
+ }
+ /*
+ Get the colormap colors.
+ */
+ colors=MagickAllocateMemory(XColor *,
+ visual_info->colormap_size*sizeof(XColor));
+ if (colors == (XColor *) NULL)
+ {
+ DestroyImage(image);
+ XDestroyImage(dps_image);
+ MagickXFreeResources(display,visual_info,map_info,(MagickXPixelInfo *) NULL,
+ (XFontStruct *) NULL,&resource_info,(MagickXWindowInfo *) NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "failed allocate memory for colormap!");
+ return((Image *) NULL);
+ }
+ if ((visual_info->class != DirectColor) &&
+ (visual_info->class != TrueColor))
+ for (i=0; i < visual_info->colormap_size; i++)
+ {
+ colors[i].pixel=i;
+ colors[i].pad=0;
+ }
+ else
+ {
+ unsigned long
+ blue,
+ blue_bit,
+ green,
+ green_bit,
+ red,
+ red_bit;
+
+ /*
+ DirectColor or TrueColor visual.
+ */
+ red=0;
+ green=0;
+ blue=0;
+ red_bit=visual_info->red_mask & (~(visual_info->red_mask)+1);
+ green_bit=visual_info->green_mask & (~(visual_info->green_mask)+1);
+ blue_bit=visual_info->blue_mask & (~(visual_info->blue_mask)+1);
+ for (i=0; i < visual_info->colormap_size; i++)
+ {
+ colors[i].pixel=red | green | blue;
+ colors[i].pad=0;
+ red+=red_bit;
+ if (red > visual_info->red_mask)
+ red=0;
+ green+=green_bit;
+ if (green > visual_info->green_mask)
+ green=0;
+ blue+=blue_bit;
+ if (blue > visual_info->blue_mask)
+ blue=0;
+ }
+ }
+ (void) XQueryColors(display,XDefaultColormap(display,visual_info->screen),
+ colors,visual_info->colormap_size);
+ /*
+ Convert X image to MIFF format.
+ */
+ if ((visual_info->class != TrueColor) &&
+ (visual_info->class != DirectColor))
+ image->storage_class=PseudoClass;
+ image->columns=dps_image->width;
+ image->rows=dps_image->height;
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ switch (image->storage_class)
+ {
+ case DirectClass:
+ default:
+ {
+ register unsigned long
+ color,
+ index_val;
+
+ unsigned long
+ blue_mask,
+ blue_shift,
+ green_mask,
+ green_shift,
+ red_mask,
+ red_shift;
+
+ /*
+ Determine shift and mask for red, green, and blue.
+ */
+ red_mask=visual_info->red_mask;
+ red_shift=0;
+ while ((red_mask & 0x01) == 0)
+ {
+ red_mask>>=1;
+ red_shift++;
+ }
+ green_mask=visual_info->green_mask;
+ green_shift=0;
+ while ((green_mask & 0x01) == 0)
+ {
+ green_mask>>=1;
+ green_shift++;
+ }
+ blue_mask=visual_info->blue_mask;
+ blue_shift=0;
+ while ((blue_mask & 0x01) == 0)
+ {
+ blue_mask>>=1;
+ blue_shift++;
+ }
+ /*
+ Convert X image to DirectClass packets.
+ */
+ if ((visual_info->colormap_size > 0) &&
+ (visual_info->class == DirectColor))
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=XGetPixel(dps_image,x,y);
+ index_val=(pixel >> red_shift) & red_mask;
+ q->red=ScaleShortToQuantum(colors[index_val].red);
+ index_val=(pixel >> green_shift) & green_mask;
+ q->green=ScaleShortToQuantum(colors[index_val].green);
+ index_val=(pixel >> blue_shift) & blue_mask;
+ q->blue=ScaleShortToQuantum(colors[index_val].blue);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ else
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=XGetPixel(dps_image,x,y);
+ color=(pixel >> red_shift) & red_mask;
+ q->red=ScaleShortToQuantum((color*65535L)/red_mask);
+ color=(pixel >> green_shift) & green_mask;
+ q->green=ScaleShortToQuantum((color*65535L)/green_mask);
+ color=(pixel >> blue_shift) & blue_mask;
+ q->blue=ScaleShortToQuantum((color*65535L)/blue_mask);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case PseudoClass:
+ {
+ /*
+ Create colormap.
+ */
+ if (!AllocateImageColormap(image,visual_info->colormap_size))
+ {
+ DestroyImage(image);
+ MagickFreeMemory(colors);
+ XDestroyImage(dps_image);
+ MagickXFreeResources(display,visual_info,map_info,(MagickXPixelInfo *) NULL,
+ (XFontStruct *) NULL,&resource_info,(MagickXWindowInfo *) NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "failed allocate image colormap!");
+ return((Image *) NULL);
+ }
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[colors[i].pixel].red=
+ ScaleShortToQuantum(colors[i].red);
+ image->colormap[colors[i].pixel].green=
+ ScaleShortToQuantum(colors[i].green);
+ image->colormap[colors[i].pixel].blue=
+ ScaleShortToQuantum(colors[i].blue);
+ }
+ /*
+ Convert X image to PseudoClass packets.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ indexes[x]=(unsigned short) XGetPixel(dps_image,x,y);
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ }
+ MagickFreeMemory(colors);
+ XDestroyImage(dps_image);
+ if (image->storage_class == PseudoClass)
+ (void) SyncImage(image);
+ /*
+ Rasterize matte image.
+ */
+ status=XDPSCreatePixmapForEPSF((DPSContext) NULL,screen,GetBlobFileHandle(image),1,
+ pixels_per_point,&pixmap,&bits_per_pixel,&page);
+ if ((status != dps_status_failure) && (status != dps_status_no_extension))
+ {
+ status=XDPSImageFileIntoDrawable((DPSContext) NULL,screen,pixmap,
+ GetBlobFileHandle(image),bits_per_pixel.height,1,&page,-page.x,
+ -page.y,pixels_per_point,True,True,True,&sans);
+ if (status == dps_status_success)
+ {
+ XImage
+ *matte_image;
+
+ /*
+ Initialize image matte.
+ */
+ matte_image=XGetImage(display,pixmap,0,0,bits_per_pixel.width,
+ bits_per_pixel.height,AllPlanes,ZPixmap);
+ (void) XFreePixmap(display,pixmap);
+ if (matte_image != (XImage *) NULL)
+ {
+ image->storage_class=DirectClass;
+ image->matte=True;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->opacity=OpaqueOpacity;
+ if (!XGetPixel(matte_image,x,y))
+ q->opacity=TransparentOpacity;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ XDestroyImage(matte_image);
+ }
+ }
+ }
+ /*
+ Free resources.
+ */
+ MagickXFreeResources(display,visual_info,map_info,(MagickXPixelInfo *) NULL,
+ (XFontStruct *) NULL,&resource_info,(MagickXWindowInfo *) NULL);
+ CloseBlob(image);
+ return(image);
+}
+#else
+static Image *ReadDPSImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ ThrowException(exception,MissingDelegateError,DPSLibraryIsNotAvailable,
+ image_info->filename);
+ return((Image *) NULL);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r D P S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterDPSImage adds attributes for the Display Postscript image
+% format to the list of supported formats. The attributes include the image
+% format tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterDPSImage method is:
+%
+% RegisterDPSImage(void)
+%
+*/
+ModuleExport void RegisterDPSImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("DPS");
+ entry->decoder=(DecoderHandler) ReadDPSImage;
+ entry->blob_support=False;
+ entry->description="Display Postscript Interpreter";
+ entry->module="DPS";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r D P S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterDPSImage removes format registrations made by the
+% DPS module from the list of supported formats.
+%
+% The format of the UnregisterDPSImage method is:
+%
+% UnregisterDPSImage(void)
+%
+*/
+ModuleExport void UnregisterDPSImage(void)
+{
+ (void) UnregisterMagickInfo("DPS");
+}
diff --git a/coders/dpx.c b/coders/dpx.c
new file mode 100644
index 0000000..a503a74
--- /dev/null
+++ b/coders/dpx.c
@@ -0,0 +1,4455 @@
+/*
+% Copyright (C) 2005-2015 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD PPPP X X %
+% D D P P X X %
+% D D PPPP XXX %
+% D D P X X %
+% DDDD P X X %
+% %
+% %
+% Read/Write SMTPE 268M-2003 DPX Image Format. %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% March 2005 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Supported features:
+%
+% Anything which can be read, can also be written.
+% All DPX header information is saved as image attributes and saved
+% when the image is written.
+%
+% Colorspaces:
+% RGB
+% Log RGB (density range = 2.048)
+% Grayscale (Luma)
+% YCbCr 4:4:4 and 4:2:2 (use -sampling-factor 2x1 for 4:2:2)
+%
+% Storage:
+% Bits per sample of 1, 8, 10, 12, and 16.
+% Packed, or fill type A or B for 10/12 bits.
+% All RGB-oriented element types (R, G, B, A, RGB, RGBA, ABGR).
+% All YCbCr-oriented element types.
+% Planar (multi-element) storage fully supported.
+% Alpha (key channel) may be stored in a separate element.
+%
+% Not currently supported:
+%
+% Colorspaces:
+% Composite Video
+%
+% Storage:
+% Bits per sample of 32 and 64 (floating point).
+% Depth.
+%
+% Notes about byte order:
+%
+% The DPX specification doesn't say anything about how endian byte
+% order should influence the image pixels. The 1994 version of the
+% specification suggests very strongly that *all* formats are
+% accessed as an array of 32-bit words (therefore implying 32-bit
+% swapping) but the 2003 specification has ammended this (ambiguously)
+% to imply the mixed use of 16 and 32 bit words. As we all know,
+% performing endian swapping on two 16-bit values does not have the
+% same effect as performing endian swapping on one 32-bit value (the
+% order of the two 16-bit samples is reversed) so the 2003 specification
+% is not compatible with the 1994 specification.
+%
+% Due to the lack of an unambiguous standard, GraphicsMagick is currently
+% using the following endian rules. These rules may change at any time:
+%
+% o 8 bit format is always written in ascending order so endian rules
+% do not apply.
+%
+% o Packed 10 and 12-bit formats are based on a 32-bit word, so
+% 32-bit words are byte-swapped to native order.
+%
+% o 12-bit filled format, and 16 bit format are based on 16-bit words,
+% so 16-bit words are byte-swapped to native order.
+%
+% o 10-bit filled format is based on a 32-bit word, so 32-bit words
+% are byte-swapped to native order.
+%
+% The default format is big-endian.
+%
+% Additional notes:
+%
+% I have received many 4:2:2 YCbCr files in which the Cb/Cr channels are
+% swapped from my interpretation of the specification. This has caused
+% considerable consternation. As a result I have decided to observe the
+% "majority rules" rule and follow the apparent direction set by systems
+% set by Quantel iQ, and DVS Clipster. Therefore, 4:2:2 YCbCr files have
+% Cb/Cr intentionally swapped from the standard. But 4:4:4 YCbCr files
+% use the ordering suggested by the standard since all such files received
+% to date follow the standard.
+%
+% If a YCbCr file reads with vertical or color distortion, try adding
+% "-define dpx:swap-samples=true" when reading the image. The same option
+% may be used to write YCbCr files with swapped samples.
+%
+% Note that some YCbCr files are interlaced. Interlaced files combine
+% two fields into one image. This means that 1/60th of a second has
+% elapsed between odd and even rows. Distortion will be evident if
+% the camera or observed object is in motion. This distortion is not
+% due to a defect in GraphicsMagick.
+%
+% The DPX specification does not specify row alignment on a 32-bit
+% word boundary, but unofficial documentation (e.g. the O'Reilly
+% GFF book) and "lore" suggest it. The GraphicsMagick implementation
+% does pad rows to the next word (16-bit or 32-bit) boundary. It is not
+% clear if the End-of-line padding field should reflect padding to a
+% word boundary.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/bit_stream.h"
+#include "magick/pixel_cache.h"
+#include "magick/constitute.h"
+#include "magick/enum_strings.h"
+#include "magick/magick_endian.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/omp_data_view.h"
+#include "magick/profile.h"
+#include "magick/resize.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+
+/*
+ Define STATIC to nothing so that normally static functions are
+ externally visible in the symbol table (for profiling).
+*/
+#undef STATIC
+#define STATIC static
+
+/*
+ Forward declaractions.
+*/
+static unsigned int
+ WriteDPXImage(const ImageInfo *,Image *);
+
+typedef char ASCII;
+typedef magick_uint8_t U8;
+typedef magick_uint16_t U16;
+typedef magick_uint32_t U32;
+typedef union _R32_u
+{
+ magick_uint32_t u;
+ float f;
+} R32;
+typedef magick_uint16_t sample_t;
+
+#define SET_UNDEFINED_U8(value) (value=0xFFU)
+#define SET_UNDEFINED_U16(value) (value=0xFFFFU)
+#define SET_UNDEFINED_U32(value) (value=0xFFFFFFFFU)
+#define SET_UNDEFINED_R32(value) (value.u=~0U);
+#define SET_UNDEFINED_ASCII(value) ((void) memset(value,0,sizeof(value)))
+
+#define IS_UNDEFINED_U8(value) (value == ((U8) 0xFFU))
+#define IS_UNDEFINED_U16(value) (value == ((U16) 0xFFFFU))
+#define IS_UNDEFINED_U32(value) (value == ((U32) 0xFFFFFFFFU))
+#define IS_UNDEFINED_R32(value) (value.u == ((U32) ~0U))
+#define IS_UNDEFINED_ASCII(value) (!(value[0] > 0))
+
+/*
+ Round the starting address of pixel data to this offset. The DPX
+ specification recommends rounding up to the next 8K boundary past
+ the file header.
+*/
+#define IMAGE_DATA_ROUNDING 8192
+
+/*
+ Image element descriptors.
+*/
+typedef enum
+{
+ ImageElementUnspecified=0,
+ ImageElementRed=1,
+ ImageElementGreen=2,
+ ImageElementBlue=3,
+ ImageElementAlpha=4,
+ ImageElementLuma=6,
+ ImageElementColorDifferenceCbCr=7,
+ ImageElementDepth=8,
+ ImageElementCompositeVideo=9,
+ ImageElementRGB=50, /* BGR order */
+ ImageElementRGBA=51, /* BGRA order */
+ ImageElementABGR=52, /* ARGB order */
+ ImageElementCbYCrY422=100, /* SMPTE 125M, 4:2:2 */
+ ImageElementCbYACrYA4224=101, /* 4:2:2:4 */
+ ImageElementCbYCr444=102, /* 4:4:4 */
+ ImageElementCbYCrA4444=103, /* 4:4:4:4 */
+ ImageElementUserDef2Element=150, /* User-defined 2-component element */
+ ImageElementUserDef3Element=151, /* User-defined 3-component element */
+ ImageElementUserDef4Element=152, /* User-defined 4-component element */
+ ImageElementUserDef5Element=153, /* User-defined 5-component element */
+ ImageElementUserDef6Element=154, /* User-defined 6-component element */
+ ImageElementUserDef7Element=155, /* User-defined 7-component element */
+ ImageElementUserDef8Element=156 /* User-defined 8-component element */
+} DPXImageElementDescriptor;
+
+/*
+ Transfer characteristic enumerations.
+*/
+typedef enum
+{
+ TransferCharacteristicUserDefined=0,
+ TransferCharacteristicPrintingDensity=1,
+ TransferCharacteristicLinear=2,
+ TransferCharacteristicLogarithmic=3,
+ TransferCharacteristicUnspecifiedVideo=4,
+ TransferCharacteristicSMTPE274M=5, /* 1920x1080 TV */
+ TransferCharacteristicITU_R709=6, /* ITU R709 */
+ TransferCharacteristicITU_R601_625L=7, /* 625 Line */
+ TransferCharacteristicITU_R601_525L=8, /* 525 Line */
+ TransferCharacteristicNTSCCompositeVideo=9,
+ TransferCharacteristicPALCompositeVideo=10,
+ TransferCharacteristicZDepthLinear=11,
+ TransferCharacteristicZDepthHomogeneous=12
+} DPXTransferCharacteristic;
+
+/*
+ Colorimetric enumerations.
+*/
+typedef enum
+{
+ ColorimetricUserDefined=0, /* User defined */
+ ColorimetricPrintingDensity=1, /* Printing density */
+ ColorimetricLinear=2, /* Linear */
+ ColorimetricLogarithmic=3, /* Logarithmic */
+ ColorimetricUnspecifiedVideo=4,
+ ColorimetricSMTPE274M=5, /* 1920x1080 TV */
+ ColorimetricITU_R709=6, /* ITU R709 */
+ ColorimetricITU_R601_625L=7, /* 625 Line ITU R601-5 B & G */
+ ColorimetricITU_R601_525L=8, /* 525 Line ITU R601-5 M */
+ ColorimetricNTSCCompositeVideo=9,
+ ColorimetricPALCompositeVideo=10,
+ ColorimetricZDepthLinear=11,
+ ColorimetricZDepthHomogeneous=12
+} DPXColorimetric;
+
+/*
+ Packing methods for filled words.
+*/
+typedef enum
+{
+ PackingMethodPacked=0, /* Packed with no padding */
+ PackingMethodWordsFillLSB=1, /* Method 'A', padding bits in LSB of 32-bit word */
+ PackingMethodWordsFillMSB=2 /* Method 'B', padding bits in MSB of 32-bit word (deprecated) */
+} ImageComponentPackingMethod;
+
+typedef struct _DPXFileInfo
+{
+ U32 magic; /* Magick number (SDPX ASCII) */
+ U32 image_data_offset; /* Offset to image data in bytes */
+ ASCII header_format_version[8]; /* Version number of header format */
+ U32 file_size; /* Total image file size in bytes */
+ U32 ditto_key; /* (0 = same as previous frame; 1 = new) */
+ U32 generic_section_length; /* Generic section header length in bytes */
+ U32 industry_section_length; /* Industry specific header length in bytes */
+ U32 user_defined_length; /* User defined header length in bytes */
+ ASCII image_filename[100]; /* Image filename */
+ ASCII creation_datetime[24]; /* Creation date/time: yyyy:mm:dd:hh:mm:ssLTZ */
+ ASCII creator[100]; /* Creator */
+ ASCII project_name[200]; /* Project name */
+ ASCII copyright[200]; /* Right to use or copyright */
+ U32 encryption_key; /* Encryption key (FFFFFFFF unencrypted ) */
+ ASCII reserved[104]; /* Reserved for future use */
+} DPXFileInfo;
+
+typedef struct _DPXImageElement
+{
+ U32 data_sign; /* Data sign (0 = unsigned; 1 = signed) */
+ U32 reference_low_data_code; /* Reference low data code value */
+ R32 reference_low_quantity; /* Low quantity represented */
+ U32 reference_high_data_code; /* Reference high data code value */
+ R32 reference_high_quantity; /* Reference high quantity represented */
+ U8 descriptor; /* Descriptor */
+ U8 transfer_characteristic; /* Transfer characteristic */
+ U8 colorimetric; /* Colorimetric specification */
+ U8 bits_per_sample; /* Bit depth */
+ U16 packing; /* Packing */
+ U16 encoding; /* Encoding */
+ U32 data_offset; /* Offset to data */
+ U32 eol_pad; /* End of line padding */
+ U32 eoi_pad; /* End of image padding */
+ ASCII description[32]; /* Description of image element */
+} DPXImageElement;
+
+typedef struct _DPXImageInfo
+{
+ U16 orientation; /* Image orientation */
+ U16 elements; /* Number of image elements (1-8) */
+ U32 pixels_per_line; /* Pixels per line (columns) */
+ U32 lines_per_image_element; /* Lines per image element (rows) */
+ DPXImageElement element_info[8]; /* Description of elements */
+ ASCII reserved[52]; /* Reserved for future use */
+} DPXImageInfo;
+
+typedef struct _DPXImageSourceBorderValidity
+{
+ /*
+ Border validity indicates portion of border pixels which have been
+ eroded due to processing.
+ */
+ U16 XL; /* Border validity XL border */
+ U16 XR; /* Border validity XR border */
+ U16 YT; /* Border validity YT border */
+ U16 YB; /* Border validity YB border */
+} DPXImageSourceBorderValidity;
+
+typedef struct _DPXImageSourcePixelAspectRatio
+{
+ U32 horizontal; /* Horizontal */
+ U32 vertical; /* Vertical */
+} DPXImageSourcePixelAspectRatio;
+
+typedef struct _DPXImageSourceInfo
+{
+ U32 x_offset; /* X offset */
+ U32 y_offset; /* Y offset */
+ R32 x_center; /* X center */
+ R32 y_center; /* Y center */
+ U32 x_original_size; /* X original size */
+ U32 y_original_size; /* Y original size */
+ ASCII source_image_filename[100];/* Source image filename */
+ ASCII source_image_datetime[24]; /* Source image date/time: yyyy:mmm:dd:hh:mm:ssLTZ */
+ ASCII input_device_name[32]; /* Input device name */
+ ASCII input_device_serialnumber[32]; /* Input device serial number */
+ DPXImageSourceBorderValidity border_validity; /* Border validity */
+ DPXImageSourcePixelAspectRatio aspect_ratio; /* Aspect ratio */
+ R32 x_scanned_size; /* X scanned size */
+ R32 y_scanned_size; /* Y scanned size */
+ ASCII reserved[20]; /* Reserved for future use */
+} DPXImageSourceInfo;
+
+typedef struct _DPXMPFilmInfo
+{
+ ASCII film_mfg_id_code[2]; /* Film mfg. ID code (2 digits from film edge code) */
+ ASCII film_type[2]; /* Film type (2 digits from film edge code) */
+ ASCII perfs_offset[2]; /* Offset in perfs (2 digits from film edge code) */
+ ASCII prefix[6]; /* Prefix (6 digits from film edge code) */
+ ASCII count[4]; /* Count (4 digits from film edge code) */
+ ASCII format[32]; /* Format -- e.g. Academy */
+ U32 frame_position; /* Frame position in sequence */
+ U32 sequence_length; /* Sequence length (frames) */
+ U32 held_count; /* Held count (1 = default) */
+ R32 frame_rate; /* Frame rate of original (frames/s) */
+ R32 shutter_angle; /* Shutter angle of camera in degrees */
+ ASCII frame_id[32]; /* Frame identification - e.g. keyframe */
+ ASCII slate_info[100]; /* Slate information */
+ ASCII reserved[56]; /* Reserved for future use */
+} DPXMPFilmInfo;
+
+typedef struct _DPXTVInfo
+{
+ U32 time_code; /* SMPTE time code */
+ U32 user_bits; /* SMPTE user bits */
+ U8 interlace; /* Interlace (0 = noninterlaced; 1 = 2:1 interlace */
+ U8 field_number; /* Field number */
+ U8 video_signal; /* Video signal standard */
+ U8 zero; /* Zero (for byte alignment) */
+ R32 horizontal_sample; /* Horizontal sampling rate */
+ R32 vertical_sample; /* Vertical sampling rate */
+ R32 temporal_sample; /* Temporal sampling rate or frame rate (Hz) */
+ R32 sync_time; /* Time offset from sync to first pixel (ms) */
+ R32 gamma; /* Gamma (applied above breakpoint) */
+ R32 black_level; /* Black level code value */
+ R32 black_gain; /* Black gain (linear gain applied below breakpoint) */
+ R32 breakpoint; /* Breakpoint (point above which gamma is applied) */
+ R32 white_level; /* Reference white level code value */
+ R32 integration_time; /* Integration time (s) */
+ ASCII reserved[76]; /* Reserved for future use */
+} DPXTVInfo;
+
+typedef struct _DPXUserDefinedData
+{
+ ASCII user_id[32]; /* User identification */
+ /* Up to 1MB of user-defined data after this point */
+} DPXUserDefinedData;
+
+typedef struct _DPXHeader
+{
+ DPXFileInfo file_info; /* File information header */
+ DPXImageInfo image_info; /* Image information header */
+ DPXImageSourceInfo source_info; /* Image source information header */
+ DPXMPFilmInfo mp_info; /* Motion picture film information header */
+ DPXTVInfo tv_info; /* Television information header */
+} DPXHeader;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s D P X %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsDPX returns True if the image format type, identified by the
+% magick string, is DPX.
+%
+% The format of the IsDPX method is:
+%
+% unsigned int IsDPX(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsDPX returns True if the image format type is DPX.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+STATIC unsigned int IsDPX(const unsigned char *magick,const size_t length)
+{
+ return ((length >= 4) &&
+ ((memcmp(magick,"SDPX",4) == 0) || (memcmp(magick,"XPDS",4) == 0)));
+}
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d D P X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadDPXImage reads an DPX X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadDPXImage method is:
+%
+% Image *ReadDPXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadDPXImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define LogSetImageAttribute(name,value) \
+{ \
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), \
+ "Attribute \"%s\" set to \"%s\"", \
+ name,value); \
+}
+/* Can't use strlcpy() since strlcpy() only handles NULL terminated
+ strings. Note that some fields occupy the full space with no
+ trailing null so we null terminate one character *after* the
+ DPX field size.
+*/
+#define StringToAttribute(image,name,member) \
+{ \
+ char \
+ buffer_[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_ASCII(member)) \
+ { \
+ (void) strncpy(buffer_,member,Min(sizeof(member),MaxTextExtent)); \
+ buffer_[Min(sizeof(member)+1,MaxTextExtent-1)]='\0'; \
+ (void) SetImageAttribute(image,name,buffer_); \
+ LogSetImageAttribute(name,buffer_); \
+ } \
+}
+#define U8ToAttribute(image,name,member) \
+{ \
+ char \
+ buffer_[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_U8(member)) \
+ { \
+ FormatString(buffer_,"%u",(unsigned int) member); \
+ (void) SetImageAttribute(image,name,buffer_); \
+ LogSetImageAttribute(name,buffer_); \
+ } \
+}
+#define U16ToAttribute(image,name,member) \
+{ \
+ char \
+ buffer_[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_U16(member)) \
+ { \
+ FormatString(buffer_,"%u",(unsigned int) member); \
+ (void) SetImageAttribute(image,name,buffer_); \
+ LogSetImageAttribute(name,buffer_); \
+ } \
+}
+#define U32ToAttribute(image,name,member) \
+{ \
+ char \
+ buffer_[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_U32(member)) \
+ { \
+ FormatString(buffer_,"%u",member); \
+ (void) SetImageAttribute(image,name,buffer_); \
+ LogSetImageAttribute(name,buffer_); \
+ } \
+}
+#define U32ToBitsAttribute(image,name,member) \
+{ \
+ char \
+ buffer_[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_U32(member)) \
+ { \
+ SMPTEBitsToString(member,buffer_); \
+ (void) SetImageAttribute(image,name,buffer_); \
+ LogSetImageAttribute(name,buffer_); \
+ } \
+}
+#define R32ToAttribute(image,name,member) \
+{ \
+ char \
+ buffer_[MaxTextExtent]; \
+\
+ if (!IS_UNDEFINED_R32(member)) \
+ { \
+ FormatString(buffer_,"%g",member.f); \
+ (void) SetImageAttribute(image,name,buffer_); \
+ LogSetImageAttribute(name,buffer_); \
+ } \
+}
+STATIC void SwabDPXFileInfo(DPXFileInfo *file_info)
+{
+ MagickSwabUInt32(&file_info->magic);
+ MagickSwabUInt32(&file_info->image_data_offset);
+ MagickSwabUInt32(&file_info->file_size);
+ MagickSwabUInt32(&file_info->ditto_key);
+ MagickSwabUInt32(&file_info->generic_section_length);
+ MagickSwabUInt32(&file_info->industry_section_length);
+ MagickSwabUInt32(&file_info->user_defined_length);
+ MagickSwabUInt32(&file_info->encryption_key);
+}
+STATIC void SwabDPXImageInfo(DPXImageInfo *image_info)
+{
+ int
+ i;
+
+ MagickSwabUInt16(&image_info->orientation);
+ MagickSwabUInt16(&image_info->elements);
+ MagickSwabUInt32(&image_info->pixels_per_line);
+ MagickSwabUInt32(&image_info->lines_per_image_element);
+ for (i=0 ; i < 8 ; i++)
+ {
+ MagickSwabUInt32(&image_info->element_info[i].data_sign);
+ MagickSwabUInt32(&image_info->element_info[i].reference_low_data_code);
+ MagickSwabFloat(&image_info->element_info[i].reference_low_quantity.f);
+ MagickSwabUInt32(&image_info->element_info[i].reference_high_data_code);
+ MagickSwabFloat(&image_info->element_info[i].reference_high_quantity.f);
+ MagickSwabUInt16(&image_info->element_info[i].packing);
+ MagickSwabUInt16(&image_info->element_info[i].encoding);
+ MagickSwabUInt32(&image_info->element_info[i].data_offset);
+ MagickSwabUInt32(&image_info->element_info[i].eol_pad);
+ MagickSwabUInt32(&image_info->element_info[i].eoi_pad);
+ }
+}
+STATIC void SwabDPXImageSourceInfo(DPXImageSourceInfo *source_info)
+{
+ MagickSwabUInt32(&source_info->x_offset);
+ MagickSwabUInt32(&source_info->y_offset);
+ MagickSwabFloat(&source_info->x_center.f);
+ MagickSwabFloat(&source_info->y_center.f);
+ MagickSwabUInt32(&source_info->x_original_size);
+ MagickSwabUInt32(&source_info->y_original_size);
+ MagickSwabUInt16(&source_info->border_validity.XL);
+ MagickSwabUInt16(&source_info->border_validity.XR);
+ MagickSwabUInt16(&source_info->border_validity.YT);
+ MagickSwabUInt16(&source_info->border_validity.YB);
+ MagickSwabUInt32(&source_info->aspect_ratio.horizontal);
+ MagickSwabUInt32(&source_info->aspect_ratio.vertical);
+ MagickSwabFloat(&source_info->x_scanned_size.f);
+ MagickSwabFloat(&source_info->y_scanned_size.f);
+}
+STATIC void SwabDPXMPFilmInfo(DPXMPFilmInfo *mp_info)
+{
+ MagickSwabUInt32(&mp_info->frame_position);
+ MagickSwabUInt32(&mp_info->sequence_length);
+ MagickSwabUInt32(&mp_info->held_count);
+ MagickSwabFloat(&mp_info->frame_rate.f);
+ MagickSwabFloat(&mp_info->shutter_angle.f);
+}
+STATIC void SwabDPXTVInfo(DPXTVInfo *tv_info)
+{
+ MagickSwabUInt32(&tv_info->time_code);
+ MagickSwabUInt32(&tv_info->user_bits);
+ MagickSwabFloat(&tv_info->horizontal_sample.f);
+ MagickSwabFloat(&tv_info->vertical_sample.f);
+ MagickSwabFloat(&tv_info->temporal_sample.f);
+ MagickSwabFloat(&tv_info->sync_time.f);
+ MagickSwabFloat(&tv_info->gamma.f);
+ MagickSwabFloat(&tv_info->black_level.f);
+ MagickSwabFloat(&tv_info->black_gain.f);
+ MagickSwabFloat(&tv_info->breakpoint.f);
+ MagickSwabFloat(&tv_info->white_level.f);
+ MagickSwabFloat(&tv_info->integration_time.f);
+}
+STATIC void SMPTEBitsToString(const U32 value, char *str)
+{
+ unsigned int
+ pos,
+ shift = 28;
+
+ for (pos=8; pos != 0; pos--, shift -= 4)
+ {
+ (void) sprintf(str,"%01u",(unsigned int) ((value >> shift) & 0x0fU));
+ str += 1;
+ if ((pos > 2) && (pos % 2))
+ {
+ (void) strcat(str,":");
+ str++;
+ }
+ }
+ *str='\0';
+}
+STATIC U32 SMPTEStringToBits(const char *str)
+{
+ U32
+ value=0;
+
+ unsigned int
+ pos = 0,
+ shift = 28;
+
+ char
+ buff[2];
+
+ buff[1]='\0';
+
+ while ((*str != 0) && (pos < 8))
+ {
+ if (!isdigit((int) *str))
+ {
+ str++;
+ continue;
+ }
+ buff[0]=*str++;
+ value |= (U32) ((strtol(buff,(char **)NULL,10)) << shift);
+ shift -= 4;
+ pos++;
+ }
+ return value;
+}
+/*
+ Compute the number of octets required to contain the specified number of
+ rows, with specified samples per row, bits per sample, and packing method.
+*/
+STATIC size_t DPXRowOctets(const unsigned long rows,
+ const unsigned int samples_per_row,
+ const unsigned int bits_per_sample,
+ const ImageComponentPackingMethod packing_method)
+{
+ size_t
+ octets = 0;
+
+ switch(bits_per_sample)
+ {
+ case 1:
+ /* Packed 1-bit samples in 32-bit words. Rows are padded out to 32-bit alignment */
+ octets=rows*(((magick_int64_t) samples_per_row*bits_per_sample+31)/32)*sizeof(U32);
+ break;
+ case 8:
+ /* C.1 8-bit samples in a 32-bit word. Rows are padded out to 32-bit alignment */
+ octets=rows*(((magick_int64_t) samples_per_row*bits_per_sample+31)/32)*sizeof(U32);
+ break;
+ case 32:
+ /* 32-bit samples in a 32-bit word */
+ octets=samples_per_row*sizeof(U32)*rows;
+ break;
+ case 10:
+ if ((packing_method == PackingMethodWordsFillLSB) ||
+ (packing_method == PackingMethodWordsFillMSB))
+ {
+ /* C.3 Three 10-bit samples per 32-bit word */
+ octets=(((((magick_int64_t) (rows*samples_per_row+2)/3)*sizeof(U32)*8)+31)/32)*sizeof(U32);
+ }
+ else
+ {
+ /* C.2 Packed 10-bit samples in a 32-bit word. */
+ octets=rows*(((magick_int64_t) samples_per_row*bits_per_sample+31)/32)*sizeof(U32);
+ }
+ break;
+ case 12:
+ if ((packing_method == PackingMethodWordsFillLSB) ||
+ (packing_method == PackingMethodWordsFillMSB))
+ {
+ /* C.5: One 12-bit sample per 16-bit word */
+ octets=((((magick_int64_t) rows*samples_per_row*sizeof(U16)*8)+15)/16)*sizeof(U16);
+ }
+ else
+ {
+ /* C.4: Packed 12-bit samples in a 32-bit word. */
+ octets=rows*(((magick_int64_t) samples_per_row*bits_per_sample+31)/32)*sizeof(U32);
+ }
+ break;
+ case 16:
+ /* C.6 16-bit samples in 16-bit words. */
+ octets=((((magick_int64_t) rows*samples_per_row*bits_per_sample)+15)/16)*sizeof(U16);
+ break;
+ case 64:
+ /* 64-bit samples in 64-bit words. */
+ octets=(magick_int64_t) rows*samples_per_row*8;
+ break;
+ }
+
+ return octets;
+}
+/*
+ Compute optimum I/O parameters based on all considerations.
+*/
+#if 0
+STATIC size_t DPXIOOctets(const long current_row, /* 0 based */
+ const unsigned long image_rows,
+ const unsigned int samples_per_row,
+ const unsigned int bits_per_sample,
+ const ImageComponentPackingMethod packing_method)
+{
+ long
+ rows_remaining;
+
+ rows_remaining=image_rows-current_row;
+
+
+
+}
+#endif
+STATIC const char *DescribeImageElementDescriptor(char *buffer, const DPXImageElementDescriptor descriptor)
+{
+ const char *
+ description="Unknown";
+
+ switch(descriptor)
+ {
+ case ImageElementUnspecified:
+ description="Generic 1 Element";
+ break;
+ case ImageElementRed:
+ description="Red";
+ break;
+ case ImageElementGreen:
+ description="Green";
+ break;
+ case ImageElementBlue:
+ description="Blue";
+ break;
+ case ImageElementAlpha:
+ description="Alpha";
+ break;
+ case ImageElementLuma:
+ description="Luma";
+ break;
+ case ImageElementColorDifferenceCbCr:
+ description="CbCr";
+ break;
+ case ImageElementDepth:
+ description="Depth(8)";
+ break;
+ case ImageElementCompositeVideo:
+ description="CompositeVideo";
+ break;
+ case ImageElementRGB:
+ description="RGB";
+ break;
+ case ImageElementRGBA:
+ description="RGBA";
+ break;
+ case ImageElementABGR:
+ description="ABGR";
+ break;
+ case ImageElementCbYCrY422:
+ description="CbYCrY 4:2:2";
+ break;
+ case ImageElementCbYACrYA4224:
+ description="CbYACrYA 4:2:2:4";
+ break;
+ case ImageElementCbYCr444:
+ description="CbYCr 4:4:4";
+ break;
+ case ImageElementCbYCrA4444:
+ description="CbYCrA 4:4:4:4";
+ break;
+ case ImageElementUserDef2Element:
+ description="Generic 2 Element";
+ break;
+ case ImageElementUserDef3Element:
+ description="Generic 3 Element";
+ break;
+ case ImageElementUserDef4Element:
+ description="Generic 4 Element";
+ break;
+ case ImageElementUserDef5Element:
+ description="Generic 5 Element";
+ break;
+ case ImageElementUserDef6Element:
+ description="Generic 6 Element";
+ break;
+ case ImageElementUserDef7Element:
+ description="Generic 7 Element";
+ break;
+ case ImageElementUserDef8Element:
+ description="Generic 8 Element";
+ break;
+ default:
+ {
+ FormatString(buffer,"Unknown (%u)",(unsigned int) descriptor);
+ description=buffer;
+ }
+ }
+
+ return description;
+}
+/*
+ Describe the element transfer characteristic.
+*/
+STATIC const char *DescribeImageTransferCharacteristic(char *buffer, const DPXTransferCharacteristic characteristic)
+{
+ const char
+ *description=buffer;
+
+ buffer[0]='\0';
+ switch(characteristic)
+ {
+ case TransferCharacteristicUserDefined:
+ description="UserDefined";
+ break;
+ case TransferCharacteristicPrintingDensity:
+ description="PrintingDensity";
+ break;
+ case TransferCharacteristicLinear:
+ description="Linear";
+ break;
+ case TransferCharacteristicLogarithmic:
+ description="Logarithmic";
+ break;
+ case TransferCharacteristicUnspecifiedVideo:
+ description="UnspecifiedVideo";
+ break;
+ case TransferCharacteristicSMTPE274M:
+ description="SMTPE274M";
+ break;
+ case TransferCharacteristicITU_R709:
+ description="ITU-R709";
+ break;
+ case TransferCharacteristicITU_R601_625L:
+ description="ITU-R601-625L";
+ break;
+ case TransferCharacteristicITU_R601_525L:
+ description="ITU-R601-525L";
+ break;
+ case TransferCharacteristicNTSCCompositeVideo:
+ description="NTSCCompositeVideo";
+ break;
+ case TransferCharacteristicPALCompositeVideo:
+ description="PALCompositeVideo";
+ break;
+ case TransferCharacteristicZDepthLinear:
+ description="ZDepthLinear";
+ break;
+ case TransferCharacteristicZDepthHomogeneous:
+ description="ZDepthHomogeneous";
+ break;
+ default:
+ {
+ FormatString(buffer,"Reserved(%u)",(unsigned int) characteristic);
+ }
+ }
+
+ return description;
+}
+/*
+ Describe the element colorimetric.
+*/
+STATIC const char *DescribeImageColorimetric(char *buffer, const DPXColorimetric colorimetric)
+{
+ const char
+ *description=buffer;
+
+ buffer[0]='\0';
+ switch(colorimetric)
+ {
+ case ColorimetricUserDefined:
+ description="UserDefined";
+ break;
+ case ColorimetricPrintingDensity:
+ description="PrintingDensity";
+ break;
+ case ColorimetricLinear:
+ description="NotApplicable";
+ break;
+ case ColorimetricLogarithmic:
+ description="NotApplicable";
+ break;
+ case ColorimetricUnspecifiedVideo:
+ description="UnspecifiedVideo";
+ break;
+ case ColorimetricSMTPE274M:
+ description="SMTPE274M";
+ break;
+ case ColorimetricITU_R709:
+ description="ITU-R709";
+ break;
+ case ColorimetricITU_R601_625L:
+ description="ITU-R601-625L";
+ break;
+ case ColorimetricITU_R601_525L:
+ description="ITU-R601-525L";
+ break;
+ case ColorimetricNTSCCompositeVideo:
+ description="NTSCCompositeVideo";
+ break;
+ case ColorimetricPALCompositeVideo:
+ description="PALCompositeVideo";
+ break;
+ case ColorimetricZDepthLinear:
+ description="NotApplicable";
+ break;
+ case ColorimetricZDepthHomogeneous:
+ description="NotApplicable";
+ break;
+ default:
+ {
+ FormatString(buffer,"Reserved(%u)",(unsigned int) colorimetric);
+ }
+ }
+
+ return description;
+}
+/*
+ Describe the image element.
+*/
+STATIC void DescribeDPXImageElement(const DPXImageElement *element_info,
+ const unsigned int element)
+{
+ char txt_buffer[MaxTextExtent];
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Element %u: data_sign=%s",element,
+ element_info->data_sign == 0 ?
+ "unsigned(0)" : "signed(1)");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Element %u: reference_low_data_code=%u reference_low_quantity=%g",
+ element,
+ element_info->reference_low_data_code,
+ element_info->reference_low_quantity.f);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Element %u: reference_high_data_code=%u reference_high_quantity=%g",
+ element,
+ element_info->reference_high_data_code,
+ element_info->reference_high_quantity.f);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Element %u: descriptor=%s(%u) transfer_characteristic=%s(%u) colorimetric=%s(%u)",
+ element,
+ DescribeImageElementDescriptor(txt_buffer,(DPXImageElementDescriptor) element_info->descriptor),
+ (unsigned int) element_info->descriptor,
+ DescribeImageTransferCharacteristic(txt_buffer,(DPXTransferCharacteristic) element_info->transfer_characteristic),
+ (unsigned int) element_info->transfer_characteristic,
+ DescribeImageColorimetric(txt_buffer,(DPXColorimetric) element_info->colorimetric),
+ (unsigned int) element_info->colorimetric);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Element %u: bits-per-sample=%u",
+ element,
+ (unsigned int) element_info->bits_per_sample);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Element %u: packing=%s encoding=%s data_offset=%u eol_pad=%u eoi_pad=%u",
+ element,
+ (element_info->packing == 0 ? "Packed(0)" :
+ element_info->packing == 1 ? "PadLSB(1)" :
+ element_info->packing == 2 ? "PadMSB(2)" :
+ "Unknown"),
+ (element_info->encoding == 0 ? "None(0)" :
+ element_info->encoding == 1 ? "RLE(1)" :
+ "Unknown"),
+ (unsigned int) element_info->data_offset,
+ (unsigned int) element_info->eol_pad,
+ (unsigned int) element_info->eoi_pad);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Element %u: description=\"%.32s\"",
+ element,
+ element_info->description);
+}
+/*
+ Obtain number of element samples required to support one pixel. For
+ example, RGB requires three samples, but if the image organization
+ is planar three elements are required to support RGB, and this
+ function will therefore return 1 rather than 3.
+*/
+STATIC unsigned int DPXSamplesPerPixel(const DPXImageElementDescriptor element_descriptor)
+{
+ unsigned int
+ samples_per_pixel=0;
+
+ switch (element_descriptor)
+ {
+ case ImageElementUnspecified:
+ case ImageElementRed:
+ case ImageElementGreen:
+ case ImageElementBlue:
+ case ImageElementAlpha:
+ case ImageElementLuma:
+ case ImageElementColorDifferenceCbCr:
+ samples_per_pixel=1;
+ break;
+ case ImageElementRGB:
+ samples_per_pixel=3;
+ break;
+ case ImageElementRGBA:
+ case ImageElementABGR:
+ samples_per_pixel=4;
+ break;
+ case ImageElementCbYCrY422:
+ /* CbY | CrY | CbY | CrY ..., even number of columns required. */
+ samples_per_pixel=2;
+ break;
+ case ImageElementCbYACrYA4224:
+ /* CbYA | CrYA | CbYA | CrYA ..., even number of columns required. */
+ samples_per_pixel=3;
+ break;
+ case ImageElementCbYCr444:
+ samples_per_pixel=3;
+ break;
+ case ImageElementCbYCrA4444:
+ samples_per_pixel=4;
+ break;
+ default:
+ samples_per_pixel=0;
+ break;
+ }
+
+ return samples_per_pixel;
+}
+/*
+ Set the image primary chromaticities based on the colorimetric.
+*/
+STATIC void DPXSetPrimaryChromaticities(const DPXColorimetric colorimetric,
+ ChromaticityInfo *chromaticity_info)
+{
+ switch(colorimetric)
+ {
+ case ColorimetricSMTPE274M:
+ case ColorimetricITU_R709:/* ITU R709 */
+ /* ITU-R BT.709-5, D65 */
+ chromaticity_info->red_primary.x=0.640;
+ chromaticity_info->red_primary.y=0.330;
+ chromaticity_info->red_primary.z=0.030;
+ chromaticity_info->green_primary.x=0.300;
+ chromaticity_info->green_primary.y=0.600;
+ chromaticity_info->green_primary.z=0.100;
+ chromaticity_info->blue_primary.x=0.150;
+ chromaticity_info->blue_primary.y=0.060;
+ chromaticity_info->blue_primary.z=0.790;
+ chromaticity_info->white_point.x=0.3127;
+ chromaticity_info->white_point.y=0.3290;
+ chromaticity_info->white_point.z=0.3582;
+ break;
+
+ case ColorimetricNTSCCompositeVideo:
+ /* Obsolete NTSC primaries, White CIE III. C */
+ chromaticity_info->red_primary.x=0.67;
+ chromaticity_info->red_primary.y=0.33;
+ chromaticity_info->red_primary.z=0.00;
+ chromaticity_info->green_primary.x=0.21;
+ chromaticity_info->green_primary.y=0.71;
+ chromaticity_info->green_primary.z=0.08;
+ chromaticity_info->blue_primary.x=0.14;
+ chromaticity_info->blue_primary.y=0.08;
+ chromaticity_info->blue_primary.z=0.78;
+ chromaticity_info->white_point.x=0.310;
+ chromaticity_info->white_point.y=0.316;
+ chromaticity_info->white_point.z=0.374;
+ break;
+
+ case ColorimetricPALCompositeVideo:
+ /* EBU Tech. 3213 primaries, D65 */
+ chromaticity_info->red_primary.x=0.640;
+ chromaticity_info->red_primary.y=0.330;
+ chromaticity_info->red_primary.z=0.030;
+ chromaticity_info->green_primary.x=0.290;
+ chromaticity_info->green_primary.y=0.600;
+ chromaticity_info->green_primary.z=0.110;
+ chromaticity_info->blue_primary.x=0.150;
+ chromaticity_info->blue_primary.y=0.060;
+ chromaticity_info->blue_primary.z=0.790;
+ chromaticity_info->white_point.x=0.3127;
+ chromaticity_info->white_point.y=0.3290;
+ chromaticity_info->white_point.z=0.3582;
+ break;
+
+#if 0
+ /* SMPTE RP 145 / SMPTE 240M primaries (as used for 480i SDTV), D65 */
+ chromaticity_info->red_primary.x=0.630;
+ chromaticity_info->red_primary.y=0.340;
+ chromaticity_info->red_primary.z=0.030;
+ chromaticity_info->green_primary.x=0.310;
+ chromaticity_info->green_primary.y=0.595;
+ chromaticity_info->green_primary.z=0.095;
+ chromaticity_info->blue_primary.x=0.155;
+ chromaticity_info->blue_primary.y=0.070;
+ chromaticity_info->blue_primary.z=0.775;
+ chromaticity_info->white_point.x=0.3127;
+ chromaticity_info->white_point.y=0.3290;
+ chromaticity_info->white_point.z=0.3582;
+#endif
+
+
+ case ColorimetricITU_R601_625L: /* 625 Line ITU R601-5 B & G */
+ case ColorimetricITU_R601_525L: /* 525 Line ITU R601-5 M */
+
+ case ColorimetricUserDefined: /* User defined */
+ case ColorimetricPrintingDensity: /* Printing density */
+ case ColorimetricLinear: /* Linear */
+ case ColorimetricLogarithmic: /* Logarithmic */
+ case ColorimetricUnspecifiedVideo:
+ default:
+ {
+ break;
+ }
+ }
+}
+
+STATIC OrientationType
+DPXOrientationToOrientationType(const unsigned int orientation)
+{
+ OrientationType
+ orientation_type = UndefinedOrientation;
+
+ switch (orientation)
+ {
+ case 0U:
+ orientation_type=TopLeftOrientation;
+ break;
+ case 1U:
+ orientation_type=TopRightOrientation;
+ break;
+ case 2U:
+ orientation_type=BottomLeftOrientation;
+ break;
+ case 3U:
+ orientation_type=BottomRightOrientation;
+ break;
+ case 4U:
+ orientation_type=LeftTopOrientation;
+ break;
+ case 5U:
+ orientation_type=RightTopOrientation;
+ break;
+ case 6U:
+ orientation_type=LeftBottomOrientation;
+ break;
+ case 7U:
+ orientation_type=RightBottomOrientation;
+ break;
+ }
+
+ return orientation_type;
+}
+
+#define LSBOctetsToPackedU32Word(scanline,packed_u32) \
+{ \
+ packed_u32 = (((magick_uint32_t) *scanline++)); \
+ packed_u32 |= (((magick_uint32_t) *scanline++) << 8); \
+ packed_u32 |= (((magick_uint32_t) *scanline++) << 16); \
+ packed_u32 |= (((magick_uint32_t) *scanline++) << 24); \
+}
+#define MSBOctetsToPackedU32Word(scanline,packed_u32) \
+{ \
+ packed_u32 = (((magick_uint32_t) *scanline++) << 24); \
+ packed_u32 |= (((magick_uint32_t) *scanline++) << 16); \
+ packed_u32 |= (((magick_uint32_t) *scanline++) << 8); \
+ packed_u32 |= (((magick_uint32_t) *scanline++)); \
+}
+
+/*
+ Scale from a video level to a full-range level.
+*/
+STATIC inline Quantum ScaleFromVideo(const double sample,
+ const double ref_low,
+ const double upscale)
+{
+ double
+ result = 0.0;
+
+ if (sample > ref_low)
+ result = (sample - ref_low)*upscale;
+ return RoundDoubleToQuantum(result);
+
+}
+
+/*
+ WordStreamLSBRead support
+*/
+typedef struct _ReadWordU32State
+{
+ const unsigned char *words;
+} ReadWordU32State;
+
+STATIC unsigned long ReadWordU32BE (void *state)
+{
+ magick_uint32_t value;
+ ReadWordU32State *read_state=(ReadWordU32State *) state;
+ value = *read_state->words++ << 24;
+ value |= *read_state->words++ << 16;
+ value |= *read_state->words++ << 8;
+ value |= *read_state->words++;
+ return value;
+}
+
+STATIC unsigned long ReadWordU32LE (void *state)
+{
+ magick_uint32_t value;
+ ReadWordU32State *read_state=(ReadWordU32State *) state;
+ value = *read_state->words++;
+ value |= *read_state->words++ << 8;
+ value |= *read_state->words++ << 16;
+ value |= *read_state->words++ << 24;
+ return value;
+}
+
+/*
+ Decode row samples. Currently just one row but in the future may be
+ multiple rows (e.g. 3).
+
+ scanline -- Raw input data (may be 8-bit, 16-bit, 32-bit, or 64-bit types)
+ which represents the encoded pixels for one or more scanlines.
+ Underlying input data type is properly aligned for access.
+ samples_per_row -- Number of samples to decode.
+ bits_per_sample -- Number of bits in one decoded sample.
+ packing_method -- Describes the way that samples are packed into enclosing words.
+ endian_type -- The endian order of the enclosing words.
+ swap_word_datums -- Use alternate sample order (BGR vs RGB, CbYCr vs CrYCb) for
+ samples filled into 32 bit words.
+ samples -- Decoded samples (currently unsigned 16-bit).
+*/
+STATIC void ReadRowSamples(const unsigned char *scanline,
+ const unsigned int samples_per_row,
+ const unsigned int bits_per_sample,
+ const ImageComponentPackingMethod packing_method,
+ const EndianType endian_type,
+ const MagickBool swap_word_datums,
+ sample_t *samples)
+{
+ register unsigned long
+ i;
+
+ sample_t
+ *sp;
+
+ register unsigned int
+ sample;
+
+ sp=samples;
+ if ((packing_method != PackingMethodPacked) &&
+ ((bits_per_sample == 10) || (bits_per_sample == 12)))
+ {
+ MagickBool
+ word_pad_lsb=MagickFalse,
+ word_pad_msb=MagickFalse;
+
+ if (packing_method == PackingMethodWordsFillLSB)
+ word_pad_lsb=MagickTrue;
+ else if (packing_method == PackingMethodWordsFillMSB)
+ word_pad_msb=MagickTrue;
+
+ if (bits_per_sample == 10)
+ {
+ register magick_uint32_t
+ packed_u32;
+
+ register unsigned int
+ datum;
+
+ unsigned int
+ shifts[3] = { 0, 0, 0 };
+
+ if (word_pad_lsb)
+ {
+ /*
+ Padding in LSB (Method A) Standard method.
+ */
+ if (swap_word_datums == MagickFalse)
+ {
+ shifts[0]=2; /* datum-0 / blue */
+ shifts[1]=12; /* datum-1 / green */
+ shifts[2]=22; /* datum-2 / red */
+ }
+ else
+ {
+ shifts[0]=22; /* datum-2 / red */
+ shifts[1]=12; /* datum-1 / green */
+ shifts[2]=2; /* datum-0 / blue */
+ }
+ }
+ else if (word_pad_msb)
+ {
+ /*
+ Padding in MSB (Method B) Deprecated method.
+ */
+ if (swap_word_datums == MagickFalse)
+ {
+ shifts[0]=0; /* datum-0 / blue */
+ shifts[1]=10; /* datum-1 / green */
+ shifts[2]=20; /* datum-2 / red */
+ }
+ else
+ {
+ shifts[0]=20; /* datum-2 / red */
+ shifts[1]=10; /* datum-1 / green */
+ shifts[2]=0; /* datum-0 / blue */
+ }
+ }
+
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row/3; i != 0; --i)
+ {
+ datum=0;
+ MSBOctetsToPackedU32Word(scanline,packed_u32);
+ *sp++=(packed_u32 >> shifts[datum++]) & 0x3FF;
+ *sp++=(packed_u32 >> shifts[datum++]) & 0x3FF;
+ *sp++=(packed_u32 >> shifts[datum]) & 0x3FF;
+ }
+ if ((samples_per_row % 3))
+ {
+ datum=0;
+ MSBOctetsToPackedU32Word(scanline,packed_u32);
+ for (i=(samples_per_row % 3); i != 0; --i)
+ *sp++=(packed_u32 >> shifts[datum++]) & 0x3FF;
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row/3; i != 0; --i)
+ {
+ datum=0;
+ LSBOctetsToPackedU32Word(scanline,packed_u32);
+ *sp++=(packed_u32 >> shifts[datum++]) & 0x3FF;
+ *sp++=(packed_u32 >> shifts[datum++]) & 0x3FF;
+ *sp++=(packed_u32 >> shifts[datum]) & 0x3FF;
+ }
+ if ((samples_per_row % 3))
+ {
+ datum=0;
+ LSBOctetsToPackedU32Word(scanline,packed_u32);
+ for (i=(samples_per_row % 3); i != 0; --i)
+ *sp++=(packed_u32 >> shifts[datum++]) & 0x3FF;
+ }
+ }
+ return;
+ }
+ else if (bits_per_sample == 12)
+ {
+ if (word_pad_lsb)
+ {
+ /*
+ Padding in LSB (Method A) Standard method.
+ */
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=0;
+ sample |= (*scanline++ << 8);
+ sample |= (*scanline++);
+ sample >>= 4;
+ *sp++=sample;
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=0;
+ sample |= (*scanline++);
+ sample |= (*scanline++ << 8);
+ sample >>= 4;
+ *sp++=sample;
+ }
+ }
+ return;
+ }
+ else if (word_pad_msb)
+ {
+ /*
+ Padding in MSB (Method B) Deprecated method.
+ */
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=0;
+ sample |= (*scanline++ << 8);
+ sample |= (*scanline++);
+ sample &= 0xFFF;
+ *sp++=sample;
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=0;
+ sample |= (*scanline++);
+ sample |= (*scanline++ << 8);
+ sample &= 0xFFF;
+ *sp++=sample;
+ }
+ }
+ return;
+ }
+ }
+ }
+
+ /*
+ Special fast handling for 8-bit images.
+ */
+ if (bits_per_sample == 8)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ *sp++= (sample_t) *scanline++;
+ return;
+ }
+
+ /*
+ Special fast handling for 16-bit images.
+ */
+ if (bits_per_sample == 16)
+ {
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=0;
+ sample |= (*scanline++ << 8);
+ sample |= (*scanline++);
+ *sp++=sample;
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=0;
+ sample |= (*scanline++);
+ sample |= (*scanline++ << 8);
+ *sp++=sample;
+ }
+ }
+ return;
+ }
+
+#if 0
+ /*
+ Special fast handling for 32-bit (float) images.
+ */
+ if (bits_per_sample == 32)
+ {
+ register magick_uint32_t
+ packed_u32;
+
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ MSBOctetsToPackedU32Word(scanline,packed_u32);
+ *sp++=packed_u32;
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ LSBOctetsToPackedU32Word(scanline,packed_u32);
+ *sp++=packed_u32;
+ }
+ }
+ return;
+ }
+#endif
+
+ /*
+ Packed data.
+ */
+ {
+ ReadWordU32State
+ read_state;
+
+ WordStreamReadHandle
+ read_stream;
+
+ WordStreamReadFunc
+ read_func=0;
+
+ if (endian_type == LSBEndian)
+ read_func=ReadWordU32LE;
+ else
+ read_func=ReadWordU32BE;
+
+ read_state.words=scanline;
+ MagickWordStreamInitializeRead(&read_stream,read_func, (void *) &read_state);
+ for (i=samples_per_row; i != 0; i--)
+ *sp++=MagickWordStreamLSBRead(&read_stream,bits_per_sample);
+ }
+}
+
+/*
+ Apply a simple "Tent" filter to upsample chroma channels.
+*/
+STATIC void TentUpsampleChroma(PixelPacket *pixels, unsigned long columns)
+{
+ unsigned long
+ column;
+
+ for (column = 1; column < columns-2; column += 2)
+ {
+#if QuantumDepth < 32
+ /*
+ Use integer computations if intermediate result will fit.
+ */
+ pixels->green=((unsigned long) pixels[column-1].green + pixels[column+1].green)/2;
+ pixels->blue=((unsigned long) pixels[column-1].blue + pixels[column+1].blue)/2;
+#else
+ /*
+ Use floating point computations.
+ */
+ double
+ result;
+
+ result=((double) pixels[column-1].green + pixels[column+1].green)/2;
+ pixels->green=RoundDoubleToQuantum(result);
+
+ result=((double) pixels[column-1].blue + pixels[column+1].blue)/2;
+ pixels->blue=RoundDoubleToQuantum(result);
+#endif
+ }
+}
+
+#define ThrowDPXReaderException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(map_Y); \
+ MagickFreeMemory(map_CbCr); \
+ if (samples_set) \
+ DestroyThreadViewDataSet(samples_set); \
+ if (scanline_set) \
+ DestroyThreadViewDataSet(scanline_set); \
+ ThrowReaderException(code_,reason_,image_); \
+}
+
+STATIC Image *ReadDPXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ txt_buffer[MaxTextExtent];
+
+ DPXFileInfo
+ dpx_file_info;
+
+ DPXImageInfo
+ dpx_image_info;
+
+ DPXImageSourceInfo
+ dpx_source_info;
+
+ DPXMPFilmInfo
+ dpx_mp_info;
+
+ DPXTVInfo
+ dpx_tv_info;
+
+ Image
+ *image=0;
+
+ long
+ y;
+
+ size_t
+ offset,
+ row_octets;
+
+ Quantum
+ *map_Y=0, /* value translation map (RGB or Y) */
+ *map_CbCr=0; /* value translation map (CbCr) */
+
+ ThreadViewDataSet
+ *samples_set=0;
+
+ ThreadViewDataSet
+ *scanline_set=0;
+
+ size_t
+ element_size; /* Number of bytes in an element */
+
+ unsigned int
+ bits_per_sample, /* number of bits per sample */
+ element, /* current element number */
+ max_bits_per_sample, /* maximum number of bits per sample for any element */
+ max_samples_per_pixel, /* maximum number of samples comprising one pixel for any element */
+ samples_per_pixel, /* number of samples comprising one pixel for this element */
+ samples_per_row; /* number of samples in one row */
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ i,
+ pixels_offset;
+
+ MagickBool
+ is_grayscale=MagickFalse, /* image is grayscale ? */
+ is_monochrome=MagickFalse, /* image is monochrome ? */
+ swap_endian=MagickFalse; /* swap endian order */
+
+ DPXImageElementDescriptor
+ element_descriptor;
+
+ DPXTransferCharacteristic
+ transfer_characteristic;
+
+ ImageComponentPackingMethod
+ packing_method;
+
+ EndianType
+ endian_type;
+
+ const char
+ *definition_value;
+
+ /*
+ Open image file.
+ */
+ assert(sizeof(DPXHeader) == 2048);
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowDPXReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read DPX image.
+ */
+ offset=ReadBlob(image,sizeof(dpx_file_info),&dpx_file_info);
+ if (offset != sizeof(dpx_file_info) ||
+ ((LocaleNCompare((char *) &dpx_file_info.magic,"SDPX",4) != 0) &&
+ (LocaleNCompare((char *) &dpx_file_info.magic,"XPDS",4) != 0)))
+ ThrowDPXReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Check for swapped endian order.
+ */
+ if (dpx_file_info.magic != 0x53445058U)
+ swap_endian=MagickTrue;
+
+#if defined(WORDS_BIGENDIAN)
+ endian_type = (swap_endian ? LSBEndian : MSBEndian);
+#else
+ endian_type = (swap_endian ? MSBEndian : LSBEndian);
+#endif
+
+ /*
+ Save original endian to image so that image write will preserve
+ original endianness.
+ */
+ image->endian = endian_type;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%s endian DPX format",
+ (endian_type == MSBEndian ? "Big" : "Little"));
+
+ if (swap_endian)
+ SwabDPXFileInfo(&dpx_file_info);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File size: %u", dpx_file_info.file_size);
+
+ StringToAttribute(image,"software",dpx_file_info.creator);
+ StringToAttribute(image,"comment",dpx_file_info.project_name);
+ StringToAttribute(image,"copyright",dpx_file_info.copyright);
+ StringToAttribute(image,"document",dpx_file_info.image_filename);
+ /* StringToAttribute(image,"timestamp",dpx_file_info.creation_datetime); */
+
+ StringToAttribute(image,"DPX:file.version",dpx_file_info.header_format_version);
+ StringToAttribute(image,"DPX:file.filename",dpx_file_info.image_filename);
+ StringToAttribute(image,"DPX:file.creation.datetime",dpx_file_info.creation_datetime);
+ StringToAttribute(image,"DPX:file.creator",dpx_file_info.creator);
+ StringToAttribute(image,"DPX:file.project.name",dpx_file_info.project_name);
+ StringToAttribute(image,"DPX:file.copyright",dpx_file_info.copyright);
+ U32ToAttribute(image,"DPX:file.encryption.key",dpx_file_info.encryption_key);
+
+ /*
+ Obtain offset to pixels.
+ */
+ pixels_offset=dpx_file_info.image_data_offset & 0xffffffff;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image data offset %lu",pixels_offset);
+ if (pixels_offset < 1408)
+ ThrowDPXReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (image->logging)
+ {
+ char
+ generic_length_str[MaxTextExtent],
+ industry_length_str[MaxTextExtent],
+ user_length_str[MaxTextExtent];
+
+ if (IS_UNDEFINED_U32(dpx_file_info.generic_section_length))
+ (void) strlcpy(generic_length_str,"UNDEFINED",sizeof(generic_length_str));
+ else
+ FormatString(generic_length_str,"%u",dpx_file_info.generic_section_length);
+
+ if (IS_UNDEFINED_U32(dpx_file_info.industry_section_length))
+ (void) strlcpy(industry_length_str,"UNDEFINED",sizeof(industry_length_str));
+ else
+ FormatString(industry_length_str,"%u",dpx_file_info.industry_section_length);
+
+ if (IS_UNDEFINED_U32(dpx_file_info.user_defined_length))
+ (void) strlcpy(user_length_str,"UNDEFINED",sizeof(user_length_str));
+ else
+ FormatString(user_length_str,"%u",dpx_file_info.user_defined_length);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Generic length %s, Industry length %s, User length %s",
+ generic_length_str,industry_length_str,user_length_str);
+ }
+ /*
+ Read image information header.
+ */
+ offset += ReadBlob(image,sizeof(dpx_image_info),&dpx_image_info);
+ if (offset != (size_t) 1408L)
+ ThrowDPXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (swap_endian)
+ SwabDPXImageInfo(&dpx_image_info);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Pixels per line %u, Lines per image %u, Elements %u",
+ (unsigned int) dpx_image_info.pixels_per_line,
+ (unsigned int) dpx_image_info.lines_per_image_element,
+ (unsigned int) dpx_image_info.elements);
+ if (dpx_image_info.orientation > 7U)
+ ThrowDPXReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (dpx_image_info.elements >
+ sizeof(dpx_image_info.element_info)/sizeof(dpx_image_info.element_info[0]))
+ ThrowDPXReaderException(CorruptImageError,ImproperImageHeader,image);
+ image->columns=dpx_image_info.pixels_per_line & 0xFFFFFFFF;
+ image->rows=dpx_image_info.lines_per_image_element & 0xFFFFFFFF;
+ U16ToAttribute(image,"DPX:image.orientation",dpx_image_info.orientation);
+ image->orientation=DPXOrientationToOrientationType(dpx_image_info.orientation);
+
+ if (pixels_offset >= 1664UL)
+ {
+ /*
+ Read Image source information header.
+ */
+ offset += ReadBlob(image,sizeof(dpx_source_info),&dpx_source_info);
+ if (offset != (size_t) 1664L)
+ ThrowDPXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (swap_endian)
+ SwabDPXImageSourceInfo(&dpx_source_info);
+
+ U32ToAttribute(image,"DPX:source.x-offset",dpx_source_info.x_offset);
+ U32ToAttribute(image,"DPX:source.y-offset",dpx_source_info.y_offset);
+ R32ToAttribute(image,"DPX:source.x-center",dpx_source_info.x_center);
+ R32ToAttribute(image,"DPX:source.y-center",dpx_source_info.y_center);
+ U32ToAttribute(image,"DPX:source.x-original-size",dpx_source_info.x_original_size);
+ U32ToAttribute(image,"DPX:source.y-original-size",dpx_source_info.y_original_size);
+ StringToAttribute(image,"DPX:source.filename",dpx_source_info.source_image_filename);
+ StringToAttribute(image,"DPX:source.creation.datetime",dpx_source_info.source_image_datetime);
+ StringToAttribute(image,"DPX:source.device.name",dpx_source_info.input_device_name);
+ StringToAttribute(image,"DPX:source.device.serialnumber",dpx_source_info.input_device_serialnumber);
+ U16ToAttribute(image,"DPX:source.border.validity.left",dpx_source_info.border_validity.XL);
+ U16ToAttribute(image,"DPX:source.border.validity.right",dpx_source_info.border_validity.XR);
+ U16ToAttribute(image,"DPX:source.border.validity.top",dpx_source_info.border_validity.YT);
+ U16ToAttribute(image,"DPX:source.border.validity.bottom",dpx_source_info.border_validity.YB);
+ U32ToAttribute(image,"DPX:source.aspect.ratio.horizontal",dpx_source_info.aspect_ratio.horizontal);
+ U32ToAttribute(image,"DPX:source.aspect.ratio.vertical",dpx_source_info.aspect_ratio.vertical);
+ R32ToAttribute(image,"DPX:source.scanned.size.x",dpx_source_info.x_scanned_size);
+ R32ToAttribute(image,"DPX:source.scanned.size.y",dpx_source_info.y_scanned_size);
+ }
+ if (pixels_offset >= 1920UL)
+ {
+ /*
+ Read Motion-picture film information header.
+ */
+ offset += ReadBlob(image,sizeof(dpx_mp_info),&dpx_mp_info);
+ if (offset != (size_t) 1920L)
+ ThrowDPXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (swap_endian)
+ SwabDPXMPFilmInfo(&dpx_mp_info);
+
+ if (dpx_file_info.industry_section_length != 0)
+ {
+ StringToAttribute(image,"DPX:mp.film.manufacturer.id",dpx_mp_info.film_mfg_id_code);
+ StringToAttribute(image,"DPX:mp.film.type",dpx_mp_info.film_type);
+ StringToAttribute(image,"DPX:mp.perfs.offset",dpx_mp_info.perfs_offset);
+ StringToAttribute(image,"DPX:mp.prefix",dpx_mp_info.prefix);
+ StringToAttribute(image,"DPX:mp.count",dpx_mp_info.count);
+ StringToAttribute(image,"DPX:mp.format",dpx_mp_info.format);
+ U32ToAttribute(image,"DPX:mp.frame.position",dpx_mp_info.frame_position);
+ U32ToAttribute(image,"DPX:mp.sequence.length",dpx_mp_info.sequence_length);
+ U32ToAttribute(image,"DPX:mp.held.count",dpx_mp_info.held_count);
+ R32ToAttribute(image,"DPX:mp.frame.rate",dpx_mp_info.frame_rate);
+ R32ToAttribute(image,"DPX:mp.shutter.angle",dpx_mp_info.shutter_angle);
+ StringToAttribute(image,"DPX:mp.frame.id",dpx_mp_info.frame_id);
+ StringToAttribute(image,"DPX:mp.slate.info",dpx_mp_info.slate_info);
+ }
+ }
+ if (pixels_offset >= 2048UL)
+ {
+ /*
+ Read Television information header.
+ */
+ offset += ReadBlob(image,sizeof(dpx_tv_info),&dpx_tv_info);
+ if (offset != (size_t) 2048L)
+ ThrowDPXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (swap_endian)
+ SwabDPXTVInfo(&dpx_tv_info);
+
+ if (dpx_file_info.industry_section_length != 0)
+ {
+ U32ToBitsAttribute(image,"DPX:tv.time.code",dpx_tv_info.time_code);
+ U32ToBitsAttribute(image,"DPX:tv.user.bits",dpx_tv_info.user_bits);
+ U8ToAttribute(image,"DPX:tv.interlace",dpx_tv_info.interlace);
+ U8ToAttribute(image,"DPX:tv.field.number",dpx_tv_info.field_number);
+ U8ToAttribute(image,"DPX:tv.video.signal",dpx_tv_info.video_signal);
+ R32ToAttribute(image,"DPX:tv.horizontal.sampling.rate",dpx_tv_info.horizontal_sample);
+ R32ToAttribute(image,"DPX:tv.temporal.sampling.rate",dpx_tv_info.temporal_sample);
+ R32ToAttribute(image,"DPX:tv.sync.time",dpx_tv_info.sync_time);
+ R32ToAttribute(image,"DPX:tv.gamma",dpx_tv_info.gamma);
+ R32ToAttribute(image,"DPX:tv.black.level",dpx_tv_info.black_level);
+ R32ToAttribute(image,"DPX:tv.black.gain",dpx_tv_info.black_gain);
+ R32ToAttribute(image,"DPX:tv.breakpoint",dpx_tv_info.breakpoint);
+ R32ToAttribute(image,"DPX:tv.white.level",dpx_tv_info.white_level);
+ R32ToAttribute(image,"DPX:tv.integration.time",dpx_tv_info.integration_time);
+ }
+ }
+ if (pixels_offset >= 2080UL)
+ {
+ if (!IS_UNDEFINED_U32(dpx_file_info.user_defined_length) &&
+ (dpx_file_info.user_defined_length >= sizeof(DPXUserDefinedData)))
+ {
+ /*
+ Read user header.
+ */
+ unsigned char
+ *user_data;
+
+ const size_t
+ block_size = 65536UL;
+
+ size_t
+ read_size,
+ user_data_length;
+
+ DPXUserDefinedData
+ *dpx_user_data;
+
+ user_data_length=0UL;
+ user_data=(unsigned char *) NULL;
+
+ while (user_data_length < dpx_file_info.user_defined_length)
+ {
+ read_size=Min(block_size,dpx_file_info.user_defined_length-user_data_length);
+ MagickReallocMemory(unsigned char *,user_data,user_data_length+read_size);
+ if (user_data == (unsigned char *) NULL)
+ ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (ReadBlob(image,read_size,user_data+user_data_length) != read_size)
+ ThrowDPXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ user_data_length += read_size;
+ offset += read_size;
+ }
+
+ dpx_user_data=(DPXUserDefinedData *) user_data;
+ StringToAttribute(image,"DPX:user.data.id",dpx_user_data->user_id);
+ if (!SetImageProfile(image,"DPXUSERDATA",user_data,user_data_length))
+ ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ MagickFreeMemory(user_data);
+ }
+ }
+ /*
+ Determine the maximum number of bits per sample, samples per element, and colorspace
+ */
+ max_bits_per_sample=0;
+ max_samples_per_pixel=0;
+ {
+ MagickBool
+ has_cbcr=MagickFalse,
+ has_luma=MagickFalse,
+ has_matte=MagickFalse,
+ has_rgb=MagickFalse;
+
+ DPXColorimetric
+ colorimetric=ColorimetricUserDefined;
+
+ transfer_characteristic=TransferCharacteristicUserDefined;
+ for (element=0; element < dpx_image_info.elements; element++)
+ {
+ if (element == 0)
+ {
+ colorimetric=
+ (DPXColorimetric) dpx_image_info.element_info[element].colorimetric;
+ DPXSetPrimaryChromaticities(colorimetric,&image->chromaticity);
+ }
+ element_descriptor=(DPXImageElementDescriptor)
+ dpx_image_info.element_info[element].descriptor;
+ bits_per_sample=dpx_image_info.element_info[element].bits_per_sample;
+ /*
+ Enforce supported bits per sample. Note that 32-bits could
+ be supported by the implementation but we don't allow it at
+ the moment.
+ */
+ if ((bits_per_sample != 1) &&
+ (bits_per_sample != 8) &&
+ (bits_per_sample != 10) &&
+ (bits_per_sample != 12) &&
+ (bits_per_sample != 16))
+ ThrowDPXReaderException(CorruptImageError,ImproperImageHeader,image);
+ max_bits_per_sample=Max(max_bits_per_sample,bits_per_sample);
+ max_samples_per_pixel=Max(max_samples_per_pixel,
+ DPXSamplesPerPixel(element_descriptor));
+ /*
+ Set image colorspace
+ */
+ switch (element_descriptor)
+ {
+ case ImageElementColorDifferenceCbCr:
+ case ImageElementCbYCrY422:
+ case ImageElementCbYACrYA4224:
+ case ImageElementCbYCr444:
+ case ImageElementCbYCrA4444:
+ {
+ has_cbcr=MagickTrue;
+ colorimetric=(DPXColorimetric) dpx_image_info.element_info[element].colorimetric;
+ transfer_characteristic=(DPXTransferCharacteristic) dpx_image_info.element_info[element].transfer_characteristic;
+ break;
+ }
+ case ImageElementRed:
+ case ImageElementGreen:
+ case ImageElementBlue:
+ case ImageElementRGB:
+ case ImageElementRGBA:
+ case ImageElementABGR:
+ {
+ has_rgb=MagickTrue;
+ colorimetric=(DPXColorimetric) dpx_image_info.element_info[element].colorimetric;
+ transfer_characteristic=(DPXTransferCharacteristic) dpx_image_info.element_info[element].transfer_characteristic;
+ break;
+ }
+ case ImageElementLuma:
+ {
+ has_luma=MagickTrue;
+ colorimetric=(DPXColorimetric) dpx_image_info.element_info[element].colorimetric;
+ transfer_characteristic=(DPXTransferCharacteristic) dpx_image_info.element_info[element].transfer_characteristic;
+ break;
+ }
+ default:
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Unhandled element descriptor: %s",
+ DescribeImageElementDescriptor(txt_buffer,element_descriptor));
+ }
+ }
+
+ /*
+ Check for a matte channel.
+ */
+ switch (element_descriptor)
+ {
+ case ImageElementAlpha:
+ case ImageElementRGBA:
+ case ImageElementABGR:
+ case ImageElementCbYACrYA4224:
+ case ImageElementCbYCrA4444:
+ has_matte=MagickTrue;
+ break;
+ default:
+ break;
+ }
+ }
+ if (has_cbcr)
+ {
+ image->colorspace=Rec709YCbCrColorspace;
+ if ((transfer_characteristic == TransferCharacteristicITU_R601_625L) ||
+ (transfer_characteristic == TransferCharacteristicITU_R601_525L))
+ image->colorspace=Rec601YCbCrColorspace;
+ }
+ else if (has_luma)
+ {
+ image->colorspace=GRAYColorspace;
+ if (transfer_characteristic == TransferCharacteristicITU_R709)
+ image->colorspace=Rec709LumaColorspace;
+ else if ((transfer_characteristic == TransferCharacteristicITU_R601_625L) ||
+ (transfer_characteristic == TransferCharacteristicITU_R601_525L))
+ image->colorspace=Rec601LumaColorspace;
+ }
+ else if (has_rgb)
+ {
+ image->colorspace=RGBColorspace;
+ if (transfer_characteristic == TransferCharacteristicPrintingDensity)
+ image->colorspace=CineonLogRGBColorspace;
+ }
+
+ image->matte=has_matte;
+ }
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image colorspace: %s",
+ ColorspaceTypeToString(image->colorspace));
+ /*
+ Set image depth to maximum bits per sample encountered in any element.
+ */
+ image->depth=max_bits_per_sample;
+ /*
+ Skip reading pixels if ping requested.
+ */
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowDPXReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Validate file size if using a seekable blob
+ */
+ if (BlobIsSeekable(image))
+ {
+ magick_off_t file_size;
+ magick_off_t file_size_estimate = dpx_file_info.image_data_offset;
+
+ /*
+ Verify that file size claimed by header is matched by file size
+ */
+ if ((file_size = GetBlobSize(image)) != 0)
+ {
+ if (file_size < dpx_file_info.file_size)
+ {
+ ThrowDPXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ }
+
+ /*
+ Estimate the required file size and assure that actual file
+ size is at least that size.
+ */
+ for (element=0; element < dpx_image_info.elements; element++)
+ {
+ bits_per_sample=dpx_image_info.element_info[element].bits_per_sample;
+ element_descriptor=(DPXImageElementDescriptor)
+ dpx_image_info.element_info[element].descriptor;
+ transfer_characteristic=
+ (DPXTransferCharacteristic) dpx_image_info.element_info[element].transfer_characteristic;
+ packing_method=(ImageComponentPackingMethod) dpx_image_info.element_info[element].packing;
+ samples_per_pixel=DPXSamplesPerPixel(element_descriptor);
+ samples_per_row=samples_per_pixel*image->columns;
+ element_size=DPXRowOctets(image->rows,samples_per_row,
+ bits_per_sample,packing_method);
+ file_size_estimate += element_size;
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File size estimate %" MAGICK_OFF_F
+ "u bytes (have %" MAGICK_OFF_F "u bytes)",
+ file_size_estimate, file_size);
+ if ((file_size_estimate <= 0) || (file_size < file_size_estimate))
+ ThrowDPXReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ }
+
+ /*
+ Read remainder of header.
+ */
+ for ( ; offset < pixels_offset ; offset++ )
+ if (ReadBlobByte(image) == EOF)
+ ThrowDPXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ /*
+ Allocate sample translation map storage.
+ */
+ map_Y=MagickAllocateArray(Quantum *,
+ MaxValueGivenBits(max_bits_per_sample)+1,
+ sizeof(Quantum));
+ if (map_Y == (Quantum *) NULL)
+ ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ map_CbCr=MagickAllocateArray(Quantum *,
+ MaxValueGivenBits(max_bits_per_sample)+1,
+ sizeof(Quantum));
+ if (map_CbCr == (Quantum *) NULL)
+ ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Allocate per-thread-view row samples.
+ */
+ samples_set=AllocateThreadViewDataArray(image,exception,image->columns,
+ MagickArraySize(max_samples_per_pixel,
+ sizeof(sample_t)));
+ if (samples_set == (ThreadViewDataSet *) NULL)
+ ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Allocate per-thread-view scanline storage.
+ */
+ scanline_set=AllocateThreadViewDataArray(image,exception,image->columns,
+ MagickArraySize(max_samples_per_pixel,
+ sizeof(U32)));
+ if (scanline_set == (ThreadViewDataSet *) NULL)
+ ThrowDPXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Allow user to over-ride pixel endianness.
+ */
+ if ((definition_value=AccessDefinition(image_info,"dpx","pixel-endian")))
+ {
+ if (LocaleCompare(definition_value,"msb") == 0)
+ endian_type=MSBEndian;
+ else if (LocaleCompare(definition_value,"lsb") == 0)
+ endian_type=LSBEndian;
+ }
+ /*
+ Convert DPX raster image to pixel packets.
+ */
+ for (element=0; element < dpx_image_info.elements; element++)
+ {
+ unsigned long
+ row_count=0;
+
+ MagickBool
+ swap_word_datums = MagickFalse;
+
+ DescribeDPXImageElement(&dpx_image_info.element_info[element],element+1);
+ /*
+ Data sign, (0 = unsigned; 1 = signed)
+ */
+ if (dpx_image_info.element_info[element].data_sign != 0)
+ continue;
+ /*
+ Bits per sample must be must be 1 to 16.
+ */
+ if (dpx_image_info.element_info[element].bits_per_sample > 16)
+ continue;
+ /*
+ Move to element data
+ */
+ if (!IS_UNDEFINED_U32(dpx_image_info.element_info[element].data_offset) &&
+ (dpx_image_info.element_info[element].data_offset != 0U))
+ {
+ pixels_offset=dpx_image_info.element_info[element].data_offset & 0xFFFFFFFF;
+ if (pixels_offset >= offset)
+ {
+ /* Data is at, or ahead of current position. Good! */
+ for ( ; offset < pixels_offset ; offset++ )
+ if (ReadBlobByte(image) == EOF)
+ break;
+ }
+ else
+ {
+ /* Data is behind current position. Bad! */
+ offset=SeekBlob(image,(magick_off_t) pixels_offset,SEEK_SET);
+ }
+
+ /* Verify that we reached our offset objective */
+ if ( pixels_offset != offset)
+ ThrowDPXReaderException(BlobError,UnableToSeekToOffset,image);
+ }
+ bits_per_sample=dpx_image_info.element_info[element].bits_per_sample;
+ element_descriptor=(DPXImageElementDescriptor)
+ dpx_image_info.element_info[element].descriptor;
+ transfer_characteristic=
+ (DPXTransferCharacteristic) dpx_image_info.element_info[element].transfer_characteristic;
+ packing_method=(ImageComponentPackingMethod) dpx_image_info.element_info[element].packing;
+ /*
+ Allow the user to over-ride the packing method specified by the header.
+ */
+ if ((definition_value=AccessDefinition(image_info,"dpx","packing-method")))
+ {
+ if (LocaleCompare(definition_value,"packed") == 0)
+ {
+ packing_method=PackingMethodPacked;
+ }
+ else if ((bits_per_sample == 10) || (bits_per_sample == 12))
+ {
+ if ((LocaleCompare(definition_value,"lsbpad") == 0) ||
+ (LocaleCompare(definition_value,"a") == 0))
+ packing_method=PackingMethodWordsFillLSB;
+ else if ((LocaleCompare(definition_value,"msbpad") == 0) ||
+ (LocaleCompare(definition_value,"b") == 0))
+ packing_method=PackingMethodWordsFillMSB;
+ }
+ }
+ /*
+ Decide if the image is grayscale and monochrome.
+ */
+ if (IsGrayColorspace(image->colorspace))
+ {
+ is_grayscale=MagickTrue;
+ }
+ if ((is_grayscale) && (bits_per_sample == 1))
+ {
+ is_monochrome=MagickTrue;
+ }
+ /*
+ Are datums returned in reverse order when extracted from a
+ 32-bit word? This is to support Note 2 in Table 1 which
+ describes how RGB/RGBA are returned in reversed order for the
+ 10-bit "filled" format. Note 3 refers to Note 2 so presumably
+ the same applies for ABGR. The majority of YCbCr 4:2:2 files
+ received have been swapped (but not YCbCr 4:4:4 for some
+ reason) so swap the samples for YCbCr as well.
+ */
+ if ((element_descriptor == ImageElementRGB) ||
+ (element_descriptor == ImageElementRGBA) ||
+ (element_descriptor == ImageElementABGR) ||
+ (element_descriptor == ImageElementCbYCrY422) ||
+ (element_descriptor == ImageElementCbYACrYA4224) ||
+ (element_descriptor == ImageElementCbYCr444) ||
+ (element_descriptor == ImageElementCbYCrA4444))
+ {
+ if ((bits_per_sample == 10) && (packing_method != PackingMethodPacked))
+ swap_word_datums = MagickTrue;
+ }
+ if ((definition_value=AccessDefinition(image_info,"dpx","swap-samples")))
+ {
+ if (LocaleCompare(definition_value,"false") != 0)
+ swap_word_datums = swap_word_datums ? MagickFalse : MagickTrue;
+ }
+ /*
+ Determine number of samples per pixel element.
+ */
+ samples_per_pixel=DPXSamplesPerPixel(element_descriptor);
+ if (samples_per_pixel != 0)
+ {
+ double
+ max_value,
+ reference_low,
+ reference_high,
+ scale_to_quantum; /* multiplier to scale to Quantum */
+
+ max_value = (double) MaxValueGivenBits(bits_per_sample);
+ reference_low = 0.0;
+ reference_high = max_value;
+ scale_to_quantum=MaxRGBDouble/max_value;
+
+ /*
+ Is this a video type space?
+ */
+ if (IsYCbCrColorspace(image->colorspace) ||
+ (image->colorspace == Rec601LumaColorspace) ||
+ (image->colorspace == Rec709LumaColorspace))
+ {
+ double
+ ScaleY = 0.0,
+ ScaleCbCr = 0.0;
+
+ /*
+ Establish YCbCr video defaults.
+ 8 bit ==> Luma 16 to 235
+ 10 bit ==> Luma 64 to 940
+ */
+ reference_low = ((max_value+1.0) * (64.0/1024.0));
+ reference_high = ((max_value+1.0) * (940.0/1024.0));
+
+ if (!IS_UNDEFINED_U32(dpx_image_info.element_info[element].reference_low_data_code))
+ reference_low=dpx_image_info.element_info[element].reference_low_data_code;
+ if ((definition_value=AccessDefinition(image_info,"dpx","reference-low")))
+ reference_low=(double) strtol(definition_value, (char **)NULL, 10);
+
+ if (!IS_UNDEFINED_U32(dpx_image_info.element_info[element].reference_high_data_code))
+ reference_high=dpx_image_info.element_info[element].reference_high_data_code;
+ if ((definition_value=AccessDefinition(image_info,"dpx","reference-high")))
+ reference_high=(double) strtol(definition_value, (char **)NULL, 10);
+
+ ScaleY = ((max_value+1.0)/(reference_high-reference_low));
+ ScaleCbCr = ScaleY*((940.0-64.0)/(960.0-64.0));
+ reference_low=reference_low*scale_to_quantum;
+
+ for(i=0; i <= (unsigned long) max_value; i++)
+ {
+ map_Y[i] = ScaleFromVideo(i*scale_to_quantum,reference_low,ScaleY);
+ map_CbCr[i] = ScaleFromVideo(i*scale_to_quantum,reference_low,ScaleCbCr);
+ }
+ }
+ else
+ {
+ for(i=0; i <= (unsigned long) max_value; i++)
+ map_Y[i]=scale_to_quantum*i+0.5;
+ }
+
+ /*
+ Compute samples per row.
+ */
+ samples_per_row=samples_per_pixel*image->columns;
+ /*
+ Compute octets per row.
+ */
+ row_octets=DPXRowOctets(1,samples_per_row,bits_per_sample,packing_method);
+ if (image->logging)
+ {
+ /*
+ Compute element size.
+ */
+ element_size=DPXRowOctets(image->rows,samples_per_row,
+ bits_per_sample,packing_method);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Samples per row %u, octets per row %lu, element size %lu",
+ samples_per_row, (unsigned long) row_octets,
+ (unsigned long) element_size);
+ }
+ if (((element_descriptor == ImageElementCbYCrY422) ||
+ (element_descriptor == ImageElementCbYACrYA4224) ||
+ (element_descriptor == ImageElementColorDifferenceCbCr)))
+ {
+ /*
+ When subsampling, image width must be evenly divisible by two.
+ */
+ if (image->columns %2)
+ ThrowDPXReaderException(CorruptImageError,SubsamplingRequiresEvenWidth,image);
+ }
+ /*
+ Read element data.
+ */
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime)
+# else
+# pragma omp parallel for schedule(static,1)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ MagickBool
+ thread_status;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ sample_t
+ *samples_itr; /* current sample */
+
+ PixelPacket
+ *pixels=(PixelPacket *) NULL;
+
+ sample_t
+ *samples; /* parsed sample array */
+
+ unsigned char
+ *scanline;
+
+ unsigned long
+ thread_row_count;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ReadDPXImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ samples=AccessThreadViewData(samples_set);
+ scanline=AccessThreadViewData(scanline_set);
+
+ /*
+ Obtain a row's worth of samples.
+ */
+ {
+ void
+ *scanline_data;
+
+ scanline_data=scanline;
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ReadDPXImage)
+#endif
+ {
+ if (ReadBlobZC(image,row_octets,&scanline_data) != row_octets)
+ thread_status=MagickFail;
+
+ thread_row_count=row_count;
+ row_count++;
+ if (QuantumTick(thread_row_count,image->rows))
+ if (!MagickMonitorFormatted(thread_row_count,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ thread_status=MagickFail;
+ }
+
+ if (thread_status != MagickFail)
+ ReadRowSamples((const unsigned char*) scanline_data,samples_per_row,bits_per_sample,
+ packing_method,endian_type,swap_word_datums,samples);
+ }
+
+ if (thread_status != MagickFail)
+ {
+ if (element == 0)
+ pixels=SetImagePixelsEx(image,0,thread_row_count,image->columns,1,exception);
+ else
+ pixels=GetImagePixelsEx(image,0,thread_row_count,image->columns,1,exception);
+ }
+
+ if (pixels == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ {
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ReadDPXImage)
+#endif
+ status=thread_status;
+ continue;
+ }
+
+ /*
+ Assign samples to pixels.
+ */
+ q = pixels;
+ samples_itr=samples;
+ switch (element_descriptor)
+ {
+ case ImageElementRed:
+ for (x=image->columns; x != 0; x--)
+ {
+ SetRedSample(q++,map_Y[*samples_itr++]);
+ }
+ break;
+ case ImageElementGreen:
+ for (x=image->columns; x != 0; x--)
+ {
+ SetGreenSample(q++,map_Y[*samples_itr++]);
+ }
+ break;
+ case ImageElementBlue:
+ for (x=image->columns; x != 0; x--)
+ {
+ SetBlueSample(q++,map_Y[*samples_itr++]);
+ }
+ break;
+ case ImageElementAlpha:
+ for (x=image->columns; x != 0; x--)
+ {
+ SetOpacitySample(q++,map_Y[*samples_itr++]);
+ }
+ break;
+ case ImageElementUnspecified:
+ case ImageElementLuma:
+ if (IsYCbCrColorspace(image->colorspace))
+ {
+ /* Video Luma (planar) */
+ for (x=image->columns; x != 0; x--)
+ {
+ SetRedSample(q,map_Y[*samples_itr++]);
+ q++;
+ }
+ }
+ else
+ {
+ /* Video Luma or Linear Grayscale */
+ for (x=image->columns; x != 0; x--)
+ {
+ SetGraySample(q,map_Y[*samples_itr++]);
+ q++;
+ }
+ }
+ break;
+ case ImageElementColorDifferenceCbCr:
+ {
+ /* CbCr 4:2:2 sampling */
+ for (x=image->columns; x > 0; x -= 2)
+ {
+ Quantum
+ Cb,
+ Cr;
+
+ Cb=map_CbCr[*samples_itr++]; /* Cb */
+ Cr=map_CbCr[*samples_itr++]; /* Cr */
+
+ SetCbSample(q,Cb); /* Cb */
+ SetCrSample(q,Cr); /* Cr */
+ q++;
+
+ SetCbSample(q,Cb); /* Cb (false) */
+ SetCrSample(q,Cr); /* Cr (false) */
+ q++;
+ }
+ TentUpsampleChroma(pixels,image->columns);
+ break;
+ }
+ case ImageElementRGB:
+ /* RGB order */
+ for (x=image->columns; x != 0; x--)
+ {
+ SetRedSample(q,map_Y[*samples_itr++]);
+ SetGreenSample(q,map_Y[*samples_itr++]);
+ SetBlueSample(q,map_Y[*samples_itr++]);
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ case ImageElementRGBA:
+ /* RGB order */
+ for (x=image->columns; x != 0; x--)
+ {
+ SetRedSample(q,map_Y[*samples_itr++]);
+ SetGreenSample(q,map_Y[*samples_itr++]);
+ SetBlueSample(q,map_Y[*samples_itr++]);
+ SetOpacitySample(q,map_Y[*samples_itr++]);
+ q++;
+ }
+ break;
+ case ImageElementABGR:
+ /* ARGB order */
+ for (x=image->columns; x != 0; x--)
+ {
+ SetOpacitySample(q,map_Y[*samples_itr++]);
+ SetRedSample(q,map_Y[*samples_itr++]);
+ SetGreenSample(q,map_Y[*samples_itr++]);
+ SetBlueSample(q,map_Y[*samples_itr++]);
+ q++;
+ }
+ break;
+ case ImageElementCbYCrY422:
+ {
+ /* CbY | CrY | CbY | CrY ..., even number of columns required. */
+ for (x=image->columns; x > 0; x -= 2)
+ {
+ Quantum
+ Cb,
+ Cr,
+ Y0,
+ Y1;
+
+ Cb=map_CbCr[*samples_itr++]; /* Cb */
+ Y0=map_Y[*samples_itr++]; /* Y0 */
+ Cr=map_CbCr[*samples_itr++]; /* Cr */
+ Y1=map_Y[*samples_itr++]; /* Y1 */
+
+ SetYSample(q,Y0); /* Y0 */
+ SetCbSample(q,Cb); /* Cb */
+ SetCrSample(q,Cr); /* Cr */
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+
+ SetYSample(q,Y1); /* Y1 */
+ SetCbSample(q,Cb) ; /* Cb (false) */
+ SetCrSample(q,Cr); /* Cr (false) */
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ TentUpsampleChroma(pixels,image->columns);
+ break;
+ }
+ case ImageElementCbYACrYA4224:
+ {
+ /* CbYA | CrYA ..., even number of columns required. */
+ for (x=image->columns; x > 0; x -= 2)
+ {
+ Quantum
+ A0,
+ A1,
+ Cb,
+ Cr,
+ Y0,
+ Y1;
+
+ Cb=map_CbCr[*samples_itr++];
+ Y0=map_Y[*samples_itr++];
+ A0=map_Y[*samples_itr++];
+
+ Cr=map_CbCr[*samples_itr++];
+ Y1=map_Y[*samples_itr++];
+ A1=map_Y[*samples_itr++];
+
+ SetYSample(q,Y0); /* Y0 */
+ SetCbSample(q,Cb); /* Cb */
+ SetCrSample(q,Cr); /* Cr */
+ SetOpacitySample(q,A0); /* A0 */
+ q++;
+
+ SetYSample(q,Y1); /* Y1 */
+ SetCbSample(q,Cb); /* Cb (false) */
+ SetCrSample(q,Cr); /* Cr (false) */
+ SetOpacitySample(q,A1); /* A1 */
+ q++;
+ }
+ TentUpsampleChroma(pixels,image->columns);
+ break;
+ }
+ case ImageElementCbYCr444:
+ {
+ /* red,green,blue = Y, Cb, Cr */
+ for (x=image->columns; x != 0; x--)
+ {
+ SetCbSample(q,map_CbCr[*samples_itr++]); /* Cb */
+ SetYSample(q,map_Y[*samples_itr++]); /* Y */
+ SetCrSample(q,map_CbCr[*samples_itr++]); /* Cr */
+ SetOpacitySample(q,OpaqueOpacity); /* A */
+ q++;
+ }
+ break;
+ }
+ case ImageElementCbYCrA4444:
+ {
+ /* red,green,blue = Y, Cb, Cr */
+ for (x=image->columns; x != 0; x--)
+ {
+ SetCbSample(q,map_CbCr[*samples_itr++]); /* Cb */
+ SetYSample(q,map_Y[*samples_itr++]); /* Y */
+ SetCrSample(q,map_CbCr[*samples_itr++]); /* Cr */
+ SetOpacitySample(q,map_Y[*samples_itr++]); /* A */
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!SyncImagePixelsEx(image,exception))
+ thread_status=MagickFail;
+
+ /*
+ FIXME: Add support for optional EOL padding.
+ */
+ if (thread_status == MagickFail)
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ReadDPXImage)
+#endif
+ status=MagickFail;
+#if 0
+ if (BlobIsSeekable(image))
+ {
+ magick_off_t reported_file_offset = TellBlob(image);
+ if (EOFBlob(image))
+ {
+ (void) fprintf(stderr,"### File length %u, TellBlob says %" MAGICK_OFF_F "d\n",
+ dpx_file_info.file_size,
+ reported_file_offset);
+ break;
+ }
+ }
+#endif
+ }
+ /* break; */
+ }
+ else
+ {
+ ThrowDPXReaderException(CoderError,ColorTypeNotSupported,image);
+ }
+ }
+
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+
+ /*
+ Support explicitly overriding the input file's colorspace. Mostly
+ useful for testing.
+ */
+ if ((definition_value=AccessDefinition(image_info,"dpx","colorspace")))
+ {
+ ColorspaceType
+ colorspace;
+
+ colorspace=StringToColorspaceType(definition_value);
+ if (colorspace != UndefinedColorspace)
+ {
+ image->colorspace=colorspace;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Explicitly set colorspace to %s",
+ ColorspaceTypeToString(image->colorspace));
+ }
+ else
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Unrecognized source colorspace \"%s\"\n",
+ definition_value);
+ ThrowException(&image->exception,OptionError,UnrecognizedColorspace,
+ definition_value);
+ }
+ }
+
+ /*
+ If image is YCbCr representing Cineon Log RGB, then return the image as
+ RGB in CineonLog colorspace.
+ */
+ if (IsYCbCrColorspace(image->colorspace) &&
+ (transfer_characteristic == TransferCharacteristicPrintingDensity))
+ {
+ (void) TransformColorspace(image,RGBColorspace);
+ image->colorspace=CineonLogRGBColorspace;
+ }
+
+ image->is_monochrome=is_monochrome;
+ image->is_grayscale=is_grayscale;
+ image->depth=Min(QuantumDepth,image->depth);
+ MagickFreeMemory(map_CbCr);
+ MagickFreeMemory(map_Y);
+ DestroyThreadViewDataSet(scanline_set);
+ DestroyThreadViewDataSet(samples_set);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r D P X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterDPXImage adds attributes for the DPX image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterDPXImage method is:
+%
+% RegisterDPXImage(void)
+%
+*/
+ModuleExport void RegisterDPXImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("DPX");
+ entry->decoder=(DecoderHandler) ReadDPXImage;
+ entry->encoder=(EncoderHandler) WriteDPXImage;
+ entry->magick=(MagickHandler) IsDPX;
+ entry->description="SMPTE 268M-2003 (DPX 2.0)";
+ entry->note="See http://www.smtpe.org/ for information on DPX.";
+ entry->module="DPX";
+ entry->adjoin=MagickFalse; /* Only one frame per file */
+ entry->seekable_stream=MagickFalse; /* Does not reqire seek() */
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r D P X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterDPXImage removes format registrations made by the
+% DPX module from the list of supported formats.
+%
+% The format of the UnregisterDPXImage method is:
+%
+% UnregisterDPXImage(void)
+%
+*/
+ModuleExport void UnregisterDPXImage(void)
+{
+ (void) UnregisterMagickInfo("DPX");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e D P X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteDPXImage writes an image in DPX encoded image format.
+%
+% The format of the WriteDPXImage method is:
+%
+% unsigned int WriteDPXImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteDPXImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+STATIC void GenerateDPXTimeStamp(char *timestamp, size_t maxsize)
+{
+ time_t
+ current_time;
+
+ const struct tm
+ *t;
+
+ char *
+ p;
+
+ current_time=time((time_t *) NULL);
+ t=localtime(&current_time);
+
+ (void) strftime(timestamp,maxsize,"%Y:%m:%d:%H:%M:%S%Z",t);
+ timestamp[maxsize-1]='\0';
+ for (p=timestamp ; *p != '\0'; p++)
+ if (*p == ' ')
+ *p='0';
+}
+
+STATIC U16 OrientationTypeToDPXOrientation(const OrientationType orientation_type)
+{
+ U16
+ orientation = 0U;
+
+ switch (orientation_type)
+ {
+ case UndefinedOrientation:
+ case TopLeftOrientation:
+ orientation=0U;
+ break;
+ case TopRightOrientation:
+ orientation=1U;
+ break;
+ case BottomLeftOrientation:
+ orientation=2U;
+ break;
+ case BottomRightOrientation:
+ orientation=3U;
+ break;
+ case LeftTopOrientation:
+ orientation=4U;
+ break;
+ case RightTopOrientation:
+ orientation=5U;
+ break;
+ case LeftBottomOrientation:
+ orientation=6U;
+ break;
+ case RightBottomOrientation:
+ orientation=7U;
+ break;
+ }
+ return orientation;
+}
+
+#define LSBPackedU32WordToOctets(packed_u32,scanline) \
+{ \
+ *scanline++=(unsigned char) ((packed_u32) & 0xFF); \
+ *scanline++=(unsigned char) ((packed_u32 >> 8) & 0xFF); \
+ *scanline++=(unsigned char) ((packed_u32 >> 16) & 0xFF); \
+ *scanline++=(unsigned char) ((packed_u32 >> 24) & 0xFF); \
+}
+#define MSBPackedU32WordToOctets(packed_u32,scanline) \
+{ \
+ *scanline++=(unsigned char) ((packed_u32 >> 24) & 0xFF); \
+ *scanline++=(unsigned char) ((packed_u32 >> 16) & 0xFF); \
+ *scanline++=(unsigned char) ((packed_u32 >> 8) & 0xFF); \
+ *scanline++=(unsigned char) ((packed_u32) & 0xFF); \
+}
+
+/*
+ WordStreamLSBWrite support
+*/
+typedef struct _WriteWordU32State
+{
+ unsigned char *words;
+} WriteWordU32State;
+
+STATIC size_t WriteWordU32BE (void *state, const unsigned long value)
+{
+ WriteWordU32State *write_state=(WriteWordU32State *) state;
+ *write_state->words++ = (unsigned char) ((value >> 24) & 0xff);
+ *write_state->words++ = (unsigned char) ((value >> 16) & 0xff);
+ *write_state->words++ = (unsigned char) ((value >> 8) & 0xff);
+ *write_state->words++ = (unsigned char) (value & 0xff);
+ return sizeof(magick_uint32_t);
+}
+
+STATIC size_t WriteWordU32LE (void *state, const unsigned long value)
+{
+ WriteWordU32State *write_state=(WriteWordU32State *) state;
+ *write_state->words++ = (unsigned char) (value & 0xff);
+ *write_state->words++ = (unsigned char) ((value >> 8) & 0xff);
+ *write_state->words++ = (unsigned char) ((value >> 16) & 0xff);
+ *write_state->words++ = (unsigned char) ((value >> 24) & 0xff);
+ return sizeof(magick_uint32_t);
+}
+
+/*
+ Encode row samples. Currently just one row but in the future may be
+ multiple rows (e.g. 3).
+
+ samples -- unencoded samples (currently unsigned 16-bit).
+ samples_per_row -- Number of samples to encode.
+ bits_per_sample -- Number of bits in one decoded sample.
+ packing_method -- Describes the way that samples are packed into enclosing words.
+ endian_type -- The endian order of the enclosing words.
+ swap_word_datums -- Use alternate sample order (BGR vs RGB, CbYCr vs CrYCb) for
+ samples filled into 32 bit words.
+ scanline -- Raw output data (may be 8-bit, 16-bit, 32-bit, or 64-bit types)
+ which represents the encoded pixels for one or more scanlines.
+ Underlying input data type is properly aligned for access.
+*/
+STATIC void WriteRowSamples(const sample_t *samples,
+ const unsigned int samples_per_row,
+ const unsigned int bits_per_sample,
+ const ImageComponentPackingMethod packing_method,
+ const EndianType endian_type,
+ const MagickBool swap_word_datums,
+ unsigned char *scanline)
+{
+ register unsigned int
+ i;
+
+ BitStreamWriteHandle
+ bit_stream;
+
+ register unsigned char
+ *sp;
+
+ register unsigned int
+ sample;
+
+ sp=scanline;
+ MagickBitStreamInitializeWrite(&bit_stream,scanline);
+
+ if ((packing_method != PackingMethodPacked) &&
+ ((bits_per_sample == 10) || (bits_per_sample == 12)))
+ {
+ MagickBool
+ word_pad_lsb=MagickFalse,
+ word_pad_msb=MagickFalse;
+
+ if (packing_method == PackingMethodWordsFillLSB)
+ word_pad_lsb=MagickTrue;
+ else if (packing_method == PackingMethodWordsFillMSB)
+ word_pad_msb=MagickTrue;
+
+ if (bits_per_sample == 10)
+ {
+ register magick_uint32_t
+ packed_u32;
+
+ register unsigned int
+ datum;
+
+ unsigned int
+ shifts[3] = { 0, 0, 0 };
+
+ if (word_pad_lsb)
+ {
+ /*
+ Padding in LSB (Method A) Standard method.
+ */
+ if (swap_word_datums == MagickFalse)
+ {
+ shifts[0]=2; /* datum-0 / blue */
+ shifts[1]=12; /* datum-1 / green */
+ shifts[2]=22; /* datum-2 / red */
+ }
+ else
+ {
+ shifts[0]=22; /* datum-2 / red */
+ shifts[1]=12; /* datum-1 / green */
+ shifts[2]=2; /* datum-0 / blue */
+ }
+ }
+ else if (word_pad_msb)
+ {
+ /*
+ Padding in MSB (Method B) Deprecated method.
+ */
+ if (swap_word_datums == MagickFalse)
+ {
+ shifts[0]=0; /* datum-0 / blue */
+ shifts[1]=10; /* datum-1 / green */
+ shifts[2]=20; /* datum-2 / red */
+ }
+ else
+ {
+ shifts[0]=20; /* datum-2 / red */
+ shifts[1]=10; /* datum-1 / green */
+ shifts[2]=0; /* datum-0 / blue */
+ }
+ }
+
+ if (endian_type == MSBEndian)
+ {
+ /* Standard specified datum order */
+ for (i=(samples_per_row/3); i != 0; --i)
+ {
+ datum=0;
+ packed_u32=0;
+ packed_u32 |= (*samples++ << shifts[datum++]);
+ packed_u32 |= (*samples++ << shifts[datum++]);
+ packed_u32 |= (*samples++ << shifts[datum]);
+ MSBPackedU32WordToOctets(packed_u32,scanline);
+ }
+ if ((samples_per_row % 3))
+ {
+ datum=0;
+ packed_u32=0;
+ for (i=(samples_per_row % 3); i != 0; --i)
+ packed_u32 |= (*samples++ << shifts[datum++]);
+ MSBPackedU32WordToOctets(packed_u32,scanline);
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ /* Standard specified datum order */
+ for (i=(samples_per_row/3); i != 0; --i)
+ {
+ datum=0;
+ packed_u32=0;
+ packed_u32 |= (*samples++ << shifts[datum++]);
+ packed_u32 |= (*samples++ << shifts[datum++]);
+ packed_u32 |= (*samples++ << shifts[datum]);
+ LSBPackedU32WordToOctets(packed_u32,scanline);
+ }
+ if ((samples_per_row % 3))
+ {
+ datum=0;
+ packed_u32=0;
+ for (i=(samples_per_row % 3); i != 0; --i)
+ packed_u32 |= (*samples++ << shifts[datum++]);
+ LSBPackedU32WordToOctets(packed_u32,scanline);
+ }
+ }
+ return;
+ }
+ else if (bits_per_sample == 12)
+ {
+ if (word_pad_lsb)
+ {
+ /*
+ Padding in LSB (Method A).
+ */
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=*samples++;
+ sample <<= 4;
+ *sp++=(unsigned char) (((unsigned int) sample) >> 8);
+ *sp++=(unsigned char) sample;
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=*samples++;
+ sample <<= 4;
+ *sp++=(unsigned char) sample;
+ *sp++=(unsigned char) (((unsigned int) sample) >> 8);
+ }
+ }
+ }
+ else if (word_pad_msb)
+ {
+ /*
+ Padding in MSB (Method B).
+ */
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=((*samples++) & 0xFFF);
+ *sp++=(unsigned char) (((unsigned int) sample) >> 8);
+ *sp++=(unsigned char) sample;
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ sample=((*samples++) & 0xFFF);
+ *sp++=(unsigned char) sample;
+ *sp++=(unsigned char) (((unsigned int) sample) >> 8);
+ }
+ }
+ }
+ return;
+ }
+ }
+
+ /*
+ Special fast handling for 8-bit images.
+ */
+ if (bits_per_sample == 8)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ *sp++=(unsigned char) *samples++;
+ return;
+ }
+
+ /*
+ Special fast handling for 16-bit images.
+ */
+ if (bits_per_sample == 16)
+ {
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ *sp++=(unsigned char) (((unsigned int) *samples) >> 8);
+ *sp++=(unsigned char) *samples;
+ samples++;
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ *sp++=(unsigned char) *samples;
+ *sp++=(unsigned char) (((unsigned int) *samples) >> 8);
+ samples++;
+ }
+ }
+ return;
+ }
+
+#if 0
+ /*
+ Special fast handling for 32-bit (float) images.
+ */
+ if (bits_per_sample == 32)
+ {
+ register magick_uint32_t
+ packed_u32;
+
+ if (endian_type == MSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ packed_u32=*samples++;
+ MSBPackedU32WordToOctets(packed_u32,scanline);
+ }
+ }
+ else if (endian_type == LSBEndian)
+ {
+ for (i=samples_per_row; i != 0; i--)
+ {
+ packed_u32=*samples++;
+ LSBPackedU32WordToOctets(packed_u32,scanline);
+ }
+ }
+ return;
+ }
+#endif
+
+ /*
+ Packed data.
+ */
+ {
+ WriteWordU32State
+ write_state;
+
+ WordStreamWriteHandle
+ write_stream;
+
+ WordStreamWriteFunc
+ write_func=0;
+
+ if (endian_type == LSBEndian)
+ write_func=WriteWordU32LE;
+ else
+ write_func=WriteWordU32BE;
+
+ write_state.words=scanline;
+ MagickWordStreamInitializeWrite(&write_stream,write_func, (void *) &write_state);
+
+ for (i=samples_per_row; i != 0; i--)
+ MagickWordStreamLSBWrite(&write_stream,bits_per_sample,*samples++);
+
+ MagickWordStreamLSBWriteFlush(&write_stream);
+ }
+}
+
+#define AttributeToU8(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute_; \
+\
+ const char \
+ *definition_value_; \
+\
+ if ((definition_value_=AccessDefinition(image_info,"dpx",key+4))) \
+ member=(U8) strtol(definition_value_, (char **) NULL, 10); \
+ else if ((attribute_=GetImageAttribute(image,key))) \
+ member=(U8) strtol(attribute_->value, (char **) NULL, 10); \
+ else \
+ SET_UNDEFINED_U8(member); \
+}
+
+#define AttributeToU16(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute_; \
+\
+ const char \
+ *definition_value_; \
+\
+ if ((definition_value_=AccessDefinition(image_info,"dpx",key+4))) \
+ member=(U16) strtol(definition_value_, (char **) NULL, 10); \
+ else if ((attribute_=GetImageAttribute(image,key))) \
+ member=(U16) strtol(attribute_->value, (char **) NULL, 10); \
+ else \
+ SET_UNDEFINED_U16(member); \
+}
+
+#define AttributeToU32(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute_; \
+\
+ const char \
+ *definition_value_; \
+\
+ if ((definition_value_=AccessDefinition(image_info,"dpx",key+4))) \
+ member=(U32) strtol(definition_value_, (char **) NULL, 10); \
+ else if ((attribute_=GetImageAttribute(image,key))) \
+ member=(U32) strtol(attribute_->value, (char **) NULL, 10); \
+ else \
+ SET_UNDEFINED_U32(member); \
+}
+
+#define AttributeBitsToU32(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute_; \
+\
+ const char \
+ *definition_value_; \
+\
+ if ((definition_value_=AccessDefinition(image_info,"dpx",key+4))) \
+ member=SMPTEStringToBits(definition_value_); \
+ else if ((attribute_=GetImageAttribute(image,key))) \
+ member=SMPTEStringToBits(attribute_->value); \
+ else \
+ SET_UNDEFINED_U32(member); \
+}
+
+#define AttributeToR32(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute_; \
+\
+ const char \
+ *definition_value_; \
+\
+ if ((definition_value_=AccessDefinition(image_info,"dpx",key+4))) \
+ member.f=strtod(definition_value_, (char **) NULL); \
+ else if ((attribute_=GetImageAttribute(image,key))) \
+ member.f=strtod(attribute_->value, (char **) NULL); \
+ else \
+ SET_UNDEFINED_R32(member); \
+}
+
+/*
+ This macro uses strncpy on purpose. The string is not required to
+ be null terminated, but any unused space should be filled with
+ nulls. Don't even think about using strlcpy here because some ASCII
+ fields occupy the full space.
+*/
+#define AttributeToString(image_info,image,key,member) \
+{ \
+ const ImageAttribute \
+ *attribute_; \
+\
+ const char \
+ *definition_value_; \
+\
+ if ((definition_value_=AccessDefinition(image_info,"dpx",key+4))) \
+ (void) strncpy(member,definition_value_,sizeof(member)); \
+ else if ((attribute_=GetImageAttribute(image,key))) \
+ (void) strncpy(member,attribute_->value,sizeof(member)); \
+ else \
+ SET_UNDEFINED_ASCII(member); \
+}
+
+/*
+ Round an offset up to specified offset boundary.
+*/
+#define RoundUpToBoundary(offset,boundary) \
+ (((offset+boundary-1)/boundary)*boundary);
+
+#define ThrowDPXWriterException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(map_CbCr); \
+ MagickFreeMemory(map_Y); \
+ MagickFreeMemory(samples); \
+ MagickFreeMemory(scanline); \
+ if (chroma_image) \
+ DestroyImage(chroma_image); \
+ ThrowWriterException(code_,reason_,image_); \
+}
+
+STATIC unsigned int WriteDPXImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ txt_buffer[MaxTextExtent];
+
+ DPXFileInfo
+ dpx_file_info;
+
+ DPXImageInfo
+ dpx_image_info;
+
+ DPXImageSourceInfo
+ dpx_source_info;
+
+ DPXMPFilmInfo
+ dpx_mp_info;
+
+ DPXTVInfo
+ dpx_tv_info;
+
+ DPXImageElementDescriptor
+ element_descriptor;
+
+ ImageComponentPackingMethod
+ packing_method;
+
+ DPXTransferCharacteristic
+ transfer_characteristic;
+
+ Image
+ *chroma_image=0;
+
+ unsigned long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned long
+ i,
+ x;
+
+ sample_t
+ *samples=0,
+ *samples_itr;
+
+ sample_t
+ *map_Y=0, /* value translation map (RGB or Y) */
+ *map_CbCr=0; /* value translation map (CbCr) */
+
+ unsigned char
+ *scanline=0;
+
+ const unsigned char
+ *user_data;
+
+ unsigned int
+ bits_per_sample=0,
+ element,
+ sampling_factor_horizontal,
+ sampling_factor_vertical,
+ max_samples_per_pixel,
+ image_data_offset,
+ number_of_elements,
+ row_samples,
+ samples_per_component,
+ samples_per_pixel,
+ samples_per_row,
+ status;
+
+ MagickBool
+ swap_endian;
+
+ size_t
+ element_size;
+
+ const char *
+ definition_value;
+
+ size_t
+ offset=0,
+ row_octets,
+ user_data_length=0;
+
+ EndianType
+ endian_type;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Support user-selection of big/little endian output.
+ */
+ endian_type=MSBEndian;
+#if defined(WORDS_BIGENDIAN)
+ swap_endian=MagickFalse;
+ if (image_info->endian == LSBEndian)
+ {
+ swap_endian=MagickTrue;
+ endian_type=LSBEndian;
+ }
+#else
+ swap_endian=MagickTrue;
+ if (image_info->endian == LSBEndian)
+ {
+ swap_endian=MagickFalse;
+ endian_type=LSBEndian;
+ }
+#endif
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%s endian DPX format",
+ (endian_type == MSBEndian ? "Big" : "Little"));
+
+ /*
+ Adjust image colorspace if necessary.
+ */
+ if ((image_info->colorspace == CineonLogRGBColorspace) &&
+ (image->colorspace != CineonLogRGBColorspace))
+ (void) TransformColorspace(image,CineonLogRGBColorspace);
+ else if ((image_info->colorspace == Rec601LumaColorspace) &&
+ (image->colorspace != Rec601LumaColorspace))
+ (void) TransformColorspace(image,Rec601LumaColorspace);
+ else if ((image_info->colorspace == Rec601YCbCrColorspace) &&
+ (image->colorspace != Rec601YCbCrColorspace))
+ (void) TransformColorspace(image,Rec601YCbCrColorspace);
+ else if ((image_info->colorspace == YCbCrColorspace) &&
+ (image->colorspace != Rec601YCbCrColorspace))
+ (void) TransformColorspace(image,Rec601YCbCrColorspace);
+ else if ((image_info->colorspace == Rec709LumaColorspace) &&
+ (image->colorspace != Rec709LumaColorspace))
+ (void) TransformColorspace(image,Rec709LumaColorspace);
+ else if ((image_info->colorspace == Rec709YCbCrColorspace) &&
+ (image->colorspace != Rec709YCbCrColorspace))
+ (void) TransformColorspace(image,Rec709YCbCrColorspace);
+ else if (IsRGBColorspace(image_info->colorspace) &&
+ !IsRGBColorspace(image->colorspace))
+ (void) TransformColorspace(image,RGBColorspace);
+ else if (!IsRGBColorspace(image->colorspace) &&
+ (image->colorspace != CineonLogRGBColorspace) &&
+ (image->colorspace != Rec601YCbCrColorspace) &&
+ (image->colorspace != Rec709YCbCrColorspace))
+ (void) TransformColorspace(image,RGBColorspace);
+
+ /*
+ Compute desired/necessary number of bits per sample.
+ */
+ if ((definition_value=AccessDefinition(image_info,"dpx","bits-per-sample")))
+ bits_per_sample=MagickAtoI(definition_value);
+
+ if (bits_per_sample == 0)
+ {
+ if (image->depth > 12 )
+ bits_per_sample=16;
+ else if (image->depth > 10)
+ bits_per_sample=12;
+ else if (image->depth > 8)
+ bits_per_sample=10;
+ else if (image->depth > 1)
+ bits_per_sample=8;
+ else
+ bits_per_sample=1;
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Bits per sample: %u", bits_per_sample);
+
+ /*
+ Obtain requested sampling factors.
+ */
+ sampling_factor_horizontal=2;
+ sampling_factor_vertical=2;
+ if (image_info->sampling_factor != (char *) NULL)
+ {
+ long
+ factors;
+
+ factors=sscanf(image_info->sampling_factor,"%ux%u",&sampling_factor_horizontal,
+ &sampling_factor_vertical);
+ if (factors != 2)
+ sampling_factor_vertical=sampling_factor_horizontal;
+ if ((sampling_factor_horizontal != 1) && (sampling_factor_horizontal != 2) &&
+ (sampling_factor_vertical != 1) && (sampling_factor_vertical != 2))
+ ThrowDPXWriterException(OptionError,UnsupportedSamplingFactor,
+ image);
+
+ /*
+ When subsampling, image width must be evenly divisible by two.
+ */
+ if (((sampling_factor_horizontal / sampling_factor_vertical) == 2) &&
+ (image->columns %2))
+ ThrowDPXWriterException(CoderError,SubsamplingRequiresEvenWidth,image);
+ }
+
+ /*
+ Intuit the samples per component and the number of elements.
+ */
+ if (IsYCbCrColorspace(image->colorspace))
+ {
+ if ((image_info->interlace == PlaneInterlace) &&
+ ((sampling_factor_horizontal / sampling_factor_vertical) == 2))
+ {
+ /* YCbCr 4:2:2 planar */
+ samples_per_component=1;
+ number_of_elements=2;
+ if (image->matte)
+ number_of_elements++;
+ }
+ else
+ {
+ if ((sampling_factor_horizontal / sampling_factor_vertical) == 2)
+ {
+ /* YCbCr 4:2:2 */
+ samples_per_component=2;
+ }
+ else
+ {
+ /* YCbCr 4:4:4 */
+ samples_per_component=3;
+ }
+ number_of_elements=1;
+ if (image->matte)
+ samples_per_component++;
+ }
+ }
+ else if (IsGrayColorspace(image->colorspace))
+ {
+ samples_per_component=1;
+ number_of_elements=1;
+ if (image->matte)
+ number_of_elements++;
+ }
+ else
+ {
+ if (image_info->interlace == PlaneInterlace)
+ {
+ samples_per_component=1;
+ number_of_elements=3;
+ if (image->matte)
+ number_of_elements++;
+ }
+ else
+ {
+ samples_per_component=3;
+ number_of_elements=1;
+ if (image->matte)
+ samples_per_component++;
+ }
+ }
+
+ /*
+ Choose the default packing method.
+ */
+ if ((bits_per_sample == 10) || (bits_per_sample == 12))
+ packing_method=PackingMethodWordsFillLSB;
+ else
+ packing_method=PackingMethodPacked;
+
+ /*
+ Allow the user to over-ride the default packing method.
+ */
+ if ((definition_value=AccessDefinition(image_info,"dpx","packing-method")))
+ {
+ if (LocaleCompare(definition_value,"packed") == 0)
+ {
+ packing_method=PackingMethodPacked;
+ }
+ else if ((bits_per_sample == 10) || (bits_per_sample == 12))
+ {
+ if ((LocaleCompare(definition_value,"lsbpad") == 0) ||
+ (LocaleCompare(definition_value,"a") == 0))
+ packing_method=PackingMethodWordsFillLSB;
+ else if ((LocaleCompare(definition_value,"msbpad") == 0) ||
+ (LocaleCompare(definition_value,"b") == 0))
+ packing_method=PackingMethodWordsFillMSB;
+ }
+ }
+
+ row_samples=((magick_int64_t) image->columns*samples_per_component);
+ row_octets=DPXRowOctets(1,row_samples,bits_per_sample,packing_method);
+ element_size=DPXRowOctets(image->rows,row_samples,bits_per_sample,packing_method);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Samples per row %u, octets per row %lu, element size %lu",
+ row_samples, (unsigned long) row_octets,
+ (unsigned long) element_size);
+ /*
+ Obtain pointer to user data and user data length (if available).
+ */
+ user_data=GetImageProfile(image,"DPXUSERDATA",&user_data_length);
+
+ /*
+ Image information header
+ */
+ (void) memset(&dpx_image_info,0,sizeof(dpx_image_info));
+ /* Image orientation */
+ dpx_image_info.orientation=OrientationTypeToDPXOrientation(image->orientation);
+ /* Number of image elements described. */
+ dpx_image_info.elements=number_of_elements;
+ /* Number of pixels per line. */
+ dpx_image_info.pixels_per_line=image->columns;
+ /* Number of lines per image element. */
+ dpx_image_info.lines_per_image_element=image->rows;
+ /* Image sample sign. */
+ dpx_image_info.element_info[0].data_sign=0; /* Unsigned data */
+
+ /* Colorimetic specification. Define the appropriate color reference
+ primaries (for additive color systems like television) or color
+ responses (for printing density). */
+ /* Reference low data code. For printing density the default is 0
+ but for ITU-R 601-5 luma, the default is 16 */
+ /* Reference low quantity represented. For printing density the
+ default is a density of 0.00. For ITU-R 601-5, the luma default
+ is 0 mv */
+ /* Reference high data code value. Defines maximum expected code
+ value for image data. For 10-bit printing density, the default
+ code value is 1023. */
+ /* Reference high quantity represented. For printing density, the
+ default is a density of 2.048. For ITU-R 601-5 luma, the default
+ is 700 mv. */
+ SET_UNDEFINED_U8(dpx_image_info.element_info[0].transfer_characteristic);
+ SET_UNDEFINED_U8(dpx_image_info.element_info[0].colorimetric);
+ SET_UNDEFINED_U8(dpx_image_info.element_info[0].reference_low_data_code);
+ SET_UNDEFINED_R32(dpx_image_info.element_info[0].reference_low_quantity);
+ SET_UNDEFINED_U32(dpx_image_info.element_info[0].reference_high_data_code);
+ SET_UNDEFINED_R32(dpx_image_info.element_info[0].reference_high_quantity);
+
+ if (image->colorspace == CineonLogRGBColorspace)
+ {
+ transfer_characteristic=TransferCharacteristicPrintingDensity;
+ }
+ else if ((image->colorspace == YCbCrColorspace) ||
+ (image->colorspace == Rec601YCbCrColorspace) ||
+ (image->colorspace == Rec601LumaColorspace))
+ {
+ if (image->rows > 525)
+ transfer_characteristic=TransferCharacteristicITU_R601_625L;
+ else
+ transfer_characteristic=TransferCharacteristicITU_R601_525L;
+ }
+ else if ((image->colorspace == Rec709YCbCrColorspace) ||
+ (image->colorspace == Rec709LumaColorspace))
+ {
+ transfer_characteristic=TransferCharacteristicITU_R709;
+ }
+ else
+ {
+ transfer_characteristic=TransferCharacteristicLinear;
+ }
+
+ /* Transfer characteristic. Define the amplitude transfer function
+ necessary to transform the data to a linear original. */
+ dpx_image_info.element_info[0].transfer_characteristic=transfer_characteristic;
+
+ if (transfer_characteristic == TransferCharacteristicPrintingDensity)
+ {
+ /* Printing density is a log encoding */
+ dpx_image_info.element_info[0].colorimetric=ColorimetricPrintingDensity;
+ dpx_image_info.element_info[0].reference_low_data_code=0;
+ dpx_image_info.element_info[0].reference_high_data_code=
+ MaxValueGivenBits(bits_per_sample);
+ dpx_image_info.element_info[0].reference_low_quantity.f=0.00F;
+ dpx_image_info.element_info[0].reference_high_quantity.f=2.047F;
+ }
+ else if ((transfer_characteristic == TransferCharacteristicUnspecifiedVideo) ||
+ (transfer_characteristic == TransferCharacteristicSMTPE274M) ||
+ (transfer_characteristic == TransferCharacteristicITU_R709) ||
+ (transfer_characteristic == TransferCharacteristicITU_R601_625L) ||
+ (transfer_characteristic == TransferCharacteristicITU_R601_525L) ||
+ (transfer_characteristic == TransferCharacteristicNTSCCompositeVideo) ||
+ (transfer_characteristic == TransferCharacteristicPALCompositeVideo))
+ {
+ /*
+ Some sort of video.
+ */
+ unsigned int
+ max_value_given_bits = MaxValueGivenBits(bits_per_sample);
+
+ switch (transfer_characteristic)
+ {
+ case TransferCharacteristicSMTPE274M:
+ dpx_image_info.element_info[0].colorimetric=ColorimetricSMTPE274M;
+ break;
+ case TransferCharacteristicITU_R709:
+ dpx_image_info.element_info[0].colorimetric=ColorimetricITU_R709;
+ break;
+ case TransferCharacteristicITU_R601_625L:
+ dpx_image_info.element_info[0].colorimetric=ColorimetricITU_R601_625L;
+ break;
+ case TransferCharacteristicITU_R601_525L:
+ dpx_image_info.element_info[0].colorimetric=ColorimetricITU_R601_525L;
+ break;
+ case TransferCharacteristicNTSCCompositeVideo:
+ dpx_image_info.element_info[0].colorimetric=ColorimetricNTSCCompositeVideo;
+ break;
+ case TransferCharacteristicPALCompositeVideo:
+ dpx_image_info.element_info[0].colorimetric=ColorimetricPALCompositeVideo;
+ break;
+ default:
+ dpx_image_info.element_info[0].colorimetric=ColorimetricUserDefined;
+ break;
+ }
+
+ dpx_image_info.element_info[0].reference_low_data_code= /* 16 for 8 bits */
+ (U32) (max_value_given_bits * (16.0/255.0) + 0.5);
+ dpx_image_info.element_info[0].reference_high_data_code= /* 235 for 8 bits */
+ (U32) (max_value_given_bits * (235.0/255.0) + 0.5);
+ dpx_image_info.element_info[0].reference_low_quantity.f=0.00F; /* 0mv */
+ dpx_image_info.element_info[0].reference_high_quantity.f=0.700F; /* 700mv */
+ }
+ else if (transfer_characteristic == TransferCharacteristicLinear)
+ {
+ /* Otherwise we are using linear encoding */
+ dpx_image_info.element_info[0].colorimetric=ColorimetricLinear;
+ dpx_image_info.element_info[0].reference_low_data_code=0;
+ dpx_image_info.element_info[0].reference_high_data_code=
+ MaxValueGivenBits(bits_per_sample);
+ }
+
+ /*
+ Compute image data offset. Should be rounded up to next 8K block.
+ */
+ image_data_offset=2048;
+ if (user_data)
+ image_data_offset += (unsigned int) user_data_length;
+ image_data_offset=RoundUpToBoundary(image_data_offset,IMAGE_DATA_ROUNDING);
+
+ /* Element Descriptor */
+ SET_UNDEFINED_U8(dpx_image_info.element_info[0].descriptor);
+ /* Number of bits per sample */
+ dpx_image_info.element_info[0].bits_per_sample=bits_per_sample;
+ /* Packing method */
+ dpx_image_info.element_info[0].packing=0;
+ if ((bits_per_sample == 10) || (bits_per_sample == 12))
+ dpx_image_info.element_info[0].packing=packing_method;
+ /* Encoding. Unencoded or run length encoded */
+ dpx_image_info.element_info[0].encoding=0; /* No encoding */
+ /* Offset to element data from beginning of file. */
+ dpx_image_info.element_info[0].data_offset=image_data_offset;
+ /* Number of padded bytes at the end of each line */
+ dpx_image_info.element_info[0].eol_pad=0;
+ /* Number of padded bytes at the end of image element. */
+ dpx_image_info.element_info[0].eoi_pad=0;
+ /* Element description */
+ SET_UNDEFINED_ASCII(dpx_image_info.element_info[0].description);
+
+ for (i=1; i < number_of_elements; i++)
+ {
+ /* Clone settings from preceding element */
+ dpx_image_info.element_info[i]=dpx_image_info.element_info[i-1];
+ /* Compute offset to data */
+ dpx_image_info.element_info[i].data_offset=
+ dpx_image_info.element_info[i-1].data_offset+(U32) element_size;
+ }
+
+ /*
+ Fill out element descriptor.
+ */
+ if (number_of_elements > 1)
+ {
+ /*
+ Planar image configuration.
+ */
+ if (IsGrayColorspace(image->colorspace))
+ {
+ /* Luma with alpha channel in second plane */
+ dpx_image_info.element_info[0].descriptor=ImageElementLuma;
+ dpx_image_info.element_info[1].descriptor=ImageElementAlpha;
+ }
+ else if (IsRGBColorspace(image->colorspace) ||
+ (image->colorspace == CineonLogRGBColorspace))
+ {
+ /* RGB Planar */
+ dpx_image_info.element_info[0].descriptor=ImageElementRed;
+ dpx_image_info.element_info[1].descriptor=ImageElementGreen;
+ dpx_image_info.element_info[2].descriptor=ImageElementBlue;
+ if ((image->matte) && (number_of_elements == 4))
+ {
+ dpx_image_info.element_info[3].descriptor=ImageElementAlpha;
+ }
+ }
+ else if (IsYCbCrColorspace(image->colorspace))
+ {
+ /* YCbCr 4:2:2 planar */
+ dpx_image_info.element_info[0].descriptor=ImageElementLuma;
+ dpx_image_info.element_info[1].descriptor=ImageElementColorDifferenceCbCr;
+ if (image->matte)
+ dpx_image_info.element_info[2].descriptor=ImageElementAlpha;
+ }
+ }
+ else
+ {
+ if (IsYCbCrColorspace(image->colorspace))
+ {
+ /* CbYCr */
+ if (samples_per_component == 2)
+ {
+ /* CbYCr 4:2:2 */
+ dpx_image_info.element_info[0].descriptor=image->matte ?
+ ImageElementCbYACrYA4224 : ImageElementCbYCrY422;
+ }
+ else
+ {
+ /* CbYCr 4:4:4 */
+ dpx_image_info.element_info[0].descriptor=image->matte ?
+ ImageElementCbYCrA4444 : ImageElementCbYCr444;
+ }
+ }
+ else if (IsGrayColorspace(image->colorspace))
+ {
+ /* Luma */
+ dpx_image_info.element_info[0].descriptor=ImageElementLuma;
+ }
+ else if (IsRGBColorspace(image->colorspace) ||
+ (image->colorspace == CineonLogRGBColorspace))
+ {
+ /* RGB */
+ dpx_image_info.element_info[0].descriptor=image->matte ?
+ ImageElementRGBA : ImageElementRGB;
+ }
+ }
+
+ /*
+ Add a textual description for each element.
+ */
+ for (i=0; i < number_of_elements; i++)
+ {
+ (void) strlcpy(dpx_image_info.element_info[i].description,
+ DescribeImageElementDescriptor(txt_buffer,
+ (DPXImageElementDescriptor) dpx_image_info.element_info[i].descriptor),
+ sizeof(dpx_image_info.element_info[0].description));
+ (void) strlcat(dpx_image_info.element_info[i].description," / ",
+ sizeof(dpx_image_info.element_info[0].description));
+ (void) strlcat(dpx_image_info.element_info[i].description,
+ DescribeImageTransferCharacteristic(txt_buffer,
+ (DPXTransferCharacteristic) dpx_image_info.element_info[i].transfer_characteristic),
+ sizeof(dpx_image_info.element_info[0].description));
+ }
+
+ /*
+ File information header.
+ */
+ (void) memset(&dpx_file_info,0,sizeof(dpx_file_info));
+ dpx_file_info.magic=0x53445058U;
+ dpx_file_info.image_data_offset=dpx_image_info.element_info[0].data_offset;
+ (void) strlcpy(dpx_file_info.header_format_version,"V2.0",
+ sizeof(dpx_file_info.header_format_version));
+ dpx_file_info.file_size=
+ dpx_file_info.image_data_offset+number_of_elements*(U32) element_size;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Estimated file length: %u",dpx_file_info.file_size);
+ dpx_file_info.ditto_key=1; /* new frame */
+ dpx_file_info.generic_section_length=sizeof(dpx_file_info)+
+ sizeof(dpx_image_info)+sizeof(dpx_source_info);
+ dpx_file_info.industry_section_length=sizeof(dpx_mp_info)+sizeof(dpx_tv_info);
+ dpx_file_info.user_defined_length=(U32) (user_data ? user_data_length : 0);
+ (void) strlcpy(dpx_file_info.image_filename,image->filename,
+ sizeof(dpx_file_info.image_filename));
+ GenerateDPXTimeStamp(dpx_file_info.creation_datetime,
+ sizeof(dpx_file_info.creation_datetime));
+#if 0 /* To enable use of original file creator. */
+ AttributeToString(image_info,image,"DPX:file.creator",dpx_file_info.creator);
+ if (dpx_file_info.creator[0] == '\0')
+#endif
+ (void) strlcpy(dpx_file_info.creator,GetMagickVersion((unsigned long *) NULL),
+ sizeof(dpx_file_info.creator));
+ AttributeToString(image_info,image,"DPX:file.project.name",dpx_file_info.project_name);
+ AttributeToString(image_info,image,"DPX:file.copyright",dpx_file_info.copyright);
+ AttributeToU32(image_info,image,"DPX:file.encryption.key",dpx_file_info.encryption_key);
+ /*
+ Image source information header
+ */
+ (void) memset(&dpx_source_info,0,sizeof(dpx_source_info));
+ SET_UNDEFINED_U32(dpx_source_info.x_offset);
+ SET_UNDEFINED_U32(dpx_source_info.y_offset);
+ SET_UNDEFINED_R32(dpx_source_info.x_center);
+ SET_UNDEFINED_R32(dpx_source_info.y_center);
+ SET_UNDEFINED_U32(dpx_source_info.x_original_size);
+ SET_UNDEFINED_U32(dpx_source_info.y_original_size);
+ if ((image->rows == image->magick_rows) && (image->columns == image->magick_columns))
+ {
+ /* If image size has not changed from original (magick_columns
+ and magick_rows contain original size), then preserve any
+ existing source image dimension and offset information. If
+ size has changed, then information may be wrong. */
+ AttributeToU32(image_info,image,"DPX:source.x-offset",dpx_source_info.x_offset);
+ AttributeToU32(image_info,image,"DPX:source.y-offset",dpx_source_info.y_offset);
+ AttributeToR32(image_info,image,"DPX:source.x-center",dpx_source_info.x_center);
+ AttributeToR32(image_info,image,"DPX:source.y-center",dpx_source_info.y_center);
+ AttributeToU32(image_info,image,"DPX:source.x-original-size",dpx_source_info.x_original_size);
+ AttributeToU32(image_info,image,"DPX:source.y-original-size",dpx_source_info.y_original_size);
+ }
+ AttributeToString(image_info,image,"DPX:source.filename",dpx_source_info.source_image_filename);
+ if (IS_UNDEFINED_ASCII(dpx_source_info.source_image_filename))
+ (void) strlcpy(dpx_source_info.source_image_filename,image->magick_filename,
+ sizeof(dpx_source_info.source_image_filename));
+ AttributeToString(image_info,image,"DPX:source.creation.datetime",dpx_source_info.source_image_datetime);
+ AttributeToString(image_info,image,"DPX:source.device.name",dpx_source_info.input_device_name);
+ AttributeToString(image_info,image,"DPX:source.device.serialnumber",dpx_source_info.input_device_serialnumber);
+ AttributeToU16(image_info,image,"DPX:source.border.validity.left",dpx_source_info.border_validity.XL);
+ AttributeToU16(image_info,image,"DPX:source.border.validity.right",dpx_source_info.border_validity.XR);
+ AttributeToU16(image_info,image,"DPX:source.border.validity.top",dpx_source_info.border_validity.YT);
+ AttributeToU16(image_info,image,"DPX:source.border.validity.bottom",dpx_source_info.border_validity.YB);
+ AttributeToU32(image_info,image,"DPX:source.aspect.ratio.horizontal",dpx_source_info.aspect_ratio.horizontal);
+ AttributeToU32(image_info,image,"DPX:source.aspect.ratio.vertical",dpx_source_info.aspect_ratio.vertical);
+ AttributeToR32(image_info,image,"DPX:source.scanned.size.x",dpx_source_info.x_scanned_size);
+ AttributeToR32(image_info,image,"DPX:source.scanned.size.y",dpx_source_info.y_scanned_size);
+ /*
+ Motion-picture film information header.
+ */
+ (void) memset(&dpx_mp_info,0,sizeof(dpx_mp_info));
+ AttributeToString(image_info,image,"DPX:mp.film.manufacturer.id",dpx_mp_info.film_mfg_id_code);
+ AttributeToString(image_info,image,"DPX:mp.film.type",dpx_mp_info.film_type);
+ AttributeToString(image_info,image,"DPX:mp.perfs.offset",dpx_mp_info.perfs_offset);
+ AttributeToString(image_info,image,"DPX:mp.prefix",dpx_mp_info.prefix);
+ AttributeToString(image_info,image,"DPX:mp.count",dpx_mp_info.count);
+ AttributeToString(image_info,image,"DPX:mp.format",dpx_mp_info.format);
+ AttributeToU32(image_info,image,"DPX:mp.frame.position",dpx_mp_info.frame_position);
+ AttributeToU32(image_info,image,"DPX:mp.sequence.length",dpx_mp_info.sequence_length);
+ AttributeToU32(image_info,image,"DPX:mp.held.count",dpx_mp_info.held_count);
+ AttributeToR32(image_info,image,"DPX:mp.frame.rate",dpx_mp_info.frame_rate);
+ AttributeToR32(image_info,image,"DPX:mp.shutter.angle",dpx_mp_info.shutter_angle);
+ AttributeToString(image_info,image,"DPX:mp.frame.id",dpx_mp_info.frame_id);
+ AttributeToString(image_info,image,"DPX:mp.slate.info",dpx_mp_info.slate_info);
+ /*
+ Television information header.
+ */
+ (void) memset(&dpx_tv_info,0,sizeof(dpx_tv_info));
+ AttributeBitsToU32(image_info,image,"DPX:tv.time.code",dpx_tv_info.time_code);
+ AttributeBitsToU32(image_info,image,"DPX:tv.user.bits",dpx_tv_info.user_bits);
+ AttributeToU8(image_info,image,"DPX:tv.interlace",dpx_tv_info.interlace);
+ AttributeToU8(image_info,image,"DPX:tv.field.number",dpx_tv_info.field_number);
+ AttributeToU8(image_info,image,"DPX:tv.video.signal",dpx_tv_info.video_signal);
+ AttributeToR32(image_info,image,"DPX:tv.horizontal.sampling.rate",dpx_tv_info.horizontal_sample);
+ AttributeToR32(image_info,image,"DPX:tv.temporal.sampling.rate",dpx_tv_info.temporal_sample);
+ AttributeToR32(image_info,image,"DPX:tv.sync.time",dpx_tv_info.sync_time);
+ AttributeToR32(image_info,image,"DPX:tv.gamma",dpx_tv_info.gamma);
+ AttributeToR32(image_info,image,"DPX:tv.black.level",dpx_tv_info.black_level);
+ AttributeToR32(image_info,image,"DPX:tv.black.gain",dpx_tv_info.black_gain);
+ AttributeToR32(image_info,image,"DPX:tv.breakpoint",dpx_tv_info.breakpoint);
+ AttributeToR32(image_info,image,"DPX:tv.white.level",dpx_tv_info.white_level);
+ AttributeToR32(image_info,image,"DPX:tv.integration.time",dpx_tv_info.integration_time);
+ /*
+ Determine the maximum number of samples required for any element.
+ */
+ max_samples_per_pixel=0;
+ for (element=0; element < dpx_image_info.elements; element++)
+ {
+ element_descriptor=(DPXImageElementDescriptor)
+ dpx_image_info.element_info[element].descriptor;
+ max_samples_per_pixel=Max(max_samples_per_pixel,
+ DPXSamplesPerPixel(element_descriptor));
+ }
+ /*
+ Allocate row samples.
+ */
+ samples=MagickAllocateArray(sample_t *,image->columns,
+ max_samples_per_pixel*sizeof(sample_t));
+ if (samples == (sample_t *) NULL)
+ ThrowDPXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) memset((void *) samples,0,max_samples_per_pixel*image->columns*
+ sizeof(sample_t));
+ /*
+ Allocate row scanline.
+ */
+ scanline=MagickAllocateMemory(unsigned char *,row_octets);
+ if (scanline == (unsigned char *) NULL)
+ ThrowDPXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) memset((void *) scanline,0,row_octets);
+
+ /*
+ Allocate sample translation map storage.
+ */
+ map_Y=MagickAllocateArray(sample_t *,MaxMap+1,sizeof(sample_t));
+ if (map_Y == (sample_t *) NULL)
+ ThrowDPXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) memset((void *) map_Y,0,(MaxMap+1)*sizeof(sample_t));
+
+ map_CbCr=MagickAllocateArray(sample_t *,MaxMap+1,sizeof(sample_t));
+ if (map_CbCr == (sample_t *) NULL)
+ ThrowDPXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) memset((void *) map_CbCr,0,(MaxMap+1)*sizeof(sample_t));
+
+ /*
+ Reserve file/blob length if requested.
+ */
+ {
+ const char
+ *env;
+
+ if (((env=getenv("MAGICK_RESERVE_STORAGE")) != NULL) &&
+ (LocaleCompare(env,"TRUE") == 0))
+ (void) BlobReserveSize(image,dpx_file_info.file_size);
+ }
+
+ /*
+ Write file headers.
+ */
+ if (swap_endian)
+ {
+ /*
+ Swap byte order.
+ */
+ SwabDPXFileInfo(&dpx_file_info);
+ SwabDPXImageInfo(&dpx_image_info);
+ SwabDPXImageSourceInfo(&dpx_source_info);
+ SwabDPXMPFilmInfo(&dpx_mp_info);
+ SwabDPXTVInfo(&dpx_tv_info);
+ }
+ offset += WriteBlob(image,sizeof(dpx_file_info),&dpx_file_info);
+ offset += WriteBlob(image,sizeof(dpx_image_info),&dpx_image_info);
+ offset += WriteBlob(image,sizeof(dpx_source_info),&dpx_source_info);
+ offset += WriteBlob(image,sizeof(dpx_mp_info),&dpx_mp_info);
+ offset += WriteBlob(image,sizeof(dpx_tv_info),&dpx_tv_info);
+ if (user_data)
+ {
+ offset += WriteBlob(image,(size_t) user_data_length,user_data);
+ }
+ if (swap_endian)
+ {
+ /*
+ Swap byte order back to original.
+ */
+ SwabDPXFileInfo(&dpx_file_info);
+ SwabDPXImageInfo(&dpx_image_info);
+ SwabDPXImageSourceInfo(&dpx_source_info);
+ SwabDPXMPFilmInfo(&dpx_mp_info);
+ SwabDPXTVInfo(&dpx_tv_info);
+ }
+ /*
+ Fill to offset.
+ */
+ while (offset < dpx_image_info.element_info[0].data_offset)
+ {
+ if (WriteBlobByte(image,0U) != 1)
+ break;
+ offset += 1;
+ }
+ /*
+ Allow user to over-ride pixel endianness.
+ */
+ if ((definition_value=AccessDefinition(image_info,"dpx","pixel-endian")))
+ {
+ if (LocaleCompare(definition_value,"msb") == 0)
+ endian_type=MSBEndian;
+ else if (LocaleCompare(definition_value,"lsb") == 0)
+ endian_type=LSBEndian;
+ }
+ /*
+ Write out elements.
+ */
+ for (element=0; element < dpx_image_info.elements; element++)
+ {
+ MagickBool
+ swap_word_datums = MagickFalse;
+
+
+ /*
+ Validate that what we are writing matches the header offsets.
+ */
+ {
+ magick_off_t
+ reported_file_offset;
+
+ if (((reported_file_offset = TellBlob(image)) != -1) &&
+ ((magick_off_t) dpx_image_info.element_info[element].data_offset !=
+ reported_file_offset))
+ {
+ (void) fprintf(stderr,"### Descriptor %u offset %u, TellBlob says %" MAGICK_OFF_F "d\n",
+ element+1, dpx_image_info.element_info[element].data_offset,
+ reported_file_offset);
+ }
+ }
+ DescribeDPXImageElement(&dpx_image_info.element_info[element],element+1);
+
+ bits_per_sample=dpx_image_info.element_info[element].bits_per_sample;
+ transfer_characteristic=(DPXTransferCharacteristic)
+ dpx_image_info.element_info[element].transfer_characteristic;
+
+ {
+ double
+ max_value,
+ reference_low,
+ reference_high,
+ scale_from_maxmap; /* multiplier to scale from MaxMap */
+
+ max_value = (double) MaxValueGivenBits(bits_per_sample);
+ reference_low = 0.0;
+ reference_high = max_value;
+ scale_from_maxmap=max_value/((double) MaxMap);
+
+ if ((transfer_characteristic == TransferCharacteristicITU_R709) ||
+ (transfer_characteristic == TransferCharacteristicITU_R601_625L) ||
+ (transfer_characteristic == TransferCharacteristicITU_R601_525L))
+ {
+ double
+ ScaleY = 0.0,
+ ScaleCbCr = 0.0;
+
+ reference_low = ((MaxRGBDouble+1.0)*(64.0/1024.0));
+ reference_high = ((MaxRGBDouble+1.0)*(940.0/1024.0));
+ ScaleY = (reference_high-reference_low)/(MaxRGBDouble+1.0);
+ ScaleCbCr = ScaleY*((960.0-64.0)/(940.0-64.0));
+
+ for (i=0; i <= MaxMap ; i++)
+ {
+ map_Y[i]=(i*ScaleY+reference_low)*scale_from_maxmap+0.5;
+ map_CbCr[i]=(i*ScaleCbCr+reference_low)*scale_from_maxmap+0.5;
+ }
+ }
+ else
+ {
+ for (i=0; i <= MaxMap ; i++)
+ map_Y[i]=i*scale_from_maxmap+0.5;
+ }
+ }
+
+ element_descriptor=(DPXImageElementDescriptor)
+ dpx_image_info.element_info[element].descriptor;
+
+ /*
+ Determine component packing method.
+ */
+ packing_method=(ImageComponentPackingMethod) dpx_image_info.element_info[element].packing;
+ samples_per_pixel=DPXSamplesPerPixel(element_descriptor);
+ samples_per_row=samples_per_pixel*image->columns;
+
+ /*
+ Are datums returned in reverse order when extracted from a
+ 32-bit word? This is to support Note 2 in Table 1 which
+ describes how RGB/RGBA are returned in reversed order for the
+ 10-bit "filled" format. Note 3 refers to Note 2 so presumably
+ the same applies for ABGR. The majority of YCbCr 4:2:2 files
+ received have been swapped (but not YCbCr 4:4:4 for some
+ reason) so swap the samples for YCbCr as well.
+ */
+ if ((element_descriptor == ImageElementRGB) ||
+ (element_descriptor == ImageElementRGBA) ||
+ (element_descriptor == ImageElementABGR) ||
+ (element_descriptor == ImageElementCbYCrY422) ||
+ (element_descriptor == ImageElementCbYACrYA4224) ||
+ (element_descriptor == ImageElementCbYCr444) ||
+ (element_descriptor == ImageElementCbYCrA4444))
+ {
+ if ((bits_per_sample == 10) && (packing_method != PackingMethodPacked))
+ swap_word_datums = MagickTrue;
+ }
+ if ((definition_value=AccessDefinition(image_info,"dpx","swap-samples")))
+ {
+ if (LocaleCompare(definition_value,"false") != 0)
+ swap_word_datums = swap_word_datums ? MagickFalse : MagickTrue;
+ }
+
+ /*
+ Create a chroma image if we are subsampling YCbCr.
+ */
+ if (((element_descriptor == ImageElementCbYCrY422) ||
+ (element_descriptor == ImageElementCbYACrYA4224) ||
+ (element_descriptor == ImageElementColorDifferenceCbCr)) &&
+ (chroma_image == (Image *) NULL))
+ {
+ chroma_image=ResizeImage(image,image->columns/2,image->rows,
+ LanczosFilter,1.0,&image->exception);
+ if (chroma_image == (Image *) NULL)
+ ThrowDPXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+
+ samples_itr=samples;
+ /*
+ Prepare row samples.
+ */
+ switch (element_descriptor)
+ {
+ case ImageElementRed:
+ for (x=image->columns; x != 0; x--)
+ {
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetRedSample(p))];
+ p++;
+ }
+ break;
+ case ImageElementGreen:
+ for (x=image->columns; x != 0; x--)
+ {
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetGreenSample(p))];
+ p++;
+ }
+ break;
+ case ImageElementBlue:
+ for (x=image->columns; x != 0; x--)
+ {
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetBlueSample(p))];
+ p++;
+ }
+ break;
+ case ImageElementAlpha:
+ {
+ for (x=image->columns; x != 0; x--)
+ {
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetOpacitySample(p))];
+ p++;
+ }
+ break;
+ }
+ case ImageElementUnspecified:
+ case ImageElementLuma:
+ {
+ if ((transfer_characteristic == TransferCharacteristicITU_R709) ||
+ (transfer_characteristic == TransferCharacteristicITU_R601_625L) ||
+ (transfer_characteristic == TransferCharacteristicITU_R601_525L))
+ {
+ /* Video luma */
+ for (x=image->columns; x != 0; x--)
+ {
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetYSample(p))];
+ p++;
+ }
+ }
+ else
+ {
+ /* Linear gray */
+ for (x=image->columns; x != 0; x--)
+ {
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetGraySample(p))];
+ p++;
+ }
+ }
+ break;
+ }
+ case ImageElementColorDifferenceCbCr:
+ {
+ /* CbCr */
+ const PixelPacket
+ *chroma_pixels;
+
+ chroma_pixels=AcquireImagePixels(chroma_image,0,y,chroma_image->columns,1,
+ &image->exception);
+ if (chroma_pixels == (const PixelPacket *) NULL)
+ break;
+
+ for (x=image->columns; x != 0; x -= 2)
+ {
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCbSample(chroma_pixels))]; /* Cb */
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCrSample(chroma_pixels))]; /* Cr */
+ chroma_pixels++;
+ }
+ break;
+ }
+ case ImageElementRGB:
+ for (x=image->columns; x != 0; x--)
+ {
+#if 0
+ /* BGR */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetBlueSample(p))];
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetGreenSample(p))];
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetRedSample(p))];
+#else
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetRedSample(p))];
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetGreenSample(p))];
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetBlueSample(p))];
+#endif
+ p++;
+ }
+ break;
+ case ImageElementRGBA:
+ for (x=image->columns; x != 0; x--)
+ {
+#if 0
+ /* BGRA */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetBlueSample(p))];
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetGreenSample(p))];
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetRedSample(p))];
+#else
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetRedSample(p))];
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetGreenSample(p))];
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetBlueSample(p))];
+#endif
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetOpacitySample(p))];
+ p++;
+ }
+ break;
+ case ImageElementCbYCrY422:
+ {
+ /* CbY | CrY | CbY | CrY ..., even number of columns required. */
+ const PixelPacket
+ *chroma_pixels;
+
+ chroma_pixels=AcquireImagePixels(chroma_image,0,y,chroma_image->columns,1,
+ &image->exception);
+ if (chroma_pixels == (const PixelPacket *) NULL)
+ break;
+
+ for (x=image->columns; x != 0; x -= 2)
+ {
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCbSample(chroma_pixels))]; /* Cb */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetYSample(p))]; /* Y */
+ p++;
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCrSample(chroma_pixels))]; /* Cr */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetYSample(p))]; /* Y */
+ p++;
+ chroma_pixels++;
+ }
+ break;
+ }
+ case ImageElementCbYACrYA4224:
+ {
+ /* CbYA | CrYA | CbYA | CrYA ..., even number of columns required. */
+ const PixelPacket
+ *chroma_pixels;
+
+ chroma_pixels=AcquireImagePixels(chroma_image,0,y,chroma_image->columns,1,
+ &image->exception);
+ if (chroma_pixels == (const PixelPacket *) NULL)
+ break;
+
+ for (x=image->columns; x != 0; x -= 2)
+ {
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCbSample(chroma_pixels))]; /* Cb */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetYSample(p))]; /* Y */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetOpacitySample(p))]; /* A */
+ p++;
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCrSample(chroma_pixels))]; /* Cr */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetYSample(p))]; /* Y */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetOpacitySample(p))]; /* A */
+ p++;
+ chroma_pixels++;
+ }
+ break;
+ }
+ case ImageElementCbYCr444:
+ for (x=image->columns; x != 0; x--)
+ {
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCbSample(p))]; /* Cb */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetYSample(p))]; /* Y */
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCrSample(p))]; /* Cr */
+ p++;
+ }
+ break;
+ case ImageElementCbYCrA4444:
+ for (x=image->columns; x != 0; x--)
+ {
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCbSample(p))]; /* Cb */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetYSample(p))]; /* Y */
+ *samples_itr++=map_CbCr[ScaleQuantumToMap(GetCrSample(p))]; /* Cr */
+ *samples_itr++=map_Y[ScaleQuantumToMap(GetOpacitySample(p))]; /* A */
+ p++;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ FIXME: RLE samples.
+ */
+
+ /*
+ Output samples.
+ */
+ WriteRowSamples(samples, samples_per_row, bits_per_sample,
+ packing_method,endian_type,swap_word_datums,scanline);
+ if (WriteBlob(image,row_octets,(void *) scanline) != row_octets)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+
+ /*
+ Validate that what we are writing matches the header offsets.
+ */
+ {
+ magick_off_t
+ reported_file_offset;
+
+ reported_file_offset = TellBlob(image);
+ if ((reported_file_offset != -1) &&
+ ((magick_off_t) dpx_file_info.file_size != reported_file_offset))
+ {
+ (void) fprintf(stderr,"### File length %u, TellBlob says %" MAGICK_OFF_F "d\n",
+ dpx_file_info.file_size,
+ reported_file_offset);
+ }
+ }
+
+ MagickFreeMemory(map_CbCr);
+ MagickFreeMemory(map_Y);
+ MagickFreeMemory(samples);
+ MagickFreeMemory(scanline);
+ CloseBlob(image);
+ if (chroma_image != (Image *) NULL)
+ {
+ DestroyImage(chroma_image);
+ chroma_image = (Image *) NULL;
+ }
+ return(status);
+}
diff --git a/coders/emf.c b/coders/emf.c
new file mode 100644
index 0000000..1ddc5aa
--- /dev/null
+++ b/coders/emf.c
@@ -0,0 +1,482 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% EEEEE M M FFFFF %
+% E MM MM F %
+% EEE M M M FFF %
+% E M M F %
+% EEEEE M M F %
+% %
+% %
+% Read Windows Enahanced Metafile Format. %
+% %
+% %
+% Software Design %
+% Bill Radcliffe %
+% 2001 %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+
+/*
+ * Include declarations.
+ */
+
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+#if defined(HasWINGDI32)
+# if defined(__CYGWIN__)
+# include <windows.h>
+# else
+ /* All MinGW needs ... */
+# include <wingdi.h>
+# endif
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d E M F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadEMFImage reads an Microsoft Windows Enhanced MetaFile (EMF) or
+% Windows MetaFile (WMF) file using the Windows API and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadEMFImage method is:
+%
+% Image *ReadEMFImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadEMFImage returns a pointer to the image after
+% reading. A null image is returned if there is a a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: The image info..
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+/*
+ This method reads either an enhanced metafile, a regular 16bit Windows
+ metafile, or an Aldus Placeable metafile and converts it into an enhanced
+ metafile. Width and height are returned in .01mm units.
+*/
+#if defined(HasWINGDI32)
+static HENHMETAFILE ReadEnhMetaFile(const char *szFileName,long *width,
+ long *height)
+{
+#pragma pack( push, 2 )
+ typedef struct
+ {
+ DWORD dwKey;
+ WORD hmf;
+ SMALL_RECT bbox;
+ WORD wInch;
+ DWORD dwReserved;
+ WORD wCheckSum;
+ } APMHEADER, *PAPMHEADER;
+#pragma pack( pop )
+
+ DWORD
+ dwSize;
+
+ ENHMETAHEADER
+ emfh;
+
+ HANDLE
+ hFile;
+
+ HDC
+ hDC;
+
+ HENHMETAFILE
+ hTemp;
+
+ LPBYTE
+ pBits;
+
+ METAFILEPICT
+ mp;
+
+ HMETAFILE
+ hOld;
+
+ *width=512;
+ *height=512;
+ hTemp=GetEnhMetaFile(szFileName);
+ if (hTemp != (HENHMETAFILE) NULL)
+ {
+ /*
+ Enhanced metafile.
+ */
+ GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh);
+ *width=emfh.rclFrame.right-emfh.rclFrame.left;
+ *height=emfh.rclFrame.bottom-emfh.rclFrame.top;
+ return(hTemp);
+ }
+ hOld=GetMetaFile(szFileName);
+ if (hOld != (HMETAFILE) NULL)
+ {
+ /*
+ 16bit windows metafile.
+ */
+ dwSize=GetMetaFileBitsEx(hOld,0,NULL);
+ if (dwSize == 0)
+ {
+ DeleteMetaFile(hOld);
+ return((HENHMETAFILE) NULL);
+ }
+ pBits=MagickAllocateMemory(LPBYTE,dwSize);
+ if (pBits == (LPBYTE) NULL)
+ {
+ DeleteMetaFile(hOld);
+ return((HENHMETAFILE) NULL);
+ }
+ if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0)
+ {
+ MagickFreeMemory(pBits);
+ DeleteMetaFile(hOld);
+ return((HENHMETAFILE) NULL);
+ }
+ /*
+ Make an enhanced metafile from the windows metafile.
+ */
+ mp.mm=MM_ANISOTROPIC;
+ mp.xExt=1000;
+ mp.yExt=1000;
+ mp.hMF=NULL;
+ hDC=GetDC(NULL);
+ hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp);
+ ReleaseDC(NULL,hDC);
+ DeleteMetaFile(hOld);
+ MagickFreeMemory(pBits);
+ GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh);
+ *width=emfh.rclFrame.right-emfh.rclFrame.left;
+ *height=emfh.rclFrame.bottom-emfh.rclFrame.top;
+ return(hTemp);
+ }
+ /*
+ Aldus Placeable metafile.
+ */
+ hFile=CreateFile(szFileName,GENERIC_READ,0,NULL,OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return(NULL);
+ dwSize=GetFileSize(hFile,NULL);
+ pBits=MagickAllocateMemory(LPBYTE,dwSize);
+ ReadFile(hFile,pBits,dwSize,&dwSize,NULL);
+ CloseHandle(hFile);
+ if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l)
+ {
+ MagickFreeMemory(pBits);
+ return((HENHMETAFILE) NULL);
+ }
+ /*
+ Make an enhanced metafile from the placable metafile.
+ */
+ mp.mm=MM_ANISOTROPIC;
+ mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left;
+ *width=mp.xExt;
+ mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch);
+ mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top;
+ *height=mp.yExt;
+ mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch);
+ mp.hMF=NULL;
+ hDC=GetDC(NULL);
+ hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp);
+ ReleaseDC(NULL,hDC);
+ MagickFreeMemory(pBits);
+ return(hTemp);
+}
+
+#define CENTIMETERS_INCH 2.54
+
+static Image *ReadEMFImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ BITMAPINFO
+ DIBinfo;
+
+ HBITMAP
+ hBitmap,
+ hOldBitmap;
+
+ HDC
+ hDC;
+
+ HENHMETAFILE
+ hemf;
+
+ Image
+ *image;
+
+ long
+ height,
+ width,
+ y;
+
+ RECT
+ rect;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ RGBQUAD
+ *pBits,
+ *ppBits;
+
+ image=AllocateImage(image_info);
+ hemf=ReadEnhMetaFile(image_info->filename,&width,&height);
+ if (!hemf)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if ((image->columns == 0) || (image->rows == 0))
+ {
+ double
+ y_resolution = 72.0,
+ x_resolution = 72.0;
+
+ if (image->y_resolution > 0)
+ {
+ y_resolution=image->y_resolution;
+ if (image->units == PixelsPerCentimeterResolution)
+ y_resolution*=CENTIMETERS_INCH;
+ }
+ if (image->x_resolution > 0)
+ {
+ x_resolution=image->x_resolution;
+ if (image->units == PixelsPerCentimeterResolution)
+ x_resolution*=CENTIMETERS_INCH;
+ }
+ image->rows=ceil((height*CENTIMETERS_INCH)/1000*y_resolution);
+ image->columns=ceil((width*CENTIMETERS_INCH)/1000*x_resolution);
+ }
+ if (image_info->size != (char *) NULL)
+ {
+ long
+ x;
+
+ image->columns=width;
+ image->rows=height;
+ x=0;
+ y=0;
+ (void) GetGeometry(image_info->size,&x,&y,&image->columns,&image->rows);
+ }
+ if (image_info->page != (char *) NULL)
+ {
+ char
+ *geometry;
+
+ long
+ sans;
+
+ register char
+ *p;
+
+/* unsigned int */
+/* flags; */
+
+ geometry=GetPageGeometry(image_info->page);
+ p=strchr(geometry,'>');
+ if (!p)
+ {
+ /*flags=*/ (void) GetMagickGeometry(geometry,&sans,&sans,&image->columns,
+ &image->rows);
+ if (image->x_resolution != 0.0)
+ image->columns=(unsigned int)
+ ((image->columns*image->x_resolution)+0.5);
+ if (image->y_resolution != 0.0)
+ image->rows=(unsigned int)
+ ((image->rows*image->y_resolution)+0.5);
+ }
+ else
+ {
+ *p='\0';
+ /*flags=*/ (void) GetMagickGeometry(geometry,&sans,&sans,&image->columns,
+ &image->rows);
+ if (image->x_resolution != 0.0)
+ image->columns=(unsigned int)
+ (((image->columns*image->x_resolution)/72.0)+0.5);
+ if (image->y_resolution != 0.0)
+ image->rows=(unsigned int)
+ (((image->rows*image->y_resolution)/72.0)+0.5);
+ }
+ MagickFreeMemory(geometry);
+ }
+ hDC=GetDC(NULL);
+ if (!hDC)
+ ThrowReaderException(CoderError,UnableToCreateADC,image);
+ /*
+ Initialize the bitmap header info.
+ */
+ (void) memset(&DIBinfo,0,sizeof(BITMAPINFO));
+ DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ DIBinfo.bmiHeader.biWidth=image->columns;
+ DIBinfo.bmiHeader.biHeight=(-1)*image->rows;
+ DIBinfo.bmiHeader.biPlanes=1;
+ DIBinfo.bmiHeader.biBitCount=32;
+ DIBinfo.bmiHeader.biCompression=BI_RGB;
+ hBitmap=
+ CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits,NULL,0);
+ ReleaseDC(NULL,hDC);
+ if (!hBitmap)
+ ThrowReaderException(CoderError,UnableToCreateBitmap,image);
+ hDC=CreateCompatibleDC(NULL);
+ if (!hDC)
+ {
+ DeleteObject(hBitmap);
+ ThrowReaderException(CoderError,UnableToCreateADC,image);
+ }
+ hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap);
+ if (!hOldBitmap)
+ {
+ DeleteDC(hDC);
+ DeleteObject(hBitmap);
+ ThrowReaderException(CoderError,UnableToCreateBitmap,image);
+ }
+ /*
+ Initialize the bitmap to the image background color.
+ */
+ pBits=ppBits;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pBits->rgbRed=ScaleQuantumToChar(image->background_color.red);
+ pBits->rgbGreen=ScaleQuantumToChar(image->background_color.green);
+ pBits->rgbBlue=ScaleQuantumToChar(image->background_color.blue);
+ pBits++;
+ }
+ }
+ rect.top=0;
+ rect.left=0;
+ rect.right=image->columns;
+ rect.bottom=image->rows;
+ /*
+ Convert metafile pixels.
+ */
+ PlayEnhMetaFile(hDC,hemf,&rect);
+ pBits=ppBits;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(pBits->rgbRed);
+ q->green=ScaleCharToQuantum(pBits->rgbGreen);
+ q->blue=ScaleCharToQuantum(pBits->rgbBlue);
+ q->opacity=OpaqueOpacity;
+ pBits++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ if (hemf)
+ DeleteEnhMetaFile(hemf);
+ SelectObject(hDC,hOldBitmap);
+ DeleteDC(hDC);
+ DeleteObject(hBitmap);
+ return(image);
+}
+#endif /* HasWINGDI32 */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r E M F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterEMFImage adds attributes for the EMF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterEMFImage method is:
+%
+% RegisterEMFImage(void)
+%
+*/
+ModuleExport void RegisterEMFImage(void)
+{
+#if defined(HasWINGDI32)
+ MagickInfo
+ *entry;
+
+ entry = SetMagickInfo("EMF");
+ entry->decoder=ReadEMFImage;
+ entry->description="Windows WIN32 API rendered Enhanced Meta File";
+ entry->blob_support=False;
+ entry->module="WMF";
+ (void) RegisterMagickInfo(entry);
+
+ entry = SetMagickInfo("WMFWIN32");
+ entry->decoder=ReadEMFImage;
+ entry->description="Windows WIN32 API rendered Meta File";
+ entry->blob_support=False;
+ entry->module="WMFWIN32";
+ (void) RegisterMagickInfo(entry);
+#endif /* HasWINGDI32 */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r E M F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterEMFImage removes format registrations made by the
+% EMF module from the list of supported formats.
+%
+% The format of the UnregisterEMFImage method is:
+%
+% UnregisterEMFImage(void)
+%
+*/
+ModuleExport void UnregisterEMFImage(void)
+{
+#if defined(HasWINGDI32)
+ (void) UnregisterMagickInfo("EMF");
+ (void) UnregisterMagickInfo("WMFWIN32");
+#endif /* HasWINGDI32 */
+}
diff --git a/coders/ept.c b/coders/ept.c
new file mode 100644
index 0000000..54bd376
--- /dev/null
+++ b/coders/ept.c
@@ -0,0 +1,709 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% EEEEE PPPP TTTTT %
+% E P P T %
+% EEE PPPP T %
+% E P T %
+% EEEEE P T %
+% %
+% %
+% Read/Write Encapsulated Postscript Format (with preview). %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/render.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteEPTImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s E P T %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsEPT returns True if the image format type, identified by the
+% magick string, is EPT.
+%
+% The format of the IsEPT method is:
+%
+% unsigned int IsEPT(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsEPT returns True if the image format type is EPT.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsEPT(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (memcmp(magick,"\305\320\323\306",4) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d E P T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadEPTImage reads a binary Adobe Postscript image file and returns
+% it. It allocates the memory necessary for the new Image structure and
+% returns a pointer to the new image.
+%
+% The format of the ReadEPTImage method is:
+%
+% Image *ReadEPTImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadEPTImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadEPTImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+#define BoundingBox "%%BoundingBox:"
+#define DocumentMedia "%%DocumentMedia:"
+#define PageBoundingBox "%%PageBoundingBox:"
+#define PostscriptLevel "%!PS-"
+#define RenderPostscriptText "[%s] Rendering postscript..."
+
+ char
+ density[MaxTextExtent],
+ command[MaxTextExtent],
+ filename[MaxTextExtent],
+ geometry[MaxTextExtent],
+ postscript_filename[MaxTextExtent],
+ translate_geometry[MaxTextExtent];
+
+ const DelegateInfo
+ *delegate_info;
+
+ double
+ dx_resolution,
+ dy_resolution;
+
+ FILE
+ *file;
+
+ Image
+ *image,
+ *next_image;
+
+ int
+ c,
+ status;
+
+ unsigned int
+ antialias=4;
+
+ ExtendedSignedIntegralType
+ filesize;
+
+ RectangleInfo
+ box,
+ page;
+
+ register char
+ *p;
+
+ register long
+ i;
+
+ SegmentInfo
+ bounds;
+
+ size_t
+ count;
+
+ unsigned long
+ height,
+ width;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ /*
+ Select Postscript delegate driver
+ */
+ delegate_info=GetPostscriptDelegateInfo(image_info,&antialias,exception);
+ if (delegate_info == (const DelegateInfo *) NULL)
+ return((Image *) NULL);
+ /*
+ Open image file.
+ */
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Set the page geometry.
+ */
+ dx_resolution=72.0;
+ dy_resolution=72.0;
+ if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0))
+ {
+ (void) strlcpy(density,PSDensityGeometry,sizeof(density));
+ count=GetMagickDimension(density,&image->x_resolution,
+ &image->y_resolution,NULL,NULL);
+ if (count != 2)
+ image->y_resolution=image->x_resolution;
+ }
+ FormatString(density,"%gx%g",image->x_resolution,image->y_resolution);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Density: %s", density);
+ SetGeometry(image,&page);
+ page.width=612;
+ page.height=792;
+ (void) GetGeometry(PSPageGeometry,&page.x,&page.y,&page.width,&page.height);
+ /*
+ Determine page geometry from the Postscript bounding box.
+ */
+ (void) ReadBlobLSBLong(image);
+ count=ReadBlobLSBLong(image);
+ filesize=ReadBlobLSBLong(image);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File Size: %lu, Offset: %lu",
+ (unsigned long) filesize, (unsigned long) count);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ for (i=0; i < (long) (count-12); i++)
+ if (ReadBlobByte(image) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ /*
+ Open temporary output file.
+ */
+ file=AcquireTemporaryFileStream(postscript_filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ ThrowReaderTemporaryFileException(postscript_filename);
+ FormatString(translate_geometry,"%g %g translate\n ",0.0,0.0);
+ (void) fputs(translate_geometry,file);
+ /*
+ Copy Postscript to temporary file.
+ */
+ box.width=0;
+ box.height=0;
+ p=command;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Copying Postscript to temporary file \"%s\" ...",
+ postscript_filename);
+ for (i=0; i < (long) filesize; i++)
+ {
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ (void) fputc(c,file);
+ *p++=c;
+ if ((c != '\n') && (c != '\r') && ((p-command) < (MaxTextExtent-1)))
+ continue;
+ *p='\0';
+ p=command;
+ /*
+ Parse a bounding box statement.
+ */
+ count=0;
+ if (LocaleNCompare(BoundingBox,command,strlen(BoundingBox)) == 0)
+ count=sscanf(command,"%%%%BoundingBox: %lf %lf %lf %lf",&bounds.x1,
+ &bounds.y1,&bounds.x2,&bounds.y2);
+ if (LocaleNCompare(DocumentMedia,command,strlen(DocumentMedia)) == 0)
+ count=sscanf(command,"%%%%DocumentMedia: %*s %lf %lf",&bounds.x2,
+ &bounds.y2)+2;
+ if (LocaleNCompare(PageBoundingBox,command,strlen(PageBoundingBox)) == 0)
+ count=sscanf(command,"%%%%PageBoundingBox: %lf %lf %lf %lf",
+ &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
+ if (count != 4)
+ continue;
+ if ((bounds.x1 > bounds.x2) ||
+ (bounds.y1 > bounds.y2))
+ continue;
+ /*
+ Set Postscript render geometry.
+ */
+ FormatString(translate_geometry,"%g %g translate\n",-bounds.x1,-bounds.y1);
+ width=(unsigned long) (bounds.x2-bounds.x1+0.5);
+ height=(unsigned long) (bounds.y2-bounds.y1+0.5);
+ if ((width <= box.width) && (height <= box.height))
+ continue;
+ page.width=width;
+ page.height=height;
+ box=page;
+ }
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Done copying.");
+ if (image_info->page != (char *) NULL)
+ (void) GetGeometry(image_info->page,&page.x,&page.y,&page.width,
+ &page.height);
+ FormatString(geometry,"%lux%lu",
+ (unsigned long) ceil(page.width*image->x_resolution/dx_resolution-0.5),
+ (unsigned long) ceil(page.height*image->y_resolution/dy_resolution-0.5));
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Page geometry: %s",geometry);
+ if (ferror(file))
+ {
+ (void) fclose(file);
+ (void) LiberateTemporaryFile(postscript_filename);
+ ThrowReaderException(CorruptImageError,AnErrorHasOccurredWritingToFile,
+ image)
+ }
+ (void) rewind(file);
+ (void) fputs(translate_geometry,file);
+ (void) fclose(file);
+ CloseBlob(image);
+ filesize=GetBlobSize(image);
+ DestroyImage(image);
+ image=(Image *) NULL;
+ /*
+ Use Ghostscript to convert Postscript image.
+ */
+ {
+ char
+ options[MaxTextExtent];
+
+ options[0]='\0';
+ /*
+ Append subrange.
+ */
+ if (image_info->subrange != 0)
+ FormatString(options,"-dFirstPage=%lu -dLastPage=%lu",
+ image_info->subimage+1,image_info->subimage+image_info->subrange);
+ /*
+ Append bounding box.
+ */
+ FormatString(options+strlen(options)," -g%s",geometry);
+ (void) strlcpy(filename,image_info->filename,MaxTextExtent);
+ if (image_info->temporary)
+ (void) LiberateTemporaryFile((char *) image_info->filename);
+ if(!AcquireTemporaryFileName((char *)image_info->filename))
+ {
+ (void) LiberateTemporaryFile(postscript_filename);
+ ThrowReaderTemporaryFileException(image_info->filename);
+ }
+ FormatString(command,delegate_info->commands,antialias,
+ antialias,density,options,image_info->filename,
+ postscript_filename);
+ }
+ (void) MagickMonitorFormatted(0,8,&image->exception,RenderPostscriptText,
+ image->filename);
+ status=InvokePostscriptDelegate(image_info->verbose,command,exception);
+ if (!IsAccessibleAndNotEmpty(image_info->filename))
+ {
+ /*
+ Ghostscript requires a showpage operator.
+ */
+ file=fopen(postscript_filename,"ab");
+ if (file == (FILE *) NULL)
+ {
+ (void) LiberateTemporaryFile((char *) image_info->filename);
+ ThrowReaderException(FileOpenError,UnableToWriteFile,image);
+ }
+ (void) fputs("showpage\n",file);
+ (void) fclose(file);
+ status=InvokePostscriptDelegate(image_info->verbose,command,exception);
+ }
+ (void) LiberateTemporaryFile(postscript_filename);
+ (void) MagickMonitorFormatted(7,8,&image->exception,RenderPostscriptText,
+ image->filename);
+ if (IsAccessibleAndNotEmpty(image_info->filename))
+ {
+ /*
+ Read Ghostscript output.
+ */
+ ImageInfo
+ *clone_info;
+
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ clone_info->magick[0]='\0';
+ image=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ }
+ (void) LiberateTemporaryFile((char *) image_info->filename);
+#if defined(HasDPS)
+ if (image == (Image *) NULL)
+ {
+ /*
+ Ghostscript has failed-- try the Display Postscript Extension.
+ */
+ (void) FormatString((char *) image_info->filename,"dps:%.1024s",filename);
+ image=ReadImage(image_info,exception);
+ }
+#endif /* defined(HasDPS) */
+ if (image == (Image *) NULL)
+ if (UndefinedException == exception->severity)
+ ThrowException(exception,DelegateError,PostscriptDelegateFailed,filename);
+ if (image != (Image *) NULL)
+ {
+ do
+ {
+ (void) strcpy(image->magick,"PS");
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ next_image=SyncNextImageInList(image);
+ if (next_image != (Image *) NULL)
+ image=next_image;
+ } while (next_image != (Image *) NULL);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r E P T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterEPTImage adds attributes for the EPT image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterEPTImage method is:
+%
+% RegisterEPTImage(void)
+%
+*/
+ModuleExport void RegisterEPTImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("EPT");
+ entry->decoder=(DecoderHandler) ReadEPTImage;
+ entry->encoder=(EncoderHandler) WriteEPTImage;
+ entry->magick=(MagickHandler) IsEPT;
+ entry->adjoin=False;
+ entry->blob_support=False;
+ entry->description="Adobe Encapsulated PostScript with MS-DOS TIFF preview";
+ entry->module="EPT";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("EPT2");
+ entry->decoder=(DecoderHandler) ReadEPTImage;
+ entry->encoder=(EncoderHandler) WriteEPTImage;
+ entry->magick=(MagickHandler) IsEPT;
+ entry->adjoin=False;
+ entry->blob_support=False;
+ entry->description="Adobe Level II Encapsulated PostScript with MS-DOS TIFF preview";
+ entry->module="EPT";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("EPT3");
+ entry->decoder=(DecoderHandler) ReadEPTImage;
+ entry->encoder=(EncoderHandler) WriteEPTImage;
+ entry->magick=(MagickHandler) IsEPT;
+ entry->adjoin=False;
+ entry->blob_support=False;
+ entry->description="Adobe Level III Encapsulated PostScript with MS-DOS TIFF preview";
+ entry->module="EPT";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r E P T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterEPTImage removes format registrations made by the
+% EPT module from the list of supported formats.
+%
+% The format of the UnregisterEPTImage method is:
+%
+% UnregisterEPTImage(void)
+%
+*/
+ModuleExport void UnregisterEPTImage(void)
+{
+ (void) UnregisterMagickInfo("EPT");
+ (void) UnregisterMagickInfo("EPT2");
+ (void) UnregisterMagickInfo("EPT3");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e E P T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteEPTImage writes an image in the Adobe Encapsulated Postscript
+% format with a TIFF preview.
+%
+% The format of the WriteEPTImage method is:
+%
+% unsigned int WriteEPTImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteEPTImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteEPTImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ filename[MaxTextExtent],
+ ps_filename[MaxTextExtent],
+ tiff_filename[MaxTextExtent];
+
+ FILE
+ *ps_file,
+ *tiff_file;
+
+ unsigned int
+ logging,
+ status;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ logging=IsEventLogging();
+
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ (void) strlcpy(ps_filename,image->magick_filename,MaxTextExtent);
+ if (LocaleCompare(image_info->magick,"EPS") != 0)
+ {
+ /*
+ Write image as Encapsulated Postscript to a temporary file.
+ */
+ char
+ subformat[MaxTextExtent];
+
+ if(!AcquireTemporaryFileName(ps_filename))
+ ThrowWriterTemporaryFileException(ps_filename);
+
+ /* Select desired EPS level */
+ (void) strcpy(subformat,"eps");
+ if (LocaleCompare(image_info->magick,"EPT2") == 0)
+ (void) strcpy(subformat,"eps2");
+ else if (LocaleCompare(image_info->magick,"EPT3") == 0)
+ (void) strcpy(subformat,"eps3");
+
+ /* JPEG compression requires at least EPS2 */
+ if ((image->compression == JPEGCompression) &&
+ (LocaleCompare(subformat,"EPS") == 0))
+ (void) strcpy(subformat,"eps2");
+
+ FormatString(image->filename,"%s:%.1024s",subformat,ps_filename);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing temporary EPS file \"%s\"",ps_filename);
+ (void) WriteImage(image_info,image);
+ }
+ /*
+ Write image as TIFF to a temporary file.
+ */
+ if(!AcquireTemporaryFileName(tiff_filename))
+ {
+ (void) LiberateTemporaryFile(ps_filename);
+ ThrowWriterTemporaryFileException(tiff_filename);
+ }
+
+ FormatString(image->filename,"tiff:%.1024s",tiff_filename);
+ image->compression=RLECompression;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing temporary TIFF preview file \"%s\"",tiff_filename);
+ (void) WriteImage(image_info,image);
+ /*
+ Write EPT image.
+ */
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ status=MagickFail;
+ if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) != MagickFail)
+ {
+ if ((ps_file=fopen(ps_filename,"rb")) != (FILE *) NULL)
+ {
+ if ((tiff_file=fopen(tiff_filename,"rb")) != (FILE *) NULL)
+ {
+ int
+ c;
+
+ struct stat
+ attributes;
+
+ /*
+ Write EPT image.
+ */
+
+ /* MS-DOS EPS binary file magic signature */
+ (void) WriteBlobLSBLong(image,0xc6d3d0c5ul);
+ /* Byte position in file for start of Postscript language code
+ section */
+ (void) WriteBlobLSBLong(image,30);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "EPS section offset is %lu bytes",(unsigned long) 30);
+ /* Byte length of PostScript language section. */
+ attributes.st_size=0;
+ (void) fstat(fileno(ps_file),&attributes);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "EPS section is %lu bytes long",
+ (unsigned long)attributes.st_size);
+ (void) WriteBlobLSBLong(image,(unsigned long) attributes.st_size);
+ /* Byte position in file for start of Metafile screen
+ representation (none provided). */
+ (void) WriteBlobLSBLong(image,0);
+ /* Byte length of Metafile section (PSize). (none provided) */
+ (void) WriteBlobLSBLong(image,0);
+ /* Byte position of TIFF representation. */
+ (void) WriteBlobLSBLong(image,(unsigned long) attributes.st_size+30);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF section offset is %lu bytes",
+ (unsigned long) attributes.st_size+30);
+ /* Byte length of TIFF section. */
+ (void) fstat(fileno(tiff_file),&attributes);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF section is %lu bytes long",
+ (unsigned long) attributes.st_size);
+ (void) WriteBlobLSBLong(image,(long) attributes.st_size);
+ /* Checksum of header (XOR of bytes 0-27). If Checksum is FFFF
+ then ignore it. This is lazy code. */
+ (void) WriteBlobLSBShort(image,0xffff);
+ /* EPS section */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing EPS section at offset %ld",
+ (long) TellBlob(image));
+ for (c=fgetc(ps_file); c != EOF; c=fgetc(ps_file))
+ (void) WriteBlobByte(image,c);
+ /* TIFF section */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing TIFF section at offset %ld",
+ (long) TellBlob(image));
+ for (c=fgetc(tiff_file); c != EOF; c=fgetc(tiff_file))
+ (void) WriteBlobByte(image,c);
+ (void) fclose(tiff_file);
+ status=MagickPass;
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Failed to open \"%s\" for read",
+ tiff_filename);
+ }
+ (void) fclose(ps_file);
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Failed to open \"%s\" for read",ps_filename);
+ }
+
+ CloseBlob(image);
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Failed to open \"%s\" for write",
+ image->filename);
+ }
+ if (LocaleCompare(image_info->magick,"EPS") != 0)
+ (void) LiberateTemporaryFile(ps_filename);
+ (void) LiberateTemporaryFile(tiff_filename);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ return(MagickPass);
+}
diff --git a/coders/fax.c b/coders/fax.c
new file mode 100644
index 0000000..198c709
--- /dev/null
+++ b/coders/fax.c
@@ -0,0 +1,330 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% FFFFF AAA X X %
+% F A A X X %
+% FFF AAAAA X %
+% F A A X X %
+% F A A X X %
+% %
+% %
+% Read/Write Group 3 FIX Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/compress.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteFAXImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s F A X %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsFAX returns True if the image format type, identified by the
+% magick string, is FAX.
+%
+% The format of the IsFAX method is:
+%
+% unsigned int IsFAX(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsFAX returns True if the image format type is FAX.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsFAX(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (LocaleNCompare((char *) magick,"DFAX",4) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d F A X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadFAXImage reads a Group 3 FAX image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadFAXImage method is:
+%
+% Image *ReadFAXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadFAXImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadFAXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Initialize image structure.
+ */
+ image->storage_class=PseudoClass;
+ if (image->columns == 0)
+ image->columns=2592;
+ if (image->rows == 0)
+ image->rows=3508;
+ image->depth=8;
+ if (!AllocateImageColormap(image,2))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Monochrome colormap.
+ */
+ image->colormap[0].red=MaxRGB;
+ image->colormap[0].green=MaxRGB;
+ image->colormap[0].blue=MaxRGB;
+ image->colormap[1].red=0;
+ image->colormap[1].green=0;
+ image->colormap[1].blue=0;
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ status=HuffmanDecodeImage(image);
+ if (status == False)
+ ThrowReaderException(CorruptImageError,UnableToReadImageData,image);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r F A X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterFAXImage adds attributes for the FAX image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterFAXImage method is:
+%
+% RegisterFAXImage(void)
+%
+*/
+ModuleExport void RegisterFAXImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("FAX");
+ entry->decoder=(DecoderHandler) ReadFAXImage;
+ entry->encoder=(EncoderHandler) WriteFAXImage;
+ entry->magick=(MagickHandler) IsFAX;
+ entry->description="Group 3 FAX (Not TIFF Group3 FAX!)";
+ entry->module="FAX";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("G3");
+ entry->decoder=(DecoderHandler) ReadFAXImage;
+ entry->encoder=(EncoderHandler) WriteFAXImage;
+ entry->magick=(MagickHandler) IsFAX;
+ entry->adjoin=False;
+ entry->description="Group 3 FAX (same as \"FAX\")";
+ entry->stealth=MagickTrue;
+ entry->module="FAX";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r F A X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterFAXImage removes format registrations made by the
+% FAX module from the list of supported formats.
+%
+% The format of the UnregisterFAXImage method is:
+%
+% UnregisterFAXImage(void)
+%
+*/
+ModuleExport void UnregisterFAXImage(void)
+{
+ (void) UnregisterMagickInfo("FAX");
+ (void) UnregisterMagickInfo("G3");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e F A X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure WriteFAXImage writes an image to a file in 1 dimensional Huffman
+% encoded format.
+%
+% The format of the WriteFAXImage method is:
+%
+% unsigned int WriteFAXImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteFAXImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteFAXImage(const ImageInfo *image_info,Image *image)
+{
+ ImageInfo
+ *clone_info;
+
+ unsigned int
+ status;
+
+ unsigned long
+ scene;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ clone_info=CloneImageInfo(image_info);
+ (void) strcpy(clone_info->magick,"FAX");
+ scene=0;
+ do
+ {
+ /*
+ Convert MIFF to monochrome.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ status=HuffmanEncodeImage(clone_info,image);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (clone_info->adjoin);
+ DestroyImageInfo(clone_info);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(status);
+}
diff --git a/coders/fits.c b/coders/fits.c
new file mode 100644
index 0000000..1b77108
--- /dev/null
+++ b/coders/fits.c
@@ -0,0 +1,838 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% FFFFF IIIII TTTTT SSSSS %
+% F I T SS %
+% FFF I T SSS %
+% F I T SS %
+% F IIIII T SSSSS %
+% %
+% %
+% Read/Write Flexible Image Transport System Images. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% Jaroslav Fojtik %
+% 2008 - 2009 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteFITSImage(const ImageInfo *,Image *);
+
+
+#define FITS_BLOCK_SIZE 2880
+#define FITS_ROW_SIZE 80
+
+
+/* Convert signed values to unsigned - and reverse. */
+static void FixSignedValues(unsigned char *data, int size, unsigned step, unsigned endian)
+{
+ if(endian != MSBEndian)
+ {
+ data += step - 1; /* LSB has most signifficant byte at the end */
+ } /* MSB has most signifficant byte first */
+
+ while(size-->0)
+ {
+ *data ^= 0x80;
+ data += step;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s F I T S %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsFITS returns True if the image format type, identified by the
+% magick string, is FITS.
+%
+% The format of the IsFITS method is:
+%
+% unsigned int IsFITS(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsFITS returns True if the image format type is FITS.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsFITS(const unsigned char *magick,const size_t length)
+{
+ if (length < 6)
+ return(False);
+ if (LocaleNCompare((char *) magick,"IT0",3) == 0)
+ return(True);
+ if (LocaleNCompare((char *) magick,"SIMPLE",6) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d F I T S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadFITSImage reads a FITS image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadFITSImage method is:
+%
+% Image *ReadFITSImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadFITSImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o filename: Specifies the name of the image to read.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadFITSImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ typedef struct _FITSInfo
+ {
+ char
+ extensions_exist;
+ int
+ simple,
+ bits_per_pixel,
+ columns,
+ rows,
+ number_axes,
+ number_scenes;
+
+ double
+ min_data,
+ max_data,
+ zero,
+ scale;
+ } FITSInfo;
+
+ char
+ keyword[FITS_ROW_SIZE+1],
+ value[FITS_ROW_SIZE+1];
+
+ FITSInfo
+ fits_info;
+
+ Image
+ *image;
+
+ int
+ c;
+
+ int logging;
+
+ long
+ packet_size,
+ scene,
+ y,
+ ax_number;
+
+ register PixelPacket
+ *q;
+
+ unsigned char
+ *fits_pixels;
+
+ unsigned int
+ status,
+ value_expected;
+
+ unsigned long
+ number_pixels;
+
+ ImportPixelAreaOptions import_options;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ logging = LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Initialize common part of image header.
+ */
+ fits_info.extensions_exist=0;
+ fits_info.simple=False;
+
+ ImportPixelAreaOptionsInit(&import_options);
+ import_options.endian = MSBEndian;
+
+ /*
+ Decode image header.
+ */
+ if ((c=ReadBlobByte(image)) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ReadExtension:
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading FITS HDU at position: %Xh", (unsigned)TellBlob(image) );
+
+ /*
+ Initialize image header for all subheaders.
+ */
+ fits_info.bits_per_pixel=8;
+ fits_info.columns=1;
+ fits_info.rows=1;
+ fits_info.number_axes=0;
+ fits_info.number_scenes=1;
+ fits_info.min_data=0.0;
+ fits_info.max_data=0.0;
+ fits_info.zero=0.0;
+ fits_info.scale=1.0;
+ number_pixels = 0;
+
+ for ( ; ; )
+ {
+ if (!isalnum((int) c))
+ c=ReadBlobByte(image);
+ else
+ {
+ register char
+ *p;
+
+ /*
+ Determine a keyword and its value.
+ */
+ p=keyword;
+ do
+ {
+ if ((p-keyword) < (FITS_ROW_SIZE-1))
+ *p++=c;
+ if ((c=ReadBlobByte(image)) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ } while (isalnum(c) || (c == '_'));
+ *p='\0';
+ if (LocaleCompare(keyword,"END") == 0)
+ break;
+ value_expected=False;
+ while (isspace(c) || (c == '='))
+ {
+ if (c == '=')
+ value_expected=True;
+ if ((c=ReadBlobByte(image)) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ if (value_expected == False)
+ continue;
+ p=value;
+ if (c == '\'')
+ c=ReadBlobByte(image);
+
+ while (isalnum(c) || (c == '-') || (c == '+') || (c == '.'))
+ {
+ if ((p-value) < (FITS_ROW_SIZE-1))
+ *p++=c;
+ if ((c=ReadBlobByte(image)) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ *p='\0';
+ /*
+ Assign a value to the specified keyword.
+ */
+ if (LocaleCompare(keyword,"SIMPLE") == 0)
+ fits_info.simple = (*value=='T') || (*value=='t');
+ if (LocaleCompare(keyword,"EXTEND") == 0)
+ fits_info.extensions_exist = (*value== 'T') || (*value=='t');
+ if (LocaleCompare(keyword,"BITPIX") == 0)
+ {
+ fits_info.bits_per_pixel=MagickAtoI(value);
+ /*
+ BITPIX valid values:
+ 8 -- Character or unsigned binary integer
+ 16 -- 16-bit two's complement binary integer
+ 32 -- 32-bit two's complement binary integer
+ -32 -- 32-bit floating point, single precision
+ -64 -- 64-bit floating point, double precision
+ */
+ if(fits_info.bits_per_pixel>0)
+ import_options.sample_type = UnsignedQuantumSampleType;
+ if(fits_info.bits_per_pixel<0)
+ import_options.sample_type = FloatQuantumSampleType;
+ }
+ if(!LocaleNCompare(keyword,"NAXIS",5))
+ {
+ if (keyword[5] == 0) ax_number=-1;
+ else
+ {
+ if(isdigit((int) keyword[5]))
+ ax_number = MagickAtoI(keyword+5);
+ else ax_number=-2; /*unsupported fits keyword*/
+ }
+ y=0;
+ if(ax_number>=-1)
+ y = MagickAtoI(value);
+ switch(ax_number)
+ {
+ case -1:fits_info.number_axes = y; break;
+ case 1: fits_info.columns = (y<=0) ? 1 : y; break;
+ case 2: fits_info.rows = (y<=0) ? 1 : y; break;
+ case 3: fits_info.number_scenes = (y<=0) ? 1 : y; break;
+ }
+ if(ax_number>0)
+ {
+ if(number_pixels == 0)
+ number_pixels = y;
+ else
+ number_pixels *= (y<=0) ? 1 : y;
+ }
+ }
+
+ if (LocaleCompare(keyword,"DATAMAX") == 0)
+ fits_info.max_data=MagickAtoF(value);
+ if (LocaleCompare(keyword,"DATAMIN") == 0)
+ fits_info.min_data=MagickAtoF(value);
+ if (LocaleCompare(keyword,"BZERO") == 0)
+ fits_info.zero=MagickAtoF(value);
+ if (LocaleCompare(keyword,"BSCALE") == 0)
+ fits_info.scale=MagickAtoF(value);
+ if (LocaleCompare(keyword,"XENDIAN") == 0)
+ {
+ if (LocaleCompare(keyword,"BIG") == 0)
+ import_options.endian = MSBEndian;
+ else
+ import_options.endian = LSBEndian;
+ }
+ }
+ while ((TellBlob(image) % 80) != 0)
+ if ((c=ReadBlobByte(image)) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if ((c=ReadBlobByte(image)) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+
+ while ((TellBlob(image) % FITS_BLOCK_SIZE) != 0) /* Read till the rest of a block. */
+ if ((c=ReadBlobByte(image)) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ /*
+ Verify that required image information is defined.
+ */
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "HDU read finished at %Xh, number of pixel is: %d (%d*%d*%d)",
+ (unsigned) TellBlob(image),
+ (unsigned) number_pixels,
+ (unsigned) fits_info.columns,
+ (unsigned) fits_info.rows,
+ (unsigned) fits_info.number_scenes);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "FITS header:\n"
+ " extensions_exist : 0x%02x\n"
+ " simple : %d\n"
+ " bits_per_pixel : %d\n"
+ " columns : %d\n"
+ " rows : %d\n"
+ " number_axes : %d\n"
+ " number_scenes : %d\n"
+ " min_data : %g\n"
+ " max_data : %g\n"
+ " zero : %g\n"
+ " scale : %g",
+ (int) fits_info.extensions_exist,
+ fits_info.simple,
+ fits_info.bits_per_pixel,
+ fits_info.columns,
+ fits_info.rows,
+ fits_info.number_axes,
+ fits_info.number_scenes,
+ fits_info.min_data,
+ fits_info.max_data,
+ fits_info.zero,
+ fits_info.scale);
+ }
+
+ if ((fits_info.bits_per_pixel != 8) &&
+ (fits_info.bits_per_pixel != 16) &&
+ (fits_info.bits_per_pixel != 32) &&
+ (fits_info.bits_per_pixel != 64) &&
+ (fits_info.bits_per_pixel != -32) &&
+ (fits_info.bits_per_pixel != -64))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if ((!fits_info.simple) || (fits_info.number_axes < 1) ||
+ (fits_info.number_axes > 4) || (number_pixels == 0))
+ {
+ if(!fits_info.extensions_exist) /* when extensions exists, process further */
+ ThrowReaderException(CorruptImageError,ImageTypeNotSupported,image);
+
+ number_pixels = (number_pixels*AbsoluteValue(fits_info.bits_per_pixel)) / 8;
+ number_pixels = ((number_pixels+FITS_BLOCK_SIZE-1) / FITS_BLOCK_SIZE) * FITS_BLOCK_SIZE; /* raw data block size */
+ (void) SeekBlob(image,number_pixels,SEEK_CUR);
+ }
+ else
+ {
+ number_pixels = fits_info.columns*fits_info.rows;
+ for (scene=0; scene < (long) fits_info.number_scenes; scene++)
+ {
+ if(image->rows!=0 && image->columns!=0)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+
+ /*
+ Create linear colormap.
+ */
+ image->columns = fits_info.columns;
+ image->rows = fits_info.rows;
+ if(fits_info.bits_per_pixel>=0)
+ image->depth = Min(QuantumDepth,fits_info.bits_per_pixel);
+ else
+ image->depth = QuantumDepth; /* double type cell */
+ /* image->storage_class=PseudoClass; */
+ image->storage_class = DirectClass;
+ image->scene=scene;
+ image->is_grayscale = 1;
+
+ if (image->depth<=8 && fits_info.bits_per_pixel==8)
+ if (!AllocateImageColormap(image,1 << image->depth))
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ /*
+ Initialize image structure.
+ */
+ packet_size=AbsoluteValue(fits_info.bits_per_pixel)/8;
+
+ number_pixels = image->columns*image->rows;
+ if ((number_pixels / image->columns) != image->rows)
+ ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
+
+ fits_pixels=MagickAllocateArray(unsigned char *, image->columns, packet_size);
+ if (fits_pixels == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ /*
+ Recover minimum and maximum from data if not present in HDU
+ */
+ if ((fits_info.min_data == 0.0) && (fits_info.max_data == 0.0))
+ { /* Determine minimum and maximum intensity. */
+ if(fits_info.bits_per_pixel==-32)
+ (void) MagickFindRawImageMinMax(image, import_options.endian, image->columns,
+ image->rows, FloatPixel, packet_size*image->columns,
+ fits_pixels, &import_options.double_minvalue,
+ &import_options.double_maxvalue);
+ if(fits_info.bits_per_pixel==-64)
+ (void) MagickFindRawImageMinMax(image, import_options.endian, image->columns,
+ image->rows, DoublePixel, packet_size*image->columns,
+ fits_pixels, &import_options.double_minvalue,
+ &import_options.double_maxvalue);
+ }
+ else
+ {
+ import_options.double_maxvalue = fits_info.max_data;
+ import_options.double_minvalue = fits_info.min_data;
+ }
+
+ /*
+ Convert FITS pixels to pixel packets.
+ */
+
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+
+ if(ReadBlob(image, packet_size*image->columns, fits_pixels) != (size_t)packet_size*image->columns)
+ {
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ " fits cannot read scanrow %u from a file.", (unsigned)y );
+ break; /* goto ExitLoop; */
+ }
+
+ switch(fits_info.bits_per_pixel)
+ {
+ case 16: FixSignedValues(fits_pixels, image->columns, 2, import_options.endian);
+ break;
+ case 32: FixSignedValues(fits_pixels, image->columns, 4, import_options.endian);
+ break;
+ case 64: FixSignedValues(fits_pixels, image->columns, 8, import_options.endian);
+ break;
+ }
+
+ if(ImportImagePixelArea(image, GrayQuantum, packet_size*8, fits_pixels, &import_options,0) == MagickFail)
+ {
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ " fits failed to ImportImagePixelArea for a row %u", (unsigned)y);
+ break;
+ }
+
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(fits_pixels);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, image->filename);
+ break;
+ }
+
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ }
+ }
+
+ if(fits_info.extensions_exist)
+ {
+ while ((TellBlob(image) % FITS_BLOCK_SIZE) != 0) /* Read till the rest of a block. */
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ if(!EOFBlob(image))
+ { /* Try to read a next extension block header. */
+ if ((c=ReadBlobByte(image)) != EOF)
+ goto ReadExtension;
+ }
+ }
+
+ CloseBlob(image);
+
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r F I T S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterFITSImage adds attributes for the FITS image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterFITSImage method is:
+%
+% RegisterFITSImage(void)
+%
+*/
+ModuleExport void RegisterFITSImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("FITS");
+ entry->decoder=(DecoderHandler) ReadFITSImage;
+ entry->encoder=(EncoderHandler) WriteFITSImage;
+ entry->magick=(MagickHandler) IsFITS;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Flexible Image Transport System";
+ entry->module="FITS";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r F I T S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterFITSImage removes format registrations made by the
+% FITS module from the list of supported formats.
+%
+% The format of the UnregisterFITSImage method is:
+%
+% UnregisterFITSImage(void)
+%
+*/
+ModuleExport void UnregisterFITSImage(void)
+{
+ (void) UnregisterMagickInfo("FITS");
+}
+
+
+/*
+ This functions inserts one row into a HDU. Note that according to
+ FITS spec a card image contains 80 bytes of ASCII data.
+
+ buffer - 2880 byte logical FITS record.
+ data - string data to append
+ offset - offset into FITS record to write the data.
+*/
+int InsertRowHDU(char *buffer, const char *data, int offset)
+{
+ size_t
+ len;
+
+ if (data == NULL)
+ return offset;
+ len = strlen(data);
+ len = Min(len,80); /* Each card image is 80 bytes max */
+
+ if (len > (size_t) (FITS_BLOCK_SIZE-offset))
+ len = FITS_BLOCK_SIZE-offset;
+
+ (void) strncpy(buffer+offset,data,len);
+ return offset +80;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e F I T S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteFITSImage writes a Flexible Image Transport System image to a
+% file as gray scale intensities [0..255].
+%
+% The format of the WriteFITSImage method is:
+%
+% unsigned int WriteFITSImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteFITSImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteFITSImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[FITS_BLOCK_SIZE],
+ *fits_info;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ quantum_size,
+ status;
+
+ unsigned long
+ packet_size;
+
+ ExportPixelAreaOptions export_options;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+
+ ExportPixelAreaOptionsInit(&export_options);
+ export_options.endian = MSBEndian;
+ export_options.sample_type = UnsignedQuantumSampleType;
+
+ if (image->depth <= 8)
+ {
+ quantum_size=8;
+ }
+ else if (image->depth <= 16)
+ {
+ quantum_size=16;
+ }
+ else
+ {
+ quantum_size=32;
+ }
+
+ /*
+ Allocate image memory.
+ */
+ packet_size=quantum_size/8;
+ fits_info=MagickAllocateMemory(char *,FITS_BLOCK_SIZE);
+ pixels=MagickAllocateMemory(unsigned char *,packet_size*image->columns);
+ if ((fits_info == (char *) NULL) || (pixels == (unsigned char *) NULL))
+ {
+ MagickFreeMemory(fits_info);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+
+ /*
+ Initialize image header.
+ */
+ memset(fits_info,' ',FITS_BLOCK_SIZE);
+ y = 0;
+ y = InsertRowHDU(fits_info, "SIMPLE = T", y);
+ FormatString(buffer, "BITPIX = %u",quantum_size);
+ y = InsertRowHDU(fits_info, buffer, y);
+ y = InsertRowHDU(fits_info, "NAXIS = 2", y);
+ FormatString(buffer, "NAXIS1 = %10lu",image->columns);
+ y = InsertRowHDU(fits_info, buffer, y);
+ FormatString(buffer, "NAXIS2 = %10lu",image->rows);
+ y = InsertRowHDU(fits_info, buffer, y);
+ FormatString(buffer, "DATAMIN = %10u",0);
+ y = InsertRowHDU(fits_info, buffer, y);
+ FormatString(buffer, "DATAMAX = %10lu", MaxValueGivenBits(quantum_size));
+ y = InsertRowHDU(fits_info, buffer, y);
+ if(quantum_size>8)
+ {
+ FormatString(buffer, "BZERO = %10u", (quantum_size <= 16) ? 32768U : 2147483648U);
+ y = InsertRowHDU(fits_info, buffer, y);
+ }
+ /* Magick version data can only be 60 bytes. */
+ (void) FormatString(buffer, "HISTORY Created by %.60s.",MagickPackageName " " MagickLibVersionText);
+ y = InsertRowHDU(fits_info, buffer, y);
+ y = InsertRowHDU(fits_info, "END", y);
+ (void) WriteBlob(image, FITS_BLOCK_SIZE, (char *)fits_info);
+
+ /*
+ Convert image to fits scale PseudoColor class.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,GrayQuantum,quantum_size,pixels,&export_options,0);
+ if(quantum_size==16) FixSignedValues(pixels, image->columns, 2, export_options.endian);
+ if(quantum_size==32) FixSignedValues(pixels, image->columns, 4, export_options.endian);
+ (void) WriteBlob(image,packet_size*image->columns,pixels);
+ if (QuantumTick(image->rows-y-1,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ &image->exception,SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+
+ /* Calculate of padding */
+ y = FITS_BLOCK_SIZE - (image->columns * image->rows * packet_size) % FITS_BLOCK_SIZE;
+ if(y>0)
+ {
+ memset(fits_info, 0, y);
+ (void)WriteBlob(image,y,(char *) fits_info);
+ }
+ MagickFreeMemory(fits_info);
+
+ MagickFreeMemory(pixels);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/fpx.c b/coders/fpx.c
new file mode 100644
index 0000000..aba1856
--- /dev/null
+++ b/coders/fpx.c
@@ -0,0 +1,1092 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% FFFFF PPPP X X %
+% F P P X X %
+% FFF PPPP X %
+% F P X X %
+% F P X X %
+% %
+% %
+% Read/Write FlashPIX Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+#if defined(HasFPX)
+# if defined(POSIX)
+# include <fpxlib.h>
+# else
+# include "Fpxlib.h"
+# endif
+#endif
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteFPXImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s F P X %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsFPX returns True if the image format type, identified by the
+% magick string, is FPX.
+%
+% The format of the IsFPX method is:
+%
+% unsigned int IsFPX(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsFPX returns True if the image format type is FPX.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsFPX(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (memcmp(magick,"\320\317\021\340",4) == 0)
+ return(True);
+ return(False);
+}
+
+#if defined(HasFPX)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d F P X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadFPXImage reads a FlashPix image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image. This method was contributed by BillR@corbis.com.
+%
+% The format of the ReadFPXImage method is:
+%
+% Image *ReadFPXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadFPXImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadFPXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ FPXColorspace
+ colorspace;
+
+ FPXImageComponentDesc
+ *alpha_component,
+ *blue_component,
+ *green_component,
+ *red_component;
+
+ FPXImageDesc
+ fpx_info;
+
+ FPXImageHandle
+ *flashpix;
+
+ FPXStatus
+ fpx_status;
+
+ FPXSummaryInformation
+ summary_info;
+
+ Image
+ *image;
+
+ IndexPacket
+ index;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *a,
+ *b,
+ *g,
+ *r;
+
+ unsigned char
+ *scanline;
+
+ unsigned int
+ status,
+ subimage,
+ height,
+ tile_width,
+ tile_height,
+ width;
+
+ size_t
+ memory_limit;
+
+ /*
+ Open image.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ CloseBlob(image);
+
+ /*
+ Initialize FPX toolkit.
+ */
+ fpx_status=FPX_InitSystem();
+ if (fpx_status != FPX_OK)
+ {
+ ThrowReaderException(CoderError,UnableToInitializeFPXLibrary,image);
+ }
+ memory_limit=20000000;
+ fpx_status=FPX_SetToolkitMemoryLimit(&memory_limit);
+ if (fpx_status != FPX_OK)
+ {
+ FPX_ClearSystem();
+ ThrowReaderException(CoderError,UnableToInitializeFPXLibrary,image);
+ }
+ tile_width=64;
+ tile_height=64;
+ flashpix=(FPXImageHandle *) NULL;
+ {
+ fpx_status=FPX_OpenImageByFilename(image->filename,(char *) NULL,
+ &width,&height,&tile_width,&tile_height,&colorspace,&flashpix);
+ }
+ if (fpx_status == FPX_LOW_MEMORY_ERROR)
+ {
+ FPX_ClearSystem();
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ if (fpx_status != FPX_OK)
+ {
+ FPX_ClearSystem();
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ if (image_info->view == (char *) NULL)
+ {
+ float
+ aspect_ratio;
+
+ /*
+ Get the aspect ratio.
+ */
+ aspect_ratio=(float) width/height;
+ fpx_status=FPX_GetImageResultAspectRatio(flashpix,&aspect_ratio);
+ if (fpx_status != FPX_OK)
+ ThrowReaderException(CoderError,UnableToReadAspectRatio,image);
+ if (width != (unsigned long) ((aspect_ratio*height)+0.5))
+ Swap(width,height);
+ }
+ fpx_status=FPX_GetSummaryInformation(flashpix,&summary_info);
+ if (fpx_status != FPX_OK)
+ {
+ FPX_ClearSystem();
+ ThrowReaderException(CoderError,UnableToReadSummaryInfo,image);
+ }
+ if (summary_info.title_valid)
+ if ((summary_info.title.length != 0) &&
+ (summary_info.title.ptr != (unsigned char *) NULL))
+ {
+ char
+ *label;
+
+ /*
+ Note image label.
+ */
+ label=MagickAllocateMemory(char *,summary_info.title.length+1);
+ if (label == (char *) NULL)
+ {
+ FPX_ClearSystem();
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ (void) strlcpy(label,(char *) summary_info.title.ptr,
+ summary_info.title.length+1);
+ (void) SetImageAttribute(image,"label",label);
+ MagickFreeMemory(label);
+ }
+ if (summary_info.comments_valid)
+ if ((summary_info.comments.length != 0) &&
+ (summary_info.comments.ptr != (unsigned char *) NULL))
+ {
+ char
+ *comments;
+
+ /*
+ Note image comment.
+ */
+ comments=MagickAllocateMemory(char *,summary_info.comments.length+1);
+ if (comments == (char *) NULL)
+ {
+ FPX_ClearSystem();
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ (void) strlcpy(comments,(char *) summary_info.comments.ptr,
+ summary_info.comments.length+1);
+ (void) SetImageAttribute(image,"comment",comments);
+ MagickFreeMemory(comments);
+ }
+ /*
+ Determine resolution by subimage specification.
+ */
+ for (i=1; ; i++)
+ if (((width >> i) < tile_width) || ((height >> i) < tile_height))
+ break;
+ subimage=i;
+ if (image_info->subrange != 0)
+ while (subimage > image_info->subimage)
+ {
+ width>>=1;
+ height>>=1;
+ subimage--;
+ }
+ if (image_info->size != (char *) NULL)
+ while ((width > image->columns) || (height > image->rows))
+ {
+ width>>=1;
+ height>>=1;
+ subimage--;
+ }
+ image->depth=8;
+ image->columns=width;
+ image->rows=height;
+ if ((colorspace.numberOfComponents % 2) == 0)
+ image->matte=True;
+ if (colorspace.numberOfComponents == 1)
+ {
+ /*
+ Create linear colormap.
+ */
+ if (!AllocateImageColormap(image,MaxColormapSize))
+ {
+ FPX_ClearSystem();
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ }
+ if (image_info->ping)
+ {
+ (void) FPX_CloseImage(flashpix);
+ FPX_ClearSystem();
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Allocate memory for the image and pixel buffer.
+ */
+ scanline=MagickAllocateMemory(unsigned char *,colorspace.numberOfComponents*
+ image->columns*(tile_height+1));
+ if (scanline == (unsigned char *) NULL)
+ {
+ FPX_ClearSystem();
+ (void) FPX_CloseImage(flashpix);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ /*
+ Initialize FlashPix image description.
+ */
+ fpx_info.numberOfComponents=colorspace.numberOfComponents;
+ for (i=0; i < 4; i++)
+ {
+ fpx_info.components[i].myColorType.myDataType=DATA_TYPE_UNSIGNED_BYTE;
+ fpx_info.components[i].horzSubSampFactor=1;
+ fpx_info.components[i].vertSubSampFactor=1;
+ fpx_info.components[i].columnStride=fpx_info.numberOfComponents;
+ fpx_info.components[i].lineStride=
+ image->columns*fpx_info.components[i].columnStride;
+ fpx_info.components[i].theData=scanline+i;
+ }
+ fpx_info.components[0].myColorType.myColor=
+ fpx_info.numberOfComponents > 2 ? NIFRGB_R : MONOCHROME;
+ red_component=(&fpx_info.components[0]);
+ fpx_info.components[1].myColorType.myColor=
+ fpx_info.numberOfComponents > 2 ? NIFRGB_G : ALPHA;
+ green_component=(&fpx_info.components[1]);
+ fpx_info.components[2].myColorType.myColor=NIFRGB_B;
+ blue_component=(&fpx_info.components[2]);
+ fpx_info.components[3].myColorType.myColor=ALPHA;
+ alpha_component=(&fpx_info.components[fpx_info.numberOfComponents-1]);
+ FPX_SetResampleMethod(FPX_LINEAR_INTERPOLATION);
+ /*
+ Initialize image pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=GetIndexes(image);
+ if ((y % tile_height) == 0)
+ {
+ /*
+ Read FPX image tile (with or without viewing affine)..
+ */
+ if (image_info->view != (char *) NULL)
+ fpx_status=FPX_ReadImageRectangle(flashpix,0,y,image->columns,y+
+ tile_height-1,subimage,&fpx_info);
+ else
+ fpx_status=FPX_ReadImageTransformRectangle(flashpix,0.0F,
+ (float) y/image->rows,(float) image->columns/image->rows,
+ (float) (y+tile_height-1)/image->rows,(long) image->columns,
+ (long) tile_height,&fpx_info);
+ if (fpx_status == FPX_LOW_MEMORY_ERROR)
+ {
+ MagickFreeMemory(scanline);
+ (void) FPX_CloseImage(flashpix);
+ FPX_ClearSystem();
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ }
+ /*
+ Transfer a FPX scanline.
+ */
+ r=red_component->theData+(y % tile_height)*red_component->lineStride;
+ g=green_component->theData+(y % tile_height)*green_component->lineStride;
+ b=blue_component->theData+(y % tile_height)*blue_component->lineStride;
+ a=alpha_component->theData+(y % tile_height)*alpha_component->lineStride;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (fpx_info.numberOfComponents > 2)
+ {
+ q->red=ScaleCharToQuantum(*r);
+ q->green=ScaleCharToQuantum(*g);
+ q->blue=ScaleCharToQuantum(*b);
+ }
+ else
+ {
+ index=ScaleCharToQuantum(*r);
+ indexes[x]=index;
+ q->red=index;
+ q->green=index;
+ q->blue=index;
+ }
+ if (image->matte)
+ q->opacity=ScaleCharToQuantum(255-*a);
+ q++;
+ r+=red_component->columnStride;
+ g+=green_component->columnStride;
+ b+=blue_component->columnStride;
+ a+=alpha_component->columnStride;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitor(LoadImageText,y,image->rows,exception))
+ break;
+ }
+ MagickFreeMemory(scanline);
+ (void) FPX_CloseImage(flashpix);
+ FPX_ClearSystem();
+ return(image);
+}
+#else
+static Image *ReadFPXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ ThrowException(exception,MissingDelegateError,FPXLibraryIsNotAvailable,
+ image_info->filename);
+ return((Image *) NULL);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r F P X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterFPXImage adds attributes for the FPX image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterFPXImage method is:
+%
+% RegisterFPXImage(void)
+%
+*/
+ModuleExport void RegisterFPXImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("FPX");
+ entry->decoder=(DecoderHandler) ReadFPXImage;
+ entry->encoder=(EncoderHandler) WriteFPXImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->blob_support=False;
+ entry->magick=(MagickHandler) IsFPX;
+ entry->description="FlashPix Format";
+ entry->module="FPX";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r F P X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterFPXImage removes format registrations made by the
+% FPX module from the list of supported formats.
+%
+% The format of the UnregisterFPXImage method is:
+%
+% UnregisterFPXImage(void)
+%
+*/
+ModuleExport void UnregisterFPXImage(void)
+{
+ (void) UnregisterMagickInfo("FPX");
+}
+
+#if defined(HasFPX)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e F P X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteFPXImage writes an image in the FlashPix image format. This
+% method was contributed by BillR@corbis.com.
+%
+% The format of the WriteFPXImage method is:
+%
+% unsigned int WriteFPXImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o fpx_status: Method WriteFPXImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static void ColorTwistMultiply(FPXColorTwistMatrix first,
+ FPXColorTwistMatrix second,FPXColorTwistMatrix *color_twist)
+{
+ /*
+ Matrix multiply.
+ */
+ assert(color_twist != (FPXColorTwistMatrix *) NULL);
+ color_twist->byy=(first.byy*second.byy)+(first.byc1*second.bc1y)+
+ (first.byc2*second.bc2y)+(first.dummy1_zero*second.dummy4_zero);
+ color_twist->byc1=(first.byy*second.byc1)+(first.byc1*second.bc1c1)+
+ (first.byc2*second.bc2c1)+(first.dummy1_zero*second.dummy5_zero);
+ color_twist->byc2=(first.byy*second.byc2)+(first.byc1*second.bc1c2)+
+ (first.byc2*second.bc2c2)+(first.dummy1_zero*second.dummy6_zero);
+ color_twist->dummy1_zero=(first.byy*second.dummy1_zero)+
+ (first.byc1*second.dummy2_zero)+(first.byc2*second.dummy3_zero)+
+ (first.dummy1_zero*second.dummy7_one);
+ color_twist->bc1y=(first.bc1y*second.byy)+(first.bc1c1*second.bc1y)+
+ (first.bc1c2*second.bc2y)+(first.dummy2_zero*second.dummy4_zero);
+ color_twist->bc1c1=(first.bc1y*second.byc1)+(first.bc1c1*second.bc1c1)+
+ (first.bc1c2*second.bc2c1)+(first.dummy2_zero*second.dummy5_zero);
+ color_twist->bc1c2=(first.bc1y*second.byc2)+(first.bc1c1*second.bc1c2)+
+ (first.bc1c2*second.bc2c2)+(first.dummy2_zero*second.dummy6_zero);
+ color_twist->dummy2_zero=(first.bc1y*second.dummy1_zero)+
+ (first.bc1c1*second.dummy2_zero)+(first.bc1c2*second.dummy3_zero)+
+ (first.dummy2_zero*second.dummy7_one);
+ color_twist->bc2y=(first.bc2y*second.byy)+(first.bc2c1*second.bc1y)+
+ (first.bc2c2*second.bc2y)+(first.dummy3_zero*second.dummy4_zero);
+ color_twist->bc2c1=(first.bc2y*second.byc1)+(first.bc2c1*second.bc1c1)+
+ (first.bc2c2*second.bc2c1)+(first.dummy3_zero*second.dummy5_zero);
+ color_twist->bc2c2=(first.bc2y*second.byc2)+(first.bc2c1*second.bc1c2)+
+ (first.bc2c2*second.bc2c2)+(first.dummy3_zero*second.dummy6_zero);
+ color_twist->dummy3_zero=(first.bc2y*second.dummy1_zero)+
+ (first.bc2c1*second.dummy2_zero)+(first.bc2c2*second.dummy3_zero)+
+ (first.dummy3_zero*second.dummy7_one);
+ color_twist->dummy4_zero=(first.dummy4_zero*second.byy)+
+ (first.dummy5_zero*second.bc1y)+(first.dummy6_zero*second.bc2y)+
+ (first.dummy7_one*second.dummy4_zero);
+ color_twist->dummy5_zero=(first.dummy4_zero*second.byc1)+
+ (first.dummy5_zero*second.bc1c1)+(first.dummy6_zero*second.bc2c1)+
+ (first.dummy7_one*second.dummy5_zero);
+ color_twist->dummy6_zero=(first.dummy4_zero*second.byc2)+
+ (first.dummy5_zero*second.bc1c2)+(first.dummy6_zero*second.bc2c2)+
+ (first.dummy7_one*second.dummy6_zero);
+ color_twist->dummy7_one=(first.dummy4_zero*second.dummy1_zero)+
+ (first.dummy5_zero*second.dummy2_zero)+
+ (first.dummy6_zero*second.dummy3_zero)+(first.dummy7_one*second.dummy7_one);
+}
+
+static void SetBrightness(double brightness,FPXColorTwistMatrix *color_twist)
+{
+ FPXColorTwistMatrix
+ effect,
+ result;
+
+ /*
+ Set image brightness in color twist matrix.
+ */
+ assert(color_twist != (FPXColorTwistMatrix *) NULL);
+ brightness=sqrt((double) brightness);
+ effect.byy=brightness;
+ effect.byc1=0.0;
+ effect.byc2=0.0;
+ effect.dummy1_zero=0.0;
+ effect.bc1y=0.0;
+ effect.bc1c1=brightness;
+ effect.bc1c2=0.0;
+ effect.dummy2_zero=0.0;
+ effect.bc2y=0.0;
+ effect.bc2c1=0.0;
+ effect.bc2c2=brightness;
+ effect.dummy3_zero=0.0;
+ effect.dummy4_zero=0.0;
+ effect.dummy5_zero=0.0;
+ effect.dummy6_zero=0.0;
+ effect.dummy7_one=1.0;
+ ColorTwistMultiply(*color_twist,effect,&result);
+ *color_twist=result;
+}
+
+static void SetColorBalance(double red,double green,double blue,
+ FPXColorTwistMatrix *color_twist)
+{
+ FPXColorTwistMatrix
+ blue_effect,
+ green_effect,
+ result,
+ rgb_effect,
+ rg_effect,
+ red_effect;
+
+ /*
+ Set image color balance in color twist matrix.
+ */
+ assert(color_twist != (FPXColorTwistMatrix *) NULL);
+ red=sqrt((double) red)-1.0;
+ green=sqrt((double) green)-1.0;
+ blue=sqrt((double) blue)-1.0;
+ red_effect.byy=1.0;
+ red_effect.byc1=0.0;
+ red_effect.byc2=0.299*red;
+ red_effect.dummy1_zero=0.0;
+ red_effect.bc1y=(-0.299)*red;
+ red_effect.bc1c1=1.0-0.299*red;
+ red_effect.bc1c2=(-0.299)*red;
+ red_effect.dummy2_zero=0.0;
+ red_effect.bc2y=0.701*red;
+ red_effect.bc2c1=0.0;
+ red_effect.bc2c2=1.0+0.402*red;
+ red_effect.dummy3_zero=0.0;
+ red_effect.dummy4_zero=0.0;
+ red_effect.dummy5_zero=0.0;
+ red_effect.dummy6_zero=0.0;
+ red_effect.dummy7_one=1.0;
+ green_effect.byy=1.0;
+ green_effect.byc1=(-0.114)*green;
+ green_effect.byc2=(-0.299)*green;
+ green_effect.dummy1_zero=0.0;
+ green_effect.bc1y=(-0.587)*green;
+ green_effect.bc1c1=1.0-0.473*green;
+ green_effect.bc1c2=0.299*green;
+ green_effect.dummy2_zero=0.0;
+ green_effect.bc2y=(-0.587)*green;
+ green_effect.bc2c1=0.114*green;
+ green_effect.bc2c2=1.0-0.288*green;
+ green_effect.dummy3_zero=0.0;
+ green_effect.dummy4_zero=0.0;
+ green_effect.dummy5_zero=0.0;
+ green_effect.dummy6_zero=0.0;
+ green_effect.dummy7_one=1.0;
+ blue_effect.byy=1.0;
+ blue_effect.byc1=0.114*blue;
+ blue_effect.byc2=0.0;
+ blue_effect.dummy1_zero=0.0;
+ blue_effect.bc1y=0.886*blue;
+ blue_effect.bc1c1=1.0+0.772*blue;
+ blue_effect.bc1c2=0.0;
+ blue_effect.dummy2_zero=0.0;
+ blue_effect.bc2y=(-0.114)*blue;
+ blue_effect.bc2c1=(-0.114)*blue;
+ blue_effect.bc2c2=1.0-0.114*blue;
+ blue_effect.dummy3_zero=0.0;
+ blue_effect.dummy4_zero=0.0;
+ blue_effect.dummy5_zero=0.0;
+ blue_effect.dummy6_zero=0.0;
+ blue_effect.dummy7_one=1.0;
+ ColorTwistMultiply(red_effect,green_effect,&rg_effect);
+ ColorTwistMultiply(rg_effect,blue_effect,&rgb_effect);
+ ColorTwistMultiply(*color_twist,rgb_effect,&result);
+ *color_twist=result;
+}
+
+static void SetSaturation(double saturation,FPXColorTwistMatrix *color_twist)
+{
+ FPXColorTwistMatrix
+ effect,
+ result;
+
+ /*
+ Set image saturation in color twist matrix.
+ */
+ assert(color_twist != (FPXColorTwistMatrix *) NULL);
+ effect.byy=1.0;
+ effect.byc1=0.0;
+ effect.byc2=0.0;
+ effect.dummy1_zero=0.0;
+ effect.bc1y=0.0;
+ effect.bc1c1=saturation;
+ effect.bc1c2=0.0;
+ effect.dummy2_zero=0.0;
+ effect.bc2y=0.0;
+ effect.bc2c1=0.0;
+ effect.bc2c2=saturation;
+ effect.dummy3_zero=0.0;
+ effect.dummy4_zero=0.0;
+ effect.dummy5_zero=0.0;
+ effect.dummy6_zero=0.0;
+ effect.dummy7_one=1.0;
+ ColorTwistMultiply(*color_twist,effect,&result);
+ *color_twist=result;
+}
+
+static unsigned int WriteFPXImage(const ImageInfo *image_info,Image *image)
+{
+ FPXBackground
+ background_color;
+
+ FPXColorspace
+ colorspace =
+ {
+ TRUE, 4,
+ {
+ { NIFRGB_R, DATA_TYPE_UNSIGNED_BYTE },
+ { NIFRGB_G, DATA_TYPE_UNSIGNED_BYTE },
+ { NIFRGB_B, DATA_TYPE_UNSIGNED_BYTE },
+ { ALPHA, DATA_TYPE_UNSIGNED_BYTE }
+ }
+ };
+
+ const ImageAttribute
+ *comment,
+ *label;
+
+ FPXCompressionOption
+ compression;
+
+ FPXImageDesc
+ fpx_info;
+
+ FPXImageHandle
+ *flashpix;
+
+ FPXStatus
+ fpx_status;
+
+ FPXSummaryInformation
+ summary_info;
+
+ long
+ y;
+
+ register long
+ i;
+
+ unsigned char
+ *pixels;
+
+ size_t
+ memory_limit;
+
+ unsigned long
+ tile_height,
+ tile_width;
+
+ /*
+ Open output file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ /*
+ Initialize FPX toolkit.
+ */
+ image->depth=8;
+ (void) TransformColorspace(image,RGBColorspace);
+ memory_limit=20000000;
+ fpx_status=FPX_SetToolkitMemoryLimit(&memory_limit);
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(DelegateError,UnableToInitializeFPXLibrary,image);
+ tile_width=64;
+ tile_height=64;
+ colorspace.numberOfComponents=3;
+ if (image->matte)
+ colorspace.numberOfComponents=4;
+ if ((image_info->type != TrueColorType) &&
+ IsGrayImage(image,&image->exception))
+ {
+ colorspace.numberOfComponents=1;
+ colorspace.theComponents[0].myColor=MONOCHROME;
+ }
+ background_color.color1_value=0;
+ background_color.color2_value=0;
+ background_color.color3_value=0;
+ background_color.color4_value=0;
+ compression=NONE;
+ if (image_info->compression == JPEGCompression)
+ compression=JPEG_UNSPECIFIED;
+ {
+ fpx_status=FPX_CreateImageByFilename(image->filename,image->columns,
+ image->rows,tile_width,tile_height,colorspace,background_color,
+ compression,&flashpix);
+ }
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ if (image_info->compression == JPEGCompression)
+ {
+ /*
+ Initialize the compression by quality for the entire image.
+ */
+ fpx_status=
+ FPX_SetJPEGCompression(flashpix,(unsigned short) (image_info->quality));
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(CoderError,UnableToSetJPEGLevel,image);
+ }
+ /*
+ Set image summary info.
+ */
+ summary_info.title_valid=False;
+ summary_info.subject_valid=False;
+ summary_info.author_valid=False;
+ summary_info.comments_valid=False;
+ summary_info.keywords_valid=False;
+ summary_info.OLEtemplate_valid=False;
+ summary_info.last_author_valid=False;
+ summary_info.rev_number_valid=False;
+ summary_info.edit_time_valid=False;
+ summary_info.last_printed_valid=False;
+ summary_info.create_dtm_valid=False;
+ summary_info.last_save_dtm_valid=False;
+ summary_info.page_count_valid=False;
+ summary_info.word_count_valid=False;
+ summary_info.char_count_valid=False;
+ summary_info.thumbnail_valid=False;
+ summary_info.appname_valid=False;
+ summary_info.security_valid=False;
+ label=GetImageAttribute(image,"label");
+ if (label != (ImageAttribute *) NULL)
+ {
+ /*
+ Note image label.
+ */
+ summary_info.title_valid=True;
+ summary_info.title.length=strlen(label->value);
+ summary_info.title.ptr=MagickAllocateMemory(unsigned char *,
+ strlen(label->value)+1);
+ if (summary_info.title.ptr != (unsigned char *) NULL)
+ (void) strlcpy((char *) summary_info.title.ptr,label->value,
+ MaxTextExtent);
+ else
+ ThrowWriterException(CoderError,UnableToSetImageTitle,image);
+ }
+ comment=GetImageAttribute(image,"comment");
+ if (comment != (ImageAttribute *) NULL)
+ {
+ /*
+ Note image comment.
+ */
+ summary_info.comments_valid=True;
+ summary_info.comments.length=strlen(comment->value);
+ summary_info.comments.ptr=MagickAllocateMemory(unsigned char *,
+ strlen(comment->value)+1);
+ if (summary_info.comments.ptr != (unsigned char *) NULL)
+ (void) strcpy((char *) summary_info.comments.ptr,comment->value);
+ else
+ ThrowWriterException(CoderError,UnableToSetImageComments,image);
+ }
+ fpx_status=FPX_SetSummaryInformation(flashpix,&summary_info);
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(CoderError,UnableToSetSummaryInfo,image);
+ /*
+ Allocate pixels.
+ */
+ pixels=MagickAllocateMemory(unsigned char *,
+ colorspace.numberOfComponents*image->columns);
+ if (pixels == (unsigned char *) NULL)
+ {
+ (void) FPX_CloseImage(flashpix);
+ FPX_ClearSystem();
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ /*
+ Initialize FlashPix image description.
+ */
+ fpx_info.numberOfComponents=colorspace.numberOfComponents;
+ for (i=0; i < (long) fpx_info.numberOfComponents; i++)
+ {
+ fpx_info.components[i].myColorType.myDataType=DATA_TYPE_UNSIGNED_BYTE;
+ fpx_info.components[i].horzSubSampFactor=1;
+ fpx_info.components[i].vertSubSampFactor=1;
+ fpx_info.components[i].columnStride=fpx_info.numberOfComponents;
+ fpx_info.components[i].lineStride=
+ image->columns*fpx_info.components[i].columnStride;
+ fpx_info.components[i].theData=pixels+i;
+ }
+ fpx_info.components[0].myColorType.myColor=
+ fpx_info.numberOfComponents != 1 ? NIFRGB_R : MONOCHROME;
+ fpx_info.components[1].myColorType.myColor=NIFRGB_G;
+ fpx_info.components[2].myColorType.myColor=NIFRGB_B;
+ fpx_info.components[3].myColorType.myColor=ALPHA;
+ /*
+ Write image scanlines.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (!AcquireImagePixels(image,0,y,image->columns,1,&image->exception))
+ break;
+ if (fpx_info.numberOfComponents == 1)
+ (void) ExportImagePixelArea(image,GrayQuantum,8,pixels,0,0);
+ else
+ if (!image->matte)
+ (void) ExportImagePixelArea(image,RGBQuantum,8,pixels,0,0);
+ else
+ (void) ExportImagePixelArea(image,RGBAQuantum,8,pixels,0,0);
+ fpx_status=FPX_WriteImageLine(flashpix,&fpx_info);
+ if (fpx_status != FPX_OK)
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitor(SaveImageText,y,image->rows,&image->exception))
+ break;
+ }
+ if (image_info->view != (char *) NULL)
+ {
+ FPXAffineMatrix
+ affine;
+
+ FPXColorTwistMatrix
+ color_twist;
+
+ FPXContrastAdjustment
+ contrast;
+
+ FPXFilteringValue
+ sharpen;
+
+ FPXResultAspectRatio
+ aspect_ratio;
+
+ FPXROI
+ view_rect;
+
+ unsigned int
+ affine_valid,
+ aspect_ratio_valid,
+ color_twist_valid,
+ contrast_valid,
+ sharpen_valid,
+ view_rect_valid;
+
+ /*
+ Initialize default viewing parameters.
+ */
+ contrast=1.0;
+ contrast_valid=False;
+ color_twist.byy=1.0;
+ color_twist.byc1=0.0;
+ color_twist.byc2=0.0;
+ color_twist.dummy1_zero=0.0;
+ color_twist.bc1y=0.0;
+ color_twist.bc1c1=1.0;
+ color_twist.bc1c2=0.0;
+ color_twist.dummy2_zero=0.0;
+ color_twist.bc2y=0.0;
+ color_twist.bc2c1=0.0;
+ color_twist.bc2c2=1.0;
+ color_twist.dummy3_zero=0.0;
+ color_twist.dummy4_zero=0.0;
+ color_twist.dummy5_zero=0.0;
+ color_twist.dummy6_zero=0.0;
+ color_twist.dummy7_one=1.0;
+ color_twist_valid=False;
+ sharpen=0.0;
+ sharpen_valid=False;
+ aspect_ratio=(double) image->columns/image->rows;
+ aspect_ratio_valid=False;
+ view_rect.left=(float) 0.1;
+ view_rect.width=aspect_ratio-0.2;
+ view_rect.top=(float) 0.1;
+ view_rect.height=(float) 0.8; /* 1.0-0.2 */
+ view_rect_valid=False;
+ affine.a11=1.0;
+ affine.a12=0.0;
+ affine.a13=0.0;
+ affine.a14=0.0;
+ affine.a21=0.0;
+ affine.a22=1.0;
+ affine.a23=0.0;
+ affine.a24=0.0;
+ affine.a31=0.0;
+ affine.a32=0.0;
+ affine.a33=1.0;
+ affine.a34=0.0;
+ affine.a41=0.0;
+ affine.a42=0.0;
+ affine.a43=0.0;
+ affine.a44=1.0;
+ affine_valid=False;
+ if (0)
+ {
+ /*
+ Color color twist.
+ */
+ SetBrightness(0.5,&color_twist);
+ SetSaturation(0.5,&color_twist);
+ SetColorBalance(0.5,1.0,1.0,&color_twist);
+ color_twist_valid=True;
+ }
+ if (affine_valid)
+ {
+ fpx_status=FPX_SetImageAffineMatrix(flashpix,&affine);
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(CoderError,UnableToSetAffineMatrix,image);
+ }
+ if (aspect_ratio_valid)
+ {
+ fpx_status=FPX_SetImageResultAspectRatio(flashpix,&aspect_ratio);
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(CoderError,UnableToSetAspectRatio,image);
+ }
+ if (color_twist_valid)
+ {
+ fpx_status=FPX_SetImageColorTwistMatrix(flashpix,&color_twist);
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(CoderError,UnableToSetColorTwist,image);
+ }
+ if (contrast_valid)
+ {
+ fpx_status=FPX_SetImageContrastAdjustment(flashpix,&contrast);
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(CoderError,UnableToSetContrast,image);
+ }
+ if (sharpen_valid)
+ {
+ fpx_status=FPX_SetImageFilteringValue(flashpix,&sharpen);
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(CoderError,UnableToSetFilteringValue,
+ image);
+ }
+ if (view_rect_valid)
+ {
+ fpx_status=FPX_SetImageROI(flashpix,&view_rect);
+ if (fpx_status != FPX_OK)
+ ThrowWriterException(CoderError,UnableToSetRegionOfInterest,
+ image);
+ }
+ }
+ (void) FPX_CloseImage(flashpix);
+ FPX_ClearSystem();
+ MagickFreeMemory(pixels);
+ return(True);
+}
+#else
+static unsigned int WriteFPXImage(const ImageInfo *image_info,Image *image)
+{
+ ThrowBinaryException(MissingDelegateError,FPXLibraryIsNotAvailable,
+ image->filename)
+}
+#endif
diff --git a/coders/gif.c b/coders/gif.c
new file mode 100644
index 0000000..596d670
--- /dev/null
+++ b/coders/gif.c
@@ -0,0 +1,1553 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% GGGG IIIII FFFFF %
+% G I F %
+% G GG I FFF %
+% G G I F %
+% GGG IIIII F %
+% %
+% %
+% Read/Write Compuserv Graphics Interchange Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/quantize.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static size_t
+ ReadBlobBlock(Image *,unsigned char *);
+
+static unsigned int
+ WriteGIFImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DecodeImage uncompresses an image via GIF-coding.
+%
+% The format of the DecodeImage method is:
+%
+% MagickPassFail DecodeImage(Image *image,const long opacity)
+%
+% A description of each parameter follows:
+%
+% o status: Method DecodeImage returns MagickPass if all the pixels are
+% uncompressed without error, otherwise MagickFail.
+%
+% o image: The address of a structure of type Image.
+%
+% o opacity: The colormap index associated with the transparent
+% color.
+%
+%
+*/
+#define MaxStackSize 4096L
+#define NullCode (-1)
+static MagickPassFail DecodeImage(Image *image,const long opacity)
+{
+ int
+ bits,
+ code_size,
+ offset,
+ pass;
+
+ long
+ available,
+ clear,
+ code,
+ code_mask,
+ end_of_information,
+ in_code,
+ old_code,
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *c;
+
+ register unsigned long
+ datum;
+
+ size_t
+ count;
+
+ short
+ *prefix;
+
+ unsigned char
+ data_size,
+ first,
+ index,
+ *packet,
+ *pixel_stack,
+ *suffix,
+ *top_stack;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+
+ data_size=ReadBlobByte(image);
+ if (data_size > 8U)
+ ThrowBinaryException(CorruptImageError,CorruptImage,image->filename);
+ /*
+ Allocate decoder tables.
+ */
+ packet=MagickAllocateMemory(unsigned char *,256);
+ prefix=MagickAllocateArray(short *,MaxStackSize,sizeof(short));
+ suffix=MagickAllocateMemory(unsigned char *,MaxStackSize);
+ pixel_stack=MagickAllocateMemory(unsigned char *,MaxStackSize+1);
+ if ((packet == (unsigned char *) NULL) ||
+ (prefix == (short *) NULL) ||
+ (suffix == (unsigned char *) NULL) ||
+ (pixel_stack == (unsigned char *) NULL))
+ {
+ MagickFreeMemory(pixel_stack);
+ MagickFreeMemory(suffix);
+ MagickFreeMemory(prefix);
+ MagickFreeMemory(packet);
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ }
+ /*
+ Initialize GIF data stream decoder.
+ */
+ clear=1 << data_size;
+ end_of_information=clear+1;
+ available=clear+2;
+ old_code=NullCode;
+ code_size=data_size+1;
+ code_mask=(1 << code_size)-1;
+ (void) memset(prefix,0,MaxStackSize*sizeof(short));
+ (void) memset(suffix,0,MaxStackSize);
+ for (code=0; code < clear; code++)
+ {
+ prefix[code]=0;
+ suffix[code]=(unsigned char) code;
+ }
+ /*
+ Decode GIF pixel stream.
+ */
+ datum=0;
+ bits=0;
+ c=0;
+ count=0;
+ first=0;
+ offset=0;
+ pass=0;
+ top_stack=pixel_stack;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,offset,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; )
+ {
+ if (top_stack == pixel_stack)
+ {
+ if (bits < code_size)
+ {
+ /*
+ Load bytes until there is enough bits for a code.
+ */
+ if (count == 0)
+ {
+ /*
+ Read a new data block.
+ */
+ count=ReadBlobBlock(image,packet);
+ if (count == 0)
+ break;
+ c=packet;
+ }
+ datum+=(unsigned long) (*c) << bits;
+ bits+=8;
+ c++;
+ count--;
+ continue;
+ }
+ /*
+ Get the next code.
+ */
+ code=(long) (datum & code_mask);
+ datum>>=code_size;
+ bits-=code_size;
+ /*
+ Interpret the code
+ */
+ if (code == end_of_information)
+ break;
+ if (code == clear)
+ {
+ /*
+ Reset decoder.
+ */
+ code_size=data_size+1;
+ code_mask=(1 << code_size)-1;
+ available=clear+2;
+ old_code=NullCode;
+ continue;
+ }
+ if (old_code == NullCode)
+ {
+ *top_stack++=suffix[code];
+ old_code=code;
+ first=(unsigned char) code;
+ continue;
+ }
+ in_code=code;
+ if (code >= available)
+ {
+ *top_stack++=first;
+ code=old_code;
+ }
+ /*
+ FIXME: Is the logic for this loop (or the loop which inits
+ suffix and prefix arrays) correct? Values are
+ intentionally accessed outside of the explictly
+ initialized range of 'clear'.
+ */
+ while (code >= clear)
+ {
+ if ((top_stack-pixel_stack) >= MaxStackSize)
+ {
+ status=MagickFail;
+ break;
+ }
+ *top_stack++=suffix[code];
+ code=prefix[code];
+ }
+ if (status == MagickFail)
+ break;
+ first=suffix[code];
+ /*
+ Add a new string to the string table,
+ */
+ if (available < MaxStackSize)
+ {
+ prefix[available]=(short) old_code;
+ suffix[available]=first;
+ available++;
+ if (available >= (code_mask + 1) && code_size < 12)
+ {
+ code_size++;
+ code_mask+=available;
+ }
+ }
+ *top_stack++=first;
+ old_code=in_code;
+ }
+ /*
+ Pop a pixel off the pixel stack.
+ */
+ top_stack--;
+ index=(*top_stack);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q=image->colormap[index];
+ q->opacity=(Quantum)
+ (index == opacity ? TransparentOpacity : OpaqueOpacity);
+ x++;
+ q++;
+ }
+ if (image->interlace == NoInterlace)
+ offset++;
+ else
+ switch (pass)
+ {
+ case 0:
+ default:
+ {
+ offset+=8;
+ if (offset >= (long) image->rows)
+ {
+ pass++;
+ offset=4;
+ }
+ break;
+ }
+ case 1:
+ {
+ offset+=8;
+ if (offset >= (long) image->rows)
+ {
+ pass++;
+ offset=2;
+ }
+ break;
+ }
+ case 2:
+ {
+ offset+=4;
+ if (offset >= (long) image->rows)
+ {
+ pass++;
+ offset=1;
+ }
+ break;
+ }
+ case 3:
+ {
+ offset+=2;
+ break;
+ }
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (x < (long) image->columns)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ MagickFreeMemory(pixel_stack);
+ MagickFreeMemory(suffix);
+ MagickFreeMemory(prefix);
+ MagickFreeMemory(packet);
+ if ((status == MagickFail) || (y < (long) image->rows))
+ {
+ if (image->exception.severity < ErrorException)
+ {
+ ThrowException(&image->exception,CorruptImageError,CorruptImage,image->filename);
+ }
+ return MagickFail;
+ }
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method EncodeImage compresses an image via GIF-coding.
+%
+% The format of the EncodeImage method is:
+%
+% MagickPassFail EncodeImage(const ImageInfo *image_info,Image *image,
+% const unsigned int data_size)
+%
+% A description of each parameter follows:
+%
+% o status: Method EncodeImage returns MagickPass if all the pixels are
+% compressed without error, otherwise MagickFail.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: The address of a structure of type Image.
+%
+% o data_size: The number of bits in the compressed packet.
+%
+%
+*/
+#define MaxCode(number_bits) ((1 << (number_bits))-1)
+#define MaxHashTable 5003
+#define MaxGIFBits 12
+#define MaxGIFTable (1 << MaxGIFBits)
+
+#define GIFOutputCode(code) \
+{ \
+ /* \
+ Emit a code. \
+ */ \
+ if (bits > 0) \
+ datum|=((long) code << bits); \
+ else \
+ datum=(long) code; \
+ bits+=number_bits; \
+ while (bits >= 8) \
+ { \
+ /* \
+ Add a character to current packet. \
+ */ \
+ packet[byte_count++]=(unsigned char) (datum & 0xff); \
+ if (byte_count >= 254) \
+ { \
+ (void) WriteBlobByte(image,byte_count); \
+ (void) WriteBlob(image,byte_count,(char *) packet); \
+ byte_count=0; \
+ } \
+ datum>>=8; \
+ bits-=8; \
+ } \
+ if (free_code > max_code) \
+ { \
+ number_bits++; \
+ if (number_bits == MaxGIFBits) \
+ max_code=MaxGIFTable; \
+ else \
+ max_code=MaxCode(number_bits); \
+ } \
+}
+static MagickPassFail EncodeImage(const ImageInfo *image_info,Image *image,
+ const unsigned int data_size)
+{
+
+ int
+ displacement,
+ next_pixel,
+ bits,
+ byte_count,
+ k,
+ number_bits,
+ offset,
+ pass;
+
+ long
+ datum,
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ short
+ clear_code,
+ end_of_information_code,
+ free_code,
+ *hash_code,
+ *hash_prefix,
+ index,
+ max_code,
+ waiting_code;
+
+ unsigned char
+ *packet,
+ *hash_suffix;
+
+ /*
+ Allocate encoder tables.
+ */
+ assert(image != (Image *) NULL);
+ packet=MagickAllocateMemory(unsigned char *,256);
+ hash_code=MagickAllocateArray(short *,MaxHashTable,sizeof(short));
+ hash_prefix=MagickAllocateArray(short *,MaxHashTable,sizeof(short));
+ hash_suffix=MagickAllocateMemory(unsigned char *,MaxHashTable);
+ if ((packet == (unsigned char *) NULL) || (hash_code == (short *) NULL) ||
+ (hash_prefix == (short *) NULL) ||
+ (hash_suffix == (unsigned char *) NULL))
+ {
+ MagickFreeMemory(packet);
+ MagickFreeMemory(hash_code);
+ MagickFreeMemory(hash_prefix);
+ MagickFreeMemory(hash_suffix);
+ return(MagickFail);
+ }
+ /*
+ Initialize GIF encoder.
+ */
+ number_bits=data_size;
+ max_code=MaxCode(number_bits);
+ clear_code=((short) 1 << (data_size-1));
+ end_of_information_code=clear_code+1;
+ free_code=clear_code+2;
+ byte_count=0;
+ datum=0;
+ bits=0;
+ for (i=0; i < MaxHashTable; i++)
+ hash_code[i]=0;
+ GIFOutputCode(clear_code);
+ /*
+ Encode pixels.
+ */
+ offset=0;
+ pass=0;
+ waiting_code=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,offset,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ if (y == 0)
+ waiting_code=(*indexes);
+ for (x=(y == 0) ? 1 : 0; x < (long) image->columns; x++)
+ {
+ /*
+ Probe hash table.
+ */
+ index=indexes[x] & 0xff;
+ p++;
+ k=(int) ((int) index << (MaxGIFBits-8))+waiting_code;
+ if (k >= MaxHashTable)
+ k-=MaxHashTable;
+ next_pixel=False;
+ displacement=1;
+ if ((image_info->compression != NoCompression) && (hash_code[k] > 0))
+ {
+ if ((hash_prefix[k] == waiting_code) && (hash_suffix[k] == index))
+ {
+ waiting_code=hash_code[k];
+ continue;
+ }
+ if (k != 0)
+ displacement=MaxHashTable-k;
+ for ( ; ; )
+ {
+ k-=displacement;
+ if (k < 0)
+ k+=MaxHashTable;
+ if (hash_code[k] == 0)
+ break;
+ if ((hash_prefix[k] == waiting_code) && (hash_suffix[k] == index))
+ {
+ waiting_code=hash_code[k];
+ next_pixel=True;
+ break;
+ }
+ }
+ if (next_pixel == True)
+ continue;
+ }
+ GIFOutputCode(waiting_code);
+ if (free_code < MaxGIFTable)
+ {
+ hash_code[k]=free_code++;
+ hash_prefix[k]=waiting_code;
+ hash_suffix[k]=(unsigned char) index;
+ }
+ else
+ {
+ /*
+ Fill the hash table with empty entries.
+ */
+ for (k=0; k < MaxHashTable; k++)
+ hash_code[k]=0;
+ /*
+ Reset compressor and issue a clear code.
+ */
+ free_code=clear_code+2;
+ GIFOutputCode(clear_code);
+ number_bits=data_size;
+ max_code=MaxCode(number_bits);
+ }
+ waiting_code=index;
+ }
+ if ((image_info->interlace == NoInterlace) ||
+ (image_info->interlace == UndefinedInterlace))
+ offset++;
+ else
+ switch (pass)
+ {
+ case 0:
+ default:
+ {
+ offset+=8;
+ if (offset >= (long) image->rows)
+ {
+ pass++;
+ offset=4;
+ }
+ break;
+ }
+ case 1:
+ {
+ offset+=8;
+ if (offset >= (long) image->rows)
+ {
+ pass++;
+ offset=2;
+ }
+ break;
+ }
+ case 2:
+ {
+ offset+=4;
+ if (offset >= (long) image->rows)
+ {
+ pass++;
+ offset=1;
+ }
+ break;
+ }
+ case 3:
+ {
+ offset+=2;
+ break;
+ }
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ /*
+ Flush out the buffered code.
+ */
+ GIFOutputCode(waiting_code);
+ GIFOutputCode(end_of_information_code);
+ if (bits > 0)
+ {
+ /*
+ Add a character to current packet.
+ */
+ packet[byte_count++]=(unsigned char) (datum & 0xff);
+ if (byte_count >= 254)
+ {
+ (void) WriteBlobByte(image,byte_count);
+ (void) WriteBlob(image,byte_count,(char *) packet);
+ byte_count=0;
+ }
+ }
+ /*
+ Flush accumulated data.
+ */
+ if (byte_count > 0)
+ {
+ (void) WriteBlobByte(image,byte_count);
+ (void) WriteBlob(image,byte_count,(char *) packet);
+ }
+ /*
+ Free encoder memory.
+ */
+ MagickFreeMemory(hash_suffix);
+ MagickFreeMemory(hash_prefix);
+ MagickFreeMemory(hash_code);
+ MagickFreeMemory(packet);
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s G I F %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsGIF returns MagickTrue if the image format type, identified by
+% the magick string, is GIF.
+%
+% The format of the IsGIF method is:
+%
+% MagickBool IsGIF(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsGIF returns True if the image format type is GIF.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static MagickBool IsGIF(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(MagickFalse);
+ if (LocaleNCompare((char *) magick,"GIF8",4) == 0)
+ return(MagickTrue);
+ return(MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b B l o c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobBlock reads data from the image file and returns it. The
+% amount of data is determined by first reading a count byte. The number
+% of bytes read is returned.
+%
+% The format of the ReadBlobBlock method is:
+%
+% size_t ReadBlobBlock(Image *image,unsigned char *data)
+%
+% A description of each parameter follows:
+%
+% o count: Method ReadBlobBlock returns the number of bytes read.
+%
+% o image: The image.
+%
+% o data: Specifies an area to place the information requested from
+% the file.
+%
+%
+*/
+static size_t ReadBlobBlock(Image *image,unsigned char *data)
+{
+ size_t
+ count=0;
+
+ unsigned char
+ block_count;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (unsigned char *) NULL);
+ if (ReadBlob(image,1,&block_count) == 1)
+ {
+ if ((count=ReadBlob(image,(size_t) block_count,data)) != (size_t) block_count)
+ count=0;
+ }
+ return count;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d G I F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadGIFImage reads a Compuserve Graphics image file and returns it.
+% It allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadGIFImage method is:
+%
+% Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadGIFImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% an error occurs.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define BitSet(byte,bit) (((byte) & (bit)) == (bit))
+#define LSBFirstOrder(x,y) (((y) << 8) | (x))
+static Image *ReadGIFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ int
+ status;
+
+ long
+ opacity;
+
+ RectangleInfo
+ page;
+
+ register unsigned int
+ i;
+
+ register unsigned char
+ *p;
+
+ size_t
+ count;
+
+ unsigned char
+ background,
+ c,
+ flag,
+ *global_colormap,
+ header[MaxTextExtent],
+ magick[12];
+
+ unsigned long
+ delay,
+ dispose,
+ global_colors,
+ image_count,
+ iterations;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Determine if this is a GIF file.
+ */
+ count=ReadBlob(image,6,(char *) magick);
+ if ((count != 6) || ((LocaleNCompare((char *) magick,"GIF87",5) != 0) &&
+ (LocaleNCompare((char *) magick,"GIF89",5) != 0)))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ global_colors=0;
+ global_colormap=(unsigned char *) NULL;
+ page.width=ReadBlobLSBShort(image);
+ page.height=ReadBlobLSBShort(image);
+ flag=ReadBlobByte(image);
+ background=ReadBlobByte(image);
+ c=ReadBlobByte(image); /* reserved */
+ global_colors=1 << ((flag & 0x07)+1);
+ global_colormap=MagickAllocateArray(unsigned char *,3,Max(global_colors,256));
+ if (global_colormap == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (BitSet(flag,0x80))
+ (void) ReadBlob(image,3*global_colors,(char *) global_colormap);
+ delay=0;
+ dispose=0;
+ iterations=1;
+ opacity=(-1);
+ image_count=0;
+ for ( ; ; )
+ {
+ count=ReadBlob(image,1,(char *) &c);
+ if (count != 1)
+ break;
+ if (c == ';')
+ break; /* terminator */
+ if (c == '!')
+ {
+ /*
+ GIF Extension block.
+ */
+ count=ReadBlob(image,1,(char *) &c);
+ if (count != 1) {
+ MagickFreeMemory(global_colormap);
+ ThrowReaderException(CorruptImageError,UnableToReadExtensionBlock,
+ image);
+ }
+ switch (c)
+ {
+ case 0xf9:
+ {
+ /*
+ Read Graphics Control extension.
+ */
+ while (ReadBlobBlock(image,header) != 0);
+ dispose=header[0] >> 2;
+ delay=(header[2] << 8) | header[1];
+ if ((header[0] & 0x01) == 1)
+ opacity=(header[3] & 0xff);
+ break;
+ }
+ case 0xfe:
+ {
+ char
+ *comments;
+
+ /*
+ Read Comment extension.
+ */
+ comments=AllocateString((char *) NULL);
+ for ( ; ; )
+ {
+ count=ReadBlobBlock(image,header);
+ if (count == 0)
+ break;
+ header[count]='\0';
+ (void) ConcatenateString(&comments,(const char *) header);
+ }
+ (void) SetImageAttribute(image,"comment",comments);
+ MagickFreeMemory(comments);
+ break;
+ }
+ case 0xff:
+ {
+ int
+ loop;
+
+ /*
+ Read Netscape Loop extension.
+ */
+ loop=False;
+ if (ReadBlobBlock(image,header) != 0)
+ loop=!LocaleNCompare((char *) header,"NETSCAPE2.0",11);
+ while (ReadBlobBlock(image,header) != 0)
+ if (loop)
+ {
+ iterations=(header[2] << 8) | header[1];
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Loop extension with iterations %lu",
+ iterations);
+
+ }
+ break;
+ }
+ default:
+ {
+ while (ReadBlobBlock(image,header) != 0);
+ break;
+ }
+ }
+ }
+ if (c != ',')
+ continue;
+ if (image_count != 0)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ MagickFreeMemory(global_colormap);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+ image_count++;
+ /*
+ Read image attributes.
+ */
+ image->storage_class=PseudoClass;
+ image->compression=LZWCompression;
+ page.x=ReadBlobLSBShort(image);
+ page.y=ReadBlobLSBShort(image);
+ image->columns=ReadBlobLSBShort(image);
+ image->rows=ReadBlobLSBShort(image);
+ image->depth=8;
+ flag=ReadBlobByte(image);
+ image->interlace=BitSet(flag,0x40) ? LineInterlace : NoInterlace;
+ image->colors=!BitSet(flag,0x80) ? global_colors : 0x01U << ((flag & 0x07)+1);
+ if (opacity >= (long) image->colors)
+ image->colors=opacity+1;
+ image->page.width=page.width;
+ image->page.height=page.height;
+ image->page.y=page.y;
+ image->page.x=page.x;
+ image->delay=delay;
+ image->dispose=(DisposeType) dispose;
+ image->iterations=iterations;
+ image->matte=opacity >= 0;
+ delay=0;
+ dispose=0;
+ iterations=1;
+ if ((image->columns == 0) || (image->rows == 0)) {
+ MagickFreeMemory(global_colormap);
+ ThrowReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+ }
+ /*
+ Inititialize colormap.
+ */
+ if (!AllocateImageColormap(image,image->colors)) {
+ MagickFreeMemory(global_colormap);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ if (!BitSet(flag,0x80))
+ {
+ /*
+ Use global colormap.
+ */
+ p=global_colormap;
+ for (i=0; i < image->colors; i++)
+ {
+ VerifyColormapIndex(image, i);
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ if ((long) i == opacity)
+ image->colormap[i].opacity=(Quantum) TransparentOpacity;
+ }
+ image->background_color=
+ image->colormap[Min(background,image->colors-1)];
+ }
+ else
+ {
+ unsigned char
+ *colormap;
+
+ /*
+ Read local colormap.
+ */
+ colormap=MagickAllocateArray(unsigned char *,3,image->colors);
+ if (colormap == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(global_colormap);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ if (ReadBlob(image,3*image->colors,(char *) colormap) != 3*image->colors)
+ {
+ MagickFreeMemory(global_colormap);
+ MagickFreeMemory(colormap);
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ }
+ p=colormap;
+ for (i=0; i < image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ if ((long) i == opacity)
+ image->colormap[i].opacity=(Quantum) TransparentOpacity;
+ }
+ MagickFreeMemory(colormap);
+ }
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Decode image.
+ */
+ status=DecodeImage(image,opacity);
+ if (!image_info->ping && (status == False)) {
+ MagickFreeMemory(global_colormap);
+ GetImageException(image,exception);
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ }
+ MagickFreeMemory(global_colormap);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r G I F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterGIFImage adds attributes for the GIF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterGIFImage method is:
+%
+% RegisterGIFImage(void)
+%
+*/
+ModuleExport void RegisterGIFImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("GIF");
+ entry->decoder=(DecoderHandler) ReadGIFImage;
+ entry->encoder=(EncoderHandler) WriteGIFImage;
+ entry->magick=(MagickHandler) IsGIF;
+ entry->description="CompuServe graphics interchange format";
+ entry->version="version 89a";
+ entry->module="GIF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("GIF87");
+ entry->decoder=(DecoderHandler) ReadGIFImage;
+ entry->encoder=(EncoderHandler) WriteGIFImage;
+ entry->magick=(MagickHandler) IsGIF;
+ entry->adjoin=False;
+ entry->description="CompuServe graphics interchange format";
+ entry->version="version 87a";
+ entry->module="GIF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r G I F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterGIFImage removes format registrations made by the
+% GIF module from the list of supported formats.
+%
+% The format of the UnregisterGIFImage method is:
+%
+% UnregisterGIFImage(void)
+%
+*/
+ModuleExport void UnregisterGIFImage(void)
+{
+ (void) UnregisterMagickInfo("GIF");
+ (void) UnregisterMagickInfo("GIF87");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e G I F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteGIFImage writes an image to a file in the Compuserve Graphics
+% image format.
+%
+% The format of the WriteGIFImage method is:
+%
+% MagickPassFail WriteGIFImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteGIFImage return MagickPass if the image is written.
+% MagickFail is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static MagickPassFail WriteGIFImage(const ImageInfo *image_info,Image *image)
+{
+ Image
+ *next_image;
+
+ int
+ y;
+
+ long
+ opacity;
+
+ QuantizeInfo
+ quantize_info;
+
+ RectangleInfo
+ page;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register unsigned int
+ i;
+
+ register unsigned char
+ *q;
+
+ size_t
+ j;
+
+ unsigned char
+ bits_per_pixel,
+ c,
+ *colormap,
+ *global_colormap;
+
+ unsigned int
+ interlace,
+ status;
+
+ unsigned long
+ scene;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Determine image bounding box.
+ */
+ page.width=image->columns;
+ page.height=image->rows;
+ page.x=0;
+ page.y=0;
+ for (next_image=image; next_image != (Image *) NULL; )
+ {
+ page.x=next_image->page.x;
+ page.y=next_image->page.y;
+ if ((next_image->columns+page.x) > page.width)
+ page.width=next_image->columns+page.x;
+ if ((next_image->rows+page.y) > page.height)
+ page.height=next_image->rows+page.y;
+ next_image=next_image->next;
+ }
+ /*
+ Allocate colormap.
+ */
+ global_colormap=MagickAllocateMemory(unsigned char *,768);
+ colormap=MagickAllocateMemory(unsigned char *,768);
+ if ((global_colormap == (unsigned char *) NULL) ||
+ (colormap == (unsigned char *) NULL))
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (i=0; i < 768; i++)
+ colormap[i]=0;
+ /*
+ Write GIF header.
+ */
+ if ((GetImageAttribute(image,"comment") == (ImageAttribute *) NULL) &&
+ !image_info->adjoin && !image->matte)
+ (void) WriteBlob(image,6,"GIF87a");
+ else
+ if (LocaleCompare(image_info->magick,"GIF87") == 0)
+ (void) WriteBlob(image,6,"GIF87a");
+ else
+ (void) WriteBlob(image,6,"GIF89a");
+ page.x=image->page.x;
+ page.y=image->page.y;
+ if ((image->page.width != 0) && (image->page.height != 0))
+ page=image->page;
+ (void) WriteBlobLSBShort(image,page.width);
+ (void) WriteBlobLSBShort(image,page.height);
+ /*
+ Write images to file.
+ */
+ interlace=(image_info->interlace == UndefinedInterlace ? NoInterlace :
+ image_info->interlace);
+ if (image_info->adjoin && (image->next != (Image *) NULL))
+ interlace=NoInterlace;
+ opacity=(-1);
+ scene=0;
+ do
+ {
+ (void) TransformColorspace(image,RGBColorspace);
+ if ((image->storage_class == DirectClass) || (image->colors > 256))
+ {
+ /*
+ GIF requires that the image is colormapped.
+ */
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.dither=image_info->dither;
+ quantize_info.number_colors=image->matte ? 255 : 256;
+ (void) QuantizeImage(&quantize_info,image);
+ if (image->matte)
+ {
+ /*
+ Set transparent pixel.
+ */
+ opacity=(long) image->colors++;
+ MagickReallocMemory(PixelPacket *,image->colormap,
+ image->colors*sizeof(PixelPacket));
+ if (image->colormap == (PixelPacket *) NULL)
+ {
+ MagickFreeMemory(global_colormap);
+ MagickFreeMemory(colormap);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image)
+ }
+ image->colormap[opacity]=image->background_color;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register IndexPacket
+ *indexes;
+
+ p=GetImagePixelsEx(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (p->opacity == TransparentOpacity)
+ indexes[x]=(IndexPacket) opacity;
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+ }
+ else
+ if (image->matte)
+ {
+ /*
+ Identify transparent pixel index.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register const IndexPacket
+ *indexes;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (p->opacity == TransparentOpacity)
+ {
+ opacity=(long) indexes[x];
+ break;
+ }
+ p++;
+ }
+ if (x < (long) image->columns)
+ break;
+ }
+ }
+ if (image->colormap == (PixelPacket *) NULL)
+ break;
+ for (bits_per_pixel=1; bits_per_pixel < 8; bits_per_pixel++)
+ if ((1UL << bits_per_pixel) >= image->colors)
+ break;
+ q=colormap;
+ for (i=0; i < image->colors; i++)
+ {
+ *q++=ScaleQuantumToChar(image->colormap[i].red);
+ *q++=ScaleQuantumToChar(image->colormap[i].green);
+ *q++=ScaleQuantumToChar(image->colormap[i].blue);
+ }
+ for ( ; i < (1U << bits_per_pixel); i++)
+ {
+ *q++=(Quantum) 0x0;
+ *q++=(Quantum) 0x0;
+ *q++=(Quantum) 0x0;
+ }
+ if ((image->previous == (Image *) NULL) || !image_info->adjoin)
+ {
+ /*
+ Write global colormap.
+ */
+ c=0x80;
+ c|=(8-1) << 4; /* color resolution */
+ c|=(bits_per_pixel-1); /* size of global colormap */
+ (void) WriteBlobByte(image,c);
+ for (p=image->colormap, j=0; j < Max(image->colors-1,1); j++, p++)
+ if (ColorMatch(&image->background_color,p))
+ break;
+ (void) WriteBlobByte(image,(long) j); /* background color */
+ (void) WriteBlobByte(image,0x0); /* reserved */
+ (void) WriteBlob(image,3*(1 << bits_per_pixel),(char *) colormap);
+ for (j=0; j < 768; j++)
+ global_colormap[j]=colormap[j];
+ }
+ if (LocaleCompare(image_info->magick,"GIF87") != 0)
+ {
+ /*
+ Write Graphics Control extension.
+ */
+ (void) WriteBlobByte(image,0x21);
+ (void) WriteBlobByte(image,0xf9);
+ (void) WriteBlobByte(image,0x04);
+ c=(unsigned char) ((int) image->dispose << 2);
+ if (opacity >= 0)
+ c|=0x01;
+ (void) WriteBlobByte(image,c);
+ (void) WriteBlobLSBShort(image,image->delay);
+ (void) WriteBlobByte(image,opacity >= 0 ? opacity : 0);
+ (void) WriteBlobByte(image,0x00);
+ {
+ const ImageAttribute
+ *attribute;
+
+ if (((attribute=GetImageAttribute(image,"comment")) !=
+ (ImageAttribute *) NULL) &&
+ (attribute->value != (const char *) NULL))
+ {
+ register char
+ *p;
+
+ size_t
+ count;
+
+ /*
+ Write Comment extension.
+ */
+ (void) WriteBlobByte(image,0x21);
+ (void) WriteBlobByte(image,0xfe);
+ p=attribute->value;
+ while (strlen(p) != 0)
+ {
+ count=Min(strlen(p),255);
+ (void) WriteBlobByte(image,(long) count);
+ for (i=0; i < count; i++)
+ (void) WriteBlobByte(image,*p++);
+ }
+ (void) WriteBlobByte(image,0x0);
+ }
+ }
+ if ((image->previous == (Image *) NULL) &&
+ (image->next != (Image *) NULL) && (image->iterations != 1))
+ {
+ /*
+ Write Netscape Loop extension.
+ */
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Loop extension with iterations %lu",
+ image->iterations);
+ (void) WriteBlobByte(image,0x21);
+ (void) WriteBlobByte(image,0xff);
+ (void) WriteBlobByte(image,0x0b);
+ (void) WriteBlob(image,11,"NETSCAPE2.0");
+ (void) WriteBlobByte(image,0x03);
+ (void) WriteBlobByte(image,0x01);
+ (void) WriteBlobLSBShort(image,image->iterations);
+ (void) WriteBlobByte(image,0x00);
+ }
+ }
+ (void) WriteBlobByte(image,','); /* image separator */
+ /*
+ Write the image header.
+ */
+ page.x=image->page.x;
+ page.y=image->page.y;
+ if ((image->page.width != 0) && (image->page.height != 0))
+ page=image->page;
+ (void) WriteBlobLSBShort(image,page.x);
+ (void) WriteBlobLSBShort(image,page.y);
+ (void) WriteBlobLSBShort(image,image->columns);
+ (void) WriteBlobLSBShort(image,image->rows);
+ c=0x00;
+ if (interlace != NoInterlace)
+ c|=0x40; /* pixel data is interlaced */
+ for (j=0; j < (3*image->colors); j++)
+ if (colormap[j] != global_colormap[j])
+ break;
+ if (j == (3*image->colors))
+ (void) WriteBlobByte(image,c);
+ else
+ {
+ c|=0x80;
+ c|=(bits_per_pixel-1); /* size of local colormap */
+ (void) WriteBlobByte(image,c);
+ (void) WriteBlob(image,3*(1 << bits_per_pixel),(char *) colormap);
+ }
+ /*
+ Write the image data.
+ */
+ c=Max(bits_per_pixel,2);
+ (void) WriteBlobByte(image,c);
+ status=EncodeImage(image_info,image,Max(bits_per_pixel,2)+1);
+ if (status == MagickFail)
+ {
+ MagickFreeMemory(global_colormap);
+ MagickFreeMemory(colormap);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image)
+ }
+ (void) WriteBlobByte(image,0x0);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == MagickFail)
+ break;
+ } while (image_info->adjoin);
+ (void) WriteBlobByte(image,';'); /* terminator */
+ MagickFreeMemory(global_colormap);
+ MagickFreeMemory(colormap);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(MagickPass);
+}
diff --git a/coders/gradient.c b/coders/gradient.c
new file mode 100644
index 0000000..e81de62
--- /dev/null
+++ b/coders/gradient.c
@@ -0,0 +1,185 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% GGGG RRRR AAA DDDD IIIII EEEEE N N TTTTT %
+% G R R A A D D I E NN N T %
+% G GG RRRR AAAAA D D I EEE N N N T %
+% G G R R A A D D I E N NN T %
+% GGG R R A A DDDD IIIII EEEEE N N T %
+% %
+% %
+% Read An Image Filled Using Gradient. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/color_lookup.h"
+#include "magick/gradient.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+#include "magick/studio.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d G R A D I E N T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadGRADIENTImage creates a gradient image and initializes it to
+% the color range as specified by the filename. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% The format of the ReadGRADIENTImage method is:
+%
+% Image *ReadGRADIENTImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadGRADIENTImage returns a pointer to the image after
+% creating it. A null image is returned if there is a memory shortage
+% or if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadGRADIENTImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ char
+ colorname[MaxTextExtent];
+
+ PixelPacket
+ start_color,
+ stop_color;
+
+ Image
+ *image;
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+ (void) SetImage(image,OpaqueOpacity);
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ (void) strlcpy(colorname,image_info->filename,MaxTextExtent);
+ (void) sscanf(image_info->filename,"%[^-]",colorname);
+ if (!QueryColorDatabase(colorname,&start_color,exception))
+ {
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ (void) strcpy(colorname,"white");
+ if (PixelIntensityToQuantum(&start_color) > (0.5*MaxRGB))
+ (void) strcpy(colorname,"black");
+ (void) sscanf(image_info->filename,"%*[^-]-%s",colorname);
+ if (!QueryColorDatabase(colorname,&stop_color,exception))
+ {
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ (void) GradientImage(image,&start_color,&stop_color);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r G R A D I E N T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterGRADIENTImage adds attributes for the GRADIENT image format
+% to the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterGRADIENTImage method is:
+%
+% RegisterGRADIENTImage(void)
+%
+*/
+ModuleExport void RegisterGRADIENTImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("GRADIENT");
+ entry->decoder=(DecoderHandler) ReadGRADIENTImage;
+ entry->adjoin=False;
+ entry->raw=True;
+ entry->description="Gradual passing from one shade to another";
+ entry->module="GRADIENT";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r G R A D I E N T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterGRADIENTImage removes format registrations made by the
+% GRADIENT module from the list of supported formats.
+%
+% The format of the UnregisterGRADIENTImage method is:
+%
+% UnregisterGRADIENTImage(void)
+%
+*/
+ModuleExport void UnregisterGRADIENTImage(void)
+{
+ (void) UnregisterMagickInfo("GRADIENT");
+}
diff --git a/coders/gray.c b/coders/gray.c
new file mode 100644
index 0000000..98ee2e4
--- /dev/null
+++ b/coders/gray.c
@@ -0,0 +1,670 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% GGGG RRRR AAA Y Y %
+% G R R A A Y Y %
+% G GG RRRR AAAAA Y %
+% G G R R A A Y %
+% GGG R R A A Y %
+% %
+% %
+% Read/Write RAW Gray Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/constitute.h"
+#include "magick/enum_strings.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteGRAYImage(const ImageInfo *,Image *);
+
+/*
+ Return an appropriate channel quantum type depending on the magick
+ format specifier.
+*/
+static QuantumType MagickToQuantumType(const char *magick,
+ const MagickBool gray_only)
+{
+ QuantumType
+ quantum_type=GrayQuantum;
+
+ /*
+ Reader returns GRAY or GRAYA images while writer writes GRAY or
+ GRAYA, or individual channels as GRAY.
+
+ For the reader, if all channels are treated as in the writer case,
+ then a color image would be returned, with only the specified
+ channel set. However, that is not what is done here.
+ */
+ if (gray_only)
+ {
+ if (strcmp(magick,"GRAY") == 0)
+ quantum_type=GrayQuantum;
+ else if (strcmp(magick,"GRAYA") == 0)
+ quantum_type=GrayAlphaQuantum;
+ }
+ else
+ {
+ if (strcmp(magick,"GRAY") == 0)
+ quantum_type=GrayQuantum;
+ else if (strcmp(magick,"GRAYA") == 0)
+ quantum_type=GrayAlphaQuantum;
+ else if (strcmp(magick,"R") == 0)
+ quantum_type=RedQuantum;
+ else if (strcmp(magick,"G") == 0)
+ quantum_type=GreenQuantum;
+ else if (strcmp(magick,"B") == 0)
+ quantum_type=BlueQuantum;
+ else if (strcmp(magick,"O") == 0)
+ quantum_type=AlphaQuantum;
+ else if (strcmp(magick,"C") == 0)
+ quantum_type=CyanQuantum;
+ else if (strcmp(magick,"M") == 0)
+ quantum_type=MagentaQuantum;
+ else if (strcmp(magick,"Y") == 0)
+ quantum_type=YellowQuantum;
+ else if (strcmp(magick,"K") == 0)
+ quantum_type=BlackQuantum;
+ }
+
+ return quantum_type;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d G R A Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadGRAYImage reads an image of raw grayscale samples and returns
+% it. It allocates the memory necessary for the new Image structure and
+% returns a pointer to the new image.
+%
+% Gray with an alpha channel is supported via magick "CMYK".
+% Red, Green, Blue, or Alpha from an RGB(A) image may be individually
+% selected for input via magick specifiers "R", "G", "B", and "A".
+% Cyan, Magenta, Yellow, Black, or Alpha from an CMYK(A) image may be
+% individually selected for input via magick specifiers "C", "M", "Y",
+% "K", and "A".
+%
+% The format of the ReadGRAYImage method is:
+%
+% Image *ReadGRAYImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadGRAYImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadGRAYImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ j,
+ y;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ size_t
+ count;
+
+ unsigned char
+ *scanline;
+
+ unsigned int
+ status;
+
+ unsigned int
+ depth,
+ quantum_size,
+ packet_size,
+ samples_per_pixel;
+
+ ImportPixelAreaOptions
+ import_options;
+
+ QuantumType
+ quantum_type;
+
+ MagickBool
+ is_grayscale;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ for (i=0; i < image->offset; i++)
+ {
+ if (EOF == ReadBlobByte(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+
+ quantum_type=MagickToQuantumType(image_info->magick,MagickTrue);
+ is_grayscale=((quantum_type == GrayQuantum) ||
+ (quantum_type == GrayAlphaQuantum));
+ /*
+ Support depth in multiples of 8 bits.
+ */
+ if (image->depth > 16)
+ depth=32;
+ else if (image->depth > 8)
+ depth=16;
+ else
+ depth=8;
+ /*
+ Allocate memory for a scanline.
+ */
+ if (depth <= 8)
+ quantum_size=8;
+ else if (depth <= 16)
+ quantum_size=16;
+ else
+ quantum_size=32;
+ samples_per_pixel=MagickGetQuantumSamplesPerPixel(quantum_type);
+ packet_size=(quantum_size*samples_per_pixel)/8;
+ scanline=MagickAllocateArray(unsigned char *,packet_size,image->tile_info.width);
+ if (scanline == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize import options.
+ */
+ ImportPixelAreaOptionsInit(&import_options);
+ if (image_info->endian != UndefinedEndian)
+ import_options.endian=image_info->endian;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Depth: %u bits, "
+ "Type: %s, "
+ "Samples/Pixel: %u, "
+ "Endian %s, "
+ "Tile: %lux%lu%+ld%+ld",
+ quantum_size,
+ QuantumTypeToString(quantum_type),
+ samples_per_pixel,
+ EndianTypeToString(import_options.endian),
+ image->tile_info.width,
+ image->tile_info.height,
+ image->tile_info.x,
+ image->tile_info.y);
+ /*
+ Support starting at intermediate image frame.
+ */
+ if (image_info->subrange != 0)
+ while (image->scene < image_info->subimage)
+ {
+ /*
+ Skip to next image.
+ */
+ image->scene++;
+ for (y=0; y < (long) image->rows; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ }
+ x=(long) (packet_size*image->tile_info.x);
+ do
+ {
+ /*
+ Convert raster image to pixel packets.
+ */
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ /*
+ Support GRAYA with matte channel
+ */
+ if (quantum_type == GrayAlphaQuantum)
+ image->matte=MagickTrue;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (!is_grayscale)
+ (void) memset(q,0,sizeof(PixelPacket)*image->columns);
+ (void) ImportImagePixelArea(image,quantum_type,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ image->is_grayscale=is_grayscale;
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (j=0; j < (long) count; j++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ count=ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (count != 0)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+ } while (count != 0);
+ MagickFreeMemory(scanline);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r G R A Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterGRAYImage adds attributes for the GRAY image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterGRAYImage method is:
+%
+% RegisterGRAYImage(void)
+%
+*/
+ModuleExport void RegisterGRAYImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("GRAY");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->description="Raw gray samples";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("GRAYA");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->description="Raw gray samples + alpha";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("R");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->description="Raw red samples";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("C");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->description="Raw cyan samples";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("G");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->description="Raw green samples";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("M");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->description="Raw magenta samples";
+ entry->module="GRAY";
+
+ (void) RegisterMagickInfo(entry);
+ entry=SetMagickInfo("B");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->description="Raw blue samples";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("Y");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->description="Raw yellow samples";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("O");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->description="Raw opacity samples";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("K");
+ entry->decoder=(DecoderHandler) ReadGRAYImage;
+ entry->encoder=(EncoderHandler) WriteGRAYImage;
+ entry->raw=True;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->description="Raw black samples";
+ entry->module="GRAY";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r G R A Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterGRAYImage removes format registrations made by the
+% GRAY module from the list of supported formats.
+%
+% The format of the UnregisterGRAYImage method is:
+%
+% UnregisterGRAYImage(void)
+%
+*/
+ModuleExport void UnregisterGRAYImage(void)
+{
+ (void) UnregisterMagickInfo("GRAY");
+ (void) UnregisterMagickInfo("GRAYA");
+ (void) UnregisterMagickInfo("R");
+ (void) UnregisterMagickInfo("C");
+ (void) UnregisterMagickInfo("G");
+ (void) UnregisterMagickInfo("M");
+ (void) UnregisterMagickInfo("B");
+ (void) UnregisterMagickInfo("Y");
+ (void) UnregisterMagickInfo("O");
+ (void) UnregisterMagickInfo("K");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e G R A Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteGRAYImage writes an image to a file as gray scale intensity
+% values. Gray with an alpha channel is supported via magick "CMYK".
+% Red, Green, Blue, or Alpha from an RGB(A) image may be individually
+% selected for output via magick specifiers "R", "G", "B", and "A".
+% Cyan, Magenta, Yellow, Black, or Alpha from an CMYK(A) image may be
+% individually selected for output via magick specifiers "C", "M", "Y",
+% "K", and "A".
+%
+% The format of the WriteGRAYImage method is:
+%
+% unsigned int WriteGRAYImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteGRAYImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static unsigned int WriteGRAYImage(const ImageInfo *image_info,Image *image)
+{
+ int
+ y;
+
+ register const PixelPacket
+ *p;
+
+ unsigned char
+ *scanline=0;
+
+ unsigned int
+ depth,
+ quantum_size,
+ packet_size,
+ samples_per_pixel,
+ scene,
+ status;
+
+ ExportPixelAreaOptions
+ export_options;
+
+ ExportPixelAreaInfo
+ export_info;
+
+ QuantumType
+ quantum_type;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ quantum_type=MagickToQuantumType(image_info->magick,MagickFalse);
+
+ /*
+ Support depth in multiples of 8 bits.
+ */
+ if (image->depth > 16)
+ depth=32;
+ else if (image->depth > 8)
+ depth=16;
+ else
+ depth=8;
+ /*
+ Convert image to gray scale PseudoColor class.
+ */
+ scene=0;
+ do
+ {
+ /*
+ Allocate memory for scanline.
+ */
+ if (depth <= 8)
+ quantum_size=8;
+ else if (depth <= 16)
+ quantum_size=16;
+ else
+ quantum_size=32;
+ samples_per_pixel=MagickGetQuantumSamplesPerPixel(quantum_type);
+ packet_size=(quantum_size*samples_per_pixel)/8;
+ /*
+ Allocate scanline
+ */
+ scanline=MagickAllocateArray(unsigned char *,packet_size,image->columns);
+ if (scanline == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Transform to target color space
+ */
+ switch (quantum_type)
+ {
+ case CyanQuantum:
+ case MagentaQuantum:
+ case YellowQuantum:
+ case BlackQuantum:
+ {
+ (void) TransformColorspace(image,CMYKColorspace);
+ break;
+ }
+ default:
+ {
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+ }
+ if (!(image->matte) &&
+ ((quantum_type == GrayAlphaQuantum) || (quantum_type == AlphaQuantum)))
+ (void) SetImageOpacity(image,OpaqueOpacity);
+ /*
+ Initialize export options.
+ */
+ ExportPixelAreaOptionsInit(&export_options);
+ if (image->endian != UndefinedEndian)
+ export_options.endian=image->endian;
+ else if (image_info->endian != UndefinedEndian)
+ export_options.endian=image_info->endian;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Depth: %u bits, "
+ "Type: %s, "
+ "Samples/Pixel: %u, "
+ "Endian %s",
+ quantum_size,
+ QuantumTypeToString(quantum_type),
+ samples_per_pixel,
+ EndianTypeToString(export_options.endian));
+ /*
+ Convert MIFF to GRAY raster scanline.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,quantum_type,quantum_size,scanline,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,scanline);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(scanline);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(scene++,GetImageListLength(image),&image->exception,
+ SaveImagesText,image->filename))
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/histogram.c b/coders/histogram.c
new file mode 100644
index 0000000..8cbe2c5
--- /dev/null
+++ b/coders/histogram.c
@@ -0,0 +1,341 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H H IIIII SSSSS TTTTT OOO GGGG RRRR AAA M M %
+% H H I SS T O O G R R A A MM MM %
+% HHHHH I SSS T O O G GG RRRR AAAAA M M M %
+% H H I SS T O O G G R R A A M M %
+% H H IIIII SSSSS T OOO GGG R R A A M M %
+% %
+% %
+% Write A Histogram Image. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteHISTOGRAMImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r H I S T O G R A M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterHISTOGRAMImage adds attributes for the Histogram image format
+% to the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterHISTOGRAMImage method is:
+%
+% RegisterHISTOGRAMImage(void)
+%
+*/
+ModuleExport void RegisterHISTOGRAMImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("HISTOGRAM");
+ entry->encoder=(EncoderHandler) WriteHISTOGRAMImage;
+ entry->adjoin=False;
+ entry->description="Histogram of the image";
+ entry->module="HISTOGRAM";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r H I S T O G R A M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterHISTOGRAMImage removes format registrations made by the
+% HISTOGRAM module from the list of supported formats.
+%
+% The format of the UnregisterHISTOGRAMImage method is:
+%
+% UnregisterHISTOGRAMImage(void)
+%
+*/
+ModuleExport void UnregisterHISTOGRAMImage(void)
+{
+ (void) UnregisterMagickInfo("HISTOGRAM");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e H I S T O G R A M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteHISTOGRAMImage writes an image to a file in Histogram format.
+% The image shows a histogram of the color (or gray) values in the image. The
+% image consists of three overlaid histograms: a red one for the red channel,
+% a green one for the green channel, and a blue one for the blue channel. The
+% image comment contains a list of unique pixel values and the number of times
+% each occurs in the image.
+%
+% This method is strongly based on a similar one written by
+% muquit@warm.semcor.com which in turn is based on ppmhistmap of netpbm.
+%
+% The format of the WriteHISTOGRAMImage method is:
+%
+% unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info,
+% Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteHISTOGRAMImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info,
+ Image *image)
+{
+#define HistogramDensity "256x200"
+
+ char
+ filename[MaxTextExtent];
+
+ double
+ scale;
+
+ FILE
+ *file;
+
+ Image
+ *histogram_image;
+
+ long
+ *blue,
+ *green,
+ maximum,
+ *red;
+
+ long
+ y;
+
+ RectangleInfo
+ geometry;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q,
+ *r;
+
+ unsigned int
+ status;
+
+ unsigned long
+ length;
+
+ /*
+ Allocate histogram image.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ (void) SetImageDepth(image,image->depth);
+ SetGeometry(image,&geometry);
+ if (image_info->density == (char *) NULL)
+ (void) GetMagickGeometry(HistogramDensity,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ else
+ (void) GetMagickGeometry(image_info->density,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ histogram_image=CloneImage(image,geometry.width,geometry.height,True,
+ &image->exception);
+ if (histogram_image == (Image *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) SetImageType(histogram_image,TrueColorType);
+ /*
+ Allocate histogram count arrays.
+ */
+ length=Max(ScaleQuantumToChar(MaxRGB)+1,histogram_image->columns);
+ red=MagickAllocateMemory(long *,length*sizeof(long));
+ green=MagickAllocateMemory(long *,length*sizeof(long));
+ blue=MagickAllocateMemory(long *,length*sizeof(long));
+ if ((red == (long *) NULL) || (green == (long *) NULL) ||
+ (blue == (long *) NULL))
+ {
+ DestroyImage(histogram_image);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image)
+ }
+ (void) memset(red,0,length*sizeof(long));
+ (void) memset(green,0,length*sizeof(long));
+ (void) memset(blue,0,length*sizeof(long));
+ /*
+ Initialize histogram count arrays.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ red[ScaleQuantumToChar(p->red)]++;
+ green[ScaleQuantumToChar(p->green)]++;
+ blue[ScaleQuantumToChar(p->blue)]++;
+ p++;
+ }
+ }
+ maximum=0;
+ for (x=0; x < (long) histogram_image->columns; x++)
+ {
+ if (maximum < red[x])
+ maximum=red[x];
+ if (maximum < green[x])
+ maximum=green[x];
+ if (maximum < blue[x])
+ maximum=blue[x];
+ }
+ if (maximum > 0L)
+ scale=(double) histogram_image->rows/maximum;
+ else
+ scale=0.0;
+ /*
+ Initialize histogram image.
+ */
+ (void) QueryColorDatabase("black",&histogram_image->background_color,
+ &image->exception);
+ (void) SetImage(histogram_image,OpaqueOpacity);
+ for (x=0; x < (long) histogram_image->columns; x++)
+ {
+ q=GetImagePixels(histogram_image,x,0,1,histogram_image->rows);
+ if (q == (PixelPacket *) NULL)
+ break;
+ y=(long) (histogram_image->rows-(long) (scale*red[x]));
+ r=q+y;
+ for ( ; y < (long) histogram_image->rows; y++)
+ {
+ r->red=MaxRGB;
+ r++;
+ }
+ y=(long) (histogram_image->rows-(long) (scale*green[x]));
+ r=q+y;
+ for ( ; y < (long) histogram_image->rows; y++)
+ {
+ r->green=MaxRGB;
+ r++;
+ }
+ y=(long) (histogram_image->rows-(long) (scale*blue[x]));
+ r=q+y;
+ for ( ; y < (long) histogram_image->rows; y++)
+ {
+ r->blue=MaxRGB;
+ r++;
+ }
+ if (!SyncImagePixels(histogram_image))
+ break;
+ if (QuantumTick(x,histogram_image->columns))
+ if (!MagickMonitorFormatted(x,histogram_image->columns,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ /*
+ Free memory resources.
+ */
+ MagickFreeMemory(blue);
+ MagickFreeMemory(green);
+ MagickFreeMemory(red);
+ file=AcquireTemporaryFileStream(filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ {
+ DestroyImage(histogram_image);
+ ThrowWriterTemporaryFileException(filename);
+ }
+ {
+ char
+ command[MaxTextExtent];
+
+ /*
+ Add a histogram as an image comment.
+ */
+ (void) GetNumberColors(image,file,&image->exception);
+ (void) fclose(file);
+ FormatString(command,"@%.1024s",filename);
+ (void) SetImageAttribute(histogram_image,"comment",command);
+ (void) LiberateTemporaryFile(filename);
+ }
+ /*
+ Write Histogram image as MIFF.
+ */
+ (void) strlcpy(filename,histogram_image->filename,MaxTextExtent);
+ (void) strlcpy(histogram_image->filename,"miff:",MaxTextExtent);
+ (void) strlcat(histogram_image->filename,filename,MaxTextExtent);
+ status=WriteImage(image_info,histogram_image);
+ DestroyImage(histogram_image);
+ return(status);
+}
diff --git a/coders/hrz.c b/coders/hrz.c
new file mode 100644
index 0000000..627d1dd
--- /dev/null
+++ b/coders/hrz.c
@@ -0,0 +1,244 @@
+/*
+% Copyright (C) 2009 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% H H RRRR ZZZZZ %
+% H H R R ZZ %
+% HHHHH RRRR Z %
+% H H R R ZZ %
+% H H R R ZZZZZ %
+% %
+% %
+% Slow scan TV. %
+% %
+% %
+% Software Design %
+% Jaroslav Fojtik %
+% March 2009 %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+#include "magick/constitute.h"
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d H R Z I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadHRZImage reads an HRZ X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadHRZImage method is:
+%
+% Image *ReadHRZImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadHRZImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadHRZImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image *image;
+ int i;
+ unsigned width,height;
+ long ldblk, j;
+ unsigned char *BImgBuff=NULL;
+ unsigned int status;
+ const PixelPacket *q;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Read HRZ image.
+ */
+ width = 256;
+ height = 240;
+
+ ldblk = (long)(3*width);
+
+ if(GetBlobSize(image)!=(((long)ldblk)*height))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ image->columns = width;
+ image->rows = height;
+ image->depth = 8;
+
+ /* printf("HRZ header checked OK %d,%d\n",image->colors,image->depth); */
+
+ /* If ping is true, then only set image size and colors without reading any image data. */
+ if (image_info->ping) goto DONE_READING;
+
+ /* ----- Load RLE compressed raster ----- */
+ BImgBuff=MagickAllocateMemory(unsigned char *,((size_t) ldblk)); /*Ldblk was set in the check phase*/
+ if(BImgBuff==NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ for(i=0; i<(int)height; i++)
+ {
+ (void) ReadBlob(image,(size_t)ldblk,(char *)BImgBuff);
+
+ for(j=0; j<ldblk; j++)
+ {
+ BImgBuff[j] <<= 2;
+ }
+
+ q = SetImagePixels(image,0,i,image->columns,1);
+ if(q == (PixelPacket *)NULL) break;
+ (void)ImportImagePixelArea(image,RGBQuantum,8,BImgBuff,NULL,0);
+ if(!SyncImagePixels(image)) break;
+ }
+
+ if(BImgBuff!=NULL)
+ MagickFreeMemory(BImgBuff);
+ if (EOFBlob(image))
+ ThrowException(exception, CorruptImageError, UnexpectedEndOfFile, image->filename);
+
+DONE_READING:
+ CloseBlob(image);
+ return(image);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e H R Z I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Function WriteHRZImage writes an HRZ image to a file.
+%
+% The format of the WriteHRZImage method is:
+%
+% unsigned int WriteHRZImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Function WriteHRZImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+*/
+/*static unsigned int WriteHRZImage(const ImageInfo *image_info,Image *image)
+{
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return HRZ");
+
+ return(status);
+} */
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r H R Z I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterHRZImage adds attributes for the HRZ image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterHRZImage method is:
+%
+% RegisterHRZImage(void)
+%
+*/
+ModuleExport void RegisterHRZImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("HRZ");
+ entry->decoder = (DecoderHandler)ReadHRZImage;
+/*entry->encoder = (EncoderHandler)WriteHRZImage; */
+ entry->description="HRZ: Slow scan TV";
+ entry->module="HRZ";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r H R Z I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterHRZImage removes format registrations made by the
+% HRZ module from the list of supported formats.
+%
+% The format of the UnregisterHRZImage method is:
+%
+% UnregisterHRZImage(void)
+%
+*/
+ModuleExport void UnregisterHRZImage(void)
+{
+ (void) UnregisterMagickInfo("HRZ");
+}
diff --git a/coders/html.c b/coders/html.c
new file mode 100644
index 0000000..f52231f
--- /dev/null
+++ b/coders/html.c
@@ -0,0 +1,447 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H H TTTTT M M L %
+% H H T MM MM L %
+% HHHHH T M M M L %
+% H H T M M L %
+% H H T M M LLLLL %
+% %
+% %
+% Write A Client-Side Image Map Using %
+% Image Montage & Directory Information. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/paint.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteHTMLImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s H T M L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsHTML returns True if the image format type, identified by the
+% magick string, is HTML.
+%
+% The format of the IsHTML method is:
+%
+% unsigned int IsHTML(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsHTML returns True if the image format type is HTML.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsHTML(const unsigned char *magick,const size_t length)
+{
+ if (length < 5)
+ return(False);
+ if (LocaleNCompare((char *) magick,"<html",5) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r H T M L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterHTMLImage adds attributes for the HTML image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterHTMLImage method is:
+%
+% RegisterHTMLImage(void)
+%
+*/
+ModuleExport void RegisterHTMLImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("HTM");
+ entry->encoder=(EncoderHandler) WriteHTMLImage;
+ entry->magick=(MagickHandler) IsHTML;
+ entry->adjoin=False;
+ entry->description="Hypertext Markup Language and a client-side image map";
+ entry->stealth=MagickTrue;
+ entry->module="HTML";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("HTML");
+ entry->encoder=(EncoderHandler) WriteHTMLImage;
+ entry->magick=(MagickHandler) IsHTML;
+ entry->adjoin=False;
+ entry->description="Hypertext Markup Language and a client-side image map";
+ entry->module="HTML";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("SHTML");
+ entry->encoder=(EncoderHandler) WriteHTMLImage;
+ entry->magick=(MagickHandler) IsHTML;
+ entry->adjoin=False;
+ entry->description="Hypertext Markup Language and a client-side image map";
+ entry->module="HTML";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r H T M L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterHTMLImage removes format registrations made by the
+% HTML module from the list of supported formats.
+%
+% The format of the UnregisterHTMLImage method is:
+%
+% UnregisterHTMLImage(void)
+%
+*/
+ModuleExport void UnregisterHTMLImage(void)
+{
+ (void) UnregisterMagickInfo("HTM");
+ (void) UnregisterMagickInfo("HTML");
+ (void) UnregisterMagickInfo("SHTML");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e H T M L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteHTMLImage writes an image in the HTML encoded image format.
+%
+% The format of the WriteHTMLImage method is:
+%
+% unsigned int WriteHTMLImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteHTMLImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteHTMLImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ basename[MaxTextExtent],
+ buffer[MaxTextExtent],
+ filename[MaxTextExtent],
+ mapname[MaxTextExtent],
+ url[MaxTextExtent];
+
+ Image
+ *next;
+
+ ImageInfo
+ *clone_info;
+
+ RectangleInfo
+ geometry;
+
+ register char
+ *p;
+
+ unsigned int
+ status;
+
+ /*
+ Open image.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ CloseBlob(image);
+ (void) TransformColorspace(image,RGBColorspace);
+ *url='\0';
+ if ((LocaleCompare(image_info->magick,"FTP") == 0) ||
+ (LocaleCompare(image_info->magick,"HTTP") == 0))
+ {
+ /*
+ Extract URL base from filename.
+ */
+ p=strrchr(image->filename,'/');
+ if (p)
+ {
+ p++;
+ (void) strlcpy(url,image_info->magick,MaxTextExtent);
+ (void) strlcat(url,":",MaxTextExtent);
+ url[strlen(url)+p-image->filename]='\0';
+ (void) strlcat(url,image->filename,(size_t)(p-image->filename+1));
+ (void) strlcpy(image->filename,p,MaxTextExtent);
+ }
+ }
+ /*
+ Refer to image map file.
+ */
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ AppendImageFormat("map",filename);
+ GetPathComponent(filename,BasePath,basename);
+ (void) strlcpy(mapname,basename,MaxTextExtent);
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ clone_info=CloneImageInfo(image_info);
+ clone_info->adjoin=True;
+ status=True;
+ if (LocaleCompare(image_info->magick,"SHTML") != 0)
+ {
+ const ImageAttribute
+ *attribute;
+
+ /*
+ Open output image file.
+ */
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Write the HTML image file.
+ */
+ (void) WriteBlobString(image,"<html version=\"2.0\">\n");
+ (void) WriteBlobString(image,"<head>\n");
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ FormatString(buffer,"<title>%.1024s</title>\n",attribute->value);
+ else
+ {
+ GetPathComponent(filename,BasePath,basename);
+ FormatString(buffer,"<title>%.1024s</title>\n",basename);
+ }
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"</head>\n");
+ (void) WriteBlobString(image,"<body>\n");
+ (void) WriteBlobString(image,"<center>\n");
+ FormatString(buffer,"<h1>%.1024s</h1>\n",image->filename);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"<br><br>\n");
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ AppendImageFormat("gif",filename);
+ FormatString(buffer,
+ "<img ismap usemap=\"#%.1024s\" src=\"%.1024s\" border=0>\n",
+ mapname,filename);
+ (void) WriteBlobString(image,buffer);
+ /*
+ Determine the size and location of each image tile.
+ */
+ SetGeometry(image,&geometry);
+ if (image->montage != (char *) NULL)
+ {
+ (void) GetGeometry(image->montage,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ (void) GetMagickGeometry(image->montage,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ }
+ /*
+ Write an image map.
+ */
+ FormatString(buffer,"<map name=\"%.1024s\">\n",mapname);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer," <area href=\"%.1024s",url);
+ (void) WriteBlobString(image,buffer);
+ if (image->directory == (char *) NULL)
+ {
+ FormatString(buffer,"%.1024s\" shape=rect coords=\"0,0,%lu,%lu\">\n",
+ image->filename,geometry.width-1,geometry.height-1);
+ (void) WriteBlobString(image,buffer);
+ }
+ else
+ for (p=image->directory; *p != '\0'; p++)
+ if (*p != '\n')
+ (void) WriteBlobByte(image,*p);
+ else
+ {
+ FormatString(buffer,"\" shape=rect coords=\"%ld,%ld,%ld,%ld\">\n",
+ geometry.x,geometry.y,geometry.x+(long) geometry.width-1,
+ geometry.y+(long) geometry.height-1);
+ (void) WriteBlobString(image,buffer);
+ if (*(p+1) != '\0')
+ {
+ FormatString(buffer," <area href=%.1024s\"",url);
+ (void) WriteBlobString(image,buffer);
+ }
+ geometry.x+=geometry.width;
+ if (geometry.x >= (long) image->columns)
+ {
+ geometry.x=0;
+ geometry.y+=geometry.height;
+ }
+ }
+ (void) WriteBlobString(image,"</map>\n");
+ if (image->montage != (char *) NULL)
+ {
+ PixelPacket
+ transparent_color;
+
+ (void) AcquireOnePixelByReference(image,&transparent_color,0,0,&image->exception);
+ (void) TransparentImage(image,transparent_color,TransparentOpacity);
+ }
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ (void) WriteBlobString(image,"</center>\n");
+ (void) WriteBlobString(image,"</body>\n");
+ (void) WriteBlobString(image,"</html>\n");
+ CloseBlob(image);
+ /*
+ Write the image as transparent GIF.
+ */
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ AppendImageFormat("gif",image->filename);
+ next=image->next;
+ image->next=(Image *) NULL;
+ (void) strcpy(image->magick,"GIF");
+ (void) WriteImage(clone_info,image);
+ image->next=next;
+ /*
+ Determine image map filename.
+ */
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ for (p=filename+strlen(filename)-1; p > (filename+1); p--)
+ if (*p == '.')
+ {
+ (void) strncpy(image->filename,filename,(size_t) (p-filename));
+ image->filename[p-filename]='\0';
+ break;
+ }
+ (void) strcat(image->filename,"_map.shtml");
+ }
+ /*
+ Open image map.
+ */
+ status=OpenBlob(clone_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ DestroyImageInfo(clone_info);
+ /*
+ Determine the size and location of each image tile.
+ */
+ SetGeometry(image,&geometry);
+ if (image->montage != (char *) NULL)
+ {
+ (void) GetGeometry(image->montage,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ (void) GetMagickGeometry(image->montage,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ }
+ /*
+ Write an image map.
+ */
+ FormatString(buffer,"<map name=\"%.1024s\">\n",mapname);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer," <area href=\"%.1024s",url);
+ (void) WriteBlobString(image,buffer);
+ if (image->directory == (char *) NULL)
+ {
+ FormatString(buffer,"%.1024s\" shape=rect coords=\"0,0,%lu,%lu\">\n",
+ image->filename,geometry.width-1,geometry.height-1);
+ (void) WriteBlobString(image,buffer);
+ }
+ else
+ for (p=image->directory; *p != '\0'; p++)
+ if (*p != '\n')
+ (void) WriteBlobByte(image,*p);
+ else
+ {
+ FormatString(buffer,"\" shape=rect coords=\"%ld,%ld,%ld,%ld\">\n",
+ geometry.x,geometry.y,geometry.x+(long) geometry.width-1,
+ geometry.y+(long) geometry.height-1);
+ (void) WriteBlobString(image,buffer);
+ if (*(p+1) != '\0')
+ {
+ FormatString(buffer," <area href=%.1024s\"",url);
+ (void) WriteBlobString(image,buffer);
+ }
+ geometry.x+=geometry.width;
+ if (geometry.x >= (long) image->columns)
+ {
+ geometry.x=0;
+ geometry.y+=geometry.height;
+ }
+ }
+ (void) WriteBlobString(image,"</map>\n");
+ CloseBlob(image);
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ return(status);
+}
diff --git a/coders/icon.c b/coders/icon.c
new file mode 100644
index 0000000..4e432ed
--- /dev/null
+++ b/coders/icon.c
@@ -0,0 +1,456 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% IIIII CCCC OOO N N %
+% I C O O NN N %
+% I C O O N N N %
+% I C O O N NN %
+% IIIII CCCC OOO N N %
+% %
+% %
+% Read Microsoft Windows Icon Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% Re-written %
+% Bob Friesenhahn %
+% January 2015 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/* http://msdn.microsoft.com/en-us/library/ms997538.aspx */
+
+#define MaxIcons 256
+/*
+ Icon Entry
+*/
+typedef struct _IconDirEntry
+{
+ magick_uint8_t
+ width,
+ height,
+ colors,
+ reserved;
+
+ magick_uint16_t
+ planes,
+ bits_per_pixel;
+
+ magick_uint32_t
+ size,
+ offset;
+} IconDirEntry;
+
+/*
+ Icon Directory
+*/
+typedef struct _IconFile
+{
+ magick_uint16_t
+ reserved,
+ resource_type, /* 1 = ICON, 2 = CURSOR */
+ count;
+
+ IconDirEntry
+ directory[MaxIcons];
+} IconFile;
+
+static void LogICONDirEntry(const unsigned int i, const IconDirEntry *icon_entry)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "IconDirEntry[%u]:\n"
+ " Width: %u\n"
+ " Height: %u\n"
+ " Colors: %u\n"
+ " Reserved: %u\n"
+ " Planes: %u\n"
+ " BPP: %u\n"
+ " Size: %u\n"
+ " Offset: %u",
+ i,
+ (unsigned int) icon_entry->width,
+ (unsigned int) icon_entry->height,
+ (unsigned int) icon_entry->colors,
+ (unsigned int) icon_entry->reserved,
+ (unsigned int) icon_entry->planes,
+ (unsigned int) icon_entry->bits_per_pixel,
+ (unsigned int) icon_entry->size,
+ (unsigned int) icon_entry->offset
+ );
+}
+static void LogICONFile(const IconFile *icon_file)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "IconFile:\n"
+ " Reserved: %u\n"
+ " ResourceType: %u\n"
+ " Count: %u",
+ (unsigned int) icon_file->reserved,
+ (unsigned int) icon_file->resource_type,
+ (unsigned int) icon_file->count
+ );
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d I C O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadIconImage reads a Microsoft icon image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadIconImage method is:
+%
+% Image *ReadIconImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadIconImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadIconImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ IconFile
+ icon_file;
+
+ Image
+ *image;
+
+ unsigned char
+ *data;
+
+ size_t
+ data_alloc_size;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read and validate icon header
+ */
+ icon_file.reserved=ReadBlobLSBShort(image);
+ icon_file.resource_type=ReadBlobLSBShort(image);
+ icon_file.count=ReadBlobLSBShort(image);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (image->logging)
+ LogICONFile(&icon_file);
+ /*
+ Windows ICO and CUR formats are essentially the same except that
+ .CUR uses resource_type==1 while .ICO uses resource_type=2.
+ */
+ if ((icon_file.reserved != 0) ||
+ ((icon_file.resource_type != 1) &&
+ (icon_file.resource_type != 2)) ||
+ (icon_file.count > MaxIcons))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Read and validate icon directory.
+ */
+ data_alloc_size=0;
+ data=(unsigned char *) NULL;
+ for (i=0; i < icon_file.count; i++)
+ {
+ /* 0 - 255, 0 means 256! */
+ icon_file.directory[i].width=ReadBlobByte(image);
+ /* 0 - 255, 0 means 256! */
+ icon_file.directory[i].height=ReadBlobByte(image);
+ icon_file.directory[i].colors=ReadBlobByte(image);
+ icon_file.directory[i].reserved=ReadBlobByte(image);
+ icon_file.directory[i].planes=ReadBlobLSBShort(image);
+ icon_file.directory[i].bits_per_pixel=ReadBlobLSBShort(image);
+ icon_file.directory[i].size=ReadBlobLSBLong(image);
+ icon_file.directory[i].offset=ReadBlobLSBLong(image);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (image->logging)
+ LogICONDirEntry(i,&icon_file.directory[i]);
+ if (
+ /*
+ Restrict allocation size
+ */
+ (icon_file.directory[i].size < 20) ||
+ (icon_file.directory[i].size > 256+256*256*2*4) ||
+
+ /*
+ planes
+
+ In ICO format (1): Specifies color planes. Should be 0 or 1.
+
+ In CUR format (2): Specifies the horizontal coordinates of
+ the hotspot in number of pixels from the left.
+ */
+ ((icon_file.resource_type == 1) &&
+ (icon_file.directory[i].planes != 0) &&
+ (icon_file.directory[i].planes != 1)) ||
+ /*
+ bits_per_pixel
+
+ In ICO format (1): Specifies bits per pixel.
+
+ In CUR format (2): Specifies the vertical coordinates of the
+ hotspot in number of pixels from the top.
+ */
+ ((icon_file.resource_type == 1) &&
+ ((icon_file.directory[i].bits_per_pixel >= 8) &&
+ (icon_file.directory[i].colors != 0))) ||
+
+ (icon_file.directory[i].size == 0) ||
+ (icon_file.directory[i].offset == 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ data_alloc_size=Max(data_alloc_size,icon_file.directory[i].size);
+ }
+ data=MagickAllocateMemory(unsigned char *,data_alloc_size);
+ if (data == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (i=0; i < icon_file.count; i++)
+ {
+ /*
+ Verify and read icons
+ */
+ Image
+ *icon_image;
+
+ ImageInfo
+ *read_info;
+
+ char
+ dib_size[MaxTextExtent],
+ format[MaxTextExtent];
+
+ size_t
+ count;
+
+ if (SeekBlob(image,icon_file.directory[i].offset,SEEK_SET) !=
+ (magick_off_t) icon_file.directory[i].offset)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Failed to seek to offset %u",
+ icon_file.directory[i].offset);
+ MagickFreeMemory(data);
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ if ((count=ReadBlob(image,icon_file.directory[i].size,data)) != icon_file.directory[i].size)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Read %" MAGICK_SIZE_T_F "u bytes from blob"
+ " (expected %" MAGICK_SIZE_T_F "u bytes)",
+ (MAGICK_SIZE_T) count,
+ (MAGICK_SIZE_T) icon_file.directory[i].size);
+ MagickFreeMemory(data);
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ format[0]='\0';
+ if (memcmp(data,"\050\000\000\000",4) == 0)
+ (void) strcpy(format,"ICODIB");
+ else if (memcmp(data,"\211PNG\r\n\032\n",8) == 0)
+ (void) strcpy(format,"PNG");
+ if (format[0] == '\0')
+ {
+ MagickFreeMemory(data);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading icon using %s format",
+ format);
+ icon_image=(Image *) NULL;
+ read_info=CloneImageInfo(image_info);
+ if (read_info != (const ImageInfo *) NULL)
+ {
+ (void) strlcpy(read_info->magick,format,MaxTextExtent);
+ (void) strlcpy(read_info->filename,format,MaxTextExtent);
+ (void) strlcat(read_info->filename,":",MaxTextExtent);
+ FormatString(dib_size,"%ux%u",
+ icon_file.directory[i].width == 0 ? 256 :
+ icon_file.directory[i].width,
+ icon_file.directory[i].height == 0 ? 256 :
+ icon_file.directory[i].height);
+ (void) CloneString(&read_info->size,dib_size);
+ icon_image=BlobToImage(read_info,data,icon_file.directory[i].size,exception);
+ DestroyImageInfo(read_info);
+ read_info=(ImageInfo *) NULL;
+ }
+ if (icon_image == (Image *) NULL)
+ {
+ MagickFreeMemory(data);
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ DestroyBlob(icon_image);
+ icon_image->blob=ReferenceBlob(image->blob);
+ icon_image->scene=i;
+ (void) strlcpy(icon_image->magick,image_info->magick,
+ sizeof(icon_image->magick));
+ ReplaceImageInList(&image,icon_image);
+
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (i < (long) (icon_file.count-1))
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+ } /* for (i=0; i < icon_file.count; i++) */
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ MagickFreeMemory(data);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r I C O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterICONImage adds attributes for the Icon image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterICONImage method is:
+%
+% RegisterICONImage(void)
+%
+*/
+ModuleExport void RegisterICONImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("CUR");
+ entry->decoder=(DecoderHandler) ReadIconImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Microsoft Cursor Icon";
+ entry->module="ICON";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("ICO");
+ entry->decoder=(DecoderHandler) ReadIconImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Microsoft Icon";
+ entry->module="ICON";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("ICON");
+ entry->decoder=(DecoderHandler) ReadIconImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Microsoft Icon";
+ entry->module="ICON";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r I C O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterICONImage removes format registrations made by the
+% ICON module from the list of supported formats.
+%
+% The format of the UnregisterICONImage method is:
+%
+% UnregisterICONImage(void)
+%
+*/
+ModuleExport void UnregisterICONImage(void)
+{
+ (void) UnregisterMagickInfo("CUR");
+ (void) UnregisterMagickInfo("ICO");
+ (void) UnregisterMagickInfo("ICON");
+}
diff --git a/coders/identity.c b/coders/identity.c
new file mode 100644
index 0000000..8c38d10
--- /dev/null
+++ b/coders/identity.c
@@ -0,0 +1,237 @@
+/*
+% Copyright (C) 2009 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d I D E N T I T Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadIdentityImage creates a Hald CLUT identity image. The argument
+% to the IDENTITY filename (e.g. "identity:8") specifies the order of the
+% identity image. The minimum order which may be specified is 2. Higher
+% order LUTs contain more colors and are therefore more accurate, but consume
+% more memory. Typical Hald CLUT identity images have an order of between 8
+% (512x512) and 16 (4096x4096). The default order is 8.
+%
+% The format of the ReadIdentityImage method is:
+%
+% Image *ReadIdentityImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadIdentityImage returns a pointer to the image after
+% creating it. A null image is returned if there is a memory shortage
+% or if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static Image *ReadIdentityImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+#define IdentityImageText "[%s] Generating Hald CLUT identity image..."
+
+ Image
+ *image;
+
+ unsigned long
+ cube_size;
+
+ long
+ order,
+ y;
+
+ unsigned long
+ row_count=0;
+
+ unsigned int
+ status=MagickPass;
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ image=(Image *) NULL;
+ order=8;
+ if (image_info->filename[0] != '\0')
+ order=MagickAtoL(image_info->filename);
+ if (order < 2)
+ order=8;
+
+ image=AllocateImage(image_info);
+ cube_size=order*order;
+ image->columns=image->rows=order*order*order;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y += order)
+ {
+ MagickPassFail
+ thread_status;
+
+ register PixelPacket
+ *q;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_IdentityImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ q=SetImagePixelsEx(image,0,y,image->columns,order,&image->exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (q != (PixelPacket *) NULL)
+ {
+ double
+ value;
+
+ unsigned int
+ red,
+ green,
+ blue;
+
+ blue=y/order;
+ for(green = 0; green < cube_size; green++)
+ {
+ for(red = 0; red < cube_size; red++)
+ {
+ value=MaxRGBDouble * (double)red / (double)(cube_size - 1);
+ q->red = RoundDoubleToQuantum(value);
+ value = MaxRGBDouble * (double)green / (double)(cube_size - 1);
+ q->green = RoundDoubleToQuantum(value);
+ value = MaxRGBDouble * (double)blue / (double)(cube_size - 1);
+ q->blue = RoundDoubleToQuantum(value);
+ q->opacity = OpaqueOpacity;
+ q++;
+ }
+ }
+
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_IdentityImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,&image->exception,
+ IdentityImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ if (status == MagickFail)
+ {
+ DestroyImage(image);
+ image=(Image *) NULL;
+ }
+
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r I D E N T I T Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterIDENTITYImage adds attributes for the Identity image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterIDENTITYImage method is:
+%
+% RegisterIDENTITYImage(void)
+%
+*/
+ModuleExport void RegisterIDENTITYImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("IDENTITY");
+ entry->decoder=(DecoderHandler) ReadIdentityImage;
+ entry->adjoin=False;
+ entry->description="Hald CLUT identity image";
+ entry->module="IDENTITY";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r I D E N T I T Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterIDENTITYImage removes format registrations made by the
+% IDENTITY module from the list of supported formats.
+%
+% The format of the UnregisterIDENTITYImage method is:
+%
+% UnregisterIDENTITYImage(void)
+%
+*/
+ModuleExport void UnregisterIDENTITYImage(void)
+{
+ (void) UnregisterMagickInfo("IDENTITY");
+}
diff --git a/coders/info.c b/coders/info.c
new file mode 100644
index 0000000..b5ebff9
--- /dev/null
+++ b/coders/info.c
@@ -0,0 +1,219 @@
+/*
+% Copyright (C) 2010 - 2012 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/describe.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+ Forward declaractions.
+*/
+static unsigned int
+ WriteINFOImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r I N F O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterINFOImage adds attributes for the INFO image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterINFOImage method is:
+%
+% RegisterINFOImage(void)
+%
+*/
+ModuleExport void RegisterINFOImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("INFO");
+ entry->encoder=(EncoderHandler) WriteINFOImage;
+ entry->description="Image descriptive information and statistics";
+ entry->module="INFO";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r I N F O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterINFOImage removes format registrations made by the
+% INFO module from the list of supported formats.
+%
+% The format of the UnregisterINFOImage method is:
+%
+% UnregisterINFOImage(void)
+%
+*/
+ModuleExport void UnregisterINFOImage(void)
+{
+ (void) UnregisterMagickInfo("INFO");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e I N F O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteINFOImage() writes image descriptive info to stdout.
+%
+% The format of the WriteINFOImage method is:
+%
+% MagickPassFail WriteINFOImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+%
+*/
+static MagickPassFail
+WriteINFOImage(const ImageInfo *image_info,Image *image)
+{
+ MagickPassFail
+ status;
+
+ FILE
+ *file;
+
+ Image
+ *list_entry;
+
+ char
+ temporary_filename[MaxTextExtent];
+
+ const char
+ *format;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ /*
+ Obtain optional 'identify' style output specification.
+ */
+ format=AccessDefinition(image_info,"info","format");
+ if (format != (char *) NULL)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "info:format=\"%s\"",format);
+
+ /*
+ Open blob.
+ */
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Allocate and open a temporary file to write output to.
+ */
+ temporary_filename[0]='\0';
+ if ((file=GetBlobFileHandle(image)) == (FILE *) NULL)
+ {
+ if(!AcquireTemporaryFileName(temporary_filename))
+ ThrowWriterException(FileOpenError,UnableToCreateTemporaryFile,image);
+ if ((file=fopen(temporary_filename,"w")) == (FILE *) NULL)
+ {
+ (void) LiberateTemporaryFile(temporary_filename);
+ ThrowWriterException(FileOpenError,UnableToCreateTemporaryFile,image);
+ }
+
+ }
+ list_entry=image;
+
+ while (list_entry != (Image *) NULL)
+ {
+ /*
+ Avoid convert style output syntax by restoring original filename.
+ */
+ (void) strlcpy(list_entry->filename,list_entry->magick_filename,
+ sizeof(list_entry->filename));
+
+ /*
+ Describe image.
+ */
+ if (format != (char *) NULL)
+ {
+ char
+ *text;
+
+ text=TranslateText(image_info,list_entry,format);
+ if (text != (char *) NULL)
+ {
+ (void) fputs(text,file);
+ (void) fputs("\n",file);
+ MagickFreeMemory(text);
+ }
+ }
+ else
+ {
+ if ((status=DescribeImage(list_entry,file,image_info->verbose))
+ == MagickFail)
+ break;
+ }
+
+ list_entry=GetNextImageInList(list_entry);
+ }
+
+ if ('\0' != temporary_filename[0])
+ {
+ /*
+ Close temporary file.
+ */
+ (void) fclose(file);
+
+ /*
+ Send content of temporary file to blob stream.
+ */
+ if (WriteBlobFile(image,temporary_filename) == MagickFail)
+ status=MagickFail;
+ (void) LiberateTemporaryFile(temporary_filename);
+ }
+
+ CloseBlob(image);
+
+ return status;
+}
diff --git a/coders/jbig.c b/coders/jbig.c
new file mode 100644
index 0000000..2f8da39
--- /dev/null
+++ b/coders/jbig.c
@@ -0,0 +1,524 @@
+/*
+% Copyright (C) 2003, 2007 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% JJJJJ BBBB IIIII GGGG %
+% J B B I G %
+% J BBBB I G GG %
+% J J B B I G G %
+% JJJ BBBB IIIII GGG %
+% %
+% %
+% Read/Write JBIG Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+#if defined(HasJBIG)
+static unsigned int
+ WriteJBIGImage(const ImageInfo *,Image *);
+#endif
+
+#if defined(HasJBIG)
+#include "jbig.h"
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d J B I G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadJBIGImage reads a JBIG image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadJBIGImage method is:
+%
+% Image *ReadJBIGImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadJBIGImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadJBIGImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+#define MaxBufferSize 8192
+
+ Image
+ *image;
+
+ int
+ status;
+
+ size_t
+ length;
+
+ unsigned long
+ y;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ size_t
+ count;
+
+ struct jbg_dec_state
+ jbig_info;
+
+ unsigned char
+ *buffer;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Initialize JBIG toolkit.
+ */
+ jbg_dec_init(&jbig_info);
+ jbg_dec_maxsize(&jbig_info,(unsigned long) image->columns,
+ (unsigned long) image->rows);
+ image->columns= jbg_dec_getwidth(&jbig_info);
+ image->rows= jbg_dec_getheight(&jbig_info);
+ image->depth=1;
+ /*
+ Read JBIG file.
+ */
+ buffer=MagickAllocateMemory(unsigned char *,MaxBufferSize);
+ if (buffer == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ status=JBG_EAGAIN;
+ do
+ {
+ length=(long) ReadBlob(image,MaxBufferSize,(char *) buffer);
+ if (length == 0)
+ break;
+ p=buffer;
+ count=0;
+ while ((length > 0) && ((status == JBG_EAGAIN) || (status == JBG_EOK)))
+ {
+ status=jbg_dec_in(&jbig_info,p,length,&count);
+ p+=count;
+ length-=count;
+ }
+ } while ((status == JBG_EAGAIN) || (status == JBG_EOK));
+ /*
+ Create colormap.
+ */
+ image->columns=jbg_dec_getwidth(&jbig_info);
+ image->rows=jbg_dec_getheight(&jbig_info);
+ if ((image_info->type != GrayscaleType) &&
+ (image_info->type != TrueColorType))
+ {
+ if (!AllocateImageColormap(image,2))
+ {
+ MagickFreeMemory(buffer);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ image->colormap[0].red=0;
+ image->colormap[0].green=0;
+ image->colormap[0].blue=0;
+ image->colormap[1].red=MaxRGB;
+ image->colormap[1].green=MaxRGB;
+ image->colormap[1].blue=MaxRGB;
+ }
+ image->x_resolution=300;
+ image->y_resolution=300;
+ image->is_grayscale=MagickTrue;
+ image->is_monochrome=MagickTrue;
+ image->colorspace=GRAYColorspace;
+ if (image_info->ping)
+ {
+ jbg_dec_free(&jbig_info);
+ MagickFreeMemory(buffer);
+ CloseBlob(image);
+ return(image);
+ }
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ {
+ jbg_dec_free(&jbig_info);
+ MagickFreeMemory(buffer);
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ }
+ /*
+ Convert bitmap image to pixel packets.
+ */
+ {
+ ImportPixelAreaOptions
+ import_options;
+
+ ImportPixelAreaInfo
+ import_info;
+
+ ImportPixelAreaOptionsInit(&import_options);
+ import_options.grayscale_miniswhite=MagickTrue;
+ p=jbg_dec_getimage(&jbig_info,0);
+ for (y=0; y < image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (!ImportImagePixelArea(image,GrayQuantum,1,p,&import_options,&import_info))
+ break;
+ p+=import_info.bytes_imported;
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ /*
+ Free scale resource.
+ */
+ jbg_dec_free(&jbig_info);
+ MagickFreeMemory(buffer);
+ CloseBlob(image);
+ image->is_grayscale=MagickTrue;
+ image->is_monochrome=MagickTrue;
+ return(image);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r J B I G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterJBIGImage adds attributes for the JBIG image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterJBIGImage method is:
+%
+% RegisterJBIGImage(void)
+%
+*/
+ModuleExport void RegisterJBIGImage(void)
+{
+ static const char
+ *description="Joint Bi-level Image experts Group interchange format";
+
+ static char
+ version[MaxTextExtent];
+
+ MagickInfo
+ *entry;
+
+ *version='\0';
+#if defined(JBG_VERSION)
+ (void) strlcpy(version,JBG_VERSION,MaxTextExtent);
+#endif
+ entry=SetMagickInfo("BIE");
+#if defined(HasJBIG)
+ entry->decoder=(DecoderHandler) ReadJBIGImage;
+ entry->encoder=(EncoderHandler) WriteJBIGImage;
+#endif
+ entry->adjoin=False;
+ entry->description=description;
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="JBIG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("JBG");
+#if defined(HasJBIG)
+ entry->decoder=(DecoderHandler) ReadJBIGImage;
+ entry->encoder=(EncoderHandler) WriteJBIGImage;
+#endif
+ entry->description=description;
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="JBIG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("JBIG");
+#if defined(HasJBIG)
+ entry->decoder=(DecoderHandler) ReadJBIGImage;
+ entry->encoder=(EncoderHandler) WriteJBIGImage;
+#endif
+ entry->description=description;
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="JBIG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r J B I G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterJBIGImage removes format registrations made by the
+% JBIG module from the list of supported formats.
+%
+% The format of the UnregisterJBIGImage method is:
+%
+% UnregisterJBIGImage(void)
+%
+*/
+ModuleExport void UnregisterJBIGImage(void)
+{
+ (void) UnregisterMagickInfo("BIE");
+ (void) UnregisterMagickInfo("JBG");
+ (void) UnregisterMagickInfo("JBIG");
+}
+
+#if defined(HasJBIG)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e J B I G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteJBIGImage writes an image in the JBIG encoded image format.
+%
+% The format of the WriteJBIGImage method is:
+%
+% unsigned int WriteJBIGImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteJBIGImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static void JBIGEncode(unsigned char *pixels,size_t length,void *data)
+{
+ Image
+ *image;
+
+ image=(Image *) data;
+ (void) WriteBlob(image,length,pixels);
+}
+
+static unsigned int WriteJBIGImage(const ImageInfo *image_info,Image *image)
+{
+ double
+ jbig_lib_version;
+
+ unsigned long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned char
+ *q;
+
+ struct jbg_enc_state
+ jbig_info;
+
+ unsigned char
+ *pixels;
+
+ size_t
+ bytes_per_row;
+
+ unsigned int
+ status;
+
+ size_t
+ number_packets;
+
+ unsigned long
+ scene;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ jbig_lib_version=strtod(JBG_VERSION, (char **)NULL);
+ scene=0;
+ do
+ {
+ /*
+ Ensure that image is in an RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Allocate pixel data.
+ */
+ bytes_per_row=((image->columns+7) >> 3);
+ number_packets=bytes_per_row*image->rows;
+ pixels=MagickAllocateMemory(unsigned char *,number_packets);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Convert pixels to a bitmap.
+ */
+ {
+ ExportPixelAreaOptions
+ export_options;
+
+ ExportPixelAreaInfo
+ export_info;
+
+ ExportPixelAreaOptionsInit(&export_options);
+ export_options.grayscale_miniswhite=MagickTrue;
+ q=pixels;
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if (ExportImagePixelArea(image,GrayQuantum,1,q,
+ &export_options,&export_info) == MagickFail)
+ break;
+ q+=export_info.bytes_exported;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ /*
+ Initialize JBIG info structure.
+ */
+ jbg_enc_init(&jbig_info,image->columns,image->rows,1,&pixels,
+ (void (*)(unsigned char *,size_t,void *)) JBIGEncode,image);
+ if (image_info->subimage != 0)
+ jbg_enc_layers(&jbig_info,(int) image_info->subimage);
+ else
+ {
+ long
+ sans_offset;
+
+ unsigned long
+ x_resolution,
+ y_resolution;
+
+ x_resolution=640;
+ y_resolution=480;
+ sans_offset=0;
+ if (image_info->density != (char *) NULL)
+ (void) GetGeometry(image_info->density,&sans_offset,&sans_offset,
+ &x_resolution,&y_resolution);
+ (void) jbg_enc_lrlmax(&jbig_info,x_resolution,y_resolution);
+ }
+ (void) jbg_enc_lrange(&jbig_info,-1,-1);
+ jbg_enc_options(&jbig_info, /* Encoder state */
+ JBG_ILEAVE| JBG_SMID, /* Order */
+ JBG_TPDON | JBG_TPBON | JBG_DPON, /* Options */
+ /* Lines per stripe in resolution layer 0. (was -1)*/
+ (jbig_lib_version < 1.6 ? -1 : 0),
+ -1, /* mx */
+ -1); /* my */
+ /*
+ Write JBIG image.
+ */
+ jbg_enc_out(&jbig_info);
+ jbg_enc_free(&jbig_info);
+ MagickFreeMemory(pixels);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename))
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
+#endif
diff --git a/coders/jnx.c b/coders/jnx.c
new file mode 100644
index 0000000..2153588
--- /dev/null
+++ b/coders/jnx.c
@@ -0,0 +1,499 @@
+/*
+% Copyright (C) 2012-2015 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% J NN N X X %
+% J N N N X X %
+% J N N N XX %
+% JJ J N N N X X %
+% JJ N NN X X %
+% %
+% %
+% JNX: Garmin proprietary Image Format. %
+% %
+% %
+% Software Design %
+% Jaroslav Fojtik %
+% 2012 - %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+#include "magick/tempfile.h"
+#include "magick/magic.h"
+#include "magick/resource.h"
+#include "magick/attribute.h"
+
+typedef struct
+{
+ int lat, lon;
+} TJNXPoint;
+
+typedef struct
+{
+ TJNXPoint NorthEast, SouthWest;
+} TJNXRect;
+
+typedef struct
+{
+ unsigned Version;
+ unsigned DeviceSN;
+ TJNXRect MapBounds;
+ unsigned Levels;
+ unsigned Expiration;
+ unsigned ProductID;
+ unsigned CRC;
+ unsigned SigVersion;
+ unsigned SigOffset;
+ unsigned ZOrder;
+} TJNXHeader;
+
+typedef struct
+{
+ unsigned TileCount;
+ unsigned TilesOffset;
+ unsigned Scale;
+ char *Copyright;
+ unsigned Dummy;
+} TJNXLevelInfo;
+
+typedef struct
+{
+ TJNXRect TileBounds;
+ unsigned short PicWidth, PicHeight;
+ unsigned PicSize;
+ unsigned PicOffset;
+} TJNXTileInfo;
+
+
+static Image *
+ExtractTileJPG(Image * image, const ImageInfo * image_info,
+ TJNXTileInfo *TileInfo, ExceptionInfo * exception)
+{
+ size_t
+ alloc_size;
+
+ unsigned char
+ *blob;
+
+ char img_label_str[MaxTextExtent];
+
+ alloc_size = TileInfo->PicSize + 2;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent, GetMagickModule(),
+ "JNX tile offset %u, size %u bytes",
+ TileInfo->PicOffset, TileInfo->PicSize);
+
+ if ((alloc_size > TileInfo->PicSize) &&
+ (blob = MagickAllocateMemory(unsigned char *,alloc_size)) != NULL)
+ {
+ /* Add missing JPEG header bytes */
+ blob[0] = 0xFF;
+ blob[1] = 0xD8;
+
+ /* Copy JPG to memory blob */
+ if (SeekBlob(image, TileInfo->PicOffset, SEEK_SET) == TileInfo->PicOffset)
+ {
+ if (ReadBlob(image,TileInfo->PicSize,blob+2) == TileInfo->PicSize)
+ {
+ Image
+ *image2;
+
+ if ((image2 = BlobToImage(image_info,blob,alloc_size,exception))
+ != NULL)
+ {
+ /*
+ Replace current image with new image while copying
+ base image attributes.
+ */
+ (void) strlcpy(image2->filename, image->filename,
+ sizeof(image2->filename));
+ (void) strlcpy(image2->magick_filename, image->magick_filename,
+ sizeof(image2->magick_filename));
+ (void) strlcpy(image2->magick, image->magick,
+ sizeof(image2->magick));
+ image2->depth = image->depth;
+ DestroyBlob(image2);
+ image2->blob = ReferenceBlob(image->blob);
+
+ if ((image->rows == 0) || (image->columns == 0))
+ DeleteImageFromList(&image);
+
+ AppendImageToList(&image, image2);
+ }
+ }
+ else
+ {
+ /* Failed to read enough data from input */
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ }
+ }
+ else
+ {
+ /* Failed to seek in input */
+ ThrowException(exception,BlobError,UnableToSeekToOffset,
+ image->filename);
+ }
+ MagickFreeMemory(blob);
+ }
+ else
+ {
+ /* Failed to allocate memory */
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ }
+
+ FormatString(img_label_str,"%.20g,%.20g",
+ (double) TileInfo->TileBounds.NorthEast.lat*180.0/0x7FFFFFFF,
+ (double) TileInfo->TileBounds.NorthEast.lon*180.0/0x7FFFFFFF);
+ SetImageAttribute(image,"jnx:northeast",img_label_str);
+
+ FormatString(img_label_str,"%.20g,%.20g",
+ (double) TileInfo->TileBounds.SouthWest.lat*180.0/0x7FFFFFFF,
+ (double) TileInfo->TileBounds.SouthWest.lon*180.0/0x7FFFFFFF);
+ SetImageAttribute(image,"jnx:southwest",img_label_str);
+
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d J N X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadJNXImage reads an JNX X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadJNXImage method is:
+%
+% Image *ReadJNXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadJNXImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+static Image *
+ReadJNXImage(const ImageInfo * image_info, ExceptionInfo * exception)
+{
+ Image
+ *image;
+
+ unsigned int
+ i,
+ j;
+
+ TJNXHeader
+ JNXHeader;
+
+ TJNXLevelInfo
+ JNXLevelInfo[20];
+
+ unsigned int
+ status;
+
+ TJNXTileInfo
+ *PositionList = NULL;
+
+ int
+ logging;
+
+ magick_int64_t
+ SaveLimit;
+
+ unsigned int
+ total_tiles,
+ current_tile;
+
+ /* Open image file. */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ logging = LogMagickEvent(CoderEvent, GetMagickModule(), "enter");
+
+ image = AllocateImage(image_info);
+ status = OpenBlob(image_info, image, ReadBinaryBlobMode, exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError, UnableToOpenFile, image);
+
+ memset(JNXLevelInfo, 0, sizeof(JNXLevelInfo));
+
+ /* Read JNX image header. */
+ JNXHeader.Version = ReadBlobLSBLong(image);
+ if (JNXHeader.Version > 4)
+ ThrowReaderException(CorruptImageError, ImproperImageHeader, image);
+ JNXHeader.DeviceSN = ReadBlobLSBLong(image);
+ JNXHeader.MapBounds.NorthEast.lat = ReadBlobLSBLong(image);
+ JNXHeader.MapBounds.NorthEast.lon = ReadBlobLSBLong(image);
+ JNXHeader.MapBounds.SouthWest.lat = ReadBlobLSBLong(image);
+ JNXHeader.MapBounds.SouthWest.lon = ReadBlobLSBLong(image);
+ JNXHeader.Levels = ReadBlobLSBLong(image);
+ if (JNXHeader.Levels > 20)
+ ThrowReaderException(CorruptImageError, ImproperImageHeader, image);
+ JNXHeader.Expiration = ReadBlobLSBLong(image);
+ JNXHeader.ProductID = ReadBlobLSBLong(image);
+ JNXHeader.CRC = ReadBlobLSBLong(image);
+ JNXHeader.SigVersion = ReadBlobLSBLong(image);
+ JNXHeader.SigOffset = ReadBlobLSBLong(image);
+ if (JNXHeader.Version >= 4)
+ JNXHeader.ZOrder = ReadBlobLSBLong(image);
+
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ /* Read JNX image level info. */
+ total_tiles = 0;
+ current_tile = 0;
+ for (i = 0; i < JNXHeader.Levels; i++)
+ {
+ JNXLevelInfo[i].TileCount = ReadBlobLSBLong(image);
+ JNXLevelInfo[i].TilesOffset = ReadBlobLSBLong(image);
+ JNXLevelInfo[i].Scale = ReadBlobLSBLong(image);
+ total_tiles += JNXLevelInfo[i].TileCount;
+
+ if (JNXHeader.Version >= 4)
+ {
+ JNXLevelInfo[i].Dummy = ReadBlobLSBLong(image);
+ JNXLevelInfo[i].Copyright = NULL;
+ while (ReadBlobLSBShort(image) != 0)
+ {
+ /* char *Copyright; */
+ }
+ }
+ else
+ {
+ JNXLevelInfo[i].Copyright = NULL;
+ }
+ }
+
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ /* Get the current limit */
+ SaveLimit = GetMagickResourceLimit(MapResource);
+
+ /* Temporarily set the limit to zero */
+ SetMagickResourceLimit(MapResource, 0);
+
+ /* Read JNX image data. */
+ for (i = 0; i < JNXHeader.Levels; i++)
+ {
+ PositionList = MagickAllocateArray(TJNXTileInfo *,
+ JNXLevelInfo[i].TileCount,
+ sizeof(TJNXTileInfo));
+ if (PositionList == NULL)
+ continue;
+
+ (void) SeekBlob(image, JNXLevelInfo[i].TilesOffset, SEEK_SET);
+ for (j = 0; j < JNXLevelInfo[i].TileCount; j++)
+ {
+ PositionList[j].TileBounds.NorthEast.lat = ReadBlobLSBLong(image);
+ PositionList[j].TileBounds.NorthEast.lon = ReadBlobLSBLong(image);
+ PositionList[j].TileBounds.SouthWest.lat = ReadBlobLSBLong(image);
+ PositionList[j].TileBounds.SouthWest.lon = ReadBlobLSBLong(image);
+ PositionList[j].PicWidth = ReadBlobLSBShort(image);
+ PositionList[j].PicHeight = ReadBlobLSBShort(image);
+ PositionList[j].PicSize = ReadBlobLSBLong(image);
+ PositionList[j].PicOffset = ReadBlobLSBLong(image);
+ }
+
+ if (EOFBlob(image))
+ {
+ MagickFreeMemory(PositionList);
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+
+ for (j = 0; j < JNXLevelInfo[i].TileCount; j++)
+ {
+ MonitorHandler
+ previous_handler;
+
+ /* Disable progress monitor while loading individual tiles */
+ previous_handler = SetMonitorHandler(0);
+ image = ExtractTileJPG(image, image_info, PositionList+j, exception);
+ (void) SetMonitorHandler(previous_handler);
+
+ current_tile++;
+ if (QuantumTick(current_tile,total_tiles))
+ if (!MagickMonitorFormatted(current_tile,total_tiles,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+
+ MagickFreeMemory(PositionList);
+ }
+
+ CloseBlob(image);
+
+ /* Restore the previous limit */
+ (void) SetMagickResourceLimit(MapResource, SaveLimit);
+
+ {
+ Image *p;
+ long scene = 0;
+
+ /* Rewind list, removing any empty images while rewinding. */
+ p = image;
+ image = NULL;
+ while (p != (Image *) NULL)
+ {
+ Image *tmp = p;
+ if ((p->rows == 0) || (p->columns == 0))
+ {
+ p = p->previous;
+ DeleteImageFromList(&tmp);
+ }
+ else
+ {
+ image = p;
+ p = p->previous;
+ }
+ }
+
+ /* Fix scene numbers */
+ for (p = image; p != (Image *) NULL; p = p->next)
+ p->scene = scene++;
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent, GetMagickModule(), "return");
+ if (image == NULL)
+ ThrowReaderException(CorruptImageError, ImageFileDoesNotContainAnyImageData,
+ image);
+
+ return (image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e J N X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Function WriteJNXImage writes an JNX image to a file.
+%
+% The format of the WriteJNXImage method is:
+%
+% unsigned int WriteJNXImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Function WriteJNXImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+*/
+/*
+static MagickPassFail WriteJNXImage(const ImageInfo *image_info,Image *image)
+{
+ return(0);
+}
+*/
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r J N X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterJNXImage adds attributes for the JNX image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterJNXImage method is:
+%
+% RegisterJNXImage(void)
+%
+*/
+ModuleExport void RegisterJNXImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry = SetMagickInfo("JNX");
+ entry->decoder = (DecoderHandler) ReadJNXImage;
+ /* entry->encoder = (EncoderHandler)WriteJNXImage; */
+ entry->description = "JNX: Garmin tile storage format";
+ entry->module = "JNX";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r J N X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterJNXImage removes format registrations made by the
+% JNX module from the list of supported formats.
+%
+% The format of the UnregisterJNXImage method is:
+%
+% UnregisterJNXImage(void)
+%
+*/
+ModuleExport void UnregisterJNXImage(void)
+{
+ (void) UnregisterMagickInfo("JNX");
+}
diff --git a/coders/jp2.c b/coders/jp2.c
new file mode 100644
index 0000000..50edf39
--- /dev/null
+++ b/coders/jp2.c
@@ -0,0 +1,1240 @@
+/*
+% Copyright (C) 2003-2017 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% JJJ PPPP 222 %
+% J P P 2 2 %
+% J PPPP 22 %
+% J J P 2 %
+% JJ P 22222 %
+% %
+% %
+% Read/Write JPEG-2000 Image Format. %
+% %
+% %
+% John Cristy %
+% Nathan Brown %
+% June 2001 %
+% Bob Friesenhahn %
+% February 2003 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/profile.h"
+#include "magick/utility.h"
+#if defined(HasJP2)
+#if !defined(uchar)
+#define uchar unsigned char
+#endif
+#if !defined(ushort)
+#define ushort unsigned short
+#endif
+#if !defined(uint)
+#define uint unsigned int
+#endif
+#if !defined(longlong)
+#define longlong long long
+#endif
+#if !defined(ulonglong)
+#define ulonglong unsigned long long
+#endif
+
+#ifdef __VMS
+#define JAS_VERSION 1.700.0
+#define PACKAGE jasper
+#define VERSION 1.700.0
+#endif
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#include "jasper/jasper.h"
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#endif
+
+/*
+ Forward declarations.
+*/
+#if defined(HasJP2)
+static unsigned int
+ WriteJP2Image(const ImageInfo *,Image *);
+#endif
+
+static MagickBool jasper_initialized=MagickFalse;
+static const char * const jasper_options[] =
+ {
+ "imgareatlx",
+ "imgareatly",
+ "tilegrdtlx",
+ "tilegrdtly",
+ "tilewidth",
+ "tileheight",
+ "prcwidth",
+ "prcheight",
+ "cblkwidth",
+ "cblkheight",
+ "mode",
+ "ilyrrates",
+ "prg",
+ "nomct",
+ "numrlvls",
+ "sop",
+ "eph",
+ "lazy",
+ "rate",
+ "termall",
+ "segsym",
+ "vcausal",
+ "pterm",
+ "resetprob",
+ "numgbits",
+ NULL
+ };
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s J P 2 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsJP2 returns True if the image format type, identified by the
+% magick string, is JP2.
+%
+% The format of the IsJP2 method is:
+%
+% unsigned int IsJP2(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsJP2 returns True if the image format type is JP2.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsJP2(const unsigned char *magick,const size_t length)
+{
+ if (length < 9)
+ return(False);
+ if (memcmp(magick+4,"\152\120\040\040\015",5) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s J P C %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsJPC returns True if the image format type, identified by the
+% magick string, is JPC.
+%
+% The format of the IsJPC method is:
+%
+% unsigned int IsJPC(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsJPC returns True if the image format type is JPC.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsJPC(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if (memcmp(magick,"\377\117",2) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P G X %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPGX returns True if the image format type, identified by the
+% magick string, is PGX.
+%
+% The format of the IsPGX method is:
+%
+% unsigned int IsPGX(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPGX returns True if the image format type is PGX.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPGX(const unsigned char *magick,const size_t length)
+{
+ if (length < 5)
+ return(False);
+ if ((memcmp(magick,"PG ML",5) == 0) || (memcmp(magick,"PG LM",5) == 0))
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d J P 2 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadJP2Image reads a JPEG 2000 Image file (JP2) or JPEG 2000
+% codestream (JPC) image file and returns it. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image or set of images.
+%
+% JP2 support is originally written by Nathan Brown, nathanbrown@letu.edu.
+%
+% The format of the ReadJP2Image method is:
+%
+% Image *ReadJP2Image(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadJP2Image returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+#if defined(HasJP2)
+
+typedef struct _StreamManager
+{
+ jas_stream_t
+ *stream;
+
+ Image
+ *image;
+} StreamManager;
+
+static int BlobRead(jas_stream_obj_t *object,char *buffer,const int length)
+{
+ size_t
+ count;
+
+ StreamManager
+ *source = (StreamManager *) object;
+
+ count=ReadBlob(source->image,(size_t) length,(void *) buffer);
+ return ((int) count);
+}
+
+static int BlobWrite(jas_stream_obj_t *object,char *buffer,const int length)
+{
+ size_t
+ count;
+
+ StreamManager
+ *source = (StreamManager *) object;
+
+ count=WriteBlob(source->image,(size_t) length,(void *) buffer);
+ return((int) count);
+}
+
+static long BlobSeek(jas_stream_obj_t *object,long offset,int origin)
+{
+ StreamManager
+ *source = (StreamManager *) object;
+
+ return (SeekBlob(source->image,offset,origin));
+}
+
+static int BlobClose(jas_stream_obj_t *object)
+{
+ StreamManager
+ *source = (StreamManager *) object;
+
+ CloseBlob(source->image);
+ MagickFreeMemory(source);
+ return (0);
+}
+
+
+static jas_stream_t *JP2StreamManager(jas_stream_ops_t *stream_ops, Image *image)
+{
+ jas_stream_t
+ *stream;
+
+ StreamManager
+ *source;
+
+ stream=MagickAllocateMemory(jas_stream_t *,sizeof(jas_stream_t));
+ if (stream == (jas_stream_t *) NULL)
+ return((jas_stream_t *) NULL);
+ (void) memset(stream,0,sizeof(jas_stream_t));
+ stream->rwlimit_=(-1);
+ stream->obj_=MagickAllocateMemory(jas_stream_obj_t *,sizeof(StreamManager));
+ if (stream->obj_ == (jas_stream_obj_t *) NULL)
+ return((jas_stream_t *) NULL);
+ stream->ops_=stream_ops;
+ stream->openmode_=JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY;
+ stream->bufbase_=stream->tinybuf_;
+ stream->bufsize_=1;
+ stream->bufstart_=(&stream->bufbase_[JAS_STREAM_MAXPUTBACK]);
+ stream->ptr_=stream->bufstart_;
+ stream->bufmode_|=JAS_STREAM_UNBUF & JAS_STREAM_BUFMODEMASK;
+ source=(StreamManager *) stream->obj_;
+ source->image=image;
+ return(stream);
+}
+
+static Image *ReadJP2Image(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ jas_image_t
+ *jp2_image;
+
+ jas_matrix_t
+ *pixels;
+
+ jas_stream_ops_t
+ StreamOperators =
+ {
+ BlobRead,
+ BlobWrite,
+ BlobSeek,
+ BlobClose
+ };
+
+ jas_stream_t
+ *jp2_stream;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ int
+ component,
+ components[4],
+ number_components;
+
+ Quantum
+ *channel_lut[4];
+
+ unsigned int
+ status;
+
+ /*
+ Initialize Jasper
+ */
+#if defined(HasJP2)
+ if (!jasper_initialized)
+ {
+ jas_init();
+ jasper_initialized=MagickTrue;
+ }
+#endif
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Obtain a JP2 Stream.
+ */
+ jp2_stream=JP2StreamManager(&StreamOperators, image);
+ if (jp2_stream == (jas_stream_t *) NULL)
+ ThrowReaderException(DelegateError,UnableToManageJP2Stream,image);
+ jp2_image=jas_image_decode(jp2_stream,-1,0);
+ if (jp2_image == (jas_image_t *) NULL)
+ {
+ (void) jas_stream_close(jp2_stream);
+ ThrowReaderException(DelegateError,UnableToDecodeImageFile,image);
+ }
+
+ /*
+ Validate that we can handle the image and obtain component
+ indexes.
+ */
+ switch (jas_clrspc_fam(jas_image_clrspc(jp2_image)))
+ {
+ case JAS_CLRSPC_FAM_RGB:
+ {
+ if (((components[0]=
+ jas_image_getcmptbytype(jp2_image,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0) ||
+ ((components[1]=
+ jas_image_getcmptbytype(jp2_image,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0) ||
+ ((components[2]=
+ jas_image_getcmptbytype(jp2_image,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0))
+ {
+ (void) jas_stream_close(jp2_stream);
+ jas_image_destroy(jp2_image);
+ ThrowReaderException(CorruptImageError,MissingImageChannel,image);
+ }
+ number_components=3;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image is in RGB colorspace family");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "RED is in channel %d, GREEN is in channel %d, BLUE is in channel %d",
+ components[0],components[1],components[2]);
+
+ if((components[3]=jas_image_getcmptbytype(jp2_image,
+ JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY))) > 0)
+ {
+ image->matte=MagickTrue;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "OPACITY is in channel %d",components[3]);
+ number_components++;
+ }
+ break;
+ }
+ case JAS_CLRSPC_FAM_GRAY:
+ {
+ if ((components[0]=
+ jas_image_getcmptbytype(jp2_image,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y))) < 0)
+ {
+ (void) jas_stream_close(jp2_stream);
+ jas_image_destroy(jp2_image);
+ ThrowReaderException(CorruptImageError,MissingImageChannel,image);
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image is in GRAY colorspace family");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "GRAY is in channel %d",components[0]);
+ number_components=1;
+ break;
+ }
+ case JAS_CLRSPC_FAM_YCBCR:
+ {
+ components[0]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_Y);
+ components[1]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CB);
+ components[2]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_YCBCR_CR);
+ if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
+ {
+ (void) jas_stream_close(jp2_stream);
+ jas_image_destroy(jp2_image);
+ ThrowReaderException(CorruptImageError,MissingImageChannel,image);
+ }
+ number_components=3;
+ components[3]=jas_image_getcmptbytype(jp2_image,JAS_IMAGE_CT_OPACITY);
+ if (components[3] > 0)
+ {
+ image->matte=True;
+ number_components++;
+ }
+ image->colorspace=YCbCrColorspace;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image is in YCBCR colorspace family");
+ break;
+ }
+ default:
+ {
+ (void) jas_stream_close(jp2_stream);
+ jas_image_destroy(jp2_image);
+ ThrowReaderException(CoderError,ColorspaceModelIsNotSupported,image);
+ }
+ }
+ image->columns=jas_image_width(jp2_image);
+ image->rows=jas_image_height(jp2_image);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "columns=%lu rows=%lu components=%d",image->columns,image->rows,
+ number_components);
+ for (component=0; component < number_components; component++)
+ {
+ if(((unsigned long) jas_image_cmptwidth(jp2_image,components[component]) != image->columns) ||
+ ((unsigned long) jas_image_cmptheight(jp2_image,components[component]) != image->rows) ||
+ (jas_image_cmpttlx(jp2_image, components[component]) != 0) ||
+ (jas_image_cmpttly(jp2_image, components[component]) != 0) ||
+ (jas_image_cmpthstep(jp2_image, components[component]) != 1) ||
+ (jas_image_cmptvstep(jp2_image, components[component]) != 1) ||
+ (jas_image_cmptsgnd(jp2_image, components[component]) != false))
+ {
+ (void) jas_stream_close(jp2_stream);
+ jas_image_destroy(jp2_image);
+ ThrowReaderException(CoderError,IrregularChannelGeometryNotSupported,image);
+ }
+ }
+
+ image->matte=number_components > 3;
+ for (component=0; component < number_components; component++)
+ {
+ unsigned int
+ component_depth;
+
+ component_depth=jas_image_cmptprec(jp2_image,components[component]);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Component[%d] depth is %u",component,component_depth);
+ if (0 == component)
+ image->depth=component_depth;
+ else
+ image->depth=Max(image->depth,component_depth);
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image depth is %u",image->depth);
+ if (image_info->ping)
+ {
+ (void) jas_stream_close(jp2_stream);
+ jas_image_destroy(jp2_image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ {
+ (void) jas_stream_close(jp2_stream);
+ jas_image_destroy(jp2_image);
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ }
+
+ /*
+ Allocate Jasper pixels.
+ */
+ pixels=jas_matrix_create(1,(unsigned int) image->columns);
+ if (pixels == (jas_matrix_t *) NULL)
+ {
+ jas_image_destroy(jp2_image);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+
+ /*
+ Allocate and populate channel LUTs
+ */
+ for (component=0; component < (long) number_components; component++)
+ {
+ unsigned long
+ component_depth,
+ i,
+ max_value;
+
+ double
+ scale_to_quantum;
+
+ component_depth=jas_image_cmptprec(jp2_image,components[component]);
+ max_value=MaxValueGivenBits(component_depth);
+ scale_to_quantum=MaxRGBDouble/max_value;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Channel %d scale is %g", component, scale_to_quantum);
+ channel_lut[component]=MagickAllocateArray(Quantum *,max_value+1,sizeof(Quantum));
+ if (channel_lut[component] == (Quantum *) NULL)
+ {
+ for ( --component; component >= 0; --component)
+ MagickFreeMemory(channel_lut[component]);
+ jas_matrix_destroy(pixels);
+ jas_image_destroy(jp2_image);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ for(i=0; i <= max_value; i++)
+ (channel_lut[component])[i]=scale_to_quantum*i+0.5;
+ }
+
+ /*
+ Convert JPEG 2000 pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+
+ if (1 == number_components)
+ {
+ /* Grayscale */
+ (void) jas_image_readcmpt(jp2_image,(short) components[0],0,
+ (unsigned int) y,
+ (unsigned int) image->columns,1,pixels);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=q->green=q->blue=(channel_lut[0])[jas_matrix_getv(pixels,x)];
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ }
+ else
+ {
+ /* Red */
+ (void) jas_image_readcmpt(jp2_image,(short) components[0],0,
+ (unsigned int) y,
+ (unsigned int) image->columns,1,pixels);
+ for (x=0; x < (long) image->columns; x++)
+ q[x].red=(channel_lut[0])[jas_matrix_getv(pixels,x)];
+
+ /* Green */
+ (void) jas_image_readcmpt(jp2_image,(short) components[1],0,
+ (unsigned int) y,
+ (unsigned int) image->columns,1,pixels);
+ for (x=0; x < (long) image->columns; x++)
+ q[x].green=(channel_lut[1])[jas_matrix_getv(pixels,x)];
+
+ /* Blue */
+ (void) jas_image_readcmpt(jp2_image,(short) components[2],0,
+ (unsigned int) y,
+ (unsigned int) image->columns,1,pixels);
+ for (x=0; x < (long) image->columns; x++)
+ q[x].blue=(channel_lut[2])[jas_matrix_getv(pixels,x)];
+
+ /* Opacity */
+ if (number_components > 3)
+ {
+ (void) jas_image_readcmpt(jp2_image,(short) components[3],0,
+ (unsigned int) y,
+ (unsigned int) image->columns,1,pixels);
+ for (x=0; x < (long) image->columns; x++)
+ q[x].opacity=MaxRGB-(channel_lut[3])[jas_matrix_getv(pixels,x)];
+ }
+ else
+ {
+ for (x=0; x < (long) image->columns; x++)
+ q[x].opacity=OpaqueOpacity;
+ }
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (number_components == 1)
+ image->is_grayscale=MagickTrue;
+ {
+ /*
+ Obtain ICC ICM color profile
+ */
+
+ jas_cmprof_t
+ *cm_profile;
+
+ /* Obtain a pointer to the existing jas_cmprof_t profile handle. */
+ cm_profile=jas_image_cmprof(jp2_image);
+ if (cm_profile != (jas_cmprof_t *) NULL)
+ {
+ jas_iccprof_t
+ *icc_profile;
+
+ /* Obtain a copy of the jas_iccprof_t ICC profile handle */
+ icc_profile=jas_iccprof_createfromcmprof(cm_profile);
+ /* or maybe just icc_profile=cm_profile->iccprof */
+ if (icc_profile != (jas_iccprof_t *) NULL)
+ {
+ jas_stream_t
+ *icc_stream;
+
+ icc_stream=jas_stream_memopen(NULL,0);
+ if ((icc_stream != (jas_stream_t *) NULL) &&
+ (jas_iccprof_save(icc_profile,icc_stream) == 0) &&
+ (jas_stream_flush(icc_stream) == 0))
+ {
+ jas_stream_memobj_t
+ *blob;
+
+ blob=(jas_stream_memobj_t *) icc_stream->obj_;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "ICC profile: %lu bytes",(unsigned long) blob->len_);
+ SetImageProfile(image,"ICM",blob->buf_,blob->len_);
+
+ (void) jas_stream_close(icc_stream);
+ jas_iccprof_destroy(icc_profile);
+ }
+ }
+ }
+ }
+
+ for (component=0; component < (long) number_components; component++)
+ MagickFreeMemory(channel_lut[component]);
+ jas_matrix_destroy(pixels);
+ (void) jas_stream_close(jp2_stream);
+ jas_image_destroy(jp2_image);
+ return(image);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r J P 2 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterJP2Image adds attributes for the JP2 image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterJP2Image method is:
+%
+% RegisterJP2Image(void)
+%
+*/
+ModuleExport void RegisterJP2Image(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("J2C");
+ entry->description="JPEG-2000 Code Stream Syntax";
+ entry->module="JP2";
+ entry->magick=(MagickHandler) IsJPC;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->thread_support=False;
+#if defined(HasJP2)
+ entry->decoder=(DecoderHandler) ReadJP2Image;
+ entry->encoder=(EncoderHandler) WriteJP2Image;
+#endif
+ entry->coder_class=StableCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("JP2");
+ entry->description="JPEG-2000 JP2 File Format Syntax";
+ entry->module="JP2";
+ entry->magick=(MagickHandler) IsJP2;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->thread_support=False;
+#if defined(HasJP2)
+ entry->decoder=(DecoderHandler) ReadJP2Image;
+ entry->encoder=(EncoderHandler) WriteJP2Image;
+#endif
+ entry->coder_class=StableCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("JPC");
+ entry->description="JPEG-2000 Code Stream Syntax";
+ entry->module="JP2";
+ entry->magick=(MagickHandler) IsJPC;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->thread_support=False;
+#if defined(HasJP2)
+ entry->decoder=(DecoderHandler) ReadJP2Image;
+ entry->encoder=(EncoderHandler) WriteJP2Image;
+#endif
+ entry->coder_class=StableCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PGX");
+ entry->description="JPEG-2000 VM Format";
+ entry->module="JP2";
+ entry->magick=(MagickHandler) IsPGX;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->thread_support=False;
+#if defined(HasJP2)
+ entry->decoder=(DecoderHandler) ReadJP2Image;
+ entry->encoder=(EncoderHandler) WriteJP2Image;
+#endif
+ entry->coder_class=StableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r J P 2 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterJP2Image removes format registrations made by the
+% PNG module from the list of supported formats.
+%
+% The format of the UnregisterJP2Image method is:
+%
+% UnregisterJP2Image(void)
+%
+*/
+ModuleExport void UnregisterJP2Image(void)
+{
+ (void) UnregisterMagickInfo("PGX");
+ (void) UnregisterMagickInfo("JPC");
+ (void) UnregisterMagickInfo("JP2");
+ (void) UnregisterMagickInfo("J2C");
+
+#if defined(HasJP2)
+ /*
+ Cleanup Jasper
+ */
+ if (jasper_initialized)
+ {
+ jas_cleanup();
+ jasper_initialized=MagickFalse;
+ }
+#endif
+}
+
+#if defined(HasJP2)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e J P 2 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteJP2Image writes an image in the JPEG 2000 image format.
+%
+% JP2 support originally written by Nathan Brown, nathanbrown@letu.edu
+%
+% The format of the WriteJP2Image method is:
+%
+% MagickPassFail WriteJP2Image(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteJP2Image return MagickTrue if the image is written.
+% MagickFalse is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static MagickPassFail
+WriteJP2Image(const ImageInfo *image_info,Image *image)
+{
+ char
+ magick[MaxTextExtent],
+ option_keyval[MaxTextExtent],
+ *options = NULL;
+
+ int
+ format;
+
+ long
+ y;
+
+ jas_image_cmptparm_t
+ component_info;
+
+ jas_image_t
+ *jp2_image;
+
+ jas_matrix_t
+ *jp2_pixels;
+
+ jas_stream_ops_t
+ StreamOperators =
+ {
+ BlobRead,
+ BlobWrite,
+ BlobSeek,
+ BlobClose
+ };
+
+ jas_stream_t
+ *jp2_stream;
+
+ register const PixelPacket
+ *p;
+
+ register int
+ x;
+
+ unsigned int
+ rate_specified=False,
+ status;
+
+ int
+ component,
+ number_components;
+
+ unsigned short
+ *lut;
+
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Initialize Jasper
+ */
+#if defined(HasJP2)
+ if (!jasper_initialized)
+ {
+ jas_init();
+ jasper_initialized=MagickTrue;
+ }
+#endif
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Ensure that image is in RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+
+ /*
+ PGX format requires a grayscale representation
+ */
+ if (strcmp("PGX",image_info->magick) == 0)
+ (void) SetImageType(image,GrayscaleType);
+
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+
+ /*
+ Obtain a JP2 stream.
+ */
+ jp2_stream=JP2StreamManager(&StreamOperators, image);
+ if (jp2_stream == (jas_stream_t *) NULL)
+ ThrowWriterException(DelegateError,UnableToManageJP2Stream,image);
+ number_components=image->matte ? 4 : 3;
+ if ((image_info->type != TrueColorType) &&
+ (characteristics.grayscale))
+ number_components=1;
+
+ jp2_image=jas_image_create0();
+ if (jp2_image == (jas_image_t *) NULL)
+ ThrowWriterException(DelegateError,UnableToCreateImage,image);
+
+ for (component=0; component < number_components; component++)
+ {
+ (void) memset((void *)&component_info,0,sizeof(jas_image_cmptparm_t));
+ component_info.tlx=0; /* top left x ordinate */
+ component_info.tly=0; /* top left y ordinate */
+ component_info.hstep=1; /* horizontal pixels per step */
+ component_info.vstep=1; /* vertical pixels per step */
+ component_info.width=(unsigned int) image->columns;
+ component_info.height=(unsigned int) image->rows;
+ component_info.prec=(unsigned int) Max(2,Min(image->depth,16)); /* bits in range */
+ component_info.sgnd = false; /* range is signed value? */
+
+ if (jas_image_addcmpt(jp2_image, component,&component_info)) {
+ jas_image_destroy(jp2_image);
+ ThrowWriterException(DelegateError,UnableToCreateImageComponent,image);
+ }
+ }
+
+ /*
+ Allocate and compute LUT.
+ */
+ {
+ unsigned long
+ i,
+ max_value;
+
+ double
+ scale_to_component;
+
+ lut=MagickAllocateArray(unsigned short *,MaxMap+1,sizeof(*lut));
+ if (lut == (unsigned short *) NULL)
+ {
+ jas_image_destroy(jp2_image);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+
+ max_value=MaxValueGivenBits(component_info.prec);
+ scale_to_component=max_value/MaxRGBDouble;
+ for(i=0; i <= MaxMap; i++)
+ lut[i]=scale_to_component*i+0.5;
+ }
+
+ if (number_components == 1)
+ {
+ /* FIXME: If image has an attached ICC profile, then the profile
+ should be transferred and the image colorspace set to
+ JAS_CLRSPC_GENGRAY */
+ /* sRGB Grayscale */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Setting SGRAY colorspace");
+ jas_image_setclrspc(jp2_image, JAS_CLRSPC_SGRAY);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Setting GRAY channel to channel 0");
+ jas_image_setcmpttype(jp2_image,0,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
+ }
+ else
+ {
+ /* FIXME: If image has an attached ICC profile, then the profile
+ should be transferred and the image colorspace set to
+ JAS_CLRSPC_GENRGB */
+
+ /* sRGB */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Setting SRGB colorspace");
+ jas_image_setclrspc(jp2_image, JAS_CLRSPC_SRGB);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Setting RED channel to channel 0");
+ jas_image_setcmpttype(jp2_image,0,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Setting GREEN channel to channel 1");
+ jas_image_setcmpttype(jp2_image,1,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Setting BLUE channel to channel 2");
+ jas_image_setcmpttype(jp2_image,2,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
+ if (number_components == 4 )
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Setting OPACITY channel to channel 3");
+ jas_image_setcmpttype(jp2_image,3,
+ JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY));
+ }
+ }
+ /*
+ Convert to JPEG 2000 pixels.
+ */
+ jp2_pixels=jas_matrix_create(1,(unsigned int) image->columns);
+ if (jp2_pixels == (jas_matrix_t *) NULL)
+ {
+ MagickFreeMemory(lut);
+ jas_image_destroy(jp2_image);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if (number_components == 1)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(PixelIntensityToQuantum(&p[x]))]);
+ (void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y,
+ (unsigned int) image->columns,1,jp2_pixels);
+ }
+ else
+ {
+ for (x=0; x < (long) image->columns; x++)
+ jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].red)]);
+ (void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y,
+ (unsigned int) image->columns,1,jp2_pixels);
+
+ for (x=0; x < (long) image->columns; x++)
+ jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].green)]);
+ (void) jas_image_writecmpt(jp2_image,1,0,(unsigned int) y,
+ (unsigned int) image->columns,1,jp2_pixels);
+
+ for (x=0; x < (long) image->columns; x++)
+ jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].blue)]);
+ (void) jas_image_writecmpt(jp2_image,2,0,(unsigned int) y,
+ (unsigned int) image->columns,1,jp2_pixels);
+
+ if (number_components > 3)
+ for (x=0; x < (long) image->columns; x++)
+ jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(MaxRGB-p[x].opacity)]);
+ (void) jas_image_writecmpt(jp2_image,3,0,(unsigned int) y,
+ (unsigned int) image->columns,1,jp2_pixels);
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) strlcpy(magick,image_info->magick,MaxTextExtent);
+ /*
+ J2C is an alias for JPC but Jasper only supports "JPC".
+ */
+ if (LocaleCompare(magick,"j2c") == 0)
+ (void) strlcpy(magick,"jpc",sizeof(magick));
+ LocaleLower(magick);
+ format=jas_image_strtofmt(magick);
+
+ /*
+ Support passing Jasper options.
+ */
+ {
+ const char
+ * const * option_name;
+
+ for (option_name = jasper_options; *option_name != NULL; option_name++)
+ {
+ const char
+ *value;
+
+ if ((value=AccessDefinition(image_info,"jp2",*option_name)) != NULL)
+ {
+ if(LocaleCompare(*option_name,"rate") == 0)
+ rate_specified=True;
+ /*
+ It is documented that a rate specification of 1.0 should
+ result in lossless compression. However, Jasper only
+ provides lossless compression if rate was not specified
+ at all. Support lossless compression as documented.
+ */
+ {
+ double
+ rate;
+
+ rate=atof(value);
+ if (rate < 1.0-MagickEpsilon)
+ {
+ FormatString(option_keyval,"%s=%.1024s ",*option_name,value);
+ ConcatenateString(&options,option_keyval);
+ }
+ }
+ }
+ }
+ }
+ /*
+ Provide an emulation of IJG JPEG "quality" by default if rate was
+ not specified.
+ */
+ if (rate_specified == False)
+ {
+ double
+ rate=INFINITY;
+
+ /*
+ A rough approximation to JPEG v1 quality using JPEG-2000.
+ Default "quality" 75 results in a request for 16:1 compression, which
+ results in image sizes approximating that of JPEG v1.
+ */
+ if ((image_info->quality < 100.0-MagickEpsilon) &&
+ (MagickArraySize(image->rows,image->columns) > 2500U))
+ {
+ double
+ header_size,
+ current_size,
+ target_size,
+ d;
+
+ d=115-image_info->quality; /* Best number is 110-115 */
+ rate=100.0/(d*d);
+ header_size=550.0; /* Base file size. */
+ header_size+=(number_components-1)*142; /* Additional components */
+ /* FIXME: Need to account for any ICC profiles here */
+
+ current_size=(double)((image->rows*image->columns*image->depth)/8)*
+ number_components;
+ target_size=(current_size*rate)+header_size;
+ rate=target_size/current_size;
+ FormatString(option_keyval,"%s=%g ","rate",rate);
+ ConcatenateString(&options,option_keyval);
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Compression rate: %g (%3.2f:1)",rate,1.0/rate);
+ }
+ if (options)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Jasper options: \"%s\"", options);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Encoding image");
+ status=jas_image_encode(jp2_image,jp2_stream,format,options);
+ (void) jas_stream_close(jp2_stream);
+ MagickFreeMemory(options);
+ MagickFreeMemory(lut);
+ jas_matrix_destroy(jp2_pixels);
+ jas_image_destroy(jp2_image);
+ if (status)
+ ThrowWriterException(DelegateError,UnableToEncodeImageFile,image);
+ return(True);
+}
+#endif
diff --git a/coders/jpeg.c b/coders/jpeg.c
new file mode 100644
index 0000000..3d768f2
--- /dev/null
+++ b/coders/jpeg.c
@@ -0,0 +1,2722 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% JJJJJ PPPP EEEEE GGGG %
+% J P P E G %
+% J PPPP EEE G GG %
+% J J P E G G %
+% JJJ P EEEEE GGG %
+% %
+% %
+% Read/Write JPEG Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This software is based in part on the work of the Independent JPEG Group.
+% See ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz for copyright and
+% licensing restrictions. Blob support contributed by Glenn Randers-Pehrson.
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/enum_strings.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/resource.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteJPEGImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s J P E G %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsJPEG returns True if the image format type, identified by the
+% magick string, is JPEG.
+%
+% The format of the IsJPEG method is:
+%
+% unsigned int IsJPEG(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsJPEG returns True if the image format type is JPEG.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsJPEG(const unsigned char *magick,const size_t length)
+{
+ if (length < 3)
+ return(False);
+ if (memcmp(magick,"\377\330\377",3) == 0)
+ return(True);
+ return(False);
+}
+
+#if defined(HasJPEG)
+#define JPEG_INTERNAL_OPTIONS
+/*
+ Avoid conflicting typedef for INT32
+*/
+#if defined(__MINGW32__)
+# define XMD_H 1
+#endif
+/*
+ The JPEG headers have the annoying problem that they define
+ HAVE_STDLIB_H and we do too. The define isn't actually used
+ so just undef it.
+*/
+#undef HAVE_STDLIB_H
+#include <setjmp.h>
+#include "jpeglib.h"
+#include "jerror.h"
+
+/*
+ Define declarations.
+*/
+#define ICC_MARKER (JPEG_APP0+2)
+#define IPTC_MARKER (JPEG_APP0+13)
+#define XML_MARKER (JPEG_APP0+1)
+#define MaxBufferExtent 8192
+#define JPEG_MARKER_MAX_SIZE 65533
+static const char *xmp_std_header="http://ns.adobe.com/xap/1.0/";
+
+
+typedef struct _DestinationManager
+{
+ struct jpeg_destination_mgr
+ manager;
+
+ Image
+ *image;
+
+ JOCTET
+ *buffer;
+} DestinationManager;
+
+typedef struct _ErrorManager
+{
+ Image
+ *image;
+
+ MagickBool
+ completed;
+
+ jmp_buf
+ error_recovery;
+
+} ErrorManager;
+
+typedef struct _SourceManager
+{
+ struct jpeg_source_mgr
+ manager;
+
+ Image
+ *image;
+
+ JOCTET
+ *buffer;
+
+ boolean
+ start_of_blob;
+} SourceManager;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d J P E G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadJPEGImage reads a JPEG image file and returns it. It allocates
+% the memory necessary for the new Image structure and returns a pointer to
+% the new image.
+%
+% The format of the ReadJPEGImage method is:
+%
+% Image *ReadJPEGImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadJPEGImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+/*
+ Format a libjpeg warning or trace event. Warnings are converted to
+ GraphicsMagick warning exceptions while traces are optionally
+ logged.
+*/
+static unsigned int JPEGMessageHandler(j_common_ptr jpeg_info,int msg_level)
+{
+ char
+ message[JMSG_LENGTH_MAX];
+
+ struct jpeg_error_mgr
+ *err;
+
+ ErrorManager
+ *error_manager;
+
+ Image
+ *image;
+
+ message[0]='\0';
+ err=jpeg_info->err;
+ error_manager=(ErrorManager *) jpeg_info->client_data;
+ image=error_manager->image;
+ /* msg_level is -1 for warnings, 0 and up for trace messages. */
+ if (msg_level < 0)
+ {
+ /* A warning */
+ (err->format_message)(jpeg_info,message);
+
+ if (image->logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "[%s] JPEG Warning: \"%s\" (code=%d, "
+ "parms=0x%02x,0x%02x,"
+ "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)",
+ image->filename,message,err->msg_code,
+ err->msg_parm.i[0], err->msg_parm.i[1],
+ err->msg_parm.i[2], err->msg_parm.i[3],
+ err->msg_parm.i[4], err->msg_parm.i[5],
+ err->msg_parm.i[6], err->msg_parm.i[7]);
+ }
+ if ((err->num_warnings == 0) ||
+ (err->trace_level >= 3))
+ ThrowBinaryException2(CorruptImageWarning,(char *) message,
+ image->filename);
+ err->num_warnings++;
+ }
+ else
+ {
+ /* A trace message */
+ if ((image->logging) && (msg_level >= err->trace_level))
+ {
+ (err->format_message)(jpeg_info,message);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "[%s] JPEG Trace: \"%s\"",image->filename,
+ message);
+ }
+ }
+ return(True);
+}
+
+static boolean FillInputBuffer(j_decompress_ptr cinfo)
+{
+ SourceManager
+ *source;
+
+ source=(SourceManager *) cinfo->src;
+ source->manager.bytes_in_buffer=
+ ReadBlob(source->image,MaxBufferExtent,(char *) source->buffer);
+ if (source->manager.bytes_in_buffer == 0)
+ {
+ if (source->start_of_blob)
+ ERREXIT(cinfo,JERR_INPUT_EMPTY);
+ WARNMS(cinfo,JWRN_JPEG_EOF);
+ source->buffer[0]=(JOCTET) 0xff;
+ source->buffer[1]=(JOCTET) JPEG_EOI;
+ source->manager.bytes_in_buffer=2;
+ }
+ source->manager.next_input_byte=source->buffer;
+ source->start_of_blob=FALSE;
+ return(TRUE);
+}
+
+static unsigned int GetCharacter(j_decompress_ptr jpeg_info)
+{
+ if (jpeg_info->src->bytes_in_buffer == 0)
+ (void) (*jpeg_info->src->fill_input_buffer)(jpeg_info);
+ jpeg_info->src->bytes_in_buffer--;
+ return(GETJOCTET(*jpeg_info->src->next_input_byte++));
+}
+
+static void InitializeSource(j_decompress_ptr cinfo)
+{
+ SourceManager
+ *source;
+
+ source=(SourceManager *) cinfo->src;
+ source->start_of_blob=TRUE;
+}
+
+/*
+ Format and report a libjpeg error event. Errors are reported via a
+ GraphicsMagick error exception. The function terminates with
+ longjmp() so it never returns to the caller.
+*/
+static void JPEGErrorHandler(j_common_ptr jpeg_info) MAGICK_FUNC_NORETURN;
+
+static void JPEGErrorHandler(j_common_ptr jpeg_info)
+{
+ char
+ message[JMSG_LENGTH_MAX];
+
+ struct jpeg_error_mgr
+ *err;
+
+ ErrorManager
+ *error_manager;
+
+ Image
+ *image;
+
+ message[0]='\0';
+ err=jpeg_info->err;
+ error_manager=(ErrorManager *) jpeg_info->client_data;
+ image=error_manager->image;
+ (err->format_message)(jpeg_info,message);
+ if (image->logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "[%s] JPEG Error: \"%s\" (code=%d, "
+ "parms=0x%02x,0x%02x,"
+ "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)",
+ image->filename,message,err->msg_code,
+ err->msg_parm.i[0], err->msg_parm.i[1],
+ err->msg_parm.i[2], err->msg_parm.i[3],
+ err->msg_parm.i[4], err->msg_parm.i[5],
+ err->msg_parm.i[6], err->msg_parm.i[7]);
+ }
+ if (error_manager->completed)
+ ThrowException2(&image->exception,CoderWarning,(char *) message,
+ image->filename);
+ else
+ ThrowException2(&image->exception,CoderError,(char *) message,
+ image->filename);
+ longjmp(error_manager->error_recovery,1);
+}
+
+static boolean ReadComment(j_decompress_ptr jpeg_info)
+{
+ char
+ *comment;
+
+ ErrorManager
+ *error_manager;
+
+ Image
+ *image;
+
+ size_t
+ i,
+ length;
+
+ register char
+ *p;
+
+ /*
+ Determine length of comment.
+ */
+ error_manager=(ErrorManager *) jpeg_info->client_data;
+ image=error_manager->image;
+ length=GetCharacter(jpeg_info) << 8;
+ length+=GetCharacter(jpeg_info);
+ if (length <= 2)
+ return(True);
+ length-=2;
+ comment=MagickAllocateMemory(char *,length+1);
+ if (comment == (char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ /*
+ Read comment.
+ */
+ p=comment;
+ for (i=length; i != 0; i--)
+ {
+ *p=GetCharacter(jpeg_info);
+ p++;
+ }
+ *p='\0';
+ (void) SetImageAttribute(image,"comment",comment);
+ MagickFreeMemory(comment);
+ return(True);
+}
+
+static boolean ReadGenericProfile(j_decompress_ptr jpeg_info)
+{
+ ErrorManager
+ *error_manager;
+
+ Image
+ *image;
+
+ size_t
+ header_length=0,
+ length;
+
+ register size_t
+ i;
+
+ char
+ profile_name[MaxTextExtent];
+
+ unsigned char
+ *profile;
+
+ int
+ marker;
+
+ boolean
+ status = True;
+
+ /*
+ Determine length of generic profile.
+ */
+ length=GetCharacter(jpeg_info) << 8;
+ length+=GetCharacter(jpeg_info);
+ if (length <= 2)
+ return(status);
+ length-=2;
+
+ marker=jpeg_info->unread_marker-JPEG_APP0;
+
+ /*
+ Compute generic profile name.
+ */
+ FormatString(profile_name,"APP%d",marker);
+
+ /*
+ Obtain Image.
+ */
+ error_manager=(ErrorManager *) jpeg_info->client_data;
+ image=error_manager->image;
+
+ /*
+ Copy profile from JPEG to allocated memory.
+ */
+ profile=MagickAllocateMemory(unsigned char *,length);
+ if (profile == (unsigned char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ for (i=0 ; i < length ; i++)
+ profile[i]=GetCharacter(jpeg_info);
+
+ /*
+ Detect EXIF and XMP profiles.
+ */
+ if ((marker == 1) && (length > 4) &&
+ (strncmp((char *) profile,"Exif",4) == 0))
+ {
+ FormatString(profile_name,"EXIF");
+ }
+ else if (((marker == 1) && (length > strlen(xmp_std_header)+1)) &&
+ (memcmp(profile, xmp_std_header, strlen(xmp_std_header)+1) == 0))
+ {
+ /*
+ XMP is required to fit in one 64KB chunk. Strip off its JPEG
+ namespace header.
+ */
+ header_length=strlen(xmp_std_header)+1;
+ FormatString((char *) profile_name,"XMP");
+ }
+
+ /*
+ Store profile in Image.
+ */
+ status=AppendImageProfile(image,profile_name,profile+header_length,
+ length-header_length);
+ MagickFreeMemory(profile);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Profile: %s, %lu bytes",
+ profile_name, (unsigned long) header_length);
+
+ return (status);
+}
+
+static boolean ReadICCProfile(j_decompress_ptr jpeg_info)
+{
+ char
+ magick[12];
+
+ ErrorManager
+ *error_manager;
+
+ Image
+ *image;
+
+ long
+ length;
+
+ register long
+ i;
+
+ unsigned char
+ *profile;
+
+ /*
+ Determine length of color profile.
+ */
+ length=(long) GetCharacter(jpeg_info) << 8;
+ length+=(long) GetCharacter(jpeg_info);
+ length-=2;
+ if (length <= 14)
+ {
+ while (--length >= 0)
+ (void) GetCharacter(jpeg_info);
+ return(True);
+ }
+ for (i=0; i < 12; i++)
+ magick[i]=GetCharacter(jpeg_info);
+ if (LocaleCompare(magick,"ICC_PROFILE") != 0)
+ {
+ /*
+ Not a ICC profile, return.
+ */
+ for (i=0; i < length-12; i++)
+ (void) GetCharacter(jpeg_info);
+ return(True);
+ }
+ (void) GetCharacter(jpeg_info); /* id */
+ (void) GetCharacter(jpeg_info); /* markers */
+ length-=14;
+ error_manager=(ErrorManager *) jpeg_info->client_data;
+ image=error_manager->image;
+
+ /*
+ Read color profile.
+ */
+ profile=MagickAllocateMemory(unsigned char *,(size_t) length);
+ if (profile == (unsigned char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "ICC profile chunk: %ld bytes",
+ length);
+
+ for (i=0 ; i < length; i++)
+ profile[i]=GetCharacter(jpeg_info);
+
+ (void) AppendImageProfile(image,"ICM",profile,length);
+
+ MagickFreeMemory(profile);
+
+ return(True);
+}
+
+static boolean ReadIPTCProfile(j_decompress_ptr jpeg_info)
+{
+ char
+ magick[MaxTextExtent];
+
+ ErrorManager
+ *error_manager;
+
+ Image
+ *image;
+
+ long
+ length,
+ tag_length;
+
+ unsigned char
+ *profile;
+
+ register long
+ i;
+
+#ifdef GET_ONLY_IPTC_DATA
+ unsigned char
+ tag[MaxTextExtent];
+#endif
+
+ /*
+ Determine length of binary data stored here.
+ */
+ length=(long) GetCharacter(jpeg_info) << 8;
+ length+=(long) GetCharacter(jpeg_info);
+ length-=2;
+ if (length <= 0)
+ return(True);
+ tag_length=0;
+#ifdef GET_ONLY_IPTC_DATA
+ *tag='\0';
+#endif
+ error_manager=(ErrorManager *) jpeg_info->client_data;
+ image=error_manager->image;
+#ifdef GET_ONLY_IPTC_DATA
+ /*
+ Find the beginning of the IPTC portion of the binary data.
+ */
+ for (*tag='\0'; length > 0; )
+ {
+ *tag=GetCharacter(jpeg_info);
+ *(tag+1)=GetCharacter(jpeg_info);
+ length-=2;
+ if ((*tag == 0x1c) && (*(tag+1) == 0x02))
+ break;
+ }
+ tag_length=2;
+#else
+ /*
+ Validate that this was written as a Photoshop resource format slug.
+ */
+ for (i=0; i < 10; i++)
+ magick[i]=GetCharacter(jpeg_info);
+ magick[10]='\0';
+ length-=10;
+ if (LocaleCompare(magick,"Photoshop ") != 0)
+ {
+ /*
+ Not a ICC profile, return.
+ */
+ for (i=0; i < length; i++)
+ (void) GetCharacter(jpeg_info);
+ return(True);
+ }
+ /*
+ Remove the version number.
+ */
+ for (i=0; i < 4; i++)
+ (void) GetCharacter(jpeg_info);
+ length-=4;
+ tag_length=0;
+#endif
+ if (length <= 0)
+ return(True);
+
+ profile=MagickAllocateMemory(unsigned char *,(size_t) length+tag_length);
+ if (profile == (unsigned char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ /*
+ Read the payload of this binary data.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Profile: IPTC, %ld bytes",
+ length);
+
+ for (i=0; i<length; i++)
+ profile[i]=GetCharacter(jpeg_info);
+
+ (void) AppendImageProfile(image,"IPTC",profile,length);
+
+ MagickFreeMemory(profile);
+ return(True);
+}
+
+static void SkipInputData(j_decompress_ptr cinfo,long number_bytes)
+{
+ SourceManager
+ *source;
+
+ if (number_bytes <= 0)
+ return;
+ source=(SourceManager *) cinfo->src;
+ while (number_bytes > (long) source->manager.bytes_in_buffer)
+ {
+ number_bytes-=(long) source->manager.bytes_in_buffer;
+ (void) FillInputBuffer(cinfo);
+ }
+ source->manager.next_input_byte+=(size_t) number_bytes;
+ source->manager.bytes_in_buffer-=(size_t) number_bytes;
+}
+
+static void TerminateSource(j_decompress_ptr cinfo)
+{
+ (void) cinfo;
+}
+
+static void JPEGSourceManager(j_decompress_ptr cinfo,Image *image)
+{
+ SourceManager
+ *source;
+
+ cinfo->src=(struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo,JPOOL_IMAGE,sizeof(SourceManager));
+ source=(SourceManager *) cinfo->src;
+ source->buffer=(JOCTET *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo,JPOOL_IMAGE,MaxBufferExtent*sizeof(JOCTET));
+ source=(SourceManager *) cinfo->src;
+ source->manager.init_source=InitializeSource;
+ source->manager.fill_input_buffer=FillInputBuffer;
+ source->manager.skip_input_data=SkipInputData;
+ source->manager.resync_to_restart=jpeg_resync_to_restart;
+ source->manager.term_source=TerminateSource;
+ source->manager.bytes_in_buffer=0;
+ source->manager.next_input_byte=NULL;
+ source->image=image;
+}
+
+/*
+ Estimate the IJG quality factor used when saving the file.
+*/
+static int
+EstimateJPEGQuality(const struct jpeg_decompress_struct *jpeg_info,
+ Image *image)
+{
+ int
+ save_quality;
+
+ register long
+ i;
+
+ save_quality=0;
+#ifdef D_LOSSLESS_SUPPORTED
+ if (image->compression==LosslessJPEGCompression)
+ {
+ save_quality=100;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Quality: 100 (lossless)");
+ }
+ else
+#endif
+
+ {
+ int
+ hashval,
+ sum;
+
+ /*
+ Log the JPEG quality that was used for compression.
+ */
+ sum=0;
+ for (i=0; i < NUM_QUANT_TBLS; i++)
+ {
+ int
+ j;
+
+ if (jpeg_info->quant_tbl_ptrs[i] != NULL)
+ for (j=0; j < DCTSIZE2; j++)
+ {
+ UINT16 *c;
+ c=jpeg_info->quant_tbl_ptrs[i]->quantval;
+ sum+=c[j];
+ }
+ }
+ if ((jpeg_info->quant_tbl_ptrs[0] != NULL) &&
+ (jpeg_info->quant_tbl_ptrs[1] != NULL))
+ {
+ int
+ hash[] =
+ {
+ 1020, 1015, 932, 848, 780, 735, 702, 679, 660, 645,
+ 632, 623, 613, 607, 600, 594, 589, 585, 581, 571,
+ 555, 542, 529, 514, 494, 474, 457, 439, 424, 410,
+ 397, 386, 373, 364, 351, 341, 334, 324, 317, 309,
+ 299, 294, 287, 279, 274, 267, 262, 257, 251, 247,
+ 243, 237, 232, 227, 222, 217, 213, 207, 202, 198,
+ 192, 188, 183, 177, 173, 168, 163, 157, 153, 148,
+ 143, 139, 132, 128, 125, 119, 115, 108, 104, 99,
+ 94, 90, 84, 79, 74, 70, 64, 59, 55, 49,
+ 45, 40, 34, 30, 25, 20, 15, 11, 6, 4,
+ 0
+ };
+
+ int
+ sums[] =
+ {
+ 32640,32635,32266,31495,30665,29804,29146,28599,28104,27670,
+ 27225,26725,26210,25716,25240,24789,24373,23946,23572,22846,
+ 21801,20842,19949,19121,18386,17651,16998,16349,15800,15247,
+ 14783,14321,13859,13535,13081,12702,12423,12056,11779,11513,
+ 11135,10955,10676,10392,10208, 9928, 9747, 9564, 9369, 9193,
+ 9017, 8822, 8639, 8458, 8270, 8084, 7896, 7710, 7527, 7347,
+ 7156, 6977, 6788, 6607, 6422, 6236, 6054, 5867, 5684, 5495,
+ 5305, 5128, 4945, 4751, 4638, 4442, 4248, 4065, 3888, 3698,
+ 3509, 3326, 3139, 2957, 2775, 2586, 2405, 2216, 2037, 1846,
+ 1666, 1483, 1297, 1109, 927, 735, 554, 375, 201, 128,
+ 0
+ };
+
+ hashval=(jpeg_info->quant_tbl_ptrs[0]->quantval[2]+
+ jpeg_info->quant_tbl_ptrs[0]->quantval[53]+
+ jpeg_info->quant_tbl_ptrs[1]->quantval[0]+
+ jpeg_info->quant_tbl_ptrs[1]->quantval[DCTSIZE2-1]);
+ for (i=0; i < 100; i++)
+ {
+ if ((hashval >= hash[i]) || (sum >= sums[i]))
+ {
+ save_quality=i+1;
+ if (image->logging)
+ {
+ if ((hashval > hash[i]) || (sum > sums[i]))
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Quality: %d (approximate)",
+ save_quality);
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Quality: %d",save_quality);
+ }
+ break;
+ }
+ }
+ }
+ else
+ if (jpeg_info->quant_tbl_ptrs[0] != NULL)
+ {
+ int
+ bwhash[] =
+ {
+ 510, 505, 422, 380, 355, 338, 326, 318, 311, 305,
+ 300, 297, 293, 291, 288, 286, 284, 283, 281, 280,
+ 279, 278, 277, 273, 262, 251, 243, 233, 225, 218,
+ 211, 205, 198, 193, 186, 181, 177, 172, 168, 164,
+ 158, 156, 152, 148, 145, 142, 139, 136, 133, 131,
+ 129, 126, 123, 120, 118, 115, 113, 110, 107, 105,
+ 102, 100, 97, 94, 92, 89, 87, 83, 81, 79,
+ 76, 74, 70, 68, 66, 63, 61, 57, 55, 52,
+ 50, 48, 44, 42, 39, 37, 34, 31, 29, 26,
+ 24, 21, 18, 16, 13, 11, 8, 6, 3, 2,
+ 0
+ };
+
+ int
+ bwsum[] =
+ {
+ 16320,16315,15946,15277,14655,14073,13623,13230,12859,12560,
+ 12240,11861,11456,11081,10714,10360,10027, 9679, 9368, 9056,
+ 8680, 8331, 7995, 7668, 7376, 7084, 6823, 6562, 6345, 6125,
+ 5939, 5756, 5571, 5421, 5240, 5086, 4976, 4829, 4719, 4616,
+ 4463, 4393, 4280, 4166, 4092, 3980, 3909, 3835, 3755, 3688,
+ 3621, 3541, 3467, 3396, 3323, 3247, 3170, 3096, 3021, 2952,
+ 2874, 2804, 2727, 2657, 2583, 2509, 2437, 2362, 2290, 2211,
+ 2136, 2068, 1996, 1915, 1858, 1773, 1692, 1620, 1552, 1477,
+ 1398, 1326, 1251, 1179, 1109, 1031, 961, 884, 814, 736,
+ 667, 592, 518, 441, 369, 292, 221, 151, 86, 64,
+ 0
+ };
+
+ hashval=(jpeg_info->quant_tbl_ptrs[0]->quantval[2]+
+ jpeg_info->quant_tbl_ptrs[0]->quantval[53]);
+ for (i=0; i < 100; i++)
+ {
+ if ((hashval >= bwhash[i]) || (sum >= bwsum[i]))
+ {
+ save_quality=i+1;
+ if (image->logging)
+ {
+ if ((hashval > bwhash[i]) || (sum > bwsum[i]))
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Quality: %ld (approximate)",
+ i+1);
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Quality: %ld",i+1);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return save_quality;
+}
+
+/*
+ Format JPEG color space to a string.
+*/
+static void
+FormatJPEGColorSpace(const J_COLOR_SPACE colorspace,
+ char *colorspace_name)
+{
+ const char
+ *s = NULL;
+
+ switch (colorspace)
+ {
+ default:
+ case JCS_UNKNOWN:
+ s = "UNKNOWN";
+ break;
+ case JCS_GRAYSCALE:
+ s = "GRAYSCALE";
+ break;
+ case JCS_RGB:
+ s = "RGB";
+ break;
+ case JCS_YCbCr:
+ s = "YCbCr";
+ break;
+ case JCS_CMYK:
+ s = "CMYK";
+ break;
+ case JCS_YCCK:
+ s = "YCCK";
+ break;
+ }
+ (void) strlcpy(colorspace_name,s,MaxTextExtent);
+}
+
+/*
+ Format JPEG sampling factors to a string.
+*/
+static void
+FormatJPEGSamplingFactors(const struct jpeg_decompress_struct *jpeg_info,
+ char *sampling_factors)
+{
+ switch (jpeg_info->out_color_space)
+ {
+ case JCS_CMYK:
+ {
+ (void) FormatString(sampling_factors,"%dx%d,%dx%d,%dx%d,%dx%d",
+ jpeg_info->comp_info[0].h_samp_factor,
+ jpeg_info->comp_info[0].v_samp_factor,
+ jpeg_info->comp_info[1].h_samp_factor,
+ jpeg_info->comp_info[1].v_samp_factor,
+ jpeg_info->comp_info[2].h_samp_factor,
+ jpeg_info->comp_info[2].v_samp_factor,
+ jpeg_info->comp_info[3].h_samp_factor,
+ jpeg_info->comp_info[3].v_samp_factor);
+ break;
+ }
+ case JCS_GRAYSCALE:
+ {
+ (void) FormatString(sampling_factors,"%dx%d",
+ jpeg_info->comp_info[0].h_samp_factor,
+ jpeg_info->comp_info[0].v_samp_factor);
+ break;
+ }
+ case JCS_RGB:
+ {
+ (void) FormatString(sampling_factors,"%dx%d,%dx%d,%dx%d",
+ jpeg_info->comp_info[0].h_samp_factor,
+ jpeg_info->comp_info[0].v_samp_factor,
+ jpeg_info->comp_info[1].h_samp_factor,
+ jpeg_info->comp_info[1].v_samp_factor,
+ jpeg_info->comp_info[2].h_samp_factor,
+ jpeg_info->comp_info[2].v_samp_factor);
+ break;
+ }
+ default:
+ {
+ (void) FormatString(sampling_factors,"%dx%d,%dx%d,%dx%d,%dx%d",
+ jpeg_info->comp_info[0].h_samp_factor,
+ jpeg_info->comp_info[0].v_samp_factor,
+ jpeg_info->comp_info[1].h_samp_factor,
+ jpeg_info->comp_info[1].v_samp_factor,
+ jpeg_info->comp_info[2].h_samp_factor,
+ jpeg_info->comp_info[2].v_samp_factor,
+ jpeg_info->comp_info[3].h_samp_factor,
+ jpeg_info->comp_info[3].v_samp_factor);
+ break;
+ }
+ }
+}
+
+static MagickBool
+IsITUFax(const Image* image)
+{
+ size_t
+ profile_length;
+
+ const unsigned char
+ *profile;
+
+ MagickBool
+ status;
+
+ status=MagickFalse;
+ if ((profile=GetImageProfile(image,"APP1",&profile_length)) &&
+ (profile_length >= 5))
+ {
+ if (profile[0] == 0x47 &&
+ profile[1] == 0x33 &&
+ profile[2] == 0x46 &&
+ profile[3] == 0x41 &&
+ profile[4] == 0x58)
+ status=MagickTrue;
+ }
+
+ return status;
+}
+
+static Image *ReadJPEGImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ ErrorManager
+ error_manager;
+
+ Image
+ *image;
+
+ IndexPacket
+ index;
+
+ long
+ y;
+
+ JSAMPLE
+ *jpeg_pixels;
+
+ JSAMPROW
+ scanline[1];
+
+ register long
+ i;
+
+ struct jpeg_decompress_struct
+ jpeg_info;
+
+ struct jpeg_error_mgr
+ jpeg_error;
+
+ register JSAMPLE
+ *p;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ number_pixels;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if (image == (Image *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ if (BlobIsSeekable(image) && GetBlobSize(image) < 107)
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ /*
+ Initialize structures.
+ */
+ (void) memset(&error_manager,0,sizeof(error_manager));
+ (void) memset(&jpeg_info,0,sizeof(jpeg_info));
+ (void) memset(&jpeg_error,0,sizeof(jpeg_error));
+ jpeg_info.err=jpeg_std_error(&jpeg_error);
+ jpeg_info.err->emit_message=(void (*)(j_common_ptr,int)) JPEGMessageHandler;
+ jpeg_info.err->error_exit=(void (*)(j_common_ptr)) JPEGErrorHandler;
+ jpeg_pixels=(JSAMPLE *) NULL;
+ error_manager.image=image;
+
+ /*
+ Set initial longjmp based error handler.
+ */
+ if (setjmp(error_manager.error_recovery))
+ {
+ jpeg_destroy_decompress(&jpeg_info);
+ GetImageException(image,exception);
+ CloseBlob(image);
+ if (exception->severity < ErrorException)
+ return(image);
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ jpeg_info.client_data=(void *) &error_manager;
+
+ jpeg_create_decompress(&jpeg_info);
+ JPEGSourceManager(&jpeg_info,image);
+ jpeg_set_marker_processor(&jpeg_info,JPEG_COM,ReadComment);
+ jpeg_set_marker_processor(&jpeg_info,ICC_MARKER,ReadICCProfile);
+ jpeg_set_marker_processor(&jpeg_info,IPTC_MARKER,ReadIPTCProfile);
+ for (i=1; i < 16; i++)
+ if ((i != 2) && (i != 13) && (i != 14))
+ jpeg_set_marker_processor(&jpeg_info,JPEG_APP0+i,ReadGenericProfile);
+ i=jpeg_read_header(&jpeg_info,True);
+ if (IsITUFax(image))
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image colorspace set to LAB");
+ image->colorspace=LABColorspace;
+ jpeg_info.out_color_space = JCS_YCbCr;
+ }
+ else if (jpeg_info.out_color_space == JCS_CMYK)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image colorspace set to CMYK");
+ image->colorspace=CMYKColorspace;
+ }
+ if (jpeg_info.saw_JFIF_marker)
+ {
+ if ((jpeg_info.X_density != 1U) && (jpeg_info.Y_density != 1U))
+ {
+ /*
+ Set image resolution.
+ */
+ image->x_resolution=jpeg_info.X_density;
+ image->y_resolution=jpeg_info.Y_density;
+ if (jpeg_info.density_unit == 1)
+ image->units=PixelsPerInchResolution;
+ if (jpeg_info.density_unit == 2)
+ image->units=PixelsPerCentimeterResolution;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image resolution set to %gx%g %s",
+ image->x_resolution,
+ image->y_resolution,
+ ResolutionTypeToString(image->units));
+ }
+ }
+ /*
+ If the desired image size is pre-set (e.g. by using -size), then
+ let the JPEG library subsample for us.
+ */
+ number_pixels=image->columns*image->rows;
+ if (number_pixels != 0)
+ {
+ double
+ scale_factor;
+
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Requested Geometry: %lux%lu",
+ image->columns,image->rows);
+ jpeg_calc_output_dimensions(&jpeg_info);
+ image->magick_columns=jpeg_info.output_width;
+ image->magick_rows=jpeg_info.output_height;
+ scale_factor=(double) jpeg_info.output_width/image->columns;
+ if (scale_factor > ((double) jpeg_info.output_height/image->rows))
+ scale_factor=(double) jpeg_info.output_height/image->rows;
+ jpeg_info.scale_denom *=(unsigned int) scale_factor;
+ jpeg_calc_output_dimensions(&jpeg_info);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Scale_factor: %ld (scale_num=%d, "
+ "scale_denom=%d)",
+ (long) scale_factor,
+ jpeg_info.scale_num,jpeg_info.scale_denom);
+ }
+#if 0
+ /*
+ The subrange parameter is set by the filename array syntax similar
+ to the way an image is requested from a list (e.g. myfile.jpg[2]).
+ Argument values other than zero are used to scale the image down
+ by that factor. IJG JPEG 62 (6b) supports values of 1,2,4, or 8
+ while IJG JPEG 70 supports all values in the range 1-16. This
+ feature is useful in case you want to view all of the images with
+ a consistent ratio. Unfortunately, it uses the same syntax as
+ list member access.
+ */
+ else if (image_info->subrange != 0)
+ {
+ jpeg_info.scale_denom *=(int) image_info->subrange;
+ jpeg_calc_output_dimensions(&jpeg_info);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Requested Scaling Denominator: %d "
+ "(scale_num=%d, scale_denom=%d)",
+ (int) image_info->subrange,
+ jpeg_info.scale_num,jpeg_info.scale_denom);
+
+ }
+#endif
+#if (JPEG_LIB_VERSION >= 61) && defined(D_PROGRESSIVE_SUPPORTED)
+#ifdef D_LOSSLESS_SUPPORTED
+ image->interlace=
+ jpeg_info.process == JPROC_PROGRESSIVE ? LineInterlace : NoInterlace;
+ image->compression=jpeg_info.process == JPROC_LOSSLESS ?
+ LosslessJPEGCompression : JPEGCompression;
+ if (jpeg_info.data_precision > 8)
+ MagickError2(OptionError,
+ "12-bit JPEG not supported. Reducing pixel data to 8 bits",
+ (char *) NULL);
+#else
+ image->interlace=jpeg_info.progressive_mode ? LineInterlace : NoInterlace;
+ image->compression=JPEGCompression;
+#endif
+#else
+ image->compression=JPEGCompression;
+ image->interlace=LineInterlace;
+#endif
+ {
+ const char
+ *value;
+
+ /*
+ Allow the user to enable/disable block smoothing.
+ */
+ if ((value=AccessDefinition(image_info,"jpeg","block-smoothing")))
+ {
+ if (LocaleCompare(value,"FALSE") == 0)
+ jpeg_info.do_block_smoothing=False;
+ else
+ jpeg_info.do_block_smoothing=True;
+ }
+
+ /*
+ Allow the user to select the DCT decoding algorithm.
+ */
+ if ((value=AccessDefinition(image_info,"jpeg","dct-method")))
+ {
+ if (LocaleCompare(value,"ISLOW") == 0)
+ jpeg_info.dct_method=JDCT_ISLOW;
+ else if (LocaleCompare(value,"IFAST") == 0)
+ jpeg_info.dct_method=JDCT_IFAST;
+ else if (LocaleCompare(value,"FLOAT") == 0)
+ jpeg_info.dct_method=JDCT_FLOAT;
+ else if (LocaleCompare(value,"DEFAULT") == 0)
+ jpeg_info.dct_method=JDCT_DEFAULT;
+ else if (LocaleCompare(value,"FASTEST") == 0)
+ jpeg_info.dct_method=JDCT_FASTEST;
+ }
+
+ /*
+ Allow the user to enable/disable fancy upsampling.
+ */
+ if ((value=AccessDefinition(image_info,"jpeg","fancy-upsampling")))
+ {
+ if (LocaleCompare(value,"FALSE") == 0)
+ jpeg_info.do_fancy_upsampling=False;
+ else
+ jpeg_info.do_fancy_upsampling=True;
+ }
+ }
+ (void) jpeg_start_decompress(&jpeg_info);
+ image->columns=jpeg_info.output_width;
+ image->rows=jpeg_info.output_height;
+ if (image->logging)
+ {
+ if (image->interlace == LineInterlace)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Interlace: progressive");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Interlace: nonprogressive");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Data precision: %d",
+ (int) jpeg_info.data_precision);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Components: %d",
+ (int) jpeg_info.output_components);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Geometry: %dx%d",
+ (int) jpeg_info.output_width,
+ (int) jpeg_info.output_height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"DCT Method: %d",
+ jpeg_info.dct_method);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Fancy Upsampling: %s",
+ (jpeg_info.do_fancy_upsampling ? "true" : "false"));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Block Smoothing: %s",
+ (jpeg_info.do_block_smoothing ? "true" : "false"));
+ }
+
+ {
+ char
+ attribute[MaxTextExtent];
+
+ /*
+ Estimate and retain JPEG properties as attributes.
+ */
+ FormatString(attribute,"%d",EstimateJPEGQuality(&jpeg_info,image));
+ (void) SetImageAttribute(image,"JPEG-Quality",attribute);
+
+ FormatString(attribute,"%ld",(long)jpeg_info.out_color_space);
+ (void) SetImageAttribute(image,"JPEG-Colorspace",attribute);
+
+ FormatJPEGColorSpace(jpeg_info.out_color_space,attribute);
+ (void) SetImageAttribute(image,"JPEG-Colorspace-Name",attribute);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Colorspace: %s (%d)", attribute,
+ jpeg_info.out_color_space);
+
+ FormatJPEGSamplingFactors(&jpeg_info,attribute);
+ (void) SetImageAttribute(image,"JPEG-Sampling-factors",attribute);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Sampling Factors: %s", attribute);
+ }
+
+ image->depth=Min(jpeg_info.data_precision,QuantumDepth);
+ if (jpeg_info.out_color_space == JCS_GRAYSCALE)
+ if (!AllocateImageColormap(image,1 << image->depth))
+ {
+ jpeg_destroy_decompress(&jpeg_info);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ if (image_info->ping)
+ {
+ jpeg_destroy_decompress(&jpeg_info);
+ CloseBlob(image);
+ return(image);
+ }
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ {
+ jpeg_destroy_decompress(&jpeg_info);
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ }
+
+ /*
+ Verify that we support the number of output components.
+ */
+ if ((jpeg_info.output_components != 1) &&
+ (jpeg_info.output_components != 3) &&
+ (jpeg_info.output_components != 4))
+ {
+ jpeg_destroy_decompress(&jpeg_info);
+ ThrowReaderException(CoderError,ImageTypeNotSupported,image);
+ }
+
+ jpeg_pixels=MagickAllocateArray(JSAMPLE *,
+ jpeg_info.output_components,
+ MagickArraySize(image->columns,
+ sizeof(JSAMPLE)));
+ if (jpeg_pixels == (JSAMPLE *) NULL)
+ {
+ jpeg_destroy_decompress(&jpeg_info);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+
+ /*
+ Extended longjmp-based error handler (with jpeg_pixels)
+ */
+ if (setjmp(error_manager.error_recovery))
+ {
+ /* Error handling code executed if longjmp was invoked */
+ MagickFreeMemory(jpeg_pixels);
+ jpeg_destroy_decompress(&jpeg_info);
+ if (image->exception.severity > exception->severity)
+ CopyException(exception,&image->exception);
+ CloseBlob(image);
+ number_pixels=image->columns*image->rows;
+ if (number_pixels != 0)
+ return(image);
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+
+ /*
+ Convert JPEG pixels to pixel packets.
+ */
+ scanline[0]=(JSAMPROW) jpeg_pixels;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ indexes=AccessMutableIndexes(image);
+
+ if (jpeg_read_scanlines(&jpeg_info,scanline,1) != 1)
+ {
+ status=MagickFail;
+ break;
+ }
+
+ p=jpeg_pixels;
+
+ if (jpeg_info.output_components == 1)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=(IndexPacket) (GETJSAMPLE(*p++));
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ }
+ }
+ else if ((jpeg_info.output_components == 3) ||
+ (jpeg_info.output_components == 4))
+ {
+ if (jpeg_info.data_precision > 8)
+ {
+ unsigned int
+ scale_short;
+
+ scale_short=65535U/MaxValueGivenBits(jpeg_info.data_precision);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleShortToQuantum(scale_short*GETJSAMPLE(*p++));
+ q->green=ScaleShortToQuantum(scale_short*GETJSAMPLE(*p++));
+ q->blue=ScaleShortToQuantum(scale_short*GETJSAMPLE(*p++));
+ if (jpeg_info.output_components > 3)
+ q->opacity=ScaleShortToQuantum(scale_short*GETJSAMPLE(*p++));
+ else
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ }
+ else
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(GETJSAMPLE(*p++));
+ q->green=ScaleCharToQuantum(GETJSAMPLE(*p++));
+ q->blue=ScaleCharToQuantum(GETJSAMPLE(*p++));
+ if (jpeg_info.output_components > 3)
+ q->opacity=ScaleCharToQuantum(GETJSAMPLE(*p++));
+ else
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ }
+ if (image->colorspace == CMYKColorspace)
+ {
+ /*
+ CMYK pixels are inverted.
+ */
+ q=AccessMutablePixels(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=MaxRGB-q->red;
+ q->green=MaxRGB-q->green;
+ q->blue=MaxRGB-q->blue;
+ q->opacity=MaxRGB-q->opacity;
+ q++;
+ }
+ }
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ jpeg_abort_decompress(&jpeg_info);
+ break;
+ }
+ }
+ /*
+ Free jpeg resources.
+ */
+ if (status == MagickPass)
+ {
+ /*
+ jpeg_finish_decompress() may throw an exception while it is
+ finishing the remainder of the JPEG file. At this point we
+ have already decoded the image so we handle exceptions from
+ jpeg_finish_decompress() specially, mapping reported
+ exceptions as warnings rather than errors. We try using
+ jpeg_finish_decompress() and if it results in a longjmp(),
+ then we skip over it again.
+ */
+ error_manager.completed=MagickTrue;
+ if (!setjmp(error_manager.error_recovery))
+ (void) jpeg_finish_decompress(&jpeg_info);
+ }
+ jpeg_destroy_decompress(&jpeg_info);
+ MagickFreeMemory(jpeg_pixels);
+ CloseBlob(image);
+
+ /*
+ Retrieve image orientation from EXIF (if present) and store in
+ image.
+
+ EXIF orienation enumerations match TIFF enumerations, which happen
+ to match the enumeration values used by GraphicsMagick.
+ */
+ if (status == MagickPass)
+ {
+ const ImageAttribute
+ *attribute;
+
+ attribute = GetImageAttribute(image,"EXIF:Orientation");
+ if ((attribute != (const ImageAttribute *) NULL) &&
+ (attribute->value != (char *) NULL))
+ {
+ int
+ orientation;
+
+ orientation=MagickAtoI(attribute->value);
+ if ((orientation > UndefinedOrientation) &&
+ (orientation <= LeftBottomOrientation))
+ image->orientation=(OrientationType) orientation;
+ }
+ }
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ GetImageException(image,exception);
+ return(image);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r J P E G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterJPEGImage adds attributes for the JPEG image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterJPEGImage method is:
+%
+% RegisterJPEGImage(void)
+%
+*/
+ModuleExport void RegisterJPEGImage(void)
+{
+ static const char
+ *description="Joint Photographic Experts Group JFIF format";
+
+ static char
+ version[MaxTextExtent];
+
+ MagickInfo
+ *entry;
+
+ version[0]='\0';
+#if defined(HasJPEG)
+ FormatString(version,"IJG JPEG %d",JPEG_LIB_VERSION);
+#endif
+
+ entry=SetMagickInfo("JPEG");
+ entry->thread_support=False; /* libjpeg is not thread safe */
+#if defined(HasJPEG)
+ entry->decoder=(DecoderHandler) ReadJPEGImage;
+ entry->encoder=(EncoderHandler) WriteJPEGImage;
+#endif
+ entry->magick=(MagickHandler) IsJPEG;
+ entry->adjoin=False;
+ entry->description=description;
+ if (version[0] != '\0')
+ entry->version=version;
+ entry->module="JPEG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("JPG");
+ entry->thread_support=False; /* libjpeg is not thread safe */
+#if defined(HasJPEG)
+ entry->decoder=(DecoderHandler) ReadJPEGImage;
+ entry->encoder=(EncoderHandler) WriteJPEGImage;
+#endif
+ entry->adjoin=False;
+ entry->description=description;
+ if (version[0] != '\0')
+ entry->version=version;
+ entry->module="JPEG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r J P E G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterJPEGImage removes format registrations made by the
+% JPEG module from the list of supported formats.
+%
+% The format of the UnregisterJPEGImage method is:
+%
+% UnregisterJPEGImage(void)
+%
+*/
+ModuleExport void UnregisterJPEGImage(void)
+{
+ (void) UnregisterMagickInfo("JPEG");
+ (void) UnregisterMagickInfo("JPG");
+}
+
+#if defined(HasJPEG)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e J P E G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteJPEGImage writes a JPEG image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the WriteJPEGImage method is:
+%
+% unsigned int WriteJPEGImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WriteJPEGImage return True if the image is written.
+% False is returned is there is of a memory shortage or if the image
+% file cannot be opened for writing.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o jpeg_image: A pointer to an Image structure.
+%
+%
+*/
+
+static boolean EmptyOutputBuffer(j_compress_ptr cinfo)
+{
+ DestinationManager
+ *destination;
+
+ destination=(DestinationManager *) cinfo->dest;
+ destination->manager.free_in_buffer=WriteBlob(destination->image,
+ MaxBufferExtent,(char *) destination->buffer);
+ if (destination->manager.free_in_buffer != MaxBufferExtent)
+ ERREXIT(cinfo,JERR_FILE_WRITE);
+ destination->manager.next_output_byte=destination->buffer;
+ return(TRUE);
+}
+
+static void InitializeDestination(j_compress_ptr cinfo)
+{
+ DestinationManager
+ *destination;
+
+ destination=(DestinationManager *) cinfo->dest;
+ destination->buffer=(JOCTET *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo,JPOOL_IMAGE,MaxBufferExtent*sizeof(JOCTET));
+ destination->manager.next_output_byte=destination->buffer;
+ destination->manager.free_in_buffer=MaxBufferExtent;
+}
+
+static void TerminateDestination(j_compress_ptr cinfo)
+{
+ DestinationManager
+ *destination;
+
+ destination=(DestinationManager *) cinfo->dest;
+ if ((MaxBufferExtent-(int) destination->manager.free_in_buffer) > 0)
+ {
+ size_t
+ number_bytes;
+
+ number_bytes=WriteBlob(destination->image,MaxBufferExtent-
+ destination->manager.free_in_buffer,(char *) destination->buffer);
+ if (number_bytes != (MaxBufferExtent-destination->manager.free_in_buffer))
+ ERREXIT(cinfo,JERR_FILE_WRITE);
+ }
+}
+
+/*
+ Output generic APPN profile
+*/
+static void WriteAPPNProfile(j_compress_ptr jpeg_info,
+ const unsigned char *profile,
+ const size_t profile_length,
+ const char * profile_name)
+{
+ size_t
+ j;
+
+ int
+ marker_id;
+
+ marker_id=JPEG_APP0+(int) MagickAtoL(profile_name+3);
+ for (j=0; j < profile_length; j+=65533L)
+ jpeg_write_marker(jpeg_info,marker_id,
+ profile+j,(int)
+ Min(profile_length-j,65533L));
+}
+
+/*
+ Output EXIF profile
+*/
+static void WriteEXIFProfile(j_compress_ptr jpeg_info,
+ const unsigned char *profile,
+ const size_t profile_length)
+{
+ size_t
+ j;
+
+ for (j=0; j < profile_length; j+=65533L)
+ jpeg_write_marker(jpeg_info,JPEG_APP0+1,
+ profile+j,(int)
+ Min(profile_length-j,65533L));
+}
+
+/*
+ Output ICC color profile as a APP marker.
+*/
+static void WriteICCProfile(j_compress_ptr jpeg_info,
+ const unsigned char *color_profile,
+ const size_t profile_length)
+{
+ register long
+ i,
+ j;
+
+ for (i=0; i < (long) profile_length; i+=65519)
+ {
+ unsigned char
+ *profile;
+
+ size_t
+ length=0;
+
+
+ length=Min(profile_length-i,65519);
+ profile=MagickAllocateMemory(unsigned char *,length+14);
+ if (profile == (unsigned char *) NULL)
+ break;
+ (void) strcpy((char *) profile,"ICC_PROFILE");
+ profile[12]=(unsigned char) ((i/65519)+1);
+ profile[13]=(unsigned char) ((profile_length/65519)+1);
+ for (j=0; j < (long) length; j++)
+ profile[j+14]=color_profile[i+j];
+ jpeg_write_marker(jpeg_info,ICC_MARKER,profile,(unsigned int) length+14);
+ MagickFreeMemory(profile);
+ }
+}
+
+/*
+ Output binary Photoshop resource data using an APP marker.
+*/
+static void WriteIPTCProfile(j_compress_ptr jpeg_info,
+ const unsigned char *iptc_profile,
+ const size_t profile_length)
+{
+ register long
+ i;
+
+ unsigned long
+ roundup,
+ tag_length;
+
+#ifdef GET_ONLY_IPTC_DATA
+ tag_length=26;
+#else
+ tag_length=14;
+#endif
+ for (i=0; i < (long) profile_length; i+=65500)
+ {
+ size_t
+ length;
+
+ unsigned char
+ *profile;
+
+ length=Min(profile_length-i,65500);
+ roundup=(length & 0x01); /* round up for Photoshop */
+ profile=MagickAllocateMemory(unsigned char *,length+roundup+tag_length);
+ if (profile == (unsigned char *) NULL)
+ break;
+#ifdef GET_ONLY_IPTC_DATA
+ (void) memcpy(profile,"Photoshop 3.0 8BIM\04\04\0\0\0\0",24);
+ profile[13]=0x00;
+ profile[24]=length >> 8;
+ profile[25]=length & 0xff;
+#else
+ (void) memcpy(profile,"Photoshop 3.0 ",14);
+ profile[13]=0x00;
+#endif
+ (void) memcpy(&(profile[tag_length]),&(iptc_profile[i]),length);
+ if (roundup)
+ profile[length+tag_length]=0;
+ jpeg_write_marker(jpeg_info,IPTC_MARKER,profile,(unsigned int)
+ (length+roundup+tag_length));
+ MagickFreeMemory(profile);
+ }
+}
+
+/*
+ Output Adobe XMP XML profile.
+*/
+static void WriteXMPProfile(j_compress_ptr jpeg_info,
+ const unsigned char *profile,
+ const size_t profile_length)
+{
+ size_t
+ count,
+ index,
+ header_length,
+ total_length;
+
+ unsigned int
+ marker_length,
+ remaining;
+
+ header_length=strlen(xmp_std_header)+1; /* Include terminating null */
+ total_length=header_length+profile_length;
+ /* XMP profile must be no larger than range of 'unsigned int' */
+ remaining=(unsigned int) Min(UINT_MAX,total_length);
+
+ marker_length=Min(remaining,JPEG_MARKER_MAX_SIZE);
+ jpeg_write_m_header(jpeg_info,XML_MARKER,marker_length);
+ count=marker_length;
+ {
+ for (index=0 ; index < header_length; index++)
+ {
+ jpeg_write_m_byte(jpeg_info,xmp_std_header[index]);
+ --remaining;
+ --count;
+ }
+ }
+
+ for (index=0; remaining > 0; --remaining)
+ {
+ if (count == 0)
+ {
+ marker_length=Min(remaining,JPEG_MARKER_MAX_SIZE);
+ jpeg_write_m_header(jpeg_info,XML_MARKER,marker_length);
+ count=marker_length;
+ }
+ jpeg_write_m_byte(jpeg_info,profile[index]);
+ index++;
+ count--;
+ }
+}
+
+/*
+ Output profiles to JPEG stream.
+*/
+static void WriteProfiles(j_compress_ptr jpeg_info,Image *image)
+{
+ const char
+ *profile_name;
+
+ const unsigned char *
+ profile;
+
+ ImageProfileIterator
+ profile_iterator;
+
+ size_t
+ profile_length=0;
+
+ profile_iterator=AllocateImageProfileIterator(image);
+ while(NextImageProfile(profile_iterator,&profile_name,&profile,
+ &profile_length) != MagickFail)
+ {
+ if (LocaleNCompare(profile_name,"APP",3) == 0)
+ {
+ WriteAPPNProfile(jpeg_info, profile, profile_length, profile_name);
+ }
+ else if (LocaleCompare(profile_name,"EXIF") == 0)
+ {
+ WriteEXIFProfile(jpeg_info, profile, profile_length);
+ }
+ else if ((LocaleCompare(profile_name,"ICM") == 0) ||
+ (LocaleCompare(profile_name,"ICC") == 0))
+ {
+ WriteICCProfile(jpeg_info, profile, profile_length);
+ }
+ else if ((LocaleCompare(profile_name,"IPTC") == 0) ||
+ (LocaleCompare(profile_name,"8BIM") == 0))
+ {
+ WriteIPTCProfile(jpeg_info, profile, profile_length);
+ }
+ else if (LocaleCompare(profile_name,"XMP") == 0)
+ {
+ WriteXMPProfile(jpeg_info, profile, profile_length);
+ }
+ else
+ {
+ /*
+ Skip unknown profile type
+ */
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Skipped Profile: %s, %"
+ MAGICK_SIZE_T_F "u bytes",
+ profile_name,
+ (MAGICK_SIZE_T) profile_length);
+ continue;
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Wrote Profile: %s, %"
+ MAGICK_SIZE_T_F "u bytes",profile_name,
+ (MAGICK_SIZE_T) profile_length);
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+}
+
+static void JPEGDestinationManager(j_compress_ptr cinfo,Image * image)
+{
+ DestinationManager
+ *destination;
+
+ cinfo->dest=(struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo,JPOOL_IMAGE,sizeof(DestinationManager));
+ destination=(DestinationManager *) cinfo->dest;
+ destination->manager.init_destination=InitializeDestination;
+ destination->manager.empty_output_buffer=EmptyOutputBuffer;
+ destination->manager.term_destination=TerminateDestination;
+ destination->image=image;
+}
+
+static MagickPassFail WriteJPEGImage(const ImageInfo *image_info,Image *imagep)
+{
+ Image
+ * volatile imagev = imagep, /* volatile to avoid "clobber" */
+ *image;
+
+ ErrorManager
+ error_manager;
+
+ const ImageAttribute
+ *attribute;
+
+ JSAMPLE
+ *jpeg_pixels;
+
+ JSAMPROW
+ scanline[1];
+
+ char
+ *sampling_factors,
+ *preserve_settings;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register JSAMPLE
+ *q;
+
+ register long
+ i,
+ x;
+
+ struct jpeg_compress_struct
+ jpeg_info;
+
+ struct jpeg_error_mgr
+ jpeg_error;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ input_colorspace;
+
+ unsigned long
+ quality;
+
+ magick_int64_t
+ huffman_memory;
+
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(imagep != (Image *) NULL);
+ assert(imagep->signature == MagickSignature);
+ status=OpenBlob(image_info,imagev,WriteBinaryBlobMode,&imagev->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,imagev);
+
+ (void) memset(&error_manager,0,sizeof(error_manager));
+ (void) memset(&jpeg_info,0,sizeof(jpeg_info));
+ (void) memset(&jpeg_error,0,sizeof(jpeg_error));
+
+ /*
+ Set initial longjmp based error handler.
+ */
+ jpeg_info.client_data=(void *) imagev;
+ jpeg_info.err=jpeg_std_error(&jpeg_error);
+ jpeg_info.err->emit_message=(void (*)(j_common_ptr,int)) JPEGMessageHandler;
+ jpeg_info.err->error_exit=(void (*)(j_common_ptr)) JPEGErrorHandler;
+ error_manager.image=imagev;
+ jpeg_info.client_data=(void *) &error_manager;
+ if (setjmp(error_manager.error_recovery))
+ {
+ jpeg_destroy_compress(&jpeg_info);
+ CloseBlob(imagev);
+ return MagickFail ;
+ }
+ image=imagev; /* Use 'image' after this point for optimization */
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Write JPEG Image: image->orientation = %d",image->orientation);
+
+ /*
+ Transform image to user-requested colorspace.
+ */
+ if (UndefinedColorspace != image_info->colorspace)
+ {
+ (void) TransformColorspace(image,image_info->colorspace);
+ }
+ /*
+ Convert RGB-compatible colorspaces (e.g. CineonLog) to RGB by
+ default. User can still override it by explicitly specifying the
+ desired colorspace.
+ */
+ else if (IsRGBCompatibleColorspace(image->colorspace) &&
+ !IsRGBColorspace(image->colorspace))
+ {
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+
+ jpeg_create_compress(&jpeg_info);
+ JPEGDestinationManager(&jpeg_info,image);
+ jpeg_info.image_width=(unsigned int) image->columns;
+ jpeg_info.image_height=(unsigned int) image->rows;
+ jpeg_info.input_components=3;
+ jpeg_info.in_color_space=JCS_RGB;
+
+ /*
+ Set JPEG colorspace as per user request.
+ */
+ {
+ MagickBool
+ colorspace_set=MagickFalse;
+
+ if (IsCMYKColorspace(image_info->colorspace))
+ {
+ jpeg_info.input_components=4;
+ jpeg_info.in_color_space=JCS_CMYK;
+ colorspace_set=MagickTrue;
+ }
+ else if (IsYCbCrColorspace(image_info->colorspace))
+ {
+ jpeg_info.input_components=3;
+ jpeg_info.in_color_space=JCS_YCbCr;
+ colorspace_set=MagickTrue;
+ }
+ else if (IsGrayColorspace(image_info->colorspace))
+ {
+ jpeg_info.input_components=1;
+ jpeg_info.in_color_space=JCS_GRAYSCALE;
+ colorspace_set=MagickTrue;
+ }
+
+ if (!colorspace_set)
+ {
+ if (IsCMYKColorspace(image->colorspace))
+ {
+ jpeg_info.input_components=4;
+ jpeg_info.in_color_space=JCS_CMYK;
+ }
+ else if (IsYCbCrColorspace(image->colorspace))
+ {
+ jpeg_info.input_components=3;
+ jpeg_info.in_color_space=JCS_YCbCr;
+ }
+ else if ((IsGrayColorspace(image->colorspace) ||
+ (characteristics.grayscale)))
+ {
+ jpeg_info.input_components=1;
+ jpeg_info.in_color_space=JCS_GRAYSCALE;
+ }
+ else
+ {
+ jpeg_info.input_components=3;
+ jpeg_info.in_color_space=JCS_RGB;
+ }
+ }
+ }
+
+ input_colorspace=UndefinedColorspace;
+ quality=image_info->quality;
+ /* Check for -define jpeg:preserve-settings */
+ /* ImageMagick:
+ GetImageOption();
+ */
+ /* GraphicsMagick */
+ preserve_settings=(char *) AccessDefinition(image_info,"jpeg",
+ "preserve-settings");
+
+ sampling_factors=image_info->sampling_factor;
+
+ if (preserve_settings)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JPEG:preserve-settings flag is defined.");
+
+ /* Retrieve input file quality */
+ attribute=GetImageAttribute(image,"JPEG-Quality");
+ if ((attribute != (const ImageAttribute *) NULL) &&
+ (attribute->value != (char *) NULL))
+ {
+ (void) sscanf(attribute->value,"%lu",&quality);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Input quality=%lu",quality);
+ }
+
+ /* Retrieve input file colorspace */
+ attribute=GetImageAttribute(image,"JPEG-Colorspace");
+ if ((attribute != (const ImageAttribute *) NULL) &&
+ (attribute->value != (char *) NULL))
+ {
+ (void) sscanf(attribute->value,"%lu",&input_colorspace);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Input colorspace=%lu",input_colorspace);
+ }
+
+ if (input_colorspace == (unsigned long) jpeg_info.in_color_space)
+ {
+ /* Retrieve input sampling factors */
+ attribute=GetImageAttribute(image,"JPEG-Sampling-factors");
+ if ((attribute != (const ImageAttribute *) NULL) &&
+ (attribute->value != (char *) NULL))
+ {
+ sampling_factors=attribute->value;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Input sampling-factors=%s",sampling_factors);
+ }
+ }
+ else
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Input colorspace (%lu) != Output colorspace (%d)",
+ input_colorspace,jpeg_info.in_color_space);
+ }
+ }
+
+ jpeg_set_defaults(&jpeg_info);
+
+ /*
+ Determine bit depth.
+ */
+ {
+ int
+ sample_size;
+
+ sample_size=sizeof(JSAMPLE)*8;
+ if (sample_size > 8)
+ sample_size=12;
+ if ((jpeg_info.data_precision != 12) &&
+ (image->depth <= 8))
+ sample_size=8;
+ jpeg_info.data_precision=sample_size;
+ }
+ if ((image->x_resolution == 0) || (image->y_resolution == 0))
+ {
+ image->x_resolution=72.0;
+ image->y_resolution=72.0;
+ image->units=PixelsPerInchResolution;
+ }
+ if (image_info->density != (char *) NULL)
+ {
+ int
+ count;
+
+ /* FIXME: density should not be set via image_info->density
+ but removing this support may break some applications. */
+ count=GetMagickDimension(image_info->density,&image->x_resolution,
+ &image->y_resolution,NULL,NULL);
+ if (count == 1 )
+ image->y_resolution=image->x_resolution;
+ }
+ jpeg_info.density_unit=1; /* default to DPI */
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image resolution: %ld,%ld",(long) image->x_resolution,
+ (long) image->y_resolution);
+ if ((image->x_resolution != 0) && (image->y_resolution != 0))
+ {
+ /*
+ Set image resolution.
+ */
+ jpeg_info.write_JFIF_header=True;
+ jpeg_info.X_density=(short) image->x_resolution;
+ jpeg_info.Y_density=(short) image->y_resolution;
+ if (image->units == PixelsPerInchResolution)
+ jpeg_info.density_unit=1;
+ if (image->units == PixelsPerCentimeterResolution)
+ jpeg_info.density_unit=2;
+ }
+
+ {
+ const char
+ *value;
+
+ /*
+ Allow the user to select the DCT encoding algorithm.
+ */
+ if ((value=AccessDefinition(image_info,"jpeg","dct-method")))
+ {
+ if (LocaleCompare(value,"ISLOW") == 0)
+ jpeg_info.dct_method=JDCT_ISLOW;
+ else if (LocaleCompare(value,"IFAST") == 0)
+ jpeg_info.dct_method=JDCT_IFAST;
+ else if (LocaleCompare(value,"FLOAT") == 0)
+ jpeg_info.dct_method=JDCT_FLOAT;
+ else if (LocaleCompare(value,"DEFAULT") == 0)
+ jpeg_info.dct_method=JDCT_DEFAULT;
+ else if (LocaleCompare(value,"FASTEST") == 0)
+ jpeg_info.dct_method=JDCT_FASTEST;
+ }
+ }
+
+{
+ const char
+ *value;
+
+ huffman_memory=0;
+ if ((value=AccessDefinition(image_info,"jpeg","optimize-coding")))
+ {
+ if (LocaleCompare(value,"FALSE") == 0)
+ jpeg_info.optimize_coding=MagickFalse;
+ else
+ jpeg_info.optimize_coding=MagickTrue;
+ }
+ else
+ {
+ /*
+ Huffman optimization requires that the whole image be buffered in
+ memory. Since this is such a large consumer, obtain a memory
+ resource for the memory to be consumed. If the memory resource
+ fails to be acquired, then don't enable huffman optimization.
+ */
+ huffman_memory=(magick_int64_t) jpeg_info.input_components*
+ image->columns*image->rows*sizeof(JSAMPLE);
+ jpeg_info.optimize_coding=AcquireMagickResource(MemoryResource,
+ huffman_memory);
+ }
+ if (!jpeg_info.optimize_coding)
+ huffman_memory=0;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Huffman optimization is %s",
+ (jpeg_info.optimize_coding ? "enabled" : "disabled"));
+ }
+
+#if (JPEG_LIB_VERSION >= 61) && defined(C_PROGRESSIVE_SUPPORTED)
+ if (image_info->interlace == LineInterlace)
+ jpeg_simple_progression(&jpeg_info);
+ if (image->logging)
+ {
+ if (image_info->interlace == LineInterlace)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Interlace: progressive");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Interlace: nonprogressive");
+ }
+#else
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Interlace: nonprogressive");
+#endif
+ if ((image->compression == LosslessJPEGCompression) ||
+ (quality > 100))
+ {
+#if defined(C_LOSSLESS_SUPPORTED)
+ if (quality < 100)
+ ThrowException(&image->exception,CoderWarning,
+ LosslessToLossyJPEGConversion,(char *) NULL);
+ else
+ {
+ int
+ point_transform,
+ predictor;
+
+ predictor=quality/100; /* range 1-7 */
+ point_transform=quality % 20; /* range 0-15 */
+ jpeg_simple_lossless(&jpeg_info,predictor,point_transform);
+ if (image->logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Compression: lossless");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Predictor: %d",predictor);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Point Transform: %d",point_transform);
+ }
+ }
+#else
+ {
+ jpeg_set_quality(&jpeg_info,100,True);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Quality: 100");
+ }
+#endif
+ }
+ else
+ {
+ jpeg_set_quality(&jpeg_info,(int) quality,True);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Quality: %lu",
+ quality);
+ }
+ if (sampling_factors != (char *) NULL)
+ {
+ double
+ hs[4]={1.0, 1.0, 1.0, 1.0},
+ vs[4]={1.0, 1.0, 1.0, 1.0};
+
+ long
+ count;
+
+ /*
+ Set sampling factors.
+ */
+ count=sscanf(sampling_factors,"%lfx%lf,%lfx%lf,%lfx%lf,%lfx%lf",
+ &hs[0],&vs[0],&hs[1],&vs[1],&hs[2],&vs[2],&hs[3],&vs[3]);
+
+ if (count%2 == 1)
+ vs[count/2]=hs[count/2];
+
+ for (i=0; i < 4; i++)
+ {
+ jpeg_info.comp_info[i].h_samp_factor=(int) hs[i];
+ jpeg_info.comp_info[i].v_samp_factor=(int) vs[i];
+ }
+ for (; i < MAX_COMPONENTS; i++)
+ {
+ jpeg_info.comp_info[i].h_samp_factor=1;
+ jpeg_info.comp_info[i].v_samp_factor=1;
+ }
+ }
+ else
+ {
+ if (quality >= 90)
+ for (i=0; i < MAX_COMPONENTS; i++)
+ {
+ jpeg_info.comp_info[i].h_samp_factor=1;
+ jpeg_info.comp_info[i].v_samp_factor=1;
+ }
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Starting JPEG compression");
+ jpeg_start_compress(&jpeg_info,True);
+ if (image->logging)
+ {
+ if (image->storage_class == PseudoClass)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Storage class: PseudoClass");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Storage class: DirectClass");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Depth: %u",
+ image->depth);
+ if (image->colors)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Number of colors: %u",image->colors);
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Number of colors: unspecified");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "JPEG data precision: %d",(int) jpeg_info.data_precision);
+ if (IsCMYKColorspace(image_info->colorspace))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Storage class: DirectClass");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Colorspace: CMYK");
+ }
+ else if (IsYCbCrColorspace(image_info->colorspace))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Colorspace: YCbCr");
+ }
+ if (IsCMYKColorspace(image->colorspace))
+ {
+ /* A CMYK space */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Colorspace: CMYK");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Sampling factors: %dx%d,%dx%d,%dx%d,%dx%d",
+ jpeg_info.comp_info[0].h_samp_factor,
+ jpeg_info.comp_info[0].v_samp_factor,
+ jpeg_info.comp_info[1].h_samp_factor,
+ jpeg_info.comp_info[1].v_samp_factor,
+ jpeg_info.comp_info[2].h_samp_factor,
+ jpeg_info.comp_info[2].v_samp_factor,
+ jpeg_info.comp_info[3].h_samp_factor,
+ jpeg_info.comp_info[3].v_samp_factor);
+ }
+ else if (IsGrayColorspace(image->colorspace))
+ {
+ /* A gray space */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Colorspace: GRAY");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Sampling factors: %dx%d",
+ jpeg_info.comp_info[0].h_samp_factor,
+ jpeg_info.comp_info[0].v_samp_factor);
+ }
+ else if (IsRGBCompatibleColorspace(image->colorspace))
+ {
+ /* An RGB space */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Image colorspace is RGB");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Sampling factors: %dx%d,%dx%d,%dx%d",
+ jpeg_info.comp_info[0].h_samp_factor,
+ jpeg_info.comp_info[0].v_samp_factor,
+ jpeg_info.comp_info[1].h_samp_factor,
+ jpeg_info.comp_info[1].v_samp_factor,
+ jpeg_info.comp_info[2].h_samp_factor,
+ jpeg_info.comp_info[2].v_samp_factor);
+ }
+ else if (IsYCbCrColorspace(image->colorspace))
+ {
+ /* A YCbCr space */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Colorspace: YCbCr");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Sampling factors: %dx%d,%dx%d,%dx%d",
+ jpeg_info.comp_info[0].h_samp_factor,
+ jpeg_info.comp_info[0].v_samp_factor,
+ jpeg_info.comp_info[1].h_samp_factor,
+ jpeg_info.comp_info[1].v_samp_factor,
+ jpeg_info.comp_info[2].h_samp_factor,
+ jpeg_info.comp_info[2].v_samp_factor);
+ }
+ else
+ {
+ /* Some other color space */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Colorspace: %d",
+ image->colorspace);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Sampling factors: %dx%d,%dx%d,%dx%d,%dx%d",
+ jpeg_info.comp_info[0].h_samp_factor,
+ jpeg_info.comp_info[0].v_samp_factor,
+ jpeg_info.comp_info[1].h_samp_factor,
+ jpeg_info.comp_info[1].v_samp_factor,
+ jpeg_info.comp_info[2].h_samp_factor,
+ jpeg_info.comp_info[2].v_samp_factor,
+ jpeg_info.comp_info[3].h_samp_factor,
+ jpeg_info.comp_info[3].v_samp_factor);
+ }
+ }
+ /*
+ Write JPEG profiles.
+ */
+ attribute=GetImageAttribute(image,"comment");
+ if ((attribute != (const ImageAttribute *) NULL) &&
+ (attribute->value != (char *) NULL))
+ for (i=0; i < (long) strlen(attribute->value); i+=65533L)
+ jpeg_write_marker(&jpeg_info,JPEG_COM,(unsigned char *) attribute->value+
+ i,(int) Min(strlen(attribute->value+i),65533L));
+#if 0
+ WriteICCProfile(&jpeg_info,image);
+ WriteIPTCProfile(&jpeg_info,image);
+ WriteXMPProfile(&jpeg_info,image);
+#endif
+ WriteProfiles(&jpeg_info,image);
+ /*
+ Convert MIFF to JPEG raster pixels.
+ */
+ jpeg_pixels=MagickAllocateArray(JSAMPLE *,
+ jpeg_info.input_components*image->columns,sizeof(JSAMPLE));
+ if (jpeg_pixels == (JSAMPLE *) NULL)
+ {
+ if (huffman_memory)
+ LiberateMagickResource(MemoryResource,huffman_memory);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ scanline[0]=(JSAMPROW) jpeg_pixels;
+ if (jpeg_info.data_precision > 8)
+ {
+ unsigned int
+ scale_short;
+
+ scale_short=65535U/MaxValueGivenBits(jpeg_info.data_precision);
+
+ if (jpeg_info.in_color_space == JCS_GRAYSCALE)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing %d bit JCS_GRAYSCALE samples",
+ jpeg_info.data_precision);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=jpeg_pixels;
+ if (image->is_grayscale)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=(JSAMPLE) (ScaleQuantumToShort(GetGraySample(p))/
+ scale_short);
+ p++;
+ }
+ }
+ else
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=(JSAMPLE)
+ (ScaleQuantumToShort(PixelIntensityToQuantum(p))/scale_short);
+ p++;
+ }
+ }
+ (void) jpeg_write_scanlines(&jpeg_info,scanline,1);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ if ((jpeg_info.in_color_space == JCS_RGB) ||
+ (jpeg_info.in_color_space == JCS_YCbCr))
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing %d bit JCS_RGB or "
+ "JCS_YCbCr samples",
+ jpeg_info.data_precision);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=jpeg_pixels;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=(JSAMPLE) (ScaleQuantumToShort(p->red)/16);
+ *q++=(JSAMPLE) (ScaleQuantumToShort(p->green)/16);
+ *q++=(JSAMPLE) (ScaleQuantumToShort(p->blue)/16);
+ p++;
+ }
+ (void) jpeg_write_scanlines(&jpeg_info,scanline,1);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing %d bit JCS_CMYK samples",
+ jpeg_info.data_precision);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=jpeg_pixels;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ /*
+ Convert DirectClass packets to contiguous CMYK scanlines.
+ */
+ *q++=(JSAMPLE) (4095-ScaleQuantumToShort(p->red)/16);
+ *q++=(JSAMPLE) (4095-ScaleQuantumToShort(p->green)/16);
+ *q++=(JSAMPLE) (4095-ScaleQuantumToShort(p->blue)/16);
+ *q++=(JSAMPLE) (4095-ScaleQuantumToShort(p->opacity)/16);
+ p++;
+ }
+ (void) jpeg_write_scanlines(&jpeg_info,scanline,1);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ }
+ else
+ if (jpeg_info.in_color_space == JCS_GRAYSCALE)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing %d bit JCS_GRAYSCALE samples",
+ jpeg_info.data_precision);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=jpeg_pixels;
+ if (image->is_grayscale)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=(JSAMPLE) ScaleQuantumToChar(GetGraySample(p));
+ p++;
+ }
+ }
+ else
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=(JSAMPLE)
+ ScaleQuantumToChar(PixelIntensityToQuantum(p));
+ p++;
+ }
+ }
+ (void) jpeg_write_scanlines(&jpeg_info,scanline,1);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ if ((jpeg_info.in_color_space == JCS_RGB) ||
+ (jpeg_info.in_color_space == JCS_YCbCr))
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing %d bit JCS_RGB or JCS_YCbCr samples",
+ jpeg_info.data_precision);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=jpeg_pixels;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=(JSAMPLE) ScaleQuantumToChar(p->red);
+ *q++=(JSAMPLE) ScaleQuantumToChar(p->green);
+ *q++=(JSAMPLE) ScaleQuantumToChar(p->blue);
+ p++;
+ }
+ (void) jpeg_write_scanlines(&jpeg_info,scanline,1);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing %d bit JCS_CMYK samples",
+ jpeg_info.data_precision);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=jpeg_pixels;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ /*
+ Convert DirectClass packets to contiguous CMYK scanlines.
+ */
+ *q++=(JSAMPLE) (ScaleQuantumToChar(MaxRGB-p->red));
+ *q++=(JSAMPLE) (ScaleQuantumToChar(MaxRGB-p->green));
+ *q++=(JSAMPLE) (ScaleQuantumToChar(MaxRGB-p->blue));
+ *q++=(JSAMPLE) (ScaleQuantumToChar(MaxRGB-p->opacity));
+ p++;
+ }
+ (void) jpeg_write_scanlines(&jpeg_info,scanline,1);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Finishing JPEG compression");
+ jpeg_finish_compress(&jpeg_info);
+ /*
+ Free memory.
+ */
+ if (huffman_memory)
+ LiberateMagickResource(MemoryResource,huffman_memory);
+ jpeg_destroy_compress(&jpeg_info);
+ MagickFreeMemory(jpeg_pixels);
+ CloseBlob(image);
+ return(True);
+}
+#endif
diff --git a/coders/label.c b/coders/label.c
new file mode 100644
index 0000000..c252859
--- /dev/null
+++ b/coders/label.c
@@ -0,0 +1,227 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L AAA BBBB EEEEE L %
+% L A A B B E L %
+% L AAAAA BBBB EEE L %
+% L A A B B E L %
+% LLLLL A A BBBB EEEEE LLLLL %
+% %
+% %
+% Read ASCII String As An Image %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/magick.h"
+#include "magick/render.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d L A B E L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadLABELImage reads a LABEL image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadLABELImage method is:
+%
+% Image *ReadLABELImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadLABELImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowLABELReaderException(code_,reason_,image_) \
+do { \
+ if (draw_info) \
+ DestroyDrawInfo(draw_info); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+
+static Image *ReadLABELImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ char
+ geometry[MaxTextExtent];
+
+ DrawInfo
+ *draw_info = (DrawInfo *) NULL;
+
+ Image
+ *image;
+
+ TypeMetric
+ metrics;
+
+ unsigned int
+ status;
+
+ unsigned long
+ height,
+ width;
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
+ if (draw_info == (DrawInfo *) NULL)
+ ThrowLABELReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ draw_info->fill=image_info->pen;
+ draw_info->text=TranslateText(image_info,image,image_info->filename);
+ if (draw_info->text == (char *) NULL)
+ ThrowLABELReaderException(CoderError,UnableToTranslateText,image);
+ if ((image->columns != 0) || (image->rows != 0))
+ {
+ /*
+ Fit label to canvas size.
+ */
+ for ( ; GetTypeMetrics(image,draw_info,&metrics); draw_info->pointsize*=2)
+ {
+ width=(unsigned long) floor(metrics.width+metrics.max_advance/2+0.5);
+ height=(unsigned long) floor(metrics.ascent-metrics.descent+0.5);
+ if (((image->columns != 0) && (width >= image->columns)) ||
+ ((image->rows != 0) && (height >= image->rows)))
+ break;
+ }
+ for ( ; GetTypeMetrics(image,draw_info,&metrics); draw_info->pointsize--)
+ {
+ width=(unsigned long) floor(metrics.width+metrics.max_advance/2+0.5);
+ height=(unsigned long) floor(metrics.ascent-metrics.descent+0.5);
+ if ((image->columns != 0) && (width <= image->columns) &&
+ ((image->rows == 0) || (height <= image->rows)))
+ break;
+ if ((image->rows != 0) && (height <= image->rows) &&
+ ((image->columns == 0) || (width <= image->columns)))
+ break;
+ if (draw_info->pointsize < 2.0)
+ break;
+ }
+ }
+ status=GetTypeMetrics(image,draw_info,&metrics);
+ if (status == False)
+ ThrowLABELReaderException(TypeError,UnableToGetTypeMetrics,image);
+ FormatString(geometry,"+%g+%g",metrics.max_advance/4,metrics.ascent);
+ if (image->columns == 0)
+ image->columns=(unsigned long)
+ floor(metrics.width+metrics.max_advance/2+0.5);
+ if (image->rows == 0)
+ {
+ image->rows=(unsigned long) floor(metrics.ascent-metrics.descent+0.5);
+ FormatString(geometry,"+%g+%g",image->columns/2.0-metrics.width/2.0,
+ metrics.ascent);
+ }
+ draw_info->geometry=AllocateString(geometry);
+ (void) SetImage(image,OpaqueOpacity);
+ (void) AnnotateImage(image,draw_info);
+ DestroyDrawInfo(draw_info);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r L A B E L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterLABELImage adds attributes for the LABEL image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterLABELImage method is:
+%
+% RegisterLABELImage(void)
+%
+*/
+ModuleExport void RegisterLABELImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("LABEL");
+ entry->decoder=(DecoderHandler) ReadLABELImage;
+ entry->adjoin=False;
+ entry->description="Image label";
+ entry->module="LABEL";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r L A B E L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterLABELImage removes format registrations made by the
+% LABEL module from the list of supported formats.
+%
+% The format of the UnregisterLABELImage method is:
+%
+% UnregisterLABELImage(void)
+%
+*/
+ModuleExport void UnregisterLABELImage(void)
+{
+ (void) UnregisterMagickInfo("LABEL");
+}
diff --git a/coders/locale.c b/coders/locale.c
new file mode 100644
index 0000000..210d284
--- /dev/null
+++ b/coders/locale.c
@@ -0,0 +1,1117 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L OOO CCCC AAA L EEEEE %
+% L O O C A A L E %
+% L O O C AAAAA L EEE %
+% L O O C A A L E %
+% LLLLL OOO CCCC A A LLLLL EEEEE %
+% %
+% Read/Write GraphicsMagick Locale Files %
+% %
+% %
+% Software Design %
+% John Cristy %
+% Kyle Shorter %
+% September 2002 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/list.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteLOCALEImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d C o n f i g u r e F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadConfigureFile() reads the locale configuration file which maps text
+% strings to localized forms.
+%
+% The format of the ReadConfigureFile method is:
+%
+% unsigned int ReadConfigureFile(Image *image,const char *basename,
+% const unsigned long depth,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method ReadConfigureFile returns True if at least one color
+% is defined otherwise False.
+%
+% o image: The image.
+%
+% o basename: The color configuration filename.
+%
+% o depth: depth of <include /> statements.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+static void ChopLocaleComponents(char *path,const unsigned long components)
+{
+ long
+ count;
+
+ register char
+ *p;
+
+ if (*path == '\0')
+ return;
+ p=path+strlen(path)-1;
+ if (*p == '/')
+ *p='\0';
+ for (count=0; (count < (long) components) && (p > path); p--)
+ if (*p == '/')
+ {
+ *p='\0';
+ count++;
+ }
+}
+
+static unsigned int ReadConfigureFile(Image *image,const char *basename,
+ const unsigned long depth,ExceptionInfo *exception)
+{
+ char
+ keyword[MaxTextExtent],
+ locale[MaxTextExtent],
+ message[MaxTextExtent],
+ path[MaxTextExtent],
+ *q,
+ *token,
+ *xml;
+
+ register char
+ *p;
+
+ size_t
+ length,
+ token_max_length;
+
+ /*
+ Read the locale configure file.
+ */
+ (void) strlcpy(path,basename,sizeof(path));
+ xml=(char *) FileToBlob(basename,&length,exception);
+ if (xml == (char *) NULL)
+ return(False);
+ (void) strlcpy(locale,"/",sizeof(locale));
+ token=AllocateString(xml);
+ token_max_length=strlen(token);
+ for (q=xml; *q != '\0'; )
+ {
+ /*
+ Interpret XML.
+ */
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == '\0')
+ break;
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ if (LocaleNCompare(keyword,"<!--",4) == 0)
+ {
+ char
+ comment[MaxTextExtent];
+
+ /*
+ Comment element.
+ */
+ p=q;
+ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
+ MagickGetToken(q,&q,token,token_max_length);
+ length=Min(q-p-2,MaxTextExtent-1);
+ (void) strncpy(comment,p+1,length);
+ comment[length]='\0';
+ (void) SetImageAttribute(image,"[LocaleComment]",comment);
+ (void) SetImageAttribute(image,"[LocaleComment]","\n");
+ continue;
+ }
+ if (LocaleCompare(keyword,"<include") == 0)
+ {
+ /*
+ Include element.
+ */
+ while ((*token != '>') && (*q != '\0'))
+ {
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(keyword,"file") == 0)
+ {
+ if (depth > 200)
+ ThrowException(exception,ConfigureError,IncludeElementNestedTooDeeply,path);
+ else
+ {
+ char
+ filename[MaxTextExtent];
+
+ filename[0]='\0';
+ GetPathComponent(path,HeadPath,filename);
+ if (filename[0] != '\0')
+ (void) strlcat(filename,DirectorySeparator,sizeof(filename));
+ (void) strlcat(filename,token,sizeof(filename));
+ (void) ReadConfigureFile(image,filename,depth+1,exception);
+ }
+ }
+ }
+ continue;
+ }
+ if (LocaleCompare(keyword,"<locale") == 0)
+ {
+ /*
+ Locale element.
+ */
+ while ((*token != '>') && (*q != '\0'))
+ {
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(keyword,"name") == 0)
+ {
+ (void) strlcpy(locale,token,MaxTextExtent);
+ (void) strlcat(locale,"/",MaxTextExtent);
+ }
+ }
+ continue;
+ }
+ if (LocaleCompare(keyword,"</locale>") == 0)
+ {
+ ChopLocaleComponents(locale,1);
+ (void) strcat(locale,"/");
+ continue;
+ }
+ if (LocaleCompare(keyword,"<localemap>") == 0)
+ continue;
+ if (LocaleCompare(keyword,"</localemap>") == 0)
+ continue;
+ if (LocaleCompare(keyword,"<message") == 0)
+ {
+ /*
+ Message element.
+ */
+ while ((*token != '>') && (*q != '\0'))
+ {
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(keyword,"name") == 0)
+ {
+ (void) strlcat(locale,token,sizeof(locale));
+ (void) strlcat(locale,"/",sizeof(locale));
+ }
+ }
+ for (p=q; (*q != '<') && (*q != '\0'); q++)
+ { /* nada */ };
+ {
+ (void) strncpy(message,p,(size_t)(q-p));
+ message[q-p]='\0';
+ Strip(message);
+ (void) strlcat(locale,message,sizeof(locale));
+ (void) strlcat(locale,"\n",sizeof(locale));
+ (void) SetImageAttribute(image,"[Locale]",locale);
+ }
+ continue;
+ }
+ if (LocaleCompare(keyword,"</message>") == 0)
+ {
+ ChopLocaleComponents(locale,2);
+ (void) strcat(locale,"/");
+ continue;
+ }
+ if (*keyword == '<')
+ {
+ /*
+ Subpath element.
+ */
+ if (*(keyword+1) == '?')
+ continue;
+ if (*(keyword+1) == '/')
+ {
+ ChopLocaleComponents(locale,1);
+ (void) strcat(locale,"/");
+ continue;
+ }
+ token[strlen(token)-1]='\0';
+ (void) memmove(token,token+1,strlen(token+1)+1);
+ (void) strlcat(locale,token,sizeof(locale));
+ (void) strlcat(locale,"/",sizeof(locale));
+ continue;
+ }
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (*token != '=')
+ continue;
+ }
+ MagickFreeMemory(token);
+ MagickFreeMemory(xml);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d L O C A L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadLOCALEImage reads a Magick Configure File as a blob an attaches
+% it as an image attribute to a proxy image. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% The format of the ReadLOCALEImage method is:
+%
+% Image *ReadLOCALEImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadLOCALEImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadLOCALEImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ MagickPassFail
+ status;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ image->columns=1;
+ image->rows=1;
+ (void) SetImage(image,OpaqueOpacity);
+ status=ReadConfigureFile(image,image->filename,0,exception);
+ (void) CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r L O C A L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterLOCALEImage adds attributes for the LOCALE image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterLOCALEImage method is:
+%
+% RegisterLOCALEImage(void)
+%
+*/
+ModuleExport void RegisterLOCALEImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("LOCALE");
+ entry->decoder=(DecoderHandler) ReadLOCALEImage;
+ entry->encoder=(EncoderHandler) WriteLOCALEImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Locale Message File";
+ entry->module="LOCALE";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("LOCALEMC");
+ entry->encoder=(EncoderHandler) WriteLOCALEImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Microsoft Message File";
+ entry->module="LOCALE";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("LOCALEC");
+ entry->encoder=(EncoderHandler) WriteLOCALEImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Locale Message File - C code";
+ entry->module="LOCALE";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("LOCALEH");
+ entry->encoder=(EncoderHandler) WriteLOCALEImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Locale Message File - C header file";
+ entry->module="LOCALE";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r L O C A L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterLOCALEImage removes format registrations made by the
+% LOCALE module from the list of supported formats.
+%
+% The format of the UnregisterLOCALEImage method is:
+%
+% UnregisterLOCALEImage(void)
+%
+*/
+ModuleExport void UnregisterLOCALEImage(void)
+{
+ (void) UnregisterMagickInfo("LOCALE");
+ (void) UnregisterMagickInfo("LOCALEMC");
+ (void) UnregisterMagickInfo("LOCALEC");
+ (void) UnregisterMagickInfo("LOCALEH");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e L O C A L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteLOCALEImage() writes a Magick Configure File as C source.
+%
+% The format of the WriteLOCALEImage method is:
+%
+% unsigned int WriteLOCALEImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteLOCALEImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+struct locale_str {
+ struct locale_str *next; /* link list of subfield names at this level */
+ struct locale_str *lower; /* link list of subfield names below this level */
+ char *name; /* the subfield name or the message */
+};
+
+static void accumulate(const char **, int, struct locale_str **);
+static void output_switches(Image *image,struct locale_str *, int, int);
+
+#define INDENT 2 /* # of spaces to indent each line of the output */
+
+static const char prologue[] = "/* This method is autogenerated-- do not edit */\
+\nconst char *GetLocaleMessage(const char *tag)\
+\n{\
+\n#define NEXT_FIELD ((p = (np = strchr((tp = np), '/')) ? np++ : (np = tp + strlen(tp))), tp)\n\
+\n\
+\n static const char *locale = 0;\
+\n register const char *p, *tp, *np;\
+\n if (!tag || *tag == '\\0')\
+\n return \"\";\n\
+\n if ( (!locale &&\
+\n ( (!(locale = setlocale(LC_CTYPE, 0)) || *locale == '\\0') &&\
+\n (!(locale = getenv(\"LC_ALL\")) || *locale == '\\0') &&\
+\n (!(locale = getenv(\"LC_MESSAGES\")) || *locale == '\\0') &&\
+\n (!(locale = getenv(\"LC_CTYPE\")) || *locale == '\\0') &&\
+\n (!(locale = getenv(\"LANG\")) || *locale == '\\0') ) )\
+\n || !LocaleCompare(locale, \"C\"))\
+\n locale = \"C\";\n\
+\n if (!LocaleNCompare(locale,\"en_US\",5))\
+\n locale = \"C\";\n\
+\n locale = \"C\";\n\
+\n tp = locale;\n p = locale + strlen(locale);\n np = tag;\n";
+
+static const char epilogue[] = "\n return tag;\n}\n";
+
+static char *EscapeLocaleString(const char *str)
+{
+ const char *p;
+ char *strput, *s;
+ size_t n;
+
+ for (p = str, n = 0; *p; p++, n++)
+ if (*p == '"' || *p == '\\')
+ ++n;
+
+ if (!(strput = MagickAllocateMemory(char *,n + 1)))
+ {
+ (void) fprintf(stderr, "out of memory!\n");
+ exit(1);
+ }
+
+ for (p = str, s = strput; *p; p++)
+ {
+ if (*str == '\\' || *str == '"')
+ *s++ = '\\';
+ *s++ = *p;
+ }
+
+ *s = '\0';
+ return strput;
+}
+
+#if 0
+static void FreeAccumulatedStrings(void *handle)
+{
+ struct locale_str *xl = (struct locale_str *)handle;
+ if (!handle)
+ return;
+ FreeAccumulatedStrings((void *)xl->next);
+ FreeAccumulatedStrings((void *)xl->lower);
+ MagickFreeMemory(xl->name);
+ MagickFreeMemory(handle);
+}
+#endif
+
+/* accumulate -- read a line from the file, break it up at the '/'s into
+ * individual subfields and build a tree structure that has
+ * a string message (the last subfield) as its leaf node.
+ */
+static void accumulate(const char **buf, int siz, struct locale_str **locstr)
+{
+ const char *p, *np, *tp;
+ char *xp, *xn, *xt;
+ struct locale_str *xl, **xloc;
+ int n;
+
+ for (n = 0; (siz == 0 || n < siz) && buf[n]; n++)
+ {
+ xloc = locstr;
+
+ /* break the line into separate fields, setting up as follows: */
+ /* tp points at the first char of the current subfield */
+ /* np points at the first char of the next subfield */
+ /* p points one after the last char of the current subfield */
+ for (p = tp = buf[n]; p && *p; p = np)
+ {
+ if (!(np = strchr(p, '/'))) /* last field is the message */
+ {
+ if (!(xp = (char *) AllocateString(tp)))
+ {
+ (void) fprintf(stderr, " out of memory!\n");
+ exit(1);
+ }
+ xt = xp;
+ for (xn = xp; (*xn = *xt); xt++) /* eliminate '\'s */
+ if (*xn != '\\')
+ ++xn;
+
+ if (*xloc && !(*xloc)->lower) /* see if already there */
+ {
+ if (LocaleCompare((*xloc)->name, xp))
+ (void) fprintf(stderr, "ignoring dup message for `%s'\n",
+ buf[n]);
+ MagickFreeMemory(xp);
+ break;
+ }
+ /* fall through to create the node */
+ }
+ else if (np == tp) /* skip multiple /'s */
+ {
+ ++np, ++tp;
+ continue;
+ }
+ else if (np[-1] == '\\') /* this '/' has been escaped */
+ {
+ ++np;
+ continue;
+ }
+ else /* subfield name */
+ {
+ int x;
+
+ if (!(xp = MagickAllocateMemory(char *,(size_t) (np - tp + 1))))
+ {
+ (void) fprintf(stderr, "out of memory!\n" );
+ exit(1);
+ }
+ (void) strlcpy(xp, tp, (size_t) (np - tp + 1));
+ tp = ++np;
+
+ if (*xloc && !(*xloc)->lower) /* skip leaf node if it's there */
+ xloc = &(*xloc)->next;
+ for (x = -1; (xl = *xloc); xloc = &xl->next)
+ if ((x = LocaleCompare(xp, xl->name)) <= 0)
+ break;
+
+ if (x == 0) /* subfield exists */
+ {
+ MagickFreeMemory(xp);
+ xloc = &xl->lower;
+ continue;
+ }
+ }
+
+ /* node doesn't exist; create it */
+
+ if (*xp == '\0')
+ (void) fprintf(stderr, "warning: message is null for '%s'\n", buf[n]);
+
+ if (!(xl = MagickAllocateMemory(struct locale_str *,sizeof *xl)))
+ {
+ (void) fprintf(stderr, "out of memory!\n");
+ exit(1);
+ }
+ xl->name = xp;
+ xl->lower = 0;
+ xl->next = *xloc;
+ *xloc = xl;
+ xloc = &xl->lower;
+ }
+ }
+}
+
+/* output_switches -- generate a single C statement from the list of names
+ * in the locstr tree. This is a recursive procedure.
+ * `indent' is the output line indentation to make the
+ * generated code readable. `elseflag' is < 0 the first
+ * time this routine is called, otherwise it's just used
+ * to line up "else if" in the output a little better.
+ */
+static void output_switches(Image *image,struct locale_str *locstr, int indent, int elseflag)
+{
+ char
+ message[10*MaxTextExtent];
+
+ int flag;
+ struct locale_str *xl;
+ char *p, *field = (char *) "NEXT_FIELD";
+
+ if (!locstr)
+ {
+ (void) fprintf(stderr, "NULL locstr in output_switches\n");
+ return;
+ }
+
+ if (elseflag < 0)
+ field = (char *) "locale", elseflag = 0;
+
+ if (!locstr->next) /* output simpler code for a single case */
+ {
+ p = EscapeLocaleString(locstr->name);
+ if (!locstr->lower)
+ {
+ FormatString(message, "%*sreturn *np ? tag : \"%s\";\n", indent, "", p);
+ (void) WriteBlobString(image,message);
+ }
+ else
+ {
+ if (elseflag)
+ indent -= INDENT;
+
+ FormatString(message, "%*sif (LocaleNCompare(%s, \"%s\", %ld) || p - tp != %ld)\n%*sreturn tag;\n%*selse\n",
+ indent, "", field, p, (long) strlen(locstr->name),
+ (long) strlen(locstr->name), indent+INDENT, "", indent, "");
+ (void) WriteBlobString(image,message);
+
+ output_switches(image, locstr->lower, indent+INDENT, 1);
+ }
+ MagickFreeMemory(p);
+ return;
+ }
+
+ FormatString(message, "%*sswitch (*%s)\n%*s{\n%*sdefault:\n%*sreturn tag;\n",
+ indent, "", field, indent, "", indent, "", indent+INDENT, "");
+
+ (void) WriteBlobString(image,message);
+ xl = locstr;
+ if (!xl->lower)
+ {
+ p = EscapeLocaleString(xl->name);
+ FormatString(message, "\n%*scase '\\0':\n%*sreturn \"%s\";\n",
+ indent, "", indent+INDENT, "", p);
+ (void) WriteBlobString(image,message);
+ MagickFreeMemory(p);
+ xl = xl->next;
+ }
+
+ for (flag = 1; xl; xl = xl->next)
+ {
+ if (flag)
+ {
+ FormatString(message, "\n%*scase '%c': case '%c':\n",
+ indent, "", tolower((int) *xl->name), toupper((int) *xl->name));
+ (void) WriteBlobString(image,message);
+ }
+
+ p = EscapeLocaleString(xl->name);
+ FormatString(message, "%*sif (p - tp == %ld && !LocaleNCompare(tp, \"%s\", %ld))\n",
+ indent+INDENT, "", (long) strlen(xl->name), p, (long) strlen(xl->name));
+ (void) WriteBlobString(image,message);
+ MagickFreeMemory(p);
+
+ output_switches(image,xl->lower, indent+INDENT+INDENT, 0);
+ FormatString(message, "%*selse\n", indent+INDENT, "");
+ (void) WriteBlobString(image,message);
+
+ flag = xl->next == 0 || tolower((int) *xl->name) != tolower((int) *xl->next->name);
+ if (flag)
+ {
+ FormatString(message, "%*sreturn tag;\n", indent+INDENT+INDENT, "");
+ (void) WriteBlobString(image,message);
+ }
+ }
+
+ FormatString(message, "%*s}\n", indent, "");
+ (void) WriteBlobString(image,message);
+}
+
+void WriteBlobStringEOL(Image *image)
+{
+#if defined(MSWINDOWS)
+ (void) WriteBlobString(image,"\r\n");
+#else
+ (void) WriteBlobString(image,"\n");
+#endif
+}
+
+void WriteBlobStringWithEOL(Image *image,const char *s)
+{
+ (void) WriteBlobString(image,s);
+#if defined(MSWINDOWS)
+ (void) WriteBlobString(image,"\r\n");
+#else
+ (void) WriteBlobString(image,"\n");
+#endif
+}
+
+#define TREE_LEVELS_SUPPORTED 5
+
+static unsigned int WriteLOCALEImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ **locale;
+
+ const ImageAttribute
+ *attribute;
+
+ register int
+ i,
+ j;
+
+ struct locale_str
+ *locales;
+
+ unsigned int
+ status;
+
+ int
+ count;
+
+ /*
+ Open output locale file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ attribute=GetImageAttribute(image,"[Locale]");
+ if (attribute == (const ImageAttribute *) NULL)
+ ThrowWriterException(ImageError,NoLocaleImageAttribute,image);
+ locale=StringToList(attribute->value);
+ if (locale == (char **) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Sort locale messages.
+ */
+ for (i=0; locale[i] != (char *) NULL; i++);
+ count=i-1;
+ for (i=0; i < count; i++)
+ for (j=(i+1); j < count; j++)
+ if (LocaleCompare(locale[i],locale[j]) > 0)
+ {
+ char
+ *swap;
+
+ swap=locale[i];
+ locale[i]=locale[j];
+ locale[j]=swap;
+ }
+ if (IsEventLogging())
+ for (i=0; i < count; i++)
+ (void) LogMagickEvent(LocaleEvent,GetMagickModule(),"%.1024s",locale[i]);
+ if (LocaleCompare(image_info->magick,"LOCALEMC") == 0)
+ {
+ /*
+ Write microsoft message compiler message file format.
+ */
+ for (i=0; i < count; i++)
+ {
+ char
+ *fields[4],
+ text[MaxTextExtent],
+ path[MaxTextExtent];
+
+ int
+ index;
+
+ register char
+ *p;
+
+ (void) strlcpy(path,locale[i],sizeof(path));
+ if (*path != '\0')
+ {
+ p=path+strlen(path)-1;
+ if (*p == '/')
+ *p='\0';
+ for (index=0; (index < 4) && (p > path); p--)
+ {
+ if (*p == '/')
+ {
+ *p='\0';
+ fields[3-index]=p+1;
+ index++;
+ }
+ }
+ (void) WriteBlobString(image,"\r\n");
+ if (i == 0)
+ {
+ (void) WriteBlobString(image,"MessageId = 0\r\nSymbolicName = GENERIC_MESSAGE\r\nLanguage = English\r\n%1\r\n.\r\n");
+ (void) WriteBlobString(image,"MessageId = 1\r\n");
+ }
+ else
+ (void) WriteBlobString(image,"MessageId = +1\r\n");
+ FormatString(text, "SymbolicName = %s%s%s\r\n", fields[0],fields[1],fields[2]);
+ (void) WriteBlobString(image,text);
+ (void) WriteBlobString(image,"Language = English\r\n");
+ FormatString(text, "%s\r\n", fields[3]);
+ (void) WriteBlobString(image,text);
+ (void) WriteBlobString(image,".\r\n");
+ }
+ }
+ }
+ else if (LocaleCompare(image_info->magick,"LOCALEH") == 0)
+ {
+ const char
+ *fields[TREE_LEVELS_SUPPORTED];
+
+ char
+ last[MaxTextExtent],
+ last2[MaxTextExtent],
+ category[MaxTextExtent],
+ severity[MaxTextExtent],
+ text[MaxTextExtent],
+ path[MaxTextExtent];
+
+ int
+ index,
+ severityindex;
+
+ register char
+ *p;
+
+ WriteBlobStringWithEOL(image,"#ifndef _LOCAL_C_H");
+ WriteBlobStringWithEOL(image,"#define _LOCAL_C_H");
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"extern MagickExport const char *GetLocaleMessageFromID(const int);");
+ WriteBlobStringEOL(image);
+ FormatString(text, "#define MAX_LOCALE_MSGS %d",count);
+ WriteBlobStringWithEOL(image,text);
+ WriteBlobStringEOL(image);
+ /*
+ Write series of #defines for all the messages in the system.
+ */
+ for (i=0; i < count; i++)
+ {
+ (void) strlcpy(path,locale[i],sizeof(path));
+ if (*path != '\0')
+ {
+ p=path+strlen(path)-1;
+ if (*p == '/')
+ *p='\0';
+ fields[0]=""; /* this one may not exist */
+ for (index=0; (index < TREE_LEVELS_SUPPORTED) && (p > path); p--)
+ {
+ if (*p == '/')
+ {
+ *p='\0';
+ fields[4-index]=p+1;
+ index++;
+ }
+ }
+ FormatString(text, "#define MGK_%s%s%s%s %d",fields[0],fields[1],
+ fields[2],fields[3],i+1);
+ WriteBlobStringWithEOL(image,text);
+ }
+ }
+ /*
+ Write a table that maps category strings over to severity id's
+ */
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"#endif");
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"#if defined(_INCLUDE_CATEGORYMAP_TABLE_)");
+ WriteBlobStringWithEOL(image,"typedef struct _CategoryInfo{");
+ WriteBlobStringWithEOL(image," const char *name;");
+ WriteBlobStringWithEOL(image," int offset;");
+ WriteBlobStringWithEOL(image,"} CategoryInfo;");
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"static const CategoryInfo category_map[] =");
+ WriteBlobStringWithEOL(image," {");
+ last[0]='\0';
+ last2[0]='\0';
+ severityindex=0;
+ for (i=0; i < count; i++)
+ {
+ (void) strlcpy(path,locale[i],sizeof(path));
+ if (*path != '\0')
+ {
+ p=path+strlen(path)-1;
+ if (*p == '/')
+ *p='\0';
+ fields[0]=""; /* this one may not exist */
+ for (index=0; (index < TREE_LEVELS_SUPPORTED) && (p > path); p--)
+ {
+ if (*p == '/')
+ {
+ *p='\0';
+ fields[4-index]=p+1;
+ index++;
+ }
+ }
+ FormatString(category, "%s%s",fields[0], fields[1]);
+ FormatString(severity, "%s%s%s",fields[0], fields[1], fields[2]);
+ if (LocaleCompare(severity,last2) != 0)
+ {
+ severityindex++;
+ (void) strlcpy(last2,severity,MaxTextExtent);
+ }
+ if (LocaleCompare(category,last) != 0)
+ {
+ FormatString(text, " { \"%s%s%s\", %d },", fields[0],
+ strlen(fields[0]) ? "/" : "", fields[1], severityindex-1);
+ WriteBlobStringWithEOL(image,text);
+ (void) strlcpy(last,category,MaxTextExtent);
+ }
+ }
+ }
+ FormatString(text, " { 0, %d }",severityindex-1);
+ WriteBlobStringWithEOL(image,text);
+ WriteBlobStringWithEOL(image," };");
+ WriteBlobStringWithEOL(image,"#endif");
+ /*
+ Write a table that maps severity strings over to severity id's
+ */
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"#if defined(_INCLUDE_SEVERITYMAP_TABLE_)");
+ WriteBlobStringWithEOL(image,"typedef struct _SeverityInfo{");
+ WriteBlobStringWithEOL(image," const char *name;");
+ WriteBlobStringWithEOL(image," int offset;");
+ WriteBlobStringWithEOL(image," ExceptionType severityid;");
+ WriteBlobStringWithEOL(image,"} SeverityInfo;");
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"static const SeverityInfo severity_map[] =");
+ WriteBlobStringWithEOL(image," {");
+ last[0]='\0';
+ for (i=0; i < count; i++)
+ {
+ (void) strlcpy(path,locale[i],sizeof(path));
+ if (*path != '\0')
+ {
+ p=path+strlen(path)-1;
+ if (*p == '/')
+ *p='\0';
+ fields[0]=""; /* this one may not exist */
+ for (index=0; (index < TREE_LEVELS_SUPPORTED) && (p > path); p--)
+ {
+ if (*p == '/')
+ {
+ *p='\0';
+ fields[4-index]=p+1;
+ index++;
+ }
+ }
+ FormatString(severity, "%s%s%s",fields[0], fields[1], fields[2]);
+ if (LocaleCompare(severity,last) != 0)
+ {
+ FormatString(text, " { \"%s%s%s/%s\", %d, %s },", fields[0],
+ strlen(fields[0]) ? "/" : "", fields[1], fields[2], i,
+ severity);
+ WriteBlobStringWithEOL(image,text);
+ (void) strlcpy(last,severity,MaxTextExtent);
+ }
+ }
+ }
+ FormatString(text, " { 0, %d, UndefinedException }",count);
+ WriteBlobStringWithEOL(image,text);
+ WriteBlobStringWithEOL(image," };");
+ WriteBlobStringWithEOL(image,"#endif");
+ /*
+ Write a table that maps tag strings over to messages id's
+ */
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"#if defined(_INCLUDE_TAGMAP_TABLE_)");
+ WriteBlobStringWithEOL(image,"typedef struct _MessageInfo");
+ WriteBlobStringWithEOL(image,"{");
+ WriteBlobStringWithEOL(image," const char *name;");
+ WriteBlobStringWithEOL(image," int messageid;");
+ WriteBlobStringWithEOL(image,"} MessageInfo;");
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"static const MessageInfo message_map[] =");
+ WriteBlobStringWithEOL(image," {");
+ for (i=0; i < count; i++)
+ {
+ (void) strlcpy(path,locale[i],sizeof(path));
+ if (*path != '\0')
+ {
+ p=path+strlen(path)-1;
+ if (*p == '/')
+ *p='\0';
+ fields[0]=""; /* this one may not exist */
+ for (index=0; (index < TREE_LEVELS_SUPPORTED) && (p > path); p--)
+ {
+ if (*p == '/')
+ {
+ *p='\0';
+ fields[4-index]=p+1;
+ index++;
+ }
+ }
+ FormatString(text, " { \"%s\", %d },", fields[3], i+1);
+ WriteBlobStringWithEOL(image,text);
+ }
+ }
+ WriteBlobStringWithEOL(image," { 0, 0 }");
+ WriteBlobStringWithEOL(image," };");
+ WriteBlobStringWithEOL(image,"#endif");
+ /*
+ Write a table of all the messages indexed by the message id.
+ */
+ WriteBlobStringEOL(image);
+ WriteBlobStringWithEOL(image,"#if defined(_INCLUDE_MESSAGE_TABLE_)");
+ WriteBlobStringWithEOL(image,"static const char *message_dat[] =");
+ WriteBlobStringWithEOL(image," {");
+ /* message 0 is reserved as the generic windows event message */
+ WriteBlobStringWithEOL(image," \"%1\",");
+ for (i=0; i < count; i++)
+ {
+ (void) strlcpy(path,locale[i],sizeof(path));
+ if (*path != '\0')
+ {
+ p=path+strlen(path)-1;
+ if (*p == '/')
+ *p='\0';
+ fields[0]=""; /* this one may not exist */
+ for (index=0; (index < TREE_LEVELS_SUPPORTED) && (p > path); p--)
+ {
+ if (*p == '/')
+ {
+ *p='\0';
+ fields[4-index]=p+1;
+ index++;
+ }
+ }
+ FormatString(text, " \"%s\",",fields[4]);
+ WriteBlobStringWithEOL(image,text);
+ }
+ }
+ WriteBlobStringWithEOL(image," 0");
+ WriteBlobStringWithEOL(image," };");
+ WriteBlobStringWithEOL(image,"#endif");
+ }
+ else if ((LocaleCompare(image_info->magick,"LOCALE") == 0) ||
+ (LocaleCompare(image_info->magick,"LOCALEC") == 0))
+ {
+ /*
+ Write locale comments.
+ */
+ attribute=GetImageAttribute(image,"[LocaleComment]");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) WriteBlobString(image,attribute->value);
+ /*
+ Write finite-state-machine.
+ */
+ locales=(struct locale_str *) NULL;
+ accumulate((const char **) locale,count,&locales);
+ (void) WriteBlobString(image,prologue);
+ output_switches(image,locales, INDENT, -1);
+ (void) WriteBlobString(image,epilogue);
+ }
+ /*
+ Free resources.
+ */
+ for (i=0; i <= count; i++)
+ MagickFreeMemory(locale[i]);
+ MagickFreeMemory(locale);
+ CloseBlob(image);
+ return(True);
+}
+
diff --git a/coders/logo.c b/coders/logo.c
new file mode 100644
index 0000000..e24ffc6
--- /dev/null
+++ b/coders/logo.c
@@ -0,0 +1,5412 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Parts Copyright (c) 1985-1988 by Supoj Sutanthavibul
+% Parts Copyright (c) 1989-2000 by Brian V. Smith
+% Parts Copyright (c) 1991 by Paul King
+% Parts Copyright (C) 2002 ImageMagick Studio
+% Parts Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L OOO GGGG OOO %
+% L O O G O O %
+% L O O G GG O O %
+% L O O G G O O %
+% LLLLL OOO GGG OOO %
+% %
+% %
+% Read Embedded GraphicsMagick Images %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% Bob Friesenhahn %
+% May 2003 %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/magick.h"
+#include "magick/texture.h"
+#include "magick/utility.h"
+
+
+/*
+ Many of these patterns are compliments of the XFig package.
+*/
+
+/*
+ Bricks image declaration.
+*/
+#define BricksImageExtent 41
+
+static const unsigned char
+ BricksImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x31, 0x36, 0x20, 0x31, 0x36, 0x0A, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xFF,
+ 0xFF, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x01, 0x00, 0xFF, 0xFF,
+ };
+
+/*
+ Circles image declaration.
+*/
+#define CirclesImageExtent 41
+
+static const unsigned char
+ CirclesImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x31, 0x36, 0x20, 0x31, 0x36, 0x0A, 0x07, 0xF0, 0x18,
+ 0x0C, 0x20, 0x02, 0x40, 0x01, 0x40, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80,
+ 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x01, 0x40,
+ 0x01, 0x20, 0x02, 0x18, 0x0C,
+ };
+
+/*
+ CrossHatch image declaration.
+*/
+#define CrossHatchImageExtent 11
+
+static const unsigned char
+ CrossHatchImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x34, 0x0A, 0xFF, 0x11, 0x11, 0x11,
+ };
+
+/*
+ CrossHatch30 image declaration.
+*/
+#define CrossHatch30ImageExtent 11
+
+static const unsigned char
+ CrossHatch30Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x34, 0x0A, 0x81, 0x66, 0x18, 0x66,
+ };
+
+/*
+ CrossHatch45 image declaration.
+*/
+#define CrossHatch45ImageExtent 15
+
+static const unsigned char
+ CrossHatch45Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x88, 0x50, 0x20, 0x50, 0x88,
+ 0x05, 0x02, 0x05,
+ };
+
+/*
+ FishScales image declaration.
+*/
+#define FishScalesImageExtent 24
+
+static const unsigned char
+ FishScalesImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x31, 0x36, 0x20, 0x38, 0x0A, 0x02, 0x40, 0x0C, 0x30,
+ 0x70, 0x0E, 0x80, 0x01, 0x40, 0x02, 0x30, 0x0C, 0x0E, 0x70, 0x01, 0x80,
+
+ };
+
+/*
+ Granite image declaration.
+*/
+
+#define GraniteImageExtent 7037
+
+static const unsigned char
+ GraniteImage[]=
+ {
+ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x80, 0x00, 0x80, 0x00, 0xf3, 0x00,
+ 0x00, 0xa0, 0xa0, 0xa0, 0xa0, 0x98, 0xa0, 0xa9, 0xb2, 0xa9, 0xa0, 0xa9,
+ 0xa0, 0xbb, 0xbb, 0xc3, 0xbb, 0xbb, 0xbb, 0xa9, 0xb2, 0xb2, 0xa9, 0xa9,
+ 0xb2, 0xbb, 0xb2, 0xbb, 0xb2, 0xb2, 0xb2, 0xb2, 0xbb, 0xb2, 0xb2, 0xa9,
+ 0xb2, 0xb2, 0xa9, 0xb2, 0xb2, 0xa9, 0xb2, 0xb2, 0xa9, 0xb2, 0xb2, 0xa9,
+ 0xb2, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xfe, 0x29,
+ 0x20, 0x20, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x66,
+ 0x72, 0x6f, 0x6d, 0x20, 0x47, 0x49, 0x46, 0x20, 0x69, 0x6d, 0x61, 0x67,
+ 0x65, 0x3a, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e,
+ 0x64, 0x2e, 0x67, 0x69, 0x66, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x80, 0x00, 0x00, 0x04, 0xfe, 0x70, 0x15, 0x54, 0x52, 0x2a, 0xea,
+ 0x24, 0x64, 0x13, 0x39, 0x9a, 0x64, 0x21, 0xc6, 0xb2, 0x9d, 0x8b, 0x30,
+ 0x9e, 0x88, 0xb2, 0x28, 0x45, 0x11, 0x76, 0xef, 0x45, 0x58, 0x45, 0xca,
+ 0x99, 0x0b, 0x38, 0x00, 0x07, 0x53, 0x48, 0x60, 0xfa, 0xcc, 0x7a, 0x08,
+ 0xe0, 0xe5, 0xc0, 0x01, 0x81, 0x10, 0xc4, 0xc4, 0xa1, 0x70, 0xe3, 0xec,
+ 0x14, 0x56, 0xc0, 0x02, 0xa8, 0xb8, 0x60, 0x78, 0x0a, 0x42, 0x2c, 0x61,
+ 0x20, 0x79, 0x62, 0x94, 0x43, 0x18, 0x4b, 0x35, 0x1c, 0x06, 0xea, 0x16,
+ 0x86, 0x4c, 0xc0, 0xc2, 0xca, 0x06, 0xcf, 0x85, 0x4c, 0x21, 0xef, 0xcb,
+ 0x5d, 0x04, 0x04, 0x79, 0x6e, 0x06, 0x62, 0x83, 0x52, 0x7e, 0x65, 0x32,
+ 0x86, 0x40, 0x32, 0x54, 0x19, 0x70, 0x06, 0x63, 0x09, 0x00, 0x02, 0x6a,
+ 0x75, 0x54, 0x62, 0x09, 0x61, 0x54, 0x9e, 0x82, 0x05, 0x3f, 0x13, 0x2a,
+ 0x5d, 0x00, 0x09, 0x03, 0x36, 0x31, 0x48, 0x9d, 0x62, 0x26, 0x3b, 0x41,
+ 0x4c, 0x1b, 0x5a, 0x00, 0x14, 0x5b, 0x53, 0x55, 0x09, 0xae, 0x13, 0x31,
+ 0x58, 0x67, 0x55, 0x39, 0x63, 0x3d, 0xb6, 0x41, 0xb9, 0x67, 0x3b, 0xb9,
+ 0x53, 0x1b, 0xc4, 0x37, 0x15, 0x14, 0xb5, 0x13, 0xc4, 0x05, 0x8e, 0x37,
+ 0x12, 0x15, 0xc2, 0x07, 0x55, 0xc4, 0x0b, 0x03, 0x12, 0x1f, 0x42, 0xb1,
+ 0x12, 0x12, 0x79, 0x5d, 0x9f, 0x15, 0x15, 0x91, 0x64, 0x6f, 0xea, 0x79,
+ 0x15, 0x44, 0x5d, 0x30, 0x90, 0x9b, 0x15, 0x06, 0x4a, 0x97, 0x31, 0x6e,
+ 0xac, 0x39, 0x40, 0xe3, 0x88, 0xf3, 0x09, 0x2a, 0x41, 0x4c, 0xb9, 0x91,
+ 0x61, 0xe1, 0x52, 0x40, 0x25, 0x9e, 0x4e, 0x01, 0x38, 0xe7, 0x84, 0xcb,
+ 0x9e, 0x79, 0x1a, 0x4e, 0x81, 0xc0, 0x00, 0xa4, 0x45, 0x9d, 0x87, 0x39,
+ 0x7c, 0xed, 0x3a, 0x40, 0x2b, 0x8a, 0x90, 0x0d, 0xfe, 0x5d, 0x12, 0x09,
+ 0x73, 0x11, 0x64, 0x97, 0x15, 0x2a, 0x95, 0x98, 0xb8, 0xd0, 0xd7, 0xe3,
+ 0xc6, 0x8d, 0x37, 0x38, 0x3c, 0x7a, 0x92, 0xd0, 0x90, 0xa6, 0x8b, 0x5c,
+ 0x5d, 0xa6, 0x80, 0x58, 0xd0, 0xaa, 0x64, 0xae, 0x1e, 0x3b, 0x8b, 0xd5,
+ 0xf2, 0x22, 0x86, 0x02, 0x01, 0x20, 0x1c, 0xb5, 0x50, 0x01, 0x11, 0x52,
+ 0x82, 0x29, 0x19, 0x3f, 0x7c, 0x1c, 0x98, 0xb4, 0x2b, 0xc6, 0x45, 0x36,
+ 0x87, 0xac, 0x1e, 0x2a, 0x31, 0x60, 0xd0, 0x16, 0x00, 0xb4, 0xdc, 0x48,
+ 0x41, 0x55, 0x46, 0x92, 0x99, 0x0a, 0x3f, 0x0c, 0x45, 0x9a, 0xca, 0xa9,
+ 0x92, 0x18, 0x98, 0x03, 0xd2, 0xec, 0xda, 0x3a, 0xb5, 0xce, 0xd5, 0x54,
+ 0x75, 0x91, 0x6e, 0x53, 0x33, 0xc6, 0x45, 0x1e, 0xb2, 0x64, 0x30, 0x14,
+ 0x28, 0xc1, 0x2e, 0x87, 0xca, 0x6c, 0x45, 0x94, 0xf1, 0x98, 0x70, 0x46,
+ 0x57, 0x51, 0x62, 0x08, 0x1a, 0x32, 0x89, 0x65, 0x45, 0xd6, 0xd0, 0x9e,
+ 0x26, 0xac, 0x21, 0xab, 0x56, 0x72, 0x8b, 0x2b, 0x58, 0x34, 0x99, 0x54,
+ 0x65, 0x7c, 0xf2, 0xe3, 0xcb, 0xcd, 0x32, 0x94, 0x1e, 0x73, 0x69, 0x98,
+ 0x42, 0x05, 0x31, 0xe3, 0x52, 0xa5, 0xc3, 0x61, 0x61, 0x41, 0x9e, 0x29,
+ 0x9d, 0xf8, 0x76, 0x71, 0xf3, 0x03, 0xd5, 0x6e, 0xa4, 0x1a, 0x80, 0xec,
+ 0x03, 0x9b, 0x8e, 0x2c, 0x47, 0x0d, 0x57, 0x09, 0x74, 0xf5, 0xc4, 0x56,
+ 0x54, 0x52, 0x6c, 0xec, 0x44, 0x30, 0x47, 0xcb, 0x17, 0x2c, 0x97, 0x64,
+ 0x77, 0x4e, 0xfd, 0x71, 0x92, 0x61, 0x37, 0x1a, 0x72, 0xcb, 0x3c, 0x59,
+ 0x35, 0x99, 0x10, 0x52, 0xed, 0x58, 0x31, 0x8e, 0xcb, 0xd0, 0x80, 0x52,
+ 0x55, 0x90, 0x12, 0x44, 0x60, 0x69, 0x48, 0x0a, 0x67, 0xc3, 0xa5, 0x0b,
+ 0x2a, 0xd6, 0xef, 0x8c, 0x46, 0x92, 0x26, 0xce, 0x6e, 0x0a, 0x2c, 0xfe,
+ 0xc4, 0x41, 0x4c, 0x3c, 0xdc, 0x27, 0x82, 0x46, 0xd4, 0x18, 0xc6, 0x89,
+ 0x66, 0x2f, 0x50, 0x23, 0xc0, 0x53, 0x6f, 0x00, 0x00, 0x07, 0x3c, 0xa7,
+ 0xbc, 0xd0, 0x57, 0x1d, 0x2d, 0xd8, 0x40, 0x4f, 0x5c, 0x20, 0xb0, 0x33,
+ 0x48, 0x0b, 0x00, 0xc4, 0xb6, 0x06, 0x27, 0x83, 0x54, 0xa4, 0x81, 0x21,
+ 0xb7, 0xa5, 0x03, 0x0b, 0x52, 0x92, 0x48, 0xc1, 0x91, 0x08, 0x58, 0xe4,
+ 0x01, 0x4a, 0x3f, 0x6d, 0x9d, 0x73, 0x08, 0x28, 0x0f, 0x7d, 0x78, 0xcf,
+ 0x20, 0x82, 0x88, 0x11, 0x22, 0x26, 0x80, 0x24, 0x02, 0xd6, 0x8b, 0xa9,
+ 0x85, 0x53, 0xe4, 0x2e, 0x40, 0x79, 0xc2, 0x41, 0x33, 0xc7, 0x45, 0x16,
+ 0x02, 0x2d, 0x27, 0xfc, 0xf2, 0x12, 0x38, 0xc7, 0x69, 0x81, 0x84, 0x50,
+ 0x19, 0xf5, 0xa0, 0x9f, 0x91, 0x1f, 0x3c, 0x73, 0x5a, 0x12, 0x49, 0x08,
+ 0x53, 0x95, 0x31, 0x2c, 0xa0, 0xe6, 0x9a, 0x8b, 0x1c, 0xb4, 0x72, 0x46,
+ 0x05, 0x41, 0x50, 0xf0, 0xd7, 0x1f, 0x89, 0xcc, 0x63, 0xdb, 0x05, 0x29,
+ 0x0c, 0xe6, 0xc7, 0x3b, 0x16, 0x96, 0xa2, 0x86, 0x86, 0x5e, 0xd0, 0x03,
+ 0xc0, 0x5b, 0x84, 0xf5, 0xa0, 0x1d, 0x6f, 0x21, 0x98, 0x63, 0x1b, 0x26,
+ 0xe4, 0xf4, 0xf1, 0x8e, 0x44, 0x03, 0x58, 0x85, 0x0f, 0xa2, 0x87, 0x04,
+ 0x18, 0x06, 0x8a, 0x7c, 0xc5, 0x50, 0xde, 0x78, 0xb7, 0x74, 0x31, 0x92,
+ 0x06, 0x7d, 0x30, 0x81, 0xca, 0x05, 0x19, 0x30, 0x51, 0x42, 0x25, 0x0b,
+ 0x19, 0x06, 0x02, 0x58, 0x3c, 0x18, 0x92, 0xcb, 0xa7, 0xaf, 0xa1, 0x54,
+ 0x84, 0x61, 0xdf, 0x7c, 0x81, 0x02, 0x08, 0xb9, 0x24, 0x84, 0x93, 0x4b,
+ 0x1e, 0x05, 0x07, 0x40, 0x06, 0xd6, 0x71, 0x9a, 0x81, 0x14, 0x48, 0x76,
+ 0xd0, 0x8a, 0xa5, 0x46, 0x99, 0x93, 0x55, 0x51, 0x29, 0x95, 0x70, 0x4e,
+ 0x22, 0x30, 0xfe, 0x58, 0x50, 0x88, 0x0d, 0x19, 0xb8, 0xa1, 0x02, 0x21,
+ 0x17, 0x44, 0xc6, 0x09, 0x02, 0xa8, 0xc0, 0xe1, 0x5b, 0x1f, 0x8b, 0x8c,
+ 0x71, 0x8e, 0x19, 0xbb, 0x4d, 0x45, 0x02, 0x5b, 0x86, 0x08, 0x42, 0x88,
+ 0x74, 0x6c, 0x09, 0x02, 0x47, 0xaf, 0xcf, 0x2d, 0xf0, 0x02, 0x36, 0x07,
+ 0xe4, 0xf7, 0x2e, 0xa5, 0x86, 0xd8, 0x48, 0xad, 0xb3, 0xa9, 0x58, 0x64,
+ 0xc2, 0x08, 0x8c, 0xa9, 0xb2, 0x87, 0x6b, 0x28, 0x39, 0xa3, 0x87, 0x91,
+ 0xae, 0x9c, 0x70, 0x0b, 0x31, 0x53, 0x7c, 0xb6, 0x1a, 0x96, 0xc7, 0xf0,
+ 0xd0, 0x19, 0xc2, 0x2f, 0x6e, 0xe1, 0x0d, 0x32, 0x68, 0x00, 0xb1, 0x00,
+ 0x02, 0x18, 0xeb, 0x83, 0xed, 0x57, 0xb4, 0x4c, 0x91, 0x5a, 0x1c, 0x8d,
+ 0xe9, 0x51, 0x19, 0x35, 0xa2, 0x51, 0x01, 0x87, 0x3f, 0xb7, 0x5d, 0x44,
+ 0x08, 0x1a, 0x54, 0xc9, 0x43, 0x07, 0x2f, 0x18, 0x44, 0x2a, 0x86, 0x2a,
+ 0xcb, 0x0d, 0x86, 0x86, 0x0c, 0x61, 0x00, 0xd4, 0x20, 0x74, 0x9b, 0x84,
+ 0x1a, 0x21, 0x36, 0x9f, 0x92, 0x11, 0xe2, 0x3f, 0x48, 0x11, 0x04, 0x27,
+ 0x44, 0x49, 0x80, 0xa5, 0x5f, 0xa8, 0x42, 0xbb, 0xdb, 0x06, 0x8f, 0xa9,
+ 0x55, 0xcb, 0x11, 0x1a, 0x5e, 0x64, 0x06, 0x8c, 0x35, 0x32, 0xc4, 0x57,
+ 0xac, 0x45, 0xbc, 0x2c, 0x56, 0xad, 0x1d, 0xd9, 0xbc, 0xe8, 0xc5, 0x8b,
+ 0x08, 0x4d, 0x00, 0xc4, 0x83, 0x20, 0x5c, 0x02, 0x65, 0xa9, 0xb4, 0x62,
+ 0x62, 0x98, 0xc5, 0x03, 0x97, 0x54, 0x4b, 0x10, 0xbf, 0xbe, 0xab, 0x44,
+ 0x6d, 0x97, 0xb8, 0x9b, 0x87, 0x07, 0x6b, 0x58, 0xcb, 0x9d, 0x56, 0x47,
+ 0x71, 0x72, 0x8b, 0x34, 0x39, 0x29, 0x51, 0x2f, 0x06, 0xa7, 0x52, 0x4b,
+ 0xce, 0xa0, 0x8a, 0x54, 0xeb, 0xe7, 0x8f, 0xd7, 0xc5, 0x76, 0xb2, 0x11,
+ 0x6e, 0x40, 0x08, 0xdd, 0xd0, 0xfe, 0xbf, 0x4a, 0xe8, 0xc1, 0x26, 0xf4,
+ 0xa8, 0x04, 0xd6, 0x20, 0x4e, 0xc8, 0xc2, 0x11, 0xb4, 0x17, 0x7d, 0x32,
+ 0x90, 0xe0, 0x43, 0xc2, 0x34, 0x5e, 0x64, 0x3b, 0x40, 0xa9, 0x86, 0x09,
+ 0x5a, 0x2c, 0x49, 0xde, 0x92, 0x4e, 0x9c, 0x44, 0xf2, 0x0d, 0x43, 0x42,
+ 0x71, 0x6a, 0x52, 0x40, 0xf5, 0x80, 0xea, 0x66, 0x2e, 0x22, 0x81, 0xf0,
+ 0x42, 0xbd, 0xd2, 0x42, 0x9a, 0x0c, 0x01, 0x2c, 0x16, 0x19, 0x70, 0x9e,
+ 0x6d, 0xd0, 0x2f, 0x92, 0x58, 0xd0, 0xca, 0xfa, 0x4f, 0xc5, 0x02, 0x46,
+ 0x55, 0x60, 0x38, 0xdc, 0xb0, 0x07, 0x60, 0x63, 0x09, 0x07, 0x96, 0xe2,
+ 0x7d, 0xfa, 0xa8, 0xd4, 0x51, 0xb6, 0xd5, 0x71, 0x1c, 0x6e, 0xaf, 0x93,
+ 0xa3, 0xb2, 0x44, 0x52, 0x8d, 0x33, 0x95, 0x9d, 0xd4, 0x0a, 0x97, 0xce,
+ 0xb4, 0xc7, 0x75, 0xe2, 0xc7, 0x3d, 0x6c, 0x99, 0xe3, 0x62, 0xb4, 0x7d,
+ 0xf0, 0x72, 0xc8, 0x62, 0x3c, 0x90, 0x05, 0x83, 0x8a, 0xc4, 0x0d, 0xe0,
+ 0x90, 0x2a, 0x33, 0xc8, 0x48, 0x58, 0x31, 0x5e, 0x05, 0xa6, 0xbd, 0x09,
+ 0x4a, 0x25, 0xbe, 0xea, 0x52, 0x18, 0x56, 0x15, 0x94, 0x11, 0xb8, 0x40,
+ 0x09, 0x57, 0x02, 0x8a, 0xf4, 0x32, 0x52, 0x11, 0x24, 0xd9, 0x6a, 0x5f,
+ 0xb5, 0xd2, 0x12, 0x9b, 0xe2, 0x65, 0x81, 0xac, 0xd4, 0xa9, 0x2e, 0x1b,
+ 0x18, 0x87, 0xa2, 0x6a, 0x00, 0x0f, 0xaf, 0xf0, 0xc2, 0x22, 0x84, 0x98,
+ 0xca, 0xa1, 0xde, 0x93, 0x2c, 0x1e, 0x95, 0xa2, 0x2d, 0x04, 0xc8, 0x50,
+ 0xbd, 0xae, 0x45, 0xa8, 0x90, 0xb4, 0x80, 0x56, 0x31, 0x68, 0x51, 0x8c,
+ 0xee, 0xc7, 0x1e, 0xb5, 0xd8, 0xf0, 0x10, 0x27, 0x92, 0x87, 0xb7, 0xec,
+ 0xf2, 0x0e, 0x1d, 0x92, 0xe0, 0x2d, 0x79, 0x3b, 0x81, 0x0c, 0x86, 0xf2,
+ 0x8c, 0xc8, 0x24, 0xa6, 0x1b, 0x8c, 0x31, 0xcd, 0xfe, 0xaa, 0x9a, 0x20,
+ 0xc5, 0x32, 0x59, 0xcd, 0x19, 0xb1, 0x78, 0x89, 0x12, 0x9e, 0x21, 0x0c,
+ 0x91, 0x24, 0x30, 0x23, 0x69, 0xca, 0x92, 0x7c, 0x90, 0x71, 0x12, 0x8c,
+ 0xe9, 0xa2, 0x60, 0xe1, 0x58, 0xa0, 0xf3, 0x5c, 0x43, 0x0c, 0x54, 0xa5,
+ 0x27, 0x38, 0xcf, 0x19, 0x8c, 0x84, 0xec, 0x58, 0xba, 0x2f, 0xc0, 0xe0,
+ 0x44, 0x52, 0x80, 0x42, 0x5b, 0x6e, 0x33, 0x95, 0xf7, 0xe5, 0x41, 0x0b,
+ 0xbb, 0xb9, 0x9f, 0xf9, 0x16, 0x85, 0x8f, 0x0e, 0xb8, 0xcf, 0x02, 0x89,
+ 0x4c, 0x64, 0x0e, 0x1a, 0x75, 0x48, 0x19, 0x5e, 0x4f, 0x53, 0x96, 0xe0,
+ 0x11, 0x3f, 0xda, 0xf0, 0x0f, 0xc1, 0x3d, 0x2b, 0x7e, 0x4b, 0xd8, 0x42,
+ 0x13, 0x3a, 0xb3, 0x2a, 0x2d, 0xd5, 0x4a, 0x4d, 0x4c, 0x72, 0x46, 0x7a,
+ 0x4a, 0x78, 0x13, 0x27, 0x54, 0xc9, 0x11, 0x9c, 0x52, 0x56, 0x0a, 0x7c,
+ 0x25, 0x05, 0x8e, 0xbd, 0x6b, 0x55, 0x2e, 0x12, 0xca, 0x29, 0x3b, 0x50,
+ 0x01, 0x3a, 0xa9, 0x60, 0x0f, 0x45, 0xe9, 0x84, 0x69, 0xb0, 0x32, 0x01,
+ 0x61, 0x9e, 0x81, 0x3d, 0x13, 0x81, 0x99, 0xb1, 0x18, 0xf1, 0xc4, 0xa5,
+ 0x90, 0x48, 0x2c, 0x76, 0xe9, 0xd6, 0xe2, 0x46, 0x54, 0x16, 0x0b, 0x78,
+ 0x6f, 0x57, 0x64, 0x68, 0x90, 0x1d, 0xae, 0x15, 0x2d, 0x98, 0x9c, 0xea,
+ 0x47, 0x13, 0x2a, 0x1d, 0xe8, 0x4c, 0xa6, 0x06, 0x09, 0xb1, 0x25, 0x10,
+ 0xca, 0x49, 0x06, 0x24, 0xca, 0x97, 0x90, 0x0e, 0x19, 0x85, 0x10, 0xe2,
+ 0xdc, 0x07, 0xb6, 0xb0, 0xf1, 0xab, 0x51, 0x16, 0x2c, 0x4c, 0x72, 0xb4,
+ 0x06, 0x38, 0x12, 0x71, 0xa6, 0x34, 0x25, 0xb0, 0x4c, 0xab, 0x21, 0xcd,
+ 0x64, 0x3e, 0xa3, 0x8b, 0x26, 0xe8, 0x25, 0x4b, 0x6c, 0x34, 0xd5, 0x64,
+ 0x12, 0x34, 0xc0, 0x89, 0x15, 0x45, 0x2f, 0xca, 0xa8, 0x88, 0xf3, 0xfe,
+ 0xae, 0xe8, 0x05, 0xda, 0xed, 0x82, 0x13, 0x73, 0x9a, 0x80, 0x88, 0xd6,
+ 0x41, 0x2e, 0x72, 0xed, 0x41, 0x7d, 0xcf, 0x4a, 0xa4, 0x71, 0x22, 0x99,
+ 0x8e, 0x45, 0xf1, 0x4a, 0x37, 0x77, 0xda, 0xd3, 0xd9, 0x86, 0x06, 0x91,
+ 0xb5, 0x08, 0xe4, 0x4e, 0x24, 0x32, 0xc7, 0x18, 0xdc, 0xa0, 0x81, 0xee,
+ 0x20, 0x4a, 0x77, 0xf5, 0x3a, 0x67, 0x60, 0x84, 0x93, 0x93, 0x78, 0x3d,
+ 0xa1, 0x3f, 0x66, 0x8b, 0x88, 0x7d, 0x46, 0x52, 0x1b, 0x1c, 0x00, 0x85,
+ 0x05, 0x96, 0xe2, 0x94, 0xbc, 0x22, 0xb2, 0x13, 0x2e, 0x78, 0x46, 0x4f,
+ 0x8e, 0xd8, 0x97, 0x4a, 0xc0, 0x70, 0x3e, 0xa0, 0x70, 0x23, 0x20, 0x2e,
+ 0xd2, 0x02, 0x6a, 0x6a, 0x40, 0xb7, 0x00, 0x96, 0x11, 0x07, 0x47, 0xd2,
+ 0xa0, 0x11, 0xa5, 0xb0, 0xb2, 0x2e, 0x70, 0x83, 0x90, 0xf3, 0x68, 0x66,
+ 0x9e, 0xf2, 0x17, 0x18, 0x88, 0x74, 0xe5, 0x36, 0x46, 0xf1, 0x0b, 0x0f,
+ 0x87, 0x54, 0x08, 0x8b, 0xac, 0xc5, 0x59, 0x18, 0x42, 0x8b, 0x6d, 0xf6,
+ 0x12, 0x0b, 0x75, 0x38, 0x8b, 0x5c, 0xbb, 0x9a, 0x67, 0x06, 0xee, 0xf1,
+ 0x07, 0x27, 0x1a, 0x40, 0x00, 0xd7, 0x53, 0x4a, 0x5f, 0xe0, 0xb5, 0x1f,
+ 0x04, 0x36, 0xcf, 0xab, 0x58, 0xba, 0x86, 0x04, 0x8e, 0x21, 0xb0, 0xc9,
+ 0x42, 0xa9, 0x16, 0x5a, 0x2d, 0xe3, 0x51, 0x81, 0x92, 0xba, 0x81, 0x16,
+ 0xc3, 0x62, 0x03, 0x0d, 0x82, 0x00, 0x96, 0xa7, 0x8d, 0x38, 0x01, 0x51,
+ 0x97, 0x61, 0x9a, 0x4b, 0x2e, 0x50, 0xd5, 0x26, 0x63, 0xcc, 0xe4, 0x04,
+ 0xd1, 0xda, 0x86, 0x29, 0xd8, 0x32, 0x91, 0x74, 0xc4, 0x66, 0x20, 0x88,
+ 0x78, 0xd3, 0xb2, 0xa8, 0x45, 0xd8, 0xc9, 0xf9, 0xa3, 0x0d, 0xb4, 0xfa,
+ 0x64, 0x0a, 0xe6, 0x54, 0x82, 0xdf, 0x70, 0x83, 0x42, 0x1a, 0x98, 0x90,
+ 0x6d, 0x53, 0xfe, 0xc0, 0x87, 0x4b, 0xc4, 0x90, 0x1f, 0x95, 0x6c, 0x69,
+ 0x49, 0x18, 0x92, 0x03, 0xb5, 0xf0, 0x49, 0xa6, 0x42, 0x60, 0x43, 0x32,
+ 0x40, 0x65, 0x83, 0x53, 0x72, 0x63, 0x09, 0x56, 0x3a, 0x1e, 0xc1, 0x9c,
+ 0x67, 0x81, 0xd7, 0x75, 0x0d, 0x27, 0x60, 0x75, 0xd8, 0x4e, 0x5a, 0x43,
+ 0x53, 0xcf, 0x20, 0xac, 0xba, 0x56, 0x50, 0xd6, 0x0f, 0x91, 0xfa, 0x8a,
+ 0x17, 0x7c, 0x63, 0x0a, 0x50, 0xf8, 0xa2, 0x14, 0x9e, 0x32, 0xc5, 0x0b,
+ 0x4c, 0x02, 0x11, 0x82, 0x58, 0x94, 0xc9, 0x3e, 0x3a, 0xc8, 0x4e, 0xa9,
+ 0x63, 0x0a, 0x9b, 0x14, 0x9a, 0x29, 0xc8, 0xeb, 0xb3, 0xd9, 0x5a, 0xea,
+ 0x5c, 0x0e, 0x54, 0x2e, 0x3d, 0xd4, 0x12, 0x07, 0x55, 0xed, 0xb1, 0x43,
+ 0x18, 0x12, 0x40, 0x51, 0x08, 0x61, 0x86, 0x67, 0x89, 0xca, 0x0f, 0x70,
+ 0xc8, 0xe1, 0x88, 0x7a, 0xb9, 0x0d, 0x47, 0xf6, 0x48, 0x13, 0xbb, 0xcc,
+ 0x0a, 0x65, 0x81, 0x23, 0x37, 0x5a, 0x75, 0xa3, 0x33, 0xc2, 0x99, 0x8f,
+ 0x52, 0x8e, 0x13, 0xbc, 0x0e, 0x58, 0x71, 0x54, 0x4e, 0x72, 0xa5, 0x8b,
+ 0x49, 0xb3, 0xc0, 0xf8, 0x20, 0x01, 0x8d, 0x7d, 0x45, 0x2a, 0x7e, 0x8f,
+ 0x47, 0xb5, 0x32, 0xe2, 0x17, 0x16, 0x55, 0xa4, 0x82, 0xee, 0x1e, 0x61,
+ 0x97, 0xb9, 0xb4, 0xe3, 0x65, 0x5f, 0xd3, 0x15, 0x89, 0xcc, 0x3a, 0x95,
+ 0x1f, 0x85, 0xe4, 0x2d, 0x92, 0x60, 0x2b, 0x21, 0x21, 0xe9, 0x15, 0xb2,
+ 0x66, 0xb3, 0x1d, 0xc4, 0x69, 0x2f, 0x60, 0xd6, 0x60, 0xce, 0xc5, 0x2d,
+ 0x6b, 0x25, 0xca, 0x61, 0x27, 0x1d, 0xde, 0x51, 0x48, 0xde, 0xca, 0x23,
+ 0xb7, 0x24, 0x52, 0x4a, 0x53, 0x7a, 0x31, 0x1e, 0x15, 0x1b, 0xc4, 0xbe,
+ 0x4e, 0x05, 0x89, 0x98, 0x92, 0x20, 0xd4, 0xfc, 0xd2, 0xed, 0x3c, 0xe1,
+ 0x40, 0x05, 0x31, 0xfe, 0x71, 0xfe, 0x92, 0x02, 0xc4, 0x27, 0x5e, 0x7b,
+ 0x2e, 0x66, 0xb5, 0x46, 0xdb, 0xa1, 0xda, 0x4c, 0xd0, 0x8a, 0xa3, 0xcd,
+ 0xd2, 0xa1, 0x7f, 0xc9, 0x45, 0xab, 0x50, 0xe6, 0x38, 0x01, 0xd8, 0x8f,
+ 0x19, 0x66, 0xe6, 0x01, 0x70, 0x81, 0x4e, 0x0b, 0xff, 0x2d, 0xdd, 0x12,
+ 0x62, 0x28, 0xd7, 0xda, 0xe2, 0xa1, 0x15, 0x30, 0xe8, 0x66, 0x09, 0x62,
+ 0xac, 0x0d, 0x36, 0x95, 0x50, 0x3f, 0x7b, 0x2b, 0xef, 0x6c, 0x6d, 0x01,
+ 0xea, 0xfb, 0xd1, 0x49, 0x06, 0x39, 0x94, 0x5c, 0x73, 0xdc, 0xf6, 0xcc,
+ 0xc1, 0xcc, 0x69, 0x44, 0x1f, 0x38, 0x9d, 0x80, 0xd8, 0x28, 0x1a, 0x6a,
+ 0xa0, 0x60, 0x8e, 0x04, 0x81, 0xa3, 0x19, 0x21, 0x3b, 0xb7, 0x3d, 0xff,
+ 0x53, 0xbd, 0x71, 0xd9, 0x0c, 0x4d, 0x57, 0x40, 0xab, 0xef, 0x86, 0x03,
+ 0x61, 0x21, 0x94, 0xcf, 0x18, 0x8c, 0xe2, 0x3c, 0x4e, 0x21, 0xe0, 0x9e,
+ 0xc0, 0x28, 0x16, 0xb2, 0x26, 0xbb, 0x04, 0x0d, 0xdc, 0x27, 0x1d, 0xed,
+ 0xd8, 0x93, 0xfd, 0x2c, 0x75, 0x14, 0xcd, 0x75, 0xa7, 0xc4, 0x21, 0x45,
+ 0x37, 0x9c, 0x51, 0xf1, 0x64, 0xde, 0xda, 0x16, 0x5a, 0x85, 0x9c, 0x16,
+ 0x2f, 0x61, 0xaa, 0x2b, 0x1a, 0x9a, 0xa7, 0x10, 0x7b, 0x9a, 0x09, 0x3b,
+ 0x88, 0xa6, 0xac, 0x3a, 0x68, 0xb3, 0x67, 0x8d, 0x73, 0x86, 0x81, 0x1e,
+ 0xed, 0xc3, 0x95, 0xbc, 0xb8, 0x05, 0x1a, 0x74, 0xc2, 0x77, 0xe7, 0xe0,
+ 0x2a, 0x93, 0x65, 0xe6, 0x00, 0x01, 0xc0, 0x49, 0x9a, 0x48, 0x02, 0x13,
+ 0xf4, 0x6e, 0x30, 0x28, 0x10, 0xcf, 0x05, 0xa5, 0x13, 0xc1, 0xa9, 0xea,
+ 0xfe, 0xb8, 0x36, 0x19, 0x11, 0x1b, 0xdc, 0x44, 0xd0, 0x55, 0x1f, 0xd4,
+ 0xb2, 0x33, 0xaa, 0x90, 0x53, 0x27, 0xcc, 0x20, 0xaa, 0xd7, 0x61, 0x83,
+ 0xb0, 0x0c, 0x5e, 0x07, 0x81, 0x77, 0x63, 0x60, 0xfe, 0x49, 0xd8, 0x29,
+ 0x21, 0xb0, 0xf1, 0x0a, 0x5c, 0xf7, 0x36, 0x91, 0xd8, 0x98, 0xab, 0x5a,
+ 0x80, 0x79, 0x84, 0xf7, 0xce, 0xf9, 0xae, 0x80, 0xe8, 0x84, 0xe7, 0x6d,
+ 0x30, 0x83, 0x97, 0x9f, 0xc5, 0x88, 0x32, 0xe9, 0xf3, 0x33, 0x9c, 0x92,
+ 0x45, 0x00, 0xe7, 0x73, 0xec, 0x8f, 0xf0, 0xd9, 0x09, 0x93, 0xdd, 0xf1,
+ 0xc4, 0xb6, 0xb6, 0xcf, 0xcf, 0xac, 0x40, 0xd9, 0x46, 0x80, 0x8c, 0x8d,
+ 0x5d, 0xf4, 0x04, 0x16, 0xa8, 0xc7, 0xc5, 0x7f, 0x52, 0x92, 0xf3, 0x58,
+ 0x03, 0xc6, 0xfa, 0x7a, 0xb2, 0x46, 0xda, 0x41, 0xc7, 0x84, 0x2a, 0xbc,
+ 0x66, 0x46, 0x2d, 0xa4, 0x71, 0xb1, 0x3d, 0xa9, 0xb9, 0x11, 0x5d, 0x5e,
+ 0xc4, 0xfd, 0x60, 0x1f, 0x89, 0x78, 0x90, 0x0b, 0x82, 0xb6, 0x1b, 0x84,
+ 0xe3, 0x03, 0x71, 0x3b, 0x8c, 0x21, 0x5a, 0xea, 0xc1, 0x16, 0x0d, 0x33,
+ 0x24, 0x99, 0xea, 0xab, 0x6e, 0x21, 0x9f, 0x52, 0x51, 0x6b, 0x8f, 0xfc,
+ 0x38, 0x87, 0xb6, 0xf1, 0x04, 0x43, 0x97, 0x98, 0x3e, 0x64, 0x36, 0x6d,
+ 0xf6, 0xd4, 0x76, 0x1f, 0xc6, 0xf2, 0x22, 0x38, 0x88, 0x26, 0xbd, 0x1e,
+ 0x7b, 0x42, 0x91, 0x8c, 0x7a, 0x13, 0x0c, 0x64, 0x8c, 0x56, 0x04, 0x30,
+ 0x50, 0xcd, 0x48, 0x2c, 0xdf, 0x99, 0x64, 0x84, 0x64, 0x4b, 0x02, 0x3c,
+ 0xad, 0x7c, 0x96, 0x93, 0x1a, 0x78, 0xd8, 0xa3, 0xe3, 0xa0, 0xeb, 0x3c,
+ 0xe1, 0x43, 0x82, 0x8a, 0x68, 0xab, 0x90, 0x51, 0x59, 0x10, 0x16, 0xa2,
+ 0x62, 0x9b, 0xc1, 0x48, 0xbd, 0x41, 0x84, 0xf2, 0x89, 0x7f, 0x6d, 0xd8,
+ 0x01, 0xdf, 0x94, 0x88, 0x3d, 0x1e, 0x78, 0x41, 0x0b, 0x32, 0x54, 0xcc,
+ 0xf6, 0xe4, 0xb5, 0xd3, 0x32, 0xe5, 0x22, 0xb7, 0x83, 0x92, 0x75, 0x92,
+ 0x7d, 0x55, 0xed, 0x70, 0x43, 0x03, 0x68, 0xf2, 0x29, 0x14, 0x5a, 0xfe,
+ 0x75, 0x90, 0xb2, 0xd1, 0x46, 0x95, 0x56, 0x81, 0x1f, 0xb2, 0x57, 0x14,
+ 0xca, 0xd8, 0x50, 0xa0, 0x58, 0x9a, 0xb5, 0x1e, 0x1f, 0xe1, 0x58, 0x90,
+ 0x21, 0x77, 0x61, 0x50, 0x53, 0x52, 0xa0, 0x1c, 0x8c, 0x73, 0x32, 0xba,
+ 0x51, 0x48, 0x29, 0x47, 0x18, 0x15, 0xd2, 0x42, 0x36, 0xb2, 0x38, 0xdb,
+ 0x37, 0x0e, 0x73, 0xc0, 0x66, 0xbd, 0x61, 0x27, 0x37, 0xe1, 0x07, 0x2a,
+ 0x10, 0x15, 0x85, 0xd4, 0x68, 0x62, 0xd1, 0x20, 0x31, 0x60, 0x0f, 0x6d,
+ 0xc1, 0x13, 0xe8, 0x10, 0x43, 0xa6, 0xb0, 0x2e, 0x95, 0x40, 0x7e, 0xff,
+ 0xc0, 0x39, 0xc2, 0x42, 0x41, 0x9e, 0xa2, 0x6c, 0x3a, 0x70, 0x47, 0xfb,
+ 0x05, 0x14, 0x02, 0x30, 0x42, 0x5e, 0xd5, 0x35, 0xc4, 0x32, 0x30, 0xe5,
+ 0x01, 0x71, 0x13, 0xe0, 0x7a, 0xca, 0x33, 0x7a, 0x44, 0xa0, 0x36, 0x35,
+ 0xa0, 0x55, 0x32, 0x84, 0x1b, 0xfb, 0x55, 0x5a, 0x44, 0xa5, 0x67, 0x53,
+ 0xf5, 0x7b, 0x19, 0x31, 0x02, 0x6d, 0xd3, 0x1f, 0xd8, 0xb0, 0x0d, 0x4c,
+ 0xa4, 0x07, 0xec, 0xa0, 0x0e, 0xd3, 0x37, 0x34, 0xcf, 0xd5, 0x17, 0x75,
+ 0xd2, 0x4b, 0xe9, 0x54, 0x5c, 0x3d, 0x82, 0x4e, 0x32, 0xb7, 0x1e, 0x13,
+ 0x42, 0x5c, 0x7c, 0x56, 0x5c, 0x49, 0x98, 0x30, 0xb0, 0xa4, 0x2d, 0x87,
+ 0xb2, 0x0f, 0xe2, 0x52, 0x08, 0x3b, 0xa3, 0x06, 0xe9, 0xd3, 0x16, 0x61,
+ 0x90, 0x6b, 0x7c, 0xc0, 0x2b, 0x82, 0x51, 0x7e, 0x16, 0x93, 0x45, 0x59,
+ 0x92, 0x1a, 0xa5, 0xc1, 0x46, 0x20, 0x41, 0x2a, 0xae, 0xe4, 0x3a, 0x18,
+ 0xa4, 0x24, 0xc2, 0x11, 0x40, 0x56, 0xc0, 0x04, 0xb9, 0x52, 0x1b, 0x16,
+ 0xb3, 0x7e, 0x68, 0xc2, 0x30, 0xc7, 0x36, 0x38, 0x06, 0xe7, 0x0b, 0x29,
+ 0x01, 0x37, 0xd3, 0xd3, 0x46, 0x09, 0xe5, 0x7f, 0x8c, 0x01, 0x1d, 0xd2,
+ 0x00, 0x2d, 0xfe, 0x7b, 0xa0, 0x61, 0x31, 0x82, 0x4d, 0xf6, 0xe6, 0x7a,
+ 0xa3, 0x93, 0x48, 0x9c, 0xf7, 0x09, 0xa9, 0xb6, 0x04, 0xc7, 0xd5, 0x0f,
+ 0x88, 0x40, 0x04, 0x84, 0x80, 0x4d, 0xec, 0x36, 0x70, 0x23, 0x46, 0x27,
+ 0xbb, 0x51, 0x0d, 0x5d, 0x60, 0x10, 0x3d, 0x13, 0x2f, 0x12, 0xa4, 0x48,
+ 0xf0, 0xa1, 0x53, 0x93, 0x84, 0x77, 0x70, 0xf0, 0x58, 0x5e, 0x50, 0x8c,
+ 0x5d, 0x32, 0x2a, 0x2e, 0x91, 0x55, 0x5a, 0xa5, 0x7f, 0x71, 0xc4, 0x45,
+ 0xea, 0x15, 0x63, 0xa7, 0x77, 0x0c, 0x44, 0xe2, 0x24, 0xf9, 0xd4, 0x4b,
+ 0xe3, 0x11, 0x47, 0x54, 0x33, 0x38, 0x5f, 0xb0, 0x0c, 0x22, 0x57, 0x41,
+ 0x60, 0x37, 0x68, 0xb5, 0x42, 0x27, 0xca, 0xf2, 0x1a, 0x63, 0xa1, 0x3f,
+ 0xe0, 0xc7, 0x0a, 0x8b, 0x73, 0x74, 0x5c, 0x91, 0x87, 0x6d, 0xf7, 0x21,
+ 0x13, 0xb4, 0x17, 0x12, 0x68, 0x07, 0x1c, 0x85, 0x07, 0x6b, 0x48, 0x58,
+ 0xb8, 0xc5, 0x0e, 0x21, 0x32, 0x27, 0x38, 0xd2, 0x09, 0x7e, 0xe4, 0x8e,
+ 0xdc, 0x84, 0x21, 0x62, 0x91, 0x12, 0x8b, 0x27, 0x08, 0x2f, 0x03, 0x43,
+ 0xd8, 0xf2, 0x32, 0xbb, 0x16, 0x76, 0x05, 0xe3, 0x7e, 0xb3, 0xd2, 0x3c,
+ 0x95, 0x75, 0x73, 0x8b, 0x68, 0x0b, 0x37, 0x51, 0x5f, 0x41, 0xe5, 0x76,
+ 0x65, 0xc4, 0x01, 0x43, 0x72, 0x55, 0xa6, 0x40, 0x5a, 0x69, 0x34, 0x42,
+ 0xa6, 0x70, 0x25, 0x8b, 0x58, 0x13, 0xf4, 0x77, 0x25, 0x6a, 0x02, 0x80,
+ 0xe9, 0xf1, 0x45, 0xdb, 0x06, 0x3f, 0x9a, 0x23, 0x5a, 0xf3, 0x41, 0x0a,
+ 0xf7, 0xe3, 0x2d, 0x77, 0xf2, 0x69, 0xef, 0x63, 0x0e, 0x1d, 0x55, 0x6a,
+ 0xc9, 0x00, 0x4f, 0x39, 0xd0, 0x0b, 0xea, 0xf0, 0x03, 0x83, 0x48, 0x0f,
+ 0x93, 0x62, 0x29, 0xfa, 0xe3, 0x5f, 0x24, 0x44, 0x41, 0xf1, 0x28, 0x38,
+ 0x59, 0x26, 0x79, 0xf2, 0xf0, 0xfe, 0x02, 0x16, 0x33, 0x0d, 0xc6, 0x02,
+ 0x18, 0xb0, 0xa3, 0x04, 0x3a, 0x16, 0x3d, 0x7b, 0x55, 0x4c, 0x48, 0xe0,
+ 0x21, 0x13, 0x19, 0x12, 0xaf, 0x33, 0x89, 0x72, 0x14, 0x40, 0x74, 0xe2,
+ 0x74, 0x44, 0x30, 0x24, 0x99, 0x96, 0x20, 0x1b, 0x53, 0x0c, 0x85, 0xb8,
+ 0x0f, 0xd9, 0xe5, 0x0a, 0x40, 0xc5, 0x67, 0x36, 0x16, 0x1f, 0xee, 0xd1,
+ 0x71, 0xc5, 0x42, 0x8e, 0xcd, 0x13, 0x2f, 0xd2, 0x60, 0x3c, 0xf3, 0xc3,
+ 0x3e, 0xe3, 0x72, 0x22, 0xb1, 0x74, 0x93, 0x71, 0x80, 0x8a, 0xee, 0xf6,
+ 0x3a, 0xc6, 0xa1, 0x42, 0x6e, 0xa0, 0x8e, 0xda, 0x01, 0x0d, 0x3a, 0x65,
+ 0x8c, 0x9e, 0x56, 0x39, 0x33, 0x39, 0x6a, 0x25, 0x35, 0x27, 0xa6, 0xa6,
+ 0x56, 0x95, 0xd3, 0x16, 0xb5, 0x82, 0x29, 0x8f, 0xf7, 0x01, 0xa8, 0x10,
+ 0x3b, 0x00, 0xb5, 0x41, 0xac, 0xe3, 0x62, 0x22, 0xe3, 0x45, 0xa7, 0x12,
+ 0x71, 0x9d, 0x09, 0x2a, 0xdc, 0xd6, 0x0d, 0x5a, 0x15, 0x35, 0xe0, 0x66,
+ 0x6c, 0xc2, 0x13, 0x9a, 0x65, 0x32, 0x03, 0xd2, 0xb8, 0x95, 0x91, 0x15,
+ 0x1e, 0x05, 0xc5, 0x84, 0xf2, 0xd1, 0x31, 0xae, 0x36, 0x22, 0xdd, 0xa1,
+ 0x08, 0x73, 0x20, 0x86, 0xfe, 0x30, 0x78, 0x89, 0x44, 0x1b, 0x6b, 0x41,
+ 0x8b, 0x83, 0xb4, 0x07, 0xed, 0xf3, 0x73, 0x76, 0x38, 0x1b, 0xe8, 0xf6,
+ 0x0f, 0xea, 0xe6, 0x07, 0x60, 0xe1, 0x1b, 0x7e, 0x79, 0x6f, 0xe1, 0xc2,
+ 0x49, 0x37, 0x57, 0x4b, 0x93, 0xd2, 0x49, 0x05, 0x01, 0x62, 0xd9, 0xc4,
+ 0x3a, 0xcf, 0x13, 0x13, 0x5e, 0x40, 0x67, 0xfd, 0xd1, 0x53, 0x0d, 0x07,
+ 0x14, 0xbd, 0xb0, 0x75, 0x7a, 0x72, 0x67, 0x23, 0x84, 0x66, 0x51, 0x90,
+ 0x34, 0x69, 0x03, 0x06, 0x55, 0xd0, 0x9d, 0x9d, 0xa9, 0x63, 0x6f, 0x90,
+ 0x19, 0xea, 0xe3, 0x5d, 0x01, 0x94, 0x20, 0x71, 0xfe, 0x44, 0x50, 0xa3,
+ 0x23, 0x04, 0xe5, 0xa2, 0x09, 0x87, 0x19, 0x7e, 0x01, 0x19, 0x08, 0x79,
+ 0x07, 0x17, 0x74, 0x68, 0x0a, 0x54, 0x26, 0x0a, 0x8a, 0xf0, 0x43, 0x6a,
+ 0xa8, 0x17, 0x97, 0x10, 0x05, 0x6c, 0xf7, 0x06, 0x5e, 0x31, 0x73, 0x43,
+ 0xc7, 0x77, 0x39, 0xd7, 0x22, 0x67, 0xc6, 0x07, 0xe3, 0x79, 0x7e, 0x1e,
+ 0x53, 0x14, 0x4b, 0x01, 0x17, 0x35, 0xa0, 0x4a, 0x8f, 0x05, 0x9b, 0x62,
+ 0x03, 0x92, 0x4b, 0xa8, 0x76, 0x53, 0x32, 0x03, 0xbf, 0x80, 0x4f, 0xb6,
+ 0x30, 0x5a, 0xc1, 0x23, 0x1f, 0x9a, 0xc9, 0x90, 0xd4, 0x58, 0x19, 0x47,
+ 0xd5, 0x30, 0xfc, 0xc4, 0x62, 0x61, 0xf7, 0x24, 0x04, 0x35, 0x9a, 0x40,
+ 0x06, 0x59, 0x26, 0x85, 0x51, 0x06, 0x21, 0x11, 0x86, 0x30, 0x66, 0xc3,
+ 0xc7, 0x1d, 0xca, 0x98, 0x36, 0x80, 0x47, 0x57, 0x3a, 0x1a, 0x2f, 0xcd,
+ 0x07, 0x34, 0xf3, 0xf8, 0x6a, 0xdb, 0x63, 0x94, 0x12, 0xc1, 0x2b, 0x6d,
+ 0xa1, 0x2d, 0x7f, 0xa7, 0x38, 0x32, 0x24, 0x78, 0x3a, 0x2a, 0xa4, 0x1f,
+ 0x03, 0x11, 0x16, 0x40, 0x16, 0x2c, 0x47, 0x03, 0xd1, 0xf1, 0x4b, 0x1f,
+ 0x11, 0x11, 0x28, 0xc1, 0x7e, 0x0d, 0x59, 0x5e, 0x35, 0x90, 0x12, 0x56,
+ 0xf3, 0x72, 0x90, 0x25, 0x2b, 0xf3, 0xf5, 0x06, 0x3b, 0xf0, 0x79, 0x67,
+ 0x83, 0x96, 0x21, 0x5a, 0x0c, 0xbf, 0x50, 0x09, 0xea, 0x65, 0xa2, 0xdd,
+ 0xc0, 0x37, 0xc2, 0xe3, 0x38, 0x16, 0xea, 0x0d, 0x30, 0x29, 0x57, 0x24,
+ 0x85, 0x8e, 0x06, 0xc7, 0x9f, 0x1c, 0x71, 0x32, 0xf7, 0x93, 0x2a, 0x73,
+ 0x72, 0x5c, 0x5a, 0x31, 0x65, 0xab, 0x37, 0x18, 0xfe, 0x88, 0x05, 0x7f,
+ 0xa2, 0x9c, 0x35, 0xe5, 0xa3, 0xdf, 0x24, 0x82, 0x77, 0xa2, 0x7c, 0x92,
+ 0xa0, 0x03, 0xf4, 0x60, 0x1e, 0xaa, 0x06, 0x7d, 0x95, 0x52, 0x23, 0xfe,
+ 0x18, 0x43, 0x88, 0x28, 0xa0, 0x55, 0x95, 0xe1, 0xa2, 0x8f, 0xb1, 0xa6,
+ 0xce, 0x98, 0x36, 0x3a, 0xb8, 0x40, 0xc1, 0xd0, 0x83, 0x09, 0x62, 0xa1,
+ 0xc5, 0xe2, 0x18, 0x35, 0x16, 0x4b, 0xef, 0x57, 0x30, 0x99, 0xf6, 0x45,
+ 0xf3, 0x57, 0x30, 0x0c, 0x82, 0x64, 0xb5, 0x32, 0x8d, 0x24, 0xd1, 0x5e,
+ 0x8a, 0x83, 0x2a, 0x11, 0x86, 0x51, 0x93, 0xb0, 0x8e, 0x7a, 0xe2, 0x2c,
+ 0x83, 0x91, 0x98, 0x19, 0x90, 0x83, 0x60, 0x58, 0xa9, 0xe8, 0x28, 0x1b,
+ 0x79, 0x20, 0x8a, 0x76, 0x02, 0x7e, 0xf0, 0x61, 0x03, 0x5d, 0x91, 0x79,
+ 0xe3, 0xd4, 0x16, 0x3e, 0x21, 0x8f, 0x91, 0x37, 0x4b, 0x03, 0xa7, 0x6f,
+ 0xba, 0x65, 0x5b, 0x88, 0x94, 0x57, 0x14, 0xf1, 0x77, 0x5d, 0x79, 0x72,
+ 0x83, 0x98, 0x42, 0x25, 0x01, 0x19, 0xa5, 0xc0, 0x62, 0x0b, 0x46, 0x63,
+ 0x58, 0x34, 0x4f, 0x99, 0x15, 0x25, 0xfc, 0x74, 0xa2, 0xe5, 0x95, 0x0c,
+ 0x00, 0x63, 0x21, 0xd2, 0x13, 0x11, 0x1a, 0x64, 0x5f, 0x1d, 0xd2, 0x84,
+ 0x19, 0xf2, 0x1f, 0x1b, 0xe0, 0x7a, 0x4d, 0x06, 0x30, 0x87, 0x93, 0x01,
+ 0xa0, 0x50, 0xac, 0x75, 0xc5, 0x0b, 0x82, 0x53, 0x6a, 0x83, 0xb4, 0x09,
+ 0xa6, 0x08, 0xa0, 0x66, 0x90, 0x8a, 0x91, 0x62, 0x7b, 0x50, 0x51, 0x03,
+ 0x96, 0x32, 0xaf, 0xe4, 0xe6, 0x0a, 0x54, 0xd7, 0x69, 0x3f, 0x20, 0x57,
+ 0xa7, 0xc1, 0x1b, 0xf2, 0x66, 0x95, 0xcd, 0xd7, 0x28, 0x6c, 0x06, 0x16,
+ 0x3e, 0x73, 0x2a, 0x72, 0x0a, 0x47, 0x48, 0xe6, 0x7b, 0x94, 0x25, 0x88,
+ 0x18, 0x49, 0x69, 0x46, 0xe8, 0x27, 0x9e, 0x81, 0x46, 0xcb, 0xb6, 0x3b,
+ 0x89, 0xa8, 0x4b, 0xac, 0x8a, 0xaa, 0x45, 0xf1, 0x6d, 0xab, 0x05, 0x40,
+ 0x22, 0xa3, 0x31, 0xc8, 0x80, 0x19, 0xd8, 0xd0, 0xb3, 0xd6, 0xe0, 0x08,
+ 0x4e, 0x02, 0xfe, 0x0d, 0x61, 0x12, 0x00, 0x01, 0xa2, 0x14, 0xb2, 0x41,
+ 0x21, 0x5c, 0xd6, 0x48, 0x1d, 0xa2, 0x04, 0xfc, 0x48, 0x65, 0xd2, 0xf2,
+ 0x15, 0x64, 0x91, 0x4e, 0x0f, 0xc2, 0x7a, 0x4c, 0x40, 0x1c, 0xdb, 0xf1,
+ 0x56, 0x50, 0x66, 0x2c, 0x09, 0x38, 0x06, 0xfb, 0xf0, 0x60, 0x12, 0xea,
+ 0x04, 0xbd, 0xf4, 0x07, 0x77, 0xa1, 0x38, 0x90, 0x57, 0x23, 0xb9, 0x55,
+ 0x48, 0xe4, 0xc3, 0x6e, 0x67, 0x64, 0x0b, 0x62, 0xda, 0x14, 0x43, 0x32,
+ 0x27, 0x09, 0x84, 0x10, 0x2e, 0x60, 0x10, 0x43, 0xa9, 0xa1, 0x96, 0x47,
+ 0x7e, 0x0e, 0x33, 0x5c, 0x60, 0xb7, 0x12, 0x5f, 0x53, 0x0b, 0x58, 0x40,
+ 0x04, 0x68, 0x94, 0x45, 0x40, 0xd5, 0x03, 0x01, 0x20, 0x5e, 0x1a, 0x17,
+ 0x85, 0x7b, 0x00, 0x14, 0xaa, 0xf2, 0x94, 0x5a, 0xb2, 0x27, 0x65, 0x51,
+ 0x61, 0xbd, 0xc2, 0x07, 0x75, 0xc5, 0x1b, 0x4e, 0xe2, 0x02, 0x3c, 0x31,
+ 0x6d, 0x3e, 0x86, 0x07, 0xaa, 0x20, 0x23, 0x4f, 0x14, 0x60, 0xdd, 0xd7,
+ 0x69, 0x8d, 0x84, 0x0a, 0x2f, 0x61, 0x7b, 0x02, 0x8a, 0x9f, 0x08, 0xf0,
+ 0x21, 0x62, 0xa1, 0x39, 0x87, 0x53, 0x5b, 0x1e, 0x43, 0x07, 0x91, 0x37,
+ 0x07, 0xf4, 0x16, 0xba, 0xd6, 0x2a, 0x2e, 0x45, 0x10, 0x10, 0x42, 0xa0,
+ 0x05, 0x18, 0x97, 0xb5, 0x6f, 0x54, 0x1f, 0xdb, 0x80, 0xb1, 0x3d, 0xe1,
+ 0x88, 0xa3, 0x73, 0x10, 0xa2, 0x91, 0x46, 0xd6, 0x39, 0x03, 0xaa, 0x49,
+ 0x96, 0xae, 0x63, 0x26, 0x66, 0x73, 0x26, 0x59, 0xb7, 0x88, 0x69, 0xb0,
+ 0x40, 0xdf, 0x06, 0x1a, 0xb8, 0x87, 0x5a, 0xa5, 0xb5, 0xb2, 0xc1, 0x2a,
+ 0x34, 0x80, 0xb1, 0xaf, 0x15, 0xeb, 0x0f, 0x93, 0x32, 0x35, 0x14, 0x12,
+ 0x06, 0x59, 0xe6, 0x1b, 0xb7, 0xf6, 0x32, 0x34, 0x92, 0x93, 0x98, 0xb2,
+ 0x38, 0x6f, 0xc2, 0x0f, 0x39, 0xfe, 0x43, 0x27, 0x15, 0x81, 0x08, 0x66,
+ 0xe5, 0x07, 0x52, 0x70, 0x43, 0x03, 0x21, 0x18, 0x39, 0x91, 0x9d, 0xcf,
+ 0x24, 0x7c, 0xf6, 0x26, 0x04, 0xcd, 0x90, 0x04, 0x8e, 0x16, 0x4c, 0x55,
+ 0x09, 0x2d, 0xba, 0xe0, 0x53, 0x41, 0x50, 0x1f, 0xd3, 0x33, 0x59, 0x04,
+ 0xd1, 0x6c, 0x86, 0xc2, 0x06, 0xa1, 0x4a, 0x62, 0xdf, 0xf9, 0x5d, 0x43,
+ 0x31, 0x4b, 0x7d, 0x30, 0x12, 0x2f, 0x31, 0x91, 0xa2, 0x61, 0x5f, 0xe5,
+ 0x7a, 0x20, 0x95, 0x65, 0x6d, 0x37, 0x11, 0x1a, 0xdf, 0x13, 0x22, 0x60,
+ 0xa1, 0x3b, 0x22, 0x35, 0x1b, 0xe3, 0xd2, 0x52, 0x19, 0xc2, 0x71, 0x52,
+ 0xa0, 0x02, 0x5c, 0xfa, 0x1b, 0xd4, 0x32, 0x70, 0xe8, 0xf5, 0x26, 0xe3,
+ 0xcb, 0x2d, 0xe3, 0xb7, 0x28, 0x62, 0xd0, 0x78, 0x03, 0x61, 0x11, 0x68,
+ 0xe3, 0x6b, 0x20, 0xb0, 0x8f, 0x7b, 0x31, 0x22, 0xe4, 0xb5, 0xbd, 0xe6,
+ 0x91, 0x43, 0xe6, 0xc0, 0x35, 0x13, 0xe0, 0x2e, 0x12, 0x0c, 0x91, 0x29,
+ 0x0a, 0x50, 0xab, 0x75, 0x04, 0x59, 0x08, 0x56, 0xd8, 0xdb, 0x58, 0xc0,
+ 0x83, 0x40, 0xb2, 0x73, 0x91, 0xc7, 0xf4, 0xa9, 0xfe, 0x82, 0x0b, 0xf2,
+ 0x27, 0x7b, 0xdc, 0x06, 0x7c, 0xbc, 0x3b, 0xc1, 0x63, 0x62, 0x24, 0xf5,
+ 0x35, 0x05, 0x98, 0x13, 0x53, 0xc3, 0x89, 0x9b, 0x7e, 0xa0, 0x9b, 0x7b,
+ 0x01, 0x8b, 0xd6, 0xaa, 0xbf, 0x8c, 0xf0, 0x16, 0x00, 0xea, 0x49, 0xcc,
+ 0x15, 0x49, 0xa0, 0x93, 0x5c, 0x89, 0xc0, 0x5b, 0x3d, 0x7c, 0x8f, 0xd0,
+ 0x32, 0x1e, 0x31, 0x13, 0x49, 0x71, 0x20, 0x44, 0x18, 0xc5, 0x3f, 0x26,
+ 0xe8, 0x21, 0x00, 0x21, 0x3d, 0x2e, 0xb0, 0x4d, 0x07, 0x8c, 0x03, 0xdb,
+ 0xb9, 0x3f, 0x16, 0x34, 0x02, 0xa4, 0x80, 0x21, 0xa2, 0x25, 0x0c, 0xa3,
+ 0xd2, 0x76, 0xf6, 0x45, 0x58, 0xd0, 0xe0, 0x58, 0xfe, 0x63, 0x20, 0x96,
+ 0x3e, 0x51, 0x76, 0x24, 0xd7, 0x1f, 0x73, 0xc7, 0x2b, 0x9a, 0x13, 0x4a,
+ 0xb0, 0x92, 0x08, 0xbe, 0xe4, 0xa6, 0x28, 0x11, 0x48, 0x9a, 0x02, 0x61,
+ 0xea, 0xc6, 0x81, 0x7a, 0xa0, 0x9c, 0xd9, 0xa2, 0x6e, 0xb2, 0x85, 0x60,
+ 0x1d, 0xe5, 0x92, 0x78, 0x30, 0x02, 0xd0, 0x65, 0x49, 0x00, 0x09, 0x8a,
+ 0x89, 0x52, 0x2f, 0xd6, 0x91, 0x13, 0xde, 0xd2, 0x61, 0x35, 0x90, 0x43,
+ 0xa3, 0xd5, 0x1d, 0xab, 0xbb, 0x42, 0x39, 0xfa, 0x49, 0x9d, 0x86, 0x15,
+ 0x2a, 0x24, 0x03, 0x78, 0x56, 0x50, 0xca, 0x40, 0xa2, 0x94, 0xf1, 0xa1,
+ 0xd7, 0xc0, 0x6d, 0x43, 0x32, 0x30, 0xa7, 0x87, 0xb2, 0x6a, 0xf2, 0x11,
+ 0xcd, 0x20, 0x47, 0x11, 0x29, 0xb3, 0x6a, 0xc2, 0xa2, 0xff, 0x12, 0x6e,
+ 0xd2, 0x70, 0x73, 0x5c, 0x12, 0x0d, 0x3b, 0xc6, 0x01, 0x01, 0xd0, 0x31,
+ 0xa4, 0x17, 0x77, 0x8c, 0xb4, 0x2b, 0xe4, 0xa2, 0x43, 0x82, 0xf3, 0xa8,
+ 0x4c, 0xb1, 0x80, 0x56, 0xc9, 0x11, 0x91, 0x62, 0x09, 0xb6, 0x46, 0x21,
+ 0x54, 0x11, 0x22, 0x69, 0x20, 0x10, 0x17, 0x42, 0x2f, 0x46, 0x41, 0x43,
+ 0x9f, 0x44, 0x42, 0x25, 0x88, 0x5f, 0x89, 0x44, 0xb8, 0xc3, 0xe9, 0xb5,
+ 0x8a, 0xa0, 0x0e, 0x40, 0xa0, 0x2d, 0x1e, 0xb8, 0x09, 0x18, 0x39, 0x1f,
+ 0x0d, 0x42, 0x0b, 0x9f, 0xe2, 0xa5, 0x53, 0xe2, 0x75, 0xe4, 0xb0, 0x57,
+ 0x73, 0xf7, 0x3d, 0x2b, 0x50, 0x19, 0x01, 0x2c, 0xcd, 0x85, 0x4b, 0x0d,
+ 0x0b, 0x16, 0x76, 0x96, 0x10, 0x02, 0x72, 0x43, 0x96, 0xec, 0x31, 0x14,
+ 0x43, 0x89, 0x96, 0x17, 0x69, 0x12, 0x17, 0x74, 0x20, 0x31, 0xc3, 0x6e,
+ 0xec, 0x56, 0x07, 0xfc, 0x4c, 0xbe, 0xe2, 0x17, 0x1b, 0x40, 0x73, 0x0a,
+ 0x0f, 0xab, 0x13, 0x64, 0x21, 0x6e, 0xd1, 0x92, 0x0e, 0x00, 0x6a, 0xfe,
+ 0x4e, 0x67, 0x65, 0x70, 0x49, 0xf4, 0xc6, 0x9d, 0x03, 0x95, 0xd9, 0x99,
+ 0x49, 0x34, 0x25, 0x2e, 0xae, 0x4c, 0x71, 0x0f, 0x66, 0x04, 0x05, 0xd1,
+ 0xa2, 0xf8, 0x20, 0xbf, 0x73, 0xd2, 0xd0, 0xb2, 0x41, 0x00, 0xe2, 0x57,
+ 0x24, 0x1a, 0x4a, 0x1c, 0xa9, 0x83, 0x4f, 0x0d, 0x43, 0xa7, 0x09, 0x6a,
+ 0x4f, 0xff, 0x32, 0x51, 0xf5, 0xe7, 0x4f, 0x8b, 0xe1, 0x2f, 0x2f, 0xd2,
+ 0x6a, 0xad, 0x72, 0x6d, 0x27, 0x81, 0x1c, 0x96, 0x72, 0x71, 0x40, 0x5b,
+ 0x77, 0x61, 0x94, 0xb2, 0xc8, 0x72, 0x08, 0x53, 0xcc, 0x1c, 0xc5, 0x92,
+ 0x14, 0x17, 0x04, 0x62, 0x21, 0x82, 0x70, 0xa8, 0x20, 0x8a, 0x66, 0xdc,
+ 0x48, 0x10, 0xd2, 0xb4, 0x30, 0x85, 0x27, 0x87, 0x07, 0x3a, 0xcd, 0x0a,
+ 0x8a, 0x86, 0x60, 0x82, 0xf2, 0x13, 0x0f, 0xe7, 0xf2, 0xd3, 0xdb, 0x5a,
+ 0x3a, 0xea, 0x21, 0x1b, 0xcb, 0x24, 0xbb, 0xe3, 0xb1, 0xd0, 0x82, 0x22,
+ 0x1e, 0xe8, 0x17, 0x3d, 0x15, 0xa0, 0x58, 0x81, 0xf4, 0x87, 0x60, 0xe0,
+ 0x3b, 0x31, 0xd6, 0xd9, 0xfa, 0xca, 0xc1, 0x8f, 0xb6, 0xae, 0x64, 0xfb,
+ 0xc1, 0x33, 0x41, 0xb2, 0x9b, 0xe0, 0x08, 0xb4, 0xa1, 0x26, 0xa0, 0x15,
+ 0xbb, 0xb6, 0x88, 0x8b, 0x12, 0xf3, 0x29, 0x19, 0x42, 0xaf, 0xe4, 0x65,
+ 0xa7, 0x10, 0x24, 0x43, 0x6a, 0x53, 0x29, 0x5b, 0x61, 0x0a, 0x8e, 0xd7,
+ 0x27, 0xa7, 0x82, 0xa5, 0x66, 0xc3, 0x59, 0x01, 0x37, 0x33, 0xd2, 0x70,
+ 0x1b, 0xfa, 0x98, 0x06, 0xd6, 0x95, 0x6b, 0xbd, 0xd4, 0x39, 0x85, 0x6d,
+ 0xb9, 0x53, 0x76, 0x0b, 0xb1, 0xb1, 0x10, 0x37, 0x50, 0x2e, 0x46, 0x21,
+ 0x06, 0x69, 0x71, 0x9c, 0xab, 0xe8, 0x3e, 0x35, 0xc5, 0x55, 0xfb, 0xe5,
+ 0x3d, 0xdb, 0x1c, 0x3a, 0xcd, 0x50, 0x24, 0x41, 0xd6, 0xd2, 0xd6, 0x69,
+ 0x59, 0x64, 0xfe, 0xcb, 0x3a, 0x17, 0x53, 0x51, 0x28, 0xed, 0x4a, 0x04,
+ 0x85, 0x50, 0x34, 0xd1, 0x31, 0x52, 0x62, 0x12, 0x3c, 0x21, 0xdf, 0xb8,
+ 0xba, 0x18, 0x55, 0xf0, 0x8b, 0xa7, 0xc2, 0x91, 0x3e, 0xa6, 0x0c, 0xc9,
+ 0xc5, 0x55, 0x3a, 0xd5, 0x78, 0x89, 0x32, 0x0f, 0xe9, 0xa1, 0x9c, 0x87,
+ 0xfc, 0x4a, 0xb9, 0x58, 0x87, 0x0a, 0x98, 0x93, 0x5b, 0xcb, 0x5c, 0x90,
+ 0x54, 0x1c, 0xd9, 0x44, 0x52, 0x30, 0xfc, 0x16, 0x43, 0x04, 0x70, 0x90,
+ 0x70, 0x9b, 0x8a, 0x80, 0xd8, 0xf0, 0x2d, 0x63, 0xa3, 0x78, 0x5c, 0x7c,
+ 0x40, 0x57, 0xb8, 0x23, 0x6b, 0xfb, 0x57, 0xbf, 0x6f, 0x88, 0x09, 0xe4,
+ 0xb5, 0x22, 0xd0, 0xb8, 0x60, 0x7c, 0x83, 0x72, 0xe9, 0x69, 0x55, 0x8e,
+ 0x96, 0x4b, 0x69, 0x80, 0xae, 0x3c, 0xb0, 0x60, 0x59, 0xbc, 0x1e, 0xd4,
+ 0xa8, 0x59, 0x3e, 0x84, 0x03, 0xdc, 0x16, 0x0a, 0xf0, 0x2d, 0x72, 0xd7,
+ 0x50, 0x3f, 0x6c, 0xa7, 0x0f, 0x2e, 0x82, 0x22, 0x09, 0x3b, 0x4f, 0xc1,
+ 0x26, 0x21, 0xba, 0x93, 0x16, 0xce, 0x30, 0x52, 0xe8, 0xbb, 0x06, 0x71,
+ 0xc0, 0x26, 0x9a, 0xb3, 0x23, 0x12, 0xf8, 0x61, 0x2e, 0xc2, 0xca, 0xe6,
+ 0x42, 0x02, 0x3a, 0x34, 0x43, 0x2c, 0x54, 0x25, 0x66, 0xcb, 0x10, 0x32,
+ 0x22, 0x34, 0x8f, 0xd9, 0x78, 0x37, 0xc0, 0x3f, 0xe7, 0x60, 0x85, 0x7c,
+ 0x0c, 0x2f, 0x0a, 0xcc, 0x26, 0xc9, 0xe6, 0x01, 0xf8, 0x3a, 0x19, 0x40,
+ 0x24, 0x30, 0xe3, 0x06, 0xa7, 0x46, 0x3b, 0x2b, 0x2e, 0x6a, 0x2d, 0xc7,
+ 0xb6, 0x1a, 0x2e, 0x06, 0x1a, 0x13, 0xa0, 0xb3, 0x11, 0x8d, 0x9a, 0xfa,
+ 0xb1, 0x5e, 0x56, 0x84, 0xaa, 0x58, 0x27, 0x84, 0x46, 0x7b, 0x73, 0xec,
+ 0xa0, 0x28, 0x53, 0x26, 0x0f, 0x5f, 0xa7, 0x85, 0x6d, 0x75, 0x60, 0x67,
+ 0xcc, 0x2c, 0x86, 0x34, 0x7c, 0xfe, 0xc0, 0x2a, 0xa4, 0xe6, 0xb6, 0x2b,
+ 0x25, 0x16, 0xe1, 0x3b, 0x04, 0x36, 0x02, 0x26, 0x02, 0x03, 0x01, 0x23,
+ 0x9c, 0x03, 0x04, 0xe6, 0x13, 0x77, 0x75, 0x51, 0x81, 0xdc, 0x6b, 0x70,
+ 0xcb, 0x21, 0x9a, 0xb8, 0x0d, 0x9d, 0xe8, 0x99, 0xb5, 0xbf, 0xe3, 0x7c,
+ 0xec, 0x31, 0x67, 0x8e, 0x16, 0x0e, 0xf9, 0xd1, 0xaf, 0xb7, 0x0d, 0xb7,
+ 0x0c, 0xcd, 0x57, 0x89, 0x6a, 0x18, 0x77, 0x94, 0x5f, 0x67, 0xb0, 0x02,
+ 0x84, 0x86, 0xaf, 0x58, 0x52, 0x4b, 0xc2, 0x82, 0x46, 0xad, 0x54, 0xeb,
+ 0x20, 0x2a, 0xdf, 0x30, 0xd0, 0x7c, 0x1e, 0xb2, 0x2c, 0x20, 0xee, 0x01,
+ 0x51, 0x41, 0x00, 0xe9, 0x0c, 0x2a, 0xe2, 0x72, 0x52, 0x84, 0x22, 0x23,
+ 0x19, 0x48, 0x87, 0x80, 0x70, 0x4e, 0xa8, 0x6b, 0x31, 0xc1, 0x7a, 0x7d,
+ 0xe1, 0x5b, 0xb5, 0xf3, 0x40, 0xd5, 0x27, 0xe2, 0x1a, 0xb1, 0x01, 0x11,
+ 0x3e, 0x71, 0x5b, 0x90, 0xc9, 0x2d, 0x40, 0x81, 0x87, 0xc8, 0x5a, 0x5a,
+ 0xc9, 0xf8, 0x19, 0x48, 0x81, 0x48, 0x92, 0x61, 0xbd, 0x18, 0x97, 0xce,
+ 0x5f, 0x95, 0xe7, 0x2c, 0x0b, 0xe0, 0xc7, 0x2b, 0x14, 0xf9, 0x37, 0x0b,
+ 0x57, 0x14, 0x0b, 0xb3, 0x45, 0x2b, 0xf8, 0x8e, 0xaa, 0x3b, 0xd0, 0x89,
+ 0x28, 0x10, 0x30, 0xb9, 0x5a, 0x5a, 0xe0, 0x57, 0xa7, 0x11, 0xf9, 0xa4,
+ 0x5f, 0x91, 0xce, 0x48, 0xf1, 0x0f, 0x71, 0xf9, 0x8b, 0x26, 0x40, 0x48,
+ 0x71, 0x5c, 0x7c, 0xdd, 0x01, 0x3a, 0x54, 0x36, 0x16, 0x42, 0xf3, 0xa8,
+ 0x1b, 0x38, 0x0e, 0xc6, 0xd7, 0x49, 0xa9, 0x13, 0x28, 0xc6, 0x81, 0x0d,
+ 0xf4, 0x33, 0x6d, 0xe0, 0x8b, 0xa3, 0x30, 0xb5, 0x5f, 0x63, 0x60, 0xbe,
+ 0x3f, 0xed, 0x92, 0x49, 0xab, 0x07, 0x5f, 0x30, 0x0c, 0x26, 0x9e, 0xe2,
+ 0x6c, 0xb1, 0xb3, 0x27, 0x50, 0xe4, 0x48, 0xa7, 0xfe, 0x54, 0x2c, 0x9d,
+ 0x9c, 0x44, 0x15, 0x84, 0x41, 0x31, 0x59, 0x44, 0x38, 0x4b, 0x20, 0x7e,
+ 0x0e, 0x73, 0x30, 0x88, 0xf4, 0xe4, 0xd6, 0xfc, 0xc2, 0x6c, 0x51, 0x20,
+ 0x36, 0x7c, 0x2b, 0x47, 0xc4, 0xfe, 0x63, 0x03, 0x17, 0x6b, 0x78, 0x20,
+ 0x21, 0xad, 0x0d, 0x24, 0x3f, 0xd4, 0x68, 0xe6, 0x5b, 0xcb, 0x28, 0xd3,
+ 0x51, 0xc6, 0x71, 0x78, 0x5a, 0x88, 0x86, 0x66, 0x19, 0x5b, 0x13, 0x21,
+ 0x31, 0xe1, 0xbb, 0x49, 0x3e, 0xd2, 0xe2, 0xfa, 0xfc, 0xce, 0x2b, 0xd3,
+ 0x48, 0x98, 0x4b, 0x0f, 0xf8, 0xb2, 0x32, 0x80, 0xc4, 0x20, 0x09, 0xc4,
+ 0x0d, 0x3c, 0xd6, 0x54, 0xae, 0xaa, 0x30, 0xb5, 0x02, 0xce, 0x6d, 0x39,
+ 0xc5, 0x2b, 0xec, 0x30, 0xc4, 0x7b, 0x31, 0x5f, 0x1a, 0x89, 0x3f, 0x96,
+ 0x63, 0x55, 0x7c, 0x6c, 0xf2, 0x39, 0x47, 0x7a, 0x70, 0x1a, 0xb7, 0x93,
+ 0x11, 0x54, 0x13, 0xef, 0x55, 0xe1, 0x32, 0x36, 0x82, 0xb0, 0x87, 0x9c,
+ 0x4e, 0xac, 0xe0, 0x10, 0x8c, 0x34, 0x3a, 0x48, 0x6f, 0x3f, 0x97, 0x40,
+ 0x6f, 0x51, 0xca, 0x9c, 0x0b, 0xab, 0xca, 0x1a, 0x95, 0x3f, 0x18, 0x92,
+ 0x0f, 0x5c, 0x08, 0x24, 0x2f, 0x48, 0x2c, 0x39, 0x68, 0x5d, 0x09, 0x31,
+ 0x09, 0x96, 0x37, 0x53, 0x8a, 0x9a, 0x79, 0xc6, 0x30, 0x73, 0xb5, 0xe7,
+ 0x70, 0xc7, 0x63, 0x50, 0xb3, 0x3a, 0x13, 0x2d, 0x3c, 0xf5, 0x39, 0x79,
+ 0xfa, 0x5f, 0x01, 0x14, 0xce, 0x20, 0x4c, 0x93, 0x01, 0x37, 0x45, 0xf5,
+ 0x62, 0xc2, 0x50, 0xc8, 0x4b, 0x88, 0x63, 0x39, 0x31, 0xe8, 0x19, 0xc4,
+ 0x06, 0x59, 0xfd, 0x15, 0xda, 0x80, 0x1b, 0x65, 0x2a, 0xd3, 0x71, 0x91,
+ 0xd8, 0x05, 0x4b, 0xc4, 0xb6, 0x17, 0x12, 0x43, 0xa2, 0x5d, 0x3f, 0xad,
+ 0xcc, 0x8a, 0x12, 0xba, 0x72, 0xf0, 0xb7, 0xa7, 0xf0, 0x01, 0x6d, 0xfe,
+ 0x9c, 0xb4, 0x87, 0x32, 0x21, 0x56, 0xa1, 0x02, 0xcc, 0xd0, 0x38, 0xb9,
+ 0xf6, 0x50, 0x6d, 0xb6, 0xb6, 0xfa, 0x33, 0x09, 0x89, 0xa2, 0x5d, 0xec,
+ 0xe1, 0x85, 0xcb, 0xca, 0xcc, 0xe4, 0xc1, 0xaa, 0x32, 0x3b, 0x4a, 0xdf,
+ 0x76, 0xb1, 0x10, 0x90, 0x50, 0xa1, 0xe4, 0xac, 0x32, 0x29, 0x3a, 0xbd,
+ 0xaf, 0x64, 0xe9, 0x42, 0x29, 0x01, 0x00, 0x10, 0x45, 0x96, 0xe5, 0x4c,
+ 0x88, 0xa4, 0x20, 0x65, 0x04, 0x21, 0x8a, 0x9b, 0x50, 0x90, 0xb8, 0x38,
+ 0x92, 0x0e, 0x02, 0x20, 0xbb, 0x81, 0x02, 0x00, 0x5e, 0xd2, 0x27, 0x39,
+ 0x4c, 0x40, 0x13, 0x4e, 0x72, 0x97, 0x50, 0x50, 0x13, 0x86, 0xc4, 0x60,
+ 0x31, 0x00, 0x28, 0x0a, 0x55, 0xac, 0xe0, 0x80, 0xc5, 0x16, 0x16, 0x06,
+ 0x5d, 0xac, 0x87, 0x2b, 0xeb, 0x6e, 0xd7, 0x84, 0x00, 0x68, 0xed, 0x88,
+ 0x15, 0xad, 0xdf, 0x79, 0xe4, 0xc3, 0xfe, 0x64, 0xff, 0xb7, 0xb2, 0x98,
+ 0xb4, 0xaa, 0x2a, 0x81, 0x93, 0x0f, 0x85, 0x37, 0x45, 0x03, 0x8c, 0xac,
+ 0x03, 0x85, 0x13, 0x84, 0x2a, 0x1c, 0x80, 0xab, 0x05, 0xc5, 0x0c, 0x85,
+ 0xb1, 0x09, 0x13, 0x94, 0x8b, 0x03, 0x44, 0xa0, 0x83, 0x37, 0x89, 0x8c,
+ 0x8c, 0x26, 0x9f, 0x8b, 0x90, 0xbb, 0x97, 0xaa, 0x55, 0x10, 0x1d, 0x91,
+ 0x03, 0xb3, 0x8e, 0xaa, 0x98, 0x56, 0x11, 0x11, 0x8e, 0x3c, 0x14, 0x9c,
+ 0xd6, 0xaf, 0xa0, 0x51, 0xc8, 0xd9, 0x10, 0x1f, 0x94, 0x85, 0xb7, 0xa6,
+ 0x97, 0x8e, 0xc6, 0x04, 0xb5, 0x26, 0x4a, 0x98, 0x18, 0x4c, 0xa1, 0x2c,
+ 0x0b, 0x0d, 0x5d, 0x53, 0x27, 0xac, 0x4c, 0x9b, 0xb8, 0x82, 0xc6, 0x1d,
+ 0xac, 0x01, 0xc8, 0x0a, 0x82, 0x1b, 0xc8, 0x49, 0x82, 0xc6, 0x66, 0x04,
+ 0xb9, 0x1f, 0x3f, 0x8a, 0x17, 0x84, 0x81, 0xb9, 0x2a, 0x74, 0x32, 0xde,
+ 0x4d, 0x9f, 0xfe, 0x3b, 0x43, 0xcc, 0x03, 0xf6, 0x0c, 0xf8, 0x38, 0x83,
+ 0x23, 0x90, 0x0e, 0x75, 0xdd, 0x72, 0xf0, 0x83, 0xe3, 0xc2, 0x83, 0x25,
+ 0x19, 0xe5, 0x0c, 0x00, 0xb8, 0x31, 0x21, 0x07, 0x85, 0x53, 0x30, 0x62,
+ 0x19, 0x03, 0x81, 0xa1, 0x62, 0xa5, 0x0f, 0x4d, 0x3a, 0xe0, 0xf0, 0x90,
+ 0x24, 0x04, 0x28, 0x0c, 0x05, 0x7c, 0x11, 0x39, 0xa5, 0x8d, 0xc7, 0xae,
+ 0x65, 0xb1, 0x32, 0x2a, 0x22, 0xd1, 0x71, 0x84, 0xc9, 0x8e, 0x2f, 0xb6,
+ 0xe1, 0x78, 0x06, 0x04, 0x09, 0xa2, 0x6a, 0xa9, 0xa0, 0x00, 0x03, 0x60,
+ 0xab, 0x22, 0x1a, 0x45, 0x45, 0x0f, 0x9d, 0x28, 0x27, 0xa6, 0x91, 0x25,
+ 0x72, 0x63, 0xa8, 0x00, 0xe0, 0x72, 0xa4, 0x90, 0x9a, 0x3e, 0x67, 0x06,
+ 0x91, 0xb1, 0x22, 0x83, 0x0c, 0xa1, 0x05, 0x72, 0x7e, 0x41, 0x3a, 0x48,
+ 0x01, 0x4b, 0xd1, 0x50, 0x06, 0x46, 0xa0, 0xf1, 0x9a, 0x28, 0xe0, 0x3b,
+ 0x38, 0x11, 0x29, 0xd0, 0x82, 0xd3, 0xed, 0x4a, 0xc0, 0x2e, 0x2a, 0x01,
+ 0x1c, 0xc1, 0x50, 0xf4, 0x89, 0x31, 0x21, 0x7b, 0xf3, 0x34, 0xe1, 0x72,
+ 0xc1, 0x0e, 0xa6, 0x67, 0xef, 0x74, 0x2d, 0x0d, 0x15, 0x0a, 0x80, 0x00,
+ 0x28, 0x1e, 0x30, 0xe9, 0xd2, 0xf2, 0x02, 0x47, 0x06, 0x13, 0x14, 0x5a,
+ 0xc1, 0x80, 0xb1, 0x21, 0x86, 0xd8, 0x33, 0x20, 0x7c, 0xf0, 0x18, 0x13,
+ 0x0a, 0x84, 0x89, 0x03, 0x02, 0xfe, 0x22, 0x08, 0x00, 0xa9, 0x28, 0x87,
+ 0xc4, 0x66, 0x6a, 0xe9, 0x0a, 0xf2, 0xc3, 0x50, 0x60, 0x45, 0xfe, 0xba,
+ 0x74, 0x6a, 0x72, 0x42, 0xce, 0x44, 0x39, 0x55, 0x2c, 0x15, 0xdd, 0x51,
+ 0xf4, 0x04, 0x5a, 0xaa, 0x04, 0x9a, 0x72, 0xc2, 0x57, 0x80, 0xcb, 0xb8,
+ 0x1f, 0x68, 0xef, 0xfc, 0xb1, 0xb8, 0x83, 0x4d, 0xc5, 0xdc, 0x69, 0x8a,
+ 0x1a, 0x78, 0x37, 0x66, 0x51, 0xfe, 0x00, 0xee, 0x6c, 0xd5, 0xe0, 0xd0,
+ 0x32, 0xf0, 0x86, 0x22, 0x81, 0x52, 0xd5, 0x9a, 0xae, 0x05, 0x85, 0x45,
+ 0xaa, 0x58, 0x0b, 0x34, 0x6c, 0xbb, 0xb9, 0x8d, 0xe3, 0x85, 0x00, 0x7c,
+ 0x49, 0xbc, 0x44, 0x9d, 0x93, 0x97, 0x4f, 0xc7, 0x8a, 0x02, 0xac, 0x07,
+ 0x02, 0x50, 0xe0, 0xe8, 0x24, 0x99, 0x60, 0xa0, 0x45, 0xa3, 0x79, 0x68,
+ 0xb3, 0xa8, 0x16, 0xd5, 0x38, 0xf0, 0xcf, 0x98, 0xb9, 0x4e, 0xfa, 0x01,
+ 0x9d, 0x3b, 0xd6, 0xc3, 0x23, 0x14, 0xaf, 0xe0, 0x00, 0x23, 0x86, 0x77,
+ 0xba, 0xb0, 0xe2, 0x19, 0x2f, 0x22, 0x11, 0x08, 0xb1, 0x53, 0xe2, 0xa2,
+ 0x05, 0xa3, 0x10, 0x4e, 0x68, 0x44, 0x0c, 0x7b, 0x32, 0xb1, 0x02, 0x3d,
+ 0x76, 0x7a, 0x20, 0x31, 0x06, 0xba, 0xd0, 0x50, 0x4b, 0x86, 0x4d, 0x3a,
+ 0x20, 0x0e, 0xc7, 0x4d, 0x74, 0x24, 0xcb, 0x2b, 0x44, 0xb6, 0xd3, 0x43,
+ 0x46, 0x2c, 0x18, 0xb4, 0x49, 0x3a, 0x20, 0x26, 0xb3, 0xd1, 0x14, 0x0c,
+ 0x9c, 0xb8, 0xe0, 0x0e, 0x5a, 0x76, 0x98, 0xd2, 0x8d, 0x57, 0x30, 0xd0,
+ 0x32, 0x1e, 0x9b, 0x40, 0xc8, 0xa3, 0x15, 0x1e, 0x9e, 0xd9, 0x25, 0x03,
+ 0x39, 0x58, 0x19, 0x85, 0xa4, 0xd4, 0x6c, 0xfa, 0x60, 0x3f, 0x33, 0x58,
+ 0xe1, 0x81, 0x02, 0x14, 0x1e, 0xeb, 0x48, 0x06, 0x52, 0xee, 0x58, 0x89,
+ 0x94, 0x79, 0x3a, 0x24, 0x25, 0x9a, 0x33, 0x11, 0x50, 0x4b, 0x2d, 0xa8,
+ 0xdc, 0x88, 0x28, 0x8e, 0x26, 0xa1, 0xa2, 0xe5, 0x87, 0x09, 0xa4, 0xc2,
+ 0x87, 0x00, 0x01, 0x94, 0x3b, 0xa2, 0xb4, 0x3f, 0x3b, 0x79, 0xaa, 0xa8,
+ 0x74, 0x4c, 0x08, 0x12, 0x91, 0x0a, 0x8f, 0x88, 0x54, 0x1a, 0x3e, 0x0a,
+ 0xdc, 0x83, 0x9d, 0x1b, 0x1e, 0x3b, 0x6e, 0x80, 0x49, 0xea, 0xca, 0xc2,
+ 0x4f, 0xa9, 0xfe, 0xb0, 0x4f, 0x34, 0xcc, 0x4c, 0xfe, 0xe2, 0xe1, 0xa2,
+ 0x1b, 0x08, 0x32, 0xe5, 0x21, 0x0c, 0xf2, 0xd8, 0xaf, 0x04, 0x56, 0xf9,
+ 0x13, 0xc1, 0xaf, 0x0b, 0x8e, 0x89, 0x87, 0x09, 0x0f, 0x50, 0x93, 0xd0,
+ 0x42, 0x91, 0x60, 0x72, 0x62, 0x0e, 0x05, 0x11, 0xbc, 0xf5, 0x84, 0x31,
+ 0x67, 0x41, 0xa9, 0xa5, 0x93, 0xc0, 0x98, 0x0b, 0xa9, 0xd4, 0xb0, 0xd2,
+ 0x4a, 0xb3, 0x8a, 0xb6, 0xa3, 0xe2, 0x0b, 0x13, 0xd2, 0xb1, 0x87, 0x54,
+ 0x16, 0xdb, 0x00, 0xd4, 0x54, 0x32, 0x1e, 0xcb, 0xe2, 0x0a, 0x46, 0xef,
+ 0x6a, 0x66, 0x8e, 0x7e, 0xe2, 0x58, 0x4b, 0xaa, 0x18, 0xf5, 0x22, 0x8e,
+ 0x2e, 0x46, 0xd8, 0x99, 0x67, 0x00, 0x6e, 0xc9, 0x19, 0x24, 0xb7, 0x05,
+ 0x35, 0xd3, 0xc9, 0x11, 0x5c, 0xa8, 0x70, 0xe2, 0xb2, 0x85, 0x10, 0x05,
+ 0xea, 0x14, 0x82, 0xcc, 0x30, 0x50, 0x31, 0x9e, 0xc4, 0x2c, 0x41, 0x96,
+ 0x1e, 0xbc, 0xb4, 0x12, 0x93, 0x22, 0xa6, 0x00, 0xd8, 0x22, 0x28, 0xab,
+ 0xfc, 0x6b, 0x24, 0xd5, 0x42, 0x10, 0xc3, 0x98, 0x67, 0x82, 0xf0, 0x01,
+ 0xb2, 0x03, 0x9d, 0x0c, 0x93, 0xc5, 0x5e, 0x3b, 0xbb, 0x62, 0x5a, 0x35,
+ 0x6e, 0x50, 0x8b, 0x12, 0x48, 0xee, 0xb2, 0x0c, 0x9d, 0x74, 0xce, 0x1a,
+ 0xc2, 0xb1, 0x26, 0xc6, 0xe5, 0x29, 0x9c, 0x1c, 0x69, 0xf1, 0x13, 0xc4,
+ 0x7e, 0xd6, 0x81, 0xa1, 0x0f, 0x0f, 0x2d, 0x22, 0xc3, 0xbb, 0x88, 0x1c,
+ 0xc9, 0x84, 0x66, 0x55, 0xd9, 0xd0, 0x4a, 0x35, 0x3a, 0x63, 0xfd, 0xc3,
+ 0x20, 0x1f, 0xc9, 0x52, 0xa2, 0x22, 0x35, 0x3c, 0x22, 0x21, 0xa0, 0x78,
+ 0x8c, 0x7b, 0x35, 0x03, 0xb4, 0xb4, 0x91, 0x41, 0x97, 0xbd, 0x7c, 0x79,
+ 0x09, 0xa8, 0x39, 0x5a, 0x88, 0xb2, 0xd7, 0x25, 0x47, 0xf8, 0x8b, 0xec,
+ 0x35, 0x53, 0x80, 0xa5, 0xd7, 0xf9, 0xb0, 0xc6, 0x09, 0x3e, 0x8c, 0xfe,
+ 0x5e, 0xda, 0x59, 0xc0, 0x8b, 0x18, 0x09, 0x10, 0x12, 0xba, 0x9c, 0xca,
+ 0x41, 0xb5, 0x46, 0x04, 0xb2, 0x02, 0x11, 0xae, 0xa3, 0xf2, 0x65, 0x14,
+ 0xe3, 0xca, 0xfe, 0xb3, 0x07, 0x71, 0xfa, 0xba, 0x2c, 0x1c, 0xaa, 0x7a,
+ 0xf2, 0xe1, 0xb2, 0xc6, 0x14, 0x02, 0xed, 0xe5, 0x21, 0x2b, 0x88, 0xa4,
+ 0x5e, 0x2c, 0x2c, 0xa3, 0x8b, 0xb8, 0x45, 0x4a, 0xbd, 0xec, 0x12, 0x0a,
+ 0xb6, 0x38, 0xa1, 0x02, 0x68, 0x4b, 0x99, 0xac, 0xc1, 0xb4, 0xe7, 0x2e,
+ 0x40, 0x0c, 0xb6, 0x95, 0xf2, 0x40, 0x8b, 0x26, 0xbc, 0x9c, 0xe4, 0x09,
+ 0x31, 0x2e, 0x9b, 0x65, 0xba, 0xb0, 0x36, 0x12, 0x66, 0x58, 0x2d, 0x01,
+ 0xdb, 0x04, 0x9c, 0x63, 0x9f, 0x29, 0xa2, 0xcd, 0xc4, 0x28, 0xe1, 0xb6,
+ 0x55, 0x33, 0x68, 0x1f, 0x29, 0x55, 0x0e, 0x00, 0xe0, 0xca, 0xa8, 0x97,
+ 0x6d, 0xc0, 0x06, 0x86, 0x4d, 0xb8, 0xf8, 0xe3, 0xc8, 0x34, 0x08, 0xd8,
+ 0xe2, 0x8a, 0x9f, 0x1b, 0xd1, 0xec, 0x0c, 0xaa, 0x56, 0x8c, 0x6e, 0x32,
+ 0x2f, 0x74, 0x2e, 0x9f, 0x37, 0xeb, 0x65, 0xf9, 0x61, 0x3d, 0x1d, 0x78,
+ 0xc9, 0x87, 0x1d, 0x80, 0x9a, 0xde, 0x77, 0x9e, 0x35, 0x3e, 0x64, 0x71,
+ 0x17, 0x9f, 0x74, 0x04, 0x5c, 0xf5, 0x5b, 0x42, 0x94, 0x76, 0xc2, 0x1f,
+ 0x57, 0xb5, 0x2a, 0x6d, 0x35, 0xa1, 0x5b, 0x63, 0x24, 0x44, 0xa5, 0xda,
+ 0x68, 0x49, 0x36, 0xb1, 0x88, 0x89, 0xdb, 0x40, 0x21, 0x84, 0x22, 0x00,
+ 0x81, 0x27, 0x29, 0x41, 0x50, 0x2a, 0x8a, 0x30, 0x12, 0x21, 0x50, 0xd0,
+ 0x23, 0xab, 0xb8, 0x90, 0x29, 0x54, 0xe6, 0x15, 0xd6, 0xa5, 0xe1, 0x2c,
+ 0xdb, 0x82, 0xca, 0x17, 0xb0, 0x73, 0x09, 0xb6, 0x08, 0xca, 0x5d, 0xcf,
+ 0x78, 0x9c, 0x70, 0xd8, 0x15, 0x33, 0xb5, 0xa4, 0xa7, 0x0f, 0x2b, 0x92,
+ 0x51, 0xfb, 0x18, 0x72, 0x84, 0xba, 0x69, 0xd8, 0x83, 0x47, 0x0f, 0x89,
+ 0x19, 0x20, 0x78, 0x64, 0x85, 0x89, 0x20, 0xc9, 0x02, 0xe9, 0x8b, 0x0a,
+ 0x29, 0x22, 0x00, 0x00, 0x3b,
+ };
+
+/*
+ Gray100 image declaration.
+*/
+#define Gray100ImageExtent 137
+
+static const unsigned char
+ Gray100Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ };
+
+/*
+ Gray95 image declaration.
+*/
+#define Gray95ImageExtent 137
+
+static const unsigned char
+ Gray95Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x10, 0x10, 0x10,
+ };
+
+/*
+ Gray90 image declaration.
+*/
+#define Gray90ImageExtent 137
+
+static const unsigned char
+ Gray90Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x08, 0x08, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x88, 0x80, 0x88, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88, 0x80, 0x88, 0x00, 0x00, 0x00,
+ 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22,
+ 0x22, 0x00, 0x00, 0x00, 0x00,
+ };
+
+/*
+ Gray85 image declaration.
+*/
+#define Gray85ImageExtent 137
+
+static const unsigned char
+ Gray85Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x00, 0x00, 0x00,
+ 0x00, 0x88, 0x8A, 0x88, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0x00, 0x00, 0x00,
+ 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x88, 0x8A,
+ 0x88, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8A, 0x88, 0x8A, 0x00, 0x00, 0x00,
+ 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA8, 0xA8,
+ 0xA8, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0x8A, 0x88, 0x8A, 0x88, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0x00, 0x00, 0x00,
+ 0x00, 0x22, 0x22, 0x22, 0x22,
+ };
+
+/*
+ Gray80 image declaration.
+*/
+#define Gray80ImageExtent 137
+
+static const unsigned char
+ Gray80Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x00, 0x00, 0x00,
+ 0x00, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x51, 0x11, 0x51,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00,
+ 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55,
+ 0x55, 0x00, 0x00, 0x00, 0x00, 0x51, 0x51, 0x51, 0x51, 0x00, 0x00, 0x00,
+ 0x00, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00,
+ 0x00, 0x51, 0x11, 0x51, 0x11, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55,
+ 0x55, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x51, 0x51, 0x51,
+ 0x51, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00,
+ 0x00, 0x11, 0x11, 0x11, 0x11,
+ };
+
+/*
+ Gray75 image declaration.
+*/
+#define Gray75ImageExtent 137
+
+static const unsigned char
+ Gray75Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00,
+ };
+
+/*
+ Gray70 image declaration.
+*/
+#define Gray70ImageExtent 137
+
+static const unsigned char
+ Gray70Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x11, 0x11,
+ 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x01, 0x01, 0x01, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x11, 0x11, 0x11, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x01, 0x11,
+ 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x11, 0x11, 0x11, 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x01, 0x01, 0x01, 0x01, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x11, 0x11,
+ 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x11, 0x01, 0x11, 0x01,
+ };
+
+/*
+ Gray65 image declaration.
+*/
+#define Gray65ImageExtent 137
+
+static const unsigned char
+ Gray65Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x44, 0x44, 0x44,
+ 0x44, 0xAA, 0xAA, 0xAA, 0xAA, 0x01, 0x01, 0x01, 0x01, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x44, 0x44, 0x44, 0x44, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x10, 0x11,
+ 0x10, 0xAA, 0xAA, 0xAA, 0xAA, 0x44, 0x44, 0x44, 0x44, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x01, 0x01, 0x01, 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0x44, 0x44, 0x44,
+ 0x44, 0xAA, 0xAA, 0xAA, 0xAA, 0x10, 0x10, 0x10, 0x10, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x44, 0x44, 0x44, 0x44, 0xAA, 0xAA, 0xAA, 0xAA, 0x01, 0x01, 0x01,
+ 0x01, 0xAA, 0xAA, 0xAA, 0xAA, 0x44, 0x44, 0x44, 0x44, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x11, 0x10, 0x11, 0x10, 0xAA, 0xAA, 0xAA, 0xAA, 0x44, 0x44, 0x44,
+ 0x44, 0xAA, 0xAA, 0xAA, 0xAA, 0x01, 0x01, 0x01, 0x01, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x44, 0x44, 0x44, 0x44, 0xAA, 0xAA, 0xAA, 0xAA, 0x10, 0x10, 0x10,
+ 0x10, 0xAA, 0xAA, 0xAA, 0xAA,
+ };
+
+/*
+ Gray60 image declaration.
+*/
+#define Gray60ImageExtent 137
+
+static const unsigned char
+ Gray60Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x11, 0x11, 0x11,
+ 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x44, 0x45, 0x44, 0x45, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x11, 0x11, 0x11, 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x54, 0x54, 0x54,
+ 0x54, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x11, 0x11, 0x11, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x45, 0x44, 0x45, 0x44, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x11, 0x11,
+ 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x54, 0x54, 0x54, 0x54, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x11, 0x11, 0x11, 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x44, 0x45, 0x44,
+ 0x45, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x11, 0x11, 0x11, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x54, 0x54, 0x54, 0x54, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x11, 0x11,
+ 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x45, 0x44, 0x45, 0x44, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x11, 0x11, 0x11, 0x11, 0xAA, 0xAA, 0xAA, 0xAA, 0x54, 0x54, 0x54,
+ 0x54, 0xAA, 0xAA, 0xAA, 0xAA,
+ };
+
+/*
+ Gray55 image declaration.
+*/
+#define Gray55ImageExtent 137
+
+static const unsigned char
+ Gray55Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0x2A, 0x2A, 0x2A,
+ 0x2A, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0x22, 0x22, 0x22, 0x22, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0x22, 0x2A, 0x22, 0x2A, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0x22, 0x22, 0x22,
+ 0x22, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0x2A, 0x2A, 0x2A, 0x2A, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0x22, 0x22, 0x22, 0x22, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0x22, 0x2A, 0x22,
+ 0x2A, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0x22, 0x22, 0x22, 0x22,
+ };
+
+/*
+ Gray50 image declaration.
+*/
+#define Gray50ImageExtent 137
+
+static const unsigned char
+ Gray50Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55,
+ };
+
+/*
+ Gray45 image declaration.
+*/
+#define Gray45ImageExtent 137
+
+static const unsigned char
+ Gray45Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0xAB, 0xAB, 0xAB, 0xAB, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0xBB, 0xBB, 0xBB, 0xBB, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xBB, 0xAB, 0xBB,
+ 0xAB, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0xBB, 0xBB, 0xBB, 0xBB, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAB, 0xAB, 0xAB, 0xAB, 0x55, 0x55, 0x55,
+ 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55,
+ 0x55, 0xBB, 0xAB, 0xBB, 0xAB, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x55, 0x55, 0x55, 0x55,
+ };
+
+/*
+ Gray40 image declaration.
+*/
+#define Gray40ImageExtent 137
+
+static const unsigned char
+ Gray40Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0x55, 0x55, 0x55, 0x55, 0xAB, 0xAB, 0xAB, 0xAB, 0x55, 0x55, 0x55,
+ 0x55, 0xEE, 0xEE, 0xEE, 0xEE, 0x55, 0x55, 0x55, 0x55, 0xBB, 0xBA, 0xBB,
+ 0xBA, 0x55, 0x55, 0x55, 0x55, 0xEE, 0xEE, 0xEE, 0xEE, 0x55, 0x55, 0x55,
+ 0x55, 0xAB, 0xAB, 0xAB, 0xAB, 0x55, 0x55, 0x55, 0x55, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0x55, 0x55, 0x55, 0x55, 0xBA, 0xBB, 0xBA, 0xBB, 0x55, 0x55, 0x55,
+ 0x55, 0xEE, 0xEE, 0xEE, 0xEE, 0x55, 0x55, 0x55, 0x55, 0xAB, 0xAB, 0xAB,
+ 0xAB, 0x55, 0x55, 0x55, 0x55, 0xEE, 0xEE, 0xEE, 0xEE, 0x55, 0x55, 0x55,
+ 0x55, 0xBB, 0xBA, 0xBB, 0xBA, 0x55, 0x55, 0x55, 0x55, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0x55, 0x55, 0x55, 0x55, 0xAB, 0xAB, 0xAB, 0xAB, 0x55, 0x55, 0x55,
+ 0x55, 0xEE, 0xEE, 0xEE, 0xEE, 0x55, 0x55, 0x55, 0x55, 0xBA, 0xBB, 0xBA,
+ 0xBB, 0x55, 0x55, 0x55, 0x55,
+ };
+
+/*
+ Gray35 image declaration.
+*/
+#define Gray35ImageExtent 137
+
+static const unsigned char
+ Gray35Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xDD, 0xDD, 0xDD, 0xDD, 0xAA, 0xAA, 0xAA, 0xAA, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0xAA, 0xAA, 0xAA, 0xAA, 0xDD, 0xDD, 0xDD, 0xDD, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x77, 0xF7, 0x77, 0xF7, 0xAA, 0xAA, 0xAA, 0xAA, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xAA, 0xAA, 0xAA, 0xAA, 0x7F, 0x7F, 0x7F, 0x7F, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xDD, 0xDD, 0xDD, 0xDD, 0xAA, 0xAA, 0xAA, 0xAA, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xAA, 0xAA, 0xAA, 0xAA, 0xDD, 0xDD, 0xDD, 0xDD, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0x7F, 0x7F, 0x7F, 0x7F, 0xAA, 0xAA, 0xAA, 0xAA, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xAA, 0xAA, 0xAA, 0xAA, 0x77, 0xF7, 0x77, 0xF7, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xDD, 0xDD, 0xDD, 0xDD, 0xAA, 0xAA, 0xAA, 0xAA, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0xAA, 0xAA, 0xAA, 0xAA, 0xDD, 0xDD, 0xDD, 0xDD, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xF7, 0xF7, 0xF7, 0xF7,
+ };
+
+/*
+ Gray30 image declaration.
+*/
+#define Gray30ImageExtent 137
+
+static const unsigned char
+ Gray30Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55, 0xEE, 0xEE, 0xEE, 0xEE, 0x55, 0x55, 0x55,
+ 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0x55, 0xEE, 0xFE, 0xEE,
+ 0xFE, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55,
+ 0x55, 0xEE, 0xEE, 0xEE, 0xEE, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFE, 0xFE, 0xFE, 0xFE, 0x55, 0x55, 0x55,
+ 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0x55, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55,
+ 0x55, 0xEE, 0xFE, 0xEE, 0xFE, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55, 0xEE, 0xEE, 0xEE, 0xEE, 0x55, 0x55, 0x55,
+ 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFE, 0xFE, 0xFE,
+ 0xFE, 0x55, 0x55, 0x55, 0x55,
+ };
+
+/*
+ Gray25 image declaration.
+*/
+#define Gray25ImageExtent 137
+
+static const unsigned char
+ Gray25Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55,
+ 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55,
+ 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55,
+ 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55,
+ 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55,
+ 0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0x55, 0x55,
+ };
+
+/*
+ Gray20 image declaration.
+*/
+#define Gray20ImageExtent 137
+
+static const unsigned char
+ Gray20Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xBB, 0xBB, 0xBB, 0xBB, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xBB, 0xBA,
+ 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xBB, 0xBB, 0xBB, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xBA, 0xBA, 0xBA, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xBB, 0xBB, 0xBB,
+ 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xBA, 0xBB, 0xBA, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA,
+ 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xBB, 0xBB, 0xBB, 0xBB, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xBA, 0xBA,
+ 0xBA, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+
+/*
+ Gray15 image declaration.
+*/
+#define Gray15ImageExtent 137
+
+static const unsigned char
+ Gray15Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0x77, 0x77, 0x77,
+ 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0x5D, 0x5D, 0x5D, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xD5, 0xDD, 0xD5,
+ 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDD, 0x5D, 0x5D, 0x5D, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77,
+ 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xD5, 0xDD, 0xD5, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0x5D, 0x5D,
+ 0x5D, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xD5, 0xDD, 0xD5, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77,
+ 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0x5D, 0x5D, 0x5D, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xD5, 0xDD,
+ 0xD5, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+
+/*
+ Gray10 image declaration.
+*/
+#define Gray10ImageExtent 137
+
+static const unsigned char
+ Gray10Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFD, 0xDD, 0xFD, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77,
+ 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD,
+ 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77,
+ 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xDD, 0xFD, 0xDD, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0x77, 0x77, 0x77, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFD, 0xFD, 0xFD, 0xFD,
+ };
+
+/*
+ Gray5 image declaration.
+*/
+#define Gray5ImageExtent 137
+
+static const unsigned char
+ Gray5Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xDD, 0xDD, 0xDD, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDD, 0xDD, 0xDD, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0xDD, 0xDD,
+ 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDF, 0xDF, 0xDF, 0xDF,
+ };
+
+/*
+ Gray0 image declaration.
+*/
+#define Gray0ImageExtent 137
+
+static const unsigned char
+ Gray0Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x32, 0x20, 0x33, 0x32, 0x0A, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+
+/*
+ Hexagons image declaration.
+*/
+#define HexagonsImageExtent 81
+
+static const unsigned char
+ HexagonsImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x33, 0x30, 0x20, 0x31, 0x38, 0x0A, 0x10, 0x01, 0x00,
+ 0x00, 0x10, 0x01, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80,
+ 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80, 0x00, 0x20,
+ 0x00, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x80, 0x00, 0x20,
+ 0x00, 0x80, 0x00, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
+ 0x00, 0x20, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80, 0x00, 0x10, 0x01, 0x00,
+ 0x00, 0x10, 0x01, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00,
+ };
+
+/*
+ Horizontal image declaration.
+*/
+#define HorizontalImageExtent 11
+
+static const unsigned char
+ HorizontalImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x34, 0x0A, 0xFF, 0x00, 0x00, 0x00,
+ };
+
+/*
+ HorizontalSaw image declaration.
+*/
+#define HorizontalSawImageExtent 24
+
+static const unsigned char
+ HorizontalSawImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x31, 0x36, 0x20, 0x38, 0x0A, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x28, 0x28, 0x44, 0x44, 0x82, 0x82, 0x01, 0x01,
+
+ };
+
+/*
+ HS_BDIAGONAL image declaration (Windows GDI HS_BDIAGONAL)
+*/
+#define HS_BDIAGONALImageExtent 15
+
+static const unsigned char
+ HS_BDIAGONALImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x01, 0x02, 0x04, 0x08, 0x10,
+ 0x20, 0x40, 0x80,
+ };
+
+/*
+ HS_CROSS image declaration (Windows GDI HS_CROSS)
+*/
+#define HS_CROSSImageExtent 15
+
+static const unsigned char
+ HS_CROSSImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x10, 0x10, 0x10, 0xFF, 0x10,
+ 0x10, 0x10, 0x10,
+ };
+
+/*
+ HS_DIAGCROSS image declaration (Windows GDI HS_DIAGCROSS)
+*/
+#define HS_DIAGCROSSImageExtent 15
+
+static const unsigned char
+ HS_DIAGCROSSImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x81, 0x42, 0x24, 0x18, 0x18,
+ 0x24, 0x42, 0x81,
+ };
+
+/*
+ HS_FDIAGONAL image declaration (Windows GDI HS_FDIAGONAL)
+*/
+#define HS_FDIAGONALImageExtent 15
+
+static const unsigned char
+ HS_FDIAGONALImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x80, 0x40, 0x20, 0x10, 0x08,
+ 0x04, 0x02, 0x01,
+ };
+
+/*
+ HS_HORIZONTAL image declaration (Windows GDI HS_HORIZONTAL)
+*/
+#define HS_HORIZONTALImageExtent 15
+
+static const unsigned char
+ HS_HORIZONTALImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x00, 0x00, 0x00, 0xFF, 0x00,
+ 0x00, 0x00, 0x00,
+ };
+
+/*
+ HS_VERTICAL image declaration (Windows GDI HS_VERTICAL)
+*/
+#define HS_VERTICALImageExtent 15
+
+static const unsigned char
+ HS_VERTICALImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10,
+ };
+
+/*
+ Left30 image declaration.
+*/
+#define Left30ImageExtent 11
+
+static const unsigned char
+ Left30Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x34, 0x0A, 0xC0, 0x30, 0x0C, 0x03,
+ };
+
+/*
+ Left45 image declaration.
+*/
+#define Left45ImageExtent 15
+
+static const unsigned char
+ Left45Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x80, 0x40, 0x20, 0x10, 0x08,
+ 0x04, 0x02, 0x01,
+ };
+
+/*
+ LeftShingle image declaration.
+*/
+#define LeftShingleImageExtent 81
+
+static const unsigned char
+ LeftShingleImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x32, 0x34, 0x20, 0x32, 0x34, 0x0A, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x04, 0x00, 0x00, 0x08, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0xFF, 0xFF, 0xFF,
+ };
+
+/*
+ GraphicsMagick Logo image
+*/
+#define LogoImageExtent 22077
+
+static const unsigned char
+ LogoImage[]=
+ {
+ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x8E, 0x02, 0xA2, 0x01, 0xF6, 0x00,
+ 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xB0, 0x4F, 0x00, 0x00, 0x00, 0x66, 0x99,
+ 0x00, 0x70, 0x9F, 0x10, 0xF6, 0xF9, 0xF0, 0x06, 0x09, 0x00, 0x00, 0x0B,
+ 0x04, 0x5F, 0x8F, 0x00, 0x00, 0xA5, 0x4A, 0x33, 0x4C, 0x00, 0x00, 0x58,
+ 0x27, 0x19, 0x26, 0x00, 0x8C, 0xB3, 0x40, 0x4C, 0x72, 0x00, 0x00, 0x84,
+ 0x3B, 0x00, 0x2C, 0x13, 0xD9, 0xE6, 0xC0, 0xB3, 0xCC, 0x80, 0xE3, 0xEC,
+ 0xD0, 0xA0, 0xBF, 0x60, 0xEC, 0xF3, 0xE0, 0xC6, 0xD9, 0xA0, 0x79, 0xA6,
+ 0x20, 0x83, 0xAC, 0x30, 0x59, 0x85, 0x00, 0x26, 0x39, 0x00, 0x0C, 0x13,
+ 0x00, 0x3F, 0x5F, 0x00, 0x00, 0x21, 0x0E, 0x52, 0x7C, 0x00, 0x00, 0x8F,
+ 0x40, 0x13, 0x1C, 0x00, 0xA9, 0xC6, 0x70, 0x00, 0x42, 0x1D, 0x00, 0x6E,
+ 0x31, 0x00, 0x9A, 0x45, 0xD0, 0xDF, 0xB0, 0x2C, 0x42, 0x00, 0x96, 0xB9,
+ 0x50, 0x00, 0x16, 0x09, 0xBC, 0xD3, 0x90, 0x46, 0x69, 0x00, 0x10, 0x10,
+ 0x10, 0x00, 0x37, 0x18, 0x39, 0x56, 0x00, 0x1F, 0x2F, 0x00, 0x00, 0x4D,
+ 0x22, 0x00, 0x79, 0x36, 0xF0, 0xF0, 0xF0, 0x80, 0x80, 0x80, 0x00, 0x63,
+ 0x2C, 0x40, 0x40, 0x40, 0xC0, 0xC0, 0xC0, 0xD0, 0xD0, 0xD0, 0x60, 0x60,
+ 0x60, 0x20, 0x20, 0x20, 0x30, 0x30, 0x30, 0xE0, 0xE0, 0xE0, 0xA0, 0xA0,
+ 0xA0, 0x50, 0x50, 0x50, 0xB0, 0xB0, 0xB0, 0x90, 0x90, 0x90, 0x70, 0x70,
+ 0x70, 0x7F, 0x7F, 0x7F, 0xEF, 0xEF, 0xEF, 0x3F, 0x3F, 0x3F, 0xBF, 0xBF,
+ 0xBF, 0x0F, 0x0F, 0x0F, 0x9F, 0x9F, 0x9F, 0x5F, 0x5F, 0x5F, 0xDF, 0xDF,
+ 0xDF, 0x8F, 0x8F, 0x8F, 0x00, 0x91, 0x42, 0xCF, 0xCF, 0xCF, 0x4F, 0x4F,
+ 0x4F, 0x2F, 0x2F, 0x2F, 0x1F, 0x1F, 0x1F, 0x6F, 0x6F, 0x6F, 0xAF, 0xAF,
+ 0xAF, 0x00, 0x48, 0x21, 0x00, 0x87, 0x3D, 0x00, 0x1B, 0x0C, 0x00, 0x09,
+ 0x04, 0x00, 0x75, 0x35, 0x00, 0x3F, 0x1C, 0x00, 0x51, 0x25, 0x00, 0x7E,
+ 0x39, 0x00, 0x24, 0x10, 0x00, 0x1F, 0x0E, 0x00, 0x2D, 0x14, 0x00, 0x6C,
+ 0x31, 0x00, 0x12, 0x08, 0x00, 0x36, 0x18, 0x00, 0x5A, 0x29, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x21, 0xF9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00,
+ 0x00, 0x00, 0x8E, 0x02, 0xA2, 0x01, 0x00, 0x07, 0xFE, 0x80, 0x00, 0x82,
+ 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
+ 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
+ 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2,
+ 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
+ 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
+ 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2,
+ 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE,
+ 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
+ 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x03, 0x0A, 0x1C, 0x48, 0xB0, 0xA0,
+ 0xC1, 0x83, 0x08, 0x13, 0x2A, 0x5C, 0xC8, 0xB0, 0xA1, 0xC3, 0x87, 0x10,
+ 0x23, 0x4A, 0x9C, 0x48, 0xB1, 0xA2, 0xC5, 0x8B, 0x18, 0x33, 0x6A, 0xDC,
+ 0xC8, 0xB1, 0xA3, 0xC7, 0x8F, 0x20, 0x43, 0x8A, 0x1C, 0x49, 0xB2, 0xA4,
+ 0xC9, 0x93, 0x28, 0x53, 0xAA, 0x5C, 0xC9, 0xB2, 0xA5, 0xCB, 0x97, 0x30,
+ 0x63, 0xCA, 0x9C, 0x49, 0xB3, 0xA6, 0xCD, 0x9B, 0x38, 0x73, 0xEA, 0xDC,
+ 0xC9, 0xB3, 0xA7, 0xCF, 0x9F, 0x40, 0x57, 0x5A, 0x28, 0x10, 0xB4, 0xA8,
+ 0xD1, 0x62, 0x25, 0x06, 0x0C, 0xC0, 0x90, 0x62, 0xC2, 0xD1, 0xA7, 0x50,
+ 0x73, 0x85, 0x50, 0x4A, 0xF5, 0x02, 0x85, 0x12, 0x51, 0xB3, 0x6A, 0x6D,
+ 0x75, 0x81, 0xAA, 0x57, 0xA5, 0x27, 0x2C, 0x54, 0xD8, 0x4A, 0xB6, 0xEC,
+ 0xA7, 0x0A, 0x5F, 0xD3, 0x2A, 0xC5, 0x20, 0xC1, 0xA9, 0xD9, 0xB7, 0xFE,
+ 0x70, 0x25, 0xA5, 0xA0, 0x9A, 0xC1, 0x83, 0x5A, 0xAF, 0x56, 0xB1, 0xC6,
+ 0xDD, 0xCB, 0xD7, 0x50, 0x03, 0xAA, 0x2D, 0x04, 0x6C, 0xD0, 0xA0, 0xE2,
+ 0xAE, 0xD7, 0x13, 0x29, 0xC6, 0xF6, 0x5D, 0x6C, 0xB6, 0x80, 0x57, 0x10,
+ 0x02, 0x22, 0x47, 0x76, 0xC1, 0x21, 0x83, 0xE1, 0xB5, 0x21, 0xDC, 0x32,
+ 0xDE, 0x3C, 0xAB, 0x00, 0xD1, 0x87, 0x16, 0xA8, 0x22, 0x90, 0x4C, 0x3A,
+ 0x32, 0x08, 0x13, 0x76, 0x2F, 0x13, 0xA0, 0xA0, 0x98, 0xB3, 0xEB, 0x54,
+ 0x15, 0x2C, 0x9C, 0x18, 0x60, 0x01, 0x22, 0x05, 0xAA, 0x1C, 0x4A, 0xEB,
+ 0x16, 0x60, 0x80, 0x30, 0x02, 0xC3, 0x11, 0x5E, 0x0B, 0x27, 0x55, 0x21,
+ 0x05, 0x86, 0xC3, 0x10, 0x09, 0x50, 0x75, 0xB1, 0xBB, 0xB9, 0x00, 0x17,
+ 0x2D, 0x2C, 0x7F, 0xD5, 0x3C, 0xBC, 0xBA, 0xA6, 0x09, 0x21, 0xBA, 0xAA,
+ 0x7D, 0x18, 0xC1, 0xAB, 0x01, 0xE7, 0xE0, 0x4F, 0x7B, 0xB5, 0x4E, 0xFE,
+ 0x52, 0x09, 0x0A, 0xDA, 0x0D, 0xEB, 0x65, 0x38, 0x55, 0xA9, 0x03, 0xF0,
+ 0xF0, 0x05, 0x8C, 0x2F, 0x4F, 0xDF, 0x51, 0x01, 0x0B, 0x14, 0x94, 0x5F,
+ 0xA6, 0x4A, 0xC1, 0x61, 0x7A, 0x13, 0xF1, 0x39, 0xB7, 0xC1, 0x7C, 0x8D,
+ 0x9C, 0x10, 0xC2, 0x7A, 0xF5, 0x31, 0x56, 0xDC, 0x6C, 0x97, 0x65, 0xD0,
+ 0x02, 0x08, 0x1A, 0x50, 0x45, 0x40, 0x43, 0x68, 0x51, 0xB5, 0x41, 0x80,
+ 0xCD, 0x31, 0x50, 0x95, 0x23, 0xA1, 0x29, 0x45, 0x40, 0x58, 0x9F, 0x25,
+ 0xB8, 0xD7, 0x5F, 0x86, 0x79, 0x60, 0xC2, 0x85, 0x91, 0x19, 0xE0, 0x55,
+ 0x70, 0xDA, 0x44, 0x10, 0x81, 0x04, 0x30, 0xC6, 0x18, 0xA3, 0x05, 0x2E,
+ 0x86, 0xF8, 0xC9, 0x5C, 0x4A, 0x65, 0x80, 0x61, 0x86, 0x54, 0x35, 0xD0,
+ 0x48, 0x01, 0xE9, 0x79, 0xC5, 0x14, 0x75, 0x22, 0x92, 0x85, 0xE3, 0x57,
+ 0x2A, 0x68, 0xFE, 0xF0, 0x9D, 0x6E, 0x0E, 0x50, 0x15, 0xC2, 0x35, 0xD8,
+ 0x1D, 0xB7, 0xDF, 0x57, 0x0D, 0x50, 0x20, 0x56, 0x27, 0x0C, 0x0E, 0x10,
+ 0xD8, 0x8E, 0xBA, 0x69, 0xA8, 0x94, 0x8F, 0x8C, 0x48, 0xB0, 0xDF, 0x05,
+ 0x07, 0x16, 0x49, 0x56, 0x85, 0x4A, 0x71, 0xE0, 0xC2, 0x92, 0xCD, 0x99,
+ 0xB0, 0xE1, 0x34, 0x05, 0xA4, 0x10, 0xE4, 0x94, 0x77, 0x31, 0x65, 0x63,
+ 0x25, 0x8E, 0x51, 0xC5, 0x00, 0x97, 0xBA, 0xB9, 0xF9, 0x25, 0x23, 0x15,
+ 0xE8, 0x47, 0x67, 0x58, 0xAD, 0x99, 0x79, 0xD4, 0x7F, 0xF1, 0x0D, 0x48,
+ 0x15, 0x91, 0x67, 0x95, 0x20, 0x01, 0x05, 0x0D, 0x48, 0xE9, 0x15, 0x01,
+ 0x55, 0x36, 0xD5, 0x49, 0x09, 0x82, 0xD2, 0x39, 0x25, 0x01, 0x12, 0x60,
+ 0x92, 0x94, 0x52, 0xA3, 0xF1, 0x59, 0x9A, 0x02, 0x4E, 0x32, 0x72, 0x1B,
+ 0x55, 0x20, 0x50, 0xF6, 0xDB, 0x65, 0x6C, 0x31, 0x6A, 0x68, 0x4F, 0xED,
+ 0x0D, 0xE0, 0x41, 0x80, 0xA9, 0x0D, 0x90, 0x02, 0x28, 0x0B, 0x66, 0x4A,
+ 0x27, 0x99, 0x85, 0x52, 0x52, 0x40, 0x96, 0x5F, 0x21, 0xE0, 0x00, 0x07,
+ 0x0A, 0x14, 0x6B, 0x6C, 0xB1, 0x0E, 0x38, 0x50, 0xAB, 0x5A, 0x18, 0xB8,
+ 0xFA, 0xC8, 0xA9, 0x03, 0xE4, 0x26, 0x2A, 0x69, 0xA4, 0x2A, 0xD5, 0xA9,
+ 0x22, 0x13, 0x78, 0xB5, 0xA5, 0x69, 0x0A, 0x2C, 0xAB, 0x56, 0x5E, 0xAF,
+ 0xFE, 0x94, 0xAD, 0x85, 0xF1, 0x55, 0xBB, 0x54, 0x27, 0x71, 0x4A, 0xAA,
+ 0xA9, 0x5A, 0xAC, 0xE1, 0xA9, 0xAE, 0x52, 0x49, 0xA2, 0x18, 0xE0, 0x06,
+ 0xD0, 0x79, 0x3B, 0x00, 0x01, 0xB5, 0x51, 0x22, 0xA8, 0x06, 0xD3, 0x52,
+ 0x4B, 0xD5, 0xB5, 0x89, 0x90, 0x38, 0x00, 0x02, 0x6C, 0x92, 0x36, 0x58,
+ 0x61, 0xFB, 0x21, 0xD6, 0x6B, 0xB8, 0x36, 0xA5, 0xC7, 0x2F, 0x7C, 0x20,
+ 0x78, 0xB5, 0x30, 0x25, 0x15, 0xFE, 0x40, 0xBB, 0xEE, 0x7E, 0x00, 0x43,
+ 0x52, 0xC0, 0xBB, 0x1C, 0xC8, 0x3B, 0xED, 0x06, 0x1C, 0xA4, 0x95, 0x6F,
+ 0x24, 0xE3, 0x2A, 0x55, 0xF0, 0xB4, 0x4D, 0x5A, 0xAB, 0x48, 0x77, 0x54,
+ 0x01, 0x08, 0x1F, 0x65, 0xD2, 0x19, 0x76, 0x2B, 0xC3, 0x38, 0x41, 0xAB,
+ 0x42, 0x7C, 0x2E, 0x78, 0x35, 0xF3, 0x25, 0x62, 0x96, 0x48, 0xAC, 0x0B,
+ 0x0C, 0x78, 0x2C, 0x00, 0x03, 0x2E, 0x74, 0xCB, 0xEC, 0x9D, 0x8C, 0x08,
+ 0x3C, 0x40, 0x06, 0x7B, 0xF6, 0x5B, 0xDA, 0x06, 0x29, 0x2F, 0x2A, 0x49,
+ 0xAC, 0xEF, 0x81, 0xC7, 0x40, 0xD0, 0xE0, 0x45, 0xCD, 0x22, 0x22, 0xE9,
+ 0xE9, 0xB8, 0x23, 0x08, 0x46, 0xAB, 0xE5, 0x2C, 0xCD, 0x30, 0x7D, 0x6A,
+ 0xF2, 0x6E, 0xBD, 0xA9, 0xB0, 0x2A, 0x55, 0x27, 0x5C, 0x32, 0xC1, 0xBB,
+ 0x39, 0xB6, 0xD0, 0x34, 0x86, 0x06, 0x98, 0x10, 0xB3, 0x87, 0x63, 0x1B,
+ 0x72, 0xA4, 0xAC, 0x27, 0x3B, 0x2D, 0x59, 0x0B, 0x78, 0x21, 0xBD, 0x88,
+ 0xA4, 0x2E, 0x3B, 0x97, 0x32, 0x02, 0x0F, 0x33, 0x49, 0xD5, 0xD6, 0x7A,
+ 0x7B, 0xC5, 0x9C, 0xA8, 0x69, 0xAF, 0x7D, 0x01, 0xD9, 0x39, 0xED, 0x6B,
+ 0xB0, 0x09, 0x08, 0xDF, 0x25, 0xB8, 0x23, 0x11, 0xE8, 0x8A, 0xC0, 0x83,
+ 0x7E, 0x2B, 0xB0, 0xF6, 0xBD, 0x79, 0x0F, 0x52, 0x80, 0xA0, 0x1E, 0xF4,
+ 0xED, 0xB7, 0x64, 0xE6, 0x0E, 0xD0, 0xDF, 0x23, 0x68, 0x0E, 0x00, 0x99,
+ 0x73, 0x2A, 0x52, 0xA5, 0x40, 0x73, 0x31, 0x33, 0x4E, 0xC8, 0xE9, 0x54,
+ 0x55, 0xED, 0x74, 0xE6, 0xAF, 0x53, 0x6E, 0x13, 0xB4, 0xB9, 0x81, 0x6D,
+ 0xEF, 0x57, 0x76, 0x52, 0xD2, 0xA1, 0x57, 0x0A, 0xA8, 0x2E, 0x2A, 0x08,
+ 0xCB, 0x12, 0xB0, 0x39, 0x21, 0x3D, 0x2B, 0x35, 0x3B, 0x78, 0x06, 0x30,
+ 0xA0, 0x81, 0x02, 0x57, 0xEF, 0x98, 0xF9, 0x00, 0xFE, 0xA5, 0x13, 0x72,
+ 0xA4, 0xD7, 0xCE, 0x45, 0xB8, 0x5C, 0x73, 0x5E, 0x39, 0x5B, 0xFD, 0x00,
+ 0x73, 0xF7, 0xBB, 0x36, 0x82, 0xC2, 0xCF, 0xB4, 0x3C, 0x02, 0x77, 0xAB,
+ 0x05, 0xA2, 0x25, 0x13, 0x64, 0xEA, 0x81, 0xD0, 0xAB, 0x1B, 0xB0, 0x2C,
+ 0x06, 0x8C, 0x10, 0xD4, 0xED, 0xC2, 0x13, 0x35, 0xD1, 0x74, 0x2C, 0x3E,
+ 0x06, 0x58, 0x5B, 0xDB, 0x1C, 0x91, 0xA5, 0x6D, 0x35, 0x27, 0x64, 0x7A,
+ 0x42, 0x1F, 0x55, 0x10, 0x11, 0x3B, 0x69, 0x39, 0x2D, 0x67, 0x54, 0x99,
+ 0x5E, 0xFC, 0x5A, 0x92, 0x27, 0xD5, 0x5C, 0x85, 0x10, 0x11, 0x08, 0x01,
+ 0x00, 0x23, 0x11, 0x28, 0xAF, 0x58, 0x70, 0x75, 0xBA, 0x59, 0xD6, 0x93,
+ 0x12, 0x61, 0xB6, 0x01, 0x38, 0x6F, 0x32, 0xA3, 0x4B, 0xCB, 0x00, 0xC1,
+ 0x63, 0x3E, 0xA5, 0x4C, 0xEC, 0x10, 0x8E, 0x83, 0xCF, 0xE8, 0xDA, 0x47,
+ 0x1A, 0x02, 0x15, 0x22, 0x4B, 0x08, 0xE0, 0x1F, 0x9F, 0x00, 0x07, 0x96,
+ 0x0D, 0xDE, 0x04, 0x58, 0x78, 0x09, 0x01, 0xE3, 0xCE, 0x23, 0x28, 0xF8,
+ 0x31, 0x42, 0x5D, 0x27, 0x44, 0x61, 0x69, 0xFC, 0xB7, 0xA2, 0x44, 0xC4,
+ 0x2A, 0x8A, 0x53, 0x8C, 0xA1, 0x5A, 0xB0, 0xA8, 0x9B, 0x98, 0xAD, 0x70,
+ 0x11, 0x66, 0x0B, 0x95, 0x73, 0x22, 0xF6, 0x98, 0xDD, 0x90, 0x51, 0x29,
+ 0x87, 0x60, 0x99, 0x52, 0x66, 0xE8, 0xB4, 0x98, 0xED, 0xCC, 0x88, 0xF2,
+ 0x43, 0x5E, 0x5B, 0x4C, 0x27, 0x1B, 0x76, 0x41, 0x62, 0x7D, 0x5C, 0x94,
+ 0xA2, 0x64, 0x36, 0x20, 0xB9, 0x80, 0x51, 0x25, 0x71, 0xBB, 0x21, 0xA2,
+ 0x52, 0x2E, 0x70, 0x02, 0x48, 0xE9, 0x8A, 0x87, 0x7D, 0x7A, 0xD3, 0x22,
+ 0x6C, 0x06, 0x1F, 0x41, 0x2A, 0x85, 0x47, 0x6B, 0x39, 0x84, 0xC0, 0x08,
+ 0xB6, 0x3A, 0x45, 0xD9, 0x10, 0x8E, 0x35, 0xA9, 0x50, 0x03, 0x12, 0xFE,
+ 0x33, 0x88, 0xE2, 0x28, 0x2D, 0x2D, 0x13, 0x72, 0x44, 0xC9, 0xF8, 0xA6,
+ 0x47, 0xF0, 0xF8, 0x49, 0x29, 0x23, 0x2B, 0x84, 0xA0, 0xAE, 0xB7, 0x9B,
+ 0xA8, 0x05, 0x4F, 0x10, 0x29, 0x40, 0x5D, 0xF6, 0xAE, 0x56, 0xB4, 0x62,
+ 0xB5, 0x20, 0x59, 0xCB, 0x0A, 0x9F, 0xC3, 0xE0, 0xE3, 0x2D, 0x48, 0x0E,
+ 0x00, 0x4C, 0x84, 0x58, 0xDE, 0x00, 0x00, 0xD9, 0xAF, 0x53, 0x8E, 0x10,
+ 0x93, 0x34, 0x29, 0x41, 0x88, 0xA2, 0xA4, 0xA9, 0xF0, 0x09, 0x62, 0x92,
+ 0x42, 0x6C, 0xCE, 0x60, 0x14, 0x90, 0x2C, 0x62, 0xB1, 0x12, 0x3E, 0x51,
+ 0x9B, 0x1C, 0x0E, 0xA9, 0x82, 0xCD, 0xC5, 0x19, 0xA2, 0x85, 0x17, 0xFB,
+ 0x22, 0x22, 0x46, 0xF9, 0x42, 0xC1, 0xA4, 0xC5, 0x97, 0xC0, 0x1C, 0x44,
+ 0x7A, 0x66, 0x85, 0xC2, 0xA8, 0x89, 0x13, 0x99, 0x33, 0x29, 0x41, 0x76,
+ 0x2E, 0x83, 0x80, 0x24, 0xD5, 0xEA, 0x9D, 0x88, 0x50, 0xE3, 0x00, 0x0A,
+ 0x07, 0x1F, 0x06, 0x14, 0xD0, 0x2B, 0x0E, 0x40, 0xE4, 0x6E, 0xBC, 0x84,
+ 0xCA, 0x6D, 0x3E, 0x32, 0x6B, 0x3D, 0x5A, 0x18, 0xDC, 0xE8, 0x74, 0x4C,
+ 0x44, 0x54, 0x8F, 0x9D, 0xCE, 0x39, 0x65, 0x8E, 0x9A, 0x63, 0xAE, 0x74,
+ 0x02, 0x60, 0x7D, 0x02, 0xE5, 0x53, 0xED, 0x94, 0xE2, 0x4C, 0x78, 0xDE,
+ 0x23, 0x84, 0xAE, 0x28, 0xA1, 0x61, 0x10, 0xA0, 0x26, 0xC9, 0x9C, 0x52,
+ 0x9B, 0x8B, 0x10, 0x18, 0xF9, 0x1A, 0x39, 0x25, 0x62, 0x5E, 0xEE, 0x9F,
+ 0x28, 0x25, 0x84, 0x57, 0xE0, 0xD3, 0xBA, 0xA5, 0x28, 0xF1, 0x33, 0xEB,
+ 0xBB, 0xD8, 0x0D, 0x05, 0x41, 0x38, 0xF8, 0x7C, 0x6F, 0x00, 0xBE, 0x1B,
+ 0xD5, 0xBF, 0x76, 0x27, 0xA8, 0xA0, 0x8E, 0x2A, 0x03, 0x26, 0x28, 0x67,
+ 0x64, 0x6A, 0x18, 0x4A, 0x8F, 0x02, 0x24, 0x02, 0x24, 0x4A, 0xA5, 0x2A,
+ 0xE6, 0x14, 0xFE, 0xB7, 0x6B, 0x9A, 0x93, 0x2A, 0x3B, 0x15, 0x44, 0xEC,
+ 0x5C, 0xBA, 0x1B, 0x08, 0xB6, 0xB4, 0x34, 0x20, 0x88, 0x0E, 0x70, 0x0C,
+ 0x31, 0x53, 0xEC, 0x69, 0x71, 0x2D, 0x27, 0x00, 0x16, 0x06, 0x1A, 0xC0,
+ 0xD6, 0x10, 0xC4, 0xA8, 0x04, 0x2E, 0x8A, 0x80, 0x06, 0x3B, 0x59, 0x46,
+ 0xDA, 0xA5, 0xC5, 0xA8, 0xAC, 0x1B, 0xEA, 0x20, 0x2C, 0x16, 0xCD, 0x04,
+ 0x82, 0x8A, 0xAB, 0xA4, 0xF1, 0xEA, 0x2B, 0x9D, 0xBA, 0x8F, 0x0A, 0x00,
+ 0x2B, 0xA6, 0xAA, 0x88, 0x15, 0x50, 0x4D, 0x60, 0x55, 0xD2, 0xD4, 0xEA,
+ 0x8D, 0x87, 0x18, 0x5F, 0x80, 0x1C, 0x39, 0x00, 0x32, 0x49, 0xC0, 0x51,
+ 0xEF, 0xDA, 0x80, 0x01, 0x54, 0x95, 0x30, 0xDD, 0x01, 0x60, 0x95, 0x10,
+ 0xAB, 0x1F, 0xB3, 0xAE, 0x32, 0xD7, 0x46, 0x2C, 0x6F, 0xA5, 0xBB, 0xC1,
+ 0x20, 0x40, 0x9B, 0x23, 0x48, 0x80, 0x55, 0xD0, 0x39, 0x5E, 0x1D, 0xC0,
+ 0xE3, 0x9C, 0xF3, 0x3E, 0xC2, 0xF2, 0xA3, 0x62, 0x6A, 0x91, 0x2A, 0x2A,
+ 0xC8, 0x19, 0x1F, 0x41, 0x36, 0xF4, 0x10, 0x92, 0x72, 0x60, 0x73, 0xCE,
+ 0x78, 0x2F, 0xDD, 0xEE, 0x4D, 0xB4, 0x5F, 0x01, 0x17, 0x22, 0x04, 0xC6,
+ 0xCF, 0xF2, 0x1D, 0x8F, 0x59, 0x29, 0x28, 0x6D, 0x22, 0xB2, 0x94, 0x47,
+ 0xC9, 0xC4, 0x76, 0x8D, 0xCD, 0x89, 0xDA, 0xCE, 0x26, 0xE9, 0x3C, 0x4B,
+ 0x1E, 0xD4, 0x39, 0x04, 0x1D, 0x80, 0x74, 0x6D, 0xCB, 0x0E, 0xDC, 0xDE,
+ 0x05, 0xB1, 0xA9, 0xB0, 0x1C, 0xC4, 0x24, 0x96, 0x88, 0x0E, 0xCA, 0x2E,
+ 0x3E, 0x99, 0x23, 0x80, 0xFA, 0xA6, 0x84, 0x81, 0xCC, 0x84, 0x89, 0x2A,
+ 0x10, 0x4D, 0x14, 0xE6, 0x90, 0x9B, 0x16, 0x0A, 0x78, 0xB6, 0x11, 0x39,
+ 0x04, 0x8F, 0x16, 0xD9, 0x48, 0x1A, 0xAD, 0x09, 0x42, 0x9F, 0x04, 0x2E,
+ 0xB0, 0x57, 0x6E, 0x06, 0x1E, 0xFE, 0x41, 0x5A, 0x94, 0xBC, 0xF2, 0x30,
+ 0xEF, 0x65, 0x74, 0x7B, 0x0A, 0x46, 0xC6, 0x27, 0x66, 0x14, 0x3E, 0x30,
+ 0x5D, 0x12, 0xA5, 0x33, 0x45, 0x50, 0xF5, 0x4B, 0x9C, 0x14, 0xA5, 0x57,
+ 0x32, 0x8A, 0x3D, 0x06, 0x28, 0x40, 0x05, 0xFC, 0xFD, 0x52, 0x56, 0xBF,
+ 0x59, 0xD6, 0x31, 0xAA, 0x25, 0xC1, 0x91, 0x31, 0x30, 0x00, 0x24, 0x85,
+ 0x5A, 0xD2, 0x84, 0x77, 0x9F, 0xF0, 0x71, 0x23, 0x84, 0xE9, 0x21, 0x61,
+ 0xAF, 0x20, 0xA0, 0x79, 0x31, 0x43, 0xEF, 0x29, 0x5A, 0x38, 0x59, 0xB6,
+ 0x25, 0xA2, 0x7A, 0x0C, 0x36, 0xA5, 0x22, 0x11, 0xB1, 0xB7, 0xD5, 0x0C,
+ 0x65, 0x12, 0x92, 0xC2, 0x2B, 0x9F, 0xE8, 0x55, 0x19, 0xB5, 0xE0, 0xEB,
+ 0x59, 0x54, 0x49, 0x32, 0x45, 0xD5, 0xD2, 0x5C, 0xC9, 0xE4, 0x0E, 0x00,
+ 0xC2, 0x04, 0xAC, 0x00, 0xEA, 0x17, 0xCD, 0xC8, 0x78, 0x77, 0xC5, 0x3B,
+ 0x36, 0x47, 0x8F, 0x45, 0xD3, 0xBC, 0xA5, 0x7A, 0x25, 0xC3, 0xA5, 0x10,
+ 0xD4, 0x6C, 0x9D, 0xA3, 0x5A, 0xF1, 0x22, 0x22, 0x56, 0x30, 0x2E, 0x4D,
+ 0xE6, 0xF0, 0x59, 0x08, 0xC7, 0x90, 0xC9, 0x89, 0x91, 0x10, 0x66, 0x97,
+ 0xFB, 0x15, 0x56, 0xD1, 0x0E, 0x36, 0x11, 0xBB, 0x04, 0xCF, 0xF1, 0x32,
+ 0x2A, 0x31, 0xDE, 0xB9, 0xA7, 0x7C, 0x5F, 0xC9, 0xEF, 0x6E, 0x4E, 0x9A,
+ 0xE6, 0x77, 0xAC, 0x19, 0x54, 0x6D, 0x26, 0x4D, 0x90, 0x27, 0x51, 0x80,
+ 0x08, 0x58, 0x00, 0x46, 0x70, 0x9D, 0x04, 0x75, 0x03, 0xB4, 0xB6, 0x0C,
+ 0x0B, 0x4C, 0xCC, 0x92, 0x89, 0x1A, 0xA0, 0x0B, 0x81, 0xE6, 0x47, 0xA8,
+ 0x8B, 0xC4, 0xD3, 0xD2, 0x40, 0xFD, 0x0E, 0x6D, 0x88, 0x51, 0x96, 0xF9,
+ 0xAA, 0x1E, 0x8A, 0xE0, 0x6E, 0xC6, 0x83, 0xD1, 0xE6, 0xF8, 0x55, 0x5B,
+ 0x3E, 0x2D, 0x55, 0xA5, 0xD9, 0x61, 0x31, 0x36, 0xFE, 0xAB, 0xAE, 0x86,
+ 0xB4, 0x81, 0x9D, 0x04, 0x16, 0x3A, 0x80, 0xB0, 0x40, 0x62, 0x7E, 0x01,
+ 0x12, 0xEC, 0x72, 0x75, 0x0D, 0x9E, 0xF4, 0xED, 0xD6, 0xC7, 0xA8, 0x9E,
+ 0x56, 0x4D, 0x33, 0x16, 0x59, 0xFC, 0xC2, 0xA7, 0x86, 0x17, 0x10, 0x14,
+ 0xA3, 0xB1, 0x2A, 0x28, 0x2D, 0x0B, 0xF5, 0x2B, 0x8D, 0x95, 0xCC, 0x46,
+ 0x07, 0xF0, 0xDF, 0x61, 0x97, 0xE3, 0x93, 0x3F, 0x2E, 0xE7, 0xA6, 0x01,
+ 0x55, 0xEC, 0xF3, 0xAE, 0xDA, 0x10, 0xEE, 0x85, 0xB5, 0x9B, 0x3D, 0x34,
+ 0x6D, 0xA5, 0xE8, 0x5B, 0x3E, 0x13, 0x4C, 0xC5, 0xDE, 0xA2, 0xA5, 0x54,
+ 0x3E, 0x31, 0x60, 0x74, 0xED, 0xE6, 0xA9, 0xED, 0x82, 0xAD, 0x14, 0xC5,
+ 0xAA, 0x2E, 0xBC, 0x7C, 0x95, 0x66, 0x0C, 0xC5, 0xD8, 0x1C, 0xD5, 0x36,
+ 0xD5, 0xDD, 0xE9, 0xD0, 0xE7, 0xFE, 0xE2, 0x83, 0x6C, 0x38, 0x03, 0xA0,
+ 0x00, 0x8A, 0x1D, 0x94, 0x74, 0x1B, 0x88, 0x40, 0xAF, 0x00, 0x5A, 0x60,
+ 0xFF, 0xF6, 0x61, 0x85, 0x83, 0xC5, 0x81, 0x74, 0x4F, 0x0B, 0x04, 0x7D,
+ 0x44, 0x84, 0x7B, 0x5D, 0x1E, 0x19, 0x93, 0xB7, 0xB8, 0x34, 0x37, 0x5E,
+ 0xF8, 0x03, 0xD3, 0x52, 0xDD, 0xC8, 0x48, 0x1B, 0xE3, 0xEB, 0xE0, 0x6E,
+ 0x80, 0xE6, 0x7D, 0x88, 0x09, 0x7C, 0x18, 0xA8, 0xB8, 0x64, 0x56, 0xF8,
+ 0x24, 0x0B, 0x5F, 0xFE, 0x48, 0x92, 0xDA, 0xCE, 0x51, 0xF9, 0x29, 0x42,
+ 0x5E, 0x55, 0x29, 0x76, 0x1C, 0x11, 0xA7, 0x7D, 0x99, 0x84, 0xDC, 0xEB,
+ 0x4B, 0x1F, 0x3B, 0x2F, 0xE7, 0xB2, 0xD5, 0x21, 0x55, 0x3C, 0x0E, 0xF4,
+ 0x70, 0x20, 0x38, 0x40, 0xE1, 0xA5, 0xB0, 0x30, 0x41, 0xD5, 0xF2, 0x29,
+ 0x6A, 0xC0, 0x5B, 0xF2, 0x5D, 0x44, 0xEC, 0x68, 0xBE, 0xEF, 0xCA, 0x3E,
+ 0xDD, 0xDF, 0xF1, 0xB1, 0xF6, 0x2A, 0x30, 0x75, 0x97, 0x0C, 0xA8, 0xFE,
+ 0xA9, 0xE0, 0x08, 0x8D, 0xE4, 0x21, 0x46, 0x0D, 0x1E, 0xAF, 0x9E, 0x40,
+ 0x9F, 0x15, 0xE7, 0xB2, 0xE1, 0xD4, 0x52, 0x4E, 0xE2, 0x8E, 0xB7, 0xEC,
+ 0xDD, 0x10, 0x7A, 0x7C, 0xB2, 0x69, 0x88, 0xB5, 0x0F, 0x20, 0xD3, 0xCD,
+ 0xD1, 0xC0, 0xE8, 0x08, 0xB0, 0x62, 0x49, 0xE5, 0xD9, 0x60, 0x7A, 0x27,
+ 0xC4, 0xA9, 0x27, 0xEF, 0x4D, 0x56, 0x14, 0x40, 0x02, 0xBA, 0x8A, 0x74,
+ 0x0B, 0xD6, 0x24, 0xAA, 0xF0, 0xBA, 0x4A, 0xCE, 0x39, 0x1E, 0xBB, 0x1A,
+ 0xA5, 0x2C, 0x80, 0x9A, 0x2E, 0x8D, 0xCE, 0x6A, 0x31, 0xB7, 0x6E, 0x1C,
+ 0x0C, 0xF9, 0x75, 0x9C, 0x3D, 0x3E, 0x69, 0x27, 0x04, 0x38, 0x37, 0x9E,
+ 0xA8, 0xFF, 0x69, 0xF0, 0x48, 0x92, 0x6E, 0xCE, 0x3D, 0x0D, 0x81, 0x67,
+ 0xD2, 0x2B, 0x05, 0xB2, 0x89, 0x48, 0x81, 0x8C, 0xA6, 0x2F, 0x23, 0x48,
+ 0xB1, 0x95, 0xAD, 0xE1, 0xBB, 0x0F, 0xB3, 0x01, 0xCA, 0x58, 0x2E, 0x3D,
+ 0x96, 0xC5, 0x54, 0x69, 0xBC, 0xC4, 0x66, 0xBF, 0xE5, 0xAF, 0x90, 0x18,
+ 0xB9, 0x83, 0x76, 0x2C, 0x55, 0xA0, 0xDF, 0xFB, 0x77, 0x8B, 0x06, 0xF0,
+ 0x94, 0xD7, 0x6A, 0xA6, 0x7A, 0xAE, 0x1B, 0x2A, 0x3A, 0x3D, 0x11, 0xB6,
+ 0x8E, 0x0F, 0xA5, 0x0B, 0x51, 0x3D, 0xE1, 0xEE, 0xC6, 0x5C, 0x7C, 0x66,
+ 0x50, 0x17, 0xC3, 0x6E, 0xB0, 0x93, 0x02, 0x9F, 0xA4, 0x16, 0x48, 0x05,
+ 0x78, 0xA7, 0xF4, 0x60, 0xB1, 0xA2, 0x7B, 0xE7, 0x76, 0x2E, 0xCB, 0x43,
+ 0x7B, 0x35, 0x45, 0x7B, 0xB5, 0x77, 0x17, 0xB7, 0xE6, 0x5D, 0x1D, 0xD5,
+ 0x7E, 0xDC, 0xF0, 0x7B, 0xFD, 0xF4, 0x66, 0xCF, 0x64, 0x42, 0x90, 0x73,
+ 0x37, 0xF7, 0x06, 0x00, 0x88, 0x02, 0x1F, 0x67, 0x56, 0x08, 0x11, 0xC8,
+ 0x71, 0x54, 0xF1, 0x5B, 0x14, 0x34, 0x80, 0x58, 0x25, 0x09, 0x15, 0x10,
+ 0x02, 0x0D, 0xFE, 0x70, 0x74, 0xA0, 0x32, 0x67, 0xBE, 0x84, 0x5E, 0x25,
+ 0xE8, 0x1C, 0xB5, 0xD2, 0x29, 0xD5, 0x93, 0x47, 0xD7, 0x95, 0x6E, 0xBF,
+ 0x16, 0x69, 0xF0, 0xB1, 0x7F, 0x1A, 0x98, 0x0E, 0x40, 0x04, 0x7F, 0x1B,
+ 0xA2, 0x4F, 0x0E, 0x18, 0x20, 0x30, 0xB7, 0x75, 0x56, 0xD4, 0x3B, 0x43,
+ 0xB7, 0x7E, 0x85, 0xA0, 0x46, 0x14, 0x27, 0x4D, 0xEC, 0xB5, 0x08, 0xFA,
+ 0x74, 0x31, 0x5A, 0x15, 0x57, 0x8E, 0x12, 0x23, 0x27, 0x70, 0x7D, 0x73,
+ 0xD2, 0x1F, 0xB1, 0x81, 0x1E, 0x77, 0x91, 0x72, 0x01, 0x37, 0x08, 0xF9,
+ 0x67, 0x57, 0x52, 0x53, 0x3D, 0x79, 0x56, 0x40, 0xD5, 0xE5, 0x48, 0xE9,
+ 0xE1, 0x7F, 0x7A, 0x26, 0x6C, 0x45, 0x88, 0x0E, 0xB1, 0xF3, 0x79, 0x36,
+ 0xF6, 0x66, 0x92, 0x37, 0x2D, 0x12, 0x15, 0x80, 0x00, 0xA0, 0x4F, 0x05,
+ 0xE7, 0x5B, 0x64, 0x15, 0x7E, 0x17, 0x26, 0x85, 0x8B, 0x10, 0x2B, 0x1E,
+ 0x70, 0x2C, 0x8A, 0x58, 0x2C, 0x5E, 0x45, 0x00, 0x59, 0xB8, 0x2E, 0x88,
+ 0x35, 0x01, 0xC6, 0xF1, 0x15, 0x35, 0xA6, 0x1B, 0x2A, 0x87, 0x7C, 0xDF,
+ 0xF6, 0x26, 0x6C, 0x98, 0x5D, 0xA2, 0x11, 0x4D, 0xDE, 0x05, 0x2C, 0xB0,
+ 0xB6, 0x6E, 0x23, 0x58, 0x87, 0xE0, 0x00, 0x2D, 0x94, 0xE4, 0x7C, 0xF7,
+ 0xE2, 0x15, 0xD9, 0x86, 0x8A, 0x03, 0xB0, 0x53, 0xEA, 0x15, 0x1E, 0x5E,
+ 0x71, 0x27, 0xE9, 0x61, 0x83, 0x81, 0xB4, 0x64, 0x5C, 0xD3, 0x32, 0x99,
+ 0xF8, 0x27, 0x2E, 0x28, 0x35, 0x86, 0x60, 0x58, 0x23, 0x06, 0x1F, 0x2A,
+ 0x27, 0x30, 0x72, 0x48, 0x1A, 0xC0, 0xF3, 0x81, 0xD8, 0xB5, 0x1B, 0x84,
+ 0x71, 0x8C, 0xBB, 0x11, 0x5F, 0x47, 0x52, 0x85, 0xBA, 0x61, 0x71, 0x93,
+ 0x10, 0x1B, 0x30, 0x92, 0x56, 0x12, 0x90, 0x02, 0x09, 0x47, 0x8A, 0xC5,
+ 0x70, 0x87, 0x68, 0x87, 0x80, 0xFE, 0x28, 0xE4, 0x5D, 0x0F, 0xB6, 0x57,
+ 0x59, 0x16, 0x85, 0x05, 0x45, 0x08, 0x24, 0x67, 0x82, 0x5E, 0xC1, 0x6D,
+ 0x28, 0xE8, 0x15, 0xB7, 0x26, 0x00, 0x5E, 0xF5, 0x24, 0xA9, 0xA7, 0x29,
+ 0xB4, 0x66, 0x8C, 0x97, 0x07, 0x8C, 0x67, 0xF8, 0x71, 0x75, 0x45, 0x5B,
+ 0x54, 0xA1, 0x17, 0x28, 0x87, 0x3D, 0xAC, 0x37, 0x50, 0xE7, 0x48, 0x3C,
+ 0xF0, 0x61, 0x78, 0x90, 0x10, 0x83, 0x34, 0xD8, 0x6C, 0x4F, 0x86, 0x8D,
+ 0xC9, 0x60, 0x8A, 0x48, 0xF8, 0x15, 0x78, 0xB8, 0x23, 0xAD, 0xD3, 0x6E,
+ 0x44, 0x16, 0x1F, 0x02, 0x29, 0x3E, 0xDE, 0xC6, 0x8A, 0xCE, 0xE2, 0x68,
+ 0x40, 0x55, 0x88, 0x4A, 0x81, 0x15, 0x2A, 0xE5, 0x00, 0x2D, 0x60, 0x2C,
+ 0x26, 0x70, 0x35, 0xDD, 0x23, 0x00, 0xC8, 0xE6, 0x2C, 0x59, 0x82, 0x87,
+ 0x04, 0x15, 0x53, 0xD0, 0x06, 0x1E, 0x75, 0x36, 0x08, 0xFB, 0xD8, 0x2F,
+ 0xB5, 0x72, 0x01, 0x18, 0x99, 0x6D, 0x18, 0x66, 0x1F, 0xF5, 0x66, 0x18,
+ 0xAB, 0xD1, 0x6A, 0x08, 0xA9, 0x0B, 0xDA, 0x08, 0x7C, 0x69, 0xB1, 0x8E,
+ 0x74, 0xB3, 0x36, 0xDF, 0x28, 0x08, 0x01, 0xC6, 0x92, 0xB1, 0x48, 0x08,
+ 0x69, 0x08, 0x1E, 0xDE, 0x75, 0x65, 0x53, 0x18, 0x24, 0xFA, 0xE6, 0x78,
+ 0x17, 0x15, 0x8E, 0xF0, 0x11, 0x84, 0x8E, 0x58, 0x79, 0xBF, 0x18, 0x51,
+ 0x3D, 0x42, 0x08, 0x00, 0xD9, 0x60, 0x46, 0xA6, 0x70, 0x78, 0x17, 0x6B,
+ 0x6F, 0xC6, 0x5B, 0x2E, 0x96, 0x41, 0x8D, 0xC0, 0x77, 0x2E, 0xD8, 0x00,
+ 0xD7, 0xB8, 0x93, 0xBB, 0xA0, 0x90, 0x01, 0x52, 0x40, 0xC9, 0xE7, 0x34,
+ 0x0F, 0x89, 0x08, 0x84, 0x27, 0x76, 0x1B, 0x59, 0x08, 0x39, 0x08, 0x1E,
+ 0x35, 0xD5, 0x00, 0x34, 0x12, 0x01, 0x06, 0x88, 0x24, 0xBD, 0xB5, 0x82,
+ 0x1A, 0x46, 0x88, 0x43, 0x28, 0x47, 0xD5, 0xB8, 0xFE, 0x6C, 0x3E, 0xD6,
+ 0x4D, 0x2A, 0x33, 0x08, 0xB0, 0x07, 0x1E, 0x35, 0x49, 0x94, 0xA8, 0x32,
+ 0x2D, 0x06, 0x10, 0x33, 0x00, 0x44, 0x35, 0x34, 0x05, 0x98, 0xF7, 0x95,
+ 0x16, 0x1E, 0xF0, 0x91, 0xC6, 0xE2, 0x00, 0x67, 0xF5, 0x4B, 0x3A, 0xA9,
+ 0x96, 0xB4, 0xD0, 0x93, 0x1D, 0xA8, 0x73, 0x52, 0x14, 0x84, 0x43, 0xB9,
+ 0x92, 0x01, 0x79, 0x7F, 0x83, 0x10, 0x2B, 0x95, 0xD8, 0x55, 0x9A, 0x92,
+ 0x3A, 0x53, 0xB9, 0x36, 0x3B, 0x23, 0x28, 0xE9, 0x37, 0x87, 0x74, 0x42,
+ 0x8B, 0xA0, 0xC7, 0x8B, 0x7F, 0xE8, 0x1D, 0xB0, 0xF8, 0x82, 0x8E, 0xF9,
+ 0x5D, 0x7C, 0x12, 0x97, 0x3D, 0xA5, 0x68, 0x86, 0xA8, 0x08, 0xC5, 0xF6,
+ 0x63, 0xD1, 0xC4, 0x59, 0x69, 0x11, 0x02, 0x8F, 0x07, 0x9A, 0xB1, 0x60,
+ 0x8A, 0x40, 0x29, 0x00, 0x51, 0x23, 0x50, 0xB3, 0xF4, 0x6F, 0x0F, 0x48,
+ 0x80, 0xF8, 0x76, 0x8F, 0x90, 0xC6, 0x6F, 0x48, 0x79, 0x95, 0x7F, 0xB9,
+ 0x1F, 0x0E, 0x50, 0x70, 0xAD, 0x13, 0x22, 0xAC, 0x59, 0x70, 0x06, 0xF0,
+ 0x53, 0x6A, 0x91, 0x6D, 0x5E, 0x15, 0x53, 0x94, 0xA9, 0x64, 0x82, 0xF7,
+ 0x9B, 0x03, 0x00, 0x99, 0x0A, 0x04, 0x00, 0xB1, 0x73, 0x81, 0xA1, 0x87,
+ 0x08, 0xC5, 0xA6, 0x02, 0xE6, 0x69, 0x37, 0x69, 0x71, 0x01, 0xA3, 0xE8,
+ 0x9C, 0xB3, 0xF0, 0x5A, 0x3E, 0x09, 0x9C, 0x91, 0xC1, 0x00, 0x3F, 0xC5,
+ 0x01, 0x80, 0xC7, 0x1B, 0x42, 0xD9, 0x6F, 0x5A, 0x52, 0x72, 0xF9, 0x58,
+ 0x08, 0x02, 0xF3, 0x96, 0x19, 0xC2, 0x5F, 0x19, 0xB0, 0x8A, 0x0A, 0xAA,
+ 0x9A, 0xF4, 0xC9, 0x3C, 0x18, 0x22, 0x6B, 0x77, 0x11, 0x50, 0xE6, 0x58,
+ 0x9C, 0x24, 0x88, 0x8B, 0xC4, 0xD9, 0x70, 0x68, 0x78, 0x73, 0x3B, 0x12,
+ 0x5B, 0x63, 0xC1, 0x74, 0xDB, 0x69, 0x77, 0xC6, 0xF9, 0x15, 0x16, 0xFE,
+ 0x4A, 0x1A, 0x1C, 0xFA, 0x15, 0x27, 0xD0, 0x9C, 0x00, 0xCA, 0x0A, 0x11,
+ 0x47, 0x7A, 0x92, 0x46, 0x59, 0xA2, 0x41, 0x77, 0x79, 0x55, 0x7A, 0x85,
+ 0xA0, 0xA2, 0xE0, 0xB1, 0x67, 0x53, 0xE8, 0x15, 0xB5, 0x39, 0x50, 0xB7,
+ 0x94, 0x2C, 0x0E, 0xA0, 0x00, 0xB8, 0xC9, 0x5A, 0x57, 0x08, 0x8E, 0x8F,
+ 0x89, 0x21, 0xA7, 0xA1, 0x00, 0x1C, 0xA0, 0x02, 0x0A, 0xD0, 0x7D, 0xA8,
+ 0x28, 0x3D, 0x74, 0x45, 0x2E, 0x6A, 0xC8, 0x51, 0x83, 0xA0, 0x46, 0x12,
+ 0xDA, 0x9B, 0x24, 0x0A, 0x00, 0xE5, 0xE8, 0x1C, 0xC5, 0x98, 0x08, 0xC5,
+ 0x66, 0x9D, 0xFF, 0x17, 0x43, 0x04, 0xF0, 0x9F, 0x35, 0x1A, 0x52, 0x20,
+ 0xE8, 0x93, 0x0E, 0x74, 0x5D, 0xC1, 0xC2, 0xA3, 0x17, 0xFA, 0x27, 0xBD,
+ 0xA8, 0x9D, 0x6D, 0x62, 0x8B, 0x00, 0x30, 0x49, 0x74, 0x8A, 0x42, 0x75,
+ 0x76, 0x68, 0x22, 0x35, 0x30, 0x7D, 0xDA, 0x2F, 0xAD, 0x93, 0x31, 0x40,
+ 0x8A, 0x8C, 0x12, 0x02, 0x42, 0x50, 0xC8, 0x27, 0x51, 0x83, 0xA5, 0xF9,
+ 0x46, 0x8F, 0x75, 0xF9, 0x84, 0x5E, 0xE1, 0x01, 0x83, 0x3A, 0x45, 0xE8,
+ 0xC9, 0x9C, 0x6D, 0x8A, 0x0B, 0x37, 0x8A, 0x4D, 0xB3, 0x55, 0x67, 0x5F,
+ 0x12, 0x2C, 0x80, 0x87, 0x6C, 0xFF, 0x35, 0x9C, 0x4A, 0x79, 0x9F, 0x00,
+ 0x30, 0x4A, 0xB0, 0x59, 0x4A, 0x66, 0xB4, 0x36, 0x58, 0xDA, 0x38, 0x3B,
+ 0xAA, 0xAA, 0xA4, 0x21, 0x51, 0xBF, 0x25, 0x8C, 0xA9, 0xA9, 0x14, 0xAF,
+ 0x44, 0x7E, 0x5C, 0x12, 0x5E, 0xD7, 0x12, 0x46, 0x5A, 0x57, 0x8F, 0x58,
+ 0x97, 0x29, 0x08, 0xB0, 0xA4, 0x01, 0xE2, 0x02, 0xF5, 0xD3, 0x2C, 0x99,
+ 0x6A, 0x0B, 0x02, 0x0A, 0x31, 0x6C, 0x72, 0x37, 0x12, 0x40, 0x14, 0x05,
+ 0xA0, 0x34, 0x4B, 0xD8, 0x45, 0x59, 0x69, 0x08, 0x0F, 0x45, 0x2B, 0x74,
+ 0x38, 0x08, 0xFE, 0xEB, 0x43, 0x81, 0x52, 0xD4, 0x84, 0x0F, 0x8A, 0x9F,
+ 0x3E, 0x56, 0xA4, 0x90, 0x19, 0x5B, 0x71, 0x67, 0x3A, 0xDE, 0xD9, 0x1C,
+ 0xB5, 0x85, 0xAD, 0x8B, 0xBA, 0x23, 0x44, 0x67, 0x61, 0xB0, 0xD5, 0x95,
+ 0x8B, 0x60, 0x74, 0x0C, 0xE9, 0x34, 0x06, 0x70, 0x5D, 0x6B, 0x7A, 0xAC,
+ 0xB5, 0xB0, 0xA9, 0x4C, 0xE8, 0x81, 0x84, 0xF0, 0x6A, 0x01, 0x22, 0xAA,
+ 0xB5, 0xA6, 0x8E, 0xFA, 0x67, 0x99, 0x85, 0x00, 0x45, 0x09, 0xCA, 0x27,
+ 0xDC, 0x6A, 0xAB, 0x8A, 0xB0, 0x31, 0x5F, 0xE1, 0x00, 0xC2, 0xCA, 0x27,
+ 0xC4, 0xFA, 0x15, 0x52, 0xC5, 0xAB, 0x56, 0x73, 0x94, 0xE8, 0xAA, 0x8C,
+ 0xFD, 0x6A, 0x72, 0x8A, 0xF9, 0x47, 0xB1, 0x37, 0x8E, 0x8C, 0xA0, 0xB0,
+ 0x26, 0x54, 0xB0, 0xCF, 0x18, 0x43, 0xEC, 0x67, 0xAF, 0xAC, 0x90, 0xAC,
+ 0x01, 0x42, 0x84, 0x9D, 0x54, 0x54, 0x18, 0x12, 0x33, 0xDF, 0x78, 0x97,
+ 0xC3, 0xD5, 0xA4, 0xA6, 0xA3, 0x3F, 0x20, 0x1B, 0x20, 0x79, 0xD9, 0xB1,
+ 0x48, 0xB4, 0x34, 0x72, 0xE3, 0x34, 0x6F, 0x27, 0x32, 0x86, 0xB0, 0x95,
+ 0xCE, 0x21, 0x48, 0x0B, 0x54, 0xB1, 0xF3, 0x18, 0x94, 0xD3, 0x7A, 0xAA,
+ 0xBC, 0x39, 0x96, 0x97, 0x84, 0x65, 0x93, 0x1A, 0x9D, 0xD2, 0xE4, 0x2D,
+ 0xF1, 0x48, 0xB2, 0xAA, 0x80, 0xAF, 0x95, 0x89, 0xB0, 0xAE, 0xFA, 0x95,
+ 0xB9, 0xA8, 0x14, 0x9E, 0xD5, 0x80, 0xE2, 0x68, 0x2B, 0x45, 0x07, 0xAC,
+ 0x68, 0x0A, 0x7C, 0xDE, 0x82, 0x01, 0xE3, 0x95, 0x53, 0x00, 0xD5, 0x02,
+ 0x21, 0x49, 0x73, 0xD9, 0x83, 0x39, 0x5A, 0x54, 0x95, 0x86, 0xF0, 0x8A,
+ 0xB8, 0x03, 0xA2, 0x00, 0x00, 0x2D, 0x0D, 0xE9, 0x2F, 0x3E, 0x8A, 0x88,
+ 0x83, 0xF9, 0x9E, 0x8F, 0xB0, 0x76, 0x08, 0xD0, 0x3E, 0xD5, 0x19, 0x9D,
+ 0xD7, 0xF5, 0xB4, 0x50, 0x7B, 0xFE, 0x0A, 0x26, 0x3B, 0xB5, 0x03, 0x10,
+ 0x80, 0xE9, 0xA1, 0xAD, 0x9A, 0x56, 0xB4, 0x5D, 0x7A, 0xB4, 0x5C, 0x89,
+ 0xB7, 0x48, 0xA9, 0x2B, 0x07, 0xA4, 0xB3, 0xFF, 0xE4, 0x3A, 0x24, 0x73,
+ 0x80, 0x86, 0x81, 0xA4, 0xC9, 0x32, 0x25, 0x33, 0x5A, 0x74, 0x00, 0xA5,
+ 0x24, 0x56, 0xE8, 0x9B, 0x2E, 0xA9, 0xB1, 0xF3, 0xE2, 0x15, 0xAF, 0x44,
+ 0xAA, 0xCA, 0xA7, 0x57, 0x24, 0xA3, 0x2B, 0x00, 0x02, 0x32, 0x94, 0x88,
+ 0x79, 0x99, 0x07, 0xB1, 0x81, 0xFB, 0x0A, 0x52, 0xEB, 0x1C, 0x15, 0x85,
+ 0x75, 0xE5, 0xBA, 0xA2, 0xD8, 0x49, 0x08, 0x6E, 0xFB, 0xB2, 0x64, 0x59,
+ 0x74, 0x70, 0xD3, 0x76, 0x5F, 0xE3, 0x1B, 0x6A, 0x31, 0xB2, 0x8C, 0x10,
+ 0x01, 0x37, 0xBB, 0x8B, 0x3D, 0x92, 0x70, 0x54, 0x27, 0x2B, 0x56, 0x6A,
+ 0x52, 0x02, 0x1B, 0xBA, 0x56, 0x5B, 0xAB, 0x49, 0x9B, 0xA1, 0x4F, 0xEA,
+ 0x6B, 0xA6, 0xFA, 0x08, 0x1E, 0xDB, 0x3B, 0x23, 0xE5, 0xBA, 0xBA, 0x81,
+ 0x6C, 0xE0, 0x13, 0xBB, 0xAD, 0x30, 0xB8, 0xE0, 0x25, 0x75, 0xEA, 0x94,
+ 0xAE, 0x1B, 0xFB, 0x4B, 0x3D, 0x2B, 0x95, 0x74, 0x99, 0x6C, 0x32, 0x77,
+ 0xBC, 0x7E, 0xC7, 0x3D, 0x58, 0x23, 0x18, 0xB4, 0x24, 0xA5, 0x93, 0xEB,
+ 0x15, 0x0D, 0x90, 0x81, 0x32, 0x27, 0x1B, 0xEF, 0xA8, 0x29, 0xAB, 0x91,
+ 0x96, 0xDB, 0x87, 0xB3, 0x8F, 0xE3, 0x4E, 0x7E, 0x01, 0x75, 0xE3, 0x8B,
+ 0xBA, 0x60, 0xB6, 0x61, 0x34, 0xA4, 0xA7, 0x1A, 0x73, 0x93, 0x86, 0x91,
+ 0x01, 0x34, 0x87, 0x6C, 0x43, 0x09, 0xBE, 0xA5, 0xB0, 0x3E, 0xD1, 0x29,
+ 0x8A, 0xB6, 0x4B, 0xC0, 0xAF, 0x3B, 0x76, 0x85, 0x20, 0xB1, 0xD2, 0x1B,
+ 0xB4, 0xBF, 0x8A, 0xBC, 0xE7, 0x45, 0x76, 0x30, 0xE8, 0x28, 0x5F, 0xB8,
+ 0xBF, 0x2B, 0x78, 0x02, 0x12, 0x90, 0x96, 0x9D, 0xFE, 0x94, 0x02, 0xC7,
+ 0xEB, 0x63, 0xDF, 0xE3, 0x59, 0xE2, 0xD6, 0x96, 0x4E, 0x38, 0x08, 0x63,
+ 0xDA, 0x1C, 0x65, 0x9A, 0x4F, 0x12, 0x20, 0x83, 0x0D, 0xE0, 0x56, 0x16,
+ 0x40, 0x24, 0x03, 0xE7, 0x21, 0x91, 0x92, 0x9E, 0x78, 0xA9, 0xAF, 0x12,
+ 0x9C, 0x0A, 0x18, 0x49, 0x7F, 0xA9, 0xE6, 0xAE, 0x86, 0xD0, 0x35, 0x2B,
+ 0x6B, 0x8B, 0xEE, 0xD5, 0xB0, 0x93, 0x41, 0xBE, 0x7D, 0x86, 0x7A, 0x20,
+ 0xEC, 0x21, 0xFE, 0x75, 0x0A, 0x9D, 0x16, 0x57, 0x11, 0xF0, 0x99, 0x32,
+ 0xC7, 0x44, 0x9B, 0x22, 0x80, 0x05, 0x77, 0x75, 0x32, 0x75, 0x3E, 0x02,
+ 0xD6, 0xAD, 0xAC, 0x96, 0x1F, 0x38, 0x79, 0x3F, 0x7F, 0x98, 0x29, 0xCD,
+ 0xAA, 0x55, 0x54, 0x07, 0x6B, 0xB5, 0x12, 0xC1, 0x45, 0x2C, 0x0A, 0x14,
+ 0x7C, 0xB1, 0xA0, 0x9B, 0x8E, 0xA2, 0x7B, 0xB5, 0xEC, 0x4B, 0xC3, 0xB8,
+ 0x41, 0x6A, 0x66, 0x9C, 0xB0, 0x16, 0xF0, 0xBF, 0x75, 0x52, 0x26, 0xCB,
+ 0xC0, 0x4C, 0x77, 0x41, 0x6B, 0x26, 0xFA, 0xB6, 0x83, 0xB4, 0xC1, 0xA2,
+ 0xD1, 0xAB, 0x4A, 0x81, 0x34, 0x64, 0x7B, 0x19, 0x20, 0x52, 0x01, 0xC7,
+ 0x31, 0xAE, 0x84, 0x50, 0x01, 0x4A, 0xD3, 0x9A, 0x05, 0x0A, 0xB3, 0x73,
+ 0xFC, 0xAE, 0x5D, 0x08, 0x6A, 0xF8, 0x2B, 0x08, 0x47, 0x1C, 0x20, 0x41,
+ 0xF8, 0xB4, 0x4C, 0xBC, 0xB5, 0x88, 0x85, 0x9A, 0x41, 0x8A, 0xA1, 0x1D,
+ 0x4B, 0xC2, 0x33, 0x88, 0x17, 0x6C, 0x45, 0x01, 0x97, 0xA5, 0xC2, 0xC7,
+ 0x10, 0x1B, 0x37, 0xAB, 0x5B, 0x5C, 0x47, 0xB8, 0xB9, 0x2B, 0x08, 0xEC,
+ 0xCA, 0xA4, 0x45, 0xB4, 0x3B, 0x82, 0x6C, 0x18, 0x88, 0xD1, 0x2E, 0xDE,
+ 0x5A, 0xBD, 0xBB, 0xA1, 0x63, 0x9D, 0xBC, 0x32, 0x68, 0x7C, 0x17, 0x6A,
+ 0xDC, 0x08, 0x75, 0x2C, 0x91, 0x9C, 0x3C, 0x08, 0x61, 0x66, 0xC7, 0xFE,
+ 0x1C, 0x6B, 0x8F, 0xC6, 0x9C, 0xC1, 0xF7, 0x82, 0x0F, 0xE7, 0xA1, 0x1D,
+ 0x48, 0x43, 0x85, 0xB1, 0xA9, 0xB8, 0x82, 0x90, 0x68, 0xCE, 0x81, 0xCC,
+ 0x82, 0x00, 0xAF, 0x48, 0xA2, 0x00, 0x1A, 0xB0, 0x3D, 0xB7, 0x94, 0x30,
+ 0x07, 0x69, 0x08, 0x92, 0x82, 0x6A, 0xE6, 0xE2, 0xC1, 0xC9, 0x0C, 0x42,
+ 0x96, 0x7B, 0xC8, 0xB4, 0x3C, 0xCA, 0x1C, 0xC6, 0xCA, 0x84, 0x70, 0xCA,
+ 0x1A, 0xC9, 0xA2, 0x83, 0x10, 0x5C, 0xD8, 0xA3, 0x01, 0x05, 0x44, 0xCB,
+ 0xED, 0x30, 0x01, 0x14, 0xA6, 0x4F, 0x24, 0xD5, 0x8F, 0xA5, 0xE1, 0x48,
+ 0xBD, 0x92, 0x94, 0x66, 0xD4, 0xA4, 0xD9, 0x3B, 0x30, 0xDC, 0x2B, 0x19,
+ 0x0C, 0x20, 0x56, 0xC2, 0x7C, 0x25, 0xA2, 0x97, 0xC7, 0xFE, 0xB8, 0xC8,
+ 0xF3, 0xBC, 0x3B, 0x2D, 0xBC, 0x1F, 0x68, 0x79, 0x99, 0x4A, 0xE1, 0xB7,
+ 0xD1, 0x2C, 0x08, 0xD3, 0xAC, 0x82, 0x1A, 0x3C, 0x08, 0x87, 0x6A, 0x66,
+ 0x26, 0x50, 0xBF, 0x7E, 0xA8, 0x0F, 0x8F, 0x08, 0x2F, 0x27, 0xB2, 0x47,
+ 0xA4, 0x4B, 0xAD, 0x15, 0x89, 0x95, 0x78, 0xAB, 0x2E, 0x94, 0x8A, 0x76,
+ 0x1C, 0xD0, 0x99, 0x98, 0xD1, 0xC3, 0xB1, 0x13, 0x8A, 0x52, 0x5C, 0xC4,
+ 0xE6, 0x4C, 0x89, 0x98, 0xEB, 0xD3, 0x27, 0x90, 0x55, 0xF8, 0xFC, 0xA1,
+ 0x54, 0x7B, 0x08, 0xFC, 0x7C, 0xBE, 0x31, 0x55, 0x9F, 0x92, 0x61, 0x3C,
+ 0x97, 0x21, 0x64, 0xFC, 0xF0, 0xC3, 0xAA, 0x07, 0x02, 0x8D, 0x8A, 0x34,
+ 0x9E, 0x87, 0x98, 0x85, 0x2B, 0xB4, 0xA4, 0xC4, 0x25, 0xCA, 0x49, 0x27,
+ 0xCE, 0x68, 0x89, 0xBE, 0xDA, 0xC9, 0xF9, 0x13, 0x2C, 0x0A, 0xC0, 0x3F,
+ 0x07, 0x63, 0x65, 0xC4, 0x1B, 0x95, 0x18, 0xEC, 0x9A, 0x77, 0x1C, 0x4C,
+ 0xAA, 0x48, 0xCD, 0x7B, 0x3C, 0x63, 0x2D, 0x53, 0xD1, 0x29, 0x06, 0x16,
+ 0xED, 0x1C, 0xFE, 0x10, 0x92, 0x18, 0xCC, 0x06, 0xAC, 0x55, 0x78, 0x3A,
+ 0x45, 0x7A, 0x17, 0x3B, 0xA9, 0x3A, 0x2D, 0x63, 0x6D, 0x18, 0x0D, 0x49,
+ 0x5C, 0x1D, 0x7D, 0xAA, 0xBA, 0x32, 0xD1, 0x4F, 0x23, 0x3A, 0x69, 0xB1,
+ 0xB9, 0x87, 0x80, 0x91, 0x88, 0x6B, 0x66, 0x35, 0x7D, 0x8B, 0x13, 0x85,
+ 0xCA, 0x84, 0xB0, 0xBC, 0x56, 0xF6, 0x41, 0x0A, 0x71, 0x1F, 0x27, 0x60,
+ 0xC2, 0x95, 0x85, 0x34, 0x59, 0x97, 0xC0, 0xDC, 0xB9, 0xA7, 0xAF, 0xEA,
+ 0xA7, 0x16, 0x9D, 0x16, 0xA7, 0x58, 0xC0, 0xE8, 0x3B, 0xCF, 0x18, 0xB9,
+ 0x34, 0x83, 0x6A, 0x00, 0x92, 0x8D, 0x17, 0xF3, 0x15, 0xD7, 0xBA, 0x81,
+ 0xA2, 0x17, 0xAC, 0x14, 0x16, 0x2A, 0xC6, 0x46, 0x5B, 0xD5, 0x4A, 0x24,
+ 0x11, 0xF2, 0xF4, 0x61, 0x14, 0x36, 0x97, 0x3B, 0x47, 0xB5, 0xA3, 0x34,
+ 0xB7, 0x53, 0xA6, 0x01, 0xEB, 0x2C, 0xA2, 0x43, 0xFC, 0xCB, 0xC9, 0xAC,
+ 0x34, 0x87, 0xBD, 0x23, 0x1B, 0xF0, 0x53, 0x6C, 0xDB, 0x67, 0x2A, 0x9B,
+ 0xCF, 0x4D, 0xBD, 0xC4, 0x08, 0xDC, 0xCF, 0x31, 0xF5, 0x61, 0xAD, 0x82,
+ 0x11, 0x9E, 0x04, 0xCE, 0x19, 0xAB, 0x14, 0x50, 0x7C, 0xAE, 0xD0, 0xA2,
+ 0xC9, 0x7A, 0xB4, 0x01, 0xDA, 0x23, 0xC3, 0xCF, 0x37, 0xCF, 0xC2, 0x54,
+ 0xDD, 0x7C, 0xA2, 0x79, 0xB0, 0x6B, 0xD3, 0xBA, 0x5D, 0x1A, 0xBC, 0x7D,
+ 0x08, 0x2D, 0x64, 0xA1, 0x12, 0x35, 0x32, 0x8A, 0xB5, 0x49, 0x5C, 0xEC,
+ 0x10, 0xF7, 0x71, 0xC5, 0xE0, 0xA7, 0x14, 0xCD, 0xDB, 0x25, 0x14, 0xBB,
+ 0xBB, 0x53, 0x29, 0x92, 0x4C, 0xBB, 0x23, 0xEB, 0x16, 0xCA, 0xCE, 0x99,
+ 0x1E, 0x41, 0xB4, 0x3A, 0xD0, 0x73, 0xDF, 0x44, 0x65, 0xBE, 0x02, 0x92,
+ 0xD9, 0x77, 0x77, 0x7B, 0x56, 0x03, 0x53, 0x83, 0x80, 0x29, 0xCD, 0x9C,
+ 0x12, 0x54, 0xE7, 0x20, 0xB4, 0xFE, 0x08, 0xB4, 0xE5, 0xCC, 0xB8, 0xFD,
+ 0x34, 0xB9, 0x49, 0xFA, 0xB5, 0xA8, 0x9D, 0xCD, 0xC9, 0x7C, 0xD2, 0xFD,
+ 0xF3, 0x4F, 0xBA, 0xD5, 0x6B, 0xD0, 0x3C, 0xD7, 0x8B, 0xAB, 0xD1, 0x36,
+ 0x56, 0xBF, 0x17, 0x30, 0xE0, 0x22, 0x41, 0x83, 0xF5, 0xE4, 0xB9, 0x63,
+ 0x66, 0x88, 0x47, 0x72, 0xD9, 0x91, 0xA1, 0xA3, 0x69, 0xA1, 0x02, 0x21,
+ 0xE9, 0x34, 0xB5, 0x02, 0xB8, 0x24, 0x9B, 0x25, 0xEC, 0x2D, 0x2A, 0xD7,
+ 0xA5, 0x3B, 0x96, 0x4D, 0xCA, 0x6B, 0xF3, 0xB4, 0x2A, 0xD5, 0x25, 0x3C,
+ 0x2E, 0xC2, 0x29, 0xE1, 0xC5, 0x97, 0x91, 0x88, 0x57, 0xB8, 0x89, 0xE5,
+ 0x32, 0x80, 0x1E, 0x19, 0x92, 0x09, 0xEA, 0x7A, 0x45, 0xEC, 0x19, 0xD6,
+ 0xEC, 0xDB, 0xB0, 0x2A, 0xAE, 0x44, 0x62, 0xE3, 0xBA, 0x7C, 0x43, 0xFA,
+ 0x94, 0x38, 0xFE, 0xF4, 0x2D, 0x5C, 0xDE, 0x12, 0x86, 0x3C, 0x26, 0x42,
+ 0x3B, 0xB7, 0xDE, 0x55, 0x59, 0x41, 0x4C, 0x27, 0x48, 0x1C, 0x63, 0x0A,
+ 0x6C, 0xAF, 0x1B, 0x23, 0xB6, 0x80, 0x08, 0xAB, 0xEC, 0x18, 0x38, 0x19,
+ 0xFE, 0x68, 0x08, 0x74, 0xE5, 0x7E, 0x34, 0x51, 0x75, 0x0E, 0x4A, 0xE8,
+ 0x98, 0x13, 0x0B, 0x72, 0x19, 0x5F, 0x24, 0xE6, 0x85, 0x87, 0xB1, 0x68,
+ 0xC8, 0xC2, 0x23, 0x05, 0x78, 0x75, 0x76, 0xE7, 0x6A, 0x99, 0xD6, 0xCD,
+ 0x86, 0x89, 0x88, 0x2E, 0x9D, 0xF6, 0xCB, 0x7F, 0xB7, 0x5B, 0x7E, 0xD3,
+ 0x3B, 0xA4, 0x74, 0x61, 0x65, 0x6D, 0x6C, 0x14, 0xDB, 0x9C, 0x16, 0x5B,
+ 0x83, 0xE9, 0xF8, 0x98, 0x98, 0x69, 0x24, 0x01, 0x9F, 0x04, 0xAE, 0x29,
+ 0x12, 0x73, 0xB1, 0x6B, 0x96, 0xB9, 0xC6, 0xE8, 0x88, 0x6E, 0x7F, 0xB6,
+ 0xFE, 0x71, 0xDB, 0xFD, 0xCD, 0xDD, 0x0D, 0xA1, 0x38, 0xF9, 0xEA, 0xE3,
+ 0x60, 0x03, 0x32, 0x80, 0x03, 0xBA, 0xB1, 0x02, 0xFE, 0x3C, 0x10, 0x03,
+ 0xD8, 0x30, 0x01, 0x86, 0x09, 0xE3, 0x82, 0x80, 0x64, 0x79, 0xD7, 0xBB,
+ 0x89, 0x10, 0xA8, 0x46, 0x2E, 0x00, 0x8E, 0x44, 0xD0, 0x3B, 0x69, 0x79,
+ 0x1A, 0x8A, 0x36, 0xB5, 0x54, 0x2C, 0x2E, 0x6E, 0x66, 0x08, 0x47, 0x91,
+ 0xF9, 0x4D, 0xB7, 0xAB, 0xAE, 0xA8, 0x92, 0x4E, 0xA3, 0xD5, 0xE0, 0x03,
+ 0xF0, 0xB1, 0x02, 0x3D, 0xA0, 0x0D, 0xB1, 0xF1, 0x46, 0xDE, 0x0C, 0xA9,
+ 0x76, 0xD6, 0x5E, 0xEA, 0x12, 0x9D, 0xE1, 0x25, 0xCF, 0x80, 0xF2, 0x69,
+ 0xD7, 0x77, 0x7D, 0x97, 0x05, 0xEF, 0x64, 0xC3, 0xC0, 0xA4, 0x49, 0x2D,
+ 0x5A, 0x94, 0x01, 0xCC, 0x9D, 0x87, 0x55, 0x61, 0x23, 0x87, 0x6B, 0xE5,
+ 0xFA, 0x0C, 0xBD, 0x1E, 0xA2, 0xEC, 0xE4, 0x70, 0x03, 0xBA, 0xD1, 0x01,
+ 0x10, 0x70, 0x00, 0xA5, 0xB1, 0x03, 0xE0, 0xF0, 0xC4, 0xEB, 0x3B, 0xE9,
+ 0x4E, 0x6A, 0xB1, 0x23, 0x7A, 0x2F, 0xE3, 0x95, 0x2E, 0x9A, 0x0B, 0xEE,
+ 0x34, 0xF3, 0x2B, 0x94, 0x28, 0x43, 0x53, 0x54, 0xBF, 0x74, 0x51, 0xA9,
+ 0x8E, 0x24, 0x4E, 0xC2, 0x64, 0x9D, 0xAD, 0x23, 0xE7, 0x15, 0x6F, 0xF0,
+ 0xD5, 0x80, 0xF1, 0x92, 0x71, 0x00, 0x23, 0x10, 0x00, 0x40, 0x1F, 0x00,
+ 0x24, 0xB0, 0x00, 0x1C, 0x1F, 0x19, 0x1E, 0xFF, 0x0D, 0x59, 0x82, 0xB8,
+ 0xB1, 0x65, 0xF1, 0xA2, 0x0C, 0x2C, 0x5F, 0x7A, 0x9D, 0x6F, 0xDD, 0x49,
+ 0x08, 0x7F, 0x17, 0x21, 0xED, 0x51, 0x11, 0x1D, 0x2D, 0x89, 0xBE, 0x5A,
+ 0x81, 0x45, 0x27, 0x2F, 0x1A, 0x19, 0xB9, 0xB4, 0xCF, 0x1A, 0xEE, 0x6B,
+ 0x0B, 0x2A, 0x97, 0x4C, 0x4F, 0x0E, 0xF2, 0x2E, 0x19, 0x2F, 0x90, 0x00,
+ 0x41, 0xBF, 0xF6, 0x09, 0xD0, 0x01, 0x92, 0x71, 0xF4, 0xDD, 0x20, 0x68,
+ 0xA5, 0x9A, 0x44, 0x72, 0x55, 0x01, 0x21, 0x04, 0xAC, 0xD1, 0xC9, 0xFE,
+ 0x47, 0xE6, 0x8D, 0x6F, 0x9E, 0x4D, 0x27, 0x2F, 0x4D, 0x33, 0xA2, 0x0E,
+ 0xDD, 0x05, 0x14, 0x54, 0x9E, 0xCA, 0x16, 0x64, 0xF8, 0x15, 0xC3, 0xF8,
+ 0xD0, 0x8A, 0x5B, 0xF3, 0x34, 0x5B, 0x45, 0xF2, 0xB0, 0x03, 0x92, 0xD1,
+ 0x01, 0x1F, 0xB0, 0xF6, 0x94, 0x1F, 0x00, 0x6D, 0x2F, 0x19, 0x3E, 0xF0,
+ 0x0D, 0x14, 0xFE, 0xC0, 0xEB, 0x82, 0x00, 0x7D, 0x5A, 0x40, 0x2B, 0xE6,
+ 0xEB, 0x3E, 0x96, 0xA4, 0x21, 0xC9, 0x00, 0x26, 0x40, 0x4D, 0x47, 0x03,
+ 0x47, 0x9D, 0x83, 0x6D, 0xA4, 0x21, 0xEC, 0x41, 0x55, 0x2B, 0xF5, 0xDA,
+ 0xA5, 0xEF, 0x92, 0xF8, 0xBB, 0xE7, 0xF8, 0xE1, 0x1C, 0xF6, 0x68, 0x33,
+ 0xF6, 0xC9, 0x50, 0x03, 0x35, 0x60, 0x03, 0xA4, 0x60, 0x03, 0x2B, 0x10,
+ 0x19, 0x1D, 0xA0, 0xF6, 0x95, 0x4F, 0xF9, 0x97, 0x6F, 0xF4, 0xDE, 0x80,
+ 0xD0, 0x0F, 0xEC, 0xD3, 0x31, 0x8F, 0x21, 0x75, 0x26, 0xF2, 0xA2, 0x7C,
+ 0x93, 0x25, 0xE5, 0x6B, 0x26, 0x10, 0x43, 0x62, 0xBB, 0x41, 0x7A, 0x6B,
+ 0x55, 0x41, 0x48, 0xD3, 0x70, 0xFB, 0x71, 0xC5, 0xF6, 0xA2, 0xA6, 0x49,
+ 0xD7, 0xEB, 0x2E, 0x18, 0x53, 0x7E, 0x0C, 0x35, 0x70, 0x03, 0xC1, 0x1F,
+ 0x19, 0x38, 0xF0, 0x03, 0xBE, 0xFF, 0x09, 0x31, 0x90, 0xFE, 0xC3, 0x5F,
+ 0xFC, 0xC5, 0x9F, 0x00, 0x10, 0x10, 0x19, 0x2B, 0xD0, 0xFE, 0xDC, 0xA0,
+ 0x58, 0x9E, 0xAF, 0x94, 0x72, 0xFA, 0xB1, 0x44, 0xCB, 0xD1, 0x80, 0x00,
+ 0x20, 0x38, 0x28, 0x38, 0x81, 0x31, 0x80, 0x98, 0xC8, 0xB1, 0x21, 0xD0,
+ 0xE8, 0xF8, 0xE8, 0x68, 0xD0, 0x92, 0x88, 0x88, 0x51, 0x40, 0x88, 0x99,
+ 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, 0x09, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A,
+ 0x6A, 0x7A, 0x8A, 0xFA, 0x19, 0x42, 0x39, 0xE0, 0xC1, 0x08, 0xD9, 0x08,
+ 0x82, 0x80, 0xFE, 0xE8, 0xC8, 0x90, 0x48, 0xC0, 0x99, 0xC2, 0xEA, 0x02,
+ 0xDB, 0x2B, 0xA0, 0x40, 0x59, 0x41, 0x78, 0x91, 0xE8, 0xE0, 0x2B, 0xB0,
+ 0xC1, 0xC1, 0x8A, 0x78, 0x92, 0xEA, 0xFC, 0x0C, 0x20, 0x73, 0x8C, 0xF3,
+ 0xA3, 0x03, 0x4D, 0x98, 0xD3, 0x28, 0x12, 0xC0, 0xDD, 0xED, 0xFD, 0xCD,
+ 0x9D, 0x70, 0xD0, 0x98, 0x73, 0x6D, 0x7E, 0x1E, 0x7A, 0xC2, 0x6A, 0x72,
+ 0xDC, 0xB8, 0x61, 0xE2, 0x90, 0x81, 0xE8, 0xA1, 0x62, 0xF2, 0xDA, 0xFE,
+ 0xA8, 0x9C, 0x18, 0xC1, 0x59, 0x42, 0xC0, 0xEA, 0x00, 0x04, 0x3E, 0x58,
+ 0x0C, 0x66, 0x25, 0x6A, 0x80, 0x2E, 0xA1, 0xC2, 0x85, 0x0C, 0x1B, 0x3A,
+ 0xF4, 0x54, 0x80, 0x02, 0x40, 0x03, 0xED, 0x5C, 0x20, 0x7A, 0x65, 0xE2,
+ 0x60, 0x27, 0x5D, 0x89, 0x10, 0xDC, 0x6B, 0x67, 0xC0, 0xE0, 0x80, 0x10,
+ 0x84, 0x2C, 0x50, 0xE2, 0x05, 0x29, 0xD9, 0x32, 0x44, 0x14, 0x84, 0x3D,
+ 0x5C, 0xC8, 0x63, 0xA0, 0x80, 0x1B, 0xD6, 0xA0, 0x49, 0x13, 0xD0, 0x21,
+ 0x01, 0xB8, 0x9D, 0xDF, 0x60, 0x38, 0x92, 0xF1, 0x32, 0xA8, 0xA9, 0x02,
+ 0x87, 0x28, 0x39, 0xF8, 0x28, 0x33, 0x69, 0x2D, 0x4A, 0x14, 0x38, 0x99,
+ 0xA4, 0x84, 0x80, 0x9D, 0xD2, 0x47, 0xB2, 0x28, 0x49, 0x10, 0x8A, 0x35,
+ 0xAB, 0xD6, 0xAD, 0xE8, 0x8A, 0x2A, 0x92, 0xA9, 0x61, 0x00, 0x83, 0x46,
+ 0x61, 0x11, 0x21, 0xEC, 0x24, 0x31, 0x91, 0x87, 0xA4, 0xFA, 0x06, 0x5C,
+ 0xC0, 0x44, 0x0C, 0x51, 0x86, 0x47, 0x06, 0x14, 0x88, 0x64, 0xEA, 0x92,
+ 0xEB, 0xB3, 0x9B, 0x28, 0x16, 0x2C, 0x80, 0x80, 0x42, 0x84, 0x08, 0x14,
+ 0xB0, 0x64, 0xC4, 0x70, 0x66, 0xA3, 0xD1, 0x01, 0x9D, 0x3C, 0x1B, 0x73,
+ 0x13, 0xE1, 0xC8, 0x86, 0xDE, 0xC9, 0x83, 0x22, 0x2E, 0x5B, 0x34, 0x75,
+ 0xAA, 0x3C, 0x44, 0x04, 0x2E, 0xFE, 0x69, 0x7A, 0xAA, 0x56, 0x60, 0x66,
+ 0xAA, 0x77, 0x27, 0x50, 0x3E, 0x8D, 0x3A, 0xB5, 0x50, 0x8E, 0x89, 0x44,
+ 0x0F, 0xE4, 0x30, 0x56, 0x80, 0xAD, 0x44, 0x9F, 0x1A, 0x50, 0x52, 0x20,
+ 0x13, 0x04, 0x25, 0xD3, 0x83, 0x40, 0x0F, 0xD0, 0x20, 0xA0, 0xEE, 0xDD,
+ 0x44, 0x2D, 0x55, 0x9F, 0xB2, 0xB1, 0x42, 0x00, 0x0B, 0xC6, 0xDF, 0x48,
+ 0x8C, 0x60, 0xF1, 0x68, 0xC5, 0x0F, 0xC9, 0xA6, 0x62, 0x64, 0x3B, 0xF0,
+ 0xC1, 0xB1, 0xF6, 0x00, 0xD0, 0x05, 0x94, 0x33, 0xBE, 0x55, 0xC2, 0x4A,
+ 0x0E, 0xAE, 0x8F, 0x31, 0x68, 0xE1, 0x01, 0xF8, 0x40, 0x60, 0x89, 0x2C,
+ 0x6C, 0x4A, 0x5B, 0x8C, 0xE2, 0x68, 0x48, 0x16, 0x35, 0x82, 0xBF, 0x8F,
+ 0x3F, 0xBF, 0x28, 0xF8, 0x03, 0x10, 0xC8, 0x1F, 0xF8, 0x8A, 0x01, 0x94,
+ 0xB8, 0xD7, 0x49, 0x01, 0xFF, 0x20, 0xE2, 0x91, 0x4C, 0x22, 0xA5, 0x00,
+ 0x57, 0x22, 0x19, 0xD8, 0xB5, 0x52, 0x71, 0xFA, 0x85, 0x12, 0x03, 0x0E,
+ 0x02, 0xCC, 0xB0, 0x1D, 0x09, 0x0B, 0x8C, 0xE3, 0x08, 0x0E, 0x3B, 0x94,
+ 0xF2, 0x43, 0x23, 0x30, 0x6C, 0xA7, 0x1D, 0x09, 0x8E, 0x7C, 0x38, 0xE1,
+ 0x4B, 0x86, 0xAC, 0x94, 0x41, 0x0B, 0x2E, 0xDC, 0x03, 0x02, 0x03, 0x0A,
+ 0xA8, 0x60, 0xD0, 0x5C, 0x00, 0x52, 0x72, 0x56, 0x26, 0xBE, 0x0D, 0xC0,
+ 0xC1, 0x7C, 0xBE, 0x4C, 0xB2, 0x4F, 0x8A, 0x42, 0x0E, 0x79, 0x9F, 0x3A,
+ 0x6A, 0xFD, 0x97, 0x94, 0x07, 0x89, 0xBC, 0xE5, 0x49, 0x04, 0x94, 0xF4,
+ 0x38, 0x90, 0x0A, 0xC4, 0x61, 0xB2, 0xE3, 0x32, 0x12, 0x12, 0xD9, 0x09,
+ 0x0D, 0x02, 0xBC, 0x40, 0x62, 0x38, 0x2F, 0x40, 0xE2, 0xC3, 0x28, 0x35,
+ 0x34, 0xC2, 0x65, 0x97, 0x8E, 0x41, 0x26, 0xC0, 0x0A, 0x87, 0x61, 0xC9,
+ 0x90, 0x04, 0x07, 0xAE, 0x04, 0x27, 0x22, 0xB8, 0xFE, 0x0D, 0xE4, 0x40,
+ 0x30, 0x9F, 0xB1, 0x02, 0xA5, 0x8F, 0xB0, 0x18, 0xB0, 0xD9, 0x00, 0xCD,
+ 0xB0, 0x09, 0x68, 0xA0, 0x41, 0x11, 0x45, 0x89, 0x0A, 0x99, 0x95, 0x85,
+ 0x08, 0x83, 0x9E, 0xF0, 0x87, 0xA4, 0x2F, 0xEC, 0x0D, 0x90, 0xE3, 0x20,
+ 0x71, 0x59, 0x99, 0x97, 0xA0, 0x98, 0xEC, 0x80, 0x93, 0x99, 0xDD, 0x3C,
+ 0x40, 0x98, 0x23, 0x34, 0x50, 0xE7, 0x49, 0x85, 0x38, 0x31, 0xA7, 0x29,
+ 0x38, 0xE2, 0x34, 0x02, 0x94, 0xA5, 0xE8, 0x14, 0xE0, 0x66, 0x9C, 0x2B,
+ 0xF9, 0x37, 0x10, 0xA2, 0x03, 0x5C, 0x95, 0x49, 0x09, 0xAC, 0xA8, 0xA7,
+ 0x67, 0x2F, 0xB2, 0x7A, 0xA6, 0x6A, 0xAF, 0xBE, 0xA6, 0x62, 0xE0, 0x93,
+ 0x99, 0xF5, 0x49, 0x40, 0xA5, 0x9A, 0x54, 0x40, 0x09, 0xAE, 0xE6, 0xDD,
+ 0xA2, 0x23, 0xA5, 0xBF, 0x62, 0x62, 0xE1, 0x08, 0xA5, 0x76, 0x33, 0x42,
+ 0xA7, 0x69, 0x82, 0xCA, 0x49, 0x4C, 0xD8, 0x4D, 0xDB, 0xD8, 0x07, 0xE3,
+ 0xA8, 0xF9, 0xEC, 0x35, 0x05, 0x58, 0xE0, 0x95, 0xAB, 0x03, 0xB4, 0x30,
+ 0x50, 0x48, 0x89, 0x60, 0xA0, 0xC9, 0x04, 0x6F, 0x9E, 0x9B, 0xEB, 0x31,
+ 0x02, 0xB6, 0x17, 0x6E, 0xBD, 0xF6, 0x76, 0xE2, 0x6E, 0xB2, 0x53, 0xD5,
+ 0x57, 0x09, 0xAF, 0x9B, 0x18, 0xC9, 0xE3, 0x40, 0xB3, 0x21, 0xA2, 0xC9,
+ 0xA4, 0x57, 0xD6, 0x9B, 0x18, 0x0A, 0xDC, 0x7A, 0x03, 0x83, 0xB5, 0x86,
+ 0x71, 0x32, 0xA6, 0x00, 0x0B, 0x68, 0x97, 0x00, 0x0C, 0x0B, 0xBC, 0x30,
+ 0xC3, 0x03, 0x0F, 0x64, 0xD7, 0xD8, 0x02, 0xA8, 0xDE, 0x0B, 0x4D, 0x05,
+ 0x16, 0x50, 0x60, 0x1B, 0x25, 0xE5, 0x22, 0xD5, 0x8B, 0x94, 0x41, 0x66,
+ 0x52, 0x6E, 0x9E, 0xF1, 0xF6, 0x52, 0x27, 0x22, 0xB4, 0x82, 0x4C, 0xF3,
+ 0xBD, 0xB6, 0xEA, 0xAB, 0x94, 0xCA, 0x2C, 0x79, 0x22, 0x1E, 0x22, 0xFE,
+ 0xC6, 0xE0, 0x33, 0xF0, 0x00, 0x77, 0x1E, 0x6C, 0x6F, 0x88, 0xD2, 0x2E,
+ 0xDC, 0x4D, 0x02, 0x1D, 0x38, 0x92, 0xC3, 0x9A, 0x99, 0x64, 0xA3, 0x70,
+ 0x63, 0x0F, 0xA0, 0x09, 0x0B, 0x0A, 0x33, 0x90, 0x9A, 0x74, 0x23, 0xE0,
+ 0xD6, 0x8C, 0x0E, 0x6B, 0x6B, 0x01, 0x4D, 0x09, 0x49, 0x99, 0xAC, 0x52,
+ 0xCC, 0xCB, 0xED, 0x3C, 0xDA, 0xCC, 0x04, 0x62, 0x73, 0xCD, 0xB6, 0xAA,
+ 0xBE, 0x21, 0x50, 0x1E, 0x3E, 0xEA, 0x4E, 0xC9, 0x49, 0xCF, 0x03, 0xFC,
+ 0xDC, 0x4E, 0xD0, 0x9B, 0x18, 0x7B, 0x2F, 0x0E, 0x07, 0x20, 0x0D, 0x0E,
+ 0xD5, 0x37, 0x68, 0x82, 0xA9, 0x00, 0x47, 0x83, 0x33, 0x83, 0xB5, 0xC7,
+ 0xE4, 0xB4, 0x93, 0xC7, 0x02, 0x84, 0xD9, 0xF6, 0x35, 0x64, 0x0F, 0x30,
+ 0x67, 0x3B, 0xC4, 0xFA, 0x2B, 0x88, 0x93, 0x0E, 0x36, 0x9A, 0x9B, 0x09,
+ 0x0A, 0x7C, 0xEE, 0x02, 0xE7, 0x8E, 0x3C, 0xDA, 0x40, 0xBE, 0x4D, 0x45,
+ 0x8E, 0x3A, 0x9B, 0xFC, 0x25, 0x98, 0x94, 0x6E, 0x4C, 0x71, 0x32, 0x39,
+ 0xDE, 0xCB, 0x72, 0x96, 0x3A, 0x21, 0x63, 0x96, 0x09, 0xB8, 0x37, 0x10,
+ 0xFC, 0x84, 0x09, 0x72, 0x02, 0x40, 0xB0, 0x53, 0x02, 0xBB, 0x1F, 0x23,
+ 0xC4, 0x23, 0x8C, 0x7F, 0x93, 0x00, 0x61, 0x38, 0xD4, 0xEE, 0x4C, 0xC9,
+ 0xAD, 0xC4, 0x0D, 0xC9, 0xA3, 0x03, 0x94, 0xA0, 0x49, 0xB9, 0xD0, 0xE3,
+ 0xA3, 0x81, 0x92, 0xAC, 0x20, 0x50, 0x79, 0xF4, 0x4B, 0xBE, 0x79, 0x3A,
+ 0xF3, 0xE2, 0xE3, 0x07, 0x70, 0x2B, 0xA2, 0xFB, 0x22, 0xEB, 0x00, 0x14,
+ 0x60, 0x0E, 0x40, 0xB0, 0x88, 0xA0, 0x8B, 0x0F, 0xE9, 0xE3, 0xDF, 0x60,
+ 0x78, 0xEE, 0xC8, 0x2F, 0xDD, 0x08, 0x8A, 0x00, 0x88, 0x2A, 0xC0, 0x03,
+ 0xE0, 0x7C, 0xA0, 0xB8, 0x46, 0x10, 0xC1, 0x08, 0x48, 0x50, 0x82, 0x20,
+ 0x8E, 0x00, 0xFE, 0x04, 0x22, 0x68, 0x63, 0x27, 0x33, 0x68, 0x44, 0x0F,
+ 0xC6, 0x67, 0x8A, 0x72, 0x51, 0x4E, 0x74, 0x73, 0x83, 0xD4, 0x9D, 0x12,
+ 0xD1, 0x3D, 0x00, 0xC5, 0x0C, 0x4E, 0x1E, 0xE0, 0x9C, 0xF4, 0x58, 0x11,
+ 0x3E, 0x08, 0x8A, 0x90, 0x32, 0x84, 0x2A, 0x9B, 0x52, 0xD2, 0x77, 0x01,
+ 0x7E, 0x0C, 0xA2, 0x02, 0xD6, 0x8B, 0x12, 0xDD, 0x98, 0x97, 0x1C, 0xFF,
+ 0xD9, 0xCF, 0x1B, 0x09, 0x40, 0xD3, 0x0A, 0x6A, 0x92, 0x8D, 0x2D, 0x81,
+ 0x63, 0x04, 0x1C, 0x72, 0x04, 0x11, 0x80, 0x10, 0x04, 0x4D, 0x1C, 0x81,
+ 0x09, 0x8D, 0x98, 0x58, 0x73, 0x1A, 0xC1, 0x83, 0x11, 0x8E, 0x62, 0x72,
+ 0x0E, 0x8A, 0xCD, 0x23, 0xA4, 0xC7, 0x37, 0x00, 0x4C, 0x2A, 0x03, 0xE7,
+ 0xD3, 0xD5, 0x70, 0x56, 0xF2, 0xB5, 0x27, 0xBA, 0x8A, 0x40, 0x4A, 0xEC,
+ 0xA2, 0x56, 0xDC, 0x87, 0x08, 0x97, 0xC5, 0x6A, 0x19, 0x17, 0xA0, 0x80,
+ 0x04, 0xCA, 0x77, 0x37, 0x05, 0xD1, 0x8B, 0x79, 0x3D, 0x68, 0xC4, 0x0C,
+ 0x77, 0xF2, 0x25, 0x01, 0xD0, 0x00, 0x00, 0x11, 0x43, 0x01, 0xD6, 0x3E,
+ 0x00, 0x89, 0x1F, 0x06, 0x91, 0x13, 0x47, 0x50, 0xE0, 0x62, 0xC0, 0x31,
+ 0xBC, 0x9A, 0x78, 0xD1, 0x13, 0x2B, 0x62, 0x85, 0x0A, 0x90, 0xD4, 0xA7,
+ 0x10, 0x0E, 0xE2, 0x66, 0x88, 0x50, 0x16, 0x3E, 0x80, 0x44, 0x09, 0x02,
+ 0x98, 0x51, 0x82, 0x19, 0xDC, 0x20, 0x9C, 0xB8, 0x38, 0xC8, 0x4C, 0x3A,
+ 0x24, 0x5F, 0x89, 0x90, 0x4A, 0x52, 0xD2, 0x07, 0x27, 0xD6, 0xB5, 0x43,
+ 0x56, 0x51, 0x64, 0x5B, 0x4C, 0x3A, 0xF0, 0xC6, 0x9D, 0xA0, 0xE9, 0x06,
+ 0xC9, 0x11, 0xC0, 0x88, 0xBC, 0xE1, 0xAD, 0x47, 0x08, 0xE1, 0x08, 0xA0,
+ 0x50, 0xC2, 0x02, 0xBF, 0x31, 0x82, 0x46, 0x40, 0x4E, 0x93, 0x1B, 0x79,
+ 0x57, 0x7F, 0xA4, 0xC2, 0xAF, 0xFE, 0x01, 0x44, 0x11, 0x60, 0x36, 0x92,
+ 0x49, 0x5B, 0x38, 0x83, 0xC9, 0x08, 0xBC, 0x09, 0x56, 0x8E, 0x18, 0x4E,
+ 0x3D, 0x58, 0x81, 0x49, 0x5E, 0x4A, 0xF3, 0x1C, 0x8C, 0x6C, 0xE4, 0x54,
+ 0x40, 0xA0, 0xBD, 0x50, 0x5E, 0x0F, 0x16, 0x7D, 0x62, 0x97, 0xF8, 0x6E,
+ 0x99, 0xCA, 0x6F, 0xE0, 0xAF, 0x11, 0x2C, 0xF8, 0x46, 0x2C, 0x05, 0x88,
+ 0x84, 0x51, 0x00, 0xA1, 0x11, 0x24, 0x00, 0xC7, 0x38, 0xBE, 0x33, 0xCD,
+ 0xBD, 0xA1, 0xF1, 0x6E, 0x20, 0x80, 0xE4, 0x9F, 0x30, 0x51, 0x00, 0x4A,
+ 0x78, 0x12, 0x1F, 0xC7, 0xF4, 0x13, 0xFB, 0x34, 0x67, 0x4D, 0x77, 0xE0,
+ 0xA9, 0x11, 0xFD, 0x8C, 0x66, 0x3C, 0x0F, 0x8A, 0x8A, 0xB7, 0x6D, 0xF3,
+ 0x18, 0x1A, 0xE8, 0xD3, 0x93, 0xAA, 0xF8, 0x88, 0x8C, 0xAC, 0xB1, 0x76,
+ 0x11, 0x3B, 0x5C, 0x38, 0x93, 0xC6, 0xA1, 0x3F, 0x26, 0xCD, 0x5A, 0x44,
+ 0x30, 0x20, 0x29, 0x9A, 0xA0, 0xC3, 0x6F, 0xA0, 0x09, 0x5B, 0x08, 0x25,
+ 0x84, 0x3F, 0x96, 0x21, 0x12, 0x83, 0x02, 0xA0, 0x9A, 0x10, 0x75, 0x44,
+ 0x3F, 0x15, 0xA5, 0x09, 0x80, 0xC1, 0x4F, 0x00, 0x12, 0x0D, 0x63, 0x3E,
+ 0x22, 0xC9, 0x9B, 0x92, 0xEA, 0xB4, 0x14, 0xAB, 0x43, 0xD9, 0x40, 0x40,
+ 0xE0, 0xB9, 0xCF, 0x69, 0xA0, 0xA5, 0x8E, 0xA8, 0x0A, 0x22, 0x98, 0xC4,
+ 0xBC, 0xC2, 0x71, 0xEC, 0xA2, 0xDE, 0x70, 0x9C, 0x45, 0x03, 0x40, 0xB5,
+ 0x26, 0x78, 0x94, 0x14, 0x43, 0x10, 0xC0, 0xDF, 0x70, 0xD9, 0x88, 0x1F,
+ 0xEC, 0x34, 0x13, 0x05, 0x60, 0x22, 0x2B, 0xA2, 0x18, 0x3B, 0x99, 0x7C,
+ 0x50, 0xA5, 0x83, 0xB0, 0x1B, 0xDE, 0x74, 0x26, 0x46, 0x01, 0x1C, 0x93,
+ 0x00, 0x39, 0xDD, 0xAA, 0x5B, 0x17, 0x45, 0x89, 0x0E, 0x9A, 0x2D, 0x5D,
+ 0x0E, 0xA5, 0x9E, 0xF8, 0x6E, 0xC2, 0x54, 0x70, 0xFE, 0x7C, 0x09, 0x78,
+ 0xDE, 0xC8, 0x65, 0x23, 0x98, 0xB0, 0x47, 0x53, 0x14, 0xEF, 0xA9, 0x0F,
+ 0x68, 0xC4, 0xF2, 0xDE, 0x4A, 0x88, 0x08, 0x48, 0x70, 0x00, 0xB8, 0xD0,
+ 0x84, 0xF3, 0x32, 0xD8, 0x0B, 0xD7, 0x4D, 0x74, 0x13, 0x66, 0x6D, 0x26,
+ 0x22, 0xF6, 0x79, 0xD3, 0x5B, 0xB4, 0x15, 0xB1, 0x9C, 0xAD, 0x4C, 0xB9,
+ 0x64, 0x37, 0x57, 0x58, 0x60, 0x93, 0x12, 0xF7, 0x64, 0x5E, 0x4C, 0xF8,
+ 0x9A, 0xD7, 0x6E, 0xA0, 0x40, 0xA3, 0xDC, 0x38, 0x27, 0x60, 0x53, 0x61,
+ 0x4B, 0x54, 0x7E, 0x23, 0x32, 0x9D, 0x2D, 0xEB, 0xBB, 0x22, 0x45, 0x08,
+ 0x4A, 0x38, 0xF1, 0x18, 0x96, 0x24, 0x2B, 0x21, 0xE0, 0x03, 0x3F, 0xD7,
+ 0x39, 0x92, 0x2E, 0xD9, 0x64, 0xEC, 0x66, 0x6B, 0x9B, 0xBA, 0x02, 0x44,
+ 0x60, 0xB9, 0xCB, 0x3D, 0x45, 0x01, 0x26, 0x15, 0xB0, 0xD0, 0x12, 0xE4,
+ 0x2E, 0x96, 0x80, 0xA0, 0x96, 0x70, 0xA7, 0x9D, 0x11, 0xBC, 0x60, 0xA9,
+ 0x66, 0x7A, 0xC0, 0xB6, 0xBC, 0x81, 0xBF, 0x26, 0x04, 0x16, 0x15, 0x44,
+ 0x94, 0x61, 0x37, 0xD0, 0xA4, 0x55, 0xE4, 0x02, 0xA0, 0x02, 0xCE, 0x0B,
+ 0x81, 0x41, 0xF3, 0x99, 0x08, 0x9F, 0x3E, 0x22, 0x68, 0x6B, 0xEB, 0xC4,
+ 0x9B, 0xA4, 0x92, 0x91, 0xE1, 0x42, 0xC2, 0x00, 0xC5, 0xBD, 0x00, 0xFB,
+ 0xD4, 0x4B, 0x33, 0xB5, 0x41, 0x77, 0x5D, 0x21, 0xB0, 0xAB, 0x28, 0x38,
+ 0x79, 0x59, 0xE9, 0x3A, 0x42, 0x25, 0x38, 0x15, 0x61, 0x11, 0xB7, 0xC3,
+ 0x29, 0x47, 0x74, 0x60, 0x04, 0x58, 0x3B, 0xD3, 0x53, 0xE3, 0xD8, 0x51,
+ 0x68, 0x20, 0xE1, 0x77, 0xE6, 0x34, 0x2C, 0x80, 0x05, 0x71, 0xD2, 0x44,
+ 0x61, 0x02, 0xA0, 0x03, 0x78, 0xCD, 0x92, 0xFE, 0x8B, 0x09, 0xD6, 0x0C,
+ 0xE0, 0x15, 0x2A, 0xD0, 0xEF, 0x9E, 0x8A, 0x5B, 0xDD, 0x0F, 0x07, 0xFE,
+ 0xD8, 0x79, 0xAE, 0xBA, 0x40, 0x08, 0x4A, 0xA9, 0x09, 0x12, 0xFF, 0x66,
+ 0x2A, 0x9E, 0x73, 0xC1, 0x6E, 0xE7, 0xDB, 0x4F, 0xB7, 0x1C, 0xB7, 0x76,
+ 0x8D, 0x30, 0x2F, 0x4F, 0xE2, 0x08, 0x89, 0xEF, 0x6E, 0xE7, 0xA9, 0x3E,
+ 0x11, 0x40, 0x86, 0xA1, 0x71, 0x84, 0x22, 0x7F, 0x83, 0x43, 0x0F, 0xFC,
+ 0x30, 0x40, 0xD9, 0x9A, 0x58, 0x4A, 0x0C, 0x64, 0x41, 0x9F, 0xA8, 0xC0,
+ 0x9B, 0xF0, 0x26, 0xDF, 0x5E, 0x6C, 0x80, 0x15, 0xDE, 0x94, 0xB1, 0xBD,
+ 0xBC, 0x6A, 0x2E, 0x96, 0xE0, 0x98, 0x4A, 0xAC, 0x58, 0xE8, 0x8B, 0x1D,
+ 0xE4, 0x00, 0x15, 0x28, 0xC0, 0x01, 0x96, 0xC4, 0x11, 0x8A, 0x53, 0x27,
+ 0xE5, 0xC6, 0x50, 0x0D, 0x16, 0x07, 0x30, 0x32, 0x4F, 0x1E, 0xD0, 0x4E,
+ 0x8C, 0x36, 0xA2, 0x08, 0xE7, 0x20, 0xE2, 0x36, 0xBC, 0xB1, 0xCA, 0x0F,
+ 0x23, 0x78, 0x00, 0x31, 0x06, 0x00, 0x89, 0x07, 0xB2, 0x1B, 0x88, 0x94,
+ 0xEB, 0xC7, 0x32, 0xE1, 0x6F, 0x24, 0x7D, 0x6B, 0xE6, 0x40, 0x95, 0x90,
+ 0x15, 0x1E, 0xA0, 0x73, 0x3C, 0xE0, 0x44, 0x80, 0x99, 0x79, 0x82, 0x89,
+ 0x70, 0x53, 0xCA, 0x06, 0xAE, 0x18, 0x27, 0x51, 0x3B, 0xB8, 0x7F, 0x1D,
+ 0x73, 0xC4, 0x12, 0x9E, 0x30, 0x84, 0x21, 0x14, 0x4F, 0x31, 0xDC, 0x25,
+ 0x11, 0x9A, 0xD2, 0x79, 0x8E, 0x75, 0x46, 0x8D, 0x5A, 0x5A, 0x03, 0xF0,
+ 0xA2, 0x11, 0xB1, 0xB6, 0x47, 0xE3, 0x83, 0x12, 0x9F, 0xE0, 0x8F, 0xA1,
+ 0x32, 0xB3, 0x81, 0xE2, 0x62, 0x39, 0x15, 0x25, 0xC0, 0x74, 0xA6, 0x85,
+ 0x32, 0x81, 0x01, 0x67, 0x60, 0xA8, 0xFB, 0xD5, 0x80, 0xCE, 0x4C, 0x36,
+ 0xE4, 0x4C, 0xF0, 0x47, 0xAE, 0xAD, 0x43, 0x35, 0x08, 0xD7, 0x4C, 0x64,
+ 0x56, 0xEF, 0x04, 0x8F, 0x8D, 0x00, 0x02, 0x26, 0x64, 0xAD, 0x98, 0x0A,
+ 0x4B, 0xAD, 0xFE, 0x11, 0x42, 0x48, 0x48, 0x11, 0x1A, 0xC1, 0x5D, 0x13,
+ 0x39, 0x10, 0xB9, 0x5E, 0x86, 0x93, 0x81, 0x29, 0xE1, 0x66, 0x01, 0x44,
+ 0x7A, 0x13, 0x96, 0xE9, 0x08, 0x51, 0x21, 0x61, 0x54, 0xCE, 0x64, 0x3B,
+ 0x14, 0xEC, 0x65, 0xEC, 0x9D, 0x9F, 0xFD, 0x12, 0x30, 0xF6, 0xC7, 0xC5,
+ 0x91, 0x80, 0x10, 0x2B, 0x60, 0xCA, 0x89, 0x4D, 0xB7, 0x62, 0x2A, 0xA0,
+ 0x24, 0x30, 0xB8, 0x99, 0x97, 0x67, 0x70, 0xE0, 0x8F, 0xD0, 0x9A, 0x30,
+ 0x02, 0x39, 0xCD, 0xD4, 0xA9, 0xA9, 0x9A, 0xA3, 0xAA, 0xAE, 0x14, 0x67,
+ 0x23, 0x06, 0x57, 0xDB, 0x72, 0x29, 0xDB, 0x33, 0x93, 0x62, 0x78, 0x23,
+ 0x12, 0xB9, 0xB7, 0x72, 0x95, 0xFA, 0x9A, 0x77, 0x59, 0xF6, 0x29, 0x5A,
+ 0xC5, 0x0C, 0x84, 0x73, 0x45, 0xE2, 0xAE, 0x48, 0x8A, 0x70, 0x58, 0xD1,
+ 0x00, 0x70, 0x3F, 0x57, 0x58, 0x27, 0x64, 0xC5, 0x09, 0x22, 0x70, 0xF0,
+ 0x55, 0xFB, 0x99, 0x1B, 0x8E, 0xE3, 0xF8, 0x26, 0x96, 0x20, 0x22, 0x12,
+ 0xF9, 0xD5, 0x08, 0x0B, 0x79, 0x70, 0x5F, 0x1D, 0xE1, 0xB4, 0xB7, 0xDA,
+ 0xCD, 0x7C, 0xD2, 0x3B, 0x0B, 0xC0, 0x8E, 0x7D, 0x0C, 0x48, 0x0E, 0xC0,
+ 0xA0, 0x16, 0xF0, 0xA5, 0xCB, 0x23, 0x7B, 0x97, 0x0B, 0x0C, 0xFC, 0x13,
+ 0x8A, 0x5D, 0x86, 0x0A, 0x75, 0x8E, 0x15, 0x95, 0xFF, 0xFB, 0x11, 0x1B,
+ 0xA8, 0x33, 0x01, 0x20, 0xDE, 0xAE, 0x77, 0x41, 0xB6, 0x1D, 0x6B, 0x4D,
+ 0xBA, 0xD2, 0xC1, 0x41, 0x82, 0x71, 0x2C, 0xC1, 0x13, 0x41, 0x50, 0xE0,
+ 0xAE, 0x1D, 0xB3, 0x3B, 0x22, 0xD0, 0x52, 0x21, 0x20, 0x3D, 0xB4, 0x37,
+ 0x4E, 0xC4, 0x59, 0x64, 0x6D, 0xAE, 0x11, 0x96, 0xBC, 0x8A, 0x6F, 0xC2,
+ 0x8C, 0x0C, 0x10, 0x22, 0x7D, 0x02, 0x16, 0x18, 0x30, 0x02, 0x50, 0xA2,
+ 0x14, 0x17, 0x50, 0xD7, 0xEF, 0xFE, 0xFC, 0x46, 0xF3, 0x51, 0x49, 0x0F,
+ 0xF7, 0x6B, 0x6C, 0x7B, 0xEE, 0xB0, 0xA8, 0xE9, 0x41, 0x0E, 0xAE, 0xE3,
+ 0xB3, 0x43, 0xE2, 0xDA, 0x8D, 0xD6, 0x64, 0xC6, 0xBB, 0xE1, 0x31, 0x22,
+ 0x8C, 0x77, 0x13, 0x1B, 0xAE, 0x9F, 0x63, 0xC8, 0x6D, 0xEE, 0x85, 0x14,
+ 0x0F, 0xB5, 0xDD, 0x70, 0x04, 0x0F, 0x62, 0x50, 0x83, 0xB7, 0xF2, 0xC7,
+ 0x89, 0x15, 0x1C, 0xC0, 0x04, 0xC0, 0x08, 0x76, 0x47, 0xA5, 0x19, 0x41,
+ 0xF9, 0x86, 0x45, 0xFA, 0x6A, 0x3F, 0x8A, 0x10, 0xC3, 0x49, 0xD5, 0xA9,
+ 0x5F, 0x88, 0x6F, 0xB8, 0xED, 0xA3, 0xD1, 0x46, 0xD2, 0xC0, 0x17, 0x6C,
+ 0x8D, 0x52, 0x2C, 0x9D, 0x88, 0xD2, 0x66, 0xB2, 0x11, 0x18, 0x9A, 0xB2,
+ 0x00, 0xA8, 0x0E, 0x8A, 0xE2, 0x1D, 0x5E, 0x95, 0x4E, 0xDE, 0x7D, 0xAE,
+ 0xAD, 0x0A, 0x8E, 0xEE, 0x74, 0x88, 0x06, 0x34, 0x29, 0xA9, 0xE4, 0xDF,
+ 0x47, 0x1F, 0x94, 0xE0, 0x5F, 0xFC, 0x01, 0x7A, 0xBE, 0x10, 0x64, 0xCB,
+ 0xE0, 0x00, 0xAC, 0x47, 0x16, 0x64, 0x86, 0x7A, 0x98, 0x50, 0x70, 0x00,
+ 0x01, 0x02, 0x96, 0xB4, 0x76, 0xDD, 0xF7, 0x0C, 0x13, 0x00, 0x15, 0x98,
+ 0xA7, 0x14, 0x1F, 0xE4, 0x4F, 0xB0, 0x03, 0x15, 0xD5, 0x17, 0x09, 0x77,
+ 0xA1, 0x48, 0x5E, 0x64, 0x75, 0xBC, 0x26, 0x00, 0x4F, 0x10, 0x0A, 0x51,
+ 0xE6, 0x7B, 0xC1, 0x33, 0x0E, 0xC1, 0xB7, 0x10, 0xEF, 0x26, 0x00, 0x3B,
+ 0xE4, 0x0B, 0x2B, 0xC0, 0x03, 0x55, 0x36, 0x4D, 0x2A, 0xC6, 0x39, 0x62,
+ 0xD7, 0x12, 0xCB, 0x94, 0x6F, 0x1A, 0xE8, 0x20, 0xB2, 0x67, 0x7D, 0x46,
+ 0xD7, 0x80, 0x84, 0x80, 0x73, 0x1D, 0x21, 0x15, 0xA7, 0x66, 0x1F, 0x14,
+ 0x98, 0x10, 0x43, 0x97, 0x08, 0x94, 0xA6, 0x27, 0xE2, 0x77, 0x0B, 0xE4,
+ 0x87, 0x09, 0xAB, 0xA7, 0x14, 0x01, 0x37, 0x00, 0xFE, 0x78, 0xD7, 0x45,
+ 0xD9, 0x40, 0x7C, 0x01, 0x90, 0x78, 0xA3, 0x40, 0x44, 0xB2, 0xC5, 0x40,
+ 0xF5, 0xD7, 0x10, 0x24, 0xE7, 0x67, 0x09, 0x80, 0x0F, 0x34, 0xD0, 0x03,
+ 0x59, 0x37, 0x48, 0xCE, 0x93, 0x56, 0xC1, 0x51, 0x5C, 0x25, 0xB0, 0x75,
+ 0x33, 0x77, 0x0C, 0x1B, 0x80, 0x1E, 0x1D, 0xD1, 0x62, 0xF3, 0xF1, 0x41,
+ 0x21, 0x08, 0x0A, 0x6D, 0x67, 0x48, 0x48, 0x22, 0x3D, 0x56, 0x88, 0x84,
+ 0xCF, 0xC0, 0x1F, 0x98, 0xF5, 0x32, 0x92, 0x60, 0x25, 0x28, 0xA6, 0x72,
+ 0xFB, 0x02, 0x4D, 0x9A, 0xA4, 0x25, 0xC4, 0x27, 0x6F, 0x83, 0x27, 0x0A,
+ 0xBD, 0x17, 0x68, 0xE0, 0x40, 0x18, 0x4E, 0xF0, 0x10, 0x8D, 0xF0, 0x54,
+ 0x01, 0x80, 0x3F, 0xDC, 0xD0, 0x30, 0xB0, 0xB0, 0x02, 0xBB, 0x34, 0x48,
+ 0x27, 0xE1, 0x0B, 0x92, 0xC5, 0x58, 0x0F, 0x88, 0x20, 0x4C, 0xA8, 0x60,
+ 0x6A, 0x05, 0x42, 0xA6, 0xF0, 0x7F, 0x4D, 0xD4, 0x0B, 0xD9, 0xD4, 0x19,
+ 0x7F, 0x68, 0x0E, 0xD5, 0x14, 0x7D, 0xD2, 0xC5, 0x00, 0x0E, 0xE5, 0x16,
+ 0x6F, 0x47, 0x08, 0x12, 0xB7, 0x86, 0x0C, 0xD5, 0x60, 0x83, 0xB4, 0x88,
+ 0xDE, 0xD0, 0x40, 0x02, 0xE0, 0x74, 0xA0, 0x10, 0x04, 0x23, 0xC8, 0x30,
+ 0x8D, 0x30, 0x04, 0x95, 0x28, 0x31, 0xE0, 0xE0, 0x38, 0x49, 0xF3, 0x17,
+ 0xE3, 0xA4, 0x4B, 0x99, 0x64, 0x81, 0x89, 0x50, 0x45, 0xAE, 0x67, 0x09,
+ 0x94, 0xA4, 0x80, 0xA3, 0xD1, 0x4F, 0x78, 0xE8, 0x09, 0x25, 0x20, 0x0C,
+ 0xE5, 0xC3, 0x01, 0xE7, 0x13, 0x34, 0xEA, 0x07, 0x8B, 0xCE, 0xF5, 0x26,
+ 0x54, 0x74, 0x8A, 0x91, 0x20, 0x76, 0xC0, 0xC6, 0x3E, 0x8B, 0xB6, 0x77,
+ 0xC7, 0xB0, 0x56, 0x17, 0x87, 0x3A, 0xBF, 0x78, 0x5E, 0x8D, 0x60, 0x7F,
+ 0x9E, 0xE0, 0x71, 0xF3, 0xC7, 0x0D, 0xD0, 0xD1, 0x04, 0x2F, 0x61, 0xFE,
+ 0x8C, 0xDC, 0x20, 0x6F, 0x4B, 0xF7, 0x00, 0xC3, 0xD3, 0x08, 0x9F, 0xE2,
+ 0x45, 0xC2, 0x76, 0x0C, 0xD7, 0x26, 0x01, 0x12, 0xD7, 0x1F, 0x2D, 0x10,
+ 0x66, 0x06, 0xC0, 0x00, 0x2F, 0xA2, 0x8D, 0xAC, 0xC0, 0x7D, 0x9E, 0x50,
+ 0x70, 0x08, 0x51, 0x6F, 0xF3, 0xD0, 0x0E, 0x62, 0x87, 0x8B, 0xE5, 0x68,
+ 0x0A, 0xE5, 0x63, 0x8A, 0x06, 0x00, 0x0F, 0xAD, 0xC0, 0x01, 0x05, 0x98,
+ 0x19, 0x05, 0xC1, 0x0A, 0x6A, 0x97, 0x09, 0xD3, 0x98, 0x08, 0x3E, 0xE8,
+ 0x08, 0xB4, 0x17, 0x84, 0x35, 0x43, 0x8F, 0xDC, 0xB0, 0x3B, 0xFD, 0x48,
+ 0x0A, 0x4F, 0x10, 0x75, 0xDE, 0x20, 0x6F, 0xF0, 0xE7, 0x10, 0xFF, 0xC8,
+ 0x0D, 0x4B, 0xB3, 0x74, 0xDC, 0x30, 0x35, 0x1D, 0x92, 0x7C, 0x4A, 0x04,
+ 0x50, 0x59, 0xE4, 0x0B, 0xCD, 0xF7, 0x7C, 0x8B, 0x35, 0x00, 0x19, 0xE0,
+ 0x00, 0x9F, 0x33, 0x23, 0x9F, 0x66, 0x53, 0x53, 0x61, 0x00, 0x75, 0xE6,
+ 0x6C, 0x99, 0x30, 0x84, 0xD4, 0xA3, 0x62, 0x82, 0xF8, 0x81, 0x27, 0xE6,
+ 0x91, 0xA7, 0x50, 0x4D, 0x33, 0x05, 0x70, 0xB6, 0xD8, 0x94, 0xA6, 0x98,
+ 0x2E, 0xD7, 0x26, 0x33, 0xCD, 0xA2, 0x5B, 0xE7, 0x57, 0x5C, 0xB8, 0x65,
+ 0x5D, 0x6E, 0xD4, 0x0D, 0xBB, 0xD3, 0x6E, 0xA4, 0x50, 0x8C, 0xCB, 0xE8,
+ 0x0D, 0x71, 0x64, 0x82, 0xCA, 0x68, 0x44, 0x22, 0x25, 0x6E, 0x3C, 0x41,
+ 0x02, 0xC3, 0x33, 0x47, 0x46, 0xE9, 0x20, 0x03, 0xD1, 0x27, 0xFE, 0x25,
+ 0x08, 0xA6, 0x17, 0x27, 0xEF, 0x28, 0x2F, 0xC5, 0x35, 0x76, 0xA3, 0xA0,
+ 0x87, 0xB7, 0x70, 0x09, 0x5E, 0x21, 0x4A, 0xB0, 0x10, 0x4C, 0x15, 0xF9,
+ 0x95, 0x10, 0x31, 0x45, 0xA2, 0x43, 0x85, 0x78, 0x92, 0x8D, 0x8E, 0x20,
+ 0x7A, 0x64, 0xD6, 0x91, 0x6F, 0xE8, 0x81, 0x8D, 0xD0, 0x7C, 0xDC, 0x58,
+ 0x3B, 0x5A, 0xFE, 0xF2, 0x82, 0x71, 0x29, 0x00, 0x2C, 0xC8, 0x85, 0x99,
+ 0xE2, 0x0D, 0xE3, 0xA0, 0x7B, 0xFE, 0x68, 0x97, 0xDF, 0xE0, 0x31, 0x41,
+ 0x49, 0x43, 0xF8, 0x43, 0x83, 0x10, 0x84, 0x90, 0xBE, 0x10, 0x4C, 0xB8,
+ 0x38, 0x01, 0x34, 0x16, 0x27, 0x2E, 0x19, 0x09, 0x8C, 0x79, 0x95, 0x95,
+ 0x81, 0x98, 0x24, 0xC1, 0x92, 0x03, 0x30, 0x8B, 0xB3, 0xB7, 0x6F, 0x97,
+ 0x19, 0x0A, 0x5B, 0xC7, 0x84, 0xE8, 0x17, 0x27, 0xA3, 0xD9, 0x0B, 0x06,
+ 0x80, 0x96, 0xEA, 0x53, 0x29, 0xFC, 0x81, 0x8E, 0xDD, 0x46, 0x09, 0x7E,
+ 0x78, 0x9A, 0x70, 0x49, 0x93, 0xC2, 0x68, 0x0A, 0xEB, 0x24, 0x00, 0x4B,
+ 0x35, 0x75, 0x41, 0xE1, 0x93, 0x01, 0x50, 0x9B, 0x19, 0x32, 0x0E, 0x87,
+ 0x35, 0x42, 0x6B, 0x79, 0x0C, 0x8F, 0x52, 0x66, 0x84, 0x30, 0x01, 0x14,
+ 0xE0, 0x4B, 0x38, 0xC3, 0x96, 0x91, 0xD4, 0x91, 0x9D, 0xA0, 0x7D, 0x2B,
+ 0xC1, 0x0F, 0x4C, 0x64, 0x92, 0x74, 0x27, 0x12, 0x6E, 0xE9, 0x9C, 0xFC,
+ 0xF6, 0x26, 0xBB, 0x28, 0x76, 0x27, 0x50, 0x01, 0x25, 0x40, 0x63, 0x2F,
+ 0x63, 0x02, 0x57, 0x74, 0x02, 0x16, 0xE0, 0x12, 0x72, 0x17, 0x7A, 0x89,
+ 0x28, 0x42, 0x21, 0x92, 0x9A, 0xE1, 0x99, 0x8C, 0xA5, 0x60, 0x4B, 0xB3,
+ 0xB9, 0x71, 0xE8, 0x59, 0x72, 0xE0, 0xE0, 0x13, 0xB6, 0xF9, 0x0D, 0xC1,
+ 0x98, 0x2A, 0x22, 0xE4, 0x15, 0x62, 0x09, 0x0B, 0x68, 0x83, 0x2F, 0x2A,
+ 0x16, 0x50, 0x53, 0xE8, 0x50, 0x36, 0x67, 0x91, 0xC0, 0x79, 0x37, 0x28,
+ 0x59, 0x09, 0xED, 0x93, 0x99, 0xF1, 0xD9, 0x9D, 0x05, 0xFA, 0x09, 0x76,
+ 0x33, 0x99, 0x0B, 0x86, 0x23, 0x8B, 0xA4, 0x16, 0x66, 0x53, 0x77, 0x70,
+ 0x52, 0x46, 0x43, 0x18, 0x5D, 0x9F, 0xD4, 0x8B, 0xE3, 0xD3, 0x46, 0x19,
+ 0xAA, 0x85, 0x02, 0xB0, 0xA1, 0xFE, 0xA5, 0xA0, 0x40, 0xE5, 0x14, 0x00,
+ 0x64, 0x28, 0x00, 0x4C, 0x20, 0x14, 0xB7, 0xB7, 0x29, 0x7D, 0xA9, 0x1D,
+ 0xC3, 0xA3, 0x3F, 0xE3, 0x33, 0x39, 0xCC, 0xD4, 0x0B, 0x8F, 0x82, 0x54,
+ 0x9A, 0x20, 0x71, 0x9F, 0x97, 0x19, 0x54, 0x28, 0xA3, 0xBD, 0xB4, 0x3D,
+ 0xF8, 0x65, 0x15, 0x2B, 0x45, 0x09, 0x2A, 0x4A, 0x9A, 0xEB, 0xF8, 0x8A,
+ 0x3C, 0x6A, 0xA0, 0x18, 0x64, 0x80, 0x90, 0x39, 0x08, 0x93, 0xE3, 0x32,
+ 0x1A, 0xA0, 0x98, 0x03, 0xE1, 0x02, 0x64, 0x19, 0x49, 0x71, 0x3A, 0x15,
+ 0x62, 0x57, 0x2C, 0x10, 0x14, 0x31, 0xBA, 0x03, 0xA5, 0xA7, 0x00, 0x75,
+ 0x7C, 0x55, 0x58, 0xE2, 0xF9, 0x12, 0x75, 0xA9, 0x6E, 0x85, 0x45, 0xA2,
+ 0xF7, 0x73, 0x2D, 0x22, 0x94, 0x9C, 0x5C, 0xD9, 0x08, 0x41, 0x03, 0x85,
+ 0x83, 0x10, 0x6D, 0x1D, 0x98, 0xA6, 0x35, 0x37, 0x81, 0x85, 0xB0, 0x58,
+ 0x87, 0xF4, 0x08, 0x1B, 0x74, 0xA8, 0xE5, 0x13, 0x37, 0x81, 0xBA, 0x0C,
+ 0x0B, 0x69, 0xA7, 0x9B, 0x00, 0x1A, 0x62, 0x4A, 0x77, 0x03, 0x42, 0x08,
+ 0x5E, 0xA1, 0x2C, 0xCA, 0xE0, 0x01, 0xD4, 0xD9, 0x7A, 0x82, 0x7A, 0x02,
+ 0xC9, 0xB9, 0x63, 0x4A, 0x1A, 0xA4, 0x10, 0x94, 0x1C, 0x8A, 0x1A, 0xA5,
+ 0xA4, 0xF0, 0x6E, 0x7C, 0xD5, 0x64, 0xF7, 0xA8, 0x10, 0x24, 0xD7, 0x18,
+ 0x5C, 0xAA, 0x1D, 0xE4, 0xB6, 0x35, 0xE3, 0xE3, 0x3C, 0xB2, 0x0A, 0x09,
+ 0xC4, 0x72, 0x5C, 0xFD, 0x09, 0x87, 0xDC, 0xB9, 0x2E, 0x17, 0xD7, 0x55,
+ 0xCB, 0x90, 0x01, 0x94, 0x26, 0x8A, 0x18, 0xF9, 0x26, 0x59, 0xB4, 0x01,
+ 0xD7, 0x59, 0x3A, 0xAF, 0xCA, 0x09, 0x5E, 0xB1, 0x8B, 0x35, 0x55, 0xA6,
+ 0xF0, 0x75, 0x11, 0x8F, 0x90, 0x4D, 0x7F, 0xFA, 0x53, 0x7D, 0x07, 0x00,
+ 0x3B, 0x62, 0x96, 0x11, 0x95, 0x92, 0xA3, 0x5A, 0xFE, 0x33, 0x31, 0x11,
+ 0x89, 0xBB, 0x53, 0xAC, 0xA3, 0x60, 0x4B, 0x51, 0xE3, 0x31, 0x8E, 0xF8,
+ 0x12, 0x1B, 0xE6, 0x85, 0x1A, 0x77, 0x89, 0x8E, 0xE1, 0x38, 0x4D, 0xA3,
+ 0x9B, 0x84, 0x8A, 0x3E, 0xFA, 0x69, 0x9C, 0xDB, 0xA3, 0xAB, 0x02, 0x70,
+ 0x7D, 0x7E, 0x57, 0x02, 0x03, 0x36, 0x41, 0xD2, 0x97, 0x08, 0x5A, 0xA9,
+ 0x4F, 0x34, 0x35, 0x1C, 0x77, 0x87, 0xAE, 0x9C, 0x90, 0x9C, 0xF2, 0xA5,
+ 0x33, 0xF5, 0x05, 0x1A, 0xC5, 0x14, 0x1C, 0x9C, 0x86, 0x81, 0xED, 0x70,
+ 0x6D, 0x06, 0x26, 0x9A, 0xFC, 0xC4, 0x80, 0x23, 0x24, 0x0D, 0xB8, 0xE3,
+ 0xAF, 0xA8, 0xD0, 0x08, 0x3A, 0xF1, 0x25, 0xC3, 0xE8, 0x0C, 0x41, 0xE0,
+ 0x04, 0x42, 0xE0, 0xB3, 0x79, 0x49, 0x08, 0x4E, 0xC0, 0x61, 0x3C, 0x01,
+ 0x01, 0x7B, 0x49, 0x22, 0xC9, 0x83, 0x44, 0x22, 0x44, 0x63, 0x0B, 0x55,
+ 0x67, 0x27, 0x20, 0x01, 0xF6, 0xA9, 0xB2, 0x87, 0x12, 0xB3, 0x9D, 0x50,
+ 0x01, 0xF3, 0x14, 0x10, 0x20, 0x71, 0x39, 0x00, 0x20, 0x99, 0x8C, 0xE9,
+ 0x27, 0xF2, 0xC8, 0xA3, 0x76, 0x83, 0x94, 0x90, 0xB0, 0x41, 0xB8, 0x28,
+ 0x53, 0xF3, 0x85, 0x52, 0x01, 0x2A, 0x13, 0xC1, 0xA4, 0x48, 0xDA, 0x79,
+ 0x3E, 0x55, 0x09, 0x42, 0x31, 0x79, 0x2F, 0x98, 0xE2, 0x85, 0x35, 0x7B,
+ 0x0A, 0x0A, 0x34, 0x22, 0xE3, 0xA0, 0xAC, 0x82, 0x05, 0x09, 0x3C, 0x29,
+ 0x08, 0xC5, 0xE3, 0x78, 0x80, 0x64, 0xB4, 0x24, 0xF2, 0xA8, 0x02, 0x70,
+ 0xA2, 0xCC, 0x93, 0x9C, 0xDB, 0xF9, 0x66, 0xE6, 0x92, 0x80, 0x52, 0x6B,
+ 0x32, 0x49, 0x97, 0x02, 0xBE, 0x14, 0x15, 0x32, 0x41, 0x5F, 0x00, 0xE0,
+ 0xAB, 0x02, 0xD8, 0xA9, 0x21, 0x8B, 0x09, 0xCE, 0xA3, 0xA9, 0x02, 0xB0,
+ 0x41, 0x06, 0xE6, 0xAE, 0x03, 0x50, 0x80, 0xEB, 0xD8, 0x92, 0x99, 0xFE,
+ 0x51, 0x41, 0x86, 0x99, 0xB9, 0x71, 0xC5, 0x39, 0xC9, 0xC6, 0x0A, 0xF5,
+ 0x25, 0x42, 0x3A, 0x00, 0x6F, 0x1A, 0x8A, 0x0A, 0xC5, 0x33, 0x31, 0x57,
+ 0x6A, 0x0E, 0x1E, 0x07, 0x0B, 0x8B, 0x27, 0x08, 0x0A, 0x14, 0xB8, 0xDE,
+ 0xF0, 0x00, 0x09, 0xAB, 0x1D, 0x71, 0x14, 0xAD, 0xCC, 0xC3, 0x44, 0xBB,
+ 0xC8, 0x86, 0xAE, 0x22, 0xAF, 0xBA, 0x92, 0x8A, 0xF8, 0x52, 0xAA, 0xAC,
+ 0x77, 0x6D, 0xFF, 0xB9, 0x12, 0x21, 0x00, 0xB7, 0xCE, 0x49, 0x09, 0x61,
+ 0x06, 0x49, 0x39, 0x12, 0xAB, 0x90, 0xE0, 0x8A, 0xB7, 0x32, 0x15, 0xCD,
+ 0x6B, 0xA6, 0x2D, 0x03, 0x70, 0xC3, 0x51, 0x9C, 0xA8, 0x13, 0x13, 0xED,
+ 0x47, 0xB7, 0xA6, 0xD0, 0xA8, 0x78, 0x44, 0x89, 0xD0, 0x40, 0x72, 0xB0,
+ 0xE0, 0x74, 0x75, 0xF9, 0x4A, 0xA9, 0x84, 0xB4, 0x84, 0x0B, 0x41, 0x12,
+ 0xE7, 0x72, 0x0E, 0x57, 0x28, 0x2B, 0x0B, 0x0B, 0xDB, 0x58, 0x20, 0x68,
+ 0xF6, 0xAD, 0xA4, 0x2B, 0x12, 0xEC, 0xA2, 0x84, 0x95, 0xA0, 0xAF, 0x21,
+ 0xFB, 0x7F, 0x08, 0x50, 0x11, 0x94, 0x60, 0x57, 0x29, 0x4A, 0x17, 0xC1,
+ 0xE0, 0x55, 0xA3, 0xE9, 0x7A, 0xAC, 0x4B, 0x08, 0x19, 0x09, 0x80, 0x64,
+ 0x51, 0x73, 0xFB, 0x39, 0x42, 0x3E, 0x10, 0x52, 0xE5, 0x4B, 0x78, 0x50,
+ 0x17, 0x9B, 0x00, 0xB0, 0x4E, 0x07, 0x00, 0x1D, 0x40, 0xEB, 0x0C, 0x20,
+ 0xD5, 0x0B, 0x3C, 0x49, 0x72, 0x91, 0x98, 0x4A, 0xD0, 0x8A, 0x86, 0xA9,
+ 0xE3, 0xAB, 0xF7, 0x6A, 0x00, 0x1A, 0xD0, 0x02, 0x0E, 0xD0, 0x02, 0xF6,
+ 0x30, 0x1F, 0xFA, 0xDB, 0x0F, 0x18, 0xAB, 0x00, 0x9D, 0x49, 0x53, 0x6F,
+ 0x7A, 0x33, 0x20, 0x8B, 0xB9, 0x79, 0x68, 0x42, 0xC7, 0x40, 0x2C, 0x15,
+ 0xB0, 0x8A, 0xE5, 0x81, 0x28, 0x4C, 0xE2, 0x1B, 0xA0, 0xE5, 0x0B, 0x46,
+ 0x78, 0x7A, 0xFE, 0xF8, 0xF2, 0x2E, 0xC0, 0xE1, 0x7A, 0xC6, 0xC5, 0x4B,
+ 0x31, 0x60, 0x55, 0x3A, 0xA1, 0xC1, 0x9C, 0x10, 0x04, 0xB3, 0x26, 0x00,
+ 0xE9, 0x4B, 0x9E, 0xF6, 0x08, 0x0D, 0x2E, 0xD8, 0x0B, 0x73, 0x09, 0x00,
+ 0x1B, 0x76, 0x55, 0x4C, 0xE5, 0x57, 0x49, 0x04, 0x41, 0x0A, 0x95, 0x8E,
+ 0x2E, 0x95, 0xBC, 0xC7, 0x62, 0xB5, 0x13, 0x2B, 0xB6, 0xB7, 0xF0, 0x8D,
+ 0x0A, 0xFA, 0xC3, 0xA1, 0x00, 0x50, 0x4A, 0x0C, 0x09, 0xB2, 0x82, 0x01,
+ 0x93, 0x83, 0xB2, 0x02, 0x50, 0xB2, 0x83, 0xA0, 0x62, 0xB1, 0xD1, 0x02,
+ 0x98, 0x01, 0x0B, 0x12, 0xF8, 0x09, 0x3B, 0x52, 0x67, 0xD8, 0xE7, 0x8B,
+ 0x38, 0x01, 0x01, 0xE3, 0xF0, 0xAF, 0x4F, 0xF7, 0x08, 0x36, 0xD9, 0xC5,
+ 0x58, 0x0A, 0x0D, 0x50, 0xE7, 0x0B, 0x62, 0x2C, 0xB4, 0x54, 0x9A, 0x57,
+ 0x71, 0xF4, 0xA5, 0xCC, 0xD3, 0x53, 0xE9, 0x68, 0x00, 0x05, 0x95, 0x0B,
+ 0x90, 0xBB, 0xB9, 0x95, 0xB6, 0x8E, 0x04, 0x5A, 0xC7, 0x9D, 0x70, 0xC7,
+ 0x20, 0x51, 0x5C, 0x12, 0x30, 0x29, 0x98, 0x45, 0x09, 0xB8, 0xA8, 0x86,
+ 0x8D, 0x50, 0x1F, 0x84, 0xDC, 0x08, 0xAE, 0x67, 0x99, 0x99, 0xE0, 0xA2,
+ 0xA4, 0x15, 0xBD, 0x91, 0xC3, 0x17, 0x4B, 0xA3, 0xB3, 0x42, 0x04, 0x0B,
+ 0xC9, 0xD8, 0xC5, 0xE9, 0xFB, 0x0C, 0x24, 0x1C, 0xC6, 0x83, 0x50, 0x3C,
+ 0xED, 0x97, 0x5A, 0xBB, 0x13, 0xBC, 0xCC, 0x43, 0x63, 0xE0, 0x37, 0x57,
+ 0xD2, 0x89, 0x08, 0x64, 0x55, 0x48, 0x85, 0xA2, 0xC3, 0x9E, 0x49, 0x96,
+ 0x10, 0x9C, 0xCA, 0xF8, 0xD2, 0x11, 0x8B, 0xC9, 0x14, 0x2C, 0xF5, 0x08,
+ 0xFC, 0xD2, 0x58, 0x42, 0x2A, 0x17, 0x02, 0xA5, 0x08, 0x02, 0xC1, 0xC4,
+ 0x8C, 0x36, 0x0A, 0xFC, 0xF1, 0x42, 0xD3, 0x74, 0x13, 0x2F, 0xF0, 0x25,
+ 0xAC, 0xC9, 0x7B, 0xB0, 0x60, 0xFE, 0x6E, 0x5D, 0x2C, 0xC2, 0xA8, 0xD0,
+ 0xA1, 0x97, 0x3C, 0x08, 0x0A, 0x54, 0x6B, 0x17, 0xE5, 0x57, 0x81, 0x39,
+ 0x3E, 0x3C, 0x97, 0xCD, 0xD5, 0x49, 0x9C, 0x66, 0xCA, 0xBF, 0xF7, 0x0A,
+ 0x20, 0xD7, 0x89, 0x01, 0x03, 0xDC, 0xCD, 0x83, 0x40, 0x09, 0xE7, 0x73,
+ 0x4C, 0x08, 0x01, 0x1F, 0xB3, 0x08, 0x49, 0x8A, 0xF4, 0xB9, 0x8E, 0x60,
+ 0x8B, 0x19, 0xE0, 0x50, 0x0E, 0x2D, 0x08, 0xC0, 0x19, 0xBE, 0x22, 0x74,
+ 0x13, 0x1F, 0x90, 0x4B, 0xF4, 0xAC, 0x09, 0x5D, 0xEC, 0x08, 0xF7, 0xEC,
+ 0x08, 0xD7, 0xB0, 0xBE, 0xBD, 0x10, 0x7C, 0xC5, 0x58, 0xC6, 0xA9, 0x15,
+ 0x00, 0x9D, 0x92, 0x9B, 0xCC, 0x13, 0xC0, 0xCF, 0x63, 0x36, 0xD4, 0x4C,
+ 0x00, 0x2A, 0x75, 0xB1, 0xCB, 0x90, 0xC3, 0xB9, 0xF2, 0xA0, 0xAC, 0xE0,
+ 0xC3, 0x0F, 0x3D, 0x0A, 0xB6, 0xDA, 0x0B, 0xC7, 0x64, 0x09, 0x9F, 0x6B,
+ 0x92, 0xD9, 0x64, 0x50, 0x5A, 0x46, 0x50, 0xAE, 0x92, 0xCB, 0x11, 0x57,
+ 0x14, 0x04, 0x70, 0xB9, 0xBC, 0xA4, 0x25, 0x7F, 0x83, 0xBE, 0x9F, 0x80,
+ 0xD2, 0x83, 0xE6, 0xC1, 0xEC, 0x76, 0x0D, 0x38, 0x79, 0x0C, 0x1C, 0x57,
+ 0x55, 0x9A, 0x1C, 0x00, 0x1F, 0x80, 0x3F, 0xBB, 0x8B, 0x34, 0x7E, 0x85,
+ 0x72, 0x10, 0xB4, 0x68, 0xD9, 0x3A, 0x1F, 0x3A, 0x7D, 0x5C, 0x55, 0x8B,
+ 0x80, 0x70, 0x4C, 0x15, 0x5C, 0x4B, 0xC7, 0x44, 0x4D, 0x0A, 0x61, 0x95,
+ 0xC7, 0x91, 0x74, 0x09, 0xAC, 0xD1, 0xC7, 0xFA, 0x96, 0x08, 0x7C, 0xE3,
+ 0xD4, 0x3B, 0x0C, 0x27, 0xF3, 0x39, 0x0A, 0x5E, 0xB6, 0xA6, 0xD3, 0x54,
+ 0x38, 0x46, 0x44, 0xBB, 0x9E, 0xB0, 0xD5, 0xF0, 0x47, 0x9E, 0x62, 0xEC,
+ 0x0C, 0xB6, 0xEB, 0x0B, 0x8B, 0xB7, 0x61, 0xED, 0x27, 0x3C, 0x8E, 0x80,
+ 0x02, 0x95, 0x3A, 0x2D, 0xCA, 0xA3, 0x44, 0x6D, 0xFE, 0x2D, 0x9C, 0xA2,
+ 0x25, 0xAA, 0xBA, 0x4C, 0xCA, 0xB9, 0x42, 0x88, 0x29, 0x59, 0xD5, 0x78,
+ 0xDD, 0x24, 0xF0, 0xB9, 0x80, 0x9A, 0x25, 0x08, 0x93, 0xA2, 0xA2, 0x92,
+ 0x55, 0xCE, 0x2B, 0x34, 0xD8, 0x41, 0x13, 0x49, 0x5E, 0xDB, 0x2E, 0xBD,
+ 0x5C, 0x3B, 0x3A, 0x70, 0x1D, 0x8C, 0xB1, 0x3B, 0x79, 0x2B, 0x08, 0x5B,
+ 0x1D, 0x7C, 0xE4, 0x69, 0xCC, 0xCE, 0xA0, 0xC5, 0xB0, 0xC0, 0x93, 0x50,
+ 0xD7, 0x4E, 0xE7, 0x24, 0x31, 0xEA, 0x06, 0x38, 0x8F, 0x2A, 0x48, 0x6C,
+ 0x2D, 0x41, 0xE1, 0x38, 0x1A, 0x1F, 0xB4, 0xA6, 0xD7, 0x9C, 0x08, 0x2A,
+ 0x80, 0xBF, 0xE6, 0xB1, 0xCD, 0xBA, 0x8D, 0xD7, 0x93, 0x92, 0x45, 0x54,
+ 0xA8, 0x42, 0x23, 0x0B, 0x09, 0x03, 0xE3, 0x96, 0xA0, 0x11, 0xDE, 0xCC,
+ 0x12, 0x01, 0x29, 0x20, 0x01, 0x21, 0x5D, 0x5B, 0x3A, 0xD0, 0x4A, 0xB8,
+ 0xE3, 0x31, 0xF9, 0x9C, 0x09, 0x2D, 0xBD, 0x9A, 0xC1, 0x5D, 0x6E, 0xD7,
+ 0x70, 0xDC, 0x90, 0xB0, 0xA1, 0x28, 0x78, 0x31, 0x9A, 0xCD, 0xD9, 0x48,
+ 0xB3, 0x3B, 0x9E, 0x38, 0xBF, 0x12, 0x94, 0x01, 0x68, 0xCB, 0x9B, 0xB6,
+ 0x28, 0xA3, 0xDD, 0xCA, 0x0A, 0x07, 0x6E, 0xDA, 0x0C, 0xED, 0xD1, 0xAA,
+ 0xAD, 0x96, 0x72, 0x22, 0x00, 0x54, 0xC8, 0x45, 0x7A, 0x6D, 0xB6, 0x47,
+ 0x95, 0x09, 0xB0, 0xFD, 0x08, 0xC4, 0xE6, 0x91, 0xA8, 0xC9, 0x5A, 0x3E,
+ 0x51, 0xDC, 0x9A, 0xB0, 0xCF, 0xC8, 0x88, 0xDF, 0xF7, 0x0D, 0x0D, 0xFB,
+ 0xED, 0x08, 0x36, 0x09, 0x00, 0x94, 0xED, 0x08, 0x0B, 0xE0, 0xDC, 0x33,
+ 0x94, 0x4B, 0xEE, 0x39, 0x42, 0xFD, 0x66, 0x14, 0x2E, 0xDC, 0x50, 0xCB,
+ 0x50, 0x7B, 0x3D, 0xCD, 0x0A, 0x2D, 0x50, 0xD0, 0x1E, 0x2B, 0xD4, 0xDE,
+ 0x29, 0xE1, 0xA3, 0x40, 0x63, 0xD9, 0xF3, 0xA6, 0x92, 0x32, 0xBA, 0xFE,
+ 0xB0, 0xB0, 0xA3, 0x65, 0x85, 0x6F, 0x1D, 0x4E, 0x1B, 0xE5, 0xD8, 0xA4,
+ 0x21, 0x0A, 0x90, 0x8D, 0xDD, 0x09, 0x0A, 0xB4, 0xD2, 0x82, 0x60, 0xC9,
+ 0x26, 0x7D, 0x0A, 0x2A, 0xCE, 0xD5, 0x00, 0x80, 0x82, 0x8E, 0x00, 0x01,
+ 0x28, 0x9C, 0x57, 0x56, 0x5A, 0xD3, 0x22, 0xB4, 0xCB, 0x4D, 0xE9, 0x22,
+ 0xA2, 0xB1, 0x01, 0x32, 0x72, 0x9D, 0xC0, 0x16, 0xC1, 0xF3, 0x94, 0xAB,
+ 0xB9, 0x12, 0x81, 0xCB, 0x70, 0xD7, 0x43, 0x9E, 0x0A, 0x12, 0xDC, 0xC6,
+ 0xEB, 0x15, 0xD1, 0x29, 0x63, 0x15, 0x7D, 0x6D, 0x14, 0x90, 0xE0, 0xE1,
+ 0x7F, 0xC8, 0x3F, 0x7F, 0xCB, 0x0D, 0xE3, 0x80, 0xBB, 0x9B, 0x00, 0xC6,
+ 0x3C, 0x49, 0x44, 0x28, 0xFE, 0x0C, 0x96, 0x0C, 0x0B, 0x41, 0xA4, 0x04,
+ 0xC8, 0x8C, 0x02, 0xEF, 0x2B, 0xD3, 0xFB, 0x28, 0x47, 0xD2, 0xC8, 0x94,
+ 0xD3, 0x77, 0x8B, 0x84, 0xF0, 0xB8, 0x6D, 0x6A, 0xDA, 0x1A, 0x78, 0x01,
+ 0xA9, 0x6D, 0xE7, 0xA4, 0x50, 0x25, 0x16, 0x54, 0x12, 0x43, 0xDA, 0x0B,
+ 0xB6, 0x8D, 0x52, 0x1F, 0x31, 0x30, 0x65, 0x4A, 0x81, 0x39, 0x74, 0x3C,
+ 0x8A, 0x8A, 0x6B, 0x9D, 0xB0, 0x61, 0x8A, 0x27, 0x08, 0xFB, 0xAC, 0xE5,
+ 0xA6, 0xD0, 0x7B, 0x90, 0xD0, 0x6E, 0x4A, 0x60, 0xE5, 0xCD, 0x5D, 0xE9,
+ 0x58, 0x25, 0x00, 0xD1, 0xDD, 0x45, 0x9D, 0xAE, 0xE9, 0x47, 0x85, 0x49,
+ 0xD8, 0x8D, 0x08, 0xDA, 0x9D, 0x2B, 0xB5, 0xB8, 0x0C, 0xD0, 0x3B, 0xEA,
+ 0x07, 0x36, 0x6A, 0x53, 0xBB, 0xA7, 0x78, 0xAA, 0xB1, 0x70, 0xE2, 0x48,
+ 0x88, 0x82, 0xCA, 0x08, 0x87, 0xC1, 0x56, 0x25, 0xE6, 0x4C, 0x47, 0xE5,
+ 0x9D, 0xA0, 0x04, 0x7B, 0xB4, 0xEB, 0x8C, 0xBE, 0xB3, 0xBF, 0xEE, 0x08,
+ 0x46, 0x30, 0x04, 0x56, 0xAE, 0x64, 0xC1, 0x2E, 0x68, 0x6B, 0x3D, 0x48,
+ 0x05, 0x90, 0xFE, 0x02, 0x18, 0xBB, 0x12, 0x11, 0x9A, 0x09, 0xBE, 0xE4,
+ 0xE0, 0x7A, 0x62, 0x9D, 0x3A, 0x1E, 0xE1, 0x43, 0x5E, 0x00, 0xEA, 0xE0,
+ 0x6C, 0xF0, 0x51, 0xA7, 0x84, 0xE0, 0x3C, 0x08, 0x7E, 0xCB, 0xD8, 0x9E,
+ 0xBF, 0x89, 0x10, 0xD5, 0x66, 0x16, 0xE5, 0xFF, 0x2C, 0x94, 0x8D, 0x70,
+ 0xE8, 0x9B, 0x30, 0x04, 0x40, 0xA0, 0xE2, 0xB9, 0xAE, 0xEB, 0xED, 0xD0,
+ 0xEE, 0xEE, 0xDE, 0x0D, 0x4D, 0x46, 0xEC, 0x83, 0x34, 0x01, 0x12, 0xD0,
+ 0x00, 0xBE, 0xD4, 0x00, 0x14, 0x60, 0x01, 0x28, 0x96, 0xC4, 0x3F, 0x1E,
+ 0xD4, 0x91, 0x24, 0xE4, 0xD1, 0xBE, 0x92, 0x5E, 0xC1, 0xCD, 0xBF, 0x25,
+ 0xC5, 0x99, 0xE0, 0x3C, 0x0A, 0x9D, 0x0C, 0x9B, 0x81, 0x00, 0xB6, 0xFC,
+ 0x08, 0x22, 0x21, 0xEA, 0x32, 0xE6, 0x3B, 0x29, 0x68, 0x2A, 0xF9, 0xBD,
+ 0x09, 0x41, 0x80, 0xD2, 0x81, 0x31, 0x03, 0x68, 0x62, 0xF1, 0xE6, 0x6B,
+ 0xE5, 0x42, 0x80, 0xCC, 0x19, 0xAF, 0xF1, 0xDD, 0xD0, 0x40, 0x02, 0x6D,
+ 0x66, 0x34, 0xB6, 0xDD, 0xA2, 0x55, 0x67, 0x5D, 0xCB, 0xF2, 0xA1, 0xF0,
+ 0x6B, 0xA6, 0x79, 0x98, 0x16, 0x0C, 0x00, 0x7B, 0xFE, 0x32, 0x88, 0x32,
+ 0xDB, 0x70, 0xC7, 0x3F, 0x68, 0xED, 0x0D, 0x84, 0x41, 0x04, 0x9B, 0xE0,
+ 0xE2, 0x2C, 0xF0, 0xBE, 0x8E, 0x43, 0xB0, 0xD7, 0x70, 0x04, 0xB1, 0xB6,
+ 0xEB, 0x4C, 0xDF, 0xF4, 0xE1, 0xF0, 0x31, 0x99, 0x26, 0xC1, 0x78, 0x2C,
+ 0x37, 0xA0, 0xBE, 0xF3, 0x57, 0xEF, 0xA9, 0xF7, 0xA9, 0x3E, 0xA7, 0xF0,
+ 0x26, 0x3F, 0xEE, 0x08, 0x1B, 0xA4, 0xF5, 0x32, 0x16, 0x13, 0x02, 0x40,
+ 0xE8, 0x3B, 0xD1, 0x1D, 0x3A, 0x5B, 0x04, 0xB3, 0xD6, 0x17, 0x62, 0xDE,
+ 0x64, 0x94, 0x9C, 0x10, 0x8B, 0x2E, 0xF7, 0x73, 0xCF, 0x0D, 0x71, 0x44,
+ 0x52, 0x00, 0xB6, 0x75, 0xA1, 0xFE, 0xED, 0xEC, 0xAB, 0xEB, 0xDD, 0x78,
+ 0x7D, 0xD3, 0xD4, 0x2E, 0x0A, 0x33, 0xFF, 0x32, 0x41, 0xC3, 0xF5, 0x0C,
+ 0xDF, 0x08, 0xB1, 0xDE, 0x18, 0xC1, 0x38, 0x97, 0x47, 0xE0, 0x04, 0x56,
+ 0x0E, 0x01, 0x94, 0x3E, 0x5B, 0x8D, 0xA0, 0x10, 0xBB, 0xEE, 0xBB, 0x96,
+ 0xCF, 0x0D, 0x84, 0xB1, 0x02, 0x99, 0xAF, 0x5E, 0x92, 0xF9, 0x6F, 0xFB,
+ 0x4E, 0x66, 0xFD, 0x1E, 0xED, 0xE5, 0xE3, 0x01, 0x29, 0xDF, 0x2F, 0xA4,
+ 0x00, 0x30, 0xA5, 0x9C, 0x14, 0x1B, 0x64, 0xD8, 0x08, 0x17, 0x03, 0xC9,
+ 0xC1, 0x5A, 0x8E, 0x31, 0xB8, 0x14, 0xEF, 0x08, 0x22, 0xE0, 0xF0, 0x88,
+ 0x66, 0xE2, 0xE7, 0x50, 0x78, 0xE0, 0x84, 0xFB, 0x3B, 0xF1, 0xA8, 0xBB,
+ 0x9F, 0x69, 0x24, 0x46, 0xBC, 0x8E, 0x60, 0xFC, 0x9C, 0xB1, 0xF2, 0x23,
+ 0x66, 0x01, 0x12, 0x10, 0x02, 0x0D, 0xC0, 0xFE, 0x66, 0x64, 0x01, 0xA7,
+ 0xFF, 0xAA, 0x24, 0x26, 0x57, 0x54, 0xA8, 0xC8, 0x1B, 0x31, 0x98, 0xB9,
+ 0x22, 0x2B, 0x7B, 0xAF, 0x5E, 0xDA, 0x72, 0xFD, 0x3F, 0xFF, 0x08, 0x07,
+ 0x00, 0x08, 0x0B, 0x09, 0x01, 0x84, 0x85, 0x86, 0x85, 0x30, 0x02, 0x02,
+ 0x40, 0x00, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x00, 0x42, 0x8A, 0x07,
+ 0x83, 0x87, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x99, 0x22, 0x8A, 0x2B, 0x3B,
+ 0x93, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xA9, 0x21, 0x03,
+ 0xAF, 0x03, 0x0C, 0x8A, 0xB3, 0xB4, 0x20, 0x0E, 0xB0, 0xB0, 0x27, 0x15,
+ 0xA7, 0x11, 0x21, 0x18, 0xB8, 0xC0, 0xB8, 0x27, 0x16, 0x05, 0xAC, 0xC6,
+ 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0x91, 0xBF, 0xAF, 0x08, 0x06, 0xB3, 0x20,
+ 0x08, 0xB8, 0x04, 0x13, 0xAA, 0x15, 0xB8, 0x1A, 0xB4, 0xDC, 0xDD, 0xDD,
+ 0x06, 0xD4, 0xAF, 0x0D, 0xCC, 0xE4, 0xE5, 0xE6, 0xFE, 0xE6, 0x3B, 0x8A,
+ 0x23, 0x9E, 0x86, 0x1D, 0xB4, 0x22, 0x24, 0xEC, 0x85, 0x0F, 0x8A, 0x4C,
+ 0xE7, 0x41, 0xB3, 0x0B, 0xF2, 0xFB, 0xFC, 0x9E, 0x09, 0x2C, 0xB3, 0x7E,
+ 0x9C, 0x1B, 0x48, 0xB0, 0xA0, 0xA3, 0x02, 0x04, 0x60, 0x65, 0xF0, 0x66,
+ 0x40, 0x41, 0xB0, 0x0B, 0x25, 0x4C, 0x4D, 0xA0, 0x90, 0x30, 0x98, 0x45,
+ 0x60, 0x14, 0x22, 0x18, 0xDC, 0xC8, 0xB1, 0x23, 0xA9, 0x09, 0xB8, 0x5C,
+ 0x70, 0x03, 0xE1, 0xA1, 0xDA, 0xB5, 0x54, 0x0D, 0x60, 0x41, 0xF3, 0xC6,
+ 0x92, 0xDB, 0x2D, 0x58, 0x27, 0x3D, 0xCA, 0x9C, 0xA9, 0xCA, 0x86, 0x22,
+ 0x7D, 0xF2, 0x3E, 0x00, 0x14, 0x00, 0x61, 0x04, 0x26, 0x7E, 0x09, 0x0E,
+ 0x28, 0x0A, 0x62, 0xAE, 0xC8, 0xAC, 0x78, 0xFD, 0x92, 0x2A, 0x9D, 0xE7,
+ 0x4E, 0xC0, 0x0D, 0x9A, 0x50, 0xA3, 0x02, 0x28, 0x81, 0x4B, 0x01, 0x37,
+ 0x06, 0x19, 0x82, 0x85, 0x28, 0x36, 0xA9, 0x40, 0x8A, 0x0B, 0x17, 0xC3,
+ 0x5A, 0x6C, 0x10, 0x53, 0xAA, 0xD9, 0xB3, 0xA4, 0x5C, 0xBD, 0x5A, 0xF8,
+ 0xAD, 0x24, 0x2C, 0x02, 0x1A, 0x51, 0x45, 0xC0, 0xE5, 0xA1, 0xA5, 0x5D,
+ 0x0E, 0xB8, 0x42, 0xA0, 0xDD, 0x2B, 0x33, 0xC6, 0x0A, 0x01, 0x28, 0xF6,
+ 0x7D, 0xB0, 0xB4, 0x6E, 0x69, 0x80, 0xC1, 0x02, 0x8A, 0x94, 0x0B, 0xD2,
+ 0xE4, 0xA6, 0xE1, 0xC7, 0xFD, 0x12, 0x34, 0x7D, 0xCA, 0xB7, 0x32, 0xB9,
+ 0x94, 0xB0, 0x36, 0x28, 0x32, 0xA0, 0x22, 0x18, 0x86, 0xB8, 0x92, 0x0A,
+ 0x48, 0xA8, 0x78, 0xD1, 0x41, 0x0B, 0x05, 0x0A, 0x5C, 0xA0, 0x6E, 0xF1,
+ 0xD2, 0xE2, 0x56, 0xCB, 0xB0, 0xA1, 0x62, 0x1E, 0x60, 0x82, 0xA5, 0x01,
+ 0xB7, 0xB0, 0x2C, 0xB4, 0xC2, 0xC5, 0x21, 0x9A, 0x5D, 0x6E, 0x1A, 0x70,
+ 0x61, 0xE0, 0x1A, 0xBB, 0xF8, 0x32, 0x1E, 0x8A, 0x1E, 0xB0, 0x23, 0xFE,
+ 0x01, 0x4A, 0xC0, 0x8B, 0x9F, 0x86, 0x21, 0x08, 0x68, 0x52, 0xCE, 0x88,
+ 0xA2, 0xC0, 0x90, 0xB3, 0xCB, 0x93, 0xAC, 0x48, 0x86, 0xF1, 0xEF, 0xA8,
+ 0x2A, 0x90, 0x76, 0x20, 0xC0, 0x44, 0xB8, 0xB7, 0x12, 0x48, 0x89, 0x26,
+ 0x0D, 0xCC, 0x81, 0x09, 0x10, 0xBF, 0x5D, 0x70, 0x38, 0x0F, 0x0B, 0x43,
+ 0x59, 0xF0, 0xF8, 0x97, 0x91, 0x96, 0x65, 0xBB, 0x33, 0x2E, 0xDD, 0xA7,
+ 0x14, 0xE0, 0xCC, 0x2B, 0x1E, 0x68, 0xF6, 0x9B, 0x22, 0x0E, 0xBD, 0x75,
+ 0x5F, 0x7E, 0x0C, 0x4E, 0xD2, 0x83, 0x22, 0x2C, 0x78, 0xF2, 0x40, 0x73,
+ 0x07, 0x20, 0x95, 0xDD, 0x08, 0x8A, 0x20, 0xB1, 0x4C, 0x10, 0x4B, 0xCC,
+ 0x32, 0x83, 0x76, 0x20, 0x7A, 0xF2, 0x81, 0x50, 0x02, 0xD8, 0xD0, 0xE0,
+ 0x89, 0x00, 0x48, 0x80, 0x4B, 0x56, 0xC0, 0x34, 0xB0, 0xCB, 0x24, 0x25,
+ 0xB0, 0x07, 0x8B, 0x07, 0x26, 0xF8, 0x76, 0xE0, 0x66, 0x1A, 0xB0, 0xA8,
+ 0x20, 0x8A, 0x3C, 0xA6, 0x82, 0xCB, 0x6F, 0x1B, 0x00, 0x83, 0x41, 0x2A,
+ 0x13, 0xB0, 0x87, 0x40, 0x6D, 0x76, 0x6D, 0xE0, 0x1F, 0x2C, 0x11, 0xF5,
+ 0xE8, 0xA4, 0x5F, 0x02, 0x5C, 0xC2, 0xC9, 0x03, 0x3B, 0x75, 0xF0, 0x80,
+ 0x85, 0xDA, 0xB9, 0x43, 0x04, 0x51, 0xC8, 0x28, 0xD1, 0xD8, 0x2C, 0xD0,
+ 0x85, 0x28, 0xA6, 0x21, 0xF4, 0x08, 0x80, 0x43, 0x0C, 0x4E, 0xE2, 0x37,
+ 0x20, 0x30, 0x04, 0x34, 0x19, 0xDA, 0x09, 0x16, 0x71, 0x00, 0xDF, 0x8D,
+ 0x2C, 0x29, 0x40, 0x9F, 0x35, 0x69, 0xE6, 0x09, 0x09, 0x2E, 0x73, 0xB2,
+ 0x84, 0xDB, 0x00, 0xC3, 0xA9, 0x52, 0x24, 0x30, 0x19, 0x68, 0x60, 0xE3,
+ 0x2C, 0x1B, 0xD8, 0x09, 0x0C, 0x80, 0x7A, 0x9E, 0x88, 0x9C, 0x00, 0x30,
+ 0x6C, 0xF2, 0x40, 0x53, 0x02, 0x88, 0x10, 0xA6, 0x76, 0x24, 0x28, 0x62,
+ 0x04, 0x32, 0xFE, 0x40, 0x70, 0x83, 0xDD, 0x98, 0xA0, 0x1A, 0xF2, 0x82,
+ 0x22, 0x3C, 0x34, 0x5A, 0xDC, 0x5C, 0x5A, 0x11, 0x17, 0xC9, 0x04, 0x60,
+ 0x01, 0xC3, 0x81, 0x81, 0x74, 0xB6, 0xB4, 0xC1, 0x9F, 0x78, 0x9A, 0x9A,
+ 0xE6, 0x6C, 0xDB, 0xD4, 0x29, 0x9C, 0xAA, 0xA8, 0x08, 0x68, 0x91, 0x69,
+ 0xA8, 0xA9, 0xF0, 0xE7, 0x2B, 0x04, 0x30, 0x6A, 0x2B, 0x7E, 0x0F, 0x0A,
+ 0x10, 0xA1, 0x26, 0x0B, 0xCC, 0x72, 0xC0, 0x87, 0xA1, 0x06, 0x00, 0x83,
+ 0x50, 0x4E, 0xB0, 0x72, 0x44, 0x25, 0x80, 0x91, 0x08, 0x41, 0xB4, 0xDC,
+ 0x26, 0x80, 0x82, 0x22, 0x02, 0x1D, 0x5B, 0x99, 0x5A, 0xAF, 0x7C, 0x56,
+ 0xCA, 0xA0, 0xB8, 0xA8, 0x00, 0x6B, 0xAC, 0xBF, 0xE1, 0x05, 0xCB, 0x05,
+ 0xBC, 0x8A, 0x9B, 0x1F, 0x05, 0x0A, 0xB5, 0x74, 0x5E, 0xA0, 0xC7, 0xA8,
+ 0x28, 0xD6, 0x43, 0x0B, 0xCA, 0x0B, 0x1B, 0x94, 0x52, 0x1E, 0x42, 0x82,
+ 0x74, 0x8A, 0x40, 0x80, 0x65, 0xA8, 0x18, 0x0A, 0xB0, 0x29, 0x2A, 0x41,
+ 0x74, 0x0A, 0x61, 0x02, 0x65, 0x6E, 0xCB, 0x6D, 0xB4, 0x09, 0x0B, 0xD0,
+ 0x83, 0xBF, 0x68, 0x21, 0x34, 0x00, 0x01, 0xE9, 0x9D, 0x6B, 0xA4, 0x48,
+ 0xEC, 0xC6, 0xEA, 0xEE, 0x2B, 0x27, 0x60, 0x9C, 0x5F, 0x01, 0x15, 0xA0,
+ 0xFA, 0x0A, 0x92, 0x57, 0xE1, 0xD2, 0xAF, 0xA0, 0xB3, 0x89, 0xC5, 0x71,
+ 0xBC, 0x26, 0x57, 0x46, 0x83, 0x22, 0x91, 0x1E, 0xB2, 0x00, 0x89, 0x28,
+ 0x14, 0x36, 0x31, 0x21, 0xCD, 0x2A, 0x6C, 0xCA, 0x11, 0x40, 0x10, 0x61,
+ 0x09, 0x4E, 0x11, 0xFF, 0x1C, 0xED, 0xB7, 0x4E, 0xD5, 0x6C, 0x56, 0x09,
+ 0x2E, 0x9A, 0xA2, 0xF1, 0x8C, 0x87, 0x86, 0x7C, 0xE3, 0x9F, 0xA0, 0x39,
+ 0x0D, 0x1B, 0xBD, 0x27, 0x90, 0x86, 0xC0, 0xBA, 0x8A, 0x04, 0x57, 0x2E,
+ 0x39, 0x13, 0xB5, 0xEA, 0x59, 0xFE, 0x0A, 0x34, 0x6B, 0x8D, 0xD6, 0x0D,
+ 0x8E, 0x91, 0xC9, 0xF4, 0x01, 0x3E, 0x2B, 0x1D, 0x00, 0x09, 0x24, 0x36,
+ 0x51, 0x04, 0x97, 0x8E, 0x04, 0xF1, 0x44, 0x87, 0x47, 0xFF, 0x94, 0xB4,
+ 0xDC, 0x63, 0x96, 0x29, 0x00, 0x9A, 0x6A, 0x17, 0xB7, 0x66, 0x6F, 0x56,
+ 0x87, 0x0C, 0xCE, 0xBB, 0x85, 0x5B, 0x36, 0x35, 0x30, 0x1E, 0x54, 0x9D,
+ 0xE0, 0x00, 0xE3, 0x98, 0x93, 0xB2, 0x04, 0x98, 0xA7, 0x10, 0x41, 0xDA,
+ 0x8D, 0x9B, 0x95, 0x8E, 0xB2, 0x3A, 0xCF, 0xC2, 0xC2, 0xA5, 0x4A, 0x27,
+ 0x40, 0xF0, 0x6F, 0x07, 0x08, 0x92, 0x89, 0x74, 0x12, 0x03, 0x2E, 0x26,
+ 0xC1, 0xDE, 0x75, 0x5E, 0x99, 0xBE, 0x04, 0x26, 0x9E, 0xB8, 0x0B, 0xB8,
+ 0x74, 0x2C, 0xBB, 0x59, 0x16, 0x84, 0xA5, 0x42, 0xCB, 0xC4, 0xEE, 0xDE,
+ 0x79, 0xB2, 0x01, 0x07, 0x60, 0xBA, 0x25, 0xD0, 0xBA, 0x2E, 0xF0, 0x02,
+ 0x4C, 0xD3, 0xD2, 0x01, 0x04, 0x0B, 0xF8, 0xB4, 0xC9, 0x0C, 0x8A, 0x90,
+ 0xAE, 0xFC, 0x52, 0x65, 0xE2, 0x20, 0x3C, 0x5A, 0x20, 0x51, 0x6D, 0x7B,
+ 0xE2, 0xAD, 0x11, 0xC0, 0xF9, 0xF6, 0x06, 0xAD, 0x19, 0x0C, 0x07, 0xB4,
+ 0x04, 0x09, 0x8B, 0xEE, 0xE4, 0x63, 0x6C, 0xC3, 0x5F, 0x90, 0x16, 0x32,
+ 0x83, 0xB6, 0x07, 0x5F, 0x6F, 0xC8, 0x07, 0x0B, 0x2C, 0x00, 0xC3, 0x07,
+ 0x82, 0xA9, 0x63, 0x3F, 0x88, 0x4D, 0xB9, 0x58, 0xFB, 0x64, 0xC3, 0xA7,
+ 0xEF, 0x25, 0x0E, 0x04, 0xB8, 0x48, 0xC1, 0x00, 0x65, 0xD2, 0xBD, 0xB0,
+ 0x90, 0x87, 0x16, 0x4B, 0x1A, 0x80, 0xB1, 0x16, 0x68, 0xAA, 0x18, 0xE0,
+ 0xC0, 0x7F, 0x01, 0x98, 0x14, 0xF2, 0xFE, 0x07, 0x2A, 0x12, 0xB1, 0x20,
+ 0x67, 0x1C, 0x5C, 0x4A, 0xC2, 0x4A, 0x45, 0x41, 0x8F, 0xA8, 0x6C, 0x00,
+ 0x56, 0x31, 0x60, 0xE2, 0x46, 0x76, 0x81, 0x12, 0xFE, 0x72, 0x84, 0x5E,
+ 0x6B, 0xD9, 0x40, 0x0B, 0xE8, 0x03, 0x36, 0x04, 0x26, 0xD0, 0x85, 0xA6,
+ 0xCA, 0x01, 0x06, 0x2B, 0xD6, 0x81, 0xFA, 0x85, 0x10, 0x32, 0x23, 0x9A,
+ 0x05, 0x0A, 0x16, 0xC0, 0xBF, 0x1F, 0xF6, 0x43, 0x28, 0x39, 0xC0, 0x21,
+ 0x47, 0x66, 0xC3, 0x16, 0xAB, 0x81, 0xC0, 0x04, 0xC2, 0xA2, 0x0B, 0x07,
+ 0x40, 0x96, 0x24, 0x5C, 0xB8, 0x49, 0x89, 0xE5, 0x78, 0x1C, 0xCB, 0x34,
+ 0x70, 0x8B, 0x14, 0x02, 0xA7, 0x45, 0x2F, 0xC2, 0x22, 0x8A, 0xD8, 0x26,
+ 0x00, 0x68, 0x8D, 0xAA, 0x6D, 0x46, 0x14, 0x53, 0xC5, 0x68, 0x01, 0x81,
+ 0x36, 0xB6, 0x31, 0x7F, 0x33, 0x78, 0xC0, 0x03, 0x8A, 0x08, 0xB8, 0x04,
+ 0xCC, 0xE0, 0x05, 0x42, 0x19, 0x22, 0x1D, 0xCF, 0xA8, 0x03, 0x31, 0x0E,
+ 0xA4, 0x81, 0x03, 0xC8, 0x55, 0xAC, 0x64, 0xA8, 0xA3, 0x8B, 0x64, 0x80,
+ 0x8A, 0x2C, 0x69, 0x4D, 0xC9, 0xFC, 0x48, 0x8E, 0xDE, 0xC1, 0xA2, 0x6A,
+ 0x60, 0xA3, 0xC5, 0xC8, 0x88, 0xA5, 0x40, 0x46, 0xE6, 0x87, 0x8C, 0x22,
+ 0x30, 0x5E, 0x95, 0xE8, 0x98, 0x46, 0x31, 0x4D, 0xEB, 0x7B, 0x10, 0x10,
+ 0xC1, 0x0C, 0xAC, 0xF7, 0x98, 0x11, 0x90, 0x88, 0x16, 0x07, 0x28, 0x62,
+ 0xA6, 0x04, 0x10, 0x2E, 0x4B, 0x32, 0x83, 0x5C, 0x4D, 0xBC, 0x11, 0x03,
+ 0x5A, 0xB3, 0xAF, 0x57, 0xA0, 0xAF, 0x25, 0x62, 0x7B, 0x45, 0x18, 0x5D,
+ 0x79, 0x8C, 0x01, 0xDD, 0x32, 0x56, 0x26, 0x78, 0xC8, 0x04, 0x79, 0xC9,
+ 0x17, 0x32, 0x76, 0x20, 0x83, 0xDF, 0x7A, 0x56, 0x27, 0xB9, 0xF5, 0x81,
+ 0xD3, 0x7D, 0x4F, 0x04, 0x20, 0x04, 0xD1, 0xB7, 0x5E, 0xA0, 0x93, 0x59,
+ 0x1C, 0x93, 0x10, 0x00, 0xD1, 0x1E, 0x31, 0x95, 0x61, 0x36, 0x96, 0xFD,
+ 0x66, 0x96, 0xB5, 0x8C, 0x93, 0x5D, 0xCE, 0x53, 0xC9, 0x6D, 0xAE, 0xFE,
+ 0x22, 0x1B, 0xB0, 0xE0, 0x0F, 0xBB, 0xB0, 0x22, 0x4C, 0x73, 0xEE, 0xE5,
+ 0x07, 0x96, 0xB0, 0xA3, 0x22, 0x3A, 0x40, 0xCA, 0x65, 0x82, 0xE8, 0x1F,
+ 0x2A, 0x04, 0x4C, 0xF2, 0xB2, 0xF3, 0x01, 0x10, 0x36, 0x6F, 0x1E, 0x8A,
+ 0x30, 0x91, 0x3B, 0x59, 0x81, 0xCE, 0x57, 0x44, 0xD2, 0x1B, 0x2D, 0xB8,
+ 0x08, 0x06, 0x42, 0x50, 0x82, 0x93, 0x4C, 0xC0, 0x02, 0x31, 0xA3, 0x4D,
+ 0x4B, 0x12, 0x3A, 0xB6, 0x81, 0xEE, 0x66, 0x2D, 0xB6, 0x33, 0x00, 0x45,
+ 0x81, 0x71, 0x01, 0xB4, 0x59, 0x94, 0x26, 0x9F, 0x83, 0x54, 0x73, 0x2C,
+ 0x65, 0x4F, 0xC0, 0xC9, 0xF1, 0xA4, 0x28, 0x7D, 0xC0, 0x08, 0xF2, 0xC7,
+ 0xD2, 0xFC, 0x35, 0xCF, 0x9A, 0xCA, 0x19, 0x53, 0x10, 0x05, 0x60, 0x88,
+ 0x6F, 0x51, 0xE6, 0xA3, 0xA8, 0x70, 0xE4, 0x00, 0xEA, 0xF2, 0x9B, 0xDB,
+ 0x3C, 0x44, 0x02, 0xBB, 0x84, 0x44, 0x8C, 0x54, 0x52, 0x35, 0x69, 0xE0,
+ 0x62, 0x7C, 0x38, 0x05, 0x00, 0x69, 0xBC, 0x98, 0x38, 0x70, 0x06, 0x83,
+ 0x00, 0x14, 0x78, 0x59, 0x52, 0xC9, 0x61, 0x93, 0xEB, 0x10, 0xEC, 0x05,
+ 0x25, 0xCD, 0x6A, 0x21, 0x10, 0x23, 0x00, 0x12, 0xEC, 0x2C, 0x1F, 0xA0,
+ 0x6A, 0x8E, 0x21, 0xA8, 0xB7, 0x82, 0xA9, 0x9E, 0x82, 0x76, 0xBF, 0xB4,
+ 0xCD, 0xB0, 0x2E, 0x30, 0x4C, 0x49, 0x9C, 0x90, 0xA9, 0xDC, 0x38, 0xCF,
+ 0x15, 0xCD, 0xEA, 0x08, 0x9D, 0x0E, 0xE0, 0xA0, 0x21, 0x73, 0xAA, 0x67,
+ 0x88, 0x41, 0xD7, 0x72, 0xE8, 0x00, 0x7E, 0xB4, 0x88, 0x9B, 0x56, 0x97,
+ 0xE9, 0xAD, 0xEB, 0x10, 0xE2, 0x03, 0xCD, 0xBB, 0x66, 0x88, 0x82, 0x66,
+ 0x88, 0xA0, 0x08, 0x60, 0x14, 0x7D, 0x95, 0x04, 0x0C, 0x51, 0xD8, 0xAE,
+ 0x6A, 0x94, 0x13, 0x15, 0x93, 0x8D, 0x25, 0x37, 0x46, 0xA6, 0x97, 0xC8,
+ 0x3A, 0x62, 0xFE, 0x36, 0xBF, 0xCB, 0xA7, 0x22, 0xF4, 0xCA, 0xA6, 0xA8,
+ 0x7A, 0x16, 0x19, 0x31, 0xD0, 0x21, 0x2A, 0x39, 0x39, 0xD8, 0x65, 0xEE,
+ 0xA4, 0x8C, 0x85, 0x38, 0x9E, 0x22, 0x32, 0x09, 0xA2, 0x20, 0x1E, 0xE0,
+ 0x10, 0xA0, 0xD0, 0xE6, 0x69, 0x3F, 0x0B, 0x0B, 0x41, 0x7A, 0x03, 0x77,
+ 0x3B, 0x3A, 0x27, 0x2E, 0xF0, 0x1A, 0x4C, 0x71, 0xEC, 0xB6, 0xA0, 0x03,
+ 0x40, 0xA4, 0x68, 0x37, 0x30, 0x9F, 0x8B, 0x74, 0x14, 0xA9, 0xBB, 0x75,
+ 0x44, 0x6A, 0xB9, 0xF1, 0x9C, 0xD6, 0x66, 0x35, 0x68, 0x02, 0x50, 0x6C,
+ 0x21, 0xB0, 0xBB, 0x4F, 0xA5, 0x40, 0x0C, 0xBB, 0x38, 0x29, 0xC4, 0x2A,
+ 0x21, 0x1B, 0xDD, 0xD9, 0xA8, 0xD3, 0x1B, 0x3A, 0xAA, 0x15, 0x2B, 0xCC,
+ 0x76, 0xDE, 0x5A, 0xE0, 0x62, 0xB7, 0xB0, 0x14, 0x2D, 0x43, 0x4C, 0x50,
+ 0x48, 0x8C, 0x64, 0x2D, 0xBA, 0x91, 0x98, 0xAE, 0x35, 0x59, 0x6B, 0xDD,
+ 0x34, 0x0A, 0x0E, 0x02, 0xA4, 0xDB, 0x49, 0xF1, 0x94, 0xD2, 0x9C, 0x79,
+ 0x5E, 0x0A, 0x20, 0x2B, 0x20, 0xDC, 0x6E, 0x67, 0xA3, 0x5C, 0xF7, 0x32,
+ 0x09, 0x19, 0xB3, 0xF1, 0x26, 0x37, 0x70, 0x11, 0x54, 0xB3, 0xB2, 0x27,
+ 0x03, 0x35, 0x92, 0x6F, 0x37, 0x18, 0x30, 0x49, 0x8E, 0x7A, 0x14, 0xBF,
+ 0x8F, 0xD0, 0xEF, 0xC3, 0xFA, 0x5B, 0x52, 0xC7, 0x3A, 0x87, 0x13, 0x26,
+ 0xC6, 0xAA, 0x61, 0x3E, 0xD0, 0x14, 0xD5, 0x65, 0xA2, 0x4C, 0x24, 0xDC,
+ 0x2D, 0x9C, 0x5E, 0x01, 0x57, 0x5A, 0x4C, 0xAE, 0x85, 0x10, 0xEE, 0x6D,
+ 0x4B, 0x74, 0x74, 0xDF, 0xA9, 0xDA, 0x35, 0x5D, 0x0D, 0x96, 0xAF, 0x01,
+ 0x4C, 0x30, 0x2C, 0x5C, 0x64, 0x04, 0xC4, 0x8D, 0x20, 0xA3, 0x22, 0x54,
+ 0x4C, 0x62, 0x7B, 0x4A, 0x07, 0x6E, 0xFE, 0x68, 0x4A, 0x77, 0x23, 0xC3,
+ 0x02, 0x1F, 0x16, 0x82, 0x60, 0xFE, 0x37, 0x7D, 0x9F, 0x00, 0x68, 0x20,
+ 0x50, 0x9C, 0xD2, 0xAE, 0xC6, 0xB3, 0x58, 0x12, 0xFB, 0x56, 0xF1, 0xB8,
+ 0xF6, 0xD2, 0xA2, 0x35, 0x3D, 0x4E, 0x6A, 0x05, 0x28, 0x62, 0x48, 0x05,
+ 0xE0, 0x35, 0x9F, 0x20, 0x68, 0xAE, 0x45, 0x2E, 0x90, 0x66, 0xBA, 0x2A,
+ 0xF9, 0x00, 0xD1, 0x6C, 0x32, 0x0C, 0x00, 0xF2, 0x82, 0x3C, 0x03, 0x6E,
+ 0x54, 0x28, 0xE0, 0xAF, 0x26, 0x4C, 0x1C, 0x53, 0x8A, 0xCD, 0x62, 0x14,
+ 0x3A, 0x50, 0x2D, 0xB8, 0x14, 0x3C, 0xD0, 0x14, 0xC0, 0xE2, 0x81, 0xDE,
+ 0x40, 0x33, 0x32, 0x68, 0x37, 0x80, 0xA2, 0xCE, 0x42, 0xD2, 0xA7, 0x2D,
+ 0x80, 0x05, 0xCC, 0x07, 0x64, 0x0D, 0x73, 0xC3, 0x00, 0x1A, 0x28, 0xB2,
+ 0x04, 0xA3, 0xAB, 0xE4, 0xD1, 0x35, 0x79, 0xAC, 0xD4, 0xAD, 0x27, 0xA8,
+ 0x12, 0x91, 0x4A, 0x7E, 0x04, 0x91, 0xC9, 0xD1, 0x3A, 0x1D, 0x0F, 0x6E,
+ 0x26, 0x00, 0x2C, 0x60, 0x41, 0x11, 0x34, 0xC0, 0xA9, 0xCA, 0x10, 0xD0,
+ 0x92, 0xD6, 0xB4, 0xF5, 0x14, 0x76, 0x4D, 0x6B, 0x37, 0x30, 0x1D, 0xDD,
+ 0x89, 0xC8, 0x48, 0x21, 0x6E, 0xF6, 0x74, 0x2D, 0xE4, 0xBC, 0x31, 0x52,
+ 0x83, 0xF5, 0xD4, 0x86, 0x38, 0xE5, 0x7E, 0x01, 0x47, 0x37, 0x01, 0x14,
+ 0x5A, 0x30, 0x07, 0xB8, 0xED, 0xC4, 0xAA, 0xCD, 0x8D, 0x28, 0x44, 0xA1,
+ 0x0A, 0x8A, 0x10, 0xE0, 0x40, 0x0B, 0x30, 0x5C, 0x96, 0x8C, 0x8C, 0x02,
+ 0xAC, 0x28, 0x00, 0xB9, 0x0C, 0x6A, 0x17, 0x62, 0x83, 0x18, 0xA2, 0xBE,
+ 0x0B, 0xB2, 0x68, 0x75, 0xD4, 0x59, 0xCF, 0x2A, 0x59, 0xB0, 0xA7, 0x4E,
+ 0x44, 0xA5, 0x66, 0x50, 0x60, 0x01, 0xE0, 0x1B, 0x54, 0xDC, 0x69, 0x5D,
+ 0x3F, 0x48, 0xB0, 0xAC, 0x89, 0xAD, 0x51, 0x11, 0x49, 0x48, 0xC2, 0x15,
+ 0xA6, 0x20, 0x80, 0x15, 0xF4, 0xD1, 0xA2, 0x03, 0xFE, 0xF2, 0x2D, 0x2D,
+ 0x72, 0x29, 0x3E, 0x6C, 0x98, 0xED, 0x15, 0x12, 0xEF, 0x06, 0x8F, 0x91,
+ 0xFC, 0x88, 0x0A, 0x84, 0xE0, 0xD8, 0x6B, 0x49, 0xB6, 0x86, 0x81, 0xAB,
+ 0xCB, 0xD3, 0xFA, 0xC0, 0x12, 0x82, 0x6E, 0xF2, 0x19, 0x7F, 0x72, 0x46,
+ 0x81, 0x47, 0xAB, 0x39, 0x29, 0x5F, 0x26, 0x76, 0x11, 0x9E, 0x70, 0x28,
+ 0x04, 0xF4, 0xA3, 0xE4, 0x0A, 0xED, 0x37, 0xF2, 0xB2, 0x8A, 0x98, 0x09,
+ 0x7B, 0xE7, 0xB0, 0x80, 0xEE, 0x69, 0xE1, 0x7D, 0x11, 0x15, 0xC8, 0xDB,
+ 0x6A, 0x4B, 0xAA, 0x5C, 0x64, 0x3F, 0xD7, 0x43, 0x68, 0x67, 0xE2, 0x5B,
+ 0xB4, 0xBD, 0x32, 0x4F, 0x7E, 0x36, 0x2A, 0x28, 0x93, 0xB8, 0xDF, 0x56,
+ 0xA8, 0x79, 0x77, 0x3E, 0x4A, 0x15, 0x58, 0xB4, 0x64, 0x92, 0xBF, 0x76,
+ 0x2B, 0x2E, 0x5A, 0xF0, 0x9B, 0x5C, 0xE2, 0x98, 0xE3, 0x92, 0xF0, 0x38,
+ 0xC8, 0x07, 0x90, 0x01, 0x91, 0xDB, 0x4E, 0x7D, 0xAF, 0x08, 0xBB, 0x45,
+ 0x99, 0xAE, 0x6A, 0xEB, 0x0E, 0xA6, 0x42, 0xF7, 0x13, 0x4A, 0x78, 0x11,
+ 0x96, 0x1C, 0x68, 0x9F, 0x51, 0x11, 0x54, 0x48, 0x82, 0xCD, 0x05, 0x10,
+ 0xBB, 0x71, 0x87, 0x84, 0x25, 0x1B, 0xA0, 0xCF, 0x09, 0xA4, 0x0A, 0x89,
+ 0xC9, 0xDE, 0xD5, 0x2E, 0x4B, 0x42, 0x37, 0xDA, 0x4B, 0x41, 0x74, 0x8B,
+ 0x18, 0xDD, 0x76, 0xC5, 0x6D, 0xF6, 0xD2, 0xE3, 0xE9, 0xF4, 0x4C, 0x8C,
+ 0x2A, 0xEA, 0xC6, 0x6B, 0x8A, 0x95, 0xB5, 0x83, 0x98, 0xBD, 0x37, 0xD9,
+ 0x94, 0x8A, 0x90, 0x42, 0x12, 0xC0, 0x4D, 0x78, 0x9C, 0xCE, 0x78, 0x00,
+ 0x3A, 0xEF, 0x46, 0x2E, 0xDF, 0xD5, 0x80, 0xDA, 0x37, 0xE0, 0x02, 0x15,
+ 0x06, 0x80, 0x78, 0x60, 0x11, 0x7B, 0x6E, 0xC0, 0x7D, 0xD4, 0x93, 0x37,
+ 0x85, 0xDA, 0xDB, 0xFC, 0x66, 0x96, 0xD0, 0x7B, 0xF3, 0x51, 0x8A, 0xFE,
+ 0xF9, 0xA9, 0xBF, 0x15, 0xCD, 0x91, 0x32, 0x53, 0x28, 0xF4, 0xEC, 0xFC,
+ 0x61, 0xA4, 0xAD, 0x88, 0x1A, 0xE0, 0xD4, 0xAE, 0x96, 0x0E, 0xDB, 0xBE,
+ 0x7E, 0x4D, 0x69, 0x33, 0x23, 0xE8, 0x2D, 0x42, 0x0F, 0x3E, 0x00, 0x2A,
+ 0x1F, 0x8C, 0xCB, 0xCB, 0xD2, 0x65, 0x7D, 0xAD, 0xC1, 0x5F, 0xF0, 0x2C,
+ 0xFD, 0x4C, 0xF4, 0x9D, 0x10, 0x09, 0x43, 0x41, 0xDD, 0x97, 0xC2, 0x9D,
+ 0xE8, 0xB7, 0x7F, 0xE6, 0x5B, 0x9E, 0x2A, 0x69, 0x24, 0xCC, 0x0D, 0x17,
+ 0xD0, 0x07, 0x23, 0x5D, 0x61, 0x36, 0x3C, 0xE5, 0x7B, 0x3C, 0x27, 0x7E,
+ 0xD8, 0xF0, 0x71, 0x17, 0x81, 0x00, 0x2D, 0x50, 0x7C, 0x02, 0x30, 0x32,
+ 0x43, 0x42, 0x57, 0x35, 0x80, 0x72, 0xED, 0x97, 0x09, 0x2C, 0xC0, 0x64,
+ 0x0F, 0x40, 0x22, 0x7E, 0x76, 0x4F, 0xEE, 0x60, 0x7F, 0xED, 0x67, 0x62,
+ 0xE1, 0x36, 0x55, 0x99, 0xD5, 0x53, 0x44, 0x36, 0x67, 0xA4, 0x60, 0x57,
+ 0x19, 0x17, 0x3E, 0xB9, 0x67, 0x80, 0xA6, 0x40, 0x7E, 0xED, 0x91, 0x71,
+ 0x9B, 0xF1, 0x1F, 0x74, 0xA5, 0x5F, 0xD7, 0x36, 0x81, 0xCC, 0x02, 0x21,
+ 0xD1, 0xC2, 0x1D, 0xAD, 0x46, 0x83, 0x01, 0x80, 0x5D, 0x65, 0x35, 0x55,
+ 0x80, 0xE4, 0x82, 0xDF, 0xC0, 0x00, 0x0C, 0x30, 0x39, 0x03, 0x90, 0x82,
+ 0x00, 0x30, 0x1B, 0x2B, 0x31, 0x0B, 0x44, 0x38, 0x66, 0x2A, 0x78, 0x80,
+ 0x6B, 0xA7, 0x80, 0x60, 0x93, 0x79, 0x15, 0x67, 0x56, 0x64, 0xF4, 0x6F,
+ 0x9B, 0x00, 0x31, 0x33, 0xB0, 0x00, 0x71, 0x24, 0x47, 0xAD, 0xD5, 0x2C,
+ 0x23, 0x30, 0x7A, 0x90, 0x01, 0x0A, 0x39, 0xA8, 0x83, 0xAB, 0xD4, 0x34,
+ 0x66, 0xC5, 0x44, 0x21, 0xA3, 0x23, 0x61, 0xF7, 0x56, 0xB3, 0x30, 0x7B,
+ 0xF0, 0xD2, 0x84, 0xCA, 0x60, 0x01, 0xAF, 0x17, 0x0C, 0x0E, 0x20, 0x48,
+ 0x3A, 0x22, 0xFE, 0x79, 0x53, 0x75, 0x72, 0x95, 0xC2, 0x0F, 0xD4, 0xE3,
+ 0x0D, 0x53, 0xA6, 0x83, 0xFB, 0x20, 0x86, 0xCA, 0xE7, 0x74, 0x24, 0x92,
+ 0x6B, 0x66, 0x75, 0x42, 0xFC, 0x77, 0x17, 0xB0, 0x80, 0x87, 0x92, 0x55,
+ 0x6E, 0xD3, 0x80, 0x0B, 0x75, 0xB6, 0x4D, 0x11, 0x60, 0x01, 0x12, 0x50,
+ 0x7B, 0xBF, 0x20, 0x13, 0x15, 0x20, 0x01, 0x17, 0x87, 0x0B, 0x0A, 0x38,
+ 0x7B, 0x8C, 0x47, 0x4C, 0xEA, 0x37, 0x75, 0xFC, 0xF0, 0x52, 0xDC, 0x00,
+ 0x60, 0x80, 0xD8, 0x0F, 0x67, 0x94, 0x81, 0x13, 0x58, 0x60, 0xD6, 0x77,
+ 0x86, 0x2A, 0xC1, 0x80, 0x13, 0x57, 0x1F, 0xA5, 0xB0, 0x7B, 0xAF, 0xA0,
+ 0x02, 0x1A, 0x40, 0x1F, 0x97, 0x65, 0x4E, 0x13, 0x50, 0x89, 0x17, 0x21,
+ 0x76, 0x17, 0xD0, 0x00, 0x21, 0xA0, 0x39, 0xE1, 0x67, 0x0A, 0x25, 0x30,
+ 0x87, 0x0A, 0x65, 0x56, 0x00, 0x33, 0x7F, 0xF0, 0x37, 0x4F, 0x64, 0x42,
+ 0x30, 0x28, 0xA0, 0x8A, 0xA7, 0x78, 0x08, 0x09, 0x03, 0x7A, 0xA7, 0x58,
+ 0x86, 0x85, 0x97, 0x54, 0x27, 0x04, 0x69, 0x07, 0xF2, 0x7B, 0xE3, 0x43,
+ 0x69, 0x00, 0xE8, 0x4E, 0x5E, 0xB1, 0x89, 0xC1, 0x20, 0x09, 0xDE, 0x08,
+ 0x0B, 0x0D, 0x40, 0x01, 0x12, 0x10, 0x01, 0x9F, 0x38, 0x8B, 0x9A, 0x18,
+ 0x16, 0x72, 0x47, 0x4C, 0x7A, 0x08, 0x8D, 0x35, 0x28, 0x8A, 0xA2, 0x22,
+ 0x81, 0xD1, 0xC8, 0x09, 0xD3, 0x78, 0x8F, 0x86, 0xD0, 0x1C, 0xAD, 0x34,
+ 0x55, 0xEB, 0x06, 0x66, 0xC6, 0xF7, 0x60, 0xEA, 0x01, 0x72, 0x8C, 0xC8,
+ 0x4B, 0xEB, 0x11, 0x4E, 0xF1, 0xE2, 0x78, 0x62, 0x81, 0x01, 0x27, 0x20,
+ 0x01, 0x25, 0x10, 0x89, 0xA4, 0x50, 0x8C, 0x4F, 0x35, 0x8C, 0x7E, 0x84,
+ 0x1C, 0x2E, 0xC7, 0x0E, 0x41, 0x73, 0x91, 0x01, 0xF0, 0x2D, 0x28, 0x50,
+ 0x70, 0xFA, 0x68, 0x08, 0xFA, 0xFE, 0x46, 0x8D, 0xF7, 0x58, 0x26, 0x86,
+ 0x68, 0x56, 0x05, 0x70, 0x71, 0x40, 0xD8, 0x0D, 0x9C, 0xB5, 0x82, 0xC1,
+ 0x50, 0x90, 0xAE, 0x54, 0x02, 0xE2, 0xB8, 0x16, 0x1C, 0xA0, 0x00, 0xB8,
+ 0xD1, 0x63, 0x11, 0x15, 0x4E, 0xAF, 0xF0, 0x8B, 0x12, 0x20, 0x8C, 0xE1,
+ 0xD1, 0x8E, 0xAF, 0xE0, 0x92, 0x16, 0xF5, 0x17, 0x33, 0x88, 0x91, 0xB3,
+ 0x00, 0x6B, 0x84, 0x30, 0x2D, 0x01, 0x30, 0x60, 0x1F, 0x19, 0x44, 0x1C,
+ 0xF8, 0x91, 0x01, 0x10, 0x0A, 0x91, 0x05, 0x48, 0x94, 0x75, 0x20, 0x99,
+ 0xF7, 0x80, 0xA5, 0xB0, 0x26, 0xB9, 0x68, 0x49, 0x05, 0xA0, 0x90, 0xB5,
+ 0xA8, 0x01, 0xB0, 0xE2, 0x6E, 0x8D, 0x50, 0x15, 0xAC, 0xF1, 0x7F, 0x38,
+ 0x49, 0x00, 0xE7, 0x98, 0x8E, 0x46, 0x38, 0x15, 0x70, 0xB2, 0x8E, 0xAE,
+ 0x94, 0x0E, 0xDA, 0xB5, 0x0F, 0x82, 0x23, 0x00, 0x2E, 0x76, 0x08, 0x30,
+ 0x00, 0x86, 0x34, 0xC8, 0x94, 0xCA, 0xD8, 0x7E, 0xCD, 0xD1, 0x65, 0x66,
+ 0xF5, 0x63, 0x2A, 0x90, 0x7D, 0x46, 0x15, 0x74, 0xA6, 0x80, 0x2A, 0x6D,
+ 0x62, 0x4E, 0xBE, 0xC2, 0x89, 0x0A, 0x50, 0x54, 0x60, 0x49, 0x6E, 0xCF,
+ 0x40, 0x0B, 0x06, 0xC0, 0x00, 0x1A, 0xA0, 0x00, 0x0E, 0x50, 0x5F, 0x38,
+ 0x09, 0x91, 0xBA, 0x47, 0x57, 0xC8, 0xF1, 0x87, 0xEC, 0xE0, 0x4C, 0x07,
+ 0xA0, 0x91, 0x4E, 0x79, 0x58, 0x42, 0xE1, 0x99, 0xFA, 0x58, 0x26, 0xD7,
+ 0xD8, 0x97, 0xC0, 0x80, 0x00, 0x29, 0xA9, 0x08, 0x72, 0x75, 0x0A, 0x27,
+ 0xD0, 0x00, 0x14, 0x39, 0x40, 0x87, 0x09, 0x0B, 0x89, 0x99, 0x48, 0xB0,
+ 0x70, 0x5F, 0x2A, 0xA3, 0x8D, 0xDE, 0xC0, 0x00, 0xAA, 0x11, 0x45, 0xB5,
+ 0x64, 0x95, 0x48, 0xF6, 0x17, 0x76, 0xB9, 0x09, 0x5C, 0x35, 0x0B, 0x9F,
+ 0xA9, 0x09, 0x78, 0x59, 0x9C, 0x87, 0xF0, 0x2D, 0xFE, 0xBA, 0xD5, 0x57,
+ 0x3F, 0xB6, 0x53, 0x29, 0xB9, 0x24, 0xF5, 0xA6, 0x1E, 0x34, 0x91, 0x96,
+ 0x27, 0xB3, 0x26, 0x19, 0xD0, 0x27, 0xDE, 0x30, 0x39, 0xF7, 0xE5, 0x68,
+ 0xAF, 0x40, 0x76, 0xEC, 0xB2, 0x01, 0x43, 0xC8, 0x01, 0x0E, 0x40, 0x96,
+ 0xC0, 0x07, 0x62, 0x55, 0x05, 0x19, 0x72, 0xB4, 0x67, 0xA2, 0xA9, 0x8F,
+ 0x4C, 0x19, 0x9C, 0xD1, 0x98, 0x30, 0x3E, 0x70, 0x5A, 0x11, 0x70, 0x6C,
+ 0x08, 0xC0, 0x01, 0x5E, 0xC9, 0x0D, 0x55, 0xC9, 0x3D, 0x11, 0x20, 0x01,
+ 0x21, 0x70, 0x7B, 0x94, 0xA3, 0x27, 0x73, 0x18, 0x39, 0xBF, 0x31, 0x39,
+ 0x13, 0x44, 0x2E, 0x00, 0x19, 0x2B, 0x8F, 0x69, 0x02, 0xAD, 0x71, 0x76,
+ 0xF8, 0xC5, 0x36, 0xEB, 0x89, 0x9C, 0x86, 0xF1, 0x49, 0x4D, 0xD9, 0x5A,
+ 0x22, 0xD0, 0x01, 0x0B, 0xE0, 0x9E, 0x57, 0x28, 0x14, 0x09, 0x96, 0x69,
+ 0xC6, 0x08, 0x39, 0x0E, 0xF0, 0xA1, 0x7F, 0x32, 0x13, 0x13, 0xB0, 0x9F,
+ 0xFD, 0x19, 0x93, 0x9A, 0xE7, 0x24, 0xDC, 0x49, 0x20, 0x80, 0xA9, 0x84,
+ 0xEB, 0x03, 0x09, 0xE6, 0x25, 0x5F, 0xBF, 0xF7, 0x8E, 0x53, 0x75, 0x33,
+ 0x0F, 0x0A, 0xA1, 0x49, 0xD1, 0x87, 0x13, 0x3A, 0x58, 0xCD, 0xA3, 0x94,
+ 0xFD, 0xD0, 0x1C, 0x31, 0xE6, 0x59, 0x11, 0x60, 0xA2, 0x61, 0x61, 0x99,
+ 0xC7, 0x30, 0xA2, 0xFC, 0xE9, 0x9F, 0x38, 0x39, 0x00, 0x69, 0x42, 0x8B,
+ 0x3B, 0xB5, 0xA2, 0x2C, 0xFA, 0x0A, 0x63, 0x66, 0x36, 0xB0, 0x28, 0x32,
+ 0x8C, 0x03, 0x62, 0x34, 0x6A, 0xA3, 0x21, 0xD2, 0x1C, 0xA6, 0x46, 0x62,
+ 0xFA, 0xE6, 0x2C, 0x43, 0xB9, 0x0F, 0xDC, 0x26, 0x6E, 0xF2, 0xD9, 0xA1,
+ 0x61, 0xC1, 0x84, 0xAC, 0x60, 0xA4, 0x25, 0x9A, 0xA4, 0x17, 0x41, 0xA4,
+ 0xC5, 0x31, 0x59, 0x5F, 0x43, 0x27, 0x93, 0x33, 0x66, 0x3F, 0xA2, 0xFE,
+ 0x61, 0x31, 0x0A, 0x62, 0x05, 0x03, 0xA1, 0x24, 0xC0, 0x85, 0x8F, 0x81,
+ 0x83, 0xF2, 0x68, 0x4F, 0xDC, 0x51, 0x29, 0xF8, 0xC4, 0xA3, 0xFB, 0xD0,
+ 0x87, 0x1B, 0x8A, 0x5F, 0x9A, 0x46, 0x01, 0x9C, 0x86, 0x0B, 0x17, 0x10,
+ 0x9D, 0xA7, 0x80, 0xA6, 0x48, 0xAA, 0xA6, 0xED, 0xA1, 0x02, 0x0A, 0xA0,
+ 0x23, 0x73, 0xC5, 0x20, 0xC8, 0x95, 0x88, 0x2C, 0x91, 0x79, 0xEC, 0x73,
+ 0x9B, 0xCA, 0x36, 0x32, 0x4A, 0xB7, 0x5B, 0x7F, 0x51, 0xA3, 0x13, 0xD8,
+ 0xA5, 0x56, 0xB2, 0x14, 0xC7, 0xC9, 0x87, 0x6E, 0x34, 0x4A, 0xCA, 0x83,
+ 0xA3, 0x84, 0x50, 0x58, 0x46, 0xD9, 0x0F, 0x04, 0xF3, 0xA3, 0x48, 0x36,
+ 0xA2, 0x11, 0x50, 0xAB, 0xB5, 0xBA, 0x8E, 0x8E, 0x2A, 0xA4, 0x38, 0xE9,
+ 0x00, 0x92, 0xAA, 0x01, 0x0C, 0x70, 0x28, 0x23, 0x63, 0xA6, 0xF8, 0x11,
+ 0x5F, 0xB1, 0xC2, 0x00, 0x2D, 0x5A, 0x57, 0xB0, 0xF0, 0x73, 0x2A, 0xF4,
+ 0x7B, 0x6C, 0x69, 0x51, 0xB4, 0x96, 0x97, 0x4E, 0xE7, 0x4C, 0x6F, 0x29,
+ 0x0F, 0xA8, 0x97, 0xA3, 0x9D, 0xD0, 0xA5, 0xD7, 0x61, 0x7A, 0x13, 0x13,
+ 0x34, 0x3E, 0x93, 0x30, 0x7B, 0xCA, 0x34, 0x62, 0x0A, 0x87, 0x8E, 0x10,
+ 0x01, 0x25, 0x70, 0xA4, 0xBA, 0x1A, 0x4E, 0xBC, 0xAA, 0x00, 0xBE, 0xEA,
+ 0xA4, 0x93, 0x03, 0x94, 0xF8, 0x41, 0x1A, 0xA9, 0xB9, 0x61, 0xE6, 0xF8,
+ 0x08, 0x5F, 0xA6, 0x6C, 0x02, 0xD0, 0x1A, 0xEE, 0x6A, 0x56, 0xB4, 0x66,
+ 0x85, 0x64, 0xD8, 0x0D, 0x83, 0x18, 0x3A, 0xD9, 0x05, 0xAD, 0x01, 0x40,
+ 0x29, 0xB4, 0xF0, 0xAA, 0xD1, 0xB2, 0x13, 0xD0, 0xF1, 0x02, 0xFC, 0x9A,
+ 0x13, 0xA1, 0xC0, 0x68, 0xC1, 0x47, 0xAE, 0x12, 0x40, 0x01, 0x0D, 0xB0,
+ 0x76, 0x49, 0x9A, 0xAE, 0xEB, 0x6A, 0x35, 0x24, 0xF7, 0xA9, 0x0C, 0xD2,
+ 0x75, 0x03, 0xFE, 0xC0, 0x6B, 0xEB, 0x34, 0xAF, 0xBC, 0xF5, 0x0A, 0x47,
+ 0xF7, 0x3D, 0x24, 0x37, 0x85, 0xA7, 0xF5, 0x28, 0xA2, 0xDA, 0x79, 0xCD,
+ 0x82, 0x02, 0x2F, 0x40, 0x30, 0x5F, 0x3A, 0x68, 0x5A, 0x2A, 0xB0, 0x18,
+ 0x32, 0x05, 0x57, 0x20, 0x05, 0xDC, 0x20, 0x92, 0xA1, 0x22, 0x7A, 0xA0,
+ 0x12, 0x34, 0x49, 0x54, 0x0E, 0x11, 0x68, 0x26, 0x34, 0x40, 0x03, 0x37,
+ 0xF0, 0x70, 0xE4, 0x03, 0xB1, 0x12, 0x4B, 0xB1, 0xBB, 0xDA, 0xAB, 0xBF,
+ 0x2A, 0x5A, 0xC6, 0x1A, 0x3C, 0x28, 0x32, 0x59, 0xDE, 0x59, 0xAC, 0x20,
+ 0xDB, 0x08, 0x03, 0x82, 0x9D, 0x1A, 0xA6, 0x86, 0xD1, 0xF5, 0xB3, 0x02,
+ 0xF0, 0xAF, 0x2A, 0x1B, 0x3F, 0x41, 0xE3, 0x9E, 0x24, 0xD0, 0x14, 0x38,
+ 0xCB, 0x0E, 0x00, 0xA1, 0x05, 0x5A, 0x47, 0x0B, 0x5C, 0x0B, 0x19, 0x7D,
+ 0x48, 0x52, 0x63, 0x32, 0x19, 0xE5, 0xF0, 0x28, 0xB4, 0xD0, 0x8A, 0x85,
+ 0x63, 0xB4, 0x13, 0x0B, 0xA9, 0x74, 0xA8, 0xB4, 0x4E, 0x6A, 0x40, 0xEF,
+ 0x85, 0x22, 0xA4, 0x61, 0xB5, 0x07, 0xD2, 0xB4, 0xFF, 0xE9, 0x08, 0x73,
+ 0x6A, 0xAF, 0x93, 0xB3, 0x48, 0xBB, 0x75, 0x41, 0x7B, 0xF8, 0x91, 0xCD,
+ 0x12, 0x21, 0x8C, 0xC5, 0x0E, 0xF3, 0xA3, 0x08, 0x9A, 0xB9, 0x99, 0x02,
+ 0x00, 0x05, 0x09, 0x97, 0x04, 0x54, 0xC0, 0x05, 0xCF, 0xF6, 0x33, 0x55,
+ 0x02, 0x03, 0x02, 0xDB, 0x09, 0x26, 0x76, 0x53, 0xCA, 0xF0, 0x17, 0x2C,
+ 0x20, 0x47, 0x00, 0x51, 0x9A, 0x26, 0x83, 0xB4, 0xB5, 0x84, 0x00, 0x0E,
+ 0x30, 0x93, 0x17, 0x6B, 0xAF, 0xF6, 0x52, 0x9B, 0x27, 0xD2, 0x40, 0x1E,
+ 0x4B, 0x27, 0x1C, 0x76, 0x1E, 0x4A, 0xD7, 0x40, 0x03, 0x98, 0x9B, 0x0A,
+ 0xC0, 0x00, 0x53, 0x4A, 0x80, 0x82, 0xB9, 0x5B, 0xF0, 0xA4, 0x08, 0x18,
+ 0x7A, 0x6A, 0xF4, 0xB0, 0x2D, 0xFE, 0xCD, 0x32, 0xB6, 0xE2, 0x75, 0x3A,
+ 0x0B, 0xEB, 0x09, 0xD2, 0xB1, 0x05, 0x95, 0x1B, 0x05, 0x56, 0x90, 0xB9,
+ 0x13, 0x23, 0x5B, 0x27, 0x26, 0x26, 0x82, 0xD3, 0x8F, 0xC7, 0x10, 0x03,
+ 0x6D, 0xD3, 0x2C, 0xD8, 0x6B, 0x32, 0xE7, 0xCA, 0x89, 0xAB, 0x9B, 0x1A,
+ 0xDE, 0xE7, 0xBA, 0xED, 0x26, 0x90, 0x0C, 0x82, 0x56, 0x74, 0x62, 0x0B,
+ 0x9E, 0xE1, 0x08, 0x1C, 0x8B, 0x9B, 0x2E, 0x41, 0x17, 0x92, 0xEA, 0x02,
+ 0xE3, 0xCB, 0x0D, 0xB8, 0x21, 0xA3, 0x16, 0x55, 0x55, 0xA0, 0xA3, 0x8F,
+ 0xFF, 0x70, 0x4C, 0xCD, 0xF2, 0xB2, 0x84, 0xF0, 0xB8, 0x51, 0xD2, 0xA7,
+ 0xCC, 0x2B, 0x00, 0x51, 0x60, 0xB9, 0x5D, 0xC0, 0x70, 0x1E, 0xE2, 0x3A,
+ 0x0F, 0xF0, 0x2D, 0xD3, 0x9A, 0x1D, 0x67, 0x54, 0x92, 0xC8, 0xA0, 0x87,
+ 0x31, 0xD5, 0x2C, 0x10, 0x5C, 0x33, 0x37, 0xF9, 0x0C, 0xE1, 0x2B, 0xBF,
+ 0xE4, 0xAB, 0x42, 0xC1, 0x7A, 0x22, 0xAF, 0x17, 0xAF, 0x8A, 0x90, 0x79,
+ 0xE3, 0xD8, 0x08, 0xF5, 0xBA, 0x63, 0x61, 0x31, 0xBF, 0x4F, 0x3A, 0x00,
+ 0xF9, 0x3A, 0xA3, 0xB3, 0xB0, 0xBC, 0x9D, 0x97, 0x00, 0x83, 0xF0, 0x00,
+ 0x06, 0x4B, 0x08, 0x03, 0x33, 0x0B, 0x06, 0xC3, 0x4F, 0x59, 0xE0, 0x05,
+ 0x36, 0xCB, 0x0D, 0xD6, 0x7A, 0x85, 0x2C, 0xD0, 0x13, 0x8F, 0xD1, 0x67,
+ 0x00, 0x47, 0x22, 0x7C, 0x49, 0x0A, 0x31, 0x50, 0x03, 0x3E, 0x20, 0x03,
+ 0x4A, 0xAC, 0xC4, 0x4A, 0x86, 0x14, 0xD9, 0x54, 0x38, 0xE4, 0xE2, 0x00,
+ 0xE2, 0xBB, 0xC1, 0xCA, 0xD6, 0xAE, 0x27, 0x42, 0x1A, 0xB0, 0xB8, 0x51,
+ 0x6F, 0x01, 0x8C, 0xBA, 0x33, 0x59, 0xA9, 0x29, 0x16, 0xBD, 0x97, 0x9B,
+ 0xB2, 0x18, 0x5D, 0x5A, 0xA6, 0x08, 0x69, 0xEB, 0x74, 0xA4, 0xF4, 0x49,
+ 0x4B, 0xB6, 0x58, 0xDD, 0x90, 0x3A, 0xD0, 0x7A, 0xFE, 0x3A, 0x28, 0xE0,
+ 0xBF, 0xFF, 0x13, 0x34, 0xCB, 0x19, 0x62, 0x3B, 0x70, 0x03, 0x34, 0x00,
+ 0x58, 0x2D, 0x71, 0x58, 0xB4, 0xB0, 0x02, 0x3C, 0xE0, 0x03, 0x44, 0x2B,
+ 0x2F, 0xB4, 0x13, 0xC6, 0x54, 0x2C, 0x5A, 0x19, 0xDB, 0x20, 0x05, 0x35,
+ 0xBB, 0x2D, 0x41, 0x72, 0xE2, 0x90, 0x66, 0x2F, 0xCA, 0x12, 0x36, 0x14,
+ 0x16, 0xB0, 0xB8, 0xB7, 0xD1, 0x95, 0x2C, 0x51, 0x32, 0xBC, 0x80, 0xF8,
+ 0x77, 0xFE, 0x26, 0x26, 0x83, 0xB1, 0x13, 0x2F, 0xF0, 0x00, 0x9D, 0xFB,
+ 0x5A, 0x23, 0xD6, 0x49, 0x26, 0x26, 0xB7, 0x47, 0x2C, 0x03, 0x70, 0x7B,
+ 0x23, 0x12, 0x13, 0x97, 0xB4, 0xF0, 0x03, 0x0E, 0x6B, 0x2A, 0x9C, 0x5A,
+ 0xC8, 0xCA, 0x06, 0xB8, 0x04, 0xD0, 0x20, 0xED, 0xDB, 0x53, 0xE7, 0x51,
+ 0x98, 0x93, 0x30, 0xB8, 0xBF, 0x95, 0x0B, 0x00, 0x40, 0xAE, 0x66, 0x13,
+ 0xB5, 0xBD, 0x06, 0xBB, 0x0D, 0x3A, 0x6D, 0x36, 0xCA, 0x62, 0x42, 0x24,
+ 0xC7, 0xA6, 0x1A, 0x00, 0x5F, 0xB8, 0xA7, 0x5F, 0xE5, 0xA5, 0xD1, 0xF2,
+ 0x01, 0x7A, 0x2A, 0x0F, 0x41, 0xA3, 0xC4, 0x79, 0x6C, 0x3B, 0x51, 0x47,
+ 0xB0, 0x7D, 0x1C, 0xAE, 0x8D, 0x02, 0x48, 0xB2, 0x6C, 0xAF, 0x94, 0x8C,
+ 0x1F, 0x25, 0xDC, 0x12, 0x44, 0x28, 0x55, 0x89, 0x6C, 0x17, 0x71, 0x8A,
+ 0xAC, 0x8D, 0x59, 0x59, 0x71, 0x87, 0x64, 0xA1, 0x18, 0x25, 0x2E, 0x4C,
+ 0x83, 0x33, 0x57, 0x5D, 0xD6, 0x95, 0x00, 0xCF, 0x0C, 0x21, 0xCA, 0x9C,
+ 0x14, 0x15, 0xA3, 0xAD, 0x57, 0x68, 0x40, 0x9D, 0xA9, 0xB0, 0x58, 0x22,
+ 0xCD, 0x28, 0x05, 0x03, 0x04, 0xD3, 0xBD, 0x7A, 0x82, 0x0B, 0x79, 0xFB,
+ 0xCD, 0x37, 0x02, 0x9E, 0x22, 0xCC, 0xA6, 0x68, 0xF1, 0xC1, 0xBF, 0x71,
+ 0x1E, 0xC2, 0xDA, 0x08, 0xB1, 0xCC, 0x12, 0x4B, 0x62, 0x2C, 0xA4, 0xFE,
+ 0x31, 0xB2, 0x02, 0x90, 0xCE, 0x48, 0x26, 0x62, 0x3D, 0xE3, 0x94, 0x1A,
+ 0x74, 0x1D, 0xF9, 0xBC, 0x4C, 0xCC, 0xC1, 0x0D, 0xF1, 0xBC, 0x0F, 0xD4,
+ 0x25, 0x0F, 0x65, 0xD8, 0x12, 0x1D, 0xC0, 0x02, 0x2C, 0x35, 0x02, 0x23,
+ 0xAD, 0x09, 0xFA, 0x06, 0xBA, 0x8D, 0xC2, 0x5E, 0x0A, 0x1D, 0x32, 0x0C,
+ 0x2D, 0x99, 0xA2, 0x36, 0x00, 0x95, 0x5A, 0x1C, 0x8F, 0xCC, 0x12, 0xB4,
+ 0x3C, 0x3E, 0x29, 0x2A, 0xCC, 0xC3, 0x46, 0xCC, 0x8D, 0x00, 0xB5, 0xBF,
+ 0xA1, 0xA9, 0x93, 0x27, 0x03, 0xB4, 0xF0, 0xD1, 0xA7, 0xF8, 0x00, 0xA7,
+ 0x93, 0x3A, 0xED, 0x47, 0x70, 0xCE, 0x12, 0xB9, 0xFD, 0x70, 0x77, 0xD8,
+ 0x35, 0x7A, 0xCC, 0x01, 0x01, 0xA4, 0x18, 0x25, 0xD0, 0x03, 0xD3, 0x3B,
+ 0x4B, 0x2A, 0xC7, 0x82, 0x2B, 0x37, 0x2D, 0x2B, 0x0C, 0x60, 0x02, 0x3A,
+ 0x9D, 0xA4, 0x13, 0x6D, 0x19, 0xBC, 0x9C, 0x9D, 0x8B, 0x68, 0x0A, 0xE4,
+ 0x82, 0xA9, 0x8A, 0x10, 0xCE, 0x53, 0x31, 0x23, 0xDF, 0xF4, 0xD6, 0x93,
+ 0xA7, 0x03, 0x3F, 0x00, 0x58, 0x07, 0xF0, 0x02, 0x98, 0x6C, 0x4F, 0x25,
+ 0x0D, 0x21, 0x7F, 0x9D, 0x55, 0x50, 0x6D, 0x4D, 0xDA, 0x41, 0x0F, 0x22,
+ 0xC0, 0x55, 0x2F, 0xDB, 0x87, 0xB3, 0x20, 0x02, 0x5A, 0x38, 0xD8, 0x49,
+ 0x81, 0x4F, 0x02, 0x10, 0x9F, 0xA6, 0x62, 0xA0, 0x65, 0x2D, 0x00, 0x39,
+ 0xED, 0x00, 0x3B, 0x8D, 0x93, 0x2B, 0x5C, 0x19, 0x2A, 0xF1, 0x1B, 0xAD,
+ 0xD1, 0xD3, 0x8F, 0xF0, 0xD3, 0xDD, 0x00, 0x77, 0x0C, 0x1A, 0x96, 0x5E,
+ 0x67, 0x17, 0x80, 0xAB, 0xB1, 0x1C, 0xA7, 0x03, 0xA9, 0x9C, 0x5D, 0x33,
+ 0x00, 0xD9, 0xFF, 0x13, 0xD8, 0x90, 0xDB, 0xB9, 0x83, 0x15, 0xD2, 0xC8,
+ 0xDB, 0x3F, 0xFA, 0x70, 0x14, 0x99, 0x20, 0x5B, 0xD0, 0x04, 0xCA, 0xF6,
+ 0x03, 0x0A, 0xFE, 0x0E, 0x67, 0x2A, 0x83, 0x4C, 0xC5, 0x99, 0xBD, 0xD9,
+ 0x38, 0x89, 0x01, 0x0D, 0xB0, 0x93, 0x11, 0x40, 0x9D, 0x7C, 0x51, 0xD1,
+ 0xB4, 0xF9, 0x0A, 0x9F, 0x48, 0x1A, 0x1E, 0x30, 0x93, 0xBC, 0x0B, 0x3C,
+ 0x81, 0xFB, 0x08, 0x03, 0x82, 0xC2, 0xAB, 0xDD, 0x84, 0x35, 0x80, 0xB8,
+ 0xB4, 0xF0, 0x41, 0xFD, 0xB5, 0x67, 0xCE, 0x13, 0xD3, 0x4E, 0xF7, 0xB8,
+ 0x10, 0x20, 0xC0, 0x9D, 0x10, 0x53, 0xCC, 0x48, 0x97, 0x42, 0xC1, 0x7E,
+ 0x21, 0xE4, 0x58, 0x39, 0xF0, 0xCA, 0x3C, 0x02, 0xDD, 0x2A, 0x04, 0x02,
+ 0x43, 0x98, 0xD6, 0x76, 0x2B, 0x1C, 0xCB, 0xAD, 0x39, 0xCE, 0x6D, 0x1C,
+ 0xF6, 0xDD, 0x0D, 0x74, 0x2D, 0x09, 0x62, 0xE1, 0x01, 0xF1, 0xBB, 0x92,
+ 0x2E, 0x9A, 0x4E, 0xAA, 0x3D, 0xB5, 0x2A, 0xE8, 0x03, 0xC1, 0x8B, 0x4A,
+ 0xD0, 0xE4, 0xA7, 0x30, 0x20, 0x02, 0xD2, 0xB6, 0x00, 0xE6, 0x2D, 0x7D,
+ 0x09, 0xD0, 0x1C, 0x81, 0x96, 0x1D, 0x68, 0x64, 0x3C, 0x67, 0xD4, 0xC3,
+ 0xCA, 0x73, 0x46, 0xE4, 0x95, 0x26, 0xDE, 0x2C, 0x5A, 0x1D, 0x06, 0xA9,
+ 0xCA, 0xCD, 0xDC, 0xFF, 0xDD, 0x20, 0x2A, 0xA3, 0xAC, 0xB4, 0x30, 0xE0,
+ 0x90, 0x70, 0x42, 0x38, 0x99, 0x95, 0xE4, 0xC2, 0xDD, 0x0C, 0xDE, 0x84,
+ 0x96, 0xCC, 0x0D, 0x07, 0x10, 0xE1, 0x1C, 0xE4, 0x55, 0xDA, 0x0C, 0x01,
+ 0x17, 0xAE, 0x83, 0x21, 0xDD, 0x01, 0x56, 0xED, 0x09, 0xC2, 0xBB, 0x55,
+ 0xEE, 0xA0, 0x4C, 0x9D, 0x44, 0x9A, 0xA6, 0x82, 0xD0, 0x30, 0x4A, 0x4B,
+ 0x61, 0x91, 0xE2, 0xFE, 0xAD, 0x35, 0x2A, 0x73, 0xA0, 0x8A, 0xD0, 0x1A,
+ 0x8C, 0xB7, 0x66, 0x75, 0x5B, 0x99, 0x91, 0x50, 0xE3, 0x76, 0x41, 0x72,
+ 0x6B, 0x8D, 0x76, 0x0F, 0xCE, 0x12, 0x3B, 0xAE, 0xDE, 0xB5, 0xB5, 0x00,
+ 0x3F, 0x6E, 0xE1, 0x58, 0xAA, 0xFE, 0x09, 0xA8, 0x97, 0x5D, 0x41, 0x4E,
+ 0x08, 0x2F, 0x60, 0x7A, 0xCA, 0x62, 0xDB, 0xDC, 0x22, 0x14, 0x75, 0xEC,
+ 0x24, 0x36, 0x5D, 0x0B, 0x43, 0xC8, 0x1A, 0x19, 0xE0, 0x00, 0xBD, 0x2B,
+ 0x00, 0x0C, 0x20, 0x6A, 0x74, 0xB6, 0xE2, 0xE2, 0x92, 0xA2, 0x56, 0x7E,
+ 0xAF, 0xB9, 0x91, 0x0A, 0x05, 0x10, 0x01, 0x29, 0x50, 0x89, 0x42, 0x1A,
+ 0x2F, 0xA4, 0xDD, 0x0D, 0x1C, 0xDD, 0x84, 0x3A, 0x20, 0x03, 0xF0, 0xE3,
+ 0xD8, 0xF9, 0xE3, 0x4C, 0x42, 0xE4, 0xD2, 0x27, 0x25, 0xDB, 0x92, 0x42,
+ 0xE1, 0xCE, 0xA3, 0xE6, 0x6B, 0xEE, 0xB9, 0x7F, 0xC7, 0xB6, 0x91, 0x71,
+ 0x08, 0xC0, 0x5D, 0x52, 0x3B, 0x51, 0xC4, 0x3D, 0x32, 0x1B, 0xAB, 0x31,
+ 0x99, 0x09, 0x28, 0xD7, 0xDE, 0x90, 0x23, 0xED, 0xB4, 0x3B, 0x86, 0x3E,
+ 0xA0, 0xBE, 0x8C, 0x0C, 0x10, 0x7B, 0x02, 0x03, 0x22, 0x09, 0xDB, 0x8D,
+ 0xCE, 0xC7, 0x6A, 0x80, 0x35, 0x40, 0x6B, 0x6E, 0x2E, 0x30, 0xA0, 0x6E,
+ 0x17, 0xFF, 0xCC, 0x52, 0xA9, 0xBE, 0xDE, 0x2B, 0xC5, 0x52, 0x5C, 0x5D,
+ 0x8A, 0xAA, 0x3A, 0xEA, 0x39, 0x41, 0x30, 0x6E, 0xFC, 0x99, 0x41, 0x23,
+ 0xB7, 0x69, 0xB2, 0x6E, 0xBB, 0xFA, 0xE7, 0x0D, 0x41, 0x96, 0x0D, 0xE0,
+ 0xD0, 0xB6, 0x52, 0xE5, 0xBF, 0x11, 0xC9, 0x45, 0x58, 0x0E, 0x15, 0xD0,
+ 0x2F, 0x6D, 0xAD, 0x92, 0xE6, 0x3B, 0x79, 0xC3, 0x4E, 0x0B, 0xFC, 0x8C,
+ 0xE4, 0xB6, 0x03, 0x01, 0x71, 0xCE, 0x02, 0xDA, 0xCC, 0x12, 0x28, 0x20,
+ 0x02, 0xD2, 0x83, 0x9C, 0x80, 0x71, 0xC6, 0xD2, 0x48, 0x22, 0x52, 0xAD,
+ 0xB8, 0xD5, 0xD7, 0x28, 0xE5, 0x18, 0x4E, 0x47, 0xC2, 0x2E, 0x06, 0x70,
+ 0xE2, 0x03, 0xA0, 0x0B, 0x8D, 0xA3, 0x32, 0x84, 0xCC, 0x0D, 0x3A, 0xC2,
+ 0xDA, 0xE7, 0xC0, 0xB1, 0xB9, 0x1B, 0x69, 0x46, 0xFE, 0xCD, 0x71, 0x31,
+ 0x70, 0x67, 0xD4, 0xC4, 0x0E, 0xD4, 0x2B, 0x97, 0x0F, 0x90, 0x85, 0x2D,
+ 0xFB, 0xEC, 0x21, 0xD3, 0x99, 0xF2, 0x1E, 0x47, 0xA3, 0xDE, 0x87, 0x82,
+ 0xBA, 0x1D, 0x7F, 0x17, 0xC7, 0xFA, 0x78, 0xED, 0x8D, 0x22, 0xE3, 0x2D,
+ 0xD2, 0x90, 0x16, 0xA0, 0xED, 0x03, 0xE0, 0xE7, 0xDF, 0x09, 0xE5, 0xAF,
+ 0xF0, 0x1A, 0x54, 0xFE, 0x68, 0x07, 0x32, 0x7B, 0x8C, 0x7A, 0x0E, 0x48,
+ 0x3D, 0x4E, 0xBF, 0xDB, 0xD1, 0x96, 0x9E, 0xAD, 0x79, 0xF9, 0xA7, 0x80,
+ 0x61, 0x3D, 0xD2, 0x0C, 0x03, 0x2D, 0xD5, 0x52, 0x30, 0xFD, 0xE6, 0xFA,
+ 0xB8, 0x5A, 0x8F, 0xD1, 0x4C, 0xCE, 0xC2, 0x02, 0x30, 0xCD, 0xEF, 0x59,
+ 0x45, 0x30, 0xAC, 0xCE, 0x23, 0x0D, 0xD4, 0x00, 0x30, 0xBF, 0x39, 0x91,
+ 0x10, 0xA4, 0xA7, 0x29, 0xEB, 0xB9, 0x59, 0x64, 0x1C, 0xA3, 0x35, 0x05,
+ 0xA5, 0x59, 0xD1, 0x0D, 0xA5, 0x05, 0x81, 0x5C, 0x28, 0x6C, 0x00, 0x30,
+ 0x7E, 0x5A, 0x7F, 0x75, 0x1D, 0x66, 0x2E, 0x30, 0xA7, 0xE4, 0x91, 0xD2,
+ 0x0E, 0x40, 0xDC, 0xF0, 0xEE, 0xFB, 0xD0, 0xE6, 0xB4, 0x40, 0x83, 0x09,
+ 0xA0, 0x08, 0x77, 0xEE, 0x24, 0x5E, 0xDF, 0x2B, 0x32, 0x4F, 0xF3, 0xEC,
+ 0x42, 0xEB, 0x1C, 0x65, 0xBF, 0x69, 0xE2, 0xE4, 0x40, 0xA2, 0x78, 0xAF,
+ 0x79, 0x0A, 0x68, 0xB8, 0xE0, 0xC6, 0x85, 0x64, 0x7B, 0x3D, 0x5B, 0x74,
+ 0x9E, 0x41, 0x81, 0x75, 0xF7, 0x63, 0x42, 0xD0, 0x6C, 0x74, 0xF9, 0x09,
+ 0xA0, 0xC9, 0x29, 0xAB, 0x55, 0xF0, 0x49, 0x3E, 0x5C, 0x99, 0x01, 0x7F,
+ 0xBE, 0x19, 0x8A, 0xD2, 0x22, 0xE0, 0x8E, 0x22, 0x91, 0x0E, 0xC9, 0x77,
+ 0x22, 0x01, 0x8F, 0x3F, 0x09, 0x8E, 0x17, 0xAF, 0x93, 0xD3, 0xF3, 0x9E,
+ 0xF5, 0xB3, 0x1D, 0x60, 0xF5, 0x9A, 0xA0, 0xC9, 0x27, 0xAD, 0xF9, 0xFE,
+ 0x83, 0xDA, 0xD4, 0xBA, 0x0F, 0x92, 0x2D, 0x4C, 0x83, 0x4D, 0x11, 0xC8,
+ 0x8D, 0x33, 0x01, 0x9C, 0xA6, 0x2E, 0x19, 0x85, 0xF0, 0xCD, 0x8A, 0x22,
+ 0xE4, 0x42, 0xD4, 0x2D, 0xF1, 0x88, 0xD5, 0x60, 0x5A, 0xC9, 0xB0, 0x95,
+ 0xB8, 0xE0, 0xBE, 0xDD, 0x70, 0xD1, 0x1D, 0x7D, 0xA7, 0xDA, 0x81, 0xAD,
+ 0xF1, 0xE3, 0xFB, 0x21, 0xB2, 0x46, 0x63, 0xA8, 0x14, 0x04, 0xD3, 0xC0,
+ 0xA7, 0x16, 0x34, 0x06, 0xED, 0x34, 0xEA, 0x16, 0x0C, 0x87, 0x94, 0x4F,
+ 0x1B, 0x00, 0xE5, 0xAB, 0x6F, 0xCB, 0xF5, 0x42, 0x27, 0xB3, 0x32, 0x67,
+ 0x0C, 0xF5, 0x9A, 0x16, 0x70, 0x71, 0x49, 0x08, 0xF4, 0xD2, 0xCD, 0x71,
+ 0xB4, 0x96, 0xB6, 0x80, 0xF0, 0x10, 0x30, 0x48, 0x18, 0x40, 0xC2, 0x22,
+ 0x90, 0xA8, 0x78, 0xF0, 0x51, 0xE8, 0xF8, 0x08, 0x19, 0x29, 0x39, 0x49,
+ 0x59, 0x69, 0x79, 0x89, 0xF9, 0x71, 0xA0, 0x88, 0x92, 0x80, 0x59, 0x38,
+ 0x92, 0x78, 0xE0, 0xF9, 0x59, 0x6A, 0x7A, 0xF9, 0x91, 0xB8, 0x12, 0x03,
+ 0xD0, 0xEA, 0xFA, 0x0A, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x1B,
+ 0x5B, 0x72, 0x31, 0xC0, 0xDB, 0xDB, 0x62, 0xA0, 0x18, 0x2C, 0x3C, 0x4C,
+ 0x9C, 0xC8, 0xE0, 0xD1, 0x2B, 0x81, 0xBB, 0xCC, 0xDC, 0xEC, 0x0C, 0x40,
+ 0xD0, 0xCB, 0x50, 0x5C, 0x6C, 0x82, 0xD0, 0x8B, 0xCD, 0x7B, 0x71, 0x22,
+ 0x61, 0x11, 0x51, 0x20, 0x5B, 0x51, 0x12, 0xB2, 0x8B, 0x8D, 0x00, 0x42,
+ 0xAD, 0x08, 0xD2, 0x7B, 0xF1, 0xEC, 0xFE, 0x0E, 0x1F, 0x2F, 0xEF, 0xBA,
+ 0x23, 0x4A, 0x4A, 0xC9, 0x72, 0x1F, 0x90, 0xF0, 0x42, 0x7D, 0x30, 0x72,
+ 0x2A, 0xA0, 0xC0, 0x81, 0x04, 0x25, 0x69, 0x52, 0xD4, 0x81, 0x50, 0x02,
+ 0x11, 0x24, 0x2A, 0x25, 0xD8, 0x24, 0x60, 0x41, 0xC1, 0x89, 0xA6, 0x3A,
+ 0x24, 0xF2, 0xFE, 0x31, 0x2F, 0xA3, 0xC6, 0x59, 0x15, 0x4E, 0x64, 0x1B,
+ 0xE0, 0x01, 0x5D, 0xBA, 0x91, 0xC5, 0x14, 0xF4, 0x0A, 0xB1, 0x31, 0x25,
+ 0x3C, 0x0A, 0xBD, 0x1C, 0x90, 0x14, 0x66, 0x40, 0x41, 0x86, 0x8F, 0x34,
+ 0x79, 0x11, 0x68, 0xD0, 0xA0, 0x26, 0xAF, 0x0C, 0x22, 0x47, 0xB6, 0xE8,
+ 0x45, 0x41, 0xA5, 0xD0, 0xA1, 0x44, 0x61, 0xDD, 0x10, 0xD5, 0x88, 0x12,
+ 0x84, 0x17, 0x84, 0x66, 0x40, 0x4C, 0x84, 0x63, 0xC5, 0x30, 0x80, 0x14,
+ 0xAB, 0x5A, 0xBD, 0x4A, 0x28, 0x94, 0x22, 0x11, 0x83, 0x16, 0x08, 0x80,
+ 0x51, 0x49, 0x44, 0xA2, 0x4E, 0x58, 0xCB, 0x3A, 0xF2, 0x2A, 0x80, 0x46,
+ 0xD1, 0xB5, 0xCD, 0x52, 0x44, 0x33, 0x67, 0xE2, 0xA5, 0x5C, 0x61, 0x1A,
+ 0x7A, 0x35, 0x60, 0x8B, 0x17, 0x56, 0x04, 0x6C, 0xD3, 0xE6, 0x2A, 0x72,
+ 0xA1, 0xE2, 0x9A, 0xCE, 0xC1, 0xD8, 0x7E, 0xC9, 0x9D, 0xC9, 0xAB, 0x44,
+ 0xDE, 0xC5, 0x8C, 0x71, 0xC5, 0x90, 0x21, 0x0A, 0xEC, 0x24, 0x08, 0x02,
+ 0x48, 0x3C, 0x40, 0x11, 0x2C, 0x87, 0x8E, 0x56, 0x3E, 0xA4, 0x06, 0x93,
+ 0x38, 0x30, 0x01, 0xE5, 0x44, 0x22, 0xF4, 0x99, 0x3D, 0x8D, 0xE9, 0xC1,
+ 0xD3, 0x19, 0x01, 0x2C, 0x52, 0x95, 0xF4, 0x40, 0x91, 0x20, 0xD4, 0x65,
+ 0xB5, 0xAE, 0xD8, 0xDC, 0xB8, 0xF1, 0x04, 0x0C, 0x1F, 0x55, 0x6C, 0xF0,
+ 0x0B, 0x9C, 0x01, 0xBB, 0xDC, 0x78, 0x73, 0xF2, 0x72, 0x09, 0x3C, 0x18,
+ 0x03, 0x05, 0x0E, 0x08, 0xD7, 0xE4, 0xF0, 0x5B, 0xAE, 0x70, 0x9B, 0xC4,
+ 0xAB, 0x5B, 0x07, 0x60, 0x03, 0x47, 0xA2, 0x17, 0x0D, 0x23, 0x51, 0x7E,
+ 0x9A, 0xE8, 0x06, 0x2B, 0x57, 0x3A, 0x68, 0x08, 0xEB, 0x90, 0xD4, 0x54,
+ 0x02, 0x8B, 0xC1, 0x3A, 0x98, 0xA6, 0x0D, 0x3F, 0x52, 0xEC, 0xAD, 0x89,
+ 0xD2, 0x43, 0x4A, 0x80, 0x59, 0xFE, 0x00, 0xEB, 0xF8, 0x56, 0x0F, 0x0A,
+ 0xE8, 0x71, 0x1D, 0x5B, 0x05, 0x84, 0xF0, 0x51, 0x06, 0x2E, 0x24, 0x27,
+ 0x40, 0x4C, 0xC0, 0x90, 0x64, 0x00, 0x36, 0x01, 0x0E, 0xB5, 0x57, 0x2F,
+ 0x07, 0x22, 0x28, 0x0C, 0x08, 0x2E, 0x28, 0xC0, 0x81, 0x03, 0xC8, 0x14,
+ 0xE8, 0x40, 0x0B, 0x2E, 0x2C, 0x38, 0x97, 0x0A, 0x40, 0x3D, 0x48, 0x22,
+ 0x5E, 0x31, 0x68, 0x27, 0x80, 0x7B, 0x91, 0xF4, 0xA3, 0x08, 0x0D, 0xB8,
+ 0xC9, 0x72, 0x94, 0x30, 0xA0, 0x95, 0x22, 0xD6, 0x30, 0x07, 0x48, 0x56,
+ 0xD5, 0x21, 0x10, 0xEC, 0x08, 0x01, 0x0B, 0xB3, 0xF1, 0x07, 0x89, 0x56,
+ 0x8B, 0x50, 0x82, 0x16, 0x04, 0x40, 0x56, 0xF5, 0x50, 0x22, 0x3C, 0x94,
+ 0x38, 0x94, 0x2E, 0x1F, 0x19, 0x96, 0x1C, 0x03, 0xD7, 0x20, 0x30, 0xE1,
+ 0x48, 0xD8, 0x4C, 0xC0, 0xE4, 0x46, 0xC6, 0x0D, 0x80, 0x00, 0x88, 0x14,
+ 0x7E, 0x29, 0xD7, 0x06, 0xD8, 0x44, 0x90, 0x65, 0x99, 0x2A, 0xD9, 0xE0,
+ 0x19, 0x04, 0x0B, 0xD8, 0xD7, 0x95, 0x22, 0x3B, 0xDC, 0x62, 0x9E, 0x30,
+ 0x10, 0xBC, 0x37, 0x49, 0x2A, 0x02, 0xB0, 0x40, 0xC2, 0x07, 0x2C, 0x46,
+ 0x64, 0xD5, 0x65, 0xC4, 0xBC, 0x76, 0x64, 0x21, 0x35, 0x26, 0x62, 0xA4,
+ 0x24, 0x24, 0x88, 0xD2, 0x5D, 0xA0, 0xA1, 0xB1, 0x87, 0xC3, 0x78, 0x66,
+ 0xCA, 0xD3, 0xD1, 0x47, 0x21, 0x51, 0xF8, 0x13, 0x36, 0x2A, 0x78, 0x49,
+ 0x4C, 0x73, 0xBC, 0x90, 0xF9, 0x68, 0x3C, 0x13, 0x58, 0x0A, 0x66, 0xA8,
+ 0x2F, 0x71, 0xD0, 0x0B, 0x06, 0x9D, 0x9E, 0x2A, 0x4F, 0x0F, 0xC1, 0x14,
+ 0x5A, 0xC8, 0xA1, 0x89, 0x38, 0x4A, 0x4B, 0x0C, 0x39, 0x0C, 0x83, 0x02,
+ 0x9B, 0x93, 0xD4, 0xF8, 0xA3, 0x45, 0x07, 0x58, 0x95, 0x64, 0x8A, 0x22,
+ 0x3C, 0x30, 0x83, 0x6C, 0x8A, 0x3A, 0xC2, 0x1E, 0xFE, 0x9F, 0x92, 0x20,
+ 0xF2, 0xD5, 0xB0, 0x03, 0x7D, 0x90, 0xDF, 0x0A, 0x36, 0xA0, 0x0A, 0x8F,
+ 0x5B, 0xD9, 0x20, 0x10, 0x17, 0x82, 0x20, 0x6C, 0x98, 0x4D, 0x06, 0x7D,
+ 0x15, 0x23, 0x22, 0x2F, 0xCA, 0x40, 0xEB, 0x8E, 0x04, 0x85, 0x89, 0x4A,
+ 0x2E, 0x31, 0xD3, 0xF1, 0x62, 0x01, 0xB8, 0xEA, 0x36, 0x83, 0x62, 0x22,
+ 0x3F, 0x12, 0x52, 0x63, 0x0D, 0x8E, 0xCD, 0x2A, 0xCC, 0x3F, 0x97, 0x40,
+ 0xC4, 0xD5, 0x20, 0x94, 0x31, 0x55, 0xD5, 0x7C, 0x07, 0x24, 0xAA, 0x15,
+ 0x0B, 0xCA, 0x12, 0x32, 0x9F, 0x00, 0xEF, 0x3A, 0x32, 0xDF, 0x7E, 0x03,
+ 0xAB, 0xC7, 0x9E, 0xB3, 0xEB, 0x3A, 0x13, 0xA1, 0xA5, 0xD1, 0x25, 0x67,
+ 0xCD, 0x60, 0x50, 0x0E, 0x63, 0x12, 0x2F, 0x28, 0x3D, 0xDC, 0x0C, 0x6F,
+ 0xBD, 0x68, 0x50, 0x6E, 0xC8, 0x09, 0x62, 0x6B, 0x2A, 0xC7, 0x26, 0xCF,
+ 0x12, 0xA7, 0x3D, 0x8E, 0xB8, 0xBA, 0xA4, 0x63, 0x3B, 0xA4, 0xAC, 0x48,
+ 0x3E, 0x95, 0x70, 0x92, 0x15, 0x0A, 0x07, 0x13, 0x34, 0x9F, 0x69, 0x16,
+ 0xA1, 0x50, 0xD5, 0x0C, 0x6B, 0x9A, 0x42, 0xE8, 0x64, 0x77, 0x2E, 0x1C,
+ 0xD0, 0x68, 0x0E, 0x9F, 0x8C, 0xCB, 0xA7, 0xBD, 0x18, 0x48, 0xA1, 0x01,
+ 0x9A, 0xF6, 0x42, 0x40, 0x08, 0x6F, 0x2D, 0xBD, 0x6D, 0x30, 0x75, 0xF1,
+ 0x72, 0x17, 0xD2, 0xB7, 0x54, 0x30, 0xF5, 0x00, 0x20, 0x8B, 0x2C, 0x6A,
+ 0xA5, 0x9B, 0x6A, 0x4D, 0x36, 0x00, 0x89, 0x74, 0x80, 0xAC, 0x8A, 0x82,
+ 0x0A, 0x90, 0x83, 0x33, 0x31, 0x06, 0x73, 0x23, 0x25, 0xF9, 0x09, 0xF0,
+ 0x1A, 0x9D, 0xCB, 0x26, 0xA2, 0xF0, 0x3E, 0x98, 0xED, 0x5A, 0xD0, 0x7A,
+ 0xA2, 0x00, 0xEA, 0x10, 0xDE, 0x92, 0x04, 0x5B, 0x19, 0xD1, 0xA6, 0xD4,
+ 0x78, 0x74, 0xD9, 0xB5, 0x60, 0x83, 0xE9, 0x5C, 0x2E, 0x08, 0x56, 0xFE,
+ 0x6A, 0x05, 0x00, 0x14, 0xE0, 0x51, 0x36, 0x17, 0x1B, 0x33, 0x9C, 0xE2,
+ 0xB4, 0x28, 0xDD, 0x8B, 0x02, 0x60, 0x83, 0x79, 0x35, 0x2F, 0x41, 0x69,
+ 0x7E, 0xB2, 0x28, 0x83, 0x0A, 0xDC, 0x6A, 0x22, 0xCF, 0x36, 0xF3, 0x76,
+ 0x30, 0xA5, 0x0D, 0xBE, 0x88, 0xAD, 0x55, 0x21, 0x9B, 0x9E, 0x9D, 0xA8,
+ 0x13, 0x54, 0x6C, 0x22, 0x80, 0x4F, 0x02, 0x43, 0x7D, 0x91, 0x24, 0x99,
+ 0x2F, 0x6A, 0x30, 0x1C, 0x90, 0xF7, 0x40, 0x68, 0xE1, 0xB0, 0x3A, 0xE9,
+ 0xB3, 0x94, 0x33, 0x40, 0xD5, 0x72, 0x19, 0x20, 0x76, 0x32, 0xB0, 0x94,
+ 0xD0, 0xF5, 0x00, 0xDA, 0x06, 0xD3, 0x60, 0x2F, 0xCA, 0xCF, 0x62, 0x41,
+ 0x36, 0x97, 0x7E, 0x9E, 0x5C, 0xE8, 0x03, 0x5C, 0x00, 0xCE, 0xF6, 0x0F,
+ 0xD3, 0x2B, 0x4C, 0xF0, 0xFA, 0x0A, 0xF0, 0xC3, 0x33, 0x90, 0x0D, 0xD3,
+ 0x41, 0xA2, 0x8E, 0xF8, 0xAD, 0xC8, 0x02, 0x76, 0x13, 0x84, 0xD6, 0x3F,
+ 0x49, 0x89, 0x85, 0xA3, 0x40, 0xF3, 0xB1, 0xB0, 0x80, 0x4D, 0xF0, 0xEC,
+ 0x12, 0x88, 0x18, 0x20, 0x24, 0x68, 0x47, 0x1B, 0x3B, 0xDD, 0xCC, 0x14,
+ 0x23, 0xC8, 0x0F, 0x0D, 0x60, 0x65, 0xBE, 0x57, 0x6C, 0xE9, 0x6B, 0x73,
+ 0x01, 0x01, 0x62, 0xD8, 0xC1, 0x29, 0x58, 0x50, 0xEE, 0x49, 0x20, 0xBA,
+ 0x52, 0x04, 0x61, 0xD1, 0x3D, 0x6C, 0x5C, 0x0F, 0x7C, 0x72, 0x11, 0xDF,
+ 0x00, 0xB0, 0xF4, 0x41, 0x75, 0xA1, 0x89, 0x18, 0xEA, 0xEB, 0x1D, 0x0E,
+ 0xDC, 0x61, 0x03, 0xF4, 0x2D, 0x62, 0x81, 0x5D, 0x79, 0x8A, 0xCD, 0xB0,
+ 0x02, 0x83, 0xD1, 0x20, 0xA5, 0x2A, 0x62, 0x41, 0x9D, 0xDF, 0xF8, 0x55,
+ 0x09, 0x8B, 0x14, 0x8F, 0x10, 0xBD, 0x4B, 0x11, 0x7C, 0xB4, 0x42, 0x43,
+ 0x54, 0xCC, 0xAD, 0x7D, 0x29, 0x8C, 0x05, 0x81, 0x78, 0xE1, 0xB9, 0xB9,
+ 0x64, 0x0C, 0xFE, 0x1B, 0x14, 0x28, 0xDF, 0x2C, 0xA8, 0x97, 0xAD, 0xBE,
+ 0x3C, 0x2D, 0x83, 0x4D, 0x9C, 0x40, 0xF5, 0x2E, 0x47, 0x42, 0x62, 0x98,
+ 0x20, 0x1B, 0xE9, 0x6A, 0xA2, 0xBA, 0x62, 0x50, 0x83, 0x34, 0xD6, 0xE0,
+ 0x7D, 0xC6, 0x1A, 0xC4, 0x26, 0xE4, 0xE5, 0x8E, 0xCE, 0x4C, 0xC5, 0x50,
+ 0x2F, 0xC0, 0x97, 0x59, 0x48, 0x90, 0xC3, 0x4D, 0xF0, 0x6D, 0x22, 0x94,
+ 0x99, 0x51, 0x92, 0xE4, 0x17, 0x09, 0xC2, 0xC9, 0xAE, 0x57, 0xFD, 0x33,
+ 0xCB, 0x7C, 0x00, 0xF9, 0x09, 0xFF, 0x08, 0xE0, 0x4D, 0x66, 0x84, 0x85,
+ 0xB8, 0x78, 0xA1, 0x82, 0x30, 0x3D, 0xCD, 0x26, 0x8A, 0xB9, 0xC5, 0x06,
+ 0x2D, 0x67, 0x80, 0x6E, 0x0D, 0xE0, 0x5B, 0x8D, 0xDC, 0xCD, 0xB4, 0xA2,
+ 0x18, 0x46, 0x98, 0x68, 0x12, 0x5D, 0x8D, 0x44, 0x5A, 0x3D, 0x7C, 0x37,
+ 0x08, 0xB1, 0xDC, 0x00, 0x1E, 0x31, 0x68, 0x5D, 0x22, 0x66, 0x04, 0x09,
+ 0x12, 0x2C, 0x00, 0x02, 0x88, 0xBC, 0x4A, 0x0E, 0x59, 0x55, 0x10, 0x44,
+ 0xC0, 0x92, 0x32, 0x43, 0x5C, 0x99, 0x00, 0x23, 0x81, 0x16, 0x20, 0xA2,
+ 0x26, 0x36, 0x09, 0x09, 0x88, 0x90, 0x56, 0x00, 0xC7, 0x52, 0xBA, 0x22,
+ 0x62, 0xC8, 0x19, 0x89, 0x06, 0x20, 0x87, 0x35, 0xC9, 0x31, 0x03, 0x8B,
+ 0x22, 0xD4, 0xE4, 0xC6, 0x4A, 0x39, 0xA0, 0x02, 0x29, 0xA0, 0x71, 0x9F,
+ 0xAB, 0x18, 0x36, 0xCA, 0xA8, 0x4C, 0x93, 0xF1, 0xE0, 0x6C, 0xA4, 0x70,
+ 0x61, 0xAA, 0x3C, 0xB3, 0x95, 0xFB, 0x19, 0x2E, 0x20, 0xC3, 0xB3, 0x0F,
+ 0x65, 0x70, 0x09, 0x89, 0x1A, 0x15, 0x72, 0x10, 0xAE, 0x82, 0xE7, 0x69,
+ 0xC4, 0x62, 0xCF, 0x4B, 0x1C, 0x33, 0x79, 0xE1, 0x04, 0x00, 0xE7, 0x06,
+ 0x30, 0x92, 0x4C, 0x7E, 0x24, 0x05, 0xEE, 0x28, 0xC0, 0x96, 0x3E, 0x92,
+ 0xB5, 0x70, 0x46, 0x80, 0x79, 0xFE, 0xBD, 0x40, 0x00, 0x07, 0x7A, 0x02,
+ 0x36, 0x0D, 0x5C, 0x90, 0x92, 0xFD, 0x3C, 0x99, 0x0E, 0x3C, 0x73, 0xBB,
+ 0x44, 0xBC, 0xE8, 0x1D, 0xAD, 0x3C, 0x4F, 0x2D, 0xD7, 0x49, 0x91, 0x22,
+ 0xE6, 0x53, 0x21, 0x9B, 0x28, 0xE6, 0x23, 0xC4, 0xF2, 0xAF, 0xF8, 0x10,
+ 0x6E, 0xA4, 0x94, 0xD8, 0x67, 0x45, 0x5F, 0xC1, 0x38, 0x6A, 0x30, 0x60,
+ 0xA2, 0x03, 0xC0, 0x00, 0x0A, 0xDF, 0x21, 0xAD, 0x8F, 0xB4, 0xA3, 0xA2,
+ 0x05, 0x90, 0x40, 0xF5, 0x76, 0xD2, 0x02, 0xE7, 0x7D, 0x69, 0x03, 0x32,
+ 0xF9, 0x08, 0x06, 0xA4, 0xF9, 0x52, 0x8E, 0xB1, 0x51, 0x32, 0x88, 0x68,
+ 0x99, 0x3C, 0x74, 0xE0, 0x4A, 0xFB, 0x81, 0x14, 0x49, 0x0F, 0x28, 0xA2,
+ 0x00, 0x84, 0xF9, 0x08, 0xAD, 0xF4, 0xD2, 0x4E, 0xB0, 0xBC, 0xE7, 0x56,
+ 0x18, 0xA8, 0x88, 0xC4, 0x25, 0x95, 0x79, 0x42, 0x4D, 0x44, 0xF4, 0x34,
+ 0x66, 0x45, 0x78, 0x54, 0xE0, 0xA0, 0xDA, 0x4B, 0x6A, 0x4F, 0x7F, 0xDA,
+ 0x12, 0x05, 0x30, 0x80, 0x9B, 0x23, 0x61, 0x40, 0x0B, 0xB0, 0x85, 0x0D,
+ 0x02, 0x70, 0x32, 0xA9, 0x1C, 0x8B, 0x81, 0x22, 0xF8, 0x45, 0x38, 0x08,
+ 0xC2, 0x03, 0xAA, 0xE8, 0x14, 0x00, 0x04, 0x92, 0x38, 0x55, 0x4C, 0x0C,
+ 0x2A, 0x11, 0x1F, 0x1D, 0x04, 0xB2, 0x6A, 0x89, 0x52, 0x75, 0x16, 0xA4,
+ 0xAA, 0x3A, 0x14, 0x80, 0xEC, 0x26, 0x21, 0x24, 0xCD, 0xF0, 0xD5, 0x15,
+ 0x13, 0x1C, 0xC6, 0xB5, 0xB2, 0x41, 0x00, 0x2E, 0xCE, 0x23, 0xA7, 0xBD,
+ 0xB8, 0xE9, 0x4B, 0x7B, 0xCA, 0x50, 0x9A, 0x20, 0xC0, 0x01, 0x1C, 0x50,
+ 0x80, 0x06, 0x18, 0x00, 0xDB, 0xD8, 0xC2, 0xD6, 0x04, 0x0A, 0x50, 0x01,
+ 0x5E, 0x3F, 0x42, 0x01, 0xA4, 0x6E, 0x96, 0x63, 0xE3, 0x34, 0xA2, 0x21,
+ 0x12, 0x91, 0xCC, 0x8C, 0x3C, 0xA6, 0xB0, 0x28, 0xFE, 0x98, 0x41, 0x63,
+ 0x13, 0x3B, 0x33, 0xC3, 0x1A, 0x77, 0x12, 0x09, 0x38, 0xDB, 0x7D, 0x5E,
+ 0x69, 0x48, 0x11, 0xCC, 0xED, 0xAB, 0x9F, 0xC8, 0xAC, 0x60, 0x5F, 0xFA,
+ 0xC4, 0x01, 0x80, 0x32, 0x11, 0xDE, 0xEC, 0xC5, 0x09, 0xD2, 0xAA, 0x91,
+ 0xB5, 0x8E, 0x69, 0xB7, 0xAD, 0x28, 0x01, 0x4B, 0x9C, 0x83, 0x5E, 0x9A,
+ 0x10, 0x20, 0xB7, 0xE4, 0x45, 0xDA, 0x0A, 0x0B, 0x17, 0x00, 0xCC, 0xC8,
+ 0x40, 0x28, 0xC3, 0x4D, 0xDF, 0x71, 0x91, 0xBB, 0xA2, 0xDD, 0x41, 0x02,
+ 0x2D, 0xBD, 0x0C, 0x96, 0x01, 0xFB, 0x93, 0x3B, 0x61, 0x20, 0x36, 0xAB,
+ 0x8A, 0xC8, 0xC1, 0x75, 0x5F, 0xFA, 0xC8, 0x01, 0x44, 0x32, 0x11, 0x4E,
+ 0x03, 0x2D, 0x41, 0x8B, 0x92, 0xD3, 0xBD, 0x92, 0xD7, 0xBC, 0xA9, 0x4D,
+ 0x6F, 0x4D, 0x4E, 0x60, 0x01, 0xF0, 0xB6, 0x57, 0xA9, 0xBA, 0x1B, 0x44,
+ 0x3F, 0x9C, 0xAA, 0x92, 0xFA, 0xBA, 0x6E, 0x9E, 0xF8, 0x25, 0x48, 0x92,
+ 0x46, 0x01, 0x09, 0xCC, 0x0C, 0xD8, 0x14, 0x24, 0xA8, 0x63, 0x30, 0x68,
+ 0xD0, 0xAE, 0xDB, 0x59, 0xA2, 0x60, 0x06, 0xDE, 0x30, 0x00, 0x98, 0x99,
+ 0x88, 0xC7, 0x65, 0xE3, 0xA8, 0x78, 0x11, 0xEF, 0x35, 0x6D, 0x0C, 0x80,
+ 0x0A, 0x58, 0x20, 0x04, 0x6C, 0x4D, 0x2F, 0x06, 0x42, 0x50, 0x02, 0x0D,
+ 0x03, 0xF9, 0x61, 0xEF, 0xDB, 0x4F, 0xEF, 0x56, 0xB0, 0x96, 0x18, 0xF8,
+ 0xA0, 0x5D, 0xA2, 0x90, 0x6A, 0x89, 0x0B, 0x42, 0xB8, 0xAE, 0x0E, 0x22,
+ 0x14, 0x2C, 0x65, 0xF1, 0x08, 0x2A, 0x9B, 0x03, 0x19, 0xB0, 0x22, 0x18,
+ 0x2B, 0x26, 0x84, 0x7F, 0x6A, 0x6C, 0xE3, 0x7F, 0x42, 0xEF, 0x23, 0x12,
+ 0x66, 0x4B, 0x0A, 0x4E, 0xB0, 0xE4, 0x70, 0x44, 0xC0, 0x02, 0x12, 0x90,
+ 0x00, 0x4E, 0xEE, 0x7C, 0xE7, 0x3A, 0x97, 0x40, 0xB4, 0x71, 0x3E, 0xFE,
+ 0x95, 0x1A, 0xFF, 0x2C, 0x03, 0x19, 0xF0, 0x00, 0x45, 0x0A, 0x49, 0xC4,
+ 0x03, 0xD9, 0xA2, 0x83, 0x97, 0xC1, 0x6D, 0x01, 0xF7, 0xBD, 0x32, 0x25,
+ 0x74, 0x45, 0x27, 0x15, 0x13, 0x84, 0x04, 0x23, 0x78, 0xC1, 0x74, 0xD3,
+ 0x22, 0xE6, 0x56, 0xD4, 0x40, 0x11, 0x5D, 0x76, 0x84, 0x7F, 0x6E, 0x13,
+ 0x67, 0x6C, 0xDC, 0xF6, 0x02, 0x7C, 0xEE, 0xB3, 0xA9, 0x4F, 0x4D, 0x8B,
+ 0x1A, 0xF8, 0x40, 0x06, 0x37, 0xA0, 0x81, 0x0C, 0xD3, 0x21, 0xE3, 0xD1,
+ 0xA0, 0x19, 0xD1, 0x3F, 0x28, 0x6C, 0x07, 0x96, 0xEB, 0xE8, 0x4F, 0xB8,
+ 0x4A, 0x7D, 0x84, 0xF0, 0xCA, 0x7F, 0x75, 0x3D, 0x02, 0xE9, 0x0E, 0x83,
+ 0x06, 0x32, 0x08, 0x2E, 0x00, 0x52, 0x76, 0xD9, 0x47, 0x28, 0x92, 0x9F,
+ 0x36, 0xAE, 0xB0, 0xE8, 0x94, 0x8C, 0xEA, 0x68, 0xF7, 0xD9, 0x06, 0x3E,
+ 0xB8, 0xC1, 0xAB, 0xFD, 0x02, 0x4B, 0xC2, 0xB1, 0xED, 0xC0, 0xF4, 0xDD,
+ 0xC1, 0x0F, 0xA8, 0xDC, 0x81, 0x11, 0x48, 0x36, 0xD7, 0x83, 0x10, 0xE4,
+ 0x23, 0x92, 0x84, 0xD5, 0x4A, 0xB4, 0x38, 0xC0, 0x6C, 0xFB, 0x41, 0x0F,
+ 0xAE, 0xBB, 0x69, 0xD2, 0xA0, 0xE2, 0x29, 0x8C, 0x8C, 0x73, 0x91, 0x09,
+ 0x50, 0x49, 0x69, 0xEB, 0x3B, 0xCE, 0x36, 0x90, 0x01, 0xCC, 0x48, 0x82,
+ 0xB6, 0x05, 0x08, 0x7C, 0x01, 0x22, 0x18, 0x0D, 0x2C, 0x5D, 0xA5, 0x8A,
+ 0x7A, 0x2F, 0xA6, 0x07, 0xBD, 0x15, 0x85, 0x9A, 0xC4, 0x4D, 0xEE, 0x48,
+ 0xEC, 0x0C, 0x12, 0xFD, 0x48, 0xA9, 0x25, 0x3E, 0x30, 0x83, 0x00, 0xE3,
+ 0xE0, 0x06, 0x3B, 0xD8, 0xA8, 0x2C, 0x1A, 0x3E, 0xEE, 0x00, 0x28, 0x52,
+ 0xE1, 0x4B, 0xCE, 0x6E, 0x34, 0xF7, 0x8D, 0xF2, 0x0D, 0xF7, 0xE0, 0x06,
+ 0x85, 0xF5, 0x87, 0x9A, 0x60, 0x90, 0x6C, 0x91, 0x9B, 0x06, 0x2D, 0x2D,
+ 0x32, 0x76, 0xFE, 0x5E, 0x6A, 0xE0, 0x6A, 0x2A, 0x43, 0x40, 0x04, 0x3F,
+ 0x8B, 0x78, 0x00, 0xE6, 0xA3, 0xE5, 0x24, 0xF5, 0xB2, 0x10, 0xC0, 0x62,
+ 0x01, 0x78, 0xD2, 0xE2, 0x03, 0x66, 0xD3, 0xC2, 0x06, 0x31, 0xBB, 0x38,
+ 0xBD, 0x51, 0x9D, 0xE0, 0x01, 0x3C, 0x38, 0xE5, 0x54, 0x7F, 0xA9, 0x0E,
+ 0x64, 0xD0, 0x72, 0xF8, 0xBD, 0x60, 0x06, 0x0F, 0x08, 0xB9, 0x24, 0xE8,
+ 0x17, 0x8C, 0x1B, 0x78, 0x7C, 0x31, 0xFF, 0x0E, 0x06, 0x0A, 0x5E, 0xB0,
+ 0x80, 0x11, 0x3C, 0xA0, 0xD1, 0xC3, 0xFA, 0xCE, 0x7B, 0xB4, 0x42, 0xA7,
+ 0x07, 0xCC, 0x72, 0x18, 0x2B, 0xB8, 0x41, 0xB1, 0x9D, 0x91, 0x32, 0xFD,
+ 0x7A, 0xFA, 0x29, 0xF3, 0x45, 0x75, 0x84, 0x6C, 0x5A, 0xF5, 0xC0, 0x87,
+ 0xB3, 0x06, 0xAE, 0xAC, 0x17, 0x0B, 0x20, 0x6E, 0x95, 0xC5, 0xAA, 0x22,
+ 0xD3, 0x8B, 0x11, 0xB1, 0x5C, 0x0E, 0xD0, 0xA3, 0x81, 0x4B, 0x7E, 0xF2,
+ 0x69, 0x5F, 0xBB, 0xF0, 0xA0, 0xFB, 0x08, 0x8B, 0xC8, 0x38, 0x00, 0x30,
+ 0x30, 0xFA, 0xB0, 0x49, 0xDE, 0x0C, 0x1F, 0x04, 0x43, 0xB2, 0xBD, 0x62,
+ 0x9B, 0xCD, 0x97, 0xBC, 0x97, 0x10, 0x40, 0x5B, 0xF0, 0xAC, 0xD7, 0x5C,
+ 0x0F, 0xCA, 0xCE, 0x69, 0x5C, 0x9B, 0x45, 0xF1, 0x8B, 0xE7, 0xF6, 0x46,
+ 0x4E, 0x74, 0x1E, 0x00, 0x4E, 0xDE, 0xD2, 0xA1, 0x82, 0xBC, 0xEE, 0x1F,
+ 0x00, 0x7C, 0x9F, 0xF1, 0x68, 0xF8, 0x3B, 0x02, 0xA0, 0xDA, 0x81, 0xFF,
+ 0x00, 0x36, 0x91, 0x40, 0x80, 0xEF, 0x99, 0x0F, 0x0A, 0x76, 0x74, 0x69,
+ 0x43, 0xD3, 0xC0, 0x07, 0x63, 0x6F, 0xC6, 0x29, 0xE5, 0xCD, 0x5C, 0x76,
+ 0x0B, 0x23, 0x07, 0x34, 0xB0, 0x7B, 0xA0, 0xBF, 0x0F, 0xFE, 0xF0, 0xCB,
+ 0xA0, 0x07, 0x35, 0xB0, 0xBD, 0xD6, 0xF2, 0xDD, 0xFA, 0xF4, 0x6B, 0xEE,
+ 0x31, 0x54, 0x3E, 0x9B, 0xC0, 0xFE, 0x11, 0x0F, 0x9F, 0x07, 0x54, 0x36,
+ 0xAC, 0x62, 0x2F, 0x8A, 0x0E, 0xD0, 0x77, 0x58, 0x4A, 0x60, 0xBC, 0xE0,
+ 0xD1, 0x0F, 0x25, 0xFC, 0x20, 0x90, 0x3B, 0x0B, 0x44, 0x7B, 0x05, 0x46,
+ 0x6C, 0xD5, 0xF7, 0x0C, 0x17, 0xC5, 0x09, 0x92, 0x35, 0x80, 0x22, 0x43,
+ 0x03, 0xEE, 0xA6, 0x7E, 0x0F, 0x08, 0x81, 0x19, 0x81, 0x75, 0x1E, 0xB5,
+ 0x30, 0x2D, 0x76, 0x74, 0x4A, 0x72, 0x7A, 0xF2, 0x10, 0x03, 0x9E, 0x11,
+ 0x3F, 0x44, 0x54, 0x7C, 0xF7, 0xF5, 0x01, 0x30, 0x40, 0x70, 0x10, 0x70,
+ 0x81, 0xFE, 0x17, 0x0C, 0xE9, 0xB6, 0x0F, 0xDB, 0xC7, 0x03, 0x3B, 0x50,
+ 0x03, 0x06, 0x08, 0x0F, 0x0D, 0x27, 0x00, 0xBC, 0xF6, 0x08, 0x05, 0x93,
+ 0x0E, 0x28, 0xC0, 0x73, 0x2F, 0x40, 0x82, 0x14, 0x52, 0x77, 0x3E, 0x50,
+ 0x7E, 0x11, 0xE8, 0x83, 0x3F, 0x48, 0x0B, 0xF7, 0x17, 0x0C, 0x32, 0x33,
+ 0x55, 0x1F, 0x10, 0x40, 0xC3, 0x80, 0x03, 0x3B, 0x60, 0x7E, 0xCD, 0xD0,
+ 0x5B, 0x29, 0x35, 0x03, 0x2C, 0x50, 0x59, 0x28, 0x58, 0x0A, 0x09, 0x10,
+ 0x7C, 0xDA, 0x57, 0x2E, 0x5A, 0x16, 0x00, 0x42, 0xC2, 0x03, 0x2E, 0x38,
+ 0x0F, 0xAA, 0x42, 0x66, 0x94, 0xA0, 0x78, 0x10, 0x70, 0x7C, 0x65, 0xA6,
+ 0x6C, 0xC8, 0xE7, 0x62, 0xC5, 0xC0, 0x03, 0x00, 0x02, 0x84, 0x6B, 0xE8,
+ 0x83, 0xEF, 0x25, 0x00, 0x71, 0x53, 0x62, 0x09, 0x50, 0x69, 0x47, 0xB7,
+ 0x02, 0x18, 0xD1, 0x85, 0x7F, 0xB5, 0x00, 0xC8, 0xC2, 0x09, 0x56, 0xD6,
+ 0x2F, 0x73, 0x83, 0x03, 0xE2, 0x07, 0x88, 0x81, 0x28, 0x68, 0xA2, 0x70,
+ 0x6B, 0x90, 0x40, 0x19, 0x38, 0xC0, 0x85, 0xF3, 0x80, 0x7B, 0x08, 0x41,
+ 0x09, 0x08, 0x07, 0x40, 0x31, 0x17, 0x10, 0xC8, 0x37, 0x03, 0xC3, 0xE7,
+ 0x87, 0x2B, 0xB8, 0x84, 0x6C, 0x88, 0x89, 0x7D, 0xFE, 0xD6, 0x03, 0xE8,
+ 0x44, 0x4B, 0x11, 0x47, 0x02, 0xEC, 0xC6, 0x03, 0x97, 0xB8, 0x74, 0x59,
+ 0x67, 0x58, 0x22, 0x00, 0x03, 0x07, 0xA3, 0x1A, 0x7A, 0x37, 0x85, 0xC5,
+ 0xA2, 0x74, 0xCC, 0x10, 0x23, 0x60, 0xF1, 0x1E, 0xAE, 0x02, 0x7A, 0x2A,
+ 0xF1, 0x03, 0x72, 0x42, 0x09, 0x2C, 0xA2, 0x8A, 0xA7, 0x81, 0x71, 0xD3,
+ 0x65, 0x89, 0x99, 0xE8, 0x8B, 0xD1, 0x76, 0x7D, 0xFA, 0x91, 0x23, 0x62,
+ 0x81, 0x02, 0x24, 0x36, 0x11, 0x95, 0x26, 0x0C, 0xC8, 0xC4, 0x51, 0xED,
+ 0x67, 0x58, 0x0B, 0x44, 0x02, 0x4E, 0x41, 0x28, 0x10, 0x60, 0x8C, 0x98,
+ 0x40, 0x3F, 0x6A, 0xE1, 0x0E, 0x3A, 0x80, 0x79, 0x90, 0x10, 0x58, 0x6B,
+ 0x11, 0x6F, 0xAB, 0xC2, 0x5C, 0x07, 0x70, 0x43, 0x03, 0xF3, 0x65, 0xC2,
+ 0xC0, 0x78, 0xBF, 0x68, 0x8E, 0x1B, 0xC6, 0x74, 0x67, 0x03, 0x89, 0x9F,
+ 0x70, 0x84, 0x29, 0x42, 0x86, 0x01, 0x41, 0x02, 0xF3, 0xC7, 0x44, 0xCD,
+ 0x20, 0x2B, 0xC2, 0x80, 0x27, 0x81, 0x44, 0x0C, 0xD3, 0x48, 0x8D, 0xEC,
+ 0x91, 0x81, 0xB6, 0x30, 0x4E, 0x64, 0x11, 0x09, 0x98, 0x61, 0x8D, 0x44,
+ 0xB1, 0x81, 0xC3, 0xD0, 0x65, 0x33, 0xF0, 0x3A, 0x9F, 0x90, 0x00, 0xBF,
+ 0xC7, 0x76, 0x96, 0x60, 0x81, 0x8A, 0x80, 0x03, 0x76, 0x78, 0x8E, 0x13,
+ 0x99, 0x54, 0x8B, 0x88, 0x85, 0xA7, 0xF0, 0x8C, 0x73, 0xB3, 0x79, 0xA7,
+ 0x91, 0x43, 0x99, 0xD1, 0x8A, 0xB2, 0x90, 0x68, 0xED, 0x02, 0x01, 0xC9,
+ 0xF6, 0x01, 0xF3, 0x07, 0x40, 0xFA, 0xA8, 0x90, 0x9B, 0xF0, 0x42, 0xCE,
+ 0x50, 0x8B, 0xC9, 0x82, 0x8F, 0x02, 0xD0, 0x77, 0x43, 0xB1, 0x89, 0xA2,
+ 0x80, 0x76, 0x28, 0x19, 0x00, 0x32, 0xE8, 0x90, 0xE7, 0x21, 0x7B, 0xA1,
+ 0xA1, 0x87, 0x02, 0xF0, 0x91, 0x14, 0x09, 0x94, 0x1F, 0xD4, 0x92, 0xFE,
+ 0x6A, 0x42, 0x79, 0x93, 0xB7, 0x62, 0x7A, 0xB2, 0x08, 0x6A, 0xD2, 0x90,
+ 0x14, 0x21, 0x24, 0x02, 0xB0, 0x02, 0xB3, 0x08, 0x0B, 0x33, 0x19, 0x11,
+ 0x03, 0x36, 0x3C, 0xC2, 0x30, 0x74, 0x03, 0x41, 0x38, 0x12, 0x89, 0x0B,
+ 0xA2, 0x67, 0x58, 0x93, 0x00, 0x11, 0xFD, 0x28, 0x0F, 0x2D, 0x79, 0x55,
+ 0x5E, 0x97, 0x00, 0x5E, 0x77, 0x52, 0xC4, 0x70, 0x78, 0x66, 0x29, 0x09,
+ 0x34, 0x07, 0x96, 0x41, 0xE9, 0x96, 0x9A, 0x03, 0x7B, 0xC5, 0x70, 0x91,
+ 0x04, 0x63, 0x3A, 0xEB, 0xA8, 0x8B, 0xD3, 0x05, 0x95, 0x00, 0x10, 0x03,
+ 0x62, 0x89, 0x93, 0x8E, 0xB0, 0x27, 0xA2, 0xF0, 0x8E, 0xA5, 0x80, 0x19,
+ 0xAB, 0xE0, 0x18, 0x6F, 0xD3, 0x58, 0xCD, 0x25, 0x00, 0x8D, 0x22, 0x14,
+ 0xE5, 0x31, 0x16, 0x76, 0x49, 0x11, 0x0F, 0x50, 0x70, 0xF3, 0x17, 0x83,
+ 0x36, 0x79, 0x8B, 0xC0, 0xF5, 0x96, 0x97, 0x29, 0x94, 0x72, 0xC1, 0x10,
+ 0x93, 0xA0, 0x1A, 0x29, 0xA2, 0x96, 0xA7, 0x31, 0x02, 0x4F, 0xD1, 0x8A,
+ 0x3B, 0xE0, 0x19, 0x07, 0xB0, 0x62, 0x61, 0xF8, 0x99, 0xD5, 0x95, 0x08,
+ 0x31, 0x39, 0x0B, 0x52, 0xD6, 0x2E, 0xB9, 0x58, 0x44, 0x3F, 0xA0, 0x03,
+ 0x35, 0xF0, 0x93, 0xCF, 0x50, 0x8F, 0x9E, 0xA9, 0x2C, 0x54, 0x08, 0x2C,
+ 0x3A, 0x74, 0x00, 0x22, 0xE0, 0x98, 0x8E, 0x30, 0x02, 0xFC, 0x88, 0x99,
+ 0xC3, 0xA9, 0x3C, 0x42, 0x98, 0x0E, 0x9B, 0x69, 0x28, 0xC8, 0x92, 0x90,
+ 0xEB, 0x74, 0x08, 0x50, 0x01, 0x41, 0xD7, 0xC7, 0x08, 0x8D, 0x18, 0x60,
+ 0x52, 0x88, 0x24, 0x10, 0x61, 0x80, 0x84, 0x97, 0x3E, 0x60, 0x48, 0x0C,
+ 0x39, 0x60, 0x77, 0x3D, 0xF8, 0x0E, 0xBD, 0x35, 0x27, 0x45, 0xF8, 0x02,
+ 0xEC, 0x71, 0x76, 0x6C, 0xF7, 0x00, 0x3D, 0x29, 0x1E, 0xC4, 0xA9, 0x9E,
+ 0x8A, 0x13, 0xFE, 0x03, 0x3D, 0xC0, 0x8C, 0x89, 0xB0, 0x91, 0x67, 0xA1,
+ 0x47, 0xB9, 0x38, 0x30, 0x07, 0x31, 0x8F, 0xAD, 0x80, 0x22, 0x70, 0x78,
+ 0x6E, 0x30, 0x30, 0x9E, 0xF5, 0x42, 0x99, 0x58, 0x16, 0x1E, 0xAE, 0x50,
+ 0x03, 0xDE, 0x46, 0x03, 0x59, 0xD7, 0x69, 0x01, 0xF0, 0x12, 0x38, 0xC0,
+ 0x03, 0xD4, 0x87, 0x77, 0xB8, 0x89, 0x5F, 0x0F, 0x50, 0x2C, 0x1D, 0xC0,
+ 0x73, 0x6A, 0xA7, 0x0F, 0x18, 0xD7, 0x93, 0xEC, 0xB3, 0x9E, 0x19, 0xCA,
+ 0x9E, 0x6A, 0x74, 0x14, 0xED, 0xF2, 0x51, 0x0B, 0xA9, 0x8E, 0x8A, 0x62,
+ 0x19, 0xC8, 0x47, 0xA2, 0x92, 0x88, 0x08, 0x2B, 0xB0, 0x82, 0xAF, 0xD0,
+ 0x8D, 0x67, 0x77, 0x8A, 0xC0, 0x37, 0x02, 0x50, 0x28, 0x99, 0x67, 0xB3,
+ 0x94, 0x02, 0x61, 0x84, 0x56, 0x48, 0x0C, 0x07, 0x30, 0x97, 0x85, 0x00,
+ 0x1C, 0x69, 0xC8, 0x0C, 0xE6, 0x41, 0x9D, 0xEB, 0x84, 0x94, 0xFF, 0x97,
+ 0x83, 0x2F, 0x26, 0x03, 0xB5, 0xA9, 0xA1, 0x47, 0xFA, 0x30, 0xEF, 0xF6,
+ 0x3E, 0x38, 0x09, 0xA1, 0xD8, 0x17, 0x7F, 0x0B, 0x80, 0x83, 0x36, 0x1A,
+ 0x0C, 0x75, 0xA7, 0x86, 0xB0, 0xD0, 0x8D, 0x24, 0xB1, 0x02, 0xE8, 0xB3,
+ 0x9C, 0x9E, 0x26, 0x77, 0x91, 0x49, 0x7C, 0x3B, 0x27, 0x70, 0x3B, 0xD9,
+ 0x2A, 0x04, 0x27, 0xA5, 0xAB, 0xB2, 0x14, 0xFF, 0x89, 0xA0, 0x57, 0x05,
+ 0x48, 0x45, 0x77, 0x81, 0x38, 0xF0, 0x03, 0x3C, 0x68, 0x0B, 0xE6, 0xF1,
+ 0x6B, 0x25, 0x46, 0x02, 0x0B, 0x08, 0x15, 0x1C, 0x27, 0x8A, 0x48, 0xAA,
+ 0xA7, 0xEA, 0x22, 0x15, 0x28, 0x56, 0x08, 0x7B, 0x72, 0x95, 0x14, 0x91,
+ 0x00, 0x4F, 0x38, 0x17, 0x1B, 0x97, 0x74, 0xB6, 0x50, 0x78, 0xC2, 0xB0,
+ 0xA0, 0xCF, 0xF2, 0x3E, 0xAF, 0x11, 0x82, 0x50, 0x0A, 0x01, 0xFD, 0x47,
+ 0x12, 0x36, 0x28, 0x79, 0x76, 0xFE, 0xAA, 0x47, 0x2F, 0xD0, 0xA2, 0x5D,
+ 0x77, 0x0A, 0x2F, 0x00, 0x89, 0x1F, 0x20, 0x77, 0x6D, 0x2A, 0x03, 0x06,
+ 0x18, 0x23, 0x33, 0x3A, 0x30, 0xF1, 0xA8, 0xA8, 0x0C, 0xBA, 0xA7, 0xA9,
+ 0xAA, 0x3C, 0xBD, 0x05, 0x4B, 0x35, 0x12, 0x8E, 0xD1, 0x25, 0x17, 0x0D,
+ 0xF8, 0x6E, 0x43, 0x11, 0x97, 0xD4, 0x90, 0x03, 0x3C, 0xC0, 0x6A, 0xB5,
+ 0x4A, 0x0D, 0xCF, 0x37, 0x86, 0x55, 0x45, 0x9F, 0x65, 0x91, 0x00, 0xB3,
+ 0x14, 0x7D, 0x3C, 0x0A, 0x0B, 0x05, 0x19, 0x9F, 0x81, 0x02, 0x7F, 0x9C,
+ 0x39, 0x37, 0x79, 0xA9, 0xAA, 0xCD, 0xCA, 0x61, 0x02, 0x30, 0x40, 0xFC,
+ 0x40, 0x28, 0xA9, 0x79, 0x09, 0x0F, 0xD0, 0x9F, 0xE9, 0xA0, 0xA0, 0x70,
+ 0xCA, 0x16, 0xBA, 0xAA, 0x08, 0x69, 0xD8, 0x8A, 0x36, 0xD0, 0x03, 0x82,
+ 0x76, 0x6D, 0x55, 0x46, 0x6E, 0x9D, 0x97, 0x8C, 0xE9, 0xD9, 0x0A, 0xEF,
+ 0xF3, 0xA3, 0x82, 0x2A, 0x09, 0x45, 0xE4, 0x23, 0x96, 0x80, 0x38, 0x46,
+ 0xEA, 0xAC, 0xF3, 0x7A, 0x2A, 0xD7, 0x37, 0x02, 0xCC, 0x22, 0x38, 0xEA,
+ 0xD6, 0x73, 0x72, 0xE8, 0x10, 0xDA, 0xB7, 0x02, 0x0D, 0x58, 0x6C, 0xF2,
+ 0x7A, 0x26, 0xEF, 0x99, 0x08, 0x39, 0x80, 0xAA, 0xB8, 0x10, 0x43, 0xC2,
+ 0xB0, 0xAE, 0x13, 0xC1, 0x02, 0x68, 0x3A, 0x09, 0xB2, 0x34, 0x5D, 0x2B,
+ 0x89, 0x9F, 0xF0, 0x59, 0x16, 0x87, 0x00, 0x73, 0xF6, 0x02, 0x09, 0x34,
+ 0x38, 0x92, 0x61, 0xA1, 0x0A, 0x02, 0x4B, 0xAF, 0x1F, 0x5B, 0x22, 0xDD,
+ 0xF8, 0x14, 0x39, 0xBA, 0x0F, 0xE3, 0x68, 0x30, 0xA9, 0xF4, 0xA3, 0xC1,
+ 0x7A, 0x74, 0x6E, 0xDA, 0x96, 0x79, 0x21, 0x65, 0x3C, 0x40, 0x03, 0x31,
+ 0x3B, 0x7D, 0x2D, 0xF8, 0x0C, 0xC1, 0x68, 0x8A, 0xF0, 0x91, 0x24, 0x3E,
+ 0x42, 0xAD, 0x8F, 0x50, 0x95, 0x17, 0xE1, 0x0A, 0xFE, 0xEF, 0x75, 0x8F,
+ 0x56, 0x51, 0x24, 0x63, 0x41, 0x62, 0x97, 0x46, 0xB2, 0x01, 0x40, 0x38,
+ 0x84, 0x09, 0xB2, 0x4B, 0xEB, 0x67, 0xC3, 0xD0, 0x97, 0x83, 0x00, 0x99,
+ 0x02, 0x34, 0x03, 0x8D, 0x00, 0xA2, 0xC9, 0x16, 0x9A, 0x99, 0x71, 0xB0,
+ 0xE6, 0xF3, 0x5E, 0x1B, 0xCB, 0x1F, 0xFE, 0x01, 0x79, 0x0B, 0x30, 0x03,
+ 0x3B, 0x3B, 0x08, 0x25, 0xA9, 0x0A, 0x8E, 0x62, 0x9C, 0x86, 0xB5, 0x00,
+ 0x81, 0x39, 0x09, 0x7F, 0x49, 0x5D, 0x44, 0xF7, 0x00, 0x2F, 0x8A, 0x10,
+ 0x90, 0x88, 0x16, 0xB3, 0xC6, 0xB4, 0x75, 0x5B, 0x22, 0x6C, 0x94, 0xAF,
+ 0x8F, 0x00, 0xB1, 0xA6, 0x73, 0x0F, 0xDF, 0xF1, 0x3B, 0x7A, 0x58, 0x77,
+ 0x1E, 0xAB, 0x35, 0x71, 0x72, 0xB4, 0x58, 0x81, 0xAF, 0x70, 0xB3, 0x75,
+ 0x62, 0x8B, 0x2C, 0xF7, 0x09, 0x00, 0x13, 0xB8, 0x15, 0x6A, 0x1B, 0x4B,
+ 0x6F, 0xFB, 0x14, 0x16, 0xC1, 0xB5, 0x7A, 0xDB, 0x8E, 0x2F, 0xA0, 0x4E,
+ 0xA3, 0xC1, 0x9A, 0x76, 0xCB, 0xB9, 0xD6, 0xF1, 0x03, 0x5A, 0x7A, 0x6E,
+ 0x26, 0x7B, 0x36, 0xFD, 0x43, 0x38, 0x38, 0xF9, 0x01, 0x0D, 0x53, 0x8E,
+ 0x4D, 0xC4, 0x95, 0xC7, 0x4A, 0x10, 0xBF, 0x0A, 0xA2, 0xC5, 0x20, 0x02,
+ 0x81, 0x1A, 0x09, 0x35, 0x32, 0x90, 0x3F, 0x7B, 0x6D, 0xDC, 0x51, 0x10,
+ 0xFE, 0x91, 0x87, 0xDB, 0x61, 0x37, 0x83, 0xAA, 0x47, 0x7C, 0xE8, 0x4B,
+ 0xFF, 0xD1, 0xB9, 0xC3, 0x7B, 0x1D, 0x7E, 0xF5, 0x86, 0x8E, 0x00, 0x03,
+ 0x03, 0xB8, 0x00, 0x30, 0x90, 0x28, 0xC8, 0x32, 0x4F, 0x3D, 0x9B, 0xBA,
+ 0x66, 0xE4, 0x19, 0xA4, 0x6A, 0x09, 0xC1, 0xB2, 0xA5, 0x92, 0x20, 0xBA,
+ 0x06, 0xD9, 0x58, 0x9E, 0x1A, 0x7C, 0x7A, 0xB8, 0x4A, 0xB2, 0x10, 0x03,
+ 0xDE, 0x26, 0x27, 0x14, 0x2A, 0x10, 0xA2, 0x01, 0x3F, 0xF7, 0x73, 0xFE,
+ 0xB5, 0x6F, 0x38, 0x74, 0x94, 0xD1, 0xB2, 0xC4, 0xEB, 0xBE, 0x2A, 0xC1,
+ 0x95, 0x2A, 0xD2, 0x62, 0x92, 0x9A, 0x94, 0x00, 0x28, 0x0A, 0xF3, 0x43,
+ 0xBB, 0x89, 0x68, 0x3E, 0x8A, 0x50, 0x16, 0x68, 0xD1, 0x81, 0x0E, 0xC9,
+ 0x7B, 0xC4, 0xD0, 0x01, 0x5D, 0x05, 0x99, 0xC5, 0xE0, 0x22, 0xB6, 0x30,
+ 0x9B, 0xAD, 0x66, 0x76, 0x61, 0x2B, 0x10, 0xE9, 0x3B, 0x43, 0xB0, 0xD1,
+ 0x1E, 0x37, 0xC3, 0xBE, 0xEF, 0x4B, 0xC1, 0x8B, 0xC1, 0x09, 0xDA, 0x17,
+ 0x66, 0x3E, 0xE0, 0x6A, 0xC5, 0xB0, 0x79, 0x35, 0xC2, 0xAC, 0x29, 0xA4,
+ 0x08, 0xBF, 0x7A, 0x0A, 0xF9, 0x41, 0x3C, 0xBA, 0x26, 0x7C, 0x43, 0x4A,
+ 0x1A, 0xA7, 0xD8, 0x91, 0x99, 0x21, 0xB3, 0x1F, 0x2C, 0x0B, 0x2B, 0x37,
+ 0x84, 0x23, 0x40, 0xBD, 0xFB, 0xC0, 0xB6, 0x6D, 0xA4, 0x10, 0x2B, 0x6C,
+ 0x76, 0x2F, 0xA0, 0xA9, 0x5A, 0xD1, 0xBE, 0x15, 0xEC, 0xC3, 0xF0, 0x40,
+ 0x8A, 0x6C, 0x13, 0xB3, 0x1B, 0x85, 0x73, 0x73, 0x44, 0x08, 0xFD, 0x20,
+ 0x56, 0xFD, 0xD4, 0x84, 0x0B, 0x6B, 0x0A, 0x30, 0x50, 0x2C, 0x9D, 0x78,
+ 0x0A, 0xD9, 0x2B, 0x0C, 0x3F, 0x30, 0x7E, 0xC2, 0xD5, 0x03, 0xB5, 0x86,
+ 0x10, 0x3D, 0xF7, 0x09, 0x7E, 0xD2, 0x1E, 0xDD, 0xB1, 0x10, 0x25, 0x58,
+ 0x2F, 0x2A, 0x99, 0xA7, 0x3F, 0x4C, 0xC6, 0xCC, 0xB0, 0x46, 0x3C, 0x98,
+ 0x46, 0xFA, 0xEB, 0x86, 0x02, 0x40, 0x0A, 0xE6, 0x9B, 0x03, 0x82, 0x6B,
+ 0x3E, 0x7B, 0x39, 0x17, 0x1D, 0xF0, 0x70, 0xEF, 0x68, 0xAE, 0x6F, 0x28,
+ 0xC2, 0x91, 0x50, 0xA7, 0xE0, 0xA1, 0xB4, 0x42, 0xB1, 0x03, 0x37, 0xD0,
+ 0x2E, 0xC5, 0xA5, 0x96, 0xAF, 0xBB, 0x08, 0x60, 0x71, 0xA1, 0x34, 0xB0,
+ 0x46, 0xE3, 0xBA, 0x48, 0x65, 0xCC, 0xC8, 0x0F, 0x72, 0x9B, 0x85, 0xD2,
+ 0x99, 0x74, 0xFE, 0xCB, 0x57, 0x89, 0xFA, 0x12, 0x1D, 0xA0, 0xC3, 0x0E,
+ 0x59, 0x23, 0x44, 0x78, 0x0A, 0x2A, 0xDB, 0xB1, 0x6C, 0x61, 0x03, 0x2C,
+ 0x47, 0x93, 0x33, 0xEA, 0xC0, 0xC4, 0x80, 0x03, 0x55, 0x0A, 0x00, 0x3A,
+ 0xF0, 0xB9, 0xAA, 0x50, 0x7F, 0x8D, 0xCC, 0xCA, 0xD6, 0xE1, 0x19, 0xAC,
+ 0x41, 0x38, 0xDF, 0xBB, 0x61, 0x94, 0x3C, 0x17, 0x87, 0xE7, 0x10, 0x62,
+ 0x81, 0x1E, 0xA1, 0x71, 0x84, 0x7F, 0x68, 0x22, 0x8E, 0x1B, 0x83, 0xBF,
+ 0x79, 0xBA, 0xC4, 0xB0, 0xA0, 0x63, 0xDC, 0xCA, 0xC5, 0x6C, 0xC1, 0xF5,
+ 0x81, 0x2C, 0x20, 0xB6, 0x61, 0x62, 0x39, 0x0C, 0xDC, 0x27, 0xB3, 0x05,
+ 0x5A, 0x0C, 0x28, 0xF0, 0xAB, 0x87, 0x80, 0xB1, 0xE5, 0x8B, 0x2C, 0x9B,
+ 0x5B, 0x14, 0x9F, 0x9C, 0x4E, 0x98, 0xC0, 0xB6, 0x6D, 0x63, 0xCC, 0xDF,
+ 0x5C, 0x26, 0x8B, 0x50, 0xB0, 0xC4, 0x5C, 0x4A, 0xB3, 0xF9, 0x67, 0x60,
+ 0x69, 0x03, 0x03, 0xCA, 0x6A, 0xED, 0x82, 0xA3, 0x92, 0x15, 0x2C, 0x9A,
+ 0x8C, 0x91, 0xEC, 0xE1, 0xC2, 0x1B, 0x71, 0x75, 0x7D, 0x2A, 0xBB, 0x44,
+ 0x37, 0x5D, 0xA6, 0x0C, 0xCE, 0xFB, 0x6C, 0x1D, 0xAD, 0x03, 0x6A, 0x40,
+ 0x68, 0x03, 0xDF, 0x16, 0xA2, 0x9C, 0x79, 0x00, 0xA6, 0xB9, 0x28, 0x4E,
+ 0x09, 0xC7, 0x8A, 0x38, 0x81, 0x1D, 0xF0, 0x8E, 0xED, 0x28, 0xBC, 0xFC,
+ 0x0C, 0xD1, 0xD5, 0xC1, 0x7E, 0xB2, 0xE9, 0x8B, 0x3B, 0x40, 0x2F, 0x24,
+ 0x7B, 0x10, 0x79, 0x23, 0x7F, 0xCB, 0x1B, 0x72, 0x07, 0x51, 0xBB, 0x8B,
+ 0xC1, 0x98, 0x31, 0x48, 0x96, 0x0D, 0x93, 0xD0, 0x11, 0x6D, 0xD2, 0x20,
+ 0x1B, 0x23, 0xFF, 0x1B, 0x09, 0x07, 0xA1, 0x3E, 0x66, 0xC7, 0x02, 0x5C,
+ 0x87, 0x59, 0x1A, 0x55, 0x1D, 0x72, 0xA4, 0x9F, 0x94, 0x40, 0x3F, 0xFF,
+ 0x7C, 0xD2, 0x39, 0x4D, 0xC1, 0xFE, 0xA7, 0x54, 0xD3, 0x7A, 0x6B, 0x11,
+ 0xC1, 0xD3, 0x94, 0xAB, 0x82, 0xA9, 0x88, 0xE4, 0xB3, 0xD5, 0x11, 0xD2,
+ 0x4C, 0xBC, 0x0F, 0xEC, 0xA1, 0xCC, 0x3A, 0xCD, 0xD4, 0x9C, 0x9B, 0xB0,
+ 0x36, 0x7C, 0x6E, 0x88, 0x90, 0x2F, 0x41, 0x7D, 0xA3, 0x00, 0x34, 0x1B,
+ 0xAB, 0x19, 0x20, 0xEF, 0x13, 0x9E, 0xFD, 0x5A, 0xD4, 0x4D, 0xED, 0xD5,
+ 0x76, 0x5B, 0x90, 0x77, 0x72, 0x3F, 0x7E, 0xC3, 0x15, 0x4F, 0x81, 0x03,
+ 0xCF, 0x1C, 0x97, 0xC2, 0x19, 0x20, 0x2B, 0x94, 0xCB, 0x5C, 0x2D, 0x00,
+ 0xFA, 0xFB, 0xD5, 0x71, 0x8D, 0xA4, 0xEF, 0xD5, 0xD6, 0xB1, 0x54, 0x52,
+ 0x05, 0xAB, 0xCF, 0x00, 0x20, 0x95, 0xC4, 0x50, 0xD2, 0xF4, 0x35, 0x2B,
+ 0xD5, 0xCC, 0x5C, 0x02, 0x29, 0xD7, 0x83, 0xFD, 0xB1, 0x4F, 0xAD, 0x36,
+ 0x41, 0xD2, 0xAD, 0xB6, 0x97, 0xC8, 0x8A, 0x70, 0x03, 0x79, 0x6D, 0x1D,
+ 0x1D, 0x15, 0x83, 0x0E, 0x39, 0xC1, 0x84, 0x4D, 0xD9, 0xAA, 0x0A, 0xD9,
+ 0x5D, 0x66, 0x11, 0x7D, 0x4C, 0x36, 0x4B, 0x6A, 0x09, 0x5E, 0x81, 0xCD,
+ 0x95, 0x0D, 0xDA, 0x19, 0xCA, 0x95, 0x4F, 0x3B, 0x1F, 0xDE, 0xAC, 0x38,
+ 0xA4, 0x09, 0xAD, 0xF4, 0x89, 0x08, 0xF3, 0x1C, 0xDA, 0xAD, 0x0D, 0x94,
+ 0xA7, 0xA4, 0x8A, 0xA3, 0xD1, 0xC3, 0xD0, 0x92, 0x1D, 0x34, 0x69, 0x2B,
+ 0xE6, 0xEB, 0x93, 0xAE, 0xAD, 0xDB, 0xA2, 0x9D, 0x08, 0xC6, 0xE8, 0x2A,
+ 0x12, 0xCB, 0x9E, 0xCC, 0x0C, 0x79, 0xC3, 0x07, 0x11, 0xB2, 0xBC, 0xDB,
+ 0xC7, 0x8D, 0x99, 0x31, 0x32, 0x74, 0x35, 0x62, 0x3E, 0x45, 0x5C, 0x0C,
+ 0x4F, 0x89, 0xDC, 0xD1, 0x3D, 0x9C, 0x31, 0x02, 0xCF, 0x50, 0x6B, 0x99,
+ 0x71, 0xBC, 0x03, 0xE2, 0x37, 0xAB, 0xD2, 0xCD, 0xDD, 0x6F, 0x19, 0x23,
+ 0xD1, 0xE9, 0x08, 0x98, 0xC1, 0xB8, 0xDD, 0x4D, 0xEE, 0xDE, 0xE5, 0xED,
+ 0x0A, 0x5C, 0x69, 0x58, 0xF6, 0x81, 0xC4, 0xE4, 0x6C, 0xDE, 0xED, 0x4D,
+ 0xD8, 0x35, 0x50, 0x9A, 0x3B, 0xC7, 0x9F, 0x8A, 0x30, 0xDB, 0xEE, 0x6D,
+ 0xDF, 0x84, 0x2D, 0xC7, 0xA4, 0x7C, 0xDF, 0xFB, 0xDD, 0xDD, 0x36, 0x50,
+ 0x76, 0x4B, 0xCD, 0xDF, 0x01, 0xEE, 0xDA, 0x16, 0x0D, 0x91, 0x7D, 0x2D,
+ 0xE0, 0x07, 0x9E, 0xD3, 0x3A, 0xB0, 0x6A, 0xEC, 0x8D, 0xE0, 0x0D, 0xEE,
+ 0xE0, 0x0F, 0x0E, 0xE1, 0x11, 0x2E, 0xE1, 0x13, 0x4E, 0xE1, 0x15, 0x6E,
+ 0xE1, 0x17, 0x8E, 0xE1, 0x19, 0xAE, 0xE1, 0x1B, 0xCE, 0xE1, 0x1D, 0xEE,
+ 0xE1, 0x1F, 0x0E, 0xE2, 0x21, 0x2E, 0xE2, 0x23, 0x4E, 0xE2, 0x25, 0x6E,
+ 0xE2, 0x27, 0x8E, 0xE2, 0x29, 0xAE, 0xE2, 0x2B, 0xCE, 0xE2, 0x2D, 0xEE,
+ 0xE2, 0x2F, 0x0E, 0xE3, 0x31, 0x2E, 0xE3, 0x33, 0x4E, 0xE3, 0x35, 0x6E,
+ 0xE3, 0x37, 0x8E, 0xE3, 0x39, 0xAE, 0xE3, 0x3B, 0xCE, 0xE3, 0x3D, 0xEE,
+ 0xE3, 0x3F, 0x0E, 0xE4, 0x41, 0x2E, 0xE4, 0x43, 0x4E, 0xE4, 0x45, 0x6E,
+ 0xE4, 0x47, 0x8E, 0xE4, 0x49, 0xAE, 0xE4, 0x4B, 0xCE, 0xE4, 0x4D, 0xEE,
+ 0xE4, 0x4F, 0x0E, 0xE5, 0x51, 0x2E, 0xE5, 0x53, 0x4E, 0xE5, 0x55, 0x6E,
+ 0xE5, 0x57, 0x8E, 0xE5, 0x59, 0xAE, 0xE5, 0x5B, 0xCE, 0xE5, 0x5D, 0xEE,
+ 0xE5, 0x5F, 0x0E, 0xE6, 0x61, 0x2E, 0xE6, 0x63, 0x4E, 0xE6, 0x65, 0x6E,
+ 0xE6, 0x67, 0x8E, 0xE6, 0x69, 0xAE, 0xE6, 0x6B, 0xCE, 0xE6, 0x6D, 0xEE,
+ 0xE6, 0x6F, 0x0E, 0xE7, 0x71, 0x2E, 0xE7, 0x73, 0x4E, 0xE7, 0x75, 0x6E,
+ 0xE7, 0x77, 0x8E, 0xE7, 0x79, 0xAE, 0xE7, 0x7B, 0xCE, 0xE7, 0x7D, 0xEE,
+ 0xE7, 0x7F, 0x0E, 0xE8, 0x26, 0x13, 0x08, 0x00, 0x3B,
+ };
+
+#define NetscapeImageExtent 9788
+static const unsigned char
+ NetscapeImage[]=
+ {
+ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0xd8, 0x00, 0x90, 0x00, 0xf7, 0x00,
+ 0x00, 0xcc, 0xff, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0x99, 0x00, 0xcc, 0x66,
+ 0x00, 0xcc, 0x33, 0x00, 0xcc, 0x00, 0x00, 0x99, 0x00, 0x00, 0x99, 0x33,
+ 0x00, 0x99, 0x66, 0x00, 0x99, 0x99, 0x00, 0x99, 0xcc, 0x00, 0x99, 0xff,
+ 0x00, 0x00, 0xff, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x99, 0x00, 0x00, 0x66,
+ 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xff, 0x33, 0xcc, 0xcc,
+ 0x33, 0xcc, 0x99, 0x33, 0xcc, 0x66, 0x33, 0xcc, 0x33, 0x33, 0xcc, 0x00,
+ 0x33, 0x99, 0x00, 0x33, 0x99, 0x33, 0x33, 0x99, 0x66, 0x33, 0x99, 0x99,
+ 0x33, 0x99, 0xcc, 0x33, 0x99, 0xff, 0x33, 0x00, 0xff, 0x33, 0x00, 0xcc,
+ 0x33, 0x00, 0x99, 0x33, 0x00, 0x66, 0x33, 0x00, 0x33, 0x33, 0x00, 0x00,
+ 0x33, 0xcc, 0xff, 0x66, 0xcc, 0xcc, 0x66, 0xcc, 0x99, 0x66, 0xcc, 0x66,
+ 0x66, 0xcc, 0x33, 0x66, 0xcc, 0x00, 0x66, 0x99, 0x00, 0x66, 0x99, 0x33,
+ 0x66, 0x99, 0x66, 0x66, 0x99, 0x99, 0x66, 0x99, 0xcc, 0x66, 0x99, 0xff,
+ 0x66, 0x00, 0xff, 0x66, 0x00, 0xcc, 0x66, 0x00, 0x99, 0x66, 0x00, 0x66,
+ 0x66, 0x00, 0x33, 0x66, 0x00, 0x00, 0x66, 0xcc, 0xff, 0x99, 0xcc, 0xcc,
+ 0x99, 0xcc, 0x99, 0x99, 0xcc, 0x66, 0x99, 0xcc, 0x33, 0x99, 0xcc, 0x00,
+ 0x99, 0x99, 0x00, 0x99, 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0x99,
+ 0x99, 0x99, 0xcc, 0x99, 0x99, 0xff, 0x99, 0x00, 0xff, 0x99, 0x00, 0xcc,
+ 0x99, 0x00, 0x99, 0x99, 0x00, 0x66, 0x99, 0x00, 0x33, 0x99, 0x00, 0x00,
+ 0x99, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x99, 0xcc, 0xcc, 0x66,
+ 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 0x00, 0xcc, 0x99, 0x00, 0xcc, 0x99, 0x33,
+ 0xcc, 0x99, 0x66, 0xcc, 0x99, 0x99, 0xcc, 0x99, 0xcc, 0xcc, 0x99, 0xff,
+ 0xcc, 0x00, 0xff, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x99, 0xcc, 0x00, 0x66,
+ 0xcc, 0x00, 0x33, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xff, 0xff, 0xcc, 0xcc,
+ 0xff, 0xcc, 0x99, 0xff, 0xcc, 0x66, 0xff, 0xcc, 0x33, 0xff, 0xcc, 0x00,
+ 0xff, 0x99, 0x00, 0xff, 0x99, 0x33, 0xff, 0x99, 0x66, 0xff, 0x99, 0x99,
+ 0xff, 0x99, 0xcc, 0xff, 0x99, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xcc,
+ 0xff, 0x00, 0x99, 0xff, 0x00, 0x66, 0xff, 0x00, 0x33, 0xff, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xff, 0xff, 0x99, 0xff, 0xff, 0x66,
+ 0xff, 0xff, 0x33, 0xff, 0xff, 0x00, 0xff, 0x66, 0x00, 0xff, 0x66, 0x33,
+ 0xff, 0x66, 0x66, 0xff, 0x66, 0x99, 0xff, 0x66, 0xcc, 0xff, 0x66, 0xff,
+ 0xff, 0x33, 0xff, 0xff, 0x33, 0xcc, 0xff, 0x33, 0x99, 0xff, 0x33, 0x66,
+ 0xff, 0x33, 0x33, 0xff, 0x33, 0x00, 0xff, 0xff, 0xff, 0xcc, 0xff, 0xcc,
+ 0xcc, 0xff, 0x99, 0xcc, 0xff, 0x66, 0xcc, 0xff, 0x33, 0xcc, 0xff, 0x00,
+ 0xcc, 0x66, 0x00, 0xcc, 0x66, 0x33, 0xcc, 0x66, 0x66, 0xcc, 0x66, 0x99,
+ 0xcc, 0x66, 0xcc, 0xcc, 0x66, 0xff, 0xcc, 0x33, 0xff, 0xcc, 0x33, 0xcc,
+ 0xcc, 0x33, 0x99, 0xcc, 0x33, 0x66, 0xcc, 0x33, 0x33, 0xcc, 0x33, 0x00,
+ 0xcc, 0xff, 0xff, 0x99, 0xff, 0xcc, 0x99, 0xff, 0x99, 0x99, 0xff, 0x66,
+ 0x99, 0xff, 0x33, 0x99, 0xff, 0x00, 0x99, 0x66, 0x00, 0x99, 0x66, 0x33,
+ 0x99, 0x66, 0x66, 0x99, 0x66, 0x99, 0x99, 0x66, 0xcc, 0x99, 0x66, 0xff,
+ 0x99, 0x33, 0xff, 0x99, 0x33, 0xcc, 0x99, 0x33, 0x99, 0x99, 0x33, 0x66,
+ 0x99, 0x33, 0x33, 0x99, 0x33, 0x00, 0x99, 0xff, 0xff, 0x66, 0xff, 0xcc,
+ 0x66, 0xff, 0x99, 0x66, 0xff, 0x66, 0x66, 0xff, 0x33, 0x66, 0xff, 0x00,
+ 0x66, 0x66, 0x00, 0x66, 0x66, 0x33, 0x66, 0x66, 0x66, 0x66, 0x66, 0x99,
+ 0x66, 0x66, 0xcc, 0x66, 0x66, 0xff, 0x66, 0x33, 0xff, 0x66, 0x33, 0xcc,
+ 0x66, 0x33, 0x99, 0x66, 0x33, 0x66, 0x66, 0x33, 0x33, 0x66, 0x33, 0x00,
+ 0x66, 0xff, 0xff, 0x33, 0xff, 0xcc, 0x33, 0xff, 0x99, 0x33, 0xff, 0x66,
+ 0x33, 0xff, 0x33, 0x33, 0xff, 0x00, 0x33, 0x66, 0x00, 0x33, 0x66, 0x33,
+ 0x33, 0x66, 0x66, 0x33, 0x66, 0x99, 0x33, 0x66, 0xcc, 0x33, 0x66, 0xff,
+ 0x33, 0x33, 0xff, 0x33, 0x33, 0xcc, 0x33, 0x33, 0x99, 0x33, 0x33, 0x66,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x33, 0xff, 0xff, 0x00, 0xff, 0xcc,
+ 0x00, 0xff, 0x99, 0x00, 0xff, 0x66, 0x00, 0xff, 0x33, 0x00, 0xff, 0x00,
+ 0x00, 0x66, 0x00, 0x00, 0x66, 0x33, 0x00, 0x66, 0x66, 0x00, 0x66, 0x99,
+ 0x00, 0x66, 0xcc, 0x00, 0x66, 0xff, 0x00, 0x33, 0xff, 0x00, 0x33, 0xcc,
+ 0x00, 0x33, 0x99, 0x00, 0x33, 0x66, 0x00, 0x33, 0x33, 0x00, 0x33, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x21, 0xfe, 0x1b, 0x20, 0x20, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74,
+ 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x47, 0x49, 0x46, 0x20,
+ 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x00, 0x2c, 0x00, 0x00, 0x00,
+ 0x00, 0xd8, 0x00, 0x90, 0x00, 0x40, 0x08, 0xfe, 0x00, 0x01, 0x08, 0x1c,
+ 0x48, 0x50, 0x60, 0x80, 0x83, 0x08, 0x13, 0x1e, 0x14, 0xc0, 0xb0, 0xa1,
+ 0x43, 0x86, 0x03, 0x22, 0x4a, 0x9c, 0x18, 0x91, 0x80, 0xc5, 0x8b, 0x18,
+ 0x2d, 0x16, 0xd8, 0xc8, 0xb1, 0xe3, 0x46, 0x03, 0x20, 0x43, 0x8a, 0x04,
+ 0x79, 0xa0, 0xa4, 0xc9, 0x93, 0x25, 0x11, 0xa8, 0x5c, 0xc9, 0x52, 0x65,
+ 0x82, 0x97, 0x30, 0x63, 0xbe, 0x54, 0x40, 0xb3, 0xa6, 0x4d, 0x9a, 0x0b,
+ 0x72, 0xea, 0xdc, 0x99, 0x93, 0x81, 0xcf, 0x9f, 0x40, 0x7d, 0x36, 0x18,
+ 0x4a, 0xb4, 0xe8, 0x50, 0x07, 0x48, 0x93, 0x2a, 0x45, 0xfa, 0xa0, 0xa9,
+ 0xd3, 0xa7, 0x4d, 0x21, 0x48, 0x9d, 0x4a, 0x55, 0x6a, 0x84, 0xab, 0x58,
+ 0xb3, 0x5e, 0x2d, 0xc8, 0x15, 0x80, 0xc2, 0xaf, 0x01, 0x1e, 0x8a, 0x15,
+ 0x40, 0xb1, 0xec, 0x80, 0x8c, 0x68, 0x09, 0x78, 0x5c, 0x5b, 0x60, 0xa4,
+ 0x5b, 0x03, 0x28, 0xe3, 0x1e, 0x68, 0x49, 0x17, 0x81, 0xcc, 0xbb, 0x09,
+ 0x6e, 0xea, 0x55, 0xc0, 0xb3, 0xef, 0x82, 0xa0, 0x80, 0x19, 0x18, 0x1d,
+ 0xdc, 0x60, 0xa9, 0x61, 0x07, 0x50, 0x13, 0x3f, 0xa8, 0xca, 0x18, 0x82,
+ 0xd6, 0xc7, 0x11, 0x24, 0x48, 0x9e, 0x4c, 0x59, 0xf2, 0x84, 0xcb, 0x98,
+ 0x33, 0x5f, 0xa6, 0xc0, 0xb9, 0xb3, 0x67, 0xce, 0x15, 0x42, 0x8b, 0x1e,
+ 0x1d, 0xda, 0x82, 0xe9, 0xd3, 0xa8, 0x4d, 0x5f, 0x58, 0xcd, 0xba, 0xf5,
+ 0x6a, 0x0c, 0xb0, 0x63, 0xcb, 0x86, 0x9d, 0xa1, 0xb6, 0xed, 0xdb, 0xb5,
+ 0x35, 0xe8, 0xde, 0xcd, 0x5b, 0xf7, 0x86, 0xdf, 0xc0, 0x83, 0xff, 0xe6,
+ 0x40, 0xbc, 0xb8, 0x71, 0xe2, 0x1d, 0x92, 0x2b, 0x5f, 0x9e, 0xdc, 0x83,
+ 0xf3, 0xe7, 0xd0, 0x9d, 0x7f, 0x98, 0x4e, 0xbd, 0xfa, 0x74, 0x10, 0xd8,
+ 0xb3, 0x6b, 0xc7, 0x1e, 0xa2, 0xbb, 0xf7, 0xef, 0xdd, 0x45, 0xfe, 0x88,
+ 0x1f, 0x4f, 0x5e, 0xfc, 0x88, 0xf3, 0xe8, 0xd3, 0x9f, 0x27, 0xc1, 0xbe,
+ 0xbd, 0x7b, 0xf6, 0x25, 0xe2, 0xcb, 0x9f, 0x1f, 0xdf, 0x84, 0xfd, 0xfb,
+ 0xf8, 0xed, 0x9f, 0xd8, 0xcf, 0xbf, 0xff, 0x7e, 0x14, 0x00, 0x06, 0x28,
+ 0x20, 0x80, 0x29, 0x14, 0x68, 0xe0, 0x81, 0x05, 0xaa, 0xa0, 0xe0, 0x82,
+ 0x0c, 0x2a, 0xb8, 0xc2, 0x83, 0x10, 0x46, 0xf8, 0x20, 0x0b, 0x14, 0x56,
+ 0x68, 0x21, 0x85, 0x2d, 0x64, 0xa8, 0xe1, 0x86, 0x19, 0xba, 0xe0, 0xe1,
+ 0x87, 0x20, 0x7a, 0xf8, 0xc2, 0x88, 0x24, 0x96, 0x38, 0x22, 0x0c, 0x28,
+ 0xa6, 0xa8, 0x22, 0x8a, 0x31, 0xb4, 0xe8, 0xe2, 0x8b, 0x2d, 0xca, 0x20,
+ 0xe3, 0x8c, 0x34, 0xca, 0x38, 0xc3, 0x8d, 0x38, 0xe6, 0x78, 0x23, 0x0d,
+ 0x3c, 0xf6, 0xe8, 0x23, 0x8f, 0x35, 0x04, 0x29, 0xe4, 0x90, 0x41, 0xbe,
+ 0x67, 0x24, 0x09, 0xf4, 0x25, 0x59, 0x42, 0x7e, 0x4c, 0x9a, 0xe0, 0xdf,
+ 0x93, 0x27, 0x0c, 0x28, 0x25, 0x0a, 0x08, 0x56, 0x99, 0x42, 0x83, 0x58,
+ 0xaa, 0x20, 0xe1, 0x96, 0x2b, 0x5c, 0xe8, 0x25, 0x0b, 0x1c, 0x86, 0xd9,
+ 0x42, 0x88, 0x64, 0xba, 0x60, 0xe2, 0x99, 0x2f, 0xac, 0xa8, 0x26, 0x0c,
+ 0x30, 0xb6, 0x19, 0x43, 0x8d, 0x70, 0xca, 0xa0, 0xe3, 0x9c, 0x33, 0xfc,
+ 0x68, 0x27, 0x0d, 0x44, 0xe6, 0x59, 0x83, 0x0d, 0x7c, 0xf6, 0xe9, 0x27,
+ 0x9f, 0x37, 0x04, 0x2a, 0xe8, 0xa0, 0x81, 0xe2, 0x60, 0xe8, 0xa1, 0x88,
+ 0x1a, 0x9a, 0xc3, 0xa2, 0x8c, 0x36, 0xba, 0xa8, 0x0e, 0x90, 0x46, 0x2a,
+ 0x29, 0xa4, 0x3b, 0x54, 0x6a, 0xe9, 0xa5, 0x95, 0xf2, 0xa0, 0xe9, 0xa6,
+ 0x9c, 0x6a, 0xda, 0xc3, 0xa7, 0xa0, 0x86, 0xfa, 0xa9, 0x0f, 0xa4, 0x96,
+ 0x6a, 0x2a, 0xa9, 0x3f, 0xa4, 0xaa, 0xea, 0xaa, 0xa9, 0x02, 0xe1, 0xea,
+ 0xab, 0xfe, 0xb0, 0xba, 0x1a, 0xc4, 0xac, 0xb4, 0xd6, 0x3a, 0xab, 0x10,
+ 0xb8, 0xe6, 0xaa, 0x2b, 0xae, 0x43, 0xf4, 0xea, 0xeb, 0xaf, 0xbd, 0x12,
+ 0x21, 0xec, 0xb0, 0xc4, 0x0a, 0x5b, 0xc4, 0xb1, 0xc8, 0x26, 0x7b, 0xac,
+ 0x11, 0xcc, 0x36, 0xeb, 0x2c, 0xb3, 0x47, 0x44, 0x2b, 0xed, 0xb4, 0xd1,
+ 0x22, 0x61, 0xed, 0xb5, 0xd8, 0x5a, 0x9b, 0xc4, 0xb6, 0xdc, 0x76, 0xbb,
+ 0xad, 0x12, 0xe0, 0x86, 0x2b, 0x2e, 0xb8, 0x4b, 0x94, 0x6b, 0xee, 0xb9,
+ 0xe5, 0x32, 0xa1, 0xee, 0xba, 0xec, 0xaa, 0xdb, 0xc4, 0xbb, 0xf0, 0xc6,
+ 0xfb, 0xae, 0x13, 0xf4, 0xd6, 0x6b, 0x2f, 0xbd, 0x4f, 0xe4, 0xab, 0xef,
+ 0xbe, 0xf9, 0x42, 0xe1, 0xef, 0xbf, 0x00, 0xfb, 0x1b, 0xc5, 0xc0, 0x04,
+ 0x17, 0x3c, 0xb0, 0x14, 0x08, 0x27, 0xac, 0x30, 0xc2, 0x53, 0x34, 0xec,
+ 0xf0, 0xc3, 0x0d, 0x53, 0x21, 0xf1, 0xc4, 0x14, 0x4b, 0x5c, 0xc5, 0xc5,
+ 0x18, 0x67, 0x7c, 0xb1, 0x15, 0x1c, 0x77, 0xec, 0x31, 0xc7, 0x57, 0x84,
+ 0x2c, 0xf2, 0xc8, 0x21, 0x63, 0x61, 0xf2, 0xc9, 0x28, 0x9b, 0x9c, 0xc5,
+ 0xca, 0x2c, 0xb7, 0xbc, 0x72, 0xb6, 0x30, 0x23, 0xe1, 0xed, 0xcc, 0x49,
+ 0x8c, 0x6b, 0xb3, 0x12, 0xe8, 0xe6, 0xbc, 0x44, 0xbb, 0x3c, 0x33, 0x21,
+ 0xef, 0xcf, 0x4d, 0xdc, 0x2b, 0xb4, 0x13, 0xfc, 0x16, 0xfd, 0x44, 0xc0,
+ 0x48, 0x43, 0x61, 0xf0, 0xd2, 0x51, 0x2c, 0xec, 0xb4, 0x14, 0x10, 0x47,
+ 0x3d, 0x45, 0xc5, 0x54, 0x53, 0xa1, 0xf1, 0xd5, 0x55, 0x7c, 0xac, 0xb5,
+ 0x15, 0x24, 0x77, 0x7d, 0x45, 0xca, 0x60, 0x63, 0xe1, 0xf2, 0xd8, 0x59,
+ 0x68, 0x61, 0xf6, 0xd9, 0x68, 0x9b, 0xbd, 0xc5, 0xda, 0x6c, 0xb7, 0xbd,
+ 0x36, 0x17, 0x70, 0xc7, 0x2d, 0x37, 0xdc, 0x5d, 0xd4, 0x6d, 0xf7, 0xdd,
+ 0x75, 0x7b, 0xa1, 0xf7, 0xfe, 0xde, 0x7c, 0xeb, 0xfd, 0xc5, 0xdf, 0x80,
+ 0x07, 0xfe, 0x37, 0x18, 0x84, 0x17, 0x6e, 0x38, 0xe1, 0x61, 0x24, 0xae,
+ 0xf8, 0xe2, 0x89, 0x8b, 0xe1, 0xf8, 0xe3, 0x90, 0x3b, 0x3e, 0xc6, 0xe4,
+ 0x94, 0x57, 0x3e, 0x39, 0x19, 0x98, 0x67, 0xae, 0x39, 0xe6, 0x65, 0x74,
+ 0xee, 0xf9, 0xe7, 0x9d, 0x9b, 0x21, 0xfa, 0xe8, 0xa4, 0x8b, 0x7e, 0xc6,
+ 0xe9, 0xa8, 0xa7, 0x7e, 0x3a, 0x1a, 0xac, 0xb7, 0xee, 0x3a, 0xeb, 0x69,
+ 0xc4, 0x2e, 0xfb, 0xec, 0xb1, 0xab, 0x61, 0xfb, 0xed, 0xb8, 0xdb, 0xbe,
+ 0xc6, 0xee, 0xbc, 0xf7, 0xbe, 0x3b, 0x1b, 0xc0, 0x07, 0x2f, 0x3c, 0xf0,
+ 0x6d, 0x14, 0x6f, 0xfc, 0xf1, 0xc5, 0xbb, 0xa1, 0xfc, 0xf2, 0xcc, 0x2b,
+ 0xff, 0xc6, 0xf3, 0xd0, 0x47, 0xff, 0x3c, 0x1c, 0xd4, 0x57, 0x6f, 0x3d,
+ 0xf5, 0x71, 0x64, 0xaf, 0xfd, 0xf6, 0xd9, 0xcb, 0xe1, 0xfd, 0xf7, 0xe0,
+ 0x7b, 0x3f, 0xc7, 0xf8, 0xe4, 0x97, 0x3f, 0x3e, 0x1d, 0xe8, 0xa7, 0xaf,
+ 0x3e, 0xfa, 0x75, 0xb4, 0xef, 0xfe, 0xfb, 0xed, 0xdb, 0x21, 0xff, 0xfc,
+ 0xf4, 0xcb, 0x7f, 0xc7, 0xfd, 0xf8, 0xe7, 0x7f, 0x3f, 0x1e, 0xfc, 0xf7,
+ 0xef, 0x3f, 0xff, 0x79, 0x08, 0xa0, 0x00, 0x07, 0x18, 0x40, 0x3d, 0x18,
+ 0xf0, 0x80, 0x08, 0x34, 0xe0, 0x1e, 0x16, 0xc8, 0xc0, 0x06, 0x2e, 0x90,
+ 0x0f, 0x10, 0x8c, 0xa0, 0x04, 0x21, 0xd8, 0x87, 0x0a, 0x5a, 0xf0, 0x82,
+ 0x15, 0x1c, 0x9e, 0x06, 0xd9, 0x80, 0xbc, 0x0e, 0xb6, 0xa1, 0x79, 0x20,
+ 0x74, 0x83, 0xf4, 0x46, 0xf8, 0x86, 0xeb, 0x99, 0x10, 0x0e, 0xdc, 0x4b,
+ 0x61, 0x1c, 0xc2, 0xc7, 0x42, 0x39, 0x98, 0xef, 0x85, 0x73, 0x58, 0x9f,
+ 0x0c, 0xe9, 0x00, 0xbf, 0x1a, 0xd6, 0xa1, 0x7e, 0x38, 0xb4, 0x83, 0xfe,
+ 0x76, 0x78, 0x87, 0xff, 0xf9, 0x10, 0x0f, 0xfe, 0x04, 0x0c, 0x62, 0x1e,
+ 0x12, 0x48, 0x44, 0x3d, 0x38, 0xf0, 0x88, 0x7b, 0x98, 0xa0, 0x12, 0xf9,
+ 0x80, 0xc1, 0x26, 0xf6, 0xc1, 0x0f, 0x50, 0x8c, 0xa2, 0x14, 0xa1, 0xf8,
+ 0x87, 0x2a, 0x5a, 0xf1, 0x8a, 0x55, 0x04, 0x84, 0x16, 0xb7, 0xc8, 0x45,
+ 0x2d, 0x06, 0xe2, 0x8b, 0x60, 0x0c, 0xe3, 0x17, 0x05, 0x41, 0xc6, 0x32,
+ 0x9a, 0x91, 0x8c, 0x83, 0x48, 0xa3, 0x1a, 0xd7, 0x98, 0x46, 0x42, 0xb8,
+ 0xf1, 0x8d, 0x70, 0x74, 0x63, 0x21, 0xe6, 0x48, 0xc7, 0x3a, 0xce, 0xd1,
+ 0x10, 0x78, 0xcc, 0xa3, 0x1e, 0xf1, 0x78, 0x88, 0x3e, 0xfa, 0xf1, 0x8f,
+ 0x7d, 0x44, 0x84, 0x20, 0x07, 0x49, 0x48, 0x41, 0x26, 0xe2, 0x90, 0x88,
+ 0x4c, 0xe4, 0x21, 0x15, 0xc1, 0xc8, 0x46, 0x3a, 0x92, 0x91, 0x8b, 0x88,
+ 0xa4, 0x24, 0x27, 0x19, 0x49, 0x46, 0x58, 0xf2, 0x92, 0x98, 0xb4, 0x64,
+ 0x23, 0x36, 0xc9, 0xc9, 0x4e, 0x6e, 0xd2, 0x11, 0xa0, 0x0c, 0xa5, 0x28,
+ 0x41, 0xf9, 0x88, 0x52, 0x9a, 0xf2, 0x94, 0xa5, 0x84, 0x84, 0x2a, 0x57,
+ 0xc9, 0x4a, 0x55, 0x46, 0xe2, 0x95, 0xb0, 0x8c, 0xe5, 0x2b, 0x25, 0x41,
+ 0xcb, 0x5a, 0xda, 0x92, 0x96, 0x93, 0xc8, 0xa5, 0x2e, 0x77, 0x99, 0x4b,
+ 0x4a, 0xf8, 0xf2, 0x97, 0xc0, 0xf4, 0x65, 0x25, 0x86, 0x49, 0xcc, 0x62,
+ 0x0e, 0xd3, 0x12, 0xc8, 0x4c, 0xa6, 0x32, 0x91, 0x79, 0x89, 0x66, 0x3a,
+ 0xf3, 0x99, 0xcd, 0xc4, 0x84, 0x34, 0xa7, 0x49, 0x4d, 0x69, 0x66, 0xe2,
+ 0x9a, 0xd8, 0xcc, 0xe6, 0x35, 0x35, 0xc1, 0xcd, 0x6e, 0x7a, 0x93, 0x9b,
+ 0x9b, 0x08, 0xa7, 0x38, 0xc7, 0x19, 0x4e, 0x4e, 0x98, 0xf3, 0x9c, 0xe8,
+ 0x34, 0x67, 0x27, 0xd6, 0xc9, 0xce, 0x76, 0xae, 0xd3, 0x13, 0xf0, 0x8c,
+ 0xa7, 0x3c, 0xe1, 0xf9, 0x89, 0x7a, 0xda, 0xf3, 0x9e, 0xf5, 0xfe, 0x04,
+ 0x85, 0x3e, 0xf7, 0xc9, 0x4f, 0x7d, 0x86, 0xe2, 0x9f, 0x00, 0x0d, 0xe8,
+ 0x3f, 0x5b, 0x49, 0x50, 0x48, 0xc8, 0xf2, 0xa0, 0x91, 0xb8, 0xa5, 0x42,
+ 0x25, 0xc1, 0xcb, 0x86, 0x4e, 0x22, 0x98, 0x10, 0xa5, 0x84, 0x31, 0x27,
+ 0x5a, 0x89, 0x65, 0x5a, 0xd4, 0x12, 0xd0, 0xcc, 0xe8, 0x25, 0xaa, 0xc9,
+ 0x51, 0x4c, 0x68, 0xf3, 0xa3, 0x99, 0xf8, 0xa6, 0x48, 0x35, 0x41, 0xce,
+ 0x92, 0x6e, 0x22, 0x9d, 0x28, 0xe5, 0x84, 0x3b, 0x57, 0xda, 0x89, 0x79,
+ 0xba, 0xd4, 0x13, 0xf8, 0x8c, 0xe9, 0x27, 0xfa, 0x49, 0x53, 0x50, 0x08,
+ 0xf4, 0xa6, 0xa1, 0x10, 0x85, 0x4e, 0x77, 0xca, 0x53, 0x9d, 0x8e, 0xe2,
+ 0xa7, 0x40, 0x0d, 0xea, 0x4f, 0x49, 0x41, 0xd4, 0xa2, 0x1a, 0x95, 0xa8,
+ 0xa5, 0x48, 0xaa, 0x52, 0x97, 0x9a, 0x54, 0x53, 0x38, 0xf5, 0xa9, 0x50,
+ 0x75, 0xea, 0x29, 0xa6, 0x4a, 0xd5, 0xaa, 0x4e, 0x15, 0x15, 0x58, 0xcd,
+ 0xaa, 0x56, 0xb1, 0x9a, 0x8a, 0xae, 0x7a, 0xf5, 0xab, 0x5d, 0x55, 0x85,
+ 0x58, 0xc7, 0x4a, 0x56, 0xb1, 0xae, 0xe2, 0xac, 0x68, 0x4d, 0xeb, 0x59,
+ 0x59, 0xc1, 0xd6, 0xb6, 0xba, 0x95, 0xad, 0xad, 0x88, 0xab, 0x5c, 0xe7,
+ 0x1a, 0x57, 0x57, 0xd8, 0xf5, 0xae, 0x78, 0xb5, 0xeb, 0x2b, 0xf6, 0xca,
+ 0xd7, 0xbe, 0xee, 0x15, 0x16, 0x80, 0x0d, 0xac, 0x60, 0x01, 0x1b, 0x8b,
+ 0xc2, 0x1a, 0xf6, 0xb0, 0x85, 0x95, 0x85, 0x62, 0x17, 0xcb, 0x58, 0xc5,
+ 0xce, 0xe2, 0xb1, 0x90, 0x8d, 0xec, 0x63, 0x69, 0x41, 0xd9, 0xca, 0x5a,
+ 0x96, 0xb2, 0xb5, 0xc8, 0xac, 0x66, 0x37, 0x9b, 0x59, 0x5b, 0x78, 0xf6,
+ 0xb3, 0xa0, 0xf5, 0xec, 0x2d, 0x46, 0x4b, 0xda, 0xd2, 0x8e, 0x16, 0x17,
+ 0xa8, 0x4d, 0xad, 0x6a, 0x51, 0x9b, 0x8b, 0xd6, 0xba, 0xf6, 0xb5, 0xad,
+ 0xd5, 0xfe, 0x85, 0x6c, 0x67, 0x4b, 0x5b, 0xd9, 0xee, 0xe2, 0xb6, 0xb8,
+ 0xcd, 0xed, 0x6d, 0x79, 0xc1, 0xdb, 0xde, 0xfa, 0x96, 0xb7, 0xbd, 0x08,
+ 0xae, 0x70, 0x87, 0x1b, 0x5c, 0x5f, 0x18, 0xf7, 0xb8, 0xc8, 0x35, 0xee,
+ 0x2f, 0x96, 0xcb, 0xdc, 0xe6, 0x2e, 0x17, 0x18, 0xd0, 0x8d, 0xae, 0x74,
+ 0xa1, 0x1b, 0x8c, 0xea, 0x5a, 0xf7, 0xba, 0xd5, 0x15, 0x86, 0x76, 0xb7,
+ 0xcb, 0x5d, 0xed, 0x0e, 0xe3, 0xbb, 0xe0, 0x0d, 0xef, 0x77, 0x89, 0x41,
+ 0xde, 0xf2, 0x9a, 0x97, 0xbc, 0xc5, 0x48, 0xaf, 0x7a, 0xd7, 0x9b, 0xde,
+ 0xcb, 0xba, 0x97, 0x16, 0x9c, 0x8d, 0x6f, 0x2d, 0x42, 0x4b, 0x5f, 0x5b,
+ 0x98, 0xf6, 0xbe, 0xb7, 0x58, 0xad, 0x7e, 0x71, 0x01, 0xdb, 0xfe, 0xe6,
+ 0xa2, 0xb6, 0x00, 0xd6, 0x85, 0x6e, 0x07, 0xbc, 0x8b, 0xdf, 0x1a, 0x98,
+ 0x17, 0xc4, 0x4d, 0x70, 0x2f, 0x92, 0xcb, 0x60, 0x5f, 0x38, 0xf7, 0xc1,
+ 0xbf, 0x98, 0xae, 0x84, 0x81, 0x81, 0xdd, 0x0a, 0x07, 0xa3, 0xbb, 0x18,
+ 0x16, 0x86, 0x78, 0x37, 0x3c, 0x8c, 0xf3, 0x7a, 0x98, 0x18, 0xec, 0x0d,
+ 0x71, 0x31, 0x8c, 0x41, 0xe2, 0x12, 0x9b, 0x98, 0xc4, 0xc7, 0x48, 0xb1,
+ 0x8a, 0x57, 0x9c, 0x62, 0x64, 0xb8, 0xf8, 0xc5, 0x30, 0x76, 0x71, 0x32,
+ 0x66, 0x4c, 0xe3, 0x1a, 0xcf, 0x58, 0x19, 0x38, 0xce, 0xb1, 0x8e, 0x71,
+ 0xbc, 0x8c, 0x1e, 0xfb, 0xf8, 0xc7, 0x3d, 0x66, 0x86, 0x90, 0x87, 0x4c,
+ 0x64, 0x21, 0x37, 0xe3, 0xc8, 0x48, 0x4e, 0xf2, 0x91, 0x9d, 0xc1, 0xe4,
+ 0x26, 0x3b, 0x99, 0xc9, 0xcf, 0x88, 0xb2, 0x94, 0xa7, 0x1c, 0x65, 0x68,
+ 0x58, 0xf9, 0xca, 0x58, 0xb6, 0x72, 0x34, 0xb6, 0xcc, 0xe5, 0x2e, 0x6f,
+ 0x59, 0x1a, 0x60, 0x0e, 0xb3, 0x98, 0xc1, 0x3c, 0x8d, 0x32, 0x9b, 0xf9,
+ 0xcc, 0x65, 0xa6, 0x86, 0xfe, 0x9a, 0xd7, 0xcc, 0x66, 0x35, 0x57, 0xe3,
+ 0xcd, 0x70, 0x8e, 0xf3, 0x9b, 0xad, 0x41, 0xe7, 0x3a, 0xdb, 0x99, 0xce,
+ 0xd7, 0xc8, 0xb3, 0x9e, 0xf7, 0x9c, 0xe7, 0xae, 0x14, 0x04, 0x2c, 0x0a,
+ 0x19, 0xcb, 0x43, 0xcc, 0x42, 0x91, 0xb4, 0x64, 0x84, 0x2d, 0x1e, 0x79,
+ 0xcb, 0x48, 0xe4, 0x82, 0x92, 0xba, 0xb4, 0x04, 0x2f, 0x32, 0xd9, 0xcb,
+ 0x4d, 0xfc, 0xc2, 0x93, 0xc0, 0x04, 0x85, 0x30, 0x46, 0x39, 0xcc, 0x52,
+ 0x14, 0x03, 0x95, 0xc6, 0x54, 0x05, 0x32, 0x5a, 0xa9, 0x8c, 0xa8, 0x25,
+ 0xa0, 0x99, 0x52, 0x4f, 0xe0, 0x33, 0xa8, 0xa6, 0x00, 0x69, 0x56, 0x5d,
+ 0x81, 0xd4, 0xb8, 0xda, 0x02, 0xae, 0x89, 0xf5, 0x05, 0x66, 0x43, 0x6b,
+ 0x0c, 0xe0, 0xe6, 0xd6, 0x19, 0xe8, 0x8d, 0xae, 0x35, 0x20, 0x9c, 0x5e,
+ 0x6f, 0xe0, 0x38, 0xc0, 0xe6, 0x00, 0x73, 0x86, 0xdd, 0x81, 0xe8, 0x18,
+ 0xdb, 0x03, 0xd6, 0x49, 0xf6, 0x07, 0xb6, 0xc3, 0x6c, 0x10, 0x80, 0xe7,
+ 0xd9, 0x21, 0x28, 0x8f, 0xb4, 0x45, 0xa0, 0x9e, 0x6a, 0x8f, 0x60, 0xd4,
+ 0x95, 0x31, 0xb5, 0x66, 0x52, 0xfd, 0x19, 0x56, 0x93, 0xe6, 0xd5, 0xa9,
+ 0x91, 0xb5, 0x6b, 0x6a, 0x3d, 0x1b, 0x5c, 0xe3, 0x66, 0xd7, 0xbd, 0xf1,
+ 0xb5, 0x70, 0x82, 0x7d, 0x1c, 0x62, 0x33, 0xe7, 0xd8, 0xd1, 0x51, 0xb6,
+ 0x75, 0x9a, 0xbd, 0x1d, 0x68, 0x83, 0x67, 0xda, 0xe5, 0xb1, 0xb6, 0x7a,
+ 0x8e, 0xf4, 0x1e, 0x25, 0xd1, 0xa7, 0x49, 0xf9, 0x81, 0x92, 0x7f, 0xa6,
+ 0x34, 0x20, 0x2b, 0x21, 0x28, 0x4b, 0x0d, 0xe2, 0x92, 0x84, 0xbe, 0x74,
+ 0x21, 0x31, 0x71, 0xa8, 0x4c, 0x21, 0x42, 0x93, 0x89, 0xd6, 0xb4, 0x22,
+ 0x37, 0xc1, 0x28, 0x4e, 0x35, 0xa2, 0x93, 0x8e, 0xee, 0xf4, 0x23, 0x3d,
+ 0x11, 0xe9, 0x4f, 0x20, 0xb7, 0x01, 0xa1, 0xfe, 0x46, 0x7e, 0x83, 0x44,
+ 0x99, 0x1c, 0x07, 0x8e, 0x4a, 0x79, 0x0e, 0x26, 0xc5, 0x72, 0x1d, 0x60,
+ 0xea, 0xe5, 0x3b, 0xe8, 0x94, 0xcc, 0x79, 0x20, 0xaa, 0x9a, 0xf7, 0xe0,
+ 0x54, 0x38, 0xf7, 0x01, 0xab, 0x76, 0xfe, 0x83, 0x58, 0xf9, 0x1c, 0x08,
+ 0xb6, 0x0a, 0x7a, 0x10, 0x76, 0x45, 0x74, 0x21, 0x00, 0xeb, 0xe8, 0x43,
+ 0x28, 0x96, 0xd2, 0x89, 0xa0, 0xac, 0xa6, 0x17, 0xe1, 0x59, 0x50, 0x37,
+ 0x02, 0xb5, 0xa6, 0x7e, 0x84, 0x90, 0xff, 0x89, 0xe4, 0x84, 0x3a, 0x79,
+ 0xa2, 0x54, 0xee, 0xa8, 0x96, 0x4f, 0x0a, 0xe6, 0x98, 0x9a, 0x79, 0xa7,
+ 0x6c, 0x2e, 0xaa, 0x9c, 0x9f, 0x8a, 0xe7, 0xac, 0xfa, 0x79, 0xac, 0x84,
+ 0x6e, 0xab, 0xa2, 0xef, 0x0a, 0xe9, 0xc0, 0x5a, 0x7a, 0xb1, 0x9c, 0xae,
+ 0xac, 0xa8, 0x3f, 0x8b, 0xea, 0xd4, 0x8a, 0x59, 0xb6, 0x68, 0xe6, 0xad,
+ 0x9b, 0x8d, 0x4b, 0x67, 0xe8, 0xea, 0x59, 0xbb, 0x80, 0x26, 0xaf, 0xa1,
+ 0xdd, 0xcb, 0x68, 0xfc, 0x4a, 0x5a, 0xc0, 0x98, 0x66, 0xb0, 0xa7, 0x2d,
+ 0x4c, 0x6a, 0x10, 0xab, 0x5a, 0xc5, 0xb0, 0xa6, 0xb1, 0xad, 0x7d, 0xcc,
+ 0x6b, 0x24, 0x0b, 0x5b, 0xca, 0xc8, 0xe6, 0xb2, 0xb4, 0x79, 0x5e, 0x0b,
+ 0x6e, 0x0b, 0xfd, 0x16, 0xe6, 0x46, 0x7a, 0x2e, 0xe0, 0xed, 0xf4, 0x5d,
+ 0xe8, 0x9b, 0xea, 0xbd, 0x20, 0xb8, 0xd6, 0x7f, 0xe1, 0x70, 0xb0, 0x07,
+ 0x03, 0xe3, 0x66, 0x1f, 0x86, 0xc8, 0xd9, 0x5e, 0x0c, 0x96, 0xcb, 0xfd,
+ 0x18, 0x36, 0xc7, 0x7b, 0x32, 0x80, 0xee, 0xf7, 0x65, 0x28, 0x9d, 0xf0,
+ 0xcd, 0xa0, 0xba, 0xe2, 0x9f, 0xe1, 0x75, 0xc8, 0x47, 0x03, 0xed, 0x96,
+ 0x9f, 0x86, 0xdc, 0x39, 0x5f, 0x0d, 0xbe, 0x8b, 0xfe, 0x1a, 0x3e, 0x9f,
+ 0x36, 0xd1, 0xbb, 0xad, 0xf4, 0x73, 0x43, 0x3d, 0xde, 0x56, 0xfe, 0xdf,
+ 0x37, 0xd7, 0x0b, 0x2e, 0xf6, 0x87, 0xa3, 0x3d, 0xe3, 0x6e, 0x1f, 0x39,
+ 0xdd, 0x5b, 0xae, 0xf7, 0x9b, 0x03, 0x3e, 0xe8, 0x86, 0x5f, 0x3a, 0xe3,
+ 0xab, 0x2e, 0xf9, 0xaf, 0x63, 0x3e, 0xed, 0x9e, 0x9f, 0x3b, 0xe9, 0xfb,
+ 0x6e, 0x83, 0xc3, 0xf3, 0x20, 0xf2, 0x42, 0xd8, 0x3c, 0x12, 0x4a, 0xef,
+ 0x84, 0xd7, 0xa3, 0x42, 0xdc, 0xd3, 0x42, 0xe1, 0x03, 0x43, 0xe6, 0x33,
+ 0x43, 0xeb, 0x63, 0x43, 0xf0, 0x93, 0x43, 0xf5, 0xc3, 0x43, 0xfa, 0xf3,
+ 0x43, 0xff, 0x23, 0x44, 0x04, 0x54, 0x44, 0x09, 0x84, 0x44, 0x0e, 0xb4,
+ 0x44, 0x13, 0xe4, 0x44, 0x18, 0x34, 0x45, 0x1c, 0xe8, 0x07, 0x58, 0xf4,
+ 0x81, 0x7f, 0xd0, 0x45, 0x22, 0x08, 0x08, 0x62, 0x54, 0x82, 0x81, 0x70,
+ 0x46, 0x28, 0x28, 0x08, 0x6c, 0xb4, 0x82, 0x83, 0x10, 0x47, 0x2e, 0x48,
+ 0x08, 0x76, 0x14, 0x83, 0x85, 0xb0, 0x47, 0x34, 0x68, 0x08, 0x80, 0x74,
+ 0x83, 0x87, 0x50, 0x48, 0x3a, 0x88, 0x08, 0x8a, 0xd4, 0x83, 0x89, 0xf0,
+ 0x48, 0x40, 0xa8, 0x08, 0x94, 0x34, 0x84, 0x8b, 0x90, 0x49, 0x46, 0xc8,
+ 0x08, 0x9e, 0x94, 0x84, 0x8d, 0x30, 0x4a, 0x4c, 0xe8, 0x08, 0xa8, 0xf4,
+ 0x84, 0x8f, 0xd0, 0x81, 0x53, 0x04, 0x82, 0x58, 0x34, 0x82, 0x5d, 0x64,
+ 0x82, 0x62, 0x94, 0x82, 0x67, 0xc4, 0x82, 0x6c, 0xf4, 0x82, 0x71, 0x24,
+ 0x83, 0x76, 0x54, 0x83, 0x7b, 0x84, 0x83, 0x80, 0xb4, 0x83, 0x85, 0xe4,
+ 0x83, 0x8a, 0x14, 0x84, 0x8f, 0x44, 0x84, 0x94, 0x74, 0x84, 0x99, 0xa4,
+ 0x84, 0x9e, 0xd4, 0x84, 0xa3, 0x04, 0x85, 0xa8, 0x54, 0x50, 0xad, 0x84,
+ 0x50, 0xb2, 0xb4, 0x50, 0xb7, 0xe4, 0x50, 0xbc, 0x14, 0x51, 0xc1, 0x44,
+ 0x51, 0xc6, 0x74, 0x51, 0xcb, 0xa4, 0x51, 0xd0, 0xd4, 0x51, 0xd5, 0x04,
+ 0x52, 0xfe, 0xda, 0x34, 0x52, 0xdf, 0x64, 0x52, 0xe4, 0x94, 0x52, 0xe9,
+ 0xc4, 0x52, 0xee, 0xf4, 0x52, 0xf3, 0x24, 0x53, 0xf8, 0x54, 0x53, 0xfd,
+ 0x84, 0x53, 0x02, 0xd5, 0x53, 0x9a, 0x28, 0x0a, 0x42, 0xd5, 0x89, 0xa3,
+ 0x70, 0x54, 0xa0, 0x48, 0x0a, 0x4c, 0x35, 0x8a, 0xa5, 0x10, 0x55, 0xa6,
+ 0x68, 0x0a, 0x56, 0x95, 0x8a, 0xa7, 0xb0, 0x55, 0xac, 0x88, 0x0a, 0x60,
+ 0xf5, 0x8a, 0xa9, 0x50, 0x56, 0xb2, 0xa8, 0x0a, 0x6a, 0x55, 0x8b, 0xab,
+ 0xf0, 0x56, 0xb8, 0xc8, 0x0a, 0x74, 0xb5, 0x8b, 0xad, 0x90, 0x57, 0xbe,
+ 0xe8, 0x0a, 0x7e, 0x15, 0x8c, 0xaf, 0x30, 0x58, 0xc4, 0x08, 0x0b, 0x88,
+ 0x75, 0x8c, 0xb1, 0xd0, 0x58, 0xca, 0x28, 0x0b, 0x92, 0xd5, 0x8c, 0xb3,
+ 0xb0, 0x89, 0x3d, 0xe5, 0x89, 0x42, 0x15, 0x8a, 0x47, 0x45, 0x8a, 0x4c,
+ 0x75, 0x8a, 0x51, 0xa5, 0x8a, 0x56, 0xd5, 0x8a, 0x5b, 0x05, 0x8b, 0x60,
+ 0x35, 0x8b, 0x65, 0x65, 0x8b, 0x6a, 0x95, 0x8b, 0x6f, 0xc5, 0x8b, 0x74,
+ 0xf5, 0x8b, 0x79, 0x25, 0x8c, 0x7e, 0x55, 0x8c, 0x83, 0x85, 0x8c, 0x88,
+ 0xb5, 0x8c, 0x8d, 0xe5, 0x8c, 0x92, 0xf5, 0x5e, 0x97, 0x25, 0x5f, 0x9c,
+ 0x55, 0x5f, 0xa1, 0x85, 0x5f, 0xa6, 0xb5, 0x5f, 0xab, 0xe5, 0x5f, 0xb0,
+ 0x15, 0x60, 0xb5, 0x45, 0x60, 0xba, 0x75, 0x60, 0xbf, 0xa5, 0x60, 0xc4,
+ 0xd5, 0x60, 0xc9, 0x05, 0x61, 0xce, 0x35, 0x61, 0xd3, 0x65, 0x61, 0xd8,
+ 0x95, 0x61, 0xdd, 0xc5, 0x61, 0xe2, 0xf5, 0x61, 0xe7, 0x25, 0x62, 0xec,
+ 0x75, 0x62, 0x18, 0x69, 0x0c, 0x2c, 0xb6, 0x91, 0xc7, 0x10, 0x63, 0x1e,
+ 0x89, 0x0c, 0x36, 0x16, 0x92, 0xc9, 0xb0, 0x63, 0x24, 0xa9, 0x0c, 0x40,
+ 0x76, 0x92, 0xcb, 0x50, 0x64, 0x2a, 0xc9, 0x0c, 0x4a, 0xd6, 0x92, 0xcd,
+ 0xf0, 0x64, 0x30, 0xe9, 0xfe, 0x0c, 0x54, 0x36, 0x93, 0xcf, 0x90, 0x65,
+ 0x36, 0x09, 0x0d, 0x5e, 0x96, 0x93, 0xd1, 0x30, 0x66, 0x3c, 0x29, 0x0d,
+ 0x68, 0xf6, 0x93, 0xd3, 0xd0, 0x66, 0x42, 0x49, 0x0d, 0x72, 0x56, 0x94,
+ 0xd5, 0x70, 0x67, 0x48, 0x69, 0x0d, 0x7c, 0xb6, 0x94, 0xd7, 0x90, 0x91,
+ 0x27, 0xc6, 0x91, 0x2c, 0xf6, 0x91, 0x31, 0x26, 0x92, 0x36, 0x56, 0x92,
+ 0x3b, 0x86, 0x92, 0x40, 0xb6, 0x92, 0x45, 0xe6, 0x92, 0x4a, 0x16, 0x93,
+ 0x4f, 0x46, 0x93, 0x54, 0x76, 0x93, 0x59, 0xa6, 0x93, 0x5e, 0xd6, 0x93,
+ 0x63, 0x06, 0x94, 0x68, 0x36, 0x94, 0x6d, 0x66, 0x94, 0x72, 0x96, 0x94,
+ 0x77, 0xc6, 0x94, 0x7c, 0xe6, 0x67, 0x04, 0x01, 0x68, 0x09, 0x21, 0x68,
+ 0x0e, 0x41, 0x68, 0x13, 0x61, 0x68, 0x18, 0x81, 0x68, 0x1d, 0xa1, 0x68,
+ 0x22, 0xc1, 0x68, 0x27, 0xe1, 0x68, 0x2c, 0x01, 0x69, 0x31, 0x21, 0x69,
+ 0x36, 0x41, 0x69, 0x3b, 0x61, 0x69, 0x40, 0x81, 0x69, 0x45, 0xa1, 0x69,
+ 0x4a, 0xc1, 0x69, 0x4f, 0xe1, 0x69, 0x54, 0x01, 0x6a, 0x59, 0x21, 0x97,
+ 0x03, 0x41, 0x97, 0x08, 0x61, 0x97, 0x0d, 0x81, 0x97, 0x12, 0xa1, 0x97,
+ 0x17, 0xc1, 0x97, 0x1c, 0xe1, 0x97, 0x21, 0x01, 0x98, 0x26, 0x21, 0x98,
+ 0x2b, 0x41, 0x98, 0x30, 0x61, 0x98, 0x35, 0x81, 0x98, 0x3a, 0xa1, 0x98,
+ 0x3f, 0xc1, 0x98, 0x44, 0xe1, 0x98, 0x49, 0x01, 0x99, 0x4e, 0x21, 0x99,
+ 0x53, 0x41, 0x99, 0x58, 0x61, 0x99, 0x06, 0x81, 0x99, 0x61, 0xa1, 0x99,
+ 0x64, 0xc1, 0x99, 0x67, 0xe1, 0x99, 0x6a, 0x01, 0x9a, 0x6d, 0x21, 0x9a,
+ 0x70, 0x41, 0x9a, 0x73, 0x61, 0x9a, 0x76, 0x81, 0x9a, 0x79, 0xa1, 0x9a,
+ 0x7c, 0xc1, 0x9a, 0x7f, 0xe1, 0x9a, 0x82, 0x01, 0x9b, 0x85, 0x21, 0x9b,
+ 0x88, 0x41, 0x9b, 0x8b, 0x61, 0x9b, 0x8e, 0xfe, 0x81, 0x9b, 0x91, 0x81,
+ 0x6d, 0x93, 0xa1, 0x6d, 0x99, 0xc1, 0x6d, 0x9e, 0xe1, 0x6d, 0xa3, 0x01,
+ 0x6e, 0xa8, 0x21, 0x6e, 0xad, 0x41, 0x6e, 0xb2, 0x61, 0x6e, 0xb7, 0x81,
+ 0x6e, 0xbc, 0xa1, 0x6e, 0xc1, 0xc1, 0x6e, 0xc6, 0xe1, 0x6e, 0xcb, 0x01,
+ 0x6f, 0xd0, 0x21, 0x6f, 0xd5, 0x41, 0x6f, 0xda, 0x61, 0x6f, 0xdf, 0x81,
+ 0x6f, 0xe4, 0xa1, 0x6f, 0xe9, 0xe1, 0x9d, 0xdf, 0x09, 0x9e, 0x9b, 0x21,
+ 0x9e, 0xa0, 0x41, 0x9e, 0xa5, 0x61, 0x9e, 0xaa, 0x81, 0x9e, 0xaf, 0xa1,
+ 0x9e, 0xb4, 0xc1, 0x9e, 0xb9, 0xe1, 0x9e, 0xbe, 0x01, 0x9f, 0xc3, 0x21,
+ 0x9f, 0xc8, 0x41, 0x9f, 0xcd, 0x61, 0x9f, 0xd2, 0x81, 0x9f, 0xd7, 0xa1,
+ 0x9f, 0xdc, 0xc1, 0x9f, 0xe1, 0xe1, 0x9f, 0xe6, 0x01, 0xa0, 0xe7, 0x21,
+ 0xa0, 0x96, 0x41, 0xa0, 0xa7, 0x66, 0xa0, 0xaa, 0x86, 0xa0, 0xad, 0xa6,
+ 0xa0, 0xb0, 0xc6, 0xa0, 0xb3, 0xe6, 0xa0, 0xb6, 0x06, 0xa1, 0xb9, 0x26,
+ 0xa1, 0xbc, 0x46, 0xa1, 0xbf, 0x66, 0xa1, 0xc2, 0x86, 0xa1, 0xc5, 0xa6,
+ 0xa1, 0xc8, 0xc6, 0xa1, 0xcb, 0xe6, 0xa1, 0xce, 0x06, 0xa2, 0xd1, 0x26,
+ 0xa2, 0xd4, 0x46, 0xa2, 0x23, 0xc0, 0x6f, 0xee, 0xe1, 0x6f, 0xf3, 0x01,
+ 0x70, 0xf8, 0x21, 0x70, 0xfd, 0x41, 0x70, 0x02, 0x62, 0x70, 0x07, 0x82,
+ 0x70, 0x0c, 0xa2, 0x70, 0x11, 0xc2, 0x70, 0x16, 0xe2, 0x70, 0x1b, 0x02,
+ 0x71, 0x20, 0x22, 0x71, 0x25, 0x42, 0x71, 0x2a, 0x62, 0x71, 0x2f, 0x82,
+ 0x71, 0x34, 0xa2, 0x71, 0x39, 0xc2, 0x71, 0x3e, 0xe2, 0x71, 0x43, 0xa2,
+ 0xa4, 0xed, 0xc1, 0xa4, 0xf2, 0xe1, 0xa4, 0xf7, 0x01, 0xa5, 0xfc, 0x21,
+ 0xa5, 0x01, 0x42, 0xa5, 0x06, 0x62, 0xa5, 0x0b, 0x82, 0xa5, 0x10, 0xa2,
+ 0xa5, 0x15, 0xc2, 0xa5, 0x1a, 0xe2, 0xa5, 0x1f, 0x02, 0xa6, 0xfe, 0x24,
+ 0x22, 0xa6, 0x29, 0x42, 0xa6, 0x2e, 0x62, 0xa6, 0x33, 0x82, 0xa6, 0x38,
+ 0xa2, 0xa6, 0x3d, 0xc2, 0xa6, 0x42, 0xe2, 0xa6, 0xf0, 0x01, 0xa7, 0x4b,
+ 0x22, 0xa7, 0x4e, 0x42, 0xa7, 0x51, 0x62, 0xa7, 0x54, 0x82, 0xa7, 0x57,
+ 0xa2, 0xa7, 0x5a, 0xc2, 0xa7, 0x5d, 0xe2, 0xa7, 0x60, 0x02, 0xa8, 0x63,
+ 0x22, 0xa8, 0x66, 0x42, 0xa8, 0x69, 0x62, 0xa8, 0x6c, 0x82, 0xa8, 0x6f,
+ 0xa2, 0xa8, 0x72, 0xc2, 0xa8, 0x75, 0xe2, 0xa8, 0x78, 0x02, 0xa9, 0x7b,
+ 0x62, 0x75, 0x7d, 0x82, 0x75, 0x83, 0xa2, 0x75, 0x88, 0xc2, 0x75, 0x8d,
+ 0xe2, 0x75, 0x92, 0x02, 0x76, 0x97, 0x22, 0x76, 0x9c, 0x42, 0x76, 0xa1,
+ 0x62, 0x76, 0xa6, 0x82, 0x76, 0xab, 0xa2, 0x76, 0xb0, 0xc2, 0x76, 0xb5,
+ 0xe2, 0x76, 0xba, 0x02, 0x77, 0xbf, 0x22, 0x77, 0xc4, 0x42, 0x77, 0xc9,
+ 0x62, 0x77, 0xce, 0x82, 0x77, 0xd3, 0x62, 0xab, 0xb7, 0x8a, 0xab, 0x85,
+ 0xa2, 0xab, 0x8a, 0xc2, 0xab, 0x8f, 0xe2, 0xab, 0x94, 0x02, 0xac, 0x99,
+ 0x22, 0xac, 0x9e, 0x42, 0xac, 0xa3, 0x62, 0xac, 0xa8, 0x82, 0xac, 0xad,
+ 0xa2, 0xac, 0xb2, 0xc2, 0xac, 0xb7, 0xe2, 0xac, 0xbc, 0x02, 0xad, 0xc1,
+ 0x22, 0xad, 0xc6, 0x42, 0xad, 0xcb, 0x62, 0xad, 0xd0, 0x82, 0xad, 0xd1,
+ 0xa2, 0xad, 0x80, 0xc2, 0xad, 0x25, 0xe7, 0xad, 0x28, 0x07, 0xae, 0x2b,
+ 0x27, 0xae, 0x2e, 0x47, 0xae, 0x31, 0x67, 0xae, 0x34, 0x87, 0xae, 0x37,
+ 0xa7, 0xae, 0x3a, 0xc7, 0xae, 0x3d, 0xe7, 0xae, 0x40, 0x07, 0xaf, 0x43,
+ 0x27, 0xaf, 0x46, 0x47, 0xaf, 0x49, 0x67, 0xaf, 0x4c, 0x87, 0xaf, 0x4f,
+ 0xa7, 0xaf, 0x52, 0xc7, 0xaf, 0x47, 0xa0, 0x77, 0xd8, 0xc2, 0x77, 0xdd,
+ 0xe2, 0x77, 0xe2, 0x02, 0x78, 0xe7, 0x22, 0x78, 0xec, 0x42, 0x78, 0xf1,
+ 0x62, 0xfe, 0x78, 0xf6, 0x82, 0x78, 0xfb, 0xa2, 0x78, 0x00, 0xc3, 0x78,
+ 0x05, 0xe3, 0x78, 0x0a, 0x03, 0x79, 0x0f, 0x23, 0x79, 0x14, 0x43, 0x79,
+ 0x19, 0x63, 0x79, 0x1e, 0x83, 0x79, 0x23, 0xa3, 0x79, 0x28, 0xc3, 0x79,
+ 0x2d, 0x23, 0xb2, 0xd7, 0x42, 0xb2, 0xdc, 0x62, 0xb2, 0xe1, 0x82, 0xb2,
+ 0xe6, 0xa2, 0xb2, 0xeb, 0xc2, 0xb2, 0xf0, 0xe2, 0xb2, 0xf5, 0x02, 0xb3,
+ 0xfa, 0x22, 0xb3, 0xff, 0x42, 0xb3, 0x04, 0x63, 0xb3, 0x09, 0x83, 0xb3,
+ 0x0e, 0xa3, 0xb3, 0x13, 0xc3, 0xb3, 0x18, 0xe3, 0xb3, 0x1d, 0x03, 0xb4,
+ 0x22, 0x23, 0xb4, 0x27, 0x43, 0xb4, 0x2c, 0x63, 0xb4, 0xda, 0x82, 0xb4,
+ 0x35, 0xa3, 0xb4, 0x38, 0xc3, 0xb4, 0x3b, 0xe3, 0xb4, 0x3e, 0x03, 0xb5,
+ 0x41, 0x23, 0xb5, 0x44, 0x43, 0xb5, 0x47, 0x63, 0xb5, 0x4a, 0x83, 0xb5,
+ 0x4d, 0xa3, 0xb5, 0x50, 0xc3, 0xb5, 0x53, 0xe3, 0xb5, 0x56, 0x03, 0xb6,
+ 0x59, 0x23, 0xb6, 0x5c, 0x43, 0xb6, 0x5f, 0x63, 0xb6, 0x62, 0x83, 0xb6,
+ 0x65, 0x43, 0x7d, 0x67, 0x63, 0x7d, 0x6d, 0x83, 0x7d, 0x72, 0xa3, 0x7d,
+ 0x77, 0xc3, 0x7d, 0x7c, 0xe3, 0x7d, 0x81, 0x03, 0x7e, 0x86, 0x23, 0x7e,
+ 0x8b, 0x43, 0x7e, 0x90, 0x63, 0x7e, 0x95, 0x83, 0x7e, 0x9a, 0xa3, 0x7e,
+ 0x9f, 0xc3, 0x7e, 0xa4, 0xe3, 0x7e, 0xa9, 0x03, 0x7f, 0xae, 0x23, 0x7f,
+ 0xb3, 0x43, 0x7f, 0xb8, 0x63, 0x7f, 0xbd, 0xe3, 0xb8, 0x8f, 0x0b, 0xb9,
+ 0x6f, 0x23, 0xb9, 0x74, 0x43, 0xb9, 0x79, 0x63, 0xb9, 0x7e, 0x83, 0xb9,
+ 0x83, 0xa3, 0xb9, 0x88, 0xc3, 0xb9, 0x8d, 0xe3, 0xb9, 0x92, 0x03, 0xba,
+ 0x97, 0x23, 0xba, 0x9c, 0x43, 0xba, 0xa1, 0x63, 0xba, 0xa6, 0x83, 0xba,
+ 0xab, 0xa3, 0xba, 0xb0, 0xc3, 0xba, 0xb5, 0xe3, 0xba, 0xba, 0x03, 0xbb,
+ 0xbb, 0x23, 0xbb, 0x6a, 0xfe, 0x43, 0xbb, 0xa3, 0x67, 0xbb, 0xa6, 0x87,
+ 0xbb, 0xa9, 0xa7, 0xbb, 0xac, 0xc7, 0xbb, 0xaf, 0xe7, 0xbb, 0xb2, 0x07,
+ 0xbc, 0xb5, 0x27, 0xbc, 0xb8, 0x47, 0xbc, 0xbb, 0x67, 0xbc, 0xbe, 0x87,
+ 0xbc, 0xc1, 0xa7, 0xbc, 0xc4, 0xc7, 0xbc, 0xc7, 0xe7, 0xbc, 0xca, 0x07,
+ 0xbd, 0xcd, 0x27, 0xbd, 0xd0, 0x47, 0xbd, 0x6b, 0x80, 0x7f, 0xc2, 0xa3,
+ 0x7f, 0xc7, 0xc3, 0x7f, 0xcc, 0xe3, 0x7f, 0xd1, 0x03, 0x80, 0xd6, 0x23,
+ 0x80, 0xdb, 0x43, 0x80, 0xe0, 0x63, 0x80, 0xe5, 0x83, 0x80, 0xea, 0xa3,
+ 0x80, 0xef, 0xc3, 0x80, 0xf4, 0xe3, 0x80, 0xf9, 0x03, 0x81, 0xfe, 0x23,
+ 0x81, 0x03, 0x44, 0x81, 0x08, 0x64, 0x81, 0x0d, 0x84, 0x81, 0x12, 0xa4,
+ 0x81, 0x17, 0xa4, 0xbf, 0xc1, 0xc3, 0xbf, 0xc6, 0xe3, 0xbf, 0xcb, 0x03,
+ 0xc0, 0xd0, 0x23, 0xc0, 0xd5, 0x43, 0xc0, 0xda, 0x63, 0xc0, 0xdf, 0x83,
+ 0xc0, 0xe4, 0xa3, 0xc0, 0xe9, 0xc3, 0xc0, 0xee, 0xe3, 0xc0, 0xf3, 0x03,
+ 0xc1, 0xf8, 0x23, 0xc1, 0xfd, 0x43, 0xc1, 0x02, 0x64, 0xc1, 0x07, 0x84,
+ 0xc1, 0x0c, 0xa4, 0xc1, 0x11, 0xc4, 0xc1, 0x16, 0xe4, 0xc1, 0xc4, 0x03,
+ 0xc2, 0x1f, 0x24, 0xc2, 0x22, 0x44, 0xc2, 0x25, 0x64, 0xc2, 0x28, 0x84,
+ 0xc2, 0x2b, 0xa4, 0xc2, 0x2e, 0xc4, 0xc2, 0x31, 0xe4, 0xc2, 0x34, 0x04,
+ 0xc3, 0x37, 0x24, 0xc3, 0x3a, 0x44, 0xc3, 0x3d, 0x64, 0xc3, 0x40, 0x84,
+ 0xc3, 0x43, 0xa4, 0xc3, 0x46, 0xc4, 0xc3, 0x49, 0xe4, 0xc3, 0x4c, 0x04,
+ 0xc4, 0x4f, 0x24, 0x85, 0x51, 0x44, 0x85, 0x57, 0x64, 0x85, 0x5c, 0x84,
+ 0x85, 0x61, 0xa4, 0x85, 0x66, 0xc4, 0x85, 0x6b, 0xe4, 0x85, 0x70, 0x04,
+ 0x86, 0x75, 0x24, 0x86, 0x7a, 0x44, 0x86, 0x7f, 0x64, 0x86, 0x84, 0x84,
+ 0x86, 0x89, 0xa4, 0x86, 0x8e, 0xc4, 0x86, 0xfe, 0x93, 0xe4, 0x86, 0x98,
+ 0x04, 0x87, 0x9d, 0x24, 0x87, 0xa2, 0x44, 0x87, 0xa7, 0x64, 0xc6, 0x67,
+ 0x8c, 0xc6, 0x59, 0xa4, 0xc6, 0x5e, 0xc4, 0xc6, 0x63, 0xe4, 0xc6, 0x68,
+ 0x04, 0xc7, 0x6d, 0x24, 0xc7, 0x72, 0x44, 0xc7, 0x77, 0x64, 0xc7, 0x7c,
+ 0x84, 0xc7, 0x81, 0xa4, 0xc7, 0x86, 0xc4, 0xc7, 0x8b, 0xe4, 0xc7, 0x90,
+ 0x04, 0xc8, 0x95, 0x24, 0xc8, 0x9a, 0x44, 0xc8, 0x9f, 0x64, 0xc8, 0xa4,
+ 0x84, 0xc8, 0xa5, 0xa4, 0xc8, 0x54, 0xc4, 0xc8, 0x21, 0xe8, 0xc8, 0x24,
+ 0x08, 0xc9, 0x27, 0x28, 0xc9, 0x2a, 0x48, 0xc9, 0x2d, 0x68, 0xc9, 0x30,
+ 0x88, 0xc9, 0x33, 0xa8, 0xc9, 0x36, 0xc8, 0xc9, 0x39, 0xe8, 0xc9, 0x3c,
+ 0x08, 0xca, 0x3f, 0x28, 0xca, 0x42, 0x48, 0xca, 0x45, 0x68, 0xca, 0x48,
+ 0x88, 0xca, 0x4b, 0xa8, 0xca, 0x4e, 0xc8, 0xca, 0x8f, 0x60, 0x87, 0xac,
+ 0x84, 0x87, 0xb1, 0xa4, 0x87, 0xb6, 0xc4, 0x87, 0xbb, 0xe4, 0x87, 0xc0,
+ 0x04, 0x88, 0xc5, 0x24, 0x88, 0xca, 0x44, 0x88, 0xcf, 0x64, 0x88, 0xd4,
+ 0x84, 0x88, 0xd9, 0xa4, 0x88, 0xde, 0xc4, 0x88, 0xe3, 0xe4, 0x88, 0xe8,
+ 0x04, 0x89, 0xed, 0x24, 0x89, 0xf2, 0x44, 0x89, 0xf7, 0x64, 0x89, 0xfc,
+ 0x84, 0x89, 0x01, 0x25, 0xcd, 0xab, 0x44, 0xcd, 0xb0, 0x64, 0xcd, 0xb5,
+ 0x84, 0xcd, 0xba, 0xa4, 0xcd, 0xbf, 0xc4, 0xcd, 0xc4, 0xe4, 0xcd, 0xc9,
+ 0x04, 0xce, 0xce, 0x24, 0xce, 0xd3, 0x44, 0xce, 0xd8, 0x64, 0xce, 0xdd,
+ 0x84, 0xce, 0xe2, 0xa4, 0xce, 0xe7, 0xc4, 0xce, 0xec, 0xe4, 0xce, 0xf1,
+ 0x04, 0xcf, 0xf6, 0x24, 0xcf, 0xfb, 0x44, 0xcf, 0x00, 0x65, 0xcf, 0xae,
+ 0x84, 0xcf, 0x09, 0xa5, 0xcf, 0x0c, 0xc5, 0xcf, 0x0f, 0xe5, 0xcf, 0x12,
+ 0x05, 0xd0, 0x15, 0x25, 0xd0, 0x18, 0x45, 0xd0, 0x1b, 0x65, 0xfe, 0xd0,
+ 0x1e, 0x85, 0xd0, 0x21, 0xa5, 0xd0, 0x24, 0xc5, 0xd0, 0x27, 0xe5, 0xd0,
+ 0x2a, 0x05, 0xd1, 0x2d, 0x25, 0xd1, 0x30, 0x45, 0xd1, 0x33, 0x65, 0xd1,
+ 0x36, 0x85, 0xd1, 0x39, 0x05, 0x8d, 0x3b, 0x25, 0x8d, 0x41, 0x45, 0x8d,
+ 0x46, 0x65, 0x8d, 0x4b, 0x85, 0x8d, 0x50, 0xa5, 0x8d, 0x55, 0xc5, 0x8d,
+ 0x5a, 0xe5, 0x8d, 0x5f, 0x05, 0x8e, 0x64, 0x25, 0x8e, 0x69, 0x45, 0x8e,
+ 0x6e, 0x65, 0x8e, 0x73, 0x85, 0x8e, 0x78, 0xa5, 0x8e, 0x7d, 0xc5, 0x8e,
+ 0x82, 0xe5, 0x8e, 0x87, 0x05, 0x8f, 0x8c, 0x25, 0x8f, 0x91, 0xe5, 0xd3,
+ 0x3f, 0x0d, 0xd4, 0x43, 0x25, 0xd4, 0x48, 0x45, 0xd4, 0x4d, 0x65, 0xd4,
+ 0x52, 0x85, 0xd4, 0x57, 0xa5, 0xd4, 0x5c, 0xc5, 0xd4, 0x61, 0xe5, 0xd4,
+ 0x66, 0x05, 0xd5, 0x6b, 0x25, 0xd5, 0x70, 0x45, 0xd5, 0x75, 0x65, 0xd5,
+ 0x7a, 0x85, 0xd5, 0x7f, 0xa5, 0xd5, 0x84, 0xc5, 0xd5, 0x89, 0xe5, 0xd5,
+ 0x8e, 0x05, 0xd6, 0x8f, 0x25, 0xd6, 0x3e, 0x45, 0xd6, 0x9f, 0x68, 0xd6,
+ 0xa2, 0x88, 0xd6, 0xa5, 0xa8, 0xd6, 0xa8, 0xc8, 0xd6, 0xab, 0xe8, 0xd6,
+ 0xae, 0x08, 0xd7, 0xb1, 0x28, 0xd7, 0xb4, 0x48, 0xd7, 0xb7, 0x68, 0xd7,
+ 0xba, 0x88, 0xd7, 0xbd, 0xa8, 0xd7, 0xc0, 0xc8, 0xd7, 0xc3, 0xe8, 0xd7,
+ 0xc6, 0x08, 0xd8, 0xc9, 0x28, 0xd8, 0xcc, 0x48, 0xd8, 0xb3, 0x40, 0x8f,
+ 0x96, 0x65, 0x8f, 0x9b, 0x85, 0x8f, 0xa0, 0xa5, 0x8f, 0xa5, 0xc5, 0x8f,
+ 0xaa, 0xe5, 0x8f, 0xaf, 0x05, 0x90, 0xb4, 0x25, 0x90, 0xb9, 0x45, 0x90,
+ 0xbe, 0x65, 0x90, 0xc3, 0x85, 0x90, 0xc8, 0xa5, 0x90, 0xcd, 0xc5, 0x90,
+ 0xd2, 0xe5, 0x90, 0xd7, 0x05, 0x91, 0xdc, 0x25, 0x91, 0xe1, 0x45, 0x91,
+ 0xe6, 0x65, 0x91, 0xeb, 0xa5, 0xda, 0x95, 0xc5, 0xda, 0x9a, 0xe5, 0xda,
+ 0x9f, 0xfe, 0x05, 0xdb, 0xa4, 0x25, 0xdb, 0xa9, 0x45, 0xdb, 0xae, 0x65,
+ 0xdb, 0xb3, 0x85, 0xdb, 0xb8, 0xa5, 0xdb, 0xbd, 0xc5, 0xdb, 0xc2, 0xe5,
+ 0xdb, 0xc7, 0x05, 0xdc, 0xcc, 0x25, 0xdc, 0xd1, 0x45, 0xdc, 0xd6, 0x65,
+ 0xdc, 0xdb, 0x85, 0xdc, 0xe0, 0xa5, 0xdc, 0xe5, 0xc5, 0xdc, 0xea, 0xe5,
+ 0xdc, 0x98, 0x05, 0xdd, 0xf3, 0x25, 0xdd, 0xf6, 0x45, 0xdd, 0xf9, 0x65,
+ 0xdd, 0xfc, 0x85, 0xdd, 0xff, 0xa5, 0xdd, 0x02, 0xc6, 0xdd, 0x05, 0xe6,
+ 0xdd, 0x08, 0x06, 0xde, 0x0b, 0x26, 0xde, 0x0e, 0x46, 0xde, 0x11, 0x66,
+ 0xde, 0x14, 0x86, 0xde, 0x17, 0xa6, 0xde, 0x1a, 0xc6, 0xde, 0x1d, 0xe6,
+ 0xde, 0x20, 0x06, 0xdf, 0x23, 0xe6, 0x94, 0x25, 0x06, 0x95, 0x2b, 0x26,
+ 0x95, 0x30, 0x46, 0x95, 0x35, 0x66, 0x95, 0x3a, 0x86, 0x95, 0x3f, 0xa6,
+ 0x95, 0x44, 0xc6, 0x95, 0x49, 0xe6, 0x95, 0x4e, 0x06, 0x96, 0x53, 0x26,
+ 0x96, 0x58, 0x46, 0x96, 0x5d, 0x66, 0x96, 0x62, 0x86, 0x96, 0x67, 0xa6,
+ 0x96, 0x6c, 0xc6, 0x96, 0x71, 0xe6, 0x96, 0x76, 0x06, 0x97, 0x7b, 0x66,
+ 0xe1, 0x17, 0x8e, 0xe1, 0x2d, 0xa6, 0xe1, 0x32, 0xc6, 0xe1, 0x37, 0xe6,
+ 0xe1, 0x3c, 0x06, 0xe2, 0x41, 0x26, 0xe2, 0x46, 0x46, 0xe2, 0x4b, 0x66,
+ 0xe2, 0x50, 0x86, 0xe2, 0x55, 0xa6, 0xe2, 0x5a, 0xc6, 0xe2, 0x5f, 0xe6,
+ 0xe2, 0x64, 0x06, 0xe3, 0x69, 0x26, 0xe3, 0x6e, 0x46, 0xe3, 0x73, 0x66,
+ 0xe3, 0x78, 0x86, 0xe3, 0x79, 0xa6, 0xe3, 0x28, 0xc6, 0xe3, 0x1d, 0xe9,
+ 0xe3, 0x20, 0x09, 0xe4, 0x23, 0x29, 0xe4, 0x26, 0x49, 0xe4, 0x29, 0x69,
+ 0xe4, 0x2c, 0x89, 0xe4, 0x2f, 0xa9, 0xe4, 0x32, 0xc9, 0xe4, 0x35, 0xe9,
+ 0xe4, 0x38, 0x09, 0xe5, 0x3b, 0x29, 0xe5, 0x3e, 0x49, 0xe5, 0x41, 0x69,
+ 0xe5, 0x44, 0x89, 0xe5, 0xfe, 0x47, 0xa9, 0xe5, 0x4a, 0xc9, 0xe5, 0xd7,
+ 0xa0, 0x9b, 0x5e, 0xc1, 0x9b, 0xbe, 0xf9, 0x9b, 0x9c, 0x29, 0x9c, 0xc3,
+ 0x09, 0x9a, 0xc6, 0x79, 0x9c, 0xa4, 0xa9, 0x9c, 0xcb, 0x89, 0x9a, 0xce,
+ 0xf9, 0x9c, 0xac, 0x29, 0x9d, 0xd3, 0x09, 0x9b, 0xd6, 0x79, 0x9d, 0xb4,
+ 0xa9, 0x9d, 0xdb, 0x89, 0x9b, 0x82, 0xce, 0x9b, 0xbd, 0xa9, 0x99, 0xc0,
+ 0x19, 0x9c, 0x9e, 0x49, 0x9c, 0xc5, 0x29, 0x9a, 0xc8, 0x99, 0x9c, 0xa6,
+ 0xc9, 0x9c, 0xcd, 0xa9, 0x9a, 0xd0, 0x19, 0x9d, 0xae, 0x49, 0x9d, 0xd5,
+ 0x29, 0x9b, 0xd8, 0x99, 0x9d, 0xb6, 0xc9, 0x9d, 0x11, 0xd0, 0xe9, 0x84,
+ 0xee, 0x9b, 0xa1, 0x8e, 0xe8, 0xa4, 0xbe, 0xe8, 0xa7, 0xee, 0xe8, 0xaa,
+ 0x1e, 0xe9, 0xad, 0x4e, 0xe9, 0xb0, 0x7e, 0xe9, 0xb3, 0xae, 0xe9, 0xb6,
+ 0x8e, 0xeb, 0x98, 0x59, 0xe8, 0xbb, 0x2e, 0x9c, 0xbd, 0x6e, 0x9c, 0xbf,
+ 0xae, 0x9c, 0xc1, 0xee, 0x9c, 0xc3, 0x2e, 0x9d, 0xc5, 0x6e, 0x9d, 0xc7,
+ 0xae, 0x9d, 0xc9, 0xae, 0x9b, 0x9e, 0xce, 0xec, 0xc0, 0xc9, 0xeb, 0xc4,
+ 0xe9, 0xeb, 0xc8, 0x09, 0xec, 0xcc, 0x29, 0xec, 0xd0, 0x49, 0xec, 0xd4,
+ 0x69, 0xec, 0xd8, 0x89, 0xec, 0xdc, 0xa9, 0xec, 0x74, 0xe9, 0xed, 0x87,
+ 0xee, 0xec, 0xe1, 0x0e, 0xed, 0xe3, 0x2e, 0xed, 0xe5, 0x4e, 0xed, 0xe7,
+ 0x6e, 0xed, 0xe9, 0x8e, 0xed, 0xeb, 0xae, 0xed, 0xdc, 0x69, 0xa2, 0xa4,
+ 0x86, 0xa2, 0x2a, 0xba, 0xa2, 0x08, 0xea, 0xa2, 0x2f, 0xca, 0xa0, 0x32,
+ 0x3a, 0xa3, 0x10, 0x6a, 0xa3, 0x37, 0x4a, 0xa1, 0x3a, 0xba, 0xa3, 0x18,
+ 0xea, 0xa3, 0x3f, 0xca, 0xa1, 0x42, 0x3a, 0xa4, 0x20, 0x6a, 0xa4, 0x47,
+ 0x4a, 0xa2, 0x00, 0x8f, 0xa2, 0x29, 0x6a, 0xa0, 0x2c, 0xda, 0xa2, 0x0a,
+ 0x0a, 0xa3, 0x31, 0xea, 0xa0, 0x34, 0x5a, 0xfe, 0xa3, 0x12, 0x8a, 0xa3,
+ 0x39, 0x6a, 0xa1, 0x3c, 0xda, 0xa3, 0x1a, 0x0a, 0xa4, 0x41, 0xea, 0xa1,
+ 0x44, 0x5a, 0xa4, 0x22, 0x8a, 0xa4, 0xd7, 0x66, 0xa2, 0x1c, 0x3f, 0xf0,
+ 0x1f, 0x6f, 0xf0, 0x22, 0x9f, 0xf0, 0x25, 0xcf, 0xf0, 0x28, 0xff, 0xf0,
+ 0x2b, 0x2f, 0xf1, 0x2e, 0x5f, 0xf1, 0x31, 0x8f, 0xf1, 0x34, 0xbf, 0xf1,
+ 0x02, 0xaf, 0xa2, 0x39, 0xef, 0xa2, 0x3b, 0x2f, 0xa3, 0x3d, 0x6f, 0xa3,
+ 0x3f, 0xaf, 0xa3, 0x41, 0xef, 0xa3, 0x43, 0x2f, 0xa4, 0x45, 0x6f, 0xa4,
+ 0x47, 0x6f, 0xf3, 0x49, 0xef, 0xf1, 0x2c, 0xaa, 0xf3, 0x30, 0xca, 0xf3,
+ 0x34, 0xea, 0xf3, 0x38, 0x0a, 0xf4, 0x3c, 0x2a, 0xf4, 0x40, 0x4a, 0xf4,
+ 0x44, 0x6a, 0xf4, 0x48, 0x8a, 0xf4, 0x04, 0x8a, 0xf3, 0x5d, 0xcf, 0xf4,
+ 0x5f, 0xef, 0xf4, 0x61, 0x0f, 0xf5, 0x63, 0x2f, 0xf5, 0x65, 0x4f, 0xf5,
+ 0x67, 0x6f, 0xf5, 0x69, 0x8f, 0xf5, 0x48, 0x2a, 0xa9, 0x48, 0x42, 0xa9,
+ 0x96, 0x7a, 0xa9, 0x74, 0xaa, 0xa9, 0x9b, 0x8a, 0xa7, 0x9e, 0xfa, 0xa9,
+ 0x7c, 0x2a, 0xaa, 0xa3, 0x0a, 0xa8, 0xa6, 0x7a, 0xaa, 0x84, 0xaa, 0xaa,
+ 0xab, 0x8a, 0xa8, 0xae, 0xfa, 0xaa, 0x8c, 0x2a, 0xab, 0xb3, 0x0a, 0xa9,
+ 0x7e, 0x4f, 0xa9, 0x95, 0x2a, 0xa7, 0x98, 0x9a, 0xa9, 0x76, 0xca, 0xa9,
+ 0x9d, 0xaa, 0xa7, 0xa0, 0x1a, 0xaa, 0x7e, 0x4a, 0xaa, 0xa5, 0x2a, 0xa8,
+ 0xa8, 0x9a, 0xaa, 0x86, 0xca, 0xaa, 0xad, 0xaa, 0xa8, 0xb0, 0x1a, 0xab,
+ 0x8e, 0x4a, 0xab, 0x35, 0x90, 0xf9, 0x80, 0x6f, 0xa9, 0x9d, 0x4f, 0xf8,
+ 0xa0, 0x7f, 0xf8, 0xa3, 0xaf, 0xf8, 0xa6, 0xdf, 0xf8, 0xa9, 0x0f, 0xf9,
+ 0xac, 0x3f, 0xf9, 0xaf, 0x6f, 0xf9, 0xb2, 0x4f, 0xfb, 0x70, 0x1a, 0xf8,
+ 0xb7, 0xaf, 0xa9, 0xb9, 0xef, 0xa9, 0xbb, 0x2f, 0xaa, 0xbd, 0xfe, 0x6f,
+ 0xaa, 0xbf, 0xaf, 0xaa, 0xc1, 0xef, 0xaa, 0xc3, 0x2f, 0xab, 0xc5, 0x2f,
+ 0xa9, 0x9a, 0x8f, 0xfc, 0x98, 0x8a, 0xfb, 0x9c, 0xaa, 0xfb, 0xa0, 0xca,
+ 0xfb, 0xa4, 0xea, 0xfb, 0xa8, 0x0a, 0xfc, 0xac, 0x2a, 0xfc, 0xb0, 0x4a,
+ 0xfc, 0xb4, 0x6a, 0xfc, 0x4c, 0xaa, 0xfd, 0x83, 0xaf, 0xfc, 0xdd, 0xcf,
+ 0xfc, 0xdf, 0xef, 0xfc, 0xe1, 0x0f, 0xfd, 0xe3, 0x2f, 0xfd, 0xe5, 0x4f,
+ 0xfd, 0xe7, 0x6f, 0xfd, 0xb4, 0xea, 0xaf, 0x22, 0x07, 0xb0, 0x02, 0x3b,
+ 0xb0, 0x00, 0x91, 0x43, 0xe0, 0x40, 0x82, 0x3a, 0x0c, 0x1e, 0x44, 0x68,
+ 0x70, 0xc7, 0x42, 0x86, 0x0d, 0x17, 0xf2, 0x80, 0x18, 0x51, 0x22, 0xc4,
+ 0x1e, 0x15, 0x2d, 0x5e, 0xac, 0xe8, 0x43, 0xe3, 0x46, 0x8e, 0x1a, 0x7f,
+ 0x7c, 0x04, 0x19, 0xf2, 0x23, 0x10, 0x92, 0x25, 0x4d, 0x92, 0x0c, 0x92,
+ 0x52, 0xe5, 0xca, 0x94, 0x42, 0x5c, 0xbe, 0x84, 0xe9, 0x72, 0xc8, 0x4c,
+ 0x9a, 0x35, 0x67, 0x12, 0xc1, 0x99, 0x53, 0x27, 0xce, 0x22, 0x3d, 0x7d,
+ 0xfe, 0xec, 0x69, 0x44, 0xe8, 0x50, 0xa2, 0x42, 0x8f, 0x1c, 0x45, 0x9a,
+ 0xf4, 0xa8, 0x0d, 0xa6, 0x4d, 0x9d, 0x32, 0xbd, 0x11, 0x55, 0xea, 0xd4,
+ 0xa8, 0x38, 0xac, 0x5e, 0xc5, 0x6a, 0x95, 0xe0, 0xd6, 0x81, 0x09, 0xbd,
+ 0xea, 0x70, 0x18, 0x76, 0xc7, 0x44, 0xb2, 0x3c, 0x30, 0x9e, 0xed, 0xd1,
+ 0x51, 0xad, 0x0f, 0x91, 0x6d, 0x7f, 0x9c, 0x84, 0x0b, 0x84, 0xe5, 0xdc,
+ 0x20, 0x31, 0xed, 0x0a, 0xb1, 0x99, 0x77, 0xc8, 0x4e, 0xbe, 0x44, 0x80,
+ 0xfe, 0x2d, 0x52, 0x54, 0xb0, 0x11, 0xa5, 0x85, 0x8f, 0x3c, 0x45, 0x6c,
+ 0x83, 0xea, 0xe2, 0x1b, 0x59, 0x1d, 0xe3, 0xe0, 0xca, 0xf5, 0x6b, 0x42,
+ 0xb1, 0x0e, 0xcb, 0x4e, 0x44, 0x8b, 0x71, 0x6d, 0x47, 0xb7, 0x22, 0xe3,
+ 0x9e, 0xfe, 0xa4, 0xcb, 0xf2, 0x6e, 0x4c, 0xbd, 0x36, 0xfb, 0xee, 0x04,
+ 0x0c, 0x74, 0x70, 0x51, 0xc3, 0x4a, 0x13, 0x3f, 0x65, 0x4c, 0xf5, 0x71,
+ 0xd6, 0xc8, 0x5b, 0x27, 0x23, 0xac, 0xdc, 0xf0, 0xb2, 0xc4, 0xcc, 0x17,
+ 0x37, 0x73, 0xec, 0x1c, 0xf2, 0xb3, 0xc9, 0xd0, 0x2b, 0x47, 0xc3, 0x2c,
+ 0x5d, 0xf3, 0xb4, 0xce, 0xd4, 0x3f, 0x57, 0x13, 0x6d, 0x9d, 0xf4, 0xb5,
+ 0xd3, 0xd8, 0x53, 0x67, 0x63, 0xad, 0x5d, 0xf0, 0xb6, 0xc2, 0xdc, 0x0f,
+ 0x77, 0x53, 0xec, 0x9d, 0xf1, 0xb7, 0xc7, 0xe0, 0x23, 0x87, 0xa3, 0x2c,
+ 0xde, 0xf2, 0xb8, 0xcc, 0xe4, 0x37, 0x97, 0xf3, 0x6c, 0x1e, 0xf4, 0xb9,
+ 0xd1, 0xe8, 0x4b, 0xa7, 0x43, 0xad, 0x5e, 0xf5, 0xba, 0xd6, 0xec, 0x02,
+ 0xb7, 0x73, 0xef, 0xee, 0x3b, 0xf0, 0xc2, 0x1b, 0x8f, 0xbc, 0xf2, 0xce,
+ 0x43, 0x2f, 0xbd, 0xf5, 0xd8, 0x6b, 0xef, 0x3d, 0xf8, 0xe2, 0x9b, 0x8f,
+ 0xbe, 0xfa, 0x90, 0xa0, 0xb0, 0x42, 0x0b, 0x29, 0x4c, 0x22, 0x43, 0x0d,
+ 0x37, 0xcc, 0x50, 0x09, 0x0f, 0x3f, 0x04, 0xd1, 0xc3, 0x25, 0x46, 0x24,
+ 0xb1, 0xc4, 0x11, 0x99, 0x40, 0x31, 0x45, 0x15, 0x51, 0x6c, 0xa2, 0x45,
+ 0x17, 0x5f, 0x6c, 0xd1, 0x09, 0x19, 0x67, 0xa4, 0x51, 0xc6, 0x27, 0x6e,
+ 0xc4, 0x31, 0xc7, 0x1b, 0xa1, 0xe0, 0xb1, 0x47, 0x1f, 0x79, 0x8c, 0x22,
+ 0x48, 0x21, 0x87, 0x0c, 0x52, 0x0a, 0x23, 0x8f, 0x44, 0xd2, 0xc8, 0x29,
+ 0x96, 0x64, 0xb2, 0xc9, 0x25, 0xa9, 0x80, 0x32, 0x4a, 0x29, 0xa1, 0xac,
+ 0xa2, 0x4a, 0x2b, 0xaf, 0xac, 0xd2, 0x0a, 0x2d, 0xb7, 0xe4, 0x52, 0xcb,
+ 0x2b, 0xbe, 0x04, 0x33, 0xcc, 0x2f, 0xb1, 0x20, 0xb3, 0x4c, 0x33, 0xc9,
+ 0xcc, 0x22, 0x4d, 0x35, 0xd7, 0x4c, 0xf3, 0x42, 0x37, 0x91, 0xe0, 0x30,
+ 0xce, 0x24, 0x42, 0xa4, 0xfe, 0x53, 0x09, 0x13, 0xef, 0x5c, 0x62, 0x45,
+ 0x3d, 0x99, 0x80, 0xb1, 0xcf, 0x26, 0x6a, 0x04, 0xd4, 0x09, 0x1d, 0x07,
+ 0x7d, 0xe2, 0x47, 0x43, 0xa1, 0x20, 0x32, 0xd1, 0x28, 0x92, 0x64, 0x54,
+ 0x0a, 0x27, 0x1f, 0x9d, 0x62, 0x4a, 0x49, 0xa9, 0xc0, 0xb2, 0xd2, 0x2a,
+ 0xba, 0xc4, 0xd4, 0x0a, 0x31, 0x37, 0xbd, 0xe2, 0x4c, 0x4f, 0xb1, 0x60,
+ 0x33, 0xd4, 0x2c, 0xde, 0xbc, 0x50, 0x4e, 0x0e, 0xeb, 0x0c, 0x11, 0x4f,
+ 0x13, 0xf7, 0x5c, 0xd1, 0x4f, 0x18, 0x03, 0xad, 0x91, 0x50, 0x1d, 0x0f,
+ 0xfd, 0x51, 0x51, 0x22, 0x1b, 0x4d, 0x12, 0x52, 0x27, 0x27, 0x9d, 0xd2,
+ 0x52, 0x2c, 0x33, 0xed, 0x92, 0x53, 0x31, 0x3f, 0x3d, 0x53, 0x54, 0x36,
+ 0x49, 0xb5, 0xd0, 0xd4, 0x0d, 0x51, 0x05, 0x51, 0xd5, 0x12, 0x59, 0x55,
+ 0xd1, 0xd5, 0x17, 0x61, 0xa5, 0x51, 0xd6, 0x1c, 0x69, 0xf5, 0xd1, 0xd6,
+ 0x21, 0x71, 0x45, 0x52, 0xd7, 0x26, 0x79, 0x95, 0xd2, 0xd7, 0x2b, 0x81,
+ 0xe5, 0x52, 0xd8, 0x30, 0x89, 0x35, 0xd3, 0xd8, 0x35, 0x91, 0xad, 0x50,
+ 0x59, 0x0d, 0x99, 0xfd, 0xd0, 0x59, 0x12, 0xa1, 0x4d, 0x51, 0x5a, 0x17,
+ 0xa9, 0x9d, 0xd1, 0x5a, 0x1c, 0xb1, 0xed, 0x51, 0x5b, 0x21, 0xb9, 0x3d,
+ 0xd2, 0x5b, 0x26, 0xc1, 0x8d, 0x52, 0x5c, 0x2b, 0xc9, 0xdd, 0xd2, 0x5c,
+ 0x30, 0xd1, 0x2d, 0x53, 0x5d, 0x35, 0xd9, 0xc5, 0xd0, 0xdd, 0x39, 0xe1,
+ 0xb5, 0x53, 0xde, 0x3c, 0xe9, 0xe5, 0xd3, 0xde, 0x3f, 0xf1, 0x15, 0x54,
+ 0xdf, 0x42, 0xf9, 0x45, 0xd4, 0xdf, 0x45, 0x01, 0x76, 0x54, 0xe0, 0x48,
+ 0x09, 0xa6, 0xd4, 0xe0, 0x4b, 0x11, 0xd6, 0x54, 0xe1, 0x4e, 0x19, 0x06,
+ 0xd5, 0xe1, 0x2c, 0xb4, 0xa0, 0xb9, 0x66, 0x9b, 0x69, 0xde, 0x22, 0x67,
+ 0x9d, 0x77, 0xce, 0x99, 0x0b, 0x9f, 0x7f, 0xfe, 0x06, 0xda, 0xe7, 0x2e,
+ 0x86, 0x26, 0xba, 0xe8, 0xa1, 0xbd, 0x40, 0x3a, 0x69, 0xa5, 0x91, 0xfe,
+ 0xa2, 0x69, 0xa7, 0x9f, 0x6e, 0x1a, 0x0c, 0xa9, 0xa7, 0xa6, 0x5a, 0xea,
+ 0x30, 0xae, 0xc6, 0x3a, 0xeb, 0xab, 0xc5, 0xe0, 0xba, 0x6b, 0xaf, 0xb9,
+ 0x1e, 0x23, 0x6c, 0xb1, 0xc7, 0x0e, 0x9b, 0x0c, 0xb3, 0xcf, 0x46, 0xdb,
+ 0xec, 0x32, 0xd6, 0x66, 0xbb, 0xed, 0xb5, 0xcd, 0x80, 0x3b, 0x6e, 0xb9,
+ 0xe1, 0x3e, 0xa3, 0x6e, 0xbb, 0xef, 0xae, 0x1b, 0x0d, 0xbd, 0xf7, 0xe6,
+ 0x5b, 0xef, 0x34, 0xfe, 0x06, 0x3c, 0xf0, 0xbf, 0xd5, 0x20, 0xbc, 0x70,
+ 0xc3, 0x09, 0x5f, 0x23, 0x71, 0xc5, 0x17, 0x4f, 0xfc, 0x66, 0xc7, 0xb5,
+ 0xe0, 0x39, 0xf2, 0x2d, 0x82, 0xa6, 0x9c, 0x0b, 0xa3, 0x2f, 0xef, 0x62,
+ 0x69, 0xcd, 0xbd, 0x80, 0xba, 0xf3, 0x2f, 0xaa, 0x06, 0x1d, 0x0c, 0xad,
+ 0x47, 0x0f, 0xe3, 0x6b, 0xd3, 0xc5, 0x20, 0x3b, 0xf5, 0x31, 0xd2, 0x66,
+ 0x9d, 0x0c, 0xb7, 0x5f, 0x2f, 0x63, 0x6e, 0xd9, 0xcd, 0xc0, 0xbb, 0xf6,
+ 0x33, 0xfa, 0xc6, 0x1d, 0x0d, 0xc1, 0x77, 0x4f, 0xe3, 0x70, 0xdf, 0xd5,
+ 0x60, 0x3c, 0xf8, 0x35, 0x1e, 0xbf, 0x59, 0x72, 0x9e, 0x2b, 0x0f, 0x1a,
+ 0x73, 0xa3, 0x37, 0x5f, 0xda, 0x73, 0xa8, 0x43, 0xaf, 0x9a, 0x74, 0xad,
+ 0x4f, 0xff, 0x5a, 0x75, 0xb2, 0x5b, 0x4f, 0x1b, 0x76, 0xb7, 0x67, 0x9f,
+ 0xdb, 0x76, 0xbc, 0x73, 0xef, 0x9b, 0x77, 0xc1, 0x7f, 0x3f, 0x5c, 0x78,
+ 0xc6, 0x89, 0xb7, 0xd9, 0xf8, 0x9d, 0x91, 0x07, 0x5a, 0xf9, 0xa2, 0x99,
+ 0x57, 0xda, 0xf9, 0xa7, 0xa1, 0xa7, 0x5a, 0xfa, 0xac, 0xa9, 0xf7, 0xda,
+ 0xfa, 0xb1, 0xb1, 0x47, 0x5b, 0xfb, 0xb6, 0xb9, 0x97, 0x9b, 0xf7, 0xee,
+ 0x06, 0x3e, 0xbe, 0x89, 0x2f, 0x70, 0xe4, 0x33, 0x9c, 0xf9, 0xfe, 0x16,
+ 0x87, 0xbe, 0x9a, 0xa9, 0x4f, 0x67, 0xec, 0xfb, 0x99, 0xfb, 0x88, 0x06,
+ 0xbf, 0xa4, 0xc9, 0xcf, 0x69, 0xf4, 0x9b, 0x9a, 0xfd, 0xb0, 0x86, 0xbf,
+ 0xae, 0xe9, 0x4f, 0x6c, 0xfc, 0x3b, 0x9b, 0xff, 0xd8, 0x06, 0xc0, 0xb8,
+ 0x09, 0xd0, 0x6e, 0x04, 0xdc, 0x9b, 0x01, 0x01, 0x87, 0xc0, 0xc2, 0x29,
+ 0x50, 0x71, 0x0c, 0xc4, 0x99, 0x03, 0x27, 0x07, 0x41, 0xcb, 0x49, 0x30,
+ 0x73, 0x14, 0xe4, 0x9c, 0x05, 0x3f, 0x87, 0x41, 0xd1, 0x69, 0xb0, 0x74,
+ 0x1c, 0x44, 0x9d, 0x07, 0x57, 0x07, 0x42, 0xd7, 0x89, 0x30, 0x76, 0x24,
+ 0xa4, 0x9d, 0x09, 0x6f, 0x87, 0x42, 0xdd, 0xa9, 0xb0, 0x77, 0x2c, 0x04,
+ 0x9e, 0x0b, 0xd7, 0xc0, 0x06, 0x2a, 0x56, 0xd1, 0x8a, 0x54, 0x6c, 0x43,
+ 0x16, 0xb5, 0xb8, 0xc5, 0x2c, 0xba, 0xc1, 0x8b, 0x5f, 0x04, 0xa3, 0x17,
+ 0xdf, 0x30, 0x46, 0x32, 0x96, 0x71, 0x8c, 0x70, 0x40, 0x63, 0x1a, 0xd5,
+ 0x88, 0xc6, 0x38, 0xb4, 0xd1, 0x8d, 0x6f, 0x6c, 0xa3, 0x1c, 0xe4, 0x38,
+ 0x47, 0x3a, 0xca, 0x71, 0x0e, 0x77, 0xc4, 0x63, 0x1e, 0xef, 0x48, 0x07,
+ 0x3e, 0xf6, 0xd1, 0x8f, 0x7c, 0xac, 0x43, 0x20, 0x05, 0x39, 0xc8, 0x40,
+ 0xda, 0xc1, 0x90, 0x87, 0x44, 0xa4, 0x21, 0xef, 0xb0, 0x48, 0x46, 0x36,
+ 0x72, 0x91, 0x78, 0x80, 0x64, 0x24, 0x25, 0x09, 0xc9, 0x3c, 0x54, 0xd2,
+ 0x92, 0x97, 0xac, 0xa4, 0x1e, 0x34, 0xb9, 0x49, 0x4e, 0x6a, 0x72, 0x0f,
+ 0x9f, 0x04, 0x65, 0x28, 0x3f, 0xc9, 0x07, 0x52, 0x96, 0xd2, 0x94, 0xa4,
+ 0xec, 0x43, 0x2a, 0x55, 0xb9, 0xca, 0x54, 0x5e, 0xd1, 0x95, 0x6c, 0xe0,
+ 0x62, 0x2c, 0xdb, 0x10, 0x46, 0x5a, 0xba, 0xc1, 0x8c, 0xb7, 0x7c, 0xc3,
+ 0x1a, 0x75, 0x09, 0x07, 0x38, 0xf6, 0x32, 0x0e, 0x75, 0x04, 0xa6, 0x1c,
+ 0xf4, 0xfe, 0x38, 0xcc, 0x39, 0xfc, 0xd1, 0x98, 0x74, 0x20, 0x64, 0x32,
+ 0xeb, 0x90, 0x48, 0x66, 0xda, 0xc1, 0x91, 0xcf, 0xbc, 0xc3, 0x24, 0xa5,
+ 0x89, 0x07, 0x4c, 0x56, 0x33, 0x0f, 0x9d, 0xc4, 0xa6, 0x1e, 0x44, 0xb9,
+ 0xcd, 0x3d, 0x9c, 0xd2, 0x9b, 0x7c, 0x60, 0x65, 0x38, 0xfb, 0xf0, 0xca,
+ 0x2b, 0xca, 0x92, 0x8b, 0xb5, 0x0c, 0x23, 0x2e, 0xcd, 0xb8, 0xcb, 0x35,
+ 0xfa, 0x12, 0x8e, 0xc1, 0xac, 0x23, 0x31, 0xf5, 0x78, 0xcc, 0x3f, 0x2a,
+ 0x93, 0x90, 0xcd, 0x4c, 0x24, 0x34, 0x1d, 0x39, 0xcd, 0x49, 0x5a, 0x13,
+ 0x93, 0xd9, 0xec, 0x24, 0x37, 0x45, 0xf9, 0xcd, 0x53, 0x8a, 0x93, 0x95,
+ 0xe4, 0xb4, 0xa2, 0x39, 0xb7, 0x88, 0x4e, 0x30, 0xaa, 0xb3, 0x8c, 0xec,
+ 0x54, 0xa3, 0x3b, 0xdf, 0x08, 0x4f, 0x3a, 0xca, 0x33, 0x8f, 0xf4, 0xf4,
+ 0xa3, 0x3d, 0x07, 0x89, 0x4f, 0x44, 0xea, 0xb3, 0x91, 0xfc, 0x94, 0xa4,
+ 0x3f, 0x2f, 0x09, 0x50, 0x4e, 0x0a, 0x34, 0x94, 0x04, 0x35, 0xa5, 0x41,
+ 0x57, 0x89, 0xd0, 0x2a, 0x2a, 0x54, 0x8b, 0x0c, 0xfd, 0xa2, 0x43, 0xc9,
+ 0x08, 0xd1, 0x34, 0x4a, 0xd4, 0x8d, 0x14, 0x9d, 0xa3, 0x45, 0xf1, 0x88,
+ 0xd1, 0x3e, 0x6a, 0x54, 0x90, 0x1c, 0x3d, 0xa4, 0x47, 0x19, 0x09, 0xd2,
+ 0x48, 0x8a, 0xd4, 0x92, 0x24, 0xdd, 0xa4, 0x49, 0x41, 0x89, 0xd2, 0x52,
+ 0xaa, 0x54, 0x95, 0x2c, 0xc5, 0xa2, 0x4b, 0x67, 0x09, 0x53, 0x5b, 0xca,
+ 0x34, 0x97, 0x34, 0xe5, 0xa5, 0x4d, 0x7f, 0x89, 0x53, 0x61, 0xea, 0xb4,
+ 0x98, 0x3c, 0x45, 0xa6, 0x4f, 0x97, 0x09, 0x54, 0x67, 0x0a, 0x35, 0x9a,
+ 0x44, 0xa5, 0xa6, 0x51, 0xaf, 0x89, 0x54, 0x6d, 0x2a, 0xb5, 0x9b, 0x4c,
+ 0x05, 0xa7, 0x53, 0xfb, 0xe0, 0x07, 0xba, 0xd6, 0xd5, 0xae, 0x74, 0xfd,
+ 0x43, 0x5e, 0xf5, 0xba, 0xfe, 0xd7, 0xbc, 0x02, 0xc2, 0xaf, 0x7f, 0x05,
+ 0xac, 0x5f, 0x03, 0x31, 0x58, 0xc2, 0x16, 0x76, 0xb0, 0x82, 0x40, 0x6c,
+ 0x62, 0x15, 0x8b, 0xd8, 0x41, 0x34, 0xd6, 0xb1, 0x8f, 0x6d, 0x2c, 0x21,
+ 0x24, 0x3b, 0x59, 0xca, 0x4a, 0xb6, 0x10, 0x97, 0xc5, 0x6c, 0x66, 0x2f,
+ 0x6b, 0x08, 0xce, 0x76, 0xd6, 0xb3, 0x9c, 0x3d, 0x44, 0x68, 0x45, 0x3b,
+ 0xda, 0xd0, 0x22, 0xc2, 0xb4, 0xa7, 0x45, 0xad, 0x69, 0x13, 0xb1, 0x5a,
+ 0xd6, 0xb6, 0x76, 0xb5, 0x8a, 0x80, 0x6d, 0x6c, 0x65, 0x0b, 0xdb, 0x45,
+ 0xd4, 0xd6, 0xb6, 0xb7, 0xad, 0x2d, 0x23, 0x74, 0xbb, 0x5b, 0xde, 0xea,
+ 0xb6, 0x11, 0xbf, 0x05, 0x6e, 0x70, 0x7f, 0xeb, 0x08, 0xe2, 0x16, 0xd7,
+ 0xb8, 0xc4, 0x7d, 0x44, 0x72, 0x95, 0xbb, 0xdc, 0xe4, 0xde, 0xd5, 0xb9,
+ 0x7e, 0xe0, 0x6b, 0x74, 0xff, 0x10, 0x58, 0xea, 0x02, 0xc2, 0xb0, 0xd7,
+ 0x0d, 0xc4, 0x62, 0xb5, 0x2b, 0x08, 0xc8, 0x76, 0x77, 0x10, 0x95, 0x05,
+ 0x2f, 0x21, 0x34, 0x3b, 0xde, 0x42, 0x7c, 0xd6, 0xbc, 0x86, 0x20, 0x6d,
+ 0x7a, 0x0f, 0x91, 0x5a, 0xf6, 0x22, 0xc2, 0xb5, 0xef, 0x4d, 0xc4, 0x6c,
+ 0xe5, 0xab, 0x08, 0xdc, 0xd6, 0x77, 0x11, 0xbd, 0xc5, 0x2f, 0x23, 0x84,
+ 0xbb, 0xdf, 0x46, 0x1c, 0xd7, 0xbf, 0x8e, 0x60, 0x6e, 0x80, 0x1f, 0xf1,
+ 0xdc, 0xbb, 0x4a, 0x97, 0xaf, 0xd5, 0x0d, 0x2c, 0x76, 0x0d, 0xbb, 0xdd,
+ 0xc5, 0x7a, 0x17, 0xb2, 0xe1, 0xad, 0x2c, 0x79, 0x35, 0x7b, 0xde, 0xcf,
+ 0xaa, 0x97, 0xb4, 0xed, 0x4d, 0x2d, 0x7c, 0x5d, 0x3b, 0xdf, 0xd9, 0xda,
+ 0x17, 0xb7, 0xf9, 0xed, 0x2d, 0x7f, 0x85, 0xfb, 0xdf, 0xe3, 0x0a, 0x98,
+ 0xb9, 0x04, 0xb6, 0xab, 0x81, 0xf7, 0x8a, 0x60, 0xc0, 0x2a, 0xb8, 0xb0,
+ 0x0c, 0x56, 0xac, 0x83, 0x1f, 0x0b, 0x61, 0xfe, 0xca, 0x4a, 0x38, 0xb3,
+ 0x14, 0xf6, 0xac, 0x85, 0x47, 0x8b, 0x61, 0xd4, 0x6a, 0xb8, 0xb5, 0x1c,
+ 0x96, 0xad, 0x87, 0x6f, 0x0b, 0x62, 0xde, 0x8a, 0x38, 0xb8, 0x24, 0x36,
+ 0xae, 0x89, 0x97, 0x8b, 0xe2, 0xba, 0xaa, 0x58, 0xaf, 0x2c, 0xfe, 0xab,
+ 0x8b, 0x09, 0x0b, 0xe3, 0xc4, 0xca, 0xd8, 0xb1, 0x34, 0x9e, 0xac, 0x8d,
+ 0x31, 0x8b, 0xe3, 0xce, 0xea, 0x58, 0xb4, 0x3c, 0x3e, 0xad, 0x8f, 0x59,
+ 0x0b, 0xe4, 0xd8, 0x0a, 0xd9, 0xb6, 0x44, 0xde, 0xad, 0x91, 0x81, 0x8b,
+ 0xe4, 0xe2, 0x2a, 0x59, 0xb9, 0x4c, 0xc6, 0xab, 0x93, 0xa7, 0x0b, 0x65,
+ 0xeb, 0x4a, 0x39, 0xbb, 0x54, 0xe6, 0xae, 0x95, 0xbf, 0x8b, 0x65, 0xf1,
+ 0x6a, 0xb9, 0xbc, 0x5c, 0x46, 0xaf, 0x97, 0xd7, 0x0b, 0x66, 0xf7, 0x8a,
+ 0x39, 0xbe, 0x64, 0xa6, 0xaf, 0x99, 0xef, 0x8b, 0x66, 0xfd, 0xaa, 0xb9,
+ 0xbf, 0x6c, 0x06, 0xb0, 0x9b, 0x1f, 0x01, 0x09, 0x4a, 0x57, 0xda, 0xd2,
+ 0x94, 0x8e, 0x44, 0xa6, 0x35, 0xbd, 0xe9, 0x4c, 0x4b, 0xc2, 0xd3, 0x9f,
+ 0x06, 0xb5, 0xa7, 0x27, 0x31, 0x6a, 0x52, 0x97, 0x7a, 0xd4, 0x94, 0x40,
+ 0x75, 0xaa, 0x55, 0x8d, 0xea, 0x4a, 0xb4, 0xda, 0xd5, 0xaf, 0x6e, 0xb5,
+ 0x25, 0x64, 0x3d, 0x6b, 0x5a, 0xcb, 0xfa, 0x12, 0xb7, 0xc6, 0x75, 0xae,
+ 0x6f, 0x8d, 0x09, 0x5e, 0xf7, 0xda, 0xd7, 0xbc, 0xce, 0x44, 0xb0, 0x85,
+ 0x3d, 0xec, 0x60, 0x6b, 0xc2, 0xd8, 0xc7, 0x46, 0xb6, 0xb1, 0x37, 0xb1,
+ 0x6c, 0x66, 0x37, 0x7b, 0xd9, 0x9c, 0x80, 0x76, 0xb4, 0xa5, 0x0d, 0xed,
+ 0x4e, 0x54, 0xdb, 0xda, 0xd7, 0xae, 0xb6, 0x27, 0xb4, 0xbd, 0x6d, 0x6e,
+ 0x6b, 0xfb, 0x13, 0xdf, 0x06, 0x77, 0xb8, 0xbf, 0x0d, 0x0a, 0x72, 0x97,
+ 0xdb, 0xdc, 0xe4, 0x0e, 0x45, 0xba, 0xd5, 0xbd, 0xee, 0x74, 0xfe, 0x5f,
+ 0xda, 0xdd, 0x90, 0xe0, 0x74, 0xbc, 0x23, 0x11, 0x6a, 0x7a, 0x4b, 0xc2,
+ 0xd4, 0xf7, 0x9e, 0xc4, 0xaa, 0xf5, 0x4d, 0x09, 0x58, 0xf7, 0xbb, 0x12,
+ 0xb5, 0x06, 0xb8, 0x25, 0x74, 0x3d, 0xf0, 0x4b, 0xfc, 0xda, 0xe0, 0x98,
+ 0x20, 0x76, 0xc2, 0x33, 0x91, 0x6c, 0x86, 0x6b, 0xc2, 0xd9, 0x0f, 0xdf,
+ 0xc4, 0xb4, 0x25, 0xce, 0x09, 0x6c, 0x57, 0xbc, 0x13, 0xdd, 0xc6, 0xb8,
+ 0x27, 0xc4, 0xbd, 0xf1, 0x4f, 0x9c, 0xdb, 0xe3, 0xa0, 0x60, 0x77, 0xc8,
+ 0x43, 0xf1, 0xee, 0x4b, 0xcb, 0x9b, 0xd3, 0xf5, 0x0e, 0x35, 0xbe, 0x4d,
+ 0xbd, 0xef, 0x55, 0xfb, 0x1b, 0xd6, 0x01, 0xaf, 0x35, 0xc1, 0x75, 0x7d,
+ 0xf0, 0x5f, 0x2b, 0x9c, 0xd8, 0x0d, 0x4f, 0x36, 0xc4, 0x9d, 0x3d, 0xf1,
+ 0x69, 0x5b, 0x1c, 0xdb, 0x19, 0xef, 0x36, 0xc7, 0xc5, 0xfd, 0xf1, 0x73,
+ 0x8b, 0x9c, 0xdd, 0x24, 0xb7, 0xb4, 0xc9, 0x37, 0x8d, 0x72, 0x50, 0xab,
+ 0xbc, 0xd4, 0x2c, 0x57, 0xb5, 0xcb, 0x5f, 0x0d, 0x73, 0x5a, 0xcb, 0x3c,
+ 0xd7, 0x34, 0xf7, 0xb5, 0xcd, 0x87, 0x8d, 0x73, 0x64, 0xeb, 0xbc, 0xd9,
+ 0x3c, 0x97, 0xb6, 0xcf, 0xaf, 0x0d, 0x74, 0x6e, 0x0b, 0x3d, 0xdc, 0x44,
+ 0x37, 0xb7, 0xd1, 0xd7, 0x8d, 0xf4, 0x4a, 0x2b, 0x5d, 0xd3, 0x4c, 0xff,
+ 0xb4, 0xd3, 0x49, 0x0d, 0xf5, 0x54, 0x4b, 0xdd, 0xd5, 0x54, 0x9f, 0xb5,
+ 0xd5, 0x71, 0x8d, 0xf5, 0x5e, 0x6b, 0x5d, 0xd8, 0x5c, 0x3f, 0xb6, 0xd7,
+ 0x99, 0x0d, 0xf6, 0x68, 0x8b, 0xdd, 0xda, 0x64, 0xdf, 0xb6, 0xd9, 0xc1,
+ 0x8d, 0xf6, 0x72, 0xab, 0x5d, 0xdd, 0x6c, 0xc7, 0xb4, 0xdb, 0xe7, 0x0d,
+ 0x77, 0x7b, 0xcb, 0x3d, 0xdf, 0x74, 0xe7, 0xb7, 0xdd, 0xff, 0x8d, 0x77,
+ 0x81, 0xeb, 0xbd, 0xe0, 0x7c, 0x47, 0xb8, 0xdf, 0x17, 0x0e, 0x78, 0x87,
+ 0x0b, 0xfe, 0x3e, 0xe2, 0x84, 0xa7, 0xb8, 0xe1, 0x2f, 0x8e, 0x78, 0x8d,
+ 0x2b, 0xbe, 0xe3, 0x8c, 0x07, 0xb9, 0xe3, 0x43, 0x21, 0x0a, 0xda, 0xd7,
+ 0xde, 0xf6, 0xb4, 0x1f, 0x45, 0xee, 0x75, 0xbf, 0xfb, 0xdc, 0x93, 0xc2,
+ 0xf7, 0xbf, 0x07, 0xbe, 0xef, 0x4b, 0x31, 0x7c, 0xe2, 0x17, 0x7f, 0xf8,
+ 0xa6, 0x40, 0x7e, 0xf2, 0x95, 0x8f, 0xfc, 0x53, 0x34, 0xdf, 0xf9, 0xcf,
+ 0x6f, 0x3e, 0x2a, 0xa4, 0x3f, 0x7d, 0xea, 0x4b, 0x3f, 0x15, 0xd7, 0xc7,
+ 0x7e, 0xf6, 0xaf, 0xaf, 0x0a, 0xee, 0x77, 0xdf, 0xfb, 0xdc, 0x5f, 0x45,
+ 0xf8, 0xc5, 0x3f, 0xfe, 0xf0, 0xb3, 0xc2, 0xfc, 0xe7, 0x47, 0xbf, 0xf9,
+ 0x5b, 0xb1, 0x7e, 0xf6, 0xb7, 0x7f, 0xfd, 0xae, 0x80, 0x7f, 0xfc, 0xe5,
+ 0x0f, 0xff, 0x57, 0xd4, 0xdf, 0xfe, 0xf7, 0xaf, 0x3f, 0x2c, 0xf4, 0xbf,
+ 0x7f, 0xfe, 0xeb, 0x3f, 0x16, 0xff, 0x07, 0xc0, 0x00, 0xfc, 0x3f, 0x59,
+ 0x20, 0xc0, 0x02, 0x34, 0x40, 0x02, 0x9c, 0x85, 0x04, 0x54, 0xc0, 0x05,
+ 0x4c, 0xc0, 0xdb, 0x73, 0x40, 0x51, 0xe0, 0xbd, 0x08, 0x1c, 0x85, 0xe0,
+ 0xa3, 0x40, 0x52, 0x30, 0xbe, 0x0b, 0x2c, 0x85, 0xe5, 0xd3, 0x40, 0x53,
+ 0x80, 0xbe, 0x0e, 0x3c, 0x85, 0xea, 0x03, 0x41, 0x54, 0xd0, 0xbe, 0x11,
+ 0x4c, 0x85, 0xef, 0x33, 0x41, 0x55, 0x20, 0xbf, 0x14, 0x5c, 0x85, 0xf4,
+ 0x63, 0x41, 0x56, 0x70, 0xbf, 0x17, 0x6c, 0x85, 0xf9, 0x93, 0x41, 0x57,
+ 0xc0, 0xbf, 0x1a, 0x7c, 0x85, 0xfe, 0xc3, 0x41, 0x58, 0x10, 0xc0, 0x1d,
+ 0x8c, 0x85, 0x03, 0xf4, 0x41, 0x59, 0x60, 0xc0, 0x20, 0x9c, 0x85, 0x07,
+ 0xbc, 0x3d, 0x09, 0xe4, 0xbd, 0x0a, 0x0c, 0x3e, 0x0c, 0x34, 0xbe, 0x0d,
+ 0x5c, 0x3e, 0x0f, 0x84, 0xbe, 0x10, 0xac, 0x3e, 0x12, 0xd4, 0xbe, 0x13,
+ 0xfc, 0x3e, 0x15, 0x24, 0xfe, 0xbf, 0x16, 0x4c, 0x3f, 0x18, 0x74, 0xbf,
+ 0x19, 0x9c, 0x3f, 0x1b, 0xc4, 0xbf, 0x1c, 0xec, 0x3f, 0x1e, 0x14, 0xc0,
+ 0x1f, 0x3c, 0x40, 0x21, 0x64, 0x40, 0x22, 0xb4, 0x3d, 0x23, 0xdc, 0x3d,
+ 0x24, 0x04, 0x3e, 0x25, 0x2c, 0x3e, 0x26, 0x54, 0x3e, 0x27, 0x7c, 0x3e,
+ 0x28, 0xa4, 0x3e, 0x29, 0xcc, 0x3e, 0x2a, 0xf4, 0x3e, 0x2b, 0x1c, 0x3f,
+ 0x2c, 0x44, 0x3f, 0x2d, 0x6c, 0x3f, 0x2e, 0x94, 0x3f, 0x2f, 0xbc, 0x3f,
+ 0x30, 0xe4, 0x3f, 0x31, 0x0c, 0x40, 0x32, 0x34, 0x40, 0x33, 0x5c, 0x40,
+ 0x34, 0xac, 0x3d, 0x35, 0xd4, 0x3d, 0x36, 0xfc, 0x3d, 0x37, 0x24, 0x3e,
+ 0x38, 0x4c, 0x3e, 0x39, 0x74, 0x3e, 0x3a, 0x9c, 0x3e, 0x3b, 0xc4, 0x3e,
+ 0x3c, 0xec, 0x3e, 0x3d, 0x14, 0x3f, 0x3e, 0x3c, 0x3f, 0x3f, 0x64, 0x3f,
+ 0x40, 0x8c, 0x3f, 0x41, 0xb4, 0x3f, 0x42, 0xdc, 0x3f, 0x43, 0x04, 0x40,
+ 0x44, 0x2c, 0x40, 0x45, 0x54, 0x40, 0x46, 0xc4, 0x3d, 0x47, 0x9c, 0x40,
+ 0x48, 0xb4, 0x40, 0x49, 0xcc, 0x40, 0x4a, 0xe4, 0x40, 0x4b, 0xfc, 0x40,
+ 0x4c, 0x14, 0x41, 0x4d, 0x2c, 0x41, 0x4e, 0x44, 0x41, 0x4f, 0x5c, 0x41,
+ 0x50, 0x74, 0x41, 0x51, 0x8c, 0x41, 0x52, 0xa4, 0x41, 0x53, 0xbc, 0x41,
+ 0x54, 0xd4, 0x41, 0x55, 0xec, 0x41, 0x56, 0x04, 0x42, 0x57, 0x9c, 0x05,
+ 0x5a, 0xa0, 0xc6, 0x6a, 0xb4, 0x46, 0x6a, 0xac, 0x85, 0x6c, 0xd4, 0xc6,
+ 0x6d, 0xcc, 0x46, 0x5b, 0xf0, 0xc6, 0x6f, 0x04, 0x47, 0x6f, 0xbc, 0x85,
+ 0x71, 0x24, 0xc7, 0x72, 0x1c, 0x47, 0x5c, 0x40, 0xc7, 0x74, 0x54, 0x47,
+ 0x74, 0xcc, 0x85, 0x76, 0x74, 0xc7, 0x77, 0x6c, 0x47, 0x5d, 0x90, 0xc7,
+ 0x79, 0xa4, 0x47, 0x79, 0xdc, 0x85, 0x7b, 0xc4, 0xc7, 0x7c, 0xbc, 0x47,
+ 0x5e, 0xe0, 0xc7, 0x7e, 0xf4, 0x47, 0x7e, 0xfe, 0xec, 0x85, 0x80, 0x14,
+ 0xc8, 0x81, 0x0c, 0x48, 0x5f, 0x30, 0xc8, 0x83, 0x44, 0x48, 0x83, 0xfc,
+ 0x85, 0x85, 0x64, 0xc8, 0x86, 0x5c, 0x48, 0x60, 0x80, 0xc8, 0x88, 0x94,
+ 0x48, 0x88, 0x0c, 0x86, 0x8a, 0xb4, 0xc8, 0x8b, 0xac, 0x48, 0x61, 0xd0,
+ 0xc8, 0x8d, 0xe4, 0x48, 0x8d, 0x1c, 0x86, 0x8f, 0x04, 0xc9, 0x90, 0xfc,
+ 0x48, 0x62, 0x20, 0xc9, 0x92, 0x34, 0x49, 0x92, 0x2c, 0x86, 0x94, 0x54,
+ 0xc9, 0x95, 0x4c, 0xc9, 0x6b, 0x74, 0x49, 0x5a, 0xe0, 0xc6, 0x98, 0xac,
+ 0x85, 0x70, 0xa4, 0x49, 0x5b, 0x30, 0xc7, 0x9b, 0xbc, 0x85, 0x75, 0xd4,
+ 0x49, 0x5c, 0x80, 0xc7, 0x9e, 0xcc, 0x85, 0x7a, 0x04, 0x4a, 0x5d, 0xd0,
+ 0xc7, 0xa1, 0xdc, 0x85, 0x7f, 0x34, 0x4a, 0x5e, 0x20, 0xc8, 0xa4, 0xec,
+ 0x85, 0x84, 0x64, 0x4a, 0x5f, 0x70, 0xc8, 0xa7, 0xfc, 0x85, 0x89, 0x94,
+ 0x4a, 0x60, 0xc0, 0xc8, 0xaa, 0x0c, 0x86, 0x8e, 0xc4, 0x4a, 0x61, 0x10,
+ 0xc9, 0xad, 0x1c, 0x86, 0x93, 0xf4, 0x4a, 0x62, 0x60, 0xc9, 0xb0, 0x2c,
+ 0x86, 0x97, 0xbc, 0x46, 0x99, 0xe4, 0xc6, 0x9a, 0x0c, 0x47, 0x9c, 0x34,
+ 0xc7, 0x9d, 0x5c, 0x47, 0x9f, 0x84, 0xc7, 0xa0, 0xac, 0x47, 0xa2, 0xd4,
+ 0xc7, 0xa3, 0xfc, 0x47, 0xa5, 0x24, 0xc8, 0xa6, 0x4c, 0x48, 0xa8, 0x74,
+ 0xc8, 0xa9, 0x9c, 0x48, 0xab, 0xc4, 0xc8, 0xac, 0xec, 0x48, 0xae, 0x14,
+ 0xc9, 0xaf, 0x3c, 0x49, 0xb1, 0x64, 0x49, 0xb2, 0xb4, 0x46, 0xb3, 0xdc,
+ 0x46, 0xb4, 0x04, 0x47, 0xb5, 0x2c, 0x47, 0xb6, 0x54, 0x47, 0xb7, 0x7c,
+ 0x47, 0xb8, 0xa4, 0x47, 0xb9, 0xcc, 0x47, 0xba, 0xf4, 0x47, 0xbb, 0x1c,
+ 0x48, 0xbc, 0x44, 0x48, 0xbd, 0x6c, 0x48, 0xbe, 0x94, 0x48, 0xbf, 0xbc,
+ 0x48, 0xc0, 0xe4, 0x48, 0xc1, 0x0c, 0x49, 0xc2, 0x34, 0x49, 0xfe, 0xc3,
+ 0x5c, 0x49, 0xc4, 0xac, 0x46, 0xc5, 0xd4, 0x46, 0xc6, 0xfc, 0x46, 0xc7,
+ 0x24, 0x47, 0xc8, 0x4c, 0x47, 0xc9, 0x74, 0x47, 0xca, 0x9c, 0x47, 0xcb,
+ 0xc4, 0x47, 0xcc, 0xec, 0x47, 0xcd, 0x14, 0x48, 0xce, 0x3c, 0x48, 0xcf,
+ 0x64, 0x48, 0xd0, 0x8c, 0x48, 0xd1, 0xb4, 0x48, 0xd2, 0xdc, 0x48, 0xd3,
+ 0x04, 0x49, 0xd4, 0x2c, 0x49, 0xd5, 0x54, 0x49, 0xd6, 0xc4, 0x46, 0xd7,
+ 0x9c, 0x49, 0xd8, 0xb4, 0x49, 0xd9, 0xcc, 0x49, 0xda, 0xe4, 0x49, 0xdb,
+ 0xfc, 0x49, 0xdc, 0x14, 0x4a, 0xdd, 0x2c, 0x4a, 0xde, 0x44, 0x4a, 0xdf,
+ 0x5c, 0x4a, 0xe0, 0x74, 0x4a, 0xe1, 0x8c, 0x4a, 0xe2, 0xa4, 0x4a, 0xe3,
+ 0xbc, 0x4a, 0xe4, 0xd4, 0x4a, 0xe5, 0xec, 0x4a, 0xe6, 0x04, 0x4b, 0xe7,
+ 0x2c, 0x06, 0x63, 0xa0, 0xcf, 0xfa, 0xb4, 0x4f, 0xfa, 0x3c, 0x86, 0xfc,
+ 0xd4, 0xcf, 0xfd, 0xcc, 0x4f, 0x64, 0xf0, 0xcf, 0xff, 0x04, 0x50, 0xff,
+ 0x4c, 0x86, 0x01, 0x25, 0xd0, 0x02, 0x1d, 0x50, 0x65, 0x40, 0xd0, 0x04,
+ 0x55, 0x50, 0x04, 0x5d, 0x86, 0x06, 0x75, 0xd0, 0x07, 0x6d, 0x50, 0x66,
+ 0x90, 0xd0, 0x09, 0xa5, 0x50, 0x09, 0x6d, 0x86, 0x0b, 0xc5, 0xd0, 0x0c,
+ 0xbd, 0x50, 0x67, 0xe0, 0xd0, 0x0e, 0xf5, 0x50, 0x0e, 0x7d, 0x86, 0x10,
+ 0x15, 0xd1, 0x11, 0x0d, 0x51, 0x68, 0x30, 0xd1, 0x13, 0x45, 0x51, 0x13,
+ 0x8d, 0x86, 0x15, 0x65, 0xd1, 0x16, 0x5d, 0x51, 0x69, 0x80, 0xd1, 0x18,
+ 0x95, 0x51, 0x18, 0x9d, 0x86, 0x1a, 0xb5, 0xd1, 0x1b, 0xad, 0x51, 0x6a,
+ 0xd0, 0xd1, 0x1d, 0xe5, 0x51, 0x1d, 0xad, 0x86, 0x1f, 0x05, 0xd2, 0x20,
+ 0xfd, 0x51, 0x6b, 0x20, 0xd2, 0x22, 0x35, 0x52, 0x22, 0xbd, 0x86, 0x24,
+ 0x55, 0xd2, 0x25, 0x4d, 0xd2, 0xfb, 0x74, 0x52, 0x63, 0xe0, 0xcf, 0x28,
+ 0x3d, 0xfe, 0x86, 0x00, 0xa5, 0x52, 0x64, 0x30, 0xd0, 0x2b, 0x4d, 0x86,
+ 0x05, 0xd5, 0x52, 0x65, 0x80, 0xd0, 0x2e, 0x5d, 0x86, 0x0a, 0x05, 0x53,
+ 0x66, 0xd0, 0xd0, 0x31, 0x6d, 0x86, 0x0f, 0x35, 0x53, 0x67, 0x20, 0xd1,
+ 0x34, 0x7d, 0x86, 0x14, 0x65, 0x53, 0x68, 0x70, 0xd1, 0x37, 0x8d, 0x86,
+ 0x19, 0x95, 0x53, 0x69, 0xc0, 0xd1, 0x3a, 0x9d, 0x86, 0x1e, 0xc5, 0x53,
+ 0x6a, 0x10, 0xd2, 0x3d, 0xad, 0x86, 0x23, 0xf5, 0x53, 0x6b, 0x60, 0xd2,
+ 0x40, 0xbd, 0x86, 0x27, 0xbd, 0x4f, 0x29, 0xe5, 0xcf, 0x2a, 0x0d, 0x50,
+ 0x2c, 0x35, 0xd0, 0x2d, 0x5d, 0x50, 0x2f, 0x85, 0xd0, 0x30, 0xad, 0x50,
+ 0x32, 0xd5, 0xd0, 0x33, 0xfd, 0x50, 0x35, 0x25, 0xd1, 0x36, 0x4d, 0x51,
+ 0x38, 0x75, 0xd1, 0x39, 0x9d, 0x51, 0x3b, 0xc5, 0xd1, 0x3c, 0xed, 0x51,
+ 0x3e, 0x15, 0xd2, 0x3f, 0x3d, 0x52, 0x41, 0x65, 0x52, 0x42, 0xb5, 0x4f,
+ 0x43, 0xdd, 0x4f, 0x44, 0x05, 0x50, 0x45, 0x2d, 0x50, 0x46, 0x55, 0x50,
+ 0x47, 0x7d, 0x50, 0x48, 0xa5, 0x50, 0x49, 0xcd, 0x50, 0x4a, 0xf5, 0x50,
+ 0x4b, 0x1d, 0x51, 0x4c, 0x45, 0x51, 0x4d, 0x6d, 0x51, 0x4e, 0x95, 0x51,
+ 0x4f, 0xbd, 0x51, 0x50, 0xe5, 0x51, 0x51, 0x0d, 0x52, 0x52, 0x35, 0x52,
+ 0x53, 0x5d, 0x52, 0x54, 0xad, 0x4f, 0x55, 0xd5, 0x4f, 0x56, 0xfd, 0x4f,
+ 0x57, 0x25, 0x50, 0x58, 0x4d, 0x50, 0x59, 0x75, 0x50, 0x5a, 0x9d, 0x50,
+ 0x5b, 0xc5, 0x50, 0x5c, 0xed, 0x50, 0x5d, 0x15, 0x51, 0x5e, 0x3d, 0x51,
+ 0x5f, 0x65, 0x51, 0x60, 0x8d, 0x51, 0x61, 0xb5, 0x51, 0x62, 0xdd, 0x51,
+ 0x63, 0x05, 0x52, 0x64, 0x2d, 0x52, 0x65, 0x55, 0x52, 0x66, 0xc5, 0x4f,
+ 0x67, 0x9d, 0x52, 0x68, 0xb5, 0x52, 0x69, 0xcd, 0x52, 0x6a, 0xe5, 0x52,
+ 0x6b, 0xfd, 0x52, 0x6c, 0x25, 0x15, 0x53, 0x6d, 0x2d, 0x53, 0x6e, 0x45,
+ 0x53, 0x6f, 0x5d, 0x53, 0x70, 0x75, 0x53, 0x71, 0x8d, 0x53, 0x72, 0xa5,
+ 0x53, 0x73, 0xbd, 0x53, 0x74, 0xd5, 0x53, 0x75, 0xed, 0x53, 0x76, 0x05,
+ 0x54, 0x77, 0xbd, 0x86, 0x80, 0x00, 0x00, 0x3b,
+ };
+
+/*
+ Octagons image declaration.
+*/
+#define OctagonsImageExtent 41
+
+static const unsigned char
+ OctagonsImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x31, 0x36, 0x20, 0x31, 0x36, 0x0A, 0x07, 0xF0, 0x08,
+ 0x08, 0x10, 0x04, 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x80, 0x00, 0x80,
+ 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x01, 0x20,
+ 0x02, 0x10, 0x04, 0x08, 0x08,
+ };
+
+/*
+ Right30 image declaration.
+*/
+#define Right30ImageExtent 11
+
+static const unsigned char
+ Right30Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x34, 0x0A, 0x03, 0x0C, 0x30, 0xC0,
+ };
+
+/*
+ Right45 image declaration.
+*/
+#define Right45ImageExtent 15
+
+static const unsigned char
+ Right45Image[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x01, 0x02, 0x04, 0x08, 0x10,
+ 0x20, 0x40, 0x80,
+ };
+
+/*
+ RightShingle image declaration.
+*/
+#define RightShingleImageExtent 81
+
+static const unsigned char
+ RightShingleImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x32, 0x34, 0x20, 0x32, 0x34, 0x0A, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02,
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x08, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0x08, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
+ };
+
+/*
+ Image of a Rose
+*/
+#define RoseImageExtent 9673
+
+static const unsigned char
+ RoseImage[]=
+ {
+ 0x50, 0x36, 0x0a, 0x37, 0x30, 0x20, 0x34, 0x36, 0x0a, 0x32, 0x35, 0x35,
+ 0x0a, 0x30, 0x2f, 0x2d, 0x32, 0x30, 0x2e, 0x36, 0x32, 0x2f, 0x38, 0x33,
+ 0x2e, 0x3a, 0x33, 0x2d, 0x39, 0x32, 0x2d, 0x38, 0x30, 0x2d, 0x39, 0x31,
+ 0x2e, 0x38, 0x30, 0x2d, 0x38, 0x30, 0x2d, 0x37, 0x2f, 0x2c, 0x35, 0x2d,
+ 0x2a, 0x34, 0x2c, 0x29, 0x35, 0x2d, 0x2a, 0x35, 0x2d, 0x2a, 0x31, 0x2d,
+ 0x27, 0x31, 0x2e, 0x27, 0x34, 0x31, 0x2a, 0x37, 0x34, 0x2d, 0x39, 0x36,
+ 0x2f, 0x3f, 0x3a, 0x2f, 0x46, 0x3f, 0x33, 0x4a, 0x42, 0x34, 0x4c, 0x41,
+ 0x32, 0x4e, 0x42, 0x32, 0x55, 0x41, 0x32, 0x74, 0x44, 0x34, 0x9a, 0x43,
+ 0x33, 0xb4, 0x41, 0x35, 0xc5, 0x45, 0x3d, 0xe0, 0x44, 0x47, 0xed, 0x43,
+ 0x46, 0xf6, 0x3d, 0x42, 0xf1, 0x3c, 0x40, 0xd6, 0x40, 0x3b, 0xb8, 0x3f,
+ 0x2f, 0xb2, 0x3f, 0x2d, 0xad, 0x40, 0x2d, 0xa3, 0x41, 0x2b, 0x98, 0x40,
+ 0x2b, 0x92, 0x3f, 0x2e, 0x91, 0x3d, 0x2c, 0x92, 0x3d, 0x2b, 0x93, 0x3d,
+ 0x2a, 0x95, 0x3f, 0x2e, 0x99, 0x3f, 0x33, 0xb1, 0x42, 0x33, 0xbb, 0x44,
+ 0x36, 0x95, 0x46, 0x39, 0x52, 0x3a, 0x2f, 0x3a, 0x35, 0x33, 0x37, 0x32,
+ 0x31, 0x37, 0x32, 0x2f, 0x36, 0x31, 0x2e, 0x33, 0x30, 0x2c, 0x2f, 0x2f,
+ 0x2d, 0x30, 0x2f, 0x2d, 0x33, 0x2c, 0x2d, 0x36, 0x2b, 0x2d, 0x50, 0x37,
+ 0x38, 0x82, 0x49, 0x47, 0x9d, 0x62, 0x6e, 0x8c, 0x7c, 0xa6, 0x6c, 0x70,
+ 0xa5, 0x50, 0x48, 0x6e, 0x52, 0x4c, 0x61, 0x75, 0x77, 0x7c, 0x95, 0x9a,
+ 0x90, 0x7a, 0x7c, 0x6c, 0x59, 0x56, 0x53, 0x2f, 0x2e, 0x2c, 0x30, 0x2f,
+ 0x2d, 0x35, 0x30, 0x2d, 0x37, 0x31, 0x2d, 0x38, 0x31, 0x2c, 0x38, 0x30,
+ 0x2c, 0x36, 0x2f, 0x2c, 0x38, 0x31, 0x2d, 0x38, 0x31, 0x2d, 0x38, 0x31,
+ 0x2e, 0x37, 0x2e, 0x2c, 0x34, 0x2d, 0x2a, 0x34, 0x2c, 0x2a, 0x36, 0x2f,
+ 0x2b, 0x36, 0x2e, 0x2b, 0x33, 0x2f, 0x2a, 0x33, 0x30, 0x2a, 0x34, 0x31,
+ 0x2b, 0x36, 0x33, 0x2d, 0x37, 0x35, 0x30, 0x3e, 0x38, 0x2d, 0x45, 0x3d,
+ 0x32, 0x48, 0x3f, 0x31, 0x49, 0x3e, 0x2e, 0x4b, 0x40, 0x2f, 0x4d, 0x44,
+ 0x33, 0x69, 0x45, 0x34, 0x8c, 0x40, 0x2e, 0xa6, 0x3c, 0x2d, 0xba, 0x47,
+ 0x3c, 0xdc, 0x44, 0x47, 0xeb, 0x42, 0x45, 0xfc, 0x3c, 0x41, 0xf7, 0x3c,
+ 0x40, 0xd1, 0x41, 0x3b, 0xb1, 0x3f, 0x2d, 0xb0, 0x3f, 0x2b, 0xad, 0x3f,
+ 0x2c, 0xa2, 0x40, 0x2b, 0x97, 0x3f, 0x2b, 0x91, 0x3e, 0x2e, 0x90, 0x3d,
+ 0x2c, 0x91, 0x3d, 0x2a, 0x90, 0x3b, 0x2a, 0x91, 0x3e, 0x2d, 0x98, 0x3e,
+ 0x33, 0xba, 0x40, 0x34, 0xc8, 0x44, 0x38, 0x93, 0x48, 0x3b, 0x44, 0x37,
+ 0x2c, 0x39, 0x35, 0x35, 0x39, 0x33, 0x31, 0x36, 0x32, 0x2f, 0x36, 0x32,
+ 0x2e, 0x31, 0x31, 0x2d, 0x2d, 0x31, 0x2e, 0x30, 0x30, 0x2e, 0x35, 0x2f,
+ 0x2e, 0x32, 0x2a, 0x2c, 0x45, 0x32, 0x31, 0x78, 0x41, 0x35, 0x94, 0x59,
+ 0x5c, 0x86, 0x7d, 0xab, 0x63, 0x6c, 0xac, 0x4a, 0x3e, 0x6b, 0x4b, 0x40,
+ 0x5c, 0x5d, 0x5e, 0x67, 0x80, 0x86, 0x7e, 0x6c, 0x70, 0x5f, 0x59, 0x57,
+ 0x53, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2b, 0x30, 0x2f, 0x2c, 0x31, 0x2e,
+ 0x2b, 0x32, 0x2c, 0x28, 0x32, 0x2d, 0x2a, 0x30, 0x2c, 0x2b, 0x32, 0x2c,
+ 0x2b, 0x32, 0x2b, 0x2b, 0x32, 0x2c, 0x2b, 0x32, 0x2c, 0x2b, 0x31, 0x2c,
+ 0x2b, 0x31, 0x2c, 0x29, 0x33, 0x2d, 0x2c, 0x33, 0x2d, 0x2c, 0x33, 0x2f,
+ 0x2c, 0x33, 0x31, 0x2c, 0x34, 0x30, 0x2c, 0x35, 0x32, 0x2d, 0x37, 0x35,
+ 0x30, 0x3a, 0x33, 0x2c, 0x3e, 0x36, 0x2d, 0x40, 0x36, 0x2d, 0x43, 0x38,
+ 0x2d, 0x48, 0x3b, 0x2f, 0x45, 0x45, 0x35, 0x55, 0x44, 0x34, 0x6d, 0x3d,
+ 0x2b, 0x84, 0x39, 0x28, 0x9f, 0x45, 0x34, 0xc0, 0x48, 0x3d, 0xdc, 0x45,
+ 0x40, 0xf6, 0x3c, 0x3e, 0xec, 0x3e, 0x3d, 0xb9, 0x41, 0x30, 0xa5, 0x40,
+ 0x2a, 0xa9, 0x3f, 0x2d, 0xa5, 0x3e, 0x2d, 0x9b, 0x3f, 0x2c, 0x91, 0x3e,
+ 0x29, 0x8e, 0x3e, 0x2c, 0x8c, 0x3d, 0x2d, 0x8b, 0x3c, 0x2d, 0x89, 0x3b,
+ 0x2e, 0x89, 0x3f, 0x2f, 0x9b, 0x42, 0x31, 0xc3, 0x40, 0x38, 0xc3, 0x47,
+ 0x44, 0x89, 0x57, 0x4e, 0x3c, 0x3f, 0x35, 0x3b, 0x34, 0x31, 0x39, 0x33,
+ 0x2e, 0x35, 0x33, 0x2e, 0x31, 0x34, 0x2f, 0x2d, 0x34, 0x2e, 0x2c, 0x34,
+ 0x30, 0x2f, 0x33, 0x2f, 0x31, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x33, 0x2d,
+ 0x2b, 0x49, 0x2e, 0x21, 0x6c, 0x4d, 0x4e, 0x8a, 0x87, 0xbd, 0x6b, 0x71,
+ 0xc6, 0x48, 0x3d, 0x7f, 0x3d, 0x31, 0x58, 0x35, 0x34, 0x48, 0x3e, 0x46,
+ 0x46, 0x49, 0x53, 0x49, 0x59, 0x5a, 0x4f, 0x2c, 0x2d, 0x2f, 0x2b, 0x2d,
+ 0x2f, 0x2e, 0x2d, 0x2d, 0x2f, 0x2d, 0x29, 0x2f, 0x2a, 0x27, 0x2d, 0x2b,
+ 0x28, 0x2c, 0x2a, 0x2a, 0x2c, 0x2a, 0x2a, 0x2e, 0x2b, 0x2b, 0x2e, 0x2b,
+ 0x2b, 0x2e, 0x2b, 0x2b, 0x2f, 0x2b, 0x2b, 0x2f, 0x2d, 0x2d, 0x30, 0x2c,
+ 0x2c, 0x30, 0x2d, 0x2e, 0x2f, 0x2d, 0x2a, 0x32, 0x2e, 0x2c, 0x32, 0x2e,
+ 0x2b, 0x32, 0x2d, 0x2c, 0x33, 0x30, 0x2e, 0x38, 0x32, 0x2f, 0x3c, 0x34,
+ 0x2f, 0x3e, 0x34, 0x2f, 0x41, 0x35, 0x2d, 0x46, 0x39, 0x31, 0x48, 0x3e,
+ 0x37, 0x51, 0x3c, 0x35, 0x5f, 0x37, 0x30, 0x79, 0x37, 0x2d, 0x93, 0x3b,
+ 0x2f, 0xa3, 0x41, 0x33, 0xbc, 0x45, 0x39, 0xde, 0x45, 0x40, 0xda, 0x48,
+ 0x41, 0xa7, 0x42, 0x2f, 0x9b, 0x40, 0x2c, 0x9e, 0x3e, 0x2d, 0x9c, 0x3d,
+ 0x2f, 0x94, 0x3d, 0x2d, 0x8c, 0x3d, 0x2b, 0x88, 0x3c, 0x2b, 0x87, 0x3c,
+ 0x2c, 0x85, 0x3c, 0x2e, 0x82, 0x3c, 0x32, 0x86, 0x43, 0x37, 0x9d, 0x47,
+ 0x3a, 0xba, 0x45, 0x40, 0xb4, 0x67, 0x5f, 0x8f, 0x8a, 0x79, 0x57, 0x65,
+ 0x57, 0x43, 0x42, 0x38, 0x37, 0x35, 0x2b, 0x2f, 0x31, 0x2a, 0x2e, 0x31,
+ 0x2b, 0x2d, 0x30, 0x2c, 0x2d, 0x30, 0x2f, 0x2f, 0x30, 0x2e, 0x30, 0x32,
+ 0x2e, 0x2f, 0x32, 0x2e, 0x2f, 0x2d, 0x32, 0x34, 0x2a, 0x2c, 0x67, 0x63,
+ 0x62, 0x9a, 0x9d, 0xce, 0x7e, 0x87, 0xd0, 0x69, 0x70, 0x9e, 0x59, 0x5c,
+ 0x6f, 0x60, 0x70, 0x72, 0x82, 0x96, 0x8c, 0x7c, 0x8f, 0x81, 0x5f, 0x65,
+ 0x51, 0x2c, 0x2f, 0x32, 0x2b, 0x2f, 0x32, 0x2e, 0x2e, 0x30, 0x2d, 0x2e,
+ 0x2d, 0x2d, 0x2b, 0x29, 0x2c, 0x2a, 0x2b, 0x2b, 0x29, 0x2b, 0x28, 0x27,
+ 0x28, 0x2a, 0x2a, 0x2b, 0x2c, 0x2a, 0x2b, 0x2c, 0x2a, 0x2b, 0x2a, 0x29,
+ 0x29, 0x2a, 0x28, 0x29, 0x2d, 0x2b, 0x2c, 0x2e, 0x2d, 0x2e, 0x2f, 0x2c,
+ 0x2b, 0x30, 0x2c, 0x2b, 0x2e, 0x2a, 0x29, 0x2f, 0x2b, 0x2b, 0x30, 0x2d,
+ 0x2d, 0x38, 0x31, 0x31, 0x3c, 0x33, 0x32, 0x3b, 0x32, 0x31, 0x3e, 0x30,
+ 0x2e, 0x41, 0x32, 0x2f, 0x41, 0x37, 0x33, 0x42, 0x3a, 0x36, 0x4b, 0x36,
+ 0x32, 0x68, 0x37, 0x2f, 0x89, 0x3d, 0x30, 0x95, 0x3e, 0x35, 0x98, 0x41,
+ 0x33, 0xaf, 0x44, 0x37, 0xba, 0x47, 0x3c, 0x9e, 0x3f, 0x33, 0x92, 0x3f,
+ 0x2c, 0x94, 0x3d, 0x2b, 0x95, 0x3b, 0x2d, 0x8e, 0x3c, 0x2d, 0x87, 0x3b,
+ 0x2c, 0x87, 0x39, 0x29, 0x82, 0x39, 0x2a, 0x7f, 0x3a, 0x2e, 0x7f, 0x3f,
+ 0x37, 0x86, 0x47, 0x40, 0x97, 0x45, 0x3e, 0xae, 0x55, 0x52, 0xa3, 0x91,
+ 0x7b, 0x8c, 0xab, 0x8c, 0x72, 0x81, 0x70, 0x53, 0x5a, 0x47, 0x3c, 0x40,
+ 0x33, 0x30, 0x31, 0x28, 0x2d, 0x29, 0x27, 0x32, 0x2c, 0x2b, 0x32, 0x2c,
+ 0x2b, 0x30, 0x2c, 0x2a, 0x30, 0x2d, 0x2b, 0x30, 0x2f, 0x2b, 0x32, 0x2a,
+ 0x31, 0x30, 0x29, 0x28, 0x65, 0x71, 0x52, 0x95, 0xa1, 0x9c, 0x8f, 0xa5,
+ 0xa3, 0xa6, 0xca, 0xb3, 0xa4, 0xc7, 0xb0, 0x8f, 0xb6, 0x97, 0x99, 0xba,
+ 0x98, 0x85, 0xa1, 0x84, 0x59, 0x64, 0x4a, 0x2e, 0x30, 0x2e, 0x2f, 0x2f,
+ 0x2d, 0x2f, 0x31, 0x2e, 0x32, 0x31, 0x2e, 0x33, 0x30, 0x2d, 0x33, 0x2f,
+ 0x2c, 0x32, 0x2d, 0x2a, 0x2d, 0x2a, 0x2b, 0x2c, 0x2b, 0x2c, 0x2a, 0x29,
+ 0x2d, 0x2b, 0x28, 0x2c, 0x2d, 0x27, 0x2c, 0x2b, 0x28, 0x29, 0x2c, 0x2a,
+ 0x29, 0x2d, 0x2d, 0x2b, 0x2f, 0x2d, 0x2c, 0x2e, 0x2b, 0x2a, 0x2f, 0x2b,
+ 0x29, 0x34, 0x2c, 0x29, 0x36, 0x2f, 0x2a, 0x3b, 0x33, 0x2e, 0x3d, 0x34,
+ 0x30, 0x3b, 0x31, 0x2d, 0x3b, 0x2f, 0x2e, 0x3e, 0x2f, 0x2e, 0x3e, 0x33,
+ 0x2c, 0x35, 0x39, 0x2f, 0x39, 0x33, 0x2c, 0x4f, 0x2c, 0x27, 0x69, 0x3a,
+ 0x2d, 0x83, 0x41, 0x31, 0x8e, 0x40, 0x31, 0x92, 0x3b, 0x2d, 0x98, 0x42,
+ 0x32, 0x94, 0x3e, 0x32, 0x93, 0x3c, 0x2f, 0x89, 0x3d, 0x2e, 0x89, 0x3f,
+ 0x2f, 0x8b, 0x3c, 0x2f, 0x84, 0x39, 0x2c, 0x7b, 0x3b, 0x2c, 0x76, 0x3a,
+ 0x2a, 0x7d, 0x3b, 0x30, 0x86, 0x47, 0x3b, 0x87, 0x4b, 0x44, 0x95, 0x51,
+ 0x4f, 0x93, 0x81, 0x70, 0x90, 0xa9, 0x8b, 0x89, 0xad, 0x8e, 0x77, 0x96,
+ 0x79, 0x5c, 0x7b, 0x5a, 0x4e, 0x5e, 0x47, 0x3d, 0x3a, 0x33, 0x32, 0x27,
+ 0x28, 0x2f, 0x27, 0x29, 0x2d, 0x28, 0x2b, 0x30, 0x28, 0x2c, 0x32, 0x28,
+ 0x2f, 0x31, 0x2b, 0x30, 0x30, 0x2a, 0x30, 0x2b, 0x27, 0x1f, 0x5b, 0x66,
+ 0x40, 0x91, 0xa2, 0x76, 0x8c, 0xaa, 0x76, 0xa0, 0xc9, 0x8c, 0x9d, 0xc3,
+ 0x93, 0x84, 0xaf, 0x7e, 0x87, 0xad, 0x82, 0x76, 0x8e, 0x70, 0x4f, 0x5b,
+ 0x44, 0x32, 0x33, 0x2d, 0x33, 0x34, 0x2d, 0x35, 0x33, 0x2e, 0x39, 0x36,
+ 0x31, 0x39, 0x36, 0x31, 0x3a, 0x32, 0x2e, 0x38, 0x30, 0x2d, 0x33, 0x2e,
+ 0x2c, 0x33, 0x30, 0x30, 0x2d, 0x2e, 0x30, 0x2f, 0x28, 0x2f, 0x31, 0x29,
+ 0x2e, 0x2f, 0x2a, 0x2c, 0x31, 0x2e, 0x2a, 0x31, 0x30, 0x2a, 0x30, 0x31,
+ 0x2e, 0x2f, 0x30, 0x30, 0x34, 0x2f, 0x2b, 0x3b, 0x31, 0x2b, 0x41, 0x35,
+ 0x2c, 0x43, 0x38, 0x2f, 0x41, 0x39, 0x30, 0x3d, 0x35, 0x2d, 0x3b, 0x30,
+ 0x2f, 0x3c, 0x31, 0x2f, 0x45, 0x31, 0x2d, 0x52, 0x29, 0x2e, 0x46, 0x2a,
+ 0x2e, 0x37, 0x30, 0x29, 0x52, 0x2f, 0x28, 0x6a, 0x39, 0x2e, 0x83, 0x3a,
+ 0x37, 0x86, 0x39, 0x34, 0x7f, 0x3f, 0x35, 0x84, 0x42, 0x36, 0x89, 0x41,
+ 0x31, 0x85, 0x3e, 0x2d, 0x88, 0x3a, 0x2b, 0x85, 0x3b, 0x2a, 0x76, 0x3e,
+ 0x29, 0x76, 0x38, 0x2c, 0x73, 0x39, 0x2d, 0x7b, 0x40, 0x34, 0x89, 0x47,
+ 0x3e, 0x88, 0x4e, 0x45, 0x86, 0x64, 0x56, 0x7a, 0x92, 0x71, 0x7b, 0xaf,
+ 0x88, 0x83, 0xb1, 0x8c, 0x76, 0x9e, 0x7c, 0x65, 0x92, 0x67, 0x64, 0x87,
+ 0x65, 0x50, 0x66, 0x50, 0x34, 0x3d, 0x30, 0x2a, 0x26, 0x23, 0x2e, 0x24,
+ 0x26, 0x2b, 0x2a, 0x2a, 0x29, 0x2b, 0x2c, 0x27, 0x2b, 0x2f, 0x27, 0x27,
+ 0x2d, 0x29, 0x24, 0x22, 0x57, 0x5c, 0x48, 0x7e, 0x91, 0x6a, 0x7b, 0x9c,
+ 0x6a, 0x7e, 0xa3, 0x6f, 0x7f, 0xa5, 0x6f, 0x7d, 0xa5, 0x74, 0x7e, 0xa1,
+ 0x7b, 0x6f, 0x89, 0x6c, 0x4c, 0x56, 0x44, 0x37, 0x38, 0x32, 0x37, 0x38,
+ 0x32, 0x39, 0x39, 0x34, 0x3c, 0x3a, 0x35, 0x40, 0x3d, 0x38, 0x42, 0x3a,
+ 0x38, 0x41, 0x39, 0x35, 0x3d, 0x37, 0x33, 0x3c, 0x37, 0x35, 0x3a, 0x35,
+ 0x34, 0x39, 0x30, 0x30, 0x39, 0x2f, 0x2f, 0x36, 0x31, 0x2e, 0x36, 0x32,
+ 0x2e, 0x36, 0x33, 0x2e, 0x36, 0x34, 0x31, 0x39, 0x37, 0x33, 0x3f, 0x37,
+ 0x32, 0x42, 0x39, 0x30, 0x48, 0x3d, 0x31, 0x4a, 0x3e, 0x34, 0x48, 0x3d,
+ 0x34, 0x42, 0x38, 0x30, 0x40, 0x36, 0x31, 0x3f, 0x36, 0x32, 0x3c, 0x39,
+ 0x34, 0x43, 0x35, 0x34, 0x41, 0x35, 0x30, 0x3c, 0x36, 0x2a, 0x45, 0x35,
+ 0x27, 0x63, 0x36, 0x2d, 0x87, 0x3d, 0x3b, 0x90, 0x42, 0x41, 0x84, 0x43,
+ 0x3b, 0x84, 0x3e, 0x36, 0x7f, 0x41, 0x35, 0x7e, 0x3a, 0x2f, 0x79, 0x3b,
+ 0x2f, 0x75, 0x3e, 0x2e, 0x7a, 0x34, 0x29, 0xb9, 0x50, 0x4c, 0xac, 0x5b,
+ 0x56, 0x70, 0x4a, 0x39, 0x6b, 0x53, 0x40, 0x73, 0x60, 0x49, 0x7f, 0x7a,
+ 0x58, 0xb6, 0x66, 0x60, 0xbf, 0x7a, 0x72, 0xa2, 0xa1, 0x85, 0x8f, 0xa0,
+ 0x7e, 0x8b, 0x97, 0x76, 0x80, 0x9e, 0x78, 0x6f, 0x93, 0x6f, 0x58, 0x69,
+ 0x4d, 0x3f, 0x3b, 0x29, 0x33, 0x29, 0x22, 0x25, 0x2b, 0x21, 0x2b, 0x2f,
+ 0x26, 0x3a, 0x26, 0x2a, 0x43, 0x29, 0x29, 0x54, 0x4e, 0x3a, 0x68, 0x71,
+ 0x52, 0x68, 0x83, 0x57, 0x6b, 0x91, 0x5c, 0x6e, 0x9a, 0x63, 0x6b, 0x98,
+ 0x68, 0x73, 0x9c, 0x74, 0x74, 0x95, 0x74, 0x68, 0x86, 0x64, 0x4e, 0x58,
+ 0x43, 0x38, 0x39, 0x33, 0x39, 0x3a, 0x34, 0x3e, 0x3e, 0x38, 0x41, 0x3f,
+ 0x3a, 0x44, 0x3f, 0x3a, 0x46, 0x41, 0x3c, 0x45, 0x41, 0x3a, 0x45, 0x40,
+ 0x3a, 0x47, 0x3f, 0x38, 0x45, 0x3d, 0x34, 0x44, 0x3b, 0x31, 0x43, 0x3a,
+ 0x33, 0x43, 0x3a, 0x33, 0x3c, 0x38, 0x30, 0x39, 0x35, 0x2f, 0x39, 0x34,
+ 0x2f, 0x3c, 0x37, 0x30, 0x42, 0x3c, 0x30, 0x49, 0x3d, 0x30, 0x4f, 0x41,
+ 0x32, 0x50, 0x40, 0x35, 0x4b, 0x3c, 0x34, 0x45, 0x3a, 0x31, 0x41, 0x3a,
+ 0x31, 0x3d, 0x3c, 0x33, 0x47, 0x37, 0x30, 0x8b, 0x45, 0x4a, 0x9a, 0x47,
+ 0x49, 0x86, 0x43, 0x3a, 0xab, 0x4b, 0x48, 0xa2, 0x46, 0x39, 0xa6, 0x3f,
+ 0x33, 0xa8, 0x43, 0x35, 0xa2, 0x45, 0x31, 0xaa, 0x40, 0x32, 0xac, 0x3e,
+ 0x42, 0x9e, 0x43, 0x45, 0x76, 0x43, 0x39, 0x79, 0x3a, 0x34, 0xbf, 0x3c,
+ 0x48, 0xe1, 0x45, 0x47, 0xc3, 0x55, 0x50, 0x70, 0x59, 0x43, 0x60, 0x6a,
+ 0x48, 0x90, 0x6c, 0x53, 0xe8, 0x53, 0x5a, 0xff, 0x28, 0x48, 0xff, 0x29,
+ 0x4b, 0xf9, 0x40, 0x56, 0xf0, 0x4d, 0x5f, 0xe4, 0x59, 0x68, 0xdb, 0x66,
+ 0x6e, 0xd4, 0x6a, 0x72, 0xd2, 0x5f, 0x6d, 0xd4, 0x57, 0x6b, 0xc2, 0x50,
+ 0x62, 0x96, 0x46, 0x4f, 0x52, 0x2e, 0x28, 0x3e, 0x33, 0x28, 0x47, 0x40,
+ 0x2d, 0x65, 0x5e, 0x3a, 0x77, 0x83, 0x5c, 0x6e, 0x87, 0x5c, 0x6d, 0x89,
+ 0x59, 0x73, 0x8f, 0x64, 0x7e, 0x98, 0x7b, 0x8c, 0xa2, 0x8e, 0x80, 0x96,
+ 0x81, 0x64, 0x7d, 0x5f, 0x53, 0x5f, 0x47, 0x36, 0x37, 0x31, 0x36, 0x38,
+ 0x31, 0x3d, 0x3d, 0x38, 0x42, 0x40, 0x3b, 0x46, 0x41, 0x3f, 0x48, 0x43,
+ 0x3e, 0x48, 0x43, 0x3e, 0x4a, 0x44, 0x3c, 0x4d, 0x42, 0x37, 0x4a, 0x3d,
+ 0x30, 0x48, 0x3c, 0x2d, 0x46, 0x3d, 0x2f, 0x45, 0x3b, 0x30, 0x41, 0x39,
+ 0x31, 0x3c, 0x37, 0x31, 0x3a, 0x37, 0x2e, 0x3e, 0x39, 0x2c, 0x45, 0x3c,
+ 0x2f, 0x4d, 0x3f, 0x2f, 0x4f, 0x41, 0x30, 0x4f, 0x3e, 0x31, 0x4b, 0x3b,
+ 0x31, 0x44, 0x3a, 0x2f, 0x3e, 0x3d, 0x31, 0x37, 0x3d, 0x30, 0x80, 0x42,
+ 0x40, 0xed, 0x4b, 0x5d, 0xcb, 0x33, 0x35, 0x9b, 0x3b, 0x23, 0xc1, 0x3f,
+ 0x35, 0xac, 0x3b, 0x30, 0xb3, 0x3e, 0x33, 0xb7, 0x44, 0x37, 0xa5, 0x3a,
+ 0x28, 0xb9, 0x3e, 0x32, 0xd1, 0x3e, 0x38, 0xef, 0x38, 0x3f, 0xe1, 0x3c,
+ 0x3c, 0xd4, 0x44, 0x3f, 0xeb, 0x37, 0x3b, 0xda, 0x2e, 0x27, 0xc4, 0x42,
+ 0x3a, 0x92, 0x64, 0x4f, 0x88, 0x63, 0x4a, 0xde, 0x63, 0x5e, 0xf7, 0x3b,
+ 0x45, 0xe0, 0x42, 0x43, 0xf5, 0x46, 0x4f, 0xfe, 0x2e, 0x45, 0xff, 0x2c,
+ 0x48, 0xff, 0x30, 0x54, 0xff, 0x34, 0x5c, 0xff, 0x3a, 0x68, 0xff, 0x3a,
+ 0x6f, 0xff, 0x41, 0x72, 0xff, 0x47, 0x6f, 0xff, 0x5a, 0x78, 0xc6, 0x5b,
+ 0x66, 0x61, 0x3d, 0x33, 0x48, 0x43, 0x2f, 0x7f, 0x76, 0x64, 0x9a, 0x9f,
+ 0x95, 0x91, 0x9e, 0x98, 0x98, 0xa0, 0x9a, 0xb6, 0xb5, 0xad, 0xd1, 0xcb,
+ 0xc6, 0xd4, 0xcc, 0xd3, 0xb0, 0xb1, 0xb1, 0x67, 0x7b, 0x65, 0x57, 0x67,
+ 0x4c, 0x33, 0x33, 0x30, 0x35, 0x35, 0x31, 0x38, 0x38, 0x33, 0x3d, 0x3c,
+ 0x36, 0x44, 0x43, 0x39, 0x47, 0x47, 0x3e, 0x4a, 0x49, 0x3b, 0x4d, 0x49,
+ 0x36, 0x49, 0x45, 0x37, 0x4d, 0x48, 0x4a, 0x48, 0x40, 0x39, 0x45, 0x3b,
+ 0x2b, 0x43, 0x39, 0x2d, 0x3f, 0x38, 0x30, 0x3e, 0x38, 0x33, 0x3d, 0x37,
+ 0x31, 0x3e, 0x39, 0x34, 0x40, 0x3d, 0x39, 0x49, 0x41, 0x36, 0x50, 0x40,
+ 0x2d, 0x48, 0x3f, 0x2d, 0x4b, 0x38, 0x31, 0x43, 0x37, 0x34, 0x35, 0x3d,
+ 0x30, 0x40, 0x3f, 0x2f, 0xa6, 0x49, 0x40, 0xaf, 0x34, 0x2b, 0xa4, 0x34,
+ 0x21, 0xa6, 0x41, 0x26, 0xa9, 0x3a, 0x24, 0xa0, 0x36, 0x27, 0xa9, 0x3d,
+ 0x32, 0xac, 0x41, 0x31, 0xb0, 0x40, 0x32, 0xbf, 0x40, 0x34, 0xcc, 0x38,
+ 0x29, 0xe8, 0x31, 0x2b, 0xf9, 0x2b, 0x2b, 0xf3, 0x30, 0x29, 0xe1, 0x36,
+ 0x25, 0xd8, 0x35, 0x21, 0xc7, 0x39, 0x2c, 0xc5, 0x55, 0x49, 0xe0, 0x55,
+ 0x51, 0xfe, 0x41, 0x4b, 0xdf, 0x3f, 0x41, 0xae, 0x3b, 0x2e, 0xc4, 0x45,
+ 0x3b, 0xec, 0x41, 0x44, 0xfc, 0x3e, 0x48, 0xfd, 0x41, 0x51, 0xff, 0x3d,
+ 0x56, 0xfe, 0x3e, 0x68, 0xfb, 0x3e, 0x71, 0xfc, 0x45, 0x77, 0xf9, 0x4a,
+ 0x6e, 0xfd, 0x57, 0x78, 0xff, 0x59, 0x7f, 0xcd, 0x5d, 0x6e, 0x87, 0x6e,
+ 0x64, 0xd3, 0xc8, 0xc1, 0xe0, 0xe0, 0xea, 0xe6, 0xd6, 0xf0, 0xf5, 0xe1,
+ 0xf9, 0xfd, 0xf3, 0xf9, 0xfd, 0xf4, 0xf3, 0xf5, 0xe7, 0xf0, 0xd3, 0xce,
+ 0xd2, 0x85, 0x8d, 0x83, 0x75, 0x81, 0x6e, 0x31, 0x30, 0x2d, 0x2f, 0x2e,
+ 0x2c, 0x34, 0x33, 0x2f, 0x38, 0x39, 0x32, 0x3e, 0x3f, 0x35, 0x47, 0x44,
+ 0x3b, 0x4f, 0x4b, 0x38, 0x4d, 0x4b, 0x34, 0x58, 0x57, 0x57, 0x80, 0x83,
+ 0xa5, 0x7c, 0x78, 0xa0, 0x5b, 0x54, 0x6f, 0x46, 0x3f, 0x4f, 0x39, 0x34,
+ 0x34, 0x36, 0x32, 0x26, 0x35, 0x32, 0x29, 0x3a, 0x39, 0x2e, 0x42, 0x3d,
+ 0x2d, 0x4b, 0x40, 0x2f, 0x50, 0x40, 0x2f, 0x43, 0x3b, 0x2a, 0x3a, 0x34,
+ 0x29, 0x30, 0x34, 0x30, 0x42, 0x31, 0x2d, 0x8a, 0x36, 0x3c, 0xae, 0x3b,
+ 0x2f, 0xa4, 0x3c, 0x27, 0xa1, 0x3b, 0x25, 0xb5, 0x3e, 0x2c, 0xc7, 0x3d,
+ 0x31, 0xb8, 0x3b, 0x31, 0xad, 0x39, 0x2a, 0xb3, 0x3a, 0x2b, 0xc3, 0x3f,
+ 0x32, 0xc4, 0x33, 0x2a, 0xd6, 0x34, 0x2c, 0xdc, 0x38, 0x2e, 0xf1, 0x31,
+ 0x2b, 0xf0, 0x2f, 0x28, 0xd4, 0x35, 0x20, 0xda, 0x34, 0x21, 0xd4, 0x39,
+ 0x2c, 0xd0, 0x3f, 0x36, 0xdb, 0x43, 0x41, 0xde, 0x41, 0x3e, 0xc7, 0x3e,
+ 0x33, 0xae, 0x39, 0x28, 0xaf, 0x3d, 0x2d, 0xd5, 0x45, 0x40, 0xf3, 0x46,
+ 0x4b, 0xf7, 0x44, 0x4b, 0xfe, 0x44, 0x58, 0xfe, 0x42, 0x62, 0xff, 0x4a,
+ 0x74, 0xff, 0x4b, 0x7d, 0xfe, 0x4d, 0x7a, 0xfe, 0x54, 0x74, 0xf3, 0x43,
+ 0x63, 0xe4, 0x7b, 0x88, 0x89, 0x5f, 0x54, 0xf1, 0xd3, 0xc9, 0xff, 0xff,
+ 0xff, 0xff, 0xf5, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe,
+ 0xfb, 0xff, 0xf9, 0xfd, 0xf2, 0xe9, 0xec, 0xc0, 0xbf, 0xb8, 0xb5, 0xba,
+ 0xb0, 0x3a, 0x38, 0x31, 0x36, 0x33, 0x2d, 0x33, 0x30, 0x2b, 0x37, 0x34,
+ 0x2c, 0x3c, 0x3b, 0x32, 0x49, 0x41, 0x36, 0x56, 0x4a, 0x39, 0x54, 0x48,
+ 0x3a, 0x64, 0x61, 0x72, 0x9e, 0xa5, 0xe4, 0xac, 0xb2, 0xff, 0x9d, 0xa1,
+ 0xec, 0x8f, 0x8f, 0xc5, 0x6e, 0x6d, 0x8e, 0x4c, 0x49, 0x58, 0x40, 0x3f,
+ 0x4d, 0x3c, 0x39, 0x39, 0x41, 0x3d, 0x28, 0x42, 0x43, 0x2e, 0x38, 0x41,
+ 0x39, 0x3a, 0x45, 0x51, 0x45, 0x55, 0x61, 0x46, 0x53, 0x52, 0x61, 0x47,
+ 0x3c, 0x94, 0x46, 0x37, 0xa8, 0x3d, 0x2b, 0xae, 0x41, 0x2d, 0xb0, 0x3b,
+ 0x28, 0xbf, 0x36, 0x2a, 0xd4, 0x38, 0x30, 0xd2, 0x3a, 0x34, 0xce, 0x38,
+ 0x32, 0xd3, 0x3a, 0x33, 0xd7, 0x3b, 0x32, 0xdf, 0x3f, 0x37, 0xeb, 0x31,
+ 0x27, 0xf4, 0x2d, 0x28, 0xf9, 0x2d, 0x28, 0xeb, 0x32, 0x28, 0xd2, 0x37,
+ 0x21, 0xcf, 0x37, 0x22, 0xd1, 0x35, 0x28, 0xd9, 0x43, 0x3c, 0xdd, 0x56,
+ 0x4d, 0xba, 0x3e, 0x32, 0xb3, 0x3a, 0x23, 0xb9, 0x3a, 0x29, 0xc6, 0x40,
+ 0x37, 0xd2, 0x48, 0x46, 0xd8, 0x47, 0x48, 0xed, 0x46, 0x4a, 0xfb, 0x4f,
+ 0x5c, 0xf8, 0x46, 0x60, 0xfd, 0x4a, 0x6e, 0xfc, 0x52, 0x7a, 0xf7, 0x58,
+ 0x7a, 0xfd, 0x55, 0x71, 0xf9, 0x53, 0x67, 0xff, 0x60, 0x70, 0xd5, 0x4b,
+ 0x55, 0xe1, 0xaa, 0xa4, 0xff, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xfd, 0xfd,
+ 0xfe, 0xfe, 0xfa, 0xf5, 0xff, 0xfa, 0xf9, 0xfe, 0xf0, 0xf4, 0xea, 0xdc,
+ 0xdb, 0xef, 0xe6, 0xdb, 0xeb, 0xed, 0xe4, 0x44, 0x40, 0x35, 0x41, 0x3d,
+ 0x33, 0x3b, 0x36, 0x2d, 0x35, 0x32, 0x28, 0x3a, 0x35, 0x2f, 0x46, 0x3d,
+ 0x37, 0x54, 0x47, 0x36, 0x57, 0x46, 0x37, 0x5d, 0x55, 0x6a, 0x90, 0x99,
+ 0xde, 0xab, 0xb8, 0xff, 0xb5, 0xbe, 0xff, 0xb9, 0xbe, 0xff, 0xa7, 0xa7,
+ 0xef, 0x80, 0x7c, 0xc2, 0x66, 0x5c, 0x9e, 0x52, 0x4c, 0x73, 0x37, 0x3a,
+ 0x43, 0x3a, 0x39, 0x37, 0x52, 0x4a, 0x4e, 0x86, 0x73, 0x9b, 0xaa, 0x81,
+ 0xae, 0xba, 0x5d, 0x7b, 0xc8, 0x4b, 0x50, 0xb3, 0x3c, 0x27, 0xa9, 0x39,
+ 0x23, 0xb3, 0x3a, 0x2a, 0xc1, 0x3b, 0x2d, 0xd4, 0x3c, 0x33, 0xe1, 0x3b,
+ 0x33, 0xdb, 0x36, 0x31, 0xe5, 0x3e, 0x39, 0xe6, 0x3c, 0x37, 0xdc, 0x38,
+ 0x2f, 0xe3, 0x44, 0x39, 0xf4, 0x3f, 0x34, 0xfb, 0x29, 0x29, 0xfa, 0x2b,
+ 0x2b, 0xe3, 0x32, 0x2c, 0xcf, 0x32, 0x25, 0xc9, 0x3c, 0x28, 0xd0, 0x3a,
+ 0x2a, 0xd4, 0x37, 0x2d, 0xe4, 0x4c, 0x48, 0xd1, 0x43, 0x40, 0xbb, 0x39,
+ 0x24, 0xbf, 0x39, 0x28, 0xc7, 0x3e, 0x32, 0xd3, 0x51, 0x49, 0xc4, 0x45,
+ 0x3e, 0xe0, 0x4e, 0x49, 0xe7, 0x51, 0x53, 0xf0, 0x54, 0x61, 0xfd, 0x56,
+ 0x6e, 0xfb, 0x4e, 0x6f, 0xfd, 0x55, 0x78, 0xff, 0x57, 0x6f, 0xff, 0x5a,
+ 0x69, 0xfc, 0x57, 0x65, 0xca, 0x4f, 0x54, 0xa1, 0x74, 0x6e, 0xfa, 0xe1,
+ 0xe0, 0xfc, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xfe, 0xf9, 0xf7, 0xff, 0xfa,
+ 0xf5, 0xfa, 0xef, 0xf0, 0xdc, 0xce, 0xc9, 0xf9, 0xf2, 0xe0, 0xf9, 0xfb,
+ 0xee, 0x4f, 0x49, 0x3b, 0x4d, 0x47, 0x3a, 0x46, 0x40, 0x35, 0x3f, 0x39,
+ 0x30, 0x3d, 0x36, 0x30, 0x41, 0x3d, 0x38, 0x4d, 0x45, 0x35, 0x53, 0x44,
+ 0x2e, 0x57, 0x4c, 0x53, 0x84, 0x8e, 0xc1, 0xa6, 0xae, 0xfb, 0xb0, 0xb2,
+ 0xff, 0xb2, 0xb4, 0xff, 0xa9, 0xac, 0xf9, 0x9c, 0xa0, 0xed, 0x8b, 0x8d,
+ 0xd8, 0x6f, 0x7a, 0xb6, 0x61, 0x65, 0x87, 0x85, 0x4e, 0x5f, 0xcb, 0x4f,
+ 0x57, 0xef, 0x4c, 0x5d, 0xdc, 0x48, 0x52, 0xd2, 0x3b, 0x3e, 0xe6, 0x3e,
+ 0x3e, 0xce, 0x3e, 0x35, 0xbc, 0x3e, 0x2f, 0xc6, 0x3f, 0x32, 0xd4, 0x3e,
+ 0x34, 0xd9, 0x39, 0x2f, 0xdb, 0x33, 0x2b, 0xda, 0x37, 0x2f, 0xde, 0x38,
+ 0x2f, 0xd9, 0x33, 0x29, 0xd1, 0x33, 0x24, 0xca, 0x39, 0x22, 0xdb, 0x3e,
+ 0x30, 0xfe, 0x38, 0x3b, 0xf7, 0x30, 0x35, 0xdb, 0x32, 0x30, 0xdf, 0x35,
+ 0x34, 0xef, 0x35, 0x33, 0xe2, 0x37, 0x2b, 0xd9, 0x3e, 0x2f, 0xe3, 0x50,
+ 0x4a, 0xdc, 0x45, 0x49, 0xd0, 0x3d, 0x33, 0xc2, 0x38, 0x2b, 0xbc, 0x3c,
+ 0x2d, 0xc0, 0x43, 0x32, 0xbc, 0x3d, 0x2d, 0xc7, 0x48, 0x3d, 0xce, 0x4e,
+ 0x4a, 0xe6, 0x5c, 0x61, 0xfe, 0x66, 0x76, 0xfd, 0x50, 0x6d, 0xfa, 0x5a,
+ 0x75, 0xf1, 0x72, 0x78, 0xf3, 0x62, 0x70, 0xee, 0x7b, 0x80, 0x92, 0x75,
+ 0x65, 0x56, 0x50, 0x41, 0xe0, 0xc3, 0xc4, 0xff, 0xfd, 0xff, 0xfd, 0xfe,
+ 0xff, 0xff, 0xfc, 0xfe, 0xfd, 0xff, 0xf8, 0xff, 0xff, 0xfa, 0xed, 0xe7,
+ 0xdc, 0xfa, 0xf8, 0xde, 0xfb, 0xfc, 0xe9, 0x57, 0x4e, 0x3f, 0x56, 0x4d,
+ 0x3f, 0x50, 0x49, 0x3a, 0x4b, 0x42, 0x34, 0x46, 0x3c, 0x31, 0x45, 0x40,
+ 0x37, 0x4c, 0x47, 0x35, 0x53, 0x47, 0x2e, 0x56, 0x4e, 0x51, 0x83, 0x8b,
+ 0xbd, 0xa3, 0xa4, 0xf6, 0xa4, 0xa4, 0xff, 0xa4, 0xad, 0xff, 0xa4, 0xad,
+ 0xf0, 0xae, 0xad, 0xf6, 0xa0, 0xaf, 0xfe, 0xa1, 0xab, 0xe0, 0xba, 0x76,
+ 0x8d, 0xde, 0x41, 0x4e, 0xef, 0x3c, 0x3f, 0xe5, 0x3b, 0x37, 0xca, 0x40,
+ 0x31, 0xd1, 0x46, 0x3b, 0xed, 0x3d, 0x41, 0xe0, 0x39, 0x3c, 0xcc, 0x40,
+ 0x3a, 0xc7, 0x45, 0x39, 0xbb, 0x36, 0x28, 0xc8, 0x32, 0x2b, 0xdc, 0x34,
+ 0x31, 0xde, 0x3b, 0x2f, 0xdf, 0x37, 0x29, 0xd3, 0x34, 0x21, 0xc4, 0x36,
+ 0x21, 0xc6, 0x37, 0x26, 0xce, 0x35, 0x29, 0xd6, 0x35, 0x2b, 0xe4, 0x38,
+ 0x2e, 0xe9, 0x34, 0x32, 0xeb, 0x2d, 0x35, 0xf7, 0x2a, 0x30, 0xe4, 0x31,
+ 0x29, 0xcb, 0x35, 0x24, 0xd9, 0x4c, 0x41, 0xda, 0x48, 0x49, 0xdf, 0x4d,
+ 0x4b, 0xc7, 0x38, 0x2e, 0xc1, 0x3a, 0x28, 0xbb, 0x3b, 0x27, 0xb7, 0x3b,
+ 0x2a, 0xb4, 0x3c, 0x2f, 0xbb, 0x40, 0x33, 0xe2, 0x5e, 0x56, 0xf7, 0x6e,
+ 0x6d, 0xf6, 0x67, 0x70, 0xf1, 0x67, 0x71, 0xed, 0x74, 0x72, 0xfb, 0x6f,
+ 0x75, 0xff, 0x7a, 0x8b, 0x88, 0x97, 0x7c, 0x41, 0x51, 0x33, 0xdd, 0xc4,
+ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xee, 0xff,
+ 0xf0, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xf1, 0xfe, 0xf8, 0xe2, 0xfd, 0xfa,
+ 0xea, 0x5b, 0x50, 0x41, 0x5b, 0x4f, 0x41, 0x59, 0x4d, 0x3f, 0x54, 0x4a,
+ 0x3a, 0x54, 0x47, 0x39, 0x4e, 0x47, 0x3c, 0x52, 0x4a, 0x39, 0x57, 0x4b,
+ 0x34, 0x58, 0x51, 0x54, 0x7f, 0x80, 0xaa, 0x94, 0x97, 0xd4, 0x95, 0x97,
+ 0xe4, 0x99, 0xa2, 0xec, 0x94, 0x9f, 0xd8, 0x88, 0x90, 0xd0, 0x87, 0x85,
+ 0xbe, 0xc5, 0x69, 0x95, 0xe6, 0x3d, 0x50, 0xe2, 0x40, 0x3a, 0xe7, 0x3e,
+ 0x43, 0xe1, 0x3f, 0x46, 0xc3, 0x3e, 0x3b, 0xd6, 0x47, 0x46, 0xe8, 0x3e,
+ 0x41, 0xd7, 0x3f, 0x3b, 0xc4, 0x3d, 0x31, 0xc0, 0x3f, 0x30, 0xb9, 0x3b,
+ 0x2b, 0xcd, 0x3a, 0x2e, 0xe4, 0x39, 0x33, 0xe0, 0x33, 0x2f, 0xe4, 0x34,
+ 0x2e, 0xd1, 0x38, 0x2a, 0xba, 0x3b, 0x2b, 0xc6, 0x3b, 0x36, 0xe9, 0x3c,
+ 0x39, 0xc9, 0x39, 0x25, 0xc2, 0x39, 0x21, 0xcf, 0x33, 0x26, 0xd4, 0x35,
+ 0x2f, 0xcf, 0x37, 0x2b, 0xc8, 0x38, 0x26, 0xc9, 0x3d, 0x29, 0xdb, 0x3e,
+ 0x35, 0xe8, 0x40, 0x42, 0xed, 0x55, 0x53, 0xdd, 0x47, 0x3d, 0xc7, 0x39,
+ 0x29, 0xb7, 0x3a, 0x2a, 0xaf, 0x3c, 0x2d, 0xac, 0x3c, 0x2e, 0xaf, 0x3a,
+ 0x2a, 0xd1, 0x56, 0x47, 0xf0, 0x6d, 0x6a, 0xe9, 0x61, 0x67, 0xf1, 0x62,
+ 0x6d, 0xfa, 0x6e, 0x71, 0xff, 0x64, 0x6c, 0xf8, 0x57, 0x70, 0x75, 0x88,
+ 0x69, 0x58, 0x6e, 0x45, 0xf1, 0xe5, 0xd4, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xe2, 0xf9, 0xe6, 0xc5, 0xeb, 0xc8, 0xe2, 0xef, 0xd5, 0xfd, 0xf8,
+ 0xe6, 0xf4, 0xe6, 0xd6, 0xf2, 0xe8, 0xdd, 0x5b, 0x4e, 0x3e, 0x5a, 0x4e,
+ 0x3e, 0x5b, 0x4e, 0x3d, 0x58, 0x4d, 0x3c, 0x5a, 0x4c, 0x3c, 0x57, 0x4b,
+ 0x3f, 0x58, 0x4c, 0x3c, 0x5a, 0x4c, 0x38, 0x55, 0x4c, 0x47, 0x64, 0x5f,
+ 0x75, 0x77, 0x78, 0x9a, 0x82, 0x80, 0xba, 0x89, 0x86, 0xcd, 0x7b, 0x7b,
+ 0xb6, 0x66, 0x6d, 0xa6, 0x7c, 0x52, 0x62, 0xdc, 0x3b, 0x46, 0xff, 0x33,
+ 0x3f, 0xe9, 0x45, 0x3e, 0xee, 0x43, 0x4e, 0xdc, 0x42, 0x47, 0xb6, 0x40,
+ 0x35, 0xc6, 0x43, 0x3b, 0xd1, 0x34, 0x31, 0xc6, 0x42, 0x35, 0xbd, 0x3b,
+ 0x29, 0xbe, 0x39, 0x25, 0xc1, 0x3a, 0x25, 0xd4, 0x38, 0x28, 0xe5, 0x34,
+ 0x2b, 0xf7, 0x31, 0x33, 0xff, 0x2c, 0x33, 0xfb, 0x2d, 0x31, 0xf3, 0x2e,
+ 0x38, 0xfb, 0x28, 0x3e, 0xf6, 0x28, 0x30, 0xd3, 0x30, 0x27, 0xcd, 0x38,
+ 0x28, 0xe4, 0x3b, 0x32, 0xe8, 0x3d, 0x34, 0xd0, 0x44, 0x36, 0xc0, 0x36,
+ 0x26, 0xca, 0x35, 0x29, 0xe3, 0x37, 0x35, 0xe5, 0x2e, 0x2f, 0xd6, 0x34,
+ 0x2a, 0xce, 0x35, 0x2a, 0xd4, 0x4a, 0x3e, 0xb8, 0x3e, 0x31, 0xa9, 0x36,
+ 0x2a, 0xa8, 0x3a, 0x2b, 0xa6, 0x37, 0x26, 0xbc, 0x48, 0x3e, 0xee, 0x71,
+ 0x72, 0xf7, 0x73, 0x7e, 0xfa, 0x72, 0x7b, 0xfd, 0x73, 0x7b, 0xfe, 0x56,
+ 0x65, 0xf9, 0x44, 0x61, 0x98, 0xa0, 0x7d, 0x7d, 0x9a, 0x67, 0xcb, 0xcc,
+ 0xae, 0xd4, 0xe2, 0xc6, 0xaf, 0xca, 0xaa, 0x95, 0xb8, 0x8e, 0x8f, 0xbc,
+ 0x86, 0xa8, 0xc7, 0x9a, 0xce, 0xd5, 0xba, 0xee, 0xde, 0xd4, 0xdd, 0xcb,
+ 0xc5, 0x5b, 0x4c, 0x3c, 0x5b, 0x4c, 0x3c, 0x5c, 0x4c, 0x3c, 0x59, 0x49,
+ 0x3b, 0x5a, 0x4b, 0x3b, 0x5b, 0x4c, 0x3e, 0x5e, 0x4d, 0x3c, 0x5e, 0x50,
+ 0x3c, 0x5b, 0x4e, 0x41, 0x59, 0x4c, 0x49, 0x5e, 0x53, 0x64, 0x6d, 0x65,
+ 0x9b, 0x87, 0x7f, 0xc4, 0x9b, 0x7e, 0xb4, 0xab, 0x71, 0xa3, 0xb5, 0x40,
+ 0x47, 0xc9, 0x3e, 0x2b, 0xe8, 0x40, 0x39, 0xfc, 0x3c, 0x40, 0xe9, 0x42,
+ 0x4a, 0xbf, 0x3c, 0x37, 0xa6, 0x39, 0x28, 0xc7, 0x42, 0x38, 0xdd, 0x3b,
+ 0x38, 0xcf, 0x44, 0x3a, 0xba, 0x37, 0x24, 0xc4, 0x3b, 0x28, 0xc9, 0x38,
+ 0x27, 0xda, 0x34, 0x27, 0xee, 0x39, 0x2e, 0xe3, 0x34, 0x27, 0xee, 0x2c,
+ 0x24, 0xf5, 0x29, 0x27, 0xf8, 0x25, 0x32, 0xff, 0x16, 0x36, 0xf3, 0x27,
+ 0x36, 0xed, 0x3c, 0x44, 0xed, 0x31, 0x3a, 0xfe, 0x30, 0x3a, 0xf3, 0x2b,
+ 0x2e, 0xdf, 0x38, 0x35, 0xe8, 0x47, 0x47, 0xd9, 0x36, 0x34, 0xdd, 0x3b,
+ 0x36, 0xd5, 0x35, 0x2a, 0xc4, 0x38, 0x26, 0xc3, 0x38, 0x2b, 0xdb, 0x51,
+ 0x47, 0xc9, 0x3c, 0x33, 0xcd, 0x39, 0x31, 0xd0, 0x3a, 0x33, 0xbf, 0x38,
+ 0x2b, 0xb3, 0x38, 0x2d, 0xe7, 0x6b, 0x6b, 0xff, 0x81, 0x89, 0xfd, 0x7a,
+ 0x83, 0xff, 0x72, 0x7f, 0xff, 0x4d, 0x64, 0xf9, 0x3f, 0x5c, 0x82, 0x86,
+ 0x5e, 0x67, 0x87, 0x51, 0x7c, 0x85, 0x5c, 0x61, 0x7e, 0x51, 0x65, 0x8d,
+ 0x59, 0x79, 0xa1, 0x68, 0x86, 0xb6, 0x74, 0x8d, 0xb9, 0x79, 0x94, 0xac,
+ 0x7f, 0xc0, 0xb5, 0xa6, 0xc5, 0xb5, 0xb3, 0x5b, 0x4b, 0x3a, 0x5b, 0x4b,
+ 0x3a, 0x59, 0x4b, 0x3a, 0x59, 0x49, 0x39, 0x5b, 0x4b, 0x3a, 0x5d, 0x4a,
+ 0x3c, 0x5e, 0x4b, 0x3c, 0x5e, 0x4f, 0x3b, 0x5e, 0x4f, 0x3b, 0x5f, 0x4e,
+ 0x3a, 0x5f, 0x4b, 0x48, 0x61, 0x57, 0x77, 0x7c, 0x77, 0x9b, 0xc2, 0x87,
+ 0x9b, 0xf5, 0x65, 0x77, 0xff, 0x34, 0x4b, 0xe4, 0x40, 0x46, 0xd1, 0x43,
+ 0x40, 0xef, 0x42, 0x47, 0xda, 0x43, 0x40, 0xb2, 0x3b, 0x2e, 0xa4, 0x38,
+ 0x26, 0xce, 0x40, 0x36, 0xec, 0x38, 0x3b, 0xe8, 0x4d, 0x45, 0xd6, 0x50,
+ 0x41, 0xc2, 0x36, 0x28, 0xcf, 0x34, 0x2a, 0xe4, 0x36, 0x30, 0xee, 0x31,
+ 0x2f, 0xf2, 0x31, 0x39, 0xfa, 0x2d, 0x3c, 0xf5, 0x2a, 0x3c, 0xf0, 0x2d,
+ 0x48, 0xf9, 0x2e, 0x57, 0xf8, 0x51, 0x63, 0xfe, 0x5c, 0x6d, 0xee, 0x38,
+ 0x4f, 0xd5, 0x30, 0x35, 0xb8, 0x37, 0x26, 0xcc, 0x43, 0x36, 0xe2, 0x53,
+ 0x4e, 0xd7, 0x43, 0x40, 0xcb, 0x39, 0x2e, 0xc2, 0x37, 0x24, 0xa7, 0x3b,
+ 0x25, 0xac, 0x38, 0x29, 0xd3, 0x46, 0x42, 0xde, 0x38, 0x33, 0xf2, 0x33,
+ 0x31, 0xfa, 0x30, 0x30, 0xe5, 0x39, 0x31, 0xbe, 0x34, 0x27, 0xd9, 0x5c,
+ 0x57, 0xff, 0x87, 0x8b, 0xfc, 0x7c, 0x84, 0xfc, 0x6b, 0x7c, 0xfb, 0x48,
+ 0x61, 0xf3, 0x3e, 0x55, 0x59, 0x61, 0x37, 0x65, 0x80, 0x4e, 0x81, 0x8b,
+ 0x64, 0x7e, 0x9d, 0x6d, 0x7f, 0xab, 0x70, 0x88, 0xab, 0x6f, 0x87, 0xb1,
+ 0x70, 0x82, 0xb9, 0x6f, 0x85, 0xaa, 0x71, 0xb5, 0xb6, 0x99, 0xc3, 0xbf,
+ 0xbe, 0x5c, 0x4b, 0x37, 0x5c, 0x4b, 0x36, 0x5c, 0x4b, 0x36, 0x5d, 0x4c,
+ 0x37, 0x5d, 0x4c, 0x39, 0x5d, 0x4c, 0x3b, 0x5e, 0x4d, 0x3d, 0x5d, 0x50,
+ 0x3d, 0x5d, 0x50, 0x3d, 0x61, 0x4d, 0x3a, 0x63, 0x47, 0x3e, 0x67, 0x5d,
+ 0x71, 0x7f, 0x86, 0xb5, 0xb3, 0x87, 0xa6, 0xf6, 0x75, 0x71, 0xff, 0x4b,
+ 0x55, 0xf3, 0x3f, 0x51, 0xe7, 0x3d, 0x47, 0xdb, 0x3c, 0x3d, 0xc7, 0x3e,
+ 0x34, 0xa9, 0x3b, 0x2a, 0xb4, 0x3e, 0x2f, 0xd1, 0x38, 0x33, 0xde, 0x33,
+ 0x2b, 0xdb, 0x39, 0x27, 0xe9, 0x4d, 0x41, 0xd2, 0x41, 0x33, 0xd3, 0x3a,
+ 0x2e, 0xec, 0x37, 0x39, 0xf7, 0x32, 0x3e, 0xfc, 0x22, 0x2f, 0xff, 0x20,
+ 0x2d, 0xf6, 0x21, 0x2b, 0xee, 0x25, 0x37, 0xf7, 0x3b, 0x56, 0xff, 0x63,
+ 0x70, 0xf1, 0x4e, 0x53, 0xcb, 0x3a, 0x35, 0xa1, 0x36, 0x24, 0x87, 0x2d,
+ 0x18, 0xad, 0x3a, 0x30, 0xc2, 0x38, 0x36, 0xd8, 0x49, 0x45, 0xc9, 0x3b,
+ 0x30, 0xc7, 0x38, 0x2b, 0xb4, 0x38, 0x2b, 0xc1, 0x38, 0x2f, 0xde, 0x4a,
+ 0x40, 0xe2, 0x33, 0x2e, 0xfc, 0x2e, 0x31, 0xfa, 0x2d, 0x30, 0xf0, 0x32,
+ 0x2c, 0xc9, 0x34, 0x25, 0xc5, 0x4d, 0x45, 0xff, 0x8f, 0x90, 0xff, 0x7b,
+ 0x88, 0xff, 0x59, 0x74, 0xff, 0x3f, 0x61, 0xd2, 0x40, 0x53, 0x49, 0x59,
+ 0x31, 0x70, 0x95, 0x5b, 0x85, 0xa6, 0x6f, 0x83, 0xaa, 0x71, 0x7c, 0xa5,
+ 0x66, 0x7e, 0xa3, 0x66, 0x7f, 0xa8, 0x6b, 0x7e, 0xb0, 0x65, 0x86, 0xb2,
+ 0x6e, 0x9c, 0xb6, 0x89, 0x96, 0xa4, 0x97, 0x5e, 0x4d, 0x3a, 0x5e, 0x4d,
+ 0x3a, 0x5e, 0x4d, 0x3a, 0x5e, 0x4d, 0x3a, 0x5e, 0x4d, 0x3a, 0x5f, 0x4c,
+ 0x37, 0x5e, 0x4e, 0x39, 0x56, 0x4e, 0x41, 0x61, 0x58, 0x59, 0x6f, 0x60,
+ 0x6d, 0x6d, 0x64, 0x70, 0x70, 0x78, 0xa8, 0x83, 0x8c, 0xea, 0x99, 0x83,
+ 0xcd, 0xb9, 0x76, 0x7c, 0xe8, 0x64, 0x5c, 0xfd, 0x4d, 0x55, 0xf2, 0x39,
+ 0x41, 0xde, 0x37, 0x37, 0xc3, 0x42, 0x32, 0xa9, 0x3a, 0x2b, 0xbd, 0x47,
+ 0x3e, 0xc5, 0x42, 0x39, 0xca, 0x36, 0x2b, 0xde, 0x36, 0x27, 0xe3, 0x34,
+ 0x2e, 0xe0, 0x44, 0x37, 0xdc, 0x3c, 0x2e, 0xf0, 0x30, 0x33, 0xff, 0x44,
+ 0x4e, 0xf5, 0x43, 0x47, 0xe6, 0x2f, 0x2d, 0xe1, 0x2c, 0x28, 0xde, 0x32,
+ 0x33, 0xdf, 0x3e, 0x43, 0xd9, 0x3f, 0x43, 0xdc, 0x37, 0x38, 0xca, 0x33,
+ 0x2e, 0xd2, 0x4f, 0x4a, 0xd4, 0x4f, 0x51, 0xca, 0x49, 0x47, 0xe9, 0x55,
+ 0x55, 0xda, 0x45, 0x41, 0xd4, 0x42, 0x3a, 0xde, 0x3c, 0x37, 0xf3, 0x32,
+ 0x3d, 0xf5, 0x37, 0x3f, 0xe8, 0x3e, 0x3a, 0xdc, 0x31, 0x2a, 0xf3, 0x32,
+ 0x30, 0xf8, 0x2e, 0x32, 0xf3, 0x30, 0x2e, 0xcd, 0x34, 0x25, 0xba, 0x48,
+ 0x3c, 0xff, 0x93, 0x95, 0xfd, 0x71, 0x81, 0xff, 0x46, 0x68, 0xff, 0x3c,
+ 0x64, 0x9d, 0x41, 0x47, 0x4e, 0x62, 0x3c, 0x72, 0x96, 0x5a, 0x79, 0xa1,
+ 0x63, 0x75, 0x9f, 0x60, 0x76, 0x9d, 0x5f, 0x7a, 0xa1, 0x64, 0x7b, 0xa6,
+ 0x64, 0x7b, 0xa9, 0x5a, 0x87, 0xb3, 0x68, 0x89, 0xaa, 0x76, 0x6c, 0x82,
+ 0x67, 0x5f, 0x4f, 0x3d, 0x5f, 0x4f, 0x3f, 0x5f, 0x4f, 0x3e, 0x5f, 0x4f,
+ 0x3d, 0x5f, 0x4f, 0x3d, 0x60, 0x50, 0x37, 0x5c, 0x4c, 0x39, 0x5f, 0x5b,
+ 0x61, 0x7d, 0x7c, 0xa0, 0x81, 0x7d, 0xb2, 0x71, 0x76, 0xb8, 0x7c, 0x86,
+ 0xc6, 0x9a, 0x9b, 0xc7, 0xba, 0xaf, 0xb7, 0xc8, 0xb6, 0x96, 0xb2, 0x70,
+ 0x52, 0xc6, 0x4c, 0x41, 0xf0, 0x48, 0x4a, 0xe8, 0x37, 0x39, 0xd5, 0x3a,
+ 0x32, 0xbb, 0x37, 0x2e, 0xba, 0x49, 0x3f, 0xcd, 0x66, 0x58, 0xc1, 0x40,
+ 0x33, 0xda, 0x32, 0x2b, 0xe4, 0x31, 0x2c, 0xe1, 0x3d, 0x31, 0xe4, 0x37,
+ 0x29, 0xf0, 0x2d, 0x29, 0xf0, 0x35, 0x35, 0xf1, 0x52, 0x58, 0xea, 0x4a,
+ 0x51, 0xeb, 0x51, 0x56, 0xec, 0x56, 0x5b, 0xd5, 0x40, 0x42, 0xea, 0x39,
+ 0x3f, 0xeb, 0x2d, 0x37, 0xf2, 0x4a, 0x56, 0xff, 0x6f, 0x7a, 0xff, 0x66,
+ 0x76, 0xe7, 0x52, 0x4e, 0xd7, 0x35, 0x33, 0xdc, 0x41, 0x3c, 0xdc, 0x45,
+ 0x3c, 0xe0, 0x34, 0x30, 0xfc, 0x2c, 0x3a, 0xff, 0x35, 0x3f, 0xe7, 0x36,
+ 0x33, 0xdd, 0x34, 0x2a, 0xf0, 0x32, 0x2f, 0xfb, 0x2e, 0x32, 0xf5, 0x2f,
+ 0x2d, 0xd3, 0x35, 0x29, 0xb2, 0x3c, 0x33, 0xfe, 0x88, 0x8f, 0xf8, 0x62,
+ 0x77, 0xff, 0x3e, 0x63, 0xf4, 0x41, 0x64, 0x5c, 0x3b, 0x2f, 0x4c, 0x5f,
+ 0x3e, 0x75, 0x91, 0x5e, 0x7b, 0x9e, 0x63, 0x6f, 0x97, 0x57, 0x72, 0x9a,
+ 0x58, 0x78, 0x9e, 0x5e, 0x79, 0xa3, 0x5b, 0x77, 0xa6, 0x56, 0x80, 0xab,
+ 0x61, 0x80, 0x9f, 0x68, 0x65, 0x7c, 0x56, 0x5b, 0x4d, 0x3d, 0x5f, 0x50,
+ 0x40, 0x5f, 0x52, 0x42, 0x60, 0x52, 0x43, 0x60, 0x52, 0x40, 0x5c, 0x4f,
+ 0x42, 0x63, 0x59, 0x61, 0x77, 0x77, 0x9a, 0x77, 0x7c, 0xb9, 0x63, 0x6a,
+ 0xb4, 0x7a, 0x7a, 0xd6, 0xaf, 0xac, 0xdb, 0xe4, 0xe1, 0xb6, 0xf8, 0xf2,
+ 0xa4, 0xeb, 0xe8, 0xab, 0xb8, 0xb5, 0x91, 0xa0, 0x79, 0x64, 0xd6, 0x6c,
+ 0x67, 0xf6, 0x57, 0x5a, 0xea, 0x36, 0x3a, 0xda, 0x36, 0x33, 0xbd, 0x3a,
+ 0x31, 0xbb, 0x4f, 0x41, 0xd3, 0x58, 0x49, 0xd0, 0x31, 0x27, 0xe8, 0x3e,
+ 0x3c, 0xe2, 0x40, 0x37, 0xe0, 0x30, 0x25, 0xe9, 0x2d, 0x27, 0xdb, 0x33,
+ 0x2a, 0xcf, 0x39, 0x35, 0xee, 0x53, 0x57, 0xf5, 0x56, 0x62, 0xff, 0x64,
+ 0x6f, 0xfb, 0x61, 0x67, 0xf6, 0x2f, 0x37, 0xf6, 0x28, 0x36, 0xf7, 0x46,
+ 0x53, 0xfa, 0x5e, 0x66, 0xf7, 0x54, 0x5b, 0xdf, 0x37, 0x33, 0xe6, 0x36,
+ 0x34, 0xdd, 0x38, 0x32, 0xd6, 0x38, 0x30, 0xe4, 0x3a, 0x35, 0xe7, 0x3b,
+ 0x3b, 0xe8, 0x36, 0x35, 0xd8, 0x35, 0x2b, 0xe2, 0x36, 0x2a, 0xf3, 0x30,
+ 0x2d, 0xfa, 0x2f, 0x34, 0xf6, 0x30, 0x2f, 0xda, 0x39, 0x2e, 0xb9, 0x38,
+ 0x32, 0xfc, 0x77, 0x82, 0xff, 0x52, 0x70, 0xff, 0x3c, 0x64, 0xc1, 0x4a,
+ 0x5b, 0x3d, 0x3c, 0x26, 0x41, 0x4a, 0x30, 0x68, 0x7e, 0x53, 0x74, 0x94,
+ 0x58, 0x68, 0x92, 0x4c, 0x6d, 0x96, 0x51, 0x73, 0x9b, 0x5a, 0x73, 0x9d,
+ 0x54, 0x6c, 0x97, 0x4d, 0x62, 0x8a, 0x45, 0x4e, 0x6a, 0x34, 0x49, 0x61,
+ 0x34, 0x54, 0x48, 0x38, 0x59, 0x4c, 0x3c, 0x5f, 0x52, 0x42, 0x62, 0x56,
+ 0x44, 0x60, 0x53, 0x3f, 0x66, 0x5d, 0x62, 0x7b, 0x79, 0x9e, 0x74, 0x7a,
+ 0xb4, 0x5d, 0x66, 0xaf, 0x6c, 0x76, 0xc1, 0x98, 0x9d, 0xdf, 0xc1, 0xc4,
+ 0xe7, 0xd8, 0xd7, 0xd7, 0xd8, 0xd3, 0xc8, 0xc2, 0xb7, 0xbc, 0x83, 0x87,
+ 0x88, 0x6f, 0x6a, 0x65, 0x99, 0x6a, 0x64, 0xe3, 0x79, 0x75, 0xff, 0x67,
+ 0x65, 0xf4, 0x44, 0x41, 0xdd, 0x3d, 0x35, 0xc2, 0x3c, 0x31, 0xc7, 0x42,
+ 0x32, 0xd1, 0x3c, 0x2d, 0xe3, 0x47, 0x46, 0xe2, 0x49, 0x46, 0xe0, 0x37,
+ 0x30, 0xe3, 0x36, 0x30, 0xcb, 0x39, 0x2b, 0xba, 0x3a, 0x26, 0xc9, 0x3d,
+ 0x36, 0xd0, 0x3a, 0x41, 0xf3, 0x5b, 0x67, 0xeb, 0x57, 0x5e, 0xe0, 0x37,
+ 0x33, 0xf6, 0x42, 0x49, 0xea, 0x3f, 0x46, 0xe6, 0x37, 0x39, 0xf7, 0x35,
+ 0x36, 0xef, 0x35, 0x31, 0xee, 0x33, 0x30, 0xe1, 0x3a, 0x2f, 0xdf, 0x3b,
+ 0x33, 0xe8, 0x36, 0x35, 0xea, 0x37, 0x38, 0xe9, 0x36, 0x34, 0xdb, 0x36,
+ 0x2d, 0xe0, 0x37, 0x28, 0xef, 0x31, 0x2b, 0xf4, 0x33, 0x35, 0xf4, 0x30,
+ 0x2f, 0xdb, 0x34, 0x2a, 0xd1, 0x44, 0x42, 0xfa, 0x68, 0x75, 0xff, 0x3b,
+ 0x64, 0xfe, 0x40, 0x68, 0x80, 0x4d, 0x47, 0x52, 0x50, 0x3c, 0x45, 0x42,
+ 0x2d, 0x4f, 0x5f, 0x39, 0x69, 0x87, 0x4c, 0x65, 0x8e, 0x44, 0x67, 0x91,
+ 0x4b, 0x6e, 0x95, 0x55, 0x68, 0x8f, 0x4c, 0x5e, 0x87, 0x45, 0x59, 0x7d,
+ 0x43, 0x57, 0x6f, 0x42, 0x5b, 0x73, 0x44, 0x44, 0x42, 0x36, 0x4a, 0x45,
+ 0x3c, 0x5c, 0x4d, 0x3e, 0x60, 0x53, 0x3e, 0x65, 0x5f, 0x58, 0x7a, 0x74,
+ 0x91, 0x73, 0x70, 0xa7, 0x5d, 0x5f, 0xa1, 0x69, 0x69, 0xbb, 0x8b, 0x88,
+ 0xdf, 0x9d, 0x9d, 0xde, 0xa2, 0xa1, 0xd6, 0xa0, 0x9b, 0xd6, 0x9e, 0x96,
+ 0xce, 0x95, 0x89, 0xc1, 0x70, 0x67, 0x7d, 0x5e, 0x56, 0x52, 0x7c, 0x53,
+ 0x48, 0xb8, 0x59, 0x51, 0xec, 0x79, 0x73, 0xff, 0x80, 0x7c, 0xef, 0x5e,
+ 0x5a, 0xc9, 0x36, 0x2d, 0xbe, 0x35, 0x23, 0xca, 0x3b, 0x2a, 0xd5, 0x3a,
+ 0x30, 0xcf, 0x37, 0x2c, 0xdc, 0x39, 0x2f, 0xdc, 0x38, 0x2f, 0xc5, 0x3c,
+ 0x2a, 0xc2, 0x40, 0x31, 0xc5, 0x3d, 0x34, 0xc1, 0x37, 0x33, 0xd9, 0x50,
+ 0x4c, 0xd2, 0x4b, 0x42, 0xcc, 0x36, 0x24, 0xeb, 0x2f, 0x30, 0xf8, 0x28,
+ 0x3a, 0xfc, 0x27, 0x3f, 0xff, 0x1f, 0x3a, 0xff, 0x23, 0x38, 0xf3, 0x2e,
+ 0x36, 0xdf, 0x3a, 0x35, 0xe0, 0x3c, 0x35, 0xea, 0x37, 0x35, 0xee, 0x33,
+ 0x35, 0xe4, 0x34, 0x30, 0xdb, 0x37, 0x29, 0xdc, 0x39, 0x26, 0xe5, 0x36,
+ 0x26, 0xef, 0x35, 0x2d, 0xed, 0x35, 0x29, 0xd7, 0x34, 0x27, 0xed, 0x56,
+ 0x5c, 0xff, 0x50, 0x6b, 0xff, 0x38, 0x65, 0xcd, 0x40, 0x58, 0x39, 0x35,
+ 0x23, 0x41, 0x42, 0x33, 0x37, 0x38, 0x21, 0x51, 0x5a, 0x34, 0x64, 0x79,
+ 0x4e, 0x5f, 0x84, 0x41, 0x63, 0x8c, 0x44, 0x6c, 0x90, 0x4e, 0x68, 0x8d,
+ 0x47, 0x63, 0x86, 0x49, 0x63, 0x82, 0x4a, 0x66, 0x7f, 0x49, 0x62, 0x7f,
+ 0x44, 0x34, 0x37, 0x2d, 0x3a, 0x3a, 0x34, 0x4f, 0x44, 0x3b, 0x56, 0x4c,
+ 0x3d, 0x67, 0x65, 0x6c, 0x6c, 0x6a, 0x91, 0x51, 0x51, 0x8a, 0x5b, 0x5d,
+ 0xa5, 0x79, 0x7b, 0xce, 0x89, 0x89, 0xdd, 0x8c, 0x8b, 0xd1, 0x88, 0x85,
+ 0xcd, 0x88, 0x81, 0xd2, 0x8d, 0x85, 0xc8, 0x87, 0x82, 0xad, 0x7e, 0x5a,
+ 0x6a, 0x5c, 0x5b, 0x4c, 0x70, 0x57, 0x44, 0xcf, 0x53, 0x56, 0xe7, 0x66,
+ 0x6b, 0xef, 0x85, 0x7f, 0xfe, 0x81, 0x7a, 0xc5, 0x3b, 0x2d, 0xbb, 0x3b,
+ 0x23, 0xc6, 0x3b, 0x29, 0xd6, 0x36, 0x2b, 0xcc, 0x3b, 0x2b, 0xcb, 0x36,
+ 0x28, 0xd6, 0x3a, 0x2d, 0xc8, 0x38, 0x28, 0xc5, 0x3a, 0x2d, 0xc8, 0x3a,
+ 0x2f, 0xca, 0x3a, 0x30, 0xce, 0x3f, 0x35, 0xc8, 0x3a, 0x2e, 0xd6, 0x31,
+ 0x27, 0xf9, 0x2f, 0x37, 0xff, 0x2b, 0x3d, 0xfa, 0x2a, 0x3e, 0xfe, 0x24,
+ 0x3a, 0xff, 0x26, 0x39, 0xf0, 0x35, 0x3d, 0xda, 0x3a, 0x36, 0xdf, 0x3b,
+ 0x34, 0xeb, 0x35, 0x34, 0xf1, 0x34, 0x38, 0xe2, 0x36, 0x2f, 0xd5, 0x37,
+ 0x29, 0xd9, 0x38, 0x26, 0xda, 0x36, 0x24, 0xd7, 0x39, 0x26, 0xd4, 0x3b,
+ 0x25, 0xd7, 0x3d, 0x34, 0xfe, 0x57, 0x6c, 0xff, 0x37, 0x63, 0xfc, 0x43,
+ 0x6a, 0x6b, 0x33, 0x3d, 0x23, 0x2f, 0x25, 0x2f, 0x34, 0x1d, 0x5e, 0x59,
+ 0x32, 0xa0, 0xb3, 0x82, 0x73, 0x8d, 0x60, 0x5d, 0x83, 0x3e, 0x6d, 0x93,
+ 0x4b, 0x70, 0x95, 0x51, 0x6b, 0x8f, 0x48, 0x69, 0x8b, 0x4d, 0x65, 0x84,
+ 0x4a, 0x66, 0x83, 0x48, 0x67, 0x89, 0x47, 0x2a, 0x30, 0x26, 0x2b, 0x30,
+ 0x2b, 0x39, 0x37, 0x35, 0x45, 0x43, 0x3d, 0x5a, 0x5c, 0x69, 0x5c, 0x5d,
+ 0x87, 0x5b, 0x5a, 0x9c, 0x79, 0x7c, 0xd6, 0x85, 0x88, 0xeb, 0x82, 0x82,
+ 0xda, 0x81, 0x85, 0xca, 0x83, 0x82, 0xd2, 0x8b, 0x82, 0xdb, 0x8d, 0x86,
+ 0xc2, 0x7e, 0x78, 0x89, 0x73, 0x57, 0x52, 0x60, 0x5f, 0x48, 0x64, 0x5f,
+ 0x43, 0xae, 0x57, 0x50, 0xec, 0x5a, 0x63, 0xf3, 0x6e, 0x6a, 0xd9, 0x4b,
+ 0x40, 0xc9, 0x37, 0x26, 0xc8, 0x3c, 0x27, 0xd6, 0x38, 0x2b, 0xd5, 0x31,
+ 0x28, 0xc5, 0x3e, 0x2b, 0xbf, 0x3a, 0x28, 0xdb, 0x47, 0x3b, 0xce, 0x39,
+ 0x2b, 0xc9, 0x3a, 0x29, 0xc8, 0x37, 0x28, 0xce, 0x37, 0x28, 0xd7, 0x3c,
+ 0x2f, 0xda, 0x3b, 0x30, 0xee, 0x36, 0x3b, 0xf9, 0x31, 0x3f, 0xee, 0x2d,
+ 0x3b, 0xe9, 0x33, 0x36, 0xf5, 0x35, 0x38, 0xf0, 0x37, 0x3b, 0xe1, 0x36,
+ 0x35, 0xdb, 0x38, 0x35, 0xe3, 0x3a, 0x38, 0xef, 0x37, 0x38, 0xf6, 0x36,
+ 0x3b, 0xe2, 0x38, 0x34, 0xcf, 0x38, 0x2a, 0xcc, 0x3a, 0x29, 0xcd, 0x3a,
+ 0x27, 0xc2, 0x3d, 0x21, 0xc1, 0x3c, 0x26, 0xe9, 0x4b, 0x4d, 0xff, 0x42,
+ 0x67, 0xff, 0x36, 0x67, 0xa7, 0x43, 0x4f, 0x33, 0x36, 0x34, 0x38, 0x2b,
+ 0x2f, 0x44, 0x4e, 0x29, 0xa5, 0xb9, 0x79, 0xb6, 0xd5, 0x9a, 0x71, 0x90,
+ 0x5c, 0x5d, 0x84, 0x3d, 0x72, 0x98, 0x4e, 0x6f, 0x94, 0x52, 0x66, 0x8a,
+ 0x45, 0x67, 0x89, 0x4d, 0x65, 0x88, 0x4b, 0x66, 0x89, 0x47, 0x6b, 0x91,
+ 0x4a, 0x2e, 0x32, 0x26, 0x2b, 0x2e, 0x28, 0x30, 0x31, 0x2b, 0x3a, 0x3d,
+ 0x30, 0x4c, 0x4f, 0x4e, 0x58, 0x56, 0x6d, 0x6e, 0x6c, 0x9f, 0x92, 0x8f,
+ 0xea, 0x93, 0x90, 0xf6, 0x81, 0x7f, 0xd1, 0x84, 0x84, 0xc7, 0x8d, 0x8d,
+ 0xce, 0x8e, 0x85, 0xbf, 0x81, 0x77, 0x93, 0x6c, 0x61, 0x5d, 0x5e, 0x5d,
+ 0x47, 0x66, 0x5d, 0x49, 0x6a, 0x5c, 0x45, 0x88, 0x59, 0x43, 0xe6, 0x52,
+ 0x51, 0xeb, 0x3d, 0x3d, 0xdc, 0x30, 0x2b, 0xdb, 0x37, 0x26, 0xd3, 0x37,
+ 0x26, 0xe1, 0x35, 0x2b, 0xc8, 0x35, 0x29, 0xbd, 0x3d, 0x2b, 0xc5, 0x3c,
+ 0x2b, 0xda, 0x44, 0x39, 0xc2, 0x38, 0x29, 0xc4, 0x3a, 0x28, 0xca, 0x39,
+ 0x28, 0xcf, 0x34, 0x28, 0xd8, 0x32, 0x29, 0xe7, 0x3b, 0x34, 0xf1, 0x38,
+ 0x3c, 0xec, 0x2f, 0x3a, 0xec, 0x45, 0x4a, 0xef, 0x56, 0x51, 0xea, 0x41,
+ 0x3d, 0xe1, 0x38, 0x32, 0xdf, 0x38, 0x34, 0xe2, 0x38, 0x38, 0xe8, 0x38,
+ 0x3c, 0xed, 0x37, 0x3c, 0xef, 0x35, 0x39, 0xdc, 0x3b, 0x36, 0xc0, 0x38,
+ 0x29, 0xba, 0x3d, 0x2a, 0xba, 0x3d, 0x2a, 0xb1, 0x39, 0x23, 0xb6, 0x35,
+ 0x29, 0xff, 0x50, 0x60, 0xfd, 0x3d, 0x5f, 0xcb, 0x49, 0x5d, 0x4b, 0x40,
+ 0x31, 0x2d, 0x33, 0x25, 0x4a, 0x33, 0x27, 0x86, 0x98, 0x65, 0xa8, 0xd4,
+ 0x8c, 0x8f, 0xaa, 0x7c, 0x4b, 0x63, 0x39, 0x60, 0x7f, 0x3d, 0x6c, 0x94,
+ 0x49, 0x64, 0x8c, 0x47, 0x65, 0x87, 0x43, 0x6b, 0x8e, 0x4f, 0x69, 0x90,
+ 0x4f, 0x66, 0x8f, 0x45, 0x70, 0x9b, 0x50, 0x40, 0x3e, 0x30, 0x3e, 0x3d,
+ 0x34, 0x3c, 0x3d, 0x32, 0x41, 0x45, 0x2a, 0x4c, 0x4d, 0x3a, 0x55, 0x54,
+ 0x41, 0x65, 0x63, 0x67, 0x84, 0x81, 0xb7, 0x91, 0x8c, 0xd4, 0x7f, 0x7a,
+ 0xaf, 0x77, 0x73, 0xa5, 0x7f, 0x7a, 0xa4, 0x79, 0x6f, 0x7f, 0x6e, 0x5f,
+ 0x57, 0x6c, 0x59, 0x47, 0x68, 0x5c, 0x4b, 0x6a, 0x5e, 0x4e, 0x7f, 0x5f,
+ 0x4f, 0xa5, 0x4b, 0x3c, 0xd8, 0x35, 0x2e, 0xe3, 0x30, 0x2b, 0xe2, 0x34,
+ 0x2a, 0xd7, 0x38, 0x24, 0xca, 0x3d, 0x24, 0xd7, 0x39, 0x2c, 0xb9, 0x3b,
+ 0x29, 0xb5, 0x37, 0x26, 0xd7, 0x3d, 0x35, 0xe7, 0x49, 0x42, 0xb3, 0x39,
+ 0x27, 0xba, 0x3a, 0x29, 0xc7, 0x39, 0x2d, 0xd6, 0x3c, 0x34, 0xe3, 0x3b,
+ 0x37, 0xea, 0x3a, 0x38, 0xe9, 0x38, 0x36, 0xf4, 0x48, 0x49, 0xe9, 0x5a,
+ 0x58, 0xcd, 0x43, 0x3d, 0xda, 0x3a, 0x37, 0xdf, 0x39, 0x32, 0xe4, 0x38,
+ 0x34, 0xea, 0x36, 0x38, 0xec, 0x38, 0x3e, 0xeb, 0x36, 0x3d, 0xec, 0x37,
+ 0x3b, 0xd6, 0x3f, 0x37, 0xb6, 0x3b, 0x2b, 0xa7, 0x3b, 0x27, 0xa4, 0x3b,
+ 0x28, 0x96, 0x36, 0x23, 0xc0, 0x49, 0x44, 0xfc, 0x55, 0x68, 0xd2, 0x4d,
+ 0x58, 0x82, 0x5d, 0x4f, 0x33, 0x39, 0x22, 0x46, 0x4f, 0x29, 0x75, 0x9c,
+ 0x5f, 0x92, 0xa5, 0x69, 0x88, 0x9b, 0x6a, 0x49, 0x54, 0x3c, 0x3c, 0x48,
+ 0x2c, 0x67, 0x7e, 0x43, 0x6a, 0x94, 0x46, 0x61, 0x8c, 0x45, 0x6b, 0x8c,
+ 0x4b, 0x6c, 0x91, 0x50, 0x6f, 0x96, 0x51, 0x6d, 0x99, 0x4d, 0x76, 0xa5,
+ 0x56, 0x55, 0x4d, 0x3e, 0x56, 0x4d, 0x3f, 0x56, 0x4e, 0x3f, 0x56, 0x50,
+ 0x3d, 0x5c, 0x52, 0x43, 0x60, 0x57, 0x42, 0x62, 0x59, 0x4b, 0x6d, 0x63,
+ 0x6b, 0x77, 0x6a, 0x7c, 0x70, 0x64, 0x6d, 0x5d, 0x57, 0x5b, 0x57, 0x55,
+ 0x52, 0x5d, 0x56, 0x47, 0x66, 0x5a, 0x46, 0x6e, 0x5f, 0x48, 0x6a, 0x64,
+ 0x4f, 0x88, 0x5a, 0x4f, 0xad, 0x52, 0x47, 0xae, 0x3a, 0x2c, 0xcb, 0x34,
+ 0x2b, 0xe1, 0x37, 0x2f, 0xde, 0x37, 0x2e, 0xd7, 0x36, 0x2a, 0xd3, 0x39,
+ 0x29, 0xd5, 0x3a, 0x2c, 0xb8, 0x3c, 0x2b, 0xa7, 0x35, 0x22, 0xc2, 0x39,
+ 0x2d, 0xd7, 0x3c, 0x34, 0xd3, 0x48, 0x3a, 0xd4, 0x42, 0x39, 0xd8, 0x3e,
+ 0x39, 0xe7, 0x3c, 0x3c, 0xee, 0x36, 0x38, 0xe5, 0x3b, 0x38, 0xc5, 0x3d,
+ 0x32, 0xb7, 0x39, 0x2a, 0xbd, 0x3b, 0x2d, 0xd6, 0x3c, 0x35, 0xed, 0x36,
+ 0x3a, 0xe8, 0x36, 0x3a, 0xe6, 0x38, 0x36, 0xe5, 0x39, 0x32, 0xe6, 0x39,
+ 0x36, 0xe8, 0x38, 0x38, 0xe7, 0x3b, 0x3d, 0xcb, 0x40, 0x38, 0xa7, 0x3b,
+ 0x2c, 0x99, 0x3b, 0x28, 0x8d, 0x38, 0x24, 0x84, 0x36, 0x27, 0xcc, 0x59,
+ 0x5a, 0xbc, 0x54, 0x56, 0x9e, 0x59, 0x52, 0x80, 0x63, 0x4b, 0x60, 0x78,
+ 0x3b, 0x9d, 0xb6, 0x71, 0x76, 0x98, 0x59, 0x4f, 0x5d, 0x3b, 0x3b, 0x3d,
+ 0x2e, 0x32, 0x33, 0x2b, 0x3b, 0x43, 0x31, 0x66, 0x7f, 0x47, 0x6f, 0x97,
+ 0x4a, 0x6a, 0x92, 0x4d, 0x6d, 0x93, 0x52, 0x6a, 0x94, 0x47, 0x71, 0x9e,
+ 0x4b, 0x78, 0xaa, 0x55, 0x71, 0x9f, 0x57, 0x63, 0x5a, 0x4b, 0x65, 0x5b,
+ 0x4b, 0x65, 0x5b, 0x4b, 0x64, 0x5b, 0x4c, 0x65, 0x5b, 0x4d, 0x67, 0x5f,
+ 0x4a, 0x68, 0x5f, 0x48, 0x67, 0x5e, 0x4d, 0x67, 0x5d, 0x4c, 0x66, 0x5c,
+ 0x49, 0x60, 0x5a, 0x47, 0x51, 0x4e, 0x3d, 0x4c, 0x48, 0x37, 0x53, 0x50,
+ 0x3e, 0x5b, 0x5a, 0x46, 0x5f, 0x5f, 0x4f, 0x96, 0x61, 0x59, 0xd1, 0x4a,
+ 0x4c, 0xd3, 0x34, 0x30, 0xb7, 0x3d, 0x29, 0xcd, 0x3a, 0x2a, 0xda, 0x39,
+ 0x2b, 0xd5, 0x38, 0x2a, 0xd5, 0x37, 0x2a, 0xd5, 0x3a, 0x2b, 0xbc, 0x3d,
+ 0x2f, 0x97, 0x35, 0x1e, 0xaa, 0x3f, 0x29, 0xc1, 0x37, 0x2a, 0xd1, 0x39,
+ 0x2f, 0xe9, 0x34, 0x39, 0xe8, 0x36, 0x3c, 0xed, 0x36, 0x3b, 0xef, 0x35,
+ 0x3c, 0xd6, 0x36, 0x34, 0xad, 0x38, 0x26, 0xa7, 0x39, 0x26, 0xb5, 0x3a,
+ 0x29, 0xd7, 0x3e, 0x34, 0xee, 0x39, 0x38, 0xf2, 0x36, 0x37, 0xeb, 0x38,
+ 0x35, 0xe5, 0x3c, 0x33, 0xe0, 0x3e, 0x39, 0xda, 0x3e, 0x3e, 0xc9, 0x40,
+ 0x3b, 0xa9, 0x38, 0x2b, 0x95, 0x3a, 0x28, 0x8d, 0x3a, 0x28, 0x81, 0x37,
+ 0x22, 0x7e, 0x3a, 0x2a, 0xa6, 0x52, 0x4a, 0x95, 0x54, 0x49, 0x8f, 0x5c,
+ 0x53, 0x96, 0x6e, 0x5d, 0x8e, 0xa1, 0x73, 0x53, 0x63, 0x42, 0x27, 0x32,
+ 0x1e, 0x35, 0x38, 0x31, 0x37, 0x36, 0x2f, 0x39, 0x39, 0x30, 0x39, 0x43,
+ 0x30, 0x67, 0x82, 0x4b, 0x77, 0x9c, 0x51, 0x70, 0x99, 0x53, 0x70, 0x98,
+ 0x4f, 0x6f, 0x99, 0x49, 0x78, 0xa6, 0x55, 0x77, 0xa6, 0x59, 0x60, 0x8b,
+ 0x4a, 0x68, 0x5f, 0x50, 0x69, 0x60, 0x51, 0x69, 0x60, 0x51, 0x69, 0x60,
+ 0x51, 0x68, 0x5f, 0x50, 0x6b, 0x62, 0x54, 0x6a, 0x62, 0x53, 0x69, 0x60,
+ 0x50, 0x69, 0x62, 0x4c, 0x69, 0x62, 0x48, 0x68, 0x62, 0x4b, 0x60, 0x5a,
+ 0x46, 0x4c, 0x4a, 0x36, 0x40, 0x45, 0x34, 0x40, 0x48, 0x38, 0x43, 0x4a,
+ 0x3e, 0x55, 0x4d, 0x3b, 0xb6, 0x58, 0x4f, 0xef, 0x44, 0x46, 0xc8, 0x3a,
+ 0x2c, 0xc3, 0x37, 0x25, 0xd2, 0x38, 0x29, 0xd1, 0x3a, 0x29, 0xd1, 0x3a,
+ 0x28, 0xd2, 0x39, 0x29, 0xbb, 0x3b, 0x2f, 0x91, 0x36, 0x1e, 0x94, 0x39,
+ 0x1f, 0xbb, 0x38, 0x2a, 0xda, 0x3b, 0x35, 0xee, 0x40, 0x45, 0xd3, 0x3e,
+ 0x3b, 0xbb, 0x36, 0x31, 0xb7, 0x3a, 0x35, 0xa2, 0x39, 0x2d, 0x9d, 0x3e,
+ 0x2a, 0x9f, 0x41, 0x2b, 0xa5, 0x3c, 0x27, 0xb7, 0x36, 0x29, 0xd3, 0x3c,
+ 0x35, 0xec, 0x3d, 0x37, 0xeb, 0x3f, 0x36, 0xdf, 0x44, 0x39, 0xca, 0x41,
+ 0x39, 0xb2, 0x38, 0x33, 0x98, 0x38, 0x2a, 0x8c, 0x38, 0x27, 0x84, 0x3c,
+ 0x29, 0x7d, 0x3b, 0x28, 0x77, 0x33, 0x22, 0x89, 0x41, 0x33, 0x94, 0x53,
+ 0x47, 0x91, 0x5a, 0x4e, 0x96, 0x59, 0x53, 0x89, 0x59, 0x4d, 0x41, 0x4d,
+ 0x2b, 0x27, 0x32, 0x25, 0x37, 0x3e, 0x3c, 0x4b, 0x4d, 0x40, 0x3d, 0x3b,
+ 0x28, 0x37, 0x3a, 0x2f, 0x38, 0x40, 0x2d, 0x68, 0x82, 0x4b, 0x76, 0x9d,
+ 0x50, 0x71, 0x9b, 0x50, 0x70, 0x9d, 0x4a, 0x79, 0xa4, 0x56, 0x7d, 0xa8,
+ 0x62, 0x62, 0x8c, 0x49, 0x60, 0x88, 0x4c, 0x69, 0x60, 0x51, 0x69, 0x60,
+ 0x51, 0x69, 0x60, 0x51, 0x6a, 0x61, 0x52, 0x6a, 0x61, 0x51, 0x6b, 0x5f,
+ 0x5a, 0x6b, 0x5f, 0x5f, 0x6b, 0x61, 0x56, 0x6b, 0x61, 0x54, 0x6b, 0x61,
+ 0x58, 0x6c, 0x61, 0x52, 0x6b, 0x62, 0x4e, 0x5a, 0x56, 0x44, 0x44, 0x46,
+ 0x38, 0x3c, 0x43, 0x35, 0x35, 0x43, 0x31, 0x3f, 0x43, 0x29, 0x96, 0x5a,
+ 0x46, 0xe6, 0x5d, 0x59, 0xf0, 0x4a, 0x4d, 0xcf, 0x3b, 0x30, 0xc8, 0x39,
+ 0x2b, 0xce, 0x3c, 0x30, 0xd2, 0x3d, 0x31, 0xd4, 0x3e, 0x32, 0xce, 0x40,
+ 0x3a, 0xb2, 0x3e, 0x33, 0xb8, 0x43, 0x33, 0xdb, 0x48, 0x41, 0xea, 0x49,
+ 0x45, 0xd1, 0x45, 0x41, 0xa0, 0x3d, 0x2f, 0x8e, 0x46, 0x32, 0x84, 0x43,
+ 0x31, 0x79, 0x41, 0x2d, 0x85, 0x3a, 0x2b, 0x89, 0x3c, 0x2c, 0x8d, 0x3d,
+ 0x2c, 0x96, 0x38, 0x2a, 0xa3, 0x3a, 0x2e, 0xb9, 0x3b, 0x30, 0xc0, 0x3f,
+ 0x31, 0xb6, 0x3c, 0x2e, 0xa1, 0x36, 0x2a, 0x90, 0x37, 0x2c, 0x84, 0x3c,
+ 0x2c, 0x7f, 0x3b, 0x2a, 0x7b, 0x3b, 0x2c, 0x73, 0x39, 0x2a, 0x76, 0x35,
+ 0x28, 0x92, 0x48, 0x3b, 0x8d, 0x4f, 0x42, 0x99, 0x53, 0x4e, 0x9c, 0x56,
+ 0x57, 0x91, 0x6f, 0x5f, 0x66, 0x76, 0x49, 0x47, 0x56, 0x34, 0x5e, 0x6b,
+ 0x51, 0x4b, 0x51, 0x35, 0x3a, 0x3b, 0x23, 0x38, 0x38, 0x2f, 0x38, 0x42,
+ 0x2f, 0x69, 0x83, 0x4c, 0x77, 0x9d, 0x50, 0x70, 0x9c, 0x4e, 0x72, 0xa2,
+ 0x50, 0x7d, 0xa9, 0x60, 0x66, 0x8e, 0x4e, 0x62, 0x8a, 0x4a, 0x62, 0x88,
+ 0x4d, 0x69, 0x60, 0x51, 0x69, 0x60, 0x51, 0x68, 0x5f, 0x50, 0x6c, 0x63,
+ 0x54, 0x6b, 0x62, 0x53, 0x6d, 0x62, 0x57, 0x6c, 0x62, 0x55, 0x6c, 0x64,
+ 0x4f, 0x6c, 0x64, 0x50, 0x6c, 0x62, 0x56, 0x6d, 0x62, 0x55, 0x6d, 0x63,
+ 0x54, 0x68, 0x61, 0x51, 0x56, 0x50, 0x40, 0x45, 0x41, 0x31, 0x38, 0x41,
+ 0x27, 0x84, 0x4b, 0x40, 0xc0, 0x3e, 0x40, 0xd8, 0x4e, 0x4f, 0xf7, 0x69,
+ 0x6d, 0xde, 0x4e, 0x4a, 0xd1, 0x43, 0x3c, 0xd3, 0x45, 0x3f, 0xd8, 0x48,
+ 0x43, 0xde, 0x49, 0x46, 0xe4, 0x47, 0x4b, 0xe0, 0x4c, 0x4b, 0xe7, 0x49,
+ 0x48, 0xed, 0x41, 0x43, 0xe5, 0x42, 0x41, 0xcc, 0x40, 0x3d, 0x9f, 0x3d,
+ 0x30, 0x8a, 0x41, 0x32, 0x85, 0x3c, 0x31, 0x81, 0x3a, 0x33, 0x7f, 0x3b,
+ 0x32, 0x7e, 0x3b, 0x31, 0x7a, 0x3b, 0x2f, 0x7a, 0x3b, 0x2b, 0x7b, 0x3a,
+ 0x2b, 0x86, 0x38, 0x2c, 0x8f, 0x38, 0x2c, 0x94, 0x38, 0x28, 0x89, 0x3a,
+ 0x2a, 0x80, 0x3c, 0x2c, 0x7f, 0x38, 0x2b, 0x7b, 0x33, 0x28, 0x79, 0x36,
+ 0x2c, 0x70, 0x34, 0x29, 0x76, 0x3d, 0x31, 0x85, 0x51, 0x40, 0x89, 0x54,
+ 0x47, 0x9a, 0x51, 0x4d, 0x8c, 0x5b, 0x53, 0x57, 0x58, 0x40, 0x4f, 0x65,
+ 0x3d, 0x60, 0x76, 0x46, 0x43, 0x57, 0x2d, 0x36, 0x40, 0x2a, 0x3a, 0x3c,
+ 0x32, 0x37, 0x39, 0x2f, 0x38, 0x40, 0x2d, 0x5f, 0x79, 0x41, 0x78, 0x9d,
+ 0x51, 0x70, 0x9e, 0x51, 0x77, 0xa8, 0x59, 0x6a, 0x95, 0x53, 0x5c, 0x84,
+ 0x47, 0x67, 0x8e, 0x4a, 0x61, 0x85, 0x49, 0x69, 0x60, 0x51, 0x6a, 0x61,
+ 0x52, 0x6c, 0x62, 0x54, 0x6a, 0x61, 0x52, 0x6a, 0x61, 0x52, 0x6b, 0x62,
+ 0x53, 0x6b, 0x62, 0x53, 0x6b, 0x62, 0x52, 0x6c, 0x63, 0x53, 0x6c, 0x63,
+ 0x54, 0x70, 0x62, 0x52, 0x70, 0x61, 0x55, 0x66, 0x5f, 0x52, 0x66, 0x61,
+ 0x50, 0x5f, 0x59, 0x43, 0x41, 0x40, 0x25, 0x72, 0x4d, 0x3c, 0x9c, 0x45,
+ 0x43, 0xae, 0x42, 0x43, 0xc1, 0x4f, 0x4e, 0xcb, 0x4c, 0x4c, 0xd2, 0x43,
+ 0x42, 0xcf, 0x40, 0x39, 0xcb, 0x45, 0x3b, 0xd9, 0x44, 0x45, 0xe0, 0x40,
+ 0x45, 0xe1, 0x43, 0x45, 0xe2, 0x44, 0x43, 0xe3, 0x41, 0x3e, 0xe2, 0x42,
+ 0x3e, 0xcd, 0x41, 0x3c, 0x9d, 0x39, 0x2f, 0x80, 0x3d, 0x2f, 0x80, 0x3c,
+ 0x33, 0x88, 0x38, 0x32, 0x85, 0x3b, 0x2f, 0x81, 0x3b, 0x2e, 0x7f, 0x3a,
+ 0x2d, 0x7c, 0x3a, 0x2e, 0x7c, 0x3a, 0x2f, 0x7b, 0x39, 0x31, 0x7b, 0x38,
+ 0x2f, 0x7c, 0x39, 0x2e, 0x7a, 0x3a, 0x2e, 0x78, 0x39, 0x2f, 0x75, 0x38,
+ 0x2e, 0x72, 0x36, 0x2b, 0x6f, 0x34, 0x2a, 0x6c, 0x32, 0x27, 0x76, 0x40,
+ 0x36, 0x88, 0x54, 0x4c, 0x94, 0x51, 0x4d, 0x93, 0x55, 0x4d, 0x79, 0x65,
+ 0x4f, 0x5a, 0x6e, 0x4a, 0x55, 0x6d, 0x44, 0x4d, 0x5f, 0x3a, 0x39, 0x43,
+ 0x28, 0x38, 0x39, 0x2c, 0x3b, 0x3d, 0x33, 0x34, 0x3b, 0x30, 0x38, 0x39,
+ 0x29, 0x56, 0x64, 0x3e, 0x74, 0x96, 0x54, 0x78, 0xa4, 0x5c, 0x72, 0x99,
+ 0x5c, 0x5a, 0x82, 0x43, 0x5f, 0x87, 0x49, 0x65, 0x8d, 0x4c, 0x5c, 0x80,
+ 0x47, 0x68, 0x61, 0x51, 0x69, 0x62, 0x52, 0x6a, 0x64, 0x53, 0x69, 0x62,
+ 0x52, 0x69, 0x62, 0x52, 0x6a, 0x62, 0x53, 0x6b, 0x62, 0x53, 0x6b, 0x62,
+ 0x53, 0x6c, 0x63, 0x54, 0x6c, 0x63, 0x54, 0x6d, 0x61, 0x54, 0x66, 0x5a,
+ 0x50, 0x73, 0x70, 0x69, 0xa3, 0xa0, 0x98, 0xb4, 0xaf, 0xa5, 0x7d, 0x7b,
+ 0x6a, 0x37, 0x3e, 0x2b, 0x33, 0x3c, 0x28, 0x3c, 0x3d, 0x2f, 0x3f, 0x3b,
+ 0x2e, 0x5e, 0x42, 0x35, 0xa5, 0x48, 0x45, 0xd5, 0x41, 0x45, 0xd9, 0x3e,
+ 0x3c, 0xdd, 0x44, 0x41, 0xde, 0x44, 0x44, 0xde, 0x44, 0x44, 0xda, 0x46,
+ 0x44, 0xd5, 0x46, 0x3f, 0xd4, 0x46, 0x3d, 0xd8, 0x44, 0x3e, 0xb0, 0x3d,
+ 0x34, 0x84, 0x3d, 0x2c, 0x7e, 0x3e, 0x2f, 0x85, 0x39, 0x2e, 0x85, 0x3a,
+ 0x2b, 0x81, 0x3a, 0x2b, 0x7f, 0x3a, 0x2c, 0x7e, 0x3a, 0x2f, 0x7e, 0x3a,
+ 0x30, 0x7b, 0x39, 0x30, 0x79, 0x38, 0x2f, 0x77, 0x39, 0x2f, 0x76, 0x39,
+ 0x30, 0x74, 0x3a, 0x2e, 0x71, 0x36, 0x2d, 0x6e, 0x33, 0x2b, 0x6b, 0x34,
+ 0x29, 0x65, 0x31, 0x25, 0x73, 0x3d, 0x32, 0x95, 0x52, 0x4e, 0x91, 0x59,
+ 0x52, 0x7f, 0x5f, 0x52, 0x5f, 0x5c, 0x48, 0x45, 0x53, 0x3b, 0x32, 0x3f,
+ 0x29, 0x3b, 0x45, 0x30, 0x42, 0x4a, 0x36, 0x39, 0x41, 0x30, 0x34, 0x3b,
+ 0x2e, 0x34, 0x39, 0x35, 0x37, 0x38, 0x2c, 0x4c, 0x57, 0x33, 0x72, 0x95,
+ 0x53, 0x7b, 0xa5, 0x5e, 0x60, 0x83, 0x49, 0x5a, 0x7e, 0x43, 0x61, 0x85,
+ 0x49, 0x61, 0x85, 0x4b, 0x58, 0x7c, 0x47, 0x68, 0x62, 0x52, 0x69, 0x62,
+ 0x52, 0x6b, 0x63, 0x53, 0x69, 0x62, 0x52, 0x69, 0x62, 0x52, 0x6a, 0x62,
+ 0x53, 0x6b, 0x62, 0x53, 0x6c, 0x63, 0x54, 0x6c, 0x63, 0x54, 0x6b, 0x62,
+ 0x52, 0x65, 0x5d, 0x53, 0x84, 0x81, 0x7c, 0xcf, 0xd1, 0xd1, 0xfa, 0xfb,
+ 0xfd, 0xff, 0xff, 0xff, 0xf4, 0xdd, 0xd5, 0xa0, 0x91, 0x7c, 0x43, 0x4a,
+ 0x32, 0x35, 0x3f, 0x2b, 0x3a, 0x37, 0x32, 0x2a, 0x30, 0x2b, 0x5a, 0x3f,
+ 0x3e, 0xcd, 0x7f, 0x7f, 0xce, 0x58, 0x55, 0xde, 0x39, 0x3a, 0xe1, 0x40,
+ 0x44, 0xdd, 0x42, 0x44, 0xdd, 0x41, 0x42, 0xd6, 0x43, 0x3f, 0xd0, 0x45,
+ 0x3b, 0xdd, 0x42, 0x3a, 0xbf, 0x42, 0x38, 0x8d, 0x3b, 0x2c, 0x7f, 0x3d,
+ 0x2c, 0x81, 0x3c, 0x2b, 0x81, 0x3a, 0x2b, 0x7d, 0x39, 0x2d, 0x7d, 0x39,
+ 0x2f, 0x7d, 0x3a, 0x30, 0x7c, 0x3a, 0x31, 0x77, 0x3a, 0x33, 0x73, 0x38,
+ 0x2f, 0x70, 0x36, 0x2c, 0x6f, 0x38, 0x2d, 0x6e, 0x37, 0x2b, 0x6e, 0x36,
+ 0x2f, 0x6b, 0x34, 0x2c, 0x67, 0x33, 0x2a, 0x60, 0x2e, 0x24, 0x70, 0x38,
+ 0x2f, 0x96, 0x55, 0x51, 0x7a, 0x5c, 0x4f, 0x4e, 0x4f, 0x3e, 0x35, 0x40,
+ 0x31, 0x2f, 0x35, 0x2c, 0x33, 0x33, 0x30, 0x2e, 0x33, 0x2b, 0x34, 0x3e,
+ 0x31, 0x3b, 0x4b, 0x38, 0x30, 0x3e, 0x2e, 0x2d, 0x32, 0x2f, 0x35, 0x34,
+ 0x2b, 0x41, 0x4d, 0x2f, 0x73, 0x95, 0x59, 0x6e, 0x98, 0x54, 0x54, 0x75,
+ 0x3f, 0x5a, 0x7c, 0x45, 0x5f, 0x81, 0x4c, 0x5f, 0x82, 0x49, 0x57, 0x77,
+ 0x48, 0x68, 0x63, 0x53, 0x68, 0x63, 0x53, 0x68, 0x63, 0x53, 0x68, 0x63,
+ 0x53, 0x68, 0x63, 0x53, 0x6a, 0x63, 0x53, 0x6c, 0x63, 0x54, 0x6d, 0x64,
+ 0x55, 0x6d, 0x64, 0x55, 0x6c, 0x62, 0x51, 0x6c, 0x6a, 0x65, 0xbc, 0xc3,
+ 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
+ 0xef, 0xea, 0xf3, 0xcc, 0x9d, 0xa7, 0x7f, 0x4b, 0x4f, 0x31, 0x3d, 0x36,
+ 0x29, 0x4f, 0x48, 0x46, 0x9e, 0x99, 0x97, 0xf2, 0xf0, 0xe7, 0xfa, 0xe0,
+ 0xd6, 0xd6, 0x71, 0x71, 0xc1, 0x3d, 0x3a, 0xca, 0x40, 0x3c, 0xd4, 0x40,
+ 0x40, 0xd6, 0x3e, 0x3f, 0xd4, 0x42, 0x3d, 0xda, 0x40, 0x3c, 0xc2, 0x43,
+ 0x3c, 0x92, 0x3b, 0x31, 0x81, 0x3d, 0x2f, 0x7e, 0x3c, 0x2c, 0x7f, 0x3a,
+ 0x2e, 0x7b, 0x39, 0x2f, 0x7c, 0x39, 0x30, 0x7b, 0x3c, 0x33, 0x7a, 0x3c,
+ 0x34, 0x70, 0x3b, 0x31, 0x6b, 0x38, 0x2d, 0x69, 0x37, 0x2d, 0x68, 0x38,
+ 0x2d, 0x68, 0x38, 0x2e, 0x6b, 0x37, 0x30, 0x69, 0x36, 0x2d, 0x61, 0x30,
+ 0x27, 0x59, 0x2b, 0x1f, 0x6d, 0x3d, 0x34, 0x76, 0x54, 0x4e, 0x47, 0x40,
+ 0x33, 0x2e, 0x39, 0x29, 0x31, 0x3c, 0x2e, 0x37, 0x3a, 0x32, 0x36, 0x38,
+ 0x36, 0x32, 0x38, 0x30, 0x2d, 0x39, 0x2a, 0x36, 0x44, 0x32, 0x39, 0x48,
+ 0x36, 0x31, 0x36, 0x2c, 0x2c, 0x2d, 0x22, 0x40, 0x4a, 0x31, 0x7a, 0x9b,
+ 0x6d, 0x5e, 0x86, 0x4d, 0x51, 0x6f, 0x3c, 0x56, 0x73, 0x42, 0x5c, 0x79,
+ 0x47, 0x62, 0x82, 0x4c, 0x51, 0x6a, 0x45, 0x67, 0x64, 0x53, 0x67, 0x64,
+ 0x52, 0x67, 0x64, 0x52, 0x67, 0x64, 0x52, 0x66, 0x64, 0x52, 0x69, 0x63,
+ 0x52, 0x6c, 0x63, 0x55, 0x6d, 0x64, 0x55, 0x6d, 0x64, 0x53, 0x6a, 0x61,
+ 0x51, 0x64, 0x64, 0x64, 0xa7, 0xb3, 0xb9, 0xef, 0xfb, 0xfc, 0xfa, 0xff,
+ 0xfc, 0xfa, 0xfc, 0xee, 0xf8, 0xfc, 0xed, 0xff, 0xff, 0xed, 0xe4, 0xdb,
+ 0xc0, 0x72, 0x6e, 0x57, 0x41, 0x4a, 0x3c, 0x96, 0x97, 0x8e, 0xf3, 0xe6,
+ 0xe5, 0xff, 0xfc, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xde, 0xb2,
+ 0x9e, 0xac, 0x4f, 0x41, 0xb5, 0x38, 0x30, 0xcd, 0x41, 0x3c, 0xcd, 0x42,
+ 0x3d, 0xd1, 0x45, 0x40, 0xb5, 0x3f, 0x3b, 0x8f, 0x3c, 0x33, 0x81, 0x3d,
+ 0x33, 0x7e, 0x3c, 0x31, 0x7e, 0x3a, 0x2e, 0x7c, 0x39, 0x2f, 0x7c, 0x39,
+ 0x30, 0x7a, 0x39, 0x32, 0x76, 0x38, 0x30, 0x6a, 0x38, 0x2f, 0x68, 0x38,
+ 0x2f, 0x66, 0x37, 0x2c, 0x65, 0x37, 0x2d, 0x65, 0x37, 0x2c, 0x69, 0x36,
+ 0x30, 0x69, 0x37, 0x30, 0x66, 0x36, 0x2e, 0x68, 0x3b, 0x32, 0x6e, 0x4c,
+ 0x42, 0x38, 0x38, 0x33, 0x31, 0x34, 0x2c, 0x33, 0x37, 0x2d, 0x35, 0x36,
+ 0x2b, 0x33, 0x37, 0x29, 0x2f, 0x39, 0x2b, 0x30, 0x39, 0x2a, 0x2e, 0x38,
+ 0x2a, 0x2f, 0x38, 0x2c, 0x38, 0x41, 0x32, 0x3b, 0x43, 0x32, 0x30, 0x31,
+ 0x24, 0x44, 0x4d, 0x3a, 0x6f, 0x8b, 0x6a, 0x47, 0x6a, 0x3d, 0x4c, 0x6b,
+ 0x3c, 0x4c, 0x69, 0x3b, 0x57, 0x75, 0x46, 0x62, 0x81, 0x4e, 0x43, 0x56,
+ 0x3b, 0x68, 0x65, 0x56, 0x68, 0x65, 0x57, 0x68, 0x65, 0x57, 0x68, 0x65,
+ 0x57, 0x68, 0x65, 0x57, 0x69, 0x65, 0x56, 0x6b, 0x64, 0x5a, 0x6e, 0x65,
+ 0x57, 0x68, 0x66, 0x51, 0x6e, 0x6c, 0x68, 0xa0, 0xa7, 0xaf, 0xe2, 0xe7,
+ 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf8, 0xfb, 0xf1, 0xf8, 0xfa,
+ 0xf3, 0xff, 0xff, 0xef, 0xda, 0xd9, 0xb8, 0x70, 0x73, 0x57, 0x6f, 0x7b,
+ 0x6a, 0xc8, 0xcd, 0xc9, 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xfd, 0xfd, 0xff,
+ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xdf, 0xd8, 0xbb, 0x6a,
+ 0x5e, 0xb0, 0x38, 0x2b, 0xc4, 0x40, 0x36, 0xc7, 0x48, 0x39, 0xa8, 0x45,
+ 0x36, 0x87, 0x42, 0x37, 0x80, 0x3f, 0x36, 0x82, 0x3b, 0x32, 0x7d, 0x39,
+ 0x32, 0x78, 0x38, 0x2f, 0x75, 0x37, 0x2e, 0x73, 0x37, 0x2e, 0x6f, 0x35,
+ 0x2b, 0x6a, 0x37, 0x30, 0x68, 0x37, 0x30, 0x66, 0x35, 0x2f, 0x67, 0x36,
+ 0x2f, 0x69, 0x37, 0x30, 0x6c, 0x37, 0x31, 0x6c, 0x3c, 0x2f, 0x67, 0x46,
+ 0x34, 0x82, 0x71, 0x5f, 0x6e, 0x6b, 0x5b, 0x29, 0x32, 0x28, 0x31, 0x37,
+ 0x2e, 0x30, 0x37, 0x2d, 0x31, 0x36, 0x2a, 0x30, 0x35, 0x2c, 0x2f, 0x33,
+ 0x2d, 0x2f, 0x33, 0x2d, 0x2f, 0x34, 0x2e, 0x2e, 0x31, 0x2c, 0x2e, 0x35,
+ 0x2e, 0x32, 0x3f, 0x34, 0x33, 0x40, 0x33, 0x40, 0x4d, 0x3a, 0x49, 0x58,
+ 0x40, 0x42, 0x55, 0x38, 0x4d, 0x67, 0x40, 0x47, 0x62, 0x39, 0x58, 0x72,
+ 0x4a, 0x5d, 0x78, 0x54, 0x34, 0x44, 0x35, 0x68, 0x65, 0x56, 0x68, 0x65,
+ 0x56, 0x68, 0x65, 0x56, 0x68, 0x65, 0x56, 0x68, 0x65, 0x56, 0x67, 0x65,
+ 0x55, 0x6b, 0x64, 0x5b, 0x6e, 0x64, 0x58, 0x67, 0x68, 0x50, 0x7d, 0x80,
+ 0x7e, 0xd9, 0xe2, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfc,
+ 0xf7, 0xe5, 0xe8, 0xde, 0xe3, 0xea, 0xd7, 0xf0, 0xf1, 0xd9, 0xd3, 0xd2,
+ 0xb7, 0xb4, 0xb0, 0x9f, 0xcd, 0xcc, 0xc7, 0xf2, 0xf2, 0xf1, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xfe, 0xfc, 0xfe, 0xfe, 0xfc, 0xff, 0xfd,
+ 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xf7, 0xc7, 0xa3, 0x8e, 0xa3, 0x45,
+ 0x34, 0xbd, 0x39, 0x2e, 0xb6, 0x3c, 0x39, 0x98, 0x3a, 0x3b, 0x7f, 0x40,
+ 0x3d, 0x70, 0x42, 0x3c, 0x71, 0x40, 0x36, 0x71, 0x3f, 0x35, 0x6f, 0x3f,
+ 0x34, 0x6a, 0x3c, 0x32, 0x68, 0x3a, 0x31, 0x71, 0x36, 0x32, 0x6d, 0x35,
+ 0x31, 0x6a, 0x37, 0x2f, 0x67, 0x39, 0x31, 0x67, 0x3e, 0x34, 0x66, 0x46,
+ 0x39, 0x63, 0x4a, 0x35, 0x5f, 0x4d, 0x35, 0x7f, 0x7f, 0x69, 0x51, 0x59,
+ 0x46, 0x2a, 0x31, 0x28, 0x30, 0x37, 0x2c, 0x31, 0x37, 0x2d, 0x30, 0x36,
+ 0x2c, 0x2f, 0x33, 0x2c, 0x2d, 0x32, 0x2d, 0x2e, 0x33, 0x2d, 0x2d, 0x32,
+ 0x2c, 0x2c, 0x30, 0x2b, 0x2c, 0x33, 0x2c, 0x29, 0x34, 0x2d, 0x2d, 0x38,
+ 0x2d, 0x32, 0x3e, 0x2d, 0x32, 0x3e, 0x2a, 0x36, 0x43, 0x2e, 0x44, 0x56,
+ 0x3b, 0x48, 0x5d, 0x3d, 0x5e, 0x71, 0x52, 0x5a, 0x6c, 0x53, 0x2c, 0x38,
+ 0x2e, 0x68, 0x65, 0x56, 0x68, 0x65, 0x56, 0x68, 0x65, 0x56, 0x69, 0x66,
+ 0x57, 0x69, 0x66, 0x57, 0x6a, 0x65, 0x56, 0x6c, 0x63, 0x5c, 0x6e, 0x67,
+ 0x5a, 0x68, 0x69, 0x51, 0x6c, 0x75, 0x70, 0xc3, 0xcd, 0xd5, 0xfe, 0xff,
+ 0xff, 0xff, 0xff, 0xfe, 0xfa, 0xfb, 0xf2, 0xe9, 0xed, 0xdc, 0xe7, 0xef,
+ 0xd2, 0xea, 0xe8, 0xce, 0xdd, 0xd4, 0xc7, 0xef, 0xe0, 0xe1, 0xff, 0xfa,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xfe, 0xfc, 0xfe, 0xfe,
+ 0xfc, 0xfe, 0xfe, 0xfc, 0xff, 0xfd, 0xfa, 0xf9, 0xff, 0xff, 0xfa, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xe8, 0xd4, 0xbc, 0xb4, 0x6b, 0x53, 0x9d, 0x3f,
+ 0x2e, 0x91, 0x36, 0x2a, 0x7f, 0x38, 0x2c, 0x6f, 0x41, 0x33, 0x72, 0x3d,
+ 0x37, 0x73, 0x3f, 0x39, 0x73, 0x41, 0x3b, 0x6f, 0x3f, 0x38, 0x6e, 0x3d,
+ 0x36, 0x71, 0x39, 0x34, 0x6c, 0x3a, 0x33, 0x64, 0x3d, 0x32, 0x5e, 0x3e,
+ 0x32, 0x50, 0x3b, 0x2b, 0x55, 0x50, 0x39, 0x5d, 0x58, 0x3d, 0x5d, 0x5d,
+ 0x3f, 0x6e, 0x76, 0x5c, 0x32, 0x40, 0x2b, 0x32, 0x37, 0x2f, 0x32, 0x38,
+ 0x2e, 0x33, 0x39, 0x2f, 0x32, 0x38, 0x2d, 0x2f, 0x35, 0x2c, 0x2e, 0x33,
+ 0x2d, 0x2e, 0x33, 0x2d, 0x2c, 0x31, 0x2b, 0x2a, 0x2f, 0x29, 0x2b, 0x30,
+ 0x2b, 0x2b, 0x33, 0x2b, 0x2a, 0x34, 0x2c, 0x2d, 0x35, 0x2c, 0x37, 0x40,
+ 0x35, 0x39, 0x43, 0x34, 0x33, 0x3e, 0x2c, 0x3e, 0x4a, 0x34, 0x5c, 0x68,
+ 0x54, 0x51, 0x5d, 0x4f, 0x2b, 0x34, 0x2d, 0x67, 0x64, 0x55, 0x68, 0x65,
+ 0x56, 0x69, 0x66, 0x57, 0x69, 0x66, 0x57, 0x69, 0x66, 0x57, 0x6a, 0x65,
+ 0x56, 0x6e, 0x63, 0x5c, 0x6c, 0x68, 0x5a, 0x66, 0x6c, 0x53, 0x68, 0x77,
+ 0x6f, 0xba, 0xc6, 0xcd, 0xfb, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff,
+ 0xf2, 0xf0, 0xf7, 0xe1, 0xdd, 0xe3, 0xc3, 0xda, 0xd7, 0xc1, 0xe9, 0xde,
+ 0xde, 0xff, 0xf5, 0xfa, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xfe,
+ 0xfc, 0xfe, 0xfe, 0xfc, 0xfe, 0xfe, 0xfc, 0xfe, 0xfe, 0xfc, 0xfa, 0xff,
+ 0xfd, 0xff, 0xfd, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff,
+ 0xff, 0xff, 0xfe, 0xeb, 0xda, 0xc3, 0xac, 0xa0, 0x75, 0x5d, 0x79, 0x48,
+ 0x31, 0x65, 0x36, 0x22, 0x65, 0x33, 0x29, 0x6a, 0x39, 0x30, 0x6c, 0x3f,
+ 0x34, 0x69, 0x3e, 0x34, 0x68, 0x3e, 0x32, 0x63, 0x41, 0x37, 0x5f, 0x44,
+ 0x35, 0x59, 0x47, 0x35, 0x65, 0x5d, 0x47, 0x45, 0x46, 0x2f, 0x39, 0x43,
+ 0x27, 0x45, 0x49, 0x2b, 0x70, 0x70, 0x52, 0x5c, 0x60, 0x47, 0x32, 0x39,
+ 0x27, 0x37, 0x3d, 0x35, 0x37, 0x3d, 0x33, 0x37, 0x3e, 0x34, 0x38, 0x3e,
+ 0x33, 0x38, 0x3c, 0x35, 0x37, 0x3b, 0x36, 0x36, 0x3b, 0x35, 0x32, 0x37,
+ 0x31, 0x2e, 0x33, 0x2d, 0x2c, 0x31, 0x2b, 0x28, 0x2e, 0x28, 0x2a, 0x2e,
+ 0x2a, 0x2c, 0x31, 0x2c, 0x2f, 0x32, 0x2f, 0x3d, 0x44, 0x3d, 0x3d, 0x4a,
+ 0x38, 0x31, 0x3f, 0x28, 0x42, 0x50, 0x3c, 0x45, 0x50, 0x44, 0x2f, 0x39,
+ 0x30, 0x64, 0x64, 0x53, 0x67, 0x64, 0x55, 0x68, 0x67, 0x57, 0x69, 0x65,
+ 0x57, 0x68, 0x66, 0x57, 0x6b, 0x65, 0x56, 0x6e, 0x64, 0x5c, 0x6c, 0x68,
+ 0x5a, 0x64, 0x6b, 0x52, 0x64, 0x77, 0x6f, 0xc3, 0xd0, 0xd9, 0xfe, 0xff,
+ 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xf2, 0xf2, 0xf7, 0xe0, 0xd1, 0xd2,
+ 0xb6, 0xc6, 0xbf, 0xb3, 0xf0, 0xe6, 0xee, 0xff, 0xff, 0xff, 0xfe, 0xff,
+ 0xfc, 0xfe, 0xff, 0xfa, 0xfe, 0xfe, 0xfc, 0xfe, 0xfe, 0xfc, 0xfe, 0xfe,
+ 0xfc, 0xfe, 0xfe, 0xfc, 0xfe, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xf9, 0xff,
+ 0xf5, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xfe, 0xf8, 0xf4, 0xe4, 0xe5, 0xd8, 0xc8, 0xd1, 0xbd,
+ 0xa7, 0x68, 0x53, 0x3b, 0x58, 0x44, 0x2c, 0x5d, 0x4b, 0x32, 0x5c, 0x4c,
+ 0x34, 0x56, 0x4f, 0x3a, 0x51, 0x4e, 0x37, 0x4d, 0x4f, 0x38, 0x5e, 0x67,
+ 0x4b, 0x40, 0x4c, 0x30, 0x3d, 0x45, 0x2a, 0x47, 0x4a, 0x2b, 0x69, 0x67,
+ 0x4a, 0x60, 0x59, 0x44, 0x46, 0x46, 0x35, 0x3a, 0x3f, 0x35, 0x3a, 0x3e,
+ 0x35, 0x38, 0x3e, 0x34, 0x39, 0x3f, 0x35, 0x39, 0x40, 0x38, 0x3b, 0x41,
+ 0x3b, 0x3a, 0x3e, 0x39, 0x3a, 0x40, 0x3a, 0x39, 0x3d, 0x38, 0x37, 0x3b,
+ 0x36, 0x30, 0x36, 0x32, 0x2c, 0x31, 0x2c, 0x2b, 0x2f, 0x2e, 0x29, 0x2d,
+ 0x2e, 0x29, 0x33, 0x29, 0x36, 0x4a, 0x32, 0x39, 0x4c, 0x33, 0x38, 0x49,
+ 0x31, 0x3b, 0x4b, 0x38, 0x2f, 0x3b, 0x2e, 0x5c, 0x67, 0x4f, 0x5f, 0x69,
+ 0x52, 0x67, 0x6b, 0x57, 0x69, 0x68, 0x58, 0x6c, 0x66, 0x58, 0x6c, 0x67,
+ 0x59, 0x6b, 0x66, 0x5b, 0x68, 0x67, 0x59, 0x65, 0x6c, 0x59, 0x7c, 0x8a,
+ 0x86, 0xc8, 0xd2, 0xd9, 0xf5, 0xfa, 0xfa, 0xf7, 0xfa, 0xf0, 0xee, 0xee,
+ 0xdc, 0xdd, 0xda, 0xc6, 0xc9, 0xc0, 0xae, 0xc9, 0xbe, 0xb6, 0xe9, 0xe0,
+ 0xe6, 0xfe, 0xfa, 0xff, 0xfd, 0xfe, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe,
+ 0xfe, 0xff, 0xfe, 0xfc, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 0xf9, 0xff, 0xfc,
+ 0xfc, 0xff, 0xfd, 0xfd, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf4, 0xf6, 0xec,
+ 0xe8, 0xfe, 0xfa, 0xfb, 0xfe, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff,
+ 0xfc, 0xff, 0xff, 0xee, 0xe9, 0xe6, 0xcd, 0x6d, 0x67, 0x4b, 0x52, 0x4b,
+ 0x2d, 0x55, 0x4f, 0x32, 0x53, 0x4f, 0x33, 0x50, 0x4e, 0x34, 0x4c, 0x4f,
+ 0x36, 0x48, 0x4f, 0x35, 0x45, 0x4e, 0x2e, 0x4c, 0x53, 0x30, 0x5d, 0x65,
+ 0x40, 0x61, 0x65, 0x46, 0x56, 0x56, 0x3d, 0x57, 0x54, 0x3c, 0x55, 0x52,
+ 0x39, 0x4d, 0x49, 0x36, 0x43, 0x42, 0x35, 0x3c, 0x3f, 0x35, 0x38, 0x41,
+ 0x35, 0x38, 0x43, 0x35, 0x39, 0x41, 0x37, 0x39, 0x41, 0x36, 0x3a, 0x42,
+ 0x37, 0x3b, 0x43, 0x38, 0x3c, 0x45, 0x3c, 0x3b, 0x45, 0x3a, 0x39, 0x40,
+ 0x35, 0x35, 0x3d, 0x36, 0x36, 0x44, 0x2f, 0x47, 0x60, 0x35, 0x47, 0x62,
+ 0x3c, 0x3a, 0x4d, 0x38, 0x40, 0x52, 0x3a, 0x48, 0x5c, 0x41, 0x34, 0x42,
+ 0x31,
+ };
+
+/*
+ SmallFishScales image declaration.
+*/
+#define SmallFishScalesImageExtent 15
+
+static const unsigned char
+ SmallFishScalesImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x80, 0x80, 0x41, 0x36, 0x08,
+ 0x08, 0x14, 0x63,
+ };
+
+/*
+ Checkerboard image declaration.
+*/
+#define CheckerboardImageExtent 107
+
+static const unsigned char
+ CheckerboardImage[]=
+ {
+ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x1E, 0x00, 0x1E, 0x00, 0xF0, 0x01,
+ 0x00, 0x66, 0x66, 0x66, 0x99, 0x99, 0x99, 0x21, 0xF9, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x1E, 0x00,
+ 0x00, 0x02, 0x42, 0x8C, 0x8F, 0x09, 0xCB, 0xED, 0x09, 0x91, 0x9B, 0x2D,
+ 0x5A, 0x8A, 0x6D, 0xC4, 0x54, 0x43, 0x3E, 0x79, 0x0A, 0x58, 0x89, 0x07,
+ 0x59, 0x9A, 0x01, 0xCA, 0xA8, 0x06, 0xBB, 0xB8, 0x2B, 0x2C, 0xC3, 0x40,
+ 0x4D, 0xBB, 0x36, 0xCE, 0xF2, 0xA8, 0x6F, 0xFB, 0xA9, 0x82, 0xBA, 0xDD,
+ 0xD0, 0x68, 0x22, 0x1E, 0x73, 0x49, 0xA4, 0x48, 0xD9, 0x64, 0x3E, 0x9D,
+ 0x1E, 0xE8, 0x54, 0x5A, 0xA5, 0x6A, 0xAC, 0x9E, 0x02, 0x00, 0x3B,
+ };
+
+/*
+ Vertical image declaration.
+*/
+#define VerticalImageExtent 15
+
+static const unsigned char
+ VerticalImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x38, 0x0A, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x11,
+ };
+
+/*
+ VerticalBricks image declaration.
+*/
+#define VerticalBricksImageExtent 41
+
+static const unsigned char
+ VerticalBricksImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x31, 0x36, 0x20, 0x31, 0x36, 0x0A, 0xFF, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01,
+ };
+
+/*
+ VerticalLeftShingle image declaration.
+*/
+#define VerticalLeftShingleImageExtent 81
+
+static const unsigned char
+ VerticalLeftShingleImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x32, 0x34, 0x20, 0x32, 0x34, 0x0A, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81,
+ 0x01, 0x01, 0x61, 0x01, 0x01, 0x19, 0x01, 0x01, 0x07, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x01,
+ 0x01, 0x61, 0x01, 0x01, 0x19, 0x01, 0x01, 0x07, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x01, 0x01,
+ 0x61, 0x01, 0x01, 0x19, 0x01, 0x01, 0x07, 0x01, 0x01,
+ };
+
+/*
+ VerticalRightShingle image declaration.
+*/
+#define VerticalRightShingleImageExtent 81
+
+static const unsigned char
+ VerticalRightShingleImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x32, 0x34, 0x20, 0x32, 0x34, 0x0A, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01,
+ 0x01, 0x0D, 0x01, 0x01, 0x31, 0x01, 0x01, 0xC1, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
+ 0x01, 0x01, 0x0D, 0x01, 0x01, 0x31, 0x01, 0x01, 0xC1, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01,
+ 0x0D, 0x01, 0x01, 0x31, 0x01, 0x01, 0xC1, 0x01, 0x01,
+ };
+
+/*
+ VerticalSaw image declaration.
+*/
+#define VerticalSawImageExtent 24
+
+static const unsigned char
+ VerticalSawImage[]=
+ {
+ 0x50, 0x34, 0x0A, 0x38, 0x20, 0x31, 0x36, 0x0A, 0x40, 0x20, 0x10, 0x08,
+ 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x80,
+ };
+
+
+typedef struct _EmbeddedImage
+{
+ char name[MaxTextExtent]; /* image name */
+ char magick[MaxTextExtent]; /* blob format */
+ const void *blob; /* blob data */
+ size_t extent; /* blob size */
+} EmbeddedImage;
+
+static const EmbeddedImage EmbeddedImageList[]=
+ {
+ { "BRICKS", "PBM", BricksImage, BricksImageExtent },
+ { "CIRCLES", "PBM", CirclesImage, CirclesImageExtent },
+ { "CROSSHATCH", "PBM", CrossHatchImage, CrossHatchImageExtent },
+ { "CROSSHATCH30", "PBM", CrossHatch30Image, CrossHatch30ImageExtent },
+ { "CROSSHATCH45", "PBM", CrossHatch45Image, CrossHatch45ImageExtent },
+ { "FISHSCALES", "PBM", FishScalesImage, FishScalesImageExtent },
+ { "GRANITE", "GIF", GraniteImage, GraniteImageExtent },
+ { "GRAY0", "PBM", Gray0Image, Gray0ImageExtent },
+ { "GRAY5", "PBM", Gray5Image, Gray5ImageExtent },
+ { "GRAY10", "PBM", Gray10Image, Gray10ImageExtent },
+ { "GRAY15", "PBM", Gray15Image, Gray15ImageExtent },
+ { "GRAY20", "PBM", Gray20Image, Gray20ImageExtent },
+ { "GRAY25", "PBM", Gray25Image, Gray25ImageExtent },
+ { "GRAY30", "PBM", Gray30Image, Gray30ImageExtent },
+ { "GRAY35", "PBM", Gray35Image, Gray35ImageExtent },
+ { "GRAY40", "PBM", Gray40Image, Gray40ImageExtent },
+ { "GRAY45", "PBM", Gray45Image, Gray45ImageExtent },
+ { "GRAY50", "PBM", Gray50Image, Gray50ImageExtent },
+ { "GRAY55", "PBM", Gray55Image, Gray55ImageExtent },
+ { "GRAY60", "PBM", Gray60Image, Gray60ImageExtent },
+ { "GRAY65", "PBM", Gray65Image, Gray65ImageExtent },
+ { "GRAY70", "PBM", Gray70Image, Gray70ImageExtent },
+ { "GRAY75", "PBM", Gray75Image, Gray75ImageExtent },
+ { "GRAY80", "PBM", Gray80Image, Gray80ImageExtent },
+ { "GRAY85", "PBM", Gray85Image, Gray85ImageExtent },
+ { "GRAY90", "PBM", Gray90Image, Gray90ImageExtent },
+ { "GRAY95", "PBM", Gray95Image, Gray95ImageExtent },
+ { "GRAY100", "PBM", Gray100Image, Gray100ImageExtent },
+ { "HEXAGONS", "PBM", HexagonsImage, HexagonsImageExtent },
+ { "HORIZONTAL", "PBM", HorizontalImage, HorizontalImageExtent },
+ { "HORIZONTALSAW", "PBM", HorizontalSawImage, HorizontalSawImageExtent },
+ { "HS_BDIAGONAL", "PBM", HS_BDIAGONALImage, HS_BDIAGONALImageExtent },
+ { "HS_CROSS", "PBM", HS_CROSSImage, HS_CROSSImageExtent },
+ { "HS_DIAGCROSS", "PBM", HS_DIAGCROSSImage, HS_DIAGCROSSImageExtent },
+ { "HS_FDIAGONAL", "PBM", HS_FDIAGONALImage, HS_FDIAGONALImageExtent },
+ { "HS_HORIZONTAL", "PBM", HS_HORIZONTALImage, HS_HORIZONTALImageExtent },
+ { "HS_VERTICAL", "PBM", HS_VERTICALImage, HS_VERTICALImageExtent },
+ { "LEFT30", "PBM", Left30Image, Left30ImageExtent },
+ { "LEFT45", "PBM", Left45Image, Left45ImageExtent },
+ { "LEFTSHINGLE", "PBM", LeftShingleImage, LeftShingleImageExtent },
+ { "LOGO", "GIF", LogoImage, LogoImageExtent },
+ { "NETSCAPE", "GIF", NetscapeImage, NetscapeImageExtent },
+ { "OCTAGONS", "PBM", OctagonsImage, OctagonsImageExtent },
+ { "RIGHT30", "PBM", Right30Image, Right30ImageExtent },
+ { "RIGHT45", "PBM", Right45Image, Right45ImageExtent },
+ { "RIGHTSHINGLE", "PBM", RightShingleImage, RightShingleImageExtent },
+ { "ROSE", "PPM", RoseImage, RoseImageExtent },
+ { "SMALLFISHSCALES", "PBM", SmallFishScalesImage, SmallFishScalesImageExtent },
+ { "CHECKERBOARD", "GIF", CheckerboardImage, CheckerboardImageExtent },
+ { "VERTICAL", "PBM", VerticalImage, VerticalImageExtent },
+ { "VERTICALBRICKS", "PBM", VerticalBricksImage, VerticalBricksImageExtent },
+ { "VERTICALLEFTSHINGLE", "PBM", VerticalLeftShingleImage, VerticalLeftShingleImageExtent },
+ { "VERTICALRIGHTSHINGLE", "PBM", VerticalRightShingleImage, VerticalRightShingleImageExtent },
+ { "VERTICALSAW", "PBM", VerticalSawImage, VerticalSawImageExtent },
+ { "", "", 0, 0 }
+ };
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteLOGOImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d L O G O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadLOGOImage reads a LOGO image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadLOGOImage method is:
+%
+% Image *ReadLOGOImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadLOGOImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadLOGOImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ const void
+ *blob;
+
+ size_t
+ extent;
+
+ int
+ i;
+
+ clone_info=CloneImageInfo(image_info);
+ image=(Image *) NULL;
+ blob=NULL;
+ extent=0;
+
+ /*
+ Support legacy format names
+ */
+ if (!(LocaleCompare(image_info->magick,"IMAGE") == 0) &&
+ !(LocaleCompare(image_info->magick,"PATTERN") == 0))
+ (void) strcpy(clone_info->filename,image_info->magick);
+
+ /*
+ Search for image name in list
+ */
+ for( i=0; EmbeddedImageList[i].blob != 0; i++)
+ if (LocaleCompare(clone_info->filename, EmbeddedImageList[i].name) == 0)
+ {
+ (void) strcpy(clone_info->magick,EmbeddedImageList[i].magick);
+ blob=EmbeddedImageList[i].blob;
+ extent=EmbeddedImageList[i].extent;
+ break;
+ }
+
+ /*
+ If a matching entry is found, then retrieve the image.
+ */
+ if (blob == 0)
+ {
+ DestroyImageInfo(clone_info);
+ ThrowReaderException(BlobError,UnableToOpenFile,image)
+ }
+ image=BlobToImage(clone_info,blob,extent,exception);
+
+ if ((image_info->size) && (LocaleCompare(image_info->magick,"PATTERN") == 0))
+ {
+ Image
+ *pattern_image;
+
+ /*
+ Tile pattern across image canvas.
+ */
+ pattern_image=image;
+ image=AllocateImage(clone_info);
+ (void) TextureImage(image,pattern_image);
+ DestroyImage(pattern_image);
+ }
+
+ DestroyImageInfo(clone_info);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r L O G O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterLOGOImage adds attributes for the LOGO, GRANITE, NETSCAPE,
+% H, and ROSE image formats to the list of supported formats. The attributes
+% include the image format tag, a method to read and/or write the format,
+% whether the format supports the saving of more than one frame to the same
+% file or blob, whether the format supports native in-memory I/O, and a
+% brief description of the format.
+%
+% The format of the RegisterLOGOImage method is:
+%
+% RegisterLOGOImage(void)
+%
+*/
+ModuleExport void RegisterLOGOImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("GRANITE");
+ entry->decoder=(DecoderHandler) ReadLOGOImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Granite texture";
+ entry->module="LOGO";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("H");
+ entry->decoder=(DecoderHandler) ReadLOGOImage;
+ entry->encoder=(EncoderHandler) WriteLOGOImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Internal format";
+ entry->module="LOGO";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("IMAGE");
+ entry->decoder=(DecoderHandler) ReadLOGOImage;
+ entry->adjoin=False;
+ entry->description="GraphicsMagick Embedded Image";
+ entry->module="LOGO";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("LOGO");
+ entry->decoder=(DecoderHandler) ReadLOGOImage;
+ entry->encoder=(EncoderHandler) WriteLOGOImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="GraphicsMagick Logo";
+ entry->module="LOGO";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("NETSCAPE");
+ entry->decoder=(DecoderHandler) ReadLOGOImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Netscape 216 color cube";
+ entry->module="LOGO";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PATTERN");
+ entry->decoder=(DecoderHandler) ReadLOGOImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Tiled pattern image";
+ entry->module="LOGO";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("ROSE");
+ entry->decoder=(DecoderHandler) ReadLOGOImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="70x46 Truecolor rose";
+ entry->module="LOGO";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r L O G O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterLOGOImage removes format registrations made by the
+% LOGO module from the list of supported formats.
+%
+% The format of the UnregisterLOGOImage method is:
+%
+% UnregisterLOGOImage(void)
+%
+*/
+ModuleExport void UnregisterLOGOImage(void)
+{
+ (void) UnregisterMagickInfo("GRANITE");
+ (void) UnregisterMagickInfo("H");
+ (void) UnregisterMagickInfo("IMAGE");
+ (void) UnregisterMagickInfo("LOGO");
+ (void) UnregisterMagickInfo("NETSCAPE");
+ (void) UnregisterMagickInfo("PATTERN");
+ (void) UnregisterMagickInfo("ROSE");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e L O G O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteLOGOImage writes an image in the LOGO encoded image format.
+% We use GIF because it is the only format that is compressed without
+% requiring addition optional delegates (TIFF, ZIP, etc).
+%
+% The format of the WriteLOGOImage method is:
+%
+% unsigned int WriteLOGOImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteLOGOImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteLOGOImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[MaxTextExtent];
+
+ Image
+ *logo_image;
+
+ size_t
+ length;
+
+ register char
+ *p;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ void
+ *blob;
+
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Write logo image.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ logo_image=CloneImage(image,0,0,True,&image->exception);
+ if (logo_image == (Image *) NULL)
+ ThrowWriterException2(ResourceLimitError,image->exception.reason,image);
+ /*
+ Analyze image to be written.
+ */
+ (void) GetImageCharacteristics(logo_image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception);
+ if ((characteristics.monochrome) &&
+ (logo_image->columns*logo_image->rows < 4097))
+ {
+ (void) strcpy(logo_image->magick,"PBM");
+ length=((logo_image->columns*logo_image->rows)/8)+16;
+ }
+ else if (LocaleCompare(image_info->magick,"ROSE") == 0)
+ {
+ (void) strcpy(logo_image->magick,"PPM");
+ length=3*logo_image->columns*logo_image->rows;
+ }
+ else
+ {
+ (void) strcpy(logo_image->magick,"GIF");
+ length=logo_image->columns*logo_image->rows;
+ }
+ blob=ImageToBlob(image_info,logo_image,&length,&image->exception);
+ if (blob == (void *) NULL)
+ {
+ DestroyImage(logo_image);
+ ThrowWriterException2(FileOpenError,image->exception.reason,image)
+ }
+ (void) WriteBlobString(image,"/*\n");
+ (void) WriteBlobString(image," Logo image declaration.\n");
+ (void) WriteBlobString(image,"*/\n");
+ FormatString(buffer,"#define LogoImageExtent %lu\n\n",
+ (unsigned long) length);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"static const unsigned char\n");
+ (void) WriteBlobString(image," LogoImage[]=\n");
+ (void) WriteBlobString(image," {\n");
+ (void) WriteBlobString(image," ");
+ p=(char *) blob;
+ for (i=0; i < (long) length ; i++)
+ {
+ FormatString(buffer,"0x%02X, ",*p & 0xff);
+ (void) WriteBlobString(image,buffer);
+ if (((i+1) % 12) == 0)
+ {
+ (void) strcpy(buffer,"\n ");
+ (void) WriteBlobString(image,buffer);
+ }
+ p++;
+ }
+ (void) WriteBlobString(image,"\n };\n");
+ CloseBlob(image);
+ MagickFreeMemory(blob);
+ DestroyImage(logo_image);
+ return(True);
+}
diff --git a/coders/mac.c b/coders/mac.c
new file mode 100644
index 0000000..ce999e7
--- /dev/null
+++ b/coders/mac.c
@@ -0,0 +1,256 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M M AAA CCC %
+% MM MM A A C %
+% M M M AAAAA C %
+% M M A A C %
+% M M A A CCC % %
+% %
+% Read MAC: MacPaint Image Format. %
+% %
+% %
+% Software Design %
+% Jaroslav Fojtik %
+% 2010 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M A C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMACImage reads an MAC image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadMACImage method is:
+%
+% Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMACImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image *image;
+ unsigned int y;
+ unsigned char x8, rep, b;
+ long ldblk;
+ unsigned char *BImgBuff = NULL;
+ unsigned char *DataPtr;
+ unsigned int status;
+ const PixelPacket *q;
+
+ /* Open image file. */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image = AllocateImage(image_info);
+ status = OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if(status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ /* Read MAC image. */
+ ldblk = ReadBlobLSBShort(image);
+ if((ldblk & 0xFF)!=0)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if(ldblk==0) /* ???? don't know why */
+ SeekBlob(image,0x200,SEEK_SET);
+ else
+ SeekBlob(image,0x280,SEEK_SET);
+
+ image->columns = 576;
+ image->rows = 720;
+ image->depth = 1;
+ image->colors = 1l << image->depth;
+
+ if (!AllocateImageColormap(image,image->colors)) goto NoMemory;
+
+ /* If ping is true, then only set image size and colors without reading any image data. */
+ if (image_info->ping) goto DONE_READING;
+
+ /* ----- Load RLE compressed raster ----- */
+ ldblk = (image->depth*image->columns) /8;
+ BImgBuff = MagickAllocateMemory(unsigned char *, ((size_t)ldblk));
+ if(BImgBuff==NULL)
+ NoMemory:
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ DataPtr = BImgBuff;
+ x8=0; y=0;
+
+ while(y<image->rows)
+ {
+ rep = ReadBlobByte(image);
+ if(EOFBlob(image)) break;
+
+ if( rep>=128 || rep<=0)
+ {
+ b = ~ReadBlobByte(image);;
+
+ rep = ~rep + 2;
+ while(rep>0)
+ {
+ *DataPtr++ = b;
+ x8++;
+ rep--;
+ if(x8>=ldblk)
+ {
+ x8=0;
+
+ q = SetImagePixels(image,0,y,image->columns,1);
+ if(q == (PixelPacket *)NULL) break;
+ (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0);
+ if(!SyncImagePixels(image)) break;
+
+ DataPtr = BImgBuff;
+ y++;
+ if(y>=image->rows)
+ {
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ rep++;
+ while(rep>0)
+ {
+ b = ~ReadBlobByte(image);
+ *DataPtr++ = b;
+ x8++;
+ rep--;
+ if(x8>=ldblk)
+ {
+ x8=0;
+
+ q = SetImagePixels(image,0,y,image->columns,1);
+ if(q == (PixelPacket *)NULL) break;
+ (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0);
+ if (!SyncImagePixels(image)) break;
+
+ DataPtr = BImgBuff;
+ y++;
+ if(y>=image->rows)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(BImgBuff!=NULL)
+ MagickFreeMemory(BImgBuff);
+ if(EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename);
+
+DONE_READING:
+ CloseBlob(image);
+ return(image);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M A C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMACImage adds attributes for the MAC image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMACImage method is:
+%
+% RegisterMACImage(void)
+*/
+ModuleExport void RegisterMACImage(void)
+{
+ MagickInfo *entry;
+
+ entry=SetMagickInfo("MAC");
+ entry->decoder = (DecoderHandler)ReadMACImage;
+ entry->description="Mac Paint";
+ entry->seekable_stream = True;
+ entry->module="MAC";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M A C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMACImage removes format registrations made by the
+% MAC module from the list of supported formats.
+%
+% The format of the UnregisterMACImage method is:
+%
+% UnregisterMACImage(void)
+%
+*/
+ModuleExport void UnregisterMACImage(void)
+{
+ (void) UnregisterMagickInfo("MAC");
+}
diff --git a/coders/map.c b/coders/map.c
new file mode 100644
index 0000000..619c7e0
--- /dev/null
+++ b/coders/map.c
@@ -0,0 +1,413 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M AAA PPPP %
+% MM MM A A P P %
+% M M M AAAAA PPPP %
+% M M A A P %
+% M M A A P %
+% %
+% %
+% Read/Write Image Colormaps As An Image File %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMAPImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M A P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMAPImage reads an image of raw RGB colormap and colormap index
+% bytes and returns it. It allocates the memory necessary for the new Image
+% structure and returns a pointer to the new image.
+%
+% The format of the ReadMAPImage method is:
+%
+% Image *ReadMAPImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMAPImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowMAPReaderException(code_,reason_,image_) \
+do { \
+ MagickFreeMemory(colormap); \
+ MagickFreeMemory(pixels); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+static Image *ReadMAPImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ unsigned int
+ index;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ unsigned char
+ *colormap = (unsigned char *) NULL,
+ *pixels = (unsigned char *) NULL;
+
+ unsigned int
+ packet_size,
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowMAPReaderException(OptionError,MustSpecifyImageSize,image);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowMAPReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Initialize image structure.
+ */
+ image->storage_class=PseudoClass;
+ if (!AllocateImageColormap(image,image->offset ? image->offset : 256))
+ ThrowMAPReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ packet_size=image->colors > 256 ? 6 : 3;
+ colormap=MagickAllocateArray(unsigned char *,packet_size,image->colors);
+ if (colormap == (unsigned char *) NULL)
+ ThrowMAPReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Read image colormap.
+ */
+ if (ReadBlob(image,packet_size*image->colors,(char *) colormap) !=
+ packet_size*image->colors)
+ ThrowMAPReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ p=colormap;
+ if (image->colors <= 256)
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ }
+ else
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].red=(*p++ << 8U);
+ image->colormap[i].red|=(*p++);
+ image->colormap[i].green=(*p++ << 8U);
+ image->colormap[i].green|=(*p++);
+ image->colormap[i].blue=(*p++ << 8U);
+ image->colormap[i].blue|=(*p++);
+ }
+ MagickFreeMemory(colormap);
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+ /*
+ Read image pixels.
+ */
+ packet_size=image->depth > 8 ? 2 : 1;
+ pixels=MagickAllocateArray(unsigned char *,packet_size,image->columns);
+ if (pixels == (unsigned char *) NULL)
+ ThrowMAPReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=pixels;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ if (ReadBlob(image,packet_size*image->columns,(char *) pixels) !=
+ packet_size*image->columns)
+ ThrowMAPReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=(*p++);
+ if (image->colors > 256)
+ index=((index << 8)+(*p++));
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ }
+ MagickFreeMemory(pixels);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M A P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMAPImage adds attributes for the MAP image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMAPImage method is:
+%
+% RegisterMAPImage(void)
+%
+*/
+ModuleExport void RegisterMAPImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("MAP");
+ entry->decoder=(DecoderHandler) ReadMAPImage;
+ entry->encoder=(EncoderHandler) WriteMAPImage;
+ entry->adjoin=False;
+ entry->raw=True;
+ entry->description="Colormap intensities and indices";
+ entry->module="MAP";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=ObeyExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M A P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMAPImage removes format registrations made by the
+% MAP module from the list of supported formats.
+%
+% The format of the UnregisterMAPImage method is:
+%
+% UnregisterMAPImage(void)
+%
+*/
+ModuleExport void UnregisterMAPImage(void)
+{
+ (void) UnregisterMagickInfo("MAP");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M A P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMAPImage writes an image to a file as red, green, and blue
+% colormap bytes followed by the colormap indexes.
+%
+% The format of the WriteMAPImage method is:
+%
+% unsigned int WriteMAPImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteMAPImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+#define ThrowMAPWriterException(code_,reason_,image_) \
+do { \
+ MagickFreeMemory(colormap); \
+ MagickFreeMemory(pixels); \
+ ThrowWriterException(code_,reason_,image_); \
+} while (0);
+static unsigned int WriteMAPImage(const ImageInfo *image_info,Image *image)
+{
+ long
+ y;
+
+ register const IndexPacket
+ *indexes;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *colormap = (unsigned char *) NULL,
+ *pixels = (unsigned char *) NULL;
+
+ unsigned int
+ status;
+
+ unsigned long
+ packet_size;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowMAPWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Allocate colormap.
+ */
+ if (!IsPaletteImage(image,&image->exception))
+ (void) SetImageType(image,PaletteType);
+ packet_size=image->depth > 8 ? 2 : 1;
+ pixels=MagickAllocateMemory(unsigned char *,image->columns*packet_size);
+ if (pixels == (unsigned char *) NULL)
+ ThrowMAPWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ packet_size=image->colors > 256 ? 6 : 3;
+ colormap=MagickAllocateMemory(unsigned char *,packet_size*image->colors);
+ if (colormap == (unsigned char *) NULL)
+ ThrowMAPWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Write colormap to file.
+ */
+ q=colormap;
+ if (image->colors <= 256)
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=image->colormap[i].red;
+ *q++=image->colormap[i].green;
+ *q++=image->colormap[i].blue;
+ }
+#if QuantumDepth > 8
+ else
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=image->colormap[i].red >> 8;
+ *q++=image->colormap[i].red & 0xff;
+ *q++=image->colormap[i].green >> 8;
+ *q++=image->colormap[i].green & 0xff;
+ *q++=image->colormap[i].blue >> 8;
+ *q++=image->colormap[i].blue & 0xff;
+ }
+#endif /* QuantumDepth > 8 */
+ if (WriteBlob(image,packet_size*image->colors,(char *) colormap) !=
+ packet_size*image->colors)
+ ThrowMAPWriterException(FileOpenError,UnableToWriteFile,image);
+ MagickFreeMemory(colormap);
+ /*
+ Write image pixels to file.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ q=pixels;
+ for (x=0; x < (long) image->columns; x++)
+ {
+#if QuantumDepth > 8
+ if (image->colors > 256)
+ *q++=indexes[x] >> 8;
+#endif /* QuantumDepth > 8 */
+ *q++=indexes[x];
+ }
+ if (WriteBlob(image,q-pixels,(char *) pixels) != (size_t) (q-pixels))
+ ThrowMAPWriterException(FileOpenError,UnableToWriteFile,image);
+ }
+ MagickFreeMemory(pixels);
+ CloseBlob(image);
+ return(status);
+}
diff --git a/coders/mat.c b/coders/mat.c
new file mode 100644
index 0000000..65efadc
--- /dev/null
+++ b/coders/mat.c
@@ -0,0 +1,1474 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M M AAA TTTTT L AAA BBBB %
+% MM MM A A T L A A B B %
+% M M M AAAAA T L AAAAA BBBB %
+% M M A A T L A A B B %
+% M M A A T LLLLL A A BBBB %
+% %
+% %
+% Read MATLAB Image Format. %
+% %
+% %
+% Software Design %
+% Jaroslav Fojtik %
+% 2001 - 2016 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%Currently supported formats:
+% 2D matrices: X*Y byte, word, dword, qword, single, double
+% 3D matrices: only X*Y*3 byte, word, dword, qword, single, double
+% complex: X*Y single, double
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/magick_endian.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/shear.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#if defined(HasZLIB)
+# include "zlib.h"
+#endif
+
+
+/* Auto coloring method, sorry this creates some artefact inside data
+MinReal+j*MaxComplex = red MaxReal+j*MaxComplex = black
+MinReal+j*0 = white MaxReal+j*0 = black
+MinReal+j*MinComplex = blue MaxReal+j*MinComplex = black
+*/
+
+typedef struct
+{
+ char identific[124];
+ unsigned short Version;
+ char EndianIndicator[2];
+ unsigned long DataType;
+ magick_uint32_t ObjectSize;
+ unsigned long unknown1;
+ unsigned long unknown2;
+
+ unsigned short unknown5;
+ unsigned char StructureFlag;
+ unsigned char StructureClass;
+ unsigned long unknown3;
+ unsigned long unknown4;
+ unsigned long DimFlag;
+
+ unsigned long SizeX;
+ unsigned long SizeY;
+ unsigned short Flag1;
+ unsigned short NameFlag;
+}
+MATHeader;
+
+static const char *MonthsTab[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
+static const char *DayOfWTab[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+static const char *OsDesc=
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+ "PCWIN";
+#else
+ #ifdef __APPLE__
+ "MAC";
+ #else
+ "LNX86";
+ #endif
+#endif
+
+typedef enum
+ {
+ miINT8 = 1, /* 8 bit signed */
+ miUINT8, /* 8 bit unsigned */
+ miINT16, /* 16 bit signed */
+ miUINT16, /* 16 bit unsigned */
+ miINT32, /* 32 bit signed */
+ miUINT32, /* 32 bit unsigned */
+ miSINGLE, /* IEEE 754 single precision float */
+ miRESERVE1,
+ miDOUBLE, /* IEEE 754 double precision float */
+ miRESERVE2,
+ miRESERVE3,
+ miINT64, /* 64 bit signed */
+ miUINT64, /* 64 bit unsigned */
+ miMATRIX, /* MATLAB array */
+ miCOMPRESSED, /* Compressed Data */
+ miUTF8, /* Unicode UTF-8 Encoded Character Data */
+ miUTF16, /* Unicode UTF-16 Encoded Character Data */
+ miUTF32 /* Unicode UTF-32 Encoded Character Data */
+ } mat5_data_type;
+
+typedef enum
+ {
+ mxCELL_CLASS=1, /* cell array */
+ mxSTRUCT_CLASS, /* structure */
+ mxOBJECT_CLASS, /* object */
+ mxCHAR_CLASS, /* character array */
+ mxSPARSE_CLASS, /* sparse array */
+ mxDOUBLE_CLASS, /* double precision array */
+ mxSINGLE_CLASS, /* single precision floating point */
+ mxINT8_CLASS, /* 8 bit signed integer */
+ mxUINT8_CLASS, /* 8 bit unsigned integer */
+ mxINT16_CLASS, /* 16 bit signed integer */
+ mxUINT16_CLASS, /* 16 bit unsigned integer */
+ mxINT32_CLASS, /* 32 bit signed integer */
+ mxUINT32_CLASS, /* 32 bit unsigned integer */
+ mxINT64_CLASS, /* 64 bit signed integer */
+ mxUINT64_CLASS, /* 64 bit unsigned integer */
+ mxFUNCTION_CLASS /* Function handle */
+ } arrayclasstype;
+
+#define FLAG_COMPLEX 0x8
+#define FLAG_GLOBAL 0x4
+#define FLAG_LOGICAL 0x2
+
+static const QuantumType z2qtype[4] = {GrayQuantum, BlueQuantum, GreenQuantum, RedQuantum};
+
+
+static void InsertComplexDoubleRow(double *p, int y, Image * image, double MinVal,
+ double MaxVal)
+{
+ double f;
+ int x;
+ register PixelPacket *q;
+
+ if (MinVal == 0)
+ MinVal = -1;
+ if (MaxVal == 0)
+ MaxVal = 1;
+
+ q = SetImagePixels(image, 0, y, image->columns, 1);
+ if (q == (PixelPacket *) NULL)
+ return;
+ for (x = 0; x < (long) image->columns; x++)
+ {
+ if (*p > 0)
+ {
+ f = (*p / MaxVal) * (MaxRGB - q->red);
+ if (f + q->red > MaxRGB)
+ q->red = MaxRGB;
+ else
+ q->red += (int) f;
+ if ((int) f / 2.0 > q->green)
+ q->green = q->blue = 0;
+ else
+ q->green = q->blue -= (int) (f / 2.0);
+ }
+ if (*p < 0)
+ {
+ f = (*p / MaxVal) * (MaxRGB - q->blue);
+ if (f + q->blue > MaxRGB)
+ q->blue = MaxRGB;
+ else
+ q->blue += (int) f;
+ if ((int) f / 2.0 > q->green)
+ q->green = q->red = 0;
+ else
+ q->green = q->red -= (int) (f / 2.0);
+ }
+ p++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ return;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ MagickMonitor(LoadImageText,image->rows-y-1,image->rows); */
+ return;
+}
+
+
+static void InsertComplexFloatRow(float *p, int y, Image * image, double MinVal,
+ double MaxVal)
+{
+ double f;
+ int x;
+ register PixelPacket *q;
+
+ if (MinVal == 0)
+ MinVal = -1;
+ if (MaxVal == 0)
+ MaxVal = 1;
+
+ q = SetImagePixels(image, 0, y, image->columns, 1);
+ if (q == (PixelPacket *) NULL)
+ return;
+ for (x = 0; x < (long) image->columns; x++)
+ {
+ if (*p > 0)
+ {
+ f = (*p / MaxVal) * (MaxRGB - q->red);
+ if (f + q->red > MaxRGB)
+ q->red = MaxRGB;
+ else
+ q->red += (int) f;
+ if ((int) f / 2.0 > q->green)
+ q->green = q->blue = 0;
+ else
+ q->green = q->blue -= (int) (f / 2.0);
+ }
+ if (*p < 0)
+ {
+ f = (*p / MaxVal) * (MaxRGB - q->blue);
+ if (f + q->blue > MaxRGB)
+ q->blue = MaxRGB;
+ else
+ q->blue += (int) f;
+ if ((int) f / 2.0 > q->green)
+ q->green = q->red = 0;
+ else
+ q->green = q->red -= (int) (f / 2.0);
+ }
+ p++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ return;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ MagickMonitor(LoadImageText,image->rows-y-1,image->rows); */
+ return;
+}
+
+
+/************** READERS ******************/
+
+
+
+static void FixSignedValues(PixelPacket *q, int y)
+{
+ while(y-->0)
+ {
+ /* Please note that negative values will overflow
+ Q=8; MaxRGB=255: <0;127> + 127+1 = <128; 255>
+ <-1;-128> + 127+1 = <0; 127> */
+ q->red += MaxRGB/2 + 1;
+ q->green += MaxRGB/ + 1;
+ q->blue += MaxRGB/ + 1;
+ q++;
+ }
+}
+
+
+/** Fix whole row of logical/binary data. It means pack it. */
+static void FixLogical(unsigned char *Buff,int ldblk)
+{
+unsigned char mask=128;
+unsigned char *BuffL = Buff;
+unsigned char val = 0;
+
+ while(ldblk-->0)
+ {
+ if(*Buff++ != 0)
+ val |= mask;
+
+ mask >>= 1;
+ if(mask==0)
+ {
+ *BuffL++ = val;
+ val = 0;
+ mask = 128;
+ }
+
+ }
+ *BuffL = val;
+}
+
+#if defined(HasZLIB)
+static voidpf ZLIBAllocFunc(voidpf opaque, uInt items, uInt size)
+{
+ ARG_NOT_USED(opaque);
+ return MagickMallocCleared((size_t) items*size);
+}
+static void ZLIBFreeFunc(voidpf opaque, voidpf address)
+{
+ ARG_NOT_USED(opaque);
+ MagickFree(address);
+}
+
+/** This procedure decompreses an image block for a new MATLAB format. */
+static Image *DecompressBlock(Image *orig, magick_uint32_t *Size, ImageInfo *clone_info, ExceptionInfo *exception)
+{
+Image *image2;
+void *cache_block, *decompress_block;
+z_stream zip_info;
+FILE *mat_file;
+size_t magick_size;
+int status;
+int zip_status;
+magick_off_t TotalSize = 0;
+
+ if(clone_info==NULL) return NULL;
+ if(clone_info->file) /* Close file opened from previous transaction. */
+ {
+ fclose(clone_info->file);
+ clone_info->file = NULL;
+ (void) unlink(clone_info->filename);
+ }
+
+ cache_block = MagickAllocateMemory(unsigned char *,(size_t)((*Size<16384) ? *Size : 16384));
+ if(cache_block==NULL) return NULL;
+ decompress_block = MagickAllocateMemory(unsigned char *,(size_t)(4096));
+ if(decompress_block==NULL)
+ {
+ MagickFreeMemory(cache_block);
+ return NULL;
+ }
+
+ mat_file = AcquireTemporaryFileStream(clone_info->filename,BinaryFileIOMode);
+ if(!mat_file)
+ {
+ MagickFreeMemory(cache_block);
+ MagickFreeMemory(decompress_block);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Cannot create file stream for decompressed image");
+ return NULL;
+ }
+
+ zip_info.zalloc = ZLIBAllocFunc;
+ zip_info.zfree = ZLIBFreeFunc;
+ zip_info.opaque = (voidpf) NULL;
+ zip_status = inflateInit(&zip_info);
+ if (zip_status != Z_OK)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Failed to initialize zlib");
+ ThrowException(exception,CorruptImageError, UnableToUncompressImage, orig->filename);
+ MagickFreeMemory(cache_block);
+ MagickFreeMemory(decompress_block);
+ (void)fclose(mat_file);
+ LiberateTemporaryFile(clone_info->filename);
+ return NULL;
+ }
+ /* zip_info.next_out = 8*4; */
+
+ zip_info.avail_in = 0;
+ zip_info.total_out = 0;
+ while(*Size>0 && !EOFBlob(orig))
+ {
+ magick_size = ReadBlob(orig, (*Size<16384)?*Size:16384, cache_block);
+ zip_info.next_in = cache_block;
+ zip_info.avail_in = (uInt) magick_size;
+
+ while(zip_info.avail_in>0)
+ {
+ zip_info.avail_out = 4096;
+ zip_info.next_out = decompress_block;
+ zip_status = inflate(&zip_info,Z_NO_FLUSH);
+ if ((zip_status != Z_OK) && (zip_status != Z_STREAM_END))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Corrupt inflate stream");
+ ThrowException(exception,CorruptImageError, UnableToUncompressImage, orig->filename);
+ MagickFreeMemory(cache_block);
+ MagickFreeMemory(decompress_block);
+ inflateEnd(&zip_info);
+ (void)fclose(mat_file);
+ LiberateTemporaryFile(clone_info->filename);
+ return NULL;
+ }
+ fwrite(decompress_block, 4096-zip_info.avail_out, 1, mat_file);
+ TotalSize += 4096-zip_info.avail_out;
+
+ if(zip_status == Z_STREAM_END) goto DblBreak;
+ }
+
+ *Size -= magick_size;
+ }
+DblBreak:
+
+ inflateEnd(&zip_info); /* Release all caches used by zip. */
+ (void)fclose(mat_file);
+ MagickFreeMemory(cache_block);
+ MagickFreeMemory(decompress_block);
+ *Size = TotalSize;
+
+ if((clone_info->file=fopen(clone_info->filename,"rb"))==NULL) goto UnlinkFile;
+ if( (image2 = AllocateImage(clone_info))==NULL ) goto EraseFile;
+ status = OpenBlob(clone_info,image2,ReadBinaryBlobMode,exception);
+ if (status == False)
+ {
+ DeleteImageFromList(&image2);
+EraseFile:
+ fclose(clone_info->file);
+ clone_info->file = NULL;
+UnlinkFile:
+ LiberateTemporaryFile(clone_info->filename);
+ return NULL;
+ }
+
+ return image2;
+}
+#endif /* defined(HasZLIB) */
+
+
+#define ThrowMATReaderException(code_,reason_,image_) \
+{ \
+ if (clone_info) \
+ DestroyImageInfo(clone_info); \
+ ThrowReaderException(code_,reason_,image_); \
+}
+
+
+
+typedef struct {
+ unsigned char Type[4];
+ magick_uint32_t nRows;
+ magick_uint32_t nCols;
+ magick_uint32_t imagf;
+ magick_uint32_t nameLen;
+} MAT4_HDR;
+
+
+/* Load Matlab V4 file. */
+static Image *ReadMATImageV4(const ImageInfo *image_info, Image *image, ImportPixelAreaOptions *import_options, ExceptionInfo *exception)
+{
+MAT4_HDR HDR;
+Image *rotated_image;
+long ldblk;
+int sample_size;
+void *BImgBuff = NULL;
+double MinVal_c, MaxVal_c;
+int i;
+BlobInfo *blob;
+PixelPacket *q;
+magick_uint32_t (*ReadBlobXXXLong)(Image *image);
+size_t (*ReadBlobXXXDoubles)(Image *image, size_t len, double *data);
+size_t (*ReadBlobXXXFloats)(Image *image, size_t len, float *data);
+
+ (void)SeekBlob(image,0,SEEK_SET);
+ while(!EOFBlob(image)) /* object parser loop */
+ {
+ ldblk = ReadBlobLSBLong(image);
+ if(EOFBlob(image)) break;
+ if(ldblk>9999 || ldblk<0) return 0;
+ HDR.Type[3] = ldblk % 10; ldblk /= 10; /* T digit */
+ HDR.Type[2] = ldblk % 10; ldblk /= 10; /* P digit */
+ HDR.Type[1] = ldblk % 10; ldblk /= 10; /* O digit */
+ HDR.Type[0] = ldblk; /* M digit */
+
+ if(HDR.Type[3]!=0) return 0; /* Data format */
+ if(HDR.Type[2]!=0) return 0; /* Always 0 */
+
+ ImportPixelAreaOptionsInit(import_options);
+
+ switch(HDR.Type[0])
+ {
+ case 0: ReadBlobXXXLong = ReadBlobLSBLong;
+ ReadBlobXXXDoubles = ReadBlobLSBDoubles;
+ ReadBlobXXXFloats = ReadBlobLSBFloats;
+ import_options->endian = LSBEndian;
+ break;
+ case 1: ReadBlobXXXLong = ReadBlobMSBLong;
+ ReadBlobXXXDoubles = ReadBlobMSBDoubles;
+ ReadBlobXXXFloats = ReadBlobMSBFloats;
+ import_options->endian = MSBEndian;
+ break;
+ default: return 0; /* Unsupported endian */
+ }
+
+ HDR.nRows = ReadBlobXXXLong(image);
+ HDR.nCols = ReadBlobXXXLong(image);
+
+ HDR.imagf = ReadBlobXXXLong(image);
+ if(HDR.imagf!=0 && HDR.imagf!=1) return NULL;
+
+ HDR.nameLen = ReadBlobXXXLong(image);
+ if(HDR.nameLen>0xFFFF) return NULL;
+ (void)SeekBlob(image,HDR.nameLen,SEEK_CUR); /* Skip a matrix name. */
+
+ switch(HDR.Type[1])
+ {
+ case 0: sample_size = 64; /* double-precision (64-bit) floating point numbers */
+ image->depth = Min(QuantumDepth,32); /* double type cell */
+ import_options->sample_type = FloatQuantumSampleType;
+ if(sizeof(double) != 8) return NULL; /* incompatible double size */
+ ldblk = (long) (8 * HDR.nRows);
+ break;
+
+ case 1: sample_size = 32; /* single-precision (32-bit) floating point numbers */
+ image->depth = Min(QuantumDepth,32); /* double type cell */
+ import_options->sample_type = FloatQuantumSampleType;
+#if 0
+ if(sizeof(float) != 4)
+ ThrowMATReaderException(CoderError, IncompatibleSizeOfFloat, image);
+#endif
+ ldblk = (long) (4 * HDR.nRows);
+ break;
+
+ case 2: sample_size = 32; /* 32-bit signed integers */
+ image->depth = Min(QuantumDepth,32); /* Dword type cell */
+ ldblk = (long) (4 * HDR.nRows);
+ import_options->sample_type = UnsignedQuantumSampleType;
+ break;
+
+ case 3: /* 16-bit signed integers */
+ case 4: /* 16-bit unsigned integers */
+ sample_size = 16;
+ image->depth = Min(QuantumDepth,16); /* Word type cell */
+ ldblk = (long) (2 * HDR.nRows);
+ import_options->sample_type = UnsignedQuantumSampleType;
+ break;
+
+ case 5: sample_size = 8; /* 8-bit unsigned integers */
+ image->depth = Min(QuantumDepth,8); /* Byte type cell */
+ import_options->sample_type = UnsignedQuantumSampleType;
+ ldblk = (long) HDR.nRows;
+ break;
+
+ default: return NULL;
+ }
+
+ image->columns = HDR.nRows;
+ image->rows = HDR.nCols;
+ image->colors = 1l << image->depth;
+ if(image->columns == 0 || image->rows == 0) return NULL;
+ if(CheckImagePixelLimits(image, exception) != MagickPass)
+ {
+ return NULL;
+ /* ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); */
+ }
+
+ /* If ping is true, then only set image size and colors without reading any image data. */
+ if(image_info->ping)
+ {
+ unsigned long temp = image->columns; /* The true image is rotater 90 degs. Do rotation without data. */
+ image->columns = image->rows;
+ image->rows = temp;
+ if(HDR.imagf==1) ldblk *= 2;
+ SeekBlob(image, HDR.nCols*ldblk, SEEK_CUR);
+ goto skip_reading_current;
+ }
+
+ /* ----- Load raster data ----- */
+ BImgBuff = MagickAllocateMemory(unsigned char *,(size_t) (ldblk)); /* Ldblk was set in the check phase */
+ if(BImgBuff == NULL) return 0;
+
+ if(HDR.Type[1]==0) /* Find Min and Max Values for doubles */
+ {
+ (void)MagickFindRawImageMinMax(image, import_options->endian, HDR.nRows,
+ HDR.nCols, DoublePixel, ldblk, BImgBuff,
+ &import_options->double_minvalue,
+ &import_options->double_maxvalue);
+ }
+ if(HDR.Type[1]==1) /* Find Min and Max Values for floats */
+ {
+ (void)MagickFindRawImageMinMax(image, import_options->endian, HDR.nRows,
+ HDR.nCols, FloatPixel, ldblk, BImgBuff,
+ &import_options->double_minvalue,
+ &import_options->double_maxvalue);
+ }
+
+ /* Main reader loop. */
+ for(i=0; i<(long)HDR.nCols; i++)
+ {
+ q = SetImagePixels(image, 0, HDR.nCols-i-1, image->columns, 1);
+ if(q == (PixelPacket *)NULL)
+ {
+ /* if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(), */
+ /* " MAT set image pixels returns unexpected NULL on a row %u.", (unsigned)(MATLAB_HDR.SizeY-i-1)); */
+ goto skip_reading_current; /* Skip image rotation, when cannot set image pixels */
+ }
+
+ if(ReadBlob(image,ldblk,(char *)BImgBuff) != (size_t)ldblk)
+ {
+ /* if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(), */
+ /* " MAT cannot read scanrow %u from a file.", (unsigned)(MATLAB_HDR.SizeY-i-1)); */
+ goto ExitLoop;
+ }
+
+ if(ImportImagePixelArea(image,GrayQuantum,sample_size,BImgBuff,import_options,0) == MagickFail)
+ goto ImportImagePixelAreaFailed;
+
+ if(HDR.Type[1]==2 || HDR.Type[1]==3)
+ FixSignedValues(q,HDR.nRows);
+
+ if(!SyncImagePixels(image))
+ {
+ /* if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(), */
+ /* " MAT failed to sync image pixels for a row %u", (unsigned)(MATLAB_HDR.SizeY-i-1)); */
+ goto ExitLoop;
+ }
+ }
+
+ /* Read complex part of data. */
+ if(HDR.imagf==1)
+ {
+ MinVal_c = MaxVal_c = 0;
+ if(HDR.Type[1]==0) /* Find Min and Max Values for doubles */
+ {
+ (void)MagickFindRawImageMinMax(image, import_options->endian, HDR.nRows,
+ HDR.nCols, DoublePixel, ldblk, BImgBuff,
+ &MinVal_c, &MaxVal_c);
+ for(i=0; i<(long)HDR.nCols; i++)
+ {
+ ReadBlobXXXDoubles(image, ldblk, (double *)BImgBuff);
+ InsertComplexDoubleRow((double *)BImgBuff, i, image, MinVal_c, MaxVal_c);
+ }
+ }
+
+ if(HDR.Type[1]==1) /* Find Min and Max Values for floats */
+ {
+ (void)MagickFindRawImageMinMax(image, import_options->endian, HDR.nRows,
+ HDR.nCols, FloatPixel, ldblk, BImgBuff,
+ &MinVal_c, &MaxVal_c);
+ for(i=0; i<(long)HDR.nCols; i++)
+ {
+ ReadBlobXXXFloats(image, ldblk, (float *)BImgBuff);
+ InsertComplexFloatRow((float *)BImgBuff, i, image, MinVal_c, MaxVal_c);
+ }
+ }
+ }
+
+ /* Rotate image. */
+ rotated_image = RotateImage(image, 90.0, exception);
+ if(rotated_image != (Image *) NULL)
+ {
+ /* Remove page offsets added by RotateImage */
+ rotated_image->page.x=0;
+ rotated_image->page.y=0;
+
+ blob = rotated_image->blob;
+ rotated_image->blob = image->blob;
+ rotated_image->colors = image->colors;
+ image->blob = blob;
+ AppendImageToList(&image,rotated_image);
+ DeleteImageFromList(&image);
+ image = rotated_image;
+ }
+
+skip_reading_current:
+ /* Allocate next image structure. */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL) break;
+ image=SyncNextImageInList(image);
+ image->columns = image->rows = 0;
+ image->colors=0;
+
+ /* row scan buffer is no longer needed */
+ MagickFreeMemory(BImgBuff);
+ BImgBuff = NULL;
+
+ }
+
+ImportImagePixelAreaFailed:
+ExitLoop:
+
+ if(BImgBuff!=NULL) MagickFreeMemory(BImgBuff);
+
+ return image;
+}
+
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M A T L A B i m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMATImage reads an MAT X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadMATImage method is:
+%
+% Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMATImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+static Image *ReadMATImage(const ImageInfo *image_info, ExceptionInfo *exception)
+{
+ Image *image, *image2=NULL,
+ *rotated_image;
+ PixelPacket *q;
+ unsigned int status;
+ MATHeader MATLAB_HDR;
+ unsigned long size;
+ magick_uint32_t CellType;
+ ImportPixelAreaOptions import_options;
+ int i;
+ long ldblk;
+ unsigned char *BImgBuff = NULL;
+ double MinVal_c, MaxVal_c;
+ unsigned z, z2;
+ unsigned Frames;
+ int logging;
+ int sample_size;
+ magick_off_t filepos=0x80;
+ BlobInfo *blob;
+ ImageInfo *clone_info = NULL;
+
+ magick_uint32_t (*ReadBlobXXXLong)(Image *image);
+ magick_uint16_t (*ReadBlobXXXShort)(Image *image);
+ size_t (*ReadBlobXXXDoubles)(Image *image, size_t len, double *data);
+ size_t (*ReadBlobXXXFloats)(Image *image, size_t len, float *data);
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ logging = LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+
+ /*
+ Open image file.
+ */
+ image = AllocateImage(image_info);
+
+ status = OpenBlob(image_info, image, ReadBinaryBlobMode, exception);
+ if (status == False)
+ ThrowMATReaderException(FileOpenError, UnableToOpenFile, image);
+
+ /*
+ Read MATLAB image.
+ */
+ if(ReadBlob(image,124,&MATLAB_HDR.identific) != 124)
+ ThrowMATReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if(strncmp(MATLAB_HDR.identific, "MATLAB", 6))
+ {
+ image2 = ReadMATImageV4(image_info,image,&import_options,exception);
+ if(image2==NULL) goto MATLAB_KO;
+ image = image2;
+ goto END_OF_READING;
+ }
+
+ MATLAB_HDR.Version = ReadBlobLSBShort(image);
+ if(ReadBlob(image,2,&MATLAB_HDR.EndianIndicator) != 2)
+ ThrowMATReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ ImportPixelAreaOptionsInit(&import_options);
+
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule()," Endian %c%c",
+ MATLAB_HDR.EndianIndicator[0],MATLAB_HDR.EndianIndicator[1]);
+ if (!strncmp(MATLAB_HDR.EndianIndicator, "IM", 2))
+ {
+ ReadBlobXXXLong = ReadBlobLSBLong;
+ ReadBlobXXXShort = ReadBlobLSBShort;
+ ReadBlobXXXDoubles = ReadBlobLSBDoubles;
+ ReadBlobXXXFloats = ReadBlobLSBFloats;
+ import_options.endian = LSBEndian;
+ }
+ else if (!strncmp(MATLAB_HDR.EndianIndicator, "MI", 2))
+ {
+ ReadBlobXXXLong = ReadBlobMSBLong;
+ ReadBlobXXXShort = ReadBlobMSBShort;
+ ReadBlobXXXDoubles = ReadBlobMSBDoubles;
+ ReadBlobXXXFloats = ReadBlobMSBFloats;
+ import_options.endian = MSBEndian;
+ }
+ else /* unsupported endian */
+ {
+MATLAB_KO: ThrowMATReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+
+ filepos = TellBlob(image);
+ if(filepos < 0)
+ ThrowMATReaderException(BlobError,UnableToObtainOffset,image);
+ while(!EOFBlob(image)) /* object parser loop */
+ {
+ Frames = 1;
+ (void) SeekBlob(image,filepos,SEEK_SET);
+ /* printf("pos=%X\n",TellBlob(image)); */
+
+ MATLAB_HDR.DataType = ReadBlobXXXLong(image);
+ if(EOFBlob(image)) break;
+ MATLAB_HDR.ObjectSize = ReadBlobXXXLong(image);
+ if(EOFBlob(image)) break;
+
+ if(BlobIsSeekable(image))
+ {
+ if(MATLAB_HDR.ObjectSize+filepos > GetBlobSize(image)) /* Safety check for forged and or corrupted data. */
+ {
+ if(logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MAT Object with size %u overflows file with size %u.", (unsigned)MATLAB_HDR.ObjectSize, (unsigned)(GetBlobSize(image)));
+ goto MATLAB_KO;
+ }
+ }
+
+ filepos += MATLAB_HDR.ObjectSize + 4 + 4; /* Position of a next object, when exists. */
+
+ image2 = image;
+#if defined(HasZLIB)
+ if(MATLAB_HDR.DataType == miCOMPRESSED)
+ {
+ if(clone_info==NULL)
+ if((clone_info=CloneImageInfo(image_info)) == NULL)
+ {
+ if(logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "CloneImageInfo failed");
+ continue;
+ }
+ image2 = DecompressBlock(image,&MATLAB_HDR.ObjectSize,clone_info,exception);
+ if(image2==NULL)
+ {
+ if(logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Decompression failed");
+ continue;
+ }
+ MATLAB_HDR.DataType = ReadBlobXXXLong(image2); /* replace compressed object type. */
+ }
+#endif
+
+ if(MATLAB_HDR.DataType!=miMATRIX) continue; /* skip another objects. */
+
+ MATLAB_HDR.unknown1 = ReadBlobXXXLong(image2);
+ MATLAB_HDR.unknown2 = ReadBlobXXXLong(image2);
+
+ MATLAB_HDR.unknown5 = ReadBlobXXXLong(image2);
+ MATLAB_HDR.StructureClass = MATLAB_HDR.unknown5 & 0xFF;
+ MATLAB_HDR.StructureFlag = (MATLAB_HDR.unknown5>>8) & 0xFF;
+
+ MATLAB_HDR.unknown3 = ReadBlobXXXLong(image2);
+ if(image!=image2)
+ MATLAB_HDR.unknown4 = ReadBlobXXXLong(image2); /* ??? don't understand why ?? */
+ MATLAB_HDR.unknown4 = ReadBlobXXXLong(image2);
+ MATLAB_HDR.DimFlag = ReadBlobXXXLong(image2);
+ MATLAB_HDR.SizeX = ReadBlobXXXLong(image2);
+ MATLAB_HDR.SizeY = ReadBlobXXXLong(image2);
+
+
+ switch(MATLAB_HDR.DimFlag)
+ {
+ case 8: z2=z=1; break; /* 2D matrix*/
+ case 12: z2=z = ReadBlobXXXLong(image2); /* 3D matrix RGB*/
+ (void) ReadBlobXXXLong(image2); /* Unknown6 */
+ if(z!=3) ThrowMATReaderException(CoderError, MultidimensionalMatricesAreNotSupported,
+ image);
+ break;
+ case 16: z2=z = ReadBlobXXXLong(image2); /* 4D matrix animation */
+ if(z!=3 && z!=1)
+ ThrowMATReaderException(CoderError, MultidimensionalMatricesAreNotSupported, image);
+ Frames = ReadBlobXXXLong(image2);
+ if (Frames == 0)
+ ThrowMATReaderException(CorruptImageError,ImproperImageHeader,image2);
+ break;
+ default: ThrowMATReaderException(CoderError, MultidimensionalMatricesAreNotSupported,
+ image);
+ }
+
+ MATLAB_HDR.Flag1 = ReadBlobXXXShort(image2);
+ MATLAB_HDR.NameFlag = ReadBlobXXXShort(image2);
+
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "MATLAB_HDR.StructureClass %d",MATLAB_HDR.StructureClass);
+ if (MATLAB_HDR.StructureClass != mxCHAR_CLASS &&
+ MATLAB_HDR.StructureClass != mxSINGLE_CLASS && /* float + complex float */
+ MATLAB_HDR.StructureClass != mxDOUBLE_CLASS && /* double + complex double */
+ MATLAB_HDR.StructureClass != mxINT8_CLASS &&
+ MATLAB_HDR.StructureClass != mxUINT8_CLASS && /* uint8 + uint8 3D */
+ MATLAB_HDR.StructureClass != mxINT16_CLASS &&
+ MATLAB_HDR.StructureClass != mxUINT16_CLASS && /* uint16 + uint16 3D */
+ MATLAB_HDR.StructureClass != mxINT32_CLASS &&
+ MATLAB_HDR.StructureClass != mxUINT32_CLASS && /* uint32 + uint32 3D */
+ MATLAB_HDR.StructureClass != mxINT64_CLASS &&
+ MATLAB_HDR.StructureClass != mxUINT64_CLASS) /* uint64 + uint64 3D */
+ ThrowMATReaderException(CoderError,UnsupportedCellTypeInTheMatrix,image);
+
+ switch (MATLAB_HDR.NameFlag)
+ {
+ case 0:
+ size = ReadBlobXXXLong(image2); /* Object name string size */
+ size = 4 * (long) ((size + 3 + 1) / 4);
+ (void) SeekBlob(image2, size, SEEK_CUR);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ (void) ReadBlob(image2, 4, &size); /* Object name string */
+ break;
+ default:
+ goto MATLAB_KO;
+ }
+
+ CellType = ReadBlobXXXLong(image2); /* Additional object type */
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "MATLAB_HDR.CellType: %d",CellType);
+
+ (void) ReadBlob(image2, 4, &size); /* data size */
+
+NEXT_FRAME:
+ /* Image is gray when no complex flag is set and 2D Matrix */
+ image->is_grayscale = (MATLAB_HDR.DimFlag==8) &&
+ ((MATLAB_HDR.StructureFlag & FLAG_COMPLEX) == 0);
+
+ switch (CellType)
+ {
+ case miINT8:
+ case miUINT8:
+ sample_size = 8;
+ if(MATLAB_HDR.StructureFlag & FLAG_LOGICAL)
+ image->depth = 1;
+ else
+ image->depth = Min(QuantumDepth,8); /* Byte type cell */
+ import_options.sample_type = UnsignedQuantumSampleType;
+ ldblk = (long) MATLAB_HDR.SizeX;
+ break;
+ case miINT16:
+ case miUINT16:
+ sample_size = 16;
+ image->depth = Min(QuantumDepth,16); /* Word type cell */
+ ldblk = (long) (2 * MATLAB_HDR.SizeX);
+ import_options.sample_type = UnsignedQuantumSampleType;
+ break;
+ case miINT32:
+ case miUINT32:
+ sample_size = 32;
+ image->depth = Min(QuantumDepth,32); /* Dword type cell */
+ ldblk = (long) (4 * MATLAB_HDR.SizeX);
+ import_options.sample_type = UnsignedQuantumSampleType;
+ break;
+ case miINT64:
+ case miUINT64:
+ sample_size = 64;
+ image->depth = Min(QuantumDepth,32); /* Qword type cell */
+ ldblk = (long) (8 * MATLAB_HDR.SizeX);
+ import_options.sample_type = UnsignedQuantumSampleType;
+ break;
+ case miSINGLE:
+ sample_size = 32;
+ image->depth = Min(QuantumDepth,32); /* double type cell */
+ import_options.sample_type = FloatQuantumSampleType;
+#if 0
+ if (sizeof(float) != 4)
+ ThrowMATReaderException(CoderError, IncompatibleSizeOfFloat, image);
+#endif
+ if (MATLAB_HDR.StructureFlag & FLAG_COMPLEX)
+ { /* complex float type cell */
+ }
+ ldblk = (long) (4 * MATLAB_HDR.SizeX);
+ break;
+ case miDOUBLE:
+ sample_size = 64;
+ image->depth = Min(QuantumDepth,32); /* double type cell */
+ import_options.sample_type = FloatQuantumSampleType;
+ if (sizeof(double) != 8)
+ ThrowMATReaderException(CoderError, IncompatibleSizeOfDouble, image);
+ if (MATLAB_HDR.StructureFlag & FLAG_COMPLEX)
+ { /* complex double type cell */
+ }
+ ldblk = (long) (8 * MATLAB_HDR.SizeX);
+ break;
+ default:
+ ThrowMATReaderException(CoderError, UnsupportedCellTypeInTheMatrix, image)
+ }
+
+ image->columns = MATLAB_HDR.SizeX;
+ image->rows = MATLAB_HDR.SizeY;
+ image->colors = 1l << image->depth;
+ if(image->columns == 0 || image->rows == 0)
+ goto MATLAB_KO;
+ if((unsigned long)ldblk*MATLAB_HDR.SizeY > MATLAB_HDR.ObjectSize) /* Safety check for forged and or corrupted data. */
+ goto MATLAB_KO;
+
+ if(CheckImagePixelLimits(image, exception) != MagickPass)
+ {
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ }
+
+ /* ----- Create gray palette ----- */
+
+ if (CellType==miUINT8 && z!=3)
+ {
+ if(image->colors>256) image->colors = 256;
+
+ if (!AllocateImageColormap(image, image->colors))
+ {
+NoMemory: ThrowMATReaderException(ResourceLimitError, MemoryAllocationFailed,
+ image)}
+ }
+
+ /*
+ If ping is true, then only set image size and colors without
+ reading any image data.
+ */
+ if (image_info->ping)
+ {
+ unsigned long temp = image->columns; /* The true image is rotater 90 degs. Do rotation without data. */
+ image->columns = image->rows;
+ image->rows = temp;
+ goto skip_reading_current;
+ }
+
+ /* ----- Load raster data ----- */
+ BImgBuff = MagickAllocateMemory(unsigned char *,(size_t) (ldblk)); /* Ldblk was set in the check phase */
+ if (BImgBuff == NULL)
+ goto NoMemory;
+
+ if (CellType==miDOUBLE) /* Find Min and Max Values for floats */
+ {
+ (void) MagickFindRawImageMinMax(image2, import_options.endian,MATLAB_HDR.SizeX,
+ MATLAB_HDR.SizeY,DoublePixel, ldblk, BImgBuff,
+ &import_options.double_minvalue,
+ &import_options.double_maxvalue);
+ }
+ if (CellType==miSINGLE) /* Find Min and Max Values for floats */
+ {
+ (void) MagickFindRawImageMinMax(image2, import_options.endian,MATLAB_HDR.SizeX,
+ MATLAB_HDR.SizeY,FloatPixel, ldblk, BImgBuff,
+ &import_options.double_minvalue,
+ &import_options.double_maxvalue);
+ }
+
+ /* Main loop for reading all scanlines */
+ if(z==1) z=0; /* read grey scanlines */
+ /* else read color scanlines */
+ do
+ {
+ for(i = 0; i < (long) MATLAB_HDR.SizeY; i++)
+ {
+ q = SetImagePixels(image,0,MATLAB_HDR.SizeY-i-1,image->columns,1);
+ if (q == (PixelPacket *)NULL)
+ {
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MAT set image pixels returns unexpected NULL on a row %u.", (unsigned)(MATLAB_HDR.SizeY-i-1));
+ goto skip_reading_current; /* Skip image rotation, when cannot set image pixels */
+ }
+ if(ReadBlob(image2,ldblk,(char *)BImgBuff) != (size_t) ldblk)
+ {
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MAT cannot read scanrow %u from a file.", (unsigned)(MATLAB_HDR.SizeY-i-1));
+ goto ExitLoop;
+ }
+ if((CellType==miINT8 || CellType==miUINT8) && (MATLAB_HDR.StructureFlag & FLAG_LOGICAL))
+ {
+ FixLogical((unsigned char *)BImgBuff,ldblk);
+ if(ImportImagePixelArea(image,z2qtype[z],1,BImgBuff,&import_options,0) == MagickFail)
+ {
+ImportImagePixelAreaFailed:
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MAT failed to ImportImagePixelArea for a row %u", (unsigned)(MATLAB_HDR.SizeY-i-1));
+ break;
+ }
+ }
+ else
+ {
+ if(ImportImagePixelArea(image,z2qtype[z],sample_size,BImgBuff,&import_options,0) == MagickFail)
+ goto ImportImagePixelAreaFailed;
+
+ if (z<=1 && /* fix only during a last pass z==0 || z==1 */
+ (CellType==miINT8 || CellType==miINT16 || CellType==miINT32 || CellType==miINT64))
+ FixSignedValues(q,MATLAB_HDR.SizeX);
+ }
+
+ if (!SyncImagePixels(image))
+ {
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MAT failed to sync image pixels for a row %u", (unsigned)(MATLAB_HDR.SizeY-i-1));
+ goto ExitLoop;
+ }
+ }
+ } while(z-- >= 2);
+ExitLoop:
+
+
+ /* Read complex part of numbers here */
+ if (MATLAB_HDR.StructureFlag & FLAG_COMPLEX)
+ { /* Find Min and Max Values for complex parts of floats */
+ MinVal_c = MaxVal_c = 0;
+ CellType = ReadBlobXXXLong(image2); /* Additional object type */
+ i = ReadBlobXXXLong(image2); /* size of a complex part - toss away*/
+
+ if (CellType==miDOUBLE)
+ {
+ (void) MagickFindRawImageMinMax(image2, import_options.endian, MATLAB_HDR.SizeX,
+ MATLAB_HDR.SizeY, DoublePixel, ldblk, BImgBuff,
+ &MinVal_c, &MaxVal_c);
+ }
+ if(CellType==miSINGLE)
+ {
+ (void) MagickFindRawImageMinMax(image2, import_options.endian, MATLAB_HDR.SizeX,
+ MATLAB_HDR.SizeY, FloatPixel, ldblk, BImgBuff,
+ &MinVal_c, &MaxVal_c);
+ }
+
+ if (CellType==miDOUBLE)
+ for (i = 0; i < (long) MATLAB_HDR.SizeY; i++)
+ {
+ ReadBlobXXXDoubles(image2, ldblk, (double *)BImgBuff);
+ InsertComplexDoubleRow((double *)BImgBuff, i, image, MinVal_c, MaxVal_c);
+ }
+
+ if (CellType==miSINGLE)
+ for (i = 0; i < (long) MATLAB_HDR.SizeY; i++)
+ {
+ ReadBlobXXXFloats(image2, ldblk, (float *)BImgBuff);
+ InsertComplexFloatRow((float *)BImgBuff, i, image, MinVal_c, MaxVal_c);
+ }
+ }
+
+ /* Image is gray when no complex flag is set and 2D Matrix AGAIN!!! */
+ image->is_grayscale = (MATLAB_HDR.DimFlag==8) &&
+ ((MATLAB_HDR.StructureFlag & FLAG_COMPLEX) == 0);
+ image->is_monochrome = image->depth==1;
+ if(image->is_monochrome)
+ image->colorspace=GRAYColorspace;
+
+ if(image2==image) /* image2 is either native image or decompressed block. */
+ image2 = NULL; /* Remove shadow copy to an image before rotation. */
+
+ /* Rotate image. */
+ rotated_image = RotateImage(image, 90.0, exception);
+ if(rotated_image != (Image *) NULL)
+ {
+ /* Remove page offsets added by RotateImage */
+ rotated_image->page.x=0;
+ rotated_image->page.y=0;
+
+ blob = rotated_image->blob;
+ rotated_image->blob = image->blob;
+ rotated_image->colors = image->colors;
+ image->blob = blob;
+ AppendImageToList(&image,rotated_image);
+ DeleteImageFromList(&image);
+ }
+
+skip_reading_current:
+
+ if(image2==image) image2 = NULL;
+
+ /* Allocate next image structure. */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL) break;
+ image=SyncNextImageInList(image);
+ image->columns = image->rows = 0;
+ image->colors=0;
+
+ /* row scan buffer is no longer needed */
+ MagickFreeMemory(BImgBuff);
+ BImgBuff = NULL;
+
+ if(--Frames>0)
+ {
+ z = z2;
+ if(image2==NULL) image2 = image;
+ goto NEXT_FRAME;
+ }
+
+ if(image2!=NULL)
+ if(image2!=image) /* Does shadow temporary decompressed image exist? */
+ {
+/* CloseBlob(image2); */
+ DeleteImageFromList(&image2);
+ if(clone_info)
+ {
+ if(clone_info->file)
+ {
+ fclose(clone_info->file);
+ clone_info->file = NULL;
+ (void) unlink(clone_info->filename);
+ }
+ }
+ }
+
+ }
+
+ MagickFreeMemory(BImgBuff);
+END_OF_READING:
+ CloseBlob(image);
+
+ {
+ Image *p;
+ long scene=0;
+
+ /*
+ Rewind list, removing any empty images while rewinding.
+ */
+ p=image;
+ image=NULL;
+ while (p != (Image *)NULL)
+ {
+ Image *tmp=p;
+ if ((p->rows == 0) || (p->columns == 0)) {
+ p=p->previous;
+ DeleteImageFromList(&tmp);
+ } else {
+ image=p;
+ p=p->previous;
+ }
+ }
+
+ /*
+ Fix scene numbers
+ */
+ for (p=image; p != (Image *) NULL; p=p->next)
+ p->scene=scene++;
+ }
+
+ if(clone_info != NULL) /* cleanup garbage file from compression */
+ {
+ if(clone_info->file)
+ {
+ fclose(clone_info->file);
+ clone_info->file = NULL;
+ (void) unlink(clone_info->filename);
+ }
+ DestroyImageInfo(clone_info);
+ clone_info = NULL;
+ }
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ if(image==NULL)
+ ThrowMATReaderException(CorruptImageError,ImageFileDoesNotContainAnyImageData,image);
+ return (image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M A T L A B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Function WriteMATLABImage writes an Matlab matrix to a file.
+%
+% The format of the WriteMATLABImage method is:
+%
+% unsigned int WriteMATLABImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Function WriteMATLABImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+*/
+static unsigned int WriteMATLABImage(const ImageInfo *image_info,Image *image)
+{
+ long y;
+ unsigned z;
+ unsigned int status;
+ int logging;
+ unsigned long DataSize;
+ char padding;
+ char MATLAB_HDR[0x80];
+ time_t current_time;
+ const struct tm *t;
+ unsigned char *pixels;
+ int is_gray;
+ unsigned char ImageName = 'A';
+
+ current_time = time((time_t *)NULL);
+ t = localtime(&current_time);
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter MAT");
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Store MAT header.
+ */
+ (void) memset(MATLAB_HDR,' ',Min(sizeof(MATLAB_HDR),124));
+ sprintf(MATLAB_HDR,"MATLAB 5.0 MAT-file, Platform: %.8s, Created on: %.3s %.3s %2d %2d:%2d:%2d %d",
+ OsDesc,
+ DayOfWTab[t->tm_wday],
+ MonthsTab[t->tm_mon],
+ t->tm_mday,
+ t->tm_hour,t->tm_min,t->tm_sec,
+ t->tm_year+1900);
+ MATLAB_HDR[0x7C]=0;
+ MATLAB_HDR[0x7D]=1;
+ MATLAB_HDR[0x7E]='I';
+ MATLAB_HDR[0x7F]='M';
+ (void) WriteBlob(image,sizeof(MATLAB_HDR),MATLAB_HDR);
+
+ pixels=(unsigned char *) NULL;
+ while(image!=NULL)
+ {
+ pixels=MagickAllocateMemory(unsigned char *,image->rows);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ is_gray = IsGrayImage(image,&image->exception);
+ z = is_gray ? 0 : 3;
+
+ DataSize = image->rows /*Y*/ * image->columns /*X*/;
+ if(!is_gray) DataSize *= 3 /*Z*/;
+ padding=((unsigned char)(DataSize-1) & 0x7) ^ 0x7;
+
+ (void) WriteBlobLSBLong(image, miMATRIX); /* 0x80 */
+ (void) WriteBlobLSBLong(image, DataSize + padding + (is_gray?48l:56l)); /* 0x84 */
+ (void) WriteBlobLSBLong(image, 0x6); /* 0x88 */
+ (void) WriteBlobLSBLong(image, 0x8); /* 0x8C */
+ (void) WriteBlobLSBLong(image, 0x6); /* 0x90 */
+ (void) WriteBlobLSBLong(image, 0);
+ (void) WriteBlobLSBLong(image, 0x5); /* 0x98 */
+ (void) WriteBlobLSBLong(image, is_gray?0x8:0xC); /* 0x9C - DimFlag */
+ (void) WriteBlobLSBLong(image, image->rows); /* x: 0xA0 */
+ (void) WriteBlobLSBLong(image, image->columns); /* y: 0xA4 */
+ if(!is_gray)
+ {
+ (void) WriteBlobLSBLong(image, 3); /* z: 0xA8 */
+ (void) WriteBlobLSBLong(image, 0);
+ }
+ (void) WriteBlobLSBShort(image, 1); /* 0xB0 */
+ (void) WriteBlobLSBShort(image, 1); /* 0xB2 */
+ (void) WriteBlobLSBLong(image, ImageName++); /* 0xB4 - here is a small bug only 'A' .. 'Z images could be generated properly */
+ (void) WriteBlobLSBLong(image, 0x2); /* 0xB8 */
+ (void) WriteBlobLSBLong(image, DataSize); /* 0xBC */
+
+ /*
+ Store image data.
+ */
+ {
+ magick_uint64_t
+ progress_span;
+
+ magick_int64_t
+ progress_quantum;
+
+ progress_span = image->columns;
+ if(!is_gray) progress_span *= 3;
+ progress_quantum = 0;
+
+ do
+ {
+ for (y=0; y<(long)image->columns; y++)
+ {
+ progress_quantum++;
+ (void) AcquireImagePixels(image,y,0,1,image->rows,&image->exception);
+ (void) ExportImagePixelArea(image,z2qtype[z],8,pixels,0,0);
+ (void) WriteBlob(image,image->rows,pixels);
+ if (QuantumTick(progress_quantum,progress_span))
+ if (!MagickMonitorFormatted(progress_quantum,progress_span,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ goto BreakAll;
+ }
+ } while(z-- >= 2);
+ }
+BreakAll:
+
+ while(padding-->0) (void) WriteBlobByte(image,0);
+
+ status=True;
+
+ if(pixels)
+ {MagickFreeMemory(pixels);pixels=NULL;}
+ if(image->next==NULL) break;
+ image=SyncNextImageInList(image);
+ }
+
+ CloseBlob(image);
+ MagickFreeMemory(pixels);
+
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return MAT");
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M A T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMATImage adds attributes for the MAT image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMATImage method is:
+%
+% RegisterMATImage(void)
+%
+*/
+ModuleExport void RegisterMATImage(void)
+{
+ MagickInfo * entry;
+
+ entry = SetMagickInfo("MAT");
+ entry->decoder = (DecoderHandler) ReadMATImage;
+ entry->encoder = (EncoderHandler) WriteMATLABImage;
+ entry->seekable_stream = True;
+ entry->description =
+#if defined(HasZLIB)
+ "MATLAB Level 4.0-7.0 image formats";
+#else
+ "MATLAB Level 4.0-6.0 image formats";
+#endif
+ entry->module = "MAT";
+ entry->blob_support=False;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M A T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMATImage removes format registrations made by the
+% MAT module from the list of supported formats.
+%
+% The format of the UnregisterMATImage method is:
+%
+% UnregisterMATImage(void)
+%
+*/
+ModuleExport void UnregisterMATImage(void)
+{
+ (void) UnregisterMagickInfo("MAT");
+}
diff --git a/coders/matte.c b/coders/matte.c
new file mode 100644
index 0000000..6872a94
--- /dev/null
+++ b/coders/matte.c
@@ -0,0 +1,201 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M AAA TTTTT TTTTT EEEEE %
+% MM MM A A T T E %
+% M M M AAAAA T T EEE %
+% M M A A T T E %
+% M M A A T T EEEEE %
+% %
+% %
+% Write Matte Channel To MIFF File. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMATTEImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M A T T E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMATTEImage adds attributes for the MATTE image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMATTEImage method is:
+%
+% RegisterMATTEImage(void)
+%
+*/
+ModuleExport void RegisterMATTEImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("MATTE");
+ entry->encoder=(EncoderHandler) WriteMATTEImage;
+ entry->raw=True;
+ entry->description="MATTE raw opacity format";
+ entry->module="MATTE";
+ entry->extension_treatment=ObeyExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M A T T E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMATTEImage removes format registrations made by the
+% MATTE module from the list of supported formats.
+%
+% The format of the UnregisterMATTEImage method is:
+%
+% UnregisterMATTEImage(void)
+%
+*/
+ModuleExport void UnregisterMATTEImage(void)
+{
+ (void) UnregisterMagickInfo("MATTE");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M A T T E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Function WriteMATTEImage writes an image of matte bytes to a file. It
+% consists of data from the matte component of the image [0..255].
+%
+% The format of the WriteMATTEImage method is:
+%
+% unsigned int WriteMATTEImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Function WriteMATTEImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteMATTEImage(const ImageInfo *image_info,Image *image)
+{
+ Image
+ *matte_image;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ status;
+
+ if (!image->matte)
+ ThrowWriterException(CoderError,ImageDoesNotHaveAMatteChannel,image);
+ matte_image=
+ CloneImage(image,image->columns,image->rows,True,&image->exception);
+ if (matte_image == (Image *) NULL)
+ return(False);
+ (void) (void) SetImageType(matte_image,TrueColorType);
+ /*
+ Convert image to matte pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ q=SetImagePixels(matte_image,0,y,matte_image->columns,1);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=p->opacity;
+ q->green=p->opacity;
+ q->blue=p->opacity;
+ q->opacity=OpaqueOpacity;
+ p++;
+ q++;
+ }
+ if (!SyncImagePixels(matte_image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) FormatString(matte_image->filename,"MIFF:%.1024s",image->filename);
+ status=WriteImage(image_info,matte_image);
+ DestroyImage(matte_image);
+ return(status);
+}
diff --git a/coders/meta.c b/coders/meta.c
new file mode 100644
index 0000000..b602181
--- /dev/null
+++ b/coders/meta.c
@@ -0,0 +1,2425 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M EEEEE TTTTT AAA %
+% MM MM E T A A %
+% M M M EEE T AAAAA %
+% M M E T A A %
+% M M EEEEE T A A %
+% %
+% %
+% Read/Write Embedded Image Profiles %
+% %
+% %
+% Software Design %
+% William Radcliffe %
+% July 2001 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/profile.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMETAImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M E T A %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsMETA returns True if the image format type, identified by the
+% magick string, is META.
+%
+% The format of the IsMETA method is:
+%
+% unsigned int IsMETA(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsMETA returns True if the image format type is META.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+#ifdef IMPLEMENT_IS_FUNCTION
+static unsigned int IsMETA(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (LocaleNCompare((char *) magick,"8BIM",4) == 0)
+ return(True);
+ if (LocaleNCompare((char *) magick,"APP1",4) == 0)
+ return(True);
+ if (LocaleNCompare((char *) magick,"\034\002",2) == 0)
+ return(True);
+ return(False);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M E T A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMETAImage reads a META image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadMETAImage method is:
+%
+% Image *ReadMETAImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% Decompression code contributed by Kyle Shorter.
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMETAImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to an ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define BUFFER_SZ 4096
+
+typedef struct _html_code
+{
+ unsigned short
+ len;
+
+ const char
+ *code,
+ val;
+
+} html_code;
+
+static html_code const html_codes[] = {
+#ifdef HANDLE_GT_LT
+ { 4,"&lt;",'<' },
+ { 4,"&gt;",'>' },
+#endif
+ { 5,"&amp;",'&' },
+ { 6,"&quot;",'"' },
+ { 6,"&apos;",'\''}
+};
+
+static int stringnicmp(const char *p,const char *q,size_t n)
+{
+ register long
+ i,
+ j;
+
+ if (p == q)
+ return(0);
+ if (p == (char *) NULL)
+ return(-1);
+ if (q == (char *) NULL)
+ return(1);
+ while ((*p != '\0') && (*q != '\0'))
+ {
+ if ((*p == '\0') || (*q == '\0'))
+ break;
+ i=(*p);
+ if (islower(i))
+ i=toupper(i);
+ j=(*q);
+ if (islower(j))
+ j=toupper(j);
+ if (i != j)
+ break;
+ n--;
+ if (n == 0)
+ break;
+ p++;
+ q++;
+ }
+ return(toupper((int) *p)-toupper((int) *q));
+}
+
+static size_t convertHTMLcodes(char *s, const size_t len)
+{
+ int val;
+
+ if ((len == 0) || (s == (char*) NULL) || (*s=='\0'))
+ return 0;
+
+ /*
+ Check for hex or decimal character escape.
+
+ e.g. hex: "&#xA0;", decimal "&#160;"
+
+ Note that scanf is expected to parse the number in hex or decimal
+ and that it does not require the terminating ';' to appear in
+ order to parse the numeric argument.
+ */
+ if ((len > 3) && (s[1] == '#') && (strchr(s,';') != (char *) NULL) &&
+ (sscanf(s,"&#%d;",&val) == 1))
+ {
+ size_t o = 3;
+ while (s[o] != ';')
+ {
+ o++;
+ if (o > 5)
+ break;
+ }
+ if (o < 6)
+ (void) memmove(s+1,s+1+o,strlen(s+1+o)+1);
+ *s = val;
+ return o;
+ }
+ else
+ {
+ int
+ i,
+ codes = sizeof(html_codes) / sizeof(html_code);
+
+ for (i=0; i < codes; i++)
+ {
+ if (html_codes[i].len <= len)
+ if (stringnicmp(s, html_codes[i].code, (size_t) (html_codes[i].len)) == 0)
+ {
+ (void) memmove(s+1, s+html_codes[i].len, strlen(s+html_codes[i].len)+1);
+ *s = html_codes[i].val;
+ return html_codes[i].len-1;
+ }
+ }
+ }
+ return 0;
+}
+
+static char *super_fgets(char **b, size_t *blen, Image *file)
+{
+ int
+ c;
+
+ size_t
+ len;
+
+ unsigned char
+ *p,
+ *q;
+
+ len=*blen;
+ p=(unsigned char *) (*b);
+ for (q=p; ; q++)
+ {
+ c=ReadBlobByte(file);
+ if (c == EOF || c == '\n')
+ break;
+ if ((q-p+1) >= (int) len)
+ {
+ int
+ tlen;
+
+ tlen=q-p;
+ len<<=1;
+ MagickReallocMemory(unsigned char *,p,(len+2));
+ *b=(char *) p;
+ if (p == (unsigned char *) NULL)
+ break;
+ q=p+tlen;
+ }
+ *q=(unsigned char) c;
+ }
+ *blen=0;
+ if (p != (unsigned char *) NULL)
+ {
+ int
+ tlen;
+
+ tlen=q-p;
+ if (tlen == 0)
+ return (char *) NULL;
+ p[tlen] = '\0';
+ *blen=++tlen;
+ }
+ return (char *)p;
+}
+
+#define BUFFER_SZ 4096
+#define IPTC_ID 1028
+#define THUMBNAIL_ID 1033
+
+static long parse8BIM(Image *ifile, Image *ofile)
+{
+ char
+ brkused,
+ quoted,
+ *line = (char *) NULL,
+ *token = (char *) NULL,
+ *newstr = (char *) NULL,
+ *name = (char *) NULL;
+
+ int
+ state,
+ next;
+
+ unsigned char
+ dataset;
+
+ unsigned int
+ recnum;
+
+ size_t
+ inputlen = BUFFER_SZ;
+
+ ssize_t
+ savedolen = 0L,
+ outputlen = 0L;
+
+ ExtendedSignedIntegralType
+ savedpos,
+ currentpos;
+
+ TokenInfo
+ token_info;
+
+ dataset = 0;
+ recnum = 0;
+ line = MagickAllocateMemory(char *,inputlen);
+ if (line == (char *) NULL)
+ goto parse8BIM_failure;
+ savedpos = 0;
+ while(super_fgets(&line,&inputlen,ifile)!=NULL)
+ {
+ state=0;
+ next=0;
+
+ token = MagickAllocateMemory(char *,inputlen);
+ if (token == (char *) NULL)
+ goto parse8BIM_failure;
+ newstr = MagickAllocateMemory(char *,inputlen);
+ if (newstr == (char *) NULL)
+ goto parse8BIM_failure;
+ while (Tokenizer(&token_info, 0, token, inputlen, line,
+ (char *) "", (char *) "=",
+ (char *) "\"", 0, &brkused,&next,&quoted)==0)
+ {
+ if (state == 0)
+ {
+ int
+ state,
+ next;
+
+ char
+ brkused,
+ quoted;
+
+ state=0;
+ next=0;
+ while(Tokenizer(&token_info, 0, newstr, inputlen, token, (char *) "",
+ (char *) "#", (char *) "", 0, &brkused, &next, &quoted)==0)
+ {
+ switch (state)
+ {
+ case 0:
+ if (strcmp(newstr,"8BIM")==0)
+ dataset = 255;
+ else
+ dataset = (unsigned char) MagickAtoI(newstr);
+ break;
+ case 1:
+ recnum = MagickAtoI(newstr);
+ break;
+ case 2:
+ name = MagickAllocateMemory(char *,strlen(newstr)+1);
+ if (name == (char *) NULL)
+ goto parse8BIM_failure;
+ (void) strcpy(name,newstr);
+ break;
+ }
+ state++;
+ }
+ }
+ else
+ if (state == 1)
+ {
+ int
+ next;
+
+ size_t
+ len;
+
+ char
+ brkused,
+ quoted;
+
+ next=0;
+ len = (unsigned long) strlen(token);
+ while (Tokenizer(&token_info,0, newstr, inputlen, token, (char *) "",
+ (char *) "&", (char *) "", 0, &brkused, &next, &quoted)==0)
+ {
+ if (brkused && next > 0)
+ {
+ size_t
+ codes_len;
+
+ char
+ *s = &token[next-1];
+
+ codes_len = convertHTMLcodes(s, strlen(s));
+ if (codes_len > len)
+ len = 0;
+ else
+ len -= codes_len;
+ }
+ }
+
+ if (dataset == 255U)
+ {
+ unsigned char
+ nlen = 0;
+
+ int
+ i;
+
+ if (savedolen > 0)
+ {
+ long diff = outputlen - savedolen;
+ currentpos = TellBlob(ofile);
+ if (currentpos < 0)
+ goto parse8BIM_failure;
+ (void) SeekBlob(ofile,savedpos,SEEK_SET);
+ (void) WriteBlobMSBLong(ofile,diff);
+ (void) SeekBlob(ofile,currentpos,SEEK_SET);
+ savedolen = 0L;
+ }
+ if (outputlen & 1)
+ {
+ (void) WriteBlobByte(ofile,0x00);
+ outputlen++;
+ }
+ (void) WriteBlobString(ofile,"8BIM");
+ (void) WriteBlobMSBShort(ofile,recnum);
+ outputlen += 6;
+ if (name)
+ nlen = (unsigned char) strlen(name);
+ (void) WriteBlobByte(ofile,nlen);
+ outputlen++;
+ for (i=0; i<nlen; i++)
+ (void) WriteBlobByte(ofile,name[i]);
+ outputlen += nlen;
+ if (!(nlen&1))
+ {
+ (void) WriteBlobByte(ofile,0x00);
+ outputlen++;
+ }
+ if (recnum != IPTC_ID)
+ {
+ (void) WriteBlobMSBLong(ofile, (const magick_uint32_t) len);
+ outputlen += 4;
+
+ next=0;
+ outputlen += len;
+ while (len--)
+ (void) WriteBlobByte(ofile,token[next++]);
+
+ if (outputlen & 1)
+ {
+ (void) WriteBlobByte(ofile,0x00);
+ outputlen++;
+ }
+ }
+ else
+ {
+ /* patch in a fake length for now and fix it later */
+ savedpos = TellBlob(ofile);
+ if (savedpos < 0)
+ goto parse8BIM_failure;
+ (void) WriteBlobMSBLong(ofile,0xFFFFFFFFUL);
+ outputlen += 4;
+ savedolen = outputlen;
+ }
+ }
+ else
+ {
+ if (len <= 0x7FFF)
+ {
+ (void) WriteBlobByte(ofile,0x1c);
+ (void) WriteBlobByte(ofile,dataset);
+ (void) WriteBlobByte(ofile,recnum & 255);
+ (void) WriteBlobMSBShort(ofile,(const magick_uint16_t) len);
+ outputlen += 5;
+ next=0;
+ outputlen += len;
+ while (len--)
+ (void) WriteBlobByte(ofile,token[next++]);
+ }
+ }
+ }
+ state++;
+ }
+ MagickFreeMemory(token);
+ MagickFreeMemory(newstr);
+ MagickFreeMemory(name);
+ }
+ MagickFreeMemory(line);
+ if (savedolen > 0)
+ {
+ long diff = outputlen - savedolen;
+
+ currentpos = TellBlob(ofile);
+ if (currentpos < 0)
+ goto parse8BIM_failure;
+
+ (void) SeekBlob(ofile,savedpos,SEEK_SET);
+ (void) WriteBlobMSBLong(ofile,diff);
+ (void) SeekBlob(ofile,currentpos,SEEK_SET);
+ savedolen = 0L;
+ }
+ return outputlen;
+
+ parse8BIM_failure:
+ MagickFreeMemory(token);
+ MagickFreeMemory(newstr);
+ MagickFreeMemory(name);
+ MagickFreeMemory(line);
+ return 0L;
+}
+
+static char *super_fgets_w(char **b, size_t *blen, Image *file)
+{
+ size_t
+ len;
+
+ int
+ c;
+
+ unsigned char
+ *p,
+ *q;
+
+ len=*blen;
+ p=(unsigned char *) (*b);
+ for (q=p; ; q++)
+ {
+ c=ReadBlobLSBShort(file);
+ if (c == ((unsigned short) ~0U) || c == '\n')
+ break;
+ if (EOFBlob(file))
+ break;
+ if ((q-p+1) >= (int) len)
+ {
+ int
+ tlen;
+
+ tlen=q-p;
+ len<<=1;
+ MagickReallocMemory(unsigned char *,p,(len+2));
+ *b=(char *) p;
+ if (p == (unsigned char *) NULL)
+ break;
+ q=p+tlen;
+ }
+ *q=(unsigned char) c;
+ }
+ *blen=0;
+ if ((*b) != (char *) NULL)
+ {
+ int
+ tlen;
+
+ tlen=q-p;
+ if (tlen == 0)
+ return (char *) NULL;
+ p[tlen] = '\0';
+ *blen=++tlen;
+ }
+ return (char *) p;
+}
+
+static long parse8BIMW(Image *ifile, Image *ofile)
+{
+ char
+ brkused,
+ quoted,
+ *line = (char *) NULL,
+ *token = (char *) NULL,
+ *newstr = (char *) NULL,
+ *name = (char *) NULL;
+
+ int
+ state,
+ next;
+
+ unsigned char
+ dataset;
+
+ unsigned int
+ recnum;
+
+ size_t
+ inputlen = BUFFER_SZ;
+
+ ssize_t
+ savedolen = 0L,
+ outputlen = 0L;
+
+ ExtendedSignedIntegralType
+ savedpos,
+ currentpos;
+
+ TokenInfo
+ token_info;
+
+ dataset = 0;
+ recnum = 0;
+ line = MagickAllocateMemory(char *,inputlen);
+ if (line == (char *) NULL)
+ goto parse8BIMW_failure;
+ name = token = (char *)NULL;
+ savedpos = 0;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "META CODER Parse8BIM");
+ while(super_fgets_w(&line,&inputlen,ifile)!=NULL)
+ {
+ state=0;
+ next=0;
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "META CODER Parse8BIM: %s (%lu)",line, (unsigned long) inputlen);
+ token = MagickAllocateMemory(char *,inputlen);
+ if (token == (char *) NULL)
+ goto parse8BIMW_failure;
+ newstr = MagickAllocateMemory(char *,inputlen);
+ if (newstr == (char *) NULL)
+ goto parse8BIMW_failure;
+ while (Tokenizer(&token_info, 0, token, inputlen, line,
+ (char *) "", (char *) "=",
+ (char *) "\"", 0, &brkused,&next,&quoted)==0)
+ {
+ if (state == 0)
+ {
+ int
+ state,
+ next;
+
+ char
+ brkused,
+ quoted;
+
+ state=0;
+ next=0;
+ while(Tokenizer(&token_info, 0, newstr, inputlen, token, (char *) "",
+ (char *) "#", (char *) "", 0, &brkused, &next, &quoted)==0)
+ {
+ switch (state)
+ {
+ case 0:
+ if (strcmp(newstr,"8BIM")==0)
+ dataset = 255;
+ else
+ dataset = (unsigned char) MagickAtoI(newstr);
+ break;
+ case 1:
+ recnum = MagickAtoI(newstr);
+ break;
+ case 2:
+ name = MagickAllocateMemory(char *,strlen(newstr)+1);
+ if (name == (char *) NULL)
+ goto parse8BIMW_failure;
+ (void) strcpy(name,newstr);
+ break;
+ }
+ state++;
+ }
+ }
+ else
+ if (state == 1)
+ {
+ int
+ next;
+
+ size_t
+ len;
+
+ char
+ brkused,
+ quoted;
+
+ next=0;
+ len = (unsigned long) strlen(token);
+ while (Tokenizer(&token_info,0, newstr, inputlen, token, (char *) "",
+ (char *) "&", (char *) "", 0, &brkused, &next, &quoted)==0)
+ {
+ if (brkused && next > 0)
+ {
+ size_t
+ codes_len;
+
+ char
+ *s = &token[next-1];
+
+ codes_len = convertHTMLcodes(s, strlen(s));
+ if (codes_len > len)
+ len = 0;
+ else
+ len -= codes_len;
+ }
+ }
+
+ if (dataset == 255)
+ {
+ unsigned char
+ nlen = 0;
+
+ int
+ i;
+
+ if (savedolen > 0)
+ {
+ long diff = outputlen - savedolen;
+ currentpos = TellBlob(ofile);
+ if (currentpos < 0)
+ goto parse8BIMW_failure;
+ (void) SeekBlob(ofile,savedpos,SEEK_SET);
+ (void) WriteBlobMSBLong(ofile,diff);
+ (void) SeekBlob(ofile,currentpos,SEEK_SET);
+ savedolen = 0L;
+ }
+ if (outputlen & 1)
+ {
+ (void) WriteBlobByte(ofile,0x00);
+ outputlen++;
+ }
+ (void) WriteBlobString(ofile,"8BIM");
+ (void) WriteBlobMSBShort(ofile,recnum);
+ outputlen += 6;
+ if (name)
+ nlen = (unsigned char) strlen(name);
+ (void) WriteBlobByte(ofile,nlen);
+ outputlen++;
+ for (i=0; i<nlen; i++)
+ (void) WriteBlobByte(ofile,name[i]);
+ outputlen += nlen;
+ if (!(nlen&1))
+ {
+ (void) WriteBlobByte(ofile,0x00);
+ outputlen++;
+ }
+ if (recnum != IPTC_ID)
+ {
+ (void) WriteBlobMSBLong(ofile, (const magick_uint32_t) len);
+ outputlen += 4;
+
+ next=0;
+ outputlen += len;
+ while (len--)
+ (void) WriteBlobByte(ofile,token[next++]);
+
+ if (outputlen & 1)
+ {
+ (void) WriteBlobByte(ofile,0x00);
+ outputlen++;
+ }
+ }
+ else
+ {
+ /* patch in a fake length for now and fix it later */
+ savedpos = TellBlob(ofile);
+ if (savedpos < 0)
+ goto parse8BIMW_failure;
+ (void) WriteBlobMSBLong(ofile,0xFFFFFFFFUL);
+ outputlen += 4;
+ savedolen = outputlen;
+ }
+ }
+ else
+ {
+ if (len <= 0x7FFF)
+ {
+ (void) WriteBlobByte(ofile,0x1c);
+ (void) WriteBlobByte(ofile,dataset);
+ (void) WriteBlobByte(ofile,recnum & 255);
+ (void) WriteBlobMSBShort(ofile,(const magick_uint16_t) len);
+ outputlen += 5;
+ next=0;
+ outputlen += (long) len;
+ while (len--)
+ (void) WriteBlobByte(ofile,token[next++]);
+ }
+ }
+ }
+ state++;
+ }
+ MagickFreeMemory(token);
+ MagickFreeMemory(newstr);
+ MagickFreeMemory(name);
+ }
+ MagickFreeMemory(line);
+ if (savedolen > 0)
+ {
+ long diff = outputlen - savedolen;
+
+ currentpos = TellBlob(ofile);
+ if (currentpos < 0)
+ goto parse8BIMW_failure;
+ (void) SeekBlob(ofile,savedpos,SEEK_SET);
+ (void) WriteBlobMSBLong(ofile,diff);
+ (void) SeekBlob(ofile,currentpos,SEEK_SET);
+ savedolen = 0L;
+ }
+ return outputlen;
+
+ parse8BIMW_failure:
+ MagickFreeMemory(token);
+ MagickFreeMemory(newstr);
+ MagickFreeMemory(name);
+ MagickFreeMemory(line);
+ return 0L;
+}
+
+/* some defines for the different JPEG block types */
+#define M_SOF0 0xC0 /* Start Of Frame N */
+#define M_SOF1 0xC1 /* N indicates which compression process */
+#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */
+#define M_SOF3 0xC3
+#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */
+#define M_SOF6 0xC6
+#define M_SOF7 0xC7
+#define M_SOF9 0xC9
+#define M_SOF10 0xCA
+#define M_SOF11 0xCB
+#define M_SOF13 0xCD
+#define M_SOF14 0xCE
+#define M_SOF15 0xCF
+#define M_SOI 0xD8
+#define M_EOI 0xD9 /* End Of Image (end of datastream) */
+#define M_SOS 0xDA /* Start Of Scan (begins compressed data) */
+#define M_APP0 0xe0
+#define M_APP1 0xe1
+#define M_APP2 0xe2
+#define M_APP3 0xe3
+#define M_APP4 0xe4
+#define M_APP5 0xe5
+#define M_APP6 0xe6
+#define M_APP7 0xe7
+#define M_APP8 0xe8
+#define M_APP9 0xe9
+#define M_APP10 0xea
+#define M_APP11 0xeb
+#define M_APP12 0xec
+#define M_APP13 0xed
+#define M_APP14 0xee
+#define M_APP15 0xef
+
+static int jpeg_transfer_1(Image *ifile, Image *ofile)
+{
+ int c;
+
+ c = ReadBlobByte(ifile);
+ if (c == EOF)
+ return EOF;
+ (void) WriteBlobByte(ofile,c);
+ return c;
+}
+
+#if 0
+static int jpeg_skip_1(Image *ifile)
+{
+ int c;
+
+ c = ReadBlobByte(ifile);
+ if (c == EOF)
+ return EOF;
+ return c;
+}
+#endif
+
+static int jpeg_read_remaining(Image *ifile, Image *ofile)
+{
+ while ((jpeg_transfer_1(ifile, ofile)) != EOF)
+ continue;
+ return M_EOI;
+}
+
+static int jpeg_skip_variable(Image *ifile, Image *ofile)
+{
+ unsigned int length;
+ int c1,c2;
+
+ if ((c1 = jpeg_transfer_1(ifile, ofile)) == EOF)
+ return M_EOI;
+ if ((c2 = jpeg_transfer_1(ifile, ofile)) == EOF)
+ return M_EOI;
+
+ length = (((unsigned char) c1) << 8) + ((unsigned char) c2);
+ length -= 2;
+
+ while (length--)
+ if (jpeg_transfer_1(ifile, ofile) == EOF)
+ return M_EOI;
+
+ return 0;
+}
+
+static int jpeg_skip_variable2(Image *ifile, Image *ofile)
+{
+ unsigned int length;
+ int c1,c2;
+
+ ARG_NOT_USED(ofile);
+ if ((c1 = ReadBlobByte(ifile)) == EOF) return M_EOI;
+ if ((c2 = ReadBlobByte(ifile)) == EOF) return M_EOI;
+
+ length = (((unsigned char) c1) << 8) + ((unsigned char) c2);
+ length -= 2;
+
+ while (length--)
+ if (ReadBlobByte(ifile) == EOF)
+ return M_EOI;
+
+ return 0;
+}
+
+static int jpeg_nextmarker(Image *ifile, Image *ofile)
+{
+ int c;
+
+ /* transfer anything until we hit 0xff */
+ do
+ {
+ c = ReadBlobByte(ifile);
+ if (c == EOF)
+ return M_EOI; /* we hit EOF */
+ else
+ if (c != 0xff)
+ (void) WriteBlobByte(ofile,c);
+ } while (c != 0xff);
+
+ /* get marker byte, swallowing possible padding */
+ do
+ {
+ c = ReadBlobByte(ifile);
+ if (c == EOF)
+ return M_EOI; /* we hit EOF */
+ } while (c == 0xff);
+
+ return c;
+}
+
+#if 0
+static int jpeg_skip_till_marker(Image *ifile, int marker)
+{
+ int c, i;
+
+ do
+ {
+ /* skip anything until we hit 0xff */
+ i = 0;
+ do
+ {
+ c = ReadBlobByte(ifile);
+ i++;
+ if (c == EOF)
+ return M_EOI; /* we hit EOF */
+ } while (c != 0xff);
+
+ /* get marker byte, swallowing possible padding */
+ do
+ {
+ c = ReadBlobByte(ifile);
+ if (c == EOF)
+ return M_EOI; /* we hit EOF */
+ } while (c == 0xff);
+ } while (c != marker);
+ return c;
+}
+#endif
+
+/* Embed binary IPTC data into a JPEG image. */
+static int jpeg_embed(Image *ifile, Image *ofile, Image *iptc)
+{
+ unsigned int marker;
+ unsigned int done = 0;
+ unsigned int len;
+ int inx;
+
+ if (jpeg_transfer_1(ifile, ofile) != 0xFF)
+ return 0;
+ if (jpeg_transfer_1(ifile, ofile) != M_SOI)
+ return 0;
+
+ while (!done)
+ {
+ marker = jpeg_nextmarker(ifile, ofile);
+ if (marker == M_EOI)
+ { /* EOF */
+ break;
+ }
+ else
+ {
+ if (marker != M_APP13)
+ {
+ (void) WriteBlobByte(ofile,0xff);
+ (void) WriteBlobByte(ofile,marker);
+ }
+ }
+
+ switch (marker)
+ {
+ case M_APP13:
+ /* we are going to write a new APP13 marker, so don't output the old one */
+ (void) jpeg_skip_variable2(ifile, ofile);
+ break;
+
+ case M_APP0:
+ /* APP0 is in each and every JPEG, so when we hit APP0 we insert our new APP13! */
+ (void) jpeg_skip_variable(ifile, ofile);
+
+ if (iptc != (Image *)NULL)
+ {
+ static const char psheader_base[] = "\xFF\xED\0\0Photoshop 3.0\08BIM\x04\x04\0\0\0\0";
+ char psheader[sizeof(psheader_base)];
+ len=GetBlobSize(iptc);
+ if (len & 1)
+ len++; /* make the length even */
+ (void) strlcpy(psheader,psheader_base,sizeof(psheader));
+ psheader[ 2 ] = (len+16)>>8;
+ psheader[ 3 ] = (len+16)&0xff;
+ for (inx = 0; inx < 18; inx++)
+ (void) WriteBlobByte(ofile,psheader[inx]);
+ (void) jpeg_read_remaining(iptc, ofile);
+ len=GetBlobSize(iptc);
+ if (len & 1)
+ (void) WriteBlobByte(ofile,0);
+ }
+ break;
+
+ case M_SOS:
+ /* we hit data, no more marker-inserting can be done! */
+ (void) jpeg_read_remaining(ifile, ofile);
+ done = 1;
+ break;
+
+ default:
+ (void) jpeg_skip_variable(ifile, ofile);
+ break;
+ }
+ }
+ return 1;
+}
+
+#if 0
+/* handle stripping the APP13 data out of a JPEG */
+static void jpeg_strip(Image *ifile, Image *ofile)
+{
+ unsigned int marker;
+
+ marker = jpeg_skip_till_marker(ifile, M_SOI);
+ if (marker == M_SOI)
+ {
+ WriteBlobByte(ofile,0xff);
+ WriteBlobByte(ofile,M_SOI);
+ jpeg_read_remaining(ifile, ofile);
+ }
+}
+
+/* Extract any APP13 binary data into a file. */
+static int jpeg_extract(Image *ifile, Image *ofile)
+{
+ unsigned int marker;
+ unsigned int done = 0;
+
+ if (jpeg_skip_1(ifile) != 0xff)
+ return 0;
+ if (jpeg_skip_1(ifile) != M_SOI)
+ return 0;
+
+ while (!done)
+ {
+ marker = jpeg_skip_till_marker(ifile, M_APP13);
+ if (marker == M_APP13)
+ {
+ marker = jpeg_nextmarker(ifile, ofile);
+ break;
+ }
+ }
+ return 1;
+}
+#endif /* NOTUSED */
+
+static Image *ReadMETAImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *buff,
+ *image;
+
+ int
+ c;
+
+ size_t
+ length;
+
+ unsigned int
+ status;
+
+ unsigned char
+ *blob;
+
+ /*
+ Open file containing binary metadata
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ image->columns=1;
+ image->rows=1;
+ (void) SetImage(image,OpaqueOpacity);
+ length=1;
+ if (LocaleNCompare(image_info->magick,"8BIM",4) == 0)
+ {
+ /*
+ Read 8BIM binary metadata.
+ */
+ buff=AllocateImage((ImageInfo *) NULL);
+ if (buff == (Image *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ blob=MagickAllocateMemory(unsigned char *,length);
+ if (blob == (unsigned char *) NULL)
+ {
+ DestroyImage(buff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image)
+ }
+ AttachBlob(buff->blob,blob,length);
+ if (LocaleCompare(image_info->magick,"8BIMTEXT") == 0)
+ {
+ length=parse8BIM(image, buff);
+ if (length & 1)
+ (void) WriteBlobByte(buff,0x0);
+ }
+ else if (LocaleCompare(image_info->magick,"8BIMWTEXT") == 0)
+ {
+ length=parse8BIMW(image, buff);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "META CODER Parse8BIMW returned: %lu",
+ (unsigned long) length);
+ if (length & 1)
+ (void) WriteBlobByte(buff,0x0);
+ }
+ else
+ {
+ for ( ; ; )
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ break;
+ (void) WriteBlobByte(buff,c);
+ }
+ }
+ blob=GetBlobStreamData(buff);
+ length=GetBlobSize(buff);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Store IPTC profile, size %lu bytes",
+ (unsigned long) length);
+ (void) SetImageProfile(image,"IPTC",blob,length);
+ DetachBlob(buff->blob);
+ MagickFreeMemory(blob);
+ DestroyImage(buff);
+ }
+ if (LocaleNCompare(image_info->magick,"APP1",4) == 0)
+ {
+ /*
+ Read APP1 binary metadata.
+ */
+ buff=AllocateImage((ImageInfo *) NULL);
+ if (buff == (Image *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ blob=MagickAllocateMemory(unsigned char *,length);
+ if (blob == (unsigned char *) NULL)
+ {
+ DestroyImage(buff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image)
+ }
+ AttachBlob(buff->blob,blob,length);
+ if (LocaleCompare(image_info->magick,"APP1JPEG") == 0)
+ {
+ Image
+ *iptc;
+
+ int
+ result;
+
+ ProfileInfo
+ *pinfo;
+
+ pinfo = (ProfileInfo *) image_info->client_data;
+ if ((pinfo == (ProfileInfo *) NULL) ||
+ (pinfo->info == (unsigned char *) NULL) || (pinfo->length == 0))
+ {
+ DetachBlob(buff->blob);
+ MagickFreeMemory(blob);
+ DestroyImage(buff);
+ ThrowReaderException(CoderError,NoIPTCProfileAvailable,image)
+ }
+ iptc=AllocateImage((ImageInfo *) NULL);
+ if (iptc == (Image *) NULL)
+ {
+ DetachBlob(buff->blob);
+ MagickFreeMemory(blob);
+ DestroyImage(buff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image)
+ }
+ AttachBlob(iptc->blob,pinfo->info,pinfo->length);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "META CODER APP1JPEG embed: %p (%ld)",
+ pinfo->info, /* unsigned char * */
+ (long) pinfo->length); /* size_t */
+ result=jpeg_embed(image,buff,iptc);
+ DetachBlob(iptc->blob);
+ DestroyImage(iptc);
+ if (result == 0)
+ {
+ DetachBlob(buff->blob);
+ MagickFreeMemory(blob);
+ DestroyImage(buff);
+ ThrowReaderException(CoderError,JPEGEmbeddingFailed,image)
+ }
+ }
+ else
+ {
+#ifdef SLOW_METHOD
+ for ( ; ; )
+ {
+ /* Really - really slow - FIX ME PLEASE!!!! */
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ break;
+ WriteBlobByte(buff,c);
+ }
+#else
+#define MaxBufferSize 65541
+ char
+ *buffer;
+
+ ExtendedSignedIntegralType
+ count;
+
+ size_t
+ i,
+ length;
+
+ buffer=MagickAllocateMemory(char *,MaxBufferSize);
+ if (buffer != (char *) NULL)
+ {
+ i=0;
+ while ((length=ReadBlob(image,MaxBufferSize,buffer)) != 0)
+ {
+ count=0;
+ for (i=0; i < length; i+=count)
+ {
+ count=WriteBlob(buff,length-i,buffer+i);
+ if (count <= 0)
+ break;
+ }
+ if (i < length)
+ break;
+ }
+ MagickFreeMemory(buffer);
+ }
+#endif
+ }
+ blob=GetBlobStreamData(buff);
+ length=GetBlobSize(buff);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Store APP1 profile, size %lu bytes",
+ (unsigned long) length);
+ (void) SetImageProfile(image,"APP1",blob,length);
+ DetachBlob(buff->blob);
+ MagickFreeMemory(blob);
+ DestroyImage(buff);
+ }
+ if ((LocaleCompare(image_info->magick,"ICC") == 0) ||
+ (LocaleCompare(image_info->magick,"ICM") == 0))
+ {
+ buff=AllocateImage((ImageInfo *) NULL);
+ if (buff == (Image *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ blob=MagickAllocateMemory(unsigned char *,length);
+ if (blob == (unsigned char *) NULL)
+ {
+ DestroyImage(buff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image)
+ }
+ AttachBlob(buff->blob,blob,length);
+ for ( ; ; )
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ break;
+ (void) WriteBlobByte(buff,c);
+ }
+ blob=GetBlobStreamData(buff);
+ length=GetBlobSize(buff);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Store ICM profile, size %lu bytes",
+ (unsigned long) length);
+ (void) SetImageProfile(image,"ICM",blob,length);
+ DetachBlob(buff->blob);
+ MagickFreeMemory(blob);
+
+ DestroyImage(buff);
+ }
+ if (LocaleNCompare(image_info->magick,"IPTC",4) == 0)
+ {
+ buff=AllocateImage((ImageInfo *) NULL);
+ if (buff == (Image *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ blob=MagickAllocateMemory(unsigned char *,length);
+ if (blob == (unsigned char *) NULL)
+ {
+ DestroyImage(buff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ AttachBlob(buff->blob,blob,length);
+ /* write out the header - length field patched below */
+ (void) WriteBlob(buff,12,"8BIM\04\04\0\0\0\0\0\0");
+ if (LocaleCompare(image_info->magick,"IPTCTEXT") == 0)
+ {
+ length=parse8BIM(image, buff);
+ if (length & 1)
+ (void) WriteBlobByte(buff,0x0);
+ }
+ else if (LocaleCompare(image_info->magick,"IPTCWTEXT") == 0)
+ {
+ }
+ else
+ {
+ for ( ; ; )
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ break;
+ (void) WriteBlobByte(buff,c);
+ }
+ }
+
+ /* subtract off the length of the 8BIM stuff */
+ blob=GetBlobStreamData(buff); /* blob may be realloced */
+ if ((blob == (const unsigned char *) NULL) || (GetBlobSize(buff) < 12))
+ {
+ DestroyImage(buff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ length=GetBlobSize(buff)-12;
+ blob[10]=(unsigned char) ((length >> 8) & 0xff);
+ blob[11]=(unsigned char) (length & 0xff);
+ blob=GetBlobStreamData(buff);
+ length=GetBlobSize(buff);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Store IPTC profile, size %" MAGICK_SIZE_T_F
+ "u bytes",(MAGICK_SIZE_T) length);
+ (void) SetImageProfile(image,"IPTC",blob,length);
+ DetachBlob(buff->blob);
+ MagickFreeMemory(blob)
+ DestroyImage(buff);
+ }
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M E T A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMETAImage adds attributes for the META image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMETAImage method is:
+%
+% RegisterMETAImage(void)
+%
+*/
+ModuleExport void RegisterMETAImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("8BIM");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Photoshop resource format";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("8BIMTEXT");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Photoshop resource text format";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("8BIMWTEXT");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Photoshop resource wide text format";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("APP1");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Raw application information";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("APP1JPEG");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Raw JPEG binary data";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("EXIF");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Exif digital camera binary data";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("XMP");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Adobe XML metadata";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("ICM");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="ICC Color Profile";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("ICC");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="ICC Color Profile";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("IPTC");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="IPTC Newsphoto";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("IPTCTEXT");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="IPTC Newsphoto text format";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("IPTCWTEXT");
+ entry->decoder=(DecoderHandler) ReadMETAImage;
+ entry->encoder=(EncoderHandler) WriteMETAImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="IPTC Newsphoto text format";
+ entry->module="META";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M E T A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMETAImage removes format registrations made by the
+% META module from the list of supported formats.
+%
+% The format of the UnregisterMETAImage method is:
+%
+% UnregisterMETAImage(void)
+%
+*/
+ModuleExport void UnregisterMETAImage(void)
+{
+ (void) UnregisterMagickInfo("8BIM");
+ (void) UnregisterMagickInfo("8BIMTEXT");
+ (void) UnregisterMagickInfo("8BIMWTEXT");
+ (void) UnregisterMagickInfo("APP1");
+ (void) UnregisterMagickInfo("APP1JPEG");
+ (void) UnregisterMagickInfo("EXIF");
+ (void) UnregisterMagickInfo("ICC");
+ (void) UnregisterMagickInfo("ICC");
+ (void) UnregisterMagickInfo("ICCTEXT");
+ (void) UnregisterMagickInfo("ICM");
+ (void) UnregisterMagickInfo("IPTC");
+ (void) UnregisterMagickInfo("IPTCTEXT");
+ (void) UnregisterMagickInfo("IPTCWTEXT");
+ (void) UnregisterMagickInfo("PICON");
+ (void) UnregisterMagickInfo("XMP");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M E T A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMETAImage writes a META image to a file.
+%
+% The format of the WriteMETAImage method is:
+%
+% unsigned int WriteMETAImage(const ImageInfo *image_info,Image *image)
+%
+% Compression code contributed by Kyle Shorter.
+%
+% A description of each parameter follows:
+%
+% o status: Method WriteMETAImage return True if the image is written.
+% False is returned if there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to an ImageInfo structure.
+%
+% o image: A pointer to a Image structure.
+%
+%
+*/
+
+static size_t GetIPTCStream(const unsigned char *blob, size_t blob_length, size_t *offset)
+{
+ size_t
+ info_length;
+
+ register long
+ i;
+
+ register const unsigned char
+ *p;
+
+ unsigned char
+ c;
+
+ unsigned int
+ marker;
+
+ size_t
+ tag_length,
+ blob_remaining;
+
+ p=blob;
+ blob_remaining=blob_length;
+ if ((*p == 0x1c) && (*(p+1) == 0x02))
+ {
+ /* This looks like a plain IPTC record 2 block so drop through */
+ *offset=0;
+ return blob_length;
+ }
+
+ /* Scan in case we are in an 8BIM block */
+ while (blob_remaining >= 12)
+ {
+ /* Check for 8BIM string ID */
+ if (strncmp((const char*)p,"8BIM",4)) break;
+ p+=4;
+ blob_remaining -= 4;
+
+ /* Read marker ID */
+ marker=(unsigned int)(*p) << 8 | *(p+1);
+ p+=2;
+ blob_remaining-=2;
+
+ /* Read length of Pascal style description string */
+ c=*p++;
+ blob_remaining--;
+ /* ...allow for possible padding byte */
+ c |= 1;
+ /* ...and skip the string data */
+ if (c >= blob_remaining) break;
+ p+=c;
+ blob_remaining-=c;
+
+ /* Read data length */
+ if (blob_remaining < 4) break;
+ tag_length=(((unsigned long)*p) << 24) | (((unsigned long)*(p+1)) << 16) |
+ (((unsigned long)*(p+2)) << 8) | ((unsigned long)*(p+3));
+ p+=4;
+ blob_remaining-=4;
+ if (tag_length > blob_remaining) break;
+ /* Check whether we have the IPTC tag data */
+ if (marker == IPTC_ID)
+ {
+ /* All looks good so return IPTC block "as is" */
+ *offset=(unsigned long)(p-blob);
+ return tag_length;
+ }
+
+ /* Allow for padding of data to even size */
+ if (tag_length & 1) tag_length++;
+
+ /* Skip unwanted data */
+ p+=tag_length;
+ blob_remaining-=tag_length;
+ }
+
+ /* Find the beginning of the IPTC info */
+ p=blob;
+ tag_length=0;
+iptc_find:
+ info_length=0;
+ marker=False;
+ while (blob_length != 0)
+ {
+ c=(*p++);
+ blob_length--;
+ if (blob_length == 0)
+ break;
+ if (c == 0x1c)
+ {
+ p--;
+ *offset=(unsigned long) (p-blob); /* let the caller know were it is */
+ break;
+ }
+ }
+ /*
+ Determine the length of the IPTC info.
+ */
+ while (blob_length != 0)
+ {
+ c=(*p++);
+ blob_length--;
+ if (blob_length == 0)
+ break;
+ if (c == 0x1c)
+ marker=True;
+ else
+ if (marker)
+ break;
+ else
+ continue;
+ info_length++;
+ /*
+ Found the 0x1c tag; skip the dataset and record number tags.
+ */
+ c=(*p++); /* should be 2 */
+ blob_length--;
+ if (blob_length == 0)
+ break;
+ if ((info_length == 1) && (c != 2))
+ goto iptc_find;
+ info_length++;
+ c=(*p++); /* should be 0 */
+ blob_length--;
+ if (blob_length == 0)
+ break;
+ if ((info_length == 2) && (c != 0))
+ goto iptc_find;
+ info_length++;
+ /*
+ Decode the length of the block that follows - long or short format.
+ */
+ c=(*p++);
+ blob_length--;
+ if (blob_length == 0)
+ break;
+ info_length++;
+ if (c & (unsigned char) 0x80)
+ {
+ /* long format */
+ tag_length=0;
+ for (i=0; i < 4; i++)
+ {
+ tag_length <<= 8;
+ tag_length |= (*p++);
+ blob_length--;
+ if (blob_length == 0)
+ break;
+ info_length++;
+ }
+ }
+ else
+ {
+ /* short format */
+ tag_length=((long) c) << 8;
+ c=(*p++);
+ blob_length--;
+ if (blob_length == 0)
+ break;
+ info_length++;
+ tag_length|=(long) c;
+ }
+ if (tag_length > blob_length)
+ break;
+ p+=tag_length;
+ blob_length-=tag_length;
+ if (blob_length == 0)
+ break;
+ info_length+=tag_length;
+ }
+ return(info_length);
+}
+
+static void formatString(Image *ofile, const char *s, int len)
+{
+ char
+ temp[MaxTextExtent];
+
+ (void) WriteBlobByte(ofile,'"');
+ for (; len > 0; --len, ++s) {
+ int c = (*s) & 255;
+ switch (c) {
+ case '&':
+ (void) WriteBlobString(ofile,"&amp;");
+ break;
+#ifdef HANDLE_GT_LT
+ case '<':
+ WriteBlobString(ofile,"&lt;");
+ break;
+ case '>':
+ WriteBlobString(ofile,"&gt;");
+ break;
+#endif
+ case '"':
+ (void) WriteBlobString(ofile,"&quot;");
+ break;
+ default:
+ if (isprint(c))
+ (void) WriteBlobByte(ofile,*s);
+ else
+ {
+ FormatString(temp, "&#%d;", c & 255);
+ (void) WriteBlobString(ofile,temp);
+ }
+ break;
+ }
+ }
+#if defined(MSWINDOWS)
+ (void) WriteBlobString(ofile,"\"\r\n");
+#else
+ (void) WriteBlobString(ofile,"\"\n");
+#endif
+}
+
+typedef struct _tag_spec
+{
+ short
+ id;
+
+ const char
+ *name;
+} tag_spec;
+
+static const tag_spec tags[] = {
+ { 5, "Image Name" },
+ { 7, "Edit Status" },
+ { 10, "Priority" },
+ { 15, "Category" },
+ { 20, "Supplemental Category" },
+ { 22, "Fixture Identifier" },
+ { 25, "Keyword" },
+ { 30, "Release Date" },
+ { 35, "Release Time" },
+ { 40, "Special Instructions" },
+ { 45, "Reference Service" },
+ { 47, "Reference Date" },
+ { 50, "Reference Number" },
+ { 55, "Created Date" },
+ { 60, "Created Time" },
+ { 65, "Originating Program" },
+ { 70, "Program Version" },
+ { 75, "Object Cycle" },
+ { 80, "Byline" },
+ { 85, "Byline Title" },
+ { 90, "City" },
+ { 95, "Province State" },
+ { 100, "Country Code" },
+ { 101, "Country" },
+ { 103, "Original Transmission Reference" },
+ { 105, "Headline" },
+ { 110, "Credit" },
+ { 115, "Source" },
+ { 116, "Copyright String" },
+ { 120, "Caption" },
+ { 121, "Image Orientation" },
+ { 122, "Caption Writer" },
+ { 131, "Local Caption" },
+ { 200, "Custom Field 1" },
+ { 201, "Custom Field 2" },
+ { 202, "Custom Field 3" },
+ { 203, "Custom Field 4" },
+ { 204, "Custom Field 5" },
+ { 205, "Custom Field 6" },
+ { 206, "Custom Field 7" },
+ { 207, "Custom Field 8" },
+ { 208, "Custom Field 9" },
+ { 209, "Custom Field 10" },
+ { 210, "Custom Field 11" },
+ { 211, "Custom Field 12" },
+ { 212, "Custom Field 13" },
+ { 213, "Custom Field 14" },
+ { 214, "Custom Field 15" },
+ { 215, "Custom Field 16" },
+ { 216, "Custom Field 17" },
+ { 217, "Custom Field 18" },
+ { 218, "Custom Field 19" },
+ { 219, "Custom Field 20" }
+};
+
+static int formatIPTC(Image *ifile, Image *ofile)
+{
+ char
+ temp[MaxTextExtent];
+
+ unsigned int
+ foundiptc,
+ tagsfound;
+
+ unsigned char
+ recnum,
+ dataset;
+
+ unsigned char
+ *readable,
+ *str;
+
+ long
+ tagindx,
+ taglen;
+
+ int
+ i,
+ tagcount = sizeof(tags) / sizeof(tag_spec);
+
+ int
+ c;
+
+ foundiptc = 0; /* found the IPTC-Header */
+ tagsfound = 0; /* number of tags found */
+
+ c = ReadBlobByte(ifile);
+ while (c != EOF)
+ {
+ if (c == 0x1c)
+ foundiptc = 1;
+ else
+ {
+ if (foundiptc)
+ {
+ return -1;
+ }
+ else
+ {
+ c = ReadBlobByte(ifile);
+ continue;
+ }
+ }
+
+ /* we found the 0x1c tag and now grab the dataset and record number tags */
+ c = ReadBlobByte(ifile);
+ if (c == EOF) return -1;
+ dataset = (unsigned char) c;
+ c = ReadBlobByte(ifile);
+ if (c == EOF) return -1;
+ recnum = (unsigned char) c;
+ /* try to match this record to one of the ones in our named table */
+ for (i=0; i< tagcount; i++)
+ {
+ if (tags[i].id == recnum)
+ break;
+ }
+ if (i < tagcount)
+ readable = (unsigned char *) tags[i].name;
+ else
+ readable = (unsigned char *) "";
+
+ /* then we decode the length of the block that follows - long or short fmt */
+ c=ReadBlobByte(ifile);
+ if (c == EOF) return -1;
+ if (c & (unsigned char) 0x80)
+ return 0;
+ else
+ {
+ int
+ c0;
+
+ c0=ReadBlobByte(ifile);
+ if (c0 == EOF) return -1;
+ taglen = (c << 8) | c0;
+ }
+ if (taglen < 0) return -1;
+ /* make a buffer to hold the tag data and snag it from the input stream */
+ str=MagickAllocateMemory(unsigned char *,(unsigned int) (taglen+1));
+ if (str == (unsigned char *) NULL)
+ {
+ (void) printf("MemoryAllocationFailed");
+ return 0;
+ }
+ for (tagindx=0; tagindx<taglen; tagindx++)
+ {
+ c=ReadBlobByte(ifile);
+ if (c == EOF)
+ {
+ MagickFreeMemory(str);
+ return -1;
+ }
+ str[tagindx] = (unsigned char) c;
+ }
+ str[taglen] = 0;
+
+ /* now finish up by formatting this binary data into ASCII equivalent */
+ if (strlen((char *)readable) != 0)
+ FormatString(temp, "%d#%d#%s=",(unsigned int)dataset, (unsigned int) recnum, readable);
+ else
+ FormatString(temp, "%d#%d=",(unsigned int)dataset, (unsigned int) recnum);
+ (void) WriteBlobString(ofile,temp);
+ formatString( ofile, (char *)str, taglen );
+ MagickFreeMemory(str);
+
+ tagsfound++;
+
+ c=ReadBlobByte(ifile);
+ }
+ return tagsfound;
+}
+
+static int readWordFromBuffer(char **s, long *len)
+{
+ unsigned char
+ buffer[2];
+
+ int
+ i,
+ c;
+
+ for (i=0; i<2; i++)
+ {
+ c = *(*s)++; (*len)--;
+ if (*len < 0) return -1;
+ buffer[i] = (unsigned char) c;
+ }
+ return (((int) buffer[ 0 ]) << 8) |
+ (((int) buffer[ 1 ]));
+}
+
+static int formatIPTCfromBuffer(Image *ofile, char *s, long len)
+{
+ char
+ temp[MaxTextExtent];
+
+ unsigned int
+ foundiptc,
+ tagsfound;
+
+ unsigned char
+ recnum,
+ dataset;
+
+ unsigned char
+ *readable,
+ *str;
+
+ long
+ tagindx,
+ taglen;
+
+ int
+ i,
+ tagcount = sizeof(tags) / sizeof(tag_spec);
+
+ int
+ c;
+
+ foundiptc = 0; /* found the IPTC-Header */
+ tagsfound = 0; /* number of tags found */
+
+ while (len > 0)
+ {
+ c = *s++; len--;
+ if (c == 0x1c)
+ foundiptc = 1;
+ else
+ {
+ if (foundiptc)
+ return -1;
+ else
+ continue;
+ }
+
+ /* we found the 0x1c tag and now grab the dataset and record number tags */
+ c = *s++; len--;
+ if (len < 0) return -1;
+ dataset = (unsigned char) c;
+ c = *s++; len--;
+ if (len < 0) return -1;
+ recnum = (unsigned char) c;
+ /* try to match this record to one of the ones in our named table */
+ for (i=0; i< tagcount; i++)
+ {
+ if (tags[i].id == recnum)
+ break;
+ }
+ if (i < tagcount)
+ readable = (unsigned char *) tags[i].name;
+ else
+ readable = (unsigned char *) "";
+
+ /* then we decode the length of the block that follows - long or short fmt */
+ c = *s++; len--;
+ if (len < 0) return -1;
+ if (c & (unsigned char) 0x80)
+ return 0;
+ else
+ {
+ s--; len++;
+ taglen = readWordFromBuffer(&s, &len);
+ }
+ if (taglen < 0) return -1;
+ /* make a buffer to hold the tag data and snag it from the input stream */
+ str=MagickAllocateMemory(unsigned char *,(unsigned int) (taglen+1));
+ if (str == (unsigned char *) NULL)
+ {
+ (void) printf("MemoryAllocationFailed");
+ return 0;
+ }
+ for (tagindx=0; tagindx<taglen; tagindx++)
+ {
+ c = *s++; len--;
+ if (len < 0)
+ {
+ MagickFreeMemory(str);
+ return -1;
+ }
+ str[tagindx] = (unsigned char) c;
+ }
+ str[ taglen ] = 0;
+
+ /* now finish up by formatting this binary data into ASCII equivalent */
+ if (strlen((char *)readable) != 0)
+ FormatString(temp, "%d#%d#%s=",(unsigned int)dataset, (unsigned int) recnum, readable);
+ else
+ FormatString(temp, "%d#%d=",(unsigned int)dataset, (unsigned int) recnum);
+ (void) WriteBlobString(ofile,temp);
+ formatString( ofile, (char *)str, taglen );
+ MagickFreeMemory(str);
+
+ tagsfound++;
+ }
+ return tagsfound;
+}
+
+#define Format8BIMLiberate() \
+ do \
+ { \
+ MagickFreeMemory(PString); \
+ MagickFreeMemory(str); \
+ } while(0);
+
+static int format8BIM(Image *ifile, Image *ofile)
+{
+ char
+ temp[MaxTextExtent];
+
+ ExtendedSignedIntegralType
+ Size;
+
+ int
+ ID,
+ resCount,
+ i,
+ c;
+
+ unsigned char
+ *PString=0,
+ *str=0;
+
+ resCount = 0;
+
+ c =ReadBlobByte(ifile);
+ while (c != EOF)
+ {
+ if (c == '8')
+ {
+ unsigned char
+ buffer[5];
+
+ buffer[0] = (unsigned char) c;
+ for (i=1; i<4; i++)
+ {
+ c=ReadBlobByte(ifile);
+ if (c == EOF)
+ {
+ Format8BIMLiberate();
+ return -1;
+ }
+ buffer[i] = (unsigned char) c;
+ }
+ buffer[4] = 0;
+ if (strcmp((const char *)buffer, "8BIM") != 0)
+ continue;
+ }
+ else
+ {
+ c=ReadBlobByte(ifile);
+ continue;
+ }
+
+ /* we found the OSType (8BIM) and now grab the ID, PString, and Size fields */
+ ID = ReadBlobMSBShort(ifile);
+ if (ID < 0)
+ {
+ Format8BIMLiberate();
+ return -1;
+ }
+ {
+ unsigned char
+ plen;
+
+ c=ReadBlobByte(ifile);
+ if (c == EOF)
+ {
+ Format8BIMLiberate();
+ return -1;
+ }
+ plen = (unsigned char) c;
+ PString=MagickAllocateMemory(unsigned char *,(unsigned int) (plen+1));
+ if (PString == (unsigned char *) NULL)
+ {
+ (void) printf("MemoryAllocationFailed");
+ Format8BIMLiberate();
+ return 0;
+ }
+ for (i=0; i<plen; i++)
+ {
+ c=ReadBlobByte(ifile);
+ if (c == EOF)
+ {
+ Format8BIMLiberate();
+ return -1;
+ }
+ PString[i] = (unsigned char) c;
+ }
+ PString[ plen ] = 0;
+ if (!(plen&1))
+ {
+ c=ReadBlobByte(ifile);
+ if (c == EOF)
+ {
+ Format8BIMLiberate();
+ return -1;
+ }
+ }
+ }
+ Size = ReadBlobMSBLong(ifile);
+ if (Size < 0)
+ {
+ Format8BIMLiberate();
+ return -1;
+ }
+ /* make a buffer to hold the data and snag it from the input stream */
+ str=MagickAllocateMemory(unsigned char *,(size_t) Size);
+ if (str == (unsigned char *) NULL)
+ {
+ (void) printf("MemoryAllocationFailed");
+ Format8BIMLiberate();
+ return 0;
+ }
+ for (i=0; i<Size; i++)
+ {
+ c=ReadBlobByte(ifile);
+ if (c == EOF)
+ {
+ Format8BIMLiberate();
+ return -1;
+ }
+ str[i] = (unsigned char) c;
+ }
+
+ /* we currently skip thumbnails, since it does not make
+ * any sense preserving them in a real world application
+ */
+ if (ID != THUMBNAIL_ID)
+ {
+ /* now finish up by formatting this binary data into
+ * ASCII equivalent
+ */
+ if (strlen((const char *) PString) != 0)
+ FormatString(temp, "8BIM#%d#%s=", ID, PString);
+ else
+ FormatString(temp, "8BIM#%d=", ID);
+ (void) WriteBlobString(ofile,temp);
+ if (ID == IPTC_ID)
+ {
+ formatString(ofile, "IPTC", 4);
+ (void) formatIPTCfromBuffer(ofile, (char *)str, (long) Size);
+ }
+ else
+ formatString(ofile, (char *)str, (long) Size);
+ }
+ Format8BIMLiberate();
+
+ resCount++;
+
+ c=ReadBlobByte(ifile);
+ }
+ return resCount;
+}
+
+static unsigned int WriteMETAImage(const ImageInfo *image_info,Image *image)
+{
+ const unsigned char
+ *profile;
+
+ size_t
+ profile_length;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (LocaleCompare(image_info->magick,"8BIM") == 0)
+ {
+ /*
+ Write 8BIM image.
+ */
+ if((profile=GetImageProfile(image,"8BIM",&profile_length)) == 0)
+ ThrowWriterException(CoderError,No8BIMDataIsAvailable,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) WriteBlob(image,profile_length,(void *) profile);
+ CloseBlob(image);
+ return(True);
+ }
+ if (LocaleCompare(image_info->magick,"IPTC") == 0)
+ {
+ size_t
+ iptc_offset,
+ length;
+
+ const unsigned char
+ *info;
+
+ if((profile=GetImageProfile(image,"IPTC",&profile_length)) == 0)
+ ThrowWriterException(CoderError,NoIPTCProfileAvailable,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ length=GetIPTCStream(profile,profile_length,&iptc_offset);
+ info=profile+iptc_offset;
+ if (length == 0)
+ {
+ ThrowWriterException(CoderError,NoIPTCInfoWasFound,image);
+ }
+ (void) WriteBlob(image,length,info);
+ CloseBlob(image);
+ return(True);
+ }
+ if (LocaleCompare(image_info->magick,"8BIMTEXT") == 0)
+ {
+ Image
+ *buff;
+
+ if((profile=GetImageProfile(image,"8BIM",&profile_length)) == 0)
+ ThrowWriterException(CoderError,No8BIMDataIsAvailable,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ buff=AllocateImage((ImageInfo *) NULL);
+ if (buff == (Image *) NULL)
+ {
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ AttachBlob(buff->blob,profile,profile_length);
+ (void) format8BIM(buff,image);
+ DetachBlob(buff->blob);
+ DestroyImage(buff);
+ CloseBlob(image);
+ return(True);
+ }
+ if (LocaleCompare(image_info->magick,"8BIMWTEXT") == 0)
+ {
+ return(False);
+ }
+ if (LocaleCompare(image_info->magick,"IPTCTEXT") == 0)
+ {
+ Image
+ *buff;
+
+ size_t
+ iptc_offset,
+ length;
+
+ const unsigned char
+ *info;
+
+ if((profile=GetImageProfile(image,"IPTC",&profile_length)) == 0)
+ ThrowWriterException(CoderError,NoIPTCProfileAvailable,image);
+ length=GetIPTCStream(profile,profile_length,&iptc_offset);
+ info=profile+iptc_offset;
+ if (length == 0)
+ ThrowWriterException(CoderError,NoIPTCInfoWasFound,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ buff=AllocateImage((ImageInfo *) NULL);
+ if (buff == (Image *) NULL)
+ {
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ AttachBlob(buff->blob,info,length);
+ (void) formatIPTC(buff,image);
+ DetachBlob(buff->blob);
+ DestroyImage(buff);
+ CloseBlob(image);
+ return(True);
+ }
+ if (LocaleCompare(image_info->magick,"IPTCWTEXT") == 0)
+ {
+ return(False);
+ }
+ if ((LocaleCompare(image_info->magick,"APP1") == 0) ||
+ (LocaleCompare(image_info->magick,"EXIF") == 0) ||
+ (LocaleCompare(image_info->magick,"XMP") == 0))
+ {
+ /*
+ Write APP1 image.
+ */
+ if((profile=GetImageProfile(image,image_info->magick,&profile_length)) == 0)
+ ThrowWriterException(CoderError,NoAPP1DataIsAvailable,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) WriteBlob(image,(int) profile_length, (char *) profile);
+ CloseBlob(image);
+ return(True);
+ }
+ if ((LocaleCompare(image_info->magick,"ICC") == 0) ||
+ (LocaleCompare(image_info->magick,"ICM") == 0))
+ {
+ /*
+ Write ICM image.
+ */
+
+ if((profile=GetImageProfile(image,"ICM",&profile_length)) == 0)
+ ThrowWriterException(CoderError,NoColorProfileAvailable,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) WriteBlob(image,profile_length,(void *) profile);
+ CloseBlob(image);
+ return(True);
+ }
+ return(False);
+}
diff --git a/coders/miff.c b/coders/miff.c
new file mode 100644
index 0000000..c578cbf
--- /dev/null
+++ b/coders/miff.c
@@ -0,0 +1,2748 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M IIIII FFFFF FFFFF %
+% MM MM I F F %
+% M M M I FFF FFF %
+% M M I F F %
+% M M IIIII F F %
+% %
+% %
+% Read/Write MIFF Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/compress.h"
+#include "magick/constitute.h"
+#include "magick/enum_strings.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/utility.h"
+#if defined(HasZLIB)
+# include "zlib.h"
+#endif
+#if defined(HasBZLIB)
+# include "bzlib.h"
+#endif
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMIFFImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M I F F %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsMIFF returns True if the image format type, identified by the
+% magick string, is MIFF.
+%
+% The format of the IsMIFF method is:
+%
+% unsigned int IsMIFF(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsMIFF returns True if the image format type is MIFF.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsMIFF(const unsigned char *magick,const size_t length)
+{
+ if (length < 14)
+ return(False);
+ if (LocaleNCompare((char *) magick,"id=ImageMagick",14) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMIFFImage reads a MIFF image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadMIFFImage method is:
+%
+% Image *ReadMIFFImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% Decompression code contributed by Kyle Shorter.
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMIFFImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+
+static unsigned int
+ImportRLEPixels(Image *image,
+ const QuantumType quantum_type,
+ const unsigned int quantum_size,
+ const unsigned char *source)
+{
+
+ register const unsigned char
+ *p;
+
+ register unsigned int
+ quantum;
+
+ register int
+ length;
+
+ register IndexPacket
+ index,
+ *indexes;
+
+ register long
+ x;
+
+ PixelPacket
+ pixel;
+
+ register PixelPacket
+ *q;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(source != (const unsigned char *) NULL);
+ assert((quantum_size == 8) || (quantum_size == 16) || (quantum_size == 32));
+ assert(((quantum_type == IndexQuantum) && (image->storage_class == PseudoClass)) ||
+ ((quantum_type == IndexAlphaQuantum) && (image->storage_class == PseudoClass)) ||
+ ((quantum_type == CMYKAQuantum) && (image->storage_class == DirectClass) && image->matte) ||
+ ((quantum_type == CMYKQuantum) && (image->storage_class == DirectClass) && !image->matte) ||
+ ((quantum_type == RGBAQuantum) && (image->storage_class == DirectClass) && image->matte) ||
+ ((quantum_type == RGBQuantum) && (image->storage_class == DirectClass) && !image->matte));
+
+ p=source;
+ q=AccessMutablePixels(image);
+ length=0;
+ index=0;
+ indexes=AccessMutableIndexes(image);
+
+ pixel.red=0;
+ pixel.green=0;
+ pixel.blue=0;
+ pixel.opacity=TransparentOpacity;
+
+ switch (quantum_type)
+ {
+ case IndexQuantum:
+ {
+ /*
+ PseudoClass
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ index=(*p++);
+ VerifyColormapIndex(image,index);
+ pixel=image->colormap[index];
+ length=(*p++)+1;
+ }
+ length--;
+ *indexes++=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ index=(*p++ << 8);
+ index|=(*p++);
+ VerifyColormapIndex(image,index);
+ pixel=image->colormap[index];
+ length=(*p++)+1;
+ }
+ length--;
+ *indexes++=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 32:
+ {
+ /*
+ This case should never actually be used.
+ */
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ index=(*p++ << 24);
+ index|=(*p++ << 16);
+ index|=(*p++ << 8);
+ index|=(*p++);
+ VerifyColormapIndex(image,index);
+ pixel=image->colormap[index];
+ length=(*p++)+1;
+ }
+ length--;
+ *indexes++=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case IndexAlphaQuantum:
+ {
+ /*
+ PseudoClass plus alpha channel
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ index=(*p++);
+ VerifyColormapIndex(image,index);
+ pixel=image->colormap[index];
+ quantum=(*p++);
+ pixel.opacity=MaxRGB-ScaleCharToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *indexes++=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ index=(*p++ << 8);
+ index|=(*p++);
+ VerifyColormapIndex(image,index);
+ pixel=image->colormap[index];
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.opacity=MaxRGB-ScaleShortToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *indexes++=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 32:
+ {
+ /*
+ This case should never actually be used.
+ */
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ index=(*p++ << 24);
+ index|=(*p++ << 16);
+ index|=(*p++ << 8);
+ index|=(*p++);
+ VerifyColormapIndex(image,index);
+ pixel=image->colormap[index];
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.opacity=MaxRGB-ScaleLongToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *indexes++=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case CMYKAQuantum:
+ {
+ /*
+ Directclass CMYK & matte
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ pixel.red=ScaleCharToQuantum(*p++);
+ pixel.green=ScaleCharToQuantum(*p++);
+ pixel.blue=ScaleCharToQuantum(*p++);
+ pixel.opacity=ScaleCharToQuantum(*p++);
+ index=(IndexPacket) MaxRGB-ScaleCharToQuantum(*p++);
+ length=(*p++)+1;
+ }
+ length--;
+ *indexes++=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.red=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.green=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.blue=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.opacity=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ index=(IndexPacket) MaxRGB-ScaleShortToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *indexes++=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.red=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.green=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.blue=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.opacity=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ index=(IndexPacket) MaxRGB-ScaleLongToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ indexes[x]=index;
+ *q++=pixel;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case CMYKQuantum:
+ {
+ /*
+ Directclass CMYK without matte
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ pixel.red=ScaleCharToQuantum(*p++);
+ pixel.green=ScaleCharToQuantum(*p++);
+ pixel.blue=ScaleCharToQuantum(*p++);
+ pixel.opacity=ScaleCharToQuantum(*p++);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.red=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.green=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.blue=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.opacity=ScaleShortToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.red=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.green=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.blue=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.opacity=ScaleLongToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case RGBAQuantum:
+ {
+ /*
+ Directclass RGB with matte
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ pixel.red=ScaleCharToQuantum(*p++);
+ pixel.green=ScaleCharToQuantum(*p++);
+ pixel.blue=ScaleCharToQuantum(*p++);
+ pixel.opacity=MaxRGB-ScaleCharToQuantum(*p++);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.red=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.green=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.blue=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.opacity=MaxRGB-ScaleShortToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.red=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.green=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.blue=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.opacity=MaxRGB-ScaleLongToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case RGBQuantum:
+ {
+ /*
+ Directclass RGB without matte
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ pixel.red=ScaleCharToQuantum(*p++);
+ pixel.green=ScaleCharToQuantum(*p++);
+ pixel.blue=ScaleCharToQuantum(*p++);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.red=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.green=ScaleShortToQuantum(quantum);
+ quantum=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.blue=ScaleShortToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (length == 0)
+ {
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.red=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.green=ScaleLongToQuantum(quantum);
+ quantum=(*p++ << 24);
+ quantum|=(*p++ << 16);
+ quantum|=(*p++ << 8);
+ quantum|=(*p++);
+ pixel.blue=ScaleLongToQuantum(quantum);
+ length=(*p++)+1;
+ }
+ length--;
+ *q++=pixel;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ }
+ }
+ return(True);
+}
+
+#if 0
+static void *BZLIBAllocFunc(void *opaque, int items, int size)
+{
+ ARG_NOT_USED(opaque);
+ return MagickMallocCleared((size_t) items*size);
+}
+static void BZLIBFreeFunc(void *opaque, void *address)
+{
+ ARG_NOT_USED(opaque);
+ MagickFree(address);
+}
+#endif
+
+#if defined(HasZLIB)
+static voidpf ZLIBAllocFunc(voidpf opaque, uInt items, uInt size)
+{
+ ARG_NOT_USED(opaque);
+ return MagickMallocCleared((size_t) items*size);
+}
+static void ZLIBFreeFunc(voidpf opaque, voidpf address)
+{
+ ARG_NOT_USED(opaque);
+ MagickFree(address);
+}
+#endif /* defined(HasZLIB) */
+
+#define ThrowMIFFReaderException(code_,reason_,image_) \
+do { \
+ if (number_of_profiles > 0) \
+ { \
+ unsigned int _index; \
+ for (_index=0; _index < number_of_profiles; _index++) \
+ { \
+ MagickFreeMemory(profiles[_index].name); \
+ MagickFreeMemory(profiles[_index].info); \
+ } \
+ MagickFreeMemory(profiles); \
+ number_of_profiles=0; \
+ } \
+ MagickFreeMemory(pixels); \
+ MagickFreeMemory(compress_pixels); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+
+static Image *ReadMIFFImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+#if defined(HasBZLIB)
+ bz_stream
+ bzip_info;
+#endif
+
+ char
+ id[MaxTextExtent],
+ keyword[MaxTextExtent];
+
+ double
+ version;
+
+ Image
+ *image;
+
+ int
+ c;
+
+ size_t
+ length,
+ compressed_length;
+
+ long
+ y;
+
+ QuantumType
+ quantum_type;
+
+ register long
+ i;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ unsigned char
+ *compress_pixels = (unsigned char *) NULL,
+ *pixels = (unsigned char *) NULL;
+
+ void
+ *pixels_p;
+
+ unsigned int
+ status;
+
+ unsigned int
+ colors,
+ depth,
+ packet_size,
+ quantum_size;
+
+ ProfileInfo
+ *profiles=0;
+
+ unsigned int
+ number_of_profiles=0;
+
+#if defined(HasZLIB)
+ z_stream
+ zip_info;
+#endif
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Decode image header; header terminates one character beyond a ':'.
+ */
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ {
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ *id='\0';
+ version=0.0;
+ do
+ {
+ /*
+ Decode image header; header terminates one character beyond a ':'.
+ */
+ colors=0;
+ image->depth=8;
+ image->compression=NoCompression;
+ image->storage_class=DirectClass;
+ while (isgraph(c) && (c != ':'))
+ {
+ register char
+ *p;
+
+ if (c == '{')
+ {
+ char
+ *comment;
+
+ size_t
+ comment_length;
+
+ /*
+ Read comment-- any text between { }.
+ */
+ comment_length=MaxTextExtent;
+ comment=MagickAllocateMemory(char *,comment_length);
+ if (comment == (char *) NULL)
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ p=comment;
+ for ( ; comment != (char *) NULL; p++)
+ {
+ c=ReadBlobByte(image);
+ if ((c == EOF) || (c == '}'))
+ break;
+ if ((size_t) (p-comment+1) >= comment_length)
+ {
+ *p='\0';
+ comment_length<<=1;
+ MagickReallocMemory(char *,comment,comment_length);
+ if (comment == (char *) NULL)
+ break;
+ p=comment+strlen(comment);
+ }
+ *p=c;
+ }
+ if (comment == (char *) NULL)
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ *p='\0';
+ (void) SetImageAttribute(image,"comment",comment);
+ MagickFreeMemory(comment);
+ c=ReadBlobByte(image);
+ }
+ else
+ if (isalnum(c))
+ {
+ char
+ *values;
+
+ size_t
+ values_length;
+
+ MagickBool
+ in_brace=MagickFalse;
+
+ /*
+ Get keyword.
+ */
+ keyword[0]='\0';
+ p=keyword;
+ do
+ {
+ if ((p-keyword) < (MaxTextExtent-1))
+ *p++=c;
+ c=ReadBlobByte(image);
+ } while ((c != '=') && (c != EOF));
+ *p='\0';
+ if (c == EOF)
+ ThrowMIFFReaderException(CorruptImageWarning,ImproperImageHeader,image);
+
+ /*
+ Get values.
+
+ Values not containing spaces are terminated by the first
+ white-space (or new-line) enountered. Values containing
+ spaces and/or new-lines must be surrounded by braces.
+ */
+ values_length=MaxTextExtent;
+ values=MagickAllocateMemory(char *,values_length);
+ if (values == (char *) NULL)
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ values[0]='\0';
+ c=ReadBlobByte(image);
+ in_brace=(c == '{');
+ if (in_brace)
+ c=ReadBlobByte(image);
+ p=values;
+ while ((((!in_brace) && (c != '\n')) ||
+ ((in_brace) && (c != '}'))) &&
+ (c != EOF))
+ {
+ if ((size_t) (p-values+1) >= values_length)
+ {
+ *p='\0';
+ values_length<<=1;
+ MagickReallocMemory(char *,values,values_length);
+ if (values == (char *) NULL)
+ break;
+ p=values+strlen(values);
+ }
+ if (values == (char *) NULL)
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ *p++=c;
+ c=ReadBlobByte(image);
+ if (!in_brace)
+ if (isspace(c))
+ break;
+ }
+ *p='\0';
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "keyword=\"%s\" values=\"%s\"",keyword,values);
+ /*
+ Assign a value to the specified keyword.
+ */
+ switch (*keyword)
+ {
+ case 'b':
+ case 'B':
+ {
+ if (LocaleCompare(keyword,"background-color") == 0)
+ {
+ (void) QueryColorDatabase(values,&image->background_color,
+ exception);
+ break;
+ }
+ if (LocaleCompare(keyword,"blue-primary") == 0)
+ {
+ (void) sscanf(values,"%lf,%lf",
+ &image->chromaticity.blue_primary.x,
+ &image->chromaticity.blue_primary.y);
+ break;
+ }
+ if (LocaleCompare(keyword,"border-color") == 0)
+ {
+ (void) QueryColorDatabase(values,&image->border_color,
+ exception);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'c':
+ case 'C':
+ {
+ if (LocaleCompare(keyword,"class") == 0)
+ {
+ image->storage_class=UndefinedClass;
+ if (LocaleCompare(values,"PseudoClass") == 0)
+ image->storage_class=PseudoClass;
+ else
+ if (LocaleCompare(values,"DirectClass") == 0)
+ image->storage_class=DirectClass;
+ break;
+ }
+ if (LocaleCompare(keyword,"colors") == 0)
+ {
+ colors=MagickAtoL(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"colorspace") == 0)
+ {
+ /*
+ ImageMagick now uses colorspace=sRGB for ordinary RGB images.
+ */
+ if (LocaleCompare(values,"sRGB") == 0)
+ image->colorspace=RGBColorspace;
+ else
+ image->colorspace=(StringToColorspaceType(values));
+ break;
+ }
+ if (LocaleCompare(keyword,"compression") == 0)
+ {
+ image->compression=NoCompression;
+ if (LocaleCompare(values,"None") == 0)
+ image->compression=NoCompression;
+ else
+ if (LocaleCompare(values,"Zip") == 0)
+ image->compression=ZipCompression;
+ else
+ if (LocaleCompare(values,"BZip") == 0)
+ image->compression=BZipCompression;
+ else
+ if ((LocaleCompare(values,"RLE") == 0) ||
+ (LocaleCompare(values,"RunlengthEncoded") == 0))
+ image->compression=RLECompression;
+ break;
+ }
+ if (LocaleCompare(keyword,"columns") == 0)
+ {
+ image->columns= MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'd':
+ case 'D':
+ {
+ if (LocaleCompare(keyword,"delay") == 0)
+ {
+ image->delay=MagickAtoL(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"depth") == 0)
+ {
+ image->depth=MagickAtoL(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"dispose") == 0)
+ {
+ image->dispose=(DisposeType) MagickAtoL(values);
+ if (LocaleCompare(values,"Background") == 0)
+ image->dispose=BackgroundDispose;
+ else
+ if (LocaleCompare(values,"None") == 0)
+ image->dispose=NoneDispose;
+ else
+ if (LocaleCompare(values,"Previous") == 0)
+ image->dispose=PreviousDispose;
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'g':
+ case 'G':
+ {
+ if (LocaleCompare(keyword,"gamma") == 0)
+ {
+ image->gamma=MagickAtoF(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"green-primary") == 0)
+ {
+ (void) sscanf(values,"%lf,%lf",
+ &image->chromaticity.green_primary.x,
+ &image->chromaticity.green_primary.y);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'i':
+ case 'I':
+ {
+ if (LocaleCompare(keyword,"id") == 0)
+ {
+ (void) strlcpy(id,values,MaxTextExtent);
+ break;
+ }
+ if (LocaleCompare(keyword,"iterations") == 0)
+ {
+ image->iterations=MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'm':
+ case 'M':
+ {
+ if (LocaleCompare(keyword,"matte") == 0)
+ {
+ image->matte=(LocaleCompare(values,"True") == 0) ||
+ (LocaleCompare(values,"true") == 0);
+ break;
+ }
+ if (LocaleCompare(keyword,"matte-color") == 0)
+ {
+ (void) QueryColorDatabase(values,&image->matte_color,
+ exception);
+ break;
+ }
+ if (LocaleCompare(keyword,"montage") == 0)
+ {
+ (void) CloneString(&image->montage,values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'o':
+ case 'O':
+ {
+ if (LocaleCompare(keyword,"opaque") == 0)
+ {
+ image->matte=(LocaleCompare(values,"True") == 0) ||
+ (LocaleCompare(values,"true") == 0);
+ break;
+ }
+ if (LocaleCompare(keyword,"orientation") == 0)
+ {
+ image->orientation=StringToOrientationType(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'p':
+ case 'P':
+ {
+ if (LocaleCompare(keyword,"page") == 0)
+ {
+ char
+ *geometry;
+
+ geometry=GetPageGeometry(values);
+ (void) GetGeometry(geometry,&image->page.x,&image->page.y,
+ &image->page.width,&image->page.height);
+ MagickFreeMemory(geometry);
+ break;
+ }
+ if ((LocaleNCompare(keyword,"profile-",8) == 0) ||
+ (LocaleNCompare(keyword,"profile:",8) == 0))
+ {
+ i=(long) number_of_profiles;
+ MagickReallocMemory(ProfileInfo *,profiles,(i+1)*sizeof(ProfileInfo));
+ if (profiles == (ProfileInfo *) NULL)
+ {
+ MagickFreeMemory(values);
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ profiles[i].name=AllocateString(keyword+8);
+ profiles[i].length=MagickAtoL(values);
+ profiles[i].info=(unsigned char *) NULL;
+ number_of_profiles++;
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'r':
+ case 'R':
+ {
+ if (LocaleCompare(keyword,"red-primary") == 0)
+ {
+ (void) sscanf(values,"%lf,%lf",
+ &image->chromaticity.red_primary.x,
+ &image->chromaticity.red_primary.y);
+ break;
+ }
+ if (LocaleCompare(keyword,"rendering-intent") == 0)
+ {
+ image->rendering_intent=UndefinedIntent;
+ if (LocaleCompare(values,"Saturation") == 0)
+ image->rendering_intent=SaturationIntent;
+ else
+ if (LocaleCompare(values,"perceptual") == 0)
+ image->rendering_intent=PerceptualIntent;
+ else
+ if (LocaleCompare(values,"absolute") == 0)
+ image->rendering_intent=AbsoluteIntent;
+ else
+ if (LocaleCompare(values,"relative") == 0)
+ image->rendering_intent=RelativeIntent;
+ break;
+ }
+ if (LocaleCompare(keyword,"resolution") == 0)
+ {
+ (void) GetMagickDimension(values,&image->x_resolution,
+ &image->y_resolution,NULL,NULL);
+ break;
+ }
+ if (LocaleCompare(keyword,"rows") == 0)
+ {
+ image->rows= MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 's':
+ case 'S':
+ {
+ if (LocaleCompare(keyword,"scene") == 0)
+ {
+ image->scene=MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'u':
+ case 'U':
+ {
+ if (LocaleCompare(keyword,"units") == 0)
+ {
+ image->units=UndefinedResolution;
+ if (LocaleCompare(values,"pixels-per-inch") == 0)
+ image->units=PixelsPerInchResolution;
+ else
+ if (LocaleCompare(values,"pixels-per-centimeter") == 0)
+ image->units=PixelsPerCentimeterResolution;
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'v':
+ case 'V':
+ {
+ if (LocaleCompare(keyword,"version") == 0)
+ {
+ version=MagickAtoF(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'w':
+ case 'W':
+ {
+ if (LocaleCompare(keyword,"white-point") == 0)
+ {
+ (void) sscanf(values,"%lf,%lf",
+ &image->chromaticity.white_point.x,
+ &image->chromaticity.white_point.y);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ default:
+ {
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ }
+ MagickFreeMemory(values);
+ }
+ else
+ {
+ c=ReadBlobByte(image);
+ }
+ while (isspace(c))
+ c=ReadBlobByte(image);
+ }
+ (void) ReadBlobByte(image);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "id=\"%s\" version=%g class=%s colorspace=%s compression=%s matte=%s "
+ "columns=%lu rows=%lu depth=%u",
+ id,version,
+ ClassTypeToString(image->storage_class),
+ ColorspaceTypeToString(image->colorspace),
+ CompressionTypeToString(image->compression),
+ MagickBoolToString(image->matte),
+ image->columns, image->rows, image->depth);
+
+ /*
+ Verify that required image information is defined.
+ */
+ if ((LocaleCompare(id,"ImageMagick") != 0) ||
+ (image->storage_class == UndefinedClass) ||
+ (image->compression == UndefinedCompression) ||
+ (image->colorspace == UndefinedColorspace) ||
+ (image->columns == 0) ||
+ (image->rows == 0))
+ {
+ if (image->previous)
+ {
+ DeleteImageFromList(&image);
+ ThrowException(exception,CorruptImageWarning,ImproperImageHeader,image->filename);
+ break;
+ }
+ else
+ {
+ ThrowMIFFReaderException(CorruptImageError,ImproperImageHeader,
+ image);
+ }
+ }
+
+ /*
+ Create a normalized version of depth.
+ */
+ if (image->depth <= 8)
+ depth=8;
+ else if (image->depth <= 16)
+ depth=16;
+ else
+ depth=32;
+
+ if (image->montage != (char *) NULL)
+ {
+ register char
+ *p;
+
+ /*
+ Image directory.
+ */
+ image->directory=MagickAllocateMemory(char *,MaxTextExtent);
+ if (image->directory == (char *) NULL)
+ ThrowMIFFReaderException(CorruptImageError,UnableToReadImageData,image);
+ p=image->directory;
+ do
+ {
+ *p='\0';
+ if (((strlen(image->directory)+1) % MaxTextExtent) == 0)
+ {
+ /*
+ Allocate more memory for the image directory.
+ */
+ MagickReallocMemory(char *,image->directory,
+ (strlen(image->directory)+MaxTextExtent+1));
+ if (image->directory == (char *) NULL)
+ ThrowMIFFReaderException(CorruptImageError,UnableToReadImageData,
+ image);
+ p=image->directory+strlen(image->directory);
+ }
+ c=ReadBlobByte(image);
+ *p++=c;
+ } while (c != '\0');
+ }
+
+ /*
+ Attached profiles.
+ */
+ if (number_of_profiles > 0)
+ {
+ for (i=0; i < (long) number_of_profiles; i++)
+ {
+ if (profiles[i].length == 0)
+ continue;
+ profiles[i].info=MagickAllocateMemory(unsigned char *,profiles[i].length);
+ if (profiles[i].info == (unsigned char *) NULL)
+ ThrowMIFFReaderException(CorruptImageError,UnableToReadGenericProfile,
+ image);
+ (void) ReadBlob(image,profiles[i].length,profiles[i].info);
+ (void) SetImageProfile(image,profiles[i].name,profiles[i].info,profiles[i].length);
+ MagickFreeMemory(profiles[i].name);
+ MagickFreeMemory(profiles[i].info);
+ }
+ MagickFreeMemory(profiles);
+ number_of_profiles=0;
+ }
+
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Create image colormap.
+ */
+ if (!AllocateImageColormap(image,colors != 0 ? colors : 256))
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if (colors != 0)
+ {
+ unsigned char
+ *colormap;
+
+ unsigned int
+ packet_size,
+ pixel;
+
+ /*
+ Read image colormap from file.
+ */
+ packet_size=3*depth/8;
+ colormap=MagickAllocateMemory(unsigned char *,packet_size*image->colors);
+ if (colormap == (unsigned char *) NULL)
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ (void) ReadBlob(image,packet_size*image->colors,colormap);
+ p=colormap;
+ switch (depth)
+ {
+ case 8:
+ {
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ }
+ break;
+ }
+ case 16:
+ {
+ for (i=0; i < (long) image->colors; i++)
+ {
+ pixel=(*p << 8) | *(p+1);
+ image->colormap[i].red=ScaleShortToQuantum(pixel);
+ p+=2;
+ pixel=(*p << 8) | *(p+1);
+ image->colormap[i].green=ScaleShortToQuantum(pixel);
+ p+=2;
+ pixel=(*p << 8) | *(p+1);
+ image->colormap[i].blue=ScaleShortToQuantum(pixel);
+ p+=2;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (i=0; i < (long) image->colors; i++)
+ {
+ pixel=(*p << 24) | (*(p+1) << 16) | (*(p+2) << 8) | *(p+3);
+ image->colormap[i].red=ScaleLongToQuantum(pixel);
+ p+=4;
+ pixel=(*p << 24) | (*(p+1) << 16) | (*(p+2) << 8) | *(p+3);
+ image->colormap[i].green=ScaleLongToQuantum(pixel);
+ p+=4;
+ pixel=(*p << 24) | (*(p+1) << 16) | (*(p+2) << 8) | *(p+3);
+ image->colormap[i].blue=ScaleLongToQuantum(pixel);
+ p+=4;
+ }
+ }
+ } /* switch (depth) */
+ MagickFreeMemory(colormap);
+ }
+ }
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowMIFFReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Determine import properties
+ */
+ quantum_size=0;
+ if (image->storage_class == PseudoClass)
+ {
+ quantum_type=image->matte ? IndexAlphaQuantum : IndexQuantum;
+ if (image->colors <= 256)
+ quantum_size=8;
+ else if (image->colors <= 65535)
+ quantum_size=16;
+ else
+ quantum_size=32;
+ }
+ else
+ {
+ quantum_type=RGBQuantum;
+ quantum_size=depth;
+ if IsGrayColorspace(image->colorspace)
+ {
+ quantum_type=GrayQuantum;
+ if (image->matte)
+ quantum_type=GrayAlphaQuantum;
+ }
+ else if (image->colorspace == CMYKColorspace)
+ {
+ quantum_type=CMYKQuantum;
+ if (image->matte)
+ quantum_type=CMYKAQuantum;
+ }
+ else
+ {
+ quantum_type=RGBQuantum;
+ if (image->matte)
+ quantum_type=RGBAQuantum;
+ }
+ }
+ /*
+ Allocate image pixels.
+ */
+ packet_size=quantum_size/8;
+ if ((image->storage_class == DirectClass) &&
+ (!IsGrayColorspace(image->colorspace)))
+ packet_size=3*quantum_size/8;
+ if (image->colorspace == CMYKColorspace)
+ packet_size+=quantum_size/8;
+ if (image->matte)
+ packet_size+=quantum_size/8;
+ if (image->compression == RLECompression)
+ packet_size++;
+ pixels=MagickAllocateArray(unsigned char *,packet_size,image->columns);
+ if (pixels == (unsigned char *) NULL)
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ length=(size_t) (1.01*MagickArraySize(packet_size,image->columns));
+ if (length)
+ length += 600;
+ compressed_length = length;
+ compress_pixels=MagickAllocateMemory(unsigned char *,compressed_length);
+ if (compress_pixels == (unsigned char *) NULL)
+ ThrowMIFFReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Read image pixels.
+ */
+ length=0;
+ switch (image->compression)
+ {
+#if defined(HasZLIB)
+ case ZipCompression:
+ {
+ int
+ code=0;
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (y == 0)
+ {
+ zip_info.zalloc=ZLIBAllocFunc;
+ zip_info.zfree=ZLIBFreeFunc;
+ zip_info.opaque=(voidpf) NULL;
+ code=inflateInit(&zip_info);
+ status|=code >= 0;
+ zip_info.avail_in=0;
+ }
+ zip_info.next_out=pixels;
+ zip_info.avail_out=(uInt) (packet_size*image->columns);
+ do
+ {
+ int
+ zip_status;
+
+ if (zip_info.avail_in == 0)
+ {
+ zip_info.next_in=compress_pixels;
+ if (version == 0)
+ {
+ length=(int) (1.01*packet_size*image->columns+12);
+ zip_info.avail_in=(uInt) ReadBlob(image,length,zip_info.next_in);
+ }
+ else
+ {
+ length=ReadBlobMSBLong(image);
+ if (length > compressed_length)
+ {
+ (void) inflateEnd(&zip_info);
+ ThrowMIFFReaderException(CorruptImageError,
+ LengthAndFilesizeDoNotMatch,
+ image);
+ }
+ zip_info.avail_in=(uInt) ReadBlob(image,length,zip_info.next_in);
+ if ((size_t) zip_info.avail_in != length)
+ {
+ (void) inflateEnd(&zip_info);
+ ThrowMIFFReaderException(CorruptImageError,
+ UnexpectedEndOfFile,
+ image);
+ }
+ }
+ }
+ zip_status=inflate(&zip_info,Z_NO_FLUSH);
+ if (zip_status == Z_STREAM_END)
+ break;
+ else if (zip_status != Z_OK)
+ {
+ (void) inflateEnd(&zip_info);
+ ThrowMIFFReaderException(CorruptImageError,UnableToUncompressImage,
+ image);
+ }
+ } while (zip_info.avail_out != 0);
+ if (y == (long) (image->rows-1))
+ {
+ if (version == 0)
+ (void) SeekBlob(image,-((ExtendedSignedIntegralType)
+ zip_info.avail_in),SEEK_CUR);
+ code=inflateEnd(&zip_info);
+ status|=code >= 0;
+ }
+ (void) ImportImagePixelArea(image,quantum_type,quantum_size,pixels,0,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ } /* End case ZipCompression */
+#endif
+#if defined(HasBZLIB)
+ case BZipCompression:
+ {
+ int
+ code=0;
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (y == 0)
+ {
+ bzip_info.bzalloc=NULL;
+ bzip_info.bzfree=NULL;
+ bzip_info.opaque=NULL;
+ code=BZ2_bzDecompressInit(&bzip_info,image_info->verbose,False);
+ status|=code >= 0;
+ bzip_info.avail_in=0;
+ }
+ bzip_info.next_out=(char *) pixels;
+ bzip_info.avail_out=(unsigned int) (packet_size*image->columns);
+ do
+ {
+ int
+ bz_status;
+
+ if (bzip_info.avail_in == 0)
+ {
+ bzip_info.next_in=(char *) compress_pixels;
+ if (version == 0)
+ {
+ length=(int) (1.01*packet_size*image->columns+600);
+ bzip_info.avail_in=(unsigned int) ReadBlob(image,length,bzip_info.next_in);
+ }
+ else
+ {
+ length=ReadBlobMSBLong(image);
+ bzip_info.avail_in=(unsigned int) ReadBlob(image,length,bzip_info.next_in);
+ if ((size_t) bzip_info.avail_in != length)
+ {
+ ThrowMIFFReaderException(CorruptImageError,UnexpectedEndOfFile,
+ image);
+ }
+ }
+ }
+ bz_status=BZ2_bzDecompress(&bzip_info);
+ if (bz_status == BZ_STREAM_END)
+ break;
+ else if (bz_status != BZ_OK)
+ {
+ (void) BZ2_bzDecompressEnd(&bzip_info);
+ ThrowMIFFReaderException(CorruptImageError,UnableToUncompressImage,
+ image);
+ }
+ } while (bzip_info.avail_out != 0);
+ if (y == (long) (image->rows-1))
+ {
+ if (version == 0)
+ (void) SeekBlob(image,-((ExtendedSignedIntegralType)
+ bzip_info.avail_in),SEEK_CUR);
+ code=BZ2_bzDecompressEnd(&bzip_info);
+ status|=code >= 0;
+ }
+ (void) ImportImagePixelArea(image,quantum_type,quantum_size,pixels,0,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ } /* End case BZipCompression */
+#endif
+ case RLECompression:
+ {
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ /*
+ Collect one pixel row
+ */
+ p=pixels;
+ for (length=0; length < image->columns; )
+ {
+ p+=ReadBlob(image,packet_size,p);
+ length+=*(p-1)+1;
+ }
+
+ (void) ImportRLEPixels(image,quantum_type,quantum_size,pixels);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+
+ }
+ break;
+ } /* End case RLECompression */
+ default:
+ {
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ pixels_p=pixels;
+ (void) ReadBlobZC(image,packet_size*image->columns,&pixels_p);
+ (void) ImportImagePixelArea(image,quantum_type,quantum_size,(const unsigned char*) pixels_p,0,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ } /* End switch (image->compression) */
+
+ /*
+ Verify that pixel transfer loops completed
+ */
+ if (y != (long) image->rows)
+ status=False;
+
+ MagickFreeMemory(pixels);
+ MagickFreeMemory(compress_pixels);
+ if (status == False)
+ {
+ GetImageException(image,exception);
+ CloseBlob(image);
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ do
+ {
+ c=ReadBlobByte(image);
+ } while (!isgraph(c) && (c != EOF));
+ if (c != EOF)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ }
+ } while (c != EOF);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMIFFImage adds attributes for the MIFF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMIFFImage method is:
+%
+% RegisterMIFFImage(void)
+%
+*/
+ModuleExport void RegisterMIFFImage(void)
+{
+ static char
+ version[MaxTextExtent];
+
+ MagickInfo
+ *entry;
+
+ *version='\0';
+#if defined(MagickLibVersionText)
+ (void) strlcpy(version,MagickLibVersionText,MaxTextExtent);
+#if defined(ZLIB_VERSION)
+ (void) strlcat(version," with Zlib ",MaxTextExtent);
+ (void) strlcat(version,ZLIB_VERSION,MaxTextExtent);
+#endif
+#if defined(HasBZLIB)
+ (void) strlcat(version," and BZlib",MaxTextExtent);
+#endif
+#endif
+ entry=SetMagickInfo("MIFF");
+ entry->decoder=(DecoderHandler) ReadMIFFImage;
+ entry->encoder=(EncoderHandler) WriteMIFFImage;
+ entry->magick=(MagickHandler) IsMIFF;
+ entry->description="Magick Image File Format";
+ entry->seekable_stream=MagickTrue;
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="MIFF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMIFFImage removes format registrations made by the
+% MIFF module from the list of supported formats.
+%
+% The format of the UnregisterMIFFImage method is:
+%
+% UnregisterMIFFImage(void)
+%
+*/
+ModuleExport void UnregisterMIFFImage(void)
+{
+ (void) UnregisterMagickInfo("MIFF");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMIFFImage writes a MIFF image to a file.
+%
+% The format of the WriteMIFFImage method is:
+%
+% unsigned int WriteMIFFImage(const ImageInfo *image_info,Image *image)
+%
+% Compression code contributed by Kyle Shorter.
+%
+% A description of each parameter follows:
+%
+% o status: Method WriteMIFFImage return True if the image is written.
+% False is returned if there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static void WriteRunlengthPacket(const Image *image,
+ const unsigned int quantum_size,
+ const PixelPacket *pixel,
+ const size_t length,
+ unsigned char **qp,
+ const IndexPacket index)
+{
+ register unsigned char
+ *q;
+
+ unsigned int
+ value;
+
+ assert((quantum_size == 8) || (quantum_size == 16) || (quantum_size == 32));
+
+ q = *qp;
+
+ if (image->storage_class != DirectClass)
+ {
+ value=index;
+ /*
+ Fall-through logic
+ */
+ switch (quantum_size)
+ {
+ case 32:
+ {
+ *q++=(unsigned char) (value >> 24);
+ *q++=(unsigned char) (value >> 16);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ break;
+ }
+ case 16:
+ {
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ break;
+ }
+ case 8:
+ {
+ *q++=(unsigned char) value;
+ break;
+ }
+ } /* switch (quantum_size) */
+ if (image->matte)
+ {
+ value=MaxRGB-pixel->opacity;
+ switch (quantum_size)
+ {
+ case 32:
+ {
+ *q++=(unsigned char) (value >> 24);
+ *q++=(unsigned char) (value >> 16);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ break;
+ }
+ case 16:
+ {
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ break;
+ }
+ case 8:
+ {
+ *q++=(unsigned char) value;
+ break;
+ }
+ } /* switch (quantum_size) */
+ }
+ }
+ else
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ *q++=ScaleQuantumToChar(pixel->red);
+ *q++=ScaleQuantumToChar(pixel->green);
+ *q++=ScaleQuantumToChar(pixel->blue);
+ if (image->colorspace == CMYKColorspace)
+ {
+ *q++=ScaleQuantumToChar(pixel->opacity);
+ if (image->matte)
+ *q++=ScaleQuantumToChar(index);
+ }
+ else
+ if (image->matte)
+ *q++=ScaleQuantumToChar(MaxRGB-pixel->opacity);
+ break;
+ }
+ case 16:
+ {
+ value=ScaleQuantumToShort(pixel->red);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ value=ScaleQuantumToShort(pixel->green);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ value=ScaleQuantumToShort(pixel->blue);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ if (image->colorspace == CMYKColorspace)
+ {
+ value=ScaleQuantumToShort(pixel->opacity);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ if (image->matte)
+ {
+ value=ScaleQuantumToShort(MaxRGB-index);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ }
+ }
+ else
+ if (image->matte)
+ {
+ value=ScaleQuantumToShort(MaxRGB-pixel->opacity);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ }
+ break;
+ }
+ case 32:
+ {
+ value=ScaleQuantumToLong(pixel->red);
+ *q++=(unsigned char) (value >> 24);
+ *q++=(unsigned char) (value >> 16);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ value=ScaleQuantumToLong(pixel->green);
+ *q++=(unsigned char) (value >> 24);
+ *q++=(unsigned char) (value >> 16);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ value=ScaleQuantumToLong(pixel->blue);
+ *q++=(unsigned char) (value >> 24);
+ *q++=(unsigned char) (value >> 16);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ if (image->colorspace == CMYKColorspace)
+ {
+ value=ScaleQuantumToLong(pixel->opacity);
+ *q++=(unsigned char) (value >> 24);
+ *q++=(unsigned char) (value >> 16);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ if (image->matte)
+ {
+ value=ScaleQuantumToLong(MaxRGB-index);
+ *q++=(unsigned char) (value >> 24);
+ *q++=(unsigned char) (value >> 16);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ }
+ }
+ else
+ if (image->matte)
+ {
+ value=ScaleQuantumToLong(MaxRGB-pixel->opacity);
+ *q++=(unsigned char) (value >> 24);
+ *q++=(unsigned char) (value >> 16);
+ *q++=(unsigned char) (value >> 8);
+ *q++=(unsigned char) value;
+ }
+ }
+ } /* switch (quantum_size) */
+ }
+ *q++=(unsigned char) length;
+ *qp=q;
+}
+
+#define ThrowMIFFWriterException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(compress_pixels) \
+ MagickFreeMemory(pixels); \
+ ThrowWriterException(code_,reason_,image_); \
+}
+
+static unsigned int WriteMIFFImage(const ImageInfo *image_info,Image *image)
+{
+
+#if defined(HasBZLIB)
+ bz_stream
+ bzip_info;
+#endif
+
+ char
+ buffer[MaxTextExtent];
+
+ CompressionType
+ compression;
+
+ const ImageAttribute
+ *attribute;
+
+ IndexPacket
+ index;
+
+ long
+ y;
+
+ PixelPacket
+ pixel;
+
+ QuantumType
+ quantum_type;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ unsigned char
+ *q;
+
+ size_t
+ length;
+
+ unsigned char
+ *compress_pixels = (unsigned char *) NULL,
+ *pixels = (unsigned char *) NULL;
+
+ unsigned int
+ depth,
+ status,
+ quantum_size;
+
+ unsigned long
+ packet_size,
+ scene;
+
+ ImageProfileIterator
+ profile_iterator;
+
+ const char
+ *profile_name;
+
+ const unsigned char
+ *profile_info;
+
+ size_t
+ profile_length;
+
+#if defined(HasZLIB)
+ z_stream
+ zip_info;
+#endif
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ compression=image->compression;
+ if (image_info->compression != UndefinedCompression)
+ compression=image_info->compression;
+ scene=0;
+ do
+ {
+ /*
+ Transform colorspace if necessary.
+ */
+ if (((image_info->colorspace != UndefinedColorspace) ||
+ (image->colorspace != CMYKColorspace)) &&
+ (image_info->colorspace != CMYKColorspace))
+ (void) TransformColorspace(image,RGBColorspace);
+ else
+ (void) TransformColorspace(image,CMYKColorspace);
+ /*
+ Valid depths are 8/16/32
+ */
+ if (image->depth > 16)
+ depth=32;
+ else if (image->depth > 8)
+ depth=16;
+ else
+ depth=8;
+ if (image->storage_class != DirectClass)
+ {
+ if (image->colors > 65536)
+ quantum_size=32;
+ else if (image->colors > 256)
+ quantum_size=16;
+ else
+ quantum_size=8;
+ }
+ else
+ {
+ quantum_size=depth;
+ }
+ /*
+ Allocate image pixels.
+ */
+ packet_size=quantum_size/8;
+ if (image->storage_class == DirectClass)
+ packet_size=3*quantum_size/8;
+ if (image->colorspace == CMYKColorspace)
+ packet_size+=quantum_size/8;
+ if (image->matte)
+ packet_size+=quantum_size/8;
+ if (compression == RLECompression)
+ packet_size+=quantum_size/8;
+ length=packet_size*image->columns;
+ pixels=MagickAllocateMemory(unsigned char *,length);
+ length=(size_t) (1.01*packet_size*image->columns+600);
+ if ((compression == BZipCompression) || (compression == ZipCompression))
+ if (length != (unsigned int) length)
+ compression=NoCompression;
+ compress_pixels=MagickAllocateMemory(unsigned char *,length);
+ if ((pixels == (unsigned char *) NULL) ||
+ (compress_pixels == (unsigned char *) NULL))
+ ThrowMIFFWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Write MIFF header.
+ */
+ (void) WriteBlobString(image,"id=ImageMagick version=1.0\n");
+ if (image->storage_class == PseudoClass)
+ FormatString(buffer,"class=PseudoClass colors=%u matte=%.1024s\n",
+ image->colors,MagickBoolToString(image->matte));
+ else
+ if (image->colorspace == CMYKColorspace)
+ FormatString(buffer,
+ "class=DirectClass colorspace=CMYK matte=%.1024s\n",
+ MagickBoolToString(image->matte));
+ else
+ FormatString(buffer,"class=DirectClass matte=%.1024s\n",
+ MagickBoolToString(image->matte));
+ (void) WriteBlobString(image,buffer);
+ *buffer='\0';
+ switch(compression)
+ {
+ case NoCompression:
+ default:
+ compression=NoCompression;
+ break;
+ case RLECompression:
+ FormatString(buffer,"compression=RLE\n");
+ break;
+#if defined(HasBZLIB)
+ case BZipCompression:
+ FormatString(buffer,"compression=BZip\n");
+ break;
+#endif /* defined(HasBZLIB) */
+#if defined(HasZLIB)
+ case ZipCompression:
+ FormatString(buffer,"compression=Zip\n");
+ break;
+#endif /* defined(HasZLIB) */
+ }
+ if (*buffer != '\0')
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"columns=%lu rows=%lu depth=%u\n",image->columns,
+ image->rows,depth);
+ (void) WriteBlobString(image,buffer);
+ if ((image->x_resolution != 0) && (image->y_resolution != 0))
+ {
+ char
+ units[MaxTextExtent];
+
+ /*
+ Set image resolution.
+ */
+ (void) strcpy(units,"undefined");
+ if (image->units == PixelsPerInchResolution)
+ (void) strcpy(units,"pixels-per-inch");
+ if (image->units == PixelsPerCentimeterResolution)
+ (void) strcpy(units,"pixels-per-centimeter");
+ FormatString(buffer,"Resolution=%gx%g units=%.1024s\n",
+ image->x_resolution,image->y_resolution,units);
+ (void) WriteBlobString(image,buffer);
+ }
+ if ((image->page.width != 0) && (image->page.height != 0))
+ {
+ FormatString(buffer,"page=%lux%lu%+ld%+ld\n",image->page.width,
+ image->page.height,image->page.x,image->page.y);
+ (void) WriteBlobString(image,buffer);
+ }
+ if ((image->next != (Image *) NULL) || (image->previous != (Image *) NULL))
+ {
+ if (image->scene == 0)
+ FormatString(buffer,"iterations=%lu delay=%lu\n",image->iterations,
+ image->delay);
+ else
+ FormatString(buffer,"scene=%lu iterations=%lu delay=%lu\n",
+ image->scene,image->iterations,image->delay);
+ (void) WriteBlobString(image,buffer);
+ }
+ else
+ {
+ if (image->scene != 0)
+ {
+ FormatString(buffer,"scene=%lu\n",image->scene);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->iterations != 0)
+ {
+ FormatString(buffer,"iterations=%lu\n",image->iterations);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->delay != 0)
+ {
+ FormatString(buffer,"delay=%lu\n",image->delay);
+ (void) WriteBlobString(image,buffer);
+ }
+ }
+ if (image->dispose != UndefinedDispose)
+ {
+ if (image->dispose == BackgroundDispose)
+ (void) strcpy(buffer,"dispose=background\n");
+ else
+ if (image->dispose == NoneDispose)
+ (void) strcpy(buffer,"dispose=none\n");
+ else
+ (void) strcpy(buffer,"dispose=previous\n");
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->rendering_intent != UndefinedIntent)
+ {
+ if (image->rendering_intent == SaturationIntent)
+ (void) strcpy(buffer,"rendering-intent=saturation\n");
+ else
+ if (image->rendering_intent == PerceptualIntent)
+ (void) strcpy(buffer,"rendering-intent=perceptual\n");
+ else
+ if (image->rendering_intent == AbsoluteIntent)
+ (void) strcpy(buffer,"rendering-intent=absolute\n");
+ else
+ (void) strcpy(buffer,"rendering-intent=relative\n");
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->gamma != 0.0)
+ {
+ FormatString(buffer,"gamma=%g\n",image->gamma);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->chromaticity.white_point.x != 0.0)
+ {
+ /*
+ Note chomaticity points.
+ */
+ FormatString(buffer,
+ "red-primary=%g,%g green-primary=%g,%g blue-primary=%g,%g\n",
+ image->chromaticity.red_primary.x,image->chromaticity.red_primary.y,
+ image->chromaticity.green_primary.x,
+ image->chromaticity.green_primary.y,
+ image->chromaticity.blue_primary.x,
+ image->chromaticity.blue_primary.y);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"white-point=%g,%g\n",
+ image->chromaticity.white_point.x,image->chromaticity.white_point.y);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->orientation != UndefinedOrientation)
+ {
+ FormatString(buffer,"orientation=%s\n",
+ OrientationTypeToString(image->orientation));
+ (void) WriteBlobString(image,buffer);
+ }
+ /*
+ Old MIFF readers (including GM 1.1) expect the ICC profile,
+ followed by the IPTC profile, followed by any remaining
+ profiles.
+ */
+ if ((GetImageProfile(image,"ICM",&profile_length)))
+ {
+ FormatString(buffer,"profile-icc=%lu\n",(unsigned long)
+ profile_length);
+ (void) WriteBlobString(image,buffer);
+ }
+ if ((GetImageProfile(image,"IPTC",&profile_length)))
+ {
+ FormatString(buffer,"profile-iptc=%lu\n",(unsigned long)
+ profile_length);
+ (void) WriteBlobString(image,buffer);
+ }
+
+ /*
+ Generic profiles.
+ */
+ profile_iterator=AllocateImageProfileIterator(image);
+ if (profile_iterator)
+ {
+ while(NextImageProfile(profile_iterator,&profile_name,&profile_info,
+ &profile_length) != MagickFail)
+ {
+ if ((LocaleCompare(profile_name,"ICC") == 0) ||
+ (LocaleCompare(profile_name,"ICM") == 0) ||
+ (LocaleCompare(profile_name,"IPTC") == 0) ||
+ (LocaleCompare(profile_name,"8BIM") == 0))
+ continue;
+ FormatString(buffer,"profile-%.1024s=%lu\n",
+ profile_name,(unsigned long) profile_length);
+ (void) WriteBlobString(image,buffer);
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+ }
+
+ if (image->montage != (char *) NULL)
+ {
+ FormatString(buffer,"montage=%.1024s\n",image->montage);
+ (void) WriteBlobString(image,buffer);
+ }
+ attribute=GetImageAttribute(image,(char *) NULL);
+ for ( ; attribute != (ImageAttribute *) NULL; attribute=attribute->next)
+ {
+ if (*attribute->key == '[')
+ continue;
+ FormatString(buffer,"%.1024s=",attribute->key);
+ (void) WriteBlobString(image,buffer);
+ for (i=0; i < (long) strlen(attribute->value); i++)
+ if (isspace((int) attribute->value[i]))
+ break;
+ if (i < (long) strlen(attribute->value))
+ (void) WriteBlobByte(image,'{');
+ (void) WriteBlob(image,strlen(attribute->value),attribute->value);
+ if (i < (long) strlen(attribute->value))
+ (void) WriteBlobByte(image,'}');
+ (void) WriteBlobByte(image,'\n');
+ }
+ (void) WriteBlobString(image,"\f\n:\032");
+ if (image->montage != (char *) NULL)
+ {
+ /*
+ Write montage tile directory.
+ */
+ if (image->directory != (char *) NULL)
+ (void) WriteBlob(image,strlen(image->directory),image->directory);
+ (void) WriteBlobByte(image,'\0');
+ }
+ /*
+ Color profile.
+ */
+ if ((profile_info=GetImageProfile(image,"ICM",&profile_length)))
+ (void) WriteBlob(image,profile_length, (const char *) profile_info);
+ /*
+ IPTC profile.
+ */
+ if ((profile_info=GetImageProfile(image,"IPTC",&profile_length)))
+ (void) WriteBlob(image,profile_length,(const char *) profile_info);
+ /*
+ Generic profiles.
+ */
+ profile_iterator=AllocateImageProfileIterator(image);
+ while(NextImageProfile(profile_iterator,&profile_name,&profile_info,
+ &profile_length) != MagickFail)
+ {
+ if ((LocaleCompare(profile_name,"ICC") == 0) ||
+ (LocaleCompare(profile_name,"ICM") == 0) ||
+ (LocaleCompare(profile_name,"IPTC") == 0) ||
+ (LocaleCompare(profile_name,"8BIM") == 0))
+ continue;
+
+ (void) WriteBlob(image,profile_length,(const char *) profile_info);
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+
+ if (image->storage_class == PseudoClass)
+ {
+ unsigned char
+ *colormap;
+
+ unsigned int
+ packet_size;
+
+ /*
+ Allocate colormap.
+ */
+ packet_size=3*depth/8;
+ colormap=MagickAllocateMemory(unsigned char *,packet_size*image->colors);
+ if (colormap == (unsigned char *) NULL)
+ ThrowMIFFWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ /*
+ Write colormap to file.
+ */
+ q=colormap;
+ switch (depth)
+ {
+ case 8:
+ {
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=ScaleQuantumToChar(image->colormap[i].red);
+ *q++=ScaleQuantumToChar(image->colormap[i].green);
+ *q++=ScaleQuantumToChar(image->colormap[i].blue);
+ }
+ break;
+ }
+#if QuantumDepth > 8
+ case 16:
+ {
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=ScaleQuantumToShort(image->colormap[i].red) >> 8;
+ *q++=ScaleQuantumToShort(image->colormap[i].red);
+ *q++=ScaleQuantumToShort(image->colormap[i].green) >> 8;
+ *q++=ScaleQuantumToShort(image->colormap[i].green);
+ *q++=ScaleQuantumToShort(image->colormap[i].blue) >> 8;
+ *q++=ScaleQuantumToShort(image->colormap[i].blue);
+ }
+ break;
+ }
+#endif /* QuantumDepth > 8 */
+#if QuantumDepth > 16
+ case 32:
+ {
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=image->colormap[i].red >> 24;
+ *q++=image->colormap[i].red >> 16;
+ *q++=image->colormap[i].red >> 8;
+ *q++=image->colormap[i].red;
+ *q++=image->colormap[i].green >> 24;
+ *q++=image->colormap[i].green >> 16;
+ *q++=image->colormap[i].green >> 8;
+ *q++=image->colormap[i].green;
+ *q++=image->colormap[i].blue >> 24;
+ *q++=image->colormap[i].blue >> 16;
+ *q++=image->colormap[i].blue >> 8;
+ *q++=image->colormap[i].blue;
+ }
+ break;
+ }
+#endif /* QuantumDepth > 16 */
+ } /* switch (depth) */
+ (void) WriteBlob(image,packet_size*image->colors,colormap);
+ MagickFreeMemory(colormap);
+ }
+ /*
+ Write image pixels to file.
+ */
+ quantum_type=RGBQuantum;
+ if (image->storage_class == PseudoClass)
+ {
+ quantum_type=IndexAlphaQuantum;
+ if (!image->matte)
+ quantum_type=IndexQuantum;
+ }
+ else
+ if (image->colorspace == CMYKColorspace)
+ {
+ quantum_type=CMYKAQuantum;
+ if (!image->matte)
+ quantum_type=CMYKQuantum;
+ }
+ else
+ {
+ quantum_type=RGBAQuantum;
+ if (!image->matte)
+ quantum_type=RGBQuantum;
+ }
+ status=True;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using QuantumType %s, depth %u",
+ QuantumTypeToString(quantum_type),quantum_size);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ q=pixels;
+ switch (compression)
+ {
+#if defined(HasZLIB)
+ case ZipCompression:
+ {
+ int
+ code;
+
+ if (y == 0)
+ {
+ zip_info.zalloc=ZLIBAllocFunc;
+ zip_info.zfree=ZLIBFreeFunc;
+ zip_info.opaque=(voidpf) NULL;
+ code=deflateInit(&zip_info,(int) Min(image_info->quality/10,9));
+ status|=code >= 0;
+ }
+ zip_info.next_in=pixels;
+ zip_info.avail_in=(uInt) (packet_size*image->columns);
+ (void) ExportImagePixelArea(image,quantum_type,quantum_size,pixels,0,0);
+ do
+ {
+ zip_info.next_out=compress_pixels;
+ zip_info.avail_out=(uInt) (1.01*packet_size*image->columns+12);
+ code=deflate(&zip_info,Z_NO_FLUSH);
+ status|=code >= 0;
+ length=zip_info.next_out-compress_pixels;
+ if (length != 0)
+ {
+ (void) WriteBlobMSBLong(image,(const magick_uint32_t) length);
+ (void) WriteBlob(image,length,compress_pixels);
+ }
+ } while (zip_info.avail_in != 0);
+ if (y == (long) (image->rows-1))
+ {
+ for ( ; ; )
+ {
+ zip_info.next_out=compress_pixels;
+ zip_info.avail_out=(uInt) (1.01*packet_size*image->columns+12);
+ code=deflate(&zip_info,Z_FINISH);
+ status|=code >= 0;
+ length=zip_info.next_out-compress_pixels;
+ if (length == 0)
+ break;
+ (void) WriteBlobMSBLong(image,(const magick_uint32_t) length);
+ (void) WriteBlob(image,length,compress_pixels);
+ }
+ status=!deflateEnd(&zip_info);
+ }
+ break;
+ }
+#endif
+#if defined(HasBZLIB)
+ case BZipCompression:
+ {
+ int
+ code;
+
+ if (y == 0)
+ {
+ bzip_info.bzalloc=NULL;
+ bzip_info.bzfree=NULL;
+ bzip_info.opaque=NULL;
+ code=BZ2_bzCompressInit(&bzip_info,
+ (int) Min(image_info->quality/10,9),image_info->verbose,0);
+ status|=code >= 0;
+ }
+ bzip_info.next_in=(char *) pixels;
+ bzip_info.avail_in=(unsigned int) (packet_size*image->columns);
+ (void) ExportImagePixelArea(image,quantum_type,quantum_size,pixels,0,0);
+ do
+ {
+ bzip_info.next_out=(char *) compress_pixels;
+ bzip_info.avail_out=(unsigned int)
+ (1.01*packet_size*image->columns+600);
+ code=BZ2_bzCompress(&bzip_info,BZ_FLUSH);
+ status|=code >= 0;
+ length=bzip_info.next_out-(char *) compress_pixels;
+ if (length != 0)
+ {
+ (void) WriteBlobMSBLong(image,(const magick_uint32_t) length);
+ (void) WriteBlob(image,length,compress_pixels);
+ }
+ } while (bzip_info.avail_in != 0);
+ if (y == (long) (image->rows-1))
+ {
+ for ( ; ; )
+ {
+ bzip_info.next_out=(char *) compress_pixels;
+ bzip_info.avail_out=(unsigned int)
+ (1.01*packet_size*image->columns+600);
+ code=BZ2_bzCompress(&bzip_info,BZ_FINISH);
+ status|=code >= 0;
+ length=bzip_info.next_out-(char *) compress_pixels;
+ if (length == 0)
+ break;
+ (void) WriteBlobMSBLong(image,(const magick_uint32_t) length);
+ (void) WriteBlob(image,length,compress_pixels);
+ }
+ status=!BZ2_bzCompressEnd(&bzip_info);
+ }
+ break;
+ }
+#endif
+ case RLECompression:
+ {
+ pixel=(*p);
+ index=0;
+ if (image->storage_class == PseudoClass)
+ index=(*indexes);
+ length=255;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((length < 255) && (x < (long) (image->columns-1)) &&
+ ColorMatch(p,(&pixel)) &&
+ ((image->matte == False) || (p->opacity == pixel.opacity)))
+ length++;
+ else
+ {
+ if (x > 0)
+ WriteRunlengthPacket(image,quantum_size,&pixel,length,&q,index);
+ length=0;
+ }
+ if (image->storage_class == PseudoClass)
+ index=indexes[x];
+ pixel=(*p);
+ p++;
+ }
+ WriteRunlengthPacket(image,quantum_size,&pixel,length,&q,index);
+ (void) WriteBlob(image,q-pixels,pixels);
+ break;
+ }
+ default:
+ {
+ (void) ExportImagePixelArea(image,quantum_type,quantum_size,pixels,0,0);
+ (void) WriteBlob(image,packet_size*image->columns,pixels);
+ break;
+ }
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(pixels);
+ MagickFreeMemory(compress_pixels);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(status);
+}
diff --git a/coders/mono.c b/coders/mono.c
new file mode 100644
index 0000000..1f5028c
--- /dev/null
+++ b/coders/mono.c
@@ -0,0 +1,341 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M OOO N N OOO %
+% MM MM O O NN N O O %
+% M M M O O N N N O O %
+% M M O O N NN O O %
+% M M OOO N N OOO %
+% %
+% %
+% Read/Write Raw Bi-Level Bitmap Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMONOImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M O N O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMONOImage reads an image of raw bytes in LSB order and returns
+% it. It allocates the memory necessary for the new Image structure and
+% returns a pointer to the new image.
+%
+% The format of the ReadMONOImage method is:
+%
+% Image *ReadMONOImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMONOImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadMONOImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ unsigned char
+ bit,
+ byte;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ for (i=0; i < image->offset; i++)
+ {
+ if (EOF == ReadBlobByte(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ }
+ /*
+ Initialize image colormap.
+ */
+ if (!AllocateImageColormap(image,2))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+ /*
+ Convert bi-level image to pixel packets.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ bit=0U;
+ byte=0U;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (bit == 0U)
+ byte=ReadBlobByte(image);
+ indexes[x]=(byte & 0x01U) ? 0x01U : 0x00U;
+ bit++;
+ if (bit == 8U)
+ bit=0U;
+ byte>>=1U;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) SyncImage(image);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M O N O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMONOImage adds attributes for the MONO image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMONOImage method is:
+%
+% RegisterMONOImage(void)
+%
+*/
+ModuleExport void RegisterMONOImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("MONO");
+ entry->decoder=(DecoderHandler) ReadMONOImage;
+ entry->encoder=(EncoderHandler) WriteMONOImage;
+ entry->adjoin=False;
+ entry->description="Bi-level bitmap in least-significant-byte first order";
+ entry->raw=True;
+ entry->module="MONO";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M O N O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMONOImage removes format registrations made by the
+% MONO module from the list of supported formats.
+%
+% The format of the UnregisterMONOImage method is:
+%
+% UnregisterMONOImage(void)
+%
+*/
+ModuleExport void UnregisterMONOImage(void)
+{
+ (void) UnregisterMagickInfo("MONO");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M O N O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMONOImage writes an image of raw bits in LSB order to a file.
+%
+% The format of the WriteMONOImage method is:
+%
+% unsigned int WriteMONOImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteMONOImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteMONOImage(const ImageInfo *image_info,Image *image)
+{
+ long
+ y;
+
+ register const IndexPacket
+ *indexes;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ unsigned char
+ bit,
+ byte,
+ polarity;
+
+ unsigned int
+ status;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Convert image to a bi-level image.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte>>=1;
+ if (indexes[x] == polarity)
+ byte|=0x80;
+ bit++;
+ if (bit == 8)
+ {
+ (void) WriteBlobByte(image,byte);
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ (void) WriteBlobByte(image,byte >> (8-bit));
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/mpc.c b/coders/mpc.c
new file mode 100644
index 0000000..a846198
--- /dev/null
+++ b/coders/mpc.c
@@ -0,0 +1,1366 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M PPPP CCCC %
+% MM MM P P C %
+% M M M PPPP C %
+% M M P C %
+% M M P CCCC %
+% %
+% %
+% Read/Write Magick Persistant Cache Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% March 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/enum_strings.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMPCImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M P C %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsMPC returns MagickTrue if the image format type, identified by the
+% magick string, is an Magick Persistent Cache image.
+%
+% The format of the IsMPC method is:
+%
+% unsigned int IsMPC(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsMPC returns MagickTrue if the image format type is MPC.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static MagickBool IsMPC(const unsigned char *magick,const size_t length)
+{
+ if (length < 14)
+ return(MagickFalse);
+ if (LocaleNCompare((char *) magick,"id=MagickCache",14) == 0)
+ return(MagickTrue);
+ return(MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d C A C H E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMPCImage reads an Magick Persistent Cache image file and returns
+% it. It allocates the memory necessary for the new Image structure and
+% returns a pointer to the new image.
+%
+% The format of the ReadMPCImage method is:
+%
+% Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% Decompression code contributed by Kyle Shorter.
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMPCImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+#define ThrowMPCReaderException(code_,reason_,image_) \
+do { \
+ if (number_of_profiles > 0) \
+ { \
+ unsigned int _index; \
+ for (_index=0; _index < number_of_profiles; _index++) \
+ { \
+ MagickFreeMemory(profiles[_index].name); \
+ MagickFreeMemory(profiles[_index].info); \
+ } \
+ MagickFreeMemory(profiles); \
+ number_of_profiles=0; \
+ } \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ cache_filename[MaxTextExtent],
+ id[MaxTextExtent],
+ keyword[MaxTextExtent];
+
+ ExtendedSignedIntegralType
+ offset;
+
+ Image
+ *image;
+
+ int
+ c;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ unsigned int
+ status;
+
+ unsigned long
+ quantum_depth;
+
+ ProfileInfo
+ *profiles=0;
+
+ unsigned int
+ number_of_profiles=0;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ /*
+ We must unset the grayscale and monochrome flags by default since
+ the MPC format does not necessarily update the pixel cache while
+ it is read.
+ */
+ image->is_grayscale=MagickFalse;
+ image->is_monochrome=MagickFalse;
+ /*
+ Open blob
+ */
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ (void) strlcpy(cache_filename,image->filename,MaxTextExtent);
+ AppendImageFormat("cache",cache_filename);
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ {
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ *id='\0';
+ offset=0;
+ do
+ {
+ /*
+ Decode image header; header terminates one character beyond a ':'.
+ */
+ quantum_depth=QuantumDepth;
+ image->depth=8;
+ image->compression=NoCompression;
+ image->storage_class=DirectClass;
+ while (isgraph(c) && (c != ':'))
+ {
+ register char
+ *p;
+
+ if (c == '{')
+ {
+ char
+ *comment;
+
+ size_t
+ comment_length;
+
+ /*
+ Read comment-- any text between { }.
+ */
+ comment_length=MaxTextExtent;
+ comment=MagickAllocateMemory(char *,comment_length);
+ if (comment == (char *) NULL)
+ ThrowMPCReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ p=comment;
+ for ( ; comment != (char *) NULL; p++)
+ {
+ c=ReadBlobByte(image);
+ if ((c == EOF) || (c == '}'))
+ break;
+ if ((size_t) (p-comment+1) >= comment_length)
+ {
+ *p='\0';
+ comment_length<<=1;
+ MagickReallocMemory(char *,comment,comment_length);
+ if (comment == (char *) NULL)
+ break;
+ p=comment+strlen(comment);
+ }
+ *p=c;
+ }
+ if (comment == (char *) NULL)
+ ThrowMPCReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ *p='\0';
+ (void) SetImageAttribute(image,"comment",comment);
+ MagickFreeMemory(comment);
+ c=ReadBlobByte(image);
+ }
+ else
+ if (isalnum(c))
+ {
+ char
+ *values;
+
+ size_t
+ values_length;
+
+ MagickBool
+ in_brace=MagickFalse;
+
+ /*
+ Get keyword.
+ */
+ keyword[0]='\0';
+ p=keyword;
+ do
+ {
+ if ((p-keyword) < (MaxTextExtent-1))
+ *p++=c;
+ c=ReadBlobByte(image);
+ } while ((c != '=') && (c != EOF));
+ *p='\0';
+ if (c == EOF)
+ ThrowMPCReaderException(CorruptImageWarning,ImproperImageHeader,image);
+
+ /*
+ Get values.
+
+ Values not containing spaces are terminated by the first
+ white-space (or new-line) enountered. Values containing
+ spaces and/or new-lines must be surrounded by braces.
+ */
+ values_length=MaxTextExtent;
+ values=MagickAllocateMemory(char *,values_length);
+ if (values == (char *) NULL)
+ ThrowMPCReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ values[0]='\0';
+ c=ReadBlobByte(image);
+ in_brace=(c == '{');
+ if (in_brace)
+ c=ReadBlobByte(image);
+ p=values;
+ while ((((!in_brace) && (c != '\n')) ||
+ ((in_brace) && (c != '}'))) &&
+ (c != EOF))
+ {
+ if ((size_t) (p-values+1) >= values_length)
+ {
+ *p='\0';
+ values_length<<=1;
+ MagickReallocMemory(char *,values,values_length);
+ if (values == (char *) NULL)
+ break;
+ p=values+strlen(values);
+ }
+ if (values == (char *) NULL)
+ ThrowMPCReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ *p++=c;
+ c=ReadBlobByte(image);
+ if (!in_brace)
+ if (isspace(c))
+ break;
+ }
+ *p='\0';
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "keyword=\"%s\" values=\"%s\"",keyword,values);
+ /*
+ Assign a value to the specified keyword.
+ */
+ switch (*keyword)
+ {
+ case 'b':
+ case 'B':
+ {
+ if (LocaleCompare(keyword,"background-color") == 0)
+ {
+ (void) QueryColorDatabase(values,&image->background_color,
+ exception);
+ break;
+ }
+ if (LocaleCompare(keyword,"blue-primary") == 0)
+ {
+ (void) sscanf(values,"%lf,%lf",
+ &image->chromaticity.blue_primary.x,
+ &image->chromaticity.blue_primary.y);
+ break;
+ }
+ if (LocaleCompare(keyword,"border-color") == 0)
+ {
+ (void) QueryColorDatabase(values,&image->border_color,
+ exception);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'c':
+ case 'C':
+ {
+ if (LocaleCompare(keyword,"class") == 0)
+ {
+ image->storage_class=UndefinedClass;
+ if (LocaleCompare(values,"PseudoClass") == 0)
+ image->storage_class=PseudoClass;
+ else
+ if (LocaleCompare(values,"DirectClass") == 0)
+ image->storage_class=DirectClass;
+ break;
+ }
+ if (LocaleCompare(keyword,"colors") == 0)
+ {
+ image->colors=MagickAtoL(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"colorspace") == 0)
+ {
+ image->colorspace=UndefinedColorspace;
+ if (LocaleCompare(values,"CMYK") == 0)
+ image->colorspace=CMYKColorspace;
+ else
+ if (LocaleCompare(values,"RGB") == 0)
+ image->colorspace=RGBColorspace;
+ break;
+ }
+ if (LocaleCompare(keyword,"compression") == 0)
+ {
+ CompressionType
+ compression;
+
+ compression=UndefinedCompression;
+ if (LocaleCompare("None",values) == 0)
+ compression=NoCompression;
+ if (LocaleCompare("BZip",values) == 0)
+ compression=BZipCompression;
+ if (LocaleCompare("Fax",values) == 0)
+ compression=FaxCompression;
+ if (LocaleCompare("Group4",values) == 0)
+ compression=Group4Compression;
+ if (LocaleCompare("JPEG",values) == 0)
+ compression=JPEGCompression;
+ if (LocaleCompare("Lossless",values) == 0)
+ compression=LosslessJPEGCompression;
+ if (LocaleCompare("LZW",values) == 0)
+ compression=LZWCompression;
+ if (LocaleCompare("RLE",values) == 0)
+ compression=RLECompression;
+ if (LocaleCompare("Zip",values) == 0)
+ compression=ZipCompression;
+ image->compression=compression;
+ break;
+ }
+ if (LocaleCompare(keyword,"columns") == 0)
+ {
+ image->columns= MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'd':
+ case 'D':
+ {
+ if (LocaleCompare(keyword,"delay") == 0)
+ {
+ image->delay=MagickAtoL(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"depth") == 0)
+ {
+ image->depth=MagickAtoL(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"dispose") == 0)
+ {
+ image->dispose=(DisposeType) MagickAtoL(values);
+ if (LocaleCompare(values,"Background") == 0)
+ image->dispose=BackgroundDispose;
+ else
+ if (LocaleCompare(values,"None") == 0)
+ image->dispose=NoneDispose;
+ else
+ if (LocaleCompare(values,"Previous") == 0)
+ image->dispose=PreviousDispose;
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'e':
+ case 'E':
+ {
+ if (LocaleCompare(keyword,"error") == 0)
+ {
+ image->error.mean_error_per_pixel=MagickAtoF(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'g':
+ case 'G':
+ {
+ if (LocaleCompare(keyword,"gamma") == 0)
+ {
+ image->gamma=MagickAtoF(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"grayscale") == 0)
+ {
+ if (LocaleCompare(values,"True") == 0)
+ image->is_grayscale=MagickTrue;
+ break;
+ }
+ if (LocaleCompare(keyword,"green-primary") == 0)
+ {
+ (void) sscanf(values,"%lf,%lf",
+ &image->chromaticity.green_primary.x,
+ &image->chromaticity.green_primary.y);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'i':
+ case 'I':
+ {
+ if (LocaleCompare(keyword,"id") == 0)
+ {
+ (void) strlcpy(id,values,MaxTextExtent);
+ break;
+ }
+ if (LocaleCompare(keyword,"iterations") == 0)
+ {
+ image->iterations=MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'm':
+ case 'M':
+ {
+ if (LocaleCompare(keyword,"matte") == 0)
+ {
+ image->matte=(LocaleCompare(values,"True") == 0) ||
+ (LocaleCompare(values,"true") == 0);
+ break;
+ }
+ if (LocaleCompare(keyword,"matte-color") == 0)
+ {
+ (void) QueryColorDatabase(values,&image->matte_color,
+ exception);
+ break;
+ }
+ if (LocaleCompare(keyword,"maximum-error") == 0)
+ {
+ image->error.normalized_maximum_error=MagickAtoF(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"mean-error") == 0)
+ {
+ image->error.normalized_mean_error=MagickAtoF(values);
+ break;
+ }
+ if (LocaleCompare(keyword,"monochrome") == 0)
+ {
+ if (LocaleCompare(values,"True") == 0)
+ image->is_monochrome=MagickTrue;
+ break;
+ }
+ if (LocaleCompare(keyword,"montage") == 0)
+ {
+ (void) CloneString(&image->montage,values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'o':
+ case 'O':
+ {
+ if (LocaleCompare(keyword,"opaque") == 0)
+ {
+ image->matte=(LocaleCompare(values,"True") == 0) ||
+ (LocaleCompare(values,"true") == 0);
+ break;
+ }
+ if (LocaleCompare(keyword,"orientation") == 0)
+ {
+ image->orientation=StringToOrientationType(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'p':
+ case 'P':
+ {
+ if (LocaleCompare(keyword,"page") == 0)
+ {
+ char
+ *geometry;
+
+ geometry=GetPageGeometry(values);
+ (void) GetGeometry(geometry,&image->page.x,&image->page.y,
+ &image->page.width,&image->page.height);
+ MagickFreeMemory(geometry);
+ break;
+ }
+ if (LocaleNCompare(keyword,"profile-",8) == 0)
+ {
+ i=(long) number_of_profiles;
+ MagickReallocMemory(ProfileInfo *,profiles,(i+1)*sizeof(ProfileInfo));
+ if (profiles == (ProfileInfo *) NULL)
+ {
+ MagickFreeMemory(values);
+ ThrowMPCReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ profiles[i].name=AllocateString(keyword+8);
+ profiles[i].length=MagickAtoL(values);
+ profiles[i].info=(unsigned char *) NULL;
+ number_of_profiles++;
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'q':
+ case 'Q':
+ {
+ if (LocaleCompare(keyword,"quantum-depth") == 0)
+ {
+ quantum_depth=MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'r':
+ case 'R':
+ {
+ if (LocaleCompare(keyword,"red-primary") == 0)
+ {
+ (void) sscanf(values,"%lf,%lf",
+ &image->chromaticity.red_primary.x,
+ &image->chromaticity.red_primary.y);
+ break;
+ }
+ if (LocaleCompare(keyword,"rendering-intent") == 0)
+ {
+ image->rendering_intent=UndefinedIntent;
+ if (LocaleCompare(values,"Saturation") == 0)
+ image->rendering_intent=SaturationIntent;
+ else
+ if (LocaleCompare(values,"perceptual") == 0)
+ image->rendering_intent=PerceptualIntent;
+ else
+ if (LocaleCompare(values,"absolute") == 0)
+ image->rendering_intent=AbsoluteIntent;
+ else
+ if (LocaleCompare(values,"relative") == 0)
+ image->rendering_intent=RelativeIntent;
+ break;
+ }
+ if (LocaleCompare(keyword,"resolution") == 0)
+ {
+ (void) GetMagickDimension(values,&image->x_resolution,
+ &image->y_resolution,NULL,NULL);
+ break;
+ }
+ if (LocaleCompare(keyword,"rows") == 0)
+ {
+ image->rows=MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 's':
+ case 'S':
+ {
+ if (LocaleCompare(keyword,"scene") == 0)
+ {
+ image->scene=MagickAtoL(values);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'u':
+ case 'U':
+ {
+ if (LocaleCompare(keyword,"units") == 0)
+ {
+ image->units=UndefinedResolution;
+ if (LocaleCompare(values,"pixels-per-inch") == 0)
+ image->units=PixelsPerInchResolution;
+ else
+ if (LocaleCompare(values,"pixels-per-centimeter") == 0)
+ image->units=PixelsPerCentimeterResolution;
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ case 'w':
+ case 'W':
+ {
+ if (LocaleCompare(keyword,"white-point") == 0)
+ {
+ (void) sscanf(values,"%lf,%lf",
+ &image->chromaticity.white_point.x,
+ &image->chromaticity.white_point.y);
+ break;
+ }
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ default:
+ {
+ (void) SetImageAttribute(image,keyword,
+ *values == '{' ? values+1 : values);
+ break;
+ }
+ }
+ MagickFreeMemory(values);
+ }
+ else
+ {
+ c=ReadBlobByte(image);
+ }
+ while (isspace(c))
+ c=ReadBlobByte(image);
+ }
+ (void) ReadBlobByte(image);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "id=\"%s\" class=%s compression=%s matte=%s "
+ "columns=%lu rows=%lu depth=%u",
+ id,ClassTypeToString(image->storage_class),
+ CompressionTypeToString(image->compression),
+ MagickBoolToString(image->matte),
+ image->columns, image->rows, image->depth);
+
+ /*
+ Verify that required image information is defined.
+ */
+ if ((LocaleCompare(id,"MagickCache") != 0) ||
+ (image->storage_class == UndefinedClass) ||
+ (image->compression == UndefinedCompression) || (image->columns == 0) ||
+ (image->rows == 0))
+ ThrowMPCReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (quantum_depth != QuantumDepth)
+ ThrowMPCReaderException(CacheError,InconsistentPersistentCacheDepth,image);
+ if (image->montage != (char *) NULL)
+ {
+ register char
+ *p;
+
+ /*
+ Image directory.
+ */
+ image->directory=AllocateString((char *) NULL);
+ if (image->directory == (char *) NULL)
+ ThrowMPCReaderException(CorruptImageError,UnableToReadImageData,image);
+ p=image->directory;
+ do
+ {
+ *p='\0';
+ if (((strlen(image->directory)+1) % MaxTextExtent) == 0)
+ {
+ /*
+ Allocate more memory for the image directory.
+ */
+ MagickReallocMemory(char *,image->directory,
+ (strlen(image->directory)+MaxTextExtent+1));
+ if (image->directory == (char *) NULL)
+ ThrowMPCReaderException(CorruptImageError,UnableToReadImageData,
+ image);
+ p=image->directory+strlen(image->directory);
+ }
+ c=ReadBlobByte(image);
+ *p++=c;
+ } while (c != '\0');
+ }
+
+ /*
+ Attached profiles.
+ */
+ if (number_of_profiles > 0)
+ {
+ for (i=0; i < (long) number_of_profiles; i++)
+ {
+ if (profiles[i].length == 0)
+ continue;
+ profiles[i].info=MagickAllocateMemory(unsigned char *,profiles[i].length);
+ if (profiles[i].info == (unsigned char *) NULL)
+ ThrowMPCReaderException(CorruptImageError,UnableToReadGenericProfile,
+ image);
+ (void) ReadBlob(image,profiles[i].length,profiles[i].info);
+ (void) SetImageProfile(image,profiles[i].name,profiles[i].info,
+ profiles[i].length);
+ MagickFreeMemory(profiles[i].name);
+ MagickFreeMemory(profiles[i].info);
+ }
+ MagickFreeMemory(profiles);
+ number_of_profiles=0;
+ }
+
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Create image colormap.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowMPCReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if (image->colors == 0)
+ for (i=0; i < 256; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(i);
+ image->colormap[i].green=ScaleCharToQuantum(i);
+ image->colormap[i].blue=ScaleCharToQuantum(i);
+ image->colors++;
+ }
+ else
+ {
+ unsigned char
+ *colormap;
+
+ unsigned int
+ packet_size;
+
+ /*
+ Read image colormap from file.
+ */
+ packet_size=image->depth > 8 ? 6 : 3;
+ colormap=MagickAllocateMemory(unsigned char *,packet_size*image->colors);
+ if (colormap == (unsigned char *) NULL)
+ ThrowMPCReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ (void) ReadBlob(image,packet_size*image->colors,colormap);
+ p=colormap;
+ if (image->depth <= 8)
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ }
+ else
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].red=(*p++ << 8);
+ image->colormap[i].red|=(*p++);
+ image->colormap[i].green=(*p++ << 8);
+ image->colormap[i].green|=(*p++);
+ image->colormap[i].blue=(*p++ << 8);
+ image->colormap[i].blue|=(*p++);
+ }
+ MagickFreeMemory(colormap);
+ }
+ }
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowMPCReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Attach persistent pixel cache.
+ */
+ status=PersistCache(image,cache_filename,MagickTrue,&offset,exception);
+ if (status == MagickFail)
+ ThrowMPCReaderException(CacheError,UnableToPeristPixelCache,image);
+ /*
+ Proceed to next image.
+ */
+ do
+ {
+ c=ReadBlobByte(image);
+ } while (!isgraph(c) && (c != EOF));
+ if (c != EOF)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename);
+ if (status == MagickFail)
+ break;
+ }
+ } while (c != EOF);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M P C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMPCImage adds attributes for the Cache image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMPCImage method is:
+%
+% RegisterMPCImage(void)
+%
+*/
+ModuleExport void RegisterMPCImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("CACHE");
+ entry->description="Magick Persistent Cache image format";
+ entry->module="CACHE";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("MPC");
+ entry->decoder=(DecoderHandler) ReadMPCImage;
+ entry->encoder=(EncoderHandler) WriteMPCImage;
+ entry->magick=(MagickHandler) IsMPC;
+ entry->description="Magick Persistent Cache image format";
+ entry->module="MPC";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M P C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMPCImage removes format registrations made by the
+% MPC module from the list of supported formats.
+%
+% The format of the UnregisterMPCImage method is:
+%
+% UnregisterMPCImage(void)
+%
+*/
+ModuleExport void UnregisterMPCImage(void)
+{
+ (void) UnregisterMagickInfo("CACHE");
+ (void) UnregisterMagickInfo("MPC");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M P C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMPCImage writes an Magick Persistent Cache image to a file.
+%
+% The format of the WriteMPCImage method is:
+%
+% MagickPassFail WriteMPCImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WriteMPCImage return MagickPass if the image is written.
+% MagickFail is returned if there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static MagickPassFail WriteMPCImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[MaxTextExtent],
+ cache_filename[MaxTextExtent];
+
+ const ImageAttribute
+ *attribute;
+
+ ExtendedSignedIntegralType
+ offset;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ unsigned long
+ scene;
+
+ ImageProfileIterator
+ profile_iterator;
+
+ const char
+ *profile_name;
+
+ const unsigned char
+ *profile_info;
+
+ size_t
+ profile_length;
+
+ /*
+ Open persistent cache.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) strlcpy(cache_filename,image->filename,MaxTextExtent);
+ AppendImageFormat("cache",cache_filename);
+ scene=0;
+ offset=0;
+ do
+ {
+ /*
+ Write persistent cache meta-information.
+ */
+ (void) WriteBlobString(image,"id=MagickCache\n");
+ FormatString(buffer,"quantum-depth=%d\n",QuantumDepth);
+ (void) WriteBlobString(image,buffer);
+ if (image->storage_class == PseudoClass)
+ FormatString(buffer,"class=PseudoClass colors=%u matte=%s\n",
+ image->colors,MagickBoolToString(image->matte));
+ else
+ if (image->colorspace == CMYKColorspace)
+ FormatString(buffer,"class=DirectClass colorspace=CMYK matte=%s\n",
+ MagickBoolToString(image->matte));
+ else
+ FormatString(buffer,"class=DirectClass matte=%s\n",
+ MagickBoolToString(image->matte));
+ (void) WriteBlobString(image,buffer);
+ switch (image->compression)
+ {
+ default:
+ case NoCompression:
+ {
+ (void) WriteBlobString(image,"compression=None\n");
+ break;
+ }
+ case BZipCompression:
+ {
+ (void) WriteBlobString(image,"compression=BZip\n");
+ break;
+ }
+ case FaxCompression:
+ {
+ (void) WriteBlobString(image,"compression=Fax\n");
+ break;
+ }
+ case Group4Compression:
+ {
+ (void) WriteBlobString(image,"compression=Group4\n");
+ break;
+ }
+ case JPEGCompression:
+ {
+ (void) WriteBlobString(image,"compression=JPEG\n");
+ break;
+ }
+ case LosslessJPEGCompression:
+ {
+ (void) WriteBlobString(image,"compression=Lossless\n");
+ break;
+ }
+ case LZWCompression:
+ {
+ (void) WriteBlobString(image,"compression=LZW\n");
+ break;
+ }
+ case RLECompression:
+ {
+ (void) WriteBlobString(image,"compression=RLE\n");
+ break;
+ }
+ case ZipCompression:
+ {
+ (void) WriteBlobString(image,"compression=Zip\n");
+ break;
+ }
+ }
+ FormatString(buffer,"columns=%lu rows=%lu depth=%u\n",image->columns,
+ image->rows,image->depth);
+ (void) WriteBlobString(image,buffer);
+ if (image->is_monochrome != MagickFalse)
+ {
+ FormatString(buffer,"monochrome=True\n");
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->is_grayscale != MagickFalse)
+ {
+ FormatString(buffer,"grayscale=True\n");
+ (void) WriteBlobString(image,buffer);
+ }
+ if ((image->x_resolution != 0) && (image->y_resolution != 0))
+ {
+ char
+ units[MaxTextExtent];
+
+ /*
+ Set image resolution.
+ */
+ (void) strcpy(units,"undefined");
+ if (image->units == PixelsPerInchResolution)
+ (void) strcpy(units,"pixels-per-inch");
+ if (image->units == PixelsPerCentimeterResolution)
+ (void) strcpy(units,"pixels-per-centimeter");
+ FormatString(buffer,"Resolution=%gx%g units=%.1024s\n",
+ image->x_resolution,image->y_resolution,units);
+ (void) WriteBlobString(image,buffer);
+ }
+ if ((image->page.width != 0) && (image->page.height != 0))
+ {
+ FormatString(buffer,"page=%lux%lu%+ld%+ld\n",image->page.width,
+ image->page.height,image->page.x,image->page.y);
+ (void) WriteBlobString(image,buffer);
+ }
+ if ((image->next != (Image *) NULL) || (image->previous != (Image *) NULL))
+ {
+ if (image->scene == 0)
+ FormatString(buffer,"iterations=%lu delay=%lu\n",image->iterations,
+ image->delay);
+ else
+ FormatString(buffer,"scene=%lu iterations=%lu delay=%lu\n",
+ image->scene,image->iterations,image->delay);
+ (void) WriteBlobString(image,buffer);
+ }
+ else
+ {
+ if (image->scene != 0)
+ {
+ FormatString(buffer,"scene=%lu\n",image->scene);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->iterations != 0)
+ {
+ FormatString(buffer,"iterations=%lu\n",image->iterations);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->delay != 0)
+ {
+ FormatString(buffer,"delay=%lu\n",image->delay);
+ (void) WriteBlobString(image,buffer);
+ }
+ }
+ if (image->dispose != UndefinedDispose)
+ {
+ if (image->dispose == BackgroundDispose)
+ (void) strcpy(buffer,"dispose=background\n");
+ else
+ if (image->dispose == NoneDispose)
+ (void) strcpy(buffer,"dispose=none\n");
+ else
+ (void) strcpy(buffer,"dispose=previous\n");
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->error.mean_error_per_pixel != 0.0)
+ {
+ FormatString(buffer,"error=%g mean-error=%g maximum-error=%g\n",
+ image->error.mean_error_per_pixel,image->error.normalized_mean_error,
+ image->error.normalized_maximum_error);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->rendering_intent != UndefinedIntent)
+ {
+ if (image->rendering_intent == SaturationIntent)
+ (void) WriteBlobString(image,"rendering-intent=saturation\n");
+ else
+ if (image->rendering_intent == PerceptualIntent)
+ (void) WriteBlobString(image,"rendering-intent=perceptual\n");
+ else
+ if (image->rendering_intent == AbsoluteIntent)
+ (void) WriteBlobString(image,"rendering-intent=absolute\n");
+ else
+ (void) WriteBlobString(image,"rendering-intent=relative\n");
+ }
+ if (image->gamma != 0.0)
+ {
+ FormatString(buffer,"gamma=%g\n",image->gamma);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->chromaticity.white_point.x != 0.0)
+ {
+ /*
+ Note chomaticity points.
+ */
+ FormatString(buffer,
+ "red-primary=%g,%g green-primary=%g,%g blue-primary=%g,%g\n",
+ image->chromaticity.red_primary.x,image->chromaticity.red_primary.y,
+ image->chromaticity.green_primary.x,
+ image->chromaticity.green_primary.y,
+ image->chromaticity.blue_primary.x,
+ image->chromaticity.blue_primary.y);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"white-point=%g,%g\n",
+ image->chromaticity.white_point.x,image->chromaticity.white_point.y);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (image->orientation != UndefinedOrientation)
+ {
+ FormatString(buffer,"orientation=%s\n",
+ OrientationTypeToString(image->orientation));
+ (void) WriteBlobString(image,buffer);
+ }
+ /*
+ Attached profiles.
+ */
+ profile_iterator=AllocateImageProfileIterator(image);
+ if (profile_iterator)
+ {
+ while(NextImageProfile(profile_iterator,&profile_name,&profile_info,
+ &profile_length)
+ != MagickFail)
+ {
+ FormatString(buffer,"profile-%.1024s=%lu\n",
+ profile_name == (char *) NULL ? "generic" :
+ profile_name,(unsigned long)
+ profile_length);
+ (void) WriteBlobString(image,buffer);
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+ }
+
+ if (image->montage != (char *) NULL)
+ {
+ FormatString(buffer,"montage=%.1024s\n",image->montage);
+ (void) WriteBlobString(image,buffer);
+ }
+ attribute=GetImageAttribute(image,(char *) NULL);
+ for ( ; attribute != (const ImageAttribute *) NULL; attribute=attribute->next)
+ {
+ if (attribute->value != NULL)
+ {
+ long
+ j;
+
+ FormatString(buffer,"%.1024s=",attribute->key);
+ (void) WriteBlobString(image,buffer);
+ for (j=0; j < (long) strlen(attribute->value); j++)
+ if (isspace((int) attribute->value[j]))
+ break;
+ if (j < (long) strlen(attribute->value))
+ (void) WriteBlobByte(image,'{');
+ (void) WriteBlobString(image,attribute->value);
+ if (j < (long) strlen(attribute->value))
+ (void) WriteBlobByte(image,'}');
+ (void) WriteBlobByte(image,'\n');
+ }
+ }
+ (void) WriteBlobString(image,"\f\n:\032");
+ if (image->montage != (char *) NULL)
+ {
+ /*
+ Write montage tile directory.
+ */
+ if (image->directory != (char *) NULL)
+ (void) WriteBlobString(image,image->directory);
+ (void) WriteBlobByte(image,'\0');
+ }
+
+ /*
+ Attached profiles.
+ */
+ profile_iterator=AllocateImageProfileIterator(image);
+ if (profile_iterator)
+ {
+ while(NextImageProfile(profile_iterator,&profile_name,&profile_info,
+ &profile_length) != MagickFail)
+ {
+ if (profile_length != 0)
+ (void) WriteBlob(image,profile_length,profile_info);
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+ }
+
+ if (image->storage_class == PseudoClass)
+ {
+ register unsigned char
+ *q;
+
+ unsigned char
+ *colormap;
+
+ unsigned int
+ packet_size;
+
+ /*
+ Allocate colormap.
+ */
+ packet_size=image->depth > 8 ? 6 : 3;
+ colormap=MagickAllocateMemory(unsigned char *,packet_size*image->colors);
+ if (colormap == (unsigned char *) NULL)
+ return(MagickFail);
+ /*
+ Write colormap to file.
+ */
+ q=colormap;
+ if (image->depth <= 8)
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=image->colormap[i].red;
+ *q++=image->colormap[i].green;
+ *q++=image->colormap[i].blue;
+ }
+#if QuantumDepth > 8
+ else
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=image->colormap[i].red >> 8;
+ *q++=image->colormap[i].red & 0xff;
+ *q++=image->colormap[i].green >> 8;
+ *q++=image->colormap[i].green & 0xff;
+ *q++=image->colormap[i].blue >> 8;
+ *q++=image->colormap[i].blue & 0xff;
+ }
+#endif /* QuantumDepth > 8 */
+
+ (void) WriteBlob(image,packet_size*image->colors,colormap);
+ MagickFreeMemory(colormap);
+ }
+ /*
+ Initialize persistent pixel cache.
+ */
+ status=PersistCache(image,cache_filename,MagickFalse,&offset,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(CacheError,UnableToPeristPixelCache,image);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(status);
+}
diff --git a/coders/mpeg.c b/coders/mpeg.c
new file mode 100644
index 0000000..470dad2
--- /dev/null
+++ b/coders/mpeg.c
@@ -0,0 +1,611 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M PPPP EEEEE GGGG %
+% MM MM P P E G %
+% M M M PPPP EEE G GG %
+% M M P E G G %
+% M M P EEEEE GGGG %
+% %
+% %
+% Write MPEG Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1999 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMPEGImage(const ImageInfo *image_info,Image *image);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M P E G %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsMPEG returns True if the image format type, identified by the
+% magick string, is MPEG.
+%
+% The format of the IsMPEG method is:
+%
+% unsigned int IsMPEG(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsMPEG returns True if the image format type is MPEG.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsMPEG(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (memcmp(magick,"\000\000\001\263",4) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M P E G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMPEGImage adds attributes for the MPEG image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMPEGImage method is:
+%
+% RegisterMPEGImage(void)
+%
+*/
+ModuleExport void RegisterMPEGImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("MPEG");
+ entry->encoder=(EncoderHandler) WriteMPEGImage;
+ entry->magick=(MagickHandler) IsMPEG;
+ entry->blob_support=False;
+ entry->description="MPEG Video Stream";
+ entry->module="MPEG";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("MPG");
+ entry->encoder=(EncoderHandler) WriteMPEGImage;
+ entry->magick=(MagickHandler) IsMPEG;
+ entry->blob_support=False;
+ entry->description="MPEG Video Stream";
+ entry->module="MPEG";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("M2V");
+ entry->encoder=(EncoderHandler) WriteMPEGImage;
+ entry->magick=(MagickHandler) IsMPEG;
+ entry->blob_support=False;
+ entry->description="MPEG Video Stream";
+ entry->module="MPEG";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M P E G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMPEGImage removes format registrations made by the
+% BIM module from the list of supported formats.
+%
+% The format of the UnregisterBIMImage method is:
+%
+% UnregisterMPEGImage(void)
+%
+*/
+ModuleExport void UnregisterMPEGImage(void)
+{
+ (void) UnregisterMagickInfo("MPEG");
+ (void) UnregisterMagickInfo("MPG");
+ (void) UnregisterMagickInfo("M2V");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M P E G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMPEGImage writes an image to a file in MPEG video stream format.
+% Lawrence Livermore National Laboratory (LLNL) contributed code to adjust
+% the MPEG parameters to correspond to the compression quality setting.
+%
+% The format of the WriteMPEGImage method is:
+%
+% unsigned int WriteMPEGImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteMPEGImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+#define ThrowMPEGWriterException(code_,reason_,image_) \
+{ \
+ if (clone_info) \
+ DestroyImageInfo(clone_info); \
+ ThrowWriterException(code_,reason_,image_); \
+}
+
+static unsigned int WriteMPEGParameterFiles(const ImageInfo *image_info,
+ Image *image)
+{
+ char
+ filename[MaxTextExtent];
+
+ double
+ q;
+
+ FILE
+ *file,
+ *parameter_file;
+
+ long
+ quant,
+ vertical_factor;
+
+ register Image
+ *p;
+
+ register long
+ i;
+
+ static int
+ q_matrix[]=
+ {
+ 8, 16, 19, 22, 26, 27, 29, 34,
+ 16, 16, 22, 24, 27, 29, 34, 37,
+ 19, 22, 26, 27, 29, 34, 34, 38,
+ 22, 22, 26, 27, 29, 34, 37, 40,
+ 22, 26, 27, 29, 32, 35, 40, 48,
+ 26, 27, 29, 32, 35, 40, 48, 58,
+ 26, 27, 29, 34, 38, 46, 56, 69,
+ 27, 29, 35, 38, 46, 56, 69, 83
+ };
+
+ unsigned int
+ mpeg;
+
+ unsigned long
+ count;
+
+ /*
+ Write parameter file (see mpeg2encode documentation for details).
+ */
+ file=fopen(image_info->unique,"w");
+ if (file == (FILE *) NULL)
+ return(False);
+ (void) fprintf(file,"MPEG\n"); /* comment */
+ (void) fprintf(file,"%.1024s.%%d\n",image->filename); /* source frame file */
+ (void) fprintf(file,"-\n"); /* reconstructed frame file */
+ if (image_info->quality == DefaultCompressionQuality)
+ (void) fprintf(file,"-\n"); /* default intra quant matrix */
+ else
+ {
+ /*
+ Write intra quant matrix file.
+ */
+ FormatString(filename,"%.1024s.iqm",image_info->unique);
+ (void) fprintf(file,"%s\n",filename);
+ parameter_file=fopen(filename,"w");
+ if (parameter_file == (FILE *) NULL)
+ {
+ (void) fclose(file);
+ file=(FILE *) NULL;
+ return(False);
+ }
+ if (image_info->quality < DefaultCompressionQuality)
+ {
+ q=Max((DefaultCompressionQuality-image_info->quality)/8.0,1.0);
+ for (i=0; i < 64; i++)
+ {
+ quant=(long) Min(Max(q*q_matrix[i]+0.5,1.0),255.0);
+ (void) fprintf(parameter_file," %ld",quant);
+ if ((i % 8) == 7)
+ (void) fprintf(parameter_file,"\n");
+ }
+ }
+ else
+ {
+ q=Max((image_info->quality-DefaultCompressionQuality)*2.0,1.0);
+ for (i=0; i < 64; i++)
+ {
+ quant=(long) Min(Max(q_matrix[i]/q,1.0),255.0);
+ (void) fprintf(parameter_file," %ld",quant);
+ if ((i % 8) == 7)
+ (void) fprintf(parameter_file,"\n");
+ }
+ }
+ (void) fclose(parameter_file);
+ parameter_file=(FILE *) NULL;
+ }
+ if (image_info->quality == DefaultCompressionQuality)
+ (void) fprintf(file,"-\n"); /* default non intra quant matrix */
+ else
+ {
+ /*
+ Write non intra quant matrix file.
+ */
+ FormatString(filename,"%.1024s.niq",image_info->unique);
+ (void) fprintf(file,"%s\n",filename);
+ parameter_file=fopen(filename,"w");
+ if (parameter_file == (FILE *) NULL)
+ {
+ (void) fclose(file);
+ file=(FILE *) NULL;
+ return(False);
+ }
+ q=Min(Max(66.0-(2*image_info->quality)/3.0,1.0),255);
+ for (i=0; i < 64; i++)
+ {
+ (void) fprintf(parameter_file," %d",(int) q);
+ if ((i % 8) == 7)
+ (void) fprintf(parameter_file,"\n");
+ }
+ (void) fclose(parameter_file);
+ parameter_file=(FILE *) NULL;
+ }
+ (void) fprintf(file,"%.1024s.log\n",image_info->unique); /* statistics log */
+ (void) fprintf(file,"1\n"); /* input picture file format */
+ count=0;
+ for (p=image; p != (Image *) NULL; p=p->next)
+ count+=Max((p->delay+1)/3,1);
+ (void) fprintf(file,"%lu\n",count); /* number of frames */
+ (void) fprintf(file,"0\n"); /* number of first frame */
+ (void) fprintf(file,"00:00:00:00\n"); /* timecode of first frame */
+ mpeg=LocaleCompare(image_info->magick,"M2V") != 0;
+ if (image_info->quality > 98)
+ (void) fprintf(file,"1\n");
+ else
+ (void) fprintf(file,"%d\n",mpeg ? 12 : 15);
+ if (image_info->quality > 98)
+ (void) fprintf(file,"1\n");
+ else
+ (void) fprintf(file,"3\n");
+ (void) fprintf(file,"%d\n",mpeg ? 1 : 0); /* ISO/IEC 11172-2 stream */
+ (void) fprintf(file,"0\n"); /* select frame picture coding */
+ (void) fprintf(file,"%lu\n",image->columns+(image->columns & 0x01 ? 1 : 0));
+ (void) fprintf(file,"%lu\n",image->rows+(image->rows & 0x01 ? 1 : 0));
+ (void) fprintf(file,"%d\n",mpeg ? 8 : 2); /* aspect ratio */
+ (void) fprintf(file,"%d\n",mpeg ? 3 : 5); /* frame rate code */
+ (void) fprintf(file,"%.1f\n",mpeg ? 1152000.0 : 5000000.0); /* bit rate */
+ (void) fprintf(file,"%d\n",mpeg ? 20 : 112); /* vbv buffer size */
+ (void) fprintf(file,"0\n"); /* low delay */
+ (void) fprintf(file,"%d\n",mpeg ? 1 : 0); /* constrained parameter */
+ (void) fprintf(file,"%d\n",mpeg ? 4 : 1); /* profile ID */
+ (void) fprintf(file,"%d\n",mpeg ? 8 : 4); /* level ID */
+ (void) fprintf(file,"%d\n",mpeg ? 1 : 0); /* progressive sequence */
+ vertical_factor=2;
+ if (image_info->sampling_factor != (char *) NULL)
+ {
+ long
+ count,
+ horizontal_factor;
+
+ horizontal_factor=2;
+ count=sscanf(image_info->sampling_factor,"%ldx%ld",&horizontal_factor,
+ &vertical_factor);
+ if (count != 2)
+ vertical_factor=horizontal_factor;
+ if (mpeg)
+ {
+ if ((horizontal_factor != 2) || (vertical_factor != 2))
+ {
+ (void) fclose(file);
+ file=(FILE *) NULL;
+ return(False);
+ }
+ }
+ else
+ if ((horizontal_factor != 2) ||
+ ((vertical_factor != 1) && (vertical_factor != 2)))
+ {
+ (void) fclose(file);
+ file=(FILE *) NULL;
+ return(False);
+ }
+ }
+ (void) fprintf(file,"%d\n",vertical_factor==2 ? 1 : 2); /* chroma format */
+ (void) fprintf(file,"%d\n",mpeg ? 1 : 2); /* video format */
+ (void) fprintf(file,"5\n"); /* color primaries */
+ (void) fprintf(file,"5\n"); /* transfer characteristics */
+ (void) fprintf(file,"%d\n",mpeg ? 5 : 4); /* matrix coefficients */
+ (void) fprintf(file,"%lu\n",image->columns+(image->columns & 0x01 ? 1 : 0));
+ (void) fprintf(file,"%lu\n",image->rows+(image->rows & 0x01 ? 1 : 0));
+ (void) fprintf(file,"0\n"); /* intra dc precision */
+ (void) fprintf(file,"%d\n",mpeg ? 0 : 1); /* top field */
+ (void) fprintf(file,"%d %d %d\n",mpeg ? 1 : 0,mpeg ? 1 : 0, mpeg ? 1 : 0);
+ (void) fprintf(file,"0 0 0\n"); /* concealment motion vector */
+ (void) fprintf(file,"%d %d %d\n",mpeg ? 0 : 1,mpeg ? 0 : 1,mpeg ? 0 : 1);
+ (void) fprintf(file,"%d 0 0\n",mpeg ? 0 : 1); /* intra vlc format */
+ (void) fprintf(file,"0 0 0\n"); /* alternate scan */
+ (void) fprintf(file,"0\n"); /* repeat first field */
+ (void) fprintf(file,"%d\n",mpeg ? 1 : 0); /* progressive frame */
+ (void) fprintf(file,"0\n"); /* intra slice refresh period */
+ (void) fprintf(file,"0\n"); /* reaction parameter */
+ (void) fprintf(file,"0\n"); /* initial average activity */
+ (void) fprintf(file,"0\n");
+ (void) fprintf(file,"0\n");
+ (void) fprintf(file,"0\n");
+ (void) fprintf(file,"0\n");
+ (void) fprintf(file,"0\n");
+ (void) fprintf(file,"0\n");
+ (void) fprintf(file,"2 2 11 11\n");
+ (void) fprintf(file,"1 1 3 3\n");
+ (void) fprintf(file,"1 1 7 7\n");
+ (void) fprintf(file,"1 1 7 7\n");
+ (void) fprintf(file,"1 1 3 3\n");
+ (void) fclose(file);
+ file=(FILE *) NULL;
+ return(True);
+}
+
+static unsigned int WriteMPEGImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ basename[MaxTextExtent],
+ filename[MaxTextExtent];
+
+ Image
+ *coalesce_image,
+ *next_image;
+
+ ImageInfo
+ *clone_info = (ImageInfo *) NULL;
+
+ register Image
+ *p;
+
+ register long
+ i;
+
+ size_t
+ length;
+
+ unsigned char
+ *blob;
+
+ unsigned int
+ logging,
+ status;
+
+ unsigned long
+ count,
+ scene;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowMPEGWriterException(FileOpenError,UnableToOpenFile,image);
+ CloseBlob(image);
+ /*
+ Determine if the sequence of images have identical page info.
+ */
+ coalesce_image=image;
+ for (next_image=image; next_image != (Image *) NULL; )
+ {
+ if ((image->columns != next_image->columns) ||
+ (image->rows != next_image->rows))
+ break;
+ if ((image->page.x != next_image->page.x) ||
+ (image->page.y != next_image->page.y))
+ break;
+ next_image=next_image->next;
+ }
+ if (next_image != (Image *) NULL)
+ {
+ coalesce_image=CoalesceImages(image,&image->exception);
+ if (coalesce_image == (Image *) NULL)
+ return(False);
+ }
+ /*
+ Write YUV files.
+ */
+ if(!AcquireTemporaryFileName(basename))
+ {
+ DestroyImage(coalesce_image);
+ ThrowWriterTemporaryFileException(basename);
+ }
+ FormatString(coalesce_image->filename,"%.1024s",basename);
+ clone_info=CloneImageInfo(image_info);
+ (void) strlcpy(clone_info->unique,basename,MaxTextExtent);
+ status=WriteMPEGParameterFiles(clone_info,coalesce_image);
+ if (status == False)
+ {
+ if (coalesce_image != image)
+ DestroyImage(coalesce_image);
+ (void) LiberateTemporaryFile(basename);
+ if (image_info->quality != DefaultCompressionQuality)
+ {
+ FormatString(filename,"%.1024s.iqm",basename);
+ (void) remove(filename);
+ FormatString(filename,"%.1024s.niq",basename);
+ (void) remove(filename);
+ }
+ ThrowMPEGWriterException(CoderError,UnableToWriteMPEGParameters,image);
+ }
+ count=0;
+ clone_info->interlace=PlaneInterlace;
+ for (p=coalesce_image; p != (Image *) NULL; p=p->next)
+ {
+ char
+ previous_image[MaxTextExtent];
+
+ blob=(unsigned char *) NULL;
+ length=0;
+ scene=p->scene;
+ for (i=0; i < (long) Max((p->delay+1)/3,1); i++)
+ {
+ p->scene=count;
+ count++;
+ status=False;
+ switch (i)
+ {
+ case 0:
+ {
+ Image
+ *frame;
+
+ FormatString(p->filename,"%.1024s.%lu.yuv",basename,p->scene);
+ FormatString(filename,"%.1024s.%lu.yuv",basename,p->scene);
+ FormatString(previous_image,"%.1024s.%lu.yuv",basename,p->scene);
+ frame=CloneImage(p,0,0,True,&p->exception);
+ if (frame == (Image *) NULL)
+ break;
+ status=WriteImage(clone_info,frame);
+ DestroyImage(frame);
+ break;
+ }
+ case 1:
+ {
+ blob=(unsigned char *)
+ FileToBlob(previous_image,&length,&image->exception);
+ FormatString(filename,"%.1024s.%lu.yuv",basename,p->scene);
+ if (length > 0)
+ status=BlobToFile(filename,blob,length,&image->exception);
+ break;
+ }
+ default:
+ {
+ FormatString(filename,"%.1024s.%lu.yuv",basename,p->scene);
+ if (length > 0)
+ status=BlobToFile(filename,blob,length,&image->exception);
+ break;
+ }
+ }
+ if (logging)
+ {
+ if (status)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%lu. Wrote YUV file for scene %lu:",i,p->scene);
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%lu. Failed to write YUV file for scene %lu:",i,p->scene);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%.1024s",
+ filename);
+ }
+ }
+ p->scene=scene;
+ if (blob != (unsigned char *) NULL)
+ MagickFreeMemory(blob);
+ if (status == False)
+ break;
+ }
+ /*
+ Convert YUV to MPEG.
+ */
+ (void) strlcpy(coalesce_image->filename,clone_info->unique,MaxTextExtent);
+ status=InvokeDelegate(clone_info,coalesce_image,(char *) NULL,"mpeg-encode",
+ &image->exception);
+ DestroyImageInfo(clone_info);
+ /*
+ Free resources.
+ */
+ count=0;
+ for (p=coalesce_image; p != (Image *) NULL; p=p->next)
+ {
+ for (i=0; i < (long) Max((p->delay+1)/3,1); i++)
+ {
+ FormatString(p->filename,"%.1024s.%lu.yuv",basename,count++);
+ (void) remove(p->filename);
+ }
+ (void) strlcpy(p->filename,image_info->filename,MaxTextExtent);
+ }
+ FormatString(filename,"%.1024s.iqm",basename);
+ (void) remove(filename);
+ FormatString(filename,"%.1024s.niq",basename);
+ (void) remove(filename);
+ FormatString(filename,"%.1024s.log",basename);
+ (void) remove(filename);
+ (void) LiberateTemporaryFile(basename);
+ if (coalesce_image != image)
+ DestroyImage(coalesce_image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit");
+ return(status);
+}
diff --git a/coders/mpr.c b/coders/mpr.c
new file mode 100644
index 0000000..5e15fe3
--- /dev/null
+++ b/coders/mpr.c
@@ -0,0 +1,239 @@
+/*
+% Copyright (C) 2003-2010 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M PPPP RRRR %
+% MM MM P P R R %
+% M M M PPPP RRRR %
+% M M P R R %
+% M M P R R %
+% %
+% %
+% Read/Write the Magick Persistent Registry. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/magick.h"
+#include "magick/registry.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMPRImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M P R I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMPRImage reads a Magick Persistent Registry image as a blob from
+% memory. It allocates the memory necessary for the new Image structure and
+% returns a pointer to the new image.
+%
+% The format of the ReadMPRImage method is:
+%
+% Image *ReadMPRImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMPRImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadMPRImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ char
+ *p;
+
+ long
+ id;
+
+ RegistryType
+ type;
+
+ size_t
+ length;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if (LocaleCompare(image_info->magick,"MPRI") != 0)
+ return(GetImageFromMagickRegistry(image_info->filename,&id,exception));
+ id=strtol(image_info->filename,&p,0);
+ return((Image *) GetMagickRegistry(id,&type,&length,exception));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M P R I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMPRImage adds attributes for the MPR image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMPRImage method is:
+%
+% RegisterMPRImage(void)
+%
+*/
+ModuleExport void RegisterMPRImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("MPR");
+ entry->decoder=(DecoderHandler) ReadMPRImage;
+ entry->encoder=(EncoderHandler) WriteMPRImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Magick Persistent Registry";
+ entry->module="MPR";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("MPRI");
+ entry->decoder=(DecoderHandler) ReadMPRImage;
+ entry->encoder=(EncoderHandler) WriteMPRImage;
+ entry->stealth=True;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="Magick Persistent Registry";
+ entry->module="MPRI";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M P R I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMPRImage removes format registrations made by the
+% MPR module from the list of supported formats.
+%
+% The format of the UnregisterMPRImage method is:
+%
+% UnregisterMPRImage(void)
+%
+*/
+ModuleExport void UnregisterMPRImage(void)
+{
+ (void) UnregisterMagickInfo("MPR");
+ (void) UnregisterMagickInfo("MPRI");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M P R I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteMPRImage() writes an image into the Magick Persistent Registry
+% image as a blob from memory. It allocates the memory necessary for the
+% new Image structure and returns a pointer to the new image.
+%
+% The format of the WriteMPRImage method is:
+%
+% unsigned int WriteMPRImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePRImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteMPRImage(const ImageInfo *image_info,Image *image)
+{
+ ExceptionInfo
+ exception;
+
+ Image
+ *registry_image;
+
+ long
+ id;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ GetExceptionInfo(&exception);
+ registry_image=GetImageFromMagickRegistry(image->filename,&id,&exception);
+ DestroyExceptionInfo(&exception);
+ if (registry_image != (Image *) NULL)
+ {
+ (void) DeleteMagickRegistry(id);
+ DestroyImage(registry_image);
+ }
+ id=SetMagickRegistry(ImageRegistryType,image,sizeof(Image),&image->exception);
+ return(id >= 0);
+}
diff --git a/coders/msl.c b/coders/msl.c
new file mode 100644
index 0000000..2c35b7c
--- /dev/null
+++ b/coders/msl.c
@@ -0,0 +1,4792 @@
+/*
+% Copyright (C) 2003 - 2017 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M SSSSS L %
+% MM MM SS L %
+% M M M SSS L %
+% M M SS L %
+% M M SSSSS LLLLL %
+% %
+% %
+% Execute Magick Scripting Language Scripts. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% Leonard Rosenthol %
+% William Radcliffe %
+% December 2001 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#if defined(HasXML)
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/pixel_cache.h"
+#include "magick/composite.h"
+#include "magick/constitute.h"
+#include "magick/decorate.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/enum_strings.h"
+#include "magick/fx.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/paint.h"
+#include "magick/profile.h"
+#include "magick/render.h"
+#include "magick/resize.h"
+#include "magick/shear.h"
+#include "magick/texture.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#if defined(MSWINDOWS)
+# if defined(__MINGW32__)
+# define _MSC_VER
+# else
+# include <win32config.h>
+# endif
+#endif
+#include <libxml/parser.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlerror.h>
+
+/*
+ Avoid shadowing library globals and functions.
+*/
+#define attribute attribute_magick
+
+/*
+ Typedef declaractions.
+*/
+typedef struct _MSLGroupInfo
+{
+ unsigned long
+ numImages; /* how many images are in this group */
+} MSLGroupInfo;
+
+typedef struct _MSLInfo
+{
+ ExceptionInfo
+ *exception;
+
+ long
+ n,
+ nGroups;
+
+ ImageInfo
+ **image_info;
+
+ DrawInfo
+ **draw_info;
+
+ Image
+ **attributes,
+ **image;
+
+ MSLGroupInfo
+ *group_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ xmlDocPtr
+ document;
+} MSLInfo;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMSLImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M S L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMSLImage reads a Magick Scripting Language file and returns it.
+% It allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadMSLImage method is:
+%
+% Image *ReadMSLImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMSLImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+/* extern "C" { */
+#endif
+
+static int
+MSLIsStandalone(void *context)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ Is this document tagged standalone?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.MSLIsStandalone()");
+ msl_info=(MSLInfo *) context;
+ return(msl_info->document->standalone == 1);
+}
+
+static int
+MSLHasInternalSubset(void *context)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ Does this document has an internal subset?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.MSLHasInternalSubset()");
+ msl_info=(MSLInfo *) context;
+ return(msl_info->document->intSubset != NULL);
+}
+
+static int
+MSLHasExternalSubset(void *context)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ Does this document has an external subset?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.MSLHasExternalSubset()");
+ msl_info=(MSLInfo *) context;
+ return(msl_info->document->extSubset != NULL);
+}
+
+static void
+MSLInternalSubset(void *context,const xmlChar *name,
+ const xmlChar *external_id,const xmlChar *system_id)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ Does this document has an internal subset?
+ */
+ (void) LogMagickEvent
+ (CoderEvent,GetMagickModule(),
+ " SAX.internalSubset(%.1024s %.1024s %.1024s)",
+ name,
+ (external_id != (const xmlChar *) NULL ? (char *) external_id : " "),
+ (system_id != (const xmlChar *) NULL ? (char *) system_id : " "));
+ msl_info=(MSLInfo *) context;
+ (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
+}
+
+static xmlParserInputPtr
+MSLResolveEntity(void *context,const xmlChar *public_id,
+ const xmlChar *system_id)
+{
+ MSLInfo
+ *msl_info;
+
+ xmlParserInputPtr
+ stream;
+
+ /*
+ Special entity resolver, better left to the parser, it has more
+ context than the application layer. The default behaviour is to
+ not resolve the entities, in that case the ENTITY_REF nodes are
+ built in the structure (and the parameter values).
+ */
+ (void) LogMagickEvent
+ (CoderEvent,GetMagickModule(),
+ " SAX.resolveEntity(%.1024s, %.1024s)",
+ (public_id != (const xmlChar *) NULL ? (char *) public_id : "none"),
+ (system_id != (const xmlChar *) NULL ? (char *) system_id : "none"));
+ msl_info=(MSLInfo *) context;
+ stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
+ public_id,msl_info->parser);
+ return(stream);
+}
+
+static xmlEntityPtr
+MSLGetEntity(void *context,const xmlChar *name)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ Get an entity by name.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.MSLGetEntity(%.1024s)",(char *) name);
+ msl_info=(MSLInfo *) context;
+ return(xmlGetDocEntity(msl_info->document,name));
+}
+
+static xmlEntityPtr
+MSLGetParameterEntity(void *context,const xmlChar *name)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ Get a parameter entity by name.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.getParameterEntity(%.1024s)",(char *) name);
+ msl_info=(MSLInfo *) context;
+ return(xmlGetParameterEntity(msl_info->document,name));
+}
+
+static void
+MSLEntityDeclaration(void *context,const xmlChar *name,int type,
+ const xmlChar *public_id,const xmlChar *system_id,
+ xmlChar *content)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ An entity definition has been parsed.
+ */
+ (void) LogMagickEvent
+ (CoderEvent,GetMagickModule(),
+ " SAX.entityDecl(%.1024s, %d, %.1024s, %.1024s, %.1024s)",
+ name,type,
+ public_id != (const xmlChar *) NULL ? (char *) public_id : "none",
+ system_id != (const xmlChar *) NULL ?(char *) system_id : "none",content);
+ msl_info=(MSLInfo *) context;
+ if (msl_info->parser->inSubset == 1)
+ (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
+ content);
+ else
+ if (msl_info->parser->inSubset == 2)
+ (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
+ content);
+}
+
+static void
+MSLAttributeDeclaration(void *context,const xmlChar *element,
+ const xmlChar *name,int type,
+ int value,const xmlChar *default_value,
+ xmlEnumerationPtr tree)
+{
+ MSLInfo
+ *msl_info;
+
+ xmlChar
+ *fullname,
+ *prefix;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ An attribute definition has been parsed.
+ */
+ (void) LogMagickEvent
+ (CoderEvent,GetMagickModule(),
+ " SAX.attributeDecl(%.1024s, %.1024s, %d, %d, %.1024s, ...)\n",
+ element,
+ name,type,value,default_value);
+ msl_info=(MSLInfo *) context;
+ fullname=(xmlChar *) NULL;
+ prefix=(xmlChar *) NULL;
+ parser=msl_info->parser;
+ fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
+ if (parser->inSubset == 1)
+ (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
+ element,fullname,prefix,(xmlAttributeType) type,
+ (xmlAttributeDefault) value,default_value,tree);
+ else
+ if (parser->inSubset == 2)
+ (void) xmlAddAttributeDecl(&parser->vctxt,
+ msl_info->document->extSubset,
+ element,fullname,prefix,
+ (xmlAttributeType) type,
+ (xmlAttributeDefault) value,
+ default_value,tree);
+ if (prefix != (xmlChar *) NULL)
+ xmlFree(prefix);
+ if (fullname != (xmlChar *) NULL)
+ xmlFree(fullname);
+}
+
+static void
+MSLElementDeclaration(void *context,const xmlChar *name,int type,
+ xmlElementContentPtr content)
+{
+ MSLInfo
+ *msl_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ An element definition has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.elementDecl(%.1024s, %d, ...)",name,type);
+ msl_info=(MSLInfo *) context;
+ parser=msl_info->parser;
+ if (parser->inSubset == 1)
+ (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
+ name,(xmlElementTypeVal) type,content);
+ else
+ if (parser->inSubset == 2)
+ (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
+ name,(xmlElementTypeVal) type,content);
+}
+
+static void
+MSLNotationDeclaration(void *context,const xmlChar *name,
+ const xmlChar *public_id,
+ const xmlChar *system_id)
+{
+ MSLInfo
+ *msl_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ What to do when a notation declaration has been parsed.
+ */
+ (void) LogMagickEvent
+ (CoderEvent,GetMagickModule(),
+ " SAX.notationDecl(%.1024s, %.1024s, %.1024s)",name,
+ public_id != (const xmlChar *) NULL ? (char *) public_id : "none",
+ system_id != (const xmlChar *) NULL ? (char *) system_id : "none");
+ msl_info=(MSLInfo *) context;
+ parser=msl_info->parser;
+ if (parser->inSubset == 1)
+ (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
+ name,public_id,system_id);
+ else
+ if (parser->inSubset == 2)
+ (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
+ name,public_id,system_id);
+}
+
+static void
+MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
+ const xmlChar *public_id,
+ const xmlChar *system_id,
+ const xmlChar *notation)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ What to do when an unparsed entity declaration is parsed.
+ */
+ (void) LogMagickEvent
+ (CoderEvent,GetMagickModule(),
+ " SAX.unparsedEntityDecl(%.1024s, %.1024s, %.1024s, %.1024s)",name,
+ public_id != (const xmlChar *) NULL ? (char *) public_id : "none",
+ system_id != (const xmlChar *) NULL ? (char *) system_id : "none",
+ notation);
+ msl_info=(MSLInfo *) context;
+ (void) xmlAddDocEntity(msl_info->document,name,
+ XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
+ public_id,system_id,notation);
+
+}
+
+static void
+MSLSetDocumentLocator(void *context,
+ xmlSAXLocatorPtr location)
+{
+ /* MSLInfo */
+ /* *msl_info; */
+
+ ARG_NOT_USED(context);
+ ARG_NOT_USED(location);
+ /*
+ Receive the document locator at startup, actually xmlDefaultSAXLocator.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.setDocumentLocator()\n");
+ /* msl_info=(MSLInfo *) context; */
+}
+
+static void
+MSLStartDocument(void *context)
+{
+ MSLInfo
+ *msl_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ Called when the document start being processed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.startDocument()");
+ msl_info=(MSLInfo *) context;
+ parser=msl_info->parser;
+ msl_info->document=xmlNewDoc(parser->version);
+ if (msl_info->document == (xmlDocPtr) NULL)
+ return;
+ if (parser->encoding == NULL)
+ msl_info->document->encoding=NULL;
+ else
+ msl_info->document->encoding=xmlStrdup(parser->encoding);
+ msl_info->document->standalone=parser->standalone;
+}
+
+static void
+MSLEndDocument(void *context)
+{
+ /* MSLInfo */
+ /* *msl_info; */
+
+ ARG_NOT_USED(context);
+ /*
+ Called when the document end has been detected.
+ */
+ /* msl_info=(MSLInfo *) context; */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
+}
+
+static void
+MSLPushImage(MSLInfo *msl_info,Image *image)
+{
+ const ImageAttribute
+ *attribute;
+
+ long
+ n;
+
+ assert(msl_info != (MSLInfo *) NULL);
+ msl_info->n++;
+ n=msl_info->n;
+ MagickReallocMemory(ImageInfo **,msl_info->image_info,
+ (n+1)*sizeof(ImageInfo *));
+ MagickReallocMemory(DrawInfo **,msl_info->draw_info,
+ (n+1)*sizeof(DrawInfo *));
+ MagickReallocMemory(Image **,msl_info->attributes,(n+1)*sizeof(Image *));
+ MagickReallocMemory(Image **,msl_info->image,(n+1)*sizeof(Image *));
+ if ((msl_info->image_info == (ImageInfo **) NULL) ||
+ (msl_info->draw_info == (DrawInfo **) NULL) ||
+ (msl_info->attributes == (Image **) NULL) ||
+ (msl_info->image == (Image **) NULL))
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,UnableToAllocateImage);
+ msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
+ msl_info->draw_info[n]=
+ CloneDrawInfo(msl_info->image_info[n-1], msl_info->draw_info[n-1]);
+ msl_info->attributes[n]=AllocateImage(msl_info->image_info[n]);
+ msl_info->image[n]=(Image *) image;
+ if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
+ (msl_info->attributes[n] == (Image *) NULL))
+ ThrowException3(msl_info->exception,ResourceLimitFatalError,
+ MemoryAllocationFailed,UnableToAllocateImage);
+ if ( msl_info->nGroups )
+ msl_info->group_info[msl_info->nGroups-1].numImages++;
+ attribute=GetImageAttribute(msl_info->attributes[n-1],(char *) NULL);
+ while (attribute != (const ImageAttribute *) NULL)
+ {
+ (void) SetImageAttribute(msl_info->attributes[n],attribute->key,NULL);
+ (void) SetImageAttribute(msl_info->attributes[n],attribute->key,
+ attribute->value);
+ attribute=attribute->next;
+ }
+}
+
+static void
+MSLPopImage(MSLInfo *msl_info)
+{
+ /*
+ only dispose of images when they aren't in a group
+ */
+ if ( (msl_info->nGroups == 0) && (msl_info->n > 0) )
+ {
+ if (msl_info->image[msl_info->n] != (Image *) NULL)
+ {
+ DestroyImage(msl_info->image[msl_info->n]);
+ msl_info->image[msl_info->n]=(Image *) NULL;
+ }
+
+ DestroyDrawInfo(msl_info->draw_info[msl_info->n]);
+ msl_info->draw_info[msl_info->n]=(DrawInfo *) NULL;
+
+ DestroyImage(msl_info->attributes[msl_info->n]);
+ msl_info->attributes[msl_info->n]=(Image *) NULL;
+
+ DestroyImageInfo(msl_info->image_info[msl_info->n]);
+ msl_info->image_info[msl_info->n]=(ImageInfo *) NULL;
+ msl_info->n--;
+ }
+}
+
+static void
+MSLStartElement(void *context,const xmlChar *name,
+ const xmlChar **attributes)
+{
+ char
+ key[MaxTextExtent],
+ *value = NULL;
+
+ const char
+ *keyword;
+
+ ExceptionInfo
+ exception;
+
+ long
+ n,
+ x,
+ y;
+
+ MSLInfo
+ *msl_info;
+
+ register long
+ i, j;
+
+ unsigned long
+ height,
+ width;
+
+ /*
+ Called when an opening tag has been processed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.startElement(%.1024s",name);
+ GetExceptionInfo(&exception);
+ msl_info=(MSLInfo *) context;
+ n=msl_info->n;
+ keyword=(const char *) NULL;
+ switch (*name)
+ {
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare((char *) name, "blur") == 0)
+ {
+ double radius = 0.0,
+ sigma = 1.0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,NoImagesDefined,
+ (char *) name);
+ break;
+ }
+ if (attributes != (const xmlChar **) NULL)
+ {
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword, "radius") == 0)
+ {
+ radius = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"sigma") == 0)
+ {
+ sigma = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ }
+
+ /*
+ blur image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=BlurImage(msl_info->image[n],radius,sigma,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name,"border") == 0)
+ {
+ /* init the values */
+ width = height = 6; /* this is the value that Magick++ uses */
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,NoImagesDefined,
+ (char *) name);
+ break;
+ }
+ if (attributes != (const xmlChar **) NULL)
+ {
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'F':
+ case'f':
+ {
+ if (LocaleCompare(keyword, "fill") == 0)
+ {
+ (void) QueryColorDatabase
+ (value,
+ &msl_info->image[n]->border_color,
+ &exception);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,
+ &width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ height = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ width = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ }
+
+ /*
+ border image.
+ */
+ {
+ Image
+ *border_image;
+ RectangleInfo
+ rectInfo;
+
+ rectInfo.height = height;
+ rectInfo.width = width;
+ rectInfo.x = x;
+ rectInfo.y = y;
+
+ border_image=BorderImage(msl_info->image[n],&rectInfo,
+ &msl_info->image[n]->exception);
+ if (border_image == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=border_image;
+ }
+
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare((char *) name, "charcoal") == 0)
+ {
+ double radius = 0.0,
+ sigma = 1.0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes != (const xmlChar **) NULL)
+ {
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword, "radius") == 0)
+ {
+ radius = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"sigma") == 0)
+ {
+ sigma = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ }
+
+ /*
+ charcoal image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=CharcoalImage(msl_info->image[n],radius,sigma,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name,"chop") == 0)
+ {
+ /* init the values */
+ width=msl_info->image[n]->columns;
+ height=msl_info->image[n]->rows;
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,&width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ height = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ width = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(keyword,"x") == 0)
+ {
+ x = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(keyword,"y") == 0)
+ {
+ y = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+ RectangleInfo
+ rectInfo;
+
+ rectInfo.height = height;
+ rectInfo.width = width;
+ rectInfo.x = x;
+ rectInfo.y = y;
+
+ newImage=ChopImage(msl_info->image[n],&rectInfo,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ else if (LocaleCompare((char *) name, "composite") == 0 )
+ {
+ Image *
+ srcImage = (Image*)NULL;
+ CompositeOperator
+ compositeOp = OverCompositeOp;
+ GravityType
+ gravity = CenterGravity;
+
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(keyword, "compose") == 0)
+ {
+ compositeOp = StringToCompositeOperator(value);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,&width,&height);
+ gravity=ForgetGravity;
+ break;
+ }
+ else if (LocaleCompare(keyword,"gravity") == 0)
+ {
+ gravity = StringToGravityType(value);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare(keyword,"image") == 0)
+ {
+ for (j=0; j<msl_info->n;j++)
+ {
+ const ImageAttribute *
+ theAttr =
+ GetImageAttribute(msl_info->attributes[j],
+ "id");
+ if (theAttr &&
+ LocaleCompare(theAttr->value, value) == 0)
+ {
+ srcImage = msl_info->image[j];
+ break;
+ }
+ }
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(keyword,"x") == 0)
+ {
+ x = MagickAtoI( value );
+ gravity=ForgetGravity;
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(keyword,"y") == 0)
+ {
+ y = MagickAtoI( value );
+ gravity=ForgetGravity;
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ if (srcImage != (Image*)NULL)
+ {
+ switch (gravity)
+ {
+ case ForgetGravity:
+ {
+ /* do nothing, since we alreay have explicit x,y */
+ break;
+ }
+ case NorthWestGravity:
+ {
+ x = 0;
+ y = 0;
+ break;
+ }
+ case NorthGravity:
+ {
+ x =(long) ((msl_info->image[n]->columns-
+ srcImage->columns) >> 1);
+ y = 0;
+ break;
+ }
+ case NorthEastGravity:
+ {
+ x = (long) (msl_info->image[n]->columns -
+ srcImage->columns);
+ y = 0;
+ break;
+ }
+ case WestGravity:
+ {
+ x = 0;
+ y = (long) ((msl_info->image[n]->rows -
+ srcImage->rows) >> 1);
+ break;
+ }
+ case CenterGravity:
+ default:
+ {
+ x =(long) ((msl_info->image[n]->columns-
+ srcImage->columns) >> 1);
+ y = (long) ((msl_info->image[n]->rows -
+ srcImage->rows) >> 1);
+ break;
+ }
+ case EastGravity:
+ {
+ x = (long) (msl_info->image[n]->columns -
+ srcImage->columns);
+ y = (long) ((msl_info->image[n]->rows -
+ srcImage->rows) >> 1);
+ break;
+ }
+ case SouthWestGravity:
+ {
+ x = 0;
+ y = (long) (msl_info->image[n]->rows -
+ srcImage->rows);
+ break;
+ }
+ case SouthGravity:
+ {
+ x =(long) ((msl_info->image[n]->columns -
+ srcImage->columns) >> 1);
+ y = (long) (msl_info->image[n]->rows -
+ srcImage->rows);
+ break;
+ }
+ case SouthEastGravity:
+ {
+ x = (long) (msl_info->image[n]->columns -
+ srcImage->columns);
+ y = (long) (msl_info->image[n]->rows -
+ srcImage->rows);
+ break;
+ }
+ }
+
+ (void) CompositeImage(msl_info->image[n], compositeOp,
+ srcImage, x, y);
+ break;
+ } else
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+
+ break;
+ }
+ else if (LocaleCompare((char *) name,"crop") == 0)
+ {
+ /* init the values */
+ width=msl_info->image[n]->columns;
+ height=msl_info->image[n]->rows;
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,&width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ height = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ width = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(keyword,"x") == 0)
+ {
+ x = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(keyword,"y") == 0)
+ {
+ y = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+ RectangleInfo
+ rectInfo;
+
+ rectInfo.height = height;
+ rectInfo.width = width;
+ rectInfo.x = x;
+ rectInfo.y = y;
+
+ newImage=CropImage(msl_info->image[n],&rectInfo,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare((char *) name, "despeckle") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ Image
+ *newImage;
+
+ newImage=DespeckleImage(msl_info->image[n],
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'E':
+ case 'e':
+ {
+ if (LocaleCompare((char *) name, "edge") == 0)
+ {
+ double radius = 0.0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes != (const xmlChar **) NULL)
+ {
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword, "radius") == 0)
+ {
+ radius = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ }
+
+ /*
+ edge image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=EdgeImage(msl_info->image[n],radius,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name, "emboss") == 0)
+ {
+ double radius = 0.0,
+ sigma = 1.0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes != (const xmlChar **) NULL)
+ {
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword, "radius") == 0)
+ {
+ radius = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"sigma") == 0)
+ {
+ sigma = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ }
+
+ /*
+ emboss image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=EmbossImage(msl_info->image[n],radius,sigma,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name, "enhance") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ Image
+ *newImage;
+
+ newImage=EnhanceImage(msl_info->image[n],
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name, "equalize") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ /* why doesn't this take an exception or return the
+ changed image */
+ (void) EqualizeImage(msl_info->image[n]);
+ break;
+ }
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare((char *) name, "flatten") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ Image
+ *newImage;
+
+ newImage=FlattenImages(msl_info->image[n],
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name, "flip") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ Image
+ *newImage;
+
+ newImage=FlipImage(msl_info->image[n],
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name, "flop") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ Image
+ *newImage;
+
+ newImage=FlopImage(msl_info->image[n],
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name,"frame") == 0)
+ {
+ /* init the values */
+ width = height = 25; /* these are the values that Magick++ uses */
+ x = y = 6;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes != (const xmlChar **) NULL)
+ {
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(keyword, "fill") == 0)
+ {
+ (void) QueryColorDatabase
+ (value,
+ &msl_info->image[n]->matte_color,
+ &exception);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,
+ &width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ height = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare(keyword,"inner") == 0)
+ {
+ y = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare(keyword,"outer") == 0)
+ {
+ x = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ width = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(keyword,"x") == 0)
+ {
+ x = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(keyword,"y") == 0)
+ {
+ y = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ }
+
+ /*
+ frame image.
+ */
+ {
+ Image
+ *newImage;
+ FrameInfo
+ frameInfo;
+
+ frameInfo.x = (long) width;
+ frameInfo.y = (long) height;
+ frameInfo.width = msl_info->image[n]->columns +
+ ( frameInfo.x << 1 );
+ frameInfo.height = msl_info->image[n]->rows +
+ ( frameInfo.y << 1 );
+ frameInfo.outer_bevel = x;
+ frameInfo.inner_bevel = y;
+
+ newImage=FrameImage(msl_info->image[n],&frameInfo,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare((char *) name, "gamma") == 0)
+ {
+ double
+ gammaRed = 0, gammaGreen = 0, gammaBlue = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ (void) CloneString(&value,(char *) attributes[i]);
+ (void) strlcpy(key,value,MaxTextExtent);
+ switch (*keyword)
+ {
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare(keyword,"blue") == 0)
+ {
+ gammaBlue = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"green") == 0)
+ {
+ gammaGreen = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"red") == 0)
+ {
+ gammaRed = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ }
+
+ /* process image */
+ {
+ char gamma[MaxTextExtent + 1];
+ FormatString( gamma, "%3.6f/%3.6f/%3.6f/",
+ gammaRed, gammaGreen, gammaBlue);
+
+ (void) GammaImage ( msl_info->image[n], gamma );
+ }
+
+ break;
+ }
+ else if (LocaleCompare((char *) name,"get") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ (void) CloneString(&value,(char *) attributes[i]);
+ (void) strlcpy(key,value,MaxTextExtent);
+ switch (*keyword)
+ {
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ FormatString(value,"%ld",msl_info->image[n]->rows);
+ (void) SetImageAttribute(msl_info->attributes[n],
+ key,NULL);
+ (void) SetImageAttribute(msl_info->attributes[n],
+ key,value);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ FormatString(value,"%ld",
+ msl_info->image[n]->columns);
+ (void) SetImageAttribute(msl_info->attributes[n],
+ key,NULL);
+ (void) SetImageAttribute(msl_info->attributes[n],
+ key,value);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ else if (LocaleCompare((char *) name, "group") == 0)
+ {
+ msl_info->nGroups++;
+ MagickReallocMemory(MSLGroupInfo *,msl_info->group_info,
+ (msl_info->nGroups+1)*sizeof(MSLGroupInfo));
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare((char *) name,"image") == 0)
+ {
+ long
+ n;
+
+ MSLPushImage(msl_info,(Image *) NULL);
+ n=msl_info->n;
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare(keyword,"background") == 0)
+ {
+ (void) QueryColorDatabase
+ (value,
+ &msl_info->image_info[n]->background_color,
+ &exception);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(keyword,"color") == 0)
+ {
+ Image
+ *next_image;
+
+ (void) strlcpy(msl_info->image_info[n]->filename,
+ "xc:",
+ sizeof(msl_info->image_info[n]->filename));
+ (void) strlcat(msl_info->image_info[n]->filename,
+ value,
+ sizeof(msl_info->image_info[n]->filename));
+ next_image=ReadImage(msl_info->image_info[n],
+ &exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (next_image == (Image *) NULL)
+ continue;
+ if (msl_info->image[n] == (Image *) NULL)
+ msl_info->image[n]=next_image;
+ else
+ {
+ register Image
+ *p;
+
+ /*
+ Link image into image list.
+ */
+ p=msl_info->image[n];
+ for ( ; p->next != (Image *) NULL; p=p->next);
+ next_image->previous=p;
+ p->next=next_image;
+ }
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare(keyword,"id") == 0)
+ {
+ (void) SetImageAttribute(msl_info->attributes[n],
+ keyword,NULL);
+ (void) SetImageAttribute(msl_info->attributes[n],
+ keyword,value);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"size") == 0)
+ {
+ (void) CloneString(&msl_info->image_info[n]->size,
+ value);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ break;
+ }
+ else if (LocaleCompare((char *) name,"implode") == 0)
+ {
+ /* init the values */
+ double amount = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'A':
+ case 'a':
+ {
+ if (LocaleCompare(keyword,"amount") == 0)
+ {
+ amount = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=ImplodeImage(msl_info->image[n],amount,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare((char *) name, "magnify") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ Image
+ *newImage;
+
+ newImage=MagnifyImage(msl_info->image[n],
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name,"medianfilter") == 0)
+ {
+ /* init the values */
+ unsigned int radius = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"radius") == 0)
+ {
+ radius = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=MedianFilterImage(msl_info->image[n], radius,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name, "minify") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ Image
+ *newImage;
+
+ newImage=MinifyImage(msl_info->image[n],
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name, "msl") == 0 )
+ {
+ /*
+ This is our base element.
+ at the moment we don't do anything special
+ but someday we might!
+ */
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'N':
+ case 'n':
+ {
+ if (LocaleCompare((char *) name, "normalize") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ (void) NormalizeImage(msl_info->image[n]);
+ break;
+ }
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare((char *) name, "oilpaint") == 0)
+ {
+ /* init the values */
+ unsigned int radius = 3;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"radius") == 0)
+ {
+ radius = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=OilPaintImage(msl_info->image[n], radius,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'P':
+ case 'p':
+ {
+ if (LocaleCompare((char *) name,"print") == 0)
+ {
+ /* print does not require an image to be present! */
+
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare(keyword,"output") == 0)
+ {
+ (void) LogMagickEvent(CoderEvent,
+ GetMagickModule(),"%s",value);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ break;
+ }
+ else if (LocaleCompare((char *) name, "profile") == 0)
+ {
+ ImageInfo
+ *clone_info;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ clone_info=CloneImageInfo(msl_info->image_info[n]);
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ {
+ DestroyImageInfo(clone_info);
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ }
+
+ if (LocaleCompare(value,"!") == 0)
+ {
+ /*
+ Remove profile named <keyword> from the image.
+ */
+ (void) ProfileImage(msl_info->image[n],keyword,
+ (unsigned char *) NULL,0,True);
+ }
+ else
+ {
+ /*
+ Add profile named <keyword> held in file <value> to the image.
+ */
+ Image
+ *profile_image;
+
+ ProfileInfo
+ profile_info;
+
+ const char
+ *profile_name;
+
+ size_t
+ profile_length;
+
+ const unsigned char *
+ profile_data;
+
+ ImageProfileIterator
+ profile_iterator;
+
+ void
+ *client_data;
+
+ client_data=clone_info->client_data;
+
+ /*
+ FIXME: Next three lines replace:
+ clone_info->client_data=(void *) &(msl_info->image[n]->iptc_profile);
+ */
+ profile_info.name="IPTC";
+ profile_info.info=(unsigned char *) GetImageProfile(msl_info->image[n],profile_info.name,
+ &profile_info.length);
+ clone_info->client_data=&profile_info;
+
+ (void) strlcpy(clone_info->filename,value,MaxTextExtent);
+ profile_image=ReadImage(clone_info,&(msl_info->image[n]->exception));
+ if (profile_image == (Image *) NULL)
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Failed to load profile from file \"%s\"",
+ clone_info->filename);
+ }
+ else
+ {
+ /*
+ Transfer profile(s) to image.
+ */
+ profile_iterator=AllocateImageProfileIterator(profile_image);
+ while(NextImageProfile(profile_iterator,&profile_name,&profile_data,
+ &profile_length) != MagickFail)
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Adding %s profile to image",profile_name);
+ if ((LocaleCompare(profile_name,"ICC") == 0) ||
+ (LocaleCompare(profile_name,"ICM") == 0))
+ (void) ProfileImage(msl_info->image[n],profile_name,(unsigned char *) profile_data,
+ profile_length,True);
+ else
+ (void) SetImageProfile(msl_info->image[n],profile_name,profile_data,profile_length);
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+ DestroyImage(profile_image);
+ profile_image=(Image *) NULL;
+ clone_info->client_data=client_data;
+ }
+ MagickFreeMemory(value);
+ }
+ }
+ DestroyImageInfo(clone_info);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare((char *) name,"read") == 0)
+ {
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(keyword,"filename") == 0)
+ {
+ Image
+ *next_image;
+
+ (void) strlcpy(msl_info->image_info[n]->filename,
+ value,
+ sizeof(msl_info->image_info[n]->filename));
+ next_image=ReadImage(msl_info->image_info[n],
+ &exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (next_image == (Image *) NULL)
+ continue;
+ if (msl_info->image[n] == (Image *) NULL)
+ msl_info->image[n]=next_image;
+ else
+ {
+ register Image
+ *p;
+
+ /*
+ Link image into image list.
+ */
+ p=msl_info->image[n];
+ for ( ; p->next != (Image *) NULL; p=p->next);
+ next_image->previous=p;
+ p->next=next_image;
+ }
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"size") == 0)
+ {
+ msl_info->image_info[n]->size=AllocateString(value);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ break;
+ }
+ else if (LocaleCompare((char *) name, "reducenoise") == 0 )
+ {
+ /* init the values */
+ unsigned int radius = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"radius") == 0)
+ {
+ radius = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=ReduceNoiseImage(msl_info->image[n], radius,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name,"resize") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* init the values */
+ width=msl_info->image[n]->columns;
+ height=msl_info->image[n]->rows;
+ x=0;
+ y=0;
+
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare(keyword,"blur") == 0)
+ {
+ msl_info->image[n]->blur = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(keyword, "filter") == 0)
+ {
+ FilterTypes
+ newFilter;
+
+ newFilter=StringToFilterTypes(value);
+ msl_info->image[n]->filter = newFilter;
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,&width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ height = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ width = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ Resize image.
+ */
+ {
+ Image
+ *resize_image;
+
+ if ((width == msl_info->image[n]->columns) &&
+ (height == msl_info->image[n]->rows))
+ break;
+ resize_image=ZoomImage(msl_info->image[n],width,height,
+ &msl_info->image[n]->exception);
+ if (resize_image == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=resize_image;
+ }
+
+ break;
+ }
+ else if (LocaleCompare((char *) name,"roll") == 0)
+ {
+ /* init the values */
+ width=msl_info->image[n]->columns;
+ height=msl_info->image[n]->rows;
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,&width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(keyword,"x") == 0)
+ {
+ x = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(keyword,"y") == 0)
+ {
+ y = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=RollImage(msl_info->image[n], x, y,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ else if (LocaleCompare((char *) name,"rotate") == 0)
+ {
+ /* init the values */
+ double degrees = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare(keyword,"degrees") == 0)
+ {
+ degrees = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=RotateImage(msl_info->image[n], degrees,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare((char *) name,"sample") == 0)
+ {
+ /* init the values */
+ width=msl_info->image[n]->columns;
+ height=msl_info->image[n]->rows;
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,&width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ height = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ width = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=SampleImage(msl_info->image[n], width, height,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ else if (LocaleCompare((char *) name,"scale") == 0)
+ {
+ /* init the values */
+ width=msl_info->image[n]->columns;
+ height=msl_info->image[n]->rows;
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,&width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ height = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ width = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=ScaleImage(msl_info->image[n], width, height,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ else if (LocaleCompare((char *) name, "set") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare(keyword,"background") == 0)
+ {
+ (void) QueryColorDatabase
+ (value,
+ &msl_info->image_info[n]->background_color,
+ &exception);
+ break;
+ }
+ else if (LocaleCompare(keyword,"bordercolor") == 0)
+ {
+ (void) QueryColorDatabase
+ (value,
+ &msl_info->image_info[n]->border_color,
+ &exception);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(keyword,"clip-mask") == 0)
+ {
+ for (j=0; j<msl_info->n;j++)
+ {
+ const ImageAttribute *
+ theAttr =
+ GetImageAttribute(msl_info->attributes[j],
+ "id");
+ if (theAttr &&
+ LocaleCompare(theAttr->value, value) == 0)
+ {
+ (void) SetImageClipMask(msl_info->image[n],
+ msl_info->image[j]);
+ break;
+ }
+ }
+ break;
+ }
+ else if (LocaleCompare(keyword, "colorspace") == 0)
+ {
+ if (LocaleCompare(value, "CMYK") == 0)
+ (void) SetImageType( msl_info->image[n],
+ ColorSeparationType );
+ else if (LocaleCompare(value, "Gray") == 0)
+ (void) SetImageType( msl_info->image[n],
+ GrayscaleType );
+ else if (LocaleCompare(value, "RGB") == 0)
+ (void) SetImageType( msl_info->image[n],
+ TrueColorType );
+ else
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedColorspace,keyword);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare(keyword, "density") == 0)
+ {
+ (void) CloneString(&msl_info->image_info[n]->density,
+ (char*)NULL);
+ (void) CloneString(&msl_info->image_info[n]->density,
+ value);
+ (void) CloneString
+ (&msl_info->draw_info[n]->density,
+ msl_info->image_info[n]->density);
+ j=GetMagickDimension
+ (msl_info->image_info[n]->density,
+ &msl_info->image[n]->x_resolution,
+ &msl_info->image[n]->y_resolution,
+ NULL,NULL);
+ if (j != 2)
+ msl_info->image[n]->y_resolution =
+ msl_info->image[n]->x_resolution;
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare(keyword, "magick") == 0)
+ {
+ (void) strlcpy( msl_info->image_info[n]->magick,
+ value,
+ sizeof(msl_info->image_info[n]->magick) );
+ break;
+ }
+ else if (LocaleCompare(keyword,"mattecolor") == 0)
+ {
+ (void) QueryColorDatabase
+ (value,
+ &msl_info->image_info[n]->matte_color,
+ &exception);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare(keyword, "opacity") == 0)
+ {
+ int opac = OpaqueOpacity,
+ len = (int) strlen( value );
+
+ if (value[len-1] == '%') {
+ char tmp[100];
+ (void) strncpy(tmp, value, (size_t) (len-1));
+ opac = MagickAtoI( tmp );
+ opac = (int)(MaxRGB * ((float)opac/100));
+ } else
+ opac = MagickAtoI( value );
+ SetImageOpacity( msl_info->image[n], opac );
+ break;
+ }
+
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ break;
+ }
+ else if (LocaleCompare((char *) name, "sharpen") == 0)
+ {
+ double radius = 0.0,
+ sigma = 1.0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes != (const xmlChar **) NULL)
+ {
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword, "radius") == 0)
+ {
+ radius = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"sigma") == 0)
+ {
+ sigma = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ }
+
+ /*
+ sharpen image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=SharpenImage(msl_info->image[n],radius,sigma,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name,"shave") == 0)
+ {
+ /* init the values */
+ width = height = 0;
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"geometry") == 0)
+ {
+ (void) GetMagickGeometry(value,&x,&y,&width,&height);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ height = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ width = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+ RectangleInfo
+ rectInfo;
+
+ rectInfo.height = height;
+ rectInfo.width = width;
+ rectInfo.x = x;
+ rectInfo.y = y;
+
+
+ newImage=ShaveImage(msl_info->image[n], &rectInfo,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ else if (LocaleCompare((char *) name,"shear") == 0)
+ {
+ /* init the values */
+ width=msl_info->image[n]->columns;
+ height=msl_info->image[n]->rows;
+ x = y = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(keyword,"x") == 0)
+ {
+ x = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(keyword,"y") == 0)
+ {
+ y = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=ShearImage(msl_info->image[n], x, y,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ else if (LocaleCompare((char *) name,"solarize") == 0)
+ {
+ /* init the values */
+ double threshold = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare(keyword,"threshold") == 0)
+ {
+ threshold = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ (void) SolarizeImage(msl_info->image[n], threshold);
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name,"spread") == 0)
+ {
+ /* init the values */
+ unsigned int radius = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"radius") == 0)
+ {
+ radius = MagickAtoI( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=SpreadImage(msl_info->image[n], radius,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name,"stegano") == 0)
+ {
+ Image *
+ watermark = (Image*)NULL;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare(keyword,"image") == 0)
+ {
+ for (j=0; j<msl_info->n;j++)
+ {
+ const ImageAttribute *
+ theAttr = GetImageAttribute
+ (msl_info->attributes[j], "id");
+ if (theAttr &&
+ LocaleCompare(theAttr->value, value) == 0)
+ {
+ watermark = msl_info->image[j];
+ break;
+ }
+ }
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ if ( watermark != (Image*) NULL )
+ {
+ Image
+ *newImage;
+
+ newImage=SteganoImage(msl_info->image[n], watermark,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ } else
+ ThrowException(msl_info->exception,OptionError,
+ MissingAnImageFilename,keyword);
+ }
+ else if (LocaleCompare((char *) name,"stereo") == 0)
+ {
+ Image *
+ stereoImage = (Image*)NULL;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare(keyword,"image") == 0)
+ {
+ for (j=0; j<msl_info->n;j++)
+ {
+ const ImageAttribute *
+ theAttr = GetImageAttribute
+ (msl_info->attributes[j], "id");
+ if (theAttr &&
+ LocaleCompare(theAttr->value, value) == 0)
+ {
+ stereoImage = msl_info->image[j];
+ break;
+ }
+ }
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ if ( stereoImage != (Image*) NULL )
+ {
+ Image
+ *newImage;
+
+ newImage=StereoImage(msl_info->image[n], stereoImage,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ } else
+ ThrowException(msl_info->exception,OptionError,
+ MissingAnImageFilename,keyword);
+ }
+ else if (LocaleCompare((char *) name,"swirl") == 0)
+ {
+ /* init the values */
+ double degrees = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare(keyword,"degrees") == 0)
+ {
+ degrees = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ Image
+ *newImage;
+
+ newImage=SwirlImage(msl_info->image[n], degrees,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ }
+
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare((char *) name,"texture") == 0)
+ {
+ Image *
+ textureImage = (Image*)NULL;
+
+ /*
+ if the image hasn't been initted yet, then clear it to white
+ */
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ Image
+ *next_image;
+
+ (void) strlcpy(msl_info->image_info[n]->filename,"xc:white",
+ sizeof(msl_info->image_info[n]->filename));
+ next_image=ReadImage(msl_info->image_info[n],&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (next_image == (Image *) NULL)
+ break;
+ if (msl_info->image[n] == (Image *) NULL)
+ msl_info->image[n]=next_image;
+ else
+ {
+ register Image
+ *p;
+
+ /*
+ Link image into image list.
+ */
+ p=msl_info->image[n];
+ for ( ; p->next != (Image *) NULL; p=p->next);
+ next_image->previous=p;
+ p->next=next_image;
+ }
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare(keyword,"image") == 0)
+ {
+ for (j=0; j<msl_info->n;j++)
+ {
+ const ImageAttribute *
+ theAttr = GetImageAttribute
+ (msl_info->attributes[j], "id");
+ if (theAttr &&
+ LocaleCompare(theAttr->value, value) == 0)
+ {
+ textureImage = msl_info->image[j];
+ break;
+ }
+ }
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ if ( textureImage != (Image*) NULL )
+ {
+ (void) TextureImage(msl_info->image[n], textureImage);
+ break;
+ }
+ else
+ ThrowException(msl_info->exception,OptionError,
+ MissingAnImageFilename,keyword);
+ }
+ else if (LocaleCompare((char *) name,"threshold") == 0)
+ {
+ /* init the values */
+ double threshold = 0;
+
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare(keyword,"threshold") == 0)
+ {
+ threshold = MagickAtoF( value );
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+
+ /*
+ process image.
+ */
+ {
+ char thresholds[MaxTextExtent];
+
+ FormatString(thresholds,"%g",threshold);
+ (void) ChannelThresholdImage(msl_info->image[n], thresholds);
+ break;
+ }
+ }
+ else if (LocaleCompare((char *) name, "transparent") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(keyword,"color") == 0)
+ {
+ PixelPacket
+ target;
+
+ (void) AcquireOnePixelByReference
+ (msl_info->image[n],
+ &target,0,0,
+ &(msl_info->image[n])->exception);
+ (void) QueryColorDatabase(value,&target,&exception);
+ (void) TransparentImage(msl_info->image[n],target,
+ TransparentOpacity);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ break;
+ }
+ else if (LocaleCompare((char *) name, "trim") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+
+ /* no attributes here */
+
+ /* process the image */
+ {
+ Image
+ *newImage;
+ RectangleInfo
+ rectInfo;
+
+ /* all zeros on a crop == trim edges! */
+ rectInfo.height = rectInfo.width = 0;
+ rectInfo.x = rectInfo.y = 0;
+
+ newImage=CropImage(msl_info->image[n],&rectInfo,
+ &msl_info->image[n]->exception);
+ if (newImage == (Image *) NULL)
+ break;
+ DestroyImage(msl_info->image[n]);
+ msl_info->image[n]=newImage;
+ break;
+ }
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare((char *) name,"write") == 0)
+ {
+ if (msl_info->image[n] == (Image *) NULL)
+ {
+ ThrowException(msl_info->exception,OptionError,
+ NoImagesDefined,(char *) name);
+ break;
+ }
+ if (attributes == (const xmlChar **) NULL)
+ break;
+ for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
+ {
+ keyword=(const char *) attributes[i++];
+ value=TranslateText(msl_info->image_info[n],
+ msl_info->attributes[n],
+ (char *) attributes[i]);
+ if (value == NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ switch (*keyword)
+ {
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(keyword,"filename") == 0)
+ {
+ (void) strlcpy(msl_info->image[n]->filename,value,
+ MaxTextExtent);
+ (void) WriteImage(msl_info->image_info[n],
+ msl_info->image[n]);
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedAttribute,keyword);
+ break;
+ }
+ }
+ MagickFreeMemory(value);
+ }
+ break;
+ }
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ }
+ default:
+ {
+ ThrowException(msl_info->exception,OptionError,
+ UnrecognizedElement,(const char *) name);
+ break;
+ }
+ }
+ if ( value != NULL )
+ MagickFreeMemory(value);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
+}
+
+static void
+MSLEndElement(void *context,const xmlChar *name)
+{
+ MSLInfo
+ *msl_info;
+
+ /*
+ Called when the end of an element has been detected.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.endElement(%.1024s)",name);
+ msl_info=(MSLInfo *) context;
+ switch (*name)
+ {
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare((char *) name, "group") == 0 )
+ {
+ if (msl_info->group_info[msl_info->nGroups-1].numImages > 0 )
+ {
+ long i = (long)
+ (msl_info->group_info[msl_info->nGroups-1].numImages);
+
+ while ( (i--) && (msl_info->n > 0) )
+ {
+ if (msl_info->image[msl_info->n] != (Image *) NULL)
+ {
+ DestroyImage(msl_info->image[msl_info->n]);
+ msl_info->image[msl_info->n]=(Image *) NULL;
+ }
+
+ DestroyDrawInfo(msl_info->draw_info[msl_info->n]);
+ msl_info->draw_info[msl_info->n]=(DrawInfo *) NULL;
+
+ DestroyImage(msl_info->attributes[msl_info->n]);
+ msl_info->attributes[msl_info->n]=(Image *) NULL;
+
+ DestroyImageInfo(msl_info->image_info[msl_info->n]);
+ msl_info->image_info[msl_info->n]=(ImageInfo *) NULL;
+
+ msl_info->n--;
+ }
+ }
+ msl_info->nGroups--;
+ }
+ }
+ break;
+
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare((char *) name, "image") == 0)
+ MSLPopImage(msl_info);
+ }
+ break;
+
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare((char *) name, "msl") == 0 )
+ {
+ /*
+ This is our base element.
+ at the moment we don't do anything special
+ but someday we might!
+ */
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+MSLCharacters(void *context,const xmlChar *c,int length)
+{
+/* MSLInfo */
+/* *msl_info; */
+
+ ARG_NOT_USED(context);
+ /*
+ Receiving some characters from the parser.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.characters(%.1024s,%d)",c,length);
+/* msl_info=(MSLInfo *) context; */
+}
+
+static void
+MSLReference(void *context,const xmlChar *name)
+{
+ MSLInfo
+ *msl_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ Called when an entity reference is detected.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.reference(%.1024s)",name);
+ msl_info=(MSLInfo *) context;
+ parser=msl_info->parser;
+ if (*name == '#')
+ (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
+ else
+ (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
+}
+
+static void
+MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
+{
+ /* MSLInfo */
+ /* *msl_info; */
+
+ ARG_NOT_USED(context);
+ /*
+ Receiving some ignorable whitespaces from the parser.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.ignorableWhitespace(%.30s, %d)",c,length);
+ /* msl_info=(MSLInfo *) context; */
+}
+
+static void
+MSLProcessingInstructions(void *context,const xmlChar *target,
+ const xmlChar *data)
+{
+ /* MSLInfo */
+ /* *msl_info; */
+
+ ARG_NOT_USED(context);
+ /*
+ A processing instruction has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.processingInstruction(%.1024s, %.1024s)",
+ target,data);
+ /* msl_info=(MSLInfo *) context; */
+}
+
+static void
+MSLComment(void *context,const xmlChar *value)
+{
+/* MSLInfo */
+/* *msl_info; */
+
+ ARG_NOT_USED(context);
+ /*
+ A comment has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.comment(%.1024s)",value);
+/* msl_info=(MSLInfo *) context; */
+}
+
+static void
+MSLWarning(void *context,const char *format,...)
+{
+ char
+ reason[MaxTextExtent];
+
+ MSLInfo
+ *msl_info;
+
+ va_list
+ operands;
+
+ /**
+ Display and format a warning messages, gives file, line, position and
+ extra parameters.
+ */
+ va_start(operands,format);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
+ msl_info=(MSLInfo *) context;
+#if !defined(HAVE_VSNPRINTF)
+ (void) vsprintf(reason,format,operands);
+#else
+ (void) vsnprintf(reason,MaxTextExtent,format,operands);
+#endif
+ ThrowException2(msl_info->exception,CoderError,reason,(char *) NULL);
+ va_end(operands);
+}
+
+static void
+MSLError(void *context,const char *format,...)
+{
+ char
+ reason[MaxTextExtent];
+
+ MSLInfo
+ *msl_info;
+
+ va_list
+ operands;
+
+ /*
+ Display and format a error formats, gives file, line, position and
+ extra parameters.
+ */
+ va_start(operands,format);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
+ msl_info=(MSLInfo *) context;
+#if !defined(HAVE_VSNPRINTF)
+ (void) vsprintf(reason,format,operands);
+#else
+ (void) vsnprintf(reason,MaxTextExtent,format,operands);
+#endif
+ ThrowException2(msl_info->exception,DelegateFatalError,reason,"some text");
+ va_end(operands);
+}
+
+static void
+MSLCDataBlock(void *context,const xmlChar *value,int length)
+{
+ MSLInfo
+ *msl_info;
+
+ xmlNodePtr
+ child;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ Called when a pcdata block has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.pcdata(%.1024s, %d)",value,length);
+ msl_info=(MSLInfo *) context;
+ parser=msl_info->parser;
+ child=xmlGetLastChild(parser->node);
+ if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
+ {
+ (void) xmlTextConcat(child,value,length);
+ return;
+ }
+ (void) xmlAddChild(parser->node,
+ xmlNewCDataBlock(parser->myDoc,value,length));
+}
+
+static void
+MSLExternalSubset(void *context,const xmlChar *name,
+ const xmlChar *external_id,
+ const xmlChar *system_id)
+{
+ MSLInfo
+ *msl_info;
+
+ xmlParserCtxt
+ parser_context;
+
+ xmlParserCtxtPtr
+ parser;
+
+ xmlParserInputPtr
+ input;
+
+ /*
+ Does this document has an external subset?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.externalSubset(%.1024s %.1024s %.1024s)",
+ name,
+ (external_id != (const xmlChar *) NULL ?
+ (char *) external_id : " "),
+ (system_id != (const xmlChar *) NULL ?
+ (char *) system_id : " "));
+ msl_info=(MSLInfo *) context;
+ parser=msl_info->parser;
+ if (((external_id == NULL) && (system_id == NULL)) ||
+ (!parser->validate || !parser->wellFormed || !msl_info->document))
+ return;
+ input=MSLResolveEntity(context,external_id,system_id);
+ if (input == NULL)
+ return;
+ (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
+ parser_context=(*parser);
+ parser->inputTab=(xmlParserInputPtr *)
+ xmlMalloc(5*sizeof(xmlParserInputPtr));
+ if (parser->inputTab == (xmlParserInputPtr *) NULL)
+ {
+ parser->errNo=XML_ERR_NO_MEMORY;
+ parser->input=parser_context.input;
+ parser->inputNr=parser_context.inputNr;
+ parser->inputMax=parser_context.inputMax;
+ parser->inputTab=parser_context.inputTab;
+ return;
+ }
+ parser->inputNr=0;
+ parser->inputMax=5;
+ parser->input=NULL;
+ xmlPushInput(parser,input);
+ (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
+ if (input->filename == (char *) NULL)
+ input->filename=(char *) xmlStrdup(system_id);
+ input->line=1;
+ input->col=1;
+ input->base=parser->input->cur;
+ input->cur=parser->input->cur;
+ input->free=NULL;
+ xmlParseExternalSubset(parser,external_id,system_id);
+ while (parser->inputNr > 1)
+ (void) xmlPopInput(parser);
+ xmlFreeInputStream(parser->input);
+ xmlFree(parser->inputTab);
+ parser->input=parser_context.input;
+ parser->inputNr=parser_context.inputNr;
+ parser->inputMax=parser_context.inputMax;
+ parser->inputTab=parser_context.inputTab;
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+/* } */
+#endif
+
+static unsigned int
+ProcessMSLScript(const ImageInfo *image_info,Image **image,
+ ExceptionInfo *exception)
+{
+ xmlSAXHandler
+ SAXModules;
+
+ char
+ message[MaxTextExtent];
+
+ Image
+ *msl_image;
+
+ long
+ n;
+
+ MSLInfo
+ msl_info;
+
+ unsigned int
+ status;
+
+ xmlSAXHandlerPtr
+ SAXHandler;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image **) NULL);
+ msl_image=AllocateImage(image_info);
+ status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ {
+ ThrowException(exception,FileOpenError,UnableToOpenFile,
+ msl_image->filename);
+ return(False);
+ }
+
+ /*
+ Parse MSL file.
+ */
+ (void) memset(&msl_info,0,sizeof(MSLInfo));
+ msl_info.exception=exception;
+ msl_info.image_info=MagickAllocateMemory(ImageInfo **,sizeof(ImageInfo *));
+ msl_info.draw_info=MagickAllocateMemory(DrawInfo **,sizeof(DrawInfo *));
+ /* top of the stack is the MSL file itself */
+ msl_info.image=MagickAllocateMemory(Image **,sizeof(Image *));
+ msl_info.attributes=MagickAllocateMemory(Image **,sizeof(Image *));
+ msl_info.group_info=MagickAllocateMemory(MSLGroupInfo *,
+ sizeof(MSLGroupInfo));
+ if ((msl_info.image_info == (ImageInfo **) NULL) ||
+ (msl_info.draw_info == (DrawInfo **) NULL) ||
+ (msl_info.image == (Image **) NULL) ||
+ (msl_info.attributes == (Image **) NULL) ||
+ (msl_info.group_info == (MSLGroupInfo *) NULL))
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToInterpretMSLImage);
+ msl_info.image_info[0]=CloneImageInfo(image_info);
+ msl_info.draw_info[0]=CloneDrawInfo(image_info,(DrawInfo *) NULL);
+ if (image_info->attributes)
+ msl_info.attributes[0]=CloneImage(image_info->attributes,0,0,True,exception);
+ else
+ msl_info.attributes[0]=(Image *) NULL;
+ msl_info.group_info[0].numImages=0;
+ /* the first slot is used to point to the MSL file image */
+ *msl_info.image=msl_image;
+ if (*image != (Image *) NULL)
+ MSLPushImage(&msl_info,*image);
+ (void) xmlSubstituteEntitiesDefault(1);
+
+ (void) memset(&SAXModules,0,sizeof(SAXModules));
+ SAXModules.internalSubset=MSLInternalSubset;
+ SAXModules.isStandalone=MSLIsStandalone;
+ SAXModules.hasInternalSubset=MSLHasInternalSubset;
+ SAXModules.hasExternalSubset=MSLHasExternalSubset;
+ SAXModules.resolveEntity=MSLResolveEntity;
+ SAXModules.getEntity=MSLGetEntity;
+ SAXModules.entityDecl=MSLEntityDeclaration;
+ SAXModules.notationDecl=MSLNotationDeclaration;
+ SAXModules.attributeDecl=MSLAttributeDeclaration;
+ SAXModules.elementDecl=MSLElementDeclaration;
+ SAXModules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
+ SAXModules.setDocumentLocator=MSLSetDocumentLocator;
+ SAXModules.startDocument=MSLStartDocument;
+ SAXModules.endDocument=MSLEndDocument;
+ SAXModules.startElement=MSLStartElement;
+ SAXModules.endElement=MSLEndElement;
+ SAXModules.reference=MSLReference;
+ SAXModules.characters=MSLCharacters;
+ SAXModules.ignorableWhitespace=MSLIgnorableWhitespace;
+ SAXModules.processingInstruction=MSLProcessingInstructions;
+ SAXModules.comment=MSLComment;
+ SAXModules.warning=MSLWarning;
+ SAXModules.error=MSLError;
+ SAXModules.fatalError=MSLError;
+ SAXModules.getParameterEntity=MSLGetParameterEntity;
+ SAXModules.cdataBlock=MSLCDataBlock;
+ SAXModules.externalSubset=MSLExternalSubset;
+
+ SAXHandler=(&SAXModules);
+ msl_info.parser=xmlCreatePushParserCtxt(SAXHandler,&msl_info,(char *) NULL,0,
+ msl_image->filename);
+ while (ReadBlobString(msl_image,message) != (char *) NULL)
+ {
+ n=(long) strlen(message);
+ if (n == 0)
+ continue;
+ status=xmlParseChunk(msl_info.parser,message,(int) n,False);
+ if (status != 0)
+ break;
+ (void) xmlParseChunk(msl_info.parser," ",1,False);
+ if (msl_info.exception->severity != UndefinedException)
+ break;
+ }
+ if (msl_info.exception->severity == UndefinedException)
+ (void) xmlParseChunk(msl_info.parser," ",1,True);
+ xmlFreeParserCtxt(msl_info.parser);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
+
+
+ xmlFreeDoc(msl_info.document);
+ xmlCleanupParser();
+
+/* printf("ProcessMSLScript(msl_info->n=%ld\n",msl_info.n); */
+
+ if (*image == (Image *) NULL)
+ *image=*msl_info.image;
+
+ if (msl_info.draw_info[0] != (DrawInfo *) NULL)
+ {
+ DestroyDrawInfo(msl_info.draw_info[0]);
+ msl_info.draw_info[0]=(DrawInfo *) NULL;
+ }
+ if (msl_info.attributes[0] != (Image *) NULL)
+ {
+ DestroyImage(msl_info.attributes[0]);
+ msl_info.attributes[0]=(Image *) NULL;
+ }
+ if (msl_info.image_info[0] != (ImageInfo *) NULL)
+ {
+ DestroyImageInfo(msl_info.image_info[0]);
+ msl_info.image_info[0]=(ImageInfo *) NULL;
+ }
+
+ MagickFreeMemory(msl_info.image_info);
+ MagickFreeMemory(msl_info.draw_info);
+ MagickFreeMemory(msl_info.attributes);
+ MagickFreeMemory(msl_info.image);
+ MagickFreeMemory(msl_info.group_info);
+
+ CloseBlob(*image);
+
+ return((*image != (Image *) NULL) &&
+ ((*image)->exception.severity == UndefinedException));
+}
+
+static Image *
+ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image *
+ image;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=(Image *) NULL;
+ (void) ProcessMSLScript(image_info,&image,exception);
+ return(image);
+}
+#endif /* defined(HasXML) */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M S L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMSLImage adds attributes for the MSL image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMSLImage method is:
+%
+% RegisterMSLImage(void)
+%
+*/
+ModuleExport void
+RegisterMSLImage(void)
+{
+#if defined(HasXML)
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("MSL");
+ entry->decoder=(DecoderHandler) ReadMSLImage;
+ entry->encoder=(EncoderHandler) WriteMSLImage;
+ entry->description="Magick Scripting Language";
+ entry->module="MSL";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+#endif /* defined(HasXML) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M S L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMSLImage removes format registrations made by the
+% MSL module from the list of supported formats.
+%
+% The format of the UnregisterMSLImage method is:
+%
+% UnregisterMSLImage(void)
+%
+*/
+ModuleExport void
+UnregisterMSLImage(void)
+{
+#if defined(HasXML)
+ (void) UnregisterMagickInfo("MSL");
+#endif /* defined(HasXML) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M S L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMSLImage processes the image via a MSL script.
+%
+% The format of the WriteMSLImage method is:
+%
+% unsigned int WriteMSLImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteMSLImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+#if defined(HasXML)
+static unsigned int WriteMSLImage(const ImageInfo *image_info,Image *image)
+{
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ (void) ReferenceImage(image);
+ (void) ProcessMSLScript(image_info,&image,&image->exception);
+ return(True);
+}
+#endif /* defined(HasXML) */
diff --git a/coders/mtv.c b/coders/mtv.c
new file mode 100644
index 0000000..117e640
--- /dev/null
+++ b/coders/mtv.c
@@ -0,0 +1,401 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M TTTTT V V %
+% MM MM T V V %
+% M M M T V V %
+% M M T V V %
+% M M T V %
+% %
+% %
+% Read/Write MTV Raytracer Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMTVImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M T V I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMTVImage reads a MTV image file and returns it. It allocates
+% the memory necessary for the new Image structure and returns a pointer to
+% the new image.
+%
+% The format of the ReadMTVImage method is:
+%
+% Image *ReadMTVImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMTVImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadMTVImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ buffer[MaxTextExtent];
+
+ Image
+ *image;
+
+ long
+ count,
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ status;
+
+ unsigned long
+ columns,
+ rows;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read MTV image.
+ */
+ (void) ReadBlobString(image,buffer);
+ columns=0;
+ rows=0;
+ count=sscanf(buffer,"%lu %lu\n",&columns,&rows);
+ if (count != 2)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ do
+ {
+ size_t
+ row_size;
+
+ /*
+ Initialize image structure.
+ */
+ image->columns=columns;
+ image->rows=rows;
+ image->depth=8;
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Convert MTV raster image to pixel packets.
+ */
+ pixels=MagickAllocateArray(unsigned char *,image->columns,3);
+ if (pixels == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ row_size=image->columns*3;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (ReadBlob(image,row_size,pixels) != row_size)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ p=pixels;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->blue=ScaleCharToQuantum(*p++);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(pixels);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ *buffer='\0';
+ (void) ReadBlobString(image,buffer);
+ count=sscanf(buffer,"%lu %lu\n",&columns,&rows);
+ if (count == 2)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ } while (count == 2);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M T V I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMTVImage adds attributes for the MTV image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMTVImage method is:
+%
+% RegisterMTVImage(void)
+%
+*/
+ModuleExport void RegisterMTVImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("MTV");
+ entry->decoder=(DecoderHandler) ReadMTVImage;
+ entry->encoder=(EncoderHandler) WriteMTVImage;
+ entry->description="MTV Raytracing image format";
+ entry->module="MTV";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M T V I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMTVImage removes format registrations made by the
+% MTV module from the list of supported formats.
+%
+% The format of the UnregisterMTVImage method is:
+%
+% UnregisterMTVImage(void)
+%
+*/
+ModuleExport void UnregisterMTVImage(void)
+{
+ (void) UnregisterMagickInfo("MTV");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M T V I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMTVImage writes an image to a file in red, green, and blue
+% MTV rasterfile format.
+%
+% The format of the WriteMTVImage method is:
+%
+% unsigned int WriteMTVImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteMTVImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteMTVImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[MaxTextExtent];
+
+ int
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ status;
+
+ unsigned long
+ scene;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ scene=0;
+ do
+ {
+ /*
+ Allocate memory for pixels.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ pixels=MagickAllocateMemory(unsigned char *,
+ image->columns*sizeof(PixelPacket));
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize raster file header.
+ */
+ FormatString(buffer,"%lu %lu\n",image->columns,image->rows);
+ (void) WriteBlobString(image,buffer);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ p++;
+ }
+ (void) WriteBlob(image,q-pixels,(char *) pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(pixels);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/mvg.c b/coders/mvg.c
new file mode 100644
index 0000000..15c31fc
--- /dev/null
+++ b/coders/mvg.c
@@ -0,0 +1,318 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M V V GGGG %
+% MM MM V V G %
+% M M M V V G GG %
+% M M V V G G %
+% M M V GGG %
+% %
+% Read/Write Magick Vector Graphics Metafiles. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% April 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/magick.h"
+#include "magick/render.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteMVGImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M V G %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsMVG returns True if the image format type, identified by the
+% magick string, is MVG.
+%
+% The format of the IsMVG method is:
+%
+% unsigned int IsMVG(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsMVG returns True if the image format type is MVG.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsMVG(const unsigned char *magick,const size_t length)
+{
+ if (length < 7)
+ return(False);
+ if (LocaleNCompare((char *) magick,"viewbox",7) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d M V G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadMVGImage creates a gradient image and initializes it to
+% the X server color range as specified by the filename. It allocates the
+% memory necessary for the new Image structure and returns a pointer to the
+% new image.
+%
+% The format of the ReadMVGImage method is:
+%
+% Image *ReadMVGImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadMVGImage returns a pointer to the image after
+% creating it. A null image is returned if there is a memory shortage
+% or if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadMVGImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define BoundingBox "viewbox"
+
+ DrawInfo
+ *draw_info;
+
+ Image
+ *image;
+
+ size_t
+ length;
+
+ unsigned int
+ status;
+
+ /*
+ Open image.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ if ((image->columns == 0) || (image->rows == 0))
+ {
+ char
+ primitive[MaxTextExtent];
+
+ register char
+ *p;
+
+ SegmentInfo
+ bounds;
+
+ /*
+ Determine size of image canvas.
+ */
+ while (ReadBlobString(image,primitive) != (char *) NULL)
+ {
+ for (p=primitive; (*p == ' ') || (*p == '\t'); p++);
+ if (LocaleNCompare(BoundingBox,p,strlen(BoundingBox)) != 0)
+ continue;
+ (void) sscanf(p,"viewbox %lf %lf %lf %lf",&bounds.x1,&bounds.y1,
+ &bounds.x2,&bounds.y2);
+ image->columns=(unsigned long) (bounds.x2-bounds.x1+0.5);
+ image->rows=(unsigned long) (bounds.y2-bounds.y1+0.5);
+ break;
+ }
+ }
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Render drawing.
+ */
+ (void) SetImage(image,OpaqueOpacity);
+ draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
+ draw_info->fill=image_info->pen;
+ if (GetBlobStreamData(image))
+ draw_info->primitive=AllocateString((char *) GetBlobStreamData(image));
+ else
+ draw_info->primitive=(char *) FileToBlob(image->filename,&length,exception);
+ if (draw_info->primitive == (char *) NULL)
+ {
+ DestroyDrawInfo(draw_info);
+ CloseBlob(image);
+ return (Image *) NULL;
+ }
+ (void) DrawImage(image,draw_info);
+ DestroyDrawInfo(draw_info);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M V G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterMVGImage adds attributes for the MVG image format
+% to the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterMVGImage method is:
+%
+% RegisterMVGImage(void)
+%
+*/
+ModuleExport void RegisterMVGImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("MVG");
+ entry->decoder=(DecoderHandler) ReadMVGImage;
+ entry->encoder=(EncoderHandler) WriteMVGImage;
+ entry->magick=(MagickHandler) IsMVG;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Magick Vector Graphics";
+ entry->module="MVG";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M V G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMVGImage removes format registrations made by the
+% MVG module from the list of supported formats.
+%
+% The format of the UnregisterMVGImage method is:
+%
+% UnregisterMVGImage(void)
+%
+*/
+ModuleExport void UnregisterMVGImage(void)
+{
+ (void) UnregisterMagickInfo("MVG");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M V G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMVGImage writes an image to a file in MVG image format.
+%
+% The format of the WriteMVGImage method is:
+%
+% unsigned int WriteMVGImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteMVGImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteMVGImage(const ImageInfo *image_info,Image *image)
+{
+ const ImageAttribute
+ *attribute;
+
+ unsigned int
+ status;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ attribute=GetImageAttribute(image,"[MVG]");
+ if (attribute == (ImageAttribute *) NULL)
+ ThrowWriterException(CoderError,NoImageVectorGraphics,image);
+ status=OpenBlob(image_info,image,WriteBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) WriteBlob(image,strlen(attribute->value),attribute->value);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/null.c b/coders/null.c
new file mode 100644
index 0000000..ccf0d08
--- /dev/null
+++ b/coders/null.c
@@ -0,0 +1,230 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N N U U L L %
+% NN N U U L L %
+% N N N U U L L %
+% N NN U U L L %
+% N N UUU LLLLL LLLLL %
+% %
+% %
+% Read/Write Image Of Uniform Color %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteNULLImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d N U L L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadNULLImage creates a constant image and initializes it to the
+% X server color as specified by the filename. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% The format of the ReadNULLImage method is:
+%
+% Image *ReadNULLImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadNULLImage returns a pointer to the image after
+% creating it. A null image is returned if there is a memory shortage
+% or if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadNULLImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ unsigned int
+ status;
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if (image->columns == 0)
+ image->columns=1;
+ if (image->rows == 0)
+ image->rows=1;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ status=QueryColorDatabase((char *) image_info->filename,
+ &image->background_color,exception);
+ if (status == False)
+ {
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ if (!AllocateImageColormap(image,1))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ image->colormap[0]=image->background_color;
+ status=SetImageEx(image,OpaqueOpacity,exception);
+ if (status == MagickFail)
+ {
+ DestroyImage(image);
+ image=(Image *) NULL;
+ }
+
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r N U L L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterNULLImage adds attributes for the NULL image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterNULLImage method is:
+%
+% RegisterNULLImage(void)
+%
+*/
+ModuleExport void RegisterNULLImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("NULL");
+ entry->decoder=(DecoderHandler) ReadNULLImage;
+ entry->encoder=(EncoderHandler) WriteNULLImage;
+ entry->adjoin=False;
+ entry->description="Constant image of uniform color";
+ entry->module="NULL";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r N U L L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterNULLImage removes format registrations made by the
+% NULL module from the list of supported formats.
+%
+% The format of the UnregisterNULLImage method is:
+%
+% UnregisterNULLImage(void)
+%
+*/
+ModuleExport void UnregisterNULLImage(void)
+{
+ (void) UnregisterMagickInfo("NULL");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e N U L L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteNULLImage writes no output at all. It is useful when specified
+% as an output format when profiling.
+%
+% The format of the WriteNULLImage method is:
+%
+% unsigned int WriteNULLImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Always returns True.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteNULLImage(const ImageInfo *image_info,Image *image)
+{
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return(True);
+}
diff --git a/coders/otb.c b/coders/otb.c
new file mode 100644
index 0000000..18835fd
--- /dev/null
+++ b/coders/otb.c
@@ -0,0 +1,373 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% OOO TTTTT BBBB %
+% O O T B B %
+% O O T BBBB %
+% O O T B B %
+% OOO T BBBB %
+% %
+% %
+% Read/Write On-The-Air Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% January 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteOTBImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d O T B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadOTBImage reads a on-the-air (level 0) bitmap and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadOTBImage method is:
+%
+% Image *ReadOTBImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadOTBImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadOTBImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define GetBit(a,i) (((a) >> (i)) & 1L)
+
+ Image
+ *image;
+
+ int
+ byte;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned char
+ bit,
+ info,
+ depth;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Initialize image structure.
+ */
+ info=ReadBlobByte(image);
+ if (GetBit(info,4) == 0)
+ {
+ image->columns=ReadBlobByte(image);
+ image->rows=ReadBlobByte(image);
+ }
+ else
+ {
+ image->columns=ReadBlobMSBShort(image);
+ image->rows=ReadBlobMSBShort(image);
+ }
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ depth=ReadBlobByte(image);
+ if (depth != 1)
+ ThrowReaderException(CoderError,OnlyLevelZerofilesSupported,image);
+ if (!AllocateImageColormap(image,2))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Convert bi-level image to pixel packets.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (bit == 0)
+ {
+ byte=ReadBlobByte(image);
+ if (byte == EOF)
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+ indexes[x]=(byte & (0x01 << (7-bit))) ? 0x01 : 0x00;
+ bit++;
+ if (bit == 8)
+ bit=0;
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) SyncImage(image);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r O T B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterOTBImage adds attributes for the OTB image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterOTBImage method is:
+%
+% RegisterOTBImage(void)
+%
+*/
+ModuleExport void RegisterOTBImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("OTB");
+ entry->decoder=(DecoderHandler) ReadOTBImage;
+ entry->encoder=(EncoderHandler) WriteOTBImage;
+ entry->adjoin=False;
+ entry->description="On-the-air bitmap";
+ entry->module="OTB";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r O T B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterOTBImage removes format registrations made by the
+% OTB module from the list of supported formats.
+%
+% The format of the UnregisterOTBImage method is:
+%
+% UnregisterOTBImage(void)
+%
+*/
+ModuleExport void UnregisterOTBImage(void)
+{
+ (void) UnregisterMagickInfo("OTB");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e O T B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteOTBImage writes an image to a file in the On-the-air Bitmap
+% (level 0) image format.
+%
+% The format of the WriteOTBImage method is:
+%
+% unsigned int WriteOTBImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteOTBImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteOTBImage(const ImageInfo *image_info,Image *image)
+{
+#define SetBit(a,i,set) \
+ a=(unsigned char) ((set) ? (a) | (1L << (i)) : (a) & ~(1L << (i)))
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ unsigned char
+ bit,
+ byte,
+ info,
+ polarity;
+
+ unsigned int
+ status;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Convert image to a bi-level image.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]);
+ info=0;
+ if ((image->columns >= 256) || (image->rows >= 256))
+ SetBit(info,4,1);
+ (void) WriteBlobByte(image,info);
+ if ((image->columns >= 256) || (image->rows >= 256))
+ {
+ (void) WriteBlobMSBShort(image,image->columns);
+ (void) WriteBlobMSBShort(image,image->rows);
+ }
+ else
+ {
+ (void) WriteBlobByte(image,(long) image->columns);
+ (void) WriteBlobByte(image,(long) image->rows);
+ }
+ (void) WriteBlobByte(image,1); /* depth */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (indexes[x] == polarity)
+ byte|=0x1 << (7-bit);
+ bit++;
+ if (bit == 8)
+ {
+ (void) WriteBlobByte(image,byte);
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ (void) WriteBlobByte(image,byte);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/palm.c b/coders/palm.c
new file mode 100644
index 0000000..62d62ef
--- /dev/null
+++ b/coders/palm.c
@@ -0,0 +1,1981 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP AAA L M M %
+% P P A A L MM MM %
+% PPPP AAAAA L M M M %
+% P A A L M M %
+% P A A LLLLL M M %
+% %
+% %
+% Read/Write Palm Pixmap. %
+% %
+% %
+% Software Design %
+% Christopher R. Hawks %
+% December 2001 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Based on pnmtopalm by Bill Janssen and ppmtobmp by Ian Goldberg.
+% See http://www.trantor.de/kawt/doc/palmimages.html
+%
+% gm convert MasterImage_70x46.ppm -monochrome -colors 2 pnm:- | pnmtopalm -verbose -depth 1 > input_gray_01bit.palm
+%
+% gm convert MasterImage_70x46.ppm -colorspace gray -map pnm:/usr/share/netpbm/palmgray2.map pnm:- | pnmtopalm -verbose -depth 2 > input_gray_02bit.palm
+%
+% gm convert MasterImage_70x46.ppm -colorspace gray -map pnm:/usr/share/netpbm/palmgray4.map pnm:- | pnmtopalm -verbose -depth 4 > input_gray_04bit.palm
+%
+% gm convert MasterImage_70x46.ppm -map pnm:/usr/share/netpbm/palmcolor8.map pnm:- | pnmtopalm -verbose -depth 8 > input_rgb_08bit.palm
+%
+% pnmtopalm -verbose -depth 16 < MasterImage_70x46.ppm > input_rgb_16bit.palm
+%
+% Add -rle or -scanline to add compression. Add -transparent color to make color transparent.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/compare.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/paint.h"
+#include "magick/pixel_cache.h"
+#include "magick/quantize.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define PALM_IS_COMPRESSED_FLAG 0x8000
+#define PALM_HAS_COLORMAP_FLAG 0x4000
+#define PALM_HAS_TRANSPARENCY_FLAG 0x2000
+#define PALM_INDIRECT_BITMAP_FLAG 0x1000
+#define PALM_FOR_SCREEN_FLAG 0x0800
+#define PALM_DIRECT_COLOR_FLAG 0x0400
+#define PALM_INDIRECT_COLORMAP_FLAG 0x0200 /* or PALM_HAS_FOUR_BYTE_FIELD? */
+#define PALM_NO_DITHER_FLAG 0x0100
+
+#define PALM_COMPRESSION_SCANLINE 0x00 /* Scanline (Palm OS 2.0) */
+#define PALM_COMPRESSION_RLE 0x01 /* RLE (Palm OS 3.5) */
+#define PALM_COMPRESSION_PACKBITS 0x02 /* Packbits (Palm OS 4.0) */
+#define PALM_COMPRESSION_END 0x03
+#define PALM_COMPRESSION_BEST 0x64
+#define PALM_COMPRESSION_NONE 0xFF
+
+/*
+ 2 color (1 bit) palette
+*/
+static const unsigned char
+PalmPalette1[2][3] =
+ {
+ { 0, 0, 0},
+ {255,255,255}
+ };
+
+/*
+ 4 color (2 bit) palette
+*/
+static const unsigned char
+PalmPalette2[4][3] =
+ {
+ { 0, 0, 0},
+ { 85, 85, 85},
+ {170,170,170},
+ {255,255,255}
+ };
+
+/*
+ 16 color (4 bit) palette
+*/
+static const unsigned char
+PalmPalette4[16][3] =
+ {
+ { 0, 0, 0},
+ { 17, 17, 17},
+ { 34, 34, 34},
+ { 51, 51, 51},
+ { 68, 68, 68},
+ { 85, 85, 85},
+ {102,102,102},
+ {119,119,119},
+ {136,136,136},
+ {153,153,153},
+ {170,170,170},
+ {187,187,187},
+ {204,204,204},
+ {221,221,221},
+ {238,238,238},
+ {255,255,255}
+ };
+
+static const unsigned char
+PalmPalette8[256][3] =
+ {
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 128, 128 },
+ { 0, 128, 0 },
+ { 128, 0, 128 },
+ { 128, 0, 0 },
+ { 192, 192, 192 },
+ { 238, 238, 238 },
+ { 221, 221, 221 },
+ { 187, 187, 187 },
+ { 170, 170, 170 },
+ { 136, 136, 136 },
+ { 119, 119, 119 },
+ { 85, 85, 85 },
+ { 68, 68, 68 },
+ { 34, 34, 34 },
+ { 17, 17, 17 },
+ { 0, 51, 0 },
+ { 0, 102, 0 },
+ { 0, 153, 0 },
+ { 0, 204, 0 },
+ { 0, 255, 0 },
+ { 0, 0, 51 },
+ { 0, 51, 51 },
+ { 0, 102, 51 },
+ { 0, 153, 51 },
+ { 0, 204, 51 },
+ { 0, 255, 51 },
+ { 0, 0, 102 },
+ { 0, 51, 102 },
+ { 0, 102, 102 },
+ { 0, 153, 102 },
+ { 0, 204, 102 },
+ { 0, 255, 102 },
+ { 51, 0, 0 },
+ { 51, 51, 0 },
+ { 51, 102, 0 },
+ { 51, 153, 0 },
+ { 51, 204, 0 },
+ { 51, 255, 0 },
+ { 51, 0, 51 },
+ { 51, 51, 51 },
+ { 51, 102, 51 },
+ { 51, 153, 51 },
+ { 51, 204, 51 },
+ { 51, 255, 51 },
+ { 51, 0, 102 },
+ { 51, 51, 102 },
+ { 51, 102, 102 },
+ { 51, 153, 102 },
+ { 51, 204, 102 },
+ { 51, 255, 102 },
+ { 102, 0, 0 },
+ { 102, 51, 0 },
+ { 102, 102, 0 },
+ { 102, 153, 0 },
+ { 102, 204, 0 },
+ { 102, 255, 0 },
+ { 102, 0, 51 },
+ { 102, 51, 51 },
+ { 102, 102, 51 },
+ { 102, 153, 51 },
+ { 102, 204, 51 },
+ { 102, 255, 51 },
+ { 102, 0, 102 },
+ { 102, 51, 102 },
+ { 102, 102, 102 },
+ { 102, 153, 102 },
+ { 102, 204, 102 },
+ { 102, 255, 102 },
+ { 153, 0, 0 },
+ { 153, 51, 0 },
+ { 153, 102, 0 },
+ { 153, 153, 0 },
+ { 153, 204, 0 },
+ { 153, 255, 0 },
+ { 153, 0, 51 },
+ { 153, 51, 51 },
+ { 153, 102, 51 },
+ { 153, 153, 51 },
+ { 153, 204, 51 },
+ { 153, 255, 51 },
+ { 153, 0, 102 },
+ { 153, 51, 102 },
+ { 153, 102, 102 },
+ { 153, 153, 102 },
+ { 153, 204, 102 },
+ { 153, 255, 102 },
+ { 204, 0, 0 },
+ { 204, 51, 0 },
+ { 204, 102, 0 },
+ { 204, 153, 0 },
+ { 204, 204, 0 },
+ { 204, 255, 0 },
+ { 204, 0, 51 },
+ { 204, 51, 51 },
+ { 204, 102, 51 },
+ { 204, 153, 51 },
+ { 204, 204, 51 },
+ { 204, 255, 51 },
+ { 204, 0, 102 },
+ { 204, 51, 102 },
+ { 204, 102, 102 },
+ { 204, 153, 102 },
+ { 204, 204, 102 },
+ { 204, 255, 102 },
+ { 255, 0, 0 },
+ { 255, 51, 0 },
+ { 255, 102, 0 },
+ { 255, 153, 0 },
+ { 255, 204, 0 },
+ { 255, 255, 0 },
+ { 255, 0, 51 },
+ { 255, 51, 51 },
+ { 255, 102, 51 },
+ { 255, 153, 51 },
+ { 255, 204, 51 },
+ { 255, 255, 51 },
+ { 255, 0, 102 },
+ { 255, 51, 102 },
+ { 255, 102, 102 },
+ { 255, 153, 102 },
+ { 255, 204, 102 },
+ { 255, 255, 102 },
+ { 0, 0, 153 },
+ { 0, 51, 153 },
+ { 0, 102, 153 },
+ { 0, 153, 153 },
+ { 0, 204, 153 },
+ { 0, 255, 153 },
+ { 0, 0, 204 },
+ { 0, 51, 204 },
+ { 0, 102, 204 },
+ { 0, 153, 204 },
+ { 0, 204, 204 },
+ { 0, 255, 204 },
+ { 0, 0, 255 },
+ { 0, 51, 255 },
+ { 0, 102, 255 },
+ { 0, 153, 255 },
+ { 0, 204, 255 },
+ { 0, 255, 255 },
+ { 51, 0, 153 },
+ { 51, 51, 153 },
+ { 51, 102, 153 },
+ { 51, 153, 153 },
+ { 51, 204, 153 },
+ { 51, 255, 153 },
+ { 51, 0, 204 },
+ { 51, 51, 204 },
+ { 51, 102, 204 },
+ { 51, 153, 204 },
+ { 51, 204, 204 },
+ { 51, 255, 204 },
+ { 51, 0, 255 },
+ { 51, 51, 255 },
+ { 51, 102, 255 },
+ { 51, 153, 255 },
+ { 51, 204, 255 },
+ { 51, 255, 255 },
+ { 102, 0, 153 },
+ { 102, 51, 153 },
+ { 102, 102, 153 },
+ { 102, 153, 153 },
+ { 102, 204, 153 },
+ { 102, 255, 153 },
+ { 102, 0, 204 },
+ { 102, 51, 204 },
+ { 102, 102, 204 },
+ { 102, 153, 204 },
+ { 102, 204, 204 },
+ { 102, 255, 204 },
+ { 102, 0, 255 },
+ { 102, 51, 255 },
+ { 102, 102, 255 },
+ { 102, 153, 255 },
+ { 102, 204, 255 },
+ { 102, 255, 255 },
+ { 153, 0, 153 },
+ { 153, 51, 153 },
+ { 153, 102, 153 },
+ { 153, 153, 153 },
+ { 153, 204, 153 },
+ { 153, 255, 153 },
+ { 153, 0, 204 },
+ { 153, 51, 204 },
+ { 153, 102, 204 },
+ { 153, 153, 204 },
+ { 153, 204, 204 },
+ { 153, 255, 204 },
+ { 153, 0, 255 },
+ { 153, 51, 255 },
+ { 153, 102, 255 },
+ { 153, 153, 255 },
+ { 153, 204, 255 },
+ { 153, 255, 255 },
+ { 204, 0, 153 },
+ { 204, 51, 153 },
+ { 204, 102, 153 },
+ { 204, 153, 153 },
+ { 204, 204, 153 },
+ { 204, 255, 153 },
+ { 204, 0, 204 },
+ { 204, 51, 204 },
+ { 204, 102, 204 },
+ { 204, 153, 204 },
+ { 204, 204, 204 },
+ { 204, 255, 204 },
+ { 204, 0, 255 },
+ { 204, 51, 255 },
+ { 204, 102, 255 },
+ { 204, 153, 255 },
+ { 204, 204, 255 },
+ { 204, 255, 255 },
+ { 255, 0, 153 },
+ { 255, 51, 153 },
+ { 255, 102, 153 },
+ { 255, 153, 153 },
+ { 255, 204, 153 },
+ { 255, 255, 153 },
+ { 255, 0, 204 },
+ { 255, 51, 204 },
+ { 255, 102, 204 },
+ { 255, 153, 204 },
+ { 255, 204, 204 },
+ { 255, 255, 204 },
+ { 255, 0, 255 },
+ { 255, 51, 255 },
+ { 255, 102, 255 },
+ { 255, 153, 255 },
+ { 255, 204, 255 },
+ { 255, 255, 255 }
+ };
+/*
+ The 256 color system palette for Palm Computing Devices.
+*/
+static const unsigned char
+ PalmPalette[256][3] =
+ {
+ {255, 255,255},
+ {255, 204,255},
+ {255, 153,255},
+ {255, 102,255},
+ {255, 51,255},
+ {255, 0,255},
+ {255, 255,204},
+ {255, 204,204},
+ {255, 153,204},
+ {255, 102,204},
+ {255, 51,204},
+ {255, 0,204},
+ {255, 255,153},
+ {255, 204,153},
+ {255, 153,153},
+ {255, 102,153},
+ {255, 51,153},
+ {255, 0,153},
+ {204, 255,255},
+ {204, 204,255},
+ {204, 153,255},
+ {204, 102,255},
+ {204, 51,255},
+ {204, 0,255},
+ {204, 255,204},
+ {204, 204,204},
+ {204, 153,204},
+ {204, 102,204},
+ {204, 51,204},
+ {204, 0,204},
+ {204, 255,153},
+ {204, 204,153},
+ {204, 153,153},
+ {204, 102,153},
+ {204, 51,153},
+ {204, 0,153},
+ {153, 255,255},
+ {153, 204,255},
+ {153, 153,255},
+ {153, 102,255},
+ {153, 51,255},
+ {153, 0,255},
+ {153, 255,204},
+ {153, 204,204},
+ {153, 153,204},
+ {153, 102,204},
+ {153, 51,204},
+ {153, 0,204},
+ {153, 255,153},
+ {153, 204,153},
+ {153, 153,153},
+ {153, 102,153},
+ {153, 51,153},
+ {153, 0,153},
+ {102, 255,255},
+ {102, 204,255},
+ {102, 153,255},
+ {102, 102,255},
+ {102, 51,255},
+ {102, 0,255},
+ {102, 255,204},
+ {102, 204,204},
+ {102, 153,204},
+ {102, 102,204},
+ {102, 51,204},
+ {102, 0,204},
+ {102, 255,153},
+ {102, 204,153},
+ {102, 153,153},
+ {102, 102,153},
+ {102, 51,153},
+ {102, 0,153},
+ { 51, 255,255},
+ { 51, 204,255},
+ { 51, 153,255},
+ { 51, 102,255},
+ { 51, 51,255},
+ { 51, 0,255},
+ { 51, 255,204},
+ { 51, 204,204},
+ { 51, 153,204},
+ { 51, 102,204},
+ { 51, 51,204},
+ { 51, 0,204},
+ { 51, 255,153},
+ { 51, 204,153},
+ { 51, 153,153},
+ { 51, 102,153},
+ { 51, 51,153},
+ { 51, 0,153},
+ { 0, 255,255},
+ { 0, 204,255},
+ { 0, 153,255},
+ { 0, 102,255},
+ { 0, 51,255},
+ { 0, 0,255},
+ { 0, 255,204},
+ { 0, 204,204},
+ { 0, 153,204},
+ { 0, 102,204},
+ { 0, 51,204},
+ { 0, 0,204},
+ { 0, 255,153},
+ { 0, 204,153},
+ { 0, 153,153},
+ { 0, 102,153},
+ { 0, 51,153},
+ { 0, 0,153},
+ {255, 255,102},
+ {255, 204,102},
+ {255, 153,102},
+ {255, 102,102},
+ {255, 51,102},
+ {255, 0,102},
+ {255, 255, 51},
+ {255, 204, 51},
+ {255, 153, 51},
+ {255, 102, 51},
+ {255, 51, 51},
+ {255, 0, 51},
+ {255, 255, 0},
+ {255, 204, 0},
+ {255, 153, 0},
+ {255, 102, 0},
+ {255, 51, 0},
+ {255, 0, 0},
+ {204, 255,102},
+ {204, 204,102},
+ {204, 153,102},
+ {204, 102,102},
+ {204, 51,102},
+ {204, 0,102},
+ {204, 255, 51},
+ {204, 204, 51},
+ {204, 153, 51},
+ {204, 102, 51},
+ {204, 51, 51},
+ {204, 0, 51},
+ {204, 255, 0},
+ {204, 204, 0},
+ {204, 153, 0},
+ {204, 102, 0},
+ {204, 51, 0},
+ {204, 0, 0},
+ {153, 255,102},
+ {153, 204,102},
+ {153, 153,102},
+ {153, 102,102},
+ {153, 51,102},
+ {153, 0,102},
+ {153, 255, 51},
+ {153, 204, 51},
+ {153, 153, 51},
+ {153, 102, 51},
+ {153, 51, 51},
+ {153, 0, 51},
+ {153, 255, 0},
+ {153, 204, 0},
+ {153, 153, 0},
+ {153, 102, 0},
+ {153, 51, 0},
+ {153, 0, 0},
+ {102, 255,102},
+ {102, 204,102},
+ {102, 153,102},
+ {102, 102,102},
+ {102, 51,102},
+ {102, 0,102},
+ {102, 255, 51},
+ {102, 204, 51},
+ {102, 153, 51},
+ {102, 102, 51},
+ {102, 51, 51},
+ {102, 0, 51},
+ {102, 255, 0},
+ {102, 204, 0},
+ {102, 153, 0},
+ {102, 102, 0},
+ {102, 51, 0},
+ {102, 0, 0},
+ { 51, 255,102},
+ { 51, 204,102},
+ { 51, 153,102},
+ { 51, 102,102},
+ { 51, 51,102},
+ { 51, 0,102},
+ { 51, 255, 51},
+ { 51, 204, 51},
+ { 51, 153, 51},
+ { 51, 102, 51},
+ { 51, 51, 51},
+ { 51, 0, 51},
+ { 51, 255, 0},
+ { 51, 204, 0},
+ { 51, 153, 0},
+ { 51, 102, 0},
+ { 51, 51, 0},
+ { 51, 0, 0},
+ { 0, 255,102},
+ { 0, 204,102},
+ { 0, 153,102},
+ { 0, 102,102},
+ { 0, 51,102},
+ { 0, 0,102},
+ { 0, 255, 51},
+ { 0, 204, 51},
+ { 0, 153, 51},
+ { 0, 102, 51},
+ { 0, 51, 51},
+ { 0, 0, 51},
+ { 0, 255, 0},
+ { 0, 204, 0},
+ { 0, 153, 0},
+ { 0, 102, 0},
+ { 0, 51, 0},
+ { 17, 17, 17},
+ { 34, 34, 34},
+ { 68, 68, 68},
+ { 85, 85, 85},
+ {119, 119,119},
+ {136, 136,136},
+ {170, 170,170},
+ {187, 187,187},
+ {221, 221,221},
+ {238, 238,238},
+ {192, 192,192},
+ {128, 0, 0},
+ {128, 0,128},
+ { 0, 128, 0},
+ { 0, 128,128},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0}
+ };
+
+typedef struct _PalmHeader
+{
+ /* Image width */
+ magick_uint16_t columns;
+ /* Image height */
+ magick_uint16_t rows;
+ /* Number of bytes in each row of the image (must be even) */
+ magick_uint16_t bytes_per_row;
+ /* Flags:
+ 0x8000 : Compressed
+ 0x4000 : Has colormap
+ 0x2000 : Has transparent color
+ */
+ magick_uint16_t flags;
+ /* Number of bits per pixel */
+ magick_uint8_t bits_per_pixel;
+ /* Version:
+ 0: Palm OS 1
+ 1: Palm OS 3, no transparency, no RLE compression.
+ 2: Palm OS 3.5; transparency and RLE compression supported
+ */
+ magick_uint8_t version;
+ /* Offset (in four byte words) to start of next image frame. */
+ magick_uint16_t next_depth_offset;
+ /* Index of transparent color if transparent flag set */
+ magick_uint8_t transparent_index;
+ /* Compression type:
+ 0 : scanline
+ 1 : RLE
+ */
+ magick_uint8_t compression_type;
+ /* Reserved for future extensions (overlaps with V3 size and pixel_format) */
+ magick_uint8_t reserved[2];
+/* 16 byte mark */
+
+#if 0
+ /*
+ Version 3 parts below
+ */
+ /* Bitmap header size (usually 24) */
+ magick_uint8_t size;
+
+ /* Pixel format */
+ magick_uint8_t pixel_format;
+
+ /* Screen density (72, 108, 144, 216, 288) */
+ magick_uint16_t density;
+
+ /* Transparent value */
+ magick_uint32_t transparent_value;
+
+#endif
+
+} PalmHeader;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePALMImage(const ImageInfo *,Image *);
+
+void LogPALMHeader(const PalmHeader* palm_header)
+{
+ static const struct
+ {
+ unsigned short mask;
+ const char * text;
+ }
+ FlagDecodes[] =
+ {
+ { PALM_IS_COMPRESSED_FLAG, "COMPRESSED" },
+ { PALM_HAS_COLORMAP_FLAG, "COLORMAP" },
+ { PALM_HAS_TRANSPARENCY_FLAG, "TRANSPARENCY" },
+ { PALM_INDIRECT_BITMAP_FLAG, "INDIRECT_BITMAP" },
+ { PALM_FOR_SCREEN_FLAG, "FOR_SCREEN" },
+ { PALM_DIRECT_COLOR_FLAG, "DIRECT_COLOR" },
+ { PALM_INDIRECT_COLORMAP_FLAG,"INDIRECT_COLORMAP" },
+ { PALM_NO_DITHER_FLAG, "NO_DITHER" }
+ };
+
+ char flags[MaxTextExtent];
+ unsigned int i;
+
+ flags[0]='\0';
+
+ for (i=0; i < sizeof(FlagDecodes)/sizeof(FlagDecodes[0]); i++)
+ {
+ if (palm_header->flags & FlagDecodes[i].mask)
+ {
+ if (flags[0])
+ (void) strlcat(flags,", ",sizeof(flags));
+ (void) strlcat(flags,FlagDecodes[i].text,sizeof(flags));
+ }
+ }
+
+ (void) LogMagickEvent
+ (CoderEvent,GetMagickModule(),
+ "PALMHeader:\n"
+ " Columns: %u\n"
+ " Rows: %u\n"
+ " BytesPerRow: %u\n"
+ " Flags: 0x%04x (%s)\n"
+ " BitsPerPixel: %u\n"
+ " Version: %u\n"
+ " NextDepthOffset: %u\n"
+ " TransparentIndex: %u\n"
+ " Compression: %u (%s)",
+ palm_header->columns,
+ palm_header->rows,
+ palm_header->bytes_per_row,
+ palm_header->flags,
+ flags,
+ palm_header->bits_per_pixel,
+ palm_header->version,
+ palm_header->next_depth_offset,
+ palm_header->transparent_index,
+ palm_header->compression_type,
+ (palm_header->compression_type == PALM_COMPRESSION_SCANLINE ? "Scanline" :
+ (palm_header->compression_type == PALM_COMPRESSION_RLE ? "RLE" :
+ (palm_header->compression_type == PALM_COMPRESSION_PACKBITS ? "PackBits" :
+ (palm_header->compression_type == PALM_COMPRESSION_NONE ? "None" : "?")))));
+}
+
+static const unsigned char *
+GetPalmPaletteGivenBits(const unsigned int bits,
+ size_t *size)
+{
+ const unsigned char
+ *palette = (const unsigned char *) NULL;
+
+ *size=0;
+ switch (bits)
+ {
+ case 1:
+ palette=(const unsigned char *) PalmPalette1;
+ *size=sizeof(PalmPalette1);
+ break;
+ case 2:
+ palette=(const unsigned char *) PalmPalette2;
+ *size=sizeof(PalmPalette2);
+ break;
+ case 4:
+ palette=(const unsigned char *) PalmPalette4;
+ *size=sizeof(PalmPalette4);
+ break;
+ case 8:
+ palette=(const unsigned char *) PalmPalette8;
+ *size=sizeof(PalmPalette8);
+ break;
+ }
+ return palette;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P A L M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPALMImage reads an image of raw bites in LSB order and returns
+% it. It allocates the memory necessary for the new Image structure and
+% returns a pointer to the new image.
+%
+% The format of the ReadPALMImage method is:
+%
+% Image *ReadPALMImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPALMImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowPALMReaderException(code_,reason_,image_) \
+do { \
+ MagickFreeMemory(one_row); \
+ MagickFreeMemory(lastrow); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+static Image *ReadPALMImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ IndexPacket
+ index;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ PixelPacket
+ transpix;
+
+ register PixelPacket
+ *q;
+
+ unsigned char
+ *lastrow,
+ *one_row,
+ *ptr;
+
+ unsigned int
+ status;
+
+ unsigned int
+ i,
+ mask,
+ bit;
+
+ PalmHeader
+ palm_header;
+
+ unsigned short
+ color16;
+
+ /*
+ Open image file.
+ */
+ one_row=(unsigned char*) NULL;
+ lastrow=(unsigned char*) NULL;
+
+ (void) memset(&palm_header,0,sizeof(palm_header));
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowPALMReaderException(FileOpenError,UnableToOpenFile,image);
+
+ palm_header.columns = ReadBlobMSBShort(image);
+ palm_header.rows = ReadBlobMSBShort(image);
+ palm_header.bytes_per_row = ReadBlobMSBShort(image);
+ palm_header.flags = ReadBlobMSBShort(image);
+ palm_header.bits_per_pixel = ReadBlobByte(image);
+ palm_header.version = ReadBlobByte(image);
+ palm_header.next_depth_offset = ReadBlobMSBShort(image);
+ palm_header.transparent_index = ReadBlobByte(image);
+ palm_header.compression_type = ReadBlobByte(image);
+ if (ReadBlob(image,sizeof(palm_header.reserved),&palm_header.reserved) != 2)
+ ThrowPALMReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ if (image->logging)
+ LogPALMHeader(&palm_header);
+
+ /*
+ Validate version (0-2, 3 not supported yet)
+ */
+ if ((palm_header.version != 0U) &&
+ (palm_header.version != 1U) &&
+ (palm_header.version != 2U))
+ ThrowPALMReaderException(CorruptImageError,InvalidFileFormatVersion,image);
+
+ /*
+ Validate bits per pixel.
+ */
+ if ((palm_header.bits_per_pixel != 1) &&
+ (palm_header.bits_per_pixel != 2) &&
+ (palm_header.bits_per_pixel != 4) &&
+ (palm_header.bits_per_pixel != 8) &&
+ (palm_header.bits_per_pixel != 16))
+ ThrowPALMReaderException(CorruptImageError,UnrecognizedBitsPerPixel,image);
+
+ /*
+ Validate compression type.
+ */
+ if ((palm_header.compression_type != PALM_COMPRESSION_NONE) &&
+ (palm_header.compression_type != PALM_COMPRESSION_SCANLINE ) &&
+ (palm_header.compression_type != PALM_COMPRESSION_RLE))
+ ThrowPALMReaderException(CorruptImageError,UnrecognizedImageCompression,image);
+
+ /*
+ Validate flags.
+ */
+ if ((palm_header.version < 2) &&
+ ((palm_header.flags & PALM_HAS_TRANSPARENCY_FLAG) ||
+ ((palm_header.flags & PALM_IS_COMPRESSED_FLAG) &&
+ (palm_header.compression_type == PALM_COMPRESSION_RLE))
+ ))
+ ThrowPALMReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ /*
+ Validate bytes per row sanity checks
+ */
+ if (
+ (palm_header.bytes_per_row % 2)
+ ||
+ ((palm_header.bits_per_pixel == 16) &&
+ ((size_t) palm_header.columns >
+ (size_t) 2*palm_header.bytes_per_row))
+ ||
+ (((size_t) palm_header.bytes_per_row*8) <
+ ((size_t) palm_header.columns*palm_header.bits_per_pixel)))
+ ThrowPALMReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ image->columns = palm_header.columns;
+ image->rows = palm_header.rows;
+ image->depth = 8;
+
+ ClearPixelPacket(&transpix);
+ if (palm_header.bits_per_pixel == 16) /* Direct Color */
+ {
+ (void) ReadBlobByte(image); /* # of bits of red */
+ (void) ReadBlobByte(image); /* # of bits of green */
+ (void) ReadBlobByte(image); /* # of bits of blue */
+ (void) ReadBlobByte(image); /* reserved by Palm */
+ (void) ReadBlobByte(image); /* reserved by Palm */
+ transpix.red = (unsigned char) (ReadBlobByte(image) * MaxRGB / 31);
+ transpix.green = (unsigned char) (ReadBlobByte(image) * MaxRGB / 63);
+ transpix.blue = (unsigned char) (ReadBlobByte(image) * MaxRGB / 31);
+ }
+
+ /*
+ Initialize image colormap.
+ */
+ if ((palm_header.bits_per_pixel < 16) &&
+ !AllocateImageColormap(image,1L << palm_header.bits_per_pixel))
+ ThrowPALMReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ if ((palm_header.bits_per_pixel == 1) ||
+ (palm_header.bits_per_pixel == 2) ||
+ (palm_header.bits_per_pixel == 4) ||
+ ((palm_header.bits_per_pixel == 8) &&
+ !(palm_header.flags & PALM_HAS_COLORMAP_FLAG)))
+ {
+ const unsigned char
+ *palette;
+
+ size_t
+ size;
+
+ palette=GetPalmPaletteGivenBits(palm_header.bits_per_pixel,
+ &size);
+ if (palette)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Default %u bit palette of %"
+ MAGICK_SIZE_T_F "u bytes...",
+ palm_header.bits_per_pixel,
+ (MAGICK_SIZE_T) size);
+ for (index=0; index < image->colors; index++)
+ {
+ image->colormap[index].red=ScaleCharToQuantum(*palette++);
+ image->colormap[index].green=ScaleCharToQuantum(*palette++);
+ image->colormap[index].blue=ScaleCharToQuantum(*palette++);
+ }
+ }
+ }
+
+ else if (palm_header.bits_per_pixel == 8)
+ {
+ i = 0;
+ if (palm_header.flags & PALM_HAS_COLORMAP_FLAG)
+ {
+ unsigned int
+ count;
+
+ count = ReadBlobMSBShort(image);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Custom %u bit palette with %u colors (%"
+ MAGICK_SIZE_T_F "u bytes)...",
+ palm_header.bits_per_pixel,
+ count,
+ (MAGICK_SIZE_T) count*3);
+
+ if (count > image->colors)
+ ThrowPALMReaderException(CorruptImageError,ColormapExceedsColorsLimit,image);
+
+ /*
+ Is palette really written reversed?
+ */
+ for (i = 0; i < count; i++)
+ {
+ /* unsigned int r, g, b; */
+ (void) ReadBlobByte(image);
+ index=255 - i;
+ VerifyColormapIndex(image,index);
+#if 0
+ r=ReadBlobByte(image);
+ g=ReadBlobByte(image);
+ b=ReadBlobByte(image);
+ fprintf(stdout,"{ %3u, %3u, %3u },\n", r, g, b);
+#endif
+#if 1
+ image->colormap[index].red = ScaleCharToQuantum(ReadBlobByte(image));
+ image->colormap[index].green = ScaleCharToQuantum(ReadBlobByte(image));
+ image->colormap[index].blue = ScaleCharToQuantum(ReadBlobByte(image));
+#endif
+ if (EOFBlob(image))
+ ThrowPALMReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ /*
+ Initialize remaining range ???.
+ */
+ for (; i < (1U << palm_header.bits_per_pixel); i++)
+ {
+ index=255 - i;
+ image->colormap[index].red = 0;
+ image->colormap[index].green = 0;
+ image->colormap[index].blue = 0;
+ }
+ }
+#if 0
+ for (; i < (1U << palm_header.bits_per_pixel); i++)
+ {
+ index=255 - i;
+ VerifyColormapIndex(image,index);
+ image->colormap[index].red = ScaleCharToQuantum(PalmPalette[i][0]);
+ image->colormap[index].green = ScaleCharToQuantum(PalmPalette[i][1]);
+ image->colormap[index].blue = ScaleCharToQuantum(PalmPalette[i][2]);
+ }
+#endif
+#if 0
+ for (i=0; i < (1U << palm_header.bits_per_pixel); i++)
+ {
+ fprintf(stdout,"{ %3u, %3u, %3u },\n",
+ ScaleQuantumToChar(image->colormap[i].red),
+ ScaleQuantumToChar(image->colormap[i].green),
+ ScaleQuantumToChar(image->colormap[i].blue));
+ }
+#endif
+ }
+
+image->depth = 8;
+#if 0
+ if (palm_header.bits_per_pixel < 16)
+ {
+ image->storage_class = PseudoClass;
+ image->depth = 8;
+ }
+ else
+ {
+ image->storage_class = DirectClass;
+ image->depth = 8;
+ }
+#endif
+
+#if 0
+ if (image->storage_class == PseudoClass)
+ for (i=0; i < image->colors; i++)
+ fprintf(stderr,"%03u: %3u, %3u, %3u\n",
+ i,
+ ScaleQuantumToChar(image->colormap[i].red),
+ ScaleQuantumToChar(image->colormap[i].green),
+ ScaleQuantumToChar(image->colormap[i].blue));
+#endif
+
+ image->compression = NoCompression;
+ if (palm_header.flags & PALM_IS_COMPRESSED_FLAG)
+ {
+ if (palm_header.compression_type == PALM_COMPRESSION_RLE)
+ image->compression = RLECompression;
+ else if (palm_header.compression_type == PALM_COMPRESSION_SCANLINE)
+ image->compression = FaxCompression;
+ }
+
+ /*
+ Skip reading pixels if ping requested.
+ */
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowPALMReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ one_row = MagickAllocateMemory(unsigned char *,Max(palm_header.bytes_per_row,2*image->columns));
+ if (one_row == (unsigned char *) NULL)
+ ThrowPALMReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (palm_header.compression_type == PALM_COMPRESSION_SCANLINE)
+ lastrow = MagickAllocateMemory(unsigned char *,Max(palm_header.bytes_per_row,2*image->columns));
+
+ mask = (1l << palm_header.bits_per_pixel) - 1;
+
+ for (y = 0; y < (long) image->rows; y++)
+ {
+ if (palm_header.flags & PALM_IS_COMPRESSED_FLAG)
+ {
+ int
+ count,
+ byte;
+
+ if (palm_header.compression_type == PALM_COMPRESSION_RLE)
+ {
+ for (i = 0; i < palm_header.bytes_per_row; )
+ {
+ if ((count = ReadBlobByte(image)) == EOF)
+ break;
+ count = Min((unsigned int) count, (unsigned int) palm_header.bytes_per_row-i);
+ if (count == 0)
+ break;
+ if ((byte = ReadBlobByte(image)) == EOF)
+ break;
+ (void) memset(one_row + i, byte, count);
+ i += count;
+ }
+ }
+ else
+ if (palm_header.compression_type == PALM_COMPRESSION_SCANLINE)
+ {
+ for (i = 0; i < (long) palm_header.bytes_per_row; i += 8)
+ {
+ if ((count = ReadBlobByte(image)) == EOF)
+ break;
+ byte = Min(palm_header.bytes_per_row - i, 8);
+ for (bit = 0; bit < (unsigned int) byte; bit++)
+ {
+ if ((y == 0) || (count & 0xff & (1 << (7 - bit))))
+ {
+ int
+ c;
+
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ one_row[i + bit] = c & 0xff;
+ }
+ else
+ {
+ one_row[i + bit] = lastrow[i + bit];
+ }
+ }
+ }
+ (void) memcpy(lastrow, one_row, palm_header.bytes_per_row);
+ }
+ }
+ else
+ {
+ (void) ReadBlob(image, palm_header.bytes_per_row, one_row);
+ }
+
+ if (EOFBlob(image))
+ ThrowPALMReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ ptr = one_row;
+ q = SetImagePixels(image, 0, y, image->columns, 1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ if (palm_header.bits_per_pixel == 16)
+ {
+ if (image->columns > 2*palm_header.bytes_per_row)
+ ThrowPALMReaderException(CorruptImageError,CorruptImage,image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ color16 = (*ptr++ << 8);
+ color16 |= *ptr++;
+ q->red = (MaxRGB*((color16 >> 11) & 0x1f))/0x1f;
+ q->green = (MaxRGB*((color16 >> 5) & 0x3f))/0x3f;
+ q->blue = (MaxRGB*((color16 >> 0) & 0x1f))/0x1f;
+ q->opacity = OpaqueOpacity;
+ q++;
+ }
+ }
+ else
+ {
+ bit = 8 - palm_header.bits_per_pixel;
+ for (x = 0; x < (long) image->columns; x++)
+ {
+ if ((unsigned int) (ptr - one_row) >= palm_header.bytes_per_row)
+ ThrowPALMReaderException(CorruptImageError,CorruptImage,image);
+ index =(IndexPacket) (mask - (((*ptr) & (mask << bit)) >> bit));
+ VerifyColormapIndex(image,index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ if (!bit)
+ {
+ ++ptr;
+ bit = 8 - palm_header.bits_per_pixel;
+ }
+ else
+ {
+ bit -= palm_header.bits_per_pixel;
+ }
+ }
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+
+ if (palm_header.flags & PALM_HAS_TRANSPARENCY_FLAG)
+ {
+ if (image->storage_class == PseudoClass)
+ {
+ index = mask - palm_header.transparent_index;
+ VerifyColormapIndex(image,index);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Index %u rgb(%u,%u,%u) set transparent",
+ index,
+ image->colormap[index].red,
+ image->colormap[index].green,
+ image->colormap[index].blue);
+ image->colormap[index].opacity=TransparentOpacity;
+ SyncImage(image);
+ image->matte=MagickTrue;
+ image->storage_class=DirectClass;
+ }
+ else
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "rgb(%u,%u,%u) set transparent",
+ transpix.red,
+ transpix.green,
+ transpix.blue);
+ (void) TransparentImage(image, transpix, TransparentOpacity);
+ }
+ }
+
+ MagickFreeMemory(one_row);
+ MagickFreeMemory(lastrow);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P A L M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPALMImage adds attributes for the PALM image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPALMImage method is:
+%
+% RegisterPALMImage(void)
+%
+*/
+ModuleExport void RegisterPALMImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PALM");
+ entry->decoder=ReadPALMImage;
+ entry->encoder=WritePALMImage;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Palm pixmap";
+ entry->module="PALM";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P A L M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPALMImage removes format registrations made by the
+% PALM module from the list of supported formats.
+%
+% The format of the UnregisterPALMImage method is:
+%
+% UnregisterPALMImage(void)
+%
+*/
+ModuleExport void UnregisterPALMImage(void)
+{
+ (void) UnregisterMagickInfo("PALM");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P A L M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePALMImage writes an image of raw bits in LSB order to a file.
+%
+% The format of the WritePALMImage method is:
+%
+% unsigned int WritePALMImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePALMImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+#if 1
+static Image *
+CreatePALMMapImage(const unsigned int depth)
+{
+ Image
+ *map_image;
+
+ PixelPacket
+ *q;
+
+ const unsigned char
+ *palette;
+
+ size_t
+ size;
+
+ unsigned int
+ colors,
+ index;
+
+ MagickPassFail
+ status;
+
+ status=MagickFail;
+ map_image = (Image *) NULL;
+ do
+ {
+ /*
+ Allocate image
+ */
+ if ((map_image=AllocateImage((const ImageInfo *) NULL)) ==
+ (Image *) NULL)
+ break;
+ /*
+ Allocate and initialize map image for depth.
+ */
+ if ((palette=GetPalmPaletteGivenBits(depth,&size)) ==
+ (const unsigned char *) NULL)
+ break;
+ colors=(1U << depth);
+ map_image->columns=colors;
+ map_image->rows=1;
+ if(!AllocateImageColormap(map_image,colors))
+ break;
+ if ((q=SetImagePixels(map_image, 0, 0, map_image->columns, 1)) ==
+ (PixelPacket *) NULL)
+ break;
+ for (index=0; index < map_image->colors; index++)
+ {
+ map_image->colormap[index].red=ScaleCharToQuantum(*palette++);
+ map_image->colormap[index].green=ScaleCharToQuantum(*palette++);
+ map_image->colormap[index].blue=ScaleCharToQuantum(*palette++);
+ q[index]=map_image->colormap[index];
+ }
+ if (!SyncImagePixels(map_image))
+ break;
+ status=MagickPass;
+ break;
+ } while(1);
+
+ if ((status != MagickPass) && (map_image != (Image *) NULL))
+ {
+ DestroyImage(map_image);
+ map_image = (Image *) NULL;
+ }
+
+ return map_image;
+}
+static Image *
+OptimizePALMImage(const ImageInfo *image_info,
+ Image *image,
+ magick_uint16_t *palm_flags,
+ magick_uint8_t *palm_bits_per_pixel)
+{
+ Image
+ *map_image = (Image *) NULL,
+ *palm_image = (Image *) NULL;
+
+ double
+ normalized_maximum_error = 1.0/230.0;
+
+ unsigned int
+ depth;
+
+ MagickPassFail
+ status = MagickFail;
+
+ if ((image_info->type == UndefinedType) ||
+ (image_info->type == BilevelType) ||
+ (image_info->type == GrayscaleType) ||
+ (image_info->type == PaletteType) ||
+ (image_info->type == OptimizeType))
+ {
+ for (depth = 1; depth <= 8; depth *= 2)
+ {
+ fprintf(stderr,"Depth %u\n",depth);
+ /*
+ Get PALM map image for depth.
+ */
+ if ((map_image=CreatePALMMapImage(depth)) == (Image *) NULL)
+ break;
+
+ /*
+ Clone optimized image
+ */
+ if ((palm_image=CloneImage(image,0,0,True,&image->exception))
+ == (Image *) NULL)
+ break;
+
+ /*
+ Make sure that image is in an RGB type space.
+ */
+ if (!TransformColorspace(palm_image,RGBColorspace))
+ break;
+
+ /*
+ Map optimize image to colormap without dithering.
+ */
+ if (!MapImage(palm_image, map_image, False))
+ break;
+
+ /*
+ Check to see if result is within error limits. If not, then
+ loop to next depth. Function returns MagickTrue if images are
+ exactly the same so return value does not reflect error.
+ */
+ (void) IsImagesEqual(palm_image,image);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Depth %u:\n"
+ " Mean error: %g\n"
+ " Normalized Mean Error: %g\n"
+ " Normalized Maximum Error: %g",
+ depth,
+ palm_image->error.mean_error_per_pixel,
+ palm_image->error.normalized_mean_error,
+ palm_image->error.normalized_maximum_error);
+
+ if (!((image_info->type == BilevelType) && (depth == 1)) &&
+ !((image_info->type == GrayscaleType) && (depth == 4)))
+ {
+ if (palm_image->error.normalized_maximum_error >
+ normalized_maximum_error)
+ {
+ DestroyImage(map_image);
+ map_image=(Image *) NULL;
+
+ DestroyImage(palm_image);
+ palm_image = (Image *) NULL;
+
+ continue;
+ }
+ }
+
+ /*
+ Replace colormap in optimize image with map image palette.
+ */
+ if (!ReplaceImageColormap(palm_image,map_image->colormap,
+ map_image->colors))
+ break;
+
+ DestroyImage(map_image);
+ map_image=(Image *) NULL;
+
+ /*
+ We achieved success!
+ */
+ *palm_bits_per_pixel=depth;
+ status=MagickPass;
+ break;
+ }
+
+ if (map_image != (Image *) NULL)
+ {
+ DestroyImage(map_image);
+ map_image=(Image *) NULL;
+ }
+
+ if ((status != MagickPass) && (palm_image != (Image *) NULL))
+ {
+ DestroyImage(palm_image);
+ palm_image = (Image *) NULL;
+ }
+
+ /*
+ If we were unable to achieve the desired quality using a standard
+ PALM colormap, then use simple quantization to produce a custom
+ colormap.
+ */
+ if (palm_image == (Image *) NULL)
+ {
+ do
+ {
+ QuantizeInfo
+ quantize_info;
+
+ if ((palm_image=CloneImage(image,0,0,True,&image->exception))
+ == (Image *) NULL)
+ break;
+
+ /*
+ Make sure that image is in an RGB type space.
+ */
+ if (!TransformColorspace(palm_image,RGBColorspace))
+ break;
+
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.number_colors=256;
+ quantize_info.dither=MagickFalse;
+ quantize_info.measure_error=MagickTrue;
+ if (!QuantizeImage(&quantize_info, palm_image))
+ break;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Custom Colormap:\n"
+ " Mean error: %g\n"
+ " Normalized Mean Error: %g\n"
+ " Normalized Maximum Error: %g",
+ palm_image->error.mean_error_per_pixel,
+ palm_image->error.normalized_mean_error,
+ palm_image->error.normalized_maximum_error);
+
+ if (palm_image->error.normalized_maximum_error >
+ normalized_maximum_error)
+ {
+ DestroyImage(map_image);
+ map_image=(Image *) NULL;
+
+ DestroyImage(palm_image);
+ palm_image = (Image *) NULL;
+
+ break;
+ }
+
+ /*
+ We achieved success!
+ */
+ *palm_bits_per_pixel=8;
+ *palm_flags |= PALM_HAS_COLORMAP_FLAG;
+ status=MagickPass;
+
+ break;
+ } while (1);
+ }
+ } /* End of colormapped optimizations */
+
+ /*
+ If we *still* were unable to achieve the desired quality using a
+ custom colormap (or were not allowed), then return a DirectClass
+ image.
+ */
+ if (palm_image == (Image *) NULL)
+ {
+ do
+ {
+ if ((palm_image=CloneImage(image,0,0,True,&image->exception))
+ == (Image *) NULL)
+ break;
+
+ /*
+ Make sure that image is in an RGB type space.
+ */
+ if (!TransformColorspace(palm_image,RGBColorspace))
+ break;
+
+
+ if (palm_image->storage_class == PseudoClass)
+ {
+ SyncImage(palm_image);
+ palm_image->storage_class=DirectClass;
+ }
+
+ /*
+ We achieved success!
+ */
+ *palm_bits_per_pixel=16;
+ *palm_flags |= PALM_DIRECT_COLOR_FLAG;
+ status=MagickPass;
+
+ break;
+ } while (1);
+ }
+
+ return palm_image;
+}
+#endif
+static unsigned int WritePALMImage(const ImageInfo *image_info,Image *image)
+{
+ int
+ y;
+
+ Image
+ *palm_image;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ PixelPacket
+ transpix;
+
+ register PixelPacket
+ *p;
+
+ unsigned char
+ bit,
+ byte,
+ color,
+ *lastrow = 0,
+ *one_row = 0,
+ *ptr,
+ version = 0;
+
+ unsigned int
+ transparentIndex = 0,
+ status;
+
+ unsigned int
+ count = 0,
+ bits_per_pixel,
+ bytes_per_row;
+
+ unsigned short
+ color16;
+
+ ImageCharacteristics
+ characteristics;
+
+ PalmHeader
+ palm_header;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Dimensions: %lux%lu",
+ image->columns,image->rows);
+
+ (void) memset(&palm_header,0,sizeof(palm_header));
+
+ /*
+ Open output image file.
+ */
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Characteristics:\n"
+ " cmyk : %u\n"
+ " grayscale : %u\n"
+ " monochrome : %u\n"
+ " opaque : %u\n"
+ " palette : %u",
+ characteristics.cmyk,
+ characteristics.grayscale,
+ characteristics.monochrome,
+ characteristics.opaque,
+ characteristics.palette);
+
+ /*
+ Prepare PALM image, setting flags and bits-per-pixel
+ appropriately.
+ */
+ palm_image=OptimizePALMImage(image_info,image,
+ &palm_header.flags,
+ &palm_header.bits_per_pixel);
+ if (palm_image == (Image *) NULL)
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+ bits_per_pixel=palm_header.bits_per_pixel;
+
+ /* Write Tbmp header. */
+ palm_header.columns=palm_image->columns;
+ palm_header.rows=palm_image->rows;
+ /* bytes per row - always a word boundary */
+ bytes_per_row=((palm_image->columns+(16/bits_per_pixel-1))/(16/bits_per_pixel))*2;
+ palm_header.bytes_per_row=bytes_per_row;
+ if ((palm_image->compression == RLECompression) ||
+ (palm_image->compression == FaxCompression))
+ palm_header.flags|=PALM_IS_COMPRESSED_FLAG;
+ if (((bytes_per_row*palm_image->rows) > 48000) &&
+ (palm_header.flags & PALM_IS_COMPRESSED_FLAG))
+ palm_header.flags|=PALM_INDIRECT_COLORMAP_FLAG;
+ if (bits_per_pixel > 1)
+ version=1;
+ if ((palm_image->compression == RLECompression) ||
+ (palm_image->compression == FaxCompression))
+ version=2;
+ palm_header.version=version;
+ palm_header.next_depth_offset=0;
+ palm_header.transparent_index=transparentIndex;
+ if (palm_image->compression == RLECompression)
+ palm_header.compression_type=PALM_COMPRESSION_RLE;
+ else
+ if (palm_image->compression == FaxCompression)
+ palm_header.compression_type=PALM_COMPRESSION_SCANLINE;
+ else
+ palm_header.compression_type=PALM_COMPRESSION_NONE;
+ (void) memset(palm_header.reserved,0,sizeof(palm_header.reserved));
+
+ /*
+ Log and write out header.
+ */
+ if (palm_image->logging)
+ LogPALMHeader(&palm_header);
+
+ (void) WriteBlobMSBShort(image,palm_header.columns); /* width */
+ (void) WriteBlobMSBShort(image,palm_header.rows ); /* height */
+ (void) WriteBlobMSBShort(image,palm_header.bytes_per_row);
+ (void) WriteBlobMSBShort(image, palm_header.flags);
+ (void) WriteBlobByte(image, palm_header.bits_per_pixel);
+ (void) WriteBlobByte(image,palm_header.version);
+ (void) WriteBlobMSBShort(image,palm_header.next_depth_offset); /* offset */
+ (void) WriteBlobByte(image,palm_header.transparent_index);
+ (void) WriteBlobByte(image,palm_header.compression_type);
+ (void) WriteBlob(image, sizeof(palm_header.reserved), palm_header.reserved);
+
+ if (bits_per_pixel == 16)
+ {
+ (void) WriteBlobByte(image, 5); /* # of bits of red */
+ (void) WriteBlobByte(image, 6); /* # of bits of green */
+ (void) WriteBlobByte(image, 5); /* # of bits of blue */
+ (void) WriteBlobByte(image, 0); /* reserved by Palm */
+ (void) WriteBlobMSBLong(image, 0); /* no transparent color, YET */
+ }
+ else if (palm_header.flags & PALM_HAS_COLORMAP_FLAG) /* Write out colormap */
+ {
+ (void) WriteBlobMSBShort(image, palm_image->colors);
+ for (count = 0; count < palm_image->colors; count++)
+ {
+ (void) WriteBlobByte(image, count);
+ (void) WriteBlobByte(image, ScaleQuantumToChar(palm_image->colormap[count].red));
+ (void) WriteBlobByte(image, ScaleQuantumToChar(palm_image->colormap[count].green));
+ (void) WriteBlobByte(image, ScaleQuantumToChar(palm_image->colormap[count].blue));
+ }
+ }
+
+ if (palm_image->compression == FaxCompression)
+ lastrow = MagickAllocateMemory(unsigned char *,bytes_per_row);
+ one_row = MagickAllocateMemory(unsigned char *,bytes_per_row);
+ if (one_row == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ ClearPixelPacket(&transpix);
+ for (y=0; y < (int) palm_image->rows; y++)
+ {
+ ptr = one_row;
+ (void) memset(ptr, 0, bytes_per_row);
+ p=GetImagePixels(palm_image,0,y,palm_image->columns,1);
+ if (p == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(palm_image);
+ if (bits_per_pixel == 16)
+ {
+ for (x=0; x < (int) palm_image->columns; x++)
+ {
+ color16 = (unsigned short) (((p->red * 31) / MaxRGB) << 11
+ | ((p->green * 63) / MaxRGB) << 5
+ | ((p->blue * 31) / MaxRGB));
+ if (p->opacity == TransparentOpacity)
+ {
+ transpix.red = p->red;
+ transpix.green = p->green;
+ transpix.blue = p->blue;
+ transpix.opacity = p->opacity;
+ palm_header.flags |= PALM_HAS_TRANSPARENCY_FLAG;
+ }
+ *ptr++ = (color16 >> 8) &0xff;
+ *ptr++ = color16 & 0xff;
+ p++;
+ }
+ }
+ else
+ {
+ byte = 0x00;
+ bit = (unsigned char) (8 - bits_per_pixel);
+ for (x=0; x < (int) palm_image->columns; x++)
+ {
+ if (bits_per_pixel < 8) /* Make sure we use the entire colorspace for bits_per_pixel */
+ color = (unsigned char) (indexes[x] * ((1 << bits_per_pixel) - 1) /
+ (palm_image->colors - 1));
+ else
+ color = (unsigned char) indexes[x];
+ byte |= color << bit;
+ if (bit == 0)
+ {
+ *ptr++ = byte;
+ byte = 0x00;
+ bit = (unsigned char) (8 - bits_per_pixel);
+ }
+ else
+ {
+ bit -= bits_per_pixel;
+ }
+ }
+ if ((palm_image->columns % (8 / bits_per_pixel)) != 0) /* Handle case of partial byte */
+ *ptr++ = byte;
+ }
+
+ if (palm_image->compression == RLECompression)
+ {
+ x = 0;
+ while (x < (long) bytes_per_row)
+ {
+ byte = one_row[x];
+ count = 1;
+ while (one_row[++x] == byte && count < 255 && x < (long) bytes_per_row)
+ count++;
+ (void) WriteBlobByte(image, count);
+ (void) WriteBlobByte(image, byte);
+ }
+ }
+ else
+ if (palm_image->compression == FaxCompression) /* Scanline really */
+ {
+ char tmpbuf[8];
+ char *tptr;
+
+ for (x = 0; x < (long) bytes_per_row; x += 8)
+ {
+ tptr = tmpbuf;
+ for (bit = 0, byte = 0; bit < Min(8, bytes_per_row - x); bit++)
+ {
+ if ((y == 0) || (lastrow[x + bit] != one_row[x + bit]))
+ {
+ byte |= (1 << (7 - bit));
+ *tptr++ = one_row[x + bit];
+ }
+ }
+ (void) WriteBlobByte(image, byte);
+ (void) WriteBlob(image, tptr - tmpbuf, tmpbuf);
+ }
+ (void) memcpy (lastrow, one_row, bytes_per_row);
+ }
+ else
+ {
+ (void) WriteBlob(image, bytes_per_row, one_row);
+ }
+ }
+
+ /*
+ Update file header in the case of when compression is used, or the
+ image used a transparent color.
+ */
+ if (bits_per_pixel < 8 && palm_header.flags & PALM_IS_COMPRESSED_FLAG)
+ {
+ count = (unsigned long) GetBlobSize(image); /* compressed size */
+ }
+
+ if (palm_header.flags & PALM_HAS_TRANSPARENCY_FLAG)
+ {
+ (void) SeekBlob(image, 6, SEEK_SET);
+ (void) WriteBlobMSBShort(image, palm_header.flags);
+ (void) SeekBlob(image, 12, SEEK_SET);
+ (void) WriteBlobByte(image,transparentIndex); /* trans index */
+
+ if (bits_per_pixel == 16)
+ {
+ (void) SeekBlob(image, 20, SEEK_SET);
+ (void) WriteBlobByte(image, 0); /* reserved by Palm */
+ (void) WriteBlobByte(image, (transpix.red * 31) / MaxRGB);
+ (void) WriteBlobByte(image, (transpix.green * 63) / MaxRGB);
+ (void) WriteBlobByte(image, (transpix.blue * 31) / MaxRGB);
+ }
+ (void) SeekBlob(image, 16, SEEK_SET);
+ if (palm_header.flags & PALM_INDIRECT_COLORMAP_FLAG)
+ (void) WriteBlobMSBLong(image, count - 16);
+ else
+ (void) WriteBlobMSBShort(image, count - 16);
+ }
+
+ CloseBlob(image);
+ DestroyImage(palm_image);
+ MagickFreeMemory(one_row);
+ MagickFreeMemory(lastrow);
+ return(True);
+}
diff --git a/coders/pcd.c b/coders/pcd.c
new file mode 100644
index 0000000..70c0600
--- /dev/null
+++ b/coders/pcd.c
@@ -0,0 +1,1154 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP CCCC DDDD %
+% P P C D D %
+% PPPP C D D %
+% P C D D %
+% P CCCC DDDD %
+% %
+% %
+% Read/Write Photo CD Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/decorate.h"
+#include "magick/gem.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/montage.h"
+#include "magick/resize.h"
+#include "magick/shear.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePCDImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U p s a m p l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Upsample() doubles the size of the image.
+%
+% The format of the Upsample method is:
+%
+% void Upsample(const unsigned long width,const unsigned long height,
+% const unsigned long scaled_width,unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o width,height: Unsigned values representing the width and height of
+% the image pixel array.
+%
+% o scaled_width: Specifies the final width of the upsampled pixel array.
+%
+% o pixels: An unsigned char containing the pixel data. On output the
+% upsampled pixels are returned here.
+%
+%
+*/
+static void Upsample(const unsigned long width,const unsigned long height,
+ const unsigned long scaled_width,unsigned char *pixels)
+{
+ register long
+ x,
+ y;
+
+ register unsigned char
+ *p,
+ *q,
+ *r;
+
+ /*
+ Create a new image that is a integral size greater than an existing one.
+ */
+ assert(pixels != (unsigned char *) NULL);
+ for (y=0; y < (long) height; y++)
+ {
+ p=pixels+(height-1-y)*scaled_width+(width-1);
+ q=pixels+((height-1-y) << 1)*scaled_width+((width-1) << 1);
+ *q=(*p);
+ *(q+1)=(*(p));
+ for (x=1; x < (long) width; x++)
+ {
+ p--;
+ q-=2;
+ *q=(*p);
+ *(q+1)=(unsigned char) ((((long) *p)+((long) *(p+1))+1) >> 1);
+ }
+ }
+ for (y=0; y < (long) (height-1); y++)
+ {
+ p=pixels+(y << 1)*scaled_width;
+ q=p+scaled_width;
+ r=q+scaled_width;
+ for (x=0; x < (long) (width-1); x++)
+ {
+ *q=(unsigned char) ((((long) *p)+((long) *r)+1) >> 1);
+ *(q+1)=(unsigned char)
+ ((((long) *p)+((long) *(p+2))+((long) *r)+((long) *(r+2))+2) >> 2);
+ q+=2;
+ p+=2;
+ r+=2;
+ }
+ *q++=(unsigned char) ((((long) *p++)+((long) *r++)+1) >> 1);
+ *q++=(unsigned char) ((((long) *p++)+((long) *r++)+1) >> 1);
+ }
+ p=pixels+(2*height-2)*scaled_width;
+ q=pixels+(2*height-1)*scaled_width;
+ (void) memcpy(q,p,2*width);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DecodeImage recovers the Huffman encoded luminance and chrominance
+% deltas.
+%
+% The format of the DecodeImage method is:
+%
+% static unsigned int DecodeImage(Image *image,unsigned char *luma,
+% unsigned char *chroma1,unsigned char *chroma2)
+%
+% A description of each parameter follows:
+%
+% o status: Method DecodeImage returns True if all the deltas are
+% recovered without error, otherwise False.
+%
+% o image: The address of a structure of type Image.
+%
+% o luma: The address of a character buffer that contains the
+% luminance information.
+%
+% o chroma1: The address of a character buffer that contains the
+% chrominance information.
+%
+% o chroma2: The address of a character buffer that contains the
+% chrominance information.
+%
+%
+%
+*/
+#define IsSync ((sum & 0xffffff00) == 0xfffffe00)
+#define DecodeImageText "[%s] PCD decode image..."
+#define PCDGetBits(n) \
+{ \
+ sum=(sum << n) & 0xffffffff; \
+ bits-=n; \
+ while (bits <= 24) \
+ { \
+ if (p >= (buffer+0x800)) \
+ { \
+ (void) ReadBlob(image,0x800,(char *) buffer); \
+ p=buffer; \
+ } \
+ sum|=((unsigned int) (*p) << (24-bits)); \
+ bits+=8; \
+ p++; \
+ } \
+ if (EOFBlob(image)) \
+ break; \
+}
+static unsigned int DecodeImage(Image *image,unsigned char *luma,
+ unsigned char *chroma1,unsigned char *chroma2)
+{
+ typedef struct PCDTable
+ {
+ unsigned int
+ length,
+ sequence;
+
+ unsigned int
+ mask;
+
+ unsigned char
+ key;
+ } PCDTable;
+
+ long
+ count,
+ quantum;
+
+ PCDTable
+ *pcd_table[3];
+
+ register long
+ i,
+ j;
+
+ register PCDTable
+ *r;
+
+ register unsigned char
+ *p,
+ *q;
+
+ size_t
+ length;
+
+ unsigned char
+ *buffer;
+
+ unsigned int
+ bits,
+ plane,
+ pcd_length[3],
+ row,
+ sum;
+
+ /*
+ Initialize Huffman tables.
+ */
+ assert(image != (const Image *) NULL);
+ assert(luma != (unsigned char *) NULL);
+ assert(chroma1 != (unsigned char *) NULL);
+ assert(chroma2 != (unsigned char *) NULL);
+ buffer=MagickAllocateMemory(unsigned char *,0x800);
+ if (buffer == (unsigned char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ sum=0;
+ bits=32;
+ p=buffer+0x800;
+ for (i=0; i < (image->columns > 1536 ? 3 : 1); i++)
+ {
+ PCDGetBits(8);
+ length=(sum & 0xff)+1;
+ pcd_table[i]=MagickAllocateMemory(PCDTable *,length*sizeof(PCDTable));
+ if (pcd_table[i] == (PCDTable *) NULL)
+ {
+ MagickFreeMemory(buffer);
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL)
+ }
+ r=pcd_table[i];
+ for (j=0; j < (long) length; j++)
+ {
+ PCDGetBits(8);
+ r->length=(sum & 0xff)+1;
+ if (r->length > 16)
+ {
+ MagickFreeMemory(buffer);
+ return(False);
+ }
+ PCDGetBits(16);
+ r->sequence=(sum & 0xffff) << 16;
+ PCDGetBits(8);
+ r->key=(unsigned char) (sum & 0xff);
+ r->mask=(~((((unsigned int) 1) << (32-r->length))-1));
+ r++;
+ }
+ pcd_length[i]=(unsigned int) length;
+ }
+ /*
+ Search for Sync byte.
+ */
+ for (i=0; i < 1; i++)
+ PCDGetBits(16);
+ for (i=0; i < 1; i++)
+ PCDGetBits(16);
+ while ((sum & 0x00fff000) != 0x00fff000)
+ PCDGetBits(8);
+ while (!IsSync)
+ PCDGetBits(1);
+ /*
+ Recover the Huffman encoded luminance and chrominance deltas.
+ */
+ count=0;
+ length=0;
+ plane=0;
+ row=0;
+ q=luma;
+ for ( ; ; )
+ {
+ if (IsSync)
+ {
+ /*
+ Determine plane and row number.
+ */
+ PCDGetBits(16);
+ row=((sum >> 9) & 0x1fff);
+ if (row == image->rows)
+ break;
+ PCDGetBits(8);
+ plane=sum >> 30;
+ PCDGetBits(16);
+ switch (plane)
+ {
+ case 0:
+ {
+ q=luma+row*image->columns;
+ count=(long) image->columns;
+ break;
+ }
+ case 2:
+ {
+ q=chroma1+(row >> 1)*image->columns;
+ count=(long) (image->columns >> 1);
+ plane--;
+ break;
+ }
+ case 3:
+ {
+ q=chroma2+(row >> 1)*image->columns;
+ count=(long) (image->columns >> 1);
+ plane--;
+ break;
+ }
+ default:
+ {
+ ThrowBinaryException(CorruptImageError,CorruptImage,
+ image->filename)
+ }
+ }
+ length=pcd_length[plane];
+ if (QuantumTick(row,image->rows))
+ if (!MagickMonitorFormatted(row,image->rows,&image->exception,
+ DecodeImageText,image->filename))
+ break;
+ continue;
+ }
+ /*
+ Decode luminance or chrominance deltas.
+ */
+ r=pcd_table[plane];
+ for (i=0; ((i < (long) length) && ((sum & r->mask) != r->sequence)); i++)
+ r++;
+ if ((row > image->rows) || (r == (PCDTable *) NULL))
+ {
+ ThrowException(&image->exception,CorruptImageWarning,SkipToSyncByte,
+ image->filename);
+ while ((sum & 0x00fff000) != 0x00fff000)
+ PCDGetBits(8);
+ while (!IsSync)
+ PCDGetBits(1);
+ continue;
+ }
+ if (r->key < 128U)
+ quantum=(long) (*q)+r->key;
+ else
+ quantum=(long) (*q)+r->key-256;
+ *q=(unsigned char) ((quantum < 0L) ? 0U :
+ (quantum > 255L) ? 255U :
+ (unsigned char) quantum);
+ q++;
+ PCDGetBits(r->length);
+ count--;
+ }
+ /*
+ Free memory.
+ */
+ for (i=0; i < (image->columns > 1536 ? 3 : 1); i++)
+ MagickFreeMemory(pcd_table[i]);
+ MagickFreeMemory(buffer);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P C D %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPCD returns True if the image format type, identified by the
+% magick string, is PCD.
+%
+% The format of the IsPCD method is:
+%
+% unsigned int IsPCD(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPCD returns True if the image format type is PCD.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPCD(const unsigned char *magick,const size_t length)
+{
+ if (length < 2052)
+ return(False);
+ if (LocaleNCompare((char *) magick+2048,"PCD_",4) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P C D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPCDImage reads a Photo CD image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image. Much of the PCD decoder was derived from
+% the program hpcdtoppm(1) by Hadmut Danisch.
+%
+% The format of the ReadPCDImage method is:
+%
+% image=ReadPCDImage(image_info)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPCDImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static Image *OverviewImage(const ImageInfo *image_info,Image *image,
+ ExceptionInfo *exception)
+{
+ Image
+ *montage_image;
+
+ MontageInfo
+ *montage_info;
+
+ /*
+ Label image tiles.
+ */
+ {
+ Image
+ *label_image;
+
+ for( label_image=GetFirstImageInList(image); label_image != 0;
+ label_image=GetNextImageInList(label_image) )
+ (void) SetImageAttribute(label_image, "label", DefaultTileLabel);
+ }
+
+ /*
+ Create the PCD Overview image.
+ */
+ montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
+ (void) strlcpy(montage_info->filename,image_info->filename,MaxTextExtent);
+ montage_image=MontageImages(image,montage_info,exception);
+ DestroyMontageInfo(montage_info);
+ if (montage_image == (Image *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ DestroyImage(image);
+ return(montage_image);
+}
+
+static Image *ReadPCDImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ x;
+
+ ExtendedSignedIntegralType
+ offset;
+
+ register long
+ y;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ register unsigned char
+ *c1,
+ *c2,
+ *yy;
+
+ size_t
+ count;
+
+ unsigned char
+ *chroma1,
+ *chroma2,
+ *header,
+ *luma;
+
+ unsigned int
+ overview,
+ rotate,
+ status;
+
+ unsigned long
+ height,
+ number_images,
+ number_pixels,
+ subimage,
+ width;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Determine if this is a PCD file.
+ */
+ header=MagickAllocateMemory(unsigned char *,3*0x800);
+ if (header == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ count=ReadBlob(image,3*0x800,(char *) header);
+ overview=LocaleNCompare((char *) header,"PCD_OPA",7) == 0;
+ if ((count == 0) ||
+ ((LocaleNCompare((char *) header+0x800,"PCD",3) != 0) && !overview))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ rotate=header[0x0e02] & 0x03;
+ number_images=((header[10] << 8) | header[11]) & 0xFFFF;
+ MagickFreeMemory(header);
+ /*
+ Determine resolution by subimage specification.
+ */
+ number_pixels=image->columns*image->rows;
+ if (number_pixels == 0)
+ subimage=3;
+ else
+ {
+ width=192;
+ height=128;
+ for (subimage=1; subimage < 6; subimage++)
+ {
+ if ((width >= image->columns) && (height >= image->rows))
+ break;
+ width<<=1;
+ height<<=1;
+ }
+ }
+ if (image_info->subrange != 0)
+ subimage=Min(image_info->subimage,6);
+ if (overview)
+ subimage=1;
+ /*
+ Initialize image structure.
+ */
+ width=192;
+ height=128;
+ for (i=1; i < (long) Min(subimage,3); i++)
+ {
+ width<<=1;
+ height<<=1;
+ }
+ image->columns=width;
+ image->rows=height;
+ image->depth=8;
+ for ( ; i < (long) subimage; i++)
+ {
+ image->columns<<=1;
+ image->rows<<=1;
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Allocate luma and chroma memory.
+ */
+ number_pixels=image->columns*image->rows;
+ chroma1=MagickAllocateMemory(unsigned char *,number_pixels+1);
+ chroma2=MagickAllocateMemory(unsigned char *,number_pixels+1);
+ luma=MagickAllocateMemory(unsigned char *,number_pixels+1);
+ if ((chroma1 == (unsigned char *) NULL) ||
+ (chroma2 == (unsigned char *) NULL) || (luma == (unsigned char *) NULL))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Advance to image data.
+ */
+ offset=93;
+ if (overview)
+ offset=2;
+ else
+ if (subimage == 2)
+ offset=20;
+ else
+ if (subimage <= 1)
+ offset=1;
+ for (i=0; i < (long) (offset*0x800); i++)
+ (void) ReadBlobByte(image);
+ if (overview)
+ {
+ Image
+ *overview_image;
+
+ MonitorHandler
+ handler;
+
+ register long
+ j;
+
+ /*
+ Read thumbnails from overview image.
+ */
+ for (j=1; j <= (long) number_images; j++)
+ {
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ FormatString(image->filename,"images/img%04ld.pcd",j);
+ FormatString(image->magick_filename,"images/img%04ld.pcd",j);
+ image->scene=j;
+ image->columns=width;
+ image->rows=height;
+ image->depth=8;
+ yy=luma;
+ c1=chroma1;
+ c2=chroma2;
+ for (y=0; y < (long) height; y+=2)
+ {
+ (void) ReadBlob(image,width,(char *) yy);
+ yy+=image->columns;
+ (void) ReadBlob(image,width,(char *) yy);
+ yy+=image->columns;
+ (void) ReadBlob(image,width >> 1,(char *) c1);
+ c1+=image->columns;
+ (void) ReadBlob(image,width >> 1,(char *) c2);
+ c2+=image->columns;
+ }
+ Upsample(image->columns >> 1,image->rows >> 1,image->columns,chroma1);
+ Upsample(image->columns >> 1,image->rows >> 1,image->columns,chroma2);
+ /*
+ Transfer luminance and chrominance channels.
+ */
+ yy=luma;
+ c1=chroma1;
+ c2=chroma2;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(*yy++);
+ q->green=ScaleCharToQuantum(*c1++);
+ q->blue=ScaleCharToQuantum(*c2++);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ if (LocaleCompare(image_info->magick,"PCDS") == 0)
+ image->colorspace=sRGBColorspace;
+ else
+ image->colorspace=YCCColorspace;
+ (void) TransformColorspace(image,RGBColorspace);
+ if (j < (long) number_images)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ }
+ (void) SetMonitorHandler(handler);
+ if (!MagickMonitorFormatted(j-1,number_images,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(chroma2);
+ MagickFreeMemory(chroma1);
+ MagickFreeMemory(luma);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ overview_image=OverviewImage(image_info,image,exception);
+ return(overview_image);
+ }
+ /*
+ Read interleaved image.
+ */
+ yy=luma;
+ c1=chroma1;
+ c2=chroma2;
+ for (y=0; y < (long) height; y+=2)
+ {
+ (void) ReadBlob(image,width,(char *) yy);
+ yy+=image->columns;
+ (void) ReadBlob(image,width,(char *) yy);
+ yy+=image->columns;
+ (void) ReadBlob(image,width >> 1,(char *) c1);
+ c1+=image->columns;
+ (void) ReadBlob(image,width >> 1,(char *) c2);
+ c2+=image->columns;
+ }
+ if (subimage >= 4)
+ {
+ /*
+ Recover luminance deltas for 1536x1024 image.
+ */
+ Upsample(768,512,image->columns,luma);
+ Upsample(384,256,image->columns,chroma1);
+ Upsample(384,256,image->columns,chroma2);
+ image->rows=1024;
+ for (i=0; i < (4*0x800); i++)
+ (void) ReadBlobByte(image);
+ status=DecodeImage(image,luma,chroma1,chroma2);
+ if ((subimage >= 5) && status)
+ {
+ /*
+ Recover luminance deltas for 3072x2048 image.
+ */
+ Upsample(1536,1024,image->columns,luma);
+ Upsample(768,512,image->columns,chroma1);
+ Upsample(768,512,image->columns,chroma2);
+ image->rows=2048;
+ offset=TellBlob(image)/0x800+12;
+ (void) SeekBlob(image,offset*0x800,SEEK_SET);
+ status=DecodeImage(image,luma,chroma1,chroma2);
+ if ((subimage >= 6) && status)
+ {
+ /*
+ Recover luminance deltas for 6144x4096 image (vaporware).
+ */
+ Upsample(3072,2048,image->columns,luma);
+ Upsample(1536,1024,image->columns,chroma1);
+ Upsample(1536,1024,image->columns,chroma2);
+ image->rows=4096;
+ }
+ }
+ }
+ Upsample(image->columns >> 1,image->rows >> 1,image->columns,chroma1);
+ Upsample(image->columns >> 1,image->rows >> 1,image->columns,chroma2);
+ /*
+ Transfer luminance and chrominance channels.
+ */
+ yy=luma;
+ c1=chroma1;
+ c2=chroma2;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(*yy++);
+ q->green=ScaleCharToQuantum(*c1++);
+ q->blue=ScaleCharToQuantum(*c2++);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(chroma2);
+ MagickFreeMemory(chroma1);
+ MagickFreeMemory(luma);
+ if (LocaleCompare(image_info->magick,"PCDS") == 0)
+ image->colorspace=sRGBColorspace;
+ else
+ image->colorspace=YCCColorspace;
+ /* FIXME: YCCColorspace transform is broken! 1.1 is ok! */
+ (void) TransformColorspace(image,RGBColorspace);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+
+ if ((rotate == 1) || (rotate == 3))
+ {
+ double
+ degrees;
+
+ Image
+ *rotated_image;
+
+ /*
+ Rotate image.
+ */
+ degrees=rotate == 1 ? -90.0 : 90.0;
+ rotated_image=RotateImage(image,degrees,exception);
+ if (rotated_image != (Image *) NULL)
+ {
+ DestroyImage(image);
+ image=rotated_image;
+ }
+ }
+
+ /*
+ Set CCIR 709 primaries with a D65 white point.
+ */
+ image->chromaticity.red_primary.x=0.6400f;
+ image->chromaticity.red_primary.y=0.3300f;
+ image->chromaticity.green_primary.x=0.3000f;
+ image->chromaticity.green_primary.y=0.6000f;
+ image->chromaticity.blue_primary.x=0.1500f;
+ image->chromaticity.blue_primary.y=0.0600f;
+ image->chromaticity.white_point.x=0.3127f;
+ image->chromaticity.white_point.y=0.3290f;
+ image->gamma=1.000f/2.200f;
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P C D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPCDImage adds attributes for the PCD image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPCDImage method is:
+%
+% RegisterPCDImage(void)
+%
+*/
+ModuleExport void RegisterPCDImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PCD");
+ entry->decoder=(DecoderHandler) ReadPCDImage;
+ entry->encoder=(EncoderHandler) WritePCDImage;
+ entry->magick=(MagickHandler) IsPCD;
+ entry->adjoin=False;
+ entry->description="Photo CD";
+ entry->seekable_stream=MagickTrue;
+ entry->module="PCD";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PCDS");
+ entry->decoder=(DecoderHandler) ReadPCDImage;
+ entry->encoder=(EncoderHandler) WritePCDImage;
+ entry->adjoin=False;
+ entry->description="Photo CD";
+ entry->seekable_stream=MagickTrue;
+ entry->module="PCD";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P C D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPCDImage removes format registrations made by the
+% PCD module from the list of supported formats.
+%
+% The format of the UnregisterPCDImage method is:
+%
+% UnregisterPCDImage(void)
+%
+*/
+ModuleExport void UnregisterPCDImage(void)
+{
+ (void) UnregisterMagickInfo("PCD");
+ (void) UnregisterMagickInfo("PCDS");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P C D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePCDImage writes an image in the Photo CD encoded image
+% format.
+%
+% The format of the WritePCDImage method is:
+%
+% unsigned int WritePCDImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePCDImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static unsigned int WritePCDTile(const ImageInfo *image_info,
+ Image *image,char *page_geometry,char *tile_geometry)
+{
+ Image
+ *downsample_image,
+ *tile_image;
+
+ long
+ y;
+
+ RectangleInfo
+ geometry;
+
+ register const PixelPacket
+ *p,
+ *q;
+
+ register long
+ i,
+ x;
+
+ ARG_NOT_USED(image_info);
+
+ /*
+ Scale image to tile size.
+ */
+ SetGeometry(image,&geometry);
+ (void) GetMagickGeometry(page_geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ if ((geometry.width % 2) != 0)
+ geometry.width--;
+ if ((geometry.height % 2) != 0)
+ geometry.height--;
+ tile_image=ResizeImage(image,geometry.width,geometry.height,TriangleFilter,
+ 1.0,&image->exception);
+ if (tile_image == (Image *) NULL)
+ return(False);
+ (void) sscanf(page_geometry,"%lux%lu",&geometry.width,&geometry.height);
+ if ((tile_image->columns != geometry.width) ||
+ (tile_image->rows != geometry.height))
+ {
+ Image
+ *bordered_image;
+
+ RectangleInfo
+ border_info;
+
+ /*
+ Put a border around the image.
+ */
+ border_info.width=(geometry.width-tile_image->columns+1) >> 1;
+ border_info.height=(geometry.height-tile_image->rows+1) >> 1;
+ bordered_image=BorderImage(tile_image,&border_info,&image->exception);
+ if (bordered_image == (Image *) NULL)
+ return(False);
+ DestroyImage(tile_image);
+ tile_image=bordered_image;
+ }
+ (void) TransformImage(&tile_image,(char *) NULL,tile_geometry);
+ (void) TransformColorspace(tile_image,YCCColorspace);
+ downsample_image=ResizeImage(tile_image,tile_image->columns/2,
+ tile_image->rows/2,TriangleFilter,1.0,&image->exception);
+ if (downsample_image == (Image *) NULL)
+ return(False);
+ /*
+ Write tile to PCD file.
+ */
+ for (y=0; y < (long) tile_image->rows; y+=2)
+ {
+ p=AcquireImagePixels(tile_image,0,y,tile_image->columns,2,
+ &tile_image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) (tile_image->columns << 1); x++)
+ {
+ (void) WriteBlobByte(image,ScaleQuantumToChar(p->red));
+ p++;
+ }
+ q=AcquireImagePixels(downsample_image,0,y >> 1,downsample_image->columns,
+ 1,&downsample_image->exception);
+ if (q == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) downsample_image->columns; x++)
+ {
+ (void) WriteBlobByte(image,ScaleQuantumToChar(q->green));
+ q++;
+ }
+ q=AcquireImagePixels(downsample_image,0,y >> 1,downsample_image->columns,
+ 1,&downsample_image->exception);
+ if (q == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) downsample_image->columns; x++)
+ {
+ (void) WriteBlobByte(image,ScaleQuantumToChar(q->blue));
+ q++;
+ }
+ if (QuantumTick(y,tile_image->rows))
+ if (!MagickMonitorFormatted(y,tile_image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ for (i=0; i < 0x800; i++)
+ (void) WriteBlobByte(image,'\0');
+ DestroyImage(downsample_image);
+ DestroyImage(tile_image);
+ return(True);
+}
+
+static unsigned int WritePCDImage(const ImageInfo *image_info,Image *image)
+{
+ Image
+ *pcd_image;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ pcd_image=image;
+ if (image->columns < image->rows)
+ {
+ Image
+ *rotated_image;
+
+ /*
+ Rotate portrait to landscape.
+ */
+ rotated_image=RotateImage(image,90.0,&image->exception);
+ if (rotated_image == (Image *) NULL)
+ return(False);
+ pcd_image=rotated_image;
+ }
+ /*
+ Open output image file.
+ */
+ status=OpenBlob(image_info,pcd_image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,pcd_image);
+ (void) TransformColorspace(pcd_image,RGBColorspace);
+ /*
+ Write PCD image header.
+ */
+ for (i=0; i < 32; i++)
+ (void) WriteBlobByte(pcd_image,0xff);
+ for (i=0; i < 4; i++)
+ (void) WriteBlobByte(pcd_image,0x0e);
+ for (i=0; i < 8; i++)
+ (void) WriteBlobByte(pcd_image,'\0');
+ for (i=0; i < 4; i++)
+ (void) WriteBlobByte(pcd_image,0x01);
+ for (i=0; i < 4; i++)
+ (void) WriteBlobByte(pcd_image,0x05);
+ for (i=0; i < 8; i++)
+ (void) WriteBlobByte(pcd_image,'\0');
+ for (i=0; i < 4; i++)
+ (void) WriteBlobByte(pcd_image,0x0A);
+ for (i=0; i < 36; i++)
+ (void) WriteBlobByte(pcd_image,'\0');
+ for (i=0; i < 4; i++)
+ (void) WriteBlobByte(pcd_image,0x01);
+ for (i=0; i < 1944; i++)
+ (void) WriteBlobByte(pcd_image,'\0');
+ (void) WriteBlob(pcd_image,7,"PCD_IPI");
+ (void) WriteBlobByte(pcd_image,0x06);
+ for (i=0; i < 1530; i++)
+ (void) WriteBlobByte(pcd_image,'\0');
+ if (image->columns < image->rows)
+ (void) WriteBlobByte(pcd_image,'\1');
+ else
+ (void) WriteBlobByte(pcd_image,'\0');
+ for (i=0; i < (3*0x800-1539); i++)
+ (void) WriteBlobByte(pcd_image,'\0');
+ /*
+ Write PCD tiles.
+ */
+ status=WritePCDTile(image_info,pcd_image,(char *) "768x512>",
+ (char *) "192x128");
+ status|=WritePCDTile(image_info,pcd_image,(char *) "768x512>",
+ (char *) "384x256");
+ status|=WritePCDTile(image_info,pcd_image,(char *) "768x512>",
+ (char *) "768x512");
+ CloseBlob(pcd_image);
+ if (pcd_image != image)
+ DestroyImage(pcd_image);
+ return(status);
+}
diff --git a/coders/pcl.c b/coders/pcl.c
new file mode 100644
index 0000000..9fdf25f
--- /dev/null
+++ b/coders/pcl.c
@@ -0,0 +1,1199 @@
+/*
+% Copyright (C) 2003-2010 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP CCCC L %
+% P P C L %
+% PPPP C L %
+% P C L %
+% P CCCC LLLLL %
+% %
+% %
+% Write HP PCL Printer Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% Rewritten by John Sergeant %
+% May 2009 %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+/*
+ Tunables
+*/
+#define NEED_END_OF_ROW_DELTA_OUTPUT
+/*#define DISABLE_ZERO_ROW_COMPRESSION */
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ PCL_NoCompression,
+ PCL_RLECompression,
+ PCL_TiffRLECompression,
+ PCL_DeltaCompression,
+ PCL_ZeroRowCompression,
+ PCL_RepeatedRowCompression,
+ PCL_UndefinedCompression
+} PCL_CompressionType;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePCLImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P C L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPCL returns True if the image format type, identified by the
+% magick string, is PCL.
+%
+% The format of the IsPCL method is:
+%
+% unsigned int IsPCL(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPCL returns True if the image format type is PCL.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPCL(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (memcmp(magick,"\033E\033",3) == 0)
+ return(True);
+ if (memcmp(magick,"\033E\033&",4) == 0)
+ return(False);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P C L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPCLImage adds attributes for the PCL image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPCLImage method is:
+%
+% RegisterPCLImage(void)
+%
+*/
+ModuleExport void RegisterPCLImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PCL");
+ entry->encoder=(EncoderHandler) WritePCLImage;
+ entry->magick=(MagickHandler) IsPCL;
+ entry->adjoin=True;
+ entry->description="Page Control Language";
+ entry->module="PCL";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P C L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPCLImage removes format registrations made by the
+% PCL module from the list of supported formats.
+%
+% The format of the UnregisterPCLImage method is:
+%
+% UnregisterPCLImage(void)
+%
+*/
+ModuleExport void UnregisterPCLImage(void)
+{
+ (void) UnregisterMagickInfo("PCL");
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P C L _ C h o o s e C o m p r e s s i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method PCL_ChooseCompression chooses a method by which to compress a given
+% row of pixels in the PCL format
+%
+% The format of the PCL_ChooseCompression method is:
+%
+% PCL_CompressionType PCL_ChooseCompression(unsigned long row_width,
+% unsigned char *row,
+% unsigned char *last_row)
+%
+% A description of each parameter follows.
+%
+% o status: Method PCL_ChooseCompression returns a PCL_CompressionType
+% variable suggesting the best form of compression to use for the row
+%
+% o row_width: An unsigned long specifying number of bytes in row
+%
+% o row: A pointer to the current row of pixels
+%
+% o last_row: A pointer to the last row of pixels (for use by delta compression)
+%
+*/
+static PCL_CompressionType PCL_ChooseCompression(unsigned long row_width,
+ unsigned char *row,
+ unsigned char *last_row)
+{
+ unsigned long
+ x,
+ rep,
+ unrep,
+ RLE_cost,
+ TiffRLE_cost,
+ delta_cost,
+ least_cost;
+
+ unsigned char
+ *q,
+ *last_row_q;
+
+ unsigned char
+ last_char,
+ this_char;
+
+ PCL_CompressionType
+ compression;
+
+ /*
+ Calculate cost to encode via either RLE method
+ */
+ TiffRLE_cost=0;
+ RLE_cost=0;
+ x=0;
+ q=row;
+ this_char=0;
+ last_char=!*q;
+ rep=0;
+ while (x < row_width)
+ {
+ /*
+ Count unrepeated bytes
+ */
+ unrep=0;
+ rep=0;
+ while (x < row_width)
+ {
+ x++;
+ this_char=*q++;
+ if (this_char == last_char)
+ {
+ unrep--;
+ rep=2;
+ break;
+ }
+ last_char=this_char;
+ unrep++;
+ }
+
+ /*
+ Count repeated bytes
+ */
+ while (x < row_width)
+ {
+ this_char=*q;
+ if (this_char != last_char)
+ break;
+ rep++;
+ x++;
+ q++;
+ }
+ /*
+ Increment costs based on what we found
+ */
+ RLE_cost += 2*(unrep+((rep+255)/256));
+ TiffRLE_cost += unrep + ((unrep+127)/128) + 2*((rep+127)/128);
+ }
+ /*
+ Special case #1 - row is all zero
+ */
+#if defined(DISABLE_ZERO_ROW_COMPRESSION)
+ if ((rep==row_width) && (!this_char))
+ return PCL_ZeroRowCompression;
+#endif
+
+ /*
+ Calculate cost to encode via delta method
+ */
+ delta_cost=0;
+ x=0;
+ q=row;
+ last_row_q=last_row;
+ while (x < row_width)
+ {
+ /*
+ Count unaltered bytes
+ */
+ unrep=0;
+ rep=0;
+ while (x < row_width)
+ {
+ x++;
+ if (*q++ != *last_row_q++)
+ {
+ unrep=1;
+ break;
+ }
+ rep++;
+ }
+
+ /*
+ Count altered bytes
+ */
+ while (x < row_width)
+ {
+ if (*q == *last_row_q)
+ break;
+ unrep++;
+ x++;
+ q++;
+ last_row_q++;
+ }
+ /*
+ Increment cost based on what we found
+ */
+ if (unrep)
+ delta_cost += 1 + ((rep+224)/255) + unrep + ((unrep+7)/8);
+#if defined(NEED_END_OF_ROW_DELTA_OUTPUT)
+ else
+ delta_cost += 2 + ((rep+223)/255);
+#endif
+ }
+ /*
+ Special case #2 - row is unchanged
+ */
+ if (rep == row_width)
+ return PCL_RepeatedRowCompression;
+
+ /* Choose compression to use, starting with most likely */
+ least_cost=delta_cost;
+ compression=PCL_DeltaCompression;
+ if (TiffRLE_cost < least_cost)
+ {
+ least_cost=TiffRLE_cost;
+ compression=PCL_TiffRLECompression;
+ }
+ if (RLE_cost < least_cost)
+ {
+ least_cost=RLE_cost;
+ compression=PCL_RLECompression;
+ }
+ if (row_width < least_cost)
+ {
+ least_cost=row_width;
+ compression=PCL_NoCompression;
+ }
+ return compression;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P C L _ D e l t a C o m p r e s s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method PCL_DeltaCompress compresses a given row of pixels using the PCL delta
+% compress method
+%
+% The format of the PCL_DeltaCompress method is:
+%
+% unsigned long PCL_DeltaCompress (unsigned long row_width,
+% unsigned char *row,
+% unsigned char *last_row,
+% unsigned char *compressed_row)
+%
+% A description of each parameter follows.
+%
+% o status: Method PCL_DataCompress returns the byte size of the
+% data stored in compressed_row
+%
+% o row_width: An unsigned long specifying number of bytes in row
+%
+% o row: A pointer to the current row of pixels
+%
+% o last_row: A pointer to the last row of pixels
+%
+% o compressed_row: A buffer into which the compressed data is to be
+% written.
+%
+*/
+static unsigned long PCL_DeltaCompress(unsigned long row_width,
+ unsigned char *row,
+ unsigned char *last_row,
+ unsigned char *compressed_row)
+{
+ unsigned long
+ x,
+ rep,
+ unrep,
+ rep_this_time,
+ unrep_this_time;
+
+ unsigned char
+ *q,
+ *last_row_q,
+ *out;
+
+ x=0;
+ q=row;
+ last_row_q=last_row;
+ out=compressed_row;
+ while (x < row_width)
+ {
+ /*
+ Count unaltered bytes
+ */
+ unrep=0;
+ rep=0;
+ while (x < row_width)
+ {
+ x++;
+ if (*q++ != *last_row_q++)
+ {
+ unrep=1;
+ break;
+ }
+ rep++;
+ }
+
+ /*
+ Count altered bytes
+ */
+ while (x < row_width)
+ {
+ if (*q == *last_row_q)
+ break;
+ unrep++;
+ x++;
+ q++;
+ last_row_q++;
+ }
+
+ /*
+ Unrep can only be zero if no further changes are required on this row
+ */
+ if (!unrep)
+ break;
+
+ /*
+ Output first control byte, including offset
+ */
+ rep_this_time = (rep >= 31)?31:rep;
+ rep -= rep_this_time;
+ unrep_this_time = (unrep >= 8)?8:unrep;
+ *out++ = (unsigned char)(((unrep_this_time-1) << 5) | rep_this_time);
+
+ if (rep_this_time == 31)
+ {
+ /*
+ Output extra offset bytes plus an extra zero if last was 255
+ */
+ rep_this_time=255;
+ while (rep)
+ {
+ if (rep_this_time > rep)
+ rep_this_time=rep;
+ *out++ = (unsigned char)rep_this_time;
+ rep -= rep_this_time;
+ }
+ if (rep_this_time == 255)
+ *out++ = (unsigned char)0;
+ }
+ /* Now skip back to beginning of unreplicated data and start outputting it */
+ q -= unrep;
+ while (1)
+ {
+ unrep -= unrep_this_time;
+ while (unrep_this_time)
+ {
+ *out++ = *q++;
+ unrep_this_time--;
+ }
+ if (!unrep)
+ break;
+
+ /* Output next control byte */
+ if (unrep >= 8)
+ unrep_this_time = 8;
+ else
+ unrep_this_time=unrep;
+ *out++=(unsigned char)((unrep_this_time-1) << 5);
+ }
+ }
+ return (unsigned long)(out-compressed_row);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P C L _ T i f f R L E C o m p r e s s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method PCL_TiffRLECompress compresses a given row of pixels using the PCL
+% Tiff RLE compress method
+%
+% The format of the PCL_TiffRLECompress method is:
+%
+% unsigned long PCL_TiffRLECompress(unsigned long row_width,
+% unsigned char *row,
+% unsigned char *compressed_row)
+%
+% A description of each parameter follows.
+%
+% o status: Method PCL_TiffRLECompress returns the byte size of the
+% data stored in compressed_row
+%
+% o row_width: An unsigned long specifying number of bytes in row
+%
+% o row: A pointer to the current row of pixels
+%
+% o compressed_row: A buffer into which the compressed data is to be
+% written.
+%
+*/
+static unsigned long PCL_TiffRLECompress(unsigned long row_width,
+ unsigned char *row,
+ unsigned char *compressed_row)
+{
+ unsigned long
+ x,
+ rep,
+ unrep,
+ rep_this_time,
+ unrep_this_time;
+
+ unsigned char
+ *q,
+ *out;
+
+ unsigned char
+ last_char,
+ this_char;
+
+ x=0;
+ q=row;
+ this_char=0;
+ last_char=!*q;
+ out=compressed_row;
+ while (x < row_width)
+ {
+ /*
+ Count unrepeated bytes
+ */
+ unrep=0;
+ rep=0;
+ while (x < row_width)
+ {
+ x++;
+ this_char=*q++;
+ if (this_char == last_char)
+ {
+ unrep--;
+ rep=2;
+ break;
+ }
+ last_char=this_char;
+ unrep++;
+ }
+
+ /*
+ Count repeated bytes
+ */
+ while (x < row_width)
+ {
+ this_char=*q;
+ if (this_char != last_char)
+ break;
+ rep++;
+ x++;
+ q++;
+ }
+
+ /*
+ Output unrepeated bytes
+ */
+ if (unrep)
+ {
+ q -= (unrep + rep);
+ while (unrep)
+ {
+ unrep_this_time = (unrep >= 128)?128:unrep;
+ *out++=(unsigned char)(unrep_this_time-1);
+ unrep -= unrep_this_time;
+ while (unrep_this_time)
+ {
+ *out++ = *q++;
+ unrep_this_time--;
+ }
+ }
+ q += rep;
+ }
+
+ /*
+ Output repeated bytes
+ */
+ rep_this_time=128;
+ while (rep)
+ {
+ if (rep_this_time > rep)
+ rep_this_time = rep;
+ *out++ = (unsigned char)(257-rep_this_time);
+ *out++ = last_char;
+ rep -= rep_this_time;
+ }
+ }
+ return (unsigned long)(out-compressed_row);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P C L _ R L E C o m p r e s s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method PCL_RLECompress compresses a given row of pixels using the PCL RLE
+% compress method
+%
+% The format of the PCL_RLECompress method is:
+%
+% unsigned long PCL_RLECompress(unsigned long row_width,
+% unsigned char *row,
+% unsigned char *compressed_row)
+%
+% A description of each parameter follows.
+%
+% o status: Method PCL_RLECompress returns the byte size of the data
+% stored in compressed_row
+%
+% o row_width: An unsigned long specifying number of bytes in row
+%
+% o row: A pointer to the current row of pixels
+%
+% o compressed_row: A buffer into which the compressed data is to be
+% written.
+%
+*/
+static unsigned long PCL_RLECompress(unsigned long row_width,
+ unsigned char *row,
+ unsigned char *compressed_row)
+{
+ unsigned long
+ x,
+ rep,
+ unrep,
+ rep_this_time;
+
+ unsigned char
+ *q,
+ *out;
+
+ unsigned char
+ last_char,
+ this_char;
+
+ x=0;
+ q=row;
+ this_char=0;
+ last_char=!*q;
+ out=compressed_row;
+ while (x < row_width)
+ {
+ /*
+ Count unrepeated bytes
+ */
+ unrep=0;
+ rep=0;
+ while (x < row_width)
+ {
+ x++;
+ this_char=*q++;
+ if (this_char == last_char)
+ {
+ unrep--;
+ rep=2;
+ break;
+ }
+ last_char=this_char;
+ unrep++;
+ }
+
+ /*
+ Count repeated bytes
+ */
+ while (x < row_width)
+ {
+ this_char=*q;
+ if (this_char != last_char)
+ break;
+ rep++;
+ x++;
+ q++;
+ }
+
+ /*
+ Output unrepeated bytes
+ */
+ if (unrep)
+ {
+ q -= (unrep + rep);
+ while (unrep)
+ {
+ *out++=0;
+ *out++=*q++;
+ unrep--;
+ }
+ q += rep;
+ }
+
+ /*
+ Output repeated bytes
+ */
+ rep_this_time=256;
+ while (rep)
+ {
+ if (rep_this_time > rep)
+ rep_this_time = rep;
+ *out++=(unsigned char)(rep_this_time-1);
+ *out++ = last_char;
+ rep -= rep_this_time;
+ }
+ }
+ return (unsigned long)(out-compressed_row);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P C L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePCLImage writes an image in the Page Control Language encoded
+% image format.
+%
+% The format of the WritePCLImage method is:
+%
+% unsigned int WritePCLImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePCLImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+%
+*/
+static unsigned int WritePCLImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[MaxTextExtent];
+
+ long
+ sans,
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *pixels,
+ *last_row_pixels,
+ *output_row;
+
+ unsigned int
+ status;
+
+ long
+ zero_rows;
+
+ unsigned long
+ bytes_to_write,
+ scene,
+ density,
+ bytes_per_line;
+
+ unsigned char
+ bits_per_pixel;
+
+ ImageCharacteristics
+ characteristics;
+
+ PCL_CompressionType
+ compression,
+ last_row_compression;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ (void) GetGeometry("75x75",&sans,&sans,&density,&density);
+ if (image_info->density != (char *) NULL)
+ (void) GetGeometry(image_info->density,&sans,&sans,&density,&density);
+
+ scene = 0;
+ output_row = (unsigned char *) NULL;
+ last_row_pixels = (unsigned char *) NULL;
+ do
+ {
+ /*
+ Ensure that image is in an RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+
+ /*
+ Initialize the printer
+ */
+ (void) WriteBlobString(image,"\033E"); /* printer reset */
+ (void) WriteBlobString(image,"\033*r3F"); /* set presentation mode */
+ /* define columns and rows in image */
+ FormatString(buffer,"\033*r%lus%luT",image->columns,image->rows);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"\033*t%luR",density); /* set resolution */
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"\033&l0E"); /* top margin 0 */
+
+ /*
+ Determine output type and initialize further accordingly
+ */
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Full color
+ */
+ bits_per_pixel=24;
+ (void) WriteBlobString(image,"\033*v6W"); /* set color mode... */
+ (void) WriteBlobByte(image,0); /* RGB */
+ (void) WriteBlobByte(image,3); /* direct by pixel */
+ (void) WriteBlobByte(image,0); /* bits per index (ignored) */
+ (void) WriteBlobByte(image,8); /* bits per red component */
+ (void) WriteBlobByte(image,8); /* bits per green component */
+ (void) WriteBlobByte(image,8); /* bits per blue component */
+ }
+ else
+ if (characteristics.monochrome)
+ {
+ /*
+ Use default printer monochrome setup - NB white = 0, black = 1
+ */
+ bits_per_pixel=1;
+ }
+ else
+ {
+ /*
+ PseudoClass
+ */
+ bits_per_pixel=8;
+ (void) WriteBlobString(image,"\033*v6W"); /* set color mode... */
+ (void) WriteBlobByte(image,0); /* RGB */
+ (void) WriteBlobByte(image,1); /* indexed by pixel */
+ (void) WriteBlobByte(image,bits_per_pixel); /* bits per index */
+ (void) WriteBlobByte(image,8); /* bits per red component (implicit) */
+ (void) WriteBlobByte(image,8); /* bits per green component (implicit) */
+ (void) WriteBlobByte(image,8); /* bits per blue component (implicit) */
+
+ /*
+ Write colormap to file.
+ */
+ for (i=0; i < (long)(image->colors); i++)
+ {
+ FormatString(buffer,"\033*v%da%db%dc%ldI",
+ ScaleQuantumToChar(image->colormap[i].red),
+ ScaleQuantumToChar(image->colormap[i].green),
+ ScaleQuantumToChar(image->colormap[i].blue),
+ i);
+ WriteBlobString(image,buffer);
+ }
+ /*
+ Initialize rest of palette with empty entries
+ */
+ for ( ; i < (1L << bits_per_pixel); i++)
+ {
+ FormatString(buffer,"\033*v%luI",i);
+ /* set index to current component values */
+ (void) WriteBlobString(image,buffer);
+ }
+ }
+
+ /*
+ Start raster image
+ */
+ if ((AccessDefinition(image_info,"pcl","fit-to-page") != NULL) ||
+ (AccessDefinition(image_info,"pcl","fit_to_page") != NULL))
+ (void) WriteBlobString(image,"\033*r3A"); /* start raster graphics with scaling */
+ else
+ (void) WriteBlobString(image,"\033*r1A"); /* start raster graphics */
+ (void) WriteBlobString(image,"\033*b0Y"); /* set y offset */
+
+ /*
+ Assign row buffer
+ */
+ bytes_per_line=(image->columns*bits_per_pixel+7)/8;
+ pixels=MagickAllocateMemory(unsigned char *,bytes_per_line);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ /*
+ Set up for compression if desired
+ */
+ last_row_compression = PCL_UndefinedCompression;
+ if (image_info->compression != NoCompression)
+ {
+ MagickFreeMemory(last_row_pixels);
+ last_row_pixels=MagickAllocateMemory(unsigned char *,bytes_per_line);
+ if (last_row_pixels == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(pixels);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ MagickFreeMemory(output_row);
+ output_row=MagickAllocateMemory(unsigned char *,bytes_per_line);
+ if (output_row == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(pixels);
+ MagickFreeMemory(last_row_pixels);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ memset(last_row_pixels,0,bytes_per_line);
+ }
+
+ /*
+ Convert MIFF to PCL raster pixels.
+ */
+ zero_rows=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels;
+
+ if (characteristics.monochrome)
+ {
+ register unsigned char
+ bit,
+ byte;
+
+ unsigned int
+ blk_ind;
+
+ /*
+ Monochrome row
+ */
+ blk_ind = ((image->colormap == NULL) || (image->colormap[0].red == 0)) ? 0U : 1U;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte<<=1;
+ if (indexes[x] == blk_ind) byte |= 1;
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ *q++=byte << (8-bit);
+ }
+ else
+ if (bits_per_pixel == 8)
+ {
+ /*
+ 8 bit PseudoClass row
+ */
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=indexes[x];
+ }
+ }
+ else
+ if ((bits_per_pixel == 24) || (bits_per_pixel == 32))
+ {
+ /*
+ DirectClass/RGB row
+ */
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ p++;
+ }
+ }
+
+ if (image_info->compression == NoCompression)
+ {
+ FormatString(buffer,"\033*b%luW",bytes_per_line); /* send row */
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlob(image,bytes_per_line,pixels);
+ }
+ else
+ {
+ compression=PCL_ChooseCompression(bytes_per_line,pixels,last_row_pixels);
+ if (compression == PCL_ZeroRowCompression)
+ {
+ zero_rows++;
+ }
+ else
+ {
+ /*
+ Skip any omitted zero rows now
+ */
+ if (zero_rows > 0)
+ {
+ i = 32767;
+ do
+ {
+ if (zero_rows < i)
+ i=zero_rows;
+ FormatString(buffer,"\033*b%ldY",i); /* Y Offset */
+ (void) WriteBlobString(image,buffer);
+ zero_rows -= i;
+ } while (zero_rows > 0);
+ }
+
+ switch (compression)
+ {
+ case PCL_DeltaCompression:
+ {
+ if (compression != last_row_compression)
+ {
+ FormatString(buffer,"\033*b3M"); /* delta compression */
+ (void) WriteBlobString(image,buffer);
+ last_row_compression=compression;
+ }
+ bytes_to_write=PCL_DeltaCompress(bytes_per_line,pixels,
+ last_row_pixels,output_row);
+ FormatString(buffer,"\033*b%luW",bytes_to_write);
+ (void) WriteBlobString(image,buffer);
+ WriteBlob(image,bytes_to_write,output_row);
+ break;
+ }
+ case PCL_TiffRLECompression:
+ {
+ if (compression != last_row_compression)
+ {
+ FormatString(buffer,"\033*b2M"); /* Tiff RLE compression */
+ (void) WriteBlobString(image,buffer);
+ last_row_compression=compression;
+ }
+ bytes_to_write=PCL_TiffRLECompress(bytes_per_line,pixels,output_row);
+ FormatString(buffer,"\033*b%luW",bytes_to_write);
+ (void) WriteBlobString(image,buffer);
+ WriteBlob(image,bytes_to_write,output_row);
+ break;
+ }
+ case PCL_RLECompression:
+ {
+ if (compression != last_row_compression)
+ {
+ FormatString(buffer,"\033*b1M"); /* RLE compression */
+ (void) WriteBlobString(image,buffer);
+ last_row_compression=compression;
+ }
+ bytes_to_write=PCL_RLECompress(bytes_per_line,pixels,output_row);
+ FormatString(buffer,"\033*b%luW",bytes_to_write);
+ (void) WriteBlobString(image,buffer);
+ WriteBlob(image,bytes_to_write,output_row);
+ break;
+ }
+ case PCL_RepeatedRowCompression:
+ {
+ compression=PCL_DeltaCompression;
+ if (compression != last_row_compression)
+ {
+ FormatString(buffer,"\033*b3M"); /* delta row compression */
+ (void) WriteBlobString(image,buffer);
+ last_row_compression=compression;
+ }
+ FormatString(buffer,"\033*b0W"); /* no data -> replicate row */
+ (void) WriteBlobString(image,buffer);
+ break;
+ }
+ case PCL_NoCompression:
+ {
+ if (compression != last_row_compression)
+ {
+ FormatString(buffer,"\033*b0M"); /* no compression */
+ (void) WriteBlobString(image,buffer);
+ last_row_compression=compression;
+ }
+ FormatString(buffer,"\033*b%luW",bytes_per_line); /* send row */
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlob(image,bytes_per_line,pixels);
+ break;
+ }
+ case PCL_ZeroRowCompression:
+ {
+ break;
+ }
+ case PCL_UndefinedCompression:
+ {
+ break;
+ }
+ }
+ }
+
+ /*
+ Swap row with last row
+ */
+ q=last_row_pixels;
+ last_row_pixels=pixels;
+ pixels=q;
+ }
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+
+ (void) WriteBlobString(image,"\033*rB"); /* end graphics */
+ MagickFreeMemory(pixels);
+ MagickFreeMemory(last_row_pixels);
+ MagickFreeMemory(output_row);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if ((status &= MagickMonitorFormatted(scene++,
+ GetImageListLength(image),
+ &image->exception,
+ SaveImagesText,
+ image->filename)) == MagickFail)
+ break;
+ } while (image_info->adjoin);
+
+ (void) WriteBlobString(image,"\033E");
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/pcx.c b/coders/pcx.c
new file mode 100644
index 0000000..4f42dde
--- /dev/null
+++ b/coders/pcx.c
@@ -0,0 +1,1317 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP CCCC X X %
+% P P C X X %
+% PPPP C X %
+% P C X X %
+% P CCCC X X %
+% %
+% %
+% Read/Write ZSoft IBM PC Paintbrush Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Typedef declarations.
+*/
+typedef struct _PCXInfo
+{
+ unsigned char
+ identifier,
+ version,
+ encoding,
+ bits_per_pixel;
+
+ unsigned short
+ left,
+ top,
+ right,
+ bottom,
+ horizontal_resolution,
+ vertical_resolution;
+
+ unsigned char
+ reserved,
+ planes;
+
+ unsigned short
+ bytes_per_line,
+ palette_info,
+ horizontal_screen_size,
+ vertical_screen_size;
+
+ unsigned char
+ colormap_signature;
+} PCXInfo;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePCXImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s D C X %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsDCX returns True if the image format type, identified by the
+% magick string, is DCX.
+%
+% The format of the IsDCX method is:
+%
+% unsigned int IsDCX(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsDCX returns True if the image format type is DCX.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsDCX(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (memcmp(magick,"\261\150\336\72",4) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P C X %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPCX returns True if the image format type, identified by the
+% magick string, is PCX.
+%
+% The format of the IsPCX method is:
+%
+% unsigned int IsPCX(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPCX returns True if the image format type is PCX.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPCX(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if (memcmp(magick,"\012\002",2) == 0)
+ return(True);
+ if (memcmp(magick,"\012\005",2) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P C X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPCXImage reads a ZSoft IBM PC Paintbrush file and returns it.
+% It allocates the memory necessary for the new Image structure and returns
+% a pointer to the new image.
+%
+% The format of the ReadPCXImage method is:
+%
+% Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPCXImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowPCXReaderException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(page_table) \
+ MagickFreeMemory(pcx_pixels); \
+ MagickFreeMemory(scanline); \
+ ThrowReaderException(code_,reason_,image_); \
+}
+static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ ExtendedSignedIntegralType
+ *page_table = (ExtendedSignedIntegralType *) NULL;
+
+ int
+ c,
+ bits,
+ id,
+ mask;
+
+ long
+ y;
+
+ PCXInfo
+ pcx_info;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned int
+ i;
+
+ register unsigned char
+ *p,
+ *r;
+
+ size_t
+ count;
+
+ unsigned char
+ packet,
+ pcx_colormap[256*3],
+ *pcx_pixels = (unsigned char *) NULL,
+ *scanline = (unsigned char *) NULL;
+
+ unsigned int
+ status;
+
+ size_t
+ pcx_packets;
+
+ magick_off_t
+ file_size;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowPCXReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Determine if this is a PCX file.
+ */
+ page_table=(ExtendedSignedIntegralType *) NULL;
+ if (LocaleCompare(image_info->magick,"DCX") == 0)
+ {
+ unsigned long
+ magic;
+
+ /*
+ Read the DCX page table.
+ */
+ magic=ReadBlobLSBLong(image);
+ if (magic != 987654321)
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image);
+ page_table=MagickAllocateArray(ExtendedSignedIntegralType *,
+ 1024,sizeof(ExtendedSignedIntegralType));
+ if (page_table == (ExtendedSignedIntegralType *) NULL)
+ ThrowPCXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (id=0; id < 1024; id++)
+ {
+ page_table[id]=(ExtendedSignedIntegralType) ReadBlobLSBLong(image);
+ if (page_table[id] == 0)
+ break;
+ }
+ }
+ if (page_table != (ExtendedSignedIntegralType *) NULL)
+ if (SeekBlob(image,(ExtendedSignedIntegralType) page_table[0],SEEK_SET)
+ == -1)
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image);
+ file_size=GetBlobSize(image);
+ count=ReadBlob(image,1,(char *) &pcx_info.identifier);
+ for (id=1; id < 1024; id++)
+ {
+ MagickBool
+ read_header_ok = MagickFalse;
+
+ /*
+ Verify PCX identifier.
+ */
+ do
+ {
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ pcx_info.version=c;
+ if ((count != 1) || (pcx_info.identifier != 0x0aU))
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image);
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ pcx_info.encoding=c;
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ pcx_info.bits_per_pixel=c;
+ pcx_info.left=ReadBlobLSBShort(image);
+ pcx_info.top=ReadBlobLSBShort(image);
+ pcx_info.right=ReadBlobLSBShort(image);
+ pcx_info.bottom=ReadBlobLSBShort(image);
+ pcx_info.horizontal_resolution=ReadBlobLSBShort(image);
+ pcx_info.vertical_resolution=ReadBlobLSBShort(image);
+ if (ReadBlob(image,3*16,(char *) pcx_colormap) != 3*16)
+ break;
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ pcx_info.reserved=c;
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ pcx_info.planes=c;
+ pcx_info.bytes_per_line=ReadBlobLSBShort(image);
+ pcx_info.palette_info=ReadBlobLSBShort(image);
+ pcx_info.horizontal_screen_size=ReadBlobLSBShort(image);
+ pcx_info.vertical_screen_size=ReadBlobLSBShort(image);
+ if (EOFBlob(image))
+ break;
+ read_header_ok=MagickTrue;
+ } while (0);
+
+ if (!read_header_ok)
+ ThrowPCXReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "PCX Header (%d):\n"
+ " version=%u\n"
+ " encoding=%u\n"
+ " bits_per_pixel=%u\n"
+ " left=%u\n"
+ " top=%u\n"
+ " right=%u\n"
+ " bottom=%u\n"
+ " horizontal_resolution=%u\n"
+ " vertical_resolution=%u\n"
+ " reserved=%u\n"
+ " planes=%u\n"
+ " bytes_per_line=%u\n"
+ " palette_info=%u\n"
+ " horizontal_screen_size=%u\n"
+ " vertical_screen_size=%u",
+ id,
+ (unsigned int) pcx_info.version,
+ (unsigned int) pcx_info.encoding,
+ (unsigned int) pcx_info.bits_per_pixel,
+ (unsigned int) pcx_info.left,
+ (unsigned int) pcx_info.top,
+ (unsigned int) pcx_info.right,
+ (unsigned int) pcx_info.bottom,
+ (unsigned int) pcx_info.horizontal_resolution,
+ (unsigned int) pcx_info.vertical_resolution,
+ (unsigned int) pcx_info.reserved,
+ (unsigned int) pcx_info.planes,
+ (unsigned int) pcx_info.bytes_per_line,
+ (unsigned int) pcx_info.palette_info,
+ (unsigned int) pcx_info.horizontal_screen_size,
+ (unsigned int) pcx_info.vertical_screen_size
+ );
+
+ /*
+ Read PCX raster colormap.
+ */
+ image->columns=(pcx_info.right-pcx_info.left)+1;
+ image->rows=(pcx_info.bottom-pcx_info.top)+1;
+ image->depth=8; /* or pcx_info.bits_per_pixel */
+ image->units=PixelsPerInchResolution;
+ image->x_resolution=pcx_info.horizontal_resolution;
+ image->y_resolution=pcx_info.vertical_resolution;
+ image->colors=16;
+
+ /*
+ Validate rows, columns, bits
+ */
+ if ((image->columns == 0) ||
+ (image->rows == 0) ||
+ ((pcx_info.bits_per_pixel != 1) &&
+ (pcx_info.bits_per_pixel != 2) &&
+ (pcx_info.bits_per_pixel != 4) &&
+ (pcx_info.bits_per_pixel != 8)))
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ /*
+ Validate bytes per line. It is ok to have more bytes per line
+ than the total bits suggest, but not less.
+ */
+ {
+ size_t bytes_per_line;
+
+ bytes_per_line = MagickArraySize(image->columns,pcx_info.bits_per_pixel);
+ if (bytes_per_line)
+ bytes_per_line += 7U;
+ if (bytes_per_line)
+ bytes_per_line /= 8U;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Bytes per line: reqire >= %" MAGICK_SIZE_T_F "u, have %u",
+ (MAGICK_SIZE_T) bytes_per_line, pcx_info.bytes_per_line);
+ if ((bytes_per_line == 0) || (pcx_info.bytes_per_line < bytes_per_line))
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ /*
+ Validate number of planes. We only support 1, 2, 3, 4 but some
+ files might have extra planes (which we ignore).
+ */
+ if (pcx_info.planes == 0)
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (pcx_info.planes > 6)
+ ThrowPCXReaderException(CorruptImageError,UnsupportedNumberOfPlanes,image);
+
+ if ((pcx_info.bits_per_pixel != 8) || (pcx_info.planes == 1))
+ if ((pcx_info.version == 3) || (pcx_info.version == 5) ||
+ ((pcx_info.bits_per_pixel*pcx_info.planes) == 1))
+ {
+ image->colors=1 << (pcx_info.bits_per_pixel*pcx_info.planes);
+ if (image->colors > 256)
+ image->colors = 256;
+ }
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowPCXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if ((pcx_info.bits_per_pixel >= 8) && (pcx_info.planes != 1))
+ image->storage_class=DirectClass;
+ p=pcx_colormap;
+ for (i=0; i < image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ }
+
+ for (i=0; i < 54; i++)
+ (void) ReadBlobByte(image);
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+
+ /*
+ Check that filesize is reasonable given header
+ */
+ {
+ double
+ uncompressed_size;
+
+ uncompressed_size=((double) image->rows*pcx_info.bytes_per_line*pcx_info.planes);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Uncompressed size: %.0f", uncompressed_size);
+ if (pcx_info.encoding == 0)
+ {
+ /* Not compressed */
+ if (uncompressed_size > file_size)
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,
+ image);
+ }
+ else
+ {
+ /* RLE compressed */
+ if (uncompressed_size > file_size*254.0)
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,
+ image);
+ }
+ }
+
+
+ /*
+ Read image data.
+ */
+ pcx_packets=MagickArraySize(image->rows,
+ MagickArraySize(pcx_info.bytes_per_line,
+ pcx_info.planes));
+ if ((size_t) (pcx_info.bits_per_pixel*pcx_info.planes*image->columns) >
+ (pcx_packets*8U))
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image);
+ pcx_pixels=MagickAllocateMemory(unsigned char *,pcx_packets);
+ if (pcx_pixels == (unsigned char *) NULL)
+ ThrowPCXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ scanline=MagickAllocateArray(unsigned char *,Max(image->columns,
+ (size_t) pcx_info.bytes_per_line),Max(pcx_info.planes,8));
+ if (scanline == (unsigned char *) NULL)
+ ThrowPCXReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (pcx_info.encoding == 0)
+ {
+ /*
+ Data is not compressed
+ */
+ p=pcx_pixels;
+ while(pcx_packets != 0)
+ {
+ packet=ReadBlobByte(image);
+ if (EOFBlob(image))
+ ThrowPCXReaderException(CorruptImageError,CorruptImage,image);
+ *p++=packet;
+ pcx_packets--;
+ continue;
+ }
+ }
+ else
+ {
+ /*
+ Uncompress image data.
+ */
+ p=pcx_pixels;
+ while (pcx_packets != 0)
+ {
+ packet=ReadBlobByte(image);
+ if (EOFBlob(image))
+ ThrowPCXReaderException(CorruptImageError,CorruptImage,image);
+ if ((packet & 0xc0) != 0xc0)
+ {
+ *p++=packet;
+ pcx_packets--;
+ continue;
+ }
+ count=packet & 0x3f;
+ packet=ReadBlobByte(image);
+ if (EOFBlob(image))
+ ThrowPCXReaderException(CorruptImageError,CorruptImage,image);
+ for (; count != 0; count--)
+ {
+ *p++=packet;
+ pcx_packets--;
+ if (pcx_packets == 0)
+ break;
+ }
+ }
+ }
+ if (image->storage_class == DirectClass)
+ image->matte=pcx_info.planes > 3;
+ else
+ if ((pcx_info.version == 5) ||
+ (((size_t) pcx_info.bits_per_pixel*pcx_info.planes) == 1))
+ {
+ /*
+ Initialize image colormap.
+ */
+ if (image->colors > 256)
+ ThrowPCXReaderException(CorruptImageError,ColormapExceedsColorsLimit,
+ image);
+ if (((size_t) pcx_info.bits_per_pixel*pcx_info.planes) == 1)
+ {
+ /*
+ Monochrome colormap.
+ */
+ image->colormap[0].red=0;
+ image->colormap[0].green=0;
+ image->colormap[0].blue=0;
+ image->colormap[1].red=MaxRGB;
+ image->colormap[1].green=MaxRGB;
+ image->colormap[1].blue=MaxRGB;
+ }
+ else
+ if (image->colors > 16)
+ {
+ /*
+ 256 color images have their color map at the end of the file.
+ */
+ pcx_info.colormap_signature=ReadBlobByte(image);
+ (void) ReadBlob(image,3*image->colors,(char *) pcx_colormap);
+ p=pcx_colormap;
+ for (i=0; i < image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(*p++);
+ image->colormap[i].green=ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ }
+ }
+ }
+ /*
+ Convert PCX raster image to pixel packets.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=pcx_pixels+((unsigned long) y*pcx_info.bytes_per_line*pcx_info.planes);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ r=scanline;
+ if (image->storage_class == DirectClass)
+ for (i=0; i < (unsigned int) pcx_info.planes; i++)
+ {
+ r=scanline+i;
+ for (x=0; x < (long) pcx_info.bytes_per_line; x++)
+ {
+ switch (i)
+ {
+ case 0:
+ {
+ *r=ScaleCharToQuantum(*p++);
+ break;
+ }
+ case 1:
+ {
+ *r=ScaleCharToQuantum(*p++);
+ break;
+ }
+ case 2:
+ {
+ *r=ScaleCharToQuantum(*p++);
+ break;
+ }
+ case 3:
+ default:
+ {
+ *r=ScaleCharToQuantum(*p++);
+ break;
+ }
+ }
+ r+=(unsigned int) pcx_info.planes;
+ }
+ }
+ else
+ if ((unsigned int) pcx_info.planes > 1)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ *r++=0;
+ for (i=0; i < (unsigned int) pcx_info.planes; i++)
+ {
+ r=scanline;
+ for (x=0; x < (long) pcx_info.bytes_per_line; x++)
+ {
+ bits=(*p++);
+ for (mask=0x80; mask != 0; mask>>=1)
+ {
+ if (bits & mask)
+ *r|=1 << i;
+ r++;
+ }
+ }
+ }
+ }
+ else
+ switch (pcx_info.bits_per_pixel)
+ {
+ case 1:
+ {
+ register long
+ bit;
+
+ for (x=0; x < ((long) image->columns-7); x+=8)
+ {
+ for (bit=7; bit >= 0; bit--)
+ *r++=((*p) & (0x01 << bit) ? 0x01 : 0x00);
+ p++;
+ }
+ if ((image->columns % 8) != 0)
+ {
+ for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--)
+ *r++=((*p) & (0x01 << bit) ? 0x01 : 0x00);
+ p++;
+ }
+ break;
+ }
+ case 2:
+ {
+ for (x=0; x < ((long) image->columns-3); x+=4)
+ {
+ *r++=(*p >> 6) & 0x3;
+ *r++=(*p >> 4) & 0x3;
+ *r++=(*p >> 2) & 0x3;
+ *r++=(*p) & 0x3;
+ p++;
+ }
+ if ((image->columns % 4) != 0)
+ {
+ for (i=3; i >= (unsigned int) (4-(image->columns % 4)); i--)
+ *r++=(*p >> (i*2)) & 0x03;
+ p++;
+ }
+ break;
+ }
+ case 4:
+ {
+ for (x=0; x < ((long) image->columns-1); x+=2)
+ {
+ *r++=(*p >> 4) & 0xf;
+ *r++=(*p) & 0xf;
+ p++;
+ }
+ if ((image->columns % 2) != 0)
+ *r++=(*p++ >> 4) & 0xf;
+ break;
+ }
+ case 8:
+ {
+ (void) memcpy(r,p,image->columns);
+ break;
+ }
+ default:
+ break;
+ }
+ /*
+ Transfer image scanline.
+ */
+ r=scanline;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->storage_class == PseudoClass)
+ indexes[x]=(*r++);
+ else
+ {
+ q->red=ScaleCharToQuantum(*r++);
+ q->green=ScaleCharToQuantum(*r++);
+ q->blue=ScaleCharToQuantum(*r++);
+ if (image->matte)
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*r++));
+ }
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (image->storage_class == PseudoClass)
+ (void) SyncImage(image);
+ MagickFreeMemory(scanline);
+ MagickFreeMemory(pcx_pixels);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (page_table == (ExtendedSignedIntegralType *) NULL)
+ break;
+ if (page_table[id] == 0)
+ break;
+ if (SeekBlob(image,(ExtendedSignedIntegralType) page_table[id],SEEK_SET)
+ == -1)
+ ThrowPCXReaderException(CorruptImageError,ImproperImageHeader,image);
+ count=ReadBlob(image,1,(char *) &pcx_info.identifier);
+ if ((count != 0) && (pcx_info.identifier == 0x0a))
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+ }
+ if (page_table != (ExtendedSignedIntegralType *) NULL)
+ MagickFreeMemory(page_table);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P C X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPCXImage adds attributes for the PCX image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPCXImage method is:
+%
+% RegisterPCXImage(void)
+%
+*/
+ModuleExport void RegisterPCXImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("DCX");
+ entry->decoder=(DecoderHandler) ReadPCXImage;
+ entry->encoder=(EncoderHandler) WritePCXImage;
+ entry->seekable_stream=True;
+ entry->magick=(MagickHandler) IsDCX;
+ entry->description="ZSoft IBM PC multi-page Paintbrush";
+ entry->module="PCX";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PCX");
+ entry->decoder=(DecoderHandler) ReadPCXImage;
+ entry->encoder=(EncoderHandler) WritePCXImage;
+ entry->magick=(MagickHandler) IsPCX;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="ZSoft IBM PC Paintbrush";
+ entry->module="PCX";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P C X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPCXImage removes format registrations made by the
+% PCX module from the list of supported formats.
+%
+% The format of the UnregisterPCXImage method is:
+%
+% UnregisterPCXImage(void)
+%
+*/
+ModuleExport void UnregisterPCXImage(void)
+{
+ (void) UnregisterMagickInfo("DCX");
+ (void) UnregisterMagickInfo("PCX");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P C X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePCXImage writes an image in the ZSoft IBM PC Paintbrush file
+% format.
+%
+% The format of the WritePCXImage method is:
+%
+% unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePCXImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static MagickPassFail WriteRLEPixels(Image *image,
+ PCXInfo *pcx_info,
+ const unsigned char *pcx_row_pixels)
+{
+ register const unsigned char
+ *q;
+
+ unsigned char
+ count,
+ packet,
+ previous;
+
+ register long
+ i,
+ x;
+
+ q=pcx_row_pixels;
+
+ /* For each color plane ... */
+ for (i=0; i < (long) pcx_info->planes; i++)
+ {
+ previous=(*q++);
+ count=1;
+ /* For each column ... */
+ for (x=0; x < (long) (pcx_info->bytes_per_line-1); x++)
+ {
+ packet=(*q++);
+ if ((packet == previous) && (count < 63))
+ {
+ count++;
+ continue;
+ }
+ if ((count > 1) || ((previous & 0xc0) == 0xc0))
+ {
+ count|=0xc0;
+ (void) WriteBlobByte(image,count);
+ }
+ (void) WriteBlobByte(image,previous);
+ previous=packet;
+ count=1;
+ }
+ if ((count > 1) || ((previous & 0xc0) == 0xc0))
+ {
+ count|=0xc0;
+ (void) WriteBlobByte(image,count);
+ }
+ (void) WriteBlobByte(image,previous);
+ }
+ return (MagickPass);
+}
+
+#define LiberatePCXAllocations() \
+ { \
+ MagickFreeMemory(pcx_colormap); \
+ MagickFreeMemory(pcx_pixels); \
+ MagickFreeMemory(page_table); \
+ }
+
+#define ThrowPCXWriterException(code_,reason_,image_) \
+{ \
+ LiberatePCXAllocations(); \
+ ThrowWriterException(code_,reason_,image_); \
+}
+static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
+{
+ long
+ y;
+
+ PCXInfo
+ pcx_info;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ size_t
+ length;
+
+ unsigned char
+ *pcx_colormap = (unsigned char *) NULL,
+ *pcx_pixels = (unsigned char *) NULL;
+
+ MagickBool
+ adjoin,
+ logging,
+ write_dcx;
+
+ unsigned int
+ status;
+
+ ExtendedSignedIntegralType
+ *page_table=(ExtendedSignedIntegralType *) NULL;
+
+ unsigned long
+ scene;
+
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ logging=image->logging;
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowPCXWriterException(FileOpenError,UnableToOpenFile,image);
+
+ write_dcx=MagickFalse;
+ if (LocaleCompare(image_info->magick,"DCX") == 0)
+ {
+ /*
+ Write the DCX page table.
+ */
+ write_dcx=MagickTrue;
+ (void) WriteBlobLSBLong(image,0x3ADE68B1L);
+ page_table=MagickAllocateMemory(ExtendedSignedIntegralType *,
+ 1024*sizeof(ExtendedSignedIntegralType));
+ if (page_table == (ExtendedSignedIntegralType *) NULL)
+ ThrowPCXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (scene=0; scene < 1024; scene++)
+ (void) WriteBlobLSBLong(image,0x00000000L);
+ }
+ adjoin=(image_info->adjoin) && (image->next != (const Image *) NULL) && (write_dcx);
+ scene=0;
+ do
+ {
+ if (logging && write_dcx)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing DCX frame %lu...",scene);
+ /*
+ Ensure that image is in RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ LiberatePCXAllocations();
+ CloseBlob(image);
+ return MagickFail;
+ }
+ if (page_table != (ExtendedSignedIntegralType *) NULL)
+ page_table[scene]=TellBlob(image);
+ /*
+ Initialize PCX raster file header.
+ */
+ pcx_info.identifier=0x0a;
+ pcx_info.version=5;
+ pcx_info.encoding=1;
+ pcx_info.bits_per_pixel=8;
+ if (characteristics.palette && characteristics.monochrome)
+ pcx_info.bits_per_pixel=1;
+ pcx_info.left=0;
+ pcx_info.top=0;
+ pcx_info.right=(unsigned short) (image->columns-1);
+ pcx_info.bottom=(unsigned short) (image->rows-1);
+ pcx_info.horizontal_resolution=72;
+ pcx_info.vertical_resolution=72;
+ switch (image->units)
+ {
+ case UndefinedResolution:
+ case PixelsPerInchResolution:
+ {
+ pcx_info.horizontal_resolution=(unsigned short) image->x_resolution;
+ pcx_info.vertical_resolution=(unsigned short) image->y_resolution;
+ break;
+ }
+ case PixelsPerCentimeterResolution:
+ {
+ pcx_info.horizontal_resolution=(unsigned short) (2.54*image->x_resolution+0.5);
+ pcx_info.vertical_resolution=(unsigned short) (2.54*image->y_resolution+0.5);
+ break;
+ }
+ }
+ pcx_info.reserved=0;
+ pcx_info.planes=1;
+ if (image->storage_class == DirectClass)
+ {
+ pcx_info.planes=3;
+ if (image->matte)
+ pcx_info.planes++;
+ }
+ pcx_info.bytes_per_line=(unsigned short)
+ (((unsigned long) image->columns*pcx_info.bits_per_pixel+7)/8);
+ pcx_info.palette_info=1;
+ pcx_info.colormap_signature=0x0c;
+ /*
+ Write PCX header.
+ */
+ (void) WriteBlobByte(image,pcx_info.identifier);
+ (void) WriteBlobByte(image,pcx_info.version);
+ (void) WriteBlobByte(image,pcx_info.encoding);
+ (void) WriteBlobByte(image,pcx_info.bits_per_pixel);
+ (void) WriteBlobLSBShort(image,(unsigned int) pcx_info.left);
+ (void) WriteBlobLSBShort(image,(unsigned int) pcx_info.top);
+ (void) WriteBlobLSBShort(image,(unsigned int) pcx_info.right);
+ (void) WriteBlobLSBShort(image,(unsigned int) pcx_info.bottom);
+ (void) WriteBlobLSBShort(image,(unsigned int)
+ pcx_info.horizontal_resolution);
+ (void) WriteBlobLSBShort(image,(unsigned int) pcx_info.vertical_resolution);
+ /*
+ Dump colormap to file.
+ */
+ pcx_colormap=MagickAllocateMemory(unsigned char *,3*256);
+ if (pcx_colormap == (unsigned char *) NULL)
+ ThrowPCXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (i=0; i < (3*256); i++)
+ pcx_colormap[i]=0;
+ q=pcx_colormap;
+ if (image->storage_class == PseudoClass)
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=ScaleQuantumToChar(image->colormap[i].red);
+ *q++=ScaleQuantumToChar(image->colormap[i].green);
+ *q++=ScaleQuantumToChar(image->colormap[i].blue);
+ }
+ (void) WriteBlob(image,3*16,(char *) pcx_colormap);
+ (void) WriteBlobByte(image,pcx_info.reserved);
+ (void) WriteBlobByte(image,pcx_info.planes);
+ (void) WriteBlobLSBShort(image,(unsigned int) pcx_info.bytes_per_line);
+ (void) WriteBlobLSBShort(image,(unsigned int) pcx_info.palette_info);
+ for (i=0; i < 58; i++)
+ (void) WriteBlobByte(image,'\0');
+ /* Allocate memory for one pixel row. */
+ length=(size_t) pcx_info.bytes_per_line*pcx_info.planes;
+ pcx_pixels=MagickAllocateMemory(unsigned char *,length);
+ if (pcx_pixels == (unsigned char *) NULL)
+ ThrowPCXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ q=pcx_pixels;
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Convert DirectClass image to PCX raster pixels.
+ */
+
+ /* For each row ... */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ const PixelPacket *
+ row_pixels;
+
+ row_pixels=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (row_pixels == (const PixelPacket *) NULL)
+ break;
+
+ q=pcx_pixels;
+
+ /* For each color plane ... */
+ for (i=0; i < pcx_info.planes; i++)
+ {
+ p=row_pixels;
+ switch ((int) i)
+ {
+ case 0:
+ {
+ /* For each column ... */
+ for (x=(long) pcx_info.bytes_per_line; x > 0; x--)
+ *q++=ScaleQuantumToChar(p++->red);
+ break;
+ }
+ case 1:
+ {
+ /* For each column ... */
+ for (x=(long) pcx_info.bytes_per_line; x > 0; x--)
+ *q++=ScaleQuantumToChar(p++->green);
+ break;
+ }
+ case 2:
+ {
+ /* For each column ... */
+ for (x=(long) pcx_info.bytes_per_line; x > 0; x--)
+ *q++=ScaleQuantumToChar(p++->blue);
+ break;
+ }
+ case 3:
+ default:
+ {
+ /* For each column ... */
+ for (x=(long) pcx_info.bytes_per_line; x > 0; x--)
+ *q++=ScaleQuantumToChar(MaxRGB-p++->opacity);
+ break;
+ }
+ }
+ }
+ if (WriteRLEPixels(image,&pcx_info,pcx_pixels) == MagickFail)
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ /*
+ Convert PseudoClass image to a PCX grayscale image.
+ */
+ if (pcx_info.bits_per_pixel > 1)
+ /* For each row ... */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ q=pcx_pixels;
+ /* For each column ... */
+ for (x=0; x < (long) image->columns; x++)
+ *q++=indexes[x];
+ if (WriteRLEPixels(image,&pcx_info,pcx_pixels) == MagickFail)
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ else
+ {
+ register unsigned char
+ bit,
+ byte,
+ polarity;
+
+ /*
+ Convert PseudoClass image to a PCX monochrome image.
+ */
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]);
+ /* For each row ... */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ q=pcx_pixels;
+ /* For each column ... */
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte<<=1;
+ if (indexes[x] == polarity)
+ byte|=0x01;
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ p++;
+ }
+ if (bit != 0)
+ *q++=byte << (8-bit);
+ if (WriteRLEPixels(image,&pcx_info,pcx_pixels) == MagickFail)
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+
+ (void) WriteBlobByte(image,pcx_info.colormap_signature);
+ (void) WriteBlob(image,3*256,(char *) pcx_colormap);
+ MagickFreeMemory(pcx_pixels);
+ MagickFreeMemory(pcx_colormap);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ if (scene >= 1023)
+ break;
+ } while (adjoin);
+ if (adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ if (page_table != (ExtendedSignedIntegralType *) NULL)
+ {
+ /*
+ Write the DCX page table.
+ */
+ page_table[scene+1]=0;
+ (void) SeekBlob(image,0L,SEEK_SET);
+ (void) WriteBlobLSBLong(image,0x3ADE68B1L);
+ for (i=0; i <= (long) scene; i++)
+ (void) WriteBlobLSBLong(image,(unsigned long) page_table[i]);
+ MagickFreeMemory(page_table);
+ }
+ if (status == False)
+ ThrowPCXWriterException(FileOpenError,UnableToWriteFile,image);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/pdb.c b/coders/pdb.c
new file mode 100644
index 0000000..0f34f50
--- /dev/null
+++ b/coders/pdb.c
@@ -0,0 +1,1007 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP DDDD BBBB %
+% P P D D B B %
+% PPPP D D BBBB %
+% P D D B B %
+% P DDDD BBBB %
+% %
+% %
+% Read/Write Palm Database ImageViewer Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Typedef declarations.
+*/
+typedef struct _PDBInfo
+{
+ char
+ name[32];
+
+ short int
+ attributes,
+ version;
+
+ unsigned long
+ create_time,
+ modify_time,
+ archive_time,
+ modify_number,
+ application_info,
+ sort_info;
+
+ char
+ type[4], /* database type identifier "vIMG" */
+ id[4]; /* database creator identifier "View" */
+
+ unsigned long
+ seed,
+ next_record;
+
+ short int
+ number_records;
+} PDBInfo;
+
+typedef struct _PDBImage
+{
+ char
+ name[32],
+ version,
+ type;
+
+ unsigned long
+ reserved_1,
+ note;
+
+ unsigned short int
+ x_last,
+ y_last;
+
+ unsigned long
+ reserved_2;
+
+ unsigned short int
+ x_anchor,
+ y_anchor,
+ width,
+ height;
+} PDBImage;
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePDBImage(const ImageInfo *,Image *);
+
+static void LogPDPInfo(const PDBInfo *info)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "PDP Info:\n"
+ " name : %.32s\n"
+ " attributes : %d\n"
+ " version : %d\n"
+ " create_time : %lu\n"
+ " modify_time : %lu\n"
+ " archive_time : %lu\n"
+ " modify_number : %lu\n"
+ " application_info: %lu\n"
+ " sort_info : %lu\n"
+ " type : %.4s\n"
+ " id : %.4s\n"
+ " seed : %lu\n"
+ " next_record : %lu\n"
+ " number_records : %u",
+ info->name,
+ info->attributes,
+ info->version,
+ info->create_time,
+ info->modify_time,
+ info->archive_time,
+ info->modify_number,
+ info->application_info,
+ info->sort_info,
+ info->type,
+ info->id,
+ info->seed,
+ info->next_record,
+ info->number_records);
+}
+
+static void LogPDPImage(const PDBImage *image)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "PDP Image:\n"
+ " name: %.32s\n"
+ " version: %d\n"
+ " type: %d\n"
+ " reserved_1: %lu\n"
+ " note: %lu\n"
+ " x_last: %u\n"
+ " y_last: %u\n"
+ " reserved_2: %lu\n"
+ " x_anchor: %u\n"
+ " y_anchor: %u\n"
+ " width: %u\n"
+ " height: %u",
+ image->name,
+ image->version,
+ image->type,
+ image->reserved_1,
+ image->note,
+ image->x_last,
+ image->y_last,
+ image->reserved_2,
+ image->x_anchor,
+ image->y_anchor,
+ image->width,
+ image->height
+ );
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DecodeImage unpacks the packed image pixels into runlength-encoded
+% pixel packets.
+%
+% The format of the DecodeImage method is:
+%
+% unsigned int DecodeImage(Image *image,unsigned char *pixels,
+% const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method DecodeImage returns True if all the pixels are
+% uncompressed without error, otherwise False.
+%
+% o image: The address of a structure of type Image.
+%
+% o pixels: The address of a byte (8 bits) array of pixel data created by
+% the decoding process.
+%
+%
+*/
+static unsigned int DecodeImage(Image *image,unsigned char *pixels,
+ const size_t length)
+{
+ int
+ count,
+ pixel;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ p=pixels;
+ while (p < (pixels+length))
+ {
+ pixel=ReadBlobByte(image);
+ if (pixel <= 0x80)
+ {
+ count=pixel+1;
+ for (i=0; i < count; i++)
+ *p++=ReadBlobByte(image);
+ continue;
+ }
+ count=pixel+1-0x80;
+ pixel=ReadBlobByte(image);
+ for (i=0; i < count; i++)
+ *p++=(unsigned char) pixel;
+ }
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P D B %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPDB returns True if the image format type, identified by the
+% magick string, is PDB.
+%
+% The format of the ReadPDBImage method is:
+%
+% unsigned int IsPDB(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPDB returns True if the image format type is PDB.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPDB(const unsigned char *magick,const size_t length)
+{
+ if (length < 68)
+ return(False);
+ if (memcmp(magick+60,"vIMGView",8) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P D B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPDBImage reads an Pilot image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadPDBImage method is:
+%
+% Image *ReadPDBImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPDBImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowPDBReaderException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(pixels); \
+ ThrowReaderException(code_,reason_,image_); \
+}
+
+static Image *ReadPDBImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ record_type,
+ tag[3];
+
+ Image
+ *image;
+
+ IndexPacket
+ index;
+
+ long
+ offset,
+ y;
+
+ PDBImage
+ pdb_image;
+
+ PDBInfo
+ pdb_info;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ size_t
+ count;
+
+ unsigned char
+ *pixels = (unsigned char *) NULL;
+
+ unsigned int
+ bits_per_pixel,
+ status;
+
+ size_t
+ packets;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowPDBReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Determine if this is a PDB image file.
+ */
+ count=ReadBlob(image,32,pdb_info.name);
+ if (count != 32)
+ ThrowPDBReaderException(CorruptImageError,ImproperImageHeader,image);
+ pdb_info.name[sizeof(pdb_info.name)-1]='\0';
+ pdb_info.attributes=ReadBlobMSBShort(image);
+ pdb_info.version=ReadBlobMSBShort(image);
+ pdb_info.create_time=ReadBlobMSBLong(image);
+ pdb_info.modify_time=ReadBlobMSBLong(image);
+ pdb_info.archive_time=ReadBlobMSBLong(image);
+ pdb_info.modify_number=ReadBlobMSBLong(image);
+ pdb_info.application_info=ReadBlobMSBLong(image);
+ pdb_info.sort_info=ReadBlobMSBLong(image);
+ (void) ReadBlob(image,4,pdb_info.type);
+ (void) ReadBlob(image,4,pdb_info.id);
+ pdb_info.seed=ReadBlobMSBLong(image);
+ pdb_info.next_record=ReadBlobMSBLong(image);
+ pdb_info.number_records=ReadBlobMSBShort(image);
+ if (image->logging)
+ LogPDPInfo(&pdb_info);
+ if ((memcmp(pdb_info.type,"vIMG",4) != 0) ||
+ (memcmp(pdb_info.id,"View",4) != 0))
+ ThrowPDBReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (pdb_info.next_record != 0)
+ ThrowPDBReaderException(CoderError,MultipleRecordListNotSupported,image);
+ /*
+ Read record header.
+ */
+ offset=(long) ReadBlobMSBLong(image);
+ (void) ReadBlob(image,3,tag);
+ record_type=ReadBlobByte(image);
+ if (((record_type != 0x00) && (record_type != 0x01)) ||
+ (memcmp(tag,"\x40\x6f\x80",3) != 0))
+ ThrowPDBReaderException(CorruptImageError,CorruptImage,image);
+ if ((offset-TellBlob(image)) == 6)
+ {
+ (void) ReadBlobByte(image);
+ (void) ReadBlobByte(image);
+ }
+ if (pdb_info.number_records > 1)
+ {
+ offset=(long) ReadBlobMSBLong(image);
+ (void) ReadBlob(image,3,tag);
+ record_type=ReadBlobByte(image);
+ if (((record_type != 0x00) && (record_type != 0x01)) ||
+ (memcmp(tag,"\x40\x6f\x80",3) != 0))
+ ThrowPDBReaderException(CorruptImageError,CorruptImage,image);
+ if ((offset-TellBlob(image)) == 6)
+ {
+ (void) ReadBlobByte(image);
+ (void) ReadBlobByte(image);
+ }
+ }
+ /*
+ Read image header.
+ */
+ (void) ReadBlob(image,32,pdb_image.name);
+ pdb_image.version=ReadBlobByte(image);
+ pdb_image.type=ReadBlobByte(image);
+ pdb_image.reserved_1=ReadBlobMSBLong(image);
+ pdb_image.note=ReadBlobMSBLong(image);
+ pdb_image.x_last=ReadBlobMSBShort(image);
+ pdb_image.y_last=ReadBlobMSBShort(image);
+ pdb_image.reserved_2=ReadBlobMSBLong(image);
+ pdb_image.x_anchor=ReadBlobMSBShort(image);
+ pdb_image.y_anchor=ReadBlobMSBShort(image);
+ pdb_image.width=ReadBlobMSBShort(image);
+ pdb_image.height=ReadBlobMSBShort(image);
+ if (image->logging)
+ LogPDPImage(&pdb_image);
+ /*
+ Initialize image structure.
+ */
+ image->columns=pdb_image.width;
+ image->rows=pdb_image.height;
+ image->depth=8;
+ image->storage_class=PseudoClass;
+ bits_per_pixel=pdb_image.type == 0 ? 2 : pdb_image.type == 2 ? 4 : 1;
+ if (!AllocateImageColormap(image,1 << bits_per_pixel))
+ ThrowPDBReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowPDBReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ packets=MagickArraySize(MagickArraySize(bits_per_pixel,image->columns)/8,
+ image->rows);
+ pixels=MagickAllocateMemory(unsigned char *,packets + (packets != 0 ? 256 : 0));
+ if (pixels == (unsigned char *) NULL)
+ ThrowPDBReaderException(ResourceLimitWarning,MemoryAllocationFailed,image);
+ switch (pdb_image.version)
+ {
+ case 0:
+ {
+ image->compression=NoCompression;
+ (void) ReadBlob(image,packets,(char *) pixels);
+ break;
+ }
+ case 1:
+ {
+ image->compression=RLECompression;
+ (void) DecodeImage(image,pixels,packets);
+ break;
+ }
+ default:
+ {
+ ThrowPDBReaderException(CorruptImageError,UnrecognizedImageCompression,image);
+ }
+ }
+ p=pixels;
+ switch (bits_per_pixel)
+ {
+ case 1:
+ {
+ int
+ bit;
+
+ /*
+ Read 1-bit PDB image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < ((long) image->columns-7); x+=8)
+ {
+ for (bit=0; bit < 8; bit++)
+ {
+ index=(*p & (0x80U >> bit) ? 0x00U : 0x01U);
+ indexes[x+bit]=index;
+ *q++=image->colormap[index];
+ }
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case 2:
+ {
+ /*
+ Read 2-bit PDB image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns-3; x+=4)
+ {
+ index=(IndexPacket) (3-((*p >> 6) & 0x03));
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) (3-((*p >> 4) & 0x03));
+ VerifyColormapIndex(image,index);
+ indexes[x+1]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) (3-((*p >> 2) & 0x03));
+ VerifyColormapIndex(image,index);
+ indexes[x+2]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) (3-((*p) & 0x03));
+ VerifyColormapIndex(image,index);
+ indexes[x+3]=index;
+ *q++=image->colormap[index];
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case 4:
+ {
+ /*
+ Read 4-bit PDB image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns-1; x+=2)
+ {
+ index=(IndexPacket) (15-((*p >> 4) & 0x0f));
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ index=(IndexPacket) (15-((*p) & 0x0f));
+ VerifyColormapIndex(image,index);
+ indexes[x+1]=index;
+ *q++=image->colormap[index];
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ ThrowPDBReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+ MagickFreeMemory(pixels);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ if ((offset-TellBlob(image)) == 0)
+ {
+ char
+ *comment;
+
+ int
+ c;
+
+ register char
+ *p;
+
+ unsigned int
+ length;
+
+ /*
+ Read comment.
+ */
+ c=ReadBlobByte(image);
+ length=MaxTextExtent;
+ comment=MagickAllocateMemory(char *,length+1);
+ p=comment;
+ if (comment != (char *) NULL)
+ for ( ; c != EOF; p++)
+ {
+ if ((p-comment) >= (int) length)
+ {
+ length<<=1;
+ length+=MaxTextExtent;
+ MagickReallocMemory(char *,comment,length+1);
+ if (comment == (char *) NULL)
+ break;
+ p=comment+strlen(comment);
+ }
+ *p=c;
+ *(p+1)='\0';
+ c=ReadBlobByte(image);
+ }
+ if (comment == (char *) NULL)
+ ThrowPDBReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) SetImageAttribute(image,"comment",comment);
+ MagickFreeMemory(comment);
+ }
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P D B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPDBImage adds attributes for the PDB image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPDBImage method is:
+%
+% RegisterPDBImage(void)
+%
+*/
+ModuleExport void RegisterPDBImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PDB");
+ entry->decoder=(DecoderHandler) ReadPDBImage;
+ entry->encoder=(EncoderHandler) WritePDBImage;
+ entry->magick=(MagickHandler) IsPDB;
+ entry->description="Palm Database ImageViewer Format";
+ entry->module="PDB";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P D B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPDBImage removes format registrations made by the
+% PDB module from the list of supported formats.
+%
+% The format of the UnregisterPDBImage method is:
+%
+% UnregisterPDBImage(void)
+%
+*/
+ModuleExport void UnregisterPDBImage(void)
+{
+ (void) UnregisterMagickInfo("PDB");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P D B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePDBImage writes an image
+%
+% The format of the WritePDBImage method is:
+%
+% unsigned int WritePDBImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePDBImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static unsigned char *EncodeRLE(unsigned char *destination,
+ unsigned char *source,unsigned int literal,unsigned int repeat)
+{
+ if (literal != 0)
+ *destination++=literal-1;
+ (void) memcpy(destination,source,literal);
+ destination+=literal;
+ if (repeat != 0)
+ {
+ *destination++=0x80 | (repeat-1);
+ *destination++=source[literal];
+ }
+ return(destination);
+}
+
+#define ThrowPDBWriterException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(buffer); \
+ MagickFreeMemory(p); \
+ MagickFreeMemory(scanline); \
+ ThrowWriterException(code_,reason_,image_); \
+}
+
+static unsigned int WritePDBImage(const ImageInfo *image_info,Image *image)
+{
+ int
+ bits;
+
+ long
+ y;
+
+ PDBImage
+ pdb_image;
+
+ PDBInfo
+ pdb_info;
+
+ register long
+ x;
+
+ unsigned char
+ *buffer = (unsigned char *) NULL,
+ *p = (unsigned char *) NULL,
+ *q,
+ *scanline = (unsigned char *) NULL;
+
+ unsigned int
+ bits_per_pixel,
+ packet_size,
+ status;
+
+ size_t
+ packets;
+
+ unsigned long
+ literal,
+ repeat;
+
+ const ImageAttribute
+ *comment;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Dimensions: %lux%lu",
+ image->columns,image->rows);
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowPDBWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ bits_per_pixel=image->depth;
+ if (GetImageType(image,&image->exception) == BilevelType)
+ bits_per_pixel=1;
+ if ((bits_per_pixel != 1) && (bits_per_pixel != 2))
+ bits_per_pixel=4;
+ (void) memset(&pdb_info,0,sizeof(pdb_info));
+ (void) strlcpy(pdb_info.name,image_info->filename,sizeof(pdb_info.name));
+ pdb_info.attributes=0;
+ pdb_info.version=0;
+ pdb_info.create_time=time(NULL);
+ pdb_info.modify_time=pdb_info.create_time;
+ pdb_info.archive_time=0;
+ pdb_info.modify_number=0;
+ pdb_info.application_info=0;
+ pdb_info.sort_info=0;
+ (void) memcpy(pdb_info.type,"vIMG",4);
+ (void) memcpy(pdb_info.id,"View",4);
+ pdb_info.seed=0;
+ pdb_info.next_record=0;
+ comment=GetImageAttribute(image,"comment");
+ pdb_info.number_records=(comment == (ImageAttribute *) NULL ? 1 : 2);
+ if (image->logging)
+ LogPDPInfo(&pdb_info);
+ (void) WriteBlob(image,32,pdb_info.name);
+ (void) WriteBlobMSBShort(image,pdb_info.attributes);
+ (void) WriteBlobMSBShort(image,pdb_info.version);
+ (void) WriteBlobMSBLong(image,pdb_info.create_time);
+ (void) WriteBlobMSBLong(image,pdb_info.modify_time);
+ (void) WriteBlobMSBLong(image,pdb_info.archive_time);
+ (void) WriteBlobMSBLong(image,pdb_info.modify_number);
+ (void) WriteBlobMSBLong(image,pdb_info.application_info);
+ (void) WriteBlobMSBLong(image,pdb_info.sort_info);
+ (void) WriteBlob(image,4,pdb_info.type);
+ (void) WriteBlob(image,4,pdb_info.id);
+ (void) WriteBlobMSBLong(image,pdb_info.seed);
+ (void) WriteBlobMSBLong(image,pdb_info.next_record);
+ (void) WriteBlobMSBShort(image,pdb_info.number_records);
+ (void) memset(&pdb_image,0,sizeof(pdb_image));
+ (void) strlcpy(pdb_image.name,pdb_info.name,sizeof(pdb_image.name));
+ pdb_image.version=1; /* RLE Compressed */
+ switch(bits_per_pixel)
+ {
+ case 1: pdb_image.type=0xffU; break; /* monochrome */
+ case 2: pdb_image.type=0x00U; break; /* 2 bit gray */
+ default: pdb_image.type=0x02U; /* 4 bit gray */
+ }
+ pdb_image.reserved_1=0;
+ pdb_image.note=0;
+ pdb_image.x_last=0;
+ pdb_image.y_last=0;
+ pdb_image.reserved_2=0;
+ pdb_image.x_anchor=(short) 0xffff;
+ pdb_image.y_anchor=(short) 0xffff;
+ pdb_image.width=(short) image->columns;
+ if (image->columns % 16)
+ pdb_image.width=(short) (16*(image->columns/16+1));
+ pdb_image.height=(short) image->rows;
+ if (image->logging)
+ LogPDPImage(&pdb_image);
+ if ((pdb_image.width < image->columns) ||
+ (pdb_image.height != image->rows))
+ ThrowPDBWriterException(CoderError,ImageColumnOrRowSizeIsNotSupported, image);
+ packets=MagickArraySize(MagickArraySize(MagickArraySize(bits_per_pixel,
+ pdb_image.width)/8,
+ pdb_image.height),2);
+ p=MagickAllocateMemory(unsigned char *,packets);
+ if (p == (unsigned char *) NULL)
+ ThrowPDBWriterException(ResourceLimitWarning,MemoryAllocationFailed,image);
+ buffer=MagickAllocateMemory(unsigned char *,512);
+ if (buffer == (unsigned char *) NULL)
+ ThrowPDBWriterException(ResourceLimitWarning,MemoryAllocationFailed,image);
+ packet_size=image->depth > 8 ? 2: 1;
+ scanline=MagickAllocateArray(unsigned char *,image->columns,packet_size);
+ if (scanline == (unsigned char *) NULL)
+ ThrowPDBWriterException(ResourceLimitWarning,MemoryAllocationFailed,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Convert to GRAY raster scanline.
+ */
+ bits=8/(long) bits_per_pixel-1; /* start at most significant bits */
+ literal=0;
+ repeat=0;
+ q=p;
+ buffer[0]=0x00;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (!AcquireImagePixels(image,0,y,image->columns,1,&image->exception))
+ break;
+ (void) ExportImagePixelArea(image,GrayQuantum,image->depth,scanline,0,0);
+ for (x=0; x < pdb_image.width; x++)
+ {
+ if (x < (long) image->columns)
+ buffer[literal+repeat]|=(0xff-scanline[x*packet_size]) >>
+ (8-bits_per_pixel) << bits*bits_per_pixel;
+ bits--;
+ if (bits < 0)
+ {
+ if (((literal+repeat) > 0) &&
+ (buffer[literal+repeat] == buffer[literal+repeat-1]))
+ {
+ if (repeat == 0)
+ {
+ literal--;
+ repeat++;
+ }
+ repeat++;
+ if (0x7f < repeat)
+ {
+ q=EncodeRLE(q,buffer,literal,repeat);
+ literal=0;
+ repeat=0;
+ }
+ }
+ else
+ {
+ if (repeat >= 2)
+ literal+=repeat;
+ else
+ {
+ q=EncodeRLE(q,buffer,literal,repeat);
+ buffer[0]=buffer[literal+repeat];
+ literal=0;
+ }
+ literal++;
+ repeat=0;
+ if (0x7f < literal)
+ {
+ q=EncodeRLE(q,buffer,(literal < 0x80 ? literal : 0x80),0);
+ (void) memmove(buffer,buffer+literal+repeat,0x80);
+ literal-=0x80;
+ }
+ }
+ bits=8/(long) bits_per_pixel-1;
+ buffer[literal+repeat]=0x00;
+ }
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ q=EncodeRLE(q,buffer,literal,repeat);
+ MagickFreeMemory(scanline);
+ MagickFreeMemory(buffer);
+ /*
+ Write the Image record header.
+ */
+ (void) WriteBlobMSBLong(image,(unsigned long)
+ (TellBlob(image)+8*pdb_info.number_records));
+ (void) WriteBlobByte(image,0x40);
+ (void) WriteBlobByte(image,0x6f);
+ (void) WriteBlobByte(image,0x80);
+ (void) WriteBlobByte(image,0);
+ if (pdb_info.number_records > 1)
+ {
+ /*
+ Write the comment record header.
+ */
+ (void) WriteBlobMSBLong(image,TellBlob(image)+8+58+q-p);
+ (void) WriteBlobByte(image,0x40);
+ (void) WriteBlobByte(image,0x6f);
+ (void) WriteBlobByte(image,0x80);
+ (void) WriteBlobByte(image,1);
+ }
+ /*
+ Write the Image data.
+ */
+ (void) WriteBlob(image,32,pdb_image.name);
+ (void) WriteBlobByte(image,pdb_image.version);
+ (void) WriteBlobByte(image,pdb_image.type);
+ (void) WriteBlobMSBLong(image,pdb_image.reserved_1);
+ (void) WriteBlobMSBLong(image,pdb_image.note);
+ (void) WriteBlobMSBShort(image,pdb_image.x_last);
+ (void) WriteBlobMSBShort(image,pdb_image.y_last);
+ (void) WriteBlobMSBLong(image,pdb_image.reserved_2);
+ (void) WriteBlobMSBShort(image,pdb_image.x_anchor);
+ (void) WriteBlobMSBShort(image,pdb_image.y_anchor);
+ (void) WriteBlobMSBShort(image,pdb_image.width);
+ (void) WriteBlobMSBShort(image,pdb_image.height);
+ (void) WriteBlob(image,q-p,p);
+ MagickFreeMemory(p);
+ if (pdb_info.number_records > 1)
+ (void) WriteBlobString(image,comment->value);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/pdf.c b/coders/pdf.c
new file mode 100644
index 0000000..ef2f75b
--- /dev/null
+++ b/coders/pdf.c
@@ -0,0 +1,1737 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP DDDD FFFFF %
+% P P D D F %
+% PPPP D D FFF %
+% P D D F %
+% P DDDD F %
+% %
+% %
+% Read/Write Portable Document Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/compress.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/enum_strings.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/resize.h"
+#include "magick/shear.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int WritePDFImage(const ImageInfo *,Image *);
+#if defined(HasZLIB)
+static unsigned int ZLIBEncodeImage(Image *,const size_t,const unsigned long,unsigned char *);
+#endif
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P D F %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPDF returns True if the image format type, identified by the
+% magick string, is PDF.
+%
+% The format of the IsPDF method is:
+%
+% unsigned int IsPDF(const unsigned char *magick,const size_t offset)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPDF returns True if the image format type is PDF.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o offset: Specifies the offset of the magick string.
+%
+%
+*/
+static unsigned int IsPDF(const unsigned char *magick,const size_t offset)
+{
+ if (offset < 5)
+ return(False);
+ if (LocaleNCompare((char *) magick,"%PDF-",5) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P D F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPDFImage reads a Portable Document Format image file and
+% returns it. It allocates the memory necessary for the new Image structure
+% and returns a pointer to the new image.
+%
+% The format of the ReadPDFImage method is:
+%
+% Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPDFImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define MediaBox "/MediaBox"
+#define RenderPostscriptText "[%s] Rendering postscript..."
+
+ char
+ density[MaxTextExtent],
+ command[MaxTextExtent],
+ filename[MaxTextExtent],
+ postscript_filename[MaxTextExtent];
+
+ const char
+ *value;
+
+ const DelegateInfo
+ *delegate_info;
+
+ double
+ dx_resolution,
+ dy_resolution;
+
+ FILE
+ *file;
+
+ Image
+ *image,
+ *next_image;
+
+ ImageInfo
+ *clone_info;
+
+ int
+ count,
+ status;
+
+ unsigned int
+ antialias=4;
+
+ MagickBool
+ use_crop_box = MagickFalse;
+
+ MagickBool
+ pdf_stop_on_error = MagickFalse;
+
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ if ((value=AccessDefinition(image_info,"pdf","use-cropbox")))
+ {
+ if (strcmp(value,"true") == 0)
+ use_crop_box = True;
+ }
+
+ if ((value=AccessDefinition(image_info,"pdf","stop-on-error")))
+ {
+ if (strcmp(value,"true") == 0)
+ pdf_stop_on_error = True;
+ }
+
+ /*
+ Select Postscript delegate driver
+ */
+ delegate_info=GetPostscriptDelegateInfo(image_info,&antialias,exception);
+ if (delegate_info == (const DelegateInfo *) NULL)
+ return((Image *) NULL);
+ /*
+ Open image file.
+ */
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Open temporary output file.
+ */
+ file=AcquireTemporaryFileStream(postscript_filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ ThrowReaderTemporaryFileException(postscript_filename);
+ /*
+ Set the page density.
+ */
+ dx_resolution=72.0;
+ dy_resolution=72.0;
+ if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0))
+ {
+ (void) strlcpy(density,PSDensityGeometry,sizeof(density));
+ count=GetMagickDimension(density,&image->x_resolution,&image->y_resolution,NULL,NULL);
+ if (count != 2)
+ image->y_resolution=image->x_resolution;
+ }
+ FormatString(density,"%gx%g",image->x_resolution,image->y_resolution);
+ {
+ /*
+ Determine page geometry from the PDF media box.
+
+ Note that we can use Ghostscript to obtain the bounding box info like
+
+ gs -q -dBATCH -dNOPAUSE -sDEVICE=bbox ENV.003.01.pdf
+ %%BoundingBox: 70 61 2089 2954
+ %%HiResBoundingBox: 70.737537 61.199998 2088.587889 2953.601629
+ */
+
+ char
+ geometry[MaxTextExtent];
+
+ RectangleInfo
+ box,
+ page;
+
+ SegmentInfo
+ bounds;
+
+ unsigned long
+ height,
+ width;
+
+ int
+ rotate;
+
+ register char
+ *p,
+ *q;
+
+ register long
+ c;
+
+ rotate=0;
+ (void) memset(&page,0,sizeof(RectangleInfo));
+ (void) memset(&box,0,sizeof(RectangleInfo));
+ for (p=command; ; )
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ break;
+ (void) fputc(c,file);
+ *p++=(char) c;
+ if ((c != '\n') && (c != '\r') && ((p-command) < (MaxTextExtent-1)))
+ continue;
+ *p='\0';
+ p=command;
+ /*
+ Continue unless this is a MediaBox statement.
+ */
+ if (LocaleNCompare(command,"/Rotate ",8) == 0)
+ {
+ count=sscanf(command,"/Rotate %d",&rotate);
+ if (count > 0)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Rotate by %d degrees",rotate);
+ }
+ }
+ q=strstr(command,MediaBox);
+ if (q == (char *) NULL)
+ continue;
+ count=sscanf(q,"/MediaBox [%lf %lf %lf %lf",&bounds.x1,&bounds.y1,
+ &bounds.x2,&bounds.y2);
+ if (count != 4)
+ count=sscanf(q,"/MediaBox[%lf %lf %lf %lf",&bounds.x1,&bounds.y1,
+ &bounds.x2,&bounds.y2);
+ if (count == 4)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Parsed: MediaBox %lf %lf %lf %lf",
+ bounds.x1,bounds.y1,
+ bounds.x2,bounds.y2);
+ }
+ if (count != 4)
+ continue;
+ if ((bounds.x1 > bounds.x2) || (bounds.y1 > bounds.y2))
+ continue;
+ /*
+ Set Postscript render geometry.
+ */
+ width=(unsigned long) (bounds.x2-bounds.x1+0.5);
+ height=(unsigned long) (bounds.y2-bounds.y1+0.5);
+ if ((width <= box.width) && (height <= box.height))
+ continue;
+ page.width=width;
+ page.height=height;
+ box=page;
+ }
+ /*
+ If page is rotated right or left, then swap width and height values.
+ */
+ if ((90 == AbsoluteValue(rotate)) || (270 == AbsoluteValue(rotate)))
+ {
+ double
+ value;
+
+ value=page.width;
+ page.width=page.height;
+ page.height=value;
+ }
+ if ((page.width == 0) || (page.height == 0))
+ {
+ SetGeometry(image,&page);
+ (void) GetGeometry(PSPageGeometry,&page.x,&page.y,&page.width,
+ &page.height);
+ }
+ if (image_info->page != (char *) NULL)
+ (void) GetGeometry(image_info->page,&page.x,&page.y,&page.width,
+ &page.height);
+ geometry[0]='\0';
+ FormatString(geometry,"%lux%lu",
+ (unsigned long) ceil(page.width*image->x_resolution/dx_resolution-0.5),
+ (unsigned long) ceil(page.height*image->y_resolution/dy_resolution-0.5));
+ if (ferror(file))
+ {
+ (void) fclose(file);
+ ThrowReaderException(CorruptImageError,AnErrorHasOccurredWritingToFile,
+ image);
+ }
+ }
+
+ (void) fclose(file);
+ CloseBlob(image);
+ /*
+ Use Ghostscript to convert Postscript image.
+ */
+ {
+ char
+ options[MaxTextExtent],
+ arg[MaxTextExtent];
+
+ options[0]='\0';
+
+ if (use_crop_box)
+ (void) strlcat(options,"-dUseCropBox",sizeof(options));
+
+ if (pdf_stop_on_error)
+ {
+ if (options[0] != '\0')
+ (void) strlcat(options," ",sizeof(options));
+ (void) strlcat(options,"-dPDFSTOPONERROR",sizeof(options));
+ }
+
+ /*
+ Append subrange.
+ */
+ if (image_info->subrange != 0)
+ {
+ FormatString(arg,"-dFirstPage=%lu -dLastPage=%lu",
+ image_info->subimage+1,
+ image_info->subimage+image_info->subrange);
+ if (options[0] != '\0')
+ (void) strlcat(options," ",sizeof(options));
+ (void) strlcat(options,arg,sizeof(options));
+ }
+
+ /*
+ Append authentication string.
+ */
+ if (image_info->authenticate != (char *) NULL)
+ {
+ FormatString(arg,"-sPDFPassword=%.1024s", image_info->authenticate);
+ if (options[0] != '\0')
+ (void) strlcat(options," ",sizeof(options));
+ (void) strlcat(options,arg,sizeof(options));
+ }
+ (void) strlcpy(filename,image_info->filename,MaxTextExtent);
+ clone_info=CloneImageInfo(image_info);
+ if (!AcquireTemporaryFileName(clone_info->filename))
+ {
+ DestroyImageInfo(clone_info);
+ ThrowReaderTemporaryFileException(clone_info->filename);
+ }
+ FormatString(command,delegate_info->commands,antialias,
+ antialias,density,options,clone_info->filename,
+ postscript_filename);
+ }
+ (void) MagickMonitorFormatted(0,8,&image->exception,RenderPostscriptText,
+ image->filename);
+ status=InvokePostscriptDelegate(clone_info->verbose,command,exception);
+ (void) MagickMonitorFormatted(7,8,&image->exception,RenderPostscriptText,
+ image->filename);
+ DestroyImage(image);
+ image=(Image *) NULL;
+ if (IsAccessibleAndNotEmpty(clone_info->filename))
+ {
+ /*
+ Read Ghostscript output.
+ */
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ clone_info->magick[0]='\0';
+ clone_info->subimage=0;
+ clone_info->subrange=0;
+ MagickFreeMemory(clone_info->tile);
+ image=ReadImage(clone_info,exception);
+ }
+ (void) LiberateTemporaryFile(postscript_filename);
+ (void) LiberateTemporaryFile(clone_info->filename);
+ DestroyImageInfo(clone_info);
+ if (image == (Image *) NULL)
+ {
+ if (UndefinedException == exception->severity)
+ ThrowException(exception,DelegateError,PostscriptDelegateFailed,filename);
+ }
+ else
+ {
+ do
+ {
+ (void) strlcpy(image->magick,"PDF",sizeof(image->magick));
+ (void) strlcpy(image->filename,filename,sizeof(image->filename));
+ next_image=SyncNextImageInList(image);
+ if (next_image != (Image *) NULL)
+ image=next_image;
+ } while (next_image != (Image *) NULL);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ if (image_info->subimage != 0)
+ {
+ unsigned long
+ scene = image_info->subimage;
+
+ for (next_image=image;
+ next_image != (Image *) NULL;
+ next_image=next_image->next)
+ next_image->scene = scene++;
+ }
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P D F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPDFImage adds attributes for the PDF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPDFImage method is:
+%
+% RegisterPDFImage(void)
+%
+*/
+ModuleExport void RegisterPDFImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("EPDF");
+ entry->decoder=(DecoderHandler) ReadPDFImage;
+ entry->encoder=(EncoderHandler) WritePDFImage;
+ entry->adjoin=False;
+ entry->blob_support=False;
+ entry->seekable_stream=True;
+ entry->description="Encapsulated Portable Document Format";
+ entry->module="PDF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PDF");
+ entry->decoder=(DecoderHandler) ReadPDFImage;
+ entry->encoder=(EncoderHandler) WritePDFImage;
+ entry->magick=(MagickHandler) IsPDF;
+ entry->blob_support=False;
+ entry->seekable_stream=True;
+ entry->description="Portable Document Format";
+ entry->module="PDF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P D F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPDFImage removes format registrations made by the
+% PDF module from the list of supported formats.
+%
+% The format of the UnregisterPDFImage method is:
+%
+% UnregisterPDFImage(void)
+%
+*/
+ModuleExport void UnregisterPDFImage(void)
+{
+ (void) UnregisterMagickInfo("EPDF");
+ (void) UnregisterMagickInfo("PDF");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P D F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePDFImage writes an image in the Portable Document image
+% format.
+%
+% The format of the WritePDFImage method is:
+%
+% unsigned int WritePDFImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePDFImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static char *EscapeParenthesis(const char *text)
+{
+ register char
+ *p;
+
+ register long
+ i;
+
+ /* FIXME: use of a static buffer here makes this function not thread safe! */
+ static char
+ buffer[MaxTextExtent];
+
+ unsigned long
+ escapes;
+
+ escapes=0;
+ p=buffer;
+ for (i=0; i < (long) Min(strlen(text),(MaxTextExtent-escapes-1)); i++)
+ {
+ if ((text[i] == '(') || (text[i] == ')'))
+ {
+ *p++='\\';
+ escapes++;
+ }
+ *p++=text[i];
+ }
+ *p='\0';
+ return(buffer);
+}
+
+static unsigned int WritePDFImage(const ImageInfo *image_info,Image *image)
+{
+#define CFormat "/Filter [ /%.1024s ]\n"
+#define ObjectsPerImage 9
+
+ char
+ basename[MaxTextExtent],
+ buffer[MaxTextExtent],
+ date[MaxTextExtent],
+ density[MaxTextExtent],
+ **labels,
+ page_geometry[MaxTextExtent];
+
+ unsigned char
+ *fax_blob=(unsigned char *) NULL;
+
+ const ImageAttribute
+ *attribute;
+
+ double
+ dx_resolution,
+ dy_resolution,
+ x_resolution,
+ x_scale,
+ y_resolution,
+ y_scale;
+
+ ExtendedSignedIntegralType
+ offset;
+
+ long
+ count,
+ y;
+
+ RectangleInfo
+ geometry,
+ media_info;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register unsigned char
+ *q;
+
+ register long
+ i,
+ x;
+
+ size_t
+ fax_blob_length,
+ length;
+
+ struct tm
+ *time_meridian;
+
+ time_t
+ seconds;
+
+ unsigned char
+ *pixels;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ info_id,
+ number_pixels,
+ object,
+ pages_id,
+ root_id,
+ scene,
+ text_size;
+
+ ExtendedSignedIntegralType
+ *xref;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Allocate X ref memory.
+ */
+ xref=MagickAllocateMemory(ExtendedSignedIntegralType *,
+ 2048*sizeof(ExtendedSignedIntegralType));
+ if (xref == (ExtendedSignedIntegralType *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) memset(xref,0,2048*sizeof(ExtendedSignedIntegralType));
+ /*
+ Write Documentation Information Dictionary
+ */
+ object=0;
+ (void) WriteBlobString(image,"%PDF-1.2 \n");
+ xref[object++]=TellBlob(image);
+ info_id=object;
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"<<\n");
+ seconds=time((time_t *) NULL);
+ time_meridian=localtime(&seconds);
+ FormatString(date,"D:%04d%02d%02d%02d%02d%02d",time_meridian->tm_year+1900,
+ time_meridian->tm_mon+1,time_meridian->tm_mday,time_meridian->tm_hour,
+ time_meridian->tm_min,time_meridian->tm_sec);
+ GetPathComponent(image->filename,BasePath,basename);
+
+ FormatString(buffer,"/Title (%.1024s)\n",EscapeParenthesis(basename));
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/CreationDate (%.1024s)\n",date);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/ModDate (%.1024s)\n",date);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/Producer (%.1024s)\n",
+ EscapeParenthesis(GetMagickVersion((unsigned long *) NULL)));
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,">>\n");
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Catalog object.
+ */
+ xref[object++]=TellBlob(image);
+ root_id=object;
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"<<\n");
+ (void) WriteBlobString(image,"/Type /Catalog\n");
+ FormatString(buffer,"/Pages %lu 0 R\n",object+1);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,">>\n");
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Pages object.
+ */
+ xref[object++]=TellBlob(image);
+ pages_id=object;
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"<<\n");
+ (void) WriteBlobString(image,"/Type /Pages\n");
+ FormatString(buffer,"/Kids [ %lu 0 R ",object+1);
+ (void) WriteBlobString(image,buffer);
+ count=(long) (pages_id+ObjectsPerImage+1);
+ if (image_info->adjoin)
+ {
+ Image
+ *kid_image;
+
+ /*
+ Predict page object id's.
+ */
+ kid_image=image;
+ for ( ; kid_image->next != (Image *) NULL; count+=ObjectsPerImage)
+ {
+ FormatString(buffer,"%ld 0 R ",count);
+ (void) WriteBlobString(image,buffer);
+ kid_image=kid_image->next;
+ }
+ MagickReallocMemory(ExtendedSignedIntegralType *,xref,
+ (count+2048)*sizeof(ExtendedSignedIntegralType));
+ if (xref == (ExtendedSignedIntegralType *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ (void) WriteBlobString(image,"]\n");
+ FormatString(buffer,"/Count %lu\n",(count-pages_id)/ObjectsPerImage);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,">>\n");
+ (void) WriteBlobString(image,"endobj\n");
+ scene=0;
+ do
+ {
+ ImageCharacteristics
+ characteristics;
+
+ CompressionType
+ compression;
+
+ /*
+ Analyze image properties.
+ */
+ (void) GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception);
+
+ compression=image->compression;
+ if (image_info->compression != UndefinedCompression)
+ {
+ /*
+ ImageInfo compression always prevails if it is set.
+ */
+ compression=image_info->compression;
+ }
+ else
+ {
+ /*
+ Default to Zip compression unless the image was JPEG
+ compressed and is not now monochrome or colormapped.
+ */
+ if ((JPEGCompression != compression) ||
+ (characteristics.monochrome) ||
+ (characteristics.palette))
+ {
+#if defined(HasZLIB)
+ compression=ZipCompression;
+#else
+ compression=LZWCompression;
+#endif
+ }
+ }
+
+ switch (compression)
+ {
+#if !defined(HasJPEG)
+ case JPEGCompression:
+ {
+ /*
+ If JPEG compression is not supported, then use RLE compression
+ and report a warning to user.
+ */
+ compression=RLECompression;
+ ThrowException(&image->exception,MissingDelegateError,JPEGLibraryIsNotAvailable,image->filename);
+ break;
+ }
+#endif
+#if !defined(HasZLIB)
+ case ZipCompression:
+ {
+ /*
+ If ZIP compression is not supported, then use RLE compression
+ and report a warning to user.
+ */
+ compression=RLECompression;
+ ThrowException(&image->exception,MissingDelegateError,ZipLibraryIsNotAvailable,image->filename);
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%s compression.",
+ CompressionTypeToString(compression));
+
+ /*
+ Scale image to size of Portable Document page.
+ */
+ text_size=0;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ text_size=(unsigned int)
+ (MultilineCensus(attribute->value)*image_info->pointsize+12);
+ SetGeometry(image,&geometry);
+ geometry.y=(long) text_size;
+ FormatString(page_geometry,"%lux%lu",image->columns,image->rows);
+ if (image_info->page != (char *) NULL)
+ {
+ (void) strlcpy(page_geometry,image_info->page,MaxTextExtent);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Page: %s (from ImageInfo) ", page_geometry);
+
+ }
+ else
+ {
+ if ((image->page.width != 0) && (image->page.height != 0))
+ {
+ (void) FormatString(page_geometry,"%lux%lu%+ld%+ld",image->page.width,
+ image->page.height,image->page.x,image->page.y);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Page: %s (from Image)", page_geometry);
+ }
+ else
+ {
+ if (LocaleCompare(image_info->magick,"PDF") == 0)
+ {
+ (void) strlcpy(page_geometry,PSPageGeometry,sizeof(page_geometry));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Page: %s (defaulted)", page_geometry);
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Page: %s (from Image columns/rows)",
+ page_geometry);
+
+ }
+ }
+ }
+ (void) GetMagickGeometry(page_geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ (void) GetGeometry(page_geometry,&media_info.x,&media_info.y,
+ &media_info.width,&media_info.height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image Resolution: %gx%g %s",
+ image->x_resolution,
+ image->y_resolution,
+ ResolutionTypeToString(image->units));
+ /*
+ Scale relative to dots-per-inch.
+ */
+ dx_resolution=72.0;
+ dy_resolution=72.0;
+ x_resolution=72.0;
+ (void) strlcpy(density,PSDensityGeometry,sizeof(density));
+ count=GetMagickDimension(density,&x_resolution,&y_resolution,NULL,NULL);
+ if (count != 2)
+ y_resolution=x_resolution;
+ /*
+ Use override resolution information if it appears to be valid.
+ */
+ if ((image_info->density != (char *) NULL) &&
+ ((image_info->units == PixelsPerInchResolution) ||
+ (image_info->units == PixelsPerCentimeterResolution)))
+ {
+ count=GetMagickDimension(image_info->density,&x_resolution,
+ &y_resolution,NULL,NULL);
+ if (count != 2)
+ y_resolution=x_resolution;
+ if (image_info->units == PixelsPerCentimeterResolution)
+ {
+ x_resolution *= 2.54;
+ y_resolution *= 2.54;
+ }
+ }
+ /*
+ Use image resolution information if it appears to be valid.
+ */
+ else if ((image->x_resolution > 0.0) && (image->y_resolution > 0.0) &&
+ ((image->units == PixelsPerInchResolution) ||
+ (image->units == PixelsPerCentimeterResolution)))
+ {
+ x_resolution = image->x_resolution;
+ y_resolution = image->y_resolution;
+ if (image->units == PixelsPerCentimeterResolution)
+ {
+ x_resolution *= 2.54;
+ y_resolution *= 2.54;
+ }
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "PDF Resolution: %gx%g DPI",
+ x_resolution,y_resolution);
+
+ x_scale=(geometry.width*dx_resolution)/x_resolution;
+ geometry.width=(unsigned long) (x_scale+0.5);
+ y_scale=(geometry.height*dy_resolution)/y_resolution;
+ geometry.height=(unsigned long) (y_scale+0.5);
+ /*
+ Write Page object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"<<\n");
+ (void) WriteBlobString(image,"/Type /Page\n");
+ FormatString(buffer,"/Parent %lu 0 R\n",pages_id);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"/Resources <<\n");
+ FormatString(buffer,"/XObject << /Im%lu %lu 0 R >>\n",image->scene,
+ object+4);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/ProcSet %lu 0 R >>\n",object+3);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/MediaBox [0 0 %ld %ld]\n",
+ media_info.width,media_info.height);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/CropBox [%ld %ld %ld %ld]\n",geometry.x,geometry.y,
+ geometry.x+geometry.width,geometry.y+geometry.height);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/Contents %lu 0 R\n",object+1);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,">>\n");
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Contents object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"<<\n");
+ FormatString(buffer,"/Length %lu 0 R\n",object+1);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,">>\n");
+ (void) WriteBlobString(image,"stream\n");
+ offset=TellBlob(image);
+ (void) WriteBlobString(image,"q\n");
+ labels=(char **) NULL;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ labels=StringToList(attribute->value);
+ if (labels != (char **) NULL)
+ {
+ for (i=0; labels[i] != (char *) NULL; i++)
+ {
+ (void) WriteBlobString(image,"BT\n");
+ FormatString(buffer,"/F%lu %g Tf\n",image->scene,
+ image_info->pointsize);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%ld %g Td\n",geometry.x,geometry.y+
+ geometry.height+i*image_info->pointsize+12);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"(%.1024s) Tj\n",labels[i]);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"ET\n");
+ MagickFreeMemory(labels[i]);
+ }
+ MagickFreeMemory(labels);
+ }
+ FormatString(buffer,"%g 0 0 %g %ld %ld cm\n",x_scale,y_scale,geometry.x,
+ geometry.y);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/Im%lu Do\n",image->scene);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"Q\n");
+ offset=TellBlob(image)-offset;
+ (void) WriteBlobString(image,"endstream\n");
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Length object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%lu\n",(unsigned long) offset);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Procset object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ if ((image->storage_class == DirectClass) || (image->colors > 256))
+ (void) strlcpy(buffer,"[ /PDF /Text /ImageC",sizeof(buffer));
+ else
+ if (compression == FaxCompression)
+ (void) strlcpy(buffer,"[ /PDF /Text /ImageB",sizeof(buffer));
+ else
+ (void) strlcpy(buffer,"[ /PDF /Text /ImageI",sizeof(buffer));
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image," ]\n");
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write XObject object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"<<\n");
+ (void) WriteBlobString(image,"/Type /XObject\n");
+ (void) WriteBlobString(image,"/Subtype /Image\n");
+ FormatString(buffer,"/Name /Im%lu\n",image->scene);
+ (void) WriteBlobString(image,buffer);
+ switch (compression)
+ {
+ case NoCompression:
+ {
+ FormatString(buffer,CFormat,"ASCII85Decode");
+ break;
+ }
+ case JPEGCompression:
+ {
+ FormatString(buffer,CFormat,"DCTDecode");
+ if (image->colorspace != CMYKColorspace)
+ break;
+ (void) WriteBlobString(image,buffer);
+ (void) strlcpy(buffer,"/Decode [1 0 1 0 1 0 1 0]\n",sizeof(buffer));
+ break;
+ }
+ case LZWCompression:
+ {
+ FormatString(buffer,CFormat,"LZWDecode");
+ break;
+ }
+ case ZipCompression:
+ {
+ FormatString(buffer,CFormat,"FlateDecode");
+ break;
+ }
+ case FaxCompression:
+ {
+ char
+ CCITTParam[4];
+
+ ExceptionInfo
+ exception;
+
+ /*
+ Try compressing page to Group4 to see if it is
+ supported, otherwise we will fall back to Group3.
+ */
+ (void) strlcpy(CCITTParam,"0",sizeof(CCITTParam));
+ GetExceptionInfo(&exception);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Executing ImageToHuffman2DBlob for CCITT Fax4 ...");
+ fax_blob=ImageToHuffman2DBlob(image,image_info,&fax_blob_length,
+ &exception);
+ if (fax_blob != (unsigned char *) NULL)
+ {
+ (void) strlcpy(CCITTParam,"-1",sizeof(CCITTParam));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "ImageToHuffman2DBlob reports success!");
+ }
+ DestroyExceptionInfo(&exception);
+ (void) strlcpy(buffer,"/Filter [ /CCITTFaxDecode ]\n",sizeof(buffer));
+ (void) WriteBlobString(image,buffer);
+ (void) strlcpy(buffer,"/Interpolate false\n",sizeof(buffer));
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,
+ "/DecodeParms [ << /K %.1024s /BlackIs1 false /Columns %ld /Rows %ld >> ]\n",
+ CCITTParam,image->columns,image->rows);
+ break;
+ }
+ default:
+ {
+ FormatString(buffer,CFormat,"RunLengthDecode");
+ break;
+ }
+ }
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/Width %lu\n",image->columns);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/Height %lu\n",image->rows);
+ (void) WriteBlobString(image,buffer);
+ if (compression == FaxCompression)
+ strlcpy(buffer,"/ColorSpace /DeviceGray\n",MaxTextExtent);
+ else
+ FormatString(buffer,"/ColorSpace %lu 0 R\n",object+2);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/BitsPerComponent %d\n",
+ compression == FaxCompression ? 1 : 8);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/Length %lu 0 R\n",object+1);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,">>\n");
+ (void) WriteBlobString(image,"stream\n");
+ offset=TellBlob(image);
+ number_pixels=image->columns*image->rows;
+ if ((compression == FaxCompression) ||
+ ((image_info->type != TrueColorType) &&
+ characteristics.grayscale))
+ {
+ /*
+ Write grayscale output.
+ */
+ switch (compression)
+ {
+ case FaxCompression:
+ {
+ /*
+ Try Group4 first and use Group3 as a fallback.
+ */
+ if (fax_blob != (unsigned char *) NULL)
+ {
+ (void) WriteBlob(image,fax_blob_length,fax_blob);
+ MagickFreeMemory(fax_blob);
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Executing HuffmanEncodeImage for CCITT Fax3 ...");
+ if (!HuffmanEncodeImage(image_info,image))
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "HuffmanEncodeImage reports failure!");
+ }
+ break;
+ }
+ case JPEGCompression:
+ {
+ unsigned char
+ *jpeg_blob;
+
+ /*
+ Write image in JPEG format.
+ */
+ jpeg_blob=ImageToJPEGBlob(image,image_info,&length,&image->exception);
+ if (jpeg_blob == (unsigned char *) NULL)
+ ThrowWriterException2(CoderError,image->exception.reason,image);
+ (void) WriteBlob(image,length,jpeg_blob);
+ MagickFreeMemory(jpeg_blob);
+ break;
+ }
+ case RLECompression:
+ default:
+ {
+ /*
+ Allocate pixel array.
+ */
+ length=number_pixels;
+ pixels=MagickAllocateMemory(unsigned char *,length);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ /*
+ Dump Runlength encoded pixels.
+ */
+ q=pixels;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+#if defined(HasZLIB)
+ if (compression == ZipCompression)
+ status=ZLIBEncodeImage(image,length,image_info->quality,pixels);
+ else
+#endif /* defined(HasZLIB) */
+ if (compression == LZWCompression)
+ status=LZWEncodeImage(image,length,pixels);
+ else
+ status=PackbitsEncodeImage(image,length,pixels);
+ MagickFreeMemory(pixels);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ break;
+ }
+ case NoCompression:
+ {
+ /*
+ Dump uncompressed PseudoColor packets.
+ */
+ Ascii85Initialize(image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ Ascii85Encode(image,
+ ScaleQuantumToChar(PixelIntensityToQuantum(p)));
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ Ascii85Flush(image);
+ break;
+ }
+ }
+ }
+ else
+ if ((image->storage_class == DirectClass) || (image->colors > 256) ||
+ (compression == JPEGCompression))
+ switch (compression)
+ {
+ case JPEGCompression:
+ {
+ unsigned char
+ *jpeg_blob;
+
+ /*
+ Write image in JPEG format.
+ */
+ jpeg_blob=ImageToJPEGBlob(image,image_info,&length,&image->exception);
+ if (jpeg_blob == (unsigned char *) NULL)
+ ThrowWriterException2(CoderError,image->exception.reason,image);
+ (void) WriteBlob(image,length,jpeg_blob);
+ MagickFreeMemory(jpeg_blob);
+ break;
+ }
+ case RLECompression:
+ default:
+ {
+ /*
+ Allocate pixel array.
+ */
+ length=(image->colorspace == CMYKColorspace ? 4 : 3)*number_pixels;
+ pixels=MagickAllocateMemory(unsigned char *,length);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ /*
+ Dump runoffset encoded pixels.
+ */
+ q=pixels;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->matte && (p->opacity == TransparentOpacity))
+ {
+ *q++=ScaleQuantumToChar(MaxRGB);
+ *q++=ScaleQuantumToChar(MaxRGB);
+ *q++=ScaleQuantumToChar(MaxRGB);
+ p++;
+ continue;
+ }
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ if (image->colorspace == CMYKColorspace)
+ *q++=ScaleQuantumToChar(p->opacity);
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+#if defined(HasZLIB)
+ if (compression == ZipCompression)
+ status=ZLIBEncodeImage(image,length,image_info->quality,pixels);
+ else
+#endif /* defined(HasZLIB) */
+ if (compression == LZWCompression)
+ status=LZWEncodeImage(image,length,pixels);
+ else
+ status=PackbitsEncodeImage(image,length,pixels);
+ MagickFreeMemory(pixels);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ break;
+ }
+ case NoCompression:
+ {
+ /*
+ Dump uncompressed DirectColor packets.
+ */
+ Ascii85Initialize(image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->matte && (p->opacity == TransparentOpacity))
+ {
+ Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
+ Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
+ Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
+ continue;
+ }
+ Ascii85Encode(image,ScaleQuantumToChar(p->red));
+ Ascii85Encode(image,ScaleQuantumToChar(p->green));
+ Ascii85Encode(image,ScaleQuantumToChar(p->blue));
+ if (image->colorspace == CMYKColorspace)
+ Ascii85Encode(image,ScaleQuantumToChar(p->opacity));
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ Ascii85Flush(image);
+ break;
+ }
+ }
+ else
+ {
+ /*
+ Dump number of colors and colormap.
+ */
+ switch (compression)
+ {
+ case RLECompression:
+ default:
+ {
+ /*
+ Allocate pixel array.
+ */
+ length=number_pixels;
+ pixels=MagickAllocateMemory(unsigned char *,length);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Dump Runlength encoded pixels.
+ */
+ q=pixels;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ *q++=indexes[x];
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+#if defined(HasZLIB)
+ if (compression == ZipCompression)
+ status=ZLIBEncodeImage(image,length,image_info->quality,pixels);
+ else
+#endif /* defined(HasZLIB) */
+ if (compression == LZWCompression)
+ status=LZWEncodeImage(image,length,pixels);
+ else
+ status=PackbitsEncodeImage(image,length,pixels);
+ MagickFreeMemory(pixels);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ break;
+ }
+ case NoCompression:
+ {
+ /*
+ Dump uncompressed PseudoColor packets.
+ */
+ Ascii85Initialize(image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ Ascii85Encode(image,indexes[x]);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ Ascii85Flush(image);
+ break;
+ }
+ }
+ }
+ offset=TellBlob(image)-offset;
+ (void) WriteBlobString(image,"\nendstream\n");
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Length object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%lu\n",(unsigned long) offset);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Colorspace object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ if (image->colorspace == CMYKColorspace)
+ {
+ (void) strlcpy(buffer,"/DeviceCMYK\n",sizeof(buffer));
+ }
+ else
+ {
+ if ((compression == FaxCompression) ||
+ (compression == Group4Compression) ||
+ ((image_info->type != TrueColorType) &&
+ (characteristics.grayscale)))
+ {
+ (void) strlcpy(buffer,"/DeviceGray\n",sizeof(buffer));
+ }
+ else
+ {
+ if ((image->storage_class == DirectClass) || (image->colors > 256) ||
+ (compression == JPEGCompression))
+ (void) strlcpy(buffer,"/DeviceRGB\n",sizeof(buffer));
+ else
+ FormatString(buffer,"[ /Indexed /DeviceRGB %u %lu 0 R ]\n",
+ (unsigned int) image->colors-1,object+1);
+ }
+ }
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Colormap object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"<<\n");
+ if ((image->storage_class != DirectClass) && (image->colors <= 256) &&
+ (compression != FaxCompression))
+ {
+ if (compression == NoCompression)
+ (void) WriteBlobString(image,"/Filter [ /ASCII85Decode ]\n");
+ FormatString(buffer,"/Length %lu 0 R\n",object+1);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,">>\n");
+ (void) WriteBlobString(image,"stream\n");
+ offset=TellBlob(image);
+ if (compression == NoCompression)
+ Ascii85Initialize(image);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ if (compression == NoCompression)
+ {
+ Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].red));
+ Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].green));
+ Ascii85Encode(image,ScaleQuantumToChar(image->colormap[i].blue));
+ continue;
+ }
+ (void) WriteBlobByte(image,
+ ScaleQuantumToChar(image->colormap[i].red));
+ (void) WriteBlobByte(image,
+ ScaleQuantumToChar(image->colormap[i].green));
+ (void) WriteBlobByte(image,
+ ScaleQuantumToChar(image->colormap[i].blue));
+ }
+ if (compression == NoCompression)
+ Ascii85Flush(image);
+ }
+ offset=TellBlob(image)-offset;
+ (void) WriteBlobString(image,"\nendstream\n");
+ (void) WriteBlobString(image,"endobj\n");
+ /*
+ Write Length object.
+ */
+ xref[object++]=TellBlob(image);
+ FormatString(buffer,"%lu 0 obj\n",object);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%lu\n",(unsigned long) offset);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"endobj\n");
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ /*
+ Write Xref object.
+ */
+ offset=TellBlob(image)-xref[0]+10;
+ (void) WriteBlobString(image,"xref\n");
+ FormatString(buffer,"0 %lu\n",object+1);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"0000000000 65535 f \n");
+ for (i=0; i < (long) object; i++)
+ {
+ FormatString(buffer,"%010lu 00000 n \n",(unsigned long) xref[i]);
+ (void) WriteBlobString(image,buffer);
+ }
+ (void) WriteBlobString(image,"trailer\n");
+ (void) WriteBlobString(image,"<<\n");
+ FormatString(buffer,"/Size %lu\n",object+1);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/Info %lu 0 R\n",info_id);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"/Root %lu 0 R\n",root_id);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,">>\n");
+ (void) WriteBlobString(image,"startxref\n");
+ FormatString(buffer,"%lu\n",(unsigned long) offset);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"%%EOF\n");
+ MagickFreeMemory(xref);
+ CloseBlob(image);
+ MagickFreeMemory(fax_blob);
+ return(True);
+}
+
+#if defined(HasZLIB)
+#include "zlib.h"
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Z L I B E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ZLIBEncodeImage compresses an image via ZLIB-coding specific to
+% Postscript Level II or Portable Document Format. To ensure portability, the
+% binary ZLIB bytes are encoded as ASCII base-85.
+%
+% The format of the ZLIBEncodeImage method is:
+%
+% unsigned int ZLIBEncodeImage(Image *image,const size_t length,
+% const unsigned long quality,unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method ZLIBEncodeImage returns True if all the pixels are
+% compressed without error, otherwise False.
+%
+% o file: The address of a structure of type FILE. ZLIB encoded pixels
+% are written to this file.
+%
+% o length: A value that specifies the number of pixels to compress.
+%
+% o quality: the compression level (0-100).
+%
+% o pixels: The address of an unsigned array of characters containing the
+% pixels to compress.
+%
+%
+*/
+static voidpf ZLIBAllocFunc(voidpf opaque, uInt items, uInt size)
+{
+ ARG_NOT_USED(opaque);
+ return MagickMallocCleared((size_t) items*size);
+}
+static void ZLIBFreeFunc(voidpf opaque, voidpf address)
+{
+ ARG_NOT_USED(opaque);
+ MagickFree(address);
+}
+static unsigned int ZLIBEncodeImage(Image *image,const size_t length,
+ const unsigned long quality,unsigned char *pixels)
+{
+ int
+ status;
+
+ register long
+ i;
+
+ unsigned char
+ *compressed_pixels;
+
+ unsigned long
+ compressed_packets;
+
+ z_stream
+ stream;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ compressed_packets=(unsigned long) (1.001*length+12);
+ compressed_pixels=MagickAllocateMemory(unsigned char *,compressed_packets);
+ if (compressed_pixels == (unsigned char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ (void) memset(&stream,0,sizeof(stream));
+ stream.next_in=pixels;
+ stream.avail_in=(unsigned int) length;
+ stream.next_out=compressed_pixels;
+ stream.avail_out=(unsigned int) compressed_packets;
+ stream.zalloc=ZLIBAllocFunc;
+ stream.zfree=ZLIBFreeFunc;
+ stream.opaque=(voidpf) NULL;
+ status=deflateInit(&stream,(int) Min(quality/10,9));
+ if (status == Z_OK)
+ {
+ status=deflate(&stream,Z_FINISH);
+ if (status == Z_STREAM_END)
+ status=deflateEnd(&stream);
+ else
+ (void) deflateEnd(&stream);
+ compressed_packets=stream.total_out;
+ }
+ if (status)
+ ThrowBinaryException(CoderError,UnableToZipCompressImage,(char *) NULL)
+ else
+ for (i=0; i < (long) compressed_packets; i++)
+ (void) WriteBlobByte(image,compressed_pixels[i]);
+ MagickFreeMemory(compressed_pixels);
+ return(!status);
+}
+#endif
diff --git a/coders/pict.c b/coders/pict.c
new file mode 100644
index 0000000..cf634d6
--- /dev/null
+++ b/coders/pict.c
@@ -0,0 +1,1960 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP IIIII CCCC TTTTT %
+% P P I C T %
+% PPPP I C T %
+% P I C T %
+% P IIIII CCCC T %
+% %
+% %
+% Read/Write Apple Macintosh QuickDraw/PICT Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/composite.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+ GraphicsMagick Macintosh PICT Methods.
+*/
+#define ReadPixmap(pixmap) \
+ { \
+ pixmap.version=ReadBlobMSBShort(image); \
+ pixmap.pack_type=ReadBlobMSBShort(image); \
+ pixmap.pack_size=ReadBlobMSBLong(image); \
+ pixmap.horizontal_resolution=ReadBlobMSBLong(image); \
+ pixmap.vertical_resolution=ReadBlobMSBLong(image); \
+ pixmap.pixel_type=ReadBlobMSBShort(image); \
+ pixmap.bits_per_pixel=ReadBlobMSBShort(image); \
+ pixmap.component_count=ReadBlobMSBShort(image); \
+ pixmap.component_size=ReadBlobMSBShort(image); \
+ pixmap.plane_bytes=ReadBlobMSBLong(image); \
+ pixmap.table=ReadBlobMSBLong(image); \
+ pixmap.reserved=ReadBlobMSBLong(image); \
+ }
+
+#define ValidatePixmap(pixmap) \
+ (!(EOFBlob(image) || \
+ pixmap.bits_per_pixel <= 0 || pixmap.bits_per_pixel > 32 || \
+ pixmap.component_count <= 0 || pixmap.component_count > 4 || \
+ pixmap.component_size <= 0))
+
+#define ReadRectangle(rectangle) \
+ { \
+ rectangle.top=ReadBlobMSBShort(image); \
+ rectangle.left=ReadBlobMSBShort(image); \
+ rectangle.bottom=ReadBlobMSBShort(image); \
+ rectangle.right=ReadBlobMSBShort(image); \
+ }
+
+#define ValidateRectangle(rectangle) \
+ (!(EOFBlob(image) || \
+ (rectangle.top > rectangle.bottom || rectangle.left > rectangle.right)))
+
+typedef struct _PICTCode
+{
+ char
+ *name;
+
+ long
+ length;
+
+ char
+ *description;
+} PICTCode;
+
+typedef struct _PICTPixmap
+{
+ short
+ version,
+ pack_type;
+
+ unsigned long
+ pack_size,
+ horizontal_resolution,
+ vertical_resolution;
+
+ short
+ pixel_type,
+ bits_per_pixel,
+ component_count,
+ component_size;
+
+ unsigned long
+ plane_bytes,
+ table,
+ reserved;
+} PICTPixmap;
+
+typedef struct _PICTRectangle
+{
+ short
+ top,
+ left,
+ bottom,
+ right;
+} PICTRectangle;
+
+static const PICTCode
+ codes[] =
+ {
+ /* 0x00 */ { (char *) "NOP", 0, (char *) "nop" },
+ /* 0x01 */ { (char *) "Clip", 0, (char *) "clip" },
+ /* 0x02 */ { (char *) "BkPat", 8, (char *) "background pattern" },
+ /* 0x03 */ { (char *) "TxFont", 2, (char *) "text font (word)" },
+ /* 0x04 */ { (char *) "TxFace", 1, (char *) "text face (byte)" },
+ /* 0x05 */ { (char *) "TxMode", 2, (char *) "text mode (word)" },
+ /* 0x06 */ { (char *) "SpExtra", 4, (char *) "space extra (fixed point)" },
+ /* 0x07 */ { (char *) "PnSize", 4, (char *) "pen size (point)" },
+ /* 0x08 */ { (char *) "PnMode", 2, (char *) "pen mode (word)" },
+ /* 0x09 */ { (char *) "PnPat", 8, (char *) "pen pattern" },
+ /* 0x0a */ { (char *) "FillPat", 8, (char *) "fill pattern" },
+ /* 0x0b */ { (char *) "OvSize", 4, (char *) "oval size (point)" },
+ /* 0x0c */ { (char *) "Origin", 4, (char *) "dh, dv (word)" },
+ /* 0x0d */ { (char *) "TxSize", 2, (char *) "text size (word)" },
+ /* 0x0e */ { (char *) "FgColor", 4, (char *) "foreground color (longword)" },
+ /* 0x0f */ { (char *) "BkColor", 4, (char *) "background color (longword)" },
+ /* 0x10 */ { (char *) "TxRatio", 8, (char *) "numerator (point), denominator (point)" },
+ /* 0x11 */ { (char *) "Version", 1, (char *) "version (byte)" },
+ /* 0x12 */ { (char *) "BkPixPat", 0, (char *) "color background pattern" },
+ /* 0x13 */ { (char *) "PnPixPat", 0, (char *) "color pen pattern" },
+ /* 0x14 */ { (char *) "FillPixPat", 0, (char *) "color fill pattern" },
+ /* 0x15 */ { (char *) "PnLocHFrac", 2, (char *) "fractional pen position" },
+ /* 0x16 */ { (char *) "ChExtra", 2, (char *) "extra for each character" },
+ /* 0x17 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x18 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x19 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x1a */ { (char *) "RGBFgCol", 6, (char *) "RGB foreColor" },
+ /* 0x1b */ { (char *) "RGBBkCol", 6, (char *) "RGB backColor" },
+ /* 0x1c */ { (char *) "HiliteMode", 0, (char *) "hilite mode flag" },
+ /* 0x1d */ { (char *) "HiliteColor", 6, (char *) "RGB hilite color" },
+ /* 0x1e */ { (char *) "DefHilite", 0, (char *) "Use default hilite color" },
+ /* 0x1f */ { (char *) "OpColor", 6, (char *) "RGB OpColor for arithmetic modes" },
+ /* 0x20 */ { (char *) "Line", 8, (char *) "pnLoc (point), newPt (point)" },
+ /* 0x21 */ { (char *) "LineFrom", 4, (char *) "newPt (point)" },
+ /* 0x22 */ { (char *) "ShortLine", 6, (char *) "pnLoc (point, dh, dv (-128 .. 127))" },
+ /* 0x23 */ { (char *) "ShortLineFrom", 2, (char *) "dh, dv (-128 .. 127)" },
+ /* 0x24 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x25 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x26 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x27 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x28 */ { (char *) "LongText", 0, (char *) "txLoc (point), count (0..255), text" },
+ /* 0x29 */ { (char *) "DHText", 0, (char *) "dh (0..255), count (0..255), text" },
+ /* 0x2a */ { (char *) "DVText", 0, (char *) "dv (0..255), count (0..255), text" },
+ /* 0x2b */ { (char *) "DHDVText", 0, (char *) "dh, dv (0..255), count (0..255), text" },
+ /* 0x2c */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x2d */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x2e */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x2f */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x30 */ { (char *) "frameRect", 8, (char *) "rect" },
+ /* 0x31 */ { (char *) "paintRect", 8, (char *) "rect" },
+ /* 0x32 */ { (char *) "eraseRect", 8, (char *) "rect" },
+ /* 0x33 */ { (char *) "invertRect", 8, (char *) "rect" },
+ /* 0x34 */ { (char *) "fillRect", 8, (char *) "rect" },
+ /* 0x35 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x36 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x37 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x38 */ { (char *) "frameSameRect", 0, (char *) "rect" },
+ /* 0x39 */ { (char *) "paintSameRect", 0, (char *) "rect" },
+ /* 0x3a */ { (char *) "eraseSameRect", 0, (char *) "rect" },
+ /* 0x3b */ { (char *) "invertSameRect", 0, (char *) "rect" },
+ /* 0x3c */ { (char *) "fillSameRect", 0, (char *) "rect" },
+ /* 0x3d */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x3e */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x3f */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x40 */ { (char *) "frameRRect", 8, (char *) "rect" },
+ /* 0x41 */ { (char *) "paintRRect", 8, (char *) "rect" },
+ /* 0x42 */ { (char *) "eraseRRect", 8, (char *) "rect" },
+ /* 0x43 */ { (char *) "invertRRect", 8, (char *) "rect" },
+ /* 0x44 */ { (char *) "fillRRrect", 8, (char *) "rect" },
+ /* 0x45 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x46 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x47 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x48 */ { (char *) "frameSameRRect", 0, (char *) "rect" },
+ /* 0x49 */ { (char *) "paintSameRRect", 0, (char *) "rect" },
+ /* 0x4a */ { (char *) "eraseSameRRect", 0, (char *) "rect" },
+ /* 0x4b */ { (char *) "invertSameRRect", 0, (char *) "rect" },
+ /* 0x4c */ { (char *) "fillSameRRect", 0, (char *) "rect" },
+ /* 0x4d */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x4e */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x4f */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x50 */ { (char *) "frameOval", 8, (char *) "rect" },
+ /* 0x51 */ { (char *) "paintOval", 8, (char *) "rect" },
+ /* 0x52 */ { (char *) "eraseOval", 8, (char *) "rect" },
+ /* 0x53 */ { (char *) "invertOval", 8, (char *) "rect" },
+ /* 0x54 */ { (char *) "fillOval", 8, (char *) "rect" },
+ /* 0x55 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x56 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x57 */ { (char *) "reserved", 8, (char *) "reserved for Apple use" },
+ /* 0x58 */ { (char *) "frameSameOval", 0, (char *) "rect" },
+ /* 0x59 */ { (char *) "paintSameOval", 0, (char *) "rect" },
+ /* 0x5a */ { (char *) "eraseSameOval", 0, (char *) "rect" },
+ /* 0x5b */ { (char *) "invertSameOval", 0, (char *) "rect" },
+ /* 0x5c */ { (char *) "fillSameOval", 0, (char *) "rect" },
+ /* 0x5d */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x5e */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x5f */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x60 */ { (char *) "frameArc", 12, (char *) "rect, startAngle, arcAngle" },
+ /* 0x61 */ { (char *) "paintArc", 12, (char *) "rect, startAngle, arcAngle" },
+ /* 0x62 */ { (char *) "eraseArc", 12, (char *) "rect, startAngle, arcAngle" },
+ /* 0x63 */ { (char *) "invertArc", 12, (char *) "rect, startAngle, arcAngle" },
+ /* 0x64 */ { (char *) "fillArc", 12, (char *) "rect, startAngle, arcAngle" },
+ /* 0x65 */ { (char *) "reserved", 12, (char *) "reserved for Apple use" },
+ /* 0x66 */ { (char *) "reserved", 12, (char *) "reserved for Apple use" },
+ /* 0x67 */ { (char *) "reserved", 12, (char *) "reserved for Apple use" },
+ /* 0x68 */ { (char *) "frameSameArc", 4, (char *) "rect, startAngle, arcAngle" },
+ /* 0x69 */ { (char *) "paintSameArc", 4, (char *) "rect, startAngle, arcAngle" },
+ /* 0x6a */ { (char *) "eraseSameArc", 4, (char *) "rect, startAngle, arcAngle" },
+ /* 0x6b */ { (char *) "invertSameArc", 4, (char *) "rect, startAngle, arcAngle" },
+ /* 0x6c */ { (char *) "fillSameArc", 4, (char *) "rect, startAngle, arcAngle" },
+ /* 0x6d */ { (char *) "reserved", 4, (char *) "reserved for Apple use" },
+ /* 0x6e */ { (char *) "reserved", 4, (char *) "reserved for Apple use" },
+ /* 0x6f */ { (char *) "reserved", 4, (char *) "reserved for Apple use" },
+ /* 0x70 */ { (char *) "framePoly", 0, (char *) "poly" },
+ /* 0x71 */ { (char *) "paintPoly", 0, (char *) "poly" },
+ /* 0x72 */ { (char *) "erasePoly", 0, (char *) "poly" },
+ /* 0x73 */ { (char *) "invertPoly", 0, (char *) "poly" },
+ /* 0x74 */ { (char *) "fillPoly", 0, (char *) "poly" },
+ /* 0x75 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x76 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x77 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x78 */ { (char *) "frameSamePoly", 0, (char *) "poly (NYI)" },
+ /* 0x79 */ { (char *) "paintSamePoly", 0, (char *) "poly (NYI)" },
+ /* 0x7a */ { (char *) "eraseSamePoly", 0, (char *) "poly (NYI)" },
+ /* 0x7b */ { (char *) "invertSamePoly", 0, (char *) "poly (NYI)" },
+ /* 0x7c */ { (char *) "fillSamePoly", 0, (char *) "poly (NYI)" },
+ /* 0x7d */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x7e */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x7f */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x80 */ { (char *) "frameRgn", 0, (char *) "region" },
+ /* 0x81 */ { (char *) "paintRgn", 0, (char *) "region" },
+ /* 0x82 */ { (char *) "eraseRgn", 0, (char *) "region" },
+ /* 0x83 */ { (char *) "invertRgn", 0, (char *) "region" },
+ /* 0x84 */ { (char *) "fillRgn", 0, (char *) "region" },
+ /* 0x85 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x86 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x87 */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x88 */ { (char *) "frameSameRgn", 0, (char *) "region (NYI)" },
+ /* 0x89 */ { (char *) "paintSameRgn", 0, (char *) "region (NYI)" },
+ /* 0x8a */ { (char *) "eraseSameRgn", 0, (char *) "region (NYI)" },
+ /* 0x8b */ { (char *) "invertSameRgn", 0, (char *) "region (NYI)" },
+ /* 0x8c */ { (char *) "fillSameRgn", 0, (char *) "region (NYI)" },
+ /* 0x8d */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x8e */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x8f */ { (char *) "reserved", 0, (char *) "reserved for Apple use" },
+ /* 0x90 */ { (char *) "BitsRect", 0, (char *) "copybits, rect clipped" },
+ /* 0x91 */ { (char *) "BitsRgn", 0, (char *) "copybits, rgn clipped" },
+ /* 0x92 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x93 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x94 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x95 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x96 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x97 */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x98 */ { (char *) "PackBitsRect", 0, (char *) "packed copybits, rect clipped" },
+ /* 0x99 */ { (char *) "PackBitsRgn", 0, (char *) "packed copybits, rgn clipped" },
+ /* 0x9a */ { (char *) "DirectBitsRect", 0, (char *) "PixMap, srcRect, dstRect, mode, PixData" },
+ /* 0x9b */ { (char *) "DirectBitsRgn", 0, (char *) "PixMap, srcRect, dstRect, mode, maskRgn, PixData" },
+ /* 0x9c */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x9d */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x9e */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0x9f */ { (char *) "reserved", -1, (char *) "reserved for Apple use" },
+ /* 0xa0 */ { (char *) "ShortComment", 2, (char *) "kind (word)" },
+ /* 0xa1 */ { (char *) "LongComment", 0, (char *) "kind (word), size (word), data" }
+ };
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePICTImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DecodeImage decompresses an image via Macintosh pack bits
+% decoding for Macintosh PICT images.
+%
+% The format of the DecodeImage method is:
+%
+% unsigned char* DecodeImage(const ImageInfo *image_info,Image *blob,
+% Image *image,unsigned long bytes_per_line,const int bits_per_pixel)
+%
+% A description of each parameter follows:
+%
+% o status: Method DecodeImage returns True if all the pixels are
+% uncompressed without error, otherwise False.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o blob,image: The address of a structure of type Image.
+%
+% o bytes_per_line: This integer identifies the number of bytes in a
+% scanline.
+%
+% o bits_per_pixel: The number of bits in a pixel.
+%
+%
+*/
+
+static unsigned char *ExpandBuffer(unsigned char *pixels,
+ unsigned long *bytes_per_line,const unsigned int bits_per_pixel)
+{
+ register long
+ i;
+
+ register unsigned char
+ *p,
+ *q;
+
+ static unsigned char
+ scanline[8*256];
+
+ p=pixels;
+ q=scanline;
+ switch (bits_per_pixel)
+ {
+ case 8:
+ case 16:
+ case 32:
+ return(pixels);
+ case 4:
+ {
+ for (i=0; i < (long) *bytes_per_line; i++)
+ {
+ *q++=(*p >> 4U) & 0xffU;
+ *q++=(*p & 15U);
+ p++;
+ }
+ *bytes_per_line*=2;
+ break;
+ }
+ case 2:
+ {
+ for (i=0; i < (long) *bytes_per_line; i++)
+ {
+ *q++=(*p >> 6U) & 0x03U;
+ *q++=(*p >> 4U) & 0x03U;
+ *q++=(*p >> 2U) & 0x03U;
+ *q++=(*p & 3U);
+ p++;
+ }
+ *bytes_per_line*=4;
+ break;
+ }
+ case 1:
+ {
+ for (i=0; i < (long) *bytes_per_line; i++)
+ {
+ *q++=(*p >> 7) & 0x01;
+ *q++=(*p >> 6) & 0x01;
+ *q++=(*p >> 5) & 0x01;
+ *q++=(*p >> 4) & 0x01;
+ *q++=(*p >> 3) & 0x01;
+ *q++=(*p >> 2) & 0x01;
+ *q++=(*p >> 1) & 0x01;
+ *q++=(*p & 0x01);
+ p++;
+ }
+ *bytes_per_line*=8;
+ break;
+ }
+ default:
+ break;
+ }
+ return(scanline);
+}
+
+static unsigned char *DecodeImage(const ImageInfo *image_info,
+ Image *blob,Image *image,unsigned long bytes_per_line,
+ const unsigned int bits_per_pixel)
+{
+ long
+ j,
+ y;
+
+ register long
+ i;
+
+ register unsigned char
+ *p,
+ *q;
+
+ size_t
+ allocated_pixels,
+ row_bytes;
+
+ unsigned char
+ *pixels,
+ *scanline;
+
+ unsigned long
+ bytes_per_pixel,
+ length,
+ number_pixels,
+ scanline_length,
+ width;
+
+ ARG_NOT_USED(image_info);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "DecodeImage: bytes_per_line=%lu,"
+ " bits_per_pixel=%u",
+ bytes_per_line, bits_per_pixel);
+
+ /*
+ Determine pixel buffer size.
+ */
+ if (bits_per_pixel <= 8)
+ bytes_per_line&=0x7fff;
+ width=image->columns;
+ bytes_per_pixel=1;
+ if (bits_per_pixel == 16)
+ {
+ bytes_per_pixel=2;
+ width*=2;
+ }
+ else
+ if (bits_per_pixel == 32)
+ width*=image->matte ? 4 : 3;
+ if (bytes_per_line == 0)
+ bytes_per_line=width;
+ row_bytes=(size_t) (image->columns | 0x8000);
+ if (image->storage_class == DirectClass)
+ row_bytes=(size_t) ((4*image->columns) | 0x8000);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "DecodeImage: Using %lu bytes per line, %"
+ MAGICK_SIZE_T_F "u bytes per row",
+ bytes_per_line,
+ (MAGICK_SIZE_T) row_bytes);
+ /*
+ Allocate pixel and scanline buffer.
+ */
+ pixels=MagickAllocateArray(unsigned char *,image->rows,row_bytes);
+ if (pixels == (unsigned char *) NULL)
+ return((unsigned char *) NULL);
+ allocated_pixels=image->rows*row_bytes;
+ (void) memset(pixels,0,allocated_pixels);
+ scanline=MagickAllocateMemory(unsigned char *,row_bytes);
+ if (scanline == (unsigned char *) NULL)
+ return((unsigned char *) NULL);
+ if (bytes_per_line < 8)
+ {
+ /*
+ Pixels are already uncompressed.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=pixels+y*width;
+ number_pixels=bytes_per_line;
+ if (ReadBlob(blob,number_pixels,(char *) scanline) != number_pixels)
+ {
+ ThrowException(&image->exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ goto decode_error_exit;
+ }
+ p=ExpandBuffer(scanline,&number_pixels,bits_per_pixel);
+ (void) memcpy(q,p,number_pixels);
+ }
+ MagickFreeMemory(scanline);
+ return(pixels);
+ }
+ /*
+ Uncompress RLE pixels into uncompressed pixel buffer.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=pixels+y*width;
+ if (bytes_per_line > 200)
+ scanline_length=ReadBlobMSBShort(blob);
+ else
+ scanline_length=ReadBlobByte(blob);
+ if (scanline_length >= row_bytes)
+ {
+ ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage,
+ "scanline length exceeds row bytes");
+ goto decode_error_exit;
+ }
+ if (ReadBlob(blob,scanline_length,(char *) scanline) != scanline_length)
+ {
+ ThrowException(&image->exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ goto decode_error_exit;
+ }
+ for (j=0; j < (long) scanline_length; )
+ if ((scanline[j] & 0x80) == 0)
+ {
+ length=(scanline[j] & 0xff)+1;
+ number_pixels=length*bytes_per_pixel;
+ p=ExpandBuffer(scanline+j+1,&number_pixels,bits_per_pixel);
+ if (j+number_pixels >= scanline_length)
+ {
+ ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage,
+ "Decoded RLE pixels exceeds allocation!");
+ goto decode_error_exit;
+ }
+ if ((q+number_pixels > pixels+allocated_pixels))
+ {
+ ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage,
+ "Decoded RLE pixels exceeds allocation!");
+ goto decode_error_exit;
+ }
+
+ (void) memcpy(q,p,number_pixels); /* ASAN report */
+ q+=number_pixels;
+ j+=length*bytes_per_pixel+1;
+ }
+ else
+ {
+ length=((scanline[j]^0xff) & 0xff)+2;
+ number_pixels=bytes_per_pixel;
+ p=ExpandBuffer(scanline+j+1,&number_pixels,bits_per_pixel);
+ for (i=0; i < (long) length; i++)
+ {
+ if ((q+number_pixels > pixels+allocated_pixels))
+ {
+ ThrowException(&image->exception,CorruptImageError,UnableToUncompressImage,
+ "Decoded RLE pixels exceeds allocation!");
+ goto decode_error_exit;
+ }
+ (void) memcpy(q,p,number_pixels);
+ q+=number_pixels;
+ }
+ j+=bytes_per_pixel+1;
+ }
+ }
+ MagickFreeMemory(scanline);
+ return(pixels);
+
+ decode_error_exit:
+
+ MagickFreeMemory(scanline);
+ MagickFreeMemory(pixels);
+ return (unsigned char *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method EncodeImage compresses an image via Macintosh pack bits encoding
+% for Macintosh PICT images.
+%
+% The format of the EncodeImage method is:
+%
+% size_t EncodeImage(Image *image,const unsigned char *scanline,
+% const unsigned long bytes_per_line,unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method EncodeImage returns the number of encoded pixels.
+%
+% o image: The address of a structure of type Image.
+%
+% o scanline: A pointer to an array of characters to pack.
+%
+% o bytes_per_line: The number of bytes in a scanline.
+%
+% o pixels: A pointer to an array of characters where the packed
+% characters are stored.
+%
+%
+*/
+static size_t EncodeImage(Image *image,const unsigned char *scanline,
+ const unsigned long bytes_per_line,unsigned char *pixels)
+{
+#define MaxCount 128U
+#define MaxPackbitsRunlength 128
+
+ long
+ count,
+ repeat_count,
+ runlength;
+
+ register const unsigned char
+ *p;
+
+ register long
+ i;
+
+ register unsigned char
+ *q;
+
+ size_t
+ length;
+
+ unsigned char
+ index;
+
+ /*
+ Pack scanline.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(scanline != (unsigned char *) NULL);
+ assert(pixels != (unsigned char *) NULL);
+ count=0;
+ runlength=0;
+ p=scanline+(bytes_per_line-1);
+ q=pixels;
+ index=(*p);
+ for (i=(long) bytes_per_line-1; i >= 0; i--)
+ {
+ if (index == *p)
+ runlength++;
+ else
+ {
+ if (runlength < 3)
+ while (runlength > 0)
+ {
+ *q++=(unsigned char) index;
+ runlength--;
+ count++;
+ if (count == MaxCount)
+ {
+ *q++=(unsigned char) (MaxCount-1);
+ count-=MaxCount;
+ }
+ }
+ else
+ {
+ if (count > 0)
+ *q++=(unsigned char) (count-1);
+ count=0;
+ while (runlength > 0)
+ {
+ repeat_count=runlength;
+ if (repeat_count > MaxPackbitsRunlength)
+ repeat_count=MaxPackbitsRunlength;
+ *q++=(unsigned char) index;
+ *q++=(unsigned char) (257-repeat_count);
+ runlength-=repeat_count;
+ }
+ }
+ runlength=1;
+ }
+ index=(*p);
+ p--;
+ }
+ if (runlength < 3)
+ while (runlength > 0)
+ {
+ *q++=(unsigned char) index;
+ runlength--;
+ count++;
+ if (count == MaxCount)
+ {
+ *q++=(unsigned char) (MaxCount-1);
+ count-=MaxCount;
+ }
+ }
+ else
+ {
+ if (count > 0)
+ *q++=(unsigned char) (count-1);
+ count=0;
+ while (runlength > 0)
+ {
+ repeat_count=runlength;
+ if (repeat_count > MaxPackbitsRunlength)
+ repeat_count=MaxPackbitsRunlength;
+ *q++=(unsigned char) index;
+ *q++=(unsigned char) (257-repeat_count);
+ runlength-=repeat_count;
+ }
+ }
+ if (count > 0)
+ *q++= (unsigned char) (count-1);
+ /*
+ Write the number of and the packed length.
+ */
+ length=(q-pixels);
+ if (bytes_per_line > 200)
+ {
+ (void) WriteBlobMSBShort(image,(const magick_uint16_t) length);
+ length+=2;
+ }
+ else
+ {
+ (void) WriteBlobByte(image,(const magick_uint8_t) length);
+ length++;
+ }
+ while (q != pixels)
+ {
+ q--;
+ (void) WriteBlobByte(image,*q);
+ }
+ return(length);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P I C T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPICTImage reads an Apple Macintosh QuickDraw/PICT image file
+% and returns it. It allocates the memory necessary for the new Image
+% structure and returns a pointer to the new image.
+%
+% The format of the ReadPICTImage method is:
+%
+% Image *ReadPICTImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPICTImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowPICTReaderException(code_,reason_,image_) \
+{ \
+ if (clone_info) \
+ DestroyImageInfo(clone_info); \
+ ThrowReaderException(code_,reason_,image_); \
+}
+
+static Image *ReadPICTImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ char
+ geometry[MaxTextExtent];
+
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info = (ImageInfo *) NULL;
+
+ IndexPacket
+ index;
+
+ int
+ c,
+ version;
+
+ unsigned int
+ code,
+ flags;
+
+ long
+ j,
+ y;
+
+ PICTRectangle
+ frame;
+
+ PICTPixmap
+ pixmap;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ size_t
+ length;
+
+ unsigned int
+ jpeg,
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowPICTReaderException(FileOpenError,UnableToOpenFile,image);
+ pixmap.bits_per_pixel=0;
+ pixmap.component_count=0;
+ /*
+ Read PICT header.
+ */
+ pixmap.bits_per_pixel=0;
+ pixmap.component_count=0;
+ for (i=0; i < 512; i++)
+ (void) ReadBlobByte(image); /* skip header */
+ (void) ReadBlobMSBShort(image); /* skip picture size */
+ ReadRectangle(frame);
+ if (!ValidateRectangle(frame))
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ while ((c=ReadBlobByte(image)) == 0);
+ if (c != 0x11)
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ version=ReadBlobByte(image);
+ if (version == 2)
+ {
+ c=ReadBlobByte(image);
+ if (c != 0xff)
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ else
+ if (version != 1)
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Validate dimensions
+ */
+ if ((frame.left < 0) || (frame.right < 0) || (frame.top < 0) || (frame.bottom < 0) ||
+ (frame.left >= frame.right) || (frame.top >= frame.bottom))
+ {
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+
+ /*
+ Create black canvas.
+ */
+ flags=0;
+ image->columns=frame.right-frame.left;
+ image->rows=frame.bottom-frame.top;
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Dimensions: %lux%lu",image->columns,image->rows);
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowPICTReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Interpret PICT opcodes.
+ */
+ jpeg=False;
+ for (code=0; EOFBlob(image) == False; )
+ {
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if ((version == 1) || ((TellBlob(image) % 2) != 0))
+ {
+ if ((c=ReadBlobByte(image)) == EOF) /* returns int */
+ break;
+ code=(unsigned int) c;
+ }
+ if (version == 2)
+ code=ReadBlobMSBShort(image); /* returns magick_uint16_t */
+ if (code > 0xa1)
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Code %04X:",code);
+ }
+ else
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Code %04X %.1024s: %.1024s",code,
+ codes[code].name,codes[code].description);
+ switch (code)
+ {
+ case 0x01:
+ {
+ /*
+ Clipping rectangle.
+ */
+ length=ReadBlobMSBShort(image);
+ if (length != 0x000a)
+ {
+ for (i=0; i < (long) (length-2); i++)
+ (void) ReadBlobByte(image);
+ break;
+ }
+ ReadRectangle(frame);
+ if (!ValidateRectangle(frame))
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ if ((frame.left & 0x8000) || (frame.top & 0x8000))
+ break;
+ image->columns=frame.right-frame.left;
+ image->rows=frame.bottom-frame.top;
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowPICTReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ (void) SetImageEx(image,OpaqueOpacity,exception);
+ break;
+ }
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ {
+ long
+ pattern;
+
+ unsigned long
+ height,
+ width;
+
+ /*
+ Skip pattern definition.
+ */
+ pattern=ReadBlobMSBShort(image);
+ for (i=0; i < 8; i++)
+ (void) ReadBlobByte(image);
+ if (pattern == 2)
+ {
+ for (i=0; i < 5; i++)
+ (void) ReadBlobByte(image);
+ break;
+ }
+ if (pattern != 1)
+ ThrowPICTReaderException(CorruptImageError,UnknownPatternType,
+ image);
+ length=ReadBlobMSBShort(image);
+ ReadRectangle(frame);
+ if (!ValidateRectangle(frame))
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ ReadPixmap(pixmap);
+ if (!ValidatePixmap(pixmap))
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ (void) ReadBlobMSBLong(image);
+ flags=ReadBlobMSBShort(image);
+ length=ReadBlobMSBShort(image);
+ for (i=0; i <= (long) length; i++)
+ (void) ReadBlobMSBLong(image);
+ width=frame.bottom-frame.top;
+ height=frame.right-frame.left;
+ image->depth=pixmap.bits_per_pixel <= 8 ? 8 : QuantumDepth;
+ if (pixmap.bits_per_pixel < 8)
+ image->depth=8;
+ if (pixmap.bits_per_pixel <= 8)
+ length&=0x7fff;
+ if (pixmap.bits_per_pixel == 16)
+ width<<=1;
+ if (length == 0)
+ length=width;
+ if (length < 8)
+ {
+ for (i=0; i < (long) (length*height); i++)
+ (void) ReadBlobByte(image);
+ }
+ else
+ for (j=0; j < (int) height; j++)
+ if (length > 200)
+ for (j=0; j < ReadBlobMSBShort(image); j++)
+ (void) ReadBlobByte(image);
+ else
+ for (j=0; j < ReadBlobByte(image); j++)
+ (void) ReadBlobByte(image);
+ break;
+ }
+ case 0x1b:
+ {
+ /*
+ Initialize image background color.
+ */
+ image->background_color.red=(Quantum)
+ ScaleShortToQuantum(ReadBlobMSBShort(image));
+ image->background_color.green=(Quantum)
+ ScaleShortToQuantum(ReadBlobMSBShort(image));
+ image->background_color.blue=(Quantum)
+ ScaleShortToQuantum(ReadBlobMSBShort(image));
+ break;
+ }
+ case 0x70:
+ case 0x71:
+ case 0x72:
+ case 0x73:
+ case 0x74:
+ case 0x75:
+ case 0x76:
+ case 0x77:
+ {
+ /*
+ Skip polygon or region.
+ */
+ length=ReadBlobMSBShort(image);
+ for (i=0; i < (long) (length-2); i++)
+ (void) ReadBlobByte(image);
+ break;
+ }
+ case 0x90:
+ case 0x91:
+ case 0x98:
+ case 0x99:
+ case 0x9a:
+ case 0x9b:
+ {
+ long
+ bytes_per_line;
+
+ PICTRectangle
+ source,
+ destination;
+
+ register unsigned char
+ *p;
+
+ size_t
+ j;
+
+ unsigned char
+ *pixels;
+
+ Image
+ *tile_image;
+
+ /*
+ Pixmap clipped by a rectangle.
+ */
+ bytes_per_line=0;
+ if ((code != 0x9a) && (code != 0x9b))
+ bytes_per_line=ReadBlobMSBShort(image);
+ else
+ {
+ (void) ReadBlobMSBShort(image);
+ (void) ReadBlobMSBShort(image);
+ (void) ReadBlobMSBShort(image);
+ }
+ ReadRectangle(frame);
+ if (!ValidateRectangle(frame))
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Initialize tile image.
+ */
+ tile_image=CloneImage(image,frame.right-frame.left,
+ frame.bottom-frame.top,True,exception);
+ if (tile_image == (Image *) NULL)
+ return((Image *) NULL);
+ DestroyBlob(tile_image);
+ tile_image->blob=CloneBlobInfo((BlobInfo *) NULL);
+ if ((code == 0x9a) || (code == 0x9b) || (bytes_per_line & 0x8000))
+ {
+ ReadPixmap(pixmap);
+ if (!ValidatePixmap(pixmap))
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ tile_image->matte=pixmap.component_count == 4;
+ }
+ if ((code != 0x9a) && (code != 0x9b))
+ {
+ /*
+ Initialize colormap.
+ */
+ tile_image->colors=2;
+ if (bytes_per_line & 0x8000)
+ {
+ (void) ReadBlobMSBLong(image);
+ flags=ReadBlobMSBShort(image);
+ tile_image->colors=ReadBlobMSBShort(image)+1;
+ }
+ if (!AllocateImageColormap(tile_image,tile_image->colors))
+ {
+ DestroyImage(tile_image);
+ ThrowPICTReaderException(ResourceLimitError,MemoryAllocationFailed,image)
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Allocated tile image colormap with %u colors",tile_image->colors);
+ if (bytes_per_line & 0x8000)
+ {
+ for (i=0; i < (long) tile_image->colors; i++)
+ {
+ j=ReadBlobMSBShort(image) % tile_image->colors;
+ if (flags & 0x8000)
+ j=i;
+ tile_image->colormap[j].red=(Quantum)
+ ScaleShortToQuantum(ReadBlobMSBShort(image));
+ tile_image->colormap[j].green=(Quantum)
+ ScaleShortToQuantum(ReadBlobMSBShort(image));
+ tile_image->colormap[j].blue=(Quantum)
+ ScaleShortToQuantum(ReadBlobMSBShort(image));
+ }
+ }
+ else
+ {
+ for (i=0; i < (long) tile_image->colors; i++)
+ {
+ tile_image->colormap[i].red=(Quantum) (MaxRGB-
+ tile_image->colormap[i].red);
+ tile_image->colormap[i].green=(Quantum) (MaxRGB-
+ tile_image->colormap[i].green);
+ tile_image->colormap[i].blue=(Quantum) (MaxRGB-
+ tile_image->colormap[i].blue);
+ }
+ }
+ }
+ ReadRectangle(source);
+ if (!ValidateRectangle(source))
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ ReadRectangle(destination);
+ if (!ValidateRectangle(destination))
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ (void) ReadBlobMSBShort(image);
+ if ((code == 0x91) || (code == 0x99) || (code == 0x9b))
+ {
+ /*
+ Skip region.
+ */
+ length=ReadBlobMSBShort(image);
+ for (i=0; i <= (long) (length-2); i++)
+ (void) ReadBlobByte(image);
+ }
+ if ((code != 0x9a) && (code != 0x9b) &&
+ (bytes_per_line & 0x8000) == 0)
+ pixels=DecodeImage(image_info,image,tile_image,bytes_per_line,1);
+ else
+ pixels=DecodeImage(image_info,image,tile_image,bytes_per_line,
+ pixmap.bits_per_pixel);
+ if (pixels == (unsigned char *) NULL)
+ {
+ CopyException(exception, &tile_image->exception);
+ DestroyImage(tile_image);
+ ThrowPICTReaderException(ResourceLimitError,MemoryAllocationFailed,image)
+ }
+ /*
+ Convert PICT tile image to pixel packets.
+ */
+ p=pixels;
+ for (y=0; y < (long) tile_image->rows; y++)
+ {
+ q=SetImagePixels(tile_image,0,y,tile_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(tile_image);
+ for (x=0; x < (long) tile_image->columns; x++)
+ {
+ if (tile_image->storage_class == PseudoClass)
+ {
+ index=(IndexPacket) (*p);
+ VerifyColormapIndex(tile_image,index);
+ indexes[x]=index;
+ q->red=tile_image->colormap[index].red;
+ q->green=tile_image->colormap[index].green;
+ q->blue=tile_image->colormap[index].blue;
+ }
+ else
+ {
+ if (pixmap.bits_per_pixel == 16)
+ {
+ i=(*p++);
+ j=(*p);
+ q->red=ScaleCharToQuantum((i & 0x7c) << 1);
+ q->green=ScaleCharToQuantum(((i & 0x03) << 6) |
+ ((j & 0xe0) >> 2));
+ q->blue=ScaleCharToQuantum((j & 0x1f) << 3);
+ }
+ else
+ if (!tile_image->matte)
+ {
+ q->red=ScaleCharToQuantum(*p);
+ q->green=
+ ScaleCharToQuantum(*(p+tile_image->columns));
+ q->blue=ScaleCharToQuantum(*(p+2*tile_image->columns));
+ }
+ else
+ {
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p));
+ q->red=ScaleCharToQuantum(*(p+tile_image->columns));
+ q->green=(Quantum)
+ ScaleCharToQuantum(*(p+2*tile_image->columns));
+ q->blue=
+ ScaleCharToQuantum(*(p+3*tile_image->columns));
+ }
+ }
+ p++;
+ q++;
+ }
+ if (!SyncImagePixels(tile_image))
+ break;
+ if ((tile_image->storage_class == DirectClass) &&
+ (pixmap.bits_per_pixel != 16))
+ p+=(pixmap.component_count-1)*tile_image->columns;
+ if (destination.bottom == (long) image->rows)
+ if (QuantumTick(y,tile_image->rows))
+ if (!MagickMonitorFormatted(y,tile_image->rows,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(pixels);
+ if (jpeg == False)
+ if ((code == 0x9a) || (code == 0x9b) ||
+ (bytes_per_line & 0x8000))
+ (void) CompositeImage(image,CopyCompositeOp,tile_image,
+ destination.left,destination.top);
+ DestroyImage(tile_image);
+ if (destination.bottom != (long) image->rows)
+ if (!MagickMonitorFormatted(destination.bottom,image->rows,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ break;
+ }
+ case 0xa1:
+ {
+ unsigned char
+ *info;
+
+ unsigned int
+ type;
+
+ /*
+ Comment.
+ */
+ type=ReadBlobMSBShort(image);
+ length=ReadBlobMSBShort(image);
+ if (length == 0)
+ break;
+ (void) ReadBlobMSBLong(image);
+ length-=4;
+ if (length == 0)
+ break;
+ info=MagickAllocateMemory(unsigned char *,length);
+ if (info == (unsigned char *) NULL)
+ break;
+ (void) ReadBlob(image,length,info);
+ switch (type)
+ {
+ case 0xe0:
+ {
+ if (length == 0)
+ break;
+ if (SetImageProfile(image,"ICM",info,length) == MagickFail)
+ ThrowPICTReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ MagickFreeMemory(info);
+ break;
+ }
+ case 0x1f2:
+ {
+ if (length == 0)
+ break;
+ if (SetImageProfile(image,"IPTC",info,length) == MagickFail)
+ ThrowPICTReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ MagickFreeMemory(info);
+ break;
+ }
+ default:
+ break;
+ }
+ MagickFreeMemory(info);
+ break;
+ }
+ default:
+ {
+ /*
+ Skip to next op code.
+ */
+ if (codes[code].length == -1)
+ (void) ReadBlobMSBShort(image);
+ else
+ for (i=0; i < (long) codes[code].length; i++)
+ (void) ReadBlobByte(image);
+ }
+ }
+ }
+ if (code == 0xc00)
+ {
+ /*
+ Skip header.
+ */
+ for (i=0; i < 24; i++)
+ (void) ReadBlobByte(image);
+ continue;
+ }
+ if (((code >= 0xb0) && (code <= 0xcf)) ||
+ ((code >= 0x8000) && (code <= 0x80ff)))
+ continue;
+ if (code == 0x8200)
+ {
+ FILE
+ *file;
+
+ Image
+ *tile_image;
+
+ /*
+ Embedded JPEG.
+ */
+ jpeg=True;
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ file=AcquireTemporaryFileStream(clone_info->filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ {
+ DestroyImageInfo(clone_info);
+ ThrowReaderTemporaryFileException(clone_info->filename);
+ }
+ length=ReadBlobMSBLong(image);
+ if (length > 154)
+ {
+ for (i=0; i < 6; i++)
+ (void) ReadBlobMSBLong(image);
+ ReadRectangle(frame);
+ if (!ValidateRectangle(frame))
+ {
+ (void) fclose(file);
+ ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ for (i=0; i < 122; i++)
+ if (ReadBlobByte(image) == EOF)
+ break;
+ for (i=0; i < (long) (length-154); i++)
+ {
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ (void) fputc(c,file);
+ }
+ }
+ (void) fclose(file);
+ tile_image=ReadImage(clone_info,exception);
+ (void) LiberateTemporaryFile(clone_info->filename);
+ DestroyImageInfo(clone_info);
+ clone_info=(ImageInfo *) NULL;
+ if (tile_image == (Image *) NULL)
+ continue;
+ FormatString(geometry,"%lux%lu",Max(image->columns,tile_image->columns),
+ Max(image->rows,tile_image->rows));
+ (void) TransformImage(&image,(char *) NULL,geometry);
+ (void) CompositeImage(image,CopyCompositeOp,tile_image,frame.left,
+ frame.right);
+ image->compression=tile_image->compression;
+ DestroyImage(tile_image);
+ continue;
+ }
+ if ((code == 0xff) || (code == 0xffff))
+ break;
+ if (((code >= 0xd0) && (code <= 0xfe)) ||
+ ((code >= 0x8100) && (code <= 0xffff)))
+ {
+ /*
+ Skip reserved.
+ */
+ length=ReadBlobMSBShort(image);
+ for (i=0; i < (long) length; i++)
+ if (ReadBlobByte(image) == EOF)
+ break;
+ continue;
+ }
+ if ((code >= 0x100) && (code <= 0x7fff))
+ {
+ /*
+ Skip reserved.
+ */
+ length=(code >> 7) & 0xff;
+ for (i=0; i < (long) length; i++)
+ if (ReadBlobByte(image) == EOF)
+ break;
+ continue;
+ }
+ }
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P I C T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPICTImage adds attributes for the PICT image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPICTImage method is:
+%
+% RegisterPICTImage(void)
+%
+*/
+ModuleExport void RegisterPICTImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PCT");
+ entry->decoder=(DecoderHandler) ReadPICTImage;
+ entry->encoder=(EncoderHandler) WritePICTImage;
+ entry->adjoin=False;
+ entry->description="Apple Macintosh QuickDraw/PICT";
+ entry->seekable_stream=MagickTrue;
+ entry->module="PICT";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PICT");
+ entry->decoder=(DecoderHandler) ReadPICTImage;
+ entry->encoder=(EncoderHandler) WritePICTImage;
+ entry->adjoin=False;
+ entry->description="Apple Macintosh QuickDraw/PICT";
+ entry->seekable_stream=MagickTrue;
+ entry->module="PICT";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P I C T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPICTImage removes format registrations made by the
+% PICT module from the list of supported formats.
+%
+% The format of the UnregisterPICTImage method is:
+%
+% UnregisterPICTImage(void)
+%
+*/
+ModuleExport void UnregisterPICTImage(void)
+{
+ (void) UnregisterMagickInfo("PCT");
+ (void) UnregisterMagickInfo("PICT");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P I C T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePICTImage writes an image to a file in the Apple Macintosh
+% QuickDraw/PICT image format.
+%
+% The format of the WritePICTImage method is:
+%
+% unsigned int WritePICTImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePICTImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+#define LiberatePICTAllocations() \
+ { \
+ MagickFreeMemory(buffer); \
+ MagickFreeMemory(packed_scanline); \
+ MagickFreeMemory(scanline); \
+ }
+#define ThrowPICTWriterException(code_,reason_,image_) \
+ { \
+ LiberatePICTAllocations(); \
+ ThrowWriterException(code_,reason_,image_); \
+ }
+static unsigned int WritePICTImage(const ImageInfo *image_info,Image *image)
+{
+#define MaxCount 128U
+#define PictCropRegionOp 0x01
+#define PictEndOfPictureOp 0xff
+#define PictJPEGOp 0x8200
+#define PictInfoOp 0x0C00
+#define PictInfoSize 512
+#define PictPixmapOp 0x9A
+#define PictPICTOp 0x98
+#define PictVersion 0x11
+
+ double
+ x_resolution,
+ y_resolution;
+
+ long
+ y;
+
+ ExtendedSignedIntegralType
+ offset;
+
+ PICTPixmap
+ pixmap;
+
+ PICTRectangle
+ bounds,
+ crop_rectangle,
+ destination_rectangle,
+ frame_rectangle,
+ size_rectangle,
+ source_rectangle;
+
+ const unsigned char
+ *profile_info;
+
+ size_t
+ profile_length;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ size_t
+ bytes_per_line,
+ count,
+ row_bytes;
+
+ unsigned char
+ *buffer = (unsigned char *) NULL,
+ *packed_scanline = (unsigned char *) NULL,
+ *scanline = (unsigned char *) NULL;
+
+ unsigned int
+ status;
+
+ unsigned long
+ storage_class;
+
+ unsigned short
+ base_address,
+ transfer_mode;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if ((image->columns > 65535L) || (image->rows > 65535L))
+ ThrowPICTWriterException(ImageError,WidthOrHeightExceedsLimit,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowPICTWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Initialize image info.
+ */
+ size_rectangle.top=0;
+ size_rectangle.left=0;
+ size_rectangle.bottom=(short) image->rows;
+ size_rectangle.right=(short) image->columns;
+ frame_rectangle=size_rectangle;
+ crop_rectangle=size_rectangle;
+ source_rectangle=size_rectangle;
+ destination_rectangle=size_rectangle;
+ base_address=0xff;
+ row_bytes=image->columns;
+ bounds.top=0;
+ bounds.left=0;
+ bounds.bottom=(short) image->rows;
+ bounds.right=(short) image->columns;
+ pixmap.version=0;
+ pixmap.pack_type=0;
+ pixmap.pack_size=0;
+ pixmap.pixel_type=0;
+ pixmap.bits_per_pixel=8;
+ pixmap.component_count=1;
+ pixmap.component_size=8;
+ pixmap.plane_bytes=0;
+ pixmap.table=0;
+ pixmap.reserved=0;
+ transfer_mode=0;
+ x_resolution=image->x_resolution ? image->x_resolution : 72.0;
+ y_resolution=image->y_resolution ? image->y_resolution : 72.0;
+ storage_class=image->storage_class;
+ if (image->compression == JPEGCompression)
+ storage_class=DirectClass;
+ if (storage_class == DirectClass)
+ {
+ pixmap.component_count=image->matte ? 4 : 3;
+ pixmap.pixel_type=16;
+ pixmap.bits_per_pixel=32;
+ pixmap.pack_type=0x04;
+ transfer_mode=0x40;
+ row_bytes=4*image->columns;
+ }
+ /*
+ Allocate memory.
+ */
+ bytes_per_line=image->columns;
+ if (storage_class == DirectClass)
+ bytes_per_line*=image->matte ? 4 : 3;
+ buffer=MagickAllocateMemory(unsigned char *,PictInfoSize);
+ packed_scanline=MagickAllocateMemory(unsigned char *,row_bytes+MaxCount);
+ scanline=MagickAllocateMemory(unsigned char *,row_bytes);
+ if ((buffer == (unsigned char *) NULL) ||
+ (packed_scanline == (unsigned char *) NULL) ||
+ (scanline == (unsigned char *) NULL))
+ ThrowPICTWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Write header, header size, size bounding box, version, and reserved.
+ */
+ (void) memset(buffer,0,PictInfoSize);
+ (void) WriteBlob(image,PictInfoSize,buffer);
+ (void) WriteBlobMSBShort(image,0);
+ (void) WriteBlobMSBShort(image,size_rectangle.top);
+ (void) WriteBlobMSBShort(image,size_rectangle.left);
+ (void) WriteBlobMSBShort(image,size_rectangle.bottom);
+ (void) WriteBlobMSBShort(image,size_rectangle.right);
+ (void) WriteBlobMSBShort(image,PictVersion);
+ (void) WriteBlobMSBShort(image,0x02ff); /* version #2 */
+ (void) WriteBlobMSBShort(image,PictInfoOp);
+ (void) WriteBlobMSBLong(image,0xFFFE0000UL);
+ /*
+ Write full size of the file, resolution, frame bounding box, and reserved.
+ */
+ (void) WriteBlobMSBShort(image,(unsigned short) x_resolution);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBShort(image,(unsigned short) y_resolution);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBShort(image,frame_rectangle.top);
+ (void) WriteBlobMSBShort(image,frame_rectangle.left);
+ (void) WriteBlobMSBShort(image,frame_rectangle.bottom);
+ (void) WriteBlobMSBShort(image,frame_rectangle.right);
+ (void) WriteBlobMSBLong(image,0x00000000L);
+ /*
+ Output 8BIM profile.
+ */
+ profile_info=GetImageProfile(image,"8BIM",&profile_length);
+ if (profile_info != (unsigned char *) NULL)
+ {
+ (void) WriteBlobMSBShort(image,0xa1);
+ (void) WriteBlobMSBShort(image,0x1f2);
+ (void) WriteBlobMSBShort(image,(const magick_uint16_t) profile_length+4);
+ (void) WriteBlobString(image,"8BIM");
+ (void) WriteBlob(image,profile_length,
+ profile_info);
+ }
+ /*
+ Ouput ICM profile.
+ */
+ profile_info=GetImageProfile(image,"ICM",&profile_length);
+ if (profile_info != (unsigned char *) NULL)
+ {
+ (void) WriteBlobMSBShort(image,0xa1);
+ (void) WriteBlobMSBShort(image,0xe0);
+ (void) WriteBlobMSBShort(image,(const magick_uint16_t) profile_length+4);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlob(image,profile_length,
+ profile_info);
+ (void) WriteBlobMSBShort(image,0xa1);
+ (void) WriteBlobMSBShort(image,0xe0);
+ (void) WriteBlobMSBShort(image,4);
+ (void) WriteBlobMSBLong(image,0x00000002UL);
+ }
+ /*
+ Write crop region opcode and crop bounding box.
+ */
+ (void) WriteBlobMSBShort(image,PictCropRegionOp);
+ (void) WriteBlobMSBShort(image,0xa);
+ (void) WriteBlobMSBShort(image,crop_rectangle.top);
+ (void) WriteBlobMSBShort(image,crop_rectangle.left);
+ (void) WriteBlobMSBShort(image,crop_rectangle.bottom);
+ (void) WriteBlobMSBShort(image,crop_rectangle.right);
+ if (image->compression == JPEGCompression)
+ {
+ Image
+ *jpeg_image;
+
+ size_t
+ length;
+
+ unsigned char
+ *blob;
+
+ jpeg_image=CloneImage(image,0,0,True,&image->exception);
+ if (jpeg_image == (Image *) NULL)
+ {
+ LiberatePICTAllocations();
+ CloseBlob(image);
+ return (False);
+ }
+ DestroyBlob(jpeg_image);
+ jpeg_image->blob=CloneBlobInfo((BlobInfo *) NULL);
+ (void) strcpy(jpeg_image->magick,"JPEG");
+ blob=(unsigned char *) ImageToBlob(image_info,jpeg_image,&length,
+ &image->exception);
+ DestroyImage(jpeg_image);
+ if (blob == (unsigned char *) NULL)
+ {
+ LiberatePICTAllocations();
+ CloseBlob(image);
+ return(False);
+ }
+ (void) WriteBlobMSBShort(image,PictJPEGOp);
+ (void) WriteBlobMSBLong(image,(const magick_uint16_t) length+154);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBLong(image,0x00010000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00010000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x40000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00400000UL);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBShort(image,image->rows);
+ (void) WriteBlobMSBShort(image,image->columns);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBShort(image,768);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00566A70UL);
+ (void) WriteBlobMSBLong(image,0x65670000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000001UL);
+ (void) WriteBlobMSBLong(image,0x00016170UL);
+ (void) WriteBlobMSBLong(image,0x706C0000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBShort(image,768);
+ (void) WriteBlobMSBShort(image,image->columns);
+ (void) WriteBlobMSBShort(image,image->rows);
+ (void) WriteBlobMSBShort(image,(unsigned short) x_resolution);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBShort(image,(unsigned short) y_resolution);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x87AC0001UL);
+ (void) WriteBlobMSBLong(image,0x0B466F74UL);
+ (void) WriteBlobMSBLong(image,0x6F202D20UL);
+ (void) WriteBlobMSBLong(image,0x4A504547UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x00000000UL);
+ (void) WriteBlobMSBLong(image,0x0018FFFFUL);
+ (void) WriteBlob(image,length,blob);
+ if (length & 0x01)
+ (void) WriteBlobByte(image,'\0');
+ MagickFreeMemory(blob);
+ }
+ /*
+ Write picture opcode, row bytes, and picture bounding box, and version.
+ */
+ if (storage_class == PseudoClass)
+ (void) WriteBlobMSBShort(image,PictPICTOp);
+ else
+ {
+ (void) WriteBlobMSBShort(image,PictPixmapOp);
+ (void) WriteBlobMSBLong(image,(unsigned long) base_address);
+ }
+ (void) WriteBlobMSBShort(image,(unsigned short) (row_bytes | 0x8000));
+ (void) WriteBlobMSBShort(image,bounds.top);
+ (void) WriteBlobMSBShort(image,bounds.left);
+ (void) WriteBlobMSBShort(image,bounds.bottom);
+ (void) WriteBlobMSBShort(image,bounds.right);
+ /*
+ Write pack type, pack size, resolution, pixel type, and pixel size.
+ */
+ (void) WriteBlobMSBShort(image,pixmap.version);
+ (void) WriteBlobMSBShort(image,pixmap.pack_type);
+ (void) WriteBlobMSBLong(image,pixmap.pack_size);
+ (void) WriteBlobMSBShort(image,(unsigned short) x_resolution);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBShort(image,(unsigned short) y_resolution);
+ (void) WriteBlobMSBShort(image,0x0000);
+ (void) WriteBlobMSBShort(image,pixmap.pixel_type);
+ (void) WriteBlobMSBShort(image,pixmap.bits_per_pixel);
+ /*
+ Write component count, size, plane bytes, table size, and reserved.
+ */
+ (void) WriteBlobMSBShort(image,pixmap.component_count);
+ (void) WriteBlobMSBShort(image,pixmap.component_size);
+ (void) WriteBlobMSBLong(image,(unsigned long) pixmap.plane_bytes);
+ (void) WriteBlobMSBLong(image,(unsigned long) pixmap.table);
+ (void) WriteBlobMSBLong(image,(unsigned long) pixmap.reserved);
+ if (storage_class == PseudoClass)
+ {
+ /*
+ Write image colormap.
+ */
+ (void) WriteBlobMSBLong(image,0x00000000L); /* color seed */
+ (void) WriteBlobMSBShort(image,0L); /* color flags */
+ (void) WriteBlobMSBShort(image,(unsigned short) (image->colors-1));
+ for (i=0; i < (long) image->colors; i++)
+ {
+ (void) WriteBlobMSBShort(image,i);
+ (void) WriteBlobMSBShort(image,
+ ScaleQuantumToShort(image->colormap[i].red));
+ (void) WriteBlobMSBShort(image,
+ ScaleQuantumToShort(image->colormap[i].green));
+ (void) WriteBlobMSBShort(image,
+ ScaleQuantumToShort(image->colormap[i].blue));
+ }
+ }
+ /*
+ Write source and destination rectangle.
+ */
+ (void) WriteBlobMSBShort(image,source_rectangle.top);
+ (void) WriteBlobMSBShort(image,source_rectangle.left);
+ (void) WriteBlobMSBShort(image,source_rectangle.bottom);
+ (void) WriteBlobMSBShort(image,source_rectangle.right);
+ (void) WriteBlobMSBShort(image,destination_rectangle.top);
+ (void) WriteBlobMSBShort(image,destination_rectangle.left);
+ (void) WriteBlobMSBShort(image,destination_rectangle.bottom);
+ (void) WriteBlobMSBShort(image,destination_rectangle.right);
+ (void) WriteBlobMSBShort(image,transfer_mode);
+ /*
+ Write picture data.
+ */
+ count=0;
+ if (storage_class == PseudoClass)
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ scanline[x]=indexes[x];
+ count+=EncodeImage(image,scanline,row_bytes & 0x7FFF,packed_scanline);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ else
+ if (image->compression == JPEGCompression)
+ {
+ (void) memset(scanline,0,row_bytes);
+ for (y=0; y < (long) image->rows; y++)
+ count+=EncodeImage(image,scanline,row_bytes & 0x7FFF,packed_scanline);
+ }
+ else
+ {
+ register unsigned char
+ *blue,
+ *green,
+ *opacity,
+ *red;
+
+ red=scanline;
+ green=scanline+image->columns;
+ blue=scanline+2*image->columns;
+ opacity=scanline+3*image->columns;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ red=scanline;
+ green=scanline+image->columns;
+ blue=scanline+2*image->columns;
+ if (image->matte)
+ {
+ opacity=scanline;
+ red=scanline+image->columns;
+ green=scanline+2*image->columns;
+ blue=scanline+3*image->columns;
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *red++=ScaleQuantumToChar(p->red);
+ *green++=ScaleQuantumToChar(p->green);
+ *blue++=ScaleQuantumToChar(p->blue);
+ if (image->matte)
+ *opacity++=ScaleQuantumToChar(MaxRGB-p->opacity);
+ p++;
+ }
+ count+=EncodeImage(image,scanline,bytes_per_line & 0x7FFF,packed_scanline);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ if (count & 0x1)
+ (void) WriteBlobByte(image,'\0');
+ (void) WriteBlobMSBShort(image,PictEndOfPictureOp);
+ offset=TellBlob(image);
+ (void) SeekBlob(image,512,SEEK_SET);
+ (void) WriteBlobMSBShort(image,(unsigned long) offset);
+ MagickFreeMemory(scanline);
+ MagickFreeMemory(packed_scanline);
+ MagickFreeMemory(buffer);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/pix.c b/coders/pix.c
new file mode 100644
index 0000000..a4b99d2
--- /dev/null
+++ b/coders/pix.c
@@ -0,0 +1,296 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP IIIII X X %
+% P P I X X %
+% PPPP I X %
+% P I X X %
+% P IIIII X X %
+% %
+% %
+% Read Alias/Wavefront RLE Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P I X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPIXImage reads a Alias/Wavefront RLE image file and returns it.
+% It allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadPIXImage method is:
+%
+% Image *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPIXImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ IndexPacket
+ index;
+
+ long
+ y;
+
+ Quantum
+ blue,
+ green,
+ red;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ status;
+
+ unsigned long
+ bits_per_pixel,
+ height,
+ length,
+ width;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read PIX image.
+ */
+ width=ReadBlobMSBShort(image);
+ height=ReadBlobMSBShort(image);
+ (void) ReadBlobMSBShort(image); /* x-offset */
+ (void) ReadBlobMSBShort(image); /* y-offset */
+ bits_per_pixel=ReadBlobMSBShort(image);
+ if ((EOFBlob(image)) ||
+ (width == 0) || (height == 0) ||
+ ((bits_per_pixel != 8) && (bits_per_pixel != 24)))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ do
+ {
+ /*
+ Initialize image structure.
+ */
+ image->columns= width;
+ image->rows= height;
+ if (bits_per_pixel == 8)
+ if (!AllocateImageColormap(image,256))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Convert PIX raster image to pixel packets.
+ */
+ red=0;
+ green=0;
+ blue=0;
+ index=0;
+ length=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (length == 0)
+ {
+ length=ReadBlobByte(image);
+ if (bits_per_pixel == 8)
+ index=ScaleCharToQuantum(ReadBlobByte(image));
+ else
+ {
+ blue=ScaleCharToQuantum(ReadBlobByte(image));
+ green=ScaleCharToQuantum(ReadBlobByte(image));
+ red=ScaleCharToQuantum(ReadBlobByte(image));
+ }
+ }
+ if (image->storage_class == PseudoClass)
+ indexes[x]=index;
+ q->blue=blue;
+ q->green=green;
+ q->red=red;
+ length--;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (image->storage_class == PseudoClass)
+ (void) SyncImage(image);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ width=ReadBlobMSBLong(image);
+ height=ReadBlobMSBLong(image);
+ (void) ReadBlobMSBShort(image);
+ (void) ReadBlobMSBShort(image);
+ bits_per_pixel=ReadBlobMSBShort(image);
+ status=(!EOFBlob(image)) && (width != 0U) && (height != 0U) &&
+ ((bits_per_pixel == 8) || (bits_per_pixel == 24));
+ if (status == True)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+ } while (status == True);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P I X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPIXImage adds attributes for the PIX image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPIXImage method is:
+%
+% RegisterPIXImage(void)
+%
+*/
+ModuleExport void RegisterPIXImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PIX");
+ entry->decoder=(DecoderHandler) ReadPIXImage;
+ entry->description="Alias/Wavefront RLE image format";
+ entry->module="PIX";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P I X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPIXImage removes format registrations made by the
+% PIX module from the list of supported formats.
+%
+% The format of the UnregisterPIXImage method is:
+%
+% UnregisterPIXImage(void)
+%
+*/
+ModuleExport void UnregisterPIXImage(void)
+{
+ (void) UnregisterMagickInfo("PIX");
+}
diff --git a/coders/plasma.c b/coders/plasma.c
new file mode 100644
index 0000000..4d1ba7f
--- /dev/null
+++ b/coders/plasma.c
@@ -0,0 +1,252 @@
+/*
+% Copyright (C) 2003-2009 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP L AAA SSSSS M M AAA %
+% P P L A A SS MM MM A A %
+% PPPP L AAAAA SSS M M M AAAAA %
+% P L A A SS M M A A %
+% P LLLLL A A SSSSS M M A A %
+% %
+% %
+% Read a Plasma Image. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/plasma.h"
+#include "magick/random.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P L A S M A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPlasmaImage creates a plasma fractal image. The image is
+% initialized to to the X server color as specified by the filename.
+%
+% The format of the ReadPlasmaImage method is:
+%
+% Image *ReadPlasmaImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPlasmaImage returns a pointer to the image after
+% creating it. A null image is returned if there is a memory shortage
+% or if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static void PlasmaPixel(Image *image,double x,double y)
+{
+ register PixelPacket
+ *q;
+
+ q=GetImagePixels(image,(long) (x+0.5),(long) (y+0.5),1,1);
+ if (q == (PixelPacket *) NULL)
+ return;
+ q->red=(Quantum) (MaxRGBDouble*MagickRandomReal()+0.5);
+ q->green=(Quantum) (MaxRGBDouble*MagickRandomReal()+0.5);
+ q->blue=(Quantum) (MaxRGBDouble*MagickRandomReal()+0.5);
+ (void) SyncImagePixels(image);
+}
+
+static Image *ReadPlasmaImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+#define PlasmaImageText "[%s] Applying image plasma..."
+
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ long
+ y;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ SegmentInfo
+ segment_info;
+
+ unsigned long
+ depth,
+ max_depth;
+
+ /*
+ Recursively apply plasma to the image.
+ */
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ (void) FormatString(clone_info->filename,"gradient:%.1024s",
+ image_info->filename);
+ image=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ if (image == (Image *) NULL)
+ return(image);
+ image->storage_class=DirectClass;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->opacity=(Quantum) (MaxRGB/2);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ segment_info.x1=0;
+ segment_info.y1=0;
+ segment_info.x2=image->columns-1;
+ segment_info.y2=image->rows-1;
+ if (LocaleCompare(image_info->filename,"fractal") == 0)
+ {
+ /*
+ Seed pixels before recursion.
+ */
+ PlasmaPixel(image,segment_info.x1,segment_info.y1);
+ PlasmaPixel(image,segment_info.x1,(segment_info.y1+segment_info.y2)/2);
+ PlasmaPixel(image,segment_info.x1,segment_info.y2);
+ PlasmaPixel(image,(segment_info.x1+segment_info.x2)/2,segment_info.y1);
+ PlasmaPixel(image,(segment_info.x1+segment_info.x2)/2,
+ (segment_info.y1+segment_info.y2)/2);
+ PlasmaPixel(image,(segment_info.x1+segment_info.x2)/2,segment_info.y2);
+ PlasmaPixel(image,segment_info.x2,segment_info.y1);
+ PlasmaPixel(image,segment_info.x2,(segment_info.y1+segment_info.y2)/2);
+ PlasmaPixel(image,segment_info.x2,segment_info.y2);
+ }
+ i=(long) (Max(image->columns,image->rows) >> 1);
+ for (max_depth=0; i != 0; max_depth++)
+ i>>=1;
+ for (depth=1; ; depth++)
+ {
+ if (!MagickMonitorFormatted(depth,max_depth,&image->exception,
+ PlasmaImageText,image->filename))
+ break;
+ if (PlasmaImage(image,&segment_info,0,depth))
+ break;
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P L A S M A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPLASMAImage adds attributes for the Plasma image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPLASMAImage method is:
+%
+% RegisterPLASMAImage(void)
+%
+*/
+ModuleExport void RegisterPLASMAImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PLASMA");
+ entry->decoder=(DecoderHandler) ReadPlasmaImage;
+ entry->adjoin=False;
+ entry->description="Plasma fractal image";
+ entry->module="PLASMA";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("FRACTAL");
+ entry->decoder=(DecoderHandler) ReadPlasmaImage;
+ entry->adjoin=False;
+ entry->description="Plasma fractal image";
+ entry->module="PLASMA";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P L A S M A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPLASMAImage removes format registrations made by the
+% PLASMA module from the list of supported formats.
+%
+% The format of the UnregisterPLASMAImage method is:
+%
+% UnregisterPLASMAImage(void)
+%
+*/
+ModuleExport void UnregisterPLASMAImage(void)
+{
+ (void) UnregisterMagickInfo("FRACTAL");
+ (void) UnregisterMagickInfo("PLASMA");
+}
diff --git a/coders/png.c b/coders/png.c
new file mode 100644
index 0000000..37de9fc
--- /dev/null
+++ b/coders/png.c
@@ -0,0 +1,9750 @@
+/*
+% Copyright (C) 2003-2017 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP N N GGGG %
+% P P NN N G %
+% PPPP N N N G GG %
+% P N NN G G %
+% P N N GGG %
+% %
+% %
+% Read/Write Portable Network Graphics Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% Glenn Randers-Pehrson %
+% November 1997 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/* GraphicsMagick differences */
+
+#define LoadImageTag LoadImageText
+#define SaveImageTag SaveImageText
+#define LoadImagesTag LoadImagesText
+#define SaveImagesTag SaveImagesText
+#define ParseMetaGeometry GetMagickGeometry
+#define AcquireUniqueFilename AcquireTemporaryFileName
+#define LiberateUniqueFileResource LiberateTemporaryFile
+#define first_scene subimage
+#define number_scenes subrange
+
+#if !defined(RGBColorMatchExact)
+#define RGBColorMatchExact(color,target) \
+ (((color).red == (target).red) && \
+ ((color).green == (target).green) && \
+ ((color).blue == (target).blue))
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/channel.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/enhance.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/quantize.h"
+#include "magick/resource.h"
+#include "magick/semaphore.h"
+#include "magick/static.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#if defined(HasPNG)
+
+/* Suppress libpng pedantic warnings */
+#define PNG_DEPRECATED /* Use of this function is deprecated */
+#define PNG_USE_RESULT /* The result of this function must be checked */
+#define PNG_NORETURN /* This function does not return */
+/* #define PNG_ALLOCATED */ /* The result of the function is new memory */
+#define PNG_DEPSTRUCT /* access to this struct member is deprecated */
+
+#include "png.h"
+#include "zlib.h"
+#if defined(HasLCMS)
+# if defined(HAVE_LCMS2_LCMS2_H)
+# include <lcms2/lcms2.h>
+# elif defined(HAVE_LCMS2_H)
+# include <lcms2.h>
+# else
+# error "LCMS 2 header missing!"
+# endif
+#endif
+
+
+#if PNG_LIBPNG_VER > 10011
+/*
+ Optional declarations. Define or undefine them as you like.
+*/
+
+/* After eXIf chunk has been approved:
+#define eXIf_SUPPORTED
+*/
+
+/* Experimental; define one or both of these:
+#define exIf_SUPPORTED
+*/
+
+/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
+
+/*
+ Features under construction. Define these to work on them.
+*/
+#undef MNG_OBJECT_BUFFERS
+#undef MNG_BASI_SUPPORTED
+#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
+#define MNG_INSERT_LAYERS /* Troublesome, but seem to work as of 5.4.4 */
+#define GMPNG_BUILD_PALETTE /* This works as of 5.4.3. */
+#if defined(HasJPEG)
+# define JNG_SUPPORTED /* Not finished as of 5.5.2. See "To do" comments. */
+#endif
+
+/*
+ Establish thread safety.
+ setjmp/longjmp is claimed to be safe on these platforms:
+ setjmp/longjmp is alleged to be unsafe on these platforms:
+*/
+#ifdef PNG_SETJMP_SUPPORTED
+# ifndef SETJMP_IS_THREAD_SAFE
+# define GMPNG_SETJMP_NOT_THREAD_SAFE
+# endif
+
+# if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+static SemaphoreInfo
+ *png_semaphore = (SemaphoreInfo *) NULL;
+# endif
+#endif
+
+/*
+ This is temporary until I set up malloc'ed object attributes array.
+ Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
+ waste more memory.
+*/
+#define MNG_MAX_OBJECTS 256
+
+/*
+ If this is not defined, spec is interpreted strictly. If it is
+ defined, an attempt will be made to recover from some errors,
+ including
+ o global PLTE too short
+*/
+#undef MNG_LOOSE
+
+/*
+ Don't try to define PNG_MNG_FEATURES_SUPPORTED here. Make sure
+ it's defined in libpng/pngconf.h, version 1.0.9 or later. It won't work
+ with earlier versions of libpng. From libpng-1.0.3a to libpng-1.0.8,
+ PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
+ libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
+ PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
+ will be enabled by default in libpng-1.2.0.
+*/
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+# ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
+# define PNG_READ_EMPTY_PLTE_SUPPORTED
+# endif
+# ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
+# define PNG_WRITE_EMPTY_PLTE_SUPPORTED
+# endif
+#endif
+
+/*
+ Maximum valid unsigned long in PNG/MNG chunks is (2^31)-1
+ This macro is only defined in libpng-1.0.3a and later.
+*/
+#ifndef PNG_MAX_UINT
+#define PNG_MAX_UINT (png_uint_32) 0x7fffffffL
+#endif
+
+/*
+ Constant strings for known chunk types. If you need to add a chunk,
+ add a string holding the name here. To make the code more
+ portable, we use ASCII numbers like this, not characters.
+*/
+
+static png_byte const mng_MHDR[5]={ 77, 72, 68, 82, '\0'};
+static png_byte const mng_BACK[5]={ 66, 65, 67, 75, '\0'};
+static png_byte const mng_BASI[5]={ 66, 65, 83, 73, '\0'};
+static png_byte const mng_CLIP[5]={ 67, 76, 73, 80, '\0'};
+static png_byte const mng_CLON[5]={ 67, 76, 79, 78, '\0'};
+static png_byte const mng_DEFI[5]={ 68, 69, 70, 73, '\0'};
+static png_byte const mng_DHDR[5]={ 68, 72, 68, 82, '\0'};
+static png_byte const mng_DISC[5]={ 68, 73, 83, 67, '\0'};
+static png_byte const mng_ENDL[5]={ 69, 78, 68, 76, '\0'};
+static png_byte const mng_FRAM[5]={ 70, 82, 65, 77, '\0'};
+static png_byte const mng_IEND[5]={ 73, 69, 78, 68, '\0'};
+static png_byte const mng_IHDR[5]={ 73, 72, 68, 82, '\0'};
+static png_byte const mng_JHDR[5]={ 74, 72, 68, 82, '\0'};
+static png_byte const mng_LOOP[5]={ 76, 79, 79, 80, '\0'};
+static png_byte const mng_MAGN[5]={ 77, 65, 71, 78, '\0'};
+static png_byte const mng_MEND[5]={ 77, 69, 78, 68, '\0'};
+static png_byte const mng_MOVE[5]={ 77, 79, 86, 69, '\0'};
+static png_byte const mng_PAST[5]={ 80, 65, 83, 84, '\0'};
+static png_byte const mng_PLTE[5]={ 80, 76, 84, 69, '\0'};
+static png_byte const mng_SAVE[5]={ 83, 65, 86, 69, '\0'};
+static png_byte const mng_SEEK[5]={ 83, 69, 69, 75, '\0'};
+static png_byte const mng_SHOW[5]={ 83, 72, 79, 87, '\0'};
+static png_byte const mng_TERM[5]={ 84, 69, 82, 77, '\0'};
+static png_byte const mng_bKGD[5]={ 98, 75, 71, 68, '\0'};
+static png_byte const mng_caNv[5]={ 99, 97, 78, 118, '\0'};
+static png_byte const mng_cHRM[5]={ 99, 72, 82, 77, '\0'};
+#ifdef exIf_SUPPORTED
+/* until registration of eXIf */
+static png_byte const mng_exIf[5]={101, 120, 73, 102, '\0'};
+#endif
+#ifdef eXIf_SUPPORTED
+/* after registration of eXIf */
+static png_byte const mng_eXIf[5]={101, 88, 73, 102, '\0'};
+#endif
+static png_byte const mng_gAMA[5]={103, 65, 77, 65, '\0'};
+static png_byte const mng_iCCP[5]={105, 67, 67, 80, '\0'};
+static png_byte const mng_nEED[5]={110, 69, 69, 68, '\0'};
+static png_byte const mng_orNT[5]={111, 114, 78, 84, '\0'};
+static png_byte const mng_pHYg[5]={112, 72, 89, 103, '\0'};
+static png_byte const mng_pHYs[5]={112, 72, 89, 115, '\0'};
+static png_byte const mng_sBIT[5]={115, 66, 73, 84, '\0'};
+static png_byte const mng_sRGB[5]={115, 82, 71, 66, '\0'};
+static png_byte const mng_tRNS[5]={116, 82, 78, 83, '\0'};
+
+#if defined(JNG_SUPPORTED)
+static png_byte const mng_IDAT[5]={ 73, 68, 65, 84, '\0'};
+static png_byte const mng_JDAT[5]={ 74, 68, 65, 84, '\0'};
+static png_byte const mng_JDAA[5]={ 74, 68, 65, 65, '\0'};
+static png_byte const mng_JdAA[5]={ 74, 100, 65, 65, '\0'};
+static png_byte const mng_JSEP[5]={ 74, 83, 69, 80, '\0'};
+static png_byte const mng_oFFs[5]={111, 70, 70, 115, '\0'};
+#endif
+
+/*
+static png_byte const mng_hIST[5]={104, 73, 83, 84, '\0'};
+static png_byte const mng_iCCP[5]={105, 67, 67, 80, '\0'};
+static png_byte const mng_iTXt[5]={105, 84, 88, 116, '\0'};
+static png_byte const mng_sPLT[5]={115, 80, 76, 84, '\0'};
+static png_byte const mng_tEXt[5]={116, 69, 88, 116, '\0'};
+static png_byte const mng_tIME[5]={116, 73, 77, 69, '\0'};
+static png_byte const mng_zTXt[5]={122, 84, 88, 116, '\0'};
+*/
+
+typedef struct _UShortPixelPacket
+{
+ unsigned short
+ red,
+ green,
+ blue,
+ opacity,
+ index;
+} UShortPixelPacket;
+
+typedef struct _MngBox
+{
+ long
+ left,
+ right,
+ top,
+ bottom;
+} MngBox;
+
+typedef struct _MngPair
+{
+ volatile long
+ a,
+ b;
+} MngPair;
+
+#ifdef MNG_OBJECT_BUFFERS
+typedef struct _MngBuffer
+{
+
+ unsigned long
+ height,
+ width;
+
+ Image
+ *image;
+
+ png_color
+ plte[256];
+
+ int
+ reference_count;
+
+ unsigned char
+ alpha_sample_depth,
+ compression_method,
+ color_type,
+ concrete,
+ filter_method,
+ frozen,
+ image_type,
+ interlace_method,
+ pixel_sample_depth,
+ plte_length,
+ sample_depth,
+ viewable;
+} MngBuffer;
+#endif
+
+typedef struct _MngInfo
+{
+
+#ifdef MNG_OBJECT_BUFFERS
+ MngBuffer
+ *ob[MNG_MAX_OBJECTS];
+#endif
+
+ Image *
+ image;
+
+ RectangleInfo
+ page;
+
+ int
+ adjoin,
+#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
+ bytes_in_read_buffer,
+ found_empty_plte,
+#endif
+ equal_backgrounds,
+ equal_chrms,
+ equal_gammas,
+#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_MNG_FEATURES_SUPPORTED)
+ equal_palettes,
+#endif
+ equal_physs,
+ equal_srgbs,
+ framing_mode,
+ have_global_bkgd,
+ have_global_chrm,
+ have_global_gama,
+ have_global_phys,
+ have_global_sbit,
+ have_global_srgb,
+ have_saved_bkgd_index,
+ have_write_global_chrm,
+ have_write_global_gama,
+ have_write_global_plte,
+ have_write_global_srgb,
+ need_fram,
+ object_id,
+ old_framing_mode,
+ saved_bkgd_index;
+
+ int
+ new_number_colors;
+
+ long
+ image_found,
+ loop_count[256],
+ loop_iteration[256],
+ scenes_found,
+ x_off[MNG_MAX_OBJECTS],
+ y_off[MNG_MAX_OBJECTS];
+
+ MngBox
+ clip,
+ frame,
+ image_box,
+ object_clip[MNG_MAX_OBJECTS];
+
+ unsigned char
+ /* These flags could be combined into one byte */
+ exists[MNG_MAX_OBJECTS],
+ frozen[MNG_MAX_OBJECTS],
+ loop_active[256],
+ invisible[MNG_MAX_OBJECTS],
+ viewable[MNG_MAX_OBJECTS];
+
+ ExtendedSignedIntegralType
+ loop_jump[256];
+
+ png_colorp
+ global_plte;
+
+ png_color_8
+ global_sbit;
+
+ png_byte
+#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
+ read_buffer[8],
+#endif
+ global_trns[256];
+
+ float
+ global_gamma;
+
+ ChromaticityInfo
+ global_chrm;
+
+ RenderingIntent
+ global_srgb_intent;
+
+ unsigned long
+ delay,
+ global_plte_length,
+ global_trns_length,
+ global_x_pixels_per_unit,
+ global_y_pixels_per_unit,
+ mng_width,
+ mng_height,
+ ticks_per_second;
+
+ unsigned int
+ IsPalette,
+ global_phys_unit_type,
+ basi_warning,
+ clon_warning,
+ dhdr_warning,
+ jhdr_warning,
+ magn_warning,
+ past_warning,
+ phyg_warning,
+ phys_warning,
+ sbit_warning,
+ show_warning,
+ mng_type,
+ write_mng,
+ write_png_colortype,
+ write_png_depth,
+ write_png8,
+ write_png24,
+ write_png32,
+ write_png48,
+ write_png64;
+
+#ifdef MNG_BASI_SUPPORTED
+ unsigned long
+ basi_width,
+ basi_height;
+
+ unsigned int
+ basi_depth,
+ basi_color_type,
+ basi_compression_method,
+ basi_filter_type,
+ basi_interlace_method,
+ basi_red,
+ basi_green,
+ basi_blue,
+ basi_alpha,
+ basi_viewable;
+#endif
+
+ png_uint_16
+ magn_first,
+ magn_last,
+ magn_mb,
+ magn_ml,
+ magn_mr,
+ magn_mt,
+ magn_mx,
+ magn_my,
+ magn_methx,
+ magn_methy;
+
+ PixelPacket
+ mng_global_bkgd;
+
+ unsigned char
+ *png_pixels;
+
+ Quantum
+ *quantum_scanline;
+
+} MngInfo;
+#endif /* VER */
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePNGImage(const ImageInfo *,Image *);
+static unsigned int
+ WriteMNGImage(const ImageInfo *,Image *);
+#if defined(JNG_SUPPORTED)
+static unsigned int
+ WriteJNGImage(const ImageInfo *,Image *);
+#endif
+static const char* PngColorTypeToString(const unsigned int color_type)
+{
+ const char
+ *result = "Unknown";
+
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ result = "Gray";
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ result = "Gray+Alpha";
+ break;
+ case PNG_COLOR_TYPE_PALETTE:
+ result = "Palette";
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ result = "RGB";
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ result = "RGB+Alpha";
+ break;
+ }
+
+ return result;
+}
+#endif /* HasPNG */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M N G %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsMNG returns True if the image format type, identified by the
+% magick string, is MNG.
+%
+% The format of the IsMNG method is:
+%
+% unsigned int IsMNG(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsMNG returns True if the image format type is MNG.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static MagickPassFail IsMNG(const unsigned char *magick,const size_t length)
+{
+ if (length < 8)
+ return(MagickFail);
+ if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
+ return(MagickPass);
+ return(MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s J N G %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsJNG returns True if the image format type, identified by the
+% magick string, is JNG.
+%
+% The format of the IsJNG method is:
+%
+% unsigned int IsJNG(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsJNG returns True if the image format type is JNG.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static MagickPassFail IsJNG(const unsigned char *magick,const size_t length)
+{
+ if (length < 8)
+ return(MagickFail);
+ if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
+ return(MagickPass);
+ return(MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P N G %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPNG returns True if the image format type, identified by the
+% magick string, is PNG.
+%
+% The format of the IsPNG method is:
+%
+% unsigned int IsPNG(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPNG returns True if the image format type is PNG.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static MagickPassFail IsPNG(const unsigned char *magick,const size_t length)
+{
+ if (length < 8)
+ return(MagickFail);
+ if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
+ return(MagickPass);
+ return(MagickFail);
+}
+
+#if defined(HasPNG)
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if (PNG_LIBPNG_VER > 10011)
+static size_t WriteBlobMSBULong(Image *image,const unsigned long value)
+{
+ unsigned char
+ buffer[4];
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ buffer[0]=(unsigned char) (value >> 24);
+ buffer[1]=(unsigned char) (value >> 16);
+ buffer[2]=(unsigned char) (value >> 8);
+ buffer[3]=(unsigned char) value;
+ return(WriteBlob(image,4,buffer));
+}
+
+static void PNGLong(png_bytep p,png_uint_32 value)
+{
+ *p++=(png_byte) ((value >> 24) & 0xff);
+ *p++=(png_byte) ((value >> 16) & 0xff);
+ *p++=(png_byte) ((value >> 8) & 0xff);
+ *p++=(png_byte) (value & 0xff);
+}
+
+static void PNGsLong(png_bytep p,png_int_32 value)
+{
+ *p++=(png_byte) ((value >> 24) & 0xff);
+ *p++=(png_byte) ((value >> 16) & 0xff);
+ *p++=(png_byte) ((value >> 8) & 0xff);
+ *p++=(png_byte) (value & 0xff);
+}
+
+static void PNGShort(png_bytep p,png_uint_16 value)
+{
+ *p++=(png_byte) ((value >> 8) & 0xff);
+ *p++=(png_byte) (value & 0xff);
+}
+
+static void PNGType(png_bytep p,png_byte const * type)
+{
+ (void) memcpy(p,type,4*sizeof(png_byte));
+}
+
+static void LogPNGChunk(int logging, png_byte const * type, unsigned long length)
+{
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing %c%c%c%c chunk, length: %lu",
+ type[0],type[1],type[2],type[3],length);
+}
+#endif /* PNG_LIBPNG_VER > 10011 */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#if PNG_LIBPNG_VER > 10011
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPNGImage reads a Portable Network Graphics (PNG) or
+% Multiple-image Network Graphics (MNG) image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image or set of images.
+%
+% MNG support written by Glenn Randers-Pehrson, randeg@alum.rpi.edu.
+%
+% The format of the ReadPNGImage method is:
+%
+% Image *ReadPNGImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPNGImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+% To do, more or less in chronological order (as of version 5.5.2,
+% November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
+%
+% Get 16-bit cheap transparency working.
+%
+% (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
+%
+% Preserve all unknown and not-yet-handled known chunks found in input
+% PNG file and copy them into output PNG files according to the PNG
+% copying rules.
+%
+% (At this point, PNG encoding should be in full MNG compliance)
+%
+% Provide options for choice of background to use when the MNG BACK
+% chunk is not present or is not mandatory (i.e., leave transparent,
+% user specified, MNG BACK, PNG bKGD)
+%
+% Implement LOOP/ENDL [done, but could do discretionary loops more
+% efficiently by linking in the duplicate frames.].
+%
+% Decode and act on the MHDR simplicity profile (offer option to reject
+% files or attempt to process them anyway when the profile isn't LC or VLC).
+%
+% Upgrade to full MNG without Delta-PNG.
+%
+% o BACK [done a while ago except for background image ID]
+% o MOVE [done 15 May 1999]
+% o CLIP [done 15 May 1999]
+% o DISC [done 19 May 1999]
+% o SAVE [partially done 19 May 1999 (marks objects frozen)]
+% o SEEK [partially done 19 May 1999 (discard function only)]
+% o SHOW
+% o PAST
+% o BASI
+% o MNG-level tEXt/iTXt/zTXt
+% o pHYg
+% o pHYs
+% o sBIT
+% o bKGD
+% o iTXt (wait for libpng implementation).
+%
+% Use the scene signature to discover when an identical scene is
+% being reused, and just point to the original image->pixels instead
+% of storing another set of pixels. This is not specific to MNG
+% but could be applied generally.
+%
+% Upgrade to full MNG with Delta-PNG.
+%
+% JNG tEXt/iTXt/zTXt
+%
+% We will not attempt to read files containing the CgBI chunk.
+% They are really Xcode files meant for display on the iPhone.
+% These are not valid PNG files and it is impossible to recover
+% the orginal PNG from files that have been converted to Xcode-PNG,
+% since irretrievable loss of color data has occurred due to the
+% use of premultiplied alpha.
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ This is the function that does the actual reading of data. It is
+ the same as the one supplied in libpng, except that it receives the
+ datastream from the ReadBlob() function instead of standard input.
+*/
+static void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
+{
+ Image
+ *image;
+
+ image=(Image *) png_get_io_ptr(png_ptr);
+ if (length)
+ {
+ png_size_t
+ check;
+
+ if (length > 0x7fffffff)
+ png_warning(png_ptr, "chunk length > 2G");
+ check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
+ if (check != length)
+ {
+ char
+ msg[MaxTextExtent];
+
+ (void) sprintf(msg,"Expected %lu bytes; found %lu bytes",
+ (unsigned long) length,(unsigned long) check);
+ png_warning(png_ptr,msg);
+ png_error(png_ptr,"Read Exception");
+ }
+ }
+}
+
+#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
+ !defined(PNG_MNG_FEATURES_SUPPORTED)
+/* We use mng_get_data() instead of png_get_data() if we have a libpng
+ * older than libpng-1.0.3a, which was the first to allow the empty
+ * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
+ * ifdef'ed out. Earlier versions would crash if the bKGD chunk was
+ * encountered after an empty PLTE, so we have to look ahead for bKGD
+ * chunks and remove them from the datastream that is passed to libpng,
+ * and store their contents for later use.
+ */
+static void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
+{
+ MngInfo
+ *mng_info;
+
+ Image
+ *image;
+
+ png_size_t
+ check;
+
+ register long
+ i;
+
+ i=0;
+ mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
+ image=(Image *) mng_info->image;
+ while (mng_info->bytes_in_read_buffer && length)
+ {
+ data[i]=mng_info->read_buffer[i];
+ mng_info->bytes_in_read_buffer--;
+ length--;
+ i++;
+ }
+ if (length)
+ {
+ check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
+ if (check != length)
+ png_error(png_ptr,"Read Exception");
+ if (length == 4)
+ {
+ if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
+ (data[3] == 0))
+ {
+ check=(png_size_t) ReadBlob(image,(size_t) length,
+ (char *) mng_info->read_buffer);
+ mng_info->read_buffer[4]=0;
+ mng_info->bytes_in_read_buffer=4;
+ if (!memcmp(mng_info->read_buffer,mng_PLTE,4))
+ mng_info->found_empty_plte=MagickTrue;
+ if (!memcmp(mng_info->read_buffer,mng_IEND,4))
+ {
+ mng_info->found_empty_plte=MagickFalse;
+ mng_info->have_saved_bkgd_index=MagickFalse;
+ }
+ }
+ if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
+ (data[3] == 1))
+ {
+ check=(png_size_t) ReadBlob(image,(size_t) length,
+ (char *) mng_info->read_buffer);
+ mng_info->read_buffer[4]=0;
+ mng_info->bytes_in_read_buffer=4;
+ if (!memcmp(mng_info->read_buffer,mng_bKGD,4))
+ if (mng_info->found_empty_plte)
+ {
+ /*
+ Skip the bKGD data byte and CRC.
+ */
+ check=(png_size_t)
+ ReadBlob(image,5,(char *) mng_info->read_buffer);
+ check=(png_size_t) ReadBlob(image,(size_t) length,
+ (char *)
+ mng_info->read_buffer);
+ mng_info->saved_bkgd_index=mng_info->read_buffer[0];
+ mng_info->have_saved_bkgd_index=MagickTrue;
+ mng_info->bytes_in_read_buffer=0;
+ }
+ }
+ }
+ }
+}
+#endif
+
+static void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
+{
+ Image
+ *image;
+
+ image=(Image *) png_get_io_ptr(png_ptr);
+ if (length)
+ {
+ png_size_t
+ check;
+
+ check=(png_size_t) WriteBlob(image,(unsigned long) length,(char *) data);
+ if (check != length)
+ png_error(png_ptr,"WriteBlob Failed");
+ }
+}
+
+static void png_flush_data(png_structp png_ptr)
+{
+ ARG_NOT_USED(png_ptr);
+
+ /* There is currently no safe API to "flush" a blob. */
+#if 0
+ Image
+ *image;
+
+ image=(Image *) png_get_io_ptr(png_ptr);
+ (void) SyncBlob(image);
+#endif
+}
+
+#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
+static int PalettesAreEqual(Image *a,Image *b)
+{
+ long
+ i;
+
+ if ((a == (Image *) NULL) || (b == (Image *) NULL))
+ return(MagickFail);
+ if (a->storage_class!=PseudoClass || b->storage_class!=PseudoClass)
+ return(MagickFail);
+ if (a->colors != b->colors)
+ return(MagickFail);
+ for (i=0; i < (long) a->colors; i++)
+ {
+ if ((a->colormap[i].red != b->colormap[i].red) ||
+ (a->colormap[i].green != b->colormap[i].green) ||
+ (a->colormap[i].blue != b->colormap[i].blue))
+ return(MagickFail);
+ }
+ return((int) MagickTrue);
+}
+#endif
+
+static void MngInfoDiscardObject(MngInfo *mng_info,int i)
+{
+ if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
+ mng_info->exists[i] && !mng_info->frozen[i])
+ {
+#ifdef MNG_OBJECT_BUFFERS
+ if (mng_info->ob[i] != (MngBuffer *) NULL)
+ {
+ if (mng_info->ob[i]->reference_count > 0)
+ mng_info->ob[i]->reference_count--;
+ if (mng_info->ob[i]->reference_count == 0)
+ {
+ if (mng_info->ob[i]->image != (Image *) NULL)
+ DestroyImage(mng_info->ob[i]->image);
+ MagickFreeMemory(mng_info->ob[i]);
+ }
+ }
+ mng_info->ob[i]=(MngBuffer *) NULL;
+#endif
+ mng_info->exists[i]=MagickFalse;
+ mng_info->invisible[i]=MagickFalse;
+ mng_info->viewable[i]=MagickFalse;
+ mng_info->frozen[i]=MagickFalse;
+ mng_info->x_off[i]=0;
+ mng_info->y_off[i]=0;
+ mng_info->object_clip[i].left=0;
+ mng_info->object_clip[i].right=PNG_MAX_UINT;
+ mng_info->object_clip[i].top=0;
+ mng_info->object_clip[i].bottom=PNG_MAX_UINT;
+ }
+}
+
+static void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
+{
+ if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
+ {
+ register long
+ i;
+
+ for (i=1; i < MNG_MAX_OBJECTS; i++)
+ MngInfoDiscardObject(mng_info,i);
+ MagickFreeMemory(mng_info->global_plte);
+ MagickFreeMemory(mng_info);
+ *have_mng_structure=MagickFalse;
+ }
+}
+
+static MngBox mng_minimum_box(MngBox box1,MngBox box2)
+{
+ MngBox
+ box;
+
+ box=box1;
+ if (box.left < box2.left)
+ box.left=box2.left;
+ if (box.top < box2.top)
+ box.top=box2.top;
+ if (box.right > box2.right)
+ box.right=box2.right;
+ if (box.bottom > box2.bottom)
+ box.bottom=box2.bottom;
+ return box;
+}
+
+static MngBox mng_read_box(MngBox previous_box,char delta_type,
+ unsigned char *p)
+{
+ MngBox
+ box;
+
+ /*
+ Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
+ */
+ box.left=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+ box.right=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
+ box.top=(long) ((p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11]);
+ box.bottom=(long) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
+ if (delta_type != 0)
+ {
+ box.left+=previous_box.left;
+ box.right+=previous_box.right;
+ box.top+=previous_box.top;
+ box.bottom+=previous_box.bottom;
+ }
+ return(box);
+}
+
+static MngPair mng_read_pair(MngPair previous_pair,int delta_type,
+ unsigned char *p)
+{
+ MngPair
+ pair;
+ /*
+ Read two longs from CLON, MOVE or PAST chunk
+ */
+ pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+ pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
+ if (delta_type != 0)
+ {
+ pair.a+=previous_pair.a;
+ pair.b+=previous_pair.b;
+ }
+ return(pair);
+}
+
+static long mng_get_long(unsigned char *p)
+{
+ return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
+}
+
+static void PNGErrorHandler(png_struct *ping,png_const_charp message) MAGICK_FUNC_NORETURN;
+
+static void PNGErrorHandler(png_struct *ping,png_const_charp message)
+{
+ Image
+ *image;
+
+ image=(Image *) png_get_error_ptr(ping);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " libpng-%.1024s error: %.1024s",
+ PNG_LIBPNG_VER_STRING, message);
+ (void) ThrowException2(&image->exception,CoderError,message,image->filename);
+#if (PNG_LIBPNG_VER < 10500)
+ longjmp(ping->jmpbuf,1);
+#else
+ png_longjmp(ping,1);
+#endif
+ SignalHandlerExit(1); /* Avoid GCC warning about non-exit function which does exit */
+}
+
+static void PNGWarningHandler(png_struct *ping,png_const_charp message)
+{
+ Image
+ *image;
+
+ if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
+ png_error(ping, message);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " libpng-%.1024s warning: %.1024s",
+ PNG_LIBPNG_VER_STRING, message);
+ image=(Image *) png_get_error_ptr(ping);
+ (void) ThrowException2(&image->exception,CoderWarning,message,
+ image->filename);
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+#if PNG_LIBPNG_VER >= 14000
+static png_voidp png_IM_malloc(png_structp png_ptr,png_alloc_size_t size)
+#else
+static png_voidp png_IM_malloc(png_structp png_ptr,png_size_t size)
+#endif
+{
+ (void) png_ptr;
+ return MagickAllocateMemory(png_voidp,(size_t) size);
+}
+
+/*
+ Free a pointer. It is removed from the list at the same time.
+*/
+static png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
+{
+ (void) png_ptr;
+ MagickFreeMemory(ptr);
+ return((png_free_ptr) NULL);
+}
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+static MagickPassFail
+png_read_raw_profile(Image *image, const ImageInfo *image_info,
+ png_textp text,int ii)
+{
+ char
+ profile_description[MaxTextExtent],
+ profile_name[MaxTextExtent];
+
+ unsigned char
+ *info;
+
+ register long
+ i;
+
+ register unsigned char
+ *dp;
+
+ register png_charp
+ sp;
+
+ png_uint_32
+ length,
+ nibbles;
+
+ unsigned char
+ unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
+ 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
+ 13,14,15};
+
+ sp=text[ii].text+1;
+ /* look for newline */
+ while (*sp != '\n')
+ sp++;
+ /* look for length */
+ while (*sp == '\0' || *sp == ' ' || *sp == '\n')
+ sp++;
+ length=MagickAtoL(sp);
+ while (*sp != ' ' && *sp != '\n')
+ sp++;
+ /* allocate space */
+ if (length == 0)
+ {
+ (void) ThrowException2(&image->exception,CoderWarning,
+ "invalid profile length",(char *) NULL);
+ return (MagickFail);
+ }
+ info=MagickAllocateMemory(unsigned char *,length);
+ if (info == (unsigned char *) NULL)
+ {
+ (void) ThrowException2(&image->exception,CoderWarning,
+ "unable to copy profile",(char *) NULL);
+ return (MagickFail);
+ }
+ /* copy profile, skipping white space and column 1 "=" signs */
+ dp=info;
+ nibbles=length*2;
+ for (i=0; i < (long) nibbles; i++)
+ {
+ while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
+ {
+ if (*sp == '\0')
+ {
+ MagickFreeMemory(info);
+ (void) ThrowException2(&image->exception,CoderWarning,
+ "ran out of profile data",(char *) NULL);
+ return (MagickFail);
+ }
+ sp++;
+ }
+ if (i%2 == 0)
+ *dp=16*unhex[(int) *sp++];
+ else
+ (*dp++)+=unhex[(int) *sp++];
+ }
+
+ /* We have already read "Raw profile type " */
+ if(!memcmp(&text[ii].key[17], "iptc\0",5))
+ {
+ strlcpy(profile_name,"IPTC",sizeof(profile_name));
+ strlcpy(profile_description,"IPTC profile.",sizeof(profile_description));
+ }
+ else if (!memcmp(&text[ii].key[17], "icm\0",4))
+ {
+ strlcpy(profile_name,"ICM",sizeof(profile_name));
+ strlcpy(profile_description,"ICM (ICCP) profile.",
+ sizeof(profile_description));
+ }
+ else
+ {
+ strlcpy(profile_name,&text[ii].key[17],sizeof(profile_name));
+ strlcpy(profile_description,"generic profile, type ",
+ sizeof(profile_description));
+ strlcat(profile_description,&text[ii].key[17],
+ sizeof(profile_description));
+ }
+ if (image_info->verbose)
+ (void) printf(" Found a %.1024s\n",profile_description);
+ if(SetImageProfile(image,profile_name,info,length) == MagickFail)
+ {
+ MagickFreeMemory(info);
+ (void) ThrowException(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,"unable to copy profile");
+ }
+ MagickFreeMemory(info);
+ return MagickTrue;
+}
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+
+static int read_user_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
+{
+ Image
+ *image;
+
+
+ /* The unknown chunk structure contains the chunk data:
+ png_byte name[5];
+ png_byte *data;
+ png_size_t size;
+
+ Note that libpng has already taken care of the CRC handling.
+
+ Returns one of the following:
+ return(-n); chunk had an error
+ return(0); did not recognize
+ return(n); success
+ */
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " read_user_chunk: found %c%c%c%c chunk",
+ chunk->name[0],chunk->name[1],chunk->name[2],chunk->name[3]);
+
+#if defined(exIf_SUPPORTED)
+ if (chunk->name[0] == 101 &&
+ (chunk->name[1] == 88 || chunk->name[1] == 120 ) &&
+ chunk->name[2] == 73 &&
+ chunk->name[3] == 102)
+ {
+ /* process eXIf or exIf chunk */
+
+ unsigned char
+ *profile;
+
+ unsigned char
+ *p;
+
+ png_byte
+ *s;
+
+ size_t
+ i;
+
+(void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " recognized eXIf|exIf chunk");
+
+ image=(Image *) png_get_user_chunk_ptr(ping);
+
+#if PNG_LIBPNG_VER >= 14000
+ profile=(unsigned char *) png_malloc(ping,
+ (png_alloc_size_t) chunk->size+6);
+#else
+ profile=(unsigned char *) png_malloc(ping,
+ (png_size_t) chunk->size+6);
+#endif
+ p=profile;
+
+ if (*p != 'E' || *(p+1) != 'x' || *(p+2) != 'i' ||
+ *(p+3) != 'f' || *(p+4) != '\0' || *(p+5) != '\0')
+ {
+ /* Initialize profile with "Exif\0\0" if it
+ doesn't already begin with it by accident
+ */
+ *p++ ='E';
+ *p++ ='x';
+ *p++ ='i';
+ *p++ ='f';
+ *p++ ='\0';
+ *p++ ='\0';
+ }
+
+ /* copy chunk->data to profile */
+ s=chunk->data;
+ for (i=0; i<chunk->size; i++)
+ *p++ = *s++;
+
+ (void) SetImageProfile(image,"exif",
+ (const unsigned char *)profile, chunk->size+6);
+ return(1);
+ }
+#endif /* exIf_SUPPORTED */
+
+ /* orNT */
+ if (chunk->name[0] == 111 &&
+ chunk->name[1] == 114 &&
+ chunk->name[2] == 78 &&
+ chunk->name[3] == 84)
+ {
+ /* recognized orNT */
+ if (chunk->size != 1)
+ return(-1); /* Error return */
+
+ image=(Image *) png_get_user_chunk_ptr(ping);
+ if (chunk->data[0] < 9)
+ image->orientation = chunk->data[0];
+ else
+ image->orientation = 0;
+ return(1);
+ }
+
+ /* caNv */
+ if (chunk->name[0] == 99 &&
+ chunk->name[1] == 97 &&
+ chunk->name[2] == 78 &&
+ chunk->name[3] == 118)
+ {
+ /* recognized caNv */
+
+ if (chunk->size != 16)
+ return(-1); /* Error return */
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " recognized caNv chunk");
+
+ image=(Image *) png_get_user_chunk_ptr(ping);
+
+ image->page.width=(size_t) ((chunk->data[0] << 24) |
+ (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
+
+ image->page.height=(size_t) ((chunk->data[4] << 24) |
+ (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
+
+ image->page.x=(size_t) ((chunk->data[8] << 24) |
+ (chunk->data[9] << 16) | (chunk->data[10] << 8) | chunk->data[11]);
+
+ image->page.y=(size_t) ((chunk->data[12] << 24) |
+ (chunk->data[13] << 16) | (chunk->data[14] << 8) | chunk->data[15]);
+
+ return(1);
+ }
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " unrecognized user chunk");
+
+ return(0); /* Did not recognize */
+}
+#endif /* PNG_UNKNOWN_CHUNKS_SUPPORTED */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d O n e P N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadOnePNGImage reads a Portable Network Graphics (PNG) image file
+% (minus the 8-byte signature) and returns it. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% The format of the ReadOnePNGImage method is:
+%
+% Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadOnePNGImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o mng_info: Specifies a pointer to a MngInfo structure.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+static Image *ReadOnePNGImage(MngInfo *mng_info,
+ const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ /* Read one PNG image */
+
+ Image
+ *image;
+
+ int
+ logging,
+ num_text,
+ num_passes,
+ pass,
+ ping_bit_depth,
+ ping_colortype,
+ ping_file_depth,
+ ping_interlace_method,
+ ping_compression_method,
+ ping_filter_method,
+ ping_num_trans;
+
+ LongPixelPacket
+ transparent_color;
+
+ png_bytep
+ ping_trans_alpha;
+
+ png_color_16p
+ ping_background,
+ ping_trans_color;
+
+ png_info
+ *end_info,
+ *ping_info;
+
+ png_struct
+ *ping;
+
+ png_uint_32
+ ping_rowbytes,
+ ping_width,
+ ping_height;
+
+ png_textp
+ text;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned long
+ length,
+ row_offset;
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ png_byte unused_chunks[]=
+ {
+ 104, 73, 83, 84, '\0', /* hIST */
+ 105, 84, 88, 116, '\0', /* iTXt */
+ 112, 67, 65, 76, '\0', /* pCAL */
+ 115, 67, 65, 76, '\0', /* sCAL */
+ 115, 80, 76, 84, '\0', /* sPLT */
+ 116, 73, 77, 69, '\0', /* tIME */
+#ifdef PNG_APNG_SUPPORTED /* libpng was built with APNG patch; */
+ /* ignore the APNG chunks */
+ 97, 99, 84, 76, '\0', /* acTL */
+ 102, 99, 84, 76, '\0', /* fcTL */
+ 102, 100, 65, 84, '\0', /* fdAT */
+#endif
+ };
+#endif
+
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),
+ " enter ReadOnePNGImage()");
+
+ /* Set to an out-of-range color unless tRNS chunk is present */
+ transparent_color.red=65537;
+ transparent_color.green=65537;
+ transparent_color.blue=65537;
+ transparent_color.opacity=65537;
+
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ LockSemaphoreInfo(png_semaphore);
+#endif
+
+#if (PNG_LIBPNG_VER < 10012)
+ if (image_info->verbose)
+ printf("Your PNG library (libpng-%s) is rather old.\n",
+ PNG_LIBPNG_VER_STRING);
+#endif
+
+ image=mng_info->image;
+
+ /*
+ Allocate the PNG structures
+ */
+#ifdef PNG_USER_MEM_SUPPORTED
+ ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
+ PNGErrorHandler,PNGWarningHandler, NULL,
+ (png_malloc_ptr) png_IM_malloc,
+ (png_free_ptr) png_IM_free);
+#else
+ ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
+ PNGErrorHandler,PNGWarningHandler);
+#endif
+ if (ping == (png_struct *) NULL)
+ {
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+
+ mng_info->png_pixels=(unsigned char *) NULL;
+ mng_info->quantum_scanline=(Quantum *) NULL;
+
+ if (setjmp(png_jmpbuf(ping)))
+ {
+ /*
+ PNG image is corrupt.
+ */
+ png_destroy_read_struct(&ping,&ping_info,&end_info);
+ MagickFreeMemory(mng_info->quantum_scanline);
+ MagickFreeMemory(mng_info->png_pixels);
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " exit ReadOnePNGImage() with error.");
+ if (image != (Image *) NULL)
+ {
+ if (image->exception.severity > exception->severity)
+ CopyException(exception,&image->exception);
+ image->columns=0;
+ }
+ return(image);
+ }
+
+/* { From here through end of ReadOnePNGImage(), use png_error(), not Throw() */
+
+ ping_info=png_create_info_struct(ping);
+ if (ping_info == (png_info *) NULL)
+ {
+ png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
+ png_error(ping,"Could not allocate PNG info struct");
+ }
+
+ end_info=png_create_info_struct(ping);
+ if (end_info == (png_info *) NULL)
+ {
+ png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
+ png_error(ping,"Could not allocate PNG end_info struct");
+ }
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ /* Allow benign errors */
+ png_set_benign_errors(ping, 1);
+#endif
+
+ /* Just use libpng's limit (PNG_USER_CHUNK_MALLOC_MAX == 8000000) on
+ chunk size */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ /* Reject images with too many rows or columns */
+ png_set_user_limits(ping,
+ (png_uint_32) Min(0x7fffffffL, GetMagickResourceLimit(WidthResource)),
+ (png_uint_32) Min(0x7fffffffL, GetMagickResourceLimit(HeightResource)));
+#endif /* PNG_SET_USER_LIMITS_SUPPORTED */
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG width limit: %lu, height limit: %lu",
+ (unsigned long) Min(0x7fffffffL, GetMagickResourceLimit(WidthResource)),
+ (unsigned long) Min(0x7fffffffL, GetMagickResourceLimit(HeightResource)));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG pixels limit: %lu",
+ (unsigned long) GetMagickResourceLimit(PixelsResource));
+
+ /*
+ Prepare PNG for reading.
+ */
+ mng_info->image_found++;
+ png_set_sig_bytes(ping,8);
+ if (LocaleCompare(image_info->magick,"MNG") == 0)
+ {
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
+ png_set_read_fn(ping,image,png_get_data);
+#else
+# if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
+ png_permit_empty_plte(ping,MagickTrue);
+ png_set_read_fn(ping,image,png_get_data);
+# else
+ mng_info->image=image;
+ mng_info->bytes_in_read_buffer=0;
+ mng_info->found_empty_plte=MagickFalse;
+ mng_info->have_saved_bkgd_index=MagickFalse;
+ png_set_read_fn(ping,mng_info,mng_get_data);
+# endif
+#endif
+ }
+ else
+ png_set_read_fn(ping,image,png_get_data);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ /* Ignore unknown chunks */
+# if PNG_LIBPNG_VER < 10700 /* Avoid a libpng16 warning */
+ png_set_keep_unknown_chunks(ping, 2, NULL, 0);
+# else
+ png_set_keep_unknown_chunks(ping, 1, NULL, 0);
+# endif
+ /* Ignore unused chunks and all unknown chunks except for eXIf
+ and caNv */
+#if defined(eXIf_SUPPORTED)
+ png_set_keep_unknown_chunks(ping, 2, (png_bytep) mng_eXIf, 1);
+#endif
+ png_set_keep_unknown_chunks(ping, 2, (png_bytep) mng_caNv, 1);
+ png_set_keep_unknown_chunks(ping, 1, unused_chunks,
+ (int)sizeof(unused_chunks)/5);
+ /* Callback for other unknown chunks */
+ png_set_read_user_chunk_fn(ping, image, read_user_chunk_callback);
+#endif
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Disable new libpng-1.5.10 feature while reading */
+ png_set_check_for_invalid_index (ping, 0);
+#endif
+
+#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
+ && (PNG_LIBPNG_VER >= 10200)
+ /* Disable thread-unsafe features of pnggccrd */
+ if (png_access_version_number() >= 10200)
+ {
+ png_uint_32 mmx_disable_mask=0;
+ png_uint_32 asm_flags;
+
+ mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
+ asm_flags=png_get_asm_flags(ping);
+ png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
+ }
+#endif
+
+ png_read_info(ping,ping_info);
+
+ (void) png_get_IHDR(ping,ping_info,
+ &ping_width,
+ &ping_height,
+ &ping_bit_depth,
+ &ping_colortype,
+ &ping_interlace_method,
+ &ping_compression_method,
+
+ &ping_filter_method);
+
+#if (QuantumDepth == 8)
+ if (ping_bit_depth > 8)
+ {
+# if defined(PNG_READ_STRIP_16_TO_8_SUPPORTED) || \
+ defined(PNG_READ_16_TO_8_SUPPORTED)
+ png_set_strip_16(ping);
+# else
+# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ png_set_scale_16(ping);
+# endif
+# endif
+ ping_bit_depth=8;
+ image->depth=8;
+ }
+#else /* QuantumDepth > 8 */
+ if (ping_bit_depth > 8)
+ image->depth=16;
+ else
+ image->depth=8;
+#endif
+
+ ping_file_depth = ping_bit_depth;
+
+ /* Save bit-depth and color-type in case we later want to write a PNG00 */
+ {
+ char
+ msg[MaxTextExtent];
+
+ (void) FormatString(msg,"%d",(int) ping_colortype);
+ (void) SetImageAttribute(image,"png:IHDR.color-type-orig",msg);
+
+ (void) FormatString(msg,"%d",(int) ping_bit_depth);
+ (void) SetImageAttribute(image,"png:IHDR.bit-depth-orig",msg);
+ }
+
+ (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
+ &ping_trans_color);
+
+ (void) png_get_bKGD(ping, ping_info, &ping_background);
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG width: %lu, height: %lu",
+ (unsigned long)ping_width,
+ (unsigned long)ping_height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG color_type: %d, bit_depth: %d",
+ ping_colortype, ping_bit_depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG compression_method: %d",
+ ping_compression_method);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG interlace_method: %d, filter_method: %d",
+ ping_interlace_method,
+ ping_filter_method);
+ }
+
+ /* Too big? */
+ if (ping_width >
+ (magick_uint64_t) GetMagickResourceLimit(PixelsResource)/ping_height)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Number of pixels exceeds resource limit");
+ png_error(ping, "Number of pixels exceeds resource limit");
+ }
+
+ if (ping_bit_depth < 8)
+ {
+ png_set_packing(ping);
+ ping_bit_depth=8;
+ image->depth=8;
+ }
+
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ if (png_get_valid(ping, ping_info, PNG_INFO_iCCP))
+ {
+ int
+ compression;
+
+#if (PNG_LIBPNG_VER < 10500)
+ png_charp
+ info;
+#else
+ png_bytep
+ info;
+#endif
+
+ png_charp
+ name;
+
+ png_uint_32
+ profile_length;
+
+ (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
+ &profile_length);
+ if (profile_length)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG iCCP chunk.");
+ /* libpng will destroy name and info */
+ if (SetImageProfile(image,"ICM",(const unsigned char *) info,
+ (size_t) profile_length) == MagickFail)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToAllocateICCProfile);
+ }
+ }
+ }
+#endif /* #if defined(PNG_READ_iCCP_SUPPORTED) */
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ {
+ int
+ intent;
+
+ if (!png_get_sRGB(ping,ping_info,&intent))
+ {
+ if (mng_info->have_global_srgb)
+ {
+ png_set_sRGB(ping,ping_info,(mng_info->global_srgb_intent+1));
+ }
+ }
+ if (png_get_sRGB(ping,ping_info,&intent))
+ {
+ image->rendering_intent=(RenderingIntent) (intent+1);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG sRGB chunk:"
+ " rendering_intent: %d",
+ intent+1);
+ }
+ }
+#endif
+ {
+ double
+ file_gamma;
+
+ if (!png_get_gAMA(ping,ping_info,&file_gamma))
+ {
+ if (mng_info->have_global_gama)
+ png_set_gAMA(ping,ping_info,mng_info->global_gamma);
+ }
+ if (png_get_gAMA(ping,ping_info,&file_gamma))
+ {
+ image->gamma=(float) file_gamma;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG gAMA chunk: gamma: %f",
+ file_gamma);
+ }
+ }
+ if (!png_get_valid(ping, ping_info, PNG_INFO_cHRM))
+ {
+ if (mng_info->have_global_chrm)
+ (void) png_set_cHRM(ping,ping_info,
+ mng_info->global_chrm.white_point.x,
+ mng_info->global_chrm.white_point.y,
+ mng_info->global_chrm.red_primary.x,
+ mng_info->global_chrm.red_primary.y,
+ mng_info->global_chrm.green_primary.x,
+ mng_info->global_chrm.green_primary.y,
+ mng_info->global_chrm.blue_primary.x,
+ mng_info->global_chrm.blue_primary.y);
+ }
+ if (png_get_valid(ping, ping_info, PNG_INFO_cHRM))
+ {
+ (void) png_get_cHRM(ping,ping_info,
+ &image->chromaticity.white_point.x,
+ &image->chromaticity.white_point.y,
+ &image->chromaticity.red_primary.x,
+ &image->chromaticity.red_primary.y,
+ &image->chromaticity.green_primary.x,
+ &image->chromaticity.green_primary.y,
+ &image->chromaticity.blue_primary.x,
+ &image->chromaticity.blue_primary.y);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG cHRM chunk.");
+ }
+ if (image->rendering_intent)
+ {
+ image->gamma=0.45455f;
+ image->chromaticity.red_primary.x=0.6400f;
+ image->chromaticity.red_primary.y=0.3300f;
+ image->chromaticity.green_primary.x=0.3000f;
+ image->chromaticity.green_primary.y=0.6000f;
+ image->chromaticity.blue_primary.x=0.1500f;
+ image->chromaticity.blue_primary.y=0.0600f;
+ image->chromaticity.white_point.x=0.3127f;
+ image->chromaticity.white_point.y=0.3290f;
+ }
+#if defined(PNG_oFFs_SUPPORTED)
+ if (mng_info->mng_type == 0 && (png_get_valid(ping, ping_info,
+ PNG_INFO_oFFs)))
+ {
+ image->page.x=png_get_x_offset_pixels(ping, ping_info);
+ image->page.y=png_get_y_offset_pixels(ping, ping_info);
+ if (logging)
+ if (image->page.x || image->page.y)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG oFFs chunk: x: %ld, y: %ld.",
+ image->page.x,
+ image->page.y);
+ }
+#endif
+#if defined(PNG_pHYs_SUPPORTED)
+ if (!png_get_valid(ping, ping_info, PNG_INFO_pHYs))
+ {
+ if (mng_info->have_global_phys)
+ {
+ png_set_pHYs(ping,ping_info,
+ mng_info->global_x_pixels_per_unit,
+ mng_info->global_y_pixels_per_unit,
+ mng_info->global_phys_unit_type);
+ }
+ }
+ if (png_get_valid(ping, ping_info, PNG_INFO_pHYs))
+ {
+ int
+ unit_type;
+
+ png_uint_32
+ x_resolution,
+ y_resolution;
+
+ /*
+ Set image resolution.
+ */
+ (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
+ &unit_type);
+ image->x_resolution=(float) x_resolution;
+ image->y_resolution=(float) y_resolution;
+ if (unit_type == PNG_RESOLUTION_METER)
+ {
+ image->units=PixelsPerCentimeterResolution;
+ image->x_resolution=(double) x_resolution/100.0;
+ image->y_resolution=(double) y_resolution/100.0;
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG pHYs chunk:"
+ " xres: %lu, yres: %lu, units: %d.",
+ (unsigned long)x_resolution,
+ (unsigned long)y_resolution,
+ unit_type);
+ }
+#endif
+ if (png_get_valid(ping, ping_info, PNG_INFO_PLTE))
+ {
+ int
+ number_colors;
+
+ png_colorp
+ palette;
+
+ (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
+ if (number_colors == 0 && ping_colortype ==
+ PNG_COLOR_TYPE_PALETTE)
+ {
+ if (mng_info->global_plte_length)
+ {
+ png_set_PLTE(ping,ping_info,mng_info->global_plte,
+ (int) mng_info->global_plte_length);
+ if (!(png_get_valid(ping, ping_info, PNG_INFO_tRNS)))
+ if (mng_info->global_trns_length)
+ {
+ if (mng_info->global_trns_length >
+ mng_info->global_plte_length)
+ png_error(ping, "global tRNS has more entries"
+ " than global PLTE");
+ png_set_tRNS(ping,ping_info,mng_info->global_trns,
+ (int) mng_info->global_trns_length,NULL);
+ }
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ if (
+#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
+ mng_info->have_saved_bkgd_index ||
+#endif
+ png_get_valid(ping, ping_info, PNG_INFO_bKGD))
+ {
+ png_color_16
+ background;
+
+#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
+ if (mng_info->have_saved_bkgd_index)
+ background.index=mng_info->saved_bkgd_index;
+#endif
+ if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
+ background.index=ping_background->index;
+ background.red=(png_uint_16)
+ mng_info->global_plte[background.index].red;
+ background.green=(png_uint_16)
+ mng_info->global_plte[background.index].green;
+ background.blue=(png_uint_16)
+ mng_info->global_plte[background.index].blue;
+ png_set_bKGD(ping,ping_info,&background);
+ }
+#endif
+ }
+ else
+ png_error (ping, "No global PLTE in file");
+ }
+ }
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ if (mng_info->have_global_bkgd &&
+ !(png_get_valid(ping,ping_info, PNG_INFO_bKGD)))
+ image->background_color=mng_info->mng_global_bkgd;
+ if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
+ {
+ /*
+ Set image background color.
+ */
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG bKGD chunk.");
+
+ if (ping_bit_depth == QuantumDepth)
+ {
+ image->background_color.red = ping_background->red;
+ image->background_color.green= ping_background->green;
+ image->background_color.blue = ping_background->blue;
+ }
+ else /* Scale background components to 16-bit */
+ {
+ unsigned int
+ bkgd_scale;
+
+ if (logging != MagickFalse)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " raw ping_background=(%d,%d,%d).",ping_background->red,
+ ping_background->green,ping_background->blue);
+
+ bkgd_scale = 1;
+ if (ping_file_depth == 1)
+ bkgd_scale = 255;
+ else if (ping_file_depth == 2)
+ bkgd_scale = 85;
+ else if (ping_file_depth == 4)
+ bkgd_scale = 17;
+ if (ping_file_depth <= 8)
+ bkgd_scale *= 257;
+
+ ping_background->red *= bkgd_scale;
+ ping_background->green *= bkgd_scale;
+ ping_background->blue *= bkgd_scale;
+
+ if (logging != MagickFalse)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " bkgd_scale=%d.",bkgd_scale);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " ping_background=(%d,%d,%d).",ping_background->red,
+ ping_background->green,ping_background->blue);
+ }
+
+ image->background_color.red=
+ ScaleShortToQuantum(ping_background->red);
+ image->background_color.green=
+ ScaleShortToQuantum(ping_background->green);
+ image->background_color.blue=
+ ScaleShortToQuantum(ping_background->blue);
+ image->background_color.opacity=OpaqueOpacity;
+
+ if (logging != MagickFalse)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image->background_color=(%d,%d,%d).",
+ image->background_color.red,
+ image->background_color.green,image->background_color.blue);
+ }
+ }
+#endif
+
+ if (png_get_valid(ping, ping_info, PNG_INFO_tRNS))
+ {
+ int
+ bit_mask;
+
+ if (logging != MagickFalse)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG tRNS chunk.");
+
+ bit_mask = (1 << ping_file_depth) - 1;
+
+ /*
+ Image has a transparent background.
+ */
+
+ transparent_color.red=
+ (unsigned long)(ping_trans_color->red & bit_mask);
+ transparent_color.green=
+ (unsigned long) (ping_trans_color->green & bit_mask);
+ transparent_color.blue=
+ (unsigned long) (ping_trans_color->blue & bit_mask);
+ transparent_color.opacity=
+ (unsigned long) (ping_trans_color->gray & bit_mask);
+
+ if (ping_colortype == PNG_COLOR_TYPE_GRAY)
+ {
+#if (QuantumDepth == 8)
+ if (ping_file_depth < QuantumDepth)
+#endif
+ transparent_color.opacity=(unsigned long) (
+ ping_trans_color->gray *
+ (65535L/((1UL << ping_file_depth)-1)));
+
+#if (QuantumDepth == 8)
+ else
+ transparent_color.opacity=(unsigned long) (
+ (ping_trans_color->gray * 65535L)/
+ ((1UL << ping_file_depth)-1));
+#endif
+ if (logging != MagickFalse)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Raw tRNS graylevel is %d.",ping_trans_color->gray);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " scaled graylevel is %d.",
+ (int) transparent_color.opacity);
+ }
+ transparent_color.red=transparent_color.opacity;
+ transparent_color.green=transparent_color.opacity;
+ transparent_color.blue=transparent_color.opacity;
+ }
+ }
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ if (!png_get_valid(ping, ping_info, PNG_INFO_sBIT))
+ if (mng_info->have_global_sbit)
+ png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
+#endif
+ num_passes=png_set_interlace_handling(ping);
+
+ png_read_update_info(ping,ping_info);
+
+ ping_rowbytes=(png_uint_32) png_get_rowbytes(ping,ping_info);
+
+ /*
+ Initialize image structure.
+ */
+ mng_info->image_box.left=0;
+ mng_info->image_box.right=(long) ping_width;
+ mng_info->image_box.top=0;
+ mng_info->image_box.bottom=(long) ping_height;
+ if (mng_info->mng_type == 0)
+ {
+ mng_info->mng_width=ping_width;
+ mng_info->mng_height=ping_height;
+ mng_info->frame=mng_info->image_box;
+ mng_info->clip=mng_info->image_box;
+ }
+ else
+ {
+ image->page.y=mng_info->y_off[mng_info->object_id];
+ }
+ image->compression=ZipCompression;
+ image->columns=ping_width;
+ image->rows=ping_height;
+ if ((ping_colortype == PNG_COLOR_TYPE_PALETTE) ||
+ (ping_colortype == PNG_COLOR_TYPE_GRAY_ALPHA) ||
+ (ping_colortype == PNG_COLOR_TYPE_GRAY))
+ {
+ image->storage_class=PseudoClass;
+ image->colors=1 << ping_file_depth;
+#if (QuantumDepth == 8)
+ if (image->colors > 256)
+ image->colors=256;
+#else
+ if (image->colors > 65536L)
+ image->colors=65536L;
+#endif
+ if (ping_colortype == PNG_COLOR_TYPE_PALETTE)
+ {
+ int
+ number_colors;
+
+ png_colorp
+ palette;
+
+ (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
+ image->colors=number_colors;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG PLTE chunk:"
+ " number_colors: %d.",number_colors);
+ }
+ }
+
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Initialize image colormap.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ png_error(ping, "Could not allocate image colormap");
+ if (ping_colortype == PNG_COLOR_TYPE_PALETTE)
+ {
+ int
+ number_colors;
+
+ png_colorp
+ palette;
+
+ (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
+ image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
+ image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
+ }
+ }
+ else
+ {
+ unsigned long
+ scale;
+
+ scale=(MaxRGB/((1 << ping_file_depth)-1));
+ if (scale < 1)
+ scale=1;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].red=(Quantum) (i*scale);
+ image->colormap[i].green=(Quantum) (i*scale);
+ image->colormap[i].blue=(Quantum) (i*scale);
+ }
+ }
+ }
+ if (image->delay != 0)
+ mng_info->scenes_found++;
+ if (image_info->ping && ((mng_info->mng_type == 0) ||
+ ((image_info->number_scenes != 0) &&
+ mng_info->scenes_found > (long) (image_info->first_scene+
+ image_info->number_scenes))))
+ {
+ /* This happens later in non-ping decodes */
+ if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
+ image->storage_class=DirectClass;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Skipping PNG image data for scene %ld",
+ mng_info->scenes_found-1);
+ png_destroy_read_struct(&ping,&ping_info,&end_info);
+ MagickFreeMemory(mng_info->quantum_scanline);
+ MagickFreeMemory(mng_info->png_pixels);
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " exit ReadOnePNGImage().");
+ return (image);
+ }
+
+ /*
+ Read image scanlines.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG IDAT chunk(s)");
+ if (num_passes > 1)
+ mng_info->png_pixels=MagickAllocateMemory(unsigned char *,
+ ping_rowbytes*image->rows);
+ else
+ mng_info->png_pixels=MagickAllocateMemory(unsigned char *, ping_rowbytes);
+ if (mng_info->png_pixels == (unsigned char *) NULL)
+ png_error(ping, "Could not allocate png_pixels array");
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Converting PNG pixels to pixel packets");
+ /*
+ Convert PNG pixels to pixel packets.
+ */
+ if (image->storage_class == DirectClass)
+ for (pass=0; pass < num_passes; pass++)
+ {
+ /*
+ Convert image to DirectClass pixel packets.
+ */
+#if (QuantumDepth == 8)
+ int
+ depth;
+
+ depth=(long) ping_bit_depth;
+#endif
+ image->matte=((ping_colortype == PNG_COLOR_TYPE_RGB_ALPHA) ||
+ (ping_colortype == PNG_COLOR_TYPE_GRAY_ALPHA) ||
+ (png_get_valid(ping, ping_info, PNG_INFO_tRNS)));
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (num_passes > 1)
+ row_offset=ping_rowbytes*y;
+
+ else
+ row_offset=0;
+
+ png_read_row(ping,mng_info->png_pixels+row_offset,NULL);
+
+ if (!SetImagePixels(image,0,y,image->columns,1))
+ break;
+
+ if (pass < num_passes-1)
+ continue;
+
+#if (QuantumDepth == 8)
+ if (depth == 16)
+ {
+ register Quantum
+ *p,
+ *r;
+
+ r=mng_info->png_pixels+row_offset;
+ p=r;
+ if (ping_colortype == PNG_COLOR_TYPE_GRAY)
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *r++=*p++;
+ p++;
+ if ((png_get_valid(ping, ping_info, PNG_INFO_tRNS)) &&
+ ((unsigned long) ((*(p-2) << 8)|*(p-1))
+ == transparent_color.opacity))
+ {
+ /* Cheap transparency */
+ *r++=TransparentOpacity;
+ }
+ else
+ *r++=OpaqueOpacity;
+ }
+ }
+ else if (ping_colortype == PNG_COLOR_TYPE_RGB)
+ {
+ if (png_get_valid(ping, ping_info, PNG_INFO_tRNS))
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *r++=*p++;
+ p++;
+ *r++=*p++;
+ p++;
+ *r++=*p++;
+ p++;
+ if (((unsigned long) ((*(p-6) << 8)|*(p-5)) ==
+ transparent_color.red) &&
+ ((unsigned long) ((*(p-4) << 8)|*(p-3)) ==
+ transparent_color.green) &&
+ ((unsigned long) ((*(p-2) << 8)|*(p-1)) ==
+ transparent_color.blue))
+ {
+ /* Cheap transparency */
+ *r++=TransparentOpacity;
+ }
+ else
+ *r++=OpaqueOpacity;
+ }
+ else
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *r++=*p++;
+ p++;
+ *r++=*p++;
+ p++;
+ *r++=*p++;
+ p++;
+ *r++=OpaqueOpacity;
+ }
+ }
+ else if (ping_colortype == PNG_COLOR_TYPE_RGB_ALPHA)
+ for (x=(long) (4*image->columns); x > 0; x--)
+ {
+ *r++=*p++;
+ p++;
+ }
+ else if (ping_colortype == PNG_COLOR_TYPE_GRAY_ALPHA)
+ for (x=(long) (2*image->columns); x > 0; x--)
+ {
+ *r++=*p++;
+ p++;
+ }
+ }
+ if (depth == 8 && ping_colortype == PNG_COLOR_TYPE_GRAY)
+ (void) ImportImagePixelArea(image,(QuantumType) GrayQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ else if (ping_colortype == PNG_COLOR_TYPE_GRAY)
+ {
+ image->depth=8;
+ (void) ImportImagePixelArea(image,
+ (QuantumType) GrayQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ image->depth=depth;
+ }
+ else if (ping_colortype == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ image->depth=8;
+ (void) ImportImagePixelArea(image,
+ (QuantumType) GrayAlphaQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ image->depth=depth;
+ }
+ else if (depth == 8 && ping_colortype == PNG_COLOR_TYPE_RGB)
+ (void) ImportImagePixelArea(image,(QuantumType) RGBQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ else if (ping_colortype == PNG_COLOR_TYPE_RGB)
+ {
+ image->depth=8;
+ (void) ImportImagePixelArea(image,(QuantumType) RGBQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ image->depth=depth;
+ }
+ else if (ping_colortype == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ image->depth=8;
+ (void) ImportImagePixelArea(image,(QuantumType) RGBAQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ image->depth=depth;
+ }
+ else if (ping_colortype == PNG_COLOR_TYPE_PALETTE)
+ (void) ImportImagePixelArea(image,(QuantumType) IndexQuantum,
+ ping_bit_depth,mng_info->png_pixels+
+ row_offset,0,0);
+ /* FIXME, sample size ??? */
+#else /* (QuantumDepth != 8) */
+
+ if (ping_colortype == PNG_COLOR_TYPE_GRAY)
+ (void) ImportImagePixelArea(image,(QuantumType) GrayQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ else if (ping_colortype == PNG_COLOR_TYPE_GRAY_ALPHA)
+ (void) ImportImagePixelArea(image,(QuantumType) GrayAlphaQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ else if (ping_colortype == PNG_COLOR_TYPE_RGB_ALPHA)
+ (void) ImportImagePixelArea(image,(QuantumType) RGBAQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+ else if (ping_colortype == PNG_COLOR_TYPE_PALETTE)
+ (void) ImportImagePixelArea(image,(QuantumType) IndexQuantum,
+ ping_bit_depth,mng_info->png_pixels+
+ row_offset,0,0);
+ /* FIXME, sample size ??? */
+ else
+ (void) ImportImagePixelArea(image,(QuantumType) RGBQuantum,
+ image->depth,mng_info->png_pixels+
+ row_offset,0,0);
+#endif
+ if (!SyncImagePixels(image))
+ break;
+ }
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(pass, num_passes))
+ if (!MagickMonitorFormatted(pass,num_passes,exception,
+ LoadImageTag,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+
+ else /* image->storage_class != DirectClass */
+ {
+ image->matte=ping_colortype == PNG_COLOR_TYPE_GRAY_ALPHA;
+ mng_info->quantum_scanline=MagickAllocateMemory(Quantum *,
+ (image->matte ? 2 : 1) * image->columns*sizeof(Quantum));
+ if (mng_info->quantum_scanline == (Quantum *) NULL)
+ png_error(ping, "Could not allocate quantum_scanline");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Allocated quantum_scanline");
+
+ for (pass=0; pass < num_passes; pass++)
+ {
+ register Quantum
+ *r;
+
+ /*
+ Convert grayscale image to PseudoClass pixel packets.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register unsigned char
+ *p;
+
+ if (num_passes > 1)
+ row_offset=ping_rowbytes*y;
+
+ else
+ row_offset=0;
+
+ png_read_row(ping,mng_info->png_pixels+row_offset,NULL);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+
+ if (pass < num_passes-1)
+ continue;
+
+ indexes=AccessMutableIndexes(image);
+ p=mng_info->png_pixels+row_offset;
+ r=mng_info->quantum_scanline;
+ switch (ping_bit_depth)
+ {
+ case 8:
+ {
+ if (ping_colortype == 4)
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *r++=*p++;
+ /* In image.h, OpaqueOpacity is 0
+ * TransparentOpacity is MaxRGB
+ * In a PNG datastream, Opaque is MaxRGB
+ * and Transparent is 0.
+ */
+ q->opacity=ScaleCharToQuantum(255-(*p++));
+ q++;
+ }
+ else
+ for (x=(long) image->columns; x > 0; x--)
+ *r++=*p++;
+ break;
+ }
+ case 16:
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+#if (QuantumDepth == 16)
+ if (image->colors > 256)
+ *r=((*p++) << 8);
+ else
+ *r=0;
+ *r|=(*p++);
+ r++;
+ if (ping_colortype == 4)
+ {
+ q->opacity=((*p++) << 8);
+ q->opacity|=(*p++);
+ q->opacity=(Quantum) (MaxRGB-q->opacity);
+ q++;
+ }
+#else
+#if (QuantumDepth == 32)
+ if (image->colors > 256)
+ *r=((*p++) << 8);
+ else
+ *r=0;
+ *r|=(*p++);
+ r++;
+ if (ping_colortype == 4)
+ {
+ q->opacity=((*p++) << 8);
+ q->opacity|=(*p++);
+ q->opacity*=65537L;
+ q->opacity=(Quantum) (MaxRGB-q->opacity);
+ q++;
+ }
+#else /* QuantumDepth == 8 */
+ *r++=(*p++);
+ p++; /* strip low byte */
+ if (ping_colortype == 4)
+ {
+ q->opacity=(Quantum) (MaxRGB-(*p++));
+ p++;
+ q++;
+ }
+#endif
+#endif
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ /*
+ Transfer image scanline.
+ */
+ r=mng_info->quantum_scanline;
+
+ for (x=0; x < (long) image->columns; x++)
+ indexes[x]=(*r++);
+
+ if (!SyncImagePixels(image))
+ break;
+ }
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(pass, num_passes))
+ if (!MagickMonitorFormatted(pass,num_passes,exception,LoadImageTag,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+
+ MagickFreeMemory(mng_info->quantum_scanline);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Free'ed quantum_scanline after last pass");
+ }
+
+ if (image->storage_class == PseudoClass)
+ (void) SyncImage(image);
+ png_read_end(ping,ping_info);
+
+ if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
+ (long) image_info->first_scene && image->delay != 0.)
+ {
+ png_destroy_read_struct(&ping,&ping_info,&end_info);
+ MagickFreeMemory(mng_info->quantum_scanline);
+ MagickFreeMemory(mng_info->png_pixels);
+ image->colors=2;
+ (void) SetImage(image,TransparentOpacity);
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " exit ReadOnePNGImage().");
+ return (image);
+ }
+ if (png_get_valid(ping, ping_info, PNG_INFO_tRNS))
+ {
+ ClassType
+ storage_class;
+
+ /*
+ Image has a transparent background.
+ */
+ storage_class=image->storage_class;
+ image->matte=MagickTrue;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ image->storage_class=storage_class;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+
+ if (storage_class == PseudoClass)
+ {
+ IndexPacket
+ index;
+
+ if (ping_colortype == PNG_COLOR_TYPE_PALETTE)
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=indexes[x];
+ if (index < (unsigned int) ping_num_trans)
+ q->opacity=
+ ScaleCharToQuantum(255-ping_trans_alpha[index]);
+ else
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ else if (ping_colortype == PNG_COLOR_TYPE_GRAY)
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=indexes[x];
+ q->red=image->colormap[index].red;
+ q->green=image->colormap[index].green;
+ q->blue=image->colormap[index].blue;
+ if ((unsigned long) ScaleQuantumToShort(q->red) ==
+ transparent_color.opacity)
+ q->opacity=TransparentOpacity;
+ else
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ }
+ else
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if ((unsigned long) ScaleQuantumToShort(q->red) ==
+ transparent_color.red &&
+ (unsigned long) ScaleQuantumToShort(q->green) ==
+ transparent_color.green &&
+ (unsigned long) ScaleQuantumToShort(q->blue) ==
+ transparent_color.blue)
+ q->opacity=TransparentOpacity;
+ else
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ image->storage_class=DirectClass;
+ }
+#if (QuantumDepth == 8)
+ if (image->depth > 8)
+ image->depth=8;
+#endif
+ if (png_get_text(ping,ping_info,&text,&num_text) != 0)
+ for (i=0; i < (long) num_text; i++)
+ {
+ /* Check for a profile */
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading PNG text chunk");
+ if (strlen(text[i].key) > 16 &&
+ !memcmp(text[i].key, "Raw profile type ",17))
+ {
+ if (png_read_raw_profile(image,image_info,text,(int) i) ==
+ MagickFail)
+ break;
+ }
+ else
+ {
+ char
+ *value;
+
+ length=(unsigned long) text[i].text_length;
+ value=MagickAllocateMemory(char *,length+1);
+ if (value == (char *) NULL)
+ {
+ png_warning(ping, "Could not allocate memory for text chunk");
+ break;
+ }
+ *value='\0';
+ (void) strlcat(value,text[i].text,length+1);
+ (void) SetImageAttribute(image,text[i].key,value);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Keyword: %s",text[i].key);
+ MagickFreeMemory(value);
+ }
+ }
+#ifdef MNG_OBJECT_BUFFERS
+ /*
+ Store the object if necessary.
+ */
+ if (object_id && !mng_info->frozen[object_id])
+ {
+ if (mng_info->ob[object_id] == (MngBuffer *) NULL)
+ {
+ /*
+ create a new object buffer.
+ */
+ mng_info->ob[object_id]=MagickAllocateMemory(MngBuffer *,
+ sizeof(MngBuffer));
+ if (mng_info->ob[object_id] != (MngBuffer *) NULL)
+ {
+ mng_info->ob[object_id]->image=(Image *) NULL;
+ mng_info->ob[object_id]->reference_count=1;
+ }
+ }
+ if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
+ mng_info->ob[object_id]->frozen)
+ {
+ if (mng_info->ob[object_id] == (MngBuffer *) NULL)
+ png_error(ping, "Could not allocate MNG object");
+ if (mng_info->ob[object_id]->frozen)
+ png_error(ping, "Could not overwrite MNG frozen object buffer");
+ }
+ else
+ {
+ png_uint_32
+ width,
+ height;
+
+ int
+ bit_depth,
+ color_type,
+ interlace_method,
+ compression_method,
+ filter_method;
+
+ if (mng_info->ob[object_id]->image != (Image *) NULL)
+ DestroyImage(mng_info->ob[object_id]->image);
+ mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
+ &image->exception);
+ if (mng_info->ob[object_id]->image != (Image *) NULL)
+ mng_info->ob[object_id]->image->file=(FILE *) NULL;
+ else
+ png_error(ping, "Cloning image for object buffer failed");
+ png_get_IHDR(ping,ping_info,&width,&height,&bit_depth,&color_type,
+ &interlace_method,&compression_method,&filter_method);
+ if (width > 250000L || height > 250000L)
+ png_error(ping,"PNG Image dimensions are too large.");
+ mng_info->ob[object_id]->width=width;
+ mng_info->ob[object_id]->height=height;
+ mng_info->ob[object_id]->color_type=color_type;
+ mng_info->ob[object_id]->sample_depth=bit_depth;
+ mng_info->ob[object_id]->interlace_method=interlace_method;
+ mng_info->ob[object_id]->compression_method=compression_method;
+ mng_info->ob[object_id]->filter_method=filter_method;
+ if (png_get_valid(ping, ping_info, PNG_INFO_PLTE))
+ {
+ int
+ number_colors;
+
+ png_colorp
+ plte;
+
+ /*
+ Copy the PLTE to the object buffer.
+ */
+ png_get_PLTE(ping,ping_info,&plte,&number_colors);
+ mng_info->ob[object_id]->plte_length=number_colors;
+ for (i=0; i < number_colors; i++)
+ {
+ mng_info->ob[object_id]->plte[i]=plte[i];
+ }
+ }
+ else
+ mng_info->ob[object_id]->plte_length=0;
+ }
+ }
+#endif
+ /*
+ Free memory.
+ */
+ png_destroy_read_struct(&ping,&ping_info,&end_info);
+ MagickFreeMemory(mng_info->quantum_scanline);
+ MagickFreeMemory(mng_info->png_pixels);
+
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " exit ReadOnePNGImage()");
+ return (image);
+
+ /* End of setjmp-controlled block } */
+
+ /* end of reading one PNG image */
+}
+
+static Image *ReadPNGImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ MngInfo
+ *mng_info;
+
+ char
+ magic_number[MaxTextExtent];
+
+ int
+ have_mng_structure,
+ logging;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
+ image=AllocateImage(image_info);
+ mng_info=(MngInfo *) NULL;
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFalse)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Verify PNG signature.
+ */
+ (void) ReadBlob(image,8,magic_number);
+ if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
+ {
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+
+ /*
+ Verify that file size large enough to contain a PNG datastream
+ if using a seekable blob
+ */
+ if (BlobIsSeekable(image) && GetBlobSize(image) < 61)
+ {
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ }
+
+ /*
+ Allocate a MngInfo structure.
+ */
+ have_mng_structure=MagickFalse;
+ mng_info=MagickAllocateMemory(MngInfo *,sizeof(MngInfo));
+ if (mng_info == (MngInfo *) NULL)
+ {
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ /*
+ Initialize members of the MngInfo structure.
+ */
+ (void) memset(mng_info,0,sizeof(MngInfo));
+ mng_info->image=image;
+ have_mng_structure=MagickTrue;
+
+ image=ReadOnePNGImage(mng_info,image_info,exception);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ if (image == (Image *) NULL)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "exit ReadPNGImage() with error");
+ return((Image *) NULL);
+ }
+ CloseBlob(image);
+ if (image->columns == 0 || image->rows == 0)
+ {
+ if (image->exception.severity > exception->severity)
+ CopyException(exception,&image->exception);
+ DestroyImageList(image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "exit ReadPNGImage() with error.");
+ return((Image *) NULL);
+ }
+ if (LocaleCompare(image_info->magick,"PNG8") == 0)
+ {
+ (void) SetImageType(image,PaletteType);
+ if (image->matte)
+ {
+ /* To do: Reduce to binary transparency */
+ }
+ }
+ if (LocaleCompare(image_info->magick,"PNG24") == 0)
+ {
+ (void) SetImageType(image,TrueColorType);
+ image->matte=MagickFalse;
+ }
+ if (LocaleCompare(image_info->magick,"PNG32") == 0)
+ (void) SetImageType(image,TrueColorMatteType);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
+ return (image);
+}
+
+
+
+#if defined(JNG_SUPPORTED)
+
+
+void
+DestroyJNGInfo(ImageInfo *color_image_info, ImageInfo *alpha_image_info)
+{
+ if (color_image_info != (ImageInfo *)NULL)
+ {
+ DestroyImageInfo(color_image_info);
+ }
+ if (alpha_image_info != (ImageInfo *)NULL)
+ {
+ DestroyImageInfo(alpha_image_info);
+ }
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d O n e J N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadOneJNGImage reads a JPEG Network Graphics (JNG) image file
+% (minus the 8-byte signature) and returns it. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% JNG support written by Glenn Randers-Pehrson, randeg@alum.rpi.edu.
+%
+% The format of the ReadOneJNGImage method is:
+%
+% Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadOneJNGImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o mng_info: Specifies a pointer to a MngInfo structure.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+static Image *ReadOneJNGImage(MngInfo *mng_info,
+ const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *alpha_image,
+ *color_image,
+ *image,
+ *jng_image;
+
+ ImageInfo
+ *alpha_image_info,
+ *color_image_info;
+
+ long
+ y;
+
+ magick_int64_t
+ height_resource,
+ width_resource;
+
+ unsigned long
+ jng_height,
+ jng_width;
+
+ png_byte
+ jng_color_type,
+ jng_image_sample_depth,
+ jng_image_compression_method,
+ jng_image_interlace_method,
+ jng_alpha_sample_depth,
+ jng_alpha_compression_method,
+ jng_alpha_filter_method,
+ jng_alpha_interlace_method;
+
+ register const PixelPacket
+ *s;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ unsigned int
+ logging,
+ read_JSEP,
+ reading_idat,
+ status;
+
+ unsigned long
+ length;
+
+ jng_alpha_compression_method=0;
+ jng_alpha_sample_depth=8;
+ jng_color_type=0;
+ jng_height=0;
+ jng_width=0;
+ alpha_image=(Image *) NULL;
+ color_image=(Image *) NULL;
+ alpha_image_info=(ImageInfo *) NULL;
+ color_image_info=(ImageInfo *) NULL;
+
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),
+ " enter ReadOneJNGImage()");
+
+ image=mng_info->image;
+ if (AccessMutablePixels(image) != (PixelPacket *) NULL)
+ {
+ /*
+ Allocate next image structure.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " AllocateNextImage()");
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ return((Image *) NULL);
+ image=SyncNextImageInList(image);
+ }
+ mng_info->image=image;
+
+ /*
+ Signature bytes have already been read.
+ */
+
+ read_JSEP=MagickFalse;
+ reading_idat=MagickFalse;
+
+ width_resource = GetMagickResourceLimit(WidthResource);
+ height_resource = GetMagickResourceLimit(HeightResource);
+
+ for (;;)
+ {
+ char
+ type[MaxTextExtent];
+
+ unsigned char
+ *chunk;
+
+ unsigned int
+ count;
+
+ /*
+ Read a new JNG chunk.
+ */
+
+ if (QuantumTick(TellBlob(image),2*GetBlobSize(image)))
+ if (!MagickMonitorFormatted(TellBlob(image),2*GetBlobSize(image),
+ exception,LoadImagesTag,image->filename))
+ break;
+
+ type[0]='\0';
+ (void) strcat(type,"errr");
+ length=ReadBlobMSBLong(image);
+ count=(unsigned int) ReadBlob(image,4,type);
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading JNG chunk type %c%c%c%c, length: %lu",
+ type[0],type[1],type[2],type[3],length);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " count=%u\n",count);
+ }
+
+ if (length > PNG_MAX_UINT || count == 0)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+
+ chunk=(unsigned char *) NULL;
+ p=NULL;
+ if (length)
+ {
+ chunk=MagickAllocateMemory(unsigned char *,length);
+ if (chunk == (unsigned char *) NULL)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ if (ReadBlob(image,length,chunk) < length)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+ p=chunk;
+ }
+ (void) ReadBlobMSBLong(image); /* read crc word */
+
+ if (!memcmp(type,mng_JHDR,4))
+ {
+ if (length != 16)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ MagickFreeMemory(chunk);
+ (void) ThrowException2(&image->exception,CoderWarning,
+ "Invalid JHDR chunk length",(char *) NULL);
+ return (MagickFail);
+ }
+
+ jng_width=(unsigned long) ((p[0] << 24) | (p[1] << 16) |
+ (p[2] << 8) | p[3]);
+ jng_height=(unsigned long) ((p[4] << 24) | (p[5] << 16) |
+ (p[6] << 8) | p[7]);
+ jng_color_type=p[8];
+ jng_image_sample_depth=p[9];
+ jng_image_compression_method=p[10];
+ jng_image_interlace_method=p[11];
+ jng_alpha_sample_depth=p[12];
+ jng_alpha_compression_method=p[13];
+ jng_alpha_filter_method=p[14];
+ jng_alpha_interlace_method=p[15];
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_width: %16lu",
+ jng_width);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_height: %16lu",
+ jng_height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_color_type: %16d",
+ jng_color_type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_image_sample_depth: %3d",
+ jng_image_sample_depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_image_compression_method:%3d",
+ jng_image_compression_method);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_image_interlace_method: %3d",
+ jng_image_interlace_method);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_alpha_sample_depth: %3d",
+ jng_alpha_sample_depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_alpha_compression_method:%3d",
+ jng_alpha_compression_method);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_alpha_filter_method: %3d",
+ jng_alpha_filter_method);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " jng_alpha_interlace_method: %3d",
+ jng_alpha_interlace_method);
+ }
+
+ if (length)
+ MagickFreeMemory(chunk);
+
+ if (jng_width > 65535 || jng_height > 65535 ||
+ (long) jng_width > GetMagickResourceLimit(WidthResource) ||
+ (long) jng_height > GetMagickResourceLimit(HeightResource))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG width or height too large: (%lu x %lu)",
+ jng_width, jng_height);
+ MagickFreeMemory(chunk);
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+
+ /* Temporarily set width and height resources to match JHDR */
+ SetMagickResourceLimit(WidthResource,jng_width);
+ SetMagickResourceLimit(HeightResource,jng_height);
+
+ continue;
+ }
+
+
+ if (!reading_idat && !read_JSEP && (!memcmp(type,mng_JDAT,4) ||
+ !memcmp(type,mng_JdAA,4) ||
+ !memcmp(type,mng_IDAT,4) ||
+ !memcmp(type,mng_JDAA,4)))
+ {
+ /*
+ o create color_image
+ o open color_blob, attached to color_image
+ o if (color type has alpha)
+ open alpha_blob, attached to alpha_image
+ */
+
+ color_image_info=MagickAllocateMemory(ImageInfo *,sizeof(ImageInfo));
+ if (color_image_info == (ImageInfo *) NULL)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ GetImageInfo(color_image_info);
+ color_image=AllocateImage(color_image_info);
+ if (color_image == (Image *) NULL)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating color_blob.");
+ (void) AcquireUniqueFilename(color_image->filename);
+ status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
+ exception);
+ if (status == MagickFalse)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(CoderError,UnableToOpenBlob,color_image);
+ }
+
+ if (!image_info->ping && jng_color_type >= 12)
+ {
+ alpha_image_info=MagickAllocateMemory(ImageInfo *,
+ sizeof(ImageInfo));
+ if (alpha_image_info == (ImageInfo *) NULL)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(ResourceLimitError,
+ MemoryAllocationFailed, image);
+ }
+ GetImageInfo(alpha_image_info);
+ alpha_image=AllocateImage(alpha_image_info);
+ if (alpha_image == (Image *) NULL)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ ThrowReaderException(ResourceLimitError,
+ MemoryAllocationFailed,
+ alpha_image);
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating alpha_blob.");
+ (void) AcquireUniqueFilename(alpha_image->filename);
+ status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
+ exception);
+ if (status == MagickFalse)
+ {
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+ DestroyImage(alpha_image);
+ ThrowReaderException(CoderError,UnableToOpenBlob,image);
+ }
+ if (jng_alpha_compression_method == 0)
+ {
+ unsigned char
+ data[18];
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing IHDR chunk"
+ " to alpha_blob.");
+ (void) WriteBlob(alpha_image,8,"\211PNG\r\n\032\n");
+ (void) WriteBlobMSBULong(alpha_image,13L);
+ PNGType(data,mng_IHDR);
+ LogPNGChunk(logging,mng_IHDR,13L);
+ PNGLong(data+4,jng_width);
+ PNGLong(data+8,jng_height);
+ data[12]=jng_alpha_sample_depth;
+ data[13]=0; /* color_type gray */
+ data[14]=0; /* compression method 0 */
+ data[15]=0; /* filter_method 0 */
+ data[16]=0; /* interlace_method 0 */
+ (void) WriteBlob(alpha_image,17,data);
+ (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
+ }
+ }
+ reading_idat=MagickTrue;
+ }
+
+ if (!memcmp(type,mng_JDAT,4))
+ {
+ /*
+ Copy chunk to color_image->blob
+ */
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Copying JDAT chunk data"
+ " to color_blob.");
+ if (color_image != (Image *)NULL)
+ (void) WriteBlob(color_image,length,(char *) chunk);
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_IDAT,4))
+ {
+ png_byte
+ data[5];
+
+ /*
+ Copy IDAT header and chunk data to alpha_image->blob
+ */
+
+ if (alpha_image != NULL && image_info->ping == MagickFalse)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Copying IDAT chunk data"
+ " to alpha_blob.");
+
+ (void) WriteBlobMSBULong(alpha_image,(unsigned long) length);
+ PNGType(data,mng_IDAT);
+ LogPNGChunk(logging,mng_IDAT,length);
+ (void) WriteBlob(alpha_image,4,(char *) data);
+ (void) WriteBlob(alpha_image,length,(char *) chunk);
+ (void) WriteBlobMSBULong(alpha_image,
+ crc32(crc32(0,data,4),chunk,length));
+ }
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_JDAA,4) || !memcmp(type,mng_JdAA,4))
+ {
+ /*
+ Copy chunk data to alpha_image->blob
+ */
+
+ if (alpha_image != NULL && image_info->ping == MagickFalse)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Copying JDAA chunk data"
+ " to alpha_blob.");
+
+ (void) WriteBlob(alpha_image,length,(char *) chunk);
+ }
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_JSEP,4))
+ {
+ read_JSEP=MagickTrue;
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_bKGD,4))
+ {
+ if (length == 2)
+ {
+ image->background_color.red=ScaleCharToQuantum(p[1]);
+ image->background_color.green=image->background_color.red;
+ image->background_color.blue=image->background_color.red;
+ }
+ if (length == 6)
+ {
+ image->background_color.red=ScaleCharToQuantum(p[1]);
+ image->background_color.green=ScaleCharToQuantum(p[3]);
+ image->background_color.blue=ScaleCharToQuantum(p[5]);
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_gAMA,4))
+ {
+ if (length == 4)
+ image->gamma=((float) mng_get_long(p))*0.00001;
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_cHRM,4))
+ {
+ if (length == 32)
+ {
+ image->chromaticity.white_point.x=0.00001*mng_get_long(p);
+ image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
+ image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
+ image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
+ image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
+ image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
+ image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
+ image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_sRGB,4))
+ {
+ if (length == 1)
+ {
+ image->rendering_intent=(RenderingIntent) (p[0]+1);
+ image->gamma=0.45455f;
+ image->chromaticity.red_primary.x=0.6400f;
+ image->chromaticity.red_primary.y=0.3300f;
+ image->chromaticity.green_primary.x=0.3000f;
+ image->chromaticity.green_primary.y=0.6000f;
+ image->chromaticity.blue_primary.x=0.1500f;
+ image->chromaticity.blue_primary.y=0.0600f;
+ image->chromaticity.white_point.x=0.3127f;
+ image->chromaticity.white_point.y=0.3290f;
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_oFFs,4))
+ {
+ if (length > 8)
+ {
+ image->page.x=mng_get_long(p);
+ image->page.y=mng_get_long(&p[4]);
+ if ((int) p[9] != 0)
+ {
+ image->page.x/=10000;
+ image->page.y/=10000;
+ }
+ }
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_pHYs,4))
+ {
+ if (length > 8)
+ {
+ image->x_resolution=(double) mng_get_long(p);
+ image->y_resolution=(double) mng_get_long(&p[4]);
+ if ((int) p[8] == PNG_RESOLUTION_METER)
+ {
+ image->units=PixelsPerCentimeterResolution;
+ image->x_resolution=image->x_resolution/100.0f;
+ image->y_resolution=image->y_resolution/100.0f;
+ }
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+#if 0
+ if (!memcmp(type,mng_iCCP,4))
+ {
+ /* To do. */
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+#endif
+
+ if (length)
+ MagickFreeMemory(chunk);
+
+ if (memcmp(type,mng_IEND,4))
+ continue;
+ break;
+ }
+
+
+ /* IEND found */
+
+ /*
+ Finish up reading image data:
+
+ o read main image from color_blob.
+
+ o close color_blob.
+
+ o if (color_type has alpha)
+ if alpha_encoding is PNG
+ read secondary image from alpha_blob via ReadPNG
+ if alpha_encoding is JPEG
+ read secondary image from alpha_blob via ReadJPEG
+
+ o close alpha_blob.
+
+ o copy intensity of secondary image into
+ opacity samples of main image.
+
+ o destroy the secondary image.
+ */
+
+ if (color_image != (Image *)NULL)
+ {
+ CloseBlob(color_image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading jng_image from color_blob.");
+
+ FormatString(color_image_info->filename,"%.1024s",color_image->filename);
+
+ color_image_info->ping=MagickFalse; /* To do: avoid this */
+ jng_image=ReadImage(color_image_info,exception);
+ (void) LiberateUniqueFileResource(color_image->filename);
+ DestroyImage(color_image);
+ color_image = (Image *)NULL;
+ DestroyImageInfo(color_image_info);
+ color_image_info = (ImageInfo *)NULL;
+
+ if (jng_image == (Image *) NULL)
+ {
+ /*
+ Don't throw exception here since ReadImage() will already
+ have thrown it.
+ */
+ DestroyImage(image);
+ return (Image *) NULL;
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Copying jng_image pixels to main image.");
+ image->rows=jng_height;
+ image->columns=jng_width;
+ length=image->columns*sizeof(PixelPacket);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ s=AcquireImagePixels(jng_image,0,y,image->columns,1,&image->exception);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ (void) memcpy(q,s,length);
+ if (!SyncImagePixels(image))
+ break;
+ }
+ DestroyImage(jng_image);
+ jng_image = (Image *)NULL;
+ if (alpha_image != (Image *)NULL && !image_info->ping)
+ {
+ if (jng_color_type >= 12)
+ {
+ if (jng_alpha_compression_method == 0)
+ {
+ png_byte
+ data[5];
+ (void) WriteBlobMSBULong(alpha_image,0x00000000L);
+ PNGType(data,mng_IEND);
+ LogPNGChunk(logging,mng_IEND,0L);
+ (void) WriteBlob(alpha_image,4,(char *) data);
+ (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
+ }
+ CloseBlob(alpha_image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading opacity from alpha_blob.");
+
+ FormatString(alpha_image_info->filename,"%.1024s",
+ alpha_image->filename);
+
+ jng_image=ReadImage(alpha_image_info,exception);
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ s=AcquireImagePixels(jng_image,0,y,image->columns,1,
+ &image->exception);
+ if (image->matte)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ for (x=(long) image->columns; x > 0; x--,q++,s++)
+ q->opacity=(Quantum) MaxRGB-s->red;
+ }
+ else
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ for (x=(long) image->columns; x > 0; x--,q++,s++)
+ {
+ q->opacity=(Quantum) MaxRGB-s->red;
+ if (q->opacity != OpaqueOpacity)
+ image->matte=MagickTrue;
+ }
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ (void) LiberateUniqueFileResource(alpha_image->filename);
+ DestroyImage(alpha_image);
+ alpha_image = (Image *)NULL;
+ DestroyImageInfo(alpha_image_info);
+ alpha_image_info = (ImageInfo *)NULL;
+ DestroyImage(jng_image);
+ jng_image = (Image *)NULL;
+ }
+ }
+
+ /*
+ Read the JNG image.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Read the JNG image");
+ image->page.width=jng_width;
+ image->page.height=jng_height;
+ image->page.x=mng_info->x_off[mng_info->object_id];
+ image->page.y=mng_info->y_off[mng_info->object_id];
+ mng_info->image_found++;
+ if (QuantumTick(2*GetBlobSize(image),2*GetBlobSize(image)))
+ (void) MagickMonitorFormatted(2*GetBlobSize(image),2*GetBlobSize(image),
+ exception,LoadImagesTag,image->filename);
+ }
+
+ /* Clean up in case we didn't earlier */
+
+ DestroyJNGInfo(color_image_info,alpha_image_info);
+
+ if (alpha_image != (Image *)NULL)
+ {
+ (void) LiberateUniqueFileResource(alpha_image->filename);
+ DestroyImage(alpha_image);
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " exit ReadOneJNGImage()");
+
+ SetMagickResourceLimit(WidthResource,width_resource);
+ SetMagickResourceLimit(HeightResource,height_resource);
+
+ return (image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d J N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadJNGImage reads a JPEG Network Graphics (JNG) image file
+% (including the 8-byte signature) and returns it. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% JNG support written by Glenn Randers-Pehrson, randeg@alum.rpi.edu.
+%
+% The format of the ReadJNGImage method is:
+%
+% Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
+% *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadJNGImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+
+static Image *ReadJNGImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ MngInfo
+ *mng_info;
+
+ char
+ magic_number[MaxTextExtent];
+
+ int
+ have_mng_structure,
+ logging;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
+ image=AllocateImage(image_info);
+ mng_info=(MngInfo *) NULL;
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFalse)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ if (LocaleCompare(image_info->magick,"JNG") != 0)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Verify JNG signature.
+ */
+ if ((ReadBlob(image,8,magic_number) != 8) ||
+ (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (BlobIsSeekable(image) && GetBlobSize(image) < 147)
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+
+ /*
+ Allocate a MngInfo structure.
+ */
+ have_mng_structure=MagickFalse;
+ mng_info=MagickAllocateMemory(MngInfo *,sizeof(MngInfo));
+ if (mng_info == (MngInfo *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize members of the MngInfo structure.
+ */
+ (void) memset(mng_info,0,sizeof(MngInfo));
+ have_mng_structure=MagickTrue;
+
+ mng_info->image=image;
+ image=ReadOneJNGImage(mng_info,image_info,exception);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ if (image == (Image *) NULL)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "exit ReadJNGImage() with error");
+ return((Image *) NULL);
+ }
+ CloseBlob(image);
+ if (image->columns == 0 || image->rows == 0)
+ {
+ DestroyImageList(image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "exit ReadJNGImage() with error");
+ return((Image *) NULL);
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
+ return (image);
+}
+#endif
+
+static Image *ReadMNGImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ char
+ page_geometry[MaxTextExtent];
+
+ Image
+ *image,
+ *previous;
+
+ int
+ have_mng_structure;
+
+ volatile int
+ first_mng_object,
+ logging,
+ object_id,
+ term_chunk_found,
+ skip_to_iend;
+
+ volatile long
+ image_count=0;
+
+ MngInfo
+ *mng_info;
+
+ MngBox
+ default_fb,
+ fb,
+ previous_fb;
+
+#ifdef MNG_INSERT_LAYERS
+ PixelPacket
+ mng_background_color;
+#endif
+
+ register long
+ i;
+
+ size_t
+ count;
+
+ short
+ loop_level,
+ loops_active = 0;
+
+ volatile short
+ skipping_loop;
+
+ unsigned int
+#ifdef MNG_INSERT_LAYERS
+ mandatory_back=0,
+#endif
+ status;
+
+ volatile unsigned int
+#ifdef MNG_OBJECT_BUFFERS
+ mng_background_object=0,
+#endif
+ mng_type=0; /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
+
+ unsigned long
+ default_frame_timeout,
+ frame_timeout,
+#ifdef MNG_INSERT_LAYERS
+ image_height,
+ image_width,
+#endif
+ length;
+
+ volatile unsigned long
+ default_frame_delay,
+ final_delay,
+ final_image_delay,
+ frame_delay,
+#ifdef MNG_INSERT_LAYERS
+ insert_layers,
+#endif
+ mng_iterations=1,
+ simplicity=0,
+ subframe_height=0,
+ subframe_width=0;
+ previous_fb.top=0;
+ previous_fb.bottom=0;
+ previous_fb.left=0;
+ previous_fb.right=0;
+ default_fb.top=0;
+ default_fb.bottom=0;
+ default_fb.left=0;
+ default_fb.right=0;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
+ image=AllocateImage(image_info);
+ mng_info=(MngInfo *) NULL;
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFalse)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ first_mng_object=MagickFalse;
+ skipping_loop=(-1);
+ have_mng_structure=MagickFalse;
+ /*
+ Allocate a MngInfo structure.
+ */
+ mng_info=MagickAllocateMemory(MngInfo *,sizeof(MngInfo));
+ if (mng_info == (MngInfo *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize members of the MngInfo structure.
+ */
+ (void) memset(mng_info,0,sizeof(MngInfo));
+ mng_info->image=image;
+ have_mng_structure=MagickTrue;
+
+ if (LocaleCompare(image_info->magick,"MNG") == 0)
+ {
+ char
+ magic_number[MaxTextExtent];
+
+ /*
+ Verify MNG signature.
+ */
+ (void) ReadBlob(image,8,magic_number);
+ if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
+ {
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ /*
+ Initialize some nonzero members of the MngInfo structure.
+ */
+ for (i=0; i < MNG_MAX_OBJECTS; i++)
+ {
+ mng_info->object_clip[i].right=PNG_MAX_UINT;
+ mng_info->object_clip[i].bottom=PNG_MAX_UINT;
+ }
+ mng_info->exists[0]=MagickTrue;
+ }
+ first_mng_object=MagickTrue;
+ mng_type=0;
+#ifdef MNG_INSERT_LAYERS
+ insert_layers=MagickFalse; /* should be False if converting or mogrifying */
+#endif
+ default_frame_delay=0;
+ default_frame_timeout=0;
+ frame_delay=0;
+ final_delay=1;
+ mng_info->ticks_per_second=100;
+ object_id=0;
+ skip_to_iend=MagickFalse;
+ term_chunk_found=MagickFalse;
+ mng_info->framing_mode=1;
+#ifdef MNG_INSERT_LAYERS
+ mandatory_back=MagickFalse;
+#endif
+#ifdef MNG_INSERT_LAYERS
+ mng_background_color=image->background_color;
+#endif
+ do
+ {
+ char
+ type[MaxTextExtent];
+
+ if (LocaleCompare(image_info->magick,"MNG") == 0)
+ {
+ register unsigned char
+ *p;
+
+ unsigned char
+ *chunk;
+
+ /*
+ Read a new chunk.
+ */
+ type[0]='\0';
+ (void) strcat(type,"errr");
+ length=ReadBlobMSBLong(image);
+ count=ReadBlob(image,4,type);
+ if (count < 4)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading MNG chunk, count: %"
+ MAGICK_SIZE_T_F "u",
+ (MAGICK_SIZE_T) count);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading MNG chunk type %c%c%c%c,"
+ " length: %lu",
+ type[0],type[1],type[2],type[3],length);
+
+ if (length > PNG_MAX_UINT)
+ status=MagickFalse;
+ p=NULL;
+ chunk=(unsigned char *) NULL;
+ if (length)
+ {
+ chunk=MagickAllocateMemory(unsigned char *,length);
+ if (chunk == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if (ReadBlob(image,length,chunk) < length)
+ {
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+ p=chunk;
+ }
+ (void) ReadBlobMSBLong(image); /* read crc word */
+
+#if !defined(JNG_SUPPORTED)
+ if (!memcmp(type,mng_JHDR,4))
+ {
+ skip_to_iend=MagickTrue;
+ if (!mng_info->jhdr_warning)
+ (void) ThrowException(&image->exception,CoderError,
+ JNGCompressionNotSupported,
+ image->filename);
+ mng_info->jhdr_warning++;
+ }
+#endif
+ if (!memcmp(type,mng_DHDR,4))
+ {
+ skip_to_iend=MagickTrue;
+ if (!mng_info->dhdr_warning)
+ (void) ThrowException(&image->exception,CoderError,
+ DeltaPNGNotSupported,image->filename);
+ mng_info->dhdr_warning++;
+ }
+ if (!memcmp(type,mng_MEND,4))
+ break;
+ if (skip_to_iend)
+ {
+ if (!memcmp(type,mng_IEND,4))
+ skip_to_iend=MagickFalse;
+ if (length)
+ MagickFreeMemory(chunk);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Skip to IEND.");
+ continue;
+ }
+ if (!memcmp(type,mng_MHDR,4))
+ {
+ if (length < 16)
+ {
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ /* To quiet a Coverity complaint */
+ LockSemaphoreInfo(png_semaphore);
+#endif
+ mng_info->mng_width=(unsigned long) ((p[0] << 24) |
+ (p[1] << 16) |
+ (p[2] << 8) | p[3]);
+ mng_info->mng_height=(unsigned long) ((p[4] << 24) |
+ (p[5] << 16) |
+ (p[6] << 8) | p[7]);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MNG width: %lu",
+ mng_info->mng_width);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MNG height: %lu",
+ mng_info->mng_height);
+ }
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ if ((long) mng_info->mng_width >
+ GetMagickResourceLimit(WidthResource) ||
+ (long) mng_info->mng_height >
+ GetMagickResourceLimit(HeightResource))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MNG width or height too large: %lu, %lu",
+ mng_info->mng_width,mng_info->mng_height);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,
+ image);
+ }
+
+ p+=8;
+ mng_info->ticks_per_second=mng_get_long(p);
+ if (mng_info->ticks_per_second == 0)
+ default_frame_delay=0;
+ else
+ default_frame_delay=100/mng_info->ticks_per_second;
+ frame_delay=default_frame_delay;
+ simplicity=0;
+ if (length >= 28)
+ {
+ p+=16;
+ simplicity=mng_get_long(p);
+ }
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " MNG simplicity: %lx",simplicity);
+ }
+ mng_type=1; /* Full MNG */
+ if ((simplicity != 0) && ((simplicity | 11) == 11))
+ mng_type=2; /* LC */
+ if ((simplicity != 0) && ((simplicity | 9) == 9))
+ mng_type=3; /* VLC */
+#ifdef MNG_INSERT_LAYERS
+ if (mng_type != 3 && !image_info->ping)
+ insert_layers=MagickTrue;
+#endif
+ if (AccessMutablePixels(image) != (PixelPacket *) NULL)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ return((Image *) NULL);
+ image=SyncNextImageInList(image);
+ mng_info->image=image;
+ }
+
+ if ((mng_info->mng_width > 65535L) || (mng_info->mng_height
+ > 65535L))
+ (void) ThrowException(&image->exception,ImageError,
+ WidthOrHeightExceedsLimit,
+ image->filename);
+ FormatString(page_geometry,"%lux%lu+0+0",mng_info->mng_width,
+ mng_info->mng_height);
+ mng_info->frame.left=0;
+ mng_info->frame.right=(long) mng_info->mng_width;
+ mng_info->frame.top=0;
+ mng_info->frame.bottom=(long) mng_info->mng_height;
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ /* To quiet a Coverity complaint */
+ LockSemaphoreInfo(png_semaphore);
+#endif
+ mng_info->clip=default_fb=previous_fb=mng_info->frame;
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ for (i=0; i < MNG_MAX_OBJECTS; i++)
+ mng_info->object_clip[i]=mng_info->frame;
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_TERM,4))
+ {
+ int
+ repeat=0;
+
+ if (length)
+ repeat=p[0];
+ if (repeat == 3 && length > 8)
+ {
+ final_delay=(png_uint_32) mng_get_long(&p[2]);
+ mng_iterations=(png_uint_32) mng_get_long(&p[6]);
+ if (mng_iterations == PNG_MAX_UINT)
+ mng_iterations=0;
+ image->iterations=mng_iterations;
+ term_chunk_found=MagickTrue;
+ }
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " repeat=%d",repeat);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " final_delay=%ld",final_delay);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image->iterations=%ld",
+ image->iterations);
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_DEFI,4))
+ {
+ if (mng_type == 3)
+ (void) ThrowException2(&image->exception,CoderError,
+ "DEFI chunk found in MNG-VLC"
+ " datastream",
+ (char *) NULL);
+ object_id=(p[0] << 8) | p[1];
+ if (mng_type == 2 && object_id != 0)
+ (void) ThrowException2(&image->exception,CoderError,
+ "Nonzero object_id in MNG-LC"
+ " datastream",
+ (char *) NULL);
+ if (object_id > MNG_MAX_OBJECTS)
+ {
+ /*
+ Instead of issuing a warning we should allocate a larger
+ MngInfo structure and continue.
+ */
+ (void) ThrowException2(&image->exception,CoderError,
+ "object id too large",(char *) NULL);
+ object_id=MNG_MAX_OBJECTS;
+ }
+ if (mng_info->exists[object_id])
+ if (mng_info->frozen[object_id])
+ {
+ MagickFreeMemory(chunk);
+ (void) ThrowException2(&image->exception,CoderError,
+ "DEFI cannot redefine a frozen"
+ " MNG object",
+ (char *) NULL);
+ continue;
+ }
+ mng_info->exists[object_id]=MagickTrue;
+ if (length > 2)
+ mng_info->invisible[object_id]=p[2];
+ /*
+ Extract object offset info.
+ */
+ if (length > 11)
+ {
+ mng_info->x_off[object_id]=(long) ((p[4] << 24) |
+ (p[5] << 16) |
+ (p[6] << 8) | p[7]);
+ mng_info->y_off[object_id]=(long) ((p[8] << 24) |
+ (p[9] << 16) |
+ (p[10] << 8) | p[11]);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " x_off[%d]: %lu",object_id,
+ mng_info->x_off[object_id]);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " y_off[%d]: %lu",object_id,
+ mng_info->y_off[object_id]);
+ }
+ }
+ /*
+ Extract object clipping info.
+ */
+ if (length > 27)
+ mng_info->object_clip[object_id]
+ =mng_read_box( mng_info->frame,0,&p[12]);
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_bKGD,4))
+ {
+ mng_info->have_global_bkgd=MagickFalse;
+ if (length > 5)
+ {
+ mng_info->mng_global_bkgd.red
+ =ScaleShortToQuantum(((p[0] << 8) | p[1]));
+ mng_info->mng_global_bkgd.green
+ =ScaleShortToQuantum(((p[2] << 8) | p[3]));
+ mng_info->mng_global_bkgd.blue
+ =ScaleShortToQuantum(((p[4] << 8) | p[5]));
+ mng_info->have_global_bkgd=MagickTrue;
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_BACK,4))
+ {
+#ifdef MNG_INSERT_LAYERS
+ if (length > 6)
+ mandatory_back=p[6];
+ else
+ mandatory_back=0;
+ if (mandatory_back && length > 5)
+ {
+ mng_background_color.red=
+ ScaleShortToQuantum(((p[0] << 8) | p[1]));
+ mng_background_color.green=
+ ScaleShortToQuantum(((p[2] << 8) | p[3]));
+ mng_background_color.blue=
+ ScaleShortToQuantum(((p[4] << 8) | p[5]));
+ mng_background_color.opacity=OpaqueOpacity;
+ }
+#ifdef MNG_OBJECT_BUFFERS
+ if (length > 8)
+ mng_background_object=(p[7] << 8) | p[8];
+#endif
+#endif
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_PLTE,4))
+ {
+ /*
+ Read global PLTE.
+ */
+ if (length && (length < 769))
+ {
+ if (mng_info->global_plte == (png_colorp) NULL)
+ mng_info->global_plte=
+ MagickAllocateMemory(png_colorp,256*sizeof(png_color));
+ for (i=0; i < (long) (length/3); i++)
+ {
+ mng_info->global_plte[i].red=p[3*i];
+ mng_info->global_plte[i].green=p[3*i+1];
+ mng_info->global_plte[i].blue=p[3*i+2];
+ }
+ mng_info->global_plte_length=length/3;
+ }
+#ifdef MNG_LOOSE
+ for ( ; i < 256; i++)
+ {
+ mng_info->global_plte[i].red=i;
+ mng_info->global_plte[i].green=i;
+ mng_info->global_plte[i].blue=i;
+ }
+ if (length)
+ mng_info->global_plte_length=256;
+#endif
+ else
+ mng_info->global_plte_length=0;
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_tRNS,4))
+ {
+ /* read global tRNS */
+
+ if (length < 257)
+ for (i=0; i < (long) length; i++)
+ mng_info->global_trns[i]=p[i];
+
+#ifdef MNG_LOOSE
+ for ( ; i < 256; i++)
+ mng_info->global_trns[i]=255;
+#endif
+ mng_info->global_trns_length=length;
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_gAMA,4))
+ {
+ if (length == 4)
+ {
+ long
+ igamma;
+
+ igamma=mng_get_long(p);
+ mng_info->global_gamma=((float) igamma)*0.00001;
+ mng_info->have_global_gama=MagickTrue;
+ }
+ else
+ mng_info->have_global_gama=MagickFalse;
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_cHRM,4))
+ {
+ /*
+ Read global cHRM
+ */
+ if (length == 32)
+ {
+ mng_info->global_chrm.white_point.x=0.00001*
+ mng_get_long(p);
+ mng_info->global_chrm.white_point.y=0.00001*
+ mng_get_long(&p[4]);
+ mng_info->global_chrm.red_primary.x=0.00001*
+ mng_get_long(&p[8]);
+ mng_info->global_chrm.red_primary.y=0.00001*
+ mng_get_long(&p[12]);
+ mng_info->global_chrm.green_primary.x=0.00001*
+ mng_get_long(&p[16]);
+ mng_info->global_chrm.green_primary.y=0.00001*
+ mng_get_long(&p[20]);
+ mng_info->global_chrm.blue_primary.x=0.00001*
+ mng_get_long(&p[24]);
+ mng_info->global_chrm.blue_primary.y=0.00001*
+ mng_get_long(&p[28]);
+ mng_info->have_global_chrm=MagickTrue;
+ }
+ else
+ mng_info->have_global_chrm=MagickFalse;
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_sRGB,4))
+ {
+ /*
+ Read global sRGB.
+ */
+ if (length)
+ {
+ mng_info->global_srgb_intent=(RenderingIntent) (p[0]+1);
+ mng_info->have_global_srgb=MagickTrue;
+ }
+ else
+ mng_info->have_global_srgb=MagickFalse;
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_iCCP,4))
+ {
+ /* To do. */
+
+ /*
+ Read global iCCP.
+ */
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_FRAM,4))
+ {
+ if (mng_type == 3)
+ (void) ThrowException2(&image->exception,CoderError,
+ "FRAM chunk found in MNG-VLC"
+ " datastream",
+ (char *) NULL);
+ if ((mng_info->framing_mode == 2) ||
+ (mng_info->framing_mode == 4))
+ image->delay=frame_delay;
+ frame_delay=default_frame_delay;
+ frame_timeout=default_frame_timeout;
+ fb=default_fb;
+ if (length)
+ if (p[0])
+ mng_info->framing_mode=p[0];
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Framing_mode=%d",
+ mng_info->framing_mode);
+ if (length > 6)
+ {
+ /*
+ Note the delay and frame clipping boundaries.
+ */
+ p++; /* framing mode */
+ while (*p && ((p-chunk) < (long) length))
+ p++; /* frame name */
+ p++; /* frame name terminator */
+ if ((p-chunk) < (long) (length-4))
+ {
+ int
+ change_delay,
+ change_timeout,
+ change_clipping;
+
+ change_delay=(*p++);
+ change_timeout=(*p++);
+ change_clipping=(*p++);
+ p++; /* change_sync */
+ if (change_delay && (p-chunk) < (ssize_t) (length-4))
+ {
+ frame_delay=(100*(mng_get_long(p))/
+ mng_info->ticks_per_second);
+ if (change_delay == 2)
+ default_frame_delay=frame_delay;
+ p+=4;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Framing_delay=%ld",
+ frame_delay);
+ }
+ if (change_timeout && (p-chunk) < (ssize_t) (length-4))
+ {
+ frame_timeout=
+ (100*(mng_get_long(p))/mng_info->ticks_per_second);
+ if (change_timeout == 2)
+ default_frame_timeout=frame_timeout;
+ p+=4;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Framing_timeout=%ld",
+ frame_timeout);
+ }
+ if (change_clipping && (p-chunk) < (ssize_t) (length-17))
+ {
+ fb=mng_read_box(previous_fb,p[0],&p[1]);
+ p+=17;
+ previous_fb=fb;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Frame_clipping:"
+ " L=%ld R=%ld T=%ld B=%ld",
+ fb.left, fb.right,fb.top,
+ fb.bottom);
+ if (change_clipping == 2)
+ default_fb=fb;
+ }
+ }
+ }
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ /* To quiet a Coverity complaint */
+ LockSemaphoreInfo(png_semaphore);
+#endif
+ mng_info->clip=fb;
+ mng_info->clip=mng_minimum_box(fb,mng_info->frame);
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ subframe_width=(mng_info->clip.right-mng_info->clip.left);
+ subframe_height=(mng_info->clip.bottom-mng_info->clip.top);
+ /*
+ Insert a background layer behind the frame
+ if framing_mode is 4.
+ */
+#ifdef MNG_INSERT_LAYERS
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " subframe_width=%lu,"
+ " subframe_height=%lu",
+ subframe_width, subframe_height);
+ if (insert_layers && (mng_info->framing_mode == 4) &&
+ (subframe_width) && (subframe_height))
+ {
+ /*
+ Allocate next image structure.
+ */
+ if (AccessMutablePixels(image) != (PixelPacket *) NULL)
+ {
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ }
+ mng_info->image=image;
+ if (term_chunk_found)
+ {
+ image->start_loop=MagickTrue;
+ image->iterations=mng_iterations;
+ term_chunk_found=MagickFalse;
+ }
+ else
+ image->start_loop=MagickFalse;
+ image->columns=subframe_width;
+ image->rows=subframe_height;
+ image->page.width=subframe_width;
+ image->page.height=subframe_height;
+ image->page.x=mng_info->clip.left;
+ image->page.y=mng_info->clip.top;
+ image->background_color=mng_background_color;
+ image->matte=MagickFalse;
+ image->delay=0;
+ (void) SetImage(image,OpaqueOpacity);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Inserted background layer,"
+ " L=%ld, R=%ld, T=%ld, B=%ld",
+ mng_info->clip.left,
+ mng_info->clip.right,
+ mng_info->clip.top,
+ mng_info->clip.bottom);
+ }
+#endif
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_CLIP,4))
+ {
+ unsigned int
+ first_object,
+ last_object;
+
+ /*
+ Read CLIP.
+ */
+ if (length > 3)
+ {
+ first_object=(p[0] << 8) | p[1];
+ last_object=(p[2] << 8) | p[3];
+ p+=4;
+
+ for (i=(int) first_object; i <= (int) last_object; i++)
+ {
+ if (mng_info->exists[i] && !mng_info->frozen[i])
+ {
+ MngBox
+ box;
+
+ box=mng_info->object_clip[i];
+ if ((p-chunk) < (ssize_t) (length-17))
+ mng_info->object_clip[i]=
+ mng_read_box(box,p[0],&p[1]);
+ }
+ }
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_SAVE,4))
+ {
+ for (i=1; i < MNG_MAX_OBJECTS; i++)
+ if (mng_info->exists[i])
+ {
+ mng_info->frozen[i]=MagickTrue;
+#ifdef MNG_OBJECT_BUFFERS
+ if (mng_info->ob[i] != (MngBuffer *) NULL)
+ mng_info->ob[i]->frozen=MagickTrue;
+#endif
+ }
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_DISC,4) || !memcmp(type,mng_SEEK,4))
+ {
+ /*
+ Read DISC or SEEK.
+ */
+ if ((length == 0) || !memcmp(type,mng_SEEK,4))
+ {
+ for (i=1; i < MNG_MAX_OBJECTS; i++)
+ MngInfoDiscardObject(mng_info,i);
+ }
+ else
+ {
+ register long
+ j;
+
+ for (j=0; j < (long) length; j+=2)
+ {
+ i=p[j] << 8 | p[j+1];
+ MngInfoDiscardObject(mng_info,i);
+ }
+ }
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_MOVE,4))
+ {
+ unsigned long
+ first_object,
+ last_object;
+
+ /*
+ read MOVE
+ */
+
+ if (length > 3)
+ {
+ first_object=(p[0] << 8) | p[1];
+ last_object=(p[2] << 8) | p[3];
+ p+=4;
+
+ for (i=(long) first_object; i <= (long) last_object; i++)
+ {
+ if (mng_info->exists[i] && !mng_info->frozen[i] &&
+ (p-chunk) < (ssize_t) (length-8))
+ {
+ MngPair
+ new_pair;
+
+ MngPair
+ old_pair;
+
+ old_pair.a=mng_info->x_off[i];
+ old_pair.b=mng_info->y_off[i];
+ new_pair=mng_read_pair(old_pair,(int) p[0],&p[1]);
+ mng_info->x_off[i]=new_pair.a;
+ mng_info->y_off[i]=new_pair.b;
+ }
+ }
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+
+ if (!memcmp(type,mng_LOOP,4))
+ {
+ long loop_iters=1;
+
+ if (length > 0) /* To do: check spec, if empty LOOP is allowed */
+ {
+ loop_level=chunk[0];
+ loops_active++;
+ mng_info->loop_active[loop_level]=1; /* mark loop active */
+ /*
+ Record starting point.
+ */
+ loop_iters=mng_get_long(&chunk[1]);
+ if (loop_iters == 0)
+ skipping_loop=loop_level;
+ else
+ {
+ mng_info->loop_jump[loop_level]=TellBlob(image);
+ mng_info->loop_count[loop_level]=loop_iters;
+ }
+ mng_info->loop_iteration[loop_level]=0;
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_ENDL,4))
+ {
+ loop_level=chunk[0];
+ if (skipping_loop > 0)
+ {
+ if (skipping_loop == loop_level)
+ {
+ /*
+ Found end of zero-iteration loop.
+ */
+ skipping_loop=(-1);
+ loops_active--;
+ mng_info->loop_active[loop_level]=0;
+ }
+ }
+ else
+ {
+ if (mng_info->loop_active[loop_level] == 1)
+ {
+ mng_info->loop_count[loop_level]--;
+ mng_info->loop_iteration[loop_level]++;
+ if (mng_info->loop_count[loop_level] != 0)
+ (void) SeekBlob(image,mng_info->loop_jump[loop_level],
+ SEEK_SET);
+ else
+ {
+ short
+ last_level;
+
+ /*
+ Finished loop.
+ */
+ loops_active--;
+ mng_info->loop_active[loop_level]=0;
+ last_level=(-1);
+ for (i=0; i < loop_level; i++)
+ if (mng_info->loop_active[i] == 1)
+ last_level=(short) i;
+ loop_level=last_level;
+ }
+ }
+ }
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (!memcmp(type,mng_CLON,4))
+ {
+ if (!mng_info->clon_warning)
+ (void) ThrowException2(&image->exception,CoderError,
+ "CLON is not implemented yet",
+ image->filename);
+ mng_info->clon_warning++;
+ }
+ if (!memcmp(type,mng_MAGN,4))
+ {
+ png_uint_16
+ magn_first,
+ magn_last,
+ magn_mb,
+ magn_ml,
+ magn_mr,
+ magn_mt,
+ magn_mx,
+ magn_my,
+ magn_methx,
+ magn_methy;
+
+ if (length > 1)
+ magn_first=(p[0] << 8) | p[1];
+ else
+ magn_first=0;
+ if (length > 3)
+ magn_last=(p[2] << 8) | p[3];
+ else
+ magn_last=magn_first;
+#ifndef MNG_OBJECT_BUFFERS
+ if (magn_first || magn_last)
+ if (!mng_info->magn_warning)
+ {
+ (void) ThrowException2(&image->exception,CoderError,
+ "MAGN is not implemented yet"
+ " for nonzero objects",
+ image->filename);
+ mng_info->magn_warning++;
+ }
+#endif
+ if (length > 4)
+ magn_methx=p[4];
+ else
+ magn_methx=0;
+
+ if (length > 6)
+ magn_mx=(p[5] << 8) | p[6];
+ else
+ magn_mx=1;
+ if (magn_mx == 0)
+ magn_mx=1;
+
+ if (length > 8)
+ magn_my=(p[7] << 8) | p[8];
+ else
+ magn_my=magn_mx;
+ if (magn_my == 0)
+ magn_my=1;
+
+ if (length > 10)
+ magn_ml=(p[9] << 8) | p[10];
+ else
+ magn_ml=magn_mx;
+ if (magn_ml == 0)
+ magn_ml=1;
+
+ if (length > 12)
+ magn_mr=(p[11] << 8) | p[12];
+ else
+ magn_mr=magn_mx;
+ if (magn_mr == 0)
+ magn_mr=1;
+
+ if (length > 14)
+ magn_mt=(p[13] << 8) | p[14];
+ else
+ magn_mt=magn_my;
+ if (magn_mt == 0)
+ magn_mt=1;
+
+ if (length > 16)
+ magn_mb=(p[15] << 8) | p[16];
+ else
+ magn_mb=magn_my;
+ if (magn_mb == 0)
+ magn_mb=1;
+
+ if (length > 17)
+ magn_methy=p[17];
+ else
+ magn_methy=magn_methx;
+
+ if (magn_methx > 5 || magn_methy > 5)
+ if (!mng_info->magn_warning)
+ {
+ (void) ThrowException2(&image->exception,CoderError,
+ "Unknown MAGN method in"
+ " MNG datastream",
+ image->filename);
+ mng_info->magn_warning++;
+ }
+#ifdef MNG_OBJECT_BUFFERS
+ /* Magnify existing objects in the range magn_first
+ to magn_last */
+#endif
+ if (magn_first == 0 || magn_last == 0)
+ {
+ /* Save the magnification factors for object 0 */
+ mng_info->magn_mb=magn_mb;
+ mng_info->magn_ml=magn_ml;
+ mng_info->magn_mr=magn_mr;
+ mng_info->magn_mt=magn_mt;
+ mng_info->magn_mx=magn_mx;
+ mng_info->magn_my=magn_my;
+ mng_info->magn_methx=magn_methx;
+ mng_info->magn_methy=magn_methy;
+ }
+ }
+ if (!memcmp(type,mng_PAST,4))
+ {
+ if (!mng_info->past_warning)
+ (void) ThrowException2(&image->exception,CoderError,
+ "PAST is not implemented yet",
+ image->filename);
+ mng_info->past_warning++;
+ }
+ if (!memcmp(type,mng_SHOW,4))
+ {
+ if (!mng_info->show_warning)
+ (void) ThrowException2(&image->exception,CoderError,
+ "SHOW is not implemented yet",
+ image->filename);
+ mng_info->show_warning++;
+ }
+ if (!memcmp(type,mng_sBIT,4))
+ {
+ if (length < 4)
+ mng_info->have_global_sbit=MagickFalse;
+ else
+ {
+ mng_info->global_sbit.gray=p[0];
+ mng_info->global_sbit.red=p[0];
+ mng_info->global_sbit.green=p[1];
+ mng_info->global_sbit.blue=p[2];
+ mng_info->global_sbit.alpha=p[3];
+ mng_info->have_global_sbit=MagickTrue;
+ }
+ }
+ if (!memcmp(type,mng_pHYs,4))
+ {
+ if (length > 8)
+ {
+ mng_info->global_x_pixels_per_unit=mng_get_long(p);
+ mng_info->global_y_pixels_per_unit=mng_get_long(&p[4]);
+ mng_info->global_phys_unit_type=p[8];
+ mng_info->have_global_phys=MagickTrue;
+ }
+ else
+ mng_info->have_global_phys=MagickFalse;
+ }
+ if (!memcmp(type,mng_pHYg,4))
+ {
+ if (!mng_info->phyg_warning)
+ (void) ThrowException2(&image->exception,CoderError,
+ "pHYg is not implemented.",
+ image->filename);
+ mng_info->phyg_warning++;
+ }
+ if (!memcmp(type,mng_BASI,4))
+ {
+ skip_to_iend=MagickTrue;
+ if (!mng_info->basi_warning)
+ (void) ThrowException2(&image->exception,CoderError,
+ "BASI is not implemented yet",
+ image->filename);
+ mng_info->basi_warning++;
+#ifdef MNG_BASI_SUPPORTED
+ basi_width=(unsigned long) ((p[0] << 24) | (p[1] << 16) |
+ (p[2] << 8) | p[3]);
+ basi_height=(unsigned long) ((p[4] << 24) | (p[5] << 16) |
+ (p[6] << 8) | p[7]);
+ basi_color_type=p[8];
+ basi_compression_method=p[9];
+ basi_filter_type=p[10];
+ basi_interlace_method=p[11];
+ if (length > 11)
+ basi_red=(p[12] << 8) & p[13];
+ else
+ basi_red=0;
+ if (length > 13)
+ basi_green=(p[14] << 8) & p[15];
+ else
+ basi_green=0;
+ if (length > 15)
+ basi_blue=(p[16] << 8) & p[17];
+ else
+ basi_blue=0;
+ if (length > 17)
+ basi_alpha=(p[18] << 8) & p[19];
+ else
+ {
+ if (basi_sample_depth == 16)
+ basi_alpha=65535L;
+ else
+ basi_alpha=255;
+ }
+ if (length > 19)
+ basi_viewable=p[20];
+ else
+ basi_viewable=0;
+#endif
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ if (memcmp(type,mng_IHDR,4)
+#if defined(JNG_SUPPORTED)
+ && memcmp(type,mng_JHDR,4)
+#endif
+ )
+ {
+ /* Not an IHDR or JHDR chunk */
+ if (length)
+ MagickFreeMemory(chunk);
+ continue;
+ }
+ /* Process IHDR */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Processing %c%c%c%c chunk",
+ type[0],type[1],type[2],type[3]);
+ mng_info->exists[object_id]=MagickTrue;
+ mng_info->viewable[object_id]=MagickTrue;
+ if (mng_info->invisible[object_id])
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Skipping invisible object");
+ skip_to_iend=MagickTrue;
+ MagickFreeMemory(chunk);
+ continue;
+ }
+#ifdef MNG_INSERT_LAYERS
+ if (length < 8)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ image_width=mng_get_long(p);
+ image_height=mng_get_long(&p[4]);
+#endif
+ MagickFreeMemory(chunk);
+
+ /*
+ Insert a transparent background layer behind the entire animation
+ if it is not full screen.
+ */
+#ifdef MNG_INSERT_LAYERS
+ if (insert_layers && mng_type && first_mng_object)
+ {
+ if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
+ (image_width < mng_info->mng_width) ||
+ (mng_info->clip.right < (long) mng_info->mng_width) ||
+ (image_height < mng_info->mng_height) ||
+ (mng_info->clip.bottom < (long) mng_info->mng_height))
+ {
+ if (AccessMutablePixels(image) != (PixelPacket *) NULL)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ }
+ mng_info->image=image;
+ if (term_chunk_found)
+ {
+ image->start_loop=MagickTrue;
+ image->iterations=mng_iterations;
+ term_chunk_found=MagickFalse;
+ }
+ else
+ image->start_loop=MagickFalse;
+ /*
+ Make a background rectangle.
+ */
+ image->delay=0;
+ image->columns=mng_info->mng_width;
+ image->rows=mng_info->mng_height;
+ image->page.width=mng_info->mng_width;
+ image->page.height=mng_info->mng_height;
+ image->page.x=0;
+ image->page.y=0;
+ image->background_color=mng_background_color;
+ (void) SetImage(image,TransparentOpacity);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Inserted transparent background"
+ " layer, W=%lud, H=%lud",
+ mng_info->mng_width,
+ mng_info->mng_height);
+ }
+ }
+ /*
+ Insert a background layer behind the upcoming image if
+ framing_mode is 3, and we haven't already inserted one.
+ */
+ if (insert_layers && (mng_info->framing_mode == 3) &&
+ (subframe_width) && (subframe_height) && (simplicity == 0 ||
+ (simplicity & 0x08)))
+ {
+ if (AccessMutablePixels(image) != (PixelPacket *) NULL)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ }
+ mng_info->image=image;
+ if (term_chunk_found)
+ {
+ image->start_loop=MagickTrue;
+ image->iterations=mng_iterations;
+ term_chunk_found=MagickFalse;
+ }
+ else
+ image->start_loop=MagickFalse;
+ image->delay=0;
+ image->columns=subframe_width;
+ image->rows=subframe_height;
+ image->page.width=subframe_width;
+ image->page.height=subframe_height;
+ image->page.x=mng_info->clip.left;
+ image->page.y=mng_info->clip.top;
+ image->background_color=mng_background_color;
+ image->matte=MagickFalse;
+ (void) SetImage(image,OpaqueOpacity);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Inserted background layer,"
+ " L=%ld, R=%ld, T=%ld, B=%ld",
+ mng_info->clip.left,
+ mng_info->clip.right,
+ mng_info->clip.top,
+ mng_info->clip.bottom);
+ }
+#endif /* MNG_INSERT_LAYERS */
+ first_mng_object=MagickFalse;
+ if (AccessMutablePixels(image) != (PixelPacket *) NULL)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ }
+ mng_info->image=image;
+ if (QuantumTick(TellBlob(image),GetBlobSize(image)))
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesTag,
+ image->filename))
+ break;
+ if (term_chunk_found)
+ {
+ image->start_loop=MagickTrue;
+ term_chunk_found=MagickFalse;
+ }
+ else
+ image->start_loop=MagickFalse;
+ if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
+ {
+ image->delay=frame_delay;
+ frame_delay=default_frame_delay;
+ }
+ else
+ image->delay=0;
+ image->page.width=mng_info->mng_width;
+ image->page.height=mng_info->mng_height;
+ image->page.x=mng_info->x_off[object_id];
+ image->page.y=mng_info->y_off[object_id];
+ image->iterations=mng_iterations;
+ /*
+ Seek back to the beginning of the IHDR or JHDR chunk's
+ length field.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Seeking back to beginning of"
+ " %c%c%c%c chunk",
+ type[0],type[1],
+ type[2],type[3]);
+ (void) SeekBlob(image,-((long) length+12),SEEK_CUR);
+ }
+
+ previous=image;
+ mng_info->image=image;
+ mng_info->mng_type=mng_type;
+ mng_info->object_id=object_id;
+
+ if (!memcmp(type,mng_IHDR,4))
+ image=ReadOnePNGImage(mng_info,image_info,exception);
+#if defined(JNG_SUPPORTED)
+ else
+ image=ReadOneJNGImage(mng_info,image_info,exception);
+#endif
+
+ if (image == (Image *) NULL)
+ {
+ DestroyImageList(previous);
+ CloseBlob(previous);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ return((Image *) NULL);
+ }
+ if (image->columns == 0 || image->rows == 0)
+ {
+ CloseBlob(image);
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ return((Image *) NULL);
+ }
+ mng_info->image=image;
+
+ if (mng_type)
+ {
+ MngBox
+ crop_box;
+
+ if (mng_info->magn_methx || mng_info->magn_methy)
+ {
+ png_uint_32
+ magnified_height,
+ magnified_width;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Processing MNG MAGN chunk");
+
+ if (mng_info->magn_methx == 1)
+ {
+ magnified_width=mng_info->magn_ml;
+ if (image->columns > 1)
+ magnified_width += mng_info->magn_mr;
+ if (image->columns > 2)
+ magnified_width += (image->columns-2)*(mng_info->magn_mx);
+ }
+ else
+ {
+ magnified_width=image->columns;
+ if (image->columns > 1)
+ magnified_width += mng_info->magn_ml-1;
+ if (image->columns > 2)
+ magnified_width += mng_info->magn_mr-1;
+ if (image->columns > 3)
+ magnified_width += (image->columns-3)*
+ (mng_info->magn_mx-1);
+ }
+ if (mng_info->magn_methy == 1)
+ {
+ magnified_height=mng_info->magn_mt;
+ if (image->rows > 1)
+ magnified_height += mng_info->magn_mb;
+ if (image->rows > 2)
+ magnified_height += (image->rows-2)*(mng_info->magn_my);
+ }
+ else
+ {
+ magnified_height=image->rows;
+ if (image->rows > 1)
+ magnified_height += mng_info->magn_mt-1;
+ if (image->rows > 2)
+ magnified_height += mng_info->magn_mb-1;
+ if (image->rows > 3)
+ magnified_height += (image->rows-3)*(mng_info->magn_my-1);
+ }
+ if (magnified_height > image->rows ||
+ magnified_width > image->columns)
+ {
+ Image
+ *large_image;
+
+ int
+ yy;
+
+ long
+ m,
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *n,
+ *p,
+ *q;
+
+ PixelPacket
+ *next,
+ *prev;
+
+ size_t
+ row_length;
+
+ png_uint_16
+ magn_methx,
+ magn_methy;
+
+ /*
+ Allocate next image structure.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Allocate magnified image");
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ return((Image *) NULL);
+ }
+
+ large_image=SyncNextImageInList(image);
+
+ large_image->columns=magnified_width;
+ large_image->rows=magnified_height;
+
+ magn_methx=mng_info->magn_methx;
+ magn_methy=mng_info->magn_methy;
+
+#if (QuantumDepth == 32)
+#define QM unsigned short
+ if (magn_methx != 1 || magn_methy != 1)
+ {
+ /*
+ Scale pixels to unsigned shorts to prevent
+ overflow of intermediate values of interpolations
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if(q == (PixelPacket *) NULL)
+ break;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ q->red=ScaleQuantumToShort(q->red);
+ q->green=ScaleQuantumToShort(q->green);
+ q->blue=ScaleQuantumToShort(q->blue);
+ q->opacity=ScaleQuantumToShort(q->opacity);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+#else
+#define QM Quantum
+#endif
+
+ if (image->matte)
+ (void) SetImage(large_image,TransparentOpacity);
+ else
+ {
+ large_image->background_color.opacity=OpaqueOpacity;
+ (void) SetImage(large_image,OpaqueOpacity);
+ if (magn_methx == 4)
+ magn_methx=2;
+ if (magn_methx == 5)
+ magn_methx=3;
+ if (magn_methy == 4)
+ magn_methy=2;
+ if (magn_methy == 5)
+ magn_methy=3;
+ }
+
+ /* magnify the rows into the right side of the large image */
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Magnify the rows to %lu",
+ large_image->rows);
+ m=mng_info->magn_mt;
+ yy=0;
+ row_length=(size_t) (image->columns*sizeof(PixelPacket));
+ next=MagickAllocateMemory(PixelPacket *,row_length);
+ prev=MagickAllocateMemory(PixelPacket *,row_length);
+ if ((prev == (PixelPacket *) NULL) ||
+ (next == (PixelPacket *) NULL))
+ {
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ ThrowReaderException(ResourceLimitError,
+ MemoryAllocationFailed,image)
+ }
+ n=GetImagePixels(image,0,0,image->columns,1);
+ if(n == (PixelPacket *) NULL)
+ return ((Image *) NULL);
+ (void) memcpy(next,n,row_length);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (y == 0)
+ m=mng_info->magn_mt;
+ else if (magn_methy > 1 && y == (long) image->rows-2)
+ m=mng_info->magn_mb;
+ else if (magn_methy <= 1 && y == (long) image->rows-1)
+ m=mng_info->magn_mb;
+ else if (magn_methy > 1 && y == (long) image->rows-1)
+ m=1;
+ else
+ m=mng_info->magn_my;
+ n=prev;
+ prev=next;
+ next=n;
+ if (y < (long) image->rows-1)
+ {
+ n=GetImagePixels(image,0,y+1,image->columns,1);
+ if(n == (PixelPacket *) NULL)
+ break;
+ (void) memcpy(next,n,row_length);
+ }
+ for (i=0; i < m; i++, yy++)
+ {
+ assert(yy < (long) large_image->rows);
+ p=prev;
+ n=next;
+ q=SetImagePixels(large_image,0,yy,
+ large_image->columns,1);
+ q+=(large_image->columns-image->columns);
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ /* TO DO: get color as function of indexes[x] */
+ /*
+ if (image->storage_class == PseudoClass)
+ {
+ }
+ */
+
+ if (magn_methy <= 1)
+ {
+ *q=(*p); /* replicate previous */
+ }
+ else if (magn_methy == 2 || magn_methy == 4)
+ {
+ if (i == 0)
+ *q=(*p);
+ else
+ {
+ /* Interpolate */
+ (*q).red=(QM) (((long) (2*i*((*n).red
+ -(*p).red)+m))/
+ ((long) (m*2))+(*p).red);
+ (*q).green=(QM) (((long) (2*i*((*n).green
+ -(*p).green)+m))/
+ ((long) (m*2))+(*p).green);
+ (*q).blue=(QM) (((long) (2*i*((*n).blue
+ -(*p).blue)+m))/
+ ((long) (m*2))+(*p).blue);
+ if (image->matte)
+ (*q).opacity=(QM) (((long)
+ (2*i*((*n).opacity-
+ (*p).opacity)+m))
+ /((long) (m*2))+
+ (*p).opacity);
+ }
+ if (magn_methy == 4)
+ {
+ /* Replicate nearest */
+ if (i <= ((m+1) << 1))
+ (*q).opacity=(*p).opacity+0;
+ else
+ (*q).opacity=(*n).opacity+0;
+ }
+ }
+ else /* if (magn_methy == 3 ||
+ magn_methy == 5) */
+ {
+ /* Replicate nearest */
+ if (i <= ((m+1) << 1))
+ *q=(*p);
+ else
+ *q=(*n);
+ if (magn_methy == 5)
+ {
+ (*q).opacity=(QM) (
+ ((long) (2*i*((*n).opacity
+ -(*p).opacity)+m))/
+ ((long) (m*2))+
+ (*p).opacity);
+ }
+ }
+ n++;
+ q++;
+ p++;
+ } /* x */
+ if (!SyncImagePixels(large_image))
+ break;
+ } /* i */
+ } /* y */
+ MagickFreeMemory(prev);
+ MagickFreeMemory(next);
+
+ row_length=image->columns;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Delete original image");
+
+ DeleteImageFromList(&image);
+
+ image=large_image;
+
+ mng_info->image=image;
+
+ /* magnify the columns */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Magnify the columns to %lu",
+ image->columns);
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if(q == (PixelPacket * ) NULL)
+ break;
+ p=q+(image->columns-row_length);
+ n=p+1;
+ for (x=(long) (image->columns-row_length);
+ x < (long) image->columns; x++)
+ {
+ if (x == (long) (image->columns-row_length))
+ m=mng_info->magn_ml;
+ else if (magn_methx > 1 &&
+ x == (long) image->columns-2)
+ m=mng_info->magn_mr;
+ else if (magn_methx <= 1 &&
+ x == (long) image->columns-1)
+ m=mng_info->magn_mr;
+ else if (magn_methx > 1 &&
+ x == (long) image->columns-1)
+ m=1;
+ else
+ m=mng_info->magn_mx;
+ for (i=0; i < m; i++)
+ {
+ if (magn_methx <= 1)
+ {
+ /* replicate previous */
+ *q=(*p);
+ }
+ else if (magn_methx == 2 || magn_methx == 4)
+ {
+ if (i == 0)
+ *q=(*p);
+ else
+ {
+ /* Interpolate */
+ (*q).red=(QM) ((2*i*((*n).red-
+ (*p).red)+m)
+ /((long) (m*2))+
+ (*p).red);
+ (*q).green=(QM) ((2*i*((*n).green-
+ (*p).green)
+ +m)/((long) (m*2))+
+ (*p).green);
+ (*q).blue=(QM) ((2*i*((*n).blue-
+ (*p).blue)+m)
+ /((long) (m*2))+
+ (*p).blue);
+ if (image->matte)
+ (*q).opacity=(QM) ((2*i*((*n).opacity
+ -(*p).opacity)+m)/
+ ((long) (m*2))
+ +(*p).opacity);
+ }
+ if (magn_methx == 4)
+ {
+ /* Replicate nearest */
+ if (i <= ((m+1) << 1))
+ (*q).opacity=(*p).opacity+0;
+ else
+ (*q).opacity=(*n).opacity+0;
+ }
+ }
+ else /* if (magn_methx == 3 ||
+ magn_methx == 5) */
+ {
+ /* Replicate nearest */
+ if (i <= ((m+1) << 1))
+ *q=(*p);
+ else
+ *q=(*n);
+ if (magn_methx == 5)
+ {
+ /* Interpolate */
+ (*q).opacity=(QM) ((2*i*((*n).opacity
+ -(*p).opacity)+m)/
+ ((long) (m*2))
+ +(*p).opacity);
+ }
+ }
+ q++;
+ }
+ n++;
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+#if (QuantumDepth == 32)
+ if (magn_methx != 1 || magn_methy != 1)
+ {
+ /*
+ Rescale pixels to Quantum
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if(q == (PixelPacket *) NULL)
+ break;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ q->red=ScaleShortToQuantum(q->red);
+ q->green=ScaleShortToQuantum(q->green);
+ q->blue=ScaleShortToQuantum(q->blue);
+ q->opacity=ScaleShortToQuantum(q->opacity);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+#endif
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Finished MAGN processing");
+ }
+ }
+
+ /*
+ Crop_box is with respect to the upper left corner of the MNG.
+ */
+ crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
+ crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
+ crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
+ crop_box.bottom=mng_info->image_box.bottom+
+ mng_info->y_off[object_id];
+ crop_box=mng_minimum_box(crop_box,mng_info->clip);
+ crop_box=mng_minimum_box(crop_box,mng_info->frame);
+ crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
+ if ((crop_box.left != (mng_info->image_box.left
+ +mng_info->x_off[object_id])) ||
+ (crop_box.right != (mng_info->image_box.right
+ +mng_info->x_off[object_id])) ||
+ (crop_box.top != (mng_info->image_box.top
+ +mng_info->y_off[object_id])) ||
+ (crop_box.bottom != (mng_info->image_box.bottom
+ +mng_info->y_off[object_id])))
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Crop the PNG image");
+ if ((crop_box.left < crop_box.right) &&
+ (crop_box.top < crop_box.bottom))
+ {
+ Image
+ *p;
+
+ RectangleInfo
+ crop_info;
+
+ /*
+ Crop_info is with respect to the upper left corner of
+ the image.
+ */
+ crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
+ crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
+ crop_info.width=(crop_box.right-crop_box.left);
+ crop_info.height=(crop_box.bottom-crop_box.top);
+ image->page.width=image->columns;
+ image->page.height=image->rows;
+ image->page.x=0;
+ image->page.y=0;
+ p=CropImage(image,&crop_info,exception);
+ if (p != (Image *) NULL)
+ {
+ image->columns=p->columns;
+ image->rows=p->rows;
+ DestroyImage(p);
+ image->page.width=image->columns;
+ image->page.height=image->rows;
+ image->page.x=crop_box.left;
+ image->page.y=crop_box.top;
+ }
+ }
+ else
+ {
+ /*
+ No pixels in crop area. The MNG spec still requires
+ a layer, though, so make a single transparent pixel in
+ the top left corner.
+ */
+ image->columns=1;
+ image->rows=1;
+ image->colors=2;
+ (void) SetImage(image,TransparentOpacity);
+ image->page.width=1;
+ image->page.height=1;
+ image->page.x=0;
+ image->page.y=0;
+ }
+ }
+#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
+ image=mng_info->image;
+#endif
+ }
+
+ /*
+ Transfer most significant exception to exception argument
+ FIXME: should status be used to terminate processing?
+ */
+ GetImageException(image,exception);
+ if (image_info->number_scenes != 0)
+ {
+ if (mng_info->scenes_found > (long) (image_info->first_scene+
+ image_info->number_scenes))
+ break;
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Finished reading image datastream.");
+ } while (LocaleCompare(image_info->magick,"MNG") == 0);
+ CloseBlob(image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Finished reading all image datastreams.");
+#ifdef MNG_INSERT_LAYERS
+ if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
+ (mng_info->mng_height))
+ {
+ /*
+ Insert a background layer if nothing else was found.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " No images found. Inserting a"
+ " background layer.");
+ if (AccessMutablePixels(image) != (PixelPacket *) NULL)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Allocation failed, returning NULL.");
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ }
+ image->columns=mng_info->mng_width;
+ image->rows=mng_info->mng_height;
+ image->page.width=mng_info->mng_width;
+ image->page.height=mng_info->mng_height;
+ image->page.x=0;
+ image->page.y=0;
+ image->background_color=mng_background_color;
+ image->matte=MagickFalse;
+ if (!image_info->ping)
+ (void) SetImage(image,OpaqueOpacity);
+ mng_info->image_found++;
+ }
+#endif
+ image->iterations=mng_iterations;
+ if (mng_iterations == 1)
+ image->start_loop=MagickTrue;
+ while (image->previous != (Image *) NULL)
+ {
+ image_count++;
+ if (image_count > 10*mng_info->image_found)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " No beginning");
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ (void) ThrowException2(&image->exception,(ExceptionType) CoderError,
+ "Linked list is corrupted,"
+ " beginning of list not found",
+ image_info->filename);
+ return((Image *) NULL);
+ }
+ image=image->previous;
+ if (image->next == (Image *) NULL)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Corrupt list");
+ (void) ThrowException2(&image->exception,(ExceptionType) CoderError,
+ "Linked list is corrupted;"
+ " next_image is NULL",
+ image_info->filename);
+ }
+ }
+ if (mng_info->ticks_per_second && mng_info->image_found > 1 && image->next ==
+ (Image *) NULL)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " First image null");
+ (void) ThrowException2(&image->exception,(ExceptionType) CoderError,
+ "image->next for first image is NULL but"
+ " shouldn't be.",
+ image_info->filename);
+ }
+ if (!mng_info->image_found)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " No visible images found.");
+ (void) ThrowException2(&image->exception,(ExceptionType) CoderError,
+ "No visible images in file",image_info->filename);
+ if (image != (Image *) NULL)
+ DestroyImageList(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ return((Image *) NULL);
+ }
+
+ if (mng_info->ticks_per_second)
+ final_delay=100*final_delay/mng_info->ticks_per_second;
+ else
+ image->start_loop=MagickTrue;
+ /* Find final nonzero image delay */
+ final_image_delay=0;
+ while (image->next != (Image *) NULL)
+ {
+ if (image->delay)
+ final_image_delay=image->delay;
+ image=image->next;
+ }
+ if (final_delay < final_image_delay)
+ final_delay=final_image_delay;
+ image->delay=final_delay;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image->delay=%lu, final_delay=%lu",
+ image->delay,final_delay);
+ if (logging)
+ {
+ int
+ scene;
+
+ scene=0;
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Before coalesce:");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " scene 0 delay=%lu",image->delay);
+ while (image->next != (Image *) NULL)
+ {
+ image=image->next;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " scene %d delay=%lu",++scene,image->delay);
+ }
+ }
+
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+#ifdef MNG_COALESCE_LAYERS
+ if (insert_layers)
+ {
+ Image
+ *next_image,
+ *next;
+
+ unsigned long
+ scene;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Coalesce Images");
+ scene=image->scene;
+ next_image=CoalesceImages(image,&image->exception);
+ if (next_image == (Image *) NULL)
+ MagickFatalError2(image->exception.severity,image->exception.reason,
+ image->exception.description);
+ DestroyImageList(image);
+ image=next_image;
+ for (next=image; next != (Image *) NULL; next=next_image)
+ {
+ next->page.width=mng_info->mng_width;
+ next->page.height=mng_info->mng_height;
+ next->page.x=0;
+ next->page.y=0;
+ next->scene=scene++;
+ next_image=next->next;
+ if (next_image == (Image *) NULL)
+ break;
+ if (next->delay == 0)
+ {
+ scene--;
+ next_image->previous=next->previous;
+ if (next->previous == (Image *) NULL)
+ image=next_image;
+ else
+ next->previous->next=next_image;
+ DestroyImage(next);
+ }
+ }
+ }
+#endif
+
+ while (image->next != (Image *) NULL)
+ image=image->next;
+ image->dispose=BackgroundDispose;
+
+ if (logging)
+ {
+ int
+ scene;
+
+ scene=0;
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " After coalesce:");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " scene 0 delay=%lu dispose=%d",
+ image->delay,(int) image->dispose);
+ while (image->next != (Image *) NULL)
+ {
+ image=image->next;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " scene %d delay=%lu dispose=%d",++scene,
+ image->delay,(int) image->dispose);
+ }
+ }
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ have_mng_structure=MagickFalse;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
+ return(image);
+}
+#else /* PNG_LIBPNG_VER > 10011 */
+static Image *ReadPNGImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ printf("Your PNG library is too old: You have libpng-%s\n",
+ PNG_LIBPNG_VER_STRING);
+ (void) ThrowException2(exception,CoderError,"PNG library is too old",
+ image_info->filename);
+ return (Image *) NULL;
+}
+static Image *ReadMNGImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ return (ReadPNGImage(image_info,exception));
+}
+#endif /* PNG_LIBPNG_VER > 10011 */
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPNGImage adds attributes for the PNG image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPNGImage method is:
+%
+% RegisterPNGImage(void)
+%
+*/
+ModuleExport void RegisterPNGImage(void)
+{
+ static char
+ version[MaxTextExtent];
+
+ MagickInfo
+ *entry;
+
+ static const char
+ *PNGNote=
+ {
+ "See http://www.libpng.org/ for information on PNG.."
+ };
+
+ static const char
+ *JNGNote=
+ {
+ "See http://www.libpng.org/pub/mng/ for information on JNG."
+ };
+
+ static const char
+ *MNGNote=
+ {
+ "See http://www.libpng.org/pub/mng/ for information on MNG."
+ };
+
+ *version='\0';
+#if defined(PNG_LIBPNG_VER_STRING)
+ (void) strlcat(version,"libpng ",MaxTextExtent);
+ (void) strlcat(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
+#if (PNG_LIBPNG_VER > 10005)
+ if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
+ {
+ (void) strlcat(version,",",MaxTextExtent);
+ (void) strlcat(version,png_get_libpng_ver(NULL),MaxTextExtent);
+ }
+#endif
+#endif
+
+#if defined(ZLIB_VERSION)
+ if (*version != '\0')
+ (void) strlcat(version,", ",MaxTextExtent);
+ (void) strlcat(version,"zlib ",MaxTextExtent);
+ (void) strlcat(version,ZLIB_VERSION,MaxTextExtent);
+ if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
+ {
+ (void) strlcat(version,",",MaxTextExtent);
+ (void) strlcat(version,zlib_version,MaxTextExtent);
+ }
+#endif
+
+ entry=SetMagickInfo("MNG");
+ entry->seekable_stream=MagickTrue; /* To do: eliminate this. */
+ entry->thread_support=MagickTrue;
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadMNGImage;
+ entry->encoder=(EncoderHandler) WriteMNGImage;
+#endif
+ entry->magick=(MagickHandler) IsMNG;
+ entry->description="Multiple-image Network Graphics";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ entry->note=MNGNote;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PNG");
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadPNGImage;
+ entry->encoder=(EncoderHandler) WritePNGImage;
+#endif
+ entry->magick=(MagickHandler) IsPNG;
+ entry->adjoin=MagickFalse;
+ entry->thread_support=MagickTrue;
+ entry->description="Portable Network Graphics";
+ if (*version != '\0')
+ entry->version=version;
+ entry->note=PNGNote;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PNG8");
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadPNGImage;
+ entry->encoder=(EncoderHandler) WritePNGImage;
+#endif
+ entry->magick=(MagickHandler) IsPNG;
+ entry->adjoin=MagickFalse;
+ entry->thread_support=MagickTrue;
+ entry->description="8-bit indexed PNG, binary transparency only";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PNG24");
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadPNGImage;
+ entry->encoder=(EncoderHandler) WritePNGImage;
+#endif
+ entry->magick=(MagickHandler) IsPNG;
+ entry->adjoin=MagickFalse;
+ entry->thread_support=MagickTrue;
+ entry->description="24-bit RGB PNG, opaque only";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PNG32");
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadPNGImage;
+ entry->encoder=(EncoderHandler) WritePNGImage;
+#endif
+ entry->magick=(MagickHandler) IsPNG;
+ entry->adjoin=MagickFalse;
+ entry->thread_support=MagickTrue;
+ entry->description="32-bit RGBA PNG, semitransparency OK";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PNG48");
+
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadPNGImage;
+ entry->encoder=(EncoderHandler) WritePNGImage;
+#endif
+
+ entry->magick=(MagickHandler) IsPNG;
+ entry->adjoin=MagickFalse;
+ entry->thread_support=MagickTrue;
+ entry->description="opaque or binary transparent 48-bit RGB";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PNG64");
+
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadPNGImage;
+ entry->encoder=(EncoderHandler) WritePNGImage;
+#endif
+
+ entry->magick=(MagickHandler) IsPNG;
+ entry->adjoin=MagickFalse;
+ entry->thread_support=MagickTrue;
+ entry->description="opaque or transparent 64-bit RGBA";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PNG00");
+
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadPNGImage;
+ entry->encoder=(EncoderHandler) WritePNGImage;
+#endif
+
+ entry->magick=(MagickHandler) IsPNG;
+ entry->adjoin=MagickFalse;
+ entry->thread_support=MagickTrue;
+ entry->description="PNG that inherits type and depth from original";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("JNG");
+#if defined(JNG_SUPPORTED)
+#if defined(HasPNG)
+ entry->decoder=(DecoderHandler) ReadJNGImage;
+ entry->encoder=(EncoderHandler) WriteJNGImage;
+#endif
+#endif
+ entry->magick=(MagickHandler) IsJNG;
+ entry->adjoin=MagickFalse;
+ entry->thread_support=MagickTrue;
+ entry->description="JPEG Network Graphics";
+ entry->note=JNGNote;
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="PNG";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ png_semaphore=AllocateSemaphoreInfo();
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPNGImage removes format registrations made by the
+% PNG module from the list of supported formats.
+%
+% The format of the UnregisterPNGImage method is:
+%
+% UnregisterPNGImage(void)
+%
+*/
+ModuleExport void UnregisterPNGImage(void)
+{
+ (void) UnregisterMagickInfo("MNG");
+ (void) UnregisterMagickInfo("PNG");
+ (void) UnregisterMagickInfo("PNG8");
+ (void) UnregisterMagickInfo("PNG24");
+ (void) UnregisterMagickInfo("PNG32");
+ (void) UnregisterMagickInfo("PNG48");
+ (void) UnregisterMagickInfo("PNG64");
+ (void) UnregisterMagickInfo("PNG00");
+ (void) UnregisterMagickInfo("JNG");
+
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ DestroySemaphoreInfo(&png_semaphore);
+#endif
+}
+
+#if defined(HasPNG)
+#if PNG_LIBPNG_VER > 10011
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e M N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteMNGImage writes an image in the Portable Network Graphics
+% Group's "Multiple-image Network Graphics" encoded image format.
+%
+% MNG support written by Glenn Randers-Pehrson, randeg@alum.rpi.edu
+%
+% The format of the WriteMNGImage method is:
+%
+% unsigned int WriteMNGImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteMNGImage return True if the image is written.
+% MagickFalse is returned is there is a memory shortage or if the
+% image file fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+% To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
+% "To do" under ReadPNGImage):
+%
+% Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
+% some GIF animations don't convert properly)
+%
+% Preserve all unknown and not-yet-handled known chunks found in input
+% PNG file and copy them into output PNG files according to the PNG
+% copying rules.
+%
+% Write the iCCP chunk at MNG level when (image->color_profile.length > 0)
+%
+% Improve selection of color type (use indexed-colour or indexed-colour
+% with tRNS when 256 or fewer unique RGBA values are present).
+%
+% Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
+% This will be complicated if we limit ourselves to generating MNG-LC
+% files. For now we ignore disposal method 3 and simply overlay the next
+% image on it.
+%
+% Check for identical PLTE's or PLTE/tRNS combinations and use a
+% global MNG PLTE or PLTE/tRNS combination when appropriate.
+% [mostly done 15 June 1999 but still need to take care of tRNS]
+%
+% Check for identical sRGB and replace with a global sRGB (and remove
+% gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
+% replace with global gAMA/cHRM (or with sRGB if appropriate; replace
+% local gAMA/cHRM with local sRGB if appropriate).
+%
+% Check for identical sBIT chunks and write global ones.
+%
+% Provide option to skip writing the signature tEXt chunks.
+%
+% Use signatures to detect identical objects and reuse the first
+% instance of such objects instead of writing duplicate objects.
+%
+% Use a smaller-than-32k value of compression window size when
+% appropriate.
+%
+% Encode JNG datastreams. Mostly done as of 5.5.2; need to write
+% ancillary text chunks and save profiles.
+%
+% Provide an option to force LC files (to ensure exact framing rate)
+% instead of VLC.
+%
+% Provide an option to force VLC files instead of LC, even when offsets
+% are present. This will involve expanding the embedded images with a
+% transparent region at the top and/or left.
+*/
+
+
+static void
+png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
+ png_info *ping_info, const char *profile_type,
+ const char *profile_description,
+ const unsigned char *profile_data,
+ png_uint_32 length)
+{
+ png_textp
+ text;
+
+ register long
+ i;
+
+ const unsigned char
+ *sp;
+
+ png_charp
+ dp;
+
+ png_uint_32
+ allocated_length,
+ description_length;
+
+ unsigned char
+ hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+ if (image_info->verbose)
+ {
+ (void) printf("writing raw profile: type=%.1024s, length=%lu\n",
+ profile_type, (unsigned long)length);
+ }
+#if PNG_LIBPNG_VER >= 14000
+ text=(png_textp) png_malloc(ping,(png_alloc_size_t) sizeof(png_text));
+#else
+ text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
+#endif
+ description_length=(png_uint_32) strlen((const char *) profile_description);
+ allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
+ + description_length);
+#if PNG_LIBPNG_VER >= 14000
+ text[0].text=(png_charp) png_malloc(ping,
+ (png_alloc_size_t) allocated_length);
+ text[0].key=(png_charp) png_malloc(ping, (png_alloc_size_t) 80);
+#else
+ text[0].text=(png_charp) png_malloc(ping, (png_size_t) allocated_length);
+ text[0].key=(png_charp) png_malloc(ping, (png_size_t) 80);
+#endif
+ text[0].key[0]='\0';
+ (void) strcat(text[0].key, "Raw profile type ");
+ (void) strncat(text[0].key, (const char *) profile_type, 61);
+ sp=profile_data;
+ dp=text[0].text;
+ *dp++='\n';
+ (void) strcpy(dp,(const char *) profile_description);
+ dp+=description_length;
+ *dp++='\n';
+ (void) sprintf(dp,"%8lu ",(unsigned long)length);
+ dp+=8;
+ for (i=0; i < (long) length; i++)
+ {
+ if (i%36 == 0)
+ *dp++='\n';
+ *(dp++)=hex[((*sp >> 4) & 0x0f)];
+ *(dp++)=hex[((*sp++ ) & 0x0f)];
+ }
+ *dp++='\n';
+ *dp='\0';
+ text[0].text_length=dp-text[0].text;
+ text[0].compression=image_info->compression == NoCompression ||
+ (image_info->compression == UndefinedCompression &&
+ text[0].text_length < 128) ? -1 : 0;
+ if (text[0].text_length <= allocated_length)
+ png_set_text(ping,ping_info,text,1);
+ png_free(ping,text[0].text);
+ png_free(ping,text[0].key);
+ png_free(ping,text);
+}
+
+static MagickPassFail WriteOnePNGImage(MngInfo *mng_info,
+ const ImageInfo *image_info,Image *imagep)
+{
+ const char
+ *gm_vers,
+ *libpng_runv,
+ *libpng_vers,
+ *zlib_runv,
+ *zlib_vers;
+
+#ifdef HasLCMS
+ char
+ lcms_vers[32];
+#endif
+
+ Image
+ * volatile imagev = imagep, /* Use only 'imagev' before setjmp() */
+ *image; /* Use only 'image' after setjmp() */
+
+ /* Write one PNG image */
+ const ImageAttribute
+ *attribute;
+
+ char
+ s[2];
+
+ int
+ num_passes,
+ pass,
+ ping_bit_depth = 0,
+ ping_colortype = 0,
+ ping_interlace_method = 0,
+ ping_compression_method = 0;
+
+ volatile int
+ ping_filter_method = 0,
+ ping_num_trans = 0,
+ ping_valid_trns = 0;
+
+ volatile png_bytep
+ ping_trans_alpha = NULL;
+
+ png_colorp
+ palette;
+
+ png_color_16
+ ping_background,
+ ping_trans_color;
+
+ png_info
+ *ping_info;
+
+ png_struct
+ *ping;
+
+ png_uint_32
+ ping_width,
+ ping_height;
+
+ long
+ y;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ unsigned char
+ *png_pixels;
+
+ unsigned int
+ image_colors,
+ image_depth,
+ image_matte,
+ logging,
+ matte;
+
+ unsigned long
+ quantum_size, /* depth for ExportImage */
+ rowbytes,
+ save_image_depth;
+
+ ImageCharacteristics
+ characteristics;
+
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),
+ " enter WriteOnePNGImage()");
+
+ /* Define these outside of the following "if logging()" block so they will
+ * show in debuggers.
+ */
+ gm_vers=MagickLibVersionText;
+#ifdef HasLCMS
+ (void) sprintf(lcms_vers,"%.4d",LCMS_VERSION);
+#endif
+ libpng_runv=png_get_libpng_ver(NULL);
+ libpng_vers=PNG_LIBPNG_VER_STRING;
+ zlib_runv=zlib_version;
+ zlib_vers=ZLIB_VERSION;
+
+ if (logging != MagickFalse)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " GM version = %.31s", gm_vers);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Libpng version = %.31s", libpng_vers);
+ if (LocaleCompare(libpng_vers,libpng_runv) != 0)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " running with %.31s", libpng_runv);
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Zlib version = %.31s", zlib_vers);
+ if (LocaleCompare(zlib_vers,zlib_runv) != 0)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " running with %.31s", zlib_runv);
+ }
+#ifdef HasLCMS
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " LCMS version = %.31s", lcms_vers);
+#endif
+ }
+ /* Initialize some stuff */
+ ping_background.red = 0;
+ ping_background.green = 0;
+ ping_background.blue = 0;
+ ping_background.gray = 0;
+ ping_background.index = 0;
+
+ ping_trans_color.red=0;
+ ping_trans_color.green=0;
+ ping_trans_color.blue=0;
+ ping_trans_color.gray=0;
+
+ /*
+ Allocate the PNG structures
+ */
+#ifdef PNG_USER_MEM_SUPPORTED
+ ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,imagev,
+ PNGErrorHandler,PNGWarningHandler,
+ (void *) NULL,
+ (png_malloc_ptr) png_IM_malloc,
+ (png_free_ptr) png_IM_free);
+#else
+ ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,imagev,
+ PNGErrorHandler,PNGWarningHandler);
+#endif
+ if (ping == (png_struct *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,imagev);
+ ping_info=png_create_info_struct(ping);
+ if (ping_info == (png_info *) NULL)
+ {
+ png_destroy_write_struct(&ping,(png_info **) NULL);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,imagev);
+ }
+ png_set_write_fn(ping,imagev,png_put_data,png_flush_data);
+ png_pixels=(unsigned char *) NULL;
+
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ LockSemaphoreInfo(png_semaphore);
+#endif
+
+ if (setjmp(png_jmpbuf(ping)))
+ {
+ /*
+ PNG write failed.
+ */
+#ifdef PNG_DEBUG
+ if (image_info->verbose)
+ (void) printf("PNG write has failed.\n");
+#endif
+ png_destroy_write_struct(&ping,&ping_info);
+ MagickFreeMemory(png_pixels);
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ return(MagickFail);
+ }
+
+/* { For navigation to end of setjmp-controlled block */
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ /* Allow benign errors */
+ png_set_benign_errors(ping, 1);
+#endif
+
+ image=imagev; /* Use 'image' after this point for optimization */
+
+ /*
+ Make sure that image is in an RGB type space.
+ */
+ if (!TransformColorspace(image,RGBColorspace))
+ {
+ CloseBlob(image);
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ return MagickFail;
+ }
+
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+ return MagickFail;
+ }
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Image Characteristics:\n"
+ " CMYK: %u\n"
+ " Grayscale: %u\n"
+ " Monochrome: %u\n"
+ " Opaque: %u\n"
+ " Palette: %u",
+ characteristics.cmyk,
+ characteristics.grayscale ,
+ characteristics.monochrome,
+ characteristics.opaque,
+ characteristics.palette);
+ }
+
+ if (image->storage_class == PseudoClass)
+ image_colors=image->colors;
+ else
+ image_colors=0;
+
+ image_depth=image->depth;
+ image_matte=image->matte;
+
+ if (image->storage_class == PseudoClass &&
+ image_colors <= 256)
+ {
+ mng_info->IsPalette=MagickTrue;
+ image_depth=8;
+ }
+
+ if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
+ image_depth=8;
+
+ else if (mng_info->write_png48 || mng_info->write_png64)
+ image_depth=16;
+
+ else if (image_depth < 8)
+ image_depth=8;
+
+ else if (image_depth > 8)
+ image_depth=16;
+
+ /*
+ Prepare PNG for writing.
+ */
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ if (mng_info->write_mng)
+ {
+# ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Disable new libpng-1.5.10 feature when writing a MNG */
+ png_set_check_for_invalid_index (ping, 0);
+# endif
+ (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
+ }
+#else
+# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
+ if (mng_info->write_mng)
+ png_permit_empty_plte(ping,MagickTrue);
+# endif
+#endif
+ x=0;
+ ping_width=image->columns;
+ ping_height=image->rows;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " width=%lu",
+ (unsigned long)ping_width);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " height=%lu",
+ (unsigned long)ping_height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image->depth=%u",image_depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image_colors=%u",image_colors);
+ }
+
+
+ quantum_size=(image_depth > 8) ? 16:8;
+
+ save_image_depth=image_depth;
+ ping_bit_depth=(png_byte) save_image_depth;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " ping_bit_depth=%u",
+ ping_bit_depth);
+ }
+ /*
+ Select the color type.
+ */
+ matte=image_matte;
+ if (mng_info->write_png8)
+ {
+ ping_colortype=PNG_COLOR_TYPE_PALETTE;
+ ping_bit_depth=8;
+ {
+ /* TO DO: make this a function cause it's used twice, except
+ for reducing the sample depth from 8. */
+
+ QuantizeInfo
+ quantize_info;
+
+ unsigned long
+ number_colors;
+
+ number_colors=image_colors;
+ if ((number_colors == 0) || (number_colors > 256))
+ {
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.dither=image_info->dither;
+ quantize_info.number_colors=256;
+ (void) QuantizeImage(&quantize_info,image);
+ number_colors=image->colors;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Colors quantized to %ld",
+ number_colors);
+ image_colors=image->colors;
+ }
+
+ /*
+ Set image palette.
+ */
+
+ ping_colortype=PNG_COLOR_TYPE_PALETTE;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up PLTE chunk with %d colors",
+ (int) number_colors);
+ palette=MagickAllocateMemory(png_color *,
+ number_colors*sizeof(png_color));
+ if (palette == (png_color *) NULL)
+ png_error(ping, "Could not allocate palette");
+ else
+ {
+ for (i=0; i < (long) number_colors; i++)
+ {
+ palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
+ palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
+ palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+#if QuantumDepth == 8
+ " %3ld (%3d,%3d,%3d)",
+#else
+ " %5ld (%5d,%5d,%5d)",
+#endif
+ i,palette[i].red,palette[i].green,
+ palette[i].blue);
+
+ }
+ png_set_PLTE(ping,ping_info,palette,(int) number_colors);
+ MagickFreeMemory(palette);
+ }
+ /*
+ Identify which colormap entry is transparent.
+ */
+ ping_trans_alpha=MagickAllocateMemory(unsigned char *, number_colors);
+ if (ping_trans_alpha == (unsigned char *) NULL)
+ png_error(ping, "Could not allocate ping_trans_alpha");
+ else
+ {
+ assert(number_colors <= 256);
+ for (i=0; i < (long) number_colors; i++)
+ ping_trans_alpha[i]=255;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register const PixelPacket
+ *p=NULL;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (p->opacity != OpaqueOpacity)
+ {
+ IndexPacket
+ index;
+
+ index=indexes[x];
+ assert((unsigned long) index < number_colors);
+ ping_trans_alpha[index]=(png_byte) (255-
+ ScaleQuantumToChar(p->opacity));
+ }
+ p++;
+ }
+ }
+ ping_num_trans=0;
+ for (i=0; i < (long) number_colors; i++)
+ if (ping_trans_alpha[i] != 255)
+ ping_num_trans=(unsigned short) (i+1);
+ if (ping_num_trans != 0)
+ ping_valid_trns = 1;
+ MagickFreeMemory(ping_trans_alpha);
+ }
+ /*
+ Identify which colormap entry is the background color.
+ */
+ for (i=0; i < (long) Max(number_colors-1,1); i++)
+ if (RGBColorMatchExact(ping_background,image->colormap[i]))
+ break;
+ ping_background.index=(png_uint_16) i;
+ }
+ if (image_matte)
+ {
+ /* TO DO: reduce to binary transparency */
+ }
+ }
+ else if (mng_info->write_png24 || mng_info->write_png48)
+ {
+ image_matte=MagickFalse;
+ ping_colortype=PNG_COLOR_TYPE_RGB;
+ }
+ else if (mng_info->write_png32 || mng_info->write_png64)
+ {
+ image_matte=MagickTrue;
+ ping_colortype=PNG_COLOR_TYPE_RGB_ALPHA;
+ }
+ else
+ {
+ if (ping_bit_depth < 8)
+ ping_bit_depth=8;
+
+ ping_colortype=PNG_COLOR_TYPE_RGB;
+ if (characteristics.monochrome)
+ {
+ if (characteristics.opaque)
+ {
+ ping_colortype=PNG_COLOR_TYPE_GRAY;
+ ping_bit_depth=1;
+ }
+ else
+ {
+ ping_colortype=PNG_COLOR_TYPE_GRAY_ALPHA;
+ }
+ }
+ else if (characteristics.grayscale)
+ {
+ if (characteristics.opaque)
+ ping_colortype=PNG_COLOR_TYPE_GRAY;
+ else
+ ping_colortype=PNG_COLOR_TYPE_GRAY_ALPHA;
+ }
+ else if (characteristics.palette && image_colors <= 256)
+ {
+ ping_colortype=PNG_COLOR_TYPE_PALETTE;
+ ping_bit_depth=8;
+ mng_info->IsPalette=MagickTrue;
+ }
+ else
+ {
+ if (characteristics.opaque)
+ ping_colortype=PNG_COLOR_TYPE_RGB;
+ else
+ ping_colortype=PNG_COLOR_TYPE_RGB_ALPHA;
+ }
+ if (image_info->type == BilevelType)
+ {
+ if (characteristics.monochrome)
+ {
+ if (!image_matte)
+ ping_bit_depth=1;
+ }
+ }
+ if (image_info->type == GrayscaleType)
+ ping_colortype=PNG_COLOR_TYPE_GRAY;
+ if (image_info->type == GrayscaleMatteType)
+ ping_colortype=PNG_COLOR_TYPE_GRAY_ALPHA;
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Tentative PNG color type: %s (%d)",
+ PngColorTypeToString(ping_colortype),
+ ping_colortype);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image_info->type: %d",image_info->type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image->depth: %u",image_depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " ping_bit_depth: %d",
+ ping_bit_depth);
+ }
+
+ if (matte && mng_info->IsPalette)
+ {
+ register const PixelPacket
+ *p=NULL;
+
+ if (characteristics.opaque)
+ {
+ /*
+ No transparent pixels are present. Change 4 or 6 to 0 or 2,
+ and unset the ping_valid_trns flag.
+ */
+ image_matte=MagickFalse;
+ ping_colortype&=0x03;
+ ping_valid_trns=0;
+ }
+ else
+ {
+ unsigned int
+ mask;
+
+ mask=0xffff;
+ if (ping_bit_depth == 8)
+ mask=0x00ff;
+ if (ping_bit_depth == 4)
+ mask=0x000f;
+ if (ping_bit_depth == 2)
+ mask=0x0003;
+ if (ping_bit_depth == 1)
+ mask=0x0001;
+
+ /*
+ Find a transparent color.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (p->opacity != OpaqueOpacity)
+ break;
+ p++;
+ }
+ if (p->opacity != OpaqueOpacity)
+ break;
+ }
+ if ((p != (const PixelPacket *) NULL) &&
+ (p->opacity != OpaqueOpacity))
+ {
+ ping_trans_color.red=ScaleQuantumToShort(p->red)&mask;
+ ping_trans_color.green=ScaleQuantumToShort(p->green)
+ &mask;
+ ping_trans_color.blue=ScaleQuantumToShort(p->blue)
+ &mask;
+ ping_trans_color.gray=
+ (png_uint_16) ScaleQuantumToShort(PixelIntensity(p))&mask;
+ ping_trans_color.index=(unsigned char)
+ (ScaleQuantumToChar(MaxRGB-p->opacity));
+ ping_valid_trns=1;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Found transparent color: (%d,%d,%d)",
+ ping_trans_color.red, ping_trans_color.green,
+ ping_trans_color.blue);
+ }
+ }
+ if (ping_valid_trns != 0)
+ {
+ /*
+ Determine if there is one and only one transparent color
+ and if so if it is fully transparent.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Determine if there is exactly one transparent color");
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ x=0;
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (p->opacity != OpaqueOpacity)
+ {
+ if (!RGBColorMatchExact(ping_trans_color,*p))
+ {
+ break; /* Can't use RGB + tRNS for multiple
+ transparent colors. */
+ }
+ if (p->opacity != TransparentOpacity)
+ {
+ break; /* Can't use RGB + tRNS for
+ semitransparency. */
+ }
+ }
+ else
+ {
+ if (RGBColorMatchExact(ping_trans_color,*p))
+ break; /* Can't use RGB + tRNS when another pixel
+ having the same RGB samples is
+ transparent. */
+ }
+ p++;
+ }
+ if (x != 0)
+ break;
+ }
+ if (x != 0)
+ {
+ ping_valid_trns = 0;
+ }
+ else if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Single transparent color (%d,%d,%d index=%d)",
+ ping_trans_color.red,ping_trans_color.green,
+ ping_trans_color.blue,ping_trans_color.index);
+ }
+ }
+ if (ping_valid_trns != 0)
+ {
+ ping_colortype &= 0x03; /* changes 4 or 6 to 0 or 2 */
+ if (image_depth == 8)
+ {
+ ping_trans_color.red&=0xff;
+ ping_trans_color.green&=0xff;
+ ping_trans_color.blue&=0xff;
+ ping_trans_color.gray&=0xff;
+ }
+ }
+ }
+ matte=image_matte;
+ if (ping_valid_trns != 0)
+ image_matte=MagickFalse;
+ if (mng_info->IsPalette &&
+ characteristics.grayscale && (!image_matte || image_depth >= 8))
+ {
+ if (image_matte)
+ ping_colortype=PNG_COLOR_TYPE_GRAY_ALPHA;
+ else
+ {
+ ping_colortype=PNG_COLOR_TYPE_GRAY;
+ if (save_image_depth == 16 && image_depth == 8)
+ ping_trans_color.gray*=0x0101;
+ }
+ if (image_depth > QuantumDepth)
+ image_depth=QuantumDepth;
+ if (image_colors == 0 || image_colors-1 > MaxRGB)
+ image_colors=1 << image_depth;
+ if (image_depth > 8)
+ ping_bit_depth=16;
+ else
+ {
+ if (ping_colortype == PNG_COLOR_TYPE_PALETTE)
+ {
+ ping_bit_depth=1;
+ while ((int) (1 << ping_bit_depth) <
+ (long) image_colors)
+ ping_bit_depth <<= 1;
+ }
+ }
+ }
+ else
+ if (mng_info->IsPalette)
+ {
+ if (image_depth <= 8)
+ {
+ unsigned long
+ number_colors;
+
+ number_colors=image_colors;
+ /*
+ Set image palette.
+ */
+ ping_colortype=PNG_COLOR_TYPE_PALETTE;
+ if (mng_info->have_write_global_plte && !matte)
+ {
+ png_set_PLTE(ping,ping_info,NULL,0);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up empty PLTE chunk");
+ }
+ else
+ {
+ palette=MagickAllocateArray(png_color *,
+ number_colors,
+ sizeof(png_color));
+ if (palette == (png_color *) NULL)
+ png_error(ping, "Could not allocate palette");
+ for (i=0; i < (long) number_colors; i++)
+ {
+ palette[i].red=ScaleQuantumToChar
+ (image->colormap[i].red);
+ palette[i].green=ScaleQuantumToChar
+ (image->colormap[i].green);
+ palette[i].blue=ScaleQuantumToChar
+ (image->colormap[i].blue);
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up PLTE chunk with %d colors",
+ (int) number_colors);
+ png_set_PLTE(ping,ping_info,palette,(int) number_colors);
+ MagickFreeMemory(palette);
+ }
+ ping_bit_depth=1;
+ while ((1UL << ping_bit_depth) < number_colors)
+ ping_bit_depth <<= 1;
+ ping_num_trans=0;
+ if (matte)
+ {
+ int
+ num_alpha=0,
+ trans_alpha[256];
+
+ /*
+ Identify which colormap entry is transparent.
+ */
+ assert(number_colors <= 256);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Look for transparent colormap entry, number_colors=%d",
+ (int) number_colors);
+
+ for (i=0; i < (long) number_colors; i++)
+ trans_alpha[i]=256;
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register const PixelPacket
+ *p=NULL;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (p->opacity != OpaqueOpacity)
+ {
+ IndexPacket
+ index;
+
+ index=indexes[x];
+ assert((unsigned long) index < number_colors);
+ if (trans_alpha[index] == 256)
+ {
+ (void) LogMagickEvent(CoderEvent,
+ GetMagickModule(),
+ " Index=%d is transparent",(int) index);
+ trans_alpha[index]=(png_byte) (255-
+ ScaleQuantumToChar(p->opacity));
+ num_alpha++;
+ }
+ }
+ p++;
+ }
+ }
+
+ (void) LogMagickEvent(CoderEvent, GetMagickModule(),
+ " num_alpha = %d",num_alpha);
+ if (num_alpha == 1)
+ ping_valid_trns=1;
+ else
+ {
+ ping_colortype=PNG_COLOR_TYPE_RGB_ALPHA;
+ ping_num_trans=0;
+ if (ping_bit_depth < 8)
+ ping_bit_depth=8;
+ ping_valid_trns = 0;
+ png_set_invalid(ping, ping_info, PNG_INFO_PLTE);
+ mng_info->IsPalette=MagickFalse;
+ (void) SyncImage(image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,
+ GetMagickModule(),
+ " Cannot write image"
+ " as indexed PNG,"
+ " writing RGBA.");
+ }
+
+ if (ping_valid_trns != 0)
+ {
+ for (i=0; i < (long) number_colors; i++)
+ {
+ if (trans_alpha[i] == 256)
+ trans_alpha[i]=255;
+ if (trans_alpha[i] != 255)
+ ping_num_trans=(unsigned short) (i+1);
+ }
+ (void) LogMagickEvent(CoderEvent, GetMagickModule(),
+ " ping_num_trans = %d",ping_num_trans);
+ }
+ if (ping_num_trans == 0)
+ ping_valid_trns = 0;
+ else
+ ping_valid_trns = 1;
+ if (ping_valid_trns == 0)
+ ping_num_trans=0;
+
+ if (ping_valid_trns != 0)
+ {
+ ping_trans_alpha=MagickAllocateMemory(
+ unsigned char *, number_colors);
+ if (ping_trans_alpha == (unsigned char *) NULL)
+ png_error(ping, "Could not allocate trans_alpha");
+
+ for (i=0; i<(int) number_colors; i++)
+ if (trans_alpha[i] == 256)
+ ping_trans_alpha[i]=255;
+ else
+ ping_trans_alpha[i]=(png_byte) trans_alpha[i];
+ (void) LogMagickEvent(CoderEvent, GetMagickModule(),
+ " Alpha[%d]=%d",(int) i, (int) trans_alpha[i]);
+ }
+ }
+
+ /*
+ Identify which colormap entry is the background color.
+ */
+ for (i=0; i < (long) Max(number_colors-1,1); i++)
+ if (RGBColorMatchExact(ping_background,
+ image->colormap[i]))
+ break;
+ ping_background.index=(png_uint_16) i;
+ }
+ }
+ else
+ {
+ if (image_depth < 8)
+ image_depth=8;
+ if ((save_image_depth == 16) && (image_depth == 8))
+ {
+ ping_trans_color.red*=0x0101;
+ ping_trans_color.green*=0x0101;
+ ping_trans_color.blue*=0x0101;
+ ping_trans_color.gray*=0x0101;
+ }
+ }
+
+ /*
+ Adjust background and transparency samples in sub-8-bit
+ grayscale files.
+ */
+ if (ping_bit_depth < 8 && ping_colortype ==
+ PNG_COLOR_TYPE_GRAY)
+ {
+ png_uint_16
+ maxval;
+
+ maxval=(1 << ping_bit_depth)-1;
+
+ ping_trans_color.gray=(png_uint_16)(maxval*
+ ping_trans_color.gray/
+ MaxRGB);
+ }
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG color type: %s (%d)",
+ PngColorTypeToString(ping_colortype),
+ ping_colortype);
+ /*
+ Initialize compression level and filtering.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up deflate compression");
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression buffer size: 32768");
+ png_set_compression_buffer_size(ping,32768L);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression mem level: 9");
+ png_set_compression_mem_level(ping, 9);
+ if (image_info->quality > 9)
+ {
+ int
+ level;
+
+ level=(int) Min(image_info->quality/10,9);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression level: %d",level);
+ png_set_compression_level(ping,level);
+ }
+ else
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Compression strategy: Z_HUFFMAN_ONLY");
+ png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
+ png_set_compression_level(ping,2);
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up filtering");
+#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
+
+ /* This became available in libpng-1.0.9. Output must be a MNG. */
+ if (mng_info->write_mng && ((image_info->quality % 10) == 7))
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
+ ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
+ }
+ else
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Filter_type: 0");
+#endif
+ {
+ int
+ base_filter;
+
+ if ((image_info->quality % 10) > 5)
+ base_filter=PNG_ALL_FILTERS;
+ else
+ if ((image_info->quality % 10) != 5)
+ base_filter=(int) image_info->quality % 10;
+ else
+ if ((ping_colortype == PNG_COLOR_TYPE_GRAY) ||
+ (ping_colortype == PNG_COLOR_TYPE_PALETTE) ||
+ (image_info->quality < 50))
+ base_filter=PNG_NO_FILTERS;
+ else
+ base_filter=PNG_ALL_FILTERS;
+ if (logging)
+ {
+ if (base_filter == PNG_ALL_FILTERS)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Base filter method: ADAPTIVE");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Base filter method: NONE");
+ }
+ png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
+ }
+
+ ping_interlace_method=(image_info->interlace == LineInterlace);
+
+ if (mng_info->write_mng)
+ png_set_sig_bytes(ping,8);
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing PNG header chunks");
+
+ png_set_IHDR(ping,ping_info,
+ ping_width,
+ ping_height,
+ ping_bit_depth,
+ ping_colortype,
+ ping_interlace_method,
+ ping_compression_method,
+ ping_filter_method);
+
+ if (ping_colortype == 3 && ping_valid_trns != 0)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up tRNS chunk");
+ (void) png_set_tRNS(ping, ping_info,
+ ping_trans_alpha,
+ ping_num_trans,
+ &ping_trans_color);
+ }
+
+ MagickFreeMemory(ping_trans_alpha);
+
+ if (image_matte && (!mng_info->adjoin || !mng_info->equal_backgrounds))
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up bKGD chunk");
+ if (ping_bit_depth < 8 && ping_colortype == PNG_COLOR_TYPE_GRAY)
+ {
+ png_uint_16
+ maxval;
+
+ png_color_16
+ background;
+
+ maxval=(1 << ping_bit_depth)-1;
+
+
+ background.gray=(png_uint_16)
+ (maxval*(PixelIntensity(&image->background_color))/MaxRGB);
+
+ png_set_bKGD(ping,ping_info,&background);
+ }
+
+ else
+ {
+ png_color_16
+ background;
+
+ if (image_depth < QuantumDepth)
+ {
+ int
+ maxval;
+
+ maxval=(1 << image_depth)-1;
+ background.red=(png_uint_16)
+ (maxval*image->background_color.red/MaxRGB);
+ background.green=(png_uint_16)
+ (maxval*image->background_color.green/MaxRGB);
+ background.blue=(png_uint_16)
+ (maxval*image->background_color.blue/MaxRGB);
+ background.gray=(png_uint_16)
+ (maxval*PixelIntensity(&image->background_color)/MaxRGB);
+ }
+ else
+ {
+ background.red=image->background_color.red;
+ background.green=image->background_color.green;
+ background.blue=image->background_color.blue;
+ background.gray=
+ (png_uint_16) PixelIntensity(&image->background_color);
+ }
+ background.index=(png_byte) background.gray;
+ png_set_bKGD(ping,ping_info,&background);
+ }
+ }
+
+#if defined(PNG_pHYs_SUPPORTED)
+ if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
+ (!mng_info->write_mng || !mng_info->equal_physs))
+ {
+ int
+ unit_type;
+
+ png_uint_32
+ x_resolution,
+ y_resolution;
+
+ if (image->units == PixelsPerInchResolution)
+ {
+ unit_type=PNG_RESOLUTION_METER;
+ x_resolution=(png_uint_32) ((100.0*image->x_resolution+0.5)/2.54);
+ y_resolution=(png_uint_32) ((100.0*image->y_resolution+0.5)/2.54);
+ }
+ else if (image->units == PixelsPerCentimeterResolution)
+ {
+ unit_type=PNG_RESOLUTION_METER;
+ x_resolution=(png_uint_32) (100.0*image->x_resolution+0.5);
+ y_resolution=(png_uint_32) (100.0*image->y_resolution+0.5);
+ }
+ else
+ {
+ unit_type=PNG_RESOLUTION_UNKNOWN;
+ x_resolution=(png_uint_32) image->x_resolution;
+ y_resolution=(png_uint_32) image->y_resolution;
+ }
+
+ png_set_pHYs(ping,ping_info,x_resolution,y_resolution,unit_type);
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up pHYs chunk");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " x_resolution=%lu",(unsigned long) x_resolution);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " y_resolution=%lu",(unsigned long) y_resolution);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " unit_type=%lu",(unsigned long) unit_type);
+ }
+ }
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
+ if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
+ {
+ if (!((image->page.width != 0 && image->page.width != image->columns) ||
+ (image->page.height != 0 && image->page.height != image->rows)))
+ {
+ png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
+ (png_int_32) image->page.y, 0);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up oFFs chunk");
+ }
+ /* else write caNv instead, later */
+ }
+#endif
+
+ {
+ ImageProfileIterator
+ *profile_iterator;
+
+ profile_iterator=AllocateImageProfileIterator(image);
+ if (profile_iterator)
+ {
+ const char
+ *profile_name;
+
+ const unsigned char
+ *profile_info;
+
+ size_t
+ profile_length;
+
+ while (NextImageProfile(profile_iterator,&profile_name,&profile_info,
+ &profile_length) != MagickFail)
+ {
+ if (LocaleCompare(profile_name,"ICM") == 0)
+ {
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up iCCP chunk");
+
+ png_set_iCCP(ping,ping_info,(png_charp) "icm",
+ (int) 0,
+#if (PNG_LIBPNG_VER < 10500)
+ (png_charp) profile_info,
+#else
+ (png_const_bytep) profile_info,
+#endif
+
+ (png_uint_32) profile_length);
+ }
+#else
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up text chunk with"
+ " iCCP Profile");
+ png_write_raw_profile(image_info,ping,ping_info,
+ "icm",
+ "ICC Profile",
+ profile_info,
+ (png_uint_32) profile_length);
+ }
+#endif
+ }
+ else if (LocaleCompare(profile_name,"IPTC") == 0)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up text chunk with"
+ " iPTC Profile");
+ png_write_raw_profile(image_info,ping,ping_info,
+ "iptc",
+ "IPTC profile",
+ profile_info,
+ (png_uint_32) profile_length);
+ }
+#ifdef exIf_SUPPORTED
+ else if (LocaleCompare(profile_name,"exif") == 0)
+ /* Do not write exif; we'll write it later as exIf */
+ ;
+#endif
+ else
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up text chunk with"
+ " %s profile",
+ profile_name);
+ png_write_raw_profile(image_info,ping,ping_info,
+ profile_name,
+ "generic profile",
+ profile_info,
+ (png_uint_32) profile_length);
+ }
+ }
+
+ DeallocateImageProfileIterator(profile_iterator);
+ }
+ }
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+ if (!mng_info->have_write_global_srgb &&
+ ((image->rendering_intent != UndefinedIntent) ||
+ image_info->colorspace == sRGBColorspace))
+ {
+ /*
+ Note image rendering intent.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up sRGB chunk");
+ if (image->rendering_intent != UndefinedIntent)
+ (void) png_set_sRGB(ping,ping_info,(int) (image->rendering_intent-1));
+ else
+ (void) png_set_sRGB(ping,ping_info,PerceptualIntent);
+ png_set_gAMA(ping,ping_info,0.45455);
+ }
+ if ((!mng_info->write_mng) ||
+ !png_get_valid(ping, ping_info, PNG_INFO_sRGB))
+#endif
+ {
+ if (!mng_info->have_write_global_gama && (image->gamma != 0.0))
+ {
+ /*
+ Note image gamma.
+ To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up gAMA chunk");
+ png_set_gAMA(ping,ping_info,image->gamma);
+ }
+ if (!mng_info->have_write_global_chrm &&
+ (image->chromaticity.red_primary.x != 0.0))
+ {
+ /*
+ Note image chromaticity.
+ To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
+ */
+ PrimaryInfo
+ bp,
+ gp,
+ rp,
+ wp;
+
+ wp=image->chromaticity.white_point;
+ rp=image->chromaticity.red_primary;
+ gp=image->chromaticity.green_primary;
+ bp=image->chromaticity.blue_primary;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up cHRM chunk");
+ png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
+ bp.x,bp.y);
+ }
+ }
+
+ png_write_info(ping,ping_info);
+
+ /* write orNT if image->orientation is defined and not TopLeft */
+ if (image->orientation > 1 && image->orientation < 9)
+ {
+ unsigned char
+ chunk[6];
+ (void) WriteBlobMSBULong(image,1L); /* data length=1 */
+ PNGType(chunk,mng_orNT);
+ LogPNGChunk(logging,mng_orNT,1L);
+ chunk[4]=image->orientation;
+ (void) WriteBlob(image,5,chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
+ }
+
+ /* write caNv chunk */
+ if ((image->page.width != 0 && image->page.width != image->columns) ||
+ (image->page.height != 0 && image->page.height != image->rows) ||
+ image->page.x != 0 || image->page.y != 0)
+ {
+ unsigned char
+ chunk[22];
+
+ (void) WriteBlobMSBULong(image,16L); /* data length=16 */
+ PNGType(chunk,mng_caNv);
+ LogPNGChunk(logging,mng_caNv,16L);
+ PNGLong(chunk+4,(png_uint_32) image->page.width);
+ PNGLong(chunk+8,(png_uint_32) image->page.height);
+ PNGsLong(chunk+12,(png_int_32) image->page.x);
+ PNGsLong(chunk+16,(png_int_32) image->page.y);
+ (void) WriteBlob(image,20,chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
+ }
+
+#if (PNG_LIBPNG_VER == 10206)
+ /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
+#define PNG_HAVE_IDAT 0x04
+ ping->mode |= PNG_HAVE_IDAT;
+#undef PNG_HAVE_IDAT
+#endif
+
+ png_set_packing(ping);
+ /*
+ Allocate memory.
+ */
+ rowbytes=image->columns;
+ if (image_depth <= 8)
+ {
+ if (mng_info->write_png24)
+ rowbytes*=3;
+ else if (mng_info->write_png32)
+ rowbytes*=4;
+ else if (!mng_info->write_png8 && (mng_info->IsPalette &&
+ IsGrayImage(image,&image->exception)))
+ rowbytes*=(image_matte ? 2 : 1);
+ else
+ {
+ if (!mng_info->IsPalette)
+ rowbytes*=(image_matte ? 4 : 3);
+ }
+ }
+ else
+ {
+ if (mng_info->write_png48)
+ rowbytes*=6;
+
+ else if (mng_info->write_png64)
+ rowbytes*=8;
+
+ else if (mng_info->IsPalette &&
+ IsGrayImage(image,&image->exception))
+ rowbytes*=(image_matte ? 4 : 2);
+
+ else
+ rowbytes*=(image_matte ? 8 : 6);
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Allocating %lu bytes of memory for pixels",
+ rowbytes);
+ png_pixels=MagickAllocateMemory(unsigned char *,rowbytes);
+ if (png_pixels == (unsigned char *) NULL)
+ png_error(ping, "Could not allocate png_pixels");
+ /*
+ Initialize image scanlines.
+ */
+ num_passes=png_set_interlace_handling(ping);
+ if ((!mng_info->write_png8 && !mng_info->write_png24 &&
+ !mng_info->write_png32 && !mng_info->write_png48 &&
+ !mng_info->write_png64) && (mng_info->IsPalette ||
+ image_info->type == BilevelType) &&
+ !image_matte &&
+ IsMonochromeImage(image,&image->exception))
+ for (pass=0; pass < num_passes; pass++)
+ {
+ /*
+ Convert PseudoClass image to a PNG monochrome image.
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " pass %d, Image Is Monochrome",pass);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (!AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception))
+ break;
+ if (mng_info->IsPalette)
+ (void) ExportImagePixelArea(image,(QuantumType) GrayQuantum,
+ quantum_size,png_pixels,0,0);
+ else
+ (void) ExportImagePixelArea(image,(QuantumType) RedQuantum,
+ quantum_size,png_pixels,0,0);
+ for (i=0; i < (long) image->columns; i++)
+ *(png_pixels+i)=(*(png_pixels+i) > 128) ? 255 : 0;
+ png_write_row(ping,png_pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick((magick_uint64_t) y*(pass+1),
+ (magick_uint64_t) image->rows * num_passes))
+ if (!MagickMonitorFormatted((magick_uint64_t) y*(pass+1),
+ (magick_uint64_t) image->rows*
+ num_passes,
+ &image->exception,
+ SaveImageTag,
+ image->filename,
+ image->columns,image->rows))
+ break;
+
+ }
+ }
+ else
+ for (pass=0; pass < num_passes; pass++)
+ {
+ if ((!mng_info->write_png8 && !mng_info->write_png24 &&
+ !mng_info->write_png32 && !mng_info->write_png48 &&
+ !mng_info->write_png64) &&
+ (!image_matte || (ping_bit_depth >= QuantumDepth)) &&
+ mng_info->IsPalette &&
+ IsGrayImage(image,&image->exception))
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " pass %d, Image Is Gray",pass);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (!AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception))
+ break;
+ if (ping_colortype == PNG_COLOR_TYPE_GRAY)
+ {
+ if (mng_info->IsPalette)
+ (void) ExportImagePixelArea(image,
+ (QuantumType) GrayQuantum,
+ quantum_size,png_pixels,0,0);
+ else
+ (void) ExportImagePixelArea(image,
+ (QuantumType) RedQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ }
+ else if (ping_colortype == PNG_COLOR_TYPE_PALETTE)
+ {
+ (void) ExportImagePixelArea(image,(QuantumType)
+ IndexQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ }
+ else /* PNG_COLOR_TYPE_GRAY_ALPHA */
+ {
+ (void) ExportImagePixelArea(image,(QuantumType)
+ GrayAlphaQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ }
+ png_write_row(ping,png_pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick((magick_uint64_t) y*(pass+1),
+ (magick_uint64_t) image->rows * num_passes))
+ if (!MagickMonitorFormatted((magick_uint64_t) y*(pass+1),
+ (magick_uint64_t) image->rows*
+ num_passes,
+ &image->exception,SaveImageTag,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ for (pass=0; pass < num_passes; pass++)
+ {
+ if ((image_depth > 8) ||
+ (mng_info->write_png24 || mng_info->write_png32 ||
+ mng_info->write_png48 || mng_info->write_png64 ||
+ (!mng_info->write_png8 && !mng_info->IsPalette)))
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " pass %d, Image Is RGB,"
+ " PNG colortype is %s (%d)",pass,
+ PngColorTypeToString(
+ ping_colortype),
+ ping_colortype);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (!AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception))
+ break;
+ if (ping_colortype == PNG_COLOR_TYPE_GRAY)
+ {
+ if (image->storage_class == DirectClass)
+ (void) ExportImagePixelArea(image,(QuantumType)
+ RedQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ else
+ (void) ExportImagePixelArea(image,(QuantumType)
+ GrayQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ }
+ else if (ping_colortype ==
+ PNG_COLOR_TYPE_GRAY_ALPHA)
+ (void) ExportImagePixelArea(image,(QuantumType)
+ GrayAlphaQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ else if (image_matte)
+ (void) ExportImagePixelArea(image,(QuantumType)
+ RGBAQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ else
+ {
+ (void) ExportImagePixelArea(image,(QuantumType)
+ RGBQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ }
+ png_write_row(ping,png_pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick((magick_uint64_t) y * (pass+1),
+ (magick_uint64_t) image->rows *
+ num_passes))
+ if (!MagickMonitorFormatted((magick_uint64_t)
+ y*(pass+1),
+ (magick_uint64_t)
+ image->rows*num_passes,
+ &image->exception,
+ SaveImageTag,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " pass %d done",pass);
+ }
+ else
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " pass %d, Image Is RGB,"
+ " 16-bit GRAY, or GRAY_ALPHA",pass);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (!AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception))
+ break;
+ if (ping_colortype == PNG_COLOR_TYPE_GRAY)
+ (void) ExportImagePixelArea(image,(QuantumType)
+ GrayQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ else if (ping_colortype ==
+ PNG_COLOR_TYPE_GRAY_ALPHA)
+ (void) ExportImagePixelArea(image,(QuantumType)
+ GrayAlphaQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ else
+ (void) ExportImagePixelArea(image,(QuantumType)
+ IndexQuantum,
+ quantum_size,
+ png_pixels,0,0);
+ png_write_row(ping,png_pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick((magick_uint64_t) y * (pass+1),
+ (magick_uint64_t) image->rows *
+ num_passes))
+ if (!MagickMonitorFormatted((magick_uint64_t)
+ y*(pass+1),
+ (magick_uint64_t)
+ image->rows*num_passes,
+ &image->exception,
+ SaveImageTag,
+ image->filename,
+ image->columns,
+ image->rows))
+ break;
+ }
+ }
+ }
+ }
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing PNG image data");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Width: %lu",
+ (unsigned long)ping_width);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Height: %lu",
+ (unsigned long)ping_height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG sample depth: %d",ping_bit_depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG color type: %s (%d)",
+ PngColorTypeToString(ping_colortype),
+ ping_colortype);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " PNG Interlace method: %d",
+ ping_interlace_method);
+ }
+ /*
+ Generate text chunks.
+ */
+ attribute=GetImageAttribute(image,(char *) NULL);
+ for ( ; attribute != (const ImageAttribute *) NULL;
+ attribute=attribute->next)
+ {
+ png_textp
+ text;
+
+ if (*attribute->key == '[')
+ continue;
+ if (LocaleCompare(attribute->key,"png:IHDR.color-type-orig") == 0 ||
+ LocaleCompare(attribute->key,"png:IHDR.bit-depth-orig") == 0)
+ continue;
+#if PNG_LIBPNG_VER >= 14000
+ text=(png_textp) png_malloc(ping,
+ (png_alloc_size_t) sizeof(png_text));
+#else
+ text=(png_textp) png_malloc(ping,(png_size_t) sizeof(png_text));
+#endif
+ text[0].key=attribute->key;
+ text[0].text=attribute->value;
+ text[0].text_length=strlen(attribute->value);
+ text[0].compression=image_info->compression == NoCompression ||
+ (image_info->compression == UndefinedCompression &&
+ text[0].text_length < 128) ? -1 : 0;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Setting up text chunk");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " keyword: %s",text[0].key);
+ }
+ png_set_text(ping,ping_info,text,1);
+ png_free(ping,text);
+ }
+
+#if defined(exIf_SUPPORTED) || \
+ defined(eXIf_SUPPORTED)
+ /* write exIf profile */
+ {
+ ImageProfileIterator
+ *profile_iterator;
+
+ profile_iterator=AllocateImageProfileIterator(image);
+ if (profile_iterator)
+ {
+ const char
+ *profile_name;
+
+ const unsigned char
+ *profile_info;
+
+ size_t
+ profile_length;
+
+ while (NextImageProfile(profile_iterator,&profile_name,&profile_info,
+ &profile_length) != MagickFail)
+ {
+ if (LocaleCompare(profile_name,"exif") == 0)
+ {
+ png_uint_32
+ length;
+ unsigned char
+ chunk[4];
+ const unsigned char
+ *data;
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Have eXIf profile");
+
+ data=profile_info;
+
+ length=(png_uint_32) profile_length;
+
+#ifdef eXIf_SUPPORTED /* eXIf chunk is registered */
+ PNGType(chunk,mng_eXIf);
+#else /* eXIf chunk not yet registered; write exIf instead */
+ PNGType(chunk,mng_exIf);
+#endif
+
+ if (length < 7)
+ break; /* othewise crashes */
+
+ /* skip the "Exif\0\0" JFIF Exif Header ID */
+ length -= 6;
+
+ LogPNGChunk(logging,chunk,length);
+ (void) WriteBlobMSBULong(image,length);
+ (void) WriteBlob(image,4,chunk);
+ (void) WriteBlob(image,length,data+6);
+ (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),
+ data+6, (uInt) length));
+ break;
+ }
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+ }
+ }
+#endif /* exIf_SUPPORTED) */
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing PNG end info");
+ png_write_end(ping,ping_info);
+ if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
+ {
+ if (mng_info->page.x || mng_info->page.y || (ping_width !=
+ mng_info->page.width) ||
+ (ping_height != mng_info->page.height))
+ {
+ unsigned char
+ chunk[32];
+
+ /*
+ Write FRAM 4 with clipping boundaries followed by FRAM 1.
+ */
+ (void) WriteBlobMSBULong(image,27L); /* data length=27 */
+ PNGType(chunk,mng_FRAM);
+ LogPNGChunk(logging,mng_FRAM,27L);
+ chunk[4]=4;
+ chunk[5]=0; /* frame name separator (no name) */
+ chunk[6]=1; /* flag for changing delay, for next frame only */
+ chunk[7]=0; /* flag for changing frame timeout */
+ chunk[8]=1; /* flag for changing frame clipping for next frame */
+ chunk[9]=0; /* flag for changing frame sync_id */
+ PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
+ chunk[14]=0; /* clipping boundaries delta type */
+ PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
+ PNGLong(chunk+19,(png_uint_32) (mng_info->page.x +
+ ping_width));
+ PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
+ PNGLong(chunk+27,(png_uint_32) (mng_info->page.y +
+ ping_height));
+ (void) WriteBlob(image,31,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
+ mng_info->old_framing_mode=4;
+ mng_info->framing_mode=1;
+ }
+ else
+ mng_info->framing_mode=3;
+ }
+ if (mng_info->write_mng && !mng_info->need_fram &&
+ ((int) image->dispose == 3))
+ png_error(ping, "Cannot convert GIF with disposal method 3 to MNG-LC");
+ image->depth=save_image_depth;
+
+ /* Save depth actually written */
+
+ s[0]=(char) ping_bit_depth;
+ s[1]='\0';
+
+ (void) SetImageAttribute(image,"[png:bit-depth-written]",s);
+
+ /*
+ Free PNG resources.
+ */
+ png_destroy_write_struct(&ping,&ping_info);
+
+ MagickFreeMemory(png_pixels);
+
+#if defined(GMPNG_SETJMP_NOT_THREAD_SAFE)
+ UnlockSemaphoreInfo(png_semaphore);
+#endif
+
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " exit WriteOnePNGImage()");
+ return (MagickPass);
+
+ /* } end of setjmp-controlled block */
+
+ /* End write one PNG image */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WritePNGImage() writes a Portable Network Graphics (PNG) or
+% Multiple-image Network Graphics (MNG) image file.
+%
+% MNG support written by Glenn Randers-Pehrson, glennrp@image...
+%
+% The format of the WritePNGImage method is:
+%
+% MagickPassFail WritePNGImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o image_info: the image info.
+%
+% o image: The image.
+%
+% Returns MagickPass on success, MagickFail on failure.
+%
+% While the datastream written is always in PNG format and normally
+% would be given the "png" file extension, this method also writes
+% the following pseudo-formats which are subsets of PNG:
+%
+% o PNG8: An 8-bit indexed PNG datastream is written.
+% If transparency is present, the tRNS chunk
+% must only have values 0 and 255 (i.e., transparency is binary:
+% fully opaque or fully transparent). The pixels contain 8-bit
+% indices even if they could be represented with 1, 2, or 4 bits.
+% Note: grayscale images will be written as indexed PNG files
+% even though the PNG grayscale type might be slightly more
+% efficient.
+%
+% o PNG24: An 8-bit per sample RGB PNG datastream is written. The tRNS
+% chunk can be present to convey binary transparency by naming
+% one of the colors as transparent.
+%
+% o PNG32: An 8-bit per sample RGBA PNG is written. Partial
+% transparency is permitted, i.e., the alpha sample for
+% each pixel can have any value from 0 to 255. The alpha
+% channel is present even if the image is fully opaque.
+%
+% o PNG48: A 16-bit per sample RGB PNG datastream is written. The tRNS
+% chunk can be present to convey binary transparency by naming
+% one of the colors as transparent. If the image has more
+% than one transparent color, has semitransparent pixels, or
+% has an opaque pixel with the same RGB components as the
+% transparent color, an image is not written.
+%
+% o PNG64: A 16-bit per sample RGBA PNG is written. Partial
+% transparency is permitted, i.e., the alpha sample for
+% each pixel can have any value from 0 to 65535. The alpha
+% channel is present even if the image is fully opaque.
+%
+% o PNG00: A PNG that inherits its colortype and bit-depth from the input
+% image, if the input was a PNG, is written. If these values
+% cannot be found, then "PNG00" falls back to the regular "PNG"
+% format.
+%
+% If the image cannot be written in the requested PNG8|24|32|48|64
+% format without loss, a PNG file will not be written, and MagickFail
+% will be returned. Since image encoders should not be responsible for
+% the "heavy lifting", the user should make sure that GraphicsMagick has
+% already reduced the image depth and number of colors and limit
+% transparency to binary transparency prior to attempting to write the
+% image in a format that is subject to depth, color, or transparency
+% limitations.
+%
+% TODO: Enforce the previous paragraph.
+%
+% TODO: Allow all other PNG subformats to be requested via new
+% "-define png:bit-depth -define png:color-type" options.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+static MagickPassFail WritePNGImage(const ImageInfo *image_info,Image *image)
+{
+ MngInfo
+ *mng_info;
+
+ int
+ have_mng_structure;
+
+ unsigned int
+ logging,
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFalse)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Allocate a MngInfo structure.
+ */
+ have_mng_structure=MagickFalse;
+ mng_info=MagickAllocateMemory(MngInfo *,sizeof(MngInfo));
+ if (mng_info == (MngInfo *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize members of the MngInfo structure.
+ */
+ (void) memset(mng_info,0,sizeof(MngInfo));
+ mng_info->image=image;
+ have_mng_structure=MagickTrue;
+ mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
+ mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
+ mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
+ mng_info->write_png48=LocaleCompare(image_info->magick,"PNG48") == 0;
+ mng_info->write_png64=LocaleCompare(image_info->magick,"PNG64") == 0;
+
+ if (LocaleCompare(image_info->magick,"png00") == 0)
+ {
+ const ImageAttribute
+ *attribute;
+
+ /* Retrieve png:IHDR.bit-depth-orig and png:IHDR.color-type-orig */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Format=%s",image_info->magick);
+
+ attribute=GetImageAttribute(image,"png:IHDR.bit-depth-orig");
+
+ if (attribute != (ImageAttribute *) NULL)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " png00 inherited bit depth=%s",attribute->value);
+
+ if (LocaleCompare(attribute->value,"1") == 0)
+ mng_info->write_png_depth = 1;
+
+ else if (LocaleCompare(attribute->value,"1") == 0)
+ mng_info->write_png_depth = 2;
+
+ else if (LocaleCompare(attribute->value,"2") == 0)
+ mng_info->write_png_depth = 4;
+
+ else if (LocaleCompare(attribute->value,"8") == 0)
+ mng_info->write_png_depth = 8;
+
+ else if (LocaleCompare(attribute->value,"16") == 0)
+ mng_info->write_png_depth = 16;
+ }
+
+ attribute=GetImageAttribute(image,"png:IHDR.color-type-orig");
+
+ if (attribute != (ImageAttribute *) NULL)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " png00 inherited color type=%s",attribute->value);
+
+ if (LocaleCompare(attribute->value,"0") == 0)
+ mng_info->write_png_colortype = 1;
+
+ else if (LocaleCompare(attribute->value,"2") == 0)
+ mng_info->write_png_colortype = 3;
+
+ else if (LocaleCompare(attribute->value,"3") == 0)
+ mng_info->write_png_colortype = 4;
+
+ else if (LocaleCompare(attribute->value,"4") == 0)
+ mng_info->write_png_colortype = 5;
+
+ else if (LocaleCompare(attribute->value,"6") == 0)
+ mng_info->write_png_colortype = 7;
+ }
+ }
+
+ status=WriteOnePNGImage(mng_info,image_info,image);
+
+ CloseBlob(image);
+
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
+ return (status);
+}
+
+#if defined(JNG_SUPPORTED)
+
+/* Write one JNG image */
+static MagickPassFail WriteOneJNGImage(MngInfo *mng_info,
+ const ImageInfo *image_info,Image *image)
+{
+ Image
+ *jpeg_image;
+
+ ImageInfo
+ *jpeg_image_info;
+
+ char
+ *blob;
+
+ size_t
+ length;
+
+ unsigned char
+ chunk[80],
+ *p;
+
+ unsigned int
+ jng_alpha_compression_method,
+ jng_alpha_sample_depth,
+ jng_color_type,
+ logging,
+ status,
+ transparent;
+
+ unsigned long
+ jng_quality;
+
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),
+ " enter WriteOneJNGImage()");
+
+ if (image->columns > 65535 || image->rows > 65535)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG dimensions too large");
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+
+ blob=(char *) NULL;
+ jpeg_image=(Image *) NULL;
+ jpeg_image_info=(ImageInfo *) NULL;
+
+ status=MagickTrue;
+ transparent=image_info->type==GrayscaleMatteType ||
+ image_info->type==TrueColorMatteType;
+ jng_color_type=10;
+ jng_alpha_sample_depth=0;
+ jng_quality=image_info->quality;
+ jng_alpha_compression_method=0;
+
+ if (image->matte)
+ {
+ /* if any pixels are transparent */
+ transparent=MagickTrue;
+ if (image_info->compression==JPEGCompression)
+ jng_alpha_compression_method=8;
+ }
+
+ if (transparent)
+ {
+ jng_color_type=14;
+ /* Create JPEG blob, image, and image_info */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating jpeg_image_info for opacity.");
+ jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
+ if (jpeg_image_info == (ImageInfo *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating jpeg_image.");
+ jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
+ if (jpeg_image == (Image *) NULL)
+ {
+ if (jpeg_image_info != (ImageInfo *)NULL)
+ {
+ DestroyImageInfo(jpeg_image_info);
+ }
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ DestroyBlob(jpeg_image);
+ jpeg_image->blob=CloneBlobInfo((BlobInfo *) NULL);
+ status=ChannelImage(jpeg_image,OpacityChannel);
+ if (status != MagickFalse)
+ status=NegateImage(jpeg_image,MagickFalse);
+ if (status == MagickFalse)
+ {
+ DestroyImage(jpeg_image);
+ DestroyImageInfo(jpeg_image_info);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ jpeg_image->matte=MagickFalse;
+ if (jng_quality >= 1000)
+ jpeg_image_info->quality=jng_quality/1000;
+ else
+ jpeg_image_info->quality=jng_quality;
+ jpeg_image_info->type=GrayscaleType;
+ (void) SetImageType(jpeg_image,GrayscaleType);
+ (void) AcquireUniqueFilename(jpeg_image->filename);
+ FormatString(jpeg_image_info->filename,"%.1024s",
+ jpeg_image->filename);
+ }
+
+ /* To do: check bit depth of PNG alpha channel */
+
+ /* Check if image is grayscale. */
+ if (image_info->type != TrueColorMatteType && image_info->type !=
+ TrueColorType && IsGrayImage(image,&image->exception))
+ jng_color_type-=2;
+
+ if (transparent)
+ {
+ if (jng_alpha_compression_method==0)
+ {
+ const ImageAttribute
+ *attribute;
+
+ /* Encode opacity as a grayscale PNG blob */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating PNG blob.");
+ status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status != MagickFalse)
+ {
+ length=0;
+
+ (void) strlcpy(jpeg_image_info->magick,"PNG",MaxTextExtent);
+ (void) strlcpy(jpeg_image->magick,"PNG",MaxTextExtent);
+ jpeg_image_info->interlace=NoInterlace;
+
+ blob=(char *) ImageToBlob(jpeg_image_info,jpeg_image,&length,
+ &image->exception);
+
+ /* Retrieve sample depth used */
+ attribute=GetImageAttribute(jpeg_image,"[png:bit-depth-written]");
+ if ((attribute != (const ImageAttribute *) NULL) &&
+ (attribute->value != (char *) NULL))
+ jng_alpha_sample_depth= (unsigned int) attribute->value[0];
+ }
+ }
+ else
+ {
+ /* Encode opacity as a grayscale JPEG blob */
+
+ status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status != MagickFalse)
+ {
+ (void) strlcpy(jpeg_image_info->magick,"JPEG",MaxTextExtent);
+ (void) strlcpy(jpeg_image->magick,"JPEG",MaxTextExtent);
+ jpeg_image_info->interlace=NoInterlace;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating blob.");
+ blob=(char *) ImageToBlob(jpeg_image_info,jpeg_image,&length,
+ &image->exception);
+ jng_alpha_sample_depth=8;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Successfully read jpeg_image into a"
+ " blob, length=%lu.",
+ (unsigned long) length);
+
+ }
+ }
+ /* Destroy JPEG image and image_info */
+ (void) LiberateUniqueFileResource(jpeg_image_info->filename);
+ DestroyImage(jpeg_image);
+ DestroyImageInfo(jpeg_image_info);
+ if (status == MagickFalse)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+
+ /* Write JHDR chunk */
+ (void) WriteBlobMSBULong(image,16L); /* chunk data length=16 */
+ PNGType(chunk,mng_JHDR);
+ LogPNGChunk(logging,mng_JHDR,16L);
+ PNGLong(chunk+4,image->columns);
+ PNGLong(chunk+8,image->rows);
+ chunk[12]=jng_color_type;
+ chunk[13]=8; /* sample depth */
+ chunk[14]=8; /*jng_image_compression_method */
+ chunk[15]=(image_info->interlace == LineInterlace) ? 8 : 0;
+ chunk[16]=jng_alpha_sample_depth;
+ chunk[17]=jng_alpha_compression_method;
+ chunk[18]=0; /*jng_alpha_filter_method */
+ chunk[19]=0; /*jng_alpha_interlace_method */
+ (void) WriteBlob(image,20,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG width:%15lu",image->columns);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG height:%14lu",image->rows);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG color type:%10d",jng_color_type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG sample depth:%8d",8);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG compression:%9d",8);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG interlace:%11d",0);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG alpha depth:%9d",jng_alpha_sample_depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG alpha compression:%3d",
+ jng_alpha_compression_method);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG alpha filter:%8d",0);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " JNG alpha interlace:%5d",0);
+ }
+
+ /*
+ Write leading ancillary chunks
+ */
+
+ if (transparent)
+ {
+ /*
+ Write JNG bKGD chunk
+ */
+
+ char
+ blue,
+ green,
+ red;
+
+ long
+ num_bytes;
+
+ if (jng_color_type == 8 || jng_color_type == 12)
+ num_bytes=6L;
+ else
+ num_bytes=10L;
+ (void) WriteBlobMSBULong(image,num_bytes-4L);
+ PNGType(chunk,mng_bKGD);
+ LogPNGChunk(logging,mng_bKGD,num_bytes-4L);
+ red=ScaleQuantumToChar(image->background_color.red);
+ green=ScaleQuantumToChar(image->background_color.green);
+ blue=ScaleQuantumToChar(image->background_color.blue);
+ *(chunk+4)=0;
+ *(chunk+5)=red;
+ *(chunk+6)=0;
+ *(chunk+7)=green;
+ *(chunk+8)=0;
+ *(chunk+9)=blue;
+ (void) WriteBlob(image,num_bytes,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,num_bytes));
+ }
+
+ if ((image_info->colorspace == sRGBColorspace || image->rendering_intent))
+ {
+ /*
+ Write JNG sRGB chunk
+ */
+ (void) WriteBlobMSBULong(image,1L);
+ PNGType(chunk,mng_sRGB);
+ LogPNGChunk(logging,mng_sRGB,1L);
+ if (image->rendering_intent != UndefinedIntent)
+ chunk[4]=(int) image->rendering_intent-1;
+ else
+ chunk[4]=(int) PerceptualIntent-1;
+ (void) WriteBlob(image,5,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
+ }
+ else
+ {
+ if (image->gamma)
+ {
+ /*
+ Write JNG gAMA chunk
+ */
+ (void) WriteBlobMSBULong(image,4L);
+ PNGType(chunk,mng_gAMA);
+ LogPNGChunk(logging,mng_gAMA,4L);
+ PNGLong(chunk+4,(unsigned long) (100000*image->gamma+0.5));
+ (void) WriteBlob(image,8,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
+ }
+ if (!mng_info->equal_chrms && image->chromaticity.red_primary.x != 0.0)
+ {
+ PrimaryInfo
+ primary;
+
+ /*
+ Write JNG cHRM chunk
+ */
+ (void) WriteBlobMSBULong(image,32L);
+ PNGType(chunk,mng_cHRM);
+ LogPNGChunk(logging,mng_cHRM,32L);
+ primary=image->chromaticity.white_point;
+ PNGLong(chunk+4,(unsigned long) (100000*primary.x+0.5));
+ PNGLong(chunk+8,(unsigned long) (100000*primary.y+0.5));
+ primary=image->chromaticity.red_primary;
+ PNGLong(chunk+12,(unsigned long) (100000*primary.x+0.5));
+ PNGLong(chunk+16,(unsigned long) (100000*primary.y+0.5));
+ primary=image->chromaticity.green_primary;
+ PNGLong(chunk+20,(unsigned long) (100000*primary.x+0.5));
+ PNGLong(chunk+24,(unsigned long) (100000*primary.y+0.5));
+ primary=image->chromaticity.blue_primary;
+ PNGLong(chunk+28,(unsigned long) (100000*primary.x+0.5));
+ PNGLong(chunk+32,(unsigned long) (100000*primary.y+0.5));
+ (void) WriteBlob(image,36,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
+ }
+ }
+ if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
+ {
+ /*
+ Write JNG pHYs chunk
+ */
+ (void) WriteBlobMSBULong(image,9L);
+ PNGType(chunk,mng_pHYs);
+ LogPNGChunk(logging,mng_pHYs,9L);
+ if (image->units == PixelsPerInchResolution)
+ {
+ PNGLong(chunk+4,(unsigned long)
+ (image->x_resolution*100.0/2.54+0.5));
+ PNGLong(chunk+8,(unsigned long)
+ (image->y_resolution*100.0/2.54+0.5));
+ chunk[12]=1;
+ }
+ else
+ {
+ if (image->units == PixelsPerCentimeterResolution)
+ {
+ PNGLong(chunk+4,(unsigned long)
+ (image->x_resolution*100.0+0.5));
+ PNGLong(chunk+8,(unsigned long)
+ (image->y_resolution*100.0+0.5));
+ chunk[12]=1;
+ }
+ else
+ {
+ PNGLong(chunk+4,(unsigned long) (image->x_resolution+0.5));
+ PNGLong(chunk+8,(unsigned long) (image->y_resolution+0.5));
+ chunk[12]=0;
+ }
+ }
+ (void) WriteBlob(image,13,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
+ }
+
+ if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
+ {
+ /*
+ Write JNG oFFs chunk
+ */
+ (void) WriteBlobMSBULong(image,9L);
+ PNGType(chunk,mng_oFFs);
+ LogPNGChunk(logging,mng_oFFs,9L);
+ PNGsLong(chunk+4,(long) (image->page.x));
+ PNGsLong(chunk+8,(long) (image->page.y));
+ chunk[12]=0;
+ (void) WriteBlob(image,13,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
+ }
+
+ if (transparent)
+ {
+ if (jng_alpha_compression_method==0)
+ {
+ unsigned long
+ len;
+
+ register long
+ i;
+
+ /* Write IDAT chunk header */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Write IDAT chunks from blob, length=%lu.",
+ (unsigned long) length);
+
+ /* Copy IDAT chunks */
+ len=0;
+ p=(unsigned char *) (blob+8);
+ for (i=8; i<(long) length; i+=len+12)
+ {
+ len=((*(p ) & 0xff) << 24) +
+ ((*(p + 1) & 0xff) << 16) +
+ ((*(p + 2) & 0xff) << 8) +
+ ((*(p + 3) & 0xff) ) ;
+ p+=4;
+ if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84)
+ {
+ /* Found an IDAT chunk. */
+ (void) WriteBlobMSBULong(image,(unsigned long) len);
+ LogPNGChunk(logging,mng_IDAT,len);
+ (void) WriteBlob(image,len+4,(char *) p);
+ (void) WriteBlobMSBULong(image,
+ crc32(0,p,len+4));
+ }
+ else
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Skipping %c%c%c%c chunk,"
+ " length=%lu.",
+ *(p),*(p+1),*(p+2),*(p+3),len);
+ }
+ p+=(8+len);
+ }
+ }
+ else
+ {
+ /* Write JDAA chunk header */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Write JDAA chunk, length=%lu.",
+ (unsigned long) length);
+ (void) WriteBlobMSBULong(image,(unsigned long) length);
+ PNGType(chunk,mng_JDAA);
+ LogPNGChunk(logging,mng_JDAA,(unsigned long) length);
+ /* Write JDAT chunk(s) data */
+ (void) WriteBlob(image,4,(char *) chunk);
+ (void) WriteBlob(image,length,(char *) blob);
+ (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),
+ (unsigned char *) blob,(uInt) length));
+ }
+ MagickFreeMemory(blob);
+ }
+
+ /* Encode image as a JPEG blob */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating jpeg_image_info.");
+ jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
+ if (jpeg_image_info == (ImageInfo *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating jpeg_image.");
+
+ jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
+ if (jpeg_image == (Image *) NULL)
+ {
+ DestroyImageInfo(jpeg_image_info);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ DestroyBlob(jpeg_image);
+ jpeg_image->blob=CloneBlobInfo((BlobInfo *) NULL);
+ (void) AcquireUniqueFilename(jpeg_image->filename);
+ FormatString(jpeg_image_info->filename,"%.1024s",jpeg_image->filename);
+
+ status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status == MagickFalse)
+ {
+ if (jpeg_image != (Image *)NULL)
+ DestroyImage(jpeg_image);
+ if (jpeg_image_info != (ImageInfo *)NULL)
+ DestroyImageInfo(jpeg_image_info);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Created jpeg_image, %lu x %lu.",
+ jpeg_image->columns,
+ jpeg_image->rows);
+
+ if (jng_color_type == 8 || jng_color_type == 12)
+ jpeg_image_info->type=GrayscaleType;
+ jpeg_image_info->quality=jng_quality%1000;
+ (void) strlcpy(jpeg_image_info->magick,"JPEG",MaxTextExtent);
+ (void) strlcpy(jpeg_image->magick,"JPEG",MaxTextExtent);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating blob.");
+ blob=(char *) ImageToBlob(jpeg_image_info,jpeg_image,&length,
+ &image->exception);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Successfully read jpeg_image into a blob,"
+ " length=%lu.",
+ (unsigned long) length);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Write JDAT chunk, length=%lu.",
+ (unsigned long) length);
+ }
+ /* Write JDAT chunk(s) */
+ (void) WriteBlobMSBULong(image,(unsigned long) length);
+ PNGType(chunk,mng_JDAT);
+ LogPNGChunk(logging,mng_JDAT,(unsigned long) length);
+ (void) WriteBlob(image,4,(char *) chunk);
+ (void) WriteBlob(image,length,(char *) blob);
+ (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),(unsigned char *)
+ blob,(uInt)length));
+
+ (void) LiberateUniqueFileResource(jpeg_image_info->filename);
+ DestroyImage(jpeg_image);
+ DestroyImageInfo(jpeg_image_info);
+ MagickFreeMemory(blob);
+
+ /* Write IEND chunk */
+ (void) WriteBlobMSBULong(image,0L);
+ PNGType(chunk,mng_IEND);
+ LogPNGChunk(logging,mng_IEND,0);
+ (void) WriteBlob(image,4,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " exit WriteOneJNGImage()");
+ return(status);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e J N G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
+%
+% JNG support written by Glenn Randers-Pehrson, glennrp@image...
+%
+% The format of the WriteJNGImage method is:
+%
+% MagickPassFail WriteJNGImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o image_info: the image info.
+%
+% o image: The image.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+static MagickPassFail WriteJNGImage(const ImageInfo *image_info,Image *image)
+{
+ MngInfo
+ *mng_info;
+
+ int
+ have_mng_structure;
+
+ unsigned int
+ logging,
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFalse)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Allocate a MngInfo structure.
+ */
+ have_mng_structure=MagickFalse;
+ mng_info=MagickAllocateMemory(MngInfo *,sizeof(MngInfo));
+ if (mng_info == (MngInfo *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize members of the MngInfo structure.
+ */
+ (void) memset(mng_info,0,sizeof(MngInfo));
+ mng_info->image=image;
+ have_mng_structure=MagickTrue;
+
+ (void) WriteBlob(image,8,"\213JNG\r\n\032\n");
+
+ status=WriteOneJNGImage(mng_info,image_info,image);
+ CloseBlob(image);
+
+ (void) CatchImageException(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
+ return (status);
+}
+#endif
+
+
+
+static unsigned int WriteMNGImage(const ImageInfo *image_info,Image *image)
+{
+ Image
+ *next_image;
+
+ MngInfo
+ *mng_info;
+
+ int
+ have_mng_structure,
+ image_count,
+ need_iterations,
+ need_matte;
+
+ volatile int
+#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_MNG_FEATURES_SUPPORTED)
+ need_local_plte,
+#endif
+ all_images_are_gray,
+ logging,
+ need_defi,
+ build_palette,
+ use_global_plte;
+
+ register long
+ i;
+
+#if 1
+ size_t
+ chunk_length=0;
+#endif
+
+ unsigned int
+ status;
+
+ volatile unsigned int
+ write_jng,
+ write_mng;
+
+ volatile unsigned long
+ scene;
+
+ unsigned long
+ final_delay=0,
+ initial_delay;
+
+#if (PNG_LIBPNG_VER < 10200)
+ if (image_info->verbose)
+ printf("Your PNG library (libpng-%s) is rather old.\n",
+ PNG_LIBPNG_VER_STRING);
+#endif
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFalse)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Allocate a MngInfo structure.
+ */
+ have_mng_structure=MagickFalse;
+ mng_info=MagickAllocateMemory(MngInfo *,sizeof(MngInfo));
+ if (mng_info == (MngInfo *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize members of the MngInfo structure.
+ */
+ (void) memset(mng_info,0,sizeof(MngInfo));
+ mng_info->image=image;
+ have_mng_structure=MagickTrue;
+
+ write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
+ mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
+ mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
+ mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
+ mng_info->write_png48=LocaleCompare(image_info->magick,"PNG48") == 0;
+ mng_info->write_png64=LocaleCompare(image_info->magick,"PNG64") == 0;
+
+ write_jng=MagickFalse;
+ if (image_info->compression==JPEGCompression)
+ write_jng=MagickTrue;
+ else
+ {
+ Image
+ *p;
+
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ if (p->compression==JPEGCompression)
+ write_jng=MagickTrue;
+ }
+ }
+
+ mng_info->adjoin=image_info->adjoin && (image->next != (Image *) NULL) &&
+ write_mng;
+
+#ifdef GMPNG_BUILD_PALETTE
+ if (mng_info->write_png8)
+ build_palette=MagickTrue;
+ else if (mng_info->write_png24 || mng_info->write_png32 ||
+ mng_info->write_png48 || mng_info->write_png64)
+ build_palette=MagickFalse;
+ else
+ build_palette=(image_info->type == UndefinedType);
+#endif
+
+ if (logging)
+ {
+ /* Log some info about the input */
+ Image
+ *p;
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Checking input image(s)");
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Image_info depth: %ld",
+ image_info->depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Type: %d",image_info->type);
+
+ scene=0;
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Scene: %ld",scene++);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Image depth: %u",p->depth);
+ if (p->matte)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Matte: True");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Matte: False");
+ if (p->storage_class == PseudoClass)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Storage class: PseudoClass");
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Storage class: DirectClass");
+ if (p->colors)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Number of colors: %u",p->colors);
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Number of colors: unspecified");
+ if (!mng_info->adjoin)
+ break;
+ }
+ }
+
+ /*
+ Sometimes we get PseudoClass images whose RGB values don't match
+ the colors in the colormap. This code syncs the RGB values.
+ */
+ {
+ Image
+ *p;
+
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ if (p->taint && p->storage_class == PseudoClass)
+ (void) SyncImage(p);
+ if (!mng_info->adjoin)
+ break;
+ }
+ }
+
+#ifdef GMPNG_BUILD_PALETTE
+ if (build_palette)
+ {
+ /*
+ Sometimes we get DirectClass images that have 256 colors or fewer.
+ This code will convert them to PseudoClass and build a colormap.
+ */
+ Image
+ *p;
+
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ if (p->storage_class != PseudoClass)
+ {
+ p->colors=GetNumberColors(p,(FILE *) NULL,&p->exception);
+ if (p->colors <= 256)
+ {
+ p->colors=0;
+ if (p->matte)
+ (void) SetImageType(p,PaletteMatteType);
+ else
+ (void) SetImageType(p,PaletteType);
+ }
+ }
+ if (!mng_info->adjoin)
+ break;
+ }
+ }
+#endif
+
+ use_global_plte=MagickFalse;
+ all_images_are_gray=MagickFalse;
+#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
+ need_local_plte=MagickTrue;
+#endif
+ need_defi=MagickFalse;
+ need_matte=MagickFalse;
+ mng_info->framing_mode=1;
+ mng_info->old_framing_mode=1;
+
+ if (write_mng)
+ if (image_info->page != (char *) NULL)
+ {
+ /*
+ Determine image bounding box.
+ */
+ SetGeometry(image,&mng_info->page);
+ (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
+ &mng_info->page.y,&mng_info->page.width,
+ &mng_info->page.height);
+ }
+ if (write_mng)
+ {
+ unsigned char
+ chunk[800];
+
+ unsigned int
+ need_geom;
+
+ unsigned short
+ red,
+ green,
+ blue;
+
+ mng_info->page=image->page;
+ need_geom=MagickTrue;
+ if (mng_info->page.width || mng_info->page.height)
+ need_geom=MagickFalse;
+ /*
+ Check all the scenes.
+ */
+ initial_delay=(long) image->delay;
+ need_iterations=MagickFalse;
+ mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
+ mng_info->equal_physs=MagickTrue,
+ mng_info->equal_gammas=MagickTrue;
+ mng_info->equal_srgbs=MagickTrue;
+ mng_info->equal_backgrounds=MagickTrue;
+ image_count=0;
+#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_MNG_FEATURES_SUPPORTED)
+ all_images_are_gray=MagickTrue;
+ mng_info->equal_palettes=MagickFalse;
+ need_local_plte=MagickFalse;
+#endif
+ for (next_image=image; next_image != (Image *) NULL; )
+ {
+ if (need_geom)
+ {
+ if ((next_image->columns+next_image->page.x) >
+ mng_info->page.width)
+ mng_info->page.width=next_image->columns+next_image->page.x;
+ if ((next_image->rows+next_image->page.y) >
+ mng_info->page.height)
+ mng_info->page.height=next_image->rows+next_image->page.y;
+ }
+ if (next_image->page.x || next_image->page.y)
+ need_defi=MagickTrue;
+ if (next_image->matte)
+ need_matte=MagickTrue;
+ if ((int) next_image->dispose >= BackgroundDispose)
+ if (next_image->matte || next_image->page.x ||
+ next_image->page.y ||
+ ((next_image->columns < mng_info->page.width) &&
+ (next_image->rows < mng_info->page.height)))
+ mng_info->need_fram=MagickTrue;
+ if (next_image->iterations)
+ need_iterations=MagickTrue;
+ final_delay=next_image->delay;
+ if (final_delay != initial_delay || final_delay > 100)
+ mng_info->need_fram=1;
+#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_MNG_FEATURES_SUPPORTED)
+ /*
+ check for global palette possibility.
+ */
+ if (image->matte)
+ need_local_plte=MagickTrue;
+ if (!need_local_plte)
+ {
+ if (!IsGrayImage(image,&image->exception))
+ all_images_are_gray=MagickFalse;
+ mng_info->equal_palettes=PalettesAreEqual(image,next_image);
+ if (!use_global_plte)
+ use_global_plte=mng_info->equal_palettes;
+ need_local_plte=!mng_info->equal_palettes;
+ }
+#endif
+ if (next_image->next != (Image *) NULL)
+ {
+ if (next_image->background_color.red !=
+ next_image->next->background_color.red ||
+ next_image->background_color.green !=
+ next_image->next->background_color.green ||
+ next_image->background_color.blue !=
+ next_image->next->background_color.blue)
+ mng_info->equal_backgrounds=MagickFalse;
+ if (next_image->gamma != next_image->next->gamma)
+ mng_info->equal_gammas=MagickFalse;
+ if (next_image->rendering_intent !=
+ next_image->next->rendering_intent)
+ mng_info->equal_srgbs=MagickFalse;
+ if ((next_image->units != next_image->next->units) ||
+ (next_image->x_resolution !=
+ next_image->next->x_resolution) ||
+ (next_image->y_resolution != next_image->next->y_resolution))
+ mng_info->equal_physs=MagickFalse;
+ if (mng_info->equal_chrms)
+ {
+ if (next_image->chromaticity.red_primary.x !=
+ next_image->next->chromaticity.red_primary.x ||
+ next_image->chromaticity.red_primary.y !=
+ next_image->next->chromaticity.red_primary.y ||
+ next_image->chromaticity.green_primary.x !=
+ next_image->next->chromaticity.green_primary.x ||
+ next_image->chromaticity.green_primary.y !=
+ next_image->next->chromaticity.green_primary.y ||
+ next_image->chromaticity.blue_primary.x !=
+ next_image->next->chromaticity.blue_primary.x ||
+ next_image->chromaticity.blue_primary.y !=
+ next_image->next->chromaticity.blue_primary.y ||
+ next_image->chromaticity.white_point.x !=
+ next_image->next->chromaticity.white_point.x ||
+ next_image->chromaticity.white_point.y !=
+ next_image->next->chromaticity.white_point.y)
+ mng_info->equal_chrms=MagickFalse;
+ }
+ }
+ image_count++;
+ next_image=next_image->next;
+ }
+ if (image_count < 2)
+ {
+ mng_info->equal_backgrounds=MagickFalse;
+ mng_info->equal_chrms=MagickFalse;
+ mng_info->equal_gammas=MagickFalse;
+ mng_info->equal_srgbs=MagickFalse;
+ mng_info->equal_physs=MagickFalse;
+ use_global_plte=MagickFalse;
+#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
+ need_local_plte=MagickTrue;
+#endif
+ need_iterations=MagickFalse;
+ }
+ if (!mng_info->need_fram)
+ {
+ /*
+ Only certain framing rates 100/n are exactly representable without
+ the FRAM chunk but we'll allow some slop in VLC files
+ */
+ if (final_delay == 0)
+ {
+ if (need_iterations)
+ {
+ /*
+ It's probably a GIF with loop; don't run it *too* fast.
+ */
+ final_delay=10;
+ (void) ThrowException2(&image->exception,CoderError,
+ "input has zero delay between"
+ " all frames; assuming 10 cs",
+ (char *) NULL);
+ }
+ else
+ mng_info->ticks_per_second=0;
+ }
+ if (final_delay)
+ mng_info->ticks_per_second=100/final_delay;
+ if (final_delay > 50)
+ mng_info->ticks_per_second=2;
+ if (final_delay > 75)
+ mng_info->ticks_per_second=1;
+ if (final_delay > 125)
+ mng_info->need_fram=MagickTrue;
+ if (need_defi && final_delay > 2 && (final_delay != 4) &&
+ (final_delay != 5) && (final_delay != 10) &&
+ (final_delay != 20) &&
+ (final_delay != 25) && (final_delay != 50) &&
+ (final_delay != 100))
+ mng_info->need_fram=MagickTrue; /* make it exact;
+ cannot be VLC anyway */
+ }
+ if (mng_info->need_fram)
+ mng_info->ticks_per_second=100;
+ /*
+ If pseudocolor, we should also check to see if all the
+ palettes are identical and write a global PLTE if they are.
+ ../glennrp Feb 99.
+ */
+ /*
+ Write the MNG version 1.0 signature and MHDR chunk.
+ */
+ (void) WriteBlob(image,8,"\212MNG\r\n\032\n");
+ (void) WriteBlobMSBULong(image,28L); /* chunk data length=28 */
+ PNGType(chunk,mng_MHDR);
+ LogPNGChunk(logging,mng_MHDR,28L);
+ PNGLong(chunk+4,mng_info->page.width);
+ PNGLong(chunk+8,mng_info->page.height);
+ PNGLong(chunk+12,mng_info->ticks_per_second);
+ PNGLong(chunk+16,0L); /* layer count=unknown */
+ PNGLong(chunk+20,0L); /* frame count=unknown */
+ PNGLong(chunk+24,0L); /* play time=unknown */
+ if (write_jng)
+ {
+ if (need_matte)
+ {
+ if (need_defi || mng_info->need_fram || use_global_plte)
+ PNGLong(chunk+28,27L); /* simplicity=LC+JNG */
+ else
+ PNGLong(chunk+28,25L); /* simplicity=VLC+JNG */
+ }
+ else
+ {
+ if (need_defi || mng_info->need_fram || use_global_plte)
+ PNGLong(chunk+28,19L); /* simplicity=LC+JNG,
+ no transparency */
+ else
+ PNGLong(chunk+28,17L); /* simplicity=VLC+JNG,
+ no transparency */
+ }
+ }
+ else
+ {
+ if (need_matte)
+ {
+ if (need_defi || mng_info->need_fram || use_global_plte)
+ PNGLong(chunk+28,11L); /* simplicity=LC */
+ else
+ PNGLong(chunk+28,9L); /* simplicity=VLC */
+ }
+ else
+ {
+ if (need_defi || mng_info->need_fram || use_global_plte)
+ PNGLong(chunk+28,3L); /* simplicity=LC, no transparency */
+ else
+ PNGLong(chunk+28,1L); /* simplicity=VLC, no transparency */
+ }
+ }
+ (void) WriteBlob(image,32,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
+#if 1
+ if (AccessDefinition(image_info,"mng","need-cacheoff"))
+ {
+ /*
+ Add a "nEED CACHEOFF" request to disable frame caching in libmng.
+ Unfortunately, standard conformant players will reject the stream
+ if they do not support a nEED request.
+ */
+ PNGType(chunk,mng_nEED);
+ chunk_length = (strlcpy((char *) chunk+4, "CACHEOFF",20));
+ (void) WriteBlobMSBULong(image,(const unsigned long) chunk_length);
+ LogPNGChunk(logging,mng_nEED,(unsigned long) chunk_length);
+ chunk_length += 4;
+ (void) WriteBlob(image,chunk_length,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) chunk_length));
+ }
+#endif
+ if ((image->previous == (Image *) NULL) &&
+ (image->next != (Image *) NULL) && (image->iterations != 1))
+ {
+ /*
+ Write MNG TERM chunk
+ */
+ (void) WriteBlobMSBULong(image,10L); /* data length=10 */
+ PNGType(chunk,mng_TERM);
+ LogPNGChunk(logging,mng_TERM,10L);
+ chunk[4]=3; /* repeat animation */
+ chunk[5]=0; /* show last frame when done */
+ PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
+ final_delay/100));
+ if (image->iterations == 0)
+ PNGLong(chunk+10,PNG_MAX_UINT);
+ else
+ PNGLong(chunk+10,(png_uint_32) image->iterations);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " TERM delay: %lu",
+ (unsigned long)
+ (mng_info->ticks_per_second*
+ final_delay/100));
+ if (image->iterations == 0)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " TERM iterations: %lu",
+ (unsigned long)PNG_MAX_UINT);
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Image iterations: %lu",
+ image->iterations);
+ }
+ (void) WriteBlob(image,14,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
+ }
+ /*
+ To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
+ */
+ if ((image_info->colorspace == sRGBColorspace ||
+ image->rendering_intent) && mng_info->equal_srgbs)
+ {
+ /*
+ Write MNG sRGB chunk
+ */
+ (void) WriteBlobMSBULong(image,1L);
+ PNGType(chunk,mng_sRGB);
+ LogPNGChunk(logging,mng_sRGB,1L);
+ if (image->rendering_intent != UndefinedIntent)
+ chunk[4]=(int) image->rendering_intent-1;
+ else
+ chunk[4]=(int) PerceptualIntent-1;
+ (void) WriteBlob(image,5,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
+ mng_info->have_write_global_srgb=MagickTrue;
+ }
+ else
+ {
+ if (image->gamma && mng_info->equal_gammas)
+ {
+ /*
+ Write MNG gAMA chunk
+ */
+ (void) WriteBlobMSBULong(image,4L);
+ PNGType(chunk,mng_gAMA);
+ LogPNGChunk(logging,mng_gAMA,4L);
+ PNGLong(chunk+4,(unsigned long) (100000*image->gamma+0.5));
+ (void) WriteBlob(image,8,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
+ mng_info->have_write_global_gama=MagickTrue;
+ }
+ if (mng_info->equal_chrms)
+ {
+ PrimaryInfo
+ primary;
+
+ /*
+ Write MNG cHRM chunk
+ */
+ (void) WriteBlobMSBULong(image,32L);
+ PNGType(chunk,mng_cHRM);
+ LogPNGChunk(logging,mng_cHRM,32L);
+ primary=image->chromaticity.white_point;
+ PNGLong(chunk+4,(unsigned long) (100000*primary.x+0.5));
+ PNGLong(chunk+8,(unsigned long) (100000*primary.y+0.5));
+ primary=image->chromaticity.red_primary;
+ PNGLong(chunk+12,(unsigned long) (100000*primary.x+0.5));
+ PNGLong(chunk+16,(unsigned long) (100000*primary.y+0.5));
+ primary=image->chromaticity.green_primary;
+ PNGLong(chunk+20,(unsigned long) (100000*primary.x+0.5));
+ PNGLong(chunk+24,(unsigned long) (100000*primary.y+0.5));
+ primary=image->chromaticity.blue_primary;
+ PNGLong(chunk+28,(unsigned long) (100000*primary.x+0.5));
+ PNGLong(chunk+32,(unsigned long) (100000*primary.y+0.5));
+ (void) WriteBlob(image,36,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
+ mng_info->have_write_global_chrm=MagickTrue;
+ }
+ }
+ if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
+ {
+ /*
+ Write MNG pHYs chunk
+ */
+ (void) WriteBlobMSBULong(image,9L);
+ PNGType(chunk,mng_pHYs);
+ LogPNGChunk(logging,mng_pHYs,9L);
+ if (image->units == PixelsPerInchResolution)
+ {
+ PNGLong(chunk+4,(unsigned long)
+ (image->x_resolution*100.0/2.54+0.5));
+ PNGLong(chunk+8,(unsigned long)
+ (image->y_resolution*100.0/2.54+0.5));
+ chunk[12]=1;
+ }
+ else
+ {
+ if (image->units == PixelsPerCentimeterResolution)
+ {
+ PNGLong(chunk+4,(unsigned long)
+ (image->x_resolution*100.0+0.5));
+ PNGLong(chunk+8,(unsigned long)
+ (image->y_resolution*100.0+0.5));
+ chunk[12]=1;
+ }
+ else
+ {
+ PNGLong(chunk+4,(unsigned long) (image->x_resolution+0.5));
+ PNGLong(chunk+8,(unsigned long) (image->y_resolution+0.5));
+ chunk[12]=0;
+ }
+ }
+ (void) WriteBlob(image,13,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
+ }
+ /*
+ Write MNG BACK chunk and global bKGD chunk, if the image is transparent
+ or does not cover the entire frame.
+ */
+ if (write_mng && (image->matte || image->page.x > 0 ||
+ image->page.y > 0 ||
+ (image->page.width &&
+ (image->page.width+image->page.x <
+ mng_info->page.width))
+ || (image->page.height &&
+ (image->page.height+image->page.y <
+ mng_info->page.height))))
+ {
+ (void) WriteBlobMSBULong(image,6L);
+ PNGType(chunk,mng_BACK);
+ LogPNGChunk(logging,mng_BACK,6L);
+ red=ScaleQuantumToShort(image->background_color.red);
+ green=ScaleQuantumToShort(image->background_color.green);
+ blue=ScaleQuantumToShort(image->background_color.blue);
+ PNGShort(chunk+4,red);
+ PNGShort(chunk+6,green);
+ PNGShort(chunk+8,blue);
+ (void) WriteBlob(image,10,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
+ if (mng_info->equal_backgrounds)
+ {
+ (void) WriteBlobMSBULong(image,6L);
+ PNGType(chunk,mng_bKGD);
+ LogPNGChunk(logging,mng_bKGD,6L);
+ (void) WriteBlob(image,10,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
+ }
+ }
+
+#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
+ if (!need_local_plte && image->storage_class == PseudoClass
+ && !all_images_are_gray)
+ {
+ unsigned long
+ data_length;
+
+ /*
+ Write MNG PLTE chunk
+ */
+ data_length=3*image->colors;
+ (void) WriteBlobMSBULong(image,data_length);
+ PNGType(chunk,mng_PLTE);
+ LogPNGChunk(logging,mng_PLTE,data_length);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
+ chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
+ chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
+ }
+ (void) WriteBlob(image,data_length+4,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,(int) (data_length+4)));
+ mng_info->have_write_global_plte=MagickTrue;
+ }
+#endif
+ }
+ scene=0;
+ mng_info->delay=0;
+#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_MNG_FEATURES_SUPPORTED)
+ mng_info->equal_palettes=MagickFalse;
+#endif
+ do
+ {
+ unsigned char
+ chunk[800];
+
+ if (mng_info->adjoin)
+ {
+#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_MNG_FEATURES_SUPPORTED)
+ /*
+ If we aren't using a global palette for the entire MNG, check to
+ see if we can use one for two or more consecutive images.
+ */
+ if (need_local_plte && use_global_plte && !all_images_are_gray)
+ {
+ if (mng_info->IsPalette)
+ {
+ /*
+ When equal_palettes is true, this image has the
+ same palette as the previous PseudoClass image
+ */
+ mng_info->have_write_global_plte=mng_info->equal_palettes;
+ mng_info->equal_palettes=PalettesAreEqual(image,image->next);
+ if (mng_info->equal_palettes &&
+ !mng_info->have_write_global_plte)
+ {
+ /*
+ Write MNG PLTE chunk
+ */
+ unsigned long
+ data_length;
+
+ data_length=3*image->colors;
+ (void) WriteBlobMSBULong(image,data_length);
+ PNGType(chunk,mng_PLTE);
+ LogPNGChunk(logging,mng_PLTE,data_length);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ chunk[4+i*3]=
+ ScaleQuantumToChar(image->colormap[i].red);
+ chunk[5+i*3]=
+ ScaleQuantumToChar(image->colormap[i].green);
+ chunk[6+i*3]=
+ ScaleQuantumToChar(image->colormap[i].blue);
+ }
+ (void) WriteBlob(image,data_length+4,(char *) chunk);
+ (void) WriteBlobMSBULong(image,
+ crc32(0,chunk,(int)
+ (data_length+4)));
+ mng_info->have_write_global_plte=MagickTrue;
+ }
+ }
+ else
+ mng_info->have_write_global_plte=MagickFalse;
+ }
+#endif
+ if (need_defi)
+ {
+ long
+ previous_x,
+ previous_y;
+
+ if (scene)
+ {
+ previous_x=mng_info->page.x;
+ previous_y=mng_info->page.y;
+ }
+ else
+ {
+ previous_x=0;
+ previous_y=0;
+ }
+ mng_info->page=image->page;
+ if ((mng_info->page.x != previous_x) || (mng_info->page.y !=
+ previous_y))
+ {
+ (void) WriteBlobMSBULong(image,12L); /* data length=12 */
+ PNGType(chunk,mng_DEFI);
+ LogPNGChunk(logging,mng_DEFI,12L);
+ chunk[4]=0; /* object 0 MSB */
+ chunk[5]=0; /* object 0 LSB */
+ chunk[6]=0; /* visible */
+ chunk[7]=0; /* abstract */
+ PNGLong(chunk+8,mng_info->page.x);
+ PNGLong(chunk+12,mng_info->page.y);
+ (void) WriteBlob(image,16,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
+ }
+ }
+ }
+
+ mng_info->write_mng=write_mng;
+
+ if ((int) image->dispose >= 3)
+ mng_info->framing_mode=3;
+
+ if (mng_info->need_fram && mng_info->adjoin &&
+ ((image->delay != mng_info->delay) ||
+ (mng_info->framing_mode != mng_info->old_framing_mode)))
+ {
+ if (image->delay == mng_info->delay)
+ {
+ /*
+ Write a MNG FRAM chunk with the new framing mode.
+ */
+ (void) WriteBlobMSBULong(image,1L); /* data length=1 */
+ PNGType(chunk,mng_FRAM);
+ LogPNGChunk(logging,mng_FRAM,1L);
+ chunk[4]=(unsigned char) mng_info->framing_mode;
+ (void) WriteBlob(image,5,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
+ }
+ else
+ {
+ /*
+ Write a MNG FRAM chunk with the delay.
+ */
+ (void) WriteBlobMSBULong(image,10L); /* data length=10 */
+ PNGType(chunk,mng_FRAM);
+ LogPNGChunk(logging,mng_FRAM,10L);
+ chunk[4]=(unsigned char) mng_info->framing_mode;
+ chunk[5]=0; /* frame name separator (no name) */
+ chunk[6]=2; /* flag for changing default delay */
+ chunk[7]=0; /* flag for changing frame timeout */
+ chunk[8]=0; /* flag for changing frame clipping */
+ chunk[9]=0; /* flag for changing frame sync_id */
+ PNGLong(chunk+10,(png_uint_32)
+ ((mng_info->ticks_per_second*image->delay)/100));
+ (void) WriteBlob(image,14,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
+ mng_info->delay=(long) image->delay;
+ }
+ mng_info->old_framing_mode=mng_info->framing_mode;
+ }
+
+#if defined(JNG_SUPPORTED)
+ if (image->compression == JPEGCompression)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing JNG object.");
+ /* To do: specify the desired alpha compression method. */
+ image->compression=UndefinedCompression;
+ status=WriteOneJNGImage(mng_info,image_info,image);
+ }
+ else
+#endif
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing PNG object.");
+ status=WriteOnePNGImage(mng_info,image_info,image);
+ }
+
+ if (!status)
+ {
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ CloseBlob(image);
+ return (MagickFail);
+ }
+ (void) CatchImageException(image);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if (QuantumTick(scene,GetImageListLength(image)))
+ if (!MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesTag,
+ image->filename))
+ break;
+ } while (mng_info->adjoin);
+ if (write_mng)
+ {
+ unsigned char
+ chunk[16];
+
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ /*
+ Write the MEND chunk.
+ */
+ (void) WriteBlobMSBULong(image,0x00000000L);
+ PNGType(chunk,mng_MEND);
+ LogPNGChunk(logging,mng_MEND,0L);
+ (void) WriteBlob(image,4,(char *) chunk);
+ (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
+ }
+ /*
+ Free memory.
+ */
+ CloseBlob(image);
+ MngInfoFreeStruct(mng_info,&have_mng_structure);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
+ return(MagickPass);
+}
+#else /* PNG_LIBPNG_VER > 10011 */
+static unsigned int WritePNGImage(const ImageInfo *image_info,Image *image)
+{
+ image=image;
+ printf("Your PNG library is too old: You have libpng-%s\n",
+ PNG_LIBPNG_VER_STRING);
+ ThrowBinaryException(CoderError,PNGLibraryTooOld,image_info->filename);
+}
+static unsigned int WriteMNGImage(const ImageInfo *image_info,Image *image)
+{
+ return (WritePNGImage(image_info,image));
+}
+#endif /* PNG_LIBPNG_VER > 10011 */
+#endif
diff --git a/coders/pnm.c b/coders/pnm.c
new file mode 100644
index 0000000..347901d
--- /dev/null
+++ b/coders/pnm.c
@@ -0,0 +1,2059 @@
+/*
+% Copyright (C) 2003-2013 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP N N M M %
+% P P NN N MM MM %
+% PPPP N N N M M M %
+% P N NN M M %
+% P N N M M %
+% %
+% %
+% Read/Write PBMPlus Portable Anymap Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/omp_data_view.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePNMImage(const ImageInfo *,Image *);
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P N M %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPNM returns True if the image format type, identified by the
+% magick string, is PNM.
+%
+% The format of the IsPNM method is:
+%
+% unsigned int IsPNM(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPNM returns True if the image format type is PNM.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPNM(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if ((*magick == 'P') && isdigit((int) magick[1]))
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P N M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPNMImage reads a Portable Anymap image file and returns it.
+% It allocates the memory necessary for the new Image structure and returns
+% a pointer to the new image.
+%
+% The format of the ReadPNMImage method is:
+%
+% Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPNMImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static unsigned int PNMInteger(Image *image,const unsigned int base)
+{
+#define P7Comment "END_OF_COMMENTS\n"
+
+ int
+ c;
+
+ unsigned long
+ value;
+
+ /*
+ Skip any leading whitespace.
+ */
+ do
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ return(0);
+ if (c == '#')
+ {
+ char
+ *comment;
+
+ ExtendedSignedIntegralType
+ offset;
+
+ register char
+ *p,
+ *q;
+
+ size_t
+ length;
+
+ /*
+ Read comment.
+ */
+ length=MaxTextExtent;
+ comment=MagickAllocateMemory(char *,length+strlen(P7Comment)+1);
+ p=comment;
+ offset=p-comment;
+ if (comment != (char *) NULL)
+ for ( ; (c != EOF) && (c != '\n'); p++)
+ {
+ if ((size_t) (p-comment) >= length)
+ {
+ length<<=1;
+ length+=MaxTextExtent;
+ MagickReallocMemory(char *,comment,length+strlen(P7Comment)+1);
+ if (comment == (char *) NULL)
+ break;
+ p=comment+strlen(comment);
+ }
+ c=ReadBlobByte(image);
+ *p=c;
+ *(p+1)='\0';
+ }
+ if (comment == (char *) NULL)
+ return(0);
+ q=comment+offset;
+ if (LocaleCompare(q,P7Comment) == 0)
+ *q='\0';
+ (void) SetImageAttribute(image,"comment",comment);
+ MagickFreeMemory(comment);
+ continue;
+ }
+ } while (!isdigit(c));
+ if (base == 2)
+ return(c-'0');
+ /*
+ Evaluate number.
+ */
+ value=0;
+ do
+ {
+ value*=10;
+ value+=c-'0';
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ return(value);
+ }
+ while (isdigit(c));
+ return(value);
+}
+
+#define ValidateScalingIndex(image, index, max) \
+ do \
+ { \
+ if (index > max) \
+ ThrowReaderException(CorruptImageError,CorruptImage, image); \
+ } while (0)
+
+#define ValidateScalingPixel(image, pixel, max) \
+ do \
+ { \
+ ValidateScalingIndex(image, pixel.red, max); \
+ ValidateScalingIndex(image, pixel.green, max); \
+ ValidateScalingIndex(image, pixel.blue, max); \
+ } while (0)
+
+typedef enum
+ {
+ Undefined_PNM_Format,
+ PBM_ASCII_Format, /* P1 */
+ PGM_ASCII_Format, /* P2 */
+ PPM_ASCII_Format, /* P3 */
+ PBM_RAW_Format, /* P4 */
+ PGM_RAW_Format, /* P5 */
+ PPM_RAW_Format, /* P6 */
+ PAM_Format, /* P7 */
+ XV_332_Format /* P7 332 */
+ } PNMSubformat;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# define PNMReadUseOpenMP 1
+# define PNMReadThreads (Min(2,omp_get_max_threads()))
+#endif
+
+static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ c;
+
+ PNMSubformat
+ format;
+
+ Image
+ *image;
+
+ long
+ y;
+
+ LongPixelPacket
+ pixel;
+
+ register IndexPacket
+ *indexes;
+
+ register unsigned long
+ i;
+
+ size_t
+ count,
+ number_pixels;
+
+ unsigned int
+ index,
+ bits_per_sample;
+
+ MagickPassFail
+ status;
+
+ unsigned int
+ max_value,
+ samples_per_pixel;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read PNM image.
+ */
+ count=ReadBlob(image,1,(char *) &c);
+ do
+ {
+ /*
+ Initialize image structure.
+ */
+ max_value=0;
+ bits_per_sample=0;
+ samples_per_pixel=0;
+
+ if (count == 0)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (c != 'P')
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Read %c rather than expected 'P'!",c);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+
+ c=ReadBlobByte(image);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"PNM Format Id: P%c",
+ c);
+
+ switch (c)
+ {
+ case '1': format=PBM_ASCII_Format; break;
+ case '2': format=PGM_ASCII_Format; break;
+ case '3': format=PPM_ASCII_Format; break;
+ case '4': format=PBM_RAW_Format; break;
+ case '5': format=PGM_RAW_Format; break;
+ case '6': format=PPM_RAW_Format; break;
+ case '7':
+ {
+ if ((ReadBlobByte(image) == ' ') &&
+ (PNMInteger(image,10) == 332))
+ format=XV_332_Format;
+ else
+ format=PAM_Format;
+ break;
+ }
+ default:
+ {
+ format=Undefined_PNM_Format;
+ }
+ }
+
+ if (PAM_Format == format)
+ {
+ /*
+ PAM header format
+
+ P7
+ WIDTH 227
+ HEIGHT 149
+ DEPTH 3
+ MAXVAL 255
+ TUPLTYPE RGB
+ ENDHDR
+ */
+
+ char
+ keyword[MaxTextExtent];
+
+ register char
+ *p;
+
+ int
+ c;
+
+ while (1)
+ {
+ p=keyword;
+ c=ReadBlobByte(image);
+ do
+ {
+ if (isalnum(c) || ('#' == c))
+ if ((p-keyword) < (MaxTextExtent-1))
+ *p++=c;
+ c=ReadBlobByte(image);
+ } while (isalnum(c) || ('#' == c));
+ *p='\0';
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Keyword \"%s\"",keyword);
+ if ((EOF == c) || (LocaleCompare(keyword,"ENDHDR") == 0))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Exiting header!");
+ break;
+ }
+ else if (LocaleCompare(keyword,"HEIGHT") == 0)
+ {
+ image->rows=PNMInteger(image,10);
+ }
+ else if (LocaleCompare(keyword,"WIDTH") == 0)
+ {
+ image->columns=PNMInteger(image,10);
+ }
+ else if (LocaleCompare(keyword,"DEPTH") == 0)
+ {
+ samples_per_pixel=PNMInteger(image,10);
+ }
+ else if (LocaleCompare(keyword,"MAXVAL") == 0)
+ {
+ max_value=PNMInteger(image,10);
+ }
+ else if (LocaleCompare(keyword,"TUPLTYPE") == 0)
+ {
+ /* Skip white space */
+ do
+ {
+ c=ReadBlobByte(image);
+ } while (isspace(c) && (EOF != c));
+ if (EOF == c)
+ break;
+ /* Tupletype argument */
+ p=keyword;
+ do
+ {
+ if ((p-keyword) < (MaxTextExtent-1))
+ *p++=c;
+ c=ReadBlobByte(image);
+ } while (('\n' != c) && (EOF != c));
+ *p='\0';
+ if (EOF == c)
+ break;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TUPLTYPE \"%s\"",keyword);
+ if (LocaleNCompare(keyword,"BLACKANDWHITE",13) == 0)
+ {
+ image->colorspace=GRAYColorspace;
+ image->is_monochrome=MagickTrue;
+ }
+ else if (LocaleNCompare(keyword,"CMYK",4) == 0)
+ {
+ image->colorspace=CMYKColorspace;
+ }
+ else if (LocaleNCompare(keyword,"GRAYSCALE",9) == 0)
+ {
+ image->colorspace=GRAYColorspace;
+ }
+ else if (LocaleNCompare(keyword,"RGB",3) == 0)
+ {
+ }
+
+ /*
+ Check for alpha flag.
+ */
+ count=strlen(keyword);
+ if ((count > 6) && (LocaleNCompare(keyword+count-6,"_ALPHA",6) == 0))
+ {
+ image->matte=MagickTrue;
+ }
+ }
+ else if (LocaleNCompare(keyword,"#",1) == 0)
+ {
+ /* Skip white space */
+ do
+ {
+ c=ReadBlobByte(image);
+ } while (isspace(c) && (EOF != c));
+ if (EOF == c)
+ break;
+
+ /* Comment */
+ p=keyword;
+ do
+ {
+ if ((p-keyword) < (MaxTextExtent-1))
+ *p++=c;
+ c=ReadBlobByte(image);
+ } while (('\n' != c) && (EOF != c));
+ *p='\0';
+ (void) SetImageAttribute(image,"comment",keyword);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Comment: \"%s\"",keyword);
+ }
+ else
+ {
+ /* Unknown! */
+ do
+ {
+ c=ReadBlobByte(image);
+ } while (('\n' != c) && (EOF != c));
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ PNM header type format
+
+ P1
+ # feep.pbm
+ 24 7
+
+ P3
+ # feep.ppm
+ 4 4
+ 15
+ */
+ image->columns=PNMInteger(image,10);
+ image->rows=PNMInteger(image,10);
+
+ if ((format == PBM_ASCII_Format) || (format == PBM_RAW_Format))
+ max_value=1; /* bitmap */
+ else
+ max_value=PNMInteger(image,10);
+
+ switch (format)
+ {
+ case PBM_ASCII_Format:
+ case PBM_RAW_Format:
+ case PGM_ASCII_Format:
+ case PGM_RAW_Format:
+ case XV_332_Format:
+ {
+ samples_per_pixel=1;
+ break;
+ }
+ case PPM_ASCII_Format:
+ case PPM_RAW_Format:
+ {
+ samples_per_pixel=3;
+ break;
+ }
+ default:
+ {
+ }
+ }
+ }
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Dimensions: %lux%lu",
+ image->columns,image->rows);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Max Value: %u",
+ max_value);
+ if ((max_value == 0) || (max_value > 4294967295U))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ bits_per_sample=0;
+ if (max_value <= 1)
+ bits_per_sample=1;
+ else if (max_value <= 255U)
+ bits_per_sample=8;
+ else if (max_value <= 65535U)
+ bits_per_sample=16;
+ else if (max_value <= 4294967295U)
+ bits_per_sample=32;
+
+ image->depth=Min(bits_per_sample,QuantumDepth);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Image Depth: %u",
+ image->depth);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Samples Per Pixel: %u",
+ samples_per_pixel);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Bits Per Sample: %u",
+ bits_per_sample);
+
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+
+ if ((1 == samples_per_pixel) && (max_value < MaxColormapSize))
+ {
+ image->storage_class=PseudoClass;
+ image->colors=
+ max_value >= MaxColormapSize ? MaxColormapSize : max_value+1;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Colors: %u",
+ image->colors);
+ }
+ number_pixels=image->columns*image->rows;
+ if (number_pixels == 0)
+ ThrowReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Create colormap.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if ((format == XV_332_Format) && (image->colors == 256))
+ {
+ /*
+ Initialize 332 colormap.
+ */
+ i=0;
+ for (pixel.red=0; pixel.red < 8; pixel.red++)
+ for (pixel.green=0; pixel.green < 8; pixel.green++)
+ for (pixel.blue=0; pixel.blue < 4; pixel.blue++)
+ {
+ image->colormap[i].red=(Quantum)
+ (((double) MaxRGB*pixel.red)/0x07+0.5);
+ image->colormap[i].green=(Quantum)
+ (((double) MaxRGB*pixel.green)/0x07+0.5);
+ image->colormap[i].blue=(Quantum)
+ (((double) MaxRGB*pixel.blue)/0x03+0.5);
+ i++;
+ }
+ }
+ }
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Convert PNM pixels to runlength-encoded MIFF packets.
+ */
+ switch (format)
+ {
+ case PBM_ASCII_Format:
+ {
+ /*
+ Convert PBM image to pixel packets.
+ */
+ register unsigned long
+ x;
+
+ register PixelPacket
+ *q;
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < image->columns; x++)
+ {
+ index=!PNMInteger(image,2);
+ if (EOFBlob(image))
+ break;
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ if (EOFBlob(image))
+ break;
+ }
+ image->is_grayscale=MagickTrue;
+ image->is_monochrome=MagickTrue;
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ case PGM_ASCII_Format:
+ {
+ /*
+ Convert PGM image to pixel packets.
+ */
+ register unsigned long
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned long
+ intensity;
+
+ MagickBool
+ is_grayscale,
+ is_monochrome;
+
+ is_grayscale=MagickTrue;
+ is_monochrome=MagickTrue;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ PseudoClass
+ */
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < image->columns; x++)
+ {
+ intensity=PNMInteger(image,10);
+ ValidateScalingIndex(image, intensity, max_value);
+ if (EOFBlob(image))
+ break;
+ index=intensity;
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ *q=image->colormap[index];
+ is_monochrome &= IsMonochrome(*q);
+ q++;
+ }
+ }
+ else
+ {
+ /*
+ DirectClass
+ */
+ for (x=0; x < image->columns; x++)
+ {
+ intensity=PNMInteger(image,10);
+ ValidateScalingIndex(image, intensity, max_value);
+ if (EOFBlob(image))
+ break;
+ intensity=ScaleAnyToQuantum(intensity, max_value);
+ q->red=q->green=q->blue=intensity;
+ is_monochrome &= IsMonochrome(*q);
+ q++;
+ }
+ }
+ if (EOFBlob(image))
+ break;
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ image->is_monochrome=is_monochrome;
+ image->is_grayscale=is_grayscale;
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ case PPM_ASCII_Format:
+ {
+ /*
+ Convert PNM image to pixel packets.
+ */
+ register unsigned long
+ x;
+
+ register PixelPacket
+ *q;
+
+ MagickBool
+ is_grayscale,
+ is_monochrome;
+
+ is_grayscale=MagickTrue;
+ is_monochrome=MagickTrue;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < image->columns; x++)
+ {
+ pixel.red=PNMInteger(image,10);
+ pixel.green=PNMInteger(image,10);
+ pixel.blue=PNMInteger(image,10);
+ if (EOFBlob(image))
+ break;
+ ValidateScalingPixel(image, pixel, max_value);
+ pixel.red=ScaleAnyToQuantum(pixel.red, max_value);
+ pixel.green=ScaleAnyToQuantum(pixel.green, max_value);
+ pixel.blue=ScaleAnyToQuantum(pixel.blue, max_value);
+ q->red=(Quantum) pixel.red;
+ q->green=(Quantum) pixel.green;
+ q->blue=(Quantum) pixel.blue;
+ is_monochrome &= IsMonochrome(*q);
+ is_grayscale &= IsGray(*q);
+ q++;
+ }
+ if (EOFBlob(image))
+ break;
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ image->is_monochrome=is_monochrome;
+ image->is_grayscale=is_grayscale;
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ case PBM_RAW_Format:
+ case PGM_RAW_Format:
+ case PPM_RAW_Format:
+ case PAM_Format:
+ case XV_332_Format:
+ {
+ /*
+ Convert PBM/PGM/PPM/PAM/XV raw raster image to pixel packets.
+ */
+ ImportPixelAreaOptions
+ import_options;
+
+ QuantumType
+ quantum_type;
+
+ size_t
+ bytes_per_row;
+
+ MagickBool
+ check_pixels,
+ is_grayscale,
+ is_monochrome,
+ use_scaling;
+
+ unsigned long
+ row_count=0;
+
+ ThreadViewDataSet
+ *scanline_set;
+
+ double
+ sample_scale;
+
+ unsigned int
+ sample_max;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+ int
+ pnm_read_threads = PNMReadThreads;
+#endif
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Reading PAM");
+
+ ImportPixelAreaOptionsInit(&import_options);
+
+ check_pixels=MagickTrue;
+ is_grayscale=MagickTrue;
+ is_monochrome=MagickTrue;
+
+ /*
+ Deduce correct import parameters.
+ */
+ quantum_type=UndefinedQuantum;
+ import_options.grayscale_miniswhite=MagickFalse;
+ sample_max=RoundDoubleToQuantum((MaxRGBDouble*max_value)/
+ MaxValueGivenBits(bits_per_sample));
+ sample_scale=MaxRGBDouble/sample_max;
+ use_scaling=(MaxRGB != sample_max);
+ bytes_per_row=0;
+ if (1 == samples_per_pixel)
+ {
+ if (1 == bits_per_sample)
+ {
+ /* PBM */
+ bytes_per_row=((image->columns+7) >> 3);
+ import_options.grayscale_miniswhite=MagickTrue;
+ quantum_type=GrayQuantum;
+ }
+ else
+ {
+ /* PGM & XV_332 */
+ bytes_per_row=((bits_per_sample+7)/8)*image->columns;
+ if (XV_332_Format == format)
+ {
+ quantum_type=IndexQuantum;
+ }
+ else
+ {
+ quantum_type=GrayQuantum;
+ }
+ }
+ }
+ else
+ {
+ bytes_per_row=(((bits_per_sample+7)/8)*samples_per_pixel)*image->columns;
+ if (3 == samples_per_pixel)
+ {
+ /* PPM */
+ quantum_type=RGBQuantum;
+ }
+ else if (4 == samples_per_pixel)
+ {
+ if (CMYKColorspace == image->colorspace)
+ quantum_type=CMYKQuantum;
+ else
+ quantum_type=RGBAQuantum;
+ }
+ else if (5 == samples_per_pixel)
+ {
+ if (CMYKColorspace == image->colorspace)
+ quantum_type=CMYKAQuantum;
+ }
+ }
+
+ if (1 == samples_per_pixel)
+ {
+ check_pixels=MagickFalse;
+ }
+ if (GrayQuantum)
+ {
+ if (1 == bits_per_sample)
+ {
+ is_grayscale=MagickTrue;
+ is_monochrome=MagickTrue;
+ }
+ else
+ {
+ is_grayscale=MagickTrue;
+ is_monochrome=MagickFalse;
+ }
+ }
+
+ scanline_set=AllocateThreadViewDataArray(image,exception,bytes_per_row,1);
+ if (scanline_set == (ThreadViewDataSet *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+#if PNMReadUseOpenMP
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(is_grayscale,is_monochrome,row_count,status)
+# else
+# pragma omp parallel for num_threads(pnm_read_threads) schedule(static,1) shared(is_grayscale,is_monochrome,row_count,status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register unsigned long
+ x;
+
+ register PixelPacket
+ *q = (PixelPacket *) NULL;
+
+ void
+ *pixels;
+
+ MagickBool
+ thread_status;
+
+ MagickBool
+ thread_is_grayscale,
+ thread_is_monochrome;
+
+ unsigned long
+ thread_row_count;
+
+ ImportPixelAreaInfo
+ import_info;
+
+#if PNMReadUseOpenMP
+# pragma omp critical (GM_ReadPNMImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ pixels=AccessThreadViewData(scanline_set);
+
+#if PNMReadUseOpenMP
+# pragma omp critical (GM_ReadPNMImage)
+#endif
+ {
+ thread_is_grayscale=is_grayscale;
+ thread_is_monochrome=is_monochrome;
+
+ if (ReadBlobZC(image,bytes_per_row,&pixels) != bytes_per_row)
+ thread_status=MagickFail;
+
+ thread_row_count=row_count;
+ row_count++;
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(thread_row_count,image->rows))
+ if (!MagickMonitorFormatted(thread_row_count,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ thread_status=MagickFail;
+ }
+
+ if (thread_status != MagickFail)
+ if ((q=SetImagePixels(image,0,thread_row_count,image->columns,1)) ==
+ (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ if (!ImportImagePixelArea(image,quantum_type,bits_per_sample,pixels,
+ &import_options,&import_info))
+ thread_status=MagickFail;
+ /*
+ Scale sub-ranged pixels up to full range if necessary
+ */
+ if ((thread_status != MagickFail) && (use_scaling))
+ for (x=0; x < image->columns; x++)
+ {
+ SetRedSample(&q[x],
+ RoundDoubleToQuantum(sample_scale*
+ GetRedSample(&q[x])));
+ SetGreenSample(&q[x],
+ RoundDoubleToQuantum(sample_scale*
+ GetGreenSample(&q[x])));
+ SetBlueSample(&q[x],
+ RoundDoubleToQuantum(sample_scale*
+ GetBlueSample(&q[x])));
+ if (image->matte)
+ SetOpacitySample(&q[x],
+ MaxRGB-
+ RoundDoubleToQuantum(sample_scale*
+ (MaxRGB-
+ GetOpacitySample(&q[x]))));
+ }
+ /*
+ For a DirectClass image, check all pixels for
+ gray/monochrome status since this format is often
+ used for input from Ghostscript, which may output
+ bilevel or gray in an RGB format. It is easier to
+ check now while the pixels are still "hot" in
+ memory.
+ */
+ if (thread_status != MagickFail)
+ if (check_pixels)
+ if (thread_is_grayscale || thread_is_monochrome)
+ for (x=0; x < image->columns; x++)
+ {
+ thread_is_grayscale = thread_is_grayscale && IsGray(q[x]);
+ thread_is_monochrome = thread_is_monochrome && IsMonochrome(q[x]);
+ if (!thread_is_grayscale && !thread_is_monochrome)
+ break;
+ }
+
+ if (thread_status != MagickFail)
+ if (!SyncImagePixels(image))
+ thread_status=MagickFail;
+
+#if PNMReadUseOpenMP
+# pragma omp critical (GM_ReadPNMImage)
+#endif
+ {
+ if (thread_status == MagickFail)
+ status=MagickFail;
+
+ if (!thread_is_grayscale)
+ is_grayscale=thread_is_grayscale;
+
+ if (!thread_is_monochrome)
+ is_monochrome=thread_is_monochrome;
+ }
+ }
+ DestroyThreadViewDataSet(scanline_set);
+ image->is_monochrome=is_monochrome;
+ image->is_grayscale=is_grayscale;
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ default:
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if ((format == PBM_ASCII_Format) || (format == PGM_ASCII_Format) || (format == PPM_ASCII_Format))
+ do
+ {
+ /*
+ Skip to end of line.
+ */
+ count=ReadBlob(image,1,&c);
+ if (count == 0)
+ break;
+ } while (c != '\n');
+ count=ReadBlob(image,1,&c);
+ if ((count != 0) && (c == 'P'))
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ } while ((count != 0) && (c == 'P'));
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P N M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPNMImage adds attributes for the PNM image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPNMImage method is:
+%
+% RegisterPNMImage(void)
+%
+*/
+ModuleExport void RegisterPNMImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("P7");
+ entry->decoder=(DecoderHandler) ReadPNMImage;
+ entry->encoder=(EncoderHandler) WritePNMImage;
+ entry->description="Xv thumbnail format";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->module="PNM";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PAM");
+ entry->decoder=(DecoderHandler) ReadPNMImage;
+ entry->encoder=(EncoderHandler) WritePNMImage;
+ entry->description="Portable Arbitrary Map format";
+ entry->module="PNM";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PBM");
+ entry->decoder=(DecoderHandler) ReadPNMImage;
+ entry->encoder=(EncoderHandler) WritePNMImage;
+ entry->description="Portable bitmap format (black/white)";
+ entry->module="PNM";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PGM");
+ entry->decoder=(DecoderHandler) ReadPNMImage;
+ entry->encoder=(EncoderHandler) WritePNMImage;
+ entry->description="Portable graymap format (gray scale)";
+ entry->module="PNM";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PNM");
+ entry->decoder=(DecoderHandler) ReadPNMImage;
+ entry->encoder=(EncoderHandler) WritePNMImage;
+ entry->magick=(MagickHandler) IsPNM;
+ entry->description="Portable anymap";
+ entry->module="PNM";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PPM");
+ entry->decoder=(DecoderHandler) ReadPNMImage;
+ entry->encoder=(EncoderHandler) WritePNMImage;
+ entry->description="Portable pixmap format (color)";
+ entry->module="PNM";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P N M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPNMImage removes format registrations made by the
+% PNM module from the list of supported formats.
+%
+% The format of the UnregisterPNMImage method is:
+%
+% UnregisterPNMImage(void)
+%
+*/
+ModuleExport void UnregisterPNMImage(void)
+{
+ (void) UnregisterMagickInfo("P7");
+ (void) UnregisterMagickInfo("PAM");
+ (void) UnregisterMagickInfo("PBM");
+ (void) UnregisterMagickInfo("PGM");
+ (void) UnregisterMagickInfo("PNM");
+ (void) UnregisterMagickInfo("PPM");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P N M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure WritePNMImage writes an image to a file in the PNM rasterfile
+% format.
+%
+% The format of the WritePNMImage method is:
+%
+% unsigned int WritePNMImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePNMImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static char *lut_255[] =
+{
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
+ "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27",
+ "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
+ "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53",
+ "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66",
+ "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
+ "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92",
+ "93", "94", "95", "96", "97", "98", "99", "100", "101", "102", "103", "104",
+ "105", "106", "107", "108", "109", "110", "111", "112", "113", "114", "115",
+ "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126",
+ "127", "128", "129", "130", "131", "132", "133", "134", "135", "136", "137",
+ "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148",
+ "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
+ "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170",
+ "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181",
+ "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192",
+ "193", "194", "195", "196", "197", "198", "199", "200", "201", "202", "203",
+ "204", "205", "206", "207", "208", "209", "210", "211", "212", "213", "214",
+ "215", "216", "217", "218", "219", "220", "221", "222", "223", "224", "225",
+ "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236",
+ "237", "238", "239", "240", "241", "242", "243", "244", "245", "246", "247",
+ "248", "249", "250", "251", "252", "253", "254", "255"
+};
+
+#define AppendUnsignedCharValueToString(j,buffer,value) \
+{ \
+ const char *lut_entry=lut_255[value]; \
+ while(*lut_entry != '\0') \
+ { \
+ buffer[j++]=*lut_entry; \
+ lut_entry++; \
+ } \
+}
+
+static unsigned int WritePNMImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[MaxTextExtent];
+
+ const ImageAttribute
+ *attribute;
+
+ IndexPacket
+ index;
+
+ PNMSubformat
+ format;
+
+ unsigned int
+ depth;
+
+ unsigned long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register unsigned long
+ i,
+ x;
+
+ unsigned int
+ scene,
+ status;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ scene=0;
+ do
+ {
+ depth=(image->depth <= 8 ? 8 : image->depth <= 16 ? 16 : 32);
+
+ /*
+ Write PNM file header.
+ */
+ format=Undefined_PNM_Format;
+ if (LocaleCompare(image_info->magick,"P7") == 0)
+ {
+ format=XV_332_Format;
+ }
+ else if (LocaleCompare(image_info->magick,"PPM") == 0)
+ {
+ format=PPM_RAW_Format;
+ }
+ else if (LocaleCompare(image_info->magick,"PGM") == 0)
+ {
+ format=PGM_RAW_Format;
+ }
+ else if (LocaleCompare(image_info->magick,"PBM") == 0)
+ {
+ format=PBM_RAW_Format;
+ }
+ else if (LocaleCompare(image_info->magick,"PAM") == 0)
+ {
+ format=PAM_Format;
+ }
+ else /* PNM auto format */
+ {
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Make sure that image is in an RGB type space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+
+ if ((characteristics.monochrome) &&
+ (image_info->type != GrayscaleType) &&
+ (image_info->type != GrayscaleMatteType) &&
+ (image_info->type != TrueColorType) &&
+ (image_info->type != TrueColorMatteType))
+ {
+ /* PBM */
+ format=PBM_RAW_Format;
+ }
+ else if ((characteristics.grayscale) &&
+ (image_info->type != TrueColorType) &&
+ (image_info->type != TrueColorMatteType))
+ {
+ /* PGM */
+ format=PGM_RAW_Format;
+ }
+ else
+ {
+ /* PPM */
+ format=PPM_RAW_Format;
+ }
+ }
+
+ /*
+ Check if ASCII subformat is requested.
+ */
+ if ((PBM_RAW_Format == format) || (PGM_RAW_Format == format) | (PPM_RAW_Format == format))
+ {
+ MagickBool
+ ascii = MagickFalse;
+
+ /*
+ If quality is set to zero or "pnm:ascii" is defined, then
+ select an ASCII subformat.
+ */
+ if (image_info->quality == 0)
+ ascii=MagickTrue;
+ else if ((AccessDefinition(image_info,"pnm","ascii")))
+ ascii=MagickTrue;
+
+ if (ascii)
+ {
+ if (PBM_RAW_Format == format)
+ format=PBM_ASCII_Format;
+ else if (PGM_RAW_Format == format)
+ format=PGM_ASCII_Format;
+ else if (PPM_RAW_Format == format)
+ format=PPM_ASCII_Format;
+ }
+ }
+
+ {
+ const char *header = "";
+ switch (format)
+ {
+ case Undefined_PNM_Format: break;
+ case PBM_ASCII_Format: header="P1"; break;
+ case PGM_ASCII_Format: header="P2"; break;
+ case PPM_ASCII_Format: header="P3"; break;
+ case PBM_RAW_Format: header="P4"; break;
+ case PGM_RAW_Format: header="P5"; break;
+ case PPM_RAW_Format: header="P6"; break;
+ case PAM_Format: header="P7"; break;
+ case XV_332_Format: header="P7 332"; break;
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Format Id: %s",
+ header);
+ (void) WriteBlobString(image,header);
+ (void) WriteBlobByte(image,'\n');
+ }
+
+ attribute=GetImageAttribute(image,"comment");
+ if (attribute != (const ImageAttribute *) NULL)
+ {
+ register char
+ *av;
+
+ /*
+ Write comments to file.
+ */
+ (void) WriteBlobByte(image,'#');
+ for (av=attribute->value; *av != '\0'; av++)
+ {
+ (void) WriteBlobByte(image,*av);
+ if ((*av == '\n') && (*(av+1) != '\0'))
+ (void) WriteBlobByte(image,'#');
+ }
+ (void) WriteBlobByte(image,'\n');
+ }
+ if ((PAM_Format != format) && (XV_332_Format != format))
+ {
+ FormatString(buffer,"%lu %lu\n",image->columns,image->rows);
+ (void) WriteBlobString(image,buffer);
+ }
+ /*
+ Write PNM raster pixels.
+ */
+ switch (format)
+ {
+ case PBM_ASCII_Format:
+ {
+ unsigned int
+ polarity;
+
+ size_t
+ j;
+
+ /*
+ Convert image to a PBM ASCII image.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]);
+ i=0;
+ j=0;
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < image->columns; x++)
+ {
+ buffer[j++] = (indexes[x] == polarity ? '0' : '1');
+ buffer[j++] = ' ';
+ i++;
+ if (i == 36)
+ {
+ buffer[j++] = '\n';
+ i=0;
+ }
+ if (j+4 > sizeof(buffer))
+ {
+ status=(WriteBlob(image,j,buffer) == j);
+ j=0;
+ if (MagickFail == status)
+ break;
+ }
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (MagickFail == status)
+ break;
+ }
+ if (MagickFail != status)
+ {
+ if (i != 0)
+ buffer[j++] = '\n';
+ if (j > 0)
+ status=(WriteBlob(image,j,buffer) == j);
+ }
+ break;
+ }
+ case PGM_ASCII_Format:
+ {
+ /*
+ Convert image to a PGM ASCII image.
+ */
+ size_t
+ j;
+
+ unsigned int
+ value;
+
+ /*
+ Make sure that image is in an RGB type space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+
+ i=0;
+ j=0;
+
+ value=(depth <=8 ? 255U : depth <= 16 ? 65535U : 4294967295U);
+
+ j += sprintf(&buffer[j],"%u\n",value);
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < image->columns; x++)
+ {
+ if (image->is_grayscale)
+ index=p->red;
+ else
+ index=PixelIntensityToQuantum(p);
+ if (depth <= 8)
+ {
+ /* Use LUT for speed */
+ value=ScaleQuantumToChar(index);
+ AppendUnsignedCharValueToString(j,buffer,value);
+ buffer[j++] = ' ';
+ }
+ else if (depth <= 16)
+ {
+ value=ScaleQuantumToShort(index);
+ j += sprintf(&buffer[j]," %u",value);
+ }
+ else
+ {
+ value=ScaleQuantumToLong(index);
+ j += sprintf(&buffer[j]," %u",value);
+ }
+
+ i++;
+ if (i == 12)
+ {
+ buffer[j++] = '\n';
+ i=0;
+ }
+ if (j+8 > sizeof(buffer))
+ {
+ status=(WriteBlob(image,j,buffer) == j);
+ j=0;
+ if (MagickFail == status)
+ break;
+ }
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (MagickFail == status)
+ break;
+ }
+ if (MagickFail != status)
+ {
+ if (i != 0)
+ buffer[j++] = '\n';
+ if (j > 0)
+ status=(WriteBlob(image,j,buffer) == j);
+ }
+ break;
+ }
+ case PPM_ASCII_Format:
+ {
+ /*
+ Convert image to a PPM ASCII image.
+ */
+ size_t
+ j;
+
+ unsigned int
+ value;
+
+ /*
+ Make sure that image is in an RGB type space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+
+ i=0;
+ j=0;
+
+ value=(depth <=8 ? 255U : (depth <= 16 ? 65535U : 4294967295U));
+
+ j += sprintf(&buffer[j],"%u\n",value);
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < image->columns; x++)
+ {
+ if (depth <= 8)
+ {
+ /* Use LUT for speed */
+ value=ScaleQuantumToChar(p->red);
+ AppendUnsignedCharValueToString(j,buffer,value);
+ buffer[j++] = ' ';
+ value=ScaleQuantumToChar(p->green);
+ AppendUnsignedCharValueToString(j,buffer,value);
+ buffer[j++] = ' ';
+ value=ScaleQuantumToChar(p->blue);
+ AppendUnsignedCharValueToString(j,buffer,value);
+ buffer[j++] = ' ';
+ }
+ else if (depth <= 16)
+ {
+ j += sprintf(&buffer[j],"%u %u %u ",
+ ScaleQuantumToShort(p->red),
+ ScaleQuantumToShort(p->green),
+ ScaleQuantumToShort(p->blue));
+ }
+ else
+ {
+ j += sprintf(&buffer[j],"%u %u %u ",
+ (unsigned int) ScaleQuantumToLong(p->red),
+ (unsigned int) ScaleQuantumToLong(p->green),
+ (unsigned int) ScaleQuantumToLong(p->blue));
+ }
+ i++;
+ if (i == 4)
+ {
+ buffer[j++] = '\n';
+ i=0;
+ }
+ if (j+(8*3) > sizeof(buffer))
+ {
+ status=(WriteBlob(image,j,buffer) == j);
+ j=0;
+ if (MagickFail == status)
+ break;
+ }
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (MagickFail == status)
+ break;
+ }
+ if (MagickFail != status)
+ {
+ if (i != 0)
+ buffer[j++] = '\n';
+ if (j > 0)
+ status=(WriteBlob(image,j,buffer) == j);
+ }
+ break;
+ }
+ case PBM_RAW_Format:
+ case PGM_RAW_Format:
+ case PPM_RAW_Format:
+ case PAM_Format:
+ {
+ ExportPixelAreaOptions
+ export_options;
+
+ size_t
+ bytes_per_row;
+
+ QuantumType
+ quantum_type;
+
+ unsigned int
+ bits_per_sample,
+ samples_per_pixel;
+
+ MagickBool
+ grayscale_miniswhite=MagickFalse;
+
+ unsigned char
+ *pixels;
+
+ /*
+ Deduce correct export parameters.
+ */
+ bits_per_sample=(depth <=8 ? 8 : (depth <= 16 ? 16 : 32));
+ quantum_type=RGBQuantum;
+ if (PBM_RAW_Format == format)
+ {
+ bits_per_sample=1;
+ grayscale_miniswhite=MagickTrue;
+ quantum_type=GrayQuantum;
+ }
+ else if (PGM_RAW_Format == format)
+ {
+ quantum_type=GrayQuantum;
+ }
+ else if (PPM_RAW_Format == format)
+ {
+ quantum_type=RGBQuantum;
+ }
+ else if (PAM_Format == format)
+ {
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Make sure image is of desired type.
+ */
+ if (UndefinedType != image_info->type)
+ SetImageType(image,image_info->type);
+
+ /*
+ Analyze the image to get its characteristics.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+
+ /*
+ Choose best encoding based on image characteristics.
+ */
+ if (characteristics.cmyk)
+ {
+ if (image->matte)
+ quantum_type=CMYKAQuantum;
+ else
+ quantum_type=CMYKQuantum;
+ }
+ else if (characteristics.monochrome)
+ {
+ bits_per_sample=1;
+ grayscale_miniswhite=MagickTrue;
+
+ if (image->matte)
+ quantum_type=GrayAlphaQuantum;
+ else
+ quantum_type=GrayQuantum;
+ }
+ else if (characteristics.grayscale)
+ {
+ if (image->matte)
+ quantum_type=GrayAlphaQuantum;
+ else
+ quantum_type=GrayQuantum;
+ }
+ else
+ {
+ if (image->matte)
+ quantum_type=RGBAQuantum;
+ else
+ quantum_type=RGBQuantum;
+ }
+ }
+
+ samples_per_pixel=MagickGetQuantumSamplesPerPixel(quantum_type);
+
+ if (1 == bits_per_sample)
+ bytes_per_row=((image->columns+7) >> 3);
+ else
+ bytes_per_row=(((bits_per_sample+7)/8)*samples_per_pixel)*image->columns;
+
+ ExportPixelAreaOptionsInit(&export_options);
+ export_options.grayscale_miniswhite=grayscale_miniswhite;
+
+ /*
+ Allocate memory for pixels.
+ */
+ pixels=MagickAllocateMemory(unsigned char *,bytes_per_row);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+
+ /*
+ Output header details
+ */
+ if (PAM_Format == format)
+ {
+ /*
+ PAM header
+ */
+ const char *tuple_type=NULL;
+
+ if (GrayQuantum == quantum_type)
+ {
+ if (1 == bits_per_sample)
+ tuple_type="BLACKANDWHITE";
+ else
+ tuple_type="GRAYSCALE";
+ }
+ else if (GrayAlphaQuantum == quantum_type)
+ {
+ if (1 == bits_per_sample)
+ tuple_type="BLACKANDWHITE_ALPHA";
+ else
+ tuple_type="GRAYSCALE_ALPHA";
+ }
+ else if (RGBQuantum == quantum_type)
+ tuple_type="RGB";
+ else if (RGBAQuantum == quantum_type)
+ tuple_type="RGB_ALPHA";
+ else if (CMYKQuantum == quantum_type)
+ tuple_type="CMYK";
+ else if (CMYKAQuantum == quantum_type)
+ tuple_type="CMYK_ALPHA";
+
+ FormatString(buffer,"WIDTH %lu\nHEIGHT %lu\nDEPTH %u\nMAXVAL %lu\nTUPLTYPE %s\n",
+ image->columns,image->rows,samples_per_pixel,
+ MaxValueGivenBits(bits_per_sample),tuple_type);
+ WriteBlobString(image,buffer);
+
+ (void) WriteBlobString(image,"ENDHDR\n");
+ }
+ else if ((PGM_RAW_Format == format) || (PPM_RAW_Format == format))
+ {
+ /*
+ PGM, PPM header
+ */
+ FormatString(buffer,"%lu\n",MaxValueGivenBits(bits_per_sample));
+ WriteBlobString(image,buffer);
+ }
+
+ /*
+ Output pixels
+ */
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if (ExportImagePixelArea(image,quantum_type,bits_per_sample,pixels,&export_options,0) == MagickFail)
+ break;
+ if (WriteBlob(image,bytes_per_row,(char *) pixels) != bytes_per_row)
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(pixels);
+
+ break;
+ }
+ case XV_332_Format:
+ {
+ static const short int
+ dither_red[2][16]=
+ {
+ {-16, 4, -1, 11,-14, 6, -3, 9,-15, 5, -2, 10,-13, 7, -4, 8},
+ { 15, -5, 0,-12, 13, -7, 2,-10, 14, -6, 1,-11, 12, -8, 3, -9}
+ },
+ dither_green[2][16]=
+ {
+ { 11,-15, 7, -3, 8,-14, 4, -2, 10,-16, 6, -4, 9,-13, 5, -1},
+ {-12, 14, -8, 2, -9, 13, -5, 1,-11, 15, -7, 3,-10, 12, -6, 0}
+ },
+ dither_blue[2][16]=
+ {
+ { -3, 9,-13, 7, -1, 11,-15, 5, -4, 8,-14, 6, -2, 10,-16, 4},
+ { 2,-10, 12, -8, 0,-12, 14, -6, 3, -9, 13, -7, 1,-11, 15, -5}
+ };
+
+ long
+ value;
+
+ Quantum
+ pixel;
+
+ unsigned short
+ *blue_map[2][16],
+ *green_map[2][16],
+ *red_map[2][16];
+
+ unsigned int
+ j;
+
+ /*
+ Allocate and initialize dither maps.
+ */
+ for (i=0; i < 2; i++)
+ for (j=0; j < 16; j++)
+ {
+ red_map[i][j]=MagickAllocateMemory(unsigned short *,
+ 256*sizeof(unsigned short));
+ green_map[i][j]=MagickAllocateMemory(unsigned short *,
+ 256*sizeof(unsigned short));
+ blue_map[i][j]=MagickAllocateMemory(unsigned short *,
+ 256*sizeof(unsigned short));
+ if ((red_map[i][j] == (unsigned short *) NULL) ||
+ (green_map[i][j] == (unsigned short *) NULL) ||
+ (blue_map[i][j] == (unsigned short *) NULL))
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ /*
+ Initialize dither tables.
+ */
+ for (i=0; i < 2; i++)
+ for (j=0; j < 16; j++)
+ for (x=0; x < 256; x++)
+ {
+ value=x-16;
+ if (x < 48)
+ value=x/2+8;
+ value+=dither_red[i][j];
+ red_map[i][j][x]=(unsigned short)
+ ((value < 0) ? 0 : (value > 255) ? 255 : value);
+ value=x-16;
+ if (x < 48)
+ value=x/2+8;
+ value+=dither_green[i][j];
+ green_map[i][j][x]=(unsigned short)
+ ((value < 0) ? 0 : (value > 255) ? 255 : value);
+ value=x-32;
+ if (x < 112)
+ value=x/2+24;
+ value+=2*dither_blue[i][j];
+ blue_map[i][j][x]=(unsigned short)
+ ((value < 0) ? 0 : (value > 255) ? 255 : value);
+ }
+ /*
+ Write pixels.
+ */
+ (void) WriteBlobString(image,"#END_OF_COMMENTS\n");
+ FormatString(buffer,"%lu %lu 255\n",image->columns,image->rows);
+ (void) WriteBlobString(image,buffer);
+ i=0;
+ j=0;
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < image->columns; x++)
+ {
+ if (!image_info->dither)
+ pixel=(Quantum) ((ScaleQuantumToChar(p->red) & 0xe0) |
+ ((ScaleQuantumToChar(p->green) & 0xe0) >> 3) |
+ ((ScaleQuantumToChar(p->blue) & 0xc0) >> 6));
+ else
+ pixel=(Quantum)
+ ((red_map[i][j][ScaleQuantumToChar(p->red)] & 0xe0) |
+ ((green_map[i][j][ScaleQuantumToChar(p->green)] & 0xe0) >> 3) |
+ ((blue_map[i][j][ScaleQuantumToChar(p->blue)] & 0xc0) >> 6));
+ (void) WriteBlobByte(image,pixel);
+ p++;
+ j++;
+ if (j == 16)
+ j=0;
+ }
+ i++;
+ if (i == 2)
+ i=0;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ /*
+ Free allocated memory.
+ */
+ for (i=0; i < 2; i++)
+ for (j=0; j < 16; j++)
+ {
+ MagickFreeMemory(green_map[i][j]);
+ MagickFreeMemory(blue_map[i][j]);
+ MagickFreeMemory(red_map[i][j]);
+ }
+ break;
+ }
+ case Undefined_PNM_Format:
+ break;
+ }
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if (status != MagickFail)
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == MagickFail)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/preview.c b/coders/preview.c
new file mode 100644
index 0000000..14cb1a4
--- /dev/null
+++ b/coders/preview.c
@@ -0,0 +1,655 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP RRRR EEEEE V V IIIII EEEEE W W %
+% P P R R E V V I E W W %
+% PPPP RRRR EEE V V I EEE W W %
+% P R R E V V I E W W W %
+% P R R EEEEE V IIIII EEEEE W W %
+% %
+% %
+% Write A Preview Image. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/constitute.h"
+#include "magick/decorate.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/fx.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/montage.h"
+#include "magick/quantize.h"
+#include "magick/resize.h"
+#include "magick/shear.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+ Constant declarations.
+*/
+static const char
+ *DefaultPreviewGeometry = "204x204+10+10";
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePreviewImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P R E V I E W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPREVIEWImage adds attributes for the Preview image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPREVIEWImage method is:
+%
+% RegisterPREVIEWImage(void)
+%
+*/
+ModuleExport void RegisterPREVIEWImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PREVIEW");
+ entry->encoder=(EncoderHandler) WritePreviewImage;
+ entry->adjoin=False;
+ entry->description="Show a preview an image enhancement, effect, or f/x";
+ entry->module="PREVIEW";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P R E V I E W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPREVIEWImage removes format registrations made by the
+% PREVIEW module from the list of supported formats.
+%
+% The format of the UnregisterPREVIEWImage method is:
+%
+% UnregisterPREVIEWImage(void)
+%
+*/
+ModuleExport void UnregisterPREVIEWImage(void)
+{
+ (void) UnregisterMagickInfo("PREVIEW");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P R E V I E W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePreviewImage creates several tiles each with a varying
+% stength of an image enhancement function (e.g. gamma). The image is written
+% in the MIFF format.
+%
+% The format of the WritePreviewImage method is:
+%
+% unsigned int WritePreviewImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePreviewImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+#define ReplaceImage(oldimage,func) \
+{ \
+ Image \
+ *temporary_image; \
+\
+ temporary_image=func; \
+ if (temporary_image) \
+ { \
+ DestroyImage(oldimage); \
+ oldimage=temporary_image; \
+ } \
+}
+static unsigned int WritePreviewImage(const ImageInfo *image_info,Image *image)
+{
+#define NumberTiles 9
+#define PreviewImageText "[%s] Creating image preview..."
+
+ char
+ factor[MaxTextExtent],
+ label[MaxTextExtent];
+
+ float
+ degrees,
+ gamma,
+ percentage,
+ radius,
+ sigma,
+ threshold;
+
+ Image
+ *images,
+ *montage_image,
+ *preview_image,
+ *master_image;
+
+ ImageInfo
+ *clone_info=0;
+
+ long
+ y;
+
+ MonitorHandler
+ handler;
+
+ MontageInfo
+ *montage_info;
+
+ RectangleInfo
+ geometry;
+
+ register long
+ i,
+ x;
+
+ unsigned int
+ status;
+
+ unsigned long
+ colors;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ CloseBlob(image);
+ (void) TransformColorspace(image,RGBColorspace);
+ clone_info=CloneImageInfo(image_info);
+ clone_info->quality=0;
+ colors=2;
+ degrees=0;
+ gamma=(-0.2f);
+ SetGeometry(image,&geometry);
+ (void) GetMagickGeometry(DefaultPreviewGeometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ images=NewImageList();
+ percentage=12.5;
+ radius=0.0;
+ sigma=1.0;
+ threshold=0.0;
+ x=0;
+ y=0;
+ master_image=ThumbnailImage(image,geometry.width,geometry.height,
+ &image->exception);
+ if (master_image == (Image *) NULL)
+ {
+ DestroyImageInfo(clone_info);
+ return False;
+ }
+ for (i=0; i < NumberTiles; i++)
+ {
+ preview_image=CloneImage(master_image,0,0,True,&image->exception);
+ if (preview_image == (Image *) NULL)
+ break;
+ (void) SetImageAttribute(preview_image,"label",DefaultTileLabel);
+ if (i == (NumberTiles >> 1))
+ {
+ (void) QueryColorDatabase("#dfdfdf",&preview_image->matte_color,
+ &image->exception);
+ AppendImageToList(&images,preview_image);
+ continue;
+ }
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ switch (image_info->preview_type)
+ {
+ case RotatePreview:
+ {
+ FormatString(factor,"%.1f",degrees+=45.0);
+ FormatString(label,"rotate %.1024s",factor);
+ ReplaceImage(preview_image,RotateImage(preview_image,degrees,
+ &image->exception));
+ break;
+ }
+ case ShearPreview:
+ {
+ degrees+=10.0;
+ FormatString(factor,"%.1fx%.1f",degrees,2.0*degrees);
+ FormatString(label,"shear %.1024s",factor);
+ ReplaceImage(preview_image,ShearImage(preview_image,degrees,
+ 2.0*degrees,&image->exception));
+ break;
+ }
+ case RollPreview:
+ {
+ x=(long) ((i+1)*preview_image->columns)/NumberTiles;
+ y=(long) ((i+1)*preview_image->rows)/NumberTiles;
+ FormatString(factor,"%+ld%+ld",x,y);
+ FormatString(label,"roll %.1024s",factor);
+ ReplaceImage(preview_image,RollImage(preview_image,x,y,
+ &image->exception));
+ break;
+ }
+ case HuePreview:
+ {
+ FormatString(factor,"100/100/%g",2.0*percentage);
+ FormatString(label,"modulate %.1024s",factor);
+ (void) ModulateImage(preview_image,factor);
+ break;
+ }
+ case SaturationPreview:
+ {
+ FormatString(factor,"100/%g",2.0*percentage);
+ FormatString(label,"modulate %.1024s",factor);
+ (void) ModulateImage(preview_image,factor);
+ break;
+ }
+ case BrightnessPreview:
+ {
+ FormatString(factor,"%g",2.0*percentage);
+ FormatString(label,"modulate %.1024s",factor);
+ (void) ModulateImage(preview_image,factor);
+ break;
+ }
+ case GammaPreview:
+ default:
+ {
+ FormatString(factor,"%g",gamma+=0.4f);
+ FormatString(label,"gamma %.1024s",factor);
+ (void) GammaImage(preview_image,factor);
+ break;
+ }
+ case SpiffPreview:
+ {
+ for (x=0; x < i; x++)
+ (void) ContrastImage(preview_image,True);
+ FormatString(label,"-contrast %ld",i+1);
+ break;
+ }
+ case DullPreview:
+ {
+ for (x=0; x < i; x++)
+ (void) ContrastImage(preview_image,False);
+ FormatString(label,"+contrast %ld",i+1);
+ break;
+ }
+ case GrayscalePreview:
+ {
+ QuantizeInfo
+ quantize_info;
+
+ GetQuantizeInfo(&quantize_info);
+ FormatString(factor,"%lu",colors);
+ FormatString(label,"colors %.1024s",factor);
+ (void) TransformColorspace(preview_image,GRAYColorspace);
+ quantize_info.number_colors=colors;
+ quantize_info.colorspace=GRAYColorspace;
+ quantize_info.dither=image_info->dither;
+ quantize_info.tree_depth=8;
+ (void) QuantizeImage(&quantize_info,preview_image);
+ colors<<=1;
+ break;
+ }
+ case QuantizePreview:
+ {
+ QuantizeInfo
+ quantize_info;
+
+ GetQuantizeInfo(&quantize_info);
+ FormatString(factor,"%lu",colors);
+ FormatString(label,"colors %.1024s",factor);
+ quantize_info.number_colors=colors;
+ quantize_info.colorspace=preview_image->colorspace;
+ quantize_info.dither=image_info->dither;
+ /* quantize_info.tree_depth=8; */
+ (void) QuantizeImage(&quantize_info,preview_image);
+ colors<<=1;
+ break;
+ }
+ case DespecklePreview:
+ {
+ for (x=0; x < i; x++)
+ {
+ ReplaceImage(preview_image,DespeckleImage(preview_image,
+ &image->exception));
+ }
+ FormatString(label,"despeckle %ld",i+1);
+ break;
+ }
+ case ReduceNoisePreview:
+ {
+ FormatString(factor,"%gx%g",radius,sigma);
+ FormatString(label,"noise %.1024s",factor);
+ ReplaceImage(preview_image,ReduceNoiseImage(preview_image,radius,
+ &image->exception));
+ break;
+ }
+ case AddNoisePreview:
+ {
+ NoiseType
+ noise;
+
+ switch ((int) x)
+ {
+ case 0:
+ (void) strcpy(factor,"uniform");
+ noise=UniformNoise;
+ break;
+ case 1:
+ (void) strcpy(factor,"Gaussian");
+ noise=GaussianNoise;
+ break;
+ case 2:
+ (void) strcpy(factor,"multiplicative");
+ noise=MultiplicativeGaussianNoise;
+ break;
+ case 3:
+ (void) strcpy(factor,"impulse");
+ noise=ImpulseNoise;
+ break;
+ case 4:
+ (void) strcpy(factor,"laplacian");
+ noise=LaplacianNoise;
+ break;
+ case 5:
+ (void) strcpy(factor,"Poisson");
+ noise=PoissonNoise;
+ break;
+ default:
+ (void) strcpy(preview_image->magick,"NULL");
+ noise=UniformNoise;
+ break;
+ }
+ x++;
+ FormatString(label,"+noise %.1024s",factor);
+ ReplaceImage(preview_image,AddNoiseImage(preview_image,noise,
+ &image->exception));
+ break;
+ }
+ case SharpenPreview:
+ {
+ FormatString(factor,"%gx%g",radius,sigma);
+ FormatString(label,"sharpen %.1024s",factor);
+ ReplaceImage(preview_image,SharpenImage(preview_image,radius,sigma,
+ &image->exception));
+ break;
+ }
+ case BlurPreview:
+ {
+ FormatString(factor,"%gx%g",radius,sigma);
+ FormatString(label,"-blur %.1024s",factor);
+ ReplaceImage(preview_image,BlurImage(preview_image,radius,sigma,
+ &image->exception));
+ break;
+ }
+ case ThresholdPreview:
+ {
+ FormatString(factor,"%lu",(unsigned long)
+ ((percentage*((double) MaxRGB+1.0))/100));
+ FormatString(label,"threshold %.1024s",factor);
+ (void ) ThresholdImage(preview_image,
+ (percentage*((double) MaxRGB+1.0))/100);
+ break;
+ }
+ case EdgeDetectPreview:
+ {
+ FormatString(factor,"%gx%g",radius,sigma);
+ FormatString(label,"edge %.1024s",factor);
+ ReplaceImage(preview_image,EdgeImage(preview_image,radius,
+ &image->exception));
+ break;
+ }
+ case SpreadPreview:
+ {
+ FormatString(factor,"%ld",i+1);
+ FormatString(label,"spread %.1024s",factor);
+ ReplaceImage(preview_image,SpreadImage(preview_image,i+1,
+ &image->exception));
+ break;
+ }
+ case SolarizePreview:
+ {
+ FormatString(factor,"%g",percentage);
+ FormatString(label,"solarize %.1024s",factor);
+ (void) SolarizeImage(preview_image,
+ (percentage*((double) MaxRGB+1.0))/100);
+ break;
+ }
+ case ShadePreview:
+ {
+ if (i == 0)
+ {
+ FormatString(factor,"30x30");
+ FormatString(label,"+shade %.1024s",factor);
+ ReplaceImage(preview_image,ShadeImage(preview_image,False,30,30,
+ &image->exception));
+ break;
+ }
+ degrees+=10.0;
+ FormatString(factor,"%gx%g",degrees,degrees);
+ FormatString(label,"shade %.1024s",factor);
+ ReplaceImage(preview_image,ShadeImage(preview_image,True,degrees,
+ degrees,&image->exception));
+ break;
+ }
+ case RaisePreview:
+ {
+ RectangleInfo
+ raise_info;
+
+ raise_info.width=2*i+2;
+ raise_info.height=2*i+2;
+ raise_info.x=0;
+ raise_info.y=0;
+ FormatString(factor,"%ldx%ld",2*i+2,2*i+2);
+ FormatString(label,"raise %.1024s",factor);
+ (void) RaiseImage(preview_image,&raise_info,True);
+ break;
+ }
+ case SegmentPreview:
+ {
+ threshold+=0.4f;
+ FormatString(factor,"%.1fx%.1f",threshold,threshold);
+ FormatString(label,"segment %.1024s",factor);
+ (void) SegmentImage(preview_image,preview_image->colorspace,False,
+ threshold,threshold);
+ break;
+ }
+ case SwirlPreview:
+ {
+ FormatString(factor,"%.1f",degrees);
+ FormatString(label,"swirl %.1024s",factor);
+ ReplaceImage(preview_image,SwirlImage(preview_image,degrees,
+ &image->exception));
+ degrees+=45.0;
+ break;
+ }
+ case ImplodePreview:
+ {
+ FormatString(factor,"%.1f",percentage/100.0);
+ FormatString(label,"implode %.1024s",factor);
+ ReplaceImage(preview_image,ImplodeImage(preview_image,
+ percentage/100.0,&image->exception));
+ break;
+ }
+ case WavePreview:
+ {
+ degrees+=5.0;
+ FormatString(factor,"%.1fx%.1f",0.5*degrees,2.0*degrees);
+ FormatString(label,"wave %.1024s",factor);
+ ReplaceImage(preview_image,WaveImage(preview_image,0.5*degrees,
+ 2.0*degrees,&image->exception));
+ break;
+ }
+ case OilPaintPreview:
+ {
+ FormatString(factor,"%g",0.5*(i+1));
+ FormatString(label,"paint %.1024s",factor);
+ ReplaceImage(preview_image,OilPaintImage(preview_image,0.5*(i+1),
+ &image->exception));
+ break;
+ }
+ case CharcoalDrawingPreview:
+ {
+ FormatString(factor,"%gx%g",radius,sigma);
+ FormatString(label,"charcoal %.1024s",factor);
+ ReplaceImage(preview_image,CharcoalImage(preview_image,radius,sigma,
+ &image->exception));
+ break;
+ }
+ case JPEGPreview:
+ {
+ char
+ filename[MaxTextExtent];
+
+ clone_info->quality=(unsigned int) (percentage+13.0);
+ FormatString(factor,"%lu",clone_info->quality);
+ if(!AcquireTemporaryFileName(filename))
+ {
+ DestroyImage(master_image);
+ DestroyImageInfo(clone_info);
+ ThrowWriterTemporaryFileException(filename);
+ }
+ FormatString(preview_image->filename,"jpeg:%.1024s",filename);
+ status=WriteImage(clone_info,preview_image);
+ if (status != False)
+ {
+ Image
+ *quality_image;
+
+ (void) strlcpy(clone_info->filename,preview_image->filename,
+ MaxTextExtent);
+ quality_image=ReadImage(clone_info,&image->exception);
+ if (quality_image != (Image *) NULL)
+ {
+ DestroyImage(preview_image);
+ preview_image=quality_image;
+ }
+ }
+ (void) LiberateTemporaryFile(filename);
+ if ((GetBlobSize(preview_image)/1024) >= 1024)
+ FormatString(label,"quality %.1024s\n%gmb ",factor,
+ (double) GetBlobSize(preview_image)/1024.0/1024.0);
+ else
+ if (GetBlobSize(preview_image) >= 1024)
+ FormatString(label,"quality %.1024s\n%gkb ",factor,
+ (double) GetBlobSize(preview_image)/1024.0);
+ else
+ FormatString(label,"quality %.1024s\n%lub ",factor,
+ (unsigned long) GetBlobSize(preview_image));
+ break;
+ }
+ }
+ percentage+=12.5;
+ radius+=0.5;
+ sigma+=0.25;
+ (void) SetImageAttribute(preview_image,"label",(char *) NULL);
+ (void) SetImageAttribute(preview_image,"label",label);
+ (void) SetMonitorHandler(handler);
+ AppendImageToList(&images,preview_image);
+ if (!MagickMonitorFormatted(i,NumberTiles,&image->exception,
+ PreviewImageText,image->filename))
+ break;
+ }
+ DestroyImage(master_image);
+ DestroyImageInfo(clone_info);
+ if (images == (Image *) NULL)
+ return(False);
+ /*
+ Create the montage.
+ */
+ montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
+ (void) strlcpy(montage_info->filename,image->filename,MaxTextExtent);
+ montage_info->shadow=True;
+ (void) CloneString(&montage_info->tile,"3x3");
+ (void) CloneString(&montage_info->geometry,DefaultPreviewGeometry);
+ (void) CloneString(&montage_info->frame,DefaultTileFrame);
+ montage_image=MontageImages(images,montage_info,&image->exception);
+ DestroyMontageInfo(montage_info);
+ DestroyImageList(images);
+ if (montage_image == (Image *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (montage_image->montage != (char *) NULL)
+ {
+ /*
+ Free image directory.
+ */
+ MagickFreeMemory(montage_image->montage);
+ montage_image->montage=(char *) NULL;
+ if (image->directory != (char *) NULL)
+ {
+ MagickFreeMemory(montage_image->directory);
+ montage_image->directory=(char *) NULL;
+ }
+ }
+ FormatString(montage_image->filename,"miff:%.1024s",image_info->filename);
+ status=WriteImage(image_info,montage_image);
+ DestroyImage(montage_image);
+ return(status);
+}
diff --git a/coders/ps.c b/coders/ps.c
new file mode 100644
index 0000000..dfd6ab9
--- /dev/null
+++ b/coders/ps.c
@@ -0,0 +1,1653 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP SSSSS %
+% P P SS %
+% PPPP SSS %
+% P SS %
+% P SSSSS %
+% %
+% %
+% Read/Write Postscript Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/color.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/enum_strings.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePSImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P S %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPS returns True if the image format type, identified by the
+% magick string, is PS.
+%
+% The format of the IsPS method is:
+%
+% unsigned int IsPS(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPS returns True if the image format type is PS.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPS(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (LocaleNCompare((char *) magick,"%!",2) == 0)
+ return(True);
+ if (memcmp(magick,"\004%!",3) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPSImage reads a Adobe Postscript image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadPSImage method is:
+%
+% Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPSImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define BoundingBox "%%BoundingBox:"
+#define DocumentMedia "%%DocumentMedia:"
+#define PageBoundingBox "%%PageBoundingBox:"
+#define PostscriptLevel "%!PS-"
+#define RenderPostscriptText "[%s] Rendering postscript..."
+
+ char
+ command[MaxTextExtent],
+ density[MaxTextExtent],
+ filename[MaxTextExtent],
+ geometry[MaxTextExtent],
+ postscript_filename[MaxTextExtent],
+ translate_geometry[MaxTextExtent];
+
+ const DelegateInfo
+ *delegate_info;
+
+ double
+ dx_resolution,
+ dy_resolution;
+
+ ExtendedSignedIntegralType
+ filesize;
+
+ FILE
+ *file;
+
+ Image
+ *image,
+ *next_image;
+
+ int
+ c,
+ status;
+
+ unsigned int
+ antialias=4;
+
+ RectangleInfo
+ page;
+
+ register char
+ *p;
+
+ register long
+ i;
+
+ SegmentInfo
+ bounds;
+
+ size_t
+ count;
+
+ unsigned long
+ height,
+ width;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ /*
+ Select Postscript delegate driver
+ */
+ delegate_info=GetPostscriptDelegateInfo(image_info,&antialias,exception);
+ if (delegate_info == (const DelegateInfo *) NULL)
+ return((Image *) NULL);
+ /*
+ Open image file.
+ */
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Open temporary output file.
+ */
+ file=AcquireTemporaryFileStream(postscript_filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ ThrowReaderTemporaryFileException(postscript_filename);
+ FormatString(translate_geometry,"%g %g translate\n ",0.0,0.0);
+ (void) fputs(translate_geometry,file);
+ /*
+ Set the page density.
+ */
+ dx_resolution=72.0;
+ dy_resolution=72.0;
+ if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0))
+ {
+ (void) strlcpy(density,PSDensityGeometry,sizeof(density));
+ count=GetMagickDimension(density,&image->x_resolution,&image->y_resolution,NULL,NULL);
+ if (count != 2)
+ image->y_resolution=image->x_resolution;
+ }
+ FormatString(density,"%gx%g",image->x_resolution,image->y_resolution);
+ /*
+ Determine page geometry from the Postscript bounding box.
+ */
+ (void) memset(&page,0,sizeof(RectangleInfo));
+ filesize=0;
+ if (LocaleCompare(image_info->magick,"EPT") == 0)
+ {
+ /*
+ Dos binary file header.
+ */
+ (void) ReadBlobLSBLong(image);
+ count=ReadBlobLSBLong(image);
+ filesize=(ExtendedSignedIntegralType) ReadBlobLSBLong(image);
+ for (i=0; i < (long) (count-12); i++)
+ (void) ReadBlobByte(image);
+ }
+ p=command;
+ for (i=0; (LocaleCompare(image_info->magick,"EPT") != 0) ||
+ (i < (long) filesize); i++)
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ break;
+ (void) fputc(c,file);
+ *p++=c;
+ if ((c != '\n') && (c != '\r') && ((p-command) < (MaxTextExtent-1)))
+ continue;
+ *p='\0';
+ p=command;
+ /*
+ Parse a bounding box statement.
+ */
+ count=0;
+ if (LocaleNCompare(BoundingBox,command,strlen(BoundingBox)) == 0)
+ count=sscanf(command,"%%%%BoundingBox: %lf %lf %lf %lf",&bounds.x1,
+ &bounds.y1,&bounds.x2,&bounds.y2);
+ if (LocaleNCompare(DocumentMedia,command,strlen(DocumentMedia)) == 0)
+ count=sscanf(command,"%%%%DocumentMedia: %*s %lf %lf",&bounds.x2,
+ &bounds.y2)+2;
+ if (LocaleNCompare(PageBoundingBox,command,strlen(PageBoundingBox)) == 0)
+ count=sscanf(command,"%%%%PageBoundingBox: %lf %lf %lf %lf",
+ &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
+ if (count != 4)
+ continue;
+ if ((bounds.x1 > bounds.x2) || (bounds.y1 > bounds.y2))
+ continue;
+ /*
+ Set Postscript render geometry.
+ */
+ FormatString(translate_geometry,"%g %g translate\n",-bounds.x1,-bounds.y1);
+ width=(unsigned long) (bounds.x2-bounds.x1+0.5);
+ height=(unsigned long) (bounds.y2-bounds.y1+0.5);
+ if (width > page.width)
+ page.width=width;
+ if (height > page.height)
+ page.height=height;
+ }
+ if ((page.width == 0) || (page.height == 0))
+ {
+ SetGeometry(image,&page);
+ (void) GetGeometry(PSPageGeometry,&page.x,&page.y,&page.width,
+ &page.height);
+ }
+ if (image_info->page != (char *) NULL)
+ (void) GetGeometry(image_info->page,&page.x,&page.y,&page.width,
+ &page.height);
+ FormatString(geometry,"%lux%lu",
+ (unsigned long) ceil(page.width*image->x_resolution/dx_resolution-0.5),
+ (unsigned long) ceil(page.height*image->y_resolution/dy_resolution-0.5));
+ if (ferror(file))
+ {
+ (void) fclose(file);
+ (void) LiberateTemporaryFile(postscript_filename);
+ ThrowReaderException(CorruptImageError,AnErrorHasOccurredWritingToFile,
+ image)
+ }
+ (void) rewind(file);
+ (void) fputs(translate_geometry,file);
+ (void) fclose(file);
+ CloseBlob(image);
+ filesize=GetBlobSize(image);
+ DestroyImage(image);
+ image=(Image *) NULL;
+ /*
+ Use Ghostscript to convert Postscript image.
+ */
+ {
+ char
+ options[MaxTextExtent],
+ arg[MaxTextExtent];
+
+ options[0]='\0';
+ /*
+ Append subrange.
+ */
+ if (image_info->subrange != 0)
+ FormatString(options,"-dFirstPage=%lu -dLastPage=%lu",
+ image_info->subimage+1,image_info->subimage+image_info->subrange);
+ /*
+ Append bounding box.
+ */
+ FormatString(arg,"-g%s",geometry);
+ if (options[0] != '\0')
+ (void) strlcat(options," ",sizeof(options));
+ (void) strlcat(options,arg,sizeof(options));
+
+ (void) strlcpy(filename,image_info->filename,MaxTextExtent);
+ if (image_info->temporary)
+ (void) LiberateTemporaryFile((char *) image_info->filename);
+ if(!AcquireTemporaryFileName((char *) image_info->filename))
+ {
+ (void) LiberateTemporaryFile(postscript_filename);
+ ThrowReaderTemporaryFileException(image_info->filename);
+ }
+ FormatString(command,delegate_info->commands,antialias,
+ antialias,density,options,image_info->filename,
+ postscript_filename);
+ }
+ (void) MagickMonitorFormatted(0,8,&image->exception,RenderPostscriptText,
+ image_info->filename);
+ status=InvokePostscriptDelegate(image_info->verbose,command,exception);
+ if (!IsAccessibleAndNotEmpty(image_info->filename))
+ {
+ /*
+ Ghostscript requires a showpage operator.
+ */
+ file=fopen(postscript_filename,"ab");
+ if (file == (FILE *) NULL)
+ {
+ (void) LiberateTemporaryFile((char *) image_info->filename);
+ ThrowReaderException(FileOpenError,UnableToWriteFile,image);
+ }
+ (void) fputs("showpage\n",file);
+ (void) fclose(file);
+ status=InvokePostscriptDelegate(image_info->verbose,command,exception);
+ }
+ (void) LiberateTemporaryFile(postscript_filename);
+ (void) MagickMonitorFormatted(7,8,&image->exception,RenderPostscriptText,
+ image_info->filename);
+ if (IsAccessibleAndNotEmpty(image_info->filename))
+ {
+ /*
+ Read Ghostscript output.
+ */
+ ImageInfo
+ *clone_info;
+
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ clone_info->magick[0]='\0';
+ clone_info->subimage=0;
+ clone_info->subrange=0;
+ MagickFreeMemory(clone_info->tile);
+ image=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ }
+ (void) LiberateTemporaryFile((char *) image_info->filename);
+#if defined(HasDPS)
+ if (image == (Image *) NULL)
+ {
+ /*
+ Ghostscript has failed-- try the Display Postscript Extension.
+ */
+ (void) FormatString((char *) image_info->filename,"dps:%.1024s",filename);
+ image=ReadImage(image_info,exception);
+ }
+#endif /* defined(HasDPS) */
+ if (image == (Image *) NULL)
+ {
+ if (UndefinedException == exception->severity)
+ ThrowException(exception,DelegateError,PostscriptDelegateFailed,filename);
+ }
+ else
+ {
+ do
+ {
+ (void) strlcpy(image->magick,"PS",sizeof(image->magick));
+ (void) strlcpy(image->filename,filename,sizeof(image->filename));
+ next_image=SyncNextImageInList(image);
+ if (next_image != (Image *) NULL)
+ image=next_image;
+ } while (next_image != (Image *) NULL);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ if (image_info->subimage != 0)
+ {
+ unsigned long
+ scene = image_info->subimage;
+
+ for (next_image=image;
+ next_image != (Image *) NULL;
+ next_image=next_image->next)
+ next_image->scene = scene++;
+ }
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPSImage adds attributes for the PS image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPSImage method is:
+%
+% RegisterPSImage(void)
+%
+*/
+ModuleExport void RegisterPSImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("EPI");
+ entry->decoder=(DecoderHandler) ReadPSImage;
+ entry->encoder=(EncoderHandler) WritePSImage;
+ entry->magick=(MagickHandler) IsPS;
+ entry->adjoin=False;
+ entry->description="Adobe Encapsulated PostScript Interchange format";
+ entry->module="PS";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("EPS");
+ entry->decoder=(DecoderHandler) ReadPSImage;
+ entry->encoder=(EncoderHandler) WritePSImage;
+ entry->magick=(MagickHandler) IsPS;
+ entry->adjoin=False;
+ entry->description="Adobe Encapsulated PostScript";
+ entry->module="PS";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("EPSF");
+ entry->decoder=(DecoderHandler) ReadPSImage;
+ entry->encoder=(EncoderHandler) WritePSImage;
+ entry->magick=(MagickHandler) IsPS;
+ entry->adjoin=False;
+ entry->description="Adobe Encapsulated PostScript";
+ entry->module="PS";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("EPSI");
+ entry->decoder=(DecoderHandler) ReadPSImage;
+ entry->encoder=(EncoderHandler) WritePSImage;
+ entry->magick=(MagickHandler) IsPS;
+ entry->adjoin=False;
+ entry->description="Adobe Encapsulated PostScript Interchange format";
+ entry->module="PS";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PS");
+ entry->decoder=(DecoderHandler) ReadPSImage;
+ entry->encoder=(EncoderHandler) WritePSImage;
+ entry->magick=(MagickHandler) IsPS;
+ entry->description="Adobe PostScript";
+ entry->module="PS";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPSImage removes format registrations made by the
+% PS module from the list of supported formats.
+%
+% The format of the UnregisterPSImage method is:
+%
+% UnregisterPSImage(void)
+%
+*/
+ModuleExport void UnregisterPSImage(void)
+{
+ (void) UnregisterMagickInfo("EPI");
+ (void) UnregisterMagickInfo("EPS");
+ (void) UnregisterMagickInfo("EPSF");
+ (void) UnregisterMagickInfo("EPSI");
+ (void) UnregisterMagickInfo("PS");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P S I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePSImage translates an image to encapsulated Postscript
+% Level I for printing. If the supplied geometry is null, the image is
+% centered on the Postscript page. Otherwise, the image is positioned as
+% specified by the geometry.
+%
+% The format of the WritePSImage method is:
+%
+% unsigned int WritePSImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WritePSImage return True if the image is printed.
+% False is returned if the image file cannot be opened for printing.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: The address of a structure of type Image; returned from
+% ReadImage.
+%
+%
+*/
+#define WriteRunlengthPacket(image,bp,pixel,length,p) \
+{ \
+ if (image->matte && (p->opacity == TransparentOpacity)) \
+ { \
+ bp=AppendHexTriplet(bp,0xff,0xff,0xff); \
+ } \
+ else \
+ { \
+ bp=AppendHexTriplet(bp, \
+ ScaleQuantumToChar(pixel.red), \
+ ScaleQuantumToChar(pixel.green), \
+ ScaleQuantumToChar(pixel.blue)); \
+ } \
+ bp=AppendHexVal(bp,Min(length,0xff)); \
+}
+
+static char* const hexvals[] =
+ {
+ "00","01","02","03","04","05","06","07","08","09","0A","0B",
+ "0C","0D","0E","0F","10","11","12","13","14","15","16","17",
+ "18","19","1A","1B","1C","1D","1E","1F","20","21","22","23",
+ "24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
+ "30","31","32","33","34","35","36","37","38","39","3A","3B",
+ "3C","3D","3E","3F","40","41","42","43","44","45","46","47",
+ "48","49","4A","4B","4C","4D","4E","4F","50","51","52","53",
+ "54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
+ "60","61","62","63","64","65","66","67","68","69","6A","6B",
+ "6C","6D","6E","6F","70","71","72","73","74","75","76","77",
+ "78","79","7A","7B","7C","7D","7E","7F","80","81","82","83",
+ "84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
+ "90","91","92","93","94","95","96","97","98","99","9A","9B",
+ "9C","9D","9E","9F","A0","A1","A2","A3","A4","A5","A6","A7",
+ "A8","A9","AA","AB","AC","AD","AE","AF","B0","B1","B2","B3",
+ "B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
+ "C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB",
+ "CC","CD","CE","CF","D0","D1","D2","D3","D4","D5","D6","D7",
+ "D8","D9","DA","DB","DC","DD","DE","DF","E0","E1","E2","E3",
+ "E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
+ "F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB",
+ "FC","FD","FE","FF",NULL
+ };
+static inline char *AppendHexVal(char *q,unsigned char val)
+{
+ *q++=*(hexvals[val]);
+ *q++=*(hexvals[val]+1);
+ return q;
+}
+static inline char* AppendHexTriplet(char *q,
+ unsigned char a,
+ unsigned char b,
+ unsigned char c)
+{
+ q=AppendHexVal(q,a);
+ q=AppendHexVal(q,b);
+ q=AppendHexVal(q,c);
+ return q;
+}
+static unsigned int WritePSImage(const ImageInfo *image_info,Image *image)
+{
+ static const char
+ * const PostscriptProlog[]=
+ {
+ "%%BeginProlog",
+ "%",
+ "% Display a color image. The image is displayed in color on",
+ "% Postscript viewers or printers that support color, otherwise",
+ "% it is displayed as grayscale.",
+ "%",
+ "/DirectClassPacket",
+ "{",
+ " %",
+ " % Get a DirectClass packet.",
+ " %",
+ " % Parameters:",
+ " % red.",
+ " % green.",
+ " % blue.",
+ " % length: number of pixels minus one of this color (optional).",
+ " %",
+ " currentfile color_packet readhexstring pop pop",
+ " compression 0 eq",
+ " {",
+ " /number_pixels 3 def",
+ " }",
+ " {",
+ " currentfile byte readhexstring pop 0 get",
+ " /number_pixels exch 1 add 3 mul def",
+ " } ifelse",
+ " 0 3 number_pixels 1 sub",
+ " {",
+ " pixels exch color_packet putinterval",
+ " } for",
+ " pixels 0 number_pixels getinterval",
+ "} bind def",
+ "",
+ "/DirectClassImage",
+ "{",
+ " %",
+ " % Display a DirectClass image.",
+ " %",
+ " systemdict /colorimage known",
+ " {",
+ " columns rows 8",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { DirectClassPacket } false 3 colorimage",
+ " }",
+ " {",
+ " %",
+ " % No colorimage operator; convert to grayscale.",
+ " %",
+ " columns rows 8",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { GrayDirectClassPacket } image",
+ " } ifelse",
+ "} bind def",
+ "",
+ "/GrayDirectClassPacket",
+ "{",
+ " %",
+ " % Get a DirectClass packet; convert to grayscale.",
+ " %",
+ " % Parameters:",
+ " % red",
+ " % green",
+ " % blue",
+ " % length: number of pixels minus one of this color (optional).",
+ " %",
+ " currentfile color_packet readhexstring pop pop",
+ " color_packet 0 get 0.299 mul",
+ " color_packet 1 get 0.587 mul add",
+ " color_packet 2 get 0.114 mul add",
+ " cvi",
+ " /gray_packet exch def",
+ " compression 0 eq",
+ " {",
+ " /number_pixels 1 def",
+ " }",
+ " {",
+ " currentfile byte readhexstring pop 0 get",
+ " /number_pixels exch 1 add def",
+ " } ifelse",
+ " 0 1 number_pixels 1 sub",
+ " {",
+ " pixels exch gray_packet put",
+ " } for",
+ " pixels 0 number_pixels getinterval",
+ "} bind def",
+ "",
+ "/GrayPseudoClassPacket",
+ "{",
+ " %",
+ " % Get a PseudoClass packet; convert to grayscale.",
+ " %",
+ " % Parameters:",
+ " % index: index into the colormap.",
+ " % length: number of pixels minus one of this color (optional).",
+ " %",
+ " currentfile byte readhexstring pop 0 get",
+ " /offset exch 3 mul def",
+ " /color_packet colormap offset 3 getinterval def",
+ " color_packet 0 get 0.299 mul",
+ " color_packet 1 get 0.587 mul add",
+ " color_packet 2 get 0.114 mul add",
+ " cvi",
+ " /gray_packet exch def",
+ " compression 0 eq",
+ " {",
+ " /number_pixels 1 def",
+ " }",
+ " {",
+ " currentfile byte readhexstring pop 0 get",
+ " /number_pixels exch 1 add def",
+ " } ifelse",
+ " 0 1 number_pixels 1 sub",
+ " {",
+ " pixels exch gray_packet put",
+ " } for",
+ " pixels 0 number_pixels getinterval",
+ "} bind def",
+ "",
+ "/PseudoClassPacket",
+ "{",
+ " %",
+ " % Get a PseudoClass packet.",
+ " %",
+ " % Parameters:",
+ " % index: index into the colormap.",
+ " % length: number of pixels minus one of this color (optional).",
+ " %",
+ " currentfile byte readhexstring pop 0 get",
+ " /offset exch 3 mul def",
+ " /color_packet colormap offset 3 getinterval def",
+ " compression 0 eq",
+ " {",
+ " /number_pixels 3 def",
+ " }",
+ " {",
+ " currentfile byte readhexstring pop 0 get",
+ " /number_pixels exch 1 add 3 mul def",
+ " } ifelse",
+ " 0 3 number_pixels 1 sub",
+ " {",
+ " pixels exch color_packet putinterval",
+ " } for",
+ " pixels 0 number_pixels getinterval",
+ "} bind def",
+ "",
+ "/PseudoClassImage",
+ "{",
+ " %",
+ " % Display a PseudoClass image.",
+ " %",
+ " % Parameters:",
+ " % class: 0-PseudoClass or 1-Grayscale.",
+ " %",
+ " currentfile buffer readline pop",
+ " token pop /class exch def pop",
+ " class 0 gt",
+ " {",
+ " currentfile buffer readline pop",
+ " token pop /depth exch def pop",
+ " /grays columns 8 add depth sub depth mul 8 idiv string def",
+ " columns rows depth",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { currentfile grays readhexstring pop } image",
+ " }",
+ " {",
+ " %",
+ " % Parameters:",
+ " % colors: number of colors in the colormap.",
+ " % colormap: red, green, blue color packets.",
+ " %",
+ " currentfile buffer readline pop",
+ " token pop /colors exch def pop",
+ " /colors colors 3 mul def",
+ " /colormap colors string def",
+ " currentfile colormap readhexstring pop pop",
+ " systemdict /colorimage known",
+ " {",
+ " columns rows 8",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { PseudoClassPacket } false 3 colorimage",
+ " }",
+ " {",
+ " %",
+ " % No colorimage operator; convert to grayscale.",
+ " %",
+ " columns rows 8",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { GrayPseudoClassPacket } image",
+ " } ifelse",
+ " } ifelse",
+ "} bind def",
+ "",
+ "/DisplayImage",
+ "{",
+ " %",
+ " % Display a DirectClass or PseudoClass image.",
+ " %",
+ " % Parameters:",
+ " % x & y translation.",
+ " % x & y scale.",
+ " % label pointsize.",
+ " % image label.",
+ " % image columns & rows.",
+ " % class: 0-DirectClass or 1-PseudoClass.",
+ " % compression: 0-none or 1-RunlengthEncoded.",
+ " % hex color packets.",
+ " %",
+ " gsave",
+ " /buffer 512 string def",
+ " /byte 1 string def",
+ " /color_packet 3 string def",
+ " /pixels 768 string def",
+ "",
+ " currentfile buffer readline pop",
+ " token pop /x exch def",
+ " token pop /y exch def pop",
+ " x y translate",
+ " currentfile buffer readline pop",
+ " token pop /x exch def",
+ " token pop /y exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /pointsize exch def pop",
+ " /Times-Roman findfont pointsize scalefont setfont",
+ (const char *) NULL
+ },
+ * const PostscriptEpilog[]=
+ {
+ " x y scale",
+ " currentfile buffer readline pop",
+ " token pop /columns exch def",
+ " token pop /rows exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /class exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /compression exch def pop",
+ " class 0 gt { PseudoClassImage } { DirectClassImage } ifelse",
+ " grestore",
+ (const char *) NULL
+ };
+
+ char
+ *bp,
+ buffer[MaxTextExtent],
+ date[MaxTextExtent],
+ density[MaxTextExtent],
+ **labels,
+ page_geometry[MaxTextExtent];
+
+ const char
+ * const *q;
+
+ const ImageAttribute
+ *attribute;
+
+ double
+ dx_resolution,
+ dy_resolution,
+ x_resolution,
+ x_scale,
+ y_resolution,
+ y_scale;
+
+ IndexPacket
+ index;
+
+ long
+ length,
+ y;
+
+ long
+ j;
+
+ PixelPacket
+ pixel;
+
+ RectangleInfo
+ geometry;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ SegmentInfo
+ bounds={0.0,0.0,0.0,0.0};
+
+ time_t
+ timer;
+
+ unsigned char
+ bit,
+ byte;
+
+ unsigned int
+ status;
+
+ unsigned long
+ count,
+ page,
+ polarity,
+ scene,
+ text_size;
+
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ page=1;
+ scene=0;
+ do
+ {
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Scale image to size of Postscript page.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ text_size=0;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ text_size=(unsigned int)
+ (MultilineCensus(attribute->value)*image_info->pointsize+12);
+ SetGeometry(image,&geometry);
+ geometry.y=(long) text_size;
+ FormatString(page_geometry,"%lux%lu",image->columns,image->rows);
+ if (image_info->page != (char *) NULL)
+ (void) strlcpy(page_geometry,image_info->page,MaxTextExtent);
+ else
+ if ((image->page.width != 0) && (image->page.height != 0))
+ (void) FormatString(page_geometry,"%lux%lu%+ld%+ld",image->page.width,
+ image->page.height,image->page.x,image->page.y);
+ else
+ if (LocaleCompare(image_info->magick,"PS") == 0)
+ (void) strlcpy(page_geometry,PSPageGeometry,sizeof(page_geometry));
+ (void) GetMagickGeometry(page_geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image Resolution: %gx%g %s",
+ image->x_resolution,
+ image->y_resolution,
+ ResolutionTypeToString(image->units));
+ /*
+ Scale relative to dots-per-inch.
+ */
+ dx_resolution=72.0;
+ dy_resolution=72.0;
+ x_resolution=72.0;
+ (void) strlcpy(density,PSDensityGeometry,sizeof(density));
+ count=GetMagickDimension(density,&x_resolution,&y_resolution,NULL,NULL);
+ if (count != 2)
+ y_resolution=x_resolution;
+ /*
+ Use override resolution information if it appears to be valid.
+ */
+ if ((image_info->density != (char *) NULL) &&
+ ((image_info->units == PixelsPerInchResolution) ||
+ (image_info->units == PixelsPerCentimeterResolution)))
+ {
+ count=GetMagickDimension(image_info->density,&x_resolution,&y_resolution,NULL,NULL);
+ if (count != 2)
+ y_resolution=x_resolution;
+ if (image_info->units == PixelsPerCentimeterResolution)
+ {
+ x_resolution *= 2.54;
+ y_resolution *= 2.54;
+ }
+ }
+ /*
+ Use image resolution information if it appears to be valid.
+ */
+ else if ((image->x_resolution > 0.0) && (image->y_resolution > 0.0) &&
+ ((image->units == PixelsPerInchResolution) ||
+ (image->units == PixelsPerCentimeterResolution)))
+ {
+ x_resolution = image->x_resolution;
+ y_resolution = image->y_resolution;
+ if (image->units == PixelsPerCentimeterResolution)
+ {
+ x_resolution *= 2.54;
+ y_resolution *= 2.54;
+ }
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Postscript Resolution: %gx%g DPI",
+ x_resolution,y_resolution);
+ x_scale=(geometry.width*dx_resolution)/x_resolution;
+ geometry.width=(unsigned long) (x_scale+0.5);
+ y_scale=(geometry.height*dy_resolution)/y_resolution;
+ geometry.height=(unsigned long) (y_scale+0.5);
+ if (page == 1)
+ {
+ /*
+ Output Postscript header.
+ */
+ if (LocaleCompare(image_info->magick,"PS") == 0)
+ (void) strlcpy(buffer,"%!PS-Adobe-3.0\n",sizeof(buffer));
+ else
+ (void) strlcpy(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n",sizeof(buffer));
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"%%Creator: (GraphicsMagick)\n");
+ FormatString(buffer,"%%%%Title: (%.1024s)\n",image->filename);
+ (void) WriteBlobString(image,buffer);
+ timer=time((time_t *) NULL);
+ (void) localtime(&timer);
+ (void) strlcpy(date,ctime(&timer),MaxTextExtent);
+ date[strlen(date)-1]='\0';
+ FormatString(buffer,"%%%%CreationDate: (%.1024s)\n",date);
+ (void) WriteBlobString(image,buffer);
+ bounds.x1=geometry.x;
+ bounds.y1=geometry.y;
+ bounds.x2=geometry.x+x_scale;
+ bounds.y2=geometry.y+(geometry.height+text_size);
+ if (image_info->adjoin && (image->next != (Image *) NULL))
+ (void) strlcpy(buffer,"%%%%BoundingBox: (atend)\n",sizeof(buffer));
+ else
+ FormatString(buffer,"%%%%BoundingBox: %g %g %g %g\n",
+ floor(bounds.x1+0.5),floor(bounds.y1+0.5),ceil(bounds.x2-0.5),
+ ceil(bounds.y2-0.5));
+ (void) WriteBlobString(image,buffer);
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) WriteBlobString(image,
+ "%%DocumentNeededResources: font Times-Roman\n");
+ (void) WriteBlobString(image,"%%DocumentData: Clean7Bit\n");
+ (void) WriteBlobString(image,"%%LanguageLevel: 1\n");
+ if (LocaleCompare(image_info->magick,"PS") != 0)
+ (void) WriteBlobString(image,"%%Pages: 1\n");
+ else
+ {
+ /*
+ Compute the number of pages.
+ */
+ (void) WriteBlobString(image,"%%Orientation: Portrait\n");
+ (void) WriteBlobString(image,"%%PageOrder: Ascend\n");
+ FormatString(buffer,"%%%%Pages: %lu\n", image_info->adjoin ?
+ (unsigned long) GetImageListLength(image) : 1L);
+ (void) WriteBlobString(image,buffer);
+ }
+ (void) WriteBlobString(image,"%%EndComments\n");
+ (void) WriteBlobString(image,"\n%%BeginDefaults\n");
+ (void) WriteBlobString(image,"%%EndDefaults\n\n");
+ if ((LocaleCompare(image_info->magick,"EPI") == 0) ||
+ (LocaleCompare(image_info->magick,"EPT") == 0) ||
+ (LocaleCompare(image_info->magick,"EPSI") == 0))
+ {
+ Image
+ *preview_image;
+
+ /*
+ Create preview image.
+ */
+ preview_image=CloneImage(image,0,0,True,&image->exception);
+ if (preview_image == (Image *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ /*
+ Dump image as bitmap.
+ */
+ (void) SetImageType(preview_image,BilevelType);
+ polarity=
+ PixelIntensityToQuantum(&preview_image->colormap[0]) < (MaxRGB/2);
+ if (preview_image->colors == 2)
+ polarity=PixelIntensityToQuantum(&preview_image->colormap[0]) >
+ PixelIntensityToQuantum(&preview_image->colormap[1]);
+ FormatString(buffer,"%%%%BeginPreview: %lu %lu %lu %lu\n%% ",
+ preview_image->columns,preview_image->rows,1L,
+ (((preview_image->columns+7) >> 3)*preview_image->rows+35)/36);
+ (void) WriteBlobString(image,buffer);
+ count=0;
+ bp=buffer;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(preview_image,0,y,preview_image->columns,1,
+ &preview_image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(preview_image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) preview_image->columns; x++)
+ {
+ byte<<=1;
+ if (indexes[x] == polarity)
+ byte|=0x01;
+ bit++;
+ if (bit == 8)
+ {
+ bp=AppendHexVal(bp,byte & 0xff);
+ count++;
+ if (count == 36)
+ {
+ count=0;
+ *bp++='\n';
+ *bp++='%';
+ *bp++=' ';
+ *bp++=' ';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ };
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ {
+ byte<<=(8-bit);
+ bp=AppendHexVal(bp,byte & 0xff);
+ count++;
+ if (count == 36)
+ {
+ count=0;
+ *bp++='\n';
+ *bp++='%';
+ *bp++=' ';
+ *bp++=' ';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ };
+ };
+ }
+ if (bp != buffer)
+ {
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ (void) WriteBlobString(image,"\n%%EndPreview\n");
+ DestroyImage(preview_image);
+ }
+ /*
+ Output Postscript commands.
+ */
+ for (q=PostscriptProlog; *q; q++)
+ {
+ FormatString(buffer,"%.1024s\n",*q);
+ (void) WriteBlobString(image,buffer);
+ }
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ for (j=(long) MultilineCensus(attribute->value)-1; j >= 0; j--)
+ {
+ (void) WriteBlobString(image," /label 512 string def\n");
+ (void) WriteBlobString(image," currentfile label readline pop\n");
+ FormatString(buffer," 0 y %g add moveto label show pop\n",
+ j*image_info->pointsize+12);
+ (void) WriteBlobString(image,buffer);
+ }
+ for (q=PostscriptEpilog; *q; q++)
+ {
+ FormatString(buffer,"%.1024s\n",*q);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (LocaleCompare(image_info->magick,"PS") == 0)
+ (void) WriteBlobString(image," showpage\n");
+ (void) WriteBlobString(image,"} bind def\n");
+ (void) WriteBlobString(image,"%%EndProlog\n");
+ }
+ FormatString(buffer,"%%%%Page: 1 %lu\n",page++);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%%%%PageBoundingBox: %ld %ld %ld %ld\n",geometry.x,
+ geometry.y,geometry.x+(long) geometry.width,geometry.y+(long)
+ (geometry.height+text_size));
+ (void) WriteBlobString(image,buffer);
+ if (geometry.x < bounds.x1)
+ bounds.x1=geometry.x;
+ if (geometry.y < bounds.y1)
+ bounds.y1=geometry.y;
+ if ((geometry.x+(long) geometry.width-1) > bounds.x2)
+ bounds.x2=geometry.x+geometry.width-1;
+ if ((geometry.y+(long) (geometry.height+text_size)-1) > bounds.y2)
+ bounds.y2=geometry.y+(geometry.height+text_size)-1;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) WriteBlobString(image,"%%%%PageResources: font Times-Roman\n");
+ if (LocaleCompare(image_info->magick,"PS") != 0)
+ (void) WriteBlobString(image,"userdict begin\n");
+ (void) WriteBlobString(image,"DisplayImage\n");
+ /*
+ Output image data.
+ */
+ FormatString(buffer,"%ld %ld\n%g %g\n%f\n",geometry.x,geometry.y,
+ x_scale,y_scale,image_info->pointsize);
+ (void) WriteBlobString(image,buffer);
+ labels=(char **) NULL;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ labels=StringToList(attribute->value);
+ if (labels != (char **) NULL)
+ {
+ for (i=0; labels[i] != (char *) NULL; i++)
+ {
+ FormatString(buffer,"%.1024s \n",labels[i]);
+ (void) WriteBlobString(image,buffer);
+ MagickFreeMemory(labels[i]);
+ }
+ MagickFreeMemory(labels);
+ }
+ (void) memset(&pixel,0,sizeof(PixelPacket));
+ pixel.opacity=TransparentOpacity;
+ i=0;
+ index=0;
+ x=0;
+ /*
+ Analyze image to be written.
+ */
+ (void) GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception);
+ if ((image_info->type != TrueColorType) &&
+ (characteristics.grayscale))
+ {
+ FormatString(buffer,"%lu %lu\n1\n1\n1\n%d\n",image->columns,
+ image->rows,((characteristics.monochrome) ? 1 : 8));
+ (void) WriteBlobString(image,buffer);
+ if (!characteristics.monochrome)
+ {
+ /*
+ Dump image as grayscale.
+ */
+ i++;
+ bp=buffer;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ Quantum
+ quantum;
+
+ if (image->is_grayscale)
+ quantum=GetGraySample(p);
+ else
+ quantum=PixelIntensityToQuantum(p);
+
+ bp=AppendHexVal(bp,ScaleQuantumToChar(quantum));
+ i++;
+ if (i == 36)
+ {
+ i=0;
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (bp != buffer)
+ {
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ }
+ else
+ {
+ /*
+ Dump image as bitmap.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[1]) <
+ PixelIntensityToQuantum(&image->colormap[0]);
+ count=0;
+ bp=buffer;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte<<=1;
+ if (indexes[x] != polarity)
+ byte|=0x01;
+ bit++;
+ if (bit == 8)
+ {
+ bp=AppendHexVal(bp,byte & 0xff);
+ count++;
+ if (count == 36)
+ {
+ count=0;
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ bit=0;
+ byte=0;
+ }
+ p++;
+ }
+ if (bit != 0)
+ {
+ byte<<=(8-bit);
+ bp=AppendHexVal(bp,byte & 0xff);
+ count++;
+ if (count == 36)
+ {
+ count=0;
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ };
+ };
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (bp != buffer)
+ {
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ }
+ if (count != 0)
+ (void) WriteBlobByte(image,'\n');
+ }
+ else
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Dump DirectClass image.
+ */
+ FormatString(buffer,"%lu %lu\n0\n%d\n",image->columns,image->rows,
+ (int) (image_info->compression == RLECompression));
+ (void) WriteBlobString(image,buffer);
+ switch (image_info->compression)
+ {
+ case RLECompression:
+ {
+ /*
+ Dump runlength-encoded DirectColor packets.
+ */
+ bp=buffer;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ pixel=(*p);
+ length=255;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((p->red == pixel.red) && (p->green == pixel.green) &&
+ (p->blue == pixel.blue) && (p->opacity == pixel.opacity) &&
+ (length < 255) && (x < (long) (image->columns-1)))
+ length++;
+ else
+ {
+ if (x > 0)
+ {
+ WriteRunlengthPacket(image,bp,pixel,length,p);
+ i++;
+ if (i == 9)
+ {
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ i=0;
+ }
+ }
+ length=0;
+ }
+ pixel=(*p);
+ p++;
+ }
+ WriteRunlengthPacket(image,bp,pixel,length,p);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (bp != buffer)
+ {
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ break;
+ }
+ case NoCompression:
+ default:
+ {
+ /*
+ Dump uncompressed DirectColor packets.
+ */
+ i=0;
+ bp=buffer;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->matte && (p->opacity == TransparentOpacity))
+ bp=AppendHexTriplet(bp,0xff,0xff,0xff);
+ else
+ bp=AppendHexTriplet(bp,
+ ScaleQuantumToChar(p->red),
+ ScaleQuantumToChar(p->green),
+ ScaleQuantumToChar(p->blue));
+ i++;
+ if (i == 12)
+ {
+ i=0;
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (bp != buffer)
+ {
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ break;
+ }
+ }
+ (void) WriteBlobByte(image,'\n');
+ }
+ else
+ {
+ /*
+ Dump PseudoClass image.
+ */
+ FormatString(buffer,"%lu %lu\n%d\n%d\n0\n",image->columns,image->rows,
+ (int) (image->storage_class == PseudoClass),
+ (int) (image_info->compression == RLECompression));
+ (void) WriteBlobString(image,buffer);
+ /*
+ Dump number of colors and colormap.
+ */
+ FormatString(buffer,"%u\n",image->colors);
+ (void) WriteBlobString(image,buffer);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ FormatString(buffer,"%02X%02X%02X\n",
+ ScaleQuantumToChar(image->colormap[i].red),
+ ScaleQuantumToChar(image->colormap[i].green),
+ ScaleQuantumToChar(image->colormap[i].blue));
+ (void) WriteBlobString(image,buffer);
+ }
+ switch (image_info->compression)
+ {
+ case RLECompression:
+ {
+ /*
+ Dump runlength-encoded PseudoColor packets.
+ */
+ i=0;
+ bp=buffer;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ index=(*indexes);
+ length=255;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((index == indexes[x]) && (length < 255) &&
+ (x < ((long) image->columns-1)))
+ length++;
+ else
+ {
+ if (x > 0)
+ {
+ bp=AppendHexVal(bp,index);
+ bp=AppendHexVal(bp,Min(length,0xff));
+ i++;
+ if (i == 18)
+ {
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ i=0;
+ }
+ }
+ length=0;
+ }
+ index=indexes[x];
+ pixel=(*p);
+ p++;
+ }
+ bp=AppendHexVal(bp,index);
+ bp=AppendHexVal(bp,Min(length,0xff));
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (bp != buffer)
+ {
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ break;
+ }
+ case NoCompression:
+ default:
+ {
+ /*
+ Dump uncompressed PseudoColor packets.
+ */
+ i=0;
+ bp=buffer;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ bp=AppendHexVal(bp,indexes[x]);
+ i++;
+ if (i == 36)
+ {
+ *bp++='\n';
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ i=0;
+ }
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (bp != buffer)
+ {
+ (void) WriteBlob(image,bp-buffer,buffer);
+ bp=buffer;
+ }
+ break;
+ }
+ }
+ (void) WriteBlobByte(image,'\n');
+ }
+ if (LocaleCompare(image_info->magick,"PS") != 0)
+ (void) WriteBlobString(image,"end\n");
+ (void) WriteBlobString(image,"%%PageTrailer\n");
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(scene++,GetImageListLength(image),&image->exception,
+ SaveImagesText,image->filename))
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ (void) WriteBlobString(image,"%%Trailer\n");
+ if (page > 2)
+ {
+ FormatString(buffer,"%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5),
+ floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5));
+ (void) WriteBlobString(image,buffer);
+ }
+ (void) WriteBlobString(image,"%%EOF\n");
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/ps2.c b/coders/ps2.c
new file mode 100644
index 0000000..dcdb8e6
--- /dev/null
+++ b/coders/ps2.c
@@ -0,0 +1,1223 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP SSSSS 22222 %
+% P P SS 22 %
+% PPPP SSS 222 %
+% P SS 22 %
+% P SSSSS 22222 %
+% %
+% %
+% Write Postscript Level II Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/color.h"
+#include "magick/constitute.h"
+#include "magick/compress.h"
+#include "magick/enum_strings.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#if defined(HasTIFF)
+#define CCITTParam "-1"
+#else
+#define CCITTParam "0"
+#endif
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePS2Image(const ImageInfo *,Image *);
+
+#if defined(HasTIFF)
+#if defined(HAVE_TIFFCONF_H)
+#include "tiffconf.h"
+#endif
+#include "tiffio.h"
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H u f f m a n 2 D E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Huffman2DEncodeImage compresses an image via two-dimensional
+% Huffman-coding.
+%
+% The format of the Huffman2DEncodeImage method is:
+%
+% unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
+% Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method Huffman2DEncodeImage returns True if all the pixels are
+% compressed without error, otherwise False.
+%
+% o image_info: The image info..
+%
+% o image: The image.
+%
+*/
+static unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
+ Image *image)
+{
+ char
+ filename[MaxTextExtent];
+
+ Image
+ *huffman_image;
+
+ ImageInfo
+ *clone_info;
+
+ long
+ count,
+ j;
+
+ register long
+ i;
+
+ TIFF
+ *tiff;
+
+ uint16
+ fillorder;
+
+ unsigned char
+ *buffer;
+
+ unsigned int
+ status;
+
+ unsigned long
+ *byte_count,
+ strip_size;
+
+ /*
+ Write image as CCITTFax4 TIFF image to a temporary file.
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ huffman_image=CloneImage(image,0,0,True,&image->exception);
+ if (huffman_image == (Image *) NULL)
+ return(False);
+ (void) SetImageType(huffman_image,BilevelType);
+ if(!AcquireTemporaryFileName(filename))
+ {
+ DestroyImage(huffman_image);
+ ThrowBinaryException(FileOpenError,UnableToCreateTemporaryFile,
+ filename);
+ }
+ FormatString(huffman_image->filename,"tiff:%s",filename);
+ clone_info=CloneImageInfo(image_info);
+ clone_info->compression=Group4Compression;
+ clone_info->type=BilevelType;
+ (void) AddDefinitions(clone_info,"tiff:fill-order=msb2lsb",
+ &image->exception);
+ status=WriteImage(clone_info,huffman_image);
+ DestroyImageInfo(clone_info);
+ DestroyImage(huffman_image);
+ if (status == False)
+ return(False);
+ tiff=TIFFOpen(filename,"rb");
+ if (tiff == (TIFF *) NULL)
+ {
+ (void) LiberateTemporaryFile(filename);
+ ThrowBinaryException(FileOpenError,UnableToOpenFile,
+ image_info->filename)
+ }
+ /*
+ Allocate raw strip buffer.
+ */
+ (void) TIFFGetField(tiff,TIFFTAG_STRIPBYTECOUNTS,&byte_count);
+ strip_size=byte_count[0];
+ for (i=1; i < (long) TIFFNumberOfStrips(tiff); i++)
+ if (byte_count[i] > strip_size)
+ strip_size=byte_count[i];
+ buffer=MagickAllocateMemory(unsigned char *,strip_size);
+ if (buffer == (unsigned char *) NULL)
+ {
+ TIFFClose(tiff);
+ (void) LiberateTemporaryFile(filename);
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL)
+ }
+ /*
+ Compress runlength encoded to 2D Huffman pixels.
+ */
+ (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_FILLORDER,&fillorder);
+ for (i=0; i < (long) TIFFNumberOfStrips(tiff); i++)
+ {
+ Ascii85Initialize(image);
+ count=TIFFReadRawStrip(tiff,(uint32) i,buffer,(long) byte_count[i]);
+ if (fillorder == FILLORDER_LSB2MSB)
+ TIFFReverseBits(buffer,count);
+ for (j=0; j < count; j++)
+ Ascii85Encode(image,(unsigned long) buffer[j]);
+ Ascii85Flush(image);
+ }
+ MagickFreeMemory(buffer);
+ TIFFClose(tiff);
+ (void) LiberateTemporaryFile(filename);
+ return(True);
+}
+#else
+static unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
+ Image *image)
+{
+ ARG_NOT_USED(image_info);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ ThrowBinaryException(MissingDelegateError,TIFFLibraryIsNotAvailable,image->filename);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P S 2 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPS2Image adds attributes for the PS2 image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPS2Image method is:
+%
+% RegisterPS2Image(void)
+%
+*/
+ModuleExport void RegisterPS2Image(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("EPS2");
+ entry->encoder=(EncoderHandler) WritePS2Image;
+ entry->adjoin=False;
+ entry->seekable_stream=True;
+ entry->description="Adobe Level II Encapsulated PostScript";
+ entry->module="PS2";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PS2");
+ entry->encoder=(EncoderHandler) WritePS2Image;
+ entry->seekable_stream=True;
+ entry->description="Adobe Level II PostScript";
+ entry->module="PS2";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P S 2 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPS2Image removes format registrations made by the
+% PS2 module from the list of supported formats.
+%
+% The format of the UnregisterPS2Image method is:
+%
+% UnregisterPS2Image(void)
+%
+*/
+ModuleExport void UnregisterPS2Image(void)
+{
+ (void) UnregisterMagickInfo("EPS2");
+ (void) UnregisterMagickInfo("PS2");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P S 2 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePS2Image translates an image to encapsulated Postscript
+% Level II for printing. If the supplied geometry is null, the image is
+% centered on the Postscript page. Otherwise, the image is positioned as
+% specified by the geometry.
+%
+% The format of the WritePS2Image method is:
+%
+% unsigned int WritePS2Image(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WritePS2Image return True if the image is printed.
+% False is returned if the image file cannot be opened for printing.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: The address of a structure of type Image; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int WritePS2Image(const ImageInfo *image_info,Image *image)
+{
+ static const char
+ * const PostscriptProlog[]=
+ {
+ "%%%%BeginProlog",
+ "%%",
+ "%% Display a color image. The image is displayed in color on",
+ "%% Postscript viewers or printers that support color, otherwise",
+ "%% it is displayed as grayscale.",
+ "%%",
+ "/DirectClassImage",
+ "{",
+ " %%",
+ " %% Display a DirectClass image.",
+ " %%",
+ " colorspace 0 eq",
+ " {",
+ " /DeviceRGB setcolorspace",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent 8",
+ " /Decode [0 1 0 1 0 1]",
+ " /ImageMatrix [columns 0 0 rows neg 0 rows]",
+ " compression 0 gt",
+ " { /DataSource pixel_stream /%.1024s filter }",
+ " { /DataSource pixel_stream /%.1024s filter } ifelse",
+ " >> image",
+ " }",
+ " {",
+ " /DeviceCMYK setcolorspace",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent 8",
+ " /Decode [1 0 1 0 1 0 1 0]",
+ " /ImageMatrix [columns 0 0 rows neg 0 rows]",
+ " compression 0 gt",
+ " { /DataSource pixel_stream /%.1024s filter }",
+ " { /DataSource pixel_stream /%.1024s filter } ifelse",
+ " >> image",
+ " } ifelse",
+ "} bind def",
+ "",
+ "/PseudoClassImage",
+ "{",
+ " %%",
+ " %% Display a PseudoClass image.",
+ " %%",
+ " %% Parameters:",
+ " %% colors: number of colors in the colormap.",
+ " %%",
+ " currentfile buffer readline pop",
+ " token pop /colors exch def pop",
+ " colors 0 eq",
+ " {",
+ " %%",
+ " %% Image is grayscale.",
+ " %%",
+ " currentfile buffer readline pop",
+ " token pop /bits exch def pop",
+ " /DeviceGray setcolorspace",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent bits",
+ " /Decode [0 1]",
+ " /ImageMatrix [columns 0 0 rows neg 0 rows]",
+ " compression 0 gt",
+ " { /DataSource pixel_stream /%.1024s filter }",
+ " {",
+ " /DataSource pixel_stream /%.1024s filter",
+ " <<",
+ " /K "CCITTParam,
+ " /Columns columns",
+ " /Rows rows",
+ " >> /CCITTFaxDecode filter",
+ " } ifelse",
+ " >> image",
+ " }",
+ " {",
+ " %%",
+ " %% Parameters:",
+ " %% colormap: red, green, blue color packets.",
+ " %%",
+ " /colormap colors 3 mul string def",
+ " currentfile colormap readhexstring pop pop",
+ " currentfile buffer readline pop",
+ " [ /Indexed /DeviceRGB colors 1 sub colormap ] setcolorspace",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent 8",
+ " /Decode [0 255]",
+ " /ImageMatrix [columns 0 0 rows neg 0 rows]",
+ " compression 0 gt",
+ " { /DataSource pixel_stream /%.1024s filter }",
+ " { /DataSource pixel_stream /%.1024s filter } ifelse",
+ " >> image",
+ " } ifelse",
+ "} bind def",
+ "",
+ "/DisplayImage",
+ "{",
+ " %%",
+ " %% Display a DirectClass or PseudoClass image.",
+ " %%",
+ " %% Parameters:",
+ " %% x & y translation.",
+ " %% x & y scale.",
+ " %% label pointsize.",
+ " %% image label.",
+ " %% image columns & rows.",
+ " %% class: 0-DirectClass or 1-PseudoClass.",
+ " %% colorspace: 0-RGB or 1-CMYK.",
+ " %% compression: 0-RLECompression or 1-NoCompression.",
+ " %% hex color packets.",
+ " %%",
+ " gsave",
+ " /buffer 512 string def",
+ " /pixel_stream currentfile def",
+ "",
+ " currentfile buffer readline pop",
+ " token pop /x exch def",
+ " token pop /y exch def pop",
+ " x y translate",
+ " currentfile buffer readline pop",
+ " token pop /x exch def",
+ " token pop /y exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /pointsize exch def pop",
+ " /Helvetica findfont pointsize scalefont setfont",
+ (const char *) NULL
+ },
+ * const PostscriptEpilog[]=
+ {
+ " x y scale",
+ " currentfile buffer readline pop",
+ " token pop /columns exch def",
+ " token pop /rows exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /class exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /colorspace exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /compression exch def pop",
+ " class 0 gt { PseudoClassImage } { DirectClassImage } ifelse",
+ " grestore",
+ (const char *) NULL
+ };
+
+ char
+ buffer[MaxTextExtent],
+ date[MaxTextExtent],
+ density[MaxTextExtent],
+ page_geometry[MaxTextExtent],
+ **labels;
+
+ const char
+ * const *q;
+
+ CompressionType
+ compression;
+
+ const ImageAttribute
+ *attribute;
+
+ double
+ dx_resolution,
+ dy_resolution,
+ x_resolution,
+ x_scale,
+ y_resolution,
+ y_scale;
+
+ magick_off_t
+ current,
+ start,
+ stop;
+
+ int
+ count,
+ status;
+
+ long
+ j,
+ y;
+
+ RectangleInfo
+ geometry;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register long
+ i;
+
+ SegmentInfo
+ bounds={0.0,0.0,0.0,0.0};
+
+ size_t
+ length;
+
+ time_t
+ timer;
+
+ unsigned char
+ *pixels;
+
+ unsigned long
+ number_pixels,
+ page,
+ scene,
+ text_size;
+
+ void
+ *blob;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ compression=image->compression;
+ if (image_info->compression != UndefinedCompression)
+ compression=image_info->compression;
+ switch (compression)
+ {
+#if !defined(HasJPEG)
+ case JPEGCompression:
+ {
+ compression=RLECompression;
+ ThrowException(&image->exception,MissingDelegateError,JPEGLibraryIsNotAvailable,image->filename);
+ break;
+ }
+#endif
+#if !defined(HasZLIB)
+ case ZipCompression:
+ {
+ compression=RLECompression;
+ ThrowException(&image->exception,MissingDelegateError,ZipLibraryIsNotAvailable,image->filename);
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+ page=1;
+ scene=0;
+ do
+ {
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Scale image to size of Postscript page.
+ */
+ text_size=0;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ text_size=(unsigned int)
+ (MultilineCensus(attribute->value)*image_info->pointsize+12);
+ SetGeometry(image,&geometry);
+ geometry.y=(long) text_size;
+ FormatString(page_geometry,"%lux%lu",image->columns,image->rows);
+ if (image_info->page != (char *) NULL)
+ (void) strlcpy(page_geometry,image_info->page,MaxTextExtent);
+ else
+ if ((image->page.width != 0) && (image->page.height != 0))
+ (void) FormatString(page_geometry,"%lux%lu%+ld%+ld",image->page.width,
+ image->page.height,image->page.x,image->page.y);
+ else
+ if (LocaleCompare(image_info->magick,"PS2") == 0)
+ (void) strlcpy(page_geometry,PSPageGeometry,sizeof(page_geometry));
+ (void) GetMagickGeometry(page_geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image Resolution: %gx%g %s",
+ image->x_resolution,
+ image->y_resolution,
+ ResolutionTypeToString(image->units));
+ /*
+ Scale relative to dots-per-inch.
+ */
+ dx_resolution=72.0;
+ dy_resolution=72.0;
+ x_resolution=72.0;
+ (void) strlcpy(density,PSDensityGeometry,sizeof(density));
+ count=GetMagickDimension(density,&x_resolution,&y_resolution,NULL,NULL);
+ if (count != 2)
+ y_resolution=x_resolution;
+ /*
+ Use override resolution information if it appears to be valid.
+ */
+ if ((image_info->density != (char *) NULL) &&
+ ((image_info->units == PixelsPerInchResolution) ||
+ (image_info->units == PixelsPerCentimeterResolution)))
+ {
+ count=GetMagickDimension(image_info->density,&x_resolution,
+ &y_resolution,NULL,NULL);
+ if (count != 2)
+ y_resolution=x_resolution;
+ if (image_info->units == PixelsPerCentimeterResolution)
+ {
+ x_resolution *= 2.54;
+ y_resolution *= 2.54;
+ }
+ }
+ /*
+ Use image resolution information if it appears to be valid.
+ */
+ else if ((image->x_resolution > 0.0) && (image->y_resolution > 0.0) &&
+ ((image->units == PixelsPerInchResolution) ||
+ (image->units == PixelsPerCentimeterResolution)))
+ {
+ x_resolution = image->x_resolution;
+ y_resolution = image->y_resolution;
+ if (image->units == PixelsPerCentimeterResolution)
+ {
+ x_resolution *= 2.54;
+ y_resolution *= 2.54;
+ }
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Postscript Resolution: %gx%g DPI",
+ x_resolution,y_resolution);
+ x_scale=(geometry.width*dx_resolution)/x_resolution;
+ geometry.width=(unsigned long) (x_scale+0.5);
+ y_scale=(geometry.height*dy_resolution)/y_resolution;
+ geometry.height=(unsigned long) (y_scale+0.5);
+ if (page == 1)
+ {
+ /*
+ Output Postscript header.
+ */
+ if (LocaleCompare(image_info->magick,"PS2") == 0)
+ (void) strcpy(buffer,"%!PS-Adobe-3.0\n");
+ else
+ (void) strcpy(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n");
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"%%Creator: (GraphicsMagick)\n");
+ FormatString(buffer,"%%%%Title: (%.1024s)\n",image->filename);
+ (void) WriteBlobString(image,buffer);
+ timer=time((time_t *) NULL);
+ (void) localtime(&timer);
+ (void) strlcpy(date,ctime(&timer),MaxTextExtent);
+ date[strlen(date)-1]='\0';
+ FormatString(buffer,"%%%%CreationDate: (%.1024s)\n",date);
+ (void) WriteBlobString(image,buffer);
+ bounds.x1=geometry.x;
+ bounds.y1=geometry.y;
+ bounds.x2=geometry.x+geometry.width;
+ bounds.y2=geometry.y+geometry.height+text_size;
+ if (image_info->adjoin && (image->next != (Image *) NULL))
+ (void) strcpy(buffer,"%%BoundingBox: (atend)\n");
+ else
+ FormatString(buffer,"%%%%BoundingBox: %g %g %g %g\n",
+ floor(bounds.x1+0.5),floor(bounds.y1+0.5),ceil(bounds.x2-0.5),
+ ceil(bounds.y2-0.5));
+ (void) WriteBlobString(image,buffer);
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) WriteBlobString(image,
+ "%%DocumentNeededResources: font Helvetica\n");
+ (void) WriteBlobString(image,"%%LanguageLevel: 2\n");
+ if (LocaleCompare(image_info->magick,"PS2") != 0)
+ (void) WriteBlobString(image,"%%Pages: 1\n");
+ else
+ {
+ (void) WriteBlobString(image,"%%Orientation: Portrait\n");
+ (void) WriteBlobString(image,"%%PageOrder: Ascend\n");
+ if (!image_info->adjoin)
+ (void) strcpy(buffer,"%%Pages: 1\n");
+ else
+ FormatString(buffer,"%%%%Pages: %lu\n",(unsigned long)
+ GetImageListLength(image));
+ (void) WriteBlobString(image,buffer);
+ }
+ (void) WriteBlobString(image,"%%EndComments\n");
+ (void) WriteBlobString(image,"\n%%BeginDefaults\n");
+ (void) WriteBlobString(image,"%%EndDefaults\n\n");
+ /*
+ Output Postscript commands.
+ */
+ for (q=PostscriptProlog; *q; q++)
+ {
+ switch (compression)
+ {
+ case NoCompression: FormatString(buffer,*q,"ASCII85Decode"); break;
+ case JPEGCompression: FormatString(buffer,*q,"DCTDecode"); break;
+ case LZWCompression: FormatString(buffer,*q,"LZWDecode"); break;
+ case FaxCompression: FormatString(buffer,*q,"ASCII85Decode"); break;
+ default: FormatString(buffer,*q,"RunLengthDecode"); break;
+ }
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobByte(image,'\n');
+ }
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ for (j=(long) MultilineCensus(attribute->value)-1; j >= 0; j--)
+ {
+ (void) WriteBlobString(image," /label 512 string def\n");
+ (void) WriteBlobString(image," currentfile label readline pop\n");
+ FormatString(buffer," 0 y %g add moveto label show pop\n",
+ j*image_info->pointsize+12);
+ (void) WriteBlobString(image,buffer);
+ }
+ for (q=PostscriptEpilog; *q; q++)
+ {
+ FormatString(buffer,"%.1024s\n",*q);
+ (void) WriteBlobString(image,buffer);
+ }
+ if (LocaleCompare(image_info->magick,"PS2") == 0)
+ (void) WriteBlobString(image," showpage\n");
+ (void) WriteBlobString(image,"} bind def\n");
+ (void) WriteBlobString(image,"%%EndProlog\n");
+ }
+ FormatString(buffer,"%%%%Page: 1 %lu\n",page++);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%%%%PageBoundingBox: %ld %ld %ld %ld\n",geometry.x,
+ geometry.y,geometry.x+(long) geometry.width,geometry.y+(long)
+ (geometry.height+text_size));
+ (void) WriteBlobString(image,buffer);
+ if (geometry.x < bounds.x1)
+ bounds.x1=geometry.x;
+ if (geometry.y < bounds.y1)
+ bounds.y1=geometry.y;
+ if ((geometry.x+(long) geometry.width-1) > bounds.x2)
+ bounds.x2=geometry.x+geometry.width-1;
+ if ((geometry.y+(long) (geometry.height+text_size)-1) > bounds.y2)
+ bounds.y2=geometry.y+(geometry.height+text_size)-1;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) WriteBlobString(image,"%%PageResources: font Times-Roman\n");
+ if (LocaleCompare(image_info->magick,"PS2") != 0)
+ (void) WriteBlobString(image,"userdict begin\n");
+ start=TellBlob(image);
+ if (start < 0)
+ ThrowWriterException(BlobError,UnableToObtainOffset,image);
+ FormatString(buffer,"%%%%BeginData:%13ld %s Bytes\n",0L,
+ compression == NoCompression ? "ASCII" : "Binary");
+ (void) WriteBlobString(image,buffer);
+ stop=TellBlob(image);
+ if (stop < 0)
+ ThrowWriterException(BlobError,UnableToObtainOffset,image);
+ (void) WriteBlobString(image,"DisplayImage\n");
+ /*
+ Output image data.
+ */
+ FormatString(buffer,"%ld %ld\n%g %g\n%f\n",geometry.x,geometry.y,
+ x_scale,y_scale,image_info->pointsize);
+ (void) WriteBlobString(image,buffer);
+ labels=(char **) NULL;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ labels=StringToList(attribute->value);
+ if (labels != (char **) NULL)
+ {
+ for (i=0; labels[i] != (char *) NULL; i++)
+ {
+ FormatString(buffer,"%.1024s \n",labels[i]);
+ (void) WriteBlobString(image,buffer);
+ MagickFreeMemory(labels[i]);
+ }
+ MagickFreeMemory(labels);
+ }
+ number_pixels=image->columns*image->rows;
+
+ /*
+ Analyze image to be written.
+ */
+ (void) GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception);
+ if ((compression == FaxCompression) ||
+ ((image_info->type != TrueColorType) &&
+ (characteristics.grayscale)))
+ {
+ FormatString(buffer,"%lu %lu\n1\n%d\n",image->columns,image->rows,
+ (int) (image->colorspace == CMYKColorspace));
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%d\n",(int) (compression != FaxCompression));
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"0\n");
+ FormatString(buffer,"%d\n",compression == FaxCompression ? 1 : 8);
+ (void) WriteBlobString(image,buffer);
+ switch (compression)
+ {
+ case FaxCompression:
+ {
+ if (LocaleCompare(CCITTParam,"0") == 0)
+ {
+ (void) HuffmanEncodeImage(image_info,image);
+ break;
+ }
+ (void) Huffman2DEncodeImage(image_info,image);
+ break;
+ }
+ case JPEGCompression:
+ {
+ /*
+ Write image in JPEG format.
+ */
+ blob=ImageToJPEGBlob(image,image_info,&length,&image->exception);
+ if (blob == (char *) NULL)
+ ThrowWriterException2(CoderError,image->exception.reason,image);
+ (void) WriteBlob(image,length,blob);
+ MagickFreeMemory(blob);
+ break;
+ }
+ case RLECompression:
+ default:
+ {
+ register unsigned char
+ *q;
+
+ /*
+ Allocate pixel array.
+ */
+ length=number_pixels;
+ pixels=MagickAllocateMemory(unsigned char *,length);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ /*
+ Dump Runlength encoded pixels.
+ */
+ q=pixels;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ if (compression == LZWCompression)
+ status=LZWEncodeImage(image,length,pixels);
+ else
+ status=PackbitsEncodeImage(image,length,pixels);
+ MagickFreeMemory(pixels);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ break;
+ }
+ case NoCompression:
+ {
+ /*
+ Dump uncompressed PseudoColor packets.
+ */
+ Ascii85Initialize(image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ Ascii85Encode(image,
+ ScaleQuantumToChar(PixelIntensityToQuantum(p)));
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ Ascii85Flush(image);
+ break;
+ }
+ }
+ }
+ else
+ if ((image->storage_class == DirectClass) || (image->colors > 256) ||
+ (compression == JPEGCompression))
+ {
+ FormatString(buffer,"%lu %lu\n0\n%d\n",image->columns,image->rows,
+ (int) (image->colorspace == CMYKColorspace));
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%d\n",(int) (compression == NoCompression));
+ (void) WriteBlobString(image,buffer);
+ switch (compression)
+ {
+ case JPEGCompression:
+ {
+ /*
+ Write image in JPEG format.
+ */
+ blob=ImageToJPEGBlob(image,image_info,&length,&image->exception);
+ if (blob == (char *) NULL)
+ ThrowWriterException2(CoderError,image->exception.reason,image);
+ (void) WriteBlob(image,length,blob);
+ MagickFreeMemory(blob);
+ break;
+ }
+ case RLECompression:
+ default:
+ {
+ register unsigned char
+ *q;
+
+ /*
+ Allocate pixel array.
+ */
+ length=(image->colorspace == CMYKColorspace ? 4 : 3)*
+ number_pixels;
+ pixels=MagickAllocateMemory(unsigned char *,length);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Dump Packbit encoded pixels.
+ */
+ q=pixels;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->matte && (p->opacity == TransparentOpacity))
+ {
+ *q++=ScaleQuantumToChar(MaxRGB);
+ *q++=ScaleQuantumToChar(MaxRGB);
+ *q++=ScaleQuantumToChar(MaxRGB);
+ }
+ else
+ if (image->colorspace != CMYKColorspace)
+ {
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ }
+ else
+ {
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ *q++=ScaleQuantumToChar(p->opacity);
+ }
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ if (compression == LZWCompression)
+ status=LZWEncodeImage(image,length,pixels);
+ else
+ status=PackbitsEncodeImage(image,length,pixels);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ MagickFreeMemory(pixels);
+ break;
+ }
+ case NoCompression:
+ {
+ /*
+ Dump uncompressed DirectColor packets.
+ */
+ Ascii85Initialize(image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->matte && (p->opacity == TransparentOpacity))
+ {
+ Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
+ Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
+ Ascii85Encode(image,ScaleQuantumToChar(MaxRGB));
+ }
+ else
+ if (image->colorspace != CMYKColorspace)
+ {
+ Ascii85Encode(image,ScaleQuantumToChar(p->red));
+ Ascii85Encode(image,ScaleQuantumToChar(p->green));
+ Ascii85Encode(image,ScaleQuantumToChar(p->blue));
+ }
+ else
+ {
+ Ascii85Encode(image,ScaleQuantumToChar(p->red));
+ Ascii85Encode(image,ScaleQuantumToChar(p->green));
+ Ascii85Encode(image,ScaleQuantumToChar(p->blue));
+ Ascii85Encode(image,ScaleQuantumToChar(p->opacity));
+ }
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ Ascii85Flush(image);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ Dump number of colors and colormap.
+ */
+ FormatString(buffer,"%lu %lu\n1\n%d\n",image->columns,image->rows,
+ (int) (image->colorspace == CMYKColorspace));
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%d\n",(int) (compression == NoCompression));
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%u\n",image->colors);
+ (void) WriteBlobString(image,buffer);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ FormatString(buffer,"%02X%02X%02X\n",
+ ScaleQuantumToChar(image->colormap[i].red),
+ ScaleQuantumToChar(image->colormap[i].green),
+ ScaleQuantumToChar(image->colormap[i].blue));
+ (void) WriteBlobString(image,buffer);
+ }
+ switch (compression)
+ {
+ case RLECompression:
+ default:
+ {
+ register unsigned char
+ *q;
+
+ /*
+ Allocate pixel array.
+ */
+ length=number_pixels;
+ pixels=MagickAllocateMemory(unsigned char *,length);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Dump Runlength encoded pixels.
+ */
+ q=pixels;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ *q++=indexes[x];
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ if (compression == LZWCompression)
+ status=LZWEncodeImage(image,length,pixels);
+ else
+ status=PackbitsEncodeImage(image,length,pixels);
+ MagickFreeMemory(pixels);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ break;
+ }
+ case NoCompression:
+ {
+ /*
+ Dump uncompressed PseudoColor packets.
+ */
+ Ascii85Initialize(image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ Ascii85Encode(image,indexes[x]);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,
+ SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ Ascii85Flush(image);
+ break;
+ }
+ }
+ }
+ (void) WriteBlobByte(image,'\n');
+ current=TellBlob(image);
+ if (current < 0)
+ ThrowWriterException(BlobError,UnableToObtainOffset,image);
+ length=current-stop;
+ stop=TellBlob(image);
+ if (stop < 0)
+ ThrowWriterException(BlobError,UnableToObtainOffset,image);
+ if (SeekBlob(image,start,SEEK_SET) != start)
+ ThrowWriterException(BlobError,UnableToSeekToOffset,image);
+ FormatString(buffer,"%%%%BeginData:%13ld %s Bytes\n",(long) length,
+ compression == NoCompression ? "ASCII" : "Binary");
+ (void) WriteBlobString(image,buffer);
+ if (SeekBlob(image,stop,SEEK_SET) != stop)
+ ThrowWriterException(BlobError,UnableToSeekToOffset,image);
+ (void) WriteBlobString(image,"%%EndData\n");
+ if (LocaleCompare(image_info->magick,"PS2") != 0)
+ (void) WriteBlobString(image,"end\n");
+ (void) WriteBlobString(image,"%%PageTrailer\n");
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ (void) WriteBlobString(image,"%%Trailer\n");
+ if (page > 1)
+ {
+ FormatString(buffer,"%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5),
+ floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5));
+ (void) WriteBlobString(image,buffer);
+ }
+ (void) WriteBlobString(image,"%%EOF\n");
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/ps3.c b/coders/ps3.c
new file mode 100644
index 0000000..706b591
--- /dev/null
+++ b/coders/ps3.c
@@ -0,0 +1,2057 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP SSSSS 33333 %
+% P P SS 33 %
+% PPPP SSS 333 %
+% P SS 33 %
+% P SSSSS 33333 %
+% %
+% %
+% Write Postscript Level III Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/channel.h"
+#include "magick/color.h"
+#include "magick/compress.h"
+#include "magick/constitute.h"
+#include "magick/enum_strings.h"
+#include "magick/magick.h"
+#include "magick/map.h"
+#include "magick/monitor.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#if defined(HasTIFF)
+#define CCITTParam "-1"
+#else
+#define CCITTParam "0"
+#endif
+
+/* For consistent PS and C code usage */
+#define PS3_NoCompression "0"
+#define PS3_FaxCompression "1"
+#define PS3_RLECompression "2"
+#define PS3_LZWCompression "3"
+#define PS3_ZipCompression "4"
+#define PS3_JPEGCompression "5"
+
+#define PS3_RGBColorspace "0"
+#define PS3_CMYKColorspace "1"
+
+#define PS3_DirectClass "0"
+#define PS3_PseudoClass "1"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePS3Image(const ImageInfo *,Image *),
+ ZLIBEncode2Image(Image *,const size_t,const unsigned long,unsigned char *,
+ WriteByteHook,void *);
+
+#if defined(HasTIFF)
+#if defined(HAVE_TIFFCONF_H)
+#include "tiffconf.h"
+#endif
+#include "tiffio.h"
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H u f f m a n 2 D E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Huffman2DEncodeImage compresses an image via two-dimensional
+% Huffman-coding.
+%
+% The format of the Huffman2DEncodeImage method is:
+%
+% unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
+% Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method Huffman2DEncodeImage returns True if all the pixels are
+% compressed without error, otherwise False.
+%
+% o image_info: The image info..
+%
+% o image: The image.
+%
+*/
+static unsigned int SerializeHuffman2DImage(const ImageInfo *image_info,
+ Image *image, unsigned char **pixels, size_t *length)
+{
+ char
+ filename[MaxTextExtent];
+
+ Image
+ *huffman_image;
+
+ ImageInfo
+ *clone_info;
+
+ long
+ count,
+ j;
+
+ register long
+ i;
+
+ TIFF
+ *tiff;
+
+ uint16
+ fillorder;
+
+ unsigned char
+ *buffer,
+ *p;
+
+ unsigned int
+ status;
+
+ unsigned long
+ *byte_count,
+ strip_size;
+
+ /*
+ Write image as CCITTFax4 TIFF image to a temporary file.
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if(!AcquireTemporaryFileName(filename))
+ {
+ ThrowBinaryException(FileOpenError,UnableToCreateTemporaryFile,
+ filename)
+ }
+ huffman_image=CloneImage(image,0,0,True,&image->exception);
+ if (huffman_image == (Image *) NULL)
+ return(False);
+ /*
+ TODO: If (image, then) huffman_image->compression is JPEG, huffman_image
+ is changed to DirectClass in WriteTIFFImage and the huffman_image ends up
+ broken. Change WriteTIFFIMage to not alter bilevel image to directclass
+ when clone_info is G4 compression. Until then, set
+ huffman_image->compression here:
+ */
+ huffman_image->compression=Group4Compression;
+
+ (void) SetImageType(huffman_image,BilevelType);
+ FormatString(huffman_image->filename,"tiff:%s",filename);
+ clone_info=CloneImageInfo(image_info);
+ clone_info->compression=Group4Compression;
+ clone_info->type=BilevelType;
+ (void) AddDefinitions(clone_info,"tiff:fill-order=msb2lsb",
+ &image->exception);
+ status=WriteImage(clone_info,huffman_image);
+ DestroyImageInfo(clone_info);
+ DestroyImage(huffman_image);
+ if (status == False)
+ {
+ (void) LiberateTemporaryFile(filename);
+ return(False);
+ }
+ tiff=TIFFOpen(filename,"rb");
+ if (tiff == (TIFF *) NULL)
+ {
+ (void) LiberateTemporaryFile(filename);
+ ThrowBinaryException(FileOpenError,UnableToOpenFile,
+ image_info->filename)
+ }
+ /*
+ Allocate raw strip buffer.
+ */
+ (void) TIFFGetField(tiff,TIFFTAG_STRIPBYTECOUNTS,&byte_count);
+ *length=strip_size=byte_count[0];
+ for (i=1; i < (long) TIFFNumberOfStrips(tiff); i++)
+ {
+ if (byte_count[i] > strip_size)
+ strip_size=byte_count[i];
+ *length+=byte_count[i];
+ }
+ buffer=MagickAllocateMemory(unsigned char *,strip_size);
+ if (buffer == (unsigned char *) NULL)
+ {
+ TIFFClose(tiff);
+ (void) LiberateTemporaryFile(filename);
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL)
+ }
+ *pixels=MagickAllocateMemory(unsigned char *,*length);
+ if (*pixels == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(buffer);
+ TIFFClose(tiff);
+ (void) LiberateTemporaryFile(filename);
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL)
+ }
+
+ (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_FILLORDER,&fillorder);
+ p=(*pixels);
+ for (i=0; i < (long) TIFFNumberOfStrips(tiff); i++)
+ {
+ count=TIFFReadRawStrip(tiff,(uint32) i,buffer,(long) byte_count[i]);
+ if (fillorder == FILLORDER_LSB2MSB)
+ TIFFReverseBits(buffer,count);
+ for (j=0; j < count; j++)
+ *p++=buffer[j];
+ }
+ MagickFreeMemory(buffer);
+ TIFFClose(tiff);
+ (void) LiberateTemporaryFile(filename);
+ return(True);
+}
+
+static unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
+ Image *image)
+{
+ size_t
+ length;
+
+ register unsigned long
+ i;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ status;
+
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ status=SerializeHuffman2DImage(image_info,image,&pixels,&length);
+ if (!status)
+ return False;
+
+ Ascii85Initialize(image);
+ for (i=0; i < length; i++)
+ Ascii85Encode(image,(unsigned long) pixels[i]);
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ return(True);
+}
+
+#else
+
+static unsigned int SerializeHuffman2DImage(const ImageInfo *image_info,
+ Image *image, unsigned char **pixels, size_t *length)
+{
+ ARG_NOT_USED(image_info);
+ ARG_NOT_USED(pixels);
+ ARG_NOT_USED(length);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ ThrowBinaryException(MissingDelegateError,TIFFLibraryIsNotAvailable,image->filename)
+}
+static unsigned int Huffman2DEncodeImage(const ImageInfo *image_info,
+ Image *image)
+{
+ ARG_NOT_USED(image_info);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ ThrowBinaryException(MissingDelegateError,TIFFLibraryIsNotAvailable,image->filename)
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% J P E G E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method JPEGEncodeImage compresses an image via JPEG compression.
+%
+% The format of the JPEGEncodeImage method is:
+%
+% unsigned int JPEGEncodeImage(const ImageInfo *image_info,
+% Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method JPEGEncodeImage returns True if all the pixels are
+% compressed without error, otherwise False.
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+*/
+static MagickPassFail JPEGEncodeImage(const ImageInfo *image_info,
+ Image *image)
+{
+ unsigned char
+ *blob;
+
+ size_t
+ length;
+
+ MagickPassFail
+ status=MagickFail;
+
+ blob=ImageToJPEGBlob(image,image_info,&length,&image->exception);
+ if (blob != (unsigned char *) NULL)
+ {
+ register const unsigned char
+ *p;
+
+ register size_t
+ i;
+
+ Ascii85Initialize(image);
+ for (p=(const unsigned char*) blob,i=0; i < length; i++)
+ Ascii85Encode(image,(unsigned long) p[i]);
+ Ascii85Flush(image);
+ MagickFreeMemory(blob);
+ status=MagickPass;
+ }
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P S 3 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPS3Image adds attributes for the PS3 image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPS3Image method is:
+%
+% RegisterPS3Image(void)
+%
+*/
+ModuleExport void RegisterPS3Image(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("EPS3");
+ entry->encoder=(EncoderHandler) WritePS3Image;
+ entry->description="Adobe Level III Encapsulated PostScript";
+ entry->seekable_stream=MagickTrue;
+ entry->module="PS3";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PS3");
+ entry->encoder=(EncoderHandler) WritePS3Image;
+ entry->description="Adobe Level III PostScript";
+ entry->seekable_stream=MagickTrue;
+ entry->module="PS3";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e r i a l i z e P s e u d o C l a s s I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Convert the indexes of a color mapped image to a stream of bytes.
+%
+% The format of the SerializePseudoClassImage method is:
+%
+% unsigned int SerializePseudoClassImage(const ImageInfo *image_info,
+% Image *image, unsigned char **pixels, size_t *length)
+%
+% A description of each parameter follows:
+%
+% o image_info: Specifies a pointer to a ImageInfo structure. required by
+% exception handlers.
+%
+% o image: The image for which the color map indexes should be serialized.
+%
+% o pixels: the serialized indexes.
+%
+% o length: the length of the pixels mamory area.
+%
+*/
+static unsigned int SerializePseudoClassImage(const ImageInfo *image_info,
+ Image *image, unsigned char **pixels, size_t *length)
+{
+ long
+ x,
+ y;
+
+ register unsigned char
+ *q;
+
+ const PixelPacket
+ *p;
+
+ int
+ status;
+
+ register const IndexPacket
+ *indexes;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=True;
+ *length=image->columns*image->rows;
+ *pixels=MagickAllocateMemory(unsigned char *, *length);
+ if (*pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ q=(*pixels);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ *q++=indexes[x];
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ if (status == False)
+ MagickFreeMemory(*pixels);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e r i a l i z e M u l t i C h a n n e l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Convert three and four channel images to a stream of bytes.
+%
+% The format of the SerializeMultiChannelImage method is:
+%
+% unsigned int SerializeMultiChannelImage(const ImageInfo *image_info,
+% Image *image, unsigned char **pixels, size_t *length)
+%
+% A description of each parameter follows:
+%
+% o image_info: Specifies a pointer to a ImageInfo structure. required by
+% exception handlers.
+%
+% o image: The image for which the RGB or CMYK channels should be
+% serialized.
+%
+% o pixels: the serialized image channels.
+%
+% o length: the length of the pixels mamory area.
+%
+*/
+static unsigned int SerializeMultiChannelImage(const ImageInfo *image_info,
+ Image *image, unsigned char **pixels, size_t *length)
+{
+ long
+ x,
+ y;
+
+ register unsigned char
+ *q;
+
+ const PixelPacket
+ *p;
+
+ int
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=True;
+ *length=(image->colorspace == CMYKColorspace ? 4 : 3)*image->columns*image->rows;
+ *pixels=MagickAllocateMemory(unsigned char *, *length);
+ if (*pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ q=(*pixels);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if (image->colorspace == CMYKColorspace)
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ *q++=ScaleQuantumToChar(p->opacity);
+ p++;
+ }
+ else
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ if (status == False)
+ MagickFreeMemory(*pixels);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e r i a l i z e S i n g l e C h a n n e l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Convert 1 and 8 bit single channel images to a stream of bytes. Bilevel
+% image pixels are packed 8 pixels in a byte.
+%
+% The format of the SerializeSingleChannelImage method is:
+%
+% unsigned int SerializeSingleChannelImage(const ImageInfo *image_info,
+% Image *image, unsigned char **pixels, size_t *length)
+%
+% A description of each parameter follows:
+%
+% o image_info: Specifies a pointer to an ImageInfo structure. Required by
+% exception handlers.
+%
+% o image: The image for which the RGB or CMYK channels should be
+% serialized.
+%
+% o characteristics: Already populated image characteristics.
+%
+% o pixels: the serialized image channels.
+%
+% o length: the length of the pixels mamory area.
+%
+*/
+static unsigned int SerializeSingleChannelImage(const ImageInfo *image_info,
+ Image *image,unsigned char **pixels, size_t *length)
+{
+ unsigned long
+ x,
+ y;
+
+ register unsigned char
+ *q;
+
+ const PixelPacket
+ *p;
+
+ unsigned long
+ pack,
+ padded_columns;
+
+ unsigned char
+ code,
+ bit;
+
+ int
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=True;
+ pack=IsMonochromeImage(image,&image->exception) ? 8 : 1;
+ /* Padded columns are padded to byte boundary */
+ padded_columns=((image->columns+pack-1)/pack)*pack;
+ *length=padded_columns*image->rows/pack;
+ *pixels=MagickAllocateMemory(unsigned char *, *length);
+ if (*pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+
+ q=(*pixels);
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if (pack == 1)
+ {
+ for (x=0; x < image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
+ p++;
+ }
+ }
+ else
+ {
+ code=0;
+ for (x=0; x < padded_columns; x++)
+ {
+ bit=0x00;
+ if (x < image->columns)
+ bit=PixelIntensityToQuantum(p) == TransparentOpacity ? 0x01 : 0x00;
+ code=(code << 1)+bit;
+ if ((x+1) % pack == 0)
+ {
+ *q++=code;
+ code=0;
+ }
+ p++;
+ }
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(y,image->rows,
+ &image->exception,SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ if (status == False)
+ MagickFreeMemory(*pixels);
+ return(status);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P S 3 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPS3Image removes format registrations made by the
+% PS3 module from the list of supported formats.
+%
+% The format of the UnregisterPS3Image method is:
+%
+% UnregisterPS3Image(void)
+%
+*/
+ModuleExport void UnregisterPS3Image(void)
+{
+ (void) UnregisterMagickInfo("EPS3");
+ (void) UnregisterMagickInfo("PS3");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P S 3 M a s k I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePS3ImageMask writes the alpha channel of an image as an
+% Encapsulated Postscript Level III image mask. The mask is written as a
+% bilevel image, converted from the grayscale alpha channel using dithering
+% options supplied in image_info.
+%
+% The format of the WritePS3MaskImage method is:
+%
+% unsigned int WritePS3MaskImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WritePS3MaskImage return True if the mask is printed.
+% False is returned on errors like out-of-memory.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: The address of a structure of type Image.
+%
+%
+*/
+typedef struct WriteByteHookInfo_
+{
+ Image
+ *image;
+} WriteByteHookInfo;
+
+static unsigned int MaskWriteByteHook(Image *mask_image,
+ const magick_uint8_t code, void *info)
+{
+ ARG_NOT_USED(mask_image);
+ Ascii85Encode(((WriteByteHookInfo *)info)->image, (unsigned long)code);
+ return(True);
+}
+
+static MagickPassFail WritePS3MaskImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[MaxTextExtent];
+
+ Image
+ *mask_image;
+
+ size_t
+ i,
+ length;
+
+ CompressionType
+ compression;
+
+ unsigned char
+ *pixels;
+
+ MagickPassFail
+ status;
+
+ magick_off_t
+ here,
+ start,
+ stop;
+
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->matte);
+ status=MagickPass;
+ compression=image->compression;
+ if (image_info->compression != UndefinedCompression)
+ compression=image_info->compression;
+
+ /* Keep position of BeginData DSC comment for update later */
+ start=TellBlob(image);
+ if (start < 0)
+ return MagickFail;
+ FormatString(buffer,"%%%%BeginData:%13ld ASCII Bytes\n",0L);
+ (void) WriteBlobString(image,buffer);
+ stop=TellBlob(image);
+ if (stop < 0)
+ return MagickFail;
+
+ /* Only lossless compressions for the mask */
+ switch (compression)
+ {
+ case NoCompression:
+ FormatString(buffer,
+ "currentfile %lu %lu "PS3_NoCompression" ByteStreamDecodeFilter\n",
+ image->columns, image->rows);
+ break;
+ case FaxCompression:
+ default:
+ FormatString(buffer,
+ "currentfile %lu %lu "PS3_FaxCompression" ByteStreamDecodeFilter\n",
+ image->columns, image->rows);
+ break;
+ case RLECompression:
+ FormatString(buffer,
+ "currentfile %lu %lu "PS3_RLECompression" ByteStreamDecodeFilter\n",
+ image->columns, image->rows);
+ break;
+ case LZWCompression:
+ FormatString(buffer,
+ "currentfile %lu %lu "PS3_LZWCompression" ByteStreamDecodeFilter\n",
+ image->columns, image->rows);
+ break;
+ case ZipCompression:
+ FormatString(buffer,
+ "currentfile %lu %lu "PS3_ZipCompression" ByteStreamDecodeFilter\n",
+ image->columns, image->rows);
+ break;
+ }
+ (void)WriteBlobString(image, buffer);
+ (void)WriteBlobString(image, "/ReusableStreamDecode filter\n");
+
+ mask_image=CloneImage(image,0,0,True,&image->exception);
+ if (mask_image == (Image *) NULL)
+ return MagickFail;
+ status=ChannelImage(mask_image, OpacityChannel);
+ if (!status)
+ {
+ CopyException(&image->exception,&mask_image->exception);
+ DestroyImage(mask_image);
+ return(MagickFail);
+ }
+ (void) SetImageType(mask_image, BilevelType);
+ mask_image->matte=False;
+
+ /* Only lossless compressions for the mask */
+ switch (compression)
+ {
+ case NoCompression:
+ status=SerializeSingleChannelImage(image_info,mask_image,&pixels,&length);
+ if (status)
+ {
+ Ascii85Initialize(image);
+ for (i=0; i < length; i++)
+ Ascii85Encode(image, (unsigned long)pixels[i]);
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ }
+ break;
+ case FaxCompression:
+ default:
+ if (LocaleCompare(CCITTParam,"0") == 0)
+ {
+ WriteByteHookInfo
+ info;
+ info.image=image;
+ /* Read bytes from mask and write them ASCII85 encoded to image */
+ Ascii85Initialize(image);
+ status=HuffmanEncode2Image(image_info,mask_image,MaskWriteByteHook,(void *)&info);
+ Ascii85Flush(image);
+ }
+ else
+ {
+ status=SerializeHuffman2DImage(image_info,mask_image,&pixels,&length);
+ if (status)
+ {
+ Ascii85Initialize(image);
+ for (i=0; i < length; i++)
+ Ascii85Encode(image,(unsigned long) pixels[i]);
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ }
+ }
+ break;
+ case RLECompression:
+ status=SerializeSingleChannelImage(image_info,mask_image,&pixels,&length);
+ if (status)
+ {
+ Ascii85Initialize(image);
+ status=PackbitsEncode2Image(image,length,pixels,
+ Ascii85WriteByteHook,(void *)NULL);
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ }
+ break;
+ case LZWCompression:
+ status=SerializeSingleChannelImage(image_info,mask_image,&pixels,&length);
+ if (status)
+ {
+ Ascii85Initialize(image);
+ status=LZWEncode2Image(image,length,pixels,Ascii85WriteByteHook,(void*)NULL);
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ }
+ break;
+ case ZipCompression:
+ status=SerializeSingleChannelImage(image_info,mask_image,&pixels,&length);
+ if (status)
+ {
+ Ascii85Initialize(image);
+ status=ZLIBEncode2Image(image,length,image_info->quality,pixels,
+ Ascii85WriteByteHook,(void*)NULL);
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ }
+ break;
+ }
+ DestroyImage(mask_image);
+ here=TellBlob(image);
+ if (here < 0)
+ return MagickFail;
+ length=here-stop;
+ stop=TellBlob(image);
+ if (stop < 0)
+ return MagickFail;
+ if (SeekBlob(image,start,SEEK_SET) != start)
+ ThrowWriterException(BlobError,UnableToSeekToOffset,image);
+ FormatString(buffer,"%%%%BeginData:%13ld ASCII Bytes\n",(long) length);
+ (void) WriteBlobString(image,buffer);
+ if (SeekBlob(image,stop,SEEK_SET) != stop)
+ ThrowWriterException(BlobError,UnableToSeekToOffset,image);
+ (void) WriteBlobString(image,"%%EndData\n");
+ (void)WriteBlobString(image, "/mask_stream exch def\n");
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P S 3 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePS3Image translates an image to encapsulated Postscript
+% Level III for printing. If the supplied geometry is null, the image is
+% centered on the Postscript page. Otherwise, the image is positioned as
+% specified by the geometry.
+%
+% The format of the WritePS3Image method is:
+%
+% unsigned int WritePS3Image(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WritePS3Image return True if the image is printed.
+% False is returned if the image file cannot be opened for printing.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: The address of a structure of type Image; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int WritePS3Image(const ImageInfo *image_info,Image *image)
+{
+ static const char
+ * const PostscriptProlog[]=
+ {
+ "/ByteStreamDecodeFilter",
+ "{",
+ " /z exch def",
+ " /r exch def",
+ " /c exch def",
+ " /ASCII85Decode filter",
+ " z "PS3_FaxCompression" eq",
+ " {",
+ " <<",
+ " /K "CCITTParam,
+ " /Columns c",
+ " /Rows r",
+ " >>",
+ " /CCITTFaxDecode filter",
+ " } if",
+ " z "PS3_RLECompression" eq {/RunLengthDecode filter} if",
+ " z "PS3_LZWCompression" eq {/LZWDecode filter} if",
+ " z "PS3_ZipCompression" eq {/FlateDecode filter} if",
+ " z "PS3_JPEGCompression" eq {/DCTDecode filter} if",
+ "} bind def",
+ "",
+ "/DirectClassImageDict",
+ "{",
+ " colorspace "PS3_RGBColorspace" eq",
+ " {",
+ " /DeviceRGB setcolorspace",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent 8",
+ " /DataSource pixel_stream",
+ " /MultipleDataSources false",
+ " /ImageMatrix [columns 0 0 rows neg 0 rows]",
+ " /Decode [0 1 0 1 0 1]",
+ " >>",
+ " }",
+ " {",
+ " /DeviceCMYK setcolorspace",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent 8",
+ " /DataSource pixel_stream",
+ " /MultipleDataSources false",
+ " /ImageMatrix [columns 0 0 rows neg 0 rows]",
+ " /Decode",
+ /*
+ JPEG coder is used for JPEG compression. It compensates
+ for inverted CMYK, so use an inverted decode matrix for
+ JPEG compressed CMYK images.
+ */
+ " compression "PS3_JPEGCompression" eq",
+ " {[1 0 1 0 1 0 1 0]}",
+ " {[0 1 0 1 0 1 0 1]}",
+ " ifelse",
+ " >>",
+ " }",
+ " ifelse",
+ "} bind def",
+ "",
+ "/PseudoClassImageDict",
+ "{",
+ " % COLORS IN PSEUDO CLASS IMAGE",
+ " currentfile buffer readline pop",
+ " token pop /colors exch def pop",
+ " colors 0 eq",
+ " {",
+ " % DEPTH OF GRAYSCALE",
+ " currentfile buffer readline pop",
+ " token pop /bits exch def pop",
+ " /DeviceGray setcolorspace",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent bits",
+ " /Decode [0 1]",
+ " /ImageMatrix [columns 0 0 rows neg 0 rows]",
+ " /DataSource pixel_stream",
+ " >>",
+ " }",
+ " {",
+ " % RGB COLORMAP",
+ " /colormap colors 3 mul string def",
+ " % INDEXES",
+ " currentfile /ASCII85Decode filter colormap readstring pop pop",
+ " [ /Indexed /DeviceRGB colors 1 sub colormap ] setcolorspace",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent 8",
+ " /Decode [0 255]",
+ " /ImageMatrix [columns 0 0 rows neg 0 rows]",
+ " /DataSource pixel_stream",
+ " >>",
+ " }",
+ " ifelse",
+ "} bind def",
+ "",
+ "/NonMaskedImageDict",
+ "{",
+ " class "PS3_PseudoClass" eq",
+ " { PseudoClassImageDict }",
+ " { DirectClassImageDict }",
+ " ifelse",
+ "} bind def",
+ "",
+ "/MaskedImageDict",
+ "{",
+ " <<",
+ " /ImageType 3",
+ " /InterleaveType 3",
+ " /DataDict NonMaskedImageDict",
+ " /MaskDict",
+ " <<",
+ " /ImageType 1",
+ " /Width columns",
+ " /Height rows",
+ " /BitsPerComponent 1",
+ " /DataSource mask_stream",
+ " /MultipleDataSources false",
+ " /ImageMatrix [ columns 0 0 rows neg 0 rows]",
+ " /Decode [ 0 1 ]",
+ " >>",
+ " >>",
+ "} bind def",
+ "",
+ /*
+ Default procedure for image clipping does nothing. Image
+ will provide overriding ClipPath procdure if relevant.
+ */
+ "/ClipImage",
+ "{} def",
+ "",
+ "/DisplayImage",
+ "{",
+ " /buffer 512 string def",
+ "",
+ " % TRANSLATION",
+ " currentfile buffer readline pop",
+ " token pop /x exch def",
+ " token pop /y exch def pop",
+ " x y translate",
+ "",
+ " % IMAGE SIZE AND FONT SIZE",
+ " currentfile buffer readline pop",
+ " token pop /x exch def",
+ " token pop /y exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /pointsize exch def pop",
+ (const char *) NULL
+ },
+ /*
+ This hole in the PS prolog is for labels.
+ */
+ *PostscriptEpilog[]=
+ {
+ " x y scale",
+ "",
+ " % CLIPPING PATH",
+ " currentfile buffer readline pop",
+ " token pop /clipped exch def pop",
+ "",
+ " % EPS",
+ " currentfile buffer readline pop",
+ " token pop /sp exch def pop",
+ "",
+ " % IMAGE PIXEL SIZE",
+ " currentfile buffer readline pop",
+ " token pop /columns exch def",
+ " token pop /rows exch def pop",
+ "",
+ " % COLORSPACE (RGB/CMYK)",
+ " currentfile buffer readline pop",
+ " token pop /colorspace exch def pop",
+ "",
+ " % TRANSPARENCY",
+ " currentfile buffer readline pop",
+ " token pop /alpha exch def pop",
+ "",
+ " % STENCIL MASK?",
+ " currentfile buffer readline pop",
+ " token pop /stencil exch def pop",
+ "",
+ " % IMAGE CLASS (DIRECT/PSEUDO)",
+ " currentfile buffer readline pop",
+ " token pop /class exch def pop",
+ "",
+ " % COMPRESSION",
+ " currentfile buffer readline pop",
+ " token pop /compression exch def pop",
+ "",
+ " % CLIP AND RENDER",
+ " /pixel_stream currentfile columns rows compression",
+ " ByteStreamDecodeFilter def",
+ " clipped {ClipImage} if",
+ " alpha stencil not and",
+ " { MaskedImageDict mask_stream resetfile }",
+ " { NonMaskedImageDict }",
+ " ifelse",
+ " stencil {0 setgray imagemask} {image} ifelse",
+ " grestore",
+ " sp {showpage} if",
+ "} bind def",
+ (const char *) NULL
+ };
+
+ char
+ buffer[MaxTextExtent],
+ date[MaxTextExtent],
+ density[MaxTextExtent],
+ page_geometry[MaxTextExtent],
+ **labels;
+
+ const char
+ * const *q;
+
+ CompressionType
+ compression;
+
+ const ImageAttribute
+ *attribute;
+
+ double
+ dx_resolution,
+ dy_resolution,
+ x_resolution,
+ x_scale,
+ y_resolution,
+ y_scale;
+
+ magick_off_t
+ current,
+ start,
+ stop;
+
+ int
+ count,
+ status;
+
+ RectangleInfo
+ geometry;
+
+ register unsigned int
+ i,
+ j;
+
+ SegmentInfo
+ bounds={0.0,0.0,0.0,0.0};
+
+ size_t
+ length;
+
+ time_t
+ timer;
+
+ unsigned char
+ *pixels;
+
+ unsigned long
+ page,
+ scene,
+ text_size;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ compression=image->compression;
+ if (image_info->compression != UndefinedCompression)
+ compression=image_info->compression;
+ switch (compression)
+ {
+#if !defined(HasJPEG)
+ case JPEGCompression:
+ {
+ compression=RLECompression;
+ ThrowException(&image->exception,MissingDelegateError,JPEGLibraryIsNotAvailable,image->filename);
+ break;
+ }
+#endif
+#if !defined(HasZLIB)
+ case ZipCompression:
+ {
+ compression=RLECompression;
+ ThrowException(&image->exception,MissingDelegateError,ZipLibraryIsNotAvailable,image->filename);
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+ page=0;
+ scene=0;
+ do
+ {
+ page++;
+ /*
+ Scale image to size of Postscript page.
+ */
+ text_size=0;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ text_size=(unsigned int)(MultilineCensus(attribute->value)*
+ image_info->pointsize+12);
+ SetGeometry(image,&geometry);
+ geometry.y=(long) text_size;
+ FormatString(page_geometry,"%lux%lu",image->columns,image->rows);
+ if (image_info->page != (char *) NULL)
+ {
+ (void) strlcpy(page_geometry,image_info->page,MaxTextExtent);
+ }
+ else
+ {
+ if ((image->page.width != 0) && (image->page.height != 0))
+ (void) FormatString(page_geometry,"%lux%lu%+ld%+ld",
+ image->page.width,image->page.height,image->page.x,
+ image->page.y);
+ else
+ if (LocaleCompare(image_info->magick,"PS3") == 0)
+ (void) strlcpy(page_geometry,PSPageGeometry,sizeof(page_geometry));
+ }
+ (void) GetMagickGeometry(page_geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image Resolution: %gx%g %s",
+ image->x_resolution,
+ image->y_resolution,
+ ResolutionTypeToString(image->units));
+ /*
+ Scale relative to dots-per-inch. First whatever resolution passed
+ in image_info. Then resolution from the image. Last default PS
+ resolution.
+ */
+ dx_resolution=72.0;
+ dy_resolution=72.0;
+ x_resolution=72.0;
+ (void) strlcpy(density,PSDensityGeometry,sizeof(density));
+ count=GetMagickDimension(density,&x_resolution,&y_resolution,NULL,NULL);
+ if (count != 2)
+ y_resolution=x_resolution;
+ /*
+ Use override resolution information if it appears to be valid.
+ */
+ if ((image_info->density != (char *) NULL) &&
+ ((image_info->units == PixelsPerInchResolution) ||
+ (image_info->units == PixelsPerCentimeterResolution)))
+ {
+ count=GetMagickDimension(image_info->density,&x_resolution,
+ &y_resolution,NULL,NULL);
+ if (count != 2)
+ y_resolution=x_resolution;
+ if (image_info->units == PixelsPerCentimeterResolution)
+ {
+ x_resolution *= 2.54;
+ y_resolution *= 2.54;
+ }
+ }
+ /*
+ Use image resolution information if it appears to be valid.
+ */
+ else if ((image->x_resolution > 0.0) && (image->y_resolution > 0.0) &&
+ ((image->units == PixelsPerInchResolution) ||
+ (image->units == PixelsPerCentimeterResolution)))
+ {
+ x_resolution = image->x_resolution;
+ y_resolution = image->y_resolution;
+ if (image->units == PixelsPerCentimeterResolution)
+ {
+ x_resolution *= 2.54;
+ y_resolution *= 2.54;
+ }
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Postscript Resolution: %gx%g DPI",
+ x_resolution,y_resolution);
+ x_scale=(geometry.width*dx_resolution)/x_resolution;
+ geometry.width=(unsigned long) (x_scale+0.5);
+ y_scale=(geometry.height*dy_resolution)/y_resolution;
+ geometry.height=(unsigned long) (y_scale+0.5);
+
+ /*
+ Postscript header on the first page
+ */
+ if (page == 1)
+ {
+ /* Postscript magic */
+ if (LocaleCompare(image_info->magick,"PS3") == 0)
+ (void) strlcpy(buffer,"%!PS-Adobe-3.0\n", sizeof(buffer));
+ else
+ (void) strlcpy(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n", sizeof(buffer));
+ (void) WriteBlobString(image,buffer);
+
+ /* Creator */
+ FormatString(buffer,"%%%%Creator: GraphicsMagick %s\n",
+ MagickLibVersionText);
+ (void) WriteBlobString(image,buffer);
+
+ /* Title */
+ FormatString(buffer,"%%%%Title: %.1024s\n",image->filename);
+ (void) WriteBlobString(image,buffer);
+
+ /* File creation timestamp */
+ timer=time((time_t *) NULL);
+ (void) localtime(&timer);
+ (void) strlcpy(date,ctime(&timer),MaxTextExtent);
+ date[strlen(date)-1]='\0';
+ FormatString(buffer,"%%%%CreationDate: %.1024s\n",date);
+ (void) WriteBlobString(image,buffer);
+
+ /* Bounding box and process colors if not RGB */
+ bounds.x1=geometry.x;
+ bounds.y1=geometry.y;
+ bounds.x2=geometry.x+x_scale;
+ bounds.y2=geometry.y+y_scale+text_size;
+ if (image_info->adjoin && (image->next != (Image *) NULL))
+ {
+ (void) WriteBlobString(image,"%%BoundingBox: (atend)\n");
+ (void) WriteBlobString(image,"%%HiResBoundingBox: (atend)\n");
+ /* No document process colors if there's more than one page */
+ }
+ else
+ {
+ FormatString(buffer,"%%%%BoundingBox: %g %g %g %g\n",
+ floor(bounds.x1+0.5),floor(bounds.y1+0.5),ceil(bounds.x2-0.5),
+ ceil(bounds.y2-0.5));
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%%%%HiResBoundingBox: %.7g %.7g %.7g %.7g\n",
+ bounds.x1,bounds.y1,bounds.x2,bounds.y2);
+ (void) WriteBlobString(image,buffer);
+
+ if (image->colorspace == CMYKColorspace)
+ (void) WriteBlobString(image,
+ "%%DocumentProcessColors: Cyan Magenta Yellow Black\n");
+ else
+ if (IsGrayImage(image,&image->exception))
+ (void) WriteBlobString(image,
+ "%%DocumentProcessColors: Black\n");
+ }
+
+ /* Font resources */
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) WriteBlobString(image,
+ "%%DocumentNeededResources: font Helvetica\n");
+
+ /* Language level */
+ (void) WriteBlobString(image,"%%LanguageLevel: 3\n");
+
+ /* Pages, orientation, and page order */
+ if (LocaleCompare(image_info->magick,"PS3") != 0)
+ {
+ (void) WriteBlobString(image,"%%Pages: 1\n");
+ }
+ else
+ {
+ (void) WriteBlobString(image,"%%Orientation: Portrait\n");
+ (void) WriteBlobString(image,"%%PageOrder: Ascend\n");
+ if (!image_info->adjoin)
+ (void) strlcpy(buffer,"%%Pages: 1\n",sizeof(buffer));
+ else
+ FormatString(buffer,"%%%%Pages: %lu\n",(unsigned long)
+ GetImageListLength(image));
+ (void) WriteBlobString(image,buffer);
+ }
+ (void) WriteBlobString(image,"%%EndComments\n");
+
+ /* The static postscript procedures prolog. */
+ (void)WriteBlobString(image,"%%BeginProlog\n");
+ for (q=PostscriptProlog; *q; q++)
+ {
+ (void) WriteBlobString(image,*q);
+ (void) WriteBlobByte(image,'\n');
+ }
+
+ /* One label line for each line in label string */
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ {
+ long
+ si;
+
+ (void) WriteBlobString(image,"\n % LABELS\n /Helvetica "
+ "findfont pointsize scalefont setfont\n");
+ for (si=(long) MultilineCensus(attribute->value)-1; si >= 0; si--)
+ {
+ (void) WriteBlobString(image,
+ " currentfile buffer readline pop token pop\n");
+ FormatString(buffer," 0 y %g add moveto show pop\n",
+ si*image_info->pointsize+12);
+ (void) WriteBlobString(image,buffer);
+ }
+ }
+
+ /* The static postscript procedures epilog. */
+ for (q=PostscriptEpilog; *q; q++)
+ {
+ (void) WriteBlobString(image,*q);
+ (void) WriteBlobByte(image,'\n');
+ }
+ (void)WriteBlobString(image,"%%EndProlog\n");
+ }
+
+ /* Page number */
+ FormatString(buffer,"%%%%Page: 1 %lu\n",page);
+ (void) WriteBlobString(image,buffer);
+
+ /* Page bounding box */
+ FormatString(buffer,"%%%%PageBoundingBox: %ld %ld %ld %ld\n",geometry.x,
+ geometry.y,geometry.x+(long) geometry.width,geometry.y+(long)
+ (geometry.height+text_size));
+ (void) WriteBlobString(image,buffer);
+
+ /* Page process colors if not RGB */
+ if (image->colorspace == CMYKColorspace)
+ (void) WriteBlobString(image,
+ "%%PageProcessColors: Cyan Magenta Yellow Black\n");
+ else
+ if (IsGrayImage(image,&image->exception))
+ (void) WriteBlobString(image,"%%PageProcessColors: Black\n");
+
+ /*
+ Adjust document bounding box to bound page bounding
+ box if page bounding box is the larger
+ */
+ if (geometry.x < bounds.x1)
+ bounds.x1=geometry.x;
+ if (geometry.y < bounds.y1)
+ bounds.y1=geometry.y;
+ if ((geometry.x+x_scale) > bounds.x2)
+ bounds.x2=geometry.x+x_scale;
+ if ((geometry.y+y_scale+text_size) > bounds.y2)
+ bounds.y2=geometry.y+y_scale+text_size;
+
+ /* Page font resource if there's a label */
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) WriteBlobString(image,"%%PageResources: font Helvetica\n");
+
+ /* PS clipping path from Photoshop clipping path */
+ if ((image->clip_mask != (Image *) NULL) &&
+ (LocaleNCompare("8BIM:",image->clip_mask->magick_filename,5) == 0))
+ {
+ const ImageAttribute
+ *attribute;
+
+ attribute=GetImageAttribute(image,image->clip_mask->magick_filename);
+ if (attribute == (const ImageAttribute *) NULL)
+ return(False);
+ (void) WriteBlobString(image,attribute->value);
+ (void) WriteBlobByte(image,'\n');
+ }
+ else
+ {
+ /* Reset definition in case previous image had a clipping path.*/
+ (void)WriteBlobString(image,"/ClipImage {} def\n");
+ }
+
+ /* Push a dictionary for our own def's if this is an EPS */
+ if (LocaleCompare(image_info->magick,"PS3") != 0)
+ (void) WriteBlobString(image,"userdict begin\n");
+
+ /* Image mask */
+ if (image->matte)
+ if (!WritePS3MaskImage(image_info, image))
+ {
+ CloseBlob(image);
+ return(False);
+ }
+
+ /*
+ Remember position of BeginData comment so we can update
+ it when we know how many ascii85 encoded bytes we have
+ in the blob.
+ */
+ start=TellBlob(image);
+ if (start < 0)
+ ThrowWriterException(BlobError,UnableToObtainOffset,image);
+ FormatString(buffer,"%%%%BeginData:%13ld ASCII Bytes\n",0L);
+ (void) WriteBlobString(image,buffer);
+ stop=TellBlob(image);
+ if (stop < 0)
+ ThrowWriterException(BlobError,UnableToObtainOffset,image);
+
+ /* Call to image display procedure */
+ (void) WriteBlobString(image,"DisplayImage\n");
+
+ /* Translate, scale, and font point size */
+ FormatString(buffer,"%ld %ld\n%.7g %.7g\n%f\n",geometry.x,geometry.y,
+ x_scale,y_scale,image_info->pointsize);
+ (void) WriteBlobString(image,buffer);
+
+ /* Output labels */
+ labels=(char **) NULL;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ labels=StringToList(attribute->value);
+ if (labels != (char **) NULL)
+ {
+ for (i=0; labels[i] != (char *) NULL; i++)
+ {
+ Ascii85Initialize(image);
+ (void) WriteBlobString(image,"<~");
+ for (j=0; labels[i][j] != '\0'; j++)
+ Ascii85Encode(image, (unsigned long)labels[i][j]);
+ Ascii85Flush(image);
+ MagickFreeMemory(labels[i]);
+ }
+ MagickFreeMemory(labels);
+ }
+
+ /* Photoshop clipping path active? */
+ if ((image->clip_mask != (Image *) NULL) &&
+ (LocaleNCompare("8BIM:",image->clip_mask->magick_filename,5) == 0))
+ (void) WriteBlobString(image,"true\n");
+ else
+ (void) WriteBlobString(image,"false\n");
+
+ /* Compression seems to take precedence over anyting */
+ if (compression == FaxCompression)
+ (void) SetImageType(image, BilevelType);
+
+ /* Showpage for non-EPS. */
+ (void) WriteBlobString(image,
+ LocaleCompare(image_info->magick,"PS3") == 0 ? "true\n" : "false\n");
+
+ /* Image columns and rows; color space */
+ FormatString(buffer,"%lu %lu\n%.1024s\n",
+ image->columns,image->rows,image->colorspace == CMYKColorspace ?
+ PS3_CMYKColorspace : PS3_RGBColorspace);
+ (void) WriteBlobString(image,buffer);
+
+ /* Masked image? */
+ (void) WriteBlobString(image,image->matte ? "true\n" : "false\n");
+
+ /* Render with imagemask operator? */
+ if (((AccessDefinition(image_info,"ps","imagemask")) != 0) &&
+ IsMonochromeImage(image,&image->exception))
+ (void) WriteBlobString(image,"true\n");
+ else
+ (void) WriteBlobString(image,"false\n");
+
+ /*
+ Output data in one of three ways:
+ 1) 1 bit and 8 bit single channel direct color image data.
+ 2) 3 and 4 channel direct color image data
+ 3) 8 bit color mapped image data
+ */
+
+ /*
+ Output 1 bit and 8 bit single channel image data. IsGray and IsMono
+ may return true for both direct class RGB and CMYK colors, so we need
+ to test that these were not requested explicitly.
+ */
+ if ((image_info->type != TrueColorType) &&
+ (image_info->type != TrueColorMatteType) &&
+ (image_info->type != ColorSeparationType) &&
+ (image_info->type != ColorSeparationMatteType) &&
+ (image->colorspace != CMYKColorspace) &&
+ (IsGrayImage(image,&image->exception) ||
+ IsMonochromeImage(image,&image->exception)))
+ {
+ /* Image class */
+ (void) WriteBlobString(image,PS3_PseudoClass"\n");
+
+ /* Compression scheme - any */
+ switch (compression)
+ {
+ case NoCompression:
+ default:
+ (void) WriteBlobString(image,PS3_NoCompression"\n");
+ break;
+ case FaxCompression:
+ (void) WriteBlobString(image,PS3_FaxCompression"\n");
+ break;
+ case RLECompression:
+ (void) WriteBlobString(image,PS3_RLECompression"\n");
+ break;
+ case LZWCompression:
+ (void) WriteBlobString(image,PS3_LZWCompression"\n");
+ break;
+ case ZipCompression:
+ (void) WriteBlobString(image,PS3_ZipCompression"\n");
+ break;
+ case JPEGCompression:
+ (void) WriteBlobString(image,PS3_JPEGCompression"\n");
+ break;
+ }
+
+ /* Number of colors -- 0 for single component non-color mapped data */
+ (void) WriteBlobString(image,"0\n");
+
+ /* 1 bit or 8 bit components? */
+ FormatString(buffer,"%d\n",
+ IsMonochromeImage(image,&image->exception) ? 1 : 8);
+ (void) WriteBlobString(image,buffer);
+
+ /* Image data. Always ASCII85 encoded. */
+ if (compression == JPEGCompression)
+ {
+ status=JPEGEncodeImage(image_info,image);
+ }
+ else
+ if (compression == FaxCompression)
+ {
+ if (LocaleCompare(CCITTParam,"0") == 0)
+ status=HuffmanEncodeImage(image_info,image);
+ else
+ status=Huffman2DEncodeImage(image_info,image);
+ }
+ else
+ {
+ status=SerializeSingleChannelImage(image_info,image,&pixels,
+ &length);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ Ascii85Initialize(image);
+ switch (compression)
+ {
+ case NoCompression:
+ default:
+ for (i=0; i < length; i++)
+ Ascii85Encode(image, (unsigned long)pixels[i]);
+ break;
+ case RLECompression:
+ status=PackbitsEncode2Image(image,length,pixels,
+ Ascii85WriteByteHook,(void*)NULL);
+ break;
+ case LZWCompression:
+ status=LZWEncode2Image(image,length,pixels,
+ Ascii85WriteByteHook,(void*)NULL);
+ break;
+ case ZipCompression:
+ status=ZLIBEncode2Image(image,length,image_info->quality,
+ pixels,Ascii85WriteByteHook,(void*)NULL);
+ break;
+ }
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ }
+ }
+ else
+ if ((image->storage_class == DirectClass) || (image->colors > 256) ||
+ (compression == JPEGCompression))
+ {
+ /* Image class */
+ (void) WriteBlobString(image,PS3_DirectClass"\n");
+
+ /* Compression scheme - fax is only for bilevel images */
+ switch (compression)
+ {
+ case NoCompression:
+ default:
+ (void) WriteBlobString(image,PS3_NoCompression"\n");
+ break;
+ case RLECompression:
+ (void) WriteBlobString(image,PS3_RLECompression"\n");
+ break;
+ case LZWCompression:
+ (void) WriteBlobString(image,PS3_LZWCompression"\n");
+ break;
+ case ZipCompression:
+ (void) WriteBlobString(image,PS3_ZipCompression"\n");
+ break;
+ case JPEGCompression:
+ (void) WriteBlobString(image,PS3_JPEGCompression"\n");
+ break;
+ }
+
+ /* Image data. Always ASCII85 encoded. */
+ if (compression == JPEGCompression)
+ {
+ status=JPEGEncodeImage(image_info,image);
+ }
+ else
+ {
+ /* Stream based compressions */
+ status=SerializeMultiChannelImage(image_info,image,&pixels,
+ &length);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ Ascii85Initialize(image);
+ switch (compression)
+ {
+ case NoCompression:
+ default:
+ for (i=0; i < length; i++)
+ Ascii85Encode(image, (unsigned long)pixels[i]);
+ status=True;
+ break;
+ case RLECompression:
+ status=PackbitsEncode2Image(image,length,pixels,
+ Ascii85WriteByteHook,(void*)NULL);
+ break;
+ case LZWCompression:
+ status=LZWEncode2Image(image,length,pixels,
+ Ascii85WriteByteHook,(void*)NULL);
+ break;
+ case ZipCompression:
+ status=ZLIBEncode2Image(image,length,image_info->quality,
+ pixels,Ascii85WriteByteHook,(void*)NULL);
+ break;
+ }
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ }
+ }
+ else
+ {
+ /*
+ Color mapped images.
+
+ Image class.
+ */
+ (void) WriteBlobString(image,PS3_PseudoClass"\n");
+
+ /*
+ Compression scheme - fax is only for bilevel images,
+ JPEG for true color (single channel) images.
+ */
+ switch (compression)
+ {
+ case NoCompression:
+ default:
+ (void) WriteBlobString(image,PS3_NoCompression"\n");
+ break;
+ case RLECompression:
+ (void) WriteBlobString(image,PS3_RLECompression"\n");
+ break;
+ case LZWCompression:
+ (void) WriteBlobString(image,PS3_LZWCompression"\n");
+ break;
+ case ZipCompression:
+ (void) WriteBlobString(image,PS3_ZipCompression"\n");
+ break;
+ }
+
+ /* Number of colors in color map */
+ FormatString(buffer,"%u\n",image->colors);
+ (void) WriteBlobString(image,buffer);
+
+ /* Color map - uncompressed, ascii85 encoded */
+ Ascii85Initialize(image);
+ for (i=0; i < image->colors; i++)
+ {
+ Ascii85Encode(image, (unsigned long)image->colormap[i].red);
+ Ascii85Encode(image, (unsigned long)image->colormap[i].green);
+ Ascii85Encode(image, (unsigned long)image->colormap[i].blue);
+ }
+ Ascii85Flush(image);
+
+ status=SerializePseudoClassImage(image_info,image,&pixels,&length);
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+ Ascii85Initialize(image);
+ switch (compression)
+ {
+ case NoCompression:
+ default:
+ for (i=0; i < length; i++)
+ Ascii85Encode(image, (unsigned long)pixels[i]);
+ status=True;
+ break;
+ case RLECompression:
+ status=PackbitsEncode2Image(image,length,pixels,
+ Ascii85WriteByteHook,(void *)NULL);
+ break;
+ case LZWCompression:
+ status=LZWEncode2Image(image,length,pixels,Ascii85WriteByteHook,
+ (void *)NULL);
+ break;
+ case ZipCompression:
+ status=ZLIBEncode2Image(image,length,image_info->quality,pixels,
+ Ascii85WriteByteHook,(void *)NULL);
+ break;
+ }
+ Ascii85Flush(image);
+ MagickFreeMemory(pixels);
+ }
+
+ if (!status)
+ {
+ CloseBlob(image);
+ return(False);
+ }
+
+ /* Update BeginData now that we know the data size */
+ current=TellBlob(image);
+ if (current < 0)
+ ThrowWriterException(BlobError,UnableToObtainOffset,image);
+ length=current-stop;
+ stop=TellBlob(image);
+ if (stop < 0)
+ ThrowWriterException(BlobError,UnableToObtainOffset,image);
+ if (SeekBlob(image,start,SEEK_SET) != start)
+ ThrowWriterException(BlobError,UnableToSeekToOffset,image);
+ FormatString(buffer,"%%%%BeginData:%13ld ASCII Bytes\n",(long) length);
+ (void) WriteBlobString(image,buffer);
+ if (SeekBlob(image,stop,SEEK_SET) != stop)
+ ThrowWriterException(BlobError,UnableToSeekToOffset,image);
+ (void) WriteBlobString(image,"%%EndData\n");
+
+ /* End private dictionary if this is an EPS */
+ if (LocaleCompare(image_info->magick,"PS3") != 0)
+ (void) WriteBlobString(image,"end\n");
+
+ (void) WriteBlobString(image,"%%PageTrailer\n");
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ scene++;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ (void) WriteBlobString(image,"%%Trailer\n");
+ if (page > 1)
+ {
+ FormatString(buffer,"%%%%BoundingBox: %g %g %g %g\n",
+ floor(bounds.x1+0.5),floor(bounds.y1+0.5),ceil(bounds.x2-0.5),
+ ceil(bounds.y2-0.5));
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%%%%HiResBoundingBox: %.7g %.7g %.7g %.7g\n",
+ bounds.x1,bounds.y1,bounds.x2,bounds.y2);
+ (void) WriteBlobString(image,buffer);
+ }
+ (void) WriteBlobString(image,"%%EOF\n");
+ CloseBlob(image);
+ return(True);
+}
+
+#if defined(HasZLIB)
+#include "zlib.h"
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Z L I B E n c o d e 2 I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ZLIBEncode2Image compresses an image via ZLIB-coding specific to
+% Postscript Level II or Portable Document Format. To ensure portability, the
+% binary ZLIB bytes are encoded as ASCII base-85.
+%
+% The format of the ZLIBEncode2Image method is:
+%
+% unsigned int ZLIBEncode2Image(Image *image,const size_t length,
+% const unsigned long quality,unsigned char *pixels,
+% WriteByteHook write_byte,void *info)
+%
+% A description of each parameter follows:
+%
+% o image: The address of a structure of type Image; returned from
+% ReadImage.
+%
+% o length: A value that specifies the number of pixels to compress.
+%
+% o quality: the compression level (0-100).
+%
+% o pixels: The address of an unsigned array of characters containing the
+% pixels to compress.
+%
+% o write_byte: function (hook) to call for writing each byte of compressed
+% data.
+%
+% o info: information block to pass along when calling write_byte
+% function.
+%
+%
+*/
+
+static voidpf ZLIBAllocFunc(voidpf opaque, uInt items, uInt size)
+{
+ ARG_NOT_USED(opaque);
+ return MagickMallocCleared((size_t) items*size);
+}
+static void ZLIBFreeFunc(voidpf opaque, voidpf address)
+{
+ ARG_NOT_USED(opaque);
+ MagickFree(address);
+}
+
+static unsigned int ZLIBEncode2Image(Image *image,const size_t length,
+ const unsigned long quality,unsigned char *pixels,WriteByteHook write_byte,
+ void *info)
+{
+ int
+ status;
+
+ register long
+ i;
+
+ unsigned char
+ *compressed_pixels;
+
+ unsigned long
+ compressed_packets;
+
+ z_stream
+ stream;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ compressed_packets=(unsigned long) (1.001*length+12);
+ compressed_pixels=MagickAllocateMemory(unsigned char *,compressed_packets);
+ if (compressed_pixels == (unsigned char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ stream.next_in=pixels;
+ stream.avail_in=(unsigned int) length;
+ stream.next_out=compressed_pixels;
+ stream.avail_out=(unsigned int) compressed_packets;
+ stream.zalloc=ZLIBAllocFunc;
+ stream.zfree=ZLIBFreeFunc;
+ stream.opaque=(voidpf) NULL;
+ status=deflateInit(&stream,(int) Min(quality/10,9));
+ if (status == Z_OK)
+ {
+ status=deflate(&stream,Z_FINISH);
+ if (status == Z_STREAM_END)
+ status=deflateEnd(&stream);
+ else
+ (void) deflateEnd(&stream);
+ compressed_packets=stream.total_out;
+ }
+ if (status)
+ ThrowBinaryException(CoderError,UnableToZipCompressImage,(char *) NULL)
+ else
+ for (i=0; i < (long) compressed_packets; i++)
+ (void) (*write_byte)(image,(magick_uint8_t)compressed_pixels[i],info);
+ MagickFreeMemory(compressed_pixels);
+ return(!status);
+}
+#else
+static unsigned int ZLIBEncode2Image(Image *image,const size_t length,
+ const unsigned long quality,unsigned char *pixels,WriteByteHook write_byte,
+ void *info)
+{
+ ARG_NOT_USED(length);
+ ARG_NOT_USED(quality);
+ ARG_NOT_USED(pixels);
+ ARG_NOT_USED(write_byte);
+ ARG_NOT_USED(info);
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ ThrowBinaryException(MissingDelegateError,ZipLibraryIsNotAvailable,image->filename);
+ return(False);
+}
+#endif
+
diff --git a/coders/psd.c b/coders/psd.c
new file mode 100644
index 0000000..023c6d2
--- /dev/null
+++ b/coders/psd.c
@@ -0,0 +1,2052 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP SSSSS DDDD %
+% P P SS D D %
+% PPPP SSS D D %
+% P SS D D %
+% P SSSSS DDDD %
+% %
+% %
+% Read/Write Adobe Photoshop Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% Leonard Rosenthol %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/utility.h"
+#if defined(EnableBrokenCoders) && EnableBrokenCoders
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePSDImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DecodeImage uncompresses an image via Macintosh encoding specific to
+% the Adobe Photoshop image format.
+%
+% The format of the DecodeImage method is:
+%
+% unsigned int DecodeImage(Image *image,const long channel)
+%
+% A description of each parameter follows:
+%
+% o status: Method DecodeImage return True if the image is
+% decoded. False is returned if there is an error occurs.
+%
+% o image,image: The address of a structure of type Image.
+%
+% o channel: Specifies which channel: red, green, blue, or index to
+% decode the pixel values into.
+%
+%
+*/
+static unsigned int DecodeImage(Image *image,const int channel)
+{
+ int
+ count;
+
+ long
+ number_pixels;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned long
+ pixel;
+
+ x=0;
+ number_pixels=(long) (image->columns*image->rows);
+ while (number_pixels > 0)
+ {
+ count=ReadBlobByte(image);
+ if (count >= 128)
+ count-=256;
+ if (count < 0)
+ {
+ if (count == -128)
+ continue;
+ pixel=ReadBlobByte(image);
+ for (count=(-count+1); count > 0; count--)
+ {
+ q=GetImagePixels(image,(long) (x % image->columns),
+ (long) (x/image->columns),1,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ switch (channel)
+ {
+ case -1:
+ {
+ if (image->colorspace == CMYKColorspace)
+ indexes[0]=(Quantum) (MaxRGB-ScaleCharToQuantum(pixel));
+ else
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(pixel));
+ break;
+ }
+ case 0:
+ {
+ q->red=ScaleCharToQuantum(pixel);
+ if (image->storage_class == PseudoClass)
+ {
+ unsigned int colormap_index=(IndexPacket) pixel;
+ VerifyColormapIndex(image,colormap_index);
+ indexes[0]=colormap_index;
+ *q=image->colormap[colormap_index];
+ }
+ break;
+ }
+ case 1:
+ {
+ if (image->storage_class == PseudoClass)
+ q->opacity=ScaleCharToQuantum(pixel);
+ else
+ q->green=ScaleCharToQuantum(pixel);
+ break;
+ }
+ case 2:
+ {
+ q->blue=ScaleCharToQuantum(pixel);
+ break;
+ }
+ case 3:
+ {
+ q->opacity=ScaleCharToQuantum(pixel);
+ break;
+ }
+ case 4:
+ {
+ if (image->colorspace == CMYKColorspace)
+ indexes[0]=(Quantum) (MaxRGB-ScaleCharToQuantum(pixel));
+ break;
+ }
+ default:
+ break;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ x++;
+ number_pixels--;
+ }
+ continue;
+ }
+ count++;
+ for (i=count; i > 0; i--)
+ {
+ pixel=ReadBlobByte(image);
+ q=GetImagePixels(image,(long) (x % image->columns),
+ (long) (x/image->columns),1,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ switch (channel)
+ {
+ case -1:
+ {
+ if (image->colorspace == CMYKColorspace)
+ indexes[0]=(Quantum) (MaxRGB-ScaleCharToQuantum(pixel));
+ else
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(pixel));
+ break;
+ }
+ case 0:
+ {
+ q->red=ScaleCharToQuantum(pixel);
+ if (image->storage_class == PseudoClass)
+ {
+ indexes[0]=(IndexPacket) pixel;
+ *q=image->colormap[pixel];
+ }
+ break;
+ }
+ case 1:
+ {
+ if (image->storage_class == PseudoClass)
+ q->opacity=ScaleCharToQuantum(pixel);
+ else
+ q->green=ScaleCharToQuantum(pixel);
+ break;
+ }
+ case 2:
+ {
+ q->blue=ScaleCharToQuantum(pixel);
+ break;
+ }
+ case 3:
+ {
+ q->opacity=ScaleCharToQuantum(pixel);
+ break;
+ }
+ case 4:
+ {
+ if (image->colorspace == CMYKColorspace)
+ indexes[0]=(Quantum) (MaxRGB-ScaleCharToQuantum(pixel));
+ break;
+ }
+ default:
+ break;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ x++;
+ number_pixels--;
+ }
+ }
+ /*
+ Guarentee the correct number of pixel packets.
+ */
+ if (number_pixels > 0)
+ {
+ ThrowBinaryException(CorruptImageError,InsufficientImageDataInFile,
+ image->filename);
+ }
+ else
+ {
+ if (number_pixels < 0)
+ ThrowBinaryException(CorruptImageError,TooMuchImageDataInFile,
+ image->filename);
+ }
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P S D %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPSD returns True if the image format type, identified by the
+% magick string, is PSD.
+%
+% The format of the IsPSD method is:
+%
+% unsigned int IsPSD(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPSD returns True if the image format type is PSD.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPSD(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (LocaleNCompare((char *) magick,"8BPS",4) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P S D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPSDImage reads an Adobe Photoshop image file and returns it.
+% It allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadPSDImage method is:
+%
+% image=ReadPSDImage(image_info)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPSDImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static CompositeOperator PSDBlendModeToCompositeOperator(const char *mode)
+{
+ if (mode == (const char *) NULL)
+ return(OverCompositeOp);
+ if (LocaleNCompare(mode,"norm",4) == 0)
+ return(OverCompositeOp);
+ if (LocaleNCompare(mode,"mul ",4) == 0)
+ return(MultiplyCompositeOp);
+ if (LocaleNCompare(mode,"diss",4) == 0)
+ return(DissolveCompositeOp);
+ if (LocaleNCompare(mode,"diff",4) == 0)
+ return(DifferenceCompositeOp);
+ if (LocaleNCompare(mode,"dark",4) == 0)
+ return(DarkenCompositeOp);
+ if (LocaleNCompare(mode,"lite",4) == 0)
+ return(LightenCompositeOp);
+ if (LocaleNCompare(mode,"hue ",4) == 0)
+ return(HueCompositeOp);
+ if (LocaleNCompare(mode,"sat ",4) == 0)
+ return(SaturateCompositeOp);
+ if (LocaleNCompare(mode,"colr",4) == 0)
+ return(ColorizeCompositeOp);
+ if (LocaleNCompare(mode,"lum ",4) == 0)
+ return(LuminizeCompositeOp);
+ if (LocaleNCompare(mode,"scrn",4) == 0)
+ return(ScreenCompositeOp);
+ if (LocaleNCompare(mode,"over",4) == 0)
+ return(OverlayCompositeOp);
+ if (LocaleNCompare(mode,"hLit",4) == 0)
+ return(HardLightCompositeOp);
+ if (LocaleNCompare(mode,"sLit",4) == 0)
+ return(SoftLightCompositeOp);
+ if (LocaleNCompare(mode,"smud",4) == 0)
+ return(ExclusionCompositeOp);
+ if (LocaleNCompare(mode,"div ",4) == 0)
+ return(ColorDodgeCompositeOp);
+ if (LocaleNCompare(mode,"idiv",4) == 0)
+ return(ColorBurnCompositeOp);
+ if (LocaleNCompare(mode,"lbrn",4) == 0)
+ return(LinearBurnCompositeOp);
+ if (LocaleNCompare(mode,"lddg",4) == 0)
+ return(LinearDodgeCompositeOp);
+ if (LocaleNCompare(mode,"lLit",4) == 0)
+ return(LinearLightCompositeOp);
+ if (LocaleNCompare(mode,"vLit",4) == 0)
+ return(VividLightCompositeOp);
+ if (LocaleNCompare(mode,"pLit",4) == 0)
+ return(PinLightCompositeOp);
+ if (LocaleNCompare(mode,"hMix",4) == 0)
+ return(HardMixCompositeOp);
+ return(OverCompositeOp);
+}
+
+static char *CompositeOperatorToPSDBlendMode(CompositeOperator inOp)
+{
+ char* outMode = (char *) "norm";
+
+ switch ( inOp )
+ {
+ case OverCompositeOp: outMode = (char *) "norm"; break;
+ case MultiplyCompositeOp: outMode = (char *) "mul "; break;
+ case DissolveCompositeOp: outMode = (char *) "diss"; break;
+ case DifferenceCompositeOp:outMode = (char *) "diff"; break;
+ case DarkenCompositeOp: outMode = (char *) "dark"; break;
+ case LightenCompositeOp: outMode = (char *) "lite"; break;
+ case HueCompositeOp: outMode = (char *) "hue "; break;
+ case SaturateCompositeOp: outMode = (char *) "sat "; break;
+ case ColorizeCompositeOp: outMode = (char *) "colr"; break;
+ case LuminizeCompositeOp: outMode = (char *) "lum "; break;
+ case ScreenCompositeOp: outMode = (char *) "scrn"; break;
+ case OverlayCompositeOp: outMode = (char *) "over"; break;
+ case HardLightCompositeOp: outMode = (char *) "hLit"; break;
+ case ExclusionCompositeOp: outMode = (char *) "smud"; break;
+ case ColorDodgeCompositeOp:outMode = (char *) "div "; break;
+ case ColorBurnCompositeOp: outMode = (char *) "idiv"; break;
+ case SoftLightCompositeOp: outMode = (char *) "sLit"; break;
+ case LinearBurnCompositeOp:outMode = (char *) "lbrn"; break;
+ case LinearDodgeCompositeOp:outMode= (char *) "lddg"; break;
+ case LinearLightCompositeOp:outMode= (char *) "lLit"; break;
+ case VividLightCompositeOp:outMode = (char *) "vLit"; break;
+ case PinLightCompositeOp: outMode = (char *) "pLit"; break;
+ case HardMixCompositeOp: outMode = (char *) "hMix"; break;
+
+ default:
+ outMode = (char *) "norm";
+ }
+
+ return outMode;
+}
+
+typedef enum
+{
+ BitmapMode = 0,
+ GrayscaleMode = 1,
+ IndexedMode = 2,
+ RGBMode = 3,
+ CMYKMode = 4,
+ MultichannelMode = 7,
+ DuotoneMode = 8,
+ LabMode = 9
+} PSDImageType;
+
+static const char* ModeToString( PSDImageType inType )
+{
+ switch ( inType )
+ {
+ case BitmapMode: return "Bitmap";
+ case GrayscaleMode: return "Grayscale";
+ case IndexedMode: return "Indexed";
+ case RGBMode: return "RGB";
+ case CMYKMode: return "CMYK";
+ case MultichannelMode: return "Multichannel";
+ case DuotoneMode: return "Duotone";
+ case LabMode: return "L*A*B";
+ default: return "unknown";
+ }
+}
+
+#define ThrowPSDReaderException(code_,reason_,image_) \
+ { \
+ MagickFreeMemory(layer_info); \
+ ThrowReaderException(code_,reason_,image_); \
+ }
+
+static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define MaxPSDChannels 24
+ typedef struct _ChannelInfo
+ {
+ short int
+ type;
+
+ unsigned long
+ size;
+ } ChannelInfo;
+
+ typedef struct _LayerInfo
+ {
+ RectangleInfo
+ page,
+ mask;
+
+ unsigned short
+ channels;
+
+ ChannelInfo
+ channel_info[MaxPSDChannels];
+
+ char
+ blendkey[4];
+
+ Quantum
+ opacity;
+
+ unsigned char
+ clipping,
+ visible,
+ flags;
+
+ unsigned long
+ offset_x,
+ offset_y;
+
+ unsigned char
+ name[256];
+
+ Image
+ *image;
+ } LayerInfo;
+
+ typedef struct _PSDInfo
+ {
+ char
+ signature[4]; /* "8BPS" */
+
+ unsigned short
+ channels, /* 1 to 24 */
+ version; /* 1 */
+
+ unsigned char
+ reserved[6]; /* Unused, null */
+
+ unsigned long
+ rows, /* Height, 1 to 30,000 in PS6 */
+ columns; /* Width, 1 to 30,000 in PS6 */
+
+ unsigned short
+ depth, /* Bits per channel. 1, 8, and 16. */
+ mode; /* Mode. Bitmap=0; Grayscale=1; Indexed=2; RGB=3; CMYK=4;
+ Multichannel=7; Duotone=8; Lab=9. */
+ } PSDInfo;
+
+ char
+ s[MaxTextExtent],
+ type[4];
+
+ Image
+ *image;
+
+ IndexPacket
+ *indexes;
+
+ LayerInfo
+ *layer_info=0;
+
+ long
+ j,
+ number_layers,
+ y;
+
+ PSDInfo
+ psd_info;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ size_t
+ count,
+ length,
+ combinedlength,
+ size;
+
+ /*
+ ExtendedSignedIntegralType
+ offset,
+ diff_offset; */
+
+ unsigned char
+ *data;
+
+ unsigned int
+ logging,
+ packet_size,
+ status;
+
+ unsigned short
+ compression;
+
+ unsigned long
+ pixel;
+
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ {
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," OpenBlob failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "return ReadPSDImage()");
+ }
+ ThrowPSDReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+
+ /*
+ Read image header.
+ */
+ count=ReadBlob(image,4,(char *) psd_info.signature);
+ psd_info.version=ReadBlobMSBShort(image);
+ if ((count != 4) ||
+ (LocaleNCompare(psd_info.signature,"8BPS",4) != 0) ||
+ (psd_info.version != 1))
+ {
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " File signature was %.4s instead of '8BPS'",
+ psd_info.signature );
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ (void) ReadBlob(image,6,(char *) psd_info.reserved);
+ psd_info.channels=ReadBlobMSBShort(image); /* Number of channels */
+ if (psd_info.channels > MaxPSDChannels)
+ ThrowPSDReaderException(CorruptImageError,ImproperImageHeader,image);
+ psd_info.rows=ReadBlobMSBLong(image); /* Height */
+ psd_info.columns=ReadBlobMSBLong(image); /* Width */
+ psd_info.depth=ReadBlobMSBShort(image); /* Depth */
+ psd_info.mode=ReadBlobMSBShort(image); /* Color mode */
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Image is %ld x %ld with channels=%d, depth=%d, mode=%s",
+ psd_info.columns, psd_info.rows, psd_info.channels,
+ psd_info.depth, ModeToString((PSDImageType) psd_info.mode));
+ }
+ /*
+ Initialize image.
+ */
+ image->depth=psd_info.depth <= 8 ? 8 : QuantumDepth;
+ image->columns=psd_info.columns;
+ image->rows=psd_info.rows;
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowPSDReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ if (SetImageEx(image,OpaqueOpacity,exception) == MagickFail)
+ {
+ CloseBlob(image);
+ DestroyImageList(image);
+ return MagickFail;
+ }
+ image->matte=psd_info.channels >= 4;
+ if (psd_info.mode == CMYKMode)
+ {
+ image->colorspace=CMYKColorspace;
+ image->matte=psd_info.channels >= 5;
+ }
+ if ((psd_info.mode == BitmapMode) ||
+ (psd_info.mode == GrayscaleMode) ||
+ (psd_info.mode == DuotoneMode))
+ {
+ if (!AllocateImageColormap(image,256)) {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " allocation of ImageColorMap failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ image->matte=psd_info.channels >= 2;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " ImageColorMap allocated");
+ }
+ }
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ image->matte ?
+ " image has matte" : " image has no matte");
+ }
+
+ /*
+ Read PSD raster colormap only present for indexed and duotone images.
+ */
+ length=ReadBlobMSBLong(image);
+ if (length != 0)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " reading colormap");
+ }
+
+ if (psd_info.mode == DuotoneMode)
+ {
+ /*
+ Duotone image data; the format of this data is undocumented.
+ */
+ data=MagickAllocateMemory(unsigned char *,length);
+ if (data == (unsigned char *) NULL) {
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " allocation of ImageColorMap failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ (void) ReadBlob(image,length,data);
+ MagickFreeMemory(data);
+ }
+ else
+ {
+ /*
+ Read PSD raster colormap.
+ */
+ unsigned long
+ colors;
+
+ colors=(const unsigned long) (length/3UL);
+ if (colors > MaxColormapSize)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " too many colors in colormap (%lu)",
+ colors);
+ ThrowPSDReaderException(CorruptImageError,ImproperImageHeader,
+ image);
+ }
+ if (!AllocateImageColormap(image,colors))
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " allocation of ImageColorMap failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ for (i=0; i < (long) image->colors; i++)
+ image->colormap[i].red=ScaleCharToQuantum(ReadBlobByte(image));
+ for (i=0; i < (long) image->colors; i++)
+ image->colormap[i].green=ScaleCharToQuantum(ReadBlobByte(image));
+ for (i=0; i < (long) image->colors; i++)
+ image->colormap[i].blue=ScaleCharToQuantum(ReadBlobByte(image));
+ image->matte=psd_info.channels >= 2;
+ }
+ }
+
+ /*
+ Image resources. Currently we simply load this up into the IPTC
+ block for access by other methods. In the future, we may need to
+ access parts of it ourselves to support newer features of PSD.
+ */
+ length=ReadBlobMSBLong(image);
+ if (length != 0)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " reading image resources (IPTC) - %ld bytes",
+ (long) length);
+ }
+ data=MagickAllocateMemory(unsigned char *,length);
+ if (data == (unsigned char *) NULL)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " allocation of resources/IPTC failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ count=ReadBlob(image,length,(char *) data);
+ if ((count == 0) || (LocaleNCompare((char *) data,"8BIM",4) != 0))
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image resources invalid");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ (void) SetImageProfile(image,"IPTC",data,length);
+ MagickFreeMemory(data);
+ }
+
+ /*
+ If we are only "pinging" the image, then we're done - so return.
+ */
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " pinging of image complete");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+
+ return(image);
+ }
+
+ /*
+ Layer and mask block.
+ */
+ layer_info=(LayerInfo *) NULL;
+ number_layers=0;
+ length=ReadBlobMSBLong(image);
+ if (length == 8)
+ {
+ length=ReadBlobMSBLong(image);
+ length=ReadBlobMSBLong(image);
+ }
+
+ if (length != 0)
+ {
+ /* offset = TellBlob(image); */
+ size=ReadBlobMSBLong(image);
+ if (size == 0)
+ {
+ for (j=0; j < (long) (length-4); j++)
+ (void) ReadBlobByte(image);
+ }
+ else
+ {
+ number_layers=(short) ReadBlobMSBShort(image);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image contains %ld layers",
+ number_layers);
+ }
+ if (number_layers < 0)
+ {
+ /*
+ Weird hack in PSD format to ignore first alpha channel.
+ */
+ number_layers=AbsoluteValue(number_layers);
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " negative layer count corrected for");
+ }
+ }
+ if (number_layers == 0)
+ {
+ for (j=0; j < (long) (size-6); j++)
+ (void) ReadBlobByte(image);
+ }
+ else
+ {
+ layer_info=MagickAllocateArray(LayerInfo *,number_layers,sizeof(LayerInfo));
+ if (layer_info == (LayerInfo *) NULL)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " allocation of LayerInfo failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ (void) memset(layer_info,0,MagickArraySize(number_layers,sizeof(LayerInfo)));
+ for (i=0; i < number_layers; i++)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " reading layer #%ld", i+1);
+ }
+ layer_info[i].page.y=(long) ReadBlobMSBLong(image);
+ layer_info[i].page.x=(long) ReadBlobMSBLong(image);
+ layer_info[i].page.height=(ReadBlobMSBLong(image)-layer_info[i].page.y);
+ layer_info[i].page.width=(ReadBlobMSBLong(image)-layer_info[i].page.x);
+ layer_info[i].channels=ReadBlobMSBShort(image);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " offset(%ld,%ld), size(%ld,%ld), channels=%d",
+ layer_info[i].page.x,
+ layer_info[i].page.y,
+ layer_info[i].page.height,
+ layer_info[i].page.width,
+ layer_info[i].channels);
+ }
+ if (layer_info[i].channels >= MaxPSDChannels)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Number of channels exceeds limit");
+ ThrowPSDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ for (j=0; j < layer_info[i].channels; j++)
+ {
+ layer_info[i].channel_info[j].type=ReadBlobMSBShort(image);
+ layer_info[i].channel_info[j].size=ReadBlobMSBLong(image);
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " channel[%ld]: type=%d, size=%ld",
+ j, layer_info[i].channel_info[j].type,
+ (long) layer_info[i].channel_info[j].size);
+ }
+ }
+ count=ReadBlob(image,4,(char *) type);
+ if ((count == 0) || (LocaleNCompare(type,"8BIM",4) != 0))
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " layer type was %.4s instead of 8BIM", type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ (void) ReadBlob(image,4,(char *) layer_info[i].blendkey);
+ layer_info[i].opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(ReadBlobByte(image)));
+ layer_info[i].clipping=ReadBlobByte(image);
+ layer_info[i].flags=ReadBlobByte(image);
+ layer_info[i].visible=!(layer_info[i].flags & 0x02);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " blend=%.4s, opacity=%d, clipping=%s, flags=%d, visible=%s",
+ layer_info[i].blendkey, layer_info[i].opacity,
+ layer_info[i].clipping ? "true" : "false",
+ layer_info[i].flags,
+ layer_info[i].visible ? "true" : "false");
+ }
+
+ (void) ReadBlobByte(image); /* filler */
+ combinedlength = 0;
+ size=ReadBlobMSBLong(image);
+ if (size != 0)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " layer contains additional info");
+ }
+ length=ReadBlobMSBLong(image);
+ if (length != 0)
+ {
+ /*
+ Layer mask info.
+ */
+ layer_info[i].mask.y=(long) ReadBlobMSBLong(image);
+ layer_info[i].mask.x=(long) ReadBlobMSBLong(image);
+ layer_info[i].mask.height=
+ (ReadBlobMSBLong(image)-layer_info[i].mask.y);
+ layer_info[i].mask.width=
+ (ReadBlobMSBLong(image)-layer_info[i].mask.x);
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " layer mask: offset(%ld,%ld), size(%ld,%ld), length=%ld",
+ layer_info[i].mask.x, layer_info[i].mask.y,
+ layer_info[i].mask.width, layer_info[i].mask.height,
+ (long) length-16);
+ }
+ /*
+ Skip over the rest of the layer mask information.
+ */
+ for (j=0; j < (long) (length-16); j++)
+ (void) ReadBlobByte(image);
+ }
+ combinedlength += length + 4; /* +4 for length */
+
+ length=ReadBlobMSBLong(image);
+ if (length != 0)
+ {
+ /*
+ Layer blending ranges info.
+ */
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " layer blending ranges: length=%ld",
+ (long) length);
+ }
+
+ /*
+ we read it, but don't use it...
+ */
+ for (j=0; j < (long) (length); j+=8) {
+ size_t blend_source = ReadBlobMSBLong(image);
+ size_t blend_dest = ReadBlobMSBLong(image);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " source(%x), dest(%x)",
+ (unsigned int) blend_source,
+ (unsigned int) blend_dest);
+ }
+ }
+ }
+ combinedlength += length + 4; /* +4 for length */
+
+ /* layer name */
+ length=ReadBlobByte(image);
+ for (j=0; j < (long) (length); j++)
+ layer_info[i].name[j] = ReadBlobByte(image);
+ layer_info[i].name[j] = 0; /* zero term */
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " layer name: %s",
+ layer_info[i].name);
+ }
+
+ combinedlength += length + 1;
+
+ /*
+ layer name, including length byte, is padded to
+ multiple of 4 bytes skip over padding
+ */
+ /* padBytes = ((length + 1 + 3) & ~3) - (length + 1); */
+ /* for (j=0; j < padBytes; j++) */
+ /* ReadBlobByte(image); */
+
+#if 0 /* still in development */
+ /*
+ Adjustment layers and other stuff...
+ */
+ {
+ char alsig[4],
+ alkey[4];
+
+ count=ReadBlob(image,4,(char *) alsig);
+ if ((count == 0) || (LocaleNCompare(alsig,"8BIM",4) != 0))
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " adjustment layer type was %.4s instead of 8BIM",
+ alsig);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+ ThrowPSDReaderException(CorruptImageError,NotAPSDImageFile,image);
+ }
+ (void) ReadBlob(image,4,(char *) alkey);
+ length=ReadBlobMSBLong(image);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " adjustment layer key: %.4s, data length=%ld",
+ alkey, length);
+ }
+
+ if ( length )
+ {
+ for (j=0; j < (long) (length); j++)
+ (void) ReadBlobByte(image);
+ }
+
+ }
+ combinedlength += 12 + length; /* sig, key, length + the actual length*/
+#endif
+
+ /*
+ Skip the rest of the variable data until we support it.
+ */
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " unsupported data: length=%"
+ MAGICK_SIZE_T_F "u",
+ (MAGICK_SIZE_T) size-combinedlength);
+ }
+ for (j=0; j < (long) (size-combinedlength); j++)
+ (void) ReadBlobByte(image);
+ }
+ /*
+ Allocate layered image.
+ */
+ layer_info[i].image=CloneImage(image,layer_info[i].page.width,
+ layer_info[i].page.height,
+ True,&image->exception);
+ if (layer_info[i].image == (Image *) NULL)
+ {
+ for (j=0; j < i; j++)
+ {
+ DestroyImage(layer_info[j].image);
+ layer_info[j].image = (Image *) NULL;
+ }
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " allocation of image for layer %ld failed", i);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+
+ ThrowPSDReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ DestroyBlob(layer_info[i].image);
+ layer_info[i].image->blob=ReferenceBlob(image->blob);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " setting up new layer image");
+ }
+ (void) SetImage(layer_info[i].image,OpaqueOpacity);
+ layer_info[i].image->compose=
+ PSDBlendModeToCompositeOperator(layer_info[i].blendkey);
+ if (layer_info[i].visible == False)
+ layer_info[i].image->compose=NoCompositeOp;
+ if (psd_info.mode == CMYKMode)
+ layer_info[i].image->colorspace=CMYKColorspace;
+ for (j=0; j < layer_info[i].channels; j++)
+ if (layer_info[i].channel_info[j].type == -1)
+ layer_info[i].image->matte=True;
+
+ /* set up some hidden attributes for folks that need them */
+ (void) sprintf( s, "%ld", layer_info[i].page.x );
+ (void) SetImageAttribute(layer_info[i].image,"[layer-xpos]",s);
+ (void) sprintf( s, "%ld", layer_info[i].page.y );
+ (void) SetImageAttribute(layer_info[i].image,"[layer-ypos]",s);
+ (void) sprintf( s, "%d", layer_info[i].opacity );
+ (void) SetImageAttribute(layer_info[i].image,"[layer-opacity]",s);
+ (void) SetImageAttribute(layer_info[i].image,"[layer-name]",
+ (char *) layer_info[i].name);
+ }
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " reading image data for layers");
+ }
+ /*
+ Read pixel data for each layer.
+ */
+ for (i=0; i < number_layers; i++)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " reading data for layer %ld", i);
+ }
+ for (j=0; j < layer_info[i].channels; j++)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " reading data for channel %ld", j);
+ }
+#if 0
+ if (layer_info[i].channel_info[j].size <= (2*layer_info[i].image->rows))
+ {
+ long
+ k;
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " layer data is empty");
+
+ /*
+ A layer without data.
+ */
+ for (k=0; k < (long) layer_info[i].channel_info[j].size; k++)
+ (void) ReadBlobByte(layer_info[i].image);
+ continue;
+ }
+#endif
+ compression=ReadBlobMSBShort(layer_info[i].image);
+ if(layer_info[i].page.height > 0 && layer_info[i].page.width > 0){
+ if (compression == 1)
+ {
+ /*
+ Read RLE compressed data.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " layer data is RLE compressed");
+
+ for (y=0; y < (long) layer_info[i].image->rows; y++)
+ (void) ReadBlobMSBShort(layer_info[i].image);
+ (void) DecodeImage(layer_info[i].image,
+ layer_info[i].channel_info[j].type);
+ continue;
+ }
+
+ /*
+ Read uncompressed pixel data as separate planes.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " layer data is uncompressed");
+ packet_size=1;
+ if (layer_info[i].image->storage_class == PseudoClass)
+ {
+ if (layer_info[i].image->colors > 256)
+ packet_size++;
+ }
+ else
+ if (layer_info[i].image->depth > 8)
+ packet_size++;
+ for (y=0; y < (long) layer_info[i].image->rows; y++)
+ {
+ q=GetImagePixels(layer_info[i].image,0,y,
+ layer_info[i].image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(layer_info[i].image);
+ for (x=0; x < (long) layer_info[i].image->columns; x++)
+ {
+ if (packet_size == 1)
+ pixel=ScaleCharToQuantum(ReadBlobByte(layer_info[i].image));
+ else
+ pixel=ScaleQuantumToShort(ReadBlobMSBShort(layer_info[i].image));
+ switch (layer_info[i].channel_info[j].type)
+ {
+ case -1: /* transparency mask */
+ {
+ if (image->colorspace == CMYKColorspace)
+ indexes[x]=(Quantum) (MaxRGB-pixel);
+ else
+ q->opacity=(Quantum) (MaxRGB-pixel);
+ break;
+ }
+ case 0: /* first component (Red, Cyan, Gray or Index) */
+ {
+ q->red=(Quantum) pixel;
+ if (layer_info[i].image->storage_class == PseudoClass)
+ {
+ indexes[x]=(IndexPacket) ScaleQuantumToChar(MaxRGB - pixel);
+ *q=layer_info[i].image->colormap[indexes[x]];
+ }
+ break;
+ }
+ case 1: /* second component (Green, Magenta, or opacity) */
+ {
+ if (layer_info[i].image->storage_class == PseudoClass)
+ q->opacity=(Quantum) pixel;
+ else
+ q->green=(Quantum) pixel;
+ break;
+ }
+ case 2: /* third component (Blue or Yellow) */
+ {
+ q->blue=(Quantum) pixel;
+ break;
+ }
+ case 3: /* fourth component (Opacity or Black) */
+ {
+ q->opacity=(Quantum) pixel;
+ break;
+ }
+ case 4: /* fifth component (opacity) */
+ {
+ if (image->colorspace == CMYKColorspace)
+ indexes[x]=(Quantum) (MaxRGB-pixel);
+ break;
+ }
+ default:
+ break;
+ }
+ q++;
+ }
+ if (!SyncImagePixels(layer_info[i].image))
+ break;
+ }
+ }
+ if (layer_info[i].opacity != OpaqueOpacity)
+ {
+ /*
+ Correct for opacity level.
+ */
+ for (y=0; y < (long) layer_info[i].image->rows; y++)
+ {
+ q=GetImagePixels(layer_info[i].image,0,y,
+ layer_info[i].image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(layer_info[i].image);
+ for (x=0; x < (long) layer_info[i].image->columns; x++)
+ {
+ q->opacity=(Quantum) ((unsigned long)
+ (q->opacity*layer_info[i].opacity)/MaxRGB);
+ if (layer_info[i].image->colorspace == CMYKColorspace)
+ indexes[x]=(IndexPacket) ((unsigned long)
+ (indexes[x]*layer_info[i].opacity)/MaxRGB);
+ q++;
+ }
+ if (!SyncImagePixels(layer_info[i].image))
+ break;
+ }
+ }
+ if (layer_info[i].image->colorspace == CMYKColorspace)
+ {
+ /*
+ Correct CMYK levels.
+ */
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " correcting CMYK values");
+ }
+ for (y=0; y < (long) layer_info[i].image->rows; y++)
+ {
+ q=GetImagePixels(layer_info[i].image,0,y,
+ layer_info[i].image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) layer_info[i].image->columns; x++)
+ {
+ q->red=(Quantum) (MaxRGB-q->red);
+ q->green=(Quantum) (MaxRGB-q->green);
+ q->blue=(Quantum) (MaxRGB-q->blue);
+ q->opacity=(Quantum) (MaxRGB-q->opacity);
+ q++;
+ }
+ if (!SyncImagePixels(layer_info[i].image))
+ break;
+ }
+ }
+ }
+ }
+ /* diff_offset = TellBlob(image) - offset; */
+
+ (void) ReadBlobMSBLong(image); /* global mask size: currently ignored */
+
+ if (number_layers > 0)
+ {
+ Image* returnImage = image;
+ LayerInfo *prevLayer = NULL;
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " putting layers into image list");
+ }
+ /* omit any 0x0 sized layers from the list, as they break compositing */
+ for (i=0; i < number_layers; i++)
+ if(layer_info[i].page.height > 0 && layer_info[i].page.width > 0)
+ {
+ if (prevLayer){
+ layer_info[i].image->previous = prevLayer->image;
+ prevLayer->image->next = layer_info[i].image;
+ }
+ layer_info[i].image->page = layer_info[i].page;
+ prevLayer = &layer_info[i];
+ }
+#ifdef use_image
+ image->next=layer_info[0].image;
+ layer_info[0].image->previous=image;
+#else
+ DestroyImage(image);
+ returnImage = layer_info[0].image;
+#endif
+ MagickFreeMemory(layer_info);
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ }
+
+ CloseBlob(returnImage);
+ return(returnImage);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " image has no layers");
+ }
+ }
+
+ /*
+ Read the precombined image, present for PSD < 4 compatibility.
+ This is a completely rendered image.
+ */
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " reading the precombined layer");
+ }
+ compression=ReadBlobMSBShort(image);
+ if (compression == 1)
+ {
+ /*
+ Read Packbit encoded pixel data as separate planes.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " packbits compression");
+ for (i=0; i < (long) (image->rows*psd_info.channels); i++)
+ (void) ReadBlobMSBShort(image);
+ for (i=0; i < psd_info.channels; i++)
+ (void) DecodeImage(image,(int) i);
+ }
+ else
+ {
+ /*
+ Read uncompressed pixel data as separate planes.
+ */
+ packet_size=1;
+ if (image->storage_class == PseudoClass)
+ {
+ if (image->colors > 256)
+ packet_size++;
+ }
+ else
+ if (image->depth > 8)
+ packet_size++;
+ for (i=0; i < psd_info.channels; i++)
+ {
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (packet_size == 1)
+ pixel=ScaleCharToQuantum(ReadBlobByte(image));
+ else
+ pixel=ScaleShortToQuantum(ReadBlobMSBShort(image));
+ switch (image->matte ? i-1 : i)
+ {
+ case -1:
+ {
+ q->opacity=(Quantum) (MaxRGB-pixel);
+ break;
+ }
+ case 0:
+ {
+ /* if (x==0 && y==0) */
+ /* printf("red=%lu\n",pixel); */
+ q->red=(Quantum) pixel;
+ if (image->storage_class == PseudoClass)
+ {
+ unsigned int colormap_index=
+ (IndexPacket) ScaleQuantumToChar(pixel);
+ VerifyColormapIndex(image,colormap_index);
+ indexes[x]=colormap_index;
+ *q=image->colormap[indexes[x]];
+ }
+ break;
+ }
+ case 1:
+ {
+ /* if (x==0 && y==0) */
+ /* printf("green=%lu\n",pixel); */
+ if (image->storage_class == PseudoClass)
+ q->opacity=(Quantum) pixel;
+ else
+ q->green=(Quantum) pixel;
+ break;
+ }
+ case 2:
+ {
+ /* if (x==0 && y==0) */
+ /* printf("blue=%lu\n",pixel); */
+ q->blue=(Quantum) pixel;
+ break;
+ }
+ case 3:
+ {
+ q->opacity=(Quantum) pixel;
+ break;
+ }
+ case 4:
+ {
+ if (image->colorspace == CMYKColorspace)
+ indexes[x]=(IndexPacket) pixel;
+ break;
+ }
+ default:
+ break;
+ }
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+ }
+ if (image->colorspace == CMYKColorspace)
+ {
+ /*
+ Correct CMYK levels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=(Quantum) (MaxRGB-q->red);
+ q->green=(Quantum) (MaxRGB-q->green);
+ q->blue=(Quantum) (MaxRGB-q->blue);
+ q->opacity=(Quantum) (MaxRGB-q->opacity);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+
+ CloseBlob(image);
+
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), "return");
+ }
+
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P S D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPSDImage adds attributes for the PSD image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPSDImage method is:
+%
+% RegisterPSDImage(void)
+%
+*/
+ModuleExport void RegisterPSDImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PSD");
+ entry->decoder=(DecoderHandler) ReadPSDImage;
+ entry->encoder=(EncoderHandler) WritePSDImage;
+ entry->magick=(MagickHandler) IsPSD;
+ entry->description="Adobe Photoshop bitmap";
+ entry->module="PSD";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P S D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPSDImage removes format registrations made by the
+% PSD module from the list of supported formats.
+%
+% The format of the UnregisterPSDImage method is:
+%
+% UnregisterPSDImage(void)
+%
+*/
+ModuleExport void UnregisterPSDImage(void)
+{
+ (void) UnregisterMagickInfo("PSD");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P S D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WritePSDImage writes an image in the Adobe Photoshop encoded image
+% format.
+%
+% The format of the WritePSDImage method is:
+%
+% unsigned int WritePSDImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePSDImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static void WriteOneChannel( Image* image, Image* tmp_image,
+ unsigned char *pixels, QuantumType whichQuantum )
+{
+ int
+ y;
+
+ register const PixelPacket
+ *p;
+
+ unsigned int
+ packet_size,
+ quantum_size;
+
+ if (tmp_image->depth <= 8)
+ quantum_size=8;
+ else
+ quantum_size=16;
+
+ if (tmp_image->depth > 16)
+ tmp_image->depth=16;
+
+ packet_size=quantum_size/8;
+
+ for (y=0; y < (long) tmp_image->rows; y++)
+ {
+ p=AcquireImagePixels(tmp_image,0,y,tmp_image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(tmp_image,whichQuantum,quantum_size,pixels,0,0);
+ (void) WriteBlob(image,packet_size*tmp_image->columns,pixels);
+ }
+}
+
+static void WriteImageChannels( Image* image, Image* tmp_image, unsigned char *pixels )
+{
+ /*
+ Write uncompressed pixel data as separate planes.
+ */
+ (void) WriteBlobMSBShort(image,0); /* compression */
+ if (tmp_image->storage_class == PseudoClass)
+ {
+ if (!tmp_image->matte)
+ WriteOneChannel( image, tmp_image, pixels, IndexQuantum );
+ else
+ WriteOneChannel( image, tmp_image, pixels, IndexAlphaQuantum );
+ }
+ else
+ {
+ if (tmp_image->matte)
+ WriteOneChannel( image, tmp_image, pixels, AlphaQuantum );
+
+ WriteOneChannel( image, tmp_image, pixels, RedQuantum );
+ WriteOneChannel( image, tmp_image, pixels, GreenQuantum );
+ WriteOneChannel( image, tmp_image, pixels, BlueQuantum );
+
+ if (tmp_image->colorspace == CMYKColorspace)
+ WriteOneChannel( image, tmp_image, pixels, BlackQuantum );
+ }
+}
+
+/* Write white background, RLE-compressed */
+
+static MagickPassFail WriteWhiteBackground( Image* image )
+{
+ long
+ count,
+ w8,
+ w;
+
+ char
+ *d,
+ *scanline;
+
+ int numChannels = 3, i, bytecount, dim = (int) (image->rows*numChannels);
+
+ scanline=MagickAllocateMemory(char *,(image->columns/128)*2 + 2);
+ if (scanline == (char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,NULL);
+
+ (void) WriteBlobMSBShort( image, 1 ); /* RLE compressed */
+
+ w8 = (long) image->columns;
+
+ d = scanline;
+ /* Set up scanline */
+ for (w=w8; w>128; w-=128)
+ {
+ *d++ = -127;
+ *d++ = (char) 255;
+ }
+
+ switch(w)
+ {
+ case 0:
+ break;
+ case 1:
+ *d++=0;
+ *d++ = (char)255;
+ break;
+ default: *d++=(char) (1-w); *d++ = (char)255;
+ break;
+ }
+
+ bytecount = d - scanline;
+
+ /* Scanline counts (rows*channels) */
+ for (i=0; i < dim; i++)
+ {
+ (void) WriteBlobMSBShort( image, bytecount );
+ }
+
+ /* RLE compressed data */
+ count = bytecount;
+ for(i=0; i < dim; i++)
+ {
+ (void) WriteBlob( image, count, scanline );
+ }
+
+ MagickFreeMemory(scanline);
+
+ return MagickPass;
+}
+
+static void WritePascalString (Image* inImage, const char *inString, int inPad)
+{
+ unsigned
+ char strLength;
+
+ int
+ i;
+
+ /* max length is 255 */
+
+ strLength = ( strlen(inString) > 255 ) ? 255 : (unsigned char) strlen(inString);
+
+ if ( strLength != 0 )
+ {
+ (void) WriteBlobByte(inImage, strLength);
+ (void) WriteBlob(inImage, strLength, inString);
+ }
+ else
+ (void) WriteBlobByte(inImage, 0);
+
+ strLength ++;
+
+ if ( (strLength % inPad) == 0 )
+ return;
+
+ for ( i=0; i < (inPad - (strLength % inPad)); i++)
+ (void) WriteBlobByte(inImage, 0);
+}
+
+static unsigned int WritePSDImage(const ImageInfo *image_info,Image *image)
+{
+ int
+ layer_count,
+ num_channels,
+ layer_info_size,
+ rounded_layer_info_size,
+ channel_size,
+ channelLength,
+ force_white_background = image->matte,
+ invert_layer_count = False;
+
+ register long
+ i;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ packet_size,
+ status;
+
+ ImageAttribute
+ *theAttr;
+
+ Image
+ * tmp_image = (Image *) NULL,
+ * base_image = force_white_background ? image : image->next;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ packet_size=image->depth > 8 ? 6 : 3;
+ if (image->matte)
+ packet_size+=image->depth > 8 ? 2 : 1;
+ pixels=MagickAllocateArray(unsigned char *,
+ packet_size,
+ MagickArraySize(image->columns,
+ sizeof(PixelPacket)));
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) WriteBlob(image,4,"8BPS");
+ (void) WriteBlobMSBShort(image,1); /* version */
+ for ( i=1; i<=6; i++)
+ (void) WriteBlobByte(image, 0); /* 6 bytes of reserved */
+ if ( force_white_background )
+ num_channels = 3;
+ else
+ {
+ if (image->storage_class == PseudoClass)
+ num_channels = (image->matte ? 2 : 1);
+ else
+ {
+ if (image->colorspace != CMYKColorspace)
+ num_channels = (image->matte ? 4 : 3);
+ else
+ num_channels = (image->matte ? 5 : 4);
+ }
+ }
+ (void) WriteBlobMSBShort(image,num_channels);
+ (void) WriteBlobMSBLong(image,image->rows);
+ (void) WriteBlobMSBLong(image,image->columns);
+ (void) WriteBlobMSBShort(image,
+ (image->storage_class == PseudoClass ? 8 :
+ image->depth > 8 ? 16 : 8));
+ if (((image_info->colorspace != UndefinedColorspace) ||
+ (image->colorspace != CMYKColorspace)) &&
+ (image_info->colorspace != CMYKColorspace))
+ {
+ (void) TransformColorspace(image,RGBColorspace);
+ (void) WriteBlobMSBShort(image,
+ image->storage_class == PseudoClass ? 2 : 3);
+ }
+ else
+ {
+ (void) TransformColorspace(image,CMYKColorspace);
+ (void) WriteBlobMSBShort(image,4);
+ }
+ if ((image->storage_class == DirectClass) || (image->colors > 256))
+ (void) WriteBlobMSBLong(image,0);
+ else
+ {
+ /*
+ Write PSD raster colormap.
+ */
+ (void) WriteBlobMSBLong(image,768);
+ for (i=0; i < (long) image->colors; i++)
+ (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].red));
+ for ( ; i < 256; i++)
+ (void) WriteBlobByte(image,0);
+ for (i=0; i < (long) image->colors; i++)
+ (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].green));
+ for ( ; i < 256; i++)
+ (void) WriteBlobByte(image,0);
+ for (i=0; i < (long) image->colors; i++)
+ (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].blue));
+ for ( ; i < 256; i++)
+ (void) WriteBlobByte(image,0);
+ }
+
+ /* image resource block */
+ {
+ const unsigned char
+ *iptc_profile;
+
+ size_t
+ iptc_profile_length;
+
+ iptc_profile=GetImageProfile(image,"IPTC",&iptc_profile_length);
+
+ if ( iptc_profile != 0 )
+ {
+ (void) WriteBlobMSBLong( image, (const magick_uint32_t) iptc_profile_length );
+ (void) WriteBlob( image, iptc_profile_length, iptc_profile );
+ }
+ else
+ (void) WriteBlobMSBLong(image,0);
+ }
+
+ compute_layer_info:
+ layer_count = 0;
+ layer_info_size = 2;
+ tmp_image = base_image;
+ while ( tmp_image != NULL ) {
+ packet_size=tmp_image->depth > 8 ? 2 : 1;
+
+ if (tmp_image->storage_class == PseudoClass)
+ num_channels = (tmp_image->matte ? 2 : 1);
+ else
+ if (tmp_image->colorspace != CMYKColorspace)
+ num_channels = (tmp_image->matte ? 4 : 3);
+ else
+ num_channels = (tmp_image->matte ? 5 : 4);
+
+ channelLength = (int) (tmp_image->columns * tmp_image->rows * packet_size + 2);
+ layer_info_size += (4*4 + 2 + num_channels * 6 + 4 + 4 + 4 * 1 + 4 + 12
+ + num_channels * channelLength);
+
+ layer_count++;
+ tmp_image = tmp_image->next;
+ }
+
+ /* if the image has a matte, then we need to use layers */
+ if ( layer_count == 0 && image->matte == True )
+ {
+ invert_layer_count = True;
+ base_image = image;
+ goto compute_layer_info; /* yes, goto's suck, but it keeps the code cleaner! */
+ }
+
+ if ( layer_count == 0 )
+ (void) WriteBlobMSBLong(image, 0);
+ else
+ {
+ (void) WriteBlobMSBLong(image,layer_info_size + 4 + 4);
+ if( layer_info_size/2 != (layer_info_size+1)/2 ) /* odd */
+ rounded_layer_info_size = layer_info_size + 1;
+ else
+ rounded_layer_info_size = layer_info_size;
+ (void) WriteBlobMSBLong(image,rounded_layer_info_size);
+
+ if ( invert_layer_count )
+ layer_count *= -1; /* if we have a matte, then use negative count! */
+ (void) WriteBlobMSBShort(image, layer_count);
+
+ layer_count = 1;
+ tmp_image = base_image;
+ while ( tmp_image != NULL ) {
+ (void) WriteBlobMSBLong(image,0);
+ (void) WriteBlobMSBLong(image,0);
+ (void) WriteBlobMSBLong(image,tmp_image->rows);
+ (void) WriteBlobMSBLong(image,tmp_image->columns);
+
+ packet_size=tmp_image->depth > 8 ? 2 : 1;
+ channel_size = (int) ((packet_size * tmp_image->rows * tmp_image->columns) + 2);
+ if (tmp_image->storage_class == PseudoClass) {
+ (void) WriteBlobMSBShort(image, tmp_image->matte ? 2 : 1);
+ if (tmp_image->matte) {
+ (void) WriteBlobMSBShort(image, (magick_uint16_t) -1);
+ (void) WriteBlobMSBLong(image, channel_size);
+ }
+ (void) WriteBlobMSBShort(image, 0);
+ (void) WriteBlobMSBLong(image, channel_size);
+ } else
+ if (tmp_image->colorspace != CMYKColorspace)
+ {
+ (void) WriteBlobMSBShort(image, tmp_image->matte ? 4 : 3);
+ if (tmp_image->matte) {
+ (void) WriteBlobMSBShort(image, (magick_uint16_t) -1);
+ (void) WriteBlobMSBLong(image, channel_size);
+ }
+ (void) WriteBlobMSBShort(image, 0);
+ (void) WriteBlobMSBLong(image, channel_size);
+ (void) WriteBlobMSBShort(image, 1);
+ (void) WriteBlobMSBLong(image, channel_size);
+ (void) WriteBlobMSBShort(image, 2);
+ (void) WriteBlobMSBLong(image, channel_size);
+ }
+ else
+ {
+ (void) WriteBlobMSBShort(image, tmp_image->matte ? 5 : 4);
+ if (tmp_image->matte) {
+ (void) WriteBlobMSBShort(image, (magick_uint16_t) -1);
+ (void) WriteBlobMSBLong(image, channel_size);
+ }
+ (void) WriteBlobMSBShort(image, 0);
+ (void) WriteBlobMSBLong(image, channel_size);
+ (void) WriteBlobMSBShort(image, 1);
+ (void) WriteBlobMSBLong(image, channel_size);
+ (void) WriteBlobMSBShort(image, 2);
+ (void) WriteBlobMSBLong(image, channel_size);
+ (void) WriteBlobMSBShort(image, 3);
+ (void) WriteBlobMSBLong(image, channel_size);
+ }
+
+ (void) WriteBlob(image, 4, "8BIM");
+ (void) WriteBlob(image, 4, CompositeOperatorToPSDBlendMode(tmp_image->compose));
+ (void) WriteBlobByte(image, 255); /* BOGUS: layer opacity */
+ (void) WriteBlobByte(image, 0);
+ (void) WriteBlobByte(image, 1); /* BOGUS: layer attributes - visible, etc. */
+ (void) WriteBlobByte(image, 0);
+
+ (void) WriteBlobMSBLong(image, 12);
+ (void) WriteBlobMSBLong(image, 0);
+ (void) WriteBlobMSBLong(image, 0);
+
+ theAttr = (ImageAttribute *)GetImageAttribute(tmp_image, "[layer-name]");
+ if (theAttr) {
+ WritePascalString( image, theAttr->value, 4 );
+ /*
+ sprintf((char *) &(layer_name[1]), "%4s", theAttr->value );
+ (void) WriteBlobByte(image, 3);
+ (void) WriteBlob(image, 3, &layer_name[1]);
+ */
+ } else {
+ /*
+ In Photoshop 5.5 the maximum number of layers was 100 but
+ Photoshop CS5 supports 8000 layers.
+
+ Layer name is documented to be a Pascal string, padded to
+ a multiple of 4 bytes.
+ */
+ char
+ layer_name[MaxTextExtent];
+
+ FormatString( layer_name, "L%04d", layer_count++ );
+ WritePascalString( image, layer_name, 4 );
+ }
+ tmp_image = tmp_image->next;
+ };
+
+ /* now the image data! */
+ tmp_image = base_image;
+ while ( tmp_image != NULL ) {
+ WriteImageChannels( image, tmp_image, pixels );
+
+ /* add in the pad! */
+ if ( rounded_layer_info_size != layer_info_size )
+ (void) WriteBlobByte(image, 0);
+
+ tmp_image = tmp_image->next;
+ };
+
+ /* user mask data */
+ (void) WriteBlobMSBLong(image, 0);
+
+ }
+
+ /* now the background image data! */
+ if ( force_white_background )
+ WriteWhiteBackground( image );
+ else
+ WriteImageChannels( image, image, pixels );
+
+ MagickFreeMemory(pixels);
+ CloseBlob(image);
+ return(True);
+}
+#endif /* defined(EnableBrokenCoders) && EnableBrokenCoders */
diff --git a/coders/pwp.c b/coders/pwp.c
new file mode 100644
index 0000000..71fbdf2
--- /dev/null
+++ b/coders/pwp.c
@@ -0,0 +1,306 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP W W PPPP %
+% P P W W P P %
+% PPPP W W PPPP %
+% P W W W P %
+% P W W P %
+% %
+% %
+% Read Seattle Film Works Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P W P %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPWP returns True if the image format type, identified by the
+% magick string, is PWP.
+%
+% The format of the IsPWP method is:
+%
+% unsigned int IsPWP(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsPWP returns True if the image format type is PWP.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsPWP(const unsigned char *magick,const size_t length)
+{
+ if (length < 5)
+ return(False);
+ if (LocaleNCompare((char *) magick,"SFW95",5) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d P W P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadPWPImage reads a Seattle Film Works multi-image file and returns
+% it. It allocates the memory necessary for the new Image structure and
+% returns a pointer to the new image.
+%
+% The format of the ReadPWPImage method is:
+%
+% Image *ReadPWPImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadPWPImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadPWPImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ FILE
+ *file;
+
+ Image
+ *image,
+ *next_image,
+ *pwp_image;
+
+ ImageInfo
+ *clone_info;
+
+ int
+ c;
+
+ MonitorHandler
+ handler;
+
+ register Image
+ *p;
+
+ register unsigned long
+ i;
+
+ size_t
+ count;
+
+ unsigned char
+ magick[MaxTextExtent];
+
+ unsigned int
+ status;
+
+ unsigned long
+ filesize;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=(Image *) NULL;
+ pwp_image=AllocateImage(image_info);
+ status=OpenBlob(image_info,pwp_image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,pwp_image);
+ count=ReadBlob(pwp_image,5,(char *) magick);
+ if ((count == 0) || (LocaleNCompare((char *) magick,"SFW95",5) != 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,pwp_image);
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ for ( ; ; )
+ {
+ for (c=ReadBlobByte(pwp_image); c != EOF; c=ReadBlobByte(pwp_image))
+ {
+ for (i=0; i < 17; i++)
+ magick[i]=magick[i+1];
+ magick[17]=(unsigned char) c;
+ if (LocaleNCompare((char *) (magick+12),"SFW94A",6) == 0)
+ break;
+ }
+ if (c == EOF)
+ break;
+ if (LocaleNCompare((char *) (magick+12),"SFW94A",6) != 0)
+ {
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,pwp_image);
+ }
+ /*
+ Dump SFW image to a temporary file.
+ */
+ file=AcquireTemporaryFileStream(clone_info->filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ {
+ char
+ filename[MaxTextExtent];
+
+ (void) strcpy(filename,clone_info->filename);
+ DestroyImageInfo(clone_info);
+ ThrowReaderTemporaryFileException(filename);
+ }
+ (void) fwrite("SFW94A",1,6,file);
+ filesize=(65535L*magick[2]+256L*magick[1]+magick[0]) & 0xFFFFFFFF;
+ for (i=0; i < filesize; i++)
+ {
+ if ((c=ReadBlobByte(pwp_image)) == EOF)
+ break;
+ (void) fputc(c,file);
+ }
+ (void) fclose(file);
+ if (c == EOF)
+ break;
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ next_image=ReadImage(clone_info,exception);
+ (void) LiberateTemporaryFile(clone_info->filename);
+ (void) SetMonitorHandler(handler);
+ if (next_image == (Image *) NULL)
+ break;
+ FormatString(next_image->filename,"slide_%02ld.sfw",next_image->scene);
+ if (image == (Image *) NULL)
+ image=next_image;
+ else
+ {
+ /*
+ Link image into image list.
+ */
+ for (p=image; p->next != (Image *) NULL; p=p->next);
+ next_image->previous=p;
+ next_image->scene=p->scene+1;
+ p->next=next_image;
+ }
+ if (image_info->subrange != 0)
+ if (next_image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (!MagickMonitorFormatted(TellBlob(pwp_image),GetBlobSize(image),
+ &image->exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ DestroyImageInfo(clone_info);
+ CloseBlob(pwp_image);
+ DestroyImage(pwp_image);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r P W P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterPWPImage adds attributes for the PWP image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterPWPImage method is:
+%
+% RegisterPWPImage(void)
+%
+*/
+ModuleExport void RegisterPWPImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PWP");
+ entry->decoder=(DecoderHandler) ReadPWPImage;
+ entry->magick=(MagickHandler) IsPWP;
+ entry->description="Seattle Film Works";
+ entry->module="PWP";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r P W P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterPWPImage removes format registrations made by the
+% PWP module from the list of supported formats.
+%
+% The format of the UnregisterPWPImage method is:
+%
+% UnregisterPWPImage(void)
+%
+*/
+ModuleExport void UnregisterPWPImage(void)
+{
+ (void) UnregisterMagickInfo("PWP");
+}
diff --git a/coders/rgb.c b/coders/rgb.c
new file mode 100644
index 0000000..5757a8a
--- /dev/null
+++ b/coders/rgb.c
@@ -0,0 +1,826 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% RRRR GGGG BBBB %
+% R R G B B %
+% RRRR G GG BBBB %
+% R R G G B B %
+% R R GGG BBBB %
+% %
+% %
+% Read/Write Raw RGB Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/constitute.h"
+#include "magick/enum_strings.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteRGBImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d R G B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadRGBImage reads an image of raw red, green, and blue samples and
+% returns it. It allocates the memory necessary for the new Image structure
+% and returns a pointer to the new image.
+%
+% The format of the ReadRGBImage method is:
+%
+% Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadRGBImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ size_t
+ count;
+
+ unsigned char
+ *scanline;
+
+ unsigned int
+ status;
+
+ unsigned int
+ packet_size,
+ quantum_size;
+
+ ImportPixelAreaOptions
+ import_options;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+ if (image_info->interlace != PartitionInterlace)
+ {
+ /*
+ Open image file.
+ */
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ for (i=0; i < image->offset; i++)
+ {
+ if (EOF == ReadBlobByte(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ }
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Tile %lux%lu%+ld%+ld",
+ image->tile_info.width,image->tile_info.height,
+ image->tile_info.x,image->tile_info.y);
+
+ /*
+ Allocate memory for a scanline.
+ */
+ if (image->depth <= 8)
+ quantum_size=8;
+ else if (image->depth <= 16)
+ quantum_size=16;
+ else
+ quantum_size=32;
+
+ packet_size=(quantum_size*3)/8;
+ if (LocaleCompare(image_info->magick,"RGBA") == 0)
+ {
+ image->matte=True;
+ packet_size=(quantum_size*4)/8;
+ }
+
+ scanline=MagickAllocateArray(unsigned char *,
+ packet_size,image->tile_info.width);
+ if (scanline == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize import options.
+ */
+ ImportPixelAreaOptionsInit(&import_options);
+ if (image_info->endian != UndefinedEndian)
+ import_options.endian=image_info->endian;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Depth %u bits, Endian %s, Interlace %s",
+ quantum_size,
+ EndianTypeToString(import_options.endian),
+ InterlaceTypeToString(image_info->interlace));
+ /*
+ Support starting at intermediate image frame.
+ */
+ if (image_info->subrange != 0)
+ while (image->scene < image_info->subimage)
+ {
+ /*
+ Skip to next image.
+ */
+ image->scene++;
+ for (y=0; y < (long) image->rows; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ }
+ x=(long) (packet_size*image->tile_info.x);
+ do
+ {
+ /*
+ Convert raster image to pixel packets.
+ */
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ switch (image_info->interlace)
+ {
+ case NoInterlace:
+ default:
+ {
+ QuantumType
+ quantum_type;
+
+ /*
+ No interlacing: RGBRGBRGBRGBRGBRGB...
+ */
+ quantum_type=(image->matte ? RGBAQuantum : RGBQuantum);
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,quantum_type,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ break;
+ }
+ case LineInterlace:
+ {
+ /*
+ Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
+ */
+ packet_size=(quantum_size)/8;
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,RedQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ (void) ImportImagePixelArea(image,GreenQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ (void) ImportImagePixelArea(image,BlueQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (image->matte)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,
+ scanline);
+ (void) ImportImagePixelArea(image,AlphaQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ break;
+ }
+ case PlaneInterlace:
+ case PartitionInterlace:
+ {
+ unsigned long
+ span;
+
+ /*
+ Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
+ */
+ if (image_info->interlace == PartitionInterlace)
+ {
+ AppendImageFormat("R",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ packet_size=(quantum_size)/8;
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ i=0;
+ span=image->rows*(image->matte ? 4 : 3);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,RedQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("G",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,GreenQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("B",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,BlueQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (image->matte)
+ {
+ /*
+ Read matte channel.
+ */
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("A",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < image->tile_info.y; y++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,
+ scanline);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ (void) ReadBlob(image,packet_size*image->tile_info.width,
+ scanline);
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void) ImportImagePixelArea(image,AlphaQuantum,quantum_size,scanline+x,
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(i,span))
+ if (!MagickMonitorFormatted(i,span,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ i++;
+ }
+ count=image->tile_info.height-image->rows-image->tile_info.y;
+ for (i=0; i < (long) count; i++)
+ (void) ReadBlob(image,packet_size*image->tile_info.width,
+ scanline);
+ }
+ if (image_info->interlace == PartitionInterlace)
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ break;
+ }
+ }
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (image_info->interlace == PartitionInterlace)
+ break;
+ count=ReadBlob(image,packet_size*image->tile_info.width,scanline);
+ if (count != 0)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ } while (count != 0);
+ MagickFreeMemory(scanline);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r R G B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterRGBImage adds attributes for the RGB image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterRGBImage method is:
+%
+% RegisterRGBImage(void)
+%
+*/
+ModuleExport void RegisterRGBImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("RGB");
+ entry->decoder=(DecoderHandler) ReadRGBImage;
+ entry->encoder=(EncoderHandler) WriteRGBImage;
+ entry->raw=True;
+ entry->description="Raw red, green, and blue samples";
+ entry->module="RGB";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("RGBA");
+ entry->decoder=(DecoderHandler) ReadRGBImage;
+ entry->encoder=(EncoderHandler) WriteRGBImage;
+ entry->raw=True;
+ entry->description="Raw red, green, blue, and matte samples";
+ entry->module="RGB";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r R G B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterRGBImage removes format registrations made by the
+% RGB module from the list of supported formats.
+%
+% The format of the UnregisterRGBImage method is:
+%
+% UnregisterRGBImage(void)
+%
+*/
+ModuleExport void UnregisterRGBImage(void)
+{
+ (void) UnregisterMagickInfo("RGB");
+ (void) UnregisterMagickInfo("RGBA");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e R G B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteRGBImage writes an image to a file in red, green, and blue
+% rasterfile format.
+%
+% The format of the WriteRGBImage method is:
+%
+% unsigned int WriteRGBImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteRGBImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteRGBImage(const ImageInfo *image_info,Image *image)
+{
+ int
+ y;
+
+ register const PixelPacket
+ *p;
+
+ unsigned char
+ *pixels;
+
+ unsigned int
+ status;
+
+ unsigned int
+ packet_size,
+ quantum_size,
+ scene;
+
+ ExportPixelAreaOptions
+ export_options;
+
+ ExportPixelAreaInfo
+ export_info;
+
+ /*
+ Allocate memory for pixels.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (image->depth <= 8)
+ quantum_size=8;
+ else if (image->depth <= 16)
+ quantum_size=16;
+ else
+ quantum_size=32;
+
+ packet_size=(quantum_size*3)/8;
+ if (LocaleCompare(image_info->magick,"RGBA") == 0)
+ packet_size=(quantum_size*4)/8;
+ pixels=MagickAllocateArray(unsigned char *,packet_size,image->columns);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (image_info->interlace != PartitionInterlace)
+ {
+ /*
+ Open output image file.
+ */
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ scene=0;
+ /*
+ Initialize export options.
+ */
+ ExportPixelAreaOptionsInit(&export_options);
+ if (image->endian != UndefinedEndian)
+ export_options.endian=image->endian;
+ else if (image_info->endian != UndefinedEndian)
+ export_options.endian=image_info->endian;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Depth %u bits, Endian %s, Interlace %s",
+ quantum_size,
+ EndianTypeToString(export_options.endian),
+ InterlaceTypeToString(image_info->interlace));
+ do
+ {
+ /*
+ Convert MIFF to RGB raster pixels.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ if (LocaleCompare(image_info->magick,"RGBA") == 0)
+ if (!image->matte)
+ SetImageOpacity(image,OpaqueOpacity);
+ switch (image_info->interlace)
+ {
+ case NoInterlace:
+ default:
+ {
+ QuantumType
+ quantum_type;
+
+ /*
+ No interlacing: RGBRGBRGBRGBRGBRGB...
+ */
+ quantum_type=RGBQuantum;
+ if (LocaleCompare(image_info->magick,"RGBA") == 0)
+ quantum_type=RGBAQuantum;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,quantum_type,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case LineInterlace:
+ {
+ /*
+ Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,RedQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ (void) ExportImagePixelArea(image,GreenQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ (void) ExportImagePixelArea(image,BlueQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ if (LocaleCompare(image_info->magick,"RGBA") == 0)
+ {
+ (void) ExportImagePixelArea(image,AlphaQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ case PlaneInterlace:
+ case PartitionInterlace:
+ {
+ /*
+ Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
+ */
+ if (image_info->interlace == PartitionInterlace)
+ {
+ AppendImageFormat("R",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,RedQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("G",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ if (!MagickMonitorFormatted(100,400,&image->exception,SaveImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,GreenQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("B",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ if (!MagickMonitorFormatted(200,400,&image->exception,SaveImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,BlueQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ if (LocaleCompare(image_info->magick,"RGBA") == 0)
+ {
+ if (!MagickMonitorFormatted(300,400,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ if (image_info->interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("A",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) ExportImagePixelArea(image,AlphaQuantum,quantum_size,pixels,
+ &export_options,&export_info);
+ (void) WriteBlob(image,export_info.bytes_exported,pixels);
+ }
+ }
+ if (image_info->interlace == PartitionInterlace)
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ (void) MagickMonitorFormatted(400,400,&image->exception,SaveImageText,
+ image->filename,
+ image->columns,image->rows);
+ break;
+ }
+ }
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename))
+ break;
+ } while (image_info->adjoin);
+ MagickFreeMemory(pixels);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/rla.c b/coders/rla.c
new file mode 100644
index 0000000..fc9f5e3
--- /dev/null
+++ b/coders/rla.c
@@ -0,0 +1,727 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% RRRR L AAA %
+% R R L A A %
+% RRRR L AAAAA %
+% R R L A A %
+% R R LLLLL A A %
+% %
+% %
+% Read Alias/Wavefront Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d R L A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadRLAImage reads a run-length encoded Wavefront RLA image file
+% and returns it. It allocates the memory necessary for the new Image
+% structure and returns a pointer to the new image.
+%
+% Note: This module was contributed by Lester Vecsey (master@internexus.net).
+%
+% The format of the ReadRLAImage method is:
+%
+% Image *ReadRLAImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadRLAImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define NULLTerminateASCIIField(field) \
+{ \
+ field[sizeof(field)-1]='\0'; \
+}
+
+#define ThrowRLAReaderException(code_,reason_,image_) \
+do { \
+ MagickFreeMemory(scanlines); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+static Image *ReadRLAImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ typedef struct _WindowFrame
+ {
+ short
+ left,
+ right,
+ bottom,
+ top;
+ } WindowFrame;
+
+ typedef struct _RLAInfo
+ {
+ WindowFrame
+ window,
+ active_window;
+
+ magick_uint16_t
+ frame,
+ storage_type,
+ number_channels,
+ number_matte_channels,
+ number_auxiliary_channels,
+ revision; /* aux_mask in RLB */
+
+ char
+ gamma[16],
+ red_primary[24],
+ green_primary[24],
+ blue_primary[24],
+ white_point[24];
+
+ magick_uint32_t
+ job_number;
+
+ char
+ name[128],
+ description[128],
+ program[64],
+ machine[32],
+ user[32],
+ date[20],
+ aspect[24],
+ aspect_ratio[8],
+ chan[32];
+
+ magick_uint16_t
+ field;
+
+ /* RLB varies after this point */
+
+ } RLAInfo;
+
+ typedef struct _RLA3ExtraInfo
+ {
+ char
+ time[12],
+ filter[32];
+
+ magick_uint16_t
+ bits_per_channel,
+ matte_type,
+ matte_bits,
+ auxiliary_type,
+ auxiliary_bits;
+
+ char
+ auxiliary[32],
+ space[36];
+
+ magick_uint32_t
+ next;
+ } RLA3ExtraInfo;
+
+ typedef struct _RLBExtraInfo
+ {
+ magick_uint16_t
+ filter_type;
+
+ magick_uint32_t
+ magic_number,
+ lut_size,
+ user_space_size,
+ wf_space_size;
+
+ magick_uint16_t
+ lut_type,
+ mix_type,
+ encode_type,
+ padding;
+
+ char
+ space[100];
+ } RLBExtraInfo;
+
+ Image
+ *image;
+
+ int
+ channel,
+ length,
+ number_channels,
+ runlength;
+
+ long
+ y;
+
+ magick_uint32_t
+ *scanlines=0;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ RLAInfo
+ rla_info;
+
+ RLA3ExtraInfo
+ rla3_extra_info;
+
+ RLBExtraInfo
+ rlb_extra_info;
+
+ MagickBool
+ is_rla3;
+
+ int
+ byte;
+
+ MagickPassFail
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ is_rla3=MagickFalse;
+ memset(&rla_info,0,sizeof(rla_info));
+ memset(&rla3_extra_info,0,sizeof(rla3_extra_info));
+ memset(&rlb_extra_info,0,sizeof(rlb_extra_info));
+ rla_info.window.left=ReadBlobMSBShort(image);
+ rla_info.window.right=ReadBlobMSBShort(image);
+ rla_info.window.bottom=ReadBlobMSBShort(image);
+ rla_info.window.top=ReadBlobMSBShort(image);
+ rla_info.active_window.left=ReadBlobMSBShort(image);
+ rla_info.active_window.right=ReadBlobMSBShort(image);
+ rla_info.active_window.bottom=ReadBlobMSBShort(image);
+ rla_info.active_window.top=ReadBlobMSBShort(image);
+ rla_info.frame=ReadBlobMSBShort(image);
+ rla_info.storage_type=ReadBlobMSBShort(image);
+ rla_info.number_channels=ReadBlobMSBShort(image);
+ rla_info.number_matte_channels=ReadBlobMSBShort(image);
+ if (rla_info.number_channels == 0)
+ rla_info.number_channels=3;
+ rla_info.number_auxiliary_channels=ReadBlobMSBShort(image);
+ rla_info.revision=ReadBlobMSBShort(image);
+ if (rla_info.revision == 0xFFFE)
+ is_rla3=MagickTrue;
+ (void) ReadBlob(image,16,(char *) rla_info.gamma);
+ NULLTerminateASCIIField(rla_info.gamma);
+ (void) ReadBlob(image,24,(char *) rla_info.red_primary);
+ NULLTerminateASCIIField(rla_info.red_primary);
+ (void) ReadBlob(image,24,(char *) rla_info.green_primary);
+ NULLTerminateASCIIField(rla_info.green_primary)
+ (void) ReadBlob(image,24,(char *) rla_info.blue_primary);
+ NULLTerminateASCIIField(rla_info.blue_primary);
+ (void) ReadBlob(image,24,(char *) rla_info.white_point);
+ NULLTerminateASCIIField(rla_info.white_point);
+ rla_info.job_number=(long) ReadBlobMSBLong(image);
+ (void) ReadBlob(image,128,(char *) rla_info.name);
+ NULLTerminateASCIIField(rla_info.name);
+ (void) ReadBlob(image,128,(char *) rla_info.description);
+ NULLTerminateASCIIField(rla_info.description);
+ (void) ReadBlob(image,64,(char *) rla_info.program);
+ NULLTerminateASCIIField(rla_info.program);
+ (void) ReadBlob(image,32,(char *) rla_info.machine);
+ NULLTerminateASCIIField(rla_info.machine);
+ (void) ReadBlob(image,32,(char *) rla_info.user);
+ NULLTerminateASCIIField(rla_info.user);
+ (void) ReadBlob(image,20,(char *) rla_info.date);
+ NULLTerminateASCIIField(rla_info.date);
+ (void) ReadBlob(image,24,(char *) rla_info.aspect);
+ NULLTerminateASCIIField(rla_info.aspect);
+ (void) ReadBlob(image,8,(char *) rla_info.aspect_ratio);
+ NULLTerminateASCIIField(rla_info.aspect_ratio);
+ (void) ReadBlob(image,32,(char *) rla_info.chan);
+ NULLTerminateASCIIField(rla_info.chan);
+ rla_info.field=ReadBlobMSBShort(image);
+ if (is_rla3)
+ {
+ (void) ReadBlob(image,12,(char *) rla3_extra_info.time);
+ NULLTerminateASCIIField(rla3_extra_info.time);
+ (void) ReadBlob(image,32,(char *) rla3_extra_info.filter);
+ NULLTerminateASCIIField(rla3_extra_info.filter);
+ rla3_extra_info.bits_per_channel=ReadBlobMSBShort(image);
+ rla3_extra_info.matte_type=ReadBlobMSBShort(image);
+ rla3_extra_info.matte_bits=ReadBlobMSBShort(image);
+ rla3_extra_info.auxiliary_type=ReadBlobMSBShort(image);
+ rla3_extra_info.auxiliary_bits=ReadBlobMSBShort(image);
+ (void) ReadBlob(image,32,(char *) rla3_extra_info.auxiliary);
+ NULLTerminateASCIIField(rla3_extra_info.auxiliary);
+ (void) ReadBlob(image,36,(char *) rla3_extra_info.space);
+ NULLTerminateASCIIField(rla3_extra_info.space);
+ rla3_extra_info.next=(long) ReadBlobMSBLong(image);
+ }
+ else
+ {
+ rlb_extra_info.filter_type=ReadBlobMSBShort(image);
+ rlb_extra_info.magic_number=ReadBlobMSBLong(image);
+ rlb_extra_info.lut_size=ReadBlobMSBLong(image);
+ rlb_extra_info.user_space_size=ReadBlobMSBLong(image);
+ rlb_extra_info.wf_space_size=ReadBlobMSBLong(image);
+ rlb_extra_info.lut_type=ReadBlobMSBShort(image);
+ rlb_extra_info.mix_type=ReadBlobMSBShort(image);
+ rlb_extra_info.encode_type=ReadBlobMSBShort(image);
+ rlb_extra_info.padding=ReadBlobMSBShort(image);
+ (void) ReadBlob(image,100,(char *) rlb_extra_info.space);
+ NULLTerminateASCIIField(rlb_extra_info.space);
+ }
+ if (EOFBlob(image))
+ ThrowRLAReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ /*
+ Verify revision.
+ */
+
+/* if (rla3_extra_info.revision != 0xFFFE) */
+/* ThrowRLAReaderException(CorruptImageError,ImproperImageHeader,image); */
+
+ /*
+ Verify dimensions.
+ */
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Active Window : Left=%d Right=%d Top=%d, Bottom=%d",
+ (int) rla_info.active_window.left,
+ (int) rla_info.active_window.right,
+ (int) rla_info.active_window.top,
+ (int) rla_info.active_window.bottom);
+ if ((((long) rla_info.active_window.right - rla_info.active_window.left) < 0) ||
+ (((long) rla_info.active_window.top-rla_info.active_window.bottom) < 0))
+ ThrowRLAReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (image->logging)
+ {
+ const char
+ *storage_type = "Unknown";
+
+ switch (rla_info.storage_type)
+ {
+ case 0:
+ storage_type = "INT8";
+ break;
+ case 1:
+ storage_type = "INT16";
+ break;
+ case 2:
+ storage_type = "INT32";
+ break;
+ case 3:
+ storage_type = "FLOAT32";
+ break;
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Storage Type : %s",storage_type);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Color Channels : %u", (unsigned int) rla_info.number_channels);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Matte Channels : %u", (unsigned int) rla_info.number_matte_channels);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Aux Channels : %u", (unsigned int) rla_info.number_auxiliary_channels);
+ if (is_rla3)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Format Revision: 0x%04X", rla_info.revision);
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Aux Mask : 0x%04X", rla_info.revision);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Gamma : %.16s", rla_info.gamma);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Red Primary : %.24s", rla_info.red_primary);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Green Primary : %.24s", rla_info.green_primary);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Blue Primary : %.24s", rla_info.blue_primary);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "White Point : %.24s", rla_info.white_point);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Job Number : %u", (unsigned int) rla_info.job_number);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Name : %.128s", rla_info.name);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Description : %.128s", rla_info.description);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Program : %.64s", rla_info.program);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Machine : %.32s", rla_info.machine);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "User : %.32s", rla_info.user);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Date : %.20s", rla_info.date);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Aspect : %.128s", rla_info.aspect);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Aspect Ratio : %.8s", rla_info.aspect_ratio);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Colorspace : %.32s", rla_info.chan);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Field : %u", (unsigned int) rla_info.field);
+
+ if (is_rla3)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Time : %.12s", rla3_extra_info.time);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Filter : %.32s", rla3_extra_info.filter);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "BitsPerChannel : %u", rla3_extra_info.bits_per_channel);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "MatteType : %u", rla3_extra_info.matte_type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "MatteBits : %u", rla3_extra_info.matte_bits);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "AuxType : %u", rla3_extra_info.auxiliary_type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "AuxBits : %u", rla3_extra_info.auxiliary_bits);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "AuxData : %.32s", rla3_extra_info.auxiliary);
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "FilterType : %u", rlb_extra_info.filter_type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "MagickNumber : %u", rlb_extra_info.magic_number);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "LUT Size : %u", rlb_extra_info.lut_size);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "User Space : %u", rlb_extra_info.user_space_size);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "WF Space : %u", rlb_extra_info.wf_space_size);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "LUT Type : %u", rlb_extra_info.lut_type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "MIX Type : %u", rlb_extra_info.mix_type);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Encode Type : %u", rlb_extra_info.encode_type);
+ }
+ }
+
+ if ((rla_info.storage_type != 0) || (rla_info.storage_type > 3))
+ ThrowRLAReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (rla_info.storage_type != 0)
+ ThrowRLAReaderException(CoderError,DataStorageTypeIsNotSupported,image);
+
+ if (LocaleNCompare(rla_info.chan,"rgb",3) != 0)
+ ThrowRLAReaderException(CoderError,ColorTypeNotSupported,image);
+
+ /*
+ Initialize image structure.
+ */
+ image->matte=(rla_info.number_matte_channels != 0 ? MagickTrue: MagickFalse);
+ image->columns=rla_info.active_window.right-rla_info.active_window.left+1;
+ image->rows=rla_info.active_window.top-rla_info.active_window.bottom+1;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Dimensions : %lux%lu",image->columns,image->rows);
+
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowRLAReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ number_channels=rla_info.number_channels+rla_info.number_matte_channels;
+ scanlines=MagickAllocateArray(magick_uint32_t *,image->rows,sizeof(magick_uint32_t));
+ if (scanlines == (magick_uint32_t *) NULL)
+ ThrowRLAReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (*rla_info.description != '\0')
+ (void) SetImageAttribute(image,"comment",rla_info.description);
+ /*
+ Read offsets to each scanline data.
+ */
+ for (i=0; i < (long) image->rows; i++)
+ {
+ scanlines[i]=(magick_uint32_t) ReadBlobMSBLong(image);
+#if 0
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "scanline[%ld] = %lu",i,(unsigned long) scanlines[i]);
+#endif
+ }
+ if (EOFBlob(image))
+ ThrowRLAReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ /*
+ Read image data.
+ */
+ x=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (SeekBlob(image,scanlines[image->rows-y-1],SEEK_SET) == -1)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Failed seek to %lu",
+ (unsigned long) image->rows-y-1);
+ status=MagickFail;
+ break;
+ }
+ for (channel=0; channel < number_channels; channel++)
+ {
+ length=ReadBlobMSBShort(image);
+ while (length > 0)
+ {
+ if ((byte=ReadBlobByte(image)) == EOF)
+ {
+ status=MagickFail;
+ break;
+ }
+ runlength=byte;
+ if (byte > 127)
+ runlength=byte-256;
+ length--;
+ if (length == 0)
+ break;
+ if (runlength < 0)
+ {
+ while (runlength < 0)
+ {
+ q=GetImagePixels(image,(long) (x % image->columns),
+ (long) (y % image->columns),1,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ if ((byte=ReadBlobByte(image)) == EOF)
+ {
+ status=MagickFail;
+ break;
+ }
+ length--;
+ switch (channel)
+ {
+ case 0:
+ {
+ q->red=ScaleCharToQuantum(byte);
+ break;
+ }
+ case 1:
+ {
+ q->green=ScaleCharToQuantum(byte);
+ break;
+ }
+ case 2:
+ {
+ q->blue=ScaleCharToQuantum(byte);
+ break;
+ }
+ case 3:
+ {
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(byte));
+ break;
+ }
+ default:
+ {
+ /* Depth channel ? */
+ break;
+ }
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ x++;
+ runlength++;
+ }
+ continue;
+ }
+ if ((byte=ReadBlobByte(image)) == EOF)
+ {
+ status=MagickFail;
+ break;
+ }
+ length--;
+ runlength++;
+ do
+ {
+ q=GetImagePixels(image,(long) (x % image->columns),
+ (long) (y % image->columns),1,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ switch (channel)
+ {
+ case 0:
+ {
+ q->red=ScaleCharToQuantum(byte);
+ break;
+ }
+ case 1:
+ {
+ q->green=ScaleCharToQuantum(byte);
+ break;
+ }
+ case 2:
+ {
+ q->blue=ScaleCharToQuantum(byte);
+ break;
+ }
+ case 3:
+ {
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(byte));
+ break;
+ }
+ default:
+ {
+ /* Depth channel ? */
+ break;
+ }
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ x++;
+ runlength--;
+ }
+ while (runlength > 0);
+
+ if (MagickFail == status)
+ break;
+ }
+ if (MagickFail == status)
+ break;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (MagickFail == status)
+ break;
+ }
+ if (EOFBlob(image))
+ ThrowRLAReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ CloseBlob(image);
+ MagickFreeMemory(scanlines);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r R L A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterRLAImage adds attributes for the RLA image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterRLAImage method is:
+%
+% RegisterRLAImage(void)
+%
+*/
+ModuleExport void RegisterRLAImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("RLA");
+ entry->decoder=(DecoderHandler) ReadRLAImage;
+ entry->adjoin=False;
+ entry->description="Alias/Wavefront image";
+ entry->seekable_stream=MagickTrue;
+ entry->module="RLA";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r R L A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterRLAImage removes format registrations made by the
+% RLA module from the list of supported formats.
+%
+% The format of the UnregisterRLAImage method is:
+%
+% UnregisterRLAImage(void)
+%
+*/
+ModuleExport void UnregisterRLAImage(void)
+{
+ (void) UnregisterMagickInfo("RLA");
+}
diff --git a/coders/rle.c b/coders/rle.c
new file mode 100644
index 0000000..cf2b34e
--- /dev/null
+++ b/coders/rle.c
@@ -0,0 +1,833 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% RRRR L EEEEE %
+% R R L E %
+% RRRR L EEE %
+% R R L E %
+% R R LLLLL EEEEE %
+% %
+% %
+% Read URT RLE Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+static unsigned int
+RLEConstrainColormapIndex(Image *image, unsigned int index,
+ unsigned int colormap_entries)
+{
+ if (index >= colormap_entries)
+ {
+ if (image->exception.severity < CorruptImageError)
+ {
+ char
+ colormapIndexBuffer[MaxTextExtent];
+
+ FormatString(colormapIndexBuffer,"index %u >= %u, %.1024s",
+ (unsigned int) index, colormap_entries, image->filename);
+ errno=0;
+ ThrowException(&image->exception,CorruptImageError,
+ InvalidColormapIndex,colormapIndexBuffer);
+ }
+ index=0U;
+ }
+
+ return index;
+}
+#define RLEVerifyColormapIndex(image,index,colormap_entries) \
+{ \
+ if (index >= colormap_entries) \
+ index=RLEConstrainColormapIndex(image,index,colormap_entries); \
+}
+typedef struct _RLE_Header
+{
+ magick_uint8_t Magic[2]; /* Magic number */
+ magick_uint16_t Xpos; /* Lower left x of image */
+ magick_uint16_t Ypos; /* Lower left y of image */
+ magick_uint16_t XSize; /* Image width */
+ magick_uint16_t YSize; /* Image height */
+ magick_uint8_t Flags; /* Misc flags */
+ magick_uint8_t Ncolors; /* Number of colors */
+ magick_uint8_t Pixelbits; /* Number of bits per channel */
+ magick_uint8_t Ncmap; /* Number of color channels in palette */
+ magick_uint8_t Cmaplen; /* Colormap length */
+
+} RLE_HEADER;
+
+static void LogRLEHeader(const RLE_HEADER* rle_header)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "RLE Header\n"
+ " Magic: \\%03o\\%03o\n"
+ " Xpos: %u\n"
+ " Ypos: %u\n"
+ " XSize: %u\n"
+ " YSize: %u\n"
+ " Flags: 0x%02x (%u,%u,%u,%u,%u,%u,%u,%u)\n"
+ " Ncolors: %u\n"
+ " Pixelbits: %u\n"
+ " Ncmap: %u\n"
+ " Cmaplen: %u",
+ rle_header->Magic[0],
+ rle_header->Magic[1],
+ rle_header->Xpos,
+ rle_header->Ypos,
+ rle_header->XSize,
+ rle_header->YSize,
+ rle_header->Flags,
+ (rle_header->Flags >> 7) & 0x01,
+ (rle_header->Flags >> 6) & 0x01,
+ (rle_header->Flags >> 5) & 0x01,
+ (rle_header->Flags >> 4) & 0x01,
+ (rle_header->Flags >> 3) & 0x01,
+ (rle_header->Flags >> 2) & 0x01,
+ (rle_header->Flags >> 1) & 0x01,
+ (rle_header->Flags >> 0) & 0x01,
+ rle_header->Ncolors,
+ rle_header->Pixelbits,
+ rle_header->Ncmap,
+ rle_header->Cmaplen);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s R L E %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsRLE returns True if the image format type, identified by the
+% magick string, is RLE.
+%
+% The format of the ReadRLEImage method is:
+%
+% unsigned int IsRLE(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsRLE returns True if the image format type is RLE.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsRLE(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if (memcmp(magick,"\122\314",2) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d R L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadRLEImage reads a run-length encoded Utah Raster Toolkit
+% image file and returns it. It allocates the memory necessary for the new
+% Image structure and returns a pointer to the new image.
+%
+% The format of the ReadRLEImage method is:
+%
+% Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadRLEImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowRLEReaderException(code_,reason_,image_) \
+do { \
+ MagickFreeMemory(colormap); \
+ MagickFreeMemory(rle_pixels); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+static Image *ReadRLEImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define SkipLinesOp 0x01
+#define SetColorOp 0x02
+#define SkipPixelsOp 0x03
+#define ByteDataOp 0x05
+#define RunDataOp 0x06
+#define EOFOp 0x07
+
+ RLE_HEADER
+ rle_header;
+
+ Image
+ *image;
+
+ int
+ opcode,
+ operand,
+ pixel,
+ status;
+
+ unsigned int
+ colormap_entries;
+
+ unsigned int
+ index;
+
+ unsigned long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register unsigned long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned int
+ i;
+
+ register unsigned char
+ *p;
+
+ size_t
+ count,
+ rle_bytes;
+
+ unsigned int
+ map_length;
+
+ unsigned char
+ background_color[256],
+ *colormap = (unsigned char *) NULL,
+ plane,
+ *rle_pixels = (unsigned char *) NULL;
+
+ unsigned int
+ number_colormaps,
+ number_pixels,
+ number_planes;
+
+ magick_off_t
+ file_size;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ (void) memset(&rle_header,0,sizeof(rle_header));
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowRLEReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Determine if this is a RLE file.
+ */
+ count=ReadBlob(image,2,(char *) &rle_header.Magic);
+ if ((count != 2) || (memcmp(&rle_header.Magic,"\122\314",2) != 0))
+ ThrowRLEReaderException(CorruptImageError,ImproperImageHeader,image);
+ file_size=GetBlobSize(image);
+ do
+ {
+ /*
+ Read image header.
+ */
+ rle_header.Xpos=ReadBlobLSBShort(image);
+ rle_header.Ypos=ReadBlobLSBShort(image);
+ rle_header.XSize=ReadBlobLSBShort(image);
+ rle_header.YSize=ReadBlobLSBShort(image);
+ rle_header.Flags=ReadBlobByte(image);
+ rle_header.Ncolors=ReadBlobByte(image);
+ rle_header.Pixelbits=ReadBlobByte(image);
+ rle_header.Ncmap=ReadBlobByte(image);
+ rle_header.Cmaplen=ReadBlobByte(image);
+ if (EOFBlob(image))
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ LogRLEHeader(&rle_header);
+
+ if ((rle_header.Ncolors == 0) ||
+ (rle_header.Ncolors == 2) ||
+ ((rle_header.Flags & 0x04) && (rle_header.Ncolors > 254)) ||
+ (rle_header.Pixelbits != 8))
+ ThrowRLEReaderException(CoderError,DataEncodingSchemeIsNotSupported,image);
+
+ if ((rle_header.XSize == 0) || (rle_header.YSize == 0))
+ ThrowRLEReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ image->columns=rle_header.XSize;
+ image->rows=rle_header.YSize;
+ image->matte=rle_header.Flags & 0x04;
+ number_planes=rle_header.Ncolors;
+ number_colormaps=rle_header.Ncmap;
+ map_length=(1U << rle_header.Cmaplen);
+
+ (void) memset(background_color,0,sizeof(background_color));
+ if (rle_header.Flags & 0x02)
+ {
+ /*
+ No background color-- initialize to black.
+ */
+ for (i=0; i < number_planes; i++)
+ background_color[i]=0;
+ (void) ReadBlobByte(image);
+ }
+ else
+ {
+ /*
+ Initialize background color.
+ */
+ p=background_color;
+ for (i=0; i < number_planes; i++)
+ *p++=ReadBlobByte(image);
+ }
+ if ((number_planes & 0x01) == 0)
+ (void) ReadBlobByte(image);
+
+ if (EOFBlob(image))
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ if (image->matte)
+ number_planes++;
+
+ /*
+ Rationalize pixels with file size
+ */
+ if ((file_size == 0) ||
+ ((((double) image->columns*image->rows*number_planes*
+ rle_header.Pixelbits/8)/file_size) > 254.0))
+ ThrowRLEReaderException(CorruptImageError,InsufficientImageDataInFile,
+ image);
+
+ if ((double) number_colormaps*map_length > file_size)
+ ThrowRLEReaderException(CorruptImageError,InsufficientImageDataInFile,
+ image);
+
+ colormap=(unsigned char *) NULL;
+ colormap_entries=0;
+ if (number_colormaps != 0)
+ {
+ /*
+ Read image colormaps. Color map values are stored as 16 bit
+ quantities, left justified in the word.
+ */
+ colormap=MagickAllocateArray(unsigned char *,number_colormaps,
+ map_length);
+ if (colormap == (unsigned char *) NULL)
+ ThrowRLEReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ p=colormap; /* unsigned char * */
+ for (i=0; i < number_colormaps; i++)
+ for (x=0; x < map_length; x++)
+ {
+ if (EOFBlob(image))
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,
+ image);
+ *p++=(ReadBlobLSBShort(image) >> 8);
+ }
+ colormap_entries=number_colormaps*map_length;
+ }
+ if (rle_header.Flags & 0x08)
+ {
+ char
+ *comment;
+
+ unsigned int
+ length;
+
+ /*
+ Read image comment.
+ */
+ length=ReadBlobLSBShort(image);
+ comment=MagickAllocateMemory(char *,length);
+ if (comment == (char *) NULL)
+ ThrowRLEReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ (void) ReadBlob(image,length-1,comment);
+ comment[length-1]='\0';
+ (void) SetImageAttribute(image,"comment",comment);
+ MagickFreeMemory(comment);
+ if ((length & 0x01) == 0)
+ (void) ReadBlobByte(image);
+ }
+
+ if (EOFBlob(image))
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowRLEReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Allocate RLE pixels.
+ */
+ number_pixels=image->columns*image->rows;
+ if ((image->columns != 0) &&
+ (image->rows != number_pixels/image->columns))
+ number_pixels=0;
+ rle_pixels=MagickAllocateArray(unsigned char *,number_pixels,
+ Max(number_planes,4));
+ if (rle_pixels == (unsigned char *) NULL)
+ ThrowRLEReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ rle_bytes=MagickArraySize(number_pixels,Max(number_planes,4));
+ (void) memset(rle_pixels,0,rle_bytes);
+ if ((rle_header.Flags & 0x01) && !(rle_header.Flags & 0x02))
+ {
+ int
+ j;
+
+ /*
+ Set background color.
+ */
+ p=rle_pixels;
+ for (i=0; i < number_pixels; i++)
+ {
+ if (!image->matte)
+ for (j=0; j < (int) number_planes; j++)
+ *p++=background_color[j];
+ else
+ {
+ for (j=0; j < ((int) number_planes-1); j++)
+ *p++=background_color[j];
+ *p++=0; /* initialize matte channel */
+ }
+ }
+ }
+ /*
+ Read runlength-encoded image.
+ */
+ plane=0;
+ x=0;
+ y=0;
+ opcode=ReadBlobByte(image);
+ if (opcode == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ do
+ {
+ switch (opcode & 0x3f)
+ {
+ case SkipLinesOp:
+ {
+ operand=ReadBlobByte(image);
+ if (operand == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (opcode & 0x40)
+ {
+ operand=ReadBlobLSBShort(image);
+ if (EOFBlob(image))
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ x=0;
+ y+=operand;
+ break;
+ }
+ case SetColorOp:
+ {
+ operand=ReadBlobByte(image);
+ if (operand == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ plane=(unsigned char) operand;
+ if (plane == 255)
+ plane=(unsigned char) (number_planes-1);
+ x=0;
+ break;
+ }
+ case SkipPixelsOp:
+ {
+ operand=ReadBlobByte(image);
+ if (operand == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (opcode & 0x40)
+ {
+ operand=ReadBlobLSBShort(image);
+ if (EOFBlob(image))
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ x+=operand;
+ break;
+ }
+ case ByteDataOp:
+ {
+ operand=ReadBlobByte(image);
+ if (operand == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (opcode & 0x40)
+ {
+ operand=ReadBlobLSBShort(image);
+ if (EOFBlob(image))
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ p=rle_pixels+((image->rows-y-1)*image->columns*number_planes)+
+ x*number_planes+plane;
+ operand++;
+ for (i=0; i < (unsigned int) operand; i++)
+ {
+ pixel=ReadBlobByte(image);
+ if (pixel == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if ((p >= rle_pixels) && (p < rle_pixels+rle_bytes))
+ *p=(unsigned char) pixel;
+ else
+ ThrowRLEReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image);
+ p+=number_planes;
+ }
+ if (operand & 0x01)
+ (void) ReadBlobByte(image);
+ x+=operand;
+ break;
+ }
+ case RunDataOp:
+ {
+ operand=ReadBlobByte(image);
+ if (operand == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (opcode & 0x40)
+ {
+ operand=ReadBlobLSBShort(image);
+ if (EOFBlob(image))
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ }
+ pixel=ReadBlobByte(image);
+ if (pixel == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ (void) ReadBlobByte(image);
+ operand++;
+ p=rle_pixels+((image->rows-y-1)*image->columns*number_planes)+
+ x*number_planes+plane;
+ for (i=0; i < (unsigned int) operand; i++)
+ {
+ if ((p >= rle_pixels) && (p < rle_pixels+rle_bytes))
+ *p=pixel;
+ else
+ ThrowRLEReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image);
+ p+=number_planes;
+ }
+ x+=operand;
+ break;
+ }
+ default:
+ break;
+ }
+ opcode=ReadBlobByte(image);
+ if (opcode == EOF)
+ ThrowRLEReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ } while (((opcode & 0x3f) != EOFOp) && (opcode != EOF));
+ if (number_colormaps != 0)
+ {
+ unsigned int
+ mask;
+
+ /*
+ Apply colormap affineation to image.
+ */
+ mask=(map_length-1);
+ p=rle_pixels;
+ if (number_colormaps == 1)
+ for (i=0; i < number_pixels; i++)
+ {
+ index=*p & mask;
+ RLEVerifyColormapIndex(image,index,colormap_entries);
+ *p=colormap[index];
+ p++;
+ }
+ else
+ if ((number_planes >= 3) && (number_colormaps >= 3))
+ for (i=0; i < number_pixels; i++)
+ for (x=0; x < number_planes; x++)
+ {
+ index=x*map_length+(*p & mask);
+ RLEVerifyColormapIndex(image,index,colormap_entries);
+ *p=colormap[index];
+ p++;
+ }
+ }
+ /*
+ Initialize image structure.
+ */
+ if (number_planes >= 3)
+ {
+ /*
+ Convert raster image to DirectClass pixel packets.
+ */
+ p=rle_pixels;
+ for (y=0; y < image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->blue=ScaleCharToQuantum(*p++);
+ if (image->matte)
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p++));
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ {
+ /*
+ Create colormap.
+ */
+ if (number_colormaps == 0)
+ map_length=256;
+ if (!AllocateImageColormap(image,map_length))
+ ThrowRLEReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ p=colormap;
+ if (number_colormaps == 1)
+ for (i=0; i < image->colors; i++)
+ {
+ /*
+ Pseudocolor.
+ */
+ image->colormap[i].red=ScaleCharToQuantum(i);
+ image->colormap[i].green=ScaleCharToQuantum(i);
+ image->colormap[i].blue=ScaleCharToQuantum(i);
+ }
+ else
+ if (number_colormaps > 1)
+ for (i=0; i < image->colors; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(*p);
+ image->colormap[i].green=ScaleCharToQuantum(*(p+map_length));
+ if (number_colormaps > 2)
+ image->colormap[i].blue=ScaleCharToQuantum(*(p+map_length*2));
+ else
+ image->colormap[i].blue=0U;
+ p++;
+ }
+ p=rle_pixels;
+ if (!image->matte)
+ {
+ /*
+ Convert raster image to PseudoClass pixel packets.
+ */
+ for (y=0; y < image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < image->columns; x++)
+ indexes[x]=(*p++);
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) SyncImage(image);
+ }
+ else
+ {
+ /*
+ Image has a matte channel-- promote to DirectClass.
+ */
+ for (y=0; y < image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < image->columns; x++)
+ {
+ index=*p++;
+ VerifyColormapIndex(image,index);
+ q->red=image->colormap[index].red;
+ index=*p++;
+ VerifyColormapIndex(image,index);
+ q->green=image->colormap[index].green;
+ index=*p++;
+ VerifyColormapIndex(image,index);
+ q->blue=image->colormap[index].blue;
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p++));
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(image->colormap);
+ image->colormap=(PixelPacket *) NULL;
+ image->storage_class=DirectClass;
+ image->colors=0;
+ }
+ }
+ if (number_colormaps != 0)
+ MagickFreeMemory(colormap);
+ MagickFreeMemory(rle_pixels);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ (void) ReadBlobByte(image);
+ count=ReadBlob(image,2,(char *) &rle_header.Magic);
+ if ((count == 2) && (memcmp(&rle_header.Magic,"\122\314",2) == 0))
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ } while ((count == 2) && (memcmp(&rle_header.Magic,"\122\314",2) == 0));
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r R L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterRLEImage adds attributes for the RLE image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterRLEImage method is:
+%
+% RegisterRLEImage(void)
+%
+*/
+ModuleExport void RegisterRLEImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("RLE");
+ entry->decoder=(DecoderHandler) ReadRLEImage;
+ entry->magick=(MagickHandler) IsRLE;
+ entry->adjoin=False;
+ entry->description="Utah Run length encoded image";
+ entry->module="RLE";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r R L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterRLEImage removes format registrations made by the
+% RLE module from the list of supported formats.
+%
+% The format of the UnregisterRLEImage method is:
+%
+% UnregisterRLEImage(void)
+%
+*/
+ModuleExport void UnregisterRLEImage(void)
+{
+ (void) UnregisterMagickInfo("RLE");
+}
diff --git a/coders/sct.c b/coders/sct.c
new file mode 100644
index 0000000..4de52d7
--- /dev/null
+++ b/coders/sct.c
@@ -0,0 +1,349 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS CCCC TTTTT %
+% SS C T %
+% SSS C T %
+% SS C T %
+% SSSSS CCCC T %
+% %
+% %
+% Read Scitex HandShake Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ The Scitex HandShake data format is specified in the document
+
+ HandShake Foreign File Transfer Protocol, Scitex Corporation, Ltd.,
+ Revision A: April 1988, Document No. 788-37898A, Catalog No. 399Z37898
+
+ http://www.oreilly.com/www/centers/gff/formats/scitex
+/
+*/
+
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s S C T %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsSCT returns True if the image format type, identified by the
+% magick string, is SCT.
+%
+% The format of the IsSCT method is:
+%
+% unsigned int IsSCT(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsSCT returns True if the image format type is SCT.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsSCT(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if (LocaleNCompare((char *) magick,"CT",2) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d S C T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadSCTImage reads a Scitex image file and returns it. It allocates
+% the memory necessary for the new Image structure and returns a pointer to
+% the new image.
+%
+% The format of the ReadSCTImage method is:
+%
+% Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadSCTImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ buffer[768],
+ magick[2];
+
+ Image
+ *image;
+
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ int
+ c;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read control block.
+ */
+ do
+ {
+ if (ReadBlob(image,80,(char *) buffer) != 80)
+ break;
+ if (ReadBlob(image,2,(char *) magick) != 2)
+ break;
+ if ((LocaleNCompare((char *) magick,"CT",2) != 0) &&
+ (LocaleNCompare((char *) magick,"LW",2) != 0) &&
+ (LocaleNCompare((char *) magick,"BM",2) != 0) &&
+ (LocaleNCompare((char *) magick,"PG",2) != 0) &&
+ (LocaleNCompare((char *) magick,"TX",2) != 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if ((LocaleNCompare((char *) magick,"LW",2) == 0) ||
+ (LocaleNCompare((char *) magick,"BM",2) == 0) ||
+ (LocaleNCompare((char *) magick,"PG",2) == 0) ||
+ (LocaleNCompare((char *) magick,"TX",2) == 0))
+ ThrowReaderException(CoderError,OnlyContinuousTonePictureSupported,image);
+ if (ReadBlob(image,174,(char *) buffer) != 174)
+ break;
+ if (ReadBlob(image,768,(char *) buffer) != 768)
+ break;
+ /*
+ Read parameter block.
+ */
+ if (ReadBlob(image,32,(char *) buffer) != 32)
+ break;
+ if (ReadBlob(image,14,(char *) buffer) != 14)
+ break;
+ buffer[14]='\0';
+ image->rows=MagickAtoL(buffer) & 0x7FFFFFFF;
+ if (ReadBlob(image,14,(char *) buffer) != 14)
+ break;
+ buffer[14]='\0';
+ image->columns=MagickAtoL(buffer) & 0x7FFFFFFF;
+ if (ReadBlob(image,196,(char *) buffer) != 196)
+ break;
+ if (ReadBlob(image,768,(char *) buffer) != 768)
+ break;
+ image->colorspace=CMYKColorspace;
+ }
+ while (0);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Convert SCT raster image to pixel packets.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ q->red=(Quantum) (MaxRGB-ScaleCharToQuantum(c));
+ q++;
+ }
+ if ((image->columns % 2) != 0)
+ if (ReadBlobByte(image) == EOF) /* pad */
+ break;
+ q=GetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ q->green=(Quantum) (MaxRGB-ScaleCharToQuantum(c));
+ q++;
+ }
+ if ((image->columns % 2) != 0)
+ if (ReadBlobByte(image) == EOF) /* pad */
+ break;
+ q=GetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ q->blue=(Quantum) (MaxRGB-ScaleCharToQuantum(c));
+ q++;
+ }
+ if ((image->columns % 2) != 0)
+ if (ReadBlobByte(image) == EOF) /* pad */
+ break;
+ q=GetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((c = ReadBlobByte(image)) == EOF)
+ break;
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(c));
+ q++;
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ if ((image->columns % 2) != 0)
+ if (ReadBlobByte(image) == EOF) /* pad */
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ if (EOFBlob(image))
+ break;
+ }
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r S C T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterSCTImage adds attributes for the SCT image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterSCTImage method is:
+%
+% RegisterSCTImage(void)
+%
+*/
+ModuleExport void RegisterSCTImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("SCT");
+ entry->decoder=(DecoderHandler) ReadSCTImage;
+ entry->magick=(MagickHandler) IsSCT;
+ entry->adjoin=False;
+ entry->description="Scitex HandShake";
+ entry->module="SCT";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r S C T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterSCTImage removes format registrations made by the
+% SCT module from the list of supported formats.
+%
+% The format of the UnregisterSCTImage method is:
+%
+% UnregisterSCTImage(void)
+%
+*/
+ModuleExport void UnregisterSCTImage(void)
+{
+ (void) UnregisterMagickInfo("SCT");
+}
diff --git a/coders/sfw.c b/coders/sfw.c
new file mode 100644
index 0000000..0880755
--- /dev/null
+++ b/coders/sfw.c
@@ -0,0 +1,431 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS FFFFF W W %
+% SS F W W %
+% SSS FFF W W %
+% SS F W W W %
+% SSSSS F W W %
+% %
+% %
+% Read/Write GraphicsMagick Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s S F W %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsSFW returns True if the image format type, identified by the
+% magick string, is SFW.
+%
+% The format of the IsSFW method is:
+%
+% unsigned int IsSFW(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsSFW returns True if the image format type is SFW.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsSFW(const unsigned char *magick,const size_t length)
+{
+ if (length < 5)
+ return(False);
+ if (LocaleNCompare((char *) magick,"SFW94",5) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d S F W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadSFWImage reads a Seattle Film Works image file and returns it.
+% It allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadSFWImage method is:
+%
+% Image *ReadSFWImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadSFWImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static unsigned char *SFWScan(const unsigned char *p,const unsigned char *q,
+ const unsigned char *target,const size_t length)
+{
+ register size_t
+ i;
+
+ if (p+length < q)
+ {
+ while( p < q )
+ {
+ for (i=0; i < length; i++)
+ if (p[i] != target[i])
+ break;
+ if (i == length)
+ return((unsigned char *) p);
+ p++;
+ }
+ }
+ return((unsigned char *) NULL);
+}
+
+static void TranslateSFWMarker(unsigned char *marker)
+{
+ switch (marker[1])
+ {
+ case 0xc8: marker[1]=0xd8; break; /* soi */
+ case 0xd0: marker[1]=0xe0; break; /* app */
+ case 0xcb: marker[1]=0xdb; break; /* dqt */
+ case 0xa0: marker[1]=0xc0; break; /* sof */
+ case 0xa4: marker[1]=0xc4; break; /* sof */
+ case 0xca: marker[1]=0xda; break; /* sos */
+ case 0xc9: marker[1]=0xd9; break; /* eoi */
+ default: break;
+ }
+}
+
+static Image *ReadSFWImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ static unsigned char
+ HuffmanTable[] =
+ {
+ 0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
+ 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00, 0x02, 0x01,
+ 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00,
+ 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21,
+ 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32,
+ 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1,
+ 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18,
+ 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64,
+ 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
+ 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3,
+ 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5,
+ 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
+ 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
+ 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x11,
+ 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04,
+ 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
+ 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13,
+ 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09,
+ 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24,
+ 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28,
+ 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45,
+ 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73,
+ 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85,
+ 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9,
+ 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2,
+ 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4,
+ 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
+ 0xF9, 0xFA
+ };
+
+ FILE
+ *file;
+
+ Image
+ *flipped_image,
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ register unsigned char
+ *header,
+ *data;
+
+ char
+ original_filename[MaxTextExtent],
+ original_magick[MaxTextExtent];
+
+ size_t
+ count;
+
+ unsigned char
+ *buffer,
+ *buffer_end,
+ *offset;
+
+ size_t
+ buffer_size;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read image into a buffer.
+ */
+ {
+ magick_off_t
+ blob_size;
+
+ blob_size=GetBlobSize(image);
+ buffer_size=(size_t)blob_size;
+ if ((magick_off_t) buffer_size != blob_size)
+ buffer_size=0;
+ }
+ if (buffer_size < 7)
+ {
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ buffer=MagickAllocateMemory(unsigned char *,buffer_size);
+ if (buffer == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ buffer_end=buffer+buffer_size-1;
+ count=ReadBlob(image,buffer_size,(char *) buffer);
+ if ((count != buffer_size) || (LocaleNCompare((char *) buffer,"SFW",3) != 0))
+ {
+ MagickFreeMemory(buffer);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ /*
+ Find the start of the JFIF data
+ */
+ header=SFWScan(buffer,buffer_end,
+ (unsigned char *)"\377\310\377\320",4);
+ if (header == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(buffer);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image)
+ }
+ /*
+ Translate soi and app tags. Accesses one beyond provided pointer.
+ */
+ TranslateSFWMarker(header);
+ TranslateSFWMarker(header+2);
+ (void) memcpy(header+6,"JFIF\0\001\0",7); /* JFIF magic */
+ /*
+ Translate remaining markers.
+ */
+ offset=header+2;
+ offset+=((unsigned int) offset[2] << 8)+offset[3]+2;
+ for ( ; ; )
+ {
+ if (offset+4 > buffer_end)
+ {
+ MagickFreeMemory(buffer);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image)
+ }
+ TranslateSFWMarker(offset);
+ if (offset[1] == 0xda)
+ break;
+ offset+=((unsigned int) offset[2] << 8)+offset[3]+2;
+ }
+ offset--;
+ data=SFWScan(offset,buffer_end,
+ (unsigned char *) "\377\311",2);
+ if (data == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(buffer);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image)
+ }
+ TranslateSFWMarker(data++); /* translate eoi marker */
+ /*
+ Write JFIF file.
+ */
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ file=AcquireTemporaryFileStream(clone_info->filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ {
+ char
+ filename[MaxTextExtent];
+
+ (void) strcpy(filename,clone_info->filename);
+ MagickFreeMemory(buffer);
+ DestroyImageInfo(clone_info);
+ ThrowReaderTemporaryFileException(filename)
+ }
+ (void) fwrite(header,(size_t) (offset-header+1),1,file);
+ (void) fwrite(HuffmanTable,1,sizeof(HuffmanTable)/sizeof(*HuffmanTable),file);
+ (void) fwrite(offset+1,(size_t) (data-offset),1,file);
+ status=ferror(file);
+ (void) fclose(file);
+ MagickFreeMemory(buffer);
+ if (status)
+ {
+ (void) LiberateTemporaryFile(clone_info->filename);
+ DestroyImageInfo(clone_info);
+ ThrowReaderException(FileOpenError,UnableToWriteFile,image)
+ }
+ CloseBlob(image);
+ strlcpy(original_filename,image->filename,sizeof(original_filename));
+ strlcpy(original_magick,image->magick,sizeof(original_magick));
+ DestroyImage(image);
+ /*
+ Read JPEG image.
+ */
+ image=ReadImage(clone_info,exception);
+ (void) LiberateTemporaryFile(clone_info->filename);
+ DestroyImageInfo(clone_info);
+ if (image == (Image *) NULL)
+ return(image);
+ /*
+ Restore the input filename and magick
+ */
+ (void) strlcpy(image->filename,original_filename,sizeof(image->filename));
+ (void) strlcpy(image->magick,original_magick,sizeof(image->magick));
+ /*
+ Correct image orientation.
+ */
+ if (GetPixelCachePresent(image))
+ {
+ flipped_image=FlipImage(image,exception);
+ if (flipped_image != (Image *) NULL)
+ {
+ DestroyImage(image);
+ image=flipped_image;
+ }
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r S F W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterSFWImage adds attributes for the SFW image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterSFWImage method is:
+%
+% RegisterSFWImage(void)
+%
+*/
+ModuleExport void RegisterSFWImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("SFW");
+ entry->decoder=(DecoderHandler) ReadSFWImage;
+ entry->magick=(MagickHandler) IsSFW;
+ entry->adjoin=False;
+ entry->description="Seattle Film Works";
+ entry->module="SFW";
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r S F W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterSFWImage removes format registrations made by the
+% SFW module from the list of supported formats.
+%
+% The format of the UnregisterSFWImage method is:
+%
+% UnregisterSFWImage(void)
+%
+*/
+ModuleExport void UnregisterSFWImage(void)
+{
+ (void) UnregisterMagickInfo("SFW");
+}
diff --git a/coders/sgi.c b/coders/sgi.c
new file mode 100644
index 0000000..b724bbe
--- /dev/null
+++ b/coders/sgi.c
@@ -0,0 +1,1288 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS GGGG IIIII %
+% SS G I %
+% SSS G GG I %
+% SS G G I %
+% SSSSS GGG IIIII %
+% %
+% %
+% Read/Write Irix RGB Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/magick_endian.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Typedef declaractions.
+*/
+
+/*
+ The SGI file header is 512 bytes in size.
+*/
+typedef struct _SGIInfo
+{
+ unsigned short
+ magic; /* Identification number (474) */
+
+ magick_int8_t
+ storage, /* Compression flag */
+ bytes_per_pixel; /* Bytes per pixel (per bit plane) */
+
+ magick_uint16_t
+ dimension, /* Number of image dimensions */
+ xsize, /* Width of image in pixels */
+ ysize, /* Height of image in pixels */
+ zsize; /* Number of bit planes */
+
+ magick_uint32_t
+ pix_min, /* Smallest pixel component value */
+ pix_max; /* Largest pixel component value */
+
+ char
+ dummy1[4]; /* Not used */
+
+ char
+ image_name[80]; /* Name of image (null terminated) */
+
+ magick_uint32_t
+ color_map; /* Format of pixel data */
+
+ char
+ dummy2[404]; /* Not used */
+} SGIInfo;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteSGIImage(const ImageInfo *,Image *);
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s S G I %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsSGI returns True if the image format type, identified by the
+% magick string, is SGI.
+%
+% The format of the IsSGI method is:
+%
+% unsigned int IsSGI(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsSGI returns True if the image format type is SGI.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsSGI(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if (memcmp(magick,"\001\332",2) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d S G I I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadSGIImage reads a SGI RGB image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadSGIImage method is:
+%
+% Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadSGIImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static int SGIDecode(const size_t bytes_per_pixel,
+ unsigned char *max_packets,unsigned char *pixels,
+ size_t npackets,size_t npixels)
+{
+ size_t
+ count;
+
+ register unsigned char
+ *p,
+ *q;
+
+ unsigned int
+ pixel;
+
+ p=max_packets;
+ q=pixels;
+ if (bytes_per_pixel == 2)
+ {
+ for ( ; ; )
+ {
+ if (npackets-- == 0)
+ return -1;
+ pixel=(*p++) << 8U;
+ pixel|=(*p++);
+ count=(pixel & 0x7fU);
+ if (count == 0)
+ break;
+ if (count > npixels)
+ return -1;
+ npixels -= count;
+ if (pixel & 0x80U)
+ for ( ; count != 0U; count--)
+ {
+ if (npackets-- == 0)
+ return -1;
+ *q=(*p++);
+ *(q+1)=(*p++);
+ q+=8U;
+ }
+ else
+ {
+ if (npackets-- == 0)
+ return -1;
+ pixel=(*p++) << 8U;
+ pixel|=(*p++);
+ for ( ; count != 0; count--)
+ {
+ *q=(unsigned char) (pixel >> 8U);
+ *(q+1)=(unsigned char) pixel;
+ q+=8U;
+ }
+ }
+ }
+ return 0;
+ }
+ for ( ; ; )
+ {
+ if (npackets-- == 0)
+ return -1;
+ pixel=(*p++);
+ count= (pixel & 0x7fU);
+ if (count == 0)
+ break;
+ if (count > npixels)
+ return -1;
+ npixels -= count;
+ if (pixel & 0x80)
+ for ( ; count != 0; count--)
+ {
+ if (npackets-- == 0)
+ return -1;
+ *q=(*p++);
+ q+=4;
+ }
+ else
+ {
+ if (npackets-- == 0)
+ return -1;
+ pixel=(*p++);
+ for ( ; count != 0; count--)
+ {
+ *q=(unsigned char) pixel;
+ q+=4;
+ }
+ }
+ }
+ return 0;
+}
+
+#define ThrowSGIReaderException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(iris_pixels) \
+ MagickFreeMemory(max_packets); \
+ MagickFreeMemory(offsets); \
+ MagickFreeMemory(runlength); \
+ MagickFreeMemory(scanline) \
+ ThrowReaderException(code_,reason_,image_); \
+}
+
+static Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ size_t
+ y,
+ z;
+
+ register IndexPacket
+ *indexes;
+
+ register size_t
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ SGIInfo
+ iris_info;
+
+ magick_uint32_t
+ *offsets = (magick_uint32_t *) NULL,
+ *runlength = (magick_uint32_t *) NULL;
+
+ unsigned char
+ *iris_pixels = (unsigned char *) NULL,
+ *max_packets = (unsigned char *) NULL,
+ *scanline = (unsigned char *) NULL;
+
+ unsigned int
+ status;
+
+ size_t
+ bytes_per_pixel;
+
+ magick_off_t
+ file_size;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read SGI raster header.
+ */
+ iris_info.magic=ReadBlobMSBShort(image);
+ file_size=GetBlobSize(image);
+ do
+ {
+ /*
+ Verify SGI identifier.
+ */
+ if (iris_info.magic != 0x01DA)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ iris_info.storage=ReadBlobByte(image);
+ iris_info.bytes_per_pixel=ReadBlobByte(image) &0xF;
+ iris_info.dimension=ReadBlobMSBShort(image) & 0xFFFF;
+ iris_info.xsize=ReadBlobMSBShort(image) & 0xFFFF;
+ iris_info.ysize=ReadBlobMSBShort(image) & 0xFFFF;
+ iris_info.zsize=ReadBlobMSBShort(image) & 0xFFFF;
+ iris_info.pix_min=ReadBlobMSBLong(image) & 0xFFFFFFFF;
+ iris_info.pix_max=ReadBlobMSBLong(image) & 0xFFFFFFFF;
+
+ (void) ReadBlob(image,(unsigned int) sizeof(iris_info.dummy1),
+ iris_info.dummy1);
+ (void) ReadBlob(image,(unsigned int) sizeof(iris_info.image_name),
+ iris_info.image_name);
+ iris_info.image_name[sizeof(iris_info.image_name)-1]=0;
+ iris_info.color_map=ReadBlobMSBLong(image);
+ (void) ReadBlob(image,(unsigned int) sizeof(iris_info.dummy2),
+ iris_info.dummy2);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "IRIS Header:\n"
+ " MAGIC=%u\n"
+ " STORAGE=%u (%s)\n"
+ " BPC=%u\n"
+ " DIMENSION=%u\n"
+ " XSIZE=%u\n"
+ " YSIZE=%u\n"
+ " ZSIZE=%u\n"
+ " PIXMIN=%u\n"
+ " PIXMAX=%u\n"
+ " IMAGENAME=\"%.79s\"\n"
+ " COLORMAP=%u",
+ (unsigned int) iris_info.magic,
+ (unsigned int) iris_info.storage,
+ (iris_info.storage == 1 ? "RLE" : "VERBATIM"),
+ (unsigned int) iris_info.bytes_per_pixel,
+ (unsigned int) iris_info.dimension,
+ (unsigned int) iris_info.xsize,
+ (unsigned int) iris_info.ysize,
+ (unsigned int) iris_info.zsize,
+ iris_info.pix_min,
+ iris_info.pix_max,
+ iris_info.image_name,
+ iris_info.color_map);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File size %" MAGICK_OFF_F "d bytes", file_size);
+
+ /*
+ Validate image header and set image attributes.
+ */
+ if (iris_info.storage == 0U)
+ {
+ /* Uncompressed */
+ image->compression=NoCompression;
+ }
+ else if (iris_info.storage == 1U)
+ {
+ /* RLE compressed */
+ image->compression=RLECompression;
+ }
+ else
+ {
+ /* Error */
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+
+ if (iris_info.color_map != 0U)
+ {
+ /* We only support images with normal (no) colormap */
+ ThrowReaderException(CorruptImageError,ImageTypeNotSupported,image);
+ }
+
+ if (iris_info.bytes_per_pixel == 1U)
+ {
+ /* 8 bits per sample */
+ image->depth=8;
+ }
+ else if (iris_info.bytes_per_pixel == 2U)
+ {
+ /* 16 bits per sample */
+ image->depth=Min(16,QuantumDepth);
+ }
+ else
+ {
+ /* Error */
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+
+ /* We only support zsize up to 4. Code further on assumes that. */
+ if (iris_info.zsize > 4U)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (iris_info.dimension == 1U)
+ {
+ /*
+ Image contains one channel and one scanline, with scanline
+ length specified by xsize.
+ */
+ image->columns=iris_info.xsize;
+ image->rows=1;
+ if (iris_info.ysize != image->rows)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Overriding unexpected value of YSIZE (%u) "
+ "for 1 dimensional image", iris_info.ysize);
+ iris_info.ysize=image->rows;
+ }
+ image->is_grayscale=MagickTrue;
+ if (iris_info.bytes_per_pixel == 1U)
+ {
+ /* Use a grayscale colormap */
+ image->storage_class=PseudoClass;
+ image->colors=256;
+ }
+ }
+ else if (iris_info.dimension == 2U)
+ {
+ /*
+ One channel with a number of scan lines. Width and height
+ of image are given by the values of xsize and ysize.
+ */
+ image->columns=iris_info.xsize;
+ image->rows=iris_info.ysize;
+ image->is_grayscale=MagickTrue;
+ if (iris_info.bytes_per_pixel == 1)
+ {
+ /* Use a grayscale colormap */
+ image->storage_class=PseudoClass;
+ image->colors=256;
+ }
+ }
+ else if (iris_info.dimension == 3U)
+ {
+ /*
+ A number of channels. Width and height of image are given
+ by the values of xsize and ysize. The number of channels is
+ specified by zsize.
+
+ B/W images have a zsize of 1. RGB images have a zsize of 3.
+ RGB images with an alpha channel have a zsize of 4. Images
+ may have more than four channels but the meaning of
+ additional channels is implementation dependent.
+ */
+
+ image->columns=iris_info.xsize;
+ image->rows=iris_info.ysize;
+
+ if (iris_info.zsize == 1U)
+ {
+ /* B/W image */
+ image->matte = MagickFalse;
+ image->is_grayscale=MagickTrue;
+ if (iris_info.bytes_per_pixel == 1U)
+ {
+ /* Use a grayscale colormap */
+ image->storage_class=PseudoClass;
+ image->colors=256U;
+ }
+ }
+ else if (iris_info.zsize == 3U)
+ {
+ /* RGB */
+ image->matte=MagickFalse;
+ }
+ else if (iris_info.zsize == 4U)
+ {
+ /* RGBA */
+ image->matte=MagickTrue;
+ }
+ else
+ {
+ /* Error */
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+ else
+ {
+ /* Error */
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+
+ if (iris_info.image_name[0])
+ (void) SetImageAttribute(image,"comment",iris_info.image_name);
+
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image columns=%lu rows=%lu", image->columns, image->rows);
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Allocate SGI pixels.
+ */
+ bytes_per_pixel=iris_info.bytes_per_pixel;
+ if (iris_info.storage != 0x01)
+ {
+ double
+ uncompressed_size;
+
+ /*
+ Check that filesize is reasonable given header
+ */
+ uncompressed_size=((double) (iris_info.dimension == 3U ? iris_info.zsize : 1U)*
+ image->columns*image->rows*iris_info.bytes_per_pixel);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Uncompressed size: %.0f", uncompressed_size);
+
+ /* Not compressed */
+ if (uncompressed_size > file_size)
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,
+ image);
+
+ /*
+ Read standard image format.
+ */
+ scanline=MagickAllocateArray(unsigned char *,
+ bytes_per_pixel,iris_info.xsize);
+ if (scanline == (unsigned char *) NULL)
+ ThrowSGIReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+
+ iris_pixels=MagickAllocateArray(unsigned char *,
+ MagickArraySize(4U,bytes_per_pixel),
+ MagickArraySize(iris_info.xsize,iris_info.ysize));
+ if (iris_pixels == (unsigned char *) NULL)
+ ThrowSGIReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Reading SGI scanlines");
+ for (z=0U; z < iris_info.zsize; z++)
+ {
+ p=iris_pixels+bytes_per_pixel*z;
+ for (y=0U; y < iris_info.ysize; y++)
+ {
+ if (ReadBlob(image,bytes_per_pixel*iris_info.xsize,
+ (char *) scanline) != bytes_per_pixel*iris_info.xsize)
+ {
+ ThrowSGIReaderException(CorruptImageError,
+ UnexpectedEndOfFile, image);
+ break;
+ }
+ if (bytes_per_pixel == 2U)
+ for (x=0; x < iris_info.xsize; x++)
+ {
+ *p=scanline[2U*x];
+ *(p+1U)=scanline[2U*x+1U];
+ p+=8U;
+ }
+ else
+ for (x=0; x < iris_info.xsize; x++)
+ {
+ *p=scanline[x];
+ p+=4U;
+ }
+ }
+ if (EOFBlob(image))
+ break;
+ }
+ MagickFreeMemory(scanline);
+ }
+ else
+ {
+ unsigned int
+ data_order;
+
+ magick_off_t
+ offset;
+
+ size_t
+ max_packets_alloc_size,
+ rle_alloc_size,
+ rle_dimensions;
+
+ magick_off_t
+ here;
+
+ rle_dimensions=MagickArraySize(iris_info.ysize, iris_info.zsize);
+ rle_alloc_size=MagickArraySize(rle_dimensions, sizeof(magick_uint32_t));
+
+ if ((rle_dimensions == 0U) || (rle_alloc_size == 0U))
+ ThrowSGIReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+
+ /*
+ Read runlength-encoded image format.
+ */
+ if (TellBlob(image)+rle_alloc_size > (size_t) file_size)
+ ThrowSGIReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ offsets=MagickAllocateMemory(magick_uint32_t *,rle_alloc_size);
+ if (offsets == (magick_uint32_t *) NULL)
+ ThrowSGIReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if (ReadBlob(image,rle_alloc_size,offsets) != rle_alloc_size)
+ ThrowSGIReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ if (TellBlob(image)+rle_alloc_size > (size_t) file_size)
+ ThrowSGIReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ runlength=MagickAllocateMemory(magick_uint32_t *,rle_alloc_size);
+ if (runlength == (magick_uint32_t *) NULL)
+ ThrowSGIReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if (ReadBlob(image,rle_alloc_size,runlength) != rle_alloc_size)
+ ThrowSGIReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+#if !defined(WORDS_BIGENDIAN)
+ MagickSwabArrayOfUInt32(offsets,rle_dimensions);
+ MagickSwabArrayOfUInt32(runlength,rle_dimensions);
+#endif
+ here=TellBlob(image);
+
+ for (i=0U; i < rle_dimensions; i++)
+ if ((offsets[i] != ((magick_off_t) offsets[i])) ||
+ (offsets[i] < here) ||
+ (offsets[i] > file_size))
+ ThrowSGIReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image);
+ for (i=0U; i < rle_dimensions; i++)
+ {
+ if (runlength[i] > ((size_t) 4U*iris_info.xsize+10U))
+ ThrowSGIReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image);
+ }
+
+ max_packets_alloc_size=MagickArraySize(iris_info.xsize+10U,4U);
+ max_packets=MagickAllocateMemory(unsigned char *,max_packets_alloc_size);
+ if (max_packets == (unsigned char *) NULL)
+ ThrowSGIReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+
+ iris_pixels=MagickAllocateArray(unsigned char *,
+ MagickArraySize(4U,bytes_per_pixel),
+ MagickArraySize(iris_info.xsize,iris_info.ysize));
+ if (iris_pixels == (unsigned char *) NULL)
+ ThrowSGIReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ /*
+ Check data order.
+ */
+ offset=0;
+ data_order=0U;
+ for (y=0; ((y < iris_info.ysize) && !data_order); y++)
+ for (z=0U; ((z < iris_info.zsize) && !data_order); z++)
+ {
+ const size_t run_index = (size_t) y+z*iris_info.ysize;
+ if (run_index >= rle_alloc_size)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage,image);
+ if (offsets[run_index] < offset)
+ data_order=1;
+ offset=(magick_off_t) offsets[run_index];
+ }
+ offset=TellBlob(image);
+ if (data_order == 1)
+ {
+ for (z=0U; z < iris_info.zsize; z++)
+ {
+ p=iris_pixels;
+ for (y=0U; y < iris_info.ysize; y++)
+ {
+ const size_t run_index = (size_t) y+z*iris_info.ysize;
+ size_t length;
+ if (run_index >= rle_alloc_size)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage,image);
+ if (offset != (magick_off_t) offsets[run_index])
+ {
+ offset=(magick_off_t) offsets[run_index];
+ if (SeekBlob(image,offset,SEEK_SET) != offset)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage, image);
+ }
+ length=runlength[run_index];
+ if (length > max_packets_alloc_size)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage,image);
+ if (ReadBlob(image,length,(char *) max_packets) != length)
+ ThrowSGIReaderException(CorruptImageError,
+ UnexpectedEndOfFile, image);
+ offset+=(magick_off_t) length;
+ if (SGIDecode(bytes_per_pixel,max_packets,p+bytes_per_pixel*z,
+ length/bytes_per_pixel,
+ iris_info.xsize) == -1)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage,image);
+ p+=((size_t) iris_info.xsize*4U*bytes_per_pixel);
+ }
+ }
+ }
+ else
+ {
+ p=iris_pixels;
+ for (y=0; y < iris_info.ysize; y++)
+ {
+ for (z=0; z < iris_info.zsize; z++)
+ {
+ const size_t run_index = (size_t) y+z*iris_info.ysize;
+ size_t length;
+ if (run_index >= rle_alloc_size)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage,image);
+ if (offset != (magick_off_t) offsets[run_index])
+ {
+ offset=(magick_off_t) offsets[run_index];
+ if (SeekBlob(image,offset,SEEK_SET) != offset)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage, image);
+ }
+ length=runlength[run_index];
+ if (length > max_packets_alloc_size)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage,image);
+ if (ReadBlob(image,length, (char *) max_packets) != length)
+ ThrowSGIReaderException(CorruptImageError,
+ UnexpectedEndOfFile, image);
+ offset+=length;
+ if (SGIDecode(bytes_per_pixel,max_packets,p+bytes_per_pixel*z,
+ length/bytes_per_pixel,
+ iris_info.xsize) == -1)
+ ThrowSGIReaderException(CorruptImageError,
+ UnableToRunlengthDecodeImage,image);
+ }
+ p+=((size_t) iris_info.xsize*4U*bytes_per_pixel);
+ if (EOFBlob(image))
+ break;
+ }
+ }
+ MagickFreeMemory(runlength);
+ MagickFreeMemory(max_packets);
+ MagickFreeMemory(offsets);
+ }
+
+ /*
+ Convert SGI raster image to pixel packets.
+ */
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Convert SGI image to DirectClass pixel packets.
+ */
+ if (bytes_per_pixel == 2U)
+ {
+ for (y=0; y < image->rows; y++)
+ {
+ p=iris_pixels+(image->rows-y-1)*8*image->columns;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0U; x < image->columns; x++)
+ {
+ q->red=ScaleShortToQuantum((*(p+0) << 8U) | (*(p+1)));
+ q->green=ScaleShortToQuantum((*(p+2) << 8U) | (*(p+3)));
+ q->blue=ScaleShortToQuantum((*(p+4) << 8U) | (*(p+5)));
+ if (image->matte)
+ q->opacity=(Quantum)
+ (MaxRGB-ScaleShortToQuantum((*(p+6) << 8) | (*(p+7))));
+ else
+ q->opacity=OpaqueOpacity;
+ p+=8U;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ for (y=0; y < image->rows; y++)
+ {
+ p=iris_pixels+(image->rows-y-1)*4*image->columns;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(*p);
+ q->green=ScaleCharToQuantum(*(p+1));
+ q->blue=ScaleCharToQuantum(*(p+2));
+ if (image->matte)
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*(p+3)));
+ else
+ q->opacity=OpaqueOpacity;
+ p+=4;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ {
+ /*
+ Create grayscale map.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowSGIReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ /*
+ Convert SGI image to PseudoClass pixel packets.
+ */
+ if (bytes_per_pixel == 2)
+ {
+ for (y=0; y < image->rows; y++)
+ {
+ p=iris_pixels+(image->rows-y-1)*8*image->columns;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < image->columns; x++)
+ {
+ indexes[x]=(*p << 8);
+ indexes[x]|=(*(p+1));
+ p+=8;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ for (y=0; y < image->rows; y++)
+ {
+ p=iris_pixels+(image->rows-y-1)*4U*image->columns;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < image->columns; x++)
+ {
+ indexes[x]=(*p);
+ p+=4;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) SyncImage(image);
+ }
+ MagickFreeMemory(iris_pixels);
+ if (EOFBlob(image))
+ {
+ ThrowSGIReaderException(CorruptImageError,UnexpectedEndOfFile,
+ image);
+ break;
+ }
+ } while (0);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r S G I I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterSGIImage adds attributes for the SGI image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterSGIImage method is:
+%
+% RegisterSGIImage(void)
+%
+*/
+ModuleExport void RegisterSGIImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("SGI");
+ entry->decoder=(DecoderHandler) ReadSGIImage;
+ entry->encoder=(EncoderHandler) WriteSGIImage;
+ entry->magick=(MagickHandler) IsSGI;
+ entry->description="Irix RGB image";
+ entry->module="SGI";
+ entry->adjoin=MagickFalse;
+ entry->seekable_stream=True;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r S G I I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterSGIImage removes format registrations made by the
+% SGI module from the list of supported formats.
+%
+% The format of the UnregisterSGIImage method is:
+%
+% UnregisterSGIImage(void)
+%
+*/
+ModuleExport void UnregisterSGIImage(void)
+{
+ (void) UnregisterMagickInfo("SGI");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e S G I I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteSGIImage writes an image in SGI RGB encoded image format.
+%
+% The format of the WriteSGIImage method is:
+%
+% unsigned int WriteSGIImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteSGIImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static size_t SGIEncode(unsigned char *pixels,size_t count,
+ unsigned char *packets)
+{
+ short
+ runlength;
+
+ register unsigned char
+ *p,
+ *q;
+
+ unsigned char
+ *limit,
+ *mark;
+
+ p=pixels;
+ limit=p+count*4;
+ q=packets;
+ while (p < limit)
+ {
+ mark=p;
+ p+=8;
+ while ((p < limit) && ((*(p-8) != *(p-4)) || (*(p-4) != *p)))
+ p+=4;
+ p-=8;
+ count=((p-mark) >> 2);
+ while (count)
+ {
+ runlength=(short) (count > 126 ? 126 : count);
+ count-=runlength;
+ *q++=0x80 | runlength;
+ for ( ; runlength > 0; runlength--)
+ {
+ *q++=(*mark);
+ mark+=4;
+ }
+ }
+ mark=p;
+ p+=4;
+ while ((p < limit) && (*p == *mark))
+ p+=4;
+ count=((p-mark) >> 2);
+ while (count)
+ {
+ runlength=(short) (count > 126 ? 126 : count);
+ count-=runlength;
+ *q++=(unsigned char) runlength;
+ *q++=(*mark);
+ }
+ }
+ *q++=0;
+ return(q-packets);
+}
+
+#define ThrowSGIWriterException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(scanline) \
+ MagickFreeMemory(offsets); \
+ MagickFreeMemory(packets); \
+ MagickFreeMemory(runlength); \
+ MagickFreeMemory(iris_pixels); \
+ ThrowWriterException(code_,reason_,image_); \
+}
+
+static unsigned int WriteSGIImage(const ImageInfo *image_info,Image *image)
+{
+ long
+ y,
+ z;
+
+ SGIInfo
+ iris_info;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned long
+ *offsets = (unsigned long *) NULL,
+ *runlength = (unsigned long *) NULL;
+
+ unsigned char
+ *iris_pixels = (unsigned char *) NULL,
+ *packets = (unsigned char *) NULL,
+ *scanline = (unsigned char *) NULL;
+
+ unsigned int
+ status;
+
+ unsigned long
+ number_pixels;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if ((image->columns > 65535L) || (image->rows > 65535L))
+ ThrowWriterException(ImageError,WidthOrHeightExceedsLimit,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ do
+ {
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Ensure that image is in an RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Analyze image to be written.
+ */
+ (void) GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception);
+ /*
+ Initialize SGI raster file header.
+ */
+ iris_info.magic=0x01DA;
+ if (image_info->compression == NoCompression)
+ iris_info.storage=0x00;
+ else
+ iris_info.storage=0x01;
+ iris_info.bytes_per_pixel=1; /* one byte per pixel */
+ iris_info.dimension=3;
+ iris_info.xsize=(unsigned short) image->columns;
+ iris_info.ysize=(unsigned short) image->rows;
+ if (image->matte != MagickFalse)
+ iris_info.zsize=4;
+ else
+ {
+ if ((image_info->type != TrueColorType) &&
+ (characteristics.grayscale))
+ {
+ iris_info.dimension=2;
+ iris_info.zsize=1;
+ }
+ else
+ iris_info.zsize=3;
+ }
+ iris_info.pix_min=0;
+ iris_info.pix_max=ScaleQuantumToChar(MaxRGB);
+
+ (void) memset(iris_info.dummy1,0,sizeof(iris_info.dummy1));
+ {
+ const ImageAttribute
+ *attribute;
+
+ (void) memset(iris_info.image_name,0,sizeof(iris_info.image_name));
+ if ((attribute=GetImageAttribute(image,"comment")))
+ (void) strlcpy(iris_info.image_name,attribute->value,sizeof(iris_info.image_name));
+ }
+ iris_info.color_map=0;
+ (void) memset(iris_info.dummy2,0,sizeof(iris_info.dummy2));
+
+ /*
+ Write SGI header.
+ */
+ (void) WriteBlobMSBShort(image,iris_info.magic);
+ (void) WriteBlobByte(image,iris_info.storage);
+ (void) WriteBlobByte(image,iris_info.bytes_per_pixel);
+ (void) WriteBlobMSBShort(image,iris_info.dimension);
+ (void) WriteBlobMSBShort(image,iris_info.xsize);
+ (void) WriteBlobMSBShort(image,iris_info.ysize);
+ (void) WriteBlobMSBShort(image,iris_info.zsize);
+ (void) WriteBlobMSBLong(image,iris_info.pix_min);
+ (void) WriteBlobMSBLong(image,iris_info.pix_max);
+ (void) WriteBlob(image,sizeof(iris_info.dummy1),
+ (char *) iris_info.dummy1);
+ (void) WriteBlob(image,sizeof(iris_info.image_name),
+ (char *) iris_info.image_name);
+ (void) WriteBlobMSBLong(image,iris_info.color_map);
+ (void) WriteBlob(image,sizeof(iris_info.dummy2),
+ (char *) iris_info.dummy2);
+ /*
+ Allocate SGI pixels.
+ */
+ number_pixels=image->columns*image->rows;
+ iris_pixels=MagickAllocateMemory(unsigned char *,4*number_pixels);
+ if (iris_pixels == (unsigned char *) NULL)
+ ThrowSGIWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Convert image pixels to uncompressed SGI pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=iris_pixels+((iris_info.ysize-1)-y)*(iris_info.xsize*4);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ *q++=ScaleQuantumToChar(MaxRGB-p->opacity);
+ p++;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (image_info->compression == NoCompression)
+ {
+ /*
+ Write uncompressed SGI pixels.
+ */
+ scanline=MagickAllocateMemory(unsigned char *,iris_info.xsize);
+ if (scanline == (unsigned char *) NULL)
+ ThrowSGIWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ for (z=0; z < (int) iris_info.zsize; z++)
+ {
+ q=iris_pixels+z;
+ for (y=0; y < (long) iris_info.ysize; y++)
+ {
+ for (x=0; x < (long) iris_info.xsize; x++)
+ {
+ scanline[x]=(*q);
+ q+=4;
+ }
+ (void) WriteBlob(image,iris_info.xsize,(char *) scanline);
+ }
+ }
+ MagickFreeMemory(scanline);
+ }
+ else
+ {
+ unsigned long
+ length,
+ number_packets,
+ offset;
+
+ /*
+ Convert SGI uncompressed pixels.
+ */
+ offsets=MagickAllocateArray(unsigned long *,iris_info.ysize,
+ MagickArraySize(iris_info.zsize,
+ sizeof(unsigned long)));
+ packets=MagickAllocateArray(unsigned char *,
+ 4*(2*(size_t) iris_info.xsize+10),
+ image->rows);
+ runlength=MagickAllocateArray(unsigned long *,iris_info.ysize,
+ MagickArraySize(iris_info.zsize,
+ sizeof(unsigned long)));
+ if ((offsets == (unsigned long *) NULL) ||
+ (packets == (unsigned char *) NULL) ||
+ (runlength == (unsigned long *) NULL))
+ ThrowSGIWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ offset=512+4*2*((size_t) iris_info.ysize*iris_info.zsize);
+ number_packets=0;
+ q=iris_pixels;
+ for (y=0; y < (long) iris_info.ysize; y++)
+ {
+ for (z=0; z < (int) iris_info.zsize; z++)
+ {
+ length=(unsigned long)
+ SGIEncode(q+z,(int) iris_info.xsize,packets+number_packets);
+ number_packets+=length;
+ offsets[y+z*iris_info.ysize]=offset;
+ runlength[y+z*iris_info.ysize]=length;
+ offset+=length;
+ }
+ q+=(iris_info.xsize*4);
+ }
+ /*
+ Write out line start and length tables and runlength-encoded pixels.
+ */
+ for (i=0; i < (int) (iris_info.ysize*iris_info.zsize); i++)
+ (void) WriteBlobMSBLong(image,offsets[i]);
+ for (i=0; i < (int) (iris_info.ysize*iris_info.zsize); i++)
+ (void) WriteBlobMSBLong(image,runlength[i]);
+ (void) WriteBlob(image,number_packets,(char *) packets);
+ /*
+ Free memory.
+ */
+ MagickFreeMemory(runlength);
+ MagickFreeMemory(packets);
+ MagickFreeMemory(offsets);
+ }
+ MagickFreeMemory(iris_pixels);
+ } while (0);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/stegano.c b/coders/stegano.c
new file mode 100644
index 0000000..ba849eb
--- /dev/null
+++ b/coders/stegano.c
@@ -0,0 +1,258 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS TTTTT EEEEE GGGG AAA N N OOO %
+% SS T E G A A NN N O O %
+% SSS T EEE G GG AAAAA N N N O O %
+% SS T E G G A A N NN O O %
+% SSSSS T EEEEE GGG A A N N OOO %
+% %
+% %
+% Write A Steganographic Image. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d S T E G A N O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadSTEGANOImage reads a steganographic image hidden within another
+% image type. It allocates the memory necessary for the new Image structure
+% and returns a pointer to the new image.
+%
+% The format of the ReadSTEGANOImage method is:
+%
+% Image *ReadSTEGANOImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadSTEGANOImage returns a pointer to the image
+% after reading. A null image is returned if there is a memory shortage
+% of if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadSTEGANOImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+#define GetBit(a,i) (((a) >> (i)) & 0x01)
+#define SetBit(a,i,set) \
+ a=(Quantum) ((set) ? (a) | (1UL << (i)) : (a) & ~(1UL << (i)))
+
+ Image
+ *image,
+ *watermark;
+
+ ImageInfo
+ *clone_info;
+
+ unsigned long
+ y;
+
+ long
+ k;
+
+ int
+ c,
+ i,
+ j;
+
+ PixelPacket
+ pixel;
+
+ register IndexPacket
+ *indexes;
+
+ register unsigned long
+ x;
+
+ register PixelPacket
+ *q;
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ *clone_info->magick='\0';
+ watermark=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ if (watermark == (Image *) NULL)
+ return((Image *) NULL);
+ watermark->depth=QuantumDepth;
+ if (!AllocateImageColormap(image,MaxColormapSize))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+ /*
+ Get hidden watermark from low-order bits of image.
+ */
+ c=0;
+ i=0;
+ j=0;
+ k=image->offset;
+ for (i=QuantumDepth-1; (i >= 0) && (j < QuantumDepth); i--)
+ {
+ for (y=0; (y < image->rows) && (j < QuantumDepth); y++)
+ {
+ for (x=0; (x < image->columns) && (j < QuantumDepth); x++)
+ {
+ (void) AcquireOnePixelByReference(watermark,&pixel,k % watermark->columns,
+ k/watermark->columns,exception);
+ q=GetImagePixels(image,x,y,1,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ switch (c)
+ {
+ case 0:
+ {
+ SetBit(*indexes,i,GetBit(pixel.red,j));
+ break;
+ }
+ case 1:
+ {
+ SetBit(*indexes,i,GetBit(pixel.green,j));
+ break;
+ }
+ case 2:
+ {
+ SetBit(*indexes,i,GetBit(pixel.blue,j));
+ break;
+ }
+ }
+ (void) SyncImage(image);
+ c++;
+ if (c == 3)
+ c=0;
+ k++;
+ if ((unsigned long) k == watermark->columns*watermark->columns)
+ k=0;
+ if (k == image->offset)
+ j++;
+ }
+ }
+ if (!MagickMonitorFormatted(i,QuantumDepth,&image->exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+ DestroyImage(watermark);
+ (void) SyncImage(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r S T E G A N O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterSTEGANOImage adds attributes for the STEGANO image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterSTEGANOImage method is:
+%
+% RegisterSTEGANOImage(void)
+%
+*/
+ModuleExport void RegisterSTEGANOImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("STEGANO");
+ entry->decoder=(DecoderHandler) ReadSTEGANOImage;
+ entry->description="Steganographic image";
+ entry->module="STEGANO";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r S T E G A N O I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterSTEGANOImage removes format registrations made by the
+% STEGANO module from the list of supported formats.
+%
+% The format of the UnregisterSTEGANOImage method is:
+%
+% UnregisterSTEGANOImage(void)
+%
+*/
+ModuleExport void UnregisterSTEGANOImage(void)
+{
+ (void) UnregisterMagickInfo("STEGANO");
+}
diff --git a/coders/sun.c b/coders/sun.c
new file mode 100644
index 0000000..f35abb2
--- /dev/null
+++ b/coders/sun.c
@@ -0,0 +1,1087 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS U U N N %
+% SS U U NN N %
+% SSS U U N N N %
+% SS U U N NN %
+% SSSSS UUU N N %
+% %
+% %
+% Read/Write Sun Rasterfile Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteSUNImage(const ImageInfo *,Image *);
+
+/* Raster Types */
+#define RT_STANDARD 1 /* Standard */
+#define RT_ENCODED 2 /* Byte encoded */
+#define RT_FORMAT_RGB 3 /* RGB format */
+
+/* Color Map Types */
+#define RMT_NONE 0 /* No color map */
+#define RMT_EQUAL_RGB 1 /* RGB color map */
+#define RMT_RAW 2 /* Raw color map */
+
+/*
+ Note that Sun headers described these fields as type 'int'.
+*/
+typedef struct _SUNInfo
+{
+ magick_uint32_t
+ magic, /* Magick (identification) number */
+ width, /* Width of image in pixels */
+ height, /* Height of image in pixels */
+ depth, /* Number of bits per pixel */
+ length, /* Size of image data in bytes */
+ type, /* Type of raster file */
+ maptype, /* Type of color map */
+ maplength; /* Size of the color map in bytes */
+} SUNInfo;
+
+static void LogSUNInfo(const SUNInfo *sun_info)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "SunHeader:\n"
+ " Magic: 0x%04X\n"
+ " Width: %u\n"
+ " Height: %u\n"
+ " Depth: %u\n"
+ " Length: %u\n"
+ " Type: %u (%s)\n"
+ " MapType: %u (%s)\n"
+ " MapLength: %u\n",
+ sun_info->magic,
+ sun_info->width,
+ sun_info->height,
+ sun_info->depth,
+ sun_info->length,
+ sun_info->type,
+ (sun_info->type == RT_STANDARD ? "Standard (RT_STANDARD)" :
+ (sun_info->type == RT_ENCODED ? "RLE encoded (RT_ENCODED)" :
+ (sun_info->type == RT_FORMAT_RGB ? "RGB format (RT_FORMAT_RGB)" :
+ "?"))),
+ sun_info->maptype,
+ (sun_info->maptype == RMT_NONE ? "No color map (RMT_NONE)" :
+ (sun_info->maptype == RMT_EQUAL_RGB ? "RGB color map (RMT_EQUAL_RGB)" :
+ (sun_info->maptype == RMT_RAW ? "Raw color map (RMT_RAW)" :
+ "?"))),
+ sun_info->maplength
+ );
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s S U N %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsSUN returns True if the image format type, identified by the
+% magick string, is SUN.
+%
+% The format of the IsSUN method is:
+%
+% unsigned int IsSUN(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsSUN returns True if the image format type is SUN.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsSUN(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (memcmp(magick,"\131\246\152\225",4) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DecodeImage unpacks the packed image pixels into
+% runlength-encoded pixel packets.
+%
+% The format of the DecodeImage method is:
+%
+% MagickPassFail DecodeImage(const unsigned char *compressed_pixels,
+% const size_t length,unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method DecodeImage returns True (MagickPass) if all the
+% pixels are uncompressed without error, otherwise False (MagickFail).
+%
+% o compressed_pixels: The address of a byte (8 bits) array of compressed
+% pixel data.
+%
+% o compressed_size: An integer value that is the total number of bytes
+% of the source image (as just read by ReadBlob)
+%
+% o pixels: The address of a byte (8 bits) array of pixel data created by
+% the uncompression process. The number of bytes in this array
+% must be at least equal to the number columns times the number of rows
+% of the source pixels.
+%
+% o pixels_size: Decompressed pixels buffer size.
+%
+%
+*/
+static MagickPassFail
+DecodeImage(const unsigned char *compressed_pixels,
+ const size_t compressed_size,
+ unsigned char *pixels,
+ const size_t pixels_size)
+{
+ register const unsigned char
+ *p;
+
+ register int
+ count;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ byte;
+
+ assert(compressed_pixels != (unsigned char *) NULL);
+ assert(pixels != (unsigned char *) NULL);
+ p=compressed_pixels;
+ q=pixels;
+ while (((size_t) (p-compressed_pixels) < compressed_size) &&
+ ((size_t) (q-pixels) < pixels_size))
+ {
+ byte=(*p++);
+ if (byte != 128U)
+ {
+ /*
+ Stand-alone byte
+ */
+ *q++=byte;
+ }
+ else
+ {
+ /*
+ Runlength-encoded packet: <count><byte>
+ */
+ if (((size_t) (p-compressed_pixels) >= compressed_size))
+ break;
+ count=(*p++);
+ if (count > 0)
+ {
+ if (((size_t) (p-compressed_pixels) >= compressed_size))
+ break;
+ byte=(*p++);
+ }
+ while ((count >= 0) && ((size_t) (q-pixels) < pixels_size))
+ {
+ *q++=byte;
+ count--;
+ }
+ }
+ }
+ return (((size_t) (q-pixels) == pixels_size) ? MagickPass : MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d S U N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadSUNImage reads a SUN image file and returns it. It allocates
+% the memory necessary for the new Image structure and returns a pointer to
+% the new image.
+%
+% The format of the ReadSUNImage method is:
+%
+% Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadSUNImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ int
+ bit;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ size_t
+ bytes_per_image,
+ bytes_per_line,
+ count,
+ sun_data_length;
+
+ SUNInfo
+ sun_info;
+
+ unsigned char
+ *sun_data,
+ *sun_pixels;
+
+ unsigned int
+ index;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read SUN raster header.
+ */
+ (void) memset(&sun_info,0,sizeof(sun_info));
+ sun_info.magic=ReadBlobMSBLong(image);
+ do
+ {
+ /*
+ Verify SUN identifier.
+ */
+ if (sun_info.magic != 0x59a66a95)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ sun_info.width=ReadBlobMSBLong(image);
+ sun_info.height=ReadBlobMSBLong(image);
+ sun_info.depth=ReadBlobMSBLong(image);
+ sun_info.length=ReadBlobMSBLong(image);
+ sun_info.type=ReadBlobMSBLong(image);
+ sun_info.maptype=ReadBlobMSBLong(image);
+ sun_info.maplength=ReadBlobMSBLong(image);
+ LogSUNInfo(&sun_info);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ /*
+ Verify that header values are in positive numeric range of a
+ 32-bit 'int' even though we store them in an unsigned value.
+ */
+ if ((sun_info.magic | sun_info.width | sun_info.height | sun_info.depth |
+ sun_info.type | sun_info.maptype | sun_info.maplength) & (1U << 31))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Verify that we support the image sub-type
+ */
+ if ((sun_info.type != RT_STANDARD) &&
+ (sun_info.type != RT_ENCODED) &&
+ (sun_info.type != RT_FORMAT_RGB))
+ ThrowReaderException(CoderError,DataEncodingSchemeIsNotSupported,image);
+ /*
+ Verify that we support the colormap type
+ */
+ if ((sun_info.maptype != RMT_NONE) &&
+ (sun_info.maptype != RMT_EQUAL_RGB))
+ ThrowReaderException(CoderError,ColormapTypeNotSupported,image);
+ /*
+ Insist that map length is zero if there is no colormap.
+ */
+ if ((sun_info.maptype == RMT_NONE) && (sun_info.maplength != 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Insist on a supported depth
+ */
+ if ((sun_info.depth != 1) &&
+ (sun_info.depth != 8) &&
+ (sun_info.depth != 24) &&
+ (sun_info.depth != 32))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ image->columns=sun_info.width;
+ image->rows=sun_info.height;
+ if (((unsigned long) ((long) image->columns) != image->columns) ||
+ ((unsigned long) ((long) image->rows) != image->rows))
+ ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ image->depth=sun_info.depth <= 8 ? 8 : QuantumDepth;
+ if (sun_info.depth < 24)
+ {
+ image->colors=sun_info.maplength;
+ if (sun_info.maptype == RMT_NONE)
+ image->colors=1 << sun_info.depth;
+ if (sun_info.maptype == RMT_EQUAL_RGB)
+ image->colors=sun_info.maplength/3;
+ }
+
+ switch (sun_info.maptype)
+ {
+ case RMT_NONE:
+ {
+ if (sun_info.depth < 24)
+ {
+ /*
+ Create linear color ramp.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ break;
+ }
+ case RMT_EQUAL_RGB:
+ {
+ unsigned char
+ *sun_colormap;
+
+ /*
+ Read SUN raster colormap.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ sun_colormap=MagickAllocateMemory(unsigned char *,image->colors);
+ if (sun_colormap == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ do
+ {
+ if (ReadBlob(image,image->colors,(char *) sun_colormap) !=
+ image->colors)
+ {
+ status = MagickFail;
+ break;
+ }
+ for (i=0; i < (long) image->colors; i++)
+ image->colormap[i].red=ScaleCharToQuantum(sun_colormap[i]);
+ if (ReadBlob(image,image->colors,(char *) sun_colormap) !=
+ image->colors)
+ {
+ status = MagickFail;
+ break;
+ }
+ for (i=0; i < (long) image->colors; i++)
+ image->colormap[i].green=ScaleCharToQuantum(sun_colormap[i]);
+ if (ReadBlob(image,image->colors,(char *) sun_colormap) !=
+ image->colors)
+ {
+ status = MagickFail;
+ break;
+ }
+ for (i=0; i < (long) image->colors; i++)
+ image->colormap[i].blue=ScaleCharToQuantum(sun_colormap[i]);
+ break;
+ } while (1);
+ MagickFreeMemory(sun_colormap);
+ if (MagickFail == status)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ break;
+ }
+ case RMT_RAW:
+ {
+ unsigned char
+ *sun_colormap;
+
+ /*
+ Read SUN raster colormap.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ sun_colormap=MagickAllocateMemory(unsigned char *,sun_info.maplength);
+ if (sun_colormap == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ if (ReadBlob(image,sun_info.maplength,(char *) sun_colormap) !=
+ sun_info.maplength)
+ status = MagickFail;
+ MagickFreeMemory(sun_colormap);
+ if (MagickFail == status)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ break;
+ }
+ default:
+ ThrowReaderException(CoderError,ColormapTypeNotSupported,image)
+ }
+ image->matte=(sun_info.depth == 32);
+ image->columns=sun_info.width;
+ image->rows=sun_info.height;
+ image->depth=8;
+ if (sun_info.depth < 8)
+ image->depth=sun_info.depth;
+
+ /*
+ Compute bytes per line and bytes per image for an unencoded
+ image.
+
+ "The width of a scan line is always 16-bits, padded when necessary."
+ */
+ bytes_per_line=MagickArraySize(sun_info.width,sun_info.depth)/8;
+ if ((bytes_per_line != 0) && (sun_info.depth == 1))
+ bytes_per_line += sun_info.width % 8 ? 1 : 0;
+ if (bytes_per_line != 0)
+ bytes_per_line=RoundUpToAlignment(bytes_per_line,2);
+
+ bytes_per_image=MagickArraySize(sun_info.height,bytes_per_line);
+
+ if (bytes_per_line == 0)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (bytes_per_image == 0)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if ((sun_info.type == RT_STANDARD) || (sun_info.type == RT_FORMAT_RGB))
+ if (bytes_per_image > sun_info.length)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+ if (sun_info.type == RT_ENCODED)
+ sun_data_length=(size_t) sun_info.length;
+ else
+ sun_data_length=bytes_per_image;
+ sun_data=MagickAllocateMemory(unsigned char *,sun_data_length);
+ if (sun_data == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if ((count=ReadBlob(image,sun_data_length,(char *) sun_data))
+ != sun_data_length)
+ {
+ MagickFreeMemory(sun_data);
+ ThrowReaderException(CorruptImageError,UnableToReadImageData,image);
+ }
+ sun_pixels=sun_data;
+ if (sun_info.type == RT_ENCODED)
+ {
+ /*
+ Read run-length encoded raster pixels (padded to 16-bit boundary).
+ */
+ sun_pixels=MagickAllocateMemory(unsigned char *,bytes_per_image);
+ if (sun_pixels == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ status &= DecodeImage(sun_data,sun_data_length,sun_pixels,bytes_per_image);
+ MagickFreeMemory(sun_data);
+ if (status != MagickPass)
+ {
+ MagickFreeMemory(sun_pixels);
+ ThrowReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image);
+ }
+ }
+ /*
+ Convert SUN raster image to pixel packets.
+ */
+ p=sun_pixels;
+ if (sun_info.depth == 1)
+ /*
+ Bilevel
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < ((long) image->columns-7); x+=8)
+ {
+ for (bit=7; bit >= 0; bit--)
+ {
+ index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
+ indexes[x+7-bit]=index;
+ q[x+7-bit]=image->colormap[index];
+ }
+ p++;
+ }
+ if ((image->columns % 8) != 0)
+ {
+ for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--)
+ {
+ index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
+ indexes[x+7-bit]=index;
+ q[x+7-bit]=image->colormap[index];
+ }
+ p++;
+ }
+ if ((((image->columns/8)+(image->columns % 8 ? 1 : 0)) % 2) != 0)
+ p++;
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ else
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Colormapped
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=(*p++);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ q[x]=image->colormap[index];
+ }
+ if ((image->columns % 2) != 0)
+ p++;
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ {
+ /*
+ (A)BGR or (A)RGB
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->matte)
+ q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p++));
+ if (sun_info.type == RT_STANDARD)
+ {
+ q->blue=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->red=ScaleCharToQuantum(*p++);
+ }
+ else
+ {
+ q->red=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->blue=ScaleCharToQuantum(*p++);
+ }
+ if (image->colors != 0)
+ {
+ q->red=image->colormap[q->red].red;
+ q->green=image->colormap[q->green].green;
+ q->blue=image->colormap[q->blue].blue;
+ }
+ q++;
+ }
+ if (((image->columns % 2) != 0) && (image->matte == False))
+ p++;
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ MagickFreeMemory(sun_pixels);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ sun_info.magic=ReadBlobMSBLong(image);
+ if (sun_info.magic == 0x59a66a95)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ } while (sun_info.magic == 0x59a66a95);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r S U N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterSUNImage adds attributes for the SUN image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterSUNImage method is:
+%
+% RegisterSUNImage(void)
+%
+*/
+ModuleExport void RegisterSUNImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("RAS");
+ entry->decoder=(DecoderHandler) ReadSUNImage;
+ entry->encoder=(EncoderHandler) WriteSUNImage;
+ entry->magick=(MagickHandler) IsSUN;
+ entry->description="SUN Rasterfile";
+ entry->module="SUN";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("SUN");
+ entry->decoder=(DecoderHandler) ReadSUNImage;
+ entry->encoder=(EncoderHandler) WriteSUNImage;
+ entry->description="SUN Rasterfile";
+ entry->module="SUN";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r S U N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterSUNImage removes format registrations made by the
+% SUN module from the list of supported formats.
+%
+% The format of the UnregisterSUNImage method is:
+%
+% UnregisterSUNImage(void)
+%
+*/
+ModuleExport void UnregisterSUNImage(void)
+{
+ (void) UnregisterMagickInfo("RAS");
+ (void) UnregisterMagickInfo("SUN");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e S U N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteSUNImage writes an image in the SUN rasterfile format.
+%
+% The format of the WriteSUNImage method is:
+%
+% unsigned int WriteSUNImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteSUNImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteSUNImage(const ImageInfo *image_info,Image *image)
+{
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register long
+ i;
+
+ SUNInfo
+ sun_info;
+
+ unsigned int
+ status;
+
+ unsigned long
+ number_pixels,
+ scene;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ scene=0;
+ do
+ {
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Ensure that image is in an RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+ /*
+ Initialize SUN raster file header.
+ */
+ sun_info.magic=0x59a66a95;
+ sun_info.width=image->columns;
+ sun_info.height=image->rows;
+ sun_info.type=
+ (image->storage_class == DirectClass ? RT_FORMAT_RGB : RT_STANDARD);
+ sun_info.maptype=RMT_NONE;
+ sun_info.maplength=0;
+ number_pixels=image->columns*image->rows;
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Full color SUN raster.
+ */
+ sun_info.depth=(image->matte ? 32U : 24U);
+ sun_info.length=(image->matte ? 4U : 3U)*number_pixels;
+ sun_info.length+=image->columns & 0x01U ? image->rows : 0U;
+ }
+ else
+ if (characteristics.monochrome)
+ {
+ /*
+ Monochrome SUN raster.
+ */
+ sun_info.depth=1;
+ sun_info.length=((image->columns+7U) >> 3)*image->rows;
+ sun_info.length+=((image->columns/8U)+(image->columns % 8U ? 1U : 0U)) %
+ 2U ? image->rows : 0U;
+ }
+ else
+ {
+ /*
+ Colormapped SUN raster.
+ */
+ sun_info.depth=8;
+ sun_info.length=number_pixels;
+ sun_info.length+=image->columns & 0x01U ? image->rows : 0;
+ sun_info.maptype=RMT_EQUAL_RGB;
+ sun_info.maplength=image->colors*3;
+ }
+ /*
+ Write SUN header.
+ */
+ LogSUNInfo(&sun_info);
+ (void) WriteBlobMSBLong(image,sun_info.magic);
+ (void) WriteBlobMSBLong(image,sun_info.width);
+ (void) WriteBlobMSBLong(image,sun_info.height);
+ (void) WriteBlobMSBLong(image,sun_info.depth);
+ (void) WriteBlobMSBLong(image,sun_info.length);
+ (void) WriteBlobMSBLong(image,sun_info.type);
+ (void) WriteBlobMSBLong(image,sun_info.maptype);
+ (void) WriteBlobMSBLong(image,sun_info.maplength);
+ /*
+ Convert MIFF to SUN raster pixels.
+ */
+ x=0;
+ y=0;
+ if (image->storage_class == DirectClass)
+ {
+ register unsigned char
+ *q;
+
+ size_t
+ length,
+ pad;
+
+ unsigned char
+ *pixels;
+
+ /*
+ Allocate memory for pixels.
+
+ Scanlines are padded to 16-bit boundary so account for padding.
+ */
+ pad=(image->columns & 0x01 ? 1 : 0);
+ length=(image->columns + pad) *sizeof(PixelPacket);
+ pixels=MagickAllocateMemory(unsigned char *,length);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ /*
+ Convert DirectClass packet to SUN RGB pixel.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (image->matte)
+ *q++=ScaleQuantumToChar(MaxRGB-p->opacity);
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ p++;
+ }
+ if (image->columns & 0x01)
+ *q++=0; /* pad scanline */
+ (void) WriteBlob(image,q-pixels,(char *) pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(pixels);
+ }
+ else
+ if (characteristics.monochrome)
+ {
+ register unsigned char
+ bit,
+ byte,
+ polarity;
+
+ /*
+ Convert PseudoClass image to a SUN monochrome image.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte<<=1;
+ if (indexes[x] == polarity)
+ byte|=0x01;
+ bit++;
+ if (bit == 8)
+ {
+ (void) WriteBlobByte(image,byte);
+ bit=0;
+ byte=0;
+ }
+ p++;
+ }
+ if (bit != 0)
+ (void) WriteBlobByte(image,byte << (8-bit));
+ if ((((image->columns/8)+
+ (image->columns % 8 ? 1 : 0)) % 2) != 0)
+ (void) WriteBlobByte(image,0); /* pad scanline */
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ {
+ /*
+ Dump colormap to file.
+ */
+ for (i=0; i < (long) image->colors; i++)
+ (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].red));
+ for (i=0; i < (long) image->colors; i++)
+ (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].green));
+ for (i=0; i < (long) image->colors; i++)
+ (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].blue));
+ /*
+ Convert PseudoClass packet to SUN colormapped pixel.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ (void) WriteBlobByte(image,indexes[x]);
+ p++;
+ }
+ if (image->columns & 0x01)
+ (void) WriteBlobByte(image,0); /* pad scanline */
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename))
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/svg.c b/coders/svg.c
new file mode 100644
index 0000000..ac83c7d
--- /dev/null
+++ b/coders/svg.c
@@ -0,0 +1,4374 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS V V GGGG %
+% SS V V G %
+% SSS V V G GG %
+% SS V V G G %
+% SSSSS V GGG %
+% %
+% %
+% Read/Write Scalable Vector Graphics Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% William Radcliffe %
+% March 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/constitute.h"
+#include "magick/gem.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/render.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#if defined(HasXML)
+# if defined(MSWINDOWS)
+# if defined(__MINGW32__)
+# define _MSC_VER
+# else
+# include <win32config.h>
+# endif
+# endif
+# include <libxml/parser.h>
+# include <libxml/xmlmemory.h>
+# include <libxml/parserInternals.h>
+# include <libxml/xmlerror.h>
+#endif
+
+/*
+ Disable SVG writer by default since it rarely works correctly.
+*/
+#if !defined(ENABLE_SVG_WRITER)
+# define ENABLE_SVG_WRITER 0
+#endif /* if !defined(ENABLE_SVG_WRITER) */
+
+/*
+ Avoid shadowing library globals and functions.
+*/
+#define attribute attribute_magick
+
+#if defined(HasAUTOTRACE)
+#include "types.h"
+#include "image-header.h"
+#include "fit.h"
+#include "output.h"
+#include "pxl-outline.h"
+#include "atquantize.h"
+#include "thin-image.h"
+
+char
+ *version_string = "AutoTrace version 0.24a";
+#endif
+
+/*
+ Define declarations.
+*/
+#define MVGPrintf (void) fprintf
+
+/*
+ Typedef declarations.
+*/
+typedef struct _BoundingBox
+{
+ double
+ x,
+ y,
+ width,
+ height;
+} BoundingBox;
+
+typedef struct _SVGInfo
+{
+ FILE
+ *file;
+
+ ExceptionInfo
+ *exception;
+
+ Image
+ *image;
+
+ const ImageInfo
+ *image_info;
+
+ AffineMatrix
+ affine;
+
+ unsigned long
+ width,
+ height;
+
+ char
+ *size,
+ *title,
+ *comment;
+
+ int
+ n;
+
+ double
+ *scale,
+ pointsize;
+
+ ElementInfo
+ element;
+
+ SegmentInfo
+ segment;
+
+ BoundingBox
+ bounds,
+ view_box;
+
+ PointInfo
+ radius;
+
+ char
+ *stop_color,
+ *offset,
+ *text,
+ *vertices,
+ *url;
+
+#if defined(HasXML)
+ xmlParserCtxtPtr
+ parser;
+
+ xmlDocPtr
+ document;
+#endif
+} SVGInfo;
+
+/*
+ Forward declarations.
+*/
+#if ENABLE_SVG_WRITER
+static unsigned int
+ WriteSVGImage(const ImageInfo *,Image *);
+#endif /* if ENABLE_SVG_WRITER */
+
+#if defined(HasXML)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d S V G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadSVGImage reads a Scalable Vector Gaphics file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadSVGImage method is:
+%
+% Image *ReadSVGImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadSVGImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static double
+GetUserSpaceCoordinateValue(const SVGInfo *svg_info,
+ int type,
+ const char *string,
+ MagickBool positive)
+{
+ char
+ *p,
+ token[MaxTextExtent];
+
+ double
+ value;
+
+ assert(string != (const char *) NULL);
+ p=(char *) string;
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if ((MagickAtoFChk(token,&value) == MagickFail) ||
+ (((positive) && value < 0.0)))
+ {
+ errno=0;
+ ThrowException(svg_info->exception,DrawError,InvalidPrimitiveArgument,
+ string);
+ }
+ if (strchr(token,'%') != (char *) NULL)
+ {
+ double
+ alpha,
+ beta;
+
+ if (type > 0)
+ return(svg_info->view_box.width*value/100.0);
+ if (type < 0)
+ return(svg_info->view_box.height*value/100.0);
+ alpha=value-svg_info->view_box.width;
+ beta=value-svg_info->view_box.height;
+ return(sqrt(alpha*alpha+beta*beta)/sqrt(2.0)/100.0);
+ }
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (LocaleNCompare(token,"cm",2) == 0)
+ return(72.0*svg_info->scale[0]/2.54*value);
+ if (LocaleNCompare(token,"em",2) == 0)
+ return(svg_info->pointsize*value);
+ if (LocaleNCompare(token,"ex",2) == 0)
+ return(svg_info->pointsize*value/2.0);
+ if (LocaleNCompare(token,"in",2) == 0)
+ return(72.0*svg_info->scale[0]*value);
+ if (LocaleNCompare(token,"mm",2) == 0)
+ return(72.0*svg_info->scale[0]/25.4*value);
+ if (LocaleNCompare(token,"pc",2) == 0)
+ return(72.0*svg_info->scale[0]/6.0*value);
+ if (LocaleNCompare(token,"pt",2) == 0)
+ return(svg_info->scale[0]*value);
+ if (LocaleNCompare(token,"px",2) == 0)
+ return(value);
+ return(value);
+}
+
+static char **GetStyleTokens(void *context,const char *text,size_t *number_tokens)
+{
+ char
+ **tokens;
+
+ register const char
+ *p,
+ *q;
+
+ register size_t
+ i;
+
+ SVGInfo
+ *svg_info;
+
+ svg_info=(SVGInfo *) context;
+ *number_tokens=0;
+ if (text == (const char *) NULL)
+ return((char **) NULL);
+ /*
+ Determine the number of arguments.
+ */
+ for (p=text; *p != '\0'; p++)
+ if (*p == ':')
+ (*number_tokens)+=2;
+ tokens=MagickAllocateMemory(char **,(*number_tokens+2)*sizeof(*tokens));
+ if (tokens == (char **) NULL)
+ {
+ ThrowException3(svg_info->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToConvertStringToTokens);
+ return((char **) NULL);
+ }
+ /*
+ Convert string to an ASCII list.
+ */
+ i=0;
+ p=text;
+ for (q=p; *q != '\0'; q++)
+ {
+ if ((*q != ':') && (*q != ';') && (*q != '\0'))
+ continue;
+ tokens[i]=AllocateString(p);
+ (void) strlcpy(tokens[i],p,q-p+1);
+ Strip(tokens[i++]);
+ p=q+1;
+ }
+ tokens[i]=AllocateString(p);
+ (void) strlcpy(tokens[i],p,q-p+1);
+ Strip(tokens[i++]);
+ tokens[i]=(char *) NULL;
+ return(tokens);
+}
+
+static char **GetTransformTokens(void *context,const char *text,
+ size_t *number_tokens)
+{
+ char
+ **tokens;
+
+ register const char
+ *p,
+ *q;
+
+ register size_t
+ i;
+
+ SVGInfo
+ *svg_info;
+
+ size_t
+ alloc_tokens;
+
+ svg_info=(SVGInfo *) context;
+ *number_tokens=0;
+ if (text == (const char *) NULL)
+ return((char **) NULL);
+
+ alloc_tokens=8;
+ tokens=MagickAllocateMemory(char **,(alloc_tokens+2)*sizeof(*tokens));
+ if (tokens == (char **) NULL)
+ {
+ ThrowException3(svg_info->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToConvertStringToTokens);
+ return((char **) NULL);
+ }
+ /*
+ Convert string to an ASCII list.
+ */
+ i=0;
+ p=text;
+ for (q=p; *q != '\0'; q++)
+ {
+ if ((*q != '(') && (*q != ')') && (*q != '\0'))
+ continue;
+ if (i == alloc_tokens)
+ {
+ alloc_tokens <<= 1;
+ MagickReallocMemory(char **,tokens,(alloc_tokens+2)*sizeof(*tokens));
+ if (tokens == (char **) NULL)
+ {
+ ThrowException3(svg_info->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToConvertStringToTokens);
+ return((char **) NULL);
+ }
+ }
+ tokens[i]=AllocateString(p);
+ (void) strlcpy(tokens[i],p,q-p+1);
+ Strip(tokens[i]);
+ i++;
+ p=q+1;
+ }
+ tokens[i]=AllocateString(p);
+ (void) strlcpy(tokens[i],p,q-p+1);
+ Strip(tokens[i++]);
+ tokens[i]=(char *) NULL;
+ *number_tokens=i;
+ return(tokens);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ static int SVGIsStandalone(void *context);
+
+ static int SVGIsStandalone(void *context);
+
+ static int SVGHasInternalSubset(void *context);
+
+ static int SVGHasExternalSubset(void *context);
+
+ static void SVGInternalSubset(void *context,const xmlChar *name,
+ const xmlChar *external_id,
+ const xmlChar *system_id);
+
+ static xmlParserInputPtr SVGResolveEntity(void *context,
+ const xmlChar *public_id,
+ const xmlChar *system_id);
+
+ static xmlEntityPtr SVGGetEntity(void *context,const xmlChar *name);
+
+ static xmlEntityPtr SVGGetParameterEntity(void *context,const xmlChar *name);
+
+ static void SVGEntityDeclaration(void *context,const xmlChar *name,int type,
+ const xmlChar *public_id,
+ const xmlChar *system_id,xmlChar *content);
+
+ static void SVGAttributeDeclaration(void *context,const xmlChar *element,
+ const xmlChar *name,int type,int value,
+ const xmlChar *default_value,
+ xmlEnumerationPtr tree);
+
+ static void SVGElementDeclaration(void *context,const xmlChar *name,int type,
+ xmlElementContentPtr content);
+
+ static void SVGNotationDeclaration(void *context,const xmlChar *name,
+ const xmlChar *public_id,
+ const xmlChar *system_id);
+
+ static void SVGUnparsedEntityDeclaration(void *context,const xmlChar *name,
+ const xmlChar *public_id,
+ const xmlChar *system_id,
+ const xmlChar *notation);
+
+ static void SVGSetDocumentLocator(void *context,
+ xmlSAXLocatorPtr location);
+
+ static void SVGStartDocument(void *context);
+
+ static void SVGEndDocument(void *context);
+
+ static void SVGStartElement(void *context,const xmlChar *name,
+ const xmlChar **attributes);
+
+ static void SVGEndElement(void *context,const xmlChar *name);
+
+ static void SVGCharacters(void *context,const xmlChar *c,int length);
+
+ static void SVGReference(void *context,const xmlChar *name);
+
+ static void SVGIgnorableWhitespace(void *context,const xmlChar *c,int length);
+
+ static void SVGProcessingInstructions(void *context,const xmlChar *target,
+ const xmlChar *data);
+
+ static void SVGComment(void *context,const xmlChar *value);
+
+ static void SVGWarning(void *context,const char *format,...);
+
+ static void SVGError(void *context,const char *format,...);
+
+ static void SVGCDataBlock(void *context,const xmlChar *value,int length);
+
+ static void SVGExternalSubset(void *context,const xmlChar *name,
+ const xmlChar *external_id,
+ const xmlChar *system_id);
+
+ ModuleExport void RegisterSVGImage(void);
+
+ ModuleExport void UnregisterSVGImage(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+static int
+SVGIsStandalone(void *context)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ Is this document tagged standalone?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.SVGIsStandalone()");
+ svg_info=(SVGInfo *) context;
+ return(svg_info->document->standalone == 1);
+}
+
+static int
+SVGHasInternalSubset(void *context)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ Does this document has an internal subset?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.SVGHasInternalSubset()");
+ svg_info=(SVGInfo *) context;
+ return(svg_info->document->intSubset != NULL);
+}
+
+static int
+SVGHasExternalSubset(void *context)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ Does this document has an external subset?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.SVGHasExternalSubset()");
+ svg_info=(SVGInfo *) context;
+ return(svg_info->document->extSubset != NULL);
+}
+
+static void
+SVGInternalSubset(void *context,const xmlChar *name,
+ const xmlChar *external_id,const xmlChar *system_id)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ Does this document has an internal subset?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.internalSubset(%.1024s, %.1024s, %.1024s)",(char *) name,
+ (external_id != (const xmlChar *) NULL ? (char *) external_id : "none"),
+ (system_id != (const xmlChar *) NULL ? (char *) system_id : "none"));
+ svg_info=(SVGInfo *) context;
+ (void) xmlCreateIntSubset(svg_info->document,name,external_id,system_id);
+}
+
+static xmlParserInputPtr
+SVGResolveEntity(void *context,
+ const xmlChar *public_id,const xmlChar *system_id)
+{
+ SVGInfo
+ *svg_info;
+
+ xmlParserInputPtr
+ stream;
+
+ /*
+ Special entity resolver, better left to the parser, it has more
+ context than the application layer. The default behaviour is to
+ not resolve the entities, in that case the ENTITY_REF nodes are
+ built in the structure (and the parameter values).
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.resolveEntity(%.1024s, %.1024s)",
+ (public_id != (const xmlChar *) NULL ? (char *) public_id : "none"),
+ (system_id != (const xmlChar *) NULL ? (char *) system_id : "none"));
+ svg_info=(SVGInfo *) context;
+ stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
+ public_id,svg_info->parser);
+ return(stream);
+}
+
+static xmlEntityPtr
+SVGGetEntity(void *context,const xmlChar *name)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ Get an entity by name.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.SVGGetEntity(%.1024s)",name);
+ svg_info=(SVGInfo *) context;
+ return(xmlGetDocEntity(svg_info->document,name));
+}
+
+static xmlEntityPtr
+SVGGetParameterEntity(void *context,const xmlChar *name)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ Get a parameter entity by name.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.getParameterEntity(%.1024s)",name);
+ svg_info=(SVGInfo *) context;
+ return(xmlGetParameterEntity(svg_info->document,name));
+}
+
+static void
+SVGEntityDeclaration(void *context,const xmlChar *name,int type,
+ const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ An entity definition has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.entityDecl(%.1024s, %d, %.1024s, %.1024s, %.1024s)",name,type,
+ public_id != (xmlChar *) NULL ? (char *) public_id : "none",
+ system_id != (xmlChar *) NULL ? (char *) system_id : "none",content);
+ svg_info=(SVGInfo *) context;
+ if (svg_info->parser->inSubset == 1)
+ (void) xmlAddDocEntity(svg_info->document,name,type,public_id,system_id,
+ content);
+ else
+ if (svg_info->parser->inSubset == 2)
+ (void) xmlAddDtdEntity(svg_info->document,name,type,public_id,system_id,
+ content);
+}
+
+static void
+SVGAttributeDeclaration(void *context,const xmlChar *element,
+ const xmlChar *name,int type,int value,const xmlChar *default_value,
+ xmlEnumerationPtr tree)
+{
+ SVGInfo
+ *svg_info;
+
+ xmlChar
+ *fullname,
+ *prefix;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ An attribute definition has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.attributeDecl(%.1024s, %.1024s, %d, %d, %.1024s, ...)",element,
+ name,type,value,default_value);
+ svg_info=(SVGInfo *) context;
+ fullname=(xmlChar *) NULL;
+ prefix=(xmlChar *) NULL;
+ parser=svg_info->parser;
+ fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
+ if (parser->inSubset == 1)
+ (void) xmlAddAttributeDecl(&parser->vctxt,svg_info->document->intSubset,
+ element,fullname,prefix,(xmlAttributeType) type,
+ (xmlAttributeDefault) value,default_value,tree);
+ else
+ if (parser->inSubset == 2)
+ (void) xmlAddAttributeDecl(&parser->vctxt,svg_info->document->extSubset,
+ element,fullname,prefix,(xmlAttributeType) type,
+ (xmlAttributeDefault) value,default_value,tree);
+ if (prefix != (xmlChar *) NULL)
+ xmlFree(prefix);
+ if (fullname != (xmlChar *) NULL)
+ xmlFree(fullname);
+}
+
+static void
+SVGElementDeclaration(void *context,const xmlChar *name,int type,
+ xmlElementContentPtr content)
+{
+ SVGInfo
+ *svg_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ An element definition has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.elementDecl(%.1024s, %d, ...)",name,type);
+ svg_info=(SVGInfo *) context;
+ parser=svg_info->parser;
+ if (parser->inSubset == 1)
+ (void) xmlAddElementDecl(&parser->vctxt,svg_info->document->intSubset,
+ name,(xmlElementTypeVal) type,content);
+ else
+ if (parser->inSubset == 2)
+ (void) xmlAddElementDecl(&parser->vctxt,svg_info->document->extSubset,
+ name,(xmlElementTypeVal) type,content);
+}
+
+static void
+SVGNotationDeclaration(void *context,const xmlChar *name,
+ const xmlChar *public_id,const xmlChar *system_id)
+{
+ SVGInfo
+ *svg_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ What to do when a notation declaration has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.notationDecl(%.1024s, %.1024s, %.1024s)",name,
+ public_id != (const xmlChar *) NULL ? (char *) public_id : "none",
+ system_id != (const xmlChar *) NULL ? (char *) system_id : "none");
+ svg_info=(SVGInfo *) context;
+ parser=svg_info->parser;
+ if (parser->inSubset == 1)
+ (void) xmlAddNotationDecl(&parser->vctxt,svg_info->document->intSubset,
+ name,public_id,system_id);
+ else
+ if (parser->inSubset == 2)
+ (void) xmlAddNotationDecl(&parser->vctxt,svg_info->document->intSubset,
+ name,public_id,system_id);
+}
+
+static void
+SVGUnparsedEntityDeclaration(void *context,const xmlChar *name,
+ const xmlChar *public_id,const xmlChar *system_id,
+ const xmlChar *notation)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ What to do when an unparsed entity declaration is parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.unparsedEntityDecl(%.1024s, %.1024s, %.1024s, %.1024s)",name,
+ public_id != (xmlChar *) NULL ? (char *) public_id : "none",
+ system_id != (xmlChar *) NULL ? (char *) system_id : "none",notation);
+ svg_info=(SVGInfo *) context;
+ (void) xmlAddDocEntity(svg_info->document,name,
+ XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
+
+}
+
+static void
+SVGSetDocumentLocator(void *context,
+ xmlSAXLocatorPtr location)
+{
+ /* SVGInfo */
+ /* *svg_info; */
+
+ ARG_NOT_USED(context);
+ ARG_NOT_USED(location);
+ /*
+ Receive the document locator at startup, actually xmlDefaultSAXLocator.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.setDocumentLocator()");
+ /* svg_info=(SVGInfo *) context; */
+}
+
+static void
+SVGStartDocument(void *context)
+{
+ SVGInfo
+ *svg_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ Called when the document start being processed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.startDocument()");
+ svg_info=(SVGInfo *) context;
+ DestroyExceptionInfo(svg_info->exception);
+ GetExceptionInfo(svg_info->exception);
+ parser=svg_info->parser;
+ svg_info->document=xmlNewDoc(parser->version);
+ if (svg_info->document == (xmlDocPtr) NULL)
+ return;
+ if (parser->encoding == NULL)
+ svg_info->document->encoding=(const xmlChar *) NULL;
+ else
+ svg_info->document->encoding=xmlStrdup(parser->encoding);
+ svg_info->document->standalone=parser->standalone;
+}
+
+static void
+SVGEndDocument(void *context)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ Called when the document end has been detected.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
+ svg_info=(SVGInfo *) context;
+ MagickFreeMemory(svg_info->offset);
+ MagickFreeMemory(svg_info->stop_color);
+ MagickFreeMemory(svg_info->scale);
+ MagickFreeMemory(svg_info->text);
+ MagickFreeMemory(svg_info->vertices);
+ MagickFreeMemory(svg_info->url);
+ if (svg_info->document != (xmlDocPtr) NULL)
+ {
+ xmlFreeDoc(svg_info->document);
+ svg_info->document=(xmlDocPtr) NULL;
+ }
+}
+
+static void
+SVGStartElement(void *context,const xmlChar *name,
+ const xmlChar **attributes)
+{
+ char
+ *color = NULL,
+ id[MaxTextExtent],
+ *p = NULL,
+ token[MaxTextExtent],
+ *units = NULL;
+
+ const char
+ *keyword = NULL,
+ *value = NULL;
+
+ size_t
+ number_tokens = 0;
+
+ SVGInfo
+ *svg_info;
+
+ size_t
+ i,
+ j;
+
+ /*
+ Called when an opening tag has been processed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.startElement(%.1024s",name);
+ id[0]='\0';
+ token[0]='\0';
+ svg_info=(SVGInfo *) context;
+ svg_info->n++;
+ MagickReallocMemory(double *,svg_info->scale,(svg_info->n+1)*sizeof(double));
+ if (svg_info->scale == (double *) NULL)
+ {
+ ThrowException(svg_info->exception,ResourceLimitError,
+ MemoryAllocationFailed,"unable to convert SVG image");
+ return;
+ }
+ svg_info->scale[svg_info->n]=svg_info->scale[svg_info->n-1];
+ color=AllocateString("none");
+ units=AllocateString("userSpaceOnUse");
+ value=(const char *) NULL;
+ if (attributes != (const xmlChar **) NULL)
+ for (i=0; (svg_info->exception->severity < ErrorException) &&
+ (attributes[i] != (const xmlChar *) NULL); i+=2)
+ {
+ keyword=(const char *) attributes[i];
+ value=(const char *) attributes[i+1];
+ switch (*keyword)
+ {
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(keyword,"cx") == 0)
+ {
+ svg_info->element.cx=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"cy") == 0)
+ {
+ svg_info->element.cy=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(keyword,"fx") == 0)
+ {
+ svg_info->element.major=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"fy") == 0)
+ {
+ svg_info->element.minor=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ svg_info->bounds.height=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickTrue);
+ break;
+ }
+ break;
+ }
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare(keyword,"id") == 0)
+ {
+ (void) strlcpy(id,value,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"r") == 0)
+ {
+ svg_info->element.angle=
+ GetUserSpaceCoordinateValue(svg_info,0,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ svg_info->bounds.width=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickTrue);
+ break;
+ }
+ break;
+ }
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(keyword,"x") == 0)
+ {
+ svg_info->bounds.x=GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"x1") == 0)
+ {
+ svg_info->segment.x1=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"x2") == 0)
+ {
+ svg_info->segment.x2=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(keyword,"y") == 0)
+ {
+ svg_info->bounds.y=GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"y1") == 0)
+ {
+ svg_info->segment.y1=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"y2") == 0)
+ {
+ svg_info->segment.y2=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (svg_info->exception->severity >= ErrorException)
+ goto svg_start_element_error;
+ if (strchr((char *) name,':') != (char *) NULL)
+ {
+ /*
+ Skip over namespace.
+ */
+ for ( ; *name != ':'; name++) ;
+ name++;
+ }
+ switch (*name)
+ {
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare((char *) name,"circle") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"clipPath") == 0)
+ {
+ MVGPrintf(svg_info->file,"push clip-path '%s'\n",id);
+ break;
+ }
+ break;
+ }
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare((char *) name,"defs") == 0)
+ {
+ MVGPrintf(svg_info->file,"push defs\n");
+ break;
+ }
+ break;
+ }
+ case 'E':
+ case 'e':
+ {
+ if (LocaleCompare((char *) name,"ellipse") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare((char *) name,"g") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare((char *) name,"image") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'L':
+ case 'l':
+ {
+ if (LocaleCompare((char *) name,"line") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"linearGradient") == 0)
+ {
+ MVGPrintf(svg_info->file,"push gradient '%s' linear %g,%g %g,%g\n",id,
+ svg_info->segment.x1,svg_info->segment.y1,svg_info->segment.x2,
+ svg_info->segment.y2);
+ break;
+ }
+ break;
+ }
+ case 'P':
+ case 'p':
+ {
+ if (LocaleCompare((char *) name,"path") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"pattern") == 0)
+ {
+ MVGPrintf(svg_info->file,"push pattern '%s' %g,%g %g,%g\n",id,
+ svg_info->bounds.x,svg_info->bounds.y,svg_info->bounds.width,
+ svg_info->bounds.height);
+ break;
+ }
+ if (LocaleCompare((char *) name,"polygon") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"polyline") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare((char *) name,"radialGradient") == 0)
+ {
+ if (svg_info->element.angle < 0.0)
+ {
+ errno=0;
+ ThrowException(svg_info->exception,DrawError,InvalidPrimitiveArgument,
+ value);
+ break;
+ }
+ MVGPrintf(svg_info->file,"push gradient '%s' radial %g,%g %g,%g %g\n",
+ id,svg_info->element.cx,svg_info->element.cy,
+ svg_info->element.major,svg_info->element.minor,
+ svg_info->element.angle);
+ break;
+ }
+ if (LocaleCompare((char *) name,"rect") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare((char *) name,"svg") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare((char *) name,"text") == 0)
+ {
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"tspan") == 0)
+ {
+ Strip(svg_info->text);
+ if (*svg_info->text != '\0')
+ {
+ DrawInfo
+ *draw_info;
+
+ TypeMetric
+ metrics;
+
+ char
+ *text;
+
+ text=EscapeString(svg_info->text,'\'');
+ MVGPrintf(svg_info->file,"text %g,%g '%s'\n",svg_info->bounds.x,
+ svg_info->bounds.y,text);
+ MagickFreeMemory(text);
+ draw_info=CloneDrawInfo(svg_info->image_info,(DrawInfo *) NULL);
+ draw_info->pointsize=svg_info->pointsize;
+ draw_info->text=AllocateString(svg_info->text);
+ (void) ConcatenateString(&draw_info->text," ");
+ (void) GetTypeMetrics(svg_info->image,draw_info,&metrics);
+ svg_info->bounds.x+=metrics.width;
+ DestroyDrawInfo(draw_info);
+ *svg_info->text='\0';
+ }
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if (attributes != (const xmlChar **) NULL)
+ for (i=0; (svg_info->exception->severity < ErrorException) &&
+ (attributes[i] != (const xmlChar *) NULL); i+=2)
+ {
+ keyword=(const char *) attributes[i];
+ value=(const char *) attributes[i+1];
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " %.1024s = %.1024s",keyword,value);
+ switch (*keyword)
+ {
+ case 'A':
+ case 'a':
+ {
+ if (LocaleCompare(keyword,"angle") == 0)
+ {
+ MVGPrintf(svg_info->file,"angle %g\n",
+ GetUserSpaceCoordinateValue(svg_info,0,value,MagickFalse));
+ break;
+ }
+ break;
+ }
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(keyword,"clip-path") == 0)
+ {
+ MVGPrintf(svg_info->file,"clip-path '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"clip-rule") == 0)
+ {
+ MVGPrintf(svg_info->file,"clip-rule '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"clipPathUnits") == 0)
+ {
+ (void) CloneString(&units,value);
+ MVGPrintf(svg_info->file,"clip-units '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"color") == 0)
+ {
+ (void) CloneString(&color,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"cx") == 0)
+ {
+ svg_info->element.cx=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"cy") == 0)
+ {
+ svg_info->element.cy=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare(keyword,"d") == 0)
+ {
+ (void) CloneString(&svg_info->vertices,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"dx") == 0)
+ {
+ svg_info->bounds.x+=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"dy") == 0)
+ {
+ svg_info->bounds.y+=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(keyword,"fill") == 0)
+ {
+ if (LocaleCompare(value,"currentColor") == 0)
+ {
+ MVGPrintf(svg_info->file,"fill '%s'\n",color);
+ break;
+ }
+ MVGPrintf(svg_info->file,"fill '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fillcolor") == 0)
+ {
+ MVGPrintf(svg_info->file,"fill '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fill-rule") == 0)
+ {
+ MVGPrintf(svg_info->file,"fill-rule '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fill-opacity") == 0)
+ {
+ MVGPrintf(svg_info->file,"fill-opacity '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-family") == 0)
+ {
+ /*
+ Deal with Adobe Illustrator 10.0 which double-quotes
+ font-family. Maybe we need a generalized solution for
+ this.
+ */
+ if ((value[0] == '\'') && (value[strlen(value)-1] == '\''))
+ {
+ char nvalue[MaxTextExtent];
+ (void) strlcpy(nvalue,value+1,sizeof(nvalue));
+ nvalue[strlen(nvalue)-1]='\0';
+ MVGPrintf(svg_info->file,"font-family '%s'\n",nvalue);
+ }
+ else
+ {
+ MVGPrintf(svg_info->file,"font-family '%s'\n",value);
+ }
+ break;
+ }
+ if (LocaleCompare(keyword,"font-stretch") == 0)
+ {
+ MVGPrintf(svg_info->file,"font-stretch '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-style") == 0)
+ {
+ MVGPrintf(svg_info->file,"font-style '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-size") == 0)
+ {
+ svg_info->pointsize=
+ GetUserSpaceCoordinateValue(svg_info,0,value,MagickTrue);
+ MVGPrintf(svg_info->file,"font-size %g\n",svg_info->pointsize);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-weight") == 0)
+ {
+ MVGPrintf(svg_info->file,"font-weight '%s'\n",value);
+ break;
+ }
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare(keyword,"gradientTransform") == 0)
+ {
+ char
+ **tokens;
+
+ AffineMatrix
+ affine,
+ current,
+ transform;
+
+ IdentityAffine(&transform);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," ");
+ tokens=GetTransformTokens(context,value,&number_tokens);
+ if ((tokens != (char **) NULL) && (number_tokens > 0))
+ {
+ for (j=0; j < (number_tokens-1); j+=2)
+ {
+ keyword=(char *) tokens[j];
+ if (keyword == (char *) NULL)
+ continue;
+ value=(char *) tokens[j+1];
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " %.1024s: %.1024s",keyword,value);
+ current=transform;
+ IdentityAffine(&affine);
+ switch (*keyword)
+ {
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare(keyword,"matrix") == 0)
+ {
+ p=(char *) value;
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.sx=MagickAtoF(value);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.rx=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.ry=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.sy=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.tx=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.ty=MagickAtoF(token);
+ break;
+ }
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"rotate") == 0)
+ {
+ double
+ angle;
+
+ angle=GetUserSpaceCoordinateValue(svg_info,0,value,MagickFalse);
+ affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"scale") == 0)
+ {
+ for (p=(char *) value; *p != '\0'; p++)
+ if (isspace((int) (*p)) || (*p == ','))
+ break;
+ affine.sx=GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ affine.sy=affine.sx;
+ if (*p != '\0')
+ affine.sy=
+ GetUserSpaceCoordinateValue(svg_info,-1,p+1,MagickFalse);
+ svg_info->scale[svg_info->n]=ExpandAffine(&affine);
+ break;
+ }
+ if (LocaleCompare(keyword,"skewX") == 0)
+ {
+ affine.sx=svg_info->affine.sx;
+ affine.ry=tan(DegreesToRadians(fmod(
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse),
+ 360.0)));
+ affine.sy=svg_info->affine.sy;
+ break;
+ }
+ if (LocaleCompare(keyword,"skewY") == 0)
+ {
+ affine.sx=svg_info->affine.sx;
+ affine.rx=tan(DegreesToRadians(fmod(
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse),
+ 360.0)));
+ affine.sy=svg_info->affine.sy;
+ break;
+ }
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare(keyword,"translate") == 0)
+ {
+ for (p=(char *) value; *p != '\0'; p++)
+ if (isspace((int) (*p)) || (*p == ','))
+ break;
+ affine.tx=GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ affine.ty=affine.tx;
+ if (*p != '\0')
+ affine.ty=
+ GetUserSpaceCoordinateValue(svg_info,-1,p+1,MagickFalse);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ } /* end switch */
+ transform.sx=current.sx*affine.sx+current.ry*affine.rx;
+ transform.rx=current.rx*affine.sx+current.sy*affine.rx;
+ transform.ry=current.sx*affine.ry+current.ry*affine.sy;
+ transform.sy=current.rx*affine.ry+current.sy*affine.sy;
+ transform.tx=current.sx*affine.tx+current.ry*affine.ty+
+ current.tx;
+ transform.ty=current.rx*affine.tx+current.sy*affine.ty+
+ current.ty;
+ } /* end for */
+ MVGPrintf(svg_info->file,"affine %g %g %g %g %g %g\n",
+ transform.sx,transform.rx,transform.ry,transform.sy,
+ transform.tx,transform.ty);
+ } /* end if */
+ if (tokens != (char **) NULL)
+ {
+ for (j=0; tokens[j] != (char *) NULL; j++)
+ MagickFreeMemory(tokens[j]);
+ MagickFreeMemory(tokens);
+ }
+ break;
+ }
+ if (LocaleCompare(keyword,"gradientUnits") == 0)
+ {
+ (void) CloneString(&units,value);
+ MVGPrintf(svg_info->file,"gradient-units '%s'\n",value);
+ break;
+ }
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ if (LocaleCompare(keyword,"height") == 0)
+ {
+ svg_info->bounds.height=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickTrue);
+ break;
+ }
+ if (LocaleCompare(keyword,"href") == 0)
+ {
+ (void) CloneString(&svg_info->url,value);
+ break;
+ }
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare(keyword,"major") == 0)
+ {
+ svg_info->element.major=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"minor") == 0)
+ {
+ svg_info->element.minor=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare(keyword,"offset") == 0)
+ {
+ (void) CloneString(&svg_info->offset,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"opacity") == 0)
+ {
+ MVGPrintf(svg_info->file,"opacity '%s'\n",value);
+ break;
+ }
+ break;
+ }
+ case 'P':
+ case 'p':
+ {
+ if (LocaleCompare(keyword,"path") == 0)
+ {
+ (void) CloneString(&svg_info->url,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"points") == 0)
+ {
+ (void) CloneString(&svg_info->vertices,value);
+ break;
+ }
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"r") == 0)
+ {
+ svg_info->element.major=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ svg_info->element.minor=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"rotate") == 0)
+ {
+ double
+ angle;
+
+ angle=GetUserSpaceCoordinateValue(svg_info,0,value,MagickFalse);
+ MVGPrintf(svg_info->file,"translate %g,%g\n",svg_info->bounds.x,
+ svg_info->bounds.y);
+ svg_info->bounds.x=0;
+ svg_info->bounds.y=0;
+ MVGPrintf(svg_info->file,"rotate %g\n",angle);
+ break;
+ }
+ if (LocaleCompare(keyword,"rx") == 0)
+ {
+ if (LocaleCompare((char *) name,"ellipse") == 0)
+ svg_info->element.major=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ else
+ svg_info->radius.x=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"ry") == 0)
+ {
+ if (LocaleCompare((char *) name,"ellipse") == 0)
+ svg_info->element.minor=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ else
+ svg_info->radius.y=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"stop-color") == 0)
+ {
+ (void) CloneString(&svg_info->stop_color,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke") == 0)
+ {
+ if (LocaleCompare(value,"currentColor") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke '%s'\n",color);
+ break;
+ }
+ MVGPrintf(svg_info->file,"stroke '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-antialiasing") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-antialias %d\n",
+ LocaleCompare(value,"true") == 0);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-dasharray") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-dasharray %s\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-dashoffset") == 0)
+ {
+ double dashoffset=GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ MVGPrintf(svg_info->file,"stroke-dashoffset %g\n",dashoffset);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-linecap") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-linecap '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-linejoin") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-linejoin '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-miterlimit") == 0)
+ {
+ double stroke_miterlimit;
+ if ((MagickAtoFChk(value,&stroke_miterlimit) != MagickPass) ||
+ stroke_miterlimit < 1.0)
+ {
+ errno=0;
+ ThrowException(svg_info->exception,DrawError,InvalidPrimitiveArgument,
+ value);
+ break;
+ }
+ MVGPrintf(svg_info->file,"stroke-miterlimit '%ld'\n",
+ (long) stroke_miterlimit);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-opacity") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-opacity '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-width") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-width %g\n",
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickTrue));
+ break;
+ }
+ if (LocaleCompare(keyword,"style") == 0)
+ {
+ char
+ **tokens;
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," ");
+ tokens=GetStyleTokens(context,value,&number_tokens);
+ if ((tokens != (char **) NULL) && (number_tokens > 0))
+ {
+ for (j=0; j < (number_tokens-1); j+=2)
+ {
+ keyword=(char *) tokens[j];
+ value=(char *) tokens[j+1];
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " %.1024s: %.1024s",keyword,value);
+ switch (*keyword)
+ {
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(keyword,"clip-path") == 0)
+ {
+ MVGPrintf(svg_info->file,"clip-path '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"clip-rule") == 0)
+ {
+ MVGPrintf(svg_info->file,"clip-rule '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"clipPathUnits") == 0)
+ {
+ (void) CloneString(&units,value);
+ MVGPrintf(svg_info->file,"clip-units '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"color") == 0)
+ {
+ (void) CloneString(&color,value);
+ break;
+ }
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(keyword,"fill") == 0)
+ {
+ if (LocaleCompare(value,"currentColor") == 0)
+ {
+ MVGPrintf(svg_info->file,"fill '%s'\n",color);
+ break;
+ }
+ MVGPrintf(svg_info->file,"fill '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fillcolor") == 0)
+ {
+ MVGPrintf(svg_info->file,"fill '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fill-rule") == 0)
+ {
+ MVGPrintf(svg_info->file,"fill-rule '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fill-opacity") == 0)
+ {
+ MVGPrintf(svg_info->file,"fill-opacity '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-family") == 0)
+ {
+ MVGPrintf(svg_info->file,"font-family '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-stretch") == 0)
+ {
+ MVGPrintf(svg_info->file,"font-stretch '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-style") == 0)
+ {
+ MVGPrintf(svg_info->file,"font-style '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-size") == 0)
+ {
+ if (LocaleCompare(value,"medium") == 0)
+ svg_info->pointsize=12;
+ else
+ svg_info->pointsize=
+ GetUserSpaceCoordinateValue(svg_info,0,value,MagickTrue);
+ MVGPrintf(svg_info->file,"font-size %g\n",
+ svg_info->pointsize);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-weight") == 0)
+ {
+ MVGPrintf(svg_info->file,"font-weight '%s'\n",value);
+ break;
+ }
+ break;
+ }
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare(keyword,"offset") == 0)
+ {
+ MVGPrintf(svg_info->file,"offset %g\n",
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse));
+ break;
+ }
+ if (LocaleCompare(keyword,"opacity") == 0)
+ {
+ MVGPrintf(svg_info->file,"opacity '%s'\n",value);
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"stop-color") == 0)
+ {
+ (void) CloneString(&svg_info->stop_color,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke") == 0)
+ {
+ if (LocaleCompare(value,"currentColor") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke '%s'\n",color);
+ break;
+ }
+ MVGPrintf(svg_info->file,"stroke '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-antialiasing") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-antialias %d\n",
+ LocaleCompare(value,"true") == 0);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-dasharray") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-dasharray %s\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-dashoffset") == 0)
+ {
+ double dashoffset=GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ MVGPrintf(svg_info->file,"stroke-dashoffset %g\n",dashoffset);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-linecap") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-linecap '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-linejoin") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-linejoin '%s'\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-miterlimit") == 0)
+ {
+ double stroke_miterlimit;
+ if ((MagickAtoFChk(value,&stroke_miterlimit) != MagickPass) ||
+ stroke_miterlimit < 1.0)
+ {
+ errno=0;
+ ThrowException(svg_info->exception,DrawError,InvalidPrimitiveArgument,
+ value);
+ break;
+ }
+ MVGPrintf(svg_info->file,"stroke-miterlimit '%ld'\n",
+ (long) stroke_miterlimit);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-opacity") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-opacity '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-width") == 0)
+ {
+ MVGPrintf(svg_info->file,"stroke-width %g\n",
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickTrue));
+ break;
+ }
+ break;
+ }
+ case 't':
+ case 'T':
+ {
+ if (LocaleCompare(keyword,"text-align") == 0)
+ {
+ MVGPrintf(svg_info->file,"text-align '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"text-anchor") == 0)
+ {
+ MVGPrintf(svg_info->file,"text-anchor '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"text-decoration") == 0)
+ {
+ if (LocaleCompare(value,"underline") == 0)
+ MVGPrintf(svg_info->file,"decorate underline\n");
+ if (LocaleCompare(value,"line-through") == 0)
+ MVGPrintf(svg_info->file,"decorate line-through\n");
+ if (LocaleCompare(value,"overline") == 0)
+ MVGPrintf(svg_info->file,"decorate overline\n");
+ break;
+ }
+ if (LocaleCompare(keyword,"text-antialiasing") == 0)
+ {
+ MVGPrintf(svg_info->file,"text-antialias %d\n",
+ LocaleCompare(value,"true") == 0);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ if (tokens != (char **) NULL)
+ {
+ for (j=0; tokens[j] != (char *) NULL; j++)
+ MagickFreeMemory(tokens[j]);
+ MagickFreeMemory(tokens);
+ }
+ break;
+ }
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare(keyword,"text-align") == 0)
+ {
+ MVGPrintf(svg_info->file,"text-align '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"text-anchor") == 0)
+ {
+ MVGPrintf(svg_info->file,"text-anchor '%s'\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"text-decoration") == 0)
+ {
+ if (LocaleCompare(value,"underline") == 0)
+ MVGPrintf(svg_info->file,"decorate underline\n");
+ if (LocaleCompare(value,"line-through") == 0)
+ MVGPrintf(svg_info->file,"decorate line-through\n");
+ if (LocaleCompare(value,"overline") == 0)
+ MVGPrintf(svg_info->file,"decorate overline\n");
+ break;
+ }
+ if (LocaleCompare(keyword,"text-antialiasing") == 0)
+ {
+ MVGPrintf(svg_info->file,"text-antialias %d\n",
+ LocaleCompare(value,"true") == 0);
+ break;
+ }
+ if (LocaleCompare(keyword,"transform") == 0)
+ {
+ char
+ **tokens;
+
+ AffineMatrix
+ affine,
+ current,
+ transform;
+
+ IdentityAffine(&transform);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," ");
+ tokens=GetTransformTokens(context,value,&number_tokens);
+ if ((tokens != (char **) NULL) && (number_tokens > 0))
+ {
+ for (j=0; j < (number_tokens-1); j+=2)
+ {
+ keyword=(char *) tokens[j];
+ value=(char *) tokens[j+1];
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " %.1024s: %.1024s",keyword,value);
+ current=transform;
+ IdentityAffine(&affine);
+ switch (*keyword)
+ {
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare(keyword,"matrix") == 0)
+ {
+ p=(char *) value;
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.sx=MagickAtoF(value);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.rx=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.ry=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.sy=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.tx=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ affine.ty=MagickAtoF(token);
+ break;
+ }
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare(keyword,"rotate") == 0)
+ {
+ double
+ angle;
+
+ angle=GetUserSpaceCoordinateValue(svg_info,0,value,MagickFalse);
+ affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"scale") == 0)
+ {
+ for (p=(char *) value; *p != '\0'; p++)
+ if (isspace((int) (*p)) || (*p == ','))
+ break;
+ affine.sx=GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ affine.sy=affine.sx;
+ if (*p != '\0')
+ affine.sy=
+ GetUserSpaceCoordinateValue(svg_info,-1,p+1,MagickFalse);
+ svg_info->scale[svg_info->n]=ExpandAffine(&affine);
+ break;
+ }
+ if (LocaleCompare(keyword,"skewX") == 0)
+ {
+ affine.sx=svg_info->affine.sx;
+ affine.ry=tan(DegreesToRadians(fmod(
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse),
+ 360.0)));
+ affine.sy=svg_info->affine.sy;
+ break;
+ }
+ if (LocaleCompare(keyword,"skewY") == 0)
+ {
+ affine.sx=svg_info->affine.sx;
+ affine.rx=tan(DegreesToRadians(fmod(
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse),
+ 360.0)));
+ affine.sy=svg_info->affine.sy;
+ break;
+ }
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare(keyword,"translate") == 0)
+ {
+ for (p=(char *) value; *p != '\0'; p++)
+ if (isspace((int) (*p)) || (*p == ','))
+ break;
+ affine.tx=GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ affine.ty=affine.tx;
+ if (*p != '\0')
+ affine.ty=
+ GetUserSpaceCoordinateValue(svg_info,-1,p+1,MagickFalse);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ transform.sx=current.sx*affine.sx+current.ry*affine.rx;
+ transform.rx=current.rx*affine.sx+current.sy*affine.rx;
+ transform.ry=current.sx*affine.ry+current.ry*affine.sy;
+ transform.sy=current.rx*affine.ry+current.sy*affine.sy;
+ transform.tx=current.sx*affine.tx+current.ry*affine.ty+
+ current.tx;
+ transform.ty=current.rx*affine.tx+current.sy*affine.ty+
+ current.ty;
+ }
+ MVGPrintf(svg_info->file,"affine %g %g %g %g %g %g\n",
+ transform.sx,transform.rx,transform.ry,transform.sy,
+ transform.tx,transform.ty);
+ } /* if ((tokens != (char **) NULL) && (number_tokens > 0)) */
+ if (tokens != (char **) NULL)
+ {
+ for (j=0; tokens[j] != (char *) NULL; j++)
+ MagickFreeMemory(tokens[j]);
+ MagickFreeMemory(tokens);
+ }
+ break;
+ }
+ break;
+ }
+ case 'V':
+ case 'v':
+ {
+ if (LocaleCompare(keyword,"verts") == 0)
+ {
+ (void) CloneString(&svg_info->vertices,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"viewBox") == 0)
+ {
+ p=(char *) value;
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ svg_info->view_box.x=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ svg_info->view_box.y=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ svg_info->view_box.width=MagickAtoF(token);
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ svg_info->view_box.height=MagickAtoF(token);
+ if (svg_info->view_box.width < 0.0 ||
+ svg_info->view_box.height < 0.0)
+ {
+ ThrowException(svg_info->exception,CorruptImageError,
+ NegativeOrZeroImageSize,
+ svg_info->image->filename);
+ goto svg_start_element_error;
+ }
+ if (svg_info->bounds.width == 0)
+ svg_info->bounds.width=svg_info->view_box.width;
+ if (svg_info->bounds.height == 0)
+ svg_info->bounds.height=svg_info->view_box.height;
+ break;
+ }
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare(keyword,"width") == 0)
+ {
+ svg_info->bounds.width=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickTrue);
+ break;
+ }
+ break;
+ }
+ case 'X':
+ case 'x':
+ {
+ if (LocaleCompare(keyword,"x") == 0)
+ {
+ svg_info->bounds.x=GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"xlink:href") == 0)
+ {
+ (void) CloneString(&svg_info->url,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"x1") == 0)
+ {
+ svg_info->segment.x1=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"x2") == 0)
+ {
+ svg_info->segment.x2=
+ GetUserSpaceCoordinateValue(svg_info,1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ case 'Y':
+ case 'y':
+ {
+ if (LocaleCompare(keyword,"y") == 0)
+ {
+ svg_info->bounds.y=GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"y1") == 0)
+ {
+ svg_info->segment.y1=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ if (LocaleCompare(keyword,"y2") == 0)
+ {
+ svg_info->segment.y2=
+ GetUserSpaceCoordinateValue(svg_info,-1,value,MagickFalse);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (svg_info->exception->severity >= ErrorException)
+ goto svg_start_element_error;
+#ifdef BROKEN_SIZE_OPTION
+ if (LocaleCompare((char *) name,"svg") == 0)
+ {
+ if (svg_info->document->encoding != (const xmlChar *) NULL)
+ MVGPrintf(svg_info->file,"encoding %.1024s\n",
+ (char *) svg_info->document->encoding);
+ if (attributes != (const xmlChar **) NULL)
+ {
+ double
+ sx,
+ sy;
+
+ if ((svg_info->view_box.width == 0.0) ||
+ (svg_info->view_box.height == 0.0))
+ svg_info->view_box=svg_info->bounds;
+ svg_info->width=(unsigned long) svg_info->bounds.width;
+ svg_info->height=(unsigned long) svg_info->bounds.height;
+ MVGPrintf(svg_info->file,"viewbox 0 0 %lu %lu\n",svg_info->width,
+ svg_info->height);
+ /*
+ Set initial canvas background color to user specified value
+ */
+ {
+ char
+ tuple[MaxTextExtent];
+
+ GetColorTuple(&svg_info->image_info->background_color,8,True,True,
+ tuple);
+
+ MVGPrintf(svg_info->file,"push graphic-context\n");
+ MVGPrintf(svg_info->file,"fill %s\n", tuple);
+ MVGPrintf(svg_info->file,"rectangle 0,0 %g,%g\n",
+ svg_info->view_box.width,svg_info->view_box.height);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ }
+ sx=(double) svg_info->width/svg_info->view_box.width;
+ sy=(double) svg_info->height/svg_info->view_box.height;
+ MVGPrintf(svg_info->file,"affine %g 0 0 %g %g %g\n",sx,sy,
+ -sx*svg_info->view_box.x,-sy*svg_info->view_box.y);
+ }
+ }
+#else
+ if (LocaleCompare((char *) name,"svg") == 0)
+ {
+ if (svg_info->document->encoding != (const xmlChar *) NULL)
+ (void) fprintf(svg_info->file,"encoding %.1024s\n",
+ (char *) svg_info->document->encoding);
+ if (attributes != (const xmlChar **) NULL)
+ {
+ char
+ *geometry,
+ *p;
+
+ RectangleInfo
+ page;
+
+ double
+ sx,
+ sy;
+
+ if (svg_info->bounds.width < 0.0 || svg_info->bounds.height < 0.0)
+ {
+ ThrowException(svg_info->exception,CorruptImageError,
+ NegativeOrZeroImageSize,(char *) NULL);
+ goto svg_start_element_error;
+ }
+ if ((svg_info->view_box.width == 0.0) ||
+ (svg_info->view_box.height == 0.0))
+ svg_info->view_box=svg_info->bounds;
+ if (svg_info->view_box.width < 0.0 || svg_info->view_box.height < 0.0)
+ {
+ ThrowException(svg_info->exception,CorruptImageError,
+ NegativeOrZeroImageSize,(char *) NULL);
+ goto svg_start_element_error;
+ }
+ SetGeometry(svg_info->image,&page);
+ page.width=(unsigned long) svg_info->bounds.width;
+ page.height=(unsigned long) svg_info->bounds.height;
+ geometry=(char *) NULL;
+ /* at one point we use to try to use either page geometry
+ or size to set the dimensions of the output page, but
+ now we only look for size
+ */
+#ifdef PARSE_PAGE_FIRST
+ if (svg_info->page != (char *) NULL)
+ geometry=GetPageGeometry(svg_info->page);
+ else
+#endif
+ if (svg_info->size != (char *) NULL)
+ geometry=GetPageGeometry(svg_info->size);
+ if (geometry != (char *) NULL)
+ {
+ p=strchr(geometry,'>');
+ if (p != (char *) NULL)
+ *p='\0';
+ (void) GetMagickGeometry(geometry,&page.x,&page.y,
+ &page.width,&page.height);
+ MagickFreeMemory(geometry);
+ }
+ if (svg_info->affine.sx != 1.0)
+ page.width=(unsigned long)
+ ceil(ExpandAffine(&svg_info->affine)*page.width-0.5);
+ if (svg_info->affine.sy != 0.0)
+ page.height=(unsigned long)
+ ceil(ExpandAffine(&svg_info->affine)*page.height-0.5);
+ (void) MVGPrintf(svg_info->file,"viewbox 0 0 %g %g\n",
+ svg_info->view_box.width,svg_info->view_box.height);
+ sx=(double) page.width/svg_info->view_box.width;
+ sy=(double) page.height/svg_info->view_box.height;
+ MVGPrintf(svg_info->file,"affine %g 0 0 %g %g %g\n",sx,sy,
+ -sx*svg_info->view_box.x,-sy*svg_info->view_box.y);
+ svg_info->width=page.width;
+ svg_info->height=page.height;
+ }
+ }
+#endif
+ /* Error dispatch point */
+ svg_start_element_error:;
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
+ MagickFreeMemory(units);
+ MagickFreeMemory(color);
+}
+
+static void
+SVGEndElement(void *context,const xmlChar *name)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ Called when the end of an element has been detected.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.endElement(%.1024s)",name);
+ svg_info=(SVGInfo *) context;
+ if (strchr((char *) name,':') != (char *) NULL)
+ {
+ /*
+ Skip over namespace.
+ */
+ for ( ; *name != ':'; name++) ;
+ name++;
+ }
+ switch (*name)
+ {
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare((char *) name,"circle") == 0)
+ {
+ MVGPrintf(svg_info->file,"circle %g,%g %g,%g\n",svg_info->element.cx,
+ svg_info->element.cy,svg_info->element.cx,svg_info->element.cy+
+ svg_info->element.minor);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"clipPath") == 0)
+ {
+ MVGPrintf(svg_info->file,"pop clip-path\n");
+ break;
+ }
+ break;
+ }
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare((char *) name,"defs") == 0)
+ {
+ MVGPrintf(svg_info->file,"pop defs\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"desc") == 0)
+ {
+ register char
+ *p;
+
+ Strip(svg_info->text);
+ if (*svg_info->text == '\0')
+ break;
+ (void) fputc('#',svg_info->file);
+ for (p=svg_info->text; *p != '\0'; p++)
+ {
+ (void) fputc(*p,svg_info->file);
+ if (*p == '\n')
+ (void) fputc('#',svg_info->file);
+ }
+ (void) fputc('\n',svg_info->file);
+ *svg_info->text='\0';
+ break;
+ }
+ break;
+ }
+ case 'E':
+ case 'e':
+ {
+ if (LocaleCompare((char *) name,"ellipse") == 0)
+ {
+ double
+ angle;
+
+ angle=svg_info->element.angle;
+ MVGPrintf(svg_info->file,"ellipse %g,%g %g,%g 0,360\n",
+ svg_info->element.cx,svg_info->element.cy,
+ angle == 0.0 ? svg_info->element.major : svg_info->element.minor,
+ angle == 0.0 ? svg_info->element.minor : svg_info->element.major);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare((char *) name,"g") == 0)
+ {
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'I':
+ case 'i':
+ {
+ if (LocaleCompare((char *) name,"image") == 0)
+ {
+ MVGPrintf(svg_info->file,"image Copy %g,%g %g,%g '%s'\n",
+ svg_info->bounds.x,svg_info->bounds.y,svg_info->bounds.width,
+ svg_info->bounds.height,svg_info->url);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'L':
+ case 'l':
+ {
+ if (LocaleCompare((char *) name,"line") == 0)
+ {
+ MVGPrintf(svg_info->file,"line %g,%g %g,%g\n",svg_info->segment.x1,
+ svg_info->segment.y1,svg_info->segment.x2,svg_info->segment.y2);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"linearGradient") == 0)
+ {
+ MVGPrintf(svg_info->file,"pop gradient\n");
+ break;
+ }
+ break;
+ }
+ case 'P':
+ case 'p':
+ {
+ if (LocaleCompare((char *) name,"pattern") == 0)
+ {
+ MVGPrintf(svg_info->file,"pop pattern\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"path") == 0)
+ {
+ MVGPrintf(svg_info->file,"path '%s'\n",svg_info->vertices);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"polygon") == 0)
+ {
+ MVGPrintf(svg_info->file,"polygon %s\n",svg_info->vertices);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"polyline") == 0)
+ {
+ MVGPrintf(svg_info->file,"polyline %s\n",svg_info->vertices);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare((char *) name,"radialGradient") == 0)
+ {
+ MVGPrintf(svg_info->file,"pop gradient\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"rect") == 0)
+ {
+ if ((svg_info->radius.x == 0.0) && (svg_info->radius.y == 0.0))
+ {
+ MVGPrintf(svg_info->file,"rectangle %g,%g %g,%g\n",
+ svg_info->bounds.x,svg_info->bounds.y,
+ svg_info->bounds.x+svg_info->bounds.width,
+ svg_info->bounds.y+svg_info->bounds.height);
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ if (svg_info->radius.x == 0.0)
+ svg_info->radius.x=svg_info->radius.y;
+ if (svg_info->radius.y == 0.0)
+ svg_info->radius.y=svg_info->radius.x;
+ MVGPrintf(svg_info->file,"roundRectangle %g,%g %g,%g %g,%g\n",
+ svg_info->bounds.x,svg_info->bounds.y,svg_info->bounds.x+
+ svg_info->bounds.width,svg_info->bounds.y+svg_info->bounds.height,
+ svg_info->radius.x,svg_info->radius.y);
+ svg_info->radius.x=0.0;
+ svg_info->radius.y=0.0;
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare((char *) name,"stop") == 0)
+ {
+ MVGPrintf(svg_info->file,"stop-color '%s' %s\n",svg_info->stop_color,
+ svg_info->offset);
+ break;
+ }
+ if (LocaleCompare((char *) name,"svg") == 0)
+ {
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ break;
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare((char *) name,"text") == 0)
+ {
+ Strip(svg_info->text);
+ if (*svg_info->text != '\0')
+ {
+ char
+ *text;
+
+ text=EscapeString(svg_info->text,'\'');
+ MVGPrintf(svg_info->file,"text %g,%g '%s'\n",svg_info->bounds.x,
+ svg_info->bounds.y,text);
+ MagickFreeMemory(text);
+ *svg_info->text='\0';
+ }
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"tspan") == 0)
+ {
+ Strip(svg_info->text);
+ if (*svg_info->text != '\0')
+ {
+ DrawInfo
+ *draw_info;
+
+ TypeMetric
+ metrics;
+
+ char
+ *text;
+
+ text=EscapeString(svg_info->text,'\'');
+ MVGPrintf(svg_info->file,"text %g,%g '%s'\n",svg_info->bounds.x,
+ svg_info->bounds.y,text);
+ MagickFreeMemory(text);
+ draw_info=CloneDrawInfo(svg_info->image_info,(DrawInfo *) NULL);
+ draw_info->pointsize=svg_info->pointsize;
+ draw_info->text=AllocateString(svg_info->text);
+ (void) ConcatenateString(&draw_info->text," ");
+ (void) GetTypeMetrics(svg_info->image,draw_info,&metrics);
+ svg_info->bounds.x+=metrics.width;
+ DestroyDrawInfo(draw_info);
+ *svg_info->text='\0';
+ }
+ MVGPrintf(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ if (LocaleCompare((char *) name,"title") == 0)
+ {
+ Strip(svg_info->text);
+ if (*svg_info->text == '\0')
+ break;
+ (void) CloneString(&svg_info->title,svg_info->text);
+ *svg_info->text='\0';
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ (void) memset(&svg_info->segment,0,sizeof(svg_info->segment));
+ (void) memset(&svg_info->element,0,sizeof(svg_info->element));
+ *svg_info->text='\0';
+ svg_info->n--;
+}
+
+static void
+SVGCharacters(void *context,const xmlChar *c,int length)
+{
+ register char
+ *p;
+
+ register size_t
+ i;
+
+ SVGInfo
+ *svg_info;
+
+ /*
+ Receiving some characters from the parser.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.characters(%.1024s,%d)",c,length);
+ svg_info=(SVGInfo *) context;
+ if (svg_info->text != (char *) NULL)
+ {
+ MagickReallocMemory(char *,svg_info->text,strlen(svg_info->text)+length+1);
+ }
+ else
+ {
+ svg_info->text=MagickAllocateMemory(char *,(size_t) length+1);
+ if (svg_info->text != (char *) NULL)
+ *svg_info->text='\0';
+ }
+ if (svg_info->text == (char *) NULL)
+ return;
+ p=svg_info->text+strlen(svg_info->text);
+ for (i=0; i < (size_t) length; i++)
+ *p++=c[i];
+ *p='\0';
+}
+
+static void
+SVGReference(void *context,const xmlChar *name)
+{
+ SVGInfo
+ *svg_info;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ Called when an entity reference is detected.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.reference(%.1024s)",name);
+ svg_info=(SVGInfo *) context;
+ parser=svg_info->parser;
+ if (*name == '#')
+ (void) xmlAddChild(parser->node,xmlNewCharRef(svg_info->document,name));
+ else
+ (void) xmlAddChild(parser->node,xmlNewReference(svg_info->document,name));
+}
+
+static void
+SVGIgnorableWhitespace(void *context,const xmlChar *c,int length)
+{
+ /* SVGInfo */
+ /* *svg_info; */
+
+ ARG_NOT_USED(context);
+ /*
+ Receiving some ignorable whitespaces from the parser.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.ignorableWhitespace(%.30s, %d)",c,length);
+ /* svg_info=(SVGInfo *) context; */
+}
+
+static void
+SVGProcessingInstructions(void *context,const xmlChar *target,
+ const xmlChar *data)
+{
+ /* SVGInfo */
+ /* *svg_info; */
+
+ ARG_NOT_USED(context);
+ /*
+ A processing instruction has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.processingInstruction(%.1024s, %.1024s)",
+ target,data);
+ /* svg_info=(SVGInfo *) context; */
+}
+
+static void
+SVGComment(void *context,const xmlChar *value)
+{
+ SVGInfo
+ *svg_info;
+
+ /*
+ A comment has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.comment(%.1024s)",value);
+ svg_info=(SVGInfo *) context;
+ if (svg_info->comment != (char *) NULL)
+ (void) ConcatenateString(&svg_info->comment,"\n");
+ (void) ConcatenateString(&svg_info->comment,(char *) value);
+}
+
+static void
+SVGWarning(void *context,const char *format,...)
+{
+ char
+ reason[MaxTextExtent];
+
+ SVGInfo
+ *svg_info;
+
+ va_list
+ operands;
+
+ /**
+ Display and format a warning messages, gives file, line, position and
+ extra parameters.
+ */
+ va_start(operands,format);
+ svg_info=(SVGInfo *) context;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
+#if !defined(HAVE_VSNPRINTF)
+ (void) vsprintf(reason,format,operands);
+#else
+ (void) vsnprintf(reason,MaxTextExtent,format,operands);
+#endif
+ ThrowException2(svg_info->exception,CoderWarning,reason,(char *) NULL);
+ va_end(operands);
+}
+
+static void
+SVGError(void *context,const char *format,...)
+{
+ char
+ reason[MaxTextExtent];
+
+ SVGInfo
+ *svg_info;
+
+ va_list
+ operands;
+
+ /*
+ Display and format a error formats, gives file, line, position and
+ extra parameters.
+ */
+ va_start(operands,format);
+ svg_info=(SVGInfo *) context;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
+#if !defined(HAVE_VSNPRINTF)
+ (void) vsprintf(reason,format,operands);
+#else
+ (void) vsnprintf(reason,MaxTextExtent,format,operands);
+#endif
+ ThrowException2(svg_info->exception,CoderError,reason,(char *) NULL);
+ va_end(operands);
+}
+
+static void
+SVGCDataBlock(void *context,const xmlChar *value,int length)
+{
+ SVGInfo
+ *svg_info;
+
+ xmlNodePtr
+ child;
+
+ xmlParserCtxtPtr
+ parser;
+
+ /*
+ Called when a pcdata block has been parsed.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.pcdata(%.1024s, %d)",value,length);
+ svg_info=(SVGInfo *) context;
+ parser=svg_info->parser;
+ child=xmlGetLastChild(parser->node);
+ if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
+ {
+ (void) xmlTextConcat(child,value,length);
+ return;
+ }
+ (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
+}
+
+static void
+SVGExternalSubset(void *context,const xmlChar *name,
+ const xmlChar *external_id,const xmlChar *system_id)
+{
+ SVGInfo
+ *svg_info;
+
+ xmlParserCtxt
+ parser_context;
+
+ xmlParserCtxtPtr
+ parser;
+
+ xmlParserInputPtr
+ input;
+
+ /*
+ Does this document has an external subset?
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " SAX.externalSubset(%.1024s, %.1024s, %.1024s)",name,
+ (external_id != (const xmlChar *) NULL ? (char *) external_id : "none"),
+ (system_id != (const xmlChar *) NULL ? (char *) system_id : "none"));
+ svg_info=(SVGInfo *) context;
+ parser=svg_info->parser;
+ if (((external_id == NULL) && (system_id == NULL)) ||
+ (!parser->validate || !parser->wellFormed || !svg_info->document))
+ return;
+ input=SVGResolveEntity(context,external_id,system_id);
+ if (input == NULL)
+ return;
+ (void) xmlNewDtd(svg_info->document,name,external_id,system_id);
+ parser_context=(*parser);
+ parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
+ if (parser->inputTab == (xmlParserInputPtr *) NULL)
+ {
+ parser->errNo=XML_ERR_NO_MEMORY;
+ parser->input=parser_context.input;
+ parser->inputNr=parser_context.inputNr;
+ parser->inputMax=parser_context.inputMax;
+ parser->inputTab=parser_context.inputTab;
+ return;
+ }
+ parser->inputNr=0;
+ parser->inputMax=5;
+ parser->input=NULL;
+ xmlPushInput(parser,input);
+ (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
+ if (input->filename == (char *) NULL)
+ input->filename=(char *) xmlStrdup(system_id);
+ input->line=1;
+ input->col=1;
+ input->base=parser->input->cur;
+ input->cur=parser->input->cur;
+ input->free=NULL;
+ xmlParseExternalSubset(parser,external_id,system_id);
+ while (parser->inputNr > 1)
+ (void) xmlPopInput(parser);
+ xmlFreeInputStream(parser->input);
+ xmlFree(parser->inputTab);
+ parser->input=parser_context.input;
+ parser->inputNr=parser_context.inputNr;
+ parser->inputMax=parser_context.inputMax;
+ parser->inputTab=parser_context.inputTab;
+}
+
+static Image *
+ReadSVGImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ xmlSAXHandler
+ SAXModules;
+
+ char
+ filename[MaxTextExtent],
+ geometry[MaxTextExtent],
+ message[MaxTextExtent];
+
+ FILE
+ *file;
+
+ Image
+ *image;
+
+ size_t
+ n;
+
+ SVGInfo
+ svg_info;
+
+ unsigned int
+ status;
+
+ xmlSAXHandlerPtr
+ SAXHandler;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Open draw file.
+ */
+ file=AcquireTemporaryFileStream(filename,TextFileIOMode);
+ if (file == (FILE *) NULL)
+ ThrowReaderTemporaryFileException(filename);
+ /*
+ Parse SVG file.
+ */
+ (void) memset(&svg_info,0,sizeof(SVGInfo));
+ svg_info.file=file;
+ svg_info.exception=exception;
+ svg_info.image=image;
+ svg_info.image_info=image_info;
+ svg_info.text=AllocateString("");
+ svg_info.scale=MagickAllocateMemory(double *,sizeof(double));
+ if ((svg_info.text == (char *) NULL) || (svg_info.scale == (double *) NULL))
+ {
+ (void) fclose(file);
+ (void) LiberateTemporaryFile(filename);
+ MagickFreeMemory(svg_info.text);
+ MagickFreeMemory(svg_info.scale);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ }
+ IdentityAffine(&svg_info.affine);
+ svg_info.affine.sx=
+ image->x_resolution == 0.0 ? 1.0 : image->x_resolution/72.0;
+ svg_info.affine.sy=
+ image->y_resolution == 0.0 ? 1.0 : image->y_resolution/72.0;
+ svg_info.scale[0]=ExpandAffine(&svg_info.affine);
+ svg_info.bounds.width=image->columns;
+ svg_info.bounds.height=image->rows;
+ if (image_info->size != (char *) NULL)
+ (void) CloneString(&svg_info.size,image_info->size);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"begin SAX");
+ (void) xmlSubstituteEntitiesDefault(1);
+
+ (void) memset(&SAXModules,0,sizeof(SAXModules));
+ SAXModules.internalSubset=SVGInternalSubset;
+ SAXModules.isStandalone=SVGIsStandalone;
+ SAXModules.hasInternalSubset=SVGHasInternalSubset;
+ SAXModules.hasExternalSubset=SVGHasExternalSubset;
+ SAXModules.resolveEntity=SVGResolveEntity;
+ SAXModules.getEntity=SVGGetEntity;
+ SAXModules.entityDecl=SVGEntityDeclaration;
+ SAXModules.notationDecl=SVGNotationDeclaration;
+ SAXModules.attributeDecl=SVGAttributeDeclaration;
+ SAXModules.elementDecl=SVGElementDeclaration;
+ SAXModules.unparsedEntityDecl=SVGUnparsedEntityDeclaration;
+ SAXModules.setDocumentLocator=SVGSetDocumentLocator;
+ SAXModules.startDocument=SVGStartDocument;
+ SAXModules.endDocument=SVGEndDocument;
+ SAXModules.startElement=SVGStartElement;
+ SAXModules.endElement=SVGEndElement;
+ SAXModules.reference=SVGReference;
+ SAXModules.characters=SVGCharacters;
+ SAXModules.ignorableWhitespace=SVGIgnorableWhitespace;
+ SAXModules.processingInstruction=SVGProcessingInstructions;
+ SAXModules.comment=SVGComment;
+ SAXModules.warning=SVGWarning;
+ SAXModules.error=SVGError;
+ SAXModules.fatalError=SVGError;
+ SAXModules.getParameterEntity=SVGGetParameterEntity;
+ SAXModules.cdataBlock=SVGCDataBlock;
+ SAXModules.externalSubset=SVGExternalSubset;
+
+ SAXHandler=(&SAXModules);
+ svg_info.parser=xmlCreatePushParserCtxt(SAXHandler,&svg_info,(char *) NULL,0,
+ image->filename);
+ while ((n=ReadBlob(image,MaxTextExtent-1,message)) != 0)
+ {
+ message[n]='\0';
+ status=xmlParseChunk(svg_info.parser,message,(int) n,False);
+ if (status != 0)
+ break;
+ }
+ (void) xmlParseChunk(svg_info.parser,message,0,True);
+ /*
+ Assure that our private context is freed, even if we abort before
+ seeing the document end.
+ */
+ SVGEndDocument(&svg_info);
+ xmlFreeParserCtxt(svg_info.parser);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
+ xmlCleanupParser();
+ (void) fclose(file);
+ CloseBlob(image);
+ DestroyImage(image);
+ image=(Image *) NULL;
+ if (!image_info->ping && (exception->severity == UndefinedException))
+ {
+ ImageInfo
+ *clone_info;
+
+ /*
+ Draw image.
+ */
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(_BlobInfoPtr_) NULL;
+ clone_info->length=0;
+ FormatString(geometry,"%ldx%ld",svg_info.width,svg_info.height);
+ (void) CloneString(&clone_info->size,geometry);
+ FormatString(clone_info->filename,"mvg:%.1024s",filename);
+ if (clone_info->density != (char *) NULL)
+ MagickFreeMemory(clone_info->density);
+ image=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ if (image != (Image *) NULL)
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ }
+ /*
+ Free resources.
+ */
+ MagickFreeMemory(svg_info.size);
+ if (svg_info.title != (char *) NULL)
+ {
+ if (image != (Image *) NULL)
+ (void) SetImageAttribute(image,"title",svg_info.title);
+ MagickFreeMemory(svg_info.title);
+ }
+ if (svg_info.comment != (char *) NULL)
+ {
+ if (image != (Image *) NULL)
+ (void) SetImageAttribute(image,"comment",svg_info.comment);
+ MagickFreeMemory(svg_info.comment);
+ }
+
+ (void) memset(&svg_info,0xbf,sizeof(SVGInfo));
+ (void) LiberateTemporaryFile(filename);
+ return(image);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r S V G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterSVGImage adds attributes for the SVG image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterSVGImage method is:
+%
+% RegisterSVGImage(void)
+%
+*/
+ModuleExport void
+RegisterSVGImage(void)
+{
+ static char
+ version[MaxTextExtent];
+
+ MagickInfo
+ *entry;
+
+ *version='\0';
+#if defined(LIBXML_DOTTED_VERSION)
+ (void) strlcpy(version,"XML " LIBXML_DOTTED_VERSION,MaxTextExtent);
+#endif /* defined(LIBXML_DOTTED_VERSION) */
+
+ entry=SetMagickInfo("SVG");
+#if defined(HasXML)
+ entry->decoder=(DecoderHandler) ReadSVGImage;
+#endif /* defined(HasXML) */
+#if ENABLE_SVG_WRITER
+ entry->encoder=(EncoderHandler) WriteSVGImage;
+#endif /* if ENABLE_SVG_WRITER */
+ entry->description="Scalable Vector Graphics";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="SVG";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("SVGZ");
+#if defined(HasXML)
+ entry->decoder=(DecoderHandler) ReadSVGImage;
+#endif /* defined(HasXML) */
+#if ENABLE_SVG_WRITER
+ entry->encoder=(EncoderHandler) WriteSVGImage;
+#endif /* if ENABLE_SVG_WRITER */
+ entry->description="Scalable Vector Graphics (ZIP compressed)";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="SVG";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r S V G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterSVGImage removes format registrations made by the
+% SVG module from the list of supported formats.
+%
+% The format of the UnregisterSVGImage method is:
+%
+% UnregisterSVGImage(void)
+%
+*/
+ModuleExport void
+UnregisterSVGImage(void)
+{
+ (void) UnregisterMagickInfo("SVG");
+ (void) UnregisterMagickInfo("SVGZ");
+}
+
+#if ENABLE_SVG_WRITER
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e S V G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteSVGImage writes a image in the SVG - XML based W3C standard
+% format.
+%
+% The format of the WriteSVGImage method is:
+%
+% unsigned int WriteSVGImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteSVGImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+#if defined(HasAUTOTRACE)
+static unsigned int
+WriteSVGImage(const ImageInfo *image_info,Image *image)
+{
+ FILE
+ *output_file;
+
+ fitting_opts_type
+ fit_info;
+
+ image_header_type
+ image_header;
+
+ bitmap_type
+ bitmap;
+
+ ImageType
+ image_type;
+
+ int
+ j;
+
+ pixel_outline_list_type
+ pixels;
+
+ PixelPacket
+ p;
+
+ PixelPacket
+ *pixel;
+
+ QuantizeObj
+ *quantize_info;
+
+ spline_list_array_type
+ splines;
+
+ output_write
+ output_writer;
+
+ register long
+ i;
+
+ unsigned long
+ number_pixels,
+ number_planes,
+ point,
+ thin;
+
+ thin=False;
+ quantize_info=(QuantizeObj *) NULL;
+ pixel=(&p);
+ fit_info=new_fitting_opts();
+ output_writer=output_get_handler("svg");
+ if (output_writer == NULL)
+ ThrowWriterException(DelegateError,UnableToWriteSVGFormat,image);
+ image_type=GetImageType(image);
+ number_planes=3;
+ if ((image_type == BilevelType) || (image_type == GrayscaleType))
+ number_planes=1;
+ bitmap.np=number_planes;
+ bitmap.dimensions.width=image->columns;
+ bitmap.dimensions.height=image->rows;
+ number_pixels=image->columns*image->rows;
+ bitmap.bitmap=MagickAllocateMemory(unsigned char *,number_planes*number_pixels);
+ if (bitmap.bitmap == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ point=0;
+ for (j=0; j < image->rows; j++)
+ {
+ for (i=0; i < image->columns; i++)
+ {
+ p=AcquireOnePixel(image,i,j,&image->exception);
+ bitmap.bitmap[point++]=pixel->red;
+ if (number_planes == 3)
+ {
+ bitmap.bitmap[point++]=pixel->green;
+ bitmap.bitmap[point++]=pixel->blue;
+ }
+ }
+ }
+ image_header.width=DIMENSIONS_WIDTH(bitmap.dimensions);
+ image_header.height=DIMENSIONS_HEIGHT(bitmap.dimensions);
+ if ((fit_info.color_count > 0) && (BITMAP_PLANES(bitmap) == 3))
+ quantize(bitmap.bitmap,bitmap.bitmap,DIMENSIONS_WIDTH(bitmap.dimensions),
+ DIMENSIONS_HEIGHT(bitmap.dimensions),fit_info.color_count,
+ fit_info.bgColor,&quantize_info);
+ if (thin)
+ thin_image(&bitmap);
+ pixels=find_outline_pixels (bitmap);
+ MagickFreeMemory((bitmap.bitmap));
+ splines=fitted_splines(pixels,&fit_info);
+ output_file=fopen(image->filename,"w");
+ if (output_file == (FILE *) NULL)
+ ThrowWriterException(FileOpenError,UnableOpenFile,image);
+ output_writer(output_file,image->filename,0,0,image_header.width,
+ image_header.height,splines);
+ return(True);
+}
+#else
+static void
+AffineToTransform(Image *image,AffineMatrix *affine)
+{
+ char
+ transform[MaxTextExtent];
+
+ if ((fabs(affine->tx) < MagickEpsilon) && (fabs(affine->ty) < MagickEpsilon))
+ {
+ if ((fabs(affine->rx) < MagickEpsilon) &&
+ (fabs(affine->ry) < MagickEpsilon))
+ {
+ if ((fabs(affine->sx-1.0) < MagickEpsilon) &&
+ (fabs(affine->sy-1.0) < MagickEpsilon))
+ {
+ (void) WriteBlobString(image,"\">\n");
+ return;
+ }
+ FormatString(transform,"\" transform=\"scale(%g,%g)\">\n",
+ affine->sx,affine->sy);
+ (void) WriteBlobString(image,transform);
+ return;
+ }
+ else
+ {
+ if ((fabs(affine->sx-affine->sy) < MagickEpsilon) &&
+ (fabs(affine->rx+affine->ry) < MagickEpsilon) &&
+ (fabs(affine->sx*affine->sx+affine->rx*affine->rx-1.0) <
+ 2*MagickEpsilon))
+ {
+ double
+ theta;
+
+ theta=(180.0/MagickPI)*atan2(affine->rx,affine->sx);
+ FormatString(transform,"\" transform=\"rotate(%g)\">\n",theta);
+ (void) WriteBlobString(image,transform);
+ return;
+ }
+ }
+ }
+ else
+ {
+ if ((fabs(affine->sx-1.0) < MagickEpsilon) &&
+ (fabs(affine->rx) < MagickEpsilon) &&
+ (fabs(affine->ry) < MagickEpsilon) &&
+ (fabs(affine->sy-1.0) < MagickEpsilon))
+ {
+ FormatString(transform,"\" transform=\"translate(%g,%g)\">\n",
+ affine->tx,affine->ty);
+ (void) WriteBlobString(image,transform);
+ return;
+ }
+ }
+ FormatString(transform,"\" transform=\"matrix(%g %g %g %g %g %g)\">\n",
+ affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
+ (void) WriteBlobString(image,transform);
+}
+
+static inline unsigned int
+IsPoint(const char *point)
+{
+ char
+ *p;
+
+ (void) strtol(point,&p,10);
+ return(p != point);
+}
+
+static unsigned int
+WriteSVGImage(const ImageInfo *image_info,Image *image)
+{
+#define BezierQuantum 200
+
+ AffineMatrix
+ affine;
+
+ char
+ keyword[MaxTextExtent],
+ message[MaxTextExtent],
+ name[MaxTextExtent],
+ *p,
+ *q,
+ *token,
+ type[MaxTextExtent];
+
+ const ImageAttribute
+ *attribute;
+
+ int
+ n;
+
+ long
+ j;
+
+ PointInfo
+ point;
+
+ PrimitiveInfo
+ *primitive_info;
+
+ PrimitiveType
+ primitive_type;
+
+ register long
+ x;
+
+ register long
+ i;
+
+ size_t
+ length,
+ token_max_length;
+
+ SVGInfo
+ svg_info;
+
+ unsigned int
+ active,
+ status;
+
+ unsigned long
+ number_points;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ attribute=GetImageAttribute(image,"[MVG]");
+ if ((attribute == (ImageAttribute *) NULL) ||
+ (attribute->value == (char *) NULL))
+ ThrowWriterException(CoderError,NoImageVectorGraphics,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Write SVG header.
+ */
+ (void) WriteBlobString(image,"<?xml version=\"1.0\" standalone=\"no\"?>\n");
+ (void) WriteBlobString(image,
+ "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n");
+ (void) WriteBlobString(image,
+ " \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n");
+ (void) FormatString(message,"<svg width=\"%lu\" height=\"%lu\">\n",
+ image->columns,image->rows);
+ (void) WriteBlobString(image,message);
+ /*
+ Allocate primitive info memory.
+ */
+ number_points=2047;
+ primitive_info=MagickAllocateMemory(PrimitiveInfo *,
+ number_points*sizeof(PrimitiveInfo));
+ if (primitive_info == (PrimitiveInfo *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ IdentityAffine(&affine);
+ token=AllocateString(attribute->value);
+ token_max_length=strlen(token);
+ active=False;
+ n=0;
+ status=True;
+ for (q=attribute->value; *q != '\0'; )
+ {
+ /*
+ Interpret graphic primitive.
+ */
+ MagickGetToken(q,&q,keyword,MaxTextExtent);
+ if (*keyword == '\0')
+ break;
+ if (*keyword == '#')
+ {
+ /*
+ Comment.
+ */
+ if (active)
+ {
+ AffineToTransform(image,&affine);
+ active=False;
+ }
+ (void) WriteBlobString(image,"<desc>");
+ (void) WriteBlobString(image,keyword+1);
+ for ( ; (*q != '\n') && (*q != '\0'); q++)
+ switch (*q)
+ {
+ case '<': (void) WriteBlobString(image,"&lt;"); break;
+ case '>': (void) WriteBlobString(image,"&gt;"); break;
+ case '&': (void) WriteBlobString(image,"&amp;"); break;
+ default: (void) WriteBlobByte(image,*q); break;
+ }
+ (void) WriteBlobString(image,"</desc>\n");
+ continue;
+ }
+ primitive_type=UndefinedPrimitive;
+ switch (*keyword)
+ {
+ case ';':
+ break;
+ case 'a':
+ case 'A':
+ {
+ if (LocaleCompare("affine",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.sx=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.rx=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.ry=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.sy=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.tx=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.ty=MagickAtoF(token);
+ break;
+ }
+ if (LocaleCompare("angle",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.rx=MagickAtoF(token);
+ affine.ry=MagickAtoF(token);
+ break;
+ }
+ if (LocaleCompare("arc",keyword) == 0)
+ {
+ primitive_type=ArcPrimitive;
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'b':
+ case 'B':
+ {
+ if (LocaleCompare("bezier",keyword) == 0)
+ {
+ primitive_type=BezierPrimitive;
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'c':
+ case 'C':
+ {
+ if (LocaleCompare("clip-path",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"clip-path:url(#%.1024s);",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("clip-rule",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"clip-rule:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("clip-units",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"clipPathUnits=%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("circle",keyword) == 0)
+ {
+ primitive_type=CirclePrimitive;
+ break;
+ }
+ if (LocaleCompare("color",keyword) == 0)
+ {
+ primitive_type=ColorPrimitive;
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'd':
+ case 'D':
+ {
+ if (LocaleCompare("decorate",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"text-decoration:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'e':
+ case 'E':
+ {
+ if (LocaleCompare("ellipse",keyword) == 0)
+ {
+ primitive_type=EllipsePrimitive;
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'f':
+ case 'F':
+ {
+ if (LocaleCompare("fill",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"fill:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("fill-rule",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"fill-rule:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("fill-opacity",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"fill-opacity:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("font-family",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"font-family:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("font-stretch",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"font-stretch:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("font-style",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"font-style:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("font-size",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"font-size:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("font-weight",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"font-weight:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'g':
+ case 'G':
+ {
+ if (LocaleCompare("gradient-units",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ if (LocaleCompare("text-align",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"text-align %.1024s ",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("text-anchor",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"text-anchor %.1024s ",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'i':
+ case 'I':
+ {
+ if (LocaleCompare("image",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ primitive_type=ImagePrimitive;
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'l':
+ case 'L':
+ {
+ if (LocaleCompare("line",keyword) == 0)
+ {
+ primitive_type=LinePrimitive;
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'm':
+ case 'M':
+ {
+ if (LocaleCompare("matte",keyword) == 0)
+ {
+ primitive_type=MattePrimitive;
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'o':
+ case 'O':
+ {
+ if (LocaleCompare("opacity",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"opacity %.1024s ",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'p':
+ case 'P':
+ {
+ if (LocaleCompare("path",keyword) == 0)
+ {
+ primitive_type=PathPrimitive;
+ break;
+ }
+ if (LocaleCompare("point",keyword) == 0)
+ {
+ primitive_type=PointPrimitive;
+ break;
+ }
+ if (LocaleCompare("polyline",keyword) == 0)
+ {
+ primitive_type=PolylinePrimitive;
+ break;
+ }
+ if (LocaleCompare("polygon",keyword) == 0)
+ {
+ primitive_type=PolygonPrimitive;
+ break;
+ }
+ if (LocaleCompare("pop",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("clip-path",token) == 0)
+ {
+ (void) WriteBlobString(image,"</clipPath>\n");
+ break;
+ }
+ if (LocaleCompare("defs",token) == 0)
+ {
+ (void) WriteBlobString(image,"</defs>\n");
+ break;
+ }
+ if (LocaleCompare("gradient",token) == 0)
+ {
+ FormatString(message,"</%sGradient>\n",type);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("graphic-context",token) == 0)
+ {
+ n--;
+ if (n < 0)
+ ThrowWriterException(DrawError,
+ UnbalancedGraphicContextPushPop,image);
+ (void) WriteBlobString(image,"</g>\n");
+ }
+ if (LocaleCompare("pattern",token) == 0)
+ {
+ (void) WriteBlobString(image,"</pattern>\n");
+ break;
+ }
+ if (LocaleCompare("defs",token) == 0)
+ (void) WriteBlobString(image,"</g>\n");
+ break;
+ }
+ if (LocaleCompare("push",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("clip-path",token) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"<clipPath id=\"%s\">\n",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("defs",token) == 0)
+ {
+ (void) WriteBlobString(image,"<defs>\n");
+ break;
+ }
+ if (LocaleCompare("gradient",token) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) strlcpy(name,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) strlcpy(type,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.segment.x1=MagickAtoF(token);
+ svg_info.element.cx=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.segment.y1=MagickAtoF(token);
+ svg_info.element.cy=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.segment.x2=MagickAtoF(token);
+ svg_info.element.major=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.segment.y2=MagickAtoF(token);
+ svg_info.element.minor=MagickAtoF(token);
+ FormatString(message,"<%sGradient id=\"%s\" x1=\"%g\" "
+ "y1=\"%g\" x2=\"%g\" y2=\"%g\">\n",type,name,
+ svg_info.segment.x1,svg_info.segment.y1,svg_info.segment.x2,
+ svg_info.segment.y2);
+ if (LocaleCompare(type,"radial") == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.element.angle=MagickAtoF(token);
+ FormatString(message,"<%sGradient id=\"%s\" cx=\"%g\" "
+ "cy=\"%g\" r=\"%g\" fx=\"%g\" fy=\"%g\">\n",type,name,
+ svg_info.element.cx,svg_info.element.cy,
+ svg_info.element.angle,svg_info.element.major,
+ svg_info.element.minor);
+ }
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("graphic-context",token) == 0)
+ {
+ n++;
+ if (active)
+ {
+ AffineToTransform(image,&affine);
+ active=False;
+ }
+ (void) WriteBlobString(image,"<g style=\"");
+ active=True;
+ }
+ if (LocaleCompare("pattern",token) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) strlcpy(name,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.bounds.x=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.bounds.y=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.bounds.width=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ svg_info.bounds.height=MagickAtoF(token);
+ FormatString(message,"<pattern id=\"%s\" x=\"%g\" y=\"%g\" "
+ "width=\"%g\" height=\"%g\">\n",name,svg_info.bounds.x,
+ svg_info.bounds.y,svg_info.bounds.width,
+ svg_info.bounds.height);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'r':
+ case 'R':
+ {
+ if (LocaleCompare("rectangle",keyword) == 0)
+ {
+ primitive_type=RectanglePrimitive;
+ break;
+ }
+ if (LocaleCompare("roundRectangle",keyword) == 0)
+ {
+ primitive_type=RoundRectanglePrimitive;
+ break;
+ }
+ if (LocaleCompare("rotate",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"rotate(%.1024s) ",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 's':
+ case 'S':
+ {
+ if (LocaleCompare("scale",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.sx=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.sy=MagickAtoF(token);
+ break;
+ }
+ if (LocaleCompare("skewX",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"skewX(%.1024s) ",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("skewY",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"skewY(%.1024s) ",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stop-color",keyword) == 0)
+ {
+ char
+ color[MaxTextExtent];
+
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) strlcpy(color,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,
+ " <stop offset=\"%s\" stop-color=\"%s\" />\n",token,color);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke-antialias",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke-antialias:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke-dasharray",keyword) == 0)
+ {
+ if (IsPoint(q))
+ {
+ long
+ k;
+
+ p=q;
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ for (k=0; IsPoint(token); k++)
+ (void) MagickGetToken(p,&p,token,MaxTextExtent);
+ (void) WriteBlobString(image,"stroke-dasharray:");
+ for (j=0; j < k; j++)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"%.1024s ",token);
+ (void) WriteBlobString(image,message);
+ }
+ (void) WriteBlobString(image,";");
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke-dasharray:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke-dashoffset",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke-dashoffset:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke-linecap",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke-linecap:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke-linejoin",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke-linejoin:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke-miterlimit",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke-miterlimit:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke-opacity",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke-opacity:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("stroke-width",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"stroke-width:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ continue;
+ }
+ status=False;
+ break;
+ }
+ case 't':
+ case 'T':
+ {
+ if (LocaleCompare("text",keyword) == 0)
+ {
+ primitive_type=TextPrimitive;
+ break;
+ }
+ if (LocaleCompare("text-antialias",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(message,"text-antialias:%.1024s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ if (LocaleCompare("tspan",keyword) == 0)
+ {
+ primitive_type=TextPrimitive;
+ break;
+ }
+ if (LocaleCompare("translate",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.tx=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ affine.ty=MagickAtoF(token);
+ break;
+ }
+ status=False;
+ break;
+ }
+ case 'v':
+ case 'V':
+ {
+ if (LocaleCompare("viewbox",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ status=False;
+ break;
+ }
+ default:
+ {
+ status=False;
+ break;
+ }
+ }
+ if (status == False)
+ break;
+ if (primitive_type == UndefinedPrimitive)
+ continue;
+ /*
+ Parse the primitive attributes.
+ */
+ i=0;
+ j=0;
+ for (x=0; *q != '\0'; x++)
+ {
+ /*
+ Define points.
+ */
+ if (!IsPoint(q))
+ break;
+ MagickGetToken(q,&q,token,token_max_length);
+ point.x=MagickAtoF(token);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ point.y=MagickAtoF(token);
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ primitive_info[i].primitive=primitive_type;
+ primitive_info[i].point=point;
+ primitive_info[i].coordinates=0;
+ primitive_info[i].method=FloodfillMethod;
+ i++;
+ if (i < (long) (number_points-6*BezierQuantum-360))
+ continue;
+ number_points+=6*BezierQuantum+360;
+ MagickReallocMemory(PrimitiveInfo *,primitive_info,
+ number_points*sizeof(PrimitiveInfo));
+ if (primitive_info == (PrimitiveInfo *) NULL)
+ {
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ break;
+ }
+ }
+ primitive_info[j].primitive=primitive_type;
+ primitive_info[j].coordinates=x;
+ primitive_info[j].method=FloodfillMethod;
+ primitive_info[j].text=(char *) NULL;
+ if (active)
+ {
+ AffineToTransform(image,&affine);
+ active=False;
+ }
+ active=False;
+ switch (primitive_type)
+ {
+ case PointPrimitive:
+ default:
+ {
+ if (primitive_info[j].coordinates != 1)
+ {
+ status=False;
+ break;
+ }
+ break;
+ }
+ case LinePrimitive:
+ {
+ if (primitive_info[j].coordinates != 2)
+ {
+ status=False;
+ break;
+ }
+ (void) FormatString(message,
+ " <line x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\"/>\n",
+ primitive_info[j].point.x,primitive_info[j].point.y,
+ primitive_info[j+1].point.x,primitive_info[j+1].point.y);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ case RectanglePrimitive:
+ {
+ if (primitive_info[j].coordinates != 2)
+ {
+ status=False;
+ break;
+ }
+ (void) FormatString(message,
+ " <rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\"/>\n",
+ primitive_info[j].point.x,primitive_info[j].point.y,
+ primitive_info[j+1].point.x-primitive_info[j].point.x,
+ primitive_info[j+1].point.y-primitive_info[j].point.y);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ case RoundRectanglePrimitive:
+ {
+ if (primitive_info[j].coordinates != 3)
+ {
+ status=False;
+ break;
+ }
+ (void) FormatString(message," <rect x=\"%g\" y=\"%g\" "
+ "width=\"%g\" height=\"%g\" rx=\"%g\" ry=\"%g\"/>\n",
+ primitive_info[j].point.x,primitive_info[j].point.y,
+ primitive_info[j+1].point.x-primitive_info[j].point.x,
+ primitive_info[j+1].point.y-primitive_info[j].point.y,
+ primitive_info[j+2].point.x,primitive_info[j+2].point.y);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ case ArcPrimitive:
+ {
+ if (primitive_info[j].coordinates != 3)
+ {
+ status=False;
+ break;
+ }
+ break;
+ }
+ case EllipsePrimitive:
+ {
+ if (primitive_info[j].coordinates != 3)
+ {
+ status=False;
+ break;
+ }
+ (void) FormatString(message,
+ " <ellipse cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\"/>\n",
+ primitive_info[j].point.x,primitive_info[j].point.y,
+ primitive_info[j+1].point.x,primitive_info[j+1].point.y);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ case CirclePrimitive:
+ {
+ double
+ alpha,
+ beta;
+
+ if (primitive_info[j].coordinates != 2)
+ {
+ status=False;
+ break;
+ }
+ alpha=primitive_info[j+1].point.x-primitive_info[j].point.x;
+ beta=primitive_info[j+1].point.y-primitive_info[j].point.y;
+ (void) FormatString(message," <circle cx=\"%g\" cy=\"%g\" r=\"%g\"/>\n",
+ primitive_info[j].point.x,primitive_info[j].point.y,
+ sqrt(alpha*alpha+beta*beta));
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ case PolylinePrimitive:
+ {
+ if (primitive_info[j].coordinates < 2)
+ {
+ status=False;
+ break;
+ }
+ (void) strcpy(message," <polyline points=\"");
+ (void) WriteBlobString(image,message);
+ length=strlen(message);
+ for ( ; j < i; j++)
+ {
+ FormatString(message,"%g,%g ",primitive_info[j].point.x,
+ primitive_info[j].point.y);
+ length+=strlen(message);
+ if (length >= 80)
+ {
+ (void) WriteBlobString(image,"\n ");
+ length=strlen(message)+5;
+ }
+ (void) WriteBlobString(image,message);
+ }
+ (void) WriteBlobString(image,"\"/>\n");
+ break;
+ }
+ case PolygonPrimitive:
+ {
+ if (primitive_info[j].coordinates < 3)
+ {
+ status=False;
+ break;
+ }
+ primitive_info[i]=primitive_info[j];
+ primitive_info[i].coordinates=0;
+ primitive_info[j].coordinates++;
+ i++;
+ (void) strcpy(message," <polygon points=\"");
+ (void) WriteBlobString(image,message);
+ length=strlen(message);
+ for ( ; j < i; j++)
+ {
+ FormatString(message,"%g,%g ",primitive_info[j].point.x,
+ primitive_info[j].point.y);
+ length+=strlen(message);
+ if (length >= 80)
+ {
+ (void) WriteBlobString(image,"\n ");
+ length=strlen(message)+5;
+ }
+ (void) WriteBlobString(image,message);
+ }
+ (void) WriteBlobString(image,"\"/>\n");
+ break;
+ }
+ case BezierPrimitive:
+ {
+ if (primitive_info[j].coordinates < 3)
+ {
+ status=False;
+ break;
+ }
+ break;
+ }
+ case PathPrimitive:
+ {
+ int
+ number_attributes;
+
+ MagickGetToken(q,&q,token,token_max_length);
+ number_attributes=1;
+ for (p=token; *p != '\0'; p++)
+ if (isalpha((int) *p))
+ number_attributes++;
+ if (i > (long) (number_points-6*BezierQuantum*number_attributes-1))
+ {
+ number_points+=6*BezierQuantum*number_attributes;
+ MagickReallocMemory(PrimitiveInfo *,primitive_info,
+ number_points*sizeof(PrimitiveInfo));
+ if (primitive_info == (PrimitiveInfo *) NULL)
+ {
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ break;
+ }
+ }
+ (void) WriteBlobString(image," <path d=\"");
+ (void) WriteBlobString(image,token);
+ (void) WriteBlobString(image,"\"/>\n");
+ break;
+ }
+ case ColorPrimitive:
+ case MattePrimitive:
+ {
+ if (primitive_info[j].coordinates != 1)
+ {
+ status=False;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("point",token) == 0)
+ primitive_info[j].method=PointMethod;
+ if (LocaleCompare("replace",token) == 0)
+ primitive_info[j].method=ReplaceMethod;
+ if (LocaleCompare("floodfill",token) == 0)
+ primitive_info[j].method=FloodfillMethod;
+ if (LocaleCompare("filltoborder",token) == 0)
+ primitive_info[j].method=FillToBorderMethod;
+ if (LocaleCompare("reset",token) == 0)
+ primitive_info[j].method=ResetMethod;
+ break;
+ }
+ case TextPrimitive:
+ {
+ register char
+ *p;
+
+ if (primitive_info[j].coordinates != 1)
+ {
+ status=False;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) FormatString(message," <text x=\"%g\" y=\"%g\">",
+ primitive_info[j].point.x,primitive_info[j].point.y);
+ (void) WriteBlobString(image,message);
+ for (p=token; *p != '\0'; p++)
+ switch (*p)
+ {
+ case '<': (void) WriteBlobString(image,"&lt;"); break;
+ case '>': (void) WriteBlobString(image,"&gt;"); break;
+ case '&': (void) WriteBlobString(image,"&amp;"); break;
+ default: (void) WriteBlobByte(image,*p); break;
+ }
+ (void) WriteBlobString(image,"</text>\n");
+ break;
+ }
+ case ImagePrimitive:
+ {
+ if (primitive_info[j].coordinates != 2)
+ {
+ status=False;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) FormatString(message," <image x=\"%g\" y=\"%g\" "
+ "width=\"%g\" height=\"%g\" xlink:href=\"%.1024s\"/>\n",
+ primitive_info[j].point.x,primitive_info[j].point.y,
+ primitive_info[j+1].point.x,primitive_info[j+1].point.y,token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
+ }
+ if (primitive_info == (PrimitiveInfo *) NULL)
+ break;
+ primitive_info[i].primitive=UndefinedPrimitive;
+ if (status == False)
+ break;
+ }
+ (void) WriteBlobString(image,"</svg>\n");
+ /*
+ Free resources.
+ */
+ MagickFreeMemory(token);
+ if (primitive_info != (PrimitiveInfo *) NULL)
+ MagickFreeMemory(primitive_info);
+ CloseBlob(image);
+ return(status);
+}
+#endif
+#endif /* if ENABLE_SVG_WRITER */
diff --git a/coders/tga.c b/coders/tga.c
new file mode 100644
index 0000000..73062b2
--- /dev/null
+++ b/coders/tga.c
@@ -0,0 +1,1070 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT GGGG AAA %
+% T G A A %
+% T G GG AAAAA %
+% T G G A A %
+% T GGG A A %
+% %
+% %
+% Read/Write Truevision Targa Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteTGAImage(const ImageInfo *,Image *);
+
+
+magick_uint16_t ReadBlobLSBShortFromBuffer(unsigned char* buffer, size_t* readerpos)
+{
+ magick_uint16_t
+ value;
+
+ value=buffer[(*readerpos)+1] << 8;
+ value|=buffer[*readerpos];
+ *readerpos = *readerpos+2;
+ return(value);
+}
+
+
+int ReadBlobByteFromBuffer(unsigned char* buffer, size_t* readerpos)
+{
+ int
+ value;
+
+ value=(int)(buffer[*readerpos]);
+ *readerpos = *readerpos + 1;
+ return(value);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d T G A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadTGAImage reads a Truevision TGA image file and returns it.
+% It allocates the memory necessary for the new Image structure and returns
+% a pointer to the new image.
+%
+% The format of the ReadTGAImage method is:
+%
+% Image *ReadTGAImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadTGAImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadTGAImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define TGAColormap 1 /* Colormapped image data */
+#define TGARGB 2 /* Truecolor image data */
+#define TGAMonochrome 3 /* Monochrome image data */
+#define TGARLEColormap 9 /* Colormapped image data (encoded) */
+#define TGARLERGB 10 /* Truecolor image data (encoded) */
+#define TGARLEMonochrome 11 /* Monochrome image data (encoded) */
+
+ typedef struct _TGAInfo
+ {
+ unsigned char
+ id_length, /* Size of Image ID field */
+ colormap_type, /* Color map type */
+ image_type; /* Image type code */
+
+ unsigned short
+ colormap_index, /* Color map origin */
+ colormap_length; /* Color map length */
+
+ unsigned char
+ colormap_size; /* Color map entry depth */
+
+ unsigned short
+ x_origin, /* X origin of image */
+ y_origin, /* Y orgin of image */
+ width, /* Width of image */
+ height; /* Height of image */
+
+ unsigned char
+ bits_per_pixel, /* Image pixel size */
+ attributes; /* Image descriptor byte */
+ } TGAInfo;
+
+ Image
+ *image;
+
+ unsigned int
+ index;
+
+ long
+ y;
+
+ PixelPacket
+ pixel;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ TGAInfo
+ tga_info;
+
+ unsigned char
+ runlength;
+
+ unsigned int
+ alpha_bits,
+ status;
+
+ unsigned long
+ base,
+ flag,
+ offset,
+ real,
+ skip;
+
+ unsigned int
+ is_grayscale=MagickFalse;
+
+ const size_t headersize = 15;
+ unsigned char readbuffer[15];
+ const size_t commentsize = 256;
+ char commentbuffer[256];
+ size_t readbufferpos = 0;
+
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFalse)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read TGA header information.
+ */
+ if (ReadBlob(image, 3, readbuffer) != 3)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ readbufferpos = 0;
+ tga_info.id_length=(unsigned char)ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ tga_info.colormap_type=(unsigned char)ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ tga_info.image_type=(unsigned char)ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+
+ do
+ {
+ if (((tga_info.image_type != TGAColormap) &&
+ (tga_info.image_type != TGARGB) &&
+ (tga_info.image_type != TGAMonochrome) &&
+ (tga_info.image_type != TGARLEColormap) &&
+ (tga_info.image_type != TGARLERGB) &&
+ (tga_info.image_type != TGARLEMonochrome)) ||
+ (((tga_info.image_type == TGAColormap) ||
+ (tga_info.image_type == TGARLEColormap)) &&
+ (tga_info.colormap_type == 0)))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (ReadBlob(image,headersize,readbuffer) != headersize)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ readbufferpos = 0;
+ tga_info.colormap_index=ReadBlobLSBShortFromBuffer(readbuffer, &readbufferpos);
+ tga_info.colormap_length=ReadBlobLSBShortFromBuffer(readbuffer, &readbufferpos) & 0xFFFF;
+ tga_info.colormap_size=ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ tga_info.x_origin=ReadBlobLSBShortFromBuffer(readbuffer, &readbufferpos);
+ tga_info.y_origin=ReadBlobLSBShortFromBuffer(readbuffer, &readbufferpos);
+ tga_info.width=ReadBlobLSBShortFromBuffer(readbuffer, &readbufferpos) & 0xFFFF;
+ tga_info.height=ReadBlobLSBShortFromBuffer(readbuffer, &readbufferpos) & 0xFFFF;
+ tga_info.bits_per_pixel=ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ tga_info.attributes=ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ assert(readbufferpos == headersize);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "ImageType=%s CMapType=%u CMapStart=%u CMapLength=%u CMapDepth=%u\n"
+ " XOffset=%u YOffset=%u Width=%u Height=%u PixelDepth=%u Attributes=0x%.2x",
+ ((tga_info.image_type == TGAColormap) ? "Colormapped" :
+ (tga_info.image_type == TGARGB) ? "TrueColor" :
+ (tga_info.image_type == TGAMonochrome) ? "Monochrome" :
+ (tga_info.image_type == TGARLEColormap) ? "Colormapped-RLE" :
+ (tga_info.image_type == TGARLERGB) ? "Truecolor-RLE" :
+ (tga_info.image_type == TGARLEMonochrome) ? "Monochrome-RLE" :
+ "Unknown"),
+ (unsigned int) tga_info.colormap_type, /* Colormap type */
+ (unsigned int) tga_info.colormap_index, /* Index of first colormap entry to use */
+ (unsigned int) tga_info.colormap_length, /* # of elements in colormap */
+ (unsigned int) tga_info.colormap_size, /* Bits in each palette entry */
+ tga_info.x_origin, tga_info.y_origin,
+ tga_info.width, tga_info.height,
+ (unsigned int) tga_info.bits_per_pixel,
+ tga_info.attributes);
+
+ /*
+ Validate depth.
+ */
+ if (!(((tga_info.bits_per_pixel > 1) && (tga_info.bits_per_pixel < 17)) ||
+ (tga_info.bits_per_pixel == 24 ) ||
+ (tga_info.bits_per_pixel == 32 )))
+ ThrowReaderException(CoderError,DataStorageTypeIsNotSupported,image);
+
+ /*
+ Initialize image structure.
+ */
+ alpha_bits=(tga_info.attributes & 0x0FU);
+ image->matte=((alpha_bits > 0) || (tga_info.bits_per_pixel == 32));
+ image->columns=tga_info.width;
+ image->rows=tga_info.height;
+ if ((tga_info.image_type != TGAColormap) && (tga_info.image_type != TGARLEColormap))
+ {
+ /*
+ TrueColor Quantum Depth
+ */
+ image->depth=((tga_info.bits_per_pixel <= 8) ? 8 :
+ (tga_info.bits_per_pixel <= 16) ? 5 : 8);
+ }
+ else
+ {
+ /*
+ ColorMapped Palette Entry Quantum Depth
+ */
+ image->depth=((tga_info.colormap_size <= 8) ? 8 :
+ (tga_info.colormap_size <= 16) ? 5 : 8);
+ }
+
+ image->storage_class=DirectClass;
+
+ if ((tga_info.image_type == TGAColormap) ||
+ (tga_info.image_type == TGAMonochrome) ||
+ (tga_info.image_type == TGARLEColormap) ||
+ (tga_info.image_type == TGARLEMonochrome))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Setting PseudoClass");
+ image->storage_class=PseudoClass;
+ }
+
+ if ((tga_info.image_type == TGARLEColormap) ||
+ (tga_info.image_type == TGARLEMonochrome))
+ image->compression=RLECompression;
+
+ is_grayscale=((tga_info.image_type == TGAMonochrome) ||
+ (tga_info.image_type == TGARLEMonochrome));
+
+ if (image->storage_class == PseudoClass)
+ {
+ if (tga_info.colormap_type != 0)
+ {
+ image->colors=tga_info.colormap_length;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using existing colormap with %u colors.",image->colors);
+
+ }
+ else
+ {
+ /*
+ Apply grayscale colormap.
+ */
+ image->colors=(0x01U << tga_info.bits_per_pixel);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Applying grayscale colormap with %u colors.",image->colors);
+ }
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "StorageClass=%s Matte=%s Depth=%u Grayscale=%s",
+ ((image->storage_class == DirectClass) ? "DirectClass" : "PseduoClass"),
+ MagickBoolToString(image->matte), image->depth,
+ MagickBoolToString(is_grayscale));
+
+ if (tga_info.id_length != 0)
+ {
+ /*
+ TGA image comment.
+ */
+ assert((size_t) (tga_info.id_length+1) == commentsize);
+ if (ReadBlob(image,tga_info.id_length,commentbuffer) != tga_info.id_length)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ commentbuffer[tga_info.id_length]='\0';
+ (void) SetImageAttribute(image,"comment",commentbuffer);
+ }
+ (void) memset(&pixel,0,sizeof(PixelPacket));
+ pixel.opacity=TransparentOpacity;
+ if (tga_info.colormap_type != 0)
+ {
+ /*
+ Read TGA raster colormap.
+ */
+ for (i=0; i < (long) image->colors; i++)
+ {
+ switch (tga_info.colormap_size)
+ {
+ case 8:
+ default:
+ {
+ /*
+ Gray scale.
+ */
+ pixel.red=ScaleCharToQuantum(ReadBlobByte(image));
+ pixel.green=pixel.red;
+ pixel.blue=pixel.red;
+ break;
+ }
+ case 15:
+ case 16:
+ {
+ /*
+ 5 bits each of red green and blue.
+ */
+ unsigned int
+ packet;
+
+ if (ReadBlob(image, 2, readbuffer) != 2)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ readbufferpos = 0;
+ packet = ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ packet |= (((unsigned int) ReadBlobByteFromBuffer(readbuffer, &readbufferpos)) << 8);
+
+ pixel.red=(packet >> 10) & 0x1f;
+ pixel.red=ScaleCharToQuantum(ScaleColor5to8(pixel.red));
+ pixel.green=(packet >> 5) & 0x1f;
+ pixel.green=ScaleCharToQuantum(ScaleColor5to8(pixel.green));
+ pixel.blue=packet & 0x1f;
+ pixel.blue=ScaleCharToQuantum(ScaleColor5to8(pixel.blue));
+ break;
+ }
+ case 24:
+ case 32:
+ {
+ /*
+ 8 bits each of blue, green and red.
+ */
+ if (ReadBlob(image, 3, readbuffer) != 3)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ readbufferpos = 0;
+ pixel.blue=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ pixel.green=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ pixel.red=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ break;
+ }
+ }
+ image->colormap[i]=pixel;
+ }
+ }
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ /*
+ Convert TGA pixels to pixel packets.
+ */
+ base=0;
+ flag=0;
+ skip=MagickFalse;
+ real=0;
+ index=0;
+ runlength=0;
+ offset=0;
+ pixel.opacity=OpaqueOpacity;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ real=offset;
+ if (((unsigned char) (tga_info.attributes & 0x20) >> 5) == 0)
+ real=image->rows-real-1;
+ q=SetImagePixels(image,0,(long) real,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((tga_info.image_type == TGARLEColormap) ||
+ (tga_info.image_type == TGARLERGB) ||
+ (tga_info.image_type == TGARLEMonochrome))
+ {
+ if (runlength != 0)
+ {
+ runlength--;
+ skip=flag != 0;
+ }
+ else
+ {
+ if (ReadBlob(image,1,(char *) &runlength) != 1)
+ {
+ status=MagickFail;
+ break;
+ }
+ flag=runlength & 0x80;
+ if (flag != 0)
+ runlength-=128;
+ skip=MagickFalse;
+ }
+ }
+ if (!skip)
+ switch (tga_info.bits_per_pixel)
+ {
+ case 8:
+ default:
+ {
+ /*
+ Gray scale.
+ */
+ index=ReadBlobByte(image);
+ if (image->storage_class == PseudoClass)
+ {
+ VerifyColormapIndex(image,index);
+ pixel=image->colormap[index];
+ }
+ else
+ {
+ pixel.blue=pixel.green=pixel.red=ScaleCharToQuantum(index);
+ }
+ break;
+ }
+ case 15:
+ case 16:
+ {
+ /*
+ 5 bits each of red green and blue.
+ */
+ unsigned int
+ packet;
+
+ if (ReadBlob(image, 2, readbuffer) != 2)
+ {
+ status=MagickFail;
+ break;
+ }
+ readbufferpos = 0;
+ packet = ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ packet |= (((unsigned int) ReadBlobByteFromBuffer(readbuffer, &readbufferpos)) << 8);
+
+ pixel.red=(packet >> 10) & 0x1f;
+ pixel.red=ScaleCharToQuantum(ScaleColor5to8(pixel.red));
+ pixel.green=(packet >> 5) & 0x1f;
+ pixel.green=ScaleCharToQuantum(ScaleColor5to8(pixel.green));
+ pixel.blue=packet & 0x1f;
+ pixel.blue=ScaleCharToQuantum(ScaleColor5to8(pixel.blue));
+ if (image->matte)
+ {
+ if ((packet >> 15) & 0x01)
+ pixel.opacity=OpaqueOpacity;
+ else
+ pixel.opacity=TransparentOpacity;
+ }
+
+ if (image->storage_class == PseudoClass)
+ {
+ index=(IndexPacket) (packet & 0x7fff);
+ VerifyColormapIndex(image,index);
+ }
+ break;
+ }
+ case 24:
+ /*
+ 8 bits each of blue green and red.
+ */
+ if (ReadBlob(image, 3, readbuffer) != 3)
+ {
+ status=MagickFail;
+ break;
+ }
+ readbufferpos = 0;
+ pixel.blue=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ pixel.green=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ pixel.red=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ break;
+ case 32:
+ {
+ /*
+ 8 bits each of blue green and red.
+ */
+ if (ReadBlob(image, 4, readbuffer) != 4)
+ {
+ status=MagickFail;
+ break;
+ }
+ readbufferpos = 0;
+ pixel.blue=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ pixel.green=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ pixel.red=ScaleCharToQuantum(ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ pixel.opacity=ScaleCharToQuantum(255-ReadBlobByteFromBuffer(readbuffer, &readbufferpos));
+ break;
+ }
+ }
+ if (EOFBlob(image))
+ status = MagickFail;
+ if (status == MagickFail)
+ ThrowReaderException(CorruptImageError,UnableToReadImageData,image);
+ if (image->storage_class == PseudoClass)
+ indexes[x]=index;
+ *q++=pixel;
+ }
+ /*
+ FIXME: Need to research what case was expected to be
+ tested here. This test case can never be true and so it
+ is commented out for the moment.
+
+ if (((unsigned char) (tga_info.attributes & 0xc0) >> 6) == 4)
+ offset+=4;
+ else
+ */
+ if (((unsigned char) (tga_info.attributes & 0xc0) >> 6) == 2)
+ offset+=2;
+ else
+ offset++;
+ if (offset >= image->rows)
+ {
+ base++;
+ offset=base;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ image->is_grayscale=is_grayscale;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ status=MagickFalse;
+ if (ReadBlob(image, 3, readbuffer) == 3)
+ {
+ readbufferpos = 0;
+ tga_info.id_length=(unsigned char)ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ tga_info.colormap_type=(unsigned char)ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ tga_info.image_type=(unsigned char)ReadBlobByteFromBuffer(readbuffer, &readbufferpos);
+ status=((tga_info.image_type == TGAColormap) ||
+ (tga_info.image_type == TGARGB) ||
+ (tga_info.image_type == TGAMonochrome) ||
+ (tga_info.image_type == TGARLEColormap) ||
+ (tga_info.image_type == TGARLERGB) ||
+ (tga_info.image_type == TGARLEMonochrome));
+ }
+ if (!EOFBlob(image) && (status == MagickTrue))
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ } while (status == MagickTrue);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r T G A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterTGAImage adds attributes for the TGA image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterTGAImage method is:
+%
+% RegisterTGAImage(void)
+%
+*/
+ModuleExport void RegisterTGAImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("ICB");
+ entry->decoder=(DecoderHandler) ReadTGAImage;
+ entry->encoder=(EncoderHandler) WriteTGAImage;
+ entry->description="Truevision Targa image";
+ entry->module="TGA";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("TGA");
+ entry->decoder=(DecoderHandler) ReadTGAImage;
+ entry->encoder=(EncoderHandler) WriteTGAImage;
+ entry->description="Truevision Targa image";
+ entry->module="TGA";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("VDA");
+ entry->decoder=(DecoderHandler) ReadTGAImage;
+ entry->encoder=(EncoderHandler) WriteTGAImage;
+ entry->description="Truevision Targa image";
+ entry->module="TGA";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("VST");
+ entry->decoder=(DecoderHandler) ReadTGAImage;
+ entry->encoder=(EncoderHandler) WriteTGAImage;
+ entry->description="Truevision Targa image";
+ entry->module="TGA";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r T G A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterTGAImage removes format registrations made by the
+% TGA module from the list of supported formats.
+%
+% The format of the UnregisterTGAImage method is:
+%
+% UnregisterTGAImage(void)
+%
+*/
+ModuleExport void UnregisterTGAImage(void)
+{
+ (void) UnregisterMagickInfo("ICB");
+ (void) UnregisterMagickInfo("TGA");
+ (void) UnregisterMagickInfo("VDA");
+ (void) UnregisterMagickInfo("VST");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e T G A I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteTGAImage writes a image in the Truevision Targa rasterfile
+% format.
+%
+% The format of the WriteTGAImage method is:
+%
+% unsigned int WriteTGAImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteTGAImage return MagickTrue if the image is written.
+% MagickFalse is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteTGAImage(const ImageInfo *image_info,Image *image)
+{
+#define TargaColormap 1
+#define TargaRGB 2
+#define TargaMonochrome 3
+#define TargaRLEColormap 9
+#define TargaRLERGB 10
+#define TargaRLEMonochrome 11
+
+ typedef struct _TargaInfo
+ {
+ unsigned char
+ id_length,
+ colormap_type,
+ image_type;
+
+ unsigned short
+ colormap_index,
+ colormap_length;
+
+ unsigned char
+ colormap_size;
+
+ unsigned short
+ x_origin,
+ y_origin,
+ width,
+ height;
+
+ unsigned char
+ bits_per_pixel,
+ attributes;
+ } TargaInfo;
+
+ const ImageAttribute
+ *attribute;
+
+ size_t
+ count;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register long
+ i;
+
+ register unsigned char
+ *q;
+
+ TargaInfo
+ targa_info;
+
+ unsigned char
+ *targa_pixels;
+
+ unsigned int
+ write_grayscale,
+ status;
+
+ unsigned long
+ scene;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFalse)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ scene=0;
+ do
+ {
+ ImageCharacteristics
+ characteristics;
+
+ write_grayscale=MagickFalse;
+
+ /*
+ If requested output is grayscale, then write grayscale.
+ */
+ if ((image_info->type == GrayscaleType) ||
+ (image_info->type == GrayscaleMatteType))
+ write_grayscale=MagickTrue;
+
+ /*
+ Convert colorspace to an RGB-compatible type.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+
+ /*
+ Analyze image to be written.
+ */
+ (void) GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception);
+
+ /*
+ If some other type has not been requested and the image is
+ grayscale, then write a grayscale image unless the image
+ contains an alpha channel.
+ */
+ if (((image_info->type != TrueColorType) &&
+ (image_info->type != TrueColorMatteType) &&
+ (image_info->type != PaletteType) &&
+ (image->matte == MagickFalse)) &&
+ (characteristics.grayscale))
+ write_grayscale=MagickTrue;
+
+ /*
+ If there are too many colors for colormapped output or the
+ image contains an alpha channel, then promote to TrueColor.
+ */
+ if (((write_grayscale == MagickFalse) &&
+ (image->storage_class == PseudoClass) &&
+ (image->colors > 256)) ||
+ (image->matte == MagickTrue))
+ {
+ /* (void) SyncImage(image); */
+ image->storage_class=DirectClass;
+ }
+
+ /*
+ Initialize TGA raster file header.
+ */
+ targa_info.id_length=0;
+ attribute=GetImageAttribute(image,"comment");
+ if (attribute != (const ImageAttribute *) NULL)
+ {
+ unsigned char id_length =(unsigned char) strlen(attribute->value);
+ targa_info.id_length=Min(id_length,255);
+ }
+ targa_info.colormap_type=0;
+ targa_info.colormap_index=0;
+ targa_info.colormap_length=0;
+ targa_info.colormap_size=0;
+ targa_info.x_origin=0;
+ targa_info.y_origin=0;
+ targa_info.width=(unsigned short) image->columns;
+ targa_info.height=(unsigned short) image->rows;
+ targa_info.bits_per_pixel=8;
+ targa_info.attributes=0;
+ if (write_grayscale == MagickTrue)
+ {
+ /*
+ Grayscale without Colormap
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing Grayscale raster ...");
+ targa_info.image_type=TargaMonochrome;
+ targa_info.bits_per_pixel=8;
+ targa_info.colormap_type=0;
+ targa_info.colormap_index=0;
+ targa_info.colormap_length=0;
+ targa_info.colormap_size=0;
+ }
+ else if (image->storage_class == DirectClass)
+ {
+ /*
+ Full color TGA raster.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing TrueColor raster ...");
+
+ targa_info.image_type=TargaRGB;
+ targa_info.bits_per_pixel=24;
+ if (image->matte)
+ {
+ targa_info.bits_per_pixel=32;
+ targa_info.attributes=8; /* # of alpha bits */
+ }
+ }
+ else
+ {
+ /*
+ Colormapped TGA raster.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing ColorMapped raster ..." );
+ targa_info.image_type=TargaColormap;
+ targa_info.colormap_type=1;
+ targa_info.colormap_index=0;
+ targa_info.colormap_length=(unsigned short) image->colors;
+ targa_info.colormap_size=24;
+ }
+ /*
+ Write TGA header.
+ */
+ (void) WriteBlobByte(image,targa_info.id_length);
+ (void) WriteBlobByte(image,targa_info.colormap_type);
+ (void) WriteBlobByte(image,targa_info.image_type);
+ (void) WriteBlobLSBShort(image,targa_info.colormap_index);
+ (void) WriteBlobLSBShort(image,targa_info.colormap_length);
+ (void) WriteBlobByte(image,targa_info.colormap_size);
+ (void) WriteBlobLSBShort(image,targa_info.x_origin);
+ (void) WriteBlobLSBShort(image,targa_info.y_origin);
+ (void) WriteBlobLSBShort(image,targa_info.width);
+ (void) WriteBlobLSBShort(image,targa_info.height);
+ (void) WriteBlobByte(image,targa_info.bits_per_pixel);
+ (void) WriteBlobByte(image,targa_info.attributes);
+ if (targa_info.id_length != 0)
+ (void) WriteBlob(image,targa_info.id_length,attribute->value);
+ if (targa_info.image_type == TargaColormap)
+ {
+ unsigned char
+ *targa_colormap;
+
+ /*
+ Dump colormap to file (blue, green, red byte order).
+ */
+ targa_colormap=MagickAllocateArray(unsigned char *,
+ targa_info.colormap_length,3);
+ if (targa_colormap == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ q=targa_colormap;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ *q++=ScaleQuantumToChar(image->colormap[i].blue);
+ *q++=ScaleQuantumToChar(image->colormap[i].green);
+ *q++=ScaleQuantumToChar(image->colormap[i].red);
+ }
+ (void) WriteBlob(image,3*targa_info.colormap_length,
+ (char *) targa_colormap);
+ MagickFreeMemory(targa_colormap);
+ }
+ /*
+ Convert MIFF to TGA raster pixels.
+ */
+ count=(size_t) ((targa_info.bits_per_pixel*targa_info.width) >> 3);
+ targa_pixels=MagickAllocateMemory(unsigned char *,count);
+ if (targa_pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (y=(long) (image->rows-1); y >= 0; y--)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=targa_pixels;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (targa_info.image_type == TargaColormap)
+ {
+ /* Colormapped */
+ *q++=*indexes;
+ indexes++;
+ }
+ else if (targa_info.image_type == TargaMonochrome)
+ {
+ /* Grayscale */
+ if (image->storage_class == PseudoClass)
+ {
+ if (image->is_grayscale)
+ *q++=ScaleQuantumToChar(image->colormap[*indexes].red);
+ else
+ *q++=PixelIntensityToQuantum(&image->colormap[*indexes]);
+ indexes++;
+ }
+ else
+ {
+ if (image->is_grayscale)
+ *q++=ScaleQuantumToChar(p->red);
+ else
+ *q++=PixelIntensityToQuantum(p);
+ }
+ }
+ else
+ {
+ /* TrueColor RGB */
+ *q++=ScaleQuantumToChar(p->blue);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->red);
+ if (image->matte)
+ *q++=ScaleQuantumToChar(MaxRGB-p->opacity);
+ }
+ p++;
+ }
+ (void) WriteBlob(image,q-targa_pixels,(char *) targa_pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(targa_pixels);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename))
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(MagickTrue);
+}
diff --git a/coders/tiff.c b/coders/tiff.c
new file mode 100644
index 0000000..affab1d
--- /dev/null
+++ b/coders/tiff.c
@@ -0,0 +1,5613 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT IIIII FFFFF FFFFF %
+% T I F F %
+% T I FFF FFF %
+% T I F F %
+% T IIIII F F %
+% %
+% %
+% Read/Write TIFF Image Format. %
+% %
+% %
+% Original Software Design %
+% John Cristy %
+% July 1992 %
+% Re-Written For GraphicsMagick %
+% Bob Friesenhahn %
+% 2002-2015 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/bit_stream.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/quantize.h"
+#include "magick/resize.h"
+#include "magick/tempfile.h"
+#include "magick/tsd.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#if defined(HasTIFF)
+# if defined(HAVE_TIFFCONF_H)
+# include "tiffconf.h"
+# endif
+# include "tiff.h"
+# include "tiffio.h"
+# if !defined(COMPRESSION_ADOBE_DEFLATE)
+# define COMPRESSION_ADOBE_DEFLATE 8
+# endif /* !defined(COMPRESSION_ADOBE_DEFLATE) */
+
+/*
+ JPEG headers are needed in order to obtain BITS_IN_JSAMPLE
+*/
+# if !defined(_VISUALC_)
+# if defined(HasJPEG)
+# if defined(__MINGW32__)
+# define XMD_H 1
+# endif
+# undef HAVE_STDLIB_H
+# include <jpeglib.h>
+# endif /* defined(HasJPEG) */
+# endif /* !defined(_VISUALC_) */
+
+#if defined(TIFF_VERSION_BIG)
+# define HasBigTIFF 1
+#endif /* defined(TIFF_BIGTIFF_VERSION) */
+
+/*
+ Set to 1 in order to log low-level BLOB I/O at "coder" level.
+*/
+#if !defined(LOG_TIFF_BLOB_IO)
+# define LOG_TIFF_BLOB_IO 0
+#endif /* !defined(LOG_TIFF_BLOB_IO) */
+
+#if !defined(PREDICTOR_NONE)
+#define PREDICTOR_NONE 1
+#endif
+#if !defined(PREDICTOR_HORIZONTAL)
+#define PREDICTOR_HORIZONTAL 2
+#endif
+#if !defined(PREDICTOR_FLOATINGPOINT)
+#define PREDICTOR_FLOATINGPOINT 3
+#endif
+#if !defined(SAMPLEFORMAT_COMPLEXINT)
+#define SAMPLEFORMAT_COMPLEXINT 5
+#endif
+#if !defined(SAMPLEFORMAT_COMPLEXIEEEFP)
+#define SAMPLEFORMAT_COMPLEXIEEEFP 6
+#endif
+
+#if !defined(TIFFTAG_COPYRIGHT)
+#define TIFFTAG_COPYRIGHT 33432
+#endif
+#if !defined(TIFFTAG_OPIIMAGEID)
+#define TIFFTAG_OPIIMAGEID 32781
+#endif
+
+/*
+ Global declarations.
+*/
+static MagickTsdKey_t tsd_key = (MagickTsdKey_t) 0;
+
+/* static ExceptionInfo */
+/* *tiff_exception; */
+
+typedef struct _Magick_TIFF_ClientData
+{
+ Image
+ *image;
+
+ const ImageInfo
+ *image_info;
+} Magick_TIFF_ClientData;
+
+/*
+ Forward declarations.
+*/
+static tsize_t
+ TIFFReadBlob(thandle_t,tdata_t,tsize_t);
+
+static MagickPassFail
+ WriteGROUP4RAWImage(const ImageInfo *image_info,Image *image),
+ WritePTIFImage(const ImageInfo *,Image *),
+ WriteTIFFImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s T I F F %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsTIFF returns True if the image format type, identified by the
+% magick string, is TIFF.
+%
+% The format of the IsTIFF method is:
+%
+% MagickBool IsTIFF(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsTIFF returns MagickTrue if the image format type
+% is TIFF.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static MagickBool
+IsTIFF(const unsigned char *magick,const size_t length)
+{
+ if (length < 8)
+ return(False);
+
+ /* Big endian Classic TIFF*/
+ if (memcmp(magick,"\115\115\000\052",4) == 0)
+ return(True);
+
+ /* Little endian Classic TIFF */
+ if (memcmp(magick,"\111\111\052\000",4) == 0)
+ return(True);
+
+#if defined(HasBigTIFF)
+ /*
+ * From http://www.remotesensing.org/libtiff/bigtiffdesign.html
+ *
+ * * The Version ID, in header bytes 2-3, formerly decimal 42, now changes to 43
+ * * Header bytes 4-5 contain the decimal number 8.
+ * - If there is some other number here, a reader should give up.
+ * - This is to provide a nice way to move to 16-byte pointers some day.
+ *
+ * * Header bytes 6-7 are reserved and must be zero.
+ * - If they're not, a reader should give up.
+ *
+ * Also http://www.awaresystems.be/imaging/tiff/bigtiff.html
+ */
+
+ /* Big endian BigTIFF*/
+ if (memcmp(magick,"\115\115\000\053\000\010\000\000",8) == 0)
+ return(True);
+
+ /* Little endian BigTIFF */
+ if (memcmp(magick,"\111\111\053\000\010\000\000\000",8) == 0)
+ return(True);
+#endif
+
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d T I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadTIFFImage reads a Tagged image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadTIFFImage method is:
+%
+% Image *ReadTIFFImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadTIFFImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#if defined(HAVE_TIFFMERGEFIELDINFO) && defined(HAVE_TIFFSETTAGEXTENDER)
+# define EXTEND_TIFF_TAGS 1
+# if !defined(TIFFTAG_EXIFIFD)
+# define TIFFTAG_EXIFIFD 34665
+# endif
+# if TIFFLIB_VERSION < 20050704
+/* It seems that support was added for the EXIFIFDOffset tag in
+ libtiff release 3-7-3 which corresponds with TIFFLIB_VERSION
+ 20050704 */
+static const TIFFFieldInfo
+ ExtensionTiffFieldInfo[] =
+ {
+ {
+ TIFFTAG_EXIFIFD, -1, -1, TIFF_LONG, FIELD_CUSTOM,
+ MagickFalse, MagickTrue, "EXIFIFDOffset"
+ }
+ };
+# endif
+
+/*
+ Ignore specific tags
+*/
+static void
+TIFFIgnoreTags(TIFF *tiff)
+{
+ char
+ *q;
+
+ const char
+ *p,
+ *tags;
+
+ const ImageInfo
+ *image_info;
+
+ register ssize_t
+ i;
+
+ size_t
+ count;
+
+ TIFFFieldInfo
+ *ignore;
+
+ if (TIFFGetReadProc(tiff) != TIFFReadBlob)
+ return;
+
+ image_info=((Magick_TIFF_ClientData *)TIFFClientdata(tiff))->image_info;
+ tags=AccessDefinition(image_info,"tiff","ignore-tags");
+ if (tags == (const char *) NULL)
+ return;
+ count=0;
+ p=tags;
+ while (*p != '\0')
+ {
+ while ((isspace((int) ((unsigned char) *p)) != 0))
+ p++;
+
+ {
+ /* Avoid warning about unused strtol return value on Linux */
+ long ignored = strtol(p,&q,10);
+ (void) ignored;
+ }
+ if (p == q)
+ return;
+
+ p=q;
+ count++;
+
+ while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
+ p++;
+ }
+ if (count == 0)
+ return;
+ i=0;
+ p=tags;
+ ignore=MagickAllocateArray(TIFFFieldInfo*,count,sizeof(*ignore));
+ /* This also sets field_bit to 0 (FIELD_IGNORE) */
+ (void) memset(ignore,0,count*sizeof(*ignore));
+ while (*p != '\0')
+ {
+ while ((isspace((int) ((unsigned char) *p)) != 0))
+ p++;
+
+ ignore[i].field_tag=(ttag_t) strtol(p,&q,10);
+
+ p=q;
+ i++;
+
+ while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
+ p++;
+ }
+ (void) TIFFMergeFieldInfo(tiff,ignore,(uint32) count);
+ MagickFreeMemory(ignore);
+}
+
+/*
+ Merge in our new fields and then call the next extender if there is
+ one in effect.
+*/
+static TIFFExtendProc _ParentExtender = NULL;
+static void
+ExtensionTagsDefaultDirectory(TIFF *tif)
+{
+# if TIFFLIB_VERSION < 20050704
+ /* Install the extended Tag field info */
+ TIFFMergeFieldInfo(tif, ExtensionTiffFieldInfo,
+ sizeof(ExtensionTiffFieldInfo)/
+ sizeof(ExtensionTiffFieldInfo[0]));
+# endif
+
+ /* Since an XTIFF client module may have overridden
+ * the default directory method, we call it now to
+ * allow it to set up the rest of its own methods.
+ */
+ if (_ParentExtender)
+ (*_ParentExtender)(tif);
+ TIFFIgnoreTags(tif);
+}
+
+/*
+ Obtain the current handler at the front of the chain, and register
+ ourselves as the new first handler.
+*/
+static
+void ExtensionTagsInitialize(void)
+{
+ static int
+ first_time=1;
+
+ if (! first_time) return; /* Been there. Done that. */
+ first_time = 0;
+
+ /* Grab the inherited method and install */
+ _ParentExtender = TIFFSetTagExtender(ExtensionTagsDefaultDirectory);
+}
+
+#endif /* defined(HAVE_TIFFMERGEFIELDINFO) && defined(HAVE_TIFFSETTAGEXTENDER) */
+
+/*
+ Return MagickTrue if libtiff supports the indicated compression type.
+ Sets buffer pointed to by 'compression_name' to the name of the compression.
+*/
+static MagickBool
+CompressionSupported(const CompressionType compression,
+ char *compression_name)
+{
+ uint16
+ compress_tag;
+
+ MagickBool
+ status;
+
+ status = MagickFalse;
+ compress_tag=COMPRESSION_NONE;
+ strlcpy(compression_name,"Undefined",MaxTextExtent);
+
+ /*
+ This switch statement should match all the values of CompressionType.
+ */
+ switch (compression)
+ {
+ case UndefinedCompression:
+ {
+ strlcpy(compression_name,"Undefined",MaxTextExtent);
+ break;
+ }
+ case NoCompression:
+ {
+ strlcpy(compression_name,"No",MaxTextExtent);
+ compress_tag=COMPRESSION_NONE;
+ status=MagickTrue;
+ break;
+ }
+ case BZipCompression:
+ {
+ strlcpy(compression_name,"BZip",MaxTextExtent);
+ break;
+ }
+ case FaxCompression:
+ {
+ strlcpy(compression_name,"Group3 FAX",MaxTextExtent);
+#if defined(COMPRESSION_CCITTFAX3)
+ compress_tag=COMPRESSION_CCITTFAX3;
+ status=MagickTrue;
+#endif
+ break;
+ }
+ case Group4Compression:
+ {
+ strlcpy(compression_name,"Group4 FAX",MaxTextExtent);
+#if defined(COMPRESSION_CCITTFAX4)
+ compress_tag=COMPRESSION_CCITTFAX4;
+ status=MagickTrue;
+#endif
+ break;
+ }
+ case JBIG1Compression:
+ {
+ strlcpy(compression_name,"JBIG",MaxTextExtent);
+#if defined(COMPRESSION_JBIG)
+ compress_tag=COMPRESSION_JBIG;
+ status=MagickTrue;
+#endif
+ break;
+ }
+ case JBIG2Compression:
+ {
+ strlcpy(compression_name,"JBIG2",MaxTextExtent);
+ break;
+ }
+ case JPEGCompression:
+ {
+ strlcpy(compression_name,"JPEG",MaxTextExtent);
+#if defined(COMPRESSION_JPEG)
+ compress_tag=COMPRESSION_JPEG;
+ status=MagickTrue;
+#endif
+ break;
+ }
+ case JPEG2000Compression:
+ {
+ strlcpy(compression_name,"JPEG2000",MaxTextExtent);
+ break;
+ }
+ case LosslessJPEGCompression:
+ {
+ strlcpy(compression_name,"Lossless JPEG",MaxTextExtent);
+ break;
+ }
+ case LZMACompression:
+ {
+ strlcpy(compression_name,"LZMA",MaxTextExtent);
+#if defined(COMPRESSION_LZMA)
+ compress_tag=COMPRESSION_LZMA;
+ status=MagickTrue;
+#endif
+ break;
+ }
+ case LZWCompression:
+ {
+ strlcpy(compression_name,"LZW",MaxTextExtent);
+#if defined(COMPRESSION_LZW)
+ compress_tag=COMPRESSION_LZW;
+ status=MagickTrue;
+#endif
+ break;
+ }
+ case RLECompression:
+ {
+ strlcpy(compression_name,"Macintosh RLE (Packbits)",MaxTextExtent);
+#if defined(COMPRESSION_PACKBITS)
+ compress_tag=COMPRESSION_PACKBITS;
+ status=MagickTrue;
+#endif
+ break;
+ }
+ case ZipCompression:
+ {
+ strlcpy(compression_name,"Adobe Deflate",MaxTextExtent);
+#if defined(COMPRESSION_ADOBE_DEFLATE)
+ compress_tag=COMPRESSION_ADOBE_DEFLATE;
+ status=MagickTrue;
+#endif
+ break;
+ }
+ }
+
+ if (MagickTrue == status)
+ {
+#if defined(HAVE_TIFFISCODECCONFIGURED) || (TIFFLIB_VERSION > 20040919)
+ if (compress_tag != COMPRESSION_NONE)
+ {
+ /*
+ Returns 1 if the codec is configured and
+ working. Otherwise 0 will be returned.
+ */
+ if (!TIFFIsCODECConfigured(compress_tag))
+ status = MagickFalse;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFFIsCODECConfigured says support for %s "
+ "compression %s configured.",
+ compression_name,
+ (status == MagickTrue ? "is" : "is not"));
+ }
+#else
+ switch (compress_tag)
+ {
+# if defined(CCITT_SUPPORT)
+ case COMPRESSION_CCITTFAX3:
+ case COMPRESSION_CCITTFAX4:
+# endif
+# if defined(YCBCR_SUPPORT) && defined(JPEG_SUPPORT)
+ case COMPRESSION_JPEG:
+# endif
+# if defined(LZW_SUPPORT)
+ case COMPRESSION_LZW:
+# endif
+# if defined(PACKBITS_SUPPORT)
+ case COMPRESSION_PACKBITS:
+# endif
+# if defined(ZIP_SUPPORT)
+ case COMPRESSION_ADOBE_DEFLATE:
+# endif
+ case COMPRESSION_NONE:
+ {
+ status = MagickTrue;
+ break;
+ }
+ default:
+ {
+ status = MagickFalse;
+ break;
+ }
+ }
+#endif
+ }
+ return status;
+}
+
+/*
+ Convert a libtiff compression tag to a human readable string.
+*/
+static const char *
+CompressionTagToString(unsigned int compress_tag)
+{
+ const char
+ *result = "Unknown";
+
+ switch (compress_tag)
+ {
+ case COMPRESSION_ADOBE_DEFLATE:
+ result="ZIP deflate (Adobe)";
+ break;
+#if defined(COMPRESSION_DEFLATE)
+ case COMPRESSION_DEFLATE:
+ result="ZIP deflate (Pixar)";
+ break;
+#endif
+ case COMPRESSION_CCITTFAX3:
+ result="CCITT Group 3 fax";
+ break;
+ case COMPRESSION_CCITTFAX4:
+ result="CCITT Group 4 fax";
+ break;
+ case COMPRESSION_CCITTRLE:
+ result="CCITT modified Huffman RLE";
+ break;
+ case COMPRESSION_CCITTRLEW:
+ result="CCITT modified Huffman RLE (Word aligned)";
+ break;
+#if defined(COMPRESSION_OJPEG)
+ case COMPRESSION_OJPEG:
+ result="JPEG DCT (Old)";
+ break;
+#endif
+ case COMPRESSION_JPEG:
+ result="JPEG DCT";
+ break;
+#if defined(COMPRESSION_JBIG)
+ case COMPRESSION_JBIG:
+ result="JBIG";
+ break;
+#endif
+ case COMPRESSION_LZW:
+ result="LZW";
+ break;
+#if defined(COMPRESSION_NEXT)
+ case COMPRESSION_NEXT:
+ result="NeXT 2-bit RLE";
+ break;
+#endif
+ case COMPRESSION_NONE:
+ result="not compressed";
+ break;
+ case COMPRESSION_PACKBITS:
+ result="Macintosh RLE (Packbits)";
+ break;
+#if defined(COMPRESSION_THUNDERSCAN)
+ case COMPRESSION_THUNDERSCAN:
+ result="ThunderScan RLE";
+ break;
+#endif
+ }
+ return result;
+}
+
+static const char *
+PhotometricTagToString(unsigned int photometric)
+{
+ const char
+ *result = "Unknown";
+
+ switch (photometric)
+ {
+ case PHOTOMETRIC_CIELAB:
+ result="CIELAB";
+ break;
+ case PHOTOMETRIC_LOGL:
+ result="CIE Log2(L)";
+ break;
+ case PHOTOMETRIC_LOGLUV:
+ result="LOGLUV";
+ break;
+#if defined(PHOTOMETRIC_MASK)
+ case PHOTOMETRIC_MASK:
+ result="MASK";
+ break;
+#endif
+ case PHOTOMETRIC_MINISBLACK:
+ result="MINISBLACK";
+ break;
+ case PHOTOMETRIC_MINISWHITE:
+ result="MINISWHITE";
+ break;
+ case PHOTOMETRIC_PALETTE:
+ result="PALETTE";
+ break;
+ case PHOTOMETRIC_RGB:
+ result="RGB";
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ result="SEPARATED";
+ break;
+ case PHOTOMETRIC_YCBCR:
+ result="YCBCR";
+ break;
+ }
+
+ return result;
+}
+
+static unsigned int
+ReadNewsProfile(char *text,long int length,Image *image,int type)
+{
+ register unsigned char
+ *p;
+
+ if (length <= 0)
+ return(False);
+ p=(unsigned char *) text;
+ if (type == TIFFTAG_RICHTIFFIPTC)
+ {
+ /*
+ Handle IPTC tag.
+ */
+ length*=4;
+ return SetImageProfile(image,"IPTC",p,(size_t) length);
+ }
+ /*
+ Handle PHOTOSHOP tag.
+ */
+ while (length > 0)
+ {
+#if defined(GET_ONLY_IPTC_DATA)
+ if (LocaleNCompare((char *) p,"8BIM44",6) == 0)
+#else
+ if (LocaleNCompare((char *) p,"8BIM",4) == 0)
+#endif
+ break;
+ length-=2;
+ p+=2;
+ }
+ if (length <= 0)
+ return(False);
+#if defined(GET_ONLY_IPTC_DATA)
+ /*
+ Eat OSType, IPTC ID code, and Pascal string length bytes.
+ */
+ p+=6;
+ length=(*p++);
+ if (length)
+ p+=length;
+ if ((length & 0x01) == 0)
+ p++; /* align to an even byte boundary */
+ length=(p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ p+=4;
+#endif
+ return SetImageProfile(image,"8BIM",p,(size_t) length);
+}
+
+/*
+ Return MagickTrue if TIFF warnings should be thrown as a warning
+ exception rather than logged.
+*/
+static MagickBool
+CheckThrowWarnings(const ImageInfo *image_info)
+{
+ const char *
+ definition_value;
+
+ MagickBool
+ report_warnings=MagickFalse;
+
+ if ((definition_value=AccessDefinition(image_info,"tiff","report-warnings")))
+ {
+ if (LocaleCompare(definition_value,"TRUE") == 0)
+ report_warnings=MagickTrue;
+ }
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reporting TIFF warnings via %s",
+ (report_warnings ? "exception" :
+ "log message"));
+
+ return report_warnings;
+}
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Close BLOB */
+static int
+TIFFCloseBlob(thandle_t image_handle)
+{
+ Image
+ *image = ((Magick_TIFF_ClientData *) image_handle)->image;
+
+#if LOG_TIFF_BLOB_IO
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"TIFF close blob");
+#endif /* LOG_TIFF_BLOB_IO */
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(0);
+}
+
+/* Report errors. */
+static unsigned int
+TIFFErrors(const char *module,const char *format,
+ va_list warning)
+{
+ ExceptionInfo
+ *tiff_exception;
+
+ char
+ message[MaxTextExtent];
+
+ errno=0;
+ (void) vsnprintf(message,MaxTextExtent-2,format,warning);
+ message[MaxTextExtent-2]='\0';
+ (void) strlcat(message,".",MaxTextExtent);
+ tiff_exception=(ExceptionInfo *) MagickTsdGetSpecific(tsd_key);
+ ThrowException2(tiff_exception,CoderError,message,module);
+ return(True);
+}
+
+/* Memory map entire input file in read-only mode. */
+static int
+TIFFMapBlob(thandle_t image_handle,tdata_t *base,toff_t *size)
+{
+ Image
+ *image = ((Magick_TIFF_ClientData *) image_handle)->image;
+
+ *base = (tdata_t *) GetBlobStreamData(image);
+ if (*base)
+ *size = (toff_t) GetBlobSize(image);
+
+ if (*base)
+ {
+#if LOG_TIFF_BLOB_IO
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF mapped blob: base=0x%p size=%" MAGICK_OFF_F
+ "d",*base, (magick_off_t) *size);
+#endif
+ return 1;
+ }
+ return(0);
+}
+
+/* Read BLOB data at current offset */
+static tsize_t
+TIFFReadBlob(thandle_t image_handle,tdata_t data,tsize_t size)
+{
+ Image
+ *image = ((Magick_TIFF_ClientData *) image_handle)->image;
+
+ tsize_t
+ result;
+
+ result=(tsize_t) ReadBlob(image,(size_t) size,data);
+
+#if LOG_TIFF_BLOB_IO
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF read blob: data=0x%p size=%"
+ MAGICK_SIZE_T_F "u, returns %"
+ MAGICK_SIZE_T_F "u",
+ data, (MAGICK_SIZE_T) size,
+ (MAGICK_SIZE_T) result);
+#endif /* LOG_TIFF_BLOB_IO */
+
+ return result;
+}
+
+/* Seek to BLOB offset */
+static toff_t
+TIFFSeekBlob(thandle_t image_handle,toff_t offset,int whence)
+{
+ Image
+ *image = ((Magick_TIFF_ClientData *) image_handle)->image;
+
+ toff_t
+ result;
+
+ result=SeekBlob(image,offset,whence);
+#if LOG_TIFF_BLOB_IO
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF seek blob: offset=%" MAGICK_OFF_F
+ "u whence=%d (%s), returns %" MAGICK_OFF_F "d",
+ (magick_off_t) offset,
+ whence,
+ (whence == SEEK_SET ? "SET" :
+ (whence == SEEK_CUR ? "CUR" :
+ (whence == SEEK_END ? "END" : "unknown"))),
+ (magick_off_t) result);
+#endif /* LOG_TIFF_BLOB_IO */
+ return result;
+}
+
+/* Obtain BLOB size */
+static toff_t
+TIFFGetBlobSize(thandle_t image_handle)
+{
+ Image
+ *image = ((Magick_TIFF_ClientData *) image_handle)->image;
+
+ toff_t
+ result;
+
+ result=(toff_t) GetBlobSize(image);
+
+#if LOG_TIFF_BLOB_IO
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF get blob size returns %" MAGICK_OFF_F "d",
+ (magick_off_t) result);
+#endif /* LOG_TIFF_BLOB_IO */
+
+ return result;
+}
+
+/* Unmap BLOB memory */
+static void
+TIFFUnmapBlob(thandle_t image,
+ tdata_t base,
+ toff_t size)
+{
+#if LOG_TIFF_BLOB_IO
+ Image
+ *image = ((Magick_TIFF_ClientData *) image_handle)->image;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF unmap blob: base=0x%p size=%" MAGICK_OFF_F "d",
+ base,(magick_off_t) size);
+#else
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(base);
+ ARG_NOT_USED(size);
+#endif /* LOG_TIFF_BLOB_IO */
+}
+
+/* Report warnings as a coder log message. */
+static unsigned int
+TIFFWarningsLogOnly(const char *module,const char *format,va_list warning)
+{
+/* ExceptionInfo */
+/* *tiff_exception; */
+
+ char
+ message[MaxTextExtent];
+
+ (void) module;
+ errno=0;
+ (void) vsnprintf(message,MaxTextExtent-2,format,warning);
+ message[MaxTextExtent-2]='\0';
+ (void) strlcat(message,".",MaxTextExtent);
+/* tiff_exception=(ExceptionInfo *) MagickTsdGetSpecific(tsd_key); */
+/* ThrowException2(tiff_exception,CoderWarning,message,module); */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF Warning: %s",message);
+ return(True);
+}
+
+/* Report warnings as exception in thread-specific ExceptionInfo */
+static unsigned int
+TIFFWarningsThrowException(const char *module,const char *format,va_list warning)
+{
+ ExceptionInfo
+ *tiff_exception;
+
+ char
+ message[MaxTextExtent];
+
+ (void) module;
+ errno=0;
+ (void) vsnprintf(message,MaxTextExtent-2,format,warning);
+ message[MaxTextExtent-2]='\0';
+ (void) strlcat(message,".",MaxTextExtent);
+ tiff_exception=(ExceptionInfo *) MagickTsdGetSpecific(tsd_key);
+ ThrowException2(tiff_exception,CoderWarning,message,module);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF Warning: %s",message);
+ return(True);
+}
+
+/* Write data at current offset */
+static tsize_t
+TIFFWriteBlob(thandle_t image_handle,tdata_t data,tsize_t size)
+{
+ Image
+ *image = ((Magick_TIFF_ClientData *) image_handle)->image;
+
+ tsize_t
+ result;
+
+ result=(tsize_t) WriteBlob(image,(size_t) size,data);
+
+#if LOG_TIFF_BLOB_IO
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF write blob: data=0x%p size=%" MAGICK_SIZE_T_F
+ "u, returns %" MAGICK_SIZE_T_F "u",
+ data, (MAGICK_SIZE_T) size,
+ (MAGICK_SIZE_T) result);
+#endif /* LOG_TIFF_BLOB_IO */
+
+ return result;
+}
+
+/*
+ Convert TIFF data from libtiff "native" format to byte-parsable big endian
+*/
+#if !defined(WORDS_BIGENDIAN)
+static void
+SwabDataToBigEndian(const uint16 bits_per_sample, tdata_t data,
+ const tsize_t size)
+{
+ if (bits_per_sample == 64U)
+ {
+ TIFFSwabArrayOfDouble((double*) data,
+ NumberOfObjectsInArray(size,sizeof(double)));
+ }
+ else if (bits_per_sample == 32U)
+ {
+ TIFFSwabArrayOfLong((uint32*) data,
+ NumberOfObjectsInArray(size,sizeof(uint32)));
+ }
+#if defined(HAVE_TIFFSWABARRAYOFTRIPLES)
+ /* New libtiff function to swap 24 bit values. Grumble ... */
+ else if (bits_per_sample == 24U)
+ {
+ TIFFSwabArrayOfTriples(data,
+ NumberOfObjectsInArray(size,3));
+ }
+#endif
+ else if (bits_per_sample == 16U)
+ {
+ TIFFSwabArrayOfShort((uint16*) data,
+ NumberOfObjectsInArray(size,sizeof(uint16)));
+ }
+}
+#endif
+
+/*
+ Convert TIFF data from byte-parsable big endian to libtiff "native" format.
+*/
+#if !defined(WORDS_BIGENDIAN)
+static void
+SwabDataToNativeEndian(const uint16 bits_per_sample, tdata_t data,
+ const tsize_t size)
+{
+ if (bits_per_sample == 64)
+ {
+ TIFFSwabArrayOfDouble((double*) data,
+ NumberOfObjectsInArray(size,sizeof(double)));
+ }
+ else if (bits_per_sample == 32)
+ {
+ TIFFSwabArrayOfLong((uint32*) data,
+ NumberOfObjectsInArray(size,sizeof(uint32)));
+ }
+#if defined(HAVE_TIFFSWABARRAYOFTRIPLES)
+ /* New libtiff function to swap 24 bit values. Grumble ... */
+ else if (bits_per_sample == 24U)
+ {
+ TIFFSwabArrayOfTriples(data,
+ NumberOfObjectsInArray(size,3));
+ }
+#endif
+ else if (bits_per_sample == 16)
+ {
+ TIFFSwabArrayOfShort((uint16*) data,
+ NumberOfObjectsInArray(size,sizeof(uint16)));
+ }
+}
+#endif
+
+/*
+ Initialize the image colormap.
+*/
+static MagickPassFail
+InitializeImageColormap(Image *image, TIFF *tiff)
+{
+ uint16
+ bits_per_sample,
+ photometric;
+
+ register unsigned int
+ i;
+
+ unsigned int
+ max_sample_value,
+ status = MagickFail;
+
+ if (TIFFGetFieldDefaulted(tiff,TIFFTAG_BITSPERSAMPLE,&bits_per_sample) != 1)
+ return status;
+ if (TIFFGetFieldDefaulted(tiff,TIFFTAG_PHOTOMETRIC,&photometric) != 1)
+ return status;
+
+ /*
+ Compute colormap size
+ */
+ max_sample_value=MaxValueGivenBits(bits_per_sample);
+
+ image->colors=0;
+ if (MaxColormapSize > max_sample_value)
+ image->colors=max_sample_value+1;
+ else if (MaxColormapSize > MaxRGB)
+ {
+ if (photometric == PHOTOMETRIC_PALETTE)
+ return status;
+ else
+ image->colors=MaxColormapSize;
+ }
+
+ if (image->colors > 0)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Allocating colormap with %u colors",
+ image->colors);
+
+ /*
+ Allocate colormap.
+ */
+ if (AllocateImageColormap(image,image->colors) == MagickFail)
+ return status;
+
+ /*
+ Create colormap.
+ */
+ switch (photometric)
+ {
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_MINISWHITE:
+ default:
+ {
+ /*
+ Ascending order produced by AllocateImageColormap() is sufficient.
+ */
+ status = MagickPass;
+ break;
+ }
+ case PHOTOMETRIC_PALETTE:
+ {
+ long
+ range;
+
+ uint16
+ *blue_colormap,
+ *green_colormap,
+ *red_colormap;
+
+ (void) TIFFGetField(tiff,TIFFTAG_COLORMAP,&red_colormap,
+ &green_colormap,&blue_colormap);
+ range=256L; /* might be old style 8-bit colormap */
+ for (i=0; i < image->colors; i++)
+ if ((red_colormap[i] >= 256) || (green_colormap[i] >= 256) ||
+ (blue_colormap[i] >= 256))
+ {
+ range=65535L;
+ break;
+ }
+ for (i=0; i < image->colors; i++)
+ {
+ image->colormap[i].red=(Quantum)
+ (((double) MaxRGB*red_colormap[i])/range+0.5);
+ image->colormap[i].green=(Quantum)
+ (((double) MaxRGB*green_colormap[i])/range+0.5);
+ image->colormap[i].blue=(Quantum)
+ (((double) MaxRGB*blue_colormap[i])/range+0.5);
+ }
+ status = MagickPass;
+ break;
+ }
+ }
+ if (status == MagickPass)
+ {
+ register const PixelPacket
+ *p;
+
+ register unsigned int
+ scale;
+
+ unsigned int
+ depth=1;
+
+ /*
+ Evaluate colormap depth.
+ */
+ p=image->colormap;
+ scale=MaxRGB / (MaxRGB >> (QuantumDepth-depth));
+ for (i=image->colors; i != 0; i--)
+ {
+ if ((p->red != scale*(p->red/scale)) ||
+ (p->green != scale*(p->green/scale)) ||
+ (p->blue != scale*(p->blue/scale)))
+ {
+ depth++;
+ if (depth == QuantumDepth)
+ break;
+ scale=MaxRGB / (MaxRGB >> (QuantumDepth-depth));
+ continue;
+ }
+ p++;
+ }
+ if (depth < 8)
+ depth=8;
+ else
+ depth=16;
+ image->depth=depth;
+ }
+ }
+
+ return status;
+}
+
+/*
+ Determine the quauntum import/export method to use with
+ ImportImagePixelArea() and ExportImagePixelArea() based on the
+ nature of the image, the TIFF photometric, sample format, samples
+ per pixel, the desired planar configuration, and the specified plane
+ (0 for contiguous planar configuration). Updates quantum_type with
+ the import/export method, and quantum_samples with the number of
+ samples consumed by one pixel. Returns MagickPass if the photometric
+ is supported.
+*/
+static MagickPassFail
+QuantumTransferMode(const Image *image,
+ const uint16 photometric,
+ const uint16 compress_tag,
+ const uint16 sample_format,
+ const unsigned int samples_per_pixel,
+ const uint16 planar_config,
+ const unsigned int plane,
+ QuantumType *quantum_type,
+ int *quantum_samples,
+ ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+
+ *quantum_type=UndefinedQuantum;
+ *quantum_samples=0;
+ if ((sample_format == SAMPLEFORMAT_INT) ||
+ (sample_format == SAMPLEFORMAT_UINT) ||
+ (sample_format == SAMPLEFORMAT_VOID) ||
+ (sample_format == SAMPLEFORMAT_IEEEFP))
+ {
+ switch (photometric)
+ {
+ case PHOTOMETRIC_CIELAB:
+ {
+ /* samples_per_pixel may be 1 or 3 */
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ switch (plane)
+ {
+ case 0:
+ if (samples_per_pixel == 1)
+ *quantum_type=GrayQuantum;
+ else
+ *quantum_type=RedQuantum;
+ break;
+ case 1:
+ *quantum_type=GreenQuantum;
+ break;
+ case 2:
+ *quantum_type=BlueQuantum;
+ break;
+ case 3:
+ *quantum_type=AlphaQuantum;
+ break;
+ }
+ *quantum_samples=1;
+ }
+ else
+ {
+ if (samples_per_pixel == 1)
+ {
+ if (image->matte)
+ {
+ *quantum_type=GrayAlphaQuantum;
+ *quantum_samples=2;
+ }
+ else
+ {
+ *quantum_type=GrayQuantum;
+ *quantum_samples=1;
+ }
+ }
+ else
+ {
+ if (image->matte)
+ {
+ *quantum_type=RGBAQuantum;
+ *quantum_samples=4;
+ }
+ else
+ {
+ *quantum_type=RGBQuantum;
+ *quantum_samples=3;
+ }
+ }
+ }
+ break;
+ }
+ case PHOTOMETRIC_LOGL:
+ {
+ *quantum_type=CIEYQuantum;
+ *quantum_samples=1;
+ break;
+ }
+ case PHOTOMETRIC_LOGLUV:
+ {
+ if (samples_per_pixel == 1)
+ {
+ /* FIXME: this might not work. */
+ *quantum_type=CIEYQuantum;
+ *quantum_samples=1;
+ }
+ else
+ {
+ *quantum_type=CIEXYZQuantum;
+ *quantum_samples=3;
+ }
+ break;
+ }
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_MINISWHITE:
+ {
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ switch (plane)
+ {
+ case 0:
+ *quantum_type=GrayQuantum;
+ *quantum_samples=1;
+ break;
+ case 1:
+ *quantum_type=AlphaQuantum;
+ *quantum_samples=1;
+ break;
+ }
+ }
+ else
+ {
+ if (image->matte)
+ {
+ *quantum_type=GrayAlphaQuantum;
+ *quantum_samples=2;
+ }
+ else
+ {
+ *quantum_type=GrayQuantum;
+ *quantum_samples=1;
+ }
+ }
+ break;
+ }
+ case PHOTOMETRIC_PALETTE:
+ {
+ if (sample_format == SAMPLEFORMAT_UINT)
+ {
+ if (image->matte)
+ {
+ *quantum_type=IndexAlphaQuantum;
+ *quantum_samples=2;
+ }
+ else
+ {
+ *quantum_type=IndexQuantum;
+ *quantum_samples=1;
+ }
+ }
+ break;
+ }
+ case PHOTOMETRIC_RGB:
+ {
+ if (compress_tag != COMPRESSION_OJPEG)
+ {
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ switch (plane)
+ {
+ case 0:
+ *quantum_type=RedQuantum;
+ break;
+ case 1:
+ *quantum_type=GreenQuantum;
+ break;
+ case 2:
+ *quantum_type=BlueQuantum;
+ break;
+ case 3:
+ *quantum_type=AlphaQuantum;
+ break;
+ }
+ *quantum_samples=1;
+ }
+ else
+ {
+ if (image->matte)
+ {
+ *quantum_type=RGBAQuantum;
+ *quantum_samples=4;
+ }
+ else
+ {
+ *quantum_type=RGBQuantum;
+ *quantum_samples=3;
+ }
+ }
+ }
+ break;
+ }
+ case PHOTOMETRIC_SEPARATED:
+ {
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ switch (plane)
+ {
+ case 0:
+ *quantum_type=CyanQuantum;
+ break;
+ case 1:
+ *quantum_type=MagentaQuantum;
+ break;
+ case 2:
+ *quantum_type=YellowQuantum;
+ break;
+ case 3:
+ *quantum_type=BlackQuantum;
+ break;
+ case 4:
+ *quantum_type=AlphaQuantum;
+ break;
+ }
+ *quantum_samples=1;
+ }
+ else
+ {
+ if (image->matte)
+ {
+ *quantum_type=CMYKAQuantum;
+ *quantum_samples=5;
+ }
+ else
+ {
+ *quantum_type=CMYKQuantum;
+ *quantum_samples=4;
+ }
+ }
+ break;
+ }
+ case PHOTOMETRIC_YCBCR:
+ {
+ /*
+ This is here to support JPEGCOLORMODE_RGB which claims a
+ YCbCr photometric, but passes RGB to libtiff.
+ */
+ if (compress_tag == COMPRESSION_JPEG)
+ {
+ *quantum_type=RGBQuantum;
+ *quantum_samples=3;
+ }
+ break;
+ }
+ }
+ }
+ /* fprintf(stderr,"Quantum Type: %d Quantum Samples: %d\n",(int) *quantum_type,*quantum_samples); */
+ /* FIXME: We do need to support YCbCr! */
+
+ if (*quantum_samples != 0)
+ {
+ /*
+ Enforce that there are no buffer-overruns.
+ */
+ if (((planar_config == PLANARCONFIG_SEPARATE) && (*quantum_samples != 1)) ||
+ ((unsigned int) (*quantum_samples) > samples_per_pixel))
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Expected >= %u samples per pixel, have only %d!",
+ *quantum_samples, samples_per_pixel);
+ ThrowException(exception,CorruptImageError,ImproperImageHeader,
+ image->filename);
+ *quantum_type=UndefinedQuantum;
+ *quantum_samples=0;
+ }
+ }
+
+ return (*quantum_samples != 0 ? MagickPass : MagickFail);
+}
+
+/*
+ Compact samples to only contain raster data. This may seem
+ inefficient, but it allows us to easily deal with contiguous images
+ which contain extra samples while optimizing performance for images
+ without extra samples.
+*/
+static void
+CompactSamples( const unsigned long total_pixels,
+ const unsigned int bits_per_sample,
+ const unsigned int samples_per_pixel,
+ const unsigned int quantum_samples,
+ unsigned char *samples)
+{
+ if (samples_per_pixel > quantum_samples)
+ {
+ /*
+ Compact scanline to only contain raster data.
+ */
+
+ BitStreamReadHandle
+ read_stream;
+
+ BitStreamWriteHandle
+ write_stream;
+
+ unsigned long
+ pixels;
+
+ unsigned int
+ count,
+ quantum_value;
+
+ MagickBitStreamInitializeRead(&read_stream,samples);
+ MagickBitStreamInitializeWrite(&write_stream,samples);
+
+ for (pixels = total_pixels; pixels != 0 ; pixels--)
+ {
+ for (count = quantum_samples; count != 0 ; count--)
+ {
+ quantum_value=MagickBitStreamMSBRead(&read_stream,bits_per_sample);
+ MagickBitStreamMSBWrite(&write_stream,bits_per_sample,quantum_value);
+ }
+ for (count = samples_per_pixel-quantum_samples; count != 0 ; count--)
+ {
+ (void) MagickBitStreamMSBRead(&read_stream,bits_per_sample);
+ }
+ }
+ }
+}
+
+
+/*
+ Convert selected pixel area to associated alpha representation.
+*/
+static void
+AssociateAlphaRegion(Image *image)
+{
+ register PixelPacket
+ *q;
+
+ register long
+ x;
+
+ register double
+ alpha,
+ value;
+
+ long
+ number_pixels;
+
+ number_pixels=(long) GetPixelCacheArea(image);
+ q=AccessMutablePixels(image);
+
+ for (x = number_pixels; x > 0; --x)
+ {
+ alpha=((double) MaxRGB-q->opacity)/MaxRGB;
+ value=(double) q->red*alpha;
+ q->red=RoundDoubleToQuantum(value);
+ value=(double) q->green*alpha;
+ q->green=RoundDoubleToQuantum(value);
+ value=(double) q->blue*alpha;
+ q->blue=RoundDoubleToQuantum(value);
+ q++;
+ }
+}
+
+/*
+ Convert associated alpha to internal representation for selected
+ pixel area.
+*/
+static void
+DisassociateAlphaRegion(Image *image)
+{
+ register PixelPacket
+ *q;
+
+ register long
+ x;
+
+ register double
+ alpha,
+ value;
+
+ long
+ number_pixels;
+
+ number_pixels=(long) GetPixelCacheArea(image);
+ q=AccessMutablePixels(image);
+
+ for (x = number_pixels; x > 0; --x)
+ {
+ if (q->opacity != (Quantum) MaxRGB)
+ {
+ alpha=((double) MaxRGB-q->opacity)/MaxRGB;
+ value=(double) q->red/alpha;
+ q->red=RoundDoubleToQuantum(value);
+ value=(double) q->green/alpha;
+ q->green=RoundDoubleToQuantum(value);
+ value=(double) q->blue/alpha;
+ q->blue=RoundDoubleToQuantum(value);
+ }
+ q++;
+ }
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+/*
+ Copy a possibly unterminated sized string to an image attribute.
+*/
+#define CopySizedFieldToAttribute(key,count,text) \
+ do \
+ { \
+ char _attribute[MaxTextExtent]; \
+ (void) memcpy(_attribute,text,Min(sizeof(_attribute),count)); \
+ _attribute[Min(sizeof(_attribute)-1,count)]='\0'; \
+ (void) SetImageAttribute(image,key,_attribute); \
+ } while(0);
+
+
+typedef enum
+{
+ ScanLineMethod, /* Scanline method */
+ StrippedMethod, /* Stripped method */
+ TiledMethod, /* Tiled method */
+ RGBAStrippedMethod, /* RGBA stripped method */
+ RGBATiledMethod, /* RGBA tiled method */
+ RGBAPuntMethod /* RGBA whole-image method (last resort) */
+} TIFFMethod;
+
+static Image *
+ReadTIFFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ *text;
+
+ const char *
+ definition_value;
+
+ float
+ *chromaticity,
+ x_resolution,
+ y_resolution;
+
+ Image
+ *image;
+
+ unsigned int
+ y;
+
+ register unsigned int
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned int
+ i;
+
+ TIFF
+ *tiff;
+
+ uint16
+ compress_tag,
+ bits_per_sample,
+ extra_samples,
+ fill_order,
+ max_sample_value,
+ min_sample_value,
+ orientation,
+ pages,
+ photometric,
+ planar_config,
+ *sample_info,
+ sample_format,
+ samples_per_pixel,
+ units;
+
+ uint32
+ count,
+ height,
+ rows_per_strip,
+ width;
+
+ TIFFMethod
+ method;
+
+ Magick_TIFF_ClientData
+ client_data;
+
+ ImportPixelAreaOptions
+ import_options;
+
+ AlphaType
+ alpha_type=UnspecifiedAlpha;
+
+ MagickBool
+ logging,
+ more_frames;
+
+ MagickPassFail
+ status;
+
+ /*
+ Open image.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ logging=IsEventLogging();
+ image=AllocateImage(image_info);
+ more_frames=MagickFalse;
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ (void) MagickTsdSetSpecific(tsd_key,(void *) exception);
+ (void) TIFFSetErrorHandler((TIFFErrorHandler) TIFFErrors);
+ (void) TIFFSetWarningHandler((TIFFErrorHandler) (CheckThrowWarnings(image_info) ?
+ TIFFWarningsThrowException :
+ TIFFWarningsLogOnly));
+ client_data.image=image;
+ client_data.image_info=image_info;
+ tiff=TIFFClientOpen(image->filename,"rb",(thandle_t) &client_data,TIFFReadBlob,
+ TIFFWriteBlob,TIFFSeekBlob,TIFFCloseBlob,
+ TIFFGetBlobSize,TIFFMapBlob,TIFFUnmapBlob);
+ if (tiff == (TIFF *) NULL)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ if (image_info->subrange != 0)
+ while (image->scene < image_info->subimage)
+ {
+ /*
+ Skip to next image.
+ */
+ image->scene++;
+ status=TIFFReadDirectory(tiff);
+ if (status == False)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(CorruptImageError,UnableToReadSubImageData,
+ image);
+ }
+ }
+ do
+ {
+ if (image_info->verbose > 1)
+ TIFFPrintDirectory(tiff,stdout,False);
+
+ /*
+ Read critical tags. We need a value for these tags in order to proceed.
+ */
+ status = 1;
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_PHOTOMETRIC,&photometric) == 1);
+ if ((status == 1) &&
+ ((photometric == PHOTOMETRIC_LOGL) || (photometric == PHOTOMETRIC_LOGLUV)))
+ status &= (TIFFSetField(tiff,TIFFTAG_SGILOGDATAFMT,SGILOGDATAFMT_FLOAT) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_COMPRESSION,&compress_tag) == 1);
+ status &= (TIFFGetField(tiff,TIFFTAG_IMAGEWIDTH,&width) == 1);
+ status &= (TIFFGetField(tiff,TIFFTAG_IMAGELENGTH,&height) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_PLANARCONFIG,&planar_config) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_SAMPLESPERPIXEL,&samples_per_pixel) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_BITSPERSAMPLE,&bits_per_sample) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_SAMPLEFORMAT,&sample_format) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_MINSAMPLEVALUE,&min_sample_value) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_MAXSAMPLEVALUE,&max_sample_value) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_ROWSPERSTRIP,&rows_per_strip) == 1);
+ status &= (TIFFGetFieldDefaulted(tiff,TIFFTAG_FILLORDER,&fill_order) == 1);
+ if (status == 0)
+ {
+ TIFFClose(tiff);
+ /*
+ Promote TIFF warnings to errors for these critical tags.
+ */
+ if ((exception->severity > WarningException) &&
+ (exception->severity < ErrorException))
+ exception->severity += (ErrorException - WarningException);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,
+ image);
+ }
+ if (TIFFGetField(tiff,TIFFTAG_ORIENTATION,&orientation) == 1)
+ image->orientation=(OrientationType) orientation;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Geometry: %ux%u",
+ (unsigned int) width,(unsigned int) height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"PlanarConfiguration: %s",
+ planar_config == PLANARCONFIG_CONTIG ? "contiguous" :
+ planar_config == PLANARCONFIG_SEPARATE ? "separate" :
+ "UNKNOWN");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Samples per pixel: %u", samples_per_pixel);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Sample format: %s",
+ sample_format == SAMPLEFORMAT_UINT ? "Unsigned integer" :
+ sample_format == SAMPLEFORMAT_INT ? "Signed integer" :
+ sample_format == SAMPLEFORMAT_IEEEFP ? "IEEE floating point" :
+ sample_format == SAMPLEFORMAT_VOID ? "Untyped data" :
+ sample_format == SAMPLEFORMAT_COMPLEXINT ? "Complex signed int" :
+ sample_format == SAMPLEFORMAT_COMPLEXIEEEFP ? "Complex IEEE floating point" :
+ "UNKNOWN");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Bits per sample: %u",bits_per_sample);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Min sample value: %u",min_sample_value);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Max sample value: %u",max_sample_value);
+ if (sample_format == SAMPLEFORMAT_IEEEFP)
+ {
+ double
+ value;
+
+ if (TIFFGetField(tiff,TIFFTAG_SMINSAMPLEVALUE,&value) == 1)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Special min sample value: %g", value);
+ if (TIFFGetField(tiff,TIFFTAG_SMAXSAMPLEVALUE,&value) == 1)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Special max sample value: %g", value);
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Photometric: %s", PhotometricTagToString(photometric));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Compression: %s", CompressionTagToString(compress_tag));
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Byte swapped: %s",TIFFIsByteSwapped(tiff) ?
+ "true" : "false");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Bit fill order: %s",
+ fill_order == FILLORDER_LSB2MSB ? "LSB2MSB" :
+ fill_order == FILLORDER_MSB2LSB ? "MSB2LSB" :
+ "unknown");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Rows per strip: %u",(unsigned int) rows_per_strip);
+ }
+ ImportPixelAreaOptionsInit(&import_options);
+ if (photometric == PHOTOMETRIC_CIELAB)
+ {
+#if 1
+ image->colorspace=LABColorspace;
+#else
+ TIFFClose(tiff);
+ ThrowReaderException(CoderError,UnableToReadCIELABImages,image);
+#endif
+ }
+ if (photometric == PHOTOMETRIC_SEPARATED)
+ image->colorspace=CMYKColorspace;
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ image->interlace=PlaneInterlace;
+ (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_RESOLUTIONUNIT,&units);
+ x_resolution=image->x_resolution;
+ y_resolution=image->y_resolution;
+ (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_XRESOLUTION,&x_resolution);
+ (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_YRESOLUTION,&y_resolution);
+ image->x_resolution=x_resolution;
+ image->y_resolution=y_resolution;
+ chromaticity=(float *) NULL;
+ if (TIFFGetField(tiff,TIFFTAG_WHITEPOINT,&chromaticity) == 1)
+ {
+ if (chromaticity != (float *) NULL)
+ {
+ image->chromaticity.white_point.x=chromaticity[0];
+ image->chromaticity.white_point.y=chromaticity[1];
+ }
+ }
+ chromaticity=(float *) NULL;
+ if (TIFFGetField(tiff,TIFFTAG_PRIMARYCHROMATICITIES,&chromaticity) == 1)
+ {
+ if (chromaticity != (float *) NULL)
+ {
+ image->chromaticity.red_primary.x=chromaticity[0];
+ image->chromaticity.red_primary.y=chromaticity[1];
+ image->chromaticity.green_primary.x=chromaticity[2];
+ image->chromaticity.green_primary.y=chromaticity[3];
+ image->chromaticity.blue_primary.x=chromaticity[4];
+ image->chromaticity.blue_primary.y=chromaticity[5];
+ }
+ }
+ {
+ /*
+ Retrieve embedded profiles.
+ */
+ uint32
+ length;
+ /*
+ ICC ICM color profile.
+ */
+#if defined(TIFFTAG_ICCPROFILE)
+ if (TIFFGetField(tiff,TIFFTAG_ICCPROFILE,&length,&text) == 1)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "ICC ICM embedded profile with length %lu bytes",
+ (unsigned long)length);
+ (void) SetImageProfile(image,"ICM",(unsigned char *) text,(size_t) length);
+ }
+#endif /* defined(TIFFTAG_ICCPROFILE) */
+ /*
+ IPTC/Photoshop profile.
+ */
+#if defined(TIFFTAG_PHOTOSHOP)
+ /* Photoshop profile (with embedded IPTC profile) */
+ if (TIFFGetField(tiff,TIFFTAG_PHOTOSHOP,&length,&text) == 1)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Photoshop embedded profile with length %lu bytes",
+ (unsigned long) length);
+ (void) ReadNewsProfile(text,(long) length,image,TIFFTAG_PHOTOSHOP);
+ }
+#elif defined(TIFFTAG_RICHTIFFIPTC)
+ /* IPTC TAG from RichTIFF specifications */
+ if (TIFFGetField(tiff,TIFFTAG_RICHTIFFIPTC,&length,&text) == 1)
+ {
+ if (TIFFIsByteSwapped(tiff))
+ TIFFSwabArrayOfLong((uint32 *) text,length);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "IPTC Newsphoto embedded profile with length %u bytes",length);
+ ReadNewsProfile(text,length,image,TIFFTAG_RICHTIFFIPTC);
+ }
+#endif
+ /*
+ XML XMP profile.
+ */
+#if defined(TIFFTAG_XMLPACKET)
+ /* %XML packet [Adobe XMP Specification, Janary 2004] */
+ if (TIFFGetField(tiff,TIFFTAG_XMLPACKET,&length,&text) == 1)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "XMP embedded profile with length %lu bytes",
+ (unsigned long) length);
+ SetImageProfile(image,"XMP",(unsigned char *) text,(size_t) length);
+ }
+#endif
+ }
+ /*
+ Allocate memory for the image and pixel buffer.
+ */
+ switch (compress_tag)
+ {
+ case COMPRESSION_NONE: image->compression=NoCompression; break;
+ case COMPRESSION_CCITTFAX3: image->compression=FaxCompression; break;
+ case COMPRESSION_CCITTFAX4: image->compression=Group4Compression; break;
+ case COMPRESSION_JPEG: image->compression=JPEGCompression; break;
+ case COMPRESSION_OJPEG: image->compression=JPEGCompression; break;
+ case COMPRESSION_LZW: image->compression=LZWCompression; break;
+#if defined(COMPRESSION_LZMA)
+ case COMPRESSION_LZMA: image->compression=LZMACompression; break;
+#endif /* defined(COMPRESSION_LZMA) */
+ case COMPRESSION_DEFLATE: image->compression=ZipCompression; break;
+ case COMPRESSION_ADOBE_DEFLATE: image->compression=ZipCompression; break;
+ default: image->compression=RLECompression; break;
+ }
+ image->columns=width;
+ image->rows=height;
+ image->depth=bits_per_sample;
+
+ /*
+ Obtain information about any extra samples.
+ */
+ extra_samples=0;
+ if (TIFFGetField(tiff,TIFFTAG_EXTRASAMPLES,&extra_samples,
+ &sample_info) == 1)
+ {
+ int
+ sample_index;
+
+ if (extra_samples != 0)
+ {
+ alpha_type=AssociatedAlpha;
+ image->matte=True;
+
+ if (sample_info[0] == EXTRASAMPLE_UNSPECIFIED)
+ alpha_type=UnspecifiedAlpha;
+ else if (sample_info[0] == EXTRASAMPLE_UNASSALPHA)
+ alpha_type=UnassociatedAlpha;
+ else if (sample_info[0] == EXTRASAMPLE_ASSOCALPHA)
+ alpha_type=AssociatedAlpha;
+ }
+ for (sample_index=0 ; sample_index < extra_samples; sample_index++)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Extra sample %u contains %s alpha",sample_index+1,
+ ((sample_info[sample_index] == EXTRASAMPLE_ASSOCALPHA) ? "ASSOCIATED" :
+ (sample_info[sample_index] == EXTRASAMPLE_UNASSALPHA) ? "UNASSOCIATED" :
+ "UNSPECIFIED"));
+ }
+ }
+ /*
+ Handle RGBA images which are improperly marked.
+ */
+ if (extra_samples == 0)
+ if ((photometric == PHOTOMETRIC_RGB) && (samples_per_pixel == 4))
+ {
+ extra_samples=1;
+ alpha_type=AssociatedAlpha;
+ image->matte=MagickTrue;
+ }
+
+ /*
+ Allow the user to over-ride the alpha channel type.
+ */
+ if (image->matte)
+ {
+ if ((definition_value=AccessDefinition(image_info,"tiff","alpha")))
+ {
+ if (LocaleCompare(definition_value,"unspecified") == 0)
+ alpha_type=UnspecifiedAlpha;
+ else if (LocaleCompare(definition_value,"associated") == 0)
+ alpha_type=AssociatedAlpha;
+ else if (LocaleCompare(definition_value,"unassociated") == 0)
+ alpha_type=UnassociatedAlpha;
+ }
+ }
+
+ /*
+ Describe how the alpha channel will be treated.
+ */
+ if (image->matte)
+ {
+ char
+ alpha_string[MaxTextExtent];
+
+ switch(alpha_type)
+ {
+ default:
+ case UnspecifiedAlpha:
+ (void) strlcpy(alpha_string,"Unspecified",MaxTextExtent);
+ break;
+ case UnassociatedAlpha:
+ (void) strlcpy(alpha_string,"Unassociated",MaxTextExtent);
+ break;
+ case AssociatedAlpha:
+ (void) strlcpy(alpha_string,"Associated",MaxTextExtent);
+ break;
+ }
+ (void) SetImageAttribute(image,"alpha",alpha_string);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image has a matte channel of type: %s",
+ alpha_string);
+ }
+
+ if (units == RESUNIT_INCH)
+ image->units=PixelsPerInchResolution;
+ if (units == RESUNIT_CENTIMETER)
+ image->units=PixelsPerCentimeterResolution;
+ {
+ uint16
+ pagenumber;
+
+ pagenumber=(unsigned short) image->scene;
+ if (TIFFGetFieldDefaulted(tiff,TIFFTAG_PAGENUMBER,&pagenumber,&pages) == 1)
+ image->scene=pagenumber;
+ }
+
+ if (TIFFGetField(tiff,TIFFTAG_ARTIST,&text) == 1)
+ (void) SetImageAttribute(image,"artist",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_COPYRIGHT,&text) == 1) /* TIFFTAG_COPYRIGHT */
+ (void) SetImageAttribute(image,"copyright",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_DATETIME,&text) == 1)
+ (void) SetImageAttribute(image,"timestamp",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_DOCUMENTNAME,&text) == 1)
+ (void) SetImageAttribute(image,"document",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_HOSTCOMPUTER,&text) == 1)
+ (void) SetImageAttribute(image,"hostcomputer",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_IMAGEDESCRIPTION,&text) == 1)
+ (void) SetImageAttribute(image,"comment",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_MAKE,&text) == 1)
+ (void) SetImageAttribute(image,"make",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_MODEL,&text) == 1)
+ (void) SetImageAttribute(image,"model",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_PAGENAME,&text) == 1)
+ (void) SetImageAttribute(image,"label",text);
+
+ if (TIFFGetField(tiff,TIFFTAG_SOFTWARE,&text) == 1)
+ (void) SetImageAttribute(image,"software",text);
+
+ /*
+ "Unsupported" tags return two arguments.
+ */
+ if (TIFFGetField(tiff,TIFFTAG_OPIIMAGEID,&count,&text) == 1)
+ CopySizedFieldToAttribute("imageid",count,text);
+
+ if (TIFFGetField(tiff,33423,&count,&text) == 1)
+ CopySizedFieldToAttribute("kodak-33423",count,text);
+
+ if (TIFFGetField(tiff,36867,&count,&text) == 1)
+ CopySizedFieldToAttribute("kodak-36867",count,text);
+
+ if ((photometric == PHOTOMETRIC_PALETTE) ||
+ ((photometric == PHOTOMETRIC_MINISWHITE ||
+ photometric == PHOTOMETRIC_MINISBLACK) &&
+ ((image_info->type == PaletteType) ||
+ (image_info->type == PaletteMatteType)) &&
+ (MaxColormapSize > MaxValueGivenBits(bits_per_sample))
+ )
+ )
+ {
+ /*
+ Palette image
+ */
+ if (MaxColormapSize > MaxValueGivenBits(bits_per_sample))
+ {
+ (void) InitializeImageColormap(image,tiff);
+ }
+ else
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(CoderError,ColormapTooLarge,image);
+ }
+ }
+
+ /*
+ Quit if in "ping" mode and we are outside of requested range,
+ otherwise continue to next frame.
+ */
+ if (image_info->ping)
+ {
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ goto read_next_frame;
+ }
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ }
+
+ /*
+ Determine which method to use for reading pixels.
+ */
+ {
+ int
+ quantum_samples;
+
+ QuantumType
+ quantum_type;
+
+ if ((samples_per_pixel > 1) &&
+ (compress_tag == COMPRESSION_JPEG) &&
+ (photometric == PHOTOMETRIC_YCBCR))
+ {
+ /* Following hack avoids the error message "Application
+ transferred too many scanlines. (JPEGLib)." caused by
+ YCbCr subsampling, but it returns data in RGB rather
+ than YCbCr. */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Resetting photometric from %s to %s for JPEG RGB",
+ PhotometricTagToString(photometric),
+ PhotometricTagToString(PHOTOMETRIC_RGB));
+ (void) TIFFSetField( tiff, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB );
+ photometric=PHOTOMETRIC_RGB;
+ }
+ method=RGBAPuntMethod;
+ quantum_type=UndefinedQuantum;
+ quantum_samples=0;
+ if (QuantumTransferMode(image,photometric,compress_tag,sample_format,
+ samples_per_pixel,planar_config,0,&quantum_type,
+ &quantum_samples,exception)
+ == MagickPass)
+ {
+ method=ScanLineMethod;
+ if ((compress_tag == COMPRESSION_JPEG) ||
+ (compress_tag == COMPRESSION_OJPEG))
+ {
+ if (TIFFIsTiled(tiff))
+ method=TiledMethod;
+ else
+ method=StrippedMethod;
+ }
+#if defined(COMPRESSION_JBIG)
+ else if (compress_tag == COMPRESSION_JBIG)
+ /* libtiff jbig coder only handles strips */
+ method=StrippedMethod;
+#endif
+ else if (TIFFIsTiled(tiff))
+ method=TiledMethod;
+ else if (TIFFStripSize(tiff) <= 1024*256)
+ method=StrippedMethod;
+ if (photometric == PHOTOMETRIC_MINISWHITE)
+ import_options.grayscale_miniswhite=MagickTrue;
+ }
+ else if (exception->severity < ErrorException)
+ {
+ if (TIFFIsTiled(tiff))
+ method=RGBATiledMethod;
+ else if (TIFFGetField(tiff,TIFFTAG_ROWSPERSTRIP,&rows_per_strip) == 1)
+ method=RGBAStrippedMethod;
+ }
+ else
+ {
+ /*
+ QuantumTransferMode reported an error
+ */
+ TIFFClose(tiff);
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ }
+
+ /*
+ Set extra import options for floating point.
+ */
+ if (sample_format == SAMPLEFORMAT_IEEEFP)
+ {
+ double
+ value;
+
+ import_options.sample_type=FloatQuantumSampleType;
+ if (TIFFGetField(tiff,TIFFTAG_SMINSAMPLEVALUE,&value) == 1)
+ import_options.double_minvalue=value;
+ if (TIFFGetField(tiff,TIFFTAG_SMAXSAMPLEVALUE,&value) == 1)
+ import_options.double_maxvalue=value;
+ if ((definition_value=AccessDefinition(image_info,"tiff","min-sample-value")))
+ import_options.double_minvalue=strtod(definition_value,(char **)NULL);
+ if ((definition_value=AccessDefinition(image_info,"tiff","max-sample-value")))
+ import_options.double_maxvalue=strtod(definition_value,(char **)NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using min sample value %g, max sample value %g",
+ import_options.double_minvalue,
+ import_options.double_maxvalue);
+ }
+
+ /*
+ For sample sizes matching a CPU native word, use native endian
+ order for import.
+ */
+ if ((16 == bits_per_sample) || (32 == bits_per_sample) || (64 == bits_per_sample))
+ import_options.endian=NativeEndian;
+
+ switch (method)
+ {
+ case ScanLineMethod:
+ {
+ /*
+ Read TIFF image as scanlines.
+ */
+ unsigned char
+ *scanline;
+
+ int
+ max_sample,
+ quantum_samples,
+ sample;
+
+ tsize_t
+ scanline_size;
+
+ QuantumType
+ quantum_type;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using scanline %s read method with %u bits per sample",
+ PhotometricTagToString(photometric),bits_per_sample);
+ /*
+ Allocate memory for one scanline.
+ */
+ scanline_size=TIFFScanlineSize(tiff);
+ if (0 == scanline_size)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Scale up to size of 32-bit word.
+ */
+ scanline_size=RoundUpToAlignment(scanline_size,sizeof(magick_int32_t));
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Allocating scanline buffer of %lu bytes",
+ (unsigned long) scanline_size);
+
+ scanline=MagickAllocateMemory(unsigned char *,(size_t) scanline_size);
+ if (scanline == (unsigned char *) NULL)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ /*
+ Prepare for separate/contiguous retrieval.
+ */
+ max_sample=1;
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,samples_per_pixel,
+ PLANARCONFIG_CONTIG,0,
+ &quantum_type,&quantum_samples,
+ exception)
+ == MagickPass)
+ max_sample=quantum_samples;
+ }
+ for (sample=0; sample < max_sample; sample++)
+ {
+ for (y=0; y < image->rows; y++)
+ {
+ if (sample == 0)
+ q=SetImagePixels(image,0,y,image->columns,1);
+ else
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ /*
+ Obtain a scanline
+ */
+ if (TIFFReadScanline(tiff,(char *) scanline,(uint32) y,sample) == -1)
+ {
+ status=MagickFail;
+ break;
+ }
+#if !defined(WORDS_BIGENDIAN)
+ if (24 == bits_per_sample)
+ SwabDataToBigEndian(bits_per_sample,scanline,scanline_size);
+#endif
+ /*
+ Determine quantum parse method.
+ */
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,
+ samples_per_pixel,planar_config,
+ sample,
+ &quantum_type,&quantum_samples,
+ exception)
+ == MagickFail)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ /*
+ Compact scanline to only contain raster data.
+ */
+ if ((samples_per_pixel > quantum_samples) &&
+ (planar_config == PLANARCONFIG_CONTIG))
+ CompactSamples(image->columns, bits_per_sample,
+ samples_per_pixel, quantum_samples, scanline);
+ /*
+ Import scanline into image.
+ */
+ if (ImportImagePixelArea(image,quantum_type,bits_per_sample,scanline,
+ &import_options,0) == MagickFail)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ /*
+ Disassociate alpha from pixels if necessary.
+ */
+ if ((image->matte) && (alpha_type == AssociatedAlpha) &&
+ (sample == (max_sample-1)))
+ DisassociateAlphaRegion(image);
+ /*
+ Save our updates.
+ */
+ if (!SyncImagePixels(image))
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y+sample*image->rows,image->rows*max_sample))
+ if (!MagickMonitorFormatted(y+sample*image->rows,
+ image->rows*max_sample,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ MagickFreeMemory(scanline);
+ break;
+ }
+ case StrippedMethod:
+ {
+ /*
+ Read TIFF image using multi-row strip storage.
+ */
+ unsigned char
+ *p,
+ *strip;
+
+ long
+ /* pixels_per_strip, */
+ stride,
+ rows_remaining;
+
+ int
+ max_sample,
+ quantum_samples,
+ sample;
+
+ tsize_t
+ strip_size,
+ strip_size_max;
+
+ tstrip_t
+ strip_id;
+
+ QuantumType
+ quantum_type;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using stripped read method with %u bits per sample",
+ bits_per_sample);
+ /* pixels_per_strip=rows_per_strip*image->columns; */
+ p=0;
+ strip_size=0;
+ strip_id=0;
+ /*
+ Allocate memory for one strip.
+ */
+ strip_size_max=TIFFStripSize(tiff);
+ /*
+ Scale up to size of 32-bit word.
+ */
+ strip_size_max=RoundUpToAlignment(strip_size_max,sizeof(magick_int32_t));
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Maximum strip size %" MAGICK_SIZE_T_F "u",
+ (MAGICK_SSIZE_T) strip_size_max);
+ if (0 == strip_size_max)
+ {
+ status=MagickFail;
+ break;
+ }
+
+ strip=MagickAllocateMemory(unsigned char *,(size_t) strip_size_max);
+ if (strip == (unsigned char *) NULL)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ /*
+ Prepare for separate/contiguous retrieval.
+ */
+ max_sample=1;
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,
+ samples_per_pixel,PLANARCONFIG_CONTIG,
+ 0,&quantum_type,&quantum_samples,
+ exception)
+ == MagickPass)
+ max_sample=quantum_samples;
+ }
+ /*
+ Compute per-row stride.
+ */
+ stride=TIFFVStripSize(tiff,1);
+ /*
+ Process each plane
+ */
+ for (sample=0; sample < max_sample; sample++)
+ {
+ rows_remaining=0;
+ /*
+ Determine quantum parse method.
+ */
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,samples_per_pixel,
+ planar_config,sample,
+ &quantum_type,&quantum_samples,
+ exception)
+ == MagickFail)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ for (y=0; y < image->rows; y++)
+ {
+ /*
+ Access Magick pixels.
+ */
+ if (sample == 0)
+ q=SetImagePixels(image,0,y,image->columns,1);
+ else
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ if (rows_remaining == 0)
+ {
+ /*
+ Obtain a strip
+ */
+ if (((strip_size=TIFFReadEncodedStrip(tiff,strip_id,strip,
+ strip_size_max)) == -1))
+ {
+ status=MagickFail;
+ break;
+ }
+#if !defined(WORDS_BIGENDIAN)
+ if (24 == bits_per_sample)
+ SwabDataToBigEndian(bits_per_sample,strip,strip_size);
+#endif
+ rows_remaining=rows_per_strip;
+ if (y+rows_per_strip > image->rows)
+ rows_remaining=(rows_per_strip-(y+rows_per_strip-image->rows));
+ p=strip;
+ strip_id++;
+ }
+ /*
+ Compact strip row to only contain raster data.
+ */
+ if ((samples_per_pixel > quantum_samples) &&
+ (planar_config == PLANARCONFIG_CONTIG))
+ CompactSamples(image->columns, bits_per_sample,
+ samples_per_pixel, quantum_samples, p);
+ /*
+ Import strip row into image.
+ */
+ if (ImportImagePixelArea(image,quantum_type,bits_per_sample,p,
+ &import_options,0) == MagickFail)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ /*
+ Disassociate alpha from pixels if necessary.
+ */
+ if ((image->matte) && (alpha_type == AssociatedAlpha)
+ && (sample == (max_sample-1)))
+ DisassociateAlphaRegion(image);
+ /*
+ Save our updates.
+ */
+ if (!SyncImagePixels(image))
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ /*
+ Advance to next row
+ */
+ p += stride;
+ rows_remaining--;
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y+image->rows*sample,image->rows*max_sample))
+ if (!MagickMonitorFormatted(y+image->rows*sample,image->rows*max_sample,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (status == MagickFail)
+ break;
+ }
+ MagickFreeMemory(strip);
+ break;
+ }
+ case TiledMethod:
+ {
+ /*
+ Read TIFF using tiled storage.
+ */
+ unsigned char
+ *tile;
+
+ uint32
+ tile_columns,
+ tile_rows;
+
+ tsize_t
+ stride,
+ tile_size,
+ tile_size_max;
+
+ int
+ max_sample,
+ quantum_samples,
+ sample;
+
+ QuantumType
+ quantum_type;
+
+ unsigned long
+ tile_total_pixels;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using tiled %s read method with %u bits per sample",
+ PhotometricTagToString(photometric), bits_per_sample);
+ /*
+ Obtain tile geometry
+ */
+ if(!(TIFFGetField(tiff,TIFFTAG_TILEWIDTH,&tile_columns) == 1) ||
+ !(TIFFGetField(tiff,TIFFTAG_TILELENGTH,&tile_rows) == 1))
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(CoderError,ImageIsNotTiled,image);
+ }
+ /*
+ Obtain the maximum number of bytes required to contain a tile.
+ */
+ tile_size_max=TIFFTileSize(tiff);
+ /*
+ Scale up to size of 32-bit word.
+ */
+ tile_size_max=RoundUpToAlignment(tile_size_max,sizeof(magick_int32_t));
+ if (0 == tile_size_max)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Compute the total number of pixels in one tile
+ */
+ tile_total_pixels=tile_columns*tile_rows;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF tile geometry %ux%u, %lu pixels",
+ (unsigned int)tile_columns,
+ (unsigned int)tile_rows,
+ tile_total_pixels);
+ }
+ /*
+ Allocate tile buffer
+ */
+ tile=MagickAllocateMemory(unsigned char *, (size_t) tile_size_max);
+ if (tile == (unsigned char *) NULL)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ /*
+ Prepare for separate/contiguous retrieval.
+ */
+ max_sample=1;
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,samples_per_pixel,
+ PLANARCONFIG_CONTIG,0,&quantum_type,
+ &quantum_samples,
+ exception)
+ == MagickPass)
+ max_sample=quantum_samples;
+ }
+ /*
+ Compute per-row stride.
+ */
+ stride=TIFFTileRowSize(tiff);
+
+ /*
+ Process each plane.
+ */
+ for (sample=0; sample < max_sample; sample++)
+ {
+ /*
+ Determine quantum parse method.
+ */
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,samples_per_pixel,
+ planar_config,sample,&quantum_type,
+ &quantum_samples,exception)
+ == MagickFail)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ for (y=0; y < image->rows; y+=tile_rows)
+ {
+ for (x=0; x < image->columns; x+=tile_columns)
+ {
+ long
+ tile_set_columns,
+ tile_set_rows;
+
+ unsigned char
+ *p;
+
+ register long
+ yy;
+
+ /*
+ Compute image region corresponding to tile.
+ */
+ if (x+tile_columns > image->columns)
+ tile_set_columns=(tile_columns-(x+tile_columns-image->columns));
+ else
+ tile_set_columns=tile_columns;
+ if (y+tile_rows > image->rows)
+ tile_set_rows=(tile_rows-(y+tile_rows-image->rows));
+ else
+ tile_set_rows=tile_rows;
+
+ /*
+ Read a tile.
+ */
+ if ((tile_size=TIFFReadTile(tiff,tile,x,y,0,sample)) == -1)
+ {
+ status=MagickFail;
+ break;
+ }
+#if !defined(WORDS_BIGENDIAN)
+ if (24 == bits_per_sample)
+ SwabDataToBigEndian(bits_per_sample,tile,tile_size);
+#endif
+ p=tile;
+ for (yy=y; yy < (long) y+tile_set_rows; yy++)
+ {
+ /*
+ Obtain pixel region corresponding to tile row.
+ */
+ if (sample == 0)
+ q=SetImagePixels(image,x,yy,tile_set_columns,1);
+ else
+ q=GetImagePixels(image,x,yy,tile_set_columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ /*
+ Compact tile row to only contain raster data.
+ */
+ if ((samples_per_pixel > quantum_samples) &&
+ (planar_config == PLANARCONFIG_CONTIG))
+ CompactSamples(tile_set_columns, bits_per_sample,
+ samples_per_pixel, quantum_samples, p);
+ /*
+ Import tile row
+ */
+ if (ImportImagePixelArea(image,quantum_type,
+ bits_per_sample,p,
+ &import_options,0)
+ == MagickFail)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ /*
+ Disassociate alpha from pixels if necessary.
+ */
+ if ((image->matte) && (alpha_type == AssociatedAlpha)
+ && (sample == (max_sample-1)))
+ DisassociateAlphaRegion(image);
+ /*
+ Save our updates.
+ */
+ if (!SyncImagePixels(image))
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ p += stride;
+ }
+ if (status == MagickFail)
+ break;
+ }
+ if (status == MagickFail)
+ break;
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick((y+sample*image->rows)/tile_rows,
+ (image->rows*max_sample)/tile_rows))
+ if (!MagickMonitorFormatted((y+sample*image->rows)/tile_rows,
+ (image->rows*max_sample)/tile_rows,
+ exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (status == MagickFail)
+ break;
+ }
+
+ MagickFreeMemory(tile);
+ break;
+ }
+ case RGBAStrippedMethod:
+ {
+ size_t
+ number_pixels;
+
+ uint32
+ *strip_pixels;
+
+ register uint32
+ *p;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using RGB stripped read method with %u bits per sample",
+ bits_per_sample);
+ /*
+ Convert stripped TIFF image to DirectClass MIFF image.
+ */
+ number_pixels=MagickArraySize(image->columns,rows_per_strip);
+ if (0 == number_pixels)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ strip_pixels=MagickAllocateArray(uint32 *,number_pixels,sizeof(uint32));
+ if (strip_pixels == (uint32 *) NULL)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Allocated %" MAGICK_SIZE_T_F "u bytes for RGBA strip",
+ (MAGICK_SIZE_T) number_pixels*sizeof(uint32));
+ /*
+ Convert image to DirectClass pixel packets.
+ */
+ i=0;
+ p=0;
+ for (y=0; y < image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ if (0 == i)
+ {
+ if (!TIFFReadRGBAStrip(tiff,y,strip_pixels))
+ {
+ status=MagickFail;
+ break;
+ }
+ i=(long) Min(rows_per_strip,image->rows-y);
+ }
+ i--;
+ p=strip_pixels+image->columns*i;
+ for (x=0; x < image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(TIFFGetR(*p));
+ q->green=ScaleCharToQuantum(TIFFGetG(*p));
+ q->blue=ScaleCharToQuantum(TIFFGetB(*p));
+ if (image->matte)
+ q->opacity=(Quantum) ScaleCharToQuantum(TIFFGetA(*p));
+ p++;
+ q++;
+ }
+ /*
+ Disassociate alpha from pixels if necessary.
+ */
+ if ((image->matte) && (alpha_type == AssociatedAlpha))
+ DisassociateAlphaRegion(image);
+ if (!SyncImagePixels(image))
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ MagickFreeMemory(strip_pixels);
+ break;
+ }
+ case RGBATiledMethod:
+ {
+ /*
+ Convert tiled TIFF image to DirectClass MIFF image.
+ */
+ register uint32
+ *p;
+
+ uint32
+ *tile_pixels,
+ tile_columns,
+ tile_rows;
+
+ size_t
+ tile_total_pixels;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using RGB tiled read method with %u bits per sample",
+ bits_per_sample);
+ /*
+ Obtain tile geometry
+ */
+ if (!(TIFFGetField(tiff,TIFFTAG_TILEWIDTH,&tile_columns) == 1) ||
+ !(TIFFGetField(tiff,TIFFTAG_TILELENGTH,&tile_rows) == 1))
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(CoderError,ImageIsNotTiled,image);
+ }
+ tile_total_pixels=MagickArraySize(tile_columns,tile_rows);
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Reading TIFF tiles ...");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF tile geometry %ux%u, %" MAGICK_SIZE_T_F "u pixels",
+ (unsigned int)tile_columns,
+ (unsigned int)tile_rows,
+ (MAGICK_SIZE_T) tile_total_pixels);
+ }
+ /*
+ Allocate tile buffer
+ */
+ tile_pixels=MagickAllocateArray(uint32*,MagickArraySize(tile_columns,tile_rows),
+ sizeof (uint32));
+ if (tile_pixels == (uint32 *) NULL)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ for (y=0; y < image->rows; y+=tile_rows)
+ {
+ /*
+ Retrieve a tile height's worth of rows
+ */
+ PixelPacket
+ *strip;
+
+ unsigned int
+ tile_columns_remaining,
+ tile_rows_remaining;
+
+ /* Compute remaining tile rows */
+ if (y+tile_rows < image->rows)
+ tile_rows_remaining=tile_rows;
+ else
+ tile_rows_remaining=image->rows-y;
+ /*
+ Obtain a row of pixels
+ */
+ strip=SetImagePixels(image,0,y,image->columns,tile_rows_remaining);
+ if (strip == (PixelPacket *) NULL)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < image->columns; x+=tile_columns)
+ {
+ register unsigned int
+ tile_column,
+ tile_row;
+
+ /*
+ Obtain one tile. Origin is bottom left of tile.
+ */
+ if (!TIFFReadRGBATile(tiff,x,y,tile_pixels))
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Compute remaining tile columns
+ */
+ if (x+tile_columns < image->columns)
+ tile_columns_remaining=tile_columns;
+ else
+ tile_columns_remaining=image->columns-x;
+ /*
+ Transfer tile to image
+ */
+ p=tile_pixels+(tile_rows-tile_rows_remaining)*tile_columns;
+ q=strip+(x+(tile_rows_remaining-1)*image->columns);
+ for ( tile_row=tile_rows_remaining; tile_row != 0; tile_row--)
+ {
+ if (image->matte)
+ for (tile_column=tile_columns_remaining; tile_column != 0;
+ tile_column--)
+ {
+ q->red=ScaleCharToQuantum(TIFFGetR(*p));
+ q->green=ScaleCharToQuantum(TIFFGetG(*p));
+ q->blue=ScaleCharToQuantum(TIFFGetB(*p));
+ q->opacity=(Quantum) ScaleCharToQuantum(TIFFGetA(*p));
+ q++;
+ p++;
+ }
+ else
+ for (tile_column=tile_columns_remaining; tile_column != 0;
+ tile_column--)
+ {
+ q->red=ScaleCharToQuantum(TIFFGetR(*p));
+ q->green=ScaleCharToQuantum(TIFFGetG(*p));
+ q->blue=ScaleCharToQuantum(TIFFGetB(*p));
+ q++;
+ p++;
+ }
+ p+=tile_columns-tile_columns_remaining;
+ q-=(image->columns+tile_columns_remaining);
+ }
+ if (status == MagickFail)
+ break;
+ }
+ if (status == MagickFail)
+ break;
+ /*
+ Disassociate alpha from pixels if necessary.
+ */
+ if ((image->matte) && (alpha_type == AssociatedAlpha))
+ DisassociateAlphaRegion(image);
+ if (!SyncImagePixels(image))
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ MagickFreeMemory(tile_pixels);
+ break;
+ }
+ case RGBAPuntMethod:
+ default:
+ {
+ register uint32
+ *p;
+
+ uint32
+ *pixels;
+
+ size_t
+ number_pixels;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using RGB punt read method with %u bits per sample",
+ bits_per_sample);
+ /*
+ Convert TIFF image to DirectClass MIFF image.
+ */
+ number_pixels=(size_t) image->columns*image->rows;
+ if ((image->columns == 0) ||
+ (number_pixels/image->columns != image->rows))
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ pixels=MagickAllocateArray(uint32 *,
+ number_pixels+6*image->columns,
+ sizeof(uint32));
+ if (pixels == (uint32 *) NULL)
+ {
+ TIFFClose(tiff);
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ if (!TIFFReadRGBAImage(tiff,(uint32) image->columns,
+ (uint32) image->rows,
+ pixels+image->columns,0))
+ {
+ MagickFreeMemory(pixels);
+ TIFFClose(tiff);
+ return ((Image *) NULL);
+ }
+ /*
+ Convert image to DirectClass pixel packets.
+ */
+ p=pixels+number_pixels+image->columns-1;
+ for (y=0; y < image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ q+=image->columns-1;
+ if (image->matte)
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ q->red=ScaleCharToQuantum(TIFFGetR(*p));
+ q->green=ScaleCharToQuantum(TIFFGetG(*p));
+ q->blue=ScaleCharToQuantum(TIFFGetB(*p));
+ q->opacity=(Quantum) ScaleCharToQuantum(TIFFGetA(*p));
+ p--;
+ q--;
+ }
+ else
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ q->red=ScaleCharToQuantum(TIFFGetR(*p));
+ q->green=ScaleCharToQuantum(TIFFGetG(*p));
+ q->blue=ScaleCharToQuantum(TIFFGetB(*p));
+ p--;
+ q--;
+ }
+ /*
+ Disassociate alpha from pixels if necessary.
+ */
+ if ((image->matte) && (alpha_type == AssociatedAlpha))
+ DisassociateAlphaRegion(image);
+ if (!SyncImagePixels(image))
+ {
+ CopyException(exception,&image->exception);
+ status=MagickFail;
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (status == MagickFail)
+ break;
+ }
+ MagickFreeMemory(pixels);
+ break;
+ }
+ }
+
+ read_next_frame:
+ if (status == MagickPass)
+ {
+ if (image->depth > QuantumDepth)
+ image->depth=QuantumDepth;
+ if ((photometric == PHOTOMETRIC_LOGL) ||
+ (photometric == PHOTOMETRIC_MINISBLACK) ||
+ (photometric == PHOTOMETRIC_MINISWHITE))
+ image->is_grayscale=MagickTrue;
+ if ((image->is_grayscale == MagickTrue) && (bits_per_sample == 1))
+ image->is_monochrome=MagickTrue;
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ more_frames=TIFFReadDirectory(tiff);
+ if (more_frames)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(image->scene-1,image->scene,
+ &image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows);
+ }
+ }
+
+ if (status == MagickFail)
+ break;
+
+ } while ((status == MagickPass) && (more_frames));
+ TIFFClose(tiff);
+ if (status == MagickFail)
+ DeleteImageFromList(&image);
+ return GetFirstImageInList(image);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r T I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterTIFFImage adds attributes for the TIFF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterTIFFImage method is:
+%
+% void RegisterTIFFImage(void)
+%
+*/
+ModuleExport void
+RegisterTIFFImage(void)
+{
+#define BIGTIFFDescription "Tagged Image File Format (64-bit offsets)"
+#define GROUP4RAWDescription "CCITT Group4 RAW"
+#define PTIFDescription "Pyramid encoded TIFF"
+#define TIFFDescription "Tagged Image File Format"
+#if defined(HasTIFF)
+
+ static char
+ version[MaxTextExtent];
+
+ MagickInfo
+ *entry;
+
+ /*
+ Initialize thread specific data key.
+ */
+ if (tsd_key == (MagickTsdKey_t) 0)
+ (void) MagickTsdKeyCreate(&tsd_key);
+
+ version[0]='\0';
+ {
+ int
+ i;
+
+ const char
+ *p;
+
+ /* TIFFGetVersion() is in libtiff 3.5.3 and later */
+ for (p=TIFFGetVersion(), i=0;
+ (i < MaxTextExtent-1) && (*p != 0) && (*p != '\n');
+ p++, i++)
+ version[i] = *p;
+ version[i]=0;
+ }
+
+ /*
+ Big TIFF (64-bit offsets)
+ */
+#if defined(HasBigTIFF)
+ entry=SetMagickInfo("BIGTIFF");
+ entry->thread_support=MagickFalse; /* libtiff uses libjpeg which is not thread safe */
+ entry->decoder=(DecoderHandler) ReadTIFFImage;
+ entry->encoder=(EncoderHandler) WriteTIFFImage;
+ entry->seekable_stream=MagickTrue;
+ entry->description=BIGTIFFDescription;
+ entry->module="TIFF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+#endif /* defined(HasBigTIFF) */
+
+ /*
+ CCITT Group4 RAW encoded page.
+ */
+ entry=SetMagickInfo("GROUP4RAW");
+ entry->thread_support=MagickTrue;
+ /* entry->decoder=(DecoderHandler) ReadGROUP4RAWImage; */
+ entry->encoder=(EncoderHandler) WriteGROUP4RAWImage;
+ entry->raw=MagickTrue;
+ entry->adjoin=MagickFalse;
+ entry->seekable_stream=MagickFalse;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->stealth=MagickTrue; /* Don't list in '-list format' output */
+ entry->description=GROUP4RAWDescription;
+ entry->module="TIFF";
+ (void) RegisterMagickInfo(entry);
+
+ /*
+ Pyramid TIFF (sequence of successively smaller versions of the same image)
+ */
+ entry=SetMagickInfo("PTIF");
+ entry->thread_support=MagickFalse; /* libtiff uses libjpeg which is not thread safe */
+ entry->decoder=(DecoderHandler) ReadTIFFImage;
+ entry->encoder=(EncoderHandler) WritePTIFImage;
+ entry->seekable_stream=MagickTrue;
+ entry->description=PTIFDescription;
+ entry->module="TIFF";
+ (void) RegisterMagickInfo(entry);
+
+ /*
+ Another name for 32-bit TIFF
+ */
+ entry=SetMagickInfo("TIF");
+ entry->thread_support=MagickFalse; /* libtiff uses libjpeg which is not thread safe */
+ entry->decoder=(DecoderHandler) ReadTIFFImage;
+ entry->encoder=(EncoderHandler) WriteTIFFImage;
+ entry->seekable_stream=MagickTrue;
+ entry->description=TIFFDescription;
+ if (*version != '\0')
+ entry->version=version;
+ entry->stealth=MagickTrue; /* Don't list in '-list format' output */
+ entry->module="TIFF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ /*
+ Traditional 32-bit TIFF
+ */
+ entry=SetMagickInfo("TIFF");
+ entry->thread_support=MagickFalse; /* libtiff uses libjpeg which is not thread safe */
+ entry->decoder=(DecoderHandler) ReadTIFFImage;
+ entry->encoder=(EncoderHandler) WriteTIFFImage;
+ entry->magick=(MagickHandler) IsTIFF;
+ entry->seekable_stream=MagickTrue;
+ entry->description=TIFFDescription;
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="TIFF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+#if defined(EXTEND_TIFF_TAGS)
+ /*
+ Add our own TIFF tag extensions.
+ */
+ ExtensionTagsInitialize();
+#endif /* defined(EXTEND_TIFF_TAGS) */
+
+
+#endif /* if defined(HasTIFF) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r T I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterTIFFImage removes format registrations made by the
+% TIFF module from the list of supported formats.
+%
+% The format of the UnregisterTIFFImage method is:
+%
+% void UnregisterTIFFImage(void)
+%
+*/
+ModuleExport void
+UnregisterTIFFImage(void)
+{
+#if defined(HasTIFF)
+#if defined(HasBigTIFF)
+ (void) UnregisterMagickInfo("BIGTIFF");
+#endif /* defined(HasBigTIFF) */
+ (void) UnregisterMagickInfo("GROUP4RAW");
+ (void) UnregisterMagickInfo("PTIF");
+ (void) UnregisterMagickInfo("TIF");
+ (void) UnregisterMagickInfo("TIFF");
+
+ /*
+ Destroy thread specific data key.
+ */
+ if (tsd_key != (MagickTsdKey_t) 0)
+ {
+ (void) MagickTsdKeyDelete(tsd_key);
+ tsd_key = (MagickTsdKey_t) 0;
+ }
+#endif
+}
+
+#if defined(HasTIFF)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e G R O U P 4 R A W I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteGROUP4RAWImage writes an image as raw Group4 compressed data.
+%
+% The format of the WriteGROUP4RAWImage method is:
+%
+% MagickPassFail WriteGROUP4RAWImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WriteGROUP4RAWImage return True if the image is written.
+% False is returned is there is of a memory shortage or if the image
+% file cannot be opened for writing.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static MagickPassFail
+WriteGROUP4RAWImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ temporary_filename[MaxTextExtent];
+
+ Image
+ *huffman_image;
+
+ ImageInfo
+ *clone_info;
+
+ TIFF
+ *tiff;
+
+ toff_t
+ *byte_counts,
+ count,
+ strip_size;
+
+ unsigned char
+ *strip;
+
+ unsigned int
+ i;
+
+ MagickPassFail
+ status;
+
+ /*
+ Write image as CCITTFax4 TIFF image.
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if(!AcquireTemporaryFileName(temporary_filename))
+ ThrowWriterException(FileOpenError,UnableToCreateTemporaryFile,image);
+
+ huffman_image=CloneImage(image,0,0,True,&image->exception);
+ if (huffman_image == (Image *) NULL)
+ return(False);
+
+ (void) SetImageType(huffman_image,BilevelType);
+ FormatString(huffman_image->filename,"tiff:%s",temporary_filename);
+ clone_info=CloneImageInfo((const ImageInfo *) NULL);
+/* clone_info->blob=0; */
+ clone_info->compression=Group4Compression;
+ clone_info->type=BilevelType;
+ (void) AddDefinitions(clone_info,"tiff:strip-per-page=TRUE",
+ &image->exception);
+ (void) AddDefinitions(clone_info,"tiff:fill-order=msb2lsb",
+ &image->exception);
+ status=WriteImage(clone_info,huffman_image);
+ if (status == MagickFail)
+ CopyException(&image->exception,&huffman_image->exception);
+ DestroyImageInfo(clone_info);
+ DestroyImage(huffman_image);
+ if (status == MagickFail)
+ {
+ (void) LiberateTemporaryFile(temporary_filename);
+ return MagickFail;
+ }
+
+ (void) MagickTsdSetSpecific(tsd_key,(void *) (&image->exception));
+ (void) TIFFSetErrorHandler((TIFFErrorHandler) TIFFErrors);
+ (void) TIFFSetWarningHandler((TIFFErrorHandler) (CheckThrowWarnings(image_info) ?
+ TIFFWarningsThrowException :
+ TIFFWarningsLogOnly));
+
+ tiff=TIFFOpen(temporary_filename,"rb");
+ if (tiff == (TIFF *) NULL)
+ {
+ (void) LiberateTemporaryFile(temporary_filename);
+ return MagickFail;
+ }
+
+ /*
+ Allocate raw strip buffer.
+ */
+ if (TIFFGetField(tiff,TIFFTAG_STRIPBYTECOUNTS,&byte_counts) != 1)
+ {
+ TIFFClose(tiff);
+ (void) LiberateTemporaryFile(temporary_filename);
+ return MagickFail;
+ }
+ strip_size=byte_counts[0];
+ for (i=1; i < TIFFNumberOfStrips(tiff); i++)
+ if (byte_counts[i] > strip_size)
+ strip_size=byte_counts[i];
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Allocating %lu bytes of memory for TIFF strip",
+ (unsigned long) strip_size);
+ strip=MagickAllocateMemory(unsigned char *,(size_t) strip_size);
+ if (strip == (unsigned char *) NULL)
+ {
+ TIFFClose(tiff);
+ (void) LiberateTemporaryFile(temporary_filename);
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ /*
+ Open blob for output
+ */
+ if ((status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception))
+ == MagickFail)
+ {
+ MagickFreeMemory(strip);
+ TIFFClose(tiff);
+ (void) LiberateTemporaryFile(temporary_filename);
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+
+ /*
+ Compress runlength encoded to 2D Huffman pixels.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Output 2D Huffman pixels.");
+ for (i=0; i < TIFFNumberOfStrips(tiff); i++)
+ {
+ count=TIFFReadRawStrip(tiff,(uint32) i,strip,strip_size);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing strip %u (%lu bytes) to blob ...",
+ i,(unsigned long) count);
+ if ((toff_t) WriteBlob(image,count,strip) != count)
+ status=MagickFail;
+ }
+
+ MagickFreeMemory(strip);
+ TIFFClose(tiff);
+
+ (void) LiberateTemporaryFile(temporary_filename);
+ CloseBlob(image);
+ return status;
+}
+#endif /* if defined(HasTIFF) */
+
+#if defined(HasTIFF)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P T I F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WritePTIFImage() writes an image in the pyrimid-encoded Tagged image file
+% format.
+%
+% The format of the WritePTIFImage method is:
+%
+% MagickPassFail WritePTIFImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WritePTIFImage return MagickPass if the image is written.
+% MagickFail is returned is there is of a memory shortage or if the image
+% file cannot be opened for writing.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static MagickPassFail
+WritePTIFImage(const ImageInfo *image_info,Image *image)
+{
+ Image
+ *pyramid_image;
+
+ ImageInfo
+ *clone_info;
+
+ FilterTypes
+ filter;
+
+ unsigned int
+ status;
+
+ /*
+ Create pyramid-encoded TIFF image.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ filter=TriangleFilter;
+ if (image->is_monochrome)
+ filter=PointFilter;
+ pyramid_image=CloneImage(image,0,0,True,&image->exception);
+ if (pyramid_image == (Image *) NULL)
+ ThrowWriterException2(FileOpenError,image->exception.reason,image);
+ (void) SetImageAttribute(pyramid_image,"subfiletype","NONE");
+ do
+ {
+ pyramid_image->next=ResizeImage(image,pyramid_image->columns/2,
+ pyramid_image->rows/2,filter,
+ 1.0,&image->exception);
+ if (pyramid_image->next == (Image *) NULL)
+ ThrowWriterException2(FileOpenError,image->exception.reason,image);
+ if ((!image->is_monochrome) && (image->storage_class == PseudoClass))
+ (void) MapImage(pyramid_image->next,image,False);
+ pyramid_image->next->x_resolution=pyramid_image->x_resolution/2;
+ pyramid_image->next->y_resolution=pyramid_image->y_resolution/2;
+ (void) SetImageAttribute(pyramid_image->next,"subfiletype","REDUCEDIMAGE");
+ pyramid_image->next->previous=pyramid_image;
+ pyramid_image=pyramid_image->next;
+ } while ((pyramid_image->columns > 64) && (pyramid_image->rows > 64));
+ while (pyramid_image->previous != (Image *) NULL)
+ pyramid_image=pyramid_image->previous;
+ /*
+ Write pyramid-encoded TIFF image.
+ */
+ clone_info=CloneImageInfo(image_info);
+ clone_info->adjoin=True;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Invoking \"%.1024s\" encoder, monochrome=%s, grayscale=%s",
+ "TIFF",
+ MagickBoolToString(image->is_monochrome),
+ MagickBoolToString(image->is_grayscale));
+ status=WriteTIFFImage(clone_info,pyramid_image);
+ DestroyImageList(pyramid_image);
+ DestroyImageInfo(clone_info);
+ return(status);
+}
+#endif /* defined(HasTIFF) */
+
+#if defined(HasTIFF)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e T I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteTIFFImage writes an image in the Tagged image file format.
+%
+% The format of the WriteTIFFImage method is:
+%
+% MagickPassFail WriteTIFFImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method WriteTIFFImage return True if the image is written.
+% False is returned is there is of a memory shortage or if the image
+% file cannot be opened for writing.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static void
+WriteNewsProfile(TIFF *tiff,
+ int profile_tag,
+ const unsigned char *profile_data,
+ const size_t profile_length)
+{
+ unsigned char
+ *profile=0;
+
+ uint32
+ length;
+
+ assert(tiff != (TIFF *) NULL);
+ assert(profile_tag != 0);
+ assert(profile_data != (const unsigned char *) NULL);
+
+ length = (uint32) profile_length;
+ if (length == 0)
+ return;
+
+ if (profile_tag == TIFFTAG_RICHTIFFIPTC)
+ {
+ /*
+ Handle TIFFTAG_RICHTIFFIPTC tag.
+ */
+ length += (4-(length & 0x03)); /* Round up for long word alignment */
+ profile=MagickAllocateMemory(unsigned char *,length);
+ if (profile == (unsigned char *) NULL)
+ return;
+ (void) memset(profile,0,length);
+ (void) memcpy(profile,profile_data,profile_length);
+
+ if (TIFFIsByteSwapped(tiff))
+ TIFFSwabArrayOfLong((uint32 *) profile,length/4);
+
+ /* Tag is type TIFF_LONG so byte length is divided by four */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFFSetField(tiff=0x%p,tag=%d,length=%lu,data=0x%p)",
+ tiff,profile_tag,(unsigned long) length/4,profile);
+ (void) TIFFSetField(tiff,profile_tag,(uint32) length/4,(void *) profile);
+ }
+ else if (profile_tag == TIFFTAG_PHOTOSHOP)
+ {
+ /*
+ Handle TIFFTAG_PHOTOSHOP tag.
+ */
+ length += (length & 0x01); /* Round up for Photoshop */
+#if defined(GET_ONLY_IPTC_DATA)
+ length += 12; /* Space for 8BIM header */
+ profile=MagickAllocateMemory(unsigned char *,length);
+ if (profile == (unsigned char *) NULL)
+ return;
+ (void) memset(profile,0,length);
+ (void) memcpy(profile,"8BIM\04\04\0\0",8);
+ profile[8]=(length >> 24) & 0xff;
+ profile[9]=(length >> 16) & 0xff;
+ profile[10]=(length >> 8) & 0xff;
+ profile[11]=length & 0xff;
+ (void) memcpy(profile+12,profile_data,profile_length);
+#else
+ profile=MagickAllocateMemory(unsigned char *,length);
+ if (profile == (unsigned char *) NULL)
+ return;
+ (void) memset(profile,0,length);
+ (void) memcpy(profile,profile_data,profile_length);
+#endif
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFFSetField(tiff=0x%p,tag=%d,length=%lu,data=0x%p)",
+ tiff,profile_tag,(unsigned long) length,profile);
+ (void) TIFFSetField(tiff,profile_tag,(uint32) length,(void *) profile);
+ }
+
+ MagickFreeMemory(profile);
+}
+
+#if !defined(TIFFDefaultStripSize)
+#define TIFFDefaultStripSize(tiff,request) ((8*1024)/TIFFScanlineSize(tiff))
+#endif
+static MagickPassFail
+WriteTIFFImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ filename[MaxTextExtent],
+ open_flags[MaxTextExtent];
+
+ const ImageAttribute
+ *attribute;
+
+ unsigned int
+ x,
+ y;
+
+ register unsigned int
+ i;
+
+ TIFF
+ *tiff;
+
+ uint16
+ bits_per_sample,
+ compress_tag,
+ fill_order,
+ photometric,
+ planar_config,
+ predictor,
+ sample_format,
+ samples_per_pixel;
+
+ uint32
+ rows_per_strip;
+
+ tsize_t
+ scanline_size;
+
+ AlphaType
+ alpha_type;
+
+ CompressionType
+ compression=UndefinedCompression;
+
+ TIFFMethod
+ method;
+
+ Magick_TIFF_ClientData
+ client_data;
+
+ ExportPixelAreaOptions
+ export_options;
+
+ ExportPixelAreaInfo
+ export_info;
+
+ MagickBool
+ logging=MagickFalse;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ depth,
+ scene;
+
+ /*
+ Open TIFF file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=IsEventLogging();
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) MagickTsdSetSpecific(tsd_key,(void *) (&image->exception));
+ (void) TIFFSetErrorHandler((TIFFErrorHandler) TIFFErrors);
+ (void) TIFFSetWarningHandler((TIFFErrorHandler) (CheckThrowWarnings(image_info) ?
+ TIFFWarningsThrowException :
+ TIFFWarningsLogOnly));
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ /*
+ Open TIFF file
+
+ 'w' open for write
+ 'l' force little-endian byte order
+ 'b' force big-endian byte order
+ 'L' force LSB to MSB bit order (weird)
+ 'B' force MSB to LSB bit order (normal)
+ '8' 64-bit offsets (BigTIFF)
+ */
+ (void) strlcpy(open_flags, "w", sizeof(open_flags));
+ switch (image_info->endian)
+ {
+ case LSBEndian:
+ (void) strlcat(open_flags, "l", sizeof(open_flags));
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using little endian byte order");
+ break;
+ case MSBEndian:
+ (void) strlcat(open_flags, "b", sizeof(open_flags));
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using big endian byte order");
+ break;
+ default:
+ case UndefinedEndian:
+ {
+ /* Default is native byte order */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using native endian byte order");
+ }
+ }
+
+#if defined(HasBigTIFF)
+ if (strcmp(image_info->magick,"BIGTIFF") == 0)
+ {
+ (void) strlcat(open_flags, "8", sizeof(open_flags));
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using 64-bit offsets (BigTIFF format)");
+ }
+#endif
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Opening TIFF file \"%s\" using open flags \"%s\".",
+ filename,open_flags);
+ client_data.image=image;
+ client_data.image_info=image_info;
+ tiff=TIFFClientOpen(filename,open_flags,(thandle_t) &client_data,
+ TIFFReadBlob,TIFFWriteBlob,TIFFSeekBlob,
+ TIFFCloseBlob,TIFFGetBlobSize,TIFFMapBlob,
+ TIFFUnmapBlob);
+ if (tiff == (TIFF *) NULL)
+ {
+ /* CloseBlob(image); */
+ return(MagickFail);
+ }
+ scene=0;
+ do
+ {
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Initialize TIFF fields.
+ */
+ (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_SAMPLESPERPIXEL,
+ &samples_per_pixel);
+ (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_BITSPERSAMPLE,
+ &bits_per_sample);
+ (void) TIFFGetFieldDefaulted(tiff,TIFFTAG_SAMPLEFORMAT,&sample_format);
+ (void) TIFFSetField(tiff,TIFFTAG_IMAGELENGTH,(uint32) image->rows);
+ (void) TIFFSetField(tiff,TIFFTAG_IMAGEWIDTH,(uint32) image->columns);
+
+ ExportPixelAreaOptionsInit(&export_options);
+ depth=image->depth;
+ bits_per_sample=8;
+ predictor=0U;
+ method=ScanLineMethod;
+ if ((AccessDefinition(image_info,"tiff","tile")) ||
+ (AccessDefinition(image_info,"tiff","tile-geometry")) ||
+ (AccessDefinition(image_info,"tiff","tile-width")) ||
+ (AccessDefinition(image_info,"tiff","tile-height")))
+ method=TiledMethod;
+
+ /*
+ Decide how to compress the image.
+ */
+ compression=image->compression;
+ if (image_info->compression != UndefinedCompression)
+ compression=image_info->compression;
+ if (UndefinedCompression == compression)
+ compression=NoCompression;
+
+ /*
+ Ensure that only supported compression types are requested.
+ */
+ {
+ char
+ compression_name[MaxTextExtent];
+
+ if (CompressionSupported(compression,compression_name) != MagickTrue)
+ {
+ compression=NoCompression;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%s compression not supported. "
+ "Compression request removed",
+ compression_name);
+ }
+ }
+
+ /*
+ Determine libtiff compression settings.
+ */
+ compress_tag=COMPRESSION_NONE;
+ fill_order=FILLORDER_MSB2LSB;
+ switch (compression)
+ {
+ /*
+ Note that RFC 2301 recommends using LSB2MSB fill order for FAX
+ since it is the transmission order used on the wire for FAX.
+ However, it also states that all conforming readers should be
+ able to read data in both bit orders.
+ */
+ case FaxCompression:
+ {
+ compress_tag=COMPRESSION_CCITTFAX3;
+ fill_order=FILLORDER_LSB2MSB;
+ break;
+ }
+ case Group4Compression:
+ {
+ compress_tag=COMPRESSION_CCITTFAX4;
+ fill_order=FILLORDER_LSB2MSB;
+ break;
+ }
+#if defined(COMPRESSION_JBIG)
+ case JBIG1Compression:
+ {
+ compress_tag=COMPRESSION_JBIG;
+ fill_order=FILLORDER_LSB2MSB;
+ break;
+ }
+#endif /* defined(COMPRESSION_JBIG) */
+ case JPEGCompression:
+ {
+ compress_tag=COMPRESSION_JPEG;
+ break;
+ }
+ case LZWCompression:
+ {
+ compress_tag=COMPRESSION_LZW;
+ break;
+ }
+#if defined(COMPRESSION_LZMA)
+ case LZMACompression:
+ {
+ compress_tag=COMPRESSION_LZMA;
+ break;
+ }
+#endif /* defined(COMPRESSION_LZMA) */
+ case RLECompression:
+ {
+ compress_tag=COMPRESSION_PACKBITS;
+ break;
+ }
+ case ZipCompression:
+ {
+ compress_tag=COMPRESSION_ADOBE_DEFLATE;
+ break;
+ }
+ default:
+ {
+ compress_tag=COMPRESSION_NONE;
+ break;
+ }
+ }
+
+ /*
+ Ensure that image is in desired output space
+ */
+ if ((image_info->type != UndefinedType) &&
+ (image_info->type != OptimizeType))
+ (void) SetImageType(image,image_info->type);
+ else if (!IsCMYKColorspace(image->colorspace) &&
+ (!IsRGBColorspace(image->colorspace)))
+ (void) TransformColorspace(image,RGBColorspace);
+
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ status=MagickFail;
+ break;
+ }
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image characteristics: cmyk=%c, gray=%c, mono=%c,"
+ " opaque=%c, palette=%c",
+ (characteristics.cmyk ? 'y' : 'n'),
+ (characteristics.grayscale ? 'y' : 'n'),
+ (characteristics.monochrome ? 'y' : 'n'),
+ (characteristics.opaque ? 'y' : 'n'),
+ (characteristics.palette ? 'y' : 'n'));
+
+
+ /*
+ Some compression types do not work with a matte channel.
+ Disable matte channel for these types.
+ */
+ if (image->matte)
+ {
+ switch (compress_tag)
+ {
+ case COMPRESSION_CCITTFAX3:
+ case COMPRESSION_CCITTFAX4:
+ case COMPRESSION_JBIG:
+ case COMPRESSION_JPEG:
+ {
+ if (logging)
+ {
+ const char *
+ compress_type;
+
+ compress_type=CompressionTagToString(compress_tag);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Disabled image matte channel since "
+ "%s compression not supported with "
+ "alpha channel.",
+ compress_type);
+ }
+ image->matte=MagickFalse;
+ break;
+ }
+ default:
+ {
+ }
+ }
+ }
+
+ /*
+ Choose best photometric based on image properties.
+ */
+ if (characteristics.cmyk)
+ {
+ photometric=PHOTOMETRIC_SEPARATED;
+ }
+ else if (characteristics.monochrome)
+ {
+ photometric=PHOTOMETRIC_MINISWHITE;
+ }
+ else if (characteristics.palette)
+ {
+ photometric=PHOTOMETRIC_PALETTE;
+ }
+ else if (characteristics.grayscale)
+ {
+ photometric=PHOTOMETRIC_MINISBLACK;
+ }
+ else
+ {
+ photometric=PHOTOMETRIC_RGB;
+ }
+
+ /*
+ If optimization is requested, disable matte channel if image
+ is opaque.
+ */
+ if ((OptimizeType == image_info->type) &&
+ (characteristics.opaque && image->matte))
+ {
+ image->matte=MagickFalse;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Disabled image matte channel since image is "
+ "opaque.");
+ }
+
+ /*
+ Currently we only support JPEG compression with MINISWHITE,
+ MINISBLACK, and RGB. FAX compression types require
+ MINISWHITE. CMYK takes precedence over JPEG compression.
+ */
+ if ((compress_tag == COMPRESSION_JPEG) &&
+ (photometric == PHOTOMETRIC_PALETTE))
+ {
+ photometric=PHOTOMETRIC_RGB;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using RGB photometric due to request for"
+ " JPEG compression.");
+ }
+ else if (compress_tag == COMPRESSION_CCITTFAX3)
+ {
+ photometric=PHOTOMETRIC_MINISWHITE;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using MINISWHITE photometric due to request"
+ " for Group3 FAX compression.");
+ }
+ else if (compress_tag == COMPRESSION_CCITTFAX4)
+ {
+ photometric=PHOTOMETRIC_MINISWHITE;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using MINISWHITE photometric due to request"
+ " for Group4 FAX compression.");
+ }
+#if defined(COMPRESSION_JBIG)
+ else if (compress_tag == COMPRESSION_JBIG)
+ {
+ photometric=PHOTOMETRIC_MINISWHITE;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using MINISWHITE photometric due to request"
+ " for JBIG compression.");
+ }
+#endif /* defined(COMPRESSION_JBIG) */
+
+ /*
+ Allow user to override the photometric.
+ */
+ switch (image_info->type)
+ {
+ case BilevelType:
+ {
+ photometric=PHOTOMETRIC_MINISWHITE;
+ break;
+ }
+ case GrayscaleType:
+ {
+ photometric=PHOTOMETRIC_MINISBLACK;
+ break;
+ }
+ case GrayscaleMatteType:
+ {
+ photometric=PHOTOMETRIC_MINISBLACK;
+ if (!image->matte)
+ SetImageOpacity(image,OpaqueOpacity);
+ break;
+ }
+ case PaletteType:
+ {
+ photometric=PHOTOMETRIC_PALETTE;
+ break;
+ }
+ case PaletteMatteType:
+ {
+ photometric=PHOTOMETRIC_PALETTE;
+ if (!image->matte)
+ SetImageOpacity(image,OpaqueOpacity);
+ break;
+ }
+ case TrueColorType:
+ {
+ photometric=PHOTOMETRIC_RGB;
+ break;
+ }
+ case TrueColorMatteType:
+ {
+ photometric=PHOTOMETRIC_RGB;
+ if (!image->matte)
+ SetImageOpacity(image,OpaqueOpacity);
+ break;
+ }
+ case ColorSeparationType:
+ {
+ photometric=PHOTOMETRIC_SEPARATED;
+ break;
+ }
+ case ColorSeparationMatteType:
+ {
+ photometric=PHOTOMETRIC_SEPARATED;
+ if (!image->matte)
+ SetImageOpacity(image,OpaqueOpacity);
+ break;
+ }
+ case UndefinedType:
+ case OptimizeType:
+ {
+ /* No special handling */
+ }
+ }
+
+ /*
+ If the user has selected something other than MINISWHITE,
+ MINISBLACK, or RGB, then remove JPEG compression. Also remove
+ fax compression if photometric is not compatible.
+ */
+ if ((compress_tag == COMPRESSION_JPEG) &&
+ ((photometric != PHOTOMETRIC_MINISWHITE) &&
+ (photometric != PHOTOMETRIC_MINISBLACK) &&
+ (photometric != PHOTOMETRIC_RGB) &&
+ (photometric != PHOTOMETRIC_YCBCR)))
+ {
+ compress_tag=COMPRESSION_NONE;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Ignoring request for JPEG compression due "
+ "to incompatible photometric.");
+ }
+ else if ((compress_tag == COMPRESSION_CCITTFAX3) &&
+ (photometric != PHOTOMETRIC_MINISWHITE))
+ {
+ compress_tag=COMPRESSION_NONE;
+ fill_order=FILLORDER_MSB2LSB;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Ignoring request for Group3 FAX compression"
+ " due to incompatible photometric.");
+ }
+ else if ((compress_tag == COMPRESSION_CCITTFAX4) &&
+ (photometric != PHOTOMETRIC_MINISWHITE))
+ {
+ compress_tag=COMPRESSION_NONE;
+ fill_order=FILLORDER_MSB2LSB;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Ignoring request for Group4 FAX compression"
+ " due to incompatible photometric.");
+ }
+#if defined(COMPRESSION_JBIG)
+ else if ((compress_tag == COMPRESSION_JBIG) &&
+ (photometric != PHOTOMETRIC_MINISWHITE))
+ {
+ compress_tag=COMPRESSION_NONE;
+ fill_order=FILLORDER_MSB2LSB;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Ignoring request for JBIG compression"
+ " due to incompatible photometric.");
+ }
+#endif /* defined(COMPRESSION_JBIG) */
+
+ /*
+ Bilevel presents a bit of a quandary since the user is free to
+ change the type so we don't want to set depth in advance. So
+ we will intuit the depth here. For the moment, we assume that
+ if the photometric is PHOTOMETRIC_MINISWHITE that we are
+ probably outputting bilevel. Note that the user is still able
+ to override bits_per_sample.
+ */
+ if (PHOTOMETRIC_MINISWHITE == photometric)
+ depth=1;
+
+ /*
+ Support writing bits per sample of 8, 16, & 32 by default.
+ */
+ for (bits_per_sample=8; bits_per_sample < depth; )
+ bits_per_sample*=2;
+
+ /*
+ Now chose appropriate settings for the photometric.
+ */
+ switch (photometric)
+ {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ {
+ samples_per_pixel=1;
+ if (depth == 1)
+ bits_per_sample=1;
+ break;
+ }
+ case PHOTOMETRIC_RGB:
+ {
+ samples_per_pixel=3;
+ break;
+ }
+ case PHOTOMETRIC_PALETTE:
+ {
+ samples_per_pixel=1;
+ bits_per_sample=1;
+ /*
+ Support colormap indexes of 1, 2, 4, 8, and 16 by default.
+ */
+ while ((1UL << bits_per_sample) < image->colors)
+ bits_per_sample*=2;
+ break;
+ }
+ case PHOTOMETRIC_SEPARATED:
+ {
+ samples_per_pixel=4; /* CMYK */
+
+ (void) TIFFSetField(tiff,TIFFTAG_INKSET,INKSET_CMYK);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using INKSET_CMYK");
+ break;
+ }
+ case PHOTOMETRIC_YCBCR:
+ {
+ /* This is here to support JPEGCOLORMODE_RGB*/
+ samples_per_pixel=3;
+ break;
+ }
+ }
+
+ if (COMPRESSION_JPEG == compress_tag)
+ {
+ /*
+ JPEG compression can only use size specified by
+ BITS_IN_JSAMPLE (except for MK1 JPEG) which supports two
+ sizes.
+
+ Maybe there is a tricky way to obtain this value from
+ libtiff or libtiff can be extended?
+
+ FIXME
+ */
+#if defined(BITS_IN_JSAMPLE)
+ depth=BITS_IN_JSAMPLE;
+ bits_per_sample=BITS_IN_JSAMPLE;
+#endif
+ }
+
+ alpha_type=UnspecifiedAlpha;
+ if (image->matte)
+ {
+ /*
+ Image has a matte channel. Mark it correctly.
+ */
+ uint16
+ extra_samples,
+ sample_info[1];
+
+ const char *
+ value;
+
+ if ((value=AccessDefinition(image_info,"tiff","alpha")))
+ {
+ if (LocaleCompare(value,"unspecified") == 0)
+ alpha_type=UnspecifiedAlpha;
+ else if (LocaleCompare(value,"associated") == 0)
+ alpha_type=AssociatedAlpha;
+ else if (LocaleCompare(value,"unassociated") == 0)
+ alpha_type=UnassociatedAlpha;
+ }
+ else if ((attribute=GetImageAttribute(image,"alpha")))
+ {
+ if (LocaleCompare(attribute->value,"unspecified") == 0)
+ alpha_type=UnspecifiedAlpha;
+ else if (LocaleCompare(attribute->value,"associated") == 0)
+ alpha_type=AssociatedAlpha;
+ else if (LocaleCompare(attribute->value,"unassociated") == 0)
+ alpha_type=UnassociatedAlpha;
+ }
+
+ samples_per_pixel += 1;
+ extra_samples=1;
+ sample_info[0]=EXTRASAMPLE_ASSOCALPHA;
+ switch (alpha_type)
+ {
+ case UnspecifiedAlpha:
+ {
+ sample_info[0]=EXTRASAMPLE_UNSPECIFIED;
+ break;
+ }
+ case AssociatedAlpha:
+ {
+ sample_info[0]=EXTRASAMPLE_ASSOCALPHA;
+ break;
+ }
+ case UnassociatedAlpha:
+ {
+ sample_info[0]=EXTRASAMPLE_UNASSALPHA;
+ break;
+ }
+ }
+
+ (void) TIFFSetField(tiff,TIFFTAG_EXTRASAMPLES,extra_samples,
+ &sample_info);
+ }
+
+ /*
+ Allow the advanced user to over-ride some TIFF write options
+ */
+ {
+ const char *
+ value;
+
+ unsigned int
+ old_value;
+
+ /*
+ Fill order
+ */
+ value=AccessDefinition(image_info,"tiff","fill-order");
+ if (value)
+ {
+ if (LocaleNCompare(value,"msb2lsb",3) == 0)
+ fill_order=FILLORDER_MSB2LSB;
+ else if (LocaleNCompare(value,"lsb2msb",3) == 0)
+ fill_order=FILLORDER_LSB2MSB;
+ }
+
+ /*
+ Sample format
+ */
+ value=AccessDefinition(image_info,"tiff","sample-format");
+ if (value)
+ {
+ if (LocaleCompare(value,"unsigned") == 0)
+ sample_format=SAMPLEFORMAT_UINT;
+ else if (LocaleCompare(value,"ieeefp") == 0)
+ sample_format=SAMPLEFORMAT_IEEEFP;
+ }
+
+ /*
+ Bits per sample (needs to be after sample format)
+ */
+ value=AccessDefinition(image_info,"tiff","bits-per-sample");
+ if (value)
+ {
+ old_value=bits_per_sample;
+ bits_per_sample=MagickAtoI(value);
+ if (sample_format == SAMPLEFORMAT_IEEEFP)
+ {
+ /*
+ If floating point is selected, ensure that valid
+ bits-per-sample values are specified.
+ */
+ if ((bits_per_sample != 16) &&
+ (bits_per_sample != 24) &&
+ (bits_per_sample != 32) &&
+ (bits_per_sample != 64))
+ bits_per_sample=32;
+ }
+ else
+ {
+ /* Clamp maximum unsigned bits per sample to 32 bits */
+ if ((bits_per_sample < 1) ||
+ ((bits_per_sample > 32) && (bits_per_sample != 64)))
+ bits_per_sample=old_value;
+ }
+ if ((logging) && (old_value != bits_per_sample))
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "User override (bits-per-sample): %u bits "
+ "per sample (was %u)",
+ (unsigned int) bits_per_sample, old_value);
+ }
+
+ /*
+ Samples per pixel
+ */
+ value=AccessDefinition(image_info,"tiff","samples-per-pixel");
+ if (value)
+ {
+ old_value=samples_per_pixel;
+ samples_per_pixel=MagickAtoI(value);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "User override (samples-per-pixel): %u "
+ "samples per pixel (was %u)",
+ (unsigned int) samples_per_pixel, old_value);
+ }
+ }
+
+ /*
+ Determine planar configuration.
+ */
+ planar_config=PLANARCONFIG_CONTIG;
+ if (samples_per_pixel > 1)
+ {
+ switch (image->interlace)
+ {
+ case UndefinedInterlace:
+ break;
+ case NoInterlace:
+ case LineInterlace:
+ case PartitionInterlace:
+ planar_config=PLANARCONFIG_CONTIG;
+ break;
+ case PlaneInterlace:
+ planar_config=PLANARCONFIG_SEPARATE;
+ break;
+ }
+
+ switch (image_info->interlace)
+ {
+ case UndefinedInterlace:
+ break;
+ case NoInterlace:
+ case LineInterlace:
+ case PartitionInterlace:
+ planar_config=PLANARCONFIG_CONTIG;
+ break;
+ case PlaneInterlace:
+ planar_config=PLANARCONFIG_SEPARATE;
+ break;
+ }
+ }
+
+ /*
+ YCbCr encoding compresses much better than RGB. Use YCbCr
+ encoding for JPEG (normal for JPEG files).
+
+ FIXME: Need to find a way to select between RGB or YCbCr
+ encoding with JPEG compression. Testing shows that YCbCr is
+ over 2.5X smaller than RGB but the PSNR is a bit lower,
+ particularly in red and blue channels. Someone might want to
+ use RGB to minimize color loss.
+ */
+ if ((compress_tag == COMPRESSION_JPEG) &&
+ (planar_config == PLANARCONFIG_CONTIG) &&
+ (photometric == PHOTOMETRIC_RGB))
+ photometric=PHOTOMETRIC_YCBCR;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using %s photometric, %u samples per pixel, "
+ "%u bits per sample, format %s",
+ PhotometricTagToString(photometric),
+ (unsigned int) samples_per_pixel,
+ (unsigned int) bits_per_sample,
+ sample_format == SAMPLEFORMAT_UINT ? "Unsigned" :
+ sample_format == SAMPLEFORMAT_IEEEFP ? "IEEEFP" :
+ "unknown");
+
+ /*
+ Only set fill order if the setting is not the default.
+ */
+ if (FILLORDER_MSB2LSB != fill_order)
+ (void) TIFFSetField(tiff,TIFFTAG_FILLORDER,fill_order);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using %s bit fill order",
+ (fill_order == FILLORDER_MSB2LSB ? "MSB2LSB" :
+ (fill_order == FILLORDER_LSB2MSB ? "LSB2MSB" :
+ "undefined")));
+ if (image->orientation != UndefinedOrientation)
+ (void) TIFFSetField(tiff,TIFFTAG_ORIENTATION,(uint16) image->orientation);
+ (void) TIFFSetField(tiff,TIFFTAG_PHOTOMETRIC,photometric);
+ (void) TIFFSetField(tiff,TIFFTAG_BITSPERSAMPLE,bits_per_sample);
+ (void) TIFFSetField(tiff,TIFFTAG_SAMPLESPERPIXEL,samples_per_pixel);
+ (void) TIFFSetField(tiff,TIFFTAG_SAMPLEFORMAT,sample_format);
+ (void) TIFFSetField(tiff,TIFFTAG_PLANARCONFIG,planar_config);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "%s image planes",
+ (planar_config == PLANARCONFIG_SEPARATE ?
+ "Separate" : "Contiguous"));
+ (void) TIFFSetField(tiff,TIFFTAG_COMPRESSION,compress_tag);
+
+ /*
+ Obtain recommended rows per strip given current image width,
+ bits per sample, samples per pixel, tags, and compression
+ specific requirements. Tries to create strips with 8K of
+ uncompressed data.
+ */
+ scanline_size=TIFFScanlineSize(tiff);
+ rows_per_strip=TIFFDefaultStripSize(tiff,0);
+ if (rows_per_strip < 1)
+ rows_per_strip=1;
+ /*
+ It seems that some programs fail to handle more than 32K or
+ 64K strips in an image due to using a 16-bit strip counter.
+ The solution is to use a larger strip size. This approach
+ might cause excessively large strips for mega-sized images and
+ someday we may remove the solution since the problematic
+ readers will have expired.
+ */
+ if ((image->rows/rows_per_strip) > 32767)
+ rows_per_strip=image->rows/32768;
+ if (rows_per_strip < 1)
+ rows_per_strip=1;
+
+ switch (compress_tag)
+ {
+ case COMPRESSION_JPEG:
+ {
+ /*
+ RowsPerStrip must be multiple of 16 for JPEG.
+
+ RowsPerStrip is required to be a multiple of 8 times the
+ largest vertical sampling factor. If YCbCr subsampling
+ is 2,2 then RowsPerStrip must be a multiple of 16.
+ */
+ rows_per_strip=(((rows_per_strip < 16 ? 16 : rows_per_strip)+1)/16)*16;
+ (void) TIFFSetField(tiff,TIFFTAG_JPEGQUALITY,image_info->quality);
+ if (IsRGBColorspace(image->colorspace))
+ (void) TIFFSetField(tiff,TIFFTAG_JPEGCOLORMODE,JPEGCOLORMODE_RGB);
+ if (bits_per_sample == 12)
+ (void) TIFFSetField(tiff,TIFFTAG_JPEGTABLESMODE,JPEGTABLESMODE_QUANT);
+ break;
+ }
+ case COMPRESSION_ADOBE_DEFLATE:
+ {
+ /*
+ Deflate strips compress better up to 32K of data
+ (enlarge if necessary)..
+ */
+ unsigned int
+ proposed_rows_per_strip;
+
+ proposed_rows_per_strip = (uint32) (32*1024) / Max(scanline_size,1);
+ if (proposed_rows_per_strip > rows_per_strip)
+ rows_per_strip=proposed_rows_per_strip;
+ /*
+ Use horizontal differencing (type 2) for images which are
+ likely to be continuous tone. The TIFF spec says that this
+ usually leads to better compression.
+ */
+ if (((photometric == PHOTOMETRIC_RGB) ||
+ (photometric == PHOTOMETRIC_MINISBLACK)) &&
+ ((bits_per_sample == 8) || (bits_per_sample == 16)))
+ predictor=PREDICTOR_HORIZONTAL;
+ {
+ /*
+ Zip quality has a useful range of 1-9.
+ */
+ unsigned int zip_quality=image_info->quality / 10;
+ if (zip_quality < 1)
+ zip_quality=1;
+ if (zip_quality > 9)
+ zip_quality=9;
+ (void) TIFFSetField(tiff,TIFFTAG_ZIPQUALITY,zip_quality);
+ }
+ break;
+ }
+ case COMPRESSION_CCITTFAX3:
+ {
+ /*
+ Set Group 3 Options. Group 3 options are arranged as 32 flag bits.
+ Specify byte-aligned EOL padding option.
+
+ Group3Options = 4,5. LONG. Data may be one- or
+ two-dimensional, but EOLs must be
+ byte-aligned. Uncompressed data is not allowed.
+
+ bit 0 = 0 for 1-Dimensional, 1 for 2-Dimensional
+
+ bit 1 = must be 0 (uncompressed data not allowed)
+
+ bit 2 = 1 for byte-aligned EOLs
+
+ */
+ uint32
+ group_three_options = 4;
+
+ const char *
+ value;
+
+ if ((value=AccessDefinition(image_info,"tiff","group-three-options")))
+ {
+ group_three_options=(uint32) strtol(value,(char **)NULL, 10);
+ }
+ (void) TIFFSetField(tiff,TIFFTAG_GROUP3OPTIONS,group_three_options);
+
+ /*
+ It is recommended (but not required) to output FAX as
+ one strip. We will limit strip size to 16 megapixels by
+ default.
+ */
+ rows_per_strip=16000000UL/image->columns;
+ if (rows_per_strip < 1)
+ rows_per_strip=1;
+ if (rows_per_strip > image->rows)
+ rows_per_strip=(uint32) image->rows;
+ break;
+ }
+ case COMPRESSION_CCITTFAX4:
+ {
+ /*
+ It is recommended (but not required) to output FAX as
+ one strip. We will limit strip size to 16 megapixels by
+ default.
+ */
+ rows_per_strip=16000000UL/image->columns;
+ if (rows_per_strip < 1)
+ rows_per_strip=1;
+ if (rows_per_strip > image->rows)
+ rows_per_strip=(uint32) image->rows;
+ break;
+ }
+#if defined(COMPRESSION_LZMA)
+ case COMPRESSION_LZMA:
+ {
+ unsigned int
+ lzma_preset;
+
+ const char *
+ lzma_preset_str;
+
+ /*
+ Lzma preset has a useful range of 1-9.
+
+ We default to 1 since testing does not show much benefit
+ from use of larger values. However, we allow the
+ power-user who wants to experiment to change the preset
+ value via syntax like '-define tiff:lzmapreset=7'. This
+ ability is intentionally not documented other than here.
+ */
+
+ lzma_preset=1;
+ if ((lzma_preset_str=AccessDefinition(image_info,"tiff","lzmapreset")))
+ lzma_preset=(unsigned short) MagickAtoI(lzma_preset_str);
+
+ if (lzma_preset < 1)
+ lzma_preset=1;
+ if (lzma_preset > 9)
+ lzma_preset=9;
+ (void) TIFFSetField(tiff,TIFFTAG_LZMAPRESET,lzma_preset);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "LZMA PRESET set to %u", lzma_preset);
+
+ {
+ /*
+ Provide a default rows-per-strip which is suitably
+ tailored for the compression level.
+ */
+
+ /*
+ Strip memory target for various compression preset levels.
+ Values are arbitrary. LZMA is a memory and CPU pig.
+ */
+ static const unsigned int
+ lzma_memory_mb[] =
+ { /* Level Compress Decompress */
+ 1U, /* 1 2 MB 1 MB */
+ 4U, /* 2 12 MB 2 MB */
+ 4U, /* 3 12 MB 1 MB */
+ 4U, /* 4 16 MB 2 MB */
+ 6U, /* 5 26 MB 3 MB */
+ 10U, /* 6 45 MB 5 MB */
+ 18U, /* 7 83 MB 9 MB */
+ 34U, /* 8 159 MB 17 MB */
+ 66U /* 9 311 MB 33 MB */
+ };
+
+ rows_per_strip = (uint32) (((lzma_memory_mb[lzma_preset-1]*1024U*1024U))/
+ ((((unsigned long) bits_per_sample*samples_per_pixel)/
+ 8U)*image->rows));
+ if (rows_per_strip < 1)
+ rows_per_strip=1U;
+ if (rows_per_strip > image->rows)
+ rows_per_strip=image->rows;
+ }
+
+ /*
+ Use horizontal differencing (type 2) for images which are
+ likely to be continuous tone. The TIFF spec says that this
+ usually leads to better compression.
+ */
+ if (((photometric == PHOTOMETRIC_RGB) ||
+ (photometric == PHOTOMETRIC_MINISBLACK)) &&
+ ((bits_per_sample == 8) || (bits_per_sample == 16)))
+ predictor=PREDICTOR_HORIZONTAL;
+ break;
+ }
+#endif /* COMPRESSION_LZMA */
+#if defined(COMPRESSION_JBIG)
+ case COMPRESSION_JBIG:
+ {
+ /*
+ It is recommended (but not required) to output FAX as
+ one strip. We will limit strip size to 16 megapixels by
+ default.
+ */
+ rows_per_strip=16000000UL/image->columns;
+ if (rows_per_strip < 1)
+ rows_per_strip=1;
+ if (rows_per_strip > image->rows)
+ rows_per_strip=(uint32) image->rows;
+ break;
+ }
+#endif /* COMPRESSION_JBIG */
+ case COMPRESSION_LZW:
+ {
+ /*
+ Use horizontal differencing (type 2) for images which are
+ likely to be continuous tone. The TIFF spec says that this
+ usually leads to better compression.
+ */
+ if (((photometric == PHOTOMETRIC_RGB) ||
+ (photometric == PHOTOMETRIC_MINISBLACK)) &&
+ ((bits_per_sample == 8) || (bits_per_sample == 16)))
+ predictor=PREDICTOR_HORIZONTAL;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ /*
+ Allow the user to specify the predictor (at their own peril)
+ */
+ {
+ const char *
+ value;
+
+ if ((value=AccessDefinition(image_info,"tiff","predictor")))
+ predictor=(unsigned short) MagickAtoI(value);
+ }
+
+ if (predictor != 0)
+ {
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Requesting predictor %u",
+ (unsigned int) predictor);
+ (void) TIFFSetField(tiff,TIFFTAG_PREDICTOR,predictor);
+ }
+
+ /*
+ Allow the user to override rows-per-strip settings.
+ */
+ if (method != TiledMethod)
+ {
+ const char *
+ value;
+
+ if ((value=AccessDefinition(image_info,"tiff","rows-per-strip")))
+ {
+ unsigned int
+ old_value;
+
+ old_value=rows_per_strip;
+ rows_per_strip=MagickAtoI(value);
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "User override (rows_per_strip): %u rows"
+ " per strip (was %u)",
+ (unsigned int) rows_per_strip, old_value);
+ }
+ if ((value=AccessDefinition(image_info,"tiff","strip-per-page")))
+ {
+ if (LocaleCompare("TRUE",value) == 0)
+ {
+ rows_per_strip=(uint32) image->rows;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "User requested a single strip per "
+ "page (strip-per-page)");
+ }
+ }
+ }
+
+ if (COMPRESSION_JPEG == compress_tag)
+ {
+ /*
+ RowsPerStrip must be multiple of 16 for JPEG.
+ */
+ rows_per_strip=(((rows_per_strip < 16 ? 16 : rows_per_strip)+1)/16)*16;
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using %s compression",
+ CompressionTagToString(compress_tag));
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image depth %lu bits",depth);
+ if (method != TiledMethod)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Rows per strip: %u (%lu bytes/strip)",
+ (unsigned int) rows_per_strip,
+ (unsigned long) scanline_size*rows_per_strip);
+ (void) TIFFSetField(tiff,TIFFTAG_ROWSPERSTRIP,rows_per_strip);
+ }
+
+
+ if ((image->x_resolution != 0) && (image->y_resolution != 0))
+ {
+ unsigned short
+ units;
+
+ /*
+ Set image resolution.
+ */
+ units=RESUNIT_NONE;
+ if (image->units == PixelsPerInchResolution)
+ units=RESUNIT_INCH;
+ if (image->units == PixelsPerCentimeterResolution)
+ units=RESUNIT_CENTIMETER;
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Resolution %gx%g pixels%s",
+ image->x_resolution, image->y_resolution,
+ (units == RESUNIT_NONE ? " (undefined units)" :
+ (units == RESUNIT_INCH ? " per inch" :
+ (units == RESUNIT_CENTIMETER ? " per centimeter"
+ : "BAD VALUE"))));
+ (void) TIFFSetField(tiff,TIFFTAG_RESOLUTIONUNIT,(uint16) units);
+ (void) TIFFSetField(tiff,TIFFTAG_XRESOLUTION,image->x_resolution);
+ (void) TIFFSetField(tiff,TIFFTAG_YRESOLUTION,image->y_resolution);
+ }
+ if (image->chromaticity.white_point.x != 0.0)
+ {
+ float
+ chromaticity[6];
+
+ /*
+ Set image primary chromaticities (x,y coordinates of RGB
+ colorants and white point).
+ */
+ chromaticity[0]=image->chromaticity.red_primary.x;
+ chromaticity[1]=image->chromaticity.red_primary.y;
+ chromaticity[2]=image->chromaticity.green_primary.x;
+ chromaticity[3]=image->chromaticity.green_primary.y;
+ chromaticity[4]=image->chromaticity.blue_primary.x;
+ chromaticity[5]=image->chromaticity.blue_primary.y;
+ (void) TIFFSetField(tiff,TIFFTAG_PRIMARYCHROMATICITIES,chromaticity);
+ chromaticity[0]=image->chromaticity.white_point.x;
+ chromaticity[1]=image->chromaticity.white_point.y;
+ (void) TIFFSetField(tiff,TIFFTAG_WHITEPOINT,chromaticity);
+ }
+ {
+ /*
+ Copy any embedded profiles to TIFF.
+ */
+ size_t
+ profile_length=0;
+
+ const unsigned char
+ *profile_data=0;
+
+#if defined(TIFFTAG_XMLPACKET)
+ /*
+ XML XMP profile.
+ */
+ if ((profile_data=GetImageProfile(image,"XMP",&profile_length)) != 0)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "XMP embedded profile with length %lu bytes",
+ (unsigned long) profile_length);
+ (void) TIFFSetField(tiff,TIFFTAG_XMLPACKET,(uint32) profile_length,
+ profile_data);
+ }
+#endif /* defined(TIFFTAG_XMLPACKET) */
+
+#if defined(TIFFTAG_ICCPROFILE)
+ /*
+ ICC color profile.
+ */
+ if ((profile_data=GetImageProfile(image,"ICM",&profile_length)) != 0)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "ICC ICM embedded profile with length %lu bytes",
+ (unsigned long) profile_length);
+ (void) TIFFSetField(tiff,TIFFTAG_ICCPROFILE,(uint32)profile_length,
+ profile_data);
+ }
+#endif /* defined(ICC_SUPPORT) */
+
+ /*
+ IPTC NewsPhoto profile.
+ */
+ if ((profile_data=GetImageProfile(image,"IPTC",&profile_length)) != 0)
+ {
+ int
+ profile_tag=0;
+#if defined(TIFFTAG_PHOTOSHOP)
+ /* Photoshop profile (with embedded IPTC profile). */
+ profile_tag=TIFFTAG_PHOTOSHOP;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Photoshop embedded profile with length %lu"
+ " bytes",
+ (unsigned long) profile_length);
+#else
+ /* IPTC TAG from RichTIFF specifications */
+ profile_tag=TIFFTAG_RICHTIFFIPTC;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "IPTC Newsphoto embedded profile with length"
+ " %lu bytes",
+ (unsigned long) profile_length);
+
+#endif /* defined(PHOTOSHOP_SUPPORT) */
+ WriteNewsProfile(tiff,profile_tag,profile_data,profile_length);
+ }
+ }
+ attribute=GetImageAttribute(image,"subfiletype");
+ if (attribute != (const ImageAttribute *) NULL)
+ {
+ /*
+ Support "REDUCEDIMAGE", "PAGE", and "MASK". Any other
+ value results in no subfile type tag applied.
+ */
+ if (LocaleCompare(attribute->value,"REDUCEDIMAGE") == 0)
+ {
+ (void) TIFFSetField(tiff,TIFFTAG_SUBFILETYPE,FILETYPE_REDUCEDIMAGE);
+ }
+ else if (LocaleCompare(attribute->value,"PAGE") == 0)
+ {
+ (void) TIFFSetField(tiff,TIFFTAG_SUBFILETYPE,FILETYPE_PAGE);
+ }
+ else if (LocaleCompare(attribute->value,"MASK") == 0)
+ {
+ (void) TIFFSetField(tiff,TIFFTAG_SUBFILETYPE,FILETYPE_MASK);
+ }
+ }
+ else
+ {
+ /*
+ Page and Page number tags. Page is the current page number
+ (0 based) and pages is the total number of pages.
+ */
+
+ uint16
+ page,
+ pages;
+
+ page=(uint16) scene;
+ pages=GetImageListLength(image);
+
+ if (image_info->adjoin && pages > 1)
+ {
+ /*
+ SubFileType = 2. LONG. The value 2 identifies a single
+ page of a multi-page image.
+ */
+ (void) TIFFSetField(tiff,TIFFTAG_SUBFILETYPE,FILETYPE_PAGE);
+ }
+
+ (void) TIFFSetField(tiff,TIFFTAG_PAGENUMBER,page,pages);
+ }
+ attribute=GetImageAttribute(image,"artist");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_ARTIST,attribute->value);
+
+ attribute=GetImageAttribute(image,"copyright");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,33432,attribute->value); /* TIFFTAG_COPYRIGHT */
+
+ attribute=GetImageAttribute(image,"timestamp");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_DATETIME,attribute->value);
+
+ (void) TIFFSetField(tiff,TIFFTAG_DOCUMENTNAME,image->filename);
+
+ attribute=GetImageAttribute(image,"hostcomputer");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_HOSTCOMPUTER,attribute->value);
+
+ attribute=GetImageAttribute(image,"comment");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_IMAGEDESCRIPTION,attribute->value);
+
+ attribute=GetImageAttribute(image,"make");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_MAKE,attribute->value);
+
+ attribute=GetImageAttribute(image,"model");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_MODEL,attribute->value);
+
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_PAGENAME,attribute->value);
+
+ attribute=GetImageAttribute(image,"software");
+ if (attribute != (const ImageAttribute *) NULL)
+ {
+ /*
+ Allow skipping software tag if attribute exists but is empty.
+ */
+ if (strlen(attribute->value))
+ (void) TIFFSetField(tiff,TIFFTAG_SOFTWARE,attribute->value);
+ }
+ else
+ {
+ (void) TIFFSetField(tiff,TIFFTAG_SOFTWARE,
+ GetMagickVersion((unsigned long *) NULL));
+ }
+
+#if 0
+ /*
+ This tag is not supported by libtiff so the tag extension
+ mechanism would need to be used to add support for it.
+ */
+ attribute=GetImageAttribute(image,"imageid");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) TIFFSetField(tiff,TIFFTAG_OPIIMAGEID,attribute->value);
+#endif
+
+ if (photometric == PHOTOMETRIC_PALETTE)
+ {
+ uint16
+ *blue,
+ *green,
+ *red;
+
+ /*
+ Initialize TIFF colormap.
+ */
+ blue=MagickAllocateMemory(unsigned short *,
+ 65536L*sizeof(unsigned short));
+ green=MagickAllocateMemory(unsigned short *,
+ 65536L*sizeof(unsigned short));
+ red=MagickAllocateMemory(unsigned short *,
+ 65536L*sizeof(unsigned short));
+ if ((blue == (unsigned short *) NULL) ||
+ (green == (unsigned short *) NULL) ||
+ (red == (unsigned short *) NULL))
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ (void) memset(red,0,65536L*sizeof(unsigned short));
+ (void) memset(green,0,65536L*sizeof(unsigned short));
+ (void) memset(blue,0,65536L*sizeof(unsigned short));
+ for (i=0; i < image->colors; i++)
+ {
+ red[i]=ScaleQuantumToShort(image->colormap[i].red);
+ green[i]=ScaleQuantumToShort(image->colormap[i].green);
+ blue[i]=ScaleQuantumToShort(image->colormap[i].blue);
+ }
+ (void) TIFFSetField(tiff,TIFFTAG_COLORMAP,red,green,blue);
+ MagickFreeMemory(red);
+ MagickFreeMemory(green);
+ MagickFreeMemory(blue);
+ }
+ /*
+ Set extra export options for grayscale.
+ */
+ if (photometric == PHOTOMETRIC_MINISWHITE)
+ export_options.grayscale_miniswhite=MagickTrue;
+ /*
+ Set extra export options for floating point.
+ */
+ if (sample_format == SAMPLEFORMAT_IEEEFP)
+ {
+ const char *
+ definition_value;
+
+ export_options.sample_type=FloatQuantumSampleType;
+ if ((definition_value=AccessDefinition(image_info,"tiff","min-sample-value")))
+ export_options.double_minvalue=strtod(definition_value,(char **)NULL);
+ if ((definition_value=AccessDefinition(image_info,"tiff","max-sample-value")))
+ export_options.double_maxvalue=strtod(definition_value,(char **)NULL);
+ (void) TIFFSetField(tiff,TIFFTAG_SMINSAMPLEVALUE,
+ export_options.double_minvalue);
+ (void) TIFFSetField(tiff,TIFFTAG_SMAXSAMPLEVALUE,
+ export_options.double_maxvalue);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using min sample value %g, max sample value %g",
+ export_options.double_minvalue,
+ export_options.double_maxvalue);
+ }
+
+ /*
+ For sample sizes matching a CPU native word, use native endian
+ order for import.
+ */
+ if ((16 == bits_per_sample) || (32 == bits_per_sample) || (64 == bits_per_sample))
+ export_options.endian=NativeEndian;
+
+ /*
+ Export pixels to TIFF.
+
+ FIXME: JBIG needs a Strip writer.
+ */
+ switch (method)
+ {
+ default:
+ case ScanLineMethod:
+ {
+ /*
+ Write TIFF image as scanlines
+ */
+ unsigned char
+ *scanline;
+
+ const PixelPacket
+ *p;
+
+ int
+ max_sample,
+ quantum_samples,
+ sample;
+
+ QuantumType
+ quantum_type;
+
+ /*
+ Allocate memory for one scanline.
+ */
+ scanline_size=TIFFScanlineSize(tiff);
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using scanline %s write method with %u "
+ "bits per sample (%lu bytes/scanline)",
+ PhotometricTagToString(photometric),
+ bits_per_sample, (unsigned long) scanline_size);
+
+ scanline=MagickAllocateMemory(unsigned char *,(size_t) scanline_size);
+ if (scanline == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Prepare for separate/contiguous retrieval.
+ */
+ max_sample=1;
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,samples_per_pixel,
+ PLANARCONFIG_CONTIG,0,&quantum_type,
+ &quantum_samples,&image->exception)
+ == MagickPass)
+ max_sample=quantum_samples;
+ }
+ /*
+ For each plane
+ */
+ for (sample=0; sample < max_sample; sample++)
+ {
+ /*
+ Determine quantum parse method.
+ */
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,samples_per_pixel,
+ planar_config,sample,&quantum_type,
+ &quantum_samples,&image->exception)
+ == MagickFail)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (y=0; y < image->rows; y++)
+ {
+ if ((image->matte) && (alpha_type == AssociatedAlpha))
+ p=GetImagePixels(image,0,y,image->columns,1);
+ else
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Convert to associated alpha if necessary.
+ */
+ if ((sample == 0) && (image->matte) &&
+ (alpha_type == AssociatedAlpha))
+ AssociateAlphaRegion(image);
+ /*
+ Export pixels to scanline.
+ */
+ if (ExportImagePixelArea(image,quantum_type,bits_per_sample,
+ scanline,&export_options,&export_info)
+ == MagickFail)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Write scanline.
+ */
+#if !defined(WORDS_BIGENDIAN)
+ if (24 == bits_per_sample)
+ SwabDataToNativeEndian(bits_per_sample,scanline,scanline_size);
+#endif
+ if (TIFFWriteScanline(tiff, scanline,y,sample) == -1)
+ {
+ status=MagickFail;
+ break;
+ }
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y+sample*image->rows,image->rows*max_sample))
+ if (!MagickMonitorFormatted(y+sample*image->rows,
+ image->rows*max_sample,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+
+ }
+ if (status == MagickFail)
+ break;
+ }
+ MagickFreeMemory(scanline);
+ break;
+ }
+ case TiledMethod:
+ {
+ /*
+ Write TIFF image as tiles
+ */
+ unsigned char
+ *tile;
+
+ uint32
+ tile_columns,
+ tile_rows;
+
+ tsize_t
+ stride,
+ tile_size,
+ tile_size_max;
+
+ int
+ max_sample,
+ quantum_samples,
+ sample;
+
+ QuantumType
+ quantum_type;
+
+ unsigned long
+ tile_total_pixels;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using tiled %s write method with %u bits "
+ "per sample",
+ PhotometricTagToString(photometric),
+ bits_per_sample);
+
+ /*
+ Determine tile size
+ */
+ {
+ const char *
+ value;
+
+ tile_columns=0;
+ tile_rows=0;
+
+ /*
+ Enable tiled output (with default size, or specified separately)
+ -define tiff:tile
+
+ Use an exact tile size in rows & columns
+ -define tiff:tile-geometry=128x128
+
+ Use a specific tile width (pixels)
+ -define tiff:tile-width=128
+
+ Use a specific tile height (pixels)
+ -define tiff:tile-height=128
+ */
+ if ((value=AccessDefinition(image_info,"tiff","tile-geometry")))
+ {
+ double
+ width,
+ height;
+
+ if (GetMagickDimension(value,&width,&height,NULL,NULL) == 2)
+ {
+ tile_rows=(uint32) height;
+ tile_columns=(uint32) width;
+ }
+ }
+ if ((value=AccessDefinition(image_info,"tiff","tile-width")))
+ {
+ tile_columns=MagickAtoL(value);
+ }
+ if ((value=AccessDefinition(image_info,"tiff","tile-height")))
+ {
+ tile_rows=MagickAtoL(value);
+ }
+
+ TIFFDefaultTileSize(tiff,&tile_columns,&tile_rows);
+ }
+
+ if (!TIFFSetField(tiff,TIFFTAG_TILEWIDTH,tile_columns))
+ status=MagickFail;
+ if (!TIFFSetField(tiff,TIFFTAG_TILELENGTH,tile_rows))
+ status=MagickFail;
+ /*
+ Obtain the maximum number of bytes required to contain a tile.
+ */
+ tile_size_max=TIFFTileSize(tiff);
+ /*
+ Compute the total number of pixels in one tile
+ */
+ tile_total_pixels=tile_columns*tile_rows;
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFF tile geometry %ux%u, %lu pixels",
+ (unsigned int)tile_columns,
+ (unsigned int)tile_rows,
+ tile_total_pixels);
+ }
+ /*
+ Allocate tile buffer
+ */
+ tile=MagickAllocateMemory(unsigned char *, (size_t) tile_size_max);
+ if (tile == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Prepare for separate/contiguous retrieval.
+ */
+ max_sample=1;
+ if (planar_config == PLANARCONFIG_SEPARATE)
+ {
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,samples_per_pixel,
+ PLANARCONFIG_CONTIG,0,&quantum_type,
+ &quantum_samples,&image->exception)
+ == MagickPass)
+ max_sample=quantum_samples;
+ }
+ /*
+ Obtain per-row stride.
+ */
+ stride=TIFFTileRowSize(tiff);
+
+ /*
+ Process each plane.
+ */
+ for (sample=0; sample < max_sample; sample++)
+ {
+ /*
+ Determine quantum parse method.
+ */
+ if (QuantumTransferMode(image,photometric,compress_tag,
+ sample_format,samples_per_pixel,
+ planar_config,sample,&quantum_type,
+ &quantum_samples,&image->exception)
+ == MagickFail)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (y=0; y < image->rows; y+=tile_rows)
+ {
+ for (x=0; x < image->columns; x+=tile_columns)
+ {
+ const PixelPacket
+ *p;
+
+ long
+ tile_set_columns,
+ tile_set_rows;
+
+ unsigned char
+ *q;
+
+ register long
+ yy;
+
+ /*
+ Compute image region corresponding to tile.
+ */
+ if (x+tile_columns > image->columns)
+ tile_set_columns=(tile_columns-(x+tile_columns-image->columns));
+ else
+ tile_set_columns=tile_columns;
+ if (y+tile_rows > image->rows)
+ tile_set_rows=(tile_rows-(y+tile_rows-image->rows));
+ else
+ tile_set_rows=tile_rows;
+
+ q=tile;
+ for (yy=y; yy < (long) y+tile_set_rows; yy++)
+ {
+ /*
+ Obtain pixel region corresponding to tile row.
+ */
+ if ((image->matte) && (alpha_type == AssociatedAlpha))
+ p=GetImagePixels(image,x,yy,tile_set_columns,1);
+ else
+ p=AcquireImagePixels(image,x,yy,tile_set_columns,
+ 1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Convert to associated alpha if necessary.
+ */
+ if ((sample == 0) && (image->matte) &&
+ (alpha_type == AssociatedAlpha))
+ AssociateAlphaRegion(image);
+ /*
+ Export tile row
+ */
+ if (ExportImagePixelArea(image,quantum_type,
+ bits_per_sample,q,
+ &export_options,&export_info)
+ == MagickFail)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Enforce that we did not overrun our buffer.
+ */
+ assert(export_info.bytes_exported <= (size_t) scanline_size);
+ q += stride;
+ } /* for yy */
+ if (status == MagickFail)
+ break;
+ /*
+ Write tile.
+ */
+#if !defined(WORDS_BIGENDIAN)
+ if (24 == bits_per_sample)
+ SwabDataToNativeEndian(bits_per_sample,tile,tile_size_max);
+#endif
+ if ((tile_size=TIFFWriteTile(tiff,tile,x,y,0,sample)) == -1)
+ {
+ status=MagickFail;
+ }
+ if (status == MagickFail)
+ break;
+ } /* for x */
+ /*
+ Progress indicator.
+ */
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick((y+sample*image->rows)/tile_rows,
+ (image->rows*max_sample)/tile_rows))
+ if (!MagickMonitorFormatted((y+sample*image->rows)/tile_rows,
+ (image->rows*max_sample)/tile_rows,
+ &image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ status=MagickFail;
+
+ if (status == MagickFail)
+ break;
+ } /* for y */
+ } /* for sample */
+ MagickFreeMemory(tile);
+ break;
+ }
+ }
+ if (image_info->verbose > 1)
+ TIFFPrintDirectory(tiff,stdout,MagickFalse);
+ if(!TIFFWriteDirectory(tiff))
+ {
+ status=MagickFail;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TIFFWriteDirectory returns failed status!");
+ }
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ if ((status &= MagickMonitorFormatted(scene++,
+ GetImageListLength(image),
+ &image->exception,
+ SaveImagesText,
+ image->filename)) == MagickFail)
+ break;
+ } while (image_info->adjoin);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ TIFFClose(tiff); /* Should implicity invoke CloseBlob(image) */
+
+ if (status == MagickFail)
+ {
+ /*
+ Handle write failure.
+ */
+
+ if (unlink(filename) != -1)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Removed broken output file \"%s\"",filename);
+ return (MagickFail);
+ }
+
+ return(MagickPass);
+}
+#endif
diff --git a/coders/tile.c b/coders/tile.c
new file mode 100644
index 0000000..0553aff
--- /dev/null
+++ b/coders/tile.c
@@ -0,0 +1,193 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT IIIII L EEEEE %
+% T I L E %
+% T I L EEE %
+% T I L E %
+% T IIIII LLLLL EEEEE %
+% %
+% %
+% Return A Tiled Image Using Texture. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/composite.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d T I L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadTILEImage tiles a texture on an image. It allocates the
+% memory necessary for the new Image structure and returns a pointer to the
+% new image.
+%
+% The format of the ReadTILEImage method is:
+%
+% Image *ReadTILEImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadTILEImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadTILEImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image,
+ *tile_image;
+
+ ImageInfo
+ *clone_info;
+
+ RectangleInfo
+ geometry;
+
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ *clone_info->magick='\0';
+ tile_image=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ if (tile_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ /*
+ Adapt tile image to desired image type.
+ */
+ if (image_info->type != UndefinedType)
+ (void) SetImageType(tile_image,image_info->type);
+
+ /*
+ Create tiled canvas image.
+ */
+ (void) GetGeometry(image_info->size,&geometry.x,&geometry.y,&geometry.width,
+ &geometry.height);
+ image=ConstituteTextureImage(geometry.width,geometry.height,tile_image,exception);
+
+ DestroyImage(tile_image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r T I L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterTILEImage adds attributes for the TILE image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterTILEImage method is:
+%
+% RegisterTILEImage(void)
+%
+*/
+ModuleExport void RegisterTILEImage(void)
+{
+ MagickInfo
+ *entry;
+
+ static const char
+ *TILENote=
+ {
+ "Use the syntax \"-size WIDTHxHEIGHT TILE:imagename\" to tile the\n"
+ "specified tile image over a canvas image of size WIDTHxHEIGHT."
+ };
+
+ entry=SetMagickInfo("TILE");
+ entry->decoder=(DecoderHandler) ReadTILEImage;
+ entry->raw=True;
+ entry->description="Tile image with a texture";
+ entry->note=TILENote;
+ entry->module="TILE";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r T I L E I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterTILEImage removes format registrations made by the
+% TILE module from the list of supported formats.
+%
+% The format of the UnregisterTILEImage method is:
+%
+% UnregisterTILEImage(void)
+%
+*/
+ModuleExport void UnregisterTILEImage(void)
+{
+ (void) UnregisterMagickInfo("TILE");
+}
diff --git a/coders/tim.c b/coders/tim.c
new file mode 100644
index 0000000..d48721c
--- /dev/null
+++ b/coders/tim.c
@@ -0,0 +1,468 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT IIIII M M %
+% T I MM MM %
+% T I M M M %
+% T I M M %
+% T IIIII M M %
+% %
+% %
+% Read PSX TIM Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d T I M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadTIMImage reads a PSX TIM image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% Contributed by os@scee.sony.co.uk.
+%
+% The format of the ReadTIMImage method is:
+%
+% Image *ReadTIMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadTIMImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadTIMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ typedef struct _TIMInfo
+ {
+ unsigned long
+ id,
+ flag;
+ } TIMInfo;
+
+ TIMInfo
+ tim_info;
+
+ Image
+ *image;
+
+ int
+ bits_per_pixel,
+ has_clut;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ unsigned char
+ *tim_data,
+ *tim_pixels;
+
+ unsigned short
+ word;
+
+ unsigned int
+ status;
+
+ size_t
+ bytes_per_line,
+ image_size;
+
+ unsigned long
+ height,
+ pixel_mode,
+ width;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Determine if this is a TIM file.
+ */
+ tim_info.id=ReadBlobLSBLong(image);
+ do
+ {
+ /*
+ Verify TIM identifier.
+ */
+ if (tim_info.id != 0x00000010)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ tim_info.flag=ReadBlobLSBLong(image);
+ has_clut=!!(tim_info.flag & (1 << 3));
+ pixel_mode=tim_info.flag & 0x07;
+ switch ((int) pixel_mode)
+ {
+ case 0: bits_per_pixel=4; break;
+ case 1: bits_per_pixel=8; break;
+ case 2: bits_per_pixel=16; break;
+ case 3: bits_per_pixel=24; break;
+ default: bits_per_pixel=4; break;
+ }
+ image->depth=8;
+ if (has_clut)
+ {
+ unsigned char
+ *tim_colormap;
+
+ /*
+ Read TIM raster colormap.
+ */
+ (void)ReadBlobLSBLong(image);
+ (void)ReadBlobLSBShort(image);
+ (void)ReadBlobLSBShort(image);
+ /* width= */ (void)ReadBlobLSBShort(image);
+ /* height= */ (void)ReadBlobLSBShort(image);
+ if (!AllocateImageColormap(image,pixel_mode == 1 ? 256 : 16))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ tim_colormap=MagickAllocateMemory(unsigned char *,image->colors*2);
+ if (tim_colormap == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ (void) ReadBlob(image,2*image->colors,(char *) tim_colormap);
+ p=tim_colormap;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ word=(*p++);
+ word|=(unsigned short) (*p++ << 8U);
+ image->colormap[i].blue=ScaleCharToQuantum(ScaleColor5to8((word >> 10U) & 0x1fU));
+ image->colormap[i].green=ScaleCharToQuantum(ScaleColor5to8((word >> 5U) & 0x1fU));
+ image->colormap[i].red=ScaleCharToQuantum(ScaleColor5to8(word & 0x1fU));
+ }
+ MagickFreeMemory(tim_colormap);
+ }
+
+ /*
+ Read image data.
+ */
+ (void) ReadBlobLSBLong(image);
+ (void) ReadBlobLSBShort(image);
+ (void) ReadBlobLSBShort(image);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ width=ReadBlobLSBShort(image);
+ height=ReadBlobLSBShort(image);
+ image_size=MagickArraySize(2,MagickArraySize(width,height));
+ bytes_per_line=MagickArraySize(width,2);
+ width=(unsigned long)(MagickArraySize(width,16))/bits_per_pixel;
+ /*
+ Initialize image structure.
+ */
+ image->columns=width;
+ image->rows=height;
+
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ tim_data=MagickAllocateMemory(unsigned char *,image_size);
+ if (tim_data == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) ReadBlob(image,image_size,(char *) tim_data);
+ tim_pixels=tim_data;
+
+ /*
+ Convert TIM raster image to pixel packets.
+ */
+ switch (bits_per_pixel)
+ {
+ case 4:
+ {
+ /*
+ Convert PseudoColor scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ p=tim_pixels+y*bytes_per_line;
+ for (x=0; x < ((long) image->columns-1); x+=2)
+ {
+ indexes[x]=(*p) & 0xf;
+ indexes[x+1]=(*p >> 4) & 0xf;
+ p++;
+ }
+ if ((image->columns % 2) != 0)
+ {
+ indexes[x]=(*p >> 4) & 0xf;
+ p++;
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 8:
+ {
+ /*
+ Convert PseudoColor scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ p=tim_pixels+y*bytes_per_line;
+ for (x=0; x < (long) image->columns; x++)
+ indexes[x]=(*p++);
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ /*
+ Convert DirectColor scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=tim_pixels+y*bytes_per_line;
+ q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ word=(*p++);
+ word|=(*p++ << 8);
+ q->blue=ScaleCharToQuantum(ScaleColor5to8((word >> 10) & 0x1f));
+ q->green=ScaleCharToQuantum(ScaleColor5to8((word >> 5) & 0x1f));
+ q->red=ScaleCharToQuantum(ScaleColor5to8(word & 0x1f));
+ q++;
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ case 24:
+ {
+ /*
+ Convert DirectColor scanline.
+ */
+ for (y=(long) image->rows-1; y >= 0; y--)
+ {
+ p=tim_pixels+y*bytes_per_line;
+ q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(*p++);
+ q->green=ScaleCharToQuantum(*p++);
+ q->blue=ScaleCharToQuantum(*p++);
+ q++;
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ if (QuantumTick(y,image->rows))
+ {
+ status=MagickMonitorFormatted(image->rows-y-1,image->rows,
+ exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows);
+ if (status == False)
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image)
+ }
+ if (image->storage_class == PseudoClass)
+ (void) SyncImage(image);
+ MagickFreeMemory(tim_pixels);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ tim_info.id=ReadBlobLSBLong(image);
+ if (tim_info.id == 0x00000010)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ }
+ } while (tim_info.id == 0x00000010);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r T I M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterTIMImage adds attributes for the TIM image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterTIMImage method is:
+%
+% RegisterTIMImage(void)
+%
+*/
+ModuleExport void RegisterTIMImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("TIM");
+ entry->decoder=(DecoderHandler) ReadTIMImage;
+ entry->description="PSX TIM";
+ entry->module="TIM";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r T I M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterTIMImage removes format registrations made by the
+% TIM module from the list of supported formats.
+%
+% The format of the UnregisterTIMImage method is:
+%
+% UnregisterTIMImage(void)
+%
+*/
+ModuleExport void UnregisterTIMImage(void)
+{
+ (void) UnregisterMagickInfo("TIM");
+}
diff --git a/coders/topol.c b/coders/topol.c
new file mode 100644
index 0000000..efc06fa
--- /dev/null
+++ b/coders/topol.c
@@ -0,0 +1,758 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% TTTTT OOO PPPP OOO L %
+% T O O P P O O L %
+% T O O PPPP O O L %
+% T O O P O O L %
+% T OOO P OOO LLLL %
+% %
+% %
+% Read/Write TOPOL X Image Raster Format. %
+% %
+% %
+% Software Design %
+% Jaroslav Fojtik %
+% June 2003 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/error.h"
+#include "magick/list.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+
+typedef struct
+{
+ char Name[20];
+ magick_uint16_t Rows;
+ magick_uint16_t Cols;
+ magick_uint16_t FileType; /* 0-binary, 1-8 bitu, 2-8 bits+PAL, 3-4 bits,
+ 4-4 bits+PAL, 5-24 bits, 6-16 bits, 7-32
+ bits */
+ magick_uint32_t Zoom;
+ magick_uint16_t Version;
+ magick_uint16_t Komprese; /* 0 - uncompressed (from release 1) */
+ magick_uint16_t Stav;
+ double xRasMin;
+ double yRasMin;
+ double xRasMax;
+ double yRasMax;
+ double Scale; /* from release 2 */
+ magick_uint16_t TileWidth; /* tile width in pixels */
+ magick_uint16_t TileHeight; /* tile height in pixels */
+ magick_uint32_t TileOffsets; /* offset to array of longints that contains
+ adresses of tiles in the raster (adreses
+ are counted from 0) */
+ magick_uint32_t TileByteCounts;/* offset to array of words, that contain amount of bytes stored in
+ tiles. The tile size might vary depending on
+ the value TileCompression */
+ magick_uint8_t TileCompression;/* 0 - uncompressed, 1 - variant TIFF
+ Packbits, 2 - CCITT G3 */
+
+ magick_uint8_t Dummy[423];
+} RasHeader;
+
+/*
+typedef struct The palette record inside TopoL
+{
+ BYTE Flag;
+ BYTE Red;
+ BYTE Green;
+ BYTE Blue;
+} paletteRAS;*/
+
+static void InsertRow(int depth, unsigned char *p, long y, Image * image, unsigned Xoffset, unsigned columns, ImportPixelAreaOptions *import_options)
+{
+ int
+ bit;
+
+ long
+ x;
+
+ register PixelPacket
+ *q;
+
+ IndexPacket
+ index;
+
+ register IndexPacket
+ *indexes;
+
+ switch (depth)
+ {
+ case 1: /* Convert bitmap scanline. */
+ {
+ q = SetImagePixels(image, Xoffset, y, columns, 1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes = AccessMutableIndexes(image);
+ for (x = 0; x < ((long)columns - 7); x += 8)
+ {
+ for (bit = 0; bit < 8; bit++)
+ {
+ index = ((*p) & (0x80U >> bit) ? 0x01U : 0x00U);
+ indexes[x + bit] = index;
+ *q++ = image->colormap[index];
+ }
+ p++;
+ }
+ if ((columns % 8) != 0)
+ {
+ for (bit = 0; bit < (long)(columns % 8); bit++)
+ {
+ index = ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
+ indexes[x + bit] = index;
+ *q++ = image->colormap[index];
+ }
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ ProgressMonitor(LoadImageText,image->rows-y-1,image->rows); */
+ break;
+ }
+ case 2: /* Convert PseudoColor scanline. */
+ {
+ q = SetImagePixels(image, Xoffset, y, columns, 1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes = AccessMutableIndexes(image);
+ for (x = 0; x < ((long)columns - 1); x += 2)
+ {
+ index = (IndexPacket) ((*p >> 6) & 0x3);
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ index = (IndexPacket) ((*p >> 4) & 0x3);
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ index = (IndexPacket) ((*p >> 2) & 0x3);
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ index = (IndexPacket) ((*p) & 0x3);
+ VerifyColormapIndex(image, index);
+ indexes[x + 1] = index;
+ *q++ = image->colormap[index];
+ p++;
+ }
+ if ((columns % 4) != 0)
+ {
+ index = (IndexPacket) ((*p >> 6) & 0x3);
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ if ((columns % 4) >= 1)
+ {
+ index = (IndexPacket) ((*p >> 4) & 0x3);
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ if((columns % 4) >= 2)
+ {
+ index = (IndexPacket) ((*p >> 2) & 0x3);
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ }
+ }
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ ProgressMonitor(LoadImageText,image->rows-y-1,image->rows); */
+ break;
+ }
+
+ case 4: /* Convert PseudoColor scanline. */
+ {
+ q = SetImagePixels(image, Xoffset, y, columns, 1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes = AccessMutableIndexes(image);
+ for (x = 0; x < ((long)columns - 1); x += 2)
+ {
+ index = (IndexPacket) ((*p >> 4) & 0xF); /* Lo nibble */
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ index = (IndexPacket) ((*p) & 0xF); /* Hi nibble */
+ VerifyColormapIndex(image, index);
+ indexes[x + 1] = index;
+ *q++ = image->colormap[index];
+ p++;
+ }
+ if((columns % 2) != 0)
+ {
+ index = (IndexPacket) ((*p >> 4) & 0xF); /* padding nibble */
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ ProgressMonitor(LoadImageText,image->rows-y-1,image->rows); */
+ break;
+ }
+ case 8: /* Convert PseudoColor scanline. */
+ {
+ q = SetImagePixels(image, Xoffset, y, columns, 1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes = AccessMutableIndexes(image);
+
+ for (x = 0; x < (long)columns; x++)
+ {
+ index = (IndexPacket) (*p);
+ VerifyColormapIndex(image, index);
+ indexes[x] = index;
+ *q++ = image->colormap[index];
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ /* if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ ProgressMonitor(LoadImageText,image->rows-y-1,image->rows); */
+ }
+ break;
+
+ case 16: /* Convert 16 bit Gray scanline. */
+ q = SetImagePixels(image, Xoffset, y, columns, 1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void)ImportImagePixelArea(image,GrayQuantum,16,p,import_options,0);
+ if(!SyncImagePixels(image)) break;
+ break;
+
+ case 24: /* Convert RGB scanline. */
+ q = SetImagePixels(image, Xoffset, y, columns, 1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void)ImportImagePixelArea(image,RGBQuantum,8,p,import_options,0);
+ if(!SyncImagePixels(image)) break;
+ break;
+
+ case 32: /* Convert 32 bit Gray scanline. */
+ q = SetImagePixels(image, Xoffset, y, columns, 1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ (void)ImportImagePixelArea(image,GrayQuantum,32,p,import_options,0);
+ if(!SyncImagePixels(image)) break;
+ break;
+
+ }
+}
+
+
+/* This function reads one block of unsigned longS */
+static void ReadBlobDwordLSB(Image *image, size_t len, magick_uint32_t *data)
+{
+ while (len >= 4)
+ {
+ *data++ = ReadBlobLSBLong(image);
+ len -= 4;
+ }
+ if (len > 0)
+ (void) SeekBlob(image, len, SEEK_CUR);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d T O P O L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadTOPOLImage reads an TOPOL X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadTOPOLImage method is:
+%
+% Image *ReadTOPOLImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadTOPOLImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: The image info.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+#define ThrowPDBReaderException(code_,reason_,image_) \
+{ \
+ if (clone_info) \
+ DestroyImageInfo(clone_info); \
+ if (palette) \
+ DestroyImage(palette); \
+ ThrowReaderException(code_,reason_,image_); \
+}
+
+static Image *ReadTOPOLImage(const ImageInfo * image_info, ExceptionInfo * exception)
+{
+ Image
+ *image,
+ *palette;
+
+ ImageInfo
+ *clone_info;
+
+ RasHeader
+ Header;
+
+ int logging;
+
+ int
+ depth,
+ status;
+
+ long
+ i,
+ j,
+ ldblk;
+
+ unsigned char
+ *BImgBuff = NULL,
+ MEZ[256];
+ ImportPixelAreaOptions import_options;
+
+
+ palette = NULL;
+ clone_info = NULL;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ logging = LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+
+ image = AllocateImage(image_info);
+ status = OpenBlob(image_info, image, ReadBinaryBlobMode, exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError, UnableToOpenFile, image);
+
+ ImportPixelAreaOptionsInit(&import_options);
+ import_options.endian = LSBEndian;
+ import_options.sample_type = UnsignedQuantumSampleType;
+
+ /*
+ Read TopoL RAS header.
+ */
+ (void) memset(&Header, 0, sizeof(Header));
+ (void) ReadBlob(image, 20, &Header.Name);
+ Header.Rows = ReadBlobLSBShort(image);
+ Header.Cols = ReadBlobLSBShort(image);
+ Header.FileType = ReadBlobLSBShort(image);
+ Header.Zoom = ReadBlobLSBLong(image);
+ Header.Version = ReadBlobLSBShort(image);
+ if (Header.Version >= 1)
+ {
+ Header.Komprese = ReadBlobLSBShort(image);
+ Header.Stav = ReadBlobLSBShort(image);
+ Header.xRasMin = ReadBlobLSBDouble(image);
+ Header.yRasMin = ReadBlobLSBDouble(image);
+ Header.xRasMax = ReadBlobLSBDouble(image);
+ Header.yRasMax = ReadBlobLSBDouble(image);
+ if (Header.Version >= 2) /* from release 2 */
+ {
+ Header.Scale = ReadBlobLSBDouble(image);
+ Header.TileWidth = ReadBlobLSBShort(image);
+ Header.TileHeight = ReadBlobLSBShort(image);
+ Header.TileOffsets = ReadBlobLSBLong(image);
+ Header.TileByteCounts = ReadBlobLSBLong(image);
+ Header.TileCompression = ReadBlobByte(image);
+ /* BYTE Dummy[423]; */
+ }
+ }
+
+ for (i = 0; i < (long) sizeof(Header.Name); i++)
+ {
+ if (Header.Name[i] < ' ')
+TOPOL_KO: ThrowPDBReaderException(CorruptImageError,ImproperImageHeader, image);
+ }
+ if (Header.Komprese != 0 || (Header.Version >= 2 && Header.TileCompression != 0))
+ ThrowPDBReaderException(CorruptImageError, UnrecognizedImageCompression, image);
+ if (Header.Rows == 0 || Header.Cols == 0)
+ goto TOPOL_KO;
+ if (Header.Version > 2)
+ ThrowPDBReaderException(CorruptImageError, InvalidFileFormatVersion, image); /* unknown version */
+
+ switch(Header.FileType)
+ {
+ case 0:
+ image->colors = 2;
+ depth = 1;
+ break;
+ case 1:
+ case 2:
+ image->colors = 256;
+ depth = 8;
+ break;
+ case 3:
+ case 4:
+ image->colors = 16;
+ depth = 4;
+ break;
+ case 5:
+ image->colors = 0;
+ image->depth = 8;
+ depth = 24;
+ break;
+ case 6:
+ image->colors = 0;
+ depth = 16;
+ break; /* ????????? 16 bits */
+ case 7:
+ image->colors = 0;
+ depth = 32;
+ break; /* ????????? 32 bits */
+ default:
+ goto TOPOL_KO;
+ }
+
+ image->columns = Header.Cols;
+ image->rows = Header.Rows;
+
+ /* If ping is true, then only set image size and colors without reading any image data. */
+ if (image_info->ping) goto DONE_READING;
+
+ /* ----- Handle the reindexing mez file ----- */
+ j = image->colors;
+ if(j<=0 || j>256) j=256;
+ for(i=0; i<j; i++)
+ {
+ MEZ[i] = (unsigned char)((i*256)/j);
+ }
+
+ if(Header.FileType>=5) goto NoMEZ;
+
+ if ((clone_info=CloneImageInfo(image_info)) == NULL) goto NoMEZ;
+
+ i=(long) strlen(clone_info->filename);
+ j=i;
+ while(--i>0)
+ {
+ if(clone_info->filename[i]=='.')
+ {
+ break;
+ }
+ if(clone_info->filename[i]=='/' || clone_info->filename[i]=='\\' || clone_info->filename[i]==':' )
+ {
+ i=j;
+ break;
+ }
+ }
+
+ (void) strcpy(clone_info->filename+i,".MEZ");
+ if((clone_info->file=fopen(clone_info->filename,"rb"))==NULL)
+ {
+ (void) strcpy(clone_info->filename+i,".mez");
+ if((clone_info->file=fopen(clone_info->filename,"rb"))==NULL)
+ {
+ DestroyImageInfo(clone_info);
+ clone_info=NULL;
+ goto NoMEZ;
+ }
+ }
+
+ if( (palette=AllocateImage(clone_info))==NULL ) goto NoMEZ;
+ status=OpenBlob(clone_info,palette,ReadBinaryBlobMode,exception);
+ if (status == False) goto NoMEZ;
+
+ ldblk=(long) GetBlobSize(palette);
+ if ( ldblk > (long) sizeof(MEZ))
+ ldblk=sizeof(MEZ);
+ (void) ReadBlob(palette, ldblk, MEZ);
+
+NoMEZ: /*Clean up palette and clone_info*/
+ if (palette != NULL) {DestroyImage(palette);palette=NULL;}
+ if (clone_info != NULL)
+ {
+ DestroyImageInfo(clone_info);
+ clone_info=NULL;
+ }
+
+ /* ----- Do something with palette ----- */
+ if(Header.FileType==5) goto NoPalette;
+ if ((clone_info=CloneImageInfo(image_info)) == NULL) goto NoPalette;
+
+ i=(long) strlen(clone_info->filename);
+ j=i;
+ while(--i>0)
+ {
+ if(clone_info->filename[i]=='.')
+ {
+ break;
+ }
+ if(clone_info->filename[i]=='/' || clone_info->filename[i]=='\\' ||
+ clone_info->filename[i]==':' )
+ {
+ i=j;
+ break;
+ }
+ }
+
+ (void) strcpy(clone_info->filename+i,".PAL");
+ if((clone_info->file=fopen(clone_info->filename,"rb"))==NULL)
+ {
+ (void) strcpy(clone_info->filename+i,".pal");
+ if((clone_info->file=fopen(clone_info->filename,"rb"))==NULL)
+ {
+ clone_info->filename[i]=0;
+ if((clone_info->file=fopen(clone_info->filename,"rb"))==NULL)
+ {
+ DestroyImageInfo(clone_info);
+ clone_info=NULL;
+ goto NoPalette;
+ }
+ }
+ }
+
+ if( (palette=AllocateImage(clone_info))==NULL ) goto NoPalette;
+ status=OpenBlob(clone_info,palette,ReadBinaryBlobMode,exception);
+ if (status == False)
+ {
+ ErasePalette:
+ DestroyImage(palette);
+ palette=NULL;
+ goto NoPalette;
+ }
+
+
+ if(palette!=NULL)
+ {
+ ldblk=ReadBlobByte(palette); /*size of palette*/
+ if(ldblk==EOF) goto ErasePalette;
+ image->colors=ldblk+1;
+ if (!AllocateImageColormap(image, image->colors)) goto NoMemory;
+
+ for(i=0;i<=ldblk;i++)
+ {
+ j = ReadBlobByte(palette); /* Flag */
+ if(j==EOF) break; /* unexpected end of file */
+ if(j<=ldblk)
+ {
+ if(j==MEZ[i])
+ j = i; /* MEZ[i]; ignore MEZ!!! proper palete element after reindexing */
+ else
+ j = MEZ[i]; /* ?? I do not know, big mess ?? */
+ if(j>=(long) image->colors) j=image->colors-1;
+ image->colormap[j].red = ScaleCharToQuantum(ReadBlobByte(palette));
+ image->colormap[j].green = ScaleCharToQuantum(ReadBlobByte(palette));
+ image->colormap[j].blue = ScaleCharToQuantum(ReadBlobByte(palette));
+ }
+ else
+ {
+ (void) SeekBlob(palette, 3, SEEK_CUR);
+ (void) fprintf(stderr,"TopoL: Wrong index inside palette %d!",(int)j);
+ }
+ }
+ }
+
+NoPalette:
+ if(palette == NULL && image->colors != 0)
+ {
+ if(Header.FileType<5)
+ {
+ if (!AllocateImageColormap(image, image->colors))
+ {
+ NoMemory:
+ ThrowPDBReaderException(ResourceLimitError, MemoryAllocationFailed, image);
+ }
+
+ for(i = 0; i < (long) image->colors; i++)
+ {
+ j = MEZ[i];
+ image->colormap[i].red = ScaleCharToQuantum(j);
+ image->colormap[i].green = ScaleCharToQuantum(j);
+ image->colormap[i].blue = ScaleCharToQuantum(j);
+ }
+ }
+ }
+
+ /* ----- Load TopoL raster ----- */
+ switch(Header.Version)
+ {
+ case 0:
+ case 1:
+ ldblk = (long) ((depth * image->columns + 7) / 8);
+ BImgBuff = MagickAllocateMemory(unsigned char *,(size_t) ldblk); /*Ldblk was set in the check phase */
+ if (BImgBuff == NULL)
+ ThrowPDBReaderException(ResourceLimitError, MemoryAllocationFailed, image);
+ (void) SeekBlob(image, 512 /*sizeof(Header)*/, SEEK_SET);
+ for (i = 0; i < (int) Header.Rows; i++)
+ {
+ (void)ReadBlob(image, ldblk, (char *)BImgBuff);
+ InsertRow(depth, BImgBuff, i, image, 0, image->columns, &import_options);
+ }
+ break;
+ case 2:
+ {
+ magick_uint32_t *Offsets;
+ long SkipBlk;
+ unsigned TilX, TilY;
+ unsigned TilesAcross = (Header.Cols+Header.TileWidth-1) / Header.TileWidth;
+ unsigned TilesDown = (Header.Rows+Header.TileHeight-1) / Header.TileHeight;
+
+ if(Header.TileCompression!=0)
+ {
+ ThrowPDBReaderException(CorruptImageError, UnrecognizedImageCompression, image);
+ break;
+ }
+
+ ldblk = (long)((depth * Header.TileWidth + 7) / 8);
+ BImgBuff = MagickAllocateMemory(unsigned char *,(size_t) ldblk); /*Ldblk was set in the check phase */
+
+ /* dlazdice.create(Header.TileWidth,Header.TileHeight,p.Planes); */
+ Offsets = MagickAllocateMemory(magick_uint32_t *,(size_t)TilesAcross*TilesDown*sizeof(magick_uint32_t));
+ if(Offsets==NULL)
+ ThrowPDBReaderException(ResourceLimitError, MemoryAllocationFailed, image);
+
+ (void)SeekBlob(image, Header.TileOffsets, SEEK_SET);
+ ReadBlobDwordLSB(image, TilesAcross*TilesDown*4, (magick_uint32_t *)Offsets);
+
+ for(TilY=0;TilY<Header.Rows;TilY+=Header.TileHeight)
+ for(TilX=0;TilX<TilesAcross;TilX++)
+ {
+ ldblk = image->columns - TilX*Header.TileWidth;
+
+ if(ldblk>Header.TileWidth) ldblk = Header.TileWidth;
+ SkipBlk = ((long)depth * (Header.TileWidth-ldblk)+7) / 8;
+ ldblk = ((long)depth * ldblk+7) / 8;
+
+ (void)SeekBlob(image, Offsets[(TilY/Header.TileHeight)*TilesAcross+TilX], SEEK_SET);
+ j = TilX * (ldblk+SkipBlk);
+ for(i=0;i<Header.TileHeight;i++)
+ {
+ (void)ReadBlob(image, ldblk, (char *)BImgBuff);
+ if(SkipBlk>0)
+ SeekBlob(image, SkipBlk, SEEK_CUR);
+ InsertRow(depth, BImgBuff, i+TilY, image, TilX,
+ (image->columns<Header.TileWidth)?image->columns:Header.TileWidth, &import_options);
+ }
+ }
+
+ if(Offsets) {MagickFreeMemory(Offsets);Offsets=NULL;}
+ break;
+ }
+ }
+
+
+ /* Finish: */
+DONE_READING:
+ if (BImgBuff != NULL)
+ MagickFreeMemory(BImgBuff);
+ if (palette != NULL)
+ DestroyImage(palette);
+ if (clone_info != NULL)
+ DestroyImageInfo(clone_info);
+ /* if (EOFBlob(image))
+ ThrowPDBReaderException(CorruptImageError,UnexpectedEndOfFile,image); */
+ CloseBlob(image);
+
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ return (image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r T O P O L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterTOPOLImage adds attributes for the TOPOL image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterTOPOLImage method is:
+%
+% RegisterTOPOLImage(void)
+%
+*/
+ModuleExport void RegisterTOPOLImage(void)
+{
+ MagickInfo * entry;
+
+ entry = SetMagickInfo("TOPOL");
+ entry->decoder = (DecoderHandler) ReadTOPOLImage;
+ entry->seekable_stream = True;
+ entry->description = "TOPOL X Image";
+ entry->module = "TOPOL";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r T O P O L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterTOPOLImage removes format registrations made by the
+% TOPOL module from the list of supported formats.
+%
+% The format of the UnregisterTOPOLImage method is:
+%
+% UnregisterTOPOLImage(void)
+%
+*/
+ModuleExport void UnregisterTOPOLImage(void)
+{
+ (void) UnregisterMagickInfo("TOPOL");
+}
diff --git a/coders/ttf.c b/coders/ttf.c
new file mode 100644
index 0000000..f46b2f1
--- /dev/null
+++ b/coders/ttf.c
@@ -0,0 +1,333 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT TTTTT FFFFF %
+% T T F %
+% T T FFF %
+% T T F %
+% T T F %
+% %
+% %
+% Return A Preview For A TrueType or Postscript Font %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/draw.h"
+#include "magick/magick.h"
+#include "magick/render.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s T T F %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsTTF returns True if the image format type, identified by the
+% magick string can be handled by this module.
+%
+% The format of the IsTTF method is:
+%
+% unsigned int IsTTF(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsTTF returns True if the image format type can be
+% handled by this module.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+
+static unsigned int IsPFA(const unsigned char *magick,const size_t length)
+{
+ if (length < 14)
+ return(False);
+ if (LocaleNCompare((char *) magick,"%!PS-AdobeFont-1.0",14) == 0)
+ return(True);
+ return(False);
+}
+
+static unsigned int IsTTF(const unsigned char *magick,const size_t length)
+{
+ if (length < 5)
+ return(False);
+ if ((magick[0] == 0x00U) && (magick[1] == 0x01U) && (magick[2] == 0x00U) &&
+ (magick[3] == 0x00U) && (magick[4] == 0x0U))
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d T T F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadTTFImage reads a TrueType font file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadTTFImage method is:
+%
+% Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadTTFImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#if defined(HasTTF)
+static Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ buffer[MaxTextExtent];
+
+ const char
+ *Text =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz\n0123456789 "
+ "\342\352\356\373\364\344\353\357\366\374\377\340\371\351\350\347\n"
+ "&#~\\\"\'(-`_^@)=+\260 $\243^\250*\265\371%!\247:/;.,?<>";
+
+ DrawContext
+ context;
+
+ DrawInfo
+ *draw_info;
+
+ Image
+ *image;
+
+ long
+ y;
+
+ PixelPacket
+ background_color;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ image->columns=800;
+ image->rows=480;
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ /*
+ Color canvas with background color
+ */
+ background_color=image_info->background_color;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ *q++=background_color;
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ }
+ (void) strlcpy(image->magick,image_info->magick,MaxTextExtent);
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ /*
+ Prepare drawing commands
+ */
+ y=20;
+ draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
+ draw_info->font=AllocateString(image->filename);
+ draw_info->fill=image_info->pen;
+ context=DrawAllocateContext(draw_info,image);
+ (void) DrawPushGraphicContext(context);
+ (void) DrawSetViewbox(context,0,0,image->columns,image->rows);
+ (void) DrawSetFont(context,image_info->filename);
+ (void) DrawSetFontSize(context,18);
+ (void) DrawAnnotation(context,10,y,(const unsigned char *) Text);
+ y+=20*MultilineCensus(Text)+20;
+ for (i=12; i <= 72; i+=6)
+ {
+ y+=i+12;
+ (void) DrawSetFontSize(context,18);
+ (void) FormatString(buffer,"%ld",i);
+ (void) DrawAnnotation(context,10,y,(const unsigned char *) buffer);
+ (void) DrawSetFontSize(context,i);
+ (void) DrawAnnotation(context,50,y,(const unsigned char *)
+ "That which does not destroy me, only makes me stronger.");
+ if (i >= 24)
+ i+=6;
+ }
+ (void) DrawPopGraphicContext(context);
+ (void) DrawRender(context);
+ /*
+ Free resources.
+ */
+ DestroyDrawInfo(draw_info);
+ DrawDestroyContext(context);
+ CloseBlob(image);
+ return(image);
+}
+#endif /* HasTTF */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r T T F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterTTFImage adds attributes for the TTF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterTTFImage method is:
+%
+% RegisterTTFImage(void)
+%
+*/
+ModuleExport void RegisterTTFImage(void)
+{
+ static char
+ version[MaxTextExtent];
+
+ MagickInfo
+ *entry;
+
+ *version='\0';
+#if defined(FREETYPE_MAJOR) && defined(FREETYPE_MINOR)
+ FormatString(version,"%d.%d",FREETYPE_MAJOR,FREETYPE_MINOR);
+#endif
+
+ entry=SetMagickInfo("TTF");
+#if defined(HasTTF)
+ entry->decoder=(DecoderHandler) ReadTTFImage;
+#endif
+ entry->magick=(MagickHandler) IsTTF;
+ entry->adjoin=False;
+ entry->description="TrueType font";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="TTF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PFA");
+#if defined(HasTTF)
+ entry->decoder=(DecoderHandler) ReadTTFImage;
+#endif
+ entry->magick=(MagickHandler) IsPFA;
+ entry->adjoin=False;
+ entry->description="Postscript Type 1 font (ASCII)";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="TTF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PFB");
+#if defined(HasTTF)
+ entry->decoder=(DecoderHandler) ReadTTFImage;
+#endif
+ entry->magick=(MagickHandler) IsPFA;
+ entry->adjoin=False;
+ entry->description="Postscript Type 1 font (binary)";
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="TTF";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r T T F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterTTFImage removes format registrations made by the
+% TTF module from the list of supported formats.
+%
+% The format of the UnregisterTTFImage method is:
+%
+% UnregisterTTFImage(void)
+%
+*/
+ModuleExport void UnregisterTTFImage(void)
+{
+ (void) UnregisterMagickInfo("TTF");
+ (void) UnregisterMagickInfo("PFA");
+ (void) UnregisterMagickInfo("PFB");
+}
diff --git a/coders/txt.c b/coders/txt.c
new file mode 100644
index 0000000..75bf7e8
--- /dev/null
+++ b/coders/txt.c
@@ -0,0 +1,1253 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT X X TTTTT %
+% T X X T %
+% T X T %
+% T X X T %
+% T X X T %
+% %
+% %
+% Render Text Onto A Canvas Image. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% Jaroslav Fojtik %
+% 2009 - 2010 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Patterns accepted:
+% 0,0: 129,129,129,255
+% 0,0: 129,129,129
+% 0,0: (129,129,129) #818181
+% 0,0: (3411594072,2774050136,1883729991) #CB58CB58A558A55870477047
+% 0,0: (129,129,129, 0) #81818100 rgba(129,129,129,0)
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/color.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/render.h"
+#include "magick/texture.h"
+#include "magick/utility.h"
+
+typedef enum
+{
+ NO_TXT = 0,
+ IMAGEMAGICK_TXT = 1,
+ TXT_GM8B_HEX,
+ TXT_GM8B_PLAIN,
+ TXT_GM8B_PLAIN2,
+ TXT_GM16B_HEX,
+ TXT_GM16B_PLAIN,
+ TXT_GM32B_HEX,
+ TXT_GM32B_PLAIN,
+ IMAGEMAGICK_TXT_Q = 17,
+ TXT_GM8B_HEX_Q,
+ TXT_GM8B_PLAIN_Q,
+ TXT_GM8B_PLAIN2_Q,
+ TXT_GM16B_HEX_Q,
+ TXT_GM16B_PLAIN_Q,
+ TXT_GM32B_HEX_Q,
+ TXT_GM32B_PLAIN_Q
+} TXT_TYPE;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteTXTImage(const ImageInfo *,Image *);
+
+
+/** Reads up to end of line. */
+static void readln(Image *image, int *pch)
+{
+ int
+ ch=0;
+
+ if (pch)
+ ch=*pch;
+ else
+ ch=' ';
+
+ while (ch != 10 && ch != 13 && ch != EOF)
+ {
+ ch = ReadBlobByte(image);
+ }
+ if (pch)
+ *pch=ch;
+}
+
+static long ReadInt(Image *image, int *pch)
+{
+ int
+ ch;
+
+ long
+ n;
+
+ n=0;
+ if (pch)
+ ch=*pch;
+ else
+ ch=' ';
+
+ while (isspace(ch) || ch == 0)
+ {
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ return (0);
+ }
+
+ while (isdigit(ch))
+ {
+ n=10*n+(ch-'0');
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ return (n);
+ }
+
+ if (pch)
+ *pch=ch;
+ /* else
+ ungetc(ch,F); */
+
+ return (n);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s T X T %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsTXT returns an enumerated value which indicates the raw TXT
+% image encoding subformat based on the file or blob header. If the data
+% is not an ASCII encoded raw image, then the value NO_TXT is returned.
+%
+% The format of the IsTXT method is:
+%
+% TXT_TYPE IsTXT(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsTXT returns a value from the TXT_TYPE enumeration.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static TXT_TYPE IsTXT(const unsigned char *magick,const size_t length)
+{
+ if (length < 20)
+ return (NO_TXT);
+
+ {
+ unsigned long
+ column,
+ row;
+
+ unsigned int
+ red,
+ green,
+ blue,
+ opacity,
+ hex_red,
+ hex_green,
+ hex_blue,
+ hex_opacity;
+
+ int
+ count;
+
+ char
+ buffer[MaxTextExtent];
+
+ (void) memset((void *)buffer,0,MaxTextExtent);
+ (void) memcpy((void *)buffer,(const void *)magick,Min(MaxTextExtent,length));
+
+ if (!strncmp(buffer,"# ImageMagick pixel enumeration:",32))
+ return IMAGEMAGICK_TXT;
+
+ count=sscanf(buffer,"%lu,%lu: (%u, %u, %u) #%02X%02X%02X",
+ &column, &row, &red, &green, &blue, &hex_red, &hex_green,
+ &hex_blue);
+ if ((count == 8) && (column == 0) && (row == 0) && (red == hex_red) &&
+ (green == hex_green) && (blue == hex_blue))
+ return (TXT_GM8B_HEX);
+
+ count=sscanf(buffer,"%lu,%lu: (%u, %u, %u) #%04X%04X%04X",
+ &column, &row, &red, &green, &blue, &hex_red, &hex_green,
+ &hex_blue);
+ if ((count == 8) && (column == 0) && (row == 0) && (red == hex_red) &&
+ (green == hex_green) && (blue == hex_blue))
+ return (TXT_GM16B_HEX);
+
+ count=sscanf(buffer,"%lu,%lu: (%u, %u, %u) #%08X%08X%08X",
+ &column, &row, &red, &green, &blue, &hex_red, &hex_green,
+ &hex_blue);
+ if ((count == 8) && (column == 0) && (row == 0) && (red == hex_red) &&
+ (green == hex_green) && (blue == hex_blue))
+ return (TXT_GM32B_HEX);
+
+ count=sscanf(buffer,"%lu,%lu: (%u, %u, %u, %u) #%02X%02X%02X%02X",
+ &column, &row, &red, &green, &blue, &opacity, &hex_red,
+ &hex_green, &hex_blue, &hex_opacity);
+ if ((count == 10) && (column == 0) && (row == 0) && (red == hex_red) &&
+ (green == hex_green) && (blue == hex_blue) && (opacity == hex_opacity))
+ return (TXT_GM8B_HEX_Q);
+
+ count=sscanf(buffer,"%lu,%lu: (%u, %u, %u, %u) #%04X%04X%04X%04X",
+ &column, &row, &red, &green, &blue, &opacity, &hex_red,
+ &hex_green, &hex_blue, &hex_opacity);
+ if ((count == 10) && (column == 0) && (row == 0) && (red == hex_red) &&
+ (green == hex_green) && (blue == hex_blue) && (opacity == hex_opacity))
+ return (TXT_GM16B_HEX_Q);
+
+ count=sscanf(buffer,"%lu,%lu: (%u, %u, %u, %u) #%08X%08X%08X%08X",
+ &column, &row, &red, &green, &blue, &opacity, &hex_red,
+ &hex_green, &hex_blue, &hex_opacity);
+ if ((count == 10) && (column == 0) && (row == 0) && (red == hex_red) &&
+ (green == hex_green) && (blue == hex_blue) && (opacity == hex_opacity))
+ return (TXT_GM32B_HEX_Q);
+
+ count=sscanf(buffer,"%lu,%lu: (%u, %u, %u, %u)",
+ &column, &row, &red, &green, &blue, &opacity);
+ if (count==6)
+ return TXT_GM8B_PLAIN_Q;
+
+ count=sscanf(buffer,"%lu,%lu: %u, %u, %u, %u",
+ &column, &row, &red, &green, &blue, &opacity);
+ if (count==6)
+ return TXT_GM8B_PLAIN2_Q;
+
+ count=sscanf(buffer,"%lu,%lu: (%u, %u, %u)",
+ &column, &row, &red, &green, &blue);
+ if (count==5)
+ return TXT_GM8B_PLAIN;
+
+ count=sscanf(buffer,"%lu,%lu: %u, %u, %u",
+ &column, &row, &red, &green, &blue);
+ if (count==5)
+ return TXT_GM8B_PLAIN2;
+
+ }
+ return (NO_TXT);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d T X T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadTXTImage reads a text file and returns it as an image. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadTXTImage method is:
+%
+% Image *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadTXTImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ *p,
+ text[MaxTextExtent];
+
+ Image
+ *image;
+
+ TXT_TYPE
+ txt_subformat;
+
+ MagickPassFail
+ status;
+
+ MagickBool
+ logging;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ logging = IsEventLogging();
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ p = ReadBlobString(image,text);
+ if (p == NULL)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ txt_subformat = IsTXT((unsigned char *)p,strlen(p));
+
+ if (txt_subformat != NO_TXT)
+ {
+#define ThrowNOTXTReaderException(code_,reason_,image_) \
+ do { \
+ MagickFreeMemory(BImgBuff); \
+ ThrowReaderException(code_,reason_,image_); \
+ } while (0);
+
+ unsigned
+ x,
+ y;
+
+ unsigned
+ x_min,
+ x_max,
+ y_curr;
+
+ int
+ ch;
+
+ unsigned long
+ max,
+ i;
+
+ char
+ NumOfPlanes;
+
+ unsigned char
+ *BImgBuff=0;
+
+ magick_uint16_t
+ *WImgBuff;
+
+ magick_uint32_t
+ *DImgBuff;
+
+ magick_uint32_t
+ R,
+ G,
+ B,
+ A;
+
+ const PixelPacket
+ *q;
+
+ ExtendedSignedIntegralType NextImagePos = 0;
+
+ ImportPixelAreaOptions
+ import_options;
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File RAW TXT type: %d", (int) txt_subformat);
+
+ do {
+ (void) SeekBlob(image,NextImagePos,SEEK_SET);
+
+ if(NextImagePos!=0)
+ {
+ /* Allocate next image structure. */
+ AllocateNextImage(image_info,image);
+ if(image->next == (Image *)NULL) break;
+ image = SyncNextImageInList(image);
+ image->columns = image->rows = 0;
+ image->colors=0;
+ }
+
+ A=0;
+ x=0;
+ y=0;
+ max=0;
+
+ switch(txt_subformat)
+ {
+ case TXT_GM8B_HEX:
+ case TXT_GM8B_HEX_Q:
+ max=255;
+ break;
+ case TXT_GM16B_HEX:
+ case TXT_GM16B_HEX_Q:
+ max=65535;
+ break;
+ case TXT_GM32B_HEX:
+ case TXT_GM32B_HEX_Q:
+ max=65536;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ Set opacity flag.
+ */
+ image->matte=MagickFalse;
+ if (txt_subformat >= IMAGEMAGICK_TXT_Q)
+ image->matte=MagickTrue;
+
+ if (!strncmp(p,"# ImageMagick pixel enumeration:",32))
+ {
+ if (sscanf(p+32,"%u,%u,%u",&x_min,&y_curr,&x_max) == 3)
+ {
+ if (strstr(p+32,",rgb")!=NULL)
+ {
+ x = x_min-1;
+ y = y_curr-1;
+ max = x_max;
+ }
+ if (strstr(p+32,",rgba")!=NULL)
+ {
+ txt_subformat = IMAGEMAGICK_TXT_Q;
+ }
+ }
+ }
+
+ ch=0;
+ if (x == 0 && y == 0)
+ while (!EOFBlob(image)) /* auto detect sizes and num of planes */
+ {
+ while (!(ch >= '0' && ch <= '9'))
+ {
+ /* go to the begin of number */
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ goto EndReading;
+ if (ch == '#')
+ {
+ readln(image,&ch);
+ continue;
+ }
+ if (ch == 0 || ch > 128 ||
+ (ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z'))
+ {
+ TXT_FAIL: /* not a text data */
+ ThrowNOTXTReaderException(CoderError,ImageTypeNotSupported,image);
+ }
+ }
+ /* x,y: (R,G,B) */
+ x_min = ReadInt(image,&ch); /* x */
+ if (x_min > x)
+ x = x_min;
+
+ while (ch != ',')
+ {
+ ch = ReadBlobByte(image);
+ if (ch==EOF)
+ break;
+ if (ch == 10 || ch == 13)
+ goto TXT_FAIL;
+ }
+ ch=0;
+ i=ReadInt(image,&ch); /* y */
+
+ /* Check for next image start. */
+ if(x_min==0 && i==0 && x>0 && y>0)
+ goto EndReading;
+
+ if (i > y)
+ y=i;
+
+ while (ch != ':')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == 10 || ch == 13)
+ goto TXT_FAIL;
+ if (ch == EOF)
+ break;
+ }
+ if (txt_subformat != TXT_GM8B_PLAIN2_Q)
+ while (ch != '(')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == 10 || ch == 13)
+ goto TXT_FAIL;
+ if (ch == EOF)
+ break;
+ }
+ ch=0;
+ R = ReadInt(image,&ch); /* R */
+ if (R > max)
+ max=R;
+
+ while (ch != ',')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == 10 || ch == 13)
+ goto TXT_FAIL;
+ if (ch == EOF)
+ break;
+ }
+ ch=0;
+ G = ReadInt(image,&ch); /* G */
+ if (G > max)
+ max=G;
+
+ while (ch != ',')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == 10 || ch == 13)
+ goto TXT_FAIL;
+ if (ch == EOF)
+ break;
+ }
+ ch=0;
+ B = ReadInt(image,&ch); /* B */
+ if (B > max)
+ max=B;
+
+ if (txt_subformat >= IMAGEMAGICK_TXT_Q)
+ {
+ while (ch != ',')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == 10 || ch == 13)
+ goto TXT_FAIL;
+ if (ch == EOF)
+ break;
+ }
+ ch=0;
+ A = ReadInt(image,&ch); /* A */
+ if (A > max)
+ max=A;
+ }
+
+ if (txt_subformat != TXT_GM8B_PLAIN2_Q)
+ while (ch != ')')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == 10 || ch == 13)
+ goto TXT_FAIL;
+ if (ch == EOF)
+ break;
+ }
+
+ readln(image,&ch);
+ }
+
+ EndReading:
+ x_min = 1;
+ x_max = 0;
+ y_curr = 0;
+
+ NumOfPlanes=8;
+ /* if (max>= 2) NumOfPlanes=2; */
+ /* if (max>= 4) NumOfPlanes=4; */
+ /* if (max>= 16) NumOfPlanes=8; */
+ if (max >= 256)
+ NumOfPlanes=16;
+ if (max >=65536)
+ NumOfPlanes=32;
+
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Image detected [%u * %u]: %d", x, y, NumOfPlanes);
+
+ image->depth = Min(QuantumDepth,NumOfPlanes);
+ ImportPixelAreaOptionsInit(&import_options);
+ import_options.endian = NativeEndian;
+
+ BImgBuff = MagickAllocateArray(unsigned char *,
+ (size_t)(x+1),
+ ( ((image->matte) ? 4 : 3)
+ * NumOfPlanes/8));
+ WImgBuff = (magick_uint16_t *)BImgBuff;
+ DImgBuff = (magick_uint32_t *)BImgBuff;
+ if (BImgBuff == NULL)
+ ThrowNOTXTReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ image->columns = x+1;
+ image->rows = y+1;
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowNOTXTReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ (void) SeekBlob(image,NextImagePos,SEEK_SET);
+ NextImagePos = 0;
+
+ /*
+ Load picture data
+ */
+ while (!EOFBlob(image))
+ {
+ x=0;
+ while (!(ch >= '0' && ch <= '9'))
+ {
+ /* move to the beginning of number */
+ if (EOFBlob(image))
+ goto FINISH;
+ ch = ReadBlobByte(image);
+ if (ch == '#')
+ {
+ readln(image,&ch);
+ continue;
+ }
+ }
+
+ x = ReadInt(image,&ch); /* x */
+
+ while (ch != ',')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ break;
+ }
+ ch = 0;
+ y = ReadInt(image,&ch); /* y */
+
+ /* New image detected. */
+ if(x==0 && y==0 && y_curr>0 && x_max>0)
+ {
+ NextImagePos = TellBlob(image) - 4;
+ break;
+ }
+
+ while (ch != ':')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ break;
+ }
+ while (ch != '(')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ break;
+ }
+ ch=0;
+ R = ReadInt(image,&ch); /* R */
+
+ while (ch != ',')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ break;
+ }
+ ch=0;
+ G = ReadInt(image,&ch); /* G */
+
+ while (ch != ',')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ break;
+ }
+ ch=0;
+ B = ReadInt(image,&ch); /* B */
+
+ if (image->matte)
+ {
+ while (ch != ',')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ break;
+ }
+ ch=0;
+ A = ReadInt(image,&ch); /* A */
+ if (A > max)
+ max=A;
+ }
+
+ while (ch != ')')
+ {
+ ch = ReadBlobByte(image);
+ if (ch == EOF)
+ break;
+ }
+
+
+ /* A new line has been detected */
+ if (y != y_curr)
+ {
+ q = SetImagePixels(image,x_min,y_curr,x_max-x_min+1,1);
+ if (q == (PixelPacket *)NULL)
+ break;
+
+ if (image->matte)
+ (void)ImportImagePixelArea(image,RGBAQuantum,NumOfPlanes,
+ BImgBuff + 4*x_min*(NumOfPlanes/8),
+ &import_options,0);
+ else
+ (void)ImportImagePixelArea(image,RGBQuantum,NumOfPlanes,
+ BImgBuff + 3*x_min*(NumOfPlanes/8),
+ &import_options,0);
+ if (!SyncImagePixels(image))
+ break;
+
+ x_min = 1;
+ x_max = 0;
+ y_curr=y;
+ }
+
+ if (x < image->columns)
+ {
+ if (image->matte)
+ {
+ switch(NumOfPlanes)
+ {
+ case 8:
+ BImgBuff[0+4*x] = R;
+ BImgBuff[1+4*x] = G;
+ BImgBuff[2+4*x] = B;
+ BImgBuff[3+4*x] = 255U-A;
+ break;
+ case 16:
+ WImgBuff[0+4*x] = R;
+ WImgBuff[1+4*x] = G;
+ WImgBuff[2+4*x] = B;
+ WImgBuff[3+4*x] = 65535U-A;
+ break;
+ case 32:
+ DImgBuff[0+4*x] = R;
+ DImgBuff[1+4*x] = G;
+ DImgBuff[2+4*x] = B;
+ DImgBuff[3+4*x] = 4294967295U-A;
+ break;
+ }
+ }
+ else
+ {
+ switch(NumOfPlanes)
+ {
+ case 8:
+ BImgBuff[0+3*x] = R;
+ BImgBuff[1+3*x] = G;
+ BImgBuff[2+3*x] = B;
+ break;
+ case 16:
+ WImgBuff[0+3*x] = R;
+ WImgBuff[1+3*x] = G;
+ WImgBuff[2+3*x] = B;
+ break;
+ case 32:
+ DImgBuff[0+3*x] = R;
+ DImgBuff[1+3*x] = G;
+ DImgBuff[2+3*x] = B;
+ break;
+ }
+ }
+ if (x_min > x_max)
+ {
+ x_max=x_min=x;
+ }
+ else
+ {
+ if (x < x_min)
+ x_min=x;
+ if (x > x_max)
+ x_max=x;
+ }
+ }
+
+ readln(image,&ch);
+ }
+
+ FINISH:
+ if (x_min <= x_max)
+ {
+ q = SetImagePixels(image,x_min,y_curr,x_max-x_min+1,1);
+ if (q != (PixelPacket *)NULL)
+ {
+ if (image->matte)
+ (void)ImportImagePixelArea(image, RGBAQuantum, NumOfPlanes,
+ BImgBuff + 4*x_min*(NumOfPlanes/8),
+ &import_options, 0);
+ else
+ (void)ImportImagePixelArea(image, RGBQuantum, NumOfPlanes,
+ BImgBuff + 3*x_min*(NumOfPlanes/8),
+ &import_options, 0);
+ if (!SyncImagePixels(image))
+ {
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ " TXT failed to sync image pixels for a row %u", y_curr);
+ }
+
+ }
+ }
+ /* Note that DImgBuff and WImgBuff point to BImgBuff */
+ MagickFreeMemory(BImgBuff);
+ } while(!EOFBlob(image) && NextImagePos>0);
+
+ goto FINISH_TXT;
+ }
+
+ {
+ /*
+ Render arbitrary ASCII text as image.
+ */
+ char
+ filename[MaxTextExtent],
+ geometry[MaxTextExtent];
+
+ double
+ dx_resolution,
+ dy_resolution;
+
+ Image
+ *texture = (Image *) NULL;
+
+ long
+ count,
+ line_num,
+ lines_per_page,
+ margins,
+ page_num,
+ pixels_per_line;
+
+ DrawInfo
+ *draw_info = (DrawInfo *) NULL;
+
+ RectangleInfo
+ page;
+
+ TypeMetric
+ metrics;
+
+ /*
+ Set the page geometry.
+ */
+ dx_resolution=72.0;
+ dy_resolution=72.0;
+ if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0))
+ {
+ char
+ density[MaxTextExtent];
+
+ (void) strlcpy(density,PSDensityGeometry,sizeof(density));
+ count=GetMagickDimension(density,&image->x_resolution,
+ &image->y_resolution,NULL,NULL);
+ if (count != 2)
+ image->y_resolution=image->x_resolution;
+ }
+ SetGeometry(image,&page);
+ page.width=612;
+ page.height=792;
+ (void) GetGeometry("612x792+43+43",&page.x,&page.y,&page.width,&page.height);
+ if (image_info->page != (char *) NULL)
+ (void) GetGeometry(image_info->page,&page.x,&page.y,&page.width,
+ &page.height);
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Page Geometry: %lux%lu%+ld%+ld",
+ page.width,page.height,page.x,page.y);
+ /*
+ Initialize Image structure.
+ */
+ image->columns=(unsigned long)
+ ceil(((page.width*image->x_resolution)/dx_resolution)-0.5);
+ image->rows=(unsigned long)
+ ceil(((page.height*image->y_resolution)/dy_resolution)-0.5);
+
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+
+ texture=(Image *) NULL;
+ if (image_info->texture != (char *) NULL)
+ {
+ ImageInfo
+ *clone_info;
+
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ (void) strlcpy(clone_info->filename,image_info->texture,MaxTextExtent);
+ texture=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ }
+ /*
+ Annotate the text image.
+ */
+ (void) SetImageEx(image,OpaqueOpacity,exception);
+ draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
+ draw_info->fill=image_info->pen;
+ (void) CloneString(&draw_info->text,image_info->filename);
+ FormatString(geometry,"0x0%+ld%+ld",page.x,page.y);
+ (void) CloneString(&draw_info->geometry,geometry);
+ status=GetTypeMetrics(image,draw_info,&metrics);
+ if (status == False)
+ {
+ if (texture != (Image *) NULL)
+ DestroyImage(texture);
+ DestroyDrawInfo(draw_info);
+ ThrowReaderException(TypeError,UnableToGetTypeMetrics,image);
+ }
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Type metrics: ascent=%g descent=%g"
+ " height=%g max_advance=%g",
+ metrics.ascent,metrics.descent,
+ metrics.height,metrics.max_advance);
+ pixels_per_line=(long) (metrics.ascent-metrics.descent);
+ margins=2*page.y;
+ lines_per_page=((image->rows+1)-margins)/pixels_per_line+1;
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Pixels per line: %ld",
+ pixels_per_line);
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Lines per page: %ld",
+ lines_per_page);
+ (void) strlcpy(filename,image_info->filename,MaxTextExtent);
+ if (draw_info->text != '\0')
+ *draw_info->text='\0';
+
+ page_num=1;
+ line_num=0;
+ while (p != (char *) NULL)
+ {
+ /*
+ Annotate image with text.
+
+ Text lines are concatenated so that a full page is
+ rendered at a time via AnnotateImage().
+ */
+ (void) ConcatenateString(&draw_info->text,text);
+ (void) ConcatenateString(&draw_info->text,"\\n");
+ line_num++;
+
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(line_num,lines_per_page))
+ if (!MagickMonitorFormatted(line_num,lines_per_page,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+
+ p=ReadBlobString(image,text);
+ if ((line_num < lines_per_page) && (p != (char *) NULL))
+ continue;
+ if (texture != (Image *) NULL)
+ {
+ MonitorHandler
+ handler;
+
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ (void) TextureImage(image,texture);
+ (void) SetMonitorHandler(handler);
+ }
+ (void) AnnotateImage(image,draw_info);
+ if (p == (char *) NULL)
+ break;
+
+ if (logging)
+ (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "page %ld scene %ld ",page_num, image->scene);
+
+ if ((image_info->subimage != 0) || (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+
+ /*
+ Page is full-- allocate next image structure.
+ */
+ *draw_info->text='\0';
+ page_num++;
+ line_num=0;
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyDrawInfo(draw_info);
+ DestroyImageList(image);
+ return ((Image *) NULL);
+ }
+ image->next->columns=image->columns;
+ image->next->rows=image->rows;
+ image=SyncNextImageInList(image);
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ (void) SetImage(image,OpaqueOpacity);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+
+ if (texture != (Image *) NULL)
+ {
+ MonitorHandler
+ handler;
+
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ (void) TextureImage(image,texture);
+ (void) SetMonitorHandler(handler);
+ }
+ (void) AnnotateImage(image,draw_info);
+ if (texture != (Image *) NULL)
+ DestroyImage(texture);
+ DestroyDrawInfo(draw_info);
+ }
+
+ FINISH_TXT:
+ CloseBlob(image);
+ {
+ Image *p;
+ long scene=0;
+
+ /*
+ Rewind list, removing any empty images while rewinding.
+ */
+ p=image;
+ image=NULL;
+ while(p != (Image *) NULL)
+ {
+ Image *tmp=p;
+ if ((p->rows == 0) || (p->columns == 0)) {
+ p=p->previous;
+ DeleteImageFromList(&tmp);
+ } else {
+ image=p;
+ p=p->previous;
+ }
+ }
+
+ /*
+ Fix scene numbers
+ */
+ for(p=image; p != (Image *)NULL; p=p->next)
+ p->scene=scene++;
+ }
+
+ if(logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ return (image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r T X T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterTXTImage adds attributes for the TXT image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterTXTImage method is:
+%
+% RegisterTXTImage(void)
+%
+*/
+ModuleExport void RegisterTXTImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("TEXT");
+ entry->decoder=(DecoderHandler) ReadTXTImage;
+ entry->encoder=(EncoderHandler) WriteTXTImage;
+ entry->raw=MagickTrue;
+ entry->description="ASCII Text";
+ entry->module="TXT";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("TXT");
+ entry->decoder=(DecoderHandler) ReadTXTImage;
+ entry->encoder=(EncoderHandler) WriteTXTImage;
+ entry->seekable_stream=MagickTrue;
+ entry->description="ASCII Text";
+ entry->module="TXT";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r T X T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterTXTImage removes format registrations made by the
+% TXT module from the list of supported formats.
+%
+% The format of the UnregisterTXTImage method is:
+%
+% UnregisterTXTImage(void)
+%
+*/
+ModuleExport void UnregisterTXTImage(void)
+{
+ (void) UnregisterMagickInfo("TEXT");
+ (void) UnregisterMagickInfo("TXT");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e T X T I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteTXTImage writes the pixel values as text numbers.
+%
+% The format of the WriteTXTImage method is:
+%
+% unsigned int WriteTXTImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteTXTImage return MagickTrue if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteTXTImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ buffer[MaxTextExtent],
+ tuple[MaxTextExtent];
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ unsigned int
+ status;
+
+ unsigned long
+ scene;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ scene=0;
+ do
+ {
+ unsigned int
+ depth;
+
+ (void) TransformColorspace(image,RGBColorspace);
+ if (image->depth <= 8)
+ depth=8;
+ else if (image->depth <= 16)
+ depth=16;
+ else
+ depth=32;
+
+ if ((AccessDefinition(image_info,"txt","with-im-header")))
+ {
+ /* Write ImageMagick txt header */
+
+ unsigned char a = image->matte ? 'a' : ' ';
+
+ FormatString(buffer,
+ "# ImageMagick pixel enumeration: %.20g,%.20g,%.20g,rgb%c\n",
+ (double) image->columns, (double) image->rows, (double) depth, a);
+
+ (void) WriteBlobString(image,buffer);
+ }
+
+ /*
+ Convert MIFF to TXT raster pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ FormatString(buffer,"%ld,%ld: ",x,y);
+ (void) WriteBlobString(image,buffer);
+ GetColorTuple(p,depth,image->matte,MagickFalse,tuple);
+ (void) strlcat(tuple," ",sizeof(tuple));
+ (void) WriteBlobString(image,tuple);
+ /* (void) QueryColorname(image,p,SVGCompliance,tuple,&image->exception); */
+ GetColorTuple(p,depth,image->matte,MagickTrue,tuple);
+ (void) WriteBlobString(image,tuple);
+ (void) WriteBlobString(image,"\n");
+ p++;
+ }
+ }
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return (MagickTrue);
+}
diff --git a/coders/uil.c b/coders/uil.c
new file mode 100644
index 0000000..9a58143
--- /dev/null
+++ b/coders/uil.c
@@ -0,0 +1,341 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U U IIIII L %
+% U U I L %
+% U U I L %
+% U U I L %
+% UUU IIIII LLLLL %
+% %
+% %
+% Write X-Motif UIL Table %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteUILImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r U I L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterUILImage adds attributes for the UIL image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterUILImage method is:
+%
+% RegisterUILImage(void)
+%
+*/
+ModuleExport void RegisterUILImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("UIL");
+ entry->encoder=(EncoderHandler) WriteUILImage;
+ entry->adjoin=False;
+ entry->description="X-Motif UIL table";
+ entry->module="UIL";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r U I L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterUILImage removes format registrations made by the
+% UIL module from the list of supported formats.
+%
+% The format of the UnregisterUILImage method is:
+%
+% UnregisterUILImage(void)
+%
+*/
+ModuleExport void UnregisterUILImage(void)
+{
+ (void) UnregisterMagickInfo("UIL");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e U I L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure WriteUILImage writes an image to a file in the X-Motif UIL table
+% format.
+%
+% The format of the WriteUILImage method is:
+%
+% unsigned int WriteUILImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteUILImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteUILImage(const ImageInfo *image_info,Image *image)
+{
+#define MaxCixels 92
+
+ static const char
+ Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk"
+ "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
+
+ char
+ basename[MaxTextExtent],
+ buffer[MaxTextExtent],
+ name[MaxTextExtent],
+ symbol[MaxTextExtent];
+
+ int
+ j;
+
+ long
+ k,
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ unsigned int
+ status,
+ transparent;
+
+ unsigned long
+ characters_per_pixel,
+ colors,
+ number_pixels;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ transparent=False;
+ i=0;
+ p=(const PixelPacket *) NULL;
+ if (image->storage_class == PseudoClass)
+ colors=image->colors;
+ else
+ {
+ unsigned char
+ *matte_image;
+
+ /*
+ Convert DirectClass to PseudoClass image.
+ */
+ matte_image=(unsigned char *) NULL;
+ if (image->matte)
+ {
+ /*
+ Map all the transparent pixels.
+ */
+ number_pixels=image->columns*image->rows;
+ matte_image=MagickAllocateMemory(unsigned char *,number_pixels);
+ if (matte_image == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ matte_image[i]=(unsigned char) (p->opacity == TransparentOpacity);
+ if (matte_image[i])
+ transparent=True;
+ i++;
+ p++;
+ }
+ }
+ }
+ (void) SetImageType(image,PaletteType);
+ colors=image->colors;
+ if (transparent)
+ {
+ colors++;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register IndexPacket
+ *indexes;
+
+ p=GetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (matte_image[i])
+ indexes[x]=(IndexPacket) image->colors;
+ p++;
+ }
+ }
+ }
+ if (matte_image != (unsigned char *) NULL)
+ MagickFreeMemory(matte_image);
+ }
+ /*
+ Compute the character per pixel.
+ */
+ characters_per_pixel=1;
+ for (k=MaxCixels; (long) colors > k; k*=MaxCixels)
+ characters_per_pixel++;
+ /*
+ UIL header.
+ */
+ (void) WriteBlobString(image,"/* UIL */\n");
+ GetPathComponent(image->filename,BasePath,basename);
+ FormatString(buffer,"value\n %.1024s_ct : color_table(\n",basename);
+ (void) WriteBlobString(image,buffer);
+ for (i=0; i < (long) colors; i++)
+ {
+ /*
+ Define UIL color.
+ */
+ (void) QueryColorname(image,image->colormap+i,X11Compliance,name,
+ &image->exception);
+ if (transparent)
+ if (i == (long) (colors-1))
+ (void) strcpy(name,"None");
+ /*
+ Write UIL color.
+ */
+ k=i % MaxCixels;
+ symbol[0]=Cixel[k];
+ for (j=1; j < (int) characters_per_pixel; j++)
+ {
+ k=((i-k)/MaxCixels) % MaxCixels;
+ symbol[j]=Cixel[k];
+ }
+ symbol[j]='\0';
+ if (LocaleCompare(name,"None") == 0)
+ FormatString(buffer," background color = '%.1024s'",symbol);
+ else
+ FormatString(buffer," color('%.1024s',%.1024s) = '%.1024s'",name,
+ PixelIntensityToQuantum(image->colormap+i) < (((double) MaxRGB+1.0)/2.0) ?
+ "background" : "foreground",symbol);
+ (void) WriteBlobString(image,buffer);
+ FormatString(buffer,"%.1024s",(i == (long) (colors-1) ? ");\n" : ",\n"));
+ (void) WriteBlobString(image,buffer);
+ }
+ /*
+ Define UIL pixels.
+ */
+ GetPathComponent(image->filename,BasePath,basename);
+ FormatString(buffer,
+ " %.1024s_icon : icon(color_table = %.1024s_ct,\n",basename,basename);
+ (void) WriteBlobString(image,buffer);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register const IndexPacket
+ *indexes;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ (void) WriteBlobString(image," \"");
+ for (x=0; x < (long) image->columns; x++)
+ {
+ k=(long) (indexes[x] % MaxCixels);
+ symbol[0]=Cixel[k];
+ for (j=1; j < (int) characters_per_pixel; j++)
+ {
+ k=(((int) indexes[x]-k)/MaxCixels) % MaxCixels;
+ symbol[j]=Cixel[k];
+ }
+ symbol[j]='\0';
+ (void) strlcpy(buffer,symbol,MaxTextExtent);
+ (void) WriteBlobString(image,buffer);
+ p++;
+ }
+ FormatString(buffer,"\"%.1024s\n",
+ (y == (long) (image->rows-1) ? ");" : ","));
+ (void) WriteBlobString(image,buffer);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/url.c b/coders/url.c
new file mode 100644
index 0000000..0effa56
--- /dev/null
+++ b/coders/url.c
@@ -0,0 +1,304 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U U RRRR L %
+% U U R R L %
+% U U RRRR L %
+% U U R R L %
+% UUU R R LLLLL %
+% %
+% %
+% Retrieve An Image Via a URL. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% Bill Radcliffe %
+% March 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#if defined(HasXML)
+#include "magick/blob.h"
+#include "magick/confirm_access.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#if defined(MSWINDOWS)
+# if defined(__MINGW32__)
+# define _MSC_VER
+# else
+# include <win32config.h>
+# endif
+#endif
+#include <libxml/parser.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/nanoftp.h>
+#include <libxml/nanohttp.h>
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d U R L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadURLImage retrieves an image via a URL, decodes the image, and
+% returns it. It allocates the memory necessary for the new Image structure
+% and returns a pointer to the new image.
+%
+% The format of the ReadURLImage method is:
+%
+% Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadURLImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static void GetFTPData(void *userdata,const char *data,int length)
+{
+ FILE
+ *file;
+
+ file=(FILE *) userdata;
+ if (file == (FILE *) NULL)
+ return;
+ if (length <= 0)
+ return;
+ (void) fwrite(data,length,1,file);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define MaxBufferExtent 8192
+
+ char
+ buffer[MaxBufferExtent],
+ filename[MaxTextExtent];
+
+ FILE
+ *file;
+
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ void
+ *context;
+
+ ConfirmAccessMode
+ access_mode=UndefinedConfirmAccessMode;
+
+ image=(Image *) NULL;
+
+ if (LocaleCompare(image_info->magick,"ftp") == 0)
+ access_mode=URLGetFTPConfirmAccessMode;
+ else if (LocaleCompare(image_info->magick,"http") == 0)
+ access_mode=URLGetHTTPConfirmAccessMode;
+ else if (LocaleCompare(image_info->magick,"file") == 0)
+ access_mode=URLGetFileConfirmAccessMode;
+
+
+ /* Attempt to re-compose original URL */
+ (void) strlcpy(filename,image_info->magick,MaxTextExtent);
+ LocaleLower(filename);
+ (void) strlcat(filename,":",MaxTextExtent);
+ (void) strlcat(filename,image_info->filename,MaxTextExtent);
+
+ if (MagickConfirmAccess(access_mode,filename,exception)
+ == MagickFail)
+ return image;
+
+ clone_info=CloneImageInfo(image_info);
+ if (LocaleCompare(clone_info->magick,"file") == 0)
+ {
+ /* Skip over "//" at start of parsed filename */
+ (void) strlcpy(clone_info->filename,image_info->filename+2,
+ sizeof(clone_info->filename));
+ clone_info->magick[0]='\'';
+ image=ReadImage(clone_info,exception);
+ }
+ else
+ {
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ file=AcquireTemporaryFileStream(clone_info->filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ {
+ (void) strlcpy(filename,clone_info->filename,sizeof(filename));
+ DestroyImageInfo(clone_info);
+ ThrowReaderTemporaryFileException(filename);
+ }
+ if (LocaleCompare(clone_info->magick,"http") == 0)
+ {
+ char
+ *type;
+
+ int
+ bytes;
+
+ type=(char *) NULL;
+ context=xmlNanoHTTPOpen(filename,&type);
+ if (context != (void *) NULL)
+ {
+ while ((bytes=xmlNanoHTTPRead(context,buffer,MaxBufferExtent)) > 0)
+ (void) fwrite(buffer,bytes,1,file);
+ xmlNanoHTTPClose(context);
+ xmlFree(type);
+ xmlNanoHTTPCleanup();
+ }
+ }
+ else if (LocaleCompare(clone_info->magick,"ftp") == 0)
+ {
+ xmlNanoFTPInit();
+ context=xmlNanoFTPNewCtxt(filename);
+ if (context != (void *) NULL)
+ {
+ if (xmlNanoFTPConnect(context) >= 0)
+ (void) xmlNanoFTPGet(context,GetFTPData,(void *) file,
+ (char *) NULL);
+ (void) xmlNanoFTPClose(context);
+ }
+ }
+ (void) fclose(file);
+ if (!IsAccessibleAndNotEmpty(clone_info->filename))
+ {
+ (void) LiberateTemporaryFile(clone_info->filename);
+ ThrowException(exception,CoderError,NoDataReturned,filename);
+ }
+ else
+ {
+ *clone_info->magick='\0';
+ image=ReadImage(clone_info,exception);
+ }
+ (void) LiberateTemporaryFile(clone_info->filename);
+ }
+ DestroyImageInfo(clone_info);
+ return(image);
+}
+#endif /* defined(HasXML) */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r U R L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterURLImage adds attributes for the URL image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterURLImage method is:
+%
+% RegisterURLImage(void)
+%
+*/
+ModuleExport void RegisterURLImage(void)
+{
+#if defined(HasXML)
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("HTTP");
+ entry->decoder=(DecoderHandler) ReadURLImage;
+ entry->description="Uniform Resource Locator (http://)";
+ entry->module="URL";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("FTP");
+ entry->decoder=(DecoderHandler) ReadURLImage;
+ entry->description="Uniform Resource Locator (ftp://)";
+ entry->module="URL";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->coder_class=UnstableCoderClass;
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("FILE");
+ entry->decoder=(DecoderHandler) ReadURLImage;
+ entry->description="Uniform Resource Locator (file://)";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ entry->module="URL";
+ entry->coder_class=StableCoderClass;
+ (void) RegisterMagickInfo(entry);
+#endif /* defined(HasXML) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r U R L I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterURLImage removes format registrations made by the
+% URL module from the list of supported formats.
+%
+% The format of the UnregisterURLImage method is:
+%
+% UnregisterURLImage(void)
+%
+*/
+ModuleExport void UnregisterURLImage(void)
+{
+#if defined(HasXML)
+ (void) UnregisterMagickInfo("HTTP");
+ (void) UnregisterMagickInfo("FTP");
+ (void) UnregisterMagickInfo("FILE");
+#endif /* defined(HasXML) */
+}
diff --git a/coders/uyvy.c b/coders/uyvy.c
new file mode 100644
index 0000000..4f003bf
--- /dev/null
+++ b/coders/uyvy.c
@@ -0,0 +1,366 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U U Y Y V V Y Y %
+% U U Y Y V V Y Y %
+% U U Y V V Y %
+% U U Y V V Y %
+% UUU Y V Y %
+% %
+% %
+% Read/Write 16bit/pixel Interleaved YUV Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteUYVYImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d U Y V Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadUYVYImage reads an image in the UYVY format and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadUYVYImage method is:
+%
+% Image *ReadUYVYImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadUYVYImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadUYVYImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ unsigned char
+ u,
+ v,
+ y1,
+ y2;
+
+ unsigned int
+ status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(OptionError,MustSpecifyImageSize,image);
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ When subsampling, image width must be evenly divisible by two.
+ */
+ if (image->columns %2)
+ ThrowReaderException(CorruptImageError,SubsamplingRequiresEvenWidth,image);
+ for (i=0; i < image->offset; i++)
+ {
+ if (EOF == ReadBlobByte(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ }
+ image->depth=8;
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+ /*
+ Accumulate UYVY, then unpack into two pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) (image->columns >> 1); x++)
+ {
+ u=ReadBlobByte(image);
+ y1=ReadBlobByte(image);
+ v=ReadBlobByte(image);
+ y2=ReadBlobByte(image);
+ q->red=ScaleCharToQuantum(y1);
+ q->green=ScaleCharToQuantum(u);
+ q->blue=ScaleCharToQuantum(v);
+ q++;
+ q->red=ScaleCharToQuantum(y2);
+ q->green=ScaleCharToQuantum(u);
+ q->blue=ScaleCharToQuantum(v);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ image->colorspace=YCbCrColorspace;
+ (void) TransformColorspace(image,RGBColorspace);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r U Y V Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterUYVYImage adds attributes for the UYVY image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterUYVYImage method is:
+%
+% RegisterUYVYImage(void)
+%
+*/
+ModuleExport void RegisterUYVYImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PAL");
+ entry->decoder=(DecoderHandler) ReadUYVYImage;
+ entry->encoder=(EncoderHandler) WriteUYVYImage;
+ entry->adjoin=False;
+ entry->raw=True;
+ entry->description="16bit/pixel interleaved YUV";
+ entry->module="UYVY";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("UYVY");
+ entry->decoder=(DecoderHandler) ReadUYVYImage;
+ entry->encoder=(EncoderHandler) WriteUYVYImage;
+ entry->adjoin=False;
+ entry->raw=True;
+ entry->description="16bit/pixel interleaved YUV";
+ entry->module="UYVY";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r U Y V Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterUYVYImage removes format registrations made by the
+% UYVY module from the list of supported formats.
+%
+% The format of the UnregisterUYVYImage method is:
+%
+% UnregisterUYVYImage(void)
+%
+*/
+ModuleExport void UnregisterUYVYImage(void)
+{
+ (void) UnregisterMagickInfo("PAL");
+ (void) UnregisterMagickInfo("UYVY");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e U Y V Y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteUYVYImage writes an image to a file in the digital UYVY
+% format. This format, used by AccomWSD, is not dramatically higher quality
+% than the 12bit/pixel YUV format, but has better locality.
+%
+% The format of the WriteUYVYImage method is:
+%
+% unsigned int WriteUYVYImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteUYVYImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+% Implicit assumption: number of columns is even.
+%
+*/
+static unsigned int WriteUYVYImage(const ImageInfo *image_info,Image *image)
+{
+ DoublePixelPacket
+ pixel;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ unsigned int
+ full,
+ status;
+
+ ColorspaceType
+ original_colorspace;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ When subsampling, image width must be evenly divisible by two.
+ */
+ if (image->columns %2)
+ ThrowWriterException(CoderError,SubsamplingRequiresEvenWidth,image);
+
+ /*
+ Convert to YUV, at full resolution.
+ */
+ original_colorspace=image->colorspace;
+ (void) TransformColorspace(image,YCbCrColorspace);
+ /*
+ Accumulate two pixels, then output.
+ */
+ full=False;
+ (void) memset(&pixel,0,sizeof(DoublePixelPacket));
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (full)
+ {
+ pixel.green=(pixel.green+p->green)/2;
+ pixel.blue=(pixel.blue+p->blue)/2;
+ (void) WriteBlobByte(image,ScaleQuantumToChar(pixel.green));
+ (void) WriteBlobByte(image,ScaleQuantumToChar(pixel.red));
+ (void) WriteBlobByte(image,ScaleQuantumToChar(pixel.blue));
+ (void) WriteBlobByte(image,ScaleQuantumToChar(p->red));
+ }
+ pixel.red=p->red;
+ pixel.green=p->green;
+ pixel.blue=p->blue;
+ full=!full;
+ p++;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ /*
+ Restore colorspace
+ */
+ (void) TransformColorspace(image,original_colorspace);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/vicar.c b/coders/vicar.c
new file mode 100644
index 0000000..3e2c90d
--- /dev/null
+++ b/coders/vicar.c
@@ -0,0 +1,463 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% V V IIIII CCCC AAA RRRR %
+% V V I C A A R R %
+% V V I C AAAAA RRRR %
+% V V I C A A R R %
+% V IIIII CCCC A A R R %
+% %
+% %
+% Read/Write VICAR Rasterfile Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteVICARImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s V I C A R %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsVICAR returns True if the image format type, identified by the
+% magick string, is VICAR.
+%
+% The format of the IsVICAR method is:
+%
+% unsigned int IsVICAR(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsVICAR returns True if the image format type is VICAR.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsVICAR(const unsigned char *magick,const size_t length)
+{
+ if (length < 7)
+ return(False);
+ if (LocaleNCompare((char *) magick,"LBLSIZE",7) == 0)
+ return(True);
+ if (LocaleNCompare((char *) magick,"NJPL1I",6) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d V I C A R I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadVICARImage reads a VICAR image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadVICARImage method is:
+%
+% Image *ReadVICARImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadVICARImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadVICARImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ char
+ keyword[MaxTextExtent],
+ value[MaxTextExtent];
+
+ Image
+ *image;
+
+ int
+ c,
+ y;
+
+ long
+ count;
+
+ unsigned char
+ *scanline;
+
+ unsigned int
+ status,
+ value_expected;
+
+ unsigned long
+ length;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Decode image header.
+ */
+ c=ReadBlobByte(image);
+ count=1;
+ if (c == EOF)
+ {
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ length=0;
+ image->columns=0;
+ image->rows=0;
+ while (isgraph(c) && ((image->columns == 0) || (image->rows == 0)))
+ {
+ if (!isalnum(c))
+ {
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ count++;
+ }
+ else
+ {
+ register char
+ *p;
+
+ /*
+ Determine a keyword and its value.
+ */
+ p=keyword;
+ do
+ {
+ if ((p-keyword) < (MaxTextExtent-1))
+ *p++=c;
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ count++;
+ } while (isalnum(c) || (c == '_'));
+ if (EOFBlob(image))
+ break;
+ *p='\0';
+ value_expected=False;
+ while (isspace(c) || (c == '='))
+ {
+ if (c == '=')
+ value_expected=True;
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ count++;
+ }
+ if (EOFBlob(image))
+ break;
+ if (value_expected == False)
+ continue;
+ p=value;
+ while (isalnum(c))
+ {
+ if ((p-value) < (MaxTextExtent-1))
+ *p++=c;
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ count++;
+ }
+ if (EOFBlob(image))
+ break;
+ *p='\0';
+ /*
+ Assign a value to the specified keyword.
+ */
+ if (LocaleCompare(keyword,"Label_RECORDS") == 0)
+ length=MagickAtoL(value);
+ if (LocaleCompare(keyword,"LBLSIZE") == 0)
+ length=MagickAtoL(value);
+ if (LocaleCompare(keyword,"RECORD_BYTES") == 0)
+ image->columns= MagickAtoL(value);
+ if (LocaleCompare(keyword,"NS") == 0)
+ image->columns= MagickAtoL(value);
+ if (LocaleCompare(keyword,"LINES") == 0)
+ image->rows= MagickAtoL(value);
+ if (LocaleCompare(keyword,"NL") == 0)
+ image->rows= MagickAtoL(value);
+ }
+ while (isspace(c))
+ {
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ count++;
+ }
+ if (EOFBlob(image))
+ break;
+ }
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ while (count < (long) length)
+ {
+ if ((c=ReadBlobByte(image)) == EOF)
+ break;
+ count++;
+ }
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+ image->depth=8;
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ if (!AllocateImageColormap(image,256))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Read VICAR pixels.
+ */
+ scanline=MagickAllocateMemory(unsigned char *,image->columns);
+ if (scanline == (unsigned char *) NULL)
+ ThrowReaderException(CorruptImageError,UnableToReadImageData,image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (!SetImagePixelsEx(image,0,y,image->columns,1,exception))
+ break;
+ if (ReadBlob(image,image->columns,scanline) != image->columns)
+ break;
+ if (ImportImagePixelArea(image,GrayQuantum,image->depth,scanline,0,0) ==
+ MagickFail)
+ break;
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(scanline);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r V I C A R I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterVICARImage adds attributes for the VICAR image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterVICARImage method is:
+%
+% RegisterVICARImage(void)
+%
+*/
+ModuleExport void RegisterVICARImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("VICAR");
+ entry->decoder=(DecoderHandler) ReadVICARImage;
+ entry->encoder=(EncoderHandler) WriteVICARImage;
+ entry->magick=(MagickHandler) IsVICAR;
+ entry->adjoin=False;
+ entry->description="VICAR rasterfile format";
+ entry->module="VICAR";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r V I C A R I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterVICARImage removes format registrations made by the
+% VICAR module from the list of supported formats.
+%
+% The format of the UnregisterVICARImage method is:
+%
+% UnregisterVICARImage(void)
+%
+*/
+ModuleExport void UnregisterVICARImage(void)
+{
+ (void) UnregisterMagickInfo("VICAR");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e V I C A R I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteVICARImage writes an image in the VICAR rasterfile format.
+% Vicar files contain a text header, followed by one or more planes of binary
+% grayscale image data. Vicar files are designed to allow many planes to be
+% stacked together to form image cubes. This method only writes a single
+% grayscale plane.
+%
+% Method WriteVICARImage was written contributed by
+% gorelick@esther.la.asu.edu.
+%
+% The format of the WriteVICARImage method is:
+%
+% unsigned int WriteVICARImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteVICARImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteVICARImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ header[MaxTextExtent];
+
+ int
+ y;
+
+ unsigned char
+ *scanline;
+
+ unsigned int
+ status;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Write header.
+ */
+ (void) memset(header,' ',MaxTextExtent);
+ FormatString(header,"LBLSIZE=%u FORMAT='BYTE' TYPE='IMAGE' BUFSIZE=20000 "
+ "DIM=2 EOL=0 RECSIZE=%lu ORG='BSQ' NL=%lu NS=%lu NB=1 N1=0 N2=0 N3=0 N4=0 "
+ "NBB=0 NLB=0 TASK='GraphicsMagick'",MaxTextExtent,image->columns,image->rows,
+ image->columns);
+ (void) WriteBlob(image,MaxTextExtent,header);
+ /*
+ Allocate memory for scanline.
+ */
+ scanline=MagickAllocateMemory(unsigned char *,image->columns);
+ if (scanline == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Write VICAR scanline.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (!AcquireImagePixels(image,0,y,image->columns,1,&image->exception))
+ break;
+ (void) ExportImagePixelArea(image,GrayQuantum,8,scanline,0,0);
+ (void) WriteBlob(image,image->columns,scanline);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(scanline);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/vid.c b/coders/vid.c
new file mode 100644
index 0000000..a6f900d
--- /dev/null
+++ b/coders/vid.c
@@ -0,0 +1,366 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% V V IIIII DDDD %
+% V V I D D %
+% V V I D D %
+% V V I D D %
+% V IIIII DDDD %
+% %
+% %
+% Return a Visual Image Directory for matching images. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/constitute.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/montage.h"
+#include "magick/resize.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteVIDImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d V I D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadVIDImage reads one of more images and creates a Visual Image
+% Directory file. It allocates the memory necessary for the new Image
+% structure and returns a pointer to the new image.
+%
+% The format of the ReadVIDImage method is:
+%
+% Image *ReadVIDImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadVIDImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+#define LiberateVIDLists() \
+ { \
+ if ((filelist) && (list != filelist)) \
+ { \
+ for (i=0; i < number_files; i++) \
+ MagickFreeMemory(filelist[i]); \
+ MagickFreeMemory(filelist); \
+ } \
+ MagickFreeMemory(list[0]); \
+ MagickFreeMemory(list); \
+ }
+
+#define ThrowVIDReaderException(code_,reason_,image_) \
+ { \
+ LiberateVIDLists(); \
+ ThrowReaderException(code_,reason_,image_); \
+ }
+
+static Image *ReadVIDImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+#define ClientName "montage"
+
+ char
+ **filelist=0,
+ **list=0;
+
+ Image
+ *image=0,
+ *montage_image,
+ *next_image,
+ *thumbnail_image;
+
+ ImageInfo
+ *clone_info=0;
+
+ int
+ number_files=0;
+
+ MonitorHandler
+ handler;
+
+ MontageInfo
+ *montage_info;
+
+ RectangleInfo
+ geometry;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ /*
+ Expand the filename.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+ image=AllocateImage(image_info);
+ list=MagickAllocateMemory(char **,sizeof(char *));
+ if (list == (char **) NULL)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ ThrowVIDReaderException(ResourceLimitError,MemoryAllocationFailed,image)
+ }
+ list[0]=(char *) AllocateString((char *) NULL);
+ (void) strlcpy(list[0],image_info->filename,MaxTextExtent);
+ number_files=1;
+ filelist=list;
+ status=ExpandFilenames(&number_files,&filelist);
+ if ((status == False) || (number_files == 0))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ ThrowVIDReaderException(ResourceLimitError,MemoryAllocationFailed,image)
+ }
+ DestroyImage(image);
+ image=(Image *) NULL;
+ /*
+ Read each image and convert them to a tile.
+ */
+ image=(Image *) NULL;
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+ if (clone_info->size == (char *) NULL)
+ (void) CloneString(&clone_info->size,DefaultTileGeometry);
+ for (i=0; i < number_files; i++)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"name: %.1024s",
+ filelist[i]);
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ (void) strlcpy(clone_info->filename,filelist[i],MaxTextExtent);
+ *clone_info->magick='\0';
+ next_image=ReadImage(clone_info,exception);
+ MagickFreeMemory(filelist[i]);
+ if (next_image != (Image *) NULL)
+ {
+ (void) SetImageAttribute(next_image,"label",DefaultTileLabel);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"geometry: %ldx%ld",
+ next_image->columns,next_image->rows);
+ SetGeometry(next_image,&geometry);
+ (void) GetMagickGeometry(clone_info->size,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ thumbnail_image=ZoomImage(next_image,geometry.width,geometry.height,
+ exception);
+ if (thumbnail_image != (Image *) NULL)
+ {
+ DestroyImage(next_image);
+ next_image=thumbnail_image;
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "thumbnail geometry: %ldx%ld",next_image->columns,next_image->rows);
+ if (image == (Image *) NULL)
+ image=next_image;
+ else
+ {
+ image->next=next_image;
+ image->next->previous=image;
+ image=SyncNextImageInList(image);
+ }
+ }
+ (void) SetMonitorHandler(handler);
+ if (image != (Image *) NULL)
+ if (!MagickMonitorFormatted(i,number_files,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ DestroyImageInfo(clone_info);
+ clone_info=(ImageInfo *) NULL;
+ MagickFreeMemory(filelist);
+ if (image == (Image *) NULL)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ ThrowVIDReaderException(CorruptImageError,UnableToReadVIDImage,image)
+ }
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ /*
+ Create the visual image directory.
+ */
+ montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"creating montage");
+ montage_image=MontageImages(image,montage_info,exception);
+ DestroyMontageInfo(montage_info);
+ montage_info=(MontageInfo *) NULL;
+ if (montage_image == (Image *) NULL)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ ThrowVIDReaderException(CorruptImageError,UnableToReadVIDImage,image)
+ }
+ DestroyImageList(image);
+ LiberateVIDLists();
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ return(montage_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r V I D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterVIDImage adds attributes for the VID image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterVIDImage method is:
+%
+% RegisterVIDImage(void)
+%
+*/
+ModuleExport void RegisterVIDImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("VID");
+ entry->decoder=(DecoderHandler) ReadVIDImage;
+ entry->encoder=(EncoderHandler) WriteVIDImage;
+ entry->description="Visual Image Directory";
+ entry->module="VID";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r V I D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterVIDImage removes format registrations made by the
+% VID module from the list of supported formats.
+%
+% The format of the UnregisterVIDImage method is:
+%
+% UnregisterVIDImage(void)
+%
+*/
+ModuleExport void UnregisterVIDImage(void)
+{
+ (void) UnregisterMagickInfo("VID");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e V I D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteVIDImage writes an image to a file in VID X image format.
+%
+% The format of the WriteVIDImage method is:
+%
+% unsigned int WriteVIDImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteVIDImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteVIDImage(const ImageInfo *image_info,Image *image)
+{
+ Image
+ *montage_image;
+
+ MontageInfo
+ *montage_info;
+
+ register Image
+ *p;
+
+ unsigned int
+ status;
+
+ /*
+ Create the visual image directory.
+ */
+ for (p=image; p != (Image *) NULL; p=p->next)
+ (void) SetImageAttribute(p,"label",DefaultTileLabel);
+ montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
+ montage_image=MontageImages(image,montage_info,&image->exception);
+ DestroyMontageInfo(montage_info);
+ montage_info=(MontageInfo *) NULL;
+ if (montage_image == (Image *) NULL)
+ ThrowWriterException2(CorruptImageError,image->exception.reason,image);
+ FormatString(montage_image->filename,"miff:%.1024s",image->filename);
+ status=WriteImage(image_info,montage_image);
+ DestroyImageList(montage_image);
+ return(status);
+}
diff --git a/coders/viff.c b/coders/viff.c
new file mode 100644
index 0000000..086414d
--- /dev/null
+++ b/coders/viff.c
@@ -0,0 +1,1350 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% V V IIIII FFFFF FFFFF %
+% V V I F F %
+% V V I FFF FFF %
+% V V I F F %
+% V IIIII F F %
+% %
+% %
+% Read/Write Khoros Visualization Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteVIFFImage(const ImageInfo *,Image *);
+
+#define VFF_CM_genericRGB 15
+#define VFF_CM_ntscRGB 1
+#define VFF_CM_NONE 0
+#define VFF_DEP_DECORDER 0x4
+#define VFF_DEP_NSORDER 0x8
+#define VFF_DES_RAW 0
+#define VFF_LOC_IMPLICIT 1
+#define VFF_MAPTYP_NONE 0
+#define VFF_MAPTYP_1_BYTE 1
+#define VFF_MAPTYP_2_BYTE 2
+#define VFF_MAPTYP_4_BYTE 4
+#define VFF_MAPTYP_FLOAT 5
+#define VFF_MAPTYP_DOUBLE 7
+#define VFF_MS_NONE 0
+#define VFF_MS_ONEPERBAND 1
+#define VFF_MS_SHARED 3
+#define VFF_TYP_BIT 0
+#define VFF_TYP_1_BYTE 1
+#define VFF_TYP_2_BYTE 2
+#define VFF_TYP_4_BYTE 4
+#define VFF_TYP_FLOAT 5
+#define VFF_TYP_DOUBLE 9
+
+typedef struct _ViffInfo
+{
+ unsigned char
+ identifier,
+ file_type,
+ release,
+ version,
+ machine_dependency,
+ reserve[3];
+
+ char
+ comment[512];
+
+ magick_uint32_t
+ rows,
+ columns,
+ subrows;
+
+ magick_int32_t
+ x_offset,
+ y_offset;
+
+ float
+ x_pixel_size,
+ y_pixel_size;
+
+ magick_uint32_t
+ location_type,
+ location_dimension,
+ number_of_images,
+ number_data_bands,
+ data_storage_type,
+ data_encode_scheme,
+ map_scheme,
+ map_storage_type,
+ map_rows,
+ map_columns,
+ map_subrows,
+ map_enable,
+ maps_per_cycle,
+ color_space_model;
+} ViffInfo;
+
+static void LogVIFFInfo(const ViffInfo *viff_info)
+{
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "VIFFHeader:\n"
+ " FileId: 0x%02X\n"
+ " FileType: 0x%02X\n"
+ " Release: 0x%02X\n"
+ " Version: 0x%02X\n"
+ " MachineDep: 0x%02X\n"
+ " Comment: \"%.60s\"\n" /* 512 bytes */
+ " NumberOfRows: %u\n"
+ " NumberOfColumns: %u\n"
+ " LengthOfSubrow: %u\n"
+ " StartX: %d\n"
+ " StartY: %d\n"
+ " XPixelSize: %f (pixel width, meters)\n"
+ " YPixelSize: %f (pixel height, meters)\n"
+ " LocationType: 0x%04X\n"
+ " LocationDim: 0x%04X\n"
+ " NumberOfImages: %u\n"
+ " NumberOfBands: %u\n"
+ " DataStorageType: 0x%04X (%s)\n"
+ " DataEncodingScheme: 0x%04X (%s)\n"
+ " MapScheme: 0x%04X (%s)\n"
+ " MapStorageType: 0x%04X (%s)\n"
+ " MapRowSize: %u\n"
+ " MapColumnSize: %u\n"
+ " MapSubrowSize: %u\n"
+ " MapEnable: 0x%04X\n"
+ " MapsPerCycle: %u\n"
+ " ColorSpaceModel: 0x%04X",
+ viff_info->identifier,
+ viff_info->file_type,
+ viff_info->release,
+ viff_info->version,
+ viff_info->machine_dependency,
+ viff_info->comment,
+ viff_info->rows,
+ viff_info->columns,
+ viff_info->subrows,
+ viff_info->x_offset,
+ viff_info->y_offset,
+ viff_info->x_pixel_size,
+ viff_info->y_pixel_size,
+ viff_info->location_type,
+ viff_info->location_dimension,
+ viff_info->number_of_images,
+ viff_info->number_data_bands,
+ viff_info->data_storage_type,
+ viff_info->data_storage_type == 0x00 ? "Bit" :
+ viff_info->data_storage_type == 0x01 ? "BYTE" :
+ viff_info->data_storage_type == 0x02 ? "WORD" :
+ viff_info->data_storage_type == 0x04 ? "DWORD" :
+ viff_info->data_storage_type == 0x05 ? "Single-precision float" :
+ viff_info->data_storage_type == 0x06 ? "Complex float" :
+ viff_info->data_storage_type == 0x09 ? "Double-precision float" :
+ viff_info->data_storage_type == 0x0A ? "Complex double" :
+ "???",
+ viff_info->data_encode_scheme,
+ viff_info->data_encode_scheme == 0x00 ? "No compression" :
+ viff_info->data_encode_scheme == 0x01 ? "ALZ" :
+ viff_info->data_encode_scheme == 0x02 ? "RLE" :
+ viff_info->data_encode_scheme == 0x03 ? "Transform-based" :
+ viff_info->data_encode_scheme == 0x04 ? "CCITT" :
+ viff_info->data_encode_scheme == 0x05 ? "ADPCM" :
+ viff_info->data_encode_scheme == 0x06 ? "User-defined" :
+ "???",
+ viff_info->map_scheme,
+ viff_info->map_scheme == 0x01 ? "Bands use distinct map" :
+ viff_info->map_scheme == 0x02 ? "Cycle maps" :
+ viff_info->map_scheme == 0x03 ? "Share maps" :
+ viff_info->map_scheme == 0x04 ? "Bands grouped to one map" :
+ "???",
+ viff_info->map_storage_type,
+ viff_info->map_storage_type == 0x00 ? "No data type" :
+ viff_info->map_storage_type == 0x01 ? "Unsigned CHAR" :
+ viff_info->map_storage_type == 0x02 ? "Short INT" :
+ viff_info->map_storage_type == 0x04 ? "INT" :
+ viff_info->map_storage_type == 0x05 ? "Single-precision float" :
+ viff_info->map_storage_type == 0x06 ? "Complex float" :
+ viff_info->map_storage_type == 0x07 ? "Double-precision float" :
+ "???",
+ viff_info->map_rows,
+ viff_info->map_columns,
+ viff_info->map_subrows,
+ viff_info->map_enable,
+ viff_info->maps_per_cycle,
+ viff_info->color_space_model
+ );
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s V I F F %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsVIFF returns True if the image format type, identified by the
+% magick string, is VIFF.
+%
+% The format of the IsVIFF method is:
+%
+% unsigned int IsVIFF(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsVIFF returns True if the image format type is VIFF.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsVIFF(const unsigned char *magick,const size_t length)
+{
+ if (length < 2)
+ return(False);
+ if (memcmp(magick,"\253\001",2) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d V I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadVIFFImage reads a Khoros Visualization image file and returns
+% it. It allocates the memory necessary for the new Image structure and
+% returns a pointer to the new image.
+%
+% The format of the ReadVIFFImage method is:
+%
+% Image *ReadVIFFImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadVIFFImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadVIFFImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+
+ double
+ min_value,
+ scale_factor,
+ value;
+
+ Image
+ *image;
+
+ int
+ bit;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ unsigned int
+ index;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ size_t
+ count;
+
+ unsigned char
+ *viff_pixels;
+
+ unsigned int
+ status;
+
+ unsigned long
+ bytes_per_pixel,
+ lsb_first;
+
+ size_t
+ alloc_size,
+ blob_size,
+ max_packets,
+ number_pixels;
+
+ ViffInfo
+ viff_info;
+
+ magick_uint32_t (*ReadHeaderLong) (Image *image);
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read VIFF header (1024 bytes).
+ */
+ count=ReadBlob(image,1,(char *) &viff_info.identifier);
+ do
+ {
+ /*
+ Verify VIFF identifier.
+ */
+ if ((count != 1) || ((unsigned char) viff_info.identifier != 0xabU))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Initialize VIFF image.
+ */
+ if (ReadBlob(image,sizeof(viff_info.file_type),&viff_info.file_type)
+ != sizeof(viff_info.file_type))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (ReadBlob(image,sizeof(viff_info.release),&viff_info.release)
+ != sizeof(viff_info.release))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (ReadBlob(image,sizeof(viff_info.version),&viff_info.version)
+ != sizeof(viff_info.version))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (ReadBlob(image,sizeof(viff_info.machine_dependency),
+ &viff_info.machine_dependency)
+ != sizeof(viff_info.machine_dependency))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (ReadBlob(image,sizeof(viff_info.reserve),&viff_info.reserve)
+ != sizeof(viff_info.reserve))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ if (ReadBlob(image,512,(char *) viff_info.comment) != 512)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ viff_info.comment[511]='\0';
+ if (strlen(viff_info.comment) > 4)
+ (void) SetImageAttribute(image,"comment",viff_info.comment);
+ if ((viff_info.machine_dependency == VFF_DEP_DECORDER) ||
+ (viff_info.machine_dependency == VFF_DEP_NSORDER))
+ ReadHeaderLong=ReadBlobLSBLong;
+ else
+ ReadHeaderLong=ReadBlobMSBLong;
+ viff_info.rows=(ReadHeaderLong)(image);
+ viff_info.columns=(ReadHeaderLong)(image);
+ viff_info.subrows=(ReadHeaderLong)(image);
+ viff_info.x_offset=(int) (ReadHeaderLong)(image);
+ viff_info.y_offset=(int) (ReadHeaderLong)(image);
+ viff_info.x_pixel_size=(float) (ReadHeaderLong)(image);
+ viff_info.y_pixel_size=(float) (ReadHeaderLong)(image);
+ viff_info.location_type=(ReadHeaderLong)(image);
+ viff_info.location_dimension=(ReadHeaderLong)(image);
+ viff_info.number_of_images=(ReadHeaderLong)(image);
+ viff_info.number_data_bands=(ReadHeaderLong)(image);
+ viff_info.data_storage_type=(ReadHeaderLong)(image);
+ viff_info.data_encode_scheme=(ReadHeaderLong)(image);
+ viff_info.map_scheme=(ReadHeaderLong)(image);
+ viff_info.map_storage_type=(ReadHeaderLong)(image);
+ viff_info.map_rows=(ReadHeaderLong)(image);
+ viff_info.map_columns=(ReadHeaderLong)(image);
+ viff_info.map_subrows=(ReadHeaderLong)(image);
+ viff_info.map_enable=(ReadHeaderLong)(image);
+ viff_info.maps_per_cycle=(ReadHeaderLong)(image);
+ viff_info.color_space_model=(ReadHeaderLong)(image);
+ for (i=0; i < 420; i++)
+ (void) ReadBlobByte(image);
+ if (EOFBlob(image))
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ LogVIFFInfo(&viff_info);
+ image->columns=viff_info.rows;
+ image->rows=viff_info.columns;
+ image->depth=viff_info.x_pixel_size <= 8 ? 8 : QuantumDepth;
+ /*
+ Verify that we can read this VIFF image.
+ */
+ number_pixels=MagickArraySize(viff_info.columns,viff_info.rows);
+ if (number_pixels == 0)
+ ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,
+ image);
+ if (viff_info.number_data_bands < 1 || viff_info.number_data_bands > 4)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if ((viff_info.data_storage_type != VFF_TYP_BIT) &&
+ (viff_info.data_storage_type != VFF_TYP_1_BYTE) &&
+ (viff_info.data_storage_type != VFF_TYP_2_BYTE) &&
+ (viff_info.data_storage_type != VFF_TYP_4_BYTE) &&
+ (viff_info.data_storage_type != VFF_TYP_FLOAT) &&
+ (viff_info.data_storage_type != VFF_TYP_DOUBLE))
+ ThrowReaderException(CoderError,DataStorageTypeIsNotSupported,image);
+ if (viff_info.data_encode_scheme != VFF_DES_RAW)
+ ThrowReaderException(CoderError,DataEncodingSchemeIsNotSupported,image);
+ if ((viff_info.map_storage_type != VFF_MAPTYP_NONE) &&
+ (viff_info.map_storage_type != VFF_MAPTYP_1_BYTE) &&
+ (viff_info.map_storage_type != VFF_MAPTYP_2_BYTE) &&
+ (viff_info.map_storage_type != VFF_MAPTYP_4_BYTE) &&
+ (viff_info.map_storage_type != VFF_MAPTYP_FLOAT) &&
+ (viff_info.map_storage_type != VFF_MAPTYP_DOUBLE))
+ ThrowReaderException(CoderError,MapStorageTypeIsNotSupported,image);
+ if ((viff_info.color_space_model != VFF_CM_NONE) &&
+ (viff_info.color_space_model != VFF_CM_ntscRGB) &&
+ (viff_info.color_space_model != VFF_CM_genericRGB))
+ ThrowReaderException(CoderError,ColorspaceModelIsNotSupported,image);
+ if (viff_info.location_type != VFF_LOC_IMPLICIT)
+ ThrowReaderException(CoderError,LocationTypeIsNotSupported,image);
+ if (viff_info.number_of_images != 1)
+ ThrowReaderException(CoderError,NumberOfImagesIsNotSupported,image);
+ if (viff_info.map_rows == 0)
+ viff_info.map_scheme=VFF_MS_NONE;
+ switch ((int) viff_info.map_scheme)
+ {
+ case VFF_MS_NONE:
+ {
+ if (viff_info.number_data_bands < 3)
+ {
+ /*
+ Create linear color ramp.
+ */
+ image->colors=image->depth <= 8 ? 256 : 65536L;
+ if (viff_info.data_storage_type == VFF_TYP_BIT)
+ image->colors=2;
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ break;
+ }
+ case VFF_MS_ONEPERBAND:
+ case VFF_MS_SHARED:
+ {
+ unsigned char
+ *viff_colormap;
+
+ size_t
+ viff_colormap_size;
+
+ /*
+ Allocate VIFF colormap.
+ */
+ switch ((int) viff_info.map_storage_type)
+ {
+ case VFF_MAPTYP_1_BYTE: bytes_per_pixel=1; break;
+ case VFF_MAPTYP_2_BYTE: bytes_per_pixel=2; break;
+ case VFF_MAPTYP_4_BYTE: bytes_per_pixel=4; break;
+ case VFF_MAPTYP_FLOAT: bytes_per_pixel=4; break;
+ case VFF_MAPTYP_DOUBLE: bytes_per_pixel=8; break;
+ default: bytes_per_pixel=1; break;
+ }
+ image->colors=viff_info.map_columns;
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+
+ viff_colormap_size=MagickArraySize(MagickArraySize(bytes_per_pixel,
+ image->colors),
+ viff_info.map_rows);
+ viff_colormap=MagickAllocateMemory(unsigned char *,viff_colormap_size);
+ if (viff_colormap == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ /*
+ Read VIFF raster colormap.
+ */
+ if (ReadBlob(image,viff_colormap_size,(char *) viff_colormap)
+ != viff_colormap_size)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ lsb_first=1;
+ if (*(char *) &lsb_first &&
+ ((viff_info.machine_dependency != VFF_DEP_DECORDER) &&
+ (viff_info.machine_dependency != VFF_DEP_NSORDER)))
+ switch ((int) viff_info.map_storage_type)
+ {
+ case VFF_MAPTYP_2_BYTE:
+ {
+ MSBOrderShort(viff_colormap,(bytes_per_pixel*image->colors*
+ viff_info.map_rows));
+ break;
+ }
+ case VFF_MAPTYP_4_BYTE:
+ case VFF_MAPTYP_FLOAT:
+ {
+ MSBOrderLong(viff_colormap,(bytes_per_pixel*image->colors*
+ viff_info.map_rows));
+ break;
+ }
+ default: break;
+ }
+ for (i=0; i < (long) (viff_info.map_rows*image->colors); i++)
+ {
+ switch ((int) viff_info.map_storage_type)
+ {
+ case VFF_MAPTYP_2_BYTE: value=((short *) viff_colormap)[i]; break;
+ case VFF_MAPTYP_4_BYTE: value=((int *) viff_colormap)[i]; break;
+ case VFF_MAPTYP_FLOAT: value=((float *) viff_colormap)[i]; break;
+ case VFF_MAPTYP_DOUBLE: value=((double *) viff_colormap)[i]; break;
+ default: value=viff_colormap[i]; break;
+ }
+ if (i < (long) image->colors)
+ {
+ image->colormap[i].red=ScaleCharToQuantum((unsigned int) value);
+ image->colormap[i].green=ScaleCharToQuantum((unsigned int) value);
+ image->colormap[i].blue=ScaleCharToQuantum((unsigned int) value);
+ }
+ else
+ if (i < (long) (2*image->colors))
+ image->colormap[i % image->colors].green=
+ ScaleCharToQuantum((unsigned int) value);
+ else
+ if (i < (long) (3*image->colors))
+ image->colormap[i % image->colors].blue=
+ ScaleCharToQuantum((unsigned int) value);
+ }
+ MagickFreeMemory(viff_colormap);
+ break;
+ }
+ default:
+ ThrowReaderException(CoderError,ColormapTypeNotSupported,image)
+ }
+ /*
+ Initialize image structure.
+ */
+ image->matte=(viff_info.number_data_bands == 4);
+ image->storage_class=
+ (viff_info.number_data_bands < 3 ? PseudoClass : DirectClass);
+ image->columns=viff_info.rows;
+ image->rows=viff_info.columns;
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ /*
+ Allocate VIFF pixels.
+ */
+ switch ((int) viff_info.data_storage_type)
+ {
+ case VFF_TYP_2_BYTE: bytes_per_pixel=2; break;
+ case VFF_TYP_4_BYTE: bytes_per_pixel=4; break;
+ case VFF_TYP_FLOAT: bytes_per_pixel=4; break;
+ case VFF_TYP_DOUBLE: bytes_per_pixel=8; break;
+ default: bytes_per_pixel=1; break;
+ }
+ if (viff_info.data_storage_type == VFF_TYP_BIT)
+ {
+ max_packets=MagickArraySize(((image->columns+7) >> 3),image->rows);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Alloc Bytes: %" MAGICK_SIZE_T_F "u, "
+ "Max Packets: %" MAGICK_SIZE_T_F "u, "
+ "Columns: %" MAGICK_SIZE_T_F "u ,"
+ "Rows: %" MAGICK_SIZE_T_F "u",
+ (MAGICK_SIZE_T) MagickArraySize(((image->columns+7) >> 3),
+ image->rows),
+ (MAGICK_SIZE_T) max_packets,
+ (MAGICK_SIZE_T) image->columns,
+ (MAGICK_SIZE_T) image->rows);
+ }
+ else
+ {
+ max_packets=MagickArraySize(number_pixels,viff_info.number_data_bands);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Alloc Bytes: %" MAGICK_SIZE_T_F "u, "
+ "Max Packets: %" MAGICK_SIZE_T_F "u, "
+ "Number Pixels: %" MAGICK_SIZE_T_F "u, "
+ "Columns: %" MAGICK_SIZE_T_F "u, "
+ "Rows: %" MAGICK_SIZE_T_F "u, "
+ "Number Data Bands: %" MAGICK_SIZE_T_F "u",
+ (MAGICK_SIZE_T) MagickArraySize(number_pixels,
+ viff_info.number_data_bands),
+ (MAGICK_SIZE_T) max_packets,
+ (MAGICK_SIZE_T) number_pixels,
+ (MAGICK_SIZE_T) image->columns,
+ (MAGICK_SIZE_T) image->rows,
+ (MAGICK_SIZE_T) viff_info.number_data_bands);
+ }
+ alloc_size=MagickArraySize(bytes_per_pixel,max_packets);
+ blob_size=GetBlobSize(image);
+ if ((blob_size != 0) && (alloc_size > blob_size))
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ viff_pixels=MagickAllocateArray(unsigned char *,
+ MagickArraySize(bytes_per_pixel,
+ max_packets),
+ sizeof(Quantum));
+ if (viff_pixels == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) ReadBlob(image,bytes_per_pixel*max_packets,(char *) viff_pixels);
+ lsb_first=1;
+ if (*(char *) &lsb_first &&
+ ((viff_info.machine_dependency != VFF_DEP_DECORDER) &&
+ (viff_info.machine_dependency != VFF_DEP_NSORDER)))
+ switch ((int) viff_info.data_storage_type)
+ {
+ case VFF_TYP_2_BYTE:
+ {
+ MSBOrderShort(viff_pixels,bytes_per_pixel*max_packets);
+ break;
+ }
+ case VFF_TYP_4_BYTE:
+ case VFF_TYP_FLOAT:
+ {
+ MSBOrderLong(viff_pixels,bytes_per_pixel*max_packets);
+ break;
+ }
+ default: break;
+ }
+ min_value=0.0;
+ scale_factor=1.0;
+ if ((viff_info.data_storage_type != VFF_TYP_1_BYTE) &&
+ (viff_info.map_scheme == VFF_MS_NONE))
+ {
+ double
+ max_value;
+
+ /*
+ Determine scale factor.
+ */
+ switch ((int) viff_info.data_storage_type)
+ {
+ case VFF_TYP_2_BYTE: value=((short *) viff_pixels)[0]; break;
+ case VFF_TYP_4_BYTE: value=((int *) viff_pixels)[0]; break;
+ case VFF_TYP_FLOAT: value=((float *) viff_pixels)[0]; break;
+ case VFF_TYP_DOUBLE: value=((double *) viff_pixels)[0]; break;
+ default: value=viff_pixels[0]; break;
+ }
+ max_value=value;
+ min_value=value;
+ for (i=0; i < (long) max_packets; i++)
+ {
+ switch ((int) viff_info.data_storage_type)
+ {
+ case VFF_TYP_2_BYTE: value=((short *) viff_pixels)[i]; break;
+ case VFF_TYP_4_BYTE: value=((int *) viff_pixels)[i]; break;
+ case VFF_TYP_FLOAT: value=((float *) viff_pixels)[i]; break;
+ case VFF_TYP_DOUBLE: value=((double *) viff_pixels)[i]; break;
+ default: value=viff_pixels[i]; break;
+ }
+ if (value > max_value)
+ max_value=value;
+ else
+ if (value < min_value)
+ min_value=value;
+ }
+ if ((min_value == 0) && (max_value == 0))
+ scale_factor=0;
+ else
+ if (min_value == max_value)
+ {
+ scale_factor=MaxRGB/min_value;
+ min_value=0;
+ }
+ else
+ scale_factor=MaxRGB/(max_value-min_value);
+ }
+ /*
+ Convert pixels to Quantum size.
+ */
+ p=(unsigned char *) viff_pixels;
+ for (i=0; i < (long) max_packets; i++)
+ {
+ switch ((int) viff_info.data_storage_type)
+ {
+ case VFF_TYP_2_BYTE: value=((short *) viff_pixels)[i]; break;
+ case VFF_TYP_4_BYTE: value=((int *) viff_pixels)[i]; break;
+ case VFF_TYP_FLOAT: value=((float *) viff_pixels)[i]; break;
+ case VFF_TYP_DOUBLE: value=((double *) viff_pixels)[i]; break;
+ default: value=viff_pixels[i]; break;
+ }
+ if (viff_info.map_scheme == VFF_MS_NONE)
+ {
+ value=(value-min_value)*scale_factor;
+ if (value > MaxRGB)
+ value=MaxRGB;
+ else
+ if (value < 0)
+ value=0;
+ }
+ *p=(Quantum) value;
+ p++;
+ }
+ /*
+ Convert VIFF raster image to pixel packets.
+ */
+ p=(unsigned char *) viff_pixels;
+ if (viff_info.data_storage_type == VFF_TYP_BIT)
+ {
+ unsigned int
+ polarity;
+
+ /*
+ Convert bitmap scanline.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors >= 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) >
+ PixelIntensityToQuantum(&image->colormap[1]);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) (image->columns-7); x+=8)
+ {
+ for (bit=0; bit < 8; bit++)
+ {
+ index=((*p) & (0x01 << bit) ? !polarity : polarity);
+ VerifyColormapIndex(image,index);
+ indexes[x+bit]=(IndexPacket) index;
+ }
+ p++;
+ }
+ if ((image->columns % 8) != 0)
+ {
+ for (bit=0; bit < (long) (image->columns % 8); bit++)
+ {
+ index=((*p) & (0x01 << bit) ? !polarity : polarity);
+ VerifyColormapIndex(image,index);
+ indexes[x+bit]=(IndexPacket) index;
+ }
+ p++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ if (image->storage_class == PseudoClass)
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=(*p++);
+ VerifyColormapIndex(image,index);
+ indexes[x]=index;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ else
+ {
+ /*
+ Convert DirectColor scanline.
+ */
+ number_pixels=image->columns*image->rows;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(*p);
+ q->green=ScaleCharToQuantum(*(p+number_pixels));
+ q->blue=ScaleCharToQuantum(*(p+2*number_pixels));
+ if (image->colors != 0)
+ {
+ index=q->red;
+ VerifyColormapIndex(image,index);
+ q->red=image->colormap[index].red;
+ index=q->green;
+ VerifyColormapIndex(image,index);
+ q->green=image->colormap[index].green;
+ index=q->blue;
+ VerifyColormapIndex(image,index);
+ q->blue=image->colormap[index].blue;
+ }
+ q->opacity=(Quantum) (image->matte ? MaxRGB-
+ ScaleCharToQuantum(*(p+number_pixels*3)) : OpaqueOpacity);
+ p++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ MagickFreeMemory(viff_pixels);
+ if (image->storage_class == PseudoClass)
+ (void) SyncImage(image);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ count=ReadBlob(image,1,(char *) &viff_info.identifier);
+ if ((count != 0) && (viff_info.identifier == 0xab))
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ } while ((count != 0) && (viff_info.identifier == 0xab));
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r V I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterVIFFImage adds attributes for the VIFF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterVIFFImage method is:
+%
+% RegisterVIFFImage(void)
+%
+*/
+ModuleExport void RegisterVIFFImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("VIFF");
+ entry->decoder=(DecoderHandler) ReadVIFFImage;
+ entry->encoder=(EncoderHandler) WriteVIFFImage;
+ entry->magick=(MagickHandler) IsVIFF;
+ entry->description="Khoros Visualization image";
+ entry->module="VIFF";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("XV");
+ entry->decoder=(DecoderHandler) ReadVIFFImage;
+ entry->encoder=(EncoderHandler) WriteVIFFImage;
+ entry->description="Khoros Visualization image";
+ entry->module="VIFF";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r V I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterVIFFImage removes format registrations made by the
+% VIFF module from the list of supported formats.
+%
+% The format of the UnregisterVIFFImage method is:
+%
+% UnregisterVIFFImage(void)
+%
+*/
+ModuleExport void UnregisterVIFFImage(void)
+{
+ (void) UnregisterMagickInfo("VIFF");
+ (void) UnregisterMagickInfo("XV");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e V I F F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteVIFFImage writes an image to a file in the VIFF image format.
+%
+% The format of the WriteVIFFImage method is:
+%
+% unsigned int WriteVIFFImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteVIFFImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+#define VFF_CM_genericRGB 15
+#define VFF_CM_NONE 0
+#define VFF_DEP_IEEEORDER 0x2
+#define VFF_DES_RAW 0
+#define VFF_LOC_IMPLICIT 1
+#define VFF_MAPTYP_NONE 0
+#define VFF_MAPTYP_1_BYTE 1
+#define VFF_MS_NONE 0
+#define VFF_MS_ONEPERBAND 1
+#define VFF_TYP_BIT 0
+#define VFF_TYP_1_BYTE 1
+static unsigned int WriteVIFFImage(const ImageInfo *image_info,Image *image)
+{
+ const ImageAttribute
+ *attribute;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register long
+ i;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *viff_pixels;
+
+ unsigned int
+ status;
+
+ unsigned long
+ number_pixels,
+ scene;
+
+ size_t
+ packets;
+
+ ViffInfo
+ viff_info;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) memset(&viff_info,0,sizeof(ViffInfo));
+ scene=0;
+ do
+ {
+ ImageCharacteristics
+ characteristics;
+
+ /*
+ Ensure that image is in an RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Analyze image to be written.
+ */
+ (void) GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception);
+ /*
+ Initialize VIFF image structure.
+ */
+ viff_info.identifier=(char) 0xab;
+ viff_info.file_type=1;
+ viff_info.release=1;
+ viff_info.version=3;
+ viff_info.machine_dependency=VFF_DEP_IEEEORDER; /* IEEE byte ordering */
+ *viff_info.comment='\0';
+ attribute=GetImageAttribute(image,"comment");
+ if (attribute != (const ImageAttribute *) NULL)
+ (void) strlcpy(viff_info.comment,attribute->value,
+ sizeof(viff_info.comment));
+ viff_info.rows=image->columns;
+ viff_info.columns=image->rows;
+ viff_info.subrows=0;
+ viff_info.x_offset=(~0);
+ viff_info.y_offset=(~0);
+ viff_info.x_pixel_size=0;
+ viff_info.y_pixel_size=0;
+ viff_info.location_type=VFF_LOC_IMPLICIT;
+ viff_info.location_dimension=0;
+ viff_info.number_of_images=1;
+ viff_info.data_encode_scheme=VFF_DES_RAW;
+ viff_info.map_scheme=VFF_MS_NONE;
+ viff_info.map_storage_type=VFF_MAPTYP_NONE;
+ viff_info.map_rows=0;
+ viff_info.map_columns=0;
+ viff_info.map_subrows=0;
+ viff_info.map_enable=1; /* no colormap */
+ viff_info.maps_per_cycle=0;
+ number_pixels=image->columns*image->rows;
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Full color VIFF raster.
+ */
+ viff_info.number_data_bands=image->matte ? 4 : 3;
+ viff_info.color_space_model=VFF_CM_genericRGB;
+ viff_info.data_storage_type=VFF_TYP_1_BYTE;
+ packets=MagickArraySize(viff_info.number_data_bands,
+ number_pixels);
+ }
+ else
+ {
+ viff_info.number_data_bands=1;
+ viff_info.color_space_model=VFF_CM_NONE;
+ viff_info.data_storage_type=VFF_TYP_1_BYTE;
+ packets=number_pixels;
+ if (!characteristics.grayscale)
+ {
+ /*
+ Colormapped VIFF raster.
+ */
+ viff_info.map_scheme=VFF_MS_ONEPERBAND;
+ viff_info.map_storage_type=VFF_MAPTYP_1_BYTE;
+ viff_info.map_rows=3;
+ viff_info.map_columns=image->colors;
+ }
+ else
+ if (image->colors <= 2)
+ {
+ /*
+ Monochrome VIFF raster.
+ */
+ viff_info.data_storage_type=VFF_TYP_BIT;
+ packets=MagickArraySize(((image->columns+7) >> 3),
+ image->rows);
+ }
+ }
+ /*
+ Write VIFF image header (pad to 1024 bytes).
+ */
+ {
+ /* FIXME: this makes no sense to me but preserve original values
+ until we figure out why this was done. */
+ union
+ {
+ float f;
+ magick_uint32_t u;
+ } v;
+ v.u = (63 << 24) | (128 << 16);
+ viff_info.x_pixel_size=viff_info.y_pixel_size=v.f;
+ /* viff_info.x_pixel_size=(63 << 24) | (128 << 16); */
+ /* viff_info.y_pixel_size=(63 << 24) | (128 << 16); */
+ }
+ LogVIFFInfo(&viff_info);
+ (void) WriteBlob(image,sizeof(viff_info.identifier),&viff_info.identifier);
+ (void) WriteBlob(image,sizeof(viff_info.file_type),&viff_info.file_type);
+ (void) WriteBlob(image,sizeof(viff_info.release),&viff_info.release);
+ (void) WriteBlob(image,sizeof(viff_info.version),&viff_info.version);
+ (void) WriteBlob(image,sizeof(viff_info.machine_dependency),
+ &viff_info.machine_dependency);
+ (void) WriteBlob(image,sizeof(viff_info.reserve),&viff_info.reserve);
+ (void) WriteBlob(image,512,(char *) viff_info.comment);
+ (void) WriteBlobMSBLong(image,viff_info.rows);
+ (void) WriteBlobMSBLong(image,viff_info.columns);
+ (void) WriteBlobMSBLong(image,viff_info.subrows);
+ (void) WriteBlobMSBLong(image,(magick_uint32_t) viff_info.x_offset);
+ (void) WriteBlobMSBLong(image,(magick_uint32_t) viff_info.y_offset);
+ (void) WriteBlobMSBLong(image,(magick_uint32_t) viff_info.x_pixel_size);
+ (void) WriteBlobMSBLong(image,(magick_uint32_t) viff_info.y_pixel_size);
+ (void) WriteBlobMSBLong(image,viff_info.location_type);
+ (void) WriteBlobMSBLong(image,viff_info.location_dimension);
+ (void) WriteBlobMSBLong(image,viff_info.number_of_images);
+ (void) WriteBlobMSBLong(image,viff_info.number_data_bands);
+ (void) WriteBlobMSBLong(image,viff_info.data_storage_type);
+ (void) WriteBlobMSBLong(image,viff_info.data_encode_scheme);
+ (void) WriteBlobMSBLong(image,viff_info.map_scheme);
+ (void) WriteBlobMSBLong(image,viff_info.map_storage_type);
+ (void) WriteBlobMSBLong(image,viff_info.map_rows);
+ (void) WriteBlobMSBLong(image,viff_info.map_columns);
+ (void) WriteBlobMSBLong(image,viff_info.map_subrows);
+ (void) WriteBlobMSBLong(image,viff_info.map_enable);
+ (void) WriteBlobMSBLong(image,viff_info.maps_per_cycle);
+ (void) WriteBlobMSBLong(image,viff_info.color_space_model);
+ for (i=0; i < 420; i++)
+ (void) WriteBlobByte(image,'\0');
+ /*
+ Convert MIFF to VIFF raster pixels.
+ */
+ viff_pixels=MagickAllocateMemory(unsigned char *,packets);
+ if (viff_pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ q=viff_pixels;
+ if (image->storage_class == DirectClass)
+ {
+ /*
+ Convert DirectClass packet to VIFF RGB pixel.
+ */
+ number_pixels=image->columns*image->rows;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q=ScaleQuantumToChar(p->red);
+ *(q+number_pixels)=ScaleQuantumToChar(p->green);
+ *(q+number_pixels*2)=ScaleQuantumToChar(p->blue);
+ if (image->matte)
+ *(q+number_pixels*3)=ScaleQuantumToChar(MaxRGB-p->opacity);
+ p++;
+ q++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ if (!characteristics.grayscale)
+ {
+ unsigned char
+ *viff_colormap;
+
+ /*
+ Dump colormap to file.
+ */
+ viff_colormap=MagickAllocateMemory(unsigned char *,
+ MagickArraySize(3,image->colors));
+ if (viff_colormap == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ q=viff_colormap;
+ for (i=0; i < (long) image->colors; i++)
+ *q++=ScaleQuantumToChar(image->colormap[i].red);
+ for (i=0; i < (long) image->colors; i++)
+ *q++=ScaleQuantumToChar(image->colormap[i].green);
+ for (i=0; i < (long) image->colors; i++)
+ *q++=ScaleQuantumToChar(image->colormap[i].blue);
+ (void) WriteBlob(image,3*image->colors,(char *) viff_colormap);
+ MagickFreeMemory(viff_colormap);
+ /*
+ Convert PseudoClass packet to VIFF colormapped pixels.
+ */
+ q=viff_pixels;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ *q++=indexes[x];
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ if (image->colors <= 2)
+ {
+ long
+ x,
+ y;
+
+ register unsigned char
+ bit,
+ byte,
+ polarity;
+
+ /*
+ Convert PseudoClass image to a VIFF monochrome image.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte>>=1;
+ if (indexes[x] == polarity)
+ byte|=0x80;
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ *q++=byte >> (8-bit);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ {
+ /*
+ Convert PseudoClass packet to VIFF grayscale pixel.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q++=(unsigned char) PixelIntensityToQuantum(p);
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ (void) WriteBlob(image,packets,(char *) viff_pixels);
+ MagickFreeMemory(viff_pixels);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/wbmp.c b/coders/wbmp.c
new file mode 100644
index 0000000..e6d616d
--- /dev/null
+++ b/coders/wbmp.c
@@ -0,0 +1,412 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W W BBBB M M PPPP %
+% W W B B MM MM P P %
+% W W W BBBB M M M PPPP %
+% WW WW B B M M P %
+% W W BBBB M M P %
+% %
+% %
+% Read/Write Wireless Bitmap (level 0) Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% January 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteWBMPImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d W B M P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadWBMPImage reads a WBMP (level 0) image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% ReadWBMPImage was contributed by Milan Votava <votava@mageo.cz>.
+%
+% The format of the ReadWBMPImage method is:
+%
+% Image *ReadWBMPImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadWBMPImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static unsigned int WBMPReadInteger(Image *image,unsigned long *value)
+{
+ int
+ byte;
+
+ *value=0;
+ do
+ {
+ byte=ReadBlobByte(image);
+ if (byte == EOF)
+ return(False);
+ *value<<=7;
+ *value|=(unsigned int) (byte & 0x7f);
+ } while (byte & 0x80);
+ return(True);
+}
+
+static Image *ReadWBMPImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ int
+ byte;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ unsigned char
+ bit;
+
+ unsigned int
+ status;
+
+ unsigned short
+ header;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ if (!ReadBlob(image,2,(char *) &header))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (header != 0U)
+ ThrowReaderException(CoderError,OnlyLevelZerofilesSupported,image);
+ /*
+ Initialize image structure.
+ */
+ if (WBMPReadInteger(image,&image->columns) == False)
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ if (WBMPReadInteger(image,&image->rows) == False)
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ for (i=0; i < image->offset; i++)
+ {
+ if (EOF == ReadBlobByte(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ }
+ if (!AllocateImageColormap(image,2))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+ /*
+ Convert bi-level image to pixel packets.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (bit == 0)
+ {
+ byte=ReadBlobByte(image);
+ if (byte == EOF)
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+ indexes[x]=(byte & (0x01 << (7-bit))) ? 1 : 0;
+ bit++;
+ if (bit == 8)
+ bit=0;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) SyncImage(image);
+ if (EOFBlob(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r W B M P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterWBMPImage adds attributes for the WBMP image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterWBMPImage method is:
+%
+% RegisterWBMPImage(void)
+%
+*/
+ModuleExport void RegisterWBMPImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("WBMP");
+ entry->decoder=(DecoderHandler) ReadWBMPImage;
+ entry->encoder=(EncoderHandler) WriteWBMPImage;
+ entry->adjoin=False;
+ entry->description="Wireless Bitmap (level 0) image";
+ entry->module="WBMP";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r W B M P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterWBMPImage removes format registrations made by the
+% WBMP module from the list of supported formats.
+%
+% The format of the UnregisterWBMPImage method is:
+%
+% UnregisterWBMPImage(void)
+%
+*/
+ModuleExport void UnregisterWBMPImage(void)
+{
+ (void) UnregisterMagickInfo("WBMP");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e W B M P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteWBMPImage writes an image to a file in the Wireless Bitmap
+% (level 0) image format.
+%
+% WriteWBMPImage was contributed by Milan Votava <votava@mageo.cz>.
+%
+% The format of the WriteWBMPImage method is:
+%
+% unsigned int WriteWBMPImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteWBMPImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+static void WBMPWriteInteger(Image *image,const unsigned long value)
+{
+ int
+ bits,
+ flag,
+ n;
+
+ register long
+ i;
+
+ unsigned char
+ buffer[5],
+ octet;
+
+ n=1;
+ bits=28;
+ flag=False;
+ for(i=4; i >= 0; i--)
+ {
+ octet=(unsigned char) ((value >> bits) & 0x7f);
+ if (!flag && octet)
+ {
+ flag=True;
+ n=i+1;
+ }
+ buffer[4-i]=octet | (i && (flag || octet))*(0x01 << 7);
+ bits-=7;
+ }
+ (void) WriteBlob(image,n,(char *) buffer+5-n);
+}
+
+static unsigned int WriteWBMPImage(const ImageInfo *image_info,Image *image)
+{
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ unsigned char
+ bit,
+ byte,
+ polarity;
+
+ unsigned int
+ status;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Convert image to a bi-level image.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]);
+ (void) WriteBlobMSBShort(image,0);
+ WBMPWriteInteger(image,image->columns);
+ WBMPWriteInteger(image,image->rows);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (indexes[x] == polarity)
+ byte|=0x1 << (7-bit);
+ bit++;
+ if (bit == 8)
+ {
+ (void) WriteBlobByte(image,byte);
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ (void) WriteBlobByte(image,byte);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/webp.c b/coders/webp.c
new file mode 100644
index 0000000..284a714
--- /dev/null
+++ b/coders/webp.c
@@ -0,0 +1,715 @@
+/*
+% Copyright (C) 2013 - 2014 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W W EEEEE BBBB PPPP %
+% W W E B B P P %
+% W W W EEE BBBB PPPP %
+% WW WW E B B P %
+% W W EEEEE BBBB P %
+% %
+% %
+% Read/Write Google WEBP Image Format. %
+% %
+% %
+% Software Design %
+% TIMEBUG %
+% January 2013 %
+% %
+% Subsequent Development By %
+% Bob Friesenhahn %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/constitute.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+#if defined(HasWEBP)
+static unsigned int WriteWEBPImage(const ImageInfo *,Image *);
+#else
+ #define WebPGetEncoderVersion() (0)
+ #define WEBP_ENCODER_ABI_VERSION 0
+#endif
+
+#if defined(HasWEBP)
+#include <webp/decode.h>
+#include <webp/encode.h>
+
+/*
+ Release versions vs ABI versions (found in src/webp/encode.h)
+
+ 0.1.3 - 0x0002
+ 0.1.99 - 0x0100
+ 0.2.0 - 0x0200
+ 0.2.1 - 0x0200
+ 0.3.0 - 0x0201
+ 0.4.0 - 0x0202
+ 0.4.1 - 0x0202
+ 0.4.2 - 0x0202
+*/
+
+/*
+ Progress indication support not added until v0.1.99
+*/
+#if WEBP_ENCODER_ABI_VERSION >= 0x0100 /* >= v0.1.99 */
+# define SUPPORT_PROGRESS 1
+# define SUPPORT_USER_ABORT
+#endif
+#if WEBP_ENCODER_ABI_VERSION >= 0x0200 /* >= 0.2.0 */
+# define SUPPORT_CONFIG_WEBP_HINT_GRAPH
+#endif
+/* These relate to 'struct WebPConfig' parameters */
+#if WEBP_ENCODER_ABI_VERSION >= 0x0201 /* >= 0.3.0 */
+# define SUPPORT_CONFIG_EMULATE_JPEG_SIZE
+# define SUPPORT_CONFIG_THREAD_LEVEL
+# define SUPPORT_CONFIG_LOW_MEMORY
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d W E B P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadWEBPImage() reads an image in the WebP image format.
+%
+% The format of the ReadWEBPImage method is:
+%
+% Image *ReadWEBPImage(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: the image info.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+static Image *ReadWEBPImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ unsigned long
+ count,
+ y;
+
+ register PixelPacket
+ *q;
+
+ size_t
+ length;
+
+ register size_t
+ x;
+
+ register unsigned char
+ *p;
+
+ unsigned char
+ *stream,
+ *pixels;
+
+ WebPBitstreamFeatures
+ stream_features;
+
+ int
+ webp_status;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if (OpenBlob(image_info,image,ReadBinaryBlobMode,exception) == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read WEBP file.
+ */
+ length = (size_t) GetBlobSize(image); /* FIXME, does not work with stream */
+ stream=MagickAllocateArray(unsigned char *,
+ length,sizeof(*stream));
+ if (stream == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ count=(long) ReadBlob(image,length,(char *) stream);
+ if (count != (size_t) length)
+ {
+ MagickFreeMemory(stream);
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ }
+ if ((webp_status=WebPGetFeatures(stream,length,&stream_features)) != VP8_STATUS_OK)
+ {
+ MagickFreeMemory(stream);
+
+ switch (webp_status)
+ {
+#if !defined(__COVERITY__)
+ case VP8_STATUS_OK:
+ break;
+#else
+ default:
+ break;
+#endif
+ case VP8_STATUS_OUT_OF_MEMORY:
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ break;
+ case VP8_STATUS_INVALID_PARAM:
+ ThrowReaderException(CoderError,WebPInvalidParameter,image);
+ break;
+ case VP8_STATUS_BITSTREAM_ERROR:
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ break;
+ case VP8_STATUS_UNSUPPORTED_FEATURE:
+ ThrowReaderException(CoderError,DataEncodingSchemeIsNotSupported,image);
+ break;
+ case VP8_STATUS_SUSPENDED:
+ /*
+ Incremental decoder object may be left in SUSPENDED state
+ if the picture is only partially decoded, pending
+ additional input. We are not doing incremental decoding
+ at this time.
+ */
+ break;
+ case VP8_STATUS_USER_ABORT:
+ /*
+ This is what is returned if the user terminates the
+ decoding.
+ */
+ ThrowReaderException(CoderError,WebPDecodingFailedUserAbort,image);
+ break;
+ case VP8_STATUS_NOT_ENOUGH_DATA:
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ break;
+ }
+ /*
+ Catch-all if not handled above.
+ */
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+ image->depth=8;
+ image->columns=(size_t) stream_features.width;
+ image->rows=(size_t) stream_features.height;
+ image->matte=(stream_features.has_alpha ? MagickTrue : MagickFalse);
+ if (image->ping)
+ {
+ MagickFreeMemory(stream);
+ CloseBlob(image);
+ return(image);
+ }
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ {
+ MagickFreeMemory(stream);
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ }
+ if (image->matte)
+ pixels=(unsigned char *) WebPDecodeRGBA(stream,length,
+ &stream_features.width,
+ &stream_features.height);
+ else
+ pixels=(unsigned char *) WebPDecodeRGB(stream,length,
+ &stream_features.width,
+ &stream_features.height);
+ if (pixels == (unsigned char *) NULL)
+ {
+ MagickFreeMemory(stream);
+ ThrowReaderException(CoderError,NoDataReturned,image);
+ }
+
+ p=pixels;
+
+ for (y=0; y < (size_t) image->rows; y++)
+ {
+ q=GetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ break;
+
+ for (x=0; x < (size_t) image->columns; x++)
+ {
+ SetRedSample(q,ScaleCharToQuantum(*p++));
+ SetGreenSample(q,ScaleCharToQuantum(*p++));
+ SetBlueSample(q,ScaleCharToQuantum(*p++));
+ if (image->matte)
+ SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(*p++));
+ else
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+
+ if(!SyncImagePixels(image))
+ break;
+ }
+ /*
+ Free scale resource.
+ */
+ free(pixels);
+ pixels=(unsigned char *) NULL;
+ MagickFreeMemory(stream);
+ CloseBlob(image);
+ return(image);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r W E B P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterWEBPImage adds attributes for the WEBP image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterWEBPImage method is:
+%
+% RegisterWEBPImage(void)
+%
+*/
+ModuleExport void RegisterWEBPImage(void)
+{
+ static const char
+ *description = "WebP Image Format";
+
+ static char
+ version[MaxTextExtent];
+
+ MagickInfo
+ *entry;
+
+ int
+ web_encoder_version;
+
+ unsigned int
+ webp_major,
+ webp_minor,
+ webp_revision;
+
+ *version='\0';
+
+ /*
+ Obtain the encoder's version number from the library, packed in
+ hexadecimal using 8bits for each of major/minor/revision. E.g:
+ v2.5.7 is 0x020507.
+
+ Also capture the encoder ABI version from <webp/encode.h> which is
+ in the form MAJOR(8b) + MINOR(8b) where ABI is related to the
+ library ABI and not the package release version.
+ */
+ web_encoder_version=(WebPGetEncoderVersion());
+ webp_major=(web_encoder_version >> 16) & 0xff;
+ webp_minor=(web_encoder_version >> 8) & 0xff;
+ webp_revision=web_encoder_version & 0xff;
+ FormatString(version, "libwepb v%u.%u.%u, ENCODER ABI 0x%04X", webp_major,
+ webp_minor, webp_revision, WEBP_ENCODER_ABI_VERSION);
+
+ entry=SetMagickInfo("WEBP");
+#if defined(HasWEBP)
+ entry->decoder=(DecoderHandler) ReadWEBPImage;
+ entry->encoder=(EncoderHandler) WriteWEBPImage;
+#endif
+ entry->description=description;
+ entry->adjoin=False;
+ entry->seekable_stream=MagickTrue; /* FIXME */
+ if (*version != '\0')
+ entry->version=version;
+ entry->module="WEBP";
+ entry->coder_class=PrimaryCoderClass;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r W E B P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterWEBPImage removes format registrations made by the
+% WEBP module from the list of supported formats.
+%
+% The format of the UnregisterWEBPImage method is:
+%
+% UnregisterWEBPImage(void)
+%
+*/
+ModuleExport void UnregisterWEBPImage(void)
+{
+ (void) UnregisterMagickInfo("WEBP");
+}
+
+#if defined(HasWEBP)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e W E B P I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteWEBPImage() writes an image in the WebP image format.
+%
+% The format of the WriteWEBPImage method is:
+%
+% MagickPassFail WriteWEBPImage(const ImageInfo *image_info, Image *image)
+%
+% A description of each parameter follows.
+%
+% o image_info: the image info.
+%
+% o image: The image.
+%
+*/
+
+/*
+ Called to write data to blob
+*/
+static int WriterCallback(const unsigned char *stream,size_t length,
+ const WebPPicture *const picture)
+{
+ Image
+ *image;
+
+ image=(Image *) picture->custom_ptr;
+ return (length != 0 ? (int) WriteBlob(image,length,stream) : 1);
+}
+
+/*
+ Called to provide progress indication
+*/
+#if defined(SUPPORT_PROGRESS)
+static int ProgressCallback(int percent, const WebPPicture* picture)
+{
+ Image
+ *image;
+
+ image=(Image *) picture->custom_ptr;
+ return MagickMonitorFormatted(percent, 101, &image->exception,
+ SaveImageText, image->filename,
+ image->columns, image->rows);
+}
+#endif
+
+static unsigned int WriteWEBPImage(const ImageInfo *image_info,Image *image)
+{
+ const char
+ *value;
+
+ int
+ webp_status;
+
+ unsigned int
+ status;
+
+ register PixelPacket
+ *p;
+
+ register size_t
+ x;
+
+ register unsigned char
+ *q;
+
+ unsigned long
+ y;
+
+ size_t
+ per_column;
+
+ unsigned char
+ *pixels;
+
+ WebPConfig
+ configure;
+
+ WebPPicture
+ picture;
+
+ WebPAuxStats
+ statistics;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if ((image->columns > 16383) || (image->rows > 16383))
+ ThrowWriterException(ImageError,WidthOrHeightExceedsLimit,image);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == MagickFail)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Initialize WebP picture. This function is declared as 'static
+ inline'. It returns false if there is a mismatch between the
+ libwebp headers and library.
+ */
+ if (WebPPictureInit(&picture) == 0)
+ ThrowWriterException(DelegateError, WebPABIMismatch, image);
+ /*
+ Make sure that image is in an RGB type space and DirectClass.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ image->storage_class=DirectClass;
+
+ picture.writer=WriterCallback;
+ picture.custom_ptr=(void *) image;
+#if defined(SUPPORT_PROGRESS)
+ picture.progress_hook=ProgressCallback;
+#endif
+ picture.stats=(&statistics);
+ picture.width=(int) image->columns;
+ picture.height=(int) image->rows;
+ if (WebPConfigInit(&configure) == 0)
+ ThrowWriterException(DelegateError, WebPABIMismatch, image);
+ if (image_info->quality != DefaultCompressionQuality)
+ configure.quality = (float) image_info->quality;
+
+ if ((value=AccessDefinition(image_info,"webp","lossless")))
+ configure.lossless=(LocaleCompare(value,"TRUE") == 0 ? 1 : 0);
+ if ((value=AccessDefinition(image_info,"webp","method")))
+ configure.method=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","image-hint")))
+ {
+ if (LocaleCompare(value,"default") == 0)
+ configure.image_hint=WEBP_HINT_DEFAULT;
+ if (LocaleCompare(value,"picture") == 0)
+ configure.image_hint=WEBP_HINT_PICTURE;
+ if (LocaleCompare(value,"photo") == 0)
+ configure.image_hint=WEBP_HINT_PHOTO;
+#if defined(SUPPORT_CONFIG_WEBP_HINT_GRAPH)
+ if (LocaleCompare(value,"graph") == 0)
+ configure.image_hint=WEBP_HINT_GRAPH;
+#endif
+ }
+ if ((value=AccessDefinition(image_info,"webp","target-size")))
+ configure.target_size=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","target-psnr")))
+ configure.target_PSNR=(float) MagickAtoF(value);
+ if ((value=AccessDefinition(image_info,"webp","segments")))
+ configure.segments=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","sns-strength")))
+ configure.sns_strength=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","filter-strength")))
+ configure.filter_strength=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","filter-sharpness")))
+ configure.filter_sharpness=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","filter-type")))
+ configure.filter_type=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","auto-filter")))
+ configure.autofilter=(LocaleCompare(value,"TRUE") == 0 ? 1 : 0);
+ if ((value=AccessDefinition(image_info,"webp","alpha-compression")))
+ configure.alpha_compression=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","alpha-filtering")))
+ configure.alpha_filtering=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","alpha-quality")))
+ configure.alpha_quality=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","pass")))
+ configure.pass=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","show-compressed")))
+ configure.show_compressed=(LocaleCompare(value,"TRUE") == 0 ? 1 : 0);
+ if ((value=AccessDefinition(image_info,"webp","preprocessing")))
+ configure.preprocessing=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","partitions")))
+ configure.partitions=MagickAtoI(value);
+ if ((value=AccessDefinition(image_info,"webp","partition-limit")))
+ configure.partition_limit=MagickAtoI(value);
+#if defined(SUPPORT_CONFIG_EMULATE_JPEG_SIZE)
+ if ((value=AccessDefinition(image_info,"webp","emulate-jpeg-size")))
+ configure.emulate_jpeg_size=(LocaleCompare(value,"TRUE") == 0 ? 1 : 0);
+#endif
+#if defined(SUPPORT_CONFIG_THREAD_LEVEL)
+ if ((value=AccessDefinition(image_info,"webp","thread-level")))
+ configure.thread_level=MagickAtoI(value);
+#endif
+#if defined(SUPPORT_CONFIG_LOW_MEMORY)
+ if ((value=AccessDefinition(image_info,"webp","low-memory")))
+ configure.low_memory=(LocaleCompare(value,"TRUE") == 0 ? 1 : 0);
+#endif
+ if (WebPValidateConfig(&configure) != 1)
+ ThrowWriterException(CoderError,WebPInvalidConfiguration,image);
+
+ if (configure.lossless == 1)
+ {
+ /*
+ Use ARGB input for lossless (YUVA input is lossy).
+ */
+ picture.use_argb = 1;
+ webp_status = WebPPictureAlloc(&picture);
+
+ for (y = 0; y < image->rows; y++)
+ {
+ magick_uint32_t *s = picture.argb + y * picture.argb_stride;
+ p=GetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x = 0; x < image->columns; x++)
+ {
+ *s = ((!image->matte ? 0xff000000u : (magick_uint32_t)
+ ScaleQuantumToChar(MaxRGB-GetOpacitySample(p)) << 24) |
+ (ScaleQuantumToChar(GetRedSample(p)) << 16) |
+ (ScaleQuantumToChar(GetGreenSample(p)) << 8) |
+ (ScaleQuantumToChar(GetBlueSample(p))));
+ s++;
+ p++;
+ }
+ }
+
+ }
+ else
+ {
+ /*
+ Allocate memory for pixels.
+ */
+ per_column = MagickArraySize(MagickArraySize(4,image->rows),sizeof(*pixels));
+ pixels=MagickAllocateArray(unsigned char *,image->columns,per_column);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ /*
+ Convert image to WebP raster pixels.
+ */
+ q=pixels;
+ for (y=0; y < image->rows; y++)
+ {
+ p=GetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < image->columns; x++)
+ {
+ *q++=ScaleQuantumToChar(GetRedSample(p));
+ *q++=ScaleQuantumToChar(GetGreenSample(p));
+ *q++=ScaleQuantumToChar(GetBlueSample(p));
+ if (image->matte == MagickTrue)
+ *q++=ScaleQuantumToChar(MaxRGB-GetOpacitySample(p));
+ p++;
+ }
+ }
+
+ /*
+ "Returns false in case of memory error."
+ */
+ if (image->matte != MagickTrue)
+ webp_status=WebPPictureImportRGB(&picture,pixels,3*picture.width);
+ else
+ webp_status=WebPPictureImportRGBA(&picture,pixels,4*picture.width);
+ MagickFreeMemory(pixels);
+ }
+
+ if (webp_status)
+ {
+ /*
+ "Returns false in case of error, true otherwise.
+ In case of error, picture->error_code is updated accordingly."
+ */
+ webp_status=WebPEncode(&configure, &picture);
+ if (! webp_status)
+ {
+ int
+ picture_error_code;
+
+ picture_error_code=picture.error_code;
+ WebPPictureFree(&picture);
+
+ switch (picture_error_code)
+ {
+ case VP8_ENC_OK:
+ break;
+ case VP8_ENC_ERROR_OUT_OF_MEMORY:
+ ThrowWriterException(CoderError,WebPEncodingFailedOutOfMemory,image);
+ break;
+ case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY:
+ ThrowWriterException(CoderError,WebPEncodingFailedBitstreamOutOfMemory,image);
+ break;
+ case VP8_ENC_ERROR_NULL_PARAMETER:
+ ThrowWriterException(CoderError,WebPEncodingFailedNULLParameter,image);
+ break;
+ case VP8_ENC_ERROR_INVALID_CONFIGURATION:
+ ThrowWriterException(CoderError,WebPEncodingFailedInvalidConfiguration,image);
+ break;
+ case VP8_ENC_ERROR_BAD_DIMENSION:
+ ThrowWriterException(CoderError,WebPEncodingFailedBadDimension,image);
+ break;
+ case VP8_ENC_ERROR_PARTITION0_OVERFLOW:
+ ThrowWriterException(CoderError,WebPEncodingFailedPartition0Overflow,image);
+ break;
+ case VP8_ENC_ERROR_PARTITION_OVERFLOW:
+ ThrowWriterException(CoderError,WebPEncodingFailedPartitionOverflow,image);
+ break;
+ case VP8_ENC_ERROR_BAD_WRITE:
+ ThrowWriterException(CoderError,WebPEncodingFailedBadWrite,image);
+ break;
+ case VP8_ENC_ERROR_FILE_TOO_BIG:
+ ThrowWriterException(CoderError,WebPEncodingFailedFileTooBig,image);
+ break;
+#if defined(SUPPORT_USER_ABORT)
+ case VP8_ENC_ERROR_USER_ABORT: /* Added in v0.1.99 */
+ ThrowWriterException(CoderError,WebPEncodingFailedUserAbort,image);
+ break;
+ case VP8_ENC_ERROR_LAST: /* Added in v0.1.99 */
+ break;
+#endif
+ } /* switch (picture_error_code) */
+ /*
+ Catch-all in case a code is added that we are not
+ explicitly prepared for.
+ */
+ ThrowWriterException(CoderError,WebPEncodingFailed,image);
+ } /* if (! webp_status) */
+ } /* if (webp_status) */
+
+ WebPPictureFree(&picture);
+ CloseBlob(image);
+
+ return (webp_status ? MagickPass : MagickFail);
+}
+#endif
diff --git a/coders/wmf.c b/coders/wmf.c
new file mode 100644
index 0000000..f10132f
--- /dev/null
+++ b/coders/wmf.c
@@ -0,0 +1,2805 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W W M M FFFFF %
+% W W MM MM F %
+% W W W M M M FFF %
+% WW WW M M F %
+% W W M M F %
+% %
+% %
+% Read Windows Metafile Format. %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% Dec 2000 - May 2001 %
+% Oct 2001 - May 2002 %
+% %
+% Port to libwmf 0.2 API %
+% Francis J. Franklin %
+% May 2001 - Oct 2001 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+
+/*
+ * Include declarations.
+ */
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/constitute.h"
+#include "magick/draw.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/paint.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+
+#if defined(MSWINDOWS)
+/* The need for this under Visual C++ is a mystery to me */
+# if !defined(M_PI)
+# define M_PI MagickPI
+# endif
+#endif
+
+#if defined(HasWMF) || defined(HasWMFlite)
+
+#define ERR(API) ((API)->err != wmf_E_None)
+#define XC(x) ((double)x)
+#define YC(y) ((double)y)
+
+#if defined(HAVE_FT2BUILD_H)
+ /* Some libwmf/FreeType installs are broken in that the libwmf
+ headers don't work without including <ft2build.h> first */
+# include <ft2build.h>
+#endif /* defined(HAVE_FT2BUILD_H) */
+#include "libwmf/fund.h"
+#include "libwmf/types.h"
+#include "libwmf/api.h"
+#undef SRCCOPY
+#undef SRCPAINT
+#undef SRCAND
+#undef SRCINVERT
+#undef SRCERASE
+#undef NOTSRCCOPY
+#undef NOTSRCERASE
+#undef MERGECOPY
+#undef MERGEPAINT
+#undef PATCOPY
+#undef PATPAINT
+#undef PATINVERT
+#undef DSTINVERT
+#undef BLACKNESS
+#undef WHITENESS
+
+/* The following additinal undefs were required for MinGW */
+#undef BS_HOLLOW
+#undef PS_STYLE_MASK
+#undef PS_ENDCAP_ROUND
+#undef PS_ENDCAP_SQUARE
+#undef PS_ENDCAP_FLAT
+#undef PS_ENDCAP_MASK
+#undef PS_JOIN_ROUND
+#undef PS_JOIN_BEVEL
+#undef PS_JOIN_MITER
+#undef PS_COSMETIC
+#undef PS_GEOMETRIC
+#undef PS_TYPE_MASK
+#undef STRETCH_ANDSCANS
+#undef STRETCH_ORSCANS
+#undef STRETCH_DELETESCANS
+#undef STRETCH_HALFTONE
+#undef ETO_OPAQUE
+#undef ETO_CLIPPED
+#undef ETO_GLYPH_INDEX
+#undef ETO_RTLREADING
+
+#include "libwmf/defs.h"
+#include "libwmf/ipa.h"
+#include "libwmf/color.h"
+#include "libwmf/macro.h"
+
+/* Unit conversions */
+#define TWIPS_PER_INCH 1440
+#define CENTIMETERS_PER_INCH 2.54
+#define POINTS_PER_INCH 72
+
+#if defined(HasWMFlite)
+# define wmf_api_create(api,flags,options) wmf_lite_create(api,flags,options)
+# define wmf_api_destroy(api) wmf_lite_destroy(api)
+# undef WMF_FONT_PSNAME
+# define WMF_FONT_PSNAME(F) ((F)->user_data ? ((wmf_magick_font_t*) (F)->user_data)->ps_name : 0)
+
+typedef struct _wmf_magick_font_t wmf_magick_font_t;
+
+struct _wmf_magick_font_t
+{
+ char* ps_name;
+ double pointsize;
+};
+
+#endif
+
+typedef struct _wmf_magick_t wmf_magick_t;
+
+struct _wmf_magick_t
+{
+ /* Bounding box */
+ wmfD_Rect
+ bbox;
+
+ /* Scale and translation factors */
+ double
+ scale_x,
+ scale_y,
+ translate_x,
+ translate_y,
+ rotate;
+
+ /* Vector output */
+ DrawContext
+ draw_context;
+
+ /* GraphicsMagick image */
+ Image
+ *image;
+
+ /* ImageInfo */
+ const ImageInfo
+ *image_info;
+
+ /* DrawInfo */
+ DrawInfo
+ *draw_info;
+
+ /* Pattern ID */
+ unsigned long
+ pattern_id;
+
+ /* Clip path flag */
+ unsigned int
+ clipping;
+
+ /* Clip path ID */
+ unsigned long
+ clip_path_id;
+
+ /* Push depth */
+ long
+ push_depth;
+};
+
+
+#define WMF_MAGICK_GetData(Z) ((wmf_magick_t*)((Z)->device_data))
+#define WMF_MAGICK_GetFontData(Z) ((wmf_magick_font_t*)((wmfFontData *)Z->font_data)->user_data)
+
+#define WmfDrawContext (((wmf_magick_t*)((API)->device_data))->draw_context)
+
+/* Enum to control whether util_set_brush applies brush to fill or
+ stroke. */
+typedef enum
+{
+ BrushApplyFill,
+ BrushApplyStroke
+} BrushApply;
+
+
+/* Enum to specify arc type */
+typedef enum
+{
+ magick_arc_ellipse = 0,
+ magick_arc_open,
+ magick_arc_pie,
+ magick_arc_chord
+}
+magick_arc_t;
+
+#if defined(HasWMFlite)
+static void lite_font_init (wmfAPI* API, wmfAPI_Options* options);
+static void lite_font_map(wmfAPI* API,wmfFont* font);
+static float lite_font_stringwidth(wmfAPI* API, wmfFont* font, char* str);
+#endif
+
+static void draw_color_fill_rgb(wmfAPI* API, const wmfRGB* rgb);
+static void draw_color_stroke_rgb(wmfAPI* API, const wmfRGB* rgb);
+static void draw_pattern_push(wmfAPI* API, unsigned long id, unsigned long columns, unsigned long rows);
+static int ipa_blob_read(void* context);
+static int ipa_blob_seek(void* context,long position);
+static long ipa_blob_tell(void* context);
+static void ipa_bmp_draw(wmfAPI * API, wmfBMP_Draw_t * bmp_draw);
+static void ipa_bmp_free(wmfAPI * API, wmfBMP * bmp);
+static void ipa_bmp_read(wmfAPI * API, wmfBMP_Read_t * bmp_read);
+static void ipa_device_begin(wmfAPI * API);
+static void ipa_device_close(wmfAPI * API);
+static void ipa_device_end(wmfAPI * API);
+static void ipa_device_open(wmfAPI * API);
+static void ipa_draw_arc(wmfAPI * API, wmfDrawArc_t * draw_arc);
+static void ipa_draw_chord(wmfAPI * API, wmfDrawArc_t * draw_arc);
+static void ipa_draw_ellipse(wmfAPI * API, wmfDrawArc_t * draw_arc);
+static void ipa_draw_line(wmfAPI * API, wmfDrawLine_t * draw_line);
+static void ipa_draw_pie(wmfAPI * API, wmfDrawArc_t * draw_arc);
+static void ipa_draw_pixel(wmfAPI * API, wmfDrawPixel_t * draw_pixel);
+static void ipa_draw_polygon(wmfAPI * API, wmfPolyLine_t * poly_line);
+#if defined(HasWMFlite)
+static void ipa_draw_polypolygon(wmfAPI * API, wmfPolyPoly_t* polypolygon);
+#endif
+static void ipa_draw_rectangle(wmfAPI * API, wmfDrawRectangle_t * draw_rect);
+static void ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text);
+static void ipa_flood_exterior(wmfAPI * API, wmfFlood_t * flood);
+static void ipa_flood_interior(wmfAPI * API, wmfFlood_t * flood);
+static void ipa_functions(wmfAPI * API);
+static void ipa_poly_line(wmfAPI * API, wmfPolyLine_t * poly_line);
+static void ipa_region_clip(wmfAPI * API, wmfPolyRectangle_t * poly_rect);
+static void ipa_region_frame(wmfAPI * API, wmfPolyRectangle_t * poly_rect);
+static void ipa_region_paint(wmfAPI * API, wmfPolyRectangle_t * poly_rect);
+static void ipa_rop_draw(wmfAPI * API, wmfROP_Draw_t * rop_draw);
+static void ipa_udata_copy(wmfAPI * API, wmfUserData_t * userdata);
+static void ipa_udata_free(wmfAPI * API, wmfUserData_t * userdata);
+static void ipa_udata_init(wmfAPI * API, wmfUserData_t * userdata);
+static void ipa_udata_set(wmfAPI * API, wmfUserData_t * userdata);
+static int magick_progress_callback(void* context,float quantum);
+static void util_draw_arc(wmfAPI * API, wmfDrawArc_t * draw_arc,magick_arc_t finish);
+#if defined(HasWMFlite)
+static int util_font_weight( const char* font );
+#endif
+static double util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height);
+static void util_set_brush(wmfAPI * API, wmfDC * dc, const BrushApply brush_apply);
+static void util_set_pen(wmfAPI * API, wmfDC * dc);
+
+/* Progress callback */
+static int magick_progress_callback (void* context,float quantum)
+{
+ Image
+ *image;
+
+ unsigned int
+ status = 0;
+
+ image=(Image *) context;
+ if (MagickMonitorFormatted((ExtendedSignedIntegralType)floor(quantum*100),100,
+ &image->exception,(char*)context,
+ image->filename) == False)
+ status = 1;
+ return status;
+}
+
+/* Set fill color */
+static void draw_color_fill_rgb( wmfAPI* API, const wmfRGB* rgb )
+{
+ PixelPacket
+ fill_color;
+
+ fill_color.red = ScaleCharToQuantum(rgb->r);
+ fill_color.green = ScaleCharToQuantum(rgb->g);
+ fill_color.blue = ScaleCharToQuantum(rgb->b);
+ fill_color.opacity = OpaqueOpacity;
+
+ DrawSetFillColor(WmfDrawContext,&fill_color);
+
+}
+
+/* Set stroke color */
+static void draw_color_stroke_rgb( wmfAPI* API, const wmfRGB* rgb )
+{
+ PixelPacket
+ stroke_color;
+
+ stroke_color.red = ScaleCharToQuantum(rgb->r);
+ stroke_color.green = ScaleCharToQuantum(rgb->g);
+ stroke_color.blue = ScaleCharToQuantum(rgb->b);
+ stroke_color.opacity = OpaqueOpacity;
+
+ DrawSetStrokeColor(WmfDrawContext,&stroke_color);
+}
+
+static void draw_pattern_push( wmfAPI* API,
+ unsigned long id,
+ unsigned long columns,
+ unsigned long rows )
+{
+ char
+ pattern_id[MaxTextExtent];
+
+ FormatString(pattern_id,"brush_%lu",id);
+ DrawPushPattern(WmfDrawContext,pattern_id,0,0,columns,rows);
+}
+
+/* Pattern/Bit BLT with raster operation (ROP) support. Invoked by
+ META_PATBLT, which is equivalent to Windows PatBlt() call, or by
+ META_DIBBITBLT which is equivalent to Windows BitBlt() call. */
+
+/* The BitBlt function transfers pixels from a rectangular area in one
+ device context called the 'source', to a rectangular area of the
+ same size in another device context, called the 'destination'. */
+
+static void ipa_rop_draw(wmfAPI * API, wmfROP_Draw_t * rop_draw)
+{
+/* wmfBrush */
+/* *brush = WMF_DC_BRUSH(rop_draw->dc); */
+
+/* wmfBMP */
+/* *brush_bmp = WMF_BRUSH_BITMAP(brush); */
+
+ if (!TO_FILL(rop_draw))
+ return;
+
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ /* FIXME: finish implementing (once we know what it is supposed to do!) */
+
+ /*
+ struct _wmfROP_Draw_t
+ { wmfDC* dc;
+
+ wmfD_Coord TL;
+ wmfD_Coord BR;
+
+ U32 ROP;
+
+ double pixel_width;
+ double pixel_height;
+ };
+ */
+
+/* if(brush_bmp && brush_bmp->data != 0) */
+/* printf("Have an image!\n"); */
+
+ switch (rop_draw->ROP) /* Ternary raster operations */
+ {
+ case SRCCOPY: /* dest = source */
+ (void) printf("ipa_rop_draw SRCCOPY ROP mode not implemented\n");
+ break;
+ case SRCPAINT: /* dest = source OR dest */
+ (void) printf("ipa_rop_draw SRCPAINT ROP mode not implemented\n");
+ break;
+ case SRCAND: /* dest = source AND dest */
+ (void) printf("ipa_rop_draw SRCAND ROP mode not implemented\n");
+ break;
+ case SRCINVERT: /* dest = source XOR dest */
+ (void) printf("ipa_rop_draw SRCINVERT ROP mode not implemented\n");
+ break;
+ case SRCERASE: /* dest = source AND (NOT dest) */
+ (void) printf("ipa_rop_draw SRCERASE ROP mode not implemented\n");
+ break;
+ case NOTSRCCOPY: /* dest = (NOT source) */
+ (void) printf("ipa_rop_draw NOTSRCCOPY ROP mode not implemented\n");
+ break;
+ case NOTSRCERASE: /* dest = (NOT src) AND (NOT dest) */
+ (void) printf("ipa_rop_draw NOTSRCERASE ROP mode not implemented\n");
+ break;
+ case MERGECOPY: /* dest = (source AND pattern) */
+ (void) printf("ipa_rop_draw MERGECOPY ROP mode not implemented\n");
+ break;
+ case MERGEPAINT: /* dest = (NOT source) OR dest */
+ (void) printf("ipa_rop_draw MERGEPAINT ROP mode not implemented\n");
+ break;
+ case PATCOPY: /* dest = pattern */
+ util_set_brush(API, rop_draw->dc, BrushApplyFill);
+ break;
+ case PATPAINT: /* dest = DPSnoo */
+ (void) printf("ipa_rop_draw PATPAINT ROP mode not implemented\n");
+ break;
+ case PATINVERT: /* dest = pattern XOR dest */
+ (void) printf("ipa_rop_draw PATINVERT ROP mode not implemented\n");
+ break;
+ case DSTINVERT: /* dest = (NOT dest) */
+ (void) printf("ipa_rop_draw DSTINVERT ROP mode not implemented\n");
+ break;
+ case BLACKNESS: /* dest = BLACK */
+ DrawSetFillColorString(WmfDrawContext,"black");
+ break;
+ case WHITENESS: /* dest = WHITE */
+ DrawSetFillColorString(WmfDrawContext,"white");
+ break;
+ default:
+ (void) printf("ipa_rop_draw 0x%x ROP mode not implemented\n", rop_draw->ROP);
+ break;
+ }
+
+ DrawRectangle(WmfDrawContext,
+ XC(rop_draw->TL.x), YC(rop_draw->TL.y),
+ XC(rop_draw->BR.x), YC(rop_draw->BR.y));
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_bmp_draw(wmfAPI *API, wmfBMP_Draw_t *bmp_draw)
+{
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ ExceptionInfo
+ exception;
+
+ Image
+ *image;
+
+ double
+ height,
+ width;
+
+ MonitorHandler
+ handler;
+
+ PixelPacket
+ white;
+
+ if (bmp_draw->bmp.data == 0)
+ return;
+
+ GetExceptionInfo(&exception);
+ image = (Image*)bmp_draw->bmp.data;
+ if(!image)
+ {
+ CopyException(&ddata->image->exception,&exception);
+ return;
+ }
+
+ if(bmp_draw->crop.x || bmp_draw->crop.y ||
+ (bmp_draw->crop.w != bmp_draw->bmp.width) ||
+ (bmp_draw->crop.h != bmp_draw->bmp.height))
+ {
+ /* Image needs to be cropped */
+ Image
+ *crop_image;
+
+ RectangleInfo
+ crop_info;
+
+ crop_info.x = bmp_draw->crop.x;
+ crop_info.y = bmp_draw->crop.y;
+ crop_info.width = bmp_draw->crop.w;
+ crop_info.height = bmp_draw->crop.h;
+
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ crop_image = CropImage( image, &crop_info, &exception );
+ (void) SetMonitorHandler(handler);
+ if(crop_image)
+ {
+ DestroyImageList(image);
+ image = crop_image;
+ bmp_draw->bmp.data = (void*)image;
+ }
+ else
+ CopyException(&ddata->image->exception,&exception);
+ }
+
+ (void) QueryColorDatabase( "white", &white, &exception );
+
+ if ( ddata->image_info->texture ||
+ !(ColorMatch(&ddata->image_info->background_color, &white)) ||
+ ddata->image_info->background_color.opacity != OpaqueOpacity )
+ {
+ /*
+ Set image white background to transparent so that it may be
+ overlaid over non-white backgrounds.
+ */
+ (void) TransparentImage( image, white, MaxRGB );
+ }
+
+ width = AbsoluteValue(bmp_draw->pixel_width * (double) bmp_draw->crop.w);
+ height = AbsoluteValue(bmp_draw->pixel_height * (double) bmp_draw->crop.h);
+
+ DrawComposite(WmfDrawContext, CopyCompositeOp, XC(bmp_draw->pt.x), YC(bmp_draw->pt.y),
+ width, height, image );
+
+#if 0
+ printf("bmp_draw->bmp.data = 0x%lx\n", (long)bmp_draw->bmp.data);
+ printf("registry id = %li\n", id);
+ /* printf("pixel_width = %.4g\n", bmp_draw->pixel_width); */
+ /* printf("pixel_height = %.4g\n", bmp_draw->pixel_height); */
+ printf("bmp_draw->bmp WxH = %ix%i\n", bmp_draw->bmp.width, bmp_draw->bmp.height);
+ printf("bmp_draw->crop WxH = %ix%i\n", bmp_draw->crop.w, bmp_draw->crop.h);
+ printf("bmp_draw->crop x,y = %i,%i\n", bmp_draw->crop.x, bmp_draw->crop.y);
+ printf("image size WxH = %lux%lu\n", image->columns, image->rows);
+#endif
+}
+
+static void ipa_bmp_read(wmfAPI * API, wmfBMP_Read_t * bmp_read) {
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ ExceptionInfo
+ exception;
+
+ ImageInfo
+ *image_info;
+
+ Image
+ *image;
+
+ MonitorHandler
+ handler;
+
+ bmp_read->bmp.data = 0;
+
+ GetExceptionInfo(&exception);
+
+ image_info = CloneImageInfo((ImageInfo *) 0);
+ (void) strcpy(image_info->magick, "DIB");
+ if(bmp_read->width || bmp_read->height)
+ {
+ char
+ size[MaxTextExtent];
+
+ FormatString(size,"%ux%u",bmp_read->width,bmp_read->height);
+ (void) CloneString(&image_info->size,size);
+ }
+#if 0
+ printf("ipa_bmp_read: buffer=0x%lx length=%ld, width=%i, height=%i\n",
+ (long) bmp_read->buffer, bmp_read->length,
+ bmp_read->width, bmp_read->height);
+#endif
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ image = BlobToImage(image_info, (const void *) bmp_read->buffer,
+ bmp_read->length, &exception);
+ (void) SetMonitorHandler(handler);
+ DestroyImageInfo(image_info);
+ if (!image)
+ {
+ char
+ description[MaxTextExtent];
+
+ FormatString(description,"packed DIB at offset %ld", bmp_read->offset);
+ ThrowException2(&ddata->image->exception,CorruptImageError,
+ exception.reason,exception.description);
+ }
+ else
+ {
+#if 0
+ printf("ipa_bmp_read: rows=%ld,columns=%ld\n\n", image->rows, image->columns);
+#endif
+
+ bmp_read->bmp.data = (void*)image;
+ bmp_read->bmp.width = (U16)image->columns;
+ bmp_read->bmp.height = (U16)image->rows;
+ }
+}
+
+static void ipa_bmp_free(wmfAPI * API, wmfBMP * bmp)
+{
+ ARG_NOT_USED(API);
+ DestroyImageList((Image*)bmp->data);
+ bmp->data = (void*) 0;
+ bmp->width = (U16) 0;
+ bmp->height = (U16) 0;
+}
+
+/*
+ This is called by wmf_play() the *first* time the meta file is played
+ */
+static void ipa_device_open(wmfAPI * API)
+{
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData (API);
+
+ ddata->pattern_id = 0;
+ ddata->clipping = False;
+ ddata->clip_path_id = 0;
+
+ ddata->push_depth = 0;
+
+ ddata->draw_context = DrawAllocateContext(ddata->draw_info,ddata->image);
+}
+
+/*
+ This is called by wmf_api_destroy()
+ */
+static void ipa_device_close(wmfAPI * API)
+{
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ if (ddata->draw_context != (DrawContext) NULL)
+ {
+ DrawDestroyContext(ddata->draw_context);
+ ddata->draw_context = (DrawContext) NULL;
+ }
+ if (ddata->draw_info != (DrawInfo *) NULL)
+ {
+ DestroyDrawInfo(ddata->draw_info);
+ ddata->draw_info = (DrawInfo *) NULL;
+ }
+ MagickFreeMemory(WMF_MAGICK_GetFontData(API)->ps_name);
+}
+
+/*
+ This is called from the beginning of each play for initial page setup
+ */
+static void ipa_device_begin(wmfAPI * API)
+{
+ char
+ comment[MaxTextExtent];
+
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ /* Make SVG output happy */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ DrawSetViewbox(WmfDrawContext, 0, 0, ddata->image->columns, ddata->image->rows );
+
+ FormatString(comment,"Created by %s",
+ GetMagickVersion((unsigned long *) NULL));
+ DrawComment(WmfDrawContext,comment);
+
+ /* Scale width and height to image */
+ DrawScale(WmfDrawContext, ddata->scale_x, ddata->scale_y);
+
+ /* Translate to TL corner of bounding box */
+ DrawTranslate(WmfDrawContext, ddata->translate_x, ddata->translate_y);
+
+ /* Apply rotation */
+ DrawRotate(WmfDrawContext, ddata->rotate);
+
+ if(ddata->image_info->texture == NULL)
+ {
+ /* Draw rectangle in background color */
+ DrawSetFillColor(WmfDrawContext,&ddata->image->background_color);
+ DrawRectangle(WmfDrawContext,
+ XC(ddata->bbox.TL.x),YC(ddata->bbox.TL.y),
+ XC(ddata->bbox.BR.x),YC(ddata->bbox.BR.y));
+ }
+ else
+ {
+ /* Draw rectangle with texture image the SVG way */
+ Image
+ *image;
+
+ ImageInfo
+ *image_info;
+
+ ExceptionInfo
+ exception;
+
+ GetExceptionInfo(&exception);
+
+ image_info = CloneImageInfo((ImageInfo *) 0);
+ (void) strlcpy(image_info->filename, ddata->image_info->texture,
+ sizeof(image_info->filename));
+
+ if ( ddata->image_info->size )
+ (void) CloneString(&image_info->size,ddata->image_info->size);
+
+ image = ReadImage(image_info,&exception);
+ DestroyImageInfo(image_info);
+ if(image)
+ {
+ char
+ pattern_id[MaxTextExtent];
+
+ (void) strlcpy(image->magick,"MIFF",sizeof(image->magick));
+ DrawPushDefs(WmfDrawContext);
+ draw_pattern_push(API, ddata->pattern_id, image->columns, image->rows);
+ DrawComposite(WmfDrawContext, CopyCompositeOp, 0, 0, image->columns, image->rows, image);
+ DrawPopPattern(WmfDrawContext);
+ DrawPopDefs(WmfDrawContext);
+ FormatString(pattern_id,"#brush_%lu",ddata->pattern_id);
+ DrawSetFillPatternURL(WmfDrawContext,pattern_id);
+ ++ddata->pattern_id;
+
+ DrawRectangle(WmfDrawContext,
+ XC(ddata->bbox.TL.x),YC(ddata->bbox.TL.y),
+ XC(ddata->bbox.BR.x),YC(ddata->bbox.BR.y));
+ DestroyImageList(image);
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"reading texture image failed!");
+ CopyException(&ddata->image->exception,&exception);
+ }
+ }
+
+ DrawSetClipRule(WmfDrawContext,EvenOddRule); /* Default for WMF is ALTERNATE polygon fill mode */
+ DrawSetFillColorString(WmfDrawContext,"none"); /* Default brush is WHITE_BRUSH */
+ DrawSetStrokeColorString(WmfDrawContext,"none"); /* Default pen is BLACK_PEN */
+ DrawSetStrokeLineCap(WmfDrawContext,ButtCap); /* Default linecap is PS_ENDCAP_FLAT */
+ DrawSetStrokeLineJoin(WmfDrawContext,MiterJoin); /* Default linejoin is PS_JOIN_MITER */
+ DrawSetTextUnderColorString(WmfDrawContext,"white"); /* Default text box is white */
+}
+
+/*
+ This is called from the end of each play for page termination
+ */
+static void ipa_device_end(wmfAPI * API)
+{
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ /* Reset any existing clip paths by popping context */
+ if(ddata->clipping)
+ DrawPopGraphicContext(WmfDrawContext);
+ ddata->clipping = False;
+
+ /* Make SVG output happy */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_flood_interior(wmfAPI * API, wmfFlood_t * flood)
+{
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ draw_color_fill_rgb(API,&(flood->color));
+
+ DrawColor(WmfDrawContext,XC(flood->pt.x), YC(flood->pt.y),
+ FillToBorderMethod);
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_flood_exterior(wmfAPI * API, wmfFlood_t * flood)
+{
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ draw_color_fill_rgb(API,&(flood->color));
+
+ if (flood->type == FLOODFILLSURFACE)
+ DrawColor(WmfDrawContext, XC(flood->pt.x), YC(flood->pt.y),
+ FloodfillMethod);
+ else
+ DrawColor(WmfDrawContext, XC(flood->pt.x), YC(flood->pt.y),
+ FillToBorderMethod);
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_draw_pixel(wmfAPI * API, wmfDrawPixel_t * draw_pixel)
+{
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ DrawSetStrokeColorString(WmfDrawContext,"none");
+
+ draw_color_fill_rgb(API,&(draw_pixel->color));
+
+ DrawRectangle(WmfDrawContext,
+ XC(draw_pixel->pt.x),
+ YC(draw_pixel->pt.y),
+ XC(draw_pixel->pt.x + draw_pixel->pixel_width),
+ YC(draw_pixel->pt.y + draw_pixel->pixel_height));
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_draw_pie(wmfAPI * API, wmfDrawArc_t * draw_arc)
+{
+ util_draw_arc(API, draw_arc, magick_arc_pie);
+}
+
+static void ipa_draw_chord(wmfAPI * API, wmfDrawArc_t * draw_arc)
+{
+ util_draw_arc(API, draw_arc, magick_arc_chord);
+}
+
+static void ipa_draw_arc(wmfAPI * API, wmfDrawArc_t * draw_arc)
+{
+ util_draw_arc(API, draw_arc, magick_arc_open);
+}
+
+static void ipa_draw_ellipse(wmfAPI * API, wmfDrawArc_t * draw_arc)
+{
+ util_draw_arc(API, draw_arc, magick_arc_ellipse);
+}
+
+static void util_draw_arc(wmfAPI * API,
+ wmfDrawArc_t * draw_arc,
+ magick_arc_t finish)
+{
+ wmfD_Coord
+ BR,
+ O,
+ TL,
+ centre,
+ end,
+ start;
+
+ double
+ phi_e = 360,
+ phi_s = 0;
+
+ double
+ Rx,
+ Ry;
+
+ end.x=0;
+ end.y=0;
+ start.x=0;
+ start.y=0;
+
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ if (TO_FILL(draw_arc) || TO_DRAW(draw_arc))
+ {
+ centre.x = (draw_arc->TL.x + draw_arc->BR.x) / 2;
+ centre.y = (draw_arc->TL.y + draw_arc->BR.y) / 2;
+
+ if (finish != magick_arc_ellipse)
+ {
+ draw_arc->start.x += centre.x;
+ draw_arc->start.y += centre.y;
+
+ draw_arc->end.x += centre.x;
+ draw_arc->end.y += centre.y;
+ }
+
+ TL = draw_arc->TL;
+ BR = draw_arc->BR;
+
+ O = centre;
+
+ if (finish != magick_arc_ellipse)
+ {
+ start = draw_arc->start;
+ end = draw_arc->end;
+ }
+
+ Rx = (BR.x - TL.x) / 2;
+ Ry = (BR.y - TL.y) / 2;
+
+ if (finish != magick_arc_ellipse)
+ {
+ start.x -= O.x;
+ start.y -= O.y;
+
+ end.x -= O.x;
+ end.y -= O.y;
+
+ phi_s = atan2((double) start.y, (double) start.x) * 180 / MagickPI;
+ phi_e = atan2((double) end.y, (double) end.x) * 180 / MagickPI;
+
+ if (phi_e <= phi_s)
+ phi_e += 360;
+ }
+
+ util_set_pen(API, draw_arc->dc);
+ if (finish == magick_arc_open)
+ DrawSetFillColorString(WmfDrawContext,"none");
+ else
+ util_set_brush(API, draw_arc->dc, BrushApplyFill);
+
+ if (finish == magick_arc_ellipse)
+ DrawEllipse(WmfDrawContext, XC(O.x), YC(O.y), Rx, Ry, 0, 360);
+ else if (finish == magick_arc_pie)
+ {
+ DrawPathStart(WmfDrawContext);
+ DrawPathMoveToAbsolute(WmfDrawContext,
+ XC(O.x+start.x),YC(O.y+start.y));
+ DrawPathEllipticArcAbsolute(WmfDrawContext, Rx, Ry, 0, 0, 1,
+ XC(O.x+end.x),YC(O.y+end.y));
+ DrawPathLineToAbsolute(WmfDrawContext, XC(O.x), YC(O.y));
+ DrawPathClose(WmfDrawContext);
+ DrawPathFinish(WmfDrawContext);
+ }
+ else if (finish == magick_arc_chord)
+ {
+ DrawArc(WmfDrawContext,
+ XC(draw_arc->TL.x), YC(draw_arc->TL.y),
+ XC(draw_arc->BR.x), XC(draw_arc->BR.y),
+ phi_s, phi_e);
+ DrawLine(WmfDrawContext,
+ XC(draw_arc->BR.x-start.x), YC(draw_arc->BR.y-start.y),
+ XC(draw_arc->BR.x-end.x), YC(draw_arc->BR.y-end.y));
+ }
+ else /* if (finish == magick_arc_open) */
+ DrawArc(WmfDrawContext,
+ XC(draw_arc->TL.x), YC(draw_arc->TL.y),
+ XC(draw_arc->BR.x), XC(draw_arc->BR.y), phi_s, phi_e);
+ }
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_draw_line(wmfAPI * API, wmfDrawLine_t * draw_line)
+{
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ if (TO_DRAW(draw_line))
+ {
+ util_set_pen(API, draw_line->dc);
+ DrawLine(WmfDrawContext,
+ XC(draw_line->from.x), YC(draw_line->from.y),
+ XC(draw_line->to.x), YC(draw_line->to.y));
+ }
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_poly_line(wmfAPI * API, wmfPolyLine_t * polyline)
+{
+ if (polyline->count <= 2)
+ return;
+
+ if (TO_DRAW(polyline))
+ {
+ int
+ point;
+
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ util_set_pen(API, polyline->dc);
+
+ DrawPathStart(WmfDrawContext);
+ DrawPathMoveToAbsolute(WmfDrawContext,
+ XC(polyline->pt[0].x),
+ YC(polyline->pt[0].y));
+ for (point = 1; point < polyline->count; point++)
+ {
+ DrawPathLineToAbsolute(WmfDrawContext,
+ XC(polyline->pt[point].x),
+ YC(polyline->pt[point].y));
+ }
+ DrawPathFinish(WmfDrawContext);
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+ }
+}
+
+static void ipa_draw_polygon(wmfAPI * API, wmfPolyLine_t * polyline)
+{
+ if (polyline->count <= 2)
+ return;
+
+ if (TO_FILL(polyline) || TO_DRAW(polyline))
+ {
+ int
+ point;
+
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ util_set_pen(API, polyline->dc);
+ util_set_brush(API, polyline->dc, BrushApplyFill);
+
+ DrawPathStart(WmfDrawContext);
+ DrawPathMoveToAbsolute(WmfDrawContext,
+ XC(polyline->pt[0].x),
+ YC(polyline->pt[0].y));
+ for (point = 1; point < polyline->count; point++)
+ {
+ DrawPathLineToAbsolute(WmfDrawContext,
+ XC(polyline->pt[point].x),
+ YC(polyline->pt[point].y));
+ }
+ DrawPathClose(WmfDrawContext);
+ DrawPathFinish(WmfDrawContext);
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+ }
+}
+
+/* Draw a polypolygon. A polypolygon is a list of polygons */
+#if defined(HasWMFlite)
+static void ipa_draw_polypolygon(wmfAPI * API, wmfPolyPoly_t* polypolygon)
+{
+ if (TO_FILL(polypolygon) || TO_DRAW(polypolygon))
+ {
+ int
+ polygon,
+ point;
+
+ wmfPolyLine_t
+ polyline;
+
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ util_set_pen(API, polypolygon->dc);
+ util_set_brush(API, polypolygon->dc, BrushApplyFill);
+
+ DrawPathStart(WmfDrawContext);
+ for (polygon = 0; polygon < polypolygon->npoly; polygon++)
+ {
+ polyline.dc = polypolygon->dc;
+ polyline.pt = polypolygon->pt[polygon];
+ polyline.count = polypolygon->count[polygon];
+ if ((polyline.count > 2) && polyline.pt)
+ {
+ DrawPathMoveToAbsolute(WmfDrawContext,
+ XC(polyline.pt[0].x),
+ YC(polyline.pt[0].y));
+ for (point = 1; point < polyline.count; point++)
+ {
+ DrawPathLineToAbsolute(WmfDrawContext,
+ XC(polyline.pt[point].x),
+ YC(polyline.pt[point].y));
+ }
+ DrawPathClose(WmfDrawContext);
+ }
+ }
+ DrawPathFinish(WmfDrawContext);
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+ }
+}
+#endif
+
+static void ipa_draw_rectangle(wmfAPI * API, wmfDrawRectangle_t * draw_rect)
+{
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ if (TO_FILL(draw_rect) || TO_DRAW(draw_rect))
+ {
+ util_set_pen(API, draw_rect->dc);
+ util_set_brush(API, draw_rect->dc, BrushApplyFill);
+
+ if ((draw_rect->width > 0) || (draw_rect->height > 0))
+ DrawRoundRectangle(WmfDrawContext,
+ XC(draw_rect->TL.x), YC(draw_rect->TL.y),
+ XC(draw_rect->BR.x), YC(draw_rect->BR.y),
+ draw_rect->width / 2, draw_rect->height / 2);
+ else
+ DrawRectangle(WmfDrawContext,
+ XC(draw_rect->TL.x), YC(draw_rect->TL.y),
+ XC(draw_rect->BR.x), YC(draw_rect->BR.y));
+ }
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+/* Draw an un-filled rectangle using the current brush */
+static void ipa_region_frame(wmfAPI * API, wmfPolyRectangle_t * poly_rect)
+{
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ if (TO_FILL(poly_rect) || TO_DRAW(poly_rect))
+ {
+ unsigned int
+ i;
+
+ DrawSetFillColorString(WmfDrawContext,"none");
+ util_set_brush(API, poly_rect->dc, BrushApplyStroke);
+
+ for (i = 0; i < poly_rect->count; i++)
+ {
+ DrawRectangle(WmfDrawContext,
+ XC(poly_rect->TL[i].x), YC(poly_rect->TL[i].y),
+ XC(poly_rect->BR[i].x), YC(poly_rect->BR[i].y));
+ }
+ }
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_region_paint(wmfAPI * API, wmfPolyRectangle_t * poly_rect)
+{
+
+ if (poly_rect->count == 0)
+ return;
+
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+ if (TO_FILL (poly_rect))
+ {
+ unsigned int
+ i;
+
+ DrawSetStrokeColorString(WmfDrawContext,"none");
+ util_set_brush(API, poly_rect->dc, BrushApplyFill);
+
+ for (i = 0; i < poly_rect->count; i++)
+ {
+ DrawRectangle(WmfDrawContext,
+ XC(poly_rect->TL[i].x), YC(poly_rect->TL[i].y),
+ XC(poly_rect->BR[i].x), YC(poly_rect->BR[i].y));
+ }
+ }
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+}
+
+static void ipa_region_clip(wmfAPI *API, wmfPolyRectangle_t *poly_rect)
+{
+ unsigned int
+ i;
+
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData (API);
+
+ /* Reset any existing clip paths by popping context */
+ if(ddata->clipping)
+ DrawPopGraphicContext(WmfDrawContext);
+ ddata->clipping = False;
+
+ if(poly_rect->count > 0)
+ {
+ char
+ clip_path_id[MaxTextExtent];
+
+ /* Define clip path */
+ ddata->clip_path_id++;
+ DrawPushDefs(WmfDrawContext);
+ FormatString(clip_path_id,"clip_%lu",ddata->clip_path_id);
+ DrawPushClipPath(WmfDrawContext,clip_path_id);
+ DrawPushGraphicContext(WmfDrawContext);
+ for (i = 0; i < poly_rect->count; i++)
+ {
+ DrawRectangle(WmfDrawContext,
+ XC(poly_rect->TL[i].x), YC(poly_rect->TL[i].y),
+ XC(poly_rect->BR[i].x), YC(poly_rect->BR[i].y));
+ }
+ DrawPopGraphicContext(WmfDrawContext);
+ DrawPopClipPath(WmfDrawContext);
+ DrawPopDefs(WmfDrawContext);
+
+ /* Push context for new clip paths */
+ DrawPushGraphicContext(WmfDrawContext);
+ DrawSetClipPath(WmfDrawContext,clip_path_id);
+ ddata->clipping = True;
+ }
+}
+
+static void ipa_functions(wmfAPI *API)
+{
+ wmf_magick_t
+ *ddata = 0;
+
+ wmfFunctionReference
+ *FR = (wmfFunctionReference *) API->function_reference;
+
+ /*
+ IPA function reference links
+ */
+ FR->device_open = ipa_device_open;
+ FR->device_close = ipa_device_close;
+ FR->device_begin = ipa_device_begin;
+ FR->device_end = ipa_device_end;
+ FR->flood_interior = ipa_flood_interior;
+ FR->flood_exterior = ipa_flood_exterior;
+ FR->draw_pixel = ipa_draw_pixel;
+ FR->draw_pie = ipa_draw_pie;
+ FR->draw_chord = ipa_draw_chord;
+ FR->draw_arc = ipa_draw_arc;
+ FR->draw_ellipse = ipa_draw_ellipse;
+ FR->draw_line = ipa_draw_line;
+ FR->poly_line = ipa_poly_line;
+ FR->draw_polygon = ipa_draw_polygon;
+#if defined(HasWMFlite)
+ FR->draw_polypolygon = ipa_draw_polypolygon;
+#endif
+ FR->draw_rectangle = ipa_draw_rectangle;
+ FR->rop_draw = ipa_rop_draw;
+ FR->bmp_draw = ipa_bmp_draw;
+ FR->bmp_read = ipa_bmp_read;
+ FR->bmp_free = ipa_bmp_free;
+ FR->draw_text = ipa_draw_text;
+ FR->udata_init = ipa_udata_init;
+ FR->udata_copy = ipa_udata_copy;
+ FR->udata_set = ipa_udata_set;
+ FR->udata_free = ipa_udata_free;
+ FR->region_frame = ipa_region_frame;
+ FR->region_paint = ipa_region_paint;
+ FR->region_clip = ipa_region_clip;
+
+ /*
+ Allocate device data structure
+ */
+ ddata = (wmf_magick_t *) wmf_malloc(API, sizeof(wmf_magick_t));
+ if (ERR(API))
+ return;
+
+ (void) memset((void *) ddata, 0, sizeof(wmf_magick_t));
+ API->device_data = (void *) ddata;
+
+ /*
+ Device data defaults
+ */
+ ddata->image = 0;
+}
+
+static void ipa_draw_text(wmfAPI * API, wmfDrawText_t * draw_text)
+{
+ double
+ angle = 0, /* text rotation angle */
+ pointsize = 0; /* pointsize to output font with desired height */
+
+ TypeMetric
+ metrics;
+
+#if !defined(HasWMFlite)
+ double
+ bbox_height, /* bounding box height */
+ bbox_width /* bounding box width */
+
+ wmfD_Coord
+ BL, /* bottom left of bounding box */
+ BR, /* bottom right of bounding box */
+ TL, /* top left of bounding box */
+ TR; /* top right of bounding box */
+#endif
+
+ wmfD_Coord
+ point; /* text placement point */
+
+ wmfFont
+ *font;
+
+ wmf_magick_t
+ * ddata = WMF_MAGICK_GetData(API);
+
+ point = draw_text->pt;
+
+ /* Choose bounding box and calculate its width and height */
+#if !defined(HasWMFlite)
+ {
+ double
+ dx,
+ dy;
+
+ if( draw_text->flags)
+ {
+ TL = draw_text->TL;
+ BR = draw_text->BR;
+ TR.x = draw_text->BR.x;
+ TR.y = draw_text->TL.y;
+ BL.x = draw_text->TL.x;
+ BL.y = draw_text->BR.y;
+ }
+ else
+ {
+ TL = draw_text->bbox.TL;
+ BR = draw_text->bbox.BR;
+ TR = draw_text->bbox.TR;
+ BL = draw_text->bbox.BL;
+ }
+
+ dx = ((TR.x - TL.x) + (BR.x - BL.x)) / 2;
+ dy = ((TR.y - TL.y) + (BR.y - BL.y)) / 2;
+ bbox_width = sqrt(dx * dx + dy * dy);
+ dx = ((BL.x - TL.x) + (BR.x - TR.x)) / 2;
+ dy = ((BL.y - TL.y) + (BR.y - TR.y)) / 2;
+ bbox_height = sqrt(dx * dx + dy * dy);
+ }
+ }
+#endif
+
+ font = WMF_DC_FONT(draw_text->dc);
+
+ /* Convert font_height to equivalent pointsize */
+ pointsize = util_pointsize( API, font, draw_text->str, draw_text->font_height);
+
+ /* Save graphic context */
+ DrawPushGraphicContext(WmfDrawContext);
+
+#if 0
+ printf("\nipa_draw_text\n");
+ printf("Text = \"%s\"\n", draw_text->str);
+ /* printf("WMF_FONT_NAME: = \"%s\"\n", WMF_FONT_NAME(font)); */
+ printf("WMF_FONT_PSNAME: = \"%s\"\n", WMF_FONT_PSNAME(font));
+ printf("Bounding box TL=%.4g,%.4g BR=%.4g,%.4g\n",
+ TL.x, TL.y, BR.x, BR.y );
+ /* printf("Text box = %.4gx%.4g\n", bbox_width, bbox_height); */
+ /* printf("WMF_FONT_HEIGHT = %i\n", (int)WMF_FONT_HEIGHT(font)); */
+ printf("Pointsize = %.4g\n", pointsize);
+ fflush(stdout);
+#endif
+
+ /*
+ * Obtain font metrics if required
+ *
+ */
+ if ((WMF_DC_TEXTALIGN(draw_text->dc) & TA_CENTER) ||
+ (WMF_TEXT_UNDERLINE(font)) || (WMF_TEXT_STRIKEOUT(font)))
+ {
+ Image
+ *image = ddata->image;
+
+ DrawInfo
+ *draw_info;
+
+ draw_info=ddata->draw_info;
+ draw_info->font=WMF_FONT_PSNAME(font);
+ draw_info->pointsize = pointsize;
+ draw_info->text=draw_text->str;
+
+ if (GetTypeMetrics(image, draw_info, &metrics) != False)
+ {
+ /* Center the text if it is not yet centered and should be */
+ if ((WMF_DC_TEXTALIGN(draw_text->dc) & TA_CENTER))
+ {
+ double
+ text_width = metrics.width * (ddata->scale_y / ddata->scale_x);
+
+#if defined(HasWMFlite)
+ point.x -= text_width / 2;
+#else
+ point.x += bbox_width / 2 - text_width / 2;
+#endif
+ }
+ }
+ draw_info->font=NULL;
+ draw_info->text=NULL;
+ }
+
+ /* Set text background color */
+ if (draw_text->flags & ETO_OPAQUE)
+ {
+ /* Draw bounding-box background color (META_EXTTEXTOUT mode) */
+ DrawSetStrokeColorString(WmfDrawContext,"none");
+ draw_color_fill_rgb(API,WMF_DC_BACKGROUND(draw_text->dc));
+ DrawRectangle(WmfDrawContext,
+ XC(draw_text->TL.x),YC(draw_text->TL.y),
+ XC(draw_text->BR.x),YC(draw_text->BR.y));
+ DrawSetFillColorString(WmfDrawContext,"none");
+ }
+ else
+ {
+ /* Set text undercolor */
+ if (WMF_DC_OPAQUE(draw_text->dc))
+ {
+ wmfRGB
+ *box = WMF_DC_BACKGROUND(draw_text->dc);
+
+ PixelPacket
+ under_color;
+
+ under_color.red = ScaleCharToQuantum(box->r);
+ under_color.green = ScaleCharToQuantum(box->g);
+ under_color.blue = ScaleCharToQuantum(box->b);
+ under_color.opacity = OpaqueOpacity;
+
+ DrawSetTextUnderColor(WmfDrawContext,&under_color);
+ }
+ else
+ DrawSetTextUnderColorString(WmfDrawContext,"none");
+ }
+
+ /* Set text clipping (META_EXTTEXTOUT mode) */
+ if( draw_text->flags & ETO_CLIPPED)
+ {
+ }
+
+ /* Set stroke color */
+ DrawSetStrokeColorString(WmfDrawContext,"none");
+
+ /* Set fill color */
+ draw_color_fill_rgb(API,WMF_DC_TEXTCOLOR(draw_text->dc));
+
+ /* Output font size */
+ DrawSetFontSize(WmfDrawContext,pointsize);
+
+ /* Output Postscript font name */
+ DrawSetFont(WmfDrawContext, WMF_FONT_PSNAME(font));
+
+ /* Translate coordinates so target is 0,0 */
+ DrawTranslate(WmfDrawContext, XC(point.x), YC(point.y));
+
+ /* Transform horizontal scale to draw text at 1:1 ratio */
+ DrawScale(WmfDrawContext, ddata->scale_y / ddata->scale_x, 1.0);
+
+ /* Apply rotation */
+ /* GraphicsMagick's drawing rotation is clockwise from horizontal
+ while WMF drawing rotation is counterclockwise from horizontal */
+ angle = AbsoluteValue(RadiansToDegrees(2 * MagickPI - WMF_TEXT_ANGLE(font)));
+ if (angle == 360)
+ angle = 0;
+ if (angle != 0)
+ DrawRotate(WmfDrawContext, angle);
+
+ /*
+ * Render text
+ *
+ */
+
+ /* Output string */
+ DrawAnnotation(WmfDrawContext, 0, 0, (unsigned char*)draw_text->str);
+
+ /* Underline text the Windows way (at the bottom) */
+ if (WMF_TEXT_UNDERLINE(font))
+ {
+ double
+ line_height;
+
+ wmfD_Coord
+ ulBR, /* bottom right of underline rectangle */
+ ulTL; /* top left of underline rectangle */
+
+ line_height = ((double)1/(ddata->scale_x))*metrics.underline_thickness;
+ if(metrics.underline_thickness < 1.5)
+ line_height *= 0.55;
+ ulTL.x = 0;
+ ulTL.y = AbsoluteValue(metrics.descent) - line_height;
+ ulBR.x = metrics.width;
+ ulBR.y = AbsoluteValue(metrics.descent);
+
+ DrawRectangle(WmfDrawContext,
+ XC(ulTL.x), YC(ulTL.y), XC(ulBR.x), YC(ulBR.y));
+ }
+
+ /* Strikeout text the Windows way */
+ if (WMF_TEXT_STRIKEOUT(font))
+ {
+ double line_height;
+
+ wmfD_Coord
+ ulBR, /* bottom right of strikeout rectangle */
+ ulTL; /* top left of strikeout rectangle */
+
+ line_height = ((double)1/(ddata->scale_x))*metrics.underline_thickness;
+
+ if(metrics.underline_thickness < 2.0)
+ line_height *= 0.55;
+ ulTL.x = 0;
+ ulTL.y = -(((double) metrics.ascent) / 2 + line_height / 2);
+ ulBR.x = metrics.width;
+ ulBR.y = -(((double) metrics.ascent) / 2 - line_height / 2);
+
+ DrawRectangle(WmfDrawContext,
+ XC(ulTL.x), YC(ulTL.y), XC(ulBR.x), YC(ulBR.y));
+
+ }
+
+ /* Restore graphic context */
+ DrawPopGraphicContext(WmfDrawContext);
+
+#if 0
+ DrawPushGraphicContext(WmfDrawContext);
+ DrawSetStrokeColorString(WmfDrawContext,"red");
+ DrawSetFillColorString(WmfDrawContext,"none");
+ DrawRectangle(WmfDrawContext,
+ XC(TL.x), YC(TL.y),
+ XC(BR.x), YC(BR.y));
+ DrawSetStrokeColorString(WmfDrawContext,"none");
+ DrawPopGraphicContext(WmfDrawContext);
+#endif
+
+}
+
+static void ipa_udata_init(wmfAPI *API, wmfUserData_t *userdata)
+{
+ ARG_NOT_USED(API);
+ ARG_NOT_USED(userdata);
+ /* wmf_magick_t* ddata = WMF_MAGICK_GetData (API); */
+
+}
+
+static void ipa_udata_copy(wmfAPI *API, wmfUserData_t *userdata)
+{
+ ARG_NOT_USED(API);
+ ARG_NOT_USED(userdata);
+ /* wmf_magick_t* ddata = WMF_MAGICK_GetData (API); */
+
+}
+
+static void ipa_udata_set(wmfAPI *API, wmfUserData_t *userdata)
+{
+ ARG_NOT_USED(API);
+ ARG_NOT_USED(userdata);
+ /* wmf_magick_t* ddata = WMF_MAGICK_GetData (API); */
+
+}
+
+static void ipa_udata_free(wmfAPI *API, wmfUserData_t *userdata)
+{
+ ARG_NOT_USED(API);
+ ARG_NOT_USED(userdata);
+ /* wmf_magick_t* ddata = WMF_MAGICK_GetData (API); */
+
+}
+
+static void util_set_brush(wmfAPI * API, wmfDC * dc, const BrushApply brush_apply)
+{
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ wmfBrush
+ *brush = WMF_DC_BRUSH(dc);
+
+ /* Set polygon fill rule */
+ switch (WMF_DC_POLYFILL(dc)) /* Is this correct ?? */
+ {
+ case WINDING:
+ DrawSetClipRule(WmfDrawContext,NonZeroRule);
+ break;
+
+ case ALTERNATE:
+ default:
+ DrawSetClipRule(WmfDrawContext,EvenOddRule);
+ break;
+ }
+
+ switch (WMF_BRUSH_STYLE(brush))
+ {
+ case BS_SOLID /* 0 */:
+ /* WMF_BRUSH_COLOR specifies brush color, WMF_BRUSH_HATCH
+ ignored */
+ {
+ if( brush_apply == BrushApplyStroke )
+ draw_color_stroke_rgb(API,WMF_BRUSH_COLOR(brush));
+ else
+ draw_color_fill_rgb(API,WMF_BRUSH_COLOR(brush));
+ break;
+ }
+ case BS_HOLLOW /* 1 */: /* BS_HOLLOW & BS_NULL share enum */
+ /* WMF_BRUSH_COLOR and WMF_BRUSH_HATCH ignored */
+ {
+ if( brush_apply == BrushApplyStroke )
+ DrawSetStrokeColorString(WmfDrawContext,"none");
+ else
+ DrawSetFillColorString(WmfDrawContext,"none");
+ break;
+ }
+ case BS_HATCHED /* 2 */:
+ /* WMF_BRUSH_COLOR specifies the hatch color, WMF_BRUSH_HATCH
+ specifies the hatch brush style. If WMF_DC_OPAQUE, then
+ WMF_DC_BACKGROUND specifies hatch background color. */
+ {
+ DrawPushDefs(WmfDrawContext);
+ draw_pattern_push(API, ddata->pattern_id, 8, 8);
+ DrawPushGraphicContext(WmfDrawContext);
+
+ if (WMF_DC_OPAQUE(dc))
+ {
+ if( brush_apply == BrushApplyStroke )
+ draw_color_stroke_rgb(API,WMF_DC_BACKGROUND(dc));
+ else
+ draw_color_fill_rgb(API,WMF_DC_BACKGROUND(dc));
+
+ DrawRectangle(WmfDrawContext, 0, 0, 7, 7 );
+ }
+
+ DrawSetStrokeAntialias(WmfDrawContext, False);
+ DrawSetStrokeWidth(WmfDrawContext, 1);
+
+ draw_color_stroke_rgb(API,WMF_BRUSH_COLOR(brush));
+
+ switch ((unsigned int) WMF_BRUSH_HATCH(brush))
+ {
+
+ case HS_HORIZONTAL: /* ----- */
+ {
+ DrawLine(WmfDrawContext, 0, 3, 7,3);
+ break;
+ }
+ case HS_VERTICAL: /* ||||| */
+ {
+ DrawLine(WmfDrawContext, 3, 0, 3, 7);
+ break;
+ }
+ case HS_FDIAGONAL: /* \\\\\ */
+ {
+ DrawLine(WmfDrawContext, 0, 0, 7, 7);
+ break;
+ }
+ case HS_BDIAGONAL: /* ///// */
+ {
+ DrawLine(WmfDrawContext, 0, 7, 7, 0 );
+ break;
+ }
+ case HS_CROSS: /* +++++ */
+ {
+ DrawLine(WmfDrawContext, 0, 3, 7, 3 );
+ DrawLine(WmfDrawContext, 3, 0, 3, 7 );
+ break;
+ }
+ case HS_DIAGCROSS: /* xxxxx */
+ {
+ DrawLine(WmfDrawContext, 0, 0, 7, 7 );
+ DrawLine(WmfDrawContext, 0, 7, 7, 0 );
+ break;
+ }
+ default:
+ {
+ (void) printf("util_set_brush: unexpected brush hatch enumeration %u\n",
+ (unsigned int)WMF_BRUSH_HATCH(brush));
+ }
+ }
+ DrawPopGraphicContext(WmfDrawContext);
+ DrawPopPattern(WmfDrawContext);
+ DrawPopDefs(WmfDrawContext);
+ {
+ char
+ pattern_id[MaxTextExtent];
+
+ FormatString(pattern_id, "#brush_%lu", ddata->pattern_id);
+
+ if( brush_apply == BrushApplyStroke )
+ DrawSetStrokePatternURL(WmfDrawContext,pattern_id);
+ else
+ DrawSetFillPatternURL(WmfDrawContext,pattern_id);
+ ++ddata->pattern_id;
+ }
+ break;
+ }
+ case BS_PATTERN /* 3 */:
+ /* WMF_BRUSH_COLOR ignored, WMF_BRUSH_HATCH provides handle to
+ bitmap */
+ {
+ (void) printf("util_set_brush: BS_PATTERN not supported\n");
+ break;
+ }
+ case BS_INDEXED /* 4 */:
+ {
+ (void) printf("util_set_brush: BS_INDEXED not supported\n");
+ break;
+ }
+ case BS_DIBPATTERN /* 5 */:
+ {
+ wmfBMP
+ *brush_bmp = WMF_BRUSH_BITMAP(brush);
+
+ if (brush_bmp && brush_bmp->data != 0)
+ {
+ CompositeOperator
+ mode;
+
+ const Image
+ *image;
+
+ ExceptionInfo
+ exception;
+
+ GetExceptionInfo(&exception);
+
+ image = (Image*)brush_bmp->data;
+
+ mode = CopyCompositeOp; /* Default is copy */
+ switch (WMF_DC_ROP(dc))
+ {
+ /* Binary raster ops */
+ case R2_BLACK:
+ (void) printf("util_set_brush: R2_BLACK ROP2 mode not supported!\n");
+ break;
+ case R2_NOTMERGEPEN:
+ (void) printf("util_set_brush: R2_NOTMERGEPEN ROP2 mode not supported!\n");
+ break;
+ case R2_MASKNOTPEN:
+ (void) printf("util_set_brush R2_MASKNOTPEN ROP2 mode not supported!\n");
+ break;
+ case R2_NOTCOPYPEN:
+ (void) printf("util_set_brush: R2_NOTCOPYPEN ROP2 mode not supported!\n");
+ break;
+ case R2_MASKPENNOT:
+ (void) printf("util_set_brush: R2_MASKPENNOT ROP2 mode not supported!\n");
+ break;
+ case R2_NOT:
+ (void) printf("util_set_brush: R2_NOT ROP2 mode not supported!\n");
+ break;
+ case R2_XORPEN:
+ (void) printf("util_set_brush: R2_XORPEN ROP2 mode not supported!\n");
+ break;
+ case R2_NOTMASKPEN:
+ (void) printf("util_set_brush: R2_NOTMASKPEN ROP2 mode not supported!\n");
+ break;
+ case R2_MASKPEN:
+ (void) printf("util_set_brush: R2_MASKPEN ROP2 mode not supported!\n");
+ break;
+ case R2_NOTXORPEN:
+ (void) printf("util_set_brush: R2_NOTXORPEN ROP2 mode not supported!\n");
+ break;
+ case R2_NOP:
+ (void) printf("util_set_brush: R2_NOP ROP2 mode not supported!\n");
+ break;
+ case R2_MERGENOTPEN:
+ (void) printf("util_set_brush: R2_MERGENOTPEN ROP2 mode not supported!\n");
+ break;
+ case R2_COPYPEN:
+ mode = CopyCompositeOp;
+ break;
+ case R2_MERGEPENNOT:
+ (void) printf("util_set_brush: R2_MERGEPENNOT ROP2 mode not supported!\n");
+ break;
+ case R2_MERGEPEN:
+ (void) printf("util_set_brush: R2_MERGEPEN ROP2 mode not supported!\n");
+ break;
+ case R2_WHITE:
+ (void) printf("util_set_brush: R2_WHITE ROP2 mode not supported!\n");
+ break;
+ default:
+ {
+ (void) printf("util_set_brush: unexpected ROP2 enumeration %u!\n",
+ (unsigned int)WMF_DC_ROP(dc));
+ }
+ }
+
+ DrawPushDefs(WmfDrawContext);
+ draw_pattern_push(API, ddata->pattern_id, brush_bmp->width, brush_bmp->height);
+ DrawComposite(WmfDrawContext,mode, 0, 0, brush_bmp->width, brush_bmp->height, image);
+ DrawPopPattern(WmfDrawContext);
+ DrawPopDefs(WmfDrawContext);
+
+ {
+ char
+ pattern_id[MaxTextExtent];
+
+ FormatString(pattern_id, "#brush_%lu", ddata->pattern_id);
+
+ if( brush_apply == BrushApplyStroke )
+ DrawSetStrokePatternURL(WmfDrawContext,pattern_id);
+ else
+ DrawSetFillPatternURL(WmfDrawContext,pattern_id);
+ ++ddata->pattern_id;
+ }
+ }
+ else
+ (void) printf("util_set_brush: no BMP image data!\n");
+
+ break;
+ }
+ case BS_DIBPATTERNPT /* 6 */:
+ /* WMF_BRUSH_COLOR ignored, WMF_BRUSH_HATCH provides pointer to
+ DIB */
+ {
+ (void) printf("util_set_brush: BS_DIBPATTERNPT not supported\n");
+ break;
+ }
+ case BS_PATTERN8X8 /* 7 */:
+ {
+ (void) printf("util_set_brush: BS_PATTERN8X8 not supported\n");
+ break;
+ }
+ case BS_DIBPATTERN8X8 /* 8 */:
+ {
+ (void) printf("util_set_brush: BS_DIBPATTERN8X8 not supported\n");
+ break;
+ }
+ default:
+ {
+ }
+ }
+}
+
+static void util_set_pen(wmfAPI * API, wmfDC * dc)
+{
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ wmfPen
+ *pen = 0;
+
+ double
+ pen_width,
+ pixel_width;
+
+ unsigned int
+ pen_style;
+
+/* unsigned int */
+/* pen_type; */
+
+ pen = WMF_DC_PEN(dc);
+
+ pen_width = (WMF_PEN_WIDTH(pen) + WMF_PEN_HEIGHT(pen)) / 2;
+
+ /* Pixel width is inverse of pixel scale */
+ pixel_width = (((double) 1 / (ddata->scale_x)) +
+ ((double) 1 / (ddata->scale_y))) / 2;
+
+ /* Don't allow pen_width to be much less than pixel_width in order
+ to avoid dissapearing or spider-web lines */
+ pen_width = Max(pen_width, pixel_width*0.8);
+
+ pen_style = (unsigned int) WMF_PEN_STYLE(pen);
+ /* pen_type = (unsigned int) WMF_PEN_TYPE(pen); */
+
+ /* Pen style specified? */
+ if (pen_style == PS_NULL)
+ {
+ DrawSetStrokeColorString(WmfDrawContext,"none");
+ return;
+ }
+
+ DrawSetStrokeAntialias(WmfDrawContext, 1 );
+ DrawSetStrokeWidth(WmfDrawContext, Max(0, pen_width));
+
+ {
+ LineCap
+ linecap;
+
+ switch ((unsigned int) WMF_PEN_ENDCAP(pen))
+ {
+ case PS_ENDCAP_SQUARE:
+ linecap = SquareCap;
+ break;
+ case PS_ENDCAP_ROUND:
+ linecap = RoundCap;
+ break;
+ case PS_ENDCAP_FLAT:
+ default:
+ linecap = ButtCap;
+ break;
+ }
+ DrawSetStrokeLineCap(WmfDrawContext, linecap);
+ }
+
+ {
+ LineJoin
+ linejoin;
+
+ switch ((unsigned int) WMF_PEN_JOIN(pen))
+ {
+ case PS_JOIN_BEVEL:
+ linejoin = BevelJoin;
+ break;
+ case PS_JOIN_ROUND:
+ linejoin = RoundJoin;
+ break;
+ case PS_JOIN_MITER:
+ default:
+ linejoin = MiterJoin;
+ break;
+ }
+ DrawSetStrokeLineJoin(WmfDrawContext,linejoin);
+ }
+
+ {
+ double
+ dasharray[7];
+
+ switch (pen_style)
+ {
+ case PS_DASH: /* ------- */
+ {
+ /* Pattern 18,7 */
+ dasharray[0] = pixel_width * 18;
+ dasharray[1] = pixel_width * 7;
+ dasharray[2] = 0;
+
+ DrawSetStrokeAntialias(WmfDrawContext,False);
+ DrawSetStrokeDashArray(WmfDrawContext,2,dasharray);
+ break;
+ }
+ case PS_ALTERNATE:
+ case PS_DOT: /* ....... */
+ {
+ /* Pattern 3,3 */
+ dasharray[0] = pixel_width * 3;
+ dasharray[1] = pixel_width * 3;
+ dasharray[2] = 0;
+
+ DrawSetStrokeAntialias(WmfDrawContext,False);
+ DrawSetStrokeDashArray(WmfDrawContext,2,dasharray);
+ break;
+ }
+ case PS_DASHDOT: /* _._._._ */
+ {
+ /* Pattern 9,6,3,6 */
+ dasharray[0] = pixel_width * 9;
+ dasharray[1] = pixel_width * 6;
+ dasharray[2] = pixel_width * 3;
+ dasharray[3] = pixel_width * 6;
+ dasharray[4] = 0;
+
+ DrawSetStrokeAntialias(WmfDrawContext,False);
+ DrawSetStrokeDashArray(WmfDrawContext,4,dasharray);
+ break;
+ }
+ case PS_DASHDOTDOT: /* _.._.._ */
+ {
+ /* Pattern 9,3,3,3,3,3 */
+ dasharray[0] = pixel_width * 9;
+ dasharray[1] = pixel_width * 3;
+ dasharray[2] = pixel_width * 3;
+ dasharray[3] = pixel_width * 3;
+ dasharray[4] = pixel_width * 3;
+ dasharray[5] = pixel_width * 3;
+ dasharray[6] = 0;
+
+ DrawSetStrokeAntialias(WmfDrawContext,False);
+ DrawSetStrokeDashArray(WmfDrawContext,6,dasharray);
+ break;
+ }
+ case PS_INSIDEFRAME: /* There is nothing to do in this case... */
+ case PS_SOLID:
+ default:
+ {
+ DrawSetStrokeDashArray(WmfDrawContext,0,(double *)NULL);
+ break;
+ }
+ }
+ }
+
+ draw_color_stroke_rgb(API,WMF_PEN_COLOR(pen));
+}
+
+/* Estimate font pointsize based on Windows font parameters */
+static double util_pointsize( wmfAPI* API, wmfFont* font, char* str, double font_height)
+{
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ Image
+ *image = ddata->image;
+
+ TypeMetric
+ metrics;
+
+ DrawInfo
+ *draw_info;
+
+ double
+ pointsize = 0.0;
+
+ draw_info=ddata->draw_info;
+ if (draw_info == (const DrawInfo *) NULL)
+ return 0;
+
+ draw_info->font=WMF_FONT_PSNAME(font);
+ draw_info->pointsize=font_height;
+ draw_info->text=str;
+
+ if (GetTypeMetrics(image, draw_info, &metrics) != False)
+ {
+
+ if(strlen(str) == 1)
+ {
+ pointsize = (font_height *
+ ( font_height / (metrics.ascent + AbsoluteValue(metrics.descent))));
+ draw_info->pointsize = pointsize;
+ if (GetTypeMetrics(image, draw_info, &metrics) != False)
+ pointsize *= (font_height / ( metrics.ascent + AbsoluteValue(metrics.descent)));
+ }
+ else
+ {
+ pointsize = (font_height * (font_height / (metrics.height)));
+ draw_info->pointsize = pointsize;
+ if (GetTypeMetrics(image, draw_info, &metrics) != False)
+ pointsize *= (font_height / metrics.height);
+
+ }
+
+
+#if 0
+ draw_info->pointsize = pointsize;
+ if (GetTypeMetrics(image, draw_info, &metrics) != False)
+ pointsize *= (font_height / (metrics.ascent + AbsoluteValue(metrics.descent)));
+ pointsize *= 1.114286; /* Magic number computed through trial and error */
+#endif
+ }
+ draw_info->font=NULL;
+ draw_info->text=NULL;
+#if 0
+ printf("String = %s\n", str);
+ printf("Font = %s\n", WMF_FONT_PSNAME(font));
+ printf("lfHeight = %.4g\n", font_height);
+ printf("bounds = %.4g,%.4g %.4g,%.4g\n", metrics.bounds.x1, metrics.bounds.y1,
+ metrics.bounds.x2,metrics.bounds.y2);
+ printf("ascent = %.4g\n", metrics.ascent);
+ printf("descent = %.4g\n", metrics.descent);
+ printf("height = %.4g\n", metrics.height);
+ printf("Pointsize = %.4g\n", pointsize);
+#endif
+
+ return floor(pointsize);
+}
+
+#if defined(HasWMFlite)
+/* Estimate weight based on font name */
+static int util_font_weight( const char* font )
+{
+ int
+ weight;
+
+ weight = 400;
+ if((strstr(font,"Normal") || strstr(font,"Regular")))
+ weight = 400;
+ else if( strstr(font,"Bold") )
+ {
+ weight = 700;
+ if((strstr(font,"Semi") || strstr(font,"Demi")))
+ weight = 600;
+ if( (strstr(font,"Extra") || strstr(font,"Ultra")))
+ weight = 800;
+ }
+ else if( strstr(font,"Light") )
+ {
+ weight = 300;
+ if( (strstr(font,"Extra") || strstr(font,"Ultra")))
+ weight = 200;
+ }
+ else if((strstr(font,"Heavy") || strstr(font,"Black")))
+ weight = 900;
+ else if( strstr(font,"Thin") )
+ weight = 100;
+ return weight;
+}
+
+/*
+ * Returns width of string in points, assuming (unstretched) font size of 1pt
+ * (similar to wmf_ipa_font_stringwidth)
+ *
+ * This is extremely odd at best, particularly since player/meta.h has access
+ * to the corrected font_height (as drawtext.font_height) when it invokes the
+ * stringwidth callback. It should be possible to compute the real stringwidth!
+ *
+ * For the moment it seems to do the least harm to simply return 0.
+ */
+static float lite_font_stringwidth( wmfAPI* API, wmfFont* font, char* str)
+{
+#if 0
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ Image
+ *image = ddata->image;
+
+ DrawInfo
+ *draw_info;
+
+ TypeMetric
+ metrics;
+
+ float
+ stringwidth = 0;
+
+ double
+ orig_x_resolution,
+ orig_y_resolution;
+
+ ResolutionType
+ orig_resolution_units;
+
+ orig_x_resolution = image->x_resolution;
+ orig_y_resolution = image->y_resolution;
+ orig_resolution_units = image->units;
+
+ draw_info=ddata->draw_info;
+ if (draw_info == (const DrawInfo *) NULL)
+ return 0;
+
+ draw_info->font=WMF_FONT_PSNAME(font);
+ draw_info->pointsize=12;
+ draw_info->text=str;
+
+ image->x_resolution = 72;
+ image->y_resolution = 72;
+ image->units = PixelsPerInchResolution;
+
+ if (GetTypeMetrics(image, draw_info, &metrics) != False)
+ stringwidth = ((metrics.width * 72)/(image->x_resolution * draw_info->pointsize)); /* *0.916348; */
+
+ draw_info->font=NULL;
+ draw_info->text=NULL;
+
+#if 0
+ printf("\nlite_font_stringwidth\n");
+ printf("string = \"%s\"\n", str);
+ printf("WMF_FONT_NAME = \"%s\"\n", WMF_FONT_NAME(font));
+ printf("WMF_FONT_PSNAME = \"%s\"\n", WMF_FONT_PSNAME(font));
+ printf("stringwidth = %.4g\n", stringwidth);
+ /* printf("WMF_FONT_HEIGHT = %i\n", (int)WMF_FONT_HEIGHT(font)); */
+ /* printf("WMF_FONT_WIDTH = %i\n", (int)WMF_FONT_WIDTH(font)); */
+ fflush(stdout);
+#endif
+
+ image->x_resolution = orig_x_resolution;
+ image->y_resolution = orig_y_resolution;
+ image->units = orig_resolution_units;
+
+ return stringwidth;
+#else
+ (void) API;
+ (void) font;
+ (void) str;
+
+ return 0;
+#endif
+}
+
+/* Map font (similar to wmf_ipa_font_map) */
+
+/* Mappings to Postscript fonts: family, normal, italic, bold, bolditalic */
+static const wmfFontMap WMFFontMap[] = {
+ { "Courier", "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique" },
+ { "Helvetica", "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique" },
+ { "Modern", "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique" },
+ { "Monotype Corsiva", "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique" },
+ { "News Gothic", "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique" },
+ { "Symbol", "Symbol", "Symbol", "Symbol", "Symbol" },
+ { "System", "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique" },
+ { "Times", "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic" },
+ { NULL, NULL, NULL, NULL, NULL }
+};
+
+/* Mapping between base name and Ghostscript family name */
+static const wmfMapping SubFontMap[] = {
+ { "Arial", "Helvetica", (FT_Encoding) 0 },
+ { "Courier", "Courier", (FT_Encoding) 0 },
+ { "Fixed", "Courier", (FT_Encoding) 0 },
+ { "Helvetica", "Helvetica", (FT_Encoding) 0 },
+ { "Sans", "Helvetica", (FT_Encoding) 0 },
+ { "Sym", "Symbol", (FT_Encoding) 0 },
+ { "Terminal", "Courier", (FT_Encoding) 0 },
+ { "Times", "Times", (FT_Encoding) 0 },
+ { "Wingdings", "Symbol", (FT_Encoding) 0 },
+ { NULL, NULL, (FT_Encoding) 0 }
+};
+
+static void lite_font_map( wmfAPI* API, wmfFont* font)
+{
+ wmfFontData
+ *font_data;
+
+ wmf_magick_font_t
+ *magick_font;
+
+ wmf_magick_t
+ *ddata = WMF_MAGICK_GetData(API);
+
+ ExceptionInfo
+ exception;
+
+ const TypeInfo
+ *type_info,
+ *type_info_base;
+
+ const char
+ *wmf_font_name;
+
+ if (font == 0)
+ return;
+
+ font_data = (wmfFontData*)API->font_data;
+ font->user_data = font_data->user_data;
+ magick_font = (wmf_magick_font_t*)font->user_data;
+ wmf_font_name = WMF_FONT_NAME(font);
+
+ MagickFreeMemory(magick_font->ps_name);
+
+ GetExceptionInfo(&exception);
+ type_info_base=GetTypeInfo("*",&exception);
+ if(type_info_base == 0)
+ {
+ CopyException(&ddata->image->exception,&exception);
+ return;
+ }
+
+ /* Certain short-hand font names are not the proper Windows names
+ and should be promoted to the proper names */
+ if(LocaleCompare(wmf_font_name,"Times") == 0)
+ wmf_font_name = "Times New Roman";
+ else if(LocaleCompare(wmf_font_name,"Courier") == 0)
+ wmf_font_name = "Courier New";
+
+ /* Look for a family-based best-match */
+ if(!magick_font->ps_name)
+ {
+ int
+ target_weight,
+ best_weight = 0;
+
+ if( WMF_FONT_WEIGHT(font) == 0 )
+ target_weight = 400;
+ else
+ target_weight = WMF_FONT_WEIGHT(font);
+
+ /* printf("Desired weight = %i\n", WMF_FONT_WEIGHT(font)); */
+ for ( type_info=(TypeInfo *) type_info_base; type_info != 0; type_info=type_info->next )
+ {
+ if(LocaleCompare(wmf_font_name,type_info->family) == 0)
+ {
+ int
+ weight;
+
+ /* printf("Considering font %s\n", type_info->description); */
+
+ if( WMF_FONT_ITALIC(font) && !(strstr(type_info->description,"Italic") ||
+ strstr(type_info->description,"Oblique")) )
+ continue;
+
+ weight = util_font_weight( type_info->description );
+ /* printf("Estimated weight = %.4g\n", weight); */
+
+ if( abs(weight - target_weight) < abs(best_weight - target_weight) )
+ {
+ best_weight = weight;
+ (void) CloneString(&magick_font->ps_name,type_info->name);
+ }
+ }
+ }
+ }
+
+ /* Look for exact full match */
+ if(!magick_font->ps_name)
+ {
+ for ( type_info=(TypeInfo *) type_info_base; type_info != 0; type_info=type_info->next)
+ {
+ if(LocaleCompare(wmf_font_name,type_info->description) == 0)
+ {
+ (void) CloneString(&magick_font->ps_name,type_info->name);
+ break;
+ }
+ }
+ }
+
+ /* Now let's try simple substitution mappings from WMFFontMap */
+ if(!magick_font->ps_name)
+ {
+ char
+ target[MaxTextExtent];
+
+ int
+ target_weight = 400,
+ want_italic = False,
+ want_bold = False,
+ i;
+
+ if( WMF_FONT_WEIGHT(font) != 0 )
+ target_weight = WMF_FONT_WEIGHT(font);
+
+ if( (target_weight > 550) || ((strstr(wmf_font_name,"Bold") ||
+ strstr(wmf_font_name,"Heavy") ||
+ strstr(wmf_font_name,"Black"))) )
+ want_bold = True;
+
+ if( (WMF_FONT_ITALIC(font)) || ((strstr(wmf_font_name,"Italic") ||
+ strstr(wmf_font_name,"Oblique"))) )
+ want_italic = True;
+
+ (void) strcpy(target,"Times");
+ for( i=0; SubFontMap[i].name != NULL; i++ )
+ {
+ if(LocaleCompare(wmf_font_name, SubFontMap[i].name) == 0)
+ {
+ (void) strlcpy(target,SubFontMap[i].mapping,sizeof(target));
+ break;
+ }
+ }
+
+ for( i=0; WMFFontMap[i].name != NULL; i++ )
+ {
+ if(LocaleNCompare(WMFFontMap[i].name,target,strlen(WMFFontMap[i].name)) == 0)
+ {
+ if(want_bold && want_italic)
+ (void) CloneString(&magick_font->ps_name,WMFFontMap[i].bolditalic);
+ else if(want_italic)
+ (void) CloneString(&magick_font->ps_name,WMFFontMap[i].italic);
+ else if(want_bold)
+ (void) CloneString(&magick_font->ps_name,WMFFontMap[i].bold);
+ else
+ (void) CloneString(&magick_font->ps_name,WMFFontMap[i].normal);
+ }
+ }
+ }
+
+#if 0
+ printf("\nlite_font_map\n");
+ printf("WMF_FONT_NAME = \"%s\"\n", WMF_FONT_NAME(font));
+ printf("WMF_FONT_WEIGHT = %i\n", WMF_FONT_WEIGHT(font));
+ printf("WMF_FONT_PSNAME = \"%s\"\n", WMF_FONT_PSNAME(font));
+ fflush(stdout);
+#endif
+
+}
+
+/* Initialize API font structures */
+static void lite_font_init( wmfAPI* API, wmfAPI_Options* options)
+{
+ wmfFontData
+ *font_data;
+
+ ARG_NOT_USED(options);
+ API->fonts = 0;
+
+ /* Allocate wmfFontData data structure */
+ API->font_data = wmf_malloc(API,sizeof(wmfFontData));
+ if (ERR (API))
+ return;
+
+ font_data = (wmfFontData*)API->font_data;
+
+ /* Assign function to map font (type wmfMap) */
+ font_data->map = lite_font_map;
+
+ /* Assign function to return string width in points (type wmfStringWidth) */
+ font_data->stringwidth = lite_font_stringwidth;
+
+ /* Assign user data, not used by libwmflite (type void*) */
+ font_data->user_data = wmf_malloc(API,sizeof(wmf_magick_font_t));
+ if(ERR(API))
+ return;
+ ((wmf_magick_font_t*)font_data->user_data)->ps_name = 0;
+ ((wmf_magick_font_t*)font_data->user_data)->pointsize = 0;
+}
+
+#endif /* HasWMFlite */
+
+/* BLOB read byte */
+static int ipa_blob_read(void* context)
+{
+ return ReadBlobByte((Image*)context);
+}
+
+/* BLOB seek */
+static int ipa_blob_seek(void* context,long position)
+{
+ return (int)SeekBlob((Image*)context,(ExtendedSignedIntegralType)position,SEEK_SET);
+}
+
+/* BLOB tell */
+static long ipa_blob_tell(void* context)
+{
+ return (long)TellBlob((Image*)context);
+}
+
+static Image *ReadWMFImage(const ImageInfo * image_info, ExceptionInfo * exception)
+{
+ Image
+ *image;
+
+ float
+ wmf_width,
+ wmf_height;
+
+ double
+ bounding_height,
+ bounding_width,
+ image_height,
+ image_height_inch,
+ image_width,
+ image_width_inch,
+ resolution_y,
+ resolution_x,
+ units_per_inch;
+
+ unsigned int
+ logging;
+
+ unsigned long
+ wmf_options_flags = 0;
+
+ wmf_error_t
+ wmf_error_code;
+
+ wmf_magick_t
+ *ddata = 0;
+
+ wmfAPI
+ *API = 0;
+
+ wmfAPI_Options
+ wmf_api_options;
+
+ wmfD_Rect
+ bbox;
+
+ logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadWMFImage()");
+
+ image = AllocateImage(image_info);
+ if (!OpenBlob(image_info,image,ReadBinaryBlobMode,exception))
+ {
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," OpenBlob failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
+ }
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+
+ /*
+ * Create WMF API
+ *
+ */
+
+ /* Register callbacks */
+ wmf_options_flags |= WMF_OPT_FUNCTION;
+ (void) memset(&wmf_api_options, 0, sizeof(wmf_api_options));
+ wmf_api_options.function = ipa_functions;
+
+ /* Ignore non-fatal errors */
+ wmf_options_flags |= WMF_OPT_IGNORE_NONFATAL;
+
+ wmf_error_code = wmf_api_create(&API, wmf_options_flags, &wmf_api_options);
+ if (wmf_error_code != wmf_E_None)
+ {
+ if (API)
+ (void) wmf_api_destroy(API);
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," wmf_api_create failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
+ }
+ ThrowReaderException(DelegateError,UnableToInitializeWMFLibrary,image);
+ }
+
+ /* Register progress monitor */
+ wmf_status_function(API,(void*)"[%s] Parsing vectors...", magick_progress_callback);
+
+ ddata = WMF_MAGICK_GetData(API);
+ ddata->image = image;
+ ddata->image_info = image_info;
+ ddata->draw_info = CloneDrawInfo((const ImageInfo *) NULL, (const DrawInfo *) NULL);
+ MagickFreeMemory(ddata->draw_info->font);
+ MagickFreeMemory(ddata->draw_info->text);
+
+#if defined(HasWMFlite)
+ /* Must initialize font subystem for WMFlite interface */
+ lite_font_init (API,&wmf_api_options); /* similar to wmf_ipa_font_init in src/font.c */
+ /* wmf_arg_fontdirs (API,options); */ /* similar to wmf_arg_fontdirs in src/wmf.c */
+
+#endif
+
+ /*
+ * Open BLOB input via libwmf API
+ *
+ */
+ wmf_error_code = wmf_bbuf_input(API,ipa_blob_read,ipa_blob_seek,
+ ipa_blob_tell,(void*)image);
+ if (wmf_error_code != wmf_E_None)
+ {
+ if(logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," wmf_bbuf_input failed");
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
+ }
+ ipa_device_close(API);
+ (void) wmf_api_destroy(API);
+ ThrowReaderException(FileOpenError,UnableToOpenFile, image);
+ }
+
+ /*
+ * Scan WMF file
+ *
+ */
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Scanning WMF to obtain bounding box");
+ wmf_error_code = wmf_scan(API, 0, &bbox);
+ if (wmf_error_code != wmf_E_None)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," wmf_scan failed with wmf_error_code %d", wmf_error_code);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
+ }
+ ipa_device_close(API);
+ (void) wmf_api_destroy(API);
+ ThrowReaderException(DelegateError,FailedToScanFile,image);
+ }
+
+ /*
+ * Compute dimensions and scale factors
+ *
+ */
+
+ ddata->bbox = bbox;
+
+ /* User specified resolution */
+ resolution_y = 72.0;
+ if (image->y_resolution > 0)
+ {
+ resolution_y = image->y_resolution;
+ if (image->units == PixelsPerCentimeterResolution)
+ resolution_y *= CENTIMETERS_PER_INCH;
+ }
+
+ resolution_x = 72.0;
+ if (image->x_resolution > 0)
+ {
+ resolution_x = image->x_resolution;
+ if (image->units == PixelsPerCentimeterResolution)
+ resolution_x *= CENTIMETERS_PER_INCH;
+ }
+
+ /* Obtain output size expressed in metafile units */
+ wmf_error_code = wmf_size(API, &wmf_width, &wmf_height);
+ if (wmf_error_code != wmf_E_None)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," wmf_size failed with wmf_error_code %d", wmf_error_code);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
+ }
+ ipa_device_close(API);
+ (void) wmf_api_destroy(API);
+ ThrowReaderException(DelegateError,FailedToComputeOutputSize,image);
+ }
+
+ /* Obtain (or guess) metafile units */
+ if ((API)->File->placeable)
+ units_per_inch = (API)->File->pmh->Inch;
+ else if( (wmf_width*wmf_height) < 1024*1024)
+ units_per_inch = POINTS_PER_INCH; /* MM_TEXT */
+ else
+ units_per_inch = TWIPS_PER_INCH; /* MM_TWIPS */
+
+ /* Calculate image width and height based on specified DPI
+ resolution */
+ image_width_inch = (double) wmf_width / units_per_inch;
+ image_height_inch = (double) wmf_height / units_per_inch;
+ image_width = image_width_inch * resolution_x;
+ image_height = image_height_inch * resolution_y;
+
+ /* Compute bounding box scale factors and origin translations
+ *
+ * This is all just a hack since libwmf does not currently seem to
+ * provide the mapping between LOGICAL coordinates and DEVICE
+ * coordinates. This mapping is necessary in order to know
+ * where to place the logical bounding box within the image.
+ *
+ */
+
+ bounding_width = bbox.BR.x - bbox.TL.x;
+ bounding_height = bbox.BR.y - bbox.TL.y;
+
+ ddata->scale_x = image_width/bounding_width;
+ ddata->translate_x = 0-bbox.TL.x;
+ ddata->rotate = 0;
+
+ /* Heuristic: guess that if the vertical coordinates mostly span
+ negative values, then the image must be inverted. */
+ if( AbsoluteValue(bbox.BR.y) > AbsoluteValue(bbox.TL.y) )
+ {
+ /* Normal (Origin at top left of image) */
+ ddata->scale_y = (image_height/bounding_height);
+ ddata->translate_y = 0-bbox.TL.y;
+ }
+ else
+ {
+ /* Inverted (Origin at bottom left of image) */
+ ddata->scale_y = (-image_height/bounding_height);
+ ddata->translate_y = 0-bbox.BR.y;
+ }
+
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Placeable metafile: %s",
+ (API)->File->placeable ? "Yes" : "No");
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Size in metafile units: %.4gx%.4g",
+ wmf_width, wmf_height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Metafile units/inch: %.4g",
+ units_per_inch);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Size in inches: %.4gx%.4g",
+ image_width_inch,image_height_inch);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Bounding Box: %.4g,%.4g %.4g,%.4g",
+ bbox.TL.x, bbox.TL.y, bbox.BR.x, bbox.BR.y);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Bounding width x height: %.4gx%.4g",
+ bounding_width, bounding_height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Output resolution: %.4gx%.4g",
+ resolution_x, resolution_y);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Image size: %.4gx%.4g",
+ image_width, image_height);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Bounding box scale factor: %.4g,%.4g",
+ ddata->scale_x, ddata->scale_y);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Translation: %.4g,%.4g",
+ ddata->translate_x, ddata->translate_y);
+ }
+
+#if 0
+#if 0
+ {
+ typedef struct _wmfPlayer_t wmfPlayer_t;
+ struct _wmfPlayer_t
+ {
+ wmfPen default_pen;
+ wmfBrush default_brush;
+ wmfFont default_font;
+
+ wmfDC* dc; /* current dc */
+ };
+
+ wmfDC
+ *dc;
+
+#define WMF_ELICIT_DC(API) (((wmfPlayer_t*)((API)->player_data))->dc)
+
+ dc = WMF_ELICIT_DC(API);
+
+ printf("dc->Window.Ox = %d\n", dc->Window.Ox);
+ printf("dc->Window.Oy = %d\n", dc->Window.Oy);
+ printf("dc->Window.width = %d\n", dc->Window.width);
+ printf("dc->Window.height = %d\n", dc->Window.height);
+ printf("dc->pixel_width = %.4g\n", dc->pixel_width);
+ printf("dc->pixel_height = %.4g\n", dc->pixel_height);
+#if defined(HasWMFlite) /* Only in libwmf 0.3 */
+ printf("dc->Ox = %.d\n", dc->Ox);
+ printf("dc->Oy = %.d\n", dc->Oy);
+ printf("dc->width = %.d\n", dc->width);
+ printf("dc->height = %.d\n", dc->height);
+#endif
+
+ }
+#endif
+
+#endif
+
+ /*
+ * Create canvas image
+ *
+ */
+ image->rows = (unsigned long)ceil(image_height);
+ image->columns = (unsigned long)ceil(image_width);
+
+ if (image_info->ping)
+ {
+ ipa_device_close(API);
+ (void) wmf_api_destroy(API);
+ CloseBlob(image);
+ if(logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
+ return(image);
+ }
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Creating canvas image with size %ldx%ld",
+ image->rows, image->columns);
+
+ /*
+ * Set solid background color
+ */
+ {
+ unsigned long
+ column,
+ row;
+
+ PixelPacket
+ *pixel,
+ background_color;
+
+ background_color = image_info->background_color;
+ image->background_color = background_color;
+ if(background_color.opacity != OpaqueOpacity)
+ image->matte = True;
+
+ for (row=0; row < image->rows; row++)
+ {
+ pixel=SetImagePixels(image,0,row,image->columns,1);
+ if (pixel == (PixelPacket *) NULL)
+ break;
+ for (column=image->columns; column; column--)
+ *pixel++ = background_color;
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+ /*
+ * Play file to generate Vector drawing commands
+ *
+ */
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Playing WMF to prepare vectors");
+
+ wmf_error_code = wmf_play(API, 0, &bbox);
+ if (wmf_error_code != wmf_E_None)
+ {
+ if (logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Playing WMF failed with wmf_error_code %d", wmf_error_code);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
+ }
+ ipa_device_close(API);
+ (void) wmf_api_destroy(API);
+ ThrowReaderException(DelegateError,FailedToRenderFile,image);
+ }
+
+ /*
+ * Scribble on canvas image
+ *
+ */
+
+ if (logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," Rendering WMF vectors");
+ (void) DrawRender(ddata->draw_context);
+
+ /* Cleanup allocated data */
+ (void) wmf_api_destroy(API);
+ CloseBlob(image);
+
+ /* Check for and report any rendering error */
+ if(image->exception.severity != UndefinedException)
+ ThrowException2(exception,
+ CoderWarning,
+ ddata->image->exception.reason,
+ ddata->image->exception.description);
+
+ if(logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"leave ReadWMFImage()");
+
+ /* Return image */
+ return image;
+}
+/* #endif */
+#endif /* HasWMF || HasWMFlite */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r W M F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterWMFImage adds attributes for the WMF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterWMFImage method is:
+%
+% RegisterWMFImage(void)
+%
+*/
+ModuleExport void RegisterWMFImage(void)
+{
+#if defined(HasWMF) || defined(HasWMFlite)
+ MagickInfo
+ *entry;
+
+ static const char
+ *WMFNote =
+ {
+ "Use density to adjust scale (default 72DPI). Use background or\n"
+ "texture to apply a background color or texture under the image."
+ };
+
+ entry = SetMagickInfo("WMF");
+ entry->decoder = ReadWMFImage;
+ entry->description = "Windows Meta File";
+ entry->note=WMFNote;
+ entry->blob_support = True;
+ entry->seekable_stream=True;
+ entry->module = "WMF";
+ (void) RegisterMagickInfo(entry);
+#endif /* HasWMF || HasWMFlite */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r W M F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterWMFImage removes format registrations made by the
+% WMF module from the list of supported formats.
+%
+% The format of the UnregisterWMFImage method is:
+%
+% UnregisterWMFImage(void)
+%
+*/
+ModuleExport void UnregisterWMFImage(void)
+{
+#if defined(HasWMF) || defined(HasWMFlite)
+ (void) UnregisterMagickInfo("WMF");
+#endif /* defined(HasWMF) */
+}
diff --git a/coders/wpg.c b/coders/wpg.c
new file mode 100644
index 0000000..b4b83ca
--- /dev/null
+++ b/coders/wpg.c
@@ -0,0 +1,1481 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% W W PPPP GGGG %
+% W W P P G %
+% W W W PPPP G GGG %
+% WW WW P G G %
+% W W P GGG %
+% %
+% %
+% Read WordPerfect Image Format. %
+% %
+% %
+% Software Design %
+% Jaroslav Fojtik %
+% June 2000 - 2016 %
+% Rework for GraphicsMagick %
+% Bob Friesenhahn %
+% Feb-May 2003 %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/magic.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/shear.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+
+typedef struct
+ {
+ unsigned char Red;
+ unsigned char Blue;
+ unsigned char Green;
+ } RGB_Record;
+
+/* Default palette for WPG level 1 */
+const RGB_Record WPG1_Palette[256]={
+{ 0, 0, 0}, { 0, 0,168},
+{ 0,168, 0}, { 0,168,168},
+{168, 0, 0}, {168, 0,168},
+{168, 84, 0}, {168,168,168},
+{ 84, 84, 84}, { 84, 84,252},
+{ 84,252, 84}, { 84,252,252},
+{252, 84, 84}, {252, 84,252},
+{252,252, 84}, {252,252,252}, /*16*/
+{ 0, 0, 0}, { 20, 20, 20},
+{ 32, 32, 32}, { 44, 44, 44},
+{ 56, 56, 56}, { 68, 68, 68},
+{ 80, 80, 80}, { 96, 96, 96},
+{112,112,112}, {128,128,128},
+{144,144,144}, {160,160,160},
+{180,180,180}, {200,200,200},
+{224,224,224}, {252,252,252}, /*32*/
+{ 0, 0,252}, { 64, 0,252},
+{124, 0,252}, {188, 0,252},
+{252, 0,252}, {252, 0,188},
+{252, 0,124}, {252, 0, 64},
+{252, 0, 0}, {252, 64, 0},
+{252,124, 0}, {252,188, 0},
+{252,252, 0}, {188,252, 0},
+{124,252, 0}, { 64,252, 0}, /*48*/
+{ 0,252, 0}, { 0,252, 64},
+{ 0,252,124}, { 0,252,188},
+{ 0,252,252}, { 0,188,252},
+{ 0,124,252}, { 0, 64,252},
+{124,124,252}, {156,124,252},
+{188,124,252}, {220,124,252},
+{252,124,252}, {252,124,220},
+{252,124,188}, {252,124,156}, /*64*/
+{252,124,124}, {252,156,124},
+{252,188,124}, {252,220,124},
+{252,252,124}, {220,252,124},
+{188,252,124}, {156,252,124},
+{124,252,124}, {124,252,156},
+{124,252,188}, {124,252,220},
+{124,252,252}, {124,220,252},
+{124,188,252}, {124,156,252}, /*80*/
+{180,180,252}, {196,180,252},
+{216,180,252}, {232,180,252},
+{252,180,252}, {252,180,232},
+{252,180,216}, {252,180,196},
+{252,180,180}, {252,196,180},
+{252,216,180}, {252,232,180},
+{252,252,180}, {232,252,180},
+{216,252,180}, {196,252,180}, /*96*/
+{180,220,180}, {180,252,196},
+{180,252,216}, {180,252,232},
+{180,252,252}, {180,232,252},
+{180,216,252}, {180,196,252},
+{0,0,112}, {28,0,112},
+{56,0,112}, {84,0,112},
+{112,0,112}, {112,0,84},
+{112,0,56}, {112,0,28}, /*112*/
+{112,0,0}, {112,28,0},
+{112,56,0}, {112,84,0},
+{112,112,0}, {84,112,0},
+{56,112,0}, {28,112,0},
+{0,112,0}, {0,112,28},
+{0,112,56}, {0,112,84},
+{0,112,112}, {0,84,112},
+{0,56,112}, {0,28,112}, /*128*/
+{56,56,112}, {68,56,112},
+{84,56,112}, {96,56,112},
+{112,56,112}, {112,56,96},
+{112,56,84}, {112,56,68},
+{112,56,56}, {112,68,56},
+{112,84,56}, {112,96,56},
+{112,112,56}, {96,112,56},
+{84,112,56}, {68,112,56}, /*144*/
+{56,112,56}, {56,112,69},
+{56,112,84}, {56,112,96},
+{56,112,112}, {56,96,112},
+{56,84,112}, {56,68,112},
+{80,80,112}, {88,80,112},
+{96,80,112}, {104,80,112},
+{112,80,112}, {112,80,104},
+{112,80,96}, {112,80,88}, /*160*/
+{112,80,80}, {112,88,80},
+{112,96,80}, {112,104,80},
+{112,112,80}, {104,112,80},
+{96,112,80}, {88,112,80},
+{80,112,80}, {80,112,88},
+{80,112,96}, {80,112,104},
+{80,112,112}, {80,114,112},
+{80,96,112}, {80,88,112}, /*176*/
+{0,0,64}, {16,0,64},
+{32,0,64}, {48,0,64},
+{64,0,64}, {64,0,48},
+{64,0,32}, {64,0,16},
+{64,0,0}, {64,16,0},
+{64,32,0}, {64,48,0},
+{64,64,0}, {48,64,0},
+{32,64,0}, {16,64,0}, /*192*/
+{0,64,0}, {0,64,16},
+{0,64,32}, {0,64,48},
+{0,64,64}, {0,48,64},
+{0,32,64}, {0,16,64},
+{32,32,64}, {40,32,64},
+{48,32,64}, {56,32,64},
+{64,32,64}, {64,32,56},
+{64,32,48}, {64,32,40}, /*208*/
+{64,32,32}, {64,40,32},
+{64,48,32}, {64,56,32},
+{64,64,32}, {56,64,32},
+{48,64,32}, {40,64,32},
+{32,64,32}, {32,64,40},
+{32,64,48}, {32,64,56},
+{32,64,64}, {32,56,64},
+{32,48,64}, {32,40,64}, /*224*/
+{44,44,64}, {48,44,64},
+{52,44,64}, {60,44,64},
+{64,44,64}, {64,44,60},
+{64,44,52}, {64,44,48},
+{64,44,44}, {64,48,44},
+{64,52,44}, {64,60,44},
+{64,64,44}, {60,64,44},
+{52,64,44}, {48,64,44}, /*240*/
+{44,64,44}, {44,64,48},
+{44,64,52}, {44,64,60},
+{44,64,64}, {44,60,64},
+{44,55,64}, {44,48,64},
+{0,0,0}, {0,0,0},
+{0,0,0}, {0,0,0},
+{0,0,0}, {0,0,0},
+{0,0,0}, {0,0,0} /*256*/
+};
+
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s W P G %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsWPG() returns True if the image format type, identified by the magick
+% string, is WPG.
+%
+% The format of the IsWPG method is:
+%
+% unsigned int IsWPG(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsWPG returns True if the image format type is WPG.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsWPG(const unsigned char *magick,const size_t length)
+{
+ if (length < 4)
+ return(False);
+ if (memcmp(magick,"\377WPC",4) == 0)
+ return(True);
+ return(False);
+}
+
+
+static void Rd_WP_DWORD(Image *image,unsigned long *d)
+{
+ unsigned char
+ b;
+
+ b=ReadBlobByte(image);
+ *d=b;
+ if (b < 0xFFU)
+ return;
+ b=ReadBlobByte(image);
+ *d=(unsigned long) b;
+ b=ReadBlobByte(image);
+ *d+=(unsigned long) b*256l;
+ if (*d < 0x8000)
+ return;
+ *d=(*d & 0x7FFF) << 16;
+ b=ReadBlobByte(image);
+ *d+=(unsigned long) b;
+ b=ReadBlobByte(image);
+ *d+=(unsigned long) b*256l;
+ return;
+}
+
+
+static MagickPassFail InsertRow(unsigned char *p,long y, Image *image, int bpp)
+{
+ long
+ x;
+ register PixelPacket
+ *q;
+ MagickPassFail RetVal = MagickFail;
+ IndexPacket index;
+ IndexPacket *indexes;
+
+
+ q = SetImagePixels(image,0,y,image->columns,1);
+ if(q == (PixelPacket *) NULL) return MagickFail;
+
+ switch (bpp)
+ {
+ case 1: /* Convert bitmap scanline. WP seems to ignore palette even if it is present. */
+ RetVal = ImportImagePixelArea(image,GrayQuantum,bpp,p,NULL,0);
+ break;
+
+ case 4: /* Convert PseudoColor scanline. */
+ case 8: /* Convert PseudoColor scanline. */
+ RetVal = ImportImagePixelArea(image,IndexQuantum,bpp,p,NULL,0);
+ break;
+
+ case 2: /* Convert PseudoColor scanline. */
+ {
+ indexes=AccessMutableIndexes(image);
+ x = 0;
+ while(x < (long)image->columns-3)
+ {
+ index = (IndexPacket)((*p >> 6) & 0x3);
+ VerifyColormapIndex(image,index);
+ indexes[x++]=index;
+ *q++=image->colormap[index];
+ index = (IndexPacket)((*p >> 4) & 0x3);
+ VerifyColormapIndex(image,index);
+ indexes[x++]=index;
+ *q++=image->colormap[index];
+ index = (IndexPacket)((*p >> 2) & 0x3);
+ VerifyColormapIndex(image,index);
+ indexes[x++]=index;
+ *q++ = image->colormap[index];
+ index = (IndexPacket)((*p) & 0x3);
+ VerifyColormapIndex(image,index);
+ indexes[x++]=index;
+ *q++ = image->colormap[index];
+ p++;
+ }
+ if(x < (long) image->columns)
+ {
+ index = (IndexPacket) ((*p >> 6) & 0x3);
+ VerifyColormapIndex(image,index);
+ indexes[x++] = index;
+ *q++=image->colormap[index];
+ if(x < (long) image->columns)
+ {
+ index = (IndexPacket) ((*p >> 4) & 0x3);
+ VerifyColormapIndex(image,index);
+ indexes[x++] = index;
+ *q++=image->colormap[index];
+ if(x < (long) image->columns)
+ {
+ index = (IndexPacket)((*p >> 2) & 0x3);
+ VerifyColormapIndex(image,index);
+ indexes[x] = index;
+ *q++=image->colormap[index];
+ }
+ }
+ /* p++; */
+ }
+ RetVal = MagickPass;
+ break;
+ }
+
+ case 24: /* Convert DirectColor scanline. */
+ RetVal = ImportImagePixelArea(image,RGBQuantum,8,p,NULL,0);
+ break;
+
+ default:
+ return MagickFail; /* emit some error here */
+ }
+
+
+ if(RetVal==MagickFail)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"ImportImagePixelArea failed for row: %ld, bpp: %d", y, bpp);
+
+ if (!SyncImagePixels(image))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"SyncImagePixels failed for row: %ld, bpp: %d", y, bpp);
+ RetVal = MagickFail;
+ }
+
+return RetVal;
+}
+
+
+/* Helper for WPG1 raster reader. */
+#define InsertByte(b) \
+{ \
+ BImgBuff[x]=b; \
+ x++; \
+ if((long) x>=ldblk) \
+ { \
+ (void)InsertRow(BImgBuff,(long) y,image,bpp); \
+ x=0; \
+ y++; \
+ } \
+}
+
+/* WPG1 raster reader. */
+static int UnpackWPGRaster(Image *image,int bpp)
+{
+ int
+ x,
+ y,
+ i;
+
+ unsigned char
+ bbuf,
+ *BImgBuff,
+ RunCount;
+
+ long
+ ldblk;
+
+ x=0;
+ y=0;
+
+ ldblk=(long) ((bpp*image->columns+7)/8);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Raster allocation size: %ld byte%s",
+ ldblk, (ldblk > 1 ? "s" : ""));
+ BImgBuff=MagickAllocateMemory(unsigned char *,(size_t) ldblk);
+ if(BImgBuff==NULL) return(-2);
+ (void) memset(BImgBuff,0,(size_t) ldblk);
+
+ while(y<(long) image->rows)
+ {
+ i = ReadBlobByte(image);
+ if(i==EOF)
+ {
+ MagickFreeMemory(BImgBuff);
+ return(-5);
+ }
+ bbuf = i;
+
+ RunCount=bbuf & 0x7F;
+ if(bbuf & 0x80)
+ {
+ if(RunCount) /* repeat next byte runcount * */
+ {
+ bbuf=ReadBlobByte(image);
+ for(i=0;i<(int) RunCount;i++) InsertByte(bbuf);
+ }
+ else { /* read next byte as RunCount; repeat 0xFF runcount* */
+ RunCount=ReadBlobByte(image);
+ for(i=0;i<(int) RunCount;i++) InsertByte(0xFF);
+ }
+ }
+ else {
+ if(RunCount) /* next runcount byte are readed directly */
+ {
+ for(i=0;i < (int) RunCount;i++)
+ {
+ bbuf=ReadBlobByte(image);
+ InsertByte(bbuf);
+ }
+ }
+ else { /* repeat previous line runcount* */
+ RunCount=ReadBlobByte(image);
+ if(x) { /* attempt to duplicate row from x position: */
+ /* I do not know what to do here */
+ MagickFreeMemory(BImgBuff);
+ return(-3);
+ }
+ for(i=0;i < (int) RunCount;i++)
+ {
+ x=0;
+ y++; /* Here I need to duplicate previous row RUNCOUNT* */
+ if(y<2) continue;
+ if(y>(long) image->rows)
+ {
+ MagickFreeMemory(BImgBuff);
+ return(-4);
+ }
+ (void) InsertRow(BImgBuff,y-1,image,bpp);
+ }
+ }
+ }
+ }
+ MagickFreeMemory(BImgBuff);
+ return(0);
+}
+
+
+/* Helper for WPG2 reader. */
+#define InsertByte6(b) \
+{ \
+ if(XorMe)\
+ BImgBuff[x] = b ^ UpImgBuff[x];\
+ else\
+ BImgBuff[x] = b;\
+ x++; \
+ if((long) x >= ldblk) \
+ { \
+ (void)InsertRow(BImgBuff,(long) y,image,bpp); \
+ x=0; \
+ y++; \
+ XorMe = 0; \
+ tmpImgBuff = BImgBuff; \
+ BImgBuff = UpImgBuff; \
+ UpImgBuff = tmpImgBuff; \
+ } \
+}
+
+#define FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff) \
+ do \
+ { \
+ MagickFreeMemory(BImgBuff); \
+ MagickFreeMemory(UpImgBuff); \
+ } while(0);
+
+/* WPG2 raster reader. */
+static int UnpackWPG2Raster(Image *image, int bpp)
+{
+ unsigned int
+ SampleSize=1;
+
+ unsigned char
+ bbuf,
+ *BImgBuff = (unsigned char *) NULL, /* Buffer for a current line. */
+ *UpImgBuff = (unsigned char *) NULL, /* Buffer for previous line. */
+ *tmpImgBuff = (unsigned char *) NULL,
+ RunCount,
+ SampleBuffer[8];
+
+ unsigned long
+ x,
+ y;
+
+ unsigned int
+ i;
+
+ long
+ ldblk;
+
+ int XorMe = 0;
+ int c;
+
+ x=0;
+ y=0;
+ ldblk=(long) ((bpp*image->columns+7)/8);
+ BImgBuff=MagickAllocateMemory(unsigned char *,(size_t) ldblk);
+ if(BImgBuff==NULL)
+ return(-2);
+ UpImgBuff=MagickAllocateMemory(unsigned char *,(size_t) ldblk);
+ if(UpImgBuff==NULL)
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-2);
+ }
+ (void) memset(UpImgBuff,0,ldblk);
+ (void) memset(SampleBuffer,0,sizeof(SampleBuffer));
+
+ while( y< image->rows)
+ {
+ bbuf=ReadBlobByte(image);
+
+ switch(bbuf)
+ {
+ case 0x7D:
+ if ((c = ReadBlobByte(image)) == EOF) /* DSZ */
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-4);
+ }
+ SampleSize=c;
+ if(SampleSize>8)
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-2);
+ }
+ if(SampleSize<1)
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-2);
+ }
+ break;
+ case 0x7E:
+ if(y==0) /* XOR */
+ (void)fprintf(stderr,"\nWPG token XOR on the first line is not supported, please report!");
+ XorMe=!XorMe; /* or XorMe=1 ?? */
+ break;
+ case 0x7F:
+ if ((c = ReadBlobByte(image)) == EOF) /* BLK */
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-4);
+ }
+ RunCount=c;
+ for(i=0; i < SampleSize*(RunCount+1); i++)
+ {
+ InsertByte6(0);
+ }
+ break;
+ case 0xFD:
+ if ((c = ReadBlobByte(image)) == EOF) /* EXT */
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-4);
+ }
+ RunCount=c;
+ for(i=0; i<= RunCount;i++)
+ for(bbuf=0; bbuf < SampleSize; bbuf++)
+ InsertByte6(SampleBuffer[bbuf]);
+ break;
+ case 0xFE:
+ if ((c = ReadBlobByte(image)) == EOF) /* RST */
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-4);
+ }
+ RunCount = c;
+ if(x!=0)
+ {
+ (void) fprintf(stderr,
+ "\nUnsupported WPG2 unaligned token RST x=%lu, please report!\n"
+ ,x);
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-3);
+ }
+ {
+ /* duplicate the previous row RunCount x */
+ for(i=0;i<=RunCount;i++)
+ {
+ (void) InsertRow(UpImgBuff,(long) (image->rows >= y ? y : image->rows-1),
+ image,bpp);
+ y++;
+ }
+ }
+ break;
+ case 0xFF:
+ if ((c = ReadBlobByte(image)) == EOF) /* WHT */
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-4);
+ }
+ RunCount=c;
+ for(i=0; i < SampleSize*(RunCount+1); i++)
+ {
+ InsertByte6(0xFF);
+ }
+ break;
+ default:
+ RunCount=bbuf & 0x7F;
+
+ if(bbuf & 0x80) /* REP */
+ {
+ for(i=0; i < SampleSize; i++)
+ SampleBuffer[i]=ReadBlobByte(image);
+ for(i=0;i<=RunCount;i++)
+ for(bbuf=0;bbuf<SampleSize;bbuf++)
+ InsertByte6(SampleBuffer[bbuf]);
+ }
+ else { /* NRP */
+ for(i=0; i< SampleSize*(RunCount+1);i++)
+ {
+ bbuf=ReadBlobByte(image);
+ InsertByte6(bbuf);
+ }
+ }
+ if (EOFBlob(image))
+ {
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(-4);
+ }
+ }
+ }
+ FreeUnpackWPG2RasterAllocs(BImgBuff,UpImgBuff);
+ return(0);
+}
+
+
+typedef float tCTM[3][3];
+
+static unsigned LoadWPG2Flags(Image *image,char Precision,float *Angle,tCTM *CTM)
+{
+const unsigned char TPR=1,TRN=2,SKW=4,SCL=8,ROT=0x10,OID=0x20,LCK=0x80;
+long x;
+unsigned DenX;
+unsigned Flags;
+
+ (void) memset(*CTM,0,sizeof(*CTM)); /*CTM.erase();CTM.resize(3,3);*/
+ (*CTM)[0][0]=1;
+ (*CTM)[1][1]=1;
+ (*CTM)[2][2]=1;
+
+ Flags=ReadBlobLSBShort(image);
+ if(Flags & LCK) /*x=*/ (void) ReadBlobLSBLong(image); /*Edit lock*/
+ if(Flags & OID)
+ {
+ if(Precision==0)
+ {/*x=*/ (void) ReadBlobLSBShort(image);} /*ObjectID*/
+ else
+ {/*x=*/ (void) ReadBlobLSBLong(image);} /*ObjectID (Double precision)*/
+ }
+ if(Flags & ROT)
+ {
+ x=ReadBlobLSBLong(image); /*Rot Angle*/
+ if(Angle) *Angle=x/65536.0;
+ }
+ if(Flags & (ROT|SCL))
+ {
+ x=ReadBlobLSBLong(image); /*Sx*cos()*/
+ (*CTM)[0][0] = (float)x/0x10000;
+ x=ReadBlobLSBLong(image); /*Sy*cos()*/
+ (*CTM)[1][1] = (float)x/0x10000;
+ }
+ if(Flags & (ROT|SKW))
+ {
+ x=ReadBlobLSBLong(image); /*Kx*sin()*/
+ (*CTM)[1][0] = (float)x/0x10000;
+ x=ReadBlobLSBLong(image); /*Ky*sin()*/
+ (*CTM)[0][1] = (float)x/0x10000;
+ }
+ if(Flags & TRN)
+ {
+ x=ReadBlobLSBLong(image); DenX=ReadBlobLSBShort(image); /*Tx*/
+ if(x>=0) (*CTM)[0][2] = (float)x+(float)DenX/0x10000;
+ else (*CTM)[0][2] = (float)x-(float)DenX/0x10000;
+ x=ReadBlobLSBLong(image); DenX=ReadBlobLSBShort(image); /*Ty*/
+ (*CTM)[1][2]=(float)x + ((x>=0)?1:-1)*(float)DenX/0x10000;
+ if(x>=0) (*CTM)[1][2] = (float)x+(float)DenX/0x10000;
+ else (*CTM)[1][2] = (float)x-(float)DenX/0x10000;
+ }
+ if(Flags & TPR)
+ {
+ x=ReadBlobLSBShort(image); DenX=ReadBlobLSBShort(image); /*Px*/
+ (*CTM)[2][0] = x + (float)DenX/0x10000;;
+ x=ReadBlobLSBShort(image); DenX=ReadBlobLSBShort(image); /*Py*/
+ (*CTM)[2][1] = x + (float)DenX/0x10000;
+ }
+ return(Flags);
+}
+
+
+static Image *ExtractPostscript(Image *image,const ImageInfo *image_info,
+ ExtendedSignedIntegralType PS_Offset,long PS_Size,ExceptionInfo *exception)
+{
+ char
+ postscript_file[MaxTextExtent];
+
+ FILE
+ *ps_file;
+
+ ImageInfo
+ *clone_info;
+
+ Image
+ *image2;
+
+ unsigned char
+ magick[2*MaxTextExtent];
+
+ size_t
+ magick_size;
+
+
+ if ((clone_info=CloneImageInfo(image_info)) == NULL)
+ return(image);
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+
+ /* Obtain temporary file */
+ ps_file=AcquireTemporaryFileStream(postscript_file,BinaryFileIOMode);
+ if (!ps_file)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Gannot create file stream for PS image");
+ goto FINISH;
+ }
+
+ /* Copy postscript to temporary file */
+ (void) SeekBlob(image,PS_Offset,SEEK_SET);
+ magick_size=ReadBlob(image, sizeof(magick), magick);
+
+ (void) SeekBlob(image,PS_Offset,SEEK_SET);
+ while(PS_Size-- > 0)
+ {
+ (void) fputc(ReadBlobByte(image),ps_file);
+ }
+ (void) fclose(ps_file);
+
+ /* Detect file format - Check magic.mgk configuration file. */
+ if (GetMagickFileFormat(magick,magick_size,clone_info->magick,
+ MaxTextExtent,exception) == MagickFail)
+ goto FINISH_UNL;
+
+ /* Read nested image */
+ /*FormatString(clone_info->filename,"%s:%.1024s",magic_info->name,postscript_file);*/
+ FormatString(clone_info->filename,"%.1024s",postscript_file);
+ image2=ReadImage(clone_info,exception);
+
+ if (!image2)
+ goto FINISH_UNL;
+
+ /*
+ Replace current image with new image while copying base image
+ attributes.
+ */
+ (void) strlcpy(image2->filename,image->filename,MaxTextExtent);
+ (void) strlcpy(image2->magick_filename,image->magick_filename,MaxTextExtent);
+ (void) strlcpy(image2->magick,image->magick,MaxTextExtent);
+ image2->depth=image->depth;
+ DestroyBlob(image2);
+ image2->blob=ReferenceBlob(image->blob);
+
+ if ((image->rows == 0) || (image->columns == 0))
+ DeleteImageFromList(&image);
+
+ AppendImageToList(&image,image2);
+
+ FINISH_UNL:
+ (void) LiberateTemporaryFile(postscript_file);
+ FINISH:
+ DestroyImageInfo(clone_info);
+ return(image);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d W P G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadWPGImage reads an WPG X image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadWPGImage method is:
+%
+% Image *ReadWPGImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadWPGImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or if
+% the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadWPGImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ typedef struct
+ {
+ unsigned long FileId;
+ ExtendedSignedIntegralType DataOffset;
+ unsigned int ProductType;
+ unsigned int FileType;
+ unsigned char MajorVersion;
+ unsigned char MinorVersion;
+ unsigned int EncryptKey;
+ unsigned int Reserved;
+ } WPGHeader;
+
+ typedef struct
+ {
+ unsigned char RecType;
+ unsigned long RecordLength;
+ } WPGRecord;
+
+ typedef struct
+ {
+ unsigned char Class;
+ unsigned char RecType;
+ unsigned long Extension;
+ unsigned long RecordLength;
+ } WPG2Record;
+
+ typedef struct
+ {
+ unsigned HorizontalUnits;
+ unsigned VerticalUnits;
+ unsigned char PosSizePrecision;
+ } WPG2Start;
+
+ typedef struct
+ {
+ unsigned int Width;
+ unsigned int Heigth;
+ unsigned int Depth;
+ unsigned int HorzRes;
+ unsigned int VertRes;
+ } WPGBitmapType1;
+
+ typedef struct
+ {
+ unsigned int Width;
+ unsigned int Heigth;
+ unsigned char Depth;
+ unsigned char Compression;
+ } WPG2BitmapType1;
+
+ typedef struct
+ {
+ unsigned int RotAngle;
+ unsigned int LowLeftX;
+ unsigned int LowLeftY;
+ unsigned int UpRightX;
+ unsigned int UpRightY;
+ unsigned int Width;
+ unsigned int Heigth;
+ unsigned int Depth;
+ unsigned int HorzRes;
+ unsigned int VertRes;
+ } WPGBitmapType2;
+
+ typedef struct
+ {
+ unsigned int StartIndex;
+ unsigned int NumOfEntries;
+ } WPGColorMapRec;
+
+ /*
+ typedef struct {
+ unsigned long PS_unknown1;
+ unsigned int PS_unknown2;
+ unsigned int PS_unknown3;
+ } WPGPSl1Record;
+ */
+
+ Image
+ *image,
+ *rotated_image;
+
+ unsigned int
+ status;
+
+ WPGHeader
+ Header;
+
+ WPGRecord
+ Rec;
+
+ WPG2Record
+ Rec2;
+
+ WPG2Start StartWPG;
+
+ WPGBitmapType1
+ BitmapHeader1;
+
+ WPG2BitmapType1
+ Bitmap2Header1;
+
+ WPGBitmapType2
+ BitmapHeader2;
+
+ WPGColorMapRec
+ WPG_Palette;
+
+ int
+ i,
+ bpp;
+
+ int logging;
+
+ long
+ ldblk;
+
+ unsigned char
+ *BImgBuff;
+ BlobInfo *TmpBlob;
+
+ tCTM CTM; /*current transform matrix*/
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ logging = LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
+
+ image=AllocateImage(image_info);
+ image->depth=8;
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+
+ /*
+ Read WPG image.
+ */
+ Header.FileId=ReadBlobLSBLong(image);
+ Header.DataOffset=(ExtendedSignedIntegralType) ReadBlobLSBLong(image);
+ Header.ProductType=ReadBlobLSBShort(image);
+ Header.FileType=ReadBlobLSBShort(image);
+ Header.MajorVersion=ReadBlobByte(image);
+ Header.MinorVersion=ReadBlobByte(image);
+ Header.EncryptKey=ReadBlobLSBShort(image);
+ Header.Reserved=ReadBlobLSBShort(image);
+
+ if (Header.FileId!=0x435057FF || (Header.ProductType>>8)!=0x16)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ if (Header.EncryptKey!=0)
+ ThrowReaderException(CoderError,EncryptedWPGImageFileNotSupported,image);
+
+ image->colors = 0;
+ bpp=0;
+
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "File type: %d", Header.FileType);
+
+ switch(Header.FileType)
+ {
+ case 1: /* WPG level 1 */
+ BitmapHeader2.RotAngle = 0;
+
+ while(!EOFBlob(image)) /* object parser loop */
+ {
+ (void) SeekBlob(image,Header.DataOffset,SEEK_SET);
+ if(EOFBlob(image))
+ break;
+
+ Rec.RecType=(i=ReadBlobByte(image));
+ if(i==EOF)
+ break;
+ Rd_WP_DWORD(image,&Rec.RecordLength);
+ if(EOFBlob(image))
+ break;
+
+ Header.DataOffset=TellBlob(image)+Rec.RecordLength;
+
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Parsing object: %X", Rec.RecType);
+
+ switch(Rec.RecType)
+ {
+ case 0x0B: /* bitmap type 1 */
+ BitmapHeader1.Width=ReadBlobLSBShort(image);
+ BitmapHeader1.Heigth=ReadBlobLSBShort(image);
+ BitmapHeader1.Depth=ReadBlobLSBShort(image);
+ BitmapHeader1.HorzRes=ReadBlobLSBShort(image);
+ BitmapHeader1.VertRes=ReadBlobLSBShort(image);
+
+ if(BitmapHeader1.HorzRes && BitmapHeader1.VertRes)
+ {
+ image->units=PixelsPerCentimeterResolution;
+ image->x_resolution=BitmapHeader1.HorzRes/470.0;
+ image->y_resolution=BitmapHeader1.VertRes/470.0;
+ }
+ image->columns=BitmapHeader1.Width;
+ image->rows=BitmapHeader1.Heigth;
+ bpp=BitmapHeader1.Depth;
+
+ goto UnpackRaster;
+
+ case 0x0E: /*Color palette */
+ WPG_Palette.StartIndex=ReadBlobLSBShort(image);
+ WPG_Palette.NumOfEntries=ReadBlobLSBShort(image);
+
+ image->colors=WPG_Palette.NumOfEntries;
+ if (!AllocateImageColormap(image,image->colors))
+ goto NoMemory;
+ image->storage_class = PseudoClass;
+ for (i=WPG_Palette.StartIndex;
+ i < (int)WPG_Palette.NumOfEntries; i++)
+ {
+ image->colormap[i].red=
+ ScaleCharToQuantum(ReadBlobByte(image));
+ image->colormap[i].green=
+ ScaleCharToQuantum(ReadBlobByte(image));
+ image->colormap[i].blue=
+ ScaleCharToQuantum(ReadBlobByte(image));
+ }
+ break;
+
+ case 0x11: /* Start PS l1 */
+ if(Rec.RecordLength > 8)
+ image=ExtractPostscript(image,image_info,
+ TellBlob(image)+8, /* skip PS header in the wpg */
+ (long) Rec.RecordLength-8,exception);
+ break;
+
+ case 0x14: /* bitmap type 2 */
+ BitmapHeader2.RotAngle=ReadBlobLSBShort(image);
+ BitmapHeader2.LowLeftX=ReadBlobLSBShort(image);
+ BitmapHeader2.LowLeftY=ReadBlobLSBShort(image);
+ BitmapHeader2.UpRightX=ReadBlobLSBShort(image);
+ BitmapHeader2.UpRightY=ReadBlobLSBShort(image);
+ BitmapHeader2.Width=ReadBlobLSBShort(image);
+ BitmapHeader2.Heigth=ReadBlobLSBShort(image);
+ BitmapHeader2.Depth=ReadBlobLSBShort(image);
+ BitmapHeader2.HorzRes=ReadBlobLSBShort(image);
+ BitmapHeader2.VertRes=ReadBlobLSBShort(image);
+
+ image->units=PixelsPerCentimeterResolution;
+ image->page.width=(unsigned int)
+ ((BitmapHeader2.LowLeftX-BitmapHeader2.UpRightX)/470.0);
+ image->page.height=(unsigned int)
+ ((BitmapHeader2.LowLeftX-BitmapHeader2.UpRightY)/470.0);
+ image->page.x=(int) (BitmapHeader2.LowLeftX/470.0);
+ image->page.y=(int) (BitmapHeader2.LowLeftX/470.0);
+ if(BitmapHeader2.HorzRes && BitmapHeader2.VertRes)
+ {
+ image->x_resolution=BitmapHeader2.HorzRes/470.0;
+ image->y_resolution=BitmapHeader2.VertRes/470.0;
+ }
+ image->columns=BitmapHeader2.Width;
+ image->rows=BitmapHeader2.Heigth;
+ bpp=BitmapHeader2.Depth;
+
+ UnpackRaster:
+ if ((image->colors == 0) && (bpp != 24))
+ {
+ image->colors=1 << bpp;
+ if (!AllocateImageColormap(image,image->colors))
+ {
+ NoMemory:
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image)
+ }
+ image->storage_class = PseudoClass;
+ /* printf("Load default colormap \n"); */
+ for (i=0; (i < (int) image->colors) && (i < 256); i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(WPG1_Palette[i].Red);
+ image->colormap[i].green=ScaleCharToQuantum(WPG1_Palette[i].Green);
+ image->colormap[i].blue=ScaleCharToQuantum(WPG1_Palette[i].Blue);
+ }
+ }
+ else
+ {
+ if (bpp < 24)
+ if ( (image->colors < (1UL<<bpp)) && (bpp != 24) )
+ MagickReallocMemory(PixelPacket *,image->colormap,
+ (size_t) (1U<<bpp)*sizeof(PixelPacket));
+ }
+
+ if (bpp == 1)
+ {
+ if(image->colormap[0].red==0 &&
+ image->colormap[0].green==0 &&
+ image->colormap[0].blue==0 &&
+ image->colormap[1].red==0 &&
+ image->colormap[1].green==0 &&
+ image->colormap[1].blue==0)
+ { /* fix crippled monochrome palette */
+ image->colormap[1].red =
+ image->colormap[1].green =
+ image->colormap[1].blue = MaxRGB;
+ }
+ }
+
+ if(!image_info->ping)
+ if(UnpackWPGRaster(image,bpp) < 0)
+ { /* The raster cannot be unpacked */
+ DecompressionFailed:
+ ThrowReaderException(CoderError,UnableToDecompressImage,image)
+ }
+
+ if(Rec.RecType==0x14 && BitmapHeader2.RotAngle!=0 && !image_info->ping)
+ {
+ /* flop command */
+ if(BitmapHeader2.RotAngle & 0x8000)
+ {
+ rotated_image = FlopImage(image, exception);
+ if (rotated_image != (Image *)NULL)
+ {
+ TmpBlob = rotated_image->blob;
+ rotated_image->blob = image->blob;
+ image->blob = TmpBlob;
+ ReplaceImageInList(&image,rotated_image);
+ }
+ }
+ /* flip command */
+ if(BitmapHeader2.RotAngle & 0x2000)
+ {
+ rotated_image = FlipImage(image, exception);
+ if (rotated_image != (Image *) NULL)
+ {
+ TmpBlob = rotated_image->blob;
+ rotated_image->blob = image->blob;
+ image->blob = TmpBlob;
+ ReplaceImageInList(&image,rotated_image);
+ }
+ }
+
+ /* rotate command */
+ if(BitmapHeader2.RotAngle & 0x0FFF)
+ {
+ rotated_image = RotateImage(image,
+ (BitmapHeader2.RotAngle & 0x0FFF),
+ exception);
+ if (rotated_image != (Image *) NULL)
+ {
+ TmpBlob = rotated_image->blob;
+ rotated_image->blob = image->blob;
+ image->blob = TmpBlob;
+ ReplaceImageInList(&image,rotated_image);
+ }
+ }
+ }
+
+ /* Allocate next image structure. */
+ AllocateNextImage(image_info,image);
+ image->depth=8;
+ if (image->next == (Image *) NULL)
+ goto Finish;
+ image=SyncNextImageInList(image);
+ image->columns=image->rows=0;
+ image->colors=0;
+ break;
+
+ case 0x1B: /* Postscript l2 */
+ if(Rec.RecordLength>0x3C)
+ image=ExtractPostscript(image,image_info,
+ TellBlob(image)+0x3C, /* skip PS l2 header in the wpg */
+ (long) Rec.RecordLength-0x3C,exception);
+ break;
+ }
+ }
+ break;
+
+ case 2: /* WPG level 2 */
+ (void) memset(CTM,0,sizeof(CTM));
+ StartWPG.PosSizePrecision = 0;
+ while(!EOFBlob(image)) /* object parser loop */
+ {
+ (void) SeekBlob(image,Header.DataOffset,SEEK_SET);
+ if(EOFBlob(image))
+ break;
+
+ Rec2.Class=(i=ReadBlobByte(image));
+ if(i==EOF)
+ break;
+ Rec2.RecType=(i=ReadBlobByte(image));
+ if(i==EOF)
+ break;
+ Rd_WP_DWORD(image,&Rec2.Extension);
+ Rd_WP_DWORD(image,&Rec2.RecordLength);
+ if(EOFBlob(image))
+ break;
+
+ Header.DataOffset=TellBlob(image)+Rec2.RecordLength;
+
+ if(logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Parsing object: %X", Rec2.RecType);
+
+ switch(Rec2.RecType)
+ {
+ case 1:
+ StartWPG.HorizontalUnits=ReadBlobLSBShort(image);
+ StartWPG.VerticalUnits=ReadBlobLSBShort(image);
+ StartWPG.PosSizePrecision=ReadBlobByte(image);
+ break;
+ case 0x0C: /* Color palette */
+ WPG_Palette.StartIndex=ReadBlobLSBShort(image);
+ WPG_Palette.NumOfEntries=ReadBlobLSBShort(image);
+
+ /* Sanity check for amount of palette entries. */
+ if( (WPG_Palette.NumOfEntries-WPG_Palette.StartIndex) > (Rec2.RecordLength-2-2) / 3)
+ ThrowReaderException(CorruptImageError,InvalidColormapIndex,image);
+
+ image->colors=WPG_Palette.NumOfEntries;
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ for (i=WPG_Palette.StartIndex;
+ i < (int)WPG_Palette.NumOfEntries; i++)
+ {
+ image->colormap[i].red=ScaleCharToQuantum(ReadBlobByte(image));
+ image->colormap[i].green=ScaleCharToQuantum(ReadBlobByte(image));
+ image->colormap[i].blue=ScaleCharToQuantum(ReadBlobByte(image));
+ (void) ReadBlobByte(image); /*Opacity??*/
+ }
+ break;
+ case 0x0E:
+ Bitmap2Header1.Width=ReadBlobLSBShort(image);
+ Bitmap2Header1.Heigth=ReadBlobLSBShort(image);
+ Bitmap2Header1.Depth=ReadBlobByte(image);
+ Bitmap2Header1.Compression=ReadBlobByte(image);
+
+ if(Bitmap2Header1.Compression > 1)
+ continue; /*Unknown compression method */
+ switch(Bitmap2Header1.Depth)
+ {
+ case 1: bpp=1;
+ break;
+ case 2: bpp=2;
+ break;
+ case 3: bpp=4;
+ break;
+ case 4: bpp=8;
+ break;
+ case 8: bpp=24;
+ break;
+ default:
+ continue; /*Ignore raster with unknown depth*/
+ }
+ image->columns=Bitmap2Header1.Width;
+ image->rows=Bitmap2Header1.Heigth;
+
+ if ((image->colors == 0) && (bpp != 24))
+ {
+ image->colors=1 << bpp;
+ if (!AllocateImageColormap(image,image->colors))
+ goto NoMemory;
+ image->storage_class = PseudoClass;
+ }
+ else
+ {
+ if(bpp < 24)
+ if( image->colors<(1UL<<bpp) && bpp!=24 )
+ MagickReallocMemory(PixelPacket *,image->colormap,
+ (size_t) (1U<<bpp)*sizeof(PixelPacket));
+ }
+
+
+ switch(Bitmap2Header1.Compression)
+ {
+ case 0: /*Uncompressed raster*/
+ {
+ ldblk=(long) ((bpp*image->columns+7)/8);
+ BImgBuff=MagickAllocateMemory(unsigned char *,(size_t) ldblk);
+ if (BImgBuff == (unsigned char *) NULL)
+ goto NoMemory;
+
+ for(i=0; i< (long) image->rows; i++)
+ {
+ (void) ReadBlob(image,ldblk,(char *) BImgBuff);
+ (void) InsertRow(BImgBuff,i,image,bpp);
+ }
+
+ if(BImgBuff)
+ MagickFreeMemory(BImgBuff);
+ break;
+ }
+ case 1: /*RLE for WPG2 */
+ {
+ if( UnpackWPG2Raster(image,bpp) < 0)
+ goto DecompressionFailed;
+ break;
+ }
+ }
+
+
+ if(CTM[0][0]<0 && !image_info->ping)
+ { /*?? RotAngle=360-RotAngle;*/
+ rotated_image = FlopImage(image, exception);
+ if (rotated_image != (Image *) NULL)
+ {
+ TmpBlob = rotated_image->blob;
+ rotated_image->blob = image->blob;
+ image->blob = TmpBlob;
+ ReplaceImageInList(&image,rotated_image);
+ }
+ /* Try to change CTM according to Flip - I am not sure, must be checked.
+ Tx(0,0)=-1; Tx(1,0)=0; Tx(2,0)=0;
+ Tx(0,1)= 0; Tx(1,1)=1; Tx(2,1)=0;
+ Tx(0,2)=(WPG._2Rect.X_ur+WPG._2Rect.X_ll);
+ Tx(1,2)=0; Tx(2,2)=1; */
+ }
+ if(CTM[1][1]<0 && !image_info->ping)
+ { /*?? RotAngle=360-RotAngle;*/
+ rotated_image = FlipImage(image, exception);
+ if (rotated_image != (Image *) NULL)
+ {
+ TmpBlob = rotated_image->blob;
+ rotated_image->blob = image->blob;
+ image->blob = TmpBlob;
+ ReplaceImageInList(&image,rotated_image);
+ }
+ /* Try to change CTM according to Flip - I am not sure, must be checked.
+ float_matrix Tx(3,3);
+ Tx(0,0)= 1; Tx(1,0)= 0; Tx(2,0)=0;
+ Tx(0,1)= 0; Tx(1,1)=-1; Tx(2,1)=0;
+ Tx(0,2)= 0; Tx(1,2)=(WPG._2Rect.Y_ur+WPG._2Rect.Y_ll);
+ Tx(2,2)=1; */
+ }
+
+
+ /* Allocate next image structure. */
+ AllocateNextImage(image_info,image);
+ image->depth=8;
+ if (image->next == (Image *) NULL)
+ goto Finish;
+ image=SyncNextImageInList(image);
+ image->columns=image->rows=0;
+ image->colors=0;
+ break;
+
+ case 0x12: /* Postscript WPG2*/
+ i=ReadBlobLSBShort(image);
+ if(Rec2.RecordLength > (unsigned int) i)
+ image=ExtractPostscript(image,image_info,
+ TellBlob(image)+i, /*skip PS header in the wpg2*/
+ (long) (Rec2.RecordLength-i-2),exception);
+ break;
+
+ case 0x1B: /*bitmap rectangle*/
+ (void) LoadWPG2Flags(image,StartWPG.PosSizePrecision,NULL,&CTM); /* WPG2Flags */
+ break;
+ }
+ }
+
+ break;
+
+ default:
+ {
+ ThrowReaderException(CoderError,DataEncodingSchemeIsNotSupported,image);
+ }
+ }
+
+ Finish:
+ CloseBlob(image);
+
+ {
+ Image
+ *p;
+
+ long
+ scene=0;
+
+ /*
+ Rewind list, removing any empty images while rewinding.
+ */
+ p=image;
+ image=NULL;
+ while (p != (Image *) NULL)
+ {
+ Image *tmp=p;
+ if ((p->rows == 0) || (p->columns == 0)) {
+ p=p->previous;
+ DeleteImageFromList(&tmp);
+ } else {
+ image=p;
+ p=p->previous;
+ }
+ }
+
+ /*
+ Fix scene numbers
+ */
+ for (p=image; p != (Image *) NULL; p=p->next)
+ p->scene=scene++;
+ }
+
+ if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return");
+ if(image==NULL)
+ ThrowReaderException(CorruptImageError,ImageFileDoesNotContainAnyImageData,image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r W P G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterWPGImage adds attributes for the WPG image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterWPGImage method is:
+%
+% RegisterWPGImage(void)
+%
+*/
+ModuleExport void RegisterWPGImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("WPG");
+ entry->decoder=(DecoderHandler) ReadWPGImage;
+ entry->magick=(MagickHandler) IsWPG;
+ entry->description="Word Perfect Graphics";
+ entry->module="WPG";
+ entry->seekable_stream=True;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r W P G I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterWPGImage removes format registrations made by the
+% WPG module from the list of supported formats.
+%
+% The format of the UnregisterWPGImage method is:
+%
+% UnregisterWPGImage(void)
+%
+*/
+ModuleExport void UnregisterWPGImage(void)
+{
+ (void) UnregisterMagickInfo("WPG");
+}
diff --git a/coders/x.c b/coders/x.c
new file mode 100644
index 0000000..7f489b4
--- /dev/null
+++ b/coders/x.c
@@ -0,0 +1,186 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X X %
+% X X %
+% X %
+% X X %
+% X X %
+% %
+% %
+% Read/Write Image from/to X11 Server. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+#include "magick/xwindow.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteXImage(const ImageInfo *,Image *);
+
+#if defined(HasX11)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure ReadXImage reads an image from an X window.
+%
+% The format of the ReadXImage method is:
+%
+% Image *ReadXImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadXImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ MagickXImportInfo
+ ximage_info;
+
+ ARG_NOT_USED(exception);
+ MagickXGetImportInfo(&ximage_info);
+ return(MagickXImportImage(image_info,&ximage_info));
+}
+#endif /* defined(HasX11) */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterXImage adds attributes for the X image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterXImage method is:
+%
+% RegisterXImage(void)
+%
+*/
+ModuleExport void RegisterXImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("X");
+#if defined(HasX11)
+ entry->decoder=(DecoderHandler) ReadXImage;
+ entry->encoder=(EncoderHandler) WriteXImage;
+#endif /* defined(HasX11) */
+ entry->adjoin=False;
+ entry->description="X Window System";
+ entry->module="X";
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterXImage removes format registrations made by the
+% X module from the list of supported formats.
+%
+% The format of the UnregisterXImage method is:
+%
+% UnregisterXImage(void)
+%
+*/
+ModuleExport void UnregisterXImage(void)
+{
+ (void) UnregisterMagickInfo("X");
+}
+
+#if defined(HasX11)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e X I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteXImage writes an image to an X server.
+%
+% The format of the WriteXImage method is:
+%
+% unsigned int WriteXImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteXImage return True if the image is displayed on
+% the X server. False is returned is there is a memory shortage or if
+% the image file fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteXImage(const ImageInfo *image_info,Image *image)
+{
+ return(DisplayImages(image_info,image));
+}
+#endif /* defined(HasX11) */
diff --git a/coders/xbm.c b/coders/xbm.c
new file mode 100644
index 0000000..b33e05e
--- /dev/null
+++ b/coders/xbm.c
@@ -0,0 +1,580 @@
+/*
+% Copyright (C) 2003 -2012 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X X BBBB M M %
+% X X B B MM MM %
+% X BBBB M M M %
+% X X B B M M %
+% X X BBBB M M %
+% %
+% %
+% Read/Write X Windows System Bitmap Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteXBMImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s X B M %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsXBM returns True if the image format type, identified by the
+% magick string, is XBM.
+%
+% The format of the IsXBM method is:
+%
+% unsigned int IsXBM(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsXBM returns True if the image format type is XBM.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsXBM(const unsigned char *magick,const size_t length)
+{
+ if (length < 7)
+ return(False);
+ if (LocaleNCompare((char *) magick,"#define",7) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d X B M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadXBMImage reads an X11 bitmap image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadXBMImage method is:
+%
+% Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadXBMImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static int XBMInteger(Image *image,short int *hex_digits)
+{
+ int
+ c,
+ flag,
+ value;
+
+ value=0;
+ flag=0;
+ for ( ; ; )
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ {
+ value=(-1);
+ break;
+ }
+ c&=0xff;
+ if (isxdigit(c))
+ {
+ value=(value << 4)+hex_digits[c];
+ flag++;
+ continue;
+ }
+ if ((hex_digits[c]) < 0 && flag)
+ break;
+ }
+ return(value);
+}
+
+static Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ buffer[MaxTextExtent],
+ name[MaxTextExtent];
+
+ Image
+ *image;
+
+ int
+ bit;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ short int
+ hex_digits[256];
+
+ unsigned char
+ *data;
+
+ unsigned int
+ status;
+
+ unsigned long
+ byte,
+ bytes_per_line,
+ padding,
+ value,
+ version;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read X bitmap header.
+ */
+ while (ReadBlobString(image,buffer) != (char *) NULL)
+ if (sscanf(buffer,"#define %s %lu",name,&image->columns) == 2)
+ if ((strlen(name) >= 6) &&
+ (LocaleCompare(name+strlen(name)-6,"_width") == 0))
+ break;
+ while (ReadBlobString(image,buffer) != (char *) NULL)
+ if (sscanf(buffer,"#define %s %lu",name,&image->rows) == 2)
+ if ((strlen(name) >= 7) &&
+ (LocaleCompare(name+strlen(name)-7,"_height") == 0))
+ break;
+ image->depth=8;
+ image->storage_class=PseudoClass;
+ image->colors=2;
+ /*
+ Scan until hex digits.
+ */
+ version=11;
+ while (ReadBlobString(image,buffer) != (char *) NULL)
+ {
+ if (sscanf(buffer,"static short %s = {",name) == 1)
+ version=10;
+ else
+ if (sscanf(buffer,"static unsigned char %s = {",name) == 1)
+ version=11;
+ else
+ if (sscanf(buffer,"static char %s = {",name) == 1)
+ version=11;
+ else
+ continue;
+ p=(unsigned char *) strrchr(name,'_');
+ if (p == (unsigned char *) NULL)
+ p=(unsigned char *) name;
+ else
+ p++;
+ if (LocaleCompare("bits[]",(char *) p) == 0)
+ break;
+ }
+ if ((image->columns == 0) || (image->rows == 0) || EOFBlob(image))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ /*
+ Initialize image structure.
+ */
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize colormap.
+ */
+ image->colormap[0].red=MaxRGB;
+ image->colormap[0].green=MaxRGB;
+ image->colormap[0].blue=MaxRGB;
+ image->colormap[1].red=0;
+ image->colormap[1].green=0;
+ image->colormap[1].blue=0;
+ if (image_info->ping)
+ {
+ CloseBlob(image);
+ return(image);
+ }
+ /*
+ Allocate temporary storage for X bitmap image
+ */
+ padding=0;
+ if ((image->columns % 16) && ((image->columns % 16) < 9) && (version == 10))
+ padding=1;
+ bytes_per_line=(image->columns+7)/8+padding;
+ data=MagickAllocateArray(unsigned char *,image->rows,bytes_per_line);
+ if (data == (unsigned char *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Initialize hex values.
+ */
+ hex_digits['0']=0;
+ hex_digits['1']=1;
+ hex_digits['2']=2;
+ hex_digits['3']=3;
+ hex_digits['4']=4;
+ hex_digits['5']=5;
+ hex_digits['6']=6;
+ hex_digits['7']=7;
+ hex_digits['8']=8;
+ hex_digits['9']=9;
+ hex_digits['A']=10;
+ hex_digits['B']=11;
+ hex_digits['C']=12;
+ hex_digits['D']=13;
+ hex_digits['E']=14;
+ hex_digits['F']=15;
+ hex_digits['a']=10;
+ hex_digits['b']=11;
+ hex_digits['c']=12;
+ hex_digits['d']=13;
+ hex_digits['e']=14;
+ hex_digits['f']=15;
+ hex_digits['x']=0;
+ hex_digits[' ']=(-1);
+ hex_digits[',']=(-1);
+ hex_digits['}']=(-1);
+ hex_digits['\n']=(-1);
+ hex_digits['\t']=(-1);
+ /*
+ Read hex image data.
+ */
+ p=data;
+ if (version == 10)
+ for (i=0; i < (long) (bytes_per_line*image->rows); (i+=2))
+ {
+ value=XBMInteger(image,hex_digits);
+ *p++=(unsigned char) value;
+ if (!padding || ((i+2) % bytes_per_line))
+ *p++=(unsigned char) (value >> 8);
+ }
+ else
+ for (i=0; i < (long) (bytes_per_line*image->rows); i++)
+ {
+ value=XBMInteger(image,hex_digits);
+ *p++=(unsigned char) value;
+ }
+ /*
+ Convert X bitmap image to pixel packets.
+ */
+ p=data;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (bit == 0)
+ byte=(*p++);
+ indexes[x]=byte & 0x01 ? 0x01 : 0x00;
+ bit++;
+ byte>>=1;
+ if (bit == 8)
+ bit=0;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(data);
+ (void) SyncImage(image);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r X B M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterXBMImage adds attributes for the XBM image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterXBMImage method is:
+%
+% RegisterXBMImage(void)
+%
+*/
+ModuleExport void RegisterXBMImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("XBM");
+ entry->decoder=(DecoderHandler) ReadXBMImage;
+ entry->encoder=(EncoderHandler) WriteXBMImage;
+ entry->magick=(MagickHandler) IsXBM;
+ entry->adjoin=False;
+ entry->description="X Windows system bitmap (black/white)";
+ entry->module="XBM";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r X B M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterXBMImage removes format registrations made by the
+% XBM module from the list of supported formats.
+%
+% The format of the UnregisterXBMImage method is:
+%
+% UnregisterXBMImage(void)
+%
+*/
+ModuleExport void UnregisterXBMImage(void)
+{
+ (void) UnregisterMagickInfo("XBM");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e X B M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure WriteXBMImage writes an image to a file in the X bitmap format.
+%
+% The format of the WriteXBMImage method is:
+%
+% unsigned int WriteXBMImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteXBMImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteXBMImage(const ImageInfo *image_info,Image *image)
+{
+ char
+ basename[MaxTextExtent],
+ buffer[MaxTextExtent];
+
+ int
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register const IndexPacket
+ *indexes;
+
+ unsigned char
+ bit,
+ byte,
+ polarity;
+
+ unsigned int
+ status;
+
+ unsigned long
+ count;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Write X bitmap header.
+ */
+ GetPathComponent(image->filename,BasePath,basename);
+ FormatString(buffer,"#define %.1024s_width %lu\n",basename,image->columns);
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ FormatString(buffer,"#define %.1024s_height %lu\n",basename,image->rows);
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ FormatString(buffer,"static char %.1024s_bits[] = {\n",basename);
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ (void) strcpy(buffer," ");
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ /*
+ Convert MIFF to X bitmap pixels.
+ */
+ (void) SetImageType(image,BilevelType);
+ polarity=(PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2));
+ if (image->colors == 2)
+ polarity=(PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]));
+ bit=0;
+ byte=0;
+ count=0;
+ x=0;
+ y=0;
+ (void) strcpy(buffer," ");
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte>>=1;
+ if (indexes[x] != polarity)
+ byte|=0x80;
+ bit++;
+ if (bit == 8)
+ {
+ /*
+ Write a bitmap byte to the image file.
+ */
+ FormatString(buffer,"0x%02X, ",(unsigned int) (byte & 0xff));
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ count++;
+ if (count == 12)
+ {
+ (void) strcpy(buffer,"\n ");
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ count=0;
+ };
+ bit=0;
+ byte=0;
+ }
+ p++;
+ }
+ if (bit != 0)
+ {
+ /*
+ Write a bitmap byte to the image file.
+ */
+ byte>>=(8-bit);
+ FormatString(buffer,"0x%02X, ",(unsigned int) (byte & 0xff));
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ count++;
+ if (count == 12)
+ {
+ (void) strcpy(buffer,"\n ");
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ count=0;
+ };
+ bit=0;
+ byte=0;
+ };
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) strcpy(buffer,"};\n");
+ (void) WriteBlob(image,strlen(buffer),buffer);
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/xc.c b/coders/xc.c
new file mode 100644
index 0000000..bf2fe95
--- /dev/null
+++ b/coders/xc.c
@@ -0,0 +1,194 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X X CCCC %
+% X X C %
+% X C %
+% X X C %
+% X X CCCC %
+% %
+% %
+% Read Constant Color Image. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/composite.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d X C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadXCImage creates a constant image and initializes it to the
+% X server color as specified by the filename. It allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% The format of the ReadXCImage method is:
+%
+% Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadXCImage returns a pointer to the image after
+% creating it. A null image is returned if there is a memory shortage
+% or if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ MagickPassFail
+ status;
+
+ /*
+ Initialize Image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ if (image->columns == 0)
+ image->columns=1;
+ if (image->rows == 0)
+ image->rows=1;
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ status=QueryColorDatabase((char *) image_info->filename,
+ &image->background_color,exception);
+ if (status == MagickFail)
+ {
+ DestroyImage(image);
+ return ((Image *) NULL);
+ }
+ /*
+ Create a colormap if image is not DirectClass type.
+ */
+ if ((TrueColorType != image_info->type) &&
+ (TrueColorMatteType != image_info->type))
+ {
+ if (!AllocateImageColormap(image,1))
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ image->colormap[0]=image->background_color;
+ }
+ /*
+ Initialize image pixels to the value of image->background_color
+ */
+ status=SetImageEx(image,image->background_color.opacity,exception);
+ if (status == MagickFail)
+ {
+ DestroyImage(image);
+ image=(Image *) NULL;
+ }
+
+ return image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r X C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterXCImage adds attributes for the XC image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterXCImage method is:
+%
+% RegisterXCImage(void)
+%
+*/
+ModuleExport void RegisterXCImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("XC");
+ entry->decoder=(DecoderHandler) ReadXCImage;
+ entry->adjoin=False;
+ entry->raw=True;
+ entry->description="Constant image uniform color";
+ entry->module="XC";
+ entry->coder_class=PrimaryCoderClass;
+ entry->extension_treatment=IgnoreExtensionTreatment;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r X C I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterXCImage removes format registrations made by the
+% XC module from the list of supported formats.
+%
+% The format of the UnregisterXCImage method is:
+%
+% UnregisterXCImage(void)
+%
+*/
+ModuleExport void UnregisterXCImage(void)
+{
+ (void) UnregisterMagickInfo("XC");
+}
diff --git a/coders/xcf.c b/coders/xcf.c
new file mode 100644
index 0000000..a4bd5b5
--- /dev/null
+++ b/coders/xcf.c
@@ -0,0 +1,1861 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X X CCCC FFFFF %
+% X X C F %
+% X C FFF %
+% X X C F %
+% X X CCCC F %
+% %
+% %
+% Read GIMP XCF Image Format. %
+% %
+% %
+% Software Design %
+% Leonard Rosenthol %
+% November 2001 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/composite.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/quantize.h"
+#include "magick/utility.h"
+
+/*
+ Typedef declarations.
+*/
+typedef enum
+{
+ GIMP_RGB,
+ GIMP_GRAY,
+ GIMP_INDEXED
+} GimpImageBaseType;
+
+typedef enum
+{
+ PROP_END = 0,
+ PROP_COLORMAP = 1,
+ PROP_ACTIVE_LAYER = 2,
+ PROP_ACTIVE_CHANNEL = 3,
+ PROP_SELECTION = 4,
+ PROP_FLOATING_SELECTION = 5,
+ PROP_OPACITY = 6,
+ PROP_MODE = 7,
+ PROP_VISIBLE = 8,
+ PROP_LINKED = 9,
+ PROP_PRESERVE_TRANSPARENCY = 10,
+ PROP_APPLY_MASK = 11,
+ PROP_EDIT_MASK = 12,
+ PROP_SHOW_MASK = 13,
+ PROP_SHOW_MASKED = 14,
+ PROP_OFFSETS = 15,
+ PROP_COLOR = 16,
+ PROP_COMPRESSION = 17,
+ PROP_GUIDES = 18,
+ PROP_RESOLUTION = 19,
+ PROP_TATTOO = 20,
+ PROP_PARASITES = 21,
+ PROP_UNIT = 22,
+ PROP_PATHS = 23,
+ PROP_USER_UNIT = 24
+} PropType;
+
+typedef enum
+{
+ COMPRESS_NONE = 0,
+ COMPRESS_RLE = 1,
+ COMPRESS_ZLIB = 2, /* unused */
+ COMPRESS_FRACTAL = 3 /* unused */
+} XcfCompressionType;
+
+typedef struct {
+ magick_uint32_t
+ width,
+ height,
+ image_type,
+ bpp; /* BYTES per pixel!! */
+
+ int
+ compression;
+
+ /* not really part of the doc, but makes it easy to pass around! */
+ ExceptionInfo
+ *exception;
+
+ /* File size */
+ magick_off_t
+ file_size;
+} XCFDocInfo;
+
+typedef struct {
+ char
+ name[1024];
+
+ unsigned int
+ active;
+
+ magick_uint32_t
+ width,
+ height,
+ type,
+ opacity,
+ visible,
+ linked,
+ preserve_trans,
+ apply_mask,
+ show_mask,
+ edit_mask,
+ floating_offset;
+
+ magick_int32_t
+ offset_x,
+ offset_y;
+
+ magick_uint32_t
+ mode,
+ tattoo;
+
+ Image
+ *image;
+} XCFLayerInfo;
+
+#define TILE_WIDTH 64
+#define TILE_HEIGHT 64
+
+typedef struct {
+ unsigned char
+ red,
+ green,
+ blue,
+ opacity; /* NOTE: reversed from IM! */
+} XCFPixelPacket;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s X C F %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsXCF returns True if the image format type, identified by the
+% magick string, is XCF (GIMP native format).
+%
+% The format of the IsXCF method is:
+%
+% unsigned int IsXCF(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsXCF returns True if the image format type is XCF.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsXCF(const unsigned char *magick,const size_t length)
+{
+ if (length < 8)
+ return(False);
+ if (LocaleNCompare((char *) magick,"gimp xcf",8) == 0)
+ return(True);
+ return(False);
+}
+
+
+typedef enum
+{
+ GIMP_NORMAL_MODE,
+ GIMP_DISSOLVE_MODE,
+ GIMP_BEHIND_MODE,
+ GIMP_MULTIPLY_MODE,
+ GIMP_SCREEN_MODE,
+ GIMP_OVERLAY_MODE,
+ GIMP_DIFFERENCE_MODE,
+ GIMP_ADDITION_MODE,
+ GIMP_SUBTRACT_MODE,
+ GIMP_DARKEN_ONLY_MODE,
+ GIMP_LIGHTEN_ONLY_MODE,
+ GIMP_HUE_MODE,
+ GIMP_SATURATION_MODE,
+ GIMP_COLOR_MODE,
+ GIMP_VALUE_MODE,
+ GIMP_DIVIDE_MODE,
+ GIMP_DODGE_MODE,
+ GIMP_BURN_MODE,
+ GIMP_HARDLIGHT_MODE
+} GimpLayerModeEffects;
+
+/*
+ Simple utility routine to convert between PSD blending modes and
+ GraphicsMagick compositing operators
+*/
+static CompositeOperator GIMPBlendModeToCompositeOperator( unsigned int blendMode )
+{
+ switch ( blendMode )
+ {
+ case GIMP_NORMAL_MODE: return( OverCompositeOp );
+ case GIMP_DISSOLVE_MODE: return( DissolveCompositeOp );
+ case GIMP_MULTIPLY_MODE: return( MultiplyCompositeOp );
+ case GIMP_SCREEN_MODE: return( ScreenCompositeOp );
+ case GIMP_OVERLAY_MODE: return( OverlayCompositeOp );
+ case GIMP_DIFFERENCE_MODE: return( DifferenceCompositeOp );
+ case GIMP_ADDITION_MODE: return( AddCompositeOp );
+ case GIMP_SUBTRACT_MODE: return( SubtractCompositeOp );
+ case GIMP_DARKEN_ONLY_MODE: return( DarkenCompositeOp );
+ case GIMP_LIGHTEN_ONLY_MODE:return( LightenCompositeOp );
+ case GIMP_HUE_MODE: return( HueCompositeOp );
+ case GIMP_SATURATION_MODE: return( SaturateCompositeOp );
+ case GIMP_COLOR_MODE: return( ColorizeCompositeOp );
+ case GIMP_DIVIDE_MODE: return( DivideCompositeOp );
+ case GIMP_HARDLIGHT_MODE: return( HardLightCompositeOp );
+ case GIMP_DODGE_MODE: return( ColorDodgeCompositeOp );
+ case GIMP_BURN_MODE: return( ColorBurnCompositeOp );
+ /* these are the ones we don't support...yet */
+ case GIMP_BEHIND_MODE: return( OverCompositeOp );
+ case GIMP_VALUE_MODE: return( OverCompositeOp );
+ default: return( OverCompositeOp );
+ }
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b S t r i n g W i t h L o n g S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobStringWithLongSize reads characters from a blob or file
+% starting with a long length byte and then characters to that length
+%
+% The format of the ReadBlobStringWithLongSize method is:
+%
+% char *ReadBlobStringWithLongSize(Image *image,char *string)
+%
+% A description of each parameter follows:
+%
+% o status: Method ReadBlobString returns the string on success, otherwise,
+% a null is returned.
+%
+% o image: The image.
+%
+% o string: The address of a character buffer.
+%
+% o max: Length of 'string' array.
+%
+%
+*/
+static char *ReadBlobStringWithLongSize(Image *image,char *string,size_t max)
+{
+ int
+ c;
+
+ register unsigned long
+ i;
+
+ unsigned long
+ length;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(max != 0);
+ length = ReadBlobMSBLong(image);
+ for (i=0; i < Min(length,max-1); i++)
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ return((char *) NULL);
+ string[i]=c;
+ }
+ string[i]='\0';
+ (void) SeekBlob(image, length-i, SEEK_CUR);
+ return(string);
+}
+
+
+static MagickPassFail load_tile (Image* image, Image* tile_image, XCFDocInfo* inDocInfo,
+ XCFLayerInfo* inLayerInfo, size_t data_length)
+{
+ size_t
+ nmemb_read_successfully;
+
+ unsigned long
+ x,
+ y;
+
+ PixelPacket
+ *q;
+
+ XCFPixelPacket
+ *xcfdata,
+ *xcfodata;
+
+ unsigned char
+ *graydata;
+
+ /*
+ Validate that claimed data length is sufficent for tile.
+ */
+ {
+ size_t
+ expected_data_length=0;
+
+ if (inDocInfo->image_type == GIMP_GRAY)
+ {
+ expected_data_length=tile_image->columns*tile_image->rows*
+ sizeof(unsigned char);
+ }
+ else if (inDocInfo->image_type == GIMP_RGB)
+ {
+ expected_data_length=tile_image->columns*tile_image->rows*
+ sizeof(XCFPixelPacket);
+ }
+ if (expected_data_length && (expected_data_length > data_length))
+ {
+ ThrowException(&image->exception,CorruptImageError,CorruptImage,
+ "Claimed tile data length is insufficient for tile data");
+ return MagickFail;
+ }
+ }
+
+ xcfdata = xcfodata = MagickAllocateMemory(XCFPixelPacket *,data_length);
+ graydata = (unsigned char *) xcfdata; /* used by gray and indexed */
+
+ if (xcfdata == (XCFPixelPacket *) NULL)
+ {
+ ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,NULL);
+ return MagickFail;
+ }
+
+ nmemb_read_successfully = ReadBlob(image, data_length, xcfdata);
+ if (nmemb_read_successfully != data_length)
+ {
+ MagickFreeMemory(xcfodata);
+ ThrowException(&image->exception,CorruptImageError,UnexpectedEndOfFile,
+ NULL);
+ return MagickFail;
+ }
+
+ q=SetImagePixels(tile_image,0,0,tile_image->columns,tile_image->rows);
+ if (q == (PixelPacket *) NULL)
+ {
+ CopyException(&image->exception,&tile_image->exception);
+ MagickFreeMemory(xcfodata);
+ return MagickFail;
+ }
+
+ for (x=0; x < tile_image->columns; x++)
+ {
+ if (inDocInfo->image_type == GIMP_GRAY)
+ {
+ for (y=tile_image->rows; y != 0; y--)
+ {
+ q->red =q->green=q->blue=ScaleCharToQuantum(*graydata);
+ q->opacity = ScaleCharToQuantum(255U-inLayerInfo->opacity);
+ graydata++;
+ q++;
+ }
+ }
+ else if (inDocInfo->image_type == GIMP_RGB)
+ {
+ for (y=tile_image->rows; y != 0; y--)
+ {
+ q->red = ScaleCharToQuantum(xcfdata->red);
+ q->green = ScaleCharToQuantum(xcfdata->green);
+ q->blue = ScaleCharToQuantum(xcfdata->blue);
+ q->opacity = (Quantum) (xcfdata->opacity==0U ? TransparentOpacity :
+ ScaleCharToQuantum(255U-inLayerInfo->opacity));
+ xcfdata++;
+ q++;
+ }
+ }
+ }
+
+ MagickFreeMemory(xcfodata);
+ return MagickPass;
+}
+
+static MagickPassFail load_tile_rle (Image* image,
+ Image* tile_image,
+ XCFDocInfo* inDocInfo,
+ XCFLayerInfo* inLayerInfo,
+ size_t data_length)
+{
+ unsigned char
+ data,
+ val;
+
+ magick_int64_t
+ size;
+
+ size_t
+ nmemb_read_successfully;
+
+ int
+ count,
+ length,
+ bpp, /* BYTES per pixel! */
+ i,
+ j;
+
+ unsigned char
+ *xcfdata,
+ *xcfodata,
+ *xcfdatalimit;
+
+ PixelPacket
+ *q;
+
+ bpp = (int) inDocInfo->bpp;
+
+ xcfdata = xcfodata = MagickAllocateMemory(unsigned char *,data_length);
+ if (xcfdata == (unsigned char *) NULL)
+ {
+ ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,NULL);
+ return MagickFail;
+ }
+
+ nmemb_read_successfully = ReadBlob(image, data_length, xcfdata);
+ if (nmemb_read_successfully != data_length)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Read %lu bytes, expected %lu bytes",
+ (unsigned long) nmemb_read_successfully,
+ (unsigned long) data_length);
+ MagickFreeMemory(xcfodata);
+ ThrowException(&image->exception,CorruptImageError,UnexpectedEndOfFile,
+ NULL);
+ return MagickFail;
+ }
+
+ xcfdatalimit = &xcfodata[nmemb_read_successfully - 1];
+
+ for (i = 0; i < bpp; i++)
+ {
+ q=SetImagePixels(tile_image,0,0,tile_image->columns,tile_image->rows);
+ if (q == (PixelPacket *) NULL)
+ {
+ CopyException(&image->exception,&tile_image->exception);
+ goto bogus_rle;
+ }
+ size = tile_image->rows * tile_image->columns;
+ count = 0;
+
+ while (size > 0)
+ {
+ if (xcfdata > xcfdatalimit)
+ {
+ goto bogus_rle;
+ }
+
+ val = *xcfdata++;
+
+ length = val;
+
+ if (length >= 128)
+ {
+ length = 255 - (length - 1);
+
+ if (length == 128)
+ {
+ if (xcfdata >= xcfdatalimit)
+ {
+ goto bogus_rle;
+ }
+
+ length = ((*xcfdata << 8) + xcfdata[1]) & 0xFFFF;
+ xcfdata += 2;
+ }
+
+ count += length;
+ size -= length;
+
+ if (size < 0)
+ {
+ goto bogus_rle;
+ }
+
+ if (&xcfdata[length-1] > xcfdatalimit)
+ {
+ goto bogus_rle;
+ }
+
+ while (length-- > 0)
+ {
+ data = *xcfdata++;
+ switch (i)
+ {
+ case 0:
+ {
+ q->red = ScaleCharToQuantum(data);
+ if ( inDocInfo->image_type == GIMP_GRAY )
+ {
+ q->green = ScaleCharToQuantum(data);
+ q->blue = ScaleCharToQuantum(data);
+ q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity);
+ }
+ else
+ {
+ q->green = q->red;
+ q->blue = q->red;
+ q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity);
+ }
+ break;
+ }
+ case 1:
+ {
+ q->green = ScaleCharToQuantum(data);
+ break;
+ }
+ case 2:
+ {
+ q->blue = ScaleCharToQuantum(data);
+ break;
+ }
+ case 3:
+ {
+ q->opacity = (Quantum) (data==0 ? TransparentOpacity :
+ ScaleCharToQuantum(255-inLayerInfo->opacity));
+ break;
+ }
+ }
+ q++;
+ }
+ }
+ else
+ {
+ length += 1;
+ if (length == 128)
+ {
+ if (xcfdata >= xcfdatalimit)
+ {
+ goto bogus_rle;
+ }
+
+ length = ((*xcfdata << 8) + xcfdata[1]) & 0xFFFF;
+ xcfdata += 2;
+ }
+
+ count += length;
+ size -= length;
+
+ if (size < 0)
+ {
+ goto bogus_rle;
+ }
+
+ if (xcfdata > xcfdatalimit)
+ {
+ goto bogus_rle;
+ }
+
+ val = *xcfdata++;
+
+ for (j = 0; j < length; j++)
+ {
+ data = val;
+ switch (i)
+ {
+ case 0:
+ {
+ q->red = ScaleCharToQuantum(data);
+ if ( inDocInfo->image_type == GIMP_GRAY )
+ {
+ q->green = ScaleCharToQuantum(data);
+ q->blue = ScaleCharToQuantum(data);
+ q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity);
+ }
+ else
+ {
+ q->green = q->red;
+ q->blue = q->red;
+ q->opacity = ScaleCharToQuantum(255-inLayerInfo->opacity);
+ }
+ break;
+ }
+ case 1:
+ {
+ q->green = ScaleCharToQuantum(data);
+ break;
+ }
+ case 2:
+ {
+ q->blue = ScaleCharToQuantum(data);
+ break;
+ }
+ case 3:
+ {
+ q->opacity = (Quantum) (data==0 ? TransparentOpacity :
+ ScaleCharToQuantum(255-inLayerInfo->opacity));
+ break;
+ }
+ }
+ q++;
+ }
+ }
+ }
+ if (SyncImagePixelsEx(tile_image,&tile_image->exception) == MagickFail)
+ break;
+ }
+ MagickFreeMemory(xcfodata);
+ return MagickPass;
+
+ bogus_rle:
+ if (xcfodata)
+ MagickFreeMemory(xcfodata);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Failed to RLE-decode tile");
+ ThrowBinaryException(CorruptImageError,CorruptImage,image->filename);
+ return MagickFail;
+}
+
+
+static MagickPassFail load_level (Image* image,
+ XCFDocInfo* inDocInfo,
+ XCFLayerInfo*
+ inLayerInfo)
+{
+ magick_off_t
+ saved_pos,
+ offset,
+ offset2;
+
+ unsigned long
+ width,
+ height;
+
+ unsigned long
+ ntiles,
+ ntile_rows,
+ ntile_cols;
+
+ size_t
+ tile_data_size;
+
+ int
+ i;
+
+ Image*
+ tile_image;
+
+ int
+ destLeft = 0,
+ destTop = 0,
+ tile_image_width,
+ tile_image_height;
+
+ MagickPassFail
+ status = MagickPass;
+
+ ExceptionInfo
+ *exception = inDocInfo->exception;
+
+ /* start reading the data */
+ width = ReadBlobMSBLong(image); /* width */
+ height = ReadBlobMSBLong(image); /* height */
+
+ /* read in the first tile offset.
+ * if it is '0', then this tile level is empty
+ * and we can simply return.
+ */
+ offset = ReadBlobMSBLong(image);
+ if (offset == 0)
+ return MagickPass;
+
+ if (offset >= inDocInfo->file_size)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Tile offset %ld (file size %lu)!",
+ (long) offset, (unsigned long) inDocInfo->file_size);
+ ThrowBinaryException(CorruptImageError,CorruptImage,image->filename);
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "load_level: dimensions %lux%lu, bpp %lu, offset %ld",
+ width,height,(unsigned long) inDocInfo->bpp,
+ (long) offset);
+
+ /*
+ Initialise the reference for the in-memory tile-compression
+ */
+ ntile_rows=(height+TILE_HEIGHT-1)/TILE_HEIGHT;
+ ntile_cols=(width+TILE_WIDTH-1)/TILE_WIDTH;
+ ntiles=ntile_rows*ntile_cols;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Tile: dimensions %lux%lu, number of tiles %lu",
+ ntile_cols,ntile_rows,ntiles);
+
+ for (i = 0; i < (long) ntiles; i++)
+ {
+ status = MagickPass;
+
+ if (offset == 0)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Tile: offset %ld!", (long) offset);
+ ThrowBinaryException(CorruptImageError,NotEnoughTiles,image->filename);
+ }
+
+ /*
+ save the current position as it is where the next tile offset
+ is stored.
+ */
+ saved_pos = TellBlob(image);
+ if (saved_pos < 0)
+ ThrowBinaryException(BlobError,UnableToObtainOffset,image->filename);
+
+ /*
+ read in the offset of the next tile so we can calculate the
+ amount of data needed for this tile
+ */
+ offset2 = ReadBlobMSBLong(image);
+ if (offset2 >= inDocInfo->file_size)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Tile: offset %ld (file size %lu)!",
+ (long) offset2, (unsigned long) inDocInfo->file_size);
+ ThrowBinaryException(CorruptImageError,CorruptImage,image->filename);
+ }
+
+ /* seek to the tile offset */
+ if (SeekBlob(image, offset, SEEK_SET) != offset)
+ ThrowBinaryException(CorruptImageError,InsufficientImageDataInFile,image->filename);
+
+ /* allocate the image for the tile
+ NOTE: the last tile in a row or column may not be a full tile!
+ */
+ tile_image_width=(size_t) (destLeft == (int) ntile_cols-1 ?
+ (int) width % TILE_WIDTH : TILE_WIDTH);
+ if (tile_image_width == 0) tile_image_width=TILE_WIDTH;
+ tile_image_height = (size_t) (destTop == (int) ntile_rows-1 ?
+ (int) height % TILE_HEIGHT : TILE_HEIGHT);
+ if (tile_image_height == 0) tile_image_height=TILE_HEIGHT;
+ tile_image=CloneImage(inLayerInfo->image, tile_image_width,
+ tile_image_height,True,exception);
+
+ /*
+ Compute the tile data size.
+ */
+ if (offset2 > offset)
+ {
+ /*
+ Tile data size is simply the difference in file offsets.
+ */
+ tile_data_size=offset2-offset;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Tile: start offset=%ld, end offset=%ld, data size=%lu",
+ (long) offset,(long) offset2,
+ (unsigned long) tile_data_size);
+ }
+ else
+ {
+ size_t
+ packet_size=4;
+
+ if (inDocInfo->image_type == GIMP_GRAY)
+ packet_size=1;
+
+ if (COMPRESS_NONE == inDocInfo->compression)
+ {
+ /*
+ If compression is not used then enforce expected tile size.
+ */
+ tile_data_size = tile_image->columns*tile_image->rows*packet_size;
+ }
+ else
+ {
+ /*
+ Estimate the tile size. First we estimate the tile
+ size, allowing for a possible expansion factor of 1.5.
+ Then we truncate to the file length, whichever is
+ smallest.
+ */
+ offset2 = offset + tile_image->columns*tile_image->rows * packet_size * 1.5;
+ tile_data_size = (size_t) offset2-offset;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "We estimated tile data size: %lu",
+ (unsigned long) tile_data_size);
+ offset2 = Min(offset2,GetBlobSize(image));
+ tile_data_size = (size_t) offset2-offset;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Final tile data size: %lu",
+ (unsigned long) tile_data_size);
+ if (offset2 <= offset)
+ ThrowBinaryException(CorruptImageError,UnexpectedEndOfFile,image->filename);
+ }
+ }
+
+ /* read in the tile */
+ switch (inDocInfo->compression)
+ {
+ case COMPRESS_NONE:
+ status=load_tile(image,tile_image,inDocInfo,inLayerInfo,
+ tile_data_size);
+ break;
+ case COMPRESS_RLE:
+ status=load_tile_rle(image,tile_image,inDocInfo,inLayerInfo,
+ tile_data_size);
+ break;
+ case COMPRESS_ZLIB:
+ ThrowBinaryException(CoderError,ZipCompressionNotSupported,
+ image->filename);
+ case COMPRESS_FRACTAL:
+ ThrowBinaryException(CoderError,FractalCompressionNotSupported,
+ image->filename);
+ }
+
+ if (MagickPass == status)
+ {
+ /*
+ Composite the tile onto the layer's image, and then
+ destroy it. We temporarily disable the progress monitor
+ so that the user does not see composition of individual
+ tiles.
+ */
+#if 0
+ const PixelPacket
+ *p;
+
+ PixelPacket
+ *q;
+
+ long
+ canvas_x,
+ canvas_y,
+ y;
+
+ unsigned long
+ tile_width;
+
+ canvas_x=destLeft*TILE_WIDTH;
+ tile_width=tile_image->columns;
+ for (y=0; y < (long) tile_image->columns; y++)
+ {
+ canvas_y=destTop*TILE_HEIGHT+y;
+ p=AcquireImagePixels(tile_image,0,y,tile_image->columns,1,
+ &inLayerInfo->image->exception);
+ q=GetImagePixels(inLayerInfo->image,canvas_x,canvas_y,
+ tile_image->columns,1);
+ if ((p != (const PixelPacket *) NULL) && (q != (PixelPacket *) NULL))
+ (void) memcpy(q,p,tile_image->columns*sizeof(PixelPacket));
+ else
+ printf("null pointer canvas: %lux%lu tile: %lux%lu+%ld+%ld !\n",
+ inLayerInfo->image->columns,inLayerInfo->image->rows,
+ tile_width,1LU,canvas_x,canvas_y);
+ }
+#else
+ MonitorHandler
+ handler;
+
+ long
+ canvas_x,
+ canvas_y;
+
+ canvas_x=destLeft*TILE_WIDTH;
+ canvas_y=destTop*TILE_HEIGHT;
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ (void) CompositeImageRegion(CopyCompositeOp,NULL,tile_image->columns,
+ tile_image->rows,tile_image,0,0,
+ inLayerInfo->image,canvas_x,
+ canvas_y,&inLayerInfo->image->exception);
+ (void) SetMonitorHandler(handler);
+#endif
+ }
+ DestroyImage(tile_image);
+ tile_image = (Image *) NULL;
+
+ /* adjust tile position */
+ destLeft++;
+ if (destLeft >= (int) ntile_cols)
+ {
+ destLeft = 0;
+ destTop++;
+ }
+
+ if (MagickPass != status)
+ return status;
+
+ /* restore the saved position so we'll be ready to
+ * read the next offset.
+ */
+ (void) SeekBlob(image, saved_pos, SEEK_SET);
+
+ /* read in the offset of the next tile */
+ offset = ReadBlobMSBLong(image);
+ if (offset != 0)
+ if (!MagickMonitorFormatted(offset,inDocInfo->file_size,
+ &image->exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+
+ if (offset != 0)
+ {
+ ThrowBinaryException(CorruptImageError,CorruptImage,image->filename);
+ }
+ else
+ {
+ (void) MagickMonitorFormatted(inDocInfo->file_size,
+ inDocInfo->file_size+1,&image->exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows);
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail load_hierarchy (Image *image, XCFDocInfo* inDocInfo, XCFLayerInfo*
+ inLayer)
+{
+ unsigned long
+ width,
+ height;
+
+ magick_off_t
+ saved_pos,
+ offset;
+
+ unsigned long
+ junk;
+
+ width=ReadBlobMSBLong(image); /* width */
+ height=ReadBlobMSBLong(image); /* height */
+ inDocInfo->bpp = ReadBlobMSBLong(image); /* bpp */
+
+ /* load in the levels...we make sure that the number of levels
+ * calculated when the TileManager was created is the same
+ * as the number of levels found in the file.
+ */
+ offset = ReadBlobMSBLong(image); /* top level */
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "load_hierarchy: dimensions %lux%lu, bpp=%lu, offset=%lu",
+ width,height,(unsigned long) inDocInfo->bpp,
+ (unsigned long) offset);
+
+ /* discard offsets for layers below first, if any.
+ */
+ do
+ {
+ junk = ReadBlobMSBLong(image);
+ }
+ while ((junk != 0) && (!EOFBlob(image)));
+
+ if (EOFBlob(image))
+ return MagickFail;
+
+ /* save the current position as it is where the
+ * next level offset is stored.
+ */
+ saved_pos = TellBlob(image);
+ if (saved_pos < 0)
+ ThrowBinaryException(BlobError,UnableToObtainOffset,image->filename);
+
+ /* seek to the level offset */
+ if (SeekBlob(image, offset, SEEK_SET) != offset)
+ ThrowBinaryException(CorruptImageError,InsufficientImageDataInFile,image->filename);
+
+ /* read in the level */
+ if (load_level (image, inDocInfo, inLayer) == MagickFail)
+ return MagickFail;
+
+ /* restore the saved position so we'll be ready to
+ * read the next offset.
+ */
+ if (SeekBlob(image, saved_pos, SEEK_SET) != saved_pos)
+ ThrowBinaryException(BlobError,UnableToSeekToOffset,image->filename);
+
+ return MagickPass;
+}
+
+
+static MagickPassFail ReadOneLayer( Image* image, XCFDocInfo* inDocInfo, XCFLayerInfo*
+ outLayer )
+{
+ unsigned int
+ i;
+
+ unsigned int
+ foundPropEnd = 0;
+
+ unsigned long
+ hierarchy_offset,
+ layer_mask_offset;
+
+ /* clear the block! */
+ (void) memset( outLayer, 0, sizeof( XCFLayerInfo ) );
+
+ /* read in the layer width, height, type and name */
+ outLayer->width = ReadBlobMSBLong(image);
+ outLayer->height = ReadBlobMSBLong(image);
+ outLayer->type = ReadBlobMSBLong(image);
+ (void) ReadBlobStringWithLongSize(image, outLayer->name,
+ sizeof(outLayer->name));
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Loading layer \"%s\", dimensions %lux%lu, type %lu",
+ outLayer->name,
+ (unsigned long) outLayer->width,
+ (unsigned long) outLayer->height,
+ (unsigned long) outLayer->type);
+
+ if (EOFBlob(image))
+ ThrowBinaryException(CorruptImageError,InsufficientImageDataInFile,image->filename);
+
+ /* allocate the image for this layer */
+ outLayer->image=CloneImage(image,outLayer->width, outLayer->height,True,
+ &image->exception);
+ if (outLayer->image == (Image *) NULL)
+ return MagickFail;
+
+ if (CheckImagePixelLimits(outLayer->image, &image->exception) != MagickPass)
+ ThrowBinaryException(ResourceLimitError,ImagePixelLimitExceeded,image->filename);
+
+ /* read the layer properties! */
+ foundPropEnd = 0;
+ while ( !foundPropEnd && !EOFBlob(image) )
+ {
+ PropType prop_type = (PropType) ReadBlobMSBLong(image);
+ size_t prop_size = ReadBlobMSBLong(image);
+
+ switch (prop_type)
+ {
+ case PROP_END:
+ foundPropEnd = 1;
+ break;
+ case PROP_ACTIVE_LAYER:
+ outLayer->active = 1;
+ break;
+ case PROP_FLOATING_SELECTION:
+ outLayer->floating_offset = ReadBlobMSBLong(image);
+ break;
+ case PROP_OPACITY:
+ outLayer->opacity = ReadBlobMSBLong(image);
+ break;
+ case PROP_VISIBLE:
+ outLayer->visible = ReadBlobMSBLong(image);
+ break;
+ case PROP_LINKED:
+ outLayer->linked = ReadBlobMSBLong(image);
+ break;
+ case PROP_PRESERVE_TRANSPARENCY:
+ outLayer->preserve_trans = ReadBlobMSBLong(image);
+ break;
+ case PROP_APPLY_MASK:
+ outLayer->apply_mask = ReadBlobMSBLong(image);
+ break;
+ case PROP_EDIT_MASK:
+ outLayer->edit_mask = ReadBlobMSBLong(image);
+ break;
+ case PROP_SHOW_MASK:
+ outLayer->show_mask = ReadBlobMSBLong(image);
+ break;
+ case PROP_OFFSETS:
+ outLayer->offset_x = (magick_int32_t) ReadBlobMSBLong(image);
+ outLayer->offset_y = (magick_int32_t) ReadBlobMSBLong(image);
+ break;
+ case PROP_MODE:
+ outLayer->mode = ReadBlobMSBLong(image);
+ break;
+ case PROP_TATTOO:
+ outLayer->preserve_trans = ReadBlobMSBLong(image);
+ break;
+ case PROP_PARASITES:
+ {
+ for (i=0; i < prop_size; i++ )
+ if (ReadBlobByte(image) == EOF)
+ break;
+
+ /*
+ long base = info->cp;
+ GimpParasite *p;
+ while (info->cp - base < prop_size)
+ {
+ p = xcf_load_parasite(info);
+ gimp_drawable_parasite_attach(GIMP_DRAWABLE(layer), p);
+ gimp_parasite_free(p);
+ }
+ if (info->cp - base != prop_size)
+ g_message ("Error detected while loading a layer's parasites");
+ */
+ }
+ break;
+ default:
+ /* g_message ("unexpected/unknown layer property: %d (skipping)",
+ prop_type); */
+
+ {
+ int buf[16];
+ size_t amount;
+
+ /* read over it... */
+ while (prop_size > 0 && !EOFBlob(image))
+ {
+ amount = Min (16, prop_size);
+ for (i=0; i < amount; i++)
+ if (ReadBlob(image, amount, &buf) != amount)
+ break;
+ prop_size -= Min (16, amount);
+ }
+ }
+ break;
+ }
+ }
+
+ if (!foundPropEnd)
+ return MagickFail;
+
+ /* clear the image based on the layer opacity */
+ if (SetImage(outLayer->image,(Quantum)(255-outLayer->opacity)) != MagickPass)
+ return MagickFail;
+
+ /* set the compositing mode */
+ outLayer->image->compose = GIMPBlendModeToCompositeOperator( outLayer->mode );
+ if ( outLayer->visible == False )
+ {
+ /* BOGUS: should really be separate member var! */
+ outLayer->image->compose = NoCompositeOp;
+ }
+
+ /* read the hierarchy and layer mask offsets */
+ hierarchy_offset = ReadBlobMSBLong(image);
+ layer_mask_offset = ReadBlobMSBLong(image);
+
+ /* read in the hierarchy */
+ if (SeekBlob(image, hierarchy_offset, SEEK_SET) != (magick_off_t) hierarchy_offset)
+ ThrowBinaryException(CorruptImageError,InsufficientImageDataInFile,image->filename);
+ if (load_hierarchy (image, inDocInfo, outLayer) == MagickFail)
+ return MagickFail;
+
+ /* read in the layer mask */
+ if (layer_mask_offset != 0)
+ {
+ if (SeekBlob(image, layer_mask_offset, SEEK_SET) != (magick_off_t) layer_mask_offset)
+ ThrowBinaryException(CorruptImageError,InsufficientImageDataInFile,image->filename);
+
+#if 0 /* BOGUS: support layer masks! */
+ layer_mask = xcf_load_layer_mask (info, gimage);
+ if (!layer_mask)
+ goto error;
+
+ /* set the offsets of the layer_mask */
+ GIMP_DRAWABLE (layer_mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x;
+ GIMP_DRAWABLE (layer_mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y;
+
+ gimp_layer_add_mask (layer, layer_mask, False);
+
+ layer->mask->apply_mask = apply_mask;
+ layer->mask->edit_mask = edit_mask;
+ layer->mask->show_mask = show_mask;
+#endif
+ }
+
+ /* attach the floating selection... */
+#if 0 /* BOGUS: we may need to read this, even if we don't support it! */
+ if (add_floating_sel)
+ {
+ GimpLayer *floating_sel;
+
+ floating_sel = info->floating_sel;
+ floating_sel_attach (floating_sel, GIMP_DRAWABLE (layer));
+ }
+#endif
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d X C F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadXCFImage reads a GIMP (GNU Image Manipulation Program) image
+% file and returns it. It allocates the memory necessary for the new Image
+% structure and returns a pointer to the new image.
+%
+% The format of the ReadXCFImage method is:
+%
+% image=ReadXCFImage(image_info)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadXCFImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define DestroyLayerInfo(number_layers,layer_info) \
+ do { \
+ size_t \
+ j; \
+ \
+ if (layer_info != (XCFLayerInfo *) NULL) \
+ { \
+ for (j=0; j < number_layers; j++) \
+ { \
+ if (layer_info[j].image != (Image *) NULL) \
+ { \
+ DestroyImage(layer_info[j].image); \
+ layer_info[j].image = (Image *) NULL; \
+ } \
+ } \
+ } \
+ MagickFreeMemory(layer_info); \
+ } while (0);
+static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ magick[14];
+
+ Image
+ *image;
+
+ unsigned int
+ status;
+
+ unsigned long
+ i,
+ image_type;
+
+ int
+ foundPropEnd = 0;
+
+ size_t
+ count;
+
+ XCFDocInfo
+ doc_info;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+ count=ReadBlob(image,14,(char *) magick);
+ if ((count == 0) ||
+ (LocaleNCompare((char *) magick,"gimp xcf",8) != 0))
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+ /* clear the docinfo stuff */
+ (void) memset( &doc_info, 0, sizeof(XCFDocInfo));
+ doc_info.exception = exception;
+
+ /* read the three simple values */
+ image->columns = doc_info.width = ReadBlobMSBLong(image);
+ image->rows = doc_info.height = ReadBlobMSBLong(image);
+ image_type = doc_info.image_type = ReadBlobMSBLong(image);
+
+ /*
+ Get file size to use for validation later.
+ */
+ doc_info.file_size=GetBlobSize(image);
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "XCF dimensions %lux%lu, type %s",
+ image->columns,image->rows,
+ (image_type == GIMP_RGB ? "RGB" :
+ (image_type == GIMP_GRAY ? "GRAY" :
+ (image_type == GIMP_INDEXED ? "INDEXED" :
+ "unknown"))));
+
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
+
+ /* setup some things about the image...*/
+ image->compression=NoCompression;
+ image->depth = 8;
+ if ( image_type == GIMP_RGB )
+ {
+ image->colorspace=RGBColorspace;
+ }
+ else if ( image_type == GIMP_GRAY )
+ {
+ image->colorspace=GRAYColorspace;
+ }
+ else if ( image_type == GIMP_INDEXED )
+ {
+ ThrowReaderException(CoderError,ColormapTypeNotSupported,image);
+ }
+ else
+ {
+ ThrowReaderException(CorruptImageError,ImageTypeNotSupported,image);
+ }
+ /*
+ SetImage can be very expensive and it is not clear that this one is
+ actually needed so comment it out for now.
+ */
+ /* (void) SetImage(image,OpaqueOpacity); */ /* until we know otherwise...*/
+ image->matte=True; /* XCF always has a matte! */
+
+ /* read properties */
+ while ( !foundPropEnd && !EOFBlob(image) )
+ {
+ PropType prop_type = (PropType) ReadBlobMSBLong(image);
+ size_t prop_size = ReadBlobMSBLong(image);
+
+ switch ( prop_type )
+ {
+ case PROP_END:
+ foundPropEnd = 1;
+ break;
+
+ case PROP_COLORMAP:
+ /* BOGUS: just skip it for now */
+ for (i=0; i <prop_size; i++ )
+ if (ReadBlobByte(image) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ /*
+ if (info->file_version == 0)
+ {
+ gint i;
+
+ g_message (_("XCF warning: version 0 of XCF file format\n"
+ "did not save indexed colormaps correctly.\n"
+ "Substituting grayscale map."));
+ info->cp +=
+ xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1);
+ gimage->cmap = g_new (guchar, gimage->num_cols*3);
+ xcf_seek_pos (info, info->cp + gimage->num_cols);
+ for (i = 0; i<gimage->num_cols; i++)
+ {
+ gimage->cmap[i*3+0] = i;
+ gimage->cmap[i*3+1] = i;
+ gimage->cmap[i*3+2] = i;
+ }
+ }
+ else
+ {
+ info->cp +=
+ xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1);
+ gimage->cmap = g_new (guchar, gimage->num_cols*3);
+ info->cp +=
+ xcf_read_int8 (info->fp,
+ (guint8*) gimage->cmap, gimage->num_cols*3);
+ }
+ */
+ break;
+
+ case PROP_COMPRESSION:
+ {
+ int c;
+ c = ReadBlobByte(image);
+ if (c == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,
+ image);
+ doc_info.compression = c;
+ if ((doc_info.compression != COMPRESS_NONE) &&
+ (doc_info.compression != COMPRESS_RLE) &&
+ (doc_info.compression != COMPRESS_ZLIB) &&
+ (doc_info.compression != COMPRESS_FRACTAL))
+ ThrowReaderException(CorruptImageError,CompressionNotValid,
+ image);
+ }
+ break;
+
+ case PROP_GUIDES:
+ {
+ /* just skip it - we don't care about guides */
+ for (i=0; i < prop_size; i++ )
+ if (ReadBlobByte(image) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,
+ image);
+ }
+ break;
+
+ case PROP_RESOLUTION:
+ {
+ /* float xres = (float) */ (void) ReadBlobMSBLong(image);
+ /* float yres = (float) */ (void) ReadBlobMSBLong(image);
+
+ /*
+ if (xres < GIMP_MIN_RESOLUTION || xres > GIMP_MAX_RESOLUTION ||
+ yres < GIMP_MIN_RESOLUTION || yres > GIMP_MAX_RESOLUTION)
+ {
+ g_message ("Warning, resolution out of range in XCF file");
+ xres = gimage->gimp->config->default_xresolution;
+ yres = gimage->gimp->config->default_yresolution;
+ }
+ */
+
+
+ /* BOGUS: we don't write these yet because we aren't
+ reading them properly yet :( */
+ /* image->x_resolution = xres; */
+ /* image->y_resolution = yres; */
+ }
+ break;
+
+ case PROP_TATTOO:
+ {
+ /* we need to read it, even if we ignore it */
+ /*unsigned long tattoo_state = */ (void) ReadBlobMSBLong(image);
+ }
+ break;
+
+ case PROP_PARASITES:
+ {
+ /* BOGUS: we may need these for IPTC stuff */
+ for (i=0; i < prop_size; i++ )
+ if (ReadBlobByte(image) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ /*
+ glong base = info->cp;
+ GimpParasite *p;
+
+ while (info->cp - base < prop_size)
+ {
+ p = xcf_load_parasite (info);
+ gimp_image_parasite_attach (gimage, p);
+ gimp_parasite_free (p);
+ }
+ if (info->cp - base != prop_size)
+ g_message ("Error detected while loading an image's parasites");
+ */
+ }
+ break;
+
+ case PROP_UNIT:
+ {
+ /* BOGUS: ignore for now... */
+ /*unsigned long unit = */ (void) ReadBlobMSBLong(image);
+ }
+ break;
+
+ case PROP_PATHS:
+ {
+ /* BOGUS: just skip it for now */
+ for (i=0; i < prop_size; i++ )
+ if (ReadBlobByte(image) == EOF)
+ ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+
+ /*
+ PathList *paths = xcf_load_bzpaths (gimage, info);
+ gimp_image_set_paths (gimage, paths);
+ */
+ }
+ break;
+
+ case PROP_USER_UNIT:
+ {
+ char unit_string[1000];
+ /*BOGUS: ignored for now */
+ /*float factor = (float) */ (void) ReadBlobMSBLong(image);
+ /* unsigned long digits = */ (void) ReadBlobMSBLong(image);
+ for (i=0; i < 5; i++)
+ (void) ReadBlobStringWithLongSize(image, unit_string,
+ sizeof(unit_string));
+ }
+ break;
+
+ default:
+ /* g_message ("unexpected/unknown image property: %d (skipping)",
+ prop_type); */
+
+ {
+ int buf[16];
+ size_t amount;
+
+ /* read over it... */
+ while (prop_size > 0) /* size_t prop_size, amount */
+ {
+ amount = Min (sizeof(buf), prop_size);
+ for (i=0; i < amount; i++)
+ {
+ amount = ReadBlob(image, amount, &buf);
+ if (amount == 0U)
+ ThrowReaderException(CorruptImageError,
+ UnexpectedEndOfFile,image);
+ }
+ prop_size -= Min (16U, amount);
+ }
+ }
+ break;
+ }
+ }
+
+ if (!foundPropEnd)
+ ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+ if (image_info->ping && (image_info->subrange != 0))
+ {
+ ; /* do nothing, we were just pinging! */
+ }
+ else
+ {
+ XCFLayerInfo
+ *layer_info;
+
+ unsigned long
+ number_layers = 0,
+ num_layers = 0;
+
+ long
+ current_layer = 0,
+ first_layer = 0,
+ last_layer = 0,
+ T = 0;
+
+ MagickBool
+ foundAllLayers = MagickFalse;
+
+ /* BIG HACK
+ because XCF doesn't include the layer count, and we
+ want to know it in advance in order to allocate memory,
+ we have to scan the layer offset list, and then reposition
+ the read pointer
+ */
+ magick_off_t oldPos = TellBlob(image);
+ if (oldPos < 0)
+ ThrowReaderException(BlobError,UnableToObtainOffset,image);
+ do
+ {
+ long
+ offset = (long) ReadBlobMSBLong(image);
+
+ if ( offset == 0 )
+ foundAllLayers = MagickTrue;
+ else
+ number_layers++;
+ } while ( !foundAllLayers );
+
+ if (SeekBlob(image, oldPos, SEEK_SET) != oldPos) /* restore the position! */
+ ThrowReaderException(BlobError,UnableToSeekToOffset,image);
+
+ first_layer = image_info->subimage;
+ num_layers = number_layers;
+ /* subrange==0 means read all the images */
+ if( image_info->subrange > 0UL && image_info->subrange < number_layers )
+ num_layers = image_info->subrange;
+ last_layer = first_layer + num_layers-1;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "XCF number_layers=%lu first_layer=%ld last_layer=%ld",
+ number_layers, first_layer, last_layer);
+
+ /* XCF has layers backwards, so this gets a bit complicated */
+ T = last_layer;
+ last_layer = number_layers - first_layer - 1;
+ first_layer = number_layers - T - 1;
+ number_layers = num_layers;
+
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "XCF reading layers %ld to %ld inclusive", first_layer,
+ last_layer);
+
+ /* allocate our array of layer info blocks */
+ layer_info=MagickAllocateArray(XCFLayerInfo *,
+ number_layers,
+ sizeof(XCFLayerInfo));
+ if (layer_info == (XCFLayerInfo *) NULL)
+ ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) memset(layer_info,0,number_layers*sizeof(XCFLayerInfo));
+
+ for ( ; ; )
+ {
+ magick_off_t
+ offset,
+ saved_pos;
+
+ MagickPassFail
+ layer_ok;
+
+ /* read in the offset of the next layer */
+ offset = ReadBlobMSBLong(image);
+
+ /* if the offset is 0 then we are at the end
+ * of the layer list.
+ */
+ if (offset == 0)
+ break;
+
+ /* save the current position as it is where the
+ * next layer offset is stored.
+ */
+ saved_pos = TellBlob(image);
+ if (saved_pos < 0)
+ {
+ MagickFreeMemory(layer_info);
+ ThrowReaderException(BlobError,UnableToObtainOffset,image);
+ }
+
+ if ( first_layer <= current_layer && current_layer <= last_layer )
+ {
+ /* seek to the layer offset */
+ if (SeekBlob(image, offset, SEEK_SET) != offset)
+ {
+ /* FIXME: CID 64064: leaks layer_info */
+ DestroyLayerInfo(number_layers,layer_info);
+ ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ }
+
+ /* read in the layer */
+ layer_ok = ReadOneLayer( image, &doc_info, &layer_info[current_layer-first_layer] );
+ if (!layer_ok)
+ {
+#if 0
+ int
+ j;
+
+ for (j=0; j <= (current_layer-first_layer); j++)
+ {
+ if (layer_info[j].image)
+ {
+ DestroyImage(layer_info[j].image);
+ layer_info[j].image = (Image *) NULL;
+ }
+ }
+ MagickFreeMemory(layer_info);
+#endif
+ DestroyLayerInfo(number_layers,layer_info);
+ CopyException(exception,&image->exception);
+ CloseBlob(image);
+ DestroyImageList(image);
+ return (Image *) NULL;
+ }
+ /* restore the saved position so we'll be ready to
+ * read the next offset.
+ */
+ if (SeekBlob(image, saved_pos, SEEK_SET) != saved_pos)
+ {
+ /* FIXME: CID 64064: leaks layer_info */
+ DestroyLayerInfo(number_layers,layer_info);
+ ThrowReaderException(BlobError,UnableToSeekToOffset,image);
+ }
+ }
+
+ current_layer++;
+ }
+
+ if ( number_layers == 1 )
+ {
+ /* composite the layer data onto the main image & then dispose the layer */
+ (void) CompositeImage(image, OverCompositeOp, layer_info[0].image,
+ layer_info[0].offset_x, layer_info[0].offset_y );
+ DestroyImage( layer_info[0].image );
+ layer_info[0].image = (Image *) NULL;
+ }
+ else
+ {
+#if 0
+ {
+ /* NOTE: XCF layers are REVERSED from composite order! */
+ long
+ j;
+
+ for (j=number_layers-1; j>=0; j--) {
+ /* BOGUS: need to consider layer blending modes!! */
+ if ( layer_info[j].visible ) { /* only visible ones, please! */
+ CompositeImage(image, OverCompositeOp, layer_info[j].image,
+ layer_info[j].offset_x, layer_info[j].offset_y );
+ DestroyImage( layer_info[j].image );
+ layer_info[j].image = (Image *) NULL;
+ }
+ }
+ }
+#else
+ {
+ /* NOTE: XCF layers are REVERSED from composite order! */
+ long
+ j;
+
+ /* first we copy the last layer on top of the main image */
+ (void) CompositeImage(image, CopyCompositeOp, layer_info[number_layers-1].image,
+ layer_info[number_layers-1].offset_x,
+ layer_info[number_layers-1].offset_y );
+ DestroyImage( layer_info[number_layers-1].image );
+ layer_info[number_layers-1].image = (Image *) NULL;
+
+ /* now reverse the order of the layers as they are put
+ into subimages
+ */
+ image->next=layer_info[number_layers-2].image;
+ layer_info[number_layers-2].image->previous=image;
+ for (j=(long) number_layers-2; j >= 0; j--)
+ {
+ if (j > 0)
+ layer_info[j].image->next=layer_info[j-1].image;
+ if (j < ((long) number_layers-1))
+ layer_info[j].image->previous=layer_info[j+1].image;
+ layer_info[j].image->page.x = layer_info[j].offset_x;
+ layer_info[j].image->page.y = layer_info[j].offset_y;
+ layer_info[j].image->page.width = layer_info[j].width;
+ layer_info[j].image->page.height = layer_info[j].height;
+ }
+ }
+#endif
+ }
+
+ MagickFreeMemory(layer_info);
+
+#if 0 /* BOGUS: do we need the channels?? */
+ while (True)
+ {
+ /* read in the offset of the next channel */
+ info->cp += xcf_read_int32 (info->fp, &offset, 1);
+
+ /* if the offset is 0 then we are at the end
+ * of the channel list.
+ */
+ if (offset == 0)
+ break;
+
+ /* save the current position as it is where the
+ * next channel offset is stored.
+ */
+ saved_pos = info->cp;
+
+ /* seek to the channel offset */
+ xcf_seek_pos (info, offset);
+
+ /* read in the layer */
+ channel = xcf_load_channel (info, gimage);
+ if (!channel)
+ goto error;
+
+ num_successful_elements++;
+
+ /* add the channel to the image if its not the selection */
+ if (channel != gimage->selection_mask)
+ gimp_image_add_channel (gimage, channel, -1);
+
+ /* restore the saved position so we'll be ready to
+ * read the next offset.
+ */
+ xcf_seek_pos (info, saved_pos);
+ }
+#endif
+ }
+
+ CloseBlob(image);
+ if ( image_type == GIMP_GRAY )
+ image->is_grayscale=MagickTrue;
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r X C F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterXCFImage adds attributes for the XCF image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterXCFImage method is:
+%
+% RegisterXCFImage(void)
+%
+*/
+ModuleExport void RegisterXCFImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("XCF");
+ entry->decoder=(DecoderHandler) ReadXCFImage;
+ entry->magick=(MagickHandler) IsXCF;
+ entry->description="GIMP image";
+ entry->module="XCF";
+ entry->seekable_stream=True;
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r X C F I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterXCFImage removes format registrations made by the
+% XCF module from the list of supported formats.
+%
+% The format of the UnregisterXCFImage method is:
+%
+% UnregisterXCFImage(void)
+%
+*/
+ModuleExport void UnregisterXCFImage(void)
+{
+ (void) UnregisterMagickInfo("XCF");
+}
diff --git a/coders/xpm.c b/coders/xpm.c
new file mode 100644
index 0000000..418daa1
--- /dev/null
+++ b/coders/xpm.c
@@ -0,0 +1,1068 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X X PPPP M M %
+% X X P P MM MM %
+% X PPPP M M M %
+% X X P M M %
+% X X P M M %
+% %
+% %
+% Read/Write X Windows system Pixmap Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/quantize.h"
+#include "magick/resize.h"
+#include "magick/utility.h"
+
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WritePICONImage(const ImageInfo *,Image *),
+ WriteXPMImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s X P M %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsXPM returns True if the image format type, identified by the
+% magick string, is XPM.
+%
+% The format of the IsXPM method is:
+%
+% unsigned int IsXPM(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsXPM returns True if the image format type is XPM.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsXPM(const unsigned char *magick,const size_t length)
+{
+ if (length < 9)
+ return(False);
+ if (LocaleNCompare((char *) magick,"/* XPM */",9) == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d X P M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadXPMImage reads an X11 pixmap image file and returns it. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ReadXPMImage method is:
+%
+% Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadXPMImage returns a pointer to the image after
+% creating it. A null image is returned if there is a memory shortage
+% or if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+
+static char *ParseColor(char *data)
+{
+#define NumberTargets 6
+
+ static const char
+ * const targets[NumberTargets] = { "c ", "g ", "g4 ", "m ", "b ", "s " };
+
+ register char
+ *p,
+ *r;
+
+ register const char
+ *q;
+
+ register long
+ i;
+
+ for (i=0; i < NumberTargets; i++)
+ {
+ r=data;
+ for (q=targets[i]; *r != '\0'; r++)
+ {
+ if (*r != *q)
+ continue;
+ if (!isspace((int) (*(r-1))))
+ continue;
+ p=r;
+ for ( ; ; )
+ {
+ if (*q == '\0')
+ return(r);
+ if (*p++ != *q++)
+ break;
+ }
+ q=targets[i];
+ }
+ }
+ return((char *) NULL);
+}
+#define ThrowXPMReaderException(code_,reason_,image_) \
+do { \
+ if (keys) \
+ for (i=0; i < (long) image->colors; i++) \
+ MagickFreeMemory(keys[i]); \
+ MagickFreeMemory(keys); \
+ if (textlist) \
+ for (i=0; textlist[i] != (char *) NULL; i++) \
+ MagickFreeMemory(textlist[i]); \
+ MagickFreeMemory(textlist); \
+ MagickFreeMemory(xpm_buffer); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+
+static Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ key[MaxTextExtent],
+ **keys = (char **) NULL,
+ target[MaxTextExtent],
+ **textlist = (char **) NULL,
+ *xpm_buffer = (char *) NULL;
+
+ Image
+ *image;
+
+ int
+ count;
+
+ unsigned long
+ j,
+ none;
+
+ long
+ k,
+ y;
+
+ register char
+ *p,
+ *q;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *r;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ size_t
+ length;
+
+ unsigned long
+ width; /* characters per pixel */
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowXPMReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read XPM file.
+ */
+ length=MaxTextExtent;
+ xpm_buffer=MagickAllocateMemory(char *,length);
+ if (xpm_buffer != (char *) NULL)
+ {
+ xpm_buffer[0]='\0';
+ p=xpm_buffer;
+ while (ReadBlobString(image,p) != (char *) NULL)
+ {
+ if (*p == '#')
+ if ((p == xpm_buffer) || (*(p-1) == '\n'))
+ continue;
+ if ((*p == '}') && (*(p+1) == ';'))
+ break;
+ p+=strlen(p);
+ if (((size_t) (p-xpm_buffer)+MaxTextExtent+1) < length)
+ continue;
+ length<<=1;
+ MagickReallocMemory(char *,xpm_buffer,length);
+ if (xpm_buffer == (char *) NULL)
+ break;
+ p=xpm_buffer+strlen(xpm_buffer);
+ }
+ }
+ if (xpm_buffer == (char *) NULL)
+ ThrowXPMReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Remove comments.
+ */
+ count=0;
+ for (p=xpm_buffer; *p != '\0'; p++)
+ {
+ if (*p != '"')
+ continue;
+ count=sscanf(p+1,"%lu %lu %u %lu",&image->columns,&image->rows,
+ &image->colors,&width);
+ if (count == 4)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Columns: %lu, Rows: %lu, Colors: %u, Char Per Pixel: %lu",
+ image->columns, image->rows, image->colors, width);
+ break;
+ }
+ }
+ if ((count != 4) || (width == 0) || (width > 2) ||
+ (image->columns == 0) || (image->rows == 0) ||
+ (image->colors == 0) || (image->colors > MaxColormapSize))
+ ThrowXPMReaderException(CorruptImageError,ImproperImageHeader,image);
+ image->depth=16;
+ /*
+ Remove unquoted characters.
+ */
+ {
+ MagickBool inquote = MagickFalse;
+ q=xpm_buffer;
+ while (*p != '\0')
+ {
+ if (*p++ == '"')
+ {
+ if (inquote)
+ *q++='\n';
+ inquote = !inquote;
+ }
+ if (inquote)
+ *q++=*p;
+ }
+ *q='\0';
+ if (inquote)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Imbalanced quotes error");
+ ThrowXPMReaderException(CorruptImageError,CorruptImage,image);
+ }
+ }
+ textlist=StringToList(xpm_buffer);
+ MagickFreeMemory(xpm_buffer);
+ if (textlist == (char **) NULL)
+ ThrowXPMReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+#if 0
+ if (image->logging)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "TextList");
+ for (i=0; textlist[i] != (char *) NULL; i++)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " %lu: %s", i, textlist[i]);
+ }
+#endif
+
+ /*
+ Initialize image structure.
+ */
+ keys=MagickAllocateArray(char **,image->colors,sizeof(char *));
+ if (keys == (char **) NULL)
+ ThrowXPMReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (i=0; i < (long) image->colors; i++)
+ keys[i]=(char *) NULL;
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowXPMReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+
+ /*
+ Read image colormap.
+ */
+ i=1;
+ none=(~0U);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Parsing colormap...");
+ for (j=0; j < image->colors; j++)
+ {
+ p=textlist[i++];
+ if ((p == (char *) NULL) || (p[0] == '\0'))
+ break;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " %lu: %s", i-1, textlist[i-1]);
+ if (strlen(p) < width)
+ break;
+ keys[j]=MagickAllocateMemory(char *,width+1);
+ if (keys[j] == (char *) NULL)
+ ThrowXPMReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ keys[j][width]='\0';
+ (void) strncpy(keys[j],p,width);
+ /*
+ Parse color.
+ */
+ (void) strcpy(target,"gray");
+ q=ParseColor(p+width);
+ if (q != (char *) NULL)
+ {
+ while (!isspace((int) (*q)) && (*q != '\0'))
+ q++;
+ (void) strlcpy(target,q,MaxTextExtent);
+ q=ParseColor(target);
+ if (q != (char *) NULL)
+ *q='\0';
+ }
+ Strip(target);
+ if (LocaleCompare(target,"none") == 0)
+ {
+ image->storage_class=DirectClass;
+ image->matte=True;
+ none=j;
+ (void) strcpy(target,"black");
+ }
+ if (!QueryColorDatabase(target,&image->colormap[j],exception))
+ break;
+ }
+ if (j < image->colors)
+ ThrowXPMReaderException(CorruptImageError,CorruptImage,image);
+ image->depth=GetImageDepth(image,&image->exception);
+ image->depth=NormalizeDepthToOctet(image->depth);
+ j=0;
+ key[width]='\0';
+ if (!image_info->ping)
+ {
+ /*
+ Read image pixels.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Parsing pixels...");
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=textlist[i++];
+ if ((p == (char *) NULL) || (p[0] == '\0'))
+ break;
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " %lu: %s", i-1, textlist[i-1]);
+ r=SetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (r == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ /* (void) strncpy(key,p,width); */
+ for (k=0; k < (long) width; k++)
+ {
+ key[k]=p[k];
+ if (p[k] == '\0')
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (MagickFail == status)
+ break;
+ key[k]='\0';
+ if (strcmp(key,keys[j]) != 0)
+ for (j=0; j < Max(image->colors-1,1); j++)
+ if (strcmp(key,keys[j]) == 0)
+ break;
+ VerifyColormapIndex(image,j);
+ if (image->storage_class == PseudoClass)
+ indexes[x]=(IndexPacket) j;
+ *r=image->colormap[j];
+ r->opacity=(Quantum)
+ (j == none ? TransparentOpacity : OpaqueOpacity);
+ r++;
+ p+=width;
+ }
+ if (MagickFail == status)
+ break;
+ if (!SyncImagePixelsEx(image,exception))
+ break;
+ }
+ if (y < (long) image->rows)
+ ThrowXPMReaderException(CorruptImageError,InsufficientImageDataInFile,image);
+ }
+ /*
+ Free resources.
+ */
+ for (i=0; i < (long) image->colors; i++)
+ MagickFreeMemory(keys[i]);
+ MagickFreeMemory(keys);
+ for (i=0; textlist[i] != (char *) NULL; i++)
+ MagickFreeMemory(textlist[i]);
+ MagickFreeMemory(textlist);
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r X P M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterXPMImage adds attributes for the XPM image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterXPMImage method is:
+%
+% RegisterXPMImage(void)
+%
+*/
+ModuleExport void RegisterXPMImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("PICON");
+ entry->decoder=(DecoderHandler) ReadXPMImage;
+ entry->encoder=(EncoderHandler) WritePICONImage;
+ entry->adjoin=False;
+ entry->description="Personal Icon";
+ entry->module="XPM";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("PM");
+ entry->decoder=(DecoderHandler) ReadXPMImage;
+ entry->encoder=(EncoderHandler) WriteXPMImage;
+ entry->adjoin=False;
+ entry->stealth=True;
+ entry->description="X Windows system pixmap (color)";
+ entry->module="XPM";
+ (void) RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("XPM");
+ entry->decoder=(DecoderHandler) ReadXPMImage;
+ entry->encoder=(EncoderHandler) WriteXPMImage;
+ entry->magick=(MagickHandler) IsXPM;
+ entry->adjoin=False;
+ entry->description="X Windows system pixmap (color)";
+ entry->module="XPM";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r X P M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterXPMImage removes format registrations made by the
+% XPM module from the list of supported formats.
+%
+% The format of the UnregisterXPMImage method is:
+%
+% UnregisterXPMImage(void)
+%
+*/
+ModuleExport void UnregisterXPMImage(void)
+{
+ (void) UnregisterMagickInfo("PICON");
+ (void) UnregisterMagickInfo("PM");
+ (void) UnregisterMagickInfo("XPM");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e P I C O N I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure WritePICONImage writes an image to a file in the Personal Icon
+% format.
+%
+% The format of the WritePICONImage method is:
+%
+% unsigned int WritePICONImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WritePICONImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WritePICONImage(const ImageInfo *image_info,Image *image)
+{
+#define ColormapExtent 155
+#define GraymapExtent 95
+#define PiconGeometry "48x48>"
+
+ static const unsigned char
+ Colormap[]=
+ {
+ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x06, 0x00, 0x05, 0x00, 0xf4, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x2f, 0x4f, 0x4f, 0x70, 0x80, 0x90, 0x7e, 0x7e,
+ 0x7e, 0xdc, 0xdc, 0xdc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0xff, 0x1e, 0x90, 0xff, 0x87, 0xce, 0xeb, 0xe6, 0xe6, 0xfa, 0x00, 0xff,
+ 0xff, 0x80, 0x00, 0x80, 0xb2, 0x22, 0x22, 0x2e, 0x8b, 0x57, 0x32, 0xcd,
+ 0x32, 0x00, 0xff, 0x00, 0x98, 0xfb, 0x98, 0xff, 0x00, 0xff, 0xff, 0x00,
+ 0x00, 0xff, 0x63, 0x47, 0xff, 0xa5, 0x00, 0xff, 0xd7, 0x00, 0xff, 0xff,
+ 0x00, 0xee, 0x82, 0xee, 0xa0, 0x52, 0x2d, 0xcd, 0x85, 0x3f, 0xd2, 0xb4,
+ 0x8c, 0xf5, 0xde, 0xb3, 0xff, 0xfa, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x05, 0x18, 0x20, 0x10, 0x08,
+ 0x03, 0x51, 0x18, 0x07, 0x92, 0x28, 0x0b, 0xd3, 0x38, 0x0f, 0x14, 0x49,
+ 0x13, 0x55, 0x59, 0x17, 0x96, 0x69, 0x1b, 0xd7, 0x85, 0x00, 0x3b,
+ },
+ Graymap[]=
+ {
+ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x04, 0x00, 0x04, 0x00, 0xf3, 0x0f,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x21, 0x21, 0x21, 0x33, 0x33,
+ 0x33, 0x45, 0x45, 0x45, 0x54, 0x54, 0x54, 0x66, 0x66, 0x66, 0x78, 0x78,
+ 0x78, 0x87, 0x87, 0x87, 0x99, 0x99, 0x99, 0xab, 0xab, 0xab, 0xba, 0xba,
+ 0xba, 0xcc, 0xcc, 0xcc, 0xde, 0xde, 0xde, 0xed, 0xed, 0xed, 0xff, 0xff,
+ 0xff, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x0c, 0x10, 0x04, 0x31,
+ 0x48, 0x31, 0x07, 0x25, 0xb5, 0x58, 0x73, 0x4f, 0x04, 0x00, 0x3b,
+ };
+
+#define MaxCixels 92
+
+ static const char
+ Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk"
+ "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
+
+ char
+ buffer[MaxTextExtent],
+ basename[MaxTextExtent],
+ name[MaxTextExtent],
+ symbol[MaxTextExtent];
+
+ Image
+ *picon,
+ *map;
+
+ int
+ j;
+
+ long
+ k,
+ y;
+
+ RectangleInfo
+ geometry;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ status,
+ transparent;
+
+ unsigned long
+ characters_per_pixel,
+ colors;
+
+ ImageCharacteristics
+ characteristics;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ /*
+ Open output image file.
+ */
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Ensure that image is in an RGB space.
+ */
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Analyze image to be written.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,
+ (OptimizeType == image_info->type),
+ &image->exception))
+ {
+ CloseBlob(image);
+ return MagickFail;
+ }
+ SetGeometry(image,&geometry);
+ (void) GetMagickGeometry(PiconGeometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ picon=ThumbnailImage(image,geometry.width,geometry.height,&image->exception);
+ if ((image_info->type != TrueColorType) &&
+ (characteristics.grayscale))
+ map=BlobToImage(image_info,Graymap,GraymapExtent,&image->exception);
+ else
+ map=BlobToImage(image_info,Colormap,ColormapExtent,&image->exception);
+ if ((picon == (Image *) NULL) || (map == (Image *) NULL))
+ return(False);
+ status=MapImage(picon,map,image_info->dither);
+ DestroyImage(map);
+ transparent=False;
+ if (picon->storage_class == PseudoClass)
+ {
+ CompressImageColormap(picon);
+ if (picon->matte)
+ transparent=True;
+ }
+ else
+ {
+ /*
+ Convert DirectClass to PseudoClass picon.
+ */
+ if (picon->matte)
+ {
+ /*
+ Map all the transparent pixels.
+ */
+ for (y=0; y < (long) picon->rows; y++)
+ {
+ q=GetImagePixels(picon,0,y,picon->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) picon->columns; x++)
+ {
+ if (q->opacity == TransparentOpacity)
+ transparent=True;
+ else
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ if (!SyncImagePixels(picon))
+ break;
+ }
+ }
+ (void) SetImageType(picon,PaletteType);
+ }
+ colors=picon->colors;
+ if (transparent)
+ {
+ colors++;
+ MagickReallocMemory(PixelPacket *,picon->colormap,colors*sizeof(PixelPacket));
+ for (y=0; y < (long) picon->rows; y++)
+ {
+ register IndexPacket
+ *indexes;
+
+ q=GetImagePixels(picon,0,y,picon->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(picon);
+ for (x=0; x < (long) picon->columns; x++)
+ {
+ if (q->opacity == TransparentOpacity)
+ indexes[x]=(IndexPacket) picon->colors;
+ q++;
+ }
+ if (!SyncImagePixels(picon))
+ break;
+ }
+ }
+ /*
+ Compute the character per pixel.
+ */
+ characters_per_pixel=1;
+ for (k=MaxCixels; (long) colors > k; k*=MaxCixels)
+ characters_per_pixel++;
+ /*
+ XPM header.
+ */
+ (void) WriteBlobString(image,"/* XPM */\n");
+ GetPathComponent(picon->filename,BasePath,basename);
+ (void) FormatString(buffer,"static char *%.1024s[] = {\n",basename);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n");
+ FormatString(buffer,"\"%lu %lu %lu %ld\",\n",picon->columns,picon->rows,
+ colors,characters_per_pixel);
+ (void) WriteBlobString(image,buffer);
+ for (i=0; i < (long) colors; i++)
+ {
+ /*
+ Define XPM color.
+ */
+ picon->colormap[i].opacity=OpaqueOpacity;
+ (void) QueryColorname(picon,picon->colormap+i,XPMCompliance,name,
+ &picon->exception);
+ if (transparent)
+ {
+ if (i == (long) (colors-1))
+ (void) strcpy(name,"grey75");
+ }
+ /*
+ Write XPM color.
+ */
+ k=i % MaxCixels;
+ symbol[0]=Cixel[k];
+ for (j=1; j < (long) characters_per_pixel; j++)
+ {
+ k=((i-k)/MaxCixels) % MaxCixels;
+ symbol[j]=Cixel[k];
+ }
+ symbol[j]='\0';
+ FormatString(buffer,"\"%.1024s c %.1024s\",\n",symbol,name);
+ (void) WriteBlobString(image,buffer);
+ }
+ /*
+ Define XPM pixels.
+ */
+ (void) WriteBlobString(image,"/* pixels */\n");
+ for (y=0; y < (long) picon->rows; y++)
+ {
+ register const IndexPacket
+ *indexes;
+
+ p=AcquireImagePixels(picon,0,y,picon->columns,1,&picon->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(picon);
+ (void) WriteBlobString(image,"\"");
+ for (x=0; x < (long) picon->columns; x++)
+ {
+ k=indexes[x] % MaxCixels;
+ symbol[0]=Cixel[k];
+ for (j=1; j < (long) characters_per_pixel; j++)
+ {
+ k=(((int) indexes[x]-k)/MaxCixels) % MaxCixels;
+ symbol[j]=Cixel[k];
+ }
+ symbol[j]='\0';
+ (void) strlcpy(buffer,symbol,MaxTextExtent);
+ (void) WriteBlobString(image,buffer);
+ }
+ FormatString(buffer,"\"%.1024s\n",
+ (y == (long) (picon->rows-1) ? "" : ","));
+ (void) WriteBlobString(image,buffer);
+ if (QuantumTick(y,picon->rows))
+ if (!MagickMonitorFormatted(y,picon->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ DestroyImage(picon);
+ (void) WriteBlobString(image,"};\n");
+ CloseBlob(image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e X P M I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure WriteXPMImage writes an image to a file in the X pixmap format.
+%
+% The format of the WriteXPMImage method is:
+%
+% unsigned int WriteXPMImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteXPMImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteXPMImage(const ImageInfo *image_info,Image *image)
+{
+#define MaxCixels 92
+
+ static const char
+ Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk"
+ "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
+
+ char
+ buffer[MaxTextExtent],
+ basename[MaxTextExtent],
+ name[MaxTextExtent],
+ symbol[MaxTextExtent];
+
+ int
+ j;
+
+ long
+ k,
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ status,
+ transparent;
+
+ unsigned long
+ characters_per_pixel,
+ colors;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Limit color resolution to what XPM can traditionally handle
+ */
+ if (image->depth > 16)
+ image->depth=16;
+ transparent=False;
+ if (image->storage_class == PseudoClass)
+ {
+ CompressImageColormap(image);
+ if (image->matte)
+ transparent=True;
+ }
+ else
+ {
+ /*
+ Convert DirectClass to PseudoClass image.
+ */
+ if (image->matte)
+ {
+ /*
+ Map all the transparent pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (q->opacity == TransparentOpacity)
+ transparent=True;
+ else
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+ (void) SetImageType(image,PaletteType);
+ }
+ colors=image->colors;
+ if (transparent)
+ {
+ colors++;
+ MagickReallocMemory(PixelPacket *,image->colormap,colors*sizeof(PixelPacket));
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register IndexPacket
+ *indexes;
+
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (q->opacity == TransparentOpacity)
+ indexes[x]=(IndexPacket) image->colors;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+ /*
+ Compute the character per pixel.
+ */
+ characters_per_pixel=1;
+ for (k=MaxCixels; (long) colors > k; k*=MaxCixels)
+ characters_per_pixel++;
+ /*
+ XPM header.
+ */
+ (void) WriteBlobString(image,"/* XPM */\n");
+ GetPathComponent(image->filename,BasePath,basename);
+ (void) FormatString(buffer,"static char *%.1024s[] = {\n",basename);
+ (void) WriteBlobString(image,buffer);
+ (void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n");
+ FormatString(buffer,"\"%lu %lu %lu %ld\",\n",image->columns,
+ image->rows,colors,characters_per_pixel);
+ (void) WriteBlobString(image,buffer);
+ for (i=0; i < (long) colors; i++)
+ {
+ /*
+ Define XPM color.
+ */
+ image->colormap[i].opacity=OpaqueOpacity;
+ (void) QueryColorname(image,image->colormap+i,XPMCompliance,name,
+ &image->exception);
+ if (transparent)
+ {
+ if (i == (long) (colors-1))
+ (void) strcpy(name,"None");
+ }
+ /*
+ Write XPM color.
+ */
+ k=i % MaxCixels;
+ symbol[0]=Cixel[k];
+ for (j=1; j < (long) characters_per_pixel; j++)
+ {
+ k=((i-k)/MaxCixels) % MaxCixels;
+ symbol[j]=Cixel[k];
+ }
+ symbol[j]='\0';
+ FormatString(buffer,"\"%.1024s c %.1024s\",\n",symbol,name);
+ (void) WriteBlobString(image,buffer);
+ }
+ /*
+ Define XPM pixels.
+ */
+ (void) WriteBlobString(image,"/* pixels */\n");
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register const IndexPacket
+ *indexes;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ (void) WriteBlobString(image,"\"");
+ for (x=0; x < (long) image->columns; x++)
+ {
+ k=indexes[x] % MaxCixels;
+ symbol[0]=Cixel[k];
+ for (j=1; j < (long) characters_per_pixel; j++)
+ {
+ k=(((int) indexes[x]-k)/MaxCixels) % MaxCixels;
+ symbol[j]=Cixel[k];
+ }
+ symbol[j]='\0';
+ (void) strlcpy(buffer,symbol,MaxTextExtent);
+ (void) WriteBlobString(image,buffer);
+ }
+ FormatString(buffer,"\"%.1024s\n",
+ (y == (long) (image->rows-1) ? "" : ","));
+ (void) WriteBlobString(image,buffer);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ (void) WriteBlobString(image,"};\n");
+ CloseBlob(image);
+ return(True);
+}
diff --git a/coders/xwd.c b/coders/xwd.c
new file mode 100644
index 0000000..5490efa
--- /dev/null
+++ b/coders/xwd.c
@@ -0,0 +1,913 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X X W W DDDD %
+% X X W W D D %
+% X W W D D %
+% X X W W W D D %
+% X X W W DDDD %
+% %
+% %
+% Read/Write X Windows System Window Dump Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteXWDImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s X W D %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsXWD returns True if the image format type, identified by the
+% magick string, is XWD.
+%
+% The format of the IsXWD method is:
+%
+% unsigned int IsXWD(const unsigned char *magick,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsXWD returns True if the image format type is XWD.
+%
+% o magick: This string is generally the first few bytes of an image file
+% or blob.
+%
+% o length: Specifies the length of the magick string.
+%
+%
+*/
+static unsigned int IsXWD(const unsigned char *magick,const size_t length)
+{
+ if (length < 8)
+ return(False);
+ if (memcmp(magick+1,"\000\000",2) == 0)
+ {
+ if (memcmp(magick+4,"\007\000\000",3) == 0)
+ return(True);
+ if (memcmp(magick+5,"\000\000\007",3) == 0)
+ return(True);
+ }
+ return(False);
+}
+
+#if defined(HasX11)
+#include "magick/xwindow.h"
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d X W D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadXWDImage reads an X Window System window dump image file and
+% returns it. It allocates the memory necessary for the new Image structure
+% and returns a pointer to the new image.
+%
+% The format of the ReadXWDImage method is:
+%
+% Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadXWDImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowXWDReaderException(code_,reason_,image_) \
+do { \
+ MagickFreeMemory(comment); \
+ if (ximage) \
+ MagickFreeMemory(ximage->data); \
+ MagickFreeMemory(ximage); \
+ MagickFreeMemory(colors); \
+ ThrowReaderException(code_,reason_,image_); \
+} while (0);
+
+static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ *comment = (char *) NULL;
+
+ Image
+ *image;
+
+ IndexPacket
+ index_val;
+
+ int
+ status;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned long
+ pixel;
+
+ size_t
+ count,
+ length;
+
+ unsigned long
+ lsb_first;
+
+ XColor
+ *colors = (XColor *) NULL;
+
+ XImage
+ *ximage = (XImage *) NULL;
+
+ XWDFileHeader
+ header;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ image=AllocateImage(image_info);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowXWDReaderException(FileOpenError,UnableToOpenFile,image);
+ /*
+ Read in header information.
+
+ XWDFileHeader is defined in /usr/include/X11/XWDFile.h
+
+ All elements are 32-bit unsigned storage but non-mask properties
+ in XImage use 32-bit signed values.
+ */
+ count=ReadBlob(image,sz_XWDheader,(char *) &header);
+ if (count != sz_XWDheader)
+ ThrowXWDReaderException(CorruptImageError,UnableToReadImageHeader,image);
+ /*
+ Ensure the header byte-order is most-significant byte first.
+ */
+ lsb_first=1;
+ if (*(char *) &lsb_first)
+ MSBOrderLong((unsigned char *) &header,sz_XWDheader);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "XWDFileHeader:\n"
+ " header_size : %u\n"
+ " file_version : %u\n"
+ " pixmap_format : %s\n"
+ " pixmap_depth : %u\n"
+ " pixmap_width : %u\n"
+ " pixmap_height : %u\n"
+ " xoffset : %u\n"
+ " byte_order : %s\n"
+ " bitmap_unit : %u\n"
+ " bitmap_bit_order : %s\n"
+ " bitmap_pad : %u\n"
+ " bits_per_pixel : %u\n"
+ " bytes_per_line : %u\n"
+ " visual_class : %s\n"
+ " red_mask : 0x%06X\n"
+ " green_mask : 0x%06X\n"
+ " blue_mask : 0x%06X\n"
+ " bits_per_rgb : %u\n"
+ " colormap_entries : %u\n"
+ " ncolors : %u\n"
+ " window_width : %u\n"
+ " window_height : %u\n"
+ " window_x : %u\n"
+ " window_y : %u\n"
+ " window_bdrwidth : %u",
+ (unsigned int) header.header_size,
+ (unsigned int) header.file_version,
+ /* (unsigned int) header.pixmap_format, */
+ (header.pixmap_format == XYBitmap ? "XYBitmap" :
+ (header.pixmap_format == XYPixmap ? "XYPixmap" :
+ (header.pixmap_format == ZPixmap ? "ZPixmap" : "?"))),
+ (unsigned int) header.pixmap_depth,
+ (unsigned int) header.pixmap_width,
+ (unsigned int) header.pixmap_height,
+ (unsigned int) header.xoffset,
+ (header.byte_order == MSBFirst? "MSBFirst" :
+ (header.byte_order == LSBFirst ? "LSBFirst" : "?")),
+ (unsigned int) header.bitmap_unit,
+ (header.bitmap_bit_order == MSBFirst? "MSBFirst" :
+ (header.bitmap_bit_order == LSBFirst ? "LSBFirst" :
+ "?")),
+ (unsigned int) header.bitmap_pad,
+ (unsigned int) header.bits_per_pixel,
+ (unsigned int) header.bytes_per_line,
+ (header.visual_class == StaticGray ? "StaticGray" :
+ (header.visual_class == GrayScale ? "GrayScale" :
+ (header.visual_class == StaticColor ? "StaticColor" :
+ (header.visual_class == PseudoColor ? "PseudoColor" :
+ (header.visual_class == TrueColor ? "TrueColor" :
+ (header.visual_class == DirectColor ?
+ "DirectColor" : "?")))))),
+ (unsigned int) header.red_mask,
+ (unsigned int) header.green_mask,
+ (unsigned int) header.blue_mask,
+ (unsigned int) header.bits_per_rgb,
+ (unsigned int) header.colormap_entries,
+ (unsigned int) header.ncolors,
+ (unsigned int) header.window_width,
+ (unsigned int) header.window_height,
+ (unsigned int) header.window_x,
+ (unsigned int) header.window_y,
+ (unsigned int) header.window_bdrwidth
+ );
+
+ /*
+ Check to see if the dump file is in the proper format.
+ */
+ if (header.file_version != XWD_FILE_VERSION)
+ ThrowXWDReaderException(CorruptImageError,InvalidFileFormatVersion,image);
+ if (header.header_size < sz_XWDheader)
+ ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+ switch (header.visual_class)
+ {
+ case StaticGray:
+ case GrayScale:
+ case StaticColor:
+ case PseudoColor:
+ case TrueColor:
+ case DirectColor:
+ break;
+ default:
+ {
+ ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+ }
+ }
+ switch (header.pixmap_format)
+ {
+ case XYBitmap:
+ case XYPixmap:
+ case ZPixmap:
+ break;
+ default:
+ {
+ ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+ }
+ }
+
+ /*
+ Retrieve comment (if any)
+ */
+ length=header.header_size-sz_XWDheader;
+ if (length > ((~0UL)/sizeof(*comment)))
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ comment=MagickAllocateMemory(char *,length+1);
+ if (comment == (char *) NULL)
+ ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ count=ReadBlob(image,length,comment);
+ if (count != length)
+ ThrowXWDReaderException(CorruptImageError,UnableToReadWindowNameFromDumpFile,
+ image);
+ comment[length]='\0';
+ (void) SetImageAttribute(image,"comment",comment);
+ MagickFreeMemory(comment);
+
+ /*
+ Initialize the X image.
+ */
+ ximage=MagickAllocateMemory(XImage *,sizeof(XImage));
+ if (ximage == (XImage *) NULL)
+ ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ ximage->depth=(int) header.pixmap_depth;
+ ximage->format=(int) header.pixmap_format;
+ ximage->xoffset=(int) header.xoffset;
+ ximage->data=(char *) NULL;
+ ximage->width=(int) header.pixmap_width;
+ ximage->height=(int) header.pixmap_height;
+ ximage->bitmap_pad=(int) header.bitmap_pad;
+ ximage->bytes_per_line=(int) header.bytes_per_line;
+ ximage->byte_order=(int) header.byte_order;
+ ximage->bitmap_unit=(int) header.bitmap_unit;
+ ximage->bitmap_bit_order=(int) header.bitmap_bit_order;
+ ximage->bits_per_pixel=(int) header.bits_per_pixel;
+ ximage->red_mask=header.red_mask;
+ ximage->green_mask=header.green_mask;
+ ximage->blue_mask=header.blue_mask;
+ /*
+ XImage uses signed integers rather than unsigned. Check for
+ overflow due to assignment.
+ */
+ if (ximage->width < 0 ||
+ ximage->height < 0 ||
+ ximage->format < 0 ||
+ ximage->byte_order < 0 ||
+ ximage->bitmap_unit < 0 ||
+ ximage->bitmap_bit_order < 0 ||
+ ximage->bitmap_pad < 0 ||
+ ximage->depth < 0 ||
+ ximage->bytes_per_line < 0 ||
+ ximage->bits_per_pixel < 0)
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ /* Guard against buffer overflow in libX11. */
+ if (ximage->bits_per_pixel > 32 || ximage->bitmap_unit > 32)
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ status=XInitImage(ximage);
+ if (status == False)
+ ThrowXWDReaderException(CorruptImageError,UnrecognizedXWDHeader,image);
+ image->columns=ximage->width;
+ image->rows=ximage->height;
+ if (!image_info->ping)
+ if (CheckImagePixelLimits(image, exception) != MagickPass)
+ ThrowXWDReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+ image->depth=8;
+ if ((header.ncolors == 0U) ||
+ ((ximage->red_mask != 0) ||
+ (ximage->green_mask != 0) ||
+ (ximage->blue_mask != 0)))
+ {
+ image->storage_class=DirectClass;
+ if (!image_info->ping)
+ if ((ximage->red_mask == 0) ||
+ (ximage->green_mask == 0) ||
+ (ximage->blue_mask == 0))
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ }
+ else
+ {
+ image->storage_class=PseudoClass;
+ }
+ image->colors=header.ncolors;
+ if (!image_info->ping)
+ {
+ /*
+ Read colormap.
+ */
+ colors=(XColor *) NULL;
+ if (header.ncolors != 0)
+ {
+ XWDColor
+ color;
+
+ register long
+ i;
+
+ length=(size_t) header.ncolors;
+ if (length > ((~0UL)/sizeof(*colors)))
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ colors=MagickAllocateArray(XColor *,length,sizeof(XColor));
+ if (colors == (XColor *) NULL)
+ ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ for (i=0; i < (long) header.ncolors; i++)
+ {
+ count=ReadBlob(image,sz_XWDColor,(char *) &color);
+ if (count != sz_XWDColor)
+ ThrowXWDReaderException(CorruptImageError,
+ UnableToReadColormapFromDumpFile,image);
+ colors[i].pixel=color.pixel;
+ colors[i].red=color.red;
+ colors[i].green=color.green;
+ colors[i].blue=color.blue;
+ colors[i].flags=color.flags;
+ }
+ /*
+ Ensure the header byte-order is most-significant byte first.
+ */
+ lsb_first=1;
+ if (*(char *) &lsb_first)
+ for (i=0; i < (long) header.ncolors; i++)
+ {
+ MSBOrderLong((unsigned char *) &colors[i].pixel,
+ sizeof(unsigned long));
+ MSBOrderShort((unsigned char *) &colors[i].red,
+ 3*sizeof(unsigned short));
+ }
+ }
+ /*
+ Convert image to MIFF format.
+ */
+ /*
+ Allocate the pixel buffer.
+ */
+#define XWD_OVERFLOW(c,a,b) ((b) != 0 && ((c)/((size_t) b) != ((size_t) a)))
+ length=ximage->bytes_per_line*ximage->height;
+ if (XWD_OVERFLOW(length,ximage->bytes_per_line,ximage->height))
+ ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ if (ximage->format != ZPixmap)
+ {
+ size_t tmp=length;
+ length*=ximage->depth;
+ if (XWD_OVERFLOW(length,tmp,ximage->depth))
+ ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ }
+ ximage->data=MagickAllocateMemory(char *,length);
+ if (ximage->data == (char *) NULL)
+ ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ count=ReadBlob(image,length,ximage->data);
+ if (count != length)
+ ThrowXWDReaderException(CorruptImageError,
+ UnableToReadPixmapFromDumpFile,image);
+ switch (image->storage_class)
+ {
+ case DirectClass:
+ default:
+ {
+ register unsigned long
+ color;
+
+ unsigned long
+ blue_mask,
+ blue_shift,
+ green_mask,
+ green_shift,
+ red_mask,
+ red_shift;
+
+ /*
+ Determine shift and mask for red, green, and blue.
+ */
+ red_mask=ximage->red_mask;
+ red_shift=0;
+ while ((red_mask != 0) && ((red_mask & 0x01) == 0))
+ {
+ red_mask>>=1;
+ red_shift++;
+ }
+ green_mask=ximage->green_mask;
+ green_shift=0;
+ while ((green_mask != 0) && ((green_mask & 0x01) == 0))
+ {
+ green_mask>>=1;
+ green_shift++;
+ }
+ blue_mask=ximage->blue_mask;
+ blue_shift=0;
+ while ((blue_mask != 0) && ((blue_mask & 0x01) == 0))
+ {
+ blue_mask>>=1;
+ blue_shift++;
+ }
+
+ /*
+ Convert X image to DirectClass packets.
+ */
+ if (image->colors != 0)
+ {
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=XGetPixel(ximage,(int) x,(int) y);
+ index_val=(unsigned short)
+ ((pixel >> red_shift) & red_mask);
+ q->red=ScaleShortToQuantum(colors[index_val].red);
+ index_val=(unsigned short)
+ ((pixel >> green_shift) & green_mask);
+ q->green=ScaleShortToQuantum(colors[index_val].green);
+ index_val=(unsigned short)
+ ((pixel >> blue_shift) & blue_mask);
+ q->blue=ScaleShortToQuantum(colors[index_val].blue);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ else
+ {
+ if ((red_mask == 0) ||
+ (green_mask == 0) ||
+ (blue_mask == 0))
+ ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=XGetPixel(ximage,(int) x,(int) y);
+ color=(pixel >> red_shift) & red_mask;
+ q->red=ScaleShortToQuantum((color*65535L)/red_mask);
+ color=(pixel >> green_shift) & green_mask;
+ q->green=ScaleShortToQuantum((color*65535L)/green_mask);
+ color=(pixel >> blue_shift) & blue_mask;
+ q->blue=ScaleShortToQuantum((color*65535L)/blue_mask);
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ }
+ break;
+ }
+ case PseudoClass:
+ {
+ /*
+ Convert X image to PseudoClass packets.
+ */
+ register long
+ i;
+
+ if (!AllocateImageColormap(image,image->colors))
+ ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
+ image);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ image->colormap[i].red=ScaleShortToQuantum(colors[i].red);
+ image->colormap[i].green=ScaleShortToQuantum(colors[i].green);
+ image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue);
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index_val=(IndexPacket) (XGetPixel(ximage,(int) x,(int) y));
+ VerifyColormapIndex(image,index_val);
+ indexes[x]=index_val;
+ *q++=image->colormap[index_val];
+ }
+ if (!SyncImagePixels(image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ break;
+ }
+ }
+ }
+ /*
+ Free image and colormap.
+ */
+ MagickFreeMemory(colors);
+ MagickFreeMemory(ximage->data);
+ MagickFreeMemory(ximage);
+ CloseBlob(image);
+ return(image);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r X W D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterXWDImage adds attributes for the XWD image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterXWDImage method is:
+%
+% RegisterXWDImage(void)
+%
+*/
+ModuleExport void RegisterXWDImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("XWD");
+#if defined(HasX11)
+ entry->decoder=(DecoderHandler) ReadXWDImage;
+ entry->encoder=(EncoderHandler) WriteXWDImage;
+#endif
+ entry->magick=(MagickHandler) IsXWD;
+ entry->adjoin=False;
+ entry->coder_class=UnstableCoderClass;
+ entry->description="X Windows system window dump (color)";
+ entry->module="XWD";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r X W D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterXWDImage removes format registrations made by the
+% XWD module from the list of supported formats.
+%
+% The format of the UnregisterXWDImage method is:
+%
+% UnregisterXWDImage(void)
+%
+*/
+ModuleExport void UnregisterXWDImage(void)
+{
+ (void) UnregisterMagickInfo("XWD");
+}
+
+#if defined(HasX11)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e X W D I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteXWDImage writes an image to a file in X window dump
+% rasterfile format.
+%
+% The format of the WriteXWDImage method is:
+%
+% unsigned int WriteXWDImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteXWDImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteXWDImage(const ImageInfo *image_info,Image *image)
+{
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register long
+ i;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ *pixels;
+
+ size_t
+ pixels_size;
+
+ unsigned int
+ status;
+
+ unsigned long
+ bits_per_pixel,
+ bytes_per_line,
+ lsb_first,
+ scanline_pad;
+
+ XWDFileHeader
+ xwd_info;
+
+ /*
+ Open output image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ XWD does not support more than 256 colors.
+ */
+ if ((image->storage_class == PseudoClass) && (image->colors > 256))
+ SetImageType(image,TrueColorType);
+ /*
+ Initialize XWD file header.
+ */
+ (void) memset(&xwd_info,0,sizeof(xwd_info));
+ xwd_info.header_size=(CARD32) (sz_XWDheader+strlen(image->filename)+1);
+ xwd_info.file_version=(CARD32) XWD_FILE_VERSION;
+ xwd_info.pixmap_format=(CARD32) ZPixmap;
+ xwd_info.pixmap_depth=(CARD32) (image->storage_class == DirectClass ? 24 : 8);
+ xwd_info.pixmap_width=(CARD32) image->columns;
+ xwd_info.pixmap_height=(CARD32) image->rows;
+ xwd_info.xoffset=(CARD32) 0;
+ xwd_info.byte_order=(CARD32) MSBFirst;
+ xwd_info.bitmap_unit=(CARD32) (image->storage_class == DirectClass ? 32 : 8);
+ xwd_info.bitmap_bit_order=(CARD32) MSBFirst;
+ xwd_info.bitmap_pad=(CARD32) (image->storage_class == DirectClass ? 32 : 8);
+ bits_per_pixel=(image->storage_class == DirectClass ? 24 : 8);
+ xwd_info.bits_per_pixel=(CARD32) bits_per_pixel;
+ bytes_per_line=(CARD32) ((((xwd_info.bits_per_pixel*
+ xwd_info.pixmap_width)+((xwd_info.bitmap_pad)-1))/
+ (xwd_info.bitmap_pad))*((xwd_info.bitmap_pad) >> 3));
+ xwd_info.bytes_per_line=(CARD32) bytes_per_line;
+ xwd_info.visual_class=(CARD32)
+ (image->storage_class == DirectClass ? DirectColor : PseudoColor);
+ xwd_info.red_mask=(CARD32)
+ (image->storage_class == DirectClass ? 0xff0000 : 0);
+ xwd_info.green_mask=(CARD32)
+ (image->storage_class == DirectClass ? 0xff00 : 0);
+ xwd_info.blue_mask=(CARD32) (image->storage_class == DirectClass ? 0xff : 0);
+ xwd_info.bits_per_rgb=(CARD32) (image->storage_class == DirectClass ? 24 : 8);
+ xwd_info.colormap_entries=(CARD32)
+ (image->storage_class == DirectClass ? 256 : image->colors);
+ xwd_info.ncolors=(unsigned int)
+ (image->storage_class == DirectClass ? 0 : image->colors);
+ xwd_info.window_width=(CARD32) image->columns;
+ xwd_info.window_height=(CARD32) image->rows;
+ xwd_info.window_x=0;
+ xwd_info.window_y=0;
+ xwd_info.window_bdrwidth=(CARD32) 0;
+ /*
+ Write XWD header.
+ */
+ lsb_first=1;
+ if (*(char *) &lsb_first)
+ MSBOrderLong((unsigned char *) &xwd_info,sizeof(xwd_info));
+ (void) WriteBlob(image,sz_XWDheader,(char *) &xwd_info);
+ (void) WriteBlob(image,strlen(image->filename)+1,(char *) image->filename);
+ if (image->storage_class == PseudoClass)
+ {
+ XColor
+ *colors;
+
+ XWDColor
+ color;
+
+ /*
+ Dump colormap to file.
+ */
+ (void) memset(&color,0,sizeof(color));
+ colors=MagickAllocateArray(XColor *,image->colors,sizeof(XColor));
+ if (colors == (XColor *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ colors[i].pixel=i;
+ colors[i].red=ScaleQuantumToShort(image->colormap[i].red);
+ colors[i].green=ScaleQuantumToShort(image->colormap[i].green);
+ colors[i].blue=ScaleQuantumToShort(image->colormap[i].blue);
+ colors[i].flags=DoRed | DoGreen | DoBlue;
+ colors[i].pad=0;
+ if (*(char *) &lsb_first)
+ {
+ MSBOrderLong((unsigned char *) &colors[i].pixel,sizeof(long));
+ MSBOrderShort((unsigned char *) &colors[i].red,3*sizeof(short));
+ }
+ }
+ for (i=0; i < (long) image->colors; i++)
+ {
+ color.pixel=(CARD32) colors[i].pixel;
+ color.red=colors[i].red;
+ color.green=colors[i].green;
+ color.blue=colors[i].blue;
+ color.flags=colors[i].flags;
+ (void) WriteBlob(image,sz_XWDColor,(char *) &color);
+ }
+ MagickFreeMemory(colors);
+ }
+ /*
+ Allocate memory for pixels.
+ */
+ scanline_pad=(bytes_per_line-((image->columns*bits_per_pixel) >> 3));
+ pixels_size=image->columns*(image->storage_class == PseudoClass ? 1 : 3)+scanline_pad;
+ pixels=MagickAllocateMemory(unsigned char *,pixels_size);
+ if (pixels == (unsigned char *) NULL)
+ ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+ (void) memset(pixels,0,pixels_size);
+ /*
+ Convert MIFF to XWD raster pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ q=pixels;
+
+ if (image->storage_class == PseudoClass)
+ {
+ register const IndexPacket
+ *indexes;
+
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ *q++=(unsigned char) indexes[x];
+ }
+ else
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+
+ *q++=ScaleQuantumToChar(p->red);
+ *q++=ScaleQuantumToChar(p->green);
+ *q++=ScaleQuantumToChar(p->blue);
+ p++;
+ }
+ }
+ for (x=(long) scanline_pad; x > 0; x--)
+ *q++=0;
+ (void) WriteBlob(image,(size_t) (q-pixels),(char *) pixels);
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ MagickFreeMemory(pixels);
+ CloseBlob(image);
+ return(True);
+}
+#endif
diff --git a/coders/yuv.c b/coders/yuv.c
new file mode 100644
index 0000000..d0aa863
--- /dev/null
+++ b/coders/yuv.c
@@ -0,0 +1,746 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Y Y U U V V %
+% Y Y U U V V %
+% Y U U V V %
+% Y U U V V %
+% Y UUU V %
+% %
+% %
+% Read/Write Raw CCIR 601 4:1:1 or 4:2:2 Image Format. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/pixel_cache.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/resize.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ WriteYUVImage(const ImageInfo *,Image *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d Y U V I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadYUVImage reads an image with digital YUV (CCIR 601 4:1:1, plane
+% or partition interlaced, or 4:2:2 plane, partition interlaced or
+% noninterlaced) bytes and returns it. It allocates the memory necessary
+% for the new Image structure and returns a pointer to the new image.
+%
+% The format of the ReadYUVImage method is:
+%
+% Image *ReadYUVImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadYUVImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o exception: return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowYUVReaderException(code_,reason_,image_) \
+{ \
+ MagickFreeMemory(scanline); \
+ ThrowReaderException(code_,reason_,image_); \
+}
+
+static Image *ReadYUVImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ Image
+ *chroma_image = (Image *) NULL,
+ *image,
+ *resize_image = (Image *) NULL;
+
+ long
+ horizontal_factor,
+ vertical_factor,
+ y;
+
+ register const PixelPacket
+ *r;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q,
+ *chroma_pixels;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ size_t
+ count;
+
+ unsigned char
+ *scanline = (unsigned char *) NULL;
+
+ MagickPassFail
+ status;
+
+ InterlaceType
+ interlace;
+
+ /*
+ Allocate image structure.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=MagickPass;
+ image=AllocateImage(image_info);
+ if ((image->columns == 0) || (image->rows == 0))
+ ThrowYUVReaderException(OptionError,MustSpecifyImageSize,image);
+ image->depth=8;
+ interlace=image_info->interlace;
+ horizontal_factor=2;
+ vertical_factor=2;
+ if (image_info->sampling_factor != (char *) NULL)
+ {
+ long
+ factors;
+
+ factors=sscanf(image_info->sampling_factor,"%ldx%ld",&horizontal_factor,
+ &vertical_factor);
+ if (factors != 2)
+ vertical_factor=horizontal_factor;
+ if ((horizontal_factor != 1) && (horizontal_factor != 2) &&
+ (vertical_factor != 1) && (vertical_factor != 2))
+ ThrowYUVReaderException(OptionError,UnsupportedSamplingFactor,
+ image);
+ }
+ if ((interlace == UndefinedInterlace) ||
+ ((interlace == NoInterlace) && (vertical_factor == 2)))
+ {
+ interlace=NoInterlace; /* CCIR 4:2:2 */
+ if (vertical_factor == 2)
+ interlace=PlaneInterlace; /* CCIR 4:1:1 */
+ }
+ if (interlace != PartitionInterlace)
+ {
+ /*
+ Open image file.
+ */
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ ThrowYUVReaderException(FileOpenError,UnableToOpenFile,image);
+ for (i=0; i < image->offset; i++)
+ {
+ if (EOF == ReadBlobByte(image))
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ }
+ }
+ /*
+ Allocate memory for a scanline.
+ */
+ if (interlace == NoInterlace)
+ scanline=MagickAllocateMemory(unsigned char *,2*image->columns+2);
+ else
+ scanline=MagickAllocateMemory(unsigned char *,image->columns);
+ if (scanline == (unsigned char *) NULL)
+ ThrowYUVReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ do
+ {
+ chroma_image=CloneImage(image,image->columns/horizontal_factor,
+ image->rows/vertical_factor,True,exception);
+ if (chroma_image == (Image *) NULL)
+ ThrowYUVReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ /*
+ Convert raster image to pixel packets.
+ */
+ if (image_info->ping && (image_info->subrange != 0))
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (interlace == PartitionInterlace)
+ {
+ AppendImageFormat("Y",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowYUVReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ if (interlace == NoInterlace)
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,2*image->columns,scanline);
+ p=scanline;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ chroma_pixels=SetImagePixels(chroma_image,0,y,chroma_image->columns,1);
+ if (chroma_pixels == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) image->columns; x+=2)
+ {
+ chroma_pixels->red=0;
+ chroma_pixels->green=ScaleCharToQuantum(*p++); /* U (Cb) */
+ q->red=ScaleCharToQuantum(*p++); /* Y */
+ q->green=0;
+ q->blue=0;
+ q++;
+ q->green=0;
+ q->blue=0;
+ chroma_pixels->blue=ScaleCharToQuantum(*p++); /* V (Cr) */
+ q->red=ScaleCharToQuantum(*p++); /* Y */
+ chroma_pixels++;
+ q++;
+ }
+ }
+ else
+ {
+ if ((y > 0) || (image->previous == (Image *) NULL))
+ (void) ReadBlob(image,image->columns,scanline);
+ p=scanline;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->red=ScaleCharToQuantum(*p++);
+ q->green=0;
+ q->blue=0;
+ q++;
+ }
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (interlace == NoInterlace)
+ if (!SyncImagePixels(chroma_image))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (image->previous == (Image *) NULL)
+ if (!MagickMonitorFormatted(y,image->rows,exception,LoadImageText,
+ image->filename,
+ image->columns,image->rows))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (status == MagickFail)
+ break;
+ if (interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("U",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowYUVReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ if (interlace != NoInterlace)
+ {
+ for (y=0; y < (long) chroma_image->rows; y++)
+ {
+ (void) ReadBlob(image,chroma_image->columns,scanline);
+ p=scanline;
+ q=SetImagePixels(chroma_image,0,y,chroma_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) chroma_image->columns; x++)
+ {
+ q->red=0;
+ q->green=ScaleCharToQuantum(*p++);
+ q->blue=0;
+ q++;
+ }
+ if (!SyncImagePixels(chroma_image))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (status ==MagickFail)
+ break;
+ if (interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("V",image->filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ ThrowYUVReaderException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < (long) chroma_image->rows; y++)
+ {
+ (void) ReadBlob(image,chroma_image->columns,scanline);
+ p=scanline;
+ q=GetImagePixels(chroma_image,0,y,chroma_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) chroma_image->columns; x++)
+ {
+ q->blue=ScaleCharToQuantum(*p++);
+ q++;
+ }
+ if (!SyncImagePixels(chroma_image))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (status == MagickFail)
+ break;
+ }
+ /*
+ Scale image.
+ */
+ resize_image=ResizeImage(chroma_image,image->columns,image->rows,
+ TriangleFilter,1.0,exception);
+ DestroyImage(chroma_image);
+ if (resize_image == (Image *) NULL)
+ ThrowYUVReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ r=AcquireImagePixels(resize_image,0,y,resize_image->columns,1,
+ &resize_image->exception);
+ if ((q == (PixelPacket *) NULL) || (r == (const PixelPacket *) NULL))
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->green=r->green;
+ q->blue=r->blue;
+ r++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ DestroyImage(resize_image);
+ if (status == MagickFail)
+ break;
+ image->colorspace=YCbCrColorspace;
+ (void) TransformColorspace(image,RGBColorspace);
+ if (interlace == PartitionInterlace)
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ if (EOFBlob(image))
+ {
+ ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,
+ image->filename);
+ break;
+ }
+ /*
+ Proceed to next image.
+ */
+ if (image_info->subrange != 0)
+ if (image->scene >= (image_info->subimage+image_info->subrange-1))
+ break;
+ if (interlace == NoInterlace)
+ count=ReadBlob(image,2*image->columns,(char *) scanline);
+ else
+ count=ReadBlob(image,image->columns,(char *) scanline);
+ if (count != 0)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,image);
+ if (image->next == (Image *) NULL)
+ {
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ image=SyncNextImageInList(image);
+ if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),
+ exception,LoadImagesText,
+ image->filename))
+ break;
+ }
+ } while (count != 0);
+ MagickFreeMemory(scanline);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r Y U V I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RegisterYUVImage adds attributes for the YUV image format to
+% the list of supported formats. The attributes include the image format
+% tag, a method to read and/or write the format, whether the format
+% supports the saving of more than one frame to the same file or blob,
+% whether the format supports native in-memory I/O, and a brief
+% description of the format.
+%
+% The format of the RegisterYUVImage method is:
+%
+% RegisterYUVImage(void)
+%
+*/
+ModuleExport void RegisterYUVImage(void)
+{
+ MagickInfo
+ *entry;
+
+ entry=SetMagickInfo("YUV");
+ entry->decoder=(DecoderHandler) ReadYUVImage;
+ entry->encoder=(EncoderHandler) WriteYUVImage;
+ entry->adjoin=False;
+ entry->raw=True;
+ entry->description="CCIR 601 4:1:1 or 4:2:2 (8-bit only)";
+ entry->module="YUV";
+ (void) RegisterMagickInfo(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r Y U V I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterYUVImage removes format registrations made by the
+% YUV module from the list of supported formats.
+%
+% The format of the UnregisterYUVImage method is:
+%
+% UnregisterYUVImage(void)
+%
+*/
+ModuleExport void UnregisterYUVImage(void)
+{
+ (void) UnregisterMagickInfo("YUV");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e Y U V I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteYUVImage writes an image to a file in the digital YUV
+% (CCIR 601 4:1:1, plane or partition interlaced, or 4:2:2 plane, partition
+% interlaced or noninterlaced) bytes and returns it.
+%
+% The format of the WriteYUVImage method is:
+%
+% unsigned int WriteYUVImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o status: Method WriteYUVImage return True if the image is written.
+% False is returned is there is a memory shortage or if the image file
+% fails to write.
+%
+% o image_info: Specifies a pointer to a ImageInfo structure.
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+static unsigned int WriteYUVImage(const ImageInfo *image_info,Image *image)
+{
+ Image
+ *chroma_image,
+ *yuv_image;
+
+ InterlaceType
+ interlace;
+
+ long
+ horizontal_factor,
+ vertical_factor,
+ y;
+
+ register const PixelPacket
+ *p,
+ *s;
+
+ register long
+ x;
+
+ unsigned int
+ status;
+
+ unsigned long
+ scene,
+ height,
+ width;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ interlace=image_info->interlace;
+ horizontal_factor=2;
+ vertical_factor=2;
+ if (image_info->sampling_factor != (char *) NULL)
+ {
+ long
+ factors;
+
+ factors=sscanf(image_info->sampling_factor,"%ldx%ld",&horizontal_factor,
+ &vertical_factor);
+ if (factors != 2)
+ vertical_factor=horizontal_factor;
+ if ((horizontal_factor != 1) && (horizontal_factor != 2) &&
+ (vertical_factor != 1) && (vertical_factor != 2))
+ ThrowWriterException(OptionError,UnsupportedSamplingFactor,
+ image);
+ }
+ if ((interlace == UndefinedInterlace) ||
+ ((interlace == NoInterlace) && (vertical_factor == 2)))
+ {
+ interlace=NoInterlace; /* CCIR 4:2:2 */
+ if (vertical_factor == 2)
+ interlace=PlaneInterlace; /* CCIR 4:1:1 */
+ }
+ if (interlace != PartitionInterlace)
+ {
+ /*
+ Open output image file.
+ */
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ else
+ {
+ AppendImageFormat("Y",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ scene=0;
+ do
+ {
+ /*
+ Sample image to an even width and height, if necessary.
+ */
+ image->depth=8;
+ (void) TransformColorspace(image,RGBColorspace);
+ width=image->columns+(image->columns & (horizontal_factor-1));
+ height=image->rows+(image->rows & (vertical_factor-1));
+ yuv_image=ResizeImage(image,width,height,TriangleFilter,1.0,
+ &image->exception);
+ if (yuv_image == (Image *) NULL)
+ ThrowWriterException2(ResourceLimitError,image->exception.reason,image);
+ (void) TransformColorspace(yuv_image,YCbCrColorspace);
+ /*
+ Downsample image.
+ */
+ chroma_image=ResizeImage(image,width/horizontal_factor,
+ height/vertical_factor,TriangleFilter,1.0,&image->exception);
+ if (chroma_image == (Image *) NULL)
+ ThrowWriterException2(ResourceLimitError,image->exception.reason,image);
+ (void) TransformColorspace(chroma_image,YCbCrColorspace);
+ if (interlace == NoInterlace)
+ {
+ /*
+ Write noninterlaced YUV.
+ */
+ for (y=0; y < (long) yuv_image->rows; y++)
+ {
+ p=AcquireImagePixels(yuv_image,0,y,yuv_image->columns,1,
+ &yuv_image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ s=AcquireImagePixels(chroma_image,0,y,chroma_image->columns,1,
+ &chroma_image->exception);
+ if (s == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) yuv_image->columns; )
+ {
+ (void) WriteBlobByte(image,ScaleQuantumToChar(s->green));
+ (void) WriteBlobByte(image,ScaleQuantumToChar(p->red));
+ p++;
+ (void) WriteBlobByte(image,ScaleQuantumToChar(s->blue));
+ (void) WriteBlobByte(image,ScaleQuantumToChar(p->red));
+ p++;
+ s++;
+ x++;
+ x++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ DestroyImage(yuv_image);
+ }
+ else
+ {
+ /*
+ Initialize Y channel.
+ */
+ for (y=0; y < (long) yuv_image->rows; y++)
+ {
+ p=AcquireImagePixels(yuv_image,0,y,yuv_image->columns,1,
+ &yuv_image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) yuv_image->columns; x++)
+ {
+ (void) WriteBlobByte(image,ScaleQuantumToChar(p->red));
+ p++;
+ }
+ if (image->previous == (Image *) NULL)
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SaveImageText,image->filename,
+ image->columns,image->rows))
+ break;
+ }
+ DestroyImage(yuv_image);
+ /*
+ Initialize U channel.
+ */
+ if (interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("U",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < (long) chroma_image->rows; y++)
+ {
+ p=AcquireImagePixels(chroma_image,0,y,chroma_image->columns,1,
+ &chroma_image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) chroma_image->columns; x++)
+ {
+ (void) WriteBlobByte(image,ScaleQuantumToChar(p->green));
+ p++;
+ }
+ }
+ /*
+ Initialize V channel.
+ */
+ if (interlace == PartitionInterlace)
+ {
+ CloseBlob(image);
+ AppendImageFormat("V",image->filename);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,
+ &image->exception);
+ if (status == False)
+ ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+ }
+ for (y=0; y < (long) chroma_image->rows; y++)
+ {
+ p=AcquireImagePixels(chroma_image,0,y,chroma_image->columns,1,
+ &chroma_image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) chroma_image->columns; x++)
+ {
+ (void) WriteBlobByte(image,ScaleQuantumToChar(p->blue));
+ p++;
+ }
+ }
+ }
+ DestroyImage(chroma_image);
+ if (interlace == PartitionInterlace)
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ if (image->next == (Image *) NULL)
+ break;
+ image=SyncNextImageInList(image);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ &image->exception,SaveImagesText,
+ image->filename);
+ if (status == False)
+ break;
+ } while (image_info->adjoin);
+ if (image_info->adjoin)
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ CloseBlob(image);
+ return(True);
+}
diff --git a/common.shi.in b/common.shi.in
new file mode 100644
index 0000000..5d1dd21
--- /dev/null
+++ b/common.shi.in
@@ -0,0 +1,18 @@
+# -*- shell-script -*-
+# Copyright (C) 2012 GraphicsMagick Group
+# Definitions of optional features and configuration values for this build.
+# Intended for use by test scripts.
+MAGICK_FEATURES='@MAGICK_FEATURES@'
+top_srcdir='@abs_top_srcdir@'
+top_builddir='@abs_top_builddir@'
+
+set -a
+GM="${MEMCHECK} @abs_top_builddir@/utilities/gm"
+LD_LIBRARY_PATH="@abs_top_builddir@/magick/.libs:${LD_LIBRARY_PATH}"
+
+MAGICK_CODER_MODULE_PATH='@abs_top_builddir@/coders'
+MAGICK_CONFIGURE_PATH='@abs_top_builddir@/config:@abs_top_srcdir@/config'
+MAGICK_FILTER_MODULE_PATH='@abs_top_builddir@/filters'
+
+PATH="@abs_top_builddir@/utilities:${PATH}"
+set +a
diff --git a/config/Makefile.am b/config/Makefile.am
new file mode 100644
index 0000000..8ee7228
--- /dev/null
+++ b/config/Makefile.am
@@ -0,0 +1,38 @@
+# Copyright (C) 2004 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for Magick library configuration files
+#
+#
+
+# Where architecture-independent configuration files get installed
+# (share/GraphicsMagick-version)
+configsharedir = $(MagickShareConfigPath)
+configshare_DATA = \
+ config/colors.mgk \
+ config/log.mgk \
+ config/modules.mgk
+
+# Where architecture-dependent configuration files get installed
+# (lib/GraphicsMagick-version)
+configlibdir = $(MagickLibConfigPath)
+configlib_DATA = \
+ config/delegates.mgk \
+ config/type-ghostscript.mgk \
+ config/type.mgk \
+ config/type-solaris.mgk \
+ config/type-windows.mgk
+
+CONFIG_EXTRA_DIST = \
+ config/colors.mgk \
+ config/delegates.mgk.in \
+ config/log.mgk \
+ config/modules.mgk \
+ config/type-ghostscript.mgk.in \
+ config/type-solaris.mgk.in \
+ config/type-windows.mgk.in \
+ config/type.mgk.in
+
diff --git a/config/colors.mgk b/config/colors.mgk
new file mode 100644
index 0000000..ae0b874
--- /dev/null
+++ b/config/colors.mgk
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!--
+Color definition file. Definitions in this file extend or replace the
+compiled in color definitions. Use 'gm convert -list color' to list
+the currently available colors. This file is optional and the
+software will still function if it is removed.
+
+For example:
+
+<colormap>
+ <color name="mycolor1" red="228" green="118" blue="33" compliance="None" />
+ <color name="mycolor2" red="228" green="123" blue="66" compliance="X11" />
+</colormap>
+-->
+<colormap>
+</colormap>
diff --git a/config/compile b/config/compile
new file mode 100755
index 0000000..a85b723
--- /dev/null
+++ b/config/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# 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, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config/config.guess b/config/config.guess
new file mode 100755
index 0000000..6c32c86
--- /dev/null
+++ b/config/config.guess
@@ -0,0 +1,1421 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-11-04'
+
+# This file 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2014 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config/config.sub b/config/config.sub
new file mode 100755
index 0000000..7ffe373
--- /dev/null
+++ b/config/config.sub
@@ -0,0 +1,1807 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-12-03'
+
+# This file 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2014 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config/delegates.mgk.in b/config/delegates.mgk.in
new file mode 100644
index 0000000..b8040cd
--- /dev/null
+++ b/config/delegates.mgk.in
@@ -0,0 +1,127 @@
+<?xml version="1.0"?>
+<!--
+ Delegate command file.
+
+ Commands which specify
+
+ decode="in_format" encode="out_format"
+
+ specify the rules for converting from in_format to out_format
+ These rules may be used to translate directly between formats.
+
+ Commands which specify only
+
+ decode="in_format"
+
+ specify the rules for converting from in_format to some format that
+ GraphicsMagick will automatically recognize. These rules are used to
+ decode formats.
+
+ Commands which specify only
+
+ encode="out_format"
+
+ specify the rules for an "encoder" which may accept any input format.
+
+ For delegates other than gs-color, gs-mono, and mpeg-encode
+ the substitution rules are as follows:
+
+ %i input image filename
+ %o output image filename
+ %u unique temporary filename
+ %z secondary unique temporary filename
+
+ %# input image signature
+ %b image file size
+ %c input image comment
+ %d original filename directory part
+ %e original filename extension part
+ %f original filename
+ %t original filename top (base) part
+ %g window group
+ %h image rows (height)
+ %k input image number colors
+ %l input image label
+ %m input image format ("magick")
+ %n input image number of scenes
+ %p page number
+ %q input image depth
+ %r input image storage class, colorspace, and matte
+ %s scene number
+ %w image columns (width)
+ %x input image x resolution
+ %y input image y resolution
+ %[ input image attribute (e.g. "%[EXIF:Orientation]")
+ %% pass through literal %
+
+ Under Unix, all text (non-numeric) substitutions should be
+ surrounded with double quotes for the purpose of security, and
+ because any double quotes occuring within the substituted text will
+ be escaped using a backslash.
+
+ Commands (excluding file names) containing one or more of the
+ special characters ";&|><" (requiring that multiple processes be
+ executed) are executed via the Unix shell with text substitutions
+ carefully excaped to avoid possible compromise. Otherwise, commands
+ are executed directly without use of the Unix shell.
+
+ Use 'gm convert -list delegates' to verify how the contents of this
+ file has been parsed.
+
+ -->
+<delegatemap>
+ <delegate decode="browse" stealth="True" command='"@BrowseDelegate@" "http://www.GraphicsMagick.org/" &' />
+ <delegate decode="cgm" command='"@CGMDecodeDelegate@" -d ps < "%i" > "%o" 2>/dev/null' />
+ <delegate decode="dcraw" command='"@DCRAWDecodeDelegate@" -c -w "%i" > "%o"' />
+ <delegate decode="dot" command='"@DOTDecodeDelegate@" -Tps "%i" -o "%o"' />
+ <delegate decode="dvi" command='"@DVIDecodeDelegate@" -q -o "%o" "%i"' />
+ <delegate decode="edit" stealth="True" command='"@EditorDelegate@" -title "Edit Image Comment" -e vi "%o"' />
+ <delegate decode="eps" encode="pdf" mode="bi" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSPDFDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+ <delegate decode="eps" encode="ps" mode="bi" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSPSDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+ <delegate decode="fig" command='"@FIGDecodeDelegate@" -L ps "%i" "%o"' />
+
+ <!-- Read monochrome Postscript, EPS, and PDF -->
+ <delegate decode="gs-mono" stealth="True" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSMonoDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+
+ <!-- Read grayscale Postscript, EPS, and PDF -->
+ <delegate decode="gs-gray" stealth="True" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSGrayDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+
+ <!-- Read colormapped Postscript, EPS, and PDF -->
+ <delegate decode="gs-palette" stealth="True" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSPaletteDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+
+ <!-- Read color Postscript, EPS, and PDF -->
+ <delegate decode="gs-color" stealth="True" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSColorDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+
+ <!-- Read color+alpha Postscript, EPS, and PDF -->
+ <delegate decode="gs-color+alpha" stealth="True" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSColorAlphaDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+
+ <!-- Read CMYK Postscript, EPS, and PDF -->
+ <delegate decode="gs-cmyk" stealth="True" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSCMYKDevice@ -dTextAlphaBits=%u -dGraphicsAlphaBits=%u -r%s %s "-sOutputFile=%s" -- "%s" -c quit' />
+
+ <delegate decode="hpg" command='"@HPGLDecodeDelegate@" -q -m eps -f `basename "%o"` "%i" && @MVDelegate@ -f `basename "%o"` "%o"' />
+ <delegate decode="hpgl" command='"@HPGLDecodeDelegate@" -q -m eps -f `basename "%o"` "%i" && @MVDelegate@ -f `basename "%o"` "%o"' />
+ <!-- Read HTML file -->
+ <delegate decode="htm" command='"@HTMLDecodeDelegate@" -U -o "%o" "%i"' />
+ <!-- Read HTML file -->
+ <delegate decode="html" command='"@HTMLDecodeDelegate@" -U -o "%o" "%i"' />
+ <!-- Read IFF ILBM file -->
+ <delegate decode="ilbm" command='"@ILBMDecodeDelegate@" "%i" > "%o"' />
+ <!-- Read MPEG file using mpeg2decode -->
+ <delegate decode="mpeg" command='"@MPEGDecodeDelegate@" -q -b "%i" -f -o3 "%u%%05d"; @GMDelegate@ convert -temporary "%u*.ppm" "miff:%o" ; rm -f "%u"*.ppm ' />
+ <!-- Write MPEG file using mpeg2encode -->
+ <delegate encode="mpeg-encode" stealth="True" command='"@MPEGEncodeDelegate@" "%i" "%o"' />
+ <!-- Convert PDF to Encapsulated Poscript using Ghostscript -->
+ <delegate decode="pdf" encode="eps" mode="bi" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSEPSDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+ <!-- Convert PDF to Postcript using Ghostscript -->
+ <delegate decode="pdf" encode="ps" mode="bi" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSPSDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+ <!-- Convert PNM file to IFF ILBM format using ppmtoilbm -->
+ <delegate decode="pnm" encode="ilbm" mode="encode" command='"@ILBMEncodeDelegate@" -24if "%i" > "%o"' />
+ <delegate decode="pnm" encode="launch" mode="encode" command='"@LaunchDelegate@" "%i"' />
+ <delegate decode="pnm" encode="win" mode="encode" command='"@GMDelegate@" display -immutable "%i"' />
+ <delegate decode="ps" encode="eps" mode="bi" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSEPSDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+ <delegate decode="ps" encode="pdf" mode="bi" command='"@PSDelegate@" -q -dBATCH -dSAFER -dMaxBitmap=50000000 -dNOPAUSE -sDEVICE=@GSPDFDevice@ "-sOutputFile=%o" -- "%i" -c quit' />
+ <delegate decode="ps" encode="print" mode="encode" command='"@PrintDelegate@" "%i"' />
+ <!-- Read HTML file -->
+ <delegate decode="shtml" command='"@HTMLDecodeDelegate@" -U -o "%o" "%i"' />
+ <delegate encode="show" stealth="True" command='"@GMDelegate@" display -immutable -delay 0 -window_group %g -title "%l of %f" "%o" &' />
+</delegatemap>
diff --git a/config/depcomp b/config/depcomp
new file mode 100755
index 0000000..fc98710
--- /dev/null
+++ b/config/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+
+# 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, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts '$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\' :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
+
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for ':'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+ "$@" $dashmflag |
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config/install-sh b/config/install-sh
new file mode 100755
index 0000000..0b0fdcb
--- /dev/null
+++ b/config/install-sh
@@ -0,0 +1,501 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2013-12-25.23; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# 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.
+
+tab=' '
+nl='
+'
+IFS=" $tab$nl"
+
+# Set DOITPROG to "echo" to test this script.
+
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t)
+ is_target_a_directory=always
+ dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) is_target_a_directory=never;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+ if test -n "$dst_arg"; then
+ echo "$0: target directory not allowed when installing a directory." >&2
+ exit 1
+ fi
+fi
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call 'install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ if test $# -gt 1 || test "$is_target_a_directory" = always; then
+ if test ! -d "$dst_arg"; then
+ echo "$0: $dst_arg: Is not a directory." >&2
+ exit 1
+ fi
+ fi
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for 'test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test "$is_target_a_directory" = never; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ dstdir=`dirname "$dst"`
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ oIFS=$IFS
+ IFS=/
+ set -f
+ set fnord $dstdir
+ shift
+ set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # 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 $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+ set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ set +f &&
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config/log.mgk b/config/log.mgk
new file mode 100644
index 0000000..d5b1558
--- /dev/null
+++ b/config/log.mgk
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<!--
+
+ GraphicsMagick Logging Configuration File
+
+The following options are available:
+
+ o events [comma separated list]
+ annotate Text annotation events.
+ blob File opening/closing/loading events.
+ cache Pixel cache events.
+ coder File format coder events.
+ configure Configuration events (searching for .mgk files, etc.).
+ deprecate Identify use of deprecated functions.
+ error Error exception report events.
+ exception Exception report events (warning and error).
+ locale Locale events.
+ none Reporting disabled.
+ render Rendering (drawing) events.
+ resource Resource allocation events (memory, disk, etc.)
+ temporaryFile Temporary file events (allocate, deallocate, etc.)
+ transform Image processing events.
+ user User events (not emitted by GraphicsMagick).
+ warning Warning exception report events.
+ X11 X11 server events.
+
+ o output
+ none Reporting disabled.
+ disabled Reporting disabled.
+ stdout Log to stdout in "human readable" format
+ stderr Log to stderr in "human readable" format
+ xmlfile Log to a file in an XML format
+ txtfile Log to a file in a text format
+ win32debug Windows, Output events to the application/system debugger.
+ win32eventlog Windows, Output events to the Application event log.
+
+ o Filename - Use specified filename if output to a file is selected.
+ Place a %d in the file name in order to support multiple log generations.
+
+ o Generations - Number of log files to maintain before circulating back to
+ the first name.
+
+ o Limit - Maximum number of logging events before creating a new log file.
+
+ o Format - Format of logging output
+
+ You can display the following components by embedding
+ special format characters:
+
+ %d domain
+ %e event
+ %f function
+ %l line
+ %m module
+ %p process ID
+ %r real CPU time
+ %t wall clock time
+ %u user CPU time
+ %% percent sign
+ \n newline
+ \r carriage return
+
+ -->
+<magicklog>
+ <log events="None" />
+ <log output="stderr" />
+ <log filename="Magick-%d.log" />
+ <log generations="3" />
+ <log limit="2000" />
+ <log format="%t %r %u %p %m/%f/%l/%d:\n %e" />
+</magicklog>
diff --git a/config/ltmain.sh b/config/ltmain.sh
new file mode 100644
index 0000000..0f0a2da
--- /dev/null
+++ b/config/ltmain.sh
@@ -0,0 +1,11147 @@
+#! /bin/sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+## by inline-source v2014-01-03.01
+
+# libtool (GNU libtool) 2.4.6
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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, see <http://www.gnu.org/licenses/>.
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.6
+package_revision=2.4.6
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2015-01-20.17; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# Copyright (C) 2004-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# 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 3 of the License, or
+# (at your option) any later version.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES 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, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
+
+
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+fi
+
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test set = \"\${$_G_var+set}\"; then
+ save_$_G_var=\$$_G_var
+ $_G_var=C
+ export $_G_var
+ _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+ _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
+ fi"
+done
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Make sure IFS has a sensible default
+sp=' '
+nl='
+'
+IFS="$sp $nl"
+
+# There are apparently some retarded systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
+
+
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+}
+
+
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
+{
+ _G_progs_list=$1
+ _G_check_func=$2
+ _G_PATH=${3-"$PATH"}
+
+ _G_path_prog_max=0
+ _G_path_prog_found=false
+ _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
+ for _G_dir in $_G_PATH; do
+ IFS=$_G_save_IFS
+ test -z "$_G_dir" && _G_dir=.
+ for _G_prog_name in $_G_progs_list; do
+ for _exeext in '' .EXE; do
+ _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+ func_executable_p "$_G_path_prog" || continue
+ case `"$_G_path_prog" --version 2>&1` in
+ *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+ *) $_G_check_func $_G_path_prog
+ func_path_progs_result=$func_check_prog_result
+ ;;
+ esac
+ $_G_path_prog_found && break 3
+ done
+ done
+ done
+ IFS=$_G_save_IFS
+ test -z "$func_path_progs_result" && {
+ echo "no acceptable sed could be found in \$PATH" >&2
+ exit 1
+ }
+}
+
+
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
+
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+ _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for _G_i in 1 2 3 4 5 6 7; do
+ _G_sed_script=$_G_sed_script$nl$_G_sed_script
+ done
+ echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+ _G_sed_script=
+
+ func_check_prog_sed ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo '' >> conftest.nl
+ "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+ rm -f conftest.sed
+ SED=$func_path_progs_result
+}
+
+
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+ func_check_prog_grep ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ _G_path_prog_max=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo 'GREP' >> conftest.nl
+ "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+ GREP=$func_path_progs_result
+}
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# All uppercase variable names are used for environment variables. These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
+
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+
+
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
+
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same. If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion. Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+ s/$_G_bs4/&\\
+/g
+ s/^$_G_bs2$_G_dollar/$_G_bs&/
+ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+ s/\n//g"
+
+
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
+
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
+
+# By convention, finish your script with:
+#
+# exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath=$0
+
+# The name of this program.
+progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+ progdir=`cd "$progdir" && pwd`
+ progpath=$progdir/$progname
+ ;;
+ *)
+ _G_IFS=$IFS
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS=$_G_IFS
+ test -x "$progdir/$progname" && break
+ done
+ IFS=$_G_IFS
+ test -n "$progdir" || progdir=`pwd`
+ progpath=$progdir/$progname
+ ;;
+esac
+
+
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
+
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
+
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
+
+# Categories 'all' and 'none' are always available. Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
+
+# By default, display warnings according to 'opt_warning_types'. Set
+# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
+
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
+
+
+## -------------------- ##
+## Resource management. ##
+## -------------------- ##
+
+# This section contains definitions for functions that each ensure a
+# particular resource (a file, or a non-empty configuration variable for
+# example) is available, and if appropriate to extract default values
+# from pertinent package files. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
+
+
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+ $debug_cmd
+
+ test -t 1 && {
+ # COLORTERM and USE_ANSI_COLORS environment variables take
+ # precedence, because most terminfo databases neglect to describe
+ # whether color sequences are supported.
+ test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+ if test 1 = "$USE_ANSI_COLORS"; then
+ # Standard ANSI escape sequences
+ tc_reset=''
+ tc_bold=''; tc_standout=''
+ tc_red=''; tc_green=''
+ tc_blue=''; tc_cyan=''
+ else
+ # Otherwise trust the terminfo database after all.
+ test -n "`tput sgr0 2>/dev/null`" && {
+ tc_reset=`tput sgr0`
+ test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+ tc_standout=$tc_bold
+ test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+ test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+ test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+ test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+ test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+ }
+ fi
+ }
+
+ require_term_colors=:
+}
+
+
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
+
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
+
+
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
+
+ # We should try to minimise forks, especially on Windows where they are
+ # unreasonably slow, so skip the feature probes when bash or zsh are
+ # being used:
+ if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+ : ${_G_HAVE_ARITH_OP="yes"}
+ : ${_G_HAVE_XSI_OPS="yes"}
+ # The += operator was introduced in bash 3.1
+ case $BASH_VERSION in
+ [12].* | 3.0 | 3.0*) ;;
+ *)
+ : ${_G_HAVE_PLUSEQ_OP="yes"}
+ ;;
+ esac
+ fi
+
+ # _G_HAVE_PLUSEQ_OP
+ # Can be empty, in which case the shell is probed, "yes" if += is
+ # useable or anything else if it does not work.
+ test -z "$_G_HAVE_PLUSEQ_OP" \
+ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+ && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_append ()
+ {
+ $debug_cmd
+
+ eval "$1+=\$2"
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_append ()
+ {
+ $debug_cmd
+
+ eval "$1=\$$1\$2"
+ }
+fi
+
+
+# func_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+ eval 'func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1+=\\ \$func_quote_for_eval_result"
+ }'
+else
+ func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1=\$$1\\ \$func_quote_for_eval_result"
+ }
+fi
+
+
+# func_append_uniq VAR VALUE
+# --------------------------
+# Append unique VALUE onto the existing contents of VAR, assuming
+# entries are delimited by the first character of VALUE. For example:
+#
+# func_append_uniq options " --another-option option-argument"
+#
+# will only append to $options if " --another-option option-argument "
+# is not already present somewhere in $options already (note spaces at
+# each end implied by leading space in second argument).
+func_append_uniq ()
+{
+ $debug_cmd
+
+ eval _G_current_value='`$ECHO $'$1'`'
+ _G_delim=`expr "$2" : '\(.\)'`
+
+ case $_G_delim$_G_current_value$_G_delim in
+ *"$2$_G_delim"*) ;;
+ *) func_append "$@" ;;
+ esac
+}
+
+
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+ test -z "$_G_HAVE_ARITH_OP" \
+ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+ && _G_HAVE_ARITH_OP=yes
+
+if test yes = "$_G_HAVE_ARITH_OP"; then
+ eval 'func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=$(( $* ))
+ }'
+else
+ func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=`expr "$@"`
+ }
+fi
+
+
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ # If this shell supports suffix pattern removal, then use it to avoid
+ # forking. Hide the definitions single quotes in case the shell chokes
+ # on unsupported syntax...
+ _b='func_basename_result=${1##*/}'
+ _d='case $1 in
+ */*) func_dirname_result=${1%/*}$2 ;;
+ * ) func_dirname_result=$3 ;;
+ esac'
+
+else
+ # ...otherwise fall back to using sed.
+ _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+ _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
+ if test "X$func_dirname_result" = "X$1"; then
+ func_dirname_result=$3
+ else
+ func_append func_dirname_result "$2"
+ fi'
+fi
+
+eval 'func_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+}'
+
+
+# func_dirname FILE APPEND NONDIR_REPLACEMENT
+# -------------------------------------------
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+ $debug_cmd
+
+ '"$_d"'
+}'
+
+
+# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
+# --------------------------------------------------------
+# Perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+ '"$_d"'
+}'
+
+
+# func_echo ARG...
+# ----------------
+# Echo program name prefixed message.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ _G_infix=$1; shift
+ _G_indent=$_G_infix
+ _G_prefix="$progname: $_G_infix: "
+ _G_message=$*
+
+ # Strip color escape sequences before counting printable length
+ for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
+ do
+ test -n "$_G_tc" && {
+ _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
+ _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
+ }
+ done
+ _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
+
+ func_echo_infix_1_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_infix_1_IFS
+ $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
+ _G_prefix=$_G_indent
+ done
+ IFS=$func_echo_infix_1_IFS
+}
+
+
+# func_error ARG...
+# -----------------
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
+}
+
+
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ $debug_cmd
+
+ func_error "$*"
+ exit $EXIT_FAILURE
+}
+
+
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $debug_cmd
+
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_len STRING
+# ---------------
+# Set func_len_result to the length of STRING. STRING may not
+# start with a hyphen.
+ test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=${#1}
+ }'
+else
+ func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+ }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ $debug_cmd
+
+ _G_directory_path=$1
+ _G_dir_list=
+
+ if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+ # Protect directory names starting with '-'
+ case $_G_directory_path in
+ -*) _G_directory_path=./$_G_directory_path ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$_G_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ _G_dir_list=$_G_directory_path:$_G_dir_list
+
+ # If the last portion added has no slash in it, the list is done
+ case $_G_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+ done
+ _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+ func_mkdir_p_IFS=$IFS; IFS=:
+ for _G_dir in $_G_dir_list; do
+ IFS=$func_mkdir_p_IFS
+ # mkdir can fail with a 'File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$_G_dir" 2>/dev/null || :
+ done
+ IFS=$func_mkdir_p_IFS
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$_G_directory_path" || \
+ func_fatal_error "Failed to create '$1'"
+ fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+ $debug_cmd
+
+ _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+ if test : = "$opt_dry_run"; then
+ # Return a directory name, but don't create it in dry-run mode
+ _G_tmpdir=$_G_template-$$
+ else
+
+ # If mktemp works, use that first and foremost
+ _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$_G_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ _G_tmpdir=$_G_template-${RANDOM-0}$$
+
+ func_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$_G_tmpdir"
+ umask $func_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$_G_tmpdir" || \
+ func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+ fi
+
+ $ECHO "$_G_tmpdir"
+}
+
+
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+ $debug_cmd
+
+ # These SED scripts presuppose an absolute path with a trailing slash.
+ _G_pathcar='s|^/\([^/]*\).*$|\1|'
+ _G_pathcdr='s|^/[^/]*||'
+ _G_removedotparts=':dotsl
+ s|/\./|/|g
+ t dotsl
+ s|/\.$|/|'
+ _G_collapseslashes='s|/\{1,\}|/|g'
+ _G_finalslash='s|/*$|/|'
+
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test / = "$func_normal_abspath_tpath"; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result"; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+ $debug_cmd
+
+ $opt_quiet || func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+ $debug_cmd
+
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=$func_dirname_result
+ if test -z "$func_relative_path_tlibdir"; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test -n "$func_stripname_result"; then
+ func_append func_relative_path_result "/$func_stripname_result"
+ fi
+
+ # Normalisation. If bindir is libdir, return '.' else relative path.
+ if test -n "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ fi
+
+ test -n "$func_relative_path_result" || func_relative_path_result=.
+
+ :
+}
+
+
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+# i) func_quote_for_eval_result
+# double-quoted, suitable for a subsequent eval
+# ii) func_quote_for_eval_unquoted_result
+# has all characters that are still active within double
+# quotes backslashified.
+func_quote_for_eval ()
+{
+ $debug_cmd
+
+ func_quote_for_eval_unquoted_result=
+ func_quote_for_eval_result=
+ while test 0 -lt $#; do
+ case $1 in
+ *[\\\`\"\$]*)
+ _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+ *)
+ _G_unquoted_arg=$1 ;;
+ esac
+ if test -n "$func_quote_for_eval_unquoted_result"; then
+ func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+ else
+ func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+ fi
+
+ case $_G_unquoted_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and variable expansion
+ # for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_quoted_arg=\"$_G_unquoted_arg\"
+ ;;
+ *)
+ _G_quoted_arg=$_G_unquoted_arg
+ ;;
+ esac
+
+ if test -n "$func_quote_for_eval_result"; then
+ func_append func_quote_for_eval_result " $_G_quoted_arg"
+ else
+ func_append func_quote_for_eval_result "$_G_quoted_arg"
+ fi
+ shift
+ done
+}
+
+
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ $debug_cmd
+
+ case $1 in
+ *[\\\`\"]*)
+ _G_arg=`$ECHO "$1" | $SED \
+ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ _G_arg=$1 ;;
+ esac
+
+ case $_G_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_arg=\"$_G_arg\"
+ ;;
+ esac
+
+ func_quote_for_expand_result=$_G_arg
+}
+
+
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_stripname ()
+ {
+ $debug_cmd
+
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary variable first.
+ func_stripname_result=$3
+ func_stripname_result=${func_stripname_result#"$1"}
+ func_stripname_result=${func_stripname_result%"$2"}
+ }'
+else
+ func_stripname ()
+ {
+ $debug_cmd
+
+ case $2 in
+ .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+ *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+ esac
+ }
+fi
+
+
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ func_quote_for_expand "$_G_cmd"
+ eval "func_notquiet $func_quote_for_expand_result"
+
+ $opt_dry_run || {
+ eval "$_G_cmd"
+ _G_status=$?
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ $opt_quiet || {
+ func_quote_for_expand "$_G_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ $opt_dry_run || {
+ eval "$_G_user_locale
+ $_G_cmd"
+ _G_status=$?
+ eval "$_G_safe_locale"
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ $debug_cmd
+
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $debug_cmd
+
+ $opt_verbose && func_echo "$*"
+
+ :
+}
+
+
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
+
+
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+ $debug_cmd
+
+ # CATEGORY must be in the warning_categories list!
+ case " $warning_categories " in
+ *" $1 "*) ;;
+ *) func_internal_error "invalid warning category '$1'" ;;
+ esac
+
+ _G_category=$1
+ shift
+
+ case " $opt_warning_types " in
+ *" $_G_category "*) $warning_func ${1+"$@"} ;;
+ esac
+}
+
+
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+func_sort_ver ()
+{
+ $debug_cmd
+
+ printf '%s\n%s\n' "$1" "$2" \
+ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
+
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false. Use it like this:
+#
+# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+ $debug_cmd
+
+ test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
+
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
+
+# Copyright (C) 2010-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+# #!/bin/sh
+# . relative/path/to/funclib.sh
+# . relative/path/to/options-parser
+# scriptversion=1.0
+# func_options ${1+"$@"}
+# eval set dummy "$func_options_result"; shift
+# ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# warranty; '.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'. Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+ --debug enable verbose shell tracing
+ -W, --warnings=CATEGORY
+ report the warnings falling in CATEGORY [all]
+ -v, --verbose verbosely report processing
+ --version print version information and exit
+ -h, --help print short or long help message and exit
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message="
+Warning categories include:
+ 'all' show all warnings
+ 'none' turn off all the warnings
+ 'error' warnings are treated as fatal errors"
+
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
+
+
+
+## ------------------------- ##
+## Hook function management. ##
+## ------------------------- ##
+
+# This section contains functions for adding, removing, and running hooks
+# to the main code. A hook is just a named list of of function, that can
+# be run in order later on.
+
+# func_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+ $debug_cmd
+
+ func_append hookable_fns " $1"
+}
+
+
+# func_add_hook FUNC_NAME HOOK_FUNC
+# ---------------------------------
+# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
+# first have been declared "hookable" by a call to 'func_hookable'.
+func_add_hook ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not accept hook functions." ;;
+ esac
+
+ eval func_append ${1}_hooks '" $2"'
+}
+
+
+# func_remove_hook FUNC_NAME HOOK_FUNC
+# ------------------------------------
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+func_remove_hook ()
+{
+ $debug_cmd
+
+ eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
+}
+
+
+# func_run_hooks FUNC_NAME [ARG]...
+# ---------------------------------
+# Run all hook functions registered to FUNC_NAME.
+# It is assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+ esac
+
+ eval _G_hook_fns=\$$1_hooks; shift
+
+ for _G_hook in $_G_hook_fns; do
+ eval $_G_hook '"$@"'
+
+ # store returned options list back into positional
+ # parameters for next 'cmd' execution.
+ eval _G_hook_result=\$${_G_hook}_result
+ eval set dummy "$_G_hook_result"; shift
+ done
+
+ func_quote_for_eval ${1+"$@"}
+ func_run_hooks_result=$func_quote_for_eval_result
+}
+
+
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# In order to add your own option parsing hooks, you must accept the
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'. Like this:
+#
+# my_options_prep ()
+# {
+# $debug_cmd
+#
+# # Extend the existing usage message.
+# usage_message=$usage_message'
+# -s, --silent don'\''t print informational messages
+# '
+#
+# func_quote_for_eval ${1+"$@"}
+# my_options_prep_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_options_prep my_options_prep
+#
+#
+# my_silent_option ()
+# {
+# $debug_cmd
+#
+# # Note that for efficiency, we parse as many options as we can
+# # recognise in a loop before passing the remainder back to the
+# # caller on the first unrecognised argument we encounter.
+# while test $# -gt 0; do
+# opt=$1; shift
+# case $opt in
+# --silent|-s) opt_silent=: ;;
+# # Separate non-argument short options:
+# -s*) func_split_short_opt "$_G_opt"
+# set dummy "$func_split_short_opt_name" \
+# "-$func_split_short_opt_arg" ${1+"$@"}
+# shift
+# ;;
+# *) set dummy "$_G_opt" "$*"; shift; break ;;
+# esac
+# done
+#
+# func_quote_for_eval ${1+"$@"}
+# my_silent_option_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_parse_options my_silent_option
+#
+#
+# my_option_validation ()
+# {
+# $debug_cmd
+#
+# $opt_silent && $opt_verbose && func_fatal_help "\
+# '--silent' and '--verbose' options are mutually exclusive."
+#
+# func_quote_for_eval ${1+"$@"}
+# my_option_validation_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_validate_options my_option_validation
+#
+# You'll alse need to manually amend $usage_message to reflect the extra
+# options you parse. It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# func_options [ARG]...
+# ---------------------
+# All the functions called inside func_options are hookable. See the
+# individual implementations for details.
+func_hookable func_options
+func_options ()
+{
+ $debug_cmd
+
+ func_options_prep ${1+"$@"}
+ eval func_parse_options \
+ ${func_options_prep_result+"$func_options_prep_result"}
+ eval func_validate_options \
+ ${func_parse_options_result+"$func_parse_options_result"}
+
+ eval func_run_hooks func_options \
+ ${func_validate_options_result+"$func_validate_options_result"}
+
+ # save modified positional parameters for caller
+ func_options_result=$func_run_hooks_result
+}
+
+
+# func_options_prep [ARG]...
+# --------------------------
+# All initialisations required before starting the option parse loop.
+# Note that when calling hook functions, we pass through the list of
+# positional parameters. If a hook function modifies that list, and
+# needs to propogate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before
+# returning.
+func_hookable func_options_prep
+func_options_prep ()
+{
+ $debug_cmd
+
+ # Option defaults:
+ opt_verbose=false
+ opt_warning_types=
+
+ func_run_hooks func_options_prep ${1+"$@"}
+
+ # save modified positional parameters for caller
+ func_options_prep_result=$func_run_hooks_result
+}
+
+
+# func_parse_options [ARG]...
+# ---------------------------
+# The main option parsing loop.
+func_hookable func_parse_options
+func_parse_options ()
+{
+ $debug_cmd
+
+ func_parse_options_result=
+
+ # this just eases exit handling
+ while test $# -gt 0; do
+ # Defer to hook functions for initial option parsing, so they
+ # get priority in the event of reusing an option name.
+ func_run_hooks func_parse_options ${1+"$@"}
+
+ # Adjust func_parse_options positional parameters to match
+ eval set dummy "$func_run_hooks_result"; shift
+
+ # Break out of the loop if we already parsed every option.
+ test $# -gt 0 || break
+
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --debug|-x) debug_cmd='set -x'
+ func_echo "enabling shell trace mode"
+ $debug_cmd
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ set dummy --warnings none ${1+"$@"}
+ shift
+ ;;
+
+ --warnings|--warning|-W)
+ test $# = 0 && func_missing_arg $_G_opt && break
+ case " $warning_categories $1" in
+ *" $1 "*)
+ # trailing space prevents matching last $1 above
+ func_append_uniq opt_warning_types " $1"
+ ;;
+ *all)
+ opt_warning_types=$warning_categories
+ ;;
+ *none)
+ opt_warning_types=none
+ warning_func=:
+ ;;
+ *error)
+ opt_warning_types=$warning_categories
+ warning_func=func_fatal_error
+ ;;
+ *)
+ func_fatal_error \
+ "unsupported warning category: '$1'"
+ ;;
+ esac
+ shift
+ ;;
+
+ --verbose|-v) opt_verbose=: ;;
+ --version) func_version ;;
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+
+ # Separate optargs to long options (plugins may need this):
+ --*=*) func_split_equals "$_G_opt"
+ set dummy "$func_split_equals_lhs" \
+ "$func_split_equals_rhs" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate optargs to short options:
+ -W*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-v*|-x*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ func_parse_options_result=$func_quote_for_eval_result
+}
+
+
+# func_validate_options [ARG]...
+# ------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+func_hookable func_validate_options
+func_validate_options ()
+{
+ $debug_cmd
+
+ # Display all warnings if -W was not given.
+ test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+
+ func_run_hooks func_validate_options ${1+"$@"}
+
+ # Bail if the options were screwed!
+ $exit_cmd $EXIT_FAILURE
+
+ # save modified positional parameters for caller
+ func_validate_options_result=$func_run_hooks_result
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ eval \$ECHO \""$fatal_help"\"
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message"
+ exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $debug_cmd
+
+ func_error "Missing argument for '$1'."
+ exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=${1%%=*}
+ func_split_equals_rhs=${1#*=}
+ test "x$func_split_equals_lhs" = "x$1" \
+ && func_split_equals_rhs=
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
+ func_split_equals_rhs=
+ test "x$func_split_equals_lhs" = "x$1" \
+ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
+ }
+fi #func_split_equals
+
+
+# func_split_short_opt SHORTOPT
+# -----------------------------
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
+ func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
+ }
+fi #func_split_short_opt
+
+
+# func_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+ exit 0
+}
+
+
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ echo
+ $SED -n 's|^# ||
+ /^Written by/{
+ x;p;x
+ }
+ h
+ /^Written by/q' < "$progpath"
+ echo
+ eval \$ECHO \""$usage_message"\"
+}
+
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $debug_cmd
+
+ printf '%s\n' "$progname $scriptversion"
+ $SED -n '
+ /(C)/!b go
+ :more
+ /\./!{
+ N
+ s|\n# | |
+ b more
+ }
+ :go
+ /^# Written by /,/# warranty; / {
+ s|^# ||
+ s|^# *$||
+ s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+ p
+ }
+ /^# Written by / {
+ s|^# ||
+ p
+ }
+ /^warranty; /q' < "$progpath"
+
+ exit $?
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+
+# Set a version string.
+scriptversion='(GNU libtool) 2.4.6'
+
+
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+ $debug_cmd
+
+ $warning_func ${1+"$@"}
+}
+
+
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+ -n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --mode=MODE use operation mode MODE
+ --no-warnings equivalent to '-Wnone'
+ --preserve-dup-deps don't remove duplicate dependency libraries
+ --quiet, --silent don't print informational messages
+ --tag=TAG use configuration variables from tag TAG
+ -v, --verbose print more informational messages than default
+ --version print version information
+ -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all]
+ -h, --help, --help-all print short, long, or detailed help message
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+ host-triplet: $host
+ shell: $SHELL
+ compiler: $LTCC
+ compiler flags: $LTCFLAGS
+ linker: $LD (gnu? $with_gnu_ld)
+ version: $progname (GNU libtool) 2.4.6
+ automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+ autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to <bug-libtool@gnu.org>.
+GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+ exit 0
+}
+
+
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
+
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_lo2o ()
+ {
+ case $1 in
+ *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+ * ) func_lo2o_result=$1 ;;
+ esac
+ }'
+
+ # func_xform LIBOBJ-OR-SOURCE
+ # ---------------------------
+ # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+ # suffix to a '.lo' libtool-object suffix.
+ eval 'func_xform ()
+ {
+ func_xform_result=${1%.*}.lo
+ }'
+else
+ # ...otherwise fall back to using sed.
+ func_lo2o ()
+ {
+ func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+ }
+
+ func_xform ()
+ {
+ func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+ }
+fi
+
+
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func__fatal_error ${1+"$@"} \
+ "See the $PACKAGE documentation for more information." \
+ "Fatal configuration error."
+}
+
+
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test yes = "$build_libtool_libs"; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test yes = "$build_old_libs"; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname=$1
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf=/$re_begincf/,/$re_endcf/p
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+ $debug_mode
+
+ # Option defaults:
+ opt_config=false
+ opt_dlopen=
+ opt_dry_run=false
+ opt_help=false
+ opt_mode=
+ opt_preserve_dup_deps=false
+ opt_quiet=false
+
+ nonopt=
+ preserve_args=
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Pass back the list of options.
+ func_quote_for_eval ${1+"$@"}
+ libtool_options_prep_result=$func_quote_for_eval_result
+}
+func_add_hook func_options_prep libtool_options_prep
+
+
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+ $debug_cmd
+
+ # Perform our own loop to consume as many options as possible in
+ # each iteration.
+ while test $# -gt 0; do
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+
+ --config) func_config ;;
+
+ --dlopen|-dlopen)
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=: ;;
+
+ --features) func_features ;;
+
+ --finish) set dummy --mode finish ${1+"$@"}; shift ;;
+
+ --help) opt_help=: ;;
+
+ --help-all) opt_help=': help-all' ;;
+
+ --mode) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_mode=$1
+ case $1 in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $_G_opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+ shift
+ ;;
+
+ --no-silent|--no-quiet)
+ opt_quiet=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ opt_warning=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-verbose)
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --silent|--quiet)
+ opt_quiet=:
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --tag) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_tag=$1
+ func_append preserve_args " $_G_opt $1"
+ func_enable_tag "$1"
+ shift
+ ;;
+
+ --verbose|-v) opt_quiet=false
+ opt_verbose=:
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ # An option not handled by this hook function:
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ libtool_parse_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_parse_options libtool_parse_options
+
+
+
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+ # save first non-option argument
+ if test 0 -lt $#; then
+ nonopt=$1
+ shift
+ fi
+
+ # preserve --debug
+ test : = "$debug_cmd" || func_append preserve_args " --debug"
+
+ case $host in
+ # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+ # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+ *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ test yes != "$build_libtool_libs" \
+ && test yes != "$build_old_libs" \
+ && func_fatal_configuration "not configured to build any kind of library"
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+ func_error "unrecognized option '-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help=$help
+ help="Try '$progname --help --mode=$opt_mode' for more information."
+ }
+
+ # Pass back the unparsed argument list
+ func_quote_for_eval ${1+"$@"}
+ libtool_validate_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_validate_options libtool_validate_options
+
+
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
+
+# Global variables.
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+ $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case $lalib_p_line in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test yes = "$lalib_p"
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ test -f "$1" &&
+ $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $debug_cmd
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $debug_cmd
+
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case $lt_sysroot:$1 in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result='='$func_stripname_result
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $debug_cmd
+
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with '--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=$1
+ if test yes = "$build_libtool_libs"; then
+ write_lobj=\'$2\'
+ else
+ write_lobj=none
+ fi
+
+ if test yes = "$build_old_libs"; then
+ write_oldobj=\'$3\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "$write_libobj"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $debug_cmd
+
+ func_convert_core_file_wine_to_w32_result=$1
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $debug_cmd
+
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result"; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $debug_cmd
+
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $debug_cmd
+
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $debug_cmd
+
+ if test -z "$2" && test -n "$1"; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result=$1
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $debug_cmd
+
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " '$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result=$3
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $debug_cmd
+
+ case $4 in
+ $1 ) func_to_host_path_result=$3$func_to_host_path_result
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $debug_cmd
+
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $debug_cmd
+
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result=$1
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_msys_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $debug_cmd
+
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd=func_convert_path_$func_stripname_result
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $debug_cmd
+
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result=$1
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_msys_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+ $debug_cmd
+
+ func_dll_def_p_tmp=`$SED -n \
+ -e 's/^[ ]*//' \
+ -e '/^\(;.*\)*$/d' \
+ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \
+ -e q \
+ "$1"`
+ test DEF = "$func_dll_def_p_tmp"
+}
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $debug_cmd
+
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile=$nonopt # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg=$arg
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj=$arg
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify '-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs=$IFS; IFS=,
+ for arg in $args; do
+ IFS=$save_ifs
+ func_append_quoted lastarg "$arg"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg=$srcfile
+ srcfile=$arg
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with '-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj=$func_basename_result
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from '$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test yes = "$build_libtool_libs" \
+ || func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name '$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname=$func_basename_result
+ xdir=$func_dirname_result
+ lobj=$xdir$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test yes = "$build_old_libs"; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test no = "$compiler_c_o"; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+ lockfile=$output_obj.lock
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test yes = "$need_locks"; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test warn = "$need_locks"; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test yes = "$build_libtool_libs"; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test no != "$pic_mode"; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test yes = "$suppress_opt"; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test yes = "$build_old_libs"; then
+ if test yes != "$pic_mode"; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test yes = "$compiler_c_o"; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test no != "$need_locks"; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a '.o' file suitable for static linking
+ -static only build a '.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the '--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE use a list of object files found in FILE to specify objects
+ -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes)
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename. Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode '$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test : = "$opt_help"; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | $SED -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ $SED '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $debug_cmd
+
+ # The first argument is the command name.
+ cmd=$nonopt
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "'$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "'$file' was not linked with '-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ ;;
+
+ *)
+ func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir=$absdir
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic=$magic
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if $opt_dry_run; then
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ else
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd=\$cmd$args
+ fi
+}
+
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $debug_cmd
+
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "'$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument '$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_quiet && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the '$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the '$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the '$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $debug_cmd
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac
+ then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=false
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=: ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test X-m = "X$prev" && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=:
+ if $isdir; then
+ destdir=$dest
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir=$func_dirname_result
+ destname=$func_basename_result
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "'$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "'$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir=$func_dirname_result
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking '$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname=$1
+ shift
+
+ srcname=$realname
+ test -n "$relink_command" && srcname=${realname}T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme=$stripme
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ os2*)
+ case $realname in
+ *_dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try 'ln -sf' first, because the 'ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib=$destdir/$realname
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name=$func_basename_result
+ instname=$dir/${name}i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest=$destfile
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to '$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test yes = "$build_old_libs"; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=.exe
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+ finalize=:
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "'$lib' has not been installed in '$libdir'"
+ finalize=false
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test no = "$fast_install" && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if $finalize; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file=$func_basename_result
+ outputname=$tmpdir/$file
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_quiet || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink '$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file=$outputname
+ else
+ func_warning "cannot relink '$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name=$func_basename_result
+
+ # Set up the ranlib parameters.
+ oldlib=$destdir/$name
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run '$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $debug_cmd
+
+ my_outputname=$1
+ my_originator=$2
+ my_pic_p=${3-false}
+ my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms=${my_outputname}S.c
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist=$output_objdir/$my_outputname.nm
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test yes = "$dlself"; then
+ func_verbose "generating symbol list for '$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols=$output_objdir/$outputname.exp
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from '$dlprefile'"
+ func_basename "$dlprefile"
+ name=$func_basename_result
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname"; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename=$func_basename_result
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename"; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ func_show_eval '$RM "${nlist}I"'
+ if test -n "$global_symbol_to_import"; then
+ eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+ LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+ for (; symbol->name; ++symbol)
+ {"
+ $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+ echo >> "$output_objdir/$my_dlsyms" "\
+ }
+}"
+ fi
+ echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {\"@INIT@\", (void *) &lt_syminit},"
+ fi
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj=$output_objdir/${my_outputname}S.$objext
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for '$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $debug_cmd
+
+ win32_libid_type=unknown
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ case $nm_interface in
+ "MS dumpbin")
+ if func_cygming_ms_implib_p "$1" ||
+ func_cygming_gnu_implib_p "$1"
+ then
+ win32_nmres=import
+ else
+ win32_nmres=
+ fi
+ ;;
+ *)
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s|.*|import|
+ p
+ q
+ }
+ }'`
+ ;;
+ esac
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $debug_cmd
+
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $debug_cmd
+
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive that possess that section. Heuristic: eliminate
+ # all those that have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $debug_cmd
+
+ if func_cygming_gnu_implib_p "$1"; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1"; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $debug_cmd
+
+ f_ex_an_ar_dir=$1; shift
+ f_ex_an_ar_oldlib=$1
+ if test yes = "$lock_old_archive_extraction"; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test yes = "$lock_old_archive_extraction"; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $debug_cmd
+
+ my_gentop=$1; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=
+ my_xlib=
+ my_xabs=
+ my_xdir=
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib=$func_basename_result
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir=$my_gentop/$my_xlib_u
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ func_basename "$darwin_archive"
+ darwin_base_archive=$func_basename_result
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches; do
+ func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+ $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+ cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+ func_extract_an_archive "`pwd`" "$darwin_base_archive"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test yes = "$fast_install"; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ \$ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+ defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+# define externally_visible volatile
+#else
+# define externally_visible __attribute__((externally_visible)) volatile
+#endif
+externally_visible const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test yes = "$fast_install"; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ int rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, (size_t) argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (STREQ (argv[i], dumpscript_opt))
+ {
+EOF
+ case $host in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (STREQ (argv[i], debug_opt))
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (STREQ (argv[i], ltwrapper_option_prefix))
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ size_t tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = (size_t) (q - p);
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (STREQ (str, pat))
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ size_t len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ size_t orig_value_len = strlen (orig_value);
+ size_t add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ size_t len = strlen (new_value);
+ while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[--len] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $debug_cmd
+
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_suncc_cstd_abi
+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
+# Several compiler flags select an ABI that is incompatible with the
+# Cstd library. Avoid specifying it if any are in CXXFLAGS.
+func_suncc_cstd_abi ()
+{
+ $debug_cmd
+
+ case " $compile_command " in
+ *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
+ suncc_use_cstd_abi=no
+ ;;
+ *)
+ suncc_use_cstd_abi=yes
+ ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $debug_cmd
+
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # what system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll that has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ os2dllname=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=false
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module=$wl-single_module
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test yes != "$build_libtool_libs" \
+ && func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg=$1
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir=$arg
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ $preload || {
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=:
+ }
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test no = "$dlself"; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test dlprefiles = "$prev"; then
+ dlself=yes
+ elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test dlfiles = "$prev"; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols=$arg
+ test -f "$arg" \
+ || func_fatal_error "symbol file '$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex=$arg
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir=$arg
+ prev=
+ continue
+ ;;
+ mllvm)
+ # Clang does not use LLVM to link, so we can simply discard any
+ # '-mllvm $arg' options when doing the link step.
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ if test none != "$pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ fi
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file '$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ os2dllname)
+ os2dllname=$arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex=$arg
+ prev=
+ continue
+ ;;
+ release)
+ release=-$arg
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test rpath = "$prev"; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds=$arg
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg=$arg
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "'-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test X-export-symbols = "X$arg"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between '-L' and '$1'"
+ else
+ func_fatal_error "need path for '-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of '$dir'"
+ dir=$absdir
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc due to us having libc/libc_r.
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test X-lc = "X$arg" && continue
+ ;;
+ esac
+ elif test X-lc_r = "X$arg"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -mllvm)
+ prev=mllvm
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module=$wl-multi_module
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "'-no-install' is ignored for $host"
+ func_warning "assuming '-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -os2dllname)
+ prev=os2dllname
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # -fstack-protector* stack protector flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ # -stdlib=* select c++ std lib with clang
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ -Z*)
+ if test os2 = "`expr $host : '.*\(os2\)'`"; then
+ # OS/2 uses -Zxxx to specify OS/2-specific options
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case $arg in
+ -Zlinker | -Zstack)
+ prev=xcompiler
+ ;;
+ esac
+ continue
+ else
+ # Otherwise treat like 'Some other compiler flag' below
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ fi
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ test none = "$pic_object" || {
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ }
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test dlfiles = "$prev"; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test dlprefiles = "$prev"; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prevarg' option requires an argument"
+
+ if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname=$func_basename_result
+ libobjs_save=$libobjs
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ # Definition is injected by LT_CONFIG during libtool generation.
+ func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
+
+ func_dirname "$output" "/" ""
+ output_objdir=$func_dirname_result$objdir
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test lib = "$linkmode"; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=false
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test lib,link = "$linkmode,$pass"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs=$tmp_deplibs
+ fi
+
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass"; then
+ libs=$deplibs
+ deplibs=
+ fi
+ if test prog = "$linkmode"; then
+ case $pass in
+ dlopen) libs=$dlfiles ;;
+ dlpreopen) libs=$dlprefiles ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test lib,dlpreopen = "$linkmode,$pass"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs=$dlprefiles
+ fi
+ if test dlopen = "$pass"; then
+ # Collect dlpreopened libraries
+ save_deplibs=$deplibs
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=false
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test lib != "$linkmode" && test prog != "$linkmode"; then
+ func_warning "'-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test lib = "$linkmode"; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib=$searchdir/lib$name$search_ext
+ if test -f "$lib"; then
+ if test .la = "$search_ext"; then
+ found=:
+ else
+ found=false
+ fi
+ break 2
+ fi
+ done
+ done
+ if $found; then
+ # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll=$l
+ done
+ if test "X$ll" = "X$old_library"; then # only static version available
+ found=false
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+ lib=$ladir/$old_library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ else
+ # deplib doesn't seem to be a libtool library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ ;; # -l
+ *.ltframework)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test conv = "$pass" && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test scan = "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "'-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test link = "$pass"; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=false
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=:
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=:
+ ;;
+ esac
+ if $valid_a_lib; then
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ else
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test link != "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ elif test prog = "$linkmode"; then
+ if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=:
+ continue
+ ;;
+ esac # case $deplib
+
+ $found || test -f "$lib" \
+ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "'$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass" ||
+ { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test conv = "$pass"; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ elif test prog != "$linkmode" && test lib != "$linkmode"; then
+ func_fatal_error "'$lib' is not a convenience library"
+ fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test yes = "$prefer_static_libs" ||
+ test built,no = "$prefer_static_libs,$installed"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib=$l
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test dlopen = "$pass"; then
+ test -z "$libdir" \
+ && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+ if test -z "$dlname" ||
+ test yes != "$dlopen_support" ||
+ test no = "$build_libtool_libs"
+ then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of '$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir=$ladir
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname=$func_basename_result
+
+ # Find the relevant object directory and library name.
+ if test yes = "$installed"; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library '$lib' was moved."
+ dir=$ladir
+ absdir=$abs_ladir
+ libdir=$abs_ladir
+ else
+ dir=$lt_sysroot$libdir
+ absdir=$lt_sysroot$libdir
+ fi
+ test yes = "$hardcode_automatic" && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir=$ladir
+ absdir=$abs_ladir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir=$ladir/$objdir
+ absdir=$abs_ladir/$objdir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test dlpreopen = "$pass"; then
+ if test -z "$libdir" && test prog = "$linkmode"; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+ fi
+ case $host in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test lib = "$linkmode"; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test prog = "$linkmode" && test link != "$pass"; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=false
+ if test no != "$link_all_deplibs" || test -z "$library_names" ||
+ test no = "$build_libtool_libs"; then
+ linkalldeplibs=:
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if $linkalldeplibs; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test prog,link = "$linkmode,$pass"; then
+ if test -n "$library_names" &&
+ { { test no = "$prefer_static_libs" ||
+ test built,yes = "$prefer_static_libs,$installed"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if $alldeplibs &&
+ { test pass_all = "$deplibs_check_method" ||
+ { test yes = "$build_libtool_libs" &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test built = "$use_static_libs" && test yes = "$installed"; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test no = "$use_static_libs" || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc* | *os2*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test no = "$installed"; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule=$dlpremoduletest
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+ echo
+ if test prog = "$linkmode"; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test lib = "$linkmode" &&
+ test yes = "$hardcode_into_libs"; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname=$dlname
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc* | *os2*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot=$soname
+ func_basename "$soroot"
+ soname=$func_basename_result
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from '$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for '$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test prog = "$linkmode" || test relink != "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test no = "$hardcode_direct"; then
+ add=$dir/$linklib
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
+ *-*-sysv4*uw2*) add_dir=-L$dir ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir=-L$dir ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we cannot
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library"; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add=$dir/$old_library
+ fi
+ elif test -n "$old_library"; then
+ add=$dir/$old_library
+ fi
+ fi
+ esac
+ elif test no = "$hardcode_minus_L"; then
+ case $host in
+ *-*-sunos*) add_shlibpath=$dir ;;
+ esac
+ add_dir=-L$dir
+ add=-l$name
+ elif test no = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$dir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$absdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test yes != "$lib_linked"; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test yes != "$hardcode_direct" &&
+ test yes != "$hardcode_minus_L" &&
+ test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test prog = "$linkmode" || test relink = "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$libdir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$libdir
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add=-l$name
+ elif test yes = "$hardcode_automatic"; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib"; then
+ add=$inst_prefix_dir$libdir/$linklib
+ else
+ add=$libdir/$linklib
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir=-L$libdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ fi
+
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test prog = "$linkmode"; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test unsupported != "$hardcode_direct"; then
+ test -n "$old_library" && linklib=$old_library
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test yes = "$build_libtool_libs"; then
+ # Not a shared library
+ if test pass_all != "$deplibs_check_method"; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test yes = "$module"; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test lib = "$linkmode"; then
+ if test -n "$dependency_libs" &&
+ { test yes != "$hardcode_into_libs" ||
+ test yes = "$build_old_libs" ||
+ test yes = "$link_static"; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs=$temp_deplibs
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test no != "$link_all_deplibs"; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path=$deplib ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of '$dir'"
+ absdir=$dir
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names"; then
+ for tmp in $deplibrary_names; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl"; then
+ depdepl=$absdir/$objdir/$depdepl
+ darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
+ func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path=-L$absdir/$objdir
+ ;;
+ esac
+ else
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "'$deplib' seems to be moved"
+
+ path=-L$absdir
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs=$newdependency_libs
+ if test dlpreopen = "$pass"; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test dlopen != "$pass"; then
+ test conv = "$pass" || {
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ }
+
+ if test prog,link = "$linkmode,$pass"; then
+ vars="compile_deplibs finalize_deplibs"
+ else
+ vars=deplibs
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+
+ # Add Sun CC postdeps if required:
+ test CXX = "$tagname" && {
+ case $host_os in
+ linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C++ 5.9
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ func_cc_basename "$CC"
+ case $func_cc_basename_result in
+ CC* | sunCC*)
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ }
+
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=
+ ;;
+ esac
+ if test -n "$i"; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test prog = "$linkmode"; then
+ dlfiles=$newdlfiles
+ fi
+ if test prog = "$linkmode" || test lib = "$linkmode"; then
+ dlprefiles=$newdlprefiles
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "'-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs=$output
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form 'libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test no = "$module" \
+ && func_fatal_help "libtool library '$output' must begin with 'lib'"
+
+ if test no != "$need_lib_prefix"; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test pass_all != "$deplibs_check_method"; then
+ func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test no = "$dlself" \
+ || func_warning "'-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test 1 -lt "$#" \
+ && func_warning "ignoring multiple '-rpath's for a libtool library"
+
+ install_libdir=$1
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test yes = "$build_libtool_libs"; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a '.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs=$IFS; IFS=:
+ set dummy $vinfo 0 0 0
+ shift
+ IFS=$save_ifs
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to '-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major=$1
+ number_minor=$2
+ number_revision=$3
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # that has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|freebsd-elf|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_revision
+ ;;
+ freebsd-aout|qnx|sunos)
+ current=$number_major
+ revision=$number_minor
+ age=0
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_minor
+ lt_irix_increment=no
+ ;;
+ esac
+ ;;
+ no)
+ current=$1
+ revision=$2
+ age=$3
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT '$current' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION '$revision' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE '$age' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE '$age' is greater than the current interface number '$current'"
+ func_fatal_error "'$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ # On Darwin other compilers
+ case $CC in
+ nagfor*)
+ verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ ;;
+ *)
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+ esac
+ ;;
+
+ freebsd-aout)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ freebsd-elf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ irix | nonstopux)
+ if test no = "$lt_irix_increment"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring=$verstring_prefix$major.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test 0 -ne "$loop"; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring_prefix$major.$iface:$verstring
+ done
+
+ # Before this point, $major must not contain '.'.
+ major=.$major
+ versuffix=$major.$revision
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=.$current.$age.$revision
+ verstring=$current.$age.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test 0 -ne "$loop"; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring:$iface.0
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":$current.0"
+ ;;
+
+ qnx)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sco)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sunos)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 file systems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type '$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring=0.0
+ ;;
+ esac
+ if test no = "$need_version"; then
+ versuffix=
+ else
+ versuffix=.0.0
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test yes,no = "$avoid_version,$need_version"; then
+ major=
+ versuffix=
+ verstring=
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test yes = "$allow_undefined"; then
+ if test unsupported = "$allow_undefined_flag"; then
+ if test yes = "$build_old_libs"; then
+ func_warning "undefined symbols not allowed in $host shared libraries; building static only"
+ build_libtool_libs=no
+ else
+ func_fatal_error "can't build $host shared library unless -no-undefined is specified"
+ fi
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag=$no_undefined_flag
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" :
+ func_append libobjs " $symfileobj"
+ test " " = "$libobjs" && libobjs=
+
+ if test relink != "$opt_mode"; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
+ if test -n "$precious_files_regex"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles=$dlfiles
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles=$dlprefiles
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test yes = "$build_libtool_libs"; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test yes = "$build_libtool_need_lc"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=
+ versuffix=
+ major=
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test yes = "$want_nocaseglob"; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib=$potent_lib
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
+ *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib=$potent_lib # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ for i in $predeps $postdeps; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test none = "$deplibs_check_method"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test yes = "$droppeddeps"; then
+ if test yes = "$module"; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test no = "$allow_undefined"; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs=$new_libs
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test yes = "$build_libtool_libs"; then
+ # Remove $wl instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test yes = "$hardcode_into_libs"; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath=$finalize_rpath
+ test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath=$finalize_shlibpath
+ test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib=$output_objdir/$realname
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols=$output_objdir/$libname.uexp
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ func_dll_def_p "$export_symbols" || {
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols=$export_symbols
+ export_symbols=
+ always_export_symbols=yes
+ }
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs=$IFS; IFS='~'
+ for cmd1 in $cmds; do
+ IFS=$save_ifs
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test yes = "$try_normal_branch" \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=$output_objdir/$output_la.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS=$save_ifs
+ if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs=$tmp_deplibs
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test yes = "$compiler_needs_object" &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test : != "$skipped_export" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+ output=$output_objdir/$output_la.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+ output=$output_objdir/$output_la.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test yes = "$compiler_needs_object"; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-$k.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test -z "$objlist" ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test 1 -eq "$k"; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-$k.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-$k.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ ${skipped_export-false} && {
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ }
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs=$IFS; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ ${skipped_export-false} && {
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ }
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $cmds; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test yes = "$module" || test yes = "$export_dynamic"; then
+ # On all known operating systems, these are identical.
+ dlname=$soname
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object '$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj=$output
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # if reload_cmds runs $LD directly, get rid of -Wl from
+ # whole_archive_flag_spec and hope we can get by with turning comma
+ # into space.
+ case $reload_cmds in
+ *\$LD[\ \$]*) wl= ;;
+ esac
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+ else
+ gentop=$output_objdir/${obj}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+
+ # Create the old-style object.
+ reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+
+ output=$obj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ test yes = "$build_libtool_libs" || {
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ }
+
+ if test -n "$pic_flag" || test default != "$pic_mode"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output=$libobj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for programs"
+
+ $preload \
+ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
+ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test CXX = "$tagname"; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " $wl-bind_at_load"
+ func_append finalize_command " $wl-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs=$new_libs
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath=$rpath
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath=$rpath
+
+ if test -n "$libobjs" && test yes = "$build_old_libs"; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" false
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=:
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=false
+ ;;
+ *cygwin* | *mingw* )
+ test yes = "$build_libtool_libs" || wrappers_required=false
+ ;;
+ *)
+ if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
+ wrappers_required=false
+ fi
+ ;;
+ esac
+ $wrappers_required || {
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command=$compile_command$compile_rpath
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.$objext"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+ fi
+
+ exit $exit_status
+ }
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test yes = "$no_install"; then
+ # We don't need to create a wrapper script.
+ link_command=$compile_var$compile_command$compile_rpath
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ case $hardcode_action,$fast_install in
+ relink,*)
+ # Fast installation is not supported
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "'$output' will be relinked during installation"
+ ;;
+ *,yes)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ ;;
+ *,no)
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+ ;;
+ *,needless)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=
+ ;;
+ esac
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource=$output_path/$objdir/lt-$output_name.c
+ cwrapper=$output_path/$output_name.exe
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host"; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ case $build_libtool_libs in
+ convenience)
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs=$convenience
+ build_libtool_libs=no
+ ;;
+ module)
+ oldobjs=$libobjs_save
+ addlibs=$old_convenience
+ build_libtool_libs=no
+ ;;
+ *)
+ oldobjs="$old_deplibs $non_pic_objects"
+ $preload && test -f "$symfileobj" \
+ && func_append oldobjs " $symfileobj"
+ addlibs=$old_convenience
+ ;;
+ esac
+
+ if test -n "$addlibs"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase=$func_basename_result
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj"; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test -z "$oldobjs"; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test yes = "$build_old_libs" && old_library=$libname.$libext
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test yes = "$hardcode_automatic"; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test yes = "$installed"; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output=$output_objdir/${outputname}i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name=$func_basename_result
+ func_resolve_sysroot "$deplib"
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs=$newdependency_libs
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles=$newdlprefiles
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles=$newdlprefiles
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test -n "$bindir"; then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result/$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that cannot go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test no,yes = "$installed,$need_relink"; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+if test link = "$opt_mode" || test relink = "$opt_mode"; then
+ func_mode_link ${1+"$@"}
+fi
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $debug_cmd
+
+ RM=$nonopt
+ files=
+ rmforce=false
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=: ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ if test . = "$dir"; then
+ odir=$objdir
+ else
+ odir=$dir/$objdir
+ fi
+ func_basename "$file"
+ name=$func_basename_result
+ test uninstall = "$opt_mode" && odir=$dir
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test clean = "$opt_mode"; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif $rmforce; then
+ continue
+ fi
+
+ rmfiles=$file
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case $opt_mode in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" && test none != "$pic_object"; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test clean = "$opt_mode"; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.$objext"
+ if test yes = "$fast_install" && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name"; then
+ func_append rmfiles " $odir/lt-$noexename.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the $objdir's in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
+ func_mode_uninstall ${1+"$@"}
+fi
+
+test -z "$opt_mode" && {
+ help=$generic_help
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode '$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# where we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/config/missing b/config/missing
new file mode 100755
index 0000000..f62bbae
--- /dev/null
+++ b/config/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+fi
+
+case $1 in
+
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
+
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'autom4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config/modules.mgk b/config/modules.mgk
new file mode 100644
index 0000000..0c12e87
--- /dev/null
+++ b/config/modules.mgk
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+ Magick Module Alias Map (modules.mgk)
+
+ Provides a mapping from a magick format identifier string to the
+ name of the loadable module which supports it. This allows a module
+ to support formats other than its own name. This file is optional
+ and the software will still function if it is removed.
+
+ Entries are of the form:
+
+ <module magick="MYMAGICK" name="MYMODULE" />
+
+-->
+<modulemap>
+
+</modulemap>
diff --git a/config/tap-driver.sh b/config/tap-driver.sh
new file mode 100755
index 0000000..4254e2b
--- /dev/null
+++ b/config/tap-driver.sh
@@ -0,0 +1,651 @@
+#! /bin/sh
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+#
+# 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, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+scriptversion=2013-12-23.17; # UTC
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+me=tap-driver.sh
+
+fatal ()
+{
+ echo "$me: fatal: $*" >&2
+ exit 1
+}
+
+usage_error ()
+{
+ echo "$me: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ tap-driver.sh --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--ignore-exit]
+ [--diagnostic-string=STRING] [--merge|--no-merge]
+ [--comments|--no-comments] [--] TEST-COMMAND
+The '--test-name', '-log-file' and '--trs-file' options are mandatory.
+END
+}
+
+# TODO: better error handling in option parsing (in particular, ensure
+# TODO: $log_file, $trs_file and $test_name are defined).
+test_name= # Used for reporting.
+log_file= # Where to save the result and output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=0
+color_tests=0
+merge=0
+ignore_exit=0
+comments=0
+diag_string='#'
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "$me $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) shift;; # No-op.
+ --merge) merge=1;;
+ --no-merge) merge=0;;
+ --ignore-exit) ignore_exit=1;;
+ --comments) comments=1;;
+ --no-comments) comments=0;;
+ --diagnostic-string) diag_string=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ esac
+ shift
+done
+
+test $# -gt 0 || usage_error "missing test command"
+
+case $expect_failure in
+ yes) expect_failure=1;;
+ *) expect_failure=0;;
+esac
+
+if test $color_tests = yes; then
+ init_colors='
+ color_map["red"]="" # Red.
+ color_map["grn"]="" # Green.
+ color_map["lgn"]="" # Light green.
+ color_map["blu"]="" # Blue.
+ color_map["mgn"]="" # Magenta.
+ color_map["std"]="" # No color.
+ color_for_result["ERROR"] = "mgn"
+ color_for_result["PASS"] = "grn"
+ color_for_result["XPASS"] = "red"
+ color_for_result["FAIL"] = "red"
+ color_for_result["XFAIL"] = "lgn"
+ color_for_result["SKIP"] = "blu"'
+else
+ init_colors=''
+fi
+
+# :; is there to work around a bug in bash 3.2 (and earlier) which
+# does not always set '$?' properly on redirection failure.
+# See the Autoconf manual for more details.
+:;{
+ (
+ # Ignore common signals (in this subshell only!), to avoid potential
+ # problems with Korn shells. Some Korn shells are known to propagate
+ # to themselves signals that have killed a child process they were
+ # waiting for; this is done at least for SIGINT (and usually only for
+ # it, in truth). Without the `trap' below, such a behaviour could
+ # cause a premature exit in the current subshell, e.g., in case the
+ # test command it runs gets terminated by a SIGINT. Thus, the awk
+ # script we are piping into would never seen the exit status it
+ # expects on its last input line (which is displayed below by the
+ # last `echo $?' statement), and would thus die reporting an internal
+ # error.
+ # For more information, see the Autoconf manual and the threads:
+ # <http://lists.gnu.org/archive/html/bug-autoconf/2011-09/msg00004.html>
+ # <http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2009-February/004121.html>
+ trap : 1 3 2 13 15
+ if test $merge -gt 0; then
+ exec 2>&1
+ else
+ exec 2>&3
+ fi
+ "$@"
+ echo $?
+ ) | LC_ALL=C ${AM_TAP_AWK-awk} \
+ -v me="$me" \
+ -v test_script_name="$test_name" \
+ -v log_file="$log_file" \
+ -v trs_file="$trs_file" \
+ -v expect_failure="$expect_failure" \
+ -v merge="$merge" \
+ -v ignore_exit="$ignore_exit" \
+ -v comments="$comments" \
+ -v diag_string="$diag_string" \
+'
+# TODO: the usages of "cat >&3" below could be optimized when using
+# GNU awk, and/on on systems that supports /dev/fd/.
+
+# Implementation note: in what follows, `result_obj` will be an
+# associative array that (partly) simulates a TAP result object
+# from the `TAP::Parser` perl module.
+
+## ----------- ##
+## FUNCTIONS ##
+## ----------- ##
+
+function fatal(msg)
+{
+ print me ": " msg | "cat >&2"
+ exit 1
+}
+
+function abort(where)
+{
+ fatal("internal error " where)
+}
+
+# Convert a boolean to a "yes"/"no" string.
+function yn(bool)
+{
+ return bool ? "yes" : "no";
+}
+
+function add_test_result(result)
+{
+ if (!test_results_index)
+ test_results_index = 0
+ test_results_list[test_results_index] = result
+ test_results_index += 1
+ test_results_seen[result] = 1;
+}
+
+# Whether the test script should be re-run by "make recheck".
+function must_recheck()
+{
+ for (k in test_results_seen)
+ if (k != "XFAIL" && k != "PASS" && k != "SKIP")
+ return 1
+ return 0
+}
+
+# Whether the content of the log file associated to this test should
+# be copied into the "global" test-suite.log.
+function copy_in_global_log()
+{
+ for (k in test_results_seen)
+ if (k != "PASS")
+ return 1
+ return 0
+}
+
+function get_global_test_result()
+{
+ if ("ERROR" in test_results_seen)
+ return "ERROR"
+ if ("FAIL" in test_results_seen || "XPASS" in test_results_seen)
+ return "FAIL"
+ all_skipped = 1
+ for (k in test_results_seen)
+ if (k != "SKIP")
+ all_skipped = 0
+ if (all_skipped)
+ return "SKIP"
+ return "PASS";
+}
+
+function stringify_result_obj(result_obj)
+{
+ if (result_obj["is_unplanned"] || result_obj["number"] != testno)
+ return "ERROR"
+
+ if (plan_seen == LATE_PLAN)
+ return "ERROR"
+
+ if (result_obj["directive"] == "TODO")
+ return result_obj["is_ok"] ? "XPASS" : "XFAIL"
+
+ if (result_obj["directive"] == "SKIP")
+ return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL;
+
+ if (length(result_obj["directive"]))
+ abort("in function stringify_result_obj()")
+
+ return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL
+}
+
+function decorate_result(result)
+{
+ color_name = color_for_result[result]
+ if (color_name)
+ return color_map[color_name] "" result "" color_map["std"]
+ # If we are not using colorized output, or if we do not know how
+ # to colorize the given result, we should return it unchanged.
+ return result
+}
+
+function report(result, details)
+{
+ if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/)
+ {
+ msg = ": " test_script_name
+ add_test_result(result)
+ }
+ else if (result == "#")
+ {
+ msg = " " test_script_name ":"
+ }
+ else
+ {
+ abort("in function report()")
+ }
+ if (length(details))
+ msg = msg " " details
+ # Output on console might be colorized.
+ print decorate_result(result) msg
+ # Log the result in the log file too, to help debugging (this is
+ # especially true when said result is a TAP error or "Bail out!").
+ print result msg | "cat >&3";
+}
+
+function testsuite_error(error_message)
+{
+ report("ERROR", "- " error_message)
+}
+
+function handle_tap_result()
+{
+ details = result_obj["number"];
+ if (length(result_obj["description"]))
+ details = details " " result_obj["description"]
+
+ if (plan_seen == LATE_PLAN)
+ {
+ details = details " # AFTER LATE PLAN";
+ }
+ else if (result_obj["is_unplanned"])
+ {
+ details = details " # UNPLANNED";
+ }
+ else if (result_obj["number"] != testno)
+ {
+ details = sprintf("%s # OUT-OF-ORDER (expecting %d)",
+ details, testno);
+ }
+ else if (result_obj["directive"])
+ {
+ details = details " # " result_obj["directive"];
+ if (length(result_obj["explanation"]))
+ details = details " " result_obj["explanation"]
+ }
+
+ report(stringify_result_obj(result_obj), details)
+}
+
+# `skip_reason` should be empty whenever planned > 0.
+function handle_tap_plan(planned, skip_reason)
+{
+ planned += 0 # Avoid getting confused if, say, `planned` is "00"
+ if (length(skip_reason) && planned > 0)
+ abort("in function handle_tap_plan()")
+ if (plan_seen)
+ {
+ # Error, only one plan per stream is acceptable.
+ testsuite_error("multiple test plans")
+ return;
+ }
+ planned_tests = planned
+ # The TAP plan can come before or after *all* the TAP results; we speak
+ # respectively of an "early" or a "late" plan. If we see the plan line
+ # after at least one TAP result has been seen, assume we have a late
+ # plan; in this case, any further test result seen after the plan will
+ # be flagged as an error.
+ plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN)
+ # If testno > 0, we have an error ("too many tests run") that will be
+ # automatically dealt with later, so do not worry about it here. If
+ # $plan_seen is true, we have an error due to a repeated plan, and that
+ # has already been dealt with above. Otherwise, we have a valid "plan
+ # with SKIP" specification, and should report it as a particular kind
+ # of SKIP result.
+ if (planned == 0 && testno == 0)
+ {
+ if (length(skip_reason))
+ skip_reason = "- " skip_reason;
+ report("SKIP", skip_reason);
+ }
+}
+
+function extract_tap_comment(line)
+{
+ if (index(line, diag_string) == 1)
+ {
+ # Strip leading `diag_string` from `line`.
+ line = substr(line, length(diag_string) + 1)
+ # And strip any leading and trailing whitespace left.
+ sub("^[ \t]*", "", line)
+ sub("[ \t]*$", "", line)
+ # Return what is left (if any).
+ return line;
+ }
+ return "";
+}
+
+# When this function is called, we know that line is a TAP result line,
+# so that it matches the (perl) RE "^(not )?ok\b".
+function setup_result_obj(line)
+{
+ # Get the result, and remove it from the line.
+ result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0)
+ sub("^(not )?ok[ \t]*", "", line)
+
+ # If the result has an explicit number, get it and strip it; otherwise,
+ # automatically assing the next progresive number to it.
+ if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/)
+ {
+ match(line, "^[0-9]+")
+ # The final `+ 0` is to normalize numbers with leading zeros.
+ result_obj["number"] = substr(line, 1, RLENGTH) + 0
+ line = substr(line, RLENGTH + 1)
+ }
+ else
+ {
+ result_obj["number"] = testno
+ }
+
+ if (plan_seen == LATE_PLAN)
+ # No further test results are acceptable after a "late" TAP plan
+ # has been seen.
+ result_obj["is_unplanned"] = 1
+ else if (plan_seen && testno > planned_tests)
+ result_obj["is_unplanned"] = 1
+ else
+ result_obj["is_unplanned"] = 0
+
+ # Strip trailing and leading whitespace.
+ sub("^[ \t]*", "", line)
+ sub("[ \t]*$", "", line)
+
+ # This will have to be corrected if we have a "TODO"/"SKIP" directive.
+ result_obj["description"] = line
+ result_obj["directive"] = ""
+ result_obj["explanation"] = ""
+
+ if (index(line, "#") == 0)
+ return # No possible directive, nothing more to do.
+
+ # Directives are case-insensitive.
+ rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*"
+
+ # See whether we have the directive, and if yes, where.
+ pos = match(line, rx "$")
+ if (!pos)
+ pos = match(line, rx "[^a-zA-Z0-9_]")
+
+ # If there was no TAP directive, we have nothing more to do.
+ if (!pos)
+ return
+
+ # Let`s now see if the TAP directive has been escaped. For example:
+ # escaped: ok \# SKIP
+ # not escaped: ok \\# SKIP
+ # escaped: ok \\\\\# SKIP
+ # not escaped: ok \ # SKIP
+ if (substr(line, pos, 1) == "#")
+ {
+ bslash_count = 0
+ for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--)
+ bslash_count += 1
+ if (bslash_count % 2)
+ return # Directive was escaped.
+ }
+
+ # Strip the directive and its explanation (if any) from the test
+ # description.
+ result_obj["description"] = substr(line, 1, pos - 1)
+ # Now remove the test description from the line, that has been dealt
+ # with already.
+ line = substr(line, pos)
+ # Strip the directive, and save its value (normalized to upper case).
+ sub("^[ \t]*#[ \t]*", "", line)
+ result_obj["directive"] = toupper(substr(line, 1, 4))
+ line = substr(line, 5)
+ # Now get the explanation for the directive (if any), with leading
+ # and trailing whitespace removed.
+ sub("^[ \t]*", "", line)
+ sub("[ \t]*$", "", line)
+ result_obj["explanation"] = line
+}
+
+function get_test_exit_message(status)
+{
+ if (status == 0)
+ return ""
+ if (status !~ /^[1-9][0-9]*$/)
+ abort("getting exit status")
+ if (status < 127)
+ exit_details = ""
+ else if (status == 127)
+ exit_details = " (command not found?)"
+ else if (status >= 128 && status <= 255)
+ exit_details = sprintf(" (terminated by signal %d?)", status - 128)
+ else if (status > 256 && status <= 384)
+ # We used to report an "abnormal termination" here, but some Korn
+ # shells, when a child process die due to signal number n, can leave
+ # in $? an exit status of 256+n instead of the more standard 128+n.
+ # Apparently, both behaviours are allowed by POSIX (2008), so be
+ # prepared to handle them both. See also Austing Group report ID
+ # 0000051 <http://www.austingroupbugs.net/view.php?id=51>
+ exit_details = sprintf(" (terminated by signal %d?)", status - 256)
+ else
+ # Never seen in practice.
+ exit_details = " (abnormal termination)"
+ return sprintf("exited with status %d%s", status, exit_details)
+}
+
+function write_test_results()
+{
+ print ":global-test-result: " get_global_test_result() > trs_file
+ print ":recheck: " yn(must_recheck()) > trs_file
+ print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file
+ for (i = 0; i < test_results_index; i += 1)
+ print ":test-result: " test_results_list[i] > trs_file
+ close(trs_file);
+}
+
+BEGIN {
+
+## ------- ##
+## SETUP ##
+## ------- ##
+
+'"$init_colors"'
+
+# Properly initialized once the TAP plan is seen.
+planned_tests = 0
+
+COOKED_PASS = expect_failure ? "XPASS": "PASS";
+COOKED_FAIL = expect_failure ? "XFAIL": "FAIL";
+
+# Enumeration-like constants to remember which kind of plan (if any)
+# has been seen. It is important that NO_PLAN evaluates "false" as
+# a boolean.
+NO_PLAN = 0
+EARLY_PLAN = 1
+LATE_PLAN = 2
+
+testno = 0 # Number of test results seen so far.
+bailed_out = 0 # Whether a "Bail out!" directive has been seen.
+
+# Whether the TAP plan has been seen or not, and if yes, which kind
+# it is ("early" is seen before any test result, "late" otherwise).
+plan_seen = NO_PLAN
+
+## --------- ##
+## PARSING ##
+## --------- ##
+
+is_first_read = 1
+
+while (1)
+ {
+ # Involutions required so that we are able to read the exit status
+ # from the last input line.
+ st = getline
+ if (st < 0) # I/O error.
+ fatal("I/O error while reading from input stream")
+ else if (st == 0) # End-of-input
+ {
+ if (is_first_read)
+ abort("in input loop: only one input line")
+ break
+ }
+ if (is_first_read)
+ {
+ is_first_read = 0
+ nextline = $0
+ continue
+ }
+ else
+ {
+ curline = nextline
+ nextline = $0
+ $0 = curline
+ }
+ # Copy any input line verbatim into the log file.
+ print | "cat >&3"
+ # Parsing of TAP input should stop after a "Bail out!" directive.
+ if (bailed_out)
+ continue
+
+ # TAP test result.
+ if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/)
+ {
+ testno += 1
+ setup_result_obj($0)
+ handle_tap_result()
+ }
+ # TAP plan (normal or "SKIP" without explanation).
+ else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/)
+ {
+ # The next two lines will put the number of planned tests in $0.
+ sub("^1\\.\\.", "")
+ sub("[^0-9]*$", "")
+ handle_tap_plan($0, "")
+ continue
+ }
+ # TAP "SKIP" plan, with an explanation.
+ else if ($0 ~ /^1\.\.0+[ \t]*#/)
+ {
+ # The next lines will put the skip explanation in $0, stripping
+ # any leading and trailing whitespace. This is a little more
+ # tricky in truth, since we want to also strip a potential leading
+ # "SKIP" string from the message.
+ sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "")
+ sub("[ \t]*$", "");
+ handle_tap_plan(0, $0)
+ }
+ # "Bail out!" magic.
+ # Older versions of prove and TAP::Harness (e.g., 3.17) did not
+ # recognize a "Bail out!" directive when preceded by leading
+ # whitespace, but more modern versions (e.g., 3.23) do. So we
+ # emulate the latter, "more modern" behaviour.
+ else if ($0 ~ /^[ \t]*Bail out!/)
+ {
+ bailed_out = 1
+ # Get the bailout message (if any), with leading and trailing
+ # whitespace stripped. The message remains stored in `$0`.
+ sub("^[ \t]*Bail out![ \t]*", "");
+ sub("[ \t]*$", "");
+ # Format the error message for the
+ bailout_message = "Bail out!"
+ if (length($0))
+ bailout_message = bailout_message " " $0
+ testsuite_error(bailout_message)
+ }
+ # Maybe we have too look for dianogtic comments too.
+ else if (comments != 0)
+ {
+ comment = extract_tap_comment($0);
+ if (length(comment))
+ report("#", comment);
+ }
+ }
+
+## -------- ##
+## FINISH ##
+## -------- ##
+
+# A "Bail out!" directive should cause us to ignore any following TAP
+# error, as well as a non-zero exit status from the TAP producer.
+if (!bailed_out)
+ {
+ if (!plan_seen)
+ {
+ testsuite_error("missing test plan")
+ }
+ else if (planned_tests != testno)
+ {
+ bad_amount = testno > planned_tests ? "many" : "few"
+ testsuite_error(sprintf("too %s tests run (expected %d, got %d)",
+ bad_amount, planned_tests, testno))
+ }
+ if (!ignore_exit)
+ {
+ # Fetch exit status from the last line.
+ exit_message = get_test_exit_message(nextline)
+ if (exit_message)
+ testsuite_error(exit_message)
+ }
+ }
+
+write_test_results()
+
+exit 0
+
+} # End of "BEGIN" block.
+'
+
+# TODO: document that we consume the file descriptor 3 :-(
+} 3>"$log_file"
+
+test $? -eq 0 || fatal "I/O or internal error"
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config/test-driver b/config/test-driver
new file mode 100755
index 0000000..8e575b0
--- /dev/null
+++ b/config/test-driver
@@ -0,0 +1,148 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2013-07-13.22; # UTC
+
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+#
+# 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, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+ echo "$0: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--]
+ TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file= # Where to save the output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "test-driver $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) enable_hard_errors=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ *) break;;
+ esac
+ shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file" = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+ usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+ usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+ # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+ red='' # Red.
+ grn='' # Green.
+ lgn='' # Light green.
+ blu='' # Blue.
+ mgn='' # Magenta.
+ std='' # No color.
+else
+ red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+ tweaked_estatus=1
+else
+ tweaked_estatus=$estatus
+fi
+
+case $tweaked_estatus:$expect_failure in
+ 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+ 0:*) col=$grn res=PASS recheck=no gcopy=no;;
+ 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
+ 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
+ *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
+ *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
+esac
+
+# Report the test outcome and exit status in the logs, so that one can
+# know whether the test passed or failed simply by looking at the '.log'
+# file, without the need of also peaking into the corresponding '.trs'
+# file (automake bug#11814).
+echo "$res $test_name (exit status: $estatus)" >>$log_file
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config/type-ghostscript.mgk.in b/config/type-ghostscript.mgk.in
new file mode 100644
index 0000000..cabb456
--- /dev/null
+++ b/config/type-ghostscript.mgk.in
@@ -0,0 +1,401 @@
+<?xml version="1.0"?>
+<typemap>
+ <type
+ name="AvantGarde-Book"
+ fullname="AvantGarde Book"
+ family="AvantGarde"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@a010013l.afm"
+ glyphs="@ghostscript_font_dir@a010013l.pfb"
+ />
+ <type
+ name="AvantGarde-BookOblique"
+ fullname="AvantGarde Book Oblique"
+ family="AvantGarde"
+ foundry="URW"
+ weight="400"
+ style="oblique"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@a010033l.afm"
+ glyphs="@ghostscript_font_dir@a010033l.pfb"
+ />
+ <type
+ name="AvantGarde-Demi"
+ fullname="AvantGarde DemiBold"
+ family="AvantGarde"
+ foundry="URW"
+ weight="600"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@a010015l.afm"
+ glyphs="@ghostscript_font_dir@a010015l.pfb"
+ />
+ <type
+ name="AvantGarde-DemiOblique"
+ fullname="AvantGarde DemiOblique"
+ family="AvantGarde"
+ foundry="URW"
+ weight="600"
+ style="oblique"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@a010035l.afm"
+ glyphs="@ghostscript_font_dir@a010035l.pfb"
+ />
+ <type
+ name="Bookman-Demi"
+ fullname="Bookman DemiBold"
+ family="Bookman"
+ foundry="URW"
+ weight="600"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@b018015l.afm"
+ glyphs="@ghostscript_font_dir@b018015l.pfb"
+ />
+ <type
+ name="Bookman-DemiItalic"
+ fullname="Bookman DemiBold Italic"
+ family="Bookman"
+ foundry="URW"
+ weight="600"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@b018035l.afm"
+ glyphs="@ghostscript_font_dir@b018035l.pfb"
+ />
+ <type
+ name="Bookman-Light"
+ fullname="Bookman Light"
+ family="Bookman"
+ foundry="URW"
+ weight="300"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@b018012l.afm"
+ glyphs="@ghostscript_font_dir@b018012l.pfb"
+ />
+ <type
+ name="Bookman-LightItalic"
+ fullname="Bookman Light Italic"
+ family="Bookman"
+ foundry="URW"
+ weight="300"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@b018032l.afm"
+ glyphs="@ghostscript_font_dir@b018032l.pfb"
+ />
+ <type
+ name="Courier"
+ fullname="Courier Regular"
+ family="Courier"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n022003l.afm"
+ glyphs="@ghostscript_font_dir@n022003l.pfb"
+ />
+ <type
+ name="Courier-Bold"
+ fullname="Courier Bold"
+ family="Courier"
+ foundry="URW"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n022004l.afm"
+ glyphs="@ghostscript_font_dir@n022004l.pfb"
+ />
+ <type
+ name="Courier-Oblique"
+ fullname="Courier Regular Oblique"
+ family="Courier"
+ foundry="URW"
+ weight="400"
+ style="oblique"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n022023l.afm"
+ glyphs="@ghostscript_font_dir@n022023l.pfb"
+ />
+ <type
+ name="Courier-BoldOblique"
+ fullname="Courier Bold Oblique"
+ family="Courier"
+ foundry="URW"
+ weight="700"
+ style="oblique"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n022024l.afm"
+ glyphs="@ghostscript_font_dir@n022024l.pfb"
+ />
+ <type
+ name="Helvetica"
+ fullname="Helvetica Regular"
+ family="Helvetica"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n019003l.afm"
+ glyphs="@ghostscript_font_dir@n019003l.pfb"
+ />
+ <type
+ name="Helvetica-Bold"
+ fullname="Helvetica Bold"
+ family="Helvetica"
+ foundry="URW"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n019004l.afm"
+ glyphs="@ghostscript_font_dir@n019004l.pfb"
+ />
+ <type
+ name="Helvetica-Oblique"
+ fullname="Helvetica Regular Italic"
+ family="Helvetica"
+ foundry="URW"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n019023l.afm"
+ glyphs="@ghostscript_font_dir@n019023l.pfb"
+ />
+ <type
+ name="Helvetica-BoldOblique"
+ fullname="Helvetica Bold Italic"
+ family="Helvetica"
+ foundry="URW"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n019024l.afm"
+ glyphs="@ghostscript_font_dir@n019024l.pfb"
+ />
+ <type
+ name="Helvetica-Narrow"
+ fullname="Helvetica Narrow"
+ family="Helvetica Narrow"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="condensed"
+ format="type1"
+ metrics="@ghostscript_font_dir@n019043l.afm"
+ glyphs="@ghostscript_font_dir@n019043l.pfb"
+ />
+ <type
+ name="Helvetica-Narrow-Oblique"
+ fullname="Helvetica Narrow Oblique"
+ family="Helvetica Narrow"
+ foundry="URW"
+ weight="400"
+ style="oblique"
+ stretch="condensed"
+ format="type1"
+ metrics="@ghostscript_font_dir@n019063l.afm"
+ glyphs="@ghostscript_font_dir@n019063l.pfb"
+ />
+ <type
+ name="Helvetica-Narrow-Bold"
+ fullname="Helvetica Narrow Bold"
+ family="Helvetica Narrow"
+ foundry="URW"
+ weight="700"
+ style="normal"
+ stretch="condensed"
+ format="type1"
+ metrics="@ghostscript_font_dir@n019044l.afm"
+ glyphs="@ghostscript_font_dir@n019044l.pfb"
+ />
+ <type
+ name="Helvetica-Narrow-BoldOblique"
+ fullname="Helvetica Narrow Bold Oblique"
+ family="Helvetica Narrow"
+ foundry="URW"
+ weight="700"
+ style="oblique"
+ stretch="condensed"
+ format="type1"
+ metrics="@ghostscript_font_dir@n019064l.afm"
+ glyphs="@ghostscript_font_dir@n019064l.pfb"
+ />
+ <type
+ name="NewCenturySchlbk-Roman"
+ fullname="New Century Schoolbook"
+ family="NewCenturySchlbk"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@c059013l.afm"
+ glyphs="@ghostscript_font_dir@c059013l.pfb"
+ />
+ <type
+ name="NewCenturySchlbk-Italic"
+ fullname="New Century Schoolbook Italic"
+ family="NewCenturySchlbk"
+ foundry="URW"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@c059033l.afm"
+ glyphs="@ghostscript_font_dir@c059033l.pfb"
+ />
+ <type
+ name="NewCenturySchlbk-Bold"
+ fullname="New Century Schoolbook Bold"
+ family="NewCenturySchlbk"
+ foundry="URW"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@c059016l.afm"
+ glyphs="@ghostscript_font_dir@c059016l.pfb"
+ />
+ <type
+ name="NewCenturySchlbk-BoldItalic"
+ fullname="New Century Schoolbook Bold Italic"
+ family="NewCenturySchlbk"
+ foundry="URW"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@c059036l.afm"
+ glyphs="@ghostscript_font_dir@c059036l.pfb"
+ />
+ <type
+ name="Palatino-Roman"
+ fullname="Palatino Regular"
+ family="Palatino"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@p052003l.afm"
+ glyphs="@ghostscript_font_dir@p052003l.pfb"
+ />
+ <type
+ name="Palatino-Italic"
+ fullname="Palatino Italic"
+ family="Palatino"
+ foundry="URW"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@p052023l.afm"
+ glyphs="@ghostscript_font_dir@p052023l.pfb"
+ />
+ <type
+ name="Palatino-Bold"
+ fullname="Palatino Bold"
+ family="Palatino"
+ foundry="URW"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@p052004l.afm"
+ glyphs="@ghostscript_font_dir@p052004l.pfb"
+ />
+ <type
+ name="Palatino-BoldItalic"
+ fullname="Palatino Bold Italic"
+ family="Palatino"
+ foundry="URW"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@p052024l.afm"
+ glyphs="@ghostscript_font_dir@p052024l.pfb"
+ />
+ <type
+ name="Times-Roman"
+ fullname="Times Regular"
+ family="Times"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n021003l.afm"
+ glyphs="@ghostscript_font_dir@n021003l.pfb"
+ />
+ <type
+ name="Times-Bold"
+ fullname="Times Medium"
+ family="Times"
+ foundry="URW"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n021004l.afm"
+ glyphs="@ghostscript_font_dir@n021004l.pfb"
+ />
+ <type
+ name="Times-Italic"
+ fullname="Times Regular Italic"
+ family="Times"
+ foundry="URW"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n021023l.afm"
+ glyphs="@ghostscript_font_dir@n021023l.pfb"
+ />
+ <type
+ name="Times-BoldItalic"
+ fullname="Times Medium Italic"
+ family="Times"
+ foundry="URW"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@n021024l.afm"
+ glyphs="@ghostscript_font_dir@n021024l.pfb"
+ />
+ <type
+ name="Symbol"
+ fullname="Symbol"
+ family="Symbol"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="@ghostscript_font_dir@s050000l.afm"
+ glyphs="@ghostscript_font_dir@s050000l.pfb"
+ version="0.1"
+ encoding="AdobeCustom"
+ />
+</typemap>
diff --git a/config/type-solaris.mgk.in b/config/type-solaris.mgk.in
new file mode 100644
index 0000000..9ad7aea
--- /dev/null
+++ b/config/type-solaris.mgk.in
@@ -0,0 +1,205 @@
+<?xml version="1.0"?>
+<typemap>
+ <type
+ name="Courier"
+ fullname="Courier Regular"
+ family="Courier"
+ foundry="Adobe"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Courier.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/cour.pfa"
+ />
+ <type
+ name="Courier-Bold"
+ fullname="Courier Bold"
+ family="Courier"
+ foundry="Adobe"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Courier-Bold.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/courb.pfa"
+ />
+ <type
+ name="Courier-Oblique"
+ fullname="Courier Regular Oblique"
+ family="Courier"
+ foundry="Adobe"
+ weight="400"
+ style="oblique"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Courier-Oblique.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/couri.pfa"
+ />
+ <type
+ name="Courier-BoldOblique"
+ fullname="Courier Bold Oblique"
+ family="Courier"
+ foundry="Adobe"
+ weight="700"
+ style="oblique"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Courier-BoldOblique.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/courbi.pfa"
+ />
+ <type
+ name="Helvetica"
+ fullname="Helvetica Regular"
+ family="Helvetica"
+ foundry="Linotype"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Helvetica.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Helvetica.pfa"
+ />
+ <type
+ name="Helvetica-Bold"
+ fullname="Helvetica Bold"
+ family="Helvetica"
+ foundry="Linotype"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Helvetica-Bold.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Helvetica-Bold.pfa"
+ />
+ <type
+ name="Helvetica-Oblique"
+ fullname="Helvetica Regular Italic"
+ family="Helvetica"
+ foundry="Linotype"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Helvetica-Oblique.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Helvetica-Oblique.pfa"
+ />
+ <type
+ name="Helvetica-BoldOblique"
+ fullname="Helvetica Bold Italic"
+ family="Helvetica"
+ foundry="Linotype"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Helvetica-BoldOblique.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Helvetica-BoldOblique.pfa"
+ />
+ <type
+ name="Times-Roman"
+ fullname="Times Regular"
+ family="Times"
+ foundry="Linotype"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Times-Roman.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Times-Roman.pfa"
+ />
+ <type
+ name="Times-Bold"
+ fullname="Times Medium"
+ family="Times"
+ foundry="Linotype"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Times-Bold.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Times-Bold.pfa"
+ />
+ <type
+ name="Times-Italic"
+ fullname="Times Regular Italic"
+ family="Times"
+ foundry="Linotype"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Times-Italic.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Times-Italic.pfa"
+ />
+ <type
+ name="Times-BoldItalic"
+ fullname="Times Medium Italic"
+ family="Times"
+ foundry="Linotype"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/afm/Times-BoldItalic.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Times-BoldItalic.pfa"
+ />
+ <type
+ name="Symbol"
+ fullname="Symbol"
+ family="Symbol"
+ foundry="Adobe"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/openwin/lib/X11/fonts/Type1/Symbol.afm"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/Symbol.pfa"
+ version="0.1"
+ encoding="AdobeCustom"
+ />
+ <type
+ name="Utopia-Regular"
+ fullname="Utopia Regular"
+ family="Utopia"
+ foundry="Adobe"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/UTRG____.pfa"
+ />
+ <type
+ name="Utopia-Italic"
+ fullname="Utopia Italic"
+ family="Utopia"
+ foundry="Adobe"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/UTI_____.pfa"
+ />
+ <type
+ name="Utopia-Bold"
+ fullname="Utopia Bold"
+ family="Utopia"
+ foundry="Adobe"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/UTB_____.pfa"
+ />
+ <type
+ name="Utopia-BoldItalic"
+ fullname="Utopia Bold Italic"
+ family="Utopia"
+ foundry="Adobe"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ format="type1"
+ glyphs="/usr/openwin/lib/X11/fonts/Type1/UTBI____.pfa"
+ />
+</typemap>
diff --git a/config/type-windows.mgk.in b/config/type-windows.mgk.in
new file mode 100644
index 0000000..b5f0106
--- /dev/null
+++ b/config/type-windows.mgk.in
@@ -0,0 +1,745 @@
+<?xml version="1.0"?>
+<typemap>
+ <type
+ name="Arial"
+ fullname="Arial"
+ family="Arial"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@arial.ttf"
+ />
+ <type
+ name="Arial-Black"
+ fullname="Arial Black"
+ family="Arial"
+ weight="900"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@ariblk.ttf"
+ />
+ <type
+ name="Arial-Bold"
+ fullname="Arial Bold"
+ family="Arial"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@arialbd.ttf"
+ />
+ <type
+ name="Arial-Bold-Italic"
+ fullname="Arial Bold Italic"
+ family="Arial"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@arialbi.ttf"
+ />
+ <type
+ name="Arial-Italic"
+ fullname="Arial Italic"
+ family="Arial"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@ariali.ttf"
+ />
+ <type
+ name="Arial-Narrow"
+ fullname="Arial Narrow"
+ family="Arial Narrow"
+ weight="400"
+ style="normal"
+ stretch="condensed"
+ glyphs="@windows_font_dir@arialn.ttf"
+ />
+ <type
+ name="Arial-Narrow-Bold"
+ fullname="Arial Narrow Bold"
+ family="Arial Narrow"
+ weight="700"
+ style="normal"
+ stretch="condensed"
+ glyphs="@windows_font_dir@arialnb.ttf"
+ />
+ <type
+ name="Arial-Narrow-Bold-Italic"
+ fullname="Arial Narrow Bold Italic"
+ family="Arial Narrow"
+ weight="700"
+ style="italic"
+ stretch="condensed"
+ glyphs="@windows_font_dir@arialnbi.ttf"
+ />
+ <type
+ name="Arial-Narrow-Italic"
+ fullname="Arial Narrow Italic"
+ family="Arial Narrow"
+ weight="400"
+ style="italic"
+ stretch="condensed"
+ glyphs="@windows_font_dir@arnari.ttf"
+ />
+ <type
+ name="Arial-Narrow-Special-G1"
+ fullname="Arial Narrow Special G1"
+ family="Arial Narrow Special G1"
+ weight="400"
+ style="normal"
+ stretch="condensed"
+ glyphs="@windows_font_dir@msgeonr1.ttf"
+ />
+ <type
+ name="Arial-Narrow-Special-G1-Bold"
+ fullname="Arial Narrow Special G1 Bold"
+ family="Arial Narrow Special G1"
+ weight="700"
+ style="normal"
+ stretch="condensed"
+ glyphs="@windows_font_dir@msgeonb1.ttf"
+ />
+ <type
+ name="Arial-Narrow-Special-G1-Italic"
+ fullname="Arial Narrow Special G1 Italic"
+ family="Arial Narrow Special G1"
+ weight="400"
+ style="italic"
+ stretch="condensed"
+ glyphs="@windows_font_dir@msgeoni1.ttf"
+ />
+ <type
+ name="Arial-Narrow-Special-G2"
+ fullname="Arial Narrow Special G2"
+ family="Arial Narrow Special G2"
+ weight="400"
+ style="normal"
+ stretch="condensed"
+ glyphs="@windows_font_dir@msgeonr2.ttf"
+ />
+ <type
+ name="Arial-Narrow-Special-G2-Bold"
+ fullname="Arial Narrow Special G2 Bold"
+ family="Arial Narrow Special G2"
+ weight="700"
+ style="Narrow"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeonb2.ttf"
+ />
+ <type
+ name="Arial-Narrow-Special-G2-Italic"
+ fullname="Arial Narrow Special G2 Italic"
+ family="Arial Narrow Special G2"
+ weight="400"
+ style="italic"
+ stretch="condensed"
+ glyphs="@windows_font_dir@msgeoni2.ttf"
+ />
+ <type
+ name="Arial-Rounded-MT-Bold"
+ fullname="Arial Rounded MT Bold"
+ family="Arial Rounded MT"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@arlrdbd.ttf"
+ />
+ <type
+ name="Arial-Special-G1"
+ fullname="Arial Special G1"
+ family="Arial Special G1"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeor1.ttf"
+ />
+ <type
+ name="Arial-Special-G1-Bold"
+ fullname="Arial Special G1 Bold"
+ family="Arial Special G1"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeoab1.ttf"
+ />
+ <type
+ name="Arial-Special-G1-Bold-Italic"
+ fullname="Arial Special G1 Bold Italic"
+ family="Arial Special G1"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeoax1.ttf"
+ />
+ <type
+ name="Arial-Special-G1-Italic"
+ fullname="Arial Special G1 Italic"
+ family="Arial Special G1"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeoai1.ttf"
+ />
+ <type
+ name="Arial-Special-G2"
+ fullname="Arial Special G2"
+ family="Arial Special G2"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeoar2.ttf"
+ />
+ <type
+ name="Arial-Special-G2-Bold"
+ fullname="Arial Special G2 Bold"
+ family="Arial Special G2"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeoab2.ttf"
+ />
+ <type
+ name="Arial-Special-G2-Bold-Italic"
+ fullname="Arial Special G2 Bold Italic"
+ family="Arial Special G2"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeoax2.ttf"
+ />
+ <type
+ name="Arial-Special-G2-Italic"
+ fullname="Arial Special G2 Italic"
+ family="Arial Special G2"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@msgeoai2.ttf"
+ />
+ <type
+ name="Bookman-Old-Style"
+ fullname="Bookman Old Style"
+ family="Bookman Old Style"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@bkmnos.ttf"
+ />
+ <type
+ name="Bookman-Old-Style-Bold"
+ fullname="Bookman Old Style Bold"
+ family="Bookman Old Style"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@bookosb.ttf"
+ />
+ <type
+ name="Bookman-Old-Style-Bold-Italic"
+ fullname="Bookman Old Style Bold Italic"
+ family="Bookman Old Style"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@bookosbi.ttf"
+ />
+ <type
+ name="Bookman-Old-Style-Italic"
+ fullname="Bookman Old Style Italic"
+ family="Bookman Old Style"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@boookosi.ttf"
+ />
+ <type
+ name="Century-Schoolbook"
+ fullname="Century Schoolbook"
+ family="Century Schoolbook"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@censcbk.ttf"
+ />
+ <type
+ name="Century-Schoolbook-Bold"
+ fullname="Century Schoolbook Bold"
+ family="Century Schoolbook"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@schlbkb.ttf"
+ />
+ <type
+ name="Century-Schoolbook-Bold-Italic"
+ fullname="Century Schoolbook Bold Italic"
+ family="Century Schoolbook"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@schlbkbi.ttf"
+ />
+ <type
+ name="Century-Schoolbook-Italic"
+ fullname="Century Schoolbook Italic"
+ family="Century Schoolbook"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@schlbki.ttf"
+ />
+ <type
+ name="Comic-Sans-MS"
+ fullname="Comic Sans MS"
+ family="Comic Sans MS"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@comic.ttf"
+ />
+ <type
+ name="Comic-Sans-MS-Bold"
+ fullname="Comic Sans MS Bold"
+ family="Comic Sans MS"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@comicbd.ttf"
+ />
+ <type
+ name="Courier-New"
+ fullname="Courier New"
+ family="Courier New"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@cour.ttf"
+ />
+ <type
+ name="Courier-New-Bold"
+ fullname="Courier New Bold"
+ family="Courier New"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@courbd.ttf"
+ />
+ <type
+ name="Courier-New-Bold-Italic"
+ fullname="Courier New Bold Italic"
+ family="Courier New"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@courbi.ttf"
+ />
+ <type
+ name="Courier-New-Italic"
+ fullname="Courier New Italic"
+ family="Courier New"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@couri.ttf"
+ />
+ <type
+ name="Garamond"
+ fullname="Garamond"
+ family="Garamond"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@gara.ttf"
+ />
+ <type
+ name="Garamond-Bold"
+ fullname="Garamond Bold"
+ family="Garamond"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@garabd.ttf"
+ />
+ <type
+ name="Garamond-Italic"
+ fullname="Garamond Italic"
+ family="Garamond"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@Italic"
+ />
+ <type
+ name="Gill-Sans-MT-Ext-Condensed-Bold"
+ fullname="Gill Sans MT Ext Condensed Bold"
+ family="Gill Sans MT"
+ weight="700"
+ style="normal"
+ stretch="extra-condensed"
+ glyphs="@windows_font_dir@glsnecb.ttf"
+ />
+ <type
+ name="Impact"
+ fullname="Impact"
+ family="Impact"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@impact.ttf"
+ />
+ <type
+ name="Lucida-Blackletter"
+ fullname="Lucida Blackletter"
+ family="Lucida Blackletter"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@lblack.ttf"
+ />
+ <type
+ name="Lucida-Bright"
+ fullname="Lucida Bright"
+ family="Lucida Bright"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@lbrite.ttf"
+ />
+ <type
+ name="Lucida-Bright-Demibold"
+ fullname="Lucida Bright Demibold"
+ family="Lucida Bright"
+ weight="600"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@lbrited.ttf"
+ />
+ <type
+ name="Lucida-Bright-Demibold-Italic"
+ fullname="Lucida Bright Demibold Italic"
+ family="Lucida Bright"
+ weight="600"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@lbritedi.ttf"
+ />
+ <type
+ name="Lucida-Bright-Italic"
+ fullname="Lucida Bright Italic"
+ family="Lucida Bright"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@lbritei.ttf"
+ />
+ <type
+ name="Lucida-Caligraphy-Italic"
+ fullname="Lucida Caligraphy Italic"
+ family="Lucida Caligraphy"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@lcalig.ttf"
+ />
+ <type
+ name="Lucida-Console, Lucida-Console"
+ fullname="Lucida Console, Lucida Console"
+ family="Regular"
+ weight="400"
+ style="lucon.ttf"
+ stretch="normal"
+ glyphs="@windows_font_dir@"
+ />
+ <type
+ name="Lucida-Fax-Demibold"
+ fullname="Lucida Fax Demibold"
+ family="Lucida Fax"
+ weight="600"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@lfaxd.ttf"
+ />
+ <type
+ name="Lucida-Fax-Demibold-Italic"
+ fullname="Lucida Fax Demibold Italic"
+ family="Lucida Fax"
+ weight="600"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@lfaxdi.ttf"
+ />
+ <type
+ name="Lucida-Fax-Italic"
+ fullname="Lucida Fax Italic"
+ family="Lucida Fax"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@lfaxi.ttf"
+ />
+ <type
+ name="Lucida-Fax-Regular"
+ fullname="Lucida Fax Regular"
+ family="Lucida Fax"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@lfax.ttf"
+ />
+ <type
+ name="Lucida-Handwriting-Italic"
+ fullname="Lucida Handwriting Italic"
+ family="Lucida Handwriting"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@lhandw.ttf"
+ />
+ <type
+ name="Lucida-Sans-Demibold-Italic"
+ fullname="Lucida Sans Demibold Italic"
+ family="Lucida Sans"
+ weight="600"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@lsansdi.ttf"
+ />
+ <type
+ name="Lucida-Sans-Demibold-Roman"
+ fullname="Lucida Sans Demibold Roman"
+ family="Lucida Sans Demibold"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@lsansd.ttf"
+ />
+ <type
+ name="Lucida-Sans-Regular"
+ fullname="Lucida Sans Regular"
+ family="Lucida Sans"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@lsans.ttf"
+ />
+ <type
+ name="Lucida-Sans-Typewriter-Bold"
+ fullname="Lucida Sans Typewriter Bold"
+ family="Lucida Sans Typewriter"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@ltypeb.ttf"
+ />
+ <type
+ name="Lucida-Sans-Typewriter-Bold-Oblique"
+ fullname="Lucida Sans Typewriter Bold Oblique"
+ family="Lucida Sans Typewriter"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@ltypebo.ttf"
+ />
+ <type
+ name="Lucida-Sans-Typewriter-Oblique"
+ fullname="Lucida Sans Typewriter Oblique"
+ family="Lucida Sans Typewriter"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@ltypeo.ttf"
+ />
+ <type
+ name="Lucida-Sans-Typewriter-Regular"
+ fullname="Lucida Sans Typewriter Regular"
+ family="Lucida Sans Typewriter"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@ltype.ttf"
+ />
+ <type
+ name="MS-Sans-Serif"
+ fullname="MS Sans Serif"
+ family="MS Sans Serif"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@sseriff.ttf"
+ />
+ <type
+ name="MS-Serif"
+ fullname="MS Serif"
+ family="MS Serif"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@seriff.ttf"
+ />
+ <type
+ name="Modern"
+ fullname="Modern"
+ family="Modern"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@modern.ttf"
+ />
+ <type
+ name="Monotype-Corsiva"
+ fullname="Monotype Corsiva"
+ family="Monotype Corsiva"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@mtcorsva.ttf"
+ />
+ <type
+ name="Small-Fonts"
+ fullname="Small Fonts"
+ family="Small Fonts"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@smallf.ttf"
+ />
+ <type
+ name="Symbol"
+ fullname="Symbol"
+ family="Symbol"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@symbol.ttf"
+ encoding="AppleRoman"
+ />
+ <type
+ name="Tahoma"
+ fullname="Tahoma"
+ family="Tahoma"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@tahoma.ttf"
+ />
+ <type
+ name="Tahoma-Bold"
+ fullname="Tahoma Bold"
+ family="Tahoma"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@tahomabd.ttf"
+ />
+ <type
+ name="Times-New-Roman"
+ fullname="Times New Roman"
+ family="Times New Roman"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@times.ttf"
+ />
+ <type
+ name="Times-New-Roman-Bold"
+ fullname="Times New Roman Bold"
+ family="Times New Roman"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@timesbd.ttf"
+ />
+ <type
+ name="Times-New-Roman-Bold-Italic"
+ fullname="Times New Roman Bold Italic"
+ family="Times New Roman"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@timesbi.ttf"
+ />
+ <type
+ name="Times-New-Roman-Italic"
+ fullname="Times New Roman Italic"
+ family="Times New Roman"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@timesi.ttf"
+ />
+ <type
+ name="Times-New-Roman-MT-Extra-Bold"
+ fullname="Times New Roman MT Extra Bold"
+ family="Times New Roman MT"
+ weight="800"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@timnreb.ttf"
+ />
+ <type
+ name="Verdana"
+ fullname="Verdana"
+ family="Verdana"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@verdana.ttf"
+ />
+ <type
+ name="Verdana-Bold"
+ fullname="Verdana Bold"
+ family="Verdana"
+ weight="700"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@verdanab.ttf"
+ />
+ <type
+ name="Verdana-Bold-Italic"
+ fullname="Verdana Bold Italic"
+ family="Verdana"
+ weight="700"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@verdanaz.ttf"
+ />
+ <type
+ name="Verdana-Italic"
+ fullname="Verdana Italic"
+ family="Verdana"
+ weight="400"
+ style="italic"
+ stretch="normal"
+ glyphs="@windows_font_dir@verdanai.ttf"
+ />
+ <type
+ name="Wingdings"
+ fullname="Wingdings"
+ family="Wingdings"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@wingding.ttf"
+ encoding="AppleRoman"
+ />
+ <type
+ name="Wingdings-2"
+ fullname="Wingdings 2"
+ family="Wingdings 2"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@wingdng2.ttf"
+ encoding="AppleRoman"
+ />
+ <type
+ name="Wingdings-3"
+ fullname="Wingdings 3"
+ family="Wingdings 3"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ glyphs="@windows_font_dir@wingdng3.ttf"
+ encoding="AppleRoman"
+ />
+</typemap>
diff --git a/config/type.mgk.in b/config/type.mgk.in
new file mode 100644
index 0000000..b6fe82b
--- /dev/null
+++ b/config/type.mgk.in
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<typemap>
+ @type_include_files@
+</typemap>
diff --git a/configure b/configure
new file mode 100755
index 0000000..effa4f1
--- /dev/null
+++ b/configure
@@ -0,0 +1,32656 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="magick/magick.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+MAGICK_API_LIBS
+MAGICK_API_LDFLAGS
+MAGICK_API_PC_CPPFLAGS
+MAGICK_API_CPPFLAGS
+MAGICK_API_CFLAGS
+MAGICK_DEP_LIBS
+MAGICK_FEATURES
+DELEGATES
+MAGICKLIBDIR
+MAGICKLIB
+PERL_SUPPORTS_DESTDIR
+WITH_PERL_DYNAMIC_FALSE
+WITH_PERL_DYNAMIC_TRUE
+WITH_PERL_STATIC_FALSE
+WITH_PERL_STATIC_TRUE
+WITH_PERL_FALSE
+WITH_PERL_TRUE
+PERL
+GSVersion
+GSEPSDevice
+GSPSDevice
+GSPDFDevice
+GSColorAlphaDevice
+GSColorDevice
+GSPaletteDevice
+GSGrayDevice
+GSCMYKDevice
+GSMonoDevice
+HAS_ZIP_FALSE
+HAS_ZIP_TRUE
+ZIP
+HAS_P7ZIP_FALSE
+HAS_P7ZIP_TRUE
+P7ZIP
+HAS_RPM_FALSE
+HAS_RPM_TRUE
+RPM
+ShowImageDelegate
+MogrifyDelegate
+ConvertDelegate
+type_include_files
+ghostscript_font_dir
+windows_font_dir
+HasTXT2HTML_FALSE
+HasTXT2HTML_TRUE
+TXT2HTML
+HasRST2HTML_FALSE
+HasRST2HTML_TRUE
+RST2HTML
+HasPSDelegate_FALSE
+HasPSDelegate_TRUE
+PrintDelegate
+PSDelegate
+MVDelegate
+MPEGEncodeDelegate
+MPEGDecodeDelegate
+LaunchDelegate
+LPRDelegate
+LPDelegate
+ILBMEncodeDelegate
+ILBMDecodeDelegate
+HTMLDecodeDelegate
+HPGLDecodeDelegate
+GMDelegate
+FIGDecodeDelegate
+EditorDelegate
+DVIDecodeDelegate
+DOTDecodeDelegate
+DCRAWDecodeDelegate
+CGMDecodeDelegate
+BrowseDelegate
+MagickShareConfigPath
+MagickSharePath
+MagickFilterModulesPath
+MagickCoderModulesPath
+MagickLibConfigPath
+MagickLibPath
+MagickBinPath
+PERLMAINCC
+LIB_WMF_DEPS
+LIB_WMF
+HasWMF_FALSE
+HasWMF_TRUE
+LIB_XML_DEPS
+LIB_XML
+HasXML_FALSE
+HasXML_TRUE
+xml2_config
+LIB_WEBP
+HasWEBP_FALSE
+HasWEBP_TRUE
+LIB_JBIG
+HasJBIG_FALSE
+HasJBIG_TRUE
+LIB_TIFF
+HasTIFF_FALSE
+HasTIFF_TRUE
+LIB_TTF
+HasTTF_FALSE
+HasTTF_TRUE
+freetype_config
+LIB_GS
+HasGS_FALSE
+HasGS_TRUE
+LIB_JP2
+HasJP2_FALSE
+HasJP2_TRUE
+LIB_JPEG
+HasJPEG_FALSE
+HasJPEG_TRUE
+LIB_PNG
+HasPNG_FALSE
+HasPNG_TRUE
+LIB_LCMS
+HasLCMS_FALSE
+HasLCMS_TRUE
+LIB_FPX
+HasFPX_FALSE
+HasFPX_TRUE
+LIB_DPS
+HasDPS_FALSE
+HasDPS_TRUE
+LIB_DL
+LIB_XEXT
+LIB_X11
+HasX11_FALSE
+HasX11_TRUE
+X_EXTRA_LIBS
+X_LIBS
+X_PRE_LIBS
+X_CFLAGS
+XMKMF
+LIB_LZMA
+HasLZMA_FALSE
+HasLZMA_TRUE
+LIB_BZLIB
+HasBZLIB_FALSE
+HasBZLIB_TRUE
+LIB_ZLIB
+HasZLIB_FALSE
+HasZLIB_TRUE
+WITH_LTDL_FALSE
+WITH_LTDL_TRUE
+LIB_TRIO
+LIB_MATH
+LIB_OMP
+LIB_UMEM
+HasUMEM_FALSE
+HasUMEM_TRUE
+LIB_THREAD
+WITH_MAGICK_PLUS_PLUS_FALSE
+WITH_MAGICK_PLUS_PLUS_TRUE
+SysCtlDelegate
+MAGICK_SSIZE_T_F
+MAGICK_SSIZE_T
+MAGICK_SIZE_T_F
+MAGICK_SIZE_T
+UINTPTR_F
+UINTPTR_T
+UINTMAX_F
+UINTMAX_T
+UINT64_F
+UINT64_T
+INT64_F
+INT64_T
+UINT32_F
+UINT32_T
+INT32_F
+INT32_T
+UINT16_T
+INT16_T
+UINT8_T
+INT8_T
+LIBRARY_EXTRA_CPPFLAGS
+MODULE_EXTRA_CPPFLAGS
+LIBSTDCLDFLAGS
+PERL_MAKE_OPTIONS
+MAGICK_LT_RELEASE_OPTS
+QuantumDepth
+MAGICK_COMPAT_FALSE
+MAGICK_COMPAT_TRUE
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+ENABLE_BROKEN_CODERS_FALSE
+ENABLE_BROKEN_CODERS_TRUE
+WITH_MODULES_FALSE
+WITH_MODULES_TRUE
+WITH_SHARED_LIBS_FALSE
+WITH_SHARED_LIBS_TRUE
+LIBTOOL_DEPS
+CXXCPP
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+LT_SYS_LIBRARY_PATH
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LIBTOOL
+OBJDUMP
+DLLTOOL
+AS
+LFS_CPPFLAGS
+OPENMP_CFLAGS
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CXX
+PTHREAD_CC
+acx_pthread_config
+CYGWIN_BUILD_FALSE
+CYGWIN_BUILD_TRUE
+WIN32_NATIVE_BUILD_FALSE
+WIN32_NATIVE_BUILD_TRUE
+HasWINGDI32_FALSE
+HasWINGDI32_TRUE
+LIB_GDI32
+LN_S
+LD
+FGREP
+SED
+DIRSEP
+MAGICK_FILTER_MODULE_PATH
+MAGICK_CONFIGURE_BUILD_PATH
+MAGICK_CONFIGURE_SRC_PATH
+MAGICK_CODER_MODULE_PATH
+WinPathScript
+MAN_DIR
+INFO_DIR
+OLDINCLUDE_DIR
+INCLUDE_DIR
+LIB_DIR
+LOCALSTATE_DIR
+SHAREDSTATE_DIR
+SYSCONF_DIR
+HTML_DIR
+DOC_DIR
+DATA_DIR
+LIBEXEC_DIR
+SBIN_DIR
+BIN_DIR
+EXEC_PREFIX_DIR
+PREFIX_DIR
+EGREP
+GREP
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+CONFIG_STATUS_DEPENDENCIES
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+MAGICK_LIB_VERSION_NUMBER
+MAGICK_LIB_VERSION_TEXT
+MAGICK_LIB_VERSION
+HG_BRANCH_TAG
+PACKAGE_RELEASE_DATE
+PACKAGE_CHANGE_DATE
+PACKAGE_VERSION_ADDENDUM
+MAGICK_WAND_LIBRARY_AGE
+MAGICK_WAND_LIBRARY_REVISION
+MAGICK_WAND_LIBRARY_CURRENT
+MAGICK_PLUS_PLUS_LIBRARY_AGE
+MAGICK_PLUS_PLUS_LIBRARY_REVISION
+MAGICK_PLUS_PLUS_LIBRARY_CURRENT
+MAGICK_LIB_INTERFACE_OLDEST
+MAGICK_LIB_INTERFACE_NEWEST
+MAGICK_LIBRARY_AGE
+MAGICK_LIBRARY_REVISION
+MAGICK_LIBRARY_CURRENT
+MAGICK_TARGET_OS
+MAGICK_TARGET_VENDOR
+MAGICK_TARGET_CPU
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+DISTCHECK_CONFIG_FLAGS
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_dependency_tracking
+with_gnu_ld
+with_threads
+enable_openmp
+enable_openmp_slow
+enable_largefile
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_aix_soname
+with_sysroot
+enable_libtool_lock
+with_modules
+enable_installed
+enable_broken_coders
+enable_maintainer_mode
+enable_prof
+enable_gprof
+enable_gcov
+enable_symbol_prefix
+enable_magick_compat
+with_quantum_depth
+enable_quantum_library_names
+with_frozenpaths
+with_magick_plus_plus
+with_perl
+with_perl_options
+with_bzlib
+with_dps
+with_fpx
+with_gslib
+with_jbig
+with_webp
+with_jpeg
+with_jp2
+with_lcms2
+with_lzma
+with_png
+with_tiff
+with_trio
+with_ttf
+with_umem
+with_wmf
+with_fontpath
+with_gs_font_dir
+with_windows_font_dir
+with_xml
+with_zlib
+with_libstdc
+with_x
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+LT_SYS_LIBRARY_PATH
+CXX
+CXXFLAGS
+CCC
+CXXCPP
+XMKMF'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+X features:
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --disable-openmp do not use OpenMP
+ --enable-openmp-slow enable OpenMP for algorithms which sometimes run
+ slower
+ --disable-largefile omit support for large files
+ --enable-shared[=PKGS] build shared libraries [default=no]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --disable-installed disable building an installed GraphicsMagick
+ --enable-broken-coders enable broken/dangerous file formats support
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
+ --enable-prof enable 'prof' profiling support
+ --enable-gprof enable 'gprof' profiling support
+ --enable-gcov enable 'gcov' profiling support
+ --enable-symbol-prefix enable prefixing library symbols with "Gm"
+ --enable-magick-compat install ImageMagick utility shortcuts
+ --enable-quantum-library-names
+ shared library name includes quantum depth to allow
+ shared libraries with different quantum depths to
+ co-exist in same directory (only one can be used for
+ development)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --without-threads disable POSIX threads API support
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-aix-soname=aix|svr4|both
+ shared library versioning (aka "SONAME") variant to
+ provide on AIX, [default=aix].
+ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the
+ compiler's sysroot if not specified).
+ --with-modules enable building dynamically loadable modules
+ --with-quantum-depth number of bits in a pixel quantum (default 8)
+ --with-frozenpaths enable frozen delegate paths
+ --without-magick-plus-plus
+ disable build/install of Magick++
+ --with-perl[=PERL] enable build/install of PerlMagick and optionally
+ specify perl to use
+ --with-perl-options=OPTIONS
+ options to pass on command-line when generating
+ PerlMagick's Makefile from Makefile.PL
+ --without-bzlib disable BZLIB support
+ --without-dps disable Display Postscript support
+ --with-fpx enable FlashPIX support
+ --with-gslib enable Ghostscript library support (not recommended)
+ --without-jbig disable JBIG support
+ --without-webp disable WEBP support
+ --without-jpeg disable JPEG support
+ --without-jp2 disable JPEG v2 support
+ --without-lcms2 disable lcms (v2.X) support
+ --without-lzma disable LZMA support
+ --without-png disable PNG support
+ --without-tiff disable TIFF support
+ --without-trio disable TRIO support
+ --without-ttf disable TrueType support
+ --with-umem enable umem memory allocation library support
+ --without-wmf disable WMF support
+ --with-fontpath=DIR prepend to default font search path
+ --with-gs-font-dir=DIR directory containing Ghostscript fonts
+ --with-windows-font-dir=DIR
+ directory containing MS-Windows fonts
+ --without-xml disable XML support
+ --without-zlib disable ZLIB support
+ --with-libstdc=DIR use libstdc++ in DIR (for GNU C++)
+ --with-x use the X Window System
+ --without-png disable PNG support
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ LT_SYS_LIBRARY_PATH
+ User-defined run-time library search path.
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ CXXCPP C++ preprocessor
+ XMKMF Path to xmkmf, Makefile generator for X Window System
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ as_decl_name=`echo $2|sed 's/ *(.*//'`
+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+ (void) $as_decl_use;
+#else
+ (void) $as_decl_name;
+#endif
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
+
+# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_cxx_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Specify directory where m4 macros may be found.
+
+
+# Directory where autotools helper scripts lives.
+ac_aux_dir=
+for ac_dir in config "$srcdir"/config; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+# Include the TAP driver
+
+
+#
+# Save initial user-tunable values
+#
+LIBS_USER=$LIBS
+for var in CC CFLAGS CPPFLAGS CXX CXXCPP LDFLAGS LIBS ; do
+ eval isset=\${$var+set}
+ if test "$isset" = 'set' ; then
+ eval val=$`echo $var`
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS}'${var}=${val}' "
+ fi
+done
+
+
+# Source file containing package/library versioning information.
+. ${srcdir}/version.sh
+
+echo "configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}"
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+MAGICK_TARGET_CPU=$host_cpu
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAGICK_TARGET_CPU $MAGICK_TARGET_CPU
+_ACEOF
+
+
+MAGICK_TARGET_VENDOR=$host_vendor
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAGICK_TARGET_VENDOR $MAGICK_TARGET_VENDOR
+_ACEOF
+
+
+MAGICK_TARGET_OS=$host_os
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAGICK_TARGET_OS $MAGICK_TARGET_OS
+_ACEOF
+
+
+# Compute newest and oldest interface numbers.
+MAGICK_LIB_INTERFACE_NEWEST=$MAGICK_LIBRARY_CURRENT
+MAGICK_LIB_INTERFACE_OLDEST=`expr ${MAGICK_LIBRARY_CURRENT} - ${MAGICK_LIBRARY_AGE}`
+
+# Substitute Magick library versioning
+
+
+
+
+# Substitute Magick++ library versioning
+
+
+
+
+# Substitute Magick Wand library versioning
+
+
+
+
+
+# Substitute Mercurial branch tag
+
+# Definition used to define MagickLibVersion in version.h
+MAGICK_LIB_VERSION="0x"
+if test ${MAGICK_LIBRARY_CURRENT} -lt 10 ; then
+ MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}0
+fi
+MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}${MAGICK_LIBRARY_CURRENT}
+if test ${MAGICK_LIBRARY_AGE} -lt 10 ; then
+ MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}0
+fi
+MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}${MAGICK_LIBRARY_AGE}
+if test ${MAGICK_LIBRARY_REVISION} -lt 10 ; then
+ MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}0
+fi
+MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}${MAGICK_LIBRARY_REVISION}
+
+
+# Definition used to define MagickLibVersionText in version.h
+MAGICK_LIB_VERSION_TEXT="${PACKAGE_VERSION}"
+
+
+# Definition used to define MagickLibVersionNumber in version.h
+MAGICK_LIB_VERSION_NUMBER="${MAGICK_LIBRARY_CURRENT},${MAGICK_LIBRARY_AGE},${MAGICK_LIBRARY_REVISION}"
+
+
+# Ensure that make can run correctly
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+
+# Generate configure header.
+ac_config_headers="$ac_config_headers magick/magick_config.h magick/magick_config_api.h"
+
+
+am__api_version='1.15'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+
+ PACKAGE=$PACKAGE_NAME
+ VERSION="${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}"
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
+
+# Enable support for silent build rules
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+
+# Regenerate config.status if ChangeLog or version.sh is updated.
+CONFIG_STATUS_DEPENDENCIES='$(top_srcdir)/ChangeLog $(top_srcdir)/version.sh'
+
+
+PERLMAINCC=$CC
+
+MAGICK_API_CFLAGS=''
+MAGICK_API_CPPFLAGS=''
+MAGICK_API_PC_CPPFLAGS=''
+MAGICK_API_LDFLAGS=''
+MAGICK_API_LIBS=''
+
+#
+# Standards compliance definitions
+#
+#AC_DEFINE(_XOPEN_SOURCE,500,[Required X Open interface level (500)])
+#AC_DEFINE(_POSIX_C_SOURCE,199506L,[Required POSIX interface level (199506L)])
+#AC_DEFINE(_ISOC99_SOURCE,1,[Code may make use of ISO C '99 features])
+#AC_DEFINE(__EXTENSIONS__,1,[Enable all API extensions (for Solaris)])
+#AC_DEFINE(_GNU_SOURCE,1,[Enable all API extensions (for GNU Linux libc)])
+#AC_DEFINE(_NETBSD_SOURCE,1,[Enable all API extensions (for NetBSD)])
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+#
+# Evaluate shell variable equivalents to Makefile directory variables
+#
+if test "x$prefix" = xNONE
+then
+ prefix=$ac_default_prefix
+fi
+# Let make expand exec_prefix.
+if test "x$exec_prefix" = xNONE
+then
+ exec_prefix='${prefix}'
+fi
+
+#
+eval "eval PREFIX_DIR=${prefix}"
+
+eval "eval EXEC_PREFIX_DIR=${exec_prefix}"
+
+eval "eval BIN_DIR=$bindir"
+
+eval "eval SBIN_DIR=$sbindir"
+
+eval "eval LIBEXEC_DIR=$libexecdir"
+
+eval "eval DATA_DIR=$datadir"
+
+eval "eval DOC_DIR=$docdir"
+
+eval "eval HTML_DIR=$htmldir"
+
+eval "eval SYSCONF_DIR=$sysconfdir"
+
+eval "eval SHAREDSTATE_DIR=$sharedstatedir"
+
+eval "eval LOCALSTATE_DIR=$localstatedir"
+
+eval "eval LIB_DIR=$libdir"
+
+eval "eval INCLUDE_DIR=$includedir"
+
+eval "eval OLDINCLUDE_DIR=$oldincludedir"
+
+eval "eval INFO_DIR=$infodir"
+
+eval "eval MAN_DIR=$mandir"
+
+
+# Get full paths to source and build directories
+srcdirfull="`cd $srcdir && pwd`"
+builddir="`pwd`"
+
+WinPathScript="${srcdirfull}/winpath.sh"
+
+
+#
+# Compute variables useful for running uninstalled software
+#
+MAGICK_CODER_MODULE_PATH="${builddir}/coders"
+MAGICK_CONFIGURE_SRC_PATH="${srcdirfull}/config"
+MAGICK_CONFIGURE_BUILD_PATH="${builddir}/config"
+MAGICK_FILTER_MODULE_PATH="${builddir}/filters"
+DIRSEP=':'
+case "${build_os}" in
+ mingw* )
+ MAGICK_CODER_MODULE_PATH=`$WinPathScript "${MAGICK_CODER_MODULE_PATH}" 0`
+ MAGICK_CONFIGURE_SRC_PATH=`$WinPathScript "${MAGICK_CONFIGURE_SRC_PATH}" 0`
+ MAGICK_CONFIGURE_BUILD_PATH=`$WinPathScript "${MAGICK_CONFIGURE_BUILD_PATH}" 0`
+ MAGICK_FILTER_MODULE_PATH=`$WinPathScript "${MAGICK_FILTER_MODULE_PATH}" 0`
+ ;;
+esac
+case "${host_os}" in
+ mingw* )
+ DIRSEP=';'
+ ;;
+esac
+
+
+
+
+
+
+# Check for programs
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ case $ac_cv_prog_cc_stdc in #(
+ no) :
+ ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #(
+ *) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str;
+ int number;
+ float fnumber;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+}
+
+int
+main ()
+{
+
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c99"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+else
+ ac_cv_prog_cc_stdc=no
+fi
+
+fi
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5
+$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; }
+ if ${ac_cv_prog_cc_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+
+ case $ac_cv_prog_cc_stdc in #(
+ no) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;; #(
+ '') :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;; #(
+ *) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5
+$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case $ECHO in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+
+ # Necessary if objects are placed in subdirectories.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+
+#
+# Tests for Windows
+#
+
+
+
+LIB_GDI32=''
+native_win32_build='no'
+cygwin_build='no'
+case "${host_os}" in
+ cygwin* )
+ cygwin_build='yes'
+ LIB_GDI32='-lgdi32'
+ ;;
+ mingw* )
+ native_win32_build='yes'
+ LIB_GDI32='-lgdi32'
+ ;;
+esac
+if test "${LIB_GDI32}x" != 'x'
+then
+
+$as_echo "#define HasWINGDI32 1" >>confdefs.h
+
+fi
+
+ if test "${LIB_GDI32}x" != 'x' ; then
+ HasWINGDI32_TRUE=
+ HasWINGDI32_FALSE='#'
+else
+ HasWINGDI32_TRUE='#'
+ HasWINGDI32_FALSE=
+fi
+
+ if test "${native_win32_build}" = 'yes' ; then
+ WIN32_NATIVE_BUILD_TRUE=
+ WIN32_NATIVE_BUILD_FALSE='#'
+else
+ WIN32_NATIVE_BUILD_TRUE='#'
+ WIN32_NATIVE_BUILD_FALSE=
+fi
+
+ if test "${cygwin_build}" = 'yes' ; then
+ CYGWIN_BUILD_TRUE=
+ CYGWIN_BUILD_FALSE='#'
+else
+ CYGWIN_BUILD_TRUE='#'
+ CYGWIN_BUILD_FALSE=
+fi
+
+
+WinPathScript="${srcdirfull}/winpath.sh"
+
+
+#
+# Compiler flags tweaks
+#
+if test "${GCC}" != "yes"
+then
+ case "${host}" in
+ *-*-hpux* )
+ # aCC: HP ANSI C++ B3910B A.03.34
+ CFLAGS="${CFLAGS} -Wp,-H30000"
+ if test -n "${CXXFLAGS}"
+ then
+ CXXFLAGS='-AA'
+ else
+ CXXFLAGS="${CXXFLAGS} -AA"
+ fi
+ ;;
+ *-dec-osf5.* )
+ # Compaq alphaev68-dec-osf5.1 compiler
+ if test -n "${CXXFLAGS}"
+ then
+ CXXFLAGS='-std strict_ansi -noimplicit_include'
+ else
+ CXXFLAGS="${CXXFLAGS} -std strict_ansi -noimplicit_include"
+ fi
+ ;;
+ esac
+else
+ CFLAGS="${CFLAGS} -Wall"
+fi
+
+#
+# Determine POSIX threads settings
+#
+# Enable support for POSIX thread APIs
+
+# Check whether --with-threads was given.
+if test "${with_threads+set}" = set; then :
+ withval=$with_threads; with_threads=$withval
+else
+ with_threads='yes'
+fi
+
+
+have_threads=no
+if test "$with_threads" != 'no'
+then
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+ if test x"$acx_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt lpthread pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+ *solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+ ;;
+
+ # The HP-UX compiler just warns about options it does not understand
+ # but it needs -mt.
+ *-hpux*)
+ acx_pthread_flags="-mt $acx_pthread_flags"
+ ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+ case $flag in
+ none)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+ ;;
+
+ -*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ # Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_acx_pthread_config+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$acx_pthread_config"; then
+ ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_acx_pthread_config="yes"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
+fi
+fi
+acx_pthread_config=$ac_cv_prog_acx_pthread_config
+if test -n "$acx_pthread_config"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5
+$as_echo "$acx_pthread_config" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test x"$acx_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+ if test "x$acx_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+int attr=$attr; return attr;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ attr_name=$attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
+$as_echo "$attr_name" >&6; }
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
+_ACEOF
+
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+ flag=no
+ case "${host_cpu}-${host_os}" in
+ *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+ *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5
+$as_echo "${flag}" >&6; }
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: must compile with xlc_r or cc_r
+ case "${host_os}" in
+ aix* )
+ if test x"$GCC" != xyes; then
+ case "$CC" in
+ *xlc )
+ # Extract the first word of "xlc_r", so it can be a program name with args.
+set dummy xlc_r; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PTHREAD_CC"; then
+ ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PTHREAD_CC="xlc_r"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}"
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ ;;
+ *cc )
+ # Extract the first word of "cc_r", so it can be a program name with args.
+set dummy cc_r; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PTHREAD_CC"; then
+ ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PTHREAD_CC="cc_r"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}"
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ ;;
+ esac
+ fi
+ case "$CXX" in
+ *xlC )
+ # Extract the first word of "xlC_r", so it can be a program name with args.
+set dummy xlC_r; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PTHREAD_CXX"; then
+ ac_cv_prog_PTHREAD_CXX="$PTHREAD_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PTHREAD_CXX="xlC_r"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_PTHREAD_CXX" && ac_cv_prog_PTHREAD_CXX="${CXX}"
+fi
+fi
+PTHREAD_CXX=$ac_cv_prog_PTHREAD_CXX
+if test -n "$PTHREAD_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CXX" >&5
+$as_echo "$PTHREAD_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ ;;
+ esac
+ ;;
+ esac
+fi
+
+if test "${PTHREAD_CC}x" = "x"
+then
+ PTHREAD_CC="$CC"
+fi
+if test "${PTHREAD_CXX}x" = "x"
+then
+ PTHREAD_CXX="$CXX"
+fi
+
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+ :
+else
+ acx_pthread_ok=no
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ if test "$acx_pthread_ok" = yes
+ then
+ have_threads=yes
+
+ DEF_THREAD="$PTHREAD_CFLAGS"
+ CFLAGS="$CFLAGS $DEF_THREAD"
+ CXXFLAGS="$CXXFLAGS $DEF_THREAD"
+
+ if test "$CC" != "$PTHREAD_CC"
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Replacing compiler $CC with compiler $PTHREAD_CC to support pthreads." >&5
+$as_echo "$as_me: WARNING: Replacing compiler $CC with compiler $PTHREAD_CC to support pthreads." >&2;}
+ CC="$PTHREAD_CC"
+ fi
+ if test "$CXX" != "$PTHREAD_CXX"
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Replacing compiler $CXX with compiler $PTHREAD_CXX to support pthreads." >&5
+$as_echo "$as_me: WARNING: Replacing compiler $CXX with compiler $PTHREAD_CXX to support pthreads." >&2;}
+ CXX="$PTHREAD_CXX"
+ fi
+ fi
+fi
+
+#
+# Determine options necessary to enable OpenMP support
+#
+# Sets Set the OPENMP_CFLAGS / OPENMP_CXXFLAGS / OPENMP_FFLAGS
+# variable to these options.
+
+
+ OPENMP_CFLAGS=
+ # Check whether --enable-openmp was given.
+if test "${enable_openmp+set}" = set; then :
+ enableval=$enable_openmp;
+fi
+
+ if test "$enable_openmp" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to support OpenMP" >&5
+$as_echo_n "checking for $CC option to support OpenMP... " >&6; }
+if ${ac_cv_prog_c_openmp+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifndef _OPENMP
+ choke me
+#endif
+#include <omp.h>
+int main () { return omp_get_num_threads (); }
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_prog_c_openmp='none needed'
+else
+ ac_cv_prog_c_openmp='unsupported'
+ for ac_option in -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp -homp \
+ -Popenmp --openmp; do
+ ac_save_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS $ac_option"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifndef _OPENMP
+ choke me
+#endif
+#include <omp.h>
+int main () { return omp_get_num_threads (); }
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_prog_c_openmp=$ac_option
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS=$ac_save_CFLAGS
+ if test "$ac_cv_prog_c_openmp" != unsupported; then
+ break
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_c_openmp" >&5
+$as_echo "$ac_cv_prog_c_openmp" >&6; }
+ case $ac_cv_prog_c_openmp in #(
+ "none needed" | unsupported)
+ ;; #(
+ *)
+ OPENMP_CFLAGS=$ac_cv_prog_c_openmp ;;
+ esac
+ fi
+
+
+CFLAGS="$OPENMP_CFLAGS $CFLAGS"
+#CXXFLAGS="$OPENMP_CXXFLAGS $CXXFLAGS"
+#LDFLAGS="$LDFLAGS $OPENMP_CFLAGS"
+
+
+# Allow the user to disable use of OpenMP where algorithms sometimes run slower.
+# Check whether --enable-openmp-slow was given.
+if test "${enable_openmp_slow+set}" = set; then :
+ enableval=$enable_openmp_slow; with_openmp_slow=$enableval
+else
+ with_openmp_slow='no'
+fi
+
+if test "$with_openmp_slow" = 'no'
+then
+
+$as_echo "#define DisableSlowOpenMP 1" >>confdefs.h
+
+fi
+
+########
+#
+# Check for large file support
+#
+# According to the X/Open LFS standard, setting _FILE_OFFSET_BITS to 64
+# remaps standard functions to their 64-bit equivalents.
+#
+# The LFS_CPPFLAGS substition is used to support building PerlMagick.
+#
+#
+########
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
+
+
+fi
+
+
+# If the `fseeko' function is available, define `HAVE_FSEEKO'. Define
+# `_LARGEFILE_SOURCE' if necessary.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_source+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_sys_largefile_source=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGEFILE_SOURCE 1
+#include <sys/types.h> /* for off_t */
+ #include <stdio.h>
+int
+main ()
+{
+int (*fp) (FILE *, off_t, int) = fseeko;
+ return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_sys_largefile_source=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_cv_sys_largefile_source=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
+$as_echo "$ac_cv_sys_largefile_source" >&6; }
+case $ac_cv_sys_largefile_source in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+;;
+esac
+rm -rf conftest*
+
+# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
+# in glibc 2.1.3, but that breaks too many other things.
+# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
+if test $ac_cv_sys_largefile_source != unknown; then
+
+$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
+
+fi
+
+
+LFS_CPPFLAGS=''
+if test "$enable_largefile" != no
+then
+ if test "$ac_cv_sys_file_offset_bits" != 'no'
+ then
+ LFS_CPPFLAGS="$LFS_CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+ fi
+ if test "$ac_cv_sys_large_files" != 'no'
+ then
+ LFS_CPPFLAGS="$LFS_CPPFLAGS -D_LARGE_FILES=1"
+ fi
+ if test "$ac_cv_sys_largefile_source" != 'no'
+ then
+ LFS_CPPFLAGS="$LFS_CPPFLAGS -D_LARGEFILE_SOURCE=1"
+ fi
+fi
+
+
+#
+# Configure libtool
+#
+
+# Configure libtool
+enable_dlopen=yes
+
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+ ac_path_lt_DD_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in dd; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+ $ac_path_lt_DD_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_lt_DD"; then
+ :
+ fi
+else
+ ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[012][,.]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+# Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_shared=no
+fi
+
+
+
+
+
+
+
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AS="as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+ ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+ shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[5-9]*,yes)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+ withval=$with_aix_soname; case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname
+else
+ if ${lt_cv_with_aix_soname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_with_aix_soname=aix
+fi
+
+ with_aix_soname=$lt_cv_with_aix_soname
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+$as_echo "$with_aix_soname" >&6; }
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/${ac_tool_prefix}file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test yes = "$GCC"; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='$wl--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ export_dynamic_flag_spec='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test no = "$ld_shlibs"; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ export_dynamic_flag_spec='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' $wl-bernotok'
+ allow_undefined_flag=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ ld_shlibs=yes
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ else
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='$wl-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='$wl-z,text'
+ allow_undefined_flag='$wl-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a(lib.so.V)'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test yes = "$hardcode_automatic"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+ test no != "$hardcode_minus_L"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+ test yes = "$inherit_rpath"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report what library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CXX" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+
+
+
+func_stripname_cnf ()
+{
+ case $2 in
+ .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;;
+ *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;;
+ esac
+} # func_stripname_cnf
+
+ if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+ if ${ac_cv_prog_CXXCPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+else
+ _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+ # save warnings/boilerplate of simple test code
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ compiler_CXX=$CC
+ func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test yes = "$GXX"; then
+ lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+ else
+ lt_prog_compiler_no_builtin_flag_CXX=
+ fi
+
+ if test yes = "$GXX"; then
+ # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test yes = "$with_gnu_ld"; then
+ archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='$wl'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec_CXX=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+ ld_shlibs_CXX=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds_CXX=''
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ file_list_spec_CXX='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ hardcode_direct_CXX=no
+ hardcode_direct_absolute_CXX=no
+ ;;
+ esac
+
+ if test yes = "$GXX"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct_CXX=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L_CXX=yes
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ hardcode_libdir_separator_CXX=
+ fi
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ export_dynamic_flag_spec_CXX='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ always_export_symbols_CXX=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ # The "-G" linker flag allows undefined symbols.
+ no_undefined_flag_CXX='-bernotok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+ hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+
+ archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag_CXX="-z nodefs"
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath__CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath__CXX"; then
+ lt_cv_aix_libpath__CXX=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+ hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag_CXX=' $wl-bernotok'
+ allow_undefined_flag_CXX=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec_CXX='$convenience'
+ fi
+ archive_cmds_need_lc_CXX=yes
+ archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared
+ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+ archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag_CXX=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX=' '
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=yes
+ file_list_spec_CXX='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+ enable_shared_with_static_runtimes_CXX=yes
+ # Don't use ranlib
+ old_postinstall_cmds_CXX='chmod 644 $oldlib'
+ postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-all-symbols'
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=no
+ enable_shared_with_static_runtimes_CXX=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc_CXX=no
+ hardcode_direct_CXX=no
+ hardcode_automatic_CXX=yes
+ hardcode_shlibpath_var_CXX=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec_CXX=''
+ fi
+ link_all_deplibs_CXX=yes
+ allow_undefined_flag_CXX=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+ fi
+
+ else
+ ld_shlibs_CXX=no
+ fi
+
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ hardcode_minus_L_CXX=yes
+ allow_undefined_flag_CXX=unsupported
+ shrext_cmds=.dll
+ archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes_CXX=yes
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ ld_shlibs_CXX=no
+ ;;
+
+ freebsd-elf*)
+ archive_cmds_need_lc_CXX=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ ld_shlibs_CXX=yes
+ ;;
+
+ haiku*)
+ archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs_CXX=yes
+ ;;
+
+ hpux9*)
+ hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+ hardcode_libdir_separator_CXX=:
+ export_dynamic_flag_spec_CXX='$wl-E'
+ hardcode_direct_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ export_dynamic_flag_spec_CXX='$wl-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ ;;
+ *)
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ fi
+ fi
+ link_all_deplibs_CXX=yes
+ ;;
+ esac
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator_CXX=:
+ inherit_rpath_CXX=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ archive_cmds_need_lc_CXX=no
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+ whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+ prelink_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ old_archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+ whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec_CXX='$wl--export-dynamic'
+ archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object_CXX=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ ld_shlibs_CXX=yes
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ hardcode_direct_absolute_CXX=yes
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ export_dynamic_flag_spec_CXX='$wl-E'
+ whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
+ archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ ;;
+ *)
+ allow_undefined_flag_CXX=' -expect_unresolved \*'
+ archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ ;;
+ esac
+
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'
+ case $host in
+ osf3*)
+ archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ archive_cmds_need_lc_CXX=yes
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_shlibpath_var_CXX=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ link_all_deplibs_CXX=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ no_undefined_flag_CXX=' $wl-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # platform.
+ archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag_CXX='$wl-z,text'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_CXX='$wl-z,text'
+ allow_undefined_flag_CXX='$wl-z,nodefs'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='$wl-R,$libdir'
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ export_dynamic_flag_spec_CXX='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+ '"$old_archive_cmds_CXX"
+ reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+ '"$reload_cmds_CXX"
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+ test no = "$ld_shlibs_CXX" && can_build_shared=no
+
+ GCC_CXX=$GXX
+ LD_CXX=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $prev$p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$compiler_lib_search_path_CXX"; then
+ compiler_lib_search_path_CXX=$prev$p
+ else
+ compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$postdeps_CXX"; then
+ postdeps_CXX=$prev$p
+ else
+ postdeps_CXX="${postdeps_CXX} $prev$p"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test no = "$pre_test_object_deps_done"; then
+ if test -z "$predep_objects_CXX"; then
+ predep_objects_CXX=$p
+ else
+ predep_objects_CXX="$predep_objects_CXX $p"
+ fi
+ else
+ if test -z "$postdep_objects_CXX"; then
+ postdep_objects_CXX=$p
+ else
+ postdep_objects_CXX="$postdep_objects_CXX $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ predep_objects_CXX=
+ postdep_objects_CXX=
+ postdeps_CXX=
+ ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+ # C++ specific cases for pic, static, wl, etc.
+ if test yes = "$GXX"; then
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ fi
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static_CXX='$wl-static'
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic_CXX='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ lt_prog_compiler_pic_CXX=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static_CXX=
+ ;;
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic_CXX=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[4-9]*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ else
+ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
+ lt_prog_compiler_pic_CXX='+Z'
+ fi
+ ;;
+ aCC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='$wl-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64, which still supported -KPIC.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fpic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-qpic'
+ lt_prog_compiler_static_CXX='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ lt_prog_compiler_pic_CXX='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ lt_prog_compiler_wl_CXX='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ lt_prog_compiler_pic_CXX='-pic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ lt_prog_compiler_can_build_shared_CXX=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic_CXX=
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works_CXX=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works_CXX=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then
+ case $lt_prog_compiler_pic_CXX in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+ esac
+else
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works_CXX=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then
+ :
+else
+ lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ case $host_os in
+ aix[4-9]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ export_symbols_cmds_CXX=$ltdll_cmds
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+ ;;
+ esac
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test no = "$ld_shlibs_CXX" && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc_CXX=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds_CXX in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl_CXX
+ pic_flag=$lt_prog_compiler_pic_CXX
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+ allow_undefined_flag_CXX=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc_CXX=no
+ else
+ lt_cv_archive_cmds_need_lc_CXX=yes
+ fi
+ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+ archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a(lib.so.V)'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+ test -n "$runpath_var_CXX" ||
+ test yes = "$hardcode_automatic_CXX"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct_CXX" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" &&
+ test no != "$hardcode_minus_L_CXX"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_CXX=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_CXX=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test relink = "$hardcode_action_CXX" ||
+ test yes = "$inherit_rpath_CXX"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+# Check to see if building shared libraries
+libtool_build_shared_libs='no'
+if test "$enable_shared" = 'yes'
+then
+ libtool_build_shared_libs='yes'
+fi
+
+# Check to see if building static libraries
+libtool_build_static_libs='no'
+if test "$enable_static" = 'yes'
+then
+ libtool_build_static_libs='yes'
+fi
+
+ if test "${libtool_build_shared_libs}" = 'yes'; then
+ WITH_SHARED_LIBS_TRUE=
+ WITH_SHARED_LIBS_FALSE='#'
+else
+ WITH_SHARED_LIBS_TRUE='#'
+ WITH_SHARED_LIBS_FALSE=
+fi
+
+
+#
+# Enable support for building loadable modules
+#
+build_modules='no'
+
+# Check whether --with-modules was given.
+if test "${with_modules+set}" = set; then :
+ withval=$with_modules; with_modules=$withval
+else
+ with_modules='no'
+fi
+
+
+# Only allow building loadable modules if we are building shared libraries
+if test "$with_modules" != 'no' ; then
+ if test "$libtool_build_shared_libs" = 'no' ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Modules may only be built if building shared libraries is enabled." >&5
+$as_echo "$as_me: WARNING: Modules may only be built if building shared libraries is enabled." >&2;}
+ build_modules='no'
+ else
+ build_modules='yes'
+ fi
+fi
+if test "$build_modules" != 'no' ; then
+
+$as_echo "#define BuildMagickModules 1" >>confdefs.h
+
+fi
+ if test "$build_modules" != 'no'; then
+ WITH_MODULES_TRUE=
+ WITH_MODULES_FALSE='#'
+else
+ WITH_MODULES_TRUE='#'
+ WITH_MODULES_FALSE=
+fi
+
+
+
+# Build a version of GraphicsMagick which operates uninstalled.
+# Used to build distributions located via MAGICK_HOME / executable path
+# Check whether --enable-installed was given.
+if test "${enable_installed+set}" = set; then :
+ enableval=$enable_installed; with_installed=$enableval
+else
+ with_installed='yes'
+fi
+
+if test "$with_installed" = 'yes'
+then
+
+$as_echo "#define UseInstalledMagick 1" >>confdefs.h
+
+else
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --disable-installed "
+fi
+
+# Enable broken/dangerous coders
+# EnableBrokenCoders CPP define and ENABLE_BROKEN_CODERS Automake conditional)
+# Check whether --enable-broken-coders was given.
+if test "${enable_broken_coders+set}" = set; then :
+ enableval=$enable_broken_coders; with_broken_coders=$enableval
+else
+ with_broken_coders='no'
+fi
+
+if test "$with_broken_coders" = 'yes'
+then
+
+$as_echo "#define EnableBrokenCoders 1" >>confdefs.h
+
+fi
+ if test "$with_broken_coders" != 'no'; then
+ ENABLE_BROKEN_CODERS_TRUE=
+ ENABLE_BROKEN_CODERS_FALSE='#'
+else
+ ENABLE_BROKEN_CODERS_TRUE='#'
+ ENABLE_BROKEN_CODERS_FALSE=
+fi
+
+
+# Add configure option --enable-maintainer-mode which enables dependency
+# checking and generation useful to package maintainers. This is made an
+# option to avoid confusing end users.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+# Enable prof-based profiling support
+# Check whether --enable-prof was given.
+if test "${enable_prof+set}" = set; then :
+ enableval=$enable_prof; with_prof=$enableval
+else
+ with_prof='no'
+fi
+
+
+# Enable gprof-based profiling support
+# Check whether --enable-gprof was given.
+if test "${enable_gprof+set}" = set; then :
+ enableval=$enable_gprof; with_gprof=$enableval
+else
+ with_gprof='no'
+fi
+
+
+# Enable gcov-based profiling support
+# Check whether --enable-gcov was given.
+if test "${enable_gcov+set}" = set; then :
+ enableval=$enable_gcov; with_gcov=$enableval
+else
+ with_gcov='no'
+fi
+
+
+with_profiling='no'
+if test "$with_prof" = 'yes' || test "$with_gprof" = 'yes' || test "$with_gcov" = 'yes'
+then
+ with_profiling='yes'
+
+ if test "$libtool_build_shared_libs" = 'yes'
+ then
+ echo "Warning: Can not profile code using shared libraries"
+ fi
+fi
+
+# Enable prefixing library symbols with a common string
+# Check whether --enable-symbol-prefix was given.
+if test "${enable_symbol_prefix+set}" = set; then :
+ enableval=$enable_symbol_prefix; with_symbol_prefix=$enableval
+else
+ with_symbol_prefix='no'
+fi
+
+if test "$with_symbol_prefix" != 'no'
+then
+
+$as_echo "#define PREFIX_MAGICK_SYMBOLS 1" >>confdefs.h
+
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --enable-symbol-prefix "
+fi
+
+# Enable ImageMagick utilities compatibility shortcuts (default no)
+# Check whether --enable-magick-compat was given.
+if test "${enable_magick_compat+set}" = set; then :
+ enableval=$enable_magick_compat; with_magick_compat=$enableval
+else
+ with_magick_compat='no'
+fi
+
+ if test "$with_magick_compat" != 'no'; then
+ MAGICK_COMPAT_TRUE=
+ MAGICK_COMPAT_FALSE='#'
+else
+ MAGICK_COMPAT_TRUE='#'
+ MAGICK_COMPAT_FALSE=
+fi
+
+
+# Number of bits in a Quantum
+
+# Check whether --with-quantum-depth was given.
+if test "${with_quantum_depth+set}" = set; then :
+ withval=$with_quantum_depth; with_quantum_depth=$withval
+else
+ with_quantum_depth=8
+fi
+
+if test "$with_quantum_depth" != '8' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-quantum-depth=$with_quantum_depth "
+fi
+
+case "${with_quantum_depth}" in
+ 8 ) ;;
+ 16 ) ;;
+ 32 ) ;;
+ * ) as_fn_error 16 "\"Pixel quantum depth must have value of 8" "$LINENO" 5 ;;
+esac
+QuantumDepth="$with_quantum_depth"
+
+cat >>confdefs.h <<_ACEOF
+#define QuantumDepth $QuantumDepth
+_ACEOF
+
+
+# Enable QuantumDepth in shared library names
+# Check whether --enable-quantum-library-names was given.
+if test "${enable_quantum_library_names+set}" = set; then :
+ enableval=$enable_quantum_library_names; with_quantum_library_names=$enableval
+else
+ with_quantum_library_names='no'
+fi
+
+MAGICK_LT_RELEASE_OPTS=
+if test "$with_quantum_library_names" != 'no'
+then
+ MAGICK_LT_RELEASE_OPTS="-release Q${QuantumDepth}"
+fi
+
+
+# Disable/Enable support for full delegate paths in delegates.mgk
+
+# Check whether --with-frozenpaths was given.
+if test "${with_frozenpaths+set}" = set; then :
+ withval=$with_frozenpaths; with_frozenpaths=$withval
+else
+ with_frozenpaths='no'
+fi
+
+
+# Enable build/install of Magick++
+
+# Check whether --with-magick-plus-plus was given.
+if test "${with_magick_plus_plus+set}" = set; then :
+ withval=$with_magick_plus_plus; with_magick_plus_plus=$withval
+else
+ with_magick_plus_plus='yes'
+fi
+
+
+# Enable build/install of PerlMagick.
+
+# Check whether --with-perl was given.
+if test "${with_perl+set}" = set; then :
+ withval=$with_perl; with_perl=$withval
+else
+ with_perl='no'
+fi
+
+
+# Options to pass when configuring PerlMagick
+
+# Check whether --with-perl-options was given.
+if test "${with_perl_options+set}" = set; then :
+ withval=$with_perl_options; PERL_MAKE_OPTIONS=$withval
+fi
+
+
+
+
+# Disable BZLIB (bzip2 library)
+
+# Check whether --with-bzlib was given.
+if test "${with_bzlib+set}" = set; then :
+ withval=$with_bzlib; with_bzlib=$withval
+else
+ with_bzlib='yes'
+fi
+
+if test "$with_bzlib" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-bzlib=$with_bzlib "
+fi
+
+# Disable Display Postscript.
+
+# Check whether --with-dps was given.
+if test "${with_dps+set}" = set; then :
+ withval=$with_dps; with_dps=$withval
+else
+ with_dps='yes'
+fi
+
+if test "$with_dps" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-dps=$with_dps "
+fi
+
+# Enable FlashPIX.
+
+# Check whether --with-fpx was given.
+if test "${with_fpx+set}" = set; then :
+ withval=$with_fpx; with_fpx=$withval
+else
+ with_fpx='no'
+fi
+
+if test "$with_fpx" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-fpx=$with_fpx "
+fi
+
+# Enable Ghostscript library support.
+
+# Check whether --with-gslib was given.
+if test "${with_gslib+set}" = set; then :
+ withval=$with_gslib; with_gslib=$withval
+else
+ with_gslib='no'
+fi
+
+if test "$with_gslib" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-gslib=$with_gslib "
+fi
+
+# Disable JBIG.
+
+# Check whether --with-jbig was given.
+if test "${with_jbig+set}" = set; then :
+ withval=$with_jbig; with_jbig=$withval
+else
+ with_jbig='yes'
+fi
+
+if test "$with_jbig" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-jbig=$with_jbig "
+fi
+
+# Disable WEBP.
+
+# Check whether --with-webp was given.
+if test "${with_webp+set}" = set; then :
+ withval=$with_webp; with_webp=$withval
+else
+ with_webp='yes'
+fi
+
+if test "$with_webp" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-webp=$with_webp "
+fi
+
+# Disable JPEG.
+
+# Check whether --with-jpeg was given.
+if test "${with_jpeg+set}" = set; then :
+ withval=$with_jpeg; with_jpeg=$withval
+else
+ with_jpeg='yes'
+fi
+
+if test "$with_jpeg" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-jpeg=$with_jpeg "
+fi
+
+# Disable JPEG Version 2.
+
+# Check whether --with-jp2 was given.
+if test "${with_jp2+set}" = set; then :
+ withval=$with_jp2; with_jp2=$withval
+else
+ with_jp2='yes'
+fi
+
+if test "$with_jp2" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-jp2=$with_jp2 "
+fi
+
+# Disable LCMS2.
+
+# Check whether --with-lcms2 was given.
+if test "${with_lcms2+set}" = set; then :
+ withval=$with_lcms2; with_lcms2=$withval
+else
+ with_lcms2='yes'
+fi
+
+if test "$with_lcms2" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-lcms2=$with_lcms2 "
+fi
+
+# Disable LZMA (lzma library)
+
+# Check whether --with-lzma was given.
+if test "${with_lzma+set}" = set; then :
+ withval=$with_lzma; with_lzma=$withval
+else
+ with_lzma='yes'
+fi
+
+if test "$with_lzma" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-lzma=$with_lzma "
+fi
+
+# # Disable MPEG.
+# AC_ARG_WITH(mpeg2,
+# AS_HELP_STRING([--without-mpeg2],
+# [disable MPEG support]),
+# [with_mpeg2=$withval],
+# [with_mpeg2='yes'])
+
+# Disable PNG.
+
+# Check whether --with-png was given.
+if test "${with_png+set}" = set; then :
+ withval=$with_png; with_png=$withval
+else
+ with_png='yes'
+fi
+
+if test "$with_png" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-png=$with_png "
+fi
+
+# Disable TIFF.
+
+# Check whether --with-tiff was given.
+if test "${with_tiff+set}" = set; then :
+ withval=$with_tiff; with_tiff=$withval
+else
+ with_tiff='yes'
+fi
+
+if test "$with_tiff" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-tiff=$with_tiff "
+fi
+
+# Disable TRIO.
+
+# Check whether --with-trio was given.
+if test "${with_trio+set}" = set; then :
+ withval=$with_trio; with_trio=$withval
+else
+ with_trio='yes'
+fi
+
+if test "$with_trio" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-trio=$with_trio "
+fi
+
+# Disable TTF.
+
+# Check whether --with-ttf was given.
+if test "${with_ttf+set}" = set; then :
+ withval=$with_ttf; with_ttf=$withval
+else
+ with_ttf='yes'
+fi
+
+if test "$with_ttf" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-ttf=$with_ttf "
+fi
+
+# Enable use of Solaris libumem (object-caching memory allocation library).
+# Available as a SourceForge project http://sourceforge.net/projects/umem/ or
+# https://labs.omniti.com/trac/portableumem/.
+
+# Check whether --with-umem was given.
+if test "${with_umem+set}" = set; then :
+ withval=$with_umem; with_umem=$withval
+else
+ with_umem='no'
+fi
+
+if test "$with_umem" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-umem=$with_umem "
+fi
+
+# Disable WMF.
+
+# Check whether --with-wmf was given.
+if test "${with_wmf+set}" = set; then :
+ withval=$with_wmf; with_wmf=$withval
+else
+ with_wmf='yes'
+fi
+
+if test "$with_wmf" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-wmf=$with_wmf "
+fi
+
+# Set default font search path
+
+# Check whether --with-fontpath was given.
+if test "${with_fontpath+set}" = set; then :
+ withval=$with_fontpath; with_fontpath=$withval
+else
+ with_fontpath=''
+fi
+
+if test "$with_fontpath" != "yes" && test -z "$with_fontpath"
+then
+ with_fontpath=''
+else
+
+cat >>confdefs.h <<_ACEOF
+#define MAGICK_FONT_PATH "$with_fontpath"
+_ACEOF
+
+fi
+if test "$with_fontpath=" != '' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-fontpath=$with_fontpath "
+fi
+
+# Set Ghostscript font directory
+
+# Check whether --with-gs-font-dir was given.
+if test "${with_gs_font_dir+set}" = set; then :
+ withval=$with_gs_font_dir; with_gs_font_dir=$withval
+else
+ with_gs_font_dir='default'
+fi
+
+if test "$with_gs_font_dir" != 'default' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-gs-font-dir=$with_gs_font_dir "
+fi
+
+# Set Windows font directory
+
+# Check whether --with-windows-font-dir was given.
+if test "${with_windows_font_dir+set}" = set; then :
+ withval=$with_windows_font_dir; with_windows_font_dir=$withval
+else
+ with_windows_font_dir=''
+fi
+
+if test "$with_windows_font_dir" != '' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-windows-font-dir=$with_windows_font_dir "
+fi
+
+# Disable XML.
+
+# Check whether --with-xml was given.
+if test "${with_xml+set}" = set; then :
+ withval=$with_xml; with_xml=$withval
+else
+ with_xml='yes'
+fi
+
+if test "$with_xml" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-xml=$with_xml "
+fi
+
+
+# Check whether --with-zlib was given.
+if test "${with_zlib+set}" = set; then :
+ withval=$with_zlib; with_zlib=$withval
+else
+ with_zlib='yes'
+fi
+
+if test "$with_zlib" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-zlib=$with_zlib "
+fi
+
+#
+# Specify path to shared libstdc++ if not in normal location
+#
+
+# Check whether --with-libstdc was given.
+if test "${with_libstdc+set}" = set; then :
+ withval=$with_libstdc; if test "$withval" != no && test "$withval" != yes; then
+ if test -d "$withval"; then
+ LIBSTDCLDFLAGS="-L$withval"
+ fi
+ fi
+fi
+
+
+
+# Does gcc required -traditional?
+if test $ac_cv_c_compiler_gnu = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5
+$as_echo_n "checking whether $CC needs -traditional... " >&6; }
+if ${ac_cv_prog_gcc_traditional+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+ ac_cv_prog_gcc_traditional=yes
+else
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5
+$as_echo "$ac_cv_prog_gcc_traditional" >&6; }
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+
+########
+#
+# Set defines required to build DLLs and modules using MinGW
+#
+########
+# These options are set for multi-thread DLL module build
+# libMagick: _DLL _MAGICKMOD_ _MAGICKLIB_
+# module: _DLL
+# executable/Magick++: _DLL _MAGICKMOD_
+MODULE_EXTRA_CPPFLAGS=''
+LIBRARY_EXTRA_CPPFLAGS=''
+if test "${native_win32_build}" = 'yes'
+then
+ if test "${libtool_build_shared_libs}" = 'yes'
+ then
+ CPPFLAGS="$CPPFLAGS -D_DLL"
+ MAGICK_API_CPPFLAGS="$MAGICK_API_CPPFLAGS -D_DLL"
+ MAGICK_API_PC_CPPFLAGS="$MAGICK_API_PC_CPPFLAGS -D_DLL"
+ LIBRARY_EXTRA_CPPFLAGS="$LIBRARY_EXTRA_CPPFLAGS -D_MAGICKLIB_"
+
+ if test "$build_modules" = 'yes'
+ then
+ LIBRARY_EXTRA_CPPFLAGS="$LIBRARY_EXTRA_CPPFLAGS -D_MAGICKMOD_"
+ else
+ MODULE_EXTRA_CPPFLAGS="$MODULE_EXTRA_CPPFLAGS -D_MAGICKLIB_"
+ fi
+
+ else
+ CPPFLAGS="$CPPFLAGS -D_LIB"
+ MAGICK_API_CPPFLAGS="$MAGICK_API_CPPFLAGS -D_LIB"
+ MAGICK_API_PC_CPPFLAGS="$MAGICK_API_PC_CPPFLAGS -D_LIB"
+
+ fi
+ if test "$with_threads" = 'yes'
+ then
+ CPPFLAGS="$CPPFLAGS -D_MT"
+ MAGICK_API_CPPFLAGS="$MAGICK_API_CPPFLAGS -D_MT"
+ MAGICK_API_PC_CPPFLAGS="$MAGICK_API_PC_CPPFLAGS -D_MT"
+ fi
+fi
+
+
+
+# Check standard headers
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if eval \${$as_ac_Header+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$as_ac_Header=yes"
+else
+ eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+
+# Check additional headers
+for ac_header in machine/param.h mach-o/dyld.h process.h sun_prefetch.h sys/mman.h sys/resource.h sys/times.h sys/types.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in wincrypt.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "wincrypt.h" "ac_cv_header_wincrypt_h" "#include <windows.h>
+"
+if test "x$ac_cv_header_wincrypt_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_WINCRYPT_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+########
+#
+# Checks for typedefs, structures, and compiler characteristics.
+#
+########
+
+# If the C compiler does not fully support the ANSI C qualifier const,
+# define const to be empty.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this sort of thing. */
+ typedef int charset[2];
+ const charset cs = { 0, 0 };
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+
+# If the C compiler supports the keyword restrict, do
+# nothing. Otherwise define restrict to __restrict__ or __restrict if
+# it accepts one of those, otherwise define restrict to be empty.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
+$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
+if ${ac_cv_c_restrict+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_restrict=no
+ # The order here caters to the fact that C++ does not require restrict.
+ for ac_kw in __restrict __restrict__ _Restrict restrict; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+typedef int * int_ptr;
+ int foo (int_ptr $ac_kw ip) {
+ return ip[0];
+ }
+int
+main ()
+{
+int s[1];
+ int * $ac_kw t = s;
+ t[0] = 0;
+ return foo(t)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_restrict=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_restrict" != no && break
+ done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
+$as_echo "$ac_cv_c_restrict" >&6; }
+
+ case $ac_cv_c_restrict in
+ restrict) ;;
+ no) $as_echo "#define restrict /**/" >>confdefs.h
+ ;;
+ *) cat >>confdefs.h <<_ACEOF
+#define restrict $ac_cv_c_restrict
+_ACEOF
+ ;;
+ esac
+
+
+# If the C compiler supports the keyword inline, do nothing. Otherwise
+# define inline to __inline__ or __inline if it accepts one of those,
+# otherwise define inline to be empty.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+
+# If words are stored with the most significant byte first (like
+# Motorola and SPARC CPUs), define `WORDS_BIGENDIAN'.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+
+# Define mode_t to a suitable type, if standard headers do not define it.
+ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
+if test "x$ac_cv_type_mode_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define mode_t int
+_ACEOF
+
+fi
+
+
+# Define off_t to a suitable type, if standard headers do not define it.
+ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
+if test "x$ac_cv_type_off_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long int
+_ACEOF
+
+fi
+
+
+# Define pid_t to a suitable type, if standard headers do not define it.
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+
+# Define size_t to a suitable type, if standard headers do not define it.
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+# Define ssize_t to a suitable type, if standard headers do not define it.
+ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
+if test "x$ac_cv_type_ssize_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define ssize_t int
+_ACEOF
+
+fi
+
+
+# If C compiler supports a working long double type with more range
+# or precision than the double type then define HAVE_LONG_DOUBLE_WIDER.
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double with more range or precision than double" >&5
+$as_echo_n "checking for long double with more range or precision than double... " >&6; }
+if ${ac_cv_type_long_double_wider+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <float.h>
+ long double const a[] =
+ {
+ 0.0L, DBL_MIN, DBL_MAX, DBL_EPSILON,
+ LDBL_MIN, LDBL_MAX, LDBL_EPSILON
+ };
+ long double
+ f (long double x)
+ {
+ return ((x + (unsigned long int) 10) * (-1 / x) + a[0]
+ + (x ? f (x) : 'c'));
+ }
+
+int
+main ()
+{
+static int test_array [1 - 2 * !((0 < ((DBL_MAX_EXP < LDBL_MAX_EXP)
+ + (DBL_MANT_DIG < LDBL_MANT_DIG)
+ - (LDBL_MAX_EXP < DBL_MAX_EXP)
+ - (LDBL_MANT_DIG < DBL_MANT_DIG)))
+ && (int) LDBL_EPSILON == 0
+ )];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_type_long_double_wider=yes
+else
+ ac_cv_type_long_double_wider=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double_wider" >&5
+$as_echo "$ac_cv_type_long_double_wider" >&6; }
+ if test $ac_cv_type_long_double_wider = yes; then
+
+$as_echo "#define HAVE_LONG_DOUBLE_WIDER 1" >>confdefs.h
+
+ fi
+
+
+# If the C type char is unsigned, define __CHAR_UNSIGNED__, unless the
+# C compiler predefines it.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether char is unsigned" >&5
+$as_echo_n "checking whether char is unsigned... " >&6; }
+if ${ac_cv_c_char_unsigned+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((char) -1) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_char_unsigned=no
+else
+ ac_cv_c_char_unsigned=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" >&5
+$as_echo "$ac_cv_c_char_unsigned" >&6; }
+if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
+ $as_echo "#define __CHAR_UNSIGNED__ 1" >>confdefs.h
+
+fi
+
+
+# Obtain size of an 'signed short' and define as SIZEOF_SIGNED_SHORT
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of signed short" >&5
+$as_echo_n "checking size of signed short... " >&6; }
+if ${ac_cv_sizeof_signed_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (signed short))" "ac_cv_sizeof_signed_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_signed_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (signed short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_signed_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_signed_short" >&5
+$as_echo "$ac_cv_sizeof_signed_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIGNED_SHORT $ac_cv_sizeof_signed_short
+_ACEOF
+
+
+
+# Obtain size of an 'unsigned short' and define as SIZEOF_UNSIGNED_SHORT
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5
+$as_echo_n "checking size of unsigned short... " >&6; }
+if ${ac_cv_sizeof_unsigned_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5
+$as_echo "$ac_cv_sizeof_unsigned_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+_ACEOF
+
+
+
+# Obtain size of an 'signed int' and define as SIZEOF_SIGNED_INT
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of signed int" >&5
+$as_echo_n "checking size of signed int... " >&6; }
+if ${ac_cv_sizeof_signed_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (signed int))" "ac_cv_sizeof_signed_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_signed_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (signed int)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_signed_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_signed_int" >&5
+$as_echo "$ac_cv_sizeof_signed_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIGNED_INT $ac_cv_sizeof_signed_int
+_ACEOF
+
+
+
+# Obtain size of an 'unsigned int' and define as SIZEOF_UNSIGNED_INT
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5
+$as_echo_n "checking size of unsigned int... " >&6; }
+if ${ac_cv_sizeof_unsigned_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned int)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5
+$as_echo "$ac_cv_sizeof_unsigned_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+_ACEOF
+
+
+
+# Obtain size of a 'signed long' and define as SIZEOF_SIGNED_LONG
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of signed long" >&5
+$as_echo_n "checking size of signed long... " >&6; }
+if ${ac_cv_sizeof_signed_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (signed long))" "ac_cv_sizeof_signed_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_signed_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (signed long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_signed_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_signed_long" >&5
+$as_echo "$ac_cv_sizeof_signed_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIGNED_LONG $ac_cv_sizeof_signed_long
+_ACEOF
+
+
+
+# Obtain size of a 'unsigned long' and define as SIZEOF_UNSIGNED_LONG
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
+$as_echo_n "checking size of unsigned long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+_ACEOF
+
+
+
+# Obtain size of a 'long long' and define as SIZEOF_SIGNED_LONG_LONG. If
+# 'signed long long' is not supported then the value defined is zero.
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of signed long long" >&5
+$as_echo_n "checking size of signed long long... " >&6; }
+if ${ac_cv_sizeof_signed_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (signed long long))" "ac_cv_sizeof_signed_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_signed_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (signed long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_signed_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_signed_long_long" >&5
+$as_echo "$ac_cv_sizeof_signed_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIGNED_LONG_LONG $ac_cv_sizeof_signed_long_long
+_ACEOF
+
+
+
+# Obtain size of a 'unsigned long long' and define as
+# SIZEOF_UNSIGNED_LONG_LONG. If 'unsigned long long' is not
+# supported then the value defined is zero.
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5
+$as_echo_n "checking size of unsigned long long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+_ACEOF
+
+
+
+# Obtain size of off_t and define as SIZEOF_OFF_T
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5
+$as_echo_n "checking size of off_t... " >&6; }
+if ${ac_cv_sizeof_off_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_off_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (off_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_off_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5
+$as_echo "$ac_cv_sizeof_off_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+_ACEOF
+
+
+
+# Obtain size of size_t and define as SIZEOF_SIZE_T
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
+$as_echo_n "checking size of size_t... " >&6; }
+if ${ac_cv_sizeof_size_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_size_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (size_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_size_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
+$as_echo "$ac_cv_sizeof_size_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+_ACEOF
+
+
+
+# Obtain size of an unsigned int pointer and define as SIZEOF_UNSIGNED_INTP
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int*" >&5
+$as_echo_n "checking size of unsigned int*... " >&6; }
+if ${ac_cv_sizeof_unsigned_intp+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int*))" "ac_cv_sizeof_unsigned_intp" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_intp" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned int*)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_intp=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_intp" >&5
+$as_echo "$ac_cv_sizeof_unsigned_intp" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_INTP $ac_cv_sizeof_unsigned_intp
+_ACEOF
+
+
+
+# If `signal.h' declares signal as returning a pointer to a function
+# returning void, define RETSIGTYPE to be void; otherwise, define it
+# to be int.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if ${ac_cv_type_signal+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_type_signal=int
+else
+ ac_cv_type_signal=void
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+# Test for C compiler __func__ support
+if test "$ac_cv_have_C__func__" != 'yes' ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler __func__ support" >&5
+$as_echo_n "checking for C compiler __func__ support... " >&6; }
+if ${ac_cv_have_C__func__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+const char *func=__func__;
+return (func != 0 ? 0 : 1);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_have_C__func__='yes'
+else
+ ac_cv_have_C__func__='no'
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_C__func__" >&5
+$as_echo "$ac_cv_have_C__func__" >&6; }
+
+if test "$ac_cv_have_C__func__" = 'yes' ; then
+
+$as_echo "#define HAS_C__func__ 1" >>confdefs.h
+
+fi
+fi
+
+#
+# Compute sized types for current CPU and compiler options.
+#
+# The reason why we don't use autoconf's recent built-in support for
+# stdint.h types is because doing it ourself seems easier for dealing
+# with Windows builds which don't use configure.
+#
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for signed 8-bit type" >&5
+$as_echo_n "checking for signed 8-bit type... " >&6; }
+INT8_T='signed char'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INT8_T" >&5
+$as_echo "$INT8_T" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned 8-bit type" >&5
+$as_echo_n "checking for unsigned 8-bit type... " >&6; }
+UINT8_T='unsigned char'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UINT8_T" >&5
+$as_echo "$UINT8_T" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for signed 16-bit type" >&5
+$as_echo_n "checking for signed 16-bit type... " >&6; }
+INT16_T='signed short'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INT16_T" >&5
+$as_echo "$INT16_T" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned 16-bit type" >&5
+$as_echo_n "checking for unsigned 16-bit type... " >&6; }
+UINT16_T='unsigned short'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UINT16_T" >&5
+$as_echo "$UINT16_T" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for signed 32-bit type" >&5
+$as_echo_n "checking for signed 32-bit type... " >&6; }
+INT32_T='none'
+INT32_F='none'
+if test $ac_cv_sizeof_signed_int -eq 4
+then
+ INT32_T='signed int'
+ INT32_F='""'
+elif test $ac_cv_sizeof_signed_long -eq 4
+then
+ INT32_T='signed long'
+ INT32_F='"l"'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INT32_T" >&5
+$as_echo "$INT32_T" >&6; }
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned 32-bit type" >&5
+$as_echo_n "checking for unsigned 32-bit type... " >&6; }
+UINT32_T='none'
+UINT32_F='none'
+if test $ac_cv_sizeof_unsigned_int -eq 4
+then
+ UINT32_T='unsigned int'
+ UINT32_F='""'
+elif test $ac_cv_sizeof_unsigned_long -eq 4
+then
+ UINT32_T='unsigned long'
+ UINT32_F='"l"'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UINT32_T" >&5
+$as_echo "$UINT32_T" >&6; }
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for signed 64-bit type" >&5
+$as_echo_n "checking for signed 64-bit type... " >&6; }
+INT64_T='none'
+INT64_F='none'
+if test $ac_cv_sizeof_signed_long -eq 8
+then
+ INT64_T='signed long'
+ INT64_F='"l"'
+elif test $ac_cv_sizeof_signed_long_long -eq 8
+then
+ INT64_T='signed long long'
+ INT64_F='"ll"'
+fi
+case "${host_os}" in
+ mingw* )
+ INT64_F='"I64"'
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INT64_T" >&5
+$as_echo "$INT64_T" >&6; }
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned 64-bit type" >&5
+$as_echo_n "checking for unsigned 64-bit type... " >&6; }
+UINT64_T='none'
+UINT64_F='none'
+if test $ac_cv_sizeof_unsigned_long -eq 8
+then
+ UINT64_T='unsigned long'
+ UINT64_F='"l"'
+elif test $ac_cv_sizeof_unsigned_long_long -eq 8
+then
+ UINT64_T='unsigned long long'
+ UINT64_F='"ll"'
+fi
+case "${host_os}" in
+ mingw* )
+ UINT64_F='"I64"'
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UINT64_T" >&5
+$as_echo "$UINT64_T" >&6; }
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned maximum type" >&5
+$as_echo_n "checking for unsigned maximum type... " >&6; }
+UINTMAX_T='none'
+UINTMAX_F='none'
+if test "$UINT64_T" != 'none'
+then
+ UINTMAX_T=$UINT64_T
+ UINTMAX_F=$UINT64_F
+elif test "$UINT32_T" != 'none'
+then
+ UINTMAX_T=$UINT32_T
+ UINTMAX_F=$UINT32_F
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UINTMAX_T" >&5
+$as_echo "$UINTMAX_T" >&6; }
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer difference type" >&5
+$as_echo_n "checking for pointer difference type... " >&6; }
+UINTPTR_T='none'
+UINTPTR_F='none'
+if test $ac_cv_sizeof_unsigned_long -eq $ac_cv_sizeof_unsigned_intp
+then
+ UINTPTR_T='unsigned long'
+ UINTPTR_F='"l"'
+elif test $ac_cv_sizeof_unsigned_long_long -eq $ac_cv_sizeof_unsigned_intp
+then
+ UINTPTR_T='unsigned long long'
+ UINTPTR_F='"ll"'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UINTPTR_T" >&5
+$as_echo "$UINTPTR_T" >&6; }
+
+
+
+MAGICK_SIZE_T='none'
+MAGICK_SIZE_T_F='none'
+MAGICK_SSIZE_T='none'
+MAGICK_SSIZE_T_F='none'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for size_t format specification" >&5
+$as_echo_n "checking for size_t format specification... " >&6; }
+if test $ac_cv_sizeof_size_t -eq $ac_cv_sizeof_unsigned_long
+then
+ # Normal case for LP32 and LP64
+ MAGICK_SIZE_T='unsigned long'
+ MAGICK_SIZE_T_F='"l"'
+ MAGICK_SSIZE_T='signed long'
+ MAGICK_SSIZE_T_F='"l"'
+elif test $ac_cv_sizeof_size_t -eq $ac_cv_sizeof_unsigned_long_long
+then
+ # Maybe a LLP64 architecture like WIN64
+ case "${host_os}" in
+ mingw* )
+ MAGICK_SIZE_T='unsigned long long'
+ MAGICK_SIZE_T_F='"I64"'
+ MAGICK_SSIZE_T='signed long long'
+ MAGICK_SSIZE_T_F='"I64"'
+ ;;
+ *)
+ MAGICK_SIZE_T='unsigned long long'
+ MAGICK_SIZE_T_F='"ll"'
+ MAGICK_SSIZE_T='signed long long'
+ MAGICK_SSIZE_T_F='"ll"'
+ ;;
+ esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGICK_SIZE_T_F" >&5
+$as_echo "$MAGICK_SIZE_T_F" >&6; }
+
+
+
+
+
+
+########
+#
+# Check for functions
+#
+########
+for ac_header in stdlib.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in getpagesize
+do :
+ ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize"
+if test "x$ac_cv_func_getpagesize" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPAGESIZE 1
+_ACEOF
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap file i/o" >&5
+$as_echo_n "checking for working mmap file i/o... " >&6; }
+if ${gm_cv_func_mmap_fileio+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ gm_cv_func_mmap_fileio=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/*
+ This test is derived from GNU Autoconf's similar macro.
+ The purpose of this test is to verify that files may be memory
+ mapped, and that memory mapping and file I/O are coherent.
+
+ The test creates a test file, memory maps the file, updates
+ the file using the memory map, and then reads the file using
+ file I/O to verify that the file contains the updates.
+*/
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !STDC_HEADERS && !HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#if !HAVE_GETPAGESIZE
+/* Assume that all systems that can run configure have sys/param.h. */
+# if !HAVE_SYS_PARAM_H
+# define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+# define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+# if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# ifdef EXEC_PAGESIZE
+# define getpagesize() EXEC_PAGESIZE
+# else /* no EXEC_PAGESIZE */
+# ifdef NBPG
+# define getpagesize() NBPG * CLSIZE
+# ifndef CLSIZE
+# define CLSIZE 1
+# endif /* no CLSIZE */
+# else /* no NBPG */
+# ifdef NBPC
+# define getpagesize() NBPC
+# else /* no NBPC */
+# ifdef PAGESIZE
+# define getpagesize() PAGESIZE
+# endif /* PAGESIZE */
+# endif /* no NBPC */
+# endif /* no NBPG */
+# endif /* no EXEC_PAGESIZE */
+# else /* no HAVE_SYS_PARAM_H */
+# define getpagesize() 8192 /* punt totally */
+# endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int
+main ()
+{
+ char *data = NULL, *data2 = NULL, *data3 = NULL;
+ int i, pagesize;
+ int fd = -1;
+ int exit_status = 0;
+
+ pagesize = getpagesize ();
+
+ /* First, make a file with some known garbage in it. */
+ data = (char *) malloc (pagesize);
+ if (!data)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand ();
+ umask (0);
+ fd = creat ("conftest.mmap", 0600);
+ if (fd < 0)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ if (write (fd, data, pagesize) != pagesize)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ close (fd);
+ fd = -1;
+
+ /* Mmap the file as read/write/shared and verify that we see the
+ same garbage. */
+ fd = open ("conftest.mmap", O_RDWR);
+ if (fd < 0)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ data2 = mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0L);
+ if (data2 == 0)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ {
+ exit_status = 1;
+ goto quit;
+ }
+
+ /* Finally, make sure that changes to the mapped area
+ percolate back to the file as seen by read(). */
+ for (i = 0; i < pagesize; ++i)
+ *(data2 + i) = *(data2 + i) + 1;
+ data3 = (char *) malloc (pagesize);
+ if (!data3)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ if (read (fd, data3, pagesize) != pagesize)
+ {
+ exit_status = 1;
+ goto quit;
+ }
+ for (i = 0; i < pagesize; ++i)
+ if (*(data2 + i) != *(data3 + i))
+ {
+ exit_status = 1;
+ goto quit;
+ }
+quit:
+ if (fd != -1)
+ close (fd);
+ if (data)
+ free (data);
+ if (data2)
+ (void) munmap (data2, pagesize);
+ if (data3)
+ free (data3);
+ exit (exit_status);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gm_cv_func_mmap_fileio=yes
+else
+ gm_cv_func_mmap_fileio=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gm_cv_func_mmap_fileio" >&5
+$as_echo "$gm_cv_func_mmap_fileio" >&6; }
+if test $gm_cv_func_mmap_fileio = yes; then
+
+$as_echo "#define HAVE_MMAP_FILEIO 1" >>confdefs.h
+
+fi
+rm -f conftest.mmap
+
+for ac_func in atoll CryptGenRandom \
+ clock_getres clock_gettime ctime_r _exit fcntl fstatvfs ftime getexecname \
+ getc_unlocked getpagesize getrlimit getpid lltostr localtime_r madvise \
+ _NSGetExecutablePath _pclose pclose poll _popen popen posix_fadvise \
+ posix_fallocate posix_madvise posix_memalign posix_spawnp pread pwrite \
+ putc_unlocked raise rand_r readdir_r readlink realpath select seekdir \
+ setrlimit sigemptyset sigaction spawnvp strerror strerror_r strlcat strlcpy \
+ strtoll sysconf times telldir ulltostr vsprintf vsnprintf qsort_r
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+########
+#
+# Check for function prototypes
+#
+########
+
+ac_fn_c_check_decl "$LINENO" "pread" "ac_cv_have_decl_pread" "
+#include <unistd.h>
+"
+if test "x$ac_cv_have_decl_pread" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_PREAD $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "pwrite" "ac_cv_have_decl_pwrite" "
+#include <unistd.h>
+"
+if test "x$ac_cv_have_decl_pwrite" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_PWRITE $ac_have_decl
+_ACEOF
+
+
+ac_fn_c_check_decl "$LINENO" "strlcpy" "ac_cv_have_decl_strlcpy" "
+#include <strings.h>
+"
+if test "x$ac_cv_have_decl_strlcpy" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRLCPY $ac_have_decl
+_ACEOF
+
+
+ac_fn_c_check_decl "$LINENO" "vsnprintf" "ac_cv_have_decl_vsnprintf" "
+#include <stdio.h>
+#include <stdarg.h>
+"
+if test "x$ac_cv_have_decl_vsnprintf" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VSNPRINTF $ac_have_decl
+_ACEOF
+
+
+#######
+#
+# Check for /dev/urandom device
+#
+#######
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/urandom" >&5
+$as_echo_n "checking for /dev/urandom... " >&6; }
+if ${gm_cv_dev_urandom+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gm_cv_dev_urandom=no
+ if test -c /dev/urandom
+ then
+ gm_cv_dev_urandom=yes
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gm_cv_dev_urandom" >&5
+$as_echo "$gm_cv_dev_urandom" >&6; }
+ if test "${gm_cv_dev_urandom}" = yes
+ then
+
+$as_echo "#define HAVE_DEV_URANDOM 1" >>confdefs.h
+
+ fi
+
+########
+#
+# Try to find a command which reports usable physical memory
+#
+########
+MAGICK_PHYSICAL_MEMORY_COMMAND=''
+case "${host}" in
+ *-*-freebsd* | *-apple-darwin*)
+ # Extract the first word of "sysctl", so it can be a program name with args.
+set dummy sysctl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_SysCtlDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $SysCtlDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SysCtlDelegate="$SysCtlDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_SysCtlDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+SysCtlDelegate=$ac_cv_path_SysCtlDelegate
+if test -n "$SysCtlDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SysCtlDelegate" >&5
+$as_echo "$SysCtlDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "${SysCtlDelegate}X" != 'X'
+ then
+ # "sysctl -n hw.physmem" became available in FreeBSD 2.0
+ # Apple's Darwin is based on FreeBSD and supports sysctl
+ MAGICK_PHYSICAL_MEMORY_COMMAND="${SysCtlDelegate} -n hw.physmem"
+ fi
+ ;;
+esac
+if test "${MAGICK_PHYSICAL_MEMORY_COMMAND}X" != 'X'
+then
+
+cat >>confdefs.h <<_ACEOF
+#define MAGICK_PHYSICAL_MEMORY_COMMAND "${MAGICK_PHYSICAL_MEMORY_COMMAND}"
+_ACEOF
+
+fi
+
+########
+#
+# C++ Support Tests (For Magick++)
+#
+########
+have_magick_plus_plus='no'
+if test "$with_magick_plus_plus" = 'yes'
+then
+ OLIBS="$LIBS"
+ LIBS=''
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+# Full set of headers used ...
+# algorithm cctype cerrno cmath cstdio cstdlib cstring ctime exception
+# functional iomanip iosfwd iostream iterator list string strstream utility
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CXX_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler recognizes bool as a built-in type" >&5
+$as_echo_n "checking whether the compiler recognizes bool as a built-in type... " >&6; }
+if ${ac_cv_cxx_bool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int f(int x){return 1;}
+int f(char x){return 1;}
+int f(bool x){return 1;}
+
+int
+main ()
+{
+bool b = true; return f(b);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_bool=yes
+else
+ ac_cv_cxx_bool=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_bool" >&5
+$as_echo "$ac_cv_cxx_bool" >&6; }
+if test "$ac_cv_cxx_bool" = yes; then
+
+$as_echo "#define HAVE_BOOL /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports const_cast<>" >&5
+$as_echo_n "checking whether the compiler supports const_cast<>... " >&6; }
+if ${ac_cv_cxx_const_cast+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+int x = 0;
+const int& y = x;
+int& z = const_cast<int&>(y);
+return z;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_const_cast=yes
+else
+ ac_cv_cxx_const_cast=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_const_cast" >&5
+$as_echo "$ac_cv_cxx_const_cast" >&6; }
+if test "$ac_cv_cxx_const_cast" = yes; then
+
+$as_echo "#define HAVE_CONST_CAST /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports default template parameters" >&5
+$as_echo_n "checking whether the compiler supports default template parameters... " >&6; }
+if ${ac_cv_cxx_default_template_parameters+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+template<class T = double, int N = 10> class A {public: int f() {return 0;}};
+
+int
+main ()
+{
+A<float> a; return a.f();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_default_template_parameters=yes
+else
+ ac_cv_cxx_default_template_parameters=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_default_template_parameters" >&5
+$as_echo "$ac_cv_cxx_default_template_parameters" >&6; }
+if test "$ac_cv_cxx_default_template_parameters" = yes; then
+
+$as_echo "#define HAVE_DEFAULT_TEMPLATE_PARAMETERS /**/" >>confdefs.h
+
+fi
+rm -rf SunWS_cache
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports exceptions" >&5
+$as_echo_n "checking whether the compiler supports exceptions... " >&6; }
+if ${ac_cv_cxx_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+try { throw 1; } catch (int i) { return i; }
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_exceptions=yes
+else
+ ac_cv_cxx_exceptions=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_exceptions" >&5
+$as_echo "$ac_cv_cxx_exceptions" >&6; }
+if test "$ac_cv_cxx_exceptions" = yes; then
+
+$as_echo "#define HAVE_EXCEPTIONS /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler implements namespaces" >&5
+$as_echo_n "checking whether the compiler implements namespaces... " >&6; }
+if ${ac_cv_cxx_namespaces+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+namespace Outer { namespace Inner { int i = 0; }}
+int
+main ()
+{
+using namespace Outer::Inner; return i;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_namespaces=yes
+else
+ ac_cv_cxx_namespaces=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_namespaces" >&5
+$as_echo "$ac_cv_cxx_namespaces" >&6; }
+if test "$ac_cv_cxx_namespaces" = yes; then
+
+$as_echo "#define HAVE_NAMESPACES /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the explicit keyword" >&5
+$as_echo_n "checking whether the compiler supports the explicit keyword... " >&6; }
+if ${ac_cv_cxx_explicit+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+class A{public:explicit A(double){}};
+int
+main ()
+{
+double c = 5.0;A x(c);return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_explicit=yes
+else
+ ac_cv_cxx_explicit=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_explicit" >&5
+$as_echo "$ac_cv_cxx_explicit" >&6; }
+if test "$ac_cv_cxx_explicit" = yes; then
+
+$as_echo "#define HAVE_EXPLICIT /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports ISO C++ standard library" >&5
+$as_echo_n "checking whether the compiler supports ISO C++ standard library... " >&6; }
+if ${ac_cv_cxx_have_std+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <iostream>
+#include <map>
+#include <iomanip>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif
+int
+main ()
+{
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_have_std=yes
+else
+ ac_cv_cxx_have_std=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_have_std" >&5
+$as_echo "$ac_cv_cxx_have_std" >&6; }
+if test "$ac_cv_cxx_have_std" = yes; then
+
+$as_echo "#define HAVE_STD /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports Standard Template Library" >&5
+$as_echo_n "checking whether the compiler supports Standard Template Library... " >&6; }
+if ${ac_cv_cxx_have_stl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <list>
+#include <deque>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif
+int
+main ()
+{
+list<int> x; x.push_back(5);
+list<int>::iterator iter = x.begin(); if (iter != x.end()) ++iter; return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_have_stl=yes
+else
+ ac_cv_cxx_have_stl=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_have_stl" >&5
+$as_echo "$ac_cv_cxx_have_stl" >&6; }
+if test "$ac_cv_cxx_have_stl" = yes; then
+
+$as_echo "#define HAVE_STL /**/" >>confdefs.h
+
+fi
+rm -rf SunWS_cache
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports ios::binary" >&5
+$as_echo_n "checking whether the compiler supports ios::binary... " >&6; }
+if ${ac_cv_cxx_ios_binary+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <fstream>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif
+int
+main ()
+{
+
+ifstream in( "/dev/null", ios::binary );
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_ios_binary=yes
+else
+ ac_cv_cxx_ios_binary=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_ios_binary" >&5
+$as_echo "$ac_cv_cxx_ios_binary" >&6; }
+if test "$ac_cv_cxx_ios_binary" = no; then
+
+$as_echo "#define MISSING_STD_IOS_BINARY /**/" >>confdefs.h
+
+fi
+rm -rf SunWS_cache
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports the mutable keyword" >&5
+$as_echo_n "checking whether the compiler supports the mutable keyword... " >&6; }
+if ${ac_cv_cxx_mutable+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+class A { mutable int i;
+ public:
+ int f (int n) const { i = n; return i; }
+ };
+
+int
+main ()
+{
+A a; return a.f (1);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_mutable=yes
+else
+ ac_cv_cxx_mutable=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_mutable" >&5
+$as_echo "$ac_cv_cxx_mutable" >&6; }
+if test "$ac_cv_cxx_mutable" = yes; then
+
+$as_echo "#define HAVE_MUTABLE /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler accepts the new for scoping rules" >&5
+$as_echo_n "checking whether the compiler accepts the new for scoping rules... " >&6; }
+if ${ac_cv_cxx_new_for_scoping+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+ int z = 0;
+ for (int i = 0; i < 10; ++i)
+ z = z + i;
+ for (int i = 0; i < 10; ++i)
+ z = z - i;
+ return z;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_new_for_scoping=yes
+else
+ ac_cv_cxx_new_for_scoping=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_new_for_scoping" >&5
+$as_echo "$ac_cv_cxx_new_for_scoping" >&6; }
+if test "$ac_cv_cxx_new_for_scoping" = yes; then
+
+$as_echo "#define HAVE_NEW_FOR_SCOPING /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports static_cast<>" >&5
+$as_echo_n "checking whether the compiler supports static_cast<>... " >&6; }
+if ${ac_cv_cxx_static_cast+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <typeinfo>
+class Base { public : Base () {} virtual void f () = 0; };
+class Derived : public Base { public : Derived () {} virtual void f () {} };
+int g (Derived&) { return 0; }
+int
+main ()
+{
+
+Derived d; Base& b = d; Derived& s = static_cast<Derived&> (b); return g (s);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_static_cast=yes
+else
+ ac_cv_cxx_static_cast=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_static_cast" >&5
+$as_echo "$ac_cv_cxx_static_cast" >&6; }
+if test "$ac_cv_cxx_static_cast" = yes; then
+
+$as_echo "#define HAVE_STATIC_CAST /**/" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports basic templates" >&5
+$as_echo_n "checking whether the compiler supports basic templates... " >&6; }
+if ${ac_cv_cxx_templates+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+template<class T> class A {public:A(){}};
+template<class T> void f(const A<T>& ){}
+int
+main ()
+{
+
+A<double> d; A<int> i; f(d); f(i); return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_templates=yes
+else
+ ac_cv_cxx_templates=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_templates" >&5
+$as_echo "$ac_cv_cxx_templates" >&6; }
+if test "$ac_cv_cxx_templates" = yes; then
+
+$as_echo "#define HAVE_TEMPLATES /**/" >>confdefs.h
+
+fi
+rm -rf SunWS_cache
+
+
+ # Test for C++ compiler __func__ support
+ if test "$ac_cv_have_CPP__func__" != 'yes' ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler __func__ support" >&5
+$as_echo_n "checking for C++ compiler __func__ support... " >&6; }
+if ${ac_cv_have_CPP__func__+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ const char *func=__func__;
+ return (func != 0 ? 0 : 1);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_have_CPP__func__='yes'
+else
+ ac_cv_have_CPP__func__='no'
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_CPP__func__" >&5
+$as_echo "$ac_cv_have_CPP__func__" >&6; }
+
+ if test "$ac_cv_have_CPP__func__" = 'yes' ; then
+
+$as_echo "#define HAS_CPP__func__ 1" >>confdefs.h
+
+ fi
+ fi
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler is sufficient for Magick++" >&5
+$as_echo_n "checking whether C++ compiler is sufficient for Magick++... " >&6; }
+ if \
+ test $ac_cv_cxx_bool = 'yes' && \
+ test $ac_cv_cxx_const_cast = 'yes' &&
+ test $ac_cv_cxx_default_template_parameters = 'yes' &&
+ test $ac_cv_cxx_exceptions = 'yes' && \
+ test $ac_cv_cxx_explicit = 'yes' && \
+ test $ac_cv_cxx_have_std = 'yes' && \
+ test $ac_cv_cxx_have_stl = 'yes' && \
+ test $ac_cv_cxx_mutable = 'yes' && \
+ test $ac_cv_cxx_namespaces = 'yes' && \
+ test $ac_cv_cxx_new_for_scoping = 'yes' && \
+ test $ac_cv_cxx_static_cast = 'yes' && \
+ test $ac_cv_cxx_templates = 'yes'
+ then
+ have_magick_plus_plus='yes'
+ else
+ have_magick_plus_plus='no (failed tests)'
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_magick_plus_plus" >&5
+$as_echo "$have_magick_plus_plus" >&6; }
+ LIBS="$OLIBS"
+fi
+ if test "$have_magick_plus_plus" = 'yes'; then
+ WITH_MAGICK_PLUS_PLUS_TRUE=
+ WITH_MAGICK_PLUS_PLUS_FALSE='#'
+else
+ WITH_MAGICK_PLUS_PLUS_TRUE='#'
+ WITH_MAGICK_PLUS_PLUS_FALSE=
+fi
+
+
+# Assume that delegate headers and libraries may reside under same
+# directory as GraphicsMagick installation prefix.
+#LDFLAGS="$LDFLAGS -L$LIB_DIR"
+#CPPFLAGS="$CPPFLAGS -I$INCLUDE_DIR"
+MAGICK_API_CPPFLAGS="-I$INCLUDE_DIR/GraphicsMagick $MAGICK_API_CPPFLAGS"
+
+#
+# Find the X11 RGB database
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11 configure files" >&5
+$as_echo_n "checking for X11 configure files... " >&6; }
+if ${gm_cv_x_configure+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /lib/usr/lib/X11 \
+ /usr/X11/lib \
+ /usr/X11R4/lib \
+ /usr/X11R5/lib \
+ /usr/X11R6/lib \
+ /usr/X11R7/lib \
+ /usr/X386/lib \
+ /usr/XFree86/lib/X11 \
+ /usr/athena/lib \
+ /usr/lib \
+ /usr/lib/X11 \
+ /usr/lib/X11R4 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R7 \
+ /usr/local/X11/lib \
+ /usr/local/X11R4/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R7/lib \
+ /usr/local/lib \
+ /usr/local/lib/X11 \
+ /usr/local/lib/X11R4 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R7 \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ /usr/unsupported/lib \
+ /usr/x386/lib \
+ ; \
+ do
+ if test -f "$ac_dir/X11/rgb.txt"
+ then
+ gm_cv_x_configure="$ac_dir/X11/"
+ break
+ elif test -f "$ac_dir/rgb.txt"
+ then
+ gm_cv_x_configure="$ac_dir/"
+ break
+ fi
+
+ done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gm_cv_x_configure" >&5
+$as_echo "$gm_cv_x_configure" >&6; }
+X11ConfigurePath="$gm_cv_x_configure"
+case "${build_os}" in
+ mingw* )
+ X11ConfigurePath=`$WinPathScript "$X11ConfigurePath=" 1`
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define X11ConfigurePath "X11ConfigurePath"
+_ACEOF
+
+
+#
+# Find Posix threads library
+#
+LIB_THREAD=''
+if test "$with_threads" != 'no' && test "$have_threads" = 'yes'
+then
+
+ if test "x$PTHREAD_LIBS" = "x"
+ then
+ case "${host_cpu}-${host_os}" in
+ *-freebsd*)
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+magick_pthread_lib_ok=no
+
+LIB=-lc_r
+save_LIBS="$LIBS"
+LIBS="$LIBS $LIB"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library $LIB" >&5
+$as_echo_n "checking for the pthreads library $LIB... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+ pthread_t th;
+ pthread_join(th, 0);
+ pthread_attr_init(0);
+ pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0);
+ pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ magick_pthread_lib_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${magick_pthread_lib_ok}" >&5
+$as_echo "${magick_pthread_lib_ok}" >&6; }
+if test "$magick_pthread_lib_ok" = yes
+then
+ PTHREAD_LIBS=-lc_r
+ :
+else
+
+ :
+fi
+
+LIBS="$save_LIBS"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ ;;
+ esac
+ fi
+
+ for lib in pthread pthreads
+ do
+ if test "x$PTHREAD_LIBS" = "x" ; then
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+magick_pthread_lib_ok=no
+
+LIB=-l$lib
+save_LIBS="$LIBS"
+LIBS="$LIBS $LIB"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library $LIB" >&5
+$as_echo_n "checking for the pthreads library $LIB... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pthread.h>
+int
+main ()
+{
+ pthread_t th;
+ pthread_join(th, 0);
+ pthread_attr_init(0);
+ pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0);
+ pthread_cleanup_pop(0);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ magick_pthread_lib_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${magick_pthread_lib_ok}" >&5
+$as_echo "${magick_pthread_lib_ok}" >&6; }
+if test "$magick_pthread_lib_ok" = yes
+then
+ PTHREAD_LIBS=-l$lib
+ :
+else
+
+ :
+fi
+
+LIBS="$save_LIBS"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ fi
+ done
+
+ LIB_THREAD="$PTHREAD_LIBS"
+ LIBS="$LIBS $LIB_THREAD"
+fi
+
+
+
+#
+# Check for Solaris-derived libumem
+#
+have_umem='no'
+LIB_UMEM=''
+if test "$with_umem" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for UMEM support " >&5
+$as_echo_n "checking for UMEM support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "umem.h" "ac_cv_header_umem_h" "$ac_includes_default"
+if test "x$ac_cv_header_umem_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for umem_alloc in -lumem" >&5
+$as_echo_n "checking for umem_alloc in -lumem... " >&6; }
+if ${ac_cv_lib_umem_umem_alloc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lumem $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char umem_alloc ();
+int
+main ()
+{
+return umem_alloc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_umem_umem_alloc=yes
+else
+ ac_cv_lib_umem_umem_alloc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_umem_umem_alloc" >&5
+$as_echo "$ac_cv_lib_umem_umem_alloc" >&6; }
+if test "x$ac_cv_lib_umem_umem_alloc" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for umem_free in -lumem" >&5
+$as_echo_n "checking for umem_free in -lumem... " >&6; }
+if ${ac_cv_lib_umem_umem_free+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lumem $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char umem_free ();
+int
+main ()
+{
+return umem_free ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_umem_umem_free=yes
+else
+ ac_cv_lib_umem_umem_free=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_umem_umem_free" >&5
+$as_echo "$ac_cv_lib_umem_umem_free" >&6; }
+if test "x$ac_cv_lib_umem_umem_free" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if umem memory allocation library is complete" >&5
+$as_echo_n "checking if umem memory allocation library is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_umem='no (failed tests)'
+ else
+ LIB_UMEM='-lumem'
+ LIBS="$LIB_UMEM $LIBS"
+
+$as_echo "#define HasUMEM 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_umem='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_umem" = 'yes'; then
+ HasUMEM_TRUE=
+ HasUMEM_FALSE='#'
+else
+ HasUMEM_TRUE='#'
+ HasUMEM_FALSE=
+fi
+
+
+
+
+#
+# Find OpenMP library
+#
+LIB_OMP=''
+if test "${OPENMP_CFLAGS}x" != 'x'
+then
+ if test "${GCC}" = "yes"
+ then
+ # Open64 (passes for GCC but uses different OpenMP implementation)
+ if test "x$LIB_OMP" = x ; then
+ if $CC --version 2>&1 | grep Open64 > /dev/null ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for omp_get_num_procs in -lopenmp" >&5
+$as_echo_n "checking for omp_get_num_procs in -lopenmp... " >&6; }
+if ${ac_cv_lib_openmp_omp_get_num_procs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lopenmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char omp_get_num_procs ();
+int
+main ()
+{
+return omp_get_num_procs ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_openmp_omp_get_num_procs=yes
+else
+ ac_cv_lib_openmp_omp_get_num_procs=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openmp_omp_get_num_procs" >&5
+$as_echo "$ac_cv_lib_openmp_omp_get_num_procs" >&6; }
+if test "x$ac_cv_lib_openmp_omp_get_num_procs" = xyes; then :
+ LIB_OMP="-lopenmp"
+fi
+
+ fi
+ fi
+ # Clang (passes for GCC but uses different OpenMP implementation)
+ if test "x$LIB_OMP" = x ; then
+ if $CC --version 2>&1 | grep clang > /dev/null ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GOMP_parallel_start in -lomp" >&5
+$as_echo_n "checking for GOMP_parallel_start in -lomp... " >&6; }
+if ${ac_cv_lib_omp_GOMP_parallel_start+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lomp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GOMP_parallel_start ();
+int
+main ()
+{
+return GOMP_parallel_start ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_omp_GOMP_parallel_start=yes
+else
+ ac_cv_lib_omp_GOMP_parallel_start=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_omp_GOMP_parallel_start" >&5
+$as_echo "$ac_cv_lib_omp_GOMP_parallel_start" >&6; }
+if test "x$ac_cv_lib_omp_GOMP_parallel_start" = xyes; then :
+ LIB_OMP="-lomp"
+fi
+
+ fi
+ fi
+ # GCC
+ if test "x$LIB_OMP" = x ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GOMP_parallel_start in -lgomp" >&5
+$as_echo_n "checking for GOMP_parallel_start in -lgomp... " >&6; }
+if ${ac_cv_lib_gomp_GOMP_parallel_start+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgomp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char GOMP_parallel_start ();
+int
+main ()
+{
+return GOMP_parallel_start ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gomp_GOMP_parallel_start=yes
+else
+ ac_cv_lib_gomp_GOMP_parallel_start=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gomp_GOMP_parallel_start" >&5
+$as_echo "$ac_cv_lib_gomp_GOMP_parallel_start" >&6; }
+if test "x$ac_cv_lib_gomp_GOMP_parallel_start" = xyes; then :
+ LIB_OMP="-lgomp"
+fi
+
+ fi
+ else
+ # Sun CC
+ if test "x$LIB_OMP" = x ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sunw_mp_register_warn in -lmtsk" >&5
+$as_echo_n "checking for sunw_mp_register_warn in -lmtsk... " >&6; }
+if ${ac_cv_lib_mtsk_sunw_mp_register_warn+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmtsk $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sunw_mp_register_warn ();
+int
+main ()
+{
+return sunw_mp_register_warn ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_mtsk_sunw_mp_register_warn=yes
+else
+ ac_cv_lib_mtsk_sunw_mp_register_warn=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mtsk_sunw_mp_register_warn" >&5
+$as_echo "$ac_cv_lib_mtsk_sunw_mp_register_warn" >&6; }
+if test "x$ac_cv_lib_mtsk_sunw_mp_register_warn" = xyes; then :
+ LIB_OMP="-lmtsk"
+fi
+
+ fi
+ # AIX xlc
+ if test "x$LIB_OMP" = x ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _xlsmpFlush in -lxlsmp" >&5
+$as_echo_n "checking for _xlsmpFlush in -lxlsmp... " >&6; }
+if ${ac_cv_lib_xlsmp__xlsmpFlush+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxlsmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _xlsmpFlush ();
+int
+main ()
+{
+return _xlsmpFlush ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xlsmp__xlsmpFlush=yes
+else
+ ac_cv_lib_xlsmp__xlsmpFlush=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xlsmp__xlsmpFlush" >&5
+$as_echo "$ac_cv_lib_xlsmp__xlsmpFlush" >&6; }
+if test "x$ac_cv_lib_xlsmp__xlsmpFlush" = xyes; then :
+ LIB_OMP="-lxlsmp"
+fi
+
+ fi
+ # SGI IRIX 6.5 MIPSpro C/C++
+ if test "x$LIB_OMP" = x ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mp_destroy in -lmp" >&5
+$as_echo_n "checking for mp_destroy in -lmp... " >&6; }
+if ${ac_cv_lib_mp_mp_destroy+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char mp_destroy ();
+int
+main ()
+{
+return mp_destroy ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_mp_mp_destroy=yes
+else
+ ac_cv_lib_mp_mp_destroy=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mp_mp_destroy" >&5
+$as_echo "$ac_cv_lib_mp_mp_destroy" >&6; }
+if test "x$ac_cv_lib_mp_mp_destroy" = xyes; then :
+ LIB_OMP="-lmp"
+fi
+
+ fi
+ fi
+ LIBS="$LIB_OMP $LIBS"
+fi
+
+
+#
+# Find math library
+#
+LIB_MATH=''
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5
+$as_echo_n "checking for sqrt in -lm... " >&6; }
+if ${ac_cv_lib_m_sqrt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sqrt ();
+int
+main ()
+{
+return sqrt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sqrt=yes
+else
+ ac_cv_lib_m_sqrt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5
+$as_echo "$ac_cv_lib_m_sqrt" >&6; }
+if test "x$ac_cv_lib_m_sqrt" = xyes; then :
+ LIB_MATH="-lm"
+fi
+
+LIBS="$LIB_MATH $LIBS"
+
+
+
+#
+# If vsnprintf is missing, look for TRIO
+#
+have_trio='no'
+LIB_TRIO=''
+if test "$ac_cv_func_vsnprintf" != 'yes' && test "$with_trio" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TRIO vsnprintf replacement" >&5
+$as_echo_n "checking for TRIO vsnprintf replacement... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for trio_vsnprintf in -ltrio" >&5
+$as_echo_n "checking for trio_vsnprintf in -ltrio... " >&6; }
+if ${ac_cv_lib_trio_trio_vsnprintf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltrio $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char trio_vsnprintf ();
+int
+main ()
+{
+return trio_vsnprintf ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_trio_trio_vsnprintf=yes
+else
+ ac_cv_lib_trio_trio_vsnprintf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_trio_trio_vsnprintf" >&5
+$as_echo "$ac_cv_lib_trio_trio_vsnprintf" >&6; }
+if test "x$ac_cv_lib_trio_trio_vsnprintf" = xyes; then :
+ have_trio='yes'
+fi
+
+ if test "$have_trio" = 'yes'
+ then
+ LIB_TRIO="-ltrio"
+ LIBS="$LIB_TRIO $LIBS"
+
+$as_echo "#define HasTRIO 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+
+
+
+#
+# Optionally check for libltdl if using it is still enabled
+#
+# Only use/depend on libtdl if we are building modules. This is a
+# change from previous releases (prior to 1.3.17) which supported
+# loaded modules via libtdl if shared libraries were built. of
+# whether modules are built or not.
+have_ltdl='no'
+LIB_LTDL=''
+if test "$build_modules" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libltdl " >&5
+$as_echo_n "checking for libltdl ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "ltdl.h" "ac_cv_header_ltdl_h" "$ac_includes_default"
+if test "x$ac_cv_header_ltdl_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lt_dlinit in -lltdl" >&5
+$as_echo_n "checking for lt_dlinit in -lltdl... " >&6; }
+if ${ac_cv_lib_ltdl_lt_dlinit+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lltdl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char lt_dlinit ();
+int
+main ()
+{
+return lt_dlinit ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ltdl_lt_dlinit=yes
+else
+ ac_cv_lib_ltdl_lt_dlinit=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ltdl_lt_dlinit" >&5
+$as_echo "$ac_cv_lib_ltdl_lt_dlinit" >&6; }
+if test "x$ac_cv_lib_ltdl_lt_dlinit" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libltdl package is complete" >&5
+$as_echo_n "checking if libltdl package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_ltdl='no (failed tests)'
+ else
+ LIB_LTDL='-lltdl'
+ LIBS="$LIB_LTDL $LIBS"
+
+$as_echo "#define HasLTDL 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_ltdl='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ if test "$have_ltdl" != 'yes'
+ then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 1 "libltdl is required by modules build
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+fi
+ if test "$have_ltdl" != 'no'; then
+ WITH_LTDL_TRUE=
+ WITH_LTDL_FALSE='#'
+else
+ WITH_LTDL_TRUE='#'
+ WITH_LTDL_FALSE=
+fi
+
+
+#
+# Check for ZLIB
+#
+have_zlib='no'
+LIB_ZLIB=''
+if test "$with_zlib" != 'no' || test "$with_png" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZLIB support " >&5
+$as_echo_n "checking for ZLIB support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "zconf.h" "ac_cv_header_zconf_h" "$ac_includes_default"
+if test "x$ac_cv_header_zconf_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5
+$as_echo_n "checking for compress in -lz... " >&6; }
+if ${ac_cv_lib_z_compress+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char compress ();
+int
+main ()
+{
+return compress ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_compress=yes
+else
+ ac_cv_lib_z_compress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5
+$as_echo "$ac_cv_lib_z_compress" >&6; }
+if test "x$ac_cv_lib_z_compress" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uncompress in -lz" >&5
+$as_echo_n "checking for uncompress in -lz... " >&6; }
+if ${ac_cv_lib_z_uncompress+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uncompress ();
+int
+main ()
+{
+return uncompress ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_uncompress=yes
+else
+ ac_cv_lib_z_uncompress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_uncompress" >&5
+$as_echo "$ac_cv_lib_z_uncompress" >&6; }
+if test "x$ac_cv_lib_z_uncompress" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5
+$as_echo_n "checking for deflate in -lz... " >&6; }
+if ${ac_cv_lib_z_deflate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char deflate ();
+int
+main ()
+{
+return deflate ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_deflate=yes
+else
+ ac_cv_lib_z_deflate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5
+$as_echo "$ac_cv_lib_z_deflate" >&6; }
+if test "x$ac_cv_lib_z_deflate" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflate in -lz" >&5
+$as_echo_n "checking for inflate in -lz... " >&6; }
+if ${ac_cv_lib_z_inflate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inflate ();
+int
+main ()
+{
+return inflate ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_inflate=yes
+else
+ ac_cv_lib_z_inflate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflate" >&5
+$as_echo "$ac_cv_lib_z_inflate" >&6; }
+if test "x$ac_cv_lib_z_inflate" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzseek in -lz" >&5
+$as_echo_n "checking for gzseek in -lz... " >&6; }
+if ${ac_cv_lib_z_gzseek+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gzseek ();
+int
+main ()
+{
+return gzseek ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_gzseek=yes
+else
+ ac_cv_lib_z_gzseek=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzseek" >&5
+$as_echo "$ac_cv_lib_z_gzseek" >&6; }
+if test "x$ac_cv_lib_z_gzseek" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gztell in -lz" >&5
+$as_echo_n "checking for gztell in -lz... " >&6; }
+if ${ac_cv_lib_z_gztell+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gztell ();
+int
+main ()
+{
+return gztell ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_gztell=yes
+else
+ ac_cv_lib_z_gztell=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gztell" >&5
+$as_echo "$ac_cv_lib_z_gztell" >&6; }
+if test "x$ac_cv_lib_z_gztell" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ZLIB package is complete" >&5
+$as_echo_n "checking if ZLIB package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_zlib='no (failed tests)'
+ else
+ LIB_ZLIB='-lz'
+ LIBS="$LIB_ZLIB $LIBS"
+
+$as_echo "#define HasZLIB 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_zlib='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_zlib" = 'yes'; then
+ HasZLIB_TRUE=
+ HasZLIB_FALSE='#'
+else
+ HasZLIB_TRUE='#'
+ HasZLIB_FALSE=
+fi
+
+
+
+#
+# Check for BZLIB
+#
+have_bzlib='no'
+if test "$with_bzlib" != 'no'
+then
+ LIB_BZLIB=''
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZLIB support " >&5
+$as_echo_n "checking for BZLIB support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ found_libbz=0
+ ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_bzlib_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzDecompress in -lbz2" >&5
+$as_echo_n "checking for BZ2_bzDecompress in -lbz2... " >&6; }
+if ${ac_cv_lib_bz2_BZ2_bzDecompress+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbz2 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char BZ2_bzDecompress ();
+int
+main ()
+{
+return BZ2_bzDecompress ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_bz2_BZ2_bzDecompress=yes
+else
+ ac_cv_lib_bz2_BZ2_bzDecompress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzDecompress" >&5
+$as_echo "$ac_cv_lib_bz2_BZ2_bzDecompress" >&6; }
+if test "x$ac_cv_lib_bz2_BZ2_bzDecompress" = xyes; then :
+ found_libbz=`expr $found_libbz + 1`
+fi
+
+ if test "$native_win32_build" = 'yes'
+ then
+ # Under MinGW, libbz2 obfuscates its functions by declaring them
+ # with DLL interfaces. This would be all better if we could
+ # somehow include bzlib.h during the test but Autoconf does not
+ # make that possible. We check for BZ2_decompress since that is
+ # one of the few functions exported from the DLL (very strange).
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _imp__BZ2_decompress in -lbz2" >&5
+$as_echo_n "checking for _imp__BZ2_decompress in -lbz2... " >&6; }
+if ${ac_cv_lib_bz2__imp__BZ2_decompress+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbz2 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _imp__BZ2_decompress ();
+int
+main ()
+{
+return _imp__BZ2_decompress ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_bz2__imp__BZ2_decompress=yes
+else
+ ac_cv_lib_bz2__imp__BZ2_decompress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2__imp__BZ2_decompress" >&5
+$as_echo "$ac_cv_lib_bz2__imp__BZ2_decompress" >&6; }
+if test "x$ac_cv_lib_bz2__imp__BZ2_decompress" = xyes; then :
+ found_libbz=`expr $found_libbz + 1`
+fi
+
+ fi
+ if test $found_libbz -gt 0
+ then
+ passed=`expr $passed + 1`
+ else
+ failed=`expr $failed + 1`
+ fi
+ #AC_CHECK_LIB(bz2,BZ2_bzCompress,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ #AC_CHECK_LIB(bz2,BZ2_bzDecompress,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ #AC_CHECK_LIB(bz2,_imp__BZ2_decompress,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if BZLIB package is complete" >&5
+$as_echo_n "checking if BZLIB package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_bzlib='no (failed tests)'
+ else
+ LIB_BZLIB='-lbz2'
+ LIBS="$LIB_BZLIB $LIBS"
+
+$as_echo "#define HasBZLIB 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_bzlib='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_bzlib" = 'yes'; then
+ HasBZLIB_TRUE=
+ HasBZLIB_FALSE='#'
+else
+ HasBZLIB_TRUE='#'
+ HasBZLIB_FALSE=
+fi
+
+
+
+#
+# Check for LZMA
+#
+have_lzma='no'
+LIB_LZMA=''
+if test "$with_lzma" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZMA support " >&5
+$as_echo_n "checking for LZMA support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default"
+if test "x$ac_cv_header_lzma_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_code in -llzma" >&5
+$as_echo_n "checking for lzma_code in -llzma... " >&6; }
+if ${ac_cv_lib_lzma_lzma_code+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-llzma $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char lzma_code ();
+int
+main ()
+{
+return lzma_code ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_lzma_lzma_code=yes
+else
+ ac_cv_lib_lzma_lzma_code=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_code" >&5
+$as_echo "$ac_cv_lib_lzma_lzma_code" >&6; }
+if test "x$ac_cv_lib_lzma_lzma_code" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if LZMA package is complete" >&5
+$as_echo_n "checking if LZMA package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_lzma='no (failed tests)'
+ else
+ LIB_LZMA='-llzma'
+ LIBS="$LIB_LZMA $LIBS"
+
+$as_echo "#define HasLZMA 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_lzma='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_lzma" = 'yes'; then
+ HasLZMA_TRUE=
+ HasLZMA_FALSE='#'
+else
+ HasLZMA_TRUE='#'
+ HasLZMA_FALSE=
+fi
+
+
+
+#
+# Find the X11 include and library directories.
+#
+LIB_X11=''
+LIB_XEXT=''
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5
+$as_echo_n "checking for X... " >&6; }
+
+
+# Check whether --with-x was given.
+if test "${with_x+set}" = set; then :
+ withval=$with_x;
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+ # The user explicitly disabled X.
+ have_x=disabled
+else
+ case $x_includes,$x_libraries in #(
+ *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
+ *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=no ac_x_libraries=no
+rm -f -r conftest.dir
+if mkdir conftest.dir; then
+ cd conftest.dir
+ cat >Imakefile <<'_ACEOF'
+incroot:
+ @echo incroot='${INCROOT}'
+usrlibdir:
+ @echo usrlibdir='${USRLIBDIR}'
+libdir:
+ @echo libdir='${LIBDIR}'
+_ACEOF
+ if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then
+ # GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+ for ac_var in incroot usrlibdir libdir; do
+ eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`"
+ done
+ # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+ for ac_extension in a so sl dylib la dll; do
+ if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" &&
+ test -f "$ac_im_libdir/libX11.$ac_extension"; then
+ ac_im_usrlibdir=$ac_im_libdir; break
+ fi
+ done
+ # Screen out bogus values from the imake configuration. They are
+ # bogus both because they are the default anyway, and because
+ # using them would break gcc on systems where it needs fixed includes.
+ case $ac_im_incroot in
+ /usr/include) ac_x_includes= ;;
+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
+ esac
+ case $ac_im_usrlibdir in
+ /usr/lib | /usr/lib64 | /lib | /lib64) ;;
+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
+ esac
+ fi
+ cd ..
+ rm -f -r conftest.dir
+fi
+
+# Standard set of common directories for X headers.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ac_x_header_dirs='
+/usr/X11/include
+/usr/X11R7/include
+/usr/X11R6/include
+/usr/X11R5/include
+/usr/X11R4/include
+
+/usr/include/X11
+/usr/include/X11R7
+/usr/include/X11R6
+/usr/include/X11R5
+/usr/include/X11R4
+
+/usr/local/X11/include
+/usr/local/X11R7/include
+/usr/local/X11R6/include
+/usr/local/X11R5/include
+/usr/local/X11R4/include
+
+/usr/local/include/X11
+/usr/local/include/X11R7
+/usr/local/include/X11R6
+/usr/local/include/X11R5
+/usr/local/include/X11R4
+
+/usr/X386/include
+/usr/x386/include
+/usr/XFree86/include/X11
+
+/usr/include
+/usr/local/include
+/usr/unsupported/include
+/usr/athena/include
+/usr/local/x11r5/include
+/usr/lpp/Xamples/include
+
+/usr/openwin/include
+/usr/openwin/share/include'
+
+if test "$ac_x_includes" = no; then
+ # Guess where to find include files, by looking for Xlib.h.
+ # First, try using that file with no special directory specified.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <X11/Xlib.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+ for ac_dir in $ac_x_header_dirs; do
+ if test -r "$ac_dir/X11/Xlib.h"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+done
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+fi # $ac_x_includes = no
+
+if test "$ac_x_libraries" = no; then
+ # Check for the libraries.
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS=$LIBS
+ LIBS="-lX11 $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <X11/Xlib.h>
+int
+main ()
+{
+XrmInitialize ()
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ LIBS=$ac_save_LIBS
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+ LIBS=$ac_save_LIBS
+for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
+do
+ # Don't even attempt the hair of trying to link an X program!
+ for ac_extension in a so sl dylib la dll; do
+ if test -r "$ac_dir/libX11.$ac_extension"; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi # $ac_x_libraries = no
+
+case $ac_x_includes,$ac_x_libraries in #(
+ no,* | *,no | *\'*)
+ # Didn't find X, or a directory has "'" in its name.
+ ac_cv_have_x="have_x=no";; #(
+ *)
+ # Record where we found X for the cache.
+ ac_cv_have_x="have_x=yes\
+ ac_x_includes='$ac_x_includes'\
+ ac_x_libraries='$ac_x_libraries'"
+esac
+fi
+;; #(
+ *) have_x=yes;;
+ esac
+ eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5
+$as_echo "$have_x" >&6; }
+ no_x=yes
+else
+ # If each of the values was on the command line, it overrides each guess.
+ test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+ test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+ # Update the cache value to reflect the command line values.
+ ac_cv_have_x="have_x=yes\
+ ac_x_includes='$x_includes'\
+ ac_x_libraries='$x_libraries'"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5
+$as_echo "libraries $x_libraries, headers $x_includes" >&6; }
+fi
+
+if test "$no_x" = yes; then
+ # Not all programs may use this symbol, but it does not hurt to define it.
+
+$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h
+
+ X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+ if test -n "$x_includes"; then
+ X_CFLAGS="$X_CFLAGS -I$x_includes"
+ fi
+
+ # It would also be nice to do this for all -L options, not just this one.
+ if test -n "$x_libraries"; then
+ X_LIBS="$X_LIBS -L$x_libraries"
+ # For Solaris; some versions of Sun CC require a space after -R and
+ # others require no space. Words are not sufficient . . . .
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5
+$as_echo_n "checking whether -R must be followed by a space... " >&6; }
+ ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries"
+ ac_xsave_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ X_LIBS="$X_LIBS -R$x_libraries"
+else
+ LIBS="$ac_xsave_LIBS -R $x_libraries"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ X_LIBS="$X_LIBS -R $x_libraries"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5
+$as_echo "neither works" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_c_werror_flag=$ac_xsave_c_werror_flag
+ LIBS=$ac_xsave_LIBS
+ fi
+
+ # Check for system-dependent libraries X programs must link with.
+ # Do this before checking for the system-independent R6 libraries
+ # (-lICE), since we may need -lsocket or whatever for X linking.
+
+ if test "$ISC" = yes; then
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+ else
+ # Martyn Johnson says this is needed for Ultrix, if the X
+ # libraries were built with DECnet support. And Karl Berry says
+ # the Alpha needs dnet_stub (dnet does not exist).
+ ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XOpenDisplay ();
+int
+main ()
+{
+return XOpenDisplay ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5
+$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; }
+if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dnet_ntoa ();
+int
+main ()
+{
+return dnet_ntoa ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dnet_dnet_ntoa=yes
+else
+ ac_cv_lib_dnet_dnet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
+$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; }
+if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then :
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+fi
+
+ if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5
+$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; }
+if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldnet_stub $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dnet_ntoa ();
+int
+main ()
+{
+return dnet_ntoa ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dnet_stub_dnet_ntoa=yes
+else
+ ac_cv_lib_dnet_stub_dnet_ntoa=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
+$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; }
+if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then :
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+fi
+
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$ac_xsave_LIBS"
+
+ # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+ # to get the SysV transport functions.
+ # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4)
+ # needs -lnsl.
+ # The nsl library prevents programs from opening the X display
+ # on Irix 5.2, according to T.E. Dickey.
+ # The functions gethostbyname, getservbyname, and inet_addr are
+ # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
+ ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+
+fi
+
+ if test $ac_cv_func_gethostbyname = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_gethostbyname=yes
+else
+ ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+fi
+
+ if test $ac_cv_lib_nsl_gethostbyname = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5
+$as_echo_n "checking for gethostbyname in -lbsd... " >&6; }
+if ${ac_cv_lib_bsd_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_bsd_gethostbyname=yes
+else
+ ac_cv_lib_bsd_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5
+$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; }
+if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then :
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
+fi
+
+ fi
+ fi
+
+ # lieder@skyler.mavd.honeywell.com says without -lsocket,
+ # socket/setsockopt and other routines are undefined under SCO ODT
+ # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary
+ # on later versions), says Simon Leinen: it contains gethostby*
+ # variants that don't use the name server (or something). -lsocket
+ # must be given before -lnsl if both are needed. We assume that
+ # if connect needs -lnsl, so does gethostbyname.
+ ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
+if test "x$ac_cv_func_connect" = xyes; then :
+
+fi
+
+ if test $ac_cv_func_connect = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5
+$as_echo_n "checking for connect in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_connect+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char connect ();
+int
+main ()
+{
+return connect ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_connect=yes
+else
+ ac_cv_lib_socket_connect=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5
+$as_echo "$ac_cv_lib_socket_connect" >&6; }
+if test "x$ac_cv_lib_socket_connect" = xyes; then :
+ X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+fi
+
+ fi
+
+ # Guillermo Gomez says -lposix is necessary on A/UX.
+ ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove"
+if test "x$ac_cv_func_remove" = xyes; then :
+
+fi
+
+ if test $ac_cv_func_remove = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5
+$as_echo_n "checking for remove in -lposix... " >&6; }
+if ${ac_cv_lib_posix_remove+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lposix $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char remove ();
+int
+main ()
+{
+return remove ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_posix_remove=yes
+else
+ ac_cv_lib_posix_remove=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5
+$as_echo "$ac_cv_lib_posix_remove" >&6; }
+if test "x$ac_cv_lib_posix_remove" = xyes; then :
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+fi
+
+ fi
+
+ # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+ ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat"
+if test "x$ac_cv_func_shmat" = xyes; then :
+
+fi
+
+ if test $ac_cv_func_shmat = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5
+$as_echo_n "checking for shmat in -lipc... " >&6; }
+if ${ac_cv_lib_ipc_shmat+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lipc $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shmat ();
+int
+main ()
+{
+return shmat ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ipc_shmat=yes
+else
+ ac_cv_lib_ipc_shmat=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5
+$as_echo "$ac_cv_lib_ipc_shmat" >&6; }
+if test "x$ac_cv_lib_ipc_shmat" = xyes; then :
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+fi
+
+ fi
+ fi
+
+ # Check for libraries that X11R6 Xt/Xaw programs need.
+ ac_save_LDFLAGS=$LDFLAGS
+ test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+ # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+ # check for ICE first), but we must link in the order -lSM -lICE or
+ # we get undefined symbols. So assume we have SM if we have ICE.
+ # These have to be linked with before -lX11, unlike the other
+ # libraries we check for below, so use a different variable.
+ # John Interrante, Karl Berry
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5
+$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; }
+if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char IceConnectionNumber ();
+int
+main ()
+{
+return IceConnectionNumber ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ICE_IceConnectionNumber=yes
+else
+ ac_cv_lib_ICE_IceConnectionNumber=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
+$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; }
+if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then :
+ X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+fi
+
+ LDFLAGS=$ac_save_LDFLAGS
+
+fi
+
+if test "$no_x" != 'yes'
+then
+ LDFLAGS="$LDFLAGS $X_LIBS"
+ LIB_X11="$X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+ LIBS="$LIB_X11 $LIBS"
+ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+
+
+$as_echo "#define HasX11 1" >>confdefs.h
+
+ #
+ # Check for X11 shared memory extension
+ #
+ # shmctl is required to support the shared memory extension
+ LIB_IPC=''
+ ac_fn_c_check_func "$LINENO" "shmctl" "ac_cv_func_shmctl"
+if test "x$ac_cv_func_shmctl" = xyes; then :
+ have_shmctl='yes'
+fi
+
+ if test "$have_shmctl" != 'yes'
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shmctl" >&5
+$as_echo_n "checking for library containing shmctl... " >&6; }
+if ${ac_cv_search_shmctl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shmctl ();
+int
+main ()
+{
+return shmctl ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' cygipc; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_shmctl=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_shmctl+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_shmctl+:} false; then :
+
+else
+ ac_cv_search_shmctl=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shmctl" >&5
+$as_echo "$ac_cv_search_shmctl" >&6; }
+ac_res=$ac_cv_search_shmctl
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ have_shmctl='yes'; LIB_IPC='-lcygipc'
+fi
+
+ fi
+
+ if test "$have_shmctl" = 'yes'
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XShmAttach in -lXext" >&5
+$as_echo_n "checking for XShmAttach in -lXext... " >&6; }
+if ${ac_cv_lib_Xext_XShmAttach+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXext $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XShmAttach ();
+int
+main ()
+{
+return XShmAttach ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_Xext_XShmAttach=yes
+else
+ ac_cv_lib_Xext_XShmAttach=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XShmAttach" >&5
+$as_echo "$ac_cv_lib_Xext_XShmAttach" >&6; }
+if test "x$ac_cv_lib_Xext_XShmAttach" = xyes; then :
+ LIB_XEXT='-lXext' ;
+$as_echo "#define HasSharedMemory 1" >>confdefs.h
+
+fi
+
+ fi
+
+ #
+ # Check for X11 shape extension
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XShapeCombineMask in -lXext" >&5
+$as_echo_n "checking for XShapeCombineMask in -lXext... " >&6; }
+if ${ac_cv_lib_Xext_XShapeCombineMask+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lXext $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XShapeCombineMask ();
+int
+main ()
+{
+return XShapeCombineMask ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_Xext_XShapeCombineMask=yes
+else
+ ac_cv_lib_Xext_XShapeCombineMask=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XShapeCombineMask" >&5
+$as_echo "$ac_cv_lib_Xext_XShapeCombineMask" >&6; }
+if test "x$ac_cv_lib_Xext_XShapeCombineMask" = xyes; then :
+ LIB_XEXT='-lXext' ;
+$as_echo "#define HasShape 1" >>confdefs.h
+
+fi
+
+
+ LIBS="$LIB_XEXT $LIBS"
+fi
+if test "$no_x" != 'yes'
+then
+ have_x='yes'
+else
+ have_x='no'
+fi
+ if test "$have_x" = 'yes'; then
+ HasX11_TRUE=
+ HasX11_FALSE='#'
+else
+ HasX11_TRUE='#'
+ HasX11_FALSE=
+fi
+
+
+
+
+#
+# If profiling, then check for -ldl and dlopen (required for Solaris & gcc)
+#
+LIB_DL=''
+if test "$with_profiling" = 'yes'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ LIB_DL='-ldl'
+fi
+
+ LIBS="$LIB_DL $LIBS"
+fi
+
+
+#
+# Check for Display Postscript
+#
+have_dps='no'
+LIB_DPS=''
+if test "$with_dps" != 'no' && test "$with_x" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Display Postscript support " >&5
+$as_echo_n "checking for Display Postscript support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ O_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I${ac_x_includes}/X11"
+ ac_fn_c_check_header_mongrel "$LINENO" "DPS/dpsXclient.h" "ac_cv_header_DPS_dpsXclient_h" "$ac_includes_default"
+if test "x$ac_cv_header_DPS_dpsXclient_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ # DPS issues:
+ # XFree86-4.x needs -lXt to provide XtMalloc for -ldps.
+ # Cygwin doesn't deliver -lXt as a DLL, which prevents a DLL build.
+ # Adobe DPS (as delivered on Solaris) doesn't require -lXt.
+ # GraphicsMagick itself doesn't use -lXt.
+ have_libdps='no'
+ LIBDPS_XT=''
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DPSInitialize in -ldps" >&5
+$as_echo_n "checking for DPSInitialize in -ldps... " >&6; }
+if ${ac_cv_lib_dps_DPSInitialize+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldps $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char DPSInitialize ();
+int
+main ()
+{
+return DPSInitialize ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dps_DPSInitialize=yes
+else
+ ac_cv_lib_dps_DPSInitialize=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dps_DPSInitialize" >&5
+$as_echo "$ac_cv_lib_dps_DPSInitialize" >&6; }
+if test "x$ac_cv_lib_dps_DPSInitialize" = xyes; then :
+ have_libdps='yes'
+else
+ have_libdps='no'
+fi
+
+ if test "$have_libdps" != 'yes'
+ then
+ # Unset cache variable so we can try again.
+ unset ac_cv_lib_dps_DPSInitialize
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DPSInitialize in -ldps" >&5
+$as_echo_n "checking for DPSInitialize in -ldps... " >&6; }
+if ${ac_cv_lib_dps_DPSInitialize+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldps -lXt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char DPSInitialize ();
+int
+main ()
+{
+return DPSInitialize ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dps_DPSInitialize=yes
+else
+ ac_cv_lib_dps_DPSInitialize=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dps_DPSInitialize" >&5
+$as_echo "$ac_cv_lib_dps_DPSInitialize" >&6; }
+if test "x$ac_cv_lib_dps_DPSInitialize" = xyes; then :
+ have_libdps='yes'
+else
+ have_libdps='no'
+fi
+
+ if test "$have_libdps" = 'yes'
+ then
+ LIBDPS_XT='-lXt'
+ fi
+ fi
+ if test "$have_libdps" = 'yes'
+ then
+ passed=`expr $passed + 1`
+ else
+ failed=`expr $failed + 1`
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XDPSPixelsPerPoint in -ldpstk" >&5
+$as_echo_n "checking for XDPSPixelsPerPoint in -ldpstk... " >&6; }
+if ${ac_cv_lib_dpstk_XDPSPixelsPerPoint+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldpstk -ldps $LIBDPS_XT $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char XDPSPixelsPerPoint ();
+int
+main ()
+{
+return XDPSPixelsPerPoint ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dpstk_XDPSPixelsPerPoint=yes
+else
+ ac_cv_lib_dpstk_XDPSPixelsPerPoint=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dpstk_XDPSPixelsPerPoint" >&5
+$as_echo "$ac_cv_lib_dpstk_XDPSPixelsPerPoint" >&6; }
+if test "x$ac_cv_lib_dpstk_XDPSPixelsPerPoint" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if DPS package is complete" >&5
+$as_echo_n "checking if DPS package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_dps='no (failed tests)'
+ CPPFLAGS="$O_CPPFLAGS"
+ else
+ LIB_DPS="-ldpstk -ldps ${LIBDPS_XT}"
+ LIBS="$LIB_DPS $LIBS"
+
+$as_echo "#define HasDPS 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_dps='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CPPFLAGS=$O_CPPFLAGS
+ fi
+fi
+ if test "$have_dps" = 'yes'; then
+ HasDPS_TRUE=
+ HasDPS_FALSE='#'
+else
+ HasDPS_TRUE='#'
+ HasDPS_FALSE=
+fi
+
+
+
+#
+# Check for FlashPIX
+#
+have_fpx='no'
+LIB_FPX=''
+if test "$with_fpx" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FlashPIX components " >&5
+$as_echo_n "checking for FlashPIX components ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_fn_cxx_check_header_mongrel "$LINENO" "fpxlib.h" "ac_cv_header_fpxlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_fpxlib_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FPX_OpenImageByFilename in -lfpx" >&5
+$as_echo_n "checking for FPX_OpenImageByFilename in -lfpx... " >&6; }
+if ${ac_cv_lib_fpx_FPX_OpenImageByFilename+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfpx $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char FPX_OpenImageByFilename ();
+int
+main ()
+{
+return FPX_OpenImageByFilename ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_fpx_FPX_OpenImageByFilename=yes
+else
+ ac_cv_lib_fpx_FPX_OpenImageByFilename=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fpx_FPX_OpenImageByFilename" >&5
+$as_echo "$ac_cv_lib_fpx_FPX_OpenImageByFilename" >&6; }
+if test "x$ac_cv_lib_fpx_FPX_OpenImageByFilename" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if FlashPIX package is complete" >&5
+$as_echo_n "checking if FlashPIX package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_fpx='no (failed tests)'
+ else
+ LIB_FPX='-lfpx'
+ # LIBS="$LIB_FPX $LIBS"
+
+$as_echo "#define HasFPX 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_fpx='yes'
+ PERLMAINCC="$CXX"
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_fpx" = 'yes'; then
+ HasFPX_TRUE=
+ HasFPX_FALSE='#'
+else
+ HasFPX_TRUE='#'
+ HasFPX_FALSE=
+fi
+
+
+
+#
+# Check for LCMS v2
+#
+have_lcms2='no'
+LIB_LCMS=''
+if test "$with_lcms2" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lcms v2 support" >&5
+$as_echo_n "checking for lcms v2 support... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ have_lcms_header='no'
+
+ # Check for <lcms2.h>
+ ac_fn_c_check_header_mongrel "$LINENO" "lcms2.h" "ac_cv_header_lcms2_h" "$ac_includes_default"
+if test "x$ac_cv_header_lcms2_h" = xyes; then :
+ have_lcms_header='yes'
+fi
+
+
+ if test "$have_lcms_header" = 'yes'
+ then
+
+$as_echo "#define HAVE_LCMS2_H 1" >>confdefs.h
+
+ passed=`expr $passed + 1`
+ fi
+
+ # Check for <lcms2/lcms2.h)
+ if test "$have_lcms_header" != 'yes'
+ then
+ ac_fn_c_check_header_mongrel "$LINENO" "lcms2/lcms2.h" "ac_cv_header_lcms2_lcms2_h" "$ac_includes_default"
+if test "x$ac_cv_header_lcms2_lcms2_h" = xyes; then :
+ have_lcms_header='yes'
+fi
+
+
+ if test "$have_lcms_header" = 'yes'
+ then
+ passed=`expr $passed + 1`
+
+$as_echo "#define HAVE_LCMS2_LCMS2_H 1" >>confdefs.h
+
+ fi
+ fi
+
+ # Failed to find lcms header?
+ if test "$have_lcms_header" != 'yes'
+ then
+ failed=`expr $failed + 1`
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cmsSetLogErrorHandler in -llcms2" >&5
+$as_echo_n "checking for cmsSetLogErrorHandler in -llcms2... " >&6; }
+if ${ac_cv_lib_lcms2_cmsSetLogErrorHandler+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-llcms2 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cmsSetLogErrorHandler ();
+int
+main ()
+{
+return cmsSetLogErrorHandler ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_lcms2_cmsSetLogErrorHandler=yes
+else
+ ac_cv_lib_lcms2_cmsSetLogErrorHandler=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lcms2_cmsSetLogErrorHandler" >&5
+$as_echo "$ac_cv_lib_lcms2_cmsSetLogErrorHandler" >&6; }
+if test "x$ac_cv_lib_lcms2_cmsSetLogErrorHandler" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if LCMS v2 package is complete" >&5
+$as_echo_n "checking if LCMS v2 package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_lcms2='no (failed tests)'
+ else
+ LIB_LCMS='-llcms2'
+ LIBS="$LIB_LCMS $LIBS"
+ #AC_DEFINE(HasLCMS2,1,Define if you have LCMS v2 library)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_lcms2='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+
+
+ if test "$have_lcms2" = 'yes'; then
+ HasLCMS_TRUE=
+ HasLCMS_FALSE='#'
+else
+ HasLCMS_TRUE='#'
+ HasLCMS_FALSE=
+fi
+
+if test "$have_lcms2" = 'yes'
+then
+
+$as_echo "#define HasLCMS 1" >>confdefs.h
+
+fi
+
+
+have_png='no'
+LIB_PNG=''
+if test "$have_zlib" = 'yes'
+then
+ #
+ # Check for PNG delegate library.
+ #
+
+# Check whether --with-png was given.
+if test "${with_png+set}" = set; then :
+ withval=$with_png; with_png=$withval
+else
+ with_png='yes'
+fi
+
+
+ if test "$with_png" != 'yes'; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-png=$with_png "
+ fi
+
+
+ if test "$with_png" != 'no' ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PNG support " >&5
+$as_echo_n "checking for PNG support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default"
+if test "x$ac_cv_header_png_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+
+ if test $passed -gt 0; then
+ for var in 7 6 5 4 2 '' ; do
+ if test "x${var}" = 'x' ; then
+ pnglib='png'
+ else
+ pnglib="png1${var}"
+ fi
+ if test "$have_png" = 'no'
+ then
+
+ # Test for compatible LIBPNG library
+ failed=0
+ passed=0
+ if test "$with_png" = 'yes' -o "$with_png" = "libpng1${var}" ; then
+ if test "${pnglib}" != 'png' ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBPNG1${var} support " >&5
+$as_echo_n "checking for LIBPNG1${var} support ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <png.h>
+
+int
+main ()
+{
+
+#if PNG_LIBPNG_VER_MINOR != ${var}
+#error LIBPNG library must be version 1${var}!
+Kaboom, Kaboom
+#endif
+return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_libpng_ok='yes'
+else
+ ac_cv_libpng_ok='no'
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test "$ac_cv_libpng_ok" = 'yes' ; then
+ passed=`expr $passed + 1`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ failed=`expr $failed + 1`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ else
+ passed=`expr $passed + 1`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+ fi
+
+ if test $passed -gt 0 -a $failed -le 0
+ then
+ if test "1${var}" = '15' ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_get_io_ptr in -lpng15" >&5
+$as_echo_n "checking for png_get_io_ptr in -lpng15... " >&6; }
+if ${ac_cv_lib_png15_png_get_io_ptr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng15 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char png_get_io_ptr ();
+int
+main ()
+{
+return png_get_io_ptr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_png15_png_get_io_ptr=yes
+else
+ ac_cv_lib_png15_png_get_io_ptr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png15_png_get_io_ptr" >&5
+$as_echo "$ac_cv_lib_png15_png_get_io_ptr" >&6; }
+if test "x$ac_cv_lib_png15_png_get_io_ptr" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_longjmp in -lpng15" >&5
+$as_echo_n "checking for png_longjmp in -lpng15... " >&6; }
+if ${ac_cv_lib_png15_png_longjmp+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng15 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char png_longjmp ();
+int
+main ()
+{
+return png_longjmp ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_png15_png_longjmp=yes
+else
+ ac_cv_lib_png15_png_longjmp=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png15_png_longjmp" >&5
+$as_echo "$ac_cv_lib_png15_png_longjmp" >&6; }
+if test "x$ac_cv_lib_png15_png_longjmp" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ fi
+ if test "1${var}" = '14' ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_get_io_ptr in -lpng14" >&5
+$as_echo_n "checking for png_get_io_ptr in -lpng14... " >&6; }
+if ${ac_cv_lib_png14_png_get_io_ptr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng14 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char png_get_io_ptr ();
+int
+main ()
+{
+return png_get_io_ptr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_png14_png_get_io_ptr=yes
+else
+ ac_cv_lib_png14_png_get_io_ptr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png14_png_get_io_ptr" >&5
+$as_echo "$ac_cv_lib_png14_png_get_io_ptr" >&6; }
+if test "x$ac_cv_lib_png14_png_get_io_ptr" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_get_io_state in -lpng14" >&5
+$as_echo_n "checking for png_get_io_state in -lpng14... " >&6; }
+if ${ac_cv_lib_png14_png_get_io_state+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng14 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char png_get_io_state ();
+int
+main ()
+{
+return png_get_io_state ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_png14_png_get_io_state=yes
+else
+ ac_cv_lib_png14_png_get_io_state=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png14_png_get_io_state" >&5
+$as_echo "$ac_cv_lib_png14_png_get_io_state" >&6; }
+if test "x$ac_cv_lib_png14_png_get_io_state" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ fi
+ if test "1${var}" = '12' ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_get_io_ptr in -lpng12" >&5
+$as_echo_n "checking for png_get_io_ptr in -lpng12... " >&6; }
+if ${ac_cv_lib_png12_png_get_io_ptr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng12 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char png_get_io_ptr ();
+int
+main ()
+{
+return png_get_io_ptr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_png12_png_get_io_ptr=yes
+else
+ ac_cv_lib_png12_png_get_io_ptr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png12_png_get_io_ptr" >&5
+$as_echo "$ac_cv_lib_png12_png_get_io_ptr" >&6; }
+if test "x$ac_cv_lib_png12_png_get_io_ptr" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ fi
+ if test "1${var}" = '1' ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_get_io_ptr in -lpng" >&5
+$as_echo_n "checking for png_get_io_ptr in -lpng... " >&6; }
+if ${ac_cv_lib_png_png_get_io_ptr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char png_get_io_ptr ();
+int
+main ()
+{
+return png_get_io_ptr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_png_png_get_io_ptr=yes
+else
+ ac_cv_lib_png_png_get_io_ptr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_get_io_ptr" >&5
+$as_echo "$ac_cv_lib_png_png_get_io_ptr" >&6; }
+if test "x$ac_cv_lib_png_png_get_io_ptr" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ fi
+ if test $passed -gt 0 -a $failed -le 0 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${pnglib} package is complete" >&5
+$as_echo_n "checking if ${pnglib} package is complete... " >&6; }
+ if test $passed -gt 0 ; then
+ if test $failed -gt 0 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_png='no (failed tests)'
+ else
+ LIB_PNG="-l${pnglib}"
+ LIBS="$LIB_PNG $LIBS"
+
+$as_echo "#define HasPNG 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_png='yes'
+ fi
+ fi
+ fi
+ fi
+ fi
+ done
+ fi
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: PNG requires zlib support" >&5
+$as_echo "PNG requires zlib support" >&6; }
+fi
+ if test "$have_png" = 'yes'; then
+ HasPNG_TRUE=
+ HasPNG_FALSE='#'
+else
+ HasPNG_TRUE='#'
+ HasPNG_FALSE=
+fi
+
+
+
+#
+# Check for JPEG
+#
+have_jpeg='no'
+LIB_JPEG=''
+if test "$with_jpeg" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JPEG support " >&5
+$as_echo_n "checking for JPEG support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "jconfig.h" "ac_cv_header_jconfig_h" "$ac_includes_default"
+if test "x$ac_cv_header_jconfig_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "jerror.h" "ac_cv_header_jerror_h" "$ac_includes_default"
+if test "x$ac_cv_header_jerror_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "jmorecfg.h" "ac_cv_header_jmorecfg_h" "$ac_includes_default"
+if test "x$ac_cv_header_jmorecfg_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default"
+if test "x$ac_cv_header_jpeglib_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_read_header in -ljpeg" >&5
+$as_echo_n "checking for jpeg_read_header in -ljpeg... " >&6; }
+if ${ac_cv_lib_jpeg_jpeg_read_header+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljpeg $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char jpeg_read_header ();
+int
+main ()
+{
+return jpeg_read_header ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_jpeg_jpeg_read_header=yes
+else
+ ac_cv_lib_jpeg_jpeg_read_header=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_read_header" >&5
+$as_echo "$ac_cv_lib_jpeg_jpeg_read_header" >&6; }
+if test "x$ac_cv_lib_jpeg_jpeg_read_header" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+# Test for compatible JPEG library
+if test "$ac_cv_jpeg_version_ok" != 'yes' ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JPEG library is version 6b or later" >&5
+$as_echo_n "checking for JPEG library is version 6b or later... " >&6; }
+if ${ac_cv_jpeg_version_ok+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <jpeglib.h>
+
+int
+main ()
+{
+
+#if JPEG_LIB_VERSION < 62
+#error IJG JPEG library must be version 6b or newer!
+Kaboom, Kaboom
+#endif
+return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_jpeg_version_ok='yes'
+else
+ ac_cv_jpeg_version_ok='no'
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_jpeg_version_ok" >&5
+$as_echo "$ac_cv_jpeg_version_ok" >&6; }
+if test "$ac_cv_jpeg_version_ok" = 'yes' ; then
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if JPEG package is complete" >&5
+$as_echo_n "checking if JPEG package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_jpeg='no (failed tests)'
+ else
+ LIB_JPEG='-ljpeg'
+ LIBS="$LIB_JPEG $LIBS"
+
+$as_echo "#define HasJPEG 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_jpeg='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_jpeg" = 'yes'; then
+ HasJPEG_TRUE=
+ HasJPEG_FALSE='#'
+else
+ HasJPEG_TRUE='#'
+ HasJPEG_FALSE=
+fi
+
+
+
+#
+# Check for JPEG Version 2
+#
+have_jp2='no'
+LIB_JP2=''
+if test "$with_jp2" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JPEG version 2 support " >&5
+$as_echo_n "checking for JPEG version 2 support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "jasper/jasper.h" "ac_cv_header_jasper_jasper_h" "$ac_includes_default"
+if test "x$ac_cv_header_jasper_jasper_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jas_stream_fopen in -ljasper" >&5
+$as_echo_n "checking for jas_stream_fopen in -ljasper... " >&6; }
+if ${ac_cv_lib_jasper_jas_stream_fopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljasper $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char jas_stream_fopen ();
+int
+main ()
+{
+return jas_stream_fopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_jasper_jas_stream_fopen=yes
+else
+ ac_cv_lib_jasper_jas_stream_fopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jasper_jas_stream_fopen" >&5
+$as_echo "$ac_cv_lib_jasper_jas_stream_fopen" >&6; }
+if test "x$ac_cv_lib_jasper_jas_stream_fopen" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if JPEG version 2 support package is complete" >&5
+$as_echo_n "checking if JPEG version 2 support package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_jp2='no (failed tests)'
+ else
+ LIB_JP2='-ljasper'
+ LIBS="$LIB_JP2 $LIBS"
+
+$as_echo "#define HasJP2 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_jp2='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_jp2" = 'yes'; then
+ HasJP2_TRUE=
+ HasJP2_FALSE='#'
+else
+ HasJP2_TRUE='#'
+ HasJP2_FALSE=
+fi
+
+
+
+#
+# Check for Ghostscript library
+#
+# Test for iapi.h & test for gsapi_new_instance in -lgs
+have_gslib='no'
+LIB_GS=''
+if test "$with_gslib" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Ghostscript library support " >&5
+$as_echo_n "checking for Ghostscript library support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "ghostscript/iapi.h" "ac_cv_header_ghostscript_iapi_h" "$ac_includes_default"
+if test "x$ac_cv_header_ghostscript_iapi_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gsapi_new_instance in -lgs" >&5
+$as_echo_n "checking for gsapi_new_instance in -lgs... " >&6; }
+if ${ac_cv_lib_gs_gsapi_new_instance+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgs $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gsapi_new_instance ();
+int
+main ()
+{
+return gsapi_new_instance ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gs_gsapi_new_instance=yes
+else
+ ac_cv_lib_gs_gsapi_new_instance=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gs_gsapi_new_instance" >&5
+$as_echo "$ac_cv_lib_gs_gsapi_new_instance" >&6; }
+if test "x$ac_cv_lib_gs_gsapi_new_instance" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Ghostscript library package is complete" >&5
+$as_echo_n "checking if Ghostscript library package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_gslib='no (failed tests)'
+ else
+ LIB_GS='-lgs'
+ LIBS="$LIB_GS $LIBS"
+
+$as_echo "#define HasGS 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_gslib='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_gslib" = 'yes'; then
+ HasGS_TRUE=
+ HasGS_FALSE='#'
+else
+ HasGS_TRUE='#'
+ HasGS_FALSE=
+fi
+
+
+
+# #
+# # Check for MPEG2 library
+# #
+# have_mpeg2='no'
+# LIB_MPEG2=''
+# if test "$with_mpeg2" != 'no'
+# then
+# AC_MSG_CHECKING(for MPEG version 2 support )
+# AC_MSG_RESULT()
+# failed=0
+# passed=0
+# AC_CHECK_HEADER(mpeg2dec/mpeg2.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+# AC_CHECK_LIB(mpeg2,mpeg2_decode_data,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+# AC_MSG_CHECKING(if MPEG version 2 support package is complete)
+# if test $passed -gt 0
+# then
+# if test $failed -gt 0
+# then
+# AC_MSG_RESULT(no -- some components failed test)
+# have_mpeg2='no (failed tests)'
+# else
+# LIB_MPEG2='-lmpeg2'
+# LIBS="$LIB_MPEG2 $LIBS"
+# AC_DEFINE(HasMPEG2,1,Define if you have MPEG2 library)
+# AC_MSG_RESULT(yes)
+# have_mpeg2='yes'
+# fi
+# else
+# AC_MSG_RESULT(no)
+# fi
+# fi
+# AM_CONDITIONAL(HasMPEG2, test "$have_mpeg2" = 'yes')
+# AC_SUBST(LIB_MPEG2)
+
+#
+# Check for TTF
+#
+have_ttf='no'
+LIB_TTF=''
+if test "$with_ttf" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeType 2.0 " >&5
+$as_echo_n "checking for FreeType 2.0 ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+
+ OLD_LDFLAGS="$LDFLAGS"
+ OLD_CPPFLAGS="$CPPFLAGS"
+ freetype_config=''
+ # Allow the user to specify the location of freetype.
+ if test "$with_ttf" != 'yes'
+ then
+ if test -x "${with_ttf}/bin/freetype-config"
+ then
+ freetype_config="${with_ttf}/bin/freetype-config"
+ elif test -x "${with_ttf}"
+ then
+ freetype_config=${with_ttf}
+ fi
+ fi
+ if test -z "$freetype_config"
+ then
+ # Extract the first word of "freetype-config", so it can be a program name with args.
+set dummy freetype-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_freetype_config+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $freetype_config in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_freetype_config="$freetype_config" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_freetype_config="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+freetype_config=$ac_cv_path_freetype_config
+if test -n "$freetype_config"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $freetype_config" >&5
+$as_echo "$freetype_config" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ fi
+ if test -n "$freetype_config"
+ then
+ freetype_cflags=`${freetype_config} --cflags`
+ # freetype-config --cflags may output values such as
+ # -I/usr/local/include/freetype2 -I/usr/local/include
+ # Take only the first -I option since non-Freetype include
+ # directories (not needed by the FreeType API) may pollute
+ # the include path.
+ for flag in $freetype_cflags
+ do
+ case $flag in
+ -I*)
+ CPPFLAGS="$CPPFLAGS $flag"
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ # freetype-config --libs may output values such as
+ # -L/usr/local/lib -lfreetype -lz
+ # or
+ # -L/usr/lib/x86_64-linux-gnu -lfreetype -lz -lpng12
+ #
+ # Problems will surely result if we have already successfully
+ # configured different dependency libraries than freetype was
+ # built against. For this reason, we only take the first
+ # argument of each type, assuming that they are specific to
+ # Freetype. In the future we may need to do something different
+ # if the FreeType library was to depend on some weird library
+ # that we don't normally test for.
+ freeype_libs=`${freetype_config} --libs`
+ for flag in $freeype_libs
+ do
+ case $flag in
+ -L*)
+ LDFLAGS="$LDFLAGS $flag"
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ for flag in $freeype_libs
+ do
+ case $flag in
+ -l*)
+ LIB_TTF_BASE=`echo $flag | sed -e 's/^-l//'`
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ fi
+
+ as_ac_Lib=`$as_echo "ac_cv_lib_$LIB_TTF_BASE''_FT_Init_FreeType" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -l$LIB_TTF_BASE" >&5
+$as_echo_n "checking for FT_Init_FreeType in -l$LIB_TTF_BASE... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$LIB_TTF_BASE $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char FT_Init_FreeType ();
+int
+main ()
+{
+return FT_Init_FreeType ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$as_ac_Lib=yes"
+else
+ eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+ LIB_TTF="-l$LIB_TTF_BASE"
+else
+ LIB_TTF=''
+fi
+
+ if test "$LIB_TTF" != ''
+ then
+ passed=`expr $passed + 1`
+ else
+ failed=`expr $failed + 1`
+ LDFLAGS="$OLD_LDFLAGS"
+ fi
+
+ # Modern Freetype2 installs require that <ft2build.h> be included
+ # prior to including any other FreeType2 headers. This header
+ # produces defines which must be used to include remaining API
+ # headers.
+ ac_fn_c_check_header_mongrel "$LINENO" "ft2build.h" "ac_cv_header_ft2build_h" "$ac_includes_default"
+if test "x$ac_cv_header_ft2build_h" = xyes; then :
+ FT2BUILD_H='#include <ft2build.h>' ; have_freetype_h='yes'
+else
+ FT2BUILD_H='' ; have_freetype_h='no'
+fi
+
+
+ if test "${FT2BUILD_H}x" = 'x'
+ then
+ # Last ditch, test old include style where everything is rooted
+ # under 'freetype'
+ ac_fn_c_check_header_mongrel "$LINENO" "freetype/freetype.h" "ac_cv_header_freetype_freetype_h" "$ac_includes_default"
+if test "x$ac_cv_header_freetype_freetype_h" = xyes; then :
+ have_freetype_h='yes'
+else
+ have_freetype_h='no'
+fi
+
+
+ fi
+ if test "$have_freetype_h" = 'yes'
+ then
+ passed=`expr $passed + 1`
+ else
+ failed=`expr $failed + 1`
+ CPPFLAGS="$OLD_CPPFLAGS"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if FreeType package is complete" >&5
+$as_echo_n "checking if FreeType package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ LIB_TTF=''
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_ttf='no (failed tests)'
+ else
+ LIBS="$LIB_TTF $LIBS"
+
+$as_echo "#define HasTTF 1" >>confdefs.h
+
+ if test "$ac_cv_header_ft2build_h" = 'yes'
+ then
+
+$as_echo "#define HAVE_FT2BUILD_H 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_ttf='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_ttf" = 'yes'; then
+ HasTTF_TRUE=
+ HasTTF_FALSE='#'
+else
+ HasTTF_TRUE='#'
+ HasTTF_FALSE=
+fi
+
+
+
+#
+# Check for TIFF
+#
+have_tiff='no'
+LIB_TIFF=''
+if test "$with_tiff" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFF support " >&5
+$as_echo_n "checking for TIFF support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "tiff.h" "ac_cv_header_tiff_h" "$ac_includes_default"
+if test "x$ac_cv_header_tiff_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "tiffio.h" "ac_cv_header_tiffio_h" "$ac_includes_default"
+if test "x$ac_cv_header_tiffio_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFOpen in -ltiff" >&5
+$as_echo_n "checking for TIFFOpen in -ltiff... " >&6; }
+if ${ac_cv_lib_tiff_TIFFOpen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltiff $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char TIFFOpen ();
+int
+main ()
+{
+return TIFFOpen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_tiff_TIFFOpen=yes
+else
+ ac_cv_lib_tiff_TIFFOpen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFOpen" >&5
+$as_echo "$ac_cv_lib_tiff_TIFFOpen" >&6; }
+if test "x$ac_cv_lib_tiff_TIFFOpen" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFClientOpen in -ltiff" >&5
+$as_echo_n "checking for TIFFClientOpen in -ltiff... " >&6; }
+if ${ac_cv_lib_tiff_TIFFClientOpen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltiff $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char TIFFClientOpen ();
+int
+main ()
+{
+return TIFFClientOpen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_tiff_TIFFClientOpen=yes
+else
+ ac_cv_lib_tiff_TIFFClientOpen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFClientOpen" >&5
+$as_echo "$ac_cv_lib_tiff_TIFFClientOpen" >&6; }
+if test "x$ac_cv_lib_tiff_TIFFClientOpen" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFIsByteSwapped in -ltiff" >&5
+$as_echo_n "checking for TIFFIsByteSwapped in -ltiff... " >&6; }
+if ${ac_cv_lib_tiff_TIFFIsByteSwapped+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltiff $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char TIFFIsByteSwapped ();
+int
+main ()
+{
+return TIFFIsByteSwapped ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_tiff_TIFFIsByteSwapped=yes
+else
+ ac_cv_lib_tiff_TIFFIsByteSwapped=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFIsByteSwapped" >&5
+$as_echo "$ac_cv_lib_tiff_TIFFIsByteSwapped" >&6; }
+if test "x$ac_cv_lib_tiff_TIFFIsByteSwapped" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFReadRGBATile in -ltiff" >&5
+$as_echo_n "checking for TIFFReadRGBATile in -ltiff... " >&6; }
+if ${ac_cv_lib_tiff_TIFFReadRGBATile+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltiff $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char TIFFReadRGBATile ();
+int
+main ()
+{
+return TIFFReadRGBATile ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_tiff_TIFFReadRGBATile=yes
+else
+ ac_cv_lib_tiff_TIFFReadRGBATile=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFReadRGBATile" >&5
+$as_echo "$ac_cv_lib_tiff_TIFFReadRGBATile" >&6; }
+if test "x$ac_cv_lib_tiff_TIFFReadRGBATile" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFReadRGBAStrip in -ltiff" >&5
+$as_echo_n "checking for TIFFReadRGBAStrip in -ltiff... " >&6; }
+if ${ac_cv_lib_tiff_TIFFReadRGBAStrip+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltiff $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char TIFFReadRGBAStrip ();
+int
+main ()
+{
+return TIFFReadRGBAStrip ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_tiff_TIFFReadRGBAStrip=yes
+else
+ ac_cv_lib_tiff_TIFFReadRGBAStrip=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFReadRGBAStrip" >&5
+$as_echo "$ac_cv_lib_tiff_TIFFReadRGBAStrip" >&6; }
+if test "x$ac_cv_lib_tiff_TIFFReadRGBAStrip" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if TIFF package is complete" >&5
+$as_echo_n "checking if TIFF package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_tiff='no (failed tests)'
+ else
+ LIB_TIFF='-ltiff'
+ LIBS="$LIB_TIFF $LIBS"
+
+$as_echo "#define HasTIFF 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_tiff='yes'
+ for ac_header in tiffconf.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "tiffconf.h" "ac_cv_header_tiffconf_h" "$ac_includes_default"
+if test "x$ac_cv_header_tiffconf_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_TIFFCONF_H 1
+_ACEOF
+
+fi
+
+done
+
+ for ac_func in TIFFIsCODECConfigured \
+ TIFFMergeFieldInfo \
+ TIFFSetErrorHandlerExt \
+ TIFFSetTagExtender \
+ TIFFSetWarningHandlerExt \
+ TIFFSwabArrayOfTriples
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_tiff" = 'yes'; then
+ HasTIFF_TRUE=
+ HasTIFF_FALSE='#'
+else
+ HasTIFF_TRUE='#'
+ HasTIFF_FALSE=
+fi
+
+
+
+#
+# Check for JBIG
+#
+have_jbig='no'
+LIB_JBIG=''
+if test "$with_jbig" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JBIG support " >&5
+$as_echo_n "checking for JBIG support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "jbig.h" "ac_cv_header_jbig_h" "$ac_includes_default"
+if test "x$ac_cv_header_jbig_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jbg_dec_init in -ljbig" >&5
+$as_echo_n "checking for jbg_dec_init in -ljbig... " >&6; }
+if ${ac_cv_lib_jbig_jbg_dec_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljbig $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char jbg_dec_init ();
+int
+main ()
+{
+return jbg_dec_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_jbig_jbg_dec_init=yes
+else
+ ac_cv_lib_jbig_jbg_dec_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jbig_jbg_dec_init" >&5
+$as_echo "$ac_cv_lib_jbig_jbg_dec_init" >&6; }
+if test "x$ac_cv_lib_jbig_jbg_dec_init" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if JBIG package is complete" >&5
+$as_echo_n "checking if JBIG package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_jbig='no (failed tests)'
+ else
+ LIB_JBIG='-ljbig'
+ LIBS="$LIB_JBIG $LIBS"
+
+$as_echo "#define HasJBIG 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_jbig='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_jbig" = 'yes'; then
+ HasJBIG_TRUE=
+ HasJBIG_FALSE='#'
+else
+ HasJBIG_TRUE='#'
+ HasJBIG_FALSE=
+fi
+
+
+
+#
+# Check for WEBP
+#
+have_webp='no'
+LIB_WEBP=''
+if test "$with_webp" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for WEBP support " >&5
+$as_echo_n "checking for WEBP support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ failed=0
+ passed=0
+ ac_fn_c_check_header_mongrel "$LINENO" "webp/decode.h" "ac_cv_header_webp_decode_h" "$ac_includes_default"
+if test "x$ac_cv_header_webp_decode_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for WebPDecodeRGB in -lwebp" >&5
+$as_echo_n "checking for WebPDecodeRGB in -lwebp... " >&6; }
+if ${ac_cv_lib_webp_WebPDecodeRGB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lwebp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char WebPDecodeRGB ();
+int
+main ()
+{
+return WebPDecodeRGB ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_webp_WebPDecodeRGB=yes
+else
+ ac_cv_lib_webp_WebPDecodeRGB=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_webp_WebPDecodeRGB" >&5
+$as_echo "$ac_cv_lib_webp_WebPDecodeRGB" >&6; }
+if test "x$ac_cv_lib_webp_WebPDecodeRGB" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if WEBP package is complete" >&5
+$as_echo_n "checking if WEBP package is complete... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_webp='no (failed tests)'
+ else
+ LIB_WEBP='-lwebp'
+ LIBS="$LIB_WEBP $LIBS"
+
+$as_echo "#define HasWEBP 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_webp='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_webp" = 'yes'; then
+ HasWEBP_TRUE=
+ HasWEBP_FALSE='#'
+else
+ HasWEBP_TRUE='#'
+ HasWEBP_FALSE=
+fi
+
+
+
+#
+# Check for XML
+#
+have_xml='no'
+LIB_XML=''
+LIB_XML_DEPS=''
+LIB_XML2_BASE=''
+if test "$with_xml" != 'no'
+then
+ OLD_LDFLAGS=$LDFLAGS
+ OLD_CPPFLAGS=$CPPFLAGS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML support " >&5
+$as_echo_n "checking for XML support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ xml2_config=''
+ # Extract the first word of "xml2-config", so it can be a program name with args.
+set dummy xml2-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_xml2_config+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $xml2_config in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_xml2_config="$xml2_config" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_xml2_config="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+xml2_config=$ac_cv_path_xml2_config
+if test -n "$xml2_config"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xml2_config" >&5
+$as_echo "$xml2_config" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test -n "$xml2_config"
+ then
+ # Sample output from xml2-config --cflags:
+ # -I/usr/include/libxml2
+ # -I/usr/local/include/libxml2 -I/usr/local/include
+ xml2_cflags=`"$xml2_config" --cflags`
+ for flag in $xml2_cflags
+ do
+ case $flag in
+ -I*)
+ # Add flag to CPPFLAGS if not already present
+ add=yes;
+ for test_flag in $CPPFLAGS
+ do
+ if test $flag = $test_flag
+ then
+ add=no
+ break
+ fi
+ done
+ if test $add = yes
+ then
+ CPPFLAGS="$CPPFLAGS $flag"
+ fi
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ # Sample output from xml2-config --libs:
+ # -lxml2
+ # -L/usr/lib -R/usr/lib -lxml2 -lz -lpthread -lm -lsocket -lnsl
+ #-L/usr/local/lib -lxml2 -lz -L/usr/local/lib -liconv -lm
+ xml2_libs=`$xml2_config --libs`
+ for flag in $xml2_libs
+ do
+ case $flag in
+ -L*)
+ # Add flag to LDFLAGS if not already present
+ add=yes;
+ for test_flag in $LDFLAGS
+ do
+ if test $flag = $test_flag
+ then
+ add=no
+ break
+ fi
+ done
+ if test $add = yes
+ then
+ LDFLAGS="$LDFLAGS $flag"
+ fi
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ for flag in $xml2_libs
+ do
+ case $flag in
+ -l*)
+ # The first library listed is assumed to be the
+ # name of the library and all others are assumed
+ # to be its dependencies.
+ if test "x$LIB_XML2_BASE" = "x"
+ then
+ LIB_XML2_BASE=`echo $flag | sed -e 's/^-l//'`
+ else
+ LIB_XML_DEPS="$LIB_XML_DEPS $flag"
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ done
+ fi
+ if test "x$LIB_XML2_BASE" = "x"
+ then
+ LIB_XML2_BASE=xml2
+ fi
+ failed=0
+ passed=0
+ # Incantation tested with libxml2 2.7.8 configured with
+ # --with-minimum --with-http --with-ftp --with-push --with-zlib --with-sax1
+ # Note that SAX1 interfaces don't seem to be directly used but parsers fail to work
+ # as expected without SAX1 support compiled in.
+ ac_fn_c_check_header_mongrel "$LINENO" "libxml/parser.h" "ac_cv_header_libxml_parser_h" "$ac_includes_default"
+if test "x$ac_cv_header_libxml_parser_h" = xyes; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+
+ as_ac_Lib=`$as_echo "ac_cv_lib_$LIB_XML2_BASE''_xmlSAXVersion" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for xmlSAXVersion in -l$LIB_XML2_BASE" >&5
+$as_echo_n "checking for xmlSAXVersion in -l$LIB_XML2_BASE... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$LIB_XML2_BASE $LIB_XML_DEPS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xmlSAXVersion ();
+int
+main ()
+{
+return xmlSAXVersion ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$as_ac_Lib=yes"
+else
+ eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ # Next two require --with-push to be enabled
+ as_ac_Lib=`$as_echo "ac_cv_lib_$LIB_XML2_BASE''_xmlParseChunk" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for xmlParseChunk in -l$LIB_XML2_BASE" >&5
+$as_echo_n "checking for xmlParseChunk in -l$LIB_XML2_BASE... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$LIB_XML2_BASE $LIB_XML_DEPS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xmlParseChunk ();
+int
+main ()
+{
+return xmlParseChunk ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$as_ac_Lib=yes"
+else
+ eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ as_ac_Lib=`$as_echo "ac_cv_lib_$LIB_XML2_BASE''_xmlCreatePushParserCtxt" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for xmlCreatePushParserCtxt in -l$LIB_XML2_BASE" >&5
+$as_echo_n "checking for xmlCreatePushParserCtxt in -l$LIB_XML2_BASE... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$LIB_XML2_BASE $LIB_XML_DEPS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xmlCreatePushParserCtxt ();
+int
+main ()
+{
+return xmlCreatePushParserCtxt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$as_ac_Lib=yes"
+else
+ eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if XML package is complete " >&5
+$as_echo_n "checking if XML package is complete ... " >&6; }
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_xml='no (failed tests)'
+ LDFLAGS="$OLD_LDFLAGS"
+ CPPFLAGS="$OLD_CPPFLAGS"
+ else
+ LIB_XML="-l$LIB_XML2_BASE"
+ # Add lib to LIBS if not already present
+ for test_lib in $LIB_XML $LIB_XML_DEPS
+ do
+ add=yes;
+ for lib in $LIBS
+ do
+ if test $lib = $test_lib
+ then
+ add=no
+ break
+ fi
+ done
+ if test $add = yes
+ then
+ LIBS="$test_lib $LIBS"
+ fi
+ done
+
+$as_echo "#define HasXML 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_xml='yes'
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+fi
+ if test "$have_xml" = 'yes'; then
+ HasXML_TRUE=
+ HasXML_FALSE='#'
+else
+ HasXML_TRUE='#'
+ HasXML_FALSE=
+fi
+
+
+
+
+#
+# Check for WMF
+#
+# We require libwmflite and now refuse to use full libwmf. Typical
+# dependencies for libwmflite are '-lpthread -lm' (which we already
+# usually depend on) whereas full libwmf has a great many
+# dependencies.
+#
+
+have_wmf='no'
+LIB_WMF=''
+LIB_WMF_DEPS=''
+OLIBS="$LIBS"
+if test "$with_wmf" != 'no'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for WMF support " >&5
+$as_echo_n "checking for WMF support ... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+
+ have_libwmflite='no'
+ have_libwmf_ipa_h='no'
+
+ ac_fn_c_check_header_compile "$LINENO" "libwmf/ipa.h" "ac_cv_header_libwmf_ipa_h" "$FT2BUILD_H
+"
+if test "x$ac_cv_header_libwmf_ipa_h" = xyes; then :
+ have_libwmf_ipa_h='yes'
+fi
+
+
+ if test "$have_libwmf_ipa_h" = 'yes'
+ then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wmf_lite_create in -lwmflite" >&5
+$as_echo_n "checking for wmf_lite_create in -lwmflite... " >&6; }
+if ${ac_cv_lib_wmflite_wmf_lite_create+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lwmflite $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char wmf_lite_create ();
+int
+main ()
+{
+return wmf_lite_create ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_wmflite_wmf_lite_create=yes
+else
+ ac_cv_lib_wmflite_wmf_lite_create=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wmflite_wmf_lite_create" >&5
+$as_echo "$ac_cv_lib_wmflite_wmf_lite_create" >&6; }
+if test "x$ac_cv_lib_wmflite_wmf_lite_create" = xyes; then :
+ have_libwmflite='yes'
+fi
+
+ if test "$have_libwmflite" = 'yes'
+ then
+
+$as_echo "#define HasWMFlite 1" >>confdefs.h
+
+
+ LIB_WMF='-lwmflite'
+ LIBS="$LIB_WMF $LIBS"
+ have_wmf='yes'
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no -- some components failed test" >&5
+$as_echo "no -- some components failed test" >&6; }
+ have_wmf='no (failed tests)'
+ have_wmflite='no (failed tests)'
+ LIBS="$OLIBS"
+ LIB_WMF=''
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if WMF package is complete " >&5
+$as_echo_n "checking if WMF package is complete ... " >&6; }
+if test "$have_wmf" = 'yes'
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+ if test "$have_wmf" = 'yes'; then
+ HasWMF_TRUE=
+ HasWMF_FALSE='#'
+else
+ HasWMF_TRUE='#'
+ HasWMF_FALSE=
+fi
+
+
+
+
+#
+# Substitute compiler name to build/link PerlMagick
+#
+
+
+#
+# Configure install Paths
+#
+
+# Subdirectory under lib to place GraphicsMagick lib files
+MagickLibSubdir="${PACKAGE_NAME}-${PACKAGE_VERSION}"
+
+cat >>confdefs.h <<_ACEOF
+#define MagickLibSubdir "$MagickLibSubdir"
+_ACEOF
+
+
+# Path to GraphicsMagick bin directory
+MagickBinPath="${BIN_DIR}"
+MagickBinPathDefine="${MagickBinPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickBinPathDefine=`$WinPathScript "$MagickBinPathDefine" 1`
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define MagickBinPath "$MagickBinPathDefine"
+_ACEOF
+
+
+
+# Path to GraphicsMagick lib
+MagickLibPath="${LIB_DIR}/${MagickLibSubdir}"
+MagickLibPathDefine="${MagickLibPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickLibPathDefine=`$WinPathScript "$MagickLibPathDefine" 1`
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define MagickLibPath "$MagickLibPathDefine"
+_ACEOF
+
+
+
+# Subdirectory under lib to place GraphicsMagick configuration files
+MagickLibConfigSubDir="${MagickLibSubdir}/config"
+
+cat >>confdefs.h <<_ACEOF
+#define MagickLibConfigSubDir "$MagickLibConfigSubDir"
+_ACEOF
+
+MagickLibConfigPath="${LIB_DIR}/${MagickLibConfigSubDir}"
+MagickLibConfigPathDefine="${MagickLibConfigPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickLibConfigPathDefine=`$WinPathScript "$MagickLibConfigPathDefine" 1`
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define MagickLibConfigPath "$MagickLibConfigPathDefine"
+_ACEOF
+
+
+
+#
+# Subdirectory under lib to place GraphicsMagick coder module files
+MagickCoderModulesSubdir="${MagickLibSubdir}/modules-Q${QuantumDepth}/coders"
+
+cat >>confdefs.h <<_ACEOF
+#define MagickCoderModulesSubdir "$MagickCoderModulesSubdir"
+_ACEOF
+
+MagickCoderModulesPath="${LIB_DIR}/${MagickCoderModulesSubdir}"
+MagickCoderModulesPathDefine="${MagickCoderModulesPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickCoderModulesPathDefine=`$WinPathScript "$MagickCoderModulesPathDefine" 1`
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define MagickCoderModulesPath "$MagickCoderModulesPathDefine"
+_ACEOF
+
+
+
+#
+# Subdirectory under lib to place GraphicsMagick filter module files
+MagickFilterModulesSubdir="${MagickLibSubdir}/modules-Q${QuantumDepth}/filters"
+
+cat >>confdefs.h <<_ACEOF
+#define MagickFilterModulesSubdir "$MagickFilterModulesSubdir"
+_ACEOF
+
+MagickFilterModulesPath="${LIB_DIR}/${MagickFilterModulesSubdir}"
+MagickFilterModulesPathDefine="${MagickFilterModulesPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickFilterModulesPathDefine=`$WinPathScript "$MagickFilterModulesPathDefine" 1`
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define MagickFilterModulesPath "$MagickFilterModulesPathDefine"
+_ACEOF
+
+
+
+#
+# Path to GraphicsMagick share files
+MagickShareSubdir="${PACKAGE_NAME}-${PACKAGE_VERSION}"
+MagickSharePath="${DATA_DIR}/${MagickShareSubdir}"
+MagickSharePathDefine="${MagickSharePath}/"
+case "${build_os}" in
+ mingw* )
+ MagickSharePathDefine=`$WinPathScript "$MagickSharePathDefine" 1`
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define MagickSharePath "$MagickSharePathDefine"
+_ACEOF
+
+
+
+# Subdirectory under share to place GraphicsMagick configuration files
+MagickShareConfigSubDir="${MagickLibSubdir}/config"
+
+cat >>confdefs.h <<_ACEOF
+#define MagickShareConfigSubDir "$MagickShareConfigSubDir"
+_ACEOF
+
+MagickShareConfigPath="${DATA_DIR}/${MagickShareConfigSubDir}"
+MagickShareConfigPathDefine="${MagickShareConfigPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickShareConfigPathDefine=`$WinPathScript "$MagickShareConfigPathDefine" 1`
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define MagickShareConfigPath "$MagickShareConfigPathDefine"
+_ACEOF
+
+
+
+#
+# program_transform_name is formed for use in a Makefile, so create a
+# modified version for use in a shell script.
+configure_transform_name=`echo ${program_transform_name} | sed 's,\\$\\$,$,'`
+
+# Default delegate definitions
+BrowseDelegateDefault='xdg-open'
+CGMDecodeDelegateDefault='ralcgm'
+DCRAWDecodeDelegateDefault='dcraw'
+DOTDecodeDelegateDefault='dot'
+DVIDecodeDelegateDefault='dvips'
+EditorDelegateDefault='xterm'
+FIGDecodeDelegateDefault='fig2dev'
+GMDelegateDefault=`echo gm | sed ${configure_transform_name}`
+HPGLDecodeDelegateDefault='hp2xx'
+HTMLDecodeDelegateDefault='html2ps'
+ILBMDecodeDelegateDefault='ilbmtoppm'
+ILBMEncodeDelegateDefault='ppmtoilbm'
+LPDelegateDefault='lp'
+LPRDelegateDefault='lpr'
+LaunchDelegateDefault='gimp'
+MPEGDecodeDelegateDefault='mpeg2decode'
+MPEGEncodeDelegateDefault='mpeg2encode'
+MVDelegateDefault='mv'
+if test "$native_win32_build" = 'yes' ; then
+ PSDelegateDefault='gswin32c'
+else
+ PSDelegateDefault='gs'
+fi
+
+# Search for delegates
+for ac_prog in "$BrowseDelegateDefault" firefox konqueror google-chrome mozilla lynx
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_BrowseDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $BrowseDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_BrowseDelegate="$BrowseDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_BrowseDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+BrowseDelegate=$ac_cv_path_BrowseDelegate
+if test -n "$BrowseDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BrowseDelegate" >&5
+$as_echo "$BrowseDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$BrowseDelegate" && break
+done
+test -n "$BrowseDelegate" || BrowseDelegate=""$BrowseDelegateDefault""
+
+# Extract the first word of ""$CGMDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$CGMDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CGMDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CGMDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CGMDecodeDelegate="$CGMDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CGMDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_CGMDecodeDelegate" && ac_cv_path_CGMDecodeDelegate=""$CGMDecodeDelegateDefault""
+ ;;
+esac
+fi
+CGMDecodeDelegate=$ac_cv_path_CGMDecodeDelegate
+if test -n "$CGMDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CGMDecodeDelegate" >&5
+$as_echo "$CGMDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$DCRAWDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$DCRAWDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DCRAWDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $DCRAWDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_DCRAWDecodeDelegate="$DCRAWDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_DCRAWDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_DCRAWDecodeDelegate" && ac_cv_path_DCRAWDecodeDelegate=""$DCRAWDecodeDelegateDefault""
+ ;;
+esac
+fi
+DCRAWDecodeDelegate=$ac_cv_path_DCRAWDecodeDelegate
+if test -n "$DCRAWDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DCRAWDecodeDelegate" >&5
+$as_echo "$DCRAWDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$DOTDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$DOTDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DOTDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $DOTDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_DOTDecodeDelegate="$DOTDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_DOTDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_DOTDecodeDelegate" && ac_cv_path_DOTDecodeDelegate=""$DOTDecodeDelegateDefault""
+ ;;
+esac
+fi
+DOTDecodeDelegate=$ac_cv_path_DOTDecodeDelegate
+if test -n "$DOTDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOTDecodeDelegate" >&5
+$as_echo "$DOTDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$DVIDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$DVIDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DVIDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $DVIDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_DVIDecodeDelegate="$DVIDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_DVIDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_DVIDecodeDelegate" && ac_cv_path_DVIDecodeDelegate=""$DVIDecodeDelegateDefault""
+ ;;
+esac
+fi
+DVIDecodeDelegate=$ac_cv_path_DVIDecodeDelegate
+if test -n "$DVIDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DVIDecodeDelegate" >&5
+$as_echo "$DVIDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$EditorDelegateDefault"", so it can be a program name with args.
+set dummy "$EditorDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_EditorDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $EditorDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_EditorDelegate="$EditorDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_EditorDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_EditorDelegate" && ac_cv_path_EditorDelegate=""$EditorDelegateDefault""
+ ;;
+esac
+fi
+EditorDelegate=$ac_cv_path_EditorDelegate
+if test -n "$EditorDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EditorDelegate" >&5
+$as_echo "$EditorDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$FIGDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$FIGDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_FIGDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $FIGDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_FIGDecodeDelegate="$FIGDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_FIGDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_FIGDecodeDelegate" && ac_cv_path_FIGDecodeDelegate=""$FIGDecodeDelegateDefault""
+ ;;
+esac
+fi
+FIGDecodeDelegate=$ac_cv_path_FIGDecodeDelegate
+if test -n "$FIGDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FIGDecodeDelegate" >&5
+$as_echo "$FIGDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$GMDelegateDefault"", so it can be a program name with args.
+set dummy "$GMDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GMDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GMDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GMDelegate="$GMDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GMDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_GMDelegate" && ac_cv_path_GMDelegate=""$GMDelegateDefault""
+ ;;
+esac
+fi
+GMDelegate=$ac_cv_path_GMDelegate
+if test -n "$GMDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMDelegate" >&5
+$as_echo "$GMDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$HPGLDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$HPGLDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_HPGLDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $HPGLDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_HPGLDecodeDelegate="$HPGLDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_HPGLDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_HPGLDecodeDelegate" && ac_cv_path_HPGLDecodeDelegate=""$HPGLDecodeDelegateDefault""
+ ;;
+esac
+fi
+HPGLDecodeDelegate=$ac_cv_path_HPGLDecodeDelegate
+if test -n "$HPGLDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HPGLDecodeDelegate" >&5
+$as_echo "$HPGLDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$HTMLDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$HTMLDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_HTMLDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $HTMLDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_HTMLDecodeDelegate="$HTMLDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_HTMLDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_HTMLDecodeDelegate" && ac_cv_path_HTMLDecodeDelegate=""$HTMLDecodeDelegateDefault""
+ ;;
+esac
+fi
+HTMLDecodeDelegate=$ac_cv_path_HTMLDecodeDelegate
+if test -n "$HTMLDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HTMLDecodeDelegate" >&5
+$as_echo "$HTMLDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$ILBMDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$ILBMDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ILBMDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ILBMDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ILBMDecodeDelegate="$ILBMDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ILBMDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_ILBMDecodeDelegate" && ac_cv_path_ILBMDecodeDelegate=""$ILBMDecodeDelegateDefault""
+ ;;
+esac
+fi
+ILBMDecodeDelegate=$ac_cv_path_ILBMDecodeDelegate
+if test -n "$ILBMDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ILBMDecodeDelegate" >&5
+$as_echo "$ILBMDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$ILBMEncodeDelegateDefault"", so it can be a program name with args.
+set dummy "$ILBMEncodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ILBMEncodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ILBMEncodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ILBMEncodeDelegate="$ILBMEncodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ILBMEncodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_ILBMEncodeDelegate" && ac_cv_path_ILBMEncodeDelegate=""$ILBMEncodeDelegateDefault""
+ ;;
+esac
+fi
+ILBMEncodeDelegate=$ac_cv_path_ILBMEncodeDelegate
+if test -n "$ILBMEncodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ILBMEncodeDelegate" >&5
+$as_echo "$ILBMEncodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$LPDelegateDefault"", so it can be a program name with args.
+set dummy "$LPDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_LPDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $LPDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_LPDelegate="$LPDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_LPDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_LPDelegate" && ac_cv_path_LPDelegate="no"
+ ;;
+esac
+fi
+LPDelegate=$ac_cv_path_LPDelegate
+if test -n "$LPDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LPDelegate" >&5
+$as_echo "$LPDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$LPRDelegateDefault"", so it can be a program name with args.
+set dummy "$LPRDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_LPRDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $LPRDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_LPRDelegate="$LPRDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_LPRDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_LPRDelegate" && ac_cv_path_LPRDelegate="no"
+ ;;
+esac
+fi
+LPRDelegate=$ac_cv_path_LPRDelegate
+if test -n "$LPRDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LPRDelegate" >&5
+$as_echo "$LPRDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$LaunchDelegateDefault"", so it can be a program name with args.
+set dummy "$LaunchDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_LaunchDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $LaunchDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_LaunchDelegate="$LaunchDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_LaunchDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_LaunchDelegate" && ac_cv_path_LaunchDelegate=""$LaunchDelegateDefault""
+ ;;
+esac
+fi
+LaunchDelegate=$ac_cv_path_LaunchDelegate
+if test -n "$LaunchDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LaunchDelegate" >&5
+$as_echo "$LaunchDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$MPEGDecodeDelegateDefault"", so it can be a program name with args.
+set dummy "$MPEGDecodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPEGDecodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPEGDecodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPEGDecodeDelegate="$MPEGDecodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPEGDecodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_MPEGDecodeDelegate" && ac_cv_path_MPEGDecodeDelegate=""$MPEGDecodeDelegateDefault""
+ ;;
+esac
+fi
+MPEGDecodeDelegate=$ac_cv_path_MPEGDecodeDelegate
+if test -n "$MPEGDecodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPEGDecodeDelegate" >&5
+$as_echo "$MPEGDecodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$MPEGEncodeDelegateDefault"", so it can be a program name with args.
+set dummy "$MPEGEncodeDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPEGEncodeDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPEGEncodeDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPEGEncodeDelegate="$MPEGEncodeDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPEGEncodeDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_MPEGEncodeDelegate" && ac_cv_path_MPEGEncodeDelegate=""$MPEGEncodeDelegateDefault""
+ ;;
+esac
+fi
+MPEGEncodeDelegate=$ac_cv_path_MPEGEncodeDelegate
+if test -n "$MPEGEncodeDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPEGEncodeDelegate" >&5
+$as_echo "$MPEGEncodeDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$MVDelegateDefault"", so it can be a program name with args.
+set dummy "$MVDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MVDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MVDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MVDelegate="$MVDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MVDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_MVDelegate" && ac_cv_path_MVDelegate=""$MVDelegateDefault""
+ ;;
+esac
+fi
+MVDelegate=$ac_cv_path_MVDelegate
+if test -n "$MVDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MVDelegate" >&5
+$as_echo "$MVDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of ""$PSDelegateDefault"", so it can be a program name with args.
+set dummy "$PSDelegateDefault"; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PSDelegate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PSDelegate in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PSDelegate="$PSDelegate" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PSDelegate="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PSDelegate" && ac_cv_path_PSDelegate=""$PSDelegateDefault""
+ ;;
+esac
+fi
+PSDelegate=$ac_cv_path_PSDelegate
+if test -n "$PSDelegate"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PSDelegate" >&5
+$as_echo "$PSDelegate" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+# Prefer lpr to lp; lp needs options tacked on.
+if test "$LPRDelegate" != no
+then
+ PrintDelegate="$LPRDelegate"
+else
+ PrintDelegate="$LPDelegate -c -s"
+fi
+
+
+# Installed GraphicsMagick utiltity paths
+GMDelegate="${BIN_DIR}/${GMDelegateDefault}"
+
+# Set delegate booleans
+have_fig2dev='no' ; if test "$FIGDecodeDelegate" != "$FIGDecodeDelegateDefault" ; then have_fig2dev='yes' ; fi
+have_gs='no' ; if test "$PSDelegate" != "$PSDelegateDefault"; then have_gs='yes' ; fi
+have_hp2xx='no' ; if test "$HPGLDecodeDelegate" != "$HPGLDecodeDelegateDefault" ; then have_hp2xx='yes' ; fi
+have_ilbmtoppm='no' ; if test "$ILBMDecodeDelegate" != "$ILBMDecodeDelegateDefault" ; then have_ilbmtoppm='yes' ; fi
+have_ppmtoilbm='no' ; if test "$ILBMEncodeDelegate" != "$ILBMEncodeDelegateDefault" ; then have_ppmtoilbm='yes' ; fi
+have_mpeg2decode='no' ; if test "$MPEGDecodeDelegate" != "$MPEGDecodeDelegateDefault" ; then have_mpeg2decode='yes' ; fi
+have_mpeg2encode='no' ; if test "$MPEGEncodeDelegate" != "$MPEGEncodeDelegateDefault" ; then have_mpeg2encode='yes' ; fi
+have_ralcgm='no' ; if test "$CGMDecodeDelegate" != "$CGMDecodeDelegateDefault" ; then have_ralcgm='yes' ; fi
+
+# Automake conditional to support test suite
+ if test "$have_gs" = 'yes'; then
+ HasPSDelegate_TRUE=
+ HasPSDelegate_FALSE='#'
+else
+ HasPSDelegate_TRUE='#'
+ HasPSDelegate_FALSE=
+fi
+
+
+# Test for optional rst2html.py utility and define automake conditional HasRST2HTML if found.
+for ac_prog in rst2html.py rst2html
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RST2HTML+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RST2HTML"; then
+ ac_cv_prog_RST2HTML="$RST2HTML" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RST2HTML="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RST2HTML=$ac_cv_prog_RST2HTML
+if test -n "$RST2HTML"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RST2HTML" >&5
+$as_echo "$RST2HTML" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$RST2HTML" && break
+done
+
+
+ if test "x$RST2HTML" != 'x'; then
+ HasRST2HTML_TRUE=
+ HasRST2HTML_FALSE='#'
+else
+ HasRST2HTML_TRUE='#'
+ HasRST2HTML_FALSE=
+fi
+
+
+# Test for optional txt2html utility and define automake conditional HasTXT2HTML if found.
+for ac_prog in txt2html
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_TXT2HTML+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $TXT2HTML in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_TXT2HTML="$TXT2HTML" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_TXT2HTML="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+TXT2HTML=$ac_cv_path_TXT2HTML
+if test -n "$TXT2HTML"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TXT2HTML" >&5
+$as_echo "$TXT2HTML" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$TXT2HTML" && break
+done
+
+
+ if test "$TXT2HTML" != 'x'; then
+ HasTXT2HTML_TRUE=
+ HasTXT2HTML_FALSE='#'
+else
+ HasTXT2HTML_TRUE='#'
+ HasTXT2HTML_FALSE=
+fi
+
+
+#
+# Test for font directories
+#
+type_include_files=''
+
+# Windows
+windows_font_dir=''
+if test "$with_windows_font_dir" != "yes" && test -n "$with_windows_font_dir"
+then
+ windows_font_dir="${with_windows_font_dir}/"
+fi
+# Sometimes Windows fonts are found under /usr/X11R6/lib/X11/fonts/truetype
+if test -n "$windows_font_dir"
+then
+ if test -f '/usr/X11R6/lib/X11/fonts/truetype/arial.ttf'
+ then
+ windows_font_dir='/usr/X11R6/lib/X11/fonts/truetype/'
+ fi
+fi
+if test -n "$windows_font_dir"
+then
+ type_include_files="$type_include_files "'<include file="type-windows.mgk" />'
+fi
+
+
+# Adobe Postscript fonts on various systems
+case $host_os in
+ solaris*)
+ # Check for OpenWindows Type 1 fonts. Not available under OpenSolaris
+ if test -f /usr/openwin/lib/X11/fonts/Type1/afm/Helvetica.afm
+ then
+ type_include_files="$type_include_files "'<include file="type-solaris.mgk" />'
+ fi
+ ;;
+esac
+
+# Ghostscript
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Ghostscript fonts directory" >&5
+$as_echo_n "checking for Ghostscript fonts directory... " >&6; }
+ghostscript_font_dir=''
+if test "${with_gs_font_dir}" != 'default'
+then
+ ghostscript_font_dir="${with_gs_font_dir}/"
+
+else
+ if test "${native_win32_build}" = 'yes'
+ then
+ # Native Windows Build
+ #
+ # Ghostscript may install fonts to several default locations now.
+ # If the user does not select the default, then he is on his own.
+ #
+ # It would be nice to use reg.exe to obtain Ghostscript information
+ # but unfortunately MSYS seems to transform registry key paths into
+ # filesystem paths so it does not work. Maybe there is a way to
+ # prevent that translation?
+ #
+ # reg query "HKLM\Software\GPL Ghostscript" /s
+ #
+ # This seems to work without translation:
+ #
+ # cmd /c "reg query \"HKLM\Software\GPL Ghostscript\" /v GS_LIB /s"
+ #
+ for font_dir in "c:\\Program Files\\gs\\fonts\\" "c:\\gs\\fonts\\"
+ do
+ if test -f "${font_dir}a010013l.pfb"
+ then
+ ghostscript_font_dir="$font_dir"
+ break 1
+ fi
+ done
+ if test "${PSDelegate}" != 'gswin32c'
+ then
+ ghostscript_font_dir=`echo "${PSDelegate}" | sed -e 's:/gs/.*:/gs:;s:^/::;s/./&:/;s:/:\\\\:g'`"\\fonts\\"
+ fi
+
+ else
+ # Unix Build
+ #
+ # Check ${prefix}/share/ghostscript/fonts first
+ # Red Hat Linux puts Ghostscript fonts in /usr/share/fonts/default/Type1
+ # Recent Cygwin puts Ghostscript fonts in /usr/share/ghostscript/fonts
+ # Recent Gentoo Linux puts Ghostscript fonts in /usr/share/fonts/ghostscript
+ # Debian puts Ghostscript fonts in /usr/share/fonts/type1/gsfonts
+ for font_dir in "${prefix}/share/ghostscript/fonts/" '/usr/share/fonts/default/Type1/' '/usr/share/ghostscript/fonts/' '/usr/share/fonts/ghostscript/' '/usr/share/fonts/type1/gsfonts/'
+ do
+ if test -f "${font_dir}a010013l.pfb"
+ then
+ ghostscript_font_dir="${font_dir}"
+ break 1
+ fi
+ done
+
+ if test "${ghostscript_font_dir}x" = 'x'
+ then
+ if test "$PSDelegate" != 'gs'
+ then
+ ghostscript_font_dir=`echo "$PSDelegate" | sed -e 's:/bin/gs:/share/ghostscript/fonts:'`"/"
+ fi
+ fi
+
+ fi
+fi
+if test "${ghostscript_font_dir}x" != 'x'
+then
+ type_include_files="${type_include_files} "'<include file="type-ghostscript.mgk" />'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ghostscript_font_dir" >&5
+$as_echo "$ghostscript_font_dir" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found!" >&5
+$as_echo "not found!" >&6; };
+fi
+
+case "${build_os}" in
+ mingw* )
+ PSDelegate=`$WinPathScript "$PSDelegate" 1`
+ ;;
+esac
+
+
+
+#
+# Handle case where user doesn't want frozen paths
+#
+if test "$with_frozenpaths" != 'yes'
+then
+ # Re-set delegate definitions to default (no paths)
+ BrowseDelegate="$BrowseDelegateDefault"
+ CGMDecodeDelegate="$CGMDecodeDelegateDefault"
+ ConvertDelegate="$ConvertDelegateDefault"
+ DOTDecodeDelegate="$DOTDecodeDelegateDefault"
+ DVIDecodeDelegate="$DVIDecodeDelegateDefault"
+ EditorDelegate="$EditorDelegateDefault"
+ FIGDecodeDelegate="$FIGDecodeDelegateDefault"
+ GMDelegate="${GMDelegateDefault}"
+ HPGLDecodeDelegate="$HPGLDecodeDelegateDefault"
+ HTMLDecodeDelegate="$HTMLDecodeDelegateDefault"
+ ILBMDecodeDelegate="$ILBMDecodeDelegateDefault"
+ ILBMEncodeDelegate="$ILBMEncodeDelegateDefault"
+ LPDelegate="$LPDelegateDefault"
+ LaunchDelegate="$LaunchDelegateDefault"
+ MPEGDecodeDelegate="$MPEGDecodeDelegateDefault"
+ MPEGEncodeDelegate="$MPEGEncodeDelegateDefault"
+ MogrifyDelegate="$MogrifyDelegateDefault"
+ PSDelegate="$PSDelegateDefault"
+ ShowImageDelegate="$ShowImageDelegateDefault"
+ WMFDecodeDelegate="$WMFDecodeDelegateDefault"
+fi
+
+# Delegate substitutions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# RedHat RPM support (http://rpm5.org/)
+#
+RPM=''
+for ac_prog in rpmbuild rpm
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RPM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RPM"; then
+ ac_cv_prog_RPM="$RPM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RPM="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RPM=$ac_cv_prog_RPM
+if test -n "$RPM"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPM" >&5
+$as_echo "$RPM" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$RPM" && break
+done
+
+
+ if test "x$RPM" != "x" ; then
+ HAS_RPM_TRUE=
+ HAS_RPM_FALSE='#'
+else
+ HAS_RPM_TRUE='#'
+ HAS_RPM_FALSE=
+fi
+
+
+#
+# 7ZIP support (http://p7zip.sourceforge.net/)
+#
+P7ZIP=''
+for ac_prog in 7za
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_P7ZIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$P7ZIP"; then
+ ac_cv_prog_P7ZIP="$P7ZIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_P7ZIP="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+P7ZIP=$ac_cv_prog_P7ZIP
+if test -n "$P7ZIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $P7ZIP" >&5
+$as_echo "$P7ZIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$P7ZIP" && break
+done
+
+
+ if test "x$P7ZIP" != "x" ; then
+ HAS_P7ZIP_TRUE=
+ HAS_P7ZIP_FALSE='#'
+else
+ HAS_P7ZIP_TRUE='#'
+ HAS_P7ZIP_FALSE=
+fi
+
+
+#
+# ZIP support (http://www.info-zip.org/Zip.html)
+#
+ZIP=''
+for ac_prog in zip
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ZIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ZIP"; then
+ ac_cv_prog_ZIP="$ZIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ZIP="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ZIP=$ac_cv_prog_ZIP
+if test -n "$ZIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP" >&5
+$as_echo "$ZIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ZIP" && break
+done
+
+
+ if test "x$ZIP" != "x" ; then
+ HAS_ZIP_TRUE=
+ HAS_ZIP_FALSE='#'
+else
+ HAS_ZIP_TRUE='#'
+ HAS_ZIP_FALSE=
+fi
+
+
+#
+# Ghostscript related configuration.
+#
+GSColorDevice=ppmraw
+GSColorAlphaDevice=pngalpha
+GSGrayDevice=pgmraw
+GSPaletteDevice=pcx256
+GSMonoDevice=pbmraw
+GSCMYKDevices="pamcmyk32 pam $GSColorDevice"
+GSPDFDevice=pdfwrite
+GSPSDevice=pswrite
+GSEPSDevice=epswrite
+GSVersion='unknown'
+if test $have_gs = 'yes'
+then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Ghostscript version" >&5
+$as_echo_n "checking for Ghostscript version... " >&6; }
+ if GSVersion=`$PSDelegate --version`
+ then
+ :
+ else
+ GSVersion=`$PSDelegate --help | sed -e '1q' | awk '{ print $3 }'`
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSVersion" >&5
+$as_echo "$GSVersion" >&6; }
+
+ # GSColorDevice # AS_MESSAGE_LOG_FD
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs color device" >&5
+$as_echo_n "checking for gs color device... " >&6; }
+ if $PSDelegate -q -dBATCH -sDEVICE=pnmraw -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSColorDevice=pnmraw
+ else
+ if $PSDelegate -q -dBATCH -sDEVICE=ppmraw -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSColorDevice=ppmraw
+ else
+ GSColorDevice=ppmraw
+ fi
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSColorDevice" >&5
+$as_echo "$GSColorDevice" >&6; }
+
+ # GSColorAlphaDevice
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs color+alpha device" >&5
+$as_echo_n "checking for gs color+alpha device... " >&6; }
+ if $PSDelegate -q -dBATCH -sDEVICE=pngalpha -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSColorAlphaDevice=pngalpha
+ else
+ GSColorAlphaDevice=$GSColorDevice
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSColorAlphaDevice" >&5
+$as_echo "$GSColorAlphaDevice" >&6; }
+
+ # GSGrayDevice
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs gray device" >&5
+$as_echo_n "checking for gs gray device... " >&6; }
+ if $PSDelegate -q -dBATCH -sDEVICE=pgmraw -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSGrayDevice=pgmraw
+ else
+ GSGrayDevice=ppmraw
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSGrayDevice" >&5
+$as_echo "$GSGrayDevice" >&6; }
+
+ # GSPaletteDevice
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs pallet device" >&5
+$as_echo_n "checking for gs pallet device... " >&6; }
+ if $PSDelegate -q -dBATCH -sDEVICE=pcx256 -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSPaletteDevice=pcx256
+ else
+ GSPaletteDevice=ppmraw
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSPaletteDevice" >&5
+$as_echo "$GSPaletteDevice" >&6; }
+
+ # GSMonoDevice
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs mono device" >&5
+$as_echo_n "checking for gs mono device... " >&6; }
+ if $PSDelegate -q -dBATCH -sDEVICE=pbmraw -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSMonoDevice=pbmraw
+ else
+ GSMonoDevice=ppmraw
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSMonoDevice" >&5
+$as_echo "$GSMonoDevice" >&6; }
+
+ # GSCMYKDevice
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs CMYK device" >&5
+$as_echo_n "checking for gs CMYK device... " >&6; }
+ GSCMYKDevice=$GSColorDevice
+ for device in $GSCMYKDevices
+ do
+ if $PSDelegate -q -dBATCH -sDEVICE=$device -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSCMYKDevice=$device
+ break
+ fi
+ done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSCMYKDevice" >&5
+$as_echo "$GSCMYKDevice" >&6; }
+
+ # GSPDFDevice
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs PDF writing device" >&5
+$as_echo_n "checking for gs PDF writing device... " >&6; }
+ if $PSDelegate -q -dBATCH -sDEVICE=pdfwrite -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSPDFDevice=pdfwrite
+ else
+ GSPDFDevice=nodevice
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSPDFDevice" >&5
+$as_echo "$GSPDFDevice" >&6; }
+
+ # GSPSDevice
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs PS writing device" >&5
+$as_echo_n "checking for gs PS writing device... " >&6; }
+ GSPSDevice=nodevice
+ for device in ps2write pswrite
+ do
+ if $PSDelegate -q -dBATCH -sDEVICE=$device -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSPSDevice=$device
+ break
+ fi
+ done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSPSDevice" >&5
+$as_echo "$GSPSDevice" >&6; }
+
+ # GSEPSDevice
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gs EPS writing device" >&5
+$as_echo_n "checking for gs EPS writing device... " >&6; }
+ GSEPSDevice=nodevice
+ for device in eps2write epswrite
+ do
+ if $PSDelegate -q -dBATCH -sDEVICE=$device -sOutputFile=/dev/null < /dev/null 1>&5 2>&5
+ then
+ GSEPSDevice=$device
+ break
+ fi
+ done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GSEPSDevice" >&5
+$as_echo "$GSEPSDevice" >&6; }
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# PerlMagick-related configuration
+#
+
+# Look for PERL if PerlMagick requested
+# If name/path of desired PERL interpreter is specified, look for that one first
+have_perl='no'
+if test "$with_perl" != 'no'
+then
+ if test "$with_perl" != 'yes'
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl" >&5
+$as_echo_n "checking for perl... " >&6; }
+if ${ac_cv_path_PERL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_path_PERL="$with_perl"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_PERL" >&5
+$as_echo "$ac_cv_path_PERL" >&6; };
+ PERL=$ac_cv_path_PERL
+ have_perl="$ac_cv_path_PERL"
+ else
+ for ac_prog in perl perl5
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PERL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PERL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+if test -n "$PERL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
+$as_echo "$PERL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$PERL" && break
+done
+ if test "$ac_cv_path_PERL"
+ then
+ have_perl="$ac_cv_path_PERL"
+ fi
+ fi
+fi
+if test "$with_perl" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-perl=$with_perl "
+fi
+
+PERL_SUPPORTS_DESTDIR='no'
+with_perl_static='no'
+with_perl_dynamic='no'
+if test "$have_perl" != 'no'
+then
+ # Should we build shared libraries?
+ if test "$with_perl" != 'no' && test "$libtool_build_shared_libs" = 'no'
+ then
+ with_perl_static='yes'
+ fi
+ if test "$with_perl" != 'no' && test "$libtool_build_shared_libs" = 'yes'
+ then
+ with_perl_dynamic='yes'
+ fi
+
+ # Is PERL's MakeMaker new enough to support DESTDIR?
+ # Make sure we have perl
+if test -z "$PERL"; then
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PERL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$PERL"; then
+ ac_cv_prog_PERL="$PERL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_PERL="perl"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+PERL=$ac_cv_prog_PERL
+if test -n "$PERL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
+$as_echo "$PERL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+
+# Check if version of Perl is sufficient
+ac_perl_version="5.8.1"
+
+if test "x$PERL" != "x"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl version greater than or equal to $ac_perl_version" >&5
+$as_echo_n "checking for perl version greater than or equal to $ac_perl_version... " >&6; }
+ # NB: It would be nice to log the error if there is one, but we cannot rely
+ # on autoconf internals
+ $PERL -e "use $ac_perl_version;" > /dev/null 2>&1
+ if test $? -ne 0; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };
+ PERL_SUPPORTS_DESTDIR='no'
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; };
+ PERL_SUPPORTS_DESTDIR='yes'
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5
+$as_echo "$as_me: WARNING: could not find perl" >&2;}
+fi
+
+fi
+ if test "$have_perl" != 'no'; then
+ WITH_PERL_TRUE=
+ WITH_PERL_FALSE='#'
+else
+ WITH_PERL_TRUE='#'
+ WITH_PERL_FALSE=
+fi
+
+ if test $with_perl_static = 'yes'; then
+ WITH_PERL_STATIC_TRUE=
+ WITH_PERL_STATIC_FALSE='#'
+else
+ WITH_PERL_STATIC_TRUE='#'
+ WITH_PERL_STATIC_FALSE=
+fi
+
+ if test $with_perl_dynamic = 'yes'; then
+ WITH_PERL_DYNAMIC_TRUE=
+ WITH_PERL_DYNAMIC_FALSE='#'
+else
+ WITH_PERL_DYNAMIC_TRUE='#'
+ WITH_PERL_DYNAMIC_FALSE=
+fi
+
+
+
+# Determine path to pick up GraphicsMagick library from for use with building PerlMagick
+MAGICKLIBDIR="${LIB_DIR}"
+MAGICKLIB="-L${MAGICKLIBDIR} -lGraphicsMagick"
+if test $with_perl_static = 'yes'
+then
+ # Find out where libtool hides its uninstalled libraries (as libtool_objdir)
+ libtool_objdir=$objdir
+
+ # Find out what extension is applied to static libraries (as libtool_libext)
+ #eval `./libtool --config|grep '^libext='|sed -e 's/^libext/libtool_libext/'`
+
+ # Find out full form of library name (as libtool_libname_spec)
+ #eval `./libtool --config|grep '^libname_spec='|sed -e 's/^libname_spec/libtool_libname_spec/'`
+ #eval 'name=GraphicsMagick '`eval 'echo library_name="${libtool_libname_spec}.${libtool_libext}"'`
+
+ # Explicit path to static library (Perl rejects it!)
+ #MAGICKLIB="${builddir}/magick/${libtool_objdir}/${library_name}"
+
+ # Linker search path to library, followed by -lGraphicsMagick
+ MAGICKLIBDIR="${builddir}/magick/${libtool_objdir}"
+ MAGICKLIB="-L${MAGICKLIBDIR} -lGraphicsMagick"
+fi
+
+
+
+# Create a simple string containing format names for all delegate libraries
+# DELEGATES is used to select sub-directories in the PerlMagick test suite
+# MAGICK_FEATURES is used to declare required features in the test suite
+DELEGATES=''
+MAGICK_FEATURES=''
+if test "$with_broken_coders" = yes; then
+ # Add the list of broken coders to feature options
+ MAGICK_FEATURES="$MAGICK_FEATURES PSD"
+fi
+if test "$have_bzlib" = 'yes' ; then
+ DELEGATES="$DELEGATES bzlib"
+ MAGICK_FEATURES="$MAGICK_FEATURES BZLIB"
+fi
+if test "$have_fpx" = 'yes' ; then
+ DELEGATES="$DELEGATES fpx"
+ MAGICK_FEATURES="$MAGICK_FEATURES FPX"
+fi
+if test "$have_hp2xx" = 'yes' ; then
+ DELEGATES="$DELEGATES hpgl"
+ MAGICK_FEATURES="$MAGICK_FEATURES HPGL"
+fi
+if test "$have_jbig" = 'yes' ; then
+ DELEGATES="$DELEGATES jbig"
+ MAGICK_FEATURES="$MAGICK_FEATURES JBIG"
+fi
+if test "$have_webp" = 'yes' ; then
+ DELEGATES="$DELEGATES webp"
+ MAGICK_FEATURES="$MAGICK_FEATURES WEBP"
+fi
+if test "$have_png$have_jpeg" = 'yesyes' ; then
+ DELEGATES="$DELEGATES jng"
+ MAGICK_FEATURES="$MAGICK_FEATURES JNG"
+fi
+if test "$have_jp2" = 'yes' ; then
+ DELEGATES="$DELEGATES jp2"
+ MAGICK_FEATURES="$MAGICK_FEATURES JP2"
+fi
+if test "$have_jpeg" = 'yes' ; then
+ DELEGATES="$DELEGATES jpeg"
+ MAGICK_FEATURES="$MAGICK_FEATURES JPEG"
+fi
+if test "$have_lcms2" = 'yes' ; then
+ DELEGATES="$DELEGATES lcms"
+ MAGICK_FEATURES="$MAGICK_FEATURES LCMS"
+fi
+if test "$have_lzma" = 'yes' ; then
+ DELEGATES="$DELEGATES lzma"
+ MAGICK_FEATURES="$MAGICK_FEATURES LZMA"
+fi
+if test "$have_mpeg2" = 'yes' ; then
+ DELEGATES="$DELEGATES mpeg2"
+ MAGICK_FEATURES="$MAGICK_FEATURES MPEG2"
+fi
+if test "$have_mpeg2decode" = 'yes' && test "$have_mpeg2encode" = 'yes' ; then
+ DELEGATES="$DELEGATES mpeg"
+ MAGICK_FEATURES="$MAGICK_FEATURES MPEG"
+fi
+if test "$have_png" = 'yes' ; then
+ DELEGATES="$DELEGATES png"
+ MAGICK_FEATURES="$MAGICK_FEATURES PNG"
+fi
+
+have_ps='no'
+if test "$have_dps" = 'yes' || \
+ test "$have_gs" = 'yes' || \
+ test "${native_win32_build}" = 'yes' ; then
+ have_ps='yes'
+fi
+if test "$have_ps" = 'yes' ; then
+ DELEGATES="$DELEGATES ps"
+ MAGICK_FEATURES="$MAGICK_FEATURES PS"
+fi
+
+if test "$have_tiff" = 'yes' ; then
+ DELEGATES="$DELEGATES tiff"
+ MAGICK_FEATURES="$MAGICK_FEATURES TIFF"
+fi
+if test "$have_ttf" = 'yes' ; then
+ DELEGATES="$DELEGATES ttf"
+ MAGICK_FEATURES="$MAGICK_FEATURES TTF"
+fi
+if test "$have_wmf" = 'yes' ; then
+ DELEGATES="$DELEGATES wmf"
+ MAGICK_FEATURES="$MAGICK_FEATURES WMF"
+fi
+if test "$have_x" = 'yes' ; then
+ DELEGATES="$DELEGATES x"
+ MAGICK_FEATURES="$MAGICK_FEATURES X"
+fi
+if test "$have_fig2dev" = 'yes' && test "$have_ps" = 'yes' ; then
+ DELEGATES="$DELEGATES xfig"
+ MAGICK_FEATURES="$MAGICK_FEATURES XFIG"
+fi
+if test "$have_xml" = 'yes' ; then
+ DELEGATES="$DELEGATES xml"
+ MAGICK_FEATURES="$MAGICK_FEATURES XML"
+fi
+if test "$have_zlib" = 'yes' ; then
+ DELEGATES="$DELEGATES zlib"
+ MAGICK_FEATURES="$MAGICK_FEATURES ZLIB"
+fi
+if test "$build_modules" != 'no' ; then
+ MAGICK_FEATURES="$MAGICK_FEATURES MODULES"
+fi
+# Remove extraneous spaces from output variables (asthetic)
+DELEGATES=`echo $DELEGATES | sed -e 's/ */ /g'`
+MAGICK_FEATURES=`echo $MAGICK_FEATURES | sed -e 's/ */ /g'`
+
+
+
+#
+# Handle special compiler flags
+#
+
+# Add '-p' if prof source profiling support enabled
+if test "$with_prof" = 'yes'
+then
+ CFLAGS="-p $CFLAGS"
+ CXXFLAGS="-p $CXXFLAGS"
+ LDFLAGS="-p $LDFLAGS"
+fi
+
+# Add '-pg' if gprof source profiling support enabled
+if test "$with_gprof" = 'yes'
+then
+ CFLAGS="-pg $CFLAGS"
+ CXXFLAGS="-pg $CXXFLAGS"
+ LDFLAGS="-pg $LDFLAGS"
+fi
+
+# Add '-ftest-coverage -fprofile-arcs' if gcov source profiling support enabled
+# This is a gcc-specific feature
+if test "$with_gcov" = 'yes'
+then
+ CFLAGS="-ftest-coverage -fprofile-arcs $CFLAGS"
+ CXXFLAGS="-ftest-coverage -fprofile-arcs $CXXFLAGS"
+ LDFLAGS="-ftest-coverage -fprofile-arcs $LDFLAGS"
+fi
+
+#
+# Build library dependency list for libMagick
+#
+
+# The build_modules variable is set to 'yes' if coders and filters are
+# to be built as modules. This requires libltdl ($LIB_LTDL).
+
+if test "$build_modules" != 'no'
+then
+ MAGICK_DEP_LIBS="$LIBS_USER $LIB_LCMS $LIB_TTF $LIB_GS $LIB_XEXT $LIB_IPC $LIB_X11 $LIB_LZMA $LIB_BZLIB $LIB_ZLIB $LIB_LTDL $LIB_TRIO $LIB_GDI32 $LIB_MATH $LIB_OMP $LIB_UMEM $LIB_THREAD"
+else
+ MAGICK_DEP_LIBS="$LIBS_USER $LIB_JBIG $LIB_WEBP $LIB_LCMS $LIB_TIFF $LIB_TTF $LIB_JP2 $LIB_JPEG $LIB_GS $LIB_PNG $LIB_FPX $LIB_WMF $LIB_DPS $LIB_XEXT $LIB_IPC $LIB_X11 $LIB_LZMA $LIB_BZLIB $LIB_XML $LIB_ZLIB $LIB_TRIO $LIB_GDI32 $LIB_MATH $LIB_OMP $LIB_UMEM $LIB_THREAD"
+fi
+
+
+#
+# Remove extraneous spaces from output variables (asthetic)
+#
+X_CFLAGS=`echo $X_CFLAGS | sed -e 's/ */ /g'`
+X_PRE_LIBS=`echo $X_PRE_LIBS | sed -e 's/ */ /g'`
+X_LIBS=`echo $X_LIBS | sed -e 's/ */ /g'`
+X_EXTRA_LIBS=`echo $X_EXTRA_LIBS | sed -e 's/ */ /g'`
+
+CC=`echo $CC | sed -e 's/ */ /g'`
+CFLAGS=`echo $CFLAGS | sed -e 's/ */ /g'`
+CPPFLAGS=`echo $CPPFLAGS | sed -e 's/ */ /g'`
+CXXFLAGS=`echo $CXXFLAGS | sed -e 's/ */ /g'`
+LDFLAGS=`echo $LDFLAGS | sed -e 's/ */ /g'`
+TESTED_LIBS=`echo $LIBS | sed -e 's/ */ /g'`
+MAGICK_DEP_LIBS=`echo $MAGICK_DEP_LIBS | sed -e 's/ */ /g'`
+#LIBS=`echo $LIBS | sed -e 's/ */ /g'`
+
+MAGICK_API_CFLAGS=$CFLAGS
+MAGICK_API_CPPFLAGS=`echo $MAGICK_API_CPPFLAGS | sed -e 's/ */ /g'`
+MAGICK_API_LDFLAGS="-L$LIB_DIR $LDFLAGS"
+MAGICK_API_DEP_LIBS="$MAGICK_DEP_LIBS"
+MAGICK_API_LIBS="-lGraphicsMagick $MAGICK_API_DEP_LIBS"
+
+MAGICK_API_DEP_LIBS=`echo $MAGICK_API_DEP_LIBS | sed -e 's/ */ /g'`
+MAGICK_API_LIBS=`echo $MAGICK_API_LIBS | sed -e 's/ */ /g'`
+
+# Save configure/build parameters for later reference
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_CONFIGURE_ARGS "$0 ${ac_configure_args}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_HOST "${host}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_CC "${CC}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_CXX "${CXX}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_CFLAGS "${CFLAGS}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_CPPFLAGS "${CPPFLAGS}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_CXXFLAGS "${CXXFLAGS}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_LDFLAGS "${LDFLAGS}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define GM_BUILD_LIBS "${MAGICK_API_DEP_LIBS}"
+_ACEOF
+
+
+# Pass only user-provided LIBS as "global" libraries
+LIBS=$LIBS_USER
+
+#AC_SUBST(CPPFLAGS)
+
+#AC_SUBST(LDFLAGS)
+#AC_SUBST(X_PRE_LIBS)
+#AC_SUBST(X_LIBS)
+#AC_SUBST(X_EXTRA_LIBS)
+
+
+
+
+
+
+
+
+ac_config_files="$ac_config_files GraphicsMagick.spec Magick++/bin/GraphicsMagick++-config Magick++/lib/GraphicsMagick++.pc Makefile PerlMagick/Magick.pm PerlMagick/Makefile.PL PerlMagick/PerlMagickCheck.sh PerlMagick/t/features.pl config/delegates.mgk config/type-ghostscript.mgk config/type-solaris.mgk config/type-windows.mgk config/type.mgk magick/GraphicsMagick-config magick/GraphicsMagick.pc magick/magick_types.h magick/version.h common.shi rungm.sh wand/GraphicsMagickWand-config wand/GraphicsMagickWand.pc"
+
+
+# Set configured scripts to executable.
+ac_config_commands="$ac_config_commands default"
+
+ac_config_commands="$ac_config_commands GraphicsMagick++-config.in"
+
+ac_config_commands="$ac_config_commands GraphicsMagick-config.in"
+
+ac_config_commands="$ac_config_commands GraphicsMagickWand-config.in"
+
+ac_config_commands="$ac_config_commands rungm.sh.in"
+
+ac_config_commands="$ac_config_commands PerlMagick/PerlMagickCheck.sh.in"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasWINGDI32_TRUE}" && test -z "${HasWINGDI32_FALSE}"; then
+ as_fn_error $? "conditional \"HasWINGDI32\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WIN32_NATIVE_BUILD_TRUE}" && test -z "${WIN32_NATIVE_BUILD_FALSE}"; then
+ as_fn_error $? "conditional \"WIN32_NATIVE_BUILD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CYGWIN_BUILD_TRUE}" && test -z "${CYGWIN_BUILD_FALSE}"; then
+ as_fn_error $? "conditional \"CYGWIN_BUILD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_SHARED_LIBS_TRUE}" && test -z "${WITH_SHARED_LIBS_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_SHARED_LIBS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_MODULES_TRUE}" && test -z "${WITH_MODULES_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_MODULES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_BROKEN_CODERS_TRUE}" && test -z "${ENABLE_BROKEN_CODERS_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_BROKEN_CODERS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MAGICK_COMPAT_TRUE}" && test -z "${MAGICK_COMPAT_FALSE}"; then
+ as_fn_error $? "conditional \"MAGICK_COMPAT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_MAGICK_PLUS_PLUS_TRUE}" && test -z "${WITH_MAGICK_PLUS_PLUS_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_MAGICK_PLUS_PLUS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasUMEM_TRUE}" && test -z "${HasUMEM_FALSE}"; then
+ as_fn_error $? "conditional \"HasUMEM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_LTDL_TRUE}" && test -z "${WITH_LTDL_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_LTDL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasZLIB_TRUE}" && test -z "${HasZLIB_FALSE}"; then
+ as_fn_error $? "conditional \"HasZLIB\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasBZLIB_TRUE}" && test -z "${HasBZLIB_FALSE}"; then
+ as_fn_error $? "conditional \"HasBZLIB\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasLZMA_TRUE}" && test -z "${HasLZMA_FALSE}"; then
+ as_fn_error $? "conditional \"HasLZMA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasX11_TRUE}" && test -z "${HasX11_FALSE}"; then
+ as_fn_error $? "conditional \"HasX11\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasDPS_TRUE}" && test -z "${HasDPS_FALSE}"; then
+ as_fn_error $? "conditional \"HasDPS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasFPX_TRUE}" && test -z "${HasFPX_FALSE}"; then
+ as_fn_error $? "conditional \"HasFPX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasLCMS_TRUE}" && test -z "${HasLCMS_FALSE}"; then
+ as_fn_error $? "conditional \"HasLCMS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasPNG_TRUE}" && test -z "${HasPNG_FALSE}"; then
+ as_fn_error $? "conditional \"HasPNG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasJPEG_TRUE}" && test -z "${HasJPEG_FALSE}"; then
+ as_fn_error $? "conditional \"HasJPEG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasJP2_TRUE}" && test -z "${HasJP2_FALSE}"; then
+ as_fn_error $? "conditional \"HasJP2\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasGS_TRUE}" && test -z "${HasGS_FALSE}"; then
+ as_fn_error $? "conditional \"HasGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasTTF_TRUE}" && test -z "${HasTTF_FALSE}"; then
+ as_fn_error $? "conditional \"HasTTF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasTIFF_TRUE}" && test -z "${HasTIFF_FALSE}"; then
+ as_fn_error $? "conditional \"HasTIFF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasJBIG_TRUE}" && test -z "${HasJBIG_FALSE}"; then
+ as_fn_error $? "conditional \"HasJBIG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasWEBP_TRUE}" && test -z "${HasWEBP_FALSE}"; then
+ as_fn_error $? "conditional \"HasWEBP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasXML_TRUE}" && test -z "${HasXML_FALSE}"; then
+ as_fn_error $? "conditional \"HasXML\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasWMF_TRUE}" && test -z "${HasWMF_FALSE}"; then
+ as_fn_error $? "conditional \"HasWMF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasPSDelegate_TRUE}" && test -z "${HasPSDelegate_FALSE}"; then
+ as_fn_error $? "conditional \"HasPSDelegate\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasRST2HTML_TRUE}" && test -z "${HasRST2HTML_FALSE}"; then
+ as_fn_error $? "conditional \"HasRST2HTML\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HasTXT2HTML_TRUE}" && test -z "${HasTXT2HTML_FALSE}"; then
+ as_fn_error $? "conditional \"HasTXT2HTML\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAS_RPM_TRUE}" && test -z "${HAS_RPM_FALSE}"; then
+ as_fn_error $? "conditional \"HAS_RPM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAS_P7ZIP_TRUE}" && test -z "${HAS_P7ZIP_FALSE}"; then
+ as_fn_error $? "conditional \"HAS_P7ZIP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAS_ZIP_TRUE}" && test -z "${HAS_ZIP_FALSE}"; then
+ as_fn_error $? "conditional \"HAS_ZIP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_PERL_TRUE}" && test -z "${WITH_PERL_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_PERL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_PERL_STATIC_TRUE}" && test -z "${WITH_PERL_STATIC_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_PERL_STATIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_PERL_DYNAMIC_TRUE}" && test -z "${WITH_PERL_DYNAMIC_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_PERL_DYNAMIC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SED \
+GREP \
+EGREP \
+FGREP \
+SHELL \
+ECHO \
+LD \
+AS \
+DLLTOOL \
+OBJDUMP \
+PATH_SEPARATOR \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "magick/magick_config.h") CONFIG_HEADERS="$CONFIG_HEADERS magick/magick_config.h" ;;
+ "magick/magick_config_api.h") CONFIG_HEADERS="$CONFIG_HEADERS magick/magick_config_api.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "GraphicsMagick.spec") CONFIG_FILES="$CONFIG_FILES GraphicsMagick.spec" ;;
+ "Magick++/bin/GraphicsMagick++-config") CONFIG_FILES="$CONFIG_FILES Magick++/bin/GraphicsMagick++-config" ;;
+ "Magick++/lib/GraphicsMagick++.pc") CONFIG_FILES="$CONFIG_FILES Magick++/lib/GraphicsMagick++.pc" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "PerlMagick/Magick.pm") CONFIG_FILES="$CONFIG_FILES PerlMagick/Magick.pm" ;;
+ "PerlMagick/Makefile.PL") CONFIG_FILES="$CONFIG_FILES PerlMagick/Makefile.PL" ;;
+ "PerlMagick/PerlMagickCheck.sh") CONFIG_FILES="$CONFIG_FILES PerlMagick/PerlMagickCheck.sh" ;;
+ "PerlMagick/t/features.pl") CONFIG_FILES="$CONFIG_FILES PerlMagick/t/features.pl" ;;
+ "config/delegates.mgk") CONFIG_FILES="$CONFIG_FILES config/delegates.mgk" ;;
+ "config/type-ghostscript.mgk") CONFIG_FILES="$CONFIG_FILES config/type-ghostscript.mgk" ;;
+ "config/type-solaris.mgk") CONFIG_FILES="$CONFIG_FILES config/type-solaris.mgk" ;;
+ "config/type-windows.mgk") CONFIG_FILES="$CONFIG_FILES config/type-windows.mgk" ;;
+ "config/type.mgk") CONFIG_FILES="$CONFIG_FILES config/type.mgk" ;;
+ "magick/GraphicsMagick-config") CONFIG_FILES="$CONFIG_FILES magick/GraphicsMagick-config" ;;
+ "magick/GraphicsMagick.pc") CONFIG_FILES="$CONFIG_FILES magick/GraphicsMagick.pc" ;;
+ "magick/magick_types.h") CONFIG_FILES="$CONFIG_FILES magick/magick_types.h" ;;
+ "magick/version.h") CONFIG_FILES="$CONFIG_FILES magick/version.h" ;;
+ "common.shi") CONFIG_FILES="$CONFIG_FILES common.shi" ;;
+ "rungm.sh") CONFIG_FILES="$CONFIG_FILES rungm.sh" ;;
+ "wand/GraphicsMagickWand-config") CONFIG_FILES="$CONFIG_FILES wand/GraphicsMagickWand-config" ;;
+ "wand/GraphicsMagickWand.pc") CONFIG_FILES="$CONFIG_FILES wand/GraphicsMagickWand.pc" ;;
+ "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
+ "GraphicsMagick++-config.in") CONFIG_COMMANDS="$CONFIG_COMMANDS GraphicsMagick++-config.in" ;;
+ "GraphicsMagick-config.in") CONFIG_COMMANDS="$CONFIG_COMMANDS GraphicsMagick-config.in" ;;
+ "GraphicsMagickWand-config.in") CONFIG_COMMANDS="$CONFIG_COMMANDS GraphicsMagickWand-config.in" ;;
+ "rungm.sh.in") CONFIG_COMMANDS="$CONFIG_COMMANDS rungm.sh.in" ;;
+ "PerlMagick/PerlMagickCheck.sh.in") CONFIG_COMMANDS="$CONFIG_COMMANDS PerlMagick/PerlMagickCheck.sh.in" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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, see <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags='CXX '
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Assembler program.
+AS=$lt_AS
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$lt_OBJDUMP
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+ "GraphicsMagick++-config.in":C) chmod +x Magick++/bin/GraphicsMagick++-config ;;
+ "GraphicsMagick-config.in":C) chmod +x magick/GraphicsMagick-config ;;
+ "GraphicsMagickWand-config.in":C) chmod +x wand/GraphicsMagickWand-config ;;
+ "rungm.sh.in":C) chmod +x rungm.sh ;;
+ "PerlMagick/PerlMagickCheck.sh.in":C) chmod +x PerlMagick/PerlMagickCheck.sh ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+rm -f magick-version
+
+echo ""
+
+echo "GraphicsMagick is configured as follows. Please verify that this"
+echo "configuration matches your expectations."
+echo ""
+echo "Host system type : $host"
+echo "Build system type : $build"
+echo ""
+echo "Option Configure option Configured value"
+echo "-----------------------------------------------------------------"
+echo "Shared libraries --enable-shared=$enable_shared $libtool_build_shared_libs"
+echo "Static libraries --enable-static=$enable_static $libtool_build_static_libs"
+echo "GNU ld --with-gnu-ld=$with_gnu_ld $lt_cv_prog_gnu_ld"
+echo "Quantum depth --with-quantum-depth=$with_quantum_depth $with_quantum_depth"
+echo "Modules --with-modules=$with_modules $build_modules"
+echo ""
+echo "Delegate Configuration:"
+echo "BZLIB --with-bzlib=$with_bzlib $have_bzlib"
+echo "DPS --with-dps=$with_dps $have_dps"
+echo "FlashPIX --with-fpx=$with_fpx $have_fpx"
+echo "FreeType 2.0 --with-ttf=$with_ttf $have_ttf"
+echo "Ghostscript None $PSDelegate ($GSVersion)"
+result_ghostscript_font_dir='none'
+if test "${ghostscript_font_dir}x" != 'x'
+then
+ result_ghostscript_font_dir="$ghostscript_font_dir"
+fi
+echo "Ghostscript fonts --with-gs-font-dir=$with_gs_font_dir $result_ghostscript_font_dir"
+echo "Ghostscript lib --with-gslib=$with_gslib $have_gslib"
+echo "JBIG --with-jbig=$with_jbig $have_jbig"
+echo "JPEG v1 --with-jpeg=$with_jpeg $have_jpeg"
+echo "JPEG-2000 --with-jp2=$with_jp2 $have_jp2"
+echo "LCMS v2 --with-lcms2=$with_lcms2 $have_lcms2"
+# echo "MPEG v2 --with-mpeg2=$with_mpeg2 $have_mpeg2"
+echo "LZMA --with-lzma=$with_lzma $have_lzma"
+echo "Magick++ --with-magick-plus-plus=$with_magick_plus_plus $have_magick_plus_plus"
+echo "PERL --with-perl=$with_perl $have_perl"
+if test "${LIB_PNG}x" != 'x'
+then
+echo "PNG --with-png=$with_png $have_png ($LIB_PNG)"
+else
+echo "PNG --with-png=$with_png $have_png"
+fi
+echo "TIFF --with-tiff=$with_tiff $have_tiff"
+echo "TRIO --with-trio=$with_trio $have_trio"
+echo "WEBP --with-webp=$with_webp $have_webp"
+result_windows_font_dir='none'
+if test "${windows_font_dir}x" != 'x'
+then
+ result_windows_font_dir="${windows_font_dir}"
+fi
+echo "Windows fonts --with-windows-font-dir=$with_windows_font_dir $result_windows_font_dir"
+echo "WMF --with-wmf=$with_wmf $have_wmf"
+echo "X11 --with-x=$with_x $have_x"
+echo "XML --with-xml=$with_xml $have_xml"
+echo "ZLIB --with-zlib=$with_zlib $have_zlib"
+echo ""
+echo "X11 Configuration:"
+if test "$have_x" != 'no'
+then
+ echo " X_CFLAGS = $X_CFLAGS"
+ echo " X_PRE_LIBS = $X_PRE_LIBS"
+ echo " X_LIBS = $X_LIBS"
+ echo " X_EXTRA_LIBS = $X_EXTRA_LIBS"
+else
+ echo ""
+ echo " Not using X11."
+fi
+echo ""
+echo "Options used to compile and link:"
+echo " CC = $CC"
+echo " CFLAGS = $CFLAGS"
+echo " CPPFLAGS = $CPPFLAGS"
+echo " CXX = $CXX"
+echo " CXXFLAGS = $CXXFLAGS"
+echo " DEFS = $DEFS"
+echo " LDFLAGS = $LDFLAGS"
+echo " LIBS = $MAGICK_API_DEP_LIBS"
+echo ""
diff --git a/configure.ac b/configure.ac
new file mode 100755
index 0000000..4bb086c
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,3642 @@
+# Copyright (C) 2003-2016 GraphicsMagick Group
+# Copyright (C) 2002 ImageMagick Studio
+# Copyright (C) 1998, 1999 E. I. du Pont de Nemours and Company
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# GraphicsMagick Configure Script
+#
+# Written by Bob Friesenhahn <bfriesen@GraphicsMagick.org>
+#
+
+AC_PREREQ(2.69)
+AC_INIT(magick/magick.h)
+
+# Specify directory where m4 macros may be found.
+AC_CONFIG_MACRO_DIR([m4])
+
+# Directory where autotools helper scripts lives.
+AC_CONFIG_AUX_DIR([config])
+
+# Include the TAP driver
+AC_REQUIRE_AUX_FILE([tap-driver.sh])
+
+#
+# Save initial user-tunable values
+#
+LIBS_USER=$LIBS
+for var in CC CFLAGS CPPFLAGS CXX CXXCPP LDFLAGS LIBS ; do
+ eval isset=\${$var+set}
+ if test "$isset" = 'set' ; then
+ eval val=$`echo $var`
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS}'${var}=${val}' "
+ fi
+done
+AC_SUBST(DISTCHECK_CONFIG_FLAGS)
+
+# Source file containing package/library versioning information.
+. ${srcdir}/version.sh
+
+echo "configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}"
+dnl Compute the canonical host (run-time) system type variable
+AC_CANONICAL_HOST
+
+MAGICK_TARGET_CPU=$host_cpu
+AC_SUBST(MAGICK_TARGET_CPU)
+AC_DEFINE_UNQUOTED(MAGICK_TARGET_CPU,$MAGICK_TARGET_CPU,[Target Host CPU])
+
+MAGICK_TARGET_VENDOR=$host_vendor
+AC_SUBST(MAGICK_TARGET_VENDOR)
+AC_DEFINE_UNQUOTED(MAGICK_TARGET_VENDOR,$MAGICK_TARGET_VENDOR,[Target Host Vendor])
+
+MAGICK_TARGET_OS=$host_os
+AC_SUBST(MAGICK_TARGET_OS)
+AC_DEFINE_UNQUOTED(MAGICK_TARGET_OS,$MAGICK_TARGET_OS,[Target Host OS])
+
+# Compute newest and oldest interface numbers.
+MAGICK_LIB_INTERFACE_NEWEST=$MAGICK_LIBRARY_CURRENT
+MAGICK_LIB_INTERFACE_OLDEST=`expr ${MAGICK_LIBRARY_CURRENT} - ${MAGICK_LIBRARY_AGE}`
+
+# Substitute Magick library versioning
+AC_SUBST(MAGICK_LIBRARY_CURRENT)dnl
+AC_SUBST(MAGICK_LIBRARY_REVISION)dnl
+AC_SUBST(MAGICK_LIBRARY_AGE)dnl
+
+AC_SUBST(MAGICK_LIB_INTERFACE_NEWEST)
+AC_SUBST(MAGICK_LIB_INTERFACE_OLDEST)
+
+# Substitute Magick++ library versioning
+AC_SUBST(MAGICK_PLUS_PLUS_LIBRARY_CURRENT)
+AC_SUBST(MAGICK_PLUS_PLUS_LIBRARY_REVISION)
+AC_SUBST(MAGICK_PLUS_PLUS_LIBRARY_AGE)
+
+# Substitute Magick Wand library versioning
+AC_SUBST(MAGICK_WAND_LIBRARY_CURRENT)
+AC_SUBST(MAGICK_WAND_LIBRARY_REVISION)
+AC_SUBST(MAGICK_WAND_LIBRARY_AGE)
+
+AC_SUBST(PACKAGE_NAME)dnl
+AC_SUBST(PACKAGE_VERSION)dnl
+AC_SUBST(PACKAGE_VERSION_ADDENDUM)dnl
+AC_SUBST(PACKAGE_CHANGE_DATE)dnl
+AC_SUBST(PACKAGE_RELEASE_DATE)dnl
+
+# Substitute Mercurial branch tag
+AC_SUBST(HG_BRANCH_TAG)dnl
+
+# Definition used to define MagickLibVersion in version.h
+MAGICK_LIB_VERSION="0x"
+if test ${MAGICK_LIBRARY_CURRENT} -lt 10 ; then
+ MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}0
+fi
+MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}${MAGICK_LIBRARY_CURRENT}
+if test ${MAGICK_LIBRARY_AGE} -lt 10 ; then
+ MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}0
+fi
+MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}${MAGICK_LIBRARY_AGE}
+if test ${MAGICK_LIBRARY_REVISION} -lt 10 ; then
+ MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}0
+fi
+MAGICK_LIB_VERSION=${MAGICK_LIB_VERSION}${MAGICK_LIBRARY_REVISION}
+AC_SUBST(MAGICK_LIB_VERSION)
+
+# Definition used to define MagickLibVersionText in version.h
+MAGICK_LIB_VERSION_TEXT="${PACKAGE_VERSION}"
+AC_SUBST(MAGICK_LIB_VERSION_TEXT)
+
+# Definition used to define MagickLibVersionNumber in version.h
+MAGICK_LIB_VERSION_NUMBER="${MAGICK_LIBRARY_CURRENT},${MAGICK_LIBRARY_AGE},${MAGICK_LIBRARY_REVISION}"
+AC_SUBST(MAGICK_LIB_VERSION_NUMBER)
+
+# Ensure that make can run correctly
+AM_SANITY_CHECK
+
+# Generate configure header.
+AC_CONFIG_HEADERS([magick/magick_config.h magick/magick_config_api.h])
+
+AM_INIT_AUTOMAKE($PACKAGE_NAME,"${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}", ' ')
+
+# Enable support for silent build rules
+AM_SILENT_RULES
+
+# Regenerate config.status if ChangeLog or version.sh is updated.
+AC_SUBST([CONFIG_STATUS_DEPENDENCIES],['$(top_srcdir)/ChangeLog $(top_srcdir)/version.sh'])
+
+PERLMAINCC=$CC
+
+MAGICK_API_CFLAGS=''
+MAGICK_API_CPPFLAGS=''
+MAGICK_API_PC_CPPFLAGS=''
+MAGICK_API_LDFLAGS=''
+MAGICK_API_LIBS=''
+
+#
+# Standards compliance definitions
+#
+#AC_DEFINE(_XOPEN_SOURCE,500,[Required X Open interface level (500)])
+#AC_DEFINE(_POSIX_C_SOURCE,199506L,[Required POSIX interface level (199506L)])
+#AC_DEFINE(_ISOC99_SOURCE,1,[Code may make use of ISO C '99 features])
+#AC_DEFINE(__EXTENSIONS__,1,[Enable all API extensions (for Solaris)])
+#AC_DEFINE(_GNU_SOURCE,1,[Enable all API extensions (for GNU Linux libc)])
+#AC_DEFINE(_NETBSD_SOURCE,1,[Enable all API extensions (for NetBSD)])
+AC_USE_SYSTEM_EXTENSIONS
+
+#
+# Evaluate shell variable equivalents to Makefile directory variables
+#
+if test "x$prefix" = xNONE
+then
+ prefix=$ac_default_prefix
+fi
+# Let make expand exec_prefix.
+if test "x$exec_prefix" = xNONE
+then
+ exec_prefix='${prefix}'
+fi
+
+#
+eval "eval PREFIX_DIR=${prefix}"
+AC_SUBST(PREFIX_DIR)
+eval "eval EXEC_PREFIX_DIR=${exec_prefix}"
+AC_SUBST(EXEC_PREFIX_DIR)
+eval "eval BIN_DIR=$bindir"
+AC_SUBST(BIN_DIR)
+eval "eval SBIN_DIR=$sbindir"
+AC_SUBST(SBIN_DIR)
+eval "eval LIBEXEC_DIR=$libexecdir"
+AC_SUBST(LIBEXEC_DIR)
+eval "eval DATA_DIR=$datadir"
+AC_SUBST(DATA_DIR)
+eval "eval DOC_DIR=$docdir"
+AC_SUBST(DOC_DIR)
+eval "eval HTML_DIR=$htmldir"
+AC_SUBST(HTML_DIR)
+eval "eval SYSCONF_DIR=$sysconfdir"
+AC_SUBST(SYSCONF_DIR)
+eval "eval SHAREDSTATE_DIR=$sharedstatedir"
+AC_SUBST(SHAREDSTATE_DIR)
+eval "eval LOCALSTATE_DIR=$localstatedir"
+AC_SUBST(LOCALSTATE_DIR)
+eval "eval LIB_DIR=$libdir"
+AC_SUBST(LIB_DIR)
+eval "eval INCLUDE_DIR=$includedir"
+AC_SUBST(INCLUDE_DIR)
+eval "eval OLDINCLUDE_DIR=$oldincludedir"
+AC_SUBST(OLDINCLUDE_DIR)
+eval "eval INFO_DIR=$infodir"
+AC_SUBST(INFO_DIR)
+eval "eval MAN_DIR=$mandir"
+AC_SUBST(MAN_DIR)
+
+# Get full paths to source and build directories
+srcdirfull="`cd $srcdir && pwd`"
+builddir="`pwd`"
+
+WinPathScript="${srcdirfull}/winpath.sh"
+AC_SUBST([WinPathScript])
+
+#
+# Compute variables useful for running uninstalled software
+#
+MAGICK_CODER_MODULE_PATH="${builddir}/coders"
+MAGICK_CONFIGURE_SRC_PATH="${srcdirfull}/config"
+MAGICK_CONFIGURE_BUILD_PATH="${builddir}/config"
+MAGICK_FILTER_MODULE_PATH="${builddir}/filters"
+DIRSEP=':'
+case "${build_os}" in
+ mingw* )
+ MAGICK_CODER_MODULE_PATH=`$WinPathScript "${MAGICK_CODER_MODULE_PATH}" 0`
+ MAGICK_CONFIGURE_SRC_PATH=`$WinPathScript "${MAGICK_CONFIGURE_SRC_PATH}" 0`
+ MAGICK_CONFIGURE_BUILD_PATH=`$WinPathScript "${MAGICK_CONFIGURE_BUILD_PATH}" 0`
+ MAGICK_FILTER_MODULE_PATH=`$WinPathScript "${MAGICK_FILTER_MODULE_PATH}" 0`
+ ;;
+esac
+case "${host_os}" in
+ mingw* )
+ DIRSEP=';'
+ ;;
+esac
+AC_SUBST(MAGICK_CODER_MODULE_PATH)
+AC_SUBST(MAGICK_CONFIGURE_SRC_PATH)
+AC_SUBST(MAGICK_CONFIGURE_BUILD_PATH)
+AC_SUBST(MAGICK_FILTER_MODULE_PATH)
+AC_SUBST(DIRSEP)
+
+# Check for programs
+AC_PROG_CC
+AC_PROG_CC_STDC
+AC_PROG_CPP
+AM_PROG_LD
+AC_SUBST(LD)
+AM_PROG_CC_C_O # Necessary if objects are placed in subdirectories.
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_PROG_LN_S
+AC_PROG_AWK
+
+#
+# Tests for Windows
+#
+AC_EXEEXT
+AC_OBJEXT
+
+LIB_GDI32=''
+native_win32_build='no'
+cygwin_build='no'
+case "${host_os}" in
+ cygwin* )
+ cygwin_build='yes'
+ LIB_GDI32='-lgdi32'
+ ;;
+ mingw* )
+ native_win32_build='yes'
+ LIB_GDI32='-lgdi32'
+ ;;
+esac
+if test "${LIB_GDI32}x" != 'x'
+then
+ AC_DEFINE(HasWINGDI32,1,Define to use the Windows GDI32 library)
+fi
+AC_SUBST(LIB_GDI32)
+AM_CONDITIONAL(HasWINGDI32, test "${LIB_GDI32}x" != 'x' )
+AM_CONDITIONAL(WIN32_NATIVE_BUILD, test "${native_win32_build}" = 'yes' )
+AM_CONDITIONAL(CYGWIN_BUILD, test "${cygwin_build}" = 'yes' )
+
+WinPathScript="${srcdirfull}/winpath.sh"
+AC_SUBST(WinPathScript)
+
+#
+# Compiler flags tweaks
+#
+if test "${GCC}" != "yes"
+then
+ case "${host}" in
+ *-*-hpux* )
+ # aCC: HP ANSI C++ B3910B A.03.34
+ CFLAGS="${CFLAGS} -Wp,-H30000"
+ if test -n "${CXXFLAGS}"
+ then
+ CXXFLAGS='-AA'
+ else
+ CXXFLAGS="${CXXFLAGS} -AA"
+ fi
+ ;;
+ *-dec-osf5.* )
+ # Compaq alphaev68-dec-osf5.1 compiler
+ if test -n "${CXXFLAGS}"
+ then
+ CXXFLAGS='-std strict_ansi -noimplicit_include'
+ else
+ CXXFLAGS="${CXXFLAGS} -std strict_ansi -noimplicit_include"
+ fi
+ ;;
+ esac
+else
+ CFLAGS="${CFLAGS} -Wall"
+fi
+
+#
+# Determine POSIX threads settings
+#
+# Enable support for POSIX thread APIs
+AC_ARG_WITH(threads,
+ AS_HELP_STRING([--without-threads],
+ [disable POSIX threads API support]),
+ [with_threads=$withval],
+ [with_threads='yes'])
+
+have_threads=no
+if test "$with_threads" != 'no'
+then
+
+ ACX_PTHREAD()
+ if test "$acx_pthread_ok" = yes
+ then
+ have_threads=yes
+
+ DEF_THREAD="$PTHREAD_CFLAGS"
+ CFLAGS="$CFLAGS $DEF_THREAD"
+ CXXFLAGS="$CXXFLAGS $DEF_THREAD"
+
+ if test "$CC" != "$PTHREAD_CC"
+ then
+ AC_MSG_WARN([Replacing compiler $CC with compiler $PTHREAD_CC to support pthreads.])
+ CC="$PTHREAD_CC"
+ fi
+ if test "$CXX" != "$PTHREAD_CXX"
+ then
+ AC_MSG_WARN([Replacing compiler $CXX with compiler $PTHREAD_CXX to support pthreads.])
+ CXX="$PTHREAD_CXX"
+ fi
+ fi
+fi
+
+#
+# Determine options necessary to enable OpenMP support
+#
+# Sets Set the OPENMP_CFLAGS / OPENMP_CXXFLAGS / OPENMP_FFLAGS
+# variable to these options.
+
+AC_OPENMP([C])
+CFLAGS="$OPENMP_CFLAGS $CFLAGS"
+#CXXFLAGS="$OPENMP_CXXFLAGS $CXXFLAGS"
+#LDFLAGS="$LDFLAGS $OPENMP_CFLAGS"
+AC_SUBST(OPENMP_CFLAGS)
+
+# Allow the user to disable use of OpenMP where algorithms sometimes run slower.
+AC_ARG_ENABLE(openmp-slow,
+ AS_HELP_STRING([--enable-openmp-slow],
+ [enable OpenMP for algorithms which
+ sometimes run slower]),
+ [with_openmp_slow=$enableval],
+ [with_openmp_slow='no'])
+if test "$with_openmp_slow" = 'no'
+then
+ AC_DEFINE(DisableSlowOpenMP,1,[Disable OpenMP for algorithms which sometimes run slower])
+fi
+
+########
+#
+# Check for large file support
+#
+# According to the X/Open LFS standard, setting _FILE_OFFSET_BITS to 64
+# remaps standard functions to their 64-bit equivalents.
+#
+# The LFS_CPPFLAGS substition is used to support building PerlMagick.
+#
+#
+########
+AC_SYS_LARGEFILE
+
+# If the `fseeko' function is available, define `HAVE_FSEEKO'. Define
+# `_LARGEFILE_SOURCE' if necessary.
+AC_FUNC_FSEEKO
+
+LFS_CPPFLAGS=''
+if test "$enable_largefile" != no
+then
+ if test "$ac_cv_sys_file_offset_bits" != 'no'
+ then
+ LFS_CPPFLAGS="$LFS_CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits"
+ fi
+ if test "$ac_cv_sys_large_files" != 'no'
+ then
+ LFS_CPPFLAGS="$LFS_CPPFLAGS -D_LARGE_FILES=1"
+ fi
+ if test "$ac_cv_sys_largefile_source" != 'no'
+ then
+ LFS_CPPFLAGS="$LFS_CPPFLAGS -D_LARGEFILE_SOURCE=1"
+ fi
+fi
+AC_SUBST(LFS_CPPFLAGS)
+
+#
+# Configure libtool
+#
+
+# Configure libtool
+AC_LIBTOOL_DLOPEN
+LT_INIT([disable-shared win32-dll])
+LT_LANG([C++])
+AC_SUBST(LIBTOOL_DEPS)
+
+# Check to see if building shared libraries
+libtool_build_shared_libs='no'
+if test "$enable_shared" = 'yes'
+then
+ libtool_build_shared_libs='yes'
+fi
+
+# Check to see if building static libraries
+libtool_build_static_libs='no'
+if test "$enable_static" = 'yes'
+then
+ libtool_build_static_libs='yes'
+fi
+
+AM_CONDITIONAL(WITH_SHARED_LIBS, test "${libtool_build_shared_libs}" = 'yes')
+
+#
+# Enable support for building loadable modules
+#
+build_modules='no'
+AC_ARG_WITH(modules,
+ AS_HELP_STRING([--with-modules],
+ [enable building dynamically loadable
+ modules]),
+ [with_modules=$withval],
+ [with_modules='no'])
+
+# Only allow building loadable modules if we are building shared libraries
+if test "$with_modules" != 'no' ; then
+ if test "$libtool_build_shared_libs" = 'no' ; then
+ AC_MSG_WARN([Modules may only be built if building shared libraries is enabled.])
+ build_modules='no'
+ else
+ build_modules='yes'
+ fi
+fi
+if test "$build_modules" != 'no' ; then
+ AC_DEFINE(BuildMagickModules,1,Define if coders and filters are to be built as modules.)
+fi
+AM_CONDITIONAL(WITH_MODULES, test "$build_modules" != 'no')
+
+
+# Build a version of GraphicsMagick which operates uninstalled.
+# Used to build distributions located via MAGICK_HOME / executable path
+AC_ARG_ENABLE(installed,
+ AS_HELP_STRING([--disable-installed],
+ [disable building an installed GraphicsMagick]),
+ [with_installed=$enableval],
+ [with_installed='yes'])
+if test "$with_installed" = 'yes'
+then
+ AC_DEFINE(UseInstalledMagick,1,[GraphicsMagick is formally installed under prefix])
+else
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --disable-installed "
+fi
+
+# Enable broken/dangerous coders
+# EnableBrokenCoders CPP define and ENABLE_BROKEN_CODERS Automake conditional)
+AC_ARG_ENABLE(broken-coders,
+ AS_HELP_STRING([--enable-broken-coders],
+ [enable broken/dangerous file formats support]),
+ [with_broken_coders=$enableval],
+ [with_broken_coders='no'])
+if test "$with_broken_coders" = 'yes'
+then
+ AC_DEFINE(EnableBrokenCoders,1,[Enable broken/dangerous file formats support])
+fi
+AM_CONDITIONAL(ENABLE_BROKEN_CODERS, test "$with_broken_coders" != 'no')
+
+# Add configure option --enable-maintainer-mode which enables dependency
+# checking and generation useful to package maintainers. This is made an
+# option to avoid confusing end users.
+AM_MAINTAINER_MODE
+
+# Enable prof-based profiling support
+AC_ARG_ENABLE(prof,
+ AS_HELP_STRING([--enable-prof],
+ [enable 'prof' profiling support]),
+ [with_prof=$enableval],
+ [with_prof='no'])
+
+# Enable gprof-based profiling support
+AC_ARG_ENABLE(gprof,
+ AS_HELP_STRING([--enable-gprof],
+ [enable 'gprof' profiling support]),
+ [with_gprof=$enableval],
+ [with_gprof='no'])
+
+# Enable gcov-based profiling support
+AC_ARG_ENABLE(gcov,
+ AS_HELP_STRING([--enable-gcov],
+ [enable 'gcov' profiling support]),
+ [with_gcov=$enableval],
+ [with_gcov='no'])
+
+with_profiling='no'
+if test "$with_prof" = 'yes' || test "$with_gprof" = 'yes' || test "$with_gcov" = 'yes'
+then
+ with_profiling='yes'
+
+ if test "$libtool_build_shared_libs" = 'yes'
+ then
+ echo "Warning: Can not profile code using shared libraries"
+ fi
+fi
+
+# Enable prefixing library symbols with a common string
+AC_ARG_ENABLE(symbol-prefix,
+ AS_HELP_STRING([--enable-symbol-prefix],
+ [enable prefixing library symbols with "Gm"]),
+ [with_symbol_prefix=$enableval],
+ [with_symbol_prefix='no'])
+if test "$with_symbol_prefix" != 'no'
+then
+ AC_DEFINE(PREFIX_MAGICK_SYMBOLS,1,[Prefix Magick library symbols with a common string.])
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --enable-symbol-prefix "
+fi
+
+# Enable ImageMagick utilities compatibility shortcuts (default no)
+AC_ARG_ENABLE(magick-compat,
+ AS_HELP_STRING([--enable-magick-compat],
+ [install ImageMagick utility shortcuts]),
+ [with_magick_compat=$enableval],
+ [with_magick_compat='no'])
+AM_CONDITIONAL(MAGICK_COMPAT, test "$with_magick_compat" != 'no')
+
+# Number of bits in a Quantum
+AC_ARG_WITH(quantum-depth,
+ AS_HELP_STRING([--with-quantum-depth],
+ [number of bits in a pixel quantum (default 8)]),
+ [with_quantum_depth=$withval],
+ [with_quantum_depth=8])
+if test "$with_quantum_depth" != '8' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-quantum-depth=$with_quantum_depth "
+fi
+
+case "${with_quantum_depth}" in
+ 8 ) ;;
+ 16 ) ;;
+ 32 ) ;;
+ * ) AC_MSG_ERROR("Pixel quantum depth must have value of 8, 16, or 32") ;;
+esac
+QuantumDepth="$with_quantum_depth"
+AC_DEFINE_UNQUOTED(QuantumDepth,$QuantumDepth,[Number of bits in a pixel Quantum (8/16/32)])
+AC_SUBST(QuantumDepth)dnl
+
+# Enable QuantumDepth in shared library names
+AC_ARG_ENABLE(quantum-library-names,
+ AS_HELP_STRING([--enable-quantum-library-names],
+ [shared library name includes quantum
+ depth to allow shared libraries with
+ different quantum depths to co-exist in
+ same directory (only one can be used for
+ development)]),
+ [with_quantum_library_names=$enableval],
+ [with_quantum_library_names='no'])
+MAGICK_LT_RELEASE_OPTS=
+if test "$with_quantum_library_names" != 'no'
+then
+ MAGICK_LT_RELEASE_OPTS="-release Q${QuantumDepth}"
+fi
+AC_SUBST(MAGICK_LT_RELEASE_OPTS)
+
+# Disable/Enable support for full delegate paths in delegates.mgk
+AC_ARG_WITH(frozenpaths,
+ AS_HELP_STRING([--with-frozenpaths],
+ [enable frozen delegate paths]),
+ [with_frozenpaths=$withval],
+ [with_frozenpaths='no'])
+
+# Enable build/install of Magick++
+AC_ARG_WITH(magick-plus-plus,
+ AS_HELP_STRING([--without-magick-plus-plus],
+ [disable build/install of Magick++]),
+ [with_magick_plus_plus=$withval],
+ [with_magick_plus_plus='yes'])
+
+# Enable build/install of PerlMagick.
+AC_ARG_WITH(perl,
+ AS_HELP_STRING([--with-perl@<:@=PERL@:>@],
+ [enable build/install of PerlMagick and optionally specify perl to use]),
+ [with_perl=$withval],
+ [with_perl='no'])
+
+# Options to pass when configuring PerlMagick
+AC_ARG_WITH(perl-options,
+ AS_HELP_STRING([--with-perl-options=OPTIONS],
+ [options to pass on command-line when
+ generating PerlMagick's Makefile from Makefile.PL]),
+ [PERL_MAKE_OPTIONS=$withval])
+AC_SUBST(PERL_MAKE_OPTIONS)
+
+
+# Disable BZLIB (bzip2 library)
+AC_ARG_WITH(bzlib,
+ AS_HELP_STRING([--without-bzlib],
+ [disable BZLIB support]),
+ [with_bzlib=$withval],
+ [with_bzlib='yes'])
+if test "$with_bzlib" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-bzlib=$with_bzlib "
+fi
+
+# Disable Display Postscript.
+AC_ARG_WITH(dps,
+ AS_HELP_STRING([--without-dps],
+ [disable Display Postscript support]),
+ [with_dps=$withval],
+ [with_dps='yes'])
+if test "$with_dps" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-dps=$with_dps "
+fi
+
+# Enable FlashPIX.
+AC_ARG_WITH(fpx,
+ AS_HELP_STRING([--with-fpx],
+ [enable FlashPIX support]),
+ [with_fpx=$withval],
+ [with_fpx='no'])
+if test "$with_fpx" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-fpx=$with_fpx "
+fi
+
+# Enable Ghostscript library support.
+AC_ARG_WITH(gslib,
+ AS_HELP_STRING([--with-gslib],
+ [enable Ghostscript library support (not recommended)]),
+ [with_gslib=$withval],
+ [with_gslib='no'])
+if test "$with_gslib" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-gslib=$with_gslib "
+fi
+
+# Disable JBIG.
+AC_ARG_WITH(jbig,
+ AS_HELP_STRING([--without-jbig],
+ [disable JBIG support]),
+ [with_jbig=$withval],
+ [with_jbig='yes'])
+if test "$with_jbig" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-jbig=$with_jbig "
+fi
+
+# Disable WEBP.
+AC_ARG_WITH(webp,
+ AS_HELP_STRING([--without-webp],
+ [disable WEBP support]),
+ [with_webp=$withval],
+ [with_webp='yes'])
+if test "$with_webp" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-webp=$with_webp "
+fi
+
+# Disable JPEG.
+AC_ARG_WITH(jpeg,
+ AS_HELP_STRING([--without-jpeg],
+ [disable JPEG support]),
+ [with_jpeg=$withval],
+ [with_jpeg='yes'])
+if test "$with_jpeg" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-jpeg=$with_jpeg "
+fi
+
+# Disable JPEG Version 2.
+AC_ARG_WITH(jp2,
+ AS_HELP_STRING([--without-jp2],
+ [disable JPEG v2 support]),
+ [with_jp2=$withval],
+ [with_jp2='yes'])
+if test "$with_jp2" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-jp2=$with_jp2 "
+fi
+
+# Disable LCMS2.
+AC_ARG_WITH(lcms2,
+ AS_HELP_STRING([--without-lcms2],
+ [disable lcms (v2.X) support]),
+ [with_lcms2=$withval],
+ [with_lcms2='yes'])
+if test "$with_lcms2" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-lcms2=$with_lcms2 "
+fi
+
+# Disable LZMA (lzma library)
+AC_ARG_WITH(lzma,
+ AS_HELP_STRING([--without-lzma],
+ [disable LZMA support]),
+ [with_lzma=$withval],
+ [with_lzma='yes'])
+if test "$with_lzma" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-lzma=$with_lzma "
+fi
+
+# # Disable MPEG.
+# AC_ARG_WITH(mpeg2,
+# AS_HELP_STRING([--without-mpeg2],
+# [disable MPEG support]),
+# [with_mpeg2=$withval],
+# [with_mpeg2='yes'])
+
+# Disable PNG.
+AC_ARG_WITH(png,
+ AS_HELP_STRING([--without-png],
+ [disable PNG support]),
+ [with_png=$withval],
+ [with_png='yes'])
+if test "$with_png" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-png=$with_png "
+fi
+
+# Disable TIFF.
+AC_ARG_WITH(tiff,
+ AS_HELP_STRING([--without-tiff],
+ [disable TIFF support]),
+ [with_tiff=$withval],
+ [with_tiff='yes'])
+if test "$with_tiff" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-tiff=$with_tiff "
+fi
+
+# Disable TRIO.
+AC_ARG_WITH(trio,
+ AS_HELP_STRING([--without-trio],
+ [disable TRIO support]),
+ [with_trio=$withval],
+ [with_trio='yes'])
+if test "$with_trio" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-trio=$with_trio "
+fi
+
+# Disable TTF.
+AC_ARG_WITH(ttf,
+ AS_HELP_STRING([--without-ttf],
+ [disable TrueType support]),
+ [with_ttf=$withval],
+ [with_ttf='yes'])
+if test "$with_ttf" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-ttf=$with_ttf "
+fi
+
+# Enable use of Solaris libumem (object-caching memory allocation library).
+# Available as a SourceForge project http://sourceforge.net/projects/umem/ or
+# https://labs.omniti.com/trac/portableumem/.
+AC_ARG_WITH(umem,
+ AS_HELP_STRING([--with-umem],
+ [enable umem memory allocation library support]),
+ [with_umem=$withval],
+ [with_umem='no'])
+if test "$with_umem" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-umem=$with_umem "
+fi
+
+# Disable WMF.
+AC_ARG_WITH(wmf,
+ AS_HELP_STRING([--without-wmf],
+ [disable WMF support]),
+ [with_wmf=$withval],
+ [with_wmf='yes'])
+if test "$with_wmf" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-wmf=$with_wmf "
+fi
+
+# Set default font search path
+AC_ARG_WITH(fontpath,
+ AS_HELP_STRING([--with-fontpath=DIR],
+ [prepend to default font search path]),
+ [with_fontpath=$withval],
+ [with_fontpath=''])
+if test "$with_fontpath" != "yes" && test -z "$with_fontpath"
+then
+ with_fontpath=''
+else
+ AC_DEFINE_UNQUOTED(MAGICK_FONT_PATH,"$with_fontpath",Define to prepend to default font search path.)
+fi
+if test "$with_fontpath=" != '' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-fontpath=$with_fontpath "
+fi
+
+# Set Ghostscript font directory
+AC_ARG_WITH(gs-font-dir,
+ AS_HELP_STRING([--with-gs-font-dir=DIR],
+ [directory containing Ghostscript fonts]),
+ [with_gs_font_dir=$withval],
+ [with_gs_font_dir='default'])
+if test "$with_gs_font_dir" != 'default' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-gs-font-dir=$with_gs_font_dir "
+fi
+
+# Set Windows font directory
+AC_ARG_WITH(windows-font-dir,
+ AS_HELP_STRING([--with-windows-font-dir=DIR],
+ [directory containing MS-Windows fonts]),
+ [with_windows_font_dir=$withval],
+ [with_windows_font_dir=''])
+if test "$with_windows_font_dir" != '' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-windows-font-dir=$with_windows_font_dir "
+fi
+
+# Disable XML.
+AC_ARG_WITH(xml,
+ AS_HELP_STRING([--without-xml],
+ [disable XML support]),
+ [with_xml=$withval],
+ [with_xml='yes'])
+if test "$with_xml" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-xml=$with_xml "
+fi
+
+AC_ARG_WITH(zlib,
+ AS_HELP_STRING([--without-zlib],
+ [disable ZLIB support]),
+ [with_zlib=$withval],
+ [with_zlib='yes'])
+if test "$with_zlib" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-zlib=$with_zlib "
+fi
+
+#
+# Specify path to shared libstdc++ if not in normal location
+#
+AC_ARG_WITH(libstdc,
+ AS_HELP_STRING([--with-libstdc=DIR],
+ [use libstdc++ in DIR (for GNU C++)]),
+ [if test "$withval" != no && test "$withval" != yes; then
+ if test -d "$withval"; then
+ LIBSTDCLDFLAGS="-L$withval"
+ fi
+ fi])
+AC_SUBST(LIBSTDCLDFLAGS)
+
+# Does gcc required -traditional?
+AC_PROG_GCC_TRADITIONAL
+
+########
+#
+# Set defines required to build DLLs and modules using MinGW
+#
+########
+# These options are set for multi-thread DLL module build
+# libMagick: _DLL _MAGICKMOD_ _MAGICKLIB_
+# module: _DLL
+# executable/Magick++: _DLL _MAGICKMOD_
+MODULE_EXTRA_CPPFLAGS=''
+LIBRARY_EXTRA_CPPFLAGS=''
+if test "${native_win32_build}" = 'yes'
+then
+ if test "${libtool_build_shared_libs}" = 'yes'
+ then
+ CPPFLAGS="$CPPFLAGS -D_DLL"
+ MAGICK_API_CPPFLAGS="$MAGICK_API_CPPFLAGS -D_DLL"
+ MAGICK_API_PC_CPPFLAGS="$MAGICK_API_PC_CPPFLAGS -D_DLL"
+ LIBRARY_EXTRA_CPPFLAGS="$LIBRARY_EXTRA_CPPFLAGS -D_MAGICKLIB_"
+
+ if test "$build_modules" = 'yes'
+ then
+ LIBRARY_EXTRA_CPPFLAGS="$LIBRARY_EXTRA_CPPFLAGS -D_MAGICKMOD_"
+ else
+ MODULE_EXTRA_CPPFLAGS="$MODULE_EXTRA_CPPFLAGS -D_MAGICKLIB_"
+ fi
+
+ else
+ CPPFLAGS="$CPPFLAGS -D_LIB"
+ MAGICK_API_CPPFLAGS="$MAGICK_API_CPPFLAGS -D_LIB"
+ MAGICK_API_PC_CPPFLAGS="$MAGICK_API_PC_CPPFLAGS -D_LIB"
+
+ fi
+ if test "$with_threads" = 'yes'
+ then
+ CPPFLAGS="$CPPFLAGS -D_MT"
+ MAGICK_API_CPPFLAGS="$MAGICK_API_CPPFLAGS -D_MT"
+ MAGICK_API_PC_CPPFLAGS="$MAGICK_API_PC_CPPFLAGS -D_MT"
+ fi
+fi
+AC_SUBST(MODULE_EXTRA_CPPFLAGS)
+AC_SUBST(LIBRARY_EXTRA_CPPFLAGS)
+
+# Check standard headers
+AC_HEADER_STDC
+AC_HEADER_DIRENT
+
+# Check additional headers
+AC_CHECK_HEADERS([machine/param.h mach-o/dyld.h process.h sun_prefetch.h sys/mman.h sys/resource.h sys/times.h sys/types.h])
+AC_CHECK_HEADERS([wincrypt.h],[],[],[#include <windows.h>])
+
+
+########
+#
+# Checks for typedefs, structures, and compiler characteristics.
+#
+########
+
+# If the C compiler does not fully support the ANSI C qualifier const,
+# define const to be empty.
+AC_C_CONST
+
+# If the C compiler supports the keyword restrict, do
+# nothing. Otherwise define restrict to __restrict__ or __restrict if
+# it accepts one of those, otherwise define restrict to be empty.
+AC_C_RESTRICT
+
+# If the C compiler supports the keyword inline, do nothing. Otherwise
+# define inline to __inline__ or __inline if it accepts one of those,
+# otherwise define inline to be empty.
+AC_C_INLINE
+
+# If words are stored with the most significant byte first (like
+# Motorola and SPARC CPUs), define `WORDS_BIGENDIAN'.
+AC_C_BIGENDIAN
+
+# Define mode_t to a suitable type, if standard headers do not define it.
+AC_TYPE_MODE_T
+
+# Define off_t to a suitable type, if standard headers do not define it.
+AC_TYPE_OFF_T
+
+# Define pid_t to a suitable type, if standard headers do not define it.
+AC_TYPE_PID_T
+
+# Define size_t to a suitable type, if standard headers do not define it.
+AC_TYPE_SIZE_T
+
+# Define ssize_t to a suitable type, if standard headers do not define it.
+AC_TYPE_SSIZE_T
+
+# If C compiler supports a working long double type with more range
+# or precision than the double type then define HAVE_LONG_DOUBLE_WIDER.
+AC_TYPE_LONG_DOUBLE_WIDER
+
+# If the C type char is unsigned, define __CHAR_UNSIGNED__, unless the
+# C compiler predefines it.
+AC_C_CHAR_UNSIGNED
+
+# Obtain size of an 'signed short' and define as SIZEOF_SIGNED_SHORT
+AC_CHECK_SIZEOF(signed short)
+
+# Obtain size of an 'unsigned short' and define as SIZEOF_UNSIGNED_SHORT
+AC_CHECK_SIZEOF(unsigned short)
+
+# Obtain size of an 'signed int' and define as SIZEOF_SIGNED_INT
+AC_CHECK_SIZEOF(signed int)
+
+# Obtain size of an 'unsigned int' and define as SIZEOF_UNSIGNED_INT
+AC_CHECK_SIZEOF(unsigned int)
+
+# Obtain size of a 'signed long' and define as SIZEOF_SIGNED_LONG
+AC_CHECK_SIZEOF(signed long)
+
+# Obtain size of a 'unsigned long' and define as SIZEOF_UNSIGNED_LONG
+AC_CHECK_SIZEOF(unsigned long)
+
+# Obtain size of a 'long long' and define as SIZEOF_SIGNED_LONG_LONG. If
+# 'signed long long' is not supported then the value defined is zero.
+AC_CHECK_SIZEOF(signed long long)
+
+# Obtain size of a 'unsigned long long' and define as
+# SIZEOF_UNSIGNED_LONG_LONG. If 'unsigned long long' is not
+# supported then the value defined is zero.
+AC_CHECK_SIZEOF(unsigned long long)
+
+# Obtain size of off_t and define as SIZEOF_OFF_T
+AC_CHECK_SIZEOF(off_t)
+
+# Obtain size of size_t and define as SIZEOF_SIZE_T
+AC_CHECK_SIZEOF(size_t)
+
+# Obtain size of an unsigned int pointer and define as SIZEOF_UNSIGNED_INTP
+AC_CHECK_SIZEOF(unsigned int*)
+
+# If `signal.h' declares signal as returning a pointer to a function
+# returning void, define RETSIGTYPE to be void; otherwise, define it
+# to be int.
+AC_TYPE_SIGNAL
+
+# Test for C compiler __func__ support
+if test "$ac_cv_have_C__func__" != 'yes' ; then
+AC_CACHE_CHECK(for C compiler __func__ support, ac_cv_have_C__func__,
+[AC_TRY_COMPILE(
+,
+changequote(<<, >>)dnl
+<<
+const char *func=__func__;
+return (func != 0 ? 0 : 1);
+>>,
+changequote([, ])dnl
+ac_cv_have_C__func__='yes',
+ac_cv_have_C__func__='no')])
+
+if test "$ac_cv_have_C__func__" = 'yes' ; then
+ AC_DEFINE(HAS_C__func__,1,Define if C compiler supports __func__)
+fi
+fi
+
+#
+# Compute sized types for current CPU and compiler options.
+#
+# The reason why we don't use autoconf's recent built-in support for
+# stdint.h types is because doing it ourself seems easier for dealing
+# with Windows builds which don't use configure.
+#
+
+AC_MSG_CHECKING(for signed 8-bit type)
+INT8_T='signed char'
+AC_MSG_RESULT($INT8_T)
+AC_SUBST(INT8_T)
+
+AC_MSG_CHECKING(for unsigned 8-bit type)
+UINT8_T='unsigned char'
+AC_MSG_RESULT($UINT8_T)
+AC_SUBST(UINT8_T)
+
+AC_MSG_CHECKING(for signed 16-bit type)
+INT16_T='signed short'
+AC_MSG_RESULT($INT16_T)
+AC_SUBST(INT16_T)
+
+AC_MSG_CHECKING(for unsigned 16-bit type)
+UINT16_T='unsigned short'
+AC_MSG_RESULT($UINT16_T)
+AC_SUBST(UINT16_T)
+
+AC_MSG_CHECKING(for signed 32-bit type)
+INT32_T='none'
+INT32_F='none'
+if test $ac_cv_sizeof_signed_int -eq 4
+then
+ INT32_T='signed int'
+ INT32_F='""'
+elif test $ac_cv_sizeof_signed_long -eq 4
+then
+ INT32_T='signed long'
+ INT32_F='"l"'
+fi
+AC_MSG_RESULT($INT32_T)
+AC_SUBST(INT32_T)
+AC_SUBST(INT32_F)
+
+AC_MSG_CHECKING(for unsigned 32-bit type)
+UINT32_T='none'
+UINT32_F='none'
+if test $ac_cv_sizeof_unsigned_int -eq 4
+then
+ UINT32_T='unsigned int'
+ UINT32_F='""'
+elif test $ac_cv_sizeof_unsigned_long -eq 4
+then
+ UINT32_T='unsigned long'
+ UINT32_F='"l"'
+fi
+AC_MSG_RESULT($UINT32_T)
+AC_SUBST(UINT32_T)
+AC_SUBST(UINT32_F)
+
+AC_MSG_CHECKING(for signed 64-bit type)
+INT64_T='none'
+INT64_F='none'
+if test $ac_cv_sizeof_signed_long -eq 8
+then
+ INT64_T='signed long'
+ INT64_F='"l"'
+elif test $ac_cv_sizeof_signed_long_long -eq 8
+then
+ INT64_T='signed long long'
+ INT64_F='"ll"'
+fi
+case "${host_os}" in
+ mingw* )
+ INT64_F='"I64"'
+ ;;
+esac
+AC_MSG_RESULT($INT64_T)
+AC_SUBST(INT64_T)
+AC_SUBST(INT64_F)
+
+AC_MSG_CHECKING(for unsigned 64-bit type)
+UINT64_T='none'
+UINT64_F='none'
+if test $ac_cv_sizeof_unsigned_long -eq 8
+then
+ UINT64_T='unsigned long'
+ UINT64_F='"l"'
+elif test $ac_cv_sizeof_unsigned_long_long -eq 8
+then
+ UINT64_T='unsigned long long'
+ UINT64_F='"ll"'
+fi
+case "${host_os}" in
+ mingw* )
+ UINT64_F='"I64"'
+ ;;
+esac
+AC_MSG_RESULT($UINT64_T)
+AC_SUBST(UINT64_T)
+AC_SUBST(UINT64_F)
+
+AC_MSG_CHECKING(for unsigned maximum type)
+UINTMAX_T='none'
+UINTMAX_F='none'
+if test "$UINT64_T" != 'none'
+then
+ UINTMAX_T=$UINT64_T
+ UINTMAX_F=$UINT64_F
+elif test "$UINT32_T" != 'none'
+then
+ UINTMAX_T=$UINT32_T
+ UINTMAX_F=$UINT32_F
+fi
+AC_MSG_RESULT($UINTMAX_T)
+AC_SUBST(UINTMAX_T)
+AC_SUBST(UINTMAX_F)
+
+AC_MSG_CHECKING(for pointer difference type)
+UINTPTR_T='none'
+UINTPTR_F='none'
+if test $ac_cv_sizeof_unsigned_long -eq $ac_cv_sizeof_unsigned_intp
+then
+ UINTPTR_T='unsigned long'
+ UINTPTR_F='"l"'
+elif test $ac_cv_sizeof_unsigned_long_long -eq $ac_cv_sizeof_unsigned_intp
+then
+ UINTPTR_T='unsigned long long'
+ UINTPTR_F='"ll"'
+fi
+AC_MSG_RESULT($UINTPTR_T)
+AC_SUBST(UINTPTR_T)
+AC_SUBST(UINTPTR_F)
+
+MAGICK_SIZE_T='none'
+MAGICK_SIZE_T_F='none'
+MAGICK_SSIZE_T='none'
+MAGICK_SSIZE_T_F='none'
+AC_MSG_CHECKING(for size_t format specification)
+if test $ac_cv_sizeof_size_t -eq $ac_cv_sizeof_unsigned_long
+then
+ # Normal case for LP32 and LP64
+ MAGICK_SIZE_T='unsigned long'
+ MAGICK_SIZE_T_F='"l"'
+ MAGICK_SSIZE_T='signed long'
+ MAGICK_SSIZE_T_F='"l"'
+elif test $ac_cv_sizeof_size_t -eq $ac_cv_sizeof_unsigned_long_long
+then
+ # Maybe a LLP64 architecture like WIN64
+ case "${host_os}" in
+ mingw* )
+ MAGICK_SIZE_T='unsigned long long'
+ MAGICK_SIZE_T_F='"I64"'
+ MAGICK_SSIZE_T='signed long long'
+ MAGICK_SSIZE_T_F='"I64"'
+ ;;
+ *)
+ MAGICK_SIZE_T='unsigned long long'
+ MAGICK_SIZE_T_F='"ll"'
+ MAGICK_SSIZE_T='signed long long'
+ MAGICK_SSIZE_T_F='"ll"'
+ ;;
+ esac
+fi
+AC_MSG_RESULT($MAGICK_SIZE_T_F)
+AC_SUBST(MAGICK_SIZE_T)
+AC_SUBST(MAGICK_SIZE_T_F)
+AC_SUBST(MAGICK_SSIZE_T)
+AC_SUBST(MAGICK_SSIZE_T_F)
+
+
+########
+#
+# Check for functions
+#
+########
+GM_FUNC_MMAP_FILEIO
+AC_CHECK_FUNCS([atoll CryptGenRandom \
+ clock_getres clock_gettime ctime_r _exit fcntl fstatvfs ftime getexecname \
+ getc_unlocked getpagesize getrlimit getpid lltostr localtime_r madvise \
+ _NSGetExecutablePath _pclose pclose poll _popen popen posix_fadvise \
+ posix_fallocate posix_madvise posix_memalign posix_spawnp pread pwrite \
+ putc_unlocked raise rand_r readdir_r readlink realpath select seekdir \
+ setrlimit sigemptyset sigaction spawnvp strerror strerror_r strlcat strlcpy \
+ strtoll sysconf times telldir ulltostr vsprintf vsnprintf qsort_r])
+
+########
+#
+# Check for function prototypes
+#
+########
+
+AC_CHECK_DECLS([pread, pwrite],[],[],[
+#include <unistd.h>])
+
+AC_CHECK_DECLS([strlcpy],[],[],[
+#include <strings.h>])
+
+AC_CHECK_DECLS([vsnprintf],[],[],[
+#include <stdio.h>
+#include <stdarg.h>])
+
+#######
+#
+# Check for /dev/urandom device
+#
+#######
+AC_CACHE_CHECK(for /dev/urandom,gm_cv_dev_urandom,
+[ gm_cv_dev_urandom=no
+ if test -c /dev/urandom
+ then
+ gm_cv_dev_urandom=yes
+ fi])
+ if test "${gm_cv_dev_urandom}" = yes
+ then
+ AC_DEFINE(HAVE_DEV_URANDOM,1,[Have a /dev/urandom device for producing random bytes])
+ fi
+
+########
+#
+# Try to find a command which reports usable physical memory
+#
+########
+MAGICK_PHYSICAL_MEMORY_COMMAND=''
+case "${host}" in
+ *-*-freebsd* | *-apple-darwin*)
+ AC_PATH_PROG(SysCtlDelegate,sysctl,)
+ if test "${SysCtlDelegate}X" != 'X'
+ then
+ # "sysctl -n hw.physmem" became available in FreeBSD 2.0
+ # Apple's Darwin is based on FreeBSD and supports sysctl
+ MAGICK_PHYSICAL_MEMORY_COMMAND="${SysCtlDelegate} -n hw.physmem"
+ fi
+ ;;
+esac
+if test "${MAGICK_PHYSICAL_MEMORY_COMMAND}X" != 'X'
+then
+ AC_DEFINE_UNQUOTED(MAGICK_PHYSICAL_MEMORY_COMMAND,
+ "${MAGICK_PHYSICAL_MEMORY_COMMAND}",
+ [Command which returns total physical memory in bytes])
+fi
+
+########
+#
+# C++ Support Tests (For Magick++)
+#
+########
+have_magick_plus_plus='no'
+if test "$with_magick_plus_plus" = 'yes'
+then
+ OLIBS="$LIBS"
+ LIBS=''
+ AC_LANG_PUSH(C++)
+
+# Full set of headers used ...
+# algorithm cctype cerrno cmath cstdio cstdlib cstring ctime exception
+# functional iomanip iosfwd iostream iterator list string strstream utility
+ AC_LANG_CPLUSPLUS
+ AC_PROG_CXX
+ AC_CXX_BOOL
+ AC_CXX_CONST_CAST
+ AC_CXX_DEFAULT_TEMPLATE_PARAMETERS
+ AC_CXX_EXCEPTIONS
+ AC_CXX_NAMESPACES
+ AC_CXX_EXPLICIT
+ AC_CXX_HAVE_STD
+ AC_CXX_HAVE_STL
+ AC_CXX_IOS_BINARY
+ AC_CXX_MUTABLE
+ AC_CXX_NEW_FOR_SCOPING
+ AC_CXX_STATIC_CAST
+ AC_CXX_TEMPLATES
+
+ # Test for C++ compiler __func__ support
+ if test "$ac_cv_have_CPP__func__" != 'yes' ; then
+ AC_CACHE_CHECK(for C++ compiler __func__ support, ac_cv_have_CPP__func__,
+ [AC_TRY_COMPILE(
+ ,
+ changequote(<<, >>)dnl
+ <<
+ const char *func=__func__;
+ return (func != 0 ? 0 : 1);
+ >>,
+ changequote([, ])dnl
+ ac_cv_have_CPP__func__='yes',
+ ac_cv_have_CPP__func__='no')])
+
+ if test "$ac_cv_have_CPP__func__" = 'yes' ; then
+ AC_DEFINE(HAS_CPP__func__,1,Define if C++ compiler supports __func__)
+ fi
+ fi
+
+ AC_LANG_POP
+
+ AC_MSG_CHECKING(whether C++ compiler is sufficient for Magick++)
+ if \
+ test $ac_cv_cxx_bool = 'yes' && \
+ test $ac_cv_cxx_const_cast = 'yes' &&
+ test $ac_cv_cxx_default_template_parameters = 'yes' &&
+ test $ac_cv_cxx_exceptions = 'yes' && \
+ test $ac_cv_cxx_explicit = 'yes' && \
+ test $ac_cv_cxx_have_std = 'yes' && \
+ test $ac_cv_cxx_have_stl = 'yes' && \
+ test $ac_cv_cxx_mutable = 'yes' && \
+ test $ac_cv_cxx_namespaces = 'yes' && \
+ test $ac_cv_cxx_new_for_scoping = 'yes' && \
+ test $ac_cv_cxx_static_cast = 'yes' && \
+ test $ac_cv_cxx_templates = 'yes'
+ then
+ have_magick_plus_plus='yes'
+ else
+ have_magick_plus_plus='no (failed tests)'
+ fi
+ AC_MSG_RESULT($have_magick_plus_plus)
+ LIBS="$OLIBS"
+fi
+AM_CONDITIONAL(WITH_MAGICK_PLUS_PLUS, test "$have_magick_plus_plus" = 'yes')
+
+# Assume that delegate headers and libraries may reside under same
+# directory as GraphicsMagick installation prefix.
+#LDFLAGS="$LDFLAGS -L$LIB_DIR"
+#CPPFLAGS="$CPPFLAGS -I$INCLUDE_DIR"
+MAGICK_API_CPPFLAGS="-I$INCLUDE_DIR/GraphicsMagick $MAGICK_API_CPPFLAGS"
+
+#
+# Find the X11 RGB database
+#
+AC_CACHE_CHECK(for X11 configure files,gm_cv_x_configure,
+[# Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /lib/usr/lib/X11 \
+ /usr/X11/lib \
+ /usr/X11R4/lib \
+ /usr/X11R5/lib \
+ /usr/X11R6/lib \
+ /usr/X11R7/lib \
+ /usr/X386/lib \
+ /usr/XFree86/lib/X11 \
+ /usr/athena/lib \
+ /usr/lib \
+ /usr/lib/X11 \
+ /usr/lib/X11R4 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R7 \
+ /usr/local/X11/lib \
+ /usr/local/X11R4/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R7/lib \
+ /usr/local/lib \
+ /usr/local/lib/X11 \
+ /usr/local/lib/X11R4 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R7 \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ /usr/unsupported/lib \
+ /usr/x386/lib \
+ ; \
+ do
+ if test -f "$ac_dir/X11/rgb.txt"
+ then
+ gm_cv_x_configure="$ac_dir/X11/"
+ break
+ elif test -f "$ac_dir/rgb.txt"
+ then
+ gm_cv_x_configure="$ac_dir/"
+ break
+ fi
+
+ done])
+X11ConfigurePath="$gm_cv_x_configure"
+case "${build_os}" in
+ mingw* )
+ X11ConfigurePath=`$WinPathScript "$X11ConfigurePath=" 1`
+ ;;
+esac
+AC_DEFINE_UNQUOTED(X11ConfigurePath,"X11ConfigurePath",Location of X11 configure files)
+
+#
+# Find Posix threads library
+#
+LIB_THREAD=''
+if test "$with_threads" != 'no' && test "$have_threads" = 'yes'
+then
+
+ if test "x$PTHREAD_LIBS" = "x"
+ then
+ case "${host_cpu}-${host_os}" in
+ *-freebsd*)
+ MAGICK_CHECK_PTHREAD_LIB(c_r,PTHREAD_LIBS=-lc_r) ;;
+ esac
+ fi
+
+ for lib in pthread pthreads
+ do
+ if test "x$PTHREAD_LIBS" = "x" ; then
+ MAGICK_CHECK_PTHREAD_LIB([$lib],[PTHREAD_LIBS=-l$lib])
+ fi
+ done
+
+ LIB_THREAD="$PTHREAD_LIBS"
+ LIBS="$LIBS $LIB_THREAD"
+fi
+AC_SUBST(LIB_THREAD)
+
+
+#
+# Check for Solaris-derived libumem
+#
+have_umem='no'
+LIB_UMEM=''
+if test "$with_umem" != 'no'
+then
+ AC_MSG_CHECKING(for UMEM support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(umem.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(umem,umem_alloc,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(umem,umem_free,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if umem memory allocation library is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_umem='no (failed tests)'
+ else
+ LIB_UMEM='-lumem'
+ LIBS="$LIB_UMEM $LIBS"
+ AC_DEFINE(HasUMEM,1,Define if you have umem memory allocation library)
+ AC_MSG_RESULT(yes)
+ have_umem='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasUMEM, test "$have_umem" = 'yes')
+AC_SUBST(LIB_UMEM)
+
+
+#
+# Find OpenMP library
+#
+LIB_OMP=''
+if test "${OPENMP_CFLAGS}x" != 'x'
+then
+ if test "${GCC}" = "yes"
+ then
+ # Open64 (passes for GCC but uses different OpenMP implementation)
+ if test "x$LIB_OMP" = x ; then
+ if $CC --version 2>&1 | grep Open64 > /dev/null ; then
+ AC_CHECK_LIB(openmp,omp_get_num_procs,LIB_OMP="-lopenmp",,)
+ fi
+ fi
+ # Clang (passes for GCC but uses different OpenMP implementation)
+ if test "x$LIB_OMP" = x ; then
+ if $CC --version 2>&1 | grep clang > /dev/null ; then
+ AC_CHECK_LIB(omp,GOMP_parallel_start,LIB_OMP="-lomp",,)
+ fi
+ fi
+ # GCC
+ if test "x$LIB_OMP" = x ; then
+ AC_CHECK_LIB(gomp,GOMP_parallel_start,LIB_OMP="-lgomp",,)
+ fi
+ else
+ # Sun CC
+ if test "x$LIB_OMP" = x ; then
+ AC_CHECK_LIB(mtsk,sunw_mp_register_warn,LIB_OMP="-lmtsk",,)
+ fi
+ # AIX xlc
+ if test "x$LIB_OMP" = x ; then
+ AC_CHECK_LIB(xlsmp,_xlsmpFlush,LIB_OMP="-lxlsmp",,)
+ fi
+ # SGI IRIX 6.5 MIPSpro C/C++
+ if test "x$LIB_OMP" = x ; then
+ AC_CHECK_LIB(mp,mp_destroy,LIB_OMP="-lmp",,)
+ fi
+ fi
+ LIBS="$LIB_OMP $LIBS"
+fi
+AC_SUBST(LIB_OMP)
+
+#
+# Find math library
+#
+LIB_MATH=''
+AC_CHECK_LIB(m,sqrt,LIB_MATH="-lm",,)
+LIBS="$LIB_MATH $LIBS"
+AC_SUBST(LIB_MATH)
+
+
+#
+# If vsnprintf is missing, look for TRIO
+#
+have_trio='no'
+LIB_TRIO=''
+if test "$ac_cv_func_vsnprintf" != 'yes' && test "$with_trio" != 'no'
+then
+ AC_MSG_CHECKING(for TRIO vsnprintf replacement)
+ AC_CHECK_LIB(trio,trio_vsnprintf,have_trio='yes',,)
+ if test "$have_trio" = 'yes'
+ then
+ LIB_TRIO="-ltrio"
+ LIBS="$LIB_TRIO $LIBS"
+ AC_DEFINE(HasTRIO,1,Define if you have TRIO vsnprintf replacement library)
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AC_SUBST(LIB_TRIO)
+
+
+#
+# Optionally check for libltdl if using it is still enabled
+#
+# Only use/depend on libtdl if we are building modules. This is a
+# change from previous releases (prior to 1.3.17) which supported
+# loaded modules via libtdl if shared libraries were built. of
+# whether modules are built or not.
+have_ltdl='no'
+LIB_LTDL=''
+if test "$build_modules" != 'no'
+then
+ AC_MSG_CHECKING([for libltdl ])
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER([ltdl.h],[passed=`expr $passed + 1`],[failed=`expr $failed + 1`])
+ AC_CHECK_LIB([ltdl],[lt_dlinit],[passed=`expr $passed + 1`],[failed=`expr $failed + 1`],)
+ AC_MSG_CHECKING([if libltdl package is complete])
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT([no -- some components failed test])
+ have_ltdl='no (failed tests)'
+ else
+ LIB_LTDL='-lltdl'
+ LIBS="$LIB_LTDL $LIBS"
+ AC_DEFINE(HasLTDL,1,[Define if using libltdl to support dynamically loadable modules])
+ AC_MSG_RESULT([yes])
+ have_ltdl='yes'
+ fi
+ else
+ AC_MSG_RESULT([no])
+ fi
+ if test "$have_ltdl" != 'yes'
+ then
+ AC_MSG_FAILURE([libltdl is required by modules build],[1])
+ fi
+fi
+AM_CONDITIONAL(WITH_LTDL, test "$have_ltdl" != 'no')
+
+#
+# Check for ZLIB
+#
+have_zlib='no'
+LIB_ZLIB=''
+dnl PNG requires zlib so enable zlib check if PNG is requested
+if test "$with_zlib" != 'no' || test "$with_png" != 'no'
+then
+ AC_MSG_CHECKING(for ZLIB support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(zconf.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_HEADER(zlib.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(z,compress,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(z,uncompress,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(z,deflate,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(z,inflate,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(z,gzseek,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(z,gztell,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if ZLIB package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_zlib='no (failed tests)'
+ else
+ LIB_ZLIB='-lz'
+ LIBS="$LIB_ZLIB $LIBS"
+ AC_DEFINE(HasZLIB,1,Define if you have zlib compression library)
+ AC_MSG_RESULT(yes)
+ have_zlib='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasZLIB, test "$have_zlib" = 'yes')
+AC_SUBST(LIB_ZLIB)
+
+#
+# Check for BZLIB
+#
+have_bzlib='no'
+if test "$with_bzlib" != 'no'
+then
+ LIB_BZLIB=''
+ AC_MSG_CHECKING(for BZLIB support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ found_libbz=0
+ AC_CHECK_HEADER(bzlib.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(bz2,BZ2_bzDecompress,found_libbz=`expr $found_libbz + 1`,,)
+ if test "$native_win32_build" = 'yes'
+ then
+ # Under MinGW, libbz2 obfuscates its functions by declaring them
+ # with DLL interfaces. This would be all better if we could
+ # somehow include bzlib.h during the test but Autoconf does not
+ # make that possible. We check for BZ2_decompress since that is
+ # one of the few functions exported from the DLL (very strange).
+ AC_CHECK_LIB(bz2,_imp__BZ2_decompress,found_libbz=`expr $found_libbz + 1`,,)
+ fi
+ if test $found_libbz -gt 0
+ then
+ passed=`expr $passed + 1`
+ else
+ failed=`expr $failed + 1`
+ fi
+ #AC_CHECK_LIB(bz2,BZ2_bzCompress,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ #AC_CHECK_LIB(bz2,BZ2_bzDecompress,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ #AC_CHECK_LIB(bz2,_imp__BZ2_decompress,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if BZLIB package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_bzlib='no (failed tests)'
+ else
+ LIB_BZLIB='-lbz2'
+ LIBS="$LIB_BZLIB $LIBS"
+ AC_DEFINE(HasBZLIB,1,Define if you have the bzip2 library)
+ AC_MSG_RESULT(yes)
+ have_bzlib='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasBZLIB, test "$have_bzlib" = 'yes')
+AC_SUBST(LIB_BZLIB)
+
+#
+# Check for LZMA
+#
+have_lzma='no'
+LIB_LZMA=''
+if test "$with_lzma" != 'no'
+then
+ AC_MSG_CHECKING(for LZMA support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(lzma.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(lzma,lzma_code,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if LZMA package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_lzma='no (failed tests)'
+ else
+ LIB_LZMA='-llzma'
+ LIBS="$LIB_LZMA $LIBS"
+ AC_DEFINE(HasLZMA,1,Define if you have lzma compression library)
+ AC_MSG_RESULT(yes)
+ have_lzma='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasLZMA, test "$have_lzma" = 'yes')
+AC_SUBST(LIB_LZMA)
+
+#
+# Find the X11 include and library directories.
+#
+LIB_X11=''
+LIB_XEXT=''
+AC_PATH_XTRA
+if test "$no_x" != 'yes'
+then
+ LDFLAGS="$LDFLAGS $X_LIBS"
+ LIB_X11="$X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+ LIBS="$LIB_X11 $LIBS"
+ CPPFLAGS="$CPPFLAGS $X_CFLAGS"
+
+ AC_DEFINE(HasX11,1,Define if you have X11 library)dnl
+
+ #
+ # Check for X11 shared memory extension
+ #
+ # shmctl is required to support the shared memory extension
+ LIB_IPC=''
+ AC_CHECK_FUNC([shmctl],[have_shmctl='yes'],[])
+ if test "$have_shmctl" != 'yes'
+ then
+ AC_SEARCH_LIBS([shmctl],[cygipc],[have_shmctl='yes'; LIB_IPC='-lcygipc'],[])
+ fi
+
+ if test "$have_shmctl" = 'yes'
+ then
+ AC_CHECK_LIB([Xext],[XShmAttach],[LIB_XEXT='-lXext' ; AC_DEFINE(HasSharedMemory,1,X11 server supports shared memory extension)],[],[])
+ fi
+
+ #
+ # Check for X11 shape extension
+ #
+ AC_CHECK_LIB([Xext],[XShapeCombineMask],[LIB_XEXT='-lXext' ; AC_DEFINE(HasShape,1,X11 server supports shape extension)],[],[])
+
+ LIBS="$LIB_XEXT $LIBS"
+fi
+if test "$no_x" != 'yes'
+then
+ have_x='yes'
+else
+ have_x='no'
+fi
+AM_CONDITIONAL(HasX11, test "$have_x" = 'yes')
+AC_SUBST(LIB_X11)
+AC_SUBST(LIB_XEXT)
+
+#
+# If profiling, then check for -ldl and dlopen (required for Solaris & gcc)
+#
+LIB_DL=''
+if test "$with_profiling" = 'yes'
+then
+ AC_CHECK_LIB(dl,dlopen,LIB_DL='-ldl',,)
+ LIBS="$LIB_DL $LIBS"
+fi
+AC_SUBST(LIB_DL)
+
+#
+# Check for Display Postscript
+#
+have_dps='no'
+LIB_DPS=''
+if test "$with_dps" != 'no' && test "$with_x" != 'no'
+then
+ AC_MSG_CHECKING([for Display Postscript support ])
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ O_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -I${ac_x_includes}/X11"
+ AC_CHECK_HEADER(DPS/dpsXclient.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ # DPS issues:
+ # XFree86-4.x needs -lXt to provide XtMalloc for -ldps.
+ # Cygwin doesn't deliver -lXt as a DLL, which prevents a DLL build.
+ # Adobe DPS (as delivered on Solaris) doesn't require -lXt.
+ # GraphicsMagick itself doesn't use -lXt.
+ have_libdps='no'
+ LIBDPS_XT=''
+ AC_CHECK_LIB(dps,DPSInitialize,have_libdps='yes',have_libdps='no',)
+ if test "$have_libdps" != 'yes'
+ then
+ # Unset cache variable so we can try again.
+ unset ac_cv_lib_dps_DPSInitialize
+ AC_CHECK_LIB(dps,DPSInitialize,have_libdps='yes',have_libdps='no',-lXt)
+ if test "$have_libdps" = 'yes'
+ then
+ LIBDPS_XT='-lXt'
+ fi
+ fi
+ if test "$have_libdps" = 'yes'
+ then
+ passed=`expr $passed + 1`
+ else
+ failed=`expr $failed + 1`
+ fi
+ AC_CHECK_LIB(dpstk,XDPSPixelsPerPoint,passed=`expr $passed + 1`,failed=`expr $failed + 1`,-ldps $LIBDPS_XT)
+ AC_MSG_CHECKING(if DPS package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT([no -- some components failed test])
+ have_dps='no (failed tests)'
+ CPPFLAGS="$O_CPPFLAGS"
+ else
+ LIB_DPS="-ldpstk -ldps ${LIBDPS_XT}"
+ LIBS="$LIB_DPS $LIBS"
+ AC_DEFINE(HasDPS,1,Define if you have Display Postscript)
+ AC_MSG_RESULT(yes)
+ have_dps='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ CPPFLAGS=$O_CPPFLAGS
+ fi
+fi
+AM_CONDITIONAL(HasDPS, test "$have_dps" = 'yes')
+AC_SUBST(LIB_DPS)
+
+#
+# Check for FlashPIX
+#
+have_fpx='no'
+LIB_FPX=''
+if test "$with_fpx" != 'no'
+then
+ AC_MSG_CHECKING(for FlashPIX components )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_LANG_PUSH(C++)
+ AC_CHECK_HEADER(fpxlib.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(fpx,FPX_OpenImageByFilename,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_LANG_POP
+ AC_MSG_CHECKING(if FlashPIX package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_fpx='no (failed tests)'
+ else
+ LIB_FPX='-lfpx'
+ # LIBS="$LIB_FPX $LIBS"
+ AC_DEFINE(HasFPX,1,Define if you have FlashPIX library)
+ AC_MSG_RESULT(yes)
+ have_fpx='yes'
+ PERLMAINCC="$CXX"
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasFPX, test "$have_fpx" = 'yes')
+AC_SUBST(LIB_FPX)
+
+#
+# Check for LCMS v2
+#
+have_lcms2='no'
+LIB_LCMS=''
+if test "$with_lcms2" != 'no'
+then
+ AC_MSG_CHECKING([for lcms v2 support])
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ have_lcms_header='no'
+
+ # Check for <lcms2.h>
+ AC_CHECK_HEADER(lcms2.h,have_lcms_header='yes',,)
+ if test "$have_lcms_header" = 'yes'
+ then
+ AC_DEFINE(HAVE_LCMS2_H,1,Define if you have the <lcms2.h> header file.)
+ passed=`expr $passed + 1`
+ fi
+
+ # Check for <lcms2/lcms2.h)
+ if test "$have_lcms_header" != 'yes'
+ then
+ AC_CHECK_HEADER(lcms2/lcms2.h,have_lcms_header='yes',,)
+ if test "$have_lcms_header" = 'yes'
+ then
+ passed=`expr $passed + 1`
+ AC_DEFINE(HAVE_LCMS2_LCMS2_H,1,Define if you have the <lcms2/lcms2.h> header file.)
+ fi
+ fi
+
+ # Failed to find lcms header?
+ if test "$have_lcms_header" != 'yes'
+ then
+ failed=`expr $failed + 1`
+ fi
+
+ AC_CHECK_LIB(lcms2,cmsSetLogErrorHandler,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if LCMS v2 package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_lcms2='no (failed tests)'
+ else
+ LIB_LCMS='-llcms2'
+ LIBS="$LIB_LCMS $LIBS"
+ #AC_DEFINE(HasLCMS2,1,Define if you have LCMS v2 library)
+ AC_MSG_RESULT(yes)
+ have_lcms2='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+
+
+AM_CONDITIONAL(HasLCMS, test "$have_lcms2" = 'yes')
+if test "$have_lcms2" = 'yes'
+then
+ AC_DEFINE(HasLCMS,1,[Define if you have LCMS (v2.0 or later) library])
+fi
+AC_SUBST(LIB_LCMS)
+
+have_png='no'
+LIB_PNG=''
+if test "$have_zlib" = 'yes'
+then
+ #
+ # Check for PNG delegate library.
+ #
+ AC_ARG_WITH(png,
+ [AC_HELP_STRING([--without-png],
+ [disable PNG support])],
+ [with_png=$withval],
+ [with_png='yes'])
+
+ if test "$with_png" != 'yes'; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-png=$with_png "
+ fi
+
+
+ if test "$with_png" != 'no' ; then
+ AC_MSG_CHECKING(for PNG support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(png.h,passed=`expr $passed + 1`,
+ failed=`expr $failed + 1`,)
+
+ if test $passed -gt 0; then
+ for var in 7 6 5 4 2 '' ; do
+ if test "x${var}" = 'x' ; then
+ pnglib='png'
+ else
+ pnglib="png1${var}"
+ fi
+ if test "$have_png" = 'no'
+ then
+
+ # Test for compatible LIBPNG library
+ failed=0
+ passed=0
+ if test "$with_png" = 'yes' -o "$with_png" = "libpng1${var}" ; then
+ if test "${pnglib}" != 'png' ; then
+ AC_MSG_CHECKING(for LIBPNG1${var} support )
+ AC_TRY_COMPILE(
+#include <stdio.h>
+#include <stdlib.h>
+#include <png.h>
+,
+changequote(<<, >>)dnl
+<<
+#if PNG_LIBPNG_VER_MINOR != ${var}
+#error LIBPNG library must be version 1${var}!
+Kaboom, Kaboom
+#endif
+return 0;
+>>,
+ changequote([, ])dnl
+ ac_cv_libpng_ok='yes',
+ ac_cv_libpng_ok='no')
+ if test "$ac_cv_libpng_ok" = 'yes' ; then
+ passed=`expr $passed + 1`
+ AC_MSG_RESULT(yes)
+ else
+ failed=`expr $failed + 1`
+ AC_MSG_RESULT(no)
+ fi
+ else
+ passed=`expr $passed + 1`
+ AC_MSG_RESULT(yes)
+ fi
+ fi
+
+ if test $passed -gt 0 -a $failed -le 0
+ then
+ if test "1${var}" = '15' ; then
+ AC_CHECK_LIB(png15,png_get_io_ptr,passed=`expr $passed + 1`,
+ failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(png15,png_longjmp,passed=`expr $passed + 1`,
+ failed=`expr $failed + 1`,)
+ fi
+ if test "1${var}" = '14' ; then
+ AC_CHECK_LIB(png14,png_get_io_ptr,passed=`expr $passed + 1`,
+ failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(png14,png_get_io_state,passed=`expr $passed + 1`,
+ failed=`expr $failed + 1`,)
+ fi
+ if test "1${var}" = '12' ; then
+ AC_CHECK_LIB(png12,png_get_io_ptr,passed=`expr $passed + 1`,
+ failed=`expr $failed + 1`,)
+ fi
+ if test "1${var}" = '1' ; then
+ AC_CHECK_LIB(png,png_get_io_ptr,passed=`expr $passed + 1`,
+ failed=`expr $failed + 1`,)
+ fi
+ if test $passed -gt 0 -a $failed -le 0 ; then
+ AC_MSG_CHECKING(if ${pnglib} package is complete)
+ if test $passed -gt 0 ; then
+ if test $failed -gt 0 ; then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_png='no (failed tests)'
+ else
+ LIB_PNG="-l${pnglib}"
+ LIBS="$LIB_PNG $LIBS"
+ AC_DEFINE(HasPNG,1,Define if you have PNG library)
+ AC_MSG_RESULT(yes)
+ have_png='yes'
+ fi
+ fi
+ fi
+ fi
+ fi
+ done
+ fi
+ fi
+else
+ AC_MSG_RESULT(PNG requires zlib support)
+fi
+AM_CONDITIONAL(HasPNG, test "$have_png" = 'yes')
+AC_SUBST(LIB_PNG)
+
+#
+# Check for JPEG
+#
+have_jpeg='no'
+LIB_JPEG=''
+if test "$with_jpeg" != 'no'
+then
+ AC_MSG_CHECKING(for JPEG support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(jconfig.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_HEADER(jerror.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_HEADER(jmorecfg.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_HEADER(jpeglib.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(jpeg,jpeg_read_header,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+
+# Test for compatible JPEG library
+if test "$ac_cv_jpeg_version_ok" != 'yes' ; then
+AC_CACHE_CHECK(for JPEG library is version 6b or later, ac_cv_jpeg_version_ok,
+[AC_TRY_COMPILE(
+#include <stdio.h>
+#include <stdlib.h>
+#include <jpeglib.h>
+,
+changequote(<<, >>)dnl
+<<
+#if JPEG_LIB_VERSION < 62
+#error IJG JPEG library must be version 6b or newer!
+Kaboom, Kaboom
+#endif
+return 0;
+>>,
+changequote([, ])dnl
+ac_cv_jpeg_version_ok='yes',
+ac_cv_jpeg_version_ok='no')])
+if test "$ac_cv_jpeg_version_ok" = 'yes' ; then
+ passed=`expr $passed + 1`
+else
+ failed=`expr $failed + 1`
+fi
+fi
+ AC_MSG_CHECKING(if JPEG package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_jpeg='no (failed tests)'
+ else
+ LIB_JPEG='-ljpeg'
+ LIBS="$LIB_JPEG $LIBS"
+ AC_DEFINE(HasJPEG,1,Define if you have JPEG library)
+ AC_MSG_RESULT(yes)
+ have_jpeg='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasJPEG, test "$have_jpeg" = 'yes')
+AC_SUBST(LIB_JPEG)
+
+#
+# Check for JPEG Version 2
+#
+have_jp2='no'
+LIB_JP2=''
+if test "$with_jp2" != 'no'
+then
+ AC_MSG_CHECKING(for JPEG version 2 support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(jasper/jasper.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(jasper,jas_stream_fopen,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if JPEG version 2 support package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_jp2='no (failed tests)'
+ else
+ LIB_JP2='-ljasper'
+ LIBS="$LIB_JP2 $LIBS"
+ AC_DEFINE(HasJP2,1,Define if you have JPEG version 2 "Jasper" library)
+ AC_MSG_RESULT(yes)
+ have_jp2='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasJP2, test "$have_jp2" = 'yes')
+AC_SUBST(LIB_JP2)
+
+#
+# Check for Ghostscript library
+#
+# Test for iapi.h & test for gsapi_new_instance in -lgs
+have_gslib='no'
+LIB_GS=''
+if test "$with_gslib" != 'no'
+then
+ AC_MSG_CHECKING(for Ghostscript library support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(ghostscript/iapi.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(gs,gsapi_new_instance,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if Ghostscript library package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_gslib='no (failed tests)'
+ else
+ LIB_GS='-lgs'
+ LIBS="$LIB_GS $LIBS"
+ AC_DEFINE(HasGS,1,Define if you have Ghostscript library)
+ AC_MSG_RESULT(yes)
+ have_gslib='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasGS, test "$have_gslib" = 'yes')
+AC_SUBST(LIB_GS)
+
+# #
+# # Check for MPEG2 library
+# #
+# have_mpeg2='no'
+# LIB_MPEG2=''
+# if test "$with_mpeg2" != 'no'
+# then
+# AC_MSG_CHECKING(for MPEG version 2 support )
+# AC_MSG_RESULT()
+# failed=0
+# passed=0
+# AC_CHECK_HEADER(mpeg2dec/mpeg2.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+# AC_CHECK_LIB(mpeg2,mpeg2_decode_data,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+# AC_MSG_CHECKING(if MPEG version 2 support package is complete)
+# if test $passed -gt 0
+# then
+# if test $failed -gt 0
+# then
+# AC_MSG_RESULT(no -- some components failed test)
+# have_mpeg2='no (failed tests)'
+# else
+# LIB_MPEG2='-lmpeg2'
+# LIBS="$LIB_MPEG2 $LIBS"
+# AC_DEFINE(HasMPEG2,1,Define if you have MPEG2 library)
+# AC_MSG_RESULT(yes)
+# have_mpeg2='yes'
+# fi
+# else
+# AC_MSG_RESULT(no)
+# fi
+# fi
+# AM_CONDITIONAL(HasMPEG2, test "$have_mpeg2" = 'yes')
+# AC_SUBST(LIB_MPEG2)
+
+#
+# Check for TTF
+#
+have_ttf='no'
+LIB_TTF=''
+if test "$with_ttf" != 'no'
+then
+ AC_MSG_CHECKING(for FreeType 2.0 )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+
+ OLD_LDFLAGS="$LDFLAGS"
+ OLD_CPPFLAGS="$CPPFLAGS"
+ freetype_config=''
+ # Allow the user to specify the location of freetype.
+ if test "$with_ttf" != 'yes'
+ then
+ if test -x "${with_ttf}/bin/freetype-config"
+ then
+ freetype_config="${with_ttf}/bin/freetype-config"
+ elif test -x "${with_ttf}"
+ then
+ freetype_config=${with_ttf}
+ fi
+ fi
+ if test -z "$freetype_config"
+ then
+ AC_PATH_PROG(freetype_config,freetype-config,)dnl
+ fi
+ if test -n "$freetype_config"
+ then
+ freetype_cflags=`${freetype_config} --cflags`
+ # freetype-config --cflags may output values such as
+ # -I/usr/local/include/freetype2 -I/usr/local/include
+ # Take only the first -I option since non-Freetype include
+ # directories (not needed by the FreeType API) may pollute
+ # the include path.
+ for flag in $freetype_cflags
+ do
+ case $flag in
+ -I*)
+ CPPFLAGS="$CPPFLAGS $flag"
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ # freetype-config --libs may output values such as
+ # -L/usr/local/lib -lfreetype -lz
+ # or
+ # -L/usr/lib/x86_64-linux-gnu -lfreetype -lz -lpng12
+ #
+ # Problems will surely result if we have already successfully
+ # configured different dependency libraries than freetype was
+ # built against. For this reason, we only take the first
+ # argument of each type, assuming that they are specific to
+ # Freetype. In the future we may need to do something different
+ # if the FreeType library was to depend on some weird library
+ # that we don't normally test for.
+ freeype_libs=`${freetype_config} --libs`
+ for flag in $freeype_libs
+ do
+ case $flag in
+ -L*)
+ LDFLAGS="$LDFLAGS $flag"
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ for flag in $freeype_libs
+ do
+ case $flag in
+ -l*)
+ LIB_TTF_BASE=`echo $flag | sed -e 's/^-l//'`
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ fi
+
+dnl First see if there is a library
+ AC_CHECK_LIB([$LIB_TTF_BASE],[FT_Init_FreeType],[LIB_TTF="-l$LIB_TTF_BASE"],[LIB_TTF=''],[])
+ if test "$LIB_TTF" != ''
+ then
+ passed=`expr $passed + 1`
+ else
+ failed=`expr $failed + 1`
+ LDFLAGS="$OLD_LDFLAGS"
+ fi
+
+dnl Now test for the headers
+ # Modern Freetype2 installs require that <ft2build.h> be included
+ # prior to including any other FreeType2 headers. This header
+ # produces defines which must be used to include remaining API
+ # headers.
+ AC_CHECK_HEADER([ft2build.h],[FT2BUILD_H='#include <ft2build.h>' ; have_freetype_h='yes'],[FT2BUILD_H='' ; have_freetype_h='no'],[])
+ if test "${FT2BUILD_H}x" = 'x'
+ then
+ # Last ditch, test old include style where everything is rooted
+ # under 'freetype'
+ AC_CHECK_HEADER([freetype/freetype.h],[have_freetype_h='yes'],[have_freetype_h='no'],)
+ fi
+ if test "$have_freetype_h" = 'yes'
+ then
+ passed=`expr $passed + 1`
+ else
+ failed=`expr $failed + 1`
+ CPPFLAGS="$OLD_CPPFLAGS"
+ fi
+
+ AC_MSG_CHECKING(if FreeType package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ LIB_TTF=''
+ AC_MSG_RESULT(no -- some components failed test)
+ have_ttf='no (failed tests)'
+ else
+ LIBS="$LIB_TTF $LIBS"
+ AC_DEFINE(HasTTF,1,Define if you have FreeType (TrueType font) library)
+ if test "$ac_cv_header_ft2build_h" = 'yes'
+ then
+ AC_DEFINE([HAVE_FT2BUILD_H],[1],[Define to 1 if you have the <ft2build.h> header file.])
+ fi
+ AC_MSG_RESULT(yes)
+ have_ttf='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasTTF, test "$have_ttf" = 'yes')
+AC_SUBST(LIB_TTF)
+
+#
+# Check for TIFF
+#
+have_tiff='no'
+LIB_TIFF=''
+if test "$with_tiff" != 'no'
+then
+ AC_MSG_CHECKING(for TIFF support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(tiff.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_HEADER(tiffio.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(tiff,TIFFOpen,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(tiff,TIFFClientOpen,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(tiff,TIFFIsByteSwapped,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(tiff,TIFFReadRGBATile,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(tiff,TIFFReadRGBAStrip,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if TIFF package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_tiff='no (failed tests)'
+ else
+ LIB_TIFF='-ltiff'
+ LIBS="$LIB_TIFF $LIBS"
+ AC_DEFINE(HasTIFF,1,Define if you have TIFF library)
+ AC_MSG_RESULT(yes)
+ have_tiff='yes'
+ AC_CHECK_HEADERS(tiffconf.h)
+ AC_CHECK_FUNCS([TIFFIsCODECConfigured \
+ TIFFMergeFieldInfo \
+ TIFFSetErrorHandlerExt \
+ TIFFSetTagExtender \
+ TIFFSetWarningHandlerExt \
+ TIFFSwabArrayOfTriples])
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasTIFF, test "$have_tiff" = 'yes')
+AC_SUBST(LIB_TIFF)
+
+#
+# Check for JBIG
+#
+have_jbig='no'
+LIB_JBIG=''
+if test "$with_jbig" != 'no'
+then
+ AC_MSG_CHECKING(for JBIG support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(jbig.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`)
+ AC_CHECK_LIB(jbig,jbg_dec_init,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if JBIG package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_jbig='no (failed tests)'
+ else
+ LIB_JBIG='-ljbig'
+ LIBS="$LIB_JBIG $LIBS"
+ AC_DEFINE(HasJBIG,1,Define if you have JBIG library)
+ AC_MSG_RESULT(yes)
+ have_jbig='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasJBIG, test "$have_jbig" = 'yes')
+AC_SUBST(LIB_JBIG)
+
+#
+# Check for WEBP
+#
+have_webp='no'
+LIB_WEBP=''
+if test "$with_webp" != 'no'
+then
+ AC_MSG_CHECKING(for WEBP support )
+ AC_MSG_RESULT()
+ failed=0
+ passed=0
+ AC_CHECK_HEADER(webp/decode.h,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_CHECK_LIB(webp,WebPDecodeRGB,passed=`expr $passed + 1`,failed=`expr $failed + 1`,)
+ AC_MSG_CHECKING(if WEBP package is complete)
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT(no -- some components failed test)
+ have_webp='no (failed tests)'
+ else
+ LIB_WEBP='-lwebp'
+ LIBS="$LIB_WEBP $LIBS"
+ AC_DEFINE(HasWEBP,1,Define if you have WEBP library)
+ AC_MSG_RESULT(yes)
+ have_webp='yes'
+ fi
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+AM_CONDITIONAL(HasWEBP, test "$have_webp" = 'yes')
+AC_SUBST(LIB_WEBP)
+
+#
+# Check for XML
+#
+have_xml='no'
+LIB_XML=''
+LIB_XML_DEPS=''
+LIB_XML2_BASE=''
+if test "$with_xml" != 'no'
+then
+ OLD_LDFLAGS=$LDFLAGS
+ OLD_CPPFLAGS=$CPPFLAGS
+ AC_MSG_CHECKING([for XML support ])
+ AC_MSG_RESULT([])
+ xml2_config=''
+ AC_PATH_PROG([xml2_config],[xml2-config],[])dnl
+ if test -n "$xml2_config"
+ then
+ # Sample output from xml2-config --cflags:
+ # -I/usr/include/libxml2
+ # -I/usr/local/include/libxml2 -I/usr/local/include
+ xml2_cflags=`"$xml2_config" --cflags`
+ for flag in $xml2_cflags
+ do
+ case $flag in
+ -I*)
+ # Add flag to CPPFLAGS if not already present
+ add=yes;
+ for test_flag in $CPPFLAGS
+ do
+ if test $flag = $test_flag
+ then
+ add=no
+ break
+ fi
+ done
+ if test $add = yes
+ then
+ CPPFLAGS="$CPPFLAGS $flag"
+ fi
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ # Sample output from xml2-config --libs:
+ # -lxml2
+ # -L/usr/lib -R/usr/lib -lxml2 -lz -lpthread -lm -lsocket -lnsl
+ #-L/usr/local/lib -lxml2 -lz -L/usr/local/lib -liconv -lm
+ xml2_libs=`$xml2_config --libs`
+ for flag in $xml2_libs
+ do
+ case $flag in
+ -L*)
+ # Add flag to LDFLAGS if not already present
+ add=yes;
+ for test_flag in $LDFLAGS
+ do
+ if test $flag = $test_flag
+ then
+ add=no
+ break
+ fi
+ done
+ if test $add = yes
+ then
+ LDFLAGS="$LDFLAGS $flag"
+ fi
+ break
+ ;;
+ *)
+ ;;
+ esac
+ done
+ for flag in $xml2_libs
+ do
+ case $flag in
+ -l*)
+ # The first library listed is assumed to be the
+ # name of the library and all others are assumed
+ # to be its dependencies.
+ if test "x$LIB_XML2_BASE" = "x"
+ then
+ LIB_XML2_BASE=`echo $flag | sed -e 's/^-l//'`
+ else
+ LIB_XML_DEPS="$LIB_XML_DEPS $flag"
+ fi
+ ;;
+ *)
+ ;;
+ esac
+ done
+ fi
+ if test "x$LIB_XML2_BASE" = "x"
+ then
+ LIB_XML2_BASE=xml2
+ fi
+ failed=0
+ passed=0
+ # Incantation tested with libxml2 2.7.8 configured with
+ # --with-minimum --with-http --with-ftp --with-push --with-zlib --with-sax1
+ # Note that SAX1 interfaces don't seem to be directly used but parsers fail to work
+ # as expected without SAX1 support compiled in.
+ AC_CHECK_HEADER([libxml/parser.h],[passed=`expr $passed + 1`],[failed=`expr $failed + 1`])
+ AC_CHECK_LIB([$LIB_XML2_BASE],[xmlSAXVersion],[passed=`expr $passed + 1`],[failed=`expr $failed + 1`],[$LIB_XML_DEPS])
+ # Next two require --with-push to be enabled
+ AC_CHECK_LIB([$LIB_XML2_BASE],[xmlParseChunk],[passed=`expr $passed + 1`],[failed=`expr $failed + 1`],[$LIB_XML_DEPS])
+ AC_CHECK_LIB([$LIB_XML2_BASE],[xmlCreatePushParserCtxt],[passed=`expr $passed + 1`],[failed=`expr $failed + 1`],[$LIB_XML_DEPS])
+ AC_MSG_CHECKING([if XML package is complete ])
+ if test $passed -gt 0
+ then
+ if test $failed -gt 0
+ then
+ AC_MSG_RESULT([no -- some components failed test])
+ have_xml='no (failed tests)'
+ LDFLAGS="$OLD_LDFLAGS"
+ CPPFLAGS="$OLD_CPPFLAGS"
+ else
+ LIB_XML="-l$LIB_XML2_BASE"
+ # Add lib to LIBS if not already present
+ for test_lib in $LIB_XML $LIB_XML_DEPS
+ do
+ add=yes;
+ for lib in $LIBS
+ do
+ if test $lib = $test_lib
+ then
+ add=no
+ break
+ fi
+ done
+ if test $add = yes
+ then
+ LIBS="$test_lib $LIBS"
+ fi
+ done
+ AC_DEFINE([HasXML],[1],[Define if you have XML library])
+ AC_MSG_RESULT([yes])
+ have_xml='yes'
+ fi
+ else
+ AC_MSG_RESULT([no])
+ fi
+fi
+AM_CONDITIONAL([HasXML], [test "$have_xml" = 'yes'])
+AC_SUBST([LIB_XML])
+AC_SUBST([LIB_XML_DEPS])
+
+#
+# Check for WMF
+#
+# We require libwmflite and now refuse to use full libwmf. Typical
+# dependencies for libwmflite are '-lpthread -lm' (which we already
+# usually depend on) whereas full libwmf has a great many
+# dependencies.
+#
+
+have_wmf='no'
+LIB_WMF=''
+LIB_WMF_DEPS=''
+OLIBS="$LIBS"
+if test "$with_wmf" != 'no'
+then
+ AC_MSG_CHECKING([for WMF support ])
+ AC_MSG_RESULT([])
+
+ have_libwmflite='no'
+ have_libwmf_ipa_h='no'
+
+ AC_CHECK_HEADER([libwmf/ipa.h],[have_libwmf_ipa_h='yes'],[],[$FT2BUILD_H])
+ if test "$have_libwmf_ipa_h" = 'yes'
+ then
+
+ AC_CHECK_LIB([wmflite],[wmf_lite_create],[have_libwmflite='yes'],[],[])
+ if test "$have_libwmflite" = 'yes'
+ then
+ AC_DEFINE([HasWMFlite],[1],[Define if you have wmflite library])
+
+ LIB_WMF='-lwmflite'
+ LIBS="$LIB_WMF $LIBS"
+ have_wmf='yes'
+ else
+ AC_MSG_RESULT([no -- some components failed test])
+ have_wmf='no (failed tests)'
+ have_wmflite='no (failed tests)'
+ LIBS="$OLIBS"
+ LIB_WMF=''
+ fi
+ fi
+fi
+AC_MSG_CHECKING([if WMF package is complete ])
+if test "$have_wmf" = 'yes'
+then
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+AM_CONDITIONAL([HasWMF], [test "$have_wmf" = 'yes'])
+AC_SUBST([LIB_WMF])
+AC_SUBST([LIB_WMF_DEPS])
+
+#
+# Substitute compiler name to build/link PerlMagick
+#
+AC_SUBST([PERLMAINCC])
+
+#
+# Configure install Paths
+#
+
+# Subdirectory under lib to place GraphicsMagick lib files
+MagickLibSubdir="${PACKAGE_NAME}-${PACKAGE_VERSION}"
+AC_DEFINE_UNQUOTED(MagickLibSubdir,"$MagickLibSubdir",Subdirectory of lib where GraphicsMagick architecture dependent files are installed)
+
+# Path to GraphicsMagick bin directory
+MagickBinPath="${BIN_DIR}"
+MagickBinPathDefine="${MagickBinPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickBinPathDefine=`$WinPathScript "$MagickBinPathDefine" 1`
+ ;;
+esac
+AC_DEFINE_UNQUOTED(MagickBinPath,"$MagickBinPathDefine",Directory where executables are installed.)
+AC_SUBST(MagickBinPath)
+
+# Path to GraphicsMagick lib
+MagickLibPath="${LIB_DIR}/${MagickLibSubdir}"
+MagickLibPathDefine="${MagickLibPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickLibPathDefine=`$WinPathScript "$MagickLibPathDefine" 1`
+ ;;
+esac
+AC_DEFINE_UNQUOTED(MagickLibPath,"$MagickLibPathDefine",Directory where architecture-dependent files live.)
+AC_SUBST(MagickLibPath)
+
+# Subdirectory under lib to place GraphicsMagick configuration files
+MagickLibConfigSubDir="${MagickLibSubdir}/config"
+AC_DEFINE_UNQUOTED(MagickLibConfigSubDir,"$MagickLibConfigSubDir",Subdirectory of lib where architecture-dependent configuration files live.)
+MagickLibConfigPath="${LIB_DIR}/${MagickLibConfigSubDir}"
+MagickLibConfigPathDefine="${MagickLibConfigPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickLibConfigPathDefine=`$WinPathScript "$MagickLibConfigPathDefine" 1`
+ ;;
+esac
+AC_DEFINE_UNQUOTED(MagickLibConfigPath,"$MagickLibConfigPathDefine",Directory where architecture-dependent configuration files live.)
+AC_SUBST(MagickLibConfigPath)
+
+#
+# Subdirectory under lib to place GraphicsMagick coder module files
+MagickCoderModulesSubdir="${MagickLibSubdir}/modules-Q${QuantumDepth}/coders"
+AC_DEFINE_UNQUOTED(MagickCoderModulesSubdir,"$MagickCoderModulesSubdir",Subdirectory of lib where coder modules are installed)
+MagickCoderModulesPath="${LIB_DIR}/${MagickCoderModulesSubdir}"
+MagickCoderModulesPathDefine="${MagickCoderModulesPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickCoderModulesPathDefine=`$WinPathScript "$MagickCoderModulesPathDefine" 1`
+ ;;
+esac
+AC_DEFINE_UNQUOTED(MagickCoderModulesPath,"$MagickCoderModulesPathDefine",Location of coder modules)
+AC_SUBST(MagickCoderModulesPath)
+
+#
+# Subdirectory under lib to place GraphicsMagick filter module files
+MagickFilterModulesSubdir="${MagickLibSubdir}/modules-Q${QuantumDepth}/filters"
+AC_DEFINE_UNQUOTED(MagickFilterModulesSubdir,"$MagickFilterModulesSubdir",Subdirectory of lib where filter modules are installed)
+MagickFilterModulesPath="${LIB_DIR}/${MagickFilterModulesSubdir}"
+MagickFilterModulesPathDefine="${MagickFilterModulesPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickFilterModulesPathDefine=`$WinPathScript "$MagickFilterModulesPathDefine" 1`
+ ;;
+esac
+AC_DEFINE_UNQUOTED(MagickFilterModulesPath,"$MagickFilterModulesPathDefine",Location of filter modules)
+AC_SUBST(MagickFilterModulesPath)
+
+#
+# Path to GraphicsMagick share files
+MagickShareSubdir="${PACKAGE_NAME}-${PACKAGE_VERSION}"
+MagickSharePath="${DATA_DIR}/${MagickShareSubdir}"
+MagickSharePathDefine="${MagickSharePath}/"
+case "${build_os}" in
+ mingw* )
+ MagickSharePathDefine=`$WinPathScript "$MagickSharePathDefine" 1`
+ ;;
+esac
+AC_DEFINE_UNQUOTED(MagickSharePath,"$MagickSharePathDefine",Directory where architecture-independent files live.)
+AC_SUBST(MagickSharePath)
+
+# Subdirectory under share to place GraphicsMagick configuration files
+MagickShareConfigSubDir="${MagickLibSubdir}/config"
+AC_DEFINE_UNQUOTED(MagickShareConfigSubDir,"$MagickShareConfigSubDir",Subdirectory of lib where architecture-independent configuration files live.)
+MagickShareConfigPath="${DATA_DIR}/${MagickShareConfigSubDir}"
+MagickShareConfigPathDefine="${MagickShareConfigPath}/"
+case "${build_os}" in
+ mingw* )
+ MagickShareConfigPathDefine=`$WinPathScript "$MagickShareConfigPathDefine" 1`
+ ;;
+esac
+AC_DEFINE_UNQUOTED(MagickShareConfigPath,"$MagickShareConfigPathDefine",Directory where architecture-independent configuration files live.)
+AC_SUBST(MagickShareConfigPath)
+
+#
+# program_transform_name is formed for use in a Makefile, so create a
+# modified version for use in a shell script.
+configure_transform_name=`echo ${program_transform_name} | sed 's,\\$\\$,$,'`
+
+# Default delegate definitions
+dnl AutotraceDecodeDelegateDefault='autotrace'
+dnl BZIPDelegateDefault='bzip2'
+BrowseDelegateDefault='xdg-open'
+CGMDecodeDelegateDefault='ralcgm'
+dnl CatDelegateDefault='cat'
+DCRAWDecodeDelegateDefault='dcraw'
+DOTDecodeDelegateDefault='dot'
+DVIDecodeDelegateDefault='dvips'
+dnl EchoDelegateDefault='echo'
+EditorDelegateDefault='xterm'
+FIGDecodeDelegateDefault='fig2dev'
+GMDelegateDefault=`echo gm | sed ${configure_transform_name}`
+dnl GnuplotDecodeDelegateDefault='gnuplot'
+HPGLDecodeDelegateDefault='hp2xx'
+HTMLDecodeDelegateDefault='html2ps'
+ILBMDecodeDelegateDefault='ilbmtoppm'
+ILBMEncodeDelegateDefault='ppmtoilbm'
+LPDelegateDefault='lp'
+LPRDelegateDefault='lpr'
+LaunchDelegateDefault='gimp'
+dnl MANDelegateDefault='groff'
+MPEGDecodeDelegateDefault='mpeg2decode'
+MPEGEncodeDelegateDefault='mpeg2encode'
+MVDelegateDefault='mv'
+dnl PGPDecodeDelegateDefault='pgpv'
+dnl POVDelegateDefault='povray'
+if test "$native_win32_build" = 'yes' ; then
+ PSDelegateDefault='gswin32c'
+else
+ PSDelegateDefault='gs'
+fi
+dnl RADDecodeDelegateDefault='ra_ppm'
+dnl RLEEncodeDelegateDefault='rawtorle'
+dnl RMDelegateDefault='rm'
+dnl SCANDecodeDelegateDefault='scanimage'
+dnl TXTDelegateDefault='enscript'
+dnl WMFDecodeDelegateDefault='wmf2eps'
+dnl WWWDecodeDelegateDefault='wget'
+dnl ZipDelegateDefault='gzip'
+
+# Search for delegates
+dnl AC_PATH_PROG(AutotraceDecodeDelegate, "$AutotraceDecodeDelegateDefault", "$AutotraceDecodeDelegateDefault")
+dnl AC_PATH_PROG(BZIPDelegate, "$BZIPDelegateDefault", "$BZIPDelegateDefault")
+AC_PATH_PROGS(BrowseDelegate, "$BrowseDelegateDefault" firefox konqueror google-chrome mozilla lynx, "$BrowseDelegateDefault")
+AC_PATH_PROG(CGMDecodeDelegate, "$CGMDecodeDelegateDefault", "$CGMDecodeDelegateDefault")
+dnl AC_PATH_PROG(CatDelegate, "$CatDelegateDefault", "$CatDelegateDefault")
+AC_PATH_PROG(DCRAWDecodeDelegate, "$DCRAWDecodeDelegateDefault", "$DCRAWDecodeDelegateDefault")
+AC_PATH_PROG(DOTDecodeDelegate, "$DOTDecodeDelegateDefault", "$DOTDecodeDelegateDefault")
+AC_PATH_PROG(DVIDecodeDelegate, "$DVIDecodeDelegateDefault", "$DVIDecodeDelegateDefault")
+dnl AC_PATH_PROG(EchoDelegate, "$EchoDelegateDefault", "$EchoDelegateDefault")
+AC_PATH_PROG(EditorDelegate, "$EditorDelegateDefault", "$EditorDelegateDefault")
+AC_PATH_PROG(FIGDecodeDelegate, "$FIGDecodeDelegateDefault", "$FIGDecodeDelegateDefault")
+AC_PATH_PROG(GMDelegate, "$GMDelegateDefault", "$GMDelegateDefault")
+dnl AC_PATH_PROG(GnuplotDecodeDelegate, "$GnuplotDecodeDelegateDefault", "$GnuplotDecodeDelegateDefault")
+AC_PATH_PROG(HPGLDecodeDelegate, "$HPGLDecodeDelegateDefault", "$HPGLDecodeDelegateDefault")
+AC_PATH_PROG(HTMLDecodeDelegate, "$HTMLDecodeDelegateDefault", "$HTMLDecodeDelegateDefault")
+AC_PATH_PROG(ILBMDecodeDelegate, "$ILBMDecodeDelegateDefault", "$ILBMDecodeDelegateDefault")
+AC_PATH_PROG(ILBMEncodeDelegate, "$ILBMEncodeDelegateDefault", "$ILBMEncodeDelegateDefault")
+AC_PATH_PROG(LPDelegate, "$LPDelegateDefault", no)
+AC_PATH_PROG(LPRDelegate, "$LPRDelegateDefault", no)
+AC_PATH_PROG(LaunchDelegate, "$LaunchDelegateDefault", "$LaunchDelegateDefault")
+dnl AC_PATH_PROG(MANDelegate, "$MANDelegateDefault", "$MANDelegateDefault")
+AC_PATH_PROG(MPEGDecodeDelegate, "$MPEGDecodeDelegateDefault", "$MPEGDecodeDelegateDefault")
+AC_PATH_PROG(MPEGEncodeDelegate, "$MPEGEncodeDelegateDefault", "$MPEGEncodeDelegateDefault")
+AC_PATH_PROG(MVDelegate, "$MVDelegateDefault", "$MVDelegateDefault")
+dnl AC_PATH_PROG(PGPDecodeDelegate, "$PGPDecodeDelegateDefault", "$PGPDecodeDelegateDefault")
+dnl AC_PATH_PROG(POVDelegate, "$POVDelegateDefault", "$POVDelegateDefault")
+AC_PATH_PROG(PSDelegate, "$PSDelegateDefault", "$PSDelegateDefault")
+dnl AC_PATH_PROG(RADDecodeDelegate, "$RADDecodeDelegateDefault", "$RADDecodeDelegateDefault")
+dnl AC_PATH_PROG(RLEEncodeDelegate, "$RLEEncodeDelegateDefault", "$RLEEncodeDelegateDefault")
+dnl AC_PATH_PROG(RMDelegate, "$RMDelegateDefault", "$RMDelegateDefault")
+dnl AC_PATH_PROG(SCANDecodeDelegate, "$SCANDecodeDelegateDefault", "$SCANDecodeDelegateDefault")
+dnl AC_PATH_PROG(TXTDelegate, "$TXTDelegateDefault", "$TXTDelegateDefault")
+dnl AC_PATH_PROG(WMFDecodeDelegate, "$WMFDecodeDelegateDefault", "$WMFDecodeDelegateDefault")
+dnl AC_PATH_PROG(WWWDecodeDelegate, "$WWWDecodeDelegateDefault", "$WWWDecodeDelegateDefault")
+dnl AC_PATH_PROG(ZipDelegate, "$ZipDelegateDefault", "$ZipDelegateDefault")
+
+# Prefer lpr to lp; lp needs options tacked on.
+if test "$LPRDelegate" != no
+then
+ PrintDelegate="$LPRDelegate"
+else
+ PrintDelegate="$LPDelegate -c -s"
+fi
+AC_SUBST(PrintDelegate)
+
+# Installed GraphicsMagick utiltity paths
+GMDelegate="${BIN_DIR}/${GMDelegateDefault}"
+
+# Set delegate booleans
+have_fig2dev='no' ; if test "$FIGDecodeDelegate" != "$FIGDecodeDelegateDefault" ; then have_fig2dev='yes' ; fi
+have_gs='no' ; if test "$PSDelegate" != "$PSDelegateDefault"; then have_gs='yes' ; fi
+have_hp2xx='no' ; if test "$HPGLDecodeDelegate" != "$HPGLDecodeDelegateDefault" ; then have_hp2xx='yes' ; fi
+have_ilbmtoppm='no' ; if test "$ILBMDecodeDelegate" != "$ILBMDecodeDelegateDefault" ; then have_ilbmtoppm='yes' ; fi
+have_ppmtoilbm='no' ; if test "$ILBMEncodeDelegate" != "$ILBMEncodeDelegateDefault" ; then have_ppmtoilbm='yes' ; fi
+have_mpeg2decode='no' ; if test "$MPEGDecodeDelegate" != "$MPEGDecodeDelegateDefault" ; then have_mpeg2decode='yes' ; fi
+have_mpeg2encode='no' ; if test "$MPEGEncodeDelegate" != "$MPEGEncodeDelegateDefault" ; then have_mpeg2encode='yes' ; fi
+dnl have_ra_ppm='no' ; if test "$RADDecodeDelegate" != "$RADDecodeDelegateDefault" ; then have_ra_ppm='yes' ; fi
+have_ralcgm='no' ; if test "$CGMDecodeDelegate" != "$CGMDecodeDelegateDefault" ; then have_ralcgm='yes' ; fi
+
+# Automake conditional to support test suite
+AM_CONDITIONAL(HasPSDelegate, test "$have_gs" = 'yes')
+
+# Test for optional rst2html.py utility and define automake conditional HasRST2HTML if found.
+AC_CHECK_PROGS(RST2HTML,[rst2html.py rst2html])
+AC_SUBST(RST2HTML)
+AM_CONDITIONAL(HasRST2HTML, test "x$RST2HTML" != 'x')
+
+# Test for optional txt2html utility and define automake conditional HasTXT2HTML if found.
+AC_PATH_PROGS(TXT2HTML, [txt2html])
+AC_SUBST(TXT2HTML)
+AM_CONDITIONAL(HasTXT2HTML, test "$TXT2HTML" != 'x')
+
+#
+# Test for font directories
+#
+type_include_files=''
+
+# Windows
+windows_font_dir=''
+if test "$with_windows_font_dir" != "yes" && test -n "$with_windows_font_dir"
+then
+ windows_font_dir="${with_windows_font_dir}/"
+fi
+# Sometimes Windows fonts are found under /usr/X11R6/lib/X11/fonts/truetype
+if test -n "$windows_font_dir"
+then
+ if test -f '/usr/X11R6/lib/X11/fonts/truetype/arial.ttf'
+ then
+ windows_font_dir='/usr/X11R6/lib/X11/fonts/truetype/'
+ fi
+fi
+if test -n "$windows_font_dir"
+then
+ type_include_files="$type_include_files "'<include file="type-windows.mgk" />'
+fi
+AC_SUBST(windows_font_dir)
+
+# Adobe Postscript fonts on various systems
+case $host_os in
+ solaris*)
+ # Check for OpenWindows Type 1 fonts. Not available under OpenSolaris
+ if test -f /usr/openwin/lib/X11/fonts/Type1/afm/Helvetica.afm
+ then
+ type_include_files="$type_include_files "'<include file="type-solaris.mgk" />'
+ fi
+ ;;
+esac
+
+# Ghostscript
+AC_MSG_CHECKING(for Ghostscript fonts directory)
+ghostscript_font_dir=''
+if test "${with_gs_font_dir}" != 'default'
+then
+ ghostscript_font_dir="${with_gs_font_dir}/"
+
+else
+ if test "${native_win32_build}" = 'yes'
+ then
+ # Native Windows Build
+ #
+ # Ghostscript may install fonts to several default locations now.
+ # If the user does not select the default, then he is on his own.
+ #
+ # It would be nice to use reg.exe to obtain Ghostscript information
+ # but unfortunately MSYS seems to transform registry key paths into
+ # filesystem paths so it does not work. Maybe there is a way to
+ # prevent that translation?
+ #
+ # reg query "HKLM\Software\GPL Ghostscript" /s
+ #
+ # This seems to work without translation:
+ #
+ # cmd /c "reg query \"HKLM\Software\GPL Ghostscript\" /v GS_LIB /s"
+ #
+ for font_dir in "c:\\Program Files\\gs\\fonts\\" "c:\\gs\\fonts\\"
+ do
+ if test -f "${font_dir}a010013l.pfb"
+ then
+ ghostscript_font_dir="$font_dir"
+ break 1
+ fi
+ done
+ if test "${PSDelegate}" != 'gswin32c'
+ then
+ ghostscript_font_dir=`echo "${PSDelegate}" | sed -e 's:/gs/.*:/gs:;s:^/::;s/./&:/;s:/:\\\\:g'`"\\fonts\\"
+ fi
+
+ else
+ # Unix Build
+ #
+ # Check ${prefix}/share/ghostscript/fonts first
+ # Red Hat Linux puts Ghostscript fonts in /usr/share/fonts/default/Type1
+ # Recent Cygwin puts Ghostscript fonts in /usr/share/ghostscript/fonts
+ # Recent Gentoo Linux puts Ghostscript fonts in /usr/share/fonts/ghostscript
+ # Debian puts Ghostscript fonts in /usr/share/fonts/type1/gsfonts
+ for font_dir in "${prefix}/share/ghostscript/fonts/" '/usr/share/fonts/default/Type1/' '/usr/share/ghostscript/fonts/' '/usr/share/fonts/ghostscript/' '/usr/share/fonts/type1/gsfonts/'
+ do
+ if test -f "${font_dir}a010013l.pfb"
+ then
+ ghostscript_font_dir="${font_dir}"
+ break 1
+ fi
+ done
+
+ if test "${ghostscript_font_dir}x" = 'x'
+ then
+ if test "$PSDelegate" != 'gs'
+ then
+ ghostscript_font_dir=`echo "$PSDelegate" | sed -e 's:/bin/gs:/share/ghostscript/fonts:'`"/"
+ fi
+ fi
+
+ fi
+fi
+if test "${ghostscript_font_dir}x" != 'x'
+then
+ type_include_files="${type_include_files} "'<include file="type-ghostscript.mgk" />'
+ AC_MSG_RESULT($ghostscript_font_dir)
+else
+ AC_MSG_RESULT(not found!);
+fi
+AC_SUBST(ghostscript_font_dir)
+case "${build_os}" in
+ mingw* )
+ PSDelegate=`$WinPathScript "$PSDelegate" 1`
+ ;;
+esac
+
+AC_SUBST(type_include_files)
+
+#
+# Handle case where user doesn't want frozen paths
+#
+if test "$with_frozenpaths" != 'yes'
+then
+ # Re-set delegate definitions to default (no paths)
+dnl AutotraceDecodeDelegate="$AutotraceDecodeDelegateDefault"
+dnl BZIPDelegate="$BZIPDelegateDefault"
+ BrowseDelegate="$BrowseDelegateDefault"
+ CGMDecodeDelegate="$CGMDecodeDelegateDefault"
+dnl CatDelegate="$CatDelegateDefault"
+ ConvertDelegate="$ConvertDelegateDefault"
+ DOTDecodeDelegate="$DOTDecodeDelegateDefault"
+ DVIDecodeDelegate="$DVIDecodeDelegateDefault"
+dnl EchoDelegate="$EchoDelegateDefault"
+ EditorDelegate="$EditorDelegateDefault"
+ FIGDecodeDelegate="$FIGDecodeDelegateDefault"
+ GMDelegate="${GMDelegateDefault}"
+dnl GnuplotDecodeDelegate="$GnuplotDecodeDelegateDefault"
+ HPGLDecodeDelegate="$HPGLDecodeDelegateDefault"
+ HTMLDecodeDelegate="$HTMLDecodeDelegateDefault"
+ ILBMDecodeDelegate="$ILBMDecodeDelegateDefault"
+ ILBMEncodeDelegate="$ILBMEncodeDelegateDefault"
+ LPDelegate="$LPDelegateDefault"
+ LaunchDelegate="$LaunchDelegateDefault"
+dnl MANDelegate="$MANDelegateDefault"
+ MPEGDecodeDelegate="$MPEGDecodeDelegateDefault"
+ MPEGEncodeDelegate="$MPEGEncodeDelegateDefault"
+dnl MVDelegate="$MVDelegateDefault"
+ MogrifyDelegate="$MogrifyDelegateDefault"
+dnl PGPDecodeDelegate="$PGPDecodeDelegateDefault"
+dnl POVDelegate="$POVDelegateDefault"
+ PSDelegate="$PSDelegateDefault"
+dnl RADDecodeDelegate="$RADDecodeDelegateDefault"
+dnl RLEEncodeDelegate="$RLEEncodeDelegateDefault"
+dnl RMDelegate="$RMDelegateDefault"
+dnl SCANDecodeDelegate="$SCANDecodeDelegateDefault"
+ ShowImageDelegate="$ShowImageDelegateDefault"
+dnl TXTDelegate="$TXTDelegateDefault"
+ WMFDecodeDelegate="$WMFDecodeDelegateDefault"
+dnl WWWDecodeDelegate="$WWWDecodeDelegateDefault"
+dnl ZipDelegate="$ZipDelegateDefault"
+fi
+
+# Delegate substitutions
+dnl AC_SUBST(AutotraceDecodeDelegate)
+dnl AC_SUBST(BZIPDelegate)
+AC_SUBST(BrowseDelegate)
+dnl AC_SUBST(CGMDecodeDelegate)
+dnl AC_SUBST(CatDelegate)
+AC_SUBST(ConvertDelegate)
+AC_SUBST(DOTDecodeDelegate)
+AC_SUBST(DVIDecodeDelegate)
+dnl AC_SUBST(EchoDelegate)
+AC_SUBST(EditorDelegate)
+AC_SUBST(FIGDecodeDelegate)
+dnl AC_SUBST(GnuplotDecodeDelegate)
+AC_SUBST(HPGLDecodeDelegate)
+AC_SUBST(HTMLDecodeDelegate)
+AC_SUBST(ILBMDecodeDelegate)
+AC_SUBST(ILBMEncodeDelegate)
+AC_SUBST(LPDelegate)
+AC_SUBST(LaunchDelegate)
+dnl AC_SUBST(MANDelegate)
+AC_SUBST(MPEGDecodeDelegate)
+AC_SUBST(MPEGEncodeDelegate)
+dnl AC_SUBST(MVDelegate)
+AC_SUBST(MogrifyDelegate)
+dnl AC_SUBST(PGPDecodeDelegate)
+dnl AC_SUBST(POVDelegate)
+AC_SUBST(PSDelegate)
+dnl AC_SUBST(RADDecodeDelegate)
+dnl AC_SUBST(RLEEncodeDelegate)
+dnl AC_SUBST(RMDelegate)
+dnl AC_SUBST(SCANDecodeDelegate)
+AC_SUBST(ShowImageDelegate)
+dnl AC_SUBST(TXTDelegate)
+dnl AC_SUBST(WMFDecodeDelegate)
+dnl AC_SUBST(WWWDecodeDelegate)
+dnl AC_SUBST(ZipDelegate)
+
+#
+# RedHat RPM support (http://rpm5.org/)
+#
+RPM=''
+AC_CHECK_PROGS(RPM,[rpmbuild rpm])
+AC_SUBST(RPM)
+AM_CONDITIONAL(HAS_RPM, test "x$RPM" != "x" )
+
+#
+# 7ZIP support (http://p7zip.sourceforge.net/)
+#
+P7ZIP=''
+AC_CHECK_PROGS(P7ZIP,[7za])
+AC_SUBST(P7ZIP)
+AM_CONDITIONAL(HAS_P7ZIP, test "x$P7ZIP" != "x" )
+
+#
+# ZIP support (http://www.info-zip.org/Zip.html)
+#
+ZIP=''
+AC_CHECK_PROGS(ZIP,[zip])
+AC_SUBST(ZIP)
+AM_CONDITIONAL(HAS_ZIP, test "x$ZIP" != "x" )
+
+#
+# Ghostscript related configuration.
+#
+GSColorDevice=ppmraw
+GSColorAlphaDevice=pngalpha
+GSGrayDevice=pgmraw
+GSPaletteDevice=pcx256
+GSMonoDevice=pbmraw
+GSCMYKDevices="pamcmyk32 pam $GSColorDevice"
+GSPDFDevice=pdfwrite
+GSPSDevice=pswrite
+GSEPSDevice=epswrite
+GSVersion='unknown'
+if test $have_gs = 'yes'
+then
+
+ AC_MSG_CHECKING(for Ghostscript version)
+ if GSVersion=`$PSDelegate --version`
+ then
+ :
+ else
+ GSVersion=`$PSDelegate --help | sed -e '1q' | awk '{ print $3 }'`
+ fi
+ AC_MSG_RESULT($GSVersion)
+
+ # GSColorDevice # AS_MESSAGE_LOG_FD
+ AC_MSG_CHECKING([for gs color device])
+ if $PSDelegate -q -dBATCH -sDEVICE=pnmraw -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSColorDevice=pnmraw
+ else
+ if $PSDelegate -q -dBATCH -sDEVICE=ppmraw -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSColorDevice=ppmraw
+ else
+ GSColorDevice=ppmraw
+ fi
+ fi
+ AC_MSG_RESULT($GSColorDevice)
+
+ # GSColorAlphaDevice
+ AC_MSG_CHECKING([for gs color+alpha device])
+ if $PSDelegate -q -dBATCH -sDEVICE=pngalpha -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSColorAlphaDevice=pngalpha
+ else
+ GSColorAlphaDevice=$GSColorDevice
+ fi
+ AC_MSG_RESULT($GSColorAlphaDevice)
+
+ # GSGrayDevice
+ AC_MSG_CHECKING([for gs gray device])
+ if $PSDelegate -q -dBATCH -sDEVICE=pgmraw -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSGrayDevice=pgmraw
+ else
+ GSGrayDevice=ppmraw
+ fi
+ AC_MSG_RESULT($GSGrayDevice)
+
+ # GSPaletteDevice
+ AC_MSG_CHECKING([for gs pallet device])
+ if $PSDelegate -q -dBATCH -sDEVICE=pcx256 -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSPaletteDevice=pcx256
+ else
+ GSPaletteDevice=ppmraw
+ fi
+ AC_MSG_RESULT($GSPaletteDevice)
+
+ # GSMonoDevice
+ AC_MSG_CHECKING([for gs mono device])
+ if $PSDelegate -q -dBATCH -sDEVICE=pbmraw -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSMonoDevice=pbmraw
+ else
+ GSMonoDevice=ppmraw
+ fi
+ AC_MSG_RESULT($GSMonoDevice)
+
+ # GSCMYKDevice
+ AC_MSG_CHECKING([for gs CMYK device])
+ GSCMYKDevice=$GSColorDevice
+ for device in $GSCMYKDevices
+ do
+ if $PSDelegate -q -dBATCH -sDEVICE=$device -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSCMYKDevice=$device
+ break
+ fi
+ done
+ AC_MSG_RESULT($GSCMYKDevice)
+
+ # GSPDFDevice
+ AC_MSG_CHECKING([for gs PDF writing device])
+ if $PSDelegate -q -dBATCH -sDEVICE=pdfwrite -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSPDFDevice=pdfwrite
+ else
+ GSPDFDevice=nodevice
+ fi
+ AC_MSG_RESULT($GSPDFDevice)
+
+ # GSPSDevice
+ AC_MSG_CHECKING([for gs PS writing device])
+ GSPSDevice=nodevice
+ for device in ps2write pswrite
+ do
+ if $PSDelegate -q -dBATCH -sDEVICE=$device -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSPSDevice=$device
+ break
+ fi
+ done
+ AC_MSG_RESULT($GSPSDevice)
+
+ # GSEPSDevice
+ AC_MSG_CHECKING([for gs EPS writing device])
+ GSEPSDevice=nodevice
+ for device in eps2write epswrite
+ do
+ if $PSDelegate -q -dBATCH -sDEVICE=$device -sOutputFile=/dev/null < /dev/null 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ then
+ GSEPSDevice=$device
+ break
+ fi
+ done
+ AC_MSG_RESULT($GSEPSDevice)
+
+fi
+
+AC_SUBST(GSMonoDevice)
+AC_SUBST(GSCMYKDevice)
+AC_SUBST(GSGrayDevice)
+AC_SUBST(GSPaletteDevice)
+AC_SUBST(GSColorDevice)
+AC_SUBST(GSColorAlphaDevice)
+AC_SUBST(GSPDFDevice)
+AC_SUBST(GSPSDevice)
+AC_SUBST(GSEPSDevice)
+AC_SUBST(GSVersion)
+
+#
+# PerlMagick-related configuration
+#
+
+# Look for PERL if PerlMagick requested
+# If name/path of desired PERL interpreter is specified, look for that one first
+have_perl='no'
+if test "$with_perl" != 'no'
+then
+ if test "$with_perl" != 'yes'
+ then
+ AC_CACHE_CHECK(for perl,ac_cv_path_PERL,ac_cv_path_PERL="$with_perl");
+ PERL=$ac_cv_path_PERL
+ AC_SUBST(PERL)dnl
+ have_perl="$ac_cv_path_PERL"
+ else
+ AC_PATH_PROGS(PERL,perl perl5,)dnl
+ if test "$ac_cv_path_PERL"
+ then
+ have_perl="$ac_cv_path_PERL"
+ fi
+ fi
+fi
+if test "$with_perl" != 'yes' ; then
+ DISTCHECK_CONFIG_FLAGS="${DISTCHECK_CONFIG_FLAGS} --with-perl=$with_perl "
+fi
+
+PERL_SUPPORTS_DESTDIR='no'
+with_perl_static='no'
+with_perl_dynamic='no'
+if test "$have_perl" != 'no'
+then
+ # Should we build shared libraries?
+ if test "$with_perl" != 'no' && test "$libtool_build_shared_libs" = 'no'
+ then
+ with_perl_static='yes'
+ fi
+ if test "$with_perl" != 'no' && test "$libtool_build_shared_libs" = 'yes'
+ then
+ with_perl_dynamic='yes'
+ fi
+
+ # Is PERL's MakeMaker new enough to support DESTDIR?
+ AC_PROG_PERL_VERSION(5.8.1,[PERL_SUPPORTS_DESTDIR='yes'],[PERL_SUPPORTS_DESTDIR='no'])
+fi
+AM_CONDITIONAL(WITH_PERL, test "$have_perl" != 'no')
+AM_CONDITIONAL(WITH_PERL_STATIC, test $with_perl_static = 'yes')
+AM_CONDITIONAL(WITH_PERL_DYNAMIC, test $with_perl_dynamic = 'yes')
+AC_SUBST(PERL_SUPPORTS_DESTDIR)
+
+# Determine path to pick up GraphicsMagick library from for use with building PerlMagick
+MAGICKLIBDIR="${LIB_DIR}"
+MAGICKLIB="-L${MAGICKLIBDIR} -lGraphicsMagick"
+if test $with_perl_static = 'yes'
+then
+ # Find out where libtool hides its uninstalled libraries (as libtool_objdir)
+ libtool_objdir=$objdir
+
+ # Find out what extension is applied to static libraries (as libtool_libext)
+ #eval `./libtool --config|grep '^libext='|sed -e 's/^libext/libtool_libext/'`
+
+ # Find out full form of library name (as libtool_libname_spec)
+ #eval `./libtool --config|grep '^libname_spec='|sed -e 's/^libname_spec/libtool_libname_spec/'`
+ #eval 'name=GraphicsMagick '`eval 'echo library_name="${libtool_libname_spec}.${libtool_libext}"'`
+
+ # Explicit path to static library (Perl rejects it!)
+ #MAGICKLIB="${builddir}/magick/${libtool_objdir}/${library_name}"
+
+ # Linker search path to library, followed by -lGraphicsMagick
+ MAGICKLIBDIR="${builddir}/magick/${libtool_objdir}"
+ MAGICKLIB="-L${MAGICKLIBDIR} -lGraphicsMagick"
+fi
+AC_SUBST(MAGICKLIB)
+AC_SUBST(MAGICKLIBDIR)
+
+# Create a simple string containing format names for all delegate libraries
+# DELEGATES is used to select sub-directories in the PerlMagick test suite
+# MAGICK_FEATURES is used to declare required features in the test suite
+DELEGATES=''
+MAGICK_FEATURES=''
+if test "$with_broken_coders" = yes; then
+ # Add the list of broken coders to feature options
+ MAGICK_FEATURES="$MAGICK_FEATURES PSD"
+fi
+if test "$have_bzlib" = 'yes' ; then
+ DELEGATES="$DELEGATES bzlib"
+ MAGICK_FEATURES="$MAGICK_FEATURES BZLIB"
+fi
+dnl if test "$have_ralcgm" = 'yes' ; then
+dnl DELEGATES="$DELEGATES cgm"
+dnl MAGICK_FEATURES="$MAGICK_FEATURES CGM"
+dnl fi
+if test "$have_fpx" = 'yes' ; then
+ DELEGATES="$DELEGATES fpx"
+ MAGICK_FEATURES="$MAGICK_FEATURES FPX"
+fi
+if test "$have_hp2xx" = 'yes' ; then
+ DELEGATES="$DELEGATES hpgl"
+ MAGICK_FEATURES="$MAGICK_FEATURES HPGL"
+fi
+if test "$have_jbig" = 'yes' ; then
+ DELEGATES="$DELEGATES jbig"
+ MAGICK_FEATURES="$MAGICK_FEATURES JBIG"
+fi
+if test "$have_webp" = 'yes' ; then
+ DELEGATES="$DELEGATES webp"
+ MAGICK_FEATURES="$MAGICK_FEATURES WEBP"
+fi
+if test "$have_png$have_jpeg" = 'yesyes' ; then
+ DELEGATES="$DELEGATES jng"
+ MAGICK_FEATURES="$MAGICK_FEATURES JNG"
+fi
+if test "$have_jp2" = 'yes' ; then
+ DELEGATES="$DELEGATES jp2"
+ MAGICK_FEATURES="$MAGICK_FEATURES JP2"
+fi
+if test "$have_jpeg" = 'yes' ; then
+ DELEGATES="$DELEGATES jpeg"
+ MAGICK_FEATURES="$MAGICK_FEATURES JPEG"
+fi
+if test "$have_lcms2" = 'yes' ; then
+ DELEGATES="$DELEGATES lcms"
+ MAGICK_FEATURES="$MAGICK_FEATURES LCMS"
+fi
+if test "$have_lzma" = 'yes' ; then
+ DELEGATES="$DELEGATES lzma"
+ MAGICK_FEATURES="$MAGICK_FEATURES LZMA"
+fi
+if test "$have_mpeg2" = 'yes' ; then
+ DELEGATES="$DELEGATES mpeg2"
+ MAGICK_FEATURES="$MAGICK_FEATURES MPEG2"
+fi
+if test "$have_mpeg2decode" = 'yes' && test "$have_mpeg2encode" = 'yes' ; then
+ DELEGATES="$DELEGATES mpeg"
+ MAGICK_FEATURES="$MAGICK_FEATURES MPEG"
+fi
+if test "$have_png" = 'yes' ; then
+ DELEGATES="$DELEGATES png"
+ MAGICK_FEATURES="$MAGICK_FEATURES PNG"
+fi
+
+have_ps='no'
+if test "$have_dps" = 'yes' || \
+ test "$have_gs" = 'yes' || \
+ test "${native_win32_build}" = 'yes' ; then
+ have_ps='yes'
+fi
+if test "$have_ps" = 'yes' ; then
+ DELEGATES="$DELEGATES ps"
+ MAGICK_FEATURES="$MAGICK_FEATURES PS"
+fi
+
+dnl if test "$have_ra_ppm" = 'yes' ; then
+dnl DELEGATES="$DELEGATES rad"
+dnl MAGICK_FEATURES="$MAGICK_FEATURES RAD"
+dnl fi
+if test "$have_tiff" = 'yes' ; then
+ DELEGATES="$DELEGATES tiff"
+ MAGICK_FEATURES="$MAGICK_FEATURES TIFF"
+fi
+if test "$have_ttf" = 'yes' ; then
+ DELEGATES="$DELEGATES ttf"
+ MAGICK_FEATURES="$MAGICK_FEATURES TTF"
+fi
+if test "$have_wmf" = 'yes' ; then
+ DELEGATES="$DELEGATES wmf"
+ MAGICK_FEATURES="$MAGICK_FEATURES WMF"
+fi
+if test "$have_x" = 'yes' ; then
+ DELEGATES="$DELEGATES x"
+ MAGICK_FEATURES="$MAGICK_FEATURES X"
+fi
+if test "$have_fig2dev" = 'yes' && test "$have_ps" = 'yes' ; then
+ DELEGATES="$DELEGATES xfig"
+ MAGICK_FEATURES="$MAGICK_FEATURES XFIG"
+fi
+if test "$have_xml" = 'yes' ; then
+ DELEGATES="$DELEGATES xml"
+ MAGICK_FEATURES="$MAGICK_FEATURES XML"
+fi
+if test "$have_zlib" = 'yes' ; then
+ DELEGATES="$DELEGATES zlib"
+ MAGICK_FEATURES="$MAGICK_FEATURES ZLIB"
+fi
+if test "$build_modules" != 'no' ; then
+ MAGICK_FEATURES="$MAGICK_FEATURES MODULES"
+fi
+# Remove extraneous spaces from output variables (asthetic)
+DELEGATES=`echo $DELEGATES | sed -e 's/ */ /g'`
+MAGICK_FEATURES=`echo $MAGICK_FEATURES | sed -e 's/ */ /g'`
+AC_SUBST(DELEGATES)
+AC_SUBST(MAGICK_FEATURES)
+
+#
+# Handle special compiler flags
+#
+
+# Add '-p' if prof source profiling support enabled
+if test "$with_prof" = 'yes'
+then
+ CFLAGS="-p $CFLAGS"
+ CXXFLAGS="-p $CXXFLAGS"
+ LDFLAGS="-p $LDFLAGS"
+fi
+
+# Add '-pg' if gprof source profiling support enabled
+if test "$with_gprof" = 'yes'
+then
+ CFLAGS="-pg $CFLAGS"
+ CXXFLAGS="-pg $CXXFLAGS"
+ LDFLAGS="-pg $LDFLAGS"
+fi
+
+# Add '-ftest-coverage -fprofile-arcs' if gcov source profiling support enabled
+# This is a gcc-specific feature
+if test "$with_gcov" = 'yes'
+then
+ CFLAGS="-ftest-coverage -fprofile-arcs $CFLAGS"
+ CXXFLAGS="-ftest-coverage -fprofile-arcs $CXXFLAGS"
+ LDFLAGS="-ftest-coverage -fprofile-arcs $LDFLAGS"
+fi
+
+#
+# Build library dependency list for libMagick
+#
+
+# The build_modules variable is set to 'yes' if coders and filters are
+# to be built as modules. This requires libltdl ($LIB_LTDL).
+
+if test "$build_modules" != 'no'
+then
+ MAGICK_DEP_LIBS="$LIBS_USER $LIB_LCMS $LIB_TTF $LIB_GS $LIB_XEXT $LIB_IPC $LIB_X11 $LIB_LZMA $LIB_BZLIB $LIB_ZLIB $LIB_LTDL $LIB_TRIO $LIB_GDI32 $LIB_MATH $LIB_OMP $LIB_UMEM $LIB_THREAD"
+else
+ MAGICK_DEP_LIBS="$LIBS_USER $LIB_JBIG $LIB_WEBP $LIB_LCMS $LIB_TIFF $LIB_TTF $LIB_JP2 $LIB_JPEG $LIB_GS $LIB_PNG $LIB_FPX $LIB_WMF $LIB_DPS $LIB_XEXT $LIB_IPC $LIB_X11 $LIB_LZMA $LIB_BZLIB $LIB_XML $LIB_ZLIB $LIB_TRIO $LIB_GDI32 $LIB_MATH $LIB_OMP $LIB_UMEM $LIB_THREAD"
+fi
+AC_SUBST(MAGICK_DEP_LIBS)
+
+#
+# Remove extraneous spaces from output variables (asthetic)
+#
+X_CFLAGS=`echo $X_CFLAGS | sed -e 's/ */ /g'`
+X_PRE_LIBS=`echo $X_PRE_LIBS | sed -e 's/ */ /g'`
+X_LIBS=`echo $X_LIBS | sed -e 's/ */ /g'`
+X_EXTRA_LIBS=`echo $X_EXTRA_LIBS | sed -e 's/ */ /g'`
+
+CC=`echo $CC | sed -e 's/ */ /g'`
+CFLAGS=`echo $CFLAGS | sed -e 's/ */ /g'`
+CPPFLAGS=`echo $CPPFLAGS | sed -e 's/ */ /g'`
+CXXFLAGS=`echo $CXXFLAGS | sed -e 's/ */ /g'`
+LDFLAGS=`echo $LDFLAGS | sed -e 's/ */ /g'`
+TESTED_LIBS=`echo $LIBS | sed -e 's/ */ /g'`
+MAGICK_DEP_LIBS=`echo $MAGICK_DEP_LIBS | sed -e 's/ */ /g'`
+#LIBS=`echo $LIBS | sed -e 's/ */ /g'`
+
+MAGICK_API_CFLAGS=$CFLAGS
+MAGICK_API_CPPFLAGS=`echo $MAGICK_API_CPPFLAGS | sed -e 's/ */ /g'`
+MAGICK_API_LDFLAGS="-L$LIB_DIR $LDFLAGS"
+MAGICK_API_DEP_LIBS="$MAGICK_DEP_LIBS"
+MAGICK_API_LIBS="-lGraphicsMagick $MAGICK_API_DEP_LIBS"
+
+MAGICK_API_DEP_LIBS=`echo $MAGICK_API_DEP_LIBS | sed -e 's/ */ /g'`
+MAGICK_API_LIBS=`echo $MAGICK_API_LIBS | sed -e 's/ */ /g'`
+
+# Save configure/build parameters for later reference
+AC_DEFINE_UNQUOTED(GM_BUILD_CONFIGURE_ARGS,"$0 ${ac_configure_args}",[arguments passed to configure])
+AC_DEFINE_UNQUOTED(GM_BUILD_HOST,"${host}",[Host identification triplet])
+AC_DEFINE_UNQUOTED(GM_BUILD_CC,"${CC}",[C compiler used for compilation])
+AC_DEFINE_UNQUOTED(GM_BUILD_CXX,"${CXX}",[C++ compiler used for compilation])
+AC_DEFINE_UNQUOTED(GM_BUILD_CFLAGS,"${CFLAGS}",[CFLAGS used for C compilation])
+AC_DEFINE_UNQUOTED(GM_BUILD_CPPFLAGS,"${CPPFLAGS}",[CPPFLAGS used for preprocessing])
+AC_DEFINE_UNQUOTED(GM_BUILD_CXXFLAGS,"${CXXFLAGS}",[CXXFLAGS used for C++ compilation])
+AC_DEFINE_UNQUOTED(GM_BUILD_LDFLAGS,"${LDFLAGS}",[LDFLAGS used for linking])
+AC_DEFINE_UNQUOTED(GM_BUILD_LIBS,"${MAGICK_API_DEP_LIBS}",[LIBS used for linking])
+
+# Pass only user-provided LIBS as "global" libraries
+LIBS=$LIBS_USER
+
+#AC_SUBST(CPPFLAGS)
+AC_SUBST(X_CFLAGS)
+#AC_SUBST(LDFLAGS)
+#AC_SUBST(X_PRE_LIBS)
+#AC_SUBST(X_LIBS)
+#AC_SUBST(X_EXTRA_LIBS)
+
+
+AC_SUBST(MAGICK_API_CFLAGS)
+AC_SUBST(MAGICK_API_CPPFLAGS)
+AC_SUBST(MAGICK_API_PC_CPPFLAGS)
+AC_SUBST(MAGICK_API_LDFLAGS)
+AC_SUBST(MAGICK_API_LIBS)
+
+AC_CONFIG_FILES(\
+ GraphicsMagick.spec \
+ Magick++/bin/GraphicsMagick++-config \
+ Magick++/lib/GraphicsMagick++.pc \
+ Makefile \
+ PerlMagick/Magick.pm \
+ PerlMagick/Makefile.PL \
+ PerlMagick/PerlMagickCheck.sh \
+ PerlMagick/t/features.pl \
+ config/delegates.mgk \
+ config/type-ghostscript.mgk \
+ config/type-solaris.mgk \
+ config/type-windows.mgk \
+ config/type.mgk \
+ magick/GraphicsMagick-config \
+ magick/GraphicsMagick.pc \
+ magick/magick_types.h \
+ magick/version.h \
+ common.shi \
+ rungm.sh \
+ wand/GraphicsMagickWand-config \
+ wand/GraphicsMagickWand.pc )
+
+# Set configured scripts to executable.
+AC_CONFIG_COMMANDS([default],[],[])
+AC_CONFIG_COMMANDS([GraphicsMagick++-config.in],[chmod +x Magick++/bin/GraphicsMagick++-config])
+AC_CONFIG_COMMANDS([GraphicsMagick-config.in],[chmod +x magick/GraphicsMagick-config])
+AC_CONFIG_COMMANDS([GraphicsMagickWand-config.in],[chmod +x wand/GraphicsMagickWand-config])
+AC_CONFIG_COMMANDS([rungm.sh.in],[chmod +x rungm.sh])
+AC_CONFIG_COMMANDS([PerlMagick/PerlMagickCheck.sh.in],[chmod +x PerlMagick/PerlMagickCheck.sh])
+
+AC_OUTPUT
+
+rm -f magick-version
+
+echo ""
+
+echo "GraphicsMagick is configured as follows. Please verify that this"
+echo "configuration matches your expectations."
+echo ""
+echo "Host system type : $host"
+echo "Build system type : $build"
+echo ""
+echo "Option Configure option Configured value"
+echo "-----------------------------------------------------------------"
+echo "Shared libraries --enable-shared=$enable_shared $libtool_build_shared_libs"
+echo "Static libraries --enable-static=$enable_static $libtool_build_static_libs"
+echo "GNU ld --with-gnu-ld=$with_gnu_ld $lt_cv_prog_gnu_ld"
+echo "Quantum depth --with-quantum-depth=$with_quantum_depth $with_quantum_depth"
+echo "Modules --with-modules=$with_modules $build_modules"
+echo ""
+echo "Delegate Configuration:"
+echo "BZLIB --with-bzlib=$with_bzlib $have_bzlib"
+echo "DPS --with-dps=$with_dps $have_dps"
+echo "FlashPIX --with-fpx=$with_fpx $have_fpx"
+echo "FreeType 2.0 --with-ttf=$with_ttf $have_ttf"
+echo "Ghostscript None $PSDelegate ($GSVersion)"
+result_ghostscript_font_dir='none'
+if test "${ghostscript_font_dir}x" != 'x'
+then
+ result_ghostscript_font_dir="$ghostscript_font_dir"
+fi
+echo "Ghostscript fonts --with-gs-font-dir=$with_gs_font_dir $result_ghostscript_font_dir"
+echo "Ghostscript lib --with-gslib=$with_gslib $have_gslib"
+echo "JBIG --with-jbig=$with_jbig $have_jbig"
+echo "JPEG v1 --with-jpeg=$with_jpeg $have_jpeg"
+echo "JPEG-2000 --with-jp2=$with_jp2 $have_jp2"
+echo "LCMS v2 --with-lcms2=$with_lcms2 $have_lcms2"
+# echo "MPEG v2 --with-mpeg2=$with_mpeg2 $have_mpeg2"
+echo "LZMA --with-lzma=$with_lzma $have_lzma"
+echo "Magick++ --with-magick-plus-plus=$with_magick_plus_plus $have_magick_plus_plus"
+echo "PERL --with-perl=$with_perl $have_perl"
+if test "${LIB_PNG}x" != 'x'
+then
+echo "PNG --with-png=$with_png $have_png ($LIB_PNG)"
+else
+echo "PNG --with-png=$with_png $have_png"
+fi
+echo "TIFF --with-tiff=$with_tiff $have_tiff"
+echo "TRIO --with-trio=$with_trio $have_trio"
+echo "WEBP --with-webp=$with_webp $have_webp"
+result_windows_font_dir='none'
+if test "${windows_font_dir}x" != 'x'
+then
+ result_windows_font_dir="${windows_font_dir}"
+fi
+echo "Windows fonts --with-windows-font-dir=$with_windows_font_dir $result_windows_font_dir"
+echo "WMF --with-wmf=$with_wmf $have_wmf"
+echo "X11 --with-x=$with_x $have_x"
+echo "XML --with-xml=$with_xml $have_xml"
+echo "ZLIB --with-zlib=$with_zlib $have_zlib"
+echo ""
+echo "X11 Configuration:"
+if test "$have_x" != 'no'
+then
+ echo " X_CFLAGS = $X_CFLAGS"
+ echo " X_PRE_LIBS = $X_PRE_LIBS"
+ echo " X_LIBS = $X_LIBS"
+ echo " X_EXTRA_LIBS = $X_EXTRA_LIBS"
+else
+ echo ""
+ echo " Not using X11."
+fi
+echo ""
+echo "Options used to compile and link:"
+echo " CC = $CC"
+echo " CFLAGS = $CFLAGS"
+echo " CPPFLAGS = $CPPFLAGS"
+echo " CXX = $CXX"
+echo " CXXFLAGS = $CXXFLAGS"
+echo " DEFS = $DEFS"
+echo " LDFLAGS = $LDFLAGS"
+echo " LIBS = $MAGICK_API_DEP_LIBS"
+echo ""
diff --git a/filters/Makefile.am b/filters/Makefile.am
new file mode 100644
index 0000000..f49860b
--- /dev/null
+++ b/filters/Makefile.am
@@ -0,0 +1,32 @@
+# Copyright (C) 2004-2014 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building GraphicsMagick filter modules
+#
+#
+
+# Where filter modules get installed
+filtersdir = $(MagickFilterModulesPath)
+
+MAGICK_FILTER_CPPFLAGS = $(AM_CPPFLAGS)
+
+MAGICK_FILTER_SRCS = \
+ filters/analyze.c
+
+
+if WITH_MODULES
+filters_LTLIBRARIES = \
+ filters/analyze.la
+else
+filters_LTLIBRARIES =
+endif # WITH_MODULES
+filters_CPPFLAGS = $(MAGICK_FILTER_CPPFLAGS)
+
+# Analyze filter module
+filters_analyze_la_SOURCES = filters/analyze.c
+filters_analyze_la_CPPFLAGS = $(MAGICK_FILTER_CPPFLAGS)
+filters_analyze_la_LDFLAGS = $(MODULECOMMONFLAGS)
+filters_analyze_la_LIBADD = $(LIBMAGICK)
diff --git a/filters/analyze.c b/filters/analyze.c
new file mode 100644
index 0000000..52b789f
--- /dev/null
+++ b/filters/analyze.c
@@ -0,0 +1,164 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% A N A L I Z E %
+% %
+% Methods to Compute a Information about an Image %
+% %
+% %
+% Software Design %
+% Bill Corbis %
+% December 1998 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/gem.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A n a l y z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method AnalyzeImage computes the brightness and saturation mean and
+% standard deviation and stores these values as attributes of the image.
+%
+% The format of the AnalyzeImage method is:
+%
+% unsigned int AnalyzeImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The address of a structure of type Image.
+%
+*/
+#define PRECISION "%.0f"
+ModuleExport unsigned int AnalyzeImage(Image **image,
+ const int argc,char **argv)
+{
+ double
+ bsumX = 0.0,
+ bsumX2 = 0.0,
+ brightness_mean = 0.0,
+ brightness_stdev = 0.0,
+ ssumX = 0.0,
+ ssumX2 = 0.0,
+ saturation_mean = 0.0,
+ saturation_stdev = 0.0,
+ total_pixels = 0.0;
+
+ double
+ brightness,
+ hue,
+ saturation;
+
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *p;
+
+ char
+ text[MaxTextExtent];
+
+ ARG_NOT_USED(argc);
+ ARG_NOT_USED(argv);
+
+ assert(image != (Image **) NULL);
+ assert(*image != (Image *) NULL);
+ for (y=0; y < (int) (*image)->rows; y++)
+ {
+ p=GetImagePixels((*image),0,y,(*image)->columns,1);
+ if (p == (PixelPacket *) NULL)
+ break;
+ if (y == 0)
+ {
+ FormatString(text,"#%02x%02x%02x",p->red,p->green,p->blue);
+ (void) SetImageAttribute((*image),"TopLeftColor",text);
+ }
+ if (y == (long) ((*image)->rows-1))
+ {
+ FormatString(text,"#%02x%02x%02x",p->red,p->green,p->blue);
+ (void) SetImageAttribute((*image),"BottomLeftColor",text);
+ }
+ for (x=0; x < (long) (*image)->columns; x++)
+ {
+ TransformHSL(p->red,p->green,p->blue,&hue,&saturation,&brightness);
+ brightness *= MaxRGB;
+ bsumX += brightness;
+ bsumX2 += brightness * brightness;
+ saturation *= MaxRGB;
+ ssumX += saturation;
+ ssumX2 += saturation * saturation;
+ total_pixels++;
+ p++;
+ }
+ p--; /* backup one pixel to allow us to sample */
+ if (y == 0)
+ {
+ FormatString(text,"#%02x%02x%02x",p->red,p->green,p->blue);
+ (void) SetImageAttribute((*image),"TopRightColor",text);
+ }
+ if (y == (long) ((*image)->rows-1))
+ {
+ FormatString(text,"#%02x%02x%02x",p->red,p->green,p->blue);
+ (void) SetImageAttribute((*image),"BottomRightColor",text);
+ }
+ }
+ if (total_pixels > 0.0)
+ {
+ brightness_mean = bsumX/total_pixels;
+ FormatString(text,PRECISION,brightness_mean);
+ (void) SetImageAttribute((*image),"BrightnessMean",text);
+ /* This formula gives a slightly biased result */
+ brightness_stdev =
+ sqrt(bsumX2/total_pixels - (bsumX/total_pixels*bsumX/total_pixels));
+ FormatString(text,PRECISION,brightness_stdev);
+ (void) SetImageAttribute((*image),"BrightnessStddev",text);
+ /* Now the correction for bias. */
+ /* stdev = stdev*sqrt((double)total_pixels/(double)(total_pixels-1)); */
+ /* Now calculate the standard deviation of the mean */
+ /* brightness_stdevmean = bstdev/sqrt((double)total_pixels); */
+
+ saturation_mean = ssumX/total_pixels;
+ FormatString(text,PRECISION,saturation_mean);
+ (void) SetImageAttribute((*image),"SaturationMean",text);
+ /* This formula gives a slightly biased result */
+ saturation_stdev =
+ sqrt(ssumX2/total_pixels - (ssumX/total_pixels*ssumX/total_pixels));
+ FormatString(text,PRECISION,saturation_stdev);
+ (void) SetImageAttribute((*image),"SaturationStddev",text);
+ /* Now the correction for bias. */
+ /* stdev = stdev*sqrt((double)total_pixels/(double)(total_pixels-1)); */
+ /* Now calculate the standard deviation of the mean */
+ /* saturation_stdevmean = sstdev/sqrt((double)total_pixels); */
+ }
+ return(True);
+}
diff --git a/lndir.sh b/lndir.sh
new file mode 100755
index 0000000..b256751
--- /dev/null
+++ b/lndir.sh
@@ -0,0 +1,97 @@
+#! /bin/sh
+
+# lndir - create shadow link tree
+#
+# Time stamp <89/11/28 18:56:54 gildea>
+# By Stephen Gildea <gildea@bbn.com> based on
+# XConsortium: lndir.sh,v 1.1 88/10/20 17:37:16 jim Exp
+#
+# Modified slightly for ImageMagick by Bob Friesenhahn, 1999
+#
+# Used to create a copy of the a directory tree that has links for all
+# non- directories. If you are building the distribution on more than
+# one machine, you should use this script.
+#
+# If your master sources are located in /usr/local/src/X and you would like
+# your link tree to be in /usr/local/src/new-X, do the following:
+#
+# % mkdir /usr/local/src/new-X
+# % cd /usr/local/src/new-X
+# % lndir ../X
+#
+# Note: does not link files beginning with "." Is this a bug or a feature?
+#
+# Improvements over R3 version:
+# Allows the fromdir to be relative: usually you want to say "../dist"
+# The name is relative to the todir, not the current directory.
+#
+# Bugs in R3 version fixed:
+# Do "pwd" command *after* "cd $DIRTO".
+# Don't try to link directories, avoiding error message "<dir> exists".
+# Barf with Usage message if either DIRFROM *or* DIRTO is not a directory.
+
+SHELL=/bin/sh
+USAGE="Usage: $0 fromdir [todir]"
+
+if [ $# -lt 1 -o $# -gt 2 ]
+then
+ echo "$USAGE"
+ exit 1
+fi
+
+DIRFROM=$1
+
+if [ $# -eq 2 ];
+then
+ DIRTO=$2
+else
+ DIRTO=.
+fi
+
+if [ ! -d $DIRTO ]
+then
+ echo "$0: $DIRTO is not a directory"
+ echo "$USAGE"
+ exit 2
+fi
+
+cd $DIRTO
+
+if [ ! -d $DIRFROM ]
+then
+ echo "$0: $DIRFROM is not a directory"
+ echo "$USAGE"
+ exit 2
+fi
+
+pwd=`pwd`
+
+if [ `(cd $DIRFROM; pwd)` = $pwd ]
+then
+ echo "$pwd: FROM and TO are identical!"
+ exit 1
+fi
+
+for file in `ls $DIRFROM`
+do
+ if [ ! -d $DIRFROM/$file ]
+ then
+ test -r $file || ln -s $DIRFROM/$file .
+ else
+ #echo $file:
+ test -d $file || mkdir $file && chmod 777 $file
+ (cd $file
+ pwd=`pwd`
+ case "$DIRFROM" in
+ /*) ;;
+ *) DIRFROM=../$DIRFROM ;;
+ esac
+ if [ `(cd $DIRFROM/$file; pwd)` = $pwd ]
+ then
+ echo "$pwd: FROM and TO are identical!"
+ exit 1
+ fi
+ ${SHELL} $0 $DIRFROM/$file
+ )
+ fi
+done
diff --git a/locale/C.mgk b/locale/C.mgk
new file mode 100644
index 0000000..bb129c1
--- /dev/null
+++ b/locale/C.mgk
@@ -0,0 +1,1830 @@
+<?xml version="1.0"?>
+<locale name="C">
+ <Blob>
+ <Error>
+ <Message name="UnableToCreateBlob">
+ Unable to create blob
+ </Message>
+ <Message name="UnableToOpenFile">
+ Unable to open file
+ </Message>
+ <Message name="UnableToReadFile">
+ Unable to read file
+ </Message>
+ <Message name="UnableToReadToOffset">
+ Unable to read to offset
+ </Message>
+ <Message name="UnableToSeekToOffset">
+ Unable to seek to offset
+ </Message>
+ <Message name="UnableToObtainOffset">
+ Unable to obtain current offset
+ </Message>
+ <Message name="UnableToWriteBlob">
+ Unable to write blob
+ </Message>
+ <Message name="UnrecognizedImageFormat">
+ Unrecognized image format
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Blob>
+ <Cache>
+ <Error>
+ <Message name="InconsistentPersistentCacheDepth">
+ Inconsistent persistent cache depth
+ </Message>
+ <Message name="PixelCacheIsNotOpen">
+ Pixel cache is not open
+ </Message>
+ <Message name="UnableToAllocateCacheView">
+ Unable to allocate cache view
+ </Message>
+ <Message name="UnableToCloneCache">
+ Unable to clone cache
+ </Message>
+ <Message name="UnableToExtendCache">
+ Unable to extend cache
+ </Message>
+ <Message name="UnableToGetCacheNexus">
+ Unable to get cache nexus
+ </Message>
+ <Message name="UnableToGetPixelsFromCache">
+ Unable to get pixels from cache
+ </Message>
+ <Message name="UnableToOpenCache">
+ Unable to open cache
+ </Message>
+ <Message name="UnableToPeristPixelCache">
+ Unable to persist pixel cache
+ </Message>
+ <Message name="UnableToReadPixelCache">
+ Unable to read pixel cache
+ </Message>
+ <Message name="UnableToSyncCache">
+ Unable to sync cache (check temporary file disk space)
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="DiskAllocationFailed">
+ disk allocation failed
+ </Message>
+ <Message name="UnableToExtendPixelCache">
+ Unable to extend pixel cache
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Cache>
+ <Coder>
+ <Error>
+ <Message name="ColormapTooLarge">
+ Colormap size exceeds limit
+ </Message>
+ <Message name="ColormapTypeNotSupported">
+ Colormap type not supported
+ </Message>
+ <Message name="ColorspaceModelIsNotSupported">
+ Colorspace model is not supported
+ </Message>
+ <Message name="ColorTypeNotSupported">
+ Color type not supported
+ </Message>
+ <Message name="DataEncodingSchemeIsNotSupported">
+ Data encoding scheme is not supported
+ </Message>
+ <Message name="CompressionNotValid">
+ Compression not valid
+ </Message>
+ <Message name="FractalCompressionNotSupported">
+ Fractal compression not supported
+ </Message>
+ <Message name="ImageIsNotTiled">
+ Image is not tiles
+ </Message>
+ <Message name="UnableToOpenBlob">
+ Unable to open blob
+ </Message>
+ <Message name="UnableToInitializeFPXLibrary">
+ Unable to Initialize FPX library
+ </Message>
+ <Message name="ZipCompressionNotSupported">
+ ZIP compression is not supported
+ </Message>
+ <Message name="JNGCompressionNotSupported">
+ JNG compression is not supported
+ </Message>
+ <Message name="JPEGCompressionNotSupported">
+ JPEG compression is not supported
+ </Message>
+ <Message name="PNGCompressionNotSupported">
+ PNG compression is not supported
+ </Message>
+ <Message name="DataStorageTypeIsNotSupported">
+ Data storage type is not supported
+ </Message>
+ <Message name="DeltaPNGNotSupported">
+ Delta-PNG is not supported
+ </Message>
+ <Message name="EncryptedWPGImageFileNotSupported">
+ Encrypted WPG image file not supported
+ </Message>
+ <Message name="ImageColumnOrRowSizeIsNotSupported">
+ Image column or row size is not supported
+ </Message>
+ <Message name="ImageDoesNotHaveAMatteChannel">
+ Image does not have a matte channel
+ </Message>
+ <Message name="ImageTypeNotSupported">
+ Image type not supported
+ </Message>
+ <Message name="IrregularChannelGeometryNotSupported">
+ Irregular channel geometry not supported
+ </Message>
+ <Message name="IncompatibleSizeOfDouble">
+ Incompatible size of double
+ </Message>
+ <Message name="JPEGEmbeddingFailed">
+ JPEG embedding failed
+ </Message>
+ <Message name="LocationTypeIsNotSupported">
+ Location type is not supported
+ </Message>
+ <Message name="MapStorageTypeIsNotSupported">
+ Map storage type is not supported
+ </Message>
+ <Message name="MSBByteOrderNotSupported">
+ MSB order not supported bitmap
+ </Message>
+ <Message name="MultidimensionalMatricesAreNotSupported">
+ Multi-dimensional matrices are not supported
+ </Message>
+ <Message name="MultipleRecordListNotSupported">
+ Multiple record list not supported
+ </Message>
+ <Message name="NoBitmapOnClipboard">
+ No bitmap on clipboard
+ </Message>
+ <Message name="NoAPP1DataIsAvailable">
+ No APP1 data is available
+ </Message>
+ <Message name="No8BIMDataIsAvailable">
+ No 8BIM data is available
+ </Message>
+ <Message name="NoDataReturned">
+ No data returned
+ </Message>
+ <Message name="NoImageVectorGraphics">
+ No image vector graphics
+ </Message>
+ <Message name="NoIPTCProfileAvailable">
+ No IPTC profile available
+ </Message>
+ <Message name="NoColorProfileAvailable">
+ No color profile available
+ </Message>
+ <Message name="NoIPTCInfoWasFound">
+ No IPTC info was found
+ </Message>
+ <Message name="NumberOfImagesIsNotSupported">
+ Number of images is not supported
+ </Message>
+ <Message name="OnlyContinuousTonePictureSupported">
+ Only continuous tone picture supported
+ </Message>
+ <Message name="OnlyLevelZerofilesSupported">
+ Only level zero files Supported
+ </Message>
+ <Message name="PNGLibraryTooOld">
+ PNG library is too old
+ </Message>
+ <Message name="RLECompressionNotSupported">
+ RLE compression not supported
+ </Message>
+ <Message name="SubsamplingRequiresEvenWidth">
+ Subsampling requires that image width be evenly divisible by two
+ </Message>
+ <Message name="UnableToCopyProfile">
+ Unable to copy profile
+ </Message>
+ <Message name="UnableToCreateBitmap">
+ Unable to create bitmap
+ </Message>
+ <Message name="UnableToCreateADC">
+ Unable to create a DC
+ </Message>
+ <Message name="UnableToDecompressImage">
+ Unable to decompress image
+ </Message>
+ <Message name="UnableToReadCIELABImages">
+ Unable to read CIELAB images
+ </Message>
+ <Message name="UnableToReadAspectRatio">
+ Unable to read aspect ratio
+ </Message>
+ <Message name="UnableToReadSummaryInfo">
+ Unable to read summary info
+ </Message>
+ <Message name="UnableToSetAffineMatrix">
+ Unable to set affine matrix
+ </Message>
+ <Message name="UnableToSetAspectRatio">
+ Unable to set aspect ratio
+ </Message>
+ <Message name="UnableToSetColorTwist">
+ Unable to set color twist
+ </Message>
+ <Message name="UnableToSetContrast">
+ Unable to set contrast
+ </Message>
+ <Message name="UnableToSetFilteringValue">
+ Unable to set filtering value
+ </Message>
+ <Message name="UnableToSetImageComments">
+ Unable to set image comment
+ </Message>
+ <Message name="UnableToSetImageTitle">
+ Unable to set image title
+ </Message>
+ <Message name="UnableToSetJPEGLevel">
+ Unable to set JPEG level
+ </Message>
+ <Message name="UnableToSetRegionOfInterest">
+ Unable to set region of interest
+ </Message>
+ <Message name="UnableToSetSummaryInfo">
+ Unable to set summary info
+ </Message>
+ <Message name="UnableToTranslateText">
+ Unable to translate text
+ </Message>
+ <Message name="UnableToWriteMPEGParameters">
+ Unable to write MPEG parameters
+ </Message>
+ <Message name="UnableToZipCompressImage">
+ Unable to zip-compress image
+ </Message>
+ <Message name="UnsupportedCellTypeInTheMatrix">
+ Unsupported cell type in the matrix
+ </Message>
+ <Message name="WebPInvalidConfiguration">
+ Invalid WebP configuration parameters supplied
+ </Message>
+ <Message name="WebPEncodingFailed">
+ WebP encoding failed: unknown reason
+ </Message>
+ <Message name="WebPEncodingFailedOutOfMemory">
+ WebP encoding failed: out of memory
+ </Message>
+ <Message name="WebPEncodingFailedBitstreamOutOfMemory">
+ WebP encoding failed: bitstream out of memory
+ </Message>
+ <Message name="WebPEncodingFailedNULLParameter">
+ WebP encoding failed: null parameter
+ </Message>
+ <Message name="WebPEncodingFailedInvalidConfiguration">
+ WebP encoding failed: invalid configuration
+ </Message>
+ <Message name="WebPEncodingFailedBadDimension">
+ WebP encoding failed: bad dimension
+ </Message>
+ <Message name="WebPEncodingFailedPartition0Overflow">
+ WebP encoding failed: partition 0 overflow (> 512K)
+ </Message>
+ <Message name="WebPEncodingFailedPartitionOverflow">
+ WebP encoding failed: partition overflow (> 16M)
+ </Message>
+ <Message name="WebPEncodingFailedBadWrite">
+ WebP encoding failed: bad write
+ </Message>
+ <Message name="WebPEncodingFailedFileTooBig">
+ WebP encoding failed: File too big (> 4GB)
+ </Message>
+ <Message name="WebPEncodingFailedUserAbort">
+ WebP encoding failed: user abort
+ </Message>
+ <Message name="WebPDecodingFailedUserAbort">
+ WebP decoding failed: user abort
+ </Message>
+ <Message name="WebPInvalidParameter">
+ WebP failed: invalid parameter
+ </Message>
+ <Message name="UnableToWriteTemporaryFile">
+ Unable to write to temporary file
+ </Message>
+ <Message name="UnsupportedBitsPerSample">
+ Unsupported bits per sample
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="LosslessToLossyJPEGConversion">
+ Lossless to lossy JPEG conversion
+ </Message>
+ </Warning>
+ </Coder>
+ <Configure>
+ <Error>
+ <Message name="IncludeElementNestedTooDeeply">
+ include element nested too deeply
+ </Message>
+ <Message name="RegistryKeyLookupFailed">
+ Registry key lookup failed. Package is not properly installed on this machine.
+ </Message>
+ <Message name="UnableToAccessConfigureFile">
+ Unable to access configuration file
+ </Message>
+ <Message name="UnableToAccessFontFile">
+ Unable to access font file
+ </Message>
+ <Message name="UnableToAccessLogFile">
+ Unable to access log configuration file
+ </Message>
+ <Message name="UnableToAccessModuleFile">
+ Unable to access module file
+ </Message>
+ <Message name="StringTokenLengthExceeded">
+ String token maximum length exceeded
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="UnableToGetCurrentDirectory">
+ Unable to get current working directory
+ </Message>
+ <Message name="UnableToChangeToWorkingDirectory">
+ Unable to change to working directory
+ </Message>
+ <Message name="UnableToRestoreCurrentDirectory">
+ Unable to restore current working directory
+ </Message>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Configure>
+ <Corrupt>
+ <Image>
+ <Error>
+ <Message name="AnErrorHasOccurredReadingFromFile">
+ An error has occurred reading from file
+ </Message>
+ <Message name="AnErrorHasOccurredWritingToFile">
+ An error has occurred writing to file
+ </Message>
+ <Message name="ColormapExceedsColorsLimit">
+ Colormap exceeded colors limit
+ </Message>
+ <Message name="CorruptImage">
+ Corrupt image
+ </Message>
+ <Message name="InvalidFileFormatVersion">
+ invalid file format version
+ </Message>
+ <Message name="ImageFileDoesNotContainAnyImageData">
+ Image file or blob does not contain any image data
+ </Message>
+ <Message name="ImageTypeNotSupported">
+ Image type not supported
+ </Message>
+ <Message name="ImproperImageHeader">
+ Improper image header
+ </Message>
+ <Message name="InsufficientImageDataInFile">
+ Insufficient image data in file
+ </Message>
+ <Message name="InvalidColormapIndex">
+ Invalid colormap index
+ </Message>
+ <Message name="LengthAndFilesizeDoNotMatch">
+ Length and filesize do not match
+ </Message>
+ <Message name="MissingImageChannel">
+ Missing a required image channel
+ </Message>
+ <Message name="NegativeOrZeroImageSize">
+ Negative or zero image size
+ </Message>
+ <Message name="NonOS2HeaderSizeError">
+ Non OS2 BMP header size less than 40
+ </Message>
+ <Message name="NotEnoughTiles">
+ Not enough tiles found in level
+ </Message>
+ <Message name="TooMuchImageDataInFile">
+ Too much image data in file
+ </Message>
+ <Message name="StaticPlanesValueNotEqualToOne">
+ Static planes value not equal to 1
+ </Message>
+ <Message name="SubsamplingRequiresEvenWidth">
+ Subsampling requires that image width be evenly divisible by two
+ </Message>
+ <Message name="UnableToReadColorProfile">
+ Unable to read color profile
+ </Message>
+ <Message name="UnableToReadColormapFromDumpFile">
+ Unable to read colormap from dump file
+ </Message>
+ <Message name="UnableToReadExtensionBlock">
+ Unable to read extension block
+ </Message>
+ <Message name="UnableToReadGenericProfile">
+ Unable to read generic profile
+ </Message>
+ <Message name="UnableToReadImageHeader">
+ Unable to read image header
+ </Message>
+ <Message name="UnableToReadIPTCProfile">
+ Unable to read IPTC profile
+ </Message>
+ <Message name="UnableToReadImageData">
+ Unable to read image data
+ </Message>
+ <Message name="UnableToReadPixmapFromDumpFile">
+ Unable to read pixmap from dump file
+ </Message>
+ <Message name="UnableToReadSubImageData">
+ Unable to read sub image data
+ </Message>
+ <Message name="UnableToReadVIDImage">
+ Unable to read VID image
+ </Message>
+ <Message name="UnableToReadWindowNameFromDumpFile">
+ Unable to read window name from dump file
+ </Message>
+ <Message name="UnableToRunlengthDecodeImage">
+ Unable to runlength decode image
+ </Message>
+ <Message name="UnableToUncompressImage">
+ Unable to uncompress image
+ </Message>
+ <Message name="UnexpectedEndOfFile">
+ Unexpected end-of-file
+ </Message>
+ <Message name="UnexpectedSamplingFactor">
+ Unexpected sampling factor
+ </Message>
+ <Message name="UnknownPatternType">
+ Unknown pattern type
+ </Message>
+ <Message name="UnrecognizedBitsPerPixel">
+ Unrecognized bits per pixel
+ </Message>
+ <Message name="UnrecognizedImageCompression">
+ Unrecognized compression
+ </Message>
+ <Message name="UnrecognizedXWDHeader">
+ Unrecognized XWD header
+ </Message>
+ <Message name="CompressionNotValid">
+ Compression not valid
+ </Message>
+ <Message name="UnrecognizedNumberOfColors">
+ Unrecognized number of colors
+ </Message>
+ <Message name="UnsupportedBitsPerSample">
+ Unsupported bits per sample
+ </Message>
+ <Message name="UnsupportedNumberOfPlanes">
+ Unsupported number of planes
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="UnableToPersistKey">
+ Unable to persist key
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="CompressionNotValid">
+ Compression not valid
+ </Message>
+ <Message name="ImproperImageHeader">
+ Improper image header
+ </Message>
+ <Message name="InvalidColormapIndex">
+ Invalid colormap index
+ </Message>
+ <Message name="NegativeOrZeroImageSize">
+ Negative or zero image size
+ </Message>
+ <Message name="NonOS2HeaderSizeError">
+ Non OS2 header size error
+ </Message>
+ <Message name="CorruptImage">
+ Corrupt image (some data returned)
+ </Message>
+ <Message name="StaticPlanesValueNotEqualToOne">
+ Static planes value not equal to one
+ </Message>
+ <Message name="UnrecognizedBitsPerPixel">
+ Unrecognized bits per pixel
+ </Message>
+ <Message name="UnrecognizedImageCompression">
+ Unrecognized image compression
+ </Message>
+ <Message name="SkipToSyncByte">
+ Corrupt PCD image, skipping to sync byte
+ </Message>
+ <Message name="LengthAndFilesizeDoNotMatch">
+ Length and filesize do not match
+ </Message>
+ </Warning>
+ </Image>
+ </Corrupt>
+ <Delegate>
+ <Error>
+ <Message name="DelegateFailed">
+ Delegate failed
+ </Message>
+ <Message name="FailedToComputeOutputSize">
+ Failed to compute output size
+ </Message>
+ <Message name="FailedToRenderFile">
+ Failed to render file
+ </Message>
+ <Message name="FailedToAllocateArgumentList">
+ Failed to allocate argument list.
+ </Message>
+ <Message name="FailedToAllocateGhostscriptInterpreter">
+ Failed to allocate Ghostscript interpreter.
+ </Message>
+ <Message name="FailedToFindGhostscript">
+ Failed to find Ghostscript (not installed?).
+ </Message>
+ <Message name="FailedToScanFile">
+ Failed to scan file
+ </Message>
+ <Message name="NoTagFound">
+ No tag found
+ </Message>
+ <Message name="PostscriptDelegateFailed">
+ Postscript delegate failed
+ </Message>
+ <Message name="UnableToCreateImage">
+ Unable to create image
+ </Message>
+ <Message name="UnableToCreateImageComponent">
+ Unable to create image component
+ </Message>
+ <Message name="UnableToDecodeImageFile">
+ Unable to decode image file
+ </Message>
+ <Message name="UnableToEncodeImageFile">
+ Unable to encode image file
+ </Message>
+ <Message name="UnableToInitializeFPXLibrary">
+ Unable to initialize FPX library
+ </Message>
+ <Message name="UnableToInitializeWMFLibrary">
+ Unable to initialize WMF library
+ </Message>
+ <Message name="UnableToManageJP2Stream">
+ Unable to manage JP2 stream
+ </Message>
+ <Message name="UnableToWriteSVGFormat">
+ Unable to write SVG format
+ </Message>
+ <Message name="WebPABIMismatch">
+ WebP library ABI does not match header ABI (build issue!)
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Delegate>
+ <Draw>
+ <Error>
+ <Message name="AlreadyPushingPatternDefinition">
+ Already pushing pattern definition
+ </Message>
+ <Message name="NonconformingDrawingPrimitiveDefinition">
+ Non-conforming drawing primitive definition
+ </Message>
+ <Message name="UnableToPrint">
+ Unable to print
+ </Message>
+ <Message name="UnbalancedGraphicContextPushPop">
+ unbalanced graphic context push-pop
+ </Message>
+ <Message name="TooManyCoordinates">
+ too many coordinates
+ </Message>
+ <Message name="FloatValueConversionError">
+ text value does not convert to float
+ </Message>
+ <Message name="IntegerValueConversionError">
+ text value does not convert to integer
+ </Message>
+ <Message name="VectorPathTruncated">
+ vector path truncated
+ </Message>
+ <Message name="InvalidPrimitiveArgument">
+ invalid primitive argument
+ </Message>
+ <Message name="DrawingRecursionDetected">
+ drawing recursion detected
+ </Message>
+ <Message name="PrimitiveArithmeticOverflow">
+ primitive arithmetic overflow
+ </Message>
+ <Message name="UnreasonableGradientSize">
+ unreasonable gradient image size
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="NotCurrentlyPushingPatternDefinition">
+ Not currently pushing pattern definition
+ </Message>
+ <Message name="NotARelativeURL">
+ Not a relative URL
+ </Message>
+ <Message name="URLNotFound">
+ URL not found
+ </Message>
+ </Warning>
+ </Draw>
+ <File>
+ <Open>
+ <Error>
+ <Message name="UnableToCreateTemporaryFile">
+ Unable to create temporary file
+ </Message>
+ <Message name="UnableToOpenFile">
+ Unable to open file
+ </Message>
+ <Message name="UnableToWriteFile">
+ Unable to write file
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Open>
+ </File>
+ <Image>
+ <Error>
+ <Message name="AngleIsDiscontinuous">
+ angle is discontinuous
+ </Message>
+ <Message name="ColorspaceColorProfileMismatch">
+ Colorspace color profile mismatch
+ </Message>
+ <Message name="InvalidColormapIndex">
+ Invalid colormap index
+ </Message>
+ <Message name="ImageColorspaceDiffers">
+ image colorspace differs
+ </Message>
+ <Message name="ImageColorspaceMismatch">
+ image colorspace mismatch
+ </Message>
+ <Message name="ImageDifferenceExceedsLimit">
+ image difference exceeds limit (%s)
+ </Message>
+ <Message name="ImageDoesNotContainResolution">
+ image does not contain resolution
+ </Message>
+ <Message name="ImageOpacityDiffers">
+ image opacity differs
+ </Message>
+ <Message name="ImageSequenceIsRequired">
+ Image sequence is required
+ </Message>
+ <Message name="ImageSizeDiffers">
+ image size differs
+ </Message>
+ <Message name="LeftAndRightImageSizesDiffer">
+ left and right image sizes differ
+ </Message>
+ <Message name="NoImagesWereFound">
+ no images were found
+ </Message>
+ <Message name="NoImagesWereLoaded">
+ no images were loaded
+ </Message>
+ <Message name="TooManyClusters">
+ too many cluster
+ </Message>
+ <Message name="NoLocaleImageAttribute">
+ no [LOCALE] image attribute
+ </Message>
+ <Message name="UnableToAppendImage">
+ unable to append image
+ </Message>
+ <Message name="UnableToAssignProfile">
+ Unable to assign profile
+ </Message>
+ <Message name="UnableToAverageImage">
+ unable to average image
+ </Message>
+ <Message name="UnableToCoalesceImage">
+ unable to coalesce image
+ </Message>
+ <Message name="UnableToCompareImages">
+ unable to compare images
+ </Message>
+ <Message name="UnableToCreateStereoImage">
+ unable to create stereo image
+ </Message>
+ <Message name="UnableToCreateImageMosaic">
+ unable to create image mosaic
+ </Message>
+ <Message name="UnableToDeconstructImageSequence">
+ unable to deconstruct image sequence
+ </Message>
+ <Message name="UnableToFlattenImage">
+ unable to flatten image
+ </Message>
+ <Message name="UnableToHandleImageChannel">
+ unable to handle image channel
+ </Message>
+ <Message name="UnableToResizeImage">
+ unable to resize image
+ </Message>
+ <Message name="UnableToSegmentImage">
+ unable to segment image
+ </Message>
+ <Message name="UnableToGetClipMask">
+ Unable to get clip mask
+ </Message>
+ <Message name="UnableToSetClipMask">
+ Unable to set clip mask
+ </Message>
+ <Message name="UnableToShearImage">
+ unable to shear image
+ </Message>
+ <Message name="WidthOrHeightExceedsLimit">
+ width or height exceeds limit
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="UnableToPersistKey">
+ Unable to persist key
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Image>
+ <Missing>
+ <Delegate>
+ <Error>
+ <Message name="DPSLibraryIsNotAvailable">
+ DPS library is not available
+ </Message>
+ <Message name="FPXLibraryIsNotAvailable">
+ FPX library is not available
+ </Message>
+ <Message name="FreeTypeLibraryIsNotAvailable">
+ FreeType library is not available
+ </Message>
+ <Message name="JPEGLibraryIsNotAvailable">
+ JPEG compression library is not available
+ </Message>
+ <Message name="LCMSLibraryIsNotAvailable">
+ LCMS encoding not enabled
+ </Message>
+ <Message name="LZWEncodingNotEnabled">
+ LZW encoding not enabled
+ </Message>
+ <Message name="NoDecodeDelegateForThisImageFormat">
+ No decode delegate for this image format
+ </Message>
+ <Message name="NoEncodeDelegateForThisImageFormat">
+ No encode delegate for this image format
+ </Message>
+ <Message name="TIFFLibraryIsNotAvailable">
+ TIFF library is not available
+ </Message>
+ <Message name="XMLLibraryIsNotAvailable">
+ XML library is not available
+ </Message>
+ <Message name="XWindowLibraryIsNotAvailable">
+ X Window library is not available
+ </Message>
+ <Message name="ZipLibraryIsNotAvailable">
+ ZLIB compression library is not available
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Delegate>
+ </Missing>
+ <Module>
+ <Error>
+ <Message name="FailedToFindSymbol">
+ Failed to find symbol
+ </Message>
+ <Message name="FailedToCloseModule">
+ Failed to close module
+ </Message>
+ <Message name="UnableToLoadModule">
+ Unable to load module
+ </Message>
+ <Message name="UnableToRegisterImageFormat">
+ Unable to register image format
+ </Message>
+ <Message name="UnrecognizedModule">
+ Unrecognized module
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="UnableToInitializeModuleLoader">
+ Unable to initialize module loader
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Module>
+ <Monitor>
+ <Error>
+ <Message name="Default">
+ default error
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="UserRequestedTerminationBySignal">
+ User requested termination (via signal)
+ </Message>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Monitor>
+ <Option>
+ <Error>
+ <Message name="BevelWidthIsNegative">
+ bevel width is negative
+ </Message>
+ <Message name="ColorSeparatedImageRequired">
+ color separated image required
+ </Message>
+ <Message name="FrameIsLessThanImageSize">
+ frame is less than image size
+ </Message>
+ <Message name="GeometryDimensionsAreZero">
+ geometry dimensions are zero
+ </Message>
+ <Message name="GeometryDoesNotContainImage">
+ geometry does not contain image
+ </Message>
+ <Message name="HaldClutImageDimensionsInvalid">
+ hald clut image dimensions are invalid
+ </Message>
+ <Message name="InputImagesAlreadySpecified">
+ input images already specified
+ </Message>
+ <Message name="ImagesAreNotTheSameSize">
+ images are not the same size
+ </Message>
+ <Message name="ImageSizeMustExceedBevelWidth">
+ size must exceed bevel width
+ </Message>
+ <Message name="ImageSmallerThanRadius">
+ image smaller than radius
+ </Message>
+ <Message name="ImageSmallerThanKernelWidth">
+ image smaller than kernel width
+ </Message>
+ <Message name="ImageWidthsOrHeightsDiffer">
+ image widths or heights differ
+ </Message>
+ <Message name="InvalidSubimageSpecification">
+ Invalid subimage specification
+ </Message>
+ <Message name="KernelRadiusIsTooSmall">
+ kernel radius is too small
+ </Message>
+ <Message name="KernelWidthMustBeAnOddNumber">
+ kernel width must be an odd number
+ </Message>
+ <Message name="MatrixOrderOutOfRange">
+ Matrix size is out of range
+ </Message>
+ <Message name="MatrixIsNotSquare">
+ Matrix is not square (%s elements)
+ </Message>
+ <Message name="RegionAreaExceedsLimit">
+ Region area exceeds implementation limit
+ </Message>
+ <Message name="MissingAnImageFilename">
+ Missing an image filename
+ </Message>
+ <Message name="MissingArgument">
+ Option '%s' requires an argument or argument is malformed
+ </Message>
+ <Message name="MustSpecifyAnImageName">
+ Must specify a image name
+ </Message>
+ <Message name="MustSpecifyImageSize">
+ Must specify image size
+ </Message>
+ <Message name="NoBlobDefined">
+ No Binary Large OBjects defined
+ </Message>
+ <Message name="NoImagesDefined">
+ No images defined
+ </Message>
+ <Message name="NonzeroWidthAndHeightRequired">
+ Non-zero width and height required
+ </Message>
+ <Message name="NoProfileNameWasGiven">
+ No profile name was given
+ </Message>
+ <Message name="NullBlobArgument">
+ Null blob argument
+ </Message>
+ <Message name="ReferenceImageRequired">
+ Reference image required
+ </Message>
+ <Message name="ReferenceIsNotMyType">
+ Reference is not my type
+ </Message>
+ <Message name="RequestDidNotReturnAnImage">
+ Request did not return an image
+ </Message>
+ <Message name="SteganoImageRequired">
+ Stegano image required
+ </Message>
+ <Message name="StereoImageRequired">
+ Stereo image required
+ </Message>
+ <Message name="SubimageSpecificationReturnsNoImages">
+ Subimage specification returns no images
+ </Message>
+ <Message name="UnableToAddOrRemoveProfile">
+ Unable to add or remove profile
+ </Message>
+ <Message name="UnableToAverageImageSequence">
+ unable to average image sequence
+ </Message>
+ <Message name="UnableToBlurImage">
+ unable to blur image
+ </Message>
+ <Message name="UnableToChopImage">
+ unable to chop image
+ </Message>
+ <Message name="UnableToColorMatrixImage">
+ Unable to color matrix image
+ </Message>
+ <Message name="UnableToConvolveImage">
+ Unable to convolve image
+ </Message>
+ <Message name="UnableToConstituteImage">
+ Unable to constitute image
+ </Message>
+ <Message name="UnableToEdgeImage">
+ Unable to edge image
+ </Message>
+ <Message name="UnableToEqualizeImage">
+ Unable to equalize image
+ </Message>
+ <Message name="UnableToFilterImage">
+ Unable to filter image
+ </Message>
+ <Message name="UnableToFormatImageMetadata">
+ unable to format image meta data
+ </Message>
+ <Message name="UnableToFrameImage">
+ Unable to frame image
+ </Message>
+ <Message name="UnableToOilPaintImage">
+ unable to oil paint image
+ </Message>
+ <Message name="UnableToPaintImage">
+ Unable to paint image
+ </Message>
+ <Message name="UnableToRaiseImage">
+ Unable to raise image
+ </Message>
+ <Message name="UnableToSharpenImage">
+ Unable to sharpen image
+ </Message>
+ <Message name="UnableToThresholdImage">
+ Unable to threshold image
+ </Message>
+ <Message name="UnableToWaveImage">
+ Unable to wave image
+ </Message>
+ <Message name="UnrecognizedAttribute">
+ Unrecognized attribute
+ </Message>
+ <Message name="UnrecognizedChannelType">
+ Unrecognized channel type
+ </Message>
+ <Message name="UnrecognizedColor">
+ Unrecognized color
+ </Message>
+ <Message name="UnrecognizedColormapType">
+ Unrecognized colormap type
+ </Message>
+ <Message name="UnrecognizedColorspace">
+ Unrecognized image colorspace
+ </Message>
+ <Message name="UnrecognizedCommand">
+ Unrecognized command '%s'. Use -help for a usage summary or see manual.
+ </Message>
+ <Message name="UnrecognizedComposeOperator">
+ Unrecognized compose operator
+ </Message>
+ <Message name="UnrecognizedDisposeMethod">
+ Unrecognized dispose method
+ </Message>
+ <Message name="UnrecognizedEndianType">
+ Unrecognized endian type
+ </Message>
+ <Message name="UnrecognizedElement">
+ Unrecognized element
+ </Message>
+ <Message name="UnrecognizedGravityType">
+ Unrecognized gravity type
+ </Message>
+ <Message name="UnrecognizedHighlightStyle">
+ Unrecognized highlight style
+ </Message>
+ <Message name="UnrecognizedImageCompression">
+ Unrecognized image compression
+ </Message>
+ <Message name="UnrecognizedImageFilter">
+ Unrecognized image filter
+ </Message>
+ <Message name="UnrecognizedImageFormat">
+ Unrecognized image format
+ </Message>
+ <Message name="UnrecognizedImageMode">
+ Unrecognized image mode
+ </Message>
+ <Message name="UnrecognizedImageType">
+ Unrecognized image type
+ </Message>
+ <Message name="UnrecognizedIntentType">
+ Unrecognized intent type
+ </Message>
+ <Message name="UnrecognizedInterlaceType">
+ Unrecognized interlace type
+ </Message>
+ <Message name="UnrecognizedListType">
+ Unrecognized list type
+ </Message>
+ <Message name="UnrecognizedMetric">
+ Unrecognized error metric
+ </Message>
+ <Message name="UnrecognizedModeType">
+ Unrecognized mode type
+ </Message>
+ <Message name="UnrecognizedNoiseType">
+ Unrecognized noise type
+ </Message>
+ <Message name="UnrecognizedPerlMagickMethod">
+ Unrecognized PerlMagick method
+ </Message>
+ <Message name="UnrecognizedPreviewType">
+ Unrecognized preview type
+ </Message>
+ <Message name="UnrecognizedType">
+ Unrecognized type
+ </Message>
+ <Message name="UnrecognizedOperator">
+ Unrecognized operator
+ </Message>
+ <Message name="UnrecognizedOption">
+ Unrecognized option
+ </Message>
+ <Message name="UnrecognizedPixelMap">
+ Unrecognized pixel map
+ </Message>
+ <Message name="UnrecognizedResourceType">
+ Unrecognized resource type
+ </Message>
+ <Message name="UnrecognizedUnitsType">
+ Unrecognized units type
+ </Message>
+ <Message name="UnrecognizedVirtualPixelMethod">
+ Unrecognized virtual pixel method
+ </Message>
+ <Message name="UnsupportedSamplingFactor">
+ Unsupported sampling factor
+ </Message>
+ <Message name="UsageError">
+ Improper arguments supplied, please see manual
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="InvalidInterlaceType">
+ Invalid interlace type
+ </Message>
+ <Message name="InvalidColorspaceType">
+ Invalid colorspace type
+ </Message>
+ <Message name="InvalidImageType">
+ Invalid image type
+ </Message>
+ <Message name="InvalidEndianType">
+ Invalid endian type
+ </Message>
+ <Message name="MissingArgument">
+ Option '%s' requires an argument or argument is malformed
+ </Message>
+ <Message name="MissingAnImageFilename">
+ Missing an image filename
+ </Message>
+ <Message name="NoImagesWereLoaded">
+ No images were loaded
+ </Message>
+ <Message name="OptionLengthExceedsLimit">
+ Option length exceeds limit
+ </Message>
+ <Message name="RequestDidNotReturnAnImage">
+ Request did not return an image
+ </Message>
+ <Message name="UnableToOpenXServer">
+ Unable to open XServer
+ </Message>
+ <Message name="UnableToPersistKey">
+ Unable to persist key
+ </Message>
+ <Message name="UnrecognizedColormapType">
+ Unrecognized colormap type
+ </Message>
+ <Message name="UnrecognizedColorspaceType">
+ Unrecognized colorspace type
+ </Message>
+ <Message name="UnrecognizedEndianType">
+ Unrecognized endian type
+ </Message>
+ <Message name="UnrecognizedImageCompressionType">
+ unrecognized compression type
+ </Message>
+ <Message name="UnrecognizedImageType">
+ Unrecognized image type
+ </Message>
+ <Message name="UnrecognizedInterlaceType">
+ Unrecognized interlace type
+ </Message>
+ <Message name="UnrecognizedDisposeMethod">
+ unrecognized dispose method
+ </Message>
+ <Message name="UnrecognizedFilterType">
+ Unrecognized filter type
+ </Message>
+ <Message name="UnrecognizedOption">
+ Unrecognized option
+ </Message>
+ <Message name="UnrecognizedResourceType">
+ Unrecognized resource type
+ </Message>
+ <Message name="UnrecognizedVirtualPixelMethod">
+ Unrecognized virtual pixel method
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="UnrecognizedColor">
+ Unrecognized color
+ </Message>
+ </Warning>
+ </Option>
+ <Registry>
+ <Error>
+ <Message name="ImageExpected">
+ image expected
+ </Message>
+ <Message name="ImageInfoExpected">
+ image info expected
+ </Message>
+ <Message name="StructureSizeMismatch">
+ structure size mismatch
+ </Message>
+ <Message name="UnableToGetRegistryID">
+ Unable to get registry ID
+ </Message>
+ <Message name="UnableToLocateImage">
+ Unable to locate image
+ </Message>
+ <Message name="UnableToSetRegistry">
+ Unable to set registry
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Registry>
+ <Resource>
+ <Limit>
+ <Error>
+ <Message name="CacheResourcesExhausted">
+ Disk space limit exceeded (see -limit Disk)
+ </Message>
+ <Message name="NoPixelsDefinedInCache">
+ No pixels defined in cache
+ </Message>
+ <Message name="PixelCacheAllocationFailed">
+ Pixel cache allocation failed
+ </Message>
+ <Message name="ImagePixelLimitExceeded">
+ Image pixel limit exceeded (see -limit Pixels)
+ </Message>
+ <Message name="ImagePixelWidthLimitExceeded">
+ Image pixel width limit exceeded (see -limit Width)
+ </Message>
+ <Message name="ImagePixelHeightLimitExceeded">
+ Image pixel height limit exceeded (see -limit Height)
+ </Message>
+ <Message name="MemoryAllocationFailed">
+ Memory allocation failed
+ </Message>
+ <Message name="UnableToAllocateCoefficients">
+ unable to allocate coefficients
+ </Message>
+ <Message name="UnableToAllocateICCProfile">
+ unable to allocate ICC profile
+ </Message>
+ <Message name="UnableToAllocateString">
+ unable to allocate string
+ </Message>
+ <Message name="UnableToAddGenericProfile">
+ unable to add generic profile
+ </Message>
+ <Message name="UnableToAddColorProfile">
+ unable to add ICC Color profile
+ </Message>
+ <Message name="UnableToAddIPTCProfile">
+ unable to add IPTC profile
+ </Message>
+ <Message name="UnableToAllocateColormap">
+ Unable to allocate colormap
+ </Message>
+ <Message name="UnableToAllocateImage">
+ Unable to allocate image
+ </Message>
+ <Message name="UnableToAnnotateImage">
+ Unable to annotate image
+ </Message>
+ <Message name="UnableToAverageImageSequence">
+ unable to average image sequence
+ </Message>
+ <Message name="UnableToCloneDrawingWand">
+ unable to clone drawing wand
+ </Message>
+ <Message name="UnableToCloneImage">
+ unable to clone image
+ </Message>
+ <Message name="UnableToComputeImageSignature">
+ unable to compute image signature
+ </Message>
+ <Message name="UnableToConstituteImage">
+ unable to constitute image
+ </Message>
+ <Message name="UnableToConvertFont">
+ unable to convert font
+ </Message>
+ <Message name="UnableToConvertStringToTokens">
+ unable to convert strings to tokens
+ </Message>
+ <Message name="UnableToCreateColormap">
+ Unable to create colormap
+ </Message>
+ <Message name="UnableToCreateImageGroup">
+ unable to create image group
+ </Message>
+ <Message name="UnableToCreateColorTransform">
+ unable to create color transform
+ </Message>
+ <Message name="UnableToCreateCommandWidget">
+ unable to create command widget
+ </Message>
+ <Message name="UnableToCreateImageMontage">
+ Unable to create image montage
+ </Message>
+ <Message name="UnableToCreateXWindow">
+ unable to create X window
+ </Message>
+ <Message name="UnableToCropImage">
+ unable to crop image
+ </Message>
+ <Message name="UnableToDespeckleImage">
+ unable to despeckle image
+ </Message>
+ <Message name="UnableToDetermineImageClass">
+ unable to determine image class
+ </Message>
+ <Message name="UnableToDetermineTheNumberOfImageColors">
+ unable to determine the number of image colors
+ </Message>
+ <Message name="UnableToDitherImage">
+ unable to dither image
+ </Message>
+ <Message name="UnableToDrawOnImage">
+ unable to draw on image
+ </Message>
+ <Message name="UnableToEdgeImage">
+ unable to edge image
+ </Message>
+ <Message name="UnableToEmbossImage">
+ unable to emboss image
+ </Message>
+ <Message name="UnableToEnhanceImage">
+ unable to enhance image
+ </Message>
+ <Message name="UnableToFloodfillImage">
+ unable to floodfill image
+ </Message>
+ <Message name="UnableToGammaCorrectImage">
+ unable to gamma correct image
+ </Message>
+ <Message name="UnableToGetBestIconSize">
+ unable to get best icon size
+ </Message>
+ <Message name="UnableToGetFromRegistry">
+ unable to get from registry
+ </Message>
+ <Message name="UnableToGetPackageInfo">
+ Unable to get package info
+ </Message>
+ <Message name="UnableToLevelImage">
+ unable to level image
+ </Message>
+ <Message name="UnableToMagnifyImage">
+ unable to magnify image
+ </Message>
+ <Message name="UnableToManageColor">
+ Unable to manage color
+ </Message>
+ <Message name="UnableToMapImage">
+ Unable to map image
+ </Message>
+ <Message name="UnableToMapImageSequence">
+ Unable to map image sequence
+ </Message>
+ <Message name="UnableToMedianFilterImage">
+ unable to median filter image
+ </Message>
+ <Message name="UnableToMotionBlurImage">
+ unable to motion blur image
+ </Message>
+ <Message name="UnableToNormalizeImage">
+ unable to normalize image
+ </Message>
+ <Message name="UnableToNoiseFilterImage">
+ unable to noise filter image
+ </Message>
+ <Message name="UnableToOpenColorProfile">
+ unable to open color profile
+ </Message>
+ <Message name="UnableToQuantizeImage">
+ unable to quantize image
+ </Message>
+ <Message name="UnableToQuantizeImageSequence">
+ unable to quantize image sequence
+ </Message>
+ <Message name="UnableToReadTextChunk">
+ unable to read text chunk
+ </Message>
+ <Message name="UnableToReadXImage">
+ unable to read X image
+ </Message>
+ <Message name="UnableToReadXServerColormap">
+ unable to read X server colormap
+ </Message>
+ <Message name="UnableToResizeImage">
+ unable to resize image
+ </Message>
+ <Message name="UnableToRotateImage">
+ unable to rotate image
+ </Message>
+ <Message name="UnableToSampleImage">
+ unable to sample image
+ </Message>
+ <Message name="UnableToScaleImage">
+ unable to scale image
+ </Message>
+ <Message name="UnableToSelectImage">
+ unable to select image
+ </Message>
+ <Message name="UnableToSharpenImage">
+ unable to sharpen image
+ </Message>
+ <Message name="UnableToShaveImage">
+ unable to shave image
+ </Message>
+ <Message name="UnableToShearImage">
+ unable to shear image
+ </Message>
+ <Message name="UnableToSortImageColormap">
+ unable to sort image colormap
+ </Message>
+ <Message name="UnableToTransformColorspace">
+ unable to transform colorspace
+ </Message>
+ <Message name="UnableToThresholdImage">
+ unable to threshold image
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="UnableToAllocateAscii85Info">
+ unable to allocate ascii85 info
+ </Message>
+ <Message name="UnableToAllocateCacheInfo">
+ unable to allocate cache info
+ </Message>
+ <Message name="UnableToAllocateCacheView">
+ unable to allocate cache view
+ </Message>
+ <Message name="UnableToAllocateColorInfo">
+ unable to allocate color info
+ </Message>
+ <Message name="UnableToAllocateDashPattern">
+ unable to allocate dash pattern
+ </Message>
+ <Message name="UnableToAllocateDelegateInfo">
+ unable to allocate delegate info
+ </Message>
+ <Message name="UnableToAllocateDerivatives">
+ unable to allocate derivates
+ </Message>
+ <Message name="UnableToAllocateDrawContext">
+ unable to allocate draw context
+ </Message>
+ <Message name="UnableToAllocateDrawingWand">
+ unable to allocate drawing wand
+ </Message>
+ <Message name="UnableToAllocateDrawInfo">
+ unable to allocate draw info
+ </Message>
+ <Message name="UnableToAllocateGammaMap">
+ unable to allocate gamma map
+ </Message>
+ <Message name="UnableToAllocateImage">
+ unable to allocate image
+ </Message>
+ <Message name="UnableToAllocateImagePixels">
+ unable to allocate image pixels
+ </Message>
+ <Message name="UnableToAllocateLogInfo">
+ unable to allocate log info
+ </Message>
+ <Message name="UnableToAllocateMagicInfo">
+ unable to allocate magic info
+ </Message>
+ <Message name="UnableToAllocateMagickInfo">
+ unable to allocate magick info
+ </Message>
+ <Message name="UnableToAllocateModuleInfo">
+ unable to allocate module info
+ </Message>
+ <Message name="UnableToAllocateMontageInfo">
+ unable to allocate montage info
+ </Message>
+ <Message name="UnableToAllocateQuantizeInfo">
+ unable to allocate quantize info
+ </Message>
+ <Message name="UnableToAllocateRandomKernel">
+ unable to allocate random kernel
+ </Message>
+ <Message name="UnableToAllocateSemaphoreInfo">
+ unable to allocate semaphore info
+ </Message>
+ <Message name="UnableToAllocateString">
+ unable to allocate string
+ </Message>
+ <Message name="UnableToAllocateTypeInfo">
+ unable to allocate type info
+ </Message>
+ <Message name="UnableToAllocateRegistryInfo">
+ unable to allocate registry info
+ </Message>
+ <Message name="UnableToAllocateWand">
+ unable to allocate wand
+ </Message>
+ <Message name="UnableToDestroySemaphore">
+ unable to destroy semaphore
+ </Message>
+ <Message name="UnableToInitializeSemaphore">
+ unable to initialize semaphore
+ </Message>
+ <Message name="UnableToLockSemaphore">
+ unable to lock semaphore
+ </Message>
+ <Message name="UnableToUnlockSemaphore">
+ unable to unlock semaphore
+ </Message>
+ <Message name="MemoryAllocationFailed">
+ Memory allocation failed
+ </Message>
+ <Message name="SemaporeOperationFailed">
+ Semaphore operation failed
+ </Message>
+ <Message name="UnableToAnimateImageSequence">
+ unable to animate image sequence
+ </Message>
+ <Message name="UnableToCloneBlobInfo">
+ unable to clone blob info
+ </Message>
+ <Message name="UnableToConcatenateString">
+ unable to concatenate string
+ </Message>
+ <Message name="UnableToConvertText">
+ unable to convert text
+ </Message>
+ <Message name="UnableToCreateColormap">
+ unable to create colormap
+ </Message>
+ <Message name="UnableToCloneCacheInfo">
+ unable to clone cache info
+ </Message>
+ <Message name="UnableToCloneImage">
+ unable to clone image
+ </Message>
+ <Message name="UnableToCloneImageInfo">
+ unable to clone image info
+ </Message>
+ <Message name="UnableToDisplayImage">
+ unable to display image
+ </Message>
+ <Message name="UnableToEscapeString">
+ unable to escape string
+ </Message>
+ <Message name="UnableToInterpretMSLImage">
+ unable to interpret MSL image
+ </Message>
+ <Message name="UnableToObtainRandomEntropy">
+ unable to obtain random bytes from operating system
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="MemoryAllocationFailed">
+ Memory allocation failed
+ </Message>
+ </Warning>
+ </Limit>
+ </Resource>
+ <Type>
+ <Error>
+ <Message name="FontSubstitutionRequired">
+ Font substitution required
+ </Message>
+ <Message name="UnableToGetTypeMetrics">
+ Unable to get type metrics
+ </Message>
+ <Message name="UnableToInitializeFreetypeLibrary">
+ Unable to initialize freetype library
+ </Message>
+ <Message name="UnableToReadFont">
+ Unable to read font
+ </Message>
+ <Message name="UnrecognizedFontEncoding">
+ Unrecognized font encoding
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Type>
+ <Stream>
+ <Error>
+ <Message name="ImageDoesNotContainTheStreamGeometry">
+ image does not contain the stream geometry
+ </Message>
+ <Message name="NoStreamHandlerIsDefined">
+ no stream handler is defined
+ </Message>
+ <Message name="PixelCacheIsNotOpen">
+ Pixel cache is not open
+ </Message>
+ <Message name="UnableToAcquirePixelStream">
+ Unable to acquire pixel stream
+ </Message>
+ <Message name="UnableToSetPixelStream">
+ Unable to set pixel stream
+ </Message>
+ <Message name="UnableToSyncPixelStream">
+ Unable to sync pixel stream
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="Default">
+ default error
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="Default">
+ default warning
+ </Message>
+ </Warning>
+ </Stream>
+ <Wand>
+ <Error>
+ <Message name="InvalidColormapIndex">
+ invalid colormap index `%.1024s'
+ </Message>
+ <Message name="WandContainsNoImages">
+ Wand contains no images `%.1024s'
+ </Message>
+ <Message name="WandContainsNoImageIndexs">
+ Wand contains no image indices `%.1024s'
+ </Message>
+ <Message name="WandAPINotImplemented">
+ Wand API not implemented `%.1024s'
+ </Message>
+ </Error>
+ </Wand>
+ <XServer>
+ <Error>
+ <Message name="ColorIsNotKnownToServer">
+ Color is not known to server
+ </Message>
+ <Message name="NoWindowWithSpecifiedIDExists">
+ No window with specified ID exists
+ </Message>
+ <Message name="StandardColormapIsNotInitialized">
+ Standard Colormap is not initialized
+ </Message>
+ <Message name="UnableToConnectToRemoteDisplay">
+ Unable to connect to remote display
+ </Message>
+ <Message name="UnableToCreateBitmap">
+ Unable to create bitmap
+ </Message>
+ <Message name="UnableToCreateColormap">
+ Unable to create colormap
+ </Message>
+ <Message name="UnableToCreatePixmap">
+ Unable to create pixmap
+ </Message>
+ <Message name="UnableToCreateProperty">
+ Unable to create property
+ </Message>
+ <Message name="UnableToCreateStandardColormap">
+ Unable to create standard colormap
+ </Message>
+ <Message name="UnableToDisplayImageInfo">
+ Unable to display image info
+ </Message>
+ <Message name="UnableToGetProperty">
+ Unable to get property
+ </Message>
+ <Message name="UnableToGetStandardColormap">
+ Unable to get Standard Colormap
+ </Message>
+ <Message name="UnableToGetVisual">
+ Unable to get visual
+ </Message>
+ <Message name="UnableToGrabMouse">
+ Unable to grab mouse
+ </Message>
+ <Message name="UnableToLoadFont">
+ Unable to load font
+ </Message>
+ <Message name="UnableToMatchVisualToStandardColormap">
+ Unable to match visual to Standard Colormap
+ </Message>
+ <Message name="UnableToOpenXServer">
+ Unable to open X server
+ </Message>
+ <Message name="UnableToReadXAttributes">
+ Unable to read X attributes
+ </Message>
+ <Message name="UnableToReadXWindowImage">
+ Unable to read X window image
+ </Message>
+ <Message name="UnrecognizedColormapType">
+ Unrecognized colormap type
+ </Message>
+ <Message name="UnrecognizedGravityType">
+ Unrecognized gravity type
+ </Message>
+ <Message name="UnrecognizedVisualSpecifier">
+ Unrecognized visual specifier
+ </Message>
+ </Error>
+ <FatalError>
+ <Message name="UnableToAllocateXHints">
+ Unable to allocate X hints
+ </Message>
+ <Message name="UnableToCreateCursor">
+ Unable to create X cursor
+ </Message>
+ <Message name="UnableToCreateGraphicContext">
+ Unable to create graphic context
+ </Message>
+ <Message name="UnableToCreateStandardColormap">
+ unable to create standard colormap
+ </Message>
+ <Message name="UnableToCreateTextProperty">
+ Unable to create text property
+ </Message>
+ <Message name="UnableToCreateXWindow">
+ Unable to create X window
+ </Message>
+ <Message name="UnableToCreateXImage">
+ Unable to create X image
+ </Message>
+ <Message name="UnableToCreateXPixmap">
+ Unable to create X pixmap
+ </Message>
+ <Message name="UnableToDisplayImage">
+ unable to display image
+ </Message>
+ <Message name="UnableToDitherImage">
+ unable to dither image
+ </Message>
+ <Message name="UnableToGetVisual">
+ Unable to get visual
+ </Message>
+ <Message name="UnableToGetPixelInfo">
+ Unable to get pixel info
+ </Message>
+ <Message name="UnableToLoadFont">
+ Unable to load font
+ </Message>
+ <Message name="UnableToMakeXWindow">
+ Unable to make X window
+ </Message>
+ <Message name="UnableToOpenXServer">
+ Unable to open X server
+ </Message>
+ <Message name="UnableToViewFonts">
+ Unable to view fonts
+ </Message>
+ </FatalError>
+ <Warning>
+ <Message name="UsingDefaultVisual">
+ UsingDefaultVisual
+ </Message>
+ <Message name="UnableToGetVisual">
+ Unable to get visual
+ </Message>
+ </Warning>
+ </XServer>
+</locale>
diff --git a/locale/Makefile b/locale/Makefile
new file mode 100644
index 0000000..6cf3b4a
--- /dev/null
+++ b/locale/Makefile
@@ -0,0 +1,39 @@
+# Copyright (C) 2003 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Generate message dictionaries from XML master file
+#
+
+# Uncomment for verbose listing
+# DEBUG=-debug locale
+
+LMC_TARGET=gm_messages.mc
+LMC_INSTALL_TARGET=../magick/$(LMC_TARGET)
+LCH_TARGET=locale_c.h
+LCH_INSTALL_TARGET=../magick/$(LCH_TARGET)
+
+LOCALE_XML_MASTER=locale.mgk
+LOCALE_XML_DEPENDS=locale.mgk C.mgk
+
+all: $(LCH_TARGET) $(LMC_TARGET)
+
+# Add '-debug locale' to convert commands to see verbose listing
+$(LCH_TARGET) : $(LOCALE_XML_DEPENDS)
+ gm convert $(DEBUG) locale:$(LOCALE_XML_MASTER) localeh:$(LCH_TARGET)
+
+$(LMC_TARGET): $(LOCALE_XML_DEPENDS)
+ gm convert $(DEBUG) locale:$(LOCALE_XML_MASTER) localemc:$(LMC_TARGET)
+
+$(LMC_INSTALL_TARGET) : $(LMC_TARGET)
+ cp $(LMC_TARGET) $(LMC_INSTALL_TARGET)
+
+$(LCH_INSTALL_TARGET) : $(LCH_TARGET)
+ cp $(LCH_TARGET) $(LCH_INSTALL_TARGET)
+
+install: $(LMC_INSTALL_TARGET) $(LCH_INSTALL_TARGET)
+
+clean:
+ rm -f $(LCH_TARGET) $(LMC_TARGET) \ No newline at end of file
diff --git a/locale/README.txt b/locale/README.txt
new file mode 100644
index 0000000..948f967
--- /dev/null
+++ b/locale/README.txt
@@ -0,0 +1,20 @@
+This directory contains the GraphicsMagick message subsystem which
+provides text message strings corresponding to pre-processor symbols
+which are used at the point where the message is emitted. This is
+indended to help support internationalizing GraphicsMagick.
+
+The definitions are in an XML format. An already working copy of
+GraphicsMagick (producing compatible output) is necessary in order to
+convert from C.mgk to locale_c.h.
+
+For now the only locale supported is C.
+
+To update messages use this procedure:
+
+1. Edit C.mgk
+
+2. 'make'
+
+3. 'make install'
+
+4. Now rebuild GraphicsMagick.
diff --git a/locale/locale.mgk b/locale/locale.mgk
new file mode 100644
index 0000000..f4ee64d
--- /dev/null
+++ b/locale/locale.mgk
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<!-- /* -->
+<!-- % Copyright (C) 2003 GraphicsMagick Group -->
+<!-- % Copyright (C) 2002 ImageMagick Studio -->
+<!-- % -->
+<!-- % This program is covered by multiple licenses, which are described in -->
+<!-- % Copyright.txt. You should have received a copy of Copyright.txt with this -->
+<!-- % package; otherwise see http://www.graphicsmagick.org/www/Copyright.html. -->
+<!-- % -->
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<!-- % % -->
+<!-- % % -->
+<!-- % % -->
+<!-- % L OOO CCCC AAA L EEEEE % -->
+<!-- % L O O C A A L E % -->
+<!-- % L O O C AAAAA L EEE % -->
+<!-- % L O O C A A L E % -->
+<!-- % LLLLL OOO CCCC A A LLLLL EEEEE % -->
+<!-- % % -->
+<!-- % % -->
+<!-- % ImageMagick Locale Message Methods % -->
+<!-- % % -->
+<!-- % % -->
+<!-- % Software Design % -->
+<!-- % John Cristy % -->
+<!-- % Kyle Shorter % -->
+<!-- % September 2002 % -->
+<!-- % % -->
+<!-- % % -->
+<!-- % % -->
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<!-- % -->
+<!-- % -->
+<!-- % -->
+<!-- */ -->
+<!-- -->
+<!-- /* -->
+<!-- Include declarations. -->
+<!-- */ -->
+<!-- #include "studio.h" -->
+<!-- #include "utility.h" -->
+<!-- -->
+<!-- /* -->
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<!-- % % -->
+<!-- % % -->
+<!-- % % -->
+<!-- % G e t L o c a l e M e s s a g e % -->
+<!-- % % -->
+<!-- % % -->
+<!-- % % -->
+<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
+<!-- % -->
+<!-- % GetLocaleMessage() returns a message in the current locale that matches the -->
+<!-- % supplied tag. -->
+<!-- % -->
+<!-- % The format of the GetLocaleMessage method is: -->
+<!-- % -->
+<!-- % const char *GetLocaleMessage(const char *tag) -->
+<!-- % -->
+<!-- % A description of each parameter follows: -->
+<!-- % -->
+<!-- % o tag: Return a message that matches this tag in the current locale. -->
+<!-- % -->
+<!-- % -->
+<!-- */ -->
+<localemap>
+ <include locale="C" file="C.mgk" />
+</localemap>
diff --git a/m4/acx_pthread.m4 b/m4/acx_pthread.m4
new file mode 100644
index 0000000..cdfed55
--- /dev/null
+++ b/m4/acx_pthread.m4
@@ -0,0 +1,305 @@
+##### http://autoconf-archive.cryp.to/acx_pthread.html
+#
+# SYNOPSIS
+#
+# ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+# This macro figures out how to build C programs using POSIX threads.
+# It sets the PTHREAD_LIBS output variable to the threads library and
+# linker flags, and the PTHREAD_CFLAGS output variable to any special
+# C compiler flags that are needed. (The user can also force certain
+# compiler flags/libs to be tested by setting these environment
+# variables.)
+#
+# Also sets PTHREAD_CC to any special C compiler that is needed for
+# multi-threaded programs (defaults to the value of CC otherwise).
+# (This is necessary on AIX to use the special cc_r compiler alias.)
+#
+# NOTE: You are assumed to not only compile your program with these
+# flags, but also link it with them as well. e.g. you should link
+# with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
+# $LIBS
+#
+# If you are only building threads programs, you may wish to use
+# these variables in your default LIBS, CFLAGS, and CC:
+#
+# LIBS="$PTHREAD_LIBS $LIBS"
+# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CC="$PTHREAD_CC"
+#
+# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
+# constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
+# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+# ACTION-IF-FOUND is a list of shell commands to run if a threads
+# library is found, and ACTION-IF-NOT-FOUND is a list of commands to
+# run it if it is not found. If ACTION-IF-FOUND is not specified, the
+# default action will define HAVE_PTHREAD.
+#
+# Please let the authors know if this macro fails on any platform, or
+# if you have any other suggestions or comments. This macro was based
+# on work by SGJ on autoconf scripts for FFTW (http://www.fftw.org/)
+# (with help from M. Frigo), as well as ac_pthread and hb_pthread
+# macros posted by Alejandro Forero Cuervo to the autoconf macro
+# repository. We are also grateful for the helpful feedback of
+# numerous users.
+#
+# LAST MODIFICATION
+#
+# 2006-05-29
+#
+# COPYLEFT
+#
+# Copyright (c) 2006 Steven G. Johnson <stevenj@alum.mit.edu>
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# As a special exception, the respective Autoconf Macro's copyright
+# owner gives unlimited permission to copy, distribute and modify the
+# configure scripts that are the output of Autoconf when processing
+# the Macro. You need not follow the terms of the GNU General Public
+# License when using or distributing such scripts, even though
+# portions of the text of the Macro appear in them. The GNU General
+# Public License (GPL) does govern all other use of the material that
+# constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the
+# Autoconf Macro released by the Autoconf Macro Archive. When you
+# make and distribute a modified version of the Autoconf Macro, you
+# may extend this special exception to the GPL to apply to your
+# modified version as well.
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+ AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+ AC_MSG_RESULT($acx_pthread_ok)
+ if test x"$acx_pthread_ok" = xno; then
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try. Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt lpthread pthread-config"
+
+# The ordering *is* (sometimes) important. Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+# other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+# doesn't hurt to check since this sometimes defines pthreads too;
+# also defines -D_REENTRANT)
+# ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+ *solaris*)
+
+ # On Solaris (at least, for some versions), libc contains stubbed
+ # (non-functional) versions of the pthreads routines, so link-based
+ # tests will erroneously succeed. (We need to link with -pthreads/-mt/
+ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
+ # a function called by this macro, so we could check for that, but
+ # who knows whether they'll stub that too in a future libc.) So,
+ # we'll just look for -pthreads and -lpthread first:
+
+ acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+ ;;
+
+ # The HP-UX compiler just warns about options it does not understand
+ # but it needs -mt.
+ *-hpux*)
+ acx_pthread_flags="-mt $acx_pthread_flags"
+ ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+ case $flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $flag])
+ PTHREAD_CFLAGS="$flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+ if test x"$acx_pthread_config" = xno; then continue; fi
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$flag])
+ PTHREAD_LIBS="-l$flag"
+ ;;
+ esac
+
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+ AC_TRY_LINK([#include <pthread.h>],
+ [pthread_t th; pthread_join(th, 0);
+ pthread_attr_init(0); pthread_cleanup_push(0, 0);
+ pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+ [acx_pthread_ok=yes])
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ AC_MSG_RESULT($acx_pthread_ok)
+ if test "x$acx_pthread_ok" = xyes; then
+ break;
+ fi
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+ save_LIBS="$LIBS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+ # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+ AC_MSG_CHECKING([for joinable pthread attribute])
+ attr_name=unknown
+ for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+ AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+ [attr_name=$attr; break])
+ done
+ AC_MSG_RESULT($attr_name)
+ if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+ AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+ [Define to necessary symbol if this constant
+ uses a non-standard name on your system.])
+ fi
+
+ AC_MSG_CHECKING([if more special flags are required for pthreads])
+ flag=no
+ case "${host_cpu}-${host_os}" in
+ *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+ *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+ esac
+ AC_MSG_RESULT(${flag})
+ if test "x$flag" != xno; then
+ PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+ fi
+
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+
+ # More AIX lossage: must compile with xlc_r or cc_r
+ case "${host_os}" in
+ aix* )
+ if test x"$GCC" != xyes; then
+ case "$CC" in
+ *xlc )
+ AC_CHECK_PROG(PTHREAD_CC, xlc_r, xlc_r, ${CC}) ;;
+ *cc )
+ AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) ;;
+ esac
+ fi
+ case "$CXX" in
+ *xlC )
+ AC_CHECK_PROG(PTHREAD_CXX, xlC_r, xlC_r, ${CXX}) ;;
+ esac
+ ;;
+ esac
+fi
+
+if test "${PTHREAD_CC}x" = "x"
+then
+ PTHREAD_CC="$CC"
+fi
+if test "${PTHREAD_CXX}x" = "x"
+then
+ PTHREAD_CXX="$CXX"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+AC_SUBST(PTHREAD_CXX)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+ ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+ :
+else
+ acx_pthread_ok=no
+ $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
diff --git a/m4/libtool.m4 b/m4/libtool.m4
new file mode 100644
index 0000000..a3bc337
--- /dev/null
+++ b/m4/libtool.m4
@@ -0,0 +1,8369 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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, see <http://www.gnu.org/licenses/>.
+])
+
+# serial 58 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in @S|@*""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
+m4_defun([_LT_CC_BASENAME],
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $[#]
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS=$save_LDFLAGS
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]][[,.]]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ m4_if([$1], [CXX],
+[ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case $ECHO in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+ [Search for dependent libraries within DIR (or the compiler's sysroot
+ if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([$with_sysroot])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen=shl_load],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen=dlopen],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test no = "$hard_links"; then
+ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+ [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x@S|@2 in
+ x)
+ ;;
+ *:)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+ ;;
+ x:*)
+ eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+ ;;
+ *)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+ [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$1"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac])
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test no = "$withval" || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi])
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+ [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+ test DEF = "`$SED -n dnl
+ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
+ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
+ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
+ -e q dnl Only consider the first "real" line
+ $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM=-lm)
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+ [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+ [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64, which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS=$save_LDFLAGS])
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting $shlibpath_var if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report what library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test yes = "$GXX"; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='$wl'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GXX"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ # The "-G" linker flag allows undefined symbols.
+ _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared
+ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)=$GXX
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case @S|@2 in
+ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $prev$p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)=$prev$p
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test no = "$pre_test_object_deps_done"; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)=$p
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)=$p
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$G77
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f "$lt_ac_sed" && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test 10 -lt "$lt_ac_count" && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test "$lt_ac_count" -gt "$lt_ac_max"; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
new file mode 100644
index 0000000..94b0829
--- /dev/null
+++ b/m4/ltoptions.m4
@@ -0,0 +1,437 @@
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 8 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option '$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
+ [_LT_WITH_AIX_SONAME([aix])])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
+shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[[5-9]]*,yes)
+ AC_MSG_CHECKING([which variant of shared library versioning to provide])
+ AC_ARG_WITH([aix-soname],
+ [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+ [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+ [case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ AC_MSG_ERROR([Unknown argument to --with-aix-soname])
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname],
+ [AC_CACHE_VAL([lt_cv_with_aix_soname],
+ [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+ with_aix_soname=$lt_cv_with_aix_soname])
+ AC_MSG_RESULT([$with_aix_soname])
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+ [Shared archive member basename, for filename based shared library versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# LT_INIT options.
+# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [pic_mode=m4_default([$1], [default])])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4
new file mode 100644
index 0000000..48bc934
--- /dev/null
+++ b/m4/ltsugar.m4
@@ -0,0 +1,124 @@
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59, which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
new file mode 100644
index 0000000..fa04b52
--- /dev/null
+++ b/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 4179 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.6'
+macro_revision='2.4.6'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/magick/GraphicsMagick-config.1 b/magick/GraphicsMagick-config.1
new file mode 100644
index 0000000..4cc3610
--- /dev/null
+++ b/magick/GraphicsMagick-config.1
@@ -0,0 +1,71 @@
+.ad l
+.nh
+.TH GraphicsMagick-Config 1 "4 December 2002" "GraphicsMagick"
+.SH NAME
+GraphicsMagick-config \- get information about the installed version of GraphicsMagick
+.SH SYNOPSIS
+.B GraphicsMagick-config
+.B [--cflags]
+.B [--cppflags]
+.B [--exec-prefix]
+.B [--ldflags]
+.B [--libs]
+.B [--prefix]
+.B [--version]
+.SH DESCRIPTION
+.B GraphicsMagick-config
+prints the compiler and linker flags required to compile and link programs
+that use the
+.BR GraphicsMagick
+Application Programmer Interface.
+.SH EXAMPLES
+To print the version of the installed distribution of
+.BR GraphicsMagick ,
+use:
+
+.nf
+ GraphicsMagick-config --version
+.fi
+
+To compile a program that calls the
+.BR GraphicsMagick
+Application Programmer Interface, use:
+
+.nf
+ cc `GraphicsMagick-config --cflags --cppflags --ldflags --libs` program.c
+.fi
+
+.SH OPTIONS
+.TP
+.B --cflags
+Print the compiler flags that were used to compile
+.BR libMagick .
+.TP
+.B --cppflags
+Print the preprocessor flags that are needed to find the
+.B GraphicsMagick
+C include files and defines to ensure that the GraphicsMagick data structures match between
+your program and the installed libraries.
+.TP
+.B --exec-prefix
+Print the directory under which target specific binaries and executables are installed.
+.TP
+.B --ldflags
+Print the linker flags that are needed to link with the
+.B GraphicsMagick
+library.
+.TP
+.B --libs
+Print the linker flags that are needed to link a program with
+.BR libGraphicsMagick .
+.TP
+.B --version
+Print the version of the
+.B GraphicsMagick
+distribution to standard output.
+.SH COPYRIGHT
+Copyright (C) 2002 GraphicsMagick Group
+
+Copyright (C) 2002 ImageMagick Studio
+.SH AUTHORS
+Bob Friesenhahn
diff --git a/magick/GraphicsMagick-config.in b/magick/GraphicsMagick-config.in
new file mode 100644
index 0000000..8b2f016
--- /dev/null
+++ b/magick/GraphicsMagick-config.in
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# Configure options script for re-calling GraphicsMagick compilation
+# options required to use the GraphicsMagick library.
+#
+# Concept derived from gtk-config in the Gtk package except that Autoconf-style
+# configuration information is presented instead so that it may be used more
+# effectively in configure scripts.
+#
+usage='Usage: GraphicsMagick-config [--cflags] [--cppflags] [--exec-prefix] [--ldflags] [--libs] [--prefix] [--version]
+
+ For example, "example.c" may be compiled to produce "example" as follows:
+
+ "gcc -o example example.c `GraphicsMagick-config --cppflags --cflags --ldflags --libs`"'
+
+if test $# -eq 0; then
+ echo "${usage}" 1>&2
+ exit 1
+fi
+
+while test $# -gt 0; do
+ case $1 in
+ --prefix)
+ echo @PREFIX_DIR@
+ ;;
+ --exec-prefix)
+ echo @EXEC_PREFIX_DIR@
+ ;;
+ --version)
+ echo @PACKAGE_VERSION@
+ ;;
+ --cflags)
+ echo '@CFLAGS@'
+ ;;
+ --cppflags)
+ echo '@MAGICK_API_CPPFLAGS@'
+ ;;
+ --ldflags)
+ echo '@MAGICK_API_LDFLAGS@'
+ ;;
+ --libs)
+ echo '@MAGICK_API_LIBS@'
+ ;;
+ *)
+ echo "${usage}" 1>&2
+ exit 1
+ ;;
+ esac
+ shift
+done
+
diff --git a/magick/GraphicsMagick.pc.in b/magick/GraphicsMagick.pc.in
new file mode 100644
index 0000000..5757b37
--- /dev/null
+++ b/magick/GraphicsMagick.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/GraphicsMagick
+
+
+Name: GraphicsMagick
+Version: @PACKAGE_VERSION@
+Description: GraphicsMagick image processing library
+Libs: -L${libdir} -lGraphicsMagick
+Cflags: -I${includedir} @MAGICK_API_PC_CPPFLAGS@
diff --git a/magick/Makefile.am b/magick/Makefile.am
new file mode 100644
index 0000000..b531136
--- /dev/null
+++ b/magick/Makefile.am
@@ -0,0 +1,332 @@
+# Copyright (C) 2004-2014 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building GraphicsMagick library
+#
+#
+
+magickincdir = $(topincludedir)/magick
+
+# Headers which are installed
+magickinc_HEADERS = \
+ $(MAGICK_INCLUDE_HDRS)
+
+MAGICK_BIN_SCRPTS = \
+ magick/GraphicsMagick-config
+
+MAGICK_PKGCONFIG = \
+ magick/GraphicsMagick.pc
+
+MAGICK_MANS = \
+ magick/GraphicsMagick-config.1
+
+LIBMAGICK=magick/libGraphicsMagick.la
+
+if WITH_MODULES
+magick_libGraphicsMagick_la_SOURCES = $(MAGICK_BASE_SRCS) $(MAGICK_PLATFORM_SRCS)
+magick_libGraphicsMagick_la_LIBADD = $(MAGICK_DEP_LIBS)
+else
+magick_libGraphicsMagick_la_SOURCES = $(MAGICK_BASE_SRCS) $(MAGICK_PLATFORM_SRCS) $(MAGICK_CODER_SRCS) $(MAGICK_FILTER_SRCS)
+magick_libGraphicsMagick_la_LIBADD = $(MAGICK_DEP_LIBS)
+endif # WITH_MODULES
+magick_libGraphicsMagick_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBRARY_EXTRA_CPPFLAGS)
+magick_libGraphicsMagick_la_LDFLAGS = \
+ -no-undefined -export-symbols-regex ".*" \
+ $(MAGICK_LT_RELEASE_OPTS) \
+ -version-info $(MAGICK_LIBRARY_CURRENT):$(MAGICK_LIBRARY_REVISION):$(MAGICK_LIBRARY_AGE)
+#magick_libGraphicsMagick_la_DEPENDENCIES =
+
+if HasX11
+MAGICK_X11_BASE_SRCS = \
+ magick/animate.c \
+ magick/animate.h \
+ magick/display.c \
+ magick/display.h \
+ magick/PreRvIcccm.c \
+ magick/PreRvIcccm.h \
+ magick/widget.c \
+ magick/widget.h \
+ magick/xwindow.c \
+ magick/xwindow.h
+endif
+
+# Library base sources
+MAGICK_BASE_SRCS = \
+ magick/alpha_composite.h \
+ magick/analyze.c \
+ magick/analyze.h \
+ magick/annotate.c \
+ magick/api.h \
+ magick/attribute.c \
+ magick/attribute.h \
+ magick/average.c \
+ magick/average.h \
+ magick/bit_stream.c \
+ magick/bit_stream.h \
+ magick/blob.c \
+ magick/blob.h \
+ magick/cdl.c \
+ magick/cdl.h \
+ magick/channel.c \
+ magick/channel.h \
+ magick/common.h \
+ magick/compare.c \
+ magick/compare.h \
+ magick/confirm_access.c \
+ magick/confirm_access.h \
+ magick/color.c \
+ magick/color.h \
+ magick/color_lookup.c \
+ magick/color_lookup.h \
+ magick/colormap.c \
+ magick/colormap.h \
+ magick/colorspace.c \
+ magick/colorspace.h \
+ magick/command.c \
+ magick/command.h \
+ magick/composite.c \
+ magick/composite.h \
+ magick/compress.c \
+ magick/compress.h \
+ magick/constitute.c \
+ magick/constitute.h \
+ magick/decorate.c \
+ magick/decorate.h \
+ magick/delegate.c \
+ magick/delegate.h \
+ magick/deprecate.c \
+ magick/deprecate.h \
+ magick/describe.c \
+ magick/describe.h \
+ magick/draw.c \
+ magick/draw.h \
+ magick/effect.c \
+ magick/effect.h \
+ magick/enhance.c \
+ magick/enhance.h \
+ magick/enum_strings.c \
+ magick/enum_strings.h \
+ magick/error.c \
+ magick/error.h \
+ magick/export.c \
+ magick/floats.c \
+ magick/floats.h \
+ magick/forward.h \
+ magick/fx.c \
+ magick/fx.h \
+ magick/gem.c \
+ magick/gem.h \
+ magick/gradient.c \
+ magick/gradient.h \
+ magick/hclut.c \
+ magick/hclut.h \
+ magick/image.c \
+ magick/image.h \
+ magick/import.c \
+ magick/list.c \
+ magick/list.h \
+ magick/locale.c \
+ magick/locale_c.h \
+ magick/log.c \
+ magick/log.h \
+ magick/magic.c \
+ magick/magic.h \
+ magick/magick.c \
+ magick/magick.h \
+ magick/magick_endian.c \
+ magick/magick_endian.h \
+ magick/map.c \
+ magick/map.h \
+ magick/memory.c \
+ magick/memory.h \
+ magick/module.c \
+ magick/module.h \
+ magick/monitor.c \
+ magick/monitor.h \
+ magick/montage.c \
+ magick/montage.h \
+ magick/omp_data_view.c \
+ magick/omp_data_view.h \
+ magick/operator.c \
+ magick/operator.h \
+ magick/paint.c \
+ magick/paint.h \
+ magick/pixel_cache.h \
+ magick/pixel_cache.c \
+ magick/pixel_iterator.c \
+ magick/pixel_iterator.h \
+ magick/plasma.c \
+ magick/plasma.h \
+ magick/prefetch.h \
+ magick/profile.c \
+ magick/profile.h \
+ magick/quantize.c \
+ magick/quantize.h \
+ magick/registry.c \
+ magick/registry.h \
+ magick/random.c \
+ magick/random.h \
+ magick/render.c \
+ magick/render.h \
+ magick/resize.c \
+ magick/resize.h \
+ magick/resource.c \
+ magick/resource.h \
+ magick/segment.c \
+ magick/semaphore.c \
+ magick/semaphore.h \
+ magick/shear.c \
+ magick/shear.h \
+ magick/signature.c \
+ magick/signature.h \
+ magick/spinlock.h \
+ magick/static.c \
+ magick/static.h \
+ magick/statistics.c \
+ magick/statistics.h \
+ magick/studio.h \
+ magick/symbols.h \
+ magick/tempfile.c \
+ magick/tempfile.h \
+ magick/texture.c \
+ magick/texture.h \
+ magick/timer.c \
+ magick/timer.h \
+ magick/transform.c \
+ magick/transform.h \
+ magick/tsd.c \
+ magick/tsd.h \
+ magick/type.c \
+ magick/type.h \
+ magick/unix_port.c \
+ magick/utility.c \
+ magick/utility.h \
+ magick/version.c \
+ magick/version.h \
+ $(MAGICK_X11_BASE_SRCS)
+
+if WIN32_NATIVE_BUILD
+MAGICK_PLATFORM_SRCS = \
+ magick/nt_base.c \
+ magick/nt_base.h \
+ magick/nt_feature.c \
+ magick/nt_feature.h
+else
+if CYGWIN_BUILD
+MAGICK_PLATFORM_SRCS = \
+ magick/nt_feature.c \
+ magick/nt_feature.h
+else
+MAGICK_PLATFORM_SRCS =
+endif # if CYGWIN_BUILD
+endif # if WIN32_NATIVE_BUILD
+
+MAGICK_INCLUDE_HDRS = \
+ magick/api.h \
+ magick/analyze.h \
+ magick/attribute.h \
+ magick/average.h \
+ magick/blob.h \
+ magick/cdl.h \
+ magick/channel.h \
+ magick/color.h \
+ magick/color_lookup.h \
+ magick/colormap.h \
+ magick/colorspace.h \
+ magick/command.h \
+ magick/common.h \
+ magick/compare.h \
+ magick/composite.h \
+ magick/compress.h \
+ magick/confirm_access.h \
+ magick/constitute.h \
+ magick/decorate.h \
+ magick/delegate.h \
+ magick/describe.h \
+ magick/deprecate.h \
+ magick/draw.h \
+ magick/effect.h \
+ magick/enhance.h \
+ magick/error.h \
+ magick/forward.h \
+ magick/fx.h \
+ magick/gem.h \
+ magick/gradient.h \
+ magick/hclut.h \
+ magick/image.h \
+ magick/list.h \
+ magick/log.h \
+ magick/magic.h \
+ magick/magick.h \
+ magick/magick_types.h \
+ magick/memory.h \
+ magick/module.h \
+ magick/monitor.h \
+ magick/montage.h \
+ magick/operator.h \
+ magick/paint.h \
+ magick/pixel_cache.h \
+ magick/pixel_iterator.h \
+ magick/plasma.h \
+ magick/profile.h \
+ magick/quantize.h \
+ magick/random.h \
+ magick/registry.h \
+ magick/render.h \
+ magick/resize.h \
+ magick/resource.h \
+ magick/shear.h \
+ magick/signature.h \
+ magick/statistics.h \
+ magick/symbols.h \
+ magick/texture.h \
+ magick/timer.h \
+ magick/transform.h \
+ magick/type.h \
+ magick/utility.h \
+ magick/version.h
+
+MAGICK_NOINST_HDRS = \
+ magick/alpha_composite.h \
+ magick/animate.h \
+ magick/bit_stream.h \
+ magick/display.h \
+ magick/floats.h \
+ magick/locale_c.h \
+ magick/map.h \
+ magick/nt_base.h \
+ magick/nt_feature.h \
+ magick/omp_data_view.h \
+ magick/prefetch.h \
+ magick/random-private.h \
+ magick/semaphore.h \
+ magick/spinlock.h \
+ magick/static.h \
+ magick/studio.h \
+ magick/tempfile.h \
+ magick/unix_port.h \
+ magick/widget.h \
+ magick/xwindow.h
+
+
+MAGICK_EXTRA_DIST = \
+ magick/GraphicsMagick-config.in \
+ $(MAGICK_MANS) \
+ magick/GraphicsMagick.pc.in \
+ magick/nt_base.c \
+ magick/nt_feature.c
+
+# Install magick_config_api.h as magick_config.h
+MAGICK_INSTALL_DATA_LOCAL_TARGETS = magick-install-data-local
+magick-install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(magickincdir)
+ $(INSTALL_HEADER) magick/magick_config_api.h $(DESTDIR)$(magickincdir)/magick_config.h
+
+# Uninstall magick_config.h
+MAGICK_UNINSTALL_LOCAL_TARGETS = magick-uninstall-local
+magick-uninstall-local:
+ rm -f $(DESTDIR)$(magickincdir)/magick_config.h
+
diff --git a/magick/PreRvIcccm.c b/magick/PreRvIcccm.c
new file mode 100644
index 0000000..7b58af3
--- /dev/null
+++ b/magick/PreRvIcccm.c
@@ -0,0 +1,342 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% %
+% IIIII CCCC CCCC CCCC M M %
+% I C C C MM MM %
+% I C C C M M M %
+% I C C C M M %
+% IIIII CCCC CCCC CCCC M M %
+% %
+% X11 Compatibility Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% December 1994 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+#include "magick/studio.h"
+#if defined(HasX11)
+#include "magick/xwindow.h"
+
+#if defined(PRE_R6_ICCCM)
+/*
+ Compatibility methods for pre X11R6 ICCCM.
+*/
+Status XInitImage(XImage *ximage)
+{
+ Display
+ display;
+
+ ScreenFormat
+ screen_format;
+
+ XImage
+ *created_ximage,
+ target_ximage;
+
+ /*
+ Initialize the X image.
+ */
+ screen_format.depth=ximage->depth;
+ screen_format.bits_per_pixel=(int) ximage->bits_per_pixel;
+ display.byte_order=ximage->byte_order;
+ display.bitmap_unit=ximage->bitmap_unit;
+ display.bitmap_bit_order=ximage->bitmap_bit_order;
+ display.pixmap_format=(&screen_format);
+ display.nformats=1;
+ created_ximage=XCreateImage(&display,(Visual *) NULL,ximage->depth,
+ ximage->format,ximage->xoffset,(char *) NULL,ximage->width,ximage->height,
+ ximage->bitmap_pad,ximage->bytes_per_line);
+ if (created_ximage == (XImage *) NULL)
+ return(0);
+ target_ximage=(*ximage);
+ *ximage=(*created_ximage);
+ created_ximage->data=(char *) NULL;
+ XDestroyImage(created_ximage);
+ ximage->red_mask=target_ximage.red_mask;
+ ximage->green_mask=target_ximage.green_mask;
+ ximage->blue_mask=target_ximage.blue_mask;
+ return(1);
+}
+#endif
+
+#if defined(PRE_R5_ICCCM)
+/*
+ Compatibility methods for pre X11R5 ICCCM.
+*/
+void XrmCombineDatabase(XrmDatabase source,XrmDatabase *target,
+ Bool override)
+{
+ XrmMergeDatabases(source,target);
+}
+
+Status XrmCombineFileDatabase(const char *filename,XrmDatabase *target,
+ Bool override)
+{
+ XrmDatabase
+ *combined_database,
+ source;
+
+ source=XrmGetFileDatabase(filename);
+ if (!override)
+ XrmMergeDatabases(source,target);
+ return(1);
+}
+
+XrmDatabase XrmGetDatabase(Display *display)
+{
+ return(display->db);
+}
+
+char *XSetLocaleModifiers(char *modifiers)
+{
+ return((char *) NULL);
+}
+
+Bool XSupportsLocale()
+{
+ return(0);
+}
+#endif
+
+#if defined(PRE_R4_ICCCM)
+/*
+ Compatibility methods for pre X11R4 ICCCM.
+*/
+XClassHint *XAllocClassHint)
+{
+ returnMagickAllocateMemory((XClassHint *,sizeof(XClassHint)));
+}
+
+XIconSize *XAllocIconSize)
+{
+ returnMagickAllocateMemory((XIconSize *,sizeof(XIconSize)));
+}
+
+XSizeHints *XAllocSizeHints)
+{
+ returnMagickAllocateMemory((XSizeHints *,sizeof(XSizeHints)));
+}
+
+Status XReconfigureWMWindow(Display *display,Window window,int screen_number,
+ unsigned int value_mask,XWindowChanges *values)
+{
+ return(XConfigureWindow(display,window,value_mask,values));
+}
+
+XStandardColormap *XAllocStandardColormap)
+{
+ returnMagickAllocateMemory((XStandardColormap *,sizeof(XStandardColormap)));
+}
+
+XWMHints *XAllocWMHints)
+{
+ returnMagickAllocateMemory((XWMHints *,sizeof(XWMHints)));
+}
+
+Status XGetGCValues(Display *display,GC gc,unsigned long mask,
+ XGCValues *values)
+{
+ return(True);
+}
+
+Status XGetRGBColormaps(Display *display,Window window,
+ XStandardColormap **colormap,int *count,Atom property)
+{
+ *count=1;
+ return(XGetStandardColormap(display,window,*colormap,property));
+}
+
+Status XGetWMColormapWindows(Display *display,Window window,
+ Window **colormap_windows,int *number_windows)
+{
+ Atom
+ actual_type,
+ *data,
+ property;
+
+ int
+ actual_format,
+ status;
+
+ unsigned long
+ leftover,
+ number_items;
+
+ property=XInternAtom(display,"WM_COLORMAP_WINDOWS",False);
+ if (property == None)
+ return(False);
+ /*
+ Get the window property.
+ */
+ *data=(Atom) NULL;
+ status=XGetWindowProperty(display,window,property,0L,1000000L,False,
+ XA_WINDOW,&actual_type,&actual_format,&number_items,&leftover,
+ (unsigned char **) &data);
+ if (status != Success)
+ return(False);
+ if ((actual_type != XA_WINDOW) || (actual_format != 32))
+ {
+ if (data != (Atom *) NULL)
+ XFree((char *) data);
+ return(False);
+ }
+ *colormap_windows=(Window *) data;
+ *number_windows=(int) number_items;
+ return(True);
+}
+
+Status XGetWMName(Display *display,Window window,XTextProperty *text_property)
+{
+ char
+ *window_name;
+
+ if (XFetchName(display,window,&window_name) == 0)
+ return(False);
+ text_property->value=(unsigned char *) window_name;
+ text_property->encoding=XA_STRING;
+ text_property->format=8;
+ text_property->nitems=strlen(window_name);
+ return(True);
+}
+
+char *XResourceManagerString(Display *display)
+{
+ return(display->xdefaults);
+}
+
+void XrmDestroyDatabase(XrmDatabase database)
+{
+}
+
+void XSetWMIconName(Display *display,Window window,XTextProperty *property)
+{
+ XSetIconName(display,window,property->value);
+}
+
+void XSetWMName(Display *display,Window window,XTextProperty *property)
+{
+ XStoreName(display,window,property->value);
+}
+
+void XSetWMProperties(Display *display,Window window,
+ XTextProperty *window_name,XTextProperty *icon_name,char **argv,
+ int argc,XSizeHints *size_hints,XWMHints *manager_hints,
+ XClassHint *class_hint)
+{
+ XSetStandardProperties(display,window,window_name->value,icon_name->value,
+ None,argv,argc,size_hints);
+ XSetWMHints(display,window,manager_hints);
+ XSetClassHint(display,window,class_hint);
+}
+
+Status XSetWMProtocols(Display *display,Window window,Atom *protocols,
+ int count)
+{
+ Atom
+ wm_protocols;
+
+ wm_protocols=XInternAtom(display,"WM_PROTOCOLS",False);
+ XChangeProperty(display,window,wm_protocols,XA_ATOM,32,PropModeReplace,
+ (unsigned char *) protocols,count);
+ return(True);
+}
+
+int XStringListToTextProperty(char **argv,int argc,XTextProperty *property)
+{
+ register int
+ i;
+
+ register unsigned int
+ number_bytes;
+
+ XTextProperty
+ protocol;
+
+ number_bytes=0;
+ for (i=0; i < argc; i++)
+ number_bytes+=(unsigned int) ((argv[i] ? strlen(argv[i]) : 0)+1);
+ protocol.encoding=XA_STRING;
+ protocol.format=8;
+ protocol.nitems=0;
+ if (number_bytes)
+ protocol.nitems=number_bytes-1;
+ protocol.value=NULL;
+ if (number_bytes <= 0)
+ {
+ protocol.value=MagickAllocateMemory(unsigned char *,1);
+ if (!protocol.value)
+ return(False);
+ *protocol.value='\0';
+ }
+ else
+ {
+ register char
+ *buffer;
+
+ buffer=MagickAllocateMemory(char *,number_bytes);
+ if (buffer == (char *) NULL)
+ return(False);
+ protocol.value=(unsigned char *) buffer;
+ for (i=0; i < argc; i++)
+ {
+ char
+ *argument;
+
+ argument=argv[i];
+ if (!argument)
+ *buffer++='\0';
+ else
+ {
+ (void) strlcpy(buffer,argument,MaxTextExtent);
+ buffer+=(strlen(argument)+1);
+ }
+ }
+ }
+ *property=protocol;
+ return(True);
+}
+
+VisualID XVisualIDFromVisual(Visual *visual)
+{
+ return(visual->visualid);
+}
+
+Status XWithdrawWindow(Display *display,Window window,int screen)
+{
+ return(XUnmapWindow(display,window));
+}
+
+int XWMGeometry(Display *display,int screen,char *user_geometry,
+ char *default_geometry,unsigned int border_width,XSizeHints *size_hints,
+ int *x,int *y,int *width,int *height,int *gravity)
+{
+ int
+ status;
+
+ status=XGeometry(display,screen,user_geometry,default_geometry,border_width,
+ 0,0,0,0,x,y,width,height);
+ *gravity=NorthWestGravity;
+ return(status);
+}
+#endif
+
+#endif
diff --git a/magick/PreRvIcccm.h b/magick/PreRvIcccm.h
new file mode 100644
index 0000000..3852fba
--- /dev/null
+++ b/magick/PreRvIcccm.h
@@ -0,0 +1,127 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick X11 compatibility methods.
+*/
+#ifndef _MAGICK_PRER5ICCCM_H
+#define _MAGICK_PRER5ICCCM_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if defined(PRE_R6_ICCCM)
+/*
+ Compatability defines for pre X11R6 ICCCM.
+*/
+#define XK_KP_Home 0xFF95
+#define XK_KP_Left 0xFF96
+#define XK_KP_Up 0xFF97
+#define XK_KP_Right 0xFF98
+#define XK_KP_Down 0xFF99
+#define XK_KP_Prior 0xFF9A
+#define XK_KP_Page_Up 0xFF9A
+#define XK_KP_Next 0xFF9B
+#define XK_KP_Page_Down 0xFF9B
+#define XK_KP_End 0xFF9C
+#define XK_KP_Delete 0xFF9F
+
+extern MagickExport Status
+ XInitImage(XImage *ximage);
+#endif
+
+#if defined(PRE_R5_ICCCM)
+/*
+ Compatability defines for pre X11R5 ICCCM.
+*/
+extern MagickExport XrmDatabase
+ XrmGetDatabase();
+#endif
+
+#if defined(PRE_R4_ICCCM)
+/*
+ Compatability defines for pre X11R4 ICCCM.
+*/
+
+#define WithdrawnState 0
+#define XInductColormap(display,colormap) XInstallColormap(display,colormap)
+#define XUninductColormap(display,colormap) XUninstallColormap(display,colormap)
+
+typedef struct _XTextProperty
+{
+ unsigned char
+ *value;
+
+ Atom
+ encoding;
+
+ int
+ format;
+
+ unsigned long
+ nitems;
+} XTextProperty;
+
+/*
+ Pre R4 ICCCM compatibility routines.
+*/
+char
+ *XResourceManagerString();
+
+extern MagickExport int
+ XWMGeometry();
+
+extern MagickExport Status
+ XGetRGBColormaps(),
+ XGetWMName(),
+ XReconfigureWMWindow(),
+ XSetWMProtocols(),
+ XWithdrawWindow();
+
+extern MagickExport XClassHint
+ *XAllocClassHint();
+
+extern MagickExport XIconSize
+ *XAllocIconSize();
+
+extern MagickExport XSizeHints
+ *XAllocSizeHints();
+
+extern MagickExport XStandardColormap
+ *XAllocStandardColormap();
+
+extern MagickExport XWMHints
+ *XAllocWMHints();
+
+extern MagickExport VisualID
+ XVisualIDFromVisual();
+
+extern MagickExport void
+ XrmDestroyDatabase(),
+ XSetWMIconName(),
+ XSetWMName(),
+ XSetWMProperties();
+#else
+#define XInductColormap(display,colormap)
+#define XUninductColormap(display,colormap)
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/alpha_composite.h b/magick/alpha_composite.h
new file mode 100644
index 0000000..d58f7ef
--- /dev/null
+++ b/magick/alpha_composite.h
@@ -0,0 +1,171 @@
+/*
+ Copyright (C) 2003, 2005, 2008, 2013 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Alpha Composite Methods.
+*/
+#ifndef _MAGICK_ALPHA_COMPOSITE_H
+#define _MAGICK_ALPHA_COMPOSITE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+static inline magick_uint32_t BlendQuantumOpacity(magick_uint32_t q,
+ const magick_uint32_t opacity)
+{
+ magick_uint32_t
+ result = 0U;
+
+ if (opacity != 0U)
+ {
+#if QuantumDepth > 16
+ result = ((magick_uint64_t) opacity*q)/MaxRGB;
+#else
+ result = ((magick_uint32_t) opacity*q)/MaxRGB;
+#endif
+ }
+ return result;
+}
+
+static inline void BlendCompositePixel(PixelPacket *composite,
+ const PixelPacket *p,
+ const PixelPacket *q,
+ const double alpha)
+{
+ double
+ color,
+ opacity;
+
+ if (q->opacity == TransparentOpacity)
+ {
+ composite->red=p->red;
+ composite->green=p->green;
+ composite->blue=p->blue;
+ }
+ else if (p->opacity == TransparentOpacity)
+ {
+ composite->red=q->red;
+ composite->green=q->green;
+ composite->blue=q->blue;
+ }
+ else
+ {
+ color=((double) p->red*(MaxRGBDouble-alpha)+q->red*alpha)/MaxRGBDouble;
+ composite->red=RoundDoubleToQuantum(color);
+
+ color=((double) p->green*(MaxRGBDouble-alpha)+q->green*alpha)/MaxRGBDouble;
+ composite->green=RoundDoubleToQuantum(color);
+
+ color=((double) p->blue*(MaxRGBDouble-alpha)+q->blue*alpha)/MaxRGBDouble;
+ composite->blue=RoundDoubleToQuantum(color);
+ }
+
+ opacity=((double) p->opacity*(MaxRGBDouble-alpha)+q->opacity*alpha)/MaxRGBDouble;
+ composite->opacity=RoundDoubleToQuantum(opacity);
+}
+
+/*
+ Alpha compose pixel 'change' over pixel 'source'.
+
+ The result will be the union of the two image shapes, with
+ opaque areas of change-image obscuring base-image in the
+ region of overlap.
+*/
+#define MagickAlphaCompositeQuantum(change,change_alpha,base,base_alpha) \
+ (1.0-(change_alpha/MaxRGBDouble))*(double) change+(1.0-(base_alpha/MaxRGBDouble))*(double) base*(change_alpha/MaxRGBDouble)
+
+static inline void AlphaCompositePixel(PixelPacket *composite, const PixelPacket *change,
+ const double change_alpha,const PixelPacket *base,
+ const double base_alpha)
+{
+ if (change_alpha == (double) TransparentOpacity)
+ {
+ if (composite != base)
+ *composite=*base;
+ }
+ else
+ {
+ double
+ delta,
+ value;
+
+ delta=1.0-(change_alpha/MaxRGBDouble)*(base_alpha/MaxRGBDouble);
+
+ value=MaxRGBDouble*(1.0-delta);
+ composite->opacity=RoundDoubleToQuantum(value);
+
+ delta=1.0/(delta <= MagickEpsilon ? 1.0 : delta);
+
+ value=delta*MagickAlphaCompositeQuantum(change->red,change_alpha,base->red,base_alpha);
+ composite->red=RoundDoubleToQuantum(value);
+
+ value=delta*MagickAlphaCompositeQuantum(change->green,change_alpha,base->green,base_alpha);
+ composite->green=RoundDoubleToQuantum(value);
+
+ value=delta*MagickAlphaCompositeQuantum(change->blue,change_alpha,base->blue,base_alpha);
+ composite->blue=RoundDoubleToQuantum(value);
+ }
+}
+
+/*
+ The result is the same shape as base-image, with change-image
+ obscuring base-image where the image shapes overlap. Note this
+ differs from over because the portion of change-image outside
+ base-image's shape does not appear in the result.
+*/
+static inline void AtopCompositePixel(PixelPacket *composite,
+ const PixelPacket *base,
+ const PixelPacket *change)
+{
+ double
+ color,
+ opacity;
+
+ opacity=((double)(MaxRGBDouble-change->opacity)*
+ (MaxRGBDouble-base->opacity)+(double) change->opacity*
+ (MaxRGBDouble-base->opacity))/MaxRGBDouble;
+
+ color=((double) (MaxRGBDouble-change->opacity)*
+ (MaxRGBDouble-base->opacity)*change->red/MaxRGBDouble+(double)
+ change->opacity*(MaxRGBDouble-base->opacity)*
+ base->red/MaxRGBDouble)/opacity;
+ composite->red=RoundDoubleToQuantum(color);
+
+ color=((double) (MaxRGBDouble-change->opacity)*
+ (MaxRGBDouble-base->opacity)*change->green/MaxRGBDouble+(double)
+ change->opacity*(MaxRGBDouble-base->opacity)*
+ base->green/MaxRGBDouble)/opacity;
+ composite->green=RoundDoubleToQuantum(color);
+
+ color=((double) (MaxRGBDouble-change->opacity)*
+ (MaxRGBDouble-base->opacity)*change->blue/MaxRGBDouble+(double)
+ change->opacity*(MaxRGBDouble-base->opacity)*
+ base->blue/MaxRGBDouble)/opacity;
+ composite->blue=RoundDoubleToQuantum(color);
+
+ composite->opacity=MaxRGB-RoundDoubleToQuantum(opacity);
+}
+
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_ALPHA_COMPOSITE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/analyze.c b/magick/analyze.c
new file mode 100644
index 0000000..6c4c489
--- /dev/null
+++ b/magick/analyze.c
@@ -0,0 +1,1010 @@
+/*
+% Copyright (C) 2003 - 2009 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% GraphicsMagick Image Analysis Methods
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/color.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/utility.h"
+
+/*
+ Constant declaration.
+*/
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t I m a g e B o u n d i n g B o x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetImageBoundingBox returns the bounding box of an image canvas.
+% If the image has an opacity channel then return a bounding box based
+% only on the opacity channel, otherwise return the bounding box of the
+% image based on the current image fuzz setting.
+%
+% The format of the GetImageBoundingBox method is:
+%
+% RectangleInfo GetImageBoundingBox(const Image *image,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o bounds: Method GetImageBoundingBox returns the bounding box of an
+% image canvas.
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define GetImageBoundingBoxText "[%s] Get bounding box..."
+MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
+ ExceptionInfo *exception)
+{
+ MagickPassFail
+ status=MagickPass;
+
+ long
+ y;
+
+ unsigned long
+ row_count=0;
+
+ PixelPacket
+ corners[3];
+
+ RectangleInfo
+ bounds;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ bounds.width=0;
+ bounds.height=0;
+ bounds.x=(long) image->columns;
+ bounds.y=(long) image->rows;
+
+ (void) AcquireOnePixelByReference(image,&corners[0],0,0,exception);
+ (void) AcquireOnePixelByReference(image,&corners[1],(long) image->columns-1,0,exception);
+ (void) AcquireOnePixelByReference(image,&corners[2],0,(long) image->rows-1,exception);
+#if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register const PixelPacket
+ * restrict p;
+
+ register long
+ x;
+
+ RectangleInfo
+ thread_bounds;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageBoundingBox)
+#endif
+ {
+ thread_status=status;
+ thread_bounds=bounds;
+ }
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ if ((image->matte) &&
+ (corners[0].opacity != OpaqueOpacity) &&
+ (corners[0].opacity == corners[1].opacity) &&
+ (corners[1].opacity == corners[2].opacity))
+ /*
+ Consider only the opacity channel. Not currently fuzzy
+ so only applied for simple transparency.
+ */
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (p->opacity != corners[0].opacity)
+ if (x < thread_bounds.x)
+ thread_bounds.x=x;
+ if (p->opacity != corners[1].opacity)
+ if (x > (long) thread_bounds.width)
+ thread_bounds.width=x;
+ if (p->opacity != corners[0].opacity)
+ if (y < thread_bounds.y)
+ thread_bounds.y=y;
+ if (p->opacity != corners[2].opacity)
+ if (y > (long) thread_bounds.height)
+ thread_bounds.height=y;
+ p++;
+ }
+ else if (image->fuzz <= MagickEpsilon)
+ {
+ /*
+ Consider only the RGB channels using absolute comparison
+ */
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (!ColorMatch(p,&corners[0]))
+ if (x < thread_bounds.x)
+ thread_bounds.x=x;
+ if (!ColorMatch(p,&corners[1]))
+ if (x > (long) thread_bounds.width)
+ thread_bounds.width=x;
+ if (!ColorMatch(p,&corners[0]))
+ if (y < thread_bounds.y)
+ thread_bounds.y=y;
+ if (!ColorMatch(p,&corners[2]))
+ if (y > (long) thread_bounds.height)
+ thread_bounds.height=y;
+ p++;
+ }
+ }
+ else
+ /*
+ Consider only the RGB channels using fuzzy comparison
+ */
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (!FuzzyColorMatch(p,&corners[0],image->fuzz))
+ if (x < thread_bounds.x)
+ thread_bounds.x=x;
+ if (!FuzzyColorMatch(p,&corners[1],image->fuzz))
+ if (x > (long) thread_bounds.width)
+ thread_bounds.width=x;
+ if (!FuzzyColorMatch(p,&corners[0],image->fuzz))
+ if (y < thread_bounds.y)
+ thread_bounds.y=y;
+ if (!FuzzyColorMatch(p,&corners[2],image->fuzz))
+ if (y > (long) thread_bounds.height)
+ thread_bounds.height=y;
+ p++;
+ }
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageBoundingBox)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ GetImageBoundingBoxText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_bounds.x < bounds.x)
+ bounds.x=thread_bounds.x;
+ if (thread_bounds.y < bounds.y)
+ bounds.y=thread_bounds.y;
+ if (thread_bounds.width > bounds.width)
+ bounds.width=thread_bounds.width;
+ if (thread_bounds.height > bounds.height)
+ bounds.height=thread_bounds.height;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ if ((bounds.width != 0) || (bounds.height != 0))
+ {
+ bounds.width-=(bounds.x-1);
+ bounds.height-=(bounds.y-1);
+ }
+ if (bounds.x < 0)
+ bounds.x=0;
+ if (bounds.y < 0)
+ bounds.y=0;
+ /*
+ If we fail to find smaller bounds, then return original image
+ dimensions.
+ */
+ if ((bounds.width == 0) || (bounds.height == 0))
+ {
+ bounds.width=image->columns;
+ bounds.height=image->rows;
+ bounds.x=0;
+ bounds.y=0;
+ }
+
+ return(bounds);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageDepth() returns the minimum bit depth of the image required to
+% ensure that data is not lost in the red, green, blue, and opacity, channels.
+% Pixel components are stored in a Quantum, which is 8, 16, or 32 bits
+% depending on the QuantumDepth value set when the software is compiled.
+% GetImageDepth() returns the smallest modulus storage size which supports
+% the scale of the pixel within the range (i.e. no information is lost).
+% As an example, the value one is returned for a black and white image
+% since only one bit of resolution is required to represent a black and white
+% image.
+%
+% The format of the GetImageDepth method is:
+%
+% unsigned long GetImageDepth(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static inline unsigned char MinimumDepthForValue(const Quantum quantum)
+{
+ register unsigned int
+ depth,
+ scale;
+
+ for (depth=1 ; depth < MaxRGB; depth++)
+ {
+ scale=MaxRGB / (MaxRGB >> (QuantumDepth-depth));
+ if (quantum == scale*(quantum/scale))
+ break;
+ }
+
+ return depth;
+}
+#if MaxMap == MaxRGB
+static magick_uint8_t* AllocateDepthMap(void)
+{
+ magick_uint8_t
+ *map;
+
+ map = MagickAllocateArray(unsigned char *, MaxMap+1, sizeof(magick_uint8_t));
+ if (map != (unsigned char *) NULL)
+ {
+ unsigned int
+ i;
+
+ for (i=0; i <= MaxMap; i++)
+ map[i] = (magick_uint8_t) MinimumDepthForValue(i);
+ }
+ return map;
+}
+#endif /* MaxMap == MaxRGB */
+#define GetImageDepthText "[%s] Get depth..."
+
+static MagickPassFail
+GetImageDepthCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *image, /* Input image */
+ const PixelPacket *pixels, /* Pixel row */
+ const IndexPacket *indexes, /* Pixel indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ unsigned int
+ *current_depth=(unsigned int *) mutable_data;
+
+ magick_uint8_t
+ *map = (magick_uint8_t *) immutable_data;
+
+ register unsigned int
+ depth;
+
+ register long
+ i;
+
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageDepthCallBack)
+#endif
+ {
+ depth=*current_depth;
+ }
+
+#if MaxMap == MaxRGB
+ if (map)
+ {
+ /*
+ Use fast table lookups if we can
+ */
+ for (i=0; i < npixels; i++)
+ {
+ depth=Max(depth,map[pixels[i].red]);
+ depth=Max(depth,map[pixels[i].green]);
+ depth=Max(depth,map[pixels[i].blue]);
+ if (image->matte)
+ depth=Max(depth,map[pixels[i].opacity]);
+ if (depth == QuantumDepth)
+ break;
+ }
+ }
+#else
+ {
+ /*
+ Use the slow, sure, way (Q32 only)
+ */
+ register unsigned int
+ scale;
+
+ ARG_NOT_USED(map);
+ scale=MaxRGB / (MaxRGB >> (QuantumDepth-depth));
+ i=0;
+ while (i < npixels)
+ {
+ if ((pixels[i].red != scale*(pixels[i].red/scale)) ||
+ (pixels[i].green != scale*(pixels[i].green/scale)) ||
+ (pixels[i].blue != scale*(pixels[i].blue/scale)) ||
+ (image->matte &&
+ (pixels[i].opacity != scale*((pixels[i].opacity/scale)))))
+ {
+ depth++;
+ if (depth == QuantumDepth)
+ break;
+ scale=MaxRGB / (MaxRGB >> (QuantumDepth-depth));
+ continue;
+ }
+ i++;
+ }
+ }
+#endif
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageDepthCallBack)
+#endif
+ {
+ if (depth > *current_depth)
+ *current_depth=depth;
+ }
+
+ return (depth >= QuantumDepth ? MagickFail : MagickPass);
+}
+
+MagickExport unsigned long GetImageDepth(const Image *image,
+ ExceptionInfo *exception)
+{
+ magick_uint8_t
+ *map = (magick_uint8_t *) NULL;
+
+ unsigned int
+ depth=1;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (image->is_monochrome)
+ return depth;
+
+#if MaxMap == MaxRGB
+ /*
+ Use fast table lookups if we can
+ */
+ map = AllocateDepthMap();
+#endif
+ if ((image->storage_class == PseudoClass) && !(image->matte))
+ {
+ /*
+ PseudoClass
+ */
+ (void) GetImageDepthCallBack(&depth,map,image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ exception);
+ }
+ else
+ {
+ /*
+ DirectClass.
+
+ Notice that all pixels in the image must be inspected if the
+ image depth is less than QuantumDepth.
+ */
+
+ (void) PixelIterateMonoRead(GetImageDepthCallBack,
+ NULL,
+ GetImageDepthText,
+ &depth,map,0,0,image->columns,
+ image->rows,image,exception);
+ }
+
+ MagickFreeMemory(map);
+
+ return depth;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e C h a r a c t e r i s t i c s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageCharacteristics obtains the basic characteristics of the image
+% and stores the characterisistics in the user provided
+% ImageCharacteristics structure. If optimize is set to MagickTrue, then
+% exhaustive testing of the image pixels is performed (as required).
+% MagickPass is returned if this method executes without error.
+%
+% The format of the GetImageCharacteristics method is:
+%
+% MagickPassFail GetImageCharacteristics(const Image *image,
+% ImageCharacteristics *characteristics,
+% MagickBool optimize,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o characteristics: An ImageCharacteristics structure to update.
+%
+% o optimize: Inspect image pixels (if required)
+%
+% o exception: Any errors are reported here.
+%
+*/
+#define AnalyzeImageText "[%s] Analyze... "
+MagickExport MagickPassFail GetImageCharacteristics(const Image *image,
+ ImageCharacteristics *characteristics,
+ const MagickBool optimize,
+ ExceptionInfo *exception)
+{
+ unsigned long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned long
+ x;
+
+ MagickBool
+ broke_loop = MagickFalse;
+
+ MagickPassFail
+ status = MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(characteristics != (ImageCharacteristics *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ characteristics->cmyk = (image->colorspace == CMYKColorspace ? MagickTrue : MagickFalse);
+ characteristics->grayscale = (image->is_grayscale ? MagickTrue : MagickFalse);
+ characteristics->monochrome = (image->is_monochrome ? MagickTrue : MagickFalse);
+ characteristics->opaque = (image->matte ? MagickFalse : MagickTrue);
+ characteristics->palette = (image->storage_class == PseudoClass ? MagickTrue : MagickFalse);
+
+ if ((optimize) && (GetPixelCachePresent(image)))
+ {
+ MagickBool
+ grayscale,
+ monochrome,
+ opaque;
+
+ /* Predicate to test */
+ grayscale=(image->is_grayscale ? MagickFalse : MagickTrue);
+ monochrome=(image->is_monochrome ? MagickFalse : MagickTrue);
+ opaque=(image->matte ? MagickTrue : MagickFalse);
+ switch (image->storage_class)
+ {
+ case DirectClass:
+ case UndefinedClass:
+ {
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status = MagickFail;
+ break;
+ }
+ for (x=image->columns; x != 0; x--)
+ {
+ grayscale = ((grayscale) &&
+ (p->red == p->green) && (p->red == p->blue));
+ monochrome = ((monochrome) && (grayscale) &&
+ ((0 == p->red) || (MaxRGB == p->red)));
+ opaque = ((opaque) &&
+ (p->opacity == OpaqueOpacity));
+ if (!grayscale &&
+ !monochrome &&
+ !opaque)
+ {
+ broke_loop=MagickTrue;
+ break;
+ }
+ p++;
+ }
+ if (!grayscale &&
+ !monochrome &&
+ !opaque)
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ AnalyzeImageText,image->filename))
+ break;
+ }
+ break;
+ }
+ case PseudoClass:
+ {
+ p=image->colormap;
+ for (x=image->colors; x != 0; x--)
+ {
+ grayscale = ((grayscale) &&
+ (p->red == p->green) && (p->red == p->blue));
+ monochrome = ((monochrome) && (grayscale) &&
+ ((0 == p->red) || (MaxRGB == p->red)));
+ if (!grayscale &&
+ !monochrome)
+ {
+ broke_loop=MagickTrue;
+ break;
+ }
+ p++;
+ }
+ if (opaque)
+ {
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status = MagickFail;
+ break;
+ }
+ for (x=image->columns; x != 0; x--)
+ {
+ opaque = ((opaque) &&
+ (p->opacity == OpaqueOpacity));
+ if (!opaque)
+ {
+ broke_loop=MagickTrue;
+ break;
+ }
+ p++;
+ }
+ if (!opaque)
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ AnalyzeImageText,image->filename))
+ break;
+ }
+ }
+ break;
+ }
+ }
+ if (!characteristics->grayscale)
+ {
+ characteristics->grayscale=grayscale;
+ ((Image *)image)->is_grayscale=grayscale; /* Intentionally ignore const */
+ }
+ if (!characteristics->monochrome)
+ {
+ characteristics->monochrome=monochrome;
+ ((Image *)image)->is_monochrome=monochrome; /* Intentionally ignore const */
+ }
+ if (!characteristics->opaque)
+ characteristics->opaque=opaque;
+ }
+
+ /*
+ Force progress indication to 100%
+ */
+ if (broke_loop)
+ (void) MagickMonitorFormatted(image->rows-1,image->rows,exception,
+ AnalyzeImageText,image->filename);
+/* printf("status=%s, cmyk=%u, grayscale=%u, monochrome=%u, opaque=%u, palette=%u\n", */
+/* (status == MagickFail ? "Fail" : "Pass"),characteristics->cmyk,characteristics->grayscale, */
+/* characteristics->monochrome,characteristics->opaque,characteristics->palette); */
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e T y p e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageType() returns the type of image:
+%
+% Bilevel Grayscale GrayscaleMatte
+% Palette PaletteMatte TrueColor
+% TrueColorMatte ColorSeparation ColorSeparationMatte
+%
+%
+% The format of the GetImageType method is:
+%
+% ImageType GetImageType(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport ImageType
+GetImageType(const Image *image,ExceptionInfo *exception)
+{
+ ImageCharacteristics
+ characteristics;
+
+ ImageType
+ image_type;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ image_type=UndefinedType;
+ if (GetImageCharacteristics(image,&characteristics,MagickTrue,exception))
+ {
+ if (characteristics.cmyk)
+ image_type=(characteristics.opaque ? ColorSeparationType : ColorSeparationMatteType);
+ else if (characteristics.monochrome)
+ image_type=BilevelType;
+ else if (characteristics.grayscale)
+ image_type=(characteristics.opaque ? GrayscaleType : GrayscaleMatteType);
+ else if (characteristics.palette)
+ image_type=(characteristics.opaque ? PaletteType : PaletteMatteType);
+ else
+ image_type=(characteristics.opaque ? TrueColorType : TrueColorMatteType);
+ }
+ return image_type;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s G r a y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsGrayImage() returns MagickTrue if all the pixels in the image have the same
+% red, green, and blue intensities.
+%
+% The format of the IsGrayImage method is:
+%
+% MagickBool IsGrayImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsGrayImage returns MagickTrue if the image is grayscale
+% otherwise MagickFalse is returned.
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define AnalyzeGrayImageText "[%s] Analyze for gray..."
+MagickExport MagickBool IsGrayImage(const Image *image,
+ ExceptionInfo *exception)
+{
+ unsigned long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned long
+ x;
+
+ MagickBool
+ is_grayscale;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ if (image->colorspace == CMYKColorspace)
+ return(MagickFalse);
+ if (image->is_grayscale)
+ return(MagickTrue);
+ is_grayscale=MagickTrue;
+ switch (image->storage_class)
+ {
+ case DirectClass:
+ case UndefinedClass:
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "IsGrayImage(): Exhaustive pixel test!");
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ return(MagickFalse);
+ for (x=image->columns; x != 0; x--)
+ {
+ if ((p->red != p->green) || (p->green != p->blue))
+ {
+ is_grayscale=MagickFalse;
+ break;
+ }
+ p++;
+ }
+ if (!is_grayscale)
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,
+ exception,AnalyzeGrayImageText,
+ image->filename))
+ break;
+ }
+ break;
+ }
+ case PseudoClass:
+ {
+ p=image->colormap;
+ for (x=image->colors; x != 0; x--)
+ {
+ if ((p->red != p->green) || (p->green != p->blue))
+ {
+ is_grayscale=MagickFalse;
+ break;
+ }
+ p++;
+ }
+ break;
+ }
+ }
+
+ /*
+ Force progress indication to 100%
+ */
+ if (!is_grayscale)
+ (void) MagickMonitorFormatted(image->rows-1,image->rows,exception,
+ AnalyzeGrayImageText,image->filename);
+
+ ((Image *)image)->is_grayscale=is_grayscale;
+ return(is_grayscale);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M o n o c h r o m e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsMonochromeImage() returns MagickTrue if all the pixels in the image have
+% the same red, green, and blue intensities and the intensity is either
+% 0 or MaxRGB.
+%
+% The format of the IsMonochromeImage method is:
+%
+% MagickBool IsMonochromeImage(const Image *image,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define AnalyzeBilevelImageText "[%s] Analyze for bilevel..."
+MagickExport MagickBool IsMonochromeImage(const Image *image,
+ ExceptionInfo *exception)
+{
+ unsigned long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned long
+ x;
+
+ MagickBool
+ is_monochrome;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ if (image->colorspace == CMYKColorspace)
+ return(MagickFalse);
+ if (image->is_monochrome)
+ return(MagickTrue);
+ is_monochrome=MagickTrue;
+ switch (image->storage_class)
+ {
+ case DirectClass:
+ case UndefinedClass:
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "IsMonochromeImage(): Exhaustive pixel test!");
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ return(MagickFalse);
+ for (x=image->columns; x != 0; x--)
+ {
+ if ((p->red != p->green) || (p->green != p->blue) ||
+ ((p->red != 0) && (p->red != MaxRGB)))
+ {
+ is_monochrome=MagickFalse;
+ break;
+ }
+ p++;
+ }
+ if (!is_monochrome)
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ AnalyzeBilevelImageText,image->filename))
+ break;
+ }
+ break;
+ }
+ case PseudoClass:
+ {
+ p=image->colormap;
+ for (x=image->colors; x != 0; x--)
+ {
+ if ((p->red != p->green) || (p->green != p->blue) ||
+ ((p->red != 0) && (p->red != MaxRGB)))
+ {
+ is_monochrome=MagickFalse;
+ break;
+ }
+ p++;
+ }
+ break;
+ }
+ }
+
+ /*
+ Force progress indication to 100%
+ */
+ if (!is_monochrome)
+ (void) MagickMonitorFormatted(image->rows-1,image->rows,exception,
+ AnalyzeBilevelImageText,image->filename);
+
+ ((Image *)image)->is_monochrome=is_monochrome;
+ return(is_monochrome);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s O p a q u e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsOpaqueImage() returns MagickTrue if none of the pixels in the image have an
+% opacity value other than opaque (0).
+%
+% The format of the IsOpaqueImage method is:
+%
+% MagickBool IsOpaqueImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsOpaqueImage returns MagickFalse if the image has one or more
+% pixels that are transparent otherwise MagickTrue is returned.
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define AnalyzeOpaqueImageText "[%s] Analyze for opacity..."
+MagickExport MagickBool IsOpaqueImage(const Image *image,
+ ExceptionInfo *exception)
+{
+ unsigned long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned long
+ x;
+
+ MagickBool
+ is_opaque;
+
+ /*
+ Determine if image is opaque.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (!image->matte)
+ return(MagickTrue);
+ is_opaque=MagickTrue;
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "IsOpaqueImage(): Exhaustive pixel test!");
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ return(MagickFalse);
+ for (x=image->columns; x > 0; x--)
+ {
+ if (p->opacity != OpaqueOpacity)
+ {
+ is_opaque=MagickFalse;
+ break;
+ }
+ p++;
+ }
+ if (!is_opaque)
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ AnalyzeOpaqueImageText,image->filename))
+ break;
+ }
+
+ /*
+ Force progress indication to 100%
+ */
+ if (!is_opaque)
+ (void) MagickMonitorFormatted(image->rows-1,image->rows,exception,
+ AnalyzeOpaqueImageText,image->filename);
+
+ return(is_opaque);
+}
diff --git a/magick/analyze.h b/magick/analyze.h
new file mode 100644
index 0000000..5530a87
--- /dev/null
+++ b/magick/analyze.h
@@ -0,0 +1,66 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Image Analysis Methods.
+*/
+#ifndef _MAGICK_ANALYZE_H
+#define _MAGICK_ANALYZE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#include "magick/image.h"
+
+typedef struct _ImageCharacteristics
+{
+ MagickBool
+ cmyk, /* CMYK(A) image */
+ grayscale, /* Grayscale image */
+ monochrome, /* Black/white image */
+ opaque, /* Opaque image */
+ palette; /* Colormapped image */
+} ImageCharacteristics;
+
+/* Functions which return unsigned int to indicate operation pass/fail */
+extern MagickExport MagickPassFail
+ GetImageCharacteristics(const Image *image,ImageCharacteristics *characteristics,
+ const MagickBool optimize,ExceptionInfo *exception);
+
+extern MagickExport unsigned long
+ GetImageDepth(const Image *,ExceptionInfo *);
+
+extern MagickExport MagickBool
+ IsGrayImage(const Image *image,ExceptionInfo *exception),
+ IsMonochromeImage(const Image *image,ExceptionInfo *exception),
+ IsOpaqueImage(const Image *image,ExceptionInfo *exception);
+
+extern MagickExport ImageType
+ GetImageType(const Image *,ExceptionInfo *);
+
+extern MagickExport RectangleInfo
+ GetImageBoundingBox(const Image *,ExceptionInfo *exception);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_ANALYZE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/animate.c b/magick/animate.c
new file mode 100644
index 0000000..b290931
--- /dev/null
+++ b/magick/animate.c
@@ -0,0 +1,2580 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% AAA N N IIIII M M AAA TTTTT EEEEE %
+% A A NN N I MM MM A A T E %
+% AAAAA N N N I M M M AAAAA T EEE %
+% A A N NN I M M A A T E %
+% A A N N IIIII M M A A T EEEEE %
+% %
+% %
+% Methods to Interactively Animate an Image Sequence %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/color.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#include "magick/xwindow.h"
+#if defined(HasX11)
+#include "magick/animate.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X M a g i c k C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMagickCommand makes a transform to the image or Image window as
+% specified by a user menu button or keyboard command.
+%
+% The format of the MagickXMagickCommand method is:
+%
+% Image *MagickXMagickCommand(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,const CommandType command_type,Image **image,
+% unsigned int *state)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; MagickXMagickCommand
+% may transform the image and return a new image pointer.
+%
+% o state: Specifies an unsigned int; MagickXMagickCommand may return a
+% modified state.
+%
+%
+*/
+static Image *MagickXMagickCommand(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,const CommandType command_type,Image **image,
+ unsigned int *state)
+{
+ Image
+ *nexus;
+
+ int
+ status;
+
+ XTextProperty
+ window_name;
+
+ /*
+ Process user command.
+ */
+ nexus=(Image *) NULL;
+ switch (command_type)
+ {
+ case OpenCommand:
+ {
+ char
+ **filelist;
+
+ ExceptionInfo
+ exception;
+
+ Image
+ *image,
+ *next;
+
+ ImageInfo
+ *clone_info;
+
+ int
+ number_files;
+
+ MonitorHandler
+ handler;
+
+ register int
+ i;
+
+ static char
+ filenames[MaxTextExtent] = "*";
+
+ unsigned int
+ status;
+
+ if (resource_info->immutable)
+ break;
+ /*
+ Request file name from user.
+ */
+ MagickXFileBrowserWidget(display,windows,"Animate",filenames);
+ if (*filenames == '\0')
+ return((Image *) NULL);
+ /*
+ Expand the filenames.
+ */
+ filelist=MagickAllocateMemory(char **,sizeof(char *));
+ if (filelist == (char **) NULL)
+ {
+ MagickError(ResourceLimitError,MemoryAllocationFailed,filenames);
+ return((Image *) NULL);
+ }
+ number_files=1;
+ filelist[0]=filenames;
+ status=ExpandFilenames(&number_files,&filelist);
+ if ((status == False) || (number_files == 0))
+ {
+ if (number_files == 0)
+ MagickError(ImageError,NoImagesWereLoaded,filenames);
+ else
+ MagickError(ResourceLimitError,MemoryAllocationFailed,filenames);
+ return((Image *) NULL);
+ }
+ clone_info=CloneImageInfo(resource_info->image_info);
+ if (clone_info == (ImageInfo *) NULL)
+ break;
+ GetExceptionInfo(&exception);
+ image=(Image *) NULL;
+ handler=(MonitorHandler) NULL;
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ for (i=0; i < number_files; i++)
+ {
+ if (number_files > 5)
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ (void) strlcpy(clone_info->filename,filelist[i],MaxTextExtent);
+ *clone_info->magick='\0';
+ next=ReadImage(clone_info,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (next != (Image *) NULL)
+ {
+ if (image == (Image *) NULL)
+ image=next;
+ else
+ {
+ image->next=next;
+ image->next->previous=image;
+ image=image->next;
+ }
+ }
+ if (number_files <= 5)
+ continue;
+ (void) SetMonitorHandler(handler);
+ if (!MagickMonitorFormatted(i,number_files,&image->exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+ DestroyExceptionInfo(&exception);
+ DestroyImageInfo(clone_info);
+ if (image == (Image *) NULL)
+ {
+ MagickXSetCursorState(display,windows,False);
+ MagickError(ImageError,NoImagesWereLoaded,filenames);
+ return((Image *) NULL);
+ }
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ nexus=image;
+ *state|=ExitState;
+ break;
+ }
+ case PlayCommand:
+ {
+ char
+ basename[MaxTextExtent];
+
+ /*
+ Window name is the base of the filename.
+ */
+ *state|=PlayAnimationState;
+ *state&=(~AutoReverseAnimationState);
+ GetPathComponent((*image)->filename,BasePath,basename);
+ FormatString(windows->image.name,"GraphicsMagick: %.1024s",basename);
+ if (resource_info->title != (char *) NULL)
+ windows->image.name=TranslateText(resource_info->image_info,*image,
+ resource_info->title);
+ status=XStringListToTextProperty(&windows->image.name,1,&window_name);
+ if (status == 0)
+ break;
+ XSetWMName(display,windows->image.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ break;
+ }
+ case StepCommand:
+ case StepBackwardCommand:
+ case StepForwardCommand:
+ {
+ *state|=StepAnimationState;
+ *state&=(~PlayAnimationState);
+ if (command_type == StepBackwardCommand)
+ *state&=(~ForwardAnimationState);
+ if (command_type == StepForwardCommand)
+ *state|=ForwardAnimationState;
+ /* if (resource_info->title != (char *) NULL) */
+ /* break; */
+ break;
+ }
+ case RepeatCommand:
+ {
+ *state|=RepeatAnimationState;
+ *state&=(~AutoReverseAnimationState);
+ *state|=PlayAnimationState;
+ break;
+ }
+ case AutoReverseCommand:
+ {
+ *state|=AutoReverseAnimationState;
+ *state&=(~RepeatAnimationState);
+ *state|=PlayAnimationState;
+ break;
+ }
+ case SlowerCommand:
+ {
+ resource_info->delay++;
+ break;
+ }
+ case FasterCommand:
+ {
+ if (resource_info->delay == 0)
+ break;
+ resource_info->delay--;
+ break;
+ }
+ case ForwardCommand:
+ {
+ *state=ForwardAnimationState;
+ *state&=(~AutoReverseAnimationState);
+ break;
+ }
+ case ReverseCommand:
+ {
+ *state&=(~ForwardAnimationState);
+ *state&=(~AutoReverseAnimationState);
+ break;
+ }
+ case InfoCommand:
+ {
+ MagickXDisplayImageInfo(display,resource_info,windows,(Image *) NULL,*image);
+ break;
+ }
+ case HelpCommand:
+ {
+ /*
+ User requested help.
+ */
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Animate",AnimateHelp);
+ break;
+ }
+ case BrowseDocumentationCommand:
+ {
+ Atom
+ mozilla_atom;
+
+ Window
+ mozilla_window,
+ root_window;
+
+ /*
+ Browse the GraphicsMagick documentation.
+ */
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ mozilla_atom=XInternAtom(display,"_MOZILLA_VERSION",False);
+ mozilla_window=MagickXWindowByProperty(display,root_window,mozilla_atom);
+ if (mozilla_window != (Window) NULL)
+ {
+ char
+ command[MaxTextExtent];
+
+ /*
+ Display documentation using Netscape remote control.
+ */
+ FormatString(command,"openURL(%.1024s,new-window,noraise)",
+ "http://www.graphicsmagick.org/");
+ mozilla_atom=XInternAtom(display,"_MOZILLA_COMMAND",False);
+ (void) XChangeProperty(display,mozilla_window,mozilla_atom,
+ XA_STRING,8,PropModeReplace,(unsigned char *) command,
+ (int) strlen(command));
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ status=InvokeDelegate(resource_info->image_info,*image,"browse",
+ (char *) NULL,&(*image)->exception);
+ if (status == False)
+ MagickXNoticeWidget(display,windows,"Unable to browse documentation",
+ (char *) NULL);
+ MagickXDelay(display,1500);
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ case VersionCommand:
+ {
+ MagickXNoticeWidget(display,windows,GetMagickVersion((unsigned long *) NULL),
+ GetMagickCopyright());
+ break;
+ }
+ case QuitCommand:
+ {
+ /*
+ Exit program
+ */
+ if (!resource_info->confirm_exit)
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_exit,CurrentTime);
+ else
+ {
+ /*
+ Confirm program exit.
+ */
+ status=MagickXConfirmWidget(display,windows,"Do you really want to exit",
+ resource_info->client_name);
+ if (status > 0)
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_exit,CurrentTime);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return(nexus);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X A n i m a t e B a c k g r o u n d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXAnimateBackgroundImage() animates an image sequence in the background of
+% a window.
+%
+% The format of the MagickXAnimateBackgroundImage method is:
+%
+% void MagickXAnimateBackgroundImage(Display *display,
+% MagickXResourceInfo *resource_info,Image *images)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o images: The image list.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int SceneCompare(const void *x,const void *y)
+{
+ Image
+ **image_1,
+ **image_2;
+
+ image_1=(Image **) x;
+ image_2=(Image **) y;
+ return((int) ((*image_1)->scene-(*image_2)->scene));
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+MagickExport void MagickXAnimateBackgroundImage(Display *display,
+ MagickXResourceInfo *resource_info,Image *images)
+{
+ char
+ geometry[MaxTextExtent],
+ visual_type[MaxTextExtent];
+
+ long
+ x,
+ y;
+
+ static MagickXPixelInfo
+ pixel;
+
+ static XStandardColormap
+ *map_info;
+
+ static XVisualInfo
+ *visual_info = (XVisualInfo *) NULL;
+
+ static MagickXWindowInfo
+ window_info;
+
+ Image
+ *display_image,
+ **image_list;
+
+ int
+ scene;
+
+ register long
+ i;
+
+ size_t
+ number_scenes;
+
+ unsigned int
+ coalesce,
+ status;
+
+ unsigned int
+ height,
+ width;
+
+ Window
+ root_window;
+
+ XEvent
+ event;
+
+ XGCValues
+ context_values;
+
+ MagickXPixelInfo
+ scene_info;
+
+ MagickXResourceInfo
+ resources;
+
+ XWindowAttributes
+ window_attributes;
+
+ /*
+ Determine target window.
+ */
+ assert(images != (Image *) NULL);
+ assert(images->signature == MagickSignature);
+ resources=(*resource_info);
+ window_info.id=(Window) NULL;
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ if (LocaleCompare(resources.window_id,"root") == 0)
+ window_info.id=root_window;
+ else
+ {
+ if (isdigit((int) (*resources.window_id)))
+ window_info.id=MagickXWindowByID(display,root_window,
+ (Window) strtol((char *) resources.window_id,(char **) NULL,0));
+ if (window_info.id == (Window) NULL)
+ window_info.id=
+ MagickXWindowByName(display,root_window,resources.window_id);
+ }
+ if (window_info.id == (Window) NULL)
+ {
+ MagickError(XServerError,NoWindowWithSpecifiedIDExists,
+ resources.window_id);
+ return;
+ }
+ /*
+ Determine window visual id.
+ */
+ window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
+ window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
+ (void) strcpy(visual_type,"default");
+ status=XGetWindowAttributes(display,window_info.id,&window_attributes);
+ if (status != False)
+ FormatString(visual_type,"0x%lx",
+ XVisualIDFromVisual(window_attributes.visual));
+ if (visual_info == (XVisualInfo *) NULL)
+ {
+ /*
+ Allocate standard colormap.
+ */
+ map_info=XAllocStandardColormap();
+ if (map_info == (XStandardColormap *) NULL)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(XServerFatalError,UnableToCreateStandardColormap));
+ map_info->colormap=(Colormap) NULL;
+ pixel.pixels=(unsigned long *) NULL;
+ /*
+ Initialize visual info.
+ */
+ resources.map_type=(char *) NULL;
+ resources.visual_type=visual_type;
+ visual_info=MagickXBestVisualInfo(display,map_info,&resources);
+ if (visual_info == (XVisualInfo *) NULL)
+ MagickFatalError(XServerFatalError,UnableToGetVisual,
+ resources.visual_type);
+ /*
+ Initialize window info.
+ */
+ window_info.ximage=(XImage *) NULL;
+ window_info.matte_image=(XImage *) NULL;
+ window_info.pixmap=(Pixmap) NULL;
+ window_info.matte_pixmap=(Pixmap) NULL;
+ }
+ /*
+ Free previous root colors.
+ */
+ if (window_info.id == root_window)
+ MagickXDestroyWindowColors(display,root_window);
+ coalesce=False;
+ if (images->next != (Image *) NULL)
+ {
+ Image
+ *next;
+
+ /*
+ Determine if the sequence of images have identical page info.
+ */
+ for (next=images; next != (Image *) NULL; )
+ {
+ if ((images->page.width != 0) && (images->page.height != 0))
+ if ((images->columns != next->columns) ||
+ (images->rows != next->rows))
+ break;
+ if ((images->page.x != next->page.x) ||
+ (images->page.y != next->page.y))
+ break;
+ next=next->next;
+ }
+ coalesce=next != (Image *) NULL;
+ if (coalesce)
+ {
+ Image
+ *coalesce_image;
+
+ coalesce_image=CoalesceImages(images,&images->exception);
+ if (coalesce_image == (Image *) NULL)
+ MagickFatalError2(images->exception.severity,
+ images->exception.reason,images->exception.description);
+ images=coalesce_image;
+ }
+ }
+ if (resources.map_type == (char *) NULL)
+ if ((visual_info->class != TrueColor) &&
+ (visual_info->class != DirectColor))
+ {
+ Image
+ *next;
+
+ /*
+ Determine if the sequence of images has the identical colormap.
+ */
+ for (next=images; next != (Image *) NULL; )
+ {
+ next->matte=False;
+ if ((next->storage_class == DirectClass) ||
+ (next->colors != images->colors) ||
+ (next->colors > (unsigned long) visual_info->colormap_size))
+ break;
+ for (i=0; i < (long) images->colors; i++)
+ if (NotColorMatch(next->colormap+i,images->colormap+i))
+ break;
+ if (i < (long) images->colors)
+ break;
+ next=next->next;
+ }
+ if (next != (Image *) NULL)
+ (void) MapImages(images,(Image *) NULL,
+ resources.quantize_info->dither);
+ }
+ /*
+ Sort images by increasing scene number.
+ */
+ number_scenes=GetImageListLength(images);
+ image_list=ImageListToArray(images,&images->exception);
+ if (image_list == (Image **) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAnimateImageSequence);
+ for (i=0; i < (long) number_scenes; i++)
+ if (image_list[i]->scene == 0)
+ break;
+ if (i == (long) number_scenes)
+ qsort((void *) image_list,number_scenes,sizeof(Image *),SceneCompare);
+ /*
+ Initialize Standard Colormap.
+ */
+ resources.colormap=SharedColormap;
+ display_image=image_list[0];
+ for (scene=0; scene < (int) number_scenes; scene++)
+ {
+ if ((resource_info->map_type != (char *) NULL) ||
+ (visual_info->class == TrueColor) ||
+ (visual_info->class == DirectColor))
+ (void) SetImageType(image_list[scene],TrueColorType);
+ if ((display_image->columns < image_list[scene]->columns) &&
+ (display_image->rows < image_list[scene]->rows))
+ display_image=image_list[scene];
+ }
+ if ((resource_info->map_type != (char *) NULL) ||
+ (visual_info->class == TrueColor) ||
+ (visual_info->class == DirectColor))
+ (void) SetImageType(display_image,TrueColorType);
+ MagickXMakeStandardColormap(display,visual_info,&resources,display_image,map_info,
+ &pixel);
+ /*
+ Graphic context superclass.
+ */
+ context_values.background=pixel.background_color.pixel;
+ context_values.foreground=pixel.foreground_color.pixel;
+ pixel.annotate_context=XCreateGC(display,window_info.id,GCBackground |
+ GCForeground,&context_values);
+ if (pixel.annotate_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ /*
+ Initialize Image window attributes.
+ */
+ MagickXGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
+ &resources,&window_info);
+ /*
+ Create the X image.
+ */
+ window_info.width=(unsigned int) image_list[0]->columns;
+ window_info.height=(unsigned int) image_list[0]->rows;
+ FormatString(geometry,"%ux%u+0+0>",window_attributes.width,
+ window_attributes.height);
+ width=window_info.width;
+ height=window_info.height;
+ x=window_info.x;
+ y=window_info.y;
+ {
+ unsigned long
+ geometry_width=width,
+ geometry_height=height;
+
+ (void) GetMagickGeometry(geometry,&x,&y,&geometry_width,&geometry_height);
+ width=(unsigned int) geometry_width;
+ height=(unsigned int) geometry_height;
+ }
+ window_info.width=(unsigned int) height;
+ window_info.height=(unsigned int) height;
+ window_info.x=(int) x;
+ window_info.y=(int) y;
+ status=MagickXMakeImage(display,&resources,&window_info,image_list[0],
+ window_info.width,window_info.height);
+ if (status == False)
+ MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
+ window_info.x=0;
+ window_info.y=0;
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Image: %.1024s[%lu] %lux%lu ",image_list[0]->filename,
+ image_list[0]->scene,image_list[0]->columns,image_list[0]->rows);
+ if (image_list[0]->colors != 0)
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%uc ",
+ image_list[0]->colors);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
+ image_list[0]->magick);
+ }
+ /*
+ Adjust image dimensions as specified by backdrop or geometry options.
+ */
+ width=window_info.width;
+ height=window_info.height;
+ if (resources.backdrop)
+ {
+ /*
+ Center image on window.
+ */
+ window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
+ window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
+ width=window_attributes.width;
+ height=window_attributes.height;
+ }
+ if (resources.image_geometry != (char *) NULL)
+ {
+ char
+ default_geometry[MaxTextExtent];
+
+ int
+ gravity;
+
+ XSizeHints
+ *size_hints;
+
+ unsigned int
+ flags;
+
+ /*
+ User specified geometry.
+ */
+ size_hints=XAllocSizeHints();
+ if (size_hints == (XSizeHints *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToDisplayImage);
+ size_hints->flags=(long) NULL;
+ FormatString(default_geometry,"%ux%u",width,height);
+ flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
+ default_geometry,window_info.border_width,size_hints,&window_info.x,
+ &window_info.y,(int *) &width,(int *) &height,&gravity);
+ if (flags & (XValue | YValue))
+ {
+ width=window_attributes.width;
+ height=window_attributes.height;
+ }
+ (void) XFree((void *) size_hints);
+ }
+ /*
+ Create the X pixmap.
+ */
+ window_info.pixmap=XCreatePixmap(display,window_info.id,(unsigned int) width,
+ (unsigned int) height,window_info.depth);
+ if (window_info.pixmap == (Pixmap) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateXPixmap,(char *) NULL);
+ /*
+ Display pixmap on the window.
+ */
+ if (((unsigned int) width > window_info.width) ||
+ ((unsigned int) height > window_info.height))
+ (void) XFillRectangle(display,window_info.pixmap,
+ window_info.annotate_context,0,0,(unsigned int) width,
+ (unsigned int) height);
+ (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
+ window_info.ximage,0,0,window_info.x,window_info.y,window_info.width,
+ window_info.height);
+ (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
+ (void) XClearWindow(display,window_info.id);
+ /*
+ Initialize image pixmaps structure.
+ */
+ window_info.pixmaps=MagickAllocateMemory(Pixmap *,number_scenes*sizeof(Pixmap));
+ window_info.matte_pixmaps=MagickAllocateMemory(Pixmap *,
+ number_scenes*sizeof(Pixmap));
+ if ((window_info.pixmaps == (Pixmap *) NULL) ||
+ (window_info.matte_pixmaps == (Pixmap *) NULL))
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAnimateImageSequence);
+ window_info.pixmaps[0]=window_info.pixmap;
+ window_info.matte_pixmaps[0]=window_info.pixmap;
+ scene_info.pixels=(unsigned long *) NULL;
+ for (scene=1; scene < (int) number_scenes; scene++)
+ {
+ /*
+ Create X image.
+ */
+ window_info.pixmap=(Pixmap) NULL;
+ window_info.matte_pixmap=(Pixmap) NULL;
+ if ((resources.map_type != (char *) NULL) ||
+ (visual_info->class == TrueColor) ||
+ (visual_info->class == DirectColor))
+ if (image_list[scene]->storage_class == PseudoClass)
+ {
+ /*
+ Get pixel info for this scene.
+ */
+ MagickXGetPixelPacket(display,visual_info,map_info,&resources,
+ image_list[scene],&scene_info);
+ window_info.pixel_info=(&scene_info);
+ }
+ status=MagickXMakeImage(display,&resources,&window_info,image_list[scene],
+ (unsigned int) image_list[scene]->columns,
+ (unsigned int) image_list[scene]->rows);
+ if (status == False)
+ MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Image: [%lu] %.1024s %lux%lu ",image_list[scene]->scene,
+ image_list[scene]->filename,image_list[scene]->columns,
+ image_list[scene]->rows);
+ if (image_list[scene]->colors != 0)
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%uc ",
+ image_list[scene]->colors);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
+ image_list[scene]->magick);
+ }
+ /*
+ Create the X pixmap.
+ */
+ window_info.pixmap=XCreatePixmap(display,window_info.id,
+ (unsigned int) width,(unsigned int) height,window_info.depth);
+ if (window_info.pixmap == (Pixmap) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateXPixmap,(char *) NULL);
+ /*
+ Display pixmap on the window.
+ */
+ if (((unsigned int) width > window_info.width) ||
+ ((unsigned int) height > window_info.height))
+ (void) XFillRectangle(display,window_info.pixmap,
+ window_info.annotate_context,0,0,(unsigned int) width,
+ (unsigned int) height);
+ (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
+ window_info.ximage,0,0,window_info.x,window_info.y,window_info.width,
+ window_info.height);
+ (void) XSetWindowBackgroundPixmap(display,window_info.id,
+ window_info.pixmap);
+ (void) XClearWindow(display,window_info.id);
+ window_info.pixmaps[scene]=window_info.pixmap;
+ window_info.matte_pixmaps[scene]=window_info.matte_pixmap;
+ if (image_list[scene]->matte)
+ (void) XClearWindow(display,window_info.id);
+ MagickXDelay(display,(unsigned long) resources.delay*10*Max(images->delay,1));
+ }
+ window_info.pixel_info=(&pixel);
+ /*
+ Display pixmap on the window.
+ */
+ (void) XSelectInput(display,window_info.id,SubstructureNotifyMask);
+ event.type=Expose;
+ do
+ {
+ for (scene=0; scene < (int) number_scenes; scene++)
+ {
+ if (XEventsQueued(display,QueuedAfterFlush) > 0)
+ {
+ (void) XNextEvent(display,&event);
+ if (event.type == DestroyNotify)
+ break;
+ }
+ window_info.pixmap=window_info.pixmaps[scene];
+ window_info.matte_pixmap=window_info.matte_pixmaps[scene];
+ (void) XSetWindowBackgroundPixmap(display,window_info.id,
+ window_info.pixmap);
+ (void) XClearWindow(display,window_info.id);
+ (void) XSync(display,False);
+ MagickXDelay(display,(unsigned long) resources.delay*10*
+ Max(image_list[scene]->delay,1));
+ }
+ } while (event.type != DestroyNotify);
+ (void) XSync(display,False);
+ MagickFreeMemory(image_list);
+ if (coalesce)
+ DestroyImageList(images);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X A n i m a t e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXAnimateImages() displays an image via X11.
+%
+% The format of the MagickXAnimateImages method is:
+%
+% Image *MagickXAnimateImages(Display *display,MagickXResourceInfo *resource_info,
+% char **argv,const int argc,Image *images)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o argv: Specifies the application's argument list.
+%
+% o argc: Specifies the number of arguments.
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport Image *
+MagickXAnimateImages(Display *display,
+ MagickXResourceInfo *resource_info,
+ char *argv[],
+ const int argc,
+ Image *images)
+{
+#define MagickMenus 4
+#define MaxWindows 8
+#define MagickTitle "Commands"
+
+ static const char
+ *CommandMenu[]=
+ {
+ "Animate",
+ "Speed",
+ "Direction",
+ "Help",
+ "Image Info",
+ "Quit",
+ (char *) NULL
+ },
+ *AnimateMenu[]=
+ {
+ "Open",
+ "Play",
+ "Step",
+ "Repeat",
+ "Auto Reverse",
+ (char *) NULL
+ },
+ *SpeedMenu[]=
+ {
+ "Faster",
+ "Slower",
+ (char *) NULL
+ },
+ *DirectionMenu[]=
+ {
+ "Forward",
+ "Reverse",
+ (char *) NULL
+ },
+ *HelpMenu[]=
+ {
+ "Overview",
+ "Browse Documentation",
+ "About Animate",
+ (char *) NULL
+ };
+
+
+ static const char
+ **Menus[MagickMenus]=
+ {
+ AnimateMenu,
+ SpeedMenu,
+ DirectionMenu,
+ HelpMenu
+ };
+
+ static const CommandType
+ CommandMenus[]=
+ {
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ InfoCommand,
+ QuitCommand
+ },
+ CommandTypes[]=
+ {
+ OpenCommand,
+ PlayCommand,
+ StepCommand,
+ RepeatCommand,
+ AutoReverseCommand
+ },
+ SpeedCommands[]=
+ {
+ FasterCommand,
+ SlowerCommand
+ },
+ DirectionCommands[]=
+ {
+ ForwardCommand,
+ ReverseCommand
+ },
+ HelpCommands[]=
+ {
+ HelpCommand,
+ BrowseDocumentationCommand,
+ VersionCommand
+ };
+
+ static const CommandType
+ *Commands[MagickMenus]=
+ {
+ CommandTypes,
+ SpeedCommands,
+ DirectionCommands,
+ HelpCommands
+ };
+
+ char
+ command[MaxTextExtent],
+ geometry[MaxTextExtent],
+ resource_name[MaxTextExtent];
+
+ CommandType
+ command_type;
+
+ Image
+ *display_image,
+ *image,
+ **image_list,
+ *nexus;
+
+ int
+ status;
+
+ unsigned int
+ iterations;
+
+ long
+ first_scene,
+ scene,
+ x,
+ y;
+
+ KeySym
+ key_symbol;
+
+ MonitorHandler
+ monitor_handler;
+
+ register char
+ *p;
+
+ register long
+ i;
+
+ static char
+ working_directory[MaxTextExtent];
+
+ static unsigned long
+ number_windows;
+
+ static MagickXWindowInfo
+ *magick_windows[MaxWindows];
+
+ time_t
+ timestamp;
+
+ unsigned int
+ context_mask,
+ coalesce,
+ state;
+
+ unsigned long
+ height,
+ number_scenes,
+ width;
+
+ WarningHandler
+ warning_handler;
+
+ Window
+ root_window;
+
+ XClassHint
+ *class_hints;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XGCValues
+ context_values;
+
+ MagickXPixelInfo
+ *icon_pixel,
+ *pixel,
+ scene_info;
+
+ MagickXResourceInfo
+ *icon_resources;
+
+ XStandardColormap
+ *icon_map,
+ *map_info;
+
+ XTextProperty
+ window_name;
+
+ XVisualInfo
+ *icon_visual,
+ *visual_info;
+
+ MagickXWindows
+ *windows;
+
+ XWMHints
+ *manager_hints;
+
+ assert(images != (Image *) NULL);
+ assert(images->signature == MagickSignature);
+ monitor_handler=(MonitorHandler) NULL;
+ warning_handler=(WarningHandler) NULL;
+ windows=MagickXSetWindows((MagickXWindows *) ~0);
+ if (windows != (MagickXWindows *) NULL)
+ {
+ if ((strlen(working_directory) > 0) &&
+ (chdir(working_directory) != 0))
+ MagickFatalError(ConfigureFatalError,UnableToRestoreCurrentDirectory,
+ NULL);
+ monitor_handler=SetMonitorHandler(MagickXMagickMonitor);
+ warning_handler=resource_info->display_warnings ?
+ SetErrorHandler(MagickXWarning) : SetErrorHandler((ErrorHandler) NULL);
+ warning_handler=resource_info->display_warnings ?
+ SetWarningHandler(MagickXWarning) : SetWarningHandler((WarningHandler) NULL);
+ }
+ else
+ {
+ register Image
+ *p;
+
+ /*
+ Initialize window structure.
+ */
+ for (p=images; p != (Image *) NULL; p=p->next)
+ {
+ if (p->storage_class == DirectClass)
+ {
+ resource_info->colors=0;
+ break;
+ }
+ if (p->colors > resource_info->colors)
+ resource_info->colors=p->colors;
+ }
+ windows=MagickXSetWindows(MagickXInitializeWindows(display,resource_info));
+ if (windows == (MagickXWindows *) NULL)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(XServerFatalError,UnableToCreateXWindow));
+ /*
+ Initialize window id's.
+ */
+ number_windows=0;
+ magick_windows[number_windows++]=(&windows->icon);
+ magick_windows[number_windows++]=(&windows->backdrop);
+ magick_windows[number_windows++]=(&windows->image);
+ magick_windows[number_windows++]=(&windows->info);
+ magick_windows[number_windows++]=(&windows->command);
+ magick_windows[number_windows++]=(&windows->widget);
+ magick_windows[number_windows++]=(&windows->popup);
+ for (i=0; i < (long) number_windows; i++)
+ magick_windows[i]->id=(Window) NULL;
+ }
+ /*
+ Initialize font info.
+ */
+ if (windows->font_info != (XFontStruct *) NULL)
+ (void) XFreeFont(display,windows->font_info);
+ windows->font_info=MagickXBestFont(display,resource_info,False);
+ if (windows->font_info == (XFontStruct *) NULL)
+ MagickFatalError(XServerFatalError,UnableToLoadFont,resource_info->font);
+ /*
+ Initialize Standard Colormap.
+ */
+ map_info=windows->map_info;
+ icon_map=windows->icon_map;
+ visual_info=windows->visual_info;
+ icon_visual=windows->icon_visual;
+ pixel=windows->pixel_info;
+ icon_pixel=windows->icon_pixel;
+ font_info=windows->font_info;
+ icon_resources=windows->icon_resources;
+ class_hints=windows->class_hints;
+ manager_hints=windows->manager_hints;
+ root_window=XRootWindow(display,visual_info->screen);
+ coalesce=False;
+ if (images->next != (Image *) NULL)
+ {
+ Image
+ *next;
+
+ /*
+ Determine if the sequence of images have identical page info.
+ */
+ for (next=images; next != (Image *) NULL; )
+ {
+ if ((images->columns != next->columns) ||
+ (images->rows != next->rows))
+ break;
+ if ((images->page.x != next->page.x) ||
+ (images->page.y != next->page.y))
+ break;
+ next=next->next;
+ }
+ coalesce=next != (Image *) NULL;
+ if (coalesce)
+ {
+ Image
+ *coalesce_image;
+
+ coalesce_image=CoalesceImages(images,&images->exception);
+ if (coalesce_image == (Image *) NULL)
+ MagickFatalError2(images->exception.severity,
+ images->exception.reason,images->exception.description);
+ images=coalesce_image;
+ }
+ }
+ if (resource_info->map_type == (char *) NULL)
+ if ((visual_info->class != TrueColor) &&
+ (visual_info->class != DirectColor))
+ {
+ Image
+ *next;
+
+ /*
+ Determine if the sequence of images has the identical colormap.
+ */
+ for (next=images; next != (Image *) NULL; )
+ {
+ next->matte=False;
+ if ((next->storage_class == DirectClass) ||
+ (next->colors != images->colors) ||
+ (next->colors > (unsigned long) visual_info->colormap_size))
+ break;
+ for (i=0; i < (long) images->colors; i++)
+ if (NotColorMatch(next->colormap+i,images->colormap+i))
+ break;
+ if (i < (long) images->colors)
+ break;
+ next=next->next;
+ }
+ if (next != (Image *) NULL)
+ (void) MapImages(images,(Image *) NULL,
+ resource_info->quantize_info->dither);
+ }
+ /*
+ Sort images by increasing scene number.
+ */
+ number_scenes=GetImageListLength(images);
+ image_list=ImageListToArray(images,&images->exception);
+ if (image_list == (Image **) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAnimateImageSequence);
+ for (scene=0; scene < (long) number_scenes; scene++)
+ if (image_list[scene]->scene == 0)
+ break;
+ if (scene == (long) number_scenes)
+ qsort((void *) image_list,number_scenes,sizeof(Image *),SceneCompare);
+ /*
+ Initialize Standard Colormap.
+ */
+ nexus=(Image *) NULL;
+ display_image=image_list[0];
+ (void) TransformColorspace(display_image,RGBColorspace);
+ for (scene=0; scene < (long) number_scenes; scene++)
+ {
+ if ((resource_info->map_type != (char *) NULL) ||
+ (visual_info->class == TrueColor) ||
+ (visual_info->class == DirectColor))
+ (void) SetImageType(image_list[scene],TrueColorType);
+ if ((display_image->columns < image_list[scene]->columns) &&
+ (display_image->rows < image_list[scene]->rows))
+ display_image=image_list[scene];
+ }
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Image: %.1024s[%lu] %lux%lu ",display_image->filename,
+ display_image->scene,display_image->columns,display_image->rows);
+ if (display_image->colors != 0)
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%uc ",
+ display_image->colors);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
+ display_image->magick);
+ }
+ MagickXMakeStandardColormap(display,visual_info,resource_info,display_image,
+ map_info,pixel);
+ /*
+ Initialize graphic context.
+ */
+ windows->context.id=(Window) NULL;
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->context);
+ class_hints->res_name=(char *) "superclass";
+ class_hints->res_class=(char *) "Display";
+ manager_hints->flags=InputHint | StateHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=WithdrawnState;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->context);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Window id: 0x%lx (context)",windows->context.id);
+ context_values.background=pixel->background_color.pixel;
+ context_values.font=font_info->fid;
+ context_values.foreground=pixel->foreground_color.pixel;
+ context_values.graphics_exposures=False;
+ context_mask=GCBackground | GCFont | GCForeground | GCGraphicsExposures;
+ if (pixel->annotate_context != (GC) NULL)
+ (void) XFreeGC(display,pixel->annotate_context);
+ pixel->annotate_context=
+ XCreateGC(display,windows->context.id,context_mask,&context_values);
+ if (pixel->annotate_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ context_values.background=pixel->depth_color.pixel;
+ if (pixel->widget_context != (GC) NULL)
+ (void) XFreeGC(display,pixel->widget_context);
+ pixel->widget_context=
+ XCreateGC(display,windows->context.id,context_mask,&context_values);
+ if (pixel->widget_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ context_values.background=pixel->foreground_color.pixel;
+ context_values.foreground=pixel->background_color.pixel;
+ context_values.plane_mask=
+ context_values.background ^ context_values.foreground;
+ if (pixel->highlight_context != (GC) NULL)
+ (void) XFreeGC(display,pixel->highlight_context);
+ pixel->highlight_context=XCreateGC(display,windows->context.id,
+ context_mask | GCPlaneMask,&context_values);
+ if (pixel->highlight_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ (void) XDestroyWindow(display,windows->context.id);
+ /*
+ Initialize icon window.
+ */
+ MagickXGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
+ icon_resources,&windows->icon);
+ windows->icon.geometry=resource_info->icon_geometry;
+ MagickXBestIconSize(display,&windows->icon,display_image);
+ windows->icon.attributes.colormap=
+ XDefaultColormap(display,icon_visual->screen);
+ windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
+ class_hints->res_name=(char *) "icon";
+ manager_hints->flags=InputHint | StateHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=IconicState;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->icon);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (icon)",
+ windows->icon.id);
+ /*
+ Initialize graphic context for icon window.
+ */
+ if (icon_pixel->annotate_context != (GC) NULL)
+ (void) XFreeGC(display,icon_pixel->annotate_context);
+ context_values.background=icon_pixel->background_color.pixel;
+ context_values.foreground=icon_pixel->foreground_color.pixel;
+ icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
+ GCBackground | GCForeground,&context_values);
+ if (icon_pixel->annotate_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ windows->icon.annotate_context=icon_pixel->annotate_context;
+ /*
+ Initialize Image window.
+ */
+ if (windows->image.id != (Window) NULL)
+ {
+ MagickFreeMemory(windows->image.name);
+ MagickFreeMemory(windows->image.icon_name);
+ }
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->image);
+ windows->image.shape=True; /* non-rectangular shape hint */
+ windows->image.shared_memory&=resource_info->use_shared_memory;
+ if (resource_info->title != (char *) NULL)
+ {
+ windows->image.name=TranslateText(resource_info->image_info,
+ display_image,resource_info->title);
+ windows->image.icon_name=TranslateText(resource_info->image_info,
+ display_image,resource_info->title);
+ }
+ else
+ {
+ char
+ filename[MaxTextExtent];
+
+ /*
+ Window name is the base of the filename.
+ */
+ windows->image.name=AllocateString((char *) NULL);
+ windows->image.icon_name=AllocateString((char *) NULL);
+ GetPathComponent(display_image->filename,TailPath,filename);
+ FormatString(windows->image.name,"GraphicsMagick: %.1024s[%lu of %lu]",
+ filename,display_image->scene,number_scenes);
+ (void) strlcpy(windows->image.icon_name,filename,MaxTextExtent);
+ }
+ if (resource_info->immutable)
+ windows->image.immutable=True;
+ windows->image.shape=True;
+ windows->image.geometry=resource_info->image_geometry;
+ FormatString(geometry,"%ux%u+0+0>!",
+ 90*XDisplayWidth(display,visual_info->screen)/100,
+ 90*XDisplayHeight(display,visual_info->screen)/100);
+ width=display_image->columns;
+ height=display_image->rows;
+ x=0;
+ y=0;
+ (void) GetMagickGeometry(geometry,&x,&y,&width,&height);
+ windows->image.width=(unsigned int) width;
+ windows->image.height=(unsigned int) height;
+ windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
+ KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
+ PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->backdrop);
+ if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
+ {
+ /*
+ Initialize backdrop window.
+ */
+ windows->backdrop.x=0;
+ windows->backdrop.y=0;
+ (void) CloneString(&windows->backdrop.name,"GraphicsMagick Backdrop");
+ windows->backdrop.flags=USSize | USPosition;
+ windows->backdrop.width=XDisplayWidth(display,visual_info->screen);
+ windows->backdrop.height=XDisplayHeight(display,visual_info->screen);
+ windows->backdrop.border_width=0;
+ windows->backdrop.immutable=True;
+ windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
+ ButtonReleaseMask;
+ windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
+ StructureNotifyMask;
+ windows->backdrop.attributes.override_redirect=True;
+ class_hints->res_name=(char *) "backdrop";
+ manager_hints->flags=IconWindowHint | InputHint | StateHint;
+ manager_hints->icon_window=windows->icon.id;
+ manager_hints->input=True;
+ manager_hints->initial_state=
+ resource_info->iconic ? IconicState : NormalState;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->backdrop);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Window id: 0x%lx (backdrop)",windows->backdrop.id);
+ (void) XMapWindow(display,windows->backdrop.id);
+ (void) XClearWindow(display,windows->backdrop.id);
+ if (windows->image.id != (Window) NULL)
+ {
+ (void) XDestroyWindow(display,windows->image.id);
+ windows->image.id=(Window) NULL;
+ }
+ /*
+ Position image in the center the backdrop.
+ */
+ windows->image.flags|=USPosition;
+ windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
+ (windows->image.width/2);
+ windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
+ (windows->image.height/2);
+ }
+ if (resource_info->name == (char *) NULL)
+ class_hints->res_name=resource_info->client_name;
+ else
+ class_hints->res_name=resource_info->name;
+ manager_hints->flags=IconWindowHint | InputHint | StateHint;
+ manager_hints->icon_window=windows->icon.id;
+ manager_hints->input=True;
+ manager_hints->initial_state=
+ resource_info->iconic ? IconicState : NormalState;
+ if (windows->group_leader.id != (Window) NULL)
+ {
+ /*
+ Follow the leader.
+ */
+ manager_hints->flags|=(unsigned int) WindowGroupHint;
+ manager_hints->window_group=windows->group_leader.id;
+ (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Window id: 0x%lx (group leader)",windows->group_leader.id);
+ }
+ MagickXMakeWindow(display,
+ (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
+ argv,argc,class_hints,manager_hints,&windows->image);
+ (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
+ XA_STRING,8,PropModeReplace,(unsigned char *) NULL,0);
+ if (windows->group_leader.id != (Window) NULL)
+ (void) XSetTransientForHint(display,windows->image.id,
+ windows->group_leader.id);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (image)",
+ windows->image.id);
+ /*
+ Initialize Info widget.
+ */
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->info);
+ (void) CloneString(&windows->info.name,"Info");
+ (void) CloneString(&windows->info.icon_name,"Info");
+ windows->info.border_width=1;
+ windows->info.x=2;
+ windows->info.y=2;
+ windows->info.flags|=PPosition;
+ windows->info.attributes.win_gravity=UnmapGravity;
+ windows->info.attributes.event_mask=
+ ButtonPressMask | ExposureMask | StructureNotifyMask;
+ class_hints->res_name=(char *) "info";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
+ &windows->info);
+ windows->info.highlight_stipple=XCreateBitmapFromData(display,
+ windows->info.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight);
+ windows->info.shadow_stipple=XCreateBitmapFromData(display,
+ windows->info.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight);
+ (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
+ if (windows->image.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (info)",
+ windows->info.id);
+ /*
+ Initialize Command widget.
+ */
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->command);
+ windows->command.data=MagickMenus;
+ (void) MagickXCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
+ FormatString(resource_name,"%.1024s.command",resource_info->client_name);
+ windows->command.geometry=MagickXGetResourceClass(resource_info->resource_database,
+ resource_name,"geometry",(char *) NULL);
+ (void) CloneString(&windows->command.name,MagickTitle);
+ windows->command.border_width=0;
+ windows->command.flags|=PPosition;
+ windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
+ OwnerGrabButtonMask | StructureNotifyMask;
+ class_hints->res_name=(char *) "command";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->command);
+ windows->command.highlight_stipple=windows->info.highlight_stipple;
+ windows->command.shadow_stipple=windows->info.shadow_stipple;
+ (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (command)",
+ windows->command.id);
+ /*
+ Initialize Widget window.
+ */
+ if (windows->widget.id != (Window) NULL)
+ MagickFreeMemory(windows->widget.name);
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->widget);
+ FormatString(resource_name,"%.1024s.widget",resource_info->client_name);
+ windows->widget.geometry=MagickXGetResourceClass(resource_info->resource_database,
+ resource_name,"geometry",(char *) NULL);
+ windows->widget.name=AllocateString((char *) NULL);
+ *windows->widget.name='\0';
+ windows->widget.border_width=0;
+ windows->widget.flags|=PPosition;
+ windows->widget.attributes.backing_store=WhenMapped;
+ windows->widget.attributes.save_under=True;
+ windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
+ KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
+ StructureNotifyMask;
+ class_hints->res_name=(char *) "widget";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=True;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->widget);
+ windows->widget.highlight_stipple=windows->info.highlight_stipple;
+ windows->widget.shadow_stipple=windows->info.shadow_stipple;
+ (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (widget)",
+ windows->widget.id);
+ /*
+ Initialize popup window.
+ */
+ if (windows->popup.id != (Window) NULL)
+ MagickFreeMemory(windows->popup.name);
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->popup);
+ windows->popup.name=AllocateString((char *) NULL);
+ *windows->popup.name='\0';
+ windows->popup.border_width=0;
+ windows->popup.flags|=PPosition;
+ windows->popup.attributes.backing_store=WhenMapped;
+ windows->popup.attributes.save_under=True;
+ windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
+ KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
+ class_hints->res_name=(char *) "popup";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=True;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->popup);
+ windows->popup.highlight_stipple=windows->info.highlight_stipple;
+ windows->popup.shadow_stipple=windows->info.shadow_stipple;
+ (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (pop up)",
+ windows->popup.id);
+ if (!windows->image.mapped || (windows->backdrop.id != (Window) NULL))
+ (void) XMapWindow(display,windows->image.id);
+ /*
+ Set out progress and warning handlers.
+ */
+ if (monitor_handler == (MonitorHandler) NULL)
+ monitor_handler=SetMonitorHandler(MagickXMagickMonitor);
+ if (warning_handler == (WarningHandler) NULL)
+ {
+ warning_handler=resource_info->display_warnings ?
+ SetErrorHandler(MagickXWarning) : SetErrorHandler((ErrorHandler) NULL);
+ warning_handler=resource_info->display_warnings ?
+ SetWarningHandler(MagickXWarning) : SetWarningHandler((WarningHandler) NULL);
+ }
+ /*
+ Initialize X image structure.
+ */
+ windows->image.x=0;
+ windows->image.y=0;
+ status=MagickXMakeImage(display,resource_info,&windows->image,display_image,
+ (unsigned int) display_image->columns,(unsigned int) display_image->rows);
+ if (status == False)
+ MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
+ if (windows->image.mapped)
+ MagickXRefreshWindow(display,&windows->image,(XEvent *) NULL);
+ /*
+ Initialize image pixmaps structure.
+ */
+ (void) XMapWindow(display,windows->image.id);
+ windows->image.pixmaps=MagickAllocateMemory(Pixmap *,number_scenes*sizeof(Pixmap));
+ windows->image.matte_pixmaps=MagickAllocateMemory(Pixmap *,
+ number_scenes*sizeof(Pixmap));
+ if ((windows->image.pixmaps == (Pixmap *) NULL) ||
+ (windows->image.matte_pixmaps == (Pixmap *) NULL))
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAnimateImageSequence);
+ windows->image.pixmaps[0]=windows->image.pixmap;
+ windows->image.matte_pixmaps[0]=windows->image.matte_pixmap;
+ scene_info.pixels=(unsigned long *) NULL;
+ for (scene=1; scene < (long) number_scenes; scene++)
+ {
+ /*
+ Create X image.
+ */
+ (void) TransformColorspace(image_list[scene],RGBColorspace);
+ windows->image.pixmap=(Pixmap) NULL;
+ windows->image.matte_pixmap=(Pixmap) NULL;
+ if ((resource_info->map_type != (char *) NULL) ||
+ (visual_info->class == TrueColor) ||
+ (visual_info->class == DirectColor))
+ if (image_list[scene]->storage_class == PseudoClass)
+ {
+ /*
+ Get pixel info for this scene.
+ */
+ MagickXGetPixelPacket(display,visual_info,map_info,resource_info,
+ image_list[scene],&scene_info);
+ windows->image.pixel_info=(&scene_info);
+ }
+ status=MagickXMakeImage(display,resource_info,&windows->image,image_list[scene],
+ (unsigned int) image_list[scene]->columns,
+ (unsigned int) image_list[scene]->rows);
+ if (status == False)
+ MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Image: [%lu] %.1024s %lux%lu ",image_list[scene]->scene,
+ image_list[scene]->filename,image_list[scene]->columns,
+ image_list[scene]->rows);
+ if (image_list[scene]->colors != 0)
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%uc ",
+ image_list[scene]->colors);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
+ image_list[scene]->magick);
+ }
+ /*
+ Window name is the base of the filename.
+ */
+ if (resource_info->title != (char *) NULL)
+ windows->image.name=TranslateText(resource_info->image_info,
+ image_list[scene],resource_info->title);
+ else
+ {
+ p=image_list[scene]->filename+strlen(image_list[scene]->filename)-1;
+ while ((p > image_list[scene]->filename) && (*(p-1) != '/'))
+ p--;
+ FormatString(windows->image.name,"GraphicsMagick: %.1024s[%lu of %lu]",p,
+ scene,number_scenes);
+ }
+ status=XStringListToTextProperty(&windows->image.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->image.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ windows->image.pixmaps[scene]=windows->image.pixmap;
+ windows->image.matte_pixmaps[scene]=windows->image.matte_pixmap;
+ event.xexpose.x=0;
+ event.xexpose.y=0;
+ event.xexpose.width=(unsigned int) image_list[scene]->columns;
+ event.xexpose.height=(unsigned int) image_list[scene]->rows;
+ MagickXRefreshWindow(display,&windows->image,&event);
+ MagickXDelay(display,(unsigned long) resource_info->delay*10*Max(images->delay,1));
+ }
+ if (windows->command.mapped)
+ (void) XMapRaised(display,windows->command.id);
+ /*
+ Respond to events.
+ */
+ nexus=(Image *) NULL;
+ scene=0;
+ first_scene=0;
+ iterations=0;
+ image=image_list[0];
+ state=ForwardAnimationState | RepeatAnimationState;
+ (void) MagickXMagickCommand(display,resource_info,windows,PlayCommand,&images,
+ &state);
+ do
+ {
+ if (XEventsQueued(display,QueuedAfterFlush) == 0)
+ if ((state & PlayAnimationState) || (state & StepAnimationState))
+ {
+ if (state & ForwardAnimationState)
+ {
+ /*
+ Forward animation: increment scene number.
+ */
+ if (scene < ((long) number_scenes-1))
+ scene++;
+ else
+ {
+ iterations++;
+ if (iterations == image_list[0]->iterations)
+ {
+ iterations=0;
+ state&=(~RepeatAnimationState);
+ }
+ if (state & AutoReverseAnimationState)
+ {
+ state&=(~ForwardAnimationState);
+ scene--;
+ }
+ else
+ {
+ if (!(state & RepeatAnimationState))
+ state&=(~PlayAnimationState);
+ scene=first_scene;
+ (void) MagickSleep(resource_info->pause);
+ }
+ }
+ }
+ else
+ {
+ /*
+ Reverse animation: decrement scene number.
+ */
+ if (scene > first_scene)
+ scene--;
+ else
+ {
+ iterations++;
+ if (iterations == image_list[0]->iterations)
+ {
+ iterations=0;
+ state&=(~RepeatAnimationState);
+ }
+ if (state & AutoReverseAnimationState)
+ {
+ state|=ForwardAnimationState;
+ scene=first_scene;
+ (void) MagickSleep(resource_info->pause);
+ }
+ else
+ {
+ if (!(state & RepeatAnimationState))
+ state&=(~PlayAnimationState);
+ scene=(long) number_scenes-1;
+ }
+ }
+ }
+ image=image_list[scene];
+ if ((image != (Image *) NULL) && image->start_loop)
+ first_scene=scene;
+ if ((state & StepAnimationState) ||
+ (resource_info->title != (char *) NULL))
+ {
+ /*
+ Update window title.
+ */
+ p=image_list[scene]->filename+
+ strlen(image_list[scene]->filename)-1;
+ while ((p > image_list[scene]->filename) && (*(p-1) != '/'))
+ p--;
+ {
+ char
+ name[MaxTextExtent];
+
+ FormatString(name,
+ "GraphicsMagick: %.1024s[%lu of %lu]",p,scene,
+ number_scenes);
+ CloneString(&windows->image.name,name);
+ }
+ if (resource_info->title != (char *) NULL)
+ {
+ MagickFreeMemory(windows->image.name);
+ windows->image.name=TranslateText(resource_info->image_info,
+ image,resource_info->title);
+ }
+ if (windows->image.name != (char *) NULL)
+ {
+ status=
+ XStringListToTextProperty(&windows->image.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->image.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ }
+ }
+ /*
+ Copy X pixmap to Image window.
+ */
+ MagickXGetPixelPacket(display,visual_info,map_info,resource_info,
+ image_list[scene],&scene_info); /* FIXME leak here */
+ windows->image.pixel_info=(&scene_info);
+ windows->image.ximage->width=(unsigned int) image->columns;
+ windows->image.ximage->height=(unsigned int) image->rows;
+ windows->image.pixmap=windows->image.pixmaps[scene];
+ windows->image.matte_pixmap=windows->image.matte_pixmaps[scene];
+ event.xexpose.x=0;
+ event.xexpose.y=0;
+ event.xexpose.width=(unsigned int) image->columns;
+ event.xexpose.height=(unsigned int) image->rows;
+ MagickXRefreshWindow(display,&windows->image,&event);
+ (void) XSync(display,False);
+ state&=(~StepAnimationState);
+ MagickXDelay(display,(unsigned long) resource_info->delay*10*
+ Max(image->delay,1));
+ continue;
+ }
+ /*
+ Handle a window event.
+ */
+ timestamp=time((time_t *) NULL);
+ (void) XNextEvent(display,&event);
+ if (!windows->image.stasis)
+ windows->image.stasis=(time((time_t *) NULL)-timestamp) > 0;
+ if (event.xany.window == windows->command.id)
+ {
+ int
+ id;
+
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,CommandMenu,&event);
+ if (id < 0)
+ continue;
+ (void) strlcpy(command,CommandMenu[id],MaxTextExtent);
+ command_type=CommandMenus[id];
+ if (id < MagickMenus)
+ {
+ int
+ entry;
+
+ /*
+ Select a command from a pop-up menu.
+ */
+ entry=MagickXMenuWidget(display,windows,CommandMenu[id],Menus[id],
+ command);
+ if (entry < 0)
+ continue;
+ (void) strlcpy(command,Menus[id][entry],MaxTextExtent);
+ command_type=Commands[id][entry];
+ }
+ if (command_type != NullCommand)
+ nexus=MagickXMagickCommand(display,resource_info,windows,
+ command_type,&image,&state);
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
+ event.xbutton.button,event.xbutton.x,event.xbutton.y);
+ if ((event.xbutton.button == Button3) &&
+ (event.xbutton.state & Mod1Mask))
+ {
+ /*
+ Convert Alt-Button3 to Button2.
+ */
+ event.xbutton.button=Button2;
+ event.xbutton.state&=(~Mod1Mask);
+ }
+ if (event.xbutton.window == windows->backdrop.id)
+ {
+ (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
+ event.xbutton.time);
+ break;
+ }
+ if (event.xbutton.window == windows->image.id)
+ {
+ if (resource_info->immutable)
+ {
+ state|=ExitState;
+ break;
+ }
+ /*
+ Map/unmap Command widget.
+ */
+ if (windows->command.mapped)
+ (void) XWithdrawWindow(display,windows->command.id,
+ windows->command.screen);
+ else
+ {
+ (void) MagickXCommandWidget(display,windows,CommandMenu,
+ (XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ }
+ }
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
+ event.xbutton.button,event.xbutton.x,event.xbutton.y);
+ break;
+ }
+ case ClientMessage:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Client Message: 0x%lx 0x%lx %d 0x%lx",event.xclient.window,
+ event.xclient.message_type,event.xclient.format,(unsigned long)
+ event.xclient.data.l[0]);
+ if (event.xclient.message_type == windows->im_protocols)
+ {
+ if (*event.xclient.data.l == (long) windows->im_update_colormap)
+ {
+ /*
+ Update graphic context and window colormap.
+ */
+ for (i=0; i < (long) number_windows; i++)
+ {
+ if (magick_windows[i]->id == windows->icon.id)
+ continue;
+ context_values.background=pixel->background_color.pixel;
+ context_values.foreground=pixel->foreground_color.pixel;
+ (void) XChangeGC(display,magick_windows[i]->annotate_context,
+ context_mask,&context_values);
+ (void) XChangeGC(display,magick_windows[i]->widget_context,
+ context_mask,&context_values);
+ context_values.background=pixel->foreground_color.pixel;
+ context_values.foreground=pixel->background_color.pixel;
+ context_values.plane_mask=
+ context_values.background ^ context_values.foreground;
+ (void) XChangeGC(display,magick_windows[i]->highlight_context,
+ context_mask | GCPlaneMask,&context_values);
+ magick_windows[i]->attributes.background_pixel=
+ pixel->background_color.pixel;
+ magick_windows[i]->attributes.border_pixel=
+ pixel->border_color.pixel;
+ magick_windows[i]->attributes.colormap=map_info->colormap;
+ (void) XChangeWindowAttributes(display,magick_windows[i]->id,
+ magick_windows[i]->mask,&magick_windows[i]->attributes);
+ }
+ if (windows->backdrop.id != (Window) NULL)
+ (void) XInstallColormap(display,map_info->colormap);
+ break;
+ }
+ if (*event.xclient.data.l == (long) windows->im_exit)
+ {
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ if (event.xclient.message_type == windows->dnd_protocols)
+ {
+ Atom
+ selection,
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ Display image named by the Drag-and-Drop selection.
+ */
+ if ((*event.xclient.data.l != 2) && (*event.xclient.data.l != 128))
+ break;
+ selection=XInternAtom(display,"DndSelection",False);
+ status=XGetWindowProperty(display,root_window,selection,0L,2047L,
+ False,(Atom) AnyPropertyType,&type,&format,&length,&after,&data);
+ if ((status != Success) || (length == 0))
+ break;
+ if (*event.xclient.data.l == 2)
+ {
+ /*
+ Offix DND.
+ */
+ (void) strlcpy(resource_info->image_info->filename,
+ (char *) data,MaxTextExtent);
+ }
+ else
+ {
+ /*
+ XDND.
+ */
+ if (LocaleNCompare((char *) data,"file:",5) != 0)
+ {
+ (void) XFree((void *) data);
+ break;
+ }
+ (void) strlcpy(resource_info->image_info->filename,
+ ((char *) data)+5,MaxTextExtent);
+ }
+ nexus=ReadImage(resource_info->image_info,&image->exception);
+ if (image->exception.severity != UndefinedException)
+ MagickError2(image->exception.severity,image->exception.reason,
+ image->exception.description);
+ if (nexus != (Image *) NULL)
+ state|=ExitState;
+ (void) XFree((void *) data);
+ break;
+ }
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (long) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (long) windows->wm_delete_window)
+ break;
+ (void) XWithdrawWindow(display,event.xclient.window,
+ visual_info->screen);
+ if (event.xclient.window == windows->image.id)
+ {
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Configure Notify: 0x%lx %dx%d+%d+%d %d",event.xconfigure.window,
+ event.xconfigure.width,event.xconfigure.height,event.xconfigure.x,
+ event.xconfigure.y,event.xconfigure.send_event);
+ if (event.xconfigure.window == windows->image.id)
+ {
+ if (event.xconfigure.send_event != 0)
+ {
+ XWindowChanges
+ window_changes;
+
+ /*
+ Position the transient windows relative of the Image window.
+ */
+ if (windows->command.geometry == (char *) NULL)
+ if (!windows->command.mapped)
+ {
+ windows->command.x=
+ event.xconfigure.x-windows->command.width-25;
+ windows->command.y=event.xconfigure.y;
+ MagickXConstrainWindowPosition(display,&windows->command);
+ window_changes.x=windows->command.x;
+ window_changes.y=windows->command.y;
+ (void) XReconfigureWMWindow(display,windows->command.id,
+ windows->command.screen,CWX | CWY,&window_changes);
+ }
+ if (windows->widget.geometry == (char *) NULL)
+ if (!windows->widget.mapped)
+ {
+ windows->widget.x=
+ event.xconfigure.x+event.xconfigure.width/10;
+ windows->widget.y=
+ event.xconfigure.y+event.xconfigure.height/10;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,
+ windows->widget.screen,CWX | CWY,&window_changes);
+ }
+ }
+ /*
+ Image window has a new configuration.
+ */
+ windows->image.width=event.xconfigure.width;
+ windows->image.height=event.xconfigure.height;
+ break;
+ }
+ if (event.xconfigure.window == windows->icon.id)
+ {
+ /*
+ Icon window has a new configuration.
+ */
+ windows->icon.width=event.xconfigure.width;
+ windows->icon.height=event.xconfigure.height;
+ break;
+ }
+ break;
+ }
+ case DestroyNotify:
+ {
+ /*
+ Group leader has exited.
+ */
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Destroy Notify: 0x%lx",
+ event.xdestroywindow.window);
+ if (event.xdestroywindow.window == windows->group_leader.id)
+ {
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case EnterNotify:
+ {
+ /*
+ Selectively install colormap.
+ */
+ if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
+ {
+ if (event.xcrossing.mode != NotifyUngrab)
+ {
+ XInductColormap(display,map_info->colormap);
+ }
+ }
+ break;
+ }
+ case Expose:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Expose: 0x%lx %dx%d+%d+%d",event.xexpose.window,
+ event.xexpose.width,event.xexpose.height,event.xexpose.x,
+ event.xexpose.y);
+ /*
+ Repaint windows that are now exposed.
+ */
+ if (event.xexpose.window == windows->image.id)
+ {
+ windows->image.pixmap=windows->image.pixmaps[scene];
+ windows->image.matte_pixmap=windows->image.matte_pixmaps[scene];
+ MagickXRefreshWindow(display,&windows->image,&event);
+ break;
+ }
+ if (event.xexpose.window == windows->icon.id)
+ if (event.xexpose.count == 0)
+ {
+ MagickXRefreshWindow(display,&windows->icon,&event);
+ break;
+ }
+ break;
+ }
+ case KeyPress:
+ {
+ static int
+ length;
+
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Key press: 0x%lx (%c)",
+ key_symbol,*command);
+ command_type=NullCommand;
+ switch (key_symbol)
+ {
+ case XK_o:
+ {
+ if (!(event.xkey.state & ControlMask))
+ break;
+ command_type=OpenCommand;
+ break;
+ }
+ case XK_BackSpace:
+ {
+ command_type=StepBackwardCommand;
+ break;
+ }
+ case XK_space:
+ {
+ command_type=StepForwardCommand;
+ break;
+ }
+ case XK_less:
+ {
+ command_type=FasterCommand;
+ break;
+ }
+ case XK_greater:
+ {
+ command_type=SlowerCommand;
+ break;
+ }
+ case XK_F1:
+ {
+ command_type=HelpCommand;
+ break;
+ }
+ case XK_Find:
+ {
+ command_type=BrowseDocumentationCommand;
+ break;
+ }
+ case XK_question:
+ {
+ command_type=InfoCommand;
+ break;
+ }
+ case XK_q:
+ case XK_Cancel:
+ {
+ if (!(event.xkey.state & ControlMask))
+ break;
+ command_type=QuitCommand;
+ break;
+ }
+ default:
+ break;
+ }
+ if (command_type != NullCommand)
+ nexus=MagickXMagickCommand(display,resource_info,windows,
+ command_type,&image,&state);
+ break;
+ }
+ case KeyRelease:
+ {
+ /*
+ Respond to a user key release.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Key release: 0x%lx (%c)",key_symbol,*command);
+ break;
+ }
+ case LeaveNotify:
+ {
+ /*
+ Selectively uninstall colormap.
+ */
+ if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
+ {
+ if (event.xcrossing.mode != NotifyUngrab)
+ {
+ XUninductColormap(display,map_info->colormap);
+ }
+ }
+ break;
+ }
+ case MapNotify:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Map Notify: 0x%lx",
+ event.xmap.window);
+ if (event.xmap.window == windows->backdrop.id)
+ {
+ (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
+ CurrentTime);
+ windows->backdrop.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->image.id)
+ {
+ if (windows->backdrop.id != (Window) NULL)
+ (void) XInstallColormap(display,map_info->colormap);
+ if (LocaleCompare(image_list[0]->magick,"LOGO") == 0)
+ {
+ if (LocaleCompare(display_image->filename,"Untitled") == 0)
+ nexus=MagickXMagickCommand(display,resource_info,windows,
+ OpenCommand,&image,&state);
+ else
+ state|=ExitState;
+ }
+ windows->image.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->info.id)
+ {
+ windows->info.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->icon.id)
+ {
+ /*
+ Create an icon image.
+ */
+ MagickXMakeStandardColormap(display,icon_visual,icon_resources,
+ display_image,icon_map,icon_pixel);
+ (void) MagickXMakeImage(display,icon_resources,&windows->icon,
+ display_image,windows->icon.width,windows->icon.height);
+ (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
+ windows->icon.pixmap);
+ (void) XClearWindow(display,windows->icon.id);
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ windows->icon.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->command.id)
+ {
+ windows->command.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->popup.id)
+ {
+ windows->popup.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->widget.id)
+ {
+ windows->widget.mapped=True;
+ break;
+ }
+ break;
+ }
+ case MappingNotify:
+ {
+ (void) XRefreshKeyboardMapping(&event.xmapping);
+ break;
+ }
+ case NoExpose:
+ break;
+ case PropertyNotify:
+ {
+ Atom
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Property Notify: 0x%lx 0x%lx %d",event.xproperty.window,
+ event.xproperty.atom,event.xproperty.state);
+ if (event.xproperty.atom != windows->im_remote_command)
+ break;
+ /*
+ Display image named by the remote command protocol.
+ */
+ status=XGetWindowProperty(display,event.xproperty.window,
+ event.xproperty.atom,0L,MaxTextExtent-1,False,(Atom) AnyPropertyType,
+ &type,&format,&length,&after,&data);
+ if ((status != Success) || (length == 0))
+ break;
+ (void) strlcpy(resource_info->image_info->filename,(char *) data,
+ MaxTextExtent);
+ nexus=ReadImage(resource_info->image_info,&image->exception);
+ if (image->exception.severity != UndefinedException)
+ MagickError2(image->exception.severity,image->exception.reason,
+ image->exception.description);
+ if (nexus != (Image *) NULL)
+ state|=ExitState;
+ (void) XFree((void *) data);
+ break;
+ }
+ case ReparentNotify:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Reparent Notify: 0x%lx=>0x%lx",event.xreparent.parent,
+ event.xreparent.window);
+ break;
+ }
+ case UnmapNotify:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Unmap Notify: 0x%lx",
+ event.xunmap.window);
+ if (event.xunmap.window == windows->backdrop.id)
+ {
+ windows->backdrop.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->image.id)
+ {
+ windows->image.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->info.id)
+ {
+ windows->info.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->icon.id)
+ {
+ if (map_info->colormap == icon_map->colormap)
+ MagickXConfigureImageColormap(display,resource_info,windows,
+ display_image);
+ (void) MagickXFreeStandardColormap(display,icon_visual,icon_map,
+ icon_pixel);
+ windows->icon.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->command.id)
+ {
+ windows->command.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->popup.id)
+ {
+ if (windows->backdrop.id != (Window) NULL)
+ (void) XSetInputFocus(display,windows->image.id,RevertToParent,
+ CurrentTime);
+ windows->popup.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->widget.id)
+ {
+ if (windows->backdrop.id != (Window) NULL)
+ (void) XSetInputFocus(display,windows->image.id,RevertToParent,
+ CurrentTime);
+ windows->widget.mapped=False;
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d",
+ event.type);
+ break;
+ }
+ }
+ }
+ while (!(state & ExitState));
+ MagickFreeMemory(image_list);
+ if (coalesce)
+ {
+ DestroyImageList(images);
+ images=(Image *) NULL;
+ }
+ if ((windows->visual_info->class == GrayScale) ||
+ (windows->visual_info->class == PseudoColor) ||
+ (windows->visual_info->class == DirectColor))
+ {
+ /*
+ Withdraw windows.
+ */
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (windows->command.mapped)
+ (void) XWithdrawWindow(display,windows->command.id,
+ windows->command.screen);
+ }
+ if (!resource_info->backdrop)
+ if (windows->backdrop.mapped)
+ {
+ (void) XWithdrawWindow(display,windows->backdrop.id,
+ windows->backdrop.screen);
+ (void) XDestroyWindow(display,windows->backdrop.id);
+ windows->backdrop.id=(Window) NULL;
+ (void) XWithdrawWindow(display,windows->image.id,windows->image.screen);
+ (void) XDestroyWindow(display,windows->image.id);
+ windows->image.id=(Window) NULL;
+ }
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ for (scene=1; scene < (long) number_scenes; scene++)
+ {
+ if (windows->image.pixmaps[scene] != (Pixmap) NULL)
+ (void) XFreePixmap(display,windows->image.pixmaps[scene]);
+ windows->image.pixmaps[scene]=(Pixmap) NULL;
+
+ if (windows->image.matte_pixmaps[scene] != (Pixmap) NULL)
+ (void) XFreePixmap(display,windows->image.matte_pixmaps[scene]);
+ windows->image.matte_pixmaps[scene]=(Pixmap) NULL;
+ }
+ MagickFreeMemory(windows->image.pixmaps);
+ MagickFreeMemory(windows->image.matte_pixmaps);
+ if (nexus == (Image *) NULL)
+ {
+ /*
+ Destroy X windows.
+ */
+ if (windows->image.mapped)
+ (void) XWithdrawWindow(display,windows->image.id,windows->image.screen);
+ MagickXDelay(display,SuspendTime);
+
+ /*
+ Free Standard Colormap.
+ */
+ (void) MagickXFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
+ if (resource_info->map_type == (char *) NULL)
+ (void) MagickXFreeStandardColormap(display,visual_info,map_info,pixel);
+ /*
+ Free X resources.
+ */
+ MagickXDestroyXWindows(windows);
+ }
+ (void) XSync(display,False);
+ /*
+ Restore our progress monitor and warning handlers.
+ */
+ (void) SetMonitorHandler(monitor_handler);
+ (void) SetErrorHandler(warning_handler);
+ (void) SetWarningHandler(warning_handler);
+ /*
+ Change to home directory.
+ */
+ if (getcwd(working_directory,MaxTextExtent-1) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+ if ((strlen(resource_info->home_directory) > 0) &&
+ (chdir(resource_info->home_directory) != 0))
+ MagickFatalError(ConfigureFatalError,UnableToRestoreCurrentDirectory,
+ resource_info->home_directory);
+ return(nexus);
+}
+#endif
diff --git a/magick/animate.h b/magick/animate.h
new file mode 100644
index 0000000..df03b6e
--- /dev/null
+++ b/magick/animate.h
@@ -0,0 +1,165 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Methods to Interactively Animate an Image Sequence.
+*/
+#ifndef _MAGICK_ANIMATE_H
+#define _MAGICK_ANIMATE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+/*
+ Animate state declarations.
+*/
+#define AutoReverseAnimationState 0x0004
+#define ForwardAnimationState 0x0008
+#define HighlightState 0x0010
+#define PlayAnimationState 0x0020
+#define RepeatAnimationState 0x0040
+#define StepAnimationState 0x0080
+
+/*
+ Static declarations.
+*/
+static const char
+ *AnimateHelp[]=
+ {
+ "BUTTONS",
+ "",
+ " Press any button to map or unmap the Command widget.",
+ "",
+ "COMMAND WIDGET",
+ " The Command widget lists a number of sub-menus and commands.",
+ " They are",
+ "",
+ " Animate",
+ " Open",
+ " Play",
+ " Step",
+ " Repeat",
+ " Auto Reverse",
+ " Speed",
+ " Slower",
+ " Faster",
+ " Direction",
+ " Forward",
+ " Reverse",
+ " Help",
+ " Overview",
+ " Browse Documentation",
+ " About Animate",
+ " Image Info",
+ " Quit",
+ "",
+ " Menu items with a indented triangle have a sub-menu. They",
+ " are represented above as the indented items. To access a",
+ " sub-menu item, move the pointer to the appropriate menu and",
+ " press a button and drag. When you find the desired sub-menu",
+ " item, release the button and the command is executed. Move",
+ " the pointer away from the sub-menu if you decide not to",
+ " execute a particular command.",
+ "",
+ "KEYBOARD ACCELERATORS",
+ " Accelerators are one or two key presses that effect a",
+ " particular command. The keyboard accelerators that",
+ " animate(1) understands is:",
+ "",
+ " Ctl+O Press to open an image from a file.",
+ "",
+ " space Press to display the next image in the sequence.",
+ "",
+ " < Press to speed-up the display of the images. Refer to",
+ " -delay for more information.",
+ "",
+ " > Press to slow the display of the images. Refer to",
+ " -delay for more information.",
+ "",
+ " F1 Press to display helpful information about animate(1).",
+ "",
+ " Find Press to browse documentation about ImageMagick.",
+ "",
+ " ? Press to display information about the image. Press",
+ " any key or button to erase the information.",
+ "",
+ " This information is printed: image name; image size;",
+ " and the total number of unique colors in the image.",
+ "",
+ " Ctl-q Press to discard all images and exit program.",
+ (char *) NULL
+ };
+
+/*
+ Constant declarations.
+*/
+static const unsigned char
+ HighlightBitmap[8] =
+ {
+ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
+ },
+ ShadowBitmap[8] =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+/*
+ Enumeration declarations.
+*/
+typedef enum
+{
+ OpenCommand,
+ PlayCommand,
+ StepCommand,
+ RepeatCommand,
+ AutoReverseCommand,
+ SlowerCommand,
+ FasterCommand,
+ ForwardCommand,
+ ReverseCommand,
+ HelpCommand,
+ BrowseDocumentationCommand,
+ VersionCommand,
+ InfoCommand,
+ QuitCommand,
+ StepBackwardCommand,
+ StepForwardCommand,
+ NullCommand
+} CommandType;
+
+/*
+ Stipples.
+*/
+#define HighlightWidth 8
+#define HighlightHeight 8
+#define ShadowWidth 8
+#define ShadowHeight 8
+
+/*
+ Function prototypes.
+*/
+static Image
+ *MagickXMagickCommand(Display *,MagickXResourceInfo *,MagickXWindows *,const CommandType,
+ Image **,unsigned int *);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/annotate.c b/magick/annotate.c
new file mode 100644
index 0000000..f0fe124
--- /dev/null
+++ b/magick/annotate.c
@@ -0,0 +1,1923 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% AAA N N N N OOO TTTTT AAA TTTTT EEEEE %
+% A A NN N NN N O O T A A T E %
+% AAAAA N N N N N N O O T AAAAA T EEE %
+% A A N NN N NN O O T A A T E %
+% A A N N N N OOO T A A T EEEEE %
+% %
+% %
+% GraphicsMagick Image Annotation Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Digital Applications (www.digapp.com) contributed the stroked text algorithm.
+% It was written by Leonard Rosenthol.
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/analyze.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/composite.h"
+#include "magick/constitute.h"
+#include "magick/gem.h"
+#include "magick/log.h"
+#include "magick/pixel_cache.h"
+#include "magick/render.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#include "magick/xwindow.h"
+#if defined(HasTTF)
+
+# if defined(__MINGW32__)
+# undef interface /* Remove interface define */
+# endif
+
+# if defined(HAVE_FT2BUILD_H)
+ /*
+ Modern FreeType2 installs require that <ft2build.h> be included
+ before including other FreeType2 headers. Including
+ <ft2build.h> establishes definitions used by other FreeType2
+ headers.
+ */
+# include <ft2build.h>
+# include FT_FREETYPE_H
+# include FT_GLYPH_H
+# include FT_OUTLINE_H
+# include FT_BBOX_H
+# else
+ /*
+ Very old way to include FreeType2
+ */
+# include <freetype/freetype.h>
+# include <freetype/ftglyph.h>
+# include <freetype/ftoutln.h>
+# include <freetype/ftbbox.h>
+# endif /* defined(HAVE_FT2BUILD_H) */
+
+#endif /* defined(HasTTF) */
+
+/*
+ Forward declarations.
+*/
+typedef magick_int32_t magick_code_point_t;
+
+static unsigned int
+ RenderType(Image *,const DrawInfo *,const PointInfo *,TypeMetric *),
+ RenderPostscript(Image *,const DrawInfo *,const PointInfo *,TypeMetric *),
+ RenderFreetype(Image *,const DrawInfo *,const char *,const PointInfo *,
+ TypeMetric *),
+ RenderX11(Image *,const DrawInfo *,const PointInfo *,TypeMetric *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A n n o t a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AnnotateImage() annotates an image with text. Optionally you can include
+% any of the following bits of information about the image by embedding
+% the appropriate special characters:
+%
+% %b file size
+% %c comment
+% %d directory
+% %e filename extension
+% %f filename
+% %g page dimensions and offsets
+% %h height
+% %i input filename
+% %k number of unique colors
+% %l label
+% %m magick
+% %n number of scenes
+% %o output filename
+% %p page number
+% %q image bit depth
+% %r image type description
+% %s scene number
+% %t top of filename
+% %w width
+% %x horizontal resolution
+% %y vertical resolution
+% %A transparency supported
+% %C compression type
+% %D GIF disposal method
+% %G Original width and height
+% %H page height
+% %M original filename specification
+% %O page offset (x,y)
+% %P page dimensions (width,height)
+% %T time delay (in centi-seconds)
+% %U resolution units
+% %W page width
+% %X page horizontal offset (x)
+% %Y page vertical offset (y)
+% %@ trim bounding box
+% %[a] named attribute 'a'
+% %# signature
+% \n newline
+% \r carriage return
+% %% % (literal)
+%
+% The format of the AnnotateImage method is:
+%
+% unsigned int AnnotateImage(Image *image,DrawInfo *draw_info)
+%
+% A description of each parameter follows:
+%
+% o status: Method AnnotateImage returns True if the image is annotated
+% otherwise False.
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+%
+*/
+MagickExport MagickPassFail AnnotateImage(Image *image,const DrawInfo *draw_info)
+{
+ char
+ primitive[MaxTextExtent],
+ *text,
+ **textlist;
+
+ DrawInfo
+ *annotate,
+ *clone_info;
+
+ PointInfo
+ offset;
+
+ RectangleInfo
+ geometry;
+
+ register long
+ i;
+
+ size_t
+ length;
+
+ TypeMetric
+ metrics;
+
+ unsigned int
+ matte;
+
+ MagickPassFail
+ status=MagickPass;
+
+ unsigned long
+ height,
+ number_lines;
+
+ MagickBool
+ metrics_initialized = MagickFalse;
+
+ /*
+ Translate any embedded format characters (e.g. %f).
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(draw_info != (DrawInfo *) NULL);
+ assert(draw_info->signature == MagickSignature);
+ if (draw_info->text == (char *) NULL)
+ return(MagickFail);
+ if (*draw_info->text == '\0')
+ return(MagickPass);
+ text=TranslateText((ImageInfo *) NULL,image,draw_info->text);
+ if (text == (char *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToAnnotateImage);
+ textlist=StringToList(text);
+ MagickFreeMemory(text);
+ if (textlist == (char **) NULL)
+ return(MagickFail);
+ length=strlen(textlist[0]);
+ for (i=1; textlist[i] != (char *) NULL; i++)
+ if (strlen(textlist[i]) > length)
+ length=strlen(textlist[i]);
+ number_lines=i;
+ text=MagickAllocateMemory(char *,length+MaxTextExtent);
+ if (text == (char *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToAnnotateImage);
+ SetGeometry(image,&geometry);
+ if (draw_info->geometry != (char *) NULL)
+ (void) GetGeometry(draw_info->geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ annotate=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ matte=image->matte;
+ status=MagickPass;
+ for (i=0; textlist[i] != (char *) NULL; i++)
+ {
+ if (*textlist[i] == '\0')
+ continue;
+ /*
+ Position text relative to image.
+ */
+ (void) CloneString(&annotate->text,textlist[i]);
+ if ((!metrics_initialized) || (annotate->gravity != NorthWestGravity))
+ {
+ metrics_initialized=MagickTrue;
+ (void) GetTypeMetrics(image,annotate,&metrics);
+ }
+ height=(unsigned long) (metrics.ascent-metrics.descent);
+ switch (annotate->gravity)
+ {
+ case ForgetGravity:
+ case NorthWestGravity:
+ default:
+ {
+ offset.x=geometry.x+i*draw_info->affine.ry*height;
+ offset.y=geometry.y+i*draw_info->affine.sy*height;
+ break;
+ }
+ case NorthGravity:
+ {
+ offset.x=geometry.x+geometry.width/2+i*draw_info->affine.ry*height-
+ draw_info->affine.sx*metrics.width/2;
+ offset.y=geometry.y+i*draw_info->affine.sy*height-draw_info->affine.rx*
+ metrics.width/2;
+ break;
+ }
+ case NorthEastGravity:
+ {
+ offset.x=(geometry.width == 0 ? 1 : -1)*geometry.x+geometry.width+i*
+ draw_info->affine.ry*height-draw_info->affine.sx*metrics.width;
+ offset.y=geometry.y+i*draw_info->affine.sy*height-draw_info->affine.rx*
+ metrics.width;
+ break;
+ }
+ case WestGravity:
+ {
+ offset.x=geometry.x+i*draw_info->affine.ry*height+draw_info->affine.ry*
+ (metrics.ascent+metrics.descent-(number_lines-1)*height)/2;
+ offset.y=geometry.y+geometry.height/2+i*draw_info->affine.sy*height+
+ draw_info->affine.sy*(metrics.ascent+metrics.descent-(number_lines-1)*
+ height)/2;
+ break;
+ }
+ case StaticGravity:
+ case CenterGravity:
+ {
+ offset.x=geometry.x+geometry.width/2+i*draw_info->affine.ry*height-
+ draw_info->affine.sx*metrics.width/2+draw_info->affine.ry*
+ (metrics.ascent+metrics.descent-(number_lines-1)*height)/2;
+ offset.y=geometry.y+geometry.height/2+i*draw_info->affine.sy*height-
+ draw_info->affine.rx*metrics.width/2+draw_info->affine.sy*
+ (metrics.ascent+metrics.descent-(number_lines-1)*height)/2;
+ break;
+ }
+ case EastGravity:
+ {
+ offset.x=(geometry.width == 0 ? 1 : -1)*geometry.x+geometry.width+i*
+ draw_info->affine.ry*height-draw_info->affine.sx*metrics.width+
+ draw_info->affine.ry*(metrics.ascent+metrics.descent-(number_lines-1)*
+ height)/2;
+ offset.y=geometry.y+geometry.height/2+i*draw_info->affine.sy*height-
+ draw_info->affine.rx*metrics.width+draw_info->affine.sy*
+ (metrics.ascent+metrics.descent-(number_lines-1)*height)/2;
+ break;
+ }
+ case SouthWestGravity:
+ {
+ offset.x=geometry.x+i*draw_info->affine.ry*height-draw_info->affine.ry*
+ (number_lines-1)*height;
+ offset.y=(geometry.height == 0 ? 1 : -1)*geometry.y+geometry.height+i*
+ draw_info->affine.sy*height-draw_info->affine.sy*(number_lines-1)*
+ height;
+ break;
+ }
+ case SouthGravity:
+ {
+ offset.x=geometry.x+geometry.width/2+i*draw_info->affine.ry*
+ height-draw_info->affine.sx*metrics.width/2-
+ draw_info->affine.ry*(number_lines-1)*height;
+ offset.y=(geometry.height == 0 ? 1 : -1)*geometry.y+geometry.height+i*
+ draw_info->affine.sy*height-draw_info->affine.rx*
+ metrics.width/2-draw_info->affine.sy*(number_lines-1)*height;
+ break;
+ }
+ case SouthEastGravity:
+ {
+ offset.x=(geometry.width == 0 ? 1 : -1)*geometry.x+geometry.width+i*
+ draw_info->affine.ry*height-draw_info->affine.sx*metrics.width-
+ draw_info->affine.ry*(number_lines-1)*height;
+ offset.y=(geometry.height == 0 ? 1 : -1)*geometry.y+geometry.height+i*
+ draw_info->affine.sy*height-draw_info->affine.rx*metrics.width-
+ draw_info->affine.sy*(number_lines-1)*height;
+ break;
+ }
+ }
+ switch (annotate->align)
+ {
+ case LeftAlign:
+ {
+ offset.x=geometry.x+i*draw_info->affine.ry*height;
+ offset.y=geometry.y+i*draw_info->affine.sy*height;
+ break;
+ }
+ case CenterAlign:
+ {
+ offset.x=geometry.x+i*draw_info->affine.ry*height-draw_info->affine.sx*
+ metrics.width/2;
+ offset.y=geometry.y+i*draw_info->affine.sy*height-draw_info->affine.rx*
+ metrics.width/2;
+ break;
+ }
+ case RightAlign:
+ {
+ offset.x=geometry.x+i*draw_info->affine.ry*height-draw_info->affine.sx*
+ metrics.width;
+ offset.y=geometry.y+i*draw_info->affine.sy*height-draw_info->affine.rx*
+ metrics.width;
+ break;
+ }
+ default:
+ break;
+ }
+ if (draw_info->undercolor.opacity != TransparentOpacity)
+ {
+ /*
+ Text box.
+ */
+ clone_info->fill=draw_info->undercolor;
+ clone_info->affine.tx=offset.x-draw_info->affine.ry*(metrics.ascent-
+ metrics.max_advance/4);
+ clone_info->affine.ty=offset.y-draw_info->affine.sy*metrics.ascent;
+ FormatString(primitive,"rectangle 0,0 %g,%ld",metrics.width+
+ metrics.max_advance/2.0,height);
+ (void) CloneString(&clone_info->primitive,primitive);
+ (void) DrawImage(image,clone_info);
+ }
+ clone_info->affine.tx=offset.x;
+ clone_info->affine.ty=offset.y;
+ FormatString(primitive,"stroke-width %g line 0,0 %g,0",
+ metrics.underline_thickness,metrics.width);
+ if (annotate->decorate == OverlineDecoration)
+ {
+ clone_info->affine.ty-=(draw_info->affine.sy*
+ (metrics.ascent+metrics.descent)-metrics.underline_position);
+ (void) CloneString(&clone_info->primitive,primitive);
+ (void) DrawImage(image,clone_info);
+ }
+ else
+ if (annotate->decorate == UnderlineDecoration)
+ {
+ clone_info->affine.ty-=metrics.underline_position;
+ (void) CloneString(&clone_info->primitive,primitive);
+ (void) DrawImage(image,clone_info);
+ }
+ /*
+ Annotate image with text.
+ */
+ status=RenderType(image,annotate,&offset,&metrics);
+ if (status == MagickFail)
+ break;
+ if (annotate->decorate == LineThroughDecoration)
+ {
+ clone_info->affine.ty-=(draw_info->affine.sy*height+
+ metrics.underline_position)/2.0;
+ (void) CloneString(&clone_info->primitive,primitive);
+ (void) DrawImage(image,clone_info);
+ }
+ }
+ image->matte=matte;
+ /*
+ Free resources.
+ */
+ DestroyDrawInfo(clone_info);
+ DestroyDrawInfo(annotate);
+ MagickFreeMemory(text);
+ for (i=0; textlist[i] != (char *) NULL; i++)
+ MagickFreeMemory(textlist[i]);
+ MagickFreeMemory(textlist);
+ return(status);
+}
+
+#if defined(HasTTF)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ E n c o d e S J I S %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EncodeSJIS() converts an ASCII text string to 2-bytes per character code
+% (like UCS-2). Returns the translated codes and the character count.
+% Characters under 0x7f are just copied, characters over 0x80 are tied with
+% the next character.
+%
+% Katsutoshi Shibuya contributed this method.
+%
+% The format of the EncodeSJIS function is:
+%
+% encoding=EncodeSJIS(const char *text,size_t count)
+%
+% A description of each parameter follows:
+%
+% o encoding: EncodeSJIS() returns a pointer to an unsigned short
+% array representing the encoded version of the ASCII string.
+%
+% o text: The text.
+%
+% o count: return the number of characters generated by the encoding.
+%
+%
+*/
+
+static int GetOneCharacter(const unsigned char *text,size_t *length)
+{
+ unsigned int
+ c;
+
+ if (*length < 1)
+ return(-1);
+ c=text[0];
+ if (!(c & 0x80))
+ {
+ *length=1;
+ return((int) c);
+ }
+ if (*length < 2)
+ {
+ *length=0;
+ return(-1);
+ }
+ *length=2;
+ c=((int) (text[0]) << 8);
+ c|=text[1];
+ return((int) c);
+}
+
+static magick_code_point_t *EncodeSJIS(const char *text,size_t *count)
+{
+ int
+ c;
+
+ register const char
+ *p;
+
+ register magick_code_point_t
+ *q;
+
+ size_t
+ length;
+
+ magick_code_point_t
+ *encoding;
+
+ *count=0;
+ if ((text == (char *) NULL) || (*text == '\0'))
+ return((magick_code_point_t *) NULL);
+ encoding=MagickAllocateArray(magick_code_point_t *,
+ (strlen(text)+MaxTextExtent),
+ sizeof(magick_code_point_t));
+ if (encoding == (magick_code_point_t *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToConvertText);
+ q=encoding;
+ for (p=text; *p != '\0'; p+=length)
+ {
+ length=strlen(p);
+ c=GetOneCharacter((const unsigned char *) p,&length);
+ if (c < 0)
+ {
+ q=encoding;
+ for (p=text; *p != '\0'; p++)
+ *q++=(unsigned char) *p;
+ break;
+ }
+ *q=(magick_code_point_t) c;
+ q++;
+ }
+ *count=q-encoding;
+ return(encoding);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ E n c o d e T e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EncodeText() converts an ASCII text string to wide text and returns the
+% translation and the character count.
+%
+% The format of the EncodeText function is:
+%
+% encoding=EncodeText(const char *text,size_t count)
+%
+% A description of each parameter follows:
+%
+% o encoding: EncodeText() returns a pointer to an unsigned short array
+% array representing the encoded version of the ASCII string.
+%
+% o text: The text.
+%
+% o count: return the number of characters generated by the encoding.
+%
+%
+*/
+static magick_code_point_t *EncodeText(const char *text,size_t *count)
+{
+ register const char
+ *p;
+
+ register magick_code_point_t
+ *q;
+
+ magick_code_point_t
+ *encoding;
+
+ *count=0;
+ if ((text == (char *) NULL) || (*text == '\0'))
+ return((magick_code_point_t *) NULL);
+ encoding=MagickAllocateArray(magick_code_point_t *,
+ (strlen(text)+MaxTextExtent),
+ sizeof(magick_code_point_t));
+ if (encoding == (magick_code_point_t *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToConvertText);
+ q=encoding;
+ for (p=text; *p != '\0'; p++)
+ *q++=(unsigned char) *p;
+ *count=q-encoding;
+ return(encoding);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ E n c o d e U n i c o d e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EncodeUnicode() converts an ASCII text string to Unicode and returns the
+% Unicode translation and the character count. Characters under 0x7f are
+% just copied, characters over 0x80 are tied with the next character.
+%
+% The format of the EncodeUnicode function is:
+%
+% unicode=EncodeUnicode(const unsigned char *text,size_t count)
+%
+% A description of each parameter follows:
+%
+% o unicode: EncodeUnicode() returns a pointer to an unsigned short array
+% array representing the encoded version of the ASCII string.
+%
+% o text: The text.
+%
+% o count: return the number of characters generated by the encoding.
+%
+%
+*/
+static int GetUnicodeCharacter(const unsigned char *text,size_t *length)
+{
+ unsigned int
+ c;
+
+ if (*length < 1)
+ return(-1);
+ c=text[0];
+ if (!(c & 0x80))
+ {
+ *length=1;
+ return((int) c);
+ }
+ if ((*length < 2) || ((text[1] & 0xc0) != 0x80))
+ {
+ *length=0;
+ return(-1);
+ }
+ if ((c & 0xe0) != 0xe0)
+ {
+ *length=2;
+ c=(text[0] & 0x1f) << 6;
+ c|=text[1] & 0x3f;
+ return((int) c);
+ }
+ if ((*length < 3) || ((text[2] & 0xc0) != 0x80))
+ {
+ *length=0;
+ return(-1);
+ }
+ if ((c & 0xf0) != 0xf0)
+ {
+ *length=3;
+ c=(text[0] & 0xf) << 12;
+ c|=(text[1] & 0x3f) << 6;
+ c|=text[2] & 0x3f;
+ return((int) c);
+ }
+ if ((*length < 4) || ((c & 0xf8) != 0xf0) || ((text[3] & 0xc0) != 0x80))
+ {
+ *length=0;
+ return(-1);
+ }
+ *length=4;
+ c=(text[0] & 0x7) << 18;
+ c|=(text[1] & 0x3f) << 12;
+ c|=(text[2] & 0x3f) << 6;
+ c|=text[3] & 0x3f;
+ return((int) c);
+}
+
+static magick_code_point_t *EncodeUnicode(const char *text,size_t *count)
+{
+ int
+ c;
+
+ register const char
+ *p;
+
+ register magick_code_point_t
+ *q;
+
+ size_t
+ length;
+
+ magick_code_point_t
+ *unicode;
+
+ *count=0;
+ if ((text == (char *) NULL) || (*text == '\0'))
+ return((magick_code_point_t *) NULL);
+ unicode=MagickAllocateArray(magick_code_point_t *,
+ (strlen(text)+MaxTextExtent),
+ sizeof(magick_code_point_t));
+ if (unicode == (magick_code_point_t *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToConvertText);
+ q=unicode;
+ for (p=text; *p != '\0'; p+=length)
+ {
+ length=strlen(p);
+ c=GetUnicodeCharacter((const unsigned char *) p,&length);
+ if (c < 0)
+ {
+ q=unicode;
+ for (p=text; *p != '\0'; p++)
+ *q++=(unsigned char) *p;
+ break;
+ }
+ *q=(magick_code_point_t) c;
+ q++;
+ }
+ *count=q-unicode;
+ return(unicode);
+}
+
+#endif /* HasTTF */
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t T y p e M e t r i c s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetTypeMetrics() returns the following information for the specified font
+% and text:
+%
+% o character width
+% o character height
+% o ascent
+% o descent
+% o text width
+% o text height
+% o maximum horizontal advance
+% o underline position
+% o underline thickness
+%
+% The format of the GetTypeMetrics method is:
+%
+% unsigned int GetTypeMetrics(Image *image,const DrawInfo *draw_info,
+% TypeMetric *metrics)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o metrics: Return the font metrics in this structure.
+%
+%
+*/
+MagickExport MagickPassFail GetTypeMetrics(Image *image,const DrawInfo *draw_info,
+ TypeMetric *metrics)
+{
+ DrawInfo
+ *clone_info;
+
+ PointInfo
+ offset;
+
+ MagickPassFail
+ status;
+
+ assert(draw_info != (DrawInfo *) NULL);
+ assert(draw_info->text != (char *) NULL);
+ assert(draw_info->signature == MagickSignature);
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ clone_info->render=False;
+ (void) memset(metrics,0,sizeof(TypeMetric));
+ offset.x=0.0;
+ offset.y=0.0;
+ status=RenderType(image,clone_info,&offset,metrics);
+ DestroyDrawInfo(clone_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e n d e r T y p e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RenderType renders text on the image. It also returns the bounding
+% box of the text relative to the image.
+%
+% The format of the RenderType method is:
+%
+% unsigned int RenderType(Image *image,DrawInfo *draw_info,
+% const PointInfo *offset,TypeMetric *metrics)
+%
+% A description of each parameter follows:
+%
+% o status: Method RenderType returns True if the text is rendered on the
+% image, otherwise False.
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o offset: (x,y) location of text relative to image.
+%
+% o metrics: bounding box of text.
+%
+%
+*/
+static MagickPassFail RenderType(Image *image,const DrawInfo *draw_info,
+ const PointInfo *offset,TypeMetric *metrics)
+{
+ const TypeInfo
+ *type_info;
+
+ DrawInfo
+ *clone_info;
+
+ MagickPassFail
+ status;
+
+ type_info=(const TypeInfo *) NULL;
+ if (draw_info->font != (char *) NULL)
+ {
+ if (*draw_info->font == '@')
+ return(RenderFreetype(image,draw_info,(char *) NULL,offset,metrics));
+ if (*draw_info->font == '-')
+ return(RenderX11(image,draw_info,offset,metrics));
+ type_info=GetTypeInfo(draw_info->font,&image->exception);
+ if (type_info == (const TypeInfo *) NULL)
+ if (IsAccessible(draw_info->font))
+ return(RenderFreetype(image,draw_info,(char *) NULL,offset,metrics));
+ }
+ if (type_info == (const TypeInfo *) NULL)
+ type_info=GetTypeInfoByFamily(draw_info->family,draw_info->style,
+ draw_info->stretch,draw_info->weight,&image->exception);
+ if (type_info == (const TypeInfo *) NULL)
+ return(RenderPostscript(image,draw_info,offset,metrics));
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ if (type_info->glyphs != (char *) NULL)
+ (void) CloneString(&clone_info->font,type_info->glyphs);
+ status=RenderFreetype(image,clone_info,type_info->encoding,offset,metrics);
+ DestroyDrawInfo(clone_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e n d e r F r e e t y p e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RenderFreetype renders text on the image with a Truetype font. It
+% also returns the bounding box of the text relative to the image.
+%
+% The format of the RenderFreetype method is:
+%
+% unsigned int RenderFreetype(Image *image,DrawInfo *draw_info,
+% const char *encoding,const PointInfo *offset,TypeMetric *metrics)
+%
+% A description of each parameter follows:
+%
+% o status: Method RenderFreetype returns True if the text is rendered on the
+% image, otherwise False.
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o encoding: The font encoding.
+%
+% o offset: (x,y) location of text relative to image.
+%
+% o metrics: bounding box of text.
+%
+%
+*/
+
+#if defined(HasTTF)
+static int TraceCubicBezier(FT_Vector *p,FT_Vector *q,FT_Vector *to,
+ DrawInfo *draw_info)
+{
+ AffineMatrix
+ affine;
+
+ char
+ path[MaxTextExtent];
+
+ affine=draw_info->affine;
+ FormatString(path,"C%g,%g %g,%g %g,%g",affine.tx+p->x/64.0,
+ affine.ty-p->y/64.0,affine.tx+q->x/64.0,affine.ty-q->y/64.0,
+ affine.tx+to->x/64.0,affine.ty-to->y/64.0);
+ (void) ConcatenateString(&draw_info->primitive,path);
+ return(0);
+}
+
+static int TraceLineTo(FT_Vector *to,DrawInfo *draw_info)
+{
+ AffineMatrix
+ affine;
+
+ char
+ path[MaxTextExtent];
+
+ affine=draw_info->affine;
+ FormatString(path,"L%g,%g",affine.tx+to->x/64.0,affine.ty-to->y/64.0);
+ (void) ConcatenateString(&draw_info->primitive,path);
+ return(0);
+}
+
+static int TraceMoveTo(FT_Vector *to,DrawInfo *draw_info)
+{
+ AffineMatrix
+ affine;
+
+ char
+ path[MaxTextExtent];
+
+ affine=draw_info->affine;
+ FormatString(path,"M%g,%g",affine.tx+to->x/64.0,affine.ty-to->y/64.0);
+ (void) ConcatenateString(&draw_info->primitive,path);
+ return(0);
+}
+
+static int TraceQuadraticBezier(FT_Vector *control,FT_Vector *to,
+ DrawInfo *draw_info)
+{
+ AffineMatrix
+ affine;
+
+ char
+ path[MaxTextExtent];
+
+ affine=draw_info->affine;
+ FormatString(path,"Q%g,%g %g,%g",affine.tx+control->x/64.0,
+ affine.ty-control->y/64.0,affine.tx+to->x/64.0,affine.ty-to->y/64.0);
+ (void) ConcatenateString(&draw_info->primitive,path);
+ return(0);
+}
+
+static MagickPassFail RenderFreetype(Image *image,const DrawInfo *draw_info,
+ const char *encoding,const PointInfo *offset,TypeMetric *metrics)
+{
+ typedef struct _GlyphInfo
+ {
+ FT_UInt
+ id;
+
+ FT_Vector
+ origin;
+
+ FT_Glyph
+ image;
+ } GlyphInfo;
+
+ double
+ opacity;
+
+ DrawInfo
+ *clone_info;
+
+ FT_BBox
+ bounds;
+
+ FT_BitmapGlyph
+ bitmap;
+
+ FT_Encoding
+ encoding_type;
+
+ FT_Error
+ ft_status;
+
+ FT_Face
+ face;
+
+ FT_Library
+ library;
+
+ FT_Matrix
+ affine;
+
+ FT_Vector
+ origin;
+
+ GlyphInfo
+ glyph,
+ last_glyph;
+
+ Image
+ *pattern;
+
+ long
+ y;
+
+ PixelPacket
+ fill_color;
+
+ PointInfo
+ point,
+ resolution;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ size_t
+ length = 0;
+
+ static FT_Outline_Funcs
+ OutlineMethods =
+ {
+ (FT_Outline_MoveTo_Func) TraceMoveTo,
+ (FT_Outline_LineTo_Func) TraceLineTo,
+ (FT_Outline_ConicTo_Func) TraceQuadraticBezier,
+ (FT_Outline_CubicTo_Func) TraceCubicBezier,
+ 0, 0
+ };
+
+ MagickBool
+ active;
+
+ magick_code_point_t
+ *text;
+
+ MagickPassFail
+ status=MagickPass;
+
+ glyph.image=(FT_Glyph) 0;
+ last_glyph.image=(FT_Glyph) 0;
+
+ /*
+ Initialize Truetype library.
+ */
+ ft_status=FT_Init_FreeType(&library);
+ if (ft_status)
+ ThrowBinaryException(TypeError,UnableToInitializeFreetypeLibrary,
+ draw_info->font);
+ if (*draw_info->font != '@')
+ ft_status=FT_New_Face(library,draw_info->font,0,&face);
+ else
+ ft_status=FT_New_Face(library,draw_info->font+1,0,&face);
+ if (ft_status != 0)
+ {
+ (void) FT_Done_FreeType(library);
+ ThrowBinaryException(TypeError,UnableToReadFont,draw_info->font)
+ }
+ /*
+ Select a charmap
+ */
+ if (face->num_charmaps != 0)
+ /* ft_status= */ (void) FT_Set_Charmap(face,face->charmaps[0]);
+ encoding_type=ft_encoding_unicode;
+ ft_status=FT_Select_Charmap(face,encoding_type);
+ if (ft_status != 0)
+ {
+ encoding_type=ft_encoding_none;
+ /* ft_status= */ (void) FT_Select_Charmap(face,encoding_type);
+ }
+ if (encoding != (char *) NULL)
+ {
+ if (LocaleCompare(encoding,"AdobeCustom") == 0)
+ encoding_type=ft_encoding_adobe_custom;
+ if (LocaleCompare(encoding,"AdobeExpert") == 0)
+ encoding_type=ft_encoding_adobe_expert;
+ if (LocaleCompare(encoding,"AdobeStandard") == 0)
+ encoding_type=ft_encoding_adobe_standard;
+ if (LocaleCompare(encoding,"AppleRoman") == 0)
+ encoding_type=ft_encoding_apple_roman;
+ if (LocaleCompare(encoding,"BIG5") == 0)
+ encoding_type=ft_encoding_big5;
+ if (LocaleCompare(encoding,"GB2312") == 0)
+ encoding_type=ft_encoding_gb2312;
+#if defined(ft_encoding_johab)
+ if (LocaleCompare(encoding,"Johab") == 0)
+ encoding_type=ft_encoding_johab;
+#endif
+#if defined(ft_encoding_latin_1)
+ if (LocaleCompare(encoding,"Latin-1") == 0)
+ encoding_type=ft_encoding_latin_1;
+#endif
+#if defined(ft_encoding_latin_2)
+ if (LocaleCompare(encoding,"Latin-2") == 0)
+ encoding_type=ft_encoding_latin_2;
+#endif
+ if (LocaleCompare(encoding,"None") == 0)
+ encoding_type=ft_encoding_none;
+ if (LocaleCompare(encoding,"SJIScode") == 0)
+ encoding_type=ft_encoding_sjis;
+ if (LocaleCompare(encoding,"Symbol") == 0)
+ encoding_type=ft_encoding_symbol;
+ if (LocaleCompare(encoding,"Unicode") == 0)
+ encoding_type=ft_encoding_unicode;
+ if (LocaleCompare(encoding,"Wansung") == 0)
+ encoding_type=ft_encoding_wansung;
+ ft_status=FT_Select_Charmap(face,encoding_type);
+ if (ft_status != 0)
+ ThrowBinaryException(TypeError,UnrecognizedFontEncoding,encoding);
+ }
+ /*
+ Set text size.
+ */
+ resolution.x=72.0;
+ resolution.y=72.0;
+ if (draw_info->density != (char *) NULL)
+ {
+ i=GetMagickDimension(draw_info->density,&resolution.x,&resolution.y,NULL,NULL);
+ if (i != 2)
+ resolution.y=resolution.x;
+ }
+ (void) FT_Set_Char_Size(face,(FT_F26Dot6) (64.0*draw_info->pointsize),
+ (FT_F26Dot6) (64.0*draw_info->pointsize),(FT_UInt) resolution.x,
+ (FT_UInt) resolution.y);
+ metrics->pixels_per_em.x=face->size->metrics.x_ppem;
+ metrics->pixels_per_em.y=face->size->metrics.y_ppem;
+ metrics->ascent=(double) face->size->metrics.ascender/64.0;
+ metrics->descent=(double) face->size->metrics.descender/64.0;
+ metrics->width=0;
+ metrics->height=(double) face->size->metrics.height/64.0;
+ metrics->max_advance=(double) face->size->metrics.max_advance/64.0;
+ metrics->bounds.x1=0.0;
+ metrics->bounds.y1=metrics->descent;
+ metrics->bounds.x2=metrics->ascent+metrics->descent;
+ metrics->bounds.y2=metrics->ascent+metrics->descent;
+ metrics->underline_position=face->underline_position/64.0;
+ metrics->underline_thickness=face->underline_thickness/64.0;
+
+ /*
+ If the user-provided text string is NULL or empty, then nothing
+ more to do.
+ */
+ if ((draw_info->text == NULL) || (draw_info->text[0] == '\0'))
+ {
+ (void) FT_Done_Face(face);
+ (void) FT_Done_FreeType(library);
+ return status;
+ }
+
+ /*
+ Convert text to 4-byte format (supporting up to 21 code point
+ bits) as prescribed by the encoding.
+ */
+ switch (encoding_type)
+ {
+ case ft_encoding_sjis:
+ {
+ text=EncodeSJIS(draw_info->text,&length);
+ break;
+ }
+ case ft_encoding_unicode:
+ {
+ text=EncodeUnicode(draw_info->text,&length);
+ break;
+ }
+ default:
+ {
+ if (draw_info->encoding != (char *) NULL)
+ {
+ if (LocaleCompare(draw_info->encoding,"SJIS") == 0)
+ {
+ text=EncodeSJIS(draw_info->text,&length);
+ break;
+ }
+ if ((LocaleCompare(draw_info->encoding,"UTF-8") == 0) ||
+ (encoding_type != ft_encoding_none))
+ {
+ text=EncodeUnicode(draw_info->text,&length);
+ break;
+ }
+ }
+ text=EncodeText(draw_info->text,&length);
+ break;
+ }
+ }
+ if (text == (magick_code_point_t *) NULL)
+ {
+ (void) FT_Done_Face(face);
+ (void) FT_Done_FreeType(library);
+ (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),
+ "Text encoding failed: encoding_type=%ld "
+ "draw_info->encoding=\"%s\" draw_info->text=\"%s\" length=%ld",
+ (long) encoding_type,
+ (draw_info->encoding ? draw_info->encoding : "(null)"),
+ (draw_info->text ? draw_info->text : "(null)"),
+ (long) length);
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ draw_info->font)
+ }
+ /*
+ Compute bounding box.
+ */
+ (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),
+ "Font %.1024s; font-encoding %.1024s; text-encoding %.1024s; pointsize %g",
+ draw_info->font != (char *) NULL ? draw_info->font : "none",
+ encoding != (char *) NULL ? encoding : "none",
+ draw_info->encoding != (char *) NULL ? draw_info->encoding : "none",
+ draw_info->pointsize);
+ glyph.id=0;
+ last_glyph.id=0;
+ origin.x=0;
+ origin.y=0;
+ affine.xx=(FT_Fixed) (65536L*draw_info->affine.sx+0.5);
+ affine.yx=(FT_Fixed) (-65536L*draw_info->affine.rx+0.5);
+ affine.xy=(FT_Fixed) (-65536L*draw_info->affine.ry+0.5);
+ affine.yy=(FT_Fixed) (65536L*draw_info->affine.sy+0.5);
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ (void) QueryColorDatabase("#000000ff",&clone_info->fill,&image->exception);
+ (void) CloneString(&clone_info->primitive,"path '");
+ pattern=draw_info->fill_pattern;
+ for (i=0; i < (long) length; i++)
+ {
+ glyph.id=FT_Get_Char_Index(face,text[i]);
+ if ((glyph.id != 0) && (last_glyph.id != 0) && FT_HAS_KERNING(face))
+ {
+ FT_Vector
+ kerning;
+
+ (void) FT_Get_Kerning(face,last_glyph.id,glyph.id,ft_kerning_default,
+ &kerning);
+ origin.x+=kerning.x;
+ }
+ glyph.origin=origin;
+ glyph.image=0;
+ ft_status=FT_Load_Glyph(face,glyph.id,FT_LOAD_DEFAULT);
+ if (ft_status != False) /* 0 means success */
+ continue;
+ ft_status=FT_Get_Glyph(face->glyph,&glyph.image);
+ if (ft_status != False) /* 0 means success */
+ continue;
+#if 0
+ /*
+ Obtain glyph's control box. Usually faster than computing the
+ exact bounding box but may be slightly larger in some
+ situations.
+ */
+ (void) FT_Glyph_Get_CBox(glyph.image,FT_GLYPH_BBOX_SUBPIXELS,&bounds);
+#else
+ /*
+ Compute exact bounding box for scaled outline. If necessary, the
+ outline Bezier arcs are walked over to extract their extrema.
+ */
+ (void) FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,&bounds);
+#endif
+ if ((i == 0) || (bounds.xMin < metrics->bounds.x1))
+ metrics->bounds.x1=bounds.xMin;
+ if ((i == 0) || (bounds.yMin < metrics->bounds.y1))
+ metrics->bounds.y1=bounds.yMin;
+ if ((i == 0) || (bounds.xMax > metrics->bounds.x2))
+ metrics->bounds.x2=bounds.xMax;
+ if ((i == 0) || (bounds.yMax > metrics->bounds.y2))
+ metrics->bounds.y2=bounds.yMax;
+ if (draw_info->render)
+ if ((draw_info->stroke.opacity != TransparentOpacity) ||
+ (draw_info->stroke_pattern != (Image *) NULL))
+ {
+ /*
+ Trace the glyph.
+ */
+ clone_info->affine.tx=glyph.origin.x/64.0;
+ clone_info->affine.ty=glyph.origin.y/64.0;
+ (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->outline,
+ &OutlineMethods,clone_info);
+ }
+ FT_Vector_Transform(&glyph.origin,&affine);
+ (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin);
+ if (draw_info->render)
+ {
+ status &= ModifyCache(image,&image->exception);
+ if ((draw_info->fill.opacity != TransparentOpacity) ||
+ (pattern != (Image *) NULL))
+ {
+ /*
+ Rasterize the glyph.
+ */
+ ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal,
+ (FT_Vector *) NULL,True);
+ if (ft_status != False)
+ continue;
+ bitmap=(FT_BitmapGlyph) glyph.image;
+ image->storage_class=DirectClass;
+ if (bitmap->bitmap.pixel_mode == ft_pixel_mode_mono)
+ {
+ point.x=offset->x+(origin.x >> 6);
+ }
+ else
+ {
+ point.x=offset->x+bitmap->left;
+ }
+ point.y=offset->y-bitmap->top;
+ p=bitmap->bitmap.buffer;
+ /* FIXME: OpenMP */
+ for (y=0; y < (long) bitmap->bitmap.rows; y++)
+ {
+ int pc = y * bitmap->bitmap.pitch;
+ int pcr = pc;
+ if ((ceil(point.y+y-0.5) < 0) ||
+ (ceil(point.y+y-0.5) >= image->rows))
+ {
+ continue;
+ }
+ /*
+ Try to get whole span. May fail.
+ */
+ q=GetImagePixels(image,(long) ceil(point.x-0.5),
+ (long) ceil(point.y+y-0.5),bitmap->bitmap.width,1);
+ active=q != (PixelPacket *) NULL;
+ for (x=0; x < (long) bitmap->bitmap.width; x++, pc++)
+ {
+ if (((long) ceil(point.x+x-0.5) < 0) ||
+ ((unsigned long) ceil(point.x+x-0.5) >= image->columns))
+ {
+ if (active)
+ q++;
+ continue;
+ }
+ /* 8-bit gray-level pixmap */
+ if (bitmap->bitmap.pixel_mode == ft_pixel_mode_grays)
+ {
+ if (draw_info->text_antialias)
+ opacity=ScaleCharToQuantum(p[pc]);
+ else
+ opacity=(p[pc] < 127 ? OpaqueOpacity : TransparentOpacity);
+ }
+ /* 1-bit monochrome bitmap */
+ else if (bitmap->bitmap.pixel_mode == ft_pixel_mode_mono)
+ {
+ opacity=((p[(x >> 3) + pcr] & (1 << (~x & 0x07))) ?
+ TransparentOpacity : OpaqueOpacity);
+ }
+ else
+ {
+ continue; /* ignore it? */
+ }
+ fill_color=draw_info->fill;
+ if (pattern != (Image *) NULL)
+ {
+ if (AcquireOnePixelByReference
+ (pattern,&fill_color,
+ (long) (point.x+x-pattern->tile_info.x) % pattern->columns,
+ (long) (point.y+y-pattern->tile_info.y) % pattern->rows,
+ &image->exception) == MagickFail)
+ {
+ status=MagickFail;
+ }
+ }
+ /*
+ If not full span, then get one pixel.
+ */
+ if (!active)
+ q=GetImagePixels(image,(long) ceil(point.x+x-0.5),
+ (long) ceil(point.y+y-0.5),1,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ continue;
+ }
+ opacity=((MaxRGB-opacity)*(MaxRGB-fill_color.opacity))/MaxRGB;
+ AlphaCompositePixel(q,&fill_color,opacity,q,
+ image->matte ? q->opacity : OpaqueOpacity);
+ if (!active)
+ {
+ /*
+ Sync the one pixel
+ */
+ if (SyncImagePixels(image) != MagickPass)
+ status=MagickFail;
+ }
+ else
+ {
+ q++;
+ }
+ if (status == MagickFail)
+ break;
+ }
+ /*
+ Sync the full span
+ */
+ if (active)
+ if (SyncImagePixels(image) != MagickPass)
+ status=MagickFail;
+ if (status == MagickFail)
+ break;
+ }
+ }
+ }
+ origin.x+=face->glyph->advance.x;
+ if (origin.x > metrics->width)
+ metrics->width=origin.x;
+ if (last_glyph.id != 0)
+ FT_Done_Glyph(last_glyph.image);
+ last_glyph=glyph;
+ }
+ metrics->width/=64.0;
+ metrics->bounds.x1/=64.0;
+ metrics->bounds.y1/=64.0;
+ metrics->bounds.x2/=64.0;
+ metrics->bounds.y2/=64.0;
+ if ((status != MagickFail)&& (draw_info->render))
+ if ((draw_info->stroke.opacity != TransparentOpacity) ||
+ (draw_info->stroke_pattern != (Image *) NULL))
+ {
+ /*
+ Draw text stroke.
+ */
+ clone_info->affine.tx=offset->x;
+ clone_info->affine.ty=offset->y;
+ (void) ConcatenateString(&clone_info->primitive,"'");
+ (void) DrawImage(image,clone_info);
+ }
+ if (glyph.id != 0)
+ FT_Done_Glyph(glyph.image);
+ /*
+ Free resources.
+ */
+ MagickFreeMemory(text);
+ DestroyDrawInfo(clone_info);
+ (void) FT_Done_Face(face);
+ (void) FT_Done_FreeType(library);
+ return(status);
+}
+#else
+static unsigned int RenderFreetype(Image *image,const DrawInfo *draw_info,
+ const char *encoding,const PointInfo *offset,
+ TypeMetric *metrics)
+{
+ ThrowBinaryException(MissingDelegateError,FreeTypeLibraryIsNotAvailable,
+ draw_info->font);
+ ARG_NOT_USED(encoding);
+ ARG_NOT_USED(offset);
+ ARG_NOT_USED(metrics);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e n d e r P o s t s c r i p t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RenderPostscript renders text on the image with a Postscript font.
+% It also returns the bounding box of the text relative to the image.
+%
+% The format of the RenderPostscript method is:
+%
+% unsigned int RenderPostscript(Image *image,DrawInfo *draw_info,
+% const PointInfo *offset,TypeMetric *metrics)
+%
+% A description of each parameter follows:
+%
+% o status: Method RenderPostscript returns True if the text is rendered on
+% the image, otherwise False.
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o offset: (x,y) location of text relative to image.
+%
+% o metrics: bounding box of text.
+%
+%
+*/
+
+static char *EscapeParenthesis(const char *source)
+{
+ char
+ *destination;
+
+ register char
+ *q;
+
+ register const char
+ *p;
+
+ size_t
+ length;
+
+ assert(source != (const char *) NULL);
+
+ /*
+ Use dry-run method to compute required string length.
+ */
+ length=0;
+ for (p=source; *p; p++)
+ {
+ if ((*p == '(') || (*p == ')'))
+ length++;
+ length++;
+ }
+ destination=MagickAllocateMemory(char *,length+1);
+ if (destination == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToEscapeString);
+ *destination='\0';
+ q=destination;
+ for (p=source; *p; p++)
+ {
+ if ((*p == '(') || (*p == ')'))
+ *q++= '\\';
+ *q++=(*p);
+ }
+ *q=0;
+ return(destination);
+}
+
+static MagickPassFail RenderPostscript(Image *image,const DrawInfo *draw_info,
+ const PointInfo *offset,TypeMetric *metrics)
+{
+ char
+ filename[MaxTextExtent],
+ geometry[MaxTextExtent],
+ *text;
+
+ FILE
+ *file;
+
+ Image
+ *annotate_image,
+ *pattern;
+
+ ImageInfo
+ *clone_info;
+
+ long
+ y;
+
+ PointInfo
+ extent,
+ point,
+ resolution;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ identity;
+
+ /*
+ Render label with a Postscript font.
+ */
+ (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),
+ "Font %.1024s; pointsize %g",draw_info->font != (char *) NULL ?
+ draw_info->font : "none",draw_info->pointsize);
+ file=AcquireTemporaryFileStream(filename,BinaryFileIOMode);
+ if (file == (FILE *) NULL)
+ ThrowBinaryException(FileOpenError,UnableToCreateTemporaryFile,filename);
+ (void) fprintf(file,"%%!PS-Adobe-3.0\n");
+ (void) fprintf(file,"/ReencodeType\n");
+ (void) fprintf(file,"{\n");
+ (void) fprintf(file," findfont dup length\n");
+ (void) fprintf(file,
+ " dict begin { 1 index /FID ne {def} {pop pop} ifelse } forall\n");
+ (void) fprintf(file,
+ " /Encoding ISOLatin1Encoding def currentdict end definefont pop\n");
+ (void) fprintf(file,"} bind def\n");
+ /*
+ Sample to compute bounding box.
+ */
+ identity=(draw_info->affine.sx == draw_info->affine.sy) &&
+ (draw_info->affine.rx == 0.0) && (draw_info->affine.ry == 0.0);
+ extent.x=0.0;
+ extent.y=0.0;
+ for (i=0; i <= (long) (strlen(draw_info->text)+2); i++)
+ {
+ point.x=fabs(draw_info->affine.sx*i*draw_info->pointsize+
+ draw_info->affine.ry*2.0*draw_info->pointsize);
+ point.y=fabs(draw_info->affine.rx*i*draw_info->pointsize+
+ draw_info->affine.sy*2.0*draw_info->pointsize);
+ if (point.x > extent.x)
+ extent.x=point.x;
+ if (point.y > extent.y)
+ extent.y=point.y;
+ }
+ (void) fprintf(file,"%g %g moveto\n",identity ? 0.0 : extent.x/2.0,
+ extent.y/2.0);
+ (void) fprintf(file,"%g %g scale\n",draw_info->pointsize,
+ draw_info->pointsize);
+ if ((draw_info->font == (char *) NULL) || (*draw_info->font == '\0'))
+ (void) fprintf(file,
+ "/Times-Roman-ISO dup /Times-Roman ReencodeType findfont setfont\n");
+ else
+ (void) fprintf(file,
+ "/%.1024s-ISO dup /%.1024s ReencodeType findfont setfont\n",
+ draw_info->font,draw_info->font);
+ (void) fprintf(file,"[%g %g %g %g 0 0] concat\n",draw_info->affine.sx,
+ -draw_info->affine.rx,-draw_info->affine.ry,draw_info->affine.sy);
+ text=EscapeParenthesis(draw_info->text);
+ if (!identity)
+ (void) fprintf(file,"(%.1024s) stringwidth pop -0.5 mul -0.5 rmoveto\n",
+ text);
+ (void) fprintf(file,"(%.1024s) show\n",text);
+ MagickFreeMemory(text);
+ (void) fprintf(file,"showpage\n");
+ (void) fclose(file);
+ FormatString(geometry,"%ldx%ld+0+0!",(long) ceil(extent.x-0.5),
+ (long) ceil(extent.y-0.5));
+ clone_info=CloneImageInfo((ImageInfo *) NULL);
+ (void) FormatString(clone_info->filename,"ps:%.1024s",filename);
+ (void) CloneString(&clone_info->page,geometry);
+ if (draw_info->density != (char *) NULL)
+ (void) CloneString(&clone_info->density,draw_info->density);
+ clone_info->antialias=draw_info->text_antialias;
+ annotate_image=ReadImage(clone_info,&image->exception);
+ if (image->exception.severity != UndefinedException)
+ MagickError2(image->exception.severity,image->exception.reason,
+ image->exception.description);
+ DestroyImageInfo(clone_info);
+ (void) LiberateTemporaryFile(filename);
+ if (annotate_image == (Image *) NULL)
+ return(False);
+ resolution.x=72.0;
+ resolution.y=72.0;
+ if (draw_info->density != (char *) NULL)
+ {
+ int
+ count;
+
+ count=GetMagickDimension(draw_info->density,&resolution.x,&resolution.y,NULL,NULL);
+ if (count != 2)
+ resolution.y=resolution.x;
+ }
+ if (!identity)
+ TransformImage(&annotate_image,"0x0",(char *) NULL);
+ else
+ {
+ RectangleInfo
+ crop_info;
+
+ crop_info=GetImageBoundingBox(annotate_image,&annotate_image->exception);
+ crop_info.height=(unsigned long) ceil((resolution.y/72.0)*
+ ExpandAffine(&draw_info->affine)*draw_info->pointsize-0.5);
+ crop_info.y=(long) ceil((resolution.y/72.0)*extent.y/8.0-0.5);
+ (void) FormatString(geometry,"%lux%lu%+ld%+ld",crop_info.width,
+ crop_info.height,crop_info.x,crop_info.y);
+ TransformImage(&annotate_image,geometry,(char *) NULL);
+ }
+ metrics->pixels_per_em.x=(resolution.y/72.0)*
+ ExpandAffine(&draw_info->affine)*draw_info->pointsize;
+ metrics->pixels_per_em.y=metrics->pixels_per_em.x;
+ metrics->ascent=metrics->pixels_per_em.x;
+ metrics->descent=metrics->pixels_per_em.y/-5.0;
+ metrics->width=annotate_image->columns/ExpandAffine(&draw_info->affine);
+ metrics->height=1.152*metrics->pixels_per_em.x;
+ metrics->max_advance=metrics->pixels_per_em.x;
+ metrics->bounds.x1=0.0;
+ metrics->bounds.y1=metrics->descent;
+ metrics->bounds.x2=metrics->ascent+metrics->descent;
+ metrics->bounds.y2=metrics->ascent+metrics->descent;
+ metrics->underline_position=(-2.0);
+ metrics->underline_thickness=1.0;
+ if (!draw_info->render)
+ {
+ DestroyImage(annotate_image);
+ return(True);
+ }
+ if (draw_info->fill.opacity != TransparentOpacity)
+ {
+ PixelPacket
+ fill_color;
+
+ /*
+ Render fill color.
+ */
+ (void) SetImageType(annotate_image,TrueColorMatteType);
+ fill_color=draw_info->fill;
+ pattern=draw_info->fill_pattern;
+ for (y=0; y < (long) annotate_image->rows; y++)
+ {
+ q=GetImagePixels(annotate_image,0,y,annotate_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) annotate_image->columns; x++)
+ {
+ if (pattern != (Image *) NULL)
+ (void) AcquireOnePixelByReference(pattern,&fill_color,
+ (long) (x-pattern->tile_info.x) % pattern->columns,
+ (long) (y-pattern->tile_info.y) % pattern->rows,
+ &image->exception);
+ q->opacity=(Quantum) (MaxRGB-(((MaxRGB-(double)
+ PixelIntensityToQuantum(q))*(MaxRGB-fill_color.opacity))/
+ MaxRGB)+0.5);
+ q->red=fill_color.red;
+ q->green=fill_color.green;
+ q->blue=fill_color.blue;
+ q++;
+ }
+ if (!SyncImagePixels(annotate_image))
+ break;
+ }
+ (void) CompositeImage(image,OverCompositeOp,annotate_image,(long)
+ ceil(offset->x-0.5),(long) ceil(offset->y-(metrics->ascent+
+ metrics->descent)-0.5));
+ }
+ DestroyImage(annotate_image);
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e n d e r X 1 1 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RenderX11 renders text on the image with an X11 font. It also
+% returns the bounding box of the text relative to the image.
+%
+% The format of the RenderX11 method is:
+%
+% unsigned int RenderX11(Image *image,DrawInfo *draw_info,
+% const PointInfo *offset,TypeMetric *metrics)
+%
+% A description of each parameter follows:
+%
+% o status: Method RenderX11 returns True if the text is rendered on the
+% image, otherwise False.
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o offset: (x,y) location of text relative to image.
+%
+% o metrics: bounding box of text.
+%
+%
+*/
+#if defined(HasX11)
+static MagickPassFail RenderX11(Image *image,const DrawInfo *draw_info,
+ const PointInfo *offset,TypeMetric *metrics)
+{
+ static DrawInfo
+ cache_info;
+
+ static Display
+ *display = (Display *) NULL;
+
+ static MagickXAnnotateInfo
+ annotate_info;
+
+ static XFontStruct
+ *font_info;
+
+ static MagickXPixelInfo
+ pixel;
+
+ static MagickXResourceInfo
+ resource_info;
+
+ static XrmDatabase
+ resource_database;
+
+ static XStandardColormap
+ *map_info;
+
+ static XVisualInfo
+ *visual_info;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ height,
+ width;
+
+ if (display == (Display *) NULL)
+ {
+ const char
+ *client_name;
+
+ /*
+ Open X server connection.
+ */
+ display=XOpenDisplay(draw_info->server_name);
+ if (display == (Display *) NULL)
+ ThrowBinaryException(XServerError,UnableToOpenXServer,
+ draw_info->server_name);
+ /*
+ Get user defaults from X resource database.
+ */
+ (void) XSetErrorHandler(MagickXError);
+ client_name=GetClientName();
+ resource_database=MagickXGetResourceDatabase(display,client_name);
+ MagickXGetResourceInfo(resource_database,client_name,&resource_info);
+ resource_info.close_server=False;
+ resource_info.colormap=PrivateColormap;
+ resource_info.font=AllocateString(draw_info->font);
+ resource_info.background_color=AllocateString("#ffffffffffff");
+ resource_info.foreground_color=AllocateString("#000000000000");
+ map_info=XAllocStandardColormap();
+ if (map_info == (XStandardColormap *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToAllocateColormap);
+ /*
+ Initialize visual info.
+ */
+ visual_info=MagickXBestVisualInfo(display,map_info,&resource_info);
+ if (visual_info == (XVisualInfo *) NULL)
+ ThrowBinaryException(XServerError,UnableToGetVisual,
+ draw_info->server_name);
+ map_info->colormap=(Colormap) NULL;
+ pixel.pixels=(unsigned long *) NULL;
+ /*
+ Initialize Standard Colormap info.
+ */
+ MagickXGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen),
+ map_info);
+ MagickXGetPixelPacket(display,visual_info,map_info,&resource_info,
+ (Image *) NULL,&pixel);
+ pixel.annotate_context=XDefaultGC(display,visual_info->screen);
+ /*
+ Initialize font info.
+ */
+ font_info=MagickXBestFont(display,&resource_info,False);
+ if (font_info == (XFontStruct *) NULL)
+ ThrowBinaryException(XServerError,UnableToLoadFont,draw_info->font);
+ cache_info=(*draw_info);
+ }
+ /*
+ Initialize annotate info.
+ */
+ MagickXGetAnnotateInfo(&annotate_info);
+ annotate_info.stencil=ForegroundStencil;
+ if (cache_info.font != draw_info->font)
+ {
+ /*
+ Type name has changed.
+ */
+ (void) XFreeFont(display,font_info);
+ (void) CloneString(&resource_info.font,draw_info->font);
+ font_info=MagickXBestFont(display,&resource_info,False);
+ if (font_info == (XFontStruct *) NULL)
+ ThrowBinaryException(XServerError,UnableToLoadFont,draw_info->font);
+ }
+ (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),
+ "Font %.1024s; pointsize %g",draw_info->font != (char *) NULL ?
+ draw_info->font : "none",draw_info->pointsize);
+ cache_info=(*draw_info);
+ annotate_info.font_info=font_info;
+ annotate_info.text=(char *) draw_info->text;
+ annotate_info.width=XTextWidth(font_info,draw_info->text,
+ (int) strlen(draw_info->text));
+ annotate_info.height=font_info->ascent+font_info->descent;
+ metrics->pixels_per_em.x=font_info->max_bounds.width;
+ metrics->pixels_per_em.y=font_info->max_bounds.width;
+ metrics->ascent=font_info->ascent;
+ metrics->descent=(-font_info->descent);
+ metrics->width=annotate_info.width/ExpandAffine(&draw_info->affine);
+ metrics->height=metrics->pixels_per_em.x+4;
+ metrics->max_advance=font_info->max_bounds.width;
+ metrics->bounds.x1=0.0;
+ metrics->bounds.y1=metrics->descent;
+ metrics->bounds.x2=metrics->ascent+metrics->descent;
+ metrics->bounds.y2=metrics->ascent+metrics->descent;
+ metrics->underline_position=(-2.0);
+ metrics->underline_thickness=1.0;
+ if (!draw_info->render)
+ return(MagickPass);
+ if (draw_info->fill.opacity == TransparentOpacity)
+ return(MagickPass);
+ /*
+ Render fill color.
+ */
+ width=annotate_info.width;
+ height=annotate_info.height;
+ if ((draw_info->affine.rx != 0.0) || (draw_info->affine.ry != 0.0))
+ {
+ if (((draw_info->affine.sx-draw_info->affine.sy) == 0.0) &&
+ ((draw_info->affine.rx+draw_info->affine.ry) == 0.0))
+ annotate_info.degrees=(180.0/MagickPI)*
+ atan2(draw_info->affine.rx,draw_info->affine.sx);
+ }
+ FormatString(annotate_info.geometry,"%lux%lu+%ld+%ld",width,height,
+ (long) ceil(offset->x-0.5),
+ (long) ceil(offset->y-metrics->ascent-metrics->descent-0.5));
+ pixel.pen_color.red=ScaleQuantumToShort(draw_info->fill.red);
+ pixel.pen_color.green=ScaleQuantumToShort(draw_info->fill.green);
+ pixel.pen_color.blue=ScaleQuantumToShort(draw_info->fill.blue);
+ status=MagickXAnnotateImage(display,&pixel,&annotate_info,image);
+ if (status == 0)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToAnnotateImage);
+ return(MagickPass);
+}
+#else
+static MagickPassFail RenderX11(Image *image,const DrawInfo *draw_info,
+ const PointInfo *offset,TypeMetric *metrics)
+{
+ ARG_NOT_USED(offset);
+ ARG_NOT_USED(metrics);
+ ThrowBinaryException(MissingDelegateError,XWindowLibraryIsNotAvailable,
+ draw_info->font);
+}
+#endif
diff --git a/magick/api.h b/magick/api.h
new file mode 100644
index 0000000..6817c06
--- /dev/null
+++ b/magick/api.h
@@ -0,0 +1,125 @@
+/*
+ Copyright (C) 2003 - 2012 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Application Programming Interface declarations.
+
+*/
+
+#if !defined(_MAGICK_API_H)
+#define _MAGICK_API_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "magick/magick_config.h"
+#if defined(__cplusplus) || defined(c_plusplus)
+# undef inline
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h> /* POSIX 1990 header and declares size_t and ssize_t */
+
+/*
+ Note that the WIN32 and WIN64 definitions are provided by the build
+ configuration rather than the compiler. Definitions available from
+ the Windows compiler are _WIN32 and _WIN64.
+*/
+#if defined(WIN32) || defined(WIN64)
+# define MSWINDOWS
+#endif /* defined(WIN32) || defined(WIN64) */
+
+#if defined(MAGICK_IMPLEMENTATION)
+# if defined(MSWINDOWS)
+ /* Use Visual C++ C inline method extension to improve performance */
+# if !defined(inline) && !defined(__cplusplus) && !defined(c_plusplus)
+# define inline __inline
+# endif
+# endif
+#endif
+
+#if defined(PREFIX_MAGICK_SYMBOLS)
+# include "magick/symbols.h"
+#endif /* defined(PREFIX_MAGICK_SYMBOLS) */
+
+#include "magick/common.h"
+#include "magick/magick_types.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/average.h"
+#include "magick/blob.h"
+#include "magick/cdl.h"
+#include "magick/channel.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/command.h"
+#include "magick/compare.h"
+#include "magick/composite.h"
+#include "magick/compress.h"
+#include "magick/confirm_access.h"
+#include "magick/constitute.h"
+#include "magick/decorate.h"
+#include "magick/delegate.h"
+#include "magick/deprecate.h"
+#include "magick/describe.h"
+#include "magick/draw.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/error.h"
+#include "magick/fx.h"
+#include "magick/gem.h"
+#include "magick/gradient.h"
+#include "magick/hclut.h"
+#include "magick/image.h"
+#include "magick/list.h"
+#include "magick/log.h"
+#include "magick/magic.h"
+#include "magick/magick.h"
+#include "magick/memory.h"
+#include "magick/module.h"
+#include "magick/monitor.h"
+#include "magick/montage.h"
+#include "magick/operator.h"
+#include "magick/paint.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/plasma.h"
+#include "magick/profile.h"
+#include "magick/quantize.h"
+ /*#include "magick/random.h"*/
+#include "magick/registry.h"
+#include "magick/render.h"
+#include "magick/resize.h"
+#include "magick/resource.h"
+#include "magick/shear.h"
+#include "magick/signature.h"
+#include "magick/statistics.h"
+#include "magick/texture.h"
+#include "magick/timer.h"
+#include "magick/transform.h"
+#include "magick/type.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_API_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/attribute.c b/magick/attribute.c
new file mode 100644
index 0000000..9a77c11
--- /dev/null
+++ b/magick/attribute.c
@@ -0,0 +1,3041 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% AAA TTTTT TTTTT RRRR IIIII BBBB U U TTTTT EEEEE %
+% A A T T R R I B B U U T E %
+% AAAAA T T RRRR I BBBB U U T EEE %
+% A A T T R R I B B U U T E %
+% A A T T R R IIIII BBBB UUU T EEEEE %
+% %
+% %
+% Methods to Get/Set/Destroy Image Text Attributes %
+% %
+% %
+% Software Design %
+% John Cristy %
+% February 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The Attributes methods gets, sets, or destroys attributes associated
+% with a particular image (e.g. comments, copyright, author, etc).
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/profile.h"
+#include "magick/render.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+static void DestroyImageAttribute(ImageAttribute *attribute);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e I m a g e A t t r i b u t e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneImageAttributes() copies the text attibutes from one image to another.
+% Any text attributes in the destination image are preserved.
+% CloneImageAttributes returns MagickPass if all of the attribututes are
+% successfully cloned or MagickFail if there is a memory allocation error.
+%
+% The format of the CloneImageAttributes method is:
+%
+% MagickPassFail CloneImageAttributes(Image* clone_image,
+% const Image* original_image)
+%
+% A description of each parameter follows:
+%
+% o clone_image: The destination image.
+%
+% o original_image: The source image.
+%
+%
+*/
+MagickExport MagickPassFail
+CloneImageAttributes(Image* clone_image,
+ const Image* original_image)
+{
+ MagickPassFail
+ status;
+
+ ImageAttribute
+ *cloned_attribute,
+ *cloned_attributes;
+
+ const ImageAttribute
+ *attribute;
+
+ status = MagickPass;
+
+ /*
+ Search for tail of list (if any)
+ */
+ for(cloned_attributes=clone_image->attributes;
+ cloned_attributes != (ImageAttribute *) NULL;
+ cloned_attributes=cloned_attributes->next);
+
+ attribute=GetImageAttribute(original_image,(char *) NULL);
+ for ( ; attribute != (const ImageAttribute *) NULL;
+ attribute=attribute->next)
+ {
+ /*
+ Construct AttributeInfo to append.
+ */
+ cloned_attribute=MagickAllocateMemory(ImageAttribute *,
+ sizeof(ImageAttribute));
+ if (cloned_attribute == (ImageAttribute *) NULL)
+ {
+ status = MagickFail;
+ break;
+ }
+ cloned_attribute->key=AcquireString(attribute->key);
+ cloned_attribute->length=attribute->length;
+ cloned_attribute->value=
+ MagickAllocateMemory(char *,cloned_attribute->length+1);
+ cloned_attribute->previous=(ImageAttribute *) NULL;
+ cloned_attribute->next=(ImageAttribute *) NULL;
+ if ((cloned_attribute->value == (char *) NULL) ||
+ (cloned_attribute->key == (char *) NULL))
+ {
+ DestroyImageAttribute(cloned_attribute);
+ status = MagickFail;
+ break;
+ }
+ strcpy(cloned_attribute->value,attribute->value);
+
+ if (cloned_attributes == (ImageAttribute *) NULL)
+ {
+ /*
+ Start list
+ */
+ cloned_attributes=cloned_attribute;
+ clone_image->attributes=cloned_attributes;
+ }
+ else
+ {
+ /*
+ Append to list
+ */
+ cloned_attributes->next=cloned_attribute;
+ cloned_attribute->previous=cloned_attributes;
+ cloned_attributes=cloned_attribute;
+ }
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y I m a g e A t t r i b u t e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyImageAttributes() deallocates memory associated with the image
+% attribute list.
+%
+% The format of the DestroyImageAttributes method is:
+%
+% DestroyImageAttributes(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+static void
+DestroyImageAttribute(ImageAttribute *attribute)
+{
+ if (attribute == (ImageAttribute *) NULL)
+ return;
+ MagickFreeMemory(attribute->value);
+ MagickFreeMemory(attribute->key);
+ (void) memset(attribute,0xbf,sizeof(ImageAttribute));
+ MagickFreeMemory(attribute);
+}
+MagickExport void DestroyImageAttributes(Image *image)
+{
+ ImageAttribute
+ *attribute;
+
+ register ImageAttribute
+ *p;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ for (p=image->attributes; p != (ImageAttribute *) NULL; )
+ {
+ attribute=p;
+ p=p->next;
+ DestroyImageAttribute(attribute);
+ }
+ image->attributes=(ImageAttribute *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e A t t r i b u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageAttribute() searches the list of image attributes and returns
+% a pointer to the attribute if it exists otherwise NULL.
+%
+% The format of the GetImageAttribute method is:
+%
+% const ImageAttribute *GetImageAttribute(const Image *image,
+% const char *key)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o key: These character strings are the name of an image attribute to
+% return.
+%
+%
+*/
+
+static unsigned int
+GenerateIPTCAttribute(Image *image,const char *key)
+{
+#if 0
+ static const struct
+ {
+ char *name;
+ int dataset;
+ int record;
+ }
+#define IPTC_ATTRIBUTE(dataset,record,name) {name,dataset,record}
+ IPTCAttributes[] =
+ {
+ IPTC_ATTRIBUTE(2,5,"Image Name"),
+ IPTC_ATTRIBUTE(2,7,"Edit Status"),
+ IPTC_ATTRIBUTE(2,10,"Priority"),
+ IPTC_ATTRIBUTE(2,15,"Category"),
+ IPTC_ATTRIBUTE(2,20,"Supplemental Category"),
+ IPTC_ATTRIBUTE(2,22,"Fixture Identifier"),
+ IPTC_ATTRIBUTE(2,25,"Keyword"),
+ IPTC_ATTRIBUTE(2,30,"Release Date"),
+ IPTC_ATTRIBUTE(2,35,"Release Time"),
+ IPTC_ATTRIBUTE(2,40,"Special Instructions"),
+ IPTC_ATTRIBUTE(2,45,"Reference Service"),
+ IPTC_ATTRIBUTE(2,47,"Reference Date"),
+ IPTC_ATTRIBUTE(2,50,"Reference Number"),
+ IPTC_ATTRIBUTE(2,55,"Created Date"),
+ IPTC_ATTRIBUTE(2,60,"Created Time"),
+ IPTC_ATTRIBUTE(2,65,"Originating Program"),
+ IPTC_ATTRIBUTE(2,70,"Program Version"),
+ IPTC_ATTRIBUTE(2,75,"Object Cycle"),
+ IPTC_ATTRIBUTE(2,80,"Byline"),
+ IPTC_ATTRIBUTE(2,85,"Byline Title"),
+ IPTC_ATTRIBUTE(2,90,"City"),
+ IPTC_ATTRIBUTE(2,95,"Province State"),
+ IPTC_ATTRIBUTE(2,100,"Country Code"),
+ IPTC_ATTRIBUTE(2,101,"Country"),
+ IPTC_ATTRIBUTE(2,103,"Original Transmission Reference"),
+ IPTC_ATTRIBUTE(2,105,"Headline"),
+ IPTC_ATTRIBUTE(2,110,"Credit"),
+ IPTC_ATTRIBUTE(2,115,"Source"),
+ IPTC_ATTRIBUTE(2,116,"Copyright String"),
+ IPTC_ATTRIBUTE(2,120,"Caption"),
+ IPTC_ATTRIBUTE(2,121,"Local Caption"),
+ IPTC_ATTRIBUTE(2,122,"Caption Writer"),
+ IPTC_ATTRIBUTE(2,200,"Custom Field 1"),
+ IPTC_ATTRIBUTE(2,201,"Custom Field 2"),
+ IPTC_ATTRIBUTE(2,202,"Custom Field 3"),
+ IPTC_ATTRIBUTE(2,203,"Custom Field 4"),
+ IPTC_ATTRIBUTE(2,204,"Custom Field 5"),
+ IPTC_ATTRIBUTE(2,205,"Custom Field 6"),
+ IPTC_ATTRIBUTE(2,206,"Custom Field 7"),
+ IPTC_ATTRIBUTE(2,207,"Custom Field 8"),
+ IPTC_ATTRIBUTE(2,208,"Custom Field 9"),
+ IPTC_ATTRIBUTE(2,209,"Custom Field 10"),
+ IPTC_ATTRIBUTE(2,210,"Custom Field 11"),
+ IPTC_ATTRIBUTE(2,211,"Custom Field 12"),
+ IPTC_ATTRIBUTE(2,212,"Custom Field 13"),
+ IPTC_ATTRIBUTE(2,213,"Custom Field 14"),
+ IPTC_ATTRIBUTE(2,214,"Custom Field 15"),
+ IPTC_ATTRIBUTE(2,215,"Custom Field 16"),
+ IPTC_ATTRIBUTE(2,216,"Custom Field 17"),
+ IPTC_ATTRIBUTE(2,217,"Custom Field 18"),
+ IPTC_ATTRIBUTE(2,218,"Custom Field 19"),
+ IPTC_ATTRIBUTE(2,219,"Custom Field 20")
+ };
+#endif
+
+ char
+ *attribute;
+
+ int
+ count,
+ dataset,
+ record;
+
+ register long
+ i;
+
+ size_t
+ length;
+
+ const unsigned char
+ *profile;
+
+ size_t
+ profile_length;
+
+ if((profile=GetImageProfile(image,"IPTC",&profile_length)) == 0)
+ return(False);
+ count=sscanf(key,"IPTC:%d:%d",&dataset,&record);
+ if (count != 2)
+ return(False);
+ for (i=0; i < (long) profile_length; i++)
+ {
+ if (profile[i] != 0x1cU)
+ continue;
+ if (profile[i+1] != dataset)
+ {
+ /* fprintf(stderr,"Skipping dataset %d\n",profile[i+1]); */
+ continue;
+ }
+ if (profile[i+2] != record)
+ {
+ /* fprintf(stderr,"Skipping record %d\n",profile[i+2]); */
+ continue;
+ }
+ length=profile[i+3] << 8;
+ length|=profile[i+4];
+ attribute=MagickAllocateMemory(char *,length+1);
+ if (attribute == (char *) NULL)
+ continue;
+ (void) strlcpy(attribute,(char *) profile+i+5,length+1);
+ (void) SetImageAttribute(image,key,(const char *) attribute);
+ MagickFreeMemory(attribute);
+ break;
+ }
+ return(i < (long) profile_length);
+}
+
+static unsigned char
+ReadByte(unsigned char **p,size_t *length)
+{
+ unsigned char
+ c;
+
+ if (*length < 1)
+ return(0xff);
+ c=(*(*p)++);
+ (*length)--;
+ return(c);
+}
+
+static long
+ReadMSBLong(unsigned char **p,size_t *length)
+{
+ int
+ c;
+
+ union
+ {
+ magick_uint32_t u;
+ magick_int32_t s;
+ } value;
+
+ register unsigned int
+ i;
+
+ unsigned char
+ buffer[4];
+
+ if (*length < 4)
+ return(-1);
+ for (i=0; i < 4; i++)
+ {
+ c=(*(*p)++);
+ (*length)--;
+ buffer[i]=(unsigned char) c;
+ }
+ value.u=(buffer[0] & 0xff) << 24;
+ value.u|=buffer[1] << 16;
+ value.u|=buffer[2] << 8;
+ value.u|=buffer[3];
+ return(value.s);
+}
+
+static int
+ReadMSBShort(unsigned char **p,size_t *length)
+{
+ int
+ c;
+
+ union
+ {
+ magick_uint32_t u;
+ magick_int32_t s;
+ } value;
+
+ register unsigned int
+ i;
+
+ unsigned char
+ buffer[2];
+
+ if (*length < 2)
+ return(-1);
+ for (i=0; i < 2; i++)
+ {
+ c=(*(*p)++);
+ (*length)--;
+ buffer[i]=(unsigned char) c;
+ }
+ value.u=(buffer[0] & 0xff) << 8;
+ value.u|=buffer[1];
+ return(value.s);
+}
+
+/*
+ FIXME: length is defined as type size_t, and then code incorrectly
+ assumes that size_t is a signed type
+*/
+static char *
+TracePSClippingPath(unsigned char *blob,size_t length,
+ unsigned long columns,
+ unsigned long rows)
+{
+ char
+ *path,
+ *message;
+
+ int
+ knot_count,
+ selector;
+
+ long
+ x,
+ y;
+
+ PointInfo
+ first[3], /* First Bezier knot in sub-path */
+ last[3], /* Last seen Bezier knot in sub-path */
+ point[3]; /* Current Bezier knot in sub-path */
+
+ register long
+ i;
+
+ unsigned int
+ in_subpath;
+
+ ARG_NOT_USED(columns);
+ ARG_NOT_USED(rows);
+
+ first[0].x=first[0].y=first[1].x=first[1].y=0;
+ last[1].x=last[1].y=last[2].x=last[2].y=0;
+ path=AllocateString((char *) NULL);
+ if (path == (char *) NULL)
+ return((char *) NULL);
+ message=AllocateString((char *) NULL);
+
+ FormatString(message,"/ClipImage {\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"/c {curveto} bind def\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"/l {lineto} bind def\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"/m {moveto} bind def\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"/v {currentpoint 6 2 roll curveto} bind def\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"/y {2 copy curveto} bind def\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"/z {closepath} bind def\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"newpath\n");
+ (void) ConcatenateString(&path,message);
+
+ knot_count=0;
+ in_subpath=False;
+
+ /*
+ Open and closed subpaths are all closed in the following
+ parser loop as there's no way for the polygon renderer
+ to render an open path to a masking image.
+
+ The clipping path format is defined in "Adobe Photoshop File
+ Formats Specification" version 6.0 downloadable from adobe.com.
+ */
+ while (length > 0)
+ {
+ selector=ReadMSBShort(&blob,&length);
+ switch (selector)
+ {
+ case 0:
+ case 3:
+ {
+ if (knot_count == 0)
+ {
+ /*
+ Expected subpath length record
+ */
+ knot_count=ReadMSBShort(&blob,&length);
+ blob+=22;
+ length-=22;
+ }
+ else
+ {
+ blob+=24;
+ length-=24;
+ }
+ break;
+ }
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ {
+ if (knot_count == 0)
+ {
+ /*
+ Unexpected subpath knot
+ */
+ blob+=24;
+ length-=24;
+ }
+ else
+ {
+ /*
+ Add sub-path knot
+ */
+ for (i=0; i < 3; i++)
+ {
+ y=ReadMSBLong(&blob,&length);
+ x=ReadMSBLong(&blob,&length);
+ point[i].x=(double) x/4096/4096;
+ point[i].y=1.0-(double) y/4096/4096;
+ }
+ if (!in_subpath)
+ {
+ FormatString(message,"%.6f %.6f m\n",
+ point[1].x,point[1].y);
+ for (i=0; i < 3; i++)
+ {
+ first[i]=point[i];
+ last[i]=point[i];
+ }
+ }
+ else
+ {
+ /*
+ Handle special cases when Bezier curves are used
+ to describe corners and straight lines. This
+ special handling is desirable to bring down the
+ size in bytes of the clipping path data.
+ */
+ if ((last[1].x == last[2].x) &&
+ (last[1].y == last[2].y) &&
+ (point[0].x == point[1].x) &&
+ (point[0].y == point[1].y))
+ {
+ /*
+ First control point equals first anchor
+ point and last control point equals last
+ anchow point. Straigt line between anchor
+ points.
+ */
+ FormatString(message,"%.6f %.6f l\n",
+ point[1].x,point[1].y);
+ }
+ else if ((last[1].x == last[2].x) &&
+ (last[1].y == last[2].y))
+ {
+ /* First control point equals first anchor point */
+ FormatString(message,"%.6f %.6f %.6f %.6f v\n",
+ point[0].x,point[0].y,
+ point[1].x,point[1].y);
+ }
+ else if ((point[0].x == point[1].x) &&
+ (point[0].y == point[1].y))
+ {
+ /* Last control point equals last anchow point. */
+ FormatString(message,"%.6f %.6f %.6f %.6f y\n",
+ last[2].x,last[2].y,
+ point[1].x,point[1].y);
+ }
+ else
+ {
+ /* The full monty */
+ FormatString(message,
+ "%.6f %.6f %.6f %.6f %.6f %.6f c\n",
+ last[2].x,last[2].y,point[0].x,
+ point[0].y,point[1].x,
+ point[1].y);
+ }
+ for (i=0; i < 3; i++)
+ last[i]=point[i];
+ }
+ (void) ConcatenateString(&path,message);
+ in_subpath=True;
+ knot_count--;
+ /*
+ Close the subpath if there are no more knots.
+ */
+ if (knot_count == 0)
+ {
+ /*
+ Same special handling as above except we compare
+ to the first point in the path and close the
+ path.
+ */
+ if ((last[1].x == last[2].x) &&
+ (last[1].y == last[2].y) &&
+ (first[0].x == first[1].x) &&
+ (first[0].y == first[1].y))
+ {
+ FormatString(message,"%.6f %.6f l z\n",
+ first[1].x,first[1].y);
+ }
+ else if ((last[1].x == last[2].x) &&
+ (last[1].y == last[2].y))
+ {
+ FormatString(message,"%.6f %.6f %.6f %.6f v z\n",
+ first[0].x,first[0].y,
+ first[1].x,first[1].y);
+ }
+ else if ((first[0].x == first[1].x) &&
+ (first[0].y == first[1].y))
+ {
+ FormatString(message,"%.6f %.6f %.6f %.6f y z\n",
+ last[2].x,last[2].y,
+ first[1].x,first[1].y);
+ }
+ else
+ {
+ FormatString(message,
+ "%.6f %.6f %.6f %.6f %.6f %.6f c z\n",
+ last[2].x,last[2].y,
+ first[0].x,first[0].y,
+ first[1].x,first[1].y);
+ }
+ (void) ConcatenateString(&path,message);
+ in_subpath=False;
+ }
+ }
+ break;
+ }
+ case 6:
+ case 7:
+ case 8:
+ default:
+ {
+ blob+=24;
+ length-=24;
+ break;
+ }
+ }
+ }
+ /*
+ Returns an empty PS path if the path has no knots.
+ */
+ FormatString(message,"eoclip\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"} bind def");
+ (void) ConcatenateString(&path,message);
+ MagickFreeMemory(message);
+ return(path);
+}
+
+/*
+ FIXME: length is defined as type size_t, and then code incorrectly
+ assumes that size_t is a signed type.
+*/
+static char *
+TraceSVGClippingPath(unsigned char *blob,size_t length,
+ unsigned long columns,unsigned long rows)
+{
+ char
+ *path,
+ *message;
+
+ int
+ knot_count,
+ selector;
+
+ long
+ x,
+ y;
+
+ PointInfo
+ first[3],
+ last[3],
+ point[3];
+
+ register long
+ i;
+
+ unsigned int
+ in_subpath;
+
+ first[0].x=first[0].y=first[1].x=first[1].y=0;
+ last[1].x=last[1].y=last[2].x=last[2].y=0;
+ path=AllocateString((char *) NULL);
+ if (path == (char *) NULL)
+ return((char *) NULL);
+ message=AllocateString((char *) NULL);
+
+ FormatString(message,"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"<svg width=\"%lu\" height=\"%lu\">\n",columns,rows);
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"<g>\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"<path style=\"fill:#00000000;stroke:#00000000;");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"stroke-width:0;stroke-antialiasing:false\" d=\"\n");
+ (void) ConcatenateString(&path,message);
+
+ knot_count=0;
+ in_subpath=False;
+
+ /*
+ Open and closed subpaths are all closed in the following parser
+ loop as there's no way for the polygon renderer to render an open
+ path to a masking image.
+
+ The clipping path format is defined in "Adobe Photoshop File
+ Formats Specification" version 6.0 downloadable from adobe.com.
+ */
+ while (length > 0)
+ {
+ selector=ReadMSBShort(&blob,&length);
+ switch (selector)
+ {
+ case 0:
+ case 3:
+ {
+ if (knot_count == 0)
+ {
+ /*
+ Expected subpath length record
+ */
+ knot_count=ReadMSBShort(&blob,&length);
+ blob+=22;
+ length-=22;
+ }
+ else
+ {
+ blob+=24;
+ length-=24;
+ }
+ break;
+ }
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ {
+ if (knot_count == 0)
+ {
+ /*
+ Unexpected subpath knot
+ */
+ blob+=24;
+ length-=24;
+ }
+ else
+ {
+ /*
+ Add sub-path knot
+ */
+ for (i=0; i < 3; i++)
+ {
+ y=ReadMSBLong(&blob,&length);
+ x=ReadMSBLong(&blob,&length);
+ point[i].x=(double) x*columns/4096/4096;
+ point[i].y=(double) y*rows/4096/4096;
+ }
+ if (!in_subpath)
+ {
+ FormatString(message,"M %.6f,%.6f\n",
+ point[1].x,point[1].y);
+ for (i=0; i < 3; i++)
+ {
+ first[i]=point[i];
+ last[i]=point[i];
+ }
+ }
+ else
+ {
+ /*
+ Handle special case when Bezier curves are used
+ to describe straight lines.
+ */
+ if ((last[1].x == last[2].x) &&
+ (last[1].y == last[2].y) &&
+ (point[0].x == point[1].x) &&
+ (point[0].y == point[1].y))
+ {
+ /*
+ First control point equals first anchor
+ point and last control point equals last
+ anchow point. Straigt line between anchor
+ points.
+ */
+ FormatString(message,"L %.6f,%.6f\n",
+ point[1].x,point[1].y);
+ }
+ else
+ {
+ FormatString(message,
+ "C %.6f,%.6f %.6f,%.6f %.6f,%.6f\n",
+ last[2].x,last[2].y,
+ point[0].x,point[0].y,
+ point[1].x,point[1].y);
+ }
+ for (i=0; i < 3; i++)
+ last[i]=point[i];
+ }
+ (void) ConcatenateString(&path,message);
+ in_subpath=True;
+ knot_count--;
+ /*
+ Close the subpath if there are no more knots.
+ */
+ if (knot_count == 0)
+ {
+ /*
+ Same special handling as above except we compare
+ to the first point in the path and close the
+ path.
+ */
+ if ((last[1].x == last[2].x) &&
+ (last[1].y == last[2].y) &&
+ (first[0].x == first[1].x) &&
+ (first[0].y == first[1].y))
+ {
+ FormatString(message,
+ "L %.6f,%.6f Z\n",first[1].x,first[1].y);
+ }
+ else
+ {
+ FormatString(message,
+ "C %.6f,%.6f %.6f,%.6f %.6f,%.6f Z\n",
+ last[2].x,last[2].y,
+ first[0].x,first[0].y,
+ first[1].x,first[1].y);
+ (void) ConcatenateString(&path,message);
+ }
+ in_subpath=False;
+ }
+ }
+ break;
+ }
+ case 6:
+ case 7:
+ case 8:
+ default:
+ {
+ blob+=24;
+ length-=24;
+ break;
+ }
+ }
+ }
+ /*
+ Returns an empty SVG image if the path has no knots.
+ */
+ FormatString(message,"\"/>\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"</g>\n");
+ (void) ConcatenateString(&path,message);
+ FormatString(message,"</svg>\n");
+ (void) ConcatenateString(&path,message);
+ MagickFreeMemory(message);
+ return(path);
+}
+
+static int
+Generate8BIMAttribute(Image *image,const char *key)
+{
+ char
+ *attribute,
+ name[MaxTextExtent],
+ format[MaxTextExtent],
+ *resource;
+
+ int
+ id,
+ start,
+ stop,
+ sub_number;
+
+ register long
+ i;
+
+ size_t
+ length;
+
+ unsigned char
+ *info;
+
+ unsigned int
+ status;
+
+ long
+ count;
+
+ const unsigned char
+ *profile;
+
+ size_t
+ profile_length;
+
+ if ((profile=GetImageProfile(image,"IPTC",&profile_length)) == 0)
+ return(False);
+
+ /*
+ There may be spaces in resource names, but there are no newlines,
+ so use a newline as terminater to get the full name.
+ */
+ count=sscanf(key,"8BIM:%d,%d:%[^\n]\n%[^\n]",&start,&stop,name,format);
+ if ((count != 2) && (count != 3) && (count != 4))
+ return(False);
+ if (count < 4)
+ (void)strcpy(format,"SVG");
+ if (count < 3)
+ *name='\0';
+ sub_number=1;
+ if (*name == '#')
+ sub_number=MagickAtoL(&name[1]);
+ sub_number=Max(sub_number,1);
+ resource=(char *) NULL;
+
+ status=False;
+ length=profile_length;
+ /*
+ FIXME: following cast should not be necessary but info can't be
+ const due to odd function design.
+ */
+ info=(unsigned char *) profile;
+
+ while ((length > 0) && (status == False))
+ {
+ if (ReadByte(&info,&length) != '8')
+ continue;
+ if (ReadByte(&info,&length) != 'B')
+ continue;
+ if (ReadByte(&info,&length) != 'I')
+ continue;
+ if (ReadByte(&info,&length) != 'M')
+ continue;
+ id=ReadMSBShort(&info,&length);
+ if (id < start)
+ continue;
+ if (id > stop)
+ continue;
+ if (resource != (char *)NULL)
+ MagickFreeMemory(resource);
+ count=ReadByte(&info,&length);
+ if ((count > 0) && ((size_t) count <= length))
+ {
+ resource=(char *) MagickAllocateMemory(char *,
+ (size_t) count+MaxTextExtent);
+ if (resource != (char *) NULL)
+ {
+ for (i=0; i < count; i++)
+ resource[i]=(char) ReadByte(&info,&length);
+ resource[count]='\0';
+ }
+ }
+ if (!(count & 0x01))
+ (void) ReadByte(&info,&length);
+ count=ReadMSBLong(&info,&length);
+ /*
+ ReadMSBLong() can return negative values such as -1 or any
+ other negative value. Make sure that it is in range.
+ */
+ if ((count < 0) || ((size_t) count > length))
+ {
+ length=0; /* Quit loop */
+ continue;
+ }
+ if ((*name != '\0') && (*name != '#'))
+ {
+ if ((resource == (char *) NULL) ||
+ (LocaleCompare(name,resource) != 0))
+ {
+ /*
+ No name match, scroll forward and try next resource.
+ */
+ info+=count;
+ length-=count;
+ continue;
+ }
+ }
+ if ((*name == '#') && (sub_number != 1))
+ {
+ /*
+ No numbered match, scroll forward and try next resource.
+ */
+ sub_number--;
+ info+=count;
+ length-=count;
+ continue;
+ }
+ /*
+ We have the resource of interest.
+ */
+ attribute=(char *) MagickAllocateMemory(char *,
+ (size_t) count+MaxTextExtent);
+ if (attribute != (char *) NULL)
+ {
+ (void) memcpy(attribute,(char *) info,(size_t) count);
+ attribute[count]='\0';
+ info+=count;
+ length-=count;
+ if ((id <= 1999) || (id >= 2999))
+ {
+ (void) SetImageAttribute(image,key,(const char *) attribute);
+ }
+ else
+ {
+ char
+ *path;
+ if (LocaleCompare("SVG",format) == 0)
+ path=TraceSVGClippingPath((unsigned char *) attribute,count,
+ image->columns,image->rows);
+ else
+ path=TracePSClippingPath((unsigned char *) attribute,count,
+ image->columns,image->rows);
+ (void) SetImageAttribute(image,key,(const char *) path);
+ MagickFreeMemory(path);
+ }
+ MagickFreeMemory(attribute);
+ status=True;
+ }
+ }
+ if (resource != (char *)NULL)
+ MagickFreeMemory(resource);
+ return(status);
+}
+
+#define DE_STACK_SIZE 16
+#define EXIF_DELIMITER "\n"
+#define EXIF_NUM_FORMATS 12
+#define EXIF_FMT_BYTE 1
+#define EXIF_FMT_STRING 2
+#define EXIF_FMT_USHORT 3
+#define EXIF_FMT_ULONG 4
+#define EXIF_FMT_URATIONAL 5
+#define EXIF_FMT_SBYTE 6
+#define EXIF_FMT_UNDEFINED 7
+#define EXIF_FMT_SSHORT 8
+#define EXIF_FMT_SLONG 9
+#define EXIF_FMT_SRATIONAL 10
+#define EXIF_FMT_SINGLE 11
+#define EXIF_FMT_DOUBLE 12
+#define EXIF_TAG_START 0x0100
+#define EXIF_TAG_STOP 0xFFFF
+#define TAG_EXIF_OFFSET 0x8769
+#define TAG_INTEROP_OFFSET 0xa005
+#define GPS_TAG_START 0x01
+#define GPS_TAG_STOP 0x1D
+#define GPS_OFFSET 0x8825
+#define GPS_LATITUDE 0x0002
+#define GPS_LONGITUDE 0x0004
+#define GPS_TIMESTAMP 0x0007
+#define MAX_TAGS_PER_IFD 1024 /* Maximum tags allowed per IFD */
+#define EXIF_ORIENTATION 0x0112
+
+typedef struct _TagInfo
+{
+ unsigned short
+ tag;
+
+ char
+ *description;
+} TagInfo;
+
+static const TagInfo
+ tag_table[] =
+ {
+ { 0x01, (char *) "GPSLatitudeRef"},
+ { 0x02, (char *) "GPSLatitude"},
+ { 0x03, (char *) "GPSLongitudeRef"},
+ { 0x04, (char *) "GPSLongitude"},
+ { 0x05, (char *) "GPSAltitudeRef"},
+ { 0x06, (char *) "GPSAltitude"},
+ { 0x07, (char *) "GPSTimeStamp"},
+ { 0x08, (char *) "GPSSatellites"},
+ { 0x09, (char *) "GPSStatus"},
+ { 0x0A, (char *) "GPSMeasureMode"},
+ { 0x0B, (char *) "GPSDOP"},
+ { 0x0C, (char *) "GPSSpeedRef"},
+ { 0x0D, (char *) "GPSSpeed"},
+ { 0x0E, (char *) "GPSTrackRef"},
+ { 0x0F, (char *) "GPSTrack"},
+ { 0x10, (char *) "GPSImgDirectionRef"},
+ { 0x11, (char *) "GPSImgDirection"},
+ { 0x12, (char *) "GPSMapDatum"},
+ { 0x13, (char *) "GPSDestLatitudeRef"},
+ { 0x14, (char *) "GPSDestLatitude"},
+ { 0x15, (char *) "GPSDestLongitudeRef"},
+ { 0x16, (char *) "GPSDestLongitude"},
+ { 0x17, (char *) "GPSDestBearingRef"},
+ { 0x18, (char *) "GPSDestBearing"},
+ { 0x19, (char *) "GPSDestDistanceRef"},
+ { 0x1A, (char *) "GPSDestDistance"},
+ { 0x1D, (char *) "GPSDateStamp"},
+ { 0x100, (char *) "ImageWidth"},
+ { 0x101, (char *) "ImageLength"},
+ { 0x102, (char *) "BitsPerSample"},
+ { 0x103, (char *) "Compression"},
+ { 0x106, (char *) "PhotometricInterpretation"},
+ { 0x10A, (char *) "FillOrder"},
+ { 0x10D, (char *) "DocumentName"},
+ { 0x10E, (char *) "ImageDescription"},
+ { 0x10F, (char *) "Make"},
+ { 0x110, (char *) "Model"},
+ { 0x111, (char *) "StripOffsets"},
+ { 0x112, (char *) "Orientation"},
+ { 0x115, (char *) "SamplesPerPixel"},
+ { 0x116, (char *) "RowsPerStrip"},
+ { 0x117, (char *) "StripByteCounts"},
+ { 0x118, (char *) "MinSampleValue"},
+ { 0x119, (char *) "MaxSampleValue"},
+ { 0x11A, (char *) "XResolution"},
+ { 0x11B, (char *) "YResolution"},
+ { 0x11C, (char *) "PlanarConfiguration"},
+ { 0x11D, (char *) "PageName"},
+ { 0x11E, (char *) "XPosition"},
+ { 0x11F, (char *) "YPosition"},
+ { 0x120, (char *) "FreeOffsets"},
+ { 0x121, (char *) "FreeByteCounts"},
+ { 0x122, (char *) "GrayResponseUnit"},
+ { 0x123, (char *) "GrayResponseCurve"},
+ { 0x124, (char *) "T4Options"},
+ { 0x125, (char *) "T6Options"},
+ { 0x128, (char *) "ResolutionUnit"},
+ { 0x12D, (char *) "TransferFunction"},
+ { 0x131, (char *) "Software"},
+ { 0x132, (char *) "DateTime"},
+ { 0x13B, (char *) "Artist"},
+ { 0x13C, (char *) "HostComputer"},
+ { 0x13D, (char *) "Predictor"},
+ { 0x13E, (char *) "WhitePoint"},
+ { 0x13F, (char *) "PrimaryChromaticities"},
+ { 0x140, (char *) "ColorMap"},
+ { 0x141, (char *) "HalfToneHints"},
+ { 0x142, (char *) "TileWidth"},
+ { 0x143, (char *) "TileLength"},
+ { 0x144, (char *) "TileOffsets"},
+ { 0x145, (char *) "TileByteCounts"},
+ { 0x14A, (char *) "SubIFD"},
+ { 0x14C, (char *) "InkSet"},
+ { 0x14D, (char *) "InkNames"},
+ { 0x14E, (char *) "NumberOfInks"},
+ { 0x150, (char *) "DotRange"},
+ { 0x151, (char *) "TargetPrinter"},
+ { 0x152, (char *) "ExtraSample"},
+ { 0x153, (char *) "SampleFormat"},
+ { 0x154, (char *) "SMinSampleValue"},
+ { 0x155, (char *) "SMaxSampleValue"},
+ { 0x156, (char *) "TransferRange"},
+ { 0x157, (char *) "ClipPath"},
+ { 0x158, (char *) "XClipPathUnits"},
+ { 0x159, (char *) "YClipPathUnits"},
+ { 0x15A, (char *) "Indexed"},
+ { 0x15B, (char *) "JPEGTables"},
+ { 0x15F, (char *) "OPIProxy"},
+ { 0x200, (char *) "JPEGProc"},
+ { 0x201, (char *) "JPEGInterchangeFormat"},
+ { 0x202, (char *) "JPEGInterchangeFormatLength"},
+ { 0x203, (char *) "JPEGRestartInterval"},
+ { 0x205, (char *) "JPEGLosslessPredictors"},
+ { 0x206, (char *) "JPEGPointTransforms"},
+ { 0x207, (char *) "JPEGQTables"},
+ { 0x208, (char *) "JPEGDCTables"},
+ { 0x209, (char *) "JPEGACTables"},
+ { 0x211, (char *) "YCbCrCoefficients"},
+ { 0x212, (char *) "YCbCrSubSampling"},
+ { 0x213, (char *) "YCbCrPositioning"},
+ { 0x214, (char *) "ReferenceBlackWhite"},
+ { 0x2BC, (char *) "ExtensibleMetadataPlatform"},
+ { 0x301, (char *) "Gamma"},
+ { 0x302, (char *) "ICCProfileDescriptor"},
+ { 0x303, (char *) "SRGBRenderingIntent"},
+ { 0x320, (char *) "ImageTitle"},
+ { 0x5001, (char *) "ResolutionXUnit"},
+ { 0x5002, (char *) "ResolutionYUnit"},
+ { 0x5003, (char *) "ResolutionXLengthUnit"},
+ { 0x5004, (char *) "ResolutionYLengthUnit"},
+ { 0x5005, (char *) "PrintFlags"},
+ { 0x5006, (char *) "PrintFlagsVersion"},
+ { 0x5007, (char *) "PrintFlagsCrop"},
+ { 0x5008, (char *) "PrintFlagsBleedWidth"},
+ { 0x5009, (char *) "PrintFlagsBleedWidthScale"},
+ { 0x500A, (char *) "HalftoneLPI"},
+ { 0x500B, (char *) "HalftoneLPIUnit"},
+ { 0x500C, (char *) "HalftoneDegree"},
+ { 0x500D, (char *) "HalftoneShape"},
+ { 0x500E, (char *) "HalftoneMisc"},
+ { 0x500F, (char *) "HalftoneScreen"},
+ { 0x5010, (char *) "JPEGQuality"},
+ { 0x5011, (char *) "GridSize"},
+ { 0x5012, (char *) "ThumbnailFormat"},
+ { 0x5013, (char *) "ThumbnailWidth"},
+ { 0x5014, (char *) "ThumbnailHeight"},
+ { 0x5015, (char *) "ThumbnailColorDepth"},
+ { 0x5016, (char *) "ThumbnailPlanes"},
+ { 0x5017, (char *) "ThumbnailRawBytes"},
+ { 0x5018, (char *) "ThumbnailSize"},
+ { 0x5019, (char *) "ThumbnailCompressedSize"},
+ { 0x501A, (char *) "ColorTransferFunction"},
+ { 0x501B, (char *) "ThumbnailData"},
+ { 0x5020, (char *) "ThumbnailImageWidth"},
+ { 0x5021, (char *) "ThumbnailImageHeight"},
+ { 0x5022, (char *) "ThumbnailBitsPerSample"},
+ { 0x5023, (char *) "ThumbnailCompression"},
+ { 0x5024, (char *) "ThumbnailPhotometricInterp"},
+ { 0x5025, (char *) "ThumbnailImageDescription"},
+ { 0x5026, (char *) "ThumbnailEquipMake"},
+ { 0x5027, (char *) "ThumbnailEquipModel"},
+ { 0x5028, (char *) "ThumbnailStripOffsets"},
+ { 0x5029, (char *) "ThumbnailOrientation"},
+ { 0x502A, (char *) "ThumbnailSamplesPerPixel"},
+ { 0x502B, (char *) "ThumbnailRowsPerStrip"},
+ { 0x502C, (char *) "ThumbnailStripBytesCount"},
+ { 0x502D, (char *) "ThumbnailResolutionX"},
+ { 0x502E, (char *) "ThumbnailResolutionY"},
+ { 0x502F, (char *) "ThumbnailPlanarConfig"},
+ { 0x5030, (char *) "ThumbnailResolutionUnit"},
+ { 0x5031, (char *) "ThumbnailTransferFunction"},
+ { 0x5032, (char *) "ThumbnailSoftwareUsed"},
+ { 0x5033, (char *) "ThumbnailDateTime"},
+ { 0x5034, (char *) "ThumbnailArtist"},
+ { 0x5035, (char *) "ThumbnailWhitePoint"},
+ { 0x5036, (char *) "ThumbnailPrimaryChromaticities"},
+ { 0x5037, (char *) "ThumbnailYCbCrCoefficients"},
+ { 0x5038, (char *) "ThumbnailYCbCrSubsampling"},
+ { 0x5039, (char *) "ThumbnailYCbCrPositioning"},
+ { 0x503A, (char *) "ThumbnailRefBlackWhite"},
+ { 0x503B, (char *) "ThumbnailCopyRight"},
+ { 0x5090, (char *) "LuminanceTable"},
+ { 0x5091, (char *) "ChrominanceTable"},
+ { 0x5100, (char *) "FrameDelay"},
+ { 0x5101, (char *) "LoopCount"},
+ { 0x5110, (char *) "PixelUnit"},
+ { 0x5111, (char *) "PixelPerUnitX"},
+ { 0x5112, (char *) "PixelPerUnitY"},
+ { 0x5113, (char *) "PaletteHistogram"},
+ { 0x1000, (char *) "RelatedImageFileFormat"},
+ { 0x800D, (char *) "ImageID"},
+ { 0x80E3, (char *) "Matteing"},
+ { 0x80E4, (char *) "DataType"},
+ { 0x80E5, (char *) "ImageDepth"},
+ { 0x80E6, (char *) "TileDepth"},
+ { 0x828D, (char *) "CFARepeatPatternDim"},
+ { 0x828E, (char *) "CFAPattern"},
+ { 0x828F, (char *) "BatteryLevel"},
+ { 0x8298, (char *) "Copyright"},
+ { 0x829A, (char *) "ExposureTime"},
+ { 0x829D, (char *) "FNumber"},
+ { 0x83BB, (char *) "IPTC/NAA"},
+ { 0x84E3, (char *) "IT8RasterPadding"},
+ { 0x84E5, (char *) "IT8ColorTable"},
+ { 0x8649, (char *) "ImageResourceInformation"},
+ { 0x8769, (char *) "ExifOffset"},
+ { 0x8773, (char *) "InterColorProfile"},
+ { 0x8822, (char *) "ExposureProgram"},
+ { 0x8824, (char *) "SpectralSensitivity"},
+ { 0x8825, (char *) "GPSInfo"},
+ { 0x8827, (char *) "ISOSpeedRatings"},
+ { 0x8828, (char *) "OECF"},
+ { 0x9000, (char *) "ExifVersion"},
+ { 0x9003, (char *) "DateTimeOriginal"},
+ { 0x9004, (char *) "DateTimeDigitized"},
+ { 0x9101, (char *) "ComponentsConfiguration"},
+ { 0x9102, (char *) "CompressedBitsPerPixel"},
+ { 0x9201, (char *) "ShutterSpeedValue"},
+ { 0x9202, (char *) "ApertureValue"},
+ { 0x9203, (char *) "BrightnessValue"},
+ { 0x9204, (char *) "ExposureBiasValue"},
+ { 0x9205, (char *) "MaxApertureValue"},
+ { 0x9206, (char *) "SubjectDistance"},
+ { 0x9207, (char *) "MeteringMode"},
+ { 0x9208, (char *) "LightSource"},
+ { 0x9209, (char *) "Flash"},
+ { 0x920A, (char *) "FocalLength"},
+ { 0x9214, (char *) "SubjectArea"},
+ { 0x927C, (char *) "MakerNote"},
+ { 0x9286, (char *) "UserComment"},
+ { 0x9290, (char *) "SubSecTime"},
+ { 0x9291, (char *) "SubSecTimeOriginal"},
+ { 0x9292, (char *) "SubSecTimeDigitized"},
+ { 0x9C9B, (char *) "WinXP-Title"}, /* Win XP specific, UTF-16 Unicode */
+ { 0x9C9C, (char *) "WinXP-Comments"}, /* Win XP specific, UTF-16 Unicode */
+ { 0x9C9D, (char *) "WinXP-Author"}, /* Win XP specific, UTF-16 Unicode */
+ { 0x9C9E, (char *) "WinXP-Keywords"}, /* Win XP specific, UTF-16 Unicode */
+ { 0x9C9F, (char *) "WinXP-Subject"}, /* Win XP specific, UTF-16 Unicode */
+ { 0xA000, (char *) "FlashPixVersion"},
+ { 0xA001, (char *) "ColorSpace"},
+ { 0xA002, (char *) "ExifImageWidth"},
+ { 0xA003, (char *) "ExifImageLength"},
+ { 0xA005, (char *) "InteroperabilityOffset"},
+ { 0xA20B, (char *) "FlashEnergy"},
+ { 0xA20C, (char *) "SpatialFrequencyResponse"},
+ { 0xA20D, (char *) "Noise"},
+ { 0xA20E, (char *) "FocalPlaneXResolution"},
+ { 0xA20F, (char *) "FocalPlaneYResolution"},
+ { 0xA210, (char *) "FocalPlaneResolutionUnit"},
+ { 0xA211, (char *) "ImageNumber"},
+ { 0xA212, (char *) "SecurityClassification"},
+ { 0xA213, (char *) "ImageHistory"},
+ { 0xA214, (char *) "SubjectLocation"},
+ { 0xA215, (char *) "ExposureIndex"},
+ { 0xA216, (char *) "TIFF_EPStandardID"},
+ { 0xA217, (char *) "SensingMethod"},
+ { 0xA300, (char *) "FileSource"},
+ { 0xA301, (char *) "SceneType"},
+ { 0xA302, (char *) "CFAPattern"},
+ { 0xA401, (char *) "CustomRendered"},
+ { 0xA402, (char *) "ExposureMode"},
+ { 0xA403, (char *) "WhiteBalance"},
+ { 0xA404, (char *) "DigitalZoomRatio"},
+ { 0xA405, (char *) "FocalLengthIn35mmFilm"},
+ { 0xA406, (char *) "SceneCaptureType"},
+ { 0xA407, (char *) "GainControl"},
+ { 0xA408, (char *) "Contrast"},
+ { 0xA409, (char *) "Saturation"},
+ { 0xA40A, (char *) "Sharpness"},
+ { 0xA40B, (char *) "DeviceSettingDescription"},
+ { 0xA40C, (char *) "SubjectDistanceRange"},
+ { 0xA420, (char *) "ImageUniqueID"}
+ };
+
+/*
+ Convert an EXIF tag ID to a tag description
+
+ An EXIF tag value to be translated, and a buffer of at least
+ MaxTextExtent length are passed as arguments. For convenience, the
+ converted string is returned.
+*/
+
+static const char *
+EXIFTagToDescription(int t, char *tag_description)
+{
+ unsigned int
+ i;
+
+ for (i=0; i < sizeof(tag_table)/sizeof(tag_table[0]); i++)
+ {
+ if (tag_table[i].tag == t)
+ {
+ (void) strlcpy(tag_description,tag_table[i].description,
+ MaxTextExtent);
+ return tag_description;
+ }
+ }
+
+ FormatString(tag_description,"0x%04X",t);
+ return tag_description;
+}
+
+/*
+ Convert an EXIF tag description to a tag ID.
+*/
+static int
+EXIFDescriptionToTag(const char *description)
+{
+ unsigned int
+ i;
+
+ for (i=0; i < sizeof(tag_table)/sizeof(tag_table[0]); i++)
+ if (LocaleCompare(tag_table[i].description,description) == 0)
+ return tag_table[i].tag;
+
+ return -1;
+}
+
+static const char *
+EXIFFormatToDescription(int f)
+{
+ const char
+ *description;
+
+ description="unknown";
+
+ switch (f)
+ {
+ case EXIF_FMT_BYTE:
+ description="BYTE";
+ break;
+ case EXIF_FMT_STRING:
+ description="STRING";
+ break;
+ case EXIF_FMT_USHORT:
+ description="USHORT";
+ break;
+ case EXIF_FMT_ULONG:
+ description="ULONG";
+ break;
+ case EXIF_FMT_URATIONAL:
+ description="URATIONAL";
+ break;
+ case EXIF_FMT_SBYTE:
+ description="SBYTE";
+ break;
+ case EXIF_FMT_UNDEFINED:
+ description="UNDEFINED";
+ break;
+ case EXIF_FMT_SSHORT:
+ description="SSHORT";
+ break;
+ case EXIF_FMT_SLONG:
+ description="SLONG";
+ break;
+ case EXIF_FMT_SRATIONAL:
+ description="SRATIONAL";
+ break;
+ case EXIF_FMT_SINGLE:
+ description="SINGLE";
+ break;
+ case EXIF_FMT_DOUBLE:
+ description="DOUBLE";
+ break;
+ }
+
+ return description;
+}
+
+static int
+ format_bytes[] =
+ {
+ 0,
+ 1, /* BYTE */
+ 1, /* STRING / ASCII */
+ 2, /* USHORT */
+ 4, /* ULONG */
+ 8, /* URATIONAL */
+ 1, /* SBYTE */
+ 1, /* UNDEFINED */
+ 2, /* SSHORT */
+ 4, /* SLONG */
+ 8, /* SRATIONAL */
+ 4, /* SINGLE / FLOAT */
+ 8 /* DOUBLE */
+ };
+
+static short
+Read16s(int morder,void *ishort)
+{
+ short
+ value;
+
+ if (morder)
+ value=(((unsigned char *) ishort)[0] << 8) | ((unsigned char *) ishort)[1];
+ else
+ value=(((unsigned char *) ishort)[1] << 8) | ((unsigned char *) ishort)[0];
+ return(value);
+}
+
+static unsigned short
+Read16u(int morder,void *ishort)
+{
+ unsigned short
+ value;
+
+ if (morder)
+ value=(((unsigned char *) ishort)[0] << 8) | ((unsigned char *) ishort)[1];
+ else
+ value=(((unsigned char *) ishort)[1] << 8) | ((unsigned char *) ishort)[0];
+ return(value);
+}
+
+static long
+Read32s(int morder,void *ilong)
+{
+ long
+ value;
+
+ if (morder)
+ value=(((char *) ilong)[0] << 24) | (((unsigned char *) ilong)[1] << 16) |
+ (((unsigned char *) ilong)[2] << 8) | (((unsigned char *) ilong)[3]);
+ else
+ value=(((char *) ilong)[3] << 24) | (((unsigned char *) ilong)[2] << 16) |
+ (((unsigned char *) ilong)[1] << 8 ) | (((unsigned char *) ilong)[0]);
+ return(value);
+}
+
+static unsigned long
+Read32u(int morder, void *ilong)
+{
+ return(Read32s(morder,ilong) & 0xffffffffUL);
+}
+
+static void
+Write16u(int morder, void *location, unsigned short value)
+{
+ char
+ *pval;
+
+ pval = (char *)location;
+ if (morder)
+ {
+ *pval++ = (char)((value >> 8) & 0xffL);
+ *pval++ = (char)(value & 0xffL);
+ }
+ else
+ {
+ *pval++ = (char)(value & 0xffL);
+ *pval++ = (char)((value >> 8) & 0xffL);
+ }
+}
+
+static int
+GenerateEXIFAttribute(Image *image,const char *specification)
+{
+ char
+ *final,
+ *key,
+ tag_description[MaxTextExtent],
+ *value;
+
+ int
+ id,
+ level,
+ morder,
+ all;
+
+ int
+ tag;
+
+ register long
+ i;
+
+ size_t
+ length;
+
+ unsigned long
+ offset;
+
+ unsigned long
+ gpsoffset;
+
+ unsigned char
+ *tiffp,
+ *tiffp_max,
+ *ifdstack[DE_STACK_SIZE],
+ *ifdp,
+ *info;
+
+ unsigned int
+ de,
+ destack[DE_STACK_SIZE],
+ nde;
+
+ const unsigned char
+ *profile_info;
+
+ size_t
+ profile_length;
+
+ MagickBool
+ gpsfoundstack[DE_STACK_SIZE],
+ gpsfound;
+
+ MagickBool
+ debug=MagickFalse;
+
+ assert((sizeof(format_bytes)/sizeof(format_bytes[0])-1) == EXIF_NUM_FORMATS);
+
+ {
+ const char *
+ env_value;
+
+ /*
+ Allow enabling debug of EXIF tags
+ */
+ if ((env_value=getenv("MAGICK_DEBUG_EXIF")))
+ {
+ if (LocaleCompare(env_value,"TRUE") == 0)
+ debug=MagickTrue;
+ }
+ }
+ gpsfound=MagickFalse;
+ gpsoffset=0;
+ /*
+ Determine if there is any EXIF data available in the image.
+ */
+ value=(char *) NULL;
+ final=AllocateString("");
+ profile_info=GetImageProfile(image,"EXIF",&profile_length);
+ if (profile_info == 0)
+ goto generate_attribute_failure;
+ /*
+ If EXIF data exists, then try to parse the request for a tag in
+ the form "EXIF:key".
+ */
+ key=(char *) NULL;
+ if (strlen(specification) > 5)
+ key=(char *) &specification[5]; /* "EXIF:key" */
+ else
+ goto generate_attribute_failure;
+ while (isspace((int) (*key)))
+ key++;
+ all=0;
+ tag=(-1);
+ switch(*key)
+ {
+ /*
+ Caller has asked for all the tags in the EXIF data.
+ */
+ case '*':
+ {
+ tag=0;
+ all=1; /* return the data in description=value format */
+ break;
+ }
+ case '!':
+ {
+ tag=0;
+ all=2; /* return the data in tageid=value format */
+ break;
+ }
+ /*
+ Check for a hex based tag specification first.
+ */
+ case '#':
+ {
+ char
+ c;
+
+ size_t
+ n;
+
+ tag=0;
+ key++;
+ n=strlen(key);
+ if (n != 4)
+ goto generate_attribute_failure;
+ else
+ {
+ /*
+ Parse tag specification as a hex number.
+ */
+ n/=4;
+ do
+ {
+ for (i=(long) n-1; i >= 0; i--)
+ {
+ c=(*key++);
+ tag<<=4;
+ if ((c >= '0') && (c <= '9'))
+ tag|=c-'0';
+ else
+ if ((c >= 'A') && (c <= 'F'))
+ tag|=c-('A'-10);
+ else
+ if ((c >= 'a') && (c <= 'f'))
+ tag|=c-('a'-10);
+ else
+ goto generate_attribute_failure;
+ }
+ } while (*key != '\0');
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Try to match the text with a tag name instead.
+ */
+ tag=EXIFDescriptionToTag(key);
+ if (debug)
+ fprintf(stderr,"Found tag %d for key \"%s\"\n",tag,key);
+ break;
+ }
+ }
+ if (tag < 0)
+ goto generate_attribute_failure;;
+ length=profile_length;
+ info=(unsigned char *) profile_info;
+ while (length != 0)
+ {
+ if (ReadByte(&info,&length) != 0x45)
+ continue;
+ if (ReadByte(&info,&length) != 0x78)
+ continue;
+ if (ReadByte(&info,&length) != 0x69)
+ continue;
+ if (ReadByte(&info,&length) != 0x66)
+ continue;
+ if (ReadByte(&info,&length) != 0x00)
+ continue;
+ if (ReadByte(&info,&length) != 0x00)
+ continue;
+ break;
+ }
+ if (length < 16)
+ goto generate_attribute_failure;
+ tiffp=info;
+ tiffp_max=tiffp+length;
+ id=Read16u(0,tiffp);
+ morder=0;
+ if (id == 0x4949) /* LSB */
+ morder=0;
+ else
+ if (id == 0x4D4D) /* MSB */
+ morder=1;
+ else
+ goto generate_attribute_failure;
+ if (Read16u(morder,tiffp+2) != 0x002a)
+ goto generate_attribute_failure;
+ /*
+ This is the offset to the first IFD.
+ */
+ offset=Read32u(morder,tiffp+4);
+ if (offset >= length)
+ goto generate_attribute_failure;
+ /*
+ Set the pointer to the first IFD and follow it were it leads.
+ */
+ ifdp=tiffp+offset;
+ level=0;
+ de=0U;
+ do
+ {
+ /*
+ If there is anything on the stack then pop it off.
+ */
+ if (level > 0)
+ {
+ level--;
+ ifdp=ifdstack[level];
+ de=destack[level];
+ gpsfound=gpsfoundstack[level];
+ }
+ /*
+ Determine how many entries there are in the current IFD.
+ Limit the number of entries parsed to MAX_TAGS_PER_IFD.
+ */
+ if ((ifdp < tiffp) || (ifdp+2 > tiffp_max))
+ goto generate_attribute_failure;
+ nde=Read16u(morder,ifdp);
+ if (nde > MAX_TAGS_PER_IFD)
+ nde=MAX_TAGS_PER_IFD;
+ for (; de < nde; de++)
+ {
+ unsigned int
+ n;
+
+ int
+ t,
+ f,
+ c;
+
+ unsigned char
+ *pde,
+ *pval;
+
+ pde=(unsigned char *) (ifdp+2+(12*de));
+ if (pde + 12 > tiffp + length)
+ {
+ if (debug)
+ fprintf(stderr, "EXIF: Invalid Exif, entry is beyond metadata limit.\n");
+ goto generate_attribute_failure;
+ }
+ t=Read16u(morder,pde); /* get tag value */
+ f=Read16u(morder,pde+2); /* get the format */
+ if ((f < 0) ||
+ ((size_t) f >= sizeof(format_bytes)/sizeof(format_bytes[0])))
+ break;
+ c=(long) Read32u(morder,pde+4); /* get number of components */
+ n=c*format_bytes[f];
+ if (n <= 4)
+ pval=(unsigned char *) pde+8;
+ else
+ {
+ unsigned long
+ oval;
+
+ /*
+ The directory entry contains an offset.
+ */
+ oval=Read32u(morder,pde+8);
+ if ((oval+n) > length)
+ continue;
+ pval=(unsigned char *)(tiffp+oval);
+ }
+
+ if (debug)
+ {
+ fprintf(stderr,
+ "EXIF: TagVal=%d TagDescr=\"%s\" Format=%d "
+ "FormatDescr=\"%s\" Components=%d\n",t,
+ EXIFTagToDescription(t,tag_description),f,
+ EXIFFormatToDescription(f),c);
+ }
+
+ if (gpsfound)
+ {
+ if ((t < GPS_TAG_START) || (t > GPS_TAG_STOP))
+ {
+ if (debug)
+ fprintf(stderr,
+ "EXIF: Skipping bogus GPS IFD tag %d ...\n",t);
+ continue;
+ }
+ }
+ else
+ {
+ if ((t < EXIF_TAG_START) || ( t > EXIF_TAG_STOP))
+ {
+ if (debug)
+ fprintf(stderr,
+ "EXIF: Skipping bogus EXIF IFD tag %d ...\n",t);
+ continue;
+ }
+ }
+
+ /*
+ Return values for all the tags, or for a specific requested tag.
+
+ Tags from the GPS sub-IFD are in a bit of a chicken and
+ egg situation in that the tag for the GPS sub-IFD will not
+ be seen unless we pass that tag through so it can be
+ processed. So we pass the GPS_OFFSET tag through, but if
+ it was not requested, then we don't return a string value
+ for it.
+ */
+ if (all || (tag == t) || (GPS_OFFSET == t))
+ {
+ char
+ s[MaxTextExtent];
+
+ switch (f)
+ {
+ case EXIF_FMT_SBYTE:
+ {
+ /* 8-bit signed integer */
+ FormatString(s,"%ld",(long) (*(char *) pval));
+ value=AllocateString(s);
+ break;
+ }
+ case EXIF_FMT_BYTE:
+ {
+ /* 8-bit unsigned integer */
+ value=MagickAllocateMemory(char *,n+1);
+ if (value != (char *) NULL)
+ {
+ unsigned int
+ a;
+
+ for (a=0; a < n; a++)
+ {
+ value[a]='.';
+ if (isprint((int) pval[a]))
+ value[a]=pval[a];
+ }
+ value[a]='\0';
+ break;
+ }
+#if 0
+ printf("format %u, length %u\n",f,n);
+ FormatString(s,"%ld",(long) (*(unsigned char *) pval));
+ value=AllocateString(s);
+#endif
+ break;
+ }
+ case EXIF_FMT_SSHORT:
+ {
+ /* 16-bit signed integer */
+ FormatString(s,"%hd",Read16u(morder,pval));
+ value=AllocateString(s);
+ break;
+ }
+ case EXIF_FMT_USHORT:
+ {
+ /* 16-bit unsigned integer */
+ FormatString(s,"%hu",Read16s(morder,pval));
+ value=AllocateString(s);
+ break;
+ }
+ case EXIF_FMT_ULONG:
+ {
+ offset=Read32u(morder,pval);
+ /*
+ Only report value if this tag was requested.
+ */
+ if (all || (tag == t))
+ {
+ FormatString(s,"%lu",offset);
+ value=AllocateString(s);
+ }
+ if (GPS_OFFSET == t)
+ gpsoffset=offset;
+ break;
+ }
+ case EXIF_FMT_SLONG:
+ {
+ FormatString(s,"%ld",Read32s(morder,pval));
+ value=AllocateString(s);
+ break;
+ }
+ case EXIF_FMT_URATIONAL:
+ {
+ if (gpsfound &&
+ (t == GPS_LATITUDE ||
+ t == GPS_LONGITUDE ||
+ t == GPS_TIMESTAMP))
+ {
+ FormatString(s,"%ld/%ld,%ld/%ld,%ld/%ld"
+ ,Read32u(morder,pval),
+ Read32u(morder,4+(char *) pval)
+ ,Read32u(morder,8+(char *)pval),
+ Read32u(morder,12+(char *) pval)
+ ,Read32u(morder,16+(char *)pval),
+ Read32u(morder,20+(char *) pval)
+ );
+ }
+ else
+ {
+ FormatString(s,"%ld/%ld"
+ ,Read32u(morder,pval),
+ Read32u(morder,4+(char *) pval)
+ );
+ }
+ value=AllocateString(s);
+ break;
+ }
+ case EXIF_FMT_SRATIONAL:
+ {
+ FormatString(s,"%ld/%ld",Read32s(morder,pval),
+ Read32s(morder,4+(char *) pval));
+ value=AllocateString(s);
+ break;
+ }
+ case EXIF_FMT_SINGLE:
+ {
+ FormatString(s,"%f",(double) *(float *) pval);
+ value=AllocateString(s);
+ break;
+ }
+ case EXIF_FMT_DOUBLE:
+ {
+ FormatString(s,"%f",*(double *) pval);
+ value=AllocateString(s);
+ break;
+ }
+ default:
+ case EXIF_FMT_UNDEFINED:
+ case EXIF_FMT_STRING:
+ {
+ unsigned int
+ a;
+
+ size_t
+ allocation_size;
+
+ MagickBool
+ binary=MagickFalse;
+
+ allocation_size=n+1;
+ for (a=0; a < n; a++)
+ if (!(isprint((int) pval[a])))
+ allocation_size += 3;
+
+ value=MagickAllocateMemory(char *,allocation_size);
+ if (value != (char *) NULL)
+ {
+ i=0;
+ for (a=0; a < n; a++)
+ {
+ if ((f == EXIF_FMT_STRING) && (pval[a] == '\0'))
+ break;
+ if ((isprint((int) pval[a])) ||
+ ((pval[a] == '\0') &&
+ (a == (n-1) && (!binary))))
+ {
+ value[i++]=pval[a];
+ }
+ else
+ {
+ i += sprintf(&value[i],"\\%03o",
+ (unsigned int) pval[a]);
+ binary |= MagickTrue;
+ }
+ }
+ value[i]='\0';
+ }
+ break;
+ }
+ }
+ if (value != (char *) NULL)
+ {
+ const char
+ *description;
+
+ if (strlen(final) != 0)
+ (void) ConcatenateString(&final,EXIF_DELIMITER);
+ description=(const char *) NULL;
+ switch (all)
+ {
+ case 1:
+ {
+ description=EXIFTagToDescription(t,tag_description);
+ FormatString(s,"%.1024s=",description);
+ (void) ConcatenateString(&final,s);
+ break;
+ }
+ case 2:
+ {
+ FormatString(s,"#%04x=",t);
+ (void) ConcatenateString(&final,s);
+ break;
+ }
+ }
+ (void) ConcatenateString(&final,value);
+ MagickFreeMemory(value);
+ }
+ }
+ if (t == GPS_OFFSET && (gpsoffset != 0))
+ {
+ if ((gpsoffset < length) && (level < (DE_STACK_SIZE-2)))
+ {
+ /*
+ Push our current directory state onto the stack.
+ */
+ ifdstack[level]=ifdp;
+ de++; /* bump to the next entry */
+ destack[level]=de;
+ gpsfoundstack[level]=gpsfound;
+ level++;
+ /*
+ Push new state onto of stack to cause a jump.
+ */
+ ifdstack[level]=tiffp+gpsoffset;
+ destack[level]=0;
+ gpsfoundstack[level]=MagickTrue;
+ level++;
+ }
+ gpsoffset=0;
+ break; /* break out of the for loop */
+ }
+
+ if ((t == TAG_EXIF_OFFSET) || (t == TAG_INTEROP_OFFSET))
+ {
+ offset=Read32u(morder,pval);
+ if ((offset < length) && (level < (DE_STACK_SIZE-2)))
+ {
+ /*
+ Push our current directory state onto the stack.
+ */
+ ifdstack[level]=ifdp;
+ de++; /* bump to the next entry */
+ destack[level]=de;
+ gpsfoundstack[level]=gpsfound;
+ level++;
+ /*
+ Push new state onto of stack to cause a jump.
+ */
+ ifdstack[level]=tiffp+offset;
+ destack[level]=0;
+ gpsfoundstack[level]=MagickFalse;
+ level++;
+ }
+ break; /* break out of the for loop */
+ }
+ }
+ } while (level > 0);
+ if (strlen(final) == 0)
+ (void) ConcatenateString(&final,"unknown");
+
+ (void) SetImageAttribute(image,specification,(const char *) final);
+ MagickFreeMemory(final);
+ return(True);
+ generate_attribute_failure:
+ MagickFreeMemory(final);
+ return False;
+}
+
+/*
+ Generate an aggregate attribute result based on a wildcard
+ specification like "foo:*".
+*/
+static int
+GenerateWildcardAttribute(Image *image,const char *key)
+{
+ char
+ *result=NULL;
+
+ size_t
+ key_length=0;
+
+ register ImageAttribute
+ *p = (ImageAttribute *) NULL;
+
+ MagickPassFail
+ status=MagickFail;
+
+ /*
+ Support a full "*" wildcard.
+ */
+ if (strcmp("*",key) == 0)
+ {
+ (void) GenerateIPTCAttribute((Image *) image,"IPTC:*");
+ (void) Generate8BIMAttribute((Image *) image,"8BIM:*");
+ (void) GenerateEXIFAttribute((Image *) image,"EXIF:*");
+ }
+
+ key_length=strlen(key)-1;
+ for (p=image->attributes; p != (ImageAttribute *) NULL; p=p->next)
+ if (LocaleNCompare(key,p->key,key_length) == 0)
+ {
+ char
+ s[MaxTextExtent];
+
+ if (result != NULL)
+ (void) ConcatenateString(&result,"\n");
+ FormatString(s,"%.512s=%.1024s",p->key,p->value);
+ (void) ConcatenateString(&result,s);
+ }
+
+ if (result != NULL)
+ {
+ status=SetImageAttribute(image,key,result);
+ MagickFreeMemory(result);
+ }
+ return status;
+}
+
+MagickExport const ImageAttribute *
+GetImageAttribute(const Image *image,const char *key)
+{
+ register ImageAttribute
+ *p = (ImageAttribute *) NULL;
+
+ size_t
+ key_length=0;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ /*
+ If key is null, then return a pointer to the attribute list.
+ */
+ if (key == (char *) NULL)
+ return(image->attributes);
+
+ key_length=strlen(key);
+
+ for (p=image->attributes; p != (ImageAttribute *) NULL; p=p->next)
+ if (LocaleCompare(key,p->key) == 0)
+ return(p);
+
+ if (LocaleNCompare("IPTC:",key,5) == 0)
+ {
+ /*
+ Create an attribute named "IPTC:*" with all matching
+ key=values and return it.
+ */
+ if (GenerateIPTCAttribute((Image *) image,key) == True)
+ return(GetImageAttribute(image,key));
+ }
+ else if (LocaleNCompare("8BIM:",key,5) == 0)
+ {
+ /*
+ Create an attribute named "8BIM:*" with all matching
+ key=values and return it.
+ */
+ if (Generate8BIMAttribute((Image *) image,key) == True)
+ return(GetImageAttribute(image,key));
+ }
+ else if (LocaleNCompare("EXIF:",key,5) == 0)
+ {
+ /*
+ Create an attribute named "EXIF:*" with all matching
+ key=values and return it.
+ */
+ if (GenerateEXIFAttribute((Image *) image,key) == True)
+ return(GetImageAttribute(image,key));
+ }
+ else if ((key_length >=2) && (key[key_length-1] == '*'))
+ {
+ /*
+ Create an attribute named "foo:*" with all matching
+ key=values and return it.
+ */
+ if (GenerateWildcardAttribute((Image *) image,key) == True)
+ return(GetImageAttribute(image,key));
+ }
+ else if ((key_length ==1) && (key[0] == '*'))
+ {
+ /*
+ Create an attribute named "*" with all key=values and return
+ it.
+ */
+ if (GenerateWildcardAttribute((Image *) image,key) == True)
+ return(GetImageAttribute(image,key));
+ }
+ return(p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e C l i p p i n g P a t h A t t r i b u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetImageClippingPathAttribute searches the list of image attributes
+% and returns a pointer to a clipping path if it exists otherwise NULL.
+%
+% The format of the GetImageClippingPathAttribute method is:
+%
+% const ImageAttribute *GetImageClippingPathAttribute(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o attribute: Method GetImageClippingPathAttribute returns the clipping
+% path if it exists otherwise NULL.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport const ImageAttribute *
+GetImageClippingPathAttribute(const Image *image)
+{
+ return(GetImageAttribute(image,"8BIM:1999,2998"));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t I m a g e I n f o A t t r i b u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageInfoAttribute() returns a "fake" attribute based on data in the
+% image info or image structures.
+%
+% The format of the GetImageInfoAttribute method is:
+%
+% const ImageAttribute *GetImageAttribute(const ImageInfo *image_info,
+% const Image *image,const char *key)
+%
+% A description of each parameter follows:
+%
+% o attribute: Method GetImageInfoAttribute returns the attribute if it
+% exists otherwise NULL.
+%
+% o image_info: The imageInfo.
+%
+% o image: The image.
+%
+% o key: These character strings are the name of an image attribute to
+% return.
+%
+*/
+MagickExport const ImageAttribute *
+GetImageInfoAttribute(const ImageInfo *image_info,const Image *image,
+ const char *key)
+{
+ char
+ attribute[MaxTextExtent],
+ filename[MaxTextExtent];
+
+ attribute[0]='\0';
+ switch(*(key))
+ {
+ case 'b':
+ {
+ if (LocaleNCompare("base",key,2) == 0)
+ {
+ GetPathComponent(image->magick_filename,BasePath,filename);
+ (void) strlcpy(attribute,filename,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 'd':
+ {
+ if (LocaleNCompare("depth",key,2) == 0)
+ {
+ FormatString(attribute,"%u",image->depth);
+ break;
+ }
+ if (LocaleNCompare("directory",key,2) == 0)
+ {
+ GetPathComponent(image->magick_filename,HeadPath,filename);
+ (void) strlcpy(attribute,filename,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 'e':
+ {
+ if (LocaleNCompare("extension",key,2) == 0)
+ {
+ GetPathComponent(image->magick_filename,ExtensionPath,filename);
+ (void) strlcpy(attribute,filename,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 'g':
+ {
+ if (LocaleNCompare("group",key,2) == 0)
+ {
+ FormatString(attribute,"0x%lx",image_info->group);
+ break;
+ }
+ break;
+ }
+ case 'h':
+ {
+ if (LocaleNCompare("height",key,2) == 0)
+ {
+ FormatString(attribute,"%lu",
+ image->magick_rows ? image->magick_rows : 256L);
+ break;
+ }
+ break;
+ }
+ case 'i':
+ {
+ if (LocaleNCompare("input",key,2) == 0)
+ {
+ (void) strlcpy(attribute,image->filename,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 'm':
+ {
+ if (LocaleNCompare("magick",key,2) == 0)
+ {
+ (void) strlcpy(attribute,image->magick,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 'n':
+ {
+ if (LocaleNCompare("name",key,2) == 0)
+ {
+ (void) strlcpy(attribute,filename,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 's':
+ {
+ if (LocaleNCompare("size",key,2) == 0)
+ {
+ char
+ format[MaxTextExtent];
+
+ FormatSize(GetBlobSize(image),format);
+ FormatString(attribute,"%.1024s",format);
+ break;
+ }
+ if (LocaleNCompare("scene",key,2) == 0)
+ {
+ FormatString(attribute,"%lu",image->scene);
+ if (image_info->subrange != 0)
+ FormatString(attribute,"%lu",image_info->subimage);
+ break;
+ }
+ if (LocaleNCompare("scenes",key,6) == 0)
+ {
+ FormatString(attribute,"%lu",
+ (unsigned long) GetImageListLength(image));
+ break;
+ }
+ break;
+ }
+ case 'o':
+ {
+ if (LocaleNCompare("output",key,2) == 0)
+ {
+ (void) strlcpy(attribute,image_info->filename,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 'p':
+ {
+ if (LocaleNCompare("page",key,2) == 0)
+ {
+ register const Image
+ *p;
+
+ unsigned int
+ page;
+
+ p=image;
+ for (page=1; p->previous != (Image *) NULL; page++)
+ p=p->previous;
+ FormatString(attribute,"%u",page);
+ break;
+ }
+ break;
+ }
+ case 'u':
+ {
+ if (LocaleNCompare("unique",key,2) == 0)
+ {
+ (void) strlcpy(filename,image_info->unique,MaxTextExtent);
+ if (*filename == '\0')
+ if(!AcquireTemporaryFileName(filename))
+ return((ImageAttribute *) NULL);
+ (void) strlcpy(attribute,filename,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ case 'w':
+ {
+ if (LocaleNCompare("width",key,2) == 0)
+ {
+ FormatString(attribute,"%lu",
+ image->magick_columns ? image->magick_columns : 256L);
+ break;
+ }
+ break;
+ }
+ case 'x':
+ {
+ if (LocaleNCompare("xresolution",key,2) == 0)
+ {
+ FormatString(attribute,"%g",image->x_resolution);
+ break;
+ }
+ break;
+ }
+ case 'y':
+ {
+ if (LocaleNCompare("yresolution",key,2) == 0)
+ {
+ FormatString(attribute,"%g",image->y_resolution);
+ break;
+ }
+ break;
+ }
+ case 'z':
+ {
+ if (LocaleNCompare("zero",key,2) == 0)
+ {
+ (void) strlcpy(filename,image_info->zero,MaxTextExtent);
+ if (*filename == '\0')
+ if(!AcquireTemporaryFileName(filename))
+ return((ImageAttribute *) NULL);
+ (void) strlcpy(attribute,filename,MaxTextExtent);
+ break;
+ }
+ break;
+ }
+ }
+ if (strlen(image->magick_filename) != 0)
+ return(GetImageAttribute(image,key));
+ return((ImageAttribute *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e A t t r i b u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageAttribute() searches the list of image attributes and replaces the
+% attribute value. If it is not found in the list, the attribute name
+% and value is added to the list. If the attribute exists in the list,
+% the value is concatenated to the attribute. SetImageAttribute returns
+% True if the attribute is successfully concatenated or added to the list,
+% otherwise False. If the value is NULL, the matching key is deleted
+% from the list.
+%
+% There is special handling for the EXIF:Orientation attribute. Setting this
+% attribute will also update the EXIF tag in the image's EXIF profile to the
+% given value provided an EXIF profile exists and has an existing EXIF
+% orientation tag and the attribute value is a valid orientation
+% (see orientationType). The attribute value will be set regardless of
+% whether the EXIF profile was successfully updated. The new
+% EXIF:Orientation attribute replaces the existing value rather than
+% being concatenated to it as when setting other attributes.
+$
+% The 'comment' and 'label' attributes are treated specially in that
+% embedded format specifications are translated according to the formatting
+% rules of TranslateText().
+%
+% The format of the SetImageAttribute method is:
+%
+% unsigned int SetImageAttribute(Image *image,const char *key,
+% const char *value)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o key,value: These character strings are the name and value of an image
+% attribute to replace or add to the list.
+%
+%
+*/
+
+/*
+ Find the location of an EXIF attribute in an EXIF profile. The EXIF attribute
+ to be found is specified as its numeric tag value (see tag_table). Returns
+ a pointer to the attribute in the EXIF profile or NULL if missing or there
+ is an error parsing the profile. Returns the EXIF profile byte order if the
+ morderp parameter is not NULL.
+*/
+
+static unsigned char *
+FindEXIFAttribute(const unsigned char *profile_info,
+ const size_t profile_length,
+ const unsigned short tag, int *morderp)
+{
+ char
+ tag_description[MaxTextExtent];
+
+ int
+ id,
+ level,
+ morder;
+
+ size_t
+ length;
+
+ unsigned long
+ offset;
+
+ unsigned char
+ *tiffp,
+ *tiffp_max,
+ *ifdstack[DE_STACK_SIZE],
+ *ifdp,
+ *info,
+ *attribp;
+
+ unsigned int
+ de,
+ destack[DE_STACK_SIZE],
+ nde;
+
+ MagickBool
+ gpsfoundstack[DE_STACK_SIZE],
+ gpsfound;
+
+ MagickBool
+ debug=MagickFalse;
+
+ attribp = (unsigned char *)NULL;
+
+ assert((sizeof(format_bytes)/sizeof(format_bytes[0])-1) == EXIF_NUM_FORMATS);
+
+ {
+ const char *
+ env_value;
+
+ /*
+ Allow enabling debug of EXIF tags
+ */
+ if ((env_value=getenv("MAGICK_DEBUG_EXIF")))
+ {
+ if (LocaleCompare(env_value,"TRUE") == 0)
+ debug=MagickTrue;
+ }
+ }
+ gpsfound=MagickFalse;
+ length=profile_length;
+ info=(unsigned char *) profile_info;
+ while (length != 0)
+ {
+ if (ReadByte(&info,&length) != 0x45)
+ continue;
+ if (ReadByte(&info,&length) != 0x78)
+ continue;
+ if (ReadByte(&info,&length) != 0x69)
+ continue;
+ if (ReadByte(&info,&length) != 0x66)
+ continue;
+ if (ReadByte(&info,&length) != 0x00)
+ continue;
+ if (ReadByte(&info,&length) != 0x00)
+ continue;
+ break;
+ }
+ if (length < 16)
+ goto find_attribute_failure;
+ tiffp=info;
+ tiffp_max=tiffp+length;
+ id=Read16u(0,tiffp);
+ morder=0;
+ if (id == 0x4949) /* LSB */
+ morder=0;
+ else
+ if (id == 0x4D4D) /* MSB */
+ morder=1;
+ else
+ goto find_attribute_failure;
+ if (morderp)
+ *morderp = morder;
+ if (Read16u(morder,tiffp+2) != 0x002a)
+ goto find_attribute_failure;
+ /*
+ This is the offset to the first IFD.
+ */
+ offset=Read32u(morder,tiffp+4);
+ if (offset >= length)
+ goto find_attribute_failure;
+ /*
+ Set the pointer to the first IFD and follow it were it leads.
+ */
+ ifdp=tiffp+offset;
+ level=0;
+ de=0U;
+ do
+ {
+ /*
+ If there is anything on the stack then pop it off.
+ */
+ if (level > 0)
+ {
+ level--;
+ ifdp=ifdstack[level];
+ de=destack[level];
+ gpsfound=gpsfoundstack[level];
+ }
+ /*
+ Determine how many entries there are in the current IFD.
+ Limit the number of entries parsed to MAX_TAGS_PER_IFD.
+ */
+ if ((ifdp < tiffp) || (ifdp+2 > tiffp_max))
+ goto find_attribute_failure;
+ nde=Read16u(morder,ifdp);
+ if (nde > MAX_TAGS_PER_IFD)
+ nde=MAX_TAGS_PER_IFD;
+ for (; de < nde; de++)
+ {
+ unsigned int
+ n;
+
+ int
+ t,
+ f,
+ c;
+
+ unsigned char
+ *pde,
+ *pval;
+
+
+ pde=(unsigned char *) (ifdp+2+(12*de));
+ if (pde + 12 > tiffp + length)
+ {
+ if (debug)
+ fprintf(stderr, "EXIF: Invalid Exif, entry is beyond metadata limit.\n");
+ goto find_attribute_failure;
+ }
+ t=Read16u(morder,pde); /* get tag value */
+ f=Read16u(morder,pde+2); /* get the format */
+ if ((f < 0) ||
+ ((size_t) f >= sizeof(format_bytes)/sizeof(format_bytes[0])))
+ break;
+ c=(long) Read32u(morder,pde+4); /* get number of components */
+ n=c*format_bytes[f];
+ if (n <= 4)
+ pval=(unsigned char *) pde+8;
+ else
+ {
+ unsigned long
+ oval;
+
+ /*
+ The directory entry contains an offset.
+ */
+ oval=Read32u(morder,pde+8);
+ if ((oval+n) > length)
+ continue;
+ pval=(unsigned char *)(tiffp+oval);
+ }
+
+ if (debug)
+ {
+ fprintf(stderr,
+ "EXIF: TagVal=%d TagDescr=\"%s\" Format=%d "
+ "FormatDescr=\"%s\" Components=%d\n",t,
+ EXIFTagToDescription(t,tag_description),f,
+ EXIFFormatToDescription(f),c);
+ }
+
+ if (gpsfound)
+ {
+ if ((t < GPS_TAG_START) || (t > GPS_TAG_STOP))
+ {
+ if (debug)
+ fprintf(stderr,
+ "EXIF: Skipping bogus GPS IFD tag %d ...\n",t);
+ continue;
+ }
+ }
+ else
+ {
+ if ((t < EXIF_TAG_START) || ( t > EXIF_TAG_STOP))
+ {
+ if (debug)
+ fprintf(stderr,
+ "EXIF: Skipping bogus EXIF IFD tag %d ...\n",t);
+ continue;
+ }
+ }
+
+ /*
+ Return values for all the tags, or for a specific requested tag.
+
+ Tags from the GPS sub-IFD are in a bit of a chicken and
+ egg situation in that the tag for the GPS sub-IFD will not
+ be seen unless we pass that tag through so it can be
+ processed. So we pass the GPS_OFFSET tag through, but if
+ it was not requested, then we don't return a string value
+ for it.
+ */
+ if (tag == t)
+ {
+ attribp = pde;
+ break;
+ }
+
+ if (t == GPS_OFFSET)
+ {
+ offset=Read32u(morder,pval);
+ if ((offset < length) && (level < (DE_STACK_SIZE-2)))
+ {
+ /*
+ Push our current directory state onto the stack.
+ */
+ ifdstack[level]=ifdp;
+ de++; /* bump to the next entry */
+ destack[level]=de;
+ gpsfoundstack[level]=gpsfound;
+ level++;
+ /*
+ Push new state onto of stack to cause a jump.
+ */
+ ifdstack[level]=tiffp+offset;
+ destack[level]=0;
+ gpsfoundstack[level]=MagickTrue;
+ level++;
+ }
+ break; /* break out of the for loop */
+ }
+
+ if ((t == TAG_EXIF_OFFSET) || (t == TAG_INTEROP_OFFSET))
+ {
+ offset=Read32u(morder,pval);
+ if ((offset < length) && (level < (DE_STACK_SIZE-2)))
+ {
+ /*
+ Push our current directory state onto the stack.
+ */
+ ifdstack[level]=ifdp;
+ de++; /* bump to the next entry */
+ destack[level]=de;
+ gpsfoundstack[level]=gpsfound;
+ level++;
+ /*
+ Push new state onto of stack to cause a jump.
+ */
+ ifdstack[level]=tiffp+offset;
+ destack[level]=0;
+ gpsfoundstack[level]=MagickFalse;
+ level++;
+ }
+ break; /* break out of the for loop */
+ }
+ }
+ } while (!attribp && (level > 0));
+ return attribp;
+ find_attribute_failure:
+ return (unsigned char *)NULL;
+}
+
+/*
+ SetEXIFOrientation() updates the EXIF orientation tag in the image's EXIF
+ profile to the value provided. Returns MagickPass on success or MagickFail
+ if either there is no EXIF profile in the image, there was an error parsing
+ the EXIF profile, there was no existing EXIF orientation attribute in
+ the EXIF profile or there was a memory allocation error.
+*/
+
+static MagickPassFail
+SetEXIFOrientation(Image *image, const int orientation)
+{
+ MagickPassFail
+ result;
+
+ const unsigned char
+ *current_profile;
+
+ size_t
+ profile_length;
+
+ unsigned char
+ *orientp,
+ *pval,
+ *new_profile;
+
+ int
+ morder,
+ current_orientation;
+
+ unsigned short
+ f;
+
+ unsigned long
+ c;
+
+ if (orientation < TopLeftOrientation || orientation > LeftBottomOrientation)
+ return(MagickFail);
+
+ current_profile=GetImageProfile(image,"EXIF",&profile_length);
+ if (current_profile == 0)
+ return(MagickFail);
+
+ /* Clone profile so orientation can be set */
+ new_profile = MagickAllocateMemory(unsigned char *,profile_length);
+ if (new_profile == 0)
+ return(MagickFail);
+
+ result = MagickFail;
+ memcpy(new_profile, current_profile, profile_length);
+ orientp = FindEXIFAttribute(new_profile, profile_length,
+ (unsigned short)EXIF_ORIENTATION, &morder);
+ if (orientp)
+ {
+ /* Make sure EXIF orientation attribute is valid */
+ f=Read16u(morder,orientp+2); /* get the format */
+ c=Read32u(morder,orientp+4); /* get number of components */
+ if ((f == EXIF_FMT_USHORT) && (c == 1))
+ {
+ pval=(unsigned char *) orientp+8;
+ current_orientation=(int)Read16u(morder, pval);
+ if (current_orientation != (unsigned short)orientation)
+ {
+ Write16u(morder, pval, orientation);
+ Write16u(morder, pval+2, 0);
+ result=SetImageProfile(image,"EXIF",new_profile,profile_length);
+ }
+ else
+ result = MagickPass;
+ }
+ }
+ MagickFreeMemory(new_profile);
+
+ return result;
+}
+
+MagickExport MagickPassFail
+SetImageAttribute(Image *image,const char *key,const char *value)
+{
+ ImageAttribute
+ *attribute;
+
+ register ImageAttribute
+ *p;
+
+ int
+ orientation;
+
+ /*
+ Initialize new attribute.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if ((key == (const char *) NULL) || (*key == '\0'))
+ return(MagickFail);
+
+ if (value == (const char *) NULL)
+ {
+ /*
+ Delete attribute from the image attributes list.
+ */
+ for (p=image->attributes; p != (ImageAttribute *) NULL; p=p->next)
+ if (LocaleCompare(key,p->key) == 0)
+ break;
+ if (p == (ImageAttribute *) NULL)
+ return(False);
+ if (p->previous != (ImageAttribute *) NULL)
+ p->previous->next=p->next;
+ else
+ {
+ image->attributes=p->next;
+ if (p->next != (ImageAttribute *) NULL)
+ p->next->previous=(ImageAttribute *) NULL;
+ }
+ if (p->next != (ImageAttribute *) NULL)
+ p->next->previous=p->previous;
+ attribute=p;
+ DestroyImageAttribute(attribute);
+ return(MagickPass);
+ }
+ attribute=MagickAllocateMemory(ImageAttribute *,sizeof(ImageAttribute));
+ if (attribute == (ImageAttribute *) NULL)
+ return(MagickFail);
+ attribute->key=AllocateString(key);
+ attribute->length=0;
+ if (!GetBlobIsOpen(image) &&
+ ((LocaleNCompare(key,"comment",7) == 0) ||
+ (LocaleNCompare(key,"label",5) == 0)))
+ {
+ /*
+ Translate format requests in attribute text when the blob is
+ not open.
+
+ This is really gross since it is assumed that the attribute is
+ supplied by the user and the user intends for translation to
+ occur. However, 'comment' and 'label' attributes may also
+ come from an image file and may contain arbitrary text. As a
+ crude-workaround, translations are only performed when the
+ blob is not open.
+ */
+ attribute->value=TranslateText((ImageInfo *) NULL,image,value);
+ if (attribute->value != (char *) NULL)
+ attribute->length=strlen(attribute->value);
+ }
+ else
+ {
+ /*
+ Use attribute text as is.
+ */
+ attribute->length=strlen(value);
+ attribute->value=MagickAllocateMemory(char *,attribute->length+1);
+ if (attribute->value != (char *) NULL)
+ (void) strlcpy(attribute->value,value,attribute->length+1);
+ }
+ if ((attribute->value == (char *) NULL) ||
+ (attribute->key == (char *) NULL))
+ {
+ DestroyImageAttribute(attribute);
+ return(MagickFail);
+ }
+
+ attribute->previous=(ImageAttribute *) NULL;
+ attribute->next=(ImageAttribute *) NULL;
+ if (image->attributes == (ImageAttribute *) NULL)
+ {
+ image->attributes=attribute;
+ return(MagickPass);
+ }
+ for (p=image->attributes; p != (ImageAttribute *) NULL; p=p->next)
+ {
+ if (LocaleCompare(attribute->key,p->key) == 0)
+ {
+ size_t
+ min_l,
+ realloc_l;
+
+ if (LocaleCompare(attribute->key,"EXIF:Orientation") == 0)
+ {
+ /*
+ Special handling for EXIF orientation tag.
+ If new value differs from existing value,
+ EXIF profile is updated as well if it exists and
+ is valid. Don't append new value to existing value,
+ replace it instead.
+ */
+ orientation = MagickAtoI(value);
+ if (orientation > 0 || orientation <= (int)LeftBottomOrientation)
+ SetEXIFOrientation(image, orientation);
+
+ /* Replace current attribute with new one */
+ attribute->next = p->next;
+ if (p->previous == (ImageAttribute *) NULL)
+ image->attributes=attribute;
+ else
+ p->previous->next = attribute;
+ DestroyImageAttribute(p);
+ return(MagickPass);
+ }
+ else
+ {
+ /*
+ Extend existing text string.
+ */
+ min_l=p->length+attribute->length+1;
+ for (realloc_l=2; realloc_l <= min_l; realloc_l *= 2)
+ { /* nada */};
+ MagickReallocMemory(char *,p->value,realloc_l);
+ if (p->value != (char *) NULL)
+ (void) strcat(p->value+p->length,attribute->value);
+ p->length += attribute->length;
+ DestroyImageAttribute(attribute);
+ }
+ if (p->value != (char *) NULL)
+ return(MagickPass);
+ (void) SetImageAttribute(image,key,NULL);
+ return(MagickFail);
+ }
+ if (p->next == (ImageAttribute *) NULL)
+ break;
+ }
+ /*
+ Place new attribute at the end of the attribute list.
+ */
+ attribute->previous=p;
+ p->next=attribute;
+ return(MagickPass);
+}
diff --git a/magick/attribute.h b/magick/attribute.h
new file mode 100644
index 0000000..9567648
--- /dev/null
+++ b/magick/attribute.h
@@ -0,0 +1,77 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Methods to Get/Set/Destroy Image Text Attributes.
+*/
+#ifndef _MAGICK_ATTRIBUTE_H
+#define _MAGICK_ATTRIBUTE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "magick/image.h"
+
+typedef struct _ImageAttribute
+{
+ char
+ *key, /* identifying key */
+ *value; /* value string */
+
+ size_t
+ length; /* value string length */
+
+ struct _ImageAttribute
+ *previous,
+ *next;
+} ImageAttribute;
+
+/*
+ MagickExported text attribute methods.
+*/
+extern MagickExport const ImageAttribute
+ *GetImageAttribute(const Image *image,const char *key),
+ *GetImageClippingPathAttribute(const Image *image),
+ *GetImageInfoAttribute(const ImageInfo *image_info,const Image *image,const char *key);
+
+extern MagickExport MagickPassFail
+ CloneImageAttributes(Image* clone_image, const Image* original_image),
+ SetImageAttribute(Image *image,const char *key,const char *value);
+
+extern MagickExport void
+ DestroyImageAttributes(Image *image);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+/* Assign value of attribute to double if attribute exists for key */
+#define MagickAttributeToDouble(image,key,variable) \
+{ \
+ const ImageAttribute \
+ *attribute; \
+\
+ if ((attribute=GetImageAttribute(image,key))) \
+ { \
+ variable=strtod(attribute->value,(char **) NULL); \
+ } \
+}
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/average.c b/magick/average.c
new file mode 100644
index 0000000..aba6120
--- /dev/null
+++ b/magick/average.c
@@ -0,0 +1,241 @@
+/*
+% Copyright (C) 2003 - 2008 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% GraphicsMagick Image Averaging Methods.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/monitor.h"
+#include "magick/omp_data_view.h"
+#include "magick/pixel_cache.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% A v e r a g e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The Average() method takes a set of images and averages them together.
+% Each image in the set must have the same width and height. Average()
+% returns a single image with each corresponding pixel component of
+% each image averaged. On failure, a NULL image is returned and
+% exception describes the reason for the failure.
+%
+% The format of the AverageImage method is:
+%
+% Image *AverageImages(Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image sequence.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *AverageImages(const Image *image,ExceptionInfo *exception)
+{
+ ThreadViewDataSet
+ *pixels_sums;
+
+ Image
+ *average_image;
+
+ const Image
+ *last_image;
+
+ long
+ y;
+
+ unsigned long
+ row_count=0;
+
+ double
+ number_scenes;
+
+ unsigned long
+ number_pixels;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Ensure the image are the same size.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if (image->next == (Image *) NULL)
+ ThrowImageException3(ImageError,ImageSequenceIsRequired,
+ UnableToAverageImage);
+ {
+ const Image
+ *next;
+
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ if ((next->columns != image->columns) || (next->rows != image->rows))
+ ThrowImageException3(OptionError,UnableToAverageImageSequence,
+ ImageWidthsOrHeightsDiffer);
+ }
+ }
+ /*
+ Allocate sum accumulation buffer.
+ */
+ number_pixels=image->columns;
+ pixels_sums=AllocateThreadViewDataArray(image,exception,number_pixels,
+ sizeof(DoublePixelPacket));
+ if (pixels_sums == (ThreadViewDataSet *) NULL)
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToAverageImageSequence);
+ /*
+ Initialize average next attributes.
+ */
+ average_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (average_image == (Image *) NULL)
+ {
+ DestroyThreadViewDataSet(pixels_sums);
+ return((Image *) NULL);
+ }
+ average_image->storage_class=DirectClass;
+
+ number_scenes=(double) GetImageListLength(image);
+ last_image=GetLastImageInList(image);
+#if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static) shared(row_count, status)
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register DoublePixelPacket
+ *pixels_sum;
+
+ const Image
+ *next;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_AverageImages)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ pixels_sum=AccessThreadViewData(pixels_sums);
+
+ /*
+ Compute sum over each pixel color component.
+ */
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ ViewInfo
+ *next_view;
+
+ next_view=OpenCacheView((Image *) next);
+ if (next_view == (ViewInfo *) NULL)
+ thread_status=MagickFail;
+ if (next_view != (ViewInfo *) NULL)
+ {
+ p=AcquireCacheViewPixels(next_view,0,y,next->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (p != (const PixelPacket *) NULL)
+ {
+ if (next == image)
+ {
+ for (x=0; x < (long) next->columns; x++)
+ {
+ pixels_sum[x].red=p[x].red;
+ pixels_sum[x].green=p[x].green;
+ pixels_sum[x].blue=p[x].blue;
+ pixels_sum[x].opacity=p[x].opacity;
+ }
+ }
+ else
+ {
+ for (x=0; x < (long) next->columns; x++)
+ {
+ pixels_sum[x].red+=p[x].red;
+ pixels_sum[x].green+=p[x].green;
+ pixels_sum[x].blue+=p[x].blue;
+ pixels_sum[x].opacity+=p[x].opacity;
+ }
+ }
+ }
+ CloseCacheView(next_view);
+ }
+ }
+ /*
+ Average next pixels.
+ */
+ if (thread_status != MagickFail)
+ {
+ register PixelPacket
+ *q;
+
+ q=SetImagePixelsEx(average_image,0,y,average_image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (q != (PixelPacket *) NULL)
+ {
+ for (x=0; x < (long) average_image->columns; x++)
+ {
+ q[x].red=(Quantum) (pixels_sum[x].red/number_scenes+0.5);
+ q[x].green=(Quantum) (pixels_sum[x].green/number_scenes+0.5);
+ q[x].blue=(Quantum) (pixels_sum[x].blue/number_scenes+0.5);
+ q[x].opacity=(Quantum) (pixels_sum[x].opacity/number_scenes+0.5);
+ }
+ if (!SyncImagePixelsEx(average_image,exception))
+ thread_status=MagickFail;
+ }
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_AverageImages)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,average_image->rows))
+ if (!MagickMonitorFormatted(row_count,average_image->rows,exception,
+ "[%s,...,%s] Average image sequence...",
+ image->filename,last_image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ DestroyThreadViewDataSet(pixels_sums);
+
+ if (status == MagickFail)
+ {
+ DestroyImage(average_image);
+ average_image=(Image *) NULL;
+ }
+
+ return(average_image);
+}
+
diff --git a/magick/average.h b/magick/average.h
new file mode 100644
index 0000000..b0c7ee0
--- /dev/null
+++ b/magick/average.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Image Averaging Methods.
+*/
+#ifndef _MAGICK_AVERAGE_H
+#define _MAGICK_AVERAGE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/image.h"
+#include "magick/error.h"
+
+extern MagickExport Image
+ *AverageImages(const Image *,ExceptionInfo *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_AVERAGE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/bit_stream.c b/magick/bit_stream.c
new file mode 100644
index 0000000..6fd852c
--- /dev/null
+++ b/magick/bit_stream.c
@@ -0,0 +1,275 @@
+/*
+ Copyright (C) 2003 - 2015 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Interfaces to deal with marshalling quantums to and from a bit-stream.
+ Written by Bob Friesenhahn, September 2003
+
+*/
+
+#include "magick/studio.h"
+#include "magick/bit_stream.h"
+
+
+static const unsigned int BitAndMasks[33] =
+ {
+ /*
+ Same as (~(~0 << retrieve_bits))
+ */
+ 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
+ 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
+ 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
+ 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
+ 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
+ 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
+ 0x3fffffffU, 0x7fffffffU, 0xffffffffU
+ };
+
+/*
+ Initialize Bit Stream for reading
+*/
+MagickExport void MagickBitStreamInitializeRead(BitStreamReadHandle *bit_stream,
+ const unsigned char *bytes)
+{
+ bit_stream->bytes = bytes;
+ bit_stream->bits_remaining = 8;
+}
+
+/*
+ Return the requested number of bits from the current position in a
+ bit stream. Stream is read in most-significant bit/byte "big endian"
+ order.
+
+ bit_stream - already initialized bit stream.
+ requested_bits - number of bits to read
+*/
+MagickExport unsigned int MagickBitStreamMSBRead(BitStreamReadHandle *bit_stream,
+ const unsigned int requested_bits)
+{
+ register unsigned int
+ remaining_quantum_bits,
+ quantum;
+
+ remaining_quantum_bits = requested_bits;
+ quantum = 0;
+
+ while (remaining_quantum_bits != 0)
+ {
+ register unsigned int
+ octet_bits;
+
+ octet_bits = remaining_quantum_bits;
+ if (octet_bits > bit_stream->bits_remaining)
+ octet_bits = bit_stream->bits_remaining;
+
+ remaining_quantum_bits -= octet_bits;
+ bit_stream->bits_remaining -= octet_bits;
+
+ quantum = (quantum << octet_bits) |
+ ((*bit_stream->bytes >> (bit_stream->bits_remaining))
+ & BitAndMasks[octet_bits]);
+
+ if (bit_stream->bits_remaining == 0)
+ {
+ bit_stream->bytes++;
+ bit_stream->bits_remaining=8;
+ }
+ }
+ return quantum;
+}
+
+/*
+ Initialize Bit Stream for writing
+
+ bit_stream - bit stream to initialize.
+ bytes - byte array to write bits to
+*/
+MagickExport void MagickBitStreamInitializeWrite(BitStreamWriteHandle *bit_stream,
+ unsigned char *bytes)
+{
+ bit_stream->bytes = bytes;
+ bit_stream->bits_remaining = 8;
+}
+
+/*
+ Write quantum using the specified number of bits at the current
+ position in the bit stream. Stream is written in most-significant
+ bit/byte "big endian" order.
+
+ bit_stream - already initialized bit stream.
+ requested_bits - number of bits to write to stream.
+ quantum - value to write.
+*/
+MagickExport void MagickBitStreamMSBWrite(BitStreamWriteHandle *bit_stream,
+ const unsigned int requested_bits,
+ const unsigned int quantum)
+{
+ register unsigned int
+ remaining_quantum_bits = requested_bits;
+
+ while (remaining_quantum_bits != 0)
+ {
+ register unsigned int
+ octet_bits;
+
+ octet_bits = remaining_quantum_bits;
+ if (octet_bits > bit_stream->bits_remaining)
+ octet_bits = bit_stream->bits_remaining;
+
+ remaining_quantum_bits -= octet_bits;
+
+ if (bit_stream->bits_remaining == 8)
+ *bit_stream->bytes = 0;
+
+ bit_stream->bits_remaining -= octet_bits;
+
+ *bit_stream->bytes |=
+ (((quantum >> (remaining_quantum_bits)) &
+ BitAndMasks[octet_bits]) << (bit_stream->bits_remaining));
+
+ if (bit_stream->bits_remaining == 0)
+ {
+ bit_stream->bytes++;
+ bit_stream->bits_remaining=8;
+ }
+ }
+}
+
+/*
+ Initialize Word Stream for reading
+
+ word_stream - stream to initialize.
+ read_func - function to retrieve the next word.
+ read_func_state - state to pass to read_func.
+*/
+MagickExport void MagickWordStreamInitializeRead(WordStreamReadHandle *word_stream,
+ WordStreamReadFunc read_func,
+ void *read_func_state)
+{
+ word_stream->word = 0;
+ word_stream->bits_remaining = 0;
+ word_stream->read_func = read_func;
+ word_stream->read_func_state = read_func_state;
+}
+
+/*
+ Return the requested number of bits from the current position in a
+ 32-bit word stream. Stream is read starting with the least significant
+ bits of the word.
+
+ word_stream - an initialized word reader stream.
+ requested_bits - number of bits to retrieve from the stream.
+*/
+MagickExport unsigned int MagickWordStreamLSBRead(WordStreamReadHandle *word_stream,
+ const unsigned int requested_bits)
+{
+ register unsigned int
+ remaining_quantum_bits,
+ quantum;
+
+ remaining_quantum_bits = requested_bits;
+ quantum = 0;
+
+ while (remaining_quantum_bits != 0)
+ {
+ register unsigned int
+ word_bits;
+
+ if (word_stream->bits_remaining == 0)
+ {
+ word_stream->word=word_stream->read_func(word_stream->read_func_state);
+ word_stream->bits_remaining=32;
+ }
+
+ word_bits = remaining_quantum_bits;
+ if (word_bits > word_stream->bits_remaining)
+ word_bits = word_stream->bits_remaining;
+
+ quantum |= (((word_stream->word >> (32-word_stream->bits_remaining))
+ & BitAndMasks[word_bits]) << (requested_bits-remaining_quantum_bits));
+
+ remaining_quantum_bits -= word_bits;
+ word_stream->bits_remaining -= word_bits;
+ }
+ return quantum;
+}
+
+/*
+ Initialize Word Stream for writing
+
+ word_stream - stream to initialize.
+ write_func_state - state to pass to write_func.
+ write_func - function to retrieve the next word.
+*/
+MagickExport void MagickWordStreamInitializeWrite(WordStreamWriteHandle *word_stream,
+ WordStreamWriteFunc write_func,
+ void *write_func_state)
+{
+ word_stream->word = 0U;
+ word_stream->bits_remaining = 32U;
+ word_stream->write_func = write_func;
+ word_stream->write_func_state = write_func_state;
+}
+
+/*
+ Write quantum using the specified number of bits at the current
+ position in a 32-bit word stream. Samples are output to words
+ starting at the least significant bits of the word.
+
+ Note that since a callback function is used to output the words,
+ the remaining bits in the last word need to be flushed out by
+ invoking MagickWordStreamLSBWriteFlush().
+
+ word_stream - already initialized word stream.
+ requested_bits - number of bits to write to stream.
+ quantum - value to write.
+*/
+MagickExport void MagickWordStreamLSBWrite(WordStreamWriteHandle *word_stream,
+ const unsigned int requested_bits,
+ const unsigned int quantum)
+{
+ register unsigned int
+ remaining_quantum_bits = requested_bits;
+
+ while (remaining_quantum_bits > 0U)
+ {
+ register unsigned int
+ word_bits;
+
+ word_bits = remaining_quantum_bits;
+ if (word_bits > word_stream->bits_remaining)
+ word_bits = word_stream->bits_remaining;
+
+ word_stream->word |=
+ (((quantum >> (requested_bits-remaining_quantum_bits)) &
+ BitAndMasks[word_bits]) << (32-word_stream->bits_remaining));
+
+ remaining_quantum_bits -= word_bits;
+ word_stream->bits_remaining -= word_bits;
+
+ if (word_stream->bits_remaining == 0U)
+ {
+ (void) word_stream->write_func(word_stream->write_func_state,
+ word_stream->word);
+ word_stream->word=0U;
+ word_stream->bits_remaining=32U;
+ }
+ }
+}
+
+/*
+ Write the current output word, regardless of completion. Unset bits
+ are set to zero. Should be used to ensure that last word in word
+ stream is written to the output. May also be used to apply
+ word-level padding at the end of an image row.
+
+ word_stream - already initialized word stream.
+*/
+MagickExport void MagickWordStreamLSBWriteFlush(WordStreamWriteHandle *word_stream)
+{
+ if (word_stream->bits_remaining != 32U)
+ MagickWordStreamLSBWrite(word_stream,word_stream->bits_remaining,0U);
+}
diff --git a/magick/bit_stream.h b/magick/bit_stream.h
new file mode 100644
index 0000000..74f5bf9
--- /dev/null
+++ b/magick/bit_stream.h
@@ -0,0 +1,127 @@
+/*
+ Copyright (C) 2003, 2005, 2009 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Interfaces to deal with marshalling quantums to and from a bit-stream.
+ Written by Bob Friesenhahn, September 2003
+
+*/
+#ifndef _MAGICK_BIT_STREAM_H
+#define _MAGICK_BIT_STREAM_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ /*
+ Bit stream reader "handle"
+ */
+ typedef struct _BitStreamReadHandle
+ {
+ const unsigned char *bytes;
+ unsigned int bits_remaining;
+ } BitStreamReadHandle;
+
+ /*
+ Bit stream writer "handle"
+ */
+ typedef struct _BitStreamWriteHandle
+ {
+ unsigned char *bytes;
+ unsigned int bits_remaining;
+ } BitStreamWriteHandle;
+
+ /*
+ Word reading function.
+
+ read_func_state - state to pass to word reading function.
+ */
+ typedef unsigned long (*WordStreamReadFunc) (void *read_func_state);
+
+ /*
+ Word stream word reader "handle"
+ */
+ typedef struct _WordStreamReadHandle
+ {
+ magick_uint32_t word;
+ unsigned int bits_remaining;
+ WordStreamReadFunc read_func;
+ void *read_func_state;
+ } WordStreamReadHandle;
+
+ /*
+ Word writing function.
+
+ write_func_state - state to pass to word writing function.
+ value - value to write
+ returns number of bytes written.
+ */
+ typedef size_t (*WordStreamWriteFunc) (void *write_func_state,
+ const unsigned long value);
+
+ /*
+ Word stream writer "handle"
+ */
+ typedef struct _WordStreamWriteHandle
+ {
+ magick_uint32_t word;
+ unsigned int bits_remaining;
+ WordStreamWriteFunc write_func;
+ void *write_func_state;
+ } WordStreamWriteHandle;
+
+ extern MagickExport void
+ MagickBitStreamInitializeRead(BitStreamReadHandle *bit_stream,
+ const unsigned char *bytes);
+
+ extern MagickExport unsigned int
+ MagickBitStreamMSBRead(BitStreamReadHandle *bit_stream,
+ const unsigned int requested_bits);
+
+ extern MagickExport void
+ MagickBitStreamInitializeWrite(BitStreamWriteHandle *bit_stream,
+ unsigned char *bytes);
+
+ extern MagickExport void
+ MagickBitStreamMSBWrite(BitStreamWriteHandle *bit_stream,
+ const unsigned int requested_bits,
+ const unsigned int quantum);
+
+ extern MagickExport void
+ MagickWordStreamInitializeRead(WordStreamReadHandle *word_stream,
+ WordStreamReadFunc read_func,
+ void *read_func_state);
+
+ extern MagickExport unsigned int
+ MagickWordStreamLSBRead(WordStreamReadHandle *word_stream,
+ const unsigned int requested_bits);
+
+ extern MagickExport void
+ MagickWordStreamInitializeWrite(WordStreamWriteHandle *word_stream,
+ WordStreamWriteFunc write_func,
+ void *write_func_state);
+
+ extern MagickExport void
+ MagickWordStreamLSBWrite(WordStreamWriteHandle *word_stream,
+ const unsigned int requested_bits,
+ const unsigned int quantum);
+
+ extern MagickExport void
+ MagickWordStreamLSBWriteFlush(WordStreamWriteHandle *word_stream);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_BIT_STREAM_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/blob.c b/magick/blob.c
new file mode 100644
index 0000000..9d1876d
--- /dev/null
+++ b/magick/blob.c
@@ -0,0 +1,5407 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% BBBB L OOO BBBB %
+% B B L O O B B %
+% BBBB L O O BBBB %
+% B B L O O B B %
+% BBBB LLLLL OOO BBBB %
+% %
+% %
+% GraphicsMagick Binary Large OBject Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1999 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+# include "magick/nt_feature.h"
+#endif
+#include "magick/blob.h"
+#include "magick/confirm_access.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/enum_strings.h"
+#include "magick/log.h"
+#include "magick/list.h"
+#include "magick/map.h"
+#include "magick/magick.h"
+#include "magick/magick_endian.h"
+#include "magick/module.h"
+#include "magick/pixel_cache.h"
+#include "magick/resource.h"
+#include "magick/semaphore.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#if defined(HasZLIB)
+# include "zlib.h"
+#endif
+#if defined(HasBZLIB)
+# include "bzlib.h"
+#endif
+
+/*
+ Define declarations.
+*/
+#define DefaultBlobQuantum 65541
+
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ UndefinedStream, /* Closed or open error */
+ FileStream, /* Opened with stdio fopen() or via image_info->file */
+ StandardStream, /* Stdin or stdout (filename "-") */
+ PipeStream, /* Command pipe stream opened via popen() */
+ ZipStream, /* Opened with zlib's gzopen() */
+ BZipStream, /* Opened with bzlib's BZ2_bzopen() */
+ BlobStream /* Memory mapped, or in allocated RAM */
+} StreamType;
+
+/*
+ Typedef declarations.
+*/
+
+typedef union _MagickFileHandle
+{
+ FILE *std; /* stdio handle */
+#if defined(HasBZLIB)
+ BZFILE *bz; /* bzip handle */
+#endif
+#if defined(HasZLIB)
+ gzFile gz; /* zlib handle */
+#endif
+} MagickFileHandle;
+
+struct _BlobInfo
+{
+ size_t
+ block_size, /* I/O block size */
+ length, /* The current size of the BLOB data. */
+ extent, /* The amount of backing store currently allocated */
+ quantum; /* The amount by which to increase the size of the backing store */
+
+ unsigned int
+ mapped, /* True if backing store is a memory mapped file. */
+ eof; /* True if input data has been entirely read. */
+
+ magick_off_t
+ offset, /* Current offset (I/O point) as would be returned by TellBlob() */
+ size; /* Size of the underlying file, or the BLOB */
+
+ MagickBool
+ exempt, /* True if file descriptor should not be closed.*/
+ temporary; /* Associated file is a temporary file */
+
+ unsigned int
+ status; /* Error status. 0 == good */
+
+ StreamType
+ type; /* Classification for how BLOB I/O is implemented. */
+
+ MagickFileHandle
+ handle; /* Handle for I/O (if any) */
+
+ BlobMode
+ mode; /* Blob open mode */
+
+ unsigned char
+ *data; /* Blob or memory mapped data. */
+
+ MagickBool
+ fsync; /* Fsync on close if true */
+
+ SemaphoreInfo
+ *semaphore; /* Lock for reference_count access */
+
+ long
+ reference_count; /* Number of times this blob is referenced. */
+
+ unsigned long
+ signature; /* Numeric value used to evaluate structure integrity. */
+};
+
+typedef union _MagickInt32Union
+{
+ magick_uint32_t
+ uint32;
+
+ magick_int32_t
+ int32;
+
+} MagickInt32Union;
+
+typedef union _MagickInt16Union
+{
+ magick_uint16_t
+ uint16;
+
+ magick_int16_t
+ int16;
+
+} MagickInt16Union;
+
+/*
+ Forward Declarations
+*/
+static int SyncBlob(Image *image);
+
+/*
+ Some systems have unlocked versions of getc & putc which are faster
+ when multi-threading is enabled. Blobs do not require multi-thread
+ support since Images are only allowed to be accessed by one thread at
+ a time. Using the unlocked version improves performance by about 30%.
+*/
+#if defined(HAVE_PTHREAD)
+# if defined(HAVE_GETC_UNLOCKED)
+# undef getc
+# define getc getc_unlocked
+# endif
+# if defined(HAVE_PUTC_UNLOCKED)
+# undef putc
+# define putc putc_unlocked
+# endif
+#endif
+
+static const char *BlobStreamTypeToString(StreamType stream_type)
+{
+ const char
+ *type_string="Undefined";
+
+ switch (stream_type)
+ {
+ case UndefinedStream:
+ type_string="Undefined";
+ break;
+ case FileStream:
+ type_string="File";
+ break;
+ case StandardStream:
+ type_string="Standard";
+ break;
+ case PipeStream:
+ type_string="Pipe";
+ break;
+ case ZipStream:
+ type_string="Zip";
+ break;
+ case BZipStream:
+ type_string="BZip";
+ break;
+ case BlobStream:
+ type_string="Blob";
+ break;
+ }
+ return type_string;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b S t r e a m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadBlobStream() allocates the requested data size, or the amount
+% remaining (whichever is smaller) from a BlobStream. This function
+% should only be invoked for Blobs of type 'BlobStream'. The number of
+% bytes available from the requested length is returned. If fewer bytes
+% are available than requested, the Blob EOF flag is set True. A user
+% provided pointer is updated with the address of the data. This pointer
+% is only valid while the BlobStream remains mapped or allocated.
+%
+% The format of the ReadBlobStream method is:
+%
+% size_t ReadBlobStream(Image *image,const size_t length,void **data)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o length: The requested amount of data.
+%
+% o data: A pointer to where the address of the data should be returned.
+%
+*/
+static inline size_t ReadBlobStream(Image *image,const size_t length,
+ void **data)
+{
+ size_t
+ available;
+
+ if (image->blob->offset >= (magick_off_t) image->blob->length)
+ {
+ image->blob->eof=MagickTrue;
+ return 0;
+ }
+ *data=(void *)(image->blob->data+image->blob->offset);
+ available=Min(length,image->blob->length-image->blob->offset);
+ image->blob->offset+=available;
+ if (available < length)
+ image->blob->eof=True;
+ return available;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b S t r e a m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteBlobStream() writes data to an in-memory Blob This function
+% should only be invoked for Blobs of type 'BlobStream'. The number of
+% bytes written is returned.
+%
+% The format of the WriteBlobStream method is:
+%
+% size_t WriteBlobStream(Image *image,const size_t length,
+% const void *data)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o length: The requested amount of data.
+%
+% o data: A pointer to where the data resides.
+%
+*/
+static void *ExtendBlobWriteStream(Image *image,const size_t length)
+{
+ if ((image->blob->offset+length) >= image->blob->extent)
+ {
+ /* In-memory Blob */
+ image->blob->quantum<<=1;
+ image->blob->extent+=length+image->blob->quantum;
+ MagickReallocMemory(unsigned char *,image->blob->data,image->blob->extent+1);
+ (void) SyncBlob(image);
+ if (image->blob->data == (unsigned char *) NULL)
+ {
+ DetachBlob(image->blob);
+ return 0;
+ }
+ }
+ return image->blob->data+image->blob->offset;
+}
+static inline size_t WriteBlobStream(Image *image,const size_t length,
+ const void *data)
+{
+ void
+ *dest;
+
+ dest=image->blob->data+image->blob->offset;
+ if ((image->blob->offset+length) >= image->blob->extent)
+ if ((dest=ExtendBlobWriteStream(image,length)) == (void *) NULL)
+ return 0;
+
+ (void) memcpy(dest,data,length);
+ image->blob->offset+=length;
+ if (image->blob->offset > (magick_off_t) image->blob->length)
+ image->blob->length=image->blob->offset;
+ return length;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A t t a c h B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AttachBlob() attaches a blob to the BlobInfo structure.
+%
+% The format of the AttachBlob method is:
+%
+% void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o blob_info: Specifies a pointer to a BlobInfo structure.
+%
+% o blob: The address of a character stream in one of the image formats
+% understood by GraphicsMagick.
+%
+% o length: This size_t integer reflects the length in bytes of the blob.
+%
+%
+*/
+MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
+ const size_t length)
+{
+ assert(blob_info != (BlobInfo *) NULL);
+ blob_info->length=length;
+ blob_info->extent=length;
+ blob_info->quantum=DefaultBlobQuantum;
+ blob_info->offset=0;
+ blob_info->type=BlobStream;
+ blob_info->handle.std=(FILE *) NULL;
+#if defined(HasBZLIB)
+ blob_info->handle.bz=(BZFILE *) NULL;
+#endif
+#if defined(HasZLIB)
+ blob_info->handle.gz=(gzFile) NULL;
+#endif
+ blob_info->data=(unsigned char *) blob;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B l o b I s S e e k a b l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BlobIsSeekable() returns MagickTrue if the blob supports seeks
+% (SeekBlob() is functional).
+%
+% The format of the BlobIsSeekable method is:
+%
+% MagickBool BlobIsSeekable(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: Image to query
+%
+%
+*/
+MagickExport MagickBool BlobIsSeekable(const Image *image)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->blob != (const BlobInfo *) NULL);
+
+ return ((image->blob->type == FileStream) ||
+ (image->blob->type == BlobStream));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B l o b R e s e r v e S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BlobReserveSize() sets the output size of the blob or file. This is used
+% as a means to minimize memory or filesystem fragmentation if the final
+% output size is known in advance. While it is possible that file
+% fragmentation is reduced, it is also possible that file write
+% performance is reduced by changing a write operation to a read, modify,
+% write operation.
+%
+% The format of the BlobReserveSize method is:
+%
+% MagickPassFail BlobReserveSize(Image *image, magick_off_t size)
+%
+% A description of each parameter follows:
+%
+% o image: Image to update
+%
+% o size: New output size.
+%
+*/
+MagickExport MagickPassFail BlobReserveSize(Image *image, magick_off_t size)
+{
+ MagickPassFail
+ status;
+
+ status=MagickPass;
+
+ if ((FileStream == image->blob->type) ||
+ ((BlobStream == image->blob->type) &&
+ (image->blob->mapped) && (image->blob->handle.std != (FILE *) NULL)))
+ {
+#if defined(HAVE_POSIX_FALLOCATE)
+ /*
+ FIXME: Solaris 11.2 documentation says that posix_fallocate()
+ reports EINVAL for anything but UFS */
+ int
+ err_status;
+
+ if ((err_status=posix_fallocate(fileno(image->blob->handle.std),
+ 0UL, size)) != 0)
+ {
+ /* ThrowException(&image->exception,BlobError,UnableToWriteBlob,strerror(err_status)); */
+ /* status=MagickFail; */
+ }
+#endif /* HAVE_POSIX_FALLOCATE */
+ }
+
+ if (BlobStream == image->blob->type)
+ {
+ /*
+ In-memory blob
+ */
+ image->blob->extent=size;
+ MagickReallocMemory(unsigned char *,image->blob->data,image->blob->extent+1);
+ (void) SyncBlob(image);
+
+ if (image->blob->data == (unsigned char *) NULL)
+ {
+ ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,
+ NULL);
+
+ DetachBlob(image->blob);
+ status=MagickFail;
+ }
+ }
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Request to reserve %" MAGICK_OFF_F "u output bytes %s",
+ size,
+ (status == MagickFail ? "failed" : "succeeded"));
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B l o b T o F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BlobToFile() writes a blob to a file. It returns MagickFail if an error
+% occurs otherwise MagickPass.
+%
+% The format of the BlobToFile method is:
+%
+% MagickPassFail BlobToFile(const char *filename,const void *blob,
+% const size_t length,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: BlobToFile returns MagickPass on success; otherwise, it
+% returns MagickFail if an error occurs.
+%
+% o filename: Write the blob to this file.
+%
+% o blob: The address of a blob.
+%
+% o length: This length in bytes of the blob.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail BlobToFile(const char *filename,const void *blob,
+ const size_t length,ExceptionInfo *exception)
+{
+ ssize_t
+ count;
+
+ int
+ file;
+
+ register size_t
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(filename != (const char *) NULL);
+ assert(blob != (const void *) NULL);
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Copying memory BLOB to file %s",filename);
+ if (MagickConfirmAccess(FileWriteConfirmAccessMode,filename,exception)
+ == MagickFail)
+ return MagickFail;
+ file=open(filename,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,0777);
+ if (file == -1)
+ {
+ ThrowException(exception,BlobError,UnableToWriteBlob,filename);
+ status=MagickFail;
+ }
+ if (status != MagickFail)
+ {
+ const char
+ *env = NULL;
+
+ size_t
+ block_size;
+
+ block_size=MagickGetFileSystemBlockSize();
+
+ /*
+ Write data to file.
+ */
+ for (i=0; i < length; i+=count)
+ {
+ size_t
+ remaining;
+
+ MAGICK_POSIX_IO_SIZE_T
+ amount;
+
+ remaining=length - i;
+ if (remaining > block_size)
+ amount=(MAGICK_POSIX_IO_SIZE_T) block_size;
+ else
+ amount=(MAGICK_POSIX_IO_SIZE_T) remaining;
+
+ count=write(file,(char *) blob+i,amount);
+ if (count <= 0)
+ break;
+ }
+
+ if (i < length)
+ {
+ if (status != MagickFail)
+ ThrowException(exception,BlobError,UnableToWriteBlob,filename);
+ status=MagickFail;
+ }
+
+ /*
+ Explicitly synchronize file to disk if requested.
+ */
+ env = getenv("MAGICK_IO_FSYNC");
+ if ((env != (const char *) NULL) && (LocaleCompare(env,"TRUE") == 0))
+ {
+ if (fsync(file) == -1)
+ {
+ if (status != MagickFail)
+ ThrowException(exception,BlobError,UnableToWriteBlob,filename);
+ status=MagickFail;
+ }
+ }
+ if (close(file) == -1)
+ {
+ if (status != MagickFail)
+ ThrowException(exception,BlobError,UnableToWriteBlob,filename);
+ status=MagickFail;
+ }
+ }
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B l o b T o I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BlobToImage() implements direct to memory image formats. It returns the
+% blob as an image.
+%
+% The format of the BlobToImage method is:
+%
+% Image *BlobToImage(const ImageInfo *image_info,const void *blob,
+% const size_t length,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o blob: The address of a character stream in one of the image formats
+% understood by GraphicsMagick.
+%
+% o length: This size_t integer reflects the length in bytes of the blob.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
+ const size_t length,ExceptionInfo *exception)
+{
+ const MagickInfo
+ *magick_info;
+
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ image=(Image *) NULL;
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(), "Entering BlobToImage");
+ if ((blob == (const void *) NULL) || (length == 0))
+ {
+ ThrowException(exception,OptionError,NullBlobArgument,
+ image_info->magick);
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Leaving BlobToImage");
+ return((Image *) NULL);
+ }
+ clone_info=CloneImageInfo(image_info);
+ clone_info->blob=(void *) blob;
+ clone_info->length=length;
+ /*
+ Set file magick based on file name or file header if magick was
+ not provided.
+ */
+ if (clone_info->magick[0] == '\0')
+ (void) SetImageInfo(clone_info,SETMAGICK_READ,exception);
+ magick_info=GetMagickInfo(clone_info->magick,exception);
+ if (magick_info == (const MagickInfo *) NULL)
+ {
+ DestroyImageInfo(clone_info);
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Leaving BlobToImage");
+ return((Image *) NULL);
+ }
+ if (magick_info->blob_support)
+ {
+ /*
+ Native blob support for this image format.
+ */
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Using native BLOB support");
+ (void) strlcpy(clone_info->filename,image_info->filename,
+ MaxTextExtent);
+ (void) strlcpy(clone_info->magick,image_info->magick,MaxTextExtent);
+ image=ReadImage(clone_info,exception);
+ if (image != (Image *) NULL)
+ DetachBlob(image->blob);
+ DestroyImageInfo(clone_info);
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Leaving BlobToImage");
+ return(image);
+ }
+ /*
+ Write blob to a temporary file on disk.
+ */
+ {
+ char
+ temporary_file[MaxTextExtent];
+
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Using temporary file");
+ clone_info->blob=(void *) NULL;
+ clone_info->length=0;
+
+ if(!AcquireTemporaryFileName(temporary_file))
+ {
+ ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,
+ clone_info->filename);
+ }
+ else
+ {
+ if (BlobToFile(temporary_file,blob,length,exception) != MagickFail)
+ {
+ clone_info->filename[0]='\0';
+ if (clone_info->magick[0] != '\0')
+ {
+ (void) strlcpy(clone_info->filename,clone_info->magick,sizeof(clone_info->filename));
+ (void) strlcat(clone_info->filename,":",sizeof(clone_info->filename));
+ }
+ (void) strlcat(clone_info->filename,temporary_file,sizeof(clone_info->filename));
+ image=ReadImage(clone_info,exception);
+ /*
+ Restore original user-provided file name field to images
+ in list so that user does not see a temporary file name.
+ */
+ if (image != (Image *) NULL)
+ {
+ Image
+ *list_image;
+
+ list_image = GetFirstImageInList(image);
+ while (list_image != (Image *) NULL)
+ {
+ (void) strlcpy(list_image->magick_filename,image_info->filename,sizeof(list_image->magick_filename));
+ (void) strlcpy(list_image->filename,image_info->filename,sizeof(list_image->filename));
+ list_image = GetNextImageInList(list_image);
+ }
+ }
+ }
+ (void) LiberateTemporaryFile(temporary_file);
+ }
+ }
+ DestroyImageInfo(clone_info);
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(), "Leaving BlobToImage");
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e B l o b I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneBlobInfo() makes a duplicate of the given blob info structure, or if
+% blob info is NULL, a new one.
+%
+% The format of the CloneBlobInfo method is:
+%
+% BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
+%
+% A description of each parameter follows:
+%
+% o clone_info: Method CloneBlobInfo returns a duplicate of the given
+% blob info, or if blob info is NULL a new one.
+%
+% o quantize_info: a structure of type info.
+%
+%
+*/
+MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
+{
+ BlobInfo
+ *clone_info;
+
+ SemaphoreInfo
+ *semaphore;
+
+ clone_info=MagickAllocateMemory(BlobInfo *,sizeof(BlobInfo));
+ if (clone_info == (BlobInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToCloneBlobInfo);
+ GetBlobInfo(clone_info);
+ if (blob_info == (BlobInfo *) NULL)
+ return(clone_info);
+ semaphore=clone_info->semaphore;
+ (void) memcpy(clone_info,blob_info,sizeof(BlobInfo));
+ clone_info->semaphore=semaphore;
+ LockSemaphoreInfo(clone_info->semaphore);
+ clone_info->reference_count=1;
+ UnlockSemaphoreInfo(clone_info->semaphore);
+ return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l o s e B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloseBlob() closes a stream associated with the image.
+%
+% If the blob 'exempt' member is MagickTrue, then any passed file descriptor
+% is left open, otherwise it is closed.
+%
+% The format of the CloseBlob method is:
+%
+% void CloseBlob(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void CloseBlob(Image *image)
+{
+ int
+ status;
+
+ /*
+ Close image file.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ /*
+ If blob was not allocated, is UndefinedStream (closed) then it
+ doesn't need to be closed.
+ */
+ if ((image->blob == (BlobInfo *) NULL) ||
+ (image->blob->type == UndefinedStream))
+ return;
+
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Closing %sStream blob: image %p, blob %p, ref %lu",
+ BlobStreamTypeToString(image->blob->type),
+ image,image->blob,image->blob->reference_count);
+
+ status=0;
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ break;
+ case FileStream:
+ case StandardStream:
+ case PipeStream:
+ {
+ if (image->blob->fsync)
+ {
+ (void) fflush(image->blob->handle.std);
+ (void) fsync(fileno(image->blob->handle.std));
+ }
+ status=ferror(image->blob->handle.std);
+ break;
+ }
+ case ZipStream:
+ {
+#if defined(HasZLIB)
+ (void) gzerror(image->blob->handle.gz,&status);
+#endif
+ break;
+ }
+ case BZipStream:
+ {
+#if defined(HasBZLIB)
+ (void) BZ2_bzerror(image->blob->handle.bz,&status);
+#endif
+ break;
+ }
+ case BlobStream:
+ break;
+ }
+ errno=0;
+ image->taint=MagickFalse;
+ image->blob->size=GetBlobSize(image);
+ image->blob->eof=MagickFalse;
+ image->blob->status=status < 0;
+ image->blob->mode=UndefinedBlobMode;
+
+ /*
+ If we are allowed to close the stream and detatch (destroy)
+ the blob.
+ */
+ if (! image->blob->exempt )
+ {
+ /*
+ Close the underlying stream.
+ */
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ break;
+ case FileStream:
+ case StandardStream:
+ {
+ status=fclose(image->blob->handle.std);
+ break;
+ }
+ case PipeStream:
+ {
+#if defined(HAVE_PCLOSE)
+ status=pclose(image->blob->handle.std);
+#endif /* defined(HAVE_PCLOSE) */
+ break;
+ }
+ case ZipStream:
+ {
+#if defined(HasZLIB)
+ status=gzclose(image->blob->handle.gz);
+#endif
+ break;
+ }
+ case BZipStream:
+ {
+#if defined(HasBZLIB)
+ BZ2_bzclose(image->blob->handle.bz);
+#endif
+ break;
+ }
+ case BlobStream:
+ {
+ break;
+ }
+ }
+ /*
+ Detatch (destroy) the blob.
+ */
+ DetachBlob(image->blob);
+ }
+ image->blob->type=UndefinedStream;
+ image->blob->status=(status != 0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyBlob() deallocates memory associated with a blob. The blob is
+% a reference counted object so the object is only destroyed once its
+% reference count decreases to zero.
+%
+% The format of the DestroyBlob method is:
+%
+% void DestroyBlob(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void DestroyBlob(Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (image->blob != (BlobInfo *) NULL)
+ {
+ MagickBool
+ destroy;
+
+ assert(image->blob->signature == MagickSignature);
+ LockSemaphoreInfo(image->blob->semaphore);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Destroy blob (ref counted): image %p, blob %p,"
+ " ref %lu, filename \"%s\"",
+ image,image->blob,image->blob->reference_count,
+ image->filename);
+ image->blob->reference_count--;
+ assert(image->blob->reference_count >= 0);
+ destroy=(image->blob->reference_count > 0 ? MagickFalse : MagickTrue);
+ UnlockSemaphoreInfo(image->blob->semaphore);
+ if (destroy)
+ {
+ /*
+ Destroy blob object.
+ */
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " Destroy blob (real): image %p, blob %p,"
+ " ref %lu, filename \"%s\"",
+ image,image->blob,
+ image->blob->reference_count,image->filename);
+ if (image->blob->type != UndefinedStream)
+ CloseBlob(image);
+ if (image->blob->mapped)
+ (void) UnmapBlob(image->blob->data,image->blob->length);
+ DestroySemaphoreInfo(&image->blob->semaphore);
+ (void) memset((void *) image->blob,0xbf,sizeof(BlobInfo));
+ MagickFreeMemory(image->blob);
+ }
+ image->blob=(BlobInfo *) NULL;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y B l o b I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyBlobInfo() deallocates memory associated with an BlobInfo structure.
+% The blob is a reference counted object so the object is only destroyed once
+% its reference count decreases to zero. Use of DestroyBlob is preferred over
+% this function since it assures that the blob is closed prior to destruction.
+%
+% This function is no longer used within GraphicsMagick.
+%
+% The format of the DestroyBlobInfo method is:
+%
+% void DestroyBlobInfo(BlobInfo *blob)
+%
+% A description of each parameter follows:
+%
+% o blob: Specifies a pointer to a BlobInfo structure.
+%
+%
+*/
+MagickExport void DestroyBlobInfo(BlobInfo *blob)
+{
+ if (blob != (BlobInfo *) NULL)
+ {
+ MagickBool
+ destroy;
+
+ assert(blob->signature == MagickSignature);
+ LockSemaphoreInfo(blob->semaphore);
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Destroy blob info: blob %p, ref %lu",
+ blob,blob->reference_count);
+ blob->reference_count--;
+ assert(blob->reference_count >= 0);
+ destroy=(blob->reference_count > 0 ? MagickFalse : MagickTrue);
+ UnlockSemaphoreInfo(blob->semaphore);
+ if (destroy)
+ {
+ if (blob->mapped)
+ (void) UnmapBlob(blob->data,blob->length);
+ DestroySemaphoreInfo(&blob->semaphore);
+ (void) memset((void *)blob,0xbf,sizeof(BlobInfo));
+ MagickFreeMemory(blob);
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e t a c h B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DetachBlob() detaches a blob from the BlobInfo structure.
+%
+% The format of the DetachBlob method is:
+%
+% void DetachBlob(BlobInfo *blob_info)
+%
+% A description of each parameter follows:
+%
+% o blob_info: Specifies a pointer to a BlobInfo structure.
+%
+%
+*/
+MagickExport void DetachBlob(BlobInfo *blob_info)
+{
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Detach (reset) blob: blob %p, ref %lu",
+ blob_info,blob_info->reference_count);
+ assert(blob_info != (BlobInfo *) NULL);
+ if (blob_info->mapped)
+ {
+ (void) UnmapBlob(blob_info->data,blob_info->length);
+ LiberateMagickResource(MapResource,blob_info->length);
+ }
+ blob_info->mapped=MagickFalse;
+ blob_info->length=0;
+ blob_info->offset=0;
+ blob_info->eof=MagickFalse;
+ blob_info->exempt=MagickFalse;
+ blob_info->type=UndefinedStream;
+ blob_info->handle.std=(FILE *) NULL;
+#if defined(HasBZLIB)
+ blob_info->handle.bz=(BZFILE *) NULL;
+#endif
+#if defined(HasZLIB)
+ blob_info->handle.gz=(gzFile) NULL;
+#endif
+ blob_info->data=(unsigned char *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ E O F B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EOFBlob() returns a non-zero value when EOF has been detected reading from
+% a blob or file.
+%
+% The format of the EOFBlob method is:
+%
+% int EOFBlob(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method EOFBlob returns 0 on success; otherwise, it
+% returns -1 and set errno to indicate the error.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport int EOFBlob(const Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ break;
+ case FileStream:
+ case StandardStream:
+ case PipeStream:
+ {
+ image->blob->eof=feof(image->blob->handle.std);
+ break;
+ }
+ case ZipStream:
+ {
+ image->blob->eof=MagickFalse;
+ break;
+ }
+ case BZipStream:
+ {
+#if defined(HasBZLIB)
+ int
+ status;
+
+ (void) BZ2_bzerror(image->blob->handle.bz,&status);
+ image->blob->eof=status == BZ_UNEXPECTED_EOF;
+#endif
+ break;
+ }
+ case BlobStream:
+ break;
+ }
+ return(image->blob->eof);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F i l e T o B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FileToBlob() returns the contents of a file in a buffer allocated via
+% MagickMalloc() (which is equivalent to the system malloc() by default).
+% The character '\0' is appended to the buffer in case the buffer will be
+% accessed as a string. The length of the buffer (not including the extra
+% terminating '\0' character) is returned via the 'length' parameter.
+% If an error occurs, a NULL pointer is returned. The returned buffer
+% must be freed by the user in a matter compatible with MagickMalloc()
+% (e.g. via MagickFree()).
+%
+% The format of the FileToBlob method is:
+%
+% void *FileToBlob(const char *filename,size_t *length,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o blob: FileToBlob() returns the contents of a file as a blob. If
+% an error occurs NULL is returned.
+%
+% o filename: The filename.
+%
+% o length: This pointer to a size_t integer sets the initial length of the
+% blob. On return, it reflects the actual length of the blob.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport void *FileToBlob(const char *filename,size_t *length,
+ ExceptionInfo *exception)
+{
+ FILE
+ *file;
+
+ unsigned char
+ *blob;
+
+ assert(filename != (const char *) NULL);
+ assert(length != (size_t *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ blob=(unsigned char *) NULL;
+ /* Open file */
+ if ((file=fopen(filename,"rb")) != (FILE *) NULL)
+ {
+ /* Set buffering size (best effort) */
+ size_t
+ vbuf_size;
+
+ vbuf_size=MagickGetFileSystemBlockSize();
+ if (0 != vbuf_size)
+ (void) setvbuf(file,NULL,_IOFBF,vbuf_size);
+
+ /* Get file length */
+ if (MagickFseek(file,0L,SEEK_END) != -1)
+ {
+ magick_off_t
+ offset;
+
+ if ((offset=MagickFtell(file)) != -1)
+ {
+ *length=(size_t) offset;
+ if ((magick_off_t) *length == offset)
+ {
+ /* Restore position to beginning of file */
+ if (MagickFseek(file,0L,SEEK_SET) != -1)
+ {
+ /* Allocate memory */
+ if ((blob=MagickAllocateMemory(unsigned char *,*length+1))
+ != (unsigned char *) NULL)
+ {
+ /* Read data from file */
+ if (fread(blob,1,*length,file) == *length)
+ {
+ /* Add terminating null byte */
+ blob[*length]='\0';
+ }
+ else
+ {
+ /* Failed to read all the data */
+ MagickFreeMemory(blob);
+ ThrowException3(exception,BlobError,
+ UnableToReadToOffset,
+ UnableToCreateBlob);
+ }
+ }
+ else
+ {
+ /* Failed to allocate the memory */
+ ThrowException(exception,ResourceLimitError,
+ MemoryAllocationFailed,
+ MagickMsg(BlobError,
+ UnableToCreateBlob));
+ }
+ }
+ else
+ {
+ /* Failed to seek back to beginning of file */
+ ThrowException3(exception,BlobError,UnableToSeekToOffset,
+ UnableToCreateBlob);
+ }
+ }
+ else
+ {
+ /* File is too large for size_t */
+ ThrowException(exception,ResourceLimitError,
+ MemoryAllocationFailed,
+ MagickMsg(BlobError,UnableToCreateBlob));
+ }
+ }
+ else
+ {
+ /* Failed to get EOF offset */
+ ThrowException3(exception,BlobError,UnableToSeekToOffset,
+ UnableToCreateBlob);
+ }
+ }
+ else
+ {
+ /* Failed to seek to end of file */
+ ThrowException3(exception,BlobError,UnableToSeekToOffset,
+ UnableToCreateBlob);
+ }
+ (void) fclose(file);
+ file=(FILE *) NULL;
+ }
+ else
+ {
+ /* Failed to open the file */
+ ThrowException(exception,BlobError,UnableToOpenFile,filename);
+ }
+ return(blob);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t B l o b F i l e H a n d l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetBlobFileHandle() returns the stdio file handle associated with the
+% image blob. If there is no associated file handle, then a null pointer
+% is returned.
+%
+% The format of the GetBlobFileHandle method is:
+%
+% FILE *GetBlobFileHandle(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: Image to query
+%
+%
+*/
+MagickExport FILE *GetBlobFileHandle(const Image *image)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->blob != (const BlobInfo *) NULL);
+ return (image->blob->handle.std);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t B l o b I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetBlobInfo() initializes the BlobInfo structure.
+%
+% The format of the GetBlobInfo method is:
+%
+% void GetBlobInfo(BlobInfo *blob_info)
+%
+% A description of each parameter follows:
+%
+% o blob_info: Specifies a pointer to a BlobInfo structure.
+%
+%
+*/
+MagickExport void GetBlobInfo(BlobInfo *blob_info)
+{
+ assert(blob_info != (BlobInfo *) NULL);
+ (void) memset(blob_info,0,sizeof(BlobInfo));
+ blob_info->quantum=DefaultBlobQuantum;
+ blob_info->fsync=MagickFalse;
+ blob_info->semaphore=AllocateSemaphoreInfo();
+ LockSemaphoreInfo(blob_info->semaphore);
+ blob_info->reference_count=1;
+ UnlockSemaphoreInfo(blob_info->semaphore);
+ blob_info->signature=MagickSignature;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t B l o b I s O p e n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetBlobIsOpen() returns MagickTrue if the blob is currently open or
+% MagickFalse if it is currently closed.
+%
+% The format of the GetBlobSize method is:
+%
+% MagickBool GetBlobIsOpen(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport MagickBool GetBlobIsOpen(const Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+
+ return (image->blob->type != UndefinedStream ? MagickTrue : MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t B l o b S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetBlobSize() returns the current length of the image file or blob; zero is
+% returned if the size cannot be determined. If BLOB is no longer open, then
+% return the size when the BLOB was closed.
+%
+% The format of the GetBlobSize method is:
+%
+% magick_off_t GetBlobSize(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o size: Method GetBlobSize returns the current length of the image file
+% or blob.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_off_t GetBlobSize(const Image *image)
+{
+ MagickStatStruct_t
+ attributes;
+
+ magick_off_t
+ offset;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+
+ offset=0;
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ offset=image->blob->size;
+ break;
+ case FileStream:
+ {
+ offset=(MagickFstat(fileno(image->blob->handle.std),&attributes) < 0 ? 0 :
+ attributes.st_size);
+ break;
+ }
+ case StandardStream:
+ case PipeStream:
+ break;
+ case ZipStream:
+ case BZipStream:
+ {
+ offset=(MagickStat(image->filename,&attributes) < 0 ? 0 :
+ attributes.st_size);
+ break;
+ }
+ case BlobStream:
+ {
+ offset=image->blob->length;
+ break;
+ }
+ }
+ return(offset);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t B l o b S t a t u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetBlobStatus() returns the blob error status.
+%
+% The format of the GetBlobStatus method is:
+%
+% int GetBlobStatus(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport int GetBlobStatus(const Image *image)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return(image->blob->status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t B l o b S t r e a m D a t a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetBlobStreamData() returns the stream data for the image. The data is only
+% available if the data is stored on the heap, or is memory mapped.
+% Otherwise a NULL value is returned.
+%
+% The format of the GetBlobStreamData method is:
+%
+% unsigned char *GetBlobStreamData(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport unsigned char *GetBlobStreamData(const Image *image)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (image->blob->type != BlobStream)
+ return 0;
+ return(image->blob->data);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t B l o b T e m p o r a r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetBlobTemporary() returns MagickTrue if the file associated with the blob
+% is a temporary file and should be removed when the associated image is
+% destroyed.
+%
+% The format of the GetBlobTemporary method is:
+%
+% MagickBool GetBlobTemporary(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: Image to query
+%
+%
+*/
+MagickExport MagickBool GetBlobTemporary(const Image *image)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (const BlobInfo *) NULL);
+ assert(image->blob->signature == MagickSignature);
+ return (image->blob->temporary != MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C o n f i g u r e B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetConfigureBlob() returns the specified configure file as a blob.
+%
+% The format of the GetConfigureBlob method is:
+%
+% void *GetConfigureBlob(const char *filename,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o filename: The configure file name.
+%
+% o path: return the full path information of the configure file.
+%
+% o length: This pointer to a size_t integer sets the initial length of the
+% blob. On return, it reflects the actual length of the blob.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+#if !defined(UseInstalledMagick) && defined(POSIX)
+static void ChopPathComponents(char *path,const unsigned long components)
+{
+ long
+ count;
+
+ register char
+ *p;
+
+ if (*path == '\0')
+ return;
+ p=path+strlen(path);
+ if (*p == *DirectorySeparator)
+ *p='\0';
+ for (count=0; (count < (long) components) && (p > path); p--)
+ if (*p == *DirectorySeparator)
+ {
+ *p='\0';
+ count++;
+ }
+}
+#endif
+
+static void AddConfigurePath(MagickMap path_map, unsigned int *path_index,
+ const char *path,ExceptionInfo *exception)
+{
+ char
+ key[MaxTextExtent];
+
+ FormatString(key,"%u",*path_index);
+ (void) MagickMapAddEntry(path_map,key,(void *)path,0,exception);
+ (*path_index)++;
+}
+
+MagickExport void *GetConfigureBlob(const char *filename,char *path,
+ size_t *length,ExceptionInfo *exception)
+{
+ MagickMap
+ path_map;
+
+ MagickMapIterator
+ path_map_iterator;
+
+ const char
+ *key;
+
+ unsigned char
+ *blob=0;
+
+ unsigned int
+ logging,
+ path_index=0;
+
+ assert(filename != (const char *) NULL);
+ assert(path != (char *) NULL);
+ assert(length != (size_t *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ logging=IsEventLogging();
+
+ (void) strlcpy(path,filename,MaxTextExtent);
+ path_map=MagickMapAllocateMap(MagickMapCopyString,MagickMapDeallocateString);
+
+ {
+ /*
+ Allow the configuration file search path to be explicitly
+ specified.
+ */
+ const char
+ *magick_configure_path = getenv("MAGICK_CONFIGURE_PATH");
+ if ( magick_configure_path )
+ {
+ const char
+ *end = NULL,
+ *start = magick_configure_path;
+
+ end=start+strlen(start);
+ while ( start < end )
+ {
+ char
+ buffer[MaxTextExtent];
+
+ const char
+ *separator;
+
+ int
+ string_length;
+
+ separator = strchr(start,DirectoryListSeparator);
+ if (separator)
+ string_length=separator-start;
+ else
+ string_length=end-start;
+ if (string_length > MaxTextExtent-1)
+ string_length = MaxTextExtent-1;
+ (void) strlcpy(buffer,start,string_length+1);
+ if (buffer[string_length-1] != DirectorySeparator[0])
+ (void) strlcat(buffer,DirectorySeparator,sizeof(buffer));
+ AddConfigurePath(path_map,&path_index,buffer,exception);
+ start += string_length+1;
+ }
+ }
+ }
+
+#if defined(UseInstalledMagick)
+
+# if defined(MagickShareConfigPath)
+ AddConfigurePath(path_map,&path_index,MagickShareConfigPath,exception);
+# endif /* defined(MagickShareConfigPath) */
+
+# if defined(MagickLibConfigPath)
+ AddConfigurePath(path_map,&path_index,MagickLibConfigPath,exception);
+# endif /* defined(MagickLibConfigPath) */
+
+# if defined(MSWINDOWS) && !(defined(MagickLibConfigPath) || defined(MagickShareConfigPath))
+ {
+ char
+ *registry_key,
+ *key_value;
+
+ /*
+ Locate file via registry key.
+ */
+ registry_key="ConfigurePath";
+ key_value=NTRegistryKeyLookup(registry_key);
+ if (key_value == (char *) NULL)
+ {
+ ThrowException(exception,ConfigureError,RegistryKeyLookupFailed,registry_key);
+ return 0;
+ }
+
+ FormatString(path,"%.1024s%s",key_value,DirectorySeparator);
+ AddConfigurePath(path_map,&path_index,path,exception);
+ }
+# endif /* defined(MSWINDOWS) */
+
+#else /* !defined(UseInstalledMagick) */
+
+ {
+ const char
+ *magick_home;
+
+ /*
+ Search under MAGICK_HOME.
+ */
+ magick_home=getenv("MAGICK_HOME");
+ if (magick_home)
+ {
+#if defined(POSIX)
+ FormatString(path,"%.1024s/share/%s/",magick_home,
+ MagickShareConfigSubDir);
+ AddConfigurePath(path_map,&path_index,path,exception);
+
+ FormatString(path,"%.1024s/lib/%s/",magick_home,
+ MagickLibConfigSubDir);
+ AddConfigurePath(path_map,&path_index,path,exception);
+#else
+ FormatString(path,"%.1024s%s",magick_home,
+ DirectorySeparator);
+ AddConfigurePath(path_map,&path_index,path,exception);
+#endif /* defined(POSIX) */
+ }
+ }
+
+ if (getenv("HOME") != (char *) NULL)
+ {
+ /*
+ Search $HOME/.magick.
+ */
+ FormatString(path,"%.1024s%s%s",getenv("HOME"),
+ *getenv("HOME") == '/' ? "/.magick" : "",DirectorySeparator);
+ AddConfigurePath(path_map,&path_index,path,exception);
+ }
+
+ if (*SetClientPath((char *) NULL) != '\0')
+ {
+#if defined(POSIX)
+ char
+ prefix[MaxTextExtent];
+
+ /*
+ Search based on executable directory if directory is known.
+ */
+ (void) strlcpy(prefix,SetClientPath((char *) NULL),MaxTextExtent);
+ ChopPathComponents(prefix,1);
+
+ FormatString(path,"%.1024s/lib/%s/",prefix,MagickLibConfigSubDir);
+ AddConfigurePath(path_map,&path_index,path,exception);
+
+ FormatString(path,"%.1024s/share/%s/",prefix,MagickShareConfigSubDir);
+ AddConfigurePath(path_map,&path_index,path,exception);
+#else /* defined(POSIX) */
+ FormatString(path,"%.1024s%s",SetClientPath((char *) NULL),
+ DirectorySeparator);
+ AddConfigurePath(path_map,&path_index,path,exception);
+#endif /* !defined(POSIX) */
+ }
+
+ /*
+ Search current directory.
+ */
+ AddConfigurePath(path_map,&path_index,"",exception);
+#endif /* !defined(UseInstalledMagick) */
+
+ path_map_iterator=MagickMapAllocateIterator(path_map);
+
+ if (logging)
+ {
+ char
+ list_separator[2],
+ *search_path=0;
+
+ list_separator[0]=DirectoryListSeparator;
+ list_separator[1]='\0';
+ while(MagickMapIterateNext(path_map_iterator,&key))
+ {
+ if (search_path)
+ (void) ConcatenateString(&search_path,list_separator);
+ (void) ConcatenateString(&search_path,
+ (const char *) MagickMapDereferenceIterator(path_map_iterator,0));
+ }
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Searching for file \"%s\" in path \"%s\"",filename,search_path);
+
+ MagickFreeMemory(search_path);
+ MagickMapIterateToFront(path_map_iterator);
+ }
+
+ while(MagickMapIterateNext(path_map_iterator,&key))
+ {
+ char
+ test_path[MaxTextExtent];
+
+ FILE
+ *file;
+
+ FormatString(test_path,"%.1024s%.256s",
+ (const char *)MagickMapDereferenceIterator(path_map_iterator,0),
+ filename);
+
+ file=fopen(test_path,"rb");
+ if (file )
+ {
+ if (logging)
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Found: %.1024s",test_path);
+ (void) strcpy(path,test_path);
+ (void) MagickFseek(file,0L,SEEK_END);
+ *length=MagickFtell(file); /* FIXME: ftell returns long, but size_t may be unsigned */
+ if (*length > 0)
+ {
+ (void) MagickFseek(file,0L,SEEK_SET);
+ blob=MagickAllocateMemory(unsigned char *,(*length)+1);
+ if (blob)
+ {
+ *length=fread((void *)blob, 1, *length, file);
+ blob[*length]='\0';
+ }
+ }
+ (void) fclose(file);
+ if (blob)
+ break;
+ }
+
+ if (logging)
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Tried: %.1024s [%.1024s]",test_path,
+ strerror(errno));
+ errno=0;
+ }
+ }
+ MagickMapDeallocateIterator(path_map_iterator);
+ MagickMapDeallocateMap(path_map);
+
+ if (blob)
+ return(blob);
+
+#if defined(MSWINDOWS)
+ {
+ void
+ *resource;
+
+ resource=NTResourceToBlob(filename);
+ if (resource)
+ return resource;
+ }
+#endif /* defined(MSWINDOWS) */
+
+ ThrowException(exception,ConfigureError,UnableToAccessConfigureFile,
+ filename);
+
+ return 0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m a g e T o B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImageToBlob() implements direct to memory image formats. It returns the
+% image as a formatted blob and its length. The magick member of the Image
+% structure determines the format of the returned blob (GIF, JPEG, PNG,
+% etc.). This function is the equivalent of WriteImage(), but writes the
+% formatted "file" to a memory buffer rather than to an actual file.
+%
+% The format of the ImageToBlob method is:
+%
+% void *ImageToBlob(const ImageInfo *image_info,Image *image,
+% size_t *length,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+% o length: This pointer to a size_t integer sets the initial length of the
+% blob. On return, it reflects the actual length of the blob.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport void *ImageToBlob(const ImageInfo *image_info,Image *image,
+ size_t *length,ExceptionInfo *exception)
+{
+ char
+ filename[MaxTextExtent],
+ unique[MaxTextExtent];
+
+ const MagickInfo
+ *magick_info;
+
+ ImageInfo
+ *clone_info;
+
+ unsigned char
+ *blob;
+
+ unsigned int
+ status;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ image->logging=IsEventLogging();
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),"Entering ImageToBlob");
+ /* SetExceptionInfo(exception,UndefinedException); */
+ clone_info=CloneImageInfo(image_info);
+ (void) strlcpy(clone_info->magick,image->magick,MaxTextExtent);
+ magick_info=GetMagickInfo(clone_info->magick,exception);
+ if (magick_info == (const MagickInfo *) NULL)
+ {
+ ThrowException(exception,MissingDelegateError,
+ NoDecodeDelegateForThisImageFormat,clone_info->magick);
+ DestroyImageInfo(clone_info);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Exiting ImageToBlob");
+ return((void *) NULL);
+ }
+ if (magick_info->blob_support)
+ {
+ /*
+ Native blob support for this image format.
+ */
+ clone_info->blob=MagickAllocateMemory(void *,65535L);
+ if (clone_info->blob == (void *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(BlobError,UnableToCreateBlob));
+ DestroyImageInfo(clone_info);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Exiting ImageToBlob");
+ return((void *) NULL);
+ }
+ /* Blob length is initially zero */
+ clone_info->length=0;
+ /* Blob file descriptor should not be closed */
+ image->blob->exempt=True;
+ /* There is no filename for a memory blob */
+ *image->filename='\0';
+ /* Write the image to the blob */
+ status=WriteImage(clone_info,image);
+ if (status == MagickFalse)
+ {
+ /* Only assert our own exception if an exception was not already reported. */
+ if (image->exception.severity == UndefinedException)
+ ThrowException(exception,BlobError,UnableToWriteBlob,
+ clone_info->magick);
+ MagickFreeMemory(image->blob->data);
+ DestroyImageInfo(clone_info);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Exiting ImageToBlob");
+ return((void *) NULL);
+ }
+ /* Request to truncate memory allocation down to memory actually used. */
+ MagickReallocMemory(unsigned char *,image->blob->data,image->blob->length+1);
+ /* Pass blob data and length to user parameters */
+ blob=image->blob->data;
+ *length=image->blob->length;
+ /* Reset BlobInfo to original state (without freeing blob data). */
+ DetachBlob(image->blob);
+ DestroyImageInfo(clone_info);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Exiting ImageToBlob");
+ return(blob);
+ }
+ /*
+ Write file to disk in blob image format.
+ */
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ if (!AcquireTemporaryFileName(unique))
+ {
+ ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,
+ unique);
+ DestroyImageInfo(clone_info);
+ return((void *) NULL);
+ }
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Allocated temporary file \"%s\"",unique);
+ FormatString(image->filename,"%.1024s:%.1024s",image->magick,unique);
+ status=WriteImage(clone_info,image);
+ DestroyImageInfo(clone_info);
+ if (status == MagickFail)
+ {
+ (void) LiberateTemporaryFile(unique);
+ ThrowException(exception,BlobError,UnableToWriteBlob,image->filename);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Exiting ImageToBlob");
+ return((void *) NULL);
+ }
+ /*
+ Read image from disk as blob.
+ */
+ blob=(unsigned char *) FileToBlob(image->filename,length,exception);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Liberating temporary file \"%s\"",image->filename);
+ (void) LiberateTemporaryFile(image->filename);
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ if (blob == (unsigned char *) NULL)
+ {
+ ThrowException(exception,BlobError,UnableToReadFile,filename);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Exiting ImageToBlob");
+ return((void *) NULL);
+ }
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Exiting ImageToBlob");
+ return(blob);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m a g e T o F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImageToFile() copies the input image from an open blob stream to a file.
+% It returns False if an error occurs otherwise True. This function is used
+% to handle coders which are unable to stream the data in using Blob I/O.
+% Instead of streaming the data in, the data is streammed to a temporary
+% file, and the coder accesses the temorary file directly.
+%
+% The format of the ImageToFile method is:
+%
+% MagickPassFail ImageToFile(Image *image,const char *filename,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: ImageToFile returns MagickPass on success; otherwise, it
+% returns MagickFail if an error occurs.
+%
+% o image: The image.
+%
+% o filename: Write the image to this file.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail ImageToFile(Image *image,const char *filename,
+ ExceptionInfo *exception)
+{
+ char
+ *buffer;
+
+ ssize_t
+ count;
+
+ int
+ file;
+
+ register size_t
+ i;
+
+ size_t
+ block_size,
+ length;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(filename != (const char *) NULL);
+
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Copying from Blob stream to file %s",filename);
+ if (MagickConfirmAccess(FileWriteConfirmAccessMode,filename,exception)
+ == MagickFail)
+ return MagickFail;
+ file=open(filename,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,0777);
+ if (file == -1)
+ {
+ ThrowException(exception,BlobError,UnableToWriteBlob,filename);
+ return(MagickFail);
+ }
+ block_size=MagickGetFileSystemBlockSize();
+ buffer=MagickAllocateMemory(char *,block_size);
+ if (buffer == (char *) NULL)
+ {
+ (void) close(file);
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ filename);
+ return(MagickFail);
+ }
+ for (i=0; (length=ReadBlob(image,block_size,buffer)) > 0; )
+ {
+ for (i=0; i < length; i+=count)
+ {
+ count=write(file,buffer+i,(MAGICK_POSIX_IO_SIZE_T) (length-i));
+ if (count <= 0)
+ break;
+ }
+ if (i < length)
+ break;
+ }
+ (void) close(file);
+ MagickFreeMemory(buffer);
+ return(i < length);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a p B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MapBlob() creates a mapping from a file to a binary large object.
+%
+% The format of the MapBlob method is:
+%
+% void *MapBlob(int file,const MapMode mode,off_t offset,size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method MapBlob returns the address of the blob as well as
+% its length in bytes.
+%
+% o file: map this file descriptor.
+%
+% o mode: ReadMode, WriteMode, or IOMode.
+%
+% o offset: starting at this offset within the file.
+%
+% o length: the length of the mapping is returned in this pointer.
+%
+%
+*/
+MagickExport void *MapBlob(int file,const MapMode mode,magick_off_t offset,
+ size_t length)
+{
+#if defined(HAVE_MMAP_FILEIO)
+ void
+ *map;
+
+ /*
+ Map file.
+ */
+ if (file == -1)
+ return((void *) NULL);
+ switch (mode)
+ {
+ case ReadMode:
+ default:
+ {
+ map=(void *) MagickMmap((char *) NULL,length,PROT_READ,MAP_PRIVATE,file,
+ (off_t)offset);
+#if 0
+#if defined(HAVE_MADVISE)
+ if (map != (void *) MAP_FAILED)
+ {
+#if defined(MADV_SEQUENTIAL)
+ /* Note: It has been noticed that madvise() wastes time if
+ the file has been accessed recently so pages are already
+ in RAM. ... */
+ (void) madvise(map,length,MADV_SEQUENTIAL);
+#endif /* defined(MADV_SEQUENTIAL) */
+#if defined(MADV_WILLNEED)
+ (void) madvise(map,length,MADV_WILLNEED);
+#endif /* defined(MADV_WILLNEED) */
+ }
+#endif /* defined(HAVE_MADVISE) */
+#endif
+ break;
+ }
+ case WriteMode:
+ {
+ map=(void *) MagickMmap((char *) NULL,length,PROT_WRITE,MAP_SHARED,file,(off_t)offset);
+#if defined(MADV_SEQUENTIAL)
+ (void) madvise(map,length,MADV_SEQUENTIAL);
+#endif /* defined(MADV_SEQUENTIAL) */
+ break;
+ }
+ case IOMode:
+ {
+ map=(void *) MagickMmap((char *) NULL,length,(PROT_READ | PROT_WRITE),
+ MAP_SHARED,file,(off_t)offset);
+ break;
+ }
+ }
+ if (map == (void *) MAP_FAILED)
+ {
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Failed to mmap fd %d using %s mode at offset %"
+ MAGICK_OFF_F "u and length %" MAGICK_OFF_F
+ "u (%d=\"%s\").",file,MapModeToString(mode),offset,
+ (magick_off_t) length,errno,strerror(errno));
+ return((void *) NULL);
+ }
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Mmapped fd %d using %s mode at offset %" MAGICK_OFF_F
+ "u and length %" MAGICK_OFF_F "u to address %p",
+ file,MapModeToString(mode),offset,(magick_off_t) length,
+ map);
+ return((void *) map);
+#else
+ (void) file;
+ (void) mode;
+ (void) offset;
+ (void) length;
+ return((void *) NULL);
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M S B O r d e r L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MSBOrderLong converts a least-significant byte first buffer
+% of integers to most-significant byte first.
+%
+% The format of the MSBOrderLong method is:
+%
+% void MSBOrderLong(unsigned char *buffer,const size_t length)
+%
+% A description of each parameter follows.
+%
+% o p: Specifies a pointer to a buffer of integers.
+%
+% o length: Specifies the length of the buffer.
+%
+%
+*/
+MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
+{
+ int
+ c;
+
+ register unsigned char
+ *p,
+ *q;
+
+ assert(buffer != (unsigned char *) NULL);
+ q=buffer+length;
+ while (buffer < q)
+ {
+ p=buffer+3;
+ c=(*p);
+ *p=(*buffer);
+ *buffer++=(unsigned char) c;
+ p=buffer+1;
+ c=(*p);
+ *p=(*buffer);
+ *buffer++=(unsigned char) c;
+ buffer+=2;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M S B O r d e r S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MSBOrderShort converts a least-significant byte first buffer of
+% integers to most-significant byte first.
+%
+% The format of the MSBOrderShort method is:
+%
+% void MSBOrderShort(unsigned char *p,const size_t length)
+%
+% A description of each parameter follows.
+%
+% o p: Specifies a pointer to a buffer of integers.
+%
+% o length: Specifies the length of the buffer.
+%
+%
+*/
+MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
+{
+ int
+ c;
+
+ register unsigned char
+ *q;
+
+ assert(p != (unsigned char *) NULL);
+ q=p+length;
+ while (p < q)
+ {
+ c=(*p);
+ *p=(*(p+1));
+ p++;
+ *p++=(unsigned char) c;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ O p e n B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% OpenBlob() opens a file associated with the image. A file name of '-' sets
+% the file to stdin for type 'r' and stdout for type 'w'. If the filename
+% suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
+% compressed for type 'w'.
+%
+% The format of the OpenBlob method is:
+%
+% MagickPassFail OpenBlob(const ImageInfo *image_info,Image *image,
+% const BlobMode mode,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method OpenBlob returns MagickPass if the file is successfully
+% opened otherwise MagickFail.
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+% o mode: The mode for opening the file.
+%
+*/
+
+static void FormMultiPartFilename(Image *image, const ImageInfo *image_info)
+{
+ char
+ filename[MaxTextExtent];
+
+ /*
+ Form filename for multi-part images.
+ */
+ if (MagickSceneFileName(filename,image->filename,"",MagickFalse,
+ GetImageIndexInList(image)))
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+
+ if (!image_info->adjoin)
+ if ((image->previous != (Image *) NULL) ||
+ (image->next != (Image *) NULL))
+ {
+ /* Propagate magick to next image in list. */
+ if (image->next != (Image *) NULL)
+ (void) strlcpy(image->next->magick,image->magick,
+ MaxTextExtent);
+ }
+}
+
+MagickExport MagickPassFail OpenBlob(const ImageInfo *image_info,Image *image,
+ const BlobMode mode,ExceptionInfo *exception)
+{
+ char
+ filename[MaxTextExtent],
+ *type;
+
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Opening blob stream: image %p, blob %p,"
+ " mode %s ...", image, image->blob,
+ BlobModeToString(mode));
+ /*
+ Cache I/O block size
+ */
+ image->blob->block_size=MagickGetFileSystemBlockSize();
+ assert(image->blob->block_size > 0);
+ /*
+ Attach existing memory buffer for I/O and immediately return.
+ */
+ if (image_info->blob != (void *) NULL)
+ {
+ AttachBlob(image->blob,image_info->blob,image_info->length);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " attached data blob (addr %p, len %"
+ MAGICK_SIZE_T_F "u) to image %p, blob %p",
+ image_info->blob,
+ (MAGICK_SIZE_T) image_info->length,
+ image,image->blob);
+ return(MagickPass);
+ }
+ /*
+ Reset BlobInfo to defaults.
+ */
+ DetachBlob(image->blob);
+ image->blob->mode=mode;
+ switch (mode)
+ {
+ default: type=(char *) "r"; break;
+ case ReadBlobMode: type=(char *) "r"; break;
+ case ReadBinaryBlobMode: type=(char *) "rb"; break;
+ case WriteBlobMode: type=(char *) "w"; break;
+ case WriteBinaryBlobMode: type=(char *) "w+b"; break;
+ }
+
+ /*
+ Open image file.
+ */
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ if (LocaleCompare(filename,"-") == 0)
+ {
+ /*
+ Handle stdin/stdout stream
+ */
+ if (*type == 'r')
+ {
+ image->blob->handle.std=stdin;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " using stdin as StandardStream image"
+ " %p, blob %p",
+ image,image->blob);
+ }
+ else
+ {
+ image->blob->handle.std=stdout;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " using stdout as StandardStream image"
+ " %p, blob %p",
+ image,image->blob);
+ }
+#if defined(MSWINDOWS)
+ if (strchr(type,'b') != (char *) NULL)
+ setmode(_fileno(image->blob->handle.std),_O_BINARY);
+#endif
+ image->blob->type=StandardStream;
+ image->blob->exempt=True;
+ }
+ else
+ {
+ if (*type == 'w')
+ {
+ /*
+ Form filename for multi-part images.
+ */
+ if (!image_info->adjoin)
+ FormMultiPartFilename(image,image_info);
+ (void) strcpy(filename,image->filename);
+ }
+#if defined(HasZLIB)
+ if (((strlen(filename) > 2) &&
+ (LocaleCompare(filename+strlen(filename)-2,".Z") == 0)) ||
+ ((strlen(filename) > 3) &&
+ (LocaleCompare(filename+strlen(filename)-3,".gz") == 0)) ||
+ ((strlen(filename) > 5) &&
+ (LocaleCompare(filename+strlen(filename)-5,".svgz") == 0)))
+ {
+ image->blob->handle.gz=(gzFile) NULL;
+ if (MagickConfirmAccess((type[0] == 'r' ? FileReadConfirmAccessMode :
+ FileWriteConfirmAccessMode),filename,
+ exception) != MagickFail)
+ image->blob->handle.gz=gzopen(filename,type);
+ if (image->blob->handle.gz != (gzFile) NULL)
+ {
+ image->blob->type=ZipStream;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " opened file %s as ZipStream image"
+ " %p, blob %p",
+ filename,image,image->blob);
+ }
+ }
+ else
+#endif
+#if defined(HasBZLIB)
+ if ((strlen(filename) > 4) &&
+ (LocaleCompare(filename+strlen(filename)-4,".bz2") == 0))
+ {
+ image->blob->handle.bz=(BZFILE *) NULL;
+ if (MagickConfirmAccess((type[0] == 'r' ? FileReadConfirmAccessMode :
+ FileWriteConfirmAccessMode),filename,
+ exception) != MagickFail)
+ image->blob->handle.bz=(BZFILE *) BZ2_bzopen(filename,type);
+ if (image->blob->handle.bz != (BZFILE *) NULL)
+ {
+ image->blob->type=BZipStream;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " opened file %s as BZipStream image"
+ " %p, blob %p",
+ filename,image,image->blob);
+ }
+ }
+ else
+#endif
+ if (image_info->file != (FILE *) NULL)
+ {
+ image->blob->handle.std=image_info->file;
+ image->blob->type=FileStream;
+ image->blob->exempt=MagickTrue;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " opened image_info->file (%d) as"
+ " FileStream image %p, blob %p",
+ fileno(image_info->file),image,image->blob);
+ }
+ else
+ {
+ image->blob->handle.std=(FILE *) NULL;
+ if (MagickConfirmAccess((type[0] == 'r' ? FileReadConfirmAccessMode :
+ FileWriteConfirmAccessMode),filename,
+ exception) != MagickFail)
+ image->blob->handle.std=(FILE *) fopen(filename,type);
+ if (image->blob->handle.std != (FILE *) NULL)
+ {
+ char
+ *env = NULL;
+
+ unsigned char
+ magick[MaxTextExtent];
+
+ size_t
+ count;
+
+ size_t
+ vbuf_size;
+
+ vbuf_size=image->blob->block_size;
+ if (0 != vbuf_size)
+ {
+ if (setvbuf(image->blob->handle.std,NULL,_IOFBF,vbuf_size) != 0)
+ {
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " setvbuf of %" MAGICK_SIZE_T_F
+ "u bytes returns failure!",
+ (MAGICK_SIZE_T) vbuf_size);
+ }
+ else
+ {
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " I/O buffer set to %"
+ MAGICK_SIZE_T_F "u bytes",
+ (MAGICK_SIZE_T) vbuf_size);
+ }
+ }
+ /*
+ Enable fsync-on-close mode if requested.
+ */
+ if (((WriteBlobMode == mode) || (WriteBinaryBlobMode == mode)) &&
+ (env = getenv("MAGICK_IO_FSYNC")))
+ {
+ if (LocaleCompare(env,"TRUE") == 0)
+ {
+ image->blob->fsync=MagickTrue;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " fsync() on close requested");
+ }
+ }
+ image->blob->type=FileStream;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " opened file \"%s\" as FileStream image %p, blob %p",
+ filename,image,image->blob);
+
+ if ((ReadBlobMode == mode) || (ReadBinaryBlobMode == mode))
+ {
+ /*
+ Read file header and check magick bytes.
+ */
+ (void) memset((void *) magick,0,MaxTextExtent);
+ count=fread(magick,1,MaxTextExtent,image->blob->handle.std);
+ (void) MagickFseek(image->blob->handle.std,
+ -(magick_off_t) count,SEEK_CUR);
+#if defined(POSIX)
+ /*
+ Discard any buffered input and adjust the
+ file pointer such that the next input
+ operation accesses the byte after the last
+ one read. This avoids possible problems if
+ the fseek()/rewind() implementations do not
+ implicitly empty the stdio input buffer.
+ */
+ (void) fflush(image->blob->handle.std);
+#endif /* defined(POSIX) */
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " read %" MAGICK_SIZE_T_F
+ "u magic header bytes",
+ (MAGICK_SIZE_T) count);
+#if defined(HasZLIB)
+ if ((magick[0] == 0x1FU) && (magick[1] == 0x8BU) &&
+ (magick[2] == 0x08U))
+ {
+ (void) fclose(image->blob->handle.std);
+ image->blob->handle.gz=gzopen(filename,type);
+ if (image->blob->handle.gz != (gzFile) NULL)
+ {
+ image->blob->type=ZipStream;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " reopened file \"%s\""
+ "as ZipStream image %p, blob %p",
+ filename,image,image->blob);
+ }
+ }
+#endif
+#if defined(HasBZLIB)
+ if (strncmp((char *) magick,"BZh",3) == 0)
+ {
+ (void) fclose(image->blob->handle.std);
+ image->blob->handle.bz=BZ2_bzopen(filename,type);
+ if (image->blob->handle.bz != (BZFILE *) NULL)
+ {
+ image->blob->type=BZipStream;
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ " reopened file %s as"
+ " BZipStream image %p, blob %p",
+ filename,image,image->blob);
+ }
+ }
+#endif
+ }
+ }
+ }
+ if (image->blob->type == FileStream)
+ {
+ const char* env_val;
+
+ if (*type == 'r')
+ {
+ /*
+ Support reading from a file using memory mapping.
+
+ This code was used for years and definitely speeds
+ re-reading of the same file, but it has been
+ discovered that some operating systems (e.g. FreeBSD
+ and Apple's OS-X) fail to perform automatic
+ read-ahead for network files. It will be disabled
+ by default until we add a way to force read-ahead.
+ */
+ if (((env_val = getenv("MAGICK_MMAP_READ")) != NULL) &&
+ (LocaleCompare(env_val,"TRUE") == 0))
+ {
+ const MagickInfo
+ *magick_info;
+
+ MagickStatStruct_t
+ attributes;
+
+ magick_info=GetMagickInfo(image_info->magick,&image->exception);
+ if ((magick_info != (const MagickInfo *) NULL) &&
+ magick_info->blob_support)
+ {
+ if ((MagickFstat(fileno(image->blob->handle.std),&attributes) >= 0) &&
+ (attributes.st_size > MinBlobExtent) &&
+ (attributes.st_size == (off_t) ((size_t) attributes.st_size)))
+ {
+ size_t
+ length;
+
+ void
+ *blob;
+
+ length=(size_t) attributes.st_size;
+
+ if (AcquireMagickResource(MapResource,length))
+ {
+ blob=MapBlob(fileno(image->blob->handle.std),ReadMode,0,length);
+ if (blob != (void *) NULL)
+ {
+ /*
+ Format supports blobs-- use memory-mapped I/O.
+ */
+ if (image_info->file != (FILE *) NULL)
+ image->blob->exempt=MagickFalse;
+ else
+ {
+ (void) fclose(image->blob->handle.std);
+ image->blob->handle.std=(FILE *) NULL;
+ }
+ AttachBlob(image->blob,blob,length);
+ image->blob->mapped=True;
+ }
+ else
+ {
+ LiberateMagickResource(MapResource,length);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ image->blob->status=MagickFalse;
+ if (image->blob->type != UndefinedStream)
+ image->blob->size=GetBlobSize(image);
+ if (*type == 'r')
+ {
+ image->next=(Image *) NULL;
+ image->previous=(Image *) NULL;
+ }
+ if (UndefinedStream == image->blob->type)
+ {
+ if (UndefinedException == exception->severity)
+ ThrowException(exception,FileOpenError,UnableToOpenFile,filename);
+ return MagickFail;
+ }
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i n g B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PingBlob() returns all the attributes of an image or image sequence except
+% for the pixels. It is much faster and consumes far less memory than
+% BlobToImage(). On failure, a NULL image is returned and exception
+% describes the reason for the failure.
+%
+%
+% The format of the PingBlob method is:
+%
+% Image *PingBlob(const ImageInfo *image_info,const void *blob,
+% const size_t length,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o blob: The address of a character stream in one of the image formats
+% understood by GraphicsMagick.
+%
+% o length: This size_t integer reflects the length in bytes of the blob.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+%
+*/
+MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
+ const size_t length,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ clone_info=CloneImageInfo(image_info);
+ clone_info->ping=MagickTrue;
+ image=BlobToImage(clone_info,blob,length,exception);
+ DestroyImageInfo(clone_info);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadBlob() reads data from the blob or image file and returns it. It
+% returns the number of bytes read.
+%
+% The format of the ReadBlob method is:
+%
+% size_t ReadBlob(Image *image,const size_t length,void *data)
+%
+% A description of each parameter follows:
+%
+% o count: Method ReadBlob returns the number of bytes read.
+%
+% o image: The image.
+%
+% o length: Specifies an integer representing the number of bytes
+% to read from the file.
+%
+% o data: Specifies an area to place the information requested from
+% the file.
+%
+%
+*/
+MagickExport size_t ReadBlob(Image *image,const size_t length,void *data)
+{
+ size_t
+ count;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+ assert(data != (void *) NULL);
+
+ count=0;
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ break;
+ case FileStream:
+ case StandardStream:
+ case PipeStream:
+ {
+ if (length == 1)
+ {
+ int
+ c;
+
+ if ((c=getc(image->blob->handle.std)) != EOF)
+ {
+ *((unsigned char *)data)=(unsigned char) c;
+ count=1;
+ }
+ else
+ {
+ count=0;
+ }
+ }
+ else
+ {
+ count=fread(data,1,length,image->blob->handle.std);
+ }
+ break;
+ }
+ case ZipStream:
+ {
+#if defined(HasZLIB)
+ size_t
+ i;
+
+ for (i=0; i < length; i+=count)
+ {
+ size_t
+ remaining;
+
+ unsigned int
+ amount;
+
+ remaining=length - i;
+ if (remaining > image->blob->block_size)
+ amount=(unsigned int) image->blob->block_size;
+ else
+ amount=(unsigned int) remaining;
+
+ count=gzread(image->blob->handle.gz,
+ (void *) ((unsigned char *) data+i),amount);
+ if (count <= 0)
+ break;
+ }
+ count=i;
+#endif
+ break;
+ }
+ case BZipStream:
+ {
+#if defined(HasBZLIB)
+ size_t
+ i;
+
+ for (i=0; i < length; i+=count)
+ {
+ size_t
+ remaining;
+
+ int
+ amount;
+
+ remaining=length - i;
+ if (remaining > image->blob->block_size)
+ amount=(int) image->blob->block_size;
+ else
+ amount=(int) remaining;
+
+ count=BZ2_bzread(image->blob->handle.bz,
+ (void *) ((unsigned char *) data+i),amount);
+ if (count <= 0)
+ break;
+ }
+ count=i;
+#endif
+ break;
+ }
+ case BlobStream:
+ {
+ void
+ *source_void = 0;
+
+ const unsigned char
+ *source;
+
+ count=ReadBlobStream(image,length,&source_void);
+ source=source_void;
+ if (count <= 10)
+ {
+ register size_t
+ i;
+
+ register unsigned char
+ *target=(unsigned char*) data;
+
+ for(i=count; i > 0; i--)
+ {
+ *target=*source;
+ target++;
+ source++;
+ }
+ }
+ else
+ (void) memcpy(data,source,count);
+ break;
+ }
+ }
+ return(count);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b Z C %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadBlobZC() reads data from the blob or image file and returns it. It
+% returns the number of bytes read. Provision is made for a "zero-copy"
+% transfer if the blob data is already in memory.
+%
+% This method is currently EXPERIMENTAL!
+%
+% The format of the ReadBlob method is:
+%
+% size_t ReadBlob(Image *image,const size_t length,void *data)
+%
+% A description of each parameter follows:
+%
+% o count: Method ReadBlob returns the number of bytes read.
+%
+% o image: The image.
+%
+% o length: Specifies an integer representing the number of bytes
+% to read from the file.
+%
+% o data: Specifies an area to place the information requested from
+% the file. If the data may be accessed without a copy, then
+% the provided pointer is updated to point to the location of
+% the data in memory, and no copy is performed.
+%
+%
+*/
+MagickExport size_t ReadBlobZC(Image *image,const size_t length,void **data)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+ assert(data != (void *) NULL);
+
+ if (image->blob->type == BlobStream)
+ return (ReadBlobStream(image,length,data));
+
+ assert(*data != (void *) NULL);
+ return ReadBlob(image,length,*data);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b B y t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobByte reads a single byte from the image file and returns it.
+% An EOF value is returned if there are no more bytes available on the input
+% stream (similar to stdio's fgetc()).
+%
+% The format of the ReadBlobByte method is:
+%
+% int ReadBlobByte(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobByte returns an integer read from the file.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport int ReadBlobByte(Image *image)
+{
+ unsigned char
+ c;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ switch (image->blob->type)
+ {
+ case FileStream:
+ case StandardStream:
+ case PipeStream:
+ {
+ return getc(image->blob->handle.std);
+ }
+ case BlobStream:
+ {
+ if (image->blob->offset < (magick_off_t) image->blob->length)
+ {
+ c=*((unsigned char *)image->blob->data+image->blob->offset);
+ image->blob->offset++;
+ return (c);
+ }
+ image->blob->eof=True;
+ break;
+ }
+ default:
+ {
+ /* Do things the slow way */
+ if (ReadBlob(image,1,&c) == 1)
+ return (c);
+ }
+ }
+ return(EOF);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B D o u b l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBDouble reads a double value as a 64 bit quantity in
+% least-significant byte first order. If insufficient octets are available
+% to compose the value, then zero is returned, and EOFBlob() may be used to
+% detect that the input is in EOF state.
+%
+% The format of the ReadBlobLSBDouble method is:
+%
+% double ReadBlobLSBDouble(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBDouble returns a double read from
+% the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport double ReadBlobLSBDouble(Image * image)
+{
+ union
+ {
+ double d;
+ unsigned char chars[8];
+ } dbl_buffer;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(sizeof(dbl_buffer) == sizeof(double));
+
+ if (ReadBlob(image, 8, dbl_buffer.chars) != 8)
+ dbl_buffer.d = 0.0;
+
+#if defined(WORDS_BIGENDIAN)
+ MagickSwabDouble(&dbl_buffer.d);
+#endif
+
+ return (dbl_buffer.d);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B D o u b l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBDoubles reads an array of little-endian 64-bit "double"
+% values from the file or BLOB and returns them in native order.
+%
+% The format of the ReadBlobLSBDoubles method is:
+%
+% size_t ReadBlobLSBDoubles(Image *image, size_t octets, double *data)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBDoubles returns the number of octets
+% which were actually read.
+%
+% o image: The image.
+%
+% o octets: The number of bytes of data to read.
+%
+% o data: The address of a user-supplied buffer in which to write
+% the decoded data. The buffer must be suitably aligned for the
+% data type.
+%
+*/
+MagickExport size_t ReadBlobLSBDoubles(Image *image, size_t octets, double *data)
+{
+ size_t
+ octets_read;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (double *) NULL);
+
+ octets_read=ReadBlob(image,octets,data);
+#if defined(WORDS_BIGENDIAN)
+ if (octets_read >= sizeof(double))
+ MagickSwabArrayOfDouble(data,(octets_read+sizeof(double)-1)/sizeof(double));
+#endif
+
+ return octets_read;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBLong reads an unsigned 32 bit value in least-significant
+% byte first order. If insufficient octets are available to compose the
+% value, then zero is returned, and EOFBlob() may be used to detect that
+% the input is in EOF state.
+%
+% The format of the ReadBlobLSBLong method is:
+%
+% magick_uint32_t ReadBlobLSBLong(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBLong returns an unsigned 32-bit value from
+% the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_uint32_t ReadBlobLSBLong(Image *image)
+{
+ unsigned char
+ buffer[4];
+
+ magick_uint32_t
+ value;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image,4,buffer) != 4)
+ return(0U);
+
+ value=buffer[3] << 24;
+ value|=buffer[2] << 16;
+ value|=buffer[1] << 8;
+ value|=buffer[0];
+ return(value & 0xffffffff);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B S i g n e d L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBSignedLong reads an signed 32 bit value in least-significant
+% byte first order. If insufficient octets are available to compose the
+% value, then zero is returned, and EOFBlob() may be used to detect that
+% the input is in EOF state.
+%
+% The format of the ReadBlobLSBSignedLong method is:
+%
+% magick_uint32_t ReadBlobLSBSignedLong(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBSignedLong returns an signed 32-bit value from
+% the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_int32_t ReadBlobLSBSignedLong(Image *image)
+{
+ unsigned char
+ buffer[4];
+
+ MagickInt32Union
+ value;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image,4,buffer) != 4)
+ return(0U);
+
+ value.uint32=buffer[3] << 24;
+ value.uint32|=buffer[2] << 16;
+ value.uint32|=buffer[1] << 8;
+ value.uint32|=buffer[0];
+ value.uint32&=0xffffffff;
+ return value.int32;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B L o n g s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBLongs reads an array of little-endian 32-bit "long"
+% values from the file or BLOB and returns them in native order.
+%
+% The format of the ReadBlobLSBLongs method is:
+%
+% size_t ReadBlobLSBLongs(Image *image, size_t octets,
+% magick_uint32_t *data)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBLongs returns the number of octets
+% which were actually read.
+%
+% o image: The image.
+%
+% o octets: The number of bytes of data to read.
+%
+% o data: The address of a user-supplied buffer in which to write
+% the decoded data. The buffer must be suitably aligned for the
+% data type.
+%
+*/
+MagickExport size_t ReadBlobLSBLongs(Image *image, size_t octets,
+ magick_uint32_t *data)
+{
+ size_t
+ octets_read;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (magick_uint32_t *) NULL);
+
+ octets_read=ReadBlob(image,octets,data);
+#if defined(WORDS_BIGENDIAN)
+ if (octets_read >= sizeof(magick_uint32_t))
+ MagickSwabArrayOfUInt32(data,(octets_read+sizeof(magick_uint32_t)-1)/sizeof(magick_uint32_t));
+#endif
+
+ return octets_read;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBShort reads a 16-bit unsigned value in least-significant
+% byte first order. If insufficient octets are available to compose the
+% value, then zero is returned, and EOFBlob() may be used to detect that
+% the input is in EOF state.
+%
+% The format of the ReadBlobLSBShort method is:
+%
+% magick_uint16_t ReadBlobLSBShort(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBShort returns an unsigned 16-bit value
+% read from the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_uint16_t ReadBlobLSBShort(Image *image)
+{
+ unsigned char
+ buffer[2];
+
+ magick_uint16_t
+ value;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image,2,buffer) != 2)
+ return(0U);
+
+ value=buffer[1] << 8;
+ value|=buffer[0];
+ return(value & 0xffff);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B S i g n e d S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBSignedShort reads a 16-bit signed value in
+% least-significant byte first order. If insufficient octets are available
+% to compose the value, then zero is returned, and EOFBlob() may be used to
+% detect that the input is in EOF state.
+%
+% The format of the ReadBlobLSBSignedShort method is:
+%
+% magick_int16_t ReadBlobLSBSignedShort(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBSignedShort returns an signed 16-bit value
+% read from the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_int16_t ReadBlobLSBSignedShort(Image *image)
+{
+ unsigned char
+ buffer[2];
+
+ MagickInt16Union
+ value;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image,2,buffer) != 2)
+ return(0U);
+
+ value.uint16=buffer[1] << 8;
+ value.uint16|=buffer[0];
+ value.uint16&=0xffff;
+ return value.int16;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B F l o a t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBFloat reads a float value as a 32 bit quantity in
+% least-significant byte first order. If insufficient octets are available
+% to compose the value, then zero is returned, and EOFBlob() may be used to
+% detect that the input is in EOF state.
+%
+% The format of the ReadBlobLSBFloat method is:
+%
+% float ReadBlobLSBFloat(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBFloat returns a float read from
+% the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport float ReadBlobLSBFloat(Image * image)
+{
+ union
+ {
+ float f;
+ unsigned char chars[4];
+ } flt_buffer;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(sizeof(flt_buffer) == sizeof(float));
+
+ if (ReadBlob(image, 4, flt_buffer.chars) != 4)
+ flt_buffer.f = 0.0;
+
+#if defined(WORDS_BIGENDIAN)
+ MagickSwabFloat(&flt_buffer.f);
+#endif
+
+ return (flt_buffer.f);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B F l o a t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBFloats reads an array of little-endian 32-bit "float"
+% values from the file or BLOB and returns them in native order.
+%
+% The format of the ReadBlobLSBFloats method is:
+%
+% size_t ReadBlobLSBFloats(Image *image, size_t octets, float *data)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBFloats returns the number of octets
+% which were actually read.
+%
+% o image: The image.
+%
+% o octets: The number of bytes of data to read.
+%
+% o data: The address of a user-supplied buffer in which to write
+% the decoded data. The buffer must be suitably aligned for the
+% data type.
+%
+*/
+MagickExport size_t ReadBlobLSBFloats(Image *image, size_t octets, float *data)
+{
+ size_t
+ octets_read;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (float *) NULL);
+
+ octets_read=ReadBlob(image,octets,data);
+#if defined(WORDS_BIGENDIAN)
+ if (octets_read >= sizeof(float))
+ MagickSwabArrayOfFloat(data,(octets_read+sizeof(float)-1)/sizeof(float));
+#endif
+
+ return octets_read;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B F l o a t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobMSBFloat reads a float value as a 32 bit quantity in
+% most-significant byte first order. If insufficient octets are available
+% to compose the value, then zero is returned, and EOFBlob() may be used to
+% detect that the input is in EOF state.
+%
+% The format of the ReadBlobMSBFloat method is:
+%
+% float ReadBlobMSBFloat(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBFloat returns a float read from
+% the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport float ReadBlobMSBFloat(Image * image)
+{
+ union
+ {
+ float f;
+ unsigned char chars[4];
+ } flt_buffer;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(sizeof(flt_buffer) == sizeof(float));
+
+ if (ReadBlob(image, 4, flt_buffer.chars) != 4)
+ flt_buffer.f = 0.0;
+
+#if !defined(WORDS_BIGENDIAN)
+ MagickSwabFloat(&flt_buffer.f);
+#endif
+
+ return (flt_buffer.f);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B F l o a t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobMSBFloats reads an array of big-endian 32-bit "float"
+% values from the file or BLOB and returns them in native order.
+%
+% The format of the ReadBlobMSBFloats method is:
+%
+% size_t ReadBlobMSBFloats(Image *image, size_t octets, float *data)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBFloats returns the number of octets
+% which were actually read.
+%
+% o image: The image.
+%
+% o octets: The number of bytes of data to read.
+%
+% o data: The address of a user-supplied buffer in which to write
+% the decoded data. The buffer must be suitably aligned for the
+% data type.
+%
+*/
+MagickExport size_t ReadBlobMSBFloats(Image *image, size_t octets, float *data)
+{
+ size_t
+ octets_read;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (float *) NULL);
+
+ octets_read=ReadBlob(image,octets,data);
+#if !defined(WORDS_BIGENDIAN)
+ if (octets_read >= sizeof(float))
+ MagickSwabArrayOfFloat(data,(octets_read+sizeof(float)-1)/sizeof(float));
+#endif
+
+ return octets_read;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B D o u b l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobMSBDouble reads a double value as a 64 bit quantity in
+% most-significant byte first order. If insufficient octets are available
+% to compose the value, then zero is returned, and EOFBlob() may be used
+% to detect that the input is in EOF state.
+%
+% The format of the ReadBlobMSBDouble method is:
+%
+% double ReadBlobMSBDouble(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBDouble returns a double read from
+% the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport double ReadBlobMSBDouble(Image * image)
+{
+ union
+ {
+ double d;
+ unsigned char chars[8];
+ } dbl_buffer;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(sizeof(dbl_buffer) == sizeof(double));
+
+ if (ReadBlob(image, 8, dbl_buffer.chars) != 8)
+ dbl_buffer.d = 0.0;
+
+#if !defined(WORDS_BIGENDIAN)
+ MagickSwabDouble(&dbl_buffer.d);
+#endif
+
+ return (dbl_buffer.d);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B D o u b l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobMSBDoubles reads an array of big-endian 64-bit "double"
+% values from the file or BLOB and returns them in native order.
+%
+% The format of the ReadBlobMSBDoubles method is:
+%
+% size_t ReadBlobMSBDoubles(Image *image, size_t octets, double *data)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBDoubles returns the number of octets
+% which were actually read.
+%
+% o image: The image.
+%
+% o octets: The number of bytes of data to read.
+%
+% o data: The address of a user-supplied buffer in which to write
+% the decoded data. The buffer must be suitably aligned for the
+% data type.
+%
+*/
+MagickExport size_t ReadBlobMSBDoubles(Image *image, size_t octets, double *data)
+{
+ size_t
+ octets_read;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (double *) NULL);
+
+ octets_read=ReadBlob(image,octets,data);
+#if !defined(WORDS_BIGENDIAN)
+ if (octets_read > 0)
+ MagickSwabArrayOfDouble(data,(octets_read+sizeof(double)-1)/sizeof(double));
+#endif
+
+ return octets_read;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadBlobMSBLong() reads a 32 bit unsigned value in most-significant byte
+% first order. If insufficient octets are available to compose the value,
+% then zero is returned, and EOFBlob() may be used to detect that the input
+% is in EOF state.
+%
+% The format of the ReadBlobMSBLong method is:
+%
+% magick_uint32_t ReadBlobMSBLong(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBLong returns an unsigned 32-bit value
+% read from the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+%
+*/
+MagickExport magick_uint32_t ReadBlobMSBLong(Image *image)
+{
+ unsigned char
+ buffer[4];
+
+ magick_uint32_t
+ value;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image,4,buffer) != 4)
+ return(0U);
+
+ value=buffer[0] << 24;
+ value|=buffer[1] << 16;
+ value|=buffer[2] << 8;
+ value|=buffer[3];
+ return(value & 0xffffffff);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B S i g n e d L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadBlobMSBSignedLong() reads a 32 bit signed value in most-significant byte
+% first order. If insufficient octets are available to compose the value,
+% then zero is returned, and EOFBlob() may be used to detect that the input
+% is in EOF state.
+%
+% The format of the ReadBlobMSBSignedLong method is:
+%
+% magick_int32_t ReadBlobMSBSignedLong(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBSignedLong returns a signed 32-bit value
+% read from the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+%
+*/
+MagickExport magick_int32_t ReadBlobMSBSignedLong(Image *image)
+{
+ unsigned char
+ buffer[4];
+
+ MagickInt32Union
+ value;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image,4,buffer) != 4)
+ return(0);
+
+ value.uint32=buffer[0] << 24;
+ value.uint32|=buffer[1] << 16;
+ value.uint32|=buffer[2] << 8;
+ value.uint32|=buffer[3];
+ value.uint32&=0xffffffff;
+ return value.int32;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobMSBShort reads a 16 bit unsigned value in most-significant
+% byte first order. If insufficient octets are available to compose the
+% value, then zero is returned, and EOFBlob() may be used to detect that
+% the input is in EOF state.
+%
+% The format of the ReadBlobMSBShort method is:
+%
+% magick_uint16_t ReadBlobMSBShort(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBShort returns an unsigned 16-bit value read
+% from the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_uint16_t ReadBlobMSBShort(Image *image)
+{
+ unsigned char
+ buffer[2];
+
+ magick_uint16_t
+ value;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image,2,buffer) != 2)
+ return(0U);
+
+ value=buffer[0] << 8;
+ value|=buffer[1];
+ return(value & 0xffff);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B S i g n e d S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobMSBSignedShort reads a 16 bit signed value in
+% most-significant byte first order. If insufficient octets are available
+% to compose the value, then zero is returned, and EOFBlob() may be used
+% to detect that the input is in EOF state.
+%
+% The format of the ReadBlobMSBSignedShort method is:
+%
+% magick_uint16_t ReadBlobMSBSignedShort(Image *image)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBSignedShort returns an signed 16-bit value read
+% from the file. Zero is returned if insufficient data is available.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_int16_t ReadBlobMSBSignedShort(Image *image)
+{
+ unsigned char
+ buffer[2];
+
+ MagickInt16Union
+ value;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image,2,buffer) != 2)
+ return(0U);
+
+ value.uint16=buffer[0] << 8;
+ value.uint16|=buffer[1];
+ value.uint16&=0xffff;
+ return value.int16;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B S h o r t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobMSBShorts reads an array of big-endian 16-bit "short"
+% values from the file or BLOB and returns them in native order.
+%
+% The format of the ReadBlobMSBShorts method is:
+%
+% size_t ReadBlobMSBShorts(Image *image, size_t octets,
+% magick_uint16_t *data)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBShorts returns the number of octets
+% which were actually read.
+%
+% o image: The image.
+%
+% o octets: The number of bytes of data to read.
+%
+% o data: The address of a user-supplied buffer in which to write
+% the decoded data. The buffer must be suitably aligned for the
+% data type.
+%
+*/
+MagickExport size_t ReadBlobMSBShorts(Image *image, size_t octets,
+ magick_uint16_t *data)
+{
+ size_t
+ octets_read;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (magick_uint16_t *) NULL);
+
+ octets_read=ReadBlob(image,octets,data);
+#if !defined(WORDS_BIGENDIAN)
+ if (octets_read >= sizeof(magick_uint32_t))
+ MagickSwabArrayOfUInt16(data,(octets_read+sizeof(magick_uint16_t)-1)/sizeof(magick_uint16_t));
+#endif
+
+ return octets_read;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadBlobString() reads characters from a blob or file until a newline
+% character is read or an end-of-file condition is encountered. Any
+% terminating newline ('\n') or carriage return ('\r') characters will be
+% removed. The string buffer is assured to be null terminated. NULL
+% is returned if zero bytes were read, otherwise a pointer to the string
+% buffer is returned.
+%
+% The format of the ReadBlobString method is:
+%
+% char *ReadBlobString(Image *image,char *string)
+%
+% A description of each parameter follows:
+%
+% o status: Method ReadBlobString returns the string on success, otherwise,
+% a null is returned.
+%
+% o image: The image.
+%
+% o string: The address of a character buffer, which must be at least
+% MaxTextExtent bytes long.
+%
+%
+*/
+MagickExport char *ReadBlobString(Image *image,char *string)
+{
+ int
+ c;
+
+ register unsigned int
+ i;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ for (i=0; i < (MaxTextExtent-1); i++)
+ {
+ c=ReadBlobByte(image);
+ if (c == EOF)
+ {
+ if (i == 0)
+ return((char *) NULL);
+ break;
+ }
+ string[i]=c;
+ if ((string[i] == '\n') || (string[i] == '\r'))
+ break;
+ }
+ string[i]='\0';
+ return(string);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e f e r e n c e B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReferenceBlob() increments the reference count associated with the pixel
+% blob, returning a pointer to the blob.
+%
+% The format of the ReferenceBlob method is:
+%
+% BlobInfo ReferenceBlob(BlobInfo *blob_info)
+%
+% A description of each parameter follows:
+%
+% o blob_info: The blob_info.
+%
+%
+*/
+MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
+{
+ assert(blob != (BlobInfo *) NULL);
+ assert(blob->signature == MagickSignature);
+ LockSemaphoreInfo(blob->semaphore);
+ blob->reference_count++;
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Reference blob: blob %p, ref %lu",
+ blob,blob->reference_count);
+ UnlockSemaphoreInfo(blob->semaphore);
+ return(blob);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S e e k B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SeekBlob() sets the offset in bytes from the beginning of a blob or file
+% and returns the resulting offset.
+%
+% The format of the SeekBlob method is:
+%
+% magick_off_t SeekBlob(Image *image,const magick_off_t offset,
+% const int whence)
+%
+% A description of each parameter follows:
+%
+% o offset: Method SeekBlob returns the offset from the beginning
+% of the file or blob.
+%
+% o image: The image.
+%
+% o offset: Specifies an integer representing the offset in bytes.
+%
+% o whence: Specifies an integer representing how the offset is
+% treated relative to the beginning of the blob as follows:
+%
+% SEEK_SET Set position equal to offset bytes.
+% SEEK_CUR Set position to current location plus offset.
+% SEEK_END Set position to EOF plus offset.
+%
+%
+*/
+MagickExport magick_off_t SeekBlob(Image *image,const magick_off_t offset,
+ const int whence)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ break;
+ case FileStream:
+ {
+ if (MagickFseek(image->blob->handle.std,offset,whence) < 0)
+ return(-1);
+ image->blob->offset=TellBlob(image);
+ break;
+ }
+ case StandardStream:
+ case PipeStream:
+ return(-1);
+ case ZipStream:
+ {
+#if defined(HasZLIB)
+ if (gzseek(image->blob->handle.gz,(off_t) offset,whence) < 0)
+ return(-1);
+#endif
+ image->blob->offset=TellBlob(image);
+ break;
+ }
+ case BZipStream:
+ return(-1);
+ case BlobStream:
+ {
+ switch (whence)
+ {
+ case SEEK_SET:
+ default:
+ {
+ if (offset < 0)
+ return(-1);
+ image->blob->offset=offset;
+ break;
+ }
+ case SEEK_CUR:
+ {
+ if ((image->blob->offset+offset) < 0)
+ return(-1);
+ image->blob->offset+=offset;
+ break;
+ }
+ case SEEK_END:
+ {
+ if ((magick_off_t)
+ (image->blob->offset+image->blob->length+offset) < 0)
+ return(-1);
+ image->blob->offset=image->blob->length+offset;
+ break;
+ }
+ }
+ if (image->blob->offset <= (magick_off_t) image->blob->length)
+ image->blob->eof=MagickFalse;
+ else
+ if (image->blob->mapped)
+ return(-1);
+ else
+ {
+ image->blob->extent=image->blob->offset+image->blob->quantum;
+ MagickReallocMemory(unsigned char *,image->blob->data,image->blob->extent+1);
+ (void) SyncBlob(image);
+ if (image->blob->data == (unsigned char *) NULL)
+ {
+ DetachBlob(image->blob);
+ return(-1);
+ }
+ }
+ break;
+ }
+ }
+ return(image->blob->offset);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t B l o b C l o s a b l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetBlobClosable() enables closing the blob if MagickTrue is passed, and
+% exempts the blob from being closed if False is passed. Blobs are closable
+% by default (default MagickTrue).
+%
+% The format of the SetBlobClosable method is:
+%
+% void SetBlobClosable(Image *image, MagickBool closeable)
+%
+% A description of each parameter follows:
+%
+% o image: Image to update
+%
+% o closeable: Set to FALSE in order to disable closing the blob.
+%
+*/
+MagickExport void SetBlobClosable(Image *image, MagickBool closeable)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->blob != (const BlobInfo *) NULL);
+ image->blob->exempt = (closeable != MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t B l o b T e m p o r a r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetBlobTemporary() sets a boolean flag (default False) to specify if
+% the file associated with the blob is a temporary file and should be
+% removed when the associated image is destroyed.
+%
+% The format of the SetBlobTemporary method is:
+%
+% void SetBlobTemporary(Image *image, MagickBool isTemporary)
+%
+% A description of each parameter follows:
+%
+% o image: Image to update
+%
+% o isTemporary: Set to True to indicate that the file associated with
+% the blob is temporary.
+%
+*/
+MagickExport void SetBlobTemporary(Image *image, MagickBool isTemporary)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->blob != (const BlobInfo *) NULL);
+ image->blob->temporary = isTemporary;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S y n c B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SyncBlob() flushes the datastream if it is a file or synchonizes the data
+% attributes if it is an blob.
+%
+% The format of the SyncBlob method is:
+%
+% int SyncBlob(Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method SyncBlob returns 0 on success; otherwise, it
+% returns -1 and set errno to indicate the error.
+%
+% o image: The image.
+%
+%
+*/
+static int SyncBlob(Image *image)
+{
+ int
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+
+#if 0
+ {
+ register Image
+ *p;
+
+ /*
+ FIXME: It is not clear why doing a sync on the blob stream
+ should try to propogate the blob stream object across the whole
+ image list. Note that code below is not yet using the blob from
+ the current image (as desired).
+ */
+ for ( p=GetFirstImageInList(image); p != (Image *) NULL;
+ p=SyncNextImageInList(p));
+ }
+#endif
+
+ status=0;
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ break;
+ case FileStream:
+ case StandardStream:
+ case PipeStream:
+ {
+ status=fflush(image->blob->handle.std);
+ break;
+ }
+ case ZipStream:
+ {
+#if defined(HasZLIB)
+ status=gzflush(image->blob->handle.gz,Z_SYNC_FLUSH);
+#endif
+ break;
+ }
+ case BZipStream:
+ {
+#if defined(HasBZLIB)
+ status=BZ2_bzflush(image->blob->handle.bz);
+#endif
+ break;
+ }
+ case BlobStream:
+ break;
+ }
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ T e l l B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TellBlob() obtains the current value of the blob or file position.
+%
+% The format of the TellBlob method is:
+%
+% magick_off_t TellBlob(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o offset: Method TellBlob returns the current value of the blob or
+% file position success; otherwise, it returns -1 and sets errno to
+% indicate the error.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_off_t TellBlob(const Image *image)
+{
+ magick_off_t
+ offset;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+ offset=(-1);
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ break;
+ case FileStream:
+ {
+ offset=MagickFtell(image->blob->handle.std);
+ break;
+ }
+ case StandardStream:
+ case PipeStream:
+ case ZipStream:
+ {
+#if defined(HasZLIB)
+ offset=gztell(image->blob->handle.gz);
+#endif
+ break;
+ }
+ case BZipStream:
+ break;
+ case BlobStream:
+ {
+ offset=image->blob->offset;
+ break;
+ }
+ }
+ return(offset);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ U n m a p B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% UnmapBlob() deallocates the binary large object previously allocated with
+% the MapBlob method.
+%
+% The format of the UnmapBlob method is:
+%
+% MagickPassFail UnmapBlob(void *map,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method UnmapBlob returns MagickPass on success; otherwise,
+% it returns MagickFail and sets errno to indicate the error.
+%
+% o map: The address of the binary large object.
+%
+% o length: The length of the binary large object.
+%
+%
+*/
+MagickExport MagickPassFail UnmapBlob(void *map,const size_t length)
+{
+#if defined(HAVE_MMAP_FILEIO)
+ int
+ status;
+
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Munmap file mapping at address %p and length %"
+ MAGICK_SIZE_T_F "u",
+ map,(MAGICK_SIZE_T) length);
+ status=MagickMunmap(map,length);
+ return(status == 0);
+#else
+ (void) map;
+ (void) length;
+ return(MagickFail);
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteBlob() writes data to a blob or image file. It returns the number of
+% bytes written.
+%
+% The format of the WriteBlob method is:
+%
+% size_t WriteBlob(Image *image,const size_t length,const void *data)
+%
+% A description of each parameter follows:
+%
+% o count: Method WriteBlob returns the number of bytes written to the
+% blob.
+%
+% o image: The image.
+%
+% o length: Specifies an integer representing the number of bytes to
+% write to the file.
+%
+% o data: The address of the data to write to the blob or file.
+%
+%
+*/
+MagickExport size_t WriteBlob(Image *image,const size_t length,const void *data)
+{
+ size_t
+ count;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (const char *) NULL);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->type != UndefinedStream);
+ count=length;
+ switch (image->blob->type)
+ {
+ case UndefinedStream:
+ break;
+ case FileStream:
+ case StandardStream:
+ case PipeStream:
+ {
+ if (length == 1)
+ {
+ if((putc((int)*((unsigned char *)data),image->blob->handle.std)) != EOF)
+ count=1;
+ else
+ count=0;
+ }
+ else
+ {
+ count=fwrite((char *) data,1,length,image->blob->handle.std);
+ }
+ break;
+ }
+ case ZipStream:
+ {
+#if defined(HasZLIB)
+ size_t
+ i;
+
+ for (i=0; i < length; i+=count)
+ {
+ size_t
+ remaining;
+
+ unsigned int
+ amount;
+
+ remaining=length - i;
+ if (remaining > image->blob->block_size)
+ amount=(unsigned int) image->blob->block_size;
+ else
+ amount=(unsigned int) remaining;
+
+ count=gzwrite(image->blob->handle.gz,
+ (void *) ((unsigned char *) data+i),amount);
+ if (count <= 0)
+ break;
+ }
+ count=i;
+#endif
+ break;
+ }
+ case BZipStream:
+ {
+#if defined(HasBZLIB)
+ size_t
+ i;
+
+ for (i=0; i < length; i+=count)
+ {
+ size_t
+ remaining;
+
+ int
+ amount;
+
+ remaining=length - i;
+ if (remaining > image->blob->block_size)
+ amount=(int) image->blob->block_size;
+ else
+ amount=(int) remaining;
+
+ count=BZ2_bzwrite(image->blob->handle.gz,
+ (void *) ((unsigned char *) data+i),amount);
+ if (count <= 0)
+ break;
+ }
+ count=i;
+#endif
+ break;
+ }
+ case BlobStream:
+ {
+ count=WriteBlobStream(image,length,data);
+ break;
+ }
+ }
+ return(count);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b B y t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobByte writes an integer to a blob. It returns the number of
+% bytes written (either 0 or 1);
+%
+% The format of the WriteBlobByte method is:
+%
+% size_t WriteBlobByte(Image *image,const unsigned int value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobByte returns the number of bytes written.
+%
+% o image: The image.
+%
+% o value: Specifies the value to write.
+%
+%
+*/
+MagickExport size_t WriteBlobByte(Image *image,const magick_uint8_t value)
+{
+ unsigned char
+ c;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ switch (image->blob->type)
+ {
+ case FileStream:
+ case StandardStream:
+ case PipeStream:
+ {
+ if(putc((int) value,image->blob->handle.std) != EOF)
+ return 1;
+ return 0;
+ }
+ /* case BlobStream: TBD */
+ default:
+ {
+ c=(unsigned char) value;
+ return(WriteBlob(image,1,&c));
+ }
+ }
+
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobFile writes the content of a disk file to a blob stream.
+% MagickPass is returned if the file is copied successfully.
+%
+% The format of the WriteBlobFile method is:
+%
+% MagickPassFail WriteBlobFile(Image *image,const char *filename)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o filename: The filename to copy to blob.
+%
+%
+*/
+MagickExport MagickPassFail WriteBlobFile(Image *image,const char *filename)
+{
+ int
+ file;
+
+ MagickPassFail
+ status=MagickFail;
+
+ if (MagickConfirmAccess(FileReadConfirmAccessMode,filename,
+ &image->exception) == MagickFail)
+ return MagickFail;
+ file=open(filename,O_RDONLY | O_BINARY,0777);
+ if (file != -1)
+ {
+ MagickStatStruct_t
+ attributes;
+
+ /* st_size has type off_t */
+ if ((MagickFstat(file,&attributes) == 0) &&
+ (attributes.st_size == (off_t) ((size_t) attributes.st_size)) &&
+ (attributes.st_size > (off_t) ((size_t) 0)))
+ {
+ unsigned char
+ *buffer;
+
+ size_t
+ block_size,
+ length;
+
+ register size_t
+ i;
+
+ MAGICK_POSIX_IO_SIZE_T
+ count;
+
+ block_size=image->blob->block_size;
+ length=(size_t) attributes.st_size;
+
+ if (length < block_size)
+ count = (MAGICK_POSIX_IO_SIZE_T) length;
+ else
+ count = (MAGICK_POSIX_IO_SIZE_T) block_size;
+
+ buffer=MagickAllocateMemory(unsigned char *,count);
+ i=0;
+ if (buffer != (unsigned char *) NULL)
+ {
+ ssize_t
+ result;
+
+ for (i=0; i < length; i+=result)
+ {
+ result=read(file,buffer,count);
+ if (result <= 0)
+ break;
+ if (WriteBlob(image,result,buffer) != (size_t) result)
+ break;
+ }
+ MagickFreeMemory(buffer);
+ }
+ if (i == length)
+ status = MagickPass;
+ }
+ (void) close(file);
+ }
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b L S B L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobLSBLong writes a 32 bit quantity in least-significant byte
+% first order.
+%
+% The format of the WriteBlobLSBLong method is:
+%
+% size_t WriteBlobLSBLong(Image *image,const magick_uint32_t value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobLSBLong returns the number of bytes written
+% (should be 4).
+%
+% o image: The image.
+%
+% o value: Specifies the value to write.
+%
+%
+*/
+MagickExport size_t WriteBlobLSBLong(Image *image,const magick_uint32_t value)
+{
+ unsigned char
+ buffer[4];
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ buffer[0]=(unsigned char) value;
+ buffer[1]=(unsigned char) (value >> 8);
+ buffer[2]=(unsigned char) (value >> 16);
+ buffer[3]=(unsigned char) (value >> 24);
+ return(WriteBlob(image,4,buffer));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b L S B S i g n e d L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobLSBSignedLong writes a 32 bit signed quantity in
+% least-significant byte first order.
+%
+% The format of the WriteBlobLSBSignedLong method is:
+%
+% size_t WriteBlobLSBSignedLong(Image *image,const magick_int32_t value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobLSBLong returns the number of bytes written
+% (should be 4).
+%
+% o image: The image.
+%
+% o value: Specifies the value to write.
+%
+%
+*/
+MagickExport size_t WriteBlobLSBSignedLong(Image *image,const magick_int32_t value)
+{
+ unsigned char
+ buffer[4];
+
+ MagickInt32Union
+ uvalue;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ uvalue.int32=value;
+ buffer[0]=(unsigned char) uvalue.uint32;
+ buffer[1]=(unsigned char) (uvalue.uint32 >> 8);
+ buffer[2]=(unsigned char) (uvalue.uint32 >> 16);
+ buffer[3]=(unsigned char) (uvalue.uint32 >> 24);
+ return(WriteBlob(image,4,buffer));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b L S B S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobLSBShort writes a 16 bit value in least-significant byte
+% first order.
+%
+% The format of the WriteBlobLSBShort method is:
+%
+% size_t WriteBlobLSBShort(Image *image,const magick_uint16_t value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobLSBShort returns the number of bytes written
+% (should be 2).
+%
+% o image: The image.
+%
+% o value: Specifies the value to write.
+%
+%
+*/
+MagickExport size_t WriteBlobLSBShort(Image *image,const magick_uint16_t value)
+{
+ unsigned char
+ buffer[2];
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ buffer[0]=(unsigned char) value;
+ buffer[1]=(unsigned char) (value >> 8);
+ return(WriteBlob(image,2,buffer));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b L S B S i g n e d S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobLSBSignedShort writes a 16 bit signed value in
+% least-significant byte first order.
+%
+% The format of the WriteBlobLSBSignedShort method is:
+%
+% size_t WriteBlobLSBSignedShort(Image *image,const magick_int16_t value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobLSBSignedShort returns the number of bytes written
+% (should be 2).
+%
+% o image: The image.
+%
+% o value: Specifies the value to write.
+%
+%
+*/
+MagickExport size_t WriteBlobLSBSignedShort(Image *image,const magick_int16_t value)
+{
+ unsigned char
+ buffer[2];
+
+ MagickInt16Union
+ uvalue;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ uvalue.int16=value;
+ buffer[0]=(unsigned char) uvalue.uint16;
+ buffer[1]=(unsigned char) (uvalue.uint16 >> 8);
+ return(WriteBlob(image,2,buffer));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b L S B S h o r t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobLSBShorts reads an array of little-endian 16-bit "short"
+% values from the file or BLOB and returns them in native order.
+%
+% The format of the ReadBlobLSBShorts method is:
+%
+% size_t ReadBlobLSBShorts(Image *image, size_t octets,
+% magick_uint16_t *data)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobLSBShorts returns the number of octets
+% which were actually read.
+%
+% o image: The image.
+%
+% o octets: The number of bytes of data to read.
+%
+% o data: The address of a user-supplied buffer in which to write
+% the decoded data. The buffer must be suitably aligned for the
+% data type.
+%
+*/
+MagickExport size_t ReadBlobLSBShorts(Image *image, size_t octets,
+ magick_uint16_t *data)
+{
+ size_t
+ octets_read;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (magick_uint16_t *) NULL);
+
+ octets_read=ReadBlob(image,octets,data);
+#if defined(WORDS_BIGENDIAN)
+ if (octets_read >= sizeof(magick_uint16_t))
+ MagickSwabArrayOfUInt16(data,(octets_read+sizeof(magick_uint16_t)-1)/sizeof(magick_uint16_t));
+#endif
+
+ return octets_read;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b M S B L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobMSBLong writes a 32 bit value in most-significant byte
+% first order.
+%
+% The format of the WriteBlobMSBLong method is:
+%
+% size_t WriteBlobMSBLong(Image *image,const magick_uint32_t value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobMSBLong returns the number of bytes written.
+%
+% o value: Specifies the value to write.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport size_t WriteBlobMSBLong(Image *image,const magick_uint32_t value)
+{
+ size_t
+ count;
+
+ unsigned char
+ buffer[4];
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ buffer[0]=(unsigned char) (value >> 24);
+ buffer[1]=(unsigned char) (value >> 16);
+ buffer[2]=(unsigned char) (value >> 8);
+ buffer[3]=(unsigned char) value;
+
+ if (image->blob->type == BlobStream)
+ count=WriteBlobStream(image,4,buffer);
+ else
+ count=WriteBlob(image,4,buffer);
+ return count;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b M S B S i g n e d L o n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobMSBSignedLong writes a 32 bit signed value in
+% most-significant byte first order.
+%
+% The format of the WriteBlobMSBSignedLong method is:
+%
+% size_t WriteBlobMSBSignedLong(Image *image,const magick_int32_t value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobMSBLong returns the number of bytes written
+% (should be 4).
+%
+% o value: Specifies the value to write.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport size_t WriteBlobMSBSignedLong(Image *image,const magick_int32_t value)
+{
+ size_t
+ count;
+
+ unsigned char
+ buffer[4];
+
+ MagickInt32Union
+ uvalue;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ uvalue.int32=value;
+ buffer[0]=(unsigned char) (uvalue.uint32 >> 24);
+ buffer[1]=(unsigned char) (uvalue.uint32 >> 16);
+ buffer[2]=(unsigned char) (uvalue.uint32 >> 8);
+ buffer[3]=(unsigned char) uvalue.uint32;
+
+ if (image->blob->type == BlobStream)
+ count=WriteBlobStream(image,4,buffer);
+ else
+ count=WriteBlob(image,4,buffer);
+ return count;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d B l o b M S B L o n g s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadBlobMSBLongs reads an array of big-endian 32-bit "long"
+% values from the file or BLOB and returns them in native order.
+%
+% The format of the ReadBlobMSBLongs method is:
+%
+% size_t ReadBlobMSBLongs(Image *image, size_t octets,
+% magick_uint32_t *data)
+%
+% A description of each parameter follows.
+%
+% o value: Method ReadBlobMSBLongs returns the number of octets
+% which were actually read.
+%
+% o image: The image.
+%
+% o octets: The number of bytes of data to read.
+%
+% o data: The address of a user-supplied buffer in which to write
+% the decoded data. The buffer must be suitably aligned for the
+% data type.
+%
+*/
+MagickExport size_t ReadBlobMSBLongs(Image *image, size_t octets,
+ magick_uint32_t *data)
+{
+ size_t
+ octets_read;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(data != (magick_uint32_t *) NULL);
+
+ octets_read=ReadBlob(image,octets,data);
+#if !defined(WORDS_BIGENDIAN)
+ if (octets_read >= sizeof(magick_uint32_t))
+ MagickSwabArrayOfUInt32(data,(octets_read+sizeof(magick_uint32_t)-1)/sizeof(magick_uint32_t));
+#endif
+
+ return octets_read;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b M S B S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobMSBShort writes a 16 bit value in most-significant byte
+% first order.
+%
+% The format of the WriteBlobMSBShort method is:
+%
+% size_t WriteBlobMSBShort(Image *image,const magick_uint16_t value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobMSBShort returns the number of bytes written
+% (should be 2).
+%
+% o value: Specifies the value to write.
+%
+% o file: Specifies the file to write the data to.
+%
+%
+*/
+MagickExport size_t WriteBlobMSBShort(Image *image,const magick_uint16_t value)
+{
+ unsigned char
+ buffer[2];
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ buffer[0]=(unsigned char) (value >> 8);
+ buffer[1]=(unsigned char) value;
+ return(WriteBlob(image,2,buffer));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b M S B S i g n e d S h o r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobMSBSignedShort writes a 16 bit signed value in
+% most-significant byte first order.
+%
+% The format of the WriteBlobMSBSignedShort method is:
+%
+% size_t WriteBlobMSBSignedShort(Image *image,const magick_int16_t value)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobMSBSignedShort returns the number of bytes written
+% (should be 2).
+%
+% o value: Specifies the value to write.
+%
+% o file: Specifies the file to write the data to.
+%
+%
+*/
+MagickExport size_t WriteBlobMSBSignedShort(Image *image,const magick_int16_t value)
+{
+ unsigned char
+ buffer[2];
+
+ MagickInt16Union
+ uvalue;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ uvalue.int16=value;
+ buffer[0]=(unsigned char) (uvalue.uint16 >> 8);
+ buffer[1]=(unsigned char) uvalue.uint16;
+ return(WriteBlob(image,2,buffer));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e B l o b S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method WriteBlobString write a string to a blob. It returns the number of
+% characters written.
+%
+% The format of the WriteBlobString method is:
+%
+% size_t WriteBlobString(Image *image,const char *string)
+%
+% A description of each parameter follows.
+%
+% o count: Method WriteBlobString returns the number of characters written.
+%
+% o image: The image.
+%
+% o string: Specifies the string to write.
+%
+%
+*/
+MagickExport size_t WriteBlobString(Image *image,const char *string)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(string != (const char *) NULL);
+ return(WriteBlob(image,strlen(string),string));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D i s a s s o c i a t e B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Checks if the blob of the specified image is referenced by other images. If
+% the reference count is higher then 1 a new blob is assigned to the image.
+%
+% The format of the DisassociateBlob method is:
+%
+% void DisassociateBlob(Image *image)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void DisassociateBlob(Image *image)
+{
+ BlobInfo
+ *blob;
+
+ int
+ clone;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->blob != (BlobInfo *) NULL);
+ assert(image->blob->signature == MagickSignature);
+ clone=MagickFalse;
+ LockSemaphoreInfo(image->blob->semaphore);
+ if (image->logging)
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Disassociate blob: image=%p, blob=%p, ref=%lu",
+ image,image->blob,image->blob->reference_count);
+ assert(image->blob->reference_count >= 0);
+ if (image->blob->reference_count > 1)
+ clone=MagickTrue;
+ UnlockSemaphoreInfo(image->blob->semaphore);
+ if (clone == MagickFalse)
+ return;
+ blob=CloneBlobInfo(image->blob);
+ DestroyBlob(image);
+ image->blob=blob;
+}
diff --git a/magick/blob.h b/magick/blob.h
new file mode 100644
index 0000000..327d736
--- /dev/null
+++ b/magick/blob.h
@@ -0,0 +1,570 @@
+/*
+ Copyright (C) 2003-2016 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Image Compression/Decompression Methods.
+*/
+#ifndef _MAGICK_BLOB_H
+#define _MAGICK_BLOB_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "magick/image.h"
+
+ /*
+ Minimum input file size before considering for memory map.
+ */
+#define MinBlobExtent 32768L
+
+ /*
+ Forward declarations.
+ */
+ typedef struct _BlobInfo BlobInfo;
+
+ /*
+ *
+ * BlobInfo methods
+ *
+ */
+
+ /*
+ Makes a duplicate of the given blob info structure, or if blob info
+ is NULL, a new one.
+ */
+ extern MagickExport BlobInfo* CloneBlobInfo(const BlobInfo *blob_info);
+
+ /*
+ Increments the reference count associated with the pixel blob,
+ returning a pointer to the blob.
+ */
+ extern MagickExport BlobInfo* ReferenceBlob(BlobInfo *blob);
+
+ /*
+ Deallocate memory associated with the BlobInfo structure.
+ */
+ extern MagickExport void DestroyBlobInfo(BlobInfo *blob) MAGICK_FUNC_DEPRECATED;
+
+ /*
+ If BLOB is a memory mapping then unmap it. Reset BlobInfo structure
+ to its default state.
+ */
+ extern MagickExport void DetachBlob(BlobInfo *blob);
+
+ /*
+ Initialize a BlobInfo structure.
+ */
+ extern MagickExport void GetBlobInfo(BlobInfo *blob);
+
+ /*
+ Attach memory buffer to a BlobInfo structure.
+ */
+ extern MagickExport void AttachBlob(BlobInfo *blob_info,
+ const void *blob,
+ const size_t length);
+
+ /*
+ *
+ * Functions for managing a BLOB (type BlobInfo) attached to an Image.
+ *
+ */
+
+ /*
+ Deallocate all memory associated with an Image blob (reference counted).
+ */
+ extern MagickExport void DestroyBlob(Image *image);
+
+
+ /*
+ *
+ * Formatted image I/O functions
+ *
+ */
+
+ /*
+ Read an Image from a formatted in-memory "file" image ("BLOB").
+ */
+ extern MagickExport Image* BlobToImage(const ImageInfo *image_info,
+ const void *blob,
+ const size_t length,
+ ExceptionInfo *exception);
+
+ /*
+ Return an Image populated with salient information regarding a
+ formatted in-memory "file" image ("BLOB") but without reading the
+ image pixels.
+ */
+ extern MagickExport Image* PingBlob(const ImageInfo *image_info,
+ const void *blob,
+ const size_t length,
+ ExceptionInfo *exception);
+
+ /*
+ Writes an Image to a formatted (like a file) in-memory
+ representation.
+ */
+ extern MagickExport void *ImageToBlob(const ImageInfo *image_info,
+ Image *image,
+ size_t *length,
+ ExceptionInfo *exception);
+
+ /*
+ *
+ * Core File or BLOB I/O functions.
+ *
+ */
+
+ /*
+ Blob open modes.
+ */
+ typedef enum
+ {
+ UndefinedBlobMode, /* Undefined */
+ ReadBlobMode, /* Open for reading (text) */ /* only locale.c */
+ ReadBinaryBlobMode, /* Open for reading (binary) */
+ WriteBlobMode, /* Open for writing (text) */ /* only mvg.c txt.c */
+ WriteBinaryBlobMode /* Open for writing (binary) */
+ } BlobMode;
+
+ /*
+ Open an input or output stream for access. May also use a stream
+ provided via image_info->stream.
+ */
+ extern MagickExport MagickPassFail OpenBlob(const ImageInfo *image_info,
+ Image *image,
+ const BlobMode mode,
+ ExceptionInfo *exception);
+
+ /*
+ Close I/O to the file or BLOB.
+ */
+ extern MagickExport void CloseBlob(Image *image);
+
+
+ /*
+ Read data from the file or BLOB into a buffer.
+ */
+ extern MagickExport size_t ReadBlob(Image *image,
+ const size_t length,
+ void *data);
+
+ /*
+ Read data from the file or BLOB into a buffer, but support zero-copy
+ if possible.
+ */
+ extern MagickExport size_t ReadBlobZC(Image *image,
+ const size_t length,
+ void **data);
+
+ /*
+ Write data from a buffer to the file or BLOB.
+ */
+ extern MagickExport size_t WriteBlob(Image *image,
+ const size_t length,
+ const void *data);
+
+ /*
+ Move the current read or write offset position in the file or BLOB.
+ */
+ extern MagickExport magick_off_t SeekBlob(Image *image,
+ const magick_off_t offset,
+ const int whence);
+
+ /*
+ Obtain the current read or write offset position in the file or
+ BLOB.
+ */
+ extern MagickExport magick_off_t TellBlob(const Image *image);
+
+ /*
+ Test to see if EOF has been detected while reading the file or BLOB.
+ */
+ extern MagickExport int EOFBlob(const Image *image);
+
+ /*
+ Test to see if an error has been encountered while doing I/O to the file
+ or BLOB.
+ */
+ extern MagickExport int GetBlobStatus(const Image *image);
+
+ /*
+ Test to see if blob is currently open.
+ */
+ extern MagickExport MagickBool GetBlobIsOpen(const Image *image);
+
+ /*
+ Obtain the current size of the file or BLOB. Zero is returned if
+ the size can not be determined. If BLOB is no longer open, then
+ return the size when the BLOB was closed.
+ */
+ extern MagickExport magick_off_t GetBlobSize(const Image *image);
+
+
+ /*
+ Obtain the underlying stdio FILE* for the file (if any).
+ */
+ extern MagickExport FILE *GetBlobFileHandle(const Image *image);
+
+ /*
+ Obtain a pointer to the base of where BLOB data is stored. The data
+ is only available if the data is stored on the heap, or is memory
+ mapped. Otherwise NULL is returned.
+ */
+ extern MagickExport unsigned char *GetBlobStreamData(const Image *image);
+
+
+ /*
+ *
+ * Formatted File or BLOB I/O functions.
+ *
+ */
+
+ /*
+ Read a single byte from the file or BLOB. Returns an EOF character if EOF
+ has been detected.
+ */
+ extern MagickExport int ReadBlobByte(Image *image);
+
+ /*
+ Read a 16-bit little-endian unsigned "short" value from the file or BLOB.
+ */
+ extern MagickExport magick_uint16_t ReadBlobLSBShort(Image *image);
+
+ /*
+ Read a 16-bit little-endian signed "short" value from the file or BLOB.
+ */
+ extern MagickExport magick_int16_t ReadBlobLSBSignedShort(Image *image);
+
+ /*
+ Read an array of little-endian unsigned 16-bit "short" values from the
+ file or BLOB.
+ */
+ extern MagickExport size_t ReadBlobLSBShorts(Image *image, size_t octets,
+ magick_uint16_t *data);
+
+ /*
+ Read a 16-bit big-endian unsigned "short" value from the file or
+ BLOB.
+ */
+ extern MagickExport magick_uint16_t ReadBlobMSBShort(Image *image);
+
+ /*
+ Read a 16-bit big-endian signed "short" value from the file or BLOB.
+ */
+ extern MagickExport magick_int16_t ReadBlobMSBSignedShort(Image *image);
+
+ /*
+ Read an array of big-endian 16-bit "short" values from the file or BLOB.
+ */
+ extern MagickExport size_t ReadBlobMSBShorts(Image *image, size_t octets,
+ magick_uint16_t *data);
+
+ /*
+ Read a 32-bit little-endian unsigned "long" value from the file or BLOB.
+ */
+ extern MagickExport magick_uint32_t ReadBlobLSBLong(Image *image);
+
+ /*
+ Read a 32-bit little-endian signed "long" value from the file or BLOB.
+ */
+ extern MagickExport magick_int32_t ReadBlobLSBSignedLong(Image *image);
+
+ /*
+ Read an array of little-endian 32-bit "long" values from the file or BLOB.
+ */
+ extern MagickExport size_t ReadBlobLSBLongs(Image *image, size_t octets,
+ magick_uint32_t *data);
+
+ /*
+ Read a 32-bit big-endian unsigned "long" value from the file or BLOB.
+ */
+ extern MagickExport magick_uint32_t ReadBlobMSBLong(Image *image);
+
+ /*
+ Read a 32-bit big-endian signed "long" value from the file or BLOB.
+ */
+ extern MagickExport magick_int32_t ReadBlobMSBSignedLong(Image *image);
+
+ /*
+ Read an array of big-endian 32-bit "long" values from the file or BLOB.
+ */
+ extern MagickExport size_t ReadBlobMSBLongs(Image *image, size_t octets,
+ magick_uint32_t *data);
+
+ /*
+ Read a little-endian 32-bit "float" value from the file or BLOB.
+ */
+ extern MagickExport float ReadBlobLSBFloat(Image *image);
+
+ /*
+ Read an array of little-endian 32-bit "float" values from the file or
+ BLOB.
+ */
+ extern MagickExport size_t ReadBlobLSBFloats(Image *image, size_t octets,
+ float *data);
+
+ /*
+ Read a big-endian 32-bit "float" value from the file or BLOB.
+ */
+ extern MagickExport float ReadBlobMSBFloat(Image *image);
+
+ /*
+ Read an array of big-endian 32-bit "float" values from the file or BLOB.
+ */
+ extern MagickExport size_t ReadBlobMSBFloats(Image *image, size_t octets,
+ float *data);
+
+ /*
+ Read a little-endian 64-bit "double" value from the file or BLOB.
+ */
+ extern MagickExport double ReadBlobLSBDouble(Image *image);
+
+ /*
+ Read an array of little-endian 64-bit "double" values from the file or
+ BLOB.
+ */
+ extern MagickExport size_t ReadBlobLSBDoubles(Image *image, size_t octets,
+ double *data);
+
+ /*
+ Read a big-endian 64-bit "double" value from the file or BLOB.
+ */
+ extern MagickExport double ReadBlobMSBDouble(Image *image);
+
+ /*
+ Read an array of big-endian 64-bit "double" values from the file or BLOB.
+ */
+ extern MagickExport size_t ReadBlobMSBDoubles(Image *image, size_t octets,
+ double *data);
+
+ /*
+ Read a string from the file or blob until a newline character is read or
+ an end-of-file condition is encountered.
+ */
+ extern MagickExport char *ReadBlobString(Image *image,
+ char *string);
+
+ /*
+ Write a single byte to the file or BLOB.
+ */
+ extern MagickExport size_t WriteBlobByte(Image *image,
+ const magick_uint8_t value);
+
+ /*
+ Write the content of an entire disk file to the file or BLOB.
+ */
+ extern MagickExport MagickPassFail WriteBlobFile(Image *image,
+ const char *filename);
+
+ /*
+ Write a 16-bit signed "short" value to the file or BLOB in little-endian
+ order.
+ */
+ extern MagickExport size_t WriteBlobLSBShort(Image *image,
+ const magick_uint16_t value);
+
+ /*
+ Write a 16-bit signed "short" value to the file or BLOB in little-endian
+ order.
+ */
+ extern MagickExport size_t WriteBlobLSBSignedShort(Image *image,
+ const magick_int16_t value);
+
+ /*
+ Write a 32-bit unsigned "long" value to the file or BLOB in little-endian
+ order.
+ */
+ extern MagickExport size_t WriteBlobLSBLong(Image *image,
+ const magick_uint32_t value);
+
+ /*
+ Write a 32-bit signed "long" value to the file or BLOB in little-endian
+ order.
+ */
+ extern MagickExport size_t WriteBlobLSBSignedLong(Image *image,
+ const magick_int32_t value);
+
+
+
+ /*
+ Write a 32-bit unsigned "long" value to the file or BLOB in big-endian
+ order.
+ */
+ extern MagickExport size_t WriteBlobMSBLong(Image *image,
+ const magick_uint32_t value);
+
+ /*
+ Write a 32-bit signed "long" value to the file or BLOB in big-endian
+ order.
+ */
+ extern MagickExport size_t WriteBlobMSBSignedLong(Image *image,
+ const magick_int32_t value);
+
+ /*
+ Write a 16-bit unsigned "short" value to the file or BLOB in big-endian
+ order.
+ */
+ extern MagickExport size_t WriteBlobMSBShort(Image *image,
+ const magick_uint16_t value);
+
+ /*
+ Write a 16-bit signed "short" value to the file or BLOB in big-endian
+ order.
+ */
+ extern MagickExport size_t WriteBlobMSBSignedShort(Image *image,
+ const magick_int16_t value);
+
+ /*
+ Write a C string to the file or BLOB, without the terminating NULL byte.
+ */
+ extern MagickExport size_t WriteBlobString(Image *image,
+ const char *string);
+
+ /*
+ *
+ * BLOB attribute access.
+ *
+ */
+
+ /*
+ Blob supports seek operations. BlobSeek() and BlobTell() may safely be
+ used.
+ */
+ extern MagickExport MagickBool BlobIsSeekable(const Image *image);
+
+ /*
+ Allow file descriptor to be closed (if True).
+ */
+ extern MagickExport void SetBlobClosable(Image *image,
+ MagickBool closable);
+
+ /*
+ Blob is for a temporary file which should be deleted (if True).
+ */
+ extern MagickExport void SetBlobTemporary(Image *image,
+ MagickBool isTemporary);
+
+ /*
+ Returns MagickTrue if the file associated with the blob is a temporary
+ file and should be removed when the associated image is destroyed.
+ */
+ extern MagickExport MagickBool GetBlobTemporary(const Image *image);
+
+ /*
+ *
+ * Memory mapped file support.
+ *
+ */
+
+ /*
+ Memory mapping modes.
+ */
+ typedef enum
+ {
+ ReadMode, /* Map for read-only access */
+ WriteMode, /* Map for write-only access (useless) */
+ IOMode /* Map for read/write access */
+ } MapMode;
+
+ /*
+ Release memory mapping for a region.
+ */
+ extern MagickExport MagickPassFail UnmapBlob(void *map,
+ const size_t length);
+
+ /*
+ Perform a requested memory mapping of a file descriptor.
+ */
+ extern MagickExport void *MapBlob(int file,
+ const MapMode mode,
+ magick_off_t offset,
+ size_t length);
+
+ /*
+ *
+ * Buffer to File / File to Buffer functions.
+ *
+ */
+
+ /*
+ Writes a buffer to a named file.
+ */
+ extern MagickExport MagickPassFail BlobToFile(const char *filename,
+ const void *blob,
+ const size_t length,
+ ExceptionInfo *exception);
+
+ /*
+ Read the contents of a file into memory.
+ */
+ extern MagickExport void *FileToBlob(const char *filename,
+ size_t *length,
+ ExceptionInfo *exception);
+
+ /*
+ *
+ * Junk yet to be categorized.
+ *
+ */
+
+ /*
+ Reserve space for a specified output size.
+ */
+ extern MagickExport MagickPassFail BlobReserveSize(Image *image, magick_off_t size);
+
+ /*
+ Copies data from the input stream to a file. Useful in case it is
+ necessary to perform seek operations on the input data.
+ */
+ extern MagickExport MagickPassFail ImageToFile(Image *image,
+ const char *filename,
+ ExceptionInfo *exception);
+
+ /*
+ Search for a configuration file (".mgk" file) using appropriate
+ rules and return as an in-memory buffer.
+ */
+ extern MagickExport void *GetConfigureBlob(const char *filename,
+ char *path,
+ size_t *length,
+ ExceptionInfo *exception);
+
+ /*
+ Converts a least-significant byte first buffer of integers to
+ most-significant byte first.
+ */
+ extern MagickExport void MSBOrderLong(unsigned char *buffer,
+ const size_t length);
+
+ /*
+ Converts a least-significant byte first buffer of integers to
+ most-significant byte first.
+ */
+ extern MagickExport void MSBOrderShort(unsigned char *p,
+ const size_t length);
+
+ /*
+ Checks if the blob of the specified image is referenced by other images. If
+ the reference count is higher then 1 a new blob is assigned to the image.
+ */
+ extern MagickExport void DisassociateBlob(Image *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/cdl.c b/magick/cdl.c
new file mode 100644
index 0000000..7d19c41
--- /dev/null
+++ b/magick/cdl.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2009 GraphicsMagick Group
+ *
+ * American Society of Cinematographers Color Decision List (ASC-CDL)
+ * implementation.
+ *
+ * Original implementation by Clment Follet. Additional work by Bob
+ * Friesenhahn.
+ */
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/cdl.h"
+#include "magick/pixel_iterator.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C d l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The CdlImage() method applies ("bakes in") the ASC-CDL which is a format
+% for the exchange of basic primary color grading information between
+% equipment and software from different manufacturers. The format defines
+% the math for three functions: slope, offset and power. Each function uses
+% a number for the red, green, and blue color channels for a total of nine
+% numbers comprising a single color decision. A tenth number for chrominance
+% (saturation) has been proposed but is not yet standardized.
+%
+% The cdl argument string is comma delimited and is in the form (but
+% without invervening spaces or line breaks):
+%
+% redslope, redoffset, redpower :
+% greenslope, greenoffset, greenpower :
+% blueslope, blueoffset, bluepower :
+% saturation
+%
+% with the unity (no change) specification being:
+%
+% "1.0,0.0,1.0:1.0,0.0,1.0:1.0,0.0,1.0:0.0"
+%
+% See http://en.wikipedia.org/wiki/ASC_CDL for more information.
+%
+% The format of the CdlImage method is:
+%
+% MagickPassFail CdlImage(Image *image,const char *cdl)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o cdl: Define the coefficients for slope offset and power in the
+% red green and blue channels, plus saturation.
+%
+*/
+
+typedef struct _CdlImageParameters_t
+{
+ double
+ redslope,
+ redoffset,
+ redpower,
+ greenslope,
+ greenoffset,
+ greenpower,
+ blueslope,
+ blueoffset,
+ bluepower,
+ saturation;
+
+ const PixelPacket
+ *lut;
+
+} CdlImageParameters_t;
+
+static Quantum
+CdlQuantum(const Quantum quantum, const double slope, const double offset,
+ const double power, const double saturation)
+{
+ double
+ v,
+ t;
+
+ t=(((double) quantum)/MaxRGBDouble)*slope+offset;
+ if (t < 0.0)
+ t = 0.0;
+ else if (t > 1.0)
+ t = 1.0;
+ v = (pow(t,power)+saturation)*MaxRGBDouble;
+ return RoundDoubleToQuantum(v);
+}
+
+static MagickPassFail
+CdlImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ const CdlImageParameters_t
+ param = *(const CdlImageParameters_t *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ if (param.lut != (PixelPacket *) NULL)
+ {
+ for(i = 0; i < npixels; i++)
+ {
+ pixels[i].red=param.lut[pixels[i].red].red;
+ pixels[i].green=param.lut[pixels[i].green].green;
+ pixels[i].blue=param.lut[pixels[i].blue].blue;
+ }
+ }
+ else
+ {
+ for(i = 0; i < npixels; i++)
+ {
+ pixels[i].red=CdlQuantum(pixels[i].red,param.redslope,param.redoffset,
+ param.redpower,param.saturation);
+ pixels[i].green=CdlQuantum(pixels[i].green,param.greenslope,param.greenoffset,
+ param.greenpower,param.saturation);
+ pixels[i].blue=CdlQuantum(pixels[i].blue,param.blueslope,param.blueoffset,
+ param.bluepower,param.saturation);
+ }
+ }
+
+ return MagickPass;
+}
+
+
+MagickExport MagickPassFail CdlImage(Image *image,const char *cdl)
+{
+ char
+ progress_message[MaxTextExtent];
+
+ CdlImageParameters_t
+ param;
+
+ PixelPacket
+ *lut = (PixelPacket *) NULL;
+
+ register long
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (cdl == (char *) NULL)
+ return(MagickFail);
+
+ param.redslope=1.0;
+ param.redoffset=0.0;
+ param.redpower=1.0;
+ param.greenslope=1.0;
+ param.greenoffset=0.0;
+ param.greenpower=1.0;
+ param.blueslope=1.0;
+ param.blueoffset=0.0;
+ param.bluepower=1.0;
+ param.saturation=0.0;
+ param.lut=(PixelPacket *) NULL;
+
+ (void) sscanf(cdl,
+ "%lf%*[,/]%lf%*[,/]%lf%*[:/]%lf%*[,/]%lf%*[,/]%lf%*"
+ "[:/]%lf%*[,/]%lf%*[,/]%lf%*[:/]%lf",
+ &param.redslope,&param.redoffset,&param.redpower,
+ &param.greenslope,&param.greenoffset,&param.greenpower
+ ,&param.blueslope,&param.blueoffset,&param.bluepower,
+ &param.saturation);
+
+ param.redslope=AbsoluteValue(param.redslope);
+ param.redpower=AbsoluteValue(param.redpower);
+ param.greenslope=AbsoluteValue(param.greenslope);
+ param.greenpower=AbsoluteValue(param.greenpower);
+ param.blueslope=AbsoluteValue(param.blueslope);
+ param.bluepower=AbsoluteValue(param.bluepower);
+
+ FormatString(progress_message,
+ "[%%s] cdl %g/%g/%g/%g/%g/%g/%g/%g/%g/%g image...",
+ param.redslope,param.redoffset,param.redpower,
+ param.greenslope,param.greenoffset,param.greenpower,
+ param.blueslope,param.blueoffset,param.bluepower,
+ param.saturation);
+
+ if (!IsRGBCompatibleColorspace(image->colorspace))
+ TransformColorspace(image,RGBColorspace);
+
+ /*
+ Build a LUT if it is beneficial to do so.
+ */
+ if ((MaxMap == MaxRGB) && (image->columns*image->rows > MaxMap*3))
+ {
+ lut=MagickAllocateMemory(PixelPacket *,(MaxMap+1)*sizeof(PixelPacket));
+ if (lut != (PixelPacket *) NULL)
+ {
+#if (MaxMap > 256) && defined(HAVE_OPENMP)
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static,4)
+# else
+# pragma omp parallel for schedule(guided)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ lut[i].red=CdlQuantum((Quantum) i,param.redslope,param.redoffset,
+ param.redpower,param.saturation);
+ lut[i].green=CdlQuantum((Quantum) i,param.greenslope,param.greenoffset,
+ param.greenpower,param.saturation);
+ lut[i].blue=CdlQuantum((Quantum) i,param.blueslope,param.blueoffset,
+ param.bluepower,param.saturation);
+ }
+ param.lut=lut;
+ }
+ }
+
+ if (image->storage_class == PseudoClass)
+ {
+ (void) CdlImagePixels(NULL,&param,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(CdlImagePixels,NULL,progress_message,
+ NULL,&param,0,0,image->columns,image->rows,
+ image,&image->exception);
+ }
+
+ MagickFreeMemory(lut);
+
+ return(status);
+}
+
+
diff --git a/magick/cdl.h b/magick/cdl.h
new file mode 100644
index 0000000..ffed18f
--- /dev/null
+++ b/magick/cdl.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2009 GraphicsMagick Group
+ *
+ * American Society of Cinematographers Color Decision List (ASC-CDL)
+ * implementation.
+ *
+ * Original implementation by Clment Follet.
+ */
+
+#ifndef _MAGICK_CDL_H
+#define _MAGICK_CDL_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport MagickPassFail
+ CdlImage(Image *image,const char *cdl);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_CDL_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/channel.c b/magick/channel.c
new file mode 100644
index 0000000..468cec2
--- /dev/null
+++ b/magick/channel.c
@@ -0,0 +1,934 @@
+/*
+% Copyright (C) 2004 - 2016 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC H H AAA N N N N EEEEE L %
+% C H H A A NN N NN N E L %
+% C HHHHH AAAAA N N N N N N EEE L %
+% C H H A A N NN N NN E L %
+% CCCC H H A A N N N N EEEEE LLLLL %
+% %
+% %
+% Image Channel Operations %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% July 2004 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/channel.h"
+#include "magick/enum_strings.h"
+#include "magick/image.h"
+#include "magick/operator.h"
+#include "magick/pixel_iterator.h"
+#include "magick/utility.h"
+
+/*
+ Verify that image colorspace is compatible with with requested
+ channel type. Only check mismatch between RGB and CMYK since user
+ might intentionally export some obsure colorspace channel. We
+ don't silently convert between RGB and CMYK since there is no one
+ correct transform, and the transform is lossy.
+ */
+static MagickPassFail ValidateChannelRequest(const ColorspaceType image_colorspace,
+ const ChannelType channel,
+ ExceptionInfo *exception)
+{
+ MagickPassFail
+ status = MagickPass;
+
+ switch(channel)
+ {
+ case CyanChannel:
+ case MagentaChannel:
+ case YellowChannel:
+ case BlackChannel:
+ if (image_colorspace != CMYKColorspace)
+ status = MagickFail;
+ break;
+ case RedChannel:
+ case GreenChannel:
+ case BlueChannel:
+ if (image_colorspace == CMYKColorspace)
+ status = MagickFail;;
+ break;
+ default:
+ {
+ }
+ }
+
+ if (MagickFail == status)
+ ThrowException3(exception,ImageError,UnableToHandleImageChannel,ImageColorspaceMismatch);
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C h a n n e l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Transform an image so that the resulting image is a grayscale image
+% based on a specified image channel. The resulting image is returned in
+% the RGB colorspace. This function does not force or assume an input
+% image colorspace so it may be used to extract channels from images in
+% colorspaces other than RGB or CMYK. For example, if the image is currently
+% transformed to the HWB colorspace, the 'B' channel may be extracted by
+% specifying RedChannel as the ChannelType argument.
+%
+% The format of the ChannelImage method is:
+%
+% unsigned int ChannelImage(Image *image,const ChannelType channel)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: Identify which channel to extract: Red, Cyan, Green, Magenta,
+% Blue, Yellow, or Opacity.
+%
+%
+*/
+static MagickPassFail
+ChannelImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket * restrict pixels, /* Pixel row */
+ IndexPacket * restrict indexes,/* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform image so that it only represents the specified channel.
+ */
+ ChannelType
+ channel = *((const ChannelType *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(exception);
+
+ switch (channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ {
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].green=pixels[i].red;
+ pixels[i].blue=pixels[i].red;
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ break;
+ }
+ case GreenChannel:
+ case MagentaChannel:
+ {
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=pixels[i].green;
+ pixels[i].blue=pixels[i].green;
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ break;
+ }
+ case BlueChannel:
+ case YellowChannel:
+ {
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=pixels[i].blue;
+ pixels[i].green=pixels[i].blue;
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ break;
+ }
+ case MatteChannel:
+ case OpacityChannel:
+ {
+ if (image->colorspace == CMYKColorspace)
+ {
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=indexes[i];
+ pixels[i].green=indexes[i];
+ pixels[i].blue=indexes[i];
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=pixels[i].opacity;
+ pixels[i].green=pixels[i].opacity;
+ pixels[i].blue=pixels[i].opacity;
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ }
+ image->matte=False;
+ break;
+ }
+ case BlackChannel:
+ {
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=pixels[i].opacity;
+ pixels[i].green=pixels[i].opacity;
+ pixels[i].blue=pixels[i].opacity;
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ image->matte=False;
+ break;
+ }
+
+ case UndefinedChannel:
+ case AllChannels:
+ case GrayChannel:
+ {
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=pixels[i].green=pixels[i].blue=PixelIntensity(&pixels[i]);
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ image->matte=False;
+ break;
+ }
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail ChannelImage(Image *image,const ChannelType channel)
+{
+ char
+ progress_message[MaxTextExtent];
+
+ ChannelType
+ channel_type = channel;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Channel DirectClass packets.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ FormatString(progress_message,"[%%s] Extract %s channel... ",
+ ChannelTypeToString(channel));
+
+ /*
+ Verify that image colorspace is compatible with with requested
+ channel type.
+ */
+ if (ValidateChannelRequest(image->colorspace,channel,&image->exception)
+ == MagickFail)
+ return MagickFail;
+
+ image->storage_class=DirectClass;
+ status=PixelIterateMonoModify(ChannelImagePixels,
+ NULL,
+ progress_message,
+ NULL,&channel_type,0,0,image->columns,image->rows,
+ image,&image->exception);
+
+ image->matte=MagickFalse;
+ image->is_grayscale=MagickTrue;
+ image->colorspace=RGBColorspace;
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x p o r t I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ExportImageChannel() exports a specified image channel as a new image.
+%
+% The format of the ExportImageChannel method is:
+%
+% Image *ExportImageChannel(const Image *image,
+% const ChannelType channel,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The source image.
+%
+% o channel: The image channel to export
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define EXPORT_CHANNEL(source) \
+ do { \
+ register long \
+ i; \
+ \
+ if (source_image->storage_class == PseudoClass) \
+ { \
+ for (i=0; i < npixels; i++) \
+ { \
+ new_pixels[i].red=new_pixels[i].green=new_pixels[i].blue= \
+ source_image->colormap[source_indexes[i]].source; \
+ new_pixels[i].opacity=OpaqueOpacity; \
+ } \
+ } \
+ else \
+ { \
+ for (i=0; i < npixels; i++) \
+ { \
+ new_pixels[i].red=new_pixels[i].green=new_pixels[i].blue= \
+ source_pixels[i].source; \
+ new_pixels[i].opacity=OpaqueOpacity; \
+ } \
+ } \
+ } while (0);
+
+static MagickPassFail
+ExportImageChannelPixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *new_image, /* New image */
+ PixelPacket *new_pixels, /* Pixel row in new image */
+ IndexPacket *new_indexes, /* Pixel row indexes in new image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ ChannelType
+ channel = *((const ChannelType *) immutable_data);
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(new_image);
+ ARG_NOT_USED(new_indexes);
+ ARG_NOT_USED(exception);
+
+ switch (channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ {
+ EXPORT_CHANNEL(red);
+ break;
+ }
+ case GreenChannel:
+ case MagentaChannel:
+ {
+ EXPORT_CHANNEL(green);
+ break;
+ }
+ case BlueChannel:
+ case YellowChannel:
+ {
+ EXPORT_CHANNEL(blue);
+ break;
+ }
+ case MatteChannel:
+ case OpacityChannel:
+ {
+ if (source_image->colorspace == CMYKColorspace)
+ {
+ register long
+ i;
+
+ for (i=0; i < npixels; i++)
+ {
+ new_pixels[i].red=new_pixels[i].green=
+ new_pixels[i].blue=source_indexes[i];
+ new_pixels[i].opacity=OpaqueOpacity;
+ }
+ }
+ else
+ {
+ EXPORT_CHANNEL(opacity);
+ }
+ break;
+ }
+ case BlackChannel:
+ {
+ EXPORT_CHANNEL(opacity);
+ break;
+ }
+ default:
+ {
+ }
+ }
+
+ return MagickPass;
+}
+#define ExportImageChannelText "[%s] Exporting channel... "
+MagickExport Image *ExportImageChannel(const Image *source_image,
+ const ChannelType channel,
+ ExceptionInfo *exception)
+{
+ ChannelType
+ channel_type = channel;
+
+ Image
+ *new_image;
+
+ assert(source_image != (Image *) NULL);
+ assert(source_image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ /*
+ Verify that image colorspace is compatible with with requested
+ channel type.
+ */
+ if (ValidateChannelRequest(source_image->colorspace,channel,exception)
+ == MagickFail)
+ return (Image *) NULL;
+
+ new_image=CloneImage(source_image,source_image->columns,source_image->rows,
+ True,exception);
+ if (new_image == (Image *) NULL)
+ return ((Image *) NULL);
+
+ new_image->storage_class=DirectClass;
+
+ (void) PixelIterateDualNew(ExportImageChannelPixels,
+ NULL,
+ ExportImageChannelText,
+ NULL,&channel_type,
+ source_image->columns,source_image->rows,
+ source_image,0,0,
+ new_image,0,0,
+ exception);
+
+ new_image->is_grayscale=True;
+ new_image->is_monochrome=source_image->is_monochrome;
+ return new_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e C h a n n e l D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageChannelDepth() returns the minimum bit depth required to store
+% the specified image channel without actual loss of color resolution.
+% Pixel components are stored in a Quantum, which is 8, 16, or 32 bits
+% depending on the QuantumDepth value set when the software is compiled.
+% GetImageChannelDepth() returns the smallest modulus storage size which
+% supports the scale of the pixel within the range (i.e. no information is
+% lost). As an example, the value one is returned for a bilevel channel
+% since only one bit of resolution is required to represent a bilevel channel.
+%
+% The format of the GetImageChannelDepth method is:
+%
+% unsigned long GetImageChannelDepth(const Image *image,
+% const ChannelType channel,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: Channel to test.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define ComputeChannelDepthText "[%s] Get channel depth..."
+
+#define CHANNEL_DEPTH(parameter) \
+ { \
+ register long \
+ i; \
+ \
+ register unsigned int \
+ scale; \
+ \
+ if (depth < 1) \
+ depth=1; \
+ scale=MaxRGB / (MaxRGB >> (QuantumDepth-depth)); \
+ i=0; \
+ while (i < npixels) \
+ { \
+ if ((parameter) != scale*((parameter)/scale)) \
+ { \
+ depth++; \
+ if (depth == QuantumDepth) \
+ break; \
+ scale=MaxRGB / (MaxRGB >> (QuantumDepth-depth)); \
+ continue; \
+ } \
+ i++; \
+ } \
+ }
+
+static MagickPassFail
+GetImageChannelDepthPixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *image, /* Input image */
+ const PixelPacket *pixels, /* Pixel row */
+ const IndexPacket *indexes, /* Pixel indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ unsigned int
+ *channel_depth=(unsigned int *) mutable_data;
+
+ ChannelType
+ channel = *((const ChannelType *) immutable_data);
+
+ register unsigned int
+ depth;
+
+ ARG_NOT_USED(exception);
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageChannelDepthPixels)
+#endif
+ {
+ depth=*channel_depth;
+ }
+
+ switch (channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ {
+ CHANNEL_DEPTH(pixels[i].red);
+ break;
+ }
+ case GreenChannel:
+ case MagentaChannel:
+ {
+ CHANNEL_DEPTH(pixels[i].green);
+ break;
+ }
+ case BlueChannel:
+ case YellowChannel:
+ {
+ CHANNEL_DEPTH(pixels[i].blue);
+ break;
+ }
+ case MatteChannel:
+ case OpacityChannel:
+ {
+ if (image->colorspace == CMYKColorspace)
+ {
+ CHANNEL_DEPTH(indexes[i]);
+ }
+ else
+ {
+ CHANNEL_DEPTH(pixels[i].opacity);
+ }
+ break;
+ }
+ case BlackChannel:
+ {
+ CHANNEL_DEPTH(pixels[i].opacity);
+ break;
+ }
+ default:
+ {
+ }
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageChannelDepthPixels)
+#endif
+ {
+ if (depth > *channel_depth)
+ *channel_depth=depth;
+ }
+
+ if (depth >= QuantumDepth)
+ return MagickFail;
+
+ return MagickPass;
+}
+
+MagickExport unsigned int
+GetImageChannelDepth(const Image *image,
+ const ChannelType channel,
+ ExceptionInfo *exception)
+{
+ unsigned int
+ depth;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ depth=1;
+
+ (void) PixelIterateMonoRead(GetImageChannelDepthPixels,
+ NULL,
+ ComputeChannelDepthText,
+ &depth,
+ &channel,
+ 0,0,image->columns,image->rows,
+ image,exception);
+ return depth;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m p o r t I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImportImageChannel() imports an image into the specified image channel.
+%
+% The format of the ImportImageChannel method is:
+%
+% MagickPassFail ImportImageChannel(const Image *source_image,
+% Image *update_image,
+% const ChannelType channel)
+%
+% A description of each parameter follows:
+%
+% o source_image: The image to use as the replacement image channel.
+%
+% o update_image: The image to import the channel into.
+%
+% o channel: The image channel to import
+%
+%
+*/
+#define IMPORT_CHANNEL(target) \
+ do \
+ { \
+ register long \
+ i; \
+ \
+ if (source_image->storage_class == PseudoClass) \
+ { \
+ if (source_image->is_grayscale) \
+ for (i=0; i < npixels; i++) \
+ target=source_image->colormap[source_indexes[i]].red; \
+ else \
+ for (i=0; i < npixels; i++) \
+ target=PixelIntensityToQuantum(&source_image->colormap[source_indexes[i]]); \
+ } \
+ else \
+ { \
+ if (source_image->is_grayscale) \
+ for (i=0; i < npixels; i++) \
+ target=source_pixels[i].red; \
+ else \
+ for (i=0; i < npixels; i++) \
+ target=PixelIntensityToQuantum(&source_pixels[i]); \
+ } \
+ } while (0);
+
+static MagickPassFail
+ImportImageChannelPixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ ChannelType
+ channel = *((const ChannelType *) immutable_data);
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(exception);
+
+ switch (channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ {
+ IMPORT_CHANNEL(update_pixels[i].red);
+ break;
+ }
+ case GreenChannel:
+ case MagentaChannel:
+ {
+ IMPORT_CHANNEL(update_pixels[i].green);
+ break;
+ }
+ case BlueChannel:
+ case YellowChannel:
+ {
+ IMPORT_CHANNEL(update_pixels[i].blue);
+ break;
+ }
+ case MatteChannel:
+ case OpacityChannel:
+ {
+ if (update_image->colorspace == CMYKColorspace)
+ {
+ IMPORT_CHANNEL(update_indexes[i]);
+ }
+ else
+ {
+ IMPORT_CHANNEL(update_pixels[i].opacity);
+ }
+ break;
+ }
+ case BlackChannel:
+ {
+ IMPORT_CHANNEL(update_pixels[i].opacity);
+ break;
+ }
+ default:
+ {
+ }
+ }
+
+ return MagickPass;
+}
+
+#define ImportImageChannelText "[%s] Importing channel..."
+MagickPassFail ImportImageChannel(const Image *source_image,
+ Image *update_image,
+ const ChannelType channel)
+{
+ ChannelType
+ channel_type = channel;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(update_image != (Image *) NULL);
+ assert(update_image->signature == MagickSignature);
+ assert(source_image != (Image *) NULL);
+ assert(source_image->signature == MagickSignature);
+
+ /*
+ Verify that image colorspace is compatible with with requested
+ channel type.
+ */
+ if (ValidateChannelRequest(update_image->colorspace,channel,&update_image->exception)
+ == MagickFail)
+ return MagickFail;
+
+ update_image->storage_class=DirectClass;
+ status=PixelIterateDualModify(ImportImageChannelPixels,
+ NULL,
+ ImportImageChannelText,
+ NULL,&channel_type,
+ source_image->columns,source_image->rows,
+ source_image,0,0,
+ update_image,0,0,
+ &update_image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m p o r t I m a g e C h a n n e l s M a s k e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImportImageChannelsMasked() imports all the channels from a source
+% image to an update image, except for the channels specified.
+%
+% The format of the ImportImageChannelsMasked method is:
+%
+% MagickPassFail ImportImageChannelsMasked(const Image *source_image,
+% Image *update_image,
+% const ChannelType channels)
+%
+% A description of each parameter follows:
+%
+% o source_image: The image from which to extract the replacement channels.
+%
+% o update_image: The image to import the channels into.
+%
+% o channel: The image channel to import
+%
+%
+*/
+static MagickPassFail
+ImportImageChannelsMaskedPixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ ChannelType
+ channels = *((const ChannelType *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(source_image);
+ ARG_NOT_USED(exception);
+
+ if (IsCMYKColorspace(update_image->colorspace))
+ {
+ if (!MagickChannelEnabled(channels,CyanChannel))
+ for (i=0 ; i < npixels; i++)
+ SetCyanSample(&update_pixels[i],GetCyanSample(&source_pixels[i]));
+ if (!MagickChannelEnabled(channels,MagentaChannel))
+ for (i=0 ; i < npixels; i++)
+ SetMagentaSample(&update_pixels[i],GetMagentaSample(&source_pixels[i]));
+ if (!MagickChannelEnabled(channels,YellowChannel))
+ for (i=0 ; i < npixels; i++)
+ SetYellowSample(&update_pixels[i],GetYellowSample(&source_pixels[i]));
+ if (!MagickChannelEnabled(channels,BlackChannel))
+ for (i=0 ; i < npixels; i++)
+ SetBlackSample(&update_pixels[i],GetBlackSample(&source_pixels[i]));
+ if ((update_image->matte) &&
+ (!MagickChannelEnabled(channels,OpacityChannel)) &&
+ (source_indexes != (const IndexPacket *) NULL) &&
+ (update_indexes != (IndexPacket *) NULL))
+ (void) memcpy(update_indexes,source_indexes,npixels*sizeof(IndexPacket));
+ }
+ else
+ {
+ if (!MagickChannelEnabled(channels,RedChannel))
+ for (i=0 ; i < npixels; i++)
+ SetRedSample(&update_pixels[i],GetRedSample(&source_pixels[i]));
+ if (!MagickChannelEnabled(channels,GreenChannel))
+ for (i=0 ; i < npixels; i++)
+ SetGreenSample(&update_pixels[i],GetGreenSample(&source_pixels[i]));
+ if (!MagickChannelEnabled(channels,BlueChannel))
+ for (i=0 ; i < npixels; i++)
+ SetBlueSample(&update_pixels[i],GetBlueSample(&source_pixels[i]));
+ if (!MagickChannelEnabled(channels,OpacityChannel))
+ for (i=0 ; i < npixels; i++)
+ SetOpacitySample(&update_pixels[i],GetOpacitySample(&source_pixels[i]));
+ }
+
+ return MagickPass;
+}
+
+#define ImportImageChannelsMaskedText "[%s] Importing channels... "
+MagickPassFail ImportImageChannelsMasked(const Image *source_image,
+ Image *update_image,
+ const ChannelType channels)
+{
+ ChannelType
+ channel_type = channels;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(update_image != (Image *) NULL);
+ assert(update_image->signature == MagickSignature);
+ assert(source_image != (Image *) NULL);
+ assert(source_image->signature == MagickSignature);
+
+ if (!((AllChannels == channel_type) || (GrayChannel == channel_type)))
+ {
+ update_image->storage_class=DirectClass;
+ status=PixelIterateDualModify(ImportImageChannelsMaskedPixels,
+ NULL,
+ ImportImageChannelsMaskedText,
+ NULL,&channel_type,
+ source_image->columns,source_image->rows,
+ source_image,0,0,
+ update_image,0,0,
+ &update_image->exception);
+ }
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e C h a n n e l D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageChannelDepth() translates the pixel quantums in the specified
+% channel so that if they are later divided to fit within the specified bit
+% depth, that no additional information is lost (i.e. no remainder resulting
+% from the division). Note that any subsequent image processing is likely
+% to increase the effective depth of the image channels. A non-zero
+% value is returned if the operation is successful. Check the exception
+% member of image to determine the cause for any failure.
+%
+% The format of the SetImageChannelDepth method is:
+%
+% MagickPassFail SetImageChannelDepth(Image *image,
+% const ChannelType channel,
+% const unsigned int depth)
+%
+% A description of each parameter follows:
+%
+% o image: The image to update.
+%
+% o channel: Channel to modify.
+%
+% o depth: Desired channel depth (range 1 to QuantumDepth)
+%
+%
+*/
+MagickExport MagickPassFail SetImageChannelDepth(Image *image,
+ const ChannelType channel,
+ const unsigned int depth)
+{
+ return QuantumOperatorImage(image,channel,DepthQuantumOp,(double) depth,
+ &image->exception);
+}
diff --git a/magick/channel.h b/magick/channel.h
new file mode 100644
index 0000000..5dceaee
--- /dev/null
+++ b/magick/channel.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2004 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+*/
+#ifndef _MAGICK_CHANNEL_H
+#define _MAGICK_CHANNEL_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+extern MagickExport Image
+ *ExportImageChannel(const Image *image,
+ const ChannelType channel,
+ ExceptionInfo *exception);
+
+extern MagickExport unsigned int
+ GetImageChannelDepth(const Image *image,
+ const ChannelType channel,
+ ExceptionInfo *exception);
+
+extern MagickExport MagickPassFail
+ ChannelImage(Image *image,const ChannelType channel),
+ ImportImageChannel(const Image *src_image,
+ Image *dst_image,
+ const ChannelType channel),
+ ImportImageChannelsMasked(const Image *source_image,
+ Image *update_image,
+ const ChannelType channels),
+ SetImageChannelDepth(Image *image,
+ const ChannelType channel,
+ const unsigned int depth);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_CHANNEL_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/color.c b/magick/color.c
new file mode 100644
index 0000000..835cf71
--- /dev/null
+++ b/magick/color.c
@@ -0,0 +1,966 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% CCCC OOO L OOO RRRR %
+% C O O L O O R R %
+% C O O L O O RRRR %
+% C O O L O O R R %
+% CCCC OOO LLLLL OOO R R %
+% %
+% %
+% Methods to Count the Colors in an Image %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/quantize.h"
+#include "magick/semaphore.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define ColorToNodeId(red,green,blue,index) ((unsigned int) \
+ (((ScaleQuantumToChar(red) >> index) & 0x01U) << 2U | \
+ ((ScaleQuantumToChar(green) >> index) & 0x01U) << 1U | \
+ ((ScaleQuantumToChar(blue) >> index) & 0x01U)))
+
+/*
+ Structures.
+*/
+typedef struct _ColorPacket
+{
+ unsigned long
+ count;
+
+ PixelPacket
+ pixel;
+
+ unsigned short
+ index;
+
+} ColorPacket;
+
+typedef struct _NodeInfo
+{
+ struct _NodeInfo
+ *child[8];
+
+ ColorPacket
+ *list;
+
+ unsigned long
+ number_unique;
+
+ unsigned char
+ level;
+} NodeInfo;
+
+typedef struct _Nodes
+{
+ NodeInfo
+ nodes[NodesInAList];
+
+ struct _Nodes
+ *next;
+} Nodes;
+
+typedef struct _CubeInfo
+{
+ NodeInfo
+ *root;
+
+ unsigned long
+ progress,
+ colors,
+ free_nodes;
+
+ NodeInfo
+ *node_info;
+
+ Nodes
+ *node_queue;
+} CubeInfo;
+
+/*
+ Static declarations.
+*/
+
+/*
+ Forward declarations.
+*/
+static CubeInfo
+ *ComputeCubeInfo(const Image *image,ExceptionInfo *exception),
+ *GetCubeInfo(void);
+
+static NodeInfo
+ *GetNodeInfo(CubeInfo *,const unsigned int);
+
+static void
+ DestroyColorList(NodeInfo *node_info),
+ DestroyCubeInfo(CubeInfo *cube_info),
+ HistogramToFile(const Image *,CubeInfo *,const NodeInfo *,FILE *,ExceptionInfo *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C o m p u t e C u b e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ComputeCubeInfo builds a populated CubeInfo tree for the specified
+% image. The returned tree should be deallocated using DestroyCubeInfo()
+% once it is no longer needed.
+%
+% The format of the ComputeCubeInfo method is:
+%
+% CubeInfo *ComputeCubeInfo(const Image *image,ExceptionInfo *exception)
+%
+%
+*/
+static CubeInfo *
+ComputeCubeInfo(const Image *image,ExceptionInfo *exception)
+{
+#define ComputeImageColorsText "[%s] Compute colors..."
+
+ CubeInfo
+ *cube_info;
+
+ long
+ y;
+
+ NodeInfo
+ *node_info;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register unsigned int
+ id,
+ index,
+ level;
+
+ /*
+ Initialize color description tree.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ cube_info=GetCubeInfo();
+ if (cube_info == (CubeInfo *) NULL)
+ {
+ ThrowException3(exception,ResourceLimitError,MemoryAllocationFailed,
+ UnableToDetermineTheNumberOfImageColors);
+ return(0);
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ DestroyCubeInfo(cube_info);
+ return(0);
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ /*
+ Start at the root and proceed level by level.
+ */
+ node_info=cube_info->root;
+ index=MaxTreeDepth-1;
+ for (level=1; level <= MaxTreeDepth; level++)
+ {
+ id=ColorToNodeId(p->red,p->green,p->blue,index);
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ {
+ node_info->child[id]=GetNodeInfo(cube_info,level);
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ {
+ DestroyCubeInfo(cube_info);
+ ThrowException3(exception,ResourceLimitError,
+ MemoryAllocationFailed,
+ UnableToDetermineTheNumberOfImageColors);
+ return(0);
+ }
+ }
+ node_info=node_info->child[id];
+ index--;
+ if (level != MaxTreeDepth)
+ continue;
+ for (i=0; i < (long) node_info->number_unique; i++)
+ if (ColorMatch(p,&node_info->list[i].pixel))
+ break;
+ if (i < (long) node_info->number_unique)
+ {
+ node_info->list[i].count++;
+ continue;
+ }
+ if (node_info->number_unique == 0)
+ node_info->list=MagickAllocateMemory(ColorPacket *,
+ sizeof(ColorPacket));
+ else
+ MagickReallocMemory(ColorPacket *,node_info->list,
+ (i+1)*sizeof(ColorPacket));
+ if (node_info->list == (ColorPacket *) NULL)
+ {
+ DestroyCubeInfo(cube_info);
+ ThrowException3(exception,ResourceLimitError,
+ MemoryAllocationFailed,
+ UnableToDetermineTheNumberOfImageColors);
+ return(0);
+ }
+ node_info->list[i].pixel=(*p);
+ node_info->list[i].count=1;
+ node_info->number_unique++;
+ cube_info->colors++;
+ }
+ p++;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ ComputeImageColorsText,image->filename))
+ break;
+ }
+ return (cube_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y C u b e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyCubeInfo() deallocates memory associated with a CubeInfo structure.
+%
+% The format of the DestroyCubeInfo method is:
+%
+% DestroyCubeInfo(CubeInfo *cube_info)
+%
+% A description of each parameter follows:
+%
+% o cube_info: The address of a structure of type CubeInfo.
+%
+%
+*/
+static void DestroyCubeInfo(CubeInfo *cube_info)
+{
+ register Nodes
+ *nodes;
+
+ /*
+ Release color cube tree storage.
+ */
+ DestroyColorList(cube_info->root);
+ do
+ {
+ nodes=cube_info->node_queue->next;
+ MagickFreeMemory(cube_info->node_queue);
+ cube_info->node_queue=nodes;
+ } while (cube_info->node_queue != (Nodes *) NULL);
+ MagickFreeMemory(cube_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y C o l o r L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyColorList traverses the color cube tree and frees the list of
+% unique colors.
+%
+% The format of the DestroyColorList method is:
+%
+% void DestroyColorList(const NodeInfo *node_info)
+%
+% A description of each parameter follows.
+%
+% o node_info: The address of a structure of type NodeInfo which points to a
+% node in the color cube tree that is to be pruned.
+%
+%
+*/
+static void DestroyColorList(NodeInfo *node_info)
+{
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < 8; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ DestroyColorList(node_info->child[id]);
+ MagickFreeMemory(node_info->list);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ F u z z y C o l o r M a t c h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FuzzyColorMatch() returns true if the distance between two colors is
+% less than the specified distance in a linear three dimensional color space.
+% This function is used by ColorFloodFill and other algorithms which
+% compare two colors.
+%
+% The format of the FuzzyColorMatc method is:
+%
+% MagickBool FuzzyColorMatch(const PixelPacket *p,
+% const PixelPacket *q,const double fuzz)
+%
+% A description of each parameter follows:
+%
+% o p: Pixel p.
+%
+% o q: Pixel q.
+%
+% o fuzz: Define how much difference is acceptable in order to
+% consider two colors to be the same.
+%
+%
+*/
+MagickExport MagickBool FuzzyColorMatch(const PixelPacket *p,
+ const PixelPacket *q,const double fuzz)
+{
+ double
+ difference,
+ distance,
+ fuzz_squared;
+
+ if (fuzz <= MagickEpsilon)
+ return (ColorMatch(q,p));
+ fuzz_squared=fuzz*fuzz;
+ difference=p->red-(double) q->red;
+ distance=difference*difference;
+ if (distance > (fuzz_squared))
+ return(MagickFalse);
+ difference=p->green-(double) q->green;
+ distance+=difference*difference;
+ if (distance > (fuzz_squared))
+ return(MagickFalse);
+ difference=p->blue-(double) q->blue;
+ distance+=difference*difference;
+ if (distance > (fuzz_squared))
+ return(MagickFalse);
+ return(MagickTrue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C o l o r H i s t o g r a m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetColorHistogram returns an array of HistogramColorPacket structures
+% which specify the number of times each unique color occurs in the image.
+% The referenced colors parameter is updated with the number of unique colors
+% in the image. The returned array should be deallocated by the user once it
+% is no longer ndded.
+%
+% The format of the GetColorHistogram method is:
+%
+% HistogramColorPacket *GetColorHistogram(const Image *,
+% unsigned long *colors, ExceptionInfo *)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o colors: The referenced value is updated with the with the number of
+% unique colors.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static void HistogramToPacket(const Image *image,CubeInfo *cube_info,
+ const NodeInfo *node_info,HistogramColorPacket **histogram_packet,
+ ExceptionInfo *exception)
+{
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < 8; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ HistogramToPacket(image,cube_info,node_info->child[id],histogram_packet,
+ exception);
+ if (node_info->level == MaxTreeDepth)
+ {
+ register ColorPacket
+ *p;
+
+ register long
+ i;
+
+ p=node_info->list;
+ for (i=0; i < (long) node_info->number_unique; i++)
+ {
+ (*histogram_packet)->pixel=p->pixel;
+ (*histogram_packet)->count=p->count;
+ (*histogram_packet)++;
+ p++;
+ }
+ }
+}
+MagickExport HistogramColorPacket *GetColorHistogram(const Image *image,
+ unsigned long *colors, ExceptionInfo *exception)
+{
+ CubeInfo
+ *cube_info;
+
+ HistogramColorPacket
+ *current_packet,
+ *histogram;
+
+ unsigned long
+ number_colors;
+
+ /*
+ Initialize color description tree.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ *colors=0;
+ cube_info=ComputeCubeInfo(image,exception);
+ if (cube_info == (CubeInfo *) NULL)
+ return(0);
+
+ number_colors=cube_info->colors;
+ histogram=MagickAllocateMemory(HistogramColorPacket *,
+ number_colors*sizeof(HistogramColorPacket));
+ if (histogram == 0)
+ {
+ DestroyCubeInfo(cube_info);
+ ThrowException3(exception,ResourceLimitError,MemoryAllocationFailed,
+ UnableToDetermineTheNumberOfImageColors);
+ return 0;
+ }
+ *colors=number_colors;
+ current_packet=histogram;
+ HistogramToPacket(image,cube_info,cube_info->root,&current_packet,exception);
+ DestroyCubeInfo(cube_info);
+ return(histogram);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t C o l o r T u p l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetColorTuple() returns a color as a color tuple string.
+%
+% The format of the GetColorTuple method is:
+%
+% GetColorTuple(const PixelPacket *color,const unsigned int depth,
+% const unsigned int matte,const unsigned int hex,char *tuple)
+%
+% A description of each parameter follows.
+%
+% o color: The color.
+%
+% o depth: The color depth.
+%
+% o matte: A value other than zero returns the opacity in the tuple.
+%
+% o hex: A value other than zero returns the tuple in a hexidecimal format.
+%
+% o tuple: Return the color tuple as this string.
+%
+%
+*/
+MagickExport void GetColorTuple(const PixelPacket *color,
+ const unsigned int depth,const unsigned int matte,const unsigned int hex,
+ char *tuple)
+{
+ assert(color != (const PixelPacket *) NULL);
+ assert(tuple != (char *) NULL);
+ if (matte)
+ {
+ if (depth <= 8)
+ {
+ FormatString(tuple,hex ? "#%02X%02X%02X%02X" : "(%3u,%3u,%3u,%3u)",
+ ScaleQuantumToChar(color->red),ScaleQuantumToChar(color->green),
+ ScaleQuantumToChar(color->blue),ScaleQuantumToChar(color->opacity));
+ return;
+ }
+ if (depth <= 16)
+ {
+ FormatString(tuple,hex ? "#%04X%04X%04X%04X" : "(%5u,%5u,%5u,%5u)",
+ ScaleQuantumToShort(color->red),ScaleQuantumToShort(color->green),
+ ScaleQuantumToShort(color->blue),
+ ScaleQuantumToShort(color->opacity));
+ return;
+ }
+ FormatString(tuple,
+ hex ? "#%08lX%08lX%08lX%08lX" : "(%10lu,%10lu,%10lu,%10lu)",
+ ScaleQuantumToLong(color->red),ScaleQuantumToLong(color->green),
+ ScaleQuantumToLong(color->blue),ScaleQuantumToLong(color->opacity));
+ return;
+ }
+ if (depth <= 8)
+ {
+ FormatString(tuple,hex ? "#%02X%02X%02X" : "(%3u,%3u,%3u)",
+ ScaleQuantumToChar(color->red),ScaleQuantumToChar(color->green),
+ ScaleQuantumToChar(color->blue));
+ return;
+ }
+ if (depth <= 16)
+ {
+ FormatString(tuple,hex ? "#%04X%04X%04X" : "(%5u,%5u,%5u)",
+ ScaleQuantumToShort(color->red),ScaleQuantumToShort(color->green),
+ ScaleQuantumToShort(color->blue));
+ return;
+ }
+ FormatString(tuple,hex ? "#%08lX%08lX%08lX" : "(%10lu,%10lu,%10lu)",
+ ScaleQuantumToLong(color->red),ScaleQuantumToLong(color->green),
+ ScaleQuantumToLong(color->blue));
+ return;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t C u b e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetCubeInfo initialize the CubeInfo data structure.
+%
+% The format of the GetCubeInfo method is:
+%
+% cube_info=GetCubeInfo()
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+%
+*/
+static CubeInfo *GetCubeInfo(void)
+{
+ CubeInfo
+ *cube_info;
+
+ /*
+ Initialize tree to describe color cube.
+ */
+ cube_info=MagickAllocateMemory(CubeInfo *,sizeof(CubeInfo));
+ if (cube_info == (CubeInfo *) NULL)
+ return((CubeInfo *) NULL);
+ (void) memset(cube_info,0,sizeof(CubeInfo));
+ /*
+ Initialize root node.
+ */
+ cube_info->root=GetNodeInfo(cube_info,0);
+ if (cube_info->root == (NodeInfo *) NULL)
+ return((CubeInfo *) NULL);
+ return(cube_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t N o d e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetNodeInfo allocates memory for a new node in the color cube tree
+% and presets all fields to zero.
+%
+% The format of the GetNodeInfo method is:
+%
+% node_info=GetNodeInfo(cube_info,level)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the CubeInfo structure.
+%
+% o level: Specifies the level in the storage_class the node resides.
+%
+%
+*/
+static NodeInfo *GetNodeInfo(CubeInfo *cube_info,const unsigned int level)
+{
+ NodeInfo
+ *node_info;
+
+ if (cube_info->free_nodes == 0)
+ {
+ Nodes
+ *nodes;
+
+ /*
+ Allocate a new nodes of nodes.
+ */
+ nodes=MagickAllocateMemory(Nodes *,sizeof(Nodes));
+ if (nodes == (Nodes *) NULL)
+ return((NodeInfo *) NULL);
+ nodes->next=cube_info->node_queue;
+ cube_info->node_queue=nodes;
+ cube_info->node_info=nodes->nodes;
+ cube_info->free_nodes=NodesInAList;
+ }
+ cube_info->free_nodes--;
+ node_info=cube_info->node_info++;
+ (void) memset(node_info,0,sizeof(NodeInfo));
+ node_info->level=level;
+ return(node_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t N u m b e r C o l o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetNumberColors returns the number of unique colors in an image.
+%
+% The format of the GetNumberColors method is:
+%
+% unsigned long GetNumberColors(const Image *image,FILE *file,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o file: Write a histogram of the color distribution to this file handle.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport unsigned long GetNumberColors(const Image *image,FILE *file,
+ ExceptionInfo *exception)
+{
+ CubeInfo
+ *cube_info;
+
+ unsigned long
+ number_colors;
+
+ /*
+ Initialize color description tree.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ cube_info=ComputeCubeInfo(image,exception);
+ if (cube_info == (CubeInfo *) NULL)
+ return(0);
+
+ if (file != (FILE *) NULL)
+ {
+ (void) fprintf(file,"\n");
+ HistogramToFile(image,cube_info,cube_info->root,file,exception);
+ (void) fflush(file);
+ }
+ number_colors=cube_info->colors;
+ DestroyCubeInfo(cube_info);
+ return(number_colors);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ H i s t o g r a m T o F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method HistogramToFile traverses the color cube tree and produces a list of
+% unique pixel field values and the number of times each occurs in the image.
+%
+% The format of the HistogramToFile method is:
+%
+% void HistogramToFile(const Image *image,CubeInfo *cube_info,
+% const NodeInfo *node_info,FILE *file,ExceptionInfo *exception
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the CubeInfo structure.
+%
+% o node_info: The address of a structure of type NodeInfo which points to a
+% node in the color cube tree that is to be pruned.
+%
+%
+*/
+static void
+HistogramToFile(const Image *image,CubeInfo *cube_info,
+ const NodeInfo *node_info,FILE *file,
+ ExceptionInfo *exception)
+{
+#define HistogramToFileImageText "[%s] Compute histogram..."
+
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < 8; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ HistogramToFile(image,cube_info,node_info->child[id],file,exception);
+ if (node_info->level == MaxTreeDepth)
+ {
+ char
+ name[MaxTextExtent],
+ tuple[MaxTextExtent];
+
+ register ColorPacket
+ *p;
+
+ register long
+ i;
+
+ p=node_info->list;
+ for (i=0; i < (long) node_info->number_unique; i++)
+ {
+ GetColorTuple(&p->pixel,image->depth,image->matte,False,tuple);
+ (void) fprintf(file,"%10lu: %.1024s ",p->count,tuple);
+ (void) fprintf(file," ");
+ (void) QueryColorname(image,&p->pixel,SVGCompliance,name,exception);
+ (void) fprintf(file,"%.1024s",name);
+ (void) fprintf(file,"\n");
+ p++;
+ }
+ if (QuantumTick(cube_info->progress,cube_info->colors))
+ (void) MagickMonitorFormatted(cube_info->progress,
+ cube_info->colors,exception,
+ HistogramToFileImageText,
+ image->filename);
+ cube_info->progress++;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s P a l e t t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsPaletteImage returns True if the image is PseudoClass and has 256
+% unique colors or less.
+%
+% The format of the IsPaletteImage method is:
+%
+% MagickBool IsPaletteImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o status: Method IsPaletteImage returns True is the image is
+% PseudoClass or has 256 color or less.
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define AnalyzePaletteImageText "[%s] Analyze for palette..."
+MagickExport MagickBool IsPaletteImage(const Image *image,
+ ExceptionInfo *exception)
+{
+ CubeInfo
+ *cube_info;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register NodeInfo
+ *node_info;
+
+ register long
+ i;
+
+ unsigned long
+ index,
+ level;
+
+ unsigned int
+ id;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if ((image->storage_class == PseudoClass) && (image->colors <= 256))
+ return(MagickTrue);
+ if (image->storage_class == PseudoClass)
+ return(MagickFalse);
+ /*
+ Initialize color description tree.
+ */
+ cube_info=GetCubeInfo();
+ if (cube_info == (CubeInfo *) NULL)
+ {
+ ThrowException3(exception,ResourceLimitError,MemoryAllocationFailed,
+ UnableToDetermineImageClass);
+ return(MagickFalse);
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ DestroyCubeInfo(cube_info);
+ cube_info=(CubeInfo *) NULL;
+ return(MagickFalse);
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ /*
+ Start at the root and proceed level by level.
+ */
+ node_info=cube_info->root;
+ index=MaxTreeDepth-1;
+ for (level=1; level < MaxTreeDepth; level++)
+ {
+ id=ColorToNodeId(p->red,p->green,p->blue,level);
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ {
+ node_info->child[id]=GetNodeInfo(cube_info,level);
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ {
+ ThrowException3(exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDetermineImageClass);
+ DestroyCubeInfo(cube_info);
+ cube_info=(CubeInfo *) NULL;
+ return(MagickFalse);
+ }
+ }
+ node_info=node_info->child[id];
+ index--;
+ }
+ for (i=0; i < (long) node_info->number_unique; i++)
+ if (ColorMatch(p,&node_info->list[i].pixel))
+ break;
+ if (i == (long) node_info->number_unique)
+ {
+ /*
+ Add this unique color to the color list.
+ */
+ if (node_info->number_unique == 0)
+ node_info->list=MagickAllocateMemory(ColorPacket *,
+ sizeof(ColorPacket));
+ else
+ MagickReallocMemory(ColorPacket *,node_info->list,
+ (i+1)*sizeof(ColorPacket));
+ if (node_info->list == (ColorPacket *) NULL)
+ {
+ ThrowException3(exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDetermineImageClass);
+ DestroyCubeInfo(cube_info);
+ cube_info=(CubeInfo *) NULL;
+ return(MagickFalse);
+ }
+ node_info->list[i].pixel=(*p);
+ node_info->list[i].index=(unsigned short) cube_info->colors++;
+ node_info->number_unique++;
+ if (cube_info->colors > 256)
+ {
+ DestroyCubeInfo(cube_info);
+ cube_info=(CubeInfo *) NULL;
+ return(MagickFalse);
+ }
+ }
+ p++;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ AnalyzePaletteImageText,
+ image->filename))
+ break;
+ }
+ DestroyCubeInfo(cube_info);
+ cube_info=(CubeInfo *) NULL;
+ return(MagickTrue);
+}
diff --git a/magick/color.h b/magick/color.h
new file mode 100644
index 0000000..f25c745
--- /dev/null
+++ b/magick/color.h
@@ -0,0 +1,103 @@
+/*
+ Copyright (C) 2003 - 2010 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Color Utility Methods.
+*/
+#ifndef _MAGICK_COLOR_H
+#define _MAGICK_COLOR_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+/*
+ PixelPacket with usage count, used to support color histograms.
+*/
+typedef struct _HistogramColorPacket
+{
+ PixelPacket
+ pixel;
+
+ unsigned long
+ count;
+} HistogramColorPacket;
+
+extern MagickExport HistogramColorPacket
+ *GetColorHistogram(const Image *image,unsigned long *colors,
+ ExceptionInfo *exception);
+
+extern MagickExport unsigned long
+ GetNumberColors(const Image *image,FILE *file,ExceptionInfo *exception);
+
+extern MagickExport void
+ GetColorTuple(const PixelPacket *color,const unsigned int depth,
+ const unsigned int matte,const unsigned int hex,char *tuple);
+
+extern MagickExport MagickBool
+ IsPaletteImage(const Image *image,ExceptionInfo *exception);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+/*
+ Macros for testing a pixel to see if it is grayscale, bilevel,
+ black, or white
+*/
+#define IsGray(color) \
+ (((color).red == (color).green) && ((color).red == (color).blue))
+#define IsMonochrome(color) \
+ (((0 == (color).red) || (MaxRGB == (color).red)) && IsGray(color))
+
+#define IsBlackPixel(color) \
+ (((color).red == 0U) && IsGray(color))
+
+#define IsWhitePixel(color) \
+ (((color).red == MaxRGB) && IsGray(color))
+
+/*
+ Compare two colors
+*/
+#define ColorMatch(p,q) \
+ (((p)->red == (q)->red) && \
+ ((p)->green == (q)->green) && \
+ ((p)->blue == (q)->blue))
+
+#define NotColorMatch(p,q) \
+ (((p)->red != (q)->red) || \
+ ((p)->green != (q)->green) || \
+ ((p)->blue != (q)->blue))
+
+extern MagickExport unsigned int
+ FuzzyColorMatch(const PixelPacket *p,const PixelPacket *q,const double fuzz);
+
+/*
+ Compare two pixels (including opacity)
+*/
+#define PixelMatch(p,q,matte) \
+ (ColorMatch(p,q) && \
+ (!matte || ((p)->opacity == (q)->opacity)))
+
+#define NotPixelMatch(p,q,matte) \
+ (NotColorMatch(p,q) || \
+ (matte && ((p)->opacity != (q)->opacity)))
+
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_COLOR_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/color_lookup.c b/magick/color_lookup.c
new file mode 100644
index 0000000..b0d88a3
--- /dev/null
+++ b/magick/color_lookup.c
@@ -0,0 +1,1698 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% Color Lookup Functions
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/semaphore.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define ColorFilename "colors.mgk"
+
+/*
+ Declare color map.
+*/
+
+static const char
+ *BuiltInPath="[Built In]";
+
+static const struct
+{
+ char
+ *name;
+
+ unsigned short
+ compliance;
+
+ unsigned char
+ red,
+ green,
+ blue,
+ opacity;
+}
+StaticColors[] =
+{
+#define COLOR(name,red,green,blue,opacity,compliance) {name,compliance,red,green,blue,opacity}
+ COLOR("AliceBlue",240,248,255,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("AntiqueWhite",250,235,215,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("AntiqueWhite1",255,239,219,0,X11Compliance),
+ COLOR("AntiqueWhite2",238,223,204,0,X11Compliance),
+ COLOR("AntiqueWhite3",205,192,176,0,X11Compliance),
+ COLOR("AntiqueWhite4",139,131,120,0,X11Compliance),
+ COLOR("aqua",0,255,255,0,SVGCompliance),
+ COLOR("aquamarine",127,255,212,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("aquamarine1",127,255,212,0,X11Compliance),
+ COLOR("aquamarine2",118,238,198,0,X11Compliance),
+ COLOR("aquamarine3",102,205,170,0,X11Compliance),
+ COLOR("aquamarine4",69,139,116,0,X11Compliance),
+ COLOR("azure",240,255,255,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("azure1",240,255,255,0,X11Compliance),
+ COLOR("azure2",224,238,238,0,X11Compliance),
+ COLOR("azure3",193,205,205,0,X11Compliance),
+ COLOR("azure4",131,139,139,0,X11Compliance),
+ COLOR("beige",245,245,220,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("bisque",255,228,196,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("bisque1",255,228,196,0,X11Compliance),
+ COLOR("bisque2",238,213,183,0,X11Compliance),
+ COLOR("bisque3",205,183,158,0,X11Compliance),
+ COLOR("bisque4",139,125,107,0,X11Compliance),
+ COLOR("black",0,0,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("BlanchedAlmond",255,235,205,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("blue",0,0,255,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("blue1",0,0,255,0,X11Compliance),
+ COLOR("blue2",0,0,238,0,X11Compliance),
+ COLOR("blue3",0,0,205,0,X11Compliance),
+ COLOR("blue4",0,0,139,0,X11Compliance),
+ COLOR("BlueViolet",138,43,226,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("brown",165,42,42,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("brown1",255,64,64,0,X11Compliance),
+ COLOR("brown2",238,59,59,0,X11Compliance),
+ COLOR("brown3",205,51,51,0,X11Compliance),
+ COLOR("brown4",139,35,35,0,X11Compliance),
+ COLOR("burlywood",222,184,135,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("burlywood1",255,211,155,0,X11Compliance),
+ COLOR("burlywood2",238,197,145,0,X11Compliance),
+ COLOR("burlywood3",205,170,125,0,X11Compliance),
+ COLOR("burlywood4",139,115,85,0,X11Compliance),
+ COLOR("cadet blue",95,158,160,0,X11Compliance),
+ COLOR("CadetBlue",95,158,160,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("CadetBlue1",152,245,255,0,X11Compliance),
+ COLOR("CadetBlue2",142,229,238,0,X11Compliance),
+ COLOR("CadetBlue3",122,197,205,0,X11Compliance),
+ COLOR("CadetBlue4",83,134,139,0,X11Compliance),
+ COLOR("chartreuse",127,255,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("chartreuse1",127,255,0,0,X11Compliance),
+ COLOR("chartreuse2",118,238,0,0,X11Compliance),
+ COLOR("chartreuse3",102,205,0,0,X11Compliance),
+ COLOR("chartreuse4",69,139,0,0,X11Compliance),
+ COLOR("chocolate",210,105,30,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("chocolate1",255,127,36,0,X11Compliance),
+ COLOR("chocolate2",238,118,33,0,X11Compliance),
+ COLOR("chocolate3",205,102,29,0,X11Compliance),
+ COLOR("chocolate4",139,69,19,0,X11Compliance),
+ COLOR("coral",255,127,80,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("coral1",255,114,86,0,X11Compliance),
+ COLOR("coral2",238,106,80,0,X11Compliance),
+ COLOR("coral3",205,91,69,0,X11Compliance),
+ COLOR("coral4",139,62,47,0,X11Compliance),
+ COLOR("CornflowerBlue",100,149,237,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("cornsilk",255,248,220,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("cornsilk1",255,248,220,0,X11Compliance),
+ COLOR("cornsilk2",238,232,205,0,X11Compliance),
+ COLOR("cornsilk3",205,200,177,0,X11Compliance),
+ COLOR("cornsilk4",139,136,120,0,X11Compliance),
+ COLOR("crimson",220,20,60,0,SVGCompliance),
+ COLOR("cyan",0,255,255,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("cyan1",0,255,255,0,X11Compliance),
+ COLOR("cyan2",0,238,238,0,X11Compliance),
+ COLOR("cyan3",0,205,205,0,X11Compliance),
+ COLOR("cyan4",0,139,139,0,X11Compliance),
+ COLOR("dark violet",148,0,211,0,X11Compliance),
+ COLOR("DarkBlue",0,0,139,0,SVGCompliance|X11Compliance),
+ COLOR("DarkCyan",0,139,139,0,SVGCompliance|X11Compliance),
+ COLOR("DarkGoldenrod",184,134,11,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkGoldenrod1",255,185,15,0,X11Compliance),
+ COLOR("DarkGoldenrod2",238,173,14,0,X11Compliance),
+ COLOR("DarkGoldenrod3",205,149,12,0,X11Compliance),
+ COLOR("DarkGoldenrod4",139,101,8,0,X11Compliance),
+ COLOR("DarkGray",169,169,169,0,SVGCompliance|X11Compliance),
+ COLOR("DarkGreen",0,100,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkKhaki",189,183,107,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkMagenta",139,0,139,0,SVGCompliance|X11Compliance),
+ COLOR("DarkOliveGreen",85,107,47,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkOliveGreen1",202,255,112,0,X11Compliance),
+ COLOR("DarkOliveGreen2",188,238,104,0,X11Compliance),
+ COLOR("DarkOliveGreen3",162,205,90,0,X11Compliance),
+ COLOR("DarkOliveGreen4",110,139,61,0,X11Compliance),
+ COLOR("DarkOrange",255,140,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkOrange1",255,127,0,0,X11Compliance),
+ COLOR("DarkOrange2",238,118,0,0,X11Compliance),
+ COLOR("DarkOrange3",205,102,0,0,X11Compliance),
+ COLOR("DarkOrange4",139,69,0,0,X11Compliance),
+ COLOR("DarkOrchid",153,50,204,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkOrchid1",191,62,255,0,X11Compliance),
+ COLOR("DarkOrchid2",178,58,238,0,X11Compliance),
+ COLOR("DarkOrchid3",154,50,205,0,X11Compliance),
+ COLOR("DarkOrchid4",104,34,139,0,X11Compliance),
+ COLOR("DarkRed",139,0,0,0,SVGCompliance|X11Compliance),
+ COLOR("DarkSalmon",233,150,122,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkSeaGreen",143,188,143,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkSeaGreen1",193,255,193,0,X11Compliance),
+ COLOR("DarkSeaGreen2",180,238,180,0,X11Compliance),
+ COLOR("DarkSeaGreen3",155,205,155,0,X11Compliance),
+ COLOR("DarkSeaGreen4",105,139,105,0,X11Compliance),
+ COLOR("DarkSlateBlue",72,61,139,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkSlateGray",47,79,79,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkSlateGray1",151,255,255,0,X11Compliance),
+ COLOR("DarkSlateGray2",141,238,238,0,X11Compliance),
+ COLOR("DarkSlateGray3",121,205,205,0,X11Compliance),
+ COLOR("DarkSlateGray4",82,139,139,0,X11Compliance),
+ COLOR("DarkTurquoise",0,206,209,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DarkViolet",148,0,211,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DeepPink",255,20,147,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DeepPink1",255,20,147,0,X11Compliance),
+ COLOR("DeepPink2",238,18,137,0,X11Compliance),
+ COLOR("DeepPink3",205,16,118,0,X11Compliance),
+ COLOR("DeepPink4",139,10,80,0,X11Compliance),
+ COLOR("DeepSkyBlue",0,191,255,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DeepSkyBlue1",0,191,255,0,X11Compliance),
+ COLOR("DeepSkyBlue2",0,178,238,0,X11Compliance),
+ COLOR("DeepSkyBlue3",0,154,205,0,X11Compliance),
+ COLOR("DeepSkyBlue4",0,104,139,0,X11Compliance),
+ COLOR("DimGray",105,105,105,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DodgerBlue",30,144,255,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("DodgerBlue1",30,144,255,0,X11Compliance),
+ COLOR("DodgerBlue2",28,134,238,0,X11Compliance),
+ COLOR("DodgerBlue3",24,116,205,0,X11Compliance),
+ COLOR("DodgerBlue4",16,78,139,0,X11Compliance),
+ COLOR("firebrick",178,34,34,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("firebrick1",255,48,48,0,X11Compliance),
+ COLOR("firebrick2",238,44,44,0,X11Compliance),
+ COLOR("firebrick3",205,38,38,0,X11Compliance),
+ COLOR("firebrick4",139,26,26,0,X11Compliance),
+ COLOR("FloralWhite",255,250,240,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("ForestGreen",34,139,34,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("fractal",128,128,128,0,SVGCompliance),
+ COLOR("fuchsia",255,0,255,0,SVGCompliance),
+ COLOR("gainsboro",220,220,220,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("GhostWhite",248,248,255,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("gold",255,215,0,0,X11Compliance|XPMCompliance),
+ COLOR("gold1",255,215,0,0,SVGCompliance|X11Compliance),
+ COLOR("gold2",238,201,0,0,X11Compliance),
+ COLOR("gold3",205,173,0,0,X11Compliance),
+ COLOR("gold4",139,117,0,0,X11Compliance),
+ COLOR("goldenrod",218,165,32,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("goldenrod1",255,193,37,0,X11Compliance),
+ COLOR("goldenrod2",238,180,34,0,X11Compliance),
+ COLOR("goldenrod3",205,155,29,0,X11Compliance),
+ COLOR("goldenrod4",139,105,20,0,X11Compliance),
+ COLOR("gray",126,126,126,0,SVGCompliance),
+ COLOR("gray",190,190,190,0,X11Compliance|XPMCompliance),
+ COLOR("gray0",0,0,0,0,X11Compliance|XPMCompliance),
+ COLOR("gray1",3,3,3,0,X11Compliance|XPMCompliance),
+ COLOR("gray10",26,26,26,0,X11Compliance|XPMCompliance),
+ COLOR("gray100",255,255,255,0,X11Compliance|XPMCompliance),
+ COLOR("gray11",28,28,28,0,X11Compliance|XPMCompliance),
+ COLOR("gray12",31,31,31,0,X11Compliance|XPMCompliance),
+ COLOR("gray13",33,33,33,0,X11Compliance|XPMCompliance),
+ COLOR("gray14",36,36,36,0,X11Compliance|XPMCompliance),
+ COLOR("gray15",38,38,38,0,X11Compliance|XPMCompliance),
+ COLOR("gray16",41,41,41,0,X11Compliance|XPMCompliance),
+ COLOR("gray17",43,43,43,0,X11Compliance|XPMCompliance),
+ COLOR("gray18",46,46,46,0,X11Compliance|XPMCompliance),
+ COLOR("gray19",48,48,48,0,X11Compliance|XPMCompliance),
+ COLOR("gray2",5,5,5,0,X11Compliance|XPMCompliance),
+ COLOR("gray20",51,51,51,0,X11Compliance|XPMCompliance),
+ COLOR("gray21",54,54,54,0,X11Compliance|XPMCompliance),
+ COLOR("gray22",56,56,56,0,X11Compliance|XPMCompliance),
+ COLOR("gray23",59,59,59,0,X11Compliance|XPMCompliance),
+ COLOR("gray24",61,61,61,0,X11Compliance|XPMCompliance),
+ COLOR("gray25",64,64,64,0,X11Compliance|XPMCompliance),
+ COLOR("gray26",66,66,66,0,X11Compliance|XPMCompliance),
+ COLOR("gray27",69,69,69,0,X11Compliance|XPMCompliance),
+ COLOR("gray28",71,71,71,0,X11Compliance|XPMCompliance),
+ COLOR("gray29",74,74,74,0,X11Compliance|XPMCompliance),
+ COLOR("gray3",8,8,8,0,X11Compliance|XPMCompliance),
+ COLOR("gray30",77,77,77,0,X11Compliance|XPMCompliance),
+ COLOR("gray31",79,79,79,0,X11Compliance|XPMCompliance),
+ COLOR("gray32",82,82,82,0,X11Compliance|XPMCompliance),
+ COLOR("gray33",84,84,84,0,X11Compliance|XPMCompliance),
+ COLOR("gray34",87,87,87,0,X11Compliance|XPMCompliance),
+ COLOR("gray35",89,89,89,0,X11Compliance|XPMCompliance),
+ COLOR("gray36",92,92,92,0,X11Compliance|XPMCompliance),
+ COLOR("gray37",94,94,94,0,X11Compliance|XPMCompliance),
+ COLOR("gray38",97,97,97,0,X11Compliance|XPMCompliance),
+ COLOR("gray39",99,99,99,0,X11Compliance|XPMCompliance),
+ COLOR("gray4",10,10,10,0,X11Compliance|XPMCompliance),
+ COLOR("gray40",102,102,102,0,X11Compliance|XPMCompliance),
+ COLOR("gray41",105,105,105,0,X11Compliance|XPMCompliance),
+ COLOR("gray42",107,107,107,0,X11Compliance|XPMCompliance),
+ COLOR("gray43",110,110,110,0,X11Compliance|XPMCompliance),
+ COLOR("gray44",112,112,112,0,X11Compliance|XPMCompliance),
+ COLOR("gray45",115,115,115,0,X11Compliance|XPMCompliance),
+ COLOR("gray46",117,117,117,0,X11Compliance|XPMCompliance),
+ COLOR("gray47",120,120,120,0,X11Compliance|XPMCompliance),
+ COLOR("gray48",122,122,122,0,X11Compliance|XPMCompliance),
+ COLOR("gray49",125,125,125,0,X11Compliance|XPMCompliance),
+ COLOR("gray5",13,13,13,0,X11Compliance|XPMCompliance),
+ COLOR("gray50",127,127,127,0,X11Compliance|XPMCompliance),
+ COLOR("gray51",130,130,130,0,X11Compliance|XPMCompliance),
+ COLOR("gray52",133,133,133,0,X11Compliance|XPMCompliance),
+ COLOR("gray53",135,135,135,0,X11Compliance|XPMCompliance),
+ COLOR("gray54",138,138,138,0,X11Compliance|XPMCompliance),
+ COLOR("gray55",140,140,140,0,X11Compliance|XPMCompliance),
+ COLOR("gray56",143,143,143,0,X11Compliance|XPMCompliance),
+ COLOR("gray57",145,145,145,0,X11Compliance|XPMCompliance),
+ COLOR("gray58",148,148,148,0,X11Compliance|XPMCompliance),
+ COLOR("gray59",150,150,150,0,X11Compliance|XPMCompliance),
+ COLOR("gray6",15,15,15,0,X11Compliance|XPMCompliance),
+ COLOR("gray60",153,153,153,0,X11Compliance|XPMCompliance),
+ COLOR("gray61",156,156,156,0,X11Compliance|XPMCompliance),
+ COLOR("gray62",158,158,158,0,X11Compliance|XPMCompliance),
+ COLOR("gray63",161,161,161,0,X11Compliance|XPMCompliance),
+ COLOR("gray64",163,163,163,0,X11Compliance|XPMCompliance),
+ COLOR("gray65",166,166,166,0,X11Compliance|XPMCompliance),
+ COLOR("gray66",168,168,168,0,X11Compliance|XPMCompliance),
+ COLOR("gray67",171,171,171,0,X11Compliance|XPMCompliance),
+ COLOR("gray68",173,173,173,0,X11Compliance|XPMCompliance),
+ COLOR("gray69",176,176,176,0,X11Compliance|XPMCompliance),
+ COLOR("gray7",18,18,18,0,X11Compliance|XPMCompliance),
+ COLOR("gray70",179,179,179,0,X11Compliance|XPMCompliance),
+ COLOR("gray71",181,181,181,0,X11Compliance|XPMCompliance),
+ COLOR("gray72",184,184,184,0,X11Compliance|XPMCompliance),
+ COLOR("gray73",186,186,186,0,X11Compliance|XPMCompliance),
+ COLOR("gray74",189,189,189,0,X11Compliance|XPMCompliance),
+ COLOR("gray75",191,191,191,0,X11Compliance|XPMCompliance),
+ COLOR("gray76",194,194,194,0,X11Compliance|XPMCompliance),
+ COLOR("gray77",196,196,196,0,X11Compliance|XPMCompliance),
+ COLOR("gray78",199,199,199,0,X11Compliance|XPMCompliance),
+ COLOR("gray79",201,201,201,0,X11Compliance|XPMCompliance),
+ COLOR("gray8",20,20,20,0,X11Compliance|XPMCompliance),
+ COLOR("gray80",204,204,204,0,X11Compliance|XPMCompliance),
+ COLOR("gray81",207,207,207,0,X11Compliance|XPMCompliance),
+ COLOR("gray82",209,209,209,0,X11Compliance|XPMCompliance),
+ COLOR("gray83",212,212,212,0,X11Compliance|XPMCompliance),
+ COLOR("gray84",214,214,214,0,X11Compliance|XPMCompliance),
+ COLOR("gray85",217,217,217,0,X11Compliance|XPMCompliance),
+ COLOR("gray86",219,219,219,0,X11Compliance|XPMCompliance),
+ COLOR("gray87",222,222,222,0,X11Compliance|XPMCompliance),
+ COLOR("gray88",224,224,224,0,X11Compliance|XPMCompliance),
+ COLOR("gray89",227,227,227,0,X11Compliance|XPMCompliance),
+ COLOR("gray9",23,23,23,0,X11Compliance|XPMCompliance),
+ COLOR("gray90",229,229,229,0,X11Compliance|XPMCompliance),
+ COLOR("gray91",232,232,232,0,X11Compliance|XPMCompliance),
+ COLOR("gray92",235,235,235,0,X11Compliance|XPMCompliance),
+ COLOR("gray93",237,237,237,0,X11Compliance|XPMCompliance),
+ COLOR("gray94",240,240,240,0,X11Compliance|XPMCompliance),
+ COLOR("gray95",242,242,242,0,X11Compliance|XPMCompliance),
+ COLOR("gray96",245,245,245,0,X11Compliance|XPMCompliance),
+ COLOR("gray97",247,247,247,0,X11Compliance|XPMCompliance),
+ COLOR("gray98",250,250,250,0,X11Compliance|XPMCompliance),
+ COLOR("gray99",252,252,252,0,X11Compliance|XPMCompliance),
+ COLOR("green",0,128,0,0,SVGCompliance),
+ COLOR("green",0,255,0,0,X11Compliance|XPMCompliance),
+ COLOR("green1",0,255,0,0,X11Compliance),
+ COLOR("green2",0,238,0,0,X11Compliance),
+ COLOR("green3",0,205,0,0,X11Compliance),
+ COLOR("green4",0,139,0,0,X11Compliance),
+ COLOR("GreenYellow",173,255,47,0,X11Compliance|XPMCompliance),
+ COLOR("honeydew",240,255,240,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("honeydew1",240,255,240,0,X11Compliance),
+ COLOR("honeydew2",224,238,224,0,X11Compliance),
+ COLOR("honeydew3",193,205,193,0,X11Compliance),
+ COLOR("honeydew4",131,139,131,0,X11Compliance),
+ COLOR("HotPink",255,105,180,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("HotPink1",255,110,180,0,X11Compliance),
+ COLOR("HotPink2",238,106,167,0,X11Compliance),
+ COLOR("HotPink3",205,96,144,0,X11Compliance),
+ COLOR("HotPink4",139,58,98,0,X11Compliance),
+ COLOR("IndianRed",205,92,92,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("IndianRed1",255,106,106,0,X11Compliance),
+ COLOR("IndianRed2",238,99,99,0,X11Compliance),
+ COLOR("IndianRed3",205,85,85,0,X11Compliance),
+ COLOR("IndianRed4",139,58,58,0,X11Compliance),
+ COLOR("indigo",75,0,130,0,SVGCompliance),
+ COLOR("ivory",255,255,240,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("ivory1",255,255,240,0,X11Compliance),
+ COLOR("ivory2",238,238,224,0,X11Compliance),
+ COLOR("ivory3",205,205,193,0,X11Compliance),
+ COLOR("ivory4",139,139,131,0,X11Compliance),
+ COLOR("khaki",240,230,140,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("khaki1",255,246,143,0,X11Compliance),
+ COLOR("khaki2",238,230,133,0,X11Compliance),
+ COLOR("khaki3",205,198,115,0,X11Compliance),
+ COLOR("khaki4",139,134,78,0,X11Compliance),
+ COLOR("lavender",230,230,250,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LavenderBlush",255,240,245,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LavenderBlush1",255,240,245,0,X11Compliance),
+ COLOR("LavenderBlush2",238,224,229,0,X11Compliance),
+ COLOR("LavenderBlush3",205,193,197,0,X11Compliance),
+ COLOR("LavenderBlush4",139,131,134,0,X11Compliance),
+ COLOR("LawnGreen",124,252,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LemonChiffon",255,250,205,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LemonChiffon1",255,250,205,0,X11Compliance),
+ COLOR("LemonChiffon2",238,233,191,0,X11Compliance),
+ COLOR("LemonChiffon3",205,201,165,0,X11Compliance),
+ COLOR("LemonChiffon4",139,137,112,0,X11Compliance),
+ COLOR("LightBlue",173,216,230,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightBlue1",191,239,255,0,X11Compliance),
+ COLOR("LightBlue2",178,223,238,0,X11Compliance),
+ COLOR("LightBlue3",154,192,205,0,X11Compliance),
+ COLOR("LightBlue4",104,131,139,0,X11Compliance),
+ COLOR("LightCoral",240,128,128,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightCyan",224,255,255,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightCyan1",224,255,255,0,X11Compliance),
+ COLOR("LightCyan2",209,238,238,0,X11Compliance),
+ COLOR("LightCyan3",180,205,205,0,X11Compliance),
+ COLOR("LightCyan4",122,139,139,0,X11Compliance),
+ COLOR("LightGoldenrod",238,221,130,0,X11Compliance|XPMCompliance),
+ COLOR("LightGoldenrod1",255,236,139,0,X11Compliance),
+ COLOR("LightGoldenrod2",238,220,130,0,X11Compliance),
+ COLOR("LightGoldenrod3",205,190,112,0,X11Compliance),
+ COLOR("LightGoldenrod4",139,129,76,0,X11Compliance),
+ COLOR("LightGoldenrodYellow",250,250,210,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightGray",211,211,211,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightGreen",144,238,144,0,SVGCompliance|X11Compliance),
+ COLOR("LightPink",255,182,193,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightPink1",255,174,185,0,X11Compliance),
+ COLOR("LightPink2",238,162,173,0,X11Compliance),
+ COLOR("LightPink3",205,140,149,0,X11Compliance),
+ COLOR("LightPink4",139,95,101,0,X11Compliance),
+ COLOR("LightSalmon",255,160,122,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightSalmon1",255,160,122,0,X11Compliance),
+ COLOR("LightSalmon2",238,149,114,0,X11Compliance),
+ COLOR("LightSalmon3",205,129,98,0,X11Compliance),
+ COLOR("LightSalmon4",139,87,66,0,X11Compliance),
+ COLOR("LightSeaGreen",32,178,170,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightSkyBlue",135,206,250,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightSkyBlue1",176,226,255,0,X11Compliance),
+ COLOR("LightSkyBlue2",164,211,238,0,X11Compliance),
+ COLOR("LightSkyBlue3",141,182,205,0,X11Compliance),
+ COLOR("LightSkyBlue4",96,123,139,0,X11Compliance),
+ COLOR("LightSlateBlue",132,112,255,0,X11Compliance|XPMCompliance),
+ COLOR("LightSlateGray",119,136,153,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightSteelBlue",176,196,222,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightSteelBlue1",202,225,255,0,X11Compliance),
+ COLOR("LightSteelBlue2",188,210,238,0,X11Compliance),
+ COLOR("LightSteelBlue3",162,181,205,0,X11Compliance),
+ COLOR("LightSteelBlue4",110,123,139,0,X11Compliance),
+ COLOR("LightYellow",255,255,224,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("LightYellow1",255,255,224,0,X11Compliance),
+ COLOR("LightYellow2",238,238,209,0,X11Compliance),
+ COLOR("LightYellow3",205,205,180,0,X11Compliance),
+ COLOR("LightYellow4",139,139,122,0,X11Compliance),
+ COLOR("lime",0,255,0,0,SVGCompliance),
+ COLOR("LimeGreen",50,205,50,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("linen",250,240,230,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("magenta",255,0,255,0,SVGCompliance),
+ COLOR("magenta",255,0,255,0,X11Compliance|XPMCompliance),
+ COLOR("magenta1",255,0,255,0,X11Compliance),
+ COLOR("magenta2",238,0,238,0,X11Compliance),
+ COLOR("magenta3",205,0,205,0,X11Compliance),
+ COLOR("magenta4",139,0,139,0,X11Compliance),
+ COLOR("maroon",128,0,0,0,SVGCompliance),
+ COLOR("maroon",176,48,96,0,X11Compliance|XPMCompliance),
+ COLOR("maroon1",255,52,179,0,X11Compliance),
+ COLOR("maroon2",238,48,167,0,X11Compliance),
+ COLOR("maroon3",205,41,144,0,X11Compliance),
+ COLOR("maroon4",139,28,98,0,X11Compliance),
+ COLOR("MediumAquamarine",102,205,170,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MediumBlue",0,0,205,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MediumForestGreen",50,129,75,0,X11Compliance|XPMCompliance),
+ COLOR("MediumGoldenRod",209,193,102,0,X11Compliance|XPMCompliance),
+ COLOR("MediumOrchid",186,85,211,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MediumOrchid1",224,102,255,0,X11Compliance),
+ COLOR("MediumOrchid2",209,95,238,0,X11Compliance),
+ COLOR("MediumOrchid3",180,82,205,0,X11Compliance),
+ COLOR("MediumOrchid4",122,55,139,0,X11Compliance),
+ COLOR("MediumPurple",147,112,219,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MediumPurple1",171,130,255,0,X11Compliance),
+ COLOR("MediumPurple2",159,121,238,0,X11Compliance),
+ COLOR("MediumPurple3",137,104,205,0,X11Compliance),
+ COLOR("MediumPurple4",93,71,139,0,X11Compliance),
+ COLOR("MediumSeaGreen",60,179,113,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MediumSlateBlue",123,104,238,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MediumSpringGreen",0,250,154,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MediumTurquoise",72,209,204,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MediumVioletRed",199,21,133,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MidnightBlue",25,25,112,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MintCream",245,255,250,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MistyRose",255,228,225,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("MistyRose1",255,228,225,0,X11Compliance),
+ COLOR("MistyRose2",238,213,210,0,X11Compliance),
+ COLOR("MistyRose3",205,183,181,0,X11Compliance),
+ COLOR("MistyRose4",139,125,123,0,X11Compliance),
+ COLOR("moccasin",255,228,181,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("NavajoWhite",255,222,173,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("NavajoWhite1",255,222,173,0,X11Compliance),
+ COLOR("NavajoWhite2",238,207,161,0,X11Compliance),
+ COLOR("NavajoWhite3",205,179,139,0,X11Compliance),
+ COLOR("NavajoWhite4",139,121,94,0,X11Compliance),
+ COLOR("navy",0,0,128,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("NavyBlue",0,0,128,0,X11Compliance|XPMCompliance),
+ COLOR("none",0,0,0,255,SVGCompliance),
+ COLOR("OldLace",253,245,230,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("olive",128,128,0,0,SVGCompliance),
+ COLOR("OliveDrab",107,142,35,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("OliveDrab1",192,255,62,0,X11Compliance),
+ COLOR("OliveDrab2",179,238,58,0,X11Compliance),
+ COLOR("OliveDrab3",154,205,50,0,X11Compliance),
+ COLOR("OliveDrab4",105,139,34,0,X11Compliance),
+ COLOR("opaque",0,0,0,0,SVGCompliance),
+ COLOR("orange",255,165,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("orange1",255,165,0,0,X11Compliance),
+ COLOR("orange2",238,154,0,0,X11Compliance),
+ COLOR("orange3",205,133,0,0,X11Compliance),
+ COLOR("orange4",139,90,0,0,X11Compliance),
+ COLOR("OrangeRed",255,69,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("OrangeRed1",255,69,0,0,X11Compliance),
+ COLOR("OrangeRed2",238,64,0,0,X11Compliance),
+ COLOR("OrangeRed3",205,55,0,0,X11Compliance),
+ COLOR("OrangeRed4",139,37,0,0,X11Compliance),
+ COLOR("orchid",218,112,214,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("orchid1",255,131,250,0,X11Compliance),
+ COLOR("orchid2",238,122,233,0,X11Compliance),
+ COLOR("orchid3",205,105,201,0,X11Compliance),
+ COLOR("orchid4",139,71,137,0,X11Compliance),
+ COLOR("PaleGoldenrod",238,232,170,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("PaleGreen",152,251,152,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("PaleGreen1",154,255,154,0,X11Compliance),
+ COLOR("PaleGreen2",144,238,144,0,X11Compliance),
+ COLOR("PaleGreen3",124,205,124,0,X11Compliance),
+ COLOR("PaleGreen4",84,139,84,0,X11Compliance),
+ COLOR("PaleTurquoise",175,238,238,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("PaleTurquoise1",187,255,255,0,X11Compliance),
+ COLOR("PaleTurquoise2",174,238,238,0,X11Compliance),
+ COLOR("PaleTurquoise3",150,205,205,0,X11Compliance),
+ COLOR("PaleTurquoise4",102,139,139,0,X11Compliance),
+ COLOR("PaleVioletRed",219,112,147,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("PaleVioletRed1",255,130,171,0,X11Compliance),
+ COLOR("PaleVioletRed2",238,121,159,0,X11Compliance),
+ COLOR("PaleVioletRed3",205,104,137,0,X11Compliance),
+ COLOR("PaleVioletRed4",139,71,93,0,X11Compliance),
+ COLOR("PapayaWhip",255,239,213,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("PeachPuff",255,218,185,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("PeachPuff1",255,218,185,0,X11Compliance),
+ COLOR("PeachPuff2",238,203,173,0,X11Compliance),
+ COLOR("PeachPuff3",205,175,149,0,X11Compliance),
+ COLOR("PeachPuff4",139,119,101,0,X11Compliance),
+ COLOR("peru",205,133,63,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("pink",255,192,203,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("pink1",255,181,197,0,X11Compliance),
+ COLOR("pink2",238,169,184,0,X11Compliance),
+ COLOR("pink3",205,145,158,0,X11Compliance),
+ COLOR("pink4",139,99,108,0,X11Compliance),
+ COLOR("plum",221,160,221,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("plum1",255,187,255,0,X11Compliance),
+ COLOR("plum2",238,174,238,0,X11Compliance),
+ COLOR("plum3",205,150,205,0,X11Compliance),
+ COLOR("plum4",139,102,139,0,X11Compliance),
+ COLOR("PowderBlue",176,224,230,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("purple",128,0,128,0,SVGCompliance),
+ COLOR("purple",160,32,240,0,X11Compliance|XPMCompliance),
+ COLOR("purple1",155,48,255,0,X11Compliance),
+ COLOR("purple2",145,44,238,0,X11Compliance),
+ COLOR("purple3",125,38,205,0,X11Compliance),
+ COLOR("purple4",85,26,139,0,X11Compliance),
+ COLOR("red",255,0,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("red1",255,0,0,0,X11Compliance),
+ COLOR("red2",238,0,0,0,X11Compliance),
+ COLOR("red3",205,0,0,0,X11Compliance),
+ COLOR("red4",139,0,0,0,X11Compliance),
+ COLOR("RosyBrown",188,143,143,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("RosyBrown1",255,193,193,0,X11Compliance),
+ COLOR("RosyBrown2",238,180,180,0,X11Compliance),
+ COLOR("RosyBrown3",205,155,155,0,X11Compliance),
+ COLOR("RosyBrown4",139,105,105,0,X11Compliance),
+ COLOR("RoyalBlue",65,105,225,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("RoyalBlue1",72,118,255,0,X11Compliance),
+ COLOR("RoyalBlue2",67,110,238,0,X11Compliance),
+ COLOR("RoyalBlue3",58,95,205,0,X11Compliance),
+ COLOR("RoyalBlue4",39,64,139,0,X11Compliance),
+ COLOR("SaddleBrown",139,69,19,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("salmon",250,128,114,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("salmon1",255,140,105,0,X11Compliance),
+ COLOR("salmon2",238,130,98,0,X11Compliance),
+ COLOR("salmon3",205,112,84,0,X11Compliance),
+ COLOR("salmon4",139,76,57,0,X11Compliance),
+ COLOR("SandyBrown",244,164,96,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("SeaGreen",46,139,87,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("SeaGreen1",84,255,159,0,X11Compliance),
+ COLOR("SeaGreen2",78,238,148,0,X11Compliance),
+ COLOR("SeaGreen3",67,205,128,0,X11Compliance),
+ COLOR("SeaGreen4",46,139,87,0,X11Compliance),
+ COLOR("seashell",255,245,238,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("seashell1",255,245,238,0,X11Compliance),
+ COLOR("seashell2",238,229,222,0,X11Compliance),
+ COLOR("seashell3",205,197,191,0,X11Compliance),
+ COLOR("seashell4",139,134,130,0,X11Compliance),
+ COLOR("sienna",160,82,45,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("sienna1",255,130,71,0,X11Compliance),
+ COLOR("sienna2",238,121,66,0,X11Compliance),
+ COLOR("sienna3",205,104,57,0,X11Compliance),
+ COLOR("sienna4",139,71,38,0,X11Compliance),
+ COLOR("silver",192,192,192,0,SVGCompliance),
+ COLOR("SkyBlue",135,206,235,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("SkyBlue1",135,206,255,0,X11Compliance),
+ COLOR("SkyBlue2",126,192,238,0,X11Compliance),
+ COLOR("SkyBlue3",108,166,205,0,X11Compliance),
+ COLOR("SkyBlue4",74,112,139,0,X11Compliance),
+ COLOR("SlateBlue",106,90,205,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("SlateBlue1",131,111,255,0,X11Compliance),
+ COLOR("SlateBlue2",122,103,238,0,X11Compliance),
+ COLOR("SlateBlue3",105,89,205,0,X11Compliance),
+ COLOR("SlateBlue4",71,60,139,0,X11Compliance),
+ COLOR("SlateGray",112,128,144,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("SlateGray1",198,226,255,0,X11Compliance),
+ COLOR("SlateGray2",185,211,238,0,X11Compliance),
+ COLOR("SlateGray3",159,182,205,0,X11Compliance),
+ COLOR("SlateGray4",108,123,139,0,X11Compliance),
+ COLOR("snow",255,250,250,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("snow1",255,250,250,0,X11Compliance),
+ COLOR("snow2",238,233,233,0,X11Compliance),
+ COLOR("snow3",205,201,201,0,X11Compliance),
+ COLOR("snow4",139,137,137,0,X11Compliance),
+ COLOR("SpringGreen",0,255,127,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("SpringGreen1",0,255,127,0,X11Compliance),
+ COLOR("SpringGreen2",0,238,118,0,X11Compliance),
+ COLOR("SpringGreen3",0,205,102,0,X11Compliance),
+ COLOR("SpringGreen4",0,139,69,0,X11Compliance),
+ COLOR("SteelBlue",70,130,180,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("SteelBlue1",99,184,255,0,X11Compliance),
+ COLOR("SteelBlue2",92,172,238,0,X11Compliance),
+ COLOR("SteelBlue3",79,148,205,0,X11Compliance),
+ COLOR("SteelBlue4",54,100,139,0,X11Compliance),
+ COLOR("tan",210,180,140,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("tan1",255,165,79,0,X11Compliance),
+ COLOR("tan2",238,154,73,0,X11Compliance),
+ COLOR("tan3",205,133,63,0,X11Compliance),
+ COLOR("tan4",139,90,43,0,X11Compliance),
+ COLOR("teal",0,128,128,0,SVGCompliance),
+ COLOR("thistle",216,191,216,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("thistle1",255,225,255,0,X11Compliance),
+ COLOR("thistle2",238,210,238,0,X11Compliance),
+ COLOR("thistle3",205,181,205,0,X11Compliance),
+ COLOR("thistle4",139,123,139,0,X11Compliance),
+ COLOR("tomato",255,99,71,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("tomato1",255,99,71,0,X11Compliance),
+ COLOR("tomato2",238,92,66,0,X11Compliance),
+ COLOR("tomato3",205,79,57,0,X11Compliance),
+ COLOR("tomato4",139,54,38,0,X11Compliance),
+ COLOR("transparent",0,0,0,255,SVGCompliance),
+ COLOR("turquoise",64,224,208,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("turquoise1",0,245,255,0,X11Compliance),
+ COLOR("turquoise2",0,229,238,0,X11Compliance),
+ COLOR("turquoise3",0,197,205,0,X11Compliance),
+ COLOR("turquoise4",0,134,139,0,X11Compliance),
+ COLOR("violet",238,130,238,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("VioletRed",208,32,144,0,X11Compliance|XPMCompliance),
+ COLOR("VioletRed1",255,62,150,0,X11Compliance),
+ COLOR("VioletRed2",238,58,140,0,X11Compliance),
+ COLOR("VioletRed3",205,50,120,0,X11Compliance),
+ COLOR("VioletRed4",139,34,82,0,X11Compliance),
+ COLOR("wheat",245,222,179,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("wheat1",255,231,186,0,X11Compliance),
+ COLOR("wheat2",238,216,174,0,X11Compliance),
+ COLOR("wheat3",205,186,150,0,X11Compliance),
+ COLOR("wheat4",139,126,102,0,X11Compliance),
+ COLOR("white",255,255,255,0,SVGCompliance|X11Compliance),
+ COLOR("WhiteSmoke",245,245,245,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("yellow",255,255,0,0,SVGCompliance|X11Compliance|XPMCompliance),
+ COLOR("yellow1",255,255,0,0,X11Compliance),
+ COLOR("yellow2",238,238,0,0,X11Compliance),
+ COLOR("yellow3",205,205,0,0,X11Compliance),
+ COLOR("yellow4",139,139,0,0,X11Compliance),
+ COLOR("YellowGreen",154,205,50,0,SVGCompliance|X11Compliance|XPMCompliance)
+};
+
+/*
+ Static declarations.
+*/
+static SemaphoreInfo
+ *color_semaphore = (SemaphoreInfo *) NULL;
+
+static ColorInfo
+ *color_list = (ColorInfo *) NULL;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ ReadColorConfigureFile(const char *,const unsigned int,ExceptionInfo *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y C o l o r I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyColorInfo deallocates memory associated with the color list.
+%
+% The format of the DestroyColorInfo method is:
+%
+% DestroyColorInfo(void)
+%
+%
+*/
+static void
+DestroyColorInfoEntry(ColorInfo *entry)
+{
+ if (entry->previous)
+ entry->previous->next=entry->next;
+ if (entry->next)
+ entry->next->previous=entry->previous;
+ if (entry == color_list)
+ color_list=entry->next;
+ if ((entry->path[0] != BuiltInPath[0]) &&
+ (LocaleCompare(entry->path,BuiltInPath) != 0))
+ {
+ MagickFreeMemory(entry->path);
+ MagickFreeMemory(entry->name);
+ }
+ MagickFreeMemory(entry);
+}
+MagickExport void
+DestroyColorInfo(void)
+{
+ ColorInfo
+ *color_info;
+
+ register ColorInfo
+ *p;
+
+ for (p=color_list; p != (const ColorInfo *) NULL; )
+ {
+ color_info=p;
+ p=p->next;
+ DestroyColorInfoEntry(color_info);
+ }
+ color_list=(ColorInfo *) NULL;
+ DestroySemaphoreInfo(&color_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t C o l o r I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetColorInfo searches the color list for the specified name and if
+% found returns attributes for that color.
+%
+% The format of the GetColorInfo method is:
+%
+% const PixelPacket *GetColorInfo(const char *name,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o color_info: Method GetColorInfo searches the color list for the
+% specified name and if found returns attributes for that color.
+%
+% o name: The color name.
+%
+% o compliance: Define the required color standard.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const ColorInfo *
+GetColorInfo(const char *name,ExceptionInfo *exception)
+{
+ char
+ colorname[MaxTextExtent];
+
+ register ColorInfo
+ *p;
+
+ LockSemaphoreInfo(color_semaphore);
+ if (color_list == (ColorInfo *) NULL)
+ (void) ReadColorConfigureFile(ColorFilename,0,exception);
+ UnlockSemaphoreInfo(color_semaphore);
+ if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
+ return((const ColorInfo *) color_list);
+ /*
+ Search for named color.
+ */
+ if (strlcpy(colorname,name,MaxTextExtent) >= MaxTextExtent)
+ {
+ ThrowException(exception,OptionWarning,UnrecognizedColor,name);
+ return (const ColorInfo *) NULL;
+ }
+ /*
+ Compact by removing spaces
+ */
+ LockSemaphoreInfo(color_semaphore);
+ for (p=color_list; p != (ColorInfo *) NULL; p=p->next)
+ if (LocaleCompare(colorname,p->name) == 0)
+ break;
+ if (p == (ColorInfo *) NULL)
+ {
+ /* Check common synonyms */
+ const char
+ *pos;
+
+ LocaleUpper(colorname);
+ if ((pos = strstr(colorname,"GREY")) != (const char *) NULL)
+ {
+ colorname[pos-colorname+2]='A';
+ for (p=color_list; p != (ColorInfo *) NULL; p=p->next)
+ if (LocaleCompare(colorname,p->name) == 0)
+ break;
+ }
+ }
+ if (p == (ColorInfo *) NULL)
+ ThrowException(exception,OptionWarning,UnrecognizedColor,name);
+ else
+ if (p != color_list)
+ {
+ /*
+ Self-adjusting list.
+ */
+ if (p->previous != (ColorInfo *) NULL)
+ p->previous->next=p->next;
+ if (p->next != (ColorInfo *) NULL)
+ p->next->previous=p->previous;
+ p->previous=(ColorInfo *) NULL;
+ p->next=color_list;
+ color_list->previous=p;
+ color_list=p;
+ }
+ UnlockSemaphoreInfo(color_semaphore);
+ return ((const ColorInfo *) p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C o l o r I n f o A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetColorInfoArray() returns a sorted null-terminated array of ColorInfo
+% pointers corresponding to the available color definitions. This function
+% should be used to access the entire list rather than GetColorInfo since
+% the list returned by GetColorInfo may be re-ordered every time it is
+% invoked. GetColorList may be used if only a list of color names is desired.
+% The array should be deallocated by the user once it is no longer needed.
+% Do not attempt to deallocate members of the array.
+%
+% The format of the GetMagickList method is:
+%
+% ColorInfo **GetColorInfoArray(ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+/*
+ Compare two ColorInfo structures based on their name
+*/
+static int
+ColorInfoCompare(const void *x, const void *y)
+{
+ const ColorInfo
+ *xx=*((const ColorInfo **) x),
+ *yy=*((const ColorInfo **) y);
+
+ return strcmp(xx->name, yy->name);
+}
+MagickExport ColorInfo **
+GetColorInfoArray(ExceptionInfo *exception)
+{
+ ColorInfo
+ **array;
+
+ ColorInfo
+ *p;
+
+ ColorInfo
+ *list;
+
+ size_t
+ entries=0;
+
+ int
+ i;
+
+ /*
+ Load color list
+ */
+ (void) GetColorInfo("*",exception);
+ if ((!color_list) || (exception->severity > UndefinedException))
+ return 0;
+
+ LockSemaphoreInfo(color_semaphore);
+
+ list=color_list;
+
+ /*
+ Count number of list entries
+ */
+ for (p=list; p != 0; p=p->next)
+ entries++;
+
+ /*
+ Allocate array memory
+ */
+ array=MagickAllocateMemory(ColorInfo **,sizeof(ColorInfo *)*(entries+1));
+ if (!array)
+ {
+ UnlockSemaphoreInfo(color_semaphore);
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,0);
+ return False;
+ }
+ (void) memset((void **)array,0,sizeof(ColorInfo *)*(entries+1));
+
+ /*
+ Add entries to array
+ */
+ i=0;
+ for (p=list; p != 0; p=p->next)
+ array[i++]=p;
+
+ UnlockSemaphoreInfo(color_semaphore);
+
+ /*
+ Sort array entries
+ */
+ qsort((void *) array, entries, sizeof(ColorInfo *), ColorInfoCompare);
+
+ return (array);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C o l o r L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetColorList returns any colors that match the specified pattern.
+%
+% The format of the GetColorList function is:
+%
+% filelist=GetColorList(const char *pattern,unsigned long *number_colors)
+%
+% A description of each parameter follows:
+%
+% o filelist: Method GetColorList returns a list of colors that match the
+% specified pattern.
+%
+% o pattern: Specifies a pointer to a text string containing a pattern.
+%
+% o number_colors: This integer returns the number of colors in the list.
+%
+%
+*/
+MagickExport char **
+GetColorList(const char *pattern,unsigned long *number_colors)
+{
+ char
+ **colorlist;
+
+ ExceptionInfo
+ exception;
+
+ register long
+ i;
+
+ register const ColorInfo
+ *p;
+
+
+ assert(pattern != (char *) NULL);
+ assert(number_colors != (unsigned long *) NULL);
+ *number_colors=0;
+ GetExceptionInfo(&exception);
+ p=GetColorInfo("*",&exception);
+ DestroyExceptionInfo(&exception);
+ if (p == (const ColorInfo *) NULL)
+ return((char **) NULL);
+
+ /*
+ Determine color list size
+ */
+ LockSemaphoreInfo(color_semaphore);
+ i=0;
+ for (p=color_list; p != (const ColorInfo *) NULL; p=p->next)
+ i++;
+ UnlockSemaphoreInfo(color_semaphore);
+
+ /*
+ Allocate color list.
+ */
+ colorlist=MagickAllocateMemory(char **,i*sizeof(char *));
+ if (colorlist == (char **) NULL)
+ return((char **) NULL);
+
+ /*
+ Add colors matching glob specification to list
+ */
+ LockSemaphoreInfo(color_semaphore);
+ i=0;
+ for (p=color_list; p != (const ColorInfo *) NULL; p=p->next)
+ {
+ if (p->stealth)
+ continue;
+ if (GlobExpression(p->name,pattern))
+ colorlist[i++]=AcquireString(p->name);
+ }
+ UnlockSemaphoreInfo(color_semaphore);
+
+ *number_colors=i;
+ return(colorlist);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t C o l o r I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ListColorInfo() lists color names to the specified file. Color names
+% are a convenience. Rather than defining a color by its red, green, and
+% blue intensities just use a color name such as white, blue, or yellow.
+%
+% The format of the ListColorInfo method is:
+%
+% unsigned int ListColorInfo(FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o file: List color names to this file handle.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport unsigned int
+ListColorInfo(FILE *file,ExceptionInfo *exception)
+{
+ register long
+ i;
+
+ register const ColorInfo
+ *p;
+
+ if (file == (const FILE *) NULL)
+ file=stdout;
+ (void) GetColorInfo("*",exception);
+ LockSemaphoreInfo(color_semaphore);
+ for (p=color_list; p != (const ColorInfo *) NULL; p=p->next)
+ {
+ if ((p->previous == (ColorInfo *) NULL) ||
+ (LocaleCompare(p->path,p->previous->path) != 0))
+ {
+ if (p->previous != (ColorInfo *) NULL)
+ (void) fprintf(file,"\n");
+ if (p->path != (char *) NULL)
+ (void) fprintf(file,"Path: %.1024s\n\n",p->path);
+ (void) fprintf(file,
+ "Name Color Compliance\n");
+ (void) fprintf(file,"-------------------------------------------------"
+ "------------------------------\n");
+ }
+ if (p->stealth)
+ continue;
+
+ (void) fprintf(file,"%.1024s",p->name);
+ for (i=(long) strlen(p->name); i <= 22; i++)
+ (void) fprintf(file," ");
+
+ if (p->color.opacity == OpaqueOpacity)
+ (void) fprintf(file,"%5d,%5d,%5d ",
+ ScaleQuantumToChar(p->color.red),
+ ScaleQuantumToChar(p->color.green),
+ ScaleQuantumToChar(p->color.blue));
+ else
+ (void) fprintf(file,"%5d,%5d,%5d,%5d ",
+ ScaleQuantumToChar(p->color.red),
+ ScaleQuantumToChar(p->color.green),
+ ScaleQuantumToChar(p->color.blue),
+ ScaleQuantumToChar(p->color.opacity));
+ if ((unsigned int) p->compliance & (unsigned int) SVGCompliance)
+ (void) fprintf(file,"SVG ");
+ if ((unsigned int) p->compliance & (unsigned int) X11Compliance)
+ (void) fprintf(file,"X11 ");
+ if ((unsigned int) p->compliance & (unsigned int) XPMCompliance)
+ (void) fprintf(file,"XPM ");
+ (void) fprintf(file,"\n");
+ }
+ (void) fflush(file);
+ UnlockSemaphoreInfo(color_semaphore);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e C o l o r I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeColorInfo initializes the color look-up facility
+%
+% The format of the InitializeColorInfo method is:
+%
+% MagickPassFail InitializeColorInfo(void)
+%
+%
+*/
+MagickPassFail
+InitializeColorInfo(void)
+{
+ assert(color_semaphore == (SemaphoreInfo *) NULL);
+ color_semaphore=AllocateSemaphoreInfo();
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Q u e r y C o l o r D a t a b a s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% QueryColorDatabase() returns the red, green, blue, and opacity intensities
+% for a given color name.
+%
+% The format of the QueryColorDatabase method is:
+%
+% unsigned int QueryColorDatabase(const char *name,PixelPacket *color,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o name: The color name (e.g. white, blue, yellow).
+%
+% o color: The red, green, blue, and opacity intensities values of the
+% named color in this structure.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport unsigned int
+QueryColorDatabase(const char *name,PixelPacket *color,
+ ExceptionInfo *exception)
+{
+ double
+ scale;
+
+ register const ColorInfo
+ *p;
+
+ register int
+ i;
+
+ /*
+ Initialize color return value.
+ */
+ assert(color != (PixelPacket *) NULL);
+ (void) memset(color,0,sizeof(PixelPacket));
+ color->opacity=TransparentOpacity;
+ if ((name == (char *) NULL) || (*name == '\0'))
+ name=BackgroundColor;
+ while (isspace((int) (*name)))
+ name++;
+ if (*name == '#')
+ {
+ char
+ c;
+
+ int
+ n;
+
+ LongPixelPacket
+ pixel;
+
+ (void) memset(&pixel,0,sizeof(pixel));
+ name++;
+ for (n=0; isxdigit((int) name[n]); n++);
+ if ((n == 3) || (n == 6) || (n == 9) || (n == 12) || (n == 24))
+ {
+ /*
+ Parse RGB specification.
+ */
+ n/=3;
+ do
+ {
+ pixel.red=pixel.green;
+ pixel.green=pixel.blue;
+ pixel.blue=0;
+ for (i=n-1; i >= 0; i--)
+ {
+ c=(*name++);
+ pixel.blue<<=4;
+ if ((c >= '0') && (c <= '9'))
+ pixel.blue|=c-'0';
+ else
+ if ((c >= 'A') && (c <= 'F'))
+ pixel.blue|=c-('A'-10);
+ else
+ if ((c >= 'a') && (c <= 'f'))
+ pixel.blue|=c-('a'-10);
+ else
+ {
+ ThrowException(exception,OptionWarning,UnrecognizedColor,name);
+ return(False);
+ }
+ }
+ } while (isxdigit((int) *name));
+ }
+ else
+ if ((n != 4) && (n != 8) && (n != 16) && (n != 32))
+ {
+ ThrowException(exception,OptionWarning,UnrecognizedColor,name);
+ return(False);
+ }
+ else
+ {
+ /*
+ Parse RGBA specification.
+ */
+ n/=4;
+ do
+ {
+ pixel.red=pixel.green;
+ pixel.green=pixel.blue;
+ pixel.blue=pixel.opacity;
+ pixel.opacity=0;
+ for (i=n-1; i >= 0; i--)
+ {
+ c=(*name++);
+ pixel.opacity<<=4;
+ if ((c >= '0') && (c <= '9'))
+ pixel.opacity|=c-'0';
+ else
+ if ((c >= 'A') && (c <= 'F'))
+ pixel.opacity|=c-('A'-10);
+ else
+ if ((c >= 'a') && (c <= 'f'))
+ pixel.opacity|=c-('a'-10);
+ else
+ {
+ ThrowException(exception,OptionWarning,UnrecognizedColor,name);
+ return(False);
+ }
+ }
+ } while (isxdigit((int) *name));
+ }
+ {
+ unsigned int
+ divisor=1;
+
+ n<<=2;
+ for( i=n-1; i; i--)
+ {
+ divisor <<= 1;
+ divisor |=1;
+ }
+ color->red=(Quantum)
+ (((double) MaxRGB*pixel.red)/divisor+0.5);
+ color->green=(Quantum)
+ (((double) MaxRGB*pixel.green)/divisor+0.5);
+ color->blue=(Quantum)
+ (((double) MaxRGB*pixel.blue)/divisor+0.5);
+ color->opacity=OpaqueOpacity;
+ if ((n != 3) && (n != 6) && (n != 9) && (n != 12) && (n != 24))
+ color->opacity=(Quantum)
+ (((double) MaxRGB*pixel.opacity)/divisor+0.5);
+ }
+ return(True);
+ }
+ if (LocaleNCompare(name,"rgb(",4) == 0)
+ {
+ DoublePixelPacket
+ pixel;
+
+ scale=strchr(name,'%') == (char *) NULL ? 1.0 :
+ ScaleQuantumToChar(MaxRGB)/100.0;
+ (void) sscanf(name,"%*[^(](%lf%*[%,]%lf%*[%,]%lf",
+ &pixel.red,&pixel.green,&pixel.blue);
+ color->red=ScaleCharToQuantum(scale*pixel.red);
+ color->green=ScaleCharToQuantum(scale*pixel.green);
+ color->blue=ScaleCharToQuantum(scale*pixel.blue);
+ color->opacity=OpaqueOpacity;
+ return(True);
+ }
+ if (LocaleNCompare(name,"rgba(",5) == 0)
+ {
+ DoublePixelPacket
+ pixel;
+
+ scale=strchr(name,'%') == (char *) NULL ? 1.0 :
+ ScaleQuantumToChar(MaxRGB)/100.0;
+ (void) sscanf(name,"%*[^(](%lf%*[%,]%lf%*[%,]%lf%*[%,]%lf",
+ &pixel.red,&pixel.green,&pixel.blue,&pixel.opacity);
+ color->red=ScaleCharToQuantum(scale*pixel.red);
+ color->green=ScaleCharToQuantum(scale*pixel.green);
+ color->blue=ScaleCharToQuantum(scale*pixel.blue);
+ color->opacity=ScaleCharToQuantum(scale*pixel.opacity);
+ return(True);
+ }
+ p=GetColorInfo(name,exception);
+ if (p == (const ColorInfo *) NULL)
+ return(False);
+ if ((LocaleCompare(p->name,"opaque") == 0) ||
+ (LocaleCompare(p->name,"transparent") == 0))
+ {
+ color->opacity=p->color.opacity;
+ return(True);
+ }
+ *color=p->color;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Q u e r y C o l o r n a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% QueryColorname() returns a named color for the given color intensity. If
+% an exact match is not found, a hex value is return instead. For example
+% an intensity of rgb:(0,0,0) returns black whereas rgb:(223,223,223)
+% returns #dfdfdf.
+%
+% The format of the QueryColorname method is:
+%
+% unsigned int QueryColorname(const Image *image,const PixelPacket *color,
+% const ComplianceType compliance,char *name,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o color: The color intensities.
+%
+% o Compliance: Adhere to this color standard: NoCompliance, SVGCompliance,
+% X11Compliance, XPMCompliance, AllCompliance.
+%
+% o name: Update with color name or hex value. Buffer should be be at
+% least MaxTextExtent long.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport unsigned int
+QueryColorname(const Image *image,const PixelPacket *color,
+ const ComplianceType compliance,char *name,
+ ExceptionInfo *exception)
+{
+ register const ColorInfo
+ *p;
+
+ MagickBool
+ matte;
+
+ *name='\0';
+ matte=image->matte;
+ if (compliance == XPMCompliance)
+ matte=MagickFalse;
+ p=GetColorInfo("*",exception);
+ if (p != (const ColorInfo *) NULL)
+ {
+ for (p=color_list; p != (const ColorInfo *) NULL; p=p->next)
+ {
+ if (!((unsigned int) p->compliance & (unsigned int) compliance))
+ continue;
+ if ((p->color.red != color->red) || (p->color.green != color->green) ||
+ (p->color.blue != color->blue) ||
+ (p->color.opacity != color->opacity))
+ continue;
+ (void) strlcpy(name,p->name,MaxTextExtent);
+ return(True);
+ }
+ }
+ GetColorTuple(color,image->depth,matte,True,name);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d C o l o r C o n f i g u r e F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadColorConfigureFile reads the color configuration file which maps
+% color strings with a particular image format.
+%
+% The format of the ReadColorConfigureFile method is:
+%
+% MagickPassFail ReadColorConfigureFile(const char *basename,
+% const unsigned int depth,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method ReadColorConfigureFile returns True if at least one color
+% is defined otherwise False.
+%
+% o basename: The color configuration filename.
+%
+% o depth: depth of <include /> statements.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail
+ReadColorConfigureFile(const char *basename,
+ const unsigned int depth,
+ ExceptionInfo *exception)
+{
+ size_t
+ length;
+
+ char
+ path[MaxTextExtent],
+ *xml;
+
+ if (depth == 0)
+ {
+ size_t
+ i;
+
+ /*
+ Load default set of colors from the static color table.
+ */
+ for (i=0 ; i < sizeof(StaticColors)/sizeof(StaticColors[0]); i++)
+ {
+ ColorInfo
+ *color_info;
+
+ color_info=MagickAllocateMemory(ColorInfo *,sizeof(ColorInfo));
+ if (color_info == (ColorInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateColorInfo);
+ color_info->path=(char *) BuiltInPath;
+ color_info->name=(char *) StaticColors[i].name;
+ color_info->compliance=(ComplianceType) StaticColors[i].compliance;
+ color_info->color.red=ScaleCharToQuantum(StaticColors[i].red);
+ color_info->color.green=ScaleCharToQuantum(StaticColors[i].green);
+ color_info->color.blue=ScaleCharToQuantum(StaticColors[i].blue);
+ color_info->color.opacity=ScaleCharToQuantum(StaticColors[i].opacity);
+ color_info->stealth=MagickFalse;
+ color_info->signature=MagickSignature;
+ color_info->previous=(ColorInfo *) NULL;
+ color_info->next=(ColorInfo *) NULL;
+ if (color_list == (ColorInfo *) NULL)
+ {
+ color_list=color_info;
+ continue;
+ }
+ color_list->next=color_info;
+ color_info->previous=color_list;
+ color_list=color_list->next;
+ }
+ }
+
+ /*
+ Read the color configure file (if any).
+ */
+ (void) strlcpy(path,basename,sizeof(path));
+ if (depth == 0)
+ {
+ ExceptionInfo
+ exception_local;
+
+ GetExceptionInfo(&exception_local);
+ xml=(char *) GetConfigureBlob(basename,path,&length,&exception_local);
+ if (exception_local.severity != ConfigureError)
+ CopyException(exception,&exception_local);
+ DestroyExceptionInfo(&exception_local);
+ }
+ else
+ {
+ xml=(char *) FileToBlob(basename,&length,exception);
+ }
+ if (xml != (char *) NULL)
+ {
+ char
+ keyword[MaxTextExtent],
+ *q,
+ *token;
+
+ size_t
+ token_max_length;
+
+ MagickBool
+ in_entry;
+
+ token=AcquireString(xml);
+ token_max_length=strlen(token);
+ in_entry=MagickFalse;
+ for (q=xml; *q != '\0'; )
+ {
+ /*
+ Interpret XML.
+ */
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == '\0')
+ break;
+ (void) strlcpy(keyword,token,sizeof(keyword));
+ if (LocaleNCompare(keyword,"<!--",4) == 0)
+ {
+ /*
+ Comment element.
+ */
+ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
+ MagickGetToken(q,&q,token,token_max_length);
+ continue;
+ }
+ if (LocaleCompare(keyword,"<include") == 0)
+ {
+ /*
+ Include element.
+ */
+ while ((*token != '>') && (*q != '\0'))
+ {
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(keyword,"file") == 0)
+ {
+ if (depth > 200)
+ ThrowException(exception,ConfigureError,
+ IncludeElementNestedTooDeeply,path);
+ else
+ {
+ char
+ filename[MaxTextExtent];
+
+ GetPathComponent(path,HeadPath,filename);
+ if (*filename != '\0')
+ (void) strlcat(filename,DirectorySeparator,sizeof(filename));
+ (void) strlcat(filename,token,sizeof(filename));
+ (void) ReadColorConfigureFile(filename,depth+1,exception);
+ }
+ if (color_list != (ColorInfo *) NULL)
+ while (color_list->next != (ColorInfo *) NULL)
+ color_list=color_list->next;
+ }
+ }
+ continue;
+ }
+ if (LocaleCompare(keyword,"<color") == 0)
+ {
+ ColorInfo
+ *color_info;
+
+ /*
+ Allocate memory for the color list.
+ */
+ in_entry=MagickTrue;
+ color_info=MagickAllocateMemory(ColorInfo *,sizeof(ColorInfo));
+ if (color_info == (ColorInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateColorInfo);
+ (void) memset(color_info,0,sizeof(ColorInfo));
+ color_info->path=AcquireString(path);
+ color_info->signature=MagickSignature;
+ if (color_list == (ColorInfo *) NULL)
+ {
+ color_list=color_info;
+ continue;
+ }
+ color_list->next=color_info;
+ color_info->previous=color_list;
+ color_list=color_list->next;
+ continue;
+ }
+ if (LocaleCompare(keyword,"/>") == 0)
+ {
+ /*
+ Closing a color specification.
+ */
+ if (in_entry)
+ {
+ /*
+ Remove any existing entry with same name (last one wins).
+ */
+ {
+ ColorInfo
+ *color_info;
+
+ for (color_info=color_list->previous;
+ color_info != (ColorInfo *) NULL;
+ color_info=color_info->previous)
+ {
+ if ((LocaleCompare(color_list->name,color_info->name) == 0) &&
+ (color_list->compliance == color_info->compliance))
+ {
+ DestroyColorInfoEntry(color_info);
+ break;
+ }
+ }
+ }
+ in_entry=MagickFalse;
+ }
+ }
+ if (color_list == (ColorInfo *) NULL)
+ continue;
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ switch (*keyword)
+ {
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare((char *) keyword,"blue") == 0)
+ {
+ color_list->color.blue=ScaleCharToQuantum(MagickAtoL(token));
+ break;
+ }
+ break;
+ }
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare((char *) keyword,"compliance") == 0)
+ {
+ long
+ compliance;
+
+ compliance=color_list->compliance;
+ if (GlobExpression(token,"*SVG*"))
+ compliance|=SVGCompliance;
+ if (GlobExpression(token,"*X11*"))
+ compliance|=X11Compliance;
+ if (GlobExpression(token,"*XPM*"))
+ compliance|=XPMCompliance;
+ color_list->compliance=(ComplianceType) compliance;
+ break;
+ }
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare((char *) keyword,"green") == 0)
+ {
+ color_list->color.green=ScaleCharToQuantum(MagickAtoL(token));
+ break;
+ }
+ break;
+ }
+ case 'N':
+ case 'n':
+ {
+ if (LocaleCompare((char *) keyword,"name") == 0)
+ {
+ color_list->name=AcquireString(token);
+ break;
+ }
+ break;
+ }
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare((char *) keyword,"opacity") == 0)
+ {
+ color_list->color.opacity=ScaleCharToQuantum(MagickAtoL(token));
+ break;
+ }
+ break;
+ }
+ case 'R':
+ case 'r':
+ {
+ if (LocaleCompare((char *) keyword,"red") == 0)
+ {
+ color_list->color.red=ScaleCharToQuantum(MagickAtoL(token));
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare((char *) keyword,"stealth") == 0)
+ {
+ color_list->stealth=LocaleCompare(token,"True") == 0;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ MagickFreeMemory(token);
+ MagickFreeMemory(xml);
+ }
+ if (color_list == (ColorInfo *) NULL)
+ return(MagickFail);
+ while (color_list->previous != (ColorInfo *) NULL)
+ color_list=color_list->previous;
+ return(MagickPass);
+}
diff --git a/magick/color_lookup.h b/magick/color_lookup.h
new file mode 100644
index 0000000..464ebd5
--- /dev/null
+++ b/magick/color_lookup.h
@@ -0,0 +1,96 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Color Lookup Methods.
+*/
+#ifndef _MAGICK_COLOR_LOOKUP_H
+#define _MAGICK_COLOR_LOOKUP_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+/*
+ Specifications that color is compliant with.
+*/
+typedef enum
+{
+ UndefinedCompliance = 0x0000,
+ NoCompliance = 0x0000,
+ SVGCompliance = 0x0001,
+ X11Compliance = 0x0002,
+ XPMCompliance = 0x0004,
+ AllCompliance = 0xffff
+} ComplianceType;
+
+extern MagickExport char
+ **GetColorList(const char *pattern,unsigned long *number_colors);
+
+extern MagickExport unsigned int
+ QueryColorDatabase(const char *name,PixelPacket *color,ExceptionInfo *exception),
+ QueryColorname(const Image *image,const PixelPacket *color,
+ const ComplianceType compliance,char *name,ExceptionInfo *exception);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+/*
+ Information about a named color (Internal).
+*/
+typedef struct _ColorInfo
+{
+ char
+ *path,
+ *name;
+
+ ComplianceType
+ compliance;
+
+ PixelPacket
+ color;
+
+ unsigned int
+ stealth;
+
+ unsigned long
+ signature;
+
+ struct _ColorInfo
+ *previous,
+ *next;
+} ColorInfo;
+
+extern MagickExport const ColorInfo
+ *GetColorInfo(const char *name, ExceptionInfo *exception);
+
+extern MagickExport ColorInfo
+ **GetColorInfoArray(ExceptionInfo *exception);
+
+extern MagickExport void
+ DestroyColorInfo(void);
+
+extern MagickExport unsigned int
+ ListColorInfo(FILE *file,ExceptionInfo *exception);
+
+extern MagickPassFail
+ InitializeColorInfo(void);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_COLOR_LOOKUP_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/colormap.c b/magick/colormap.c
new file mode 100644
index 0000000..8fb7ce9
--- /dev/null
+++ b/magick/colormap.c
@@ -0,0 +1,547 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% GraphicsMagick Colormap Methods
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/pixel_iterator.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A l l o c a t e I m a g e C o l o r m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AllocateImageColormap() allocates an image colormap and initializes
+% it to a linear gray colorspace with increasing intensity. If the image
+% already has a colormap, it is replaced. AllocateImageColormap() returns
+% True if successful, otherwise False if there is not enough memory.
+%
+% The format of the AllocateImageColormap method is:
+%
+% unsigned int AllocateImageColormap(Image *image,
+% const unsigned long colors)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o colors: The number of colors in the image colormap.
+%
+%
+*/
+MagickExport MagickPassFail AllocateImageColormap(Image *image,
+ const unsigned long colors)
+{
+ register long
+ i;
+
+ size_t
+ length;
+
+ Quantum
+ quantum;
+
+ /*
+ Allocate image colormap.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (colors > MaxColormapSize)
+ return (MagickFail);
+ image->storage_class=PseudoClass;
+ image->colors=colors;
+ length=image->colors*sizeof(PixelPacket);
+ if (image->colormap == (PixelPacket *) NULL)
+ image->colormap=MagickAllocateMemory(PixelPacket *,length);
+ else
+ MagickReallocMemory(PixelPacket *,image->colormap,length);
+ if (image->colormap == (PixelPacket *) NULL)
+ {
+ image->colors=0;
+ image->storage_class=DirectClass;
+ return(MagickFail);
+ }
+ for (i=0; i < (long) image->colors; i++)
+ {
+ quantum=(Quantum) (i*(MaxRGB/Max(colors-1,1)));
+ image->colormap[i].red=quantum;
+ image->colormap[i].green=quantum;
+ image->colormap[i].blue=quantum;
+ image->colormap[i].opacity=OpaqueOpacity;
+ }
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C y c l e C o l o r m a p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CycleColormap() displaces an image's colormap by a given number of
+% positions. If you cycle the colormap a number of times you can produce
+% a psychodelic effect.
+%
+% The format of the CycleColormapImage method is:
+%
+% CycleColormapImage(Image *image,const int amount)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o amount: Offset the colormap this much.
+%
+%
+*/
+#define CycleColormapImageText "[%s] Cycle colormap..."
+static MagickPassFail
+CycleColormapCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Cycle colormap by amount.
+ */
+ const int
+ amount = *((const int *) immutable_data);
+
+
+ long
+ colormap_index;
+
+ register const PixelPacket
+ *colormap = image->colormap;
+
+ const unsigned long
+ colors = image->colors;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ colormap_index=(long) ((indexes[i]+amount) % colors);
+ if (colormap_index < 0L)
+ colormap_index+=colors;
+ indexes[i]=(IndexPacket) colormap_index;
+ pixels[i].red=colormap[colormap_index].red;
+ pixels[i].green=colormap[colormap_index].green;
+ pixels[i].blue=colormap[colormap_index].blue;
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail CycleColormapImage(Image *image,const int amount)
+{
+ unsigned int
+ is_grayscale,
+ is_monochrome,
+ status = MagickPass;
+
+ PixelIteratorOptions
+ options;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ is_grayscale=image->is_grayscale;
+ is_monochrome=image->is_monochrome;
+ if (image->storage_class == DirectClass)
+ (void) SetImageType(image,PaletteType);
+
+ InitializePixelIteratorOptions(&options,&image->exception);
+#if defined(HAVE_OPENMP) && defined(DisableSlowOpenMP)
+ options.max_threads=1;
+#endif
+ status=PixelIterateMonoModify(CycleColormapCallBack,&options,
+ CycleColormapImageText,
+ NULL,&amount,0,0,image->columns,image->rows,
+ image,&image->exception);
+ image->is_grayscale=is_grayscale;
+ image->is_monochrome=is_monochrome;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k C o n s t r a i n C o l o r m a p I n d e x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickConstrainColormapIndex() is a subordinate function for use by
+% the VerifyColormapIndex macro. If the colormap index is outside the
+% bounds of the image colormap then zero is returned and an
+% InvalidColormapIndex exception is thrown, otherwise the colormap
+% index is returned.
+%
+% The format of the MagickConstrainColormapIndex method is:
+%
+% unsigned int MagickConstrainColormapIndex(Image *image,
+% unsigned int index)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o index: The colormap index
+%
+%
+*/
+MagickExport unsigned int
+MagickConstrainColormapIndex(Image *image, unsigned int index)
+{
+ if (index < image->colors)
+ return index;
+
+ if (image->exception.severity < CorruptImageError )
+ {
+ char
+ colormapIndexBuffer[MaxTextExtent];
+
+ FormatString(colormapIndexBuffer,"index %u >= %u colors, %.1024s",
+ index, image->colors, image->filename);
+ errno=0;
+ ThrowException(&image->exception,CorruptImageError,
+ InvalidColormapIndex,colormapIndexBuffer);
+ }
+ return 0U;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e p l a c e I m a g e C o l o r m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReplaceImageColormap() replaces an existing image colormap with a new
+% image colormap. The new image colormap is expected to contain all of the
+% colors from the existing colormap. The existing colormap indexes are
+% adjusted to conform with positions in the new colormap. If the new
+% colormap contains duplicate entries, then the associated colormap index
+% will point to the first entry found in the colormap and other matching
+% entries will not be used. MagickPass is returned if the operation is
+% successful, otherwise MagickFail is returned, and image->exception is
+% updated with the cause of the failure.
+%
+% This function is useful in case colormap entries need to match across
+% multiple images or otherwise occupy specific locations.
+%
+% The format of the ReplaceImageColormap method is:
+%
+% MagickPassFail ReplaceImageColormap(Image *image,
+% const PixelPacket *colormap,
+% const unsigned int colors)
+%
+% A description of each parameter follows:
+%
+% o image: image in which to replace colormap.
+%
+% o colormap: new colormap.
+%
+% o colors: number of colors in new colormap.
+%
+*/
+#define ReplaceImageColormapText "[%s] Replacing image colormap..."
+static MagickPassFail
+ReplaceImageColormapCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Replace image colormap
+ */
+
+ const unsigned int
+ *colormap_index=(const unsigned int *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(pixels);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ indexes[i]=colormap_index[indexes[i]];
+
+ return MagickPass;
+}
+MagickExport MagickPassFail
+ReplaceImageColormap(Image *image,
+ const PixelPacket *colormap,
+ const unsigned int colors)
+{
+ unsigned int
+ *colormap_index=(unsigned int *) NULL;
+
+ PixelPacket
+ *new_colormap;
+
+ register unsigned int
+ i,
+ j;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(colormap != (const PixelPacket *) NULL);
+ assert(colors != 0);
+ assert(image->storage_class == PseudoClass);
+
+ /*
+ Allocate memory for colormap index
+ */
+ colormap_index=MagickAllocateArray(unsigned int *,
+ MaxColormapSize,sizeof(unsigned int));
+ if (colormap_index == (unsigned int *) NULL)
+ {
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToAllocateColormap);
+ return MagickFail;
+ }
+
+ /*
+ Allocate replacement colormap
+ */
+ new_colormap=MagickAllocateArray(PixelPacket *,
+ sizeof(PixelPacket),colors);
+ if (new_colormap == (PixelPacket *) NULL)
+ {
+ MagickFreeMemory(colormap_index);
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToAllocateColormap);
+ return MagickFail;
+ }
+
+ /*
+ Build a map between the new colormap and the old colormap.
+ */
+ (void) memset(colormap_index,0,MaxColormapSize*sizeof(unsigned int));
+ for (i=0; i < image->colors ; i++)
+ {
+ for (j=0; j < colors; j++)
+ {
+ if (ColorMatch(&colormap[j],&image->colormap[i]))
+ {
+ colormap_index[i]=j;
+ break;
+ }
+ }
+ }
+
+ if (status == MagickPass)
+ {
+ /*
+ Reassign image colormap indexes
+ */
+ status=PixelIterateMonoModify(ReplaceImageColormapCallBack,NULL,
+ ReplaceImageColormapText,
+ NULL,colormap_index,0,0,
+ image->columns,image->rows,
+ image,&image->exception);
+ /*
+ Replace existing colormap.
+ */
+ if (status == MagickPass)
+ {
+ (void) memcpy(new_colormap,colormap,sizeof(PixelPacket)*colors);
+ MagickFreeMemory(image->colormap);
+ image->colormap=new_colormap;
+ new_colormap=(PixelPacket *) NULL;
+
+ }
+ }
+
+ MagickFreeMemory(new_colormap);
+ MagickFreeMemory(colormap_index);
+
+ image->is_grayscale=IsGrayImage(image,&image->exception);
+ image->is_monochrome=IsMonochromeImage(image,&image->exception);
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S o r t C o l o r m a p B y I n t e n t s i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SortColormapByIntensity() sorts the colormap of a PseudoClass image by
+% decreasing color intensity.
+%
+% The format of the SortColormapByIntensity method is:
+%
+% unsigned int SortColormapByIntensity(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: A pointer to an Image structure.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int InverseIntensityCompare(const void *x,const void *y)
+{
+ long
+ intensity;
+
+ PixelPacket
+ *color_1,
+ *color_2;
+
+ color_1=(PixelPacket *) x;
+ color_2=(PixelPacket *) y;
+ /*
+ y - x results in decreasing order
+ */
+ intensity=PixelIntensityToQuantum(color_2)-
+ (long) PixelIntensityToQuantum(color_1);
+ return(intensity);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#define SortColormapByIntensityText "[%s] Sorting colormap by intensity... "
+static MagickPassFail
+SortColormapByIntensityCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Update image colormap indexes to reflect new ordering indicated by
+ new_indexes array.
+ */
+ const unsigned short
+ *new_indexes = (const unsigned short *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(pixels);
+ ARG_NOT_USED(exception);
+ for (i=0; i < npixels; i++)
+ indexes[i]=new_indexes[indexes[i]];
+
+ return MagickPass;
+}
+MagickExport MagickPassFail SortColormapByIntensity(Image *image)
+{
+ register long
+ i;
+
+ unsigned int
+ is_grayscale,
+ is_monochrome;
+
+ unsigned short
+ *new_indexes;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (image->storage_class != PseudoClass)
+ return(MagickFail);
+ is_grayscale=image->is_grayscale;
+ is_monochrome=image->is_monochrome;
+ /*
+ Allocate memory for pixel indexes.
+ */
+ new_indexes=MagickAllocateMemory(unsigned short *,image->colors*sizeof(unsigned short));
+ if (new_indexes == (unsigned short *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToSortImageColormap);
+ /*
+ Assign index values to colormap entries.
+ */
+ for (i=0; i < (long) image->colors; i++)
+ image->colormap[i].opacity=(unsigned short) i;
+ /*
+ Sort image colormap by decreasing intensity.
+ */
+ qsort((void *) image->colormap,image->colors,sizeof(PixelPacket),
+ InverseIntensityCompare);
+ /*
+ Update image colormap indexes to new order.
+ */
+ for (i=0; i < (long) image->colors; i++)
+ new_indexes[image->colormap[i].opacity]=(unsigned short) i;
+ status=PixelIterateMonoModify(SortColormapByIntensityCallBack,NULL,
+ SortColormapByIntensityText,
+ NULL,new_indexes,0,0,image->columns,image->rows,
+ image,&image->exception);
+ MagickFreeMemory(new_indexes);
+ image->is_grayscale=is_grayscale;
+ image->is_monochrome=is_monochrome;
+ return(status);
+}
+
diff --git a/magick/colormap.h b/magick/colormap.h
new file mode 100644
index 0000000..3c289cb
--- /dev/null
+++ b/magick/colormap.h
@@ -0,0 +1,57 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Colormap Methods
+*/
+#ifndef _MAGICK_COLORMAP_H
+#define _MAGICK_COLORMAP_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/image.h"
+#include "magick/error.h"
+
+extern MagickExport MagickPassFail
+ AllocateImageColormap(Image *,const unsigned long),
+ CycleColormapImage(Image *image,const int amount),
+ ReplaceImageColormap(Image *image,const PixelPacket *colormap,
+ const unsigned int colors),
+ SortColormapByIntensity(Image *);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+#define VerifyColormapIndex(image,index) \
+{ \
+ if (index >= image->colors) \
+ index=MagickConstrainColormapIndex(image,index); \
+}
+
+extern MagickExport unsigned int
+ MagickConstrainColormapIndex(Image *image, unsigned int index);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_COLORMAP_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/colorspace.c b/magick/colorspace.c
new file mode 100644
index 0000000..00bcc86
--- /dev/null
+++ b/magick/colorspace.c
@@ -0,0 +1,2028 @@
+/*
+% Copyright (C) 2003 - 2008 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% Methods to transform the image colorspace %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% Bob Friesenhahn %
+% March 2003 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/color.h"
+#include "magick/colorspace.h"
+#include "magick/enum_strings.h"
+#include "magick/gem.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/pixel_iterator.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R G B T r a n s f o r m I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RGBTransformImage converts the reference image from RGB to
+% an alternate colorspace. The transformation matrices are not the standard
+% ones: the weights are rescaled to normalize the range of the transformed
+% values to be [0..MaxRGB].
+%
+% The format of the RGBTransformImage method is:
+%
+% unsigned int RGBTransformImage(Image *image,
+% const ColorspaceType colorspace)
+%
+% A description of each parameter follows:
+%
+% o image: the image
+%
+% o colorspace: the colorspace to transform the image to.
+%
+%
+*/
+
+static MagickPassFail
+RGBToCMYKTransform(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform RGB to CMYK(A) pixels.
+ */
+ register long
+ i;
+
+ Quantum
+ black,
+ cyan,
+ magenta,
+ yellow;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ cyan=(Quantum) (MaxRGB-pixels[i].red);
+ magenta=(Quantum) (MaxRGB-pixels[i].green);
+ yellow=(Quantum) (MaxRGB-pixels[i].blue);
+ black=(cyan < magenta ? Min(cyan,yellow) : Min(magenta,yellow));
+ pixels[i].red=cyan;
+ pixels[i].green=magenta;
+ pixels[i].blue=yellow;
+ indexes[i]=pixels[i].opacity;
+ pixels[i].opacity=black;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+RGBToCineonLogTransform(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform RGB pixels to CineonLog based on an existing lookup
+ table.
+ */
+ const unsigned int
+ *logmap = (const unsigned int *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red = logmap[ScaleQuantumToMap(pixels[i].red)];
+ pixels[i].green = logmap[ScaleQuantumToMap(pixels[i].green)];
+ pixels[i].blue = logmap[ScaleQuantumToMap(pixels[i].blue)];
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+RGBToHSLTransform(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform pixels from RGB space to HSL space.
+ */
+ double
+ h,
+ s,
+ l;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ TransformHSL(pixels[i].red,pixels[i].green,pixels[i].blue,&h,&s,&l);
+ h *= MaxRGB;
+ s *= MaxRGB;
+ l *= MaxRGB;
+ pixels[i].red=RoundDoubleToQuantum(h);
+ pixels[i].green=RoundDoubleToQuantum(s);
+ pixels[i].blue=RoundDoubleToQuantum(l);
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+RGBToHWBTransform(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform pixels from RGB space to HWB space.
+ */
+ double
+ h,
+ w,
+ b;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ TransformHWB(pixels[i].red,pixels[i].green,pixels[i].blue,&h,&w,&b);
+ h *= MaxRGB;
+ w *= MaxRGB;
+ b *= MaxRGB;
+ pixels[i].red=RoundDoubleToQuantum(h);
+ pixels[i].green=RoundDoubleToQuantum(w);
+ pixels[i].blue=RoundDoubleToQuantum(b);
+ }
+
+ return MagickPass;
+}
+
+typedef struct _XYZColorTransformPacket
+{
+ float
+ x,
+ y,
+ z;
+} XYZColorTransformPacket;
+
+typedef struct _XYZColorTransformInfo_t
+{
+ XYZColorTransformPacket *x;
+ XYZColorTransformPacket *y;
+ XYZColorTransformPacket *z;
+ XYZColorTransformPacket primary_info;
+} XYZColorTransformInfo_t;
+
+static const size_t
+ XYZMapAllocSize=(MaxMap+1)*sizeof(XYZColorTransformPacket);
+
+
+static MagickPassFail
+XYZTransformPackets(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ 3D transform pixels from RGB to alternate colorspace.
+ */
+ float
+ b,
+ g,
+ r;
+
+ const XYZColorTransformInfo_t
+ *xform = (const XYZColorTransformInfo_t *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ register unsigned int
+ x_index,
+ y_index,
+ z_index;
+
+ x_index = ScaleQuantumToMap(pixels[i].red);
+ y_index = ScaleQuantumToMap(pixels[i].green);
+ z_index = ScaleQuantumToMap(pixels[i].blue);
+
+ r = (xform->x[x_index].x + xform->y[y_index].x + xform->z[z_index].x + xform->primary_info.x);
+ g = (xform->x[x_index].y + xform->y[y_index].y + xform->z[z_index].y + xform->primary_info.y);
+ b = (xform->x[x_index].z + xform->y[y_index].z + xform->z[z_index].z + xform->primary_info.z);
+
+ r = r < 0.0f ? 0.0f : r > MaxMapFloat ? MaxMapFloat : (r + 0.5f);
+ g = g < 0.0f ? 0.0f : g > MaxMapFloat ? MaxMapFloat : (g + 0.5f);
+ b = b < 0.0f ? 0.0f : b > MaxMapFloat ? MaxMapFloat : (b + 0.5f);
+
+ pixels[i].red = ScaleMapToQuantum((Quantum) r);
+ pixels[i].green = ScaleMapToQuantum((Quantum) g);
+ pixels[i].blue = ScaleMapToQuantum((Quantum) b);
+ }
+
+ return MagickPass;
+}
+
+MagickExport MagickPassFail RGBTransformImage(Image *image,
+ const ColorspaceType colorspace)
+{
+ char
+ progress_message[MaxTextExtent];
+
+ register long
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ /* Detect bogus request to convert to RGB */
+ assert(colorspace != RGBColorspace);
+ assert(colorspace != TransparentColorspace);
+ assert(colorspace != UndefinedColorspace);
+
+ /*
+ Ensure that image is an RGB-compatible colorspace prior to
+ transforming to an alternate colorspace.
+ */
+ if (!IsRGBColorspace(image->colorspace))
+ (void) TransformRGBImage(image,image->colorspace);
+
+ /*
+ Log colorspace transform event
+ */
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Transform colorspace from %s to %s",
+ ColorspaceTypeToString(image->colorspace),
+ ColorspaceTypeToString(colorspace));
+ FormatString(progress_message,"[%%s] Transform colorspace from %s to %s...",
+ ColorspaceTypeToString(image->colorspace),
+ ColorspaceTypeToString(colorspace));
+
+ /*
+ Store colorspace in image.
+ */
+ image->colorspace=colorspace;
+
+ if (colorspace == CMYKColorspace)
+ {
+ /*
+ Transform RGB to CMYK(A) pixels.
+ */
+ if (image->storage_class == PseudoClass)
+ {
+
+ status=SyncImage(image);
+ image->storage_class=DirectClass;
+ }
+ if (status != MagickFail)
+ status=PixelIterateMonoModify(RGBToCMYKTransform,
+ NULL,
+ progress_message,
+ NULL,NULL,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Colorspace transform completed");
+ return(status);
+ }
+
+ if (colorspace == CineonLogRGBColorspace)
+ {
+ /*
+ Transform from linear RGB to Cineon Log RGB.
+ */
+ double
+ DisplayGamma,
+ Gain,
+ MaxLinearValue,
+ NegativeFilmGamma,
+ Offset,
+ ReferenceBlack,
+ ReferenceWhite;
+
+ unsigned int
+ *logmap,
+ scale_to_short;
+
+ /*
+ Establish defaults.
+ */
+ MaxLinearValue=MaxRGB; /* Maximum linear value output */
+ ReferenceWhite=685; /* 90% white card (default 685) */
+ ReferenceBlack=95; /* 1% black card (default 95) */
+ DisplayGamma=1.7; /* Typical display gamma (Kodak recommends 1.7) */
+ NegativeFilmGamma=0.6; /* Typical gamma for a film negative */
+
+ /*
+ Allow image attributes to override defaults.
+ */
+ MagickAttributeToDouble(image,"reference-white",ReferenceWhite);
+ MagickAttributeToDouble(image,"reference-black",ReferenceBlack);
+ MagickAttributeToDouble(image,"display-gamma",DisplayGamma);
+ MagickAttributeToDouble(image,"film-gamma",NegativeFilmGamma);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Log Transform: ReferenceWhite=%g ReferenceBlack=%g DisplayGamma=%g FilmGamma=%g",
+ ReferenceWhite,ReferenceBlack,DisplayGamma,NegativeFilmGamma);
+
+ /*
+ FIXME: Math seems to be producing data with gamma 1.0 rather than 1.7.
+ */
+
+#if 1
+ Gain=MaxLinearValue/(1.0 - pow(pow(10,((ReferenceBlack-ReferenceWhite)
+ *0.002/NegativeFilmGamma)),
+ (DisplayGamma/1.7)));
+#else
+ Gain=MaxLinearValue/(1.0 - pow(pow(10,((ReferenceBlack-ReferenceWhite)
+ *0.002/NegativeFilmGamma)),
+ (1.0/DisplayGamma)));
+#endif
+ Offset=Gain-MaxLinearValue;
+
+ /*
+ Build LUT
+ */
+ logmap=MagickAllocateMemory(unsigned int *,(MaxMap+1)*sizeof(unsigned int));
+ if (logmap == 0)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToTransformColorspace);
+ scale_to_short=(65535U / (65535U >> (16-10)));
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ double
+ linearval,
+ logval;
+
+ linearval=i*(double) MaxRGB/MaxMap;
+
+ /*
+ FIXME: Math seems to be expecting data with gamma 1.0 rather than 1.7.
+ Also, quantizing to 64K levels does not do justice to the Q32 build at all.
+ */
+ logval=685+log10(pow((((double) linearval+Offset)/Gain),
+ (1.7/DisplayGamma)))/(0.002/NegativeFilmGamma);
+
+ /* logval=685+log10(pow((((double) linearval+Offset)/Gain), */
+ /* (DisplayGamma/1.0)))/(0.002/NegativeFilmGamma); */
+
+ logval *= scale_to_short;
+ logmap[i]=ScaleShortToQuantum((unsigned int) (logval + 0.5));
+ /* printf("logmap[%u]=%u\n",i,(unsigned int) logmap[i]); */
+ }
+ /*
+ Transform pixels.
+ */
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Convert PseudoClass image colormap.
+ */
+ (void) RGBToCineonLogTransform(0,
+ logmap,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ /*
+ Convert DirectClass image.
+ */
+ status=PixelIterateMonoModify(RGBToCineonLogTransform,
+ NULL,
+ progress_message,
+ NULL,logmap,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+
+ MagickFreeMemory(logmap);
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Transform to colorspace %s completed",
+ ColorspaceTypeToString(colorspace));
+ return(status);
+ }
+
+
+ if (colorspace == HSLColorspace)
+ {
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Convert PseudoClass image colormap.
+ */
+ RGBToHSLTransform(NULL,
+ NULL,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ /*
+ Convert DirectClass image.
+ */
+ status=PixelIterateMonoModify(RGBToHSLTransform,
+ NULL,
+ progress_message,
+ NULL,NULL,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Colorspace transform completed");
+ return(status);
+ }
+
+ if (colorspace == HWBColorspace)
+ {
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Convert PseudoClass image colormap.
+ */
+ RGBToHWBTransform(NULL,
+ NULL,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(RGBToHWBTransform,
+ NULL,
+ progress_message,
+ NULL,NULL,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Colorspace transform completed");
+ return(status);
+ }
+
+ {
+ /*
+ 3D Transform.
+ */
+
+ XYZColorTransformInfo_t
+ xform;
+
+ /*
+ Allocate the tables.
+ */
+ xform.x=MagickAllocateMemory(XYZColorTransformPacket *,XYZMapAllocSize);
+ xform.y=MagickAllocateMemory(XYZColorTransformPacket *,XYZMapAllocSize);
+ xform.z=MagickAllocateMemory(XYZColorTransformPacket *,XYZMapAllocSize);
+ if ((xform.x == 0) || (xform.y == 0) || (xform.z == 0))
+ {
+ MagickFreeMemory(xform.x);
+ MagickFreeMemory(xform.y);
+ MagickFreeMemory(xform.z);
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToTransformColorspace);
+ }
+ xform.primary_info.x=xform.primary_info.y=xform.primary_info.z=0;
+ switch (colorspace)
+ {
+ case GRAYColorspace:
+ case Rec601LumaColorspace:
+ {
+ /*
+ Initialize Rec. 601 Luma tables:
+
+ G = 0.29900*R+0.58700*G+0.11400*B
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=xform.x[i].y=xform.x[i].z=(0.299f*(float) i);
+ xform.y[i].x=xform.y[i].y=xform.y[i].z=(0.587f*(float) i);
+ xform.z[i].x=xform.z[i].y=xform.z[i].z=(0.114f*(float) i);
+ }
+ break;
+ }
+ case Rec709LumaColorspace:
+ {
+ /*
+ Initialize Rec. 709 Luma tables:
+
+ G = 0.2126*R+0.7152*G+0.0722*B
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=xform.x[i].y=xform.x[i].z=(0.2126f*(float) i);
+ xform.y[i].x=xform.y[i].y=xform.y[i].z=(0.7152f*(float) i);
+ xform.z[i].x=xform.z[i].y=xform.z[i].z=(0.0722f*(float) i);
+ }
+ break;
+ }
+ case OHTAColorspace:
+ {
+ /*
+ Initialize OHTA tables:
+
+ I1 = 0.33333*R+0.33334*G+0.33333*B
+ I2 = 0.50000*R+0.00000*G-0.50000*B
+ I3 =-0.25000*R+0.50000*G-0.25000*B
+
+ I and Q, normally -0.5 through 0.5, are normalized to the range 0
+ through MaxRGB.
+ */
+ xform.primary_info.y=((MaxMap+1)/2);
+ xform.primary_info.z=((MaxMap+1)/2);
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=(0.33333f*(float) i);
+ xform.y[i].x=(0.33334f*(float) i);
+ xform.z[i].x=(0.33333f*(float) i);
+ xform.x[i].y=(0.5f*(float) i);
+ xform.y[i].y=(0.0f);
+ xform.z[i].y=((-0.5f)*(float) i);
+ xform.x[i].z=((-0.25f)*(float) i);
+ xform.y[i].z=(0.5f*(float) i);
+ xform.z[i].z=((-0.25f)*(float) i);
+ }
+ break;
+ }
+ case sRGBColorspace:
+ {
+ /*
+ Kodak PhotoYCC Color Space
+
+ Initialize sRGB tables:
+
+ Y = 0.29900*R+0.58700*G+0.11400*B
+ C1= -0.29900*R-0.58700*G+0.88600*B
+ C2= 0.70100*R-0.58700*G-0.11400*B
+
+ sRGB is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
+ */
+ /* FIXME! The scaling factors for this transform look bizarre,
+ and in fact, the results are not correct. */
+ xform.primary_info.y=(ScaleCharToMap(156));
+ xform.primary_info.z=(ScaleCharToMap(137));
+ for (i=0; i <= (long) (0.018*MaxMap); i++)
+ {
+ xform.x[i].x=(0.003962014134275617*i);
+ xform.y[i].x=(0.007778268551236748*i);
+ xform.z[i].x=(0.001510600706713781*i);
+ xform.x[i].y=((-0.002426619775463276)*i);
+ xform.y[i].y=((-0.004763965913702149)*i);
+ xform.z[i].y=(0.007190585689165425*i);
+ xform.x[i].z=(0.006927257754597858*i);
+ xform.y[i].z=((-0.005800713697502058)*i);
+ xform.z[i].z=((-0.0011265440570958)*i);
+ }
+ for ( ; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=(0.2201118963486454*(1.099*i-0.099));
+ xform.y[i].x=(0.4321260306242638*(1.099*i-0.099));
+ xform.z[i].x=(0.08392226148409894*(1.099*i-0.099));
+ xform.x[i].y=((-0.1348122097479598)*(1.099*i-0.099));
+ xform.y[i].y=((-0.2646647729834528)*(1.099*i-0.099));
+ xform.z[i].y=(0.3994769827314126*(1.099*i-0.099));
+ xform.x[i].z=(0.3848476530332144*(1.099*i-0.099));
+ xform.y[i].z=((-0.3222618720834477)*(1.099*i-0.099));
+ xform.z[i].z=((-0.06258578094976668)*(1.099*i-0.099));
+ }
+ break;
+ }
+ case XYZColorspace:
+ {
+ /*
+ Initialize CIE XYZ tables (from ITU-R 709 RGB):
+
+ X = 0.412453*X+0.357580*Y+0.180423*Z
+ Y = 0.212671*X+0.715160*Y+0.072169*Z
+ Z = 0.019334*X+0.119193*Y+0.950227*Z
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=(0.412453f*(float) i);
+ xform.y[i].x=(0.35758f*(float) i);
+ xform.z[i].x=(0.180423f*(float) i);
+ xform.x[i].y=(0.212671f*(float) i);
+ xform.y[i].y=(0.71516f*(float) i);
+ xform.z[i].y=(0.072169f*(float) i);
+ xform.x[i].z=(0.019334f*(float) i);
+ xform.y[i].z=(0.119193f*(float) i);
+ xform.z[i].z=(0.950227f*(float) i);
+ }
+ break;
+ }
+ case Rec601YCbCrColorspace:
+ {
+ /*
+ Initialize YCbCr tables (using ITU-R BT.601 luma):
+
+ Y = 0.299000*R+0.587000*G+0.114000*B
+ Cb= -0.168736*R-0.331264*G+0.500000*B
+ Cr= 0.500000*R-0.418688*G-0.081312*B
+
+ Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
+ through MaxRGB.
+ */
+ xform.primary_info.y=((MaxMap+1)/2);
+ xform.primary_info.z=((MaxMap+1)/2);
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ /* Red */
+ xform.x[i].x=(0.299f*(float) i);
+ xform.y[i].x=(0.587f*(float) i);
+ xform.z[i].x=(0.114f*(float) i);
+ /* Green */
+ xform.x[i].y=((-0.16873f)*(float) i);
+ xform.y[i].y=((-0.331264f)*(float) i);
+ xform.z[i].y=(0.500000f*(float) i);
+ /* Blue */
+ xform.x[i].z=(0.500000f*(float) i);
+ xform.y[i].z=((-0.418688f)*(float) i);
+ xform.z[i].z=((-0.081312f)*(float) i);
+ }
+ break;
+ }
+ case Rec709YCbCrColorspace:
+ {
+ /*
+ Initialize YCbCr tables (using ITU-R BT.709 luma):
+
+ Y = 0.212600*R+0.715200*G+0.072200*B
+ Cb= -0.114572*R-0.385428*G+0.500000*B
+ Cr= 0.500000*R-0.454153*G-0.045847*B
+
+ Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
+ through MaxRGB.
+ */
+ xform.primary_info.y=((MaxMap+1)/2);
+ xform.primary_info.z=((MaxMap+1)/2);
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ /* Red */
+ xform.x[i].x=(0.212600f*(float) i);
+ xform.y[i].x=(0.715200f*(float) i);
+ xform.z[i].x=(0.072200f*(float) i);
+ /* Green */
+ xform.x[i].y=((-0.114572f)*(float) i);
+ xform.y[i].y=((-0.385428f)*(float) i);
+ xform.z[i].y=(0.500000f*(float) i);
+ /* Blue */
+ xform.x[i].z=(0.500000f*(float) i);
+ xform.y[i].z=((-0.454153f)*(float) i);
+ xform.z[i].z=((-0.045847f)*(float) i);
+ }
+ break;
+ }
+ case YCCColorspace:
+ {
+ /*
+ Kodak PhotoYCC Color Space.
+
+ Initialize YCC tables:
+
+ Y = 0.29900*R+0.58700*G+0.11400*B
+ C1= -0.29900*R-0.58700*G+0.88600*B
+ C2= 0.70100*R-0.58700*G-0.11400*B
+
+ YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
+ */
+ /* FIXME! The scaling factors for this transform look bizarre,
+ and in fact, the results are not correct. */
+ xform.primary_info.y=(ScaleCharToMap(156));
+ xform.primary_info.z=(ScaleCharToMap(137));
+ for (i=0; i <= (long) (0.018*MaxMap); i++)
+ {
+ xform.x[i].x=(0.003962014134275617*i);
+ xform.y[i].x=(0.007778268551236748*i);
+ xform.z[i].x=(0.001510600706713781*i);
+ xform.x[i].y=((-0.002426619775463276)*i);
+ xform.y[i].y=((-0.004763965913702149)*i);
+ xform.z[i].y=(0.007190585689165425*i);
+ xform.x[i].z=(0.006927257754597858*i);
+ xform.y[i].z=((-0.005800713697502058)*i);
+ xform.z[i].z=((-0.0011265440570958)*i);
+ }
+ for ( ; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=(0.2201118963486454*(1.099*i-0.099));
+ xform.y[i].x=(0.4321260306242638*(1.099*i-0.099));
+ xform.z[i].x=(0.08392226148409894*(1.099*i-0.099));
+ xform.x[i].y=((-0.1348122097479598)*(1.099*i-0.099));
+ xform.y[i].y=((-0.2646647729834528)*(1.099*i-0.099));
+ xform.z[i].y=(0.3994769827314126*(1.099*i-0.099));
+ xform.x[i].z=(0.3848476530332144*(1.099*i-0.099));
+ xform.y[i].z=((-0.3222618720834477)*(1.099*i-0.099));
+ xform.z[i].z=((-0.06258578094976668)*(1.099*i-0.099));
+ }
+ break;
+ }
+ case YIQColorspace:
+ {
+ /*
+ Initialize YIQ tables:
+
+ Y = 0.29900*R+0.58700*G+0.11400*B
+ I = 0.59600*R-0.27400*G-0.32200*B
+ Q = 0.21100*R-0.52300*G+0.31200*B
+
+ I and Q, normally -0.5 through 0.5, are normalized to the range 0
+ through MaxRGB.
+ */
+ xform.primary_info.y=((MaxMap+1)/2);
+ xform.primary_info.z=((MaxMap+1)/2);
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=(0.299f*(float) i);
+ xform.y[i].x=(0.587f*(float) i);
+ xform.z[i].x=(0.114f*(float) i);
+ xform.x[i].y=(0.596f*(float) i);
+ xform.y[i].y=((-0.274f)*(float) i);
+ xform.z[i].y=((-0.322f)*(float) i);
+ xform.x[i].z=(0.211f*(float) i);
+ xform.y[i].z=((-0.523f)*(float) i);
+ xform.z[i].z=(0.312f*(float) i);
+ }
+ break;
+ }
+ case YPbPrColorspace:
+ {
+ /*
+ Initialize YPbPr tables (according to ITU-R BT.601):
+
+ Y = 0.299000*R+0.587000*G+0.114000*B
+ Pb= -0.168736*R-0.331264*G+0.500000*B
+ Pr= 0.500000*R-0.418688*G-0.081312*B
+
+ Pb and Pr, normally -0.5 through 0.5, are normalized to the range 0
+ through MaxRGB.
+ */
+ xform.primary_info.y=((MaxMap+1)/2);
+ xform.primary_info.z=((MaxMap+1)/2);
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=(0.299f*(float) i);
+ xform.y[i].x=(0.587f*(float) i);
+ xform.z[i].x=(0.114f*(float) i);
+ xform.x[i].y=((-0.168736f)*(float) i);
+ xform.y[i].y=((-0.331264f)*(float) i);
+ xform.z[i].y=(0.5f*(float) i);
+ xform.x[i].z=(0.5f*(float) i);
+ xform.y[i].z=((-0.418688f)*(float) i);
+ xform.z[i].z=((-0.081312f)*(float) i);
+ }
+ break;
+ }
+ case YUVColorspace:
+ default:
+ {
+ /*
+ Initialize YUV tables:
+
+ Y = 0.29900*R+0.58700*G+0.11400*B
+ U = -0.14740*R-0.28950*G+0.43690*B
+ V = 0.61500*R-0.51500*G-0.10000*B
+
+ U and V, normally -0.5 through 0.5, are normalized to the range 0
+ through MaxRGB. Note that U = 0.493*(B-Y), V = 0.877*(R-Y).
+ */
+ xform.primary_info.y=((MaxMap+1)/2);
+ xform.primary_info.z=((MaxMap+1)/2);
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.x[i].x=(0.299f*(float) i);
+ xform.y[i].x=(0.587f*(float) i);
+ xform.z[i].x=(0.114f*(float) i);
+ xform.x[i].y=((-0.1474f)*(float) i);
+ xform.y[i].y=((-0.2895f)*(float) i);
+ xform.z[i].y=(0.4369f*(float) i);
+ xform.x[i].z=(0.615f*(float) i);
+ xform.y[i].z=((-0.515f)*(float) i);
+ xform.z[i].z=((-0.1f)*(float) i);
+ }
+ break;
+ }
+ }
+
+#if 0
+ /*
+ Dump tables
+ */
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ printf("%5ld: xform.x(%g,%g,%g) xform.y(%g,%g,%g) xform.z(%g,%g,%g)\n",
+ i,
+ ((xform.x[i].x)),
+ ((xform.x[i].y)),
+ ((xform.x[i].z)),
+
+ ((xform.y[i].x)),
+ ((xform.y[i].y)),
+ ((xform.y[i].z)),
+
+ ((xform.z[i].x)),
+ ((xform.z[i].y)),
+ ((xform.z[i].z)));
+ }
+#endif
+
+ /*
+ Convert from RGB.
+ */
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Convert PseudoClass image colormap.
+ */
+ (void) XYZTransformPackets(NULL,
+ &xform,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ /*
+ Convert DirectClass image.
+ */
+ status=PixelIterateMonoModify(XYZTransformPackets,
+ NULL,
+ progress_message,
+ NULL,&xform,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+
+ /*
+ Free allocated memory.
+ */
+ MagickFreeMemory(xform.x);
+ MagickFreeMemory(xform.y);
+ MagickFreeMemory(xform.z);
+ }
+
+ image->is_grayscale=IsGrayColorspace(colorspace);
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Transform to colorspace %s completed",
+ ColorspaceTypeToString(colorspace));
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ T r a n s f o r m C o l o r s p a c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method (void) TransformColorspace converts the image to a specified colorspace.
+% If the image is already in the requested colorspace, no work is performed.
+% Note that the current colorspace is stored in the image colorspace member.
+% The transformation matrices are not necessarily the standard ones: the
+% weights are rescaled to normalize the range of the transformed values to
+% be [0..MaxRGB].
+%
+% The format of the (void) TransformColorspace method is:
+%
+% unsigned int (void) TransformColorspace(Image *image,
+% const ColorspaceType colorspace)
+%
+% A description of each parameter follows:
+%
+% o image: the image to transform
+%
+% o colorspace: the desired colorspace.
+%
+*/
+MagickExport MagickPassFail TransformColorspace(Image *image,
+ const ColorspaceType colorspace)
+{
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(colorspace != UndefinedColorspace);
+ assert(image->colorspace != UndefinedColorspace);
+ /*
+ If the image colorspace is the same as requested, do nothing.
+ */
+ if (image->colorspace == colorspace)
+ return (status);
+
+ /*
+ If the requested colorspace is RGB or Transparent, then convert
+ via TransformRGBImage.
+ */
+ if ((colorspace == RGBColorspace) ||
+ (colorspace == TransparentColorspace))
+ {
+ status &= TransformRGBImage(image,image->colorspace);
+ image->colorspace=colorspace;
+ return (status);
+ }
+
+ /*
+ If the image is not already in an RGB-compatible colorspace, then
+ convert it to RGB via TransformRGBImage, and then to the target
+ colorspace via RGBTransformImage, otherwise just convert to the
+ target colorspace via RGBTransformImage.
+ */
+ if (!IsRGBColorspace(image->colorspace))
+ status=TransformRGBImage(image,image->colorspace);
+
+ status &= RGBTransformImage(image,colorspace);
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ T r a n s f o r m R G B I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method TransformRGBImage converts the reference image from an alternate
+% colorspace to RGB. The transformation matrices are not the standard ones:
+% the weights are rescaled to normalize the range of the transformed values
+% to be [0..MaxRGB].
+%
+% The format of the TransformRGBImage method is:
+%
+% unsigned int TransformRGBImage(Image *image,
+% const ColorspaceType colorspace)
+%
+% A description of each parameter follows:
+%
+% o image: the image
+%
+% o colorspace: the colorspace to transform the image to.
+%
+*/
+static MagickPassFail
+CMYKToRGBTransform(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform CMYK(A) pixels to RGB.
+ */
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ black_factor;
+
+ black_factor=MaxRGBDouble-GetBlackSample(&pixels[i]);
+ SetRedSample(&pixels[i],
+ (Quantum) (((MaxRGBDouble-GetCyanSample(&pixels[i]))*
+ black_factor)/MaxRGBDouble+0.5));
+ SetGreenSample(&pixels[i],
+ (Quantum) (((MaxRGBDouble-GetMagentaSample(&pixels[i]))*
+ black_factor)/MaxRGBDouble+0.5));
+ SetBlueSample(&pixels[i],
+ (Quantum) (((MaxRGBDouble-GetYellowSample(&pixels[i]))*
+ black_factor)/ MaxRGBDouble+0.5));
+ SetOpacitySample(&pixels[i],(image->matte ? indexes[i] : OpaqueOpacity));
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+CineonLogToRGBTransform(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform CineonLog pixels to RGB based on an existing lookup
+ table.
+ */
+ const Quantum
+ *linearmap = (const Quantum *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red = linearmap[ScaleQuantumToShort(pixels[i].red)/64U];
+ pixels[i].green = linearmap[ScaleQuantumToShort(pixels[i].green)/64U];
+ pixels[i].blue = linearmap[ScaleQuantumToShort(pixels[i].blue)/64U];
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+HSLToRGBTransform(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform pixels from HSL space to RGB space.
+ */
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ HSLTransform((double) pixels[i].red/MaxRGB,(double) pixels[i].green/MaxRGB,
+ (double) pixels[i].blue/MaxRGB,&pixels[i].red,&pixels[i].green,&pixels[i].blue);
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+HWBToRGBTransform(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Transform pixels from HWB space to RGB space.
+ */
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ HWBTransform((double) pixels[i].red/MaxRGB,(double) pixels[i].green/MaxRGB,
+ (double) pixels[i].blue/MaxRGB,&pixels[i].red,&pixels[i].green,&pixels[i].blue);
+ }
+
+ return MagickPass;
+}
+
+typedef struct _RGBColorTransformPacket
+{
+ float
+ r,
+ g,
+ b;
+} RGBColorTransformPacket;
+
+typedef struct _RGBTransformInfo_t
+{
+ RGBColorTransformPacket *r;
+ RGBColorTransformPacket *g;
+ RGBColorTransformPacket *b;
+ const unsigned char *rgb_map;
+ unsigned int rgb_map_max_index;
+} RGBTransformInfo_t;
+
+static MagickPassFail
+RGBTransformPackets(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ 3D transform pixels to RGB.
+ */
+ float
+ b,
+ g,
+ r;
+
+ const RGBTransformInfo_t
+ *xform = (const RGBTransformInfo_t *) immutable_data;
+
+ register long
+ i;
+
+ unsigned int
+ r_index,
+ g_index,
+ b_index;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ r_index = ScaleQuantumToMap(pixels[i].red);
+ g_index = ScaleQuantumToMap(pixels[i].green);
+ b_index = ScaleQuantumToMap(pixels[i].blue);
+
+ r = (xform->r[r_index].r + xform->g[g_index].r + xform->b[b_index].r);
+ g = (xform->r[r_index].g + xform->g[g_index].g + xform->b[b_index].g);
+ b = (xform->r[r_index].b + xform->g[g_index].b + xform->b[b_index].b);
+
+ r = r < 0.0f ? 0.0f : r > MaxMapFloat ? MaxMapFloat : (r + 0.5f);
+ g = g < 0.0f ? 0.0f : g > MaxMapFloat ? MaxMapFloat : (g + 0.5f);
+ b = b < 0.0f ? 0.0f : b > MaxMapFloat ? MaxMapFloat : (b + 0.5f);
+
+ if ( xform->rgb_map != 0 )
+ {
+ r_index = ScaleMapToChar(r);
+ g_index = ScaleMapToChar(g);
+ b_index = ScaleMapToChar(b);
+
+ if (r_index > xform->rgb_map_max_index) r_index = xform->rgb_map_max_index;
+ if (g_index > xform->rgb_map_max_index) g_index = xform->rgb_map_max_index;
+ if (b_index > xform->rgb_map_max_index) b_index = xform->rgb_map_max_index;
+
+ pixels[i].red = ScaleCharToQuantum(xform->rgb_map[r_index]);
+ pixels[i].green = ScaleCharToQuantum(xform->rgb_map[g_index]);
+ pixels[i].blue = ScaleCharToQuantum(xform->rgb_map[b_index]);
+ }
+ else
+ {
+ pixels[i].red = ScaleMapToQuantum(r);
+ pixels[i].green = ScaleMapToQuantum(g);
+ pixels[i].blue = ScaleMapToQuantum(b);
+ }
+ }
+
+ return MagickPass;
+}
+
+MagickExport MagickPassFail TransformRGBImage(Image *image,
+ const ColorspaceType colorspace)
+{
+ static const unsigned char
+ sRGBMap[351] =
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99,
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 130, 131, 132, 133, 135, 136, 137, 138, 139, 140,
+ 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
+ 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
+ 167, 168, 169, 170, 171, 172, 173, 174, 175, 175, 176, 177, 178,
+ 179, 180, 181, 182, 183, 184, 185, 186, 187, 187, 188, 189, 190,
+ 191, 192, 193, 194, 194, 195, 196, 197, 198, 199, 199, 200, 201,
+ 202, 203, 203, 204, 205, 206, 207, 207, 208, 209, 210, 210, 211,
+ 212, 213, 213, 214, 215, 215, 216, 217, 218, 218, 219, 220, 220,
+ 221, 222, 222, 223, 223, 224, 225, 225, 226, 227, 227, 228, 228,
+ 229, 229, 230, 230, 231, 232, 232, 233, 233, 234, 234, 235, 235,
+ 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, 240,
+ 241, 241, 242, 242, 242, 243, 243, 243, 243, 244, 244, 244, 245,
+ 245, 245, 245, 246, 246, 246, 247, 247, 247, 247, 247, 248, 248,
+ 248, 248, 249, 249, 249, 249, 249, 249, 250, 250, 250, 250, 250,
+ 250, 251, 251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252,
+ 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 253, 253, 254,
+ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255,
+ 255, 255, 255, 255, 255
+ };
+
+ static const unsigned char
+ YCCMap[351] = /* Photo CD information beyond 100% white, Gamma 2.2 */
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125, 126, 127, 129, 130, 131, 132,
+ 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
+ 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
+ 172, 173, 174, 175, 176, 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 193, 194, 195,
+ 196, 197, 198, 199, 200, 201, 201, 202, 203, 204, 205, 206, 207,
+ 207, 208, 209, 210, 211, 211, 212, 213, 214, 215, 215, 216, 217,
+ 218, 218, 219, 220, 221, 221, 222, 223, 224, 224, 225, 226, 226,
+ 227, 228, 228, 229, 230, 230, 231, 232, 232, 233, 234, 234, 235,
+ 236, 236, 237, 237, 238, 238, 239, 240, 240, 241, 241, 242, 242,
+ 243, 243, 244, 244, 245, 245, 245, 246, 246, 247, 247, 247, 248,
+ 248, 248, 249, 249, 249, 249, 250, 250, 250, 250, 251, 251, 251,
+ 251, 251, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253,
+ 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254,
+ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255
+ };
+
+ char
+ progress_message[MaxTextExtent];
+
+ register long
+ i;
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->colorspace != UndefinedColorspace);
+
+ is_grayscale=((image->is_grayscale) || IsGrayColorspace(image->colorspace));
+
+ /*
+ If colorspace is already an RGB type then simply return.
+ */
+ if (IsRGBColorspace(image->colorspace))
+ return(status);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Transform colorspace from %s to RGB",
+ ColorspaceTypeToString(image->colorspace));
+
+ FormatString(progress_message,"[%%s] Transform colorspace from %s to RGB...",
+ ColorspaceTypeToString(image->colorspace));
+
+ if (image->colorspace == CMYKColorspace)
+ {
+ if (image->storage_class == PseudoClass)
+ {
+ status=SyncImage(image);
+ image->storage_class=DirectClass;
+ }
+ if (status != MagickFail)
+ status=PixelIterateMonoModify(CMYKToRGBTransform,
+ NULL,
+ progress_message,
+ NULL,NULL,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ image->colorspace=RGBColorspace;
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Colorspace transform completed");
+ return(status);
+ }
+
+ if (colorspace == CineonLogRGBColorspace)
+ {
+ /*
+ Transform from Cineon Log RGB to Linear RGB
+ */
+ double
+ BreakPoint,
+ DisplayGamma,
+ Gain,
+ KneeGain,
+ KneeOffset,
+ MaxLinearValue,
+ NegativeFilmGamma,
+ Offset,
+ ReferenceBlack,
+ ReferenceWhite,
+ SoftClip;
+
+ Quantum
+ *linearmap;
+
+ /*
+ Establish defaults.
+ */
+ MaxLinearValue=MaxRGB; /* Maximum linear value output */
+ ReferenceWhite=685.0; /* 90% white card (default 685) */
+ ReferenceBlack=95.0; /* 1% black card (default 95) */
+ DisplayGamma=1.7; /* Typical display gamma (Kodak recommended 1.7) */
+ NegativeFilmGamma=0.6; /* Typical gamma for a film negative */
+ SoftClip=0.0; /* Soft clip offset */
+
+ /*
+ Allow image attributes to override defaults.
+ */
+ MagickAttributeToDouble(image,"reference-white",ReferenceWhite);
+ MagickAttributeToDouble(image,"reference-black",ReferenceBlack);
+ MagickAttributeToDouble(image,"display-gamma",DisplayGamma);
+ MagickAttributeToDouble(image,"film-gamma",NegativeFilmGamma);
+ MagickAttributeToDouble(image,"soft-clip-offset",SoftClip);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Log Transform: ReferenceWhite=%g ReferenceBlack=%g DisplayGamma=%g FilmGamma=%g SoftClip=%g",
+ ReferenceWhite,ReferenceBlack,DisplayGamma,NegativeFilmGamma,SoftClip);
+
+ BreakPoint=ReferenceWhite-SoftClip;
+ Gain=MaxLinearValue/(1.0 - pow(pow(10,((ReferenceBlack-ReferenceWhite)
+ *0.002/NegativeFilmGamma)),
+ (DisplayGamma/1.7)));
+ Offset=Gain-MaxLinearValue;
+ KneeOffset=pow(pow(10,((BreakPoint-ReferenceWhite)*0.002/NegativeFilmGamma)),
+ (DisplayGamma/1.7))*Gain-Offset;
+ KneeGain=(MaxLinearValue-KneeOffset)/pow((5*SoftClip),(SoftClip/100));
+
+
+ linearmap=MagickAllocateMemory(Quantum *,1024*sizeof(Quantum));
+ if (linearmap == 0)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToTransformColorspace);
+
+ for (i=0; i < 1023; i++)
+ {
+ double
+ linearval,
+ logval;
+
+ logval=i;
+ if (logval < ReferenceBlack)
+ {
+ /* Values below reference black are clipped to zero */
+ linearval=0.0;
+ }
+ else if (logval > BreakPoint)
+ {
+ /* Values above the breakpoint are soft-clipped. */
+ linearval=pow((logval-BreakPoint),(SoftClip/100))*KneeGain+KneeOffset;
+ }
+ else
+ {
+ /* Otherwise, normal values */
+ linearval=pow(pow(10,((logval-ReferenceWhite)*0.002/NegativeFilmGamma)),
+ (DisplayGamma/1.7))*Gain-Offset;
+ }
+
+ linearmap[i]=(unsigned int) (linearval + 0.5);
+ }
+ /*
+ Transform pixels.
+ */
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Convert PseudoClass image colormap.
+ */
+ CineonLogToRGBTransform(NULL,
+ linearmap,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ /*
+ Convert DirectClass image.
+ */
+ status=PixelIterateMonoModify(CineonLogToRGBTransform,
+ NULL,
+ progress_message,
+ NULL,linearmap,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ MagickFreeMemory(linearmap);
+ image->colorspace=RGBColorspace;
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Transform to colorspace %s completed",
+ ColorspaceTypeToString(colorspace));
+ return(status);
+ }
+
+ if (image->colorspace == HSLColorspace)
+ {
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Convert PseudoClass image colormap.
+ */
+ HSLToRGBTransform(NULL,
+ NULL,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(HSLToRGBTransform,
+ NULL,
+ progress_message,
+ NULL,NULL,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ image->colorspace=RGBColorspace;
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Colorspace transform completed");
+ return(status);
+ }
+
+ if (image->colorspace == HWBColorspace)
+ {
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Convert PseudoClass image colormap.
+ */
+ HWBToRGBTransform(NULL,
+ NULL,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(HWBToRGBTransform,
+ NULL,
+ progress_message,
+ NULL,NULL,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ image->colorspace=RGBColorspace;
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Colorspace transform completed");
+ return(status);
+ }
+
+ {
+ /*
+ 3D Transform.
+ */
+
+ RGBTransformInfo_t
+ xform;
+
+ /*
+ Allocate the tables.
+ */
+ xform.rgb_map = (const unsigned char *) NULL;
+ xform.rgb_map_max_index = 0;
+ xform.r=MagickAllocateMemory(RGBColorTransformPacket *,
+ (MaxMap+1)*sizeof(RGBColorTransformPacket));
+ xform.g=MagickAllocateMemory(RGBColorTransformPacket *,
+ (MaxMap+1)*sizeof(RGBColorTransformPacket));
+ xform.b=MagickAllocateMemory(RGBColorTransformPacket *,
+ (MaxMap+1)*sizeof(RGBColorTransformPacket));
+ if ((xform.r == (RGBColorTransformPacket *) NULL) ||
+ (xform.g == (RGBColorTransformPacket *) NULL) ||
+ (xform.b == (RGBColorTransformPacket *) NULL))
+ {
+ MagickFreeMemory(xform.r);
+ MagickFreeMemory(xform.g);
+ MagickFreeMemory(xform.b);
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToTransformColorspace);
+ }
+
+ switch (image->colorspace)
+ {
+ case OHTAColorspace:
+ {
+ /*
+ Initialize OHTA tables:
+
+ R = I1+1.00000*I2-0.66668*I3
+ G = I1+0.00000*I2+1.33333*I3
+ B = I1-1.00000*I2-0.66668*I3
+
+ I and Q, normally -0.5 through 0.5, must be normalized to the range 0
+ through MaxMap.
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.r[i].r=((float) i);
+ xform.g[i].r=(0.5f*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].r=((-0.33334f)*(2.0f*(float) i-MaxMapFloat));
+ xform.r[i].g=((float) i);
+ xform.g[i].g=(0.0f);
+ xform.b[i].g=(0.666665f*(2.0f*(float) i-MaxMapFloat));
+ xform.r[i].b=((float) i);
+ xform.g[i].b=((-0.5f)*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].b=((-0.33334f)*(2.0f*(float) i-MaxMapFloat));
+ }
+ break;
+ }
+ case sRGBColorspace:
+ {
+ /*
+ Initialize sRGB tables:
+
+ R = Y +1.032096*C2
+ G = Y-0.326904*C1-0.704445*C2
+ B = Y+1.685070*C1
+
+ sRGB is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
+ */
+ xform.rgb_map=sRGBMap;
+ xform.rgb_map_max_index=350;
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.r[i].r=(1.40200f*(float) i);
+ xform.g[i].r=(0.0f);
+ xform.b[i].r=(1.88000f*((float) i-ScaleCharToMap(137)));
+ xform.r[i].g=(1.40200f*(float) i);
+ xform.g[i].g=((-0.444066f)*((float) i-ScaleCharToMap(156)));
+ xform.b[i].g=((-0.95692f)*((float) i-ScaleCharToMap(137)));
+ xform.r[i].b=(1.40200f*(float) i);
+ xform.g[i].b=(2.28900f*((float) i-ScaleCharToMap(156)));
+ xform.b[i].b=(0.0f);
+ }
+ break;
+ }
+ case XYZColorspace:
+ {
+ /*
+ Initialize CIE XYZ tables (to ITU R-709 RGB):
+
+ R = 3.240479*R-1.537150*G-0.498535*B
+ G = -0.969256*R+1.875992*G+0.041556*B
+ B = 0.055648*R-0.204043*G+1.057311*B
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.r[i].r=(3.240479f*(float) i);
+ xform.g[i].r=((-1.537150f)*(float) i);
+ xform.b[i].r=((-0.498535f)*(float) i);
+ xform.r[i].g=((-0.969256f)*(float) i);
+ xform.g[i].g=(1.875992f*(float) i);
+ xform.b[i].g=(0.041556f*(float) i);
+ xform.r[i].b=(0.055648f*(float) i);
+ xform.g[i].b=((-0.204043f)*(float) i);
+ xform.b[i].b=(1.057311f*(float) i);
+ }
+ break;
+ }
+ case Rec601YCbCrColorspace:
+ {
+ /*
+ Y'CbCr based on ITU-R 601 Luma
+
+ Initialize Y'CbCr tables:
+
+ R' = Y' +1.402000*Cr
+ G' = Y'-0.344136*Cb-0.714136*Cr
+ B' = Y'+1.772000*Cb
+
+ Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
+ through MaxMap.
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ /* Y */
+ xform.r[i].r=((float) i);
+ xform.g[i].r=(0.0f);
+ xform.b[i].r=((1.402000f*0.5f)*(2.0f*(float) i-MaxMapFloat));
+ /* Pb */
+ xform.r[i].g=((float) i);
+ xform.g[i].g=((-0.344136f*0.5f)*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].g=((-0.714136f*0.5f)*(2.0f*(float) i-MaxMapFloat));
+ /* Pr */
+ xform.r[i].b=((float) i);
+ xform.g[i].b=((1.772000f*0.5f)*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].b=(0.0f);
+ }
+ break;
+ }
+ case Rec709YCbCrColorspace:
+ {
+ /*
+ Y'CbCr based on ITU-R 709 Luma.
+
+ R' = Y' +1.574800*Cr
+ G' = Y'-0.187324*Cb-0.468124*Cr
+ B' = Y'+1.855600*Cb
+
+ Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
+ through MaxMap.
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ /* Y */
+ xform.r[i].r=((float) i);
+ xform.g[i].r=(0.0f);
+ xform.b[i].r=((1.5748f*0.5f)*(2.0f*(float) i-MaxMapFloat));
+ /* Pb */
+ xform.r[i].g=((float) i);
+ xform.g[i].g=((-0.187324f*0.5f)*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].g=((-0.468124f*0.5f)*(2.0f*(float) i-MaxMapFloat));
+ /* Pr */
+ xform.r[i].b=((float) i);
+ xform.g[i].b=((1.8556f*0.5f)*(2.0f*(float) i- MaxMapFloat));
+ xform.b[i].b=(0.0f);
+ }
+ break;
+ }
+ case YCCColorspace:
+ {
+ /*
+ Kodak PhotoYCC Color Space.
+
+ Initialize YCC tables:
+
+ R = Y +1.340762*C2
+ G = Y-0.317038*C1-0.682243*C2
+ B = Y+1.632639*C1
+
+ YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
+ */
+ xform.rgb_map=YCCMap;
+ xform.rgb_map_max_index=350;
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.r[i].r=(1.3584f*(float) i);
+ xform.g[i].r=(0.0f);
+ xform.b[i].r=(1.8215f*((float) i-ScaleCharToMap(137)));
+ xform.r[i].g=(1.3584f*(float) i);
+ xform.g[i].g=((-0.4302726f)*((float) i-ScaleCharToMap(156)));
+ xform.b[i].g=((-0.9271435f)*((float) i-ScaleCharToMap(137)));
+ xform.r[i].b=(1.3584f*i);
+ xform.g[i].b=(2.2179f*((float) i-ScaleCharToMap(156)));
+ xform.b[i].b=(0.0f);
+ }
+ break;
+ }
+ case YIQColorspace:
+ {
+ /*
+ Initialize YIQ tables:
+
+ R = Y+0.95620*I+0.62140*Q
+ G = Y-0.27270*I-0.64680*Q
+ B = Y-1.10370*I+1.70060*Q
+
+ I and Q, normally -0.5 through 0.5, must be normalized to the range 0
+ through MaxMap.
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.r[i].r=((float) i);
+ xform.g[i].r=(0.4781f*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].r=(0.3107f*(2.0f*(float) i-MaxMapFloat));
+ xform.r[i].g=((float) i);
+ xform.g[i].g=((-0.13635f)*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].g=((-0.3234f)*(2.0f*(float) i-MaxMapFloat));
+ xform.r[i].b=((float) i);
+ xform.g[i].b=((-0.55185f)*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].b=(0.8503f*(2.0f*(float) i-MaxMapFloat));
+ }
+ break;
+ }
+ case YPbPrColorspace:
+ {
+ /*
+ Initialize Y'PbPr tables using ITU-R 601 luma:
+
+ R = Y +1.402000*C2
+ G = Y-0.344136*C1+0.714136*C2
+ B = Y+1.772000*C1
+
+ Pb and Pr, normally -0.5 through 0.5, must be normalized to the range 0
+ through MaxMap.
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.r[i].r=((float) i);
+ xform.g[i].r=(0.0f);
+ xform.b[i].r=(0.701f*(2.0f*(float) i-MaxMapFloat));
+ xform.r[i].g=((float) i);
+ xform.g[i].g=((-0.172068f)*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].g=(0.357068f*(2.0f*(float) i-MaxMapFloat));
+ xform.r[i].b=((float) i);
+ xform.g[i].b=(0.886f*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].b=(0.0f);
+ }
+ break;
+ }
+ case YUVColorspace:
+ default:
+ {
+ /*
+ Initialize YUV tables:
+
+ R = Y +1.13980*V
+ G = Y-0.39380*U-0.58050*V
+ B = Y+2.02790*U
+
+ U and V, normally -0.5 through 0.5, must be normalized to the range 0
+ through MaxMap.
+ */
+#if MaxMap > 255
+# if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,64)
+# endif
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ xform.r[i].r=((float) i);
+ xform.g[i].r=(0.0f);
+ xform.b[i].r=(0.5699f*(2.0f*(float) i-MaxMapFloat));
+ xform.r[i].g=((float) i);
+ xform.g[i].g=((-0.1969f)*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].g=((-0.29025f)*(2.0f*(float) i-MaxMapFloat));
+ xform.r[i].b=((float) i);
+ xform.g[i].b=(1.01395f*(2.0f*(float) i-MaxMapFloat));
+ xform.b[i].b=(0.0f);
+ }
+ break;
+ }
+ }
+
+#if 0
+ /*
+ Dump tables
+ */
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ printf("%5ld: xform.r(%g,%g,%g) xform.g(%g,%g,%g) xform.b(%g,%g,%g)\n",
+ i,
+ ((xform.r[i].r)),
+ ((xform.r[i].g)),
+ ((xform.r[i].b)),
+
+ ((xform.g[i].r)),
+ ((xform.g[i].g)),
+ ((xform.g[i].b)),
+
+ ((xform.b[i].r)),
+ ((xform.b[i].g)),
+ ((xform.b[i].b)));
+ }
+#endif
+
+ /*
+ Convert to RGB.
+ */
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Convert PseudoClass image colormap.
+ */
+ (void) RGBTransformPackets(NULL,
+ &xform,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ /*
+ Convert DirectClass image.
+ */
+ status=PixelIterateMonoModify(RGBTransformPackets,
+ NULL,
+ progress_message,
+ NULL,&xform,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+
+
+ /*
+ Free allocated memory.
+ */
+ MagickFreeMemory(xform.b);
+ MagickFreeMemory(xform.g);
+ MagickFreeMemory(xform.r);
+ }
+ image->is_grayscale=is_grayscale;
+ image->colorspace=RGBColorspace;
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Colorspace transform completed");
+ return(status);
+}
diff --git a/magick/colorspace.h b/magick/colorspace.h
new file mode 100644
index 0000000..f14d1ec
--- /dev/null
+++ b/magick/colorspace.h
@@ -0,0 +1,129 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Colorspace Methods.
+*/
+#ifndef _MAGICK_COLORSPACE_H
+#define _MAGICK_COLORSPACE_H
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+#if (QuantumDepth == 8) || (QuantumDepth == 16)
+ /*
+ intensity=0.299*red+0.587*green+0.114*blue.
+ Premultiply by 1024 to obtain integral values, and then divide
+ result by 1024 by shifting to the right by 10 bits.
+ */
+#define PixelIntensityRec601(pixel) \
+ ((unsigned int) \
+ (((unsigned int) (pixel)->red*306U+ \
+ (unsigned int) (pixel)->green*601U+ \
+ (unsigned int) (pixel)->blue*117U) \
+ >> 10U))
+#elif (QuantumDepth == 32)
+ /*
+ intensity=0.299*red+0.587*green+0.114*blue.
+ */
+#define PixelIntensityRec601(pixel) \
+ ((unsigned int) \
+ (((double)306.0*(pixel)->red+ \
+ (double)601.0*(pixel)->green+ \
+ (double)117.0*(pixel)->blue) \
+ / 1024.0))
+#endif
+
+ /*
+ intensity=0.2126*red+0.7152*green+0.0722*blue
+ */
+#define PixelIntensityRec709(pixel) \
+ ((unsigned int) \
+ (0.2126*(pixel)->red+ \
+ 0.7152*(pixel)->green+ \
+ 0.0722*(pixel)->blue))
+
+#define PixelIntensity(pixel) PixelIntensityRec601(pixel)
+#define PixelIntensityToDouble(pixel) ((double)PixelIntensity(pixel))
+#define PixelIntensityToQuantum(pixel) ((Quantum)PixelIntensity(pixel))
+#define IsCMYKColorspace(colorspace) \
+ ( \
+ (colorspace == CMYKColorspace) \
+ )
+#define IsGrayColorspace(colorspace) \
+ ( \
+ (colorspace == GRAYColorspace) || \
+ (colorspace == Rec601LumaColorspace) || \
+ (colorspace == Rec709LumaColorspace) \
+ )
+#define IsRGBColorspace(colorspace) \
+ ( \
+ (IsGrayColorspace(colorspace)) || \
+ (colorspace == RGBColorspace) || \
+ (colorspace == TransparentColorspace) \
+ )
+#define IsLABColorspace(colorspace) \
+ ( \
+ (colorspace == LABColorspace) \
+ )
+#define IsRGBCompatibleColorspace(colorspace) \
+ ( \
+ (IsRGBColorspace(colorspace)) || \
+ (colorspace == CineonLogRGBColorspace ) \
+ )
+#define IsYCbCrColorspace(colorspace) \
+ ( \
+ (colorspace == YCbCrColorspace) || \
+ (colorspace == Rec601YCbCrColorspace) || \
+ (colorspace == Rec709YCbCrColorspace) \
+ )
+
+#define YCbCrColorspace Rec601YCbCrColorspace
+typedef enum
+{
+ UndefinedColorspace,
+ RGBColorspace, /* Plain old RGB colorspace */
+ GRAYColorspace, /* Plain old full-range grayscale */
+ TransparentColorspace, /* RGB but preserve matte channel during quantize */
+ OHTAColorspace,
+ XYZColorspace, /* CIE XYZ */
+ YCCColorspace, /* Kodak PhotoCD PhotoYCC */
+ YIQColorspace,
+ YPbPrColorspace,
+ YUVColorspace,
+ CMYKColorspace, /* Cyan, magenta, yellow, black, alpha */
+ sRGBColorspace, /* Kodak PhotoCD sRGB */
+ HSLColorspace, /* Hue, saturation, luminosity */
+ HWBColorspace, /* Hue, whiteness, blackness */
+ LABColorspace, /* LAB colorspace not supported yet other than via lcms */
+ CineonLogRGBColorspace,/* RGB data with Cineon Log scaling, 2.048 density range */
+ Rec601LumaColorspace, /* Luma (Y) according to ITU-R 601 */
+ Rec601YCbCrColorspace, /* YCbCr according to ITU-R 601 */
+ Rec709LumaColorspace, /* Luma (Y) according to ITU-R 709 */
+ Rec709YCbCrColorspace /* YCbCr according to ITU-R 709 */
+} ColorspaceType;
+
+extern MagickExport MagickPassFail
+ RGBTransformImage(ImagePtr,const ColorspaceType),
+ TransformColorspace(ImagePtr,const ColorspaceType),
+ TransformRGBImage(ImagePtr,const ColorspaceType);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_COLORSPACE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/command.c b/magick/command.c
new file mode 100644
index 0000000..ca8b6b2
--- /dev/null
+++ b/magick/command.c
@@ -0,0 +1,17456 @@
+/*
+% Copyright (C) 2003 - 2017 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC OOO M M M M AAA N N DDDD %
+% C O O MM MM MM MM A A NN N D D %
+% C O O M M M M M M AAAAA N N N D D %
+% C O O M M M M A A N NN D D %
+% CCCC OOO M M M M A A N N DDDD %
+% %
+% %
+% Image Command Methods %
+% %
+% Software Design %
+% John Cristy %
+% Bill Radcliffe %
+% July 2002 %
+% Bob Friesenhahn %
+% 2003-2008 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/average.h"
+#include "magick/cdl.h"
+#include "magick/channel.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/confirm_access.h"
+#include "magick/constitute.h"
+#include "magick/command.h"
+#include "magick/compare.h"
+#include "magick/composite.h"
+#include "magick/decorate.h"
+#include "magick/delegate.h"
+#include "magick/describe.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/enum_strings.h"
+#include "magick/fx.h"
+#include "magick/gem.h"
+#include "magick/hclut.h"
+#include "magick/log.h"
+#include "magick/magic.h"
+#include "magick/magick.h"
+#include "magick/map.h"
+#include "magick/module.h"
+#include "magick/monitor.h"
+#include "magick/montage.h"
+#include "magick/operator.h"
+#include "magick/paint.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/quantize.h"
+#include "magick/registry.h"
+#include "magick/render.h"
+#include "magick/resize.h"
+#include "magick/resource.h"
+#include "magick/shear.h"
+#include "magick/semaphore.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#include "magick/xwindow.h"
+
+/*
+ Typedef declarations.
+*/
+typedef enum
+{
+ SingleMode = 0x01,
+ BatchMode = 0x02
+} RunMode;
+
+typedef enum
+{
+ OptionSuccess = 0,
+ OptionHelp = -1,
+ OptionUnknown = -2,
+ OptionMissingValue = -3,
+ OptionInvalidValue = -4
+} OptionStatus;
+
+typedef struct _CompositeOptions
+{
+ char
+ *displace_geometry,
+ *geometry,
+ *unsharp_geometry,
+ *watermark_geometry;
+
+ CompositeOperator
+ compose;
+
+ GravityType
+ gravity;
+
+ double
+ dissolve;
+
+ long
+ stegano;
+
+ unsigned int
+ stereo,
+ tile;
+} CompositeOptions;
+
+typedef int (*CommandLineParser)(FILE *in, int acmax, char **av);
+
+#define SIZE_OPTION_VALUE 256
+typedef struct _BatchOptions {
+ MagickBool stop_on_error,
+ is_feedback_enabled,
+ is_echo_enabled;
+ char prompt[SIZE_OPTION_VALUE],
+ pass[SIZE_OPTION_VALUE],
+ fail[SIZE_OPTION_VALUE];
+ CommandLineParser command_line_parser;
+} BatchOptions;
+
+typedef MagickPassFail (*CommandVectorHandler)(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception);
+
+typedef void (*UsageVectorHandler)(void);
+
+typedef struct _CommandInfo
+{
+ const char *command;
+ const char *description;
+ CommandVectorHandler command_vector;
+ UsageVectorHandler usage_vector;
+ int pass_metadata;
+ RunMode support_mode;
+} CommandInfo;
+
+static void InitializeBatchOptions(MagickBool);
+static MagickBool GMCommandSingle(int argc, char **argv);
+static int ProcessBatchOptions(int argc, char **argv, BatchOptions *options);
+static int ParseUnixCommandLine(FILE *in, int acmax, char **av);
+static int ParseWindowsCommandLine(FILE *in, int acmax, char **av);
+
+static void
+#if defined(HasX11)
+ AnimateUsage(void),
+#endif /* HasX11 */
+ BatchUsage(void),
+ BenchmarkUsage(void),
+ CompositeUsage(void),
+ CompareUsage(void),
+ ConjureUsage(void),
+ ConvertUsage(void),
+#if defined(HasX11)
+ DisplayUsage(void),
+#endif /* HasX11 */
+ GMUsage(void),
+ IdentifyUsage(void),
+#if defined(HasX11)
+ ImportUsage(void),
+#endif /* HasX11 */
+ LiberateArgumentList(const int argc,char **argv),
+ MogrifyUsage(void),
+ MontageUsage(void),
+ SetUsage(void),
+ TimeUsage(void);
+
+static MagickPassFail
+ HelpCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+#if defined(MSWINDOWS)
+ RegisterCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+#endif
+ SetCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ VersionCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception);
+
+static const CommandInfo commands[] =
+ {
+#if defined(HasX11)
+ { "animate", "animate a sequence of images",
+ AnimateImageCommand, AnimateUsage, 0, SingleMode | BatchMode },
+#endif
+ { "batch", "issue multiple commands in interactive or batch mode",
+ 0, BatchUsage, 1, SingleMode },
+ { "benchmark", "benchmark one of the other commands",
+ BenchmarkImageCommand, BenchmarkUsage, 1, SingleMode | BatchMode },
+ { "compare", "compare two images",
+ CompareImageCommand, CompareUsage, 0, SingleMode | BatchMode },
+ { "composite", "composite images together",
+ CompositeImageCommand, CompositeUsage, 0, SingleMode | BatchMode },
+ { "conjure", "execute a Magick Scripting Language (MSL) XML script",
+ ConjureImageCommand, ConjureUsage, 0, SingleMode | BatchMode },
+ { "convert", "convert an image or sequence of images",
+ ConvertImageCommand, ConvertUsage, 0, SingleMode | BatchMode },
+#if defined(HasX11)
+ { "display", "display an image on a workstation running X",
+ DisplayImageCommand, DisplayUsage, 0, SingleMode | BatchMode },
+#endif
+ { "help", "obtain usage message for named command",
+ HelpCommand, GMUsage, 0, SingleMode | BatchMode },
+ { "identify", "describe an image or image sequence",
+ IdentifyImageCommand, IdentifyUsage, 1, SingleMode | BatchMode },
+#if defined(HasX11)
+ { "import", "capture an application or X server screen",
+ ImportImageCommand, ImportUsage, 0, SingleMode | BatchMode },
+#endif
+ { "mogrify", "transform an image or sequence of images",
+ MogrifyImageCommand, MogrifyUsage, 0, SingleMode | BatchMode },
+ { "montage", "create a composite image (in a grid) from separate images",
+ MontageImageCommand, MontageUsage, 0, SingleMode | BatchMode },
+ { "set", "change batch mode option",
+ SetCommand, SetUsage, 1, BatchMode },
+ { "time", "time one of the other commands",
+ TimeImageCommand, TimeUsage, 1, SingleMode | BatchMode },
+ { "version", "obtain release version",
+ VersionCommand, 0, 0, SingleMode | BatchMode },
+#if defined(MSWINDOWS)
+ { "register", "register this application as the source of messages",
+ RegisterCommand, 0, 0, SingleMode | BatchMode },
+#endif
+ { 0, 0, 0, 0, 0, 0}
+ };
+
+static SemaphoreInfo
+ *command_semaphore = (SemaphoreInfo *) NULL;
+
+static RunMode run_mode = SingleMode;
+
+static BatchOptions batch_options;
+
+static const char *on_off_option_values[3] = { "off", "on", (char *) NULL };
+
+static const char *escape_option_values[3] = { "unix", "windows", (char *)NULL };
+
+#define MAX_PARAM_CHAR 4096
+#define MAX_PARAM 256
+static char commandline[MAX_PARAM_CHAR+2];
+
+#define PrintVersionAndCopyright() { \
+ (void) printf("%.1024s\n",GetMagickVersion((unsigned long *) NULL)); \
+ (void) printf("%.1024s\n",GetMagickCopyright()); \
+}
+
+#define PrintUsageHeader() { \
+ if (run_mode != BatchMode) \
+ PrintVersionAndCopyright(); \
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C o m m a n d A c c e s s M o n i t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method CommandAccessMonitor displays the files and programs which are
+% attempted to be accessed.
+%
+% The format of the CommandAccessMonitor method is:
+%
+% MagickBool CommandAccessMonitor(const ConfirmAccessMode mode,
+% const char *path,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o mode: The type of access to be performed.
+%
+% o path: The local path or URL requested to be accessed.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+static MagickBool CommandAccessMonitor(const ConfirmAccessMode mode,
+ const char *path,
+ ExceptionInfo *exception)
+{
+ const char
+ *env;
+
+ ARG_NOT_USED(mode);
+ ARG_NOT_USED(path);
+ ARG_NOT_USED(exception);
+
+ if (((env=getenv("MAGICK_ACCESS_MONITOR")) != (const char *) NULL) &&
+ (LocaleCompare(env,"TRUE") == 0))
+ {
+ (void) fprintf(stderr," %s %s\n",
+ ConfirmAccessModeToString(mode),path);
+ }
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C o m m a n d P r o g r e s s M o n i t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method CommandProgressMonitor displays the progress a task is making in
+% completing a task.
+%
+% The format of the CommandProgressMonitor method is:
+%
+% MagickBool CommandProgressMonitor(const char *task,
+% const magick_int64_t quantum,const magick_uint64_t span,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o task: Identifies the task in progress.
+%
+% o quantum: Specifies the quantum position within the span which represents
+% how much progress has been made in completing a task.
+%
+% o span: Specifies the span relative to completing a task.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+static MagickBool CommandProgressMonitor(const char *task,
+ const magick_int64_t quantum,
+ const magick_uint64_t span,
+ ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+
+ if ((span > 1) && (quantum >= 0) && ((magick_uint64_t) quantum < span))
+ {
+ const char
+ *p;
+
+ /* Skip over any preceding white space */
+ for (p=task; (*p) && (isspace((int) *p)); p++);
+ (void) fprintf(stderr," %3lu%% %s\r",
+ (unsigned long)
+ ((double) 100.0*quantum/
+ (
+#ifdef _MSC_VER
+# if _MSC_VER <= 1200 /*Older Visual Studio lacks UINT64 to double conversion*/
+ (magick_int64_t)
+# endif
+#endif
+ span-1)),
+ p);
+ if ((magick_uint64_t) quantum == (span-1))
+ (void) fprintf(stderr,"\n");
+ (void) fflush(stderr);
+ }
+ return(MagickTrue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N o r m a l i z e S a m p l i n g F a c t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NormalizeSamplingFactor() transforms industry-standard subsampling
+% specifications into the internal geometry-style form.
+%
+% The format of the NormalizeSamplingFactor method is:
+%
+% void NormalizeSamplingFactor(ImageInfo *image_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: ImageInfo structure containing sampling factor to transform.
+%
+%
+*/
+static void NormalizeSamplingFactor(ImageInfo *image_info)
+{
+ int
+ count;
+
+ unsigned int
+ factors[3],
+ horizontal,
+ vertical;
+
+ char
+ buffer[MaxTextExtent];
+
+ if (image_info->sampling_factor == NULL)
+ return;
+
+ factors[0]=factors[1]=factors[2]=0;
+ count=sscanf(image_info->sampling_factor,"%u:%u:%u",
+ &factors[0], &factors[1], &factors[2]);
+ if ((count != 3) || (factors[1] == 0))
+ return;
+
+ horizontal=factors[0]/factors[1];
+ vertical=1;
+ if (factors[2] == 0)
+ vertical=2;
+
+ FormatString(buffer,"%ux%u",horizontal,vertical);
+ (void) CloneString(&image_info->sampling_factor,buffer);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A n i m a t e U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AnimateUsage() displays the program command syntax.
+%
+% The format of the AnimateUsage method is:
+%
+% void AnimateUsage()
+%
+% A description of each parameter follows:
+%
+%
+*/
+#if defined(HasX11)
+static void AnimateUsage(void)
+{
+ const char
+ **p;
+
+ static const char
+ *buttons[]=
+ {
+ "Press any button to map or unmap the Command widget",
+ (char *) NULL
+ },
+ *options[]=
+ {
+ "-authenticate value decrypt image with this password",
+ "-backdrop display image centered on a backdrop",
+ "-colormap type Shared or Private",
+ "-colors value preferred number of colors in the image",
+ "-colorspace type alternate image colorspace",
+ "-crop geometry preferred size and location of the cropped image",
+ "-debug events display copious debugging information",
+ "-define values Coder/decoder specific options",
+ "-delay value display the next image after pausing",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-display server display image to this X server",
+ "-dither apply Floyd/Steinberg error diffusion to image",
+ "-gamma value level of gamma correction",
+ "-geometry geometry preferred size and location of the Image window",
+ "-help print program options",
+ "-interlace type None, Line, Plane, or Partition",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-log format format of debugging information",
+ "-matte store matte channel if the image has one",
+ "-map type display image using this Standard Colormap",
+ "-monitor show progress indication",
+ "-monochrome transform image to black and white",
+ "-noop do not apply options to image",
+ "-pause seconds to pause before reanimating",
+ "-remote command execute a command in a remote display process",
+ "-rotate degrees apply Paeth rotation to the image",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-scenes range image scene range",
+ "-size geometry width and height of image",
+ "-treedepth value color tree depth",
+ "-trim trim image edges",
+ "-type type image type",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ "-visual type display image using this visual type",
+ "-virtual-pixel method",
+ " Constant, Edge, Mirror, or Tile",
+ "-window id display image to background of this window",
+ (char *) NULL
+ };
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] file [ [options ...] file ...]\n",
+ GetClientName());
+ (void) printf("\nWhere options include: \n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) printf(
+ "\nIn addition to those listed above, you can specify these standard X\n");
+ (void) printf(
+ "resources as command line options: -background, -bordercolor,\n");
+ (void) printf(
+ "-borderwidth, -font, -foreground, -iconGeometry, -iconic, -name,\n");
+ (void) printf("-mattecolor, -shared-memory, or -title.\n");
+ (void) printf(
+ "\nBy default, the image format of `file' is determined by its magic\n");
+ (void) printf(
+ "number. To specify a particular image format, precede the filename\n");
+ (void) printf(
+ "with an image format name and a colon (i.e. ps:image) or specify the\n");
+ (void) printf(
+ "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n");
+ (void) printf("'-' for standard input or output.\n");
+ (void) printf("\nButtons: \n");
+ for (p=buttons; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+}
+#endif /* HasX11 */
+MagickExport MagickPassFail AnimateImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+#if defined(HasX11)
+ char
+ *option,
+ *resource_value,
+ *server_name;
+
+ const char
+ *client_name;
+
+ Display
+ *display;
+
+ Image
+ *image,
+ *image_list,
+ *loaded_image,
+ *next_image;
+
+ long
+ first_scene,
+ j,
+ k,
+ last_scene,
+ scene,
+ x;
+
+ QuantizeInfo
+ *quantize_info;
+
+ register Image
+ *p;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ MagickXResourceInfo
+ resource_info;
+
+ XrmDatabase
+ resource_database;
+
+ /*
+ Set defaults.
+ */
+ SetNotifyHandlers;
+ display=(Display *) NULL;
+ first_scene=0;
+ image=(Image *) NULL;
+ image_list=(Image *) NULL;
+ last_scene=0;
+ server_name=(char *) NULL;
+ status=MagickTrue;
+ /*
+ Check for server name specified on the command line.
+ */
+ for (i=1; i < argc; i++)
+ {
+ /*
+ Check command line for server name.
+ */
+ option=argv[i];
+ if ((strlen(option) == 1) || ((*option != '-') && (*option != '+')))
+ continue;
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ /*
+ User specified server name.
+ */
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ server_name=argv[i];
+ break;
+ }
+ if (LocaleCompare("help",option+1) == 0)
+ {
+ AnimateUsage();
+ return MagickPass;
+ }
+ if (LocaleCompare("version",option+1) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+ }
+
+ /*
+ Expand argument list
+ */
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ /*
+ Get user defaults from X resource database.
+ */
+ display=XOpenDisplay(server_name);
+ if (display == (Display *) NULL)
+ MagickFatalError(XServerFatalError,UnableToOpenXServer,
+ XDisplayName(server_name));
+ (void) XSetErrorHandler(MagickXError);
+ client_name=GetClientName();
+ resource_database=MagickXGetResourceDatabase(display,client_name);
+ MagickXGetResourceInfo(resource_database,(char *) client_name,&resource_info);
+ image_info=resource_info.image_info;
+ quantize_info=resource_info.quantize_info;
+ image_info->density=
+ MagickXGetResourceInstance(resource_database,client_name,"density",(char *) NULL);
+ if (image_info->density == (char *) NULL)
+ image_info->density=MagickXGetScreenDensity(display);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"interlace","none");
+ image_info->interlace=StringToInterlaceType(resource_value);
+ if (image_info->interlace == UndefinedInterlace)
+ MagickError(OptionFatalError,InvalidInterlaceType,resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"verbose","False");
+ image_info->verbose=MagickIsTrue(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"dither","True");
+ quantize_info->dither=MagickIsTrue(resource_value);
+ /*
+ Parse command line.
+ */
+ j=1;
+ k=0;
+ for (i=1; i <= argc; i++)
+ {
+ if (i < argc)
+ option=argv[i];
+ else
+ if (image != (Image *) NULL)
+ break;
+ else
+ option=(char *) "logo:Untitled";
+ if ((strlen(option) < 2) ||
+ /* stdin + subexpression */
+ ((option[0] == '-') && (option[1] == '[')) ||
+ ((option[0] != '-') && option[0] != '+'))
+ {
+ /*
+ Option is a file name.
+ */
+ k=i;
+ for (scene=first_scene; scene <= last_scene ; scene++)
+ {
+ /*
+ Read image.
+ */
+ (void) strlcpy(image_info->filename,option,MaxTextExtent);
+ if (first_scene != last_scene)
+ {
+ char
+ filename[MaxTextExtent];
+
+ /*
+ Form filename for multi-part images.
+ */
+ (void) MagickSceneFileName(filename,image_info->filename,"[%lu]",MagickTrue,scene);
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ }
+ image_info->colorspace=quantize_info->colorspace;
+ image_info->dither=quantize_info->dither;
+ next_image=ReadImage(image_info,exception);
+ if (exception->severity > UndefinedException)
+ {
+ CatchException(exception);
+ DestroyExceptionInfo(exception);
+ GetExceptionInfo(exception);
+ }
+ status&=next_image != (Image *) NULL;
+ if (next_image == (Image *) NULL)
+ continue;
+ if (image == (Image *) NULL)
+ {
+ image=next_image;
+ continue;
+ }
+ /*
+ Link image into image list.
+ */
+ for (p=image; p->next != (Image *) NULL; p=p->next);
+ next_image->previous=p;
+ p->next=next_image;
+ }
+ continue;
+ }
+ if (j != (k+1))
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image);
+ (void) CatchImageException(image);
+ AppendImageToList(&image_list,image);
+ image=(Image *) NULL;
+ j=k+1;
+ }
+ switch (*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("authenticate",option+1) == 0)
+ {
+ (void) CloneString(&image_info->authenticate,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->authenticate,argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'b':
+ {
+ if (LocaleCompare("backdrop",option+1) == 0)
+ {
+ resource_info.backdrop=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("background",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.background_color=argv[i];
+ (void) QueryColorDatabase(argv[i],&image_info->background_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("bordercolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.border_color=argv[i];
+ (void) QueryColorDatabase(argv[i],&image_info->border_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("borderwidth",option+1) == 0)
+ {
+ resource_info.border_width=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.border_width=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'c':
+ {
+ if (LocaleCompare("colormap",option+1) == 0)
+ {
+ resource_info.colormap=PrivateColormap;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ resource_info.colormap=UndefinedColormap;
+ if (LocaleCompare("private",option) == 0)
+ resource_info.colormap=PrivateColormap;
+ if (LocaleCompare("shared",option) == 0)
+ resource_info.colormap=SharedColormap;
+ if (resource_info.colormap == UndefinedColormap)
+ MagickFatalError(OptionFatalError,UnrecognizedColormapType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("colors",option+1) == 0)
+ {
+ quantize_info->number_colors=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ quantize_info->number_colors=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ quantize_info->colorspace=RGBColorspace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ quantize_info->colorspace=StringToColorspaceType(option);
+ if (IsGrayColorspace(quantize_info->colorspace))
+ {
+ quantize_info->number_colors=256;
+ quantize_info->tree_depth=8;
+ }
+ if (quantize_info->colorspace == UndefinedColorspace)
+ MagickFatalError(OptionFatalError,InvalidColorspaceType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("crop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'd':
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("delay",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ (void) CloneString(&image_info->server_name,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->server_name,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("dither",option+1) == 0)
+ {
+ quantize_info->dither=(*option == '-');
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'f':
+ {
+ if (LocaleCompare("font",option+1) == 0)
+ {
+ (void) CloneString(&image_info->font,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->font,argv[i]);
+ }
+ if ((image_info->font == (char *) NULL) ||
+ (*image_info->font != '@'))
+ resource_info.font=AllocateString(image_info->font);
+ break;
+ }
+ if (LocaleCompare("foreground",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ resource_info.foreground_color=argv[i];
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'g':
+ {
+ if (LocaleCompare("gamma",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("geometry",option+1) == 0)
+ {
+ resource_info.image_geometry=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.image_geometry=argv[i];
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'h':
+ {
+ if (LocaleCompare("help",option+1) == 0)
+ {
+ AnimateUsage();
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'i':
+ {
+ if (LocaleCompare("iconGeometry",option+1) == 0)
+ {
+ resource_info.icon_geometry=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.icon_geometry=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("iconic",option+1) == 0)
+ {
+ resource_info.iconic=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ MagickFatalError(OptionFatalError,InvalidInterlaceType,
+ option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'l':
+ {
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ MagickFatalError(OptionFatalError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'm':
+ {
+ if (LocaleCompare("map",option+1) == 0)
+ {
+ (void) strcpy(argv[i]+1,"sans");
+ resource_info.map_type=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.map_type=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("matte",option+1) == 0)
+ break;
+ if (LocaleCompare("mattecolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.matte_color=argv[i];
+ (void) QueryColorDatabase(argv[i],&image_info->matte_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ if (LocaleCompare("monochrome",option+1) == 0)
+ {
+ image_info->monochrome=(*option == '-');
+ if (image_info->monochrome)
+ {
+ quantize_info->number_colors=2;
+ quantize_info->tree_depth=8;
+ quantize_info->colorspace=GRAYColorspace;
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'n':
+ {
+ if (LocaleCompare("name",option+1) == 0)
+ {
+ resource_info.name=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.name=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("noop",option+1) == 0)
+ break;
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'p':
+ {
+ if (LocaleCompare("pause",option+1) == 0)
+ {
+ resource_info.pause=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ resource_info.pause=MagickAtoI(argv[i]);
+ break;
+ }
+ break;
+ }
+ case 'r':
+ {
+ if (LocaleCompare("remote",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ status=MagickXRemoteCommand(display,resource_info.window_id,argv[i]);
+ Exit(!status);
+ }
+ if (LocaleCompare("rotate",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 's':
+ {
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("scenes",option+1) == 0)
+ {
+ first_scene=0;
+ last_scene=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ first_scene=MagickAtoL(argv[i]);
+ last_scene=first_scene;
+ (void) sscanf(argv[i],"%ld-%ld",&first_scene,&last_scene);
+ }
+ break;
+ }
+ if (LocaleCompare("shared-memory",option+1) == 0)
+ {
+ resource_info.use_shared_memory=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 't':
+ {
+ if (LocaleCompare("text-font",option+1) == 0)
+ {
+ resource_info.text_font=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.text_font=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("title",option+1) == 0)
+ {
+ resource_info.title=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.title=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("treedepth",option+1) == 0)
+ {
+ quantize_info->tree_depth=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ quantize_info->tree_depth=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("trim",option+1) == 0)
+ {
+ break;
+ }
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ resource_info.image_info->type=UndefinedType;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ resource_info.image_info->type=StringToImageType(option);
+ if (resource_info.image_info->type == UndefinedType)
+ MagickFatalError(OptionFatalError,UnrecognizedImageType,
+ option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("version",option+1) == 0)
+ break;
+ if (LocaleCompare("virtual-pixel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ option=argv[i];
+ virtual_pixel_method=StringToVirtualPixelMethod(option);
+ if (virtual_pixel_method == UndefinedVirtualPixelMethod)
+ MagickFatalError(OptionFatalError,UnrecognizedVirtualPixelMethod,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("visual",option+1) == 0)
+ {
+ resource_info.visual_type=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ resource_info.visual_type=argv[i];
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'w':
+ {
+ if (LocaleCompare("window",option+1) == 0)
+ {
+ resource_info.window_id=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ resource_info.window_id=argv[i];
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case '?':
+ {
+ AnimateUsage();
+ break;
+ }
+ default:
+ {
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ }
+ }
+ i--;
+ if ((image == (Image *) NULL) && (image_list == (Image *) NULL))
+ MagickFatalError(OptionFatalError,RequestDidNotReturnAnImage,(char *) NULL);
+ if (image == (Image *) NULL)
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image_list);
+ (void) CatchImageException(image_list);
+ }
+ else
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image);
+ (void) CatchImageException(image);
+ AppendImageToList(&image_list,image);
+ }
+ if (resource_info.window_id != (char *) NULL)
+ MagickXAnimateBackgroundImage(display,&resource_info,image_list);
+ else
+ {
+ /*
+ Animate image to X server.
+ */
+ loaded_image=MagickXAnimateImages(display,&resource_info,argv,argc,image_list);
+ while (loaded_image != (Image *) NULL)
+ {
+ image_list=loaded_image;
+ loaded_image=
+ MagickXAnimateImages(display,&resource_info,argv,argc,image_list);
+ }
+ }
+ DestroyImageList(image_list);
+ LiberateArgumentList(argc,argv);
+ MagickXDestroyResourceInfo(&resource_info);
+ MagickXDestroyX11Resources();
+ (void) XCloseDisplay(display);
+ return(status);
+#else
+ ARG_NOT_USED(image_info);
+ ARG_NOT_USED(argc);
+ ARG_NOT_USED(argv);
+ ARG_NOT_USED(metadata);
+ ARG_NOT_USED(exception);
+
+ MagickFatalError(MissingDelegateError,XWindowLibraryIsNotAvailable,
+ (char *) NULL);
+ return(MagickFail);
+#endif
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B a t c h C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BatchCommand runs multiple commands in interactive or batch mode.
+%
+% The format of the BatchCommand method is:
+%
+% MagickPassFail BatchCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+static MagickPassFail BatchCommand(int argc, char **argv)
+{
+ int result;
+ MagickBool hasInputFile;
+ int ac;
+ char *av[MAX_PARAM+1];
+
+ {
+ char client_name[MaxTextExtent];
+ FormatString(client_name,"%.1024s %s", argv[0], argv[1]);
+ (void) SetClientName(client_name);
+ }
+
+ {
+ BatchOptions dummy;
+ result = ProcessBatchOptions(argc-1, argv+1, &dummy);
+ if (result < 0 )
+ {
+ BatchUsage();
+ return result == OptionHelp;
+ }
+ }
+
+ hasInputFile = (++result <= argc-1);
+ if (result < argc-1)
+ {
+ (void) fprintf(stderr, "Error: unexpected parameter: %s\n", argv[result+1]);
+ BatchUsage();
+ return MagickFail;
+ }
+
+ if (hasInputFile && (argv[result][0] != '-' || argv[result][1] != '\0'))
+ if (freopen(argv[result], "r", stdin) == (FILE *)NULL)
+ {
+ perror(argv[result]);
+ exit(1);
+ }
+
+ InitializeBatchOptions(!hasInputFile);
+ result = ProcessBatchOptions(argc-1, argv+1, &batch_options);
+
+ run_mode = BatchMode;
+#if defined(MSWINDOWS)
+ InitializeMagick((char *) NULL);
+#else
+ InitializeMagick(argv[0]);
+#endif
+
+ av[0] = argv[0];
+ av[MAX_PARAM] = (char *)NULL;
+ if (batch_options.prompt[0])
+ {
+ PrintVersionAndCopyright();
+ (void) fflush(stdout);
+ }
+
+ while (!(ferror(stdin) || ferror(stdout) || ferror(stderr) || feof(stdin)))
+ {
+ if (batch_options.prompt[0])
+ {
+ (void) fputs(batch_options.prompt, stdout);
+ (void) fflush(stdout);
+ }
+
+ ac = (batch_options.command_line_parser)(stdin, MAX_PARAM, av);
+ if (ac < 0)
+ {
+ result = MagickPass;
+ break;
+ };
+ if (batch_options.is_echo_enabled)
+ {
+ int i;
+ for (i = 1; i < ac; i++)
+ {
+ (void) fputs(av[i], stdout);
+ (void) putchar(' ');
+ }
+ (void) putchar('\n');
+ (void) fflush(stdout);
+ }
+ if (ac == 1)
+ continue;
+ if (ac > 0 && ac <= MAX_PARAM)
+ result = GMCommandSingle(ac, av);
+ else
+ {
+ if (ac == 0)
+ (void) fprintf(stderr,
+ "Error: command line exceeded %d characters.\n",
+ MAX_PARAM_CHAR);
+ else
+ (void) fprintf(stderr,
+ "Error: command line exceeded %d parameters.\n",
+ MAX_PARAM);
+ result = MagickFail;
+ }
+
+ if (batch_options.is_feedback_enabled)
+ {
+ (void) fputs(result ? batch_options.pass : batch_options.fail, stdout);
+ (void) fputc('\n', stdout);
+ }
+ (void) fflush(stderr);
+ (void) fflush(stdout);
+
+ if (batch_options.stop_on_error && !result)
+ break;
+ }
+
+ if (batch_options.prompt[0])
+ {
+ (void) fputs("\n", stdout);
+ (void) fflush(stdout);
+ }
+ DestroyMagick();
+ return(result);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B a t c h O p t i o n U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BatchOptionUsage() displays the option detail for "batch" and "set" command.
+%
+% The format of the BatchOptionUsage method is:
+%
+% void BatchOptionUsage()
+%
+*/
+static void BatchOptionUsage(void)
+{
+ static const char
+ *options[]=
+ {
+ "-echo on|off echo command back to standard out, default is off",
+ "-escape unix|windows force use Unix or Windows escape format for command line",
+ " argument parsing, default is platform dependent",
+ "-fail text when feedback is on, output the designated text if the",
+ " command returns error, default is 'FAIL'",
+ "-feedback on|off print text (see -pass and -fail options) feedback after",
+ " each command to indicate the result, default is off",
+ "-help print program options",
+ "-pass text when feedback is on, output the designated text if the",
+ " command executed successfully, default is 'PASS'",
+ "-prompt text use the given text as command prompt. use text 'off' or",
+ " empty string to turn off prompt. default to 'GM> ' if",
+ " and only if batch mode was entered with no file argument",
+ "-stop-on-error on|off",
+ " when turned on, batch execution quits prematurely when",
+ " any command returns error",
+ (char *) NULL
+ };
+
+ const char
+ **p;
+
+ (void) printf("\nWhere options include:\n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) puts("\nUnix escape allows the use backslash(\\), single quote(') and double quote(\") in");
+ (void) puts("the command line. Windows escape only uses double quote(\"). For example,");
+
+ (void) puts("\n Orignal Unix escape Windows escape");
+ (void) puts(" [a\\b\\c\\d] [a\\\\b\\\\c\\\\d] [a\\b\\c\\d]");
+ (void) puts(" [Text with space] [Text\\ with\\ space] [\"Text with space\"]");
+ (void) puts(" [Text with (\")] ['Text with (\")'] [\"Text with (\"\")\"]");
+ (void) puts(" [Mix: \"It's a (\\)\"] [\"Mix: \\\"It's a (\\\\)\\\"\"] [\"Mix: \"\"It's a (\\)\"\"\"]");
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B a t c h U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BatchUsage displays the program command syntax.
+%
+% The format of the BatchUsage method is:
+%
+% void BatchUsage()
+%
+*/
+static void BatchUsage(void)
+{
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] [file|-]\n", GetClientName());
+ BatchOptionUsage();
+ (void) puts("\nUse '-' to read command from standard input without default prompt.");
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B e n c h m a r k U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BenchmarkUsage() displays the program command syntax.
+%
+% The format of the BenchmarkUsage method is:
+%
+% void BenchmarkUsage()
+%
+% A description of each parameter follows:
+%
+%
+*/
+static void BenchmarkUsage(void)
+{
+ static const char
+ *options[]=
+ {
+ "-duration duration duration to run each benchmark (in seconds)",
+ "-iterations loops number of command iterations",
+ "-rawcsv CSV output (threads,iterations,user_time,elapsed_time)",
+ "-stepthreads step step benchmark with increasing number of threads",
+ (char *) NULL
+ };
+
+ const char
+ **p;
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s options command ... ",GetClientName());
+ (void) printf("\nWhere options include one of:\n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) printf("Followed by some other GraphicsMagick command\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B e n c h m a r k I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BenchmarkImageCommand() executes a specified GraphicsMagick sub-command
+% (e.g. 'convert') for a specified number of interations or for a specified
+% elapsed time. When the command completes, various statistics are printed
+% including the number of iterations per second as a floating point value.
+%
+% The format of the BenchmarkImageCommand method is:
+%
+% unsigned int BenchmarkImageCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail ExecuteSubCommand(const ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ unsigned int
+ status;
+
+ ImageInfo
+ *clone_info;
+
+ char
+ *text = (char *) NULL;;
+
+ clone_info=CloneImageInfo(image_info);
+ status=MagickCommand(clone_info,argc,argv,metadata,exception);
+ if (metadata != (char **) NULL)
+ text=*metadata;
+ if (text != (char *) NULL)
+ {
+ if (strlen(text))
+ {
+ (void) fputs(text,stdout);
+ (void) fputc('\n',stdout);
+ (void) fflush(stdout);
+ }
+ MagickFreeMemory(text);
+ *metadata=text;
+ }
+ DestroyImageInfo(clone_info);
+ return status;
+}
+MagickExport MagickPassFail
+BenchmarkImageCommand(ImageInfo *image_info,
+ int argc,char **argv,
+ char **metadata,ExceptionInfo *exception)
+{
+ MagickBool
+ concurrent;
+
+ MagickBool
+ raw_csv,
+ thread_bench;
+
+ long
+ current_threads,
+ max_threads;
+
+ double
+ rate_total_st;
+
+ double
+ duration;
+
+ long
+ max_iterations,
+ thread_step;
+
+ unsigned int
+ status=MagickTrue;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ BenchmarkUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+
+ /*
+ Skip over our command name argv[0].
+ */
+ argc--;
+ argv++;
+ concurrent=MagickFalse;
+ raw_csv=MagickFalse;
+ thread_bench=MagickFalse;
+ max_threads = (long) GetMagickResourceLimit(ThreadsResource);
+ current_threads = 1;
+ rate_total_st = 1.0;
+ duration=-1.0;
+ max_iterations=1L;
+ thread_step=1L;
+
+ while ((argc) && (*argv[0] == '-'))
+ {
+ if (LocaleCompare("-duration",argv[0]) == 0)
+ {
+ argc--;
+ argv++;
+ if (argc)
+ {
+ duration=MagickAtoF(argv[0]);
+ }
+ }
+ else if (LocaleCompare("-iterations",argv[0]) == 0)
+ {
+ argc--;
+ argv++;
+ if (argc)
+ {
+ max_iterations=MagickAtoL(argv[0]);
+ }
+ }
+ else if (LocaleCompare("-concurrent",argv[0]) == 0)
+ {
+ concurrent=MagickTrue;
+ }
+ else if (LocaleCompare("-rawcsv",argv[0]) == 0)
+ {
+ raw_csv=MagickTrue;
+ }
+ else if (LocaleCompare("-stepthreads",argv[0]) == 0)
+ {
+ thread_bench=MagickTrue;
+ argc--;
+ argv++;
+ if (argc)
+ {
+ thread_step=MagickAtoL(argv[0]);
+ }
+ }
+ argc--;
+ argv++;
+ }
+
+ if ((argc < 1) ||
+ ((duration <= 0) && (max_iterations <= 0)))
+ {
+ BenchmarkUsage();
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+
+ if (raw_csv)
+ {
+ /*
+ Print a header line since spreadsheet programs (and Python's
+ CSV parser) use the first line as the column titles.
+ */
+ (void) fprintf(stderr,"\"Threads\",\"Iterations\",\"User Time\",\"Elapsed Time\"\n");
+ }
+
+ do
+ {
+ char
+ client_name[MaxTextExtent];
+
+ long
+ iteration=0;
+
+ TimerInfo
+ timer;
+
+ if (thread_bench)
+ (void) SetMagickResourceLimit(ThreadsResource,current_threads);
+
+
+ (void) strlcpy(client_name,GetClientName(),sizeof(client_name));
+
+ /*
+ If doing a thread run-up, then warm things up first with one iteration.
+ */
+ if (thread_bench)
+ status=ExecuteSubCommand(image_info,argc,argv,metadata,exception);
+
+ GetTimerInfo(&timer);
+
+ if (concurrent)
+ {
+ MagickBool
+ quit = MagickFalse;
+
+ long
+ count = 0;
+
+#if defined(HAVE_OPENMP)
+ omp_set_nested(MagickTrue);
+#endif
+ if (duration > 0)
+ {
+ count=0;
+#if defined(HAVE_OPENMP)
+# pragma omp parallel for shared(count, status, quit)
+#endif
+ for (iteration=0; iteration < 1000000; iteration++)
+ {
+ MagickPassFail
+ thread_status;
+
+ MagickBool
+ thread_quit;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_BenchmarkImageCommand)
+#endif
+ thread_quit=quit;
+
+ if (thread_quit)
+ continue;
+
+ thread_status=ExecuteSubCommand(image_info,argc,argv,metadata,exception);
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_BenchmarkImageCommand)
+#endif
+ {
+ count++;
+ if (!thread_status)
+ {
+ status=thread_status;
+ thread_quit=MagickTrue;
+ }
+ if (GetElapsedTime(&timer) > duration)
+ thread_quit=MagickTrue;
+ else
+ (void) ContinueTimer(&timer);
+ if (thread_quit)
+ quit=thread_quit;
+ }
+ }
+ }
+ else if (max_iterations > 0)
+ {
+#if defined(HAVE_OPENMP)
+# pragma omp parallel for shared(count, status, quit)
+#endif
+ for (iteration=0; iteration < max_iterations; iteration++)
+ {
+ MagickPassFail
+ thread_status;
+
+ MagickBool
+ thread_quit;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_BenchmarkImageCommand)
+#endif
+ thread_quit=quit;
+
+ if (thread_quit)
+ continue;
+
+ thread_status=ExecuteSubCommand(image_info,argc,argv,metadata,exception);
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_BenchmarkImageCommand)
+#endif
+ {
+ count++;
+ if (!thread_status)
+ {
+ status=thread_status;
+ thread_quit=MagickTrue;
+ }
+ if (thread_quit)
+ quit=thread_quit;
+ }
+ }
+ }
+ iteration=count;
+ }
+ else
+ {
+ if (duration > 0)
+ {
+ /*
+ Loop until duration or max_iterations has been hit.
+ */
+ for (iteration=0; iteration < (LONG_MAX-1); )
+ {
+ status=ExecuteSubCommand(image_info,argc,argv,metadata,exception);
+ iteration++;
+ if (!status)
+ break;
+ if (GetElapsedTime(&timer) > duration)
+ break;
+ (void) ContinueTimer(&timer);
+ }
+ }
+ else if (max_iterations > 0)
+ {
+ /*
+ Loop until max_iterations has been hit.
+ */
+ for (iteration=0; iteration < max_iterations; )
+ {
+ status=ExecuteSubCommand(image_info,argc,argv,metadata,exception);
+ iteration++;
+ if (!status)
+ break;
+ }
+ }
+ }
+ {
+ double
+ rate_cpu,
+ rate_total,
+ /* resolution, */
+ user_time;
+
+ double
+ elapsed_time;
+
+ long
+ threads_limit;
+
+ /* resolution=GetTimerResolution(); */
+ user_time=GetUserTime(&timer);
+ elapsed_time=GetElapsedTime(&timer);
+ rate_total=(((double) iteration)/elapsed_time);
+ rate_cpu=(((double) iteration)/user_time);
+ threads_limit=(long) GetMagickResourceLimit(ThreadsResource);
+ if (1 == threads_limit)
+ rate_total_st=rate_total;
+ (void) fflush(stdout);
+ if (raw_csv)
+ {
+ /* RAW CSV value output */
+ (void) fprintf(stderr,"\"%ld\",\"%ld\",\"%.2f\",\"%.3f\"",
+ threads_limit,iteration,user_time,elapsed_time);
+ }
+ else
+ {
+ /* Formatted and summarized output */
+ (void) fprintf(stderr,
+ "Results: %ld threads %ld iter %.2fs user %.2fs total %.3f iter/s "
+ "%.3f iter/cpu",
+ threads_limit,iteration,user_time,elapsed_time,rate_total,rate_cpu);
+ if (thread_bench)
+ {
+ double
+ karp_flatt_metric,
+ speedup;
+
+ /* Speedup ratio */
+ speedup=rate_total/rate_total_st;
+
+ /* Karp-Flatt metric, http://en.wikipedia.org/wiki/Karp%E2%80%93Flatt_metric */
+ karp_flatt_metric=1.0;
+ if (threads_limit > 1)
+ karp_flatt_metric=((1.0/Min(threads_limit,speedup))-
+ (1.0/threads_limit))/(1.0-(1.0/threads_limit));
+ (void) fprintf(stderr," %.2f speedup %.3f karp-flatt",speedup,karp_flatt_metric);
+ }
+ }
+ (void) fprintf(stderr,"\n");
+ (void) fflush(stderr);
+ }
+ /*
+ Always measure with one thread, and then step up as if from zero.
+ */
+ if ((current_threads == 1) && (thread_step > 1))
+ current_threads = thread_step;
+ else
+ current_threads += thread_step;
+ }
+ while ((thread_bench) && (current_threads <= max_threads));
+
+ return status;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C h e c k O p t i o n V a l u e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CheckOptionValue prints error message to stderr if value agrument is null
+% and returns OPtionMissingValue. Otherwise return OptionSuccess.
+%
+% The format of the CheckOptionValue method is:
+%
+% OptionStatus CheckOptionValue(const char *option, const char *value)
+%
+% A description of each parameter follows:
+%
+% o option: The option to check the value.
+%
+% o value: The value to check for non-null.
+%
+*/
+static OptionStatus CheckOptionValue(const char *option, const char *value)
+{
+ if (value == (char *) NULL)
+ {
+ fprintf(stderr, "Error: Missing value for %s option\n", option);
+ return OptionMissingValue;
+ }
+ return OptionSuccess;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o m p a r e I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CompareImageCommand() reads two images, compares them via a specified
+% comparison metric, and prints the results.
+%
+% The format of the CompareImageCommand method is:
+%
+% unsigned int CompareImageCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowCompareException(code,reason,description) \
+{ \
+ DestroyImageList(compare_image); \
+ DestroyImageList(difference_image); \
+ DestroyImageList(reference_image); \
+ ThrowException(exception,code,reason,description); \
+ LiberateArgumentList(argc,argv); \
+ return(MagickFail); \
+}
+#define ThrowCompareException3(code,reason,description) \
+{ \
+ DestroyImageList(compare_image); \
+ DestroyImageList(difference_image); \
+ DestroyImageList(reference_image); \
+ ThrowException3(exception,code,reason,description); \
+ LiberateArgumentList(argc,argv); \
+ return(MagickFail); \
+}
+MagickExport MagickPassFail
+CompareImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ const char
+ *difference_filename;
+
+ char
+ *filename,
+ message[MaxTextExtent],
+ *option;
+
+ double
+ maximum_error=-1;
+
+ Image
+ *compare_image,
+ *difference_image,
+ *reference_image;
+
+ MetricType
+ metric=UndefinedMetric;
+
+ DifferenceImageOptions
+ difference_options;
+
+ long
+ x;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ /*
+ Set default.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ status=MagickPass;
+
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ CompareUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ InitializeDifferenceImageOptions(&difference_options,exception);
+ difference_image=NewImageList();
+ reference_image=NewImageList();
+ difference_filename=(const char *) NULL;
+ filename=(char *) NULL;
+ compare_image=NewImageList();
+ (void) strlcpy(image_info->filename,argv[argc-1],MaxTextExtent);
+ (void) SetImageInfo(image_info,SETMAGICK_WRITE,exception);
+
+ status=MagickPass;
+ /*
+ Check command syntax.
+ */
+ for (i=1; i < argc; i++)
+ {
+ option=argv[i];
+ if ((strlen(option) < 2) ||
+ /* stdin + subexpression */
+ ((option[0] == '-') && (option[1] == '[')) ||
+ ((option[0] != '-') && option[0] != '+'))
+ {
+ /*
+ Read input images.
+ */
+ filename=argv[i];
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ DestroyExceptionInfo(exception);
+ GetExceptionInfo(exception);
+ if (reference_image == (Image *) NULL)
+ {
+ reference_image=ReadImage(image_info,exception);
+ continue;
+ }
+ if (compare_image == (Image *) NULL)
+ {
+ compare_image=ReadImage(image_info,exception);
+ continue;
+ }
+ continue;
+ }
+ switch(*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("authenticate",option+1) == 0)
+ {
+ (void) CloneString(&image_info->authenticate,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->authenticate,argv[i]);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'c':
+ {
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ image_info->colorspace=RGBColorspace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->colorspace=StringToColorspaceType(option);
+ if (image_info->colorspace == UndefinedColorspace)
+ ThrowCompareException(OptionError,UnrecognizedColorspace,
+ option);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'd':
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompareException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ (void) CloneString(&image_info->server_name,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->server_name,argv[i]);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'e':
+ {
+ if (LocaleCompare("endian",option+1) == 0)
+ {
+ image_info->endian=UndefinedEndian;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->endian=StringToEndianType(option);
+ if (image_info->endian == UndefinedEndian)
+ ThrowCompareException(OptionError,UnrecognizedEndianType,
+ option);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'f':
+ {
+ if (LocaleCompare("file",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ difference_filename=argv[i];
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'h':
+ {
+ if (LocaleCompare("help",option+1) == 0)
+ {
+ CompareUsage();
+ break;
+ /* ThrowCompareException(OptionError,UsageError,NULL); */
+ }
+ if ((LocaleCompare("highlight-color",option+1) == 0) ||
+ (LocaleCompare("hilight-color",option+1) == 0))
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ (void) QueryColorDatabase(argv[i],&difference_options.highlight_color,
+ exception);
+ }
+ break;
+ }
+ if ((LocaleCompare("highlight-style",option+1) == 0) ||
+ (LocaleCompare("hilight-style",option+1) == 0))
+ {
+ difference_options.highlight_style=UndefinedHighlightStyle;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,option);
+ option=argv[i];
+ difference_options.highlight_style=StringToHighlightStyle(option);
+ if (difference_options.highlight_style == UndefinedHighlightStyle)
+ ThrowCompareException(OptionError,UnrecognizedHighlightStyle,
+ option);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'i':
+ {
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ image_info->interlace=UndefinedInterlace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ ThrowCompareException(OptionError,UnrecognizedInterlaceType,
+ option);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'l':
+ {
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompareException(OptionError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ ThrowCompareException(OptionError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'm':
+ {
+ if (LocaleCompare("matte",option+1) == 0)
+ break;
+ if (LocaleCompare("maximum-error",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ maximum_error=MagickAtoF(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("metric",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,
+ option);
+ metric=StringToMetricType(argv[i]);
+ if (metric == UndefinedMetric)
+ ThrowCompareException(OptionError,UnrecognizedMetric,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 's':
+ {
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompareException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 't':
+ {
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ image_info->type=UndefinedType;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompareException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->type=StringToImageType(option);
+ if (image_info->type == UndefinedType)
+ ThrowCompareException(OptionError,UnrecognizedImageType,
+ option);
+ }
+ break;
+ }
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("verbose",option+1) == 0)
+ break;
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ case '?':
+ break;
+ default:
+ ThrowCompareException(OptionError,UnrecognizedOption,option)
+ }
+ }
+ if (compare_image == (Image *) NULL)
+ {
+ if (exception->severity == UndefinedException)
+ ThrowCompareException(OptionError,RequestDidNotReturnAnImage,
+ (char *) NULL);
+ return(MagickFail);
+ }
+ if ((reference_image == (Image *) NULL) ||
+ (compare_image == (Image *) NULL))
+ ThrowCompareException(OptionError,MissingAnImageFilename,(char *) NULL);
+
+ /*
+ Apply any user settings to images prior to compare.
+ */
+ if (image_info->type != UndefinedType)
+ {
+ (void) SetImageType(reference_image,image_info->type);
+ (void) SetImageType(compare_image,image_info->type);
+ }
+
+ if (image_info->colorspace != UndefinedColorspace)
+ {
+ (void) TransformColorspace(reference_image,image_info->colorspace);
+ (void) TransformColorspace(compare_image,image_info->colorspace);
+ }
+
+ if (metric != UndefinedMetric)
+ {
+ /*
+ Compute and print statistical differences based on metric.
+ */
+ DifferenceStatistics
+ statistics;
+
+ InitializeDifferenceStatistics(&statistics,exception);
+ status&=GetImageChannelDifference(reference_image,compare_image,metric,
+ &statistics,exception);
+ fprintf(stdout,"Image Difference (%s):\n",MetricTypeToString(metric));
+ if (metric == PeakSignalToNoiseRatioMetric)
+ {
+ fprintf(stdout, " PSNR\n");
+ fprintf(stdout, " ======\n");
+ fprintf(stdout," Red: %#-6.2f\n",statistics.red);
+ fprintf(stdout," Green: %#-6.2f\n",statistics.green);
+ fprintf(stdout," Blue: %#-6.2f\n",statistics.blue);
+ if (reference_image->matte)
+ fprintf(stdout," Opacity: %#-6.2f\n",statistics.opacity);
+ fprintf(stdout," Total: %#-6.2f\n",statistics.combined);
+
+ if ((maximum_error >= 0.0) && (statistics.combined < maximum_error))
+ {
+ status &= MagickFail;
+ FormatString(message,"%g",statistics.combined);
+ ThrowException(exception,ImageError,ImageDifferenceExceedsLimit,message);
+ }
+ }
+ else
+ {
+ fprintf(stdout, " Normalized Absolute\n");
+ fprintf(stdout, " ============ ==========\n");
+ fprintf(stdout," Red: %#-12.10f % 10.1f\n",statistics.red,statistics.red*MaxRGBDouble);
+ fprintf(stdout," Green: %#-12.10f % 10.1f\n",statistics.green,statistics.green*MaxRGBDouble);
+ fprintf(stdout," Blue: %#-12.10f % 10.1f\n",statistics.blue,statistics.blue*MaxRGBDouble);
+ if (reference_image->matte)
+ fprintf(stdout," Opacity: %#-12.10f % 10.1f\n",statistics.opacity,statistics.opacity*MaxRGBDouble);
+ fprintf(stdout," Total: %#-12.10f % 10.1f\n",statistics.combined,statistics.combined*MaxRGBDouble);
+
+ if ((maximum_error >= 0.0) && (statistics.combined > maximum_error))
+ {
+ status &= MagickFail;
+ FormatString(message,"%g > %g",statistics.combined, maximum_error);
+ ThrowException(exception,ImageError,ImageDifferenceExceedsLimit,message);
+ }
+ }
+ }
+
+ if ((difference_filename != (const char *) NULL) &&
+ (difference_options.highlight_style != UndefinedHighlightStyle))
+ {
+ /*
+ Generate an annotated difference image and write file.
+ */
+
+ difference_image=DifferenceImage(reference_image,compare_image,
+ &difference_options,exception);
+ if (difference_image != (Image *) NULL)
+ {
+ (void) strlcpy(difference_image->filename,difference_filename,
+ MaxTextExtent);
+ if (WriteImage(image_info,difference_image) == MagickFail)
+ {
+ status &= MagickFail;
+ CopyException(exception,&difference_image->exception);
+ }
+ }
+ }
+
+ DestroyImageList(difference_image);
+ DestroyImageList(reference_image);
+ DestroyImageList(compare_image);
+ LiberateArgumentList(argc,argv);
+ return(status);
+}
+#undef ThrowCompareException
+#undef ThrowCompareException3
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o m p a r e U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CompareUsage() displays the program command syntax.
+%
+% The format of the CompareUsage method is:
+%
+% void CompareUsage()
+%
+%
+*/
+static void CompareUsage(void)
+{
+ const char
+ **p;
+
+ static const char
+ *options[]=
+ {
+ "-authenticate value decrypt image with this password",
+ "-colorspace type alternate image colorspace",
+ "-debug events display copious debugging information",
+ "-define values coder/decoder specific options",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-display server get image or font from this X server",
+ "-endian type multibyte word order (LSB, MSB, or Native)",
+ "-file filename write difference image to this file",
+ "-help print program options",
+ "-highlight-color color",
+ " color to use when annotating difference pixels",
+ "-highlight-style style",
+ " pixel highlight style (assign, threshold, tint, xor)",
+ "-interlace type None, Line, Plane, or Partition",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-log format format of debugging information",
+ "-matte store matte channel if the image has one",
+ "-maximum-error maximum total difference before returning error",
+ "-metric comparison metric (MAE, MSE, PAE, PSNR, RMSE)",
+ "-monitor show progress indication",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-size geometry width and height of image",
+ "-type type image type",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ (char *) NULL
+ };
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] reference [options ...] compare"
+ " [options ...]\n",GetClientName());
+ (void) printf("\nWhere options include:\n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o m p o s i t e I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CompositeImageCommand() reads one or more images and an optional mask and
+% composites them into a new image.
+%
+% The format of the CompositeImageCommand method is:
+%
+% MagickPassFail CompositeImageCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail CompositeImageList(ImageInfo *image_info,Image **image,
+ Image *composite_image,Image *mask_image,CompositeOptions *option_info,
+ ExceptionInfo *exception)
+{
+ long
+ x,
+ y;
+
+ unsigned int
+ matte,
+ status;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image **) NULL);
+ assert((*image)->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ status=MagickPass;
+ if (composite_image != (Image *) NULL)
+ {
+ assert(composite_image->signature == MagickSignature);
+ if (mask_image != (Image *) NULL)
+ {
+ assert(mask_image->signature == MagickSignature);
+ (void) SetImageType(composite_image,TrueColorMatteType);
+ if (!composite_image->matte)
+ SetImageOpacity(composite_image,OpaqueOpacity);
+ status&=CompositeImage(composite_image,CopyOpacityCompositeOp,
+ mask_image,0,0);
+ if (status == MagickFail)
+ GetImageException(composite_image,exception);
+ }
+ if (option_info->compose == DissolveCompositeOp)
+ {
+ register PixelPacket
+ *q;
+
+ /*
+ Create mattes for dissolve.
+ */
+ if (!composite_image->matte)
+ SetImageOpacity(composite_image,OpaqueOpacity);
+ for (y=0; y < (long) composite_image->rows; y++)
+ {
+ q=GetImagePixels(composite_image,0,y,composite_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) composite_image->columns; x++)
+ {
+ q->opacity=(Quantum)
+ ((((unsigned long) MaxRGB-q->opacity)*option_info->dissolve)/100.0);
+ q++;
+ }
+ if (!SyncImagePixels(composite_image))
+ break;
+ }
+ }
+ if (option_info->compose == DisplaceCompositeOp)
+ (void) CloneString(&composite_image->geometry,
+ option_info->displace_geometry);
+ if (option_info->compose == ModulateCompositeOp)
+ (void) CloneString(&composite_image->geometry,
+ option_info->watermark_geometry);
+ if (option_info->compose == ThresholdCompositeOp)
+ (void) CloneString(&composite_image->geometry,
+ option_info->unsharp_geometry);
+ /*
+ Composite image.
+ */
+ matte=(*image)->matte;
+ if (option_info->stegano != 0)
+ {
+ Image
+ *stegano_image;
+
+ (*image)->offset=option_info->stegano-1;
+ stegano_image=SteganoImage(*image,composite_image,exception);
+ if (stegano_image != (Image *) NULL)
+ {
+ DestroyImageList(*image);
+ *image=stegano_image;
+ }
+ }
+ else
+ if (option_info->stereo)
+ {
+ Image
+ *stereo_image;
+
+ stereo_image=StereoImage(*image,composite_image,exception);
+ if (stereo_image != (Image *) NULL)
+ {
+ DestroyImageList(*image);
+ *image=stereo_image;
+ }
+ }
+ else
+ if (option_info->tile)
+ {
+ /*
+ Tile the composite image.
+ */
+ for (y=0; y < (long) (*image)->rows; y+=composite_image->rows)
+ for (x=0; x < (long) (*image)->columns; x+=composite_image->columns)
+ {
+ status&=CompositeImage(*image,option_info->compose,
+ composite_image,x,y);
+ GetImageException(*image,exception);
+ }
+ }
+ else
+ {
+ char
+ composite_geometry[MaxTextExtent];
+
+ RectangleInfo
+ geometry;
+
+ /*
+ Digitally composite image.
+ */
+ geometry.x=0;
+ geometry.y=0;
+ (void) GetGeometry(option_info->geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ FormatString(composite_geometry,"%lux%lu%+ld%+ld",
+ composite_image->columns,composite_image->rows,geometry.x,
+ geometry.y);
+ (*image)->gravity=option_info->gravity;
+ (void) GetImageGeometry(*image,composite_geometry,MagickFalse,
+ &geometry);
+ status&=CompositeImage(*image,option_info->compose,
+ composite_image,geometry.x,geometry.y);
+ GetImageException(*image,exception);
+ }
+ if (option_info->compose != CopyOpacityCompositeOp)
+ (*image)->matte=matte;
+ }
+ return(status);
+}
+
+static void LiberateCompositeOptions(CompositeOptions *option_info)
+{
+ MagickFreeMemory(option_info->displace_geometry);
+ MagickFreeMemory(option_info->geometry);
+ MagickFreeMemory(option_info->unsharp_geometry);
+ MagickFreeMemory(option_info->watermark_geometry);
+}
+
+#define NotInitialized (unsigned int) (~0)
+#define ThrowCompositeException(code,reason,description) \
+{ \
+ LiberateCompositeOptions(&option_info); \
+ DestroyImageList(image); \
+ DestroyImageList(composite_image); \
+ DestroyImageList(mask_image); \
+ ThrowException(exception,code,reason,description); \
+ LiberateArgumentList(argc,argv); \
+ return(MagickFail); \
+}
+#define ThrowCompositeException3(code,reason,description) \
+{ \
+ LiberateCompositeOptions(&option_info); \
+ DestroyImageList(image); \
+ DestroyImageList(composite_image); \
+ DestroyImageList(mask_image); \
+ ThrowException3(exception,code,reason,description); \
+ LiberateArgumentList(argc,argv); \
+ return(MagickFail); \
+}
+MagickExport MagickPassFail CompositeImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ char
+ *filename,
+ *format,
+ *option;
+
+ CompositeOptions
+ option_info;
+
+ Image
+ *composite_image,
+ *image,
+ *mask_image;
+
+ long
+ j,
+ x;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ /*
+ Set default.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ status=MagickPass;
+
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ CompositeUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ (void) memset(&option_info,0,sizeof(CompositeOptions));
+ option_info.dissolve=0.0;
+ option_info.compose=OverCompositeOp;
+ composite_image=NewImageList();
+ option_info.displace_geometry=(char *) NULL;
+ filename=(char *) NULL;
+ format=(char *) NULL;
+ option_info.geometry=(char *) NULL;
+ image=NewImageList();
+ (void) strlcpy(image_info->filename,argv[argc-1],MaxTextExtent);
+ (void) SetImageInfo(image_info,SETMAGICK_WRITE,exception);
+ mask_image=NewImageList();
+ option_info.stegano=0;
+ option_info.stereo=MagickFalse;
+ option_info.tile=MagickFalse;
+ option_info.watermark_geometry=(char *) NULL;
+ option_info.unsharp_geometry=(char *) NULL;
+ status=MagickPass;
+ /*
+ Check command syntax.
+ */
+ j=1;
+ for (i=1; i < (argc-1); i++)
+ {
+ option=argv[i];
+ if ((strlen(option) < 2) ||
+ /* stdin + subexpression */
+ ((option[0] == '-') && (option[1] == '[')) ||
+ ((option[0] != '-') && option[0] != '+'))
+ {
+ /*
+ Read input images.
+ */
+ filename=argv[i];
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ if (composite_image == (Image *) NULL)
+ {
+ composite_image=ReadImage(image_info,exception);
+ if (composite_image != (Image *) NULL)
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&composite_image);
+ GetImageException(composite_image,exception);
+ }
+ j=i+1;
+ continue;
+ }
+ if (mask_image != (Image *) NULL)
+ ThrowCompositeException(OptionError,InputImagesAlreadySpecified,
+ filename);
+ if (image == (Image *) NULL)
+ {
+ image=ReadImage(image_info,exception);
+ if (image != (Image *) NULL)
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image);
+ GetImageException(image,exception);
+ }
+ j=i+1;
+ continue;
+ }
+ mask_image=ReadImage(image_info,exception);
+ status&=mask_image != (Image *) NULL;
+ if (mask_image != (Image *) NULL)
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&mask_image);
+ GetImageException(mask_image,exception);
+ }
+ j=i+1;
+ continue;
+ }
+ switch(*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("affine",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("authenticate",option+1) == 0)
+ {
+ (void) CloneString(&image_info->authenticate,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->authenticate,argv[i]);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'b':
+ {
+ if (LocaleCompare("background",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ (void) QueryColorDatabase(argv[i],&image_info->background_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("blue-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'c':
+ {
+ if (LocaleCompare("colors",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ image_info->colorspace=RGBColorspace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->colorspace=StringToColorspaceType(option);
+ if (image_info->colorspace == UndefinedColorspace)
+ ThrowCompositeException(OptionError,UnrecognizedColorspace,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("comment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("compose",option+1) == 0)
+ {
+ option_info.compose=CopyCompositeOp;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ option_info.compose=StringToCompositeOperator(option);
+ if (option_info.compose == UndefinedCompositeOp)
+ ThrowCompositeException(OptionError,UnrecognizedComposeOperator,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ image_info->compression=NoCompression;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->compression=StringToCompressionType(option);
+ if (image_info->compression == UndefinedCompression)
+ ThrowCompositeException(OptionError,UnrecognizedImageCompression,
+ option);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'd':
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("displace",option+1) == 0)
+ {
+ (void) CloneString(&option_info.displace_geometry,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&option_info.displace_geometry,argv[i]);
+ option_info.compose=DisplaceCompositeOp;
+ }
+ break;
+ }
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ (void) CloneString(&image_info->server_name,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->server_name,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("dispose",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ option=argv[i];
+ if ((LocaleCompare("0",option) != 0) &&
+ (LocaleCompare("1",option) != 0) &&
+ (LocaleCompare("2",option) != 0) &&
+ (LocaleCompare("3",option) != 0) &&
+ (LocaleCompare("Undefined",option) != 0) &&
+ (LocaleCompare("None",option) != 0) &&
+ (LocaleCompare("Background",option) != 0) &&
+ (LocaleCompare("Previous",option) != 0))
+ ThrowCompositeException(OptionError,UnrecognizedDisposeMethod,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("dissolve",option+1) == 0)
+ {
+ option_info.dissolve=0.0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ option_info.dissolve=MagickAtoF(argv[i]);
+ option_info.compose=DissolveCompositeOp;
+ }
+ break;
+ }
+ if (LocaleCompare("dither",option+1) == 0)
+ {
+ image_info->dither=(*option == '-');
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'e':
+ {
+ if (LocaleCompare("encoding",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("endian",option+1) == 0)
+ {
+ image_info->endian=UndefinedEndian;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->endian=StringToEndianType(option);
+ if (image_info->endian == UndefinedEndian)
+ ThrowCompositeException(OptionError,UnrecognizedEndianType,
+ option);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'f':
+ {
+ if (LocaleCompare("filter",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ FilterTypes
+ filter;
+
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ filter=StringToFilterTypes(option);
+ if (filter == UndefinedFilter)
+ ThrowCompositeException(OptionError,UnrecognizedImageFilter,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("font",option+1) == 0)
+ {
+ (void) CloneString(&image_info->font,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->font,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("format",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ format=argv[i];
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'g':
+ {
+ if (LocaleCompare("geometry",option+1) == 0)
+ {
+ (void) CloneString(&option_info.geometry,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&option_info.geometry,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("gravity",option+1) == 0)
+ {
+ option_info.gravity=ForgetGravity;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ option_info.gravity=StringToGravityType(option);
+ if (option_info.gravity == ForgetGravity)
+ ThrowCompositeException(OptionError,UnrecognizedGravityType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("green-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'h':
+ {
+ if (LocaleCompare("help",option+1) == 0)
+ {
+ CompositeUsage();
+ break;
+ /* ThrowCompositeException(OptionError,UsageError,NULL); */
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'i':
+ {
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ image_info->interlace=UndefinedInterlace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ ThrowCompositeException(OptionError,UnrecognizedInterlaceType,
+ option);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'l':
+ {
+ if (LocaleCompare("label",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ ThrowCompositeException(OptionError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'm':
+ {
+ if (LocaleCompare("matte",option+1) == 0)
+ break;
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ if (LocaleCompare("monochrome",option+1) == 0)
+ break;
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'n':
+ {
+ if (LocaleCompare("negate",option+1) == 0)
+ break;
+ if (LocaleCompare("noop",option+1) == 0)
+ {
+ status&=CompositeImageList(image_info,&image,composite_image,
+ mask_image,&option_info,exception);
+ if (composite_image != (Image *) NULL)
+ {
+ DestroyImageList(composite_image);
+ composite_image=NewImageList();
+ }
+ if (mask_image != (Image *) NULL)
+ {
+ DestroyImageList(mask_image);
+ mask_image=NewImageList();
+ }
+ GetImageException(image,exception);
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'p':
+ {
+ if (LocaleCompare("page",option+1) == 0)
+ {
+ (void) CloneString(&image_info->page,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ image_info->page=GetPageGeometry(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("process",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("profile",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'q':
+ {
+ if (LocaleCompare("quality",option+1) == 0)
+ {
+ image_info->quality=DefaultCompressionQuality;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ image_info->quality=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'r':
+ {
+ if (LocaleCompare("recolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("red-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("render",option+1) == 0)
+ break;
+ if (LocaleCompare("repage",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("resize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("rotate",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 's':
+ {
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("scene",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("set",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ if (*option == '-')
+ {
+ /* -set attribute value */
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("sharpen",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("stegano",option+1) == 0)
+ {
+ option_info.stegano=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option_info.stegano=MagickAtoL(argv[i])+1;
+ }
+ break;
+ }
+ if (LocaleCompare("stereo",option+1) == 0)
+ {
+ option_info.stereo=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("strip",option+1) == 0)
+ {
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 't':
+ {
+ if (LocaleCompare("thumbnail",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("tile",option+1) == 0)
+ {
+ option_info.tile=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("transform",option+1) == 0)
+ break;
+ if (LocaleCompare("treedepth",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowCompositeException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ image_info->type=UndefinedType;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->type=StringToImageType(option);
+ if (image_info->type == UndefinedType)
+ ThrowCompositeException(OptionError,UnrecognizedImageType,
+ option);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'u':
+ {
+ if (LocaleCompare("units",option+1) == 0)
+ {
+ image_info->units=UndefinedResolution;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->units=UndefinedResolution;
+ if (LocaleCompare("PixelsPerInch",option) == 0)
+ image_info->units=PixelsPerInchResolution;
+ if (LocaleCompare("PixelsPerCentimeter",option) == 0)
+ image_info->units=PixelsPerCentimeterResolution;
+ }
+ break;
+ }
+ if (LocaleCompare("unsharp",option+1) == 0)
+ {
+ (void) CloneString(&option_info.unsharp_geometry,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&option_info.unsharp_geometry,argv[i]);
+ option_info.compose=ThresholdCompositeOp;
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("verbose",option+1) == 0)
+ break;
+ if (LocaleCompare("virtual-pixel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ option=argv[i];
+ virtual_pixel_method=StringToVirtualPixelMethod(option);
+ if (virtual_pixel_method == UndefinedVirtualPixelMethod)
+ ThrowCompositeException(OptionError,UnrecognizedVirtualPixelMethod,option);
+ }
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case 'w':
+ {
+ if (LocaleCompare("watermark",option+1) == 0)
+ {
+ (void) CloneString(&option_info.watermark_geometry,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ (void) CloneString(&option_info.watermark_geometry,argv[i]);
+ option_info.compose=ModulateCompositeOp;
+ }
+ break;
+ }
+ if (LocaleCompare("white-point",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("write",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowCompositeException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ case '?':
+ break;
+ default:
+ ThrowCompositeException(OptionError,UnrecognizedOption,option)
+ }
+ }
+ if (image == (Image *) NULL)
+ {
+ if (exception->severity == UndefinedException)
+ ThrowCompositeException(OptionError,RequestDidNotReturnAnImage,
+ (char *) NULL);
+ return(MagickFail);
+ }
+ if (i != (argc-1))
+ ThrowCompositeException(OptionError,MissingAnImageFilename,(char *) NULL);
+ status&=MogrifyImages(image_info,i-j,argv+j,&image);
+ GetImageException(image,exception);
+ status&=CompositeImageList(image_info,&image,composite_image,mask_image,
+ &option_info,exception);
+ /*
+ Write composite images.
+ */
+ status&=WriteImages(image_info,image,argv[argc-1],exception);
+ if (metadata != (char **) NULL)
+ {
+ char
+ *text;
+
+ text=TranslateText(image_info,image,(format != (char *) NULL) ? format : "%w,%h,%m");
+ if (text == (char *) NULL)
+ ThrowCompositeException(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(OptionError,UnableToFormatImageMetadata));
+ (void) ConcatenateString(&(*metadata),text);
+ (void) ConcatenateString(&(*metadata),"\n");
+ MagickFreeMemory(text);
+ }
+ LiberateCompositeOptions(&option_info);
+ DestroyImageList(composite_image);
+ DestroyImageList(mask_image);
+ DestroyImageList(image);
+ LiberateArgumentList(argc,argv);
+ return(status);
+}
+#undef ThrowCompositeException
+#undef ThrowCompositeException3
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o m p o s i t e U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CompositeUsage() displays the program command syntax.
+%
+% The format of the CompositeUsage method is:
+%
+% void CompositeUsage()
+%
+%
+*/
+static void CompositeUsage(void)
+{
+ const char
+ **p;
+
+ static const char
+ *options[]=
+ {
+ "-affine matrix affine transform matrix",
+ "-authenticate value decrypt image with this password",
+ "-blue-primary point chomaticity blue primary point",
+ "-colors value preferred number of colors in the image",
+ "-colorspace type alternate image colorspace",
+ "-comment string annotate image with comment",
+ "-compose operator composite operator",
+ "-compress type image compression type",
+ "-debug events display copious debugging information",
+ "-define values Coder/decoder specific options",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-displace geometry shift image pixels defined by a displacement map",
+ "-display server get image or font from this X server",
+ "-dispose method Undefined, None, Background, Previous",
+ "-dissolve value dissolve the two images a given percent",
+ "-dither apply Floyd/Steinberg error diffusion to image",
+ "-encoding type text encoding type",
+ "-endian type multibyte word order (LSB, MSB, or Native)",
+ "-filter type use this filter when resizing an image",
+ "-font name render text with this font",
+ "-geometry geometry location of the composite image",
+ "-gravity type which direction to gravitate towards",
+ "-green-primary point chomaticity green primary point",
+ "-help print program options",
+ "-interlace type None, Line, Plane, or Partition",
+ "-label name ssign a label to an image",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-log format format of debugging information",
+ "-matte store matte channel if the image has one",
+ "-monitor show progress indication",
+ "-monochrome transform image to black and white",
+ "-negate replace every pixel with its complementary color ",
+ "+page reset current page offsets to default",
+ "-page geometry size and location of an image canvas",
+ "-profile filename add ICM or IPTC information profile to image",
+ "-quality value JPEG/MIFF/PNG compression level",
+ "-recolor matrix apply a color translation matrix to image channels",
+ "-red-primary point chomaticity red primary point",
+ "-rotate degrees apply Paeth rotation to the image",
+ "+repage reset current page offsets to default",
+ "-repage geometry adjust current page offsets by geometry",
+ "-resize geometry resize the image",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-scene value image scene number",
+ "-set attribute value set image attribute",
+ "+set attribute unset image attribute",
+ "-sharpen geometry sharpen the image",
+ "-size geometry width and height of image",
+ "-stegano offset hide watermark within an image",
+ "-stereo combine two image to create a stereo anaglyph",
+ "-strip strip all profiles and text attributes from image",
+ "-thumbnail geometry resize the image (optimized for thumbnails)",
+ "-tile repeat composite operation across image",
+ "-transform affine transform image",
+ "-treedepth value color tree depth",
+ "-type type image type",
+ "-units type PixelsPerInch, PixelsPerCentimeter, or Undefined",
+ "-unsharp geometry sharpen the image",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ "-virtual-pixel method",
+ " Constant, Edge, Mirror, or Tile",
+ "-watermark geometry percent brightness and saturation of a watermark",
+ "-white-point point chomaticity white point",
+ "-write filename write image to this file",
+ (char *) NULL
+ };
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] image [options ...] composite\n"
+ " [ [options ...] mask ] [options ...] composite\n",GetClientName());
+ (void) printf("\nWhere options include:\n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o n v e r t I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ConvertImageCommand() reads one or more images, applies one or more image
+% processing operations, and writes out the image in the same or differing
+% format.
+%
+% The format of the ConvertImageCommand method is:
+%
+% unsigned int ConvertImageCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+static MagickPassFail ConcatenateImages(const int argc,char **argv,
+ ExceptionInfo *exception)
+{
+ FILE
+ *input,
+ *output;
+
+ int
+ c;
+
+ register long
+ i;
+
+ /*
+ Open output file.
+ */
+ output=fopen(argv[argc-1],"wb");
+ if (output == (FILE *) NULL)
+ {
+ ThrowException(exception,FileOpenError,UnableToOpenFile,argv[argc-1]);
+ return(MagickFail);
+ }
+ for (i=2; i < (argc-1); i++)
+ {
+ input=fopen(argv[i],"rb");
+ if (input == (FILE *) NULL)
+ {
+ ThrowException(exception,FileOpenError,UnableToOpenFile,argv[i]);
+ continue;
+ }
+ for (c=fgetc(input); c != EOF; c=fgetc(input))
+ (void) fputc((char) c,output);
+ (void) fclose(input);
+ (void) remove(argv[i]);
+ }
+ (void) fclose(output);
+ return(MagickPass);
+}
+
+#define NotInitialized (unsigned int) (~0)
+
+#define ThrowConvertException(code,reason,description) \
+{ \
+ status = MagickFail; \
+ ThrowException(exception,code,reason,description); \
+ goto convert_cleanup_and_return; \
+}
+#define ThrowConvertException3(code,reason,description) \
+{ \
+ status = MagickFail; \
+ ThrowException3(exception,code,reason,description); \
+ goto convert_cleanup_and_return; \
+}
+
+MagickExport MagickPassFail ConvertImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ char
+ *filename,
+ *format,
+ *option;
+
+ double
+ sans;
+
+ Image
+ *image = (Image *) NULL,
+ *image_list = (Image *) NULL,
+ *next_image = (Image *) NULL;
+
+ long
+ j,
+ k,
+ x;
+
+ register int
+ i;
+
+ unsigned int
+ ping,
+ status = 0;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ ConvertUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ /*
+ Set defaults.
+ */
+ filename=(char *) NULL;
+ format=(char *) NULL;
+ image=NewImageList();
+ image_list=(Image *) NULL;
+ (void) strlcpy(image_info->filename,argv[argc-1],MaxTextExtent);
+ (void) SetImageInfo(image_info,SETMAGICK_WRITE,exception);
+ ping=MagickFalse;
+ option=(char *) NULL;
+ status=MagickPass;
+ /*
+ Parse command-line arguments.
+ */
+ if ((argc > 2) && (LocaleCompare("-concatenate",argv[1]) == 0))
+ return(ConcatenateImages(argc,argv,exception));
+ j=1;
+ k=0;
+ for (i=1; i < (argc-1); i++)
+ {
+ option=argv[i];
+ if ((strlen(option) < 2) ||
+ /* stdin + subexpression */
+ ((option[0] == '-') && (option[1] == '[')) ||
+ ((option[0] != '-') && option[0] != '+'))
+ {
+ /*
+ Read input image.
+ */
+ k=i;
+ filename=argv[i];
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ if (ping)
+ next_image=PingImage(image_info,exception);
+ else
+ next_image=ReadImage(image_info,exception);
+ status&=(next_image != (Image *) NULL) &&
+ (exception->severity < ErrorException);
+ if (next_image == (Image *) NULL)
+ continue;
+ if (image == (Image *) NULL)
+ {
+ image=next_image;
+ continue;
+ }
+ AppendImageToList(&image,next_image);
+ continue;
+ }
+ if ((image != (Image *) NULL) && (j != (k+1)))
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image);
+ GetImageException(image,exception);
+ AppendImageToList(&image_list,image);
+ image=NewImageList();
+ j=k+1;
+ }
+ switch (*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("adjoin",option+1) == 0)
+ {
+ image_info->adjoin=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("affine",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("antialias",option+1) == 0)
+ {
+ image_info->antialias=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("append",option+1) == 0)
+ {
+ break;
+ }
+ if (LocaleCompare("asc-cdl",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("authenticate",option+1) == 0)
+ {
+ (void) CloneString(&image_info->authenticate,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->authenticate,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("auto-orient",option+1) == 0)
+ break;
+ if (LocaleCompare("average",option+1) == 0)
+ break;
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'b':
+ {
+ if (LocaleCompare("background",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ (void) QueryColorDatabase(argv[i],&image_info->background_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("black-threshold",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("blue-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("blur",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("border",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("bordercolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ (void) QueryColorDatabase(argv[i],&image_info->border_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("box",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'c':
+ {
+ if (LocaleCompare("channel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ChannelType
+ channel;
+
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ channel=StringToChannelType(argv[i]);
+ if (channel == UndefinedChannel)
+ ThrowConvertException(OptionError,UnrecognizedChannelType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("charcoal",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("chop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("clip",option+1) == 0)
+ break;
+ if (LocaleCompare("clippath",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ break;
+ }
+ if (LocaleCompare("coalesce",option+1) == 0)
+ break;
+ if (LocaleCompare("colorize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("compose",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ if ((StringToCompositeOperator(option)) == UndefinedCompositeOp)
+ ThrowConvertException(OptionError,UnrecognizedComposeOperator,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("colors",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ if ((*option == '-') || (*option == '+'))
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->colorspace=StringToColorspaceType(option);
+ if (image_info->colorspace == UndefinedColorspace)
+ ThrowConvertException(OptionError,UnrecognizedColorspace,option);
+ }
+ break;
+ }
+ if (LocaleCompare("comment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ image_info->compression=NoCompression;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->compression=StringToCompressionType(option);
+ if (image_info->compression == UndefinedCompression)
+ ThrowConvertException(OptionError,UnrecognizedImageCompression,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("contrast",option+1) == 0)
+ break;
+ if (LocaleCompare("convolve",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == (argc-1))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("crop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("cycle",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'd':
+ {
+ if (LocaleCompare("deconstruct",option+1) == 0)
+ break;
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("delay",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("despeckle",option+1) == 0)
+ break;
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ (void) CloneString(&image_info->server_name,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->server_name,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("dispose",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ option=argv[i];
+ if ((LocaleCompare("0",option) != 0) &&
+ (LocaleCompare("1",option) != 0) &&
+ (LocaleCompare("2",option) != 0) &&
+ (LocaleCompare("3",option) != 0) &&
+ (LocaleCompare("Undefined",option) != 0) &&
+ (LocaleCompare("None",option) != 0) &&
+ (LocaleCompare("Background",option) != 0) &&
+ (LocaleCompare("Previous",option) != 0))
+ ThrowConvertException(OptionError,UnrecognizedDisposeMethod,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("dither",option+1) == 0)
+ {
+ image_info->dither=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("draw",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'e':
+ {
+ if (LocaleCompare("edge",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("emboss",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("encoding",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("endian",option+1) == 0)
+ {
+ image_info->endian=UndefinedEndian;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->endian=StringToEndianType(option);
+ if (image_info->endian == UndefinedEndian)
+ ThrowConvertException(OptionError,UnrecognizedEndianType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("enhance",option+1) == 0)
+ break;
+ if (LocaleCompare("equalize",option+1) == 0)
+ break;
+ if (LocaleCompare("extent",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'f':
+ {
+ if (LocaleCompare("fill",option+1) == 0)
+ {
+ (void) QueryColorDatabase("none",&image_info->pen,exception);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) QueryColorDatabase(argv[i],&image_info->pen,exception);
+ }
+ break;
+ }
+ if (LocaleCompare("filter",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ FilterTypes
+ filter;
+
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ filter=StringToFilterTypes(option);
+ if (filter == UndefinedFilter)
+ ThrowConvertException(OptionError,UnrecognizedImageFilter,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("flatten",option+1) == 0)
+ break;
+ if (LocaleCompare("flip",option+1) == 0)
+ break;
+ if (LocaleCompare("flop",option+1) == 0)
+ break;
+ if (LocaleCompare("font",option+1) == 0)
+ {
+ (void) CloneString(&image_info->font,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->font,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("format",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ format=argv[i];
+ /*
+ Add definition to defines for use by 'info' coder.
+ */
+ (void) AddDefinition(image_info,"info","format",format,exception);
+ }
+ break;
+ }
+ if (LocaleCompare("frame",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("fuzz",option+1) == 0)
+ {
+ image_info->fuzz=0.0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ image_info->fuzz=StringToDouble(argv[i],MaxRGB);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'g':
+ {
+ if (LocaleCompare("gamma",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if ((LocaleCompare("gaussian",option+1) == 0) ||
+ (LocaleCompare("gaussian-blur",option+1) == 0))
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("geometry",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("gravity",option+1) == 0)
+ {
+ GravityType
+ gravity;
+
+ gravity=ForgetGravity;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ gravity=StringToGravityType(option);
+ if (gravity == ForgetGravity)
+ ThrowConvertException(OptionError,UnrecognizedGravityType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("green-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'h':
+ {
+ if (LocaleCompare("hald-clut",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("help",option+1) == 0)
+ {
+ ConvertUsage();
+ break;
+ /* ThrowConvertException(OptionError,UsageError,NULL); */
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'i':
+ {
+ if (LocaleCompare("implode",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("intent",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ RenderingIntent
+ rendering_intent;
+
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ rendering_intent=UndefinedIntent;
+ if (LocaleCompare("Absolute",option) == 0)
+ rendering_intent=AbsoluteIntent;
+ if (LocaleCompare("Perceptual",option) == 0)
+ rendering_intent=PerceptualIntent;
+ if (LocaleCompare("Relative",option) == 0)
+ rendering_intent=RelativeIntent;
+ if (LocaleCompare("Saturation",option) == 0)
+ rendering_intent=SaturationIntent;
+ if (rendering_intent == UndefinedIntent)
+ ThrowConvertException(OptionError,UnrecognizedIntentType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ image_info->interlace=UndefinedInterlace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ ThrowConvertException(OptionError,UnrecognizedInterlaceType,
+ option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'l':
+ {
+ if (LocaleCompare("label",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("lat",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("level",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("linewidth",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ ThrowConvertException(OptionError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("list",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ switch (*option)
+ {
+ case 'C':
+ case 'c':
+ {
+ if ((LocaleCompare("Color",option) == 0) ||
+ (LocaleCompare("Colors",option) == 0))
+ {
+ (void) ListColorInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'D':
+ case 'd':
+ {
+ if ((LocaleCompare("Delegate",option) == 0) ||
+ (LocaleCompare("Delegates",option) == 0))
+ {
+ (void) ListDelegateInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'F':
+ case 'f':
+ {
+ if ((LocaleCompare("Font",option) == 0) ||
+ (LocaleCompare("Fonts",option) == 0))
+ {
+ (void) ListTypeInfo((FILE *) NULL,exception);
+ break;
+ }
+ if ((LocaleCompare("Format",option) == 0) ||
+ (LocaleCompare("Formats",option) == 0))
+ {
+ (void) ListMagickInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare("Magic",option) == 0)
+ {
+ (void) ListMagicInfo((FILE *) NULL,exception);
+ break;
+ }
+#if defined(SupportMagickModules)
+ if ((LocaleCompare("Module",option) == 0) ||
+ (LocaleCompare("Modules",option) == 0))
+ {
+ (void) ListModuleInfo((FILE *) NULL,exception);
+ break;
+ }
+#endif /* SupportMagickModules */
+ if (LocaleCompare("ModuleMap",option) == 0)
+ {
+ (void) ListModuleMap((FILE *) NULL,exception);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'R':
+ case 'r':
+ {
+ if ((LocaleCompare("Resource",option) == 0) ||
+ (LocaleCompare("Resource",option)))
+ {
+ (void) ListMagickResourceInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare("Type",option) == 0)
+ {
+ (void) ListTypeInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedListType,
+ option)
+ }
+ default:
+ ThrowConvertException(OptionError,UnrecognizedListType,
+ option)
+ }
+ status=MagickPass;
+ goto convert_cleanup_and_return;
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("loop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'm':
+ {
+ if (LocaleCompare("magnify",option+1) == 0)
+ break;
+ if (LocaleCompare("map",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("mask",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("matte",option+1) == 0)
+ break;
+ if (LocaleCompare("mattecolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) QueryColorDatabase(argv[i],&image_info->matte_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("median",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("minify",option+1) == 0)
+ break;
+ if (LocaleCompare("modulate",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ if (LocaleCompare("monochrome",option+1) == 0)
+ {
+ image_info->monochrome=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("morph",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("mosaic",option+1) == 0)
+ break;
+ if (LocaleCompare("motion-blur",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'n':
+ {
+ if (LocaleCompare("negate",option+1) == 0)
+ break;
+ if (LocaleCompare("noise",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ if (*option == '+')
+ {
+ NoiseType
+ noise_type;
+
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ noise_type=StringToNoiseType(option);
+ if (UndefinedNoise == noise_type)
+ ThrowConvertException(OptionError,UnrecognizedNoiseType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("noop",option+1) == 0)
+ break;
+ if (LocaleCompare("normalize",option+1) == 0)
+ break;
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'o':
+ {
+ if (LocaleCompare("opaque",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("operator",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ChannelType
+ channel;
+
+ QuantumOperator
+ quantum_operator;
+
+ double
+ rvalue;
+
+ /* channel */
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ channel=StringToChannelType(argv[i]);
+ if (channel == UndefinedChannel)
+ ThrowConvertException(OptionError,UnrecognizedChannelType,
+ option);
+
+ /* operator id */
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ quantum_operator=StringToQuantumOperator(argv[i]);
+ if (quantum_operator == UndefinedQuantumOp)
+ ThrowConvertException(OptionError,UnrecognizedOperator,
+ option);
+
+ /* rvalue */
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&rvalue))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("ordered-dither",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("orient",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'p':
+ {
+ if (LocaleCompare("page",option+1) == 0)
+ {
+ (void) CloneString(&image_info->page,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ image_info->page=GetPageGeometry(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("paint",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("ping",option+1) == 0)
+ {
+ ping=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("pointsize",option+1) == 0)
+ {
+ image_info->pointsize=12;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ image_info->pointsize=MagickAtoF(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("preview",option+1) == 0)
+ {
+ image_info->preview_type=UndefinedPreview;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->preview_type=StringToPreviewType(option);
+ if (image_info->preview_type == UndefinedPreview)
+ ThrowConvertException(OptionError,UnrecognizedPreviewType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("process",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("profile",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'q':
+ {
+ if (LocaleCompare("quality",option+1) == 0)
+ {
+ image_info->quality=DefaultCompressionQuality;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ image_info->quality=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'r':
+ {
+ if (LocaleCompare("raise",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("random-threshold",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("recolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("red-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("region",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("render",option+1) == 0)
+ break;
+ if (LocaleCompare("repage",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("resample",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == (argc-1)) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("resize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("roll",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("rotate",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 's':
+ {
+ if (LocaleCompare("sample",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("scale",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("scene",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("segment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("set",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ if (*option == '-')
+ {
+ /* -set attribute value */
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("shade",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("sharpen",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("shave",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("shear",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("solarize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("spread",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("strip",option+1) == 0)
+ {
+ break;
+ }
+ if (LocaleCompare("stroke",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("strokewidth",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("swirl",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 't':
+ {
+ if (LocaleCompare("temporary",option+1) == 0)
+ {
+ image_info->temporary=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("texture",option+1) == 0)
+ {
+ (void) CloneString(&image_info->texture,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->texture,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("thumbnail",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("threshold",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("tile",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("transform",option+1) == 0)
+ break;
+ if (LocaleCompare("transparent",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("treedepth",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("trim",option+1) == 0)
+ break;
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ image_info->type=UndefinedType;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->type=StringToImageType(option);
+ if (image_info->type == UndefinedType)
+ ThrowConvertException(OptionError,UnrecognizedImageType,option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'u':
+ {
+ if (LocaleCompare("undercolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("units",option+1) == 0)
+ {
+ image_info->units=UndefinedResolution;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->units=UndefinedResolution;
+ if (LocaleCompare("PixelsPerInch",option) == 0)
+ image_info->units=PixelsPerInchResolution;
+ if (LocaleCompare("PixelsPerCentimeter",option) == 0)
+ image_info->units=PixelsPerCentimeterResolution;
+ }
+ break;
+ }
+ if (LocaleCompare("unsharp",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("verbose",option+1) == 0)
+ break;
+ if (LocaleCompare("view",option+1) == 0)
+ {
+ (void) CloneString(&image_info->view,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->view,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("virtual-pixel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,
+ option);
+ option=argv[i];
+ virtual_pixel_method=StringToVirtualPixelMethod(option);
+ if (virtual_pixel_method == UndefinedVirtualPixelMethod)
+ ThrowConvertException(OptionError,UnrecognizedVirtualPixelMethod,option);
+ }
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case 'w':
+ {
+ if (LocaleCompare("wave",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("white-point",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("white-threshold",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowConvertException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("write",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowConvertException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowConvertException(OptionError,UnrecognizedOption,option)
+ }
+ case '?':
+ {
+ ConvertUsage();
+ break;
+ /* ThrowConvertException(OptionError,UsageError,NULL); */
+ }
+ default:
+ {
+ ThrowConvertException(OptionError,UnrecognizedOption,option);
+ }
+ }
+ }
+ if ((image == (Image *) NULL) && (image_list == (Image *) NULL))
+ {
+ if (exception->severity == UndefinedException)
+ ThrowConvertException(OptionError,RequestDidNotReturnAnImage,
+ (char *) NULL);
+ status = MagickFail;
+ goto convert_cleanup_and_return;
+ }
+ if (i != (argc-1))
+ ThrowConvertException(OptionError,MissingAnImageFilename,(char *) NULL);
+ if (image == (Image *) NULL)
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image_list);
+ GetImageException(image_list,exception);
+ }
+ else
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image);
+ GetImageException(image,exception);
+ AppendImageToList(&image_list,image);
+ }
+ status&=WriteImages(image_info,image_list,argv[argc-1],exception);
+ if (metadata != (char **) NULL)
+ {
+ char
+ *text;
+
+ /*
+ Return formatted string with image characteristics if metadata
+ is requested.
+ */
+ text=TranslateText(image_info,image_list,(format != (char *) NULL) ? format : "%w,%h,%m");
+ if (text == (char *) NULL)
+ ThrowConvertException(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(OptionError,UnableToFormatImageMetadata));
+ (void) ConcatenateString(&(*metadata),text);
+ (void) ConcatenateString(&(*metadata),"\n");
+ MagickFreeMemory(text);
+ }
+ convert_cleanup_and_return:
+ DestroyImageList(image_list);
+ LiberateArgumentList(argc,argv);
+ return(status);
+}
+#undef ThrowConvertException
+#undef ThrowConvertException3
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o n v e r t U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure ConvertUsage displays the program command syntax.
+%
+% The format of the ConvertUsage method is:
+%
+% void ConvertUsage()
+%
+*/
+static void ConvertUsage(void)
+{
+ static const char
+ *options[]=
+ {
+ "-adjoin join images into a single multi-image file",
+ "-affine matrix affine transform matrix",
+ "-antialias remove pixel-aliasing",
+ "-append append an image sequence",
+ "-asc-cdl spec apply ASC CDL transform",
+ "-authenticate value decrypt image with this password",
+ "-auto-orient orient (rotate) image so it is upright",
+ "-average average an image sequence",
+ "-background color background color",
+ "-black-threshold value",
+ " pixels below the threshold become black",
+ "-blue-primary point chomaticity blue primary point",
+ "-blur geometry blur the image",
+ "-border geometry surround image with a border of color",
+ "-bordercolor color border color",
+ "-box color set the color of the annotation bounding box",
+ "-channel type extract a particular color channel from image",
+ "-charcoal radius simulate a charcoal drawing",
+ "-chop geometry remove pixels from the image interior",
+ "-clip apply first clipping path if the image has one",
+ "-clippath apply named clipping path if the image has one",
+ "-coalesce merge a sequence of images",
+ "-colorize value colorize the image with the fill color",
+ "-colors value preferred number of colors in the image",
+ "-colorspace type alternate image colorspace",
+ "-comment string annotate image with comment",
+ "-compose operator composite operator",
+ "-compress type image compression type",
+ "-contrast enhance or reduce the image contrast",
+ "-convolve kernel convolve image with the specified convolution kernel",
+ "-crop geometry preferred size and location of the cropped image",
+ "-cycle amount cycle the image colormap",
+ "-debug events display copious debugging information",
+ "-deconstruct break down an image sequence into constituent parts",
+ "-define values Coder/decoder specific options",
+ "-delay value display the next image after pausing",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-despeckle reduce the speckles within an image",
+ "-display server get image or font from this X server",
+ "-dispose method Undefined, None, Background, Previous",
+ "-dither apply Floyd/Steinberg error diffusion to image",
+ "-draw string annotate the image with a graphic primitive",
+ "-edge radius apply a filter to detect edges in the image",
+ "-emboss radius emboss an image",
+ "-encoding type text encoding type",
+ "-endian type multibyte word order (LSB, MSB, or Native)",
+ "-enhance apply a digital filter to enhance a noisy image",
+ "-equalize perform histogram equalization to an image",
+ "-extent composite image on background color canvas image",
+ "-fill color color to use when filling a graphic primitive",
+ "-filter type use this filter when resizing an image",
+ "-flatten flatten a sequence of images",
+ "-flip flip image in the vertical direction",
+ "-flop flop image in the horizontal direction",
+ "-font name render text with this font",
+ "-frame geometry surround image with an ornamental border",
+ "-fuzz distance colors within this distance are considered equal",
+ "-gamma value level of gamma correction",
+ "-gaussian geometry gaussian blur an image",
+ "-geometry geometry perferred size or location of the image",
+ "-green-primary point chomaticity green primary point",
+ "-gravity type horizontal and vertical text/object placement",
+ "-hald-clut clut apply a Hald CLUT to the image",
+ "-help print program options",
+ "-implode amount implode image pixels about the center",
+ "-intent type Absolute, Perceptual, Relative, or Saturation",
+ "-interlace type None, Line, Plane, or Partition",
+ "-label name assign a label to an image",
+ "-lat geometry local adaptive thresholding",
+ "-level value adjust the level of image contrast",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-linewidth width the line width for subsequent draw operations",
+ "-list type Color, Delegate, Format, Magic, Module, Resource,",
+ " or Type",
+ "-log format format of debugging information",
+ "-loop iterations add Netscape loop extension to your GIF animation",
+ "-magnify interpolate image to double size",
+ "-map filename transform image colors to match this set of colors",
+ "-mask filename set the image clip mask",
+ "-matte store matte channel if the image has one",
+ "-mattecolor color specify the color to be used with the -frame option",
+ "-median radius apply a median filter to the image",
+ "-minify interpolate the image to half size",
+ "-modulate value vary the brightness, saturation, and hue",
+ "-monitor show progress indication",
+ "-monochrome transform image to black and white",
+ "-morph value morph an image sequence",
+ "-mosaic create a mosaic from an image sequence",
+ "-motion-blur radiusxsigma+angle",
+ " simulate motion blur",
+ "-negate replace every pixel with its complementary color ",
+ "-noop do not apply options to image",
+ "-noise radius add or reduce noise in an image",
+ "-normalize transform image to span the full range of colors",
+ "-opaque color change this color to the fill color",
+ "-operator channel operator rvalue",
+ " apply a mathematical or bitwise operator to channel",
+ "-ordered-dither channeltype NxN",
+ " ordered dither the image",
+ "-orient orientation set image orientation attribute",
+ "+page reset current page offsets to default",
+ "-page geometry size and location of an image canvas",
+ "-paint radius simulate an oil painting",
+ "-ping efficiently determine image attributes",
+ "-pointsize value font point size",
+ "-preview type image preview type",
+ "-profile filename add ICM or IPTC information profile to image",
+ "-quality value JPEG/MIFF/PNG compression level",
+ "-raise value lighten/darken image edges to create a 3-D effect",
+ "-random-threshold channeltype LOWxHIGH",
+ " random threshold the image",
+ "-recolor matrix apply a color translation matrix to image channels",
+ "-red-primary point chomaticity red primary point",
+ "-region geometry apply options to a portion of the image",
+ "-render render vector graphics",
+ "+render disable rendering vector graphics",
+ "-resample geometry resample to horizontal and vertical resolution",
+ "+repage reset current page offsets to default",
+ "-repage geometry adjust current page offsets by geometry",
+ "-resize geometry resize the image",
+ "-roll geometry roll an image vertically or horizontally",
+ "-rotate degrees apply Paeth rotation to the image",
+ "-sample geometry scale image with pixel sampling",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-scale geometry scale the image",
+ "-scene value image scene number",
+ "-seed value pseudo-random number generator seed value",
+ "-segment values segment an image",
+ "-set attribute value set image attribute",
+ "+set attribute unset image attribute",
+ "-shade degrees shade the image using a distant light source",
+ "-sharpen geometry sharpen the image",
+ "-shave geometry shave pixels from the image edges",
+ "-shear geometry slide one edge of the image along the X or Y axis",
+ "-size geometry width and height of image",
+ "-solarize threshold negate all pixels above the threshold level",
+ "-spread amount displace image pixels by a random amount",
+ "-stroke color graphic primitive stroke color",
+ "-strokewidth value graphic primitive stroke width",
+ "-strip strip all profiles and text attributes from image",
+ "-swirl degrees swirl image pixels about the center",
+ "-texture filename name of texture to tile onto the image background",
+ "-threshold value threshold the image",
+ "-thumbnail geometry resize the image (optimized for thumbnails)",
+ "-tile filename tile image when filling a graphic primitive",
+ "-transform affine transform image",
+ "-transparent color make this color transparent within the image",
+ "-treedepth value color tree depth",
+ "-trim trim image edges",
+ "-type type image type",
+ "-undercolor color annotation bounding box color",
+ "-units type PixelsPerInch, PixelsPerCentimeter, or Undefined",
+ "-unsharp geometry sharpen the image",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ "-view FlashPix viewing transforms",
+ "-virtual-pixel method",
+ " Constant, Edge, Mirror, or Tile",
+ "-wave geometry alter an image along a sine wave",
+ "-white-point point chomaticity white point",
+ "-white-threshold value",
+ " pixels above the threshold become white",
+ "-write filename write image to this file",
+ (char *) NULL
+ };
+
+ const char
+ **p;
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] file [ [options ...] "
+ "file ...] [options ...] file\n",GetClientName());
+ (void) printf("\nWhere options include:\n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) printf(
+ "\nBy default, the image format of `file' is determined by its magic\n");
+ (void) printf(
+ "number. To specify a particular image format, precede the filename\n");
+ (void) printf(
+ "with an image format name and a colon (i.e. ps:image) or specify the\n");
+ (void) printf(
+ "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n");
+ (void) printf("'-' for standard input or output.\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o n j u r e U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ConjureUsage() displays the program command syntax.
+%
+% The format of the ConjureUsage method is:
+%
+% void ConjureUsage()
+%
+*/
+static void ConjureUsage(void)
+{
+ static const char
+ *options[]=
+ {
+ "-debug events display copious debugging information",
+ "-help print program options",
+ "-log format format of debugging information",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ (char *) NULL
+ };
+
+ const char
+ **p;
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] file [ [options ...] file ...]\n",
+ GetClientName());
+ (void) printf("\nWhere options include:\n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) printf("\nIn additiion, define any key value pairs required by "
+ "your script. For\nexample,\n\n");
+ (void) printf(" conjure -size 100x100 -color blue -foo bar script.msl\n");
+}
+
+MagickExport MagickPassFail ConjureImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ char
+ *option;
+
+ Image
+ *image;
+
+ register long
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ ConjureUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+
+ /*
+ Expand argument list
+ */
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ /*
+ Validate command list
+ */
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ image_info->attributes=AllocateImage(image_info);
+ status=MagickPass;
+ for (i=1; i < argc; i++)
+ {
+ option=argv[i];
+ if ((strlen(option) != 1) && ((*option == '-') || (*option == '+')))
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ continue;
+ }
+ if (LocaleCompare("help",option+1) == 0 ||
+ LocaleCompare("?",option+1) == 0)
+ {
+ if (*option == '-')
+ ConjureUsage();
+ continue;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) SetLogFormat(argv[i]);
+ }
+ continue;
+ }
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ continue;
+ }
+ if (LocaleCompare("version",option+1) == 0)
+ {
+ PrintVersionAndCopyright();
+ Exit(0);
+ continue;
+ }
+ /*
+ Persist key/value pair.
+ */
+ (void) SetImageAttribute(image_info->attributes,option+1,(char *) NULL);
+ status&=SetImageAttribute(image_info->attributes,option+1,argv[i+1]);
+ if (status == MagickFail)
+ MagickFatalError(ImageFatalError,UnableToPersistKey,option);
+ i++;
+ continue;
+ }
+ /*
+ Interpret MSL script.
+ */
+ (void) SetImageAttribute(image_info->attributes,"filename",(char *) NULL);
+ status&=SetImageAttribute(image_info->attributes,"filename",argv[i]);
+ if (status == MagickFail)
+ MagickFatalError(ImageFatalError,UnableToPersistKey,argv[i]);
+ (void) FormatString(image_info->filename,"msl:%.1024s",argv[i]);
+ image=ReadImage(image_info,exception);
+ if (exception->severity > UndefinedException)
+ {
+ CatchException(exception);
+ DestroyExceptionInfo(exception);
+ GetExceptionInfo(exception);
+ }
+ status&=(image != (Image *) NULL);
+ if (image != (Image *) NULL)
+ DestroyImageList(image);
+ }
+ DestroyImageInfo(image_info);
+ LiberateArgumentList(argc,argv);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D i s p l a y U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DisplayUsage() displays the program command syntax.
+%
+% The format of the DisplayUsage method is:
+%
+% void DisplayUsage(void)
+%
+% A description of each parameter follows:
+%
+%
+*/
+#if defined(HasX11)
+static void DisplayUsage(void)
+{
+ const char
+ **p;
+
+ static const char
+ *buttons[]=
+ {
+ "1 press to map or unmap the Command widget",
+ "2 press and drag to magnify a region of an image",
+ "3 press to load an image from a visual image directory",
+ (char *) NULL
+ },
+ *options[]=
+ {
+ "-authenticate value decrypt image with this password",
+ "-backdrop display image centered on a backdrop",
+ "-border geometry surround image with a border of color",
+ "-colormap type Shared or Private",
+ "-colors value preferred number of colors in the image",
+ "-colorspace type alternate image colorspace",
+ "-comment string annotate image with comment",
+ "-compress type image compression type",
+ "-contrast enhance or reduce the image contrast",
+ "-crop geometry preferred size and location of the cropped image",
+ "-debug events display copious debugging information",
+ "-define values Coder/decoder specific options",
+ "-delay value display the next image after pausing",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-despeckle reduce the speckles within an image",
+ "-display server display image to this X server",
+ "-dispose method Undefined, None, Background, Previous",
+ "-dither apply Floyd/Steinberg error diffusion to image",
+ "-edge factor apply a filter to detect edges in the image",
+ "-endian type multibyte word order (LSB, MSB, or Native)",
+ "-enhance apply a digital filter to enhance a noisy image",
+ "-filter type use this filter when resizing an image",
+ "-flip flip image in the vertical direction",
+ "-flop flop image in the horizontal direction",
+ "-frame geometry surround image with an ornamental border",
+ "-gamma value level of gamma correction",
+ "-geometry geometry preferred size and location of the Image window",
+ "-help print program options",
+ "-immutable displayed image cannot be modified",
+ "-interlace type None, Line, Plane, or Partition",
+ "-label name assign a label to an image",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-log format format of debugging information",
+ "-map type display image using this Standard Colormap",
+ "-matte store matte channel if the image has one",
+ "-monitor show progress indication",
+ "-monochrome transform image to black and white",
+ "-negate replace every pixel with its complementary color",
+ "-noop do not apply options to image",
+ "-page geometry size and location of an image canvas",
+ "+progress disable progress monitor and busy cursor",
+ "-quality value JPEG/MIFF/PNG compression level",
+ "-raise value lighten/darken image edges to create a 3-D effect",
+ "-remote command execute a command in an remote display process",
+ "-roll geometry roll an image vertically or horizontally",
+ "-rotate degrees apply Paeth rotation to the image",
+ "-sample geometry scale image with pixel sampling",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-scenes range image scene range",
+ "-segment value segment an image",
+ "-set attribute value set image attribute",
+ "+set attribute unset image attribute",
+ "-sharpen geometry sharpen the image",
+ "-size geometry width and height of image",
+ "-texture filename name of texture to tile onto the image background",
+ "-treedepth value color tree depth",
+ "-trim trim image edges",
+ "-type type image type",
+ "-update seconds detect when image file is modified and redisplay",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ "-visual type display image using this visual type",
+ "-virtual-pixel method",
+ " Constant, Edge, Mirror, or Tile",
+ "-window id display image to background of this window",
+ "-window_group id exit program when this window id is destroyed",
+ "-write filename write image to a file",
+ (char *) NULL
+ };
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] file [ [options ...] file ...]\n",
+ GetClientName());
+ (void) printf("\nWhere options include: \n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) printf(
+ "\nIn addition to those listed above, you can specify these standard X\n");
+ (void) printf(
+ "resources as command line options: -background, -bordercolor,\n");
+ (void) printf(
+ "-borderwidth, -font, -foreground, -iconGeometry, -iconic, -mattecolor,\n");
+ (void) printf("-name, -shared-memory, -usePixmap, or -title.\n");
+ (void) printf(
+ "\nBy default, the image format of `file' is determined by its magic\n");
+ (void) printf(
+ "number. To specify a particular image format, precede the filename\n");
+ (void) printf(
+ "with an image format name and a colon (i.e. ps:image) or specify the\n");
+ (void) printf(
+ "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n");
+ (void) printf("'-' for standard input or output.\n");
+ (void) printf("\nButtons: \n");
+ for (p=buttons; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+}
+#endif /* HasX11 */
+
+MagickExport MagickPassFail DisplayImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+#if defined(HasX11)
+ char
+ *option,
+ *resource_value,
+ *server_name;
+
+ const char
+ *client_name;
+
+ Display
+ *display;
+
+ double
+ sans;
+
+ Image
+ *image,
+ *next;
+
+ long
+ first_scene,
+ image_number,
+ j,
+ k,
+ last_scene,
+ scene,
+ x;
+
+ QuantizeInfo
+ *quantize_info;
+
+ register long
+ i;
+
+ unsigned int
+ *image_marker,
+ last_image;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ state;
+
+ MagickXResourceInfo
+ resource_info;
+
+ XrmDatabase
+ resource_database;
+
+ if (argc < 3)
+ {
+ if ((LocaleCompare("-help",argv[1]) == 0) ||
+ (LocaleCompare("-?",argv[1]) == 0))
+ {
+ DisplayUsage();
+ return MagickPass;
+ }
+ else if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+ }
+
+ /*
+ Expand Argument List
+ */
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ /*
+ Set defaults.
+ */
+ SetNotifyHandlers;
+ display=(Display *) NULL;
+ first_scene=0;
+ image_number=0;
+ last_image=0;
+ last_scene=0;
+ image_marker=
+ MagickAllocateMemory(unsigned int *,(argc+1)*sizeof(unsigned int));
+ if (image_marker == (unsigned int *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToDisplayImage);
+ for (i=0; i <= argc; i++)
+ image_marker[i]=argc;
+ resource_database=(XrmDatabase) NULL;
+ server_name=(char *) NULL;
+ state=0;
+ /*
+ Check for server name specified on the command line.
+ */
+ for (i=1; i < argc; i++)
+ {
+ /*
+ Check command line for server name.
+ */
+ option=argv[i];
+ if ((strlen(option) == 1) || ((*option != '-') && (*option != '+')))
+ continue;
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ /*
+ User specified server name.
+ */
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ server_name=argv[i];
+ break;
+ }
+ }
+ /*
+ Get user defaults from X resource database.
+ */
+ display=XOpenDisplay(server_name);
+ if (display == (Display *) NULL)
+ MagickFatalError(XServerFatalError,UnableToOpenXServer,
+ XDisplayName(server_name));
+ (void) XSetErrorHandler(MagickXError);
+ client_name=GetClientName();
+ resource_database=MagickXGetResourceDatabase(display,client_name);
+ MagickXGetResourceInfo(resource_database,(char *) client_name,&resource_info);
+ image_info=resource_info.image_info;
+ quantize_info=resource_info.quantize_info;
+ image_info->density=
+ MagickXGetResourceInstance(resource_database,client_name,"density",(char *) NULL);
+ if (image_info->density == (char *) NULL)
+ image_info->density=MagickXGetScreenDensity(display);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"interlace","none");
+ image_info->interlace=StringToInterlaceType(resource_value);
+ if (image_info->interlace == UndefinedInterlace)
+ MagickError(OptionError,UnrecognizedInterlaceType,resource_value);
+ image_info->page=MagickXGetResourceInstance(resource_database,client_name,
+ "pageGeometry",(char *) NULL);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"quality","75");
+ image_info->quality=MagickAtoL(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"verbose","False");
+ image_info->verbose=MagickIsTrue(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"dither","True");
+ quantize_info->dither=MagickIsTrue(resource_value);
+ /*
+ Parse command line.
+ */
+ status=MagickPass;
+ j=1;
+ k=0;
+ for (i=1; ((i <= argc) && !(state & ExitState)); i++)
+ {
+ if (i < argc)
+ option=argv[i];
+ else
+ if (image_number != 0)
+ break;
+ else
+ option=(char *) "logo:Untitled";
+ if ((strlen(option) < 2) ||
+ /* stdin + subexpression */
+ ((option[0] == '-') && (option[1] == '[')) ||
+ ((option[0] != '-') && option[0] != '+'))
+ {
+ /*
+ Option is a file name.
+ */
+ k=i;
+ for (scene=first_scene; scene <= last_scene ; scene++)
+ {
+ /*
+ Read image.
+ */
+ (void) strlcpy(image_info->filename,option,MaxTextExtent);
+ if (first_scene != last_scene)
+ {
+ char
+ filename[MaxTextExtent];
+
+ /*
+ Form filename for multi-part images.
+ */
+ (void) MagickSceneFileName(filename,image_info->filename,".%lu",MagickTrue,scene);
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ }
+ (void) strcpy(image_info->magick,"MIFF");
+ image_info->colorspace=quantize_info->colorspace;
+ image_info->dither=quantize_info->dither;
+ DestroyExceptionInfo(exception);
+ GetExceptionInfo(exception);
+ image=ReadImage(image_info,exception);
+ if (exception->severity > UndefinedException)
+ {
+ CatchException(exception);
+ DestroyExceptionInfo(exception);
+ GetExceptionInfo(exception);
+ }
+ status&=image != (Image *) NULL;
+ if (image == (Image *) NULL)
+ continue;
+ status&=MogrifyImage(image_info,i-j,argv+j,&image);
+ (void) CatchImageException(image);
+ do
+ {
+ /*
+ Transmogrify image as defined by the image processing options.
+ */
+ resource_info.quantum=1;
+ if (first_scene != last_scene)
+ image->scene=scene;
+ /*
+ Display image to X server.
+ */
+ if (resource_info.window_id != (char *) NULL)
+ {
+ /*
+ Display image to a specified X window.
+ */
+ if (MagickXDisplayBackgroundImage(display,&resource_info,image))
+ state|=RetainColorsState;
+ }
+ else
+ do
+ {
+ Image
+ *nexus;
+
+ /*
+ Display image to X server.
+ */
+ nexus=
+ MagickXDisplayImage(display,&resource_info,argv,argc,&image,&state);
+ if (nexus == (Image *) NULL)
+ break;
+ while ((nexus != (Image *) NULL) && (!(state & ExitState)))
+ {
+ if (nexus->montage != (char *) NULL)
+ {
+ /*
+ User selected a visual directory image (montage).
+ */
+ DestroyImageList(image);
+ image=nexus;
+ break;
+ }
+ if (first_scene != last_scene)
+ image->scene=scene;
+ next=MagickXDisplayImage(display,&resource_info,argv,argc,&nexus,
+ &state);
+ if ((next == (Image *) NULL) &&
+ (nexus->next != (Image *) NULL))
+ {
+ DestroyImageList(image);
+ image=nexus->next;
+ nexus=(Image *) NULL;
+ }
+ else
+ {
+ if (nexus != image)
+ DestroyImageList(nexus);
+ nexus=next;
+ }
+ }
+ } while (!(state & ExitState));
+ if (resource_info.write_filename != (char *) NULL)
+ {
+ /*
+ Write image.
+ */
+ (void) strlcpy(image->filename,resource_info.write_filename,
+ MaxTextExtent);
+ (void) SetImageInfo(image_info,SETMAGICK_WRITE,&image->exception);
+ status&=WriteImage(image_info,image);
+ (void) CatchImageException(image);
+ }
+ if (image_info->verbose)
+ (void) DescribeImage(image,stderr,MagickFalse);
+ /*
+ Proceed to next/previous image.
+ */
+ next=image;
+ if (state & FormerImageState)
+ for (k=0; k < resource_info.quantum; k++)
+ {
+ next=next->previous;
+ if (next == (Image *) NULL)
+ break;
+ }
+ else
+ for (k=0; k < resource_info.quantum; k++)
+ {
+ next=next->next;
+ if (next == (Image *) NULL)
+ break;
+ }
+ if (next != (Image *) NULL)
+ image=next;
+ } while ((next != (Image *) NULL) && !(state & ExitState));
+ /*
+ Free image resources.
+ */
+ DestroyImageList(image);
+ image=(Image *) NULL;
+ if (!(state & FormerImageState))
+ {
+ last_image=image_number;
+ image_marker[i]=image_number++;
+ }
+ else
+ {
+ /*
+ Proceed to previous image.
+ */
+ for (i--; i > 0; i--)
+ if ((int) image_marker[i] == (image_number-2))
+ break;
+ image_number--;
+ }
+ if (state & ExitState)
+ break;
+ }
+ /*
+ Determine if we should proceed to the first image.
+ */
+ if (image_number < 0)
+ {
+ if (state & FormerImageState)
+ {
+ for (i=1; i < (argc-2); i++)
+ if (image_marker[i] == last_image)
+ break;
+ image_number=image_marker[i]+1;
+ }
+ continue;
+ }
+ continue;
+ }
+ j=k+1;
+ switch (*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("authenticate",option+1) == 0)
+ {
+ (void) CloneString(&image_info->authenticate,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->authenticate,argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'b':
+ {
+ if (LocaleCompare("backdrop",option+1) == 0)
+ {
+ resource_info.backdrop=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("background",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.background_color=argv[i];
+ (void) QueryColorDatabase(argv[i],&image_info->background_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("border",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("bordercolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.border_color=argv[i];
+ (void) QueryColorDatabase(argv[i],&image_info->border_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("borderwidth",option+1) == 0)
+ {
+ resource_info.border_width=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.border_width=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'c':
+ {
+ if (LocaleCompare("colormap",option+1) == 0)
+ {
+ resource_info.colormap=PrivateColormap;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ resource_info.colormap=UndefinedColormap;
+ if (LocaleCompare("private",option) == 0)
+ resource_info.colormap=PrivateColormap;
+ if (LocaleCompare("shared",option) == 0)
+ resource_info.colormap=SharedColormap;
+ if (resource_info.colormap == UndefinedColormap)
+ MagickFatalError(OptionFatalError,UnrecognizedColormapType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("colors",option+1) == 0)
+ {
+ quantize_info->number_colors=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ quantize_info->number_colors=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ quantize_info->colorspace=RGBColorspace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ quantize_info->colorspace=StringToColorspaceType(option);
+ if (IsGrayColorspace(quantize_info->colorspace))
+ {
+ quantize_info->number_colors=256;
+ quantize_info->tree_depth=8;
+ }
+ if (quantize_info->colorspace == UndefinedColorspace)
+ MagickFatalError(OptionFatalError,InvalidColorspaceType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("comment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ image_info->compression=NoCompression;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ image_info->compression=StringToCompressionType(option);
+ if (image_info->compression == UndefinedCompression)
+ MagickFatalError(OptionFatalError,UnrecognizedImageCompressionType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("contrast",option+1) == 0)
+ break;
+ if (LocaleCompare("crop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'd':
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("delay",option+1) == 0)
+ {
+ resource_info.delay=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.delay=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("despeckle",option+1) == 0)
+ break;
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+
+ (void) CloneString(&image_info->server_name,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("dispose",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ if ((LocaleCompare("0",option) != 0) &&
+ (LocaleCompare("1",option) != 0) &&
+ (LocaleCompare("2",option) != 0) &&
+ (LocaleCompare("3",option) != 0) &&
+ (LocaleCompare("Undefined",option) != 0) &&
+ (LocaleCompare("None",option) != 0) &&
+ (LocaleCompare("Background",option) != 0) &&
+ (LocaleCompare("Previous",option) != 0))
+ MagickFatalError(OptionFatalError,UnrecognizedDisposeMethod,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("dither",option+1) == 0)
+ {
+ quantize_info->dither=(*option == '-');
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'e':
+ {
+ if (LocaleCompare("edge",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("endian",option+1) == 0)
+ {
+ image_info->endian=UndefinedEndian;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ image_info->endian=StringToEndianType(option);
+ if (image_info->endian == UndefinedEndian)
+ MagickFatalError(OptionFatalError,InvalidEndianType,option);
+ }
+ break;
+ }
+ if (LocaleCompare("enhance",option+1) == 0)
+ break;
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'f':
+ {
+ if (LocaleCompare("filter",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ FilterTypes
+ filter;
+
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ filter=StringToFilterTypes(option);
+ if (filter == UndefinedFilter)
+ MagickFatalError(OptionFatalError,UnrecognizedFilterType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("flip",option+1) == 0)
+ break;
+ if (LocaleCompare("flop",option+1) == 0)
+ break;
+ if (LocaleCompare("font",option+1) == 0)
+ {
+ (void) CloneString(&image_info->font,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ image_info->font=argv[i];
+ }
+ if ((image_info->font == (char *) NULL) ||
+ (*image_info->font != '@'))
+ resource_info.font=AllocateString(image_info->font);
+ break;
+ }
+ if (LocaleCompare("foreground",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.foreground_color=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("frame",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'g':
+ {
+ if (LocaleCompare("gamma",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("geometry",option+1) == 0)
+ {
+ MagickFreeMemory(resource_info.image_geometry);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.image_geometry=AcquireString(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'h':
+ {
+ if (LocaleCompare("help",option+1) == 0)
+ {
+ DisplayUsage();
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'i':
+ {
+ if (LocaleCompare("iconGeometry",option+1) == 0)
+ {
+ resource_info.icon_geometry=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.icon_geometry=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("iconic",option+1) == 0)
+ {
+ resource_info.iconic=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("immutable",option+1) == 0)
+ {
+ resource_info.immutable=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ image_info->interlace=UndefinedInterlace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ MagickFatalError(OptionFatalError,InvalidInterlaceType,
+ option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'l':
+ {
+ if (LocaleCompare("label",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ MagickFatalError(OptionFatalError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'm':
+ {
+ if (LocaleCompare("magnify",option+1) == 0)
+ {
+ resource_info.magnify=2;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.magnify=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("map",option+1) == 0)
+ {
+ (void) strcpy(argv[i]+1,"sans");
+ resource_info.map_type=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.map_type=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("matte",option+1) == 0)
+ break;
+ if (LocaleCompare("mattecolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.matte_color=argv[i];
+ (void) QueryColorDatabase(argv[i],&image_info->matte_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ if (LocaleCompare("monochrome",option+1) == 0)
+ {
+ image_info->monochrome=(*option == '-');
+ if (image_info->monochrome)
+ {
+ quantize_info->number_colors=2;
+ quantize_info->tree_depth=8;
+ quantize_info->colorspace=GRAYColorspace;
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'n':
+ {
+ if (LocaleCompare("name",option+1) == 0)
+ {
+ resource_info.name=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.name=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("negate",option+1) == 0)
+ break;
+ if (LocaleCompare("noop",option+1) == 0)
+ break;
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'p':
+ {
+ if (LocaleCompare("page",option+1) == 0)
+ {
+ (void) CloneString(&image_info->page,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ image_info->page=GetPageGeometry(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("progress",option+1) == 0)
+ {
+ resource_info.image_info->progress=(*option == '-');
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'q':
+ {
+ if (LocaleCompare("quality",option+1) == 0)
+ {
+ image_info->quality=DefaultCompressionQuality;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ image_info->quality=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'r':
+ {
+ if (LocaleCompare("raise",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("remote",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ status=MagickXRemoteCommand(display,resource_info.window_id,argv[i]);
+ Exit(!status);
+ }
+ if (LocaleCompare("roll",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("rotate",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 's':
+ {
+ if (LocaleCompare("sample",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("scenes",option+1) == 0)
+ {
+ first_scene=0;
+ last_scene=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ first_scene=MagickAtoL(argv[i]);
+ last_scene=first_scene;
+ (void) sscanf(argv[i],"%ld-%ld",&first_scene,&last_scene);
+ }
+ break;
+ }
+ if (LocaleCompare("segment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("set",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ if (*option == '-')
+ {
+ /* -set attribute value */
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("sharpen",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("shared-memory",option+1) == 0)
+ {
+ resource_info.use_shared_memory=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 't':
+ {
+ if (LocaleCompare("text_font",option+1) == 0)
+ {
+ resource_info.text_font=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.text_font=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("texture",option+1) == 0)
+ {
+ (void) CloneString(&image_info->texture,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->texture,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("title",option+1) == 0)
+ {
+ resource_info.title=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.title=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("treedepth",option+1) == 0)
+ {
+ quantize_info->tree_depth=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ quantize_info->tree_depth=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("trim",option+1) == 0)
+ {
+ break;
+ }
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ resource_info.image_info->type=UndefinedType;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ resource_info.image_info->type=StringToImageType(option);
+ if (resource_info.image_info->type == UndefinedType)
+ MagickFatalError(OptionFatalError,UnrecognizedImageType,
+ option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'u':
+ {
+ if (LocaleCompare("update",option+1) == 0)
+ {
+ resource_info.update=(*option == '-');
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.update=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ if ((LocaleCompare("use_pixmap",option+1) == 0) ||
+ (LocaleCompare("usePixmap",option+1) == 0))
+ {
+ resource_info.use_pixmap=(*option == '-');
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("version",option+1) == 0)
+ break;
+ if (LocaleCompare("visual",option+1) == 0)
+ {
+ resource_info.visual_type=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ resource_info.visual_type=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("virtual-pixel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ option=argv[i];
+ virtual_pixel_method=StringToVirtualPixelMethod(option);
+ if (virtual_pixel_method == UndefinedVirtualPixelMethod)
+ MagickFatalError(OptionFatalError,UnrecognizedVirtualPixelMethod,option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'w':
+ {
+ if (LocaleCompare("window",option+1) == 0)
+ {
+ resource_info.window_id=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ resource_info.window_id=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("window_group",option+1) == 0)
+ {
+ resource_info.window_group=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ resource_info.window_group=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("write",option+1) == 0)
+ {
+ resource_info.write_filename=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.write_filename=argv[i];
+ if (IsAccessible(resource_info.write_filename))
+ {
+ char
+ *answer,
+ answer_buffer[2];
+
+ answer_buffer[0]='\0';
+ (void) fprintf(stderr,"Overwrite %.1024s? ",
+ resource_info.write_filename);
+ answer=fgets(answer_buffer,sizeof(answer_buffer),stdin);
+ if ((NULL == answer) || !((answer[0] == 'y') || (answer[0] == 'Y')))
+ Exit(0);
+ }
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case '?':
+ {
+ DisplayUsage();
+ break;
+ }
+ default:
+ {
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ }
+ }
+ if (state & RetainColorsState)
+ {
+ MagickXRetainWindowColors(display,XRootWindow(display,XDefaultScreen(display)));
+ (void) XSync(display,MagickFalse);
+ }
+ if (resource_database != (XrmDatabase) NULL)
+ {
+ /* It seems that recent X11 libraries (as found in FreeBSD 5.4)
+ automatically destroy the resource database associated with
+ the display and there are double-frees if we destroy the
+ resource database ourselves. */
+ /* XrmDestroyDatabase(resource_database); */
+ resource_database=(XrmDatabase) NULL;
+ }
+
+ MagickFreeMemory(image_marker);
+ MagickXDestroyResourceInfo(&resource_info);
+ LiberateArgumentList(argc,argv);
+ MagickXDestroyX11Resources();
+ (void) XCloseDisplay(display);
+ return(status);
+#else
+ ARG_NOT_USED(image_info);
+ ARG_NOT_USED(argc);
+ ARG_NOT_USED(argv);
+ ARG_NOT_USED(metadata);
+ ARG_NOT_USED(exception);
+
+ MagickFatalError(MissingDelegateError,XWindowLibraryIsNotAvailable,
+ (char *) NULL);
+ return(MagickFail);
+#endif
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t O p t i o n V a l u e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetOptionValue sets the option value to variable pointed by result pointer
+% and return OptionSuccess when the value is not null. Otherwise, print error
+% and returns OPtionMissingValue.
+%
+% The format of the GetOptionValue method is:
+%
+% OptionStatus GetOptionValue(const char *option, const char *value,
+% char **result)
+%
+% A description of each parameter follows:
+%
+% o option: The option to get the value.
+%
+% o value: The value to be check.
+%
+% o result: Points to the variable to be set to value.
+%
+*/
+static OptionStatus GetOptionValue(const char *option, char *value,
+ char **result)
+{
+ OptionStatus status = CheckOptionValue(option, value);
+ if (status == OptionSuccess)
+ *result = value;
+ return status;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t O p t i o n V a l u e R e s t r i c t e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetOptionValueRestricted searchs the value in the a list of predefined
+% values. If a match is found, it sets variable pointed by the result pointer
+% and return OptionSuccess when the value is one. Otherwise, print error
+% and returns OPtionInvalidValue.
+%
+% The format of the GetOptionValueRestricted method is:
+%
+% OptionStatus GetOptionValueRestricted(const char *option, char **values,
+% const char *value, int *result)
+%
+% A description of each parameter follows:
+%
+% o option: The option to get the value.
+%
+% o value: The option value to be checked.
+%
+% o values: The predefined set of acceptable values.
+%
+% o result: Points to the variable to be set to value.
+%
+*/
+static OptionStatus GetOptionValueRestricted(const char *option,
+ const char **values, const char *value, int *result)
+{
+ int i;
+ OptionStatus status = CheckOptionValue(option, value);
+ if (status != OptionSuccess)
+ return status;
+ for (i = 0; values[i] != (char *) NULL; i++)
+ {
+ if (LocaleCompare(values[i], value) == 0)
+ {
+ *result = i;
+ return OptionSuccess;
+ }
+ }
+ fprintf(stderr, "Error: Invalid value for %s option: %s\n", option, value);
+ return OptionInvalidValue;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t O n O f f O p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetOnOffOptionValue expectes the value to be either "on" or "off". It then
+% sets the corresponding value to the boolean variable pointed by the result
+% pointer and return OptionSuccess. Otherwise, print error and returns
+% OPtionInvalidValue.
+%
+% The format of the GetOnOffOptionValue method is:
+%
+% OptionStatus GetOnOffOptionValue(const char *option,
+% const char *value, int *result)
+%
+% A description of each parameter follows:
+%
+% o option: The option to get the value.
+%
+% o value: The value to be checked.
+%
+% o result: Points to the variable to accept the result.
+%
+*/
+static OptionStatus GetOnOffOptionValue(const char *option, const char *value,
+ MagickBool *result)
+{
+ int i;
+ OptionStatus status = GetOptionValueRestricted(option, on_off_option_values, value, &i);
+ if (status != OptionSuccess)
+ return status;
+ *result = i;
+ return OptionSuccess;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G M U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GMUsage() displays the gm program command syntax.
+%
+% The format of the GMUsage method is:
+%
+% void GMUsage()
+%
+%
+*/
+static void GMUsage(void)
+{
+ int
+ i;
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s command [options ...]\n",GetClientName());
+ (void) printf("\nWhere commands include: \n");
+
+ for (i=0; commands[i].command != 0; i++)
+ {
+ if (commands[i].support_mode & run_mode)
+ (void) printf("%11s - %s\n",commands[i].command,
+ commands[i].description);
+ }
+
+ return;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H e l p C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% HelpCommand() prints a usage message for gm, or for a gm subcommand.
+%
+% The format of the HelpCommand method is:
+%
+% MagickPassFail HelpCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail HelpCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,
+ ExceptionInfo *exception)
+{
+ ARG_NOT_USED(image_info);
+ ARG_NOT_USED(metadata);
+ ARG_NOT_USED(exception);
+ if (argc > 1)
+ {
+ int
+ i;
+
+ for (i=0; commands[i].command != 0; i++)
+ {
+ if (!(commands[i].support_mode & run_mode))
+ continue;
+ if (LocaleCompare(commands[i].command,argv[1]) == 0)
+ {
+ (void) SetClientName(commands[i].command);
+ if (commands[i].usage_vector)
+ {
+ (commands[i].usage_vector)();
+ return MagickPass;
+ }
+ }
+ }
+ }
+
+ GMUsage();
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I d e n t i f y I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IdentifyImageCommand() describes the format and characteristics of one or
+% more image files. It will also report if an image is incomplete or corrupt.
+% The information displayed includes the scene number, the file name, the
+% width and height of the image, whether the image is colormapped or not,
+% the number of colors in the image, the number of bytes in the image, the
+% format of the image (JPEG, PNM, etc.), and finally the number of seconds
+% it took to read and process the image.
+%
+% The format of the IdentifyImageCommand method is:
+%
+% MagickPassFail IdentifyImageCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+#define ThrowIdentifyException(code,reason,description) \
+{ \
+ status = MagickFail; \
+ ThrowException(exception,code,reason,description); \
+ goto identify_cleanup_and_return; \
+}
+#define ThrowIdentifyException3(code,reason,description) \
+{ \
+ status = MagickFail; \
+ ThrowException3(exception,code,reason,description); \
+ goto identify_cleanup_and_return; \
+}
+
+MagickExport MagickPassFail IdentifyImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ char
+ *format = NULL,
+ *option = NULL,
+ *q = NULL;
+
+ Image
+ *image;
+
+ long
+ count,
+ number_images,
+ x;
+
+ register Image
+ *p;
+
+ register long
+ i;
+
+ unsigned int
+ ping;
+
+ MagickPassFail
+ status = MagickPass;
+
+ /*
+ Check for sufficient arguments
+ */
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ IdentifyUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+
+ /*
+ Set defaults.
+ */
+ count=0;
+ format=(char *) NULL;
+ image=NewImageList();
+ number_images=0;
+ status=MagickTrue;
+ ping=MagickTrue;
+
+ /*
+ Expand argument list
+ */
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ for (i=1; i < argc; i++)
+ {
+ option=argv[i];
+ if (LocaleCompare("-format",argv[i]) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ (void) CloneString(&format,argv[i]);
+ break;
+ }
+ else if (LocaleCompare("+ping",argv[i]) == 0)
+ {
+ ping=MagickFalse;
+ }
+ }
+ for (i=1; i < argc; i++)
+ {
+ option=argv[i];
+ if ((strlen(option) < 2) ||
+ /* stdin + subexpression */
+ ((option[0] == '-') && (option[1] == '[')) ||
+ ((option[0] != '-') && option[0] != '+'))
+ {
+ /*
+ Identify image.
+ */
+ (void) strlcpy(image_info->filename,argv[i],MaxTextExtent);
+ if (format != (char *) NULL)
+ for (q=strchr(format,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
+ {
+ const char c=*(q+1);
+ if ((c == 'A') || (c == 'k') || (c == 'q') || (c == 'r') ||
+ (c == '#'))
+ {
+ ping=MagickFalse;
+ break;
+ }
+ }
+ if (image_info->verbose || !ping)
+ image=ReadImage(image_info,exception);
+ else
+ image=PingImage(image_info,exception);
+ status&=image != (Image *) NULL;
+ if (image == (Image *) NULL)
+ {
+ CatchException(exception);
+ DestroyExceptionInfo(exception);
+ GetExceptionInfo(exception);
+ continue;
+ }
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ if (p->scene == 0)
+ p->scene=count++;
+ if (format == (char *) NULL)
+ {
+ (void) DescribeImage(p,stdout,image_info->verbose);
+ continue;
+ }
+ if (metadata != (char **) NULL)
+ {
+ char
+ *text;
+
+ text=TranslateText(image_info,p,format);
+ if (text == (char *) NULL)
+ ThrowIdentifyException(ResourceLimitError,
+ MemoryAllocationFailed,
+ MagickMsg(OptionError,UnableToFormatImageMetadata));
+ (void) ConcatenateString(&(*metadata),text);
+/* (void) ConcatenateString(&(*metadata),"\n"); */
+ MagickFreeMemory(text);
+ }
+ }
+ DestroyImageList(image);
+ image=NewImageList();
+ number_images++;
+ continue;
+ }
+ switch(*(option+1))
+ {
+ case 'd':
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowIdentifyException(OptionError,MissingArgument,
+ option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'f':
+ {
+ if (LocaleCompare("format",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowIdentifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'h':
+ {
+ if (LocaleCompare("help",option+1) == 0)
+ break;
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'i':
+ {
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ ThrowIdentifyException(OptionError,UnrecognizedInterlaceType,option);
+ }
+ break;
+ }
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'l':
+ {
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ MagickFatalError(OptionFatalError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'm':
+ {
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'p':
+ {
+ if (LocaleCompare("ping",option+1) == 0)
+ break;
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 's':
+ {
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("verbose",option+1) == 0)
+ break;
+ if (LocaleCompare("virtual-pixel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ i++;
+ if (i == argc)
+ ThrowIdentifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ virtual_pixel_method=StringToVirtualPixelMethod(option);
+ if (virtual_pixel_method == UndefinedVirtualPixelMethod)
+ ThrowIdentifyException(OptionError,UnrecognizedVirtualPixelMethod,option);
+ }
+ break;
+ }
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ case '?':
+ break;
+ default:
+ ThrowIdentifyException(OptionError,UnrecognizedOption,option)
+ }
+ }
+ if (number_images == 0)
+ {
+ if (exception->severity == UndefinedException)
+ ThrowIdentifyException(OptionError,RequestDidNotReturnAnImage,
+ (char *) NULL);
+ status = MagickFail;
+ }
+ if (i != argc)
+ ThrowIdentifyException(OptionError,MissingAnImageFilename,(char *) NULL);
+ identify_cleanup_and_return:
+ MagickFreeMemory(format);
+ DestroyImageList(image);
+ LiberateArgumentList(argc,argv);
+ return(status);
+}
+#undef ThrowIdentifyException
+#undef ThrowIdentifyException3
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I d e n t i f y U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IdentifyUsage() displays the program command syntax.
+%
+% The format of the IdentifyUsage method is:
+%
+% void IdentifyUsage()
+%
+%
+*/
+static void IdentifyUsage(void)
+{
+ const char
+ **p;
+
+ static const char
+ *options[]=
+ {
+ "-debug events display copious debugging information",
+ "-define values Coder/decoder specific options",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-format \"string\" output formatted image characteristics",
+ "-help print program options",
+ "-interlace type None, Line, Plane, or Partition",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-log format format of debugging information",
+ "-monitor show progress indication",
+ "-ping efficiently determine image attributes",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-size geometry width and height of image",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ "-virtual-pixel method",
+ " Constant, Edge, Mirror, or Tile",
+ (char *) NULL
+ };
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] file [ [options ...] "
+ "file ... ]\n",GetClientName());
+ (void) printf("\nWhere options include:\n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n i t i a l i z e B a t c h O p t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializeBatchOptions initializes the default batch options.
+%
+% The format of the InitializeBatchOptions method is:
+%
+% void InitializeBatchOptions(MagickBool prompt)
+%
+% A description of each parameter follows:
+%
+% o prompt: whether enable prompt or not
+%
+*/
+static void InitializeBatchOptions(MagickBool prompt)
+{
+ strcpy(batch_options.pass, "PASS");
+ strcpy(batch_options.fail, "FAIL");
+#if defined(MSWINDOWS)
+ batch_options.command_line_parser = ParseWindowsCommandLine;
+#else
+ batch_options.command_line_parser = ParseUnixCommandLine;
+#endif
+ if (prompt)
+ strcpy(batch_options.prompt, "GM> ");
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i b e r a t e A r g u m e n t L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% LiberateArgumentList() deallocates the argument list allocated by
+% ExpandFilenames().
+%
+% The format of the LiberateArgumentList method is:
+%
+% void LiberateArgumentList(const int argc,char **argv)
+%
+% A description of each parameter follows:
+%
+% o argc: number of arguments in argument vector array
+%
+% o argv: argument vector array
+%
+*/
+static void LiberateArgumentList(const int argc,char **argv)
+{
+ int
+ i;
+
+ for (i=0; i< argc; i++)
+ MagickFreeMemory(argv[i]);
+ MagickFreeMemory(argv);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCommand() invokes a GraphicsMagick utility subcommand based
+% on the first argument supplied in the argument vector.
+%
+% The format of the MagickCommand method is:
+%
+% MagickPassFail MagickCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail MagickCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ char
+ *option;
+
+ MagickPassFail
+ status=MagickFail;
+
+ int
+ i;
+
+ option=argv[0];
+ if (option[0] == '-')
+ option++;
+
+ for (i=0; commands[i].command != 0; i++)
+ {
+ if (!(commands[i].support_mode & run_mode))
+ continue;
+ if (LocaleCompare(commands[i].command,option) == 0)
+ {
+ char
+ command_name[MaxTextExtent];
+
+ const char
+ *pos;
+
+ /*
+ Append subcommand name to existing client name if end of
+ existing client name is not identical to subcommand name.
+ */
+ LockSemaphoreInfo(command_semaphore);
+ if (run_mode == BatchMode)
+ (void) SetClientName(commands[i].command);
+ else
+ {
+ GetPathComponent(GetClientName(),BasePath,command_name);
+ pos=strrchr(command_name,' ');
+ if ((pos == (const char *) NULL) ||
+ (LocaleCompare(commands[i].command,pos+1) != 0))
+ {
+ char
+ client_name[MaxTextExtent];
+
+ FormatString(client_name,"%.1024s %s",GetClientName(),
+ commands[i].command);
+
+ (void) SetClientName(client_name);
+ }
+ }
+ UnlockSemaphoreInfo(command_semaphore);
+
+ return(commands[i].command_vector)(image_info,argc,argv,
+ commands[i].pass_metadata ? metadata : (char **) NULL,exception);
+ }
+ }
+ ThrowException(exception,OptionError,UnrecognizedCommand,option);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k D e s t r o y C o m m a n d I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickDestroyCommandInfo deallocates memory associated with the
+% command parser.
+%
+% The format of the MagickDestroyCommandInfo method is:
+%
+% void MagickDestroyCommandInfo(void)
+%
+%
+*/
+void MagickDestroyCommandInfo(void)
+{
+ DestroySemaphoreInfo(&command_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k I n i t i a l i z e C o m m a n d I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickInitializeCommandInfo initializes the command parsing
+% facility.
+%
+% The format of the MagickInitializeCommandInfo method is:
+%
+% MagickPassFail MagickInitializeCommandInfo(void)
+%
+%
+*/
+MagickPassFail
+MagickInitializeCommandInfo(void)
+{
+ assert(command_semaphore == (SemaphoreInfo *) NULL);
+ command_semaphore=AllocateSemaphoreInfo();
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
++ M o g r i f y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MogrifyImage applies image processing options to an image as
+% prescribed by command line options.
+%
+% The format of the MogrifyImage method is:
+%
+% MagickPassFail MogrifyImage(const ImageInfo *image_info,const int argc,
+% char **argv,Image **image)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info..
+%
+% o argc: Specifies a pointer to an integer describing the number of
+% elements in the argument vector.
+%
+% o argv: Specifies a pointer to a text array containing the command line
+% arguments.
+%
+% o image: The image; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport MagickPassFail MogrifyImage(const ImageInfo *image_info,
+ int argc,char **argv,Image **image)
+{
+ char
+ *option;
+
+ DrawInfo
+ *draw_info;
+
+ Image
+ *region_image;
+
+ ImageInfo
+ *clone_info;
+
+ int
+ count;
+
+ QuantizeInfo
+ quantize_info;
+
+ RectangleInfo
+ geometry,
+ region_geometry;
+
+ register long
+ i;
+
+ unsigned int
+ matte;
+
+ /*
+ Verify option length.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image **) NULL);
+ assert((*image)->signature == MagickSignature);
+ if (argc <= 0)
+ return(MagickFail);
+
+#if defined(DEBUG_COMMAND_PARSER)
+ fprintf(stderr," MogrifyImage (0x%p->%s):", *image, (*image)->filename);
+ for (i=0; i < argc; i++)
+ fprintf(stderr," %s",argv[i]);
+ fprintf(stderr,"\n");
+#endif /* DEBUG_COMMAND_PARSER */
+
+ for (i=0; i < argc; i++)
+ if (strlen(argv[i]) > (MaxTextExtent/2-1))
+ MagickFatalError(OptionFatalError,OptionLengthExceedsLimit,argv[i]);
+ /*
+ Initialize method variables.
+ */
+ clone_info=CloneImageInfo(image_info);
+ draw_info=CloneDrawInfo(clone_info,(DrawInfo *) NULL);
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.number_colors=0;
+ quantize_info.tree_depth=0;
+ quantize_info.dither=MagickTrue;
+ SetGeometry(*image,&region_geometry);
+ region_image=(Image *) NULL;
+ /*
+ Transmogrify the image.
+ */
+ for (i=0; i < argc; i++)
+ {
+ option=argv[i];
+ if ((strlen(option) <= 1) || ((option[0] != '-') && (option[0] != '+')))
+ continue;
+ switch (*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("affine",option+1) == 0)
+ {
+ char
+ *p;
+
+ /*
+ Draw affine matrix.
+ */
+ if (*option == '+')
+ {
+ IdentityAffine(&draw_info->affine);
+ continue;
+ }
+ p=argv[++i];
+ draw_info->affine.sx=strtod(p,&p);
+ if (*p ==',')
+ p++;
+ draw_info->affine.rx=strtod(p,&p);
+ if (*p ==',')
+ p++;
+ draw_info->affine.ry=strtod(p,&p);
+ if (*p ==',')
+ p++;
+ draw_info->affine.sy=strtod(p,&p);
+ if (*p ==',')
+ p++;
+ draw_info->affine.tx=strtod(p,&p);
+ if (*p ==',')
+ p++;
+ draw_info->affine.ty=strtod(p,&p);
+ break;
+ }
+ if (LocaleCompare("antialias",option+1) == 0)
+ {
+ clone_info->antialias=(*option == '-');
+ draw_info->stroke_antialias=(*option == '-');
+ draw_info->text_antialias=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("asc-cdl",option+1) == 0)
+ {
+ ++i;
+ (void) CdlImage(*image,argv[i]);
+ continue;
+ }
+ if (LocaleCompare("auto-orient",option+1) == 0)
+ {
+ Image
+ *orient_image;
+
+ /*
+ Auto orient (upright) image scanlines.
+ */
+ orient_image=AutoOrientImage(*image,(*image)->orientation,
+ &(*image)->exception);
+ if (orient_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=orient_image;
+ continue;
+ } break;
+ }
+ case 'b':
+ {
+ if (LocaleCompare("background",option+1) == 0)
+ {
+ (void) QueryColorDatabase(argv[++i],&clone_info->background_color,
+ &(*image)->exception);
+ (*image)->background_color=clone_info->background_color;
+ continue;
+ }
+ if (LocaleCompare("blue-primary",option+1) == 0)
+ {
+ /*
+ Blue chromaticity primary point.
+ */
+ if (*option == '+')
+ {
+ (*image)->chromaticity.blue_primary.x=0.0;
+ (*image)->chromaticity.blue_primary.y=0.0;
+ continue;
+ }
+ (void) sscanf(argv[++i],"%lf%*[,/]%lf",
+ &(*image)->chromaticity.blue_primary.x,
+ &(*image)->chromaticity.blue_primary.y);
+ continue;
+ }
+ if (LocaleCompare("black-threshold",option+1) == 0)
+ {
+ /*
+ Black threshold image.
+ */
+ ++i;
+ (void) BlackThresholdImage(*image,argv[i]);
+ continue;
+ }
+ if (LocaleCompare("blur",option+1) == 0)
+ {
+ double
+ radius,
+ sigma;
+
+ Image
+ *blur_image;
+
+ /*
+ Gaussian blur image.
+ */
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(argv[++i],&radius,&sigma,NULL,NULL);
+ blur_image=BlurImage(*image,radius,sigma,&(*image)->exception);
+ if (blur_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=blur_image;
+ continue;
+ }
+ if (LocaleCompare("border",option+1) == 0)
+ {
+ Image
+ *border_image;
+
+ /*
+ Surround image with a border of solid color.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickFalse,&geometry);
+ border_image=BorderImage(*image,&geometry,&(*image)->exception);
+ if (border_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=border_image;
+ continue;
+ }
+ if (LocaleCompare("bordercolor",option+1) == 0)
+ {
+ (void) QueryColorDatabase(argv[++i],&clone_info->border_color,
+ &(*image)->exception);
+ draw_info->border_color=clone_info->border_color;
+ (*image)->border_color=clone_info->border_color;
+ continue;
+ }
+ if (LocaleCompare("box",option+1) == 0)
+ {
+ (void) QueryColorDatabase(argv[++i],&draw_info->undercolor,
+ &(*image)->exception);
+ continue;
+ }
+ break;
+ }
+ case 'c':
+ {
+ if (LocaleCompare("channel",option+1) == 0)
+ {
+ ChannelType
+ channel;
+
+ channel=StringToChannelType(argv[++i]);
+ if (clone_info->colorspace != UndefinedColorspace)
+ (void) TransformColorspace(*image,clone_info->colorspace);
+ (void) ChannelImage(*image,channel);
+ continue;
+ }
+ if (LocaleCompare("charcoal",option+1) == 0)
+ {
+ double
+ radius,
+ sigma;
+
+ Image
+ *charcoal_image;
+
+ /*
+ Charcoal image.
+ */
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(argv[++i],&radius,&sigma,NULL,NULL);
+ charcoal_image=
+ CharcoalImage(*image,radius,sigma,&(*image)->exception);
+ if (charcoal_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=charcoal_image;
+ continue;
+ }
+ if (LocaleCompare("chop",option+1) == 0)
+ {
+ Image
+ *chop_image;
+
+ /*
+ Chop the image.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickFalse,&geometry);
+ chop_image=ChopImage(*image,&geometry,&(*image)->exception);
+ if (chop_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=chop_image;
+ continue;
+ }
+ if (LocaleCompare("clip",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetImageClipMask(*image,(Image *) NULL);
+ continue;
+ }
+ (void) ClipImage(*image);
+ continue;
+ }
+ if (LocaleCompare("clippath",option+1) == 0)
+ {
+ (void) ClipPathImage(*image,argv[++i],*option == '-');
+ continue;
+ }
+ if (LocaleCompare("colorize",option+1) == 0)
+ {
+ Image
+ *colorize_image;
+
+ /*
+ Colorize the image.
+ */
+ colorize_image=ColorizeImage(*image,argv[++i],draw_info->fill,
+ &(*image)->exception);
+ if (colorize_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=colorize_image;
+ continue;
+ }
+ if (LocaleCompare("colors",option+1) == 0)
+ {
+ quantize_info.number_colors=MagickAtoL(argv[++i]);
+
+ if ( IsGrayColorspace(quantize_info.colorspace) )
+ {
+ /*
+ If color reduction is requested, then quantize to the requested
+ number of colors in the gray colorspace, otherwise simply
+ transform the image to the gray colorspace.
+ */
+ if ( quantize_info.number_colors != 0 )
+ (void) QuantizeImage(&quantize_info,*image);
+ else
+ (void) TransformColorspace(*image,quantize_info.colorspace);
+ }
+ else
+ {
+ /*
+ If color reduction is requested, and the image is DirectClass,
+ or the image is PseudoClass and the number of colors exceeds
+ the number requested, then quantize the image colors. Otherwise
+ compress an existing colormap.
+ */
+ if ( quantize_info.number_colors != 0 )
+ {
+ if (((*image)->storage_class == DirectClass) ||
+ ((*image)->colors > quantize_info.number_colors))
+ (void) QuantizeImage(&quantize_info,*image);
+ else
+ CompressImageColormap(*image);
+ }
+ }
+
+ quantize_info.number_colors=0;
+
+ continue;
+ }
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ char
+ type;
+
+ ColorspaceType
+ colorspace;
+
+ type=(*option);
+ option=argv[++i];
+ colorspace=StringToColorspaceType(option);
+ quantize_info.colorspace=colorspace;
+ /* Never quantize in CMYK colorspace */
+ if (IsCMYKColorspace(colorspace))
+ quantize_info.colorspace=RGBColorspace;
+ (void) TransformColorspace(*image,colorspace);
+ clone_info->colorspace=colorspace;
+ if (type == '+')
+ (*image)->colorspace=colorspace;
+ continue;
+ }
+ if (LocaleCompare("comment",option+1) == 0)
+ {
+ (void) SetImageAttribute(*image,"comment",(char *) NULL);
+ if (*option == '-')
+ (void) SetImageAttribute(*image,"comment",argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("compose",option+1) == 0)
+ {
+ (*image)->compose=CopyCompositeOp;
+ if (*option == '-')
+ (*image)->compose=StringToCompositeOperator(argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (*image)->compression=UndefinedCompression;
+ continue;
+ }
+ option=argv[++i];
+ (*image)->compression=StringToCompressionType(option);
+ continue;
+ }
+ if (LocaleCompare("contrast",option+1) == 0)
+ {
+ (void) ContrastImage(*image,*option == '-');
+ continue;
+ }
+ if (LocaleCompare("convolve",option+1) == 0)
+ {
+ Image
+ *convolve_image;
+
+ char
+ *p,
+ token[MaxTextExtent];
+
+ double
+ *kernel;
+
+ register long
+ x;
+
+ unsigned int
+ elements,
+ order;
+
+ /*
+ Convolve image.
+ */
+ p=argv[++i];
+ for (elements=0; *p != '\0'; elements++)
+ {
+ MagickGetToken(p,&p,token,MaxTextExtent);
+ if (token[0] == '\0')
+ break;
+ if (*token == ',')
+ MagickGetToken(p,&p,token,MaxTextExtent);
+ if (token[0] == '\0')
+ break;
+ }
+ order=(unsigned int) sqrt(elements);
+ if ((0 == elements) || (order*order != elements))
+ {
+ char
+ message[MaxTextExtent];
+
+ FormatString(message,"%u",elements);
+ ThrowException(&(*image)->exception,OptionError,MatrixIsNotSquare,message);
+ continue;
+ }
+ kernel=MagickAllocateArray(double *,order*order,sizeof(double));
+ if (kernel == (double *) NULL)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(ResourceLimitError,UnableToAllocateCoefficients));
+ p=argv[i];
+ for (x=0; *p != '\0'; x++)
+ {
+ MagickGetToken(p,&p,token,MaxTextExtent);
+ if (token[0] == '\0')
+ break;
+ if (token[0] == ',')
+ MagickGetToken(p,&p,token,MaxTextExtent);
+ if (token[0] == '\0')
+ break;
+ kernel[x]=MagickAtoF(token);
+ }
+ for ( ; x < (long) (order*order); x++)
+ kernel[x]=0.0;
+ convolve_image=ConvolveImage(*image,order,kernel,
+ &(*image)->exception);
+ MagickFreeMemory(kernel);
+ if (convolve_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=convolve_image;
+ continue;
+ }
+ if (LocaleCompare("crop",option+1) == 0)
+ {
+ /*
+ FIXME: This command can produce multiple images from one
+ image, causing only the first to be fully processed.
+ */
+ TransformImage(image,argv[++i],(char *) NULL);
+ continue;
+ }
+ if (LocaleCompare("cycle",option+1) == 0)
+ {
+ /*
+ Cycle an image colormap.
+ */
+ (void) CycleColormapImage(*image,MagickAtoI(argv[++i]));
+ continue;
+ }
+ break;
+ }
+ case 'd':
+ {
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (*option == '+')
+ (void) RemoveDefinitions(clone_info,argv[i]);
+ else
+ (void) AddDefinitions(clone_info,argv[i],&(*image)->exception);
+ break;
+ }
+ if (LocaleCompare("delay",option+1) == 0)
+ {
+ double
+ maximum_delay,
+ minimum_delay;
+
+ /*
+ Set image delay.
+ */
+ if (*option == '+')
+ {
+ (*image)->delay=0;
+ continue;
+ }
+ count=sscanf(argv[++i],"%lf-%lf",&minimum_delay,&maximum_delay);
+ if (count == 1)
+ (*image)->delay=(unsigned long) minimum_delay;
+ else
+ {
+ if ((*image)->delay < minimum_delay)
+ (*image)->delay=(unsigned long) minimum_delay;
+ if ((*image)->delay > maximum_delay)
+ (*image)->delay=(unsigned long) maximum_delay;
+ }
+ continue;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ /*
+ Set image density.
+ */
+ (void) CloneString(&clone_info->density,argv[++i]);
+ (void) CloneString(&draw_info->density,clone_info->density);
+ count=GetMagickDimension(clone_info->density,
+ &(*image)->x_resolution,
+ &(*image)->y_resolution,NULL,NULL);
+ if (count != 2)
+ (*image)->y_resolution=(*image)->x_resolution;
+ continue;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ /* (*image)->depth = MagickAtoL(argv[++i]); */
+ (void) SetImageDepth(*image,MagickAtoL(argv[++i]));
+ continue;
+ }
+ if (LocaleCompare("despeckle",option+1) == 0)
+ {
+ Image
+ *despeckle_image;
+
+ /*
+ Reduce the speckles within an image.
+ */
+ despeckle_image=DespeckleImage(*image,&(*image)->exception);
+ if (despeckle_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=despeckle_image;
+ continue;
+ }
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ (void) CloneString(&clone_info->server_name,argv[++i]);
+ (void) CloneString(&draw_info->server_name,clone_info->server_name);
+ continue;
+ }
+ if (LocaleCompare("dispose",option+1) == 0)
+ {
+ DisposeType
+ dispose;;
+
+ if (*option == '+')
+ {
+ (*image)->dispose=UndefinedDispose;
+ continue;
+ }
+ option=argv[++i];
+ dispose=UndefinedDispose;
+ if (LocaleCompare("0",option) == 0)
+ dispose=UndefinedDispose;
+ if (LocaleCompare("1",option) == 0)
+ dispose=NoneDispose;
+ if (LocaleCompare("2",option) == 0)
+ dispose=BackgroundDispose;
+ if (LocaleCompare("3",option) == 0)
+ dispose=PreviousDispose;
+ if (LocaleCompare("Background",option) == 0)
+ dispose=BackgroundDispose;
+ if (LocaleCompare("None",option) == 0)
+ dispose=NoneDispose;
+ if (LocaleCompare("Previous",option) == 0)
+ dispose=PreviousDispose;
+ if (LocaleCompare("Undefined",option) == 0)
+ dispose=UndefinedDispose;
+ (*image)->dispose=dispose;
+ continue;
+ }
+ if (LocaleCompare("dither",option+1) == 0)
+ {
+ clone_info->dither=(*option == '-');
+ quantize_info.dither=clone_info->dither;
+ (*image)->dither=quantize_info.dither;
+ continue;
+ }
+ if (LocaleCompare("draw",option+1) == 0)
+ {
+ /*
+ Draw image.
+ */
+ (void) CloneString(&draw_info->primitive,argv[++i]);
+ (void) DrawImage(*image,draw_info);
+ continue;
+ }
+ break;
+ }
+ case 'e':
+ {
+ if (LocaleCompare("edge",option+1) == 0)
+ {
+ double
+ radius;
+
+ Image
+ *edge_image;
+
+ /*
+ Enhance edges in the image.
+ */
+ radius=MagickAtoF(argv[++i]);
+ edge_image=EdgeImage(*image,radius,&(*image)->exception);
+ if (edge_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=edge_image;
+ continue;
+ }
+ if (LocaleCompare("emboss",option+1) == 0)
+ {
+ double
+ radius,
+ sigma;
+
+ Image
+ *emboss_image;
+
+ /*
+ Emboss the image.
+ */
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(argv[++i],&radius,&sigma,NULL,NULL);
+ emboss_image=EmbossImage(*image,radius,sigma,&(*image)->exception);
+ if (emboss_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=emboss_image;
+ continue;
+ }
+ if (LocaleCompare("encoding",option+1) == 0)
+ {
+ (void) CloneString(&draw_info->encoding,argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("endian",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ clone_info->endian=NativeEndian;
+ continue;
+ }
+ option=argv[++i];
+ clone_info->endian=StringToEndianType(option);
+ continue;
+ }
+ if (LocaleCompare("enhance",option+1) == 0)
+ {
+ Image
+ *enhance_image;
+
+ /*
+ Enhance image.
+ */
+ enhance_image=EnhanceImage(*image,&(*image)->exception);
+ if (enhance_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=enhance_image;
+ continue;
+ }
+ if (LocaleCompare("equalize",option+1) == 0)
+ {
+ /*
+ Equalize image.
+ */
+ (void) EqualizeImage(*image);
+ continue;
+ }
+ if (LocaleCompare("extent",option+1) == 0)
+ {
+ Image
+ *extent_image;
+
+ /*
+ Extent image.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickFalse,&geometry);
+ if (geometry.width == 0)
+ geometry.width=(*image)->columns;
+ if (geometry.height == 0)
+ geometry.height=(*image)->rows;
+ geometry.x=(-geometry.x);
+ geometry.y=(-geometry.y);
+ extent_image=ExtentImage(*image,&geometry,&(*image)->exception);
+ if (extent_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=extent_image;
+ continue;
+ }
+ break;
+ }
+ case 'f':
+ {
+ if (LocaleCompare("fill",option+1) == 0)
+ {
+ (void) QueryColorDatabase(argv[++i],&draw_info->fill,
+ &(*image)->exception);
+ continue;
+ }
+ if (LocaleCompare("filter",option+1) == 0)
+ {
+ FilterTypes
+ filter;
+
+ if (*option == '+')
+ {
+ (*image)->filter=DefaultResizeFilter;
+ continue;
+ }
+ option=argv[++i];
+ filter=StringToFilterTypes(option);
+ (*image)->filter=filter;
+ continue;
+ }
+ if (LocaleCompare("flip",option+1) == 0)
+ {
+ Image
+ *flip_image;
+
+ /*
+ Flip image scanlines.
+ */
+ flip_image=FlipImage(*image,&(*image)->exception);
+ if (flip_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=flip_image;
+ continue;
+ }
+ if (LocaleCompare("flop",option+1) == 0)
+ {
+ Image
+ *flop_image;
+
+ /*
+ Flop image scanlines.
+ */
+ flop_image=FlopImage(*image,&(*image)->exception);
+ if (flop_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=flop_image;
+ continue;
+ }
+ if (LocaleCompare("frame",option+1) == 0)
+ {
+ Image
+ *frame_image;
+
+ FrameInfo
+ frame_info;
+
+ /*
+ Surround image with an ornamental border.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickFalse,&geometry);
+ frame_info.width=geometry.width;
+ frame_info.height=geometry.height;
+ frame_info.outer_bevel=geometry.x;
+ frame_info.inner_bevel=geometry.y;
+ frame_info.x=(long) frame_info.width;
+ frame_info.y=(long) frame_info.height;
+ frame_info.width=(*image)->columns+2*frame_info.width;
+ frame_info.height=(*image)->rows+2*frame_info.height;
+ frame_image=FrameImage(*image,&frame_info,&(*image)->exception);
+ if (frame_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=frame_image;
+ continue;
+ }
+ if (LocaleCompare("fuzz",option+1) == 0)
+ {
+ (*image)->fuzz=StringToDouble(argv[++i],MaxRGB);
+ continue;
+ }
+ if (LocaleCompare("font",option+1) == 0)
+ {
+ (void) CloneString(&clone_info->font,argv[++i]);
+ (void) CloneString(&draw_info->font,clone_info->font);
+ continue;
+ }
+ break;
+ }
+ case 'g':
+ {
+ if (LocaleCompare("gamma",option+1) == 0)
+ {
+ if (*option == '+')
+ (*image)->gamma=MagickAtoF(argv[++i]);
+ else
+ (void) GammaImage(*image,argv[++i]);
+ continue;
+ }
+ if ((LocaleCompare("gaussian",option+1) == 0) ||
+ (LocaleCompare("gaussian-blur",option+1) == 0))
+ {
+ double
+ radius,
+ sigma;
+
+ Image
+ *blur_image;
+
+ /*
+ Gaussian blur image.
+ */
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(argv[++i],&radius,&sigma,NULL,NULL);
+ blur_image=
+ GaussianBlurImage(*image,radius,sigma,&(*image)->exception);
+ if (blur_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=blur_image;
+ continue;
+ }
+ if (LocaleCompare("geometry",option+1) == 0)
+ {
+ Image
+ *zoom_image;
+
+ /*
+ Resize image.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickTrue,&geometry);
+ if ((geometry.width == (*image)->columns) &&
+ (geometry.height == (*image)->rows))
+ break;
+ zoom_image=ZoomImage(*image,geometry.width,geometry.height,
+ &(*image)->exception);
+ if (zoom_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=zoom_image;
+ continue;
+ }
+ if (LocaleCompare("gravity",option+1) == 0)
+ {
+ GravityType
+ gravity;
+
+ if (*option == '+')
+ {
+ draw_info->gravity=(GravityType) ForgetGravity;
+ (*image)->gravity=(GravityType) ForgetGravity;
+ continue;
+ }
+ option=argv[++i];
+ gravity=StringToGravityType(option);
+ draw_info->gravity=gravity;
+ (*image)->gravity=gravity;
+ continue;
+ }
+ if (LocaleCompare("green-primary",option+1) == 0)
+ {
+ /*
+ Green chromaticity primary point.
+ */
+ if (*option == '+')
+ {
+ (*image)->chromaticity.green_primary.x=0.0;
+ (*image)->chromaticity.green_primary.y=0.0;
+ continue;
+ }
+ (void) sscanf(argv[++i],"%lf%*[,/]%lf",
+ &(*image)->chromaticity.green_primary.x,
+ &(*image)->chromaticity.green_primary.y);
+ continue;
+ }
+ break;
+ }
+ case 'h':
+ {
+ if (LocaleCompare("hald-clut",option+1) == 0)
+ {
+ Image
+ *clut_image;
+
+ (void) strlcpy(clone_info->filename,argv[++i],MaxTextExtent);
+ clut_image=ReadImage(clone_info,&(*image)->exception);
+ if (clut_image == (Image *) NULL)
+ continue;
+
+ (void) HaldClutImage(*image,clut_image);
+
+ (void) DestroyImage(clut_image);
+ clut_image=(Image *) NULL;
+ continue;
+ }
+ break;
+ }
+ case 'i':
+ {
+ if (LocaleCompare("implode",option+1) == 0)
+ {
+ double
+ amount;
+
+ Image
+ *implode_image;
+
+ /*
+ Implode image.
+ */
+ amount=MagickAtoF(argv[++i]);
+ implode_image=ImplodeImage(*image,amount,&(*image)->exception);
+ if (implode_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=implode_image;
+ continue;
+ }
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ clone_info->interlace=UndefinedInterlace;
+ continue;
+ }
+ option=argv[++i];
+ clone_info->interlace=StringToInterlaceType(option);
+ continue;
+ }
+ if (LocaleCompare("intent",option+1) == 0)
+ {
+ RenderingIntent
+ rendering_intent;
+
+ if (*option == '+')
+ {
+ (*image)->rendering_intent=UndefinedIntent;
+ continue;
+ }
+ option=argv[++i];
+ rendering_intent=UndefinedIntent;
+ if (LocaleCompare("Absolute",option) == 0)
+ rendering_intent=AbsoluteIntent;
+ if (LocaleCompare("Perceptual",option) == 0)
+ rendering_intent=PerceptualIntent;
+ if (LocaleCompare("Relative",option) == 0)
+ rendering_intent=RelativeIntent;
+ if (LocaleCompare("Saturation",option) == 0)
+ rendering_intent=SaturationIntent;
+ (*image)->rendering_intent=rendering_intent;
+ continue;
+ }
+ break;
+ }
+ case 'l':
+ {
+ if (LocaleCompare("label",option+1) == 0)
+ {
+ (void) SetImageAttribute(*image,"label",(char *) NULL);
+ if (*option == '-')
+ (void) SetImageAttribute(*image,"label",argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("lat",option+1) == 0)
+ {
+ Image
+ *threshold_image;
+
+ double
+ offset;
+
+ unsigned long
+ height,
+ width;
+
+ /*
+ Local adaptive threshold image.
+ */
+ offset=0;
+ height=3;
+ width=3;
+ (void) sscanf(argv[++i],"%lux%lu%lf",&width,&height,&offset);
+ if (strchr(argv[i],'%') != (char *) NULL)
+ offset*=((double) MaxRGB/100.0);
+ threshold_image=AdaptiveThresholdImage(*image,width,height,offset,
+ &(*image)->exception);
+ if (threshold_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=threshold_image;
+ continue;
+ }
+ if (LocaleCompare("level",option+1) == 0)
+ {
+ (void) LevelImage(*image,argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("linewidth",option+1) == 0)
+ {
+ draw_info->stroke_width=MagickAtoF(argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("loop",option+1) == 0)
+ {
+ /*
+ Set image iterations.
+ */
+ (*image)->iterations=MagickAtoL(argv[++i]);
+ continue;
+ }
+ break;
+ }
+ case 'm':
+ {
+ if (LocaleCompare("magnify",option+1) == 0)
+ {
+ Image
+ *magnify_image;
+
+ /*
+ Magnify image.
+ */
+ magnify_image=MagnifyImage(*image,&(*image)->exception);
+ if (magnify_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=magnify_image;
+ continue;
+ }
+ if (LocaleCompare("map",option+1) == 0)
+ {
+ /*
+ Transform image colors to match this set of colors.
+ */
+ if (*option == '+')
+ continue;
+ (void) strlcpy(clone_info->filename,argv[++i],MaxTextExtent);
+ {
+ Image
+ *map_image;
+
+ if ((map_image=ReadImage(clone_info,&(*image)->exception)) !=
+ (Image *) NULL)
+ {
+ (void) MapImage(*image,map_image,quantize_info.dither);
+ DestroyImage(map_image);
+ }
+ }
+ continue;
+ }
+ if (LocaleCompare("mask",option+1) == 0)
+ {
+ Image
+ *mask;
+
+ long
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ if (*option == '+')
+ {
+ /*
+ Remove a clip mask.
+ */
+ (void) SetImageClipMask(*image,(Image *) NULL);
+ continue;
+ }
+ /*
+ Set the image clip mask.
+ */
+ (void) strlcpy(clone_info->filename,argv[++i],MaxTextExtent);
+ mask=ReadImage(clone_info,&(*image)->exception);
+ if (mask == (Image *) NULL)
+ continue;
+ for (y=0; y < (long) mask->rows; y++)
+ {
+ q=GetImagePixels(mask,0,y,mask->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) mask->columns; x++)
+ {
+ if (!mask->matte)
+ q->opacity=PixelIntensityToQuantum(q);
+ q->red=q->opacity;
+ q->green=q->opacity;
+ q->blue=q->opacity;
+ q++;
+ }
+ if (!SyncImagePixels(mask))
+ break;
+ }
+ (void) SetImageType(mask,TrueColorMatteType);
+ (void) SetImageClipMask(*image,mask);
+ /*
+ SetImageClipMask clones the image.
+ */
+ DestroyImage(mask);
+ }
+ if (LocaleCompare("matte",option+1) == 0)
+ {
+ if (*option == '-')
+ if (!(*image)->matte)
+ SetImageOpacity(*image,OpaqueOpacity);
+ (*image)->matte=(*option == '-');
+ continue;
+ }
+ if (LocaleCompare("mattecolor",option+1) == 0)
+ {
+ (void) QueryColorDatabase(argv[++i],&clone_info->matte_color,
+ &(*image)->exception);
+ (*image)->matte_color=clone_info->matte_color;
+ continue;
+ }
+ if (LocaleCompare("median",option+1) == 0)
+ {
+ double
+ radius;
+
+ Image
+ *median_image;
+
+ /*
+ Median filter image.
+ */
+ radius=MagickAtoF(argv[++i]);
+ median_image=MedianFilterImage(*image,radius,&(*image)->exception);
+ if (median_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=median_image;
+ continue;
+ }
+ if (LocaleCompare("minify",option+1) == 0)
+ {
+ Image
+ *minify_image;
+
+ /*
+ Minify image.
+ */
+ minify_image=MinifyImage(*image,&(*image)->exception);
+ if (minify_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=minify_image;
+ continue;
+ }
+ if (LocaleCompare("modulate",option+1) == 0)
+ {
+ (void) ModulateImage(*image,argv[++i]);
+ continue;
+ }
+ if ((LocaleCompare("mono",option+1) == 0) ||
+ (LocaleCompare("monochrome",option+1) == 0))
+ {
+ clone_info->monochrome=MagickTrue;
+ (void) SetImageType(*image,BilevelType);
+ continue;
+ }
+ if (LocaleCompare("motion-blur",option+1) == 0)
+ {
+ double
+ angle,
+ radius,
+ sigma;
+
+ Image
+ *blur_image;
+
+ /*
+ Motion blur image.
+ */
+ radius=0.0;
+ sigma=1.0;
+ angle=0.0;
+ (void) GetMagickDimension(argv[++i],&radius,&sigma,&angle,NULL);
+ blur_image=MotionBlurImage(*image,radius,sigma,angle,&(*image)->exception);
+ if (blur_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=blur_image;
+ continue;
+ }
+ break;
+ }
+ case 'n':
+ {
+ if (LocaleCompare("negate",option+1) == 0)
+ {
+ (void) NegateImage(*image,*option == '+');
+ continue;
+ }
+ if (LocaleCompare("noise",option+1) == 0)
+ {
+ Image
+ *noisy_image;
+
+ if (*option == '-')
+ noisy_image=
+ ReduceNoiseImage(*image,MagickAtoL(argv[++i]),&(*image)->exception);
+ else
+ {
+ NoiseType
+ noise_type;
+
+ /*
+ Add noise to image.
+ */
+ option=argv[++i];
+ noise_type=StringToNoiseType(option);
+ noisy_image=
+ AddNoiseImage(*image,noise_type,&(*image)->exception);
+ }
+ if (noisy_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=noisy_image;
+ continue;
+ }
+ if (LocaleCompare("normalize",option+1) == 0)
+ {
+ (void) NormalizeImage(*image);
+ continue;
+ }
+ break;
+ }
+ case 'o':
+ {
+ if (LocaleCompare("opaque",option+1) == 0)
+ {
+ PixelPacket
+ target;
+
+ (void) AcquireOnePixelByReference(*image,&target,0,0,&(*image)->exception);
+ (void) QueryColorDatabase(argv[++i],&target,&(*image)->exception);
+ (void) OpaqueImage(*image,target,draw_info->fill);
+ continue;
+ }
+ if (LocaleCompare("operator",option+1) == 0)
+ {
+ ChannelType
+ channel;
+
+ QuantumOperator
+ quantum_operator;
+
+ double
+ rvalue;
+
+ /* channel */
+ channel=StringToChannelType(argv[++i]);
+
+ /* operator id */
+ quantum_operator=StringToQuantumOperator(argv[++i]);
+
+ /* rvalue */
+ option=argv[++i];
+ rvalue=StringToDouble(option,MaxRGB);
+ (void) QuantumOperatorImage(*image,channel,quantum_operator,
+ rvalue,&(*image)->exception);
+
+ continue;
+ }
+ if (LocaleCompare("ordered-dither",option+1) == 0)
+ {
+ /*
+ Ordered-dither image.
+ */
+ (void) RandomChannelThresholdImage(*image,argv[i+1],argv[i+2],
+ &(*image)->exception);
+ i+=2;
+ continue;
+ }
+ if (LocaleCompare("orient",option+1) == 0)
+ {
+ (*image)->orientation=UndefinedOrientation;
+ if (*option == '-')
+ {
+ char orientation[MaxTextExtent];
+ (*image)->orientation=StringToOrientationType(argv[++i]);
+ FormatString(orientation,"%d",(*image)->orientation);
+ (void) SetImageAttribute((*image),"EXIF:Orientation",orientation);
+ }
+ continue;
+ }
+ break;
+ }
+ case 'p':
+ {
+ if (LocaleCompare("page",option+1) == 0)
+ {
+ if (option[0] == '+')
+ {
+ (*image)->page.width=0U;
+ (*image)->page.height=0U;
+ (*image)->page.x=0;
+ (*image)->page.y=0;
+ }
+ else
+ {
+ char
+ *geometry_str;
+
+ geometry_str=GetPageGeometry(argv[++i]);
+ (void) GetGeometry(geometry_str,&(*image)->page.x,&(*image)->page.y,
+ &(*image)->page.width,&(*image)->page.height);
+ MagickFreeMemory(geometry_str);
+ }
+ }
+ if (LocaleCompare("paint",option+1) == 0)
+ {
+ double
+ radius;
+
+ Image
+ *paint_image;
+
+ /*
+ Oil paint image.
+ */
+ radius=MagickAtoF(argv[++i]);
+ paint_image=OilPaintImage(*image,radius,&(*image)->exception);
+ if (paint_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=paint_image;
+ continue;
+ }
+ if (LocaleCompare("pen",option+1) == 0)
+ {
+ (void) QueryColorDatabase(argv[++i],&draw_info->fill,
+ &(*image)->exception);
+ continue;
+ }
+ if (LocaleCompare("pointsize",option+1) == 0)
+ {
+ clone_info->pointsize=MagickAtoF(argv[++i]);
+ draw_info->pointsize=clone_info->pointsize;
+ continue;
+ }
+ if (LocaleCompare("profile",option+1) == 0)
+ {
+ void
+ *client_data;
+
+ if (*option == '+')
+ {
+ /*
+ Remove a ICM, IPTC, or generic profile from the image.
+ */
+ (void) ProfileImage(*image,argv[++i],
+ (unsigned char *) NULL,0,MagickTrue);
+ continue;
+ }
+ else if (*option == '-')
+ {
+ /*
+ Add a ICM, IPTC, or generic profile to the image.
+ */
+
+ Image
+ *profile_image;
+
+ ProfileInfo
+ profile_info;
+
+ const char
+ *profile_name;
+
+ size_t
+ profile_length;
+
+ const unsigned char *
+ profile_data;
+
+ ImageProfileIterator
+ profile_iterator;
+
+ client_data=clone_info->client_data;
+
+ /*
+ FIXME: Next three lines replace:
+ clone_info->client_data=(void *) &(*image)->iptc_profile;
+ */
+ profile_info.name="IPTC";
+ profile_info.info=
+ (unsigned char *) GetImageProfile(*image,profile_info.name,
+ &profile_info.length);
+ clone_info->client_data=&profile_info; /* used to pass profile to meta.c */
+
+ (void) strlcpy(clone_info->filename,argv[++i],MaxTextExtent);
+ profile_image=ReadImage(clone_info,&(*image)->exception);
+ if (profile_image == (Image *) NULL)
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Failed to load profile from file \"%s\"",
+ clone_info->filename);
+ continue;
+ }
+ /*
+ Transfer profile(s) to image.
+ */
+ profile_iterator=AllocateImageProfileIterator(profile_image);
+ while(NextImageProfile(profile_iterator,&profile_name,&profile_data,
+ &profile_length) != MagickFail)
+ {
+ size_t
+ existing_length;
+
+ if (((LocaleCompare(profile_name,"ICC") == 0) ||
+ (LocaleCompare(profile_name,"ICM") == 0)) &&
+ (GetImageProfile(*image,"ICM",&existing_length)))
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Transform using %s profile \"%s\","
+ " %lu bytes",
+ profile_name,clone_info->filename,
+ (unsigned long) profile_length);
+ (void) ProfileImage(*image,profile_name,
+ (unsigned char *) profile_data,
+ profile_length,MagickTrue);
+ }
+ else
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Adding %s profile \"%s\","
+ " %lu bytes",
+ profile_name,clone_info->filename,
+ (unsigned long) profile_length);
+ (void) SetImageProfile(*image,profile_name,profile_data,profile_length);
+ }
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+ DestroyImage(profile_image);
+ profile_image=(Image *) NULL;
+ clone_info->client_data=client_data;
+ }
+ continue;
+ }
+ break;
+ }
+ case 'q':
+ {
+ if (LocaleCompare("quality",option+1) == 0)
+ {
+ /*
+ Set image compression quality.
+ */
+ clone_info->quality=MagickAtoL(argv[++i]);
+ continue;
+ }
+ break;
+ }
+ case 'r':
+ {
+ if (LocaleCompare("raise",option+1) == 0)
+ {
+ /*
+ Surround image with a raise of solid color.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickFalse,&geometry);
+ (void) RaiseImage(*image,&geometry,*option == '-');
+ continue;
+ }
+ if (LocaleCompare("random-threshold",option+1) == 0)
+ {
+ /*
+ Threshold image.
+ */
+ (void) RandomChannelThresholdImage(*image,argv[i+1],argv[i+2],
+ &(*image)->exception);
+ i+=2;
+ continue;
+ }
+ if (LocaleCompare("recolor",option+1) == 0)
+ {
+ char
+ *p,
+ token[MaxTextExtent];
+
+ double
+ *matrix;
+
+ register long
+ x;
+
+ unsigned int
+ elements,
+ order;
+
+ /*
+ Color matrix image.
+ */
+ p=argv[++i];
+ for (elements=0; *p != '\0'; elements++)
+ {
+ MagickGetToken(p,&p,token,MaxTextExtent);
+ if (token[0] == '\0')
+ break;
+ if (token[0] == ',')
+ MagickGetToken(p,&p,token,MaxTextExtent);
+ if (token[0] == '\0')
+ break;
+ }
+ order=(unsigned int) sqrt(elements);
+ if ((0 == elements) || (order*order != elements))
+ {
+ char
+ message[MaxTextExtent];
+
+ FormatString(message,"%u",elements);
+ ThrowException(&(*image)->exception,OptionError,MatrixIsNotSquare,message);
+ continue;
+ }
+ matrix=MagickAllocateArray(double *,order*order,sizeof(double));
+ if (matrix == (double *) NULL)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(ResourceLimitError,UnableToAllocateCoefficients));
+ p=argv[i];
+ for (x=0; *p != '\0'; x++)
+ {
+ MagickGetToken(p,&p,token,MaxTextExtent);
+ if (token[0] == ',')
+ MagickGetToken(p,&p,token,MaxTextExtent);
+ if (token[0] == '\0')
+ break;
+ matrix[x]=MagickAtoF(token);
+ }
+ for ( ; x < (long) (order*order); x++)
+ matrix[x]=0.0;
+ (void) ColorMatrixImage(*image,order,matrix);
+ MagickFreeMemory(matrix);
+ continue;
+ }
+ if (LocaleCompare("red-primary",option+1) == 0)
+ {
+ /*
+ Red chromaticity primary point.
+ */
+ if (*option == '+')
+ {
+ (*image)->chromaticity.red_primary.x=0.0;
+ (*image)->chromaticity.red_primary.y=0.0;
+ continue;
+ }
+ (void) sscanf(argv[++i],"%lf%*[,/]%lf",
+ &(*image)->chromaticity.red_primary.x,
+ &(*image)->chromaticity.red_primary.y);
+ continue;
+ }
+ if (LocaleCompare("region",option+1) == 0)
+ {
+ Image
+ *crop_image;
+
+ if (region_image != (Image *) NULL)
+ {
+ /*
+ Composite region.
+ */
+ (void) CompositeImage(region_image,(*image)->matte ?
+ OverCompositeOp : CopyCompositeOp,*image,region_geometry.x,
+ region_geometry.y);
+ DestroyImage(*image);
+ *image=region_image;
+ }
+ if (*option == '+')
+ continue;
+ /*
+ Apply transformations to a selected region of the image.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickFalse,&region_geometry);
+ crop_image=CropImage(*image,&region_geometry,&(*image)->exception);
+ if (crop_image == (Image *) NULL)
+ break;
+ region_image=(*image);
+ *image=crop_image;
+ continue;
+ }
+ if (LocaleCompare("render",option+1) == 0)
+ {
+ draw_info->render=(*option == '+');
+ continue;
+ }
+ if (LocaleCompare("repage",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ /* Reset page to defaults */
+ (*image)->page.width=0U;
+ (*image)->page.height=0U;
+ (*image)->page.x=0;
+ (*image)->page.y=0;
+ }
+ else
+ {
+ /* Adjust page offsets */
+ (void) ResetImagePage(*image,argv[++i]);
+ }
+ continue;
+ }
+ if (LocaleCompare("resample",option+1) == 0)
+ {
+ Image
+ *resample_image;
+
+ char
+ resample_density[MaxTextExtent];
+
+ double
+ x_resolution,
+ y_resolution;
+
+ unsigned long
+ resample_height,
+ resample_width;
+
+ /*
+ Verify that image contains useful resolution information.
+ */
+ if ( ((*image)->x_resolution == 0) || ((*image)->y_resolution == 0) )
+ {
+ ThrowException(&(*image)->exception,ImageError,
+ ImageDoesNotContainResolution,image_info->filename);
+ continue;
+ }
+
+ /*
+ Obtain target resolution.
+ */
+ {
+ unsigned long
+ x_integral_resolution=0,
+ y_integral_resolution=0;
+
+ long
+ x,
+ y;
+
+ int
+ flags;
+
+ flags=GetGeometry(argv[++i],&x,&y,&x_integral_resolution,&y_integral_resolution);
+ if (!(flags & HeightValue))
+ y_integral_resolution=x_integral_resolution;
+ FormatString(resample_density,"%lux%lu",x_integral_resolution,y_integral_resolution);
+ x_resolution=x_integral_resolution;
+ y_resolution=y_integral_resolution;
+ }
+
+ resample_width=(unsigned long)
+ ((*image)->columns*(x_resolution/(*image)->x_resolution)+0.5);
+ if (resample_width < 1)
+ resample_width = 1;
+ resample_height=(unsigned long)
+ ((*image)->rows*(y_resolution/(*image)->y_resolution)+0.5);
+ if (resample_height < 1)
+ resample_height = 1;
+
+ (void) CloneString(&clone_info->density,resample_density);
+ (void) CloneString(&draw_info->density,resample_density);
+ (*image)->x_resolution=x_resolution;
+ (*image)->y_resolution=y_resolution;
+ if ((((*image)->columns == resample_width)) && ((*image)->rows == resample_height))
+ break;
+
+ /*
+ Resample image.
+ */
+ resample_image=ResizeImage(*image,resample_width,resample_height,(*image)->filter,
+ (*image)->blur,&(*image)->exception);
+ if (resample_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=resample_image;
+ continue;
+ }
+ if (LocaleCompare("resize",option+1) == 0)
+ {
+ Image
+ *resize_image;
+
+ /*
+ Resize image.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickTrue,&geometry);
+ if ((geometry.width == (*image)->columns) &&
+ (geometry.height == (*image)->rows))
+ break;
+ resize_image=ResizeImage(*image,geometry.width,geometry.height,
+ (*image)->filter,(*image)->blur,&(*image)->exception);
+ if (resize_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=resize_image;
+ continue;
+ }
+ if (LocaleCompare("roll",option+1) == 0)
+ {
+ Image
+ *roll_image;
+
+ /*
+ Roll image.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickFalse,&geometry);
+ roll_image=RollImage(*image,geometry.x,geometry.y,
+ &(*image)->exception);
+ if (roll_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=roll_image;
+ continue;
+ }
+ if (LocaleCompare("rotate",option+1) == 0)
+ {
+ double
+ degrees;
+
+ Image
+ *rotate_image;
+
+ /*
+ Check for conditional image rotation.
+ */
+ i++;
+ if (strchr(argv[i],'>') != (char *) NULL)
+ if ((*image)->columns <= (*image)->rows)
+ break;
+ if (strchr(argv[i],'<') != (char *) NULL)
+ if ((*image)->columns >= (*image)->rows)
+ break;
+ /*
+ Rotate image.
+ */
+ degrees=MagickAtoF(argv[i]);
+ rotate_image=RotateImage(*image,degrees,&(*image)->exception);
+ if (rotate_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=rotate_image;
+ continue;
+ }
+ break;
+ }
+ case 's':
+ {
+ if (LocaleCompare("sample",option+1) == 0)
+ {
+ Image
+ *sample_image;
+
+ /*
+ Sample image with pixel replication.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickTrue,&geometry);
+ if ((geometry.width == (*image)->columns) &&
+ (geometry.height == (*image)->rows))
+ break;
+ sample_image=SampleImage(*image,geometry.width,geometry.height,
+ &(*image)->exception);
+ if (sample_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=sample_image;
+ continue;
+ }
+ if (LocaleCompare("sampling_factor",option+1) == 0)
+ {
+ /*
+ Set image sampling factor.
+ */
+ (void) CloneString(&clone_info->sampling_factor,argv[++i]);
+ NormalizeSamplingFactor(clone_info);
+ continue;
+ }
+ if (LocaleCompare("sans",option+1) == 0)
+ if (*option == '-')
+ i++;
+ if (LocaleCompare("scale",option+1) == 0)
+ {
+ Image
+ *scale_image;
+
+ /*
+ Resize image.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickTrue,&geometry);
+ if ((geometry.width == (*image)->columns) &&
+ (geometry.height == (*image)->rows))
+ break;
+ scale_image=ScaleImage(*image,geometry.width,geometry.height,
+ &(*image)->exception);
+ if (scale_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=scale_image;
+ continue;
+ }
+ if (LocaleCompare("scene",option+1) == 0)
+ {
+ (*image)->scene=MagickAtoL(argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("set",option+1) == 0)
+ {
+ const char
+ *key,
+ *value;
+
+ key=argv[++i];
+ (void) SetImageAttribute(*image,key,(char *) NULL);
+ if (*option == '-')
+ {
+ value=argv[++i];
+ (void) SetImageAttribute(*image,key,value);
+ }
+ continue;
+ }
+ if (LocaleCompare("segment",option+1) == 0)
+ {
+ double
+ cluster_threshold,
+ smoothing_threshold;
+
+ /*
+ Segment image.
+ */
+ cluster_threshold=1.0;
+ smoothing_threshold=1.5;
+ (void) GetMagickDimension(argv[++i],&cluster_threshold,
+ &smoothing_threshold,NULL,NULL);
+ (void) SegmentImage(*image,quantize_info.colorspace,
+ clone_info->verbose,cluster_threshold,smoothing_threshold);
+ continue;
+ }
+ if (LocaleCompare("shade",option+1) == 0)
+ {
+ double
+ azimuth,
+ elevation;
+
+ Image
+ *shade_image;
+
+ /*
+ Shade image.
+ */
+ azimuth=30.0;
+ elevation=30.0;
+ (void) GetMagickDimension(argv[++i],&azimuth,&elevation,NULL,NULL);
+ shade_image=ShadeImage(*image,*option == '-',azimuth,elevation,
+ &(*image)->exception);
+ if (shade_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=shade_image;
+ continue;
+ }
+ if (LocaleCompare("sharpen",option+1) == 0)
+ {
+ double
+ radius,
+ sigma;
+
+ Image
+ *sharp_image;
+
+ /*
+ Gaussian sharpen image.
+ */
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(argv[++i],&radius,&sigma,NULL,NULL);
+ sharp_image=SharpenImage(*image,radius,sigma,&(*image)->exception);
+ if (sharp_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=sharp_image;
+ continue;
+ }
+ if (LocaleCompare("shave",option+1) == 0)
+ {
+ Image
+ *shave_image;
+
+ /*
+ Shave the image edges.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickFalse,&geometry);
+ shave_image=ShaveImage(*image,&geometry,&(*image)->exception);
+ if (shave_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=shave_image;
+ continue;
+ }
+ if (LocaleCompare("shear",option+1) == 0)
+ {
+ double
+ x_shear,
+ y_shear;
+
+ Image
+ *shear_image;
+
+ /*
+ Shear image.
+ */
+ x_shear=0.0;
+ y_shear=0.0;
+ (void) GetMagickDimension(argv[++i],&x_shear,&y_shear,NULL,NULL);
+ shear_image=ShearImage(*image,x_shear,y_shear,&(*image)->exception);
+ if (shear_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=shear_image;
+ continue;
+ }
+ if (LocaleCompare("solarize",option+1) == 0)
+ {
+ double
+ threshold;
+
+ threshold=StringToDouble(argv[++i],MaxRGB);
+ (void) SolarizeImage(*image,threshold);
+ continue;
+ }
+ if (LocaleCompare("spread",option+1) == 0)
+ {
+ unsigned int
+ amount;
+
+ Image
+ *spread_image;
+
+ /*
+ Spread an image.
+ */
+ amount=MagickAtoI(argv[++i]);
+ spread_image=SpreadImage(*image,amount,&(*image)->exception);
+ if (spread_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=spread_image;
+ continue;
+ }
+ if (LocaleCompare("strip",option+1) == 0)
+ {
+ (void) StripImage(*image);
+ continue;
+ }
+ if (LocaleCompare("stroke",option+1) == 0)
+ {
+ (void) QueryColorDatabase(argv[++i],&draw_info->stroke,
+ &(*image)->exception);
+ continue;
+ }
+ if (LocaleCompare("strokewidth",option+1) == 0)
+ {
+ draw_info->stroke_width=MagickAtoF(argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("swirl",option+1) == 0)
+ {
+ double
+ degrees;
+
+ Image
+ *swirl_image;
+
+ /*
+ Swirl image.
+ */
+ degrees=MagickAtoF(argv[++i]);
+ swirl_image=SwirlImage(*image,degrees,&(*image)->exception);
+ if (swirl_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=swirl_image;
+ continue;
+ }
+ break;
+ }
+ case 't':
+ {
+ if (LocaleCompare("threshold",option+1) == 0)
+ {
+ /*
+ Threshold image.
+ */
+ double
+ threshold;
+
+ ++i;
+ count=sscanf(argv[i],"%lf",&threshold);
+ if (count > 0)
+ {
+ if (strchr(argv[i],'%') != (char *) NULL)
+ threshold *= MaxRGB/100.0;
+ (void) ThresholdImage(*image,threshold);
+ }
+ continue;
+ }
+ if (LocaleCompare("thumbnail",option+1) == 0)
+ {
+ Image
+ *resize_image;
+
+ /*
+ Resize image.
+ */
+ (void) GetImageGeometry(*image,argv[++i],MagickTrue,&geometry);
+ if ((geometry.width == (*image)->columns) &&
+ (geometry.height == (*image)->rows))
+ break;
+ resize_image=ThumbnailImage(*image,geometry.width,geometry.height,
+ &(*image)->exception);
+ if (resize_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=resize_image;
+ continue;
+ }
+ if (LocaleCompare("tile",option+1) == 0)
+ {
+ Image
+ *fill_pattern;
+
+ (void) strlcpy(clone_info->filename,argv[++i],MaxTextExtent);
+ fill_pattern=ReadImage(clone_info,&(*image)->exception);
+ if (fill_pattern == (Image *) NULL)
+ continue;
+ draw_info->fill_pattern=
+ CloneImage(fill_pattern,0,0,MagickTrue,&(*image)->exception);
+ DestroyImage(fill_pattern);
+ fill_pattern=(Image *) NULL;
+ continue;
+ }
+ if (LocaleCompare("transform",option+1) == 0)
+ {
+ Image
+ *transform_image;
+
+ /*
+ Affine transform image.
+ */
+ transform_image=AffineTransformImage(*image,&draw_info->affine,
+ &(*image)->exception);
+ if (transform_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=transform_image;
+ continue;
+ }
+ if (LocaleCompare("transparent",option+1) == 0)
+ {
+ PixelPacket
+ target;
+
+ (void) AcquireOnePixelByReference(*image,&target,0,0,&(*image)->exception);
+ (void) QueryColorDatabase(argv[++i],&target,&(*image)->exception);
+ (void) TransparentImage(*image,target,TransparentOpacity);
+ continue;
+ }
+ if (LocaleCompare("treedepth",option+1) == 0)
+ {
+ quantize_info.tree_depth=MagickAtoI(argv[++i]);
+ continue;
+ }
+ if (LocaleCompare("trim",option+1) == 0)
+ {
+ TransformImage(image,"0x0",(char *) NULL);
+ continue;
+ }
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ ImageType
+ image_type;
+
+ option=argv[++i];
+ image_type=StringToImageType(option);
+ (*image)->dither=image_info->dither;
+ if (UndefinedType != image_type)
+ (void) SetImageType(*image,image_type);
+ continue;
+ }
+ break;
+ }
+ case 'u':
+ {
+ if (LocaleCompare("undercolor",option+1) == 0)
+ {
+ (void) QueryColorDatabase(argv[++i],&draw_info->undercolor,
+ &(*image)->exception);
+ continue;
+ }
+ if (LocaleCompare("units",option+1) == 0)
+ {
+ ResolutionType
+ resolution_type = UndefinedResolution;
+
+ if (*option == '+')
+ {
+ }
+ else if (*option == '-')
+ {
+ option=argv[++i];
+ if (LocaleCompare("PixelsPerInch",option) == 0)
+ resolution_type=PixelsPerInchResolution;
+ else if (LocaleCompare("PixelsPerCentimeter",option) == 0)
+ resolution_type=PixelsPerCentimeterResolution;
+ else
+ {
+ ThrowException(&(*image)->exception,OptionError,
+ UnrecognizedUnitsType,option);
+ continue;
+ }
+
+ /*
+ Adjust resolution values if necessary.
+ */
+ if ( (resolution_type == PixelsPerInchResolution) &&
+ ((*image)->units == PixelsPerCentimeterResolution) )
+ {
+ (*image)->x_resolution *= 2.54;
+ (*image)->y_resolution *= 2.54;
+ }
+ else if ( (resolution_type == PixelsPerCentimeterResolution) &&
+ ((*image)->units == PixelsPerInchResolution) )
+ {
+ (*image)->x_resolution /= 2.54;
+ (*image)->y_resolution /= 2.54;
+ }
+ }
+
+ (*image)->units=resolution_type;
+ continue;
+ }
+ if (LocaleCompare("unsharp",option+1) == 0)
+ {
+ double
+ amount,
+ radius,
+ sigma,
+ threshold;
+
+ Image
+ *unsharp_image;
+
+ /*
+ Gaussian unsharpen image.
+ */
+ amount=1.0;
+ radius=0.0;
+ sigma=1.0;
+ threshold=0.05;
+ (void) GetMagickDimension(argv[++i],&radius,&sigma,&amount,&threshold);
+ unsharp_image=UnsharpMaskImage(*image,radius,sigma,amount,threshold,
+ &(*image)->exception);
+ if (unsharp_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=unsharp_image;
+ continue;
+ }
+ break;
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ clone_info->verbose+=(*option == '-');
+ quantize_info.measure_error=(*option == '-');
+ continue;
+ }
+ if (LocaleCompare("virtual-pixel",option+1) == 0)
+ {
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ if (*option == '+')
+ {
+ (void) SetImageVirtualPixelMethod(*image,UndefinedVirtualPixelMethod);
+ continue;
+ }
+ option=argv[++i];
+ virtual_pixel_method=StringToVirtualPixelMethod(option);
+ (void) SetImageVirtualPixelMethod(*image,virtual_pixel_method);
+ continue;
+ }
+ break;
+ }
+ case 'w':
+ {
+ if (LocaleCompare("wave",option+1) == 0)
+ {
+ double
+ amplitude,
+ wavelength;
+
+ Image
+ *wave_image;
+
+ /*
+ Wave image.
+ */
+ amplitude=25.0;
+ wavelength=150.0;
+ (void) GetMagickDimension(argv[++i],&amplitude,&wavelength,NULL,NULL);
+ wave_image=WaveImage(*image,amplitude,wavelength,
+ &(*image)->exception);
+ if (wave_image == (Image *) NULL)
+ break;
+ DestroyImage(*image);
+ *image=wave_image;
+ continue;
+ }
+ if (LocaleCompare("white-point",option+1) == 0)
+ {
+ /*
+ White chromaticity point.
+ */
+ if (*option == '+')
+ {
+ (*image)->chromaticity.white_point.x=0.0;
+ (*image)->chromaticity.white_point.y=0.0;
+ continue;
+ }
+ (void) sscanf(argv[++i],"%lf%*[,/]%lf",
+ &(*image)->chromaticity.white_point.x,
+ &(*image)->chromaticity.white_point.y);
+ continue;
+ }
+ if (LocaleCompare("white-threshold",option+1) == 0)
+ {
+ /*
+ White threshold image.
+ */
+ ++i;
+ (void) WhiteThresholdImage(*image,argv[i]);
+ continue;
+ }
+ if (LocaleCompare("write",option+1) == 0)
+ {
+ /*
+ Write current image to specified file.
+ */
+ Image
+ *clone_image;
+
+ ++i;
+ clone_image=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
+ if (clone_image != (Image *) NULL)
+ {
+ (void) strlcpy(clone_image->filename,argv[i],sizeof(clone_image->filename));
+ (void) WriteImage(clone_info,clone_image);
+ if (clone_info->verbose)
+ (void) DescribeImage(clone_image,stderr,MagickFalse);
+ DestroyImage(clone_image);
+ clone_image=(Image *) NULL;
+ }
+ continue;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (region_image != (Image *) NULL)
+ {
+ /*
+ Composite transformed region onto image.
+ */
+ matte=region_image->matte;
+ (void) CompositeImage(region_image,
+ (*image)->matte ? OverCompositeOp : CopyCompositeOp,*image,
+ region_geometry.x,region_geometry.y);
+ DestroyImage(*image);
+ *image=region_image;
+ (*image)->matte=matte;
+ }
+#if 0
+ if ( IsGrayColorspace(quantize_info.colorspace) )
+ {
+ /*
+ If color reduction is requested, then quantize to the requested
+ number of colors in the gray colorspace, otherwise simply
+ transform the image to the gray colorspace.
+ */
+
+ if ( quantize_info.number_colors != 0 )
+ (void) QuantizeImage(&quantize_info,*image);
+ else
+ (void) TransformColorspace(*image,quantize_info.colorspace);
+ }
+ else
+ {
+ /*
+ If color reduction is requested, and the image is DirectClass,
+ or the image is PseudoClass and the number of colors exceeds
+ the number requested, then quantize the image colors. Otherwise
+ compress an existing colormap.
+ */
+
+ if ( quantize_info.number_colors != 0 )
+ {
+ if (((*image)->storage_class == DirectClass) ||
+ ((*image)->colors > quantize_info.number_colors))
+ (void) QuantizeImage(&quantize_info,*image);
+ else
+ CompressImageColormap(*image);
+ }
+ }
+#endif
+
+ /*
+ Free resources.
+ */
+ DestroyDrawInfo(draw_info);
+ DestroyImageInfo(clone_info);
+ return((*image)->exception.severity == UndefinedException);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
++ M o g r i f y I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MogrifyImages applies next processing options to a sequence of
+% images as prescribed by command line options.
+%
+% The format of the MogrifyImage method is:
+%
+% MagickPassFail MogrifyImages(const ImageInfo *image_info,const int argc,
+% char **argv,Image **images)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info..
+%
+% o argc: Specifies a pointer to an integer describing the number of
+% elements in the argument vector.
+%
+% o argv: Specifies a pointer to a text array containing the command line
+% arguments.
+%
+% o images: The image; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport MagickPassFail MogrifyImages(const ImageInfo *image_info,
+ int argc,char **argv,Image **images)
+{
+#define MogrifyImageText "Transform image... "
+
+ char
+ *option;
+
+ Image
+ *image,
+ *mogrify_images;
+
+ register long
+ i;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ scene;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(images != (Image **) NULL);
+ assert((*images)->signature == MagickSignature);
+ if ((argc <= 0) || (*argv == (char *) NULL))
+ return(MagickPass);
+
+#if defined(DEBUG_COMMAND_PARSER)
+ fprintf(stderr,"MogrifyImages (");
+ for (image=*images; image; image=image->next)
+ {
+ if (image != *images)
+ fprintf(stderr,", ");
+ fprintf(stderr,"0x%p->%s", image, image->filename);
+ }
+ fprintf(stderr,"):");
+ for (i=0; i < argc; i++)
+ fprintf(stderr," %s",argv[i]);
+ fprintf(stderr,"\n");
+#endif /* DEBUG_COMMAND_PARSER */
+
+ scene=MagickFalse;
+ for (i=0; i < argc; i++)
+ {
+ option=argv[i];
+ if ((strlen(option) <= 1) || ((*option != '-') && (*option != '+')))
+ continue;
+ switch (*(option+1))
+ {
+ case 's':
+ {
+ if (LocaleCompare("scene",option+1) == 0)
+ scene=MagickTrue;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ /*
+ Apply options to each individual image in the list.
+ */
+ status=MagickPass;
+ mogrify_images=NewImageList();
+ i=0;
+ while ((image=RemoveFirstImageFromList(images)) != (Image *) NULL)
+ {
+ status&=MogrifyImage(image_info,argc,argv,&image);
+ {
+ Image
+ *p;
+
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ if (scene)
+ p->scene += i;
+ if (image_info->verbose)
+ (void) DescribeImage(p,stderr,MagickFalse);
+ i++;
+ }
+ }
+ AppendImageToList(&mogrify_images,image);
+ }
+
+ /*
+ Apply options to the entire image list.
+ */
+ for (i=0; i < argc; i++)
+ {
+ option=argv[i];
+ if ((strlen(option) == 1) || ((option[0] != '-') && (option[0] != '+')))
+ continue;
+ switch (*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("append",option+1) == 0)
+ {
+ Image
+ *append_image;
+
+ append_image=AppendImages(mogrify_images,*option == '-',
+ &mogrify_images->exception);
+ if (append_image != (Image *) NULL)
+ {
+ DestroyImageList(mogrify_images);
+ mogrify_images=append_image;
+ }
+ break;
+ }
+ if (LocaleCompare("average",option+1) == 0)
+ {
+ Image
+ *average_image;
+
+ average_image=AverageImages(mogrify_images,
+ &mogrify_images->exception);
+ if (average_image != (Image *) NULL)
+ {
+ DestroyImageList(mogrify_images);
+ mogrify_images=average_image;
+ }
+ break;
+ }
+ break;
+ }
+ case 'c':
+ {
+ if (LocaleCompare("coalesce",option+1) == 0)
+ {
+ Image
+ *coalesce_image;
+
+ coalesce_image=CoalesceImages(mogrify_images,
+ &mogrify_images->exception);
+ if (coalesce_image != (Image *) NULL)
+ {
+ DestroyImageList(mogrify_images);
+ mogrify_images=coalesce_image;
+ }
+ break;
+ }
+ break;
+ }
+ case 'd':
+ {
+ if (LocaleCompare("deconstruct",option+1) == 0)
+ {
+ Image
+ *deconstruct_image;
+
+ deconstruct_image=DeconstructImages(mogrify_images,
+ &mogrify_images->exception);
+ if (deconstruct_image != (Image *) NULL)
+ {
+ DestroyImageList(mogrify_images);
+ mogrify_images=deconstruct_image;
+ }
+ break;
+ }
+ break;
+ }
+ case 'f':
+ {
+ if (LocaleCompare("flatten",option+1) == 0)
+ {
+ Image
+ *flatten_image;
+
+ flatten_image=FlattenImages(mogrify_images,
+ &mogrify_images->exception);
+ if (flatten_image != (Image *) NULL)
+ {
+ DestroyImageList(mogrify_images);
+ mogrify_images=flatten_image;
+ }
+ break;
+ }
+ break;
+ }
+ case 'm':
+ {
+ if (LocaleCompare("map",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) MapImages(mogrify_images,(Image *) NULL,
+ image_info->dither);
+ break;
+ }
+ i++;
+ break;
+ }
+ if (LocaleCompare("morph",option+1) == 0)
+ {
+ Image
+ *morph_image;
+
+ morph_image=MorphImages(mogrify_images,MagickAtoL(argv[++i]),
+ &mogrify_images->exception);
+ if (morph_image != (Image *) NULL)
+ {
+ DestroyImageList(mogrify_images);
+ mogrify_images=morph_image;
+ }
+ break;
+ }
+ if (LocaleCompare("mosaic",option+1) == 0)
+ {
+ Image
+ *mosaic_image;
+
+ mosaic_image=MosaicImages(mogrify_images,
+ &mogrify_images->exception);
+ if (mosaic_image != (Image *) NULL)
+ {
+ DestroyImageList(mogrify_images);
+ mogrify_images=mosaic_image;
+ }
+ break;
+ }
+ break;
+ }
+ case 'p':
+ {
+ if (LocaleCompare("process",option+1) == 0)
+ {
+ char
+ *arguments,
+ breaker,
+ quote,
+ *token;
+
+ int
+ next,
+ t_status;
+
+ size_t
+ length;
+
+ TokenInfo
+ token_info;
+
+ length=strlen(argv[++i]);
+ token=MagickAllocateMemory(char *,length+1);
+ if (token == (char *) NULL)
+ continue;
+ next=0;
+ /* FIXME: This code truncates the last character for an
+ argument like "analyze" but works for "analyze=" */
+ arguments=argv[i];
+ t_status=Tokenizer(&token_info,0,token,length,arguments,
+ (char *) "",(char *) "=",(char *) "\"",
+ 0,&breaker,&next,&quote);
+ if (t_status == 0)
+ {
+ char
+ *t_argv;
+
+ t_argv=&(arguments[next]);
+ (void) ExecuteModuleProcess(token,&mogrify_images,1,
+ &t_argv);
+ }
+ MagickFreeMemory(token);
+ continue;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ *images=mogrify_images;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o g r i f y I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MogrifyImageCommand() transforms an image or a sequence of images. These
+% transforms include image scaling, image rotation, color reduction, and
+% others. The transmogrified image overwrites the original image.
+%
+% The format of the MogrifyImageCommand method is:
+%
+% unsigned int MogrifyImageCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+#define ThrowMogrifyException(code,reason,description) \
+{ \
+ status = MagickFail; \
+ ThrowException(exception,code,reason,description); \
+ goto mogrify_cleanup_and_return; \
+}
+
+typedef struct _TransmogrifyOptions
+{
+ ImageInfo *image_info;
+ const char *input_filename;
+ int argc;
+ char **argv;
+ const char *output_format;
+ const char *output_directory;
+ MagickBool create_directories;
+ MagickBool global_colormap;
+ MagickBool preserve_file_attr;
+ MagickPassFail status;
+ ExceptionInfo exception;
+} TransmogrifyOptions;
+static MagickPassFail* TransmogrifyImage(TransmogrifyOptions *options)
+{
+ Image
+ *image;
+
+ ImageInfo
+ *image_info;
+
+ MagickPassFail
+ status = MagickPass;
+
+ int
+ fileatt_error = -1;
+
+ MagickStatStruct_t
+ statbuf;
+
+ assert(options != (TransmogrifyOptions *) NULL);
+ assert(options->input_filename != (char *) NULL);
+
+ image_info=CloneImageInfo(options->image_info);
+ (void) strlcpy(image_info->filename,options->input_filename,MaxTextExtent);
+
+ while (MagickTrue)
+ {
+ char
+ output_filename[MaxTextExtent],
+ temporary_filename[MaxTextExtent];
+
+ image=ReadImage(image_info,&options->exception);
+ status = (image != (Image *) NULL) &&
+ (options->exception.severity < ErrorException);
+
+ if (status == MagickFail)
+ break;
+
+ /*
+ Transmogrify image as defined by the preceding image
+ processing options.
+ */
+ status = MogrifyImages(image_info,options->argc,options->argv,&image);
+ if (image->exception.severity > options->exception.severity)
+ CopyException(&options->exception,&image->exception);
+ if (status == MagickFail)
+ break;
+
+ if (options->global_colormap)
+ {
+ /*
+ Apply a global colormap to the image sequence.
+ */
+ status = MapImages(image,(Image *) NULL,image_info->dither);
+ if (image->exception.severity > options->exception.severity)
+ CopyException(&options->exception,&image->exception);
+ }
+ if (status == MagickFail)
+ break;
+
+ /*
+ Write transmogrified image to disk.
+ */
+
+ (void) strlcpy(temporary_filename,"",MaxTextExtent);
+
+ /*
+ Compute final output file name and format
+ */
+ (void) strlcpy(output_filename,"",MaxTextExtent);
+ if (((const char *) NULL != options->output_directory) &&
+ (options->output_directory[0] != '\0'))
+ {
+ size_t
+ output_directory_length;
+
+ output_directory_length = strlen(options->output_directory);
+ if (0 != output_directory_length)
+ {
+ (void) strlcat(output_filename,options->output_directory,MaxTextExtent);
+ if (output_filename[output_directory_length-1] != DirectorySeparator[0])
+ (void) strlcat(output_filename,DirectorySeparator,MaxTextExtent);
+ }
+ }
+ (void) strlcat(output_filename,image->filename,MaxTextExtent);
+ if (options->output_format != (char *) NULL)
+ {
+ /*
+ Replace file extension with new output format.
+ */
+ AppendImageFormat(options->output_format,output_filename);
+ (void) strlcpy(image->magick,options->output_format,MaxTextExtent);
+ }
+
+ if (options->preserve_file_attr)
+ fileatt_error = MagickGetFileAttributes(image->filename, &statbuf);
+
+ if (options->create_directories)
+ {
+ /*
+ Create directory (as required)
+ */
+ char
+ directory[MaxTextExtent];
+
+ GetPathComponent(output_filename,HeadPath,directory);
+ if (IsAccessibleNoLogging(directory) == MagickFalse)
+ {
+ if (image_info->verbose)
+ fprintf(stdout,"Creating directory \"%s\".\n",directory);
+
+ if (MagickCreateDirectoryPath(directory,&options->exception)
+ == MagickFail)
+ {
+ status = MagickFail;
+ }
+ }
+ if (status == MagickFail)
+ break;
+ }
+ if (LocaleCompare(image_info->filename,"-") != 0)
+ {
+ /*
+ If output file already exists and is writeable by the
+ user, then create a rescue file by adding a tilde to the
+ existing file name and renaming. If output file does
+ not exist or the rename of the existing file fails, then
+ there is no backup! Note that this approach allows working
+ within a read-only directory if the output file already exists
+ and is writeable.
+ */
+ if (IsWriteable(output_filename))
+ {
+ (void) strlcpy(temporary_filename,output_filename,MaxTextExtent);
+ (void) strcat(temporary_filename,"~");
+ if (rename(output_filename,temporary_filename) == 0)
+ {
+ if (image_info->verbose)
+ (void) fprintf(stdout, "rename to backup %.1024s=>%.1024s\n",
+ output_filename,temporary_filename);
+ }
+ else
+ {
+ (void) strlcpy(temporary_filename,"",MaxTextExtent);
+ }
+ }
+ }
+ /*
+ Write the output file.
+ */
+ (void) strlcpy(image->filename,output_filename,MaxTextExtent);
+ status = WriteImages(image_info,image,image->filename,&options->exception);
+
+ if (options->preserve_file_attr)
+ {
+ if (fileatt_error == 0)
+ {
+ if (MagickSetFileAttributes(image->filename, &statbuf) != 0)
+ {
+ fprintf(stderr, "Error preserving file timestamps\n");
+ }
+ }
+ }
+
+ if ((status != MagickFail) && (temporary_filename[0] != 0))
+ {
+ /*
+ Remove backup file.
+ */
+ if (remove(temporary_filename) == 0)
+ {
+ if (image_info->verbose)
+ (void) fprintf(stdout, "remove backup %.1024s\n",temporary_filename);
+ }
+ }
+ break;
+ }
+ if (image)
+ DestroyImageList(image);
+ DestroyImageInfo(image_info);
+ options->status=status;
+ return (&options->status);
+}
+
+static MagickPassFail
+LoadAndCacheImageFile(char **filename,long *id,ExceptionInfo *exception)
+{
+ MagickPassFail
+ status;
+
+ status=MagickFail;
+ *id=-1;
+ if (LocaleNCompare(*filename,"MPRI:",5) != 0)
+ {
+ ImageInfo
+ *image_info;
+
+ image_info=CloneImageInfo((const ImageInfo *) NULL);
+ if (image_info != (ImageInfo *) NULL)
+ {
+ Image
+ *clut_image;
+
+ (void) strlcpy(image_info->filename,*filename,MaxTextExtent);
+ clut_image=ReadImage(image_info,exception);
+ if (clut_image != (Image *) NULL)
+ {
+ *id=SetMagickRegistry(ImageRegistryType,clut_image,sizeof(Image),exception);
+ if (*id != -1)
+ {
+ char
+ mpri[MaxTextExtent];
+
+ FormatString(mpri,"MPRI:%ld",*id);
+ MagickFreeMemory(*filename);
+ *filename=AcquireString(mpri);
+ if (*filename != (char *) NULL)
+ status=MagickPass;
+ }
+ DestroyImage(clut_image);
+ }
+ DestroyImageInfo(image_info);
+ }
+ }
+ return status;
+}
+
+#define MaxStaticArrayEntries(a) (sizeof(a)/sizeof(*a))
+
+#define CacheArgumentImage(argp,cache,index,exception) \
+ { \
+ if (index < MaxStaticArrayEntries(cache)) \
+ { \
+ if (LoadAndCacheImageFile(argp,&cache[index],exception)) \
+ index++; \
+ } \
+}
+
+
+MagickExport MagickPassFail MogrifyImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+
+ char
+ *format = NULL,
+ *option = NULL,
+ output_directory[MaxTextExtent];
+
+ double
+ sans;
+
+ long
+ image_cache[64],
+ j,
+ k,
+ x;
+
+ size_t
+ image_cache_entries=0;
+
+ register long
+ i;
+
+ MagickBool
+ create_directories,
+ global_colormap,
+ preserve_file_attr;
+
+ MagickPassFail
+ status;
+
+ /*
+ Check for sufficient arguments
+ */
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ MogrifyUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+
+ /*
+ Set defaults.
+ */
+ format=(char *) NULL;
+ output_directory[0]='\0';
+ create_directories=MagickFalse;
+ global_colormap=MagickFalse;
+ preserve_file_attr=MagickFalse;
+ status=MagickPass;
+
+ /*
+ Expand argument list
+ */
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ j=1;
+ k=0;
+ for (i=1; i < argc; i++)
+ {
+ option=argv[i];
+ if ((strlen(option) == 1) || ((*option != '-') && (*option != '+')))
+ {
+ TransmogrifyOptions
+ transmogrify_options;
+ /*
+ Option is a file name: begin by reading image from specified file.
+ */
+ k=i;
+
+ transmogrify_options.image_info=image_info;
+ transmogrify_options.input_filename=argv[i];
+ transmogrify_options.argc=i-j;
+ transmogrify_options.argv=argv+j;
+ transmogrify_options.output_format=format;
+ transmogrify_options.output_directory=output_directory;
+ transmogrify_options.create_directories=create_directories;
+ transmogrify_options.global_colormap=global_colormap;
+ transmogrify_options.preserve_file_attr=preserve_file_attr;
+ transmogrify_options.status=MagickPass;
+ GetExceptionInfo(&transmogrify_options.exception);
+ status &= *TransmogrifyImage(&transmogrify_options);
+ if (transmogrify_options.exception.severity > exception->severity)
+ CopyException(exception,&transmogrify_options.exception);
+ DestroyExceptionInfo(&transmogrify_options.exception);
+ continue;
+ }
+ j=k+1;
+ switch (*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("affine",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("antialias",option+1) == 0)
+ {
+ image_info->antialias=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("asc-cdl",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("authenticate",option+1) == 0)
+ {
+ (void) CloneString(&image_info->authenticate,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->authenticate,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("auto-orient",option+1) == 0)
+ break;
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'b':
+ {
+ if (LocaleCompare("background",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) QueryColorDatabase(argv[i],&image_info->background_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("black-threshold",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("blue-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("blur",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("border",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("bordercolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) QueryColorDatabase(argv[i],&image_info->border_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("box",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'c':
+ {
+ if (LocaleCompare("channel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ChannelType
+ channel;
+
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ channel=StringToChannelType(argv[i]);
+ if (channel == UndefinedChannel)
+ ThrowMogrifyException(OptionError,UnrecognizedChannelType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("charcoal",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("chop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("colorize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("colors",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->colorspace=StringToColorspaceType(option);
+ if (image_info->colorspace == UndefinedColorspace)
+ ThrowMogrifyException(OptionError,UnrecognizedColorspace,option);
+ }
+ break;
+ }
+ if (LocaleCompare("comment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("compose",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ if ((StringToCompositeOperator(option)) == UndefinedCompositeOp)
+ ThrowMogrifyException(OptionError,UnrecognizedComposeOperator,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ image_info->compression=NoCompression;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->compression=StringToCompressionType(option);
+ if (image_info->compression == UndefinedCompression)
+ ThrowMogrifyException(OptionError,UnrecognizedImageCompression,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("contrast",option+1) == 0)
+ break;
+ if (LocaleCompare("convolve",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == (argc-1))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("create-directories",option+1) == 0)
+ {
+ create_directories=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("crop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("cycle",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'd':
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("delay",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("despeckle",option+1) == 0)
+ break;
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ (void) CloneString(&image_info->server_name,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->server_name,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("dispose",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ option=argv[i];
+ if ((LocaleCompare("0",option) != 0) &&
+ (LocaleCompare("1",option) != 0) &&
+ (LocaleCompare("2",option) != 0) &&
+ (LocaleCompare("3",option) != 0) &&
+ (LocaleCompare("Undefined",option) != 0) &&
+ (LocaleCompare("None",option) != 0) &&
+ (LocaleCompare("Background",option) != 0) &&
+ (LocaleCompare("Previous",option) != 0))
+ ThrowMogrifyException(OptionError,UnrecognizedDisposeMethod,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("dither",option+1) == 0)
+ {
+ image_info->dither=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("draw",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'e':
+ {
+ if (LocaleCompare("edge",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("emboss",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("encoding",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("endian",option+1) == 0)
+ {
+ image_info->endian=UndefinedEndian;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->endian=StringToEndianType(option);
+ if (image_info->endian == UndefinedEndian)
+ ThrowMogrifyException(OptionError,UnrecognizedEndianType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("enhance",option+1) == 0)
+ break;
+ if (LocaleCompare("equalize",option+1) == 0)
+ break;
+ if (LocaleCompare("extent",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'f':
+ {
+ if (LocaleCompare("fill",option+1) == 0)
+ {
+ (void) QueryColorDatabase("none",&image_info->pen,exception);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ (void) QueryColorDatabase(argv[i],&image_info->pen,exception);
+ }
+ break;
+ }
+ if (LocaleCompare("filter",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ FilterTypes
+ filter;
+
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ filter=StringToFilterTypes(option);
+ if (filter == UndefinedFilter)
+ ThrowMogrifyException(OptionError,UnrecognizedImageFilter,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("flip",option+1) == 0)
+ break;
+ if (LocaleCompare("flop",option+1) == 0)
+ break;
+ if (LocaleCompare("font",option+1) == 0)
+ {
+ (void) CloneString(&image_info->font,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->font,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("format",option+1) == 0)
+ {
+ (void) CloneString(&format,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&format,argv[i]);
+ (void) strlcpy(image_info->filename,format,MaxTextExtent);
+ (void) strcat(image_info->filename,":");
+ (void) SetImageInfo(image_info,SETMAGICK_WRITE,exception);
+ if (*image_info->magick == '\0')
+ ThrowMogrifyException(OptionError,UnrecognizedImageFormat,format);
+ }
+ break;
+ }
+ if (LocaleCompare("frame",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("fuzz",option+1) == 0)
+ {
+ image_info->fuzz=0.0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ image_info->fuzz=StringToDouble(argv[i],MaxRGB);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'g':
+ {
+ if (LocaleCompare("gamma",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if ((LocaleCompare("gaussian",option+1) == 0) ||
+ (LocaleCompare("gaussian-blur",option+1) == 0))
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("geometry",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("gravity",option+1) == 0)
+ {
+ GravityType
+ gravity;
+
+ gravity=ForgetGravity;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ gravity=StringToGravityType(option);
+ if (gravity == ForgetGravity)
+ ThrowMogrifyException(OptionError,UnrecognizedGravityType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("green-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'h':
+ {
+ if (LocaleCompare("hald-clut",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+
+ /*
+ Cache argument image.
+ */
+ CacheArgumentImage(&argv[i],image_cache,image_cache_entries,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("help",option+1) == 0)
+ break;
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'i':
+ {
+ if (LocaleCompare("implode",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ image_info->interlace=UndefinedInterlace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ ThrowMogrifyException(OptionError,UnrecognizedInterlaceType,
+ option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'l':
+ {
+ if (LocaleCompare("label",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("lat",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("level",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("linewidth",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ ThrowMogrifyException(OptionError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("list",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ option=argv[i];
+ switch (*option)
+ {
+ case 'C':
+ case 'c':
+ {
+ if ((LocaleCompare("Color",option) == 0) ||
+ (LocaleCompare("Colors",option) == 0))
+ {
+ (void) ListColorInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'D':
+ case 'd':
+ {
+ if ((LocaleCompare("Delegate",option) == 0) ||
+ (LocaleCompare("Delegates",option) == 0))
+ {
+ (void) ListDelegateInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'F':
+ case 'f':
+ {
+ if ((LocaleCompare("Font",option) == 0) ||
+ (LocaleCompare("Fonts",option) == 0))
+ {
+ (void) ListTypeInfo((FILE *) NULL,exception);
+ break;
+ }
+ if ((LocaleCompare("Format",option) == 0) ||
+ (LocaleCompare("Formats",option) == 0))
+ {
+ (void) ListMagickInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare("Magic",option) == 0)
+ {
+ (void) ListMagicInfo((FILE *) NULL,exception);
+ break;
+ }
+#if defined(SupportMagickModules)
+ if ((LocaleCompare("Module",option) == 0) ||
+ (LocaleCompare("Modules",option) == 0))
+ {
+ (void) ListModuleInfo((FILE *) NULL,exception);
+ break;
+ }
+#endif /* SupportMagickModules */
+ if (LocaleCompare("ModuleMap",option) == 0)
+ {
+ (void) ListModuleMap((FILE *) NULL,exception);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'R':
+ case 'r':
+ {
+ if ((LocaleCompare("Resource",option) == 0) ||
+ (LocaleCompare("Resources",option) == 0))
+ {
+ (void) ListMagickResourceInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedListType,
+ option)
+ }
+ case 'T':
+ case 't':
+ {
+ if (LocaleCompare("Type",option) == 0)
+ {
+ (void) ListTypeInfo((FILE *) NULL,exception);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedListType,
+ option)
+ }
+ default:
+ ThrowMogrifyException(OptionError,UnrecognizedListType,
+ option)
+ }
+ status=MagickPass;
+ goto mogrify_cleanup_and_return;
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("loop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'm':
+ {
+ if (LocaleCompare("magnify",option+1) == 0)
+ break;
+ if (LocaleCompare("map",option+1) == 0)
+ {
+ global_colormap=(*option == '+');
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+
+ /*
+ Cache argument image.
+ */
+ CacheArgumentImage(&argv[i],image_cache,image_cache_entries,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("mask",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+
+ /*
+ Cache argument image.
+ */
+ CacheArgumentImage(&argv[i],image_cache,image_cache_entries,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("matte",option+1) == 0)
+ break;
+ if (LocaleCompare("mattecolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) QueryColorDatabase(argv[i],&image_info->matte_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("modulate",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("median",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("minify",option+1) == 0)
+ break;
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ if (LocaleCompare("monochrome",option+1) == 0)
+ {
+ image_info->monochrome=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("motion-blur",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'n':
+ {
+ if (LocaleCompare("negate",option+1) == 0)
+ break;
+ if (LocaleCompare("noise",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ if (*option == '+')
+ {
+ NoiseType
+ noise_type;
+
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ noise_type=StringToNoiseType(option);
+ if (UndefinedNoise == noise_type)
+ ThrowMogrifyException(OptionError,UnrecognizedNoiseType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("noop",option+1) == 0)
+ break;
+ if (LocaleCompare("normalize",option+1) == 0)
+ break;
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'o':
+ {
+ if (LocaleCompare("opaque",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("operator",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ChannelType
+ channel;
+
+ QuantumOperator
+ quantum_operator;
+
+ double
+ rvalue;
+
+ /* channel */
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ channel=StringToChannelType(argv[i]);
+ if (channel == UndefinedChannel)
+ ThrowMogrifyException(OptionError,UnrecognizedChannelType,
+ option);
+
+ /* operator id */
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ quantum_operator=StringToQuantumOperator(argv[i]);
+ if (quantum_operator == UndefinedQuantumOp)
+ ThrowMogrifyException(OptionError,UnrecognizedOperator,
+ option);
+
+ /* rvalue */
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&rvalue))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("ordered-dither",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("orient",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("output-directory",option+1) == 0)
+ {
+ output_directory[0]='\0';
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) strlcpy(output_directory,argv[i],sizeof(output_directory));
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'p':
+ {
+ if (LocaleCompare("page",option+1) == 0)
+ {
+ (void) CloneString(&image_info->page,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ image_info->page=GetPageGeometry(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("paint",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("pointsize",option+1) == 0)
+ {
+ image_info->pointsize=12;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ image_info->pointsize=MagickAtoF(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("preserve-timestamp", option+1) == 0)
+ {
+ preserve_file_attr = MagickTrue;
+ break;
+ }
+ if (LocaleCompare("profile",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'q':
+ {
+ if (LocaleCompare("quality",option+1) == 0)
+ {
+ image_info->quality=DefaultCompressionQuality;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ image_info->quality=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'r':
+ {
+ if (LocaleCompare("raise",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("random-threshold",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("recolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("red-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("region",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("render",option+1) == 0)
+ break;
+ if (LocaleCompare("repage",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("resample",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == (argc-1)) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("resize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("resize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("roll",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("rotate",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 's':
+ {
+ if (LocaleCompare("sample",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("scale",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("scene",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("set",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ if (*option == '-')
+ {
+ /* -set attribute value */
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("segment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("shade",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("sharpen",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("shave",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("shear",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("solarize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("spread",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("strip",option+1) == 0)
+ {
+ break;
+ }
+ if (LocaleCompare("stroke",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("strokewidth",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("swirl",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 't':
+ {
+ if (LocaleCompare("texture",option+1) == 0)
+ {
+ (void) CloneString(&image_info->texture,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->texture,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("threshold",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("thumbnail",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("tile",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+
+ /*
+ Cache argument image.
+ */
+ CacheArgumentImage(&argv[i],image_cache,image_cache_entries,
+ exception);
+ break;
+ }
+ if (LocaleCompare("transform",option+1) == 0)
+ break;
+ if (LocaleCompare("transparent",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("treedepth",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("trim",option+1) == 0)
+ break;
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ image_info->type=UndefinedType;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->type=StringToImageType(option);
+ if (image_info->type == UndefinedType)
+ ThrowMogrifyException(OptionError,UnrecognizedImageType,
+ option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'u':
+ {
+ if (LocaleCompare("undercolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("units",option+1) == 0)
+ {
+ image_info->units=UndefinedResolution;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->units=UndefinedResolution;
+ if (LocaleCompare("PixelsPerInch",option) == 0)
+ image_info->units=PixelsPerInchResolution;
+ if (LocaleCompare("PixelsPerCentimeter",option) == 0)
+ image_info->units=PixelsPerCentimeterResolution;
+ }
+ break;
+ }
+ if (LocaleCompare("unsharp",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("view",option+1) == 0)
+ {
+ (void) CloneString(&image_info->view,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->view,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("virtual-pixel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ i++;
+ if (i == argc)
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ option=argv[i];
+ virtual_pixel_method=StringToVirtualPixelMethod(option);
+ if (virtual_pixel_method == UndefinedVirtualPixelMethod)
+ ThrowMogrifyException(OptionError,UnrecognizedVirtualPixelMethod,option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case 'w':
+ {
+ if (LocaleCompare("wave",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("white-point",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("white-threshold",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMogrifyException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ case '?':
+ break;
+ default:
+ ThrowMogrifyException(OptionError,UnrecognizedOption,option)
+ }
+ }
+ if (i != argc)
+ {
+ if (exception->severity == UndefinedException)
+ ThrowMogrifyException(OptionError,MissingAnImageFilename,
+ (char *) NULL);
+ }
+ mogrify_cleanup_and_return:
+
+ /*
+ Release cached temporary files.
+ */
+ while (image_cache_entries > 0)
+ (void) DeleteMagickRegistry(image_cache[--image_cache_entries]);
+ MagickFreeMemory(format);
+ LiberateArgumentList(argc,argv);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o g r i f y U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MogrifyUsage() displays the program command syntax.
+%
+% The format of the MogrifyUsage method is:
+%
+% void MogrifyUsage()
+%
+%
+*/
+static void MogrifyUsage(void)
+{
+ static const char
+ *options[]=
+ {
+ "-affine matrix affine transform matrix",
+ "-antialias remove pixel-aliasing",
+ "-asc-cdl spec apply ASC CDL transform",
+ "-authenticate value decrypt image with this password",
+ "-auto-orient orient (rotate) image so it is upright",
+ "-background color background color",
+ "-black-threshold value",
+ " pixels below the threshold become black",
+ "-blue-primary point chomaticity blue primary point",
+ "-blur radius blur the image",
+ "-border geometry surround image with a border of color",
+ "-bordercolor color border color",
+ "-box color set the color of the annotation bounding box",
+ "-channel type extract a particular color channel from image",
+ "-charcoal radius simulate a charcoal drawing",
+ "-chop geometry remove pixels from the image interior",
+ "-colorize value colorize the image with the fill color",
+ "-colors value preferred number of colors in the image",
+ "-colorspace type alternate image colorspace",
+ "-comment string annotate image with comment",
+ "-compose operator composite operator",
+ "-compress type image compression type",
+ "-contrast enhance or reduce the image contrast",
+ "-convolve kernel convolve image with the specified convolution kernel",
+ "-create-directories create output directories if required",
+ "-crop geometry preferred size and location of the cropped image",
+ "-cycle amount cycle the image colormap",
+ "-debug events display copious debugging information",
+ "-define values Coder/decoder specific options",
+ "-delay value display the next image after pausing",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-despeckle reduce the speckles within an image",
+ "-display server get image or font from this X server",
+ "-dispose method Undefined, None, Background, Previous",
+ "-dither apply Floyd/Steinberg error diffusion to image",
+ "-draw string annotate the image with a graphic primitive",
+ "-edge radius apply a filter to detect edges in the image",
+ "-emboss radius emboss an image",
+ "-encoding type text encoding type",
+ "-endian type multibyte word order (LSB, MSB, or Native)",
+ "-enhance apply a digital filter to enhance a noisy image",
+ "-equalize perform histogram equalization to an image",
+ "-extent composite image on background color canvas image",
+ "-fill color color to use when filling a graphic primitive",
+ "-filter type use this filter when resizing an image",
+ "-flip flip image in the vertical direction",
+ "-flop flop image in the horizontal direction",
+ "-font name render text with this font",
+ "-format type image format type",
+ "-frame geometry surround image with an ornamental border",
+ "-fuzz distance colors within this distance are considered equal",
+ "-gamma value level of gamma correction",
+ "-gaussian geometry gaussian blur an image",
+ "-geometry geometry perferred size or location of the image",
+ "-gravity type horizontal and vertical text/object placement",
+ "-green-primary point chomaticity green primary point",
+ "-implode amount implode image pixels about the center",
+ "-interlace type None, Line, Plane, or Partition",
+ "-hald-clut clut apply a Hald CLUT to the image",
+ "-help print program options",
+ "-label name assign a label to an image",
+ "-lat geometry local adaptive thresholding",
+ "-level value adjust the level of image contrast",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-linewidth width the line width for subsequent draw operations",
+ "-list type Color, Delegate, Format, Magic, Module, Resource,",
+ " or Type",
+ "-log format format of debugging information",
+ "-loop iterations add Netscape loop extension to your GIF animation",
+ "-magnify interpolate image to double size",
+ "-map filename transform image colors to match this set of colors",
+ "-mask filename set the image clip mask",
+ "-matte store matte channel if the image has one",
+ "-mattecolor color specify the color to be used with the -frame option",
+ "-median radius apply a median filter to the image",
+ "-minify interpolate the image to half size",
+ "-modulate value vary the brightness, saturation, and hue",
+ "-monitor show progress indication",
+ "-monochrome transform image to black and white",
+ "-motion-blur radiusxsigma+angle",
+ " simulate motion blur",
+ "-negate replace every pixel with its complementary color ",
+ "-noop do not apply options to image",
+ "-noise radius add or reduce noise in an image",
+ "-normalize transform image to span the full range of colors",
+ "-opaque color change this color to the fill color",
+ "-operator channel operator rvalue",
+ " apply a mathematical or bitwise operator to channel",
+ "-ordered-dither channeltype NxN",
+ " ordered dither the image",
+ "-orient orientation set image orientation attribute",
+ "-output-directory directory",
+ " write output files to directory",
+ "+page reset current page offsets to default",
+ "-page geometry size and location of an image canvas",
+ "-paint radius simulate an oil painting",
+ "-fill color color for annotating or changing opaque color",
+ "-pointsize value font point size",
+ "-profile filename add ICM or IPTC information profile to image",
+ "-preserve-timestamp preserve original timestamps of the file",
+ "-quality value JPEG/MIFF/PNG compression level",
+ "-raise value lighten/darken image edges to create a 3-D effect",
+ "-random-threshold channeltype LOWxHIGH",
+ " random threshold the image",
+ "-recolor matrix apply a color translation matrix to image channels",
+ "-red-primary point chomaticity red primary point",
+ "-region geometry apply options to a portion of the image",
+ "-render render vector graphics",
+ "+render disable rendering vector graphics",
+ "-resample geometry resample to horizontal and vertical resolution",
+ "+repage reset current page offsets to default",
+ "-repage geometry adjust current page offsets by geometry",
+ "-resize geometry perferred size or location of the image",
+ "-roll geometry roll an image vertically or horizontally",
+ "-rotate degrees apply Paeth rotation to the image",
+ "-sample geometry scale image with pixel sampling",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-scale geometry scale the image",
+ "-scene number image scene number",
+ "-seed value pseudo-random number generator seed value",
+ "-segment values segment an image",
+ "-set attribute value set image attribute",
+ "+set attribute unset image attribute",
+ "-shade degrees shade the image using a distant light source",
+ "-sharpen radius sharpen the image",
+ "-shave geometry shave pixels from the image edges",
+ "-shear geometry slide one edge of the image along the X or Y axis",
+ "-size geometry width and height of image",
+ "-solarize threshold negate all pixels above the threshold level",
+ "-spread amount displace image pixels by a random amount",
+ "-strip strip all profiles and text attributes from image",
+ "-stroke color graphic primitive stroke color",
+ "-strokewidth value graphic primitive stroke width",
+ "-swirl degrees swirl image pixels about the center",
+ "-texture filename name of texture to tile onto the image background",
+ "-threshold value threshold the image",
+ "-thumbnail geometry resize the image (optimized for thumbnails)",
+ "-tile filename tile image when filling a graphic primitive",
+ "-transform affine transform image",
+ "-transparent color make this color transparent within the image",
+ "-treedepth value color tree depth",
+ "-trim trim image edges",
+ "-type type image type",
+ "-undercolor color annotation bounding box color",
+ "-units type PixelsPerInch, PixelsPerCentimeter, or Undefined",
+ "-unsharp geometry sharpen the image",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ "-view FlashPix viewing transforms",
+ "-virtual-pixel method",
+ " Constant, Edge, Mirror, or Tile",
+ "-wave geometry alter an image along a sine wave",
+ "-white-point point chomaticity white point",
+ "-white-threshold value",
+ " pixels above the threshold become white",
+ (char *) NULL
+ };
+
+ const char
+ **p;
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] file [ [options ...] file ...]\n",
+ GetClientName());
+ (void) printf("\nWhere options include: \n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) printf(
+ "\nBy default, the image format of `file' is determined by its magic\n");
+ (void) printf(
+ "number. To specify a particular image format, precede the filename\n");
+ (void) printf(
+ "with an image format name and a colon (i.e. ps:image) or specify the\n");
+ (void) printf(
+ "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n");
+ (void) printf("'-' for standard input or output.\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o n t a g e I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MontageImageCommand() reads one or more images, applies one or more image
+% processing operations, and writes out the image in the same or
+% differing format.
+%
+% The format of the MontageImageCommand method is:
+%
+% MagickPassFail MontageImageCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define ThrowMontageException(code,reason,description) \
+{ \
+ DestroyImageList(image); \
+ DestroyImageList(image_list); \
+ DestroyImageList(montage_image); \
+ DestroyMontageInfo(montage_info); \
+ ThrowException(exception,code,reason,description); \
+ LiberateArgumentList(argc,argv); \
+ return(MagickFail); \
+}
+#define ThrowMontageException3(code,reason,description) \
+{ \
+ DestroyImageList(image); \
+ DestroyImageList(image_list); \
+ DestroyImageList(montage_image); \
+ DestroyMontageInfo(montage_info); \
+ ThrowException3(exception,code,reason,description); \
+ LiberateArgumentList(argc,argv); \
+ return(MagickFail); \
+}
+MagickExport MagickPassFail MontageImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ char
+ *format,
+ *option,
+ *transparent_color;
+
+ double
+ sans;
+
+ Image
+ *image,
+ *image_list,
+ *montage_image,
+ *next_image;
+
+ long
+ first_scene,
+ j,
+ k,
+ last_scene,
+ scene,
+ x;
+
+ MontageInfo
+ *montage_info;
+
+ QuantizeInfo
+ quantize_info;
+
+ register long
+ i;
+
+ MagickPassFail
+ status;
+
+ /*
+ Validate command line.
+ */
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ MontageUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+
+ /*
+ Set defaults.
+ */
+ format=(char *) NULL;
+ first_scene=0;
+ image=NewImageList();
+ image_list=(Image *) NULL;
+ montage_image=NewImageList();
+ last_scene=0;
+
+ /*
+ Expand argument list
+ */
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ (void) strlcpy(image_info->filename,argv[argc-1],MaxTextExtent);
+ (void) SetImageInfo(image_info,SETMAGICK_WRITE,exception);
+ montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.number_colors=0;
+ scene=0;
+ status=MagickPass;
+ transparent_color=(char *) NULL;
+
+ j=1;
+ k=0;
+ for (i=1; i < (argc-1); i++)
+ {
+ option=argv[i];
+ if ((strlen(option) < 2) ||
+ /* stdin + subexpression */
+ ((option[0] == '-') && (option[1] == '[')) ||
+ ((option[0] != '-') && option[0] != '+'))
+ {
+ k=i;
+ for (scene=first_scene; scene <= last_scene ; scene++)
+ {
+ /*
+ Option is a file name: begin by reading image from specified file.
+ */
+ (void) strlcpy(image_info->filename,argv[i],MaxTextExtent);
+ if (first_scene != last_scene)
+ {
+ char
+ filename[MaxTextExtent];
+
+ /*
+ Form filename for multi-part images.
+ */
+ (void) MagickSceneFileName(filename,image_info->filename,".%lu",MagickTrue,scene);
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ }
+ (void) CloneString(&image_info->font,montage_info->font);
+ image_info->colorspace=quantize_info.colorspace;
+ image_info->dither=quantize_info.dither;
+ if (image_info->size == (char *) NULL)
+ (void) CloneString(&image_info->size,montage_info->geometry);
+ next_image=ReadImage(image_info,exception);
+ status&=(next_image != (Image *) NULL) &&
+ (exception->severity < ErrorException);
+ if (next_image == (Image *) NULL)
+ continue;
+ if (image == (Image *) NULL)
+ {
+ image=next_image;
+ continue;
+ }
+ AppendImageToList(&image,next_image);
+ }
+ continue;
+ }
+ if ((image != (Image *) NULL) && (j != (k+1)))
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image);
+ GetImageException(image,exception);
+ AppendImageToList(&image_list,image);
+ image=NewImageList();
+ j=k+1;
+ }
+ switch (*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("adjoin",option+1) == 0)
+ {
+ image_info->adjoin=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("affine",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("authenticate",option+1) == 0)
+ {
+ (void) CloneString(&image_info->authenticate,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->authenticate,argv[i]);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'b':
+ {
+ if (LocaleCompare("background",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) QueryColorDatabase(argv[i],
+ &montage_info->background_color,exception);
+ (void) QueryColorDatabase(argv[i],&image_info->background_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("blue-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("blur",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("bordercolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) QueryColorDatabase(argv[i],&montage_info->border_color,
+ exception);
+ (void) QueryColorDatabase(argv[i],&image_info->border_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("borderwidth",option+1) == 0)
+ {
+ montage_info->border_width=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ montage_info->border_width=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'c':
+ {
+ if (LocaleCompare("colors",option+1) == 0)
+ {
+ quantize_info.number_colors=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ quantize_info.number_colors=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ quantize_info.colorspace=RGBColorspace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ quantize_info.colorspace=StringToColorspaceType(option);
+ if (IsGrayColorspace(quantize_info.colorspace))
+ {
+ quantize_info.number_colors=256;
+ quantize_info.tree_depth=8;
+ }
+ if (quantize_info.colorspace == UndefinedColorspace)
+ ThrowMontageException(OptionError,UnrecognizedColorspace,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("comment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("compose",option+1) == 0)
+ {
+ CompositeOperator
+ compose;
+
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ compose=StringToCompositeOperator(option);
+ if (compose == UndefinedCompositeOp)
+ ThrowMontageException(OptionError,UnrecognizedComposeOperator,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ image_info->compression=NoCompression;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->compression=StringToCompressionType(option);
+ if (image_info->compression == UndefinedCompression)
+ ThrowMontageException(OptionError,UnrecognizedImageCompression,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("crop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'd':
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ (void) CloneString(&image_info->server_name,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->server_name,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("dispose",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,
+ option);
+ option=argv[i];
+ if ((LocaleCompare("0",option) != 0) &&
+ (LocaleCompare("1",option) != 0) &&
+ (LocaleCompare("2",option) != 0) &&
+ (LocaleCompare("3",option) != 0) &&
+ (LocaleCompare("Undefined",option) != 0) &&
+ (LocaleCompare("None",option) != 0) &&
+ (LocaleCompare("Background",option) != 0) &&
+ (LocaleCompare("Previous",option) != 0))
+ ThrowMontageException(OptionError,UnrecognizedDisposeMethod,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("dither",option+1) == 0)
+ {
+ quantize_info.dither=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("draw",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'e':
+ {
+ if (LocaleCompare("encoding",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("endian",option+1) == 0)
+ {
+ image_info->endian=UndefinedEndian;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->endian=StringToEndianType(option);
+ if (image_info->endian == UndefinedEndian)
+ ThrowMontageException(OptionError,UnrecognizedEndianType,
+ option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'f':
+ {
+ if (LocaleCompare("fill",option+1) == 0)
+ {
+ (void) QueryColorDatabase("none",&image_info->pen,exception);
+ (void) QueryColorDatabase("none",&montage_info->fill,exception);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) QueryColorDatabase(argv[i],&image_info->pen,exception);
+ (void) QueryColorDatabase(argv[i],&montage_info->fill,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("filter",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ FilterTypes
+ filter;
+
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ filter=StringToFilterTypes(option);
+ if (filter == UndefinedFilter)
+ ThrowMontageException(OptionError,UnrecognizedImageFilter,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("flip",option+1) == 0)
+ break;
+ if (LocaleCompare("flop",option+1) == 0)
+ break;
+ if (LocaleCompare("font",option+1) == 0)
+ {
+ (void) CloneString(&image_info->font,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->font,argv[i]);
+ (void) CloneString(&montage_info->font,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("format",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,
+ option);
+ format=argv[i];
+ }
+ break;
+ }
+ if (LocaleCompare("frame",option+1) == 0)
+ {
+ (void) CloneString(&montage_info->frame,(char *) NULL);
+ (void) strcpy(argv[i]+1,"sans");
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&montage_info->frame,argv[i]);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'g':
+ {
+ if (LocaleCompare("gamma",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%lf",&sans))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ break;
+ }
+ if (LocaleCompare("geometry",option+1) == 0)
+ {
+ (void) CloneString(&montage_info->geometry,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&montage_info->geometry,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("gravity",option+1) == 0)
+ {
+ GravityType
+ gravity;
+
+ gravity=ForgetGravity;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ gravity=StringToGravityType(option);
+ }
+ montage_info->gravity=gravity;
+ break;
+ }
+ if (LocaleCompare("green-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'h':
+ {
+ if (LocaleCompare("help",option+1) == 0)
+ break;
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'i':
+ {
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ image_info->interlace=UndefinedInterlace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ ThrowMontageException(OptionError,UnrecognizedInterlaceType,option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'l':
+ {
+ if (LocaleCompare("label",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ ThrowMontageException(OptionError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'm':
+ {
+ if (LocaleCompare("matte",option+1) == 0)
+ break;
+ if (LocaleCompare("mattecolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) QueryColorDatabase(argv[i],&montage_info->matte_color,
+ exception);
+ (void) QueryColorDatabase(argv[i],&image_info->matte_color,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("mode",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ MontageMode
+ mode;
+
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ mode=UndefinedMode;
+ if (LocaleCompare("frame",option) == 0)
+ {
+ mode=FrameMode;
+ (void) CloneString(&montage_info->frame,"15x15+3+3");
+ montage_info->shadow=MagickTrue;
+ break;
+ }
+ if (LocaleCompare("unframe",option) == 0)
+ {
+ mode=UnframeMode;
+ montage_info->frame=(char *) NULL;
+ montage_info->shadow=MagickFalse;
+ montage_info->border_width=0;
+ break;
+ }
+ if (LocaleCompare("concatenate",option) == 0)
+ {
+ mode=ConcatenateMode;
+ montage_info->frame=(char *) NULL;
+ montage_info->shadow=MagickFalse;
+ (void) CloneString(&montage_info->geometry,"+0+0");
+ montage_info->border_width=0;
+ break;
+ }
+ if (mode == UndefinedMode)
+ ThrowMontageException(OptionError,UnrecognizedImageMode,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ if (LocaleCompare("monochrome",option+1) == 0)
+ {
+ image_info->monochrome=(*option == '-');
+ if (image_info->monochrome)
+ {
+ quantize_info.number_colors=2;
+ quantize_info.tree_depth=8;
+ quantize_info.colorspace=GRAYColorspace;
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'n':
+ {
+ if (LocaleCompare("noop",option+1) == 0)
+ break;
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'p':
+ {
+ if (LocaleCompare("page",option+1) == 0)
+ {
+ (void) CloneString(&image_info->page,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,
+ option);
+ image_info->page=GetPageGeometry(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("pointsize",option+1) == 0)
+ {
+ image_info->pointsize=12;
+ montage_info->pointsize=12;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ image_info->pointsize=MagickAtoF(argv[i]);
+ montage_info->pointsize=MagickAtoF(argv[i]);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'q':
+ {
+ if (LocaleCompare("quality",option+1) == 0)
+ {
+ image_info->quality=DefaultCompressionQuality;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,
+ option);
+ image_info->quality=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'r':
+ {
+ if (LocaleCompare("red-primary",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("render",option+1) == 0)
+ break;
+ if (LocaleCompare("repage",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("resize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("rotate",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 's':
+ {
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("scenes",option+1) == 0)
+ {
+ first_scene=0;
+ last_scene=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ first_scene=MagickAtoL(argv[i]);
+ last_scene=first_scene;
+ (void) sscanf(argv[i],"%ld-%ld",&first_scene,&last_scene);
+ }
+ break;
+ }
+ if (LocaleCompare("set",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ if (*option == '-')
+ {
+ /* -set attribute value */
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("shadow",option+1) == 0)
+ {
+ montage_info->shadow=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("sharpen",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("strip",option+1) == 0)
+ {
+ break;
+ }
+ if (LocaleCompare("stroke",option+1) == 0)
+ {
+ (void) QueryColorDatabase("none",&montage_info->stroke,exception);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) QueryColorDatabase(argv[i],&montage_info->stroke,
+ exception);
+ }
+ break;
+ }
+ if (LocaleCompare("strokewidth",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 't':
+ {
+ if (LocaleCompare("texture",option+1) == 0)
+ {
+ (void) CloneString(&montage_info->texture,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&montage_info->texture,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("thumbnail",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("tile",option+1) == 0)
+ {
+ (void) CloneString(&montage_info->tile,(char *) NULL);
+ (void) strcpy(argv[i]+1,"sans");
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&montage_info->tile,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("title",option+1) == 0)
+ {
+ (void) CloneString(&montage_info->title,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&montage_info->title,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("transform",option+1) == 0)
+ break;
+ if (LocaleCompare("transparent",option+1) == 0)
+ {
+ transparent_color=(char *) NULL;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ (void) CloneString(&transparent_color,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("treedepth",option+1) == 0)
+ {
+ quantize_info.tree_depth=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ quantize_info.tree_depth=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("trim",option+1) == 0)
+ break;
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ image_info->type=UndefinedType;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,option);
+ option=argv[i];
+ image_info->type=StringToImageType(option);
+ if (image_info->type == UndefinedType)
+ ThrowMontageException(OptionError,UnrecognizedImageType,
+ option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("verbose",option+1) == 0)
+ break;
+ if (LocaleCompare("virtual-pixel",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ i++;
+ if (i == argc)
+ ThrowMontageException(OptionError,MissingArgument,
+ option);
+ option=argv[i];
+ virtual_pixel_method=StringToVirtualPixelMethod(option);
+ if (virtual_pixel_method == UndefinedVirtualPixelMethod)
+ ThrowMontageException(OptionError,UnrecognizedVirtualPixelMethod,option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case 'w':
+ {
+ if (LocaleCompare("white-point",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ ThrowMontageException(OptionError,MissingArgument,option);
+ }
+ break;
+ }
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ case '?':
+ break;
+ default:
+ ThrowMontageException(OptionError,UnrecognizedOption,option)
+ }
+ }
+ if ((image == (Image *) NULL) && (image_list == (Image *) NULL))
+ {
+ if (exception->severity == UndefinedException)
+ ThrowMontageException(OptionError,RequestDidNotReturnAnImage,
+ (char *) NULL);
+ return(MagickFail);
+ }
+ if (i != (argc-1))
+ ThrowMontageException(OptionError,MissingAnImageFilename,(char *) NULL);
+ if (image != (Image *) NULL)
+ {
+ status&=MogrifyImages(image_info,i-j,argv+j,&image);
+ GetImageException(image,exception);
+ AppendImageToList(&image_list,image);
+ image=NewImageList();
+ j=i;
+ }
+ /*
+ FIXME: Overlapping memory detected here where memory should not be overlapping.
+ */
+ (void) strlcpy(montage_info->filename,argv[argc-1],MaxTextExtent);
+ /* (void) memmove(montage_info->filename,argv[argc-1],strlen(argv[argc-1])+1); */
+ montage_image=MontageImages(image_list,montage_info,exception);
+ if (montage_image == (Image *) NULL)
+ ThrowMontageException(OptionError,RequestDidNotReturnAnImage,(char *) NULL);
+ DestroyImageList(image_list);
+ /*
+ Write image.
+ */
+ status&=MogrifyImages(image_info,i-j,argv+j,&montage_image);
+ GetImageException(montage_image,exception);
+ (void) strlcpy(image_info->filename,argv[argc-1],MaxTextExtent);
+ (void) strlcpy(montage_image->magick_filename,argv[argc-1],MaxTextExtent);
+ status&=WriteImages(image_info,montage_image,argv[argc-1],exception);
+ if (metadata != (char **) NULL)
+ {
+ char
+ *text;
+
+ /*
+ Return metadata to user
+ */
+ text=TranslateText(image_info,montage_image,(format != (char *) NULL) ? format : "%w,%h,%m");
+ if (text == (char *) NULL)
+ ThrowMontageException(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(OptionError,UnableToFormatImageMetadata));
+ (void) ConcatenateString(&(*metadata),text);
+ (void) ConcatenateString(&(*metadata),"\n");
+ MagickFreeMemory(text);
+ }
+ DestroyImageList(montage_image);
+ DestroyMontageInfo(montage_info);
+ LiberateArgumentList(argc,argv);
+ return(status);
+}
+#undef ThrowMontageException
+#undef ThrowMontageException3
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o n t a g e U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MontageUsage() displays the program command syntax.
+%
+% The format of the MontageUsage method is:
+%
+% void MontageUsage()
+%
+%
+*/
+static void MontageUsage(void)
+{
+ const char
+ **p;
+
+ static const char
+ *options[]=
+ {
+ "-adjoin join images into a single multi-image file",
+ "-affine matrix affine transform matrix",
+ "-authenticate value decrypt image with this password",
+ "-background color background color",
+ "-blue-primary point chomaticity blue primary point",
+ "-blur factor apply a filter to blur the image",
+ "-bordercolor color border color",
+ "-borderwidth geometry",
+ " border width",
+ "-colors value preferred number of colors in the image",
+ "-colorspace type alternate image colorsapce",
+ "-comment string annotate image with comment",
+ "-compose operator composite operator",
+ "-compress type image compression type",
+ "-crop geometry preferred size and location of the cropped image",
+ "-debug events display copious debugging information",
+ "-define values Coder/decoder specific options",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-display server query font from this X server",
+ "-dispose method Undefined, None, Background, Previous",
+ "-dither apply Floyd/Steinberg error diffusion to image",
+ "-draw string annotate the image with a graphic primitive",
+ "-encoding type text encoding type",
+ "-endian type multibyte word order (LSB, MSB, or Native)",
+ "-fill color color to use when filling a graphic primitive",
+ "-filter type use this filter when resizing an image",
+ "-flip flip image in the vertical direction",
+ "-flop flop image in the horizontal direction",
+ "-font name font to use when annotating with text",
+ "-format string output formatted image characteristics",
+ "-frame geometry surround image with an ornamental border",
+ "-gamma value level of gamma correction",
+ "-geometry geometry preferred tile and border sizes",
+ "-gravity direction which direction to gravitate towards",
+ "-green-primary point chomaticity green primary point",
+ "-help print program options",
+ "-interlace type None, Line, Plane, or Partition",
+ "-label name assign a label to an image",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-log format format of debugging information",
+ "-matte store matte channel if the image has one",
+ "-mattecolor color color to be used with the -frame option",
+ "-mode type Frame, Unframe, or Concatenate",
+ "-monitor show progress indication",
+ "-monochrome transform image to black and white",
+ "-noop do not apply options to image",
+ "+page reset current page offsets to default",
+ "-page geometry size and location of an image canvas",
+ "-pointsize value font point size",
+ "-quality value JPEG/MIFF/PNG compression level",
+ "-red-primary point chomaticity red primary point",
+ "+repage reset current page offsets to default",
+ "-repage geometry adjust current page offsets by geometry",
+ "-resize geometry resize the image",
+ "-rotate degrees apply Paeth rotation to the image",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-scenes range image scene range",
+ "-set attribute value set image attribute",
+ "+set attribute unset image attribute",
+ "-shadow add a shadow beneath a tile to simulate depth",
+ "-sharpen geometry sharpen the image",
+ "-size geometry width and height of image",
+ "-strip strip all profiles and text attributes from image",
+ "-stroke color color to use when stroking a graphic primitive",
+ "-strokewidth value stroke (line) width",
+ "-texture filename name of texture to tile onto the image background",
+ "-thumbnail geometry resize the image (optimized for thumbnails)",
+ "-tile geometry number of tiles per row and column",
+ "-title string thumbnail title",
+ "-transform affine transform image",
+ "-transparent color make this color transparent within the image",
+ "-treedepth value color tree depth",
+ "-trim trim image edges",
+ "-type type image type",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ "-virtual-pixel method",
+ " Constant, Edge, Mirror, or Tile",
+ "-white-point point chomaticity white point",
+ (char *) NULL
+ };
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] file [ [options ...] file ...]\n",
+ GetClientName());
+ (void) printf("\nWhere options include: \n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) printf(
+ "\nIn addition to those listed above, you can specify these standard X\n");
+ (void) printf(
+ "resources as command line options: -background, -bordercolor,\n");
+ (void) printf(
+ "-borderwidth, -font, -mattecolor, or -title\n");
+ (void) printf(
+ "\nBy default, the image format of `file' is determined by its magic\n");
+ (void) printf(
+ "number. To specify a particular image format, precede the filename\n");
+ (void) printf(
+ "with an image format name and a colon (i.e. ps:image) or specify the\n");
+ (void) printf(
+ "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n");
+ (void) printf("'-' for standard input or output.\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m p o r t I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImportImageCommand() reads an image from any visible window on an X server
+% and outputs it as an image file. You can capture a single window, the
+% entire screen, or any rectangular portion of the screen. You can use the
+% display utility for redisplay, printing, editing, formatting, archiving,
+% image processing, etc. of the captured image.</dd>
+%
+% The target window can be specified by id, name, or may be selected by
+% clicking the mouse in the desired window. If you press a button and then
+% drag, a rectangle will form which expands and contracts as the mouse moves.
+% To save the portion of the screen defined by the rectangle, just release
+% the button. The keyboard bell is rung once at the beginning of the screen
+% capture and twice when it completes.
+%
+% The format of the ImportImageCommand method is:
+%
+% MagickPassFail ImportImageCommand(ImageInfo *image_info,int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail ImportImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+#if defined(HasX11)
+ char
+ *filename,
+ *option,
+ *resource_value,
+ *server_name,
+ *target_window;
+
+ const char
+ *client_name;
+
+ Display
+ *display;
+
+ Image
+ *image,
+ *next_image;
+
+ long
+ snapshots,
+ x;
+
+ QuantizeInfo
+ *quantize_info;
+
+ register long
+ i;
+
+ MagickPassFail
+ status;
+
+ MagickXImportInfo
+ ximage_info;
+
+ MagickXResourceInfo
+ resource_info;
+
+ XrmDatabase
+ resource_database;
+
+ /*
+ Check for server name specified on the command line.
+ */
+ server_name=(char *) NULL;
+ for (i=1; i < argc; i++)
+ {
+ /*
+ Check command line for server name.
+ */
+ option=argv[i];
+ if ((strlen(option) == 1) || ((*option != '-') && (*option != '+')))
+ continue;
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ /*
+ User specified server name.
+ */
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ server_name=argv[i];
+ break;
+ }
+ if (LocaleCompare("help",option+1) == 0 ||
+ LocaleCompare("?", option+1) == 0)
+ {
+ ImportUsage();
+ return MagickPass;
+ }
+ if (LocaleCompare("version",option+1) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+ }
+
+ /*
+ Expand argument list
+ */
+ status=ExpandFilenames(&argc,&argv);
+ if (status == MagickFail)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ (char *) NULL);
+
+ /*
+ Get user defaults from X resource database.
+ */
+ SetNotifyHandlers;
+ display=XOpenDisplay(server_name);
+ if (display == (Display *) NULL)
+ MagickFatalError(OptionFatalError,UnableToOpenXServer,
+ XDisplayName(server_name));
+ (void) XSetErrorHandler(MagickXError);
+ client_name=GetClientName();
+ resource_database=MagickXGetResourceDatabase(display,client_name);
+ MagickXGetImportInfo(&ximage_info);
+ MagickXGetResourceInfo(resource_database,(char *) client_name,&resource_info);
+ image_info=resource_info.image_info;
+ quantize_info=resource_info.quantize_info;
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"border","False");
+ ximage_info.borders=MagickIsTrue(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"delay","0");
+ resource_info.delay=MagickAtoL(resource_value);
+ image_info->density=MagickXGetResourceInstance(resource_database,client_name,
+ "density",(char *) NULL);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"descend","True");
+ ximage_info.descend=MagickIsTrue(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"frame","False");
+ ximage_info.frame=MagickIsTrue(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"interlace","none");
+ image_info->interlace=StringToInterlaceType(resource_value);
+ if (image_info->interlace == UndefinedInterlace)
+ MagickError(OptionError,UnrecognizedInterlaceType,resource_value);
+ image_info->page=MagickXGetResourceInstance(resource_database,client_name,
+ "pageGeometry",(char *) NULL);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"pause","0");
+ resource_info.pause=MagickAtoL(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"quality","85");
+ image_info->quality=MagickAtoL(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"screen","False");
+ ximage_info.screen=MagickIsTrue(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"silent","False");
+ ximage_info.silent=MagickIsTrue(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"verbose","False");
+ image_info->verbose=MagickIsTrue(resource_value);
+ resource_value=
+ MagickXGetResourceInstance(resource_database,client_name,"dither","True");
+ quantize_info->dither=MagickIsTrue(resource_value);
+ snapshots=1;
+ status=MagickPass;
+ filename=(char *) NULL;
+ target_window=(char *) NULL;
+ /*
+ Check command syntax.
+ */
+ for (i=1; i < argc; i++)
+ {
+ option=argv[i];
+ if ((strlen(option) == 1) || ((*option != '-') && (*option != '+')))
+ {
+ filename=argv[i];
+ continue;
+ }
+ switch(*(option+1))
+ {
+ case 'a':
+ {
+ if (LocaleCompare("adjoin",option+1) == 0)
+ {
+ image_info->adjoin=(*option == '-');
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'b':
+ {
+ if (LocaleCompare("border",option+1) == 0)
+ {
+ ximage_info.borders=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("bordercolor",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ (void) QueryColorDatabase(argv[i],&image_info->border_color,
+ exception);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'c':
+ {
+ if (LocaleCompare("colors",option+1) == 0)
+ {
+ quantize_info->number_colors=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ quantize_info->number_colors=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("colorspace",option+1) == 0)
+ {
+ quantize_info->colorspace=RGBColorspace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ quantize_info->colorspace=StringToColorspaceType(option);
+ if (IsGrayColorspace(quantize_info->colorspace))
+ {
+ quantize_info->number_colors=256;
+ quantize_info->tree_depth=8;
+ }
+ if (quantize_info->colorspace == UndefinedColorspace)
+ MagickFatalError(OptionFatalError,InvalidColorspaceType,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("comment",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ image_info->compression=NoCompression;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ image_info->compression=StringToCompressionType(option);
+ if (image_info->compression == UndefinedCompression)
+ MagickFatalError(OptionFatalError,
+ UnrecognizedImageCompressionType,option);
+ }
+ break;
+ }
+ if (LocaleCompare("crop",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'd':
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask("None");
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) SetLogEventMask(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("define",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ if (*option == '+')
+ (void) RemoveDefinitions(image_info,argv[i]);
+ else
+ (void) AddDefinitions(image_info,argv[i],exception);
+ break;
+ }
+ if (LocaleCompare("delay",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("density",option+1) == 0)
+ {
+ (void) CloneString(&image_info->density,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->density,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("depth",option+1) == 0)
+ {
+ image_info->depth=QuantumDepth;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ image_info->depth=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("descend",option+1) == 0)
+ {
+ ximage_info.descend=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("display",option+1) == 0)
+ {
+ (void) CloneString(&image_info->server_name,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ (void) CloneString(&image_info->server_name,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("dispose",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ option=argv[i];
+ if ((LocaleCompare("0",option) != 0) &&
+ (LocaleCompare("1",option) != 0) &&
+ (LocaleCompare("2",option) != 0) &&
+ (LocaleCompare("3",option) != 0) &&
+ (LocaleCompare("Undefined",option) != 0) &&
+ (LocaleCompare("None",option) != 0) &&
+ (LocaleCompare("Background",option) != 0) &&
+ (LocaleCompare("Previous",option) != 0))
+ MagickFatalError(OptionFatalError,UnrecognizedDisposeMethod,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("dither",option+1) == 0)
+ {
+ quantize_info->dither=(*option == '-');
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'e':
+ {
+ if (LocaleCompare("encoding",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("endian",option+1) == 0)
+ {
+ image_info->endian=UndefinedEndian;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ image_info->endian=StringToEndianType(option);
+ if (image_info->endian == UndefinedEndian)
+ MagickFatalError(OptionFatalError,InvalidEndianType,option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'f':
+ {
+ if (LocaleCompare("frame",option+1) == 0)
+ {
+ ximage_info.frame=(*option == '-');
+ MagickFreeMemory(argv[i]);
+ argv[i]=AcquireString("-ignore"); /* resolve option confict */
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'g':
+ {
+ if (LocaleCompare("geometry",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'h':
+ {
+ if (LocaleCompare("help",option+1) == 0)
+ break;
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'i':
+ {
+ if (LocaleCompare("interlace",option+1) == 0)
+ {
+ image_info->interlace=UndefinedInterlace;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ image_info->interlace=StringToInterlaceType(option);
+ if (image_info->interlace == UndefinedInterlace)
+ MagickFatalError(OptionFatalError,InvalidInterlaceType,
+ option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'l':
+ {
+ if (LocaleCompare("label",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("limit",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ ResourceType
+ resource_type;
+
+ char
+ *type;
+
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ type=argv[i];
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_type=StringToResourceType(type);
+ if (resource_type == UndefinedResource)
+ MagickFatalError(OptionFatalError,UnrecognizedResourceType,type);
+ (void) SetMagickResourceLimit(resource_type,MagickSizeStrToInt64(argv[i],1024));
+ }
+ break;
+ }
+ if (LocaleCompare("log",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) SetLogFormat(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'm':
+ {
+ if (LocaleCompare("monitor",option+1) == 0)
+ {
+ if (*option == '+')
+ {
+ (void) SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickSetConfirmAccessHandler((ConfirmAccessHandler) NULL);
+ }
+ else
+ {
+ (void) SetMonitorHandler(CommandProgressMonitor);
+ (void) MagickSetConfirmAccessHandler(CommandAccessMonitor);
+ }
+ break;
+ }
+ if (LocaleCompare("monochrome",option+1) == 0)
+ {
+ image_info->monochrome=(*option == '-');
+ if (image_info->monochrome)
+ {
+ quantize_info->number_colors=2;
+ quantize_info->tree_depth=8;
+ quantize_info->colorspace=GRAYColorspace;
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'n':
+ {
+ if (LocaleCompare("negate",option+1) == 0)
+ break;
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'p':
+ {
+ if (LocaleCompare("page",option+1) == 0)
+ {
+ (void) CloneString(&image_info->page,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ image_info->page=GetPageGeometry(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("pause",option+1) == 0)
+ {
+ resource_info.pause=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ resource_info.pause=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("pointsize",option+1) == 0)
+ {
+ image_info->pointsize=12;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ image_info->pointsize=MagickAtoF(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'q':
+ {
+ if (LocaleCompare("quality",option+1) == 0)
+ {
+ image_info->quality=DefaultCompressionQuality;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ image_info->quality=MagickAtoL(argv[i]);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'r':
+ {
+ if (LocaleCompare("resize",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("rotate",option+1) == 0)
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 's':
+ {
+ if (LocaleCompare("sampling-factor",option+1) == 0)
+ {
+ (void) CloneString(&image_info->sampling_factor,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->sampling_factor,argv[i]);
+ NormalizeSamplingFactor(image_info);
+ }
+ break;
+ }
+ if (LocaleCompare("scene",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,
+ option);
+ }
+ break;
+ }
+ if (LocaleCompare("screen",option+1) == 0)
+ {
+ ximage_info.screen=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("set",option+1) == 0)
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ if (*option == '-')
+ {
+ /* -set attribute value */
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("silent",option+1) == 0)
+ {
+ ximage_info.silent=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("size",option+1) == 0)
+ {
+ (void) CloneString(&image_info->size,(char *) NULL);
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&image_info->size,argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("snaps",option+1) == 0)
+ {
+ (void) strcpy(argv[i]+1,"sans");
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ snapshots=MagickAtoL(argv[i]);
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 't':
+ {
+ if (LocaleCompare("thumbnail",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !IsGeometry(argv[i]))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("transparent",option+1) == 0)
+ {
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ }
+ break;
+ }
+ if (LocaleCompare("treedepth",option+1) == 0)
+ {
+ quantize_info->tree_depth=0;
+ if (*option == '-')
+ {
+ i++;
+ if ((i == argc) || !sscanf(argv[i],"%ld",&x))
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ quantize_info->tree_depth=MagickAtoI(argv[i]);
+ }
+ break;
+ }
+ if (LocaleCompare("trim",option+1) == 0)
+ break;
+ if (LocaleCompare("type",option+1) == 0)
+ {
+ image_info->type=UndefinedType;
+ if (*option == '-')
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ option=argv[i];
+ image_info->type=StringToImageType(option);
+ if (image_info->type == UndefinedType)
+ MagickFatalError(OptionFatalError,InvalidImageType,option);
+ }
+ break;
+ }
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'v':
+ {
+ if (LocaleCompare("verbose",option+1) == 0)
+ {
+ image_info->verbose+=(*option == '-');
+ break;
+ }
+ if (LocaleCompare("version",option+1) == 0)
+ break;
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ case 'w':
+ {
+ i++;
+ if (i == argc)
+ MagickFatalError(OptionFatalError,MissingArgument,option);
+ (void) CloneString(&target_window,argv[i]);
+ break;
+ }
+ case '?':
+ {
+ break;
+ }
+ default:
+ {
+ MagickFatalError(OptionFatalError,UnrecognizedOption,option);
+ break;
+ }
+ }
+ }
+ /*
+ Erase existing exception.
+ */
+ DestroyExceptionInfo(exception);
+ GetExceptionInfo(exception);
+ if (filename == (char *) NULL)
+ filename=(char *) "magick.miff";
+ /*
+ Read image from X server.
+ */
+ if (target_window != (char *) NULL)
+ (void) strlcpy(image_info->filename,target_window,MaxTextExtent);
+ image_info->colorspace=quantize_info->colorspace;
+ image_info->dither=quantize_info->dither;
+ image=(Image *) NULL;
+ for (i=0; i < (long) Max(snapshots,1); i++)
+ {
+ (void) MagickSleep(resource_info.pause);
+ next_image=MagickXImportImage(image_info,&ximage_info);
+ status&=next_image != (Image *) NULL;
+ if (next_image == (Image *) NULL)
+ continue;
+ (void) strlcpy(next_image->filename,filename,MaxTextExtent);
+ (void) strcpy(next_image->magick,"PS");
+ next_image->scene=i;
+ next_image->previous=image;
+ if (image != (Image *) NULL)
+ image->next=next_image;
+ image=next_image;
+ }
+ if (image == (Image *) NULL)
+ MagickFatalError(OptionFatalError,RequestDidNotReturnAnImage,(char *) NULL);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ status&=MogrifyImages(image_info,argc-1,argv,&image);
+ (void) CatchImageException(image);
+ status&=WriteImages(image_info,image,filename,&image->exception);
+
+ DestroyImageList(image);
+ LiberateArgumentList(argc,argv);
+ MagickXDestroyResourceInfo(&resource_info);
+ MagickXDestroyX11Resources();
+ (void) XCloseDisplay(display);
+ return(status);
+#else
+ ARG_NOT_USED(image_info);
+ ARG_NOT_USED(argc);
+ ARG_NOT_USED(argv);
+ ARG_NOT_USED(metadata);
+ ARG_NOT_USED(exception);
+
+ MagickFatalError(MissingDelegateError,XWindowLibraryIsNotAvailable,
+ (char *) NULL);
+ return(MagickFail);
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m p o r t U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImportUsage() displays the program command syntax.
+%
+% The format of the ImportUsage method is:
+%
+% void ImportUsage()
+%
+%
+*/
+#if defined(HasX11)
+static void ImportUsage(void)
+{
+ const char
+ **p;
+
+ static const char
+ *options[]=
+ {
+ "-adjoin join images into a single multi-image file",
+ "-border include image borders in the output image",
+ "-colors value preferred number of colors in the image",
+ "-colorspace type alternate image colorspace",
+ "-comment string annotate image with comment",
+ "-compress type image compression type",
+ "-crop geometry preferred size and location of the cropped image",
+ "-debug events display copious debugging information",
+ "-define values Coder/decoder specific options",
+ "-delay value display the next image after pausing",
+ "-density geometry horizontal and vertical density of the image",
+ "-depth value image depth",
+ "-descend obtain image by descending window hierarchy",
+ "-display server X server to contact",
+ "-dispose method Undefined, None, Background, Previous",
+ "-dither apply Floyd/Steinberg error diffusion to image",
+ "-frame include window manager frame",
+ "-encoding type text encoding type",
+ "-endian type multibyte word order (LSB, MSB, or Native)",
+ "-geometry geometry perferred size or location of the image",
+ "-interlace type None, Line, Plane, or Partition",
+ "-help print program options",
+ "-label name assign a label to an image",
+ "-limit type value Disk, File, Map, Memory, Pixels, Width, Height or",
+ " Threads resource limit",
+ "-log format format of debugging information",
+ "-monitor show progress indication",
+ "-monochrome transform image to black and white",
+ "-negate replace every pixel with its complementary color ",
+ "-page geometry size and location of an image canvas",
+ "-pause value seconds delay between snapshots",
+ "-pointsize value font point size",
+ "-quality value JPEG/MIFF/PNG compression level",
+ "-resize geometry resize the image",
+ "-rotate degrees apply Paeth rotation to the image",
+ "-sampling-factor HxV[,...]",
+ " horizontal and vertical sampling factors",
+ "-scene value image scene number",
+ "-screen select image from root window",
+ "-set attribute value set image attribute",
+ "+set attribute unset image attribute",
+ "-silent operate silently, i.e. don't ring any bells ",
+ "-snaps value number of screen snapshots",
+ "-thumbnail geometry resize the image (optimized for thumbnails)",
+ "-transparent color make this color transparent within the image",
+ "-treedepth value color tree depth",
+ "-trim trim image edges",
+ "-type type image type",
+ "-verbose print detailed information about the image",
+ "-version print version information",
+ "-virtual-pixel method",
+ " Constant, Edge, Mirror, or Tile",
+ "-window id select window with this id or name",
+ (char *) NULL
+ };
+
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s [options ...] [ file ]\n",GetClientName());
+ (void) printf("\nWhere options include:\n");
+ for (p=options; *p != (char *) NULL; p++)
+ (void) printf(" %.1024s\n",*p);
+ (void) printf(
+ "\nBy default, 'file' is written in the MIFF image format. To\n");
+ (void) printf(
+ "specify a particular image format, precede the filename with an image\n");
+ (void) printf(
+ "format name and a colon (i.e. ps:image) or specify the image type as\n");
+ (void) printf(
+ "the filename suffix (i.e. image.ps). Specify 'file' as '-' for\n");
+ (void) printf("standard input or output.\n");
+}
+#endif /* HasX11 */
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P a r s e U n i x C o m m a n d L i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ParseUnixCommandLine reads the command line from input file handler,
+% parses the arguments following the Unix escape rule, and stores it in a
+% given text array.
+%
+% The format of the ParseUnixCommandLine method is:
+%
+% void ParseUnixCommandLine(FILE *in, int acmax, char **av)
+%
+% A description of each parameter follows:
+%
+% o in: An input file handler to read the command line from.
+%
+% o acmax: The max capacity of the 'av' text array.
+%
+% o av: A text array to store the parsed command line arguments.
+%
+*/
+static int ParseUnixCommandLine(FILE *in, int acmax, char **av)
+{
+ register int c;
+ register char *p = commandline;
+ register int n = 1;
+
+ char *limit = p + MAX_PARAM_CHAR;
+ limit[1] = 0;
+ av[1] = p;
+ *p = 0;
+ do
+ {
+ c = fgetc(in);
+ }
+ while(MagickIsBlank(c));
+
+ while (c != EOF)
+ {
+ switch (c)
+ {
+ case '\'':
+ while((c = fgetc(in)) != '\'')
+ {
+ if (p >= limit )
+ {
+ while ((c = fgetc(in)) != '\n');
+ return 0;
+ }
+ *p++ = c;
+ }
+ break;
+
+ case '"':
+ while((c = fgetc(in)) != '"')
+ {
+ if (c == '\\')
+ {
+ int next = fgetc(in);
+ if (next != '\\' && next != '"')
+ *p++ = c;
+ c = next;
+ }
+ if (p >= limit )
+ {
+ while ((c = fgetc(in)) != '\n');
+ return 0;
+ }
+ *p++ = c;
+ }
+ break;
+
+ case ' ':
+ case '\t':
+ *p++ = '\0';
+ if (++n > acmax)
+ {
+ while ((c = fgetc(in)) != '\n');
+ return acmax+1;
+ }
+ av[n] = p;
+ *p = 0;
+ do { c = fgetc(in); }
+ while(MagickIsBlank(c));
+ continue;
+
+ case '\r':
+ break;
+
+ case '#':
+ while ((c = fgetc(in)) != '\n');
+ /* Same handling as '\n' since we are at end of line */
+ *p = 0;
+ n = av[n][0] ? n+1 : n;
+ av[n] = (char *)NULL;
+ return n;
+
+ case '\n':
+ *p = 0;
+ n = av[n][0] ? n+1 : n;
+ av[n] = (char *)NULL;
+ return n;
+
+ case '\\':
+ c = fgetc(in);
+ if (p >= limit )
+ {
+ while ((c = fgetc(in)) != '\n');
+ return 0;
+ }
+ *p++ = c;
+ break;
+
+ default:
+ if (p >= limit )
+ {
+ while ((c = fgetc(in)) != '\n');
+ return 0;
+ }
+ *p++ = c;
+ break;
+ }
+ c = fgetc(in);
+ }
+ return EOF;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P a r s e W i n d o w s C o m m a n d L i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ParseWindowsCommandLine reads the command line from input file handler,
+% parses the arguments following the Windows escape rule, and stores it in a
+% given text array.
+%
+% The format of the ParseWindowsCommandLine method is:
+%
+% void ParseWindowsCommandLine(FILE *in, int acmax, char **av)
+%
+% A description of each parameter follows:
+%
+% o in: An input file handler to read the command line from.
+%
+% o acmax: The max capacity of the 'av' text array.
+%
+% o av: A text array to store the parsed command line arguments.
+%
+*/
+static int ParseWindowsCommandLine(FILE *in, int acmax, char **av)
+{
+ register int c;
+ register char *p = commandline;
+ register int n = 1;
+
+ char *limit = p + MAX_PARAM_CHAR;
+ limit[1] = 0;
+ av[1] = p;
+ *p = 0;
+ do
+ {
+ c = fgetc(in);
+ }
+ while(MagickIsBlank(c));
+
+ while (c != EOF)
+ {
+ switch (c)
+ {
+ case '"':
+ for(;;)
+ {
+ c = fgetc(in);
+ if (c == '"')
+ {
+ int next = fgetc(in);
+ if (next != '"')
+ {
+ ungetc(next, in);
+ break;
+ }
+ }
+ if (p >= limit )
+ {
+ while ((c = fgetc(in)) != '\n');
+ return 0;
+ }
+ *p++ = c;
+ }
+ break;
+
+ case ' ':
+ case '\t':
+ *p++ = '\0';
+ if (++n > acmax)
+ {
+ while ((c = fgetc(in)) != '\n');
+ return acmax+1;
+ }
+ av[n] = p;
+ *p = 0;
+ do { c = fgetc(in); }
+ while(MagickIsBlank(c));
+ continue;
+
+ case '\r':
+ break;
+
+ case '#':
+ while ((c = fgetc(in)) != '\n');
+ /* Same handling as '\n' since we are at end of line */
+ *p = 0;
+ n = av[n][0] ? n+1 : n;
+ av[n] = (char *)NULL;
+ return n;
+
+ case '\n':
+ *p = 0;
+ n = av[n][0] ? n+1 : n;
+ av[n] = (char *)NULL;
+ return n;
+
+ default:
+ if (p >= limit )
+ {
+ while ((c = fgetc(in)) != '\n');
+ return 0;
+ }
+ *p++ = c;
+ break;
+ }
+ c = fgetc(in);
+ }
+ return EOF;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P r o c e s s B a t c h O p t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ProcessBatchOptions processes arguments of batch and set command and stores
+% option values in given pointer. The return value is either OptionStatus if
+% negative or the first none option argument position.
+%
+% The format of the ProcessBatchOptions method is:
+%
+% int ProcessBatchOptions(int argc, char **argv, BatchOptions *options)
+%
+% A description of each parameter follows:
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o options: Points to the variable to accept the the option value.
+%
+*/
+static int ProcessBatchOptions(int argc, char **argv, BatchOptions *options)
+{
+ int i;
+ for (i = 1; i < argc; i++ )
+ {
+ char *option;
+ char *p = argv[i];
+ OptionStatus status = OptionUnknown;
+
+ if (p[0] != '-')
+ return i;
+
+ switch (p[1])
+ {
+ case '\0':
+ return i;
+
+ case '-':
+ if (p[2] == '\0')
+ return i+1;
+ break;
+
+ case 'e':
+ case 'E':
+ if (LocaleCompare(option = "-escape", p) == 0)
+ {
+ int index;
+ status = GetOptionValueRestricted(option, escape_option_values, argv[++i], &index);
+ if (status == OptionSuccess)
+ options->command_line_parser = index ? ParseWindowsCommandLine : ParseUnixCommandLine;
+ }
+ else if (LocaleCompare(option = "-echo", p) == 0)
+ status = GetOnOffOptionValue(option, argv[++i], &options->is_echo_enabled);
+ break;
+
+ case 'f':
+ case 'F':
+ if (LocaleCompare(option = "-feedback", p) == 0)
+ status = GetOnOffOptionValue(option, argv[++i], &options->is_feedback_enabled);
+ else if (LocaleCompare(option = "-fail", p) == 0)
+ {
+ char *value = NULL;
+ status = GetOptionValue(option, argv[++i], &value);
+ if (OptionSuccess == status)
+ strlcpy(options->fail, value, sizeof(options->fail));
+ }
+ break;
+
+ case '?':
+ if (p[2] == '\0')
+ status = OptionHelp;
+ break;
+
+ case 'h':
+ case 'H':
+ if (LocaleCompare("-help", p) == 0)
+ status = OptionHelp;
+ break;
+
+ case 'p':
+ case 'P':
+ if (LocaleCompare(option = "-pass", p) == 0)
+ {
+ char *value = NULL;
+ status = GetOptionValue(option, argv[++i], &value);
+ if (OptionSuccess == status)
+ strlcpy(options->pass, value, sizeof(options->pass));
+ }
+ else if (LocaleCompare(option = "-prompt", p) == 0) {
+ char *value = NULL;
+ status = GetOptionValue(option, argv[++i], &value);
+ if (OptionSuccess == status)
+ strlcpy(options->prompt,
+ LocaleCompare("off", value) == 0 ? "" : value,
+ sizeof(options->prompt));
+ }
+ break;
+
+ case 's':
+ case 'S':
+ if (LocaleCompare(option = "-stop-on-error", p) == 0)
+ status = GetOnOffOptionValue(option, argv[++i], &options->stop_on_error);
+ break;
+ }
+ if (status == OptionSuccess)
+ continue;
+ if (status == OptionUnknown)
+ fprintf(stderr, "Error: Unknown option: %s\n", p);
+ return status;
+ }
+ return argc;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetCommand reads the arguments and sets the batch options.
+%
+% The format of the SetCommand method is:
+%
+% unsigned int SetCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+static unsigned int SetCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+
+ ARG_NOT_USED(image_info);
+ ARG_NOT_USED(metadata);
+ ARG_NOT_USED(exception);
+
+ if (argc > 1)
+ {
+ /* use a dummy first so we don't change the real one when error. */
+ BatchOptions dummy;
+ int i = ProcessBatchOptions(argc, argv, &dummy);
+ if (i < 0)
+ {
+ SetUsage();
+ return i == OptionHelp;
+ }
+ if (i != argc)
+ {
+ fprintf(stderr, "Error: unexpected parameter: %s\n", argv[i]);
+ SetUsage();
+ return MagickFalse;
+ }
+ ProcessBatchOptions(argc, argv, &batch_options);
+ return MagickTrue;
+ }
+
+ printf("escape : %s\n", escape_option_values[batch_options.command_line_parser == ParseWindowsCommandLine]);
+ printf("fail : %s\n", batch_options.fail);
+ printf("feedback : %s\n", on_off_option_values[batch_options.is_feedback_enabled]);
+ printf("stop-on-error : %s\n", on_off_option_values[batch_options.stop_on_error]);
+ printf("pass : %s\n", batch_options.pass);
+ printf("prompt : %s\n", batch_options.prompt);
+ return MagickTrue;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetUsage displays the program command syntax.
+%
+% The format of the SetUsage method is:
+%
+% void SetUsage()
+%
+*/
+static void SetUsage(void)
+{
+ (void) puts("Usage: set [options ...]");
+ BatchOptionUsage();
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T i m e U s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TimeUsage() displays the program command syntax.
+%
+% The format of the TimeUsage method is:
+%
+% void TimeUsage()
+%
+% A description of each parameter follows:
+%
+%
+*/
+static void TimeUsage(void)
+{
+ PrintUsageHeader();
+ (void) printf("Usage: %.1024s command ... \n",GetClientName());
+ (void) printf("where 'command' is some other GraphicsMagick command\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T i m e I m a g e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TimeImageCommand() executes a specified GraphicsMagick sub-command
+% (e.g. 'convert') and prints out a summary of how long it took to the
+% standard error output. The format is similar to the output of the 'time'
+% command in the zsh shell.
+%
+% The format of the TimeImageCommand method is:
+%
+% unsigned int TimeImageCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail
+TimeImageCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,ExceptionInfo *exception)
+{
+ double
+ elapsed_time,
+ /* resolution, */
+ user_time;
+
+ TimerInfo
+ timer;
+
+ const char
+ *pad=" ";
+
+ char
+ client_name[MaxTextExtent];
+
+ int
+ formatted,
+ i,
+ screen_width;
+
+ MagickPassFail
+ status=MagickTrue;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ if (argc < 2 || ((argc < 3) && (LocaleCompare("-help",argv[1]) == 0 ||
+ LocaleCompare("-?",argv[1]) == 0)))
+ {
+ TimeUsage();
+ if (argc < 2)
+ {
+ ThrowException(exception,OptionError,UsageError,NULL);
+ return MagickFail;
+ }
+ return MagickPass;
+ }
+ if (LocaleCompare("-version",argv[1]) == 0)
+ {
+ (void) VersionCommand(image_info,argc,argv,metadata,exception);
+ return MagickPass;
+ }
+
+ /*
+ Skip over our command name argv[0].
+ */
+ argc--;
+ argv++;
+ i=0;
+
+ (void) strlcpy(client_name,GetClientName(),sizeof(client_name));
+ GetTimerInfo(&timer);
+ status=ExecuteSubCommand(image_info,argc,argv,metadata,exception);
+ (void) SetClientName(client_name);
+
+ /* resolution=GetTimerResolution(); */
+ user_time=GetUserTime(&timer);
+ elapsed_time=GetElapsedTime(&timer);
+ (void) fflush(stdout);
+
+ screen_width=0;
+ if (getenv("COLUMNS"))
+ screen_width=MagickAtoI(getenv("COLUMNS"))-1;
+ if (screen_width < 80)
+ screen_width=80;
+
+ formatted=0;
+ for (i=0; i < argc; i++)
+ {
+ if (i != 0)
+ formatted += fprintf(stderr," ");
+ formatted += fprintf(stderr,"%s",argv[i]);
+ if (formatted > (screen_width-55))
+ {
+ if ((i+1) < argc)
+ pad="... ";
+ break;
+ }
+ }
+ (void) fprintf(stderr,
+ "%s%.2fs user %.2fs system %.0f%% cpu %.3f total\n",
+ pad,user_time,0.0,100.0*user_time/elapsed_time,elapsed_time);
+ (void) fflush(stderr);
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% V e r s i o n C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% VersionCommand() prints the package copyright and release version.
+%
+% The format of the VersionCommand method is:
+%
+% MagickPassFail VersionCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static void PrintFeatureTextual(const char* feature,MagickBool support,const char *text)
+{
+ const char
+ *support_text;
+
+ support_text=(support ? "yes" : "no");
+ if ((text != NULL) && strlen(text) != 0)
+ (void) fprintf(stdout," %-24s %s (%s)\n", feature, support_text, text);
+ else
+ (void) fprintf(stdout," %-24s %s\n", feature, support_text);
+}
+static void PrintFeature(const char* feature,MagickBool support)
+{
+ PrintFeatureTextual(feature,support, NULL);
+}
+static MagickPassFail VersionCommand(ImageInfo *image_info,
+ int argc,char **argv,char **metadata,
+ ExceptionInfo *exception)
+{
+ MagickBool
+ supported;
+
+ char
+ text[MaxTextExtent];
+
+ ARG_NOT_USED(image_info);
+ ARG_NOT_USED(argc);
+ ARG_NOT_USED(argv);
+ ARG_NOT_USED(metadata);
+ ARG_NOT_USED(exception);
+
+ PrintVersionAndCopyright();
+
+ (void) fprintf(stdout,"\nFeature Support:\n");
+
+ /* Thread Safe */
+ supported=MagickFalse;
+#if defined(MSWINDOWS) || defined(HAVE_PTHREAD)
+ supported=MagickTrue;
+#endif /* defined((MSWINDOWS) || defined(HAVE_PTHREAD) */
+ PrintFeature("Native Thread Safe", supported);
+
+ /*
+ Large File Support
+
+ For POSIX, the 'stat' structure has 'st_size' member which is of
+ type 'off_t'. However, Windows provides a large family of _stat*
+ structures with varying proportions and we might be using 'struct
+ stat' or 'struct _stati64' which use different hard-coded types
+ for the 'st_size' member. While large files might be otherwise
+ supported, we consider the maximum size reportable by 'stat' to be
+ the limiting factor.
+ */
+ {
+ MagickStatStruct_t
+ attributes;
+
+ supported=(sizeof(attributes.st_size) > 4);
+ (void) attributes;
+ }
+ PrintFeature("Large Files (> 32 bit)", supported);
+
+ /* Large Memory Support */
+ supported=(sizeof(PixelPacket *) > 4);
+ PrintFeature("Large Memory (> 32 bit)", supported);
+
+ /* BZIP */
+ supported=MagickFalse;
+#if defined(HasBZLIB)
+ supported=MagickTrue;
+#endif /* defined(HasBZLIB) */
+ PrintFeature("BZIP", supported);
+
+ /* DPS */
+ supported=MagickFalse;
+#if defined(HasDPS)
+ supported=MagickTrue;
+#endif /* defined(HasDPS) */
+ PrintFeature("DPS", supported);
+
+ /* FlashPix */
+ supported=MagickFalse;
+#if defined(HasFPX)
+ supported=MagickTrue;
+#endif /* defined(HasFPX) */
+ PrintFeature("FlashPix", supported);
+
+ /* FreeType */
+ supported=MagickFalse;
+#if defined(HasTTF)
+ supported=MagickTrue;
+#endif /* defined(HasTTF) */
+ PrintFeature("FreeType", supported);
+
+ /* Ghostscript Library */
+ supported=MagickFalse;
+#if defined(HasGS)
+ supported=MagickTrue;
+#endif /* defined(HasGS) */
+ PrintFeature("Ghostscript (Library)", supported);
+
+ /* JBIG */
+ supported=MagickFalse;
+#if defined(HasJBIG)
+ supported=MagickTrue;
+#endif /* defined(HasJBIG) */
+ PrintFeature("JBIG",supported);
+
+ /* JPEG-2000 */
+ supported=MagickFalse;
+#if defined(HasJP2)
+ supported=MagickTrue;
+#endif /* defined(HasJP2) */
+ PrintFeature("JPEG-2000", supported);
+
+ /* JPEG */
+ supported=MagickFalse;
+#if defined(HasJPEG)
+ supported=MagickTrue;
+#endif /* defined(HasJPEG) */
+ PrintFeature("JPEG", supported);
+
+ /* Little CMS */
+ supported=MagickFalse;
+#if defined(HasLCMS)
+ supported=MagickTrue;
+#endif /* defined(HasLCMS) */
+ PrintFeature("Little CMS", supported);
+
+ /* Loadable Modules */
+ supported=MagickFalse;
+#if defined(SupportMagickModules)
+ supported=MagickTrue;
+#endif /* defined(SupportMagickModules) */
+ PrintFeature("Loadable Modules", supported);
+
+ /* OpenMP */
+ supported=MagickFalse;
+ text[0]='\0';
+#if defined(HAVE_OPENMP)
+ supported=MagickTrue;
+ FormatString(text,"%u",(unsigned int) _OPENMP);
+#endif /* defined(HAVE_OPENMP) */
+ PrintFeatureTextual("OpenMP", supported, text);
+
+ /* PNG */
+ supported=MagickFalse;
+#if defined(HasPNG)
+ supported=MagickTrue;
+#endif /* defined(HasPNG) */
+ PrintFeature("PNG", supported);
+
+ /* TIFF */
+ supported=MagickFalse;
+#if defined(HasTIFF)
+ supported=MagickTrue;
+#endif /* defined(HasTIFF) */
+ PrintFeature("TIFF", supported);
+
+ /* TRIO */
+ supported=MagickFalse;
+#if defined(HasTRIO)
+ supported=MagickTrue;
+#endif /* defined(HasTRIO) */
+ PrintFeature("TRIO", supported);
+
+ /* Solaris libumem */
+ supported=MagickFalse;
+#if defined(HasUMEM)
+ supported=MagickTrue;
+#endif /* defined(HasUMEM) */
+ PrintFeature("UMEM", supported);
+
+ /* WebP */
+ supported=MagickFalse;
+#if defined(HasWEBP)
+ supported=MagickTrue;
+#endif /* defined(HasWEBP) */
+ PrintFeature("WebP", supported);
+
+ /* WMF */
+ supported=MagickFalse;
+#if defined(HasWMF) || defined(HasWMFlite)
+ supported=MagickTrue;
+#endif /* defined(HasWMF) || defined(HasWMFlite) */
+ PrintFeature("WMF", supported);
+
+ /* X11 */
+ supported=MagickFalse;
+#if defined(HasX11)
+ supported=MagickTrue;
+#endif /* defined(HasX11) */
+ PrintFeature("X11", supported);
+
+ /* XML */
+ supported=MagickFalse;
+#if defined(HasXML)
+ supported=MagickTrue;
+#endif /* defined(HasXML) */
+ PrintFeature("XML", supported);
+
+ /* ZLIB */
+ supported=MagickFalse;
+#if defined(HasZLIB)
+ supported=MagickTrue;
+#endif /* defined(HasZLIB) */
+ PrintFeature("ZLIB", supported);
+
+#if defined(GM_BUILD_HOST)
+ (void) fprintf(stdout,"\nHost type: %.1024s\n", GM_BUILD_HOST);
+#endif /* defined(GM_BUILD_HOST) */
+
+#if defined(GM_BUILD_CONFIGURE_ARGS)
+ (void) fprintf(stdout,"\nConfigured using the command:\n %.1024s\n",
+ GM_BUILD_CONFIGURE_ARGS);
+#endif /* defined(GM_BUILD_CONFIGURE_ARGS) */
+
+#if defined(GM_BUILD_CC)
+ (void) fprintf(stdout,"\nFinal Build Parameters:\n");
+ (void) fprintf(stdout," CC = %.1024s\n", GM_BUILD_CC);
+#endif /* defined(GM_BUILD_CC) */
+
+#if defined(GM_BUILD_CFLAGS)
+ (void) fprintf(stdout," CFLAGS = %.1024s\n", GM_BUILD_CFLAGS);
+#endif /* defined(GM_BUILD_CFLAGS) */
+
+#if defined(GM_BUILD_CPPFLAGS)
+ (void) fprintf(stdout," CPPFLAGS = %.1024s\n", GM_BUILD_CPPFLAGS);
+#endif /* defined(GM_BUILD_CPPFLAGS) */
+
+#if defined(GM_BUILD_CXX)
+ (void) fprintf(stdout," CXX = %.1024s\n", GM_BUILD_CXX);
+#endif /* defined(GM_BUILD_CXX) */
+
+#if defined(GM_BUILD_CXXFLAGS)
+ (void) fprintf(stdout," CXXFLAGS = %.1024s\n", GM_BUILD_CXXFLAGS);
+#endif /* defined(GM_BUILD_CXXFLAGS) */
+
+#if defined(GM_BUILD_LDFLAGS)
+ (void) fprintf(stdout," LDFLAGS = %.1024s\n", GM_BUILD_LDFLAGS);
+#endif /* defined(GM_BUILD_LDFLAGS) */
+
+#if defined(GM_BUILD_LIBS)
+ (void) fprintf(stdout," LIBS = %.1024s\n", GM_BUILD_LIBS);
+#endif /* defined(GM_BUILD_LIBS) */
+
+#if defined(_VISUALC_)
+
+ (void) fprintf(stdout,"\nWindows Build Parameters:\n\n");
+
+# if defined(_MSC_VER)
+ (void) fprintf(stdout," MSVC Version: %d\n", _MSC_VER);
+# endif /* defined(_MSC_VER) */
+
+# if defined(__CLR_VER)
+ (void) fprintf(stdout," CLR Version: %d\n", __CLR_VER);
+# endif /* defined(__CLR_VER) */
+
+ /* Defined for compilations that target x86 processors. This is not
+ defined for x64 processors. */
+# if defined(_M_IX86)
+ {
+ const char
+ *processor_target = "";
+
+ if (_M_IX86 >= 600)
+ processor_target="Pentium Pro, Pentium II, and Pentium III";
+ else if (_M_IX86 >= 500)
+ processor_target="Pentium";
+ else if (_M_IX86 >= 400)
+ processor_target="80486";
+ else if (_M_IX86 >= 300)
+ processor_target="80386";
+
+ if (strlen(processor_target) > 0)
+ (void) fprintf(stdout," Processor target: %s\n", processor_target);
+ }
+# endif /* defined(_M_IX86) */
+# if defined(_M_IX86_FP)
+ {
+ const char
+ *processor_arch = "";
+
+ if (_M_IX86_FP == 0)
+ processor_arch="NONE";
+ else if (_M_IX86_FP == 1)
+ processor_arch="SSE";
+ else if (_M_IX86_FP == 2)
+ processor_arch="SSE2";
+
+ if (strlen(processor_arch) > 0)
+ (void) fprintf(stdout," Processor arch: %s\n", processor_arch);
+ }
+# endif /* defined(_M_IX86_FP) */
+
+#endif /* defined(_VISUALC_) */
+
+ return MagickPass;
+}
+
+#if defined(MSWINDOWS)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RegisterCommand() registers this appplication as the source for messages
+% compatible with the windows event logging system. All this does is to set
+% a registry value to point to either an EXE or DLL that contains a special
+% binary resource containing all the messages that can be used.
+%
+% The format of the RegisterCommand method is:
+%
+% MagickPassFail RegisterCommand(ImageInfo *image_info,const int argc,
+% char **argv,char **metadata,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+% o metadata: any metadata is returned here.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail RegisterCommand(ImageInfo *image_info,
+ int argc,
+ char **argv,
+ char **metadata,
+ ExceptionInfo *exception)
+{
+ char
+ *szRegPath =
+ "SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\";
+
+ char
+ szKey[_MAX_PATH*2];
+
+ DWORD
+ dwResult = 0;
+
+ HKEY
+ hKey = NULL;
+
+ LONG
+ lRet;
+
+ ARG_NOT_USED(image_info);
+ ARG_NOT_USED(argc);
+ ARG_NOT_USED(argv);
+ ARG_NOT_USED(metadata);
+ ARG_NOT_USED(exception);
+
+ memset(szKey, 0, _MAX_PATH*2*sizeof(char));
+ strcpy(szKey, szRegPath);
+ strcat(szKey, "GraphicsMagick");
+
+ /* open the registry event source key */
+ lRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
+ &hKey, &dwResult);
+ if (lRet == ERROR_SUCCESS)
+ {
+ char
+ szPathName[MaxTextExtent];
+
+ DWORD
+ dwSupportedTypes;
+
+ /* set a pointer to thsi application as the source for our messages */
+ memset(szPathName, 0, MaxTextExtent*sizeof(char));
+ FormatString(szPathName,"%.1024s%s%.1024s",
+ GetClientPath(),DirectorySeparator,GetClientName());
+ RegSetValueEx(hKey, "EventMessageFile", 0, REG_SZ,
+ (const BYTE *) szPathName,
+ ((DWORD) strlen(szPathName) + 1)*sizeof(char));
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Registered path to messages as: %s",szPathName);
+
+ /* supports all types of messages */
+ dwSupportedTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
+ EVENTLOG_INFORMATION_TYPE | EVENTLOG_AUDIT_SUCCESS |
+ EVENTLOG_AUDIT_FAILURE;
+ RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD,
+ (const BYTE *) &dwSupportedTypes, sizeof(DWORD));
+
+ RegCloseKey(hKey);
+ return MagickPass;
+ }
+
+ return MagickFail;
+}
+#endif
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G M C o m m a n d S i n g l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GMCommandSingle() is used by GMCommand() and BatchCommand to run one single
+% command of the 'gm' utility.
+%
+% The format of the GMCommandSingle method is:
+%
+% MagickPassFail GMCommandSingle(int argc,char **argv)
+%
+% A description of each parameter follows:
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+%
+*/
+static MagickPassFail GMCommandSingle(int argc,char **argv)
+{
+ char
+ command[MaxTextExtent],
+ *text;
+
+ ExceptionInfo
+ exception;
+
+ ImageInfo
+ *image_info;
+
+ MagickPassFail
+ status=MagickTrue;
+
+ /*
+ Initialize locale from environment variables (LANG, LC_CTYPE,
+ LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES,
+ LC_ALL), but require that LC_NUMERIC use common conventions. The
+ LC_NUMERIC variable affects the decimal point character and
+ thousands separator character for the formatted input/output
+ functions and string conversion functions.
+ */
+ (void) setlocale(LC_ALL,"");
+ (void) setlocale(LC_NUMERIC,"C");
+
+ if (run_mode == SingleMode)
+ {
+#if defined(MSWINDOWS)
+ InitializeMagick((char *) NULL);
+#else
+ InitializeMagick(argv[0]);
+#endif
+ }
+
+ ReadCommandlLine(argc,&argv);
+
+ (void) SetClientName(argv[0]);
+ {
+ /*
+ Support traditional alternate names for GraphicsMagick subcommands.
+ */
+ static const char *command_names [] =
+ {
+ "animate",
+ "composite",
+ "conjure",
+ "convert",
+ "display",
+ "identify",
+ "import",
+ "mogrify",
+ "montage",
+ NULL
+ };
+
+ unsigned int
+ i;
+
+ GetPathComponent(argv[0],BasePath,command);
+ for (i=0; command_names[i]; i++)
+ if (LocaleCompare(command,command_names[i]) == 0)
+ break;
+
+ if (command_names[i])
+ {
+ /*
+ Set command name to alternate name.
+ */
+ argv[0]=(char *) SetClientName(command);
+ }
+ else
+ {
+ if (argc < 2)
+ {
+ GMUsage();
+ return(MagickFail);
+ }
+
+ /*
+ Skip to subcommand name.
+ */
+ argc--;
+ argv++;
+ }
+ if (!strcmp(argv[0], "ping"))
+ return MagickTrue;
+ }
+
+ GetExceptionInfo(&exception);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ text=(char *) NULL;
+ status=MagickCommand(image_info,argc,argv,&text,&exception);
+ if (text != (char *) NULL)
+ {
+ if (strlen(text))
+ {
+ (void) fputs(text,stdout);
+ (void) fputc('\n',stdout);
+ (void) fflush(stdout);
+ }
+ MagickFreeMemory(text);
+ }
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ DestroyImageInfo(image_info);
+ DestroyExceptionInfo(&exception);
+ if (run_mode == SingleMode)
+ DestroyMagick();
+
+ return (status);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G M C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GMCommand() implements the 'gm' utility.
+%
+% The format of the GMCommand method is:
+%
+% int GMCommand(int argc,char **argv)
+%
+% A description of each parameter follows:
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+%
+*/
+
+MagickExport int GMCommand(int argc,char **argv)
+{
+ int status;
+ if ((argc <= 1) || LocaleCompare("batch", argv[1]) != 0)
+ {
+ status = GMCommandSingle(argc, argv);
+ }
+ else
+ {
+ status = BatchCommand(argc, argv);
+ }
+ return(!status);
+}
diff --git a/magick/command.h b/magick/command.h
new file mode 100644
index 0000000..58eaca0
--- /dev/null
+++ b/magick/command.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2003 - 2017 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Image Command Methods.
+*/
+#ifndef _MAGICK_COMMAND_H
+#define _MAGICK_COMMAND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+extern MagickExport MagickPassFail
+ AnimateImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ BenchmarkImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ CompareImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ CompositeImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ ConjureImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ ConvertImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ DisplayImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ IdentifyImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ ImportImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ MagickCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ MogrifyImage(const ImageInfo *,int,char **,Image **),
+ MogrifyImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ MogrifyImages(const ImageInfo *,int,char **,Image **),
+ MontageImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception),
+ TimeImageCommand(ImageInfo *image_info,int argc,char **argv,
+ char **metadata,ExceptionInfo *exception);
+
+extern MagickExport int
+ GMCommand(int argc,char **argv);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+extern void
+ MagickDestroyCommandInfo(void);
+
+extern MagickPassFail
+ MagickInitializeCommandInfo(void);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/common.h b/magick/common.h
new file mode 100644
index 0000000..d975a6e
--- /dev/null
+++ b/magick/common.h
@@ -0,0 +1,281 @@
+/*
+ Copyright (C) 2009-2016 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Magick API common definitions support.
+*/
+#ifndef _MAGICK_COMMON_H
+#define _MAGICK_COMMON_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ * Borland C++ Builder DLL compilation defines
+ */
+#if defined(__BORLANDC__) && defined(_DLL)
+# pragma message("BCBMagick lib DLL export interface")
+# define _MAGICKDLL_
+# define _MAGICKLIB_
+# undef BuildMagickModules
+# define SupportMagickModules
+#endif
+
+#if defined(MSWINDOWS) && !defined(__CYGWIN__)
+# if defined(_MT) && defined(_DLL) && !defined(_MAGICKDLL_) && !defined(_LIB)
+# define _MAGICKDLL_
+# endif
+# if defined(_MAGICKDLL_)
+# if defined(_VISUALC_)
+# pragma warning( disable: 4273 ) /* Disable the dll linkage warnings */
+# endif
+# if !defined(_MAGICKLIB_)
+# define MagickExport __declspec(dllimport)
+# if defined(_VISUALC_)
+# pragma message( "Magick lib DLL import interface" )
+# endif
+# else
+# define MagickExport __declspec(dllexport)
+# if defined(_VISUALC_)
+# pragma message( "Magick lib DLL export interface" )
+# endif
+# endif
+# else
+# define MagickExport
+# if defined(_VISUALC_)
+# pragma message( "Magick lib static interface" )
+# endif
+# endif
+# if defined(_DLL) && !defined(_LIB)
+# define ModuleExport __declspec(dllexport)
+# if defined(_VISUALC_)
+# pragma message( "Magick module DLL export interface" )
+# endif
+# else
+# define ModuleExport
+# if defined(_VISUALC_)
+# pragma message( "Magick module static interface" )
+# endif
+# endif
+# define MagickGlobal __declspec(thread)
+# if defined(_VISUALC_)
+# pragma warning(disable : 4018)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4275) /* non dll-interface class 'foo' used as base for dll-interface class 'bar' */
+# pragma warning(disable : 4800)
+# pragma warning(disable : 4786)
+# pragma warning(disable : 4996) /* function deprecation warnings */
+# endif
+#else
+# define MagickExport
+# define ModuleExport
+# define MagickGlobal
+#endif
+
+/*
+ This size is the default minimum string allocation size (heap or
+ stack) for a C string in GraphicsMagick. The weird size is claimed
+ to be based on 2*FILENAME_MAX (not including terminating NULL) on
+ some antique system. Linux has a FILENAME_MAX definition, but it is
+ 4096 bytes. Many OSs have path limits of 1024 bytes.
+
+ The FormatString() function assumes that the buffer it is writing to
+ has at least this many bytes remaining.
+*/
+#if !defined(MaxTextExtent)
+# define MaxTextExtent 2053
+#endif
+
+#define MagickSignature 0xabacadabUL
+
+#define MagickPassFail unsigned int
+#define MagickPass 1
+#define MagickFail 0
+
+#define MagickBool unsigned int
+#define MagickTrue 1
+#define MagickFalse 0
+
+/*
+ Support for __attribute__ was added in GCC 2.0. It is not supported
+ in strict ANSI mode which is indicated by __STRICT_ANSI__ being
+ defined.
+
+ http://www.ohse.de/uwe/articles/gcc-attributes.html
+
+ Note that GCC 3.2 on MinGW does not define __GNUC__ or __GNUC_MINOR__.
+
+ Clang/llvm and GCC 5.0 support __has_attribute(attribute) to test if an
+ attribute is supported. Clang/llvm supports __has_builtin(builtin) to test
+ if a builtin is supported. Clang/llvm attempts to support most GCC
+ features.
+
+ __SANITIZE_ADDRESS__ is defined by GCC and Clang if -fsanitize=address is
+ supplied.
+
+ After incuding valgrind/memcheck.h or valgrind/valgrind.h, the macro
+ RUNNING_ON_VALGRIND can be used to test if the program is run under valgrind.
+ See http://valgrind.org/docs/manual/manual-core-adv.html.
+
+*/
+#if !defined(MAGICK_ATTRIBUTE)
+# if ((!defined(__clang__)) && (!defined(__GNUC__) || (__GNUC__ < 2 || __STRICT_ANSI__)))
+# define MAGICK_ATTRIBUTE(x) /*nothing*/
+# else
+# define MAGICK_ATTRIBUTE(x) __attribute__(x)
+# if ((defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 5)) && !defined(__COVERITY__))
+# define MAGICK_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
+# else
+# define MAGICK_HAS_ATTRIBUTE(attribute) (0)
+# endif
+# if (defined(__clang__) && !defined(__COVERITY__))
+# define MAGICK_CLANG_HAS_BUILTIN(builtin) __has_builtin(builtin)
+# else
+# define MAGICK_CLANG_HAS_BUILTIN(builtin) (0)
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__deprecated__)) || \
+ (((__GNUC__) > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))) /* 3.1+ */
+# define MAGICK_FUNC_DEPRECATED MAGICK_ATTRIBUTE((__deprecated__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__malloc__)) || \
+ (__GNUC__ >= 3)) /* 3.0+ */
+# define MAGICK_FUNC_MALLOC MAGICK_ATTRIBUTE((__malloc__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__nonnull__)) || \
+ (((__GNUC__) > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))) /* 3.3+ */
+ /* Supports argument syntax like MAGICK_ATTRIBUTE((nonnull (1, 2))) but
+ don't know how to support non-GCC fallback. */
+# define MAGICK_FUNC_NONNULL MAGICK_ATTRIBUTE((__nonnull__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__noreturn__)) || \
+ (((__GNUC__) > 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 5)))) /* 2.5+ */
+# define MAGICK_FUNC_NORETURN MAGICK_ATTRIBUTE((__noreturn__))
+# endif
+ /* clang 3.0 seems to have difficulties with __has_attribute(__const__) but
+ clang 3.3 does not. Just assume that it is supported for clang since
+ Linux headers are riddled with it. */
+# if (defined(__clang__) || \
+ (((__GNUC__) > 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 5)))) /* 2.5+ */
+# define MAGICK_FUNC_CONST MAGICK_ATTRIBUTE((__const__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__pure__)) || \
+ ((__GNUC__) >= 3)) /* 2.96+ */
+# define MAGICK_FUNC_PURE MAGICK_ATTRIBUTE((__pure__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__unused__)) || \
+ (((__GNUC__) > 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))) /* 2.7+ */
+# define MAGICK_FUNC_UNUSED MAGICK_ATTRIBUTE((__unused__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__warn_unused_result__)) || \
+ (((__GNUC__) > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))) /* 3.3+ */
+# define MAGICK_FUNC_WARN_UNUSED_RESULT MAGICK_ATTRIBUTE((__warn_unused_result__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__noinline__)) || \
+ (((__GNUC__) > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))) /* 3.4+ */
+# define MAGICK_FUNC_NOINLINE MAGICK_ATTRIBUTE((__noinline__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__always_inline__)) || \
+ (((__GNUC__) > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))) /* 3.4+ */
+# define MAGICK_FUNC_ALWAYSINLINE MAGICK_ATTRIBUTE((__always_inline__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__alloc_size__)) || \
+ (((__GNUC__) > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))) /* 4.3+ */
+# define MAGICK_FUNC_ALLOC_SIZE_1ARG(arg_num) MAGICK_ATTRIBUTE((__alloc_size__(arg_num)))
+# define MAGICK_FUNC_ALLOC_SIZE_2ARG(arg_num1,arg_num2) MAGICK_ATTRIBUTE((__alloc_size__(arg_num1,arg_num2)))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__hot__)) || \
+ (((__GNUC__) > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))) /* 4.3+ */
+# define MAGICK_FUNC_HOT MAGICK_ATTRIBUTE((__hot__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__cold__)) || \
+ (((__GNUC__) > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))) /* 4.3+ */
+# define MAGICK_FUNC_COLD MAGICK_ATTRIBUTE((__cold__))
+# endif
+# if ((MAGICK_HAS_ATTRIBUTE(__optimize__)) || \
+ (((__GNUC__) > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))) /* 4.3+ */
+# define MAGICK_OPTIMIZE_FUNC(opt) MAGICK_ATTRIBUTE((__optimize__ (opt)))
+# endif
+ /*
+ https://code.google.com/p/address-sanitizer/wiki/AddressSanitizer#Introduction
+
+ To ignore certain functions, one can use the no_sanitize_address attribute
+ supported by Clang (3.3+) and GCC (4.8+).
+ */
+# if ((MAGICK_HAS_ATTRIBUTE(__no_sanitize_address__)) || \
+ (((__GNUC__) > 4) || ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 0)))) /* 4.8+ */
+# define MAGICK_NO_SANITIZE_ADDRESS MAGICK_ATTRIBUTE((__no_sanitize_address__))
+# endif
+# if ((MAGICK_CLANG_HAS_BUILTIN(__builtin_assume_aligned)) || \
+ (((__GNUC__) > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))) /* 4.7+ */
+# define MAGICK_ASSUME_ALIGNED(exp,align) __builtin_assume_aligned(exp,align)
+# endif
+# if ((MAGICK_CLANG_HAS_BUILTIN(__builtin_assume_aligned)) || \
+ (((__GNUC__) > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))) /* 4.7+ */
+# define MAGICK_ASSUME_ALIGNED_OFFSET(exp,align,offset) __builtin_assume_aligned(exp,align,offset)
+# endif
+# endif
+#endif
+#if !defined(MAGICK_FUNC_DEPRECATED)
+# define MAGICK_FUNC_DEPRECATED /*nothing*/
+#endif
+#if !defined(MAGICK_FUNC_MALLOC)
+# define MAGICK_FUNC_MALLOC /*nothing*/
+#endif
+#if !defined (MAGICK_FUNC_NONNULL)
+# define MAGICK_FUNC_NONNULL /*nothing*/
+#endif
+#if !defined (MAGICK_FUNC_NORETURN)
+# define MAGICK_FUNC_NORETURN /*nothing*/
+#endif
+#if !defined (MAGICK_FUNC_CONST)
+# define MAGICK_FUNC_CONST /*nothing*/
+#endif
+#if !defined (MAGICK_FUNC_PURE)
+# define MAGICK_FUNC_PURE /*nothing*/
+#endif
+#if !defined (MAGICK_FUNC_UNUSED)
+# define MAGICK_FUNC_UNUSED /*nothing*/
+#endif
+#if !defined(MAGICK_FUNC_WARN_UNUSED_RESULT)
+# define MAGICK_FUNC_WARN_UNUSED_RESULT /*nothing*/
+#endif
+#if !defined(MAGICK_FUNC_ALLOC_SIZE_1ARG)
+# define MAGICK_FUNC_ALLOC_SIZE_1ARG(arg_num) /*nothing*/
+#endif
+#if !defined(MAGICK_FUNC_ALLOC_SIZE_2ARG)
+# define MAGICK_FUNC_ALLOC_SIZE_2ARG(arg_num1,arg_num2) /*nothing*/
+#endif
+#if !defined(MAGICK_FUNC_HOT)
+# define MAGICK_FUNC_HOT /*nothing*/
+#endif
+#if !defined(MAGICK_FUNC_COLD)
+# define MAGICK_FUNC_COLD /*nothing*/
+#endif
+#if !defined(MAGICK_ASSUME_ALIGNED)
+# define MAGICK_ASSUME_ALIGNED(exp,align) (exp)
+#endif
+#if !defined(MAGICK_ASSUME_ALIGNED_OFFSET)
+# define MAGICK_ASSUME_ALIGNED_OFFSET(exp,align,offset) (exp)
+#endif
+#if !defined(MAGICK_OPTIMIZE_FUNC)
+# define MAGICK_OPTIMIZE_FUNC(opt) /*nothing*/
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_COMMON_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/compare.c b/magick/compare.c
new file mode 100644
index 0000000..a818f06
--- /dev/null
+++ b/magick/compare.c
@@ -0,0 +1,1029 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC OOO M M PPPP AAA RRRR EEEEE %
+% C O O MM MM P P A A R R E %
+% C O O M M M PPPP AAAAA RRRR EEE %
+% C O O M M P A A R R E %
+% CCCC OOO M M P A A R R EEEEE %
+% %
+% %
+% GraphicsMagick Image Compare Methods %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/compare.h"
+#include "magick/enum_strings.h"
+#include "magick/pixel_iterator.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D i f f e r e n c e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DifferenceImage() returns an annotated difference image based on the
+% the difference between a reference image and a compare image.
+%
+% The format of the DifferenceImage method is:
+%
+% Image *DifferenceImage(const Image *reference_image,
+% const Image *compare_image,
+% const DifferenceImageOptions *difference_options,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o reference_image: the reference image.
+%
+% o compare_image: the comparison image.
+%
+% o difference_options: options to use when differencing.
+%
+% o channel: the channel(s) to compare.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+static MagickPassFail
+DifferenceImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *reference_image, /* Source 1 image */
+ const PixelPacket *reference_pixels, /* Pixel row in source 1 image */
+ const IndexPacket *reference_indexes,/* Pixel row indexes in source 1 image */
+ const Image *compare_image, /* Source 2 image */
+ const PixelPacket *compare_pixels, /* Pixel row in source 2 image */
+ const IndexPacket *compare_indexes, /* Pixel row indexes in source 2 image */
+ Image *result_image, /* Update image */
+ PixelPacket *result_pixels, /* Pixel row in update image */
+ IndexPacket *result_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ const DifferenceImageOptions
+ *difference_options = (const DifferenceImageOptions *) immutable_data;
+
+ register ChannelType
+ channels = difference_options->channel;
+
+ register long
+ i;
+
+ register MagickBool
+ change;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(compare_image);
+ ARG_NOT_USED(result_image);
+ ARG_NOT_USED(result_indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ change=MagickFalse;
+
+ if (IsCMYKColorspace(reference_image->colorspace))
+ {
+ if (MagickChannelEnabled(channels,CyanChannel) &&
+ (GetCyanSample(&reference_pixels[i]) != GetCyanSample(&compare_pixels[i])))
+ change=MagickTrue;
+ if (MagickChannelEnabled(channels,MagentaChannel) &&
+ (GetMagentaSample(&reference_pixels[i]) != GetMagentaSample(&compare_pixels[i])))
+ change=MagickTrue;
+ if (MagickChannelEnabled(channels,YellowChannel) &&
+ (GetYellowSample(&reference_pixels[i]) != GetYellowSample(&compare_pixels[i])))
+ change=MagickTrue;
+ if (MagickChannelEnabled(channels,BlackChannel) &&
+ (GetBlackSample(&reference_pixels[i]) != GetBlackSample(&compare_pixels[i])))
+ change=MagickTrue;
+ if (MagickChannelEnabled(channels,OpacityChannel) &&
+ (reference_indexes[i] != compare_indexes[i]))
+ change=MagickTrue;
+ }
+ else
+ {
+ if (MagickChannelEnabled(channels,RedChannel) &&
+ (GetRedSample(&reference_pixels[i]) != GetRedSample(&compare_pixels[i])))
+ change=MagickTrue;
+ if (MagickChannelEnabled(channels,GreenChannel) &&
+ (GetGreenSample(&reference_pixels[i]) != GetGreenSample(&compare_pixels[i])))
+ change=MagickTrue;
+ if (MagickChannelEnabled(channels,BlueChannel) &&
+ (GetBlueSample(&reference_pixels[i]) != GetBlueSample(&compare_pixels[i])))
+ change=MagickTrue;
+ if (MagickChannelEnabled(channels,OpacityChannel) &&
+ (GetOpacitySample(&reference_pixels[i]) != GetOpacitySample(&compare_pixels[i])))
+ change=MagickTrue;
+ }
+ /*
+ Modify result image to reflect change.
+ */
+ switch (difference_options->highlight_style)
+ {
+ case UndefinedHighlightStyle:
+ break;
+ case AssignHighlightStyle:
+ {
+ /*
+ Changed pixels are assigned the highlight color.
+ */
+ if (change)
+ result_pixels[i]=difference_options->highlight_color;
+ else
+ result_pixels[i]=compare_pixels[i];
+ break;
+ }
+ case ThresholdHighlightStyle:
+ {
+ /*
+ For changed pixels, compare the pixel intensity. If the
+ pixel intensity in the compare image is higher than the
+ reference image, then set the pixel to white, otherwise
+ set it to black.
+ */
+ if (change)
+ {
+ Quantum
+ compare_intensity,
+ intensity,
+ reference_intensity;
+
+ compare_intensity=PixelIntensity(&compare_pixels[i]);
+ reference_intensity=PixelIntensity(&reference_pixels[i]);
+ if (compare_intensity > reference_intensity)
+ intensity=MaxRGB;
+ else
+ intensity=0U;
+ result_pixels[i].red = result_pixels[i].green = result_pixels[i].blue = intensity;
+ result_pixels[i].opacity=compare_pixels[i].opacity;
+ }
+ else
+ {
+ result_pixels[i]=compare_pixels[i];
+ }
+ break;
+ }
+ case TintHighlightStyle:
+ {
+ /*
+ Alpha composite highlight color on top of change pixels.
+ */
+ if (change)
+ AlphaCompositePixel(&result_pixels[i],&difference_options->highlight_color,0.75*MaxRGBDouble,
+ &compare_pixels[i],compare_pixels[i].opacity);
+ else
+ result_pixels[i]=compare_pixels[i];
+ break;
+ }
+ case XorHighlightStyle:
+ {
+ if (change)
+ {
+ result_pixels[i].red = compare_pixels[i].red ^ difference_options->highlight_color.red;
+ result_pixels[i].green = compare_pixels[i].green ^ difference_options->highlight_color.green;
+ result_pixels[i].blue = compare_pixels[i].blue ^ difference_options->highlight_color.blue;
+ result_pixels[i].opacity = compare_pixels[i].opacity ^ difference_options->highlight_color.opacity;
+ }
+ else
+ {
+ result_pixels[i]=compare_pixels[i];
+ }
+ break;
+ }
+ }
+ }
+
+ return MagickPass;
+}
+
+MagickExport Image *
+DifferenceImage(const Image *reference_image,const Image *compare_image,
+ const DifferenceImageOptions *difference_options,
+ ExceptionInfo *exception)
+{
+ Image
+ *difference_image;
+
+ assert(reference_image != (const Image *) NULL);
+ assert(reference_image->signature == MagickSignature);
+ assert(compare_image != (const Image *) NULL);
+ assert(compare_image->signature == MagickSignature);
+ assert(difference_options != (const DifferenceImageOptions *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ difference_image=AllocateImage((ImageInfo *) NULL);
+ if (difference_image == (Image *) NULL)
+ {
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToAllocateImage);
+ return ((Image *) NULL);
+ }
+ difference_image->storage_class = DirectClass;
+ difference_image->rows = reference_image->rows;
+ difference_image->columns = reference_image->columns;
+ difference_image->depth = Max(reference_image->depth, compare_image->depth);
+
+ /*
+ Update "difference" image to mark changes.
+ */
+ (void) PixelIterateTripleModify(DifferenceImagePixels,
+ NULL,
+ "[%s]*[%s]->[%s] Difference image pixels ...",
+ NULL,difference_options,
+ reference_image->columns,reference_image->rows,
+ reference_image, compare_image,0, 0,
+ difference_image, 0, 0,
+ exception);
+ return difference_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e C h a n n e l D i f f e r e n c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageChannelDifference() updates a user provided statistics structure
+% with per-channel, and totalized, difference statistics corresponding
+% to a specified comparison metric.
+%
+% The format of the GetImageChannelDifference method is:
+%
+% MagickPassFail GetImageChannelDifference(const Image *reference_image,
+% const Image *compare_image,
+% const MetricType metric,
+% DifferenceStatistics *statistics,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o reference_image: the reference image.
+%
+% o compare_image: the comparison image.
+%
+% o metric: metric to use when differencing.
+%
+% o statistics: the statistics structure to populate.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+/*
+ Compute the total absolute value difference.
+
+ In this case we sum the absolute value difference between channel
+ pixel quantums.
+*/
+static MagickPassFail
+ComputeAbsoluteError(void *mutable_data,
+ const void *immutable_data,
+ const Image *first_image,
+ const PixelPacket *first_pixels,
+ const IndexPacket *first_indexes,
+ const Image *second_image,
+ const PixelPacket *second_pixels,
+ const IndexPacket *second_indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ DifferenceStatistics
+ lstats,
+ *stats = (DifferenceStatistics *) mutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(first_image);
+ ARG_NOT_USED(first_indexes);
+ ARG_NOT_USED(second_image);
+ ARG_NOT_USED(second_indexes);
+ ARG_NOT_USED(exception);
+
+ InitializeDifferenceStatistics(&lstats,exception);
+ for (i=0; i < npixels; i++)
+ {
+ lstats.red += fabs(first_pixels[i].red-(double) second_pixels[i].red)/MaxRGBDouble;
+ lstats.green += fabs(first_pixels[i].green-(double) second_pixels[i].green)/MaxRGBDouble;
+ lstats.blue += fabs(first_pixels[i].blue-(double) second_pixels[i].blue)/MaxRGBDouble;
+ lstats.opacity += fabs(first_pixels[i].opacity-(double) second_pixels[i].opacity)/MaxRGBDouble;
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ComputeAbsoluteError)
+#endif
+ {
+ stats->red += lstats.red;
+ stats->green += lstats.green;
+ stats->blue += lstats.blue;
+ stats->opacity += lstats.opacity;
+ }
+
+ return (MagickPass);
+}
+
+/*
+ Compute the peak absolute difference.
+
+ In this case we compute the simple difference between channel pixel
+ quantums, obtain the absolute value, and store the value if it is
+ greater than the current peak value.
+*/
+static MagickPassFail
+ComputePeakAbsoluteError(void *mutable_data,
+ const void *immutable_data,
+ const Image *first_image,
+ const PixelPacket *first_pixels,
+ const IndexPacket *first_indexes,
+ const Image *second_image,
+ const PixelPacket *second_pixels,
+ const IndexPacket *second_indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ DifferenceStatistics
+ lstats,
+ *stats = (DifferenceStatistics *) mutable_data;
+
+ double
+ difference;
+
+ register long
+ i;
+
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(first_image);
+ ARG_NOT_USED(first_indexes);
+ ARG_NOT_USED(second_image);
+ ARG_NOT_USED(second_indexes);
+
+ InitializeDifferenceStatistics(&lstats,exception);
+ for (i=0; i < npixels; i++)
+ {
+ difference=fabs(first_pixels[i].red-(double) second_pixels[i].red)/MaxRGBDouble;
+ if (difference > lstats.red)
+ lstats.red=difference;
+
+ difference=fabs(first_pixels[i].green-(double) second_pixels[i].green)/MaxRGBDouble;
+ if (difference > lstats.green)
+ lstats.green=difference;
+
+ difference=fabs(first_pixels[i].blue-(double) second_pixels[i].blue)/MaxRGBDouble;
+ if (difference > lstats.blue)
+ lstats.blue=difference;
+
+ difference=fabs(first_pixels[i].opacity-(double) second_pixels[i].opacity)/MaxRGBDouble;
+ if (difference > lstats.opacity)
+ lstats.opacity=difference;
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ComputePeakAbsoluteError)
+#endif
+ {
+ if (lstats.red > stats->red)
+ stats->red=lstats.red;
+ if (lstats.green > stats->green)
+ stats->green=lstats.green;
+ if (lstats.blue > stats->blue)
+ stats->blue=lstats.blue;
+ if (lstats.opacity > stats->opacity)
+ stats->opacity=lstats.opacity;
+ }
+
+ return (MagickPass);
+}
+
+/*
+ Compute the squared difference.
+
+ In this case we sum the square of the difference between channel
+ pixel quantums.
+*/
+static MagickPassFail
+ComputeSquaredError(void *mutable_data,
+ const void *immutable_data,
+ const Image *first_image,
+ const PixelPacket *first_pixels,
+ const IndexPacket *first_indexes,
+ const Image *second_image,
+ const PixelPacket *second_pixels,
+ const IndexPacket *second_indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ DifferenceStatistics
+ lstats,
+ *stats = (DifferenceStatistics *) mutable_data;
+
+ double
+ difference;
+
+ register long
+ i;
+
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(first_image);
+ ARG_NOT_USED(first_indexes);
+ ARG_NOT_USED(second_image);
+ ARG_NOT_USED(second_indexes);
+ ARG_NOT_USED(exception);
+
+ InitializeDifferenceStatistics(&lstats,exception);
+ for (i=0; i < npixels; i++)
+ {
+ difference=(first_pixels[i].red-(double) second_pixels[i].red)/MaxRGBDouble;
+ lstats.red += difference*difference;
+
+ difference=(first_pixels[i].green-(double) second_pixels[i].green)/MaxRGBDouble;
+ lstats.green += difference*difference;
+
+ difference=(first_pixels[i].blue-(double) second_pixels[i].blue)/MaxRGBDouble;
+ lstats.blue += difference*difference;
+
+ difference=(first_pixels[i].opacity-(double) second_pixels[i].opacity)/MaxRGBDouble;
+ lstats.opacity += difference*difference;
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ComputeSquaredError)
+#endif
+ {
+ stats->red += lstats.red;
+ stats->green += lstats.green;
+ stats->blue += lstats.blue;
+ stats->opacity += lstats.opacity;
+ }
+
+ return (MagickPass);
+}
+MagickExport MagickPassFail
+GetImageChannelDifference(const Image *reference_image,
+ const Image *compare_image,
+ const MetricType metric,
+ DifferenceStatistics *statistics,
+ ExceptionInfo *exception)
+{
+ PixelIteratorDualReadCallback
+ call_back = (PixelIteratorDualReadCallback) NULL;
+
+ MagickPassFail
+ status = MagickFail;
+
+ assert(reference_image != (const Image *) NULL);
+ assert(reference_image->signature == MagickSignature);
+ assert(compare_image != (const Image *) NULL);
+ assert(compare_image->signature == MagickSignature);
+ assert(statistics != (DifferenceStatistics *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ InitializeDifferenceStatistics(statistics,exception);
+
+ /*
+ Select basic differencing function to use.
+ */
+ switch (metric)
+ {
+ case UndefinedMetric:
+ break;
+ case MeanAbsoluteErrorMetric:
+ call_back=ComputeAbsoluteError;
+ break;
+ case MeanSquaredErrorMetric:
+ call_back=ComputeSquaredError;
+ break;
+ case PeakAbsoluteErrorMetric:
+ call_back=ComputePeakAbsoluteError;
+ break;
+ case PeakSignalToNoiseRatioMetric:
+ call_back=ComputeSquaredError;
+ break;
+ case RootMeanSquaredErrorMetric:
+ call_back=ComputeSquaredError;
+ break;
+ }
+
+ if (call_back != (PixelIteratorDualReadCallback) NULL)
+ {
+ double
+ number_channels,
+ number_pixels;
+
+ char
+ description[MaxTextExtent];
+
+ FormatString(description,"[%%s]*[%%s] Compute image difference using %s metric...",
+ MetricTypeToString(metric));
+
+ status=PixelIterateDualRead(call_back,
+ NULL,
+ description,
+ statistics, NULL,
+ reference_image->columns,reference_image->rows,
+ reference_image,0,0,
+ compare_image,0,0,
+ exception);
+ /*
+ Post-process statistics (as required)
+ */
+
+ number_channels=3.0 + (reference_image->matte ? 1.0 : 0.0);
+ number_pixels=(double) reference_image->columns*reference_image->rows;
+
+ if ((MeanAbsoluteErrorMetric == metric) ||
+ (MeanSquaredErrorMetric == metric) ||
+ (PeakSignalToNoiseRatioMetric == metric)||
+ (RootMeanSquaredErrorMetric == metric))
+ {
+ /*
+ Compute mean values.
+ */
+ statistics->combined=((statistics->red+statistics->green+
+ statistics->blue+
+ (reference_image->matte ? statistics->opacity : 0.0))/
+ (number_pixels*number_channels));
+ statistics->red /= number_pixels;
+ statistics->green /= number_pixels;
+ statistics->blue /= number_pixels;
+ statistics->opacity /= number_pixels;
+ }
+
+ if (PeakAbsoluteErrorMetric == metric)
+ {
+ /*
+ Determine peak channel value
+ */
+ if (statistics->red > statistics->combined)
+ statistics->combined=statistics->red;
+
+ if (statistics->green > statistics->combined)
+ statistics->combined=statistics->green;
+
+ if (statistics->blue > statistics->combined)
+ statistics->combined=statistics->blue;
+
+ if ((reference_image->matte) && (statistics->opacity > statistics->combined))
+ statistics->combined=statistics->opacity;
+ }
+
+ if (PeakSignalToNoiseRatioMetric == metric)
+ {
+ /*
+ Compute PSNR.
+ */
+ statistics->red=(20.0 * log10(1.0/sqrt(statistics->red)));
+ statistics->green=(20.0 * log10(1.0/sqrt(statistics->green)));
+ statistics->blue=(20.0 * log10(1.0/sqrt(statistics->blue)));
+ statistics->opacity=(20.0 * log10(1.0/sqrt(statistics->opacity)));
+ statistics->combined=(20.0 * log10(1.0/sqrt(statistics->combined)));
+ }
+
+ if (RootMeanSquaredErrorMetric == metric)
+ {
+ /*
+ Compute RMSE.
+ */
+ statistics->red=sqrt(statistics->red);
+ statistics->green=sqrt(statistics->green);
+ statistics->blue=sqrt(statistics->blue);
+ statistics->opacity=sqrt(statistics->opacity);
+ statistics->combined=sqrt(statistics->combined);
+ }
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e C h a n n e l D i s t o r t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageChannelDistortion() updates a distortion parameter with the
+% distortion (error) computed according to the specified comparison metric.
+% The value returned is only for the channel specified.
+%
+% The format of the GetImageChannelDistortion method is:
+%
+% MagickPassFail GetImageChannelDistortion(const Image *reference_image,
+% const Image *compare_image,
+% const ChannelType channel,
+% const MetricType metric,
+% double *distortion,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o reference_image: the reference image.
+%
+% o compare_image: the comparison image.
+%
+% o channel: the channel to obtain error data for.
+%
+% o metric: metric to use when differencing.
+%
+% o distortion: updated with the computed distortion.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickPassFail
+GetImageChannelDistortion(const Image *reference_image,
+ const Image *compare_image,
+ const ChannelType channel,
+ const MetricType metric,
+ double *distortion,
+ ExceptionInfo *exception)
+{
+ DifferenceStatistics
+ statistics;
+
+ MagickPassFail
+ status;
+
+ assert(distortion != (double *) NULL);
+
+ *distortion=1.0;
+ status=GetImageChannelDifference(reference_image,compare_image,metric,
+ &statistics,exception);
+ switch (channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ *distortion=statistics.red;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ *distortion=statistics.green;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ *distortion=statistics.blue;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ *distortion=statistics.opacity;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ case GrayChannel:
+ *distortion=statistics.combined;
+ break;
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e D i s t o r t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageDistortion() updates a distortion parameter with the distortion
+% (error) computed according to the specified comparison metric. The value
+% returned reflects all enabled channels.
+%
+% The format of the GetImageDistortion method is:
+%
+% MagickPassFail GetImageDistortion(const Image *reference_image,
+% const Image *compare_image,
+% const MetricType metric,
+% double *distortion,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o reference_image: the reference image.
+%
+% o compare_image: the comparison image.
+%
+% o channel: the channel to obtain error data for.
+%
+% o metric: metric to use when differencing.
+%
+% o distortion: updated with the computed distortion.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickPassFail
+GetImageDistortion(const Image *reference_image,
+ const Image *compare_image,
+ const MetricType metric,
+ double *distortion,
+ ExceptionInfo *exception)
+{
+ return GetImageChannelDistortion(reference_image,compare_image,AllChannels,
+ metric,distortion,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s I m a g e s E q u a l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsImagesEqual() measures the difference between colors at each pixel
+% location of two images. A value other than 0 means the colors match
+% exactly. Otherwise an error measure is computed by summing over all
+% pixels in an image the distance squared in RGB space between each image
+% pixel and its corresponding pixel in the reference image. The error
+% measure is assigned to these image members:
+%
+% o mean_error_per_pixel: The mean error for any single pixel in
+% the image.
+%
+% o normalized_mean_error: The normalized mean quantization error for
+% any single pixel in the image. This distance measure is normalized to
+% a range between 0 and 1. It is independent of the range of red, green,
+% and blue values in the image.
+%
+% o normalized_maximum_error: The normalized maximum quantization
+% error for any single pixel in the image. This distance measure is
+% normalized to a range between 0 and 1. It is independent of the range
+% of red, green, and blue values in your image.
+%
+% A small normalized mean square error, accessed as
+% image->normalized_mean_error, suggests the images are very similiar in
+% spatial layout and color.
+%
+% The format of the IsImagesEqual method is:
+%
+% MagickBool IsImagesEqual(Image *image,const Image *reference)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o reference: The reference image.
+%
+*/
+typedef struct _ErrorStatistics {
+ double
+ maximum,
+ total;
+} ErrorStatistics;
+
+static MagickPassFail
+ComputePixelError(void *mutable_data,
+ const void *immutable_data,
+ const Image *first_image,
+ const PixelPacket *first_pixels,
+ const IndexPacket *first_indexes,
+ const Image *second_image,
+ const PixelPacket *second_pixels,
+ const IndexPacket *second_indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ ErrorStatistics
+ *stats = (ErrorStatistics *) mutable_data;
+
+ double
+ difference,
+ distance,
+ distance_squared,
+ stats_maximum,
+ stats_total;
+
+ register long
+ i;
+
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(first_indexes);
+ ARG_NOT_USED(second_image);
+ ARG_NOT_USED(second_indexes);
+ ARG_NOT_USED(exception);
+
+ stats_maximum=0.0;
+ stats_total=0.0;
+
+ for (i=0; i < npixels; i++)
+ {
+ difference=(first_pixels[i].red-(double) second_pixels[i].red)/MaxRGBDouble;
+ distance_squared=(difference*difference);
+
+ difference=(first_pixels[i].green-(double) second_pixels[i].green)/MaxRGBDouble;
+ distance_squared+=(difference*difference);
+
+ difference=(first_pixels[i].blue-(double) second_pixels[i].blue)/MaxRGBDouble;
+ distance_squared+=(difference*difference);
+
+ if (first_image->matte)
+ {
+ difference=(first_pixels[i].opacity-(double) second_pixels[i].opacity)/MaxRGBDouble;
+ distance_squared+=(difference*difference);
+ }
+ distance=sqrt(distance_squared);
+
+ stats_total+=distance;
+ if (distance > stats_maximum)
+ stats_maximum=distance;
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ComputePixelError)
+#endif
+ {
+ stats->total+=stats_total;
+
+ if (stats_maximum > stats->maximum)
+ stats->maximum=stats_maximum;
+ }
+ return (MagickPass);
+}
+
+MagickExport MagickBool
+IsImagesEqual(Image *image,const Image *reference)
+{
+ ErrorStatistics
+ stats;
+
+ double
+ mean_error_per_pixel,
+ normalize,
+ number_pixels;
+
+ /*
+ Initialize measurement.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(reference != (const Image *) NULL);
+ assert(reference->signature == MagickSignature);
+ (void) memset(&image->error,0,sizeof(ErrorInfo));
+ if ((image->rows != reference->rows) ||
+ (image->columns != reference->columns))
+ ThrowBinaryException3(ImageError,UnableToCompareImages,
+ ImageSizeDiffers);
+ if ((image->colorspace != reference->colorspace) &&
+ (!IsRGBColorspace(image->colorspace) || !IsRGBColorspace(reference->colorspace)))
+ ThrowBinaryException3(ImageError,UnableToCompareImages,
+ ImageColorspaceDiffers);
+ if(image->matte != reference->matte)
+ ThrowBinaryException3(ImageError,UnableToCompareImages,
+ ImageOpacityDiffers);
+
+ /*
+ For each pixel, collect error statistics.
+ */
+ number_pixels=(double) image->columns*image->rows;
+
+ stats.maximum=0.0;
+ stats.total=0.0;
+
+ (void) PixelIterateDualRead(ComputePixelError,
+ NULL,
+ "[%s]*[%s] Compute pixel error ...",
+ &stats, NULL,
+ image->columns,image->rows,
+ image,0,0,
+ reference,0,0,
+ &image->exception);
+
+ /*
+ Compute final error statistics.
+ */
+
+ if (image->matte)
+ normalize = sqrt(4.0); /* sqrt(1.0*1.0+1.0*1.0+1.0*1.0+1.0*1.0) */
+ else
+ normalize = sqrt(3.0); /* sqrt(1.0*1.0+1.0*1.0+1.0*1.0) */
+ mean_error_per_pixel=stats.total/number_pixels;
+ image->error.mean_error_per_pixel=mean_error_per_pixel*MaxRGBDouble;
+ image->error.normalized_mean_error=mean_error_per_pixel/normalize;
+ image->error.normalized_maximum_error=stats.maximum/normalize;
+ return(image->error.normalized_mean_error == 0.0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n i t i a l i z e D i f f e r e n c e I m a g e O p t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializeDifferenceImageOptions() assigns default options to a user-provided
+% DifferenceImageOptions structure. This function should always be used
+% to initialize the DifferenceImageOptions structure prior to making any
+% changes to it.
+%
+% The format of the InitializeDifferenceImageOptions method is:
+%
+% void InitializeDifferenceImageOptions(DifferenceImageOptions *options,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o options: pointer to DifferenceImageOptions structure to initialize.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport void
+InitializeDifferenceImageOptions(DifferenceImageOptions *options,
+ ExceptionInfo *exception)
+{
+ assert(options != (DifferenceImageOptions *) NULL);
+ memset(options,0,sizeof(DifferenceImageOptions));
+ options->channel=AllChannels;
+ options->highlight_style=TintHighlightStyle;
+ (void) QueryColorDatabase(HighlightColor,&options->highlight_color,exception);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n i t i a l i z e D i f f e r e n c e S t a t i s t i c s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializeDifferenceStatistics() assigns default options to a user-provided
+% DifferenceStatistics structure.
+%
+% The format of the InitializeDifferenceStatistics method is:
+%
+% void InitializeDifferenceStatistics(DifferenceStatistics *options,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o options: pointer to DifferenceStatistics structure to initialize.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport void
+InitializeDifferenceStatistics(DifferenceStatistics *statistics,
+ ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+ assert(statistics != (DifferenceStatistics *) NULL);
+ statistics->red=0.0;
+ statistics->green=0.0;
+ statistics->blue=0.0;
+ statistics->opacity=0.0;
+ statistics->combined=0.0;
+}
diff --git a/magick/compare.h b/magick/compare.h
new file mode 100644
index 0000000..31c29b7
--- /dev/null
+++ b/magick/compare.h
@@ -0,0 +1,108 @@
+/*
+ Copyright (C) 2008 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Image Comparison Methods.
+*/
+#ifndef _MAGICK_COMPARE_H
+#define _MAGICK_COMPARE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+/*
+ Pixel differencing algorithms.
+*/
+typedef enum
+{
+ UndefinedHighlightStyle,
+ AssignHighlightStyle,
+ ThresholdHighlightStyle,
+ TintHighlightStyle,
+ XorHighlightStyle
+} HighlightStyle;
+
+typedef struct _DifferenceImageOptions
+{
+ ChannelType channel; /* Channel(s) to difference */
+ HighlightStyle highlight_style; /* Pixel annotation style */
+ PixelPacket highlight_color; /* Changed pixel highlight color */
+} DifferenceImageOptions;
+
+extern MagickExport void
+ InitializeDifferenceImageOptions(DifferenceImageOptions *options,
+ ExceptionInfo *exception);
+
+extern MagickExport Image
+ *DifferenceImage(const Image *reference_image,const Image *compare_image,
+ const DifferenceImageOptions *difference_options,
+ ExceptionInfo *exception);
+
+/*
+ Pixel error metrics.
+*/
+typedef enum
+{
+ UndefinedMetric,
+ MeanAbsoluteErrorMetric,
+ MeanSquaredErrorMetric,
+ PeakAbsoluteErrorMetric,
+ PeakSignalToNoiseRatioMetric,
+ RootMeanSquaredErrorMetric
+} MetricType;
+
+/*
+ Pixel difference statistics.
+*/
+typedef struct _DifferenceStatistics
+{
+ double
+ red,
+ green,
+ blue,
+ opacity,
+ combined;
+} DifferenceStatistics;
+
+extern MagickExport void
+ InitializeDifferenceStatistics(DifferenceStatistics *difference_statistics,
+ ExceptionInfo *exception);
+
+extern MagickExport MagickPassFail
+ GetImageChannelDifference(const Image *reference_image,
+ const Image *compare_image,
+ const MetricType metric,
+ DifferenceStatistics *statistics,
+ ExceptionInfo *exception),
+ GetImageChannelDistortion(const Image *reference_image,
+ const Image *compare_image,
+ const ChannelType channel,
+ const MetricType metric,
+ double *distortion,
+ ExceptionInfo *exception),
+ GetImageDistortion(const Image *reference_image,
+ const Image *compare_image,
+ const MetricType metric,
+ double *distortion,
+ ExceptionInfo *exception);
+
+extern MagickExport MagickBool
+ IsImagesEqual(Image *,const Image *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_COMPARE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/composite.c b/magick/composite.c
new file mode 100644
index 0000000..a35ccf2
--- /dev/null
+++ b/magick/composite.c
@@ -0,0 +1,3805 @@
+/*
+% Copyright (C) 2003 - 2014 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC OOO M M PPPP OOO SSSSS IIIII TTTTT EEEEE %
+% C O O MM MM P P O O SS I T E %
+% C O O M M M PPPP O O SSS I T EEE %
+% C O O M M P O O SS I T E %
+% CCCC OOO M M P OOO SSSSS IIIII T EEEEE %
+% %
+% %
+% GraphicsMagick Image Composition Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% Re-design/Re-write %
+% Bob Friesenhahn %
+% 2008 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/composite.h"
+#include "magick/enum_strings.h"
+#include "magick/gem.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/utility.h"
+
+
+/*
+ Structure to pass any necessary options to composition callbacks.
+*/
+#if 0
+typedef struct _CompositeOptions_t
+{
+ /* Composition operator */
+ /* CompositeOperator compose; */
+
+ /* ModulateComposite */
+ double percent_brightness;
+
+ /* ThresholdComposite */
+ double amount;
+ double threshold;
+} CompositeOptions_t;
+#endif
+
+
+/*
+ Build a PixelPacket representing the canvas pixel.
+*/
+static inline void
+PrepareDestinationPacket(PixelPacket *destination,
+ const PixelPacket *update_pixels,
+ const Image *update_image,
+ const IndexPacket *update_indexes,
+ const long i)
+{
+ *destination=update_pixels[i];
+ if (!update_image->matte)
+ destination->opacity=OpaqueOpacity;
+ else
+ if (update_image->colorspace == CMYKColorspace)
+ destination->opacity=update_indexes[i];
+}
+
+
+/*
+ Build a PixelPacket representing the update pixel.
+*/
+static inline void
+PrepareSourcePacket(PixelPacket *source,
+ const PixelPacket *source_pixels,
+ const Image *source_image,
+ const IndexPacket *source_indexes,
+ const long i)
+{
+ *source=source_pixels[i];
+ if (!source_image->matte)
+ source->opacity=OpaqueOpacity;
+ else
+ if (source_image->colorspace == CMYKColorspace)
+ source->opacity=source_indexes[i];
+}
+
+
+/*
+ Apply composition updates to the canvas image.
+*/
+static inline void
+ApplyPacketUpdates(PixelPacket *update_pixels,
+ IndexPacket *update_indexes,
+ const Image *update_image,
+ const PixelPacket *composite,
+ const long i
+ )
+{
+ if (update_image->colorspace != CMYKColorspace)
+ {
+ /*
+ RGB stores opacity in 'opacity'.
+ */
+ update_pixels[i]=*composite;
+ }
+ else
+ {
+ /*
+ CMYK(A) stores K in 'opacity' and A in the indexes.
+ */
+ update_pixels[i].red=composite->red;
+ update_pixels[i].green=composite->green;
+ update_pixels[i].blue=composite->blue;
+ update_indexes[i]=composite->opacity; /* opacity */
+ }
+}
+
+
+static MagickPassFail
+OverCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result will be the union of the two image shapes, with
+ opaque areas of change-image obscuring base-image in the
+ region of overlap.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ AlphaCompositePixel(&destination,&source,source.opacity,&destination,destination.opacity);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+InCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result is simply change-image cut by the shape of
+ base-image. None of the image data of base-image will be
+ in the result.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ if (source.opacity == TransparentOpacity)
+ {
+ destination=source;
+ }
+ else if (destination.opacity == TransparentOpacity)
+ {
+ }
+ else
+ {
+ double
+ opacity;
+
+ opacity=(double)
+ (((double) MaxRGBDouble-source.opacity)*
+ (MaxRGBDouble-destination.opacity)/MaxRGBDouble);
+
+ destination.red=(Quantum)
+ (((double) MaxRGBDouble-source.opacity)*
+ (MaxRGBDouble-destination.opacity)*source.red/MaxRGBDouble/opacity+0.5);
+
+ destination.green=(Quantum)
+ (((double) MaxRGBDouble-source.opacity)*
+ (MaxRGBDouble-destination.opacity)*source.green/MaxRGBDouble/opacity+0.5);
+
+ destination.blue=(Quantum)
+ (((double) MaxRGBDouble-source.opacity)*
+ (MaxRGBDouble-destination.opacity)*source.blue/MaxRGBDouble/opacity+0.5);
+
+ destination.opacity=(Quantum) (MaxRGBDouble-opacity+0.5);
+ }
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+OutCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The resulting image is change-image with the shape of
+ base-image cut out.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ if (source.opacity == TransparentOpacity)
+ {
+ destination=source;
+ }
+ else if (destination.opacity == OpaqueOpacity)
+ {
+ destination.opacity=TransparentOpacity;
+ }
+ else
+ {
+ double
+ opacity;
+
+ opacity=(double)
+ (MaxRGBDouble-source.opacity)*destination.opacity/MaxRGBDouble;
+
+ destination.red=(Quantum)
+ (((double) MaxRGBDouble-source.opacity)*
+ destination.opacity*source.red/MaxRGBDouble/opacity+0.5);
+
+ destination.green=(Quantum)
+ (((double) MaxRGBDouble-source.opacity)*
+ destination.opacity*source.green/MaxRGBDouble/opacity+0.5);
+
+ destination.blue=(Quantum)
+ (((double) MaxRGBDouble-source.opacity)*
+ destination.opacity*source.blue/MaxRGBDouble/opacity+0.5);
+
+ destination.opacity=(Quantum) (MaxRGBDouble-opacity+0.5);
+ }
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+AtopCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result is the same shape as base-image, with
+ change-image obscuring base-image where the image shapes
+ overlap. Note this differs from over because the portion
+ of change-image outside base-image's shape does not appear
+ in the result.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ AtopCompositePixel(&destination,&destination,&source);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+XorCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result is the image data from both change-image and
+ base-image that is outside the overlap region. The overlap
+ region will be blank.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ 2.0*(1.0-source_alpha)*(1.0-dest_alpha);
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(gamma <= MagickEpsilon ? 1.0 : gamma);
+
+ composite=((1.0-source_alpha)*source.red*dest_alpha+
+ (1.0-dest_alpha)*destination.red*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ composite=((1.0-source_alpha)*source.green*dest_alpha+
+ (1.0-dest_alpha)*destination.green*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ composite=((1.0-source_alpha)*source.blue*dest_alpha+
+ (1.0-dest_alpha)*destination.blue*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+PlusCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result is just the sum of the image data. Output values are
+ cropped to MaxRGB (no overflow). This operation is independent of
+ the matte channels.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ value=((double) (MaxRGBDouble-source.opacity)*source.red+(double)
+ (MaxRGBDouble-destination.opacity)*destination.red)/MaxRGBDouble;
+ destination.red=RoundDoubleToQuantum(value);
+
+ value=((double) (MaxRGBDouble-source.opacity)*source.green+(double)
+ (MaxRGBDouble-destination.opacity)*destination.green)/MaxRGBDouble;
+ destination.green=RoundDoubleToQuantum(value);
+
+ value=((double) (MaxRGBDouble-source.opacity)*source.blue+(double)
+ (MaxRGBDouble-destination.opacity)*destination.blue)/MaxRGBDouble;
+ destination.blue=RoundDoubleToQuantum(value);
+
+ value=((double) (MaxRGBDouble-source.opacity)+
+ (double) (MaxRGBDouble-destination.opacity))/MaxRGBDouble;
+ destination.opacity=MaxRGB-RoundDoubleToQuantum(value);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+MinusCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result of change-image - base-image, with underflow cropped to
+ zero. The matte channel is ignored (set to opaque, full coverage).
+ */
+ for (i=0; i < npixels; i++)
+ {
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ value=((double) (MaxRGBDouble-destination.opacity)*destination.red-
+ (double) (MaxRGBDouble-source.opacity)*source.red)/MaxRGBDouble;
+ destination.red=RoundDoubleToQuantum(value);
+
+ value=((double) (MaxRGBDouble-destination.opacity)*destination.green-
+ (double) (MaxRGBDouble-source.opacity)*source.green)/MaxRGBDouble;
+ destination.green=RoundDoubleToQuantum(value);
+
+ value=((double) (MaxRGBDouble-destination.opacity)*destination.blue-
+ (double) (MaxRGBDouble-source.opacity)*source.blue)/MaxRGBDouble;
+ destination.blue=RoundDoubleToQuantum(value);
+
+ value=((double) (MaxRGBDouble-destination.opacity)-
+ (double) (MaxRGBDouble-source.opacity))/MaxRGBDouble;
+ destination.opacity=MaxRGB-RoundDoubleToQuantum(value);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+AddCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result of change-image + base-image, with overflow wrapping
+ around (mod MaxRGB+1).
+ */
+ for (i=0; i < npixels; i++)
+ {
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ value=(double) source.red+destination.red;
+ if (value > MaxRGBDouble) value -= ((double) MaxRGBDouble+1.0);
+ destination.red=RoundDoubleToQuantum(value);
+
+ value=(double) source.green+destination.green;
+ if (value > MaxRGBDouble) value -= ((double) MaxRGBDouble+1.0);
+ destination.green=RoundDoubleToQuantum(value);
+
+ value=(double) source.blue+destination.blue;
+ if (value > MaxRGBDouble) value -= ((double) MaxRGBDouble+1.0);
+ destination.blue=RoundDoubleToQuantum(value);
+
+ destination.opacity=OpaqueOpacity;
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+SubtractCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result of change-image - base-image, with underflow wrapping
+ around (mod MaxRGB+1). The add and subtract operators can be used
+ to perform reversible transformations.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ value=(double) source.red-destination.red;
+ if (value < 0) value += ((double) MaxRGBDouble+1.0);
+ destination.red=RoundDoubleToQuantum(value);
+
+ value=(double) source.green-destination.green;
+ if (value < 0) value += ((double) MaxRGBDouble+1.0);
+ destination.green=RoundDoubleToQuantum(value);
+
+ value=(double) source.blue-destination.blue;
+ if (value < 0) value += ((double) MaxRGBDouble+1.0);
+ destination.blue=RoundDoubleToQuantum(value);
+
+ destination.opacity=OpaqueOpacity;
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+DifferenceCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result of abs(change-image - base-image). This is useful for
+ comparing two very similar images.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ composite=(fabs((double)source.red - (double)destination.red)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ composite=(fabs((double)source.green - (double)destination.green)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ composite=(fabs((double)source.blue - (double)destination.blue)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+MultiplyCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result of change-image * base-image. This is useful for the
+ creation of drop-shadows.
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ composite=(((double)source.red*(1.0-source_alpha)*
+ (double)destination.red*(1.0-dest_alpha))/MaxRGBDouble+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ composite=(((double)source.green*(1.0-source_alpha)*
+ (double)destination.green*(1.0-dest_alpha))/MaxRGBDouble+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ composite=(((double)source.blue*(1.0-source_alpha)*
+ (double)destination.blue*(1.0-dest_alpha))/MaxRGBDouble+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+BumpmapCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result base-image shaded by change-image.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ double value;
+ double source_intensity;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_intensity=(double) PixelIntensity(&source)/MaxRGBDouble;
+
+ value=source_intensity*destination.red;
+ destination.red=RoundDoubleToQuantum(value);
+
+ value=source_intensity*destination.green;
+ destination.green=RoundDoubleToQuantum(value);
+
+ value=source_intensity*destination.blue;
+ destination.blue=RoundDoubleToQuantum(value);
+
+ value=source_intensity*destination.opacity;
+ destination.opacity=RoundDoubleToQuantum(value);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+
+
+static MagickPassFail
+CopyCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The resulting image is base-image replaced with change-image. Here
+ the matte information is ignored.
+ */
+ if ((update_image->colorspace == CMYKColorspace) &&
+ (update_image->matte))
+ {
+ if (source_image->matte)
+ {
+ (void) memcpy(update_pixels,source_pixels,npixels*sizeof(PixelPacket));
+ (void) memcpy(update_indexes,source_indexes,npixels*sizeof(IndexPacket));
+ }
+ else
+ {
+ (void) memcpy(update_pixels,source_pixels,npixels*sizeof(PixelPacket));
+ (void) memset(update_indexes,OpaqueOpacity,npixels*sizeof(IndexPacket));
+ }
+ }
+ else
+ {
+ (void) memcpy(update_pixels,source_pixels,npixels*sizeof(PixelPacket));
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+CopyRedCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(source_image);
+ ARG_NOT_USED(source_indexes);
+ ARG_NOT_USED(update_image);
+ ARG_NOT_USED(update_indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ The resulting image is the red channel in base-image replaced with
+ the red channel in change-image. The other channels are copied
+ untouched.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].red = source_pixels[i].red;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+CopyGreenCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(source_image);
+ ARG_NOT_USED(source_indexes);
+ ARG_NOT_USED(update_image);
+ ARG_NOT_USED(update_indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ The resulting image is the green channel in base-image replaced
+ with the green channel in change-image. The other channels are
+ copied untouched.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].green = source_pixels[i].green;
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+CopyBlueCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(source_image);
+ ARG_NOT_USED(source_indexes);
+ ARG_NOT_USED(update_image);
+ ARG_NOT_USED(update_indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ The resulting image is the blue channel in base-image replaced
+ with the blue channel in change-image. The other channels are
+ copied untouched.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].blue = source_pixels[i].blue;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+CopyOpacityCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The resulting image is the opacity channel in base-image replaced
+ with the opacity channel in change-image. The other channels are
+ copied untouched.
+ */
+ if (update_image->colorspace == CMYKColorspace)
+ {
+ if (!source_image->matte)
+ {
+ for (i=0; i < npixels; i++)
+ {
+ update_indexes[i] =
+ (Quantum) (MaxRGB-PixelIntensityToQuantum(&source_pixels[i]));
+ }
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ {
+ update_indexes[i] = source_indexes[i];
+ }
+ }
+ }
+ else
+ {
+ if (!source_image->matte)
+ {
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].opacity =
+ (Quantum) (MaxRGB-PixelIntensityToQuantum(&source_pixels[i]));
+ }
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].opacity = source_pixels[i].opacity;
+ }
+ }
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ClearCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(source_image);
+ ARG_NOT_USED(source_pixels);
+ ARG_NOT_USED(source_indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ Set destination pixels to transparent.
+ */
+ if (update_image->colorspace == CMYKColorspace)
+ {
+ update_image->matte=MagickTrue;
+ for (i=0; i < npixels; i++)
+ {
+ update_indexes[i] = TransparentOpacity;
+ }
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].opacity = TransparentOpacity;
+ }
+ }
+
+ return MagickPass;
+}
+
+
+
+static MagickPassFail
+DissolveCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ destination.red=(Quantum)
+ (((double) source.opacity*source.red+
+ (MaxRGBDouble-source.opacity)*destination.red)/MaxRGBDouble+0.5);
+ destination.green=(Quantum)
+ (((double) source.opacity*source.green+
+ (MaxRGBDouble-source.opacity)*destination.green)/MaxRGBDouble+0.5);
+ destination.blue=(Quantum)
+ (((double) source.opacity*source.blue+
+ (MaxRGBDouble-source.opacity)*destination.blue)/MaxRGBDouble+0.5);
+ destination.opacity=OpaqueOpacity;
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+ModulateCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ const CompositeOptions_t
+ *options = (const CompositeOptions_t *) immutable_data;
+
+ const double
+ percent_brightness = options->percent_brightness;
+
+
+ double
+ midpoint;
+
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(exception);
+
+ midpoint=((double) MaxRGB+1.0)/2;
+ for (i=0; i < npixels; i++)
+ {
+ double
+ offset;
+
+ double
+ brightness,
+ hue,
+ saturation;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ offset=(long) (PixelIntensityToQuantum(&source)-midpoint);
+ if (offset == 0)
+ break;
+ TransformHSL(destination.red,destination.green,destination.blue,
+ &hue,&saturation,&brightness);
+ brightness+=(percent_brightness*offset)/midpoint;
+ if (brightness < 0.0)
+ brightness=0.0;
+ else
+ if (brightness > 1.0)
+ brightness=1.0;
+ HSLTransform(hue,saturation,brightness,&destination.red,
+ &destination.green,&destination.blue);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+ThresholdCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ const CompositeOptions_t
+ *options = (const CompositeOptions_t *) immutable_data;
+
+ const double
+ amount = options->amount,
+ threshold = options->threshold;
+
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ value=destination.red-(double) source.red;
+ if (fabs(2.0*value) < threshold)
+ value=destination.red;
+ else
+ value=destination.red+(value*amount);
+ destination.red=RoundDoubleToQuantum(value);
+
+ value=destination.green-(double) source.green;
+ if (fabs(2.0*value) < threshold)
+ value=destination.green;
+ else
+ value=destination.green+(value*amount);
+ destination.green=RoundDoubleToQuantum(value);
+
+ value=destination.blue-(double) source.blue;
+ if (fabs(2.0*value) < threshold)
+ value=destination.blue;
+ else
+ value=destination.blue+(value*amount);
+ destination.blue=RoundDoubleToQuantum(value);
+
+ value=destination.opacity-(double) source.opacity;
+ if (fabs(2.0*value) < threshold)
+ value=destination.opacity;
+ else
+ value=destination.opacity+(value*amount);
+ destination.opacity=RoundDoubleToQuantum(value);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+DarkenCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ composite=(MagickFmin((double)source.red,(double)destination.red)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ composite=(MagickFmin((double)source.green,(double)destination.green)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ composite=(MagickFmin((double)source.blue,(double)destination.blue)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+LightenCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ composite=(MagickFmax((double)source.red,(double)destination.red)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ composite=(MagickFmax((double)source.green,(double)destination.green)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ composite=(MagickFmax((double)source.blue,(double)destination.blue)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+HueCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ brightness,
+ hue,
+ saturation,
+ sans;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ if (source.opacity == TransparentOpacity)
+ {
+ }
+ else if (destination.opacity == TransparentOpacity)
+ {
+ destination=source;
+ }
+ else
+ {
+ TransformHSL(destination.red,destination.green,destination.blue,
+ &hue,&saturation,&brightness);
+ TransformHSL(source.red,source.green,source.blue,&hue,&sans,&sans);
+ HSLTransform(hue,saturation,brightness,&destination.red,
+ &destination.green,&destination.blue);
+ if (source.opacity < destination.opacity)
+ destination.opacity=source.opacity;
+ }
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+SaturateCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ brightness,
+ hue,
+ saturation,
+ sans;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ if (source.opacity == TransparentOpacity)
+ {
+ }
+ else if (destination.opacity == TransparentOpacity)
+ {
+ destination=source;
+ }
+ else
+ {
+ TransformHSL(destination.red,destination.green,destination.blue,
+ &hue,&saturation,&brightness);
+ TransformHSL(source.red,source.green,source.blue,&sans,&saturation,
+ &sans);
+ HSLTransform(hue,saturation,brightness,&destination.red,
+ &destination.green,&destination.blue);
+ if (source.opacity < destination.opacity)
+ destination.opacity=source.opacity;
+ }
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+ColorizeCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ brightness,
+ hue,
+ saturation,
+ sans;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ if (source.opacity == TransparentOpacity)
+ {
+ }
+ else if (destination.opacity == TransparentOpacity)
+ {
+ destination=source;
+ }
+ else
+ {
+ TransformHSL(destination.red,destination.green,destination.blue,
+ &sans,&sans,&brightness);
+ TransformHSL(source.red,source.green,source.blue,&hue,&saturation,
+ &sans);
+ HSLTransform(hue,saturation,brightness,&destination.red,
+ &destination.green,&destination.blue);
+ if (source.opacity < destination.opacity)
+ destination.opacity=source.opacity;
+ }
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+LuminizeCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ brightness,
+ hue,
+ saturation,
+ sans;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ if (source.opacity == TransparentOpacity)
+ {
+ }
+ else if (destination.opacity == TransparentOpacity)
+ {
+ destination=source;
+ }
+ else
+ {
+ TransformHSL(destination.red,destination.green,destination.blue,
+ &hue,&saturation,&brightness);
+ TransformHSL(source.red,source.green,source.blue,&sans,&sans,
+ &brightness);
+ HSLTransform(hue,saturation,brightness,&destination.red,
+ &destination.green,&destination.blue);
+ if (source.opacity < destination.opacity)
+ destination.opacity=source.opacity;
+ }
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+ScreenCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Input colors are complimented and multiplied, then the product is complimented again.
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ composite=(((double)source.red+(double)destination.red-
+ ((double)source.red*(double)destination.red)/MaxRGBDouble)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ composite=(((double)source.green+(double)destination.green-
+ ((double)source.green*(double)destination.green)/MaxRGBDouble)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ composite=(((double)source.blue+(double)destination.blue-
+ ((double)source.blue*(double)destination.blue)/MaxRGBDouble)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+OverlayCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Multiplies or screens, depending on the destination colour.
+ Overlay(a,b) = HardLight(b,a)
+ */
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ if(destination.red < (0.5*MaxRGBDouble))
+ value=((double) source.red*destination.red*2.0)/MaxRGBDouble;
+ else
+ value= MaxRGBDouble * (1.0 - 2.0 * (1.0-(double) source.red/MaxRGBDouble) *
+ (1.0-(double)destination.red/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ if(destination.green < (0.5*MaxRGBDouble))
+ value=((double) source.green*destination.green*2.0)/MaxRGBDouble;
+ else
+ value= MaxRGBDouble * (1.0 - 2.0 * (1.0-(double) source.green/MaxRGBDouble) *
+ (1.0-(double)destination.green/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ if(destination.blue < (0.5*MaxRGBDouble))
+ value=((double) source.blue*destination.blue*2.0)/MaxRGBDouble;
+ else
+ value= MaxRGBDouble * (1.0 - 2.0 * (1.0-(double) source.blue/MaxRGBDouble) *
+ (1.0-(double)destination.blue/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+CopyBlackCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(source_indexes);
+ ARG_NOT_USED(update_indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ Copy the CMYK Black (K) channel into the image.
+ */
+ if ((update_image->colorspace == CMYKColorspace) &&
+ (source_image->colorspace == CMYKColorspace))
+ {
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].opacity=source_pixels[i].opacity;
+ }
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].opacity = PixelIntensityToQuantum(&source_pixels[i]);
+ }
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+DivideCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result of change-image / base-image. This is useful for
+ improving the readability of text on unevenly illuminated photos.
+ (by using a gaussian blurred copy of change-image as base-image)
+ */
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ composite,
+ divisor;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ /* Avoid division by zero error, use value near zero instead */
+ divisor=((destination.red != 0.0) ? destination.red : 1.0/MaxRGBDouble);
+ composite=((double) (source.red*MaxRGBDouble)/divisor);
+ destination.red=RoundDoubleToQuantum(composite);
+
+ divisor=((destination.green != 0.0) ? destination.green : 1.0/MaxRGBDouble);
+ composite=((double) (source.green*MaxRGBDouble)/divisor);
+ destination.green=RoundDoubleToQuantum(composite);
+
+ divisor=((destination.blue != 0.0) ? destination.blue : 1.0/MaxRGBDouble);
+ composite=((double) (source.blue*MaxRGBDouble)/divisor);
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ divisor=((destination.opacity != 0.0) ? destination.opacity : 1.0/MaxRGBDouble);
+ composite=((double) (source.opacity*MaxRGBDouble)/divisor);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+HardLightCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ The result of base-image gets lighting effects by change-image.
+ */
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ if(source.red <= (0.5*MaxRGBDouble))
+ value=((double) source.red*destination.red*2.0)/MaxRGBDouble;
+ else
+ value= MaxRGBDouble * (1.0 - 2.0 * (1.0-(double) source.red/MaxRGBDouble) *
+ (1.0-(double)destination.red/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ if(source.green <= (0.5*MaxRGBDouble))
+ value=((double) source.green*destination.green*2.0)/MaxRGBDouble;
+ else
+ value= MaxRGBDouble * (1.0 - 2.0 * (1.0-(double) source.green/MaxRGBDouble) *
+ (1.0-(double)destination.green/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ if(source.blue <= (0.5*MaxRGBDouble))
+ value=((double) source.blue*destination.blue*2.0)/MaxRGBDouble;
+ else
+ value= MaxRGBDouble * (1.0 - 2.0 * (1.0-(double) source.blue/MaxRGBDouble) *
+ (1.0-(double)destination.blue/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+ExclusionCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ A similar effect to Difference, but lower in contrast.
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ composite=(((double)source.red+(double)destination.red-
+ 2*((double)source.red*(double)destination.red)/MaxRGBDouble)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ composite=(((double)source.green+(double)destination.green-
+ 2*((double)source.green*(double)destination.green)/MaxRGBDouble)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ composite=(((double)source.blue+(double)destination.blue-
+ 2*((double)source.blue*(double)destination.blue)/MaxRGBDouble)*
+ (1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+ColorDodgeCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Brightens the destination color by an amount depending on the source color
+ */
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ if(source.red == MaxRGB)
+ value = MaxRGBDouble;
+ else
+ value=MagickFmin(MaxRGBDouble,(double)destination.red/(1.0-(double) source.red/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ if(source.green == MaxRGB)
+ value = MaxRGBDouble;
+ else
+ value=MagickFmin(MaxRGBDouble,(double)destination.green/(1.0-(double) source.green/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ if(source.blue == MaxRGB)
+ value = MaxRGBDouble;
+ else
+ value=MagickFmin(MaxRGBDouble,(double)destination.blue/(1.0-(double) source.blue/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+ColorBurnCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Darkens the destination color by an amount depending on the source color
+ */
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ if(source.red == 0)
+ value=0;
+ else
+ value = MaxRGBDouble-MagickFmin(MaxRGBDouble,(MaxRGBDouble-(double)destination.red)/((double) source.red/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ if(source.green == 0)
+ value=0;
+ else
+ value = MaxRGBDouble-MagickFmin(MaxRGBDouble,(MaxRGBDouble-(double)destination.green)/((double) source.green/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ if(source.blue == 0)
+ value=0;
+ else
+ value = MaxRGBDouble-MagickFmin(MaxRGBDouble,(MaxRGBDouble-(double)destination.blue)/((double) source.blue/MaxRGBDouble));
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+SoftLightCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Darkens or lightens, depending on the source color
+ */
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+ double ramp;
+
+ double
+ value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+
+ if(source.red <= (0.5*MaxRGBDouble))
+ value=destination.red*(1.0 - (1.0-(double)destination.red/MaxRGBDouble)*(1.0-2.0*(double)source.red/MaxRGBDouble));
+ else
+ {
+ if(destination.red <= (0.25*MaxRGBDouble))
+ ramp = ((16.0*((double)destination.red/MaxRGBDouble)-12.0)*((double)destination.red/MaxRGBDouble)+4.0)*(double)destination.red/MaxRGBDouble;
+ else
+ ramp = sqrt((double)destination.red/MaxRGBDouble);
+ value=destination.red + ((2.0*source.red)-MaxRGBDouble)*(ramp-(double)destination.red/MaxRGBDouble);
+ }
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ if(source.green <= (0.5*MaxRGBDouble))
+ value=destination.green*(1.0 - (1.0-(double)destination.green/MaxRGBDouble)*(1.0-2.0*(double)source.green/MaxRGBDouble));
+ else
+ {
+ if(destination.green <= (0.25*MaxRGBDouble))
+ ramp = ((16.0*((double)destination.green/MaxRGBDouble)-12.0)*((double)destination.green/MaxRGBDouble)+4.0)*(double)destination.green/MaxRGBDouble;
+ else
+ ramp = sqrt((double)destination.green/MaxRGBDouble);
+ value=destination.green + ((2.0*source.green)-MaxRGBDouble)*(ramp-(double)destination.green/MaxRGBDouble);
+ }
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ if(source.blue <= (0.5*MaxRGBDouble))
+ value=destination.blue*(1.0 - (1.0-(double)destination.blue/MaxRGBDouble)*(1.0-2.0*(double)source.blue/MaxRGBDouble));
+ else
+ {
+ if(destination.blue <= (0.25*MaxRGBDouble))
+ ramp = ((16.0*((double)destination.blue/MaxRGBDouble)-12.0)*((double)destination.blue/MaxRGBDouble)+4.0)*(double)destination.blue/MaxRGBDouble;
+ else
+ ramp = sqrt((double)destination.blue/MaxRGBDouble);
+ value=destination.blue + ((2.0*source.blue)-MaxRGBDouble)*(ramp-(double)destination.blue/MaxRGBDouble);
+ }
+ composite=(value*(1.0-source_alpha)*(1.0-dest_alpha)+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+LinearBurnCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Inverts the sum of the inverted images
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+ double value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ value = MagickFmax(0.0,(double)source.red+(double)destination.red-MaxRGBDouble);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ value = MagickFmax(0.0,(double)source.green+(double)destination.green-MaxRGBDouble);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ value = MagickFmax(0.0,(double)source.blue+(double)destination.blue-MaxRGBDouble);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+LinearDodgeCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ A simple alpha-blended sum of the images
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+ double value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ value = MagickFmin(MaxRGBDouble,(double)source.red+(double)destination.red);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ value = MagickFmin(MaxRGBDouble,(double)source.green+(double)destination.green);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ value = MagickFmin(MaxRGBDouble,(double)source.blue+(double)destination.blue);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+LinearLightCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Acts like LinearDodge (sum) for bright source pixels, LinearBurn (inverted sum) for dark source pixels
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+ double value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ value = MagickFmin(MaxRGBDouble,MagickFmax(0.0,2.0*(double)source.red+(double)destination.red-MaxRGBDouble));
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ value = MagickFmin(MaxRGBDouble,MagickFmax(0.0,2.0*(double)source.green+(double)destination.green-MaxRGBDouble));
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ value = MagickFmin(MaxRGBDouble,MagickFmax(0.0,2.0*(double)source.blue+(double)destination.blue-MaxRGBDouble));
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+VividLightCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Acts like ColorDodge for bright source pixels, ColorBurn for dark source pixels
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+ double value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ if(source.red==MaxRGB)
+ value = MaxRGBDouble;
+ else if(source.red==0)
+ value = 0.;
+ else if(source.red>=(0.5*MaxRGBDouble))
+ value = MagickFmin(MaxRGBDouble,destination.red/(2.0-(2.0*(double)source.red/MaxRGBDouble)));
+ else
+ value = MagickFmax(0.0,((double)destination.red+2.0*source.red-MaxRGBDouble)/(2.0*(double)source.red/MaxRGBDouble));
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ if(source.green==MaxRGB)
+ value = MaxRGBDouble;
+ else if(source.green==0)
+ value = 0.;
+ else if(source.green>=(0.5*MaxRGBDouble))
+ value = MagickFmin(MaxRGBDouble,destination.green/(2.0-(2.0*(double)source.green/MaxRGBDouble)));
+ else
+ value = MagickFmax(0.0,((double)destination.green+2.0*source.green-MaxRGBDouble)/(2.0*(double)source.green/MaxRGBDouble));
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ if(source.blue==MaxRGB)
+ value = MaxRGBDouble;
+ else if(source.blue==0)
+ value = 0.;
+ else if(source.blue>=(0.5*MaxRGBDouble))
+ value = MagickFmin(MaxRGBDouble,destination.blue/(2.0-(2.0*(double)source.blue/MaxRGBDouble)));
+ else
+ value = MagickFmax(0.0,((double)destination.blue+2.0*source.blue-MaxRGBDouble)/(2.0*(double)source.blue/MaxRGBDouble));
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+PinLightCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Acts like Lighten for bright source pixels, Darken for dark source pixels
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+ double value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ if(source.red>=(0.5*MaxRGBDouble))
+ value = MagickFmax((double)destination.red,2.0*((double)source.red-0.5*MaxRGBDouble));
+ else
+ value = MagickFmin((double)destination.red,2.0*(double)source.red);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ if(source.green>=(0.5*MaxRGBDouble))
+ value = MagickFmax((double)destination.green,2.0*((double)source.green-0.5*MaxRGBDouble));
+ else
+ value = MagickFmin((double)destination.green,2.0*(double)source.green);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ if(source.blue>=(0.5*MaxRGBDouble))
+ value = MagickFmax((double)destination.blue,2.0*((double)source.blue-0.5*MaxRGBDouble));
+ else
+ value = MagickFmin((double)destination.blue,2.0*(double)source.blue);
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+
+static MagickPassFail
+HardMixCompositePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ register long
+ i;
+
+ PixelPacket
+ destination,
+ source;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ /*
+ Averages each channel, then thresholds at half-value;
+ i.e. sets to zero if the average value is less than one half,
+ sets to full if above half.
+ */
+
+
+ for (i=0; i < npixels; i++)
+ {
+ double gamma;
+ double source_alpha;
+ double dest_alpha;
+ double composite;
+ double value;
+
+ PrepareSourcePacket(&source,source_pixels,source_image,source_indexes,i);
+ PrepareDestinationPacket(&destination,update_pixels,update_image,update_indexes,i);
+
+ source_alpha=(double) source.opacity/MaxRGBDouble;
+ dest_alpha=(double) destination.opacity/MaxRGBDouble;
+
+ gamma=(1.0-source_alpha)+(1.0-dest_alpha)-
+ (1.0-source_alpha)*(1.0-dest_alpha);
+ gamma=gamma < 0.0 ? 0.0 : (gamma > 1.0) ? 1.0 : gamma;
+
+ composite=MaxRGBDouble*(1.0-gamma);
+ destination.opacity=RoundDoubleToQuantum(composite);
+
+ gamma=1.0/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
+
+ if(source.red + destination.red < MaxRGB)
+ value = 0.0;
+ else
+ value = MaxRGBDouble;
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.red*(1.0-source_alpha)*dest_alpha+
+ destination.red*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.red=RoundDoubleToQuantum(composite);
+
+ if(source.green + destination.green < MaxRGB)
+ value = 0.0;
+ else
+ value = MaxRGBDouble;
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.green*(1.0-source_alpha)*dest_alpha+
+ destination.green*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.green=RoundDoubleToQuantum(composite);
+
+ if(source.blue + destination.blue < MaxRGB)
+ value = 0.0;
+ else
+ value = MaxRGBDouble;
+ composite=((value*(1.0-source_alpha)*(1.0-dest_alpha))+
+ source.blue*(1.0-source_alpha)*dest_alpha+
+ destination.blue*(1.0-dest_alpha)*source_alpha)*gamma;
+ destination.blue=RoundDoubleToQuantum(composite);
+
+ ApplyPacketUpdates(update_pixels,update_indexes,update_image,&destination,i);
+ }
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o m p o s i t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CompositeImage() composites the second image (composite_image) onto the
+% first (canvas_image) at the specified offsets.
+%
+% The format of the CompositeImage method is:
+%
+% MagickPassFail CompositeImage(Image *canvas_image,
+% const CompositeOperator compose,const Image *composite_image,
+% const long x_offset,const long y_offset)
+%
+% A description of each parameter follows:
+%
+% o canvas_image: The image to be updated.
+%
+% o compose: This operator affects how the composite is applied to
+% the image. Choose from one of these operators: AddCompositeOp,
+% AtopCompositeOp, BumpmapCompositeOp, ClearCompositeOp,
+% ColorizeCompositeOp, CopyBlackCompositeOp, CopyBlueCompositeOp,
+% CopyCompositeOp, CopyCyanCompositeOp,CopyGreenCompositeOp,
+% CopyMagentaCompositeOp, CopyOpacityCompositeOp, CopyRedCompositeOp,
+% CopyYellowCompositeOp, DarkenCompositeOp, DifferenceCompositeOp,
+% DisplaceCompositeOp, DissolveCompositeOp, DivideCompositeOp,
+% HueCompositeOp, InCompositeOp, LightenCompositeOp, LuminizeCompositeOp,
+% MinusCompositeOp, ModulateCompositeOp, MultiplyCompositeOp,
+% NoCompositeOp, OutCompositeOp, OverlayCompositeOp, PlusCompositeOp,
+% SaturateCompositeOp, ScreenCompositeOp, SubtractCompositeOp,
+% ThresholdCompositeOp, XorCompositeOp, HardLightCompositeOp.
+%
+% o composite_image: The composite image.
+%
+% o x_offset: The column offset of the composited image.
+%
+% o y_offset: The row offset of the composited image.
+%
+%
+*/
+static PixelIteratorDualModifyCallback
+GetCompositionPixelIteratorCallback(const CompositeOperator compose,
+ const MagickBool canvas_matte,
+ const MagickBool change_matte,
+ MagickBool *clear)
+{
+ PixelIteratorDualModifyCallback
+ call_back = (PixelIteratorDualModifyCallback) NULL;
+
+ MagickBool
+ clear_flag=MagickFalse;
+
+ assert(clear != (MagickBool *) NULL);
+
+ switch (compose)
+ {
+ case UndefinedCompositeOp:
+ /* Does nothing */
+ break;
+ case OverCompositeOp:
+ if (canvas_matte || change_matte)
+ call_back=OverCompositePixels;
+ else
+ call_back=CopyCompositePixels;
+ break;
+ case InCompositeOp:
+ call_back=InCompositePixels;
+ break;
+ case OutCompositeOp:
+ call_back=OutCompositePixels;
+ break;
+ case AtopCompositeOp:
+ if (canvas_matte || change_matte)
+ call_back=AtopCompositePixels;
+ else
+ call_back=CopyCompositePixels;
+ break;
+ case XorCompositeOp:
+ call_back=XorCompositePixels;
+ break;
+ case PlusCompositeOp:
+ call_back=PlusCompositePixels;
+ break;
+ case MinusCompositeOp:
+ call_back=MinusCompositePixels;
+ break;
+ case AddCompositeOp:
+ call_back=AddCompositePixels;
+ break;
+ case SubtractCompositeOp:
+ call_back=SubtractCompositePixels;
+ break;
+ case DifferenceCompositeOp:
+ call_back=DifferenceCompositePixels;
+ break;
+ case MultiplyCompositeOp:
+ call_back=MultiplyCompositePixels;
+ break;
+ case BumpmapCompositeOp:
+ call_back=BumpmapCompositePixels;
+ break;
+ case CopyCompositeOp:
+ call_back=CopyCompositePixels;
+ break;
+ case CopyRedCompositeOp:
+ call_back=CopyRedCompositePixels;
+ break;
+ case CopyGreenCompositeOp:
+ call_back=CopyGreenCompositePixels;
+ break;
+ case CopyBlueCompositeOp:
+ call_back=CopyBlueCompositePixels;
+ break;
+ case CopyOpacityCompositeOp:
+ call_back=CopyOpacityCompositePixels;
+ break;
+ case ClearCompositeOp:
+ call_back=ClearCompositePixels;
+ break;
+ case DissolveCompositeOp:
+ call_back=DissolveCompositePixels;
+ break;
+ case DisplaceCompositeOp:
+ call_back=CopyCompositePixels;
+ break;
+ case ModulateCompositeOp:
+ call_back=ModulateCompositePixels;
+ break;
+ case ThresholdCompositeOp:
+ call_back=ThresholdCompositePixels;
+ break;
+ case NoCompositeOp:
+ break;
+ case DarkenCompositeOp:
+ call_back=DarkenCompositePixels;
+ break;
+ case LightenCompositeOp:
+ call_back=LightenCompositePixels;
+ break;
+ case HueCompositeOp:
+ call_back=HueCompositePixels;
+ break;
+ case SaturateCompositeOp:
+ call_back=SaturateCompositePixels;
+ break;
+ case ColorizeCompositeOp:
+ call_back=ColorizeCompositePixels;
+ break;
+ case LuminizeCompositeOp:
+ call_back=LuminizeCompositePixels;
+ break;
+ case ScreenCompositeOp:
+ call_back=ScreenCompositePixels;
+ break;
+ case OverlayCompositeOp:
+ call_back=OverlayCompositePixels;
+ break;
+ case CopyCyanCompositeOp:
+ call_back=CopyRedCompositePixels;
+ break;
+ case CopyMagentaCompositeOp:
+ call_back=CopyGreenCompositePixels;
+ break;
+ case CopyYellowCompositeOp:
+ call_back=CopyBlueCompositePixels;
+ break;
+ case CopyBlackCompositeOp:
+ call_back=CopyBlackCompositePixels;
+ break;
+ case DivideCompositeOp:
+ call_back=DivideCompositePixels;
+ break;
+ case HardLightCompositeOp:
+ call_back=HardLightCompositePixels;
+ break;
+ case ExclusionCompositeOp:
+ call_back=ExclusionCompositePixels;
+ break;
+ case ColorDodgeCompositeOp:
+ call_back=ColorDodgeCompositePixels;
+ break;
+ case ColorBurnCompositeOp:
+ call_back=ColorBurnCompositePixels;
+ break;
+ case SoftLightCompositeOp:
+ call_back=SoftLightCompositePixels;
+ break;
+ case LinearBurnCompositeOp:
+ call_back=LinearBurnCompositePixels;
+ break;
+ case LinearDodgeCompositeOp:
+ call_back=LinearDodgeCompositePixels;
+ break;
+ case LinearLightCompositeOp:
+ call_back=LinearLightCompositePixels;
+ break;
+ case VividLightCompositeOp:
+ call_back=VividLightCompositePixels;
+ break;
+ case PinLightCompositeOp:
+ call_back=PinLightCompositePixels;
+ break;
+ case HardMixCompositeOp:
+ call_back=HardMixCompositePixels;
+ break;
+ default:
+ {
+ break;
+ }
+ }
+
+ if ((CopyCompositePixels == call_back) ||
+ (ClearCompositePixels == call_back))
+ clear_flag=MagickTrue;
+
+ *clear=clear_flag;
+ return call_back;
+}
+MagickExport MagickPassFail
+CompositeImage(Image *canvas_image,
+ const CompositeOperator compose,
+ const Image *update_image,
+ const long x_offset,const long y_offset)
+{
+ CompositeOptions_t
+ options;
+
+ Image
+ *change_image;
+
+ double
+ amount=0.0,
+ percent_brightness=0.0,
+ percent_saturation=0.0,
+ threshold=0.0;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Prepare composite image.
+ */
+ assert(canvas_image != (Image *) NULL);
+ assert(canvas_image->signature == MagickSignature);
+ assert(update_image != (Image *) NULL);
+ assert(update_image->signature == MagickSignature);
+ if (compose == NoCompositeOp)
+ return(MagickPass);
+
+ /*
+ Clone composite image so that we can modify it if need be.
+ */
+ change_image=CloneImage(update_image,0,0,True,&canvas_image->exception);
+ if (change_image == (Image *) NULL)
+ return(MagickFail);
+
+ canvas_image->storage_class=DirectClass;
+ switch (compose)
+ {
+ case CopyCyanCompositeOp:
+ case CopyMagentaCompositeOp:
+ case CopyYellowCompositeOp:
+ case CopyBlackCompositeOp:
+ {
+ canvas_image->colorspace=CMYKColorspace;
+ break;
+ }
+ case CopyOpacityCompositeOp:
+ {
+ canvas_image->matte=MagickTrue;
+ break;
+ }
+ case DisplaceCompositeOp:
+ {
+ double
+ x_displace,
+ y_displace;
+
+ double
+ horizontal_scale,
+ vertical_scale;
+
+ register PixelPacket
+ *r;
+
+ horizontal_scale=20.0;
+ vertical_scale=20.0;
+ if (update_image->geometry != (char *) NULL)
+ {
+ int
+ count;
+
+ /*
+ Determine the horizontal and vertical displacement scale.
+ */
+ count=GetMagickDimension(update_image->geometry,
+ &horizontal_scale,&vertical_scale,NULL,NULL);
+ if (count == 1)
+ vertical_scale=horizontal_scale;
+ }
+ /*
+ Shift image pixels as defined by a displacement map.
+ */
+ for (y=0; y < (long) update_image->rows; y++)
+ {
+ if (((y+y_offset) < 0) || ((y+y_offset) >= (long) canvas_image->rows))
+ continue;
+ p=AcquireImagePixels(update_image,0,y,update_image->columns,1,
+ &canvas_image->exception);
+ q=GetImagePixels(canvas_image,0,y+y_offset,canvas_image->columns,1);
+ r=GetImagePixels(change_image,0,y,change_image->columns,1);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL) ||
+ (r == (PixelPacket *) NULL))
+ {
+ status=MagickFail;
+ break;
+ }
+ q+=x_offset;
+ for (x=0; x < (long) update_image->columns; x++)
+ {
+ if (((x_offset+x) < 0) || ((x_offset+x) >= (long) canvas_image->columns))
+ {
+ p++;
+ q++;
+ continue;
+ }
+ x_displace=(horizontal_scale*(PixelIntensityToQuantum(p)-
+ (((double) MaxRGB+1.0)/2)))/(((double) MaxRGB+1.0)/2);
+ y_displace=x_displace;
+ if (update_image->matte)
+ y_displace=(vertical_scale*(p->opacity-
+ (((double) MaxRGB+1.0)/2)))/(((double) MaxRGB+1.0)/2);
+ InterpolateViewColor(AccessDefaultCacheView(canvas_image),r,
+ x_offset+x+x_displace,y_offset+y+y_displace,
+ &canvas_image->exception);
+ p++;
+ q++;
+ r++;
+ }
+ if (!SyncImagePixels(change_image))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ break;
+ }
+ case ModulateCompositeOp:
+ {
+ percent_saturation=50.0;
+ percent_brightness=50.0;
+ if (update_image->geometry != (char *) NULL)
+ {
+ int
+ count;
+
+ /*
+ Determine the brightness and saturation scale.
+ */
+ count=GetMagickDimension(update_image->geometry,
+ &percent_brightness,&percent_saturation,NULL,NULL);
+ if (count == 1)
+ percent_saturation=percent_brightness;
+ }
+ percent_brightness/=100.0;
+ percent_saturation/=100.0;
+ break;
+ }
+ case ThresholdCompositeOp:
+ {
+ /*
+ Determine the amount and threshold.
+ */
+ amount=0.5;
+ threshold=0.05;
+ if (update_image->geometry != (char *) NULL)
+ (void) GetMagickDimension(update_image->geometry,&amount,&threshold,NULL,NULL);
+ threshold*=MaxRGB;
+ break;
+ }
+ default:
+ break;
+ }
+
+ /*
+ Make sure that the composite image is in a colorspace which is
+ compatible (as need be) with the canvas image.
+ */
+ switch (compose)
+ {
+ case CopyRedCompositeOp:
+ case CopyGreenCompositeOp:
+ case CopyBlueCompositeOp:
+ case CopyCyanCompositeOp:
+ case CopyMagentaCompositeOp:
+ case CopyYellowCompositeOp:
+ case CopyBlackCompositeOp:
+ {
+ /*
+ Assume that the user is right for channel copies.
+ */
+ break;
+ }
+ default:
+ {
+ if (IsRGBColorspace(canvas_image->colorspace))
+ {
+ if (!IsRGBColorspace(change_image->colorspace))
+ TransformColorspace(change_image,RGBColorspace);
+ }
+ else if (IsYCbCrColorspace(canvas_image->colorspace))
+ {
+ if (canvas_image->colorspace != change_image->colorspace)
+ TransformColorspace(change_image,canvas_image->colorspace);
+ }
+ else if (IsCMYKColorspace(canvas_image->colorspace))
+ {
+ if (!IsCMYKColorspace(change_image->colorspace))
+ TransformColorspace(change_image,canvas_image->colorspace);
+ }
+ else
+ {
+ TransformColorspace(change_image,canvas_image->colorspace);
+ }
+ break;
+ }
+ }
+
+ /*
+ Composite image.
+ */
+ options.percent_brightness=percent_brightness;
+ options.amount=amount;
+ options.threshold=threshold;
+
+ {
+ unsigned long
+ columns,
+ rows;
+
+ long
+ composite_x,
+ composite_y,
+ canvas_x,
+ canvas_y;
+
+ columns=change_image->columns;
+ rows=change_image->rows;
+
+ composite_x=0;
+ composite_y=0;
+ canvas_x=x_offset;
+ canvas_y=y_offset;
+
+ if (x_offset < 0)
+ composite_x += -x_offset;
+ if (y_offset < 0)
+ composite_y += -y_offset;
+
+ columns -= composite_x;
+ rows -= composite_y;
+
+ if (canvas_x < 0)
+ canvas_x=0;
+ if (canvas_y < 0)
+ canvas_y=0;
+
+#if 0
+ fprintf(stderr,
+ "Parameters: canvas=%lux%lu | composite=%lux%lu | offset x=%ld y=%ld\n"
+ "Overlap: canvas x=%ld y=%ld | composite x=%ld y=%ld | size=%ldx%ld\n",
+ canvas_image->columns,canvas_image->rows,
+ change_image->columns,change_image->rows,
+ x_offset,y_offset,
+ canvas_x,canvas_y,
+ composite_x,composite_y,
+ columns,rows);
+#endif
+
+ if (((unsigned long) canvas_x < canvas_image->columns) &&
+ ((unsigned long) canvas_y < canvas_image->rows) &&
+ ((unsigned long) composite_x < change_image->columns) &&
+ ((unsigned long) composite_y < change_image->rows))
+ {
+ PixelIteratorDualModifyCallback
+ call_back = (PixelIteratorDualModifyCallback) NULL;
+
+ MagickBool
+ clear_pixels = MagickFalse;
+
+ columns = Min(canvas_image->columns - canvas_x,
+ change_image->columns - composite_x);
+ rows = Min(canvas_image->rows - canvas_y,
+ change_image->rows - composite_y);
+
+ call_back=GetCompositionPixelIteratorCallback(compose,
+ canvas_image->matte,
+ change_image->matte,
+ &clear_pixels);
+ if (call_back != (PixelIteratorDualModifyCallback) NULL)
+ {
+ char
+ description[MaxTextExtent];
+
+ FormatString(description,"[%%s] Composite %s image pixels ...",
+ CompositeOperatorToString(compose));
+
+ if (clear_pixels)
+ {
+ /*
+ We don't care about existing pixels in the region.
+ */
+ status=PixelIterateDualNew(call_back, /* Callback */
+ NULL,
+ description, /* Description */
+ NULL,
+ &options, /* Options */
+ columns, /* Number of columns */
+ rows, /* Number of rows */
+ change_image, /* Composite image */
+ composite_x, /* Composite x offset */
+ composite_y, /* Composite y offset */
+ canvas_image, /* Canvas image */
+ canvas_x, /* Canvas x offset */
+ canvas_y, /* Canvas y offset */
+ &canvas_image->exception); /* Exception */
+ }
+ else
+ {
+ /*
+ Blend with existing pixels in the region.
+ */
+ status=PixelIterateDualModify(call_back, /* Callback */
+ NULL,
+ description, /* Description */
+ NULL,
+ &options, /* Options */
+ columns, /* Number of columns */
+ rows, /* Number of rows */
+ change_image, /* Composite image */
+ composite_x, /* Composite x offset */
+ composite_y, /* Composite y offset */
+ canvas_image, /* Canvas image */
+ canvas_x, /* Canvas x offset */
+ canvas_y, /* Canvas y offset */
+ &canvas_image->exception); /* Exception */
+ }
+ }
+ else
+ {
+ status=MagickFail;
+ }
+ }
+ }
+
+ DestroyImage(change_image);
+ change_image=(Image *) NULL;
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C o m p o s i t e I m a g e R e g i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CompositeImageRegion() composites the update image on the canvas image
+% using a specified composition operation. The offset and dimensions of
+% the region in update image to use are specified. The offset to
+% composite on the canvas image is specified. These parameters are
+% adjusted as needed so that only the portions which overlap (according
+% to the user's specification and the image sizes) are actually composited.
+% If there is no overlap at all, then no work is performed and MagickFail
+% is returned.
+%
+% The format of the CompositeImage method is:
+%
+% MagickPassFail CompositeImageRegion(const CompositeOperator compose,
+% const CompositeOptions_t *options,
+% const unsigned long columns,
+% const unsigned long rows,
+% const Image *update_image,
+% const long update_x,
+% const long update_y,
+% Image *canvas_image,
+% const long canvas_x,
+% const long canvas_y,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o compose: This operator affects how the composite is applied to
+% the image. Choose from one of these operators: AddCompositeOp,
+% AtopCompositeOp, BumpmapCompositeOp, ClearCompositeOp,
+% ColorizeCompositeOp, CopyBlackCompositeOp, CopyBlueCompositeOp,
+% CopyCompositeOp, CopyCyanCompositeOp,CopyGreenCompositeOp,
+% CopyMagentaCompositeOp, CopyOpacityCompositeOp, CopyRedCompositeOp,
+% CopyYellowCompositeOp, DarkenCompositeOp, DifferenceCompositeOp,
+% DisplaceCompositeOp, DissolveCompositeOp, DivideCompositeOp,
+% HueCompositeOp, InCompositeOp, LightenCompositeOp, LuminizeCompositeOp,
+% MinusCompositeOp, ModulateCompositeOp, MultiplyCompositeOp,
+% NoCompositeOp, OutCompositeOp, OverlayCompositeOp, PlusCompositeOp,
+% SaturateCompositeOp, ScreenCompositeOp, SubtractCompositeOp,
+% ThresholdCompositeOp, XorCompositeOp, HardLightCompositeOp.
+%
+% o options: This optional structure passes options required by
+% ModulateComposite and ThresholdComposite and NULL may be
+% passed if it is not otherwise needed.
+%
+% o columns: Width of update region.
+%
+% o rows: Height of update region.
+%
+% o update_image: Image to composite on canvas image.
+%
+% o update_x: X ordinate of region to composite.
+%
+% o update_y: Y ordinate of region to composite.
+%
+% o canvas_image: Image to update.
+%
+% o canvas_x: X ordinate of canvas region to composite on.
+%
+% o canvas_y: Y ordinate of canvas region to composite on.
+%
+% o exception: Details of any error are reported here.
+%
+*/
+MagickExport MagickPassFail
+CompositeImageRegion(const CompositeOperator compose,
+ const CompositeOptions_t *options,
+ const unsigned long arg_columns,
+ const unsigned long arg_rows,
+ const Image *update_image,
+ const long arg_update_x,
+ const long arg_update_y,
+ Image *canvas_image,
+ const long arg_canvas_x,
+ const long arg_canvas_y,
+ ExceptionInfo *exception)
+{
+ PixelIteratorDualModifyCallback
+ call_back = (PixelIteratorDualModifyCallback) NULL;
+
+ MagickBool
+ clear_pixels = MagickFalse;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /* printf("columns=%lu rows=%lu update_x=%ld update_y=%ld canvas_x=%ld canvas_y=%ld\n", */
+ /* columns,rows,update_x,update_y,canvas_x,canvas_y); */
+
+ if (compose == NoCompositeOp)
+ return(MagickPass);
+
+ canvas_image->storage_class=DirectClass;
+
+ call_back=GetCompositionPixelIteratorCallback(compose,
+ canvas_image->matte,
+ update_image->matte,
+ &clear_pixels);
+ if (call_back != (PixelIteratorDualModifyCallback) NULL)
+ {
+ const char
+ *description = "[%s] Composite image pixels ...";
+
+ unsigned long
+ columns=arg_columns,
+ rows=arg_rows;
+
+ long
+ update_x=arg_update_x,
+ update_y=arg_update_y,
+ canvas_x=arg_canvas_x,
+ canvas_y=arg_canvas_y;
+
+ /*
+ FIXME: The area logic is not implemented yet.
+ */
+
+ if ((update_x >= (long) update_image->columns) ||
+ (update_y >= (long) update_image->rows) ||
+ (canvas_x >= (long) canvas_image->columns) ||
+ (canvas_y >= (long) canvas_image->rows))
+ status = MagickFail;
+
+#if 0
+ printf("canvas_image=%lux%lu update_image=%lux%lu update_region=%lux%lu+%ld+%ld canvas_region=%lux%lu+%ld+%ld \n",
+ canvas_image->columns,canvas_image->rows,
+ update_image->columns,update_image->rows,
+ columns,rows,update_x,update_y,
+ columns,rows,canvas_x,canvas_y);
+#endif
+
+ if ((status == MagickPass) &&
+ ((unsigned long) canvas_x < canvas_image->columns) &&
+ ((unsigned long) canvas_y < canvas_image->rows) &&
+ ((unsigned long) update_x < update_image->columns) &&
+ ((unsigned long) update_y < update_image->rows) &&
+ (columns != 0) && (rows != 0))
+ {
+ if (clear_pixels)
+ {
+ /*
+ We don't care about existing pixels in the region.
+ */
+ status=PixelIterateDualNew(call_back, /* Callback */
+ NULL,
+ description, /* Description */
+ NULL,
+ options, /* Options */
+ columns, /* Number of columns */
+ rows, /* Number of rows */
+ update_image, /* Composite image */
+ update_x, /* Composite x offset */
+ update_y, /* Composite y offset */
+ canvas_image, /* Canvas image */
+ canvas_x, /* Canvas x offset */
+ canvas_y, /* Canvas y offset */
+ exception); /* Exception */
+ }
+ else
+ {
+ /*
+ Blend with existing pixels in the region.
+ */
+ status=PixelIterateDualModify(call_back, /* Callback */
+ NULL,
+ description, /* Description */
+ NULL,
+ options, /* Options */
+ columns, /* Number of columns */
+ rows, /* Number of rows */
+ update_image, /* Composite image */
+ update_x, /* Composite x offset */
+ update_y, /* Composite y offset */
+ canvas_image, /* Canvas image */
+ canvas_x, /* Canvas x offset */
+ canvas_y, /* Canvas y offset */
+ exception); /* Exception */
+ }
+ }
+ }
+ else
+ {
+ status=MagickFail;
+ }
+
+ return status;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k C o m p o s i t e I m a g e U n d e r C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCompositeImageUnderColor() composites a color underneath an image,
+% removing any existing opacity.
+%
+% The format of the MagickCompositeImageUnderColor method is:
+%
+% MagickPassFail MagickCompositeImageUnderColor(Image *image,
+% PixelPacket *undercolor,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Image to modify.
+%
+% o undercolor: Background color to apply.
+%
+% o exception: Details of any error are reported here.
+%
+*/
+static MagickPassFail
+MagickCompositeImageUnderColorPixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket * restrict pixels, /* Pixel row */
+ IndexPacket * restrict indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ const PixelPacket
+ * restrict background_color = (const PixelPacket *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ AlphaCompositePixel(&pixels[i],&pixels[i],pixels[i].opacity,background_color,
+ background_color->opacity);
+ pixels[i].opacity=OpaqueOpacity;
+ }
+
+ return MagickPass;
+}
+
+MagickExport MagickPassFail
+MagickCompositeImageUnderColor(Image *image,const PixelPacket *undercolor,
+ ExceptionInfo *exception)
+{
+ MagickPassFail
+ status;
+
+ image->storage_class=DirectClass;
+ status=PixelIterateMonoModify(MagickCompositeImageUnderColorPixels,
+ NULL,
+ "[%s] Applying undercolor...",
+ NULL,undercolor,
+ 0,0,image->columns,image->rows,
+ image,
+ exception);
+ image->matte=MagickFalse;
+
+ return status;
+}
diff --git a/magick/composite.h b/magick/composite.h
new file mode 100644
index 0000000..c8a43c1
--- /dev/null
+++ b/magick/composite.h
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 2003 - 2010 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Image Composite Methods.
+*/
+#ifndef _MAGICK_COMPOSITE_H
+#define _MAGICK_COMPOSITE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+/*
+ Special options required by some composition operators.
+*/
+typedef struct _CompositeOptions_t
+{
+ /* ModulateComposite */
+ double percent_brightness;
+
+ /* ThresholdComposite */
+ double amount;
+ double threshold;
+} CompositeOptions_t;
+
+extern MagickExport MagickPassFail
+ CompositeImage(Image *canvas_image,const CompositeOperator compose,
+ const Image *update_image,
+ const long x_offset,const long y_offset),
+ CompositeImageRegion(const CompositeOperator compose,
+ const CompositeOptions_t *options,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *update_image,
+ const long update_x,
+ const long update_y,
+ Image *canvas_image,
+ const long canvas_x,
+ const long canvas_y,
+ ExceptionInfo *exception),
+ MagickCompositeImageUnderColor(Image *image,const PixelPacket *undercolor,
+ ExceptionInfo *exception);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_COMPOSITE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/compress.c b/magick/compress.c
new file mode 100644
index 0000000..c8aa1ab
--- /dev/null
+++ b/magick/compress.c
@@ -0,0 +1,1346 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC OOO M M PPPP RRRR EEEEE SSSSS SSSSS %
+% C O O MM MM P P R R E SS SS %
+% C O O M M M PPPP RRRR EEE SSS SSS %
+% C O O M M P R R E SS SS %
+% CCCC OOO M M P R R EEEEE SSSSS SSSSS %
+% %
+% %
+% Image Compression/Decompression Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% May 1993 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/compress.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+
+
+/*
+ Typedef declarations.
+*/
+typedef struct HuffmanTable
+{
+ int
+ id,
+ code,
+ length,
+ count;
+} HuffmanTable;
+
+/*
+ Huffman coding declarations.
+*/
+#define TWId 23
+#define MWId 24
+#define TBId 25
+#define MBId 26
+#define EXId 27
+
+static const HuffmanTable
+ MBTable[]=
+ {
+ { MBId, 0x0f, 10, 64 }, { MBId, 0xc8, 12, 128 },
+ { MBId, 0xc9, 12, 192 }, { MBId, 0x5b, 12, 256 },
+ { MBId, 0x33, 12, 320 }, { MBId, 0x34, 12, 384 },
+ { MBId, 0x35, 12, 448 }, { MBId, 0x6c, 13, 512 },
+ { MBId, 0x6d, 13, 576 }, { MBId, 0x4a, 13, 640 },
+ { MBId, 0x4b, 13, 704 }, { MBId, 0x4c, 13, 768 },
+ { MBId, 0x4d, 13, 832 }, { MBId, 0x72, 13, 896 },
+ { MBId, 0x73, 13, 960 }, { MBId, 0x74, 13, 1024 },
+ { MBId, 0x75, 13, 1088 }, { MBId, 0x76, 13, 1152 },
+ { MBId, 0x77, 13, 1216 }, { MBId, 0x52, 13, 1280 },
+ { MBId, 0x53, 13, 1344 }, { MBId, 0x54, 13, 1408 },
+ { MBId, 0x55, 13, 1472 }, { MBId, 0x5a, 13, 1536 },
+ { MBId, 0x5b, 13, 1600 }, { MBId, 0x64, 13, 1664 },
+ { MBId, 0x65, 13, 1728 }, { MBId, 0x00, 0, 0 }
+ };
+
+static const HuffmanTable
+ EXTable[]=
+ {
+ { EXId, 0x08, 11, 1792 }, { EXId, 0x0c, 11, 1856 },
+ { EXId, 0x0d, 11, 1920 }, { EXId, 0x12, 12, 1984 },
+ { EXId, 0x13, 12, 2048 }, { EXId, 0x14, 12, 2112 },
+ { EXId, 0x15, 12, 2176 }, { EXId, 0x16, 12, 2240 },
+ { EXId, 0x17, 12, 2304 }, { EXId, 0x1c, 12, 2368 },
+ { EXId, 0x1d, 12, 2432 }, { EXId, 0x1e, 12, 2496 },
+ { EXId, 0x1f, 12, 2560 }, { EXId, 0x00, 0, 0 }
+ };
+
+static const HuffmanTable
+ MWTable[]=
+ {
+ { MWId, 0x1b, 5, 64 }, { MWId, 0x12, 5, 128 },
+ { MWId, 0x17, 6, 192 }, { MWId, 0x37, 7, 256 },
+ { MWId, 0x36, 8, 320 }, { MWId, 0x37, 8, 384 },
+ { MWId, 0x64, 8, 448 }, { MWId, 0x65, 8, 512 },
+ { MWId, 0x68, 8, 576 }, { MWId, 0x67, 8, 640 },
+ { MWId, 0xcc, 9, 704 }, { MWId, 0xcd, 9, 768 },
+ { MWId, 0xd2, 9, 832 }, { MWId, 0xd3, 9, 896 },
+ { MWId, 0xd4, 9, 960 }, { MWId, 0xd5, 9, 1024 },
+ { MWId, 0xd6, 9, 1088 }, { MWId, 0xd7, 9, 1152 },
+ { MWId, 0xd8, 9, 1216 }, { MWId, 0xd9, 9, 1280 },
+ { MWId, 0xda, 9, 1344 }, { MWId, 0xdb, 9, 1408 },
+ { MWId, 0x98, 9, 1472 }, { MWId, 0x99, 9, 1536 },
+ { MWId, 0x9a, 9, 1600 }, { MWId, 0x18, 6, 1664 },
+ { MWId, 0x9b, 9, 1728 }, { MWId, 0x00, 0, 0 }
+ };
+
+static const HuffmanTable
+ TBTable[]=
+ {
+ { TBId, 0x37, 10, 0 }, { TBId, 0x02, 3, 1 }, { TBId, 0x03, 2, 2 },
+ { TBId, 0x02, 2, 3 }, { TBId, 0x03, 3, 4 }, { TBId, 0x03, 4, 5 },
+ { TBId, 0x02, 4, 6 }, { TBId, 0x03, 5, 7 }, { TBId, 0x05, 6, 8 },
+ { TBId, 0x04, 6, 9 }, { TBId, 0x04, 7, 10 }, { TBId, 0x05, 7, 11 },
+ { TBId, 0x07, 7, 12 }, { TBId, 0x04, 8, 13 }, { TBId, 0x07, 8, 14 },
+ { TBId, 0x18, 9, 15 }, { TBId, 0x17, 10, 16 }, { TBId, 0x18, 10, 17 },
+ { TBId, 0x08, 10, 18 }, { TBId, 0x67, 11, 19 }, { TBId, 0x68, 11, 20 },
+ { TBId, 0x6c, 11, 21 }, { TBId, 0x37, 11, 22 }, { TBId, 0x28, 11, 23 },
+ { TBId, 0x17, 11, 24 }, { TBId, 0x18, 11, 25 }, { TBId, 0xca, 12, 26 },
+ { TBId, 0xcb, 12, 27 }, { TBId, 0xcc, 12, 28 }, { TBId, 0xcd, 12, 29 },
+ { TBId, 0x68, 12, 30 }, { TBId, 0x69, 12, 31 }, { TBId, 0x6a, 12, 32 },
+ { TBId, 0x6b, 12, 33 }, { TBId, 0xd2, 12, 34 }, { TBId, 0xd3, 12, 35 },
+ { TBId, 0xd4, 12, 36 }, { TBId, 0xd5, 12, 37 }, { TBId, 0xd6, 12, 38 },
+ { TBId, 0xd7, 12, 39 }, { TBId, 0x6c, 12, 40 }, { TBId, 0x6d, 12, 41 },
+ { TBId, 0xda, 12, 42 }, { TBId, 0xdb, 12, 43 }, { TBId, 0x54, 12, 44 },
+ { TBId, 0x55, 12, 45 }, { TBId, 0x56, 12, 46 }, { TBId, 0x57, 12, 47 },
+ { TBId, 0x64, 12, 48 }, { TBId, 0x65, 12, 49 }, { TBId, 0x52, 12, 50 },
+ { TBId, 0x53, 12, 51 }, { TBId, 0x24, 12, 52 }, { TBId, 0x37, 12, 53 },
+ { TBId, 0x38, 12, 54 }, { TBId, 0x27, 12, 55 }, { TBId, 0x28, 12, 56 },
+ { TBId, 0x58, 12, 57 }, { TBId, 0x59, 12, 58 }, { TBId, 0x2b, 12, 59 },
+ { TBId, 0x2c, 12, 60 }, { TBId, 0x5a, 12, 61 }, { TBId, 0x66, 12, 62 },
+ { TBId, 0x67, 12, 63 }, { TBId, 0x00, 0, 0 }
+ };
+
+static const HuffmanTable
+ TWTable[]=
+ {
+ { TWId, 0x35, 8, 0 }, { TWId, 0x07, 6, 1 }, { TWId, 0x07, 4, 2 },
+ { TWId, 0x08, 4, 3 }, { TWId, 0x0b, 4, 4 }, { TWId, 0x0c, 4, 5 },
+ { TWId, 0x0e, 4, 6 }, { TWId, 0x0f, 4, 7 }, { TWId, 0x13, 5, 8 },
+ { TWId, 0x14, 5, 9 }, { TWId, 0x07, 5, 10 }, { TWId, 0x08, 5, 11 },
+ { TWId, 0x08, 6, 12 }, { TWId, 0x03, 6, 13 }, { TWId, 0x34, 6, 14 },
+ { TWId, 0x35, 6, 15 }, { TWId, 0x2a, 6, 16 }, { TWId, 0x2b, 6, 17 },
+ { TWId, 0x27, 7, 18 }, { TWId, 0x0c, 7, 19 }, { TWId, 0x08, 7, 20 },
+ { TWId, 0x17, 7, 21 }, { TWId, 0x03, 7, 22 }, { TWId, 0x04, 7, 23 },
+ { TWId, 0x28, 7, 24 }, { TWId, 0x2b, 7, 25 }, { TWId, 0x13, 7, 26 },
+ { TWId, 0x24, 7, 27 }, { TWId, 0x18, 7, 28 }, { TWId, 0x02, 8, 29 },
+ { TWId, 0x03, 8, 30 }, { TWId, 0x1a, 8, 31 }, { TWId, 0x1b, 8, 32 },
+ { TWId, 0x12, 8, 33 }, { TWId, 0x13, 8, 34 }, { TWId, 0x14, 8, 35 },
+ { TWId, 0x15, 8, 36 }, { TWId, 0x16, 8, 37 }, { TWId, 0x17, 8, 38 },
+ { TWId, 0x28, 8, 39 }, { TWId, 0x29, 8, 40 }, { TWId, 0x2a, 8, 41 },
+ { TWId, 0x2b, 8, 42 }, { TWId, 0x2c, 8, 43 }, { TWId, 0x2d, 8, 44 },
+ { TWId, 0x04, 8, 45 }, { TWId, 0x05, 8, 46 }, { TWId, 0x0a, 8, 47 },
+ { TWId, 0x0b, 8, 48 }, { TWId, 0x52, 8, 49 }, { TWId, 0x53, 8, 50 },
+ { TWId, 0x54, 8, 51 }, { TWId, 0x55, 8, 52 }, { TWId, 0x24, 8, 53 },
+ { TWId, 0x25, 8, 54 }, { TWId, 0x58, 8, 55 }, { TWId, 0x59, 8, 56 },
+ { TWId, 0x5a, 8, 57 }, { TWId, 0x5b, 8, 58 }, { TWId, 0x4a, 8, 59 },
+ { TWId, 0x4b, 8, 60 }, { TWId, 0x32, 8, 61 }, { TWId, 0x33, 8, 62 },
+ { TWId, 0x34, 8, 63 }, { TWId, 0x00, 0, 0 }
+ };
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A S C I I 8 5 E n c o d e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ASCII85Encode encodes data in ASCII base-85 format. ASCII base-85
+% encoding produces five ASCII printing characters from every four bytes of
+% binary data.
+%
+% The format of the ASCII85Encode method is:
+%
+% void Ascii85Encode(Image *image,const unsigned long code)
+%
+% A description of each parameter follows:
+%
+% o code: a binary unsigned char to encode to ASCII 85.
+%
+% o file: write the encoded ASCII character to this file.
+%
+%
+*/
+#define MaxLineExtent 36
+
+static char *Ascii85Tuple(unsigned char *data)
+{
+ static char
+ tuple[6];
+
+ register long
+ i,
+ x;
+
+ unsigned long
+ code,
+ quantum;
+
+ code=((((unsigned long) data[0] << 8) | (unsigned long) data[1]) << 16) |
+ ((unsigned long) data[2] << 8) | (unsigned long) data[3];
+ if (code == 0L)
+ {
+ tuple[0]='z';
+ tuple[1]='\0';
+ return(tuple);
+ }
+ quantum=85UL*85UL*85UL*85UL;
+ for (i=0; i < 4; i++)
+ {
+ x=(long) (code/quantum);
+ code-=quantum*x;
+ tuple[i]=(char) (x+(int) '!');
+ quantum/=85L;
+ }
+ tuple[4]=(char) ((code % 85L)+(int) '!');
+ tuple[5]='\0';
+ return(tuple);
+}
+
+MagickExport void Ascii85Initialize(Image *image)
+{
+ /*
+ Allocate image structure.
+ */
+ if (image->ascii85 == (Ascii85Info *) NULL)
+ {
+ image->ascii85=MagickAllocateMemory(Ascii85Info *,sizeof(Ascii85Info));
+ if (image->ascii85 == (Ascii85Info *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateAscii85Info);
+ }
+ (void) memset(image->ascii85,0,sizeof(Ascii85Info));
+ image->ascii85->line_break=MaxLineExtent << 1;
+ image->ascii85->offset=0;
+}
+
+MagickExport void Ascii85Flush(Image *image)
+{
+ register char
+ *tuple;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->ascii85 != (Ascii85Info *) NULL);
+ if (image->ascii85->offset > 0)
+ {
+ image->ascii85->buffer[image->ascii85->offset]=0;
+ image->ascii85->buffer[image->ascii85->offset+1]=0;
+ image->ascii85->buffer[image->ascii85->offset+2]=0;
+ tuple=Ascii85Tuple(image->ascii85->buffer);
+ (void) WriteBlob(image,image->ascii85->offset+1,
+ *tuple == 'z' ? "!!!!" : tuple);
+ }
+ (void) WriteBlobByte(image,'~');
+ (void) WriteBlobByte(image,'>');
+ (void) WriteBlobByte(image,'\n');
+}
+
+MagickExport void Ascii85Encode(Image *image,const magick_uint8_t code)
+{
+ long
+ n;
+
+ register char
+ *q;
+
+ register unsigned char
+ *p;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->ascii85 != (Ascii85Info *) NULL);
+ image->ascii85->buffer[image->ascii85->offset]=code;
+ image->ascii85->offset++;
+ if (image->ascii85->offset < 4)
+ return;
+ p=image->ascii85->buffer;
+ for (n=image->ascii85->offset; n >= 4; n-=4)
+ {
+ for (q=Ascii85Tuple(p); *q; q++)
+ {
+ image->ascii85->line_break--;
+ if ((image->ascii85->line_break < 0) && (*q != '%'))
+ {
+ (void) WriteBlobByte(image,'\n');
+ image->ascii85->line_break=2*MaxLineExtent;
+ }
+ (void) WriteBlobByte(image,*q);
+ }
+ p+=8;
+ }
+ image->ascii85->offset=n;
+ p-=4;
+ for (n=0; n < 4; n++)
+ image->ascii85->buffer[n]=(*p++);
+}
+
+MagickExport unsigned int Ascii85WriteByteHook(Image *image,
+ const magick_uint8_t code, void *info)
+{
+ ARG_NOT_USED(info);
+ Ascii85Encode(image,code);
+ return(True);
+}
+
+MagickExport unsigned int BlobWriteByteHook(Image *image,
+ const magick_uint8_t code, void *info)
+{
+ ARG_NOT_USED(info);
+ return((unsigned int) WriteBlobByte(image,code));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H u f f m a n D e c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method HuffmanDecodeImage uncompresses an image via Huffman-coding.
+%
+% The format of the HuffmanDecodeImage method is:
+%
+% unsigned int HuffmanDecodeImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method HuffmanDecodeImage returns True if all the pixels are
+% compressed without error, otherwise False.
+%
+% o image: The image.
+%
+%
+*/
+#define HashSize 1021
+#define MBHashA 293
+#define MBHashB 2695
+#define MWHashA 3510
+#define MWHashB 1178
+
+#define InitializeHashTable(hash,table,a,b) \
+{ \
+ entry=table; \
+ while (entry->code != 0) \
+ { \
+ hash[((entry->length+a)*(entry->code+b)) % HashSize]=(HuffmanTable *) entry; \
+ entry++; \
+ } \
+}
+
+#define InputBit(bit) \
+{ \
+ if ((mask & 0xffU) == 0) \
+ { \
+ byte=ReadBlobByte(image); \
+ if (byte == EOF) \
+ break; \
+ mask=0x80U; \
+ } \
+ runlength++; \
+ bit=(((unsigned int) byte) & mask) ? 0x01U : 0x00U; \
+ mask >>= 1U; \
+ if (bit) \
+ runlength=0; \
+}
+
+MagickExport MagickPassFail HuffmanDecodeImage(Image *image)
+{
+ const HuffmanTable
+ *entry;
+
+ HuffmanTable
+ **mb_hash,
+ **mw_hash;
+
+ int
+ bail,
+ byte,
+ code,
+ color,
+ length,
+ null_lines,
+ runlength;
+
+ unsigned int
+ bit,
+ index,
+ mask;
+
+ long
+ count,
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ unsigned char
+ *scanline;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Allocate buffers.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ mb_hash=MagickAllocateMemory(HuffmanTable **,HashSize*sizeof(HuffmanTable *));
+ mw_hash=MagickAllocateMemory(HuffmanTable **,HashSize*sizeof(HuffmanTable *));
+ scanline=MagickAllocateMemory(unsigned char *,image->columns);
+ if ((mb_hash == (HuffmanTable **) NULL) ||
+ (mw_hash == (HuffmanTable **) NULL) ||
+ (scanline == (unsigned char *) NULL))
+ {
+ MagickFreeMemory(mw_hash);
+ MagickFreeMemory(mb_hash);
+ MagickFreeMemory(scanline);
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ }
+ /*
+ Initialize Huffman tables.
+ */
+ for (i=0; i < HashSize; i++)
+ {
+ mb_hash[i]=(HuffmanTable *) NULL;
+ mw_hash[i]=(HuffmanTable *) NULL;
+ }
+ InitializeHashTable(mw_hash,TWTable,MWHashA,MWHashB);
+ InitializeHashTable(mw_hash,MWTable,MWHashA,MWHashB);
+ InitializeHashTable(mw_hash,EXTable,MWHashA,MWHashB);
+ InitializeHashTable(mb_hash,TBTable,MBHashA,MBHashB);
+ InitializeHashTable(mb_hash,MBTable,MBHashA,MBHashB);
+ InitializeHashTable(mb_hash,EXTable,MBHashA,MBHashB);
+ /*
+ Uncompress 1D Huffman to runlength encoded pixels.
+ */
+ byte=0;
+ mask=0;
+ null_lines=0;
+ runlength=0;
+ while (runlength < 11)
+ InputBit(bit);
+ do
+ {
+ InputBit(bit);
+ } while (bit == 0);
+ image->x_resolution=204.0;
+ image->y_resolution=196.0;
+ image->units=PixelsPerInchResolution;
+ for (y=0; ((y < (long) image->rows) && (null_lines < 3)); )
+ {
+ /*
+ Initialize scanline to white.
+ */
+ p=scanline;
+ for (x=0; x < (long) image->columns; x++)
+ *p++=0;
+ /*
+ Decode Huffman encoded scanline.
+ */
+ color=True;
+ code=0;
+ count=0;
+ length=0;
+ runlength=0;
+ x=0;
+ for ( ; ; )
+ {
+ if (byte == EOF)
+ break;
+ if (x >= (long) image->columns)
+ {
+ while (runlength < 11)
+ InputBit(bit);
+ do { InputBit(bit); } while (bit == 0);
+ break;
+ }
+ bail=False;
+ do
+ {
+ if (runlength < 11)
+ InputBit(bit)
+ else
+ {
+ InputBit(bit);
+ if (bit)
+ {
+ null_lines++;
+ if (x != 0)
+ null_lines=0;
+ bail=True;
+ break;
+ }
+ }
+ code=(code << 1)+bit;
+ length++;
+ } while (code <= 0);
+ if (bail)
+ break;
+ if (length > 13)
+ {
+ while (runlength < 11)
+ InputBit(bit);
+ do
+ {
+ InputBit(bit);
+ } while (bit == 0);
+ break;
+ }
+ if (color)
+ {
+ if (length < 4)
+ continue;
+ entry=mw_hash[((length+MWHashA)*(code+MWHashB)) % HashSize];
+ }
+ else
+ {
+ if (length < 2)
+ continue;
+ entry=mb_hash[((length+MBHashA)*(code+MBHashB)) % HashSize];
+ }
+ if (!entry)
+ continue;
+ if ((entry->length != length) || (entry->code != code))
+ continue;
+ switch (entry->id)
+ {
+ case TWId:
+ case TBId:
+ {
+ count+=entry->count;
+ if ((x+count) > (long) image->columns)
+ count=(long) image->columns-x;
+ if (count > 0)
+ {
+ if (color)
+ {
+ x+=count;
+ count=0;
+ }
+ else
+ for ( ; count > 0; count--)
+ scanline[x++]=1;
+ }
+ color=!color;
+ break;
+ }
+ case MWId:
+ case MBId:
+ case EXId:
+ {
+ count+=entry->count;
+ break;
+ }
+ default:
+ break;
+ }
+ code=0;
+ length=0;
+ }
+ /*
+ Transfer scanline to image pixels.
+ */
+ p=scanline;
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=(unsigned int) (*p++);
+ indexes[x]=index;
+ *q++=image->colormap[index];
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ "[%s] Huffman decode image...",image->filename))
+ {
+ status=MagickFail;
+ break;
+ }
+ y++;
+ }
+ image->rows=Max(y-3,1);
+ image->compression=FaxCompression;
+ /*
+ Free decoder memory.
+ */
+ MagickFreeMemory(mw_hash);
+ MagickFreeMemory(mb_hash);
+ MagickFreeMemory(scanline);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H u f f m a n E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method HuffmanEncodeImage compresses an image via Huffman-coding.
+%
+% The format of the HuffmanEncodeImage method is:
+%
+% unsigned int HuffmanEncodeImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method HuffmanEncodeImage returns True if all the pixels are
+% compressed without error, otherwise False.
+%
+% o image_info: The image info..
+%
+% o image: The image.
+%
+*/
+#define HuffmanOutputCode(entry) \
+{ \
+ mask=1 << (entry->length-1); \
+ while (mask != 0) \
+ { \
+ OutputBit((entry->code & mask ? 1 : 0)); \
+ mask>>=1; \
+ } \
+}
+
+#define OutputBit(count) \
+{ \
+ if (count > 0) \
+ byte=byte | bit; \
+ bit >>= 1; \
+ if ((bit & 0xffU) == 0) \
+ { \
+ (void) (*write_byte)(image,(magick_uint8_t) byte,info); \
+ byte=0U; \
+ bit=0x80U; \
+ } \
+}
+MagickExport MagickPassFail HuffmanEncode2Image(const ImageInfo *image_info,
+ Image *image, WriteByteHook write_byte, void *info)
+{
+ const HuffmanTable
+ *entry;
+
+ int
+ k,
+ is_fax,
+ runlength;
+
+ long
+ n,
+ y;
+
+ Image
+ *huffman_image;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned char
+ *q;
+
+ register unsigned int
+ polarity;
+
+ unsigned int
+ bit,
+ byte;
+
+ unsigned char
+ *scanline;
+
+ unsigned long
+ mask,
+ width;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Allocate scanline buffer.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ is_fax=False;
+ if (LocaleCompare(image_info->magick,"FAX") == 0)
+ is_fax=True;
+ width=image->columns;
+ if (is_fax == True)
+ width=Max(image->columns,1728);
+ scanline=MagickAllocateMemory(unsigned char *,width+1);
+ if (scanline == (unsigned char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ huffman_image=CloneImage(image,0,0,True,&image->exception);
+ if (huffman_image == (Image *) NULL)
+ {
+ MagickFreeMemory(scanline);
+ return(MagickFail);
+ }
+ status &= SetImageType(huffman_image,BilevelType);
+ byte=0;
+ bit=0x80;
+ if (is_fax == True)
+ {
+ /*
+ End of line.
+ */
+ for (k=0; k < 11; k++)
+ OutputBit(0);
+ OutputBit(1);
+ }
+ /*
+ Compress runlength encoded to 1D Huffman pixels.
+ */
+ polarity=(PixelIntensity(&huffman_image->colormap[0]) < (MaxRGB/2));
+ if (huffman_image->colors == 2)
+ polarity=(PixelIntensityToQuantum(&huffman_image->colormap[0]) <
+ PixelIntensityToQuantum(&huffman_image->colormap[1]) ? 0x00 : 0x01);
+ q=scanline;
+ for (i=(long) width; i > 0; i--)
+ *q++=(unsigned char) polarity;
+ q=scanline;
+ for (y=0; y < (long) huffman_image->rows; y++)
+ {
+ p=AcquireImagePixels(huffman_image,0,y,huffman_image->columns,1,
+ &huffman_image->exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ indexes=AccessImmutableIndexes(huffman_image);
+ for (x=0; x < (long) huffman_image->columns; x++)
+ {
+ *q=(unsigned char) (indexes[x] == polarity ? !polarity : polarity);
+ q++;
+ }
+ /*
+ Huffman encode scanline.
+ */
+ q=scanline;
+ for (n=(long) width; n > 0; )
+ {
+ /*
+ Output white run.
+ */
+ for (runlength=0; ((n > 0) && (*q == polarity)); n--)
+ {
+ q++;
+ runlength++;
+ }
+ if (runlength >= 64)
+ {
+ if (runlength < 1792)
+ entry=MWTable+((runlength/64)-1);
+ else
+ entry=EXTable+(Min(runlength,2560)-1792)/64;
+ runlength-=entry->count;
+ HuffmanOutputCode(entry);
+ }
+ entry=TWTable+Min(runlength,63);
+ HuffmanOutputCode(entry);
+ if (n != 0)
+ {
+ /*
+ Output black run.
+ */
+ for (runlength=0; ((*q != polarity) && (n > 0)); n--)
+ {
+ q++;
+ runlength++;
+ }
+ if (runlength >= 64)
+ {
+ entry=MBTable+((runlength/64)-1);
+ if (runlength >= 1792)
+ entry=EXTable+(Min(runlength,2560)-1792)/64;
+ runlength-=entry->count;
+ HuffmanOutputCode(entry);
+ }
+ entry=TBTable+Min(runlength,63);
+ HuffmanOutputCode(entry);
+ }
+ }
+ /*
+ End of line.
+ */
+ for (k=0; k < 11; k++)
+ OutputBit(0);
+ OutputBit(1);
+ q=scanline;
+ if (huffman_image->previous == (Image *) NULL)
+ if (QuantumTick(y,huffman_image->rows))
+ if (!MagickMonitorFormatted(y,huffman_image->rows,&image->exception,
+ "[%s] Huffman encode image...",image->filename))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ /*
+ End of page.
+ */
+ for (i=0; i < 6; i++)
+ {
+ for (k=0; k < 11; k++)
+ OutputBit(0);
+ OutputBit(1);
+ }
+ /*
+ Flush bits.
+ */
+ if (bit != 0x80U)
+ (void) (*write_byte)(image,(magick_uint8_t)byte,info);
+ DestroyImage(huffman_image);
+ MagickFreeMemory(scanline);
+ return(status);
+}
+
+MagickExport MagickPassFail HuffmanEncodeImage(const ImageInfo *image_info,
+ Image *image)
+{
+ if (LocaleCompare(image_info->magick,"FAX") == 0)
+ {
+ return(HuffmanEncode2Image(image_info,image,BlobWriteByteHook,(void *)NULL));
+ }
+ else
+ {
+ MagickPassFail
+ status;
+ Ascii85Initialize(image);
+ status=HuffmanEncode2Image(image_info,image,Ascii85WriteByteHook,(void *)NULL);
+ Ascii85Flush(image);
+ return(status);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I m a g e T o H u f f m a n 2 D B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ImageToHuffman2DBlob compresses an image via two-dimensional
+% Huffman-coding (CCITT Group4 FAX) and returns the compressed data in a
+% heap allocated buffer. NULL is returned if there is an error.
+%
+% Data is output with one strip per page with MSB2LSB fill order.
+%
+% The format of the ImageToHuffman2DBlob method is:
+%
+% unsigned char *ImageToHuffman2DBlob(const Image *image,
+% const ImageInfo *image_info,
+% size_t *blob_length,
+% ExceptionInfo *exception);
+%
+% A description of each parameter follows:
+%
+% o image: The image to compress.
+%
+% o image_info: Image options
+%
+% o blob_length: Updated with the length of the compressed data.
+%
+% o exception: Any exception is reported here.
+%
+*/
+MagickExport unsigned char *
+ImageToHuffman2DBlob(const Image *image,const ImageInfo *image_info,
+ size_t *blob_length,ExceptionInfo *exception)
+{
+ unsigned char
+ *blob = (unsigned char *) NULL;
+
+ ImageInfo
+ *huffman_info;
+
+ ARG_NOT_USED(image_info);
+ *blob_length=0;
+ huffman_info=CloneImageInfo((const ImageInfo *) NULL);
+ if (huffman_info != (ImageInfo *) NULL)
+ {
+ Image
+ *huffman_image;
+
+ huffman_image=CloneImage(image,0,0,MagickTrue,exception);
+ if (huffman_image != (Image *) NULL)
+ {
+ (void) strlcpy(huffman_image->magick,"GROUP4RAW",sizeof(huffman_image->magick));
+ (void) strlcpy(huffman_image->filename,"",sizeof(huffman_image->filename));
+ blob=ImageToBlob(huffman_info, huffman_image, blob_length, exception);
+ DestroyImage(huffman_image);
+ }
+ DestroyImageInfo(huffman_info);
+ }
+ return blob;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I m a g e T o J P E G B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ImageToJPEGBlob compresses an image into a JFIF JPEG format and
+% returns the compressed data in a heap allocated buffer. NULL is
+% returned if there is an error.
+%
+% The format of the ImageToJPEGBlob method is:
+%
+% unsigned char *ImageToJPEGBlob(const Image *image,
+% const ImageInfo *image_info,
+% size_t *blob_length,
+% ExceptionInfo *exception);
+%
+% A description of each parameter follows:
+%
+% o image: The image to compress.
+%
+% o image_info: Image options
+%
+% o blob_length: Updated with the length of the compressed data.
+%
+% o exception: Any exception is reported here.
+%
+*/
+MagickExport unsigned char *
+ImageToJPEGBlob(const Image *image,const ImageInfo *image_info,
+ size_t *blob_length,ExceptionInfo *exception)
+{
+ unsigned char
+ *blob = NULL;
+
+ ImageInfo
+ *jpeg_info;
+
+ *blob_length=0;
+ jpeg_info=CloneImageInfo(image_info);
+ if (jpeg_info != (ImageInfo *) NULL)
+ {
+ Image
+ *jpeg_image;
+
+ /*
+ Try to preserve any existing JPEG options but if the user
+ applies any override, then existing JPEG options are ignored.
+ */
+ if ((JPEGCompression == image->compression) &&
+ (DefaultCompressionQuality == image_info->quality) &&
+ ((char *) NULL == jpeg_info->sampling_factor))
+ (void) AddDefinitions(jpeg_info,"jpeg:preserve-settings=TRUE",
+ exception);
+ jpeg_image=CloneImage(image,0,0,MagickTrue,exception);
+ if (jpeg_image != (Image *) NULL)
+ {
+ (void) strlcpy(jpeg_image->magick,"JPEG",sizeof(jpeg_image->magick));
+ (void) strlcpy(jpeg_image->filename,"",sizeof(jpeg_image->filename));
+ blob =(unsigned char *) ImageToBlob(jpeg_info, jpeg_image, blob_length, exception);
+ DestroyImage(jpeg_image);
+ }
+ DestroyImageInfo(jpeg_info);
+ }
+ return blob;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L Z W E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method LZWEncodeImage compresses an image via LZW-coding specific to
+% Postscript Level II or Portable Document Format. To ensure portability, the
+% binary LZW bytes are encoded as ASCII base-85.
+%
+% The format of the LZWEncodeImage method is:
+%
+% unsigned int LZWEncodeImage(Image *image,const size_t length,
+% unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method LZWEncodeImage returns True if all the pixels are
+% compressed without error, otherwise False.
+%
+% o image: The image.
+%
+% o length: A value that specifies the number of pixels to compress.
+%
+% o pixels: The address of an unsigned array of characters containing the
+% pixels to compress.
+%
+%
+*/
+#define LZWClr 256 /* Clear Table Marker */
+#define LZWEod 257 /* End of Data marker */
+#define OutputCode(code) \
+{ \
+ accumulator+=((long) code) << (32-code_width-number_bits); \
+ number_bits+=code_width; \
+ while (number_bits >= 8) \
+ { \
+ (void) (*write_byte)(image,(magick_uint8_t) (accumulator >> 24),info); \
+ accumulator=accumulator << 8; \
+ number_bits-=8; \
+ } \
+}
+
+MagickExport MagickPassFail LZWEncode2Image(Image *image,
+ const size_t length,magick_uint8_t *pixels,WriteByteHook write_byte,void *info)
+{
+ typedef struct _TableType
+ {
+ short
+ prefix,
+ suffix,
+ next;
+ } TableType;
+
+ int
+ index;
+
+ register long
+ i;
+
+ short
+ number_bits,
+ code_width,
+ last_code,
+ next_index;
+
+ TableType
+ *table;
+
+ unsigned long
+ accumulator;
+
+ /*
+ Allocate string table.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(pixels != (unsigned char *) NULL);
+ table=MagickAllocateMemory(TableType *,(1 << 12)*sizeof(TableType));
+ if (table == (TableType *) NULL)
+ return(False);
+ /*
+ Initialize variables.
+ */
+ accumulator=0;
+ code_width=9;
+ number_bits=0;
+ last_code=0;
+ OutputCode(LZWClr);
+ for (index=0; index < 256; index++)
+ {
+ table[index].prefix=(-1);
+ table[index].suffix=index;
+ table[index].next=(-1);
+ }
+ next_index=LZWEod+1;
+ code_width=9;
+ last_code=pixels[0];
+ for (i=1; i < (long) length; i++)
+ {
+ /*
+ Find string.
+ */
+ index=last_code;
+ while (index != -1)
+ if ((table[index].prefix != last_code) ||
+ (table[index].suffix != pixels[i]))
+ index=table[index].next;
+ else
+ {
+ last_code=index;
+ break;
+ }
+ if (last_code != index)
+ {
+ /*
+ Add string.
+ */
+ OutputCode(last_code);
+ table[next_index].prefix=last_code;
+ table[next_index].suffix=pixels[i];
+ table[next_index].next=table[last_code].next;
+ table[last_code].next=next_index;
+ next_index++;
+ /*
+ Did we just move up to next bit width?
+ */
+ if ((next_index >> code_width) != 0)
+ {
+ code_width++;
+ if (code_width > 12)
+ {
+ /*
+ Did we overflow the max bit width?
+ */
+ code_width--;
+ OutputCode(LZWClr);
+ for (index=0; index < 256; index++)
+ {
+ table[index].prefix=(-1);
+ table[index].suffix=index;
+ table[index].next=(-1);
+ }
+ next_index=LZWEod+1;
+ code_width=9;
+ }
+ }
+ last_code=pixels[i];
+ }
+ }
+ /*
+ Flush tables.
+ */
+ OutputCode(last_code);
+ OutputCode(LZWEod);
+ if (number_bits != 0)
+ (void) (*write_byte)(image,(magick_uint8_t)(accumulator >> 24),info);
+ MagickFreeMemory(table);
+ return(MagickPass);
+}
+
+MagickExport MagickPassFail LZWEncodeImage(Image *image, const size_t length,
+ magick_uint8_t *pixels)
+{
+ return(LZWEncode2Image(image,length,pixels,BlobWriteByteHook,(void *)NULL));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P a c k b i t s E n c o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method PackbitsEncodeImage compresses an image via Macintosh Packbits
+% encoding specific to Postscript Level II or Portable Document Format. To
+% ensure portability, the binary Packbits bytes are encoded as ASCII Base-85.
+%
+% The format of the PackbitsEncodeImage method is:
+%
+% unsigned int PackbitsEncodeImage(Image *image,const size_t length,
+% unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o status: Method PackbitsEncodeImage returns True if all the pixels are
+% compressed without error, otherwise False.
+%
+% o image: The image.
+%
+% o length: A value that specifies the number of pixels to compress.
+%
+% o pixels: The address of an unsigned array of characters containing the
+% pixels to compress.
+%
+%
+*/
+MagickExport MagickPassFail PackbitsEncode2Image(Image *image,
+ const size_t length,magick_uint8_t *pixels,WriteByteHook write_byte,
+ void *info)
+{
+ int
+ count;
+
+ register int
+ i,
+ j;
+
+ unsigned char
+ *packbits;
+
+ /*
+ Compress pixels with Packbits encoding.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(pixels != (unsigned char *) NULL);
+ packbits=MagickAllocateMemory(unsigned char *,128);
+ if (packbits == (unsigned char *) NULL)
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ i=(long) length;
+ while (i != 0)
+ {
+ switch (i)
+ {
+ case 1:
+ {
+ i--;
+ (void) (*write_byte)(image,(magick_uint8_t)0,info);
+ (void) (*write_byte)(image,(magick_uint8_t)*pixels,info);
+ break;
+ }
+ case 2:
+ {
+ i-=2;
+ (void) (*write_byte)(image,(magick_uint8_t)1,info);
+ (void) (*write_byte)(image,(magick_uint8_t)*pixels,info);
+ (void) (*write_byte)(image,(magick_uint8_t)pixels[1],info);
+ break;
+ }
+ case 3:
+ {
+ i-=3;
+ if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
+ {
+ (void) (*write_byte)(image,(magick_uint8_t)((256-3)+1),info);
+ (void) (*write_byte)(image,(magick_uint8_t)*pixels,info);
+ break;
+ }
+ (void) (*write_byte)(image,(magick_uint8_t)2,info);
+ (void) (*write_byte)(image,(magick_uint8_t)*pixels,info);
+ (void) (*write_byte)(image,(magick_uint8_t)pixels[1],info);
+ (void) (*write_byte)(image,(magick_uint8_t)pixels[2],info);
+ break;
+ }
+ default:
+ {
+ if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
+ {
+ /*
+ Packed run.
+ */
+ count=3;
+ while (((long) count < i) && (*pixels == *(pixels+count)))
+ {
+ count++;
+ if (count >= 127)
+ break;
+ }
+ i-=count;
+ (void) (*write_byte)(image,(magick_uint8_t)((256-count)+1),info);
+ (void) (*write_byte)(image,(magick_uint8_t)*pixels,info);
+ pixels+=count;
+ break;
+ }
+ /*
+ Literal run.
+ */
+ count=0;
+ while ((*(pixels+count) != *(pixels+count+1)) ||
+ (*(pixels+count+1) != *(pixels+count+2)))
+ {
+ packbits[count+1]=pixels[count];
+ count++;
+ if (((long) count >= (i-3)) || (count >= 127))
+ break;
+ }
+ i-=count;
+ *packbits=count-1;
+ for (j=0; j <= (long) count; j++)
+ (void) (*write_byte)(image,(magick_uint8_t)packbits[j],info);
+ pixels+=count;
+ break;
+ }
+ }
+ }
+ (void) (*write_byte)(image,(magick_uint8_t)128,info); /* EOD marker */
+ MagickFreeMemory(packbits);
+ return(MagickPass);
+}
+
+MagickExport MagickPassFail PackbitsEncodeImage(Image *image,const size_t length,
+ magick_uint8_t *pixels)
+{
+ return(PackbitsEncode2Image(image,length,pixels,BlobWriteByteHook,(void *)NULL));
+}
diff --git a/magick/compress.h b/magick/compress.h
new file mode 100644
index 0000000..2d0046a
--- /dev/null
+++ b/magick/compress.h
@@ -0,0 +1,83 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Image Compression/Decompression Methods.
+*/
+#ifndef _MAGICK_COMPRESS_H
+#define _MAGICK_COMPRESS_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Typedef declaration.
+*/
+typedef struct _Ascii85Info
+{
+ long
+ offset,
+ line_break;
+
+ magick_uint8_t
+ buffer[10];
+} Ascii85Info;
+
+/*
+ TODO: Clean up the interface between BLOB write functions,
+ compression functions, and encoding functions so they
+ may be hooked into/stacked on top of each other. Most are
+ (or can be changed to be) stream based.
+*/
+typedef unsigned int
+ (*WriteByteHook)(Image *, const magick_uint8_t, void *info);
+
+/*
+ Commonly used byte writer hooks.
+*/
+extern MagickExport unsigned int
+ Ascii85WriteByteHook(Image *image, const magick_uint8_t code, void *info),
+ BlobWriteByteHook(Image *image, const magick_uint8_t code, void *info);
+
+/*
+ Compress methods.
+*/
+extern MagickExport MagickPassFail
+ HuffmanDecodeImage(Image *image),
+ HuffmanEncodeImage(const ImageInfo *image_info,Image *image),
+ HuffmanEncode2Image(const ImageInfo *image_info,Image *image,WriteByteHook write_byte,void *info),
+ LZWEncodeImage(Image *image,const size_t length,magick_uint8_t *pixels),
+ LZWEncode2Image(Image *image,const size_t length,magick_uint8_t *pixels,WriteByteHook write_byte,void *info),
+ PackbitsEncodeImage(Image *image,const size_t length,magick_uint8_t *pixels),
+ PackbitsEncode2Image(Image *image,const size_t length,magick_uint8_t *pixels,WriteByteHook write_byte,void *info);
+
+extern MagickExport unsigned char
+ *ImageToHuffman2DBlob(const Image *image,const ImageInfo *image_info,
+ size_t *length,ExceptionInfo *exception),
+ *ImageToJPEGBlob(const Image *image,const ImageInfo *image_info,
+ size_t *length,ExceptionInfo *exception);
+
+extern MagickExport void
+ Ascii85Encode(Image *image,const magick_uint8_t code),
+ Ascii85Flush(Image *image),
+ Ascii85Initialize(Image *image);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/confirm_access.c b/magick/confirm_access.c
new file mode 100644
index 0000000..dbc6db3
--- /dev/null
+++ b/magick/confirm_access.c
@@ -0,0 +1,111 @@
+/*
+% Copyright (C) 2009 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/confirm_access.h"
+#include "magick/utility.h"
+
+/*
+ Global declarations.
+*/
+static ConfirmAccessHandler
+ confirm_access_handler = (ConfirmAccessHandler) NULL;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o n f i r m A c c e s s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickConfirmAccess() calls the access confirmation handler method with
+% parameters which describe the requested access mode and path/URL, as well
+% as an ExceptionInfo structure to update with any error information. A
+% user-provided callback (set by MagickSetConfirmAccessHandler()) is
+% invoked. If the callback returns MagickFail, then this function also
+% returns MagickFail, which is intended to determine if the operation may
+% continue. The callback is expected to report the reason access is denied
+% by filling out the ExceptionInfo structure. If the callback fails to do
+% so, then a generic "access denied" error is reported.
+%
+% The format of the MagickConfirmAccess method is:
+%
+% MagickPassFail MagickConfirmAccess(const ConfirmAccessMode mode,
+% const char *path,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o mode: The type of access to be performed.
+%
+% o path: The local path or URL requested to be accessed.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickPassFail
+MagickConfirmAccess(const ConfirmAccessMode mode,
+ const char *path,
+ ExceptionInfo *exception)
+{
+ MagickPassFail
+ status;
+
+ assert(path != (const char *) NULL);
+ status=MagickPass;
+ if (confirm_access_handler != (ConfirmAccessHandler) NULL)
+ status=(*confirm_access_handler)(mode,path,exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t C o n f i r m A c c e s s H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetConfirmAccessHandler() sets the access confirmation handler to
+% the specified method and returns the previous access confirmation handler.
+% This access confirmation handler is used to "approve" access to files and
+% URLs. If the handler returns MagickFalse, then access is denied. This
+% mechanism may be used to enforce security policies and/or may be used to
+% monitor file and URL accesses.
+%
+% The format of the MagickSetConfirmAccessHandler method is:
+%
+% ConfirmAccessHandler MagickSetConfirmAccessHandler(ConfirmAccessHandler handler)
+%
+% A description of each parameter follows:
+%
+% o handler: Specifies a pointer to a method to handle access confirmation.
+%
+%
+*/
+MagickExport ConfirmAccessHandler
+MagickSetConfirmAccessHandler(ConfirmAccessHandler handler)
+{
+ ConfirmAccessHandler
+ previous_handler;
+
+ previous_handler=confirm_access_handler;
+ confirm_access_handler=handler;
+ return(previous_handler);
+}
diff --git a/magick/confirm_access.h b/magick/confirm_access.h
new file mode 100644
index 0000000..721f824
--- /dev/null
+++ b/magick/confirm_access.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2009 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Access Confirmation Methods.
+*/
+#ifndef _MAGICK_CONFIRM_ACCESS_H
+#define _MAGICK_CONFIRM_ACCESS_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ typedef enum
+ {
+ UndefinedConfirmAccessMode,
+ FileExecuteConfirmAccessMode, /* Path is to be opened for execution */
+ FileReadConfirmAccessMode, /* Path is to be opened for read */
+ FileWriteConfirmAccessMode, /* Path is to be opened for write */
+ URLGetFTPConfirmAccessMode, /* ftp:// URL get */
+ URLGetFileConfirmAccessMode, /* file:// URL get */
+ URLGetHTTPConfirmAccessMode /* http:// URL get */
+ } ConfirmAccessMode;
+
+ typedef MagickPassFail
+ (*ConfirmAccessHandler)(const ConfirmAccessMode mode,
+ const char *path,
+ ExceptionInfo *exception);
+
+ extern MagickExport MagickPassFail
+ MagickConfirmAccess(const ConfirmAccessMode mode,
+ const char *path,
+ ExceptionInfo *exception);
+
+ extern MagickExport ConfirmAccessHandler
+ MagickSetConfirmAccessHandler(ConfirmAccessHandler handler);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_CONFIRM_ACCESS_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/constitute.c b/magick/constitute.c
new file mode 100644
index 0000000..07b8424
--- /dev/null
+++ b/magick/constitute.c
@@ -0,0 +1,2464 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% CCCC OOO N N SSSSS TTTTT IIIII TTTTT U U TTTTT EEEEE %
+% C O O NN N SS T I T U U T E %
+% C O O N N N ESSS T I T U U T EEE %
+% C O O N NN SS T I T U U T E %
+% CCCC OOO N N SSSSS T IIIII T UUU T EEEEE %
+% %
+% %
+% Methods to Constitute an Image %
+% %
+% %
+% Software Design %
+% John Cristy %
+% October 1998 %
+% %
+% Re-implemented By %
+% Bob Friesenhahn %
+% 2003-2008 %
+% %
+% Small Float Support By %
+% Richard Nolde %
+% December, 2008 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/describe.h"
+#include "magick/enum_strings.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/semaphore.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+ Type definitions
+*/
+typedef enum
+{
+ BlueMapQuanum,
+ GreenMapQuantum,
+ IntensityMapQuantum,
+ TransparencyMapQuantum,
+ PadMapQuantum,
+ RedMapQuantum,
+ OpacityMapQuantum
+} MapQuantumType;
+
+typedef enum {
+ UndefinedDispatchType,
+ BGRDispatchType,
+ BGRADispatchType,
+ BGRPDispatchType,
+ RGBDispatchType,
+ RGBADispatchType,
+ IDispatchType
+} DispatchType;
+
+static SemaphoreInfo
+ *constitute_semaphore = (SemaphoreInfo *) NULL;
+
+/*
+ Forward declarations.
+*/
+static Image
+ *ReadImages(const ImageInfo *,ExceptionInfo *);
+
+
+/*
+ Macros
+*/
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o n s t i t u t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ConstituteImage() returns an Image corresponding to an image stored
+% in a raw memory array format. The pixel data must be in scanline order
+% top-to-bottom. The data can be unsigned char, unsigned short int, unsigned
+% int, unsigned long, float, or double. Float and double require the pixels
+% to be normalized to the range [0..1], otherwise the range is [0..MaxVal]
+% where MaxVal is the maximum possible value for that type.
+%
+% Note that for most 32-bit architectures the size of an unsigned long is
+% the same as unsigned int, but for 64-bit architectures observing the LP64
+% standard, an unsigned long is 64 bits, while an unsigned int remains 32
+% bits. This should be considered when deciding if the data should be
+% described as "Integer" or "Long".
+%
+% For example, to create a 640x480 image from unsigned red-green-blue
+% character data, use
+%
+% image=ConstituteImage(640,480,"RGB",CharPixel,pixels,&exception);
+%
+% The format of the Constitute method is:
+%
+% Image *ConstituteImage(const unsigned long width,
+% const unsigned long height,const char *map,const StorageType type,
+% const void *pixels,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o width: width in pixels of the image.
+%
+% o height: height in pixels of the image.
+%
+% o map: This string reflects the expected ordering of the pixel array.
+% It can be any combination or order of R = red, G = green, B = blue,
+% A = alpha (same as Transparency), O = Opacity, T = Transparency,
+% C = cyan, Y = yellow, M = magenta, K = black, or I = intensity
+% (for grayscale). Specify "P" = pad, to skip over a quantum which is
+% intentionally ignored. Creation of an alpha channel for CMYK images
+% is currently not supported.
+%
+% o type: Define the data type of the pixels. Float and double types are
+% expected to be normalized [0..1] otherwise [0..MaxRGB]. Choose from
+% these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
+% or DoublePixel.
+%
+% o pixels: This array of values contain the pixel components as defined by
+% map and type. You must preallocate this array where the expected
+% length varies depending on the values of width, height, map, and type.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+MagickExport Image *ConstituteImage(const unsigned long width,
+ const unsigned long height,const char *map,const StorageType type,
+ const void *pixels,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ long
+ y;
+
+ PixelPacket
+ * restrict q;
+
+ register Quantum
+ quantum;
+
+ MapQuantumType
+ switch_map[MaxTextExtent/sizeof(MapQuantumType)];
+
+ register IndexPacket
+ * restrict indexes;
+
+ register long
+ i,
+ x;
+
+ size_t
+ length;
+
+ /*
+ Allocate image structure.
+ */
+ assert(pixels != (void *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ /* SetExceptionInfo(exception,UndefinedException); */
+ image=AllocateImage((ImageInfo *) NULL);
+ if (image == (Image *) NULL)
+ return((Image *) NULL);
+ if ((width == 0) || (height == 0))
+ ThrowBinaryException3(OptionError,UnableToConstituteImage,
+ NonzeroWidthAndHeightRequired);
+ image->columns=width;
+ image->rows=height;
+
+ /*
+ Handle a few common special cases in order to improve performance.
+ */
+ if (type == CharPixel)
+ {
+ DispatchType
+ dispatch_type=UndefinedDispatchType;
+
+ if (LocaleCompare(map,"BGR") == 0)
+ dispatch_type=BGRDispatchType;
+ else if (LocaleCompare(map,"BGRA") == 0)
+ dispatch_type=BGRADispatchType;
+ else if (LocaleCompare(map,"BGRP") == 0)
+ dispatch_type=BGRPDispatchType;
+ else if (LocaleCompare(map,"RGB") == 0)
+ dispatch_type=RGBDispatchType;
+ else if (LocaleCompare(map,"RGBA") == 0)
+ dispatch_type=RGBADispatchType;
+ else if (LocaleCompare(map,"I") == 0)
+ {
+ if (!AllocateImageColormap(image,MaxColormapSize))
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToConstituteImage);
+ dispatch_type=IDispatchType;
+ }
+
+ if (dispatch_type != UndefinedDispatchType)
+ {
+ register const unsigned char
+ * restrict p = (const unsigned char*) pixels;
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+
+ switch (dispatch_type)
+ {
+ case BGRDispatchType:
+ {
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ SetBlueSample(q,ScaleCharToQuantum(*p++));
+ SetGreenSample(q,ScaleCharToQuantum(*p++));
+ SetRedSample(q,ScaleCharToQuantum(*p++));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case BGRADispatchType:
+ {
+ image->matte=True;
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ SetBlueSample(q,ScaleCharToQuantum(*p++));
+ SetGreenSample(q,ScaleCharToQuantum(*p++));
+ SetRedSample(q,ScaleCharToQuantum(*p++));
+ SetOpacitySample(q,(Quantum) MaxRGB-ScaleCharToQuantum(*p++));
+ q++;
+ }
+ break;
+ }
+ case BGRPDispatchType:
+ {
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ SetBlueSample(q,ScaleCharToQuantum(*p++));
+ SetGreenSample(q,ScaleCharToQuantum(*p++));
+ SetRedSample(q,ScaleCharToQuantum(*p++));
+ p++;
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case RGBDispatchType:
+ {
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ SetRedSample(q,ScaleCharToQuantum(*p++));
+ SetGreenSample(q,ScaleCharToQuantum(*p++));
+ SetBlueSample(q,ScaleCharToQuantum(*p++));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case RGBADispatchType:
+ {
+ image->matte=True;
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ SetRedSample(q,ScaleCharToQuantum(*p++));
+ SetGreenSample(q,ScaleCharToQuantum(*p++));
+ SetBlueSample(q,ScaleCharToQuantum(*p++));
+ SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(*p++));
+ q++;
+ }
+ break;
+ }
+ case IDispatchType:
+ {
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ *indexes=ScaleQuantumToIndex(ScaleCharToQuantum(*p++));
+ SetGraySample(q,image->colormap[*indexes].red);
+ SetOpacitySample(q,OpaqueOpacity);
+ indexes++;
+ q++;
+ }
+ break;
+ }
+#if !defined(__COVERITY__)
+ case UndefinedDispatchType:
+ {
+ break;
+ }
+#else
+ default:
+ {
+ break;
+ }
+#endif
+ } /* end switch */
+ if (!SyncImagePixels(image))
+ break;
+ } /* end for (y=0; y < (long) image->rows; y++) */
+ if (dispatch_type == IDispatchType)
+ {
+ (void) IsMonochromeImage(image,exception);
+ image->is_grayscale=True;
+ }
+ return (image);
+ } /* end if (dispatch_type != UndefinedDispatchType) */
+ } /* end if (type == CharPixel) */
+
+ /*
+ Prepare a validated and more efficient version of the map.
+ */
+ length=strlen(map);
+ length=Min(length,sizeof(switch_map)/sizeof(MapQuantumType));
+ for (i=0; i < (long) length; i++)
+ {
+ switch ((int) toupper((int) map[i]))
+ {
+ case 'R':
+ {
+ switch_map[i]=RedMapQuantum;
+ break;
+ }
+ case 'G':
+ {
+ switch_map[i]=GreenMapQuantum;
+ break;
+ }
+ case 'B':
+ {
+ switch_map[i]=BlueMapQuanum;
+ break;
+ }
+ case 'A':
+ {
+ switch_map[i]=TransparencyMapQuantum;
+ image->matte=True;
+ break;
+ }
+ case 'C':
+ {
+ image->colorspace=CMYKColorspace;
+ switch_map[i]=RedMapQuantum;
+ break;
+ }
+ case 'M':
+ {
+ image->colorspace=CMYKColorspace;
+ switch_map[i]=GreenMapQuantum;
+ break;
+ }
+ case 'Y':
+ {
+ image->colorspace=CMYKColorspace;
+ switch_map[i]=BlueMapQuanum;
+ break;
+ }
+ case 'K':
+ {
+ image->colorspace=CMYKColorspace;
+ switch_map[i]=OpacityMapQuantum;
+ break;
+ }
+ case 'I':
+ {
+ if (!AllocateImageColormap(image,MaxColormapSize))
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToConstituteImage);
+ switch_map[i]=IntensityMapQuantum;
+ break;
+ }
+ case 'O':
+ {
+ switch_map[i]=OpacityMapQuantum;
+ image->matte=True;
+ break;
+ }
+ case 'P':
+ {
+ switch_map[i]=PadMapQuantum;
+ break;
+ }
+ case 'T':
+ {
+ switch_map[i]=TransparencyMapQuantum;
+ image->matte=True;
+ break;
+ }
+ default:
+ {
+ DestroyImage(image);
+ ThrowImageException(OptionError,UnrecognizedPixelMap,map)
+ }
+ }
+ }
+
+ /*
+ Transfer the pixels from the pixel data array to the image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ SetRedSample(q,0);
+ SetGreenSample(q,0);
+ SetBlueSample(q,0);
+ if (image->colorspace == CMYKColorspace)
+ {
+ SetBlackSample(q,0);
+ *indexes=OpaqueOpacity;
+ }
+ else
+ {
+ SetOpacitySample(q,OpaqueOpacity);
+ }
+ for (i=0; i < (long) length; i++)
+ {
+ /*
+ Input a quantum
+ */
+ quantum=0U;
+
+ switch (type)
+ {
+ case CharPixel:
+ {
+ register const unsigned char *p = (const unsigned char*) pixels;
+ quantum=ScaleCharToQuantum(*p++);
+ pixels = (const void *) p;
+ break;
+ }
+ case ShortPixel:
+ {
+ register const unsigned short *p = (const unsigned short*) pixels;
+ quantum=ScaleShortToQuantum(*p++);
+ pixels = (const void *) p;
+ break;
+ }
+ case IntegerPixel:
+ {
+ register const unsigned int *p = (const unsigned int*) pixels;
+ quantum=ScaleLongToQuantum(*p++);
+ pixels = (const void *) p;
+ break;
+ }
+ case LongPixel:
+ {
+ register const unsigned long *p = (const unsigned long*) pixels;
+ quantum=ScaleLongToQuantum(*p++);
+ pixels = (const void *) p;
+ break;
+ }
+ case FloatPixel:
+ {
+ double quantum_float;
+ register const float *p = (const float*) pixels;
+ quantum_float=(double) MaxRGB*(*p++);
+ quantum=RoundDoubleToQuantum(quantum_float);
+ pixels = (const void *) p;
+ break;
+ }
+ case DoublePixel:
+ {
+ double quantum_float;
+ register const double *p = (const double*) pixels;
+ quantum_float=(double) MaxRGB*(*p++);
+ quantum=RoundDoubleToQuantum(quantum_float);
+ pixels = (const void *) p;
+ break;
+ }
+ }
+
+ /*
+ Transfer quantum to image
+ */
+ switch (switch_map[i])
+ {
+ case RedMapQuantum:
+ {
+ SetRedSample(q,quantum);
+ break;
+ }
+ case GreenMapQuantum:
+ {
+ SetGreenSample(q,quantum);
+ break;
+ }
+ case BlueMapQuanum:
+ {
+ SetBlueSample(q,quantum);
+ break;
+ }
+ case OpacityMapQuantum:
+ {
+ SetOpacitySample(q,quantum);
+ break;
+ }
+ case TransparencyMapQuantum:
+ {
+ SetOpacitySample(q,MaxRGB-quantum);
+ break;
+ }
+ case IntensityMapQuantum:
+ {
+ *indexes=ScaleQuantumToIndex(quantum);
+ SetGraySample(q,image->colormap[*indexes].red);
+ break;
+ }
+ case PadMapQuantum:
+ {
+ /* Discard quantum */
+ break;
+ }
+ }
+ }
+ indexes++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Check and cache monochrome and grayscale status
+ */
+ (void) IsMonochromeImage(image,exception);
+ if (image->is_monochrome)
+ image->is_grayscale=True;
+ else
+ (void) IsGrayImage(image,exception);
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y C o n s t i t u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyConstitute() destroys the constitute environment.
+%
+% The format of the DestroyConstitute method is:
+%
+% DestroyConstitute(void)
+%
+%
+*/
+MagickExport void DestroyConstitute(void)
+{
+ DestroySemaphoreInfo(&constitute_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D i s p a t c h I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DispatchImage() extracts pixel data from an Image into a raw memory array.
+% The pixel data is written in scanline order top-to-bottom using an
+% arbitrary quantum order specified by 'map', and with quantum size
+% specified by 'type'.
+%
+% The output array data may be unsigned char, unsigned short int, unsigned
+% int, unsigned long, float, or double. Float and double require the pixels
+% to be normalized to the range [0..1], otherwise the range is [0..MaxVal]
+% where MaxVal is the maximum possible value for that type.
+%
+% The method returns MagickPass on success or MagickFail if an error is
+% encountered.
+%
+% Suppose we want want to extract the first scanline of a 640x480 image as
+% character data in red-green-blue order:
+%
+% DispatchImage(image,0,0,640,1,"RGB",0,pixels,exception);
+%
+% The format of the DispatchImage method is:
+%
+% MagickPassFail DispatchImage(const Image *image,const long x_offset,
+% const long y_offset,const unsigned long columns,
+% const unsigned long rows,const char *map,const StorageType type,
+% void *pixels,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o x_offset, y_offset, columns, rows: These values define the perimeter
+% of a region of pixels you want to extract.
+%
+% o map: This string reflects the expected ordering of the pixel array.
+% It can be any combination or order of R = red, G = green, B = blue,
+% A = alpha (same as Transparency), O = Opacity, T = Transparency,
+% C = cyan, Y = yellow, M = magenta, K = black, I = intensity (for
+% grayscale). Specify "P" = pad, to output a pad quantum. Pad quantums
+% are zero-value.
+%
+% o type: Define the data type of the pixels. Float and double types are
+% expected to be normalized [0..1] otherwise [0..MaxRGB]. Choose from
+% these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
+% or DoublePixel.
+%
+% o pixels: This array of values contain the pixel components as defined by
+% map and type. You must preallocate this array where the expected
+% length varies depending on the values of width, height, map, and type.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail DispatchImage(const Image *image,const long x_offset,
+ const long y_offset,const unsigned long columns,const unsigned long rows,
+ const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
+{
+ long
+ y;
+
+ register long
+ i,
+ x;
+
+ register const PixelPacket
+ * restrict p;
+
+ register Quantum
+ quantum;
+
+ MapQuantumType
+ switch_map[MaxTextExtent/sizeof(MapQuantumType)];
+
+ size_t
+ length;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ /*
+ Handle a few common special cases in order to improve performance.
+ */
+ if (type == CharPixel)
+ {
+ DispatchType
+ dispatch_type=UndefinedDispatchType;
+
+ if (LocaleCompare(map,"BGR") == 0)
+ dispatch_type=BGRDispatchType;
+ else if (LocaleCompare(map,"BGRA") == 0)
+ dispatch_type=BGRADispatchType;
+ else if (LocaleCompare(map,"BGRP") == 0)
+ dispatch_type=BGRPDispatchType;
+ else if (LocaleCompare(map,"RGB") == 0)
+ dispatch_type=RGBDispatchType;
+ else if (LocaleCompare(map,"RGBA") == 0)
+ dispatch_type=RGBADispatchType;
+ else if (LocaleCompare(map,"I") == 0)
+ dispatch_type=IDispatchType;
+
+ if (dispatch_type != UndefinedDispatchType)
+ {
+ register unsigned char
+ * restrict q = (unsigned char*) pixels;
+
+ for (y=0; y < (long) rows; y++)
+ {
+ p=AcquireImagePixels(image,x_offset,y_offset+y,columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+
+ switch (dispatch_type)
+ {
+ case BGRDispatchType:
+ {
+ for (x=(long) columns; x != 0; x--)
+ {
+ *q++=ScaleQuantumToChar(GetBlueSample(p));
+ *q++=ScaleQuantumToChar(GetGreenSample(p));
+ *q++=ScaleQuantumToChar(GetRedSample(p));
+ p++;
+ }
+ break;
+ }
+ case BGRADispatchType:
+ {
+ for (x=(long) columns; x != 0; x--)
+ {
+ *q++=ScaleQuantumToChar(GetBlueSample(p));
+ *q++=ScaleQuantumToChar(GetGreenSample(p));
+ *q++=ScaleQuantumToChar(GetRedSample(p));
+ *q++=ScaleQuantumToChar(MaxRGB-GetOpacitySample(p));
+ p++;
+ }
+ break;
+ }
+ case BGRPDispatchType:
+ {
+ for (x=(long) columns; x != 0; x--)
+ {
+ *q++=ScaleQuantumToChar(GetBlueSample(p));
+ *q++=ScaleQuantumToChar(GetGreenSample(p));
+ *q++=ScaleQuantumToChar(GetRedSample(p));
+ *q++=0;
+ p++;
+ }
+ break;
+ }
+ case RGBDispatchType:
+ {
+ for (x=(long) columns; x != 0; x--)
+ {
+ *q++=ScaleQuantumToChar(GetRedSample(p));
+ *q++=ScaleQuantumToChar(GetGreenSample(p));
+ *q++=ScaleQuantumToChar(GetBlueSample(p));
+ p++;
+ }
+ break;
+ }
+ case RGBADispatchType:
+ {
+ for (x=(long) columns; x != 0; x--)
+ {
+ *q++=ScaleQuantumToChar(GetRedSample(p));
+ *q++=ScaleQuantumToChar(GetGreenSample(p));
+ *q++=ScaleQuantumToChar(GetBlueSample(p));
+ *q++=ScaleQuantumToChar(MaxRGB-GetOpacitySample(p));
+ p++;
+ }
+ break;
+ }
+ case IDispatchType:
+ {
+ if (image->is_grayscale)
+ {
+ for (x=(long) columns; x != 0; x--)
+ {
+ *q++=ScaleQuantumToChar(GetGraySample(p));
+ p++;
+ }
+ }
+ else
+ {
+ for (x=(long) columns; x != 0; x--)
+ {
+ *q++=ScaleQuantumToChar(PixelIntensity(p));
+ p++;
+ }
+ }
+ break;
+ }
+ case UndefinedDispatchType:
+ {
+ }
+ }
+ }
+ return (status);
+ }
+ }
+
+ length=strlen(map);
+ length=Min(length,sizeof(switch_map)/sizeof(MapQuantumType));
+
+ /*
+ Prepare a validated and more efficient version of the map.
+ */
+ for (i=0; i < (long) length; i++)
+ {
+ switch ((int) toupper((int) map[i]))
+ {
+ case 'R':
+ {
+ switch_map[i]=RedMapQuantum;
+ break;
+ }
+ case 'G':
+ {
+ switch_map[i]=GreenMapQuantum;
+ break;
+ }
+ case 'B':
+ {
+ switch_map[i]=BlueMapQuanum;
+ break;
+ }
+ case 'A':
+ case 'T':
+ {
+ switch_map[i]=TransparencyMapQuantum;
+ break;
+ }
+ case 'C':
+ {
+ switch_map[i]=RedMapQuantum;
+ if (image->colorspace == CMYKColorspace)
+ break;
+ ThrowException(exception,OptionError,ColorSeparatedImageRequired,map);
+ return(MagickFail);
+ }
+ case 'M':
+ {
+ switch_map[i]=GreenMapQuantum;
+ if (image->colorspace == CMYKColorspace)
+ break;
+ ThrowException(exception,OptionError,ColorSeparatedImageRequired,map);
+ return(MagickFail);
+ }
+ case 'Y':
+ {
+ switch_map[i]=BlueMapQuanum;
+ if (image->colorspace == CMYKColorspace)
+ break;
+ ThrowException(exception,OptionError,ColorSeparatedImageRequired,map);
+ return(MagickFail);
+ }
+ case 'K':
+ {
+ switch_map[i]=OpacityMapQuantum;
+ if (image->colorspace == CMYKColorspace)
+ break;
+ ThrowException(exception,OptionError,ColorSeparatedImageRequired,map);
+ return(MagickFail);
+ }
+ case 'I':
+ {
+ switch_map[i]=IntensityMapQuantum;
+ break;
+ }
+ case 'O':
+ {
+ switch_map[i]=OpacityMapQuantum;
+ break;
+ }
+ case 'P':
+ {
+ switch_map[i]=PadMapQuantum;
+ break;
+ }
+ default:
+ {
+ ThrowException(exception,OptionError,UnrecognizedPixelMap,map);
+ return(MagickFail);
+ }
+ }
+ }
+
+ for (y=0; y < (long) rows; y++)
+ {
+ p=AcquireImagePixels(image,x_offset,y_offset+y,columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) columns; x++)
+ {
+ for (i=0; i < (long) length; i++)
+ {
+ /*
+ Obtain quantum value
+ */
+ quantum=0U;
+ switch (switch_map[i])
+ {
+ case RedMapQuantum:
+ {
+ quantum=GetRedSample(p);
+ break;
+ }
+ case GreenMapQuantum:
+ {
+ quantum=GetGreenSample(p);
+ break;
+ }
+ case BlueMapQuanum:
+ {
+ quantum=GetBlueSample(p);
+ break;
+ }
+ case IntensityMapQuantum:
+ {
+ if (image->is_grayscale)
+ {
+ quantum=GetRedSample(p);
+ }
+ else
+ {
+ double intensity = PixelIntensity(p);
+ quantum=RoundDoubleToQuantum(intensity);
+ }
+ break;
+ }
+ case TransparencyMapQuantum:
+ {
+ if (image->matte)
+ quantum=GetOpacitySample(p);
+ quantum=MaxRGB-quantum;
+ break;
+ }
+ case OpacityMapQuantum:
+ {
+ if ((image->matte) ||
+ (image->colorspace == CMYKColorspace))
+ quantum=GetOpacitySample(p);
+ break;
+ }
+ case PadMapQuantum:
+ {
+ /* Zero quantum */
+ break;
+ }
+ }
+
+ /*
+ Output quantum
+ */
+ switch (type)
+ {
+ case CharPixel:
+ {
+ register unsigned char *q = (unsigned char*) pixels;
+ *q++=ScaleQuantumToChar(quantum);
+ pixels=(void *) q;
+ break;
+ }
+ case ShortPixel:
+ {
+ register unsigned short *q = (unsigned short*) pixels;
+ *q++=ScaleQuantumToShort(quantum);
+ pixels=(void *) q;
+ break;
+ }
+ case IntegerPixel:
+ {
+ register unsigned int *q = (unsigned int*) pixels;
+ *q++=ScaleQuantumToLong(quantum);
+ pixels=(void *) q;
+ break;
+ }
+ case LongPixel:
+ {
+ register unsigned long *q = (unsigned long*) pixels;
+ *q++=ScaleQuantumToLong(quantum);
+ pixels=(void *) q;
+ break;
+ }
+ case FloatPixel:
+ {
+ register float *q = (float*) pixels;
+ *q++=(float) ((double) quantum/MaxRGB);
+ pixels=(void *) q;
+ break;
+ }
+ case DoublePixel:
+ {
+ register double *q = (double*) pixels;
+ *q++=(double) quantum/MaxRGB;
+ pixels=(void *) q;
+ break;
+ }
+ }
+ }
+ p++;
+ }
+ }
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k F i n d R a w I m a g e M i n M a x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFindRawImageMinMax() obtains the minimum and maximum sample values
+% for a raw image. The image blob must already be open with its current
+% seek offset pointing to the start of the raw data. The seek offset is
+% restored when this function returns. File data is processed on a
+% scanline basis in order to minimize memory consumption. The purpose of
+% this function is to support pre-scanning a raw image to find its maximum
+% values so that appropriate scaling may be applied when the data is read a
+% second time. MagickFail is returned if a problem occurs while scanning the
+% data.
+%
+% The format of the MagickFindRawImageMinMax method is:
+%
+% MagickPassFail MagickFindRawImageMinMax(Image *image, EndianType endian,
+% unsigned long width, unsigned long height,StorageType type,
+% unsigned scanline_octets, void *scanline_buffer,
+% double *min, double *max)
+%
+% A description of each parameter follows:
+%
+% o image: Pointer to an image with an already open blob, with seek
+% offset pointing to raw data.
+%
+% o endian: Endian order of raw data (LSBEndian or MSBEndian)
+%
+% o width: Number of raw samples in a scanline.
+%
+% o height: Number of scanlines to process.
+%
+% o type: Raw data storage type.
+%
+% o scanline_octets: Number of octets to read per scanline.
+%
+% o scanline_buffer: Working buffer for scanlines. Allocation size
+% must at least be enough to contain scanline octets.
+%
+% o min: Pointer to double value to update with minimum value.
+%
+% o max: Pointer to double value to update with maximum value.
+%
+*/
+#define MagickFindMinMax(status,image,read_func,basic_type,scanline_octets,scanline_buffer,min,max) \
+ { \
+ unsigned long \
+ y; \
+ \
+ for (y = 0; y < height; y++) \
+ { \
+ unsigned long \
+ x; \
+ \
+ basic_type \
+ * restrict scanline; \
+ \
+ scanline=(basic_type *) scanline_buffer; \
+ if ((read_func)(image, scanline_octets, scanline) != \
+ scanline_octets) \
+ { \
+ status=MagickFail; \
+ break; \
+ } \
+ \
+ if (y == 0) \
+ *min = *max = (double) scanline[0]; \
+ \
+ for (x = 0; x < width; x++) \
+ { \
+ if (*min > (double) scanline[x]) \
+ *min = (double) scanline[x]; \
+ if (*max < (double) scanline[x]) \
+ *max = (double) scanline[x]; \
+ } \
+ } \
+ }
+
+MagickPassFail
+MagickFindRawImageMinMax(Image *image, EndianType endian,
+ unsigned long width, unsigned long height,StorageType type,
+ unsigned scanline_octets, void *scanline_buffer,
+ double *min, double *max)
+{
+ magick_off_t
+ filepos;
+
+ MagickPassFail
+ status;
+
+ *min=0.0;
+ *max=1.0;
+ status=MagickFail;
+
+ filepos = TellBlob(image);
+
+ if (filepos >= 0)
+ {
+ status=MagickPass;
+ switch (type)
+ {
+ case CharPixel:
+ {
+ size_t (*read_func)(Image * image, size_t octets, void *data);
+
+ read_func = ReadBlob;
+
+ MagickFindMinMax(status,image,read_func,char,scanline_octets,
+ scanline_buffer,min,max)
+ break;
+ }
+ case ShortPixel:
+ {
+ size_t (*read_func)(Image * image, size_t octets, magick_uint16_t *data);
+
+ if (endian == LSBEndian)
+ read_func = ReadBlobLSBShorts;
+ else
+ read_func = ReadBlobMSBShorts;
+
+ MagickFindMinMax(status,image,read_func,magick_uint16_t,scanline_octets,
+ scanline_buffer,min,max);
+ break;
+ }
+ case IntegerPixel:
+ case LongPixel:
+ {
+ size_t (*read_func)(Image * image, size_t octets, magick_uint32_t *data);
+
+ if (endian == LSBEndian)
+ read_func = ReadBlobLSBLongs;
+ else
+ read_func = ReadBlobMSBLongs;
+
+ MagickFindMinMax(status,image,read_func,magick_uint32_t,scanline_octets,
+ scanline_buffer,min,max);
+ break;
+ }
+ case FloatPixel:
+ {
+ size_t (*read_func)(Image * image, size_t octets, float *data);
+
+ if (endian == LSBEndian)
+ read_func = ReadBlobLSBFloats;
+ else
+ read_func = ReadBlobMSBFloats;
+
+ MagickFindMinMax(status,image,read_func,float,scanline_octets,
+ scanline_buffer,min,max);
+ break;
+ }
+ case DoublePixel:
+ {
+ size_t (*read_func)(Image * image, size_t octets, double *data);
+
+ if (endian == LSBEndian)
+ read_func = ReadBlobLSBDoubles;
+ else
+ read_func = ReadBlobMSBDoubles;
+
+ MagickFindMinMax(status,image,read_func,double,scanline_octets,
+ scanline_buffer,min,max);
+ break;
+ }
+ }
+
+ (void) SeekBlob(image, filepos, SEEK_SET);
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k G e t Q u a n t u m S a m p l e s P e r P i x e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetQuantumSamplesPerPixel() returns the number of discrete samples
+% which will be encoded/decoded per-pixel for the specified QuantumType.
+%
+% The format of the MagickGetQuantumSamplesPerPixel method is:
+%
+% unsigned int MagickGetQuantumSamplesPerPixel(const QuantumType quantum_type)
+%
+% A description of each parameter follows:
+%
+% o quantum_type: Quantum type
+%
+%
+*/
+MagickExport unsigned int
+MagickGetQuantumSamplesPerPixel(const QuantumType quantum_type)
+{
+ unsigned int
+ samples=0;
+
+ switch (quantum_type)
+ {
+ case UndefinedQuantum:
+ samples=0;
+ break;
+ case IndexQuantum:
+ samples=1;
+ break;
+ case GrayQuantum:
+ samples=1;
+ break;
+ case IndexAlphaQuantum:
+ samples=2;
+ break;
+ case GrayAlphaQuantum:
+ samples=2;
+ break;
+ case RedQuantum:
+ samples=1;
+ break;
+ case CyanQuantum:
+ samples=1;
+ break;
+ case GreenQuantum:
+ samples=1;
+ break;
+ case YellowQuantum:
+ samples=1;
+ break;
+ case BlueQuantum:
+ samples=1;
+ break;
+ case MagentaQuantum:
+ samples=1;
+ break;
+ case AlphaQuantum:
+ samples=1;
+ break;
+ case BlackQuantum:
+ samples=1;
+ break;
+ case RGBQuantum:
+ samples=3;
+ break;
+ case RGBAQuantum:
+ samples=4;
+ break;
+ case CMYKQuantum:
+ samples=4;
+ break;
+ case CMYKAQuantum:
+ samples=5;
+ break;
+ case CIEYQuantum:
+ samples=1;
+ break;
+ case CIEXYZQuantum:
+ samples=3;
+ break;
+ }
+
+ return samples;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e C o n s t i t u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeConstitute initializes the constitute facility
+%
+% The format of the InitializeConstitute method is:
+%
+% MagickPassFail InitializeConstitute(void)
+%
+%
+*/
+MagickPassFail
+InitializeConstitute(void)
+{
+ assert(constitute_semaphore == (SemaphoreInfo *) NULL);
+ constitute_semaphore=AllocateSemaphoreInfo();
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i n g I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PingImage() returns all the attributes of an image or image sequence
+% except for the pixels. It is much faster and consumes far less memory
+% than ReadImage(). On failure, a NULL image is returned and exception
+% describes the reason for the failure.
+%
+% The format of the PingImage method is:
+%
+% Image *PingImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: Ping the image defined by the file or filename members of
+% this structure.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *PingImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ /* SetExceptionInfo(exception,UndefinedException); */
+ clone_info=CloneImageInfo(image_info);
+ clone_info->ping=True;
+ image=ReadImage(clone_info,exception);
+ DestroyImageInfo(clone_info);
+ /*
+ Intentionally restart timer if ping is requested since timing ping
+ is meaningless and misleading.
+ */
+ if (image != (Image *) NULL)
+ GetTimerInfo(&image->timer);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadImage() reads an image or image sequence from a file or file handle.
+% The method returns a NULL if there is a memory shortage or if the image
+% cannot be read. On failure, a NULL image is returned and exception
+% describes the reason for the failure.
+%
+% The format of the ReadImage method is:
+%
+% Image *ReadImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: Read the image defined by the file or filename members of
+% this structure.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static void RemoveTemporaryInputFile(ImageInfo *image_info)
+{
+ size_t
+ filename_length;
+
+ /*
+ Remove normal file name.
+ */
+ if(!LiberateTemporaryFile(image_info->filename))
+ (void) remove(image_info->filename);
+
+ /*
+ Remove a .cache file corresponding to a .mpc file.
+ This stupidity is necessary because MPC "files" are comprised of two
+ separate files.
+ */
+ filename_length=strlen(image_info->filename);
+ if ((filename_length > 4U) &&
+ (LocaleCompare(image_info->filename+filename_length-4,".mpc") == 0))
+ {
+ char remove_name[MaxTextExtent];
+ (void) strcpy(remove_name,image_info->filename);
+ remove_name[filename_length-4]=0;
+ (void) strcat(remove_name,".cache");
+ (void) printf("removing %s\n", remove_name);
+ (void) remove(remove_name);
+ }
+ else if (LocaleCompare(image_info->magick,"mpc") == 0)
+ {
+ char remove_name[MaxTextExtent];
+ (void) strcpy(remove_name,image_info->filename);
+ (void) strcat(remove_name,".cache");
+ (void) printf("removing %s\n", remove_name);
+ (void) remove(remove_name);
+ }
+
+ errno=0;
+}
+
+MagickExport Image *ReadImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ char
+ filename[MaxTextExtent],
+ magick[MaxTextExtent];
+
+ const DelegateInfo
+ *delegate_info;
+
+ const MagickInfo
+ *magick_info;
+
+ Image
+ *image,
+ *next;
+
+ ImageInfo
+ *clone_info;
+
+ /*
+ Determine image type from filename prefix or suffix (e.g. image.jpg).
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image_info->filename != (char *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+ /* SetExceptionInfo(exception,UndefinedException); */
+ if ((*image_info->filename == '@') && (!IsAccessibleNoLogging(image_info->filename)))
+ return(ReadImages(image_info,exception));
+ clone_info=CloneImageInfo(image_info);
+
+ /*
+ Obtain file magick from filename
+ */
+ (void) SetImageInfo(clone_info,SETMAGICK_READ,exception);
+ (void) LogMagickEvent(BlobEvent,GetMagickModule(),
+ "Magick=%s, Filename=%s", clone_info->magick,clone_info->filename);
+ (void) strlcpy(filename,clone_info->filename,MaxTextExtent);
+ (void) strlcpy(magick,clone_info->magick,MaxTextExtent);
+ /*
+ Call appropriate image reader based on image type.
+ */
+ {
+ ExceptionInfo
+ module_exception,
+ delegate_exception;
+
+ GetExceptionInfo(&module_exception);
+ GetExceptionInfo(&delegate_exception);
+ magick_info=GetMagickInfo(clone_info->magick,&module_exception);
+ delegate_info=(const DelegateInfo *) NULL;
+ if ((magick_info == (const MagickInfo *) NULL) ||
+ (magick_info->decoder == NULL))
+ delegate_info=GetDelegateInfo(clone_info->magick,(char *) NULL,&delegate_exception);
+
+ if (((magick_info == (const MagickInfo *) NULL) ||
+ (magick_info->decoder == NULL)) &&
+ ((delegate_info == (const DelegateInfo *) NULL) ||
+ (delegate_info->decode == NULL)))
+ {
+ /*
+ Module loader ConfigureError errors are intentionally
+ ignored here in order to provide the user with familiar "no
+ delegate" error messages. This may be re-considered later.
+ */
+ if ((module_exception.severity != UndefinedException) &&
+ (module_exception.severity != ConfigureError))
+ CopyException(exception,&module_exception);
+ else if (delegate_exception.severity != UndefinedException)
+ CopyException(exception,&delegate_exception);
+ else
+ {
+ /*
+ Try to choose a useful error type
+ */
+ if (clone_info->filename[0] == 0)
+ {
+ errno=0;
+ ThrowException(exception,MissingDelegateError,
+ NoDecodeDelegateForThisImageFormat,clone_info->magick);
+ }
+ else if (IsAccessibleAndNotEmpty(clone_info->filename))
+ {
+ errno=0;
+ ThrowException(exception,MissingDelegateError,
+ NoDecodeDelegateForThisImageFormat,clone_info->filename);
+ }
+ else
+ {
+ ThrowException(exception,FileOpenError,UnableToOpenFile,
+ clone_info->filename);
+ }
+ }
+ DestroyExceptionInfo(&module_exception);
+ DestroyExceptionInfo(&delegate_exception);
+ if (clone_info->temporary)
+ RemoveTemporaryInputFile(clone_info);
+ DestroyImageInfo(clone_info);
+ return((Image *) NULL);
+ }
+
+ DestroyExceptionInfo(&module_exception);
+ DestroyExceptionInfo(&delegate_exception);
+ }
+
+ if ((magick_info != (const MagickInfo *) NULL) &&
+ (magick_info->seekable_stream == MagickTrue))
+ {
+ unsigned int
+ status;
+
+ image=AllocateImage(clone_info);
+ if (image == (Image *) NULL)
+ {
+ DestroyImageInfo(clone_info);
+ return((Image *) NULL);
+ }
+ (void) strlcpy(image->filename,clone_info->filename,MaxTextExtent);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == False)
+ {
+ DestroyImageInfo(clone_info);
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ if (!BlobIsSeekable(image))
+ {
+ /*
+ Coder requires a random access stream.
+ */
+ if(!AcquireTemporaryFileName(clone_info->filename))
+ {
+ ThrowException(exception,FileOpenError,
+ UnableToCreateTemporaryFile,clone_info->filename);
+ CloseBlob(image);
+ DestroyImageInfo(clone_info);
+ DestroyImage(image);
+ return((Image *) NULL);
+ }
+ (void) ImageToFile(image,clone_info->filename,exception);
+ clone_info->temporary=True;
+ }
+ CloseBlob(image);
+ DestroyImage(image);
+ }
+ image=(Image *) NULL;
+ if ((magick_info != (const MagickInfo *) NULL) &&
+ (magick_info->decoder != NULL))
+ {
+ if (!magick_info->thread_support)
+ LockSemaphoreInfo(constitute_semaphore);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Invoking \"%.1024s\" decoder (%.1024s) subimage=%lu subrange=%lu",
+ magick_info->name,
+ magick_info->description,
+ clone_info->subimage,
+ clone_info->subrange);
+ image=(magick_info->decoder)(clone_info,exception);
+ if (!magick_info->thread_support)
+ UnlockSemaphoreInfo(constitute_semaphore);
+
+ if (image != (Image *) NULL)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returned from \"%.1024s\" decoder: frames=%lu cache=%s monochrome=%s grayscale=%s class=%s colorspace=%s",
+ magick_info->name,
+ GetImageListLength(image),
+ (GetPixelCachePresent(image) ? "present" : "missing"),
+ MagickBoolToString(image->is_monochrome),
+ MagickBoolToString(image->is_grayscale),
+ ClassTypeToString(image->storage_class),
+ ColorspaceTypeToString(image->colorspace));
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returned from \"%.1024s\" decoder, returned image is NULL!",
+ magick_info->name);
+
+ /*
+ Enforce that returned images do not have open blobs.
+ */
+ if (image != (Image *) NULL)
+ {
+ assert(!GetBlobIsOpen(image));
+ }
+
+ /*
+ Deal with errors in the image which were not properly reported
+ to exception. If there is an exception at error level, then
+ destroy image so that bad image is not consumed by user.
+ */
+ if (image != (Image *) NULL)
+ {
+ GetImageException(image,exception);
+ if (exception->severity >= ErrorException)
+ {
+ DestroyImageList(image);
+ image=(Image *) NULL;
+ }
+ }
+ }
+ else
+ {
+ if (delegate_info == (const DelegateInfo *) NULL)
+ {
+ if (clone_info->temporary)
+ RemoveTemporaryInputFile(clone_info);
+ DestroyImageInfo(clone_info);
+ return((Image *) NULL);
+ }
+ /*
+ Let our decoding delegate process the image.
+ */
+ image=AllocateImage(clone_info);
+ if (image == (Image *) NULL)
+ {
+ DestroyImageInfo(clone_info);
+ return((Image *) NULL);
+ }
+ (void) strlcpy(image->filename,clone_info->filename,MaxTextExtent);
+ if(!AcquireTemporaryFileName(clone_info->filename))
+ {
+ ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,
+ clone_info->filename);
+ DestroyImageInfo(clone_info);
+ return((Image *) NULL);
+ }
+ (void) InvokeDelegate(clone_info,image,clone_info->magick,(char *) NULL,
+ exception);
+ DestroyImageList(image);
+ image=(Image *) NULL;
+ clone_info->temporary=True;
+ (void) SetImageInfo(clone_info,SETMAGICK_READ,exception);
+ magick_info=GetMagickInfo(clone_info->magick,exception);
+ /*
+ If there is no magick info entry for this format, or there is
+ no decoder for the format, or an error is reported, then
+ attempt to return a reasonable error report.
+ */
+ if ((magick_info == (const MagickInfo *) NULL) ||
+ (magick_info->decoder == NULL) ||
+ (exception->severity != UndefinedException))
+ {
+ if (exception->severity == UndefinedException)
+ {
+ if (IsAccessibleAndNotEmpty(clone_info->filename))
+ ThrowException(exception,MissingDelegateError,
+ NoDecodeDelegateForThisImageFormat,clone_info->filename);
+ else
+ ThrowException(exception,FileOpenError,UnableToOpenFile,
+ clone_info->filename);
+ }
+ if (clone_info->temporary)
+ RemoveTemporaryInputFile(clone_info);
+ DestroyImageInfo(clone_info);
+ return((Image *) NULL);
+ }
+ /*
+ Invoke decoder for format
+ */
+ if (!magick_info->thread_support)
+ LockSemaphoreInfo(constitute_semaphore);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Invoking \"%.1024s\" decoder (%.1024s) subimage=%lu subrange=%lu",
+ magick_info->name,
+ magick_info->description,
+ clone_info->subimage,
+ clone_info->subrange);
+ image=(magick_info->decoder)(clone_info,exception);
+ if (!magick_info->thread_support)
+ UnlockSemaphoreInfo(constitute_semaphore);
+
+ if (image != (Image *) NULL)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returned from \"%.1024s\" decoder: frames=%lu cache=%s monochrome=%s grayscale=%s class=%s colorspace=%s",
+ magick_info->name,
+ GetImageListLength(image),
+ (GetPixelCachePresent(image) ? "present" : "missing"),
+ MagickBoolToString(image->is_monochrome),
+ MagickBoolToString(image->is_grayscale),
+ ClassTypeToString(image->storage_class),
+ ColorspaceTypeToString(image->colorspace));
+ else
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returned from \"%.1024s\" decoder: returned image is NULL!",
+ magick_info->name);
+
+ /*
+ Enforce that returned images do not have open blobs.
+ */
+ if (image != (Image *) NULL)
+ {
+ assert(!GetBlobIsOpen(image));
+ }
+
+ /*
+ Deal with errors in the image which were not properly reported
+ to exception. If there is an exception at error level, then
+ destroy image so that bad image is not consumed by user.
+ */
+ if (image != (Image *) NULL)
+ {
+ GetImageException(image,exception);
+ if (exception->severity >= ErrorException)
+ {
+ DestroyImageList(image);
+ image=(Image *) NULL;
+ }
+ }
+
+ /*
+ Restore original input file magick in case read is from a
+ temporary file prepared by an external delegate. The user
+ will expect that the format reported is that of the input
+ file.
+ */
+ if (image != (Image *) NULL)
+ (void) strlcpy(image->magick,magick,MaxTextExtent);
+ }
+ if (clone_info->temporary)
+ {
+ RemoveTemporaryInputFile(clone_info);
+ clone_info->temporary=False;
+ if (image != (Image *) NULL)
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ }
+ if (image == (Image *) NULL)
+ {
+ DestroyImageInfo(clone_info);
+ return((Image *) NULL);
+ }
+ if (GetBlobTemporary(image))
+ RemoveTemporaryInputFile(clone_info);
+
+ if ((image->next != (Image *) NULL) && IsSubimage(clone_info->tile,False))
+ {
+ char
+ *q;
+
+ Image
+ *clone_image,
+ *subimages;
+
+ long
+ quantum;
+
+ register char
+ *p;
+
+ register long
+ i;
+
+ unsigned long
+ first,
+ last;
+
+ /*
+ User specified subimages (e.g. image.miff[1,3-5,7-6,2]).
+ */
+ subimages=NewImageList();
+ p=clone_info->tile;
+ for (q=p; *q != '\0'; p++)
+ {
+ while (isspace((int) *p) || (*p == ','))
+ p++;
+ first=strtol(p,&q,10);
+ last=first;
+ while (isspace((int) *q))
+ q++;
+ if (*q == '-')
+ last=strtol(q+1,&q,10);
+ quantum=first > last ? -1 : 1;
+ for (p=q; first != (last+quantum); first+=quantum)
+ {
+ i=0;
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ if (next->scene != 0)
+ i=(long) next->scene;
+ if (i != (long) first)
+ {
+ i++;
+ continue;
+ }
+ clone_image=CloneImage(next,0,0,True,exception);
+ if (clone_image == (Image *) NULL)
+ break;
+ AppendImageToList(&subimages,clone_image);
+ i++;
+ }
+ }
+ }
+ if (subimages == (Image *) NULL)
+ ThrowException(exception,OptionError,
+ SubimageSpecificationReturnsNoImages,
+ clone_info->filename);
+ else
+ {
+ while (subimages->previous != (Image *) NULL)
+ subimages=subimages->previous;
+ DestroyImageList(image);
+ image=subimages;
+ }
+ }
+ for (next=image; next; next=next->next)
+ {
+#if 0
+ /*
+ Apply user-requested colorspace setting. This allows the user
+ to override the default colorspace for the image type.
+ FIXME: Does not work yet.
+ */
+ {
+ const ImageAttribute
+ *attribute;
+
+/* if ((image_info->attributes) && */
+/* (attribute=GetImageAttribute(image_info->attributes,"colorspace-override"))) */
+ if ((attribute=GetImageAttribute(image,"colorspace-override")))
+ {
+ next->colorspace = StringToColorspaceType(attribute->value);
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Colorspace explicitly set to %s",
+ ColorspaceTypeToString(image->colorspace));
+ }
+ }
+#endif
+ if (next->storage_class == PseudoClass)
+ {
+ /*
+ Check and cache monochrome and grayscale status
+ */
+ (void) IsMonochromeImage(next,exception);
+ if (next->is_monochrome)
+ next->is_grayscale=True;
+ else
+ (void) IsGrayImage(next,exception);
+ }
+ next->taint=False;
+ (void) strlcpy(next->magick_filename,filename,MaxTextExtent);
+ if (GetBlobTemporary(image))
+ (void) strlcpy(next->filename,filename,MaxTextExtent);
+ if (next->magick_columns == 0)
+ next->magick_columns=next->columns;
+ if (next->magick_rows == 0)
+ next->magick_rows=next->rows;
+ if (next->page.width == 0)
+ next->page.width=next->columns;
+ if (next->page.height == 0)
+ next->page.height=next->rows;
+ }
+ DestroyImageInfo(clone_info);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadImages() reads a list of image names from a file and then returns the
+% images as a linked list.
+%
+% The format of the ReadImage method is:
+%
+% Image *ReadImages(const ImageInfo *image_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Method ReadImage returns a pointer to the image after
+% reading. A null image is returned if there is a memory shortage or
+% if the image cannot be read.
+%
+% o image_info: The list of filenames are defined in the filename member of
+% this structure.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static Image *ReadImages(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+ char
+ *command,
+ **images;
+
+ Image
+ *image;
+
+ ImageInfo
+ *clone_info;
+
+ int
+ number_images;
+
+ register Image
+ *next;
+
+ register long
+ i;
+
+ size_t
+ length;
+
+ /*
+ Read image list from a file.
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ command=(char *) FileToBlob(image_info->filename+1,&length,exception);
+ if (command == (char *) NULL)
+ return((Image *) NULL);
+ Strip(command);
+ images=StringToArgv(command,&number_images);
+ MagickFreeMemory(command);
+ if (images == (char **) NULL)
+ return((Image *) NULL);
+ /*
+ Read the images into a linked list.
+ */
+ image=(Image *) NULL;
+ clone_info=CloneImageInfo(image_info);
+ for (i=1; i < number_images; i++)
+ {
+ (void) strlcpy(clone_info->filename,images[i],MaxTextExtent);
+ if ((image_info->filename[0] == '@') &&
+ (clone_info->filename[0] == '@') &&
+ (strcmp(clone_info->filename+1,image_info->filename+1) == 0))
+ continue;
+ next=ReadImage(clone_info,exception);
+ if (next == (Image *) NULL)
+ continue;
+ if (image == (Image *) NULL)
+ image=next;
+ else
+ {
+ register Image
+ *q;
+
+ /*
+ Link image into image list.
+ */
+ for (q=image; q->next != (Image *) NULL; q=q->next);
+ next->previous=q;
+ q->next=next;
+ }
+ }
+ DestroyImageInfo(clone_info);
+ for (i=0; i < number_images; i++)
+ MagickFreeMemory(images[i]);
+ MagickFreeMemory(images);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a d I n l i n e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadInlineImage() reads a Base64-encoded inline image or image sequence.
+% The method returns a NULL if there is a memory shortage or if the image
+% cannot be read. On failure, a NULL image is returned and exception
+% describes the reason for the failure.
+%
+% The format of the ReadInlineImage method is:
+%
+% Image *ReadInlineImage(const ImageInfo *image_info,const char *content,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o content: The image encoded in Base64.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *ReadInlineImage(const ImageInfo *image_info,
+ const char *content,ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ MonitorHandler
+ handler;
+
+ unsigned char
+ *blob;
+
+ size_t
+ length;
+
+ register const char
+ *p;
+
+ /* SetExceptionInfo(exception,UndefinedException); */
+ image=(Image *) NULL;
+ for (p=content; (*p != ',') && (*p != '\0'); p++);
+ if (*p == '\0')
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ p++;
+ blob=Base64Decode(p,&length);
+ if (length == 0)
+ {
+ MagickFreeMemory(blob);
+ ThrowReaderException(CorruptImageError,CorruptImage,image);
+ }
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ image=BlobToImage(image_info,blob,length,exception);
+ (void) SetMonitorHandler(handler);
+ MagickFreeMemory(blob);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use WriteImage() to write an image or an image sequence to a file or
+% filehandle. If writing to a file on disk, the name is defined by the
+% filename member of the image structure. Write() returns 0 is there is a
+% memory shortage or if the image cannot be written. Check the exception
+% member of image to determine the cause for any failure.
+%
+% The format of the WriteImage method is:
+%
+% unsigned int WriteImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport unsigned int WriteImage(const ImageInfo *image_info,Image *image)
+{
+ const DelegateInfo
+ *delegate_info;
+
+ const MagickInfo
+ *magick_info;
+
+ ImageInfo
+ *clone_info;
+
+ unsigned int
+ status;
+
+ /*
+ Determine image type from filename prefix or suffix (e.g. image.jpg).
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image_info->filename != (char *) NULL);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ GetTimerInfo(&image->timer);
+ image->logging=IsEventLogging();
+ clone_info=CloneImageInfo(image_info);
+ (void) strlcpy(clone_info->filename,image->filename,MaxTextExtent);
+ (void) strlcpy(clone_info->magick,image->magick,MaxTextExtent);
+ (void) SetImageInfo(clone_info,SETMAGICK_WRITE,&image->exception);
+ (void) strlcpy(image->filename,clone_info->filename,MaxTextExtent);
+ image->dither=image_info->dither;
+ DisassociateBlob(image);
+
+#if 0
+ /*
+ This bi-modal delegate code allows short-circuiting GraphicsMagick
+ in case the delegates support a direct translation. For example,
+ PDF to PS using Ghostscript.
+
+ This is currently disabled due to potential side-effects.
+ */
+ if (((image->next == (Image *) NULL) || clone_info->adjoin) &&
+ (image->previous == (Image *) NULL) &&
+ (clone_info->page == (char *) NULL) && !IsTaintImage(image))
+ {
+ delegate_info=GetDelegateInfo(image->magick,clone_info->magick,
+ &image->exception);
+ if ((delegate_info != (const DelegateInfo *) NULL) &&
+ (delegate_info->mode == 0) && IsAccessible(image->magick_filename))
+ {
+ /*
+ Let our bi-modal delegate process the image.
+ */
+ (void) strlcpy(image->filename,image->magick_filename,
+ MaxTextExtent);
+ status=InvokeDelegate(clone_info,image,image->magick,
+ clone_info->magick,&image->exception);
+ DestroyImageInfo(clone_info);
+ return(!status);
+ }
+ }
+#endif
+
+ /*
+ Call appropriate image writer based on image type.
+ */
+ status=False;
+ magick_info=GetMagickInfo(clone_info->magick,&image->exception);
+ if ((magick_info != (const MagickInfo *) NULL) &&
+ (magick_info->encoder != NULL))
+ {
+ char
+ tempfile[MaxTextExtent];
+
+ tempfile[0]='\0';
+
+ if (magick_info->seekable_stream == MagickTrue)
+ {
+ /*
+ Divert output to temporary file if coder requires a
+ seekable stream and output is not seekable.
+ */
+ if (OpenBlob(clone_info,image,WriteBinaryBlobMode,&image->exception))
+ {
+ if (!BlobIsSeekable(image))
+ {
+ if(!AcquireTemporaryFileName(tempfile))
+ {
+ ThrowException(&image->exception,FileOpenError,
+ UnableToCreateTemporaryFile,image->filename);
+ DestroyImageInfo(clone_info);
+ return(False);
+ }
+ (void) strlcpy(image->filename,tempfile,sizeof(image->filename));
+ }
+ else
+ {
+ /*
+ OpenBlob may expand image->filename so we need to restore it.
+ */
+ (void) strlcpy(image->filename,clone_info->filename,sizeof(image->filename));
+ }
+ CloseBlob(image);
+ }
+ }
+
+ if (!magick_info->thread_support)
+ LockSemaphoreInfo(constitute_semaphore);
+ if (image->logging)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Invoking \"%.1024s\" encoder (%.1024s): "
+ "cache=%s "
+ "adjoin=%s type=%s monochrome=%s grayscale=%s "
+ "class=%s colorspace=%s",
+ magick_info->name,
+ magick_info->description,
+ (GetPixelCachePresent(image) ? "present" : "missing"),
+ MagickBoolToString(clone_info->adjoin),
+ ImageTypeToString(clone_info->type),
+ MagickBoolToString(image->is_monochrome),
+ MagickBoolToString(image->is_grayscale),
+ ClassTypeToString(image->storage_class),
+ ColorspaceTypeToString(image->colorspace));
+ status=(magick_info->encoder)(clone_info,image);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returned from \"%.1024s\" encoder",magick_info->name);
+ if (!magick_info->thread_support)
+ UnlockSemaphoreInfo(constitute_semaphore);
+
+ if (tempfile[0] != '\0')
+ {
+ /*
+ Send temporary file to stream.
+ */
+ (void) strlcpy(image->filename,clone_info->filename,MaxTextExtent);
+ if ((status &= OpenBlob(clone_info,image,WriteBinaryBlobMode,
+ &image->exception)))
+ {
+ status &= WriteBlobFile(image,tempfile);
+ CloseBlob(image);
+ }
+ LiberateTemporaryFile(tempfile);
+ }
+ }
+ else
+ {
+ delegate_info=GetDelegateInfo((char *) NULL,clone_info->magick,
+ &image->exception);
+ if (delegate_info != (DelegateInfo *) NULL)
+ {
+ /*
+ Let our encoding delegate process the image.
+ */
+ if(!AcquireTemporaryFileName(image->filename))
+ {
+ ThrowException(&image->exception,FileOpenError,
+ UnableToCreateTemporaryFile,image->filename);
+ DestroyImageInfo(clone_info);
+ return(False);
+ }
+ status=InvokeDelegate(clone_info,image,(char *) NULL,
+ clone_info->magick,&image->exception);
+ (void) LiberateTemporaryFile(image->filename);
+ DestroyImageInfo(clone_info);
+ return(!status);
+ }
+ magick_info=GetMagickInfo(clone_info->magick,&image->exception);
+ if (!clone_info->affirm && (magick_info == (const MagickInfo *) NULL))
+ magick_info=(MagickInfo *)
+ GetMagickInfo(image->magick,&image->exception);
+ if ((magick_info == (MagickInfo *) NULL) ||
+ (magick_info->encoder == NULL))
+ {
+ DestroyImageInfo(clone_info);
+ ThrowBinaryException(MissingDelegateError,
+ NoEncodeDelegateForThisImageFormat,
+ image->filename)
+ }
+ if (!magick_info->thread_support)
+ LockSemaphoreInfo(constitute_semaphore);
+ status=(magick_info->encoder)(clone_info,image);
+ if (!magick_info->thread_support)
+ UnlockSemaphoreInfo(constitute_semaphore);
+ }
+ (void) strlcpy(image->magick,clone_info->magick,MaxTextExtent);
+ DestroyImageInfo(clone_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteImages() writes an image sequence into one or more files. While
+% WriteImage() will also write an image sequence, it is limited to writing
+% the sequence into a single file using a format which supports multiple
+% frames. WriteImages() does not have that limitation since it will
+% generate multiple output files if necessary (or when requested). When
+% ImageInfo's adjoin flag is set to MagickFalse, the file name is expected
+% to include a printf-style formatting string for the frame number (e.g.
+% "image%02d.miff") so that the frames may be written.
+%
+% The format of the WriteImages method is:
+%
+% unsigned int WriteImages(const ImageInfo *image_info,Image *image,
+% const char *filename,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o images: The image list.
+%
+% o filename: The image filename.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail WriteImages(const ImageInfo *image_info,Image *image,
+ const char *filename,ExceptionInfo *exception)
+{
+ ImageInfo
+ *clone_info;
+
+ unsigned int
+ status=MagickPass;
+
+ /*
+ Write converted images.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ image->logging=IsEventLogging();
+ clone_info=CloneImageInfo(image_info);
+ if (clone_info)
+ {
+ register Image
+ *p;
+
+ if (filename != (const char *) NULL)
+ {
+ if (strlcpy(clone_info->filename,filename,MaxTextExtent) >= MaxTextExtent)
+ status &= MagickFail;
+ /* Set file name in all image frames */
+ for (p=image; p != (Image *) NULL; p=p->next)
+ if (p->filename != filename)
+ if (strlcpy(p->filename,filename,MaxTextExtent) >= MaxTextExtent)
+ status &= MagickFail;
+ }
+ (void) SetImageInfo(clone_info,
+ (SETMAGICK_WRITE |
+ (!clone_info->adjoin ? SETMAGICK_RECTIFY : 0U)),
+ exception);
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ status &= WriteImage(clone_info,p);
+ if (p->exception.severity > exception->severity)
+ CopyException(exception,&p->exception);
+ GetImageException(p,exception);
+ if (clone_info->adjoin)
+ break;
+ }
+ if (clone_info->verbose)
+ (void) DescribeImage(image,stderr,False);
+ DestroyImageInfo(clone_info);
+ clone_info=0;
+ }
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% W r i t e I m a g e s F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteImagesFile() writes an image or image sequence to a stdio
+% FILE handle. This may be used to append an encoded image to an already
+% existing appended image sequence if the file seek position is at the end
+% of an existing file.
+%
+% The format of the WriteImagesFile method is:
+%
+% unsigned int WriteImagesFile(const ImageInfo *image_info,Image *image,
+% FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o images: The image list.
+%
+% o file: The open (and positioned) file handle.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail WriteImagesFile(const ImageInfo *image_info,Image *image,
+ FILE * file ,ExceptionInfo *exception)
+{
+ ImageInfo
+ *clone_info;
+
+ unsigned int
+ status=MagickPass;
+
+ /*
+ Write converted images.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ image->logging=IsEventLogging();
+ clone_info=CloneImageInfo(image_info);
+ if (clone_info)
+ {
+ register Image
+ *p;
+
+ clone_info->file=file;
+ (void) SetImageInfo(clone_info,
+ (SETMAGICK_WRITE |
+ (!clone_info->adjoin ? SETMAGICK_RECTIFY : 0U)),
+ exception);
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ status &= WriteImage(clone_info,p);
+ if(p->exception.severity > exception->severity)
+ CopyException(exception,&p->exception);
+ GetImageException(p,exception);
+ if (clone_info->adjoin)
+ break;
+ }
+ if (clone_info->verbose)
+ (void) DescribeImage(image,stderr,False);
+ clone_info->file=0;
+ DestroyImageInfo(clone_info);
+ clone_info=0;
+ }
+ return(status);
+}
diff --git a/magick/constitute.h b/magick/constitute.h
new file mode 100644
index 0000000..cfac9f0
--- /dev/null
+++ b/magick/constitute.h
@@ -0,0 +1,216 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Constitute Methods.
+*/
+#ifndef _MAGICK_CONSTITUTE_H
+#define _MAGICK_CONSTITUTE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+/*
+ Quantum import/export types as used by ImportImagePixelArea() and
+ ExportImagePixelArea(). Values are imported or exported in network
+ byte order ("big endian") by default, but little endian may be
+ selected via the 'endian' option in ExportPixelAreaOptions and
+ ImportPixelAreaOptions.
+*/
+typedef enum
+{
+ UndefinedQuantum, /* Not specified */
+ IndexQuantum, /* Colormap indexes */
+ GrayQuantum, /* Grayscale values (minimum value is black) */
+ IndexAlphaQuantum, /* Colormap indexes with transparency */
+ GrayAlphaQuantum, /* Grayscale values with transparency */
+ RedQuantum, /* Red values only (RGBA) */
+ CyanQuantum, /* Cyan values only (CMYKA) */
+ GreenQuantum, /* Green values only (RGBA) */
+ YellowQuantum, /* Yellow values only (CMYKA) */
+ BlueQuantum, /* Blue values only (RGBA) */
+ MagentaQuantum, /* Magenta values only (CMYKA) */
+ AlphaQuantum, /* Transparency values (RGBA or CMYKA) */
+ BlackQuantum, /* Black values only (CMYKA) */
+ RGBQuantum, /* Red, green, and blue values */
+ RGBAQuantum, /* Red, green, blue, and transparency values */
+ CMYKQuantum, /* Cyan, magenta, yellow, and black values */
+ CMYKAQuantum, /* Cyan, magenta, yellow, black, and transparency values */
+ CIEYQuantum, /* CIE Y values, based on CCIR-709 primaries */
+ CIEXYZQuantum /* CIE XYZ values, based on CCIR-709 primaries */
+} QuantumType;
+
+/*
+ Quantum sample type for when exporting/importing a pixel area.
+*/
+typedef enum
+{
+ UndefinedQuantumSampleType, /* Not specified */
+ UnsignedQuantumSampleType, /* Unsigned integral type (1-32 or 64 bits) */
+ FloatQuantumSampleType /* Floating point type (16, 24, 32, or 64 bit) */
+} QuantumSampleType;
+
+/*
+ Quantum size types as used by ConstituteImage() and DispatchImage()/
+*/
+typedef enum
+{
+ CharPixel, /* Unsigned 8 bit 'unsigned char' */
+ ShortPixel, /* Unsigned 16 bit 'unsigned short int' */
+ IntegerPixel, /* Unsigned 32 bit 'unsigned int' */
+ LongPixel, /* Unsigned 32 or 64 bit (CPU dependent) 'unsigned long' */
+ FloatPixel, /* Floating point 32-bit 'float' */
+ DoublePixel /* Floating point 64-bit 'double' */
+} StorageType;
+
+/*
+ Additional options for ExportImagePixelArea()
+*/
+typedef struct _ExportPixelAreaOptions
+{
+ QuantumSampleType
+ sample_type; /* Quantum sample type */
+
+ double
+ double_minvalue, /* Minimum value (default 0.0) for linear floating point samples */
+ double_maxvalue; /* Maximum value (default 1.0) for linear floating point samples */
+
+ MagickBool
+ grayscale_miniswhite; /* Grayscale minimum value is white rather than black */
+
+ unsigned long
+ pad_bytes; /* Number of pad bytes to output after pixel data */
+
+ unsigned char
+ pad_value; /* Value to use when padding end of pixel data */
+
+ EndianType
+ endian; /* Endian orientation for 16/32/64 bit types (default MSBEndian) */
+
+ unsigned long
+ signature;
+} ExportPixelAreaOptions;
+
+/*
+ Optional results info for ExportImagePixelArea()
+*/
+typedef struct _ExportPixelAreaInfo
+{
+ size_t
+ bytes_exported; /* Number of bytes which were exported */
+
+} ExportPixelAreaInfo;
+
+/*
+ Additional options for ImportImagePixelArea()
+*/
+typedef struct _ImportPixelAreaOptions
+{
+ QuantumSampleType
+ sample_type; /* Quantum sample type */
+
+ double
+ double_minvalue, /* Minimum value (default 0.0) for linear floating point samples */
+ double_maxvalue; /* Maximum value (default 1.0) for linear floating point samples */
+
+ MagickBool
+ grayscale_miniswhite; /* Grayscale minimum value is white rather than black */
+
+ EndianType
+ endian; /* Endian orientation for 16/32/64 bit types (default MSBEndian) */
+
+ unsigned long
+ signature;
+} ImportPixelAreaOptions;
+
+/*
+ Optional results info for ImportImagePixelArea()
+*/
+typedef struct _ImportPixelAreaInfo
+{
+ size_t
+ bytes_imported; /* Number of bytes which were imported */
+
+} ImportPixelAreaInfo;
+
+extern MagickExport const char
+ *StorageTypeToString(const StorageType storage_type),
+ *QuantumSampleTypeToString(const QuantumSampleType sample_type),
+ *QuantumTypeToString(const QuantumType quantum_type);
+
+extern MagickExport Image
+ *ConstituteImage(const unsigned long width,const unsigned long height,
+ const char *map,const StorageType type,const void *pixels,
+ ExceptionInfo *exception),
+ *ConstituteTextureImage(const unsigned long columns,const unsigned long rows,
+ const Image *texture,ExceptionInfo *exception),
+ *PingImage(const ImageInfo *image_info,ExceptionInfo *exception),
+ *ReadImage(const ImageInfo *image_info,ExceptionInfo *exception),
+ *ReadInlineImage(const ImageInfo *image_info,const char *content,
+ ExceptionInfo *exception);
+
+extern MagickExport MagickPassFail
+ DispatchImage(const Image *image,const long x_offset,const long y_offset,
+ const unsigned long columns,const unsigned long rows,const char *map,
+ const StorageType type,void *pixels,ExceptionInfo *exception),
+ ExportImagePixelArea(const Image *image,const QuantumType quantum_type,
+ const unsigned int quantum_size,unsigned char *destination,
+ const ExportPixelAreaOptions *options,ExportPixelAreaInfo *export_info),
+ ExportViewPixelArea(const ViewInfo *view,const QuantumType quantum_type,
+ const unsigned int quantum_size,unsigned char *destination,
+ const ExportPixelAreaOptions *options,ExportPixelAreaInfo *export_info);
+
+extern MagickExport MagickPassFail
+ ImportImagePixelArea(Image *image,const QuantumType quantum_type,
+ const unsigned int quantum_size,const unsigned char *source,
+ const ImportPixelAreaOptions *options,ImportPixelAreaInfo *import_info),
+ ImportViewPixelArea(ViewInfo *view,const QuantumType quantum_type,
+ const unsigned int quantum_size,const unsigned char *source,
+ const ImportPixelAreaOptions *options,ImportPixelAreaInfo *import_info),
+ WriteImage(const ImageInfo *image_info,Image *image),
+ WriteImages(const ImageInfo *image_info,Image *image,const char *filename,
+ ExceptionInfo *exception),
+ WriteImagesFile(const ImageInfo *image_info,Image *image,FILE * file,
+ ExceptionInfo *exception);
+
+extern MagickExport void
+ ExportPixelAreaOptionsInit(ExportPixelAreaOptions *options),
+ ImportPixelAreaOptionsInit(ImportPixelAreaOptions *options);
+
+extern MagickExport MagickPassFail
+ MagickFindRawImageMinMax(Image *image, EndianType endian,
+ unsigned long width, unsigned long height,StorageType type,
+ unsigned scanline_octets, void *scanline_buffer,
+ double *min, double *max);
+
+extern MagickExport unsigned int
+ MagickGetQuantumSamplesPerPixel(const QuantumType quantum_type);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+extern MagickExport void
+ DestroyConstitute(void);
+
+extern MagickPassFail
+ InitializeConstitute(void);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_CONSTITUTE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/decorate.c b/magick/decorate.c
new file mode 100644
index 0000000..f3f03e9
--- /dev/null
+++ b/magick/decorate.c
@@ -0,0 +1,624 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD EEEEE CCCC OOO RRRR AAA TTTTT EEEEE %
+% D D E C O O R R A A T E %
+% D D EEE C O O RRRR AAAAA T EEE %
+% D D E C O O R R A A T E %
+% DDDD EEEEE CCCC OOO R R A A T EEEEE %
+% %
+% %
+% GraphicsMagick Image Decoration Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/color.h"
+#include "magick/decorate.h"
+#include "magick/pixel_cache.h"
+#include "magick/monitor.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B o r d e r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BorderImage() surrounds the image with a border of the color defined by
+% the bordercolor member of the image structure. The width and height
+% of the border are defined by the corresponding members of the border_info
+% structure.
+%
+% The format of the BorderImage method is:
+%
+% Image *BorderImage(const Image *image,const RectangleInfo *border_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o border_info: Define the width and height of the border.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *BorderImage(const Image *image,
+ const RectangleInfo *border_info,ExceptionInfo *exception)
+{
+ Image
+ *border_image,
+ *clone_image;
+
+ FrameInfo
+ frame_info;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(border_info != (RectangleInfo *) NULL);
+ frame_info.width=image->columns+(border_info->width << 1);
+ frame_info.height=image->rows+(border_info->height << 1);
+ frame_info.x=(long) border_info->width;
+ frame_info.y=(long) border_info->height;
+ frame_info.inner_bevel=0;
+ frame_info.outer_bevel=0;
+ clone_image=CloneImage(image,0,0,True,exception);
+ if (clone_image == (Image *) NULL)
+ return((Image *) NULL);
+ clone_image->matte_color=image->border_color;
+ border_image=FrameImage(clone_image,&frame_info,exception);
+ DestroyImage(clone_image);
+ if (border_image != (Image *) NULL)
+ border_image->matte_color=image->matte_color;
+ return(border_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F r a m e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FrameImage() adds a simulated three-dimensional border around the image.
+% The color of the border is defined by the matte_color member of image.
+% Members width and height of frame_info specify the border width of the
+% vertical and horizontal sides of the frame. Members inner and outer
+% indicate the width of the inner and outer shadows of the frame.
+%
+% The format of the FrameImage method is:
+%
+% Image *FrameImage(const Image *image,const FrameInfo *frame_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o frame_info: Define the width and height of the frame and its bevels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *FrameImage(const Image *image,const FrameInfo *frame_info,
+ ExceptionInfo *exception)
+{
+#define FrameImageText "[%s] Frame: %lux%lu%+ld%+ld bevel inner %ld outer %ld..."
+
+ Image
+ *frame_image;
+
+ unsigned long
+ row_count=0;
+
+ long
+ height,
+ width,
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ PixelPacket
+ accentuate,
+ highlight,
+ matte,
+ shadow,
+ trough;
+
+ unsigned long
+ bevel_width;
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Check frame geometry.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(frame_info != (FrameInfo *) NULL);
+ is_grayscale=image->is_grayscale;
+ if ((frame_info->outer_bevel < 0) || (frame_info->inner_bevel < 0))
+ ThrowImageException3(OptionError,UnableToFrameImage,
+ BevelWidthIsNegative);
+ bevel_width=frame_info->outer_bevel+frame_info->inner_bevel;
+ width=(long) (frame_info->width-frame_info->x-bevel_width);
+ height=(long) (frame_info->height-frame_info->y-bevel_width);
+ if ((width < (long) image->columns) || (height < (long) image->rows))
+ ThrowImageException3(OptionError,UnableToFrameImage,
+ FrameIsLessThanImageSize);
+ /*
+ Allocate image
+ */
+ frame_image=
+ CloneImage(image,frame_info->width,frame_info->height,True,exception);
+ if (frame_image == (Image *) NULL)
+ return(False);
+
+ /*
+ Set image type.
+ */
+ (void) SetImageType(frame_image,frame_image->matte_color.opacity !=
+ OpaqueOpacity ? TrueColorMatteType : TrueColorType);
+
+ /*
+ Initialize 3D effects color.
+ */
+ matte=image->matte_color;
+ if (!IsGray(image->matte_color))
+ is_grayscale=False;
+ accentuate.red=(Quantum) ((((double) MaxRGB-AccentuateModulate)*matte.red+
+ ((double) MaxRGB*AccentuateModulate))/MaxRGB+0.5);
+ accentuate.green=(Quantum) ((((double) MaxRGB-AccentuateModulate)*matte.green+
+ ((double) MaxRGB*AccentuateModulate))/MaxRGB+0.5);
+ accentuate.blue=(Quantum) ((((double) MaxRGB-AccentuateModulate)*matte.blue+
+ ((double) MaxRGB*AccentuateModulate))/MaxRGB+0.5);
+ accentuate.opacity=(Quantum) ((((double) MaxRGB-AccentuateModulate)*
+ matte.opacity+((double) MaxRGB*AccentuateModulate))/MaxRGB+0.5);
+ highlight.red=(Quantum) ((((double) MaxRGB-HighlightModulate)*matte.red+
+ ((double) MaxRGB*HighlightModulate))/MaxRGB+0.5);
+ highlight.green=(Quantum) ((((double) MaxRGB-HighlightModulate)*matte.green+
+ ((double) MaxRGB*HighlightModulate))/MaxRGB+0.5);
+ highlight.blue=(Quantum) ((((double) MaxRGB-HighlightModulate)*matte.blue+
+ ((double) MaxRGB*HighlightModulate))/MaxRGB+0.5);
+ highlight.opacity=(Quantum) ((((double) MaxRGB-HighlightModulate)*
+ matte.opacity+((double) MaxRGB*HighlightModulate))/MaxRGB+0.5);
+ shadow.red=(Quantum) (((double) matte.red*ShadowModulate)/MaxRGB+0.5);
+ shadow.green=(Quantum) (((double) matte.green*ShadowModulate)/MaxRGB+0.5);
+ shadow.blue=(Quantum) (((double) matte.blue*ShadowModulate)/MaxRGB+0.5);
+ shadow.opacity=(Quantum) (((double) matte.opacity*ShadowModulate)/MaxRGB+0.5);
+ trough.red=(Quantum) (((double) matte.red*TroughModulate)/MaxRGB+0.5);
+ trough.green=(Quantum) (((double) matte.green*TroughModulate)/MaxRGB+0.5);
+ trough.blue=(Quantum) (((double) matte.blue*TroughModulate)/MaxRGB+0.5);
+ trough.opacity=(Quantum) (((double) matte.opacity*TroughModulate)/MaxRGB+0.5);
+ /*
+ Draw top of ornamental border.
+ */
+ height=(long) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
+ frame_info->inner_bevel);
+ q=SetImagePixelsEx(frame_image,0,0,frame_image->columns,height,exception);
+ if (q != (PixelPacket *) NULL)
+ {
+ for (y=0; y < frame_info->outer_bevel; y++)
+ {
+ for (x=0; x < (long) (frame_image->columns-y); x++)
+ if (x < y)
+ *q++=highlight;
+ else
+ *q++=accentuate;
+ for ( ; x < (long) frame_image->columns; x++)
+ *q++=shadow;
+ }
+ for (y=0; y < (long) (frame_info->y-bevel_width); y++)
+ {
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=highlight;
+ width=(long) (frame_image->columns-2*frame_info->outer_bevel);
+ for (x=0; x < (long) width; x++)
+ *q++=matte;
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=shadow;
+ }
+ for (y=0; y < frame_info->inner_bevel; y++)
+ {
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=highlight;
+ for (x=0; x < (long) (frame_info->x-bevel_width); x++)
+ *q++=matte;
+ width=(long) (image->columns+(frame_info->inner_bevel << 1)-y);
+ for (x=0; x < width; x++)
+ if (x < y)
+ *q++=shadow;
+ else
+ *q++=trough;
+ for ( ; x < (long) (image->columns+(frame_info->inner_bevel << 1)); x++)
+ *q++=highlight;
+ width=(long)
+ (frame_info->width-frame_info->x-image->columns-bevel_width);
+ for (x=0; x < width; x++)
+ *q++=matte;
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=shadow;
+ }
+ (void) SyncImagePixelsEx(frame_image,exception);
+ }
+ /*
+ Draw sides of ornamental border.
+ */
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status) private (p, q, width, x)
+# else
+# pragma omp parallel for schedule(static,8) shared(row_count, status) private (p, q, width, x)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_FrameImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ /*
+ Initialize scanline with border color.
+ */
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ q=SetImagePixelsEx(frame_image,0,frame_info->y+y,frame_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=highlight;
+ for (x=0; x < (long) (frame_info->x-bevel_width); x++)
+ *q++=matte;
+ for (x=0; x < frame_info->inner_bevel; x++)
+ *q++=shadow;
+ /*
+ Transfer scanline.
+ */
+ (void) memcpy(q,p,image->columns*sizeof(PixelPacket));
+ q+=image->columns;
+ for (x=0; x < frame_info->inner_bevel; x++)
+ *q++=highlight;
+ width=(long) (frame_info->width-frame_info->x-image->columns-bevel_width);
+ for (x=0; x < width; x++)
+ *q++=matte;
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=shadow;
+ if (!SyncImagePixelsEx(frame_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_FrameImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ FrameImageText,image->filename,
+ frame_info->width,frame_info->height,
+ frame_info->x,
+ frame_info->y,
+ frame_info->inner_bevel,
+ frame_info->outer_bevel))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ /*
+ Draw bottom of ornamental border.
+ */
+ height=(long) (frame_info->inner_bevel+frame_info->height-frame_info->y-
+ image->rows-bevel_width+frame_info->outer_bevel);
+ q=SetImagePixelsEx(frame_image,0,(long) (frame_image->rows-height),
+ frame_image->columns,height,exception);
+ if (q == (PixelPacket *) NULL)
+ return(frame_image);
+ for (y=frame_info->inner_bevel-1; y >= 0; y--)
+ {
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=highlight;
+ for (x=0; x < (long) (frame_info->x-bevel_width); x++)
+ *q++=matte;
+ for (x=0; x < y; x++)
+ *q++=shadow;
+ for ( ; x < (long) (image->columns+(frame_info->inner_bevel << 1)); x++)
+ if (x >= (long) (image->columns+(frame_info->inner_bevel << 1)-y))
+ *q++=highlight;
+ else
+ *q++=accentuate;
+ width=(long) (frame_info->width-frame_info->x-image->columns-bevel_width);
+ for (x=0; x < (long) width; x++)
+ *q++=matte;
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=shadow;
+ }
+ height=(long) (frame_info->height-frame_info->y-image->rows-bevel_width);
+ for (y=0; y < height; y++)
+ {
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=highlight;
+ for (x=0; x < (long) (frame_image->columns-2*frame_info->outer_bevel); x++)
+ *q++=matte;
+ for (x=0; x < frame_info->outer_bevel; x++)
+ *q++=shadow;
+ }
+ for (y=frame_info->outer_bevel-1; y >= 0; y--)
+ {
+ for (x=0; x < y; x++)
+ *q++=highlight;
+ for ( ; x < (long) frame_image->columns; x++)
+ if (x >= (long) (frame_image->columns-y))
+ *q++=shadow;
+ else
+ *q++=trough;
+ }
+ (void) SyncImagePixelsEx(frame_image,exception);
+
+ frame_image->is_grayscale=is_grayscale;
+ return(frame_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R a i s e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RaiseImage() creates a simulated three-dimensional button-like effect
+% by lightening and darkening the edges of the image. Members width and
+% height of raise_info define the width of the vertical and horizontal
+% edge of the effect.
+%
+% The format of the RaiseImage method is:
+%
+% unsigned int RaiseImage(Image *image,const RectangleInfo *raise_info,
+% const int raise_flag)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o raise_info: Define the width and height of the raise area.
+%
+% o raise_flag: A value other than zero creates a 3-D raise effect,
+% otherwise it has a lowered effect.
+%
+%
+*/
+#define AccentuateFactor (double) ScaleCharToQuantum(135)
+#define HighlightFactor (double) ScaleCharToQuantum(190)
+#define ShadowFactor (double) ScaleCharToQuantum(190)
+#define RaiseImageText "[%s] Raise..."
+#define TroughFactor (double) ScaleCharToQuantum(135)
+
+MagickExport MagickPassFail
+RaiseImage(Image *image,const RectangleInfo *raise_info,const int raise_flag)
+{
+ unsigned long
+ row_count=0;
+
+ double
+ foreground,
+ background;
+
+ long
+ y;
+
+ register long
+ x;
+
+ unsigned int
+ is_grayscale;
+
+ register PixelPacket
+ *q;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(raise_info != (RectangleInfo *) NULL);
+ is_grayscale=image->is_grayscale;
+ if ((image->columns <= (raise_info->width << 1)) ||
+ (image->rows <= (raise_info->height << 1)))
+ ThrowBinaryException3(OptionError,UnableToRaiseImage,
+ ImageSizeMustExceedBevelWidth);
+
+ foreground=MaxRGBDouble;
+ background=0.0;
+ if (!raise_flag)
+ {
+ foreground=0.0;
+ background=MaxRGBDouble;
+ }
+ (void) SetImageType(image,TrueColorType);
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status) private (q, x)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status) private (q, x)
+# endif
+#endif
+ for ( y=0; y < (long) image->rows; y++)
+ {
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_RaiseImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ q=GetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ if (y < (long) raise_info->height)
+ {
+ for (x=0; x < y; x++)
+ {
+ q[x].red=(Quantum) ((q[x].red*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble);
+ q[x].green=(Quantum) ((q[x].green*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble);
+ q[x].blue=(Quantum) ((q[x].blue*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble);
+ }
+ for ( ; x < (long) (image->columns-y); x++)
+ {
+ q[x].red=(Quantum) ((q[x].red*AccentuateFactor+
+ foreground*(MaxRGBDouble-AccentuateFactor))/MaxRGBDouble);
+ q[x].green=(Quantum) ((q[x].green*AccentuateFactor+
+ foreground*(MaxRGBDouble-AccentuateFactor))/MaxRGBDouble);
+ q[x].blue=(Quantum) ((q[x].blue*AccentuateFactor+
+ foreground*(MaxRGBDouble-AccentuateFactor))/MaxRGBDouble);
+ }
+ for ( ; x < (long) image->columns; x++)
+ {
+ q[x].red=(Quantum) ((q[x].red*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble);
+ q[x].green=(Quantum) ((q[x].green*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble);
+ q[x].blue=(Quantum) ((q[x].blue*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble);
+ }
+ }
+ else if (y < (long) (image->rows-raise_info->height))
+ {
+ for (x=0; x < (long) raise_info->width; x++)
+ {
+ q[x].red=(Quantum) ((q[x].red*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble);
+ q[x].green=(Quantum) ((q[x].green*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble);
+ q[x].blue=(Quantum) ((q[x].blue*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble);
+ }
+ for ( ; x < (long) (image->columns-raise_info->width); x++);
+ for ( ; x < (long) image->columns; x++)
+ {
+ q[x].red=(Quantum) ((q[x].red*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble);
+ q[x].green=(Quantum) ((q[x].green*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble);
+ q[x].blue=(Quantum) ((q[x].blue*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble);
+ }
+ }
+ else
+ {
+ for (x=0; x < (long) (image->rows-y); x++)
+ {
+ q[x].red=(Quantum) ((q[x].red*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble+0.5);
+ q[x].green=(Quantum) ((q[x].green*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble+0.5);
+ q[x].blue=(Quantum) ((q[x].blue*HighlightFactor+
+ foreground*(MaxRGBDouble-HighlightFactor))/MaxRGBDouble+0.5);
+ }
+ for ( ; x < (long) (image->columns-(image->rows-y)); x++)
+ {
+ q[x].red=(Quantum) ((q[x].red*TroughFactor+
+ background*(MaxRGBDouble-TroughFactor))/MaxRGBDouble+0.5);
+ q[x].green=(Quantum) ((q[x].green*TroughFactor+
+ background*(MaxRGBDouble-TroughFactor))/MaxRGBDouble+0.5);
+ q[x].blue=(Quantum) ((q[x].blue*TroughFactor+
+ background*(MaxRGBDouble-TroughFactor))/MaxRGBDouble+0.5);
+ }
+ for ( ; x < (long) image->columns; x++)
+ {
+ q[x].red=(Quantum) ((q[x].red*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble+0.5);
+ q[x].green=(Quantum) ((q[x].green*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble+0.5);
+ q[x].blue=(Quantum) ((q[x].blue*ShadowFactor+
+ background*(MaxRGBDouble-ShadowFactor))/MaxRGBDouble+0.5);
+ }
+ }
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_RaiseImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,&image->exception,
+ RaiseImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ image->is_grayscale=is_grayscale;
+ return(status);
+}
diff --git a/magick/decorate.h b/magick/decorate.h
new file mode 100644
index 0000000..f041984
--- /dev/null
+++ b/magick/decorate.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Decorate Methods.
+*/
+#ifndef _MAGICK_DECORATE_H
+#define _MAGICK_DECORATE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport Image
+ *BorderImage(const Image *,const RectangleInfo *,ExceptionInfo *),
+ *FrameImage(const Image *,const FrameInfo *,ExceptionInfo *);
+
+MagickExport unsigned int
+ RaiseImage(Image *,const RectangleInfo *,const int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_DECORATE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/delegate.c b/magick/delegate.c
new file mode 100644
index 0000000..3ea785c
--- /dev/null
+++ b/magick/delegate.c
@@ -0,0 +1,1622 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% DDDD EEEEE L EEEEE GGGG AAA TTTTT EEEEE %
+% D D E L E G A A T E %
+% D D EEE L EEE G GG AAAAA T EEE %
+% D D E L E G G A A T E %
+% DDDD EEEEE LLLLL EEEEE GGG A A T EEEEE %
+% %
+% %
+% Methods to Read/Write/Invoke Delegates %
+% %
+% %
+% Software Design %
+% John Cristy %
+% October 1998 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The Delegates methods associate a set of commands with a particular
+% image format. GraphicsMagick uses delegates for formats it does not handle
+% directly.
+%
+% Thanks to Bob Friesenhahn for the initial inspiration and design of the
+% delegates methods.
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/log.h"
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+# include "magick/nt_feature.h"
+#endif
+#if defined(POSIX)
+# include "magick/unix_port.h"
+#endif
+#include "magick/semaphore.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define DelegateFilename "delegates.mgk"
+
+/*
+ Declare delegate map.
+*/
+static char
+ *DelegateMap = (char *)
+ "<?xml version=\"1.0\"?>"
+ "<delegatemap>"
+ " <delegate stealth=\"True\" />"
+ "</delegatemap>";
+
+/*
+ Global declaractions.
+*/
+static SemaphoreInfo
+ *delegate_semaphore = (SemaphoreInfo *) NULL;
+
+static DelegateInfo
+ *delegate_list = (DelegateInfo *) NULL;
+
+/*
+ Forward declaractions.
+*/
+static unsigned int
+ ReadConfigureFile(const char *,const unsigned long,ExceptionInfo *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y D e l e g a t e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyDelegateInfo deallocates memory associated with the delegates
+% list.
+%
+% The format of the DestroyDelegateInfo method is:
+%
+% DestroyDelegateInfo(void)
+%
+*/
+MagickExport void DestroyDelegateInfo(void)
+{
+ DelegateInfo
+ *delegate_info;
+
+ register DelegateInfo
+ *p;
+
+ for (p=delegate_list; p != (DelegateInfo *) NULL; )
+ {
+ delegate_info=p;
+ p=p->next;
+ if (delegate_info->path != (char *) NULL)
+ MagickFreeMemory(delegate_info->path);
+ if (delegate_info->decode != (char *) NULL)
+ MagickFreeMemory(delegate_info->decode);
+ if (delegate_info->encode != (char *) NULL)
+ MagickFreeMemory(delegate_info->encode);
+ if (delegate_info->commands != (char *) NULL)
+ MagickFreeMemory(delegate_info->commands);
+ MagickFreeMemory(delegate_info);
+ }
+ delegate_list=(DelegateInfo *) NULL;
+ DestroySemaphoreInfo(&delegate_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t D e l e g a t e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetDelegateCommand replaces any embedded formatting characters with
+% the appropriate image attribute and returns the resulting command.
+%
+% The format of the GetDelegateCommand method is:
+%
+% char *GetDelegateCommand(const ImageInfo *image_info,Image *image,
+% const char *decode,const char *encode,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o command: Method GetDelegateCommand returns the command associated
+% with specified delegate tag.
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+% o decode: Specifies the decode delegate we are searching for as a
+% character string.
+%
+% o encode: Specifies the encode delegate we are searching for as a
+% character string.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport char *GetDelegateCommand(const ImageInfo *image_info,Image *image,
+ const char *decode,const char *encode,ExceptionInfo *exception)
+{
+ char
+ *command,
+ **commands;
+
+ const DelegateInfo
+ *delegate_info;
+
+ register long
+ i;
+
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ delegate_info=GetDelegateInfo(decode,encode,exception);
+ if (delegate_info == (const DelegateInfo *) NULL)
+ {
+ ThrowException(exception,DelegateError,NoTagFound,
+ decode ? decode : encode);
+ return((char *) NULL);
+ }
+ commands=StringToList(delegate_info->commands);
+ if (commands == (char **) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ decode ? decode : encode);
+ return((char *) NULL);
+ }
+ command=TranslateText(image_info,image,commands[0]);
+ if (command == (char *) NULL)
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ commands[0]);
+ /*
+ Free resources.
+ */
+ for (i=0; commands[i] != (char *) NULL; i++)
+ MagickFreeMemory(commands[i]);
+ MagickFreeMemory(commands);
+ return(command);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t D e l e g a t e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetDelegateInfo returns any delegates associated with the specified
+% tag.
+%
+% The format of the GetDelegateInfo method is:
+%
+% const DelegateInfo *GetDelegateInfo(const char *decode,
+% const char *encode,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o delgate_info: Method GetDelegateInfo returns any delegates associated
+% with the specified tag.
+%
+% o decode: Specifies the decode delegate we are searching for as a
+% character string.
+%
+% o encode: Specifies the encode delegate we are searching for as a
+% character string.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const DelegateInfo *GetDelegateInfo(const char *decode,
+ const char *encode,ExceptionInfo *exception)
+{
+ register DelegateInfo
+ *p;
+
+ if (delegate_list == (DelegateInfo *) NULL)
+ {
+ LockSemaphoreInfo(delegate_semaphore);
+ if (delegate_list == (DelegateInfo *) NULL)
+ (void) ReadConfigureFile(DelegateFilename,0,exception);
+ UnlockSemaphoreInfo(delegate_semaphore);
+ }
+ if ((LocaleCompare(decode,"*") == 0) && (LocaleCompare(encode,"*") == 0))
+ return((const DelegateInfo *) delegate_list);
+ /*
+ Search for requested delegate.
+ */
+ LockSemaphoreInfo(delegate_semaphore);
+ for (p=delegate_list; p != (const DelegateInfo *) NULL; p=p->next)
+ {
+ if (p->mode > 0)
+ {
+ if (LocaleCompare(p->decode,decode) == 0)
+ break;
+ continue;
+ }
+ if (p->mode < 0)
+ {
+ if (LocaleCompare(p->encode,encode) == 0)
+ break;
+ continue;
+ }
+ if (LocaleCompare(decode,p->decode) == 0)
+ if (LocaleCompare(encode,p->encode) == 0)
+ break;
+ if (LocaleCompare(decode,"*") == 0)
+ if (LocaleCompare(encode,p->encode) == 0)
+ break;
+ if (LocaleCompare(decode,p->decode) == 0)
+ if (LocaleCompare(encode,"*") == 0)
+ break;
+ }
+ if (p != (DelegateInfo *) NULL)
+ if (p != delegate_list)
+ {
+ /*
+ Self-adjusting list.
+ */
+ if (p->previous != (DelegateInfo *) NULL)
+ p->previous->next=p->next;
+ if (p->next != (DelegateInfo *) NULL)
+ p->next->previous=p->previous;
+ p->previous=(DelegateInfo *) NULL;
+ p->next=delegate_list;
+ delegate_list->previous=p;
+ delegate_list=p;
+ }
+ UnlockSemaphoreInfo(delegate_semaphore);
+ return((const DelegateInfo *) p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t P o s t s c r i p t D e l e g a t e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetPostscriptDelegateInfo returns the Postscript delegate which
+% best supports the image type requested via ImageInfo
+%
+% The format of the GetPostscriptDelegateInfo method is:
+%
+% const DelegateInfo *(const ImageInfo *image_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The 'monochrome' and 'type' fields of image_info are used
+% to select the best postscript delegate type.
+%
+% o antialias: Set to best antialias setting for this delegate based on
+% user requested antialias setting, and rendering depth.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const DelegateInfo *GetPostscriptDelegateInfo(const ImageInfo *image_info,
+ unsigned int *antialias,
+ ExceptionInfo *exception)
+{
+ char
+ delegate[MaxTextExtent];
+
+ (void) strlcpy(delegate,"gs-color",sizeof(delegate));
+ *antialias=(image_info->antialias ? 4 : 1);
+ if ((image_info->monochrome) || (BilevelType == image_info->type))
+ {
+ (void) strlcpy(delegate,"gs-mono",sizeof(delegate));
+ *antialias=1;
+ }
+ else if (GrayscaleType == image_info->type)
+ {
+ (void) strlcpy(delegate,"gs-gray",sizeof(delegate));
+ }
+ else if (PaletteType == image_info->type)
+ {
+ (void) strlcpy(delegate,"gs-palette",sizeof(delegate));
+ }
+ else if ((GrayscaleMatteType == image_info->type) ||
+ (PaletteMatteType == image_info->type) ||
+ (TrueColorMatteType == image_info->type))
+ {
+ (void) strlcpy(delegate,"gs-color+alpha",sizeof(delegate));
+ }
+ else if (ColorSeparationType == image_info->type)
+ {
+ (void) strlcpy(delegate,"gs-cmyk",sizeof(delegate));
+ }
+ else if (ColorSeparationMatteType == image_info->type)
+ {
+ (void) strlcpy(delegate,"gs-cmyka",sizeof(delegate));
+ }
+ return GetDelegateInfo(delegate,(char *) NULL,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e D e l e g a t e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeDelegateInfo initializes the delegate facility
+%
+% The format of the InitializeDelegateInfo method is:
+%
+% MagickPassFail InitializeDelegateInfo(void)
+%
+%
+*/
+MagickPassFail
+InitializeDelegateInfo(void)
+{
+ assert(delegate_semaphore == (SemaphoreInfo *) NULL);
+ delegate_semaphore=AllocateSemaphoreInfo();
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n v o k e D e l e g a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InvokeDelegate replaces any embedded formatting characters with
+% the appropriate image attribute and executes the resulting command. False
+% is returned if the commands execute with success otherwise True.
+%
+% The format of the InvokeDelegate method is:
+%
+% unsigned int InvokeDelegate(ImageInfo *image_info,Image *image,
+% const char *decode,const char *encode,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The imageInfo.
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#if defined(POSIX)
+/*
+ Escape characters from the string 'src' to the string 'dst',
+ limiting the number of output characters according to 'size'.
+*/
+static size_t
+UnixShellTextEscape(char *dst, const char *src, const size_t size)
+{
+ size_t
+ length=0;
+
+ char
+ *p;
+
+ const char
+ *q;
+
+ assert(dst != NULL);
+ assert(src != (const char *) NULL);
+ assert(size >= 1);
+
+ /*
+ Copy src to dst within bounds of size-1, while escaping special
+ characters.
+ */
+ for ( p=dst, q=src, length=0 ;
+ (*q != 0) && (length < size-1) ;
+ length++, p++, q++ )
+ {
+ register const char c = *q;
+ if ((c == '\\') ||
+ (c == '`') ||
+ (c == '"') ||
+ (c == '$'))
+ {
+ if (length+1 >= size-1)
+ break;
+ *p = '\\';
+ p++;
+ length++;
+ }
+ *p = c;
+ }
+
+ dst[length]='\0';
+
+ return length;
+}
+#endif /* POSIX */
+
+#if defined(HAVE_SPAWNVP) /* Windows spawnvp() */
+/*
+ Escape a dynamically-allocated string argument (if needed),
+ replacing with a new allocation if escaping was necessary.
+*/
+static void
+WindowsArgumentTextEscape(char **arg)
+{
+ const char
+ *sa;
+
+ char
+ *escaped;
+
+ size_t
+ e,
+ i,
+ length;
+
+ MagickBool
+ do_escape=MagickFalse;
+
+ /*
+ Compute length, allowing for escape characters.
+
+ It is possible that other characters should be escaped, but we are
+ unaware of the specific characters or the correct syntax. The
+ characters and syntax might depend on the version of Windows or
+ the Windows CRT used.
+ */
+ e=0;
+ length=0;
+ sa=*arg;
+ for ( i=0; sa[i] != '\0'; i++)
+ {
+ if (isspace((int) sa[i]))
+ {
+ length += 2;
+ do_escape=MagickTrue;
+ }
+ length++;
+ }
+ length++; /* null */
+ if (do_escape)
+ {
+ /*
+ Allocate buffer
+ */
+ escaped=MagickAllocateMemory(char *,length);
+ /*
+ Escape into buffer
+ */
+ if (escaped != (char *) NULL)
+ {
+ sa=*arg;
+ e=0;
+ for ( i=0; sa[i] != '\0'; i++)
+ {
+ char c=sa[i];
+ if (isspace((int) c))
+ {
+ escaped[e++]='"';
+ escaped[e++]=c;
+ escaped[e++]='"';
+ }
+ else
+ {
+ escaped[e++]=c;
+ }
+ }
+ escaped[e]='\0';
+ MagickFreeMemory(*arg);
+ *arg = escaped;
+ }
+ }
+}
+#endif /* defined(HAVE_SPAWNVP) */
+#if defined(MSWINDOWS)
+/*
+ Escape characters from the string 'src' to the string 'dst',
+ limiting the number of output characters according to 'size'.
+*/
+static size_t
+WindowsShellTextEscape(char *dst, const char *src, const size_t size)
+{
+ size_t
+ length=0;
+
+ char
+ *p;
+
+ const char
+ *q;
+
+ assert(dst != NULL);
+ assert(src != (const char *) NULL);
+ assert(size >= 1);
+
+
+ /*
+ Copy src to dst within bounds of size-1, while escaping special
+ characters.
+ */
+ for ( p=dst, q=src, length=0 ;
+ (*q != 0) && (length < size-1) ;
+ length++, p++, q++ )
+ {
+ register const char c = *q;
+#if 0
+ /*
+ FIXME: Currently the correct implementation is not known so we
+ don't alter arguments at the moment.
+ */
+ if ((c == '\\') ||
+ (c == '"') ||
+ (c == '%%'))
+ {
+ if (length+1 >= size-1)
+ break;
+ *p = '\\';
+ p++;
+ length++;
+ }
+#endif
+ *p = c;
+ }
+
+ dst[length]='\0';
+
+ return length;
+}
+#endif /* MSWINDOWS */
+
+MagickExport unsigned int InvokeDelegate(ImageInfo *image_info,Image *image,
+ const char *decode,const char *encode,ExceptionInfo *exception)
+{
+ char
+ *command,
+ **commands,
+ filename[MaxTextExtent];
+
+ const DelegateInfo
+ *delegate_info;
+
+ register long
+ i;
+
+ unsigned int
+ status,
+ temporary_image_filename;
+
+ /*
+ Get delegate.
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ temporary_image_filename=(*image->filename == '\0');
+ if (temporary_image_filename)
+ {
+ /* Allocate a temporary filename if image is unnamed. */
+ if(!AcquireTemporaryFileName(image->filename))
+ {
+ (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image->filename);
+ return(False);
+ }
+ }
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ delegate_info=GetDelegateInfo(decode,encode,exception);
+ if (delegate_info == (DelegateInfo *) NULL)
+ {
+ if (temporary_image_filename)
+ (void) LiberateTemporaryFile(image->filename);
+ (void) ThrowException(exception,DelegateError,NoTagFound,
+ decode ? decode : encode);
+ return(False);
+ }
+
+ if (*image_info->filename == '\0')
+ {
+ /* ReadImage will normally have already set image_info->filename
+ to the name of a temporary file. If not, then assign
+ one. Setting image_info->temporary to True indicates that
+ there is a temporary file to be removed later. */
+ if(!AcquireTemporaryFileName(image_info->filename))
+ {
+ if (temporary_image_filename)
+ (void) LiberateTemporaryFile(image->filename);
+ (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->filename);
+ return(False);
+ }
+ image_info->temporary=True;
+ }
+
+ if (delegate_info->mode != 0)
+ if ((decode && (delegate_info->encode != (char *) NULL)) ||
+ (encode && (delegate_info->decode != (char *) NULL)))
+ {
+ char
+ decode_filename[MaxTextExtent],
+ *magick;
+
+ ImageInfo
+ *clone_info;
+
+ register Image
+ *p;
+
+ /*
+ Delegate requires a particular image format.
+ */
+
+ if (!AcquireTemporaryFileName(image_info->unique))
+ {
+ if (temporary_image_filename)
+ (void) LiberateTemporaryFile(image->filename);
+ (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->unique);
+ return(False);
+ }
+
+ if (!AcquireTemporaryFileName(image_info->zero))
+ {
+ if (temporary_image_filename)
+ (void) LiberateTemporaryFile(image->filename);
+ (void) LiberateTemporaryFile(image_info->unique);
+ (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->zero);
+ return(False);
+ }
+ /* Expand sprintf-style codes in delegate command to command string */
+ magick=TranslateText(image_info,image,decode != (char *) NULL ?
+ delegate_info->encode : delegate_info->decode);
+ if (magick == (char *) NULL)
+ {
+ (void) LiberateTemporaryFile(image_info->unique);
+ (void) LiberateTemporaryFile(image_info->zero);
+ if (temporary_image_filename)
+ (void) LiberateTemporaryFile(image->filename);
+ (void) ThrowException(exception,DelegateError,DelegateFailed,
+ decode ? decode : encode);
+ return(False);
+ }
+ LocaleUpper(magick);
+ clone_info=CloneImageInfo(image_info);
+ (void) strlcpy((char *) clone_info->magick,magick,MaxTextExtent);
+ (void) strlcpy(image->magick,magick,MaxTextExtent);
+ MagickFreeMemory(magick);
+ (void) strlcpy(decode_filename,image->filename,MaxTextExtent);
+ FormatString(clone_info->filename,"%.1024s:",delegate_info->decode);
+ (void) SetImageInfo(clone_info,SETMAGICK_WRITE,exception);
+ (void) strlcpy(clone_info->filename,image_info->filename,
+ MaxTextExtent);
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ FormatString(p->filename,"%.1024s:%.1024s",delegate_info->decode,
+ decode_filename);
+ status=WriteImage(clone_info,p);
+ if (status == False)
+ {
+ (void) LiberateTemporaryFile(image_info->unique);
+ (void) LiberateTemporaryFile(image_info->zero);
+ if (temporary_image_filename)
+ (void) LiberateTemporaryFile(image->filename);
+ DestroyImageInfo(clone_info);
+ (void) ThrowException(exception,DelegateError,DelegateFailed,
+ decode ? decode : encode);
+ return(False);
+ }
+ if (clone_info->adjoin)
+ break;
+ }
+ (void) LiberateTemporaryFile(image_info->unique);
+ (void) LiberateTemporaryFile(image_info->zero);
+ DestroyImageInfo(clone_info);
+ }
+ /*
+ Invoke delegate.
+ */
+ (void) strlcpy(image->filename,filename,MaxTextExtent);
+ commands=StringToList(delegate_info->commands);
+ if (commands == (char **) NULL)
+ {
+ if (temporary_image_filename)
+ (void) LiberateTemporaryFile(image->filename);
+ (void) ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,decode ? decode : encode);
+ return(False);
+ }
+ command=(char *) NULL;
+ status=True;
+ /* For each delegate command ... */
+ for (i=0; commands[i] != (char *) NULL; i++)
+ {
+ status=True;
+ /* Allocate convenience temporary files */
+ if (!AcquireTemporaryFileName(image_info->unique))
+ {
+ (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->unique);
+ status=False;
+ goto error_exit;
+ }
+ if (!AcquireTemporaryFileName(image_info->zero))
+ {
+ (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->zero);
+ (void) LiberateTemporaryFile(image_info->unique);
+ status=False;
+ goto error_exit;
+ }
+ {
+ MagickBool
+ needs_shell;
+
+ /*
+ Check to see if command template must be executed via shell
+ due to using constructs requiring multiple processes or I/O
+ redirection.
+ */
+ needs_shell = MagickFalse;
+ {
+ char *
+ p;
+
+ p = commands[i];
+ for (p = commands[i]; *p; p++)
+ {
+ if (('&' == *p) ||
+ (';' == *p) ||
+ ('<' == *p) ||
+ ('>' == *p) ||
+ ('|' == *p))
+ {
+ needs_shell = MagickTrue;
+ break;
+ }
+ }
+ }
+
+ if (MagickFalse == needs_shell)
+ {
+ int
+ arg_count,
+ j;
+
+ char
+ **arg_array;
+
+ /*
+ Convert command template into an argument array. Translate
+ each argument array element individually in order to
+ absolutely avoid any possibility that the number of arguments
+ may be altered due to substituted data.
+ */
+ arg_array = StringToArgv(commands[i],&arg_count);
+ for (j = 0; arg_array[j] != (const char*) NULL; j++)
+ {
+ if (strchr(arg_array[j], '%') != (const char*) NULL)
+ {
+ char *expanded = TranslateText(image_info,image,arg_array[j]);
+ if (expanded != (char *) NULL)
+ {
+ MagickFreeMemory(arg_array[j]);
+ arg_array[j] = expanded;
+ }
+ }
+#if defined(HAVE_SPAWNVP)
+ /*
+ Windows _spawnvp() pretends to offer an argv style
+ interface but actually splits arguments into
+ additional arguments based on white-space. It might
+ have more wonderful properties we are not aware of
+ yet. Escape white-space in arguments with double
+ quotes to avoid the splitting.
+
+ This code should likely be in MagickSpawnVP() but then
+ we would need to clone the input array so it can be
+ modified.
+
+ This undocumented feature is an example of why
+ Microsoft Windows can not be a secure operating
+ system.
+ */
+ WindowsArgumentTextEscape(&arg_array[j]);
+#endif
+ }
+ /*
+ Execute delegate using our secure "spawn" facility.
+ */
+ status = MagickSpawnVP(image_info->verbose,arg_array[1],arg_array+1);
+ for (j = 0; arg_array[j] != (const char*) NULL; j++)
+ MagickFreeMemory(arg_array[j]);
+ MagickFreeMemory(arg_array);
+ }
+ else
+ {
+ /*
+ Expand sprintf-style codes in delegate command to command
+ string, escaping replacement text appropriately
+ */
+ command=TranslateTextEx(image_info,image,commands[i],
+#if defined(POSIX)
+ UnixShellTextEscape
+#endif /* POSIX */
+#if defined(MSWINDOWS)
+ WindowsShellTextEscape
+#endif /* MSWINDOWS */
+ );
+ if (command == (char *) NULL)
+ break;
+ /*
+ Execute delegate using command shell.
+ */
+ status=SystemCommand(image_info->verbose,command);
+ }
+ }
+ MagickFreeMemory(command);
+ /* Liberate convenience temporary files */
+ (void) LiberateTemporaryFile(image_info->unique);
+ (void) LiberateTemporaryFile(image_info->zero);
+ if (status != False)
+ {
+ (void) ThrowException(exception,DelegateError,DelegateFailed,
+ commands[i]);
+ goto error_exit;
+ }
+ MagickFreeMemory(commands[i]);
+ }
+ /*
+ Free resources.
+ */
+ error_exit:
+ if (temporary_image_filename)
+ (void) LiberateTemporaryFile(image->filename);
+ for ( ; commands[i] != (char *) NULL; i++)
+ MagickFreeMemory(commands[i]);
+ MagickFreeMemory(commands);
+ return(status != False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n v o k e P o s t s c r i p t D e l e g a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InvokePostscriptDelegate() executes the postscript interpreter with the
+% specified command.
+%
+% The format of the InvokePostscriptDelegate method is:
+%
+% MagickPassFail InvokePostscriptDelegate(const unsigned int verbose,
+% const char *command, ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method InvokePostscriptDelegate returns MagickPass if the command
+% is successfully executed, otherwise MagickFail.
+%
+% o verbose: A value other than zero displays the command prior to
+% executing it.
+%
+% o command: The address of a character string containing the command to
+% execute. The command is formulated through direct FormatString()
+% substitutions rather than using TranslateText.
+%
+%
+*/
+MagickExport MagickPassFail
+InvokePostscriptDelegate(const unsigned int verbose,
+ const char *command,ExceptionInfo *exception)
+{
+ register long
+ i;
+
+ char
+ **argv;
+
+ int
+ argc;
+
+ int
+ status;
+
+#if defined(HasGS) || defined(MSWINDOWS)
+
+ gs_main_instance
+ *interpreter;
+
+ int
+ pexit_code;
+
+#if defined(MSWINDOWS)
+ const GhostscriptVectors
+ *gs_func;
+
+ gs_func=NTGhostscriptDLLVectors();
+#elif defined(HasGS)
+ GhostscriptVectors
+ gs_func_struct;
+
+ const GhostscriptVectors
+ *gs_func;
+
+ gs_func=(&gs_func_struct);
+ gs_func_struct.exit=gsapi_exit;
+ gs_func_struct.init_with_args=gsapi_init_with_args;
+ gs_func_struct.new_instance=gsapi_new_instance;
+ gs_func_struct.run_string=gsapi_run_string;
+ gs_func_struct.delete_instance=gsapi_delete_instance;
+#endif
+ if (gs_func != (GhostscriptVectors *) NULL)
+ {
+
+ /*
+ Allocate an interpreter.
+ */
+ interpreter = (gs_main_instance *) NULL;
+ status=(gs_func->new_instance)(&interpreter,(void *) NULL);
+ if (status < 0)
+ {
+ ThrowException(exception,DelegateError,
+ FailedToAllocateGhostscriptInterpreter,command);
+ return(MagickFail);
+ }
+ /*
+ Initialize interpreter with argument list.
+ */
+ argv=StringToArgv(command,&argc);
+ if (argv == (char **) NULL)
+ {
+ ThrowException(exception,DelegateError,FailedToAllocateArgumentList,
+ command);
+ return(MagickFail);
+ }
+
+ if (verbose)
+ {
+ char
+ buffer[MaxTextExtent];
+
+#if defined(MSWINDOWS)
+ (void) NTGhostscriptDLL(buffer,sizeof(buffer));
+#else
+ (void) strlcpy(buffer,"[ghostscript library]",sizeof(buffer));
+#endif
+ (void) fputs(buffer,stderr);
+ for (i=2 ; i < argc ; i++)
+ (void) fprintf(stderr," \"%s\"",argv[i]);
+ (void) fflush(stderr);
+ }
+ status=(gs_func->init_with_args)(interpreter,argc-1,argv+1);
+ if (status == 0)
+ {
+ status=(gs_func->run_string)
+ (interpreter,"systemdict /start get exec\n",0,&pexit_code);
+ if ((status == 0) || (status <= -100))
+ {
+ char
+ reason[MaxTextExtent];
+
+ FormatString(reason,"Ghostscript returns status %d, exit code %d",
+ status,pexit_code);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%s",reason);
+ ThrowException(exception,DelegateError,PostscriptDelegateFailed,command);
+ }
+ }
+ /*
+ Exit interpreter.
+ */
+ (gs_func->exit)(interpreter);
+ /*
+ Deallocate interpreter.
+ */
+ (gs_func->delete_instance)(interpreter);
+ for (i=0; i < argc; i++)
+ MagickFreeMemory(argv[i]);
+ MagickFreeMemory(argv);
+ if ((status == 0) || (status <= -100))
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returning with failure");
+ return(MagickFail);
+ }
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returning with success");
+ return(MagickPass);
+ }
+#endif /* defined(HasGS) || defined(MSWINDOWS) */
+
+ status=MagickFail;
+ {
+ /*
+ Build Ghostscript command argument list
+ */
+ argv = StringToArgv(command,&argc);
+ if (argv == (char **) NULL)
+ {
+ ThrowException(exception,DelegateError,
+ FailedToAllocateArgumentList,
+ command);
+ }
+ else
+ {
+ if (strlen(argv[1]) == 0)
+ {
+ /*
+ argv[1] can be empty under Windows due to empty
+ command substitution text.
+ */
+ ThrowException(exception,DelegateError,
+ FailedToFindGhostscript,
+ command);
+ status=MagickFail;
+ }
+ else
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Invoking Ghostscript utility command");
+ if (MagickSpawnVP(verbose,argv[1],argv+1) == 0)
+ status=MagickPass;
+ }
+ for (i=0; i < argc; i++)
+ MagickFreeMemory(argv[i]);
+ MagickFreeMemory(argv);
+ }
+ }
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returning with %s", status == MagickFail ?
+ "failure" : "success");
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t D e l e g a t e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ListDelegateInfo lists the image formats to a file.
+%
+% The format of the ListDelegateInfo method is:
+%
+% unsigned int ListDelegateInfo(FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o file: An pointer to a FILE.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport unsigned int ListDelegateInfo(FILE *file,ExceptionInfo *exception)
+{
+ char
+ **commands,
+ delegate[MaxTextExtent];
+
+ register long
+ i;
+
+ register const DelegateInfo
+ *p;
+
+ if (file == (const FILE *) NULL)
+ file=stdout;
+ (void) GetDelegateInfo("*","*",exception);
+ LockSemaphoreInfo(delegate_semaphore);
+ for (p=delegate_list; p != (const DelegateInfo *) NULL; p=p->next)
+ {
+ if ((p->previous == (DelegateInfo *) NULL) ||
+ (LocaleCompare(p->path,p->previous->path) != 0))
+ {
+ if (p->previous != (DelegateInfo *) NULL)
+ (void) fprintf(file,"\n");
+ if (p->path != (char *) NULL)
+ (void) fprintf(file,"Path: %.1024s\n\n",p->path);
+ (void) fprintf(file,"Delegate Command\n");
+ (void) fprintf(file,"-------------------------------------------------"
+ "------------------------------\n");
+ }
+ if (p->stealth)
+ continue;
+ *delegate='\0';
+ if (p->encode != (char *) NULL)
+ (void) strlcpy(delegate,p->encode,MaxTextExtent);
+ (void) strcat(delegate," ");
+ delegate[8]='\0';
+ commands=StringToList(p->commands);
+ if (commands == (char **) NULL)
+ continue;
+ {
+ size_t
+ command_length,
+ length=0;
+
+ int
+ command_start_column,
+ formatted_chars=0,
+ screen_width=79,
+ strip_length;
+
+ char
+ *s;
+
+ /* Format output so that command spans multiple lines if
+ necessary */
+ if (getenv("COLUMNS"))
+ screen_width=MagickAtoI(getenv("COLUMNS"))-1;
+ command_length=strlen(commands[0]);
+ command_start_column=fprintf(file,"%8s%c=%c%s ",p->decode ? p->decode : "",
+ p->mode <= 0 ? '<' : ' ',p->mode >= 0 ? '>' : ' ',delegate);
+ for (s=commands[0]; length < command_length; s+=formatted_chars)
+ {
+ if (s != commands[0])
+ (void) fprintf(file,"%*s",command_start_column,"");
+ strip_length=screen_width-command_start_column;
+ if (length+strip_length < command_length)
+ {
+ char
+ *e;
+
+ for(e=s+strip_length; (*e != ' ') && (e > s) ; e--);
+ strip_length=e-s;
+ }
+ formatted_chars=fprintf(file,"%.*s",strip_length,s);
+ length+=formatted_chars;
+ (void) fprintf(file,"\n");
+ if (formatted_chars <= 0)
+ break;
+ }
+ }
+ for (i=0; commands[i] != (char *) NULL; i++)
+ MagickFreeMemory(commands[i]);
+ MagickFreeMemory(commands);
+ }
+ (void) fflush(file);
+ UnlockSemaphoreInfo(delegate_semaphore);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d C o n f i g u r e F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadConfigureFile reads the delegate configuration file which maps
+% delegate invokation strings to a particular image format.
+%
+% The format of the ReadConfigureFile method is:
+%
+% unsigned int ReadConfigureFile(const char *basename,
+% const unsigned long depth,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method ReadConfigureFile returns True if a matching
+% entry is found, otherwise False.
+%
+% o basename: The color configuration filename.
+%
+% o depth: depth of <include /> statements.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#if defined(MSWINDOWS)
+static void CatDelegatePath(char *path,
+ const char *binpath,
+ const char *command)
+{
+ strcpy(path,binpath);
+ strcat(path,command);
+ if (IsAccessibleNoLogging(path))
+ return;
+
+ strcpy(path,command);
+ return;
+}
+#endif /* defined(MSWINDOWS) */
+static unsigned int ReadConfigureFile(const char *basename,
+ const unsigned long depth,ExceptionInfo *exception)
+{
+ char
+ keyword[MaxTextExtent],
+ path[MaxTextExtent],
+ *q,
+ *token,
+ *xml;
+
+ size_t
+ length,
+ token_max_length;
+
+ /*
+ Read the delegates configure file.
+ */
+ (void) strlcpy(path,basename,sizeof(path));
+ if (depth == 0)
+ xml=(char *) GetConfigureBlob(basename,path,&length,exception);
+ else
+ xml=(char *) FileToBlob(basename,&length,exception);
+ if (xml == (char *) NULL)
+ xml=AllocateString(DelegateMap);
+ token=AllocateString(xml);
+ token_max_length=strlen(token);
+ for (q=xml; *q != '\0'; )
+ {
+ /*
+ Interpret XML.
+ */
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == '\0')
+ break;
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ if (LocaleNCompare(keyword,"<!--",4) == 0)
+ {
+ /*
+ Comment element.
+ */
+ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
+ MagickGetToken(q,&q,token,token_max_length);
+ continue;
+ }
+ if (LocaleCompare(keyword,"<include") == 0)
+ {
+ /*
+ Include element.
+ */
+ while ((*token != '>') && (*q != '\0'))
+ {
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(keyword,"file") == 0)
+ {
+ if (depth > 200)
+ ThrowException(exception,ConfigureError,IncludeElementNestedTooDeeply,path);
+ else
+ {
+ char
+ filename[MaxTextExtent];
+
+ GetPathComponent(path,HeadPath,filename);
+ if (*filename != '\0')
+ (void) strlcat(filename,DirectorySeparator,MaxTextExtent);
+ (void) strlcat(filename,token,MaxTextExtent);
+ (void) ReadConfigureFile(filename,depth+1,exception);
+ }
+ if (delegate_list != (DelegateInfo *) NULL)
+ while (delegate_list->next != (DelegateInfo *) NULL)
+ delegate_list=delegate_list->next;
+ }
+ }
+ continue;
+ }
+ if (LocaleCompare(keyword,"<delegate") == 0)
+ {
+ DelegateInfo
+ *delegate_info;
+
+ /*
+ Allocate memory for the delegate list.
+ */
+ delegate_info=MagickAllocateMemory(DelegateInfo *,sizeof(DelegateInfo));
+ if (delegate_info == (DelegateInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateDelegateInfo);
+ (void) memset(delegate_info,0,sizeof(DelegateInfo));
+ delegate_info->path=AcquireString(path);
+ delegate_info->signature=MagickSignature;
+ if (delegate_list == (DelegateInfo *) NULL)
+ {
+ delegate_list=delegate_info;
+ continue;
+ }
+ delegate_list->next=delegate_info;
+ delegate_info->previous=delegate_list;
+ delegate_list=delegate_list->next;
+ continue;
+ }
+ if (delegate_list == (DelegateInfo *) NULL)
+ continue;
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ switch (*keyword)
+ {
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare((char *) keyword,"command") == 0)
+ {
+ delegate_list->commands=AllocateString(token);
+#if defined(MSWINDOWS)
+ if (strchr(delegate_list->commands,'@') != (char *) NULL)
+ {
+ char
+ BinPath[MaxTextExtent],
+ path[MaxTextExtent];
+
+ BinPath[0]=0;
+ /* Substitute @PSDelegate@ with path to Ghostscript */
+ NTGhostscriptEXE(path,MaxTextExtent-1);
+ SubstituteString((char **) &delegate_list->commands,
+ "@PSDelegate@",path);
+
+# if defined(UseInstalledMagick)
+# if defined(MagickBinPath)
+ strlcpy(BinPath,MagickBinPath,sizeof(BinPath));
+# else
+ {
+ char
+ *key,
+ *key_value;
+
+ /* Obtain installation path from registry */
+ key="BinPath";
+ key_value=NTRegistryKeyLookup(key);
+ if (!key_value)
+ {
+ ThrowException(exception,ConfigureError,
+ RegistryKeyLookupFailed,key);
+ }
+ else
+ {
+ strlcpy(BinPath,key_value,sizeof(BinPath));
+ MagickFreeMemory(key_value);
+ }
+ }
+# endif /* defined(MagickBinPath) */
+# else
+ /* Base path off of client path */
+ strlcpy(BinPath,SetClientPath(NULL),sizeof(BinPath));
+# endif /* defined(UseInstalledMagick) */
+ if ((BinPath[0] != 0) &&
+ (BinPath[strlen(BinPath)-1] != *DirectorySeparator))
+ strcat(BinPath,DirectorySeparator);
+
+ /* Substitute @GMDelegate@ with path to gm.exe */
+ CatDelegatePath(path,BinPath,"gm.exe");
+ SubstituteString((char **) &delegate_list->commands,
+ "@GMDelegate@",path);
+
+ /* Substitute @GMDisplayDelegate@ with path to
+ gmdisplay.exe */
+ CatDelegatePath(path,BinPath,"gmdisplay.exe");
+ SubstituteString((char **) &delegate_list->commands,
+ "@GMDisplayDelegate@",path);
+
+ /* Substitute @MPEGDecodeDelegate@ with path to
+ mpeg2dec.exe */
+ CatDelegatePath(path,BinPath,"mpeg2dec.exe");
+ SubstituteString((char **) &delegate_list->commands,
+ "@MPEGDecodeDelegate@",path);
+
+ /* Substitute @MPEGEncodeDelegate@ with path to
+ mpeg2enc.exe */
+ CatDelegatePath(path,BinPath,"mpeg2enc.exe");
+ SubstituteString((char **) &delegate_list->commands,
+ "@MPEGEncodeDelegate@",path);
+
+ /* Substitute @HPGLDecodeDelegate@ with path to
+ hp2xx.exe */
+ CatDelegatePath(path,BinPath,"hp2xx.exe");
+ SubstituteString((char **) &delegate_list->commands,
+ "@HPGLDecodeDelegate@",path);
+ }
+#endif /* defined(MSWINDOWS) */
+ } /* LocaleCompare */
+ break;
+ }
+ case 'D':
+ case 'd':
+ {
+ if (LocaleCompare((char *) keyword,"decode") == 0)
+ {
+ delegate_list->decode=AcquireString(token);
+ delegate_list->mode=1;
+ break;
+ }
+ break;
+ }
+ case 'E':
+ case 'e':
+ {
+ if (LocaleCompare((char *) keyword,"encode") == 0)
+ {
+ delegate_list->encode=AcquireString(token);
+ delegate_list->mode=(-1);
+ break;
+ }
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare((char *) keyword,"mode") == 0)
+ {
+ delegate_list->mode=1;
+ if (LocaleCompare(token,"bi") == 0)
+ delegate_list->mode=0;
+ else
+ if (LocaleCompare(token,"encode") == 0)
+ delegate_list->mode=(-1);
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare((char *) keyword,"stealth") == 0)
+ {
+ delegate_list->stealth=LocaleCompare(token,"True") == 0;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ MagickFreeMemory(token);
+ MagickFreeMemory(xml);
+ if (delegate_list == (DelegateInfo *) NULL)
+ return(False);
+ while (delegate_list->previous != (DelegateInfo *) NULL)
+ delegate_list=delegate_list->previous;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t D e l e g a t e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SetDelegateInfo adds or replaces a delegate in the delegate list and
+% returns the address of the first delegate. If the delegate is NULL, just
+% the address of the first delegate is returned.
+%
+% The format of the SetDelegateInfo method is:
+%
+% DelegateInfo *SetDelegateInfo(DelegateInfo *delegate_info)
+%
+% A description of each parameter follows:
+%
+% o delegate_info: Method SetDelegateInfo returns the address of the
+% first delegate in the delegates list.
+%
+% o delegate_info: A structure of type DelegateInfo. This information
+% is added to the end of the delegates linked-list.
+%
+%
+*/
+MagickExport DelegateInfo *SetDelegateInfo(DelegateInfo *delegate_info)
+{
+ register DelegateInfo
+ *p;
+
+ DelegateInfo
+ *delegate;
+
+ /*
+ Initialize new delegate.
+ */
+ assert(delegate_info != (DelegateInfo *) NULL);
+ assert(delegate_info->signature == MagickSignature);
+ delegate=MagickAllocateMemory(DelegateInfo *,sizeof(DelegateInfo));
+ if (delegate == (DelegateInfo *) NULL)
+ return((DelegateInfo *) delegate_list);
+ delegate->decode=AcquireString(delegate_info->decode);
+ delegate->encode=AcquireString(delegate_info->encode);
+ delegate->mode=delegate_info->mode;
+ delegate->commands=(char *) NULL;
+ if (delegate_info->commands != (char *) NULL)
+ delegate->commands=AllocateString(delegate_info->commands);
+ delegate->previous=(DelegateInfo *) NULL;
+ delegate->next=(DelegateInfo *) NULL;
+ if (delegate_list == (DelegateInfo *) NULL)
+ {
+ delegate_list=delegate;
+ return((DelegateInfo *) delegate_list);
+ }
+ for (p=delegate_list; p != (DelegateInfo *) NULL; p=p->next)
+ {
+ if ((LocaleCompare(p->decode,delegate_info->decode) == 0) &&
+ (LocaleCompare(p->encode,delegate_info->encode) == 0) &&
+ (p->mode == delegate_info->mode))
+ {
+ /*
+ Delegate overrides an existing one with the same tags.
+ */
+ MagickFreeMemory(p->commands);
+ p->commands=delegate->commands;
+ MagickFreeMemory(delegate);
+ return((DelegateInfo *) delegate_list);
+ }
+ if (p->next == (DelegateInfo *) NULL)
+ break;
+ }
+ /*
+ Place new delegate at the end of the delegate list.
+ */
+ delegate->previous=p;
+ p->next=delegate;
+ return((DelegateInfo *) delegate_list);
+}
diff --git a/magick/delegate.h b/magick/delegate.h
new file mode 100644
index 0000000..de5f9c9
--- /dev/null
+++ b/magick/delegate.h
@@ -0,0 +1,136 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Methods to Read/Write/Invoke Delegates.
+*/
+#ifndef _MAGICK_DELEGATE_H
+#define _MAGICK_DELEGATE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Delegate structure definitions.
+*/
+typedef struct _DelegateInfo
+{
+ char
+ *path, /* Path to delegate configuation file */
+ *decode, /* Decode from format */
+ *encode; /* Transcode to format */
+
+ char
+ *commands; /* Commands to execute */
+
+ int mode; /* <0 = encoder, >0 = decoder */
+
+ MagickBool
+ stealth; /* Don't list this delegate */
+
+ unsigned long
+ signature;
+
+ struct _DelegateInfo
+ *previous,
+ *next;
+} DelegateInfo;
+
+/*
+ Magick delegate methods.
+*/
+extern MagickExport char
+ *GetDelegateCommand(const ImageInfo *image_info,Image *image,
+ const char *decode,const char *encode,
+ ExceptionInfo *exception);
+
+extern MagickExport const DelegateInfo
+ *GetDelegateInfo(const char *decode,const char *encode,
+ ExceptionInfo *exception),
+ *GetPostscriptDelegateInfo(const ImageInfo *image_info,
+ unsigned int *antialias, ExceptionInfo *exception);
+
+extern MagickExport DelegateInfo
+ *SetDelegateInfo(DelegateInfo *);
+
+extern MagickExport MagickPassFail
+ InvokePostscriptDelegate(const unsigned int verbose,const char *command,
+ ExceptionInfo *exception),
+ InvokeDelegate(ImageInfo *image_info,Image *image,const char *decode,
+ const char *encode,ExceptionInfo *exception),
+ ListDelegateInfo(FILE *file,ExceptionInfo *exception);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+#if defined(HasGS)
+#include "ghostscript/iapi.h"
+#endif
+
+#ifndef gs_main_instance_DEFINED
+# define gs_main_instance_DEFINED
+typedef struct gs_main_instance_s gs_main_instance;
+#endif
+
+#if !defined(MagickDLLCall)
+# if defined(MSWINDOWS)
+# define MagickDLLCall __stdcall
+# else
+# define MagickDLLCall
+# endif
+#endif
+
+/*
+ Define a vector of Ghostscript library callback functions so that
+ DLL/shared and static Ghostscript libbraries may be handled identically.
+ These definitions must be compatible with those in the Ghostscript API
+ headers (which we don't require).
+
+ http://pages.cs.wisc.edu/~ghost/doc/cvs/API.htm
+ */
+typedef struct _GhostscriptVectors
+{
+ /* Exit the interpreter (gsapi_exit)*/
+ int (MagickDLLCall *exit)(gs_main_instance *instance);
+
+ /* Destroy instance of Ghostscript. Call exit first! (gsapi_delete_instance) */
+ void (MagickDLLCall *delete_instance)(gs_main_instance *instance);
+
+ /* Initialize the Ghostscript interpreter (gsapi_init_with_args) */
+ int (MagickDLLCall *init_with_args)(gs_main_instance *instance,int argc,
+ char **argv);
+
+ /* Create a new instance of the Ghostscript interpreter (gsapi_new_instance) */
+ int (MagickDLLCall *new_instance)(gs_main_instance **pinstance,
+ void *caller_handle);
+
+ /* Execute string command in Ghostscript interpreter (gsapi_run_string) */
+ int (MagickDLLCall *run_string)(gs_main_instance *instance,const char *str,
+ int user_errors,int *pexit_code);
+} GhostscriptVectors;
+
+extern MagickExport void
+ DestroyDelegateInfo(void);
+
+extern MagickPassFail
+ InitializeDelegateInfo(void);
+
+#endif /* MAGICK_IMPLEMENTATION */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_DELEGATE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/deprecate.c b/magick/deprecate.c
new file mode 100644
index 0000000..d4f48ff
--- /dev/null
+++ b/magick/deprecate.c
@@ -0,0 +1,484 @@
+/*
+% Copyright (C) 2003 - 2010 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% DDDD EEEEE PPPP RRRR EEEEE CCCC AAA TTTTT EEEEE %
+% D D E P P R R E C A A T E %
+% D D EEE PPPPP RRRR EEE C AAAAA T EEE %
+% D D E P R R E C A A T E %
+% DDDD EEEEE P R R EEEEE CCCC A A T EEEEE %
+% %
+% %
+% GraphicsMagick Deprecated Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% October 2002 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/constitute.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+#include "magick/deprecate.h"
+
+#undef LoadImageText
+#undef SaveImageText
+#undef LoadImagesText
+#undef SaveImagesText
+
+extern MagickExport const char
+ *LoadImageText,
+ *LoadImagesText,
+ *SaveImageText,
+ *SaveImagesText;
+
+const char
+ *LoadImageText = "[%s] Loading image: %lux%lu... ",
+ *LoadImagesText = "[%s] Loading images... ",
+ *SaveImageText = "[%s] Saving image: %lux%lu... ",
+ *SaveImagesText = "[%s] Saving images... ";
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e C a c h e V i e w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method AcquireCacheView gets pixels from the in-memory or disk pixel cache
+% as defined by the geometry parameters for read-only access. A pointer to
+% the pixels is returned if the pixels are transferred, otherwise NULL is
+% returned.
+%
+% The format of the AcquireCacheView method is:
+%
+% const PixelPacket *AcquireCacheView(const ViewInfo *view,const long x,
+% const long y,const unsigned long columns,const unsigned long rows,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o pixels: Method AcquireCacheView returns a null pointer if an error
+% occurs, otherwise a pointer to the view pixels.
+%
+% o view: The address of a structure of type ViewInfo.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const PixelPacket *
+AcquireCacheView(const ViewInfo *view,
+ const long x,const long y,const unsigned long columns,
+ const unsigned long rows,ExceptionInfo *exception)
+{
+ return AcquireCacheViewPixels(view,x,y,columns,rows,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e M e m o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireMemory() returns a pointer to a block of memory of at least size
+% bytes suitably aligned for any use. NULL is returned if insufficient
+% memory is available or the requested size is zero.
+%
+% The format of the AcquireMemory method is:
+%
+% void *AcquireMemory(const size_t size)
+%
+% A description of each parameter follows:
+%
+% o size: The size of the memory in bytes to allocate.
+%
+%
+*/
+MagickExport void *AcquireMemory(const size_t size)
+{
+ if (IsEventLogging())
+ (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
+ "Method has been deprecated");
+
+ return MagickAllocateMemory(void *,size);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e M e m o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneMemory() copies size bytes from memory area source to the
+% destination. Copying between objects that overlap will take place
+% correctly. It returns destination.
+%
+% The format of the CloneMemory method is:
+%
+% void *CloneMemory(void *destination,const void *source,const size_t size)
+%
+% A description of each parameter follows:
+%
+% o size: The size of the memory in bytes to allocate.
+%
+%
+*/
+MagickExport void *CloneMemory(void *destination,const void *source,
+ const size_t size)
+{
+ if (IsEventLogging())
+ (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
+ "Method has been deprecated");
+
+ return MagickCloneMemory(destination,source,size);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C a c h e V i e w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetCacheView() gets writeable pixels from the in-memory or disk pixel
+% cache as defined by the geometry parameters. A pointer to the pixels
+% is returned if the pixels are transferred, otherwise a NULL is returned.
+%
+% The format of the GetCacheView method is:
+%
+% PixelPacket *GetCacheView(ViewInfo *view,const long x,const long y,
+% const unsigned long columns,const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o pixels: Method GetCacheView returns a null pointer if an error
+% occurs, otherwise a pointer to the view pixels.
+%
+% o view: The address of a structure of type ViewInfo.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+%
+*/
+MagickExport PixelPacket *
+GetCacheView(ViewInfo *view,const long x,const long y,
+ const unsigned long columns,const unsigned long rows)
+{
+ return GetCacheViewPixels(view,x,y,columns,rows,
+ &GetCacheViewImage(view)->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i b e r a t e M e m o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% LiberateMemory() frees memory that has already been allocated, and
+% NULLs the pointer to it.
+%
+% The format of the LiberateMemory method is:
+%
+% void LiberateMemory(void **memory)
+%
+% A description of each parameter follows:
+%
+% o memory: A pointer to a block of memory to free for reuse.
+%
+%
+*/
+MagickExport void LiberateMemory(void **memory)
+{
+ assert(memory != (void **) NULL);
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
+ "Method has been deprecated");
+
+ MagickFreeMemory(*memory);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P o p I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PopImagePixels() transfers one or more pixel components from the image pixel
+% cache to a user supplied buffer. True is returned if the pixels are
+% successfully transferred, otherwise False.
+%
+% The format of the PopImagePixels method is:
+%
+% unsigned int PopImagePixels(const Image *,const QuantumType quantum,
+% unsigned char *destination)
+%
+% A description of each parameter follows:
+%
+% o status: Method PopImagePixels returns True if the pixels are
+% successfully transferred, otherwise False.
+%
+% o image: The image.
+%
+% o quantum: Declare which pixel components to transfer (RGB, RGBA, etc).
+%
+% o destination: The components are transferred to this buffer.
+%
+%
+*/
+MagickExport unsigned int PopImagePixels(const Image *image,
+ const QuantumType quantum_type,unsigned char *destination)
+{
+ unsigned int
+ quantum_size;
+
+ quantum_size=image->depth;
+
+ if (quantum_size <= 8)
+ quantum_size=8;
+ else if (quantum_size <= 16)
+ quantum_size=16;
+ else
+ quantum_size=32;
+
+ if ( (quantum_type == IndexQuantum) || (quantum_type == IndexAlphaQuantum) )
+ {
+ if (image->colors <= 256)
+ quantum_size=8;
+ else if (image->colors <= 65536L)
+ quantum_size=16;
+ else
+ quantum_size=32;
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
+ "Method has been deprecated");
+
+ return ExportImagePixelArea(image,quantum_type,quantum_size,destination,0,0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P u s h I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PushImagePixels() transfers one or more pixel components from a user
+% supplied buffer into the image pixel cache of an image. It returns True if
+% the pixels are successfully transferred, otherwise False.
+%
+% The format of the PushImagePixels method is:
+%
+% unsigned int PushImagePixels(Image *image,
+% const QuantumType quantum_type,
+% const unsigned char *source)
+%
+% A description of each parameter follows:
+%
+% o status: Method PushImagePixels returns True if the pixels are
+% successfully transferred, otherwise False.
+%
+% o image: The image.
+%
+% o quantum_type: Declare which pixel components to transfer (red, green,
+% blue, opacity, RGB, or RGBA).
+%
+% o source: The pixel components are transferred from this buffer.
+%
+*/
+MagickExport unsigned int PushImagePixels(Image *image,
+ const QuantumType quantum_type,const unsigned char *source)
+{
+ unsigned int
+ quantum_size;
+
+ quantum_size=image->depth;
+
+ if (quantum_size <= 8)
+ quantum_size=8;
+ else if (quantum_size <= 16)
+ quantum_size=16;
+ else
+ quantum_size=32;
+
+ if ( (quantum_type == IndexQuantum) || (quantum_type == IndexAlphaQuantum) )
+ {
+ if (image->colors <= 256)
+ quantum_size=8;
+ else if (image->colors <= 65536L)
+ quantum_size=16;
+ else
+ quantum_size=32;
+ }
+
+ if (image->logging)
+ (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
+ "Method has been deprecated");
+
+ return ImportImagePixelArea(image,quantum_type,quantum_size,source,0,0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e a c q u i r e M e m o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReacquireMemory() changes the size of the memory and returns a
+% pointer to the (possibly moved) block. The contents will be unchanged
+% up to the lesser of the new and old sizes.
+%
+% The format of the ReacquireMemory method is:
+%
+% void ReacquireMemory(void **memory,const size_t size)
+%
+% A description of each parameter follows:
+%
+% o memory: A pointer to a memory allocation. On return the pointer
+% may change but the contents of the original allocation will not.
+%
+% o size: The new size of the allocated memory.
+%
+%
+*/
+MagickExport void ReacquireMemory(void **memory,const size_t size)
+{
+ assert(memory != (void **) NULL);
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(DeprecateEvent,GetMagickModule(),
+ "Method has been deprecated");
+
+ MagickReallocMemory(void*,*memory,size);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t C a c h e V i e w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetCacheView() gets pixels from the in-memory or disk pixel cache as
+% defined by the geometry parameters. A pointer to the pixels is returned
+% if the pixels are transferred, otherwise a NULL is returned.
+%
+% The format of the SetCacheView method is:
+%
+% PixelPacket *SetCacheView(ViewInfo *view,const long x,const long y,
+% const unsigned long columns,const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o view: The address of a structure of type ViewInfo.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+%
+*/
+MagickExport PixelPacket *
+SetCacheView(ViewInfo *view,const long x,const long y,
+ const unsigned long columns,const unsigned long rows)
+{
+ return SetCacheViewPixels(view,x,y,columns,rows,
+ &GetCacheViewImage(view)->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S y n c C a c h e V i e w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SyncCacheView() saves the view pixels to the in-memory or disk cache.
+% The method returns MagickPass if the pixel region is synced, otherwise
+% MagickFail.
+%
+% The format of the SyncCacheView method is:
+%
+% MagickPassFail SyncCacheView(ViewInfo *view)
+%
+% A description of each parameter follows:
+%
+% o view: The address of a structure of type ViewInfo.
+%
+%
+*/
+MagickExport MagickPassFail
+SyncCacheView(ViewInfo *view)
+{
+ return SyncCacheViewPixels(view,&GetCacheViewImage(view)->exception);
+}
diff --git a/magick/deprecate.h b/magick/deprecate.h
new file mode 100644
index 0000000..136e950
--- /dev/null
+++ b/magick/deprecate.h
@@ -0,0 +1,95 @@
+/*
+ Copyright (C) 2003, 2008 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Log methods.
+*/
+#ifndef _MAGICK_DEPRECATE_H
+#define _MAGICK_DEPRECATE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ /*
+ Legacy names for (possibly) large integral types
+ */
+
+#if !defined(ExtendedSignedIntegralType)
+# define ExtendedSignedIntegralType magick_int64_t
+#endif
+#if !defined(ExtendedUnsignedIntegralType)
+# define ExtendedUnsignedIntegralType magick_uint64_t
+#endif
+
+ /*
+ Compatibility definitions to handle the renaming of
+ ExtendedSignedIntegralType and ExtendedUnsignedIntegralType to
+ MagickSignedType and MagickUnsignedType which occured in ImageMagick
+ 5.5.8. ImageMagick 5.5.8 also introduced MagickRationalType.
+ */
+#if !defined(MagickSignedType)
+# define MagickSignedType magick_int64_t
+#endif
+#if !defined(MagickUnsignedType)
+# define MagickUnsignedType magick_uint64_t
+#endif
+#if !defined(MagickRationalType)
+# if defined(HAVE_LONG_DOUBLE)
+# define MagickRationalType long double
+# else
+# define MagickRationalType double
+# endif
+#endif
+
+ extern MagickExport unsigned int
+ PopImagePixels(const Image *,const QuantumType,unsigned char *) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport unsigned int
+ PushImagePixels(Image *,const QuantumType,const unsigned char *) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport void
+ *AcquireMemory(const size_t) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport void
+ *CloneMemory(void *,const void *,const size_t) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport void
+ LiberateMemory(void **) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport void
+ ReacquireMemory(void **,const size_t) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport const PixelPacket
+ *AcquireCacheView(const ViewInfo *view,
+ const long x,const long y,const unsigned long columns,
+ const unsigned long rows,ExceptionInfo *exception) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport PixelPacket
+ *GetCacheView(ViewInfo *view,const long x,const long y,
+ const unsigned long columns,const unsigned long rows) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport PixelPacket
+ *SetCacheView(ViewInfo *view,const long x,const long y,
+ const unsigned long columns,const unsigned long rows) MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport MagickPassFail
+ SyncCacheView(ViewInfo *view) MAGICK_FUNC_DEPRECATED;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/describe.c b/magick/describe.c
new file mode 100644
index 0000000..81c7843
--- /dev/null
+++ b/magick/describe.c
@@ -0,0 +1,907 @@
+/*
+% Copyright (C) 2003 - 2012 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% GraphicsMagick Describe Methods.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/channel.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/constitute.h"
+#include "magick/enum_strings.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/profile.h"
+#include "magick/signature.h"
+#include "magick/statistics.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s c r i b e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DescribeImage() describes an image by printing its attributes to the file.
+% Attributes include the image width, height, size, and others.
+%
+% The format of the DescribeImage method is:
+%
+% void DescribeImage(Image *image,FILE *file,const MagickBool verbose)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o file: The file, typically stdout.
+%
+% o verbose: A value other than zero prints more detailed information
+% about the image. Values greater than one enable counting the number of
+% colors in the image.
+%
+%
+*/
+MagickExport MagickPassFail DescribeImage(Image *image,FILE *file,
+ const MagickBool verbose)
+{
+ char
+ color[MaxTextExtent],
+ format[MaxTextExtent];
+
+ const unsigned char
+ *profile;
+
+ size_t
+ profile_length;
+
+ const ImageAttribute
+ *attribute;
+
+ const MagickInfo
+ *magick_info;
+
+ double
+ elapsed_time,
+ user_time;
+
+ unsigned long
+ columns,
+ rows;
+
+ magick_int64_t
+ pixels_per_second;
+
+ Image
+ *p;
+
+ unsigned long
+ y;
+
+ register size_t
+ i;
+
+ register unsigned long
+ x;
+
+ unsigned long
+ count;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(file != (FILE *) NULL);
+ elapsed_time=GetElapsedTime(&image->timer);
+ user_time=GetUserTime(&image->timer);
+ GetTimerInfo(&image->timer);
+ if (!verbose)
+ {
+ /*
+ Display summary info about the image.
+ */
+ if (*image->magick_filename != '\0')
+ if (LocaleCompare(image->magick_filename,image->filename) != 0)
+ (void) fprintf(file,"%.1024s=>",image->magick_filename);
+ if ((image->previous == (Image *) NULL) &&
+ (image->next == (Image *) NULL) && (image->scene == 0))
+ (void) fprintf(file,"%.1024s ",image->filename);
+ else
+ (void) fprintf(file,"%.1024s[%lu] ",image->filename,image->scene);
+ (void) fprintf(file,"%.1024s ",image->magick);
+ columns=image->columns;
+ rows=image->rows;
+ if ((image->magick_columns != 0) || (image->magick_rows != 0))
+ if ((image->magick_columns != image->columns) ||
+ (image->magick_rows != image->rows))
+ {
+ columns=image->magick_columns;
+ rows=image->magick_rows;
+ (void) fprintf(file,"%lux%lu=>",image->magick_columns,
+ image->magick_rows);
+ }
+ (void) fprintf(file,"%lux%lu%+ld%+ld ",image->columns,image->rows,
+ image->page.x,image->page.y);
+ if (image->storage_class == DirectClass)
+ {
+ (void) fprintf(file,"DirectClass ");
+ if (image->total_colors != 0)
+ {
+ FormatSize(image->total_colors,format);
+ (void) fprintf(file,"%.1024s ",format);
+ }
+ }
+ else
+ if (image->total_colors <= image->colors)
+ (void) fprintf(file,"PseudoClass %uc ",image->colors);
+ else
+ {
+ (void) fprintf(file,"PseudoClass %lu=>%uc ",image->total_colors,
+ image->colors);
+ (void) fprintf(file,"%ld/%.6f/%.6fe ",
+ (long) image->error.mean_error_per_pixel,
+ image->error.normalized_mean_error,
+ image->error.normalized_maximum_error);
+ }
+ (void) fprintf(file,"%u-bit ",image->depth);
+ if (GetBlobSize(image) != 0)
+ {
+ FormatSize(GetBlobSize(image),format);
+ (void) fprintf(file,"%.1024s ",format);
+ }
+ (void) fprintf(file,"%0.3fu %ldm:%.6fs",
+ user_time,
+ (long) (elapsed_time/60.0),
+ fmod(elapsed_time,60.0));
+ /*
+ Only display pixel read rate if the time accumulated is at
+ least six times the timer's resolution (typically 0.01 on
+ Unix).
+ */
+ if (!(image->ping) && (elapsed_time >= GetTimerResolution()*6))
+ {
+ pixels_per_second=(magick_int64_t) ((double) rows*columns/
+ elapsed_time);
+ FormatSize(pixels_per_second,format);
+ (void) fprintf(file," (%s pixels/s)",format);
+ }
+ (void) fprintf(file,"\n");
+
+ return (ferror(file) ? MagickFail : MagickPass);
+ }
+ /*
+ Display verbose info about the image.
+ */
+ (void) SignatureImage(image);
+ if (verbose > 1)
+ image->total_colors=GetNumberColors(image,(FILE *) NULL,&image->exception);
+ (void) fprintf(file,"Image: %.1024s\n",image->filename);
+ magick_info=GetMagickInfo(image->magick,&image->exception);
+ if ((magick_info == (const MagickInfo *) NULL) ||
+ (*magick_info->description == '\0'))
+ (void) fprintf(file," Format: %.1024s\n",image->magick);
+ else
+ (void) fprintf(file," Format: %.1024s (%.1024s)\n",image->magick,
+ magick_info->description);
+ (void) fprintf(file," Geometry: %lux%lu\n",image->columns,image->rows);
+ if (image->storage_class == DirectClass)
+ (void) fprintf(file," Class: DirectClass\n");
+ else
+ (void) fprintf(file," Class: PseudoClass\n");
+ if ((image->magick_columns != 0) || (image->magick_rows != 0))
+ if ((image->magick_columns != image->columns) ||
+ (image->magick_rows != image->rows))
+ (void) fprintf(file," Base geometry: %lux%lu\n",image->magick_columns,
+ image->magick_rows);
+ (void) fprintf(file," Type: ");
+ switch (GetImageType(image,&image->exception))
+ {
+ case BilevelType: (void) fprintf(file,"bilevel"); break;
+ case GrayscaleType: (void) fprintf(file,"grayscale"); break;
+ case GrayscaleMatteType:
+ (void) fprintf(file,"grayscale with transparency"); break;
+ case PaletteType: (void) fprintf(file,"palette"); break;
+ case PaletteMatteType:
+ (void) fprintf(file,"palette with transparency"); break;
+ case TrueColorType: (void) fprintf(file,"true color"); break;
+ case TrueColorMatteType:
+ (void) fprintf(file,"true color with transparency"); break;
+ case ColorSeparationType: (void) fprintf(file,"color separated"); break;
+ case ColorSeparationMatteType:
+ (void) fprintf(file,"color separated with transparency"); break;
+ default: (void) fprintf(file,"undefined"); break;
+ }
+ (void) fprintf(file,"\n");
+ (void) fprintf(file," Depth: %lu bits-per-pixel component\n",
+ GetImageDepth(image,&image->exception));
+ (void) fprintf(file," Channel Depths:\n");
+ if (image->colorspace == CMYKColorspace)
+ {
+ (void) fprintf(file," Cyan: %u bits\n",
+ GetImageChannelDepth(image,CyanChannel,
+ &image->exception));
+ (void) fprintf(file," Magenta: %u bits\n",
+ GetImageChannelDepth(image,MagentaChannel,
+ &image->exception));
+ (void) fprintf(file," Yellow: %u bits\n",
+ GetImageChannelDepth(image,YellowChannel,
+ &image->exception));
+ (void) fprintf(file," Black: %u bits\n",
+ GetImageChannelDepth(image,BlackChannel,
+ &image->exception));
+ }
+ else if ((IsGrayColorspace(image->colorspace)) ||
+ (image->is_grayscale == True))
+ {
+ (void) fprintf(file," Gray: %u bits\n",
+ GetImageChannelDepth(image,RedChannel,
+ &image->exception));
+ }
+ else
+ {
+ (void) fprintf(file," Red: %u bits\n",
+ GetImageChannelDepth(image,RedChannel,
+ &image->exception));
+ (void) fprintf(file," Green: %u bits\n",
+ GetImageChannelDepth(image,GreenChannel,
+ &image->exception));
+ (void) fprintf(file," Blue: %u bits\n",
+ GetImageChannelDepth(image,BlueChannel,
+ &image->exception));
+ }
+ if (image->matte)
+ (void) fprintf(file," Opacity: %u bits\n",
+ GetImageChannelDepth(image,OpacityChannel,
+ &image->exception));
+ (void) fprintf(file," Channel Statistics:\n");
+ {
+ ImageStatistics
+ statistics;
+
+ (void) GetImageStatistics(image,&statistics,&image->exception);
+
+ if (image->colorspace == CMYKColorspace)
+ {
+ (void) fprintf(file," Cyan:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.minimum,
+ statistics.red.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.maximum,
+ statistics.red.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.mean,
+ statistics.red.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.standard_deviation,
+ statistics.red.standard_deviation);
+ (void) fprintf(file," Magenta:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.green.minimum,
+ statistics.green.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.green.maximum,
+ statistics.green.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.green.mean,
+ statistics.green.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.green.standard_deviation,
+ statistics.green.standard_deviation);
+ (void) fprintf(file," Yellow:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.blue.minimum,
+ statistics.blue.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.blue.maximum,
+ statistics.blue.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.blue.mean,
+ statistics.blue.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.blue.standard_deviation,
+ statistics.blue.standard_deviation);
+ (void) fprintf(file," Black:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.minimum,
+ statistics.opacity.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.maximum,
+ statistics.opacity.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.mean,
+ statistics.opacity.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.standard_deviation,
+ statistics.opacity.standard_deviation);
+ /*
+ if (image->matte)
+ (void) fprintf(file," Opacity:\n");
+ */
+ }
+ else if ((IsGrayColorspace(image->colorspace)) ||
+ (image->is_grayscale == MagickTrue))
+ {
+ (void) fprintf(file," Gray:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.minimum,
+ statistics.red.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.maximum,
+ statistics.red.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.mean,
+ statistics.red.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.standard_deviation,
+ statistics.red.standard_deviation);
+ if (image->matte)
+ {
+ (void) fprintf(file," Opacity:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.minimum,
+ statistics.opacity.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.maximum,
+ statistics.opacity.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.mean,
+ statistics.opacity.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.standard_deviation,
+ statistics.opacity.standard_deviation);
+ }
+ }
+ else
+ {
+ (void) fprintf(file," Red:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.minimum,
+ statistics.red.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.maximum,
+ statistics.red.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.mean,
+ statistics.red.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.red.standard_deviation,
+ statistics.red.standard_deviation);
+ (void) fprintf(file," Green:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.green.minimum,
+ statistics.green.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.green.maximum,
+ statistics.green.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.green.mean,
+ statistics.green.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.green.standard_deviation,
+ statistics.green.standard_deviation);
+ (void) fprintf(file," Blue:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.blue.minimum,
+ statistics.blue.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.blue.maximum,
+ statistics.blue.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.blue.mean,
+ statistics.blue.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.blue.standard_deviation,
+ statistics.blue.standard_deviation);
+ if (image->matte)
+ {
+ (void) fprintf(file," Opacity:\n");
+ (void) fprintf(file," Minimum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.minimum,
+ statistics.opacity.minimum);
+ (void) fprintf(file," Maximum: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.maximum,
+ statistics.opacity.maximum);
+ (void) fprintf(file," Mean: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.mean,
+ statistics.opacity.mean);
+ (void) fprintf(file," Standard Deviation: %13.02lf (%1.4f)\n",
+ MaxRGB*statistics.opacity.standard_deviation,
+ statistics.opacity.standard_deviation);
+ }
+ }
+ }
+ x=0;
+ p=(Image *) NULL;
+ if ((image->matte && (strcmp(image->magick,"GIF") != 0)) || image->taint)
+ {
+ char
+ tuple[MaxTextExtent];
+
+ register const PixelPacket
+ *p;
+
+ p=(PixelPacket *) NULL;
+ for (y=0; y < image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < image->columns; x++)
+ {
+ if (p->opacity == TransparentOpacity)
+ break;
+ p++;
+ }
+ if (x < image->columns)
+ break;
+ }
+ if ((x < image->columns) || (y < image->rows))
+ {
+ GetColorTuple(p,image->depth,image->matte,False,tuple);
+ (void) fprintf(file," Opacity: %.1024s\t",tuple);
+ GetColorTuple(p,image->depth,image->matte,True,tuple);
+ (void) fprintf(file," %.1024s\n",tuple);
+ }
+ }
+ if (image->storage_class == DirectClass)
+ {
+ if (image->total_colors != 0)
+ (void) fprintf(file," Colors: %lu\n",image->total_colors);
+ }
+ else
+ {
+ if (image->total_colors <= image->colors)
+ (void) fprintf(file," Colors: %u\n",image->colors);
+ else
+ (void) fprintf(file," Colors: %lu=>%u\n",image->total_colors,
+ image->colors);
+ }
+ if (image->storage_class == DirectClass)
+ {
+ if (image->total_colors < 1024)
+ if (verbose > 1)
+ (void) GetNumberColors(image,file,&image->exception);
+ }
+ else
+ {
+ char
+ name[MaxTextExtent];
+
+ register PixelPacket
+ *p;
+
+ /*
+ Display image colormap.
+ */
+ p=image->colormap;
+ for (i=0; i < image->colors; i++)
+ {
+ char
+ tuple[MaxTextExtent];
+
+ GetColorTuple(p,image->depth,image->matte,False,tuple);
+ (void) fprintf(file," %" MAGICK_SIZE_T_F "u: %.1024s",
+ (MAGICK_SIZE_T) i,tuple);
+ (void) fprintf(file,"\t");
+ (void) QueryColorname(image,p,SVGCompliance,name,&image->exception);
+ (void) fprintf(file," %.1024s",name);
+ (void) fprintf(file,"\n");
+ p++;
+ }
+ }
+ if (image->error.mean_error_per_pixel != 0.0)
+ (void) fprintf(file," Mean Exception Per Pixel: %ld\n",
+ (long) image->error.mean_error_per_pixel);
+ if (image->error.normalized_mean_error != 0.0)
+ (void) fprintf(file," Normalized Mean Exception: %g\n",
+ image->error.normalized_mean_error);
+ if (image->error.normalized_maximum_error != 0.0)
+ (void) fprintf(file," Normalized Maximum Exception: %gn",
+ image->error.normalized_maximum_error);
+ if (image->rendering_intent == SaturationIntent)
+ (void) fprintf(file," Rendering-Intent: saturation\n");
+ else
+ if (image->rendering_intent == PerceptualIntent)
+ (void) fprintf(file," Rendering-Intent: perceptual\n");
+ else
+ if (image->rendering_intent == AbsoluteIntent)
+ (void) fprintf(file," Rendering-Intent: absolute\n");
+ else
+ if (image->rendering_intent == RelativeIntent)
+ (void) fprintf(file," Rendering-Intent: relative\n");
+ if (image->gamma != 0.0)
+ (void) fprintf(file," Gamma: %g\n",image->gamma);
+ if ((image->chromaticity.red_primary.x != 0.0) ||
+ (image->chromaticity.green_primary.x != 0.0) ||
+ (image->chromaticity.blue_primary.x != 0.0) ||
+ (image->chromaticity.white_point.x != 0.0))
+ {
+ /*
+ Display image chromaticity.
+ */
+ (void) fprintf(file," Chromaticity:\n");
+ (void) fprintf(file," red primary: (%g,%g)\n",
+ image->chromaticity.red_primary.x,
+ image->chromaticity.red_primary.y);
+ (void) fprintf(file," green primary: (%g,%g)\n",
+ image->chromaticity.green_primary.x,
+ image->chromaticity.green_primary.y);
+ (void) fprintf(file," blue primary: (%g,%g)\n",
+ image->chromaticity.blue_primary.x,
+ image->chromaticity.blue_primary.y);
+ (void) fprintf(file," white point: (%g,%g)\n",
+ image->chromaticity.white_point.x,
+ image->chromaticity.white_point.y);
+ }
+ if ((image->tile_info.width*image->tile_info.height) != 0)
+ (void) fprintf(file," Tile geometry: %lux%lu%+ld%+ld\n",
+ image->tile_info.width,image->tile_info.height,
+ image->tile_info.x,
+ image->tile_info.y);
+ if ((image->x_resolution != 0.0) && (image->y_resolution != 0.0))
+ {
+ /*
+ Display image resolution.
+ */
+ (void) fprintf(file," Resolution: %gx%g",image->x_resolution,
+ image->y_resolution);
+ if (image->units == UndefinedResolution)
+ (void) fprintf(file," pixels\n");
+ else
+ if (image->units == PixelsPerInchResolution)
+ (void) fprintf(file," pixels/inch\n");
+ else
+ if (image->units == PixelsPerCentimeterResolution)
+ (void) fprintf(file," pixels/centimeter\n");
+ else
+ (void) fprintf(file,"\n");
+ }
+ FormatSize(GetBlobSize(image),format);
+ (void) fprintf(file," Filesize: %.1024s\n",format);
+ fprintf(file," Interlace: %s\n",
+ InterlaceTypeToString(image->interlace == UndefinedInterlace ?
+ NoInterlace : image->interlace));
+ (void) fprintf(file," Orientation: %s\n",
+ OrientationTypeToString(image->orientation));
+ (void) QueryColorname(image,&image->background_color,SVGCompliance,color,
+ &image->exception);
+ (void) fprintf(file," Background Color: %.1024s\n",color);
+ (void) QueryColorname(image,&image->border_color,SVGCompliance,color,
+ &image->exception);
+ (void) fprintf(file," Border Color: %.1024s\n",color);
+ (void) QueryColorname(image,&image->matte_color,SVGCompliance,color,
+ &image->exception);
+ (void) fprintf(file," Matte Color: %.1024s\n",color);
+ if ((image->page.width != 0) && (image->page.height != 0))
+ (void) fprintf(file," Page geometry: %lux%lu%+ld%+ld\n",image->page.width,
+ image->page.height,image->page.x,image->page.y);
+ (void) fprintf(file," Compose: %s\n",
+ CompositeOperatorToString(image->compose));
+ (void) fprintf(file," Dispose: ");
+ switch (image->dispose)
+ {
+ case UndefinedDispose: (void) fprintf(file,"Undefined\n"); break;
+ case NoneDispose: (void) fprintf(file,"None\n"); break;
+ case BackgroundDispose: (void) fprintf(file,"Background\n"); break;
+ case PreviousDispose: (void) fprintf(file,"Previous\n"); break;
+ default: (void) fprintf(file,"\n"); break;
+ }
+ if (image->delay != 0)
+ (void) fprintf(file," Delay: %lu\n",image->delay);
+ if (image->iterations != 1)
+ (void) fprintf(file," Iterations: %lu\n",image->iterations);
+ p=image;
+ while (p->previous != (Image *) NULL)
+ p=p->previous;
+ for (count=1; p->next != (Image *) NULL; count++)
+ p=p->next;
+ if (count > 1)
+ (void) fprintf(file," Scene: %lu of %lu\n",image->scene,count);
+ else
+ if (image->scene != 0)
+ (void) fprintf(file," Scene: %lu\n",image->scene);
+ (void) fprintf(file," Compression: %s\n",
+ CompressionTypeToString(image->compression));
+ /*
+ Display formatted image attributes. This must happen before we access
+ any pseudo attributes like EXIF since doing so causes real attributes
+ to be created and we would get duplicates in the output.
+ */
+ attribute=GetImageAttribute(image,(char *) NULL);
+ {
+ for ( ; attribute != (const ImageAttribute *) NULL;
+ attribute=attribute->next)
+ {
+ if (LocaleNCompare("EXIF",attribute->key,4) != 0)
+ {
+ (void) fprintf(file," %c", toupper((int)attribute->key[0]));
+ if (strlen(attribute->key) > 1)
+ (void) fprintf(file,"%.1024s",attribute->key+1);
+
+ (void) fprintf(file,": ");
+ (void) fprintf(file,"%s\n",attribute->value);
+ }
+ }
+ }
+ if((profile=GetImageProfile(image,"ICM",&profile_length)) != 0)
+ (void) fprintf(file," Profile-color: %lu bytes\n",(unsigned long)
+ profile_length);
+ if((profile=GetImageProfile(image,"IPTC",&profile_length)) != 0)
+ {
+ char
+ *tag,
+ *text;
+
+ size_t
+ length;
+
+ /*
+ Describe IPTC data.
+ */
+ (void) fprintf(file," Profile-iptc: %lu bytes\n",(unsigned long)
+ profile_length);
+ for (i=0; i < profile_length; )
+ {
+ if (profile[i] != 0x1c)
+ {
+ i++;
+ continue;
+ }
+ i++; /* skip file separator */
+ i++; /* skip record number */
+ switch (profile[i])
+ {
+ case 5: tag=(char *) "Image Name"; break;
+ case 7: tag=(char *) "Edit Status"; break;
+ case 10: tag=(char *) "Priority"; break;
+ case 15: tag=(char *) "Category"; break;
+ case 20: tag=(char *) "Supplemental Category"; break;
+ case 22: tag=(char *) "Fixture Identifier"; break;
+ case 25: tag=(char *) "Keyword"; break;
+ case 30: tag=(char *) "Release Date"; break;
+ case 35: tag=(char *) "Release Time"; break;
+ case 40: tag=(char *) "Special Instructions"; break;
+ case 45: tag=(char *) "Reference Service"; break;
+ case 47: tag=(char *) "Reference Date"; break;
+ case 50: tag=(char *) "Reference Number"; break;
+ case 55: tag=(char *) "Created Date"; break;
+ case 60: tag=(char *) "Created Time"; break;
+ case 65: tag=(char *) "Originating Program"; break;
+ case 70: tag=(char *) "Program Version"; break;
+ case 75: tag=(char *) "Object Cycle"; break;
+ case 80: tag=(char *) "Byline"; break;
+ case 85: tag=(char *) "Byline Title"; break;
+ case 90: tag=(char *) "City"; break;
+ case 95: tag=(char *) "Province State"; break;
+ case 100: tag=(char *) "Country Code"; break;
+ case 101: tag=(char *) "Country"; break;
+ case 103: tag=(char *) "Original Transmission Reference"; break;
+ case 105: tag=(char *) "Headline"; break;
+ case 110: tag=(char *) "Credit"; break;
+ case 115: tag=(char *) "Source"; break;
+ case 116: tag=(char *) "Copyright String"; break;
+ case 120: tag=(char *) "Caption"; break;
+ case 121: tag=(char *) "Local Caption"; break;
+ case 122: tag=(char *) "Caption Writer"; break;
+ case 200: tag=(char *) "Custom Field 1"; break;
+ case 201: tag=(char *) "Custom Field 2"; break;
+ case 202: tag=(char *) "Custom Field 3"; break;
+ case 203: tag=(char *) "Custom Field 4"; break;
+ case 204: tag=(char *) "Custom Field 5"; break;
+ case 205: tag=(char *) "Custom Field 6"; break;
+ case 206: tag=(char *) "Custom Field 7"; break;
+ case 207: tag=(char *) "Custom Field 8"; break;
+ case 208: tag=(char *) "Custom Field 9"; break;
+ case 209: tag=(char *) "Custom Field 10"; break;
+ case 210: tag=(char *) "Custom Field 11"; break;
+ case 211: tag=(char *) "Custom Field 12"; break;
+ case 212: tag=(char *) "Custom Field 13"; break;
+ case 213: tag=(char *) "Custom Field 14"; break;
+ case 214: tag=(char *) "Custom Field 15"; break;
+ case 215: tag=(char *) "Custom Field 16"; break;
+ case 216: tag=(char *) "Custom Field 17"; break;
+ case 217: tag=(char *) "Custom Field 18"; break;
+ case 218: tag=(char *) "Custom Field 19"; break;
+ case 219: tag=(char *) "Custom Field 20"; break;
+ default: tag=(char *) "unknown"; break;
+ }
+ i++;
+ (void) fprintf(file," %.1024s:\n",tag);
+ length=profile[i++] << 8;
+ length|=profile[i++];
+ text=MagickAllocateMemory(char *,length+1);
+ if (text != (char *) NULL)
+ {
+ char
+ **textlist;
+
+ register unsigned long
+ j;
+
+ (void) strncpy(text,(char *) profile+i,length);
+ text[length]='\0';
+ textlist=StringToList(text);
+ if (textlist != (char **) NULL)
+ {
+ for (j=0; textlist[j] != (char *) NULL; j++)
+ {
+ (void) fprintf(file," %s\n",textlist[j]);
+ MagickFreeMemory(textlist[j]);
+ }
+ MagickFreeMemory(textlist);
+ }
+ MagickFreeMemory(text);
+ }
+ i+=length;
+ }
+ }
+ {
+ const char
+ *profile_name;
+
+ size_t
+ profile_length;
+
+ const unsigned char *
+ profile_info;
+
+ ImageProfileIterator
+ profile_iterator;
+
+ profile_iterator=AllocateImageProfileIterator(image);
+ while(NextImageProfile(profile_iterator,&profile_name,&profile_info,
+ &profile_length) != MagickFail)
+ {
+ if ((LocaleCompare(profile_name,"ICC") == 0) ||
+ (LocaleCompare(profile_name,"ICM") == 0) ||
+ (LocaleCompare(profile_name,"IPTC") == 0) ||
+ (LocaleCompare(profile_name,"8BIM") == 0))
+ continue;
+
+ if (profile_length == 0)
+ continue;
+ (void) fprintf(file," Profile-%.1024s: %lu bytes\n",
+ profile_name == (char *) NULL ? "generic" : profile_name,
+ (unsigned long) profile_length);
+ if (LocaleCompare(profile_name,"EXIF") == 0)
+ {
+ attribute=GetImageAttribute(image,"EXIF:*");
+ if (attribute != (const ImageAttribute *) NULL)
+ {
+ char
+ **values;
+
+ register char
+ *p;
+
+ values=StringToList(attribute->value);
+ if (values != (char **) NULL)
+ {
+ for (x=0; values[x] != (char *) NULL; x++)
+ {
+ (void) fprintf(file," ");
+ for (p=values[x]; *p != '\0'; p++)
+ {
+ if (p > values[x])
+ if ((isupper((int) ((unsigned char) *p))
+ != MagickFalse) &&
+ (islower((int) ((unsigned char) *(p+1)))
+ != MagickFalse))
+ (void) fprintf(file," ");
+ if (*p == '=')
+ {
+ (void) fprintf(file,": ");
+ for (p++; *p != '\0'; p++)
+ (void) fputc(*p,file);
+ break;
+ }
+ (void) fputc(*p,file);
+ }
+ (void) fputc('\n',file);
+ MagickFreeMemory(values[x]);
+ }
+ MagickFreeMemory(values);
+ }
+ }
+ } /* End of EXIF */
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+ }
+ if (image->montage != (char *) NULL)
+ (void) fprintf(file," Montage: %.1024s\n",image->montage);
+ if (image->directory != (char *) NULL)
+ {
+ Image
+ *tile;
+
+ ImageInfo
+ *image_info;
+
+ register char
+ *p,
+ *q;
+
+ WarningHandler
+ handler;
+
+ /*
+ Display visual image directory.
+ */
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ (void) CloneString(&image_info->size,"64x64");
+ (void) fprintf(file," Directory:\n");
+ for (p=image->directory; *p != '\0'; p++)
+ {
+ q=p;
+ while ((*q != '\n') && (*q != '\0'))
+ q++;
+ (void) strncpy(image_info->filename,p,q-p);
+ image_info->filename[q-p]='\0';
+ p=q;
+ (void) fprintf(file," %.1024s",image_info->filename);
+ handler=SetWarningHandler((WarningHandler) NULL);
+ tile=ReadImage(image_info,&image->exception);
+ (void) SetWarningHandler(handler);
+ if (tile == (Image *) NULL)
+ {
+ (void) fprintf(file,"\n");
+ continue;
+ }
+ (void) fprintf(file," %lux%lu %.1024s\n",tile->magick_columns,
+ tile->magick_rows,tile->magick);
+ (void) SignatureImage(tile);
+ attribute=GetImageAttribute(tile,(char *) NULL);
+ for ( ; attribute != (const ImageAttribute *) NULL;
+ attribute=attribute->next)
+ {
+ if (*attribute->key == '[')
+ continue;
+ (void) fprintf(file," %.1024s:\n",attribute->key);
+ (void) fprintf(file,"%s\n",attribute->value);
+ }
+ DestroyImage(tile);
+ }
+ DestroyImageInfo(image_info);
+ }
+ if (image->taint)
+ (void) fprintf(file," Tainted: True\n");
+ else
+ (void) fprintf(file," Tainted: False\n");
+ /*
+ Only display time information if the time accumulated is at least
+ the timer's resolution.
+ */
+ if (user_time >= GetTimerResolution())
+ (void) fprintf(file," User Time: %0.3fu\n",user_time);
+ if (!(image->ping) && (elapsed_time >= GetTimerResolution()))
+ {
+ (void) fprintf(file," Elapsed Time: %ldm:%.6fs\n",
+ (long) (elapsed_time/60.0),
+ fmod(elapsed_time,60.0));
+ pixels_per_second=(magick_int64_t) ((double) image->rows*
+ image->columns/
+ (elapsed_time > GetTimerResolution() ?
+ elapsed_time : GetTimerResolution()));
+ FormatSize(pixels_per_second,format);
+ (void) fprintf(file," Pixels Per Second: %s\n", format);
+ }
+ (void) fflush(file);
+ return (ferror(file) ? MagickFail : MagickPass);
+}
diff --git a/magick/describe.h b/magick/describe.h
new file mode 100644
index 0000000..fb45a67
--- /dev/null
+++ b/magick/describe.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Describe Methods.
+*/
+#ifndef _MAGICK_DESCRIBE_H
+#define _MAGICK_DESCRIBE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/image.h"
+#include "magick/error.h"
+
+extern MagickExport MagickPassFail
+ DescribeImage(Image *image,FILE *file,const MagickBool verbose);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_DESCRIBE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/display.c b/magick/display.c
new file mode 100644
index 0000000..f41525f
--- /dev/null
+++ b/magick/display.c
@@ -0,0 +1,13887 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD IIIII SSSSS PPPP L AAA Y Y %
+% D D I SS P P L A A Y Y %
+% D D I SSS PPPP L AAAAA Y %
+% D D I SS P L A A Y %
+% DDDD IIIII SSSSS P LLLLL A A Y %
+% %
+% %
+% Methods to Interactively Display and Edit an Image %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#if defined(HasX11)
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/composite.h"
+#include "magick/constitute.h"
+#include "magick/decorate.h"
+#include "magick/delegate.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/fx.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/montage.h"
+#include "magick/paint.h"
+#include "magick/pixel_cache.h"
+#include "magick/quantize.h"
+#include "magick/render.h"
+#include "magick/resize.h"
+#include "magick/shear.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#include "magick/xwindow.h"
+#include "magick/display.h"
+
+/*
+ Constant declaration.
+*/
+static const int
+ RoiDelta = 8;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X A n n o t a t e E d i t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXAnnotateEditImage annotates the image with text.
+%
+% The format of the MagickXAnnotateEditImage method is:
+%
+% unsigned int MagickXAnnotateEditImage(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,Image *image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+*/
+static unsigned int MagickXAnnotateEditImage(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows,Image *image)
+{
+ static const char
+ *AnnotateMenu[]=
+ {
+ "Font Name",
+ "Font Color",
+ "Box Color",
+ "Rotate Text",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ },
+ *TextMenu[]=
+ {
+ "Help",
+ "Apply",
+ (char *) NULL
+ };
+
+ static double
+ degrees = 0.0;
+
+ static const ModeType
+ AnnotateCommands[]=
+ {
+ AnnotateNameCommand,
+ AnnotateFontColorCommand,
+ AnnotateBackgroundColorCommand,
+ AnnotateRotateCommand,
+ AnnotateHelpCommand,
+ AnnotateDismissCommand
+ },
+ TextCommands[]=
+ {
+ TextHelpCommand,
+ TextApplyCommand
+ };
+
+ static unsigned int
+ box_id = MaxNumberPens-2,
+ font_id = 0,
+ pen_id = 0,
+ transparent_box = True,
+ transparent_pen = False;
+
+ char
+ *ColorMenu[MaxNumberPens+1],
+ command[MaxTextExtent],
+ text[MaxTextExtent];
+
+ Cursor
+ cursor;
+
+ GC
+ annotate_context;
+
+ int
+ id,
+ pen_number,
+ x,
+ y;
+
+ KeySym
+ key_symbol;
+
+ register char
+ *p;
+
+ register long
+ i;
+
+ unsigned int
+ height,
+ status,
+ width;
+
+ unsigned long
+ state;
+
+ MagickXAnnotateInfo
+ *annotate_info,
+ *previous_info;
+
+ XColor
+ color;
+
+ XFontStruct
+ *font_info;
+
+ XEvent
+ event,
+ text_event;
+
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"Annotate");
+ windows->command.data=4;
+ (void) MagickXCommandWidget(display,windows,AnnotateMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Track pointer until button 1 is pressed.
+ */
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ cursor=XCreateFontCursor(display,XC_left_side);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+d%+d ",x+windows->image.x,y+windows->image.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,AnnotateMenu,&event);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ if (id < 0)
+ continue;
+ switch (AnnotateCommands[id])
+ {
+ case AnnotateNameCommand:
+ {
+ char
+ *FontMenu[MaxNumberFonts];
+
+ int
+ font_number;
+
+ /*
+ Initialize menu selections.
+ */
+ for (i=0; i < MaxNumberFonts; i++)
+ FontMenu[i]=resource_info->font_name[i];
+ FontMenu[MaxNumberFonts-2]=(char *) "Browser...";
+ FontMenu[MaxNumberFonts-1]=(char *) NULL;
+ /*
+ Select a font name from the pop-up menu.
+ */
+ font_number=MagickXMenuWidget(display,windows,AnnotateMenu[id],
+ (const char **) FontMenu,command);
+ if (font_number < 0)
+ break;
+ if (font_number == (MaxNumberFonts-2))
+ {
+ static char
+ font_name[MaxTextExtent] = "fixed";
+
+ /*
+ Select a font name from a browser.
+ */
+ resource_info->font_name[font_number]=font_name;
+ MagickXFontBrowserWidget(display,windows,"Select",font_name);
+ if (*font_name == '\0')
+ break;
+ }
+ /*
+ Initialize font info.
+ */
+ font_info=
+ XLoadQueryFont(display,resource_info->font_name[font_number]);
+ if (font_info == (XFontStruct *) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to load font:",
+ resource_info->font_name[font_number]);
+ break;
+ }
+ font_id=font_number;
+ (void) XFreeFont(display,font_info);
+ break;
+ }
+ case AnnotateFontColorCommand:
+ {
+ /*
+ Initialize menu selections.
+ */
+ for (i=0; i < (int) (MaxNumberPens-2); i++)
+ ColorMenu[i]=resource_info->pen_colors[i];
+ ColorMenu[MaxNumberPens-2]=(char *) "transparent";
+ ColorMenu[MaxNumberPens-1]=(char *) "Browser...";
+ ColorMenu[MaxNumberPens]=(char *) NULL;
+ /*
+ Select a pen color from the pop-up menu.
+ */
+ pen_number=MagickXMenuWidget(display,windows,AnnotateMenu[id],
+ (const char **) ColorMenu,command);
+ if (pen_number < 0)
+ break;
+ transparent_pen=pen_number == (MaxNumberPens-2);
+ if (transparent_pen)
+ break;
+ if (pen_number == (MaxNumberPens-1))
+ {
+ static char
+ color_name[MaxTextExtent] = "gray";
+
+ /*
+ Select a pen color from a dialog.
+ */
+ resource_info->pen_colors[pen_number]=color_name;
+ MagickXColorBrowserWidget(display,windows,"Select",color_name);
+ if (*color_name == '\0')
+ break;
+ }
+ /*
+ Set pen color.
+ */
+ (void) XParseColor(display,windows->map_info->colormap,
+ resource_info->pen_colors[pen_number],&color);
+ MagickXBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
+ (unsigned int) MaxColors,&color);
+ windows->pixel_info->pen_colors[pen_number]=color;
+ pen_id=pen_number;
+ break;
+ }
+ case AnnotateBackgroundColorCommand:
+ {
+ /*
+ Initialize menu selections.
+ */
+ for (i=0; i < (int) (MaxNumberPens-2); i++)
+ ColorMenu[i]=resource_info->pen_colors[i];
+ ColorMenu[MaxNumberPens-2]=(char *) "transparent";
+ ColorMenu[MaxNumberPens-1]=(char *) "Browser...";
+ ColorMenu[MaxNumberPens]=(char *) NULL;
+ /*
+ Select a pen color from the pop-up menu.
+ */
+ pen_number=MagickXMenuWidget(display,windows,AnnotateMenu[id],
+ (const char **) ColorMenu,command);
+ if (pen_number < 0)
+ break;
+ transparent_box=pen_number == (MaxNumberPens-2);
+ if (transparent_box)
+ break;
+ if (pen_number == (MaxNumberPens-1))
+ {
+ static char
+ color_name[MaxTextExtent] = "gray";
+
+ /*
+ Select a pen color from a dialog.
+ */
+ resource_info->pen_colors[pen_number]=color_name;
+ MagickXColorBrowserWidget(display,windows,"Select",color_name);
+ if (*color_name == '\0')
+ break;
+ }
+ /*
+ Set pen color.
+ */
+ (void) XParseColor(display,windows->map_info->colormap,
+ resource_info->pen_colors[pen_number],&color);
+ MagickXBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
+ (unsigned int) MaxColors,&color);
+ windows->pixel_info->pen_colors[pen_number]=color;
+ box_id=pen_number;
+ break;
+ }
+ case AnnotateRotateCommand:
+ {
+ int
+ entry;
+
+ static char
+ angle[MaxTextExtent] = "30.0";
+
+ static const char
+ *RotateMenu[]=
+ {
+ "-90",
+ "-45",
+ "-30",
+ "0",
+ "30",
+ "45",
+ "90",
+ "180",
+ "Dialog...",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ entry=MagickXMenuWidget(display,windows,AnnotateMenu[id],RotateMenu,
+ command);
+ if (entry < 0)
+ break;
+ if (entry != 8)
+ {
+ degrees=MagickAtoF(RotateMenu[entry]);
+ break;
+ }
+ (void) MagickXDialogWidget(display,windows,"OK","Enter rotation angle:",
+ angle);
+ if (*angle == '\0')
+ break;
+ degrees=MagickAtoF(angle);
+ break;
+ }
+ case AnnotateHelpCommand:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Annotation",ImageAnnotateHelp);
+ break;
+ }
+ case AnnotateDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ Change to text entering mode.
+ */
+ x=event.xbutton.x;
+ y=event.xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case ButtonRelease:
+ break;
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Annotation",ImageAnnotateHelp);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (state & EscapeState)
+ return(True);
+ /*
+ Set font info and check boundary conditions.
+ */
+ font_info=XLoadQueryFont(display,resource_info->font_name[font_id]);
+ if (font_info == (XFontStruct *) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to load font:",
+ resource_info->font_name[font_id]);
+ font_info=windows->font_info;
+ }
+ if ((x+font_info->max_bounds.width) >= (int) windows->image.width)
+ x=windows->image.width-font_info->max_bounds.width;
+ if (y < (long) (font_info->ascent+font_info->descent))
+ y=font_info->ascent+font_info->descent;
+ if ((font_info->max_bounds.width > (int) windows->image.width) ||
+ ((font_info->ascent+font_info->descent) >= (int) windows->image.height))
+ return(False);
+ /*
+ Initialize annotate structure.
+ */
+ annotate_info=MagickAllocateMemory(MagickXAnnotateInfo *,sizeof(MagickXAnnotateInfo));
+ if (annotate_info == (MagickXAnnotateInfo *) NULL)
+ return(False);
+ MagickXGetAnnotateInfo(annotate_info);
+ annotate_info->x=x;
+ annotate_info->y=y;
+ if (!transparent_box && !transparent_pen)
+ annotate_info->stencil=OpaqueStencil;
+ else
+ if (!transparent_box)
+ annotate_info->stencil=BackgroundStencil;
+ else
+ annotate_info->stencil=ForegroundStencil;
+ annotate_info->height=font_info->ascent+font_info->descent;
+ annotate_info->degrees=degrees;
+ annotate_info->font_info=font_info;
+ annotate_info->text=MagickAllocateMemory(char *,
+ windows->image.width/Max(font_info->min_bounds.width,1)+2);
+ if (annotate_info->text == (char *) NULL)
+ {
+ MagickFreeMemory(annotate_info);
+ return(False);
+ }
+ /*
+ Create cursor and set graphic context.
+ */
+ cursor=XCreateFontCursor(display,XC_pencil);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ annotate_context=windows->image.annotate_context;
+ (void) XSetFont(display,annotate_context,font_info->fid);
+ (void) XSetBackground(display,annotate_context,
+ windows->pixel_info->pen_colors[box_id].pixel);
+ (void) XSetForeground(display,annotate_context,
+ windows->pixel_info->pen_colors[pen_id].pixel);
+ /*
+ Begin annotating the image with text.
+ */
+ (void) CloneString(&windows->command.name,"Text");
+ windows->command.data=0;
+ (void) MagickXCommandWidget(display,windows,TextMenu,(XEvent *) NULL);
+ state=DefaultState;
+ (void) XDrawString(display,windows->image.id,annotate_context,x,y,"_",1);
+ text_event.xexpose.width=(unsigned int) font_info->max_bounds.width;
+ text_event.xexpose.height=font_info->max_bounds.ascent+
+ font_info->max_bounds.descent;
+ p=annotate_info->text;
+ do
+ {
+ /*
+ Display text cursor.
+ */
+ *p='\0';
+ (void) XDrawString(display,windows->image.id,annotate_context,x,y,"_",1);
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ (void) XSetBackground(display,annotate_context,
+ windows->pixel_info->background_color.pixel);
+ (void) XSetForeground(display,annotate_context,
+ windows->pixel_info->foreground_color.pixel);
+ id=MagickXCommandWidget(display,windows,AnnotateMenu,&event);
+ (void) XSetBackground(display,annotate_context,
+ windows->pixel_info->pen_colors[box_id].pixel);
+ (void) XSetForeground(display,annotate_context,
+ windows->pixel_info->pen_colors[pen_id].pixel);
+ if (id < 0)
+ continue;
+ switch (TextCommands[id])
+ {
+ case TextHelpCommand:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Annotation",ImageAnnotateHelp);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ break;
+ }
+ case TextApplyCommand:
+ {
+ /*
+ Finished annotating.
+ */
+ annotate_info->width=XTextWidth(font_info,annotate_info->text,
+ (int) strlen(annotate_info->text));
+ MagickXRefreshWindow(display,&windows->image,&text_event);
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ continue;
+ }
+ /*
+ Erase text cursor.
+ */
+ text_event.xexpose.x=x;
+ text_event.xexpose.y=y-font_info->max_bounds.ascent;
+ (void) XClearArea(display,windows->image.id,x,text_event.xexpose.y,
+ text_event.xexpose.width,text_event.xexpose.height,False);
+ MagickXRefreshWindow(display,&windows->image,&text_event);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.window != windows->image.id)
+ break;
+ if (event.xbutton.button == Button2)
+ {
+ /*
+ Request primary selection.
+ */
+ (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
+ windows->image.id,CurrentTime);
+ break;
+ }
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.count == 0)
+ {
+ MagickXAnnotateInfo
+ *text_info;
+
+ /*
+ Refresh Image window.
+ */
+ MagickXRefreshWindow(display,&windows->image,(XEvent *) NULL);
+ text_info=annotate_info;
+ while (text_info != (MagickXAnnotateInfo *) NULL)
+ {
+ if (annotate_info->stencil == ForegroundStencil)
+ (void) XDrawString(display,windows->image.id,annotate_context,
+ text_info->x,text_info->y,text_info->text,
+ (int) strlen(text_info->text));
+ else
+ (void) XDrawImageString(display,windows->image.id,
+ annotate_context,text_info->x,text_info->y,text_info->text,
+ (int) strlen(text_info->text));
+ text_info=text_info->previous;
+ }
+ (void) XDrawString(display,windows->image.id,annotate_context,
+ x,y,"_",1);
+ }
+ break;
+ }
+ case KeyPress:
+ {
+ int
+ length;
+
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if ((event.xkey.state & ControlMask) || (event.xkey.state & Mod1Mask))
+ state|=ModifierState;
+ if (state & ModifierState)
+ switch ((int) key_symbol)
+ {
+ case XK_u:
+ case XK_U:
+ {
+ key_symbol=DeleteCommand;
+ break;
+ }
+ default:
+ break;
+ }
+ switch ((int) key_symbol)
+ {
+ case XK_BackSpace:
+ {
+ /*
+ Erase one character.
+ */
+ if (p == annotate_info->text)
+ {
+ if (annotate_info->previous == (MagickXAnnotateInfo *) NULL)
+ break;
+ else
+ {
+ /*
+ Go to end of the previous line of text.
+ */
+ annotate_info=annotate_info->previous;
+ p=annotate_info->text;
+ x=annotate_info->x+annotate_info->width;
+ y=annotate_info->y;
+ if (annotate_info->width != 0)
+ p+=strlen(annotate_info->text);
+ break;
+ }
+ }
+ p--;
+ x-=XTextWidth(font_info,p,1);
+ text_event.xexpose.x=x;
+ text_event.xexpose.y=y-font_info->max_bounds.ascent;
+ MagickXRefreshWindow(display,&windows->image,&text_event);
+ break;
+ }
+ case XK_bracketleft:
+ {
+ key_symbol=XK_Escape;
+ break;
+ }
+ case DeleteCommand:
+ {
+ /*
+ Erase the entire line of text.
+ */
+ while (p != annotate_info->text)
+ {
+ p--;
+ x-=XTextWidth(font_info,p,1);
+ text_event.xexpose.x=x;
+ MagickXRefreshWindow(display,&windows->image,&text_event);
+ }
+ break;
+ }
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Finished annotating.
+ */
+ annotate_info->width=XTextWidth(font_info,annotate_info->text,
+ (int) strlen(annotate_info->text));
+ MagickXRefreshWindow(display,&windows->image,&text_event);
+ state|=ExitState;
+ break;
+ }
+ default:
+ {
+ /*
+ Draw a single character on the Image window.
+ */
+ if (state & ModifierState)
+ break;
+ if (*command == '\0')
+ break;
+ *p=(*command);
+ if (annotate_info->stencil == ForegroundStencil)
+ (void) XDrawString(display,windows->image.id,annotate_context,
+ x,y,p,1);
+ else
+ (void) XDrawImageString(display,windows->image.id,
+ annotate_context,x,y,p,1);
+ x+=XTextWidth(font_info,p,1);
+ p++;
+ if ((x+font_info->max_bounds.width) < (int) windows->image.width)
+ break;
+ }
+ case XK_Return:
+ case XK_KP_Enter:
+ {
+ /*
+ Advance to the next line of text.
+ */
+ *p='\0';
+ annotate_info->width=XTextWidth(font_info,annotate_info->text,
+ (int) strlen(annotate_info->text));
+ if (annotate_info->next != (MagickXAnnotateInfo *) NULL)
+ {
+ /*
+ Line of text already exists.
+ */
+ annotate_info=annotate_info->next;
+ x=annotate_info->x;
+ y=annotate_info->y;
+ p=annotate_info->text;
+ break;
+ }
+ annotate_info->next=MagickAllocateMemory(MagickXAnnotateInfo *,
+ sizeof(MagickXAnnotateInfo));
+ if (annotate_info->next == (MagickXAnnotateInfo *) NULL)
+ return(False);
+ *annotate_info->next=(*annotate_info);
+ annotate_info->next->previous=annotate_info;
+ annotate_info=annotate_info->next;
+ annotate_info->text=MagickAllocateMemory(char *,windows->image.width/
+ Max(font_info->min_bounds.width,1)+2);
+ if (annotate_info->text == (char *) NULL)
+ return(False);
+ annotate_info->y+=annotate_info->height;
+ if (annotate_info->y > (int) windows->image.height)
+ annotate_info->y=annotate_info->height;
+ annotate_info->next=(MagickXAnnotateInfo *) NULL;
+ x=annotate_info->x;
+ y=annotate_info->y;
+ p=annotate_info->text;
+ break;
+ }
+ }
+ break;
+ }
+ case KeyRelease:
+ {
+ /*
+ Respond to a user key release.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ state&=(~ModifierState);
+ break;
+ }
+ case SelectionNotify:
+ {
+ Atom
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ Obtain response from primary selection.
+ */
+ if (event.xselection.property == (Atom) None)
+ break;
+ status=XGetWindowProperty(display,event.xselection.requestor,
+ event.xselection.property,0L,MaxTextExtent-1,True,XA_STRING,&type,
+ &format,&length,&after,&data);
+ if ((status != Success) || (type != XA_STRING) || (format == 32) ||
+ (length == 0))
+ break;
+ /*
+ Annotate Image window with primary selection.
+ */
+ for (i=0; i < (long) length; i++)
+ {
+ if ((char) data[i] != '\n')
+ {
+ /*
+ Draw a single character on the Image window.
+ */
+ *p=data[i];
+ (void) XDrawString(display,windows->image.id,annotate_context,
+ x,y,p,1);
+ x+=XTextWidth(font_info,p,1);
+ p++;
+ if ((x+font_info->max_bounds.width) < (int) windows->image.width)
+ continue;
+ }
+ /*
+ Advance to the next line of text.
+ */
+ *p='\0';
+ annotate_info->width=XTextWidth(font_info,annotate_info->text,
+ (int) strlen(annotate_info->text));
+ if (annotate_info->next != (MagickXAnnotateInfo *) NULL)
+ {
+ /*
+ Line of text already exists.
+ */
+ annotate_info=annotate_info->next;
+ x=annotate_info->x;
+ y=annotate_info->y;
+ p=annotate_info->text;
+ continue;
+ }
+ annotate_info->next=MagickAllocateMemory(MagickXAnnotateInfo *,
+ sizeof(MagickXAnnotateInfo));
+ if (annotate_info->next == (MagickXAnnotateInfo *) NULL)
+ return(False);
+ *annotate_info->next=(*annotate_info);
+ annotate_info->next->previous=annotate_info;
+ annotate_info=annotate_info->next;
+ annotate_info->text=MagickAllocateMemory(char *,windows->image.width/
+ Max(font_info->min_bounds.width,1)+2);
+ if (annotate_info->text == (char *) NULL)
+ return(False);
+ annotate_info->y+=annotate_info->height;
+ if (annotate_info->y > (int) windows->image.height)
+ annotate_info->y=annotate_info->height;
+ annotate_info->next=(MagickXAnnotateInfo *) NULL;
+ x=annotate_info->x;
+ y=annotate_info->y;
+ p=annotate_info->text;
+ }
+ (void) XFree((void *) data);
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ (void) XFreeCursor(display,cursor);
+ /*
+ Annotation is relative to image configuration.
+ */
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ /*
+ Initialize annotated image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ while (annotate_info != (MagickXAnnotateInfo *) NULL)
+ {
+ if (annotate_info->width == 0)
+ {
+ /*
+ No text on this line-- go to the next line of text.
+ */
+ previous_info=annotate_info->previous;
+ MagickFreeMemory(annotate_info->text);
+ MagickFreeMemory(annotate_info);
+ annotate_info=previous_info;
+ continue;
+ }
+ /*
+ Determine pixel index for box and pen color.
+ */
+ windows->pixel_info->box_color=windows->pixel_info->pen_colors[box_id];
+ if (windows->pixel_info->colors != 0)
+ for (i=0; i < (long) windows->pixel_info->colors; i++)
+ if (windows->pixel_info->pixels[i] ==
+ windows->pixel_info->pen_colors[box_id].pixel)
+ {
+ windows->pixel_info->box_index=(unsigned short) i;
+ break;
+ }
+ windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
+ if (windows->pixel_info->colors != 0)
+ for (i=0; i < (long) windows->pixel_info->colors; i++)
+ if (windows->pixel_info->pixels[i] ==
+ windows->pixel_info->pen_colors[pen_id].pixel)
+ {
+ windows->pixel_info->pen_index=(unsigned short) i;
+ break;
+ }
+ /*
+ Define the annotate geometry string.
+ */
+ annotate_info->x=
+ width*(annotate_info->x+windows->image.x)/windows->image.ximage->width;
+ annotate_info->y=height*(annotate_info->y-font_info->ascent+
+ windows->image.y)/windows->image.ximage->height;
+ FormatString(annotate_info->geometry,"%ux%u%+d%+d",
+ width*annotate_info->width/windows->image.ximage->width,
+ height*annotate_info->height/windows->image.ximage->height,
+ annotate_info->x+x,annotate_info->y+y);
+ /*
+ Annotate image with text.
+ */
+ status=MagickXAnnotateImage(display,windows->pixel_info,annotate_info,image);
+ if (status == 0)
+ return(False);
+ /*
+ Free up memory.
+ */
+ previous_info=annotate_info->previous;
+ MagickFreeMemory(annotate_info->text);
+ MagickFreeMemory(annotate_info);
+ annotate_info=previous_info;
+ }
+ (void) XSetForeground(display,annotate_context,
+ windows->pixel_info->foreground_color.pixel);
+ (void) XSetBackground(display,annotate_context,
+ windows->pixel_info->background_color.pixel);
+ (void) XSetFont(display,annotate_context,windows->font_info->fid);
+ MagickXSetCursorState(display,windows,False);
+ (void) XFreeFont(display,font_info);
+ /*
+ Update image configuration.
+ */
+ MagickXConfigureImageColormap(display,resource_info,windows,image);
+ (void) MagickXConfigureImage(display,resource_info,windows,image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X B a c k g r o u n d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXBackgroundImage displays the image in the background of a window.
+%
+% The format of the MagickXBackgroundImage method is:
+%
+% unsigned int MagickXBackgroundImage(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,Image **image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXBackgroundImage return True if the image is
+% printed. False is returned is there is a memory shortage or if the
+% image fails to print.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int MagickXBackgroundImage(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows,Image **image)
+{
+#define BackgroundImageText " Background the image... "
+
+ static char
+ window_id[MaxTextExtent] = "root";
+
+ MagickXResourceInfo
+ background_resources;
+
+ unsigned int
+ status;
+
+ /*
+ Put image in background.
+ */
+ status=MagickXDialogWidget(display,windows,"Background",
+ "Enter window id (id 0x00 selects window with pointer):",window_id);
+ if (*window_id == '\0')
+ return(False);
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXInfoWidget(display,windows,BackgroundImageText);
+ /*
+ Display hourglass cursor if progress indication enabled.
+ */
+ if (resource_info->image_info->progress)
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ background_resources=(*resource_info);
+ background_resources.window_id=window_id;
+ background_resources.backdrop=status;
+ status=MagickXDisplayBackgroundImage(display,&background_resources,*image);
+ if (status)
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_retain_colors,CurrentTime);
+ MagickXSetCursorState(display,windows,False);
+ (void) MagickXMagickCommand(display,resource_info,windows,UndoCommand,image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X C h o p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXChopImage chops the X image.
+%
+% The format of the MagickXChopImage method is:
+%
+% unsigned int MagickXChopImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image **image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXChopImage return True if the image is
+% cut. False is returned is there is a memory shortage or if the
+% image fails to cut.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int MagickXChopImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image **image)
+{
+ static const char
+ *ChopMenu[]=
+ {
+ "Direction",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ };
+
+ static ModeType
+ direction = HorizontalChopCommand;
+
+ static const ModeType
+ ChopCommands[]=
+ {
+ ChopDirectionCommand,
+ ChopHelpCommand,
+ ChopDismissCommand
+ },
+ DirectionCommands[]=
+ {
+ HorizontalChopCommand,
+ VerticalChopCommand
+ };
+
+ char
+ text[MaxTextExtent];
+
+ double
+ scale_factor;
+
+ Image
+ *chop_image;
+
+ int
+ id,
+ x,
+ y;
+
+ RectangleInfo
+ chop_info;
+
+ unsigned int
+ distance,
+ height,
+ width;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ XSegment
+ segment_info;
+
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"Chop");
+ windows->command.data=1;
+ (void) MagickXCommandWidget(display,windows,ChopMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Track pointer until button 1 is pressed.
+ */
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+d%+d ",x+windows->image.x,y+windows->image.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,ChopMenu,&event);
+ if (id < 0)
+ continue;
+ switch (ChopCommands[id])
+ {
+ case ChopDirectionCommand:
+ {
+ char
+ command[MaxTextExtent];
+
+ static const char
+ *Directions[]=
+ {
+ "horizontal",
+ "vertical",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ id=
+ MagickXMenuWidget(display,windows,ChopMenu[id],Directions,command);
+ if (id >= 0)
+ direction=DirectionCommands[id];
+ break;
+ }
+ case ChopHelpCommand:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Chop",ImageChopHelp);
+ break;
+ }
+ case ChopDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ User has committed to start point of chopping line.
+ */
+ segment_info.x1=event.xbutton.x;
+ segment_info.x2=event.xbutton.x;
+ segment_info.y1=event.xbutton.y;
+ segment_info.y2=event.xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case ButtonRelease:
+ break;
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ char
+ command[MaxTextExtent];
+
+ KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,
+ sizeof(command),&key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Chop",ImageChopHelp);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ }
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (state & EscapeState)
+ return(True);
+ /*
+ Draw line as pointer moves until the mouse button is released.
+ */
+ chop_info.width=0;
+ chop_info.height=0;
+ chop_info.x=0;
+ chop_info.y=0;
+ distance=0;
+ (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
+ state=DefaultState;
+ do
+ {
+ if (distance > 9)
+ {
+ /*
+ Display info and draw chopping line.
+ */
+ if (!windows->info.mapped)
+ (void) XMapWindow(display,windows->info.id);
+ FormatString(text," %lux%lu%+ld%+ld",chop_info.width,chop_info.height,
+ chop_info.x,chop_info.y);
+ MagickXInfoWidget(display,windows,text);
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&segment_info);
+ }
+ else
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (distance > 9)
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&segment_info);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ segment_info.x2=event.xmotion.x;
+ segment_info.y2=event.xmotion.y;
+ break;
+ }
+ case ButtonRelease:
+ {
+ /*
+ User has committed to chopping line.
+ */
+ segment_info.x2=event.xbutton.x;
+ segment_info.y2=event.xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case Expose:
+ break;
+ case MotionNotify:
+ {
+ segment_info.x2=event.xmotion.x;
+ segment_info.y2=event.xmotion.y;
+ }
+ default:
+ break;
+ }
+ /*
+ Check boundary conditions.
+ */
+ if (segment_info.x2 < 0)
+ segment_info.x2=0;
+ else
+ if (segment_info.x2 > windows->image.ximage->width)
+ segment_info.x2=windows->image.ximage->width;
+ if (segment_info.y2 < 0)
+ segment_info.y2=0;
+ else
+ if (segment_info.y2 > windows->image.ximage->height)
+ segment_info.y2=windows->image.ximage->height;
+ distance=
+ ((segment_info.x2-segment_info.x1)*(segment_info.x2-segment_info.x1))+
+ ((segment_info.y2-segment_info.y1)*(segment_info.y2-segment_info.y1));
+ /*
+ Compute chopping geometry.
+ */
+ if (direction == HorizontalChopCommand)
+ {
+ chop_info.width=segment_info.x2-segment_info.x1+1;
+ chop_info.x=windows->image.x+segment_info.x1;
+ chop_info.height=0;
+ chop_info.y=0;
+ if (segment_info.x1 > (int) segment_info.x2)
+ {
+ chop_info.width=segment_info.x1-segment_info.x2+1;
+ chop_info.x=windows->image.x+segment_info.x2;
+ }
+ }
+ else
+ {
+ chop_info.width=0;
+ chop_info.height=segment_info.y2-segment_info.y1+1;
+ chop_info.x=0;
+ chop_info.y=windows->image.y+segment_info.y1;
+ if (segment_info.y1 > segment_info.y2)
+ {
+ chop_info.height=segment_info.y1-segment_info.y2+1;
+ chop_info.y=windows->image.y+segment_info.y2;
+ }
+ }
+ } while (!(state & ExitState));
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (distance <= 9)
+ return(True);
+ /*
+ Image chopping is relative to image configuration.
+ */
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ windows->image.window_changes.width=
+ windows->image.ximage->width-(unsigned int) chop_info.width;
+ windows->image.window_changes.height=
+ windows->image.ximage->height-(unsigned int) chop_info.height;
+ width=(unsigned int) (*image)->columns;
+ height=(unsigned int) (*image)->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ scale_factor=(double) width/windows->image.ximage->width;
+ chop_info.x+=x;
+ chop_info.x=(int) (scale_factor*chop_info.x+0.5);
+ chop_info.width=(unsigned int) (scale_factor*chop_info.width+0.5);
+ scale_factor=(double) height/windows->image.ximage->height;
+ chop_info.y+=y;
+ chop_info.y=(int) (scale_factor*chop_info.y+0.5);
+ chop_info.height=(unsigned int) (scale_factor*chop_info.height+0.5);
+ /*
+ Chop image.
+ */
+ chop_image=ChopImage(*image,&chop_info,&(*image)->exception);
+ MagickXSetCursorState(display,windows,False);
+ if (chop_image == (Image *) NULL)
+ return(False);
+ DestroyImage(*image);
+ *image=chop_image;
+ /*
+ Update image configuration.
+ */
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X C o l o r E d i t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXColorEditImage allows the user to interactively change
+% the color of one pixel for a DirectColor image or one colormap entry for
+% a PseudoClass image.
+%
+% The format of the MagickXColorEditImage method is:
+%
+% unsigned int MagickXColorEditImage(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,Image **image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+*/
+static unsigned int MagickXColorEditImage(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows,Image **image)
+{
+ static const char
+ *ColorEditMenu[]=
+ {
+ "Method",
+ "Pixel Color",
+ "Border Color",
+ "Fuzz",
+ "Undo",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ };
+
+ static const ModeType
+ ColorEditCommands[]=
+ {
+ ColorEditMethodCommand,
+ ColorEditColorCommand,
+ ColorEditBorderCommand,
+ ColorEditFuzzCommand,
+ ColorEditUndoCommand,
+ ColorEditHelpCommand,
+ ColorEditDismissCommand
+ };
+
+ static PaintMethod
+ method = PointMethod;
+
+ static unsigned int
+ pen_id = 0;
+
+ static XColor
+ border_color = { 0, 0, 0, 0, 0, 0 }; /* Also fill 'pad' field */
+
+ char
+ command[MaxTextExtent],
+ text[MaxTextExtent];
+
+ Cursor
+ cursor;
+
+ int
+ entry,
+ id,
+ x,
+ x_offset,
+ y,
+ y_offset;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ unsigned int
+ height,
+ width;
+
+ unsigned long
+ state;
+
+ XColor
+ color;
+
+ XEvent
+ event;
+
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"Color Edit");
+ windows->command.data=4;
+ (void) MagickXCommandWidget(display,windows,ColorEditMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Make cursor.
+ */
+ cursor=MagickXMakeCursor(display,windows->image.id,windows->map_info->colormap,
+ resource_info->background_color,resource_info->foreground_color);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ /*
+ Track pointer until button 1 is pressed.
+ */
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+d%+d ",x+windows->image.x,y+windows->image.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,ColorEditMenu,&event);
+ if (id < 0)
+ {
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ continue;
+ }
+ switch (ColorEditCommands[id])
+ {
+ case ColorEditMethodCommand:
+ {
+ static const char
+ *MethodMenu[]=
+ {
+ "point",
+ "replace",
+ "floodfill",
+ "filltoborder",
+ "reset",
+ (char *) NULL,
+ };
+
+ /*
+ Select a method from the pop-up menu.
+ */
+ entry=
+ MagickXMenuWidget(display,windows,ColorEditMenu[id],MethodMenu,command);
+ if (entry >= 0)
+ method=(PaintMethod) entry;
+ break;
+ }
+ case ColorEditColorCommand:
+ {
+ char
+ *ColorMenu[MaxNumberPens];
+
+ int
+ pen_number;
+
+ /*
+ Initialize menu selections.
+ */
+ for (i=0; i < (int) (MaxNumberPens-2); i++)
+ ColorMenu[i]=resource_info->pen_colors[i];
+ ColorMenu[MaxNumberPens-2]=(char *) "Browser...";
+ ColorMenu[MaxNumberPens-1]=(char *) NULL;
+ /*
+ Select a pen color from the pop-up menu.
+ */
+ pen_number=MagickXMenuWidget(display,windows,ColorEditMenu[id],
+ (const char **) ColorMenu,command);
+ if (pen_number < 0)
+ break;
+ if (pen_number == (MaxNumberPens-2))
+ {
+ static char
+ color_name[MaxTextExtent] = "gray";
+
+ /*
+ Select a pen color from a dialog.
+ */
+ resource_info->pen_colors[pen_number]=color_name;
+ MagickXColorBrowserWidget(display,windows,"Select",color_name);
+ if (*color_name == '\0')
+ break;
+ }
+ /*
+ Set pen color.
+ */
+ (void) XParseColor(display,windows->map_info->colormap,
+ resource_info->pen_colors[pen_number],&color);
+ MagickXBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
+ (unsigned int) MaxColors,&color);
+ windows->pixel_info->pen_colors[pen_number]=color;
+ pen_id=pen_number;
+ break;
+ }
+ case ColorEditBorderCommand:
+ {
+ char
+ *ColorMenu[MaxNumberPens];
+
+ int
+ pen_number;
+
+ /*
+ Initialize menu selections.
+ */
+ for (i=0; i < (int) (MaxNumberPens-2); i++)
+ ColorMenu[i]=resource_info->pen_colors[i];
+ ColorMenu[MaxNumberPens-2]=(char *) "Browser...";
+ ColorMenu[MaxNumberPens-1]=(char *) NULL;
+ /*
+ Select a pen color from the pop-up menu.
+ */
+ pen_number=MagickXMenuWidget(display,windows,ColorEditMenu[id],
+ (const char **) ColorMenu,command);
+ if (pen_number < 0)
+ break;
+ if (pen_number == (MaxNumberPens-2))
+ {
+ static char
+ color_name[MaxTextExtent] = "gray";
+
+ /*
+ Select a pen color from a dialog.
+ */
+ resource_info->pen_colors[pen_number]=color_name;
+ MagickXColorBrowserWidget(display,windows,"Select",color_name);
+ if (*color_name == '\0')
+ break;
+ }
+ /*
+ Set border color.
+ */
+ (void) XParseColor(display,windows->map_info->colormap,
+ resource_info->pen_colors[pen_number],&border_color);
+ break;
+ }
+ case ColorEditFuzzCommand:
+ {
+ static char
+ fuzz[MaxTextExtent];
+
+ static const char
+ *FuzzMenu[]=
+ {
+ "0%",
+ "2%",
+ "5%",
+ "10%",
+ "15%",
+ "Dialog...",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ entry=MagickXMenuWidget(display,windows,ColorEditMenu[id],FuzzMenu,
+ command);
+ if (entry < 0)
+ break;
+ if (entry != 5)
+ {
+ (*image)->fuzz=StringToDouble(FuzzMenu[entry],MaxRGB);
+ break;
+ }
+ (void) strcpy(fuzz,"20%");
+ (void) MagickXDialogWidget(display,windows,"Ok",
+ "Enter fuzz factor (0.0 - 99.9%):",fuzz);
+ if (*fuzz == '\0')
+ break;
+ (void) strcat(fuzz,"%");
+ (*image)->fuzz=StringToDouble(fuzz,MaxRGB);
+ break;
+ }
+ case ColorEditUndoCommand:
+ {
+ (void) MagickXMagickCommand(display,resource_info,windows,UndoCommand,
+ image);
+ break;
+ }
+ case ColorEditHelpCommand:
+ default:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Annotation",ImageColorEditHelp);
+ break;
+ }
+ case ColorEditDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ }
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if ((event.xbutton.window != windows->image.id) &&
+ (event.xbutton.window != windows->magnify.id))
+ break;
+ /*
+ Exit loop.
+ */
+ x=event.xbutton.x;
+ y=event.xbutton.y;
+ (void) MagickXMagickCommand(display,resource_info,windows,
+ SaveToUndoBufferCommand,image);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if ((event.xbutton.window != windows->image.id) &&
+ (event.xbutton.window != windows->magnify.id))
+ break;
+ /*
+ Update colormap information.
+ */
+ x=event.xbutton.x;
+ y=event.xbutton.y;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ MagickXInfoWidget(display,windows,text);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ state&=(~UpdateConfigurationState);
+ break;
+ }
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ KeySym
+ key_symbol;
+
+ if (event.xkey.window == windows->magnify.id)
+ {
+ Window
+ window;
+
+ window=windows->magnify.id;
+ while (XCheckWindowEvent(display,window,KeyPressMask,&event));
+ }
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Annotation",ImageColorEditHelp);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ break;
+ }
+ default:
+ break;
+ }
+ if (event.xany.window == windows->magnify.id)
+ {
+ x=windows->magnify.x-windows->image.x;
+ y=windows->magnify.y-windows->image.y;
+ }
+ x_offset=x;
+ y_offset=y;
+ if (state & UpdateConfigurationState)
+ {
+ int
+ x,
+ y;
+
+ /*
+ Pixel edit is relative to image configuration.
+ */
+ (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,True);
+ color=windows->pixel_info->pen_colors[pen_id];
+ XPutPixel(windows->image.ximage,x_offset,y_offset,color.pixel);
+ width=(unsigned int) (*image)->columns;
+ height=(unsigned int) (*image)->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
+ &width,&height);
+ x_offset=
+ width*(windows->image.x+x_offset)/windows->image.ximage->width+x;
+ y_offset=
+ height*(windows->image.y+y_offset)/windows->image.ximage->height+y;
+ if ((x_offset < 0) || (y_offset < 0))
+ continue;
+ if ((x_offset >= (long) (*image)->columns) ||
+ (y_offset >= (long) (*image)->rows))
+ continue;
+ switch (method)
+ {
+ case PointMethod:
+ default:
+ {
+ /*
+ Update color information using point algorithm.
+ */
+ (void) SetImageType(*image,TrueColorType);
+ q=GetImagePixels(*image,x_offset,y_offset,1,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ q->red=ScaleShortToQuantum(color.red);
+ q->green=ScaleShortToQuantum(color.green);
+ q->blue=ScaleShortToQuantum(color.blue);
+ (void) SyncImagePixels(*image);
+ break;
+ }
+ case ReplaceMethod:
+ {
+ PixelPacket
+ target;
+
+ /*
+ Update color information using replace algorithm.
+ */
+ (void) AcquireOnePixelByReference(*image,&target,x_offset,y_offset,&((*image)->exception));
+ if ((*image)->storage_class == DirectClass)
+ {
+ for (y=0; y < (long) (*image)->rows; y++)
+ {
+ q=GetImagePixels(*image,0,y,(*image)->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (int) (*image)->columns; x++)
+ {
+ if (FuzzyColorMatch(q,&target,(*image)->fuzz))
+ {
+ q->red=ScaleShortToQuantum(color.red);
+ q->green=ScaleShortToQuantum(color.green);
+ q->blue=ScaleShortToQuantum(color.blue);
+ }
+ q++;
+ }
+ if (!SyncImagePixels(*image))
+ break;
+ }
+ }
+ else
+ {
+ for (i=0; i < (int) (*image)->colors; i++)
+ if (FuzzyColorMatch((*image)->colormap+i,&target,(*image)->fuzz))
+ {
+ (*image)->colormap[i].red=ScaleShortToQuantum(color.red);
+ (*image)->colormap[i].green=
+ ScaleShortToQuantum(color.green);
+ (*image)->colormap[i].blue=
+ ScaleShortToQuantum(color.blue);
+ }
+ (void) SyncImage(*image);
+ }
+ break;
+ }
+ case FloodfillMethod:
+ case FillToBorderMethod:
+ {
+ DrawInfo
+ *draw_info;
+
+ PixelPacket
+ target;
+
+ /*
+ Update color information using floodfill algorithm.
+ */
+ (void) AcquireOnePixelByReference(*image,&target,x_offset,y_offset,&((*image)->exception));
+ if (method == FillToBorderMethod)
+ {
+ target.red=ScaleShortToQuantum(border_color.red);
+ target.green=ScaleShortToQuantum(border_color.green);
+ target.blue=ScaleShortToQuantum(border_color.blue);
+ }
+ draw_info=
+ CloneDrawInfo(resource_info->image_info,(DrawInfo *) NULL);
+ (void) QueryColorDatabase(resource_info->pen_colors[pen_id],
+ &draw_info->fill,&(*image)->exception);
+ (void) ColorFloodfillImage(*image,draw_info,target,x_offset,
+ y_offset,method);
+ DestroyDrawInfo(draw_info);
+ break;
+ }
+ case ResetMethod:
+ {
+ /*
+ Update color information using reset algorithm.
+ */
+ (void) SetImageType(*image,TrueColorType);
+ for (y=0; y < (long) (*image)->rows; y++)
+ {
+ q=SetImagePixels(*image,0,y,(*image)->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (int) (*image)->columns; x++)
+ {
+ q->red=ScaleShortToQuantum(color.red);
+ q->green=ScaleShortToQuantum(color.green);
+ q->blue=ScaleShortToQuantum(color.blue);
+ q++;
+ }
+ if (!SyncImagePixels(*image))
+ break;
+ }
+ break;
+ }
+ }
+ state&=(~UpdateConfigurationState);
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ MagickXSetCursorState(display,windows,False);
+ (void) XFreeCursor(display,cursor);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X C o m p o s i t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXCompositeImage requests an image name from the user, reads
+% the image and composites it with the X window image at a location the user
+% chooses with the pointer.
+%
+% The format of the MagickXCompositeImage method is:
+%
+% unsigned int MagickXCompositeImage(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXCompositeImage returns True if the image is
+% composited. False is returned is there is a memory shortage or if the
+% image fails to be composited.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+*/
+static unsigned int MagickXCompositeImage(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows,Image *image)
+{
+ static char
+ displacement_geometry[MaxTextExtent] = "30x30",
+ filename[MaxTextExtent] = "\0";
+
+ static const char
+ *CompositeMenu[]=
+ {
+ "Operators",
+ "Dissolve",
+ "Displace",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ };
+
+ static CompositeOperator
+ compose = CopyCompositeOp;
+
+ static const ModeType
+ CompositeCommands[]=
+ {
+ CompositeOperatorsCommand,
+ CompositeDissolveCommand,
+ CompositeDisplaceCommand,
+ CompositeHelpCommand,
+ CompositeDismissCommand
+ };
+
+ char
+ text[MaxTextExtent];
+
+ Cursor
+ cursor;
+
+ double
+ blend,
+ scale_factor;
+
+ Image
+ *composite_image;
+
+ int
+ id,
+ x,
+ y;
+
+ RectangleInfo
+ highlight_info,
+ composite_info;
+
+ unsigned int
+ height,
+ width;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ /*
+ Request image file name from user.
+ */
+ MagickXFileBrowserWidget(display,windows,"Composite",filename);
+ if (*filename == '\0')
+ return(True);
+ /*
+ Read image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) strlcpy(resource_info->image_info->filename,filename,MaxTextExtent);
+ composite_image=ReadImage(resource_info->image_info,&image->exception);
+ if (image->exception.severity != UndefinedException)
+ MagickError2(image->exception.severity,image->exception.reason,
+ image->exception.description);
+ MagickXSetCursorState(display,windows,False);
+ if (composite_image == (Image *) NULL)
+ return(False);
+ if (!composite_image->matte)
+ {
+ /*
+ Request mask image file name from user.
+ */
+ MagickXNoticeWidget(display,windows,
+ "Your image does not have the required matte information.",
+ "Press dismiss and choose an image to use as a mask.");
+ MagickXFileBrowserWidget(display,windows,"Composite",filename);
+ if (*filename != '\0')
+ {
+ char
+ size[MaxTextExtent];
+
+ Image
+ *mask_image;
+
+ ImageInfo
+ *image_info;
+
+ /*
+ Read image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ (void) CloneString(&image_info->size,size);
+ FormatString(image_info->size,"%lux%lu",composite_image->columns,
+ composite_image->rows);
+ mask_image=ReadImage(image_info,&image->exception);
+ if (image->exception.severity != UndefinedException)
+ MagickError2(image->exception.severity,image->exception.reason,
+ image->exception.description);
+ MagickXSetCursorState(display,windows,False);
+ if (mask_image == (Image *) NULL)
+ return(False);
+ (void) CompositeImage(composite_image,CopyOpacityCompositeOp,
+ mask_image,0,0);
+ DestroyImage(mask_image);
+ DestroyImageInfo(image_info);
+ }
+ }
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"Composite");
+ windows->command.data=1;
+ (void) MagickXCommandWidget(display,windows,CompositeMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Track pointer until button 1 is pressed.
+ */
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ composite_info.x=windows->image.x+x;
+ composite_info.y=windows->image.y+y;
+ composite_info.width=0;
+ composite_info.height=0;
+ cursor=XCreateFontCursor(display,XC_ul_angle);
+ (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
+ blend=0.0;
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+ld%+ld ",composite_info.x,composite_info.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ highlight_info=composite_info;
+ highlight_info.x=composite_info.x-windows->image.x;
+ highlight_info.y=composite_info.y-windows->image.y;
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,CompositeMenu,&event);
+ if (id < 0)
+ continue;
+ switch (CompositeCommands[id])
+ {
+ case CompositeOperatorsCommand:
+ {
+ char
+ command[MaxTextExtent];
+
+ static const char
+ *OperatorMenu[]=
+ {
+ "Over",
+ "In",
+ "Out",
+ "Atop",
+ "Xor",
+ "Plus",
+ "Minus",
+ "Add",
+ "Subtract",
+ "Difference",
+ "Multiply",
+ "Bumpmap",
+ "Copy",
+ "CopyRed",
+ "CopyGreen",
+ "CopyBlue",
+ "CopyOpacity",
+ "Clear",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ compose=(CompositeOperator) (MagickXMenuWidget(display,windows,
+ CompositeMenu[id],OperatorMenu,command)+1);
+ break;
+ }
+ case CompositeDissolveCommand:
+ {
+ static char
+ factor[MaxTextExtent] = "20.0";
+
+ /*
+ Dissolve the two images a given percent.
+ */
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ (void) MagickXDialogWidget(display,windows,"Dissolve",
+ "Enter the blend factor (0.0 - 99.9%):",factor);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ if (*factor == '\0')
+ break;
+ blend=MagickAtoF(factor);
+ compose=DissolveCompositeOp;
+ break;
+ }
+ case CompositeDisplaceCommand:
+ {
+ /*
+ Get horizontal and vertical scale displacement geometry.
+ */
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ (void) MagickXDialogWidget(display,windows,"Displace",
+ "Enter the horizontal and vertical scale:",displacement_geometry);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ if (*displacement_geometry == '\0')
+ break;
+ compose=DisplaceCompositeOp;
+ break;
+ }
+ case CompositeHelpCommand:
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Composite",ImageCompositeHelp);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ break;
+ }
+ case CompositeDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
+ event.xbutton.button,event.xbutton.x,event.xbutton.y);
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ Change cursor.
+ */
+ composite_info.width=composite_image->columns;
+ composite_info.height=composite_image->rows;
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ composite_info.x=windows->image.x+event.xbutton.x;
+ composite_info.y=windows->image.y+event.xbutton.y;
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
+ event.xbutton.button,event.xbutton.x,event.xbutton.y);
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ if ((composite_info.width != 0) && (composite_info.height != 0))
+ {
+ /*
+ User has selected the location of the composite image.
+ */
+ composite_info.x=windows->image.x+event.xbutton.x;
+ composite_info.y=windows->image.y+event.xbutton.y;
+ state|=ExitState;
+ }
+ break;
+ }
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ char
+ command[MaxTextExtent];
+
+ KeySym
+ key_symbol;
+
+ int
+ length;
+
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Key press: 0x%lx (%.1024s)",key_symbol,command);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ DestroyImage(composite_image);
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Composite",ImageCompositeHelp);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ composite_info.x=windows->image.x+x;
+ composite_info.y=windows->image.y+y;
+ break;
+ }
+ default:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d",
+ event.type);
+ break;
+ }
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ MagickXSetCursorState(display,windows,False);
+ (void) XFreeCursor(display,cursor);
+ if (state & EscapeState)
+ return(True);
+ /*
+ Image compositing is relative to image configuration.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ scale_factor=(double) width/windows->image.ximage->width;
+ composite_info.x+=x;
+ composite_info.x=(int) (scale_factor*composite_info.x+0.5);
+ composite_info.width=(unsigned int) (scale_factor*composite_info.width+0.5);
+ scale_factor=(double) height/windows->image.ximage->height;
+ composite_info.y+=y;
+ composite_info.y=(int) (scale_factor*composite_info.y+0.5);
+ composite_info.height=(unsigned int) (scale_factor*composite_info.height+0.5);
+ if ((composite_info.width != composite_image->columns) ||
+ (composite_info.height != composite_image->rows))
+ {
+ Image
+ *resize_image;
+
+ /*
+ Scale composite image.
+ */
+ resize_image=ZoomImage(composite_image,composite_info.width,
+ composite_info.height,&image->exception);
+ DestroyImage(composite_image);
+ if (resize_image == (Image *) NULL)
+ {
+ MagickXSetCursorState(display,windows,False);
+ return(False);
+ }
+ composite_image=resize_image;
+ }
+ if (compose == DisplaceCompositeOp)
+ composite_image->geometry=displacement_geometry;
+ if (blend != 0.0)
+ {
+ int
+ y;
+
+ Quantum
+ opacity;
+
+ register int
+ x;
+
+ register PixelPacket
+ *q;
+
+ /*
+ Create mattes for blending.
+ */
+ SetImageOpacity(composite_image,OpaqueOpacity);
+ opacity=(Quantum) (ScaleQuantumToChar(MaxRGB)-
+ ((long) ScaleQuantumToChar(MaxRGB)*blend)/100);
+ (void) SetImageType(image,TrueColorMatteType);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (int) image->columns; x++)
+ {
+ q->opacity=opacity;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ }
+ /*
+ Composite image with X Image window.
+ */
+ (void) CompositeImage(image,compose,composite_image,composite_info.x,
+ composite_info.y);
+ DestroyImage(composite_image);
+ MagickXSetCursorState(display,windows,False);
+ /*
+ Update image configuration.
+ */
+ MagickXConfigureImageColormap(display,resource_info,windows,image);
+ (void) MagickXConfigureImage(display,resource_info,windows,image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X C o n f i g u r e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXConfigureImage creates a new X image. It also notifies the
+% window manager of the new image size and configures the transient widows.
+%
+% The format of the MagickXConfigureImage method is:
+%
+% unsigned int MagickXConfigureImage(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXConfigureImage returns True if the window is
+% resized. False is returned is there is a memory shortage or if the
+% window fails to resize.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int MagickXConfigureImage(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows,Image *image)
+{
+ char
+ geometry[MaxTextExtent];
+
+ long
+ x,
+ y;
+
+ unsigned int
+ mask,
+ status;
+
+ unsigned long
+ height,
+ width;
+
+ XSizeHints
+ *size_hints;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Dismiss if window dimensions are zero.
+ */
+ width=windows->image.window_changes.width;
+ height=windows->image.window_changes.height;
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Configure Image: %dx%d=>%lux%lu",windows->image.ximage->width,
+ windows->image.ximage->height,width,height);
+ if ((width*height) == 0)
+ return(True);
+ x=0;
+ y=0;
+ /*
+ Display hourglass cursor if progress indication enabled.
+ */
+ if (resource_info->image_info->progress)
+ MagickXSetCursorState(display,windows,True);
+ /*
+ Resize image to fit Image window dimensions.
+ */
+ (void) XFlush(display);
+ if (((int) width != windows->image.ximage->width) ||
+ ((int) height != windows->image.ximage->height))
+ image->taint=True;
+ windows->magnify.x=(unsigned int)
+ width*windows->magnify.x/windows->image.ximage->width;
+ windows->magnify.y=(unsigned int)
+ height*windows->magnify.y/windows->image.ximage->height;
+ windows->image.x=(int) (width*windows->image.x/windows->image.ximage->width);
+ windows->image.y=(int)
+ (height*windows->image.y/windows->image.ximage->height);
+ status=MagickXMakeImage(display,resource_info,&windows->image,image,
+ (unsigned int) width,(unsigned int) height);
+ if (status == False)
+ MagickXNoticeWidget(display,windows,"Unable to configure X image:",
+ windows->image.name);
+ /*
+ Notify window manager of the new configuration.
+ */
+ FormatString(geometry,"%ux%u+0+0>!",
+ XDisplayWidth(display,windows->image.screen),
+ XDisplayHeight(display,windows->image.screen));
+ (void) GetMagickGeometry(geometry,&x,&y,&width,&height);
+ window_changes.width=(unsigned int) width;
+ window_changes.height=(unsigned int) height;
+ mask=CWWidth | CWHeight;
+ if (resource_info->backdrop)
+ {
+ mask|=CWX | CWY;
+ window_changes.x=(int)
+ ((XDisplayWidth(display,windows->image.screen)/2)-(width/2));
+ window_changes.y=(int)
+ ((XDisplayHeight(display,windows->image.screen)/2)-(height/2));
+ }
+ (void) XReconfigureWMWindow(display,windows->image.id,windows->image.screen,
+ mask,&window_changes);
+ (void) XClearWindow(display,windows->image.id);
+ MagickXRefreshWindow(display,&windows->image,(XEvent *) NULL);
+ /*
+ Update Magnify window configuration.
+ */
+ if (windows->magnify.mapped)
+ MagickXMakeMagnifyImage(display,windows);
+ /*
+ Update pan window configuration.
+ */
+ windows->pan.crop_geometry=windows->image.crop_geometry;
+ MagickXBestIconSize(display,&windows->pan,image);
+ while ((windows->pan.width < MaxIconSize) &&
+ (windows->pan.height < MaxIconSize))
+ {
+ windows->pan.width<<=1;
+ windows->pan.height<<=1;
+ }
+ if (windows->pan.geometry != (char *) NULL)
+ (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
+ &windows->pan.width,&windows->pan.height);
+ window_changes.width=windows->pan.width;
+ window_changes.height=windows->pan.height;
+ size_hints=XAllocSizeHints();
+ if (size_hints != (XSizeHints *) NULL)
+ {
+ /*
+ Set new size hints.
+ */
+ size_hints->flags=PSize | PMinSize | PMaxSize;
+ size_hints->width=window_changes.width;
+ size_hints->height=window_changes.height;
+ size_hints->min_width=size_hints->width;
+ size_hints->min_height=size_hints->height;
+ size_hints->max_width=size_hints->width;
+ size_hints->max_height=size_hints->height;
+ (void) XSetNormalHints(display,windows->pan.id,size_hints);
+ (void) XFree((void *) size_hints);
+ }
+ (void) XReconfigureWMWindow(display,windows->pan.id,windows->pan.screen,
+ CWWidth | CWHeight,&window_changes);
+ if (windows->pan.mapped)
+ MagickXMakePanImage(display,resource_info,windows,image);
+ /*
+ Update icon window configuration.
+ */
+ windows->icon.crop_geometry=windows->image.crop_geometry;
+ MagickXBestIconSize(display,&windows->icon,image);
+ window_changes.width=windows->icon.width;
+ window_changes.height=windows->icon.height;
+ (void) XReconfigureWMWindow(display,windows->icon.id,windows->icon.screen,
+ CWWidth | CWHeight,&window_changes);
+ MagickXSetCursorState(display,windows,False);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X C r o p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXCropImage allows the user to select a region of the image and
+% crop, copy, or cut it. For copy or cut, the image can subsequently be
+% composited onto the image with MagickXPasteImage.
+%
+% The format of the MagickXCropImage method is:
+%
+% unsigned int MagickXCropImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image *image,const ClipboardMode mode)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXCropImage returns True if the image is
+% copied. False is returned is there is a memory shortage or if the
+% image fails to be copied.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o mode: This unsigned value specified whether the image should be
+% cropped, copied, or cut.
+%
+%
+*/
+static unsigned int MagickXCropImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *image,const ClipboardMode mode)
+{
+ static const char
+ *CropModeMenu[]=
+ {
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ },
+ *RectifyModeMenu[]=
+ {
+ "Crop",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ };
+
+ static const ModeType
+ CropCommands[]=
+ {
+ CropHelpCommand,
+ CropDismissCommand
+ },
+ RectifyCommands[]=
+ {
+ RectifyCopyCommand,
+ RectifyHelpCommand,
+ RectifyDismissCommand
+ };
+
+ char
+ command[MaxTextExtent],
+ text[MaxTextExtent];
+
+ Cursor
+ cursor;
+
+ double
+ scale_factor;
+
+ int
+ id,
+ x,
+ y;
+
+ KeySym
+ key_symbol;
+
+ Image
+ *crop_image;
+
+ RectangleInfo
+ crop_info,
+ highlight_info;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ height,
+ width;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ /*
+ Map Command widget.
+ */
+ switch (mode)
+ {
+ case CopyMode:
+ {
+ (void) CloneString(&windows->command.name,"Copy");
+ break;
+ }
+ case CropMode:
+ {
+ (void) CloneString(&windows->command.name,"Crop");
+ break;
+ }
+ case CutMode:
+ {
+ (void) CloneString(&windows->command.name,"Cut");
+ break;
+ }
+ }
+ RectifyModeMenu[0]=windows->command.name;
+ windows->command.data=0;
+ (void) MagickXCommandWidget(display,windows,CropModeMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Track pointer until button 1 is pressed.
+ */
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ crop_info.x=windows->image.x+x;
+ crop_info.y=windows->image.y+y;
+ crop_info.width=0;
+ crop_info.height=0;
+ cursor=XCreateFontCursor(display,XC_fleur);
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+ld%+ld ",crop_info.x,crop_info.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,CropModeMenu,&event);
+ if (id < 0)
+ continue;
+ switch (CropCommands[id])
+ {
+ case CropHelpCommand:
+ {
+ switch (mode)
+ {
+ case CopyMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Copy",ImageCopyHelp);
+ break;
+ }
+ case CropMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Crop",ImageCropHelp);
+ break;
+ }
+ case CutMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Cut",ImageCutHelp);
+ break;
+ }
+ }
+ break;
+ }
+ case CropDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ Note first corner of cropping rectangle-- exit loop.
+ */
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ crop_info.x=windows->image.x+event.xbutton.x;
+ crop_info.y=windows->image.y+event.xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case ButtonRelease:
+ break;
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ switch (mode)
+ {
+ case CopyMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Copy",ImageCopyHelp);
+ break;
+ }
+ case CropMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Crop",ImageCropHelp);
+ break;
+ }
+ case CutMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Cut",ImageCutHelp);
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ crop_info.x=windows->image.x+x;
+ crop_info.y=windows->image.y+y;
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ if (state & EscapeState)
+ {
+ /*
+ User want to exit without cropping.
+ */
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ (void) XFreeCursor(display,cursor);
+ return(True);
+ }
+ (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
+ do
+ {
+ /*
+ Size rectangle as pointer moves until the mouse button is released.
+ */
+ x=(int) crop_info.x;
+ y=(int) crop_info.y;
+ crop_info.width=0;
+ crop_info.height=0;
+ state=DefaultState;
+ do
+ {
+ highlight_info=crop_info;
+ highlight_info.x=crop_info.x-windows->image.x;
+ highlight_info.y=crop_info.y-windows->image.y;
+ if ((highlight_info.width > 3) && (highlight_info.height > 3))
+ {
+ /*
+ Display info and draw cropping rectangle.
+ */
+ if (!windows->info.mapped)
+ (void) XMapWindow(display,windows->info.id);
+ FormatString(text," %lux%lu%+ld%+ld",crop_info.width,crop_info.height,
+ crop_info.x,crop_info.y);
+ MagickXInfoWidget(display,windows,text);
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ }
+ else
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if ((highlight_info.width > 3) && (highlight_info.height > 3))
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ crop_info.x=windows->image.x+event.xbutton.x;
+ crop_info.y=windows->image.y+event.xbutton.y;
+ break;
+ }
+ case ButtonRelease:
+ {
+ /*
+ User has committed to cropping rectangle.
+ */
+ crop_info.x=windows->image.x+event.xbutton.x;
+ crop_info.y=windows->image.y+event.xbutton.y;
+ MagickXSetCursorState(display,windows,False);
+ state|=ExitState;
+ if (LocaleCompare(windows->command.name,"Rectify") == 0)
+ break;
+ (void) CloneString(&windows->command.name,"Rectify");
+ windows->command.data=0;
+ (void) MagickXCommandWidget(display,windows,RectifyModeMenu,
+ (XEvent *) NULL);
+ break;
+ }
+ case Expose:
+ break;
+ case MotionNotify:
+ {
+ crop_info.x=windows->image.x+event.xmotion.x;
+ crop_info.y=windows->image.y+event.xmotion.y;
+ }
+ default:
+ break;
+ }
+ if ((((int) crop_info.x != x) && ((int) crop_info.y != y)) ||
+ (state & ExitState))
+ {
+ /*
+ Check boundary conditions.
+ */
+ if (crop_info.x < 0)
+ crop_info.x=0;
+ else
+ if (crop_info.x > (int) windows->image.ximage->width)
+ crop_info.x=windows->image.ximage->width;
+ if ((int) crop_info.x < x)
+ crop_info.width=(unsigned int) (x-crop_info.x);
+ else
+ {
+ crop_info.width=(unsigned int) (crop_info.x-x);
+ crop_info.x=x;
+ }
+ if (crop_info.y < 0)
+ crop_info.y=0;
+ else
+ if (crop_info.y > (int) windows->image.ximage->height)
+ crop_info.y=windows->image.ximage->height;
+ if ((int) crop_info.y < y)
+ crop_info.height=(unsigned int) (y-crop_info.y);
+ else
+ {
+ crop_info.height=(unsigned int) (crop_info.y-y);
+ crop_info.y=y;
+ }
+ }
+ } while (!(state & ExitState));
+ /*
+ Wait for user to grab a corner of the rectangle or press return.
+ */
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %lux%lu%+ld%+ld",crop_info.width,crop_info.height,
+ crop_info.x,crop_info.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ highlight_info=crop_info;
+ highlight_info.x=crop_info.x-windows->image.x;
+ highlight_info.y=crop_info.y-windows->image.y;
+ if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
+ {
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ id=MagickXCommandWidget(display,windows,RectifyModeMenu,&event);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ if (id >= 0)
+ switch (RectifyCommands[id])
+ {
+ case RectifyCopyCommand:
+ {
+ state|=ExitState;
+ break;
+ }
+ case RectifyHelpCommand:
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ switch (mode)
+ {
+ case CopyMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Copy",ImageCopyHelp);
+ break;
+ }
+ case CropMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Crop",ImageCropHelp);
+ break;
+ }
+ case CutMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Cut",ImageCutHelp);
+ break;
+ }
+ }
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ break;
+ }
+ case RectifyDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ continue;
+ }
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ x=windows->image.x+event.xbutton.x;
+ y=windows->image.y+event.xbutton.y;
+ if ((x < (int) (crop_info.x+RoiDelta)) &&
+ (x > (int) (crop_info.x-RoiDelta)) &&
+ (y < (int) (crop_info.y+RoiDelta)) &&
+ (y > (int) (crop_info.y-RoiDelta)))
+ {
+ crop_info.x=(long) (crop_info.x+crop_info.width);
+ crop_info.y=(long) (crop_info.y+crop_info.height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ if ((x < (int) (crop_info.x+RoiDelta)) &&
+ (x > (int) (crop_info.x-RoiDelta)) &&
+ (y < (int) (crop_info.y+crop_info.height+RoiDelta)) &&
+ (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
+ {
+ crop_info.x=(long) (crop_info.x+crop_info.width);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ if ((x < (int) (crop_info.x+crop_info.width+RoiDelta)) &&
+ (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
+ (y < (int) (crop_info.y+RoiDelta)) &&
+ (y > (int) (crop_info.y-RoiDelta)))
+ {
+ crop_info.y=(long) (crop_info.y+crop_info.height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ if ((x < (int) (crop_info.x+crop_info.width+RoiDelta)) &&
+ (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
+ (y < (int) (crop_info.y+crop_info.height+RoiDelta)) &&
+ (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
+ {
+ state|=UpdateConfigurationState;
+ break;
+ }
+ }
+ case ButtonRelease:
+ {
+ if (event.xbutton.window == windows->pan.id)
+ if ((highlight_info.x != crop_info.x-windows->image.x) ||
+ (highlight_info.y != crop_info.y-windows->image.y))
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window == windows->image.id)
+ if (event.xexpose.count == 0)
+ {
+ event.xexpose.x=(int) highlight_info.x;
+ event.xexpose.y=(int) highlight_info.y;
+ event.xexpose.width=(unsigned int) highlight_info.width;
+ event.xexpose.height=(unsigned int) highlight_info.height;
+ MagickXRefreshWindow(display,&windows->image,&event);
+ }
+ if (event.xexpose.window == windows->info.id)
+ if (event.xexpose.count == 0)
+ MagickXInfoWidget(display,windows,text);
+ break;
+ }
+ case KeyPress:
+ {
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,
+ sizeof(command),&key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ state|=EscapeState;
+ break;
+ }
+ case XK_Return:
+ {
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ switch (mode)
+ {
+ case CopyMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Copy",ImageCopyHelp);
+ break;
+ }
+ case CropMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Cropg",ImageCropHelp);
+ break;
+ }
+ case CutMode:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Cutg",ImageCutHelp);
+ break;
+ }
+ }
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case KeyRelease:
+ break;
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ break;
+ }
+ default:
+ break;
+ }
+ if (state & UpdateConfigurationState)
+ {
+ (void) XPutBackEvent(display,&event);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ break;
+ }
+ } while (!(state & ExitState));
+ } while (!(state & ExitState));
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ MagickXSetCursorState(display,windows,False);
+ if (state & EscapeState)
+ return(True);
+ if (mode == CropMode)
+ if (((int) crop_info.width != windows->image.ximage->width) ||
+ ((int) crop_info.height != windows->image.ximage->height))
+ {
+ /*
+ Reconfigure Image window as defined by cropping rectangle.
+ */
+ MagickXSetCropGeometry(display,windows,&crop_info,image);
+ windows->image.window_changes.width=(unsigned int) crop_info.width;
+ windows->image.window_changes.height=(unsigned int) crop_info.height;
+ (void) MagickXConfigureImage(display,resource_info,windows,image);
+ return(True);
+ }
+ /*
+ Copy image before applying image transforms.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ scale_factor=(double) width/windows->image.ximage->width;
+ crop_info.x+=x;
+ crop_info.x=(int) (scale_factor*crop_info.x+0.5);
+ crop_info.width=(unsigned int) (scale_factor*crop_info.width+0.5);
+ scale_factor=(double) height/windows->image.ximage->height;
+ crop_info.y+=y;
+ crop_info.y=(int) (scale_factor*crop_info.y+0.5);
+ crop_info.height=(unsigned int) (scale_factor*crop_info.height+0.5);
+ crop_image=CropImage(image,&crop_info,&image->exception);
+ MagickXSetCursorState(display,windows,False);
+ if (crop_image == (Image *) NULL)
+ return(False);
+ if (resource_info->copy_image != (Image *) NULL)
+ DestroyImage(resource_info->copy_image);
+ resource_info->copy_image=crop_image;
+ if (mode == CopyMode)
+ {
+ (void) MagickXConfigureImage(display,resource_info,windows,image);
+ return(True);
+ }
+ /*
+ Cut image.
+ */
+ (void) SetImageType(image,TrueColorMatteType);
+ for (y=0; y < (long) crop_info.height; y++)
+ {
+ q=GetImagePixels(image,crop_info.x,y+crop_info.y,crop_info.width,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (int) crop_info.width; x++)
+ {
+ q->opacity=TransparentOpacity;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ /*
+ Update image configuration.
+ */
+ MagickXConfigureImageColormap(display,resource_info,windows,image);
+ (void) MagickXConfigureImage(display,resource_info,windows,image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X D r a w I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXDrawEditImage draws a graphic element (point, line, rectangle,
+% etc.) on the image.
+%
+% The format of the MagickXDrawEditImage method is:
+%
+% unsigned int MagickXDrawEditImage(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,Image **image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXDrawEditImage return True if the image is drawn
+% upon. False is returned is there is a memory shortage or if the
+% image cannot be drawn on.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int MagickXDrawEditImage(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows,Image **image)
+{
+ static const char
+ *DrawMenu[]=
+ {
+ "Element",
+ "Color",
+ "Stipple",
+ "Width",
+ "Undo",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ };
+
+ static ElementType
+ element = PointElement;
+
+ static const ModeType
+ DrawCommands[]=
+ {
+ DrawElementCommand,
+ DrawColorCommand,
+ DrawStippleCommand,
+ DrawWidthCommand,
+ DrawUndoCommand,
+ DrawHelpCommand,
+ DrawDismissCommand
+ };
+
+ static Pixmap
+ stipple = (Pixmap) NULL;
+
+ static unsigned int
+ pen_id = 0,
+ line_width = 1;
+
+ char
+ command[MaxTextExtent],
+ text[MaxTextExtent];
+
+ Cursor
+ cursor;
+
+ double
+ degrees;
+
+ int
+ entry,
+ id,
+ number_coordinates,
+ x,
+ y;
+
+ RectangleInfo
+ rectangle_info;
+
+ register int
+ i;
+
+ unsigned int
+ distance,
+ height,
+ max_coordinates,
+ status,
+ width;
+
+ unsigned long
+ state;
+
+ Window
+ root_window;
+
+ MagickXDrawInfo
+ draw_info;
+
+ XEvent
+ event;
+
+ XPoint
+ *coordinate_info;
+
+ XSegment
+ line_info;
+
+ /*
+ Allocate polygon info.
+ */
+ max_coordinates=2048;
+ coordinate_info=MagickAllocateMemory(XPoint *,max_coordinates*sizeof(XPoint));
+ if (coordinate_info == (XPoint *) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage);
+ return(False);
+ }
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"Draw");
+ windows->command.data=4;
+ (void) MagickXCommandWidget(display,windows,DrawMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Wait for first button press.
+ */
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ draw_info.stencil=OpaqueStencil;
+ status=True;
+ cursor=XCreateFontCursor(display,XC_tcross);
+ for ( ; ; )
+ {
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+d%+d ",x+windows->image.x,y+windows->image.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,DrawMenu,&event);
+ if (id < 0)
+ continue;
+ switch (DrawCommands[id])
+ {
+ case DrawElementCommand:
+ {
+ static const char
+ *Elements[]=
+ {
+ "point",
+ "line",
+ "rectangle",
+ "fill rectangle",
+ "circle",
+ "fill circle",
+ "ellipse",
+ "fill ellipse",
+ "polygon",
+ "fill polygon",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ element=(ElementType) (MagickXMenuWidget(display,windows,
+ DrawMenu[id],Elements,command)+1);
+ break;
+ }
+ case DrawColorCommand:
+ {
+ char
+ *ColorMenu[MaxNumberPens+1];
+
+ int
+ pen_number;
+
+ unsigned int
+ transparent;
+
+ XColor
+ color;
+
+ /*
+ Initialize menu selections.
+ */
+ for (i=0; i < (int) (MaxNumberPens-2); i++)
+ ColorMenu[i]=resource_info->pen_colors[i];
+ ColorMenu[MaxNumberPens-2]=(char *) "transparent";
+ ColorMenu[MaxNumberPens-1]=(char *) "Browser...";
+ ColorMenu[MaxNumberPens]=(char *) NULL;
+ /*
+ Select a pen color from the pop-up menu.
+ */
+ pen_number=MagickXMenuWidget(display,windows,DrawMenu[id],
+ (const char **) ColorMenu,command);
+ if (pen_number < 0)
+ break;
+ transparent=pen_number == (MaxNumberPens-2);
+ if (transparent)
+ {
+ draw_info.stencil=TransparentStencil;
+ break;
+ }
+ if (pen_number == (MaxNumberPens-1))
+ {
+ static char
+ color_name[MaxTextExtent] = "gray";
+
+ /*
+ Select a pen color from a dialog.
+ */
+ resource_info->pen_colors[pen_number]=color_name;
+ MagickXColorBrowserWidget(display,windows,"Select",color_name);
+ if (*color_name == '\0')
+ break;
+ }
+ /*
+ Set pen color.
+ */
+ (void) XParseColor(display,windows->map_info->colormap,
+ resource_info->pen_colors[pen_number],&color);
+ MagickXBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
+ (unsigned int) MaxColors,&color);
+ windows->pixel_info->pen_colors[pen_number]=color;
+ pen_id=pen_number;
+ draw_info.stencil=OpaqueStencil;
+ break;
+ }
+ case DrawStippleCommand:
+ {
+ Image
+ *stipple_image;
+
+ ImageInfo
+ *image_info;
+
+ static char
+ filename[MaxTextExtent] = "\0";
+
+ static const char
+ *StipplesMenu[]=
+ {
+ "Brick",
+ "Diagonal",
+ "Scales",
+ "Vertical",
+ "Wavy",
+ "Translucent",
+ "Opaque",
+ (char *) NULL,
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ StipplesMenu[7]=(char *) "Open...";
+ entry=MagickXMenuWidget(display,windows,DrawMenu[id],StipplesMenu,
+ command);
+ if (entry < 0)
+ break;
+ if (stipple != (Pixmap) NULL)
+ (void) XFreePixmap(display,stipple);
+ stipple=(Pixmap) NULL;
+ if (entry == 6)
+ break;
+ if (entry != 7)
+ {
+ switch (entry)
+ {
+ case 0:
+ {
+ stipple=XCreateBitmapFromData(display,root_window,
+ (char *) BricksBitmap,BricksWidth,BricksHeight);
+ break;
+ }
+ case 1:
+ {
+ stipple=XCreateBitmapFromData(display,root_window,
+ (char *) DiagonalBitmap,DiagonalWidth,DiagonalHeight);
+ break;
+ }
+ case 2:
+ {
+ stipple=XCreateBitmapFromData(display,root_window,
+ (char *) ScalesBitmap,ScalesWidth,ScalesHeight);
+ break;
+ }
+ case 3:
+ {
+ stipple=XCreateBitmapFromData(display,root_window,
+ (char *) VerticalBitmap,VerticalWidth,VerticalHeight);
+ break;
+ }
+ case 4:
+ {
+ stipple=XCreateBitmapFromData(display,root_window,
+ (char *) WavyBitmap,WavyWidth,WavyHeight);
+ break;
+ }
+ case 5:
+ default:
+ {
+ stipple=XCreateBitmapFromData(display,root_window,
+ (char *) HighlightBitmap,HighlightWidth,
+ HighlightHeight);
+ break;
+ }
+ }
+ break;
+ }
+ MagickXFileBrowserWidget(display,windows,"Stipple",filename);
+ if (*filename == '\0')
+ break;
+ /*
+ Read image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ stipple_image=ReadImage(image_info,&(*image)->exception);
+ if ((*image)->exception.severity != UndefinedException)
+ MagickError2((*image)->exception.severity,
+ (*image)->exception.reason,(*image)->exception.description);
+ MagickXSetCursorState(display,windows,False);
+ if (stipple_image == (Image *) NULL)
+ break;
+ if (!AcquireTemporaryFileName(filename))
+ {
+ MagickXNoticeWidget(display,windows,
+ "Unable to open temporary file:",filename);
+ break;
+ }
+ FormatString(stipple_image->filename,"xbm:%.1024s",filename);
+ (void) WriteImage(image_info,stipple_image);
+ DestroyImage(stipple_image);
+ DestroyImageInfo(image_info);
+ status=XReadBitmapFile(display,root_window,filename,&width,
+ &height,&stipple,&x,&y);
+ (void) LiberateTemporaryFile(filename);
+ if (status != BitmapSuccess)
+ MagickXNoticeWidget(display,windows,"Unable to read X bitmap image:",
+ filename);
+ break;
+ }
+ case DrawWidthCommand:
+ {
+ static char
+ width[MaxTextExtent] = "0";
+
+ static const char
+ *WidthsMenu[]=
+ {
+ "1",
+ "2",
+ "4",
+ "8",
+ "16",
+ "Dialog...",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ entry=MagickXMenuWidget(display,windows,DrawMenu[id],WidthsMenu,
+ command);
+ if (entry < 0)
+ break;
+ if (entry != 5)
+ {
+ line_width=MagickAtoI(WidthsMenu[entry]);
+ break;
+ }
+ (void) MagickXDialogWidget(display,windows,"Ok","Enter line width:",
+ width);
+ if (*width == '\0')
+ break;
+ line_width=MagickAtoI(width);
+ break;
+ }
+ case DrawUndoCommand:
+ {
+ (void) MagickXMagickCommand(display,resource_info,windows,UndoCommand,
+ image);
+ break;
+ }
+ case DrawHelpCommand:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Rotation",ImageDrawHelp);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ break;
+ }
+ case DrawDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ Exit loop.
+ */
+ x=event.xbutton.x;
+ y=event.xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case ButtonRelease:
+ break;
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,
+ sizeof(command),&key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Rotation",ImageDrawHelp);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ break;
+ }
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (state & EscapeState)
+ break;
+ /*
+ Draw element as pointer moves until the button is released.
+ */
+ distance=0;
+ degrees=0.0;
+ line_info.x1=x;
+ line_info.y1=y;
+ line_info.x2=x;
+ line_info.y2=y;
+ rectangle_info.x=x;
+ rectangle_info.y=y;
+ rectangle_info.width=0;
+ rectangle_info.height=0;
+ number_coordinates=1;
+ coordinate_info->x=x;
+ coordinate_info->y=y;
+ (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
+ state=DefaultState;
+ do
+ {
+ switch (element)
+ {
+ case PointElement:
+ default:
+ {
+ if (number_coordinates > 1)
+ {
+ (void) XDrawLines(display,windows->image.id,
+ windows->image.highlight_context,coordinate_info,
+ number_coordinates,CoordModeOrigin);
+ FormatString(text," %+d%+d",
+ coordinate_info[number_coordinates-1].x,
+ coordinate_info[number_coordinates-1].y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ break;
+ }
+ case LineElement:
+ {
+ if (distance > 9)
+ {
+ /*
+ Display angle of the line.
+ */
+ degrees=RadiansToDegrees(-atan2((double) (line_info.y2-
+ line_info.y1),(double) (line_info.x2-line_info.x1)));
+ FormatString(text," %.2f",degrees);
+ MagickXInfoWidget(display,windows,text);
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&line_info);
+ }
+ else
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ break;
+ }
+ case RectangleElement:
+ case FillRectangleElement:
+ {
+ if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
+ {
+ /*
+ Display info and draw drawing rectangle.
+ */
+ FormatString(text," %lux%lu%+ld%+ld",rectangle_info.width,
+ rectangle_info.height,rectangle_info.x,rectangle_info.y);
+ MagickXInfoWidget(display,windows,text);
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&rectangle_info);
+ }
+ else
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ break;
+ }
+ case CircleElement:
+ case FillCircleElement:
+ case EllipseElement:
+ case FillEllipseElement:
+ {
+ if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
+ {
+ /*
+ Display info and draw drawing rectangle.
+ */
+ FormatString(text," %lux%lu%+ld%+ld",rectangle_info.width,
+ rectangle_info.height,rectangle_info.x,rectangle_info.y);
+ MagickXInfoWidget(display,windows,text);
+ MagickXHighlightEllipse(display,windows->image.id,
+ windows->image.highlight_context,&rectangle_info);
+ }
+ else
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ break;
+ }
+ case PolygonElement:
+ case FillPolygonElement:
+ {
+ if (number_coordinates > 1)
+ (void) XDrawLines(display,windows->image.id,
+ windows->image.highlight_context,coordinate_info,
+ number_coordinates,CoordModeOrigin);
+ if (distance > 9)
+ {
+ /*
+ Display angle of the line.
+ */
+ degrees=RadiansToDegrees(-atan2((double) (line_info.y2-
+ line_info.y1),(double) (line_info.x2-line_info.x1)));
+ FormatString(text," %.2f",degrees);
+ MagickXInfoWidget(display,windows,text);
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&line_info);
+ }
+ else
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ break;
+ }
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ switch (element)
+ {
+ case PointElement:
+ default:
+ {
+ if (number_coordinates > 1)
+ (void) XDrawLines(display,windows->image.id,
+ windows->image.highlight_context,coordinate_info,
+ number_coordinates,CoordModeOrigin);
+ break;
+ }
+ case LineElement:
+ {
+ if (distance > 9)
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&line_info);
+ break;
+ }
+ case RectangleElement:
+ case FillRectangleElement:
+ {
+ if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&rectangle_info);
+ break;
+ }
+ case CircleElement:
+ case FillCircleElement:
+ case EllipseElement:
+ case FillEllipseElement:
+ {
+ if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
+ MagickXHighlightEllipse(display,windows->image.id,
+ windows->image.highlight_context,&rectangle_info);
+ break;
+ }
+ case PolygonElement:
+ case FillPolygonElement:
+ {
+ if (number_coordinates > 1)
+ (void) XDrawLines(display,windows->image.id,
+ windows->image.highlight_context,coordinate_info,
+ number_coordinates,CoordModeOrigin);
+ if (distance > 9)
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&line_info);
+ break;
+ }
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ break;
+ case ButtonRelease:
+ {
+ /*
+ User has committed to element.
+ */
+ line_info.x2=event.xbutton.x;
+ line_info.y2=event.xbutton.y;
+ rectangle_info.x=event.xbutton.x;
+ rectangle_info.y=event.xbutton.y;
+ coordinate_info[number_coordinates].x=event.xbutton.x;
+ coordinate_info[number_coordinates].y=event.xbutton.y;
+ if (((element != PolygonElement) &&
+ (element != FillPolygonElement)) || (distance <= 9))
+ {
+ state|=ExitState;
+ break;
+ }
+ number_coordinates++;
+ if (number_coordinates < (int) max_coordinates)
+ {
+ line_info.x1=event.xbutton.x;
+ line_info.y1=event.xbutton.y;
+ break;
+ }
+ max_coordinates<<=1;
+ MagickReallocMemory(XPoint *,coordinate_info,
+ max_coordinates*sizeof(XPoint));
+ if (coordinate_info == (XPoint *) NULL)
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage);
+ break;
+ }
+ case Expose:
+ break;
+ case MotionNotify:
+ {
+ if (event.xmotion.window != windows->image.id)
+ break;
+ if (element != PointElement)
+ {
+ line_info.x2=event.xmotion.x;
+ line_info.y2=event.xmotion.y;
+ rectangle_info.x=event.xmotion.x;
+ rectangle_info.y=event.xmotion.y;
+ break;
+ }
+ coordinate_info[number_coordinates].x=event.xbutton.x;
+ coordinate_info[number_coordinates].y=event.xbutton.y;
+ number_coordinates++;
+ if (number_coordinates < (int) max_coordinates)
+ break;
+ max_coordinates<<=1;
+ MagickReallocMemory(XPoint *,coordinate_info,
+ max_coordinates*sizeof(XPoint));
+ if (coordinate_info == (XPoint *) NULL)
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage);
+ break;
+ }
+ default:
+ break;
+ }
+ /*
+ Check boundary conditions.
+ */
+ if (line_info.x2 < 0)
+ line_info.x2=0;
+ else
+ if (line_info.x2 > (int) windows->image.width)
+ line_info.x2=windows->image.width;
+ if (line_info.y2 < 0)
+ line_info.y2=0;
+ else
+ if (line_info.y2 > (int) windows->image.height)
+ line_info.y2=windows->image.height;
+ distance=
+ ((line_info.x2-line_info.x1+1)*(line_info.x2-line_info.x1+1))+
+ ((line_info.y2-line_info.y1+1)*(line_info.y2-line_info.y1+1));
+ if ((((int) rectangle_info.x != x) && ((int) rectangle_info.y != y)) ||
+ (state & ExitState))
+ {
+ if (rectangle_info.x < 0)
+ rectangle_info.x=0;
+ else
+ if (rectangle_info.x > (int) windows->image.width)
+ rectangle_info.x=(long) windows->image.width;
+ if ((int) rectangle_info.x < x)
+ rectangle_info.width=(unsigned int) (x-rectangle_info.x);
+ else
+ {
+ rectangle_info.width=(unsigned int) (rectangle_info.x-x);
+ rectangle_info.x=x;
+ }
+ if (rectangle_info.y < 0)
+ rectangle_info.y=0;
+ else
+ if (rectangle_info.y > (int) windows->image.height)
+ rectangle_info.y=(long) windows->image.height;
+ if ((int) rectangle_info.y < y)
+ rectangle_info.height=(unsigned int) (y-rectangle_info.y);
+ else
+ {
+ rectangle_info.height=(unsigned int) (rectangle_info.y-y);
+ rectangle_info.y=y;
+ }
+ }
+ } while (!(state & ExitState));
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ if ((element == PointElement) || (element == PolygonElement) ||
+ (element == FillPolygonElement))
+ {
+ /*
+ Determine polygon bounding box.
+ */
+ rectangle_info.x=coordinate_info->x;
+ rectangle_info.y=coordinate_info->y;
+ x=coordinate_info->x;
+ y=coordinate_info->y;
+ for (i=1; i < number_coordinates; i++)
+ {
+ if (coordinate_info[i].x > x)
+ x=coordinate_info[i].x;
+ if (coordinate_info[i].y > y)
+ y=coordinate_info[i].y;
+ if (coordinate_info[i].x < rectangle_info.x)
+ rectangle_info.x=Max(coordinate_info[i].x,0);
+ if (coordinate_info[i].y < rectangle_info.y)
+ rectangle_info.y=Max(coordinate_info[i].y,0);
+ }
+ rectangle_info.width=x-rectangle_info.x;
+ rectangle_info.height=y-rectangle_info.y;
+ for (i=0; i < number_coordinates; i++)
+ {
+ coordinate_info[i].x-=rectangle_info.x;
+ coordinate_info[i].y-=rectangle_info.y;
+ }
+ }
+ else
+ if (distance <= 9)
+ continue;
+ else
+ if ((element == RectangleElement) ||
+ (element == CircleElement) || (element == EllipseElement))
+ {
+ rectangle_info.width--;
+ rectangle_info.height--;
+ }
+ /*
+ Drawing is relative to image configuration.
+ */
+ draw_info.x=(int) rectangle_info.x;
+ draw_info.y=(int) rectangle_info.y;
+ (void) MagickXMagickCommand(display,resource_info,windows,SaveToUndoBufferCommand,
+ image);
+ width=(unsigned int) (*image)->columns;
+ height=(unsigned int) (*image)->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ draw_info.x+=windows->image.x-(line_width/2);
+ if (draw_info.x < 0)
+ draw_info.x=0;
+ draw_info.x=width*draw_info.x/windows->image.ximage->width;
+ draw_info.y+=windows->image.y-(line_width/2);
+ if (draw_info.y < 0)
+ draw_info.y=0;
+ draw_info.y=height*draw_info.y/windows->image.ximage->height;
+ draw_info.width=(unsigned int) rectangle_info.width+(line_width << 1);
+ if (draw_info.width > (unsigned int) (*image)->columns)
+ draw_info.width=(unsigned int) (*image)->columns;
+ draw_info.height=(unsigned int) rectangle_info.height+(line_width << 1);
+ if (draw_info.height > (unsigned int) (*image)->rows)
+ draw_info.height=(unsigned int) (*image)->rows;
+ FormatString(draw_info.geometry,"%ux%u%+d%+d",
+ width*draw_info.width/windows->image.ximage->width,
+ height*draw_info.height/windows->image.ximage->height,
+ draw_info.x+x,draw_info.y+y);
+ /*
+ Initialize drawing attributes.
+ */
+ draw_info.degrees=0.0;
+ draw_info.element=element;
+ draw_info.stipple=stipple;
+ draw_info.line_width=line_width;
+ draw_info.line_info=line_info;
+ if (line_info.x1 > (int) (line_width/2))
+ draw_info.line_info.x1=line_width/2;
+ if (line_info.y1 > (int) (line_width/2))
+ draw_info.line_info.y1=line_width/2;
+ draw_info.line_info.x2=line_info.x2-line_info.x1+(line_width/2);
+ draw_info.line_info.y2=line_info.y2-line_info.y1+(line_width/2);
+ if ((draw_info.line_info.x2 < 0) && (draw_info.line_info.y2 < 0))
+ {
+ draw_info.line_info.x2=(-draw_info.line_info.x2);
+ draw_info.line_info.y2=(-draw_info.line_info.y2);
+ }
+ if (draw_info.line_info.x2 < 0)
+ {
+ draw_info.line_info.x2=(-draw_info.line_info.x2);
+ Swap(draw_info.line_info.x1,draw_info.line_info.x2);
+ }
+ if (draw_info.line_info.y2 < 0)
+ {
+ draw_info.line_info.y2=(-draw_info.line_info.y2);
+ Swap(draw_info.line_info.y1,draw_info.line_info.y2);
+ }
+ draw_info.rectangle_info=rectangle_info;
+ if (draw_info.rectangle_info.x > (int) (line_width/2))
+ draw_info.rectangle_info.x=(long) line_width/2;
+ if (draw_info.rectangle_info.y > (int) (line_width/2))
+ draw_info.rectangle_info.y=(long) line_width/2;
+ draw_info.number_coordinates=number_coordinates;
+ draw_info.coordinate_info=coordinate_info;
+ windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
+ /*
+ Draw element on image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ status=MagickXDrawImage(display,windows->pixel_info,&draw_info,*image);
+ MagickXSetCursorState(display,windows,False);
+ /*
+ Update image colormap and return to image drawing.
+ */
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ }
+ MagickXSetCursorState(display,windows,False);
+ MagickFreeMemory(coordinate_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X D r a w P a n R e c t a n g l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXDrawPanRectangle draws a rectangle in the pan window. The pan
+% window displays a zoom image and the rectangle shows which portion of
+% the image is displayed in the Image window.
+%
+% The format of the MagickXDrawPanRectangle method is:
+%
+% MagickXDrawPanRectangle(Display *display,MagickXWindows *windows)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+%
+*/
+static void MagickXDrawPanRectangle(Display *display,MagickXWindows *windows)
+{
+ double
+ scale_factor;
+
+ RectangleInfo
+ highlight_info;
+
+ /*
+ Determine dimensions of the panning rectangle.
+ */
+ scale_factor=(double) windows->pan.width/windows->image.ximage->width;
+ highlight_info.x=(int) (scale_factor*windows->image.x+0.5);
+ highlight_info.width=(unsigned int) (scale_factor*windows->image.width+0.5);
+ scale_factor=(double) windows->pan.height/windows->image.ximage->height;
+ highlight_info.y=(int) (scale_factor*windows->image.y+0.5);
+ highlight_info.height=(unsigned int) (scale_factor*windows->image.height+0.5);
+ /*
+ Display the panning rectangle.
+ */
+ (void) XClearWindow(display,windows->pan.id);
+ MagickXHighlightRectangle(display,windows->pan.id,windows->pan.annotate_context,
+ &highlight_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X I m a g e C a c h e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXImageCache handles the creation, manipulation, and destruction of
+% the image cache (undo and redo buffers).
+%
+% The format of the MagickXImageCache method is:
+%
+% void MagickXImageCache(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,const CommandType command,Image **image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o command: Specifies a command to perform.
+%
+% o image: Specifies a pointer to an Image structure; MagickXImageCache
+% may transform the image and return a new image pointer.
+%
+%
+*/
+static void MagickXImageCache(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,const CommandType command,Image **image)
+{
+ Image
+ *cache_image;
+
+ static Image
+ *redo_image = (Image *) NULL,
+ *undo_image = (Image *) NULL;
+
+ switch (command)
+ {
+ case FreeBuffersCommand:
+ {
+ /*
+ Free memory from the undo and redo cache.
+ */
+ while (undo_image != (Image *) NULL)
+ {
+ cache_image=undo_image;
+ undo_image=undo_image->previous;
+ DestroyImage(cache_image->list);
+ DestroyImage(cache_image);
+ }
+ undo_image=(Image *) NULL;
+ if (redo_image != (Image *) NULL)
+ DestroyImage(redo_image);
+ redo_image=(Image *) NULL;
+ return;
+ }
+ case UndoCommand:
+ {
+ /*
+ Undo the last image transformation.
+ */
+ if (undo_image == (Image *) NULL)
+ {
+ (void) XBell(display,0);
+ return;
+ }
+ cache_image=undo_image;
+ undo_image=undo_image->previous;
+ windows->image.window_changes.width=(unsigned int) cache_image->columns;
+ windows->image.window_changes.height=(unsigned int) cache_image->rows;
+ if (windows->image.crop_geometry != (char *) NULL)
+ MagickFreeMemory(windows->image.crop_geometry);
+ windows->image.crop_geometry=cache_image->geometry;
+ if (redo_image != (Image *) NULL)
+ DestroyImage(redo_image);
+ redo_image=(*image);
+ *image=cache_image->list;
+ DestroyImage(cache_image);
+ if (windows->image.orphan)
+ return;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ return;
+ }
+ case CutCommand:
+ case PasteCommand:
+ case ApplyCommand:
+ case HalfSizeCommand:
+ case OriginalSizeCommand:
+ case DoubleSizeCommand:
+ case ResizeCommand:
+ case TrimCommand:
+ case CropCommand:
+ case ChopCommand:
+ case FlipCommand:
+ case FlopCommand:
+ case RotateRightCommand:
+ case RotateLeftCommand:
+ case RotateCommand:
+ case ShearCommand:
+ case RollCommand:
+ case NegateCommand:
+ case EqualizeCommand:
+ case NormalizeCommand:
+ case HueCommand:
+ case SaturationCommand:
+ case BrightnessCommand:
+ case GammaCommand:
+ case SpiffCommand:
+ case DullCommand:
+ case GrayscaleCommand:
+ case MapCommand:
+ case QuantizeCommand:
+ case DespeckleCommand:
+ case EmbossCommand:
+ case ReduceNoiseCommand:
+ case AddNoiseCommand:
+ case SharpenCommand:
+ case BlurCommand:
+ case ThresholdCommand:
+ case EdgeDetectCommand:
+ case SpreadCommand:
+ case ShadeCommand:
+ case RaiseCommand:
+ case SegmentCommand:
+ case SolarizeCommand:
+ case SwirlCommand:
+ case ImplodeCommand:
+ case WaveCommand:
+ case OilPaintCommand:
+ case CharcoalDrawCommand:
+ case AnnotateCommand:
+ case AddBorderCommand:
+ case AddFrameCommand:
+ case CompositeCommand:
+ case CommentCommand:
+ case LaunchCommand:
+ case RegionofInterestCommand:
+ case SaveToUndoBufferCommand:
+ case RedoCommand:
+ {
+ Image
+ *previous_image;
+
+ long
+ bytes;
+
+ bytes=(long) ((*image)->columns*(*image)->rows*sizeof(PixelPacket));
+ if (undo_image != (Image *) NULL)
+ {
+ /*
+ Ensure the undo stash.has enough memory available.
+ */
+ previous_image=undo_image;
+ while (previous_image != (Image *) NULL)
+ {
+ bytes+=previous_image->list->columns*previous_image->list->rows*
+ sizeof(PixelPacket);
+ if (bytes <= (long) (resource_info->undo_cache << 20))
+ {
+ previous_image=previous_image->previous;
+ continue;
+ }
+ bytes-=previous_image->list->columns*previous_image->list->rows*
+ sizeof(PixelPacket);
+ if (previous_image == undo_image)
+ undo_image=(Image *) NULL;
+ else
+ previous_image->next->previous=(Image *) NULL;
+ break;
+ }
+ while (previous_image != (Image *) NULL)
+ {
+ /*
+ Delete any excess memory from undo cache.
+ */
+ cache_image=previous_image;
+ previous_image=previous_image->previous;
+ DestroyImage(cache_image->list);
+ DestroyImage(cache_image);
+ }
+ }
+ if (bytes > (long) (resource_info->undo_cache << 20))
+ break;
+ /*
+ Save image before transformations are applied.
+ */
+ cache_image=AllocateImage((ImageInfo *) NULL);
+ if (cache_image == (Image *) NULL)
+ break;
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ cache_image->list=CloneImage(*image,0,0,True,&(*image)->exception);
+ MagickXSetCursorState(display,windows,False);
+ if (cache_image->list == (Image *) NULL)
+ {
+ DestroyImage(cache_image);
+ break;
+ }
+ cache_image->columns=windows->image.ximage->width;
+ cache_image->rows=windows->image.ximage->height;
+ cache_image->geometry=windows->image.crop_geometry;
+ if (windows->image.crop_geometry != (char *) NULL)
+ {
+ cache_image->geometry=AllocateString((char *) NULL);
+ (void) strlcpy(cache_image->geometry,windows->image.crop_geometry,
+ MaxTextExtent);
+ }
+ if (undo_image == (Image *) NULL)
+ {
+ undo_image=cache_image;
+ break;
+ }
+ undo_image->next=cache_image;
+ undo_image->next->previous=undo_image;
+ undo_image=undo_image->next;
+ break;
+ }
+ default:
+ break;
+ }
+ if (command == RedoCommand)
+ {
+ /*
+ Redo the last image transformation.
+ */
+ if (redo_image == (Image *) NULL)
+ {
+ (void) XBell(display,0);
+ return;
+ }
+ windows->image.window_changes.width=(unsigned int) redo_image->columns;
+ windows->image.window_changes.height=(unsigned int) redo_image->rows;
+ if (windows->image.crop_geometry != (char *) NULL)
+ MagickFreeMemory(windows->image.crop_geometry);
+ windows->image.crop_geometry=redo_image->geometry;
+ DestroyImage(*image);
+ *image=redo_image;
+ redo_image=(Image *) NULL;
+ if (windows->image.orphan)
+ return;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ return;
+ }
+ if (command != InfoCommand)
+ return;
+ /*
+ Display image info.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ MagickXDisplayImageInfo(display,resource_info,windows,undo_image,*image);
+ MagickXSetCursorState(display,windows,False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X I m a g e W i n d o w C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXImageWindowCommand makes a transform to the image or Image window
+% as specified by a user menu button or keyboard command.
+%
+% The format of the MagickXMagickCommand method is:
+%
+% CommandType MagickXImageWindowCommand(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,
+% const unsigned int state,KeySym key_symbol,Image **image)
+%
+% A description of each parameter follows:
+%
+% o nexus: Method MagickXImageWindowCommand returns an image when the
+% user chooses 'Open Image' from the command menu. Otherwise a null
+% image is returned.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o state: key mask.
+%
+% o key_symbol: Specifies a command to perform.
+%
+% o image: Specifies a pointer to an Image structure; XImageWIndowCommand
+% may transform the image and return a new image pointer.
+%
+%
+*/
+static CommandType MagickXImageWindowCommand(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows,const unsigned int state,
+ KeySym key_symbol,Image **image)
+{
+ static char
+ delta[MaxTextExtent] = "";
+
+ static const char
+ Digits[] = "01234567890";
+
+ static KeySym
+ last_symbol = XK_0;
+
+ if ((key_symbol >= XK_0) && (key_symbol <= XK_9))
+ {
+ if (!((last_symbol >= XK_0) && (last_symbol <= XK_9)))
+ {
+ *delta='\0';
+ resource_info->quantum=1;
+ }
+ last_symbol=key_symbol;
+ delta[strlen(delta)+1]='\0';
+ delta[strlen(delta)]=Digits[key_symbol-XK_0];
+ resource_info->quantum=MagickAtoI(delta);
+ return(NullCommand);
+ }
+ last_symbol=key_symbol;
+ if (resource_info->immutable)
+ {
+ /*
+ Immutable image window has a restricted command set.
+ */
+ switch(key_symbol)
+ {
+ case XK_question:
+ return(InfoCommand);
+ case XK_p:
+ case XK_Print:
+ return(PrintCommand);
+ case XK_space:
+ return(NextCommand);
+ case XK_q:
+ {
+ if (!(state & ControlMask))
+ break;
+ return(QuitCommand);
+ }
+ default:
+ break;
+ }
+ return(NullCommand);
+ }
+ switch ((int) key_symbol)
+ {
+ case XK_o:
+ {
+ if (!(state & ControlMask))
+ break;
+ return(OpenCommand);
+ }
+ case XK_space:
+ return(NextCommand);
+ case XK_BackSpace:
+ return(FormerCommand);
+ case XK_s:
+ {
+ if (state & Mod1Mask)
+ return(SwirlCommand);
+ if (!(state & ControlMask))
+ return(ShearCommand);
+ return(SaveCommand);
+ }
+ case XK_p:
+ case XK_Print:
+ {
+ if (state & Mod1Mask)
+ return(OilPaintCommand);
+ if (state & Mod4Mask)
+ return(ColorCommand);
+ if (!(state & ControlMask))
+ return(NullCommand);
+ return(PrintCommand);
+ }
+ case XK_d:
+ {
+ if (state & Mod4Mask)
+ return(DrawCommand);
+ if (!(state & ControlMask))
+ return(NullCommand);
+ return(DeleteCommand);
+ }
+ case XK_Select:
+ {
+ if (!(state & ControlMask))
+ return(NullCommand);
+ return(SelectCommand);
+ }
+ case XK_n:
+ {
+ if (!(state & ControlMask))
+ return(NullCommand);
+ return(NewCommand);
+ }
+ case XK_q:
+ case XK_Cancel:
+ {
+ if (!(state & ControlMask))
+ return(NullCommand);
+ return(QuitCommand);
+ }
+ case XK_z:
+ case XK_Undo:
+ {
+ if (!(state & ControlMask))
+ return(NullCommand);
+ return(UndoCommand);
+ }
+ case XK_r:
+ case XK_Redo:
+ {
+ if (!(state & ControlMask))
+ return(RollCommand);
+ return(RedoCommand);
+ }
+ case XK_x:
+ {
+ if (!(state & ControlMask))
+ return(NullCommand);
+ return(CutCommand);
+ }
+ case XK_c:
+ {
+ if (state & Mod1Mask)
+ return(CharcoalDrawCommand);
+ if (!(state & ControlMask))
+ return(CropCommand);
+ return(CopyCommand);
+ }
+ case XK_v:
+ case XK_Insert:
+ {
+ if (state & Mod4Mask)
+ return(CompositeCommand);
+ if (!(state & ControlMask))
+ return(FlipCommand);
+ return(PasteCommand);
+ }
+ case XK_less:
+ return(HalfSizeCommand);
+ case XK_minus:
+ return(OriginalSizeCommand);
+ case XK_greater:
+ return(DoubleSizeCommand);
+ case XK_percent:
+ return(ResizeCommand);
+ case XK_at:
+ return(RefreshCommand);
+ case XK_bracketleft:
+ return(ChopCommand);
+ case XK_h:
+ return(FlopCommand);
+ case XK_slash:
+ return(RotateRightCommand);
+ case XK_backslash:
+ return(RotateLeftCommand);
+ case XK_asterisk:
+ return(RotateCommand);
+ case XK_t:
+ return(TrimCommand);
+ case XK_H:
+ return(HueCommand);
+ case XK_S:
+ return(SaturationCommand);
+ case XK_L:
+ return(BrightnessCommand);
+ case XK_G:
+ return(GammaCommand);
+ case XK_C:
+ return(SpiffCommand);
+ case XK_Z:
+ return(DullCommand);
+ case XK_equal:
+ return(EqualizeCommand);
+ case XK_N:
+ return(NormalizeCommand);
+ case XK_asciitilde:
+ return(NegateCommand);
+ case XK_period:
+ return(GrayscaleCommand);
+ case XK_numbersign:
+ return(QuantizeCommand);
+ case XK_F2:
+ return(DespeckleCommand);
+ case XK_F3:
+ return(EmbossCommand);
+ case XK_F4:
+ return(ReduceNoiseCommand);
+ case XK_F5:
+ return(AddNoiseCommand);
+ case XK_F6:
+ return(SharpenCommand);
+ case XK_F7:
+ return(BlurCommand);
+ case XK_F8:
+ return(ThresholdCommand);
+ case XK_F9:
+ return(EdgeDetectCommand);
+ case XK_F10:
+ return(SpreadCommand);
+ case XK_F11:
+ return(ShadeCommand);
+ case XK_F12:
+ return(RaiseCommand);
+ case XK_F13:
+ return(SegmentCommand);
+ case XK_i:
+ {
+ if (!(state & Mod1Mask))
+ return(NullCommand);
+ return(ImplodeCommand);
+ }
+ case XK_w:
+ {
+ if (!(state & Mod1Mask))
+ return(NullCommand);
+ return(WaveCommand);
+ }
+ case XK_m:
+ {
+ if (!(state & Mod4Mask))
+ return(NullCommand);
+ return(MatteCommand);
+ }
+ case XK_b:
+ {
+ if (!(state & Mod4Mask))
+ return(NullCommand);
+ return(AddBorderCommand);
+ }
+ case XK_f:
+ {
+ if (!(state & Mod4Mask))
+ return(NullCommand);
+ return(AddFrameCommand);
+ }
+ case XK_exclam:
+ {
+ if (!(state & Mod4Mask))
+ return(NullCommand);
+ return(CommentCommand);
+ }
+ case XK_a:
+ {
+ if (state & Mod1Mask)
+ return(ApplyCommand);
+ if (state & Mod4Mask)
+ return(AnnotateCommand);
+ if (!(state & ControlMask))
+ return(NullCommand);
+ return(RegionofInterestCommand);
+ }
+ case XK_question:
+ return(InfoCommand);
+ case XK_plus:
+ return(ZoomCommand);
+ case XK_P:
+ {
+ if (!(state & ShiftMask))
+ return(NullCommand);
+ return(ShowPreviewCommand);
+ }
+ case XK_Execute:
+ return(LaunchCommand);
+ case XK_F1:
+ return(HelpCommand);
+ case XK_Find:
+ return(BrowseDocumentationCommand);
+ case XK_Menu:
+ {
+ (void) XMapRaised(display,windows->command.id);
+ return(NullCommand);
+ }
+ case XK_Next:
+ case XK_Prior:
+ case XK_Home:
+ case XK_KP_Home:
+ {
+ MagickXTranslateImage(display,windows,*image,key_symbol);
+ return(NullCommand);
+ }
+ case XK_Up:
+ case XK_KP_Up:
+ case XK_Down:
+ case XK_KP_Down:
+ case XK_Left:
+ case XK_KP_Left:
+ case XK_Right:
+ case XK_KP_Right:
+ {
+ if (state & Mod1Mask)
+ {
+ RectangleInfo
+ crop_info;
+
+ /*
+ Trim one pixel from edge of image.
+ */
+ crop_info.x=0;
+ crop_info.y=0;
+ crop_info.width=windows->image.ximage->width;
+ crop_info.height=windows->image.ximage->height;
+ if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
+ {
+ if (resource_info->quantum >= (int) crop_info.height)
+ resource_info->quantum=(unsigned int) crop_info.height-1;
+ crop_info.height-=resource_info->quantum;
+ }
+ if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
+ {
+ if (resource_info->quantum >= (int) (crop_info.height-crop_info.y))
+ resource_info->quantum=(unsigned int)
+ (crop_info.height-crop_info.y-1);
+ crop_info.y+=resource_info->quantum;
+ crop_info.height-=resource_info->quantum;
+ }
+ if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
+ {
+ if (resource_info->quantum >= (int) crop_info.width)
+ resource_info->quantum=(int) crop_info.width-1;
+ crop_info.width-=resource_info->quantum;
+ }
+ if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
+ {
+ if (resource_info->quantum >= (int) (crop_info.width-crop_info.x))
+ resource_info->quantum=(unsigned int)
+ (crop_info.width-crop_info.x-1);
+ crop_info.x+=resource_info->quantum;
+ crop_info.width-=resource_info->quantum;
+ }
+ if ((int) (windows->image.x+windows->image.width) >
+ (int) crop_info.width)
+ windows->image.x=(int) (crop_info.width-windows->image.width);
+ if ((int) (windows->image.y+windows->image.height) >
+ (int) crop_info.height)
+ windows->image.y=(int) (crop_info.height-windows->image.height);
+ MagickXSetCropGeometry(display,windows,&crop_info,*image);
+ windows->image.window_changes.width=(unsigned int) crop_info.width;
+ windows->image.window_changes.height=(unsigned int) crop_info.height;
+ (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ return(NullCommand);
+ }
+ MagickXTranslateImage(display,windows,*image,key_symbol);
+ return(NullCommand);
+ }
+ default:
+ return(NullCommand);
+ }
+ return(NullCommand);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X M a g i c k C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMagickCommand makes a transform to the image or Image window
+% as specified by a user menu button or keyboard command.
+%
+% The format of the MagickXMagickCommand method is:
+%
+% Image *MagickXMagickCommand(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,const CommandType command,Image **image)
+%
+% A description of each parameter follows:
+%
+% o nexus: Method MagickXMagickCommand returns an image when the
+% user chooses 'Load Image' from the command menu. Otherwise a null
+% image is returned.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o command: Specifies a command to perform.
+%
+% o image: Specifies a pointer to an Image structure; MagickXMagickCommand
+% may transform the image and return a new image pointer.
+%
+%
+*/
+#define ReplaceImage(oldimage,func) \
+{ \
+ Image \
+ *temporary_image; \
+\
+ temporary_image=func; \
+ if (temporary_image) \
+ { \
+ DestroyImage(oldimage); \
+ oldimage=temporary_image; \
+ } \
+}
+static Image *MagickXMagickCommand(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,const CommandType command,Image **image)
+{
+ char
+ /* *argv[10], */
+ filename[MaxTextExtent],
+ geometry[MaxTextExtent],
+ modulate_factors[MaxTextExtent];
+
+ Image
+ *nexus;
+
+ ImageInfo
+ *image_info;
+
+ RectangleInfo
+ rectangle;
+
+ int
+ status,
+ x,
+ y;
+
+ static char
+ color[MaxTextExtent] = "gray";
+
+ unsigned int
+ height,
+ width;
+
+ /*
+ Process user command.
+ */
+ MagickXCheckRefreshWindows(display,windows);
+ MagickXImageCache(display,resource_info,windows,command,image);
+ /* argv[0]=resource_info->client_name; */
+ nexus=(Image *) NULL;
+ windows->image.window_changes.width=windows->image.ximage->width;
+ windows->image.window_changes.height=windows->image.ximage->height;
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ switch (command)
+ {
+ case OpenCommand:
+ {
+ /*
+ Load image.
+ */
+ nexus=MagickXOpenImage(display,resource_info,windows,False);
+ break;
+ }
+ case NextCommand:
+ {
+ /*
+ Display next image.
+ */
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ break;
+ }
+ case FormerCommand:
+ {
+ /*
+ Display former image.
+ */
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_former_image,CurrentTime);
+ break;
+ }
+ case SelectCommand:
+ {
+ /*
+ Select image.
+ */
+ if ((strlen(resource_info->home_directory) > 0) &&
+ (chdir(resource_info->home_directory) != 0))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to restore directory:",
+ resource_info->home_directory);
+ MagickFatalError(ConfigureFatalError,UnableToRestoreCurrentDirectory,
+ resource_info->home_directory);
+ }
+ nexus=MagickXOpenImage(display,resource_info,windows,True);
+ break;
+ }
+ case SaveCommand:
+ {
+ /*
+ Save image.
+ */
+ status=MagickXSaveImage(display,resource_info,windows,*image);
+ if (status == MagickFail)
+ {
+ char reason[MaxTextExtent];
+
+ FormatString(reason,"%s \"%s\"",
+ (*image)->exception.reason ? (*image)->exception.reason : "",
+ (*image)->exception.description ? (*image)->exception.description : "");
+ MagickXNoticeWidget(display,windows,"Unable to save file:",reason);
+ break;
+ }
+ break;
+ }
+ case PrintCommand:
+ {
+ /*
+ Print image.
+ */
+ status=MagickXPrintImage(display,resource_info,windows,*image);
+ if (status == False)
+ {
+ char reason[MaxTextExtent];
+
+ FormatString(reason,"%s \"%s\"",
+ (*image)->exception.reason ? (*image)->exception.reason : "",
+ (*image)->exception.description ? (*image)->exception.description : "");
+ MagickXNoticeWidget(display,windows,"Unable to print image:",reason);
+ break;
+ }
+ break;
+ }
+ case DeleteCommand:
+ {
+ static char
+ filename[MaxTextExtent] = "\0";
+
+ /*
+ Delete image file.
+ */
+ MagickXFileBrowserWidget(display,windows,"Delete",filename);
+ if (*filename == '\0')
+ break;
+ status=remove(filename);
+ if (status != False)
+ MagickXNoticeWidget(display,windows,"Unable to delete image file:",filename);
+ break;
+ }
+ case NewCommand:
+ {
+ static char
+ *format = (char *) "gradient",
+ color[MaxTextExtent] = "gray",
+ geometry[MaxTextExtent] = "640x480";
+
+ /*
+ Query user for canvas geometry.
+ */
+ status=MagickXDialogWidget(display,windows,"New","Enter image geometry:",
+ geometry);
+ if (*geometry == '\0')
+ break;
+ if (!status)
+ format=(char *) "xc";
+ MagickXColorBrowserWidget(display,windows,"Select",color);
+ if (*color == '\0')
+ break;
+ /*
+ Create canvas.
+ */
+ FormatString(image_info->filename,"%.1024s:%.1024s",format,color);
+ (void) CloneString(&image_info->size,geometry);
+ nexus=ReadImage(image_info,&(*image)->exception);
+ if ((*image)->exception.severity != UndefinedException)
+ MagickError2((*image)->exception.severity,(*image)->exception.reason,
+ (*image)->exception.description);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ break;
+ }
+ case VisualDirectoryCommand:
+ {
+ /*
+ Visual Image directory.
+ */
+ nexus=MagickXVisualDirectoryImage(display,resource_info,windows);
+ break;
+ }
+ case QuitCommand:
+ {
+ /*
+ Exit program.
+ */
+ if (!resource_info->confirm_exit)
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_exit,CurrentTime);
+ else
+ {
+ /*
+ Confirm program exit.
+ */
+ status=MagickXConfirmWidget(display,windows,"Do you really want to exit",
+ resource_info->client_name);
+ if (status > 0)
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_exit,CurrentTime);
+ }
+ break;
+ }
+ case CutCommand:
+ {
+ /*
+ Cut image.
+ */
+ (void) MagickXCropImage(display,resource_info,windows,*image,CutMode);
+ break;
+ }
+ case CopyCommand:
+ {
+ /*
+ Copy image.
+ */
+ (void) MagickXCropImage(display,resource_info,windows,*image,CopyMode);
+ break;
+ }
+ case PasteCommand:
+ {
+ /*
+ Paste image.
+ */
+ status=MagickXPasteImage(display,resource_info,windows,*image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to paste X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case HalfSizeCommand:
+ {
+ /*
+ Half image size.
+ */
+ windows->image.window_changes.width=windows->image.ximage->width/2;
+ windows->image.window_changes.height=windows->image.ximage->height/2;
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case OriginalSizeCommand:
+ {
+ /*
+ Original image size.
+ */
+ windows->image.window_changes.width=(unsigned int) (*image)->columns;
+ windows->image.window_changes.height=(unsigned int) (*image)->rows;
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case DoubleSizeCommand:
+ {
+ /*
+ Double the image size.
+ */
+ windows->image.window_changes.width=windows->image.ximage->width << 1;
+ windows->image.window_changes.height=windows->image.ximage->height << 1;
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case ResizeCommand:
+ {
+ long
+ x,
+ y;
+
+ unsigned long
+ height,
+ width;
+
+ /*
+ Resize image.
+ */
+ width=windows->image.ximage->width;
+ height=windows->image.ximage->height;
+ x=0;
+ y=0;
+ FormatString(geometry,"%lux%lu+0+0",width,height);
+ status=MagickXDialogWidget(display,windows,"Resize",
+ "Enter resize geometry (e.g. 640x480, 200%):",geometry);
+ if (*geometry == '\0')
+ break;
+ if (!status)
+ (void) strcat(geometry,"!");
+ (void) GetMagickGeometry(geometry,&x,&y,&width,&height);
+ windows->image.window_changes.width=(unsigned int) width;
+ windows->image.window_changes.height=(unsigned int) height;
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case ApplyCommand:
+ {
+ char
+ image_geometry[MaxTextExtent];
+
+ if ((windows->image.crop_geometry == (char *) NULL) &&
+ ((int) (*image)->columns == windows->image.ximage->width) &&
+ ((int) (*image)->rows == windows->image.ximage->height))
+ break;
+ /*
+ Apply size transforms to image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ /*
+ Crop and/or scale displayed image.
+ */
+ FormatString(image_geometry,"%dx%d!",windows->image.ximage->width,
+ windows->image.ximage->height);
+ TransformImage(image,windows->image.crop_geometry,image_geometry);
+ if (windows->image.crop_geometry != (char *) NULL)
+ {
+ MagickFreeMemory(windows->image.crop_geometry);
+ windows->image.crop_geometry=(char *) NULL;
+ }
+ windows->image.x=0;
+ windows->image.y=0;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case RefreshCommand:
+ {
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case RestoreCommand:
+ {
+ /*
+ Restore Image window to its original size.
+ */
+ if ((windows->image.width == (unsigned int) (*image)->columns) &&
+ (windows->image.height == (unsigned int) (*image)->rows) &&
+ (windows->image.crop_geometry == (char *) NULL))
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ windows->image.window_changes.width=(unsigned int) (*image)->columns;
+ windows->image.window_changes.height=(unsigned int) (*image)->rows;
+ if (windows->image.crop_geometry != (char *) NULL)
+ {
+ MagickFreeMemory(windows->image.crop_geometry);
+ windows->image.crop_geometry=(char *) NULL;
+ windows->image.x=0;
+ windows->image.y=0;
+ }
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case CropCommand:
+ {
+ /*
+ Crop image.
+ */
+ (void) MagickXCropImage(display,resource_info,windows,*image,CropMode);
+ break;
+ }
+ case ChopCommand:
+ {
+ /*
+ Chop image.
+ */
+ status=MagickXChopImage(display,resource_info,windows,image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to cut X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case FlopCommand:
+ {
+ /*
+ Flop image scanlines.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,FlopImage(*image,&(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.crop_geometry != (char *) NULL)
+ {
+ /*
+ Flop crop geometry.
+ */
+ width=(unsigned int) (*image)->columns;
+ height=(unsigned int) (*image)->rows;
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
+ &width,&height);
+ FormatString(windows->image.crop_geometry,"%ux%u%+d%+d",width,
+ height,(int) (*image)->columns-(int) width-x,y);
+ }
+ if (windows->image.orphan)
+ break;
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case FlipCommand:
+ {
+ /*
+ Flip image scanlines.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,FlipImage(*image,&(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.crop_geometry != (char *) NULL)
+ {
+ /*
+ Flip crop geometry.
+ */
+ width=(unsigned int) (*image)->columns;
+ height=(unsigned int) (*image)->rows;
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
+ &width,&height);
+ FormatString(windows->image.crop_geometry,"%ux%u%+d%+d",width,
+ height,x,(int) (*image)->rows-(int) height-y);
+ }
+ if (windows->image.orphan)
+ break;
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case RotateRightCommand:
+ {
+ /*
+ Rotate image 90 degrees clockwise.
+ */
+ status=MagickXRotateImage(display,resource_info,windows,90.0,image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to rotate X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case RotateLeftCommand:
+ {
+ /*
+ Rotate image 90 degrees counter-clockwise.
+ */
+ status=MagickXRotateImage(display,resource_info,windows,-90.0,image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to rotate X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case RotateCommand:
+ {
+ /*
+ Rotate image.
+ */
+ status=MagickXRotateImage(display,resource_info,windows,0.0,image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to rotate X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case ShearCommand:
+ {
+ static char
+ geometry[MaxTextExtent] = "45.0x45.0";
+
+ double
+ x_shear,
+ y_shear;
+
+ /*
+ Query user for shear color and geometry.
+ */
+ MagickXColorBrowserWidget(display,windows,"Select",color);
+ if (*color == '\0')
+ break;
+ (void) MagickXDialogWidget(display,windows,"Shear","Enter shear geometry:",
+ geometry);
+ if (*geometry == '\0')
+ break;
+ /*
+ Shear image.
+ */
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) QueryColorDatabase(color,&(*image)->background_color,
+ &(*image)->exception);
+ x_shear=0.0;
+ y_shear=0.0;
+ (void) GetMagickDimension(geometry,&x_shear,&y_shear,NULL,NULL);
+ ReplaceImage(*image,ShearImage(*image,x_shear,y_shear,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ windows->image.window_changes.width=(unsigned int) (*image)->columns;
+ windows->image.window_changes.height=(unsigned int) (*image)->rows;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case RollCommand:
+ {
+ static char
+ geometry[MaxTextExtent] = "+2+2";
+
+ /*
+ Query user for the roll geometry.
+ */
+ (void) MagickXDialogWidget(display,windows,"Roll","Enter roll geometry:",
+ geometry);
+ if (*geometry == '\0')
+ break;
+ /*
+ Roll image.
+ */
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) GetImageGeometry(*image,geometry,False,&rectangle);
+ ReplaceImage(*image,RollImage(*image,rectangle.x,rectangle.y,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ windows->image.window_changes.width=(unsigned int) (*image)->columns;
+ windows->image.window_changes.height=(unsigned int) (*image)->rows;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case TrimCommand:
+ {
+ /*
+ Trim image.
+ */
+ status=MagickXTrimImage(display,resource_info,windows,*image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to trim X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case HueCommand:
+ {
+ static char
+ hue_percent[MaxTextExtent] = "110";
+
+ /*
+ Query user for percent hue change.
+ */
+ (void) MagickXDialogWidget(display,windows,"Apply",
+ "Enter percent change in image hue (0-200):",hue_percent);
+ if (*hue_percent == '\0')
+ break;
+ /*
+ Vary the image hue.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) strlcpy(modulate_factors,"100.0/100.0/",MaxTextExtent);
+ (void) strlcat(modulate_factors,hue_percent,MaxTextExtent);
+ (void) ModulateImage(*image,modulate_factors);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case SaturationCommand:
+ {
+ static char
+ saturation_percent[MaxTextExtent] = "110";
+
+ /*
+ Query user for percent saturation change.
+ */
+ (void) MagickXDialogWidget(display,windows,"Apply",
+ "Enter percent change in color saturation (0-200):",saturation_percent);
+ if (*saturation_percent == '\0')
+ break;
+ /*
+ Vary color saturation.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) strlcpy(modulate_factors,"100.0/",MaxTextExtent);
+ (void) strlcat(modulate_factors,saturation_percent,MaxTextExtent);
+ (void) ModulateImage(*image,modulate_factors);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case BrightnessCommand:
+ {
+ static char
+ brightness_percent[MaxTextExtent] = "110";
+
+ /*
+ Query user for percent brightness change.
+ */
+ (void) MagickXDialogWidget(display,windows,"Apply",
+ "Enter percent change in color brightness (0-200):",brightness_percent);
+ if (*brightness_percent == '\0')
+ break;
+ /*
+ Vary the color brightness.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) strlcpy(modulate_factors,brightness_percent,MaxTextExtent);
+ (void) ModulateImage(*image,modulate_factors);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case GammaCommand:
+ {
+ static char
+ factor[MaxTextExtent] = "1.6";
+
+ /*
+ Query user for gamma value.
+ */
+ (void) MagickXDialogWidget(display,windows,"Gamma",
+ "Enter gamma value (e.g. 1.0/1.0/1.6):",factor);
+ if (*factor == '\0')
+ break;
+ /*
+ Gamma correct image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) GammaImage(*image,factor);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case SpiffCommand:
+ {
+ /*
+ Sharpen the image contrast.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) ContrastImage(*image,True);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case DullCommand:
+ {
+ /*
+ Dull the image contrast.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) ContrastImage(*image,False);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case EqualizeCommand:
+ {
+ /*
+ Perform histogram equalization on the image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) EqualizeImage(*image);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case NormalizeCommand:
+ {
+ /*
+ Perform histogram normalization on the image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) NormalizeImage(*image);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case NegateCommand:
+ {
+ /*
+ Negate colors in image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) NegateImage(*image,False);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case GrayscaleCommand:
+ {
+ /*
+ Convert image to grayscale.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) TransformColorspace(*image,GRAYColorspace);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case MapCommand:
+ {
+ static char
+ filename[MaxTextExtent] = "\0";
+
+ Image
+ *map_image;
+
+ /*
+ Request image file name from user.
+ */
+ MagickXFileBrowserWidget(display,windows,"Map",filename);
+ if (*filename == '\0')
+ break;
+ /*
+ Map image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ map_image=ReadImage(resource_info->image_info,&(*image)->exception);
+ if (map_image != (Image *) NULL)
+ {
+ (void) MapImage(*image,map_image,True);
+ DestroyImage(map_image);
+ }
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case QuantizeCommand:
+ {
+ static char
+ colors[MaxTextExtent] = "256";
+
+ QuantizeInfo
+ quantize_info;
+
+ /*
+ Query user for maximum number of colors.
+ */
+ status=MagickXDialogWidget(display,windows,"Quantize",
+ "Maximum number of colors:",colors);
+ if (*colors == '\0')
+ break;
+ /*
+ Color reduce the image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.number_colors=MagickAtoL(colors);
+ quantize_info.dither=(status ? False : True);
+ quantize_info.colorspace=(*image)->colorspace;
+ (void) QuantizeImage(&quantize_info,*image);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case DespeckleCommand:
+ {
+ /*
+ Despeckle image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,DespeckleImage(*image,&(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case EmbossCommand:
+ {
+ static char
+ emboss_argument[MaxTextExtent] = "0.0x1.0";
+
+ double
+ radius,
+ sigma;
+
+ /*
+ Query user for emboss radius.
+ */
+ (void) MagickXDialogWidget(display,windows,"Emboss",
+ "Enter the emboss radius and standard deviation:",emboss_argument);
+ if (*emboss_argument == '\0')
+ break;
+ /*
+ Reduce noise in the image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(emboss_argument,&radius,&sigma,NULL,NULL);
+ ReplaceImage(*image,EmbossImage(*image,radius,sigma,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case ReduceNoiseCommand:
+ {
+ static char
+ radius[MaxTextExtent] = "0";
+
+ /*
+ Query user for noise radius.
+ */
+ (void) MagickXDialogWidget(display,windows,"Reduce Noise",
+ "Enter the noise radius:",radius);
+ if (*radius == '\0')
+ break;
+ /*
+ Reduce noise in the image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,ReduceNoiseImage(*image,MagickAtoL(radius),
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case AddNoiseCommand:
+ {
+ static char
+ option[MaxTextExtent] = "Gaussian";
+
+ NoiseType
+ noise_type;
+
+ /*
+ Add noise to the image.
+ */
+ MagickXListBrowserWidget(display,windows,&windows->widget,NoiseTypes,
+ "Add Noise","Select a type of noise to add to your image:",
+ option);
+ if (*option == '\0')
+ break;
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ noise_type=UniformNoise;
+ if (LocaleCompare("Gaussian",option) == 0)
+ noise_type=GaussianNoise;
+ if (LocaleCompare("multiplicative",option) == 0)
+ noise_type=MultiplicativeGaussianNoise;
+ if (LocaleCompare("impulse",option) == 0)
+ noise_type=ImpulseNoise;
+ if (LocaleCompare("laplacian",option) == 0)
+ noise_type=LaplacianNoise;
+ if (LocaleCompare("Poisson",option) == 0)
+ noise_type=PoissonNoise;
+ ReplaceImage(*image,AddNoiseImage(*image,noise_type,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case SharpenCommand:
+ {
+ static char
+ option[MaxTextExtent] = "0.0x1.0";
+
+ double
+ radius,
+ sigma;
+
+ /*
+ Query user for sharpen radius.
+ */
+ (void) MagickXDialogWidget(display,windows,"Sharpen",
+ "Enter the sharpen radius and standard deviation:",option);
+ if (*option == '\0')
+ break;
+ /*
+ Sharpen image scanlines.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(option,&radius,&sigma,NULL,NULL);
+ ReplaceImage(*image,SharpenImage(*image,radius,sigma,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case BlurCommand:
+ {
+ static char
+ option[MaxTextExtent] = "0.0x1.0";
+
+ double
+ radius,
+ sigma;
+
+ /*
+ Query user for blur radius.
+ */
+ (void) MagickXDialogWidget(display,windows,"Blur",
+ "Enter the blur radius and standard deviation:",option);
+ if (*option == '\0')
+ break;
+ /*
+ Blur an image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(option,&radius,&sigma,NULL,NULL);
+ ReplaceImage(*image,BlurImage(*image,radius,sigma,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case ThresholdCommand:
+ {
+ static char
+ factor[MaxTextExtent];
+
+ /*
+ Query user for threshold value.
+ */
+ (void) sprintf(factor,"%lu",(unsigned long)(MaxRGB+1)/2);
+ (void) MagickXDialogWidget(display,windows,"Threshold",
+ "Enter threshold value:",factor);
+ if (*factor == '\0')
+ break;
+ /*
+ Threshold image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) ChannelThresholdImage(*image,factor);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case EdgeDetectCommand:
+ {
+ static char
+ radius[MaxTextExtent] = "0";
+
+ /*
+ Query user for edge factor.
+ */
+ (void) MagickXDialogWidget(display,windows,"Detect Edges",
+ "Enter the edge detect radius:",radius);
+ if (*radius == '\0')
+ break;
+ /*
+ Detect edge in image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,EdgeImage(*image,MagickAtoF(radius),
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case SpreadCommand:
+ {
+ static char
+ amount[MaxTextExtent] = "2";
+
+ /*
+ Query user for spread amount.
+ */
+ (void) MagickXDialogWidget(display,windows,"Spread",
+ "Enter the displacement amount:",amount);
+ if (*amount == '\0')
+ break;
+ /*
+ Displace image pixels by a random amount.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,SpreadImage(*image,MagickAtoI(amount),
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case ShadeCommand:
+ {
+ static char
+ geometry[MaxTextExtent] = "30x30";
+
+ double
+ azimuth,
+ elevation;
+
+ /*
+ Query user for the shade geometry.
+ */
+ status=MagickXDialogWidget(display,windows,"Shade",
+ "Enter the azimuth and elevation of the light source:",geometry);
+ if (*geometry == '\0')
+ break;
+ /*
+ Shade image pixels.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ azimuth=30.0;
+ elevation=30.0;
+ (void) GetMagickDimension(geometry,&azimuth,&elevation,NULL,NULL);
+ ReplaceImage(*image,ShadeImage(*image,(status ? True : False),
+ azimuth,elevation,&(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case RaiseCommand:
+ {
+ static char
+ bevel_width[MaxTextExtent] = "10";
+
+ /*
+ Query user for bevel width.
+ */
+ (void) MagickXDialogWidget(display,windows,"Raise","Bevel width:",bevel_width);
+ if (*bevel_width == '\0')
+ break;
+ /*
+ Raise an image.
+ */
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) GetImageGeometry(*image,bevel_width,False,&rectangle);
+ (void) RaiseImage(*image,&rectangle,True);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case SegmentCommand:
+ {
+ static char
+ threshold[MaxTextExtent] = "1.0x1.5";
+
+ double
+ cluster_threshold,
+ smoothing_threshold;
+
+ /*
+ Query user for smoothing threshold.
+ */
+ (void) MagickXDialogWidget(display,windows,"Segment","Smooth threshold:",
+ threshold);
+ if (*threshold == '\0')
+ break;
+ /*
+ Segment an image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ cluster_threshold=1.0;
+ smoothing_threshold=1.5;
+ (void) GetMagickDimension(threshold,&cluster_threshold,
+ &smoothing_threshold,NULL,NULL);
+ (void) SegmentImage(*image,(*image)->colorspace,False,
+ cluster_threshold,smoothing_threshold);
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case SolarizeCommand:
+ {
+ static char
+ factor[MaxTextExtent] = "60";
+
+ /*
+ Query user for solarize factor.
+ */
+ (void) MagickXDialogWidget(display,windows,"Solarize",
+ "Enter the solarize factor (0 - 99.9%):",factor);
+ if (*factor == '\0')
+ break;
+ /*
+ Solarize image pixels.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) SolarizeImage(*image,StringToDouble(factor,MaxRGB));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case SwirlCommand:
+ {
+ static char
+ degrees[MaxTextExtent] = "60";
+
+ /*
+ Query user for swirl angle.
+ */
+ (void) MagickXDialogWidget(display,windows,"Swirl","Enter the swirl angle:",
+ degrees);
+ if (*degrees == '\0')
+ break;
+ /*
+ Swirl image pixels about the center.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,SwirlImage(*image,MagickAtoF(degrees),
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case ImplodeCommand:
+ {
+ static char
+ factor[MaxTextExtent] = "0.3";
+
+ /*
+ Query user for implode factor.
+ */
+ (void) MagickXDialogWidget(display,windows,"Implode",
+ "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
+ if (*factor == '\0')
+ break;
+ /*
+ Implode image pixels about the center.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,ImplodeImage(*image,MagickAtoF(factor),
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case WaveCommand:
+ {
+ static char
+ geometry[MaxTextExtent] = "25x150";
+
+ double
+ amplitude,
+ wavelength;
+
+ /*
+ Query user for the shade geometry.
+ */
+ (void) MagickXDialogWidget(display,windows,"Wave",
+ "Enter the amplitude and length of the wave:",geometry);
+ if (*geometry == '\0')
+ break;
+ /*
+ Shade image pixels.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ amplitude=25.0;
+ wavelength=150.0;
+ (void) GetMagickDimension(geometry,&amplitude,&wavelength,NULL,NULL);
+ ReplaceImage(*image,WaveImage(*image,amplitude,wavelength,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case OilPaintCommand:
+ {
+ static char
+ radius[MaxTextExtent] = "0";
+
+ /*
+ Query user for circular neighborhood radius.
+ */
+ (void) MagickXDialogWidget(display,windows,"Oil Paint",
+ "Enter the mask radius:",radius);
+ if (*radius == '\0')
+ break;
+ /*
+ OilPaint image scanlines.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ ReplaceImage(*image,OilPaintImage(*image,MagickAtoF(radius),
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case CharcoalDrawCommand:
+ {
+ static char
+ option[MaxTextExtent] = "0.0";
+
+ double
+ radius,
+ sigma;
+
+ /*
+ Query user for charcoal radius.
+ */
+ (void) MagickXDialogWidget(display,windows,"Charcoal Draw",
+ "Enter the charcoal radius:",option);
+ if (*option == '\0')
+ break;
+ /*
+ Charcoal the image.
+ */
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ radius=0.0;
+ sigma=1.0;
+ (void) GetMagickDimension(option,&radius,&sigma,NULL,NULL);
+ ReplaceImage(*image,CharcoalImage(*image,radius,sigma,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case AnnotateCommand:
+ {
+ /*
+ Annotate the image with text.
+ */
+ status=MagickXAnnotateEditImage(display,resource_info,windows,*image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to annotate X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case DrawCommand:
+ {
+ /*
+ Draw image.
+ */
+ status=MagickXDrawEditImage(display,resource_info,windows,image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to draw on the X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case ColorCommand:
+ {
+ /*
+ Color edit.
+ */
+ status=MagickXColorEditImage(display,resource_info,windows,image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to pixel edit X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case MatteCommand:
+ {
+ /*
+ Matte edit.
+ */
+ status=MagickXMatteEditImage(display,resource_info,windows,image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to matte edit X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case CompositeCommand:
+ {
+ /*
+ Composite image.
+ */
+ status=MagickXCompositeImage(display,resource_info,windows,*image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to composite X image",
+ (*image)->filename);
+ break;
+ }
+ break;
+ }
+ case AddBorderCommand:
+ {
+ static char
+ geometry[MaxTextExtent] = "6x6";
+
+ /*
+ Query user for border color and geometry.
+ */
+ MagickXColorBrowserWidget(display,windows,"Select",color);
+ if (*color == '\0')
+ break;
+ (void) MagickXDialogWidget(display,windows,"Add Border",
+ "Enter border geometry:",geometry);
+ if (*geometry == '\0')
+ break;
+ /*
+ Add a border to the image.
+ */
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) QueryColorDatabase(color,&(*image)->border_color,
+ &(*image)->exception);
+ (void) GetImageGeometry(*image,geometry,False,&rectangle);
+ ReplaceImage(*image,BorderImage(*image,&rectangle,
+ &(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ windows->image.window_changes.width=(unsigned int) (*image)->columns;
+ windows->image.window_changes.height=(unsigned int) (*image)->rows;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case AddFrameCommand:
+ {
+ static char
+ geometry[MaxTextExtent] = "6x6";
+
+ FrameInfo
+ frame_info;
+
+ /*
+ Query user for frame color and geometry.
+ */
+ MagickXColorBrowserWidget(display,windows,"Select",color);
+ if (*color == '\0')
+ break;
+ (void) MagickXDialogWidget(display,windows,"Add Frame","Enter frame geometry:",
+ geometry);
+ if (*geometry == '\0')
+ break;
+ /*
+ Surround image with an ornamental border.
+ */
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) QueryColorDatabase(color,&(*image)->matte_color,
+ &(*image)->exception);
+ (void) GetImageGeometry(*image,geometry,False,&rectangle);
+ frame_info.width=rectangle.width;
+ frame_info.height=rectangle.height;
+ frame_info.outer_bevel=rectangle.x;
+ frame_info.inner_bevel=rectangle.y;
+ frame_info.x=(long) frame_info.width;
+ frame_info.y=(long) frame_info.height;
+ frame_info.width=(*image)->columns+2*frame_info.width;
+ frame_info.height=(*image)->rows+2*frame_info.height;
+ ReplaceImage(*image,FrameImage(*image,&frame_info,&(*image)->exception));
+ MagickXSetCursorState(display,windows,False);
+ if (windows->image.orphan)
+ break;
+ windows->image.window_changes.width=(unsigned int) (*image)->columns;
+ windows->image.window_changes.height=(unsigned int) (*image)->rows;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ break;
+ }
+ case CommentCommand:
+ {
+ const ImageAttribute
+ *attribute;
+
+ FILE
+ *file;
+
+ /*
+ Edit image comment.
+ */
+ if (!AcquireTemporaryFileName(image_info->filename))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to open temporary file:",
+ image_info->filename);
+ break;
+ }
+ attribute=GetImageAttribute(*image,"comment");
+ if ((attribute != (const ImageAttribute *) NULL) &&
+ (attribute->value != (char *) NULL))
+ {
+ register char
+ *p;
+
+ file=fopen(image_info->filename,"w");
+ if (file == (FILE *) NULL)
+ {
+ (void) LiberateTemporaryFile(image_info->filename);
+ MagickXNoticeWidget(display,windows,"Unable to edit image comment",
+ image_info->filename);
+ break;
+ }
+ for (p=attribute->value; *p != '\0'; p++)
+ (void) fputc((int) *p,file);
+ (void) fputc('\n',file);
+ (void) fclose(file);
+ }
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ status=InvokeDelegate(image_info,*image,"edit",(char *) NULL,
+ &(*image)->exception);
+ if (status == False)
+ MagickXNoticeWidget(display,windows,"Unable to edit image comment",
+ (char *) NULL);
+ else
+ {
+ char
+ command[MaxTextExtent];
+
+ FormatString(command,"@%.1024s",image_info->filename);
+ (void) SetImageAttribute(*image,"comment",(char *) NULL);
+ (void) SetImageAttribute(*image,"comment",command);
+ (*image)->taint=True;
+ }
+ (void) LiberateTemporaryFile(image_info->filename);
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ case LaunchCommand:
+ {
+ /*
+ Launch program.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ if (!AcquireTemporaryFileName(filename))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to open temporary file:",
+ filename);
+ break;
+ }
+ FormatString((*image)->filename,"launch:%s",filename);
+ status=WriteImage(image_info,*image);
+ if (status == False)
+ {
+ (void) LiberateTemporaryFile(filename);
+ MagickXNoticeWidget(display,windows,"Unable to launch image editor",
+ (char *) NULL);
+ }
+ else
+ {
+ nexus=ReadImage(resource_info->image_info,&(*image)->exception);
+ if ((*image)->exception.severity != UndefinedException)
+ MagickError2((*image)->exception.severity,
+ (*image)->exception.reason,(*image)->exception.description);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ }
+ (void) LiberateTemporaryFile(filename);
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ case RegionofInterestCommand:
+ {
+ /*
+ Apply an image processing technique to a region of interest.
+ */
+ (void) MagickXROIImage(display,resource_info,windows,image);
+ break;
+ }
+ case InfoCommand:
+ break;
+ case ZoomCommand:
+ {
+ /*
+ Zoom image.
+ */
+ if (windows->magnify.mapped)
+ (void) XRaiseWindow(display,windows->magnify.id);
+ else
+ {
+ /*
+ Make magnify image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ (void) XMapRaised(display,windows->magnify.id);
+ MagickXSetCursorState(display,windows,False);
+ }
+ break;
+ }
+ case ShowPreviewCommand:
+ {
+ static char
+ preview_type[MaxTextExtent] = "Gamma";
+
+ register int
+ i;
+
+ /*
+ Select preview type from menu.
+ */
+ MagickXListBrowserWidget(display,windows,&windows->widget,PreviewTypes,
+ "Preview","Select an enhancement, effect, or F/X:",preview_type);
+ if (*preview_type == '\0')
+ break;
+ for (i=0; PreviewTypes[i] != (char *) NULL; i++)
+ if (LocaleCompare(PreviewTypes[i],preview_type) == 0)
+ break;
+ if (PreviewTypes[i] == (char *) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"unknown preview type",preview_type);
+ break;
+ }
+ /*
+ Show image preview.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ image_info->preview_type=(PreviewType) (i+1);
+ image_info->group=(long) windows->image.id;
+ (void) SetImageAttribute(*image,"label",(char *) NULL);
+ (void) SetImageAttribute(*image,"label","Preview");
+ if (!AcquireTemporaryFileName(filename))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to open temporary file:",
+ filename);
+ break;
+ }
+ FormatString((*image)->filename,"preview:%s",filename);
+ status=WriteImage(image_info,*image);
+ FormatString((*image)->filename,"show:%s",filename);
+ status=WriteImage(image_info,*image);
+ if (status == False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to show image preview",
+ (*image)->filename);
+ }
+ MagickXDelay(display,1500);
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ case ShowHistogramCommand:
+ {
+ /*
+ Show image histogram.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ image_info->group=(long) windows->image.id;
+ (void) SetImageAttribute(*image,"label",(char *) NULL);
+ (void) SetImageAttribute(*image,"label","Histogram");
+ if (!AcquireTemporaryFileName(filename))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to open temporary file:",
+ filename);
+ break;
+ }
+ FormatString((*image)->filename,"histogram:%s",filename);
+ status=WriteImage(image_info,*image);
+ FormatString((*image)->filename,"show:%s",filename);
+ status=WriteImage(image_info,*image);
+ if (status == False)
+ MagickXNoticeWidget(display,windows,"Unable to show histogram",
+ (*image)->filename);
+ MagickXDelay(display,1500);
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ case ShowMatteCommand:
+ {
+ if (!(*image)->matte)
+ {
+ MagickXNoticeWidget(display,windows,
+ "Image does not have any matte information",(*image)->filename);
+ break;
+ }
+ /*
+ Show image matte.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ image_info->group=(long) windows->image.id;
+ (void) SetImageAttribute(*image,"label",(char *) NULL);
+ (void) SetImageAttribute(*image,"label","Matte");
+ if (!AcquireTemporaryFileName(filename))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to open temporary file:",
+ filename);
+ break;
+ }
+ FormatString((*image)->filename,"matte:%s",filename);
+ status=WriteImage(image_info,*image);
+ FormatString((*image)->filename,"show:%s",filename);
+ status=WriteImage(image_info,*image);
+ if (status == False)
+ MagickXNoticeWidget(display,windows,"Unable to show matte",
+ (*image)->filename);
+ MagickXDelay(display,1500);
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ case BackgroundCommand:
+ {
+ /*
+ Background image.
+ */
+ status=MagickXBackgroundImage(display,resource_info,windows,image);
+ if (status == False)
+ break;
+ nexus=CloneImage(*image,0,0,True,&(*image)->exception);
+ if (nexus != (Image *) NULL)
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ break;
+ }
+ case SlideShowCommand:
+ {
+ static char
+ delay[MaxTextExtent] = "5";
+
+ /*
+ Display next image after pausing.
+ */
+ (void) MagickXDialogWidget(display,windows,"Slide Show",
+ "Pause how many 1/100ths of a second between images:",delay);
+ if (*delay == '\0')
+ break;
+ resource_info->delay=MagickAtoI(delay);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ break;
+ }
+ case PreferencesCommand:
+ {
+ /*
+ Set user preferences.
+ */
+ status=MagickXPreferencesWidget(display,resource_info,windows);
+ if (status == False)
+ break;
+ nexus=CloneImage(*image,0,0,True,&(*image)->exception);
+ if (nexus != (Image *) NULL)
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ break;
+ }
+ case HelpCommand:
+ {
+ /*
+ User requested help.
+ */
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Display",DisplayHelp);
+ break;
+ }
+ case BrowseDocumentationCommand:
+ {
+ Atom
+ mozilla_atom;
+
+ Window
+ mozilla_window,
+ root_window;
+
+ /*
+ Browse the GraphicsMagick documentation.
+ */
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ mozilla_atom=XInternAtom(display,"_MOZILLA_VERSION",False);
+ mozilla_window=MagickXWindowByProperty(display,root_window,mozilla_atom);
+ if (mozilla_window != (Window) NULL)
+ {
+ char
+ command[MaxTextExtent];
+
+ /*
+ Display documentation using Netscape remote control.
+ */
+ FormatString(command,"openURL(%.1024s,new-window,noraise)",
+ "http://www.graphicsmagick.org/");
+ mozilla_atom=XInternAtom(display,"_MOZILLA_COMMAND",False);
+ (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
+ 8,PropModeReplace,(unsigned char *) command,(int) strlen(command));
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ status=InvokeDelegate(image_info,*image,"browse",(char *) NULL,
+ &(*image)->exception);
+ if (status == False)
+ MagickXNoticeWidget(display,windows,"Unable to browse documentation",
+ (char *) NULL);
+ MagickXDelay(display,1500);
+ MagickXSetCursorState(display,windows,False);
+ break;
+ }
+ case VersionCommand:
+ {
+ MagickXNoticeWidget(display,windows,GetMagickVersion((unsigned long *) NULL),
+ GetMagickCopyright());
+ break;
+ }
+ case SaveToUndoBufferCommand:
+ break;
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ DestroyImageInfo(image_info);
+ return(nexus);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X M a g n i f y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMagnifyImage magnifies portions of the image as indicated
+% by the pointer. The magnified portion is displayed in a separate window.
+%
+% The format of the MagickXMagnifyImage method is:
+%
+% void MagickXMagnifyImage(Display *display,MagickXWindows *windows,XEvent *event)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o event: Specifies a pointer to a XEvent structure. If it is NULL,
+% the entire image is refreshed.
+%
+%
+*/
+static void MagickXMagnifyImage(Display *display,MagickXWindows *windows,XEvent *event)
+{
+ char
+ text[MaxTextExtent];
+
+ register int
+ x,
+ y;
+
+ unsigned long
+ state;
+
+ /*
+ Update magnified image until the mouse button is released.
+ */
+ (void) XDefineCursor(display,windows->image.id,windows->magnify.cursor);
+ state=DefaultState;
+ x=event->xbutton.x;
+ y=event->xbutton.y;
+ windows->magnify.x=windows->image.x+x;
+ windows->magnify.y=windows->image.y+y;
+ do
+ {
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+d%+d ",windows->magnify.x,windows->magnify.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,event);
+ switch (event->type)
+ {
+ case ButtonPress:
+ break;
+ case ButtonRelease:
+ {
+ /*
+ User has finished magnifying image.
+ */
+ x=event->xbutton.x;
+ y=event->xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case Expose:
+ break;
+ case MotionNotify:
+ {
+ x=event->xmotion.x;
+ y=event->xmotion.y;
+ break;
+ }
+ default:
+ break;
+ }
+ /*
+ Check boundary conditions.
+ */
+ if (x < 0)
+ x=0;
+ else
+ if (x >= (int) windows->image.width)
+ x=windows->image.width-1;
+ if (y < 0)
+ y=0;
+ else
+ if (y >= (int) windows->image.height)
+ y=windows->image.height-1;
+ } while (!(state & ExitState));
+ /*
+ Display magnified image.
+ */
+ MagickXSetCursorState(display,windows,False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X M a g n i f y W i n d o w C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMagnifyWindowCommand moves the image within an Magnify window by
+% one pixel as specified by the key symbol.
+%
+% The format of the MagickXMagnifyWindowCommand method is:
+%
+% void MagickXMagnifyWindowCommand(Display *display,MagickXWindows *windows,
+% const unsigned int state,const KeySym key_symbol)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o state: key mask.
+%
+% o key_symbol: Specifies a KeySym which indicates which side of the image
+% to trim.
+%
+%
+*/
+static void MagickXMagnifyWindowCommand(Display *display,MagickXWindows *windows,
+ const unsigned int state,const KeySym key_symbol)
+{
+ unsigned int
+ quantum;
+
+ /*
+ User specified a magnify factor or position.
+ */
+ quantum=1;
+ if (state & Mod1Mask)
+ quantum=10;
+ switch ((int) key_symbol)
+ {
+ case QuitCommand:
+ {
+ (void) XWithdrawWindow(display,windows->magnify.id,
+ windows->magnify.screen);
+ break;
+ }
+ case XK_Home:
+ case XK_KP_Home:
+ {
+ windows->magnify.x=windows->image.width/2;
+ windows->magnify.y=windows->image.height/2;
+ break;
+ }
+ case XK_Left:
+ case XK_KP_Left:
+ {
+ if (windows->magnify.x > 0)
+ windows->magnify.x-=quantum;
+ break;
+ }
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ if (windows->magnify.y > 0)
+ windows->magnify.y-=quantum;
+ break;
+ }
+ case XK_Right:
+ case XK_KP_Right:
+ {
+ if (windows->magnify.x < (int) (windows->image.ximage->width-1))
+ windows->magnify.x+=quantum;
+ break;
+ }
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ if (windows->magnify.y < (int) (windows->image.ximage->height-1))
+ windows->magnify.y+=quantum;
+ break;
+ }
+ case XK_0:
+ case XK_1:
+ case XK_2:
+ case XK_3:
+ case XK_4:
+ case XK_5:
+ case XK_6:
+ case XK_7:
+ case XK_8:
+ case XK_9:
+ {
+ windows->magnify.data=(key_symbol-XK_0);
+ break;
+ }
+ case XK_KP_0:
+ case XK_KP_1:
+ case XK_KP_2:
+ case XK_KP_3:
+ case XK_KP_4:
+ case XK_KP_5:
+ case XK_KP_6:
+ case XK_KP_7:
+ case XK_KP_8:
+ case XK_KP_9:
+ {
+ windows->magnify.data=(key_symbol-XK_KP_0);
+ break;
+ }
+ default:
+ break;
+ }
+ MagickXMakeMagnifyImage(display,windows);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X M a k e P a n I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakePanImage creates a thumbnail of the image and displays it in
+% the Pan icon window.
+%
+% The format of the MagickXMakePanImage method is:
+%
+% void MagickXMakePanImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image *image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static void MagickXMakePanImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *image)
+{
+ unsigned int
+ status;
+
+ /*
+ Display hourglass cursor if progress indication enabled.
+ */
+ if (resource_info->image_info->progress)
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ windows->pan.x=windows->image.x;
+ windows->pan.y=windows->image.y;
+ /*
+ Create and display image for panning icon.
+ */
+ status=MagickXMakeImage(display,resource_info,&windows->pan,image,
+ windows->pan.width,windows->pan.height);
+ if (status == False)
+ MagickError2(XServerError,image->exception.reason,(char *) NULL);
+ (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
+ windows->pan.pixmap);
+ (void) XClearWindow(display,windows->pan.id);
+ MagickXDrawPanRectangle(display,windows);
+ MagickXSetCursorState(display,windows,False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X M a t t a E d i t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMatteEditImage allows the user to interactively change
+% the Matte channel of an image. If the image is PseudoClass it is promoted
+% to DirectClass before the matte information is stored.
+%
+% The format of the MagickXMatteEditImage method is:
+%
+% unsigned int MagickXMatteEditImage(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,Image **image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+*/
+static unsigned int MagickXMatteEditImage(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows,Image **image)
+{
+ static char
+ matte[MaxTextExtent] = "0";
+
+ static const char
+ *MatteEditMenu[]=
+ {
+ "Method",
+ "Border Color",
+ "Fuzz",
+ "Matte Value",
+ "Undo",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ };
+
+ static const ModeType
+ MatteEditCommands[]=
+ {
+ MatteEditMethod,
+ MatteEditBorderCommand,
+ MatteEditFuzzCommand,
+ MatteEditValueCommand,
+ MatteEditUndoCommand,
+ MatteEditHelpCommand,
+ MatteEditDismissCommand
+ };
+
+ static PaintMethod
+ method = PointMethod;
+
+ static XColor
+ border_color = { 0, 0, 0, 0, 0, 0 }; /* Also fill 'pad' field */
+
+ char
+ command[MaxTextExtent],
+ text[MaxTextExtent];
+
+ Cursor
+ cursor;
+
+ int
+ entry,
+ id,
+ x,
+ x_offset,
+ y,
+ y_offset;
+
+ register int
+ i;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ height,
+ width;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"Matte Edit");
+ windows->command.data=4;
+ (void) MagickXCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Make cursor.
+ */
+ cursor=MagickXMakeCursor(display,windows->image.id,windows->map_info->colormap,
+ resource_info->background_color,resource_info->foreground_color);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ /*
+ Track pointer until button 1 is pressed.
+ */
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+d%+d ",x+windows->image.x,y+windows->image.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,MatteEditMenu,&event);
+ if (id < 0)
+ {
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ continue;
+ }
+ switch (MatteEditCommands[id])
+ {
+ case MatteEditMethod:
+ {
+ static const char
+ *MethodMenu[]=
+ {
+ "point",
+ "replace",
+ "floodfill",
+ "filltoborder",
+ "reset",
+ (char *) NULL,
+ };
+
+ /*
+ Select a method from the pop-up menu.
+ */
+ entry=
+ MagickXMenuWidget(display,windows,MatteEditMenu[id],MethodMenu,command);
+ if (entry >= 0)
+ method=(PaintMethod) entry;
+ break;
+ }
+ case MatteEditBorderCommand:
+ {
+ char
+ *ColorMenu[MaxNumberPens];
+
+ int
+ pen_number;
+
+ /*
+ Initialize menu selections.
+ */
+ for (i=0; i < (int) (MaxNumberPens-2); i++)
+ ColorMenu[i]=resource_info->pen_colors[i];
+ ColorMenu[MaxNumberPens-2]=(char *) "Browser...";
+ ColorMenu[MaxNumberPens-1]=(char *) NULL;
+ /*
+ Select a pen color from the pop-up menu.
+ */
+ pen_number=MagickXMenuWidget(display,windows,MatteEditMenu[id],
+ (const char **) ColorMenu,command);
+ if (pen_number < 0)
+ break;
+ if (pen_number == (MaxNumberPens-2))
+ {
+ static char
+ color_name[MaxTextExtent] = "gray";
+
+ /*
+ Select a pen color from a dialog.
+ */
+ resource_info->pen_colors[pen_number]=color_name;
+ MagickXColorBrowserWidget(display,windows,"Select",color_name);
+ if (*color_name == '\0')
+ break;
+ }
+ /*
+ Set border color.
+ */
+ (void) XParseColor(display,windows->map_info->colormap,
+ resource_info->pen_colors[pen_number],&border_color);
+ break;
+ }
+ case MatteEditFuzzCommand:
+ {
+ static char
+ fuzz[MaxTextExtent];
+
+ static const char
+ *FuzzMenu[]=
+ {
+ "0%",
+ "2%",
+ "5%",
+ "10%",
+ "15%",
+ "Dialog...",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ entry=MagickXMenuWidget(display,windows,MatteEditMenu[id],FuzzMenu,
+ command);
+ if (entry < 0)
+ break;
+ if (entry != 5)
+ {
+ (*image)->fuzz=StringToDouble(FuzzMenu[entry],MaxRGB);
+ break;
+ }
+ (void) strcpy(fuzz,"20%");
+ (void) MagickXDialogWidget(display,windows,"Ok",
+ "Enter fuzz factor (0.0 - 99.9%):",fuzz);
+ if (*fuzz == '\0')
+ break;
+ (void) strcat(fuzz,"%");
+ (*image)->fuzz=StringToDouble(fuzz,MaxRGB);
+ break;
+ }
+ case MatteEditValueCommand:
+ {
+ static char
+ message[MaxTextExtent];
+
+ static const char
+ *MatteMenu[]=
+ {
+ "Opaque",
+ "Transparent",
+ "Dialog...",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ entry=MagickXMenuWidget(display,windows,MatteEditMenu[id],MatteMenu,
+ command);
+ if (entry < 0)
+ break;
+ if (entry != 2)
+ {
+ FormatString(matte,"%lu",(unsigned long) OpaqueOpacity);
+ if (LocaleCompare(MatteMenu[entry],"Transparent") == 0)
+ FormatString(matte,"%lu",(unsigned long) TransparentOpacity);
+ break;
+ }
+ FormatString(message,"Enter matte value (0 - %lu):",(unsigned long) MaxRGB);
+ (void) MagickXDialogWidget(display,windows,"Matte",message,matte);
+ if (*matte == '\0')
+ break;
+ break;
+ }
+ case MatteEditUndoCommand:
+ {
+ (void) MagickXMagickCommand(display,resource_info,windows,UndoCommand,
+ image);
+ break;
+ }
+ case MatteEditHelpCommand:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Matte Edit",ImageMatteEditHelp);
+ break;
+ }
+ case MatteEditDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if ((event.xbutton.window != windows->image.id) &&
+ (event.xbutton.window != windows->magnify.id))
+ break;
+ /*
+ Update matte data.
+ */
+ x=event.xbutton.x;
+ y=event.xbutton.y;
+ (void) MagickXMagickCommand(display,resource_info,windows,
+ SaveToUndoBufferCommand,image);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if ((event.xbutton.window != windows->image.id) &&
+ (event.xbutton.window != windows->magnify.id))
+ break;
+ /*
+ Update colormap information.
+ */
+ x=event.xbutton.x;
+ y=event.xbutton.y;
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ MagickXInfoWidget(display,windows,text);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ state&=(~UpdateConfigurationState);
+ break;
+ }
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ char
+ command[MaxTextExtent];
+
+ KeySym
+ key_symbol;
+
+ if (event.xkey.window == windows->magnify.id)
+ {
+ Window
+ window;
+
+ window=windows->magnify.id;
+ while (XCheckWindowEvent(display,window,KeyPressMask,&event));
+ }
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Matte Edit",ImageMatteEditHelp);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ break;
+ }
+ default:
+ break;
+ }
+ if (event.xany.window == windows->magnify.id)
+ {
+ x=windows->magnify.x-windows->image.x;
+ y=windows->magnify.y-windows->image.y;
+ }
+ x_offset=x;
+ y_offset=y;
+ if (state & UpdateConfigurationState)
+ {
+ int
+ x,
+ y;
+
+ /*
+ Matte edit is relative to image configuration.
+ */
+ (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,True);
+ XPutPixel(windows->image.ximage,x_offset,y_offset,
+ windows->pixel_info->background_color.pixel);
+ width=(unsigned int) (*image)->columns;
+ height=(unsigned int) (*image)->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
+ &width,&height);
+ x_offset=
+ width*(windows->image.x+x_offset)/windows->image.ximage->width+x;
+ y_offset=
+ height*(windows->image.y+y_offset)/windows->image.ximage->height+y;
+ if ((x_offset < 0) || (y_offset < 0))
+ continue;
+ if ((x_offset >= (int) (*image)->columns) ||
+ (y_offset >= (int) (*image)->rows))
+ continue;
+ (void) SetImageType(*image,TrueColorMatteType);
+ switch (method)
+ {
+ case PointMethod:
+ default:
+ {
+ /*
+ Update matte information using point algorithm.
+ */
+ q=GetImagePixels(*image,x_offset,y_offset,1,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ q->opacity=(Quantum) MagickAtoL(matte);
+ (void) SyncImagePixels(*image);
+ break;
+ }
+ case ReplaceMethod:
+ {
+ PixelPacket
+ target;
+
+ /*
+ Update matte information using replace algorithm.
+ */
+ (void) AcquireOnePixelByReference(*image,&target,x_offset,y_offset,&((*image)->exception));
+ for (y=0; y < (long) (*image)->rows; y++)
+ {
+ q=GetImagePixels(*image,0,y,(*image)->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (int) (*image)->columns; x++)
+ {
+ if (FuzzyColorMatch(q,&target,(*image)->fuzz))
+ q->opacity=(Quantum) MagickAtoL(matte);
+ q++;
+ }
+ if (!SyncImagePixels(*image))
+ break;
+ }
+ break;
+ }
+ case FloodfillMethod:
+ case FillToBorderMethod:
+ {
+ PixelPacket
+ target;
+
+ /*
+ Update matte information using floodfill algorithm.
+ */
+ (void) AcquireOnePixelByReference(*image,&target,x_offset,y_offset,&((*image)->exception));
+ if (method == FillToBorderMethod)
+ {
+ target.red=ScaleShortToQuantum(border_color.red);
+ target.green=ScaleShortToQuantum(border_color.green);
+ target.blue=ScaleShortToQuantum(border_color.blue);
+ }
+ (void) MatteFloodfillImage(*image,target,MagickAtoI(matte),x_offset,
+ y_offset,method);
+ break;
+ }
+ case ResetMethod:
+ {
+ /*
+ Update matte information using reset algorithm.
+ */
+ (void) SetImageType(*image,TrueColorType);
+ for (y=0; y < (long) (*image)->rows; y++)
+ {
+ q=SetImagePixels(*image,0,y,(*image)->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (int) (*image)->columns; x++)
+ {
+ q->opacity=(Quantum) MagickAtoL(matte);
+ q++;
+ }
+ if (!SyncImagePixels(*image))
+ break;
+ }
+ if (MagickAtoL(matte) == OpaqueOpacity)
+ (*image)->matte=False;
+ break;
+ }
+ }
+ state&=(~UpdateConfigurationState);
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ MagickXSetCursorState(display,windows,False);
+ (void) XFreeCursor(display,cursor);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X O p e n I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXOpenImage loads an image from a file.
+%
+% The format of the MagickXOpenImage method is:
+%
+% Image *MagickXOpenImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,const unsigned int command)
+%
+% A description of each parameter follows:
+%
+% o nexus: Method MagickXOpenImage returns an image if can be loaded
+% successfully. Otherwise a null image is returned.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o command: A value other than zero indicates that the file is selected
+% from the command line argument list.
+%
+%
+*/
+static Image *MagickXOpenImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,const unsigned int command)
+{
+ ExceptionInfo
+ exception;
+
+ Image
+ *nexus;
+
+ ImageInfo
+ *image_info;
+
+ MonitorHandler
+ handler;
+
+ static char
+ filename[MaxTextExtent] = "\0";
+
+ /*
+ Request file name from user.
+ */
+ if (!command)
+ MagickXFileBrowserWidget(display,windows,"Open",filename);
+ else
+ {
+ char
+ **filelist,
+ **files;
+
+ int
+ count,
+ status;
+
+ register int
+ i,
+ j;
+
+ /*
+ Select next image from the command line.
+ */
+ status=XGetCommand(display,windows->image.id,&files,&count);
+ if (!status)
+ {
+ MagickError(XServerError,UnableToGetProperty,
+ MagickMsg(ResourceLimitError,UnableToSelectImage));
+ return((Image *) NULL);
+ }
+ filelist=MagickAllocateMemory(char **,count*sizeof(char *));
+ if (filelist == (char **) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToSelectImage);
+ (void) XFreeStringList(files);
+ return((Image *) NULL);
+ }
+ j=0;
+ for (i=1; i < count; i++)
+ if (*files[i] != '-')
+ filelist[j++]=files[i];
+ filelist[j]=(char *) NULL;
+ MagickXListBrowserWidget(display,windows,&windows->widget,
+ (const char **) filelist,"Load","Select Image to Load:",filename);
+ MagickFreeMemory(filelist);
+ (void) XFreeStringList(files);
+ }
+ if (*filename == '\0')
+ return((Image *) NULL);
+ image_info=CloneImageInfo(resource_info->image_info);
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ GetExceptionInfo(&exception);
+ (void) SetImageInfo(image_info,SETMAGICK_READ,&exception);
+ if (LocaleCompare(image_info->magick,"X") == 0)
+ {
+ char
+ seconds[MaxTextExtent];
+
+ /*
+ User may want to delay the X server screen grab.
+ */
+ (void) strcpy(seconds,"0");
+ (void) MagickXDialogWidget(display,windows,"Grab","Enter any delay in seconds:",
+ seconds);
+ if (*seconds == '\0')
+ return((Image *) NULL);
+ MagickXDelay(display,1000*MagickAtoL(seconds));
+ }
+ if ((LocaleCompare(image_info->magick,"CMYK") == 0) ||
+ (LocaleCompare(image_info->magick,"GRAY") == 0) ||
+ (LocaleCompare(image_info->magick,"MAP") == 0) ||
+ (LocaleCompare(image_info->magick,"Matte") == 0) ||
+ (LocaleCompare(image_info->magick,"RGB") == 0) ||
+ (LocaleCompare(image_info->magick,"RGBA") == 0) ||
+ (LocaleCompare(image_info->magick,"TEXT") == 0) ||
+ (LocaleCompare(image_info->magick,"TILE") == 0) ||
+ (LocaleCompare(image_info->magick,"UYVY") == 0) ||
+ (LocaleCompare(image_info->magick,"XC") == 0) ||
+ (LocaleCompare(image_info->magick,"YUV") == 0))
+ {
+ char
+ geometry[MaxTextExtent];
+
+ /*
+ Request image size from the user.
+ */
+ (void) strcpy(geometry,"512x512");
+ if (image_info->size != (char *) NULL)
+ (void) strlcpy(geometry,image_info->size,MaxTextExtent);
+ (void) MagickXDialogWidget(display,windows,"Load","Enter the image geometry:",
+ geometry);
+ (void) CloneString(&image_info->size,geometry);
+ }
+ /*
+ Load the image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ handler=(MonitorHandler) NULL;
+ if (LocaleCompare(image_info->magick,"X") == 0)
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ DestroyExceptionInfo(&exception);
+ GetExceptionInfo(&exception);
+ nexus=ReadImage(image_info,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (LocaleCompare(image_info->magick,"X") == 0)
+ (void) SetMonitorHandler(handler);
+ MagickXSetCursorState(display,windows,False);
+ if (nexus != (Image *) NULL)
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ else
+ {
+ char
+ *text,
+ **textlist;
+
+ size_t
+ length;
+
+ /*
+ Unknown image format.
+ */
+ text=(char *) FileToBlob(filename,&length,&exception);
+ if (text == (char *) NULL)
+ return((Image *) NULL);
+ textlist=StringToList(text);
+ if (textlist != (char **) NULL)
+ {
+ char
+ title[MaxTextExtent];
+
+ register int
+ i;
+
+ FormatString(title,"Unknown format: %.1024s",filename);
+ MagickXTextViewWidget(display,resource_info,windows,True,title,
+ (const char **) textlist);
+ for (i=0; textlist[i] != (char *) NULL; i++)
+ MagickFreeMemory(textlist[i]);
+ MagickFreeMemory(textlist);
+ }
+ MagickFreeMemory(text);
+ }
+ DestroyExceptionInfo(&exception);
+ DestroyImageInfo(image_info);
+ return(nexus);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X P a n I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXPanImage pans the image until the mouse button is released.
+%
+% The format of the MagickXPanImage method is:
+%
+% void MagickXPanImage(Display *display,MagickXWindows *windows,XEvent *event)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o event: Specifies a pointer to a XEvent structure. If it is NULL,
+% the entire image is refreshed.
+%
+*/
+static void MagickXPanImage(Display *display,MagickXWindows *windows,XEvent *event)
+{
+ char
+ text[MaxTextExtent];
+
+ Cursor
+ cursor;
+
+ double
+ x_factor,
+ y_factor;
+
+ RectangleInfo
+ pan_info;
+
+ unsigned long
+ state;
+
+ /*
+ Define cursor.
+ */
+ if ((windows->image.ximage->width > (int) windows->image.width) &&
+ (windows->image.ximage->height > (int) windows->image.height))
+ cursor=XCreateFontCursor(display,XC_fleur);
+ else
+ if (windows->image.ximage->width > (int) windows->image.width)
+ cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
+ else
+ if (windows->image.ximage->height > (int) windows->image.height)
+ cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
+ else
+ cursor=XCreateFontCursor(display,XC_arrow);
+ (void) XDefineCursor(display,windows->pan.id,cursor);
+ /*
+ Pan image as pointer moves until the mouse button is released.
+ */
+ x_factor=(double) windows->image.ximage->width/windows->pan.width;
+ y_factor=(double) windows->image.ximage->height/windows->pan.height;
+ pan_info.x=0;
+ pan_info.y=0;
+ pan_info.width=
+ windows->pan.width*windows->image.width/windows->image.ximage->width;
+ pan_info.height=
+ windows->pan.height*windows->image.height/windows->image.ximage->height;
+ state=UpdateConfigurationState;
+ do
+ {
+ switch (event->type)
+ {
+ case ButtonPress:
+ {
+ /*
+ User choose an initial pan location.
+ */
+ pan_info.x=event->xbutton.x;
+ pan_info.y=event->xbutton.y;
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case ButtonRelease:
+ {
+ /*
+ User has finished panning the image.
+ */
+ pan_info.x=event->xbutton.x;
+ pan_info.y=event->xbutton.y;
+ state|=UpdateConfigurationState | ExitState;
+ break;
+ }
+ case MotionNotify:
+ {
+ pan_info.x=event->xmotion.x;
+ pan_info.y=event->xmotion.y;
+ state|=UpdateConfigurationState;
+ }
+ default:
+ break;
+ }
+ if (state & UpdateConfigurationState)
+ {
+ /*
+ Check boundary conditions.
+ */
+ if (pan_info.x < (int) (pan_info.width/2))
+ pan_info.x=0;
+ else
+ pan_info.x=(int) (x_factor*(pan_info.x-(pan_info.width/2)));
+ if (pan_info.x < 0)
+ pan_info.x=0;
+ else
+ if ((int) (pan_info.x+windows->image.width) >
+ windows->image.ximage->width)
+ pan_info.x=(long)
+ (windows->image.ximage->width-windows->image.width);
+ if (pan_info.y < (long) (pan_info.height/2))
+ pan_info.y=0;
+ else
+ pan_info.y=(long) (y_factor*(pan_info.y-(pan_info.height/2)));
+ if (pan_info.y < 0)
+ pan_info.y=0;
+ else
+ if ((int) (pan_info.y+windows->image.height) >
+ windows->image.ximage->height)
+ pan_info.y=(long)
+ (windows->image.ximage->height-windows->image.height);
+ if ((windows->image.x != (int) pan_info.x) ||
+ (windows->image.y != (int) pan_info.y))
+ {
+ /*
+ Display image pan offset.
+ */
+ windows->image.x=(int) pan_info.x;
+ windows->image.y=(int) pan_info.y;
+ FormatString(text," %ux%u%+d%+d ",windows->image.width,
+ windows->image.height,windows->image.x,windows->image.y);
+ MagickXInfoWidget(display,windows,text);
+ /*
+ Refresh Image window.
+ */
+ MagickXDrawPanRectangle(display,windows);
+ MagickXRefreshWindow(display,&windows->image,(XEvent *) NULL);
+ }
+ state&=(~UpdateConfigurationState);
+ }
+ /*
+ Wait for next event.
+ */
+ if (!(state & ExitState))
+ MagickXScreenEvent(display,windows,event);
+ } while (!(state & ExitState));
+ /*
+ Restore cursor.
+ */
+ (void) XDefineCursor(display,windows->pan.id,windows->pan.cursor);
+ (void) XFreeCursor(display,cursor);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X P a s t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXPasteImage pastes an image previously saved with MagickXCropImage
+% in the X window image at a location the user chooses with the pointer.
+%
+% The format of the MagickXPasteImage method is:
+%
+% unsigned int MagickXPasteImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXPasteImage returns True if the image is
+% pasted. False is returned is there is a memory shortage or if the
+% image fails to be pasted.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+*/
+static unsigned int MagickXPasteImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *image)
+{
+ static const char
+ *PasteMenu[]=
+ {
+ "Operator",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ };
+
+ static const ModeType
+ PasteCommands[]=
+ {
+ PasteOperatorsCommand,
+ PasteHelpCommand,
+ PasteDismissCommand
+ };
+
+ static CompositeOperator
+ operation = CopyCompositeOp;
+
+ char
+ text[MaxTextExtent];
+
+ Cursor
+ cursor;
+
+ double
+ scale_factor;
+
+ Image
+ *paste_image;
+
+ int
+ id,
+ x,
+ y;
+
+ RectangleInfo
+ highlight_info,
+ paste_info;
+
+ unsigned int
+ height,
+ width;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ /*
+ Copy image.
+ */
+ if (resource_info->copy_image == (Image *) NULL)
+ return(False);
+ paste_image=CloneImage(resource_info->copy_image,0,0,True,&image->exception);
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"Paste");
+ windows->command.data=1;
+ (void) MagickXCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Track pointer until button 1 is pressed.
+ */
+ MagickXSetCursorState(display,windows,False);
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ paste_info.x=windows->image.x+x;
+ paste_info.y=windows->image.y+y;
+ paste_info.width=0;
+ paste_info.height=0;
+ cursor=XCreateFontCursor(display,XC_ul_angle);
+ (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+ld%+ld ",paste_info.x,paste_info.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ highlight_info=paste_info;
+ highlight_info.x=paste_info.x-windows->image.x;
+ highlight_info.y=paste_info.y-windows->image.y;
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,PasteMenu,&event);
+ if (id < 0)
+ continue;
+ switch (PasteCommands[id])
+ {
+ case PasteOperatorsCommand:
+ {
+ char
+ command[MaxTextExtent];
+
+ static const char
+ *OperatorMenu[]=
+ {
+ "Over",
+ "In",
+ "Out",
+ "Atop",
+ "Xor",
+ "Plus",
+ "Minus",
+ "Add",
+ "Subtract",
+ "Difference",
+ "Multiply",
+ "Bumpmap",
+ "Copy",
+ "CopyRed",
+ "CopyGreen",
+ "CopyBlue",
+ "CopyOpacity",
+ "Clear",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ operation=(CompositeOperator) (MagickXMenuWidget(display,windows,
+ PasteMenu[id],OperatorMenu,command)+1);
+ break;
+ }
+ case PasteHelpCommand:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Composite",ImagePasteHelp);
+ break;
+ }
+ case PasteDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
+ event.xbutton.button,event.xbutton.x,event.xbutton.y);
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ Paste rectangle is relative to image configuration.
+ */
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
+ &width,&height);
+ scale_factor=(double) windows->image.ximage->width/width;
+ paste_info.width=(unsigned int) (scale_factor*paste_image->columns+0.5);
+ scale_factor=(double) windows->image.ximage->height/height;
+ paste_info.height=(unsigned int) (scale_factor*paste_image->rows+0.5);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ paste_info.x=windows->image.x+event.xbutton.x;
+ paste_info.y=windows->image.y+event.xbutton.y;
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
+ event.xbutton.button,event.xbutton.x,event.xbutton.y);
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ if ((paste_info.width != 0) && (paste_info.height != 0))
+ {
+ /*
+ User has selected the location of the paste image.
+ */
+ paste_info.x=windows->image.x+event.xbutton.x;
+ paste_info.y=windows->image.y+event.xbutton.y;
+ state|=ExitState;
+ }
+ break;
+ }
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ char
+ command[MaxTextExtent];
+
+ KeySym
+ key_symbol;
+
+ int
+ length;
+
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Key press: 0x%lx (%.1024s)",key_symbol,command);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ DestroyImage(paste_image);
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Composite",ImagePasteHelp);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ paste_info.x=windows->image.x+x;
+ paste_info.y=windows->image.y+y;
+ break;
+ }
+ default:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d",
+ event.type);
+ break;
+ }
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ MagickXSetCursorState(display,windows,False);
+ (void) XFreeCursor(display,cursor);
+ if (state & EscapeState)
+ return(True);
+ /*
+ Image pasting is relative to image configuration.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ scale_factor=(double) width/windows->image.ximage->width;
+ paste_info.x+=x;
+ paste_info.x=(int) (scale_factor*paste_info.x+0.5);
+ paste_info.width=(unsigned int) (scale_factor*paste_info.width+0.5);
+ scale_factor=(double) height/windows->image.ximage->height;
+ paste_info.y+=y;
+ paste_info.y=(int) (scale_factor*paste_info.y*scale_factor+0.5);
+ paste_info.height=(unsigned int) (scale_factor*paste_info.height+0.5);
+ /*
+ Paste image with X Image window.
+ */
+ (void) CompositeImage(image,operation,paste_image,paste_info.x,paste_info.y);
+ DestroyImage(paste_image);
+ MagickXSetCursorState(display,windows,False);
+ /*
+ Update image colormap.
+ */
+ MagickXConfigureImageColormap(display,resource_info,windows,image);
+ (void) MagickXConfigureImage(display,resource_info,windows,image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X P r i n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXPrintImage prints an image to a Postscript printer.
+%
+% The format of the MagickXPrintImage method is:
+%
+% unsigned int MagickXPrintImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXPrintImage return True if the image is
+% printed. False is returned is there is a memory shortage or if the
+% image fails to print.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int MagickXPrintImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *image)
+{
+ char
+ filename[MaxTextExtent],
+ geometry[MaxTextExtent];
+
+ Image
+ *print_image;
+
+ ImageInfo
+ *image_info;
+
+ unsigned int
+ status=True;
+
+ /*
+ Request Postscript page geometry from user.
+ */
+ image_info=CloneImageInfo(resource_info->image_info);
+ FormatString(geometry,"Letter");
+ if (image_info->page != (char *) NULL)
+ (void) strlcpy(geometry,image_info->page,MaxTextExtent);
+ MagickXListBrowserWidget(display,windows,&windows->widget,PageSizes,"Select",
+ "Select Postscript Page Geometry:",geometry);
+ if (*geometry == '\0')
+ return(True);
+ image_info->page=GetPageGeometry(geometry);
+ /*
+ Apply image transforms.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ print_image=CloneImage(image,0,0,True,&image->exception);
+ if (print_image == (Image *) NULL)
+ return(False);
+ FormatString(geometry,"%dx%d!",windows->image.ximage->width,
+ windows->image.ximage->height);
+ TransformImage(&print_image,windows->image.crop_geometry,geometry);
+ /*
+ Print image.
+ */
+ if (!AcquireTemporaryFileName(print_image->magick_filename))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to open temporary file:",
+ print_image->magick_filename);
+ status=False;
+ goto error_return;
+ }
+ if (!AcquireTemporaryFileName(filename))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to open temporary file:",
+ filename);
+ status=False;
+ goto error_return;
+ }
+ FormatString(print_image->filename,"print:%s",filename);
+ status=WriteImage(image_info,print_image);
+ error_return:
+ if (MagickFail == status)
+ CopyException(&image->exception,&print_image->exception);
+ DestroyImage(print_image);
+ DestroyImageInfo(image_info);
+ MagickXSetCursorState(display,windows,False);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X R O I I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXROIImage applies an image processing technique to a region
+% of interest.
+%
+% The format of the MagickXROIImage method is:
+%
+% unsigned int MagickXROIImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image **image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXROIImage returns True if the image is
+% cropped. False is returned is there is a memory shortage or if the
+% image fails to be cropped.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int MagickXROIImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image **image)
+{
+#define ApplyMenus 7
+
+ static const char
+ *ROIMenu[]=
+ {
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ },
+ *ApplyMenu[]=
+ {
+ "File",
+ "Edit",
+ "Transform",
+ "Enhance",
+ "Effects",
+ "F/X",
+ "Miscellany",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ },
+ *FileMenu[]=
+ {
+ "Save...",
+ "Print...",
+ (char *) NULL
+ },
+ *EditMenu[]=
+ {
+ "Undo",
+ "Redo",
+ (char *) NULL
+ },
+ *TransformMenu[]=
+ {
+ "Flop",
+ "Flip",
+ "Rotate Right",
+ "Rotate Left",
+ (char *) NULL
+ },
+ *EnhanceMenu[]=
+ {
+ "Hue...",
+ "Saturation...",
+ "Brightness...",
+ "Gamma...",
+ "Spiff",
+ "Dull",
+ "Equalize",
+ "Normalize",
+ "Negate",
+ "Grayscale",
+ "Map...",
+ "Quantize...",
+ (char *) NULL
+ },
+ *EffectsMenu[]=
+ {
+ "Despeckle",
+ "Emboss",
+ "Reduce Noise",
+ "Add Noise",
+ "Sharpen...",
+ "Blur...",
+ "Threshold...",
+ "Edge Detect...",
+ "Spread...",
+ "Shade...",
+ "Raise...",
+ "Segment...",
+ (char *) NULL
+ },
+ *FXMenu[]=
+ {
+ "Solarize...",
+ "Swirl...",
+ "Implode...",
+ "Wave...",
+ "Oil Paint...",
+ "Charcoal Draw...",
+ (char *) NULL
+ },
+ *MiscellanyMenu[]=
+ {
+ "Image Info",
+ "Zoom Image",
+ "Show Preview...",
+ "Show Histogram",
+ "Show Matte",
+ (char *) NULL
+ };
+
+ static const char
+ **Menus[ApplyMenus]=
+ {
+ FileMenu,
+ EditMenu,
+ TransformMenu,
+ EnhanceMenu,
+ EffectsMenu,
+ FXMenu,
+ MiscellanyMenu
+ };
+
+ static const CommandType
+ ApplyCommands[]=
+ {
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ HelpCommand,
+ QuitCommand
+ },
+ FileCommands[]=
+ {
+ SaveCommand,
+ PrintCommand
+ },
+ EditCommands[]=
+ {
+ UndoCommand,
+ RedoCommand
+ },
+ TransformCommands[]=
+ {
+ FlopCommand,
+ FlipCommand,
+ RotateRightCommand,
+ RotateLeftCommand
+ },
+ EnhanceCommands[]=
+ {
+ HueCommand,
+ SaturationCommand,
+ BrightnessCommand,
+ GammaCommand,
+ SpiffCommand,
+ DullCommand,
+ EqualizeCommand,
+ NormalizeCommand,
+ NegateCommand,
+ GrayscaleCommand,
+ MapCommand,
+ QuantizeCommand
+ },
+ EffectsCommands[]=
+ {
+ DespeckleCommand,
+ EmbossCommand,
+ ReduceNoiseCommand,
+ AddNoiseCommand,
+ SharpenCommand,
+ BlurCommand,
+ EdgeDetectCommand,
+ SpreadCommand,
+ ShadeCommand,
+ RaiseCommand,
+ SegmentCommand
+ },
+ FXCommands[]=
+ {
+ SolarizeCommand,
+ SwirlCommand,
+ ImplodeCommand,
+ WaveCommand,
+ OilPaintCommand,
+ CharcoalDrawCommand
+ },
+ MiscellanyCommands[]=
+ {
+ InfoCommand,
+ ZoomCommand,
+ ShowPreviewCommand,
+ ShowHistogramCommand,
+ ShowMatteCommand
+ },
+ ROICommands[]=
+ {
+ ROIHelpCommand,
+ ROIDismissCommand
+ };
+
+ static const CommandType
+ *Commands[ApplyMenus]=
+ {
+ FileCommands,
+ EditCommands,
+ TransformCommands,
+ EnhanceCommands,
+ EffectsCommands,
+ FXCommands,
+ MiscellanyCommands
+ };
+
+ char
+ command[MaxTextExtent],
+ text[MaxTextExtent];
+
+ CommandType
+ command_type;
+
+ Cursor
+ cursor;
+
+ double
+ scale_factor;
+
+ Image
+ *roi_image;
+
+ int
+ entry,
+ id,
+ x,
+ y;
+
+ MonitorHandler
+ handler;
+
+ RectangleInfo
+ crop_info,
+ highlight_info,
+ roi_info;
+
+ unsigned int
+ height,
+ width;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"ROI");
+ windows->command.data=0;
+ (void) MagickXCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Track pointer until button 1 is pressed.
+ */
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask | PointerMotionMask);
+ roi_info.x=windows->image.x+x;
+ roi_info.y=windows->image.y+y;
+ roi_info.width=0;
+ roi_info.height=0;
+ cursor=XCreateFontCursor(display,XC_fleur);
+ state=DefaultState;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %+ld%+ld ",roi_info.x,roi_info.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,ROIMenu,&event);
+ if (id < 0)
+ continue;
+ switch (ROICommands[id])
+ {
+ case ROIHelpCommand:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Region of Interest",ImageROIHelp);
+ break;
+ }
+ case ROIDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ Note first corner of region of interest rectangle-- exit loop.
+ */
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ roi_info.x=windows->image.x+event.xbutton.x;
+ roi_info.y=windows->image.y+event.xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case ButtonRelease:
+ break;
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Region of Interest",ImageROIHelp);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ roi_info.x=windows->image.x+x;
+ roi_info.y=windows->image.y+y;
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ (void) XSelectInput(display,windows->image.id,
+ windows->image.attributes.event_mask);
+ if (state & EscapeState)
+ {
+ /*
+ User want to exit without region of interest.
+ */
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ (void) XFreeCursor(display,cursor);
+ return(True);
+ }
+ (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
+ do
+ {
+ /*
+ Size rectangle as pointer moves until the mouse button is released.
+ */
+ x=(int) roi_info.x;
+ y=(int) roi_info.y;
+ roi_info.width=0;
+ roi_info.height=0;
+ state=DefaultState;
+ do
+ {
+ highlight_info=roi_info;
+ highlight_info.x=roi_info.x-windows->image.x;
+ highlight_info.y=roi_info.y-windows->image.y;
+ if ((highlight_info.width > 3) && (highlight_info.height > 3))
+ {
+ /*
+ Display info and draw region of interest rectangle.
+ */
+ if (!windows->info.mapped)
+ (void) XMapWindow(display,windows->info.id);
+ FormatString(text," %lux%lu%+ld%+ld",roi_info.width,roi_info.height,
+ roi_info.x,roi_info.y);
+ MagickXInfoWidget(display,windows,text);
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ }
+ else
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if ((highlight_info.width > 3) && (highlight_info.height > 3))
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ roi_info.x=windows->image.x+event.xbutton.x;
+ roi_info.y=windows->image.y+event.xbutton.y;
+ break;
+ }
+ case ButtonRelease:
+ {
+ /*
+ User has committed to region of interest rectangle.
+ */
+ roi_info.x=windows->image.x+event.xbutton.x;
+ roi_info.y=windows->image.y+event.xbutton.y;
+ MagickXSetCursorState(display,windows,False);
+ state|=ExitState;
+ if (LocaleCompare(windows->command.name,"Apply") == 0)
+ break;
+ (void) CloneString(&windows->command.name,"Apply");
+ windows->command.data=ApplyMenus;
+ (void) MagickXCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
+ break;
+ }
+ case Expose:
+ break;
+ case MotionNotify:
+ {
+ roi_info.x=windows->image.x+event.xmotion.x;
+ roi_info.y=windows->image.y+event.xmotion.y;
+ }
+ default:
+ break;
+ }
+ if ((((int) roi_info.x != x) && ((int) roi_info.y != y)) ||
+ (state & ExitState))
+ {
+ /*
+ Check boundary conditions.
+ */
+ if (roi_info.x < 0)
+ roi_info.x=0;
+ else
+ if (roi_info.x > (int) windows->image.ximage->width)
+ roi_info.x=windows->image.ximage->width;
+ if ((int) roi_info.x < x)
+ roi_info.width=(unsigned int) (x-roi_info.x);
+ else
+ {
+ roi_info.width=(unsigned int) (roi_info.x-x);
+ roi_info.x=x;
+ }
+ if (roi_info.y < 0)
+ roi_info.y=0;
+ else
+ if (roi_info.y > (int) windows->image.ximage->height)
+ roi_info.y=windows->image.ximage->height;
+ if ((int) roi_info.y < y)
+ roi_info.height=(unsigned int) (y-roi_info.y);
+ else
+ {
+ roi_info.height=(unsigned int) (roi_info.y-y);
+ roi_info.y=y;
+ }
+ }
+ } while (!(state & ExitState));
+ /*
+ Wait for user to grab a corner of the rectangle or press return.
+ */
+ state=DefaultState;
+ command_type=NullCommand;
+ do
+ {
+ if (windows->info.mapped)
+ {
+ /*
+ Display pointer position.
+ */
+ FormatString(text," %lux%lu%+ld%+ld",roi_info.width,roi_info.height,
+ roi_info.x,roi_info.y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ highlight_info=roi_info;
+ highlight_info.x=roi_info.x-windows->image.x;
+ highlight_info.y=roi_info.y-windows->image.y;
+ if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
+ {
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ if (state & UpdateRegionState)
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ switch (command_type)
+ {
+ case UndoCommand:
+ case RedoCommand:
+ {
+ (void) MagickXMagickCommand(display,resource_info,windows,command_type,
+ image);
+ break;
+ }
+ default:
+ {
+ /*
+ Region of interest is relative to image configuration.
+ */
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ crop_info=roi_info;
+ width=(unsigned int) (*image)->columns;
+ height=(unsigned int) (*image)->rows;
+ x=0;
+ y=0;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
+ &width,&height);
+ scale_factor=(double) width/windows->image.ximage->width;
+ crop_info.x+=x;
+ crop_info.x=(int) (scale_factor*crop_info.x+0.5);
+ crop_info.width=(unsigned int) (scale_factor*crop_info.width+0.5);
+ scale_factor=(double) height/windows->image.ximage->height;
+ crop_info.y+=y;
+ crop_info.y=(int) (scale_factor*crop_info.y+0.5);
+ crop_info.height=(unsigned int)
+ (scale_factor*crop_info.height+0.5);
+ roi_image=CropImage(*image,&crop_info,&(*image)->exception);
+ (void) SetMonitorHandler(handler);
+ if (roi_image == (Image *) NULL)
+ continue;
+ /*
+ Apply image processing technique to the region of interest.
+ */
+ windows->image.orphan=True;
+ (void) MagickXMagickCommand(display,resource_info,windows,command_type,
+ &roi_image);
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ (void) MagickXMagickCommand(display,resource_info,windows,
+ SaveToUndoBufferCommand,image);
+ windows->image.orphan=False;
+ (void) CompositeImage(*image,CopyCompositeOp,roi_image,
+ crop_info.x,crop_info.y);
+ DestroyImage(roi_image);
+ (void) SetMonitorHandler(handler);
+ break;
+ }
+ }
+ if (command_type != InfoCommand)
+ {
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ }
+ MagickXCheckRefreshWindows(display,windows);
+ MagickXInfoWidget(display,windows,text);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ state&=(~UpdateRegionState);
+ }
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ MagickXScreenEvent(display,windows,&event);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ command_type=NullCommand;
+ id=MagickXCommandWidget(display,windows,ApplyMenu,&event);
+ if (id >= 0)
+ {
+ (void) strlcpy(command,ApplyMenu[id],MaxTextExtent);
+ command_type=ApplyCommands[id];
+ if (id < ApplyMenus)
+ {
+ /*
+ Select a command from a pop-up menu.
+ */
+ entry=MagickXMenuWidget(display,windows,ApplyMenu[id],
+ (const char **) Menus[id],command);
+ if (entry >= 0)
+ {
+ (void) strlcpy(command,Menus[id][entry],MaxTextExtent);
+ command_type=Commands[id][entry];
+ }
+ }
+ }
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ if (command_type == HelpCommand)
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Region of Interest",ImageROIHelp);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ continue;
+ }
+ if (command_type == QuitCommand)
+ {
+ /*
+ Exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ continue;
+ }
+ if (command_type != NullCommand)
+ state|=UpdateRegionState;
+ continue;
+ }
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ x=windows->image.x;
+ y=windows->image.y;
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ x=windows->image.x+event.xbutton.x;
+ y=windows->image.y+event.xbutton.y;
+ if ((x < (int) (roi_info.x+RoiDelta)) &&
+ (x > (int) (roi_info.x-RoiDelta)) &&
+ (y < (int) (roi_info.y+RoiDelta)) &&
+ (y > (int) (roi_info.y-RoiDelta)))
+ {
+ roi_info.x=(long) (roi_info.x+roi_info.width);
+ roi_info.y=(long) (roi_info.y+roi_info.height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ if ((x < (int) (roi_info.x+RoiDelta)) &&
+ (x > (int) (roi_info.x-RoiDelta)) &&
+ (y < (int) (roi_info.y+roi_info.height+RoiDelta)) &&
+ (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
+ {
+ roi_info.x=(long) (roi_info.x+roi_info.width);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ if ((x < (int) (roi_info.x+roi_info.width+RoiDelta)) &&
+ (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
+ (y < (int) (roi_info.y+RoiDelta)) &&
+ (y > (int) (roi_info.y-RoiDelta)))
+ {
+ roi_info.y=(long) (roi_info.y+roi_info.height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ if ((x < (int) (roi_info.x+roi_info.width+RoiDelta)) &&
+ (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
+ (y < (int) (roi_info.y+roi_info.height+RoiDelta)) &&
+ (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
+ {
+ state|=UpdateConfigurationState;
+ break;
+ }
+ }
+ case ButtonRelease:
+ {
+ if (event.xbutton.window == windows->pan.id)
+ if ((highlight_info.x != crop_info.x-windows->image.x) ||
+ (highlight_info.y != crop_info.y-windows->image.y))
+ MagickXHighlightRectangle(display,windows->image.id,
+ windows->image.highlight_context,&highlight_info);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window == windows->image.id)
+ if (event.xexpose.count == 0)
+ {
+ event.xexpose.x=(int) highlight_info.x;
+ event.xexpose.y=(int) highlight_info.y;
+ event.xexpose.width=(unsigned int) highlight_info.width;
+ event.xexpose.height=(unsigned int) highlight_info.height;
+ MagickXRefreshWindow(display,&windows->image,&event);
+ }
+ if (event.xexpose.window == windows->info.id)
+ if (event.xexpose.count == 0)
+ MagickXInfoWidget(display,windows,text);
+ break;
+ }
+ case KeyPress:
+ {
+ KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,
+ sizeof(command),&key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Shift_L:
+ case XK_Shift_R:
+ break;
+ case XK_Escape:
+ case XK_F20:
+ {
+ state|=EscapeState;
+ break;
+ }
+ case XK_Return:
+ {
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Region of Interest",ImageROIHelp);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ break;
+ }
+ default:
+ {
+ command_type=MagickXImageWindowCommand(display,resource_info,windows,
+ event.xkey.state,key_symbol,image);
+ if (command_type != NullCommand)
+ state|=UpdateRegionState;
+ break;
+ }
+ }
+ break;
+ }
+ case KeyRelease:
+ break;
+ case MotionNotify:
+ {
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ Map and unmap Info widget as text cursor crosses its boundaries.
+ */
+ x=event.xmotion.x;
+ y=event.xmotion.y;
+ if (windows->info.mapped)
+ {
+ if ((x < (int) (windows->info.x+windows->info.width)) &&
+ (y < (int) (windows->info.y+windows->info.height)))
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ }
+ else
+ if ((x > (int) (windows->info.x+windows->info.width)) ||
+ (y > (int) (windows->info.y+windows->info.height)))
+ (void) XMapWindow(display,windows->info.id);
+ break;
+ }
+ default:
+ break;
+ }
+ if (state & UpdateConfigurationState)
+ {
+ (void) XPutBackEvent(display,&event);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ break;
+ }
+ } while (!(state & ExitState));
+ } while (!(state & ExitState));
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ MagickXSetCursorState(display,windows,False);
+ if (state & EscapeState)
+ return(True);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X R o t a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXRotateImage rotates the X image. If the degrees parameter
+% if zero, the rotation angle is computed from the slope of a line drawn by
+% the user.
+%
+% The format of the MagickXRotateImage method is:
+%
+% unsigned int MagickXRotateImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,double degrees,Image **image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXRotateImage return True if the image is
+% rotate. False is returned is there is a memory shortage or if the
+% image fails to rotate.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o degrees: Specifies the number of degrees to rotate the image.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int MagickXRotateImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,double degrees,Image **image)
+{
+ static const char
+ *RotateMenu[]=
+ {
+ "Pixel Color",
+ "Direction",
+ "Help",
+ "Dismiss",
+ (char *) NULL
+ };
+
+ static ModeType
+ direction = HorizontalRotateCommand;
+
+ static const ModeType
+ DirectionCommands[]=
+ {
+ HorizontalRotateCommand,
+ VerticalRotateCommand
+ },
+ RotateCommands[]=
+ {
+ RotateColorCommand,
+ RotateDirectionCommand,
+ RotateHelpCommand,
+ RotateDismissCommand
+ };
+
+ static unsigned int
+ pen_id = 0;
+
+ char
+ command[MaxTextExtent],
+ text[MaxTextExtent];
+
+ double
+ normalized_degrees;
+
+ Image
+ *rotate_image;
+
+ int
+ id,
+ x,
+ y;
+
+ register int
+ i;
+
+ unsigned int
+ height,
+ rotations,
+ width;
+
+ if (degrees == 0.0)
+ {
+ unsigned int
+ distance;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ XSegment
+ rotate_info;
+
+ /*
+ Map Command widget.
+ */
+ (void) CloneString(&windows->command.name,"Rotate");
+ windows->command.data=2;
+ (void) MagickXCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_widget,CurrentTime);
+ /*
+ Wait for first button press.
+ */
+ (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
+ MagickXQueryPosition(display,windows->image.id,&x,&y);
+ rotate_info.x1=x;
+ rotate_info.y1=y;
+ rotate_info.x2=x;
+ rotate_info.y2=y;
+ state=DefaultState;
+ do
+ {
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&rotate_info);
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&rotate_info);
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,RotateMenu,&event);
+ if (id < 0)
+ continue;
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ switch (RotateCommands[id])
+ {
+ case RotateColorCommand:
+ {
+ char
+ *ColorMenu[MaxNumberPens];
+
+ int
+ pen_number;
+
+ XColor
+ color;
+
+ /*
+ Initialize menu selections.
+ */
+ for (i=0; i < (int) (MaxNumberPens-2); i++)
+ ColorMenu[i]=resource_info->pen_colors[i];
+ ColorMenu[MaxNumberPens-2]=(char *) "Browser...";
+ ColorMenu[MaxNumberPens-1]=(char *) NULL;
+ /*
+ Select a pen color from the pop-up menu.
+ */
+ pen_number=MagickXMenuWidget(display,windows,RotateMenu[id],
+ (const char **) ColorMenu,command);
+ if (pen_number < 0)
+ break;
+ if (pen_number == (MaxNumberPens-2))
+ {
+ static char
+ color_name[MaxTextExtent] = "gray";
+
+ /*
+ Select a pen color from a dialog.
+ */
+ resource_info->pen_colors[pen_number]=color_name;
+ MagickXColorBrowserWidget(display,windows,"Select",color_name);
+ if (*color_name == '\0')
+ break;
+ }
+ /*
+ Set pen color.
+ */
+ (void) XParseColor(display,windows->map_info->colormap,
+ resource_info->pen_colors[pen_number],&color);
+ MagickXBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
+ (unsigned int) MaxColors,&color);
+ windows->pixel_info->pen_colors[pen_number]=color;
+ pen_id=pen_number;
+ break;
+ }
+ case RotateDirectionCommand:
+ {
+ static const char
+ *Directions[]=
+ {
+ "horizontal",
+ "vertical",
+ (char *) NULL,
+ };
+
+ /*
+ Select a command from the pop-up menu.
+ */
+ id=MagickXMenuWidget(display,windows,RotateMenu[id],
+ Directions,command);
+ if (id >= 0)
+ direction=DirectionCommands[id];
+ break;
+ }
+ case RotateHelpCommand:
+ {
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Rotation",ImageRotateHelp);
+ break;
+ }
+ case RotateDismissCommand:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ default:
+ break;
+ }
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.button != Button1)
+ break;
+ if (event.xbutton.window != windows->image.id)
+ break;
+ /*
+ Exit loop.
+ */
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ rotate_info.x1=event.xbutton.x;
+ rotate_info.y1=event.xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case ButtonRelease:
+ break;
+ case Expose:
+ break;
+ case KeyPress:
+ {
+ char
+ command[MaxTextExtent];
+
+ KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->image.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,
+ sizeof(command),&key_symbol,(XComposeStatus *) NULL);
+ switch ((int) key_symbol)
+ {
+ case XK_Escape:
+ case XK_F20:
+ {
+ /*
+ Prematurely exit.
+ */
+ state|=EscapeState;
+ state|=ExitState;
+ break;
+ }
+ case XK_F1:
+ case XK_Help:
+ {
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXcopy);
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Rotation",ImageRotateHelp);
+ (void) XSetFunction(display,windows->image.highlight_context,
+ GXinvert);
+ break;
+ }
+ default:
+ {
+ (void) XBell(display,0);
+ break;
+ }
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ rotate_info.x1=event.xmotion.x;
+ rotate_info.y1=event.xmotion.y;
+ }
+ }
+ rotate_info.x2=rotate_info.x1;
+ rotate_info.y2=rotate_info.y1;
+ if (direction == HorizontalRotateCommand)
+ rotate_info.x2+=32;
+ else
+ rotate_info.y2-=32;
+ } while (!(state & ExitState));
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (state & EscapeState)
+ return(True);
+ /*
+ Draw line as pointer moves until the mouse button is released.
+ */
+ distance=0;
+ (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
+ state=DefaultState;
+ do
+ {
+ if (distance > 9)
+ {
+ /*
+ Display info and draw rotation line.
+ */
+ if (!windows->info.mapped)
+ (void) XMapWindow(display,windows->info.id);
+ FormatString(text," %.2f",
+ direction == VerticalRotateCommand ? degrees-90.0 : degrees);
+ MagickXInfoWidget(display,windows,text);
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&rotate_info);
+ }
+ else
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ /*
+ Wait for next event.
+ */
+ MagickXScreenEvent(display,windows,&event);
+ if (distance > 9)
+ MagickXHighlightLine(display,windows->image.id,
+ windows->image.highlight_context,&rotate_info);
+ switch (event.type)
+ {
+ case ButtonPress:
+ break;
+ case ButtonRelease:
+ {
+ /*
+ User has committed to rotation line.
+ */
+ rotate_info.x2=event.xbutton.x;
+ rotate_info.y2=event.xbutton.y;
+ state|=ExitState;
+ break;
+ }
+ case Expose:
+ break;
+ case MotionNotify:
+ {
+ rotate_info.x2=event.xmotion.x;
+ rotate_info.y2=event.xmotion.y;
+ }
+ default:
+ break;
+ }
+ /*
+ Check boundary conditions.
+ */
+ if (rotate_info.x2 < 0)
+ rotate_info.x2=0;
+ else
+ if (rotate_info.x2 > (int) windows->image.width)
+ rotate_info.x2=windows->image.width;
+ if (rotate_info.y2 < 0)
+ rotate_info.y2=0;
+ else
+ if (rotate_info.y2 > (int) windows->image.height)
+ rotate_info.y2=windows->image.height;
+ /*
+ Compute rotation angle from the slope of the line.
+ */
+ degrees=0.0;
+ distance=
+ ((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
+ ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1));
+ if (distance > 9)
+ degrees=RadiansToDegrees(-atan2((double) (rotate_info.y2-
+ rotate_info.y1),(double) (rotate_info.x2-rotate_info.x1)));
+ } while (!(state & ExitState));
+ (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (distance <= 9)
+ return(True);
+ }
+ if (direction == VerticalRotateCommand)
+ degrees-=90.0;
+ if (degrees == 0.0)
+ return(True);
+ /*
+ Rotate image.
+ */
+ normalized_degrees=degrees;
+ while (normalized_degrees < -45.0)
+ normalized_degrees+=360.0;
+ for (rotations=0; normalized_degrees > 45.0; rotations++)
+ normalized_degrees-=90.0;
+ if (normalized_degrees != 0.0)
+ (void) MagickXMagickCommand(display,resource_info,windows,ApplyCommand,image);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (*image)->background_color.red=
+ ScaleShortToQuantum(windows->pixel_info->pen_colors[pen_id].red);
+ (*image)->background_color.green=
+ ScaleShortToQuantum(windows->pixel_info->pen_colors[pen_id].green);
+ (*image)->background_color.blue=
+ ScaleShortToQuantum(windows->pixel_info->pen_colors[pen_id].blue);
+ rotate_image=RotateImage(*image,degrees,&(*image)->exception);
+ MagickXSetCursorState(display,windows,False);
+ if (rotate_image == (Image *) NULL)
+ return(False);
+ DestroyImage(*image);
+ *image=rotate_image;
+ if (windows->image.crop_geometry != (char *) NULL)
+ {
+ /*
+ Rotate crop geometry.
+ */
+ width=(unsigned int) (*image)->columns;
+ height=(unsigned int) (*image)->rows;
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ switch (rotations % 4)
+ {
+ default:
+ case 0:
+ break;
+ case 1:
+ {
+ /*
+ Rotate 90 degrees.
+ */
+ FormatString(windows->image.crop_geometry,"%ux%u%+d%+d",
+ height,width,(int) (*image)->columns-(int) height-y,x);
+ break;
+ }
+ case 2:
+ {
+ /*
+ Rotate 180 degrees.
+ */
+ FormatString(windows->image.crop_geometry,"%ux%u%+d%+d",
+ width,height,(int) width-x,(int) height-y);
+ break;
+ }
+ case 3:
+ {
+ /*
+ Rotate 270 degrees.
+ */
+ FormatString(windows->image.crop_geometry,"%ux%u%+d%+d",
+ height,width,y,(int) (*image)->rows-(int) width-x);
+ break;
+ }
+ }
+ }
+ if (windows->image.orphan)
+ return(True);
+ if (normalized_degrees != 0.0)
+ {
+ /*
+ Update image colormap.
+ */
+ windows->image.window_changes.width=(unsigned int) (*image)->columns;
+ windows->image.window_changes.height=(unsigned int) (*image)->rows;
+ if (windows->image.crop_geometry != (char *) NULL)
+ {
+ /*
+ Obtain dimensions of image from crop geometry.
+ */
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
+ &width,&height);
+ windows->image.window_changes.width=width;
+ windows->image.window_changes.height=height;
+ }
+ MagickXConfigureImageColormap(display,resource_info,windows,*image);
+ }
+ else
+ if (((rotations % 4) == 1) || ((rotations % 4) == 3))
+ {
+ windows->image.window_changes.width=windows->image.ximage->height;
+ windows->image.window_changes.height=windows->image.ximage->width;
+ }
+ /*
+ Update image configuration.
+ */
+ (void) MagickXConfigureImage(display,resource_info,windows,*image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X S a v e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXSaveImage saves an image to a file.
+%
+% The format of the MagickXSaveImage method is:
+%
+% unsigned int MagickXSaveImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXSaveImage return True if the image is
+% written. False is returned is there is a memory shortage or if the
+% image fails to write.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static unsigned int MagickXSaveImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *image)
+{
+ char
+ filename[MaxTextExtent],
+ geometry[MaxTextExtent];
+
+ Image
+ *save_image;
+
+ ImageInfo
+ *image_info;
+
+ int
+ status;
+
+ /*
+ Request file name from user.
+ */
+ if (resource_info->write_filename != (char *) NULL)
+ (void) strlcpy(filename,resource_info->write_filename,MaxTextExtent);
+ else
+ {
+ char
+ path[MaxTextExtent];
+
+ GetPathComponent(image->filename,HeadPath,path);
+ GetPathComponent(image->filename,TailPath,filename);
+ if ((strlen(path) > 0) && (chdir(path) != 0))
+ MagickXNoticeWidget(display,windows,"Unable to change to directory:",
+ path);
+ }
+ MagickXFileBrowserWidget(display,windows,"Save",filename);
+ if (*filename == '\0')
+ return(True);
+ if (IsAccessible(filename))
+ {
+ /*
+ File exists-- seek user's permission before overwriting.
+ */
+ status=MagickXConfirmWidget(display,windows,"Overwrite",filename);
+ if (status <= 0)
+ return(True);
+ }
+ image_info=CloneImageInfo(resource_info->image_info);
+ (void) strlcpy(image_info->filename,filename,MaxTextExtent);
+ (void) SetImageInfo(image_info,SETMAGICK_WRITE,&image->exception);
+ if ((LocaleCompare(image_info->magick,"JPEG") == 0) ||
+ (LocaleCompare(image_info->magick,"JPG") == 0))
+ {
+ char
+ quality[MaxTextExtent];
+
+ /*
+ Request JPEG quality from user.
+ */
+ FormatString(quality,"%lu",image_info->quality);
+ status=MagickXDialogWidget(display,windows,"Save","Enter JPEG quality:",
+ quality);
+ if (*quality == '\0')
+ return(True);
+ image_info->quality=MagickAtoL(quality);
+ image_info->interlace=status ? NoInterlace : PlaneInterlace;
+ }
+ if ((LocaleCompare(image_info->magick,"EPS") == 0) ||
+ (LocaleCompare(image_info->magick,"PDF") == 0) ||
+ (LocaleCompare(image_info->magick,"PS") == 0) ||
+ (LocaleCompare(image_info->magick,"PS2") == 0))
+ {
+ char
+ geometry[MaxTextExtent];
+
+ /*
+ Request page geometry from user.
+ */
+ FormatString(geometry,"%.1024s",PSPageGeometry);
+ if (LocaleCompare(image_info->magick,"PDF") == 0)
+ FormatString(geometry,"%.1024s",PSPageGeometry);
+ if (image_info->page != (char *) NULL)
+ (void) strlcpy(geometry,image_info->page,MaxTextExtent);
+ MagickXListBrowserWidget(display,windows,&windows->widget,PageSizes,"Select",
+ "Select page geometry:",geometry);
+ if (*geometry != '\0')
+ image_info->page=GetPageGeometry(geometry);
+ }
+ /*
+ Apply image transforms.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ save_image=CloneImage(image,0,0,True,&image->exception);
+ if (save_image == (Image *) NULL)
+ return(False);
+ FormatString(geometry,"%dx%d!",windows->image.ximage->width,
+ windows->image.ximage->height);
+ TransformImage(&save_image,windows->image.crop_geometry,geometry);
+ /*
+ Write image.
+ */
+ (void) strlcpy(save_image->filename,filename,MaxTextExtent);
+ status=WriteImage(image_info,save_image);
+ if (status != MagickFail)
+ image->taint=False;
+ else
+ CopyException(&image->exception,&save_image->exception);
+ DestroyImage(save_image);
+ DestroyImageInfo(image_info);
+ MagickXSetCursorState(display,windows,False);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X S c r e e n E v e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXScreenEvent handles global events associated with the Pan and
+% Magnify windows.
+%
+% The format of the MagickXScreenEvent function is:
+%
+% void MagickXScreenEvent(Display *display,MagickXWindows *windows,XEvent *event)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o event: Specifies a pointer to a X11 XEvent structure.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int MagickXPredicate(Display *display,XEvent *event,char *data)
+{
+ register MagickXWindows
+ *windows;
+
+ ARG_NOT_USED(display);
+ windows=(MagickXWindows *) data;
+ if ((event->type == ClientMessage) &&
+ (event->xclient.window == windows->image.id))
+ return(False);
+ return(True);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+static void MagickXScreenEvent(Display *display,MagickXWindows *windows,XEvent *event)
+{
+ MonitorHandler
+ handler;
+
+ register int
+ x,
+ y;
+
+ (void) XIfEvent(display,event,MagickXPredicate,(char *) windows);
+ if (event->xany.window == windows->command.id)
+ return;
+ switch (event->type)
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ if ((event->xbutton.button == Button3) &&
+ (event->xbutton.state & Mod1Mask))
+ {
+ /*
+ Convert Alt-Button3 to Button2.
+ */
+ event->xbutton.button=Button2;
+ event->xbutton.state&=(~Mod1Mask);
+ }
+ if (event->xbutton.window == windows->backdrop.id)
+ {
+ (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
+ event->xbutton.time);
+ break;
+ }
+ if (event->xbutton.window == windows->pan.id)
+ {
+ MagickXPanImage(display,windows,event);
+ break;
+ }
+ if (event->xbutton.window == windows->image.id)
+ if (event->xbutton.button == Button2)
+ {
+ /*
+ Update magnified image.
+ */
+ x=event->xbutton.x;
+ y=event->xbutton.y;
+ if (x < 0)
+ x=0;
+ else
+ if (x >= (int) windows->image.width)
+ x=windows->image.width-1;
+ windows->magnify.x=windows->image.x+x;
+ if (y < 0)
+ y=0;
+ else
+ if (y >= (int) windows->image.height)
+ y=windows->image.height-1;
+ windows->magnify.y=windows->image.y+y;
+ if (!windows->magnify.mapped)
+ (void) XMapRaised(display,windows->magnify.id);
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ MagickXMakeMagnifyImage(display,windows);
+ (void) SetMonitorHandler(handler);
+ if (event->type == ButtonRelease)
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ break;
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event->xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event->xclient.data.l != (long) windows->wm_delete_window)
+ break;
+ if (event->xclient.window == windows->magnify.id)
+ {
+ (void) XWithdrawWindow(display,windows->magnify.id,
+ windows->magnify.screen);
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ if (event->xconfigure.window == windows->magnify.id)
+ {
+ unsigned int
+ magnify;
+
+ /*
+ Magnify window has a new configuration.
+ */
+ windows->magnify.width=event->xconfigure.width;
+ windows->magnify.height=event->xconfigure.height;
+ if (!windows->magnify.mapped)
+ break;
+ magnify=1;
+ while ((int) magnify <= event->xconfigure.width)
+ magnify<<=1;
+ while ((int) magnify <= event->xconfigure.height)
+ magnify<<=1;
+ magnify>>=1;
+ if (((int) magnify != event->xconfigure.width) ||
+ ((int) magnify != event->xconfigure.height))
+ {
+ XWindowChanges
+ window_changes;
+
+ window_changes.width=magnify;
+ window_changes.height=magnify;
+ (void) XReconfigureWMWindow(display,windows->magnify.id,
+ windows->magnify.screen,CWWidth | CWHeight,&window_changes);
+ break;
+ }
+ MagickXMakeMagnifyImage(display,windows);
+ break;
+ }
+ break;
+ }
+ case Expose:
+ {
+ if (event->xexpose.window == windows->image.id)
+ {
+ MagickXRefreshWindow(display,&windows->image,event);
+ break;
+ }
+ if (event->xexpose.window == windows->pan.id)
+ if (event->xexpose.count == 0)
+ {
+ MagickXDrawPanRectangle(display,windows);
+ break;
+ }
+ if (event->xexpose.window == windows->magnify.id)
+ if (event->xexpose.count == 0)
+ {
+ MagickXMakeMagnifyImage(display,windows);
+ break;
+ }
+ break;
+ }
+ case KeyPress:
+ {
+ char
+ command[MaxTextExtent];
+
+ KeySym
+ key_symbol;
+
+ if (event->xkey.window != windows->magnify.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event->xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ MagickXMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol);
+ break;
+ }
+ case MapNotify:
+ {
+ if (event->xmap.window == windows->magnify.id)
+ {
+ windows->magnify.mapped=True;
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ break;
+ }
+ if (event->xmap.window == windows->info.id)
+ {
+ windows->info.mapped=True;
+ break;
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+ while (XCheckMaskEvent(display,ButtonMotionMask,event));
+ if (event->xmotion.window == windows->image.id)
+ if (windows->magnify.mapped)
+ {
+ /*
+ Update magnified image.
+ */
+ x=event->xmotion.x;
+ y=event->xmotion.y;
+ if (x < 0)
+ x=0;
+ else
+ if (x >= (int) windows->image.width)
+ x=windows->image.width-1;
+ windows->magnify.x=windows->image.x+x;
+ if (y < 0)
+ y=0;
+ else
+ if (y >= (int) windows->image.height)
+ y=windows->image.height-1;
+ windows->magnify.y=windows->image.y+y;
+ MagickXMakeMagnifyImage(display,windows);
+ }
+ break;
+ }
+ case UnmapNotify:
+ {
+ if (event->xunmap.window == windows->magnify.id)
+ {
+ windows->magnify.mapped=False;
+ break;
+ }
+ if (event->xunmap.window == windows->info.id)
+ {
+ windows->info.mapped=False;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X S e t C r o p G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXSetCropGeometry accepts a cropping geometry relative to the
+% Image window and translates it to a cropping geometry relative to the
+% image.
+%
+% The format of the MagickXSetCropGeometry method is:
+%
+% void MagickXSetCropGeometry(Display *display,MagickXWindows *windows,
+% RectangleInfo *crop_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o crop_info: A pointer to a RectangleInfo that defines a region of the
+% Image window to crop.
+%
+% o image: Specifies a pointer to an Image structure.
+%
+%
+*/
+static void MagickXSetCropGeometry(Display *display,MagickXWindows *windows,
+ RectangleInfo *crop_info,Image *image)
+{
+ char
+ text[MaxTextExtent];
+
+ double
+ scale_factor;
+
+ int
+ x,
+ y;
+
+ unsigned int
+ height,
+ width;
+
+ if (windows->info.mapped)
+ {
+ /*
+ Display info on cropping rectangle.
+ */
+ FormatString(text," %lux%lu%+ld%+ld",crop_info->width,crop_info->height,
+ crop_info->x,crop_info->y);
+ MagickXInfoWidget(display,windows,text);
+ }
+ /*
+ Cropping geometry is relative to any previous crop geometry.
+ */
+ x=0;
+ y=0;
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ else
+ windows->image.crop_geometry=AllocateString((char *) NULL);
+ /*
+ Define the crop geometry string from the cropping rectangle.
+ */
+ scale_factor=(double) width/windows->image.ximage->width;
+ if (crop_info->x > 0)
+ x+=(int) (scale_factor*crop_info->x+0.5);
+ width=(unsigned int) (scale_factor*crop_info->width+0.5);
+ if (width == 0)
+ width=1;
+ scale_factor=(double) height/windows->image.ximage->height;
+ if (crop_info->y > 0)
+ y+=(int) (scale_factor*crop_info->y+0.5);
+ height=(unsigned int) (scale_factor*crop_info->height+0.5);
+ if (height == 0)
+ height=1;
+ FormatString(windows->image.crop_geometry,"%ux%u%+d%+d",width,height,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X T i l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXTileImage loads or deletes a selected tile from a visual
+% image directory. The load or delete command is chosen from a menu.
+%
+% The format of the MagickXTileImage method is:
+%
+% Image *MagickXTileImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image *image,XEvent *event)
+%
+% A description of each parameter follows:
+%
+% o tile_image: MagickXTileImage reads or deletes the tile image
+% and returns it. A null image is returned if an error occurs.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o event: Specifies a pointer to a XEvent structure. If it is NULL,
+% the entire image is refreshed.
+%
+%
+*/
+static Image *MagickXTileImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *image,XEvent *event)
+{
+ static const char
+ *VerbMenu[]=
+ {
+ "Load",
+ "Next",
+ "Former",
+ "Delete",
+ "Update",
+ (char *) NULL,
+ };
+
+ static const ModeType
+ TileCommands[]=
+ {
+ TileLoadCommand,
+ TileNextCommand,
+ TileFormerCommand,
+ TileDeleteCommand,
+ TileUpdateCommand
+ };
+
+ char
+ command[MaxTextExtent],
+ filename[MaxTextExtent];
+
+ double
+ scale_factor;
+
+ Image
+ *tile_image;
+
+ int
+ id,
+ status,
+ tile,
+ x,
+ y;
+
+ register char
+ *p,
+ *q;
+
+ register int
+ i;
+
+ unsigned int
+ height,
+ width;
+
+ /*
+ Tile image is relative to montage image configuration.
+ */
+ x=0;
+ y=0;
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
+ scale_factor=(double) width/windows->image.ximage->width;
+ event->xbutton.x+=windows->image.x;
+ event->xbutton.x=(int) (scale_factor*event->xbutton.x+x+0.5);
+ scale_factor=(double) height/windows->image.ximage->height;
+ event->xbutton.y+=windows->image.y;
+ event->xbutton.y=(int) (scale_factor*event->xbutton.y+y+0.5);
+ /*
+ Determine size and location of each tile in the visual image directory.
+ */
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ x=0;
+ y=0;
+ (void) XParseGeometry(image->montage,&x,&y,&width,&height);
+ tile=((event->xbutton.y-y)/height)*(((int) image->columns-x)/width)+
+ (event->xbutton.x-x)/width;
+ if (tile < 0)
+ {
+ /*
+ Button press is outside any tile.
+ */
+ (void) XBell(display,0);
+ return((Image *) NULL);
+ }
+ /*
+ Determine file name from the tile directory.
+ */
+ p=image->directory;
+ for (i=tile; (i != 0) && (*p != '\0'); )
+ {
+ if (*p == '\n')
+ i--;
+ p++;
+ }
+ if (*p == '\0')
+ {
+ /*
+ Button press is outside any tile.
+ */
+ (void) XBell(display,0);
+ return((Image *) NULL);
+ }
+ /*
+ Select a command from the pop-up menu.
+ */
+ id=MagickXMenuWidget(display,windows,"Tile Verb",VerbMenu,command);
+ if (id < 0)
+ return((Image *) NULL);
+ q=p;
+ while ((*q != '\n') && (*q != '\0'))
+ q++;
+ (void) strncpy(filename,p,q-p);
+ filename[q-p]='\0';
+ /*
+ Perform command for the selected tile.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ tile_image=(Image *) NULL;
+ switch (TileCommands[id])
+ {
+ case TileLoadCommand:
+ {
+ /*
+ Load tile image.
+ */
+ MagickXCheckRefreshWindows(display,windows);
+ (void) strcpy(resource_info->image_info->magick,"MIFF");
+ (void) strlcpy(resource_info->image_info->filename,filename,
+ MaxTextExtent);
+ tile_image=ReadImage(resource_info->image_info,&image->exception);
+ if (image->exception.severity != UndefinedException)
+ MagickError2(image->exception.severity,image->exception.reason,
+ image->exception.description);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ break;
+ }
+ case TileNextCommand:
+ {
+ /*
+ Display next image.
+ */
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ break;
+ }
+ case TileFormerCommand:
+ {
+ /*
+ Display former image.
+ */
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_former_image,CurrentTime);
+ break;
+ }
+ case TileDeleteCommand:
+ {
+ /*
+ Delete tile image.
+ */
+ if (!IsAccessible(filename))
+ {
+ MagickXNoticeWidget(display,windows,"Image file does not exist:",filename);
+ break;
+ }
+ status=MagickXConfirmWidget(display,windows,"Really delete tile",filename);
+ if (status <= 0)
+ break;
+ status=remove(filename);
+ if (status != False)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to delete image file:",
+ filename);
+ break;
+ }
+ }
+ case TileUpdateCommand:
+ {
+ int
+ x_offset,
+ y_offset;
+
+ PixelPacket
+ pixel;
+
+ register int
+ j;
+
+ register PixelPacket
+ *s;
+
+ /*
+ Ensure all the images exist.
+ */
+ tile=0;
+ for (p=image->directory; *p != '\0'; p++)
+ {
+ q=p;
+ while ((*q != '\n') && (*q != '\0'))
+ q++;
+ (void) strncpy(filename,p,q-p);
+ filename[q-p]='\0';
+ p=q;
+ if (IsAccessible(filename))
+ {
+ tile++;
+ continue;
+ }
+ /*
+ Overwrite tile with background color.
+ */
+ x_offset=width*(tile % (((int) image->columns-x)/width))+x;
+ y_offset=height*(tile/(((int) image->columns-x)/width))+y;
+ (void) AcquireOnePixelByReference(image,&pixel,0,0,&image->exception);
+ for (i=0; i < (int) height; i++)
+ {
+ s=GetImagePixels(image,x_offset,y_offset+i,width,1);
+ if (s == (PixelPacket *) NULL)
+ break;
+ for (j=0; j < (int) width; j++)
+ *s++=pixel;
+ if (!SyncImagePixels(image))
+ break;
+ }
+ tile++;
+ }
+ windows->image.window_changes.width=(unsigned int) image->columns;
+ windows->image.window_changes.height=(unsigned int) image->rows;
+ MagickXConfigureImageColormap(display,resource_info,windows,image);
+ (void) MagickXConfigureImage(display,resource_info,windows,image);
+ break;
+ }
+ default:
+ break;
+ }
+ MagickXSetCursorState(display,windows,False);
+ return(tile_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X T r a n s l a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXTranslateImage translates the image within an Image window
+% by one pixel as specified by the key symbol. If the image has a `montage'
+% string the translation is respect to the width and height contained within
+% the string.
+%
+% The format of the MagickXTranslateImage method is:
+%
+% void MagickXTranslateImage(Display *display,MagickXWindows *windows,
+% Image *image,const KeySym key_symbol)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o key_symbol: Specifies a KeySym which indicates which side of the image
+% to trim.
+%
+%
+*/
+static void MagickXTranslateImage(Display *display,MagickXWindows *windows,
+ Image *image,const KeySym key_symbol)
+{
+ char
+ text[MaxTextExtent];
+
+ int
+ x,
+ y;
+
+ unsigned int
+ x_offset,
+ y_offset;
+
+ /*
+ User specified a pan position offset.
+ */
+ x_offset=windows->image.width;
+ y_offset=windows->image.height;
+ if (image->montage != (char *) NULL)
+ (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
+ switch ((int) key_symbol)
+ {
+ case XK_Home:
+ case XK_KP_Home:
+ {
+ windows->image.x=windows->image.width/2;
+ windows->image.y=windows->image.height/2;
+ break;
+ }
+ case XK_Left:
+ case XK_KP_Left:
+ {
+ windows->image.x-=x_offset;
+ break;
+ }
+ case XK_Next:
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ windows->image.y-=y_offset;
+ break;
+ }
+ case XK_Right:
+ case XK_KP_Right:
+ {
+ windows->image.x+=x_offset;
+ break;
+ }
+ case XK_Prior:
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ windows->image.y+=y_offset;
+ break;
+ }
+ default:
+ return;
+ }
+ /*
+ Check boundary conditions.
+ */
+ if (windows->image.x < 0)
+ windows->image.x=0;
+ else
+ if ((int) (windows->image.x+windows->image.width) >
+ windows->image.ximage->width)
+ windows->image.x=windows->image.ximage->width-windows->image.width;
+ if (windows->image.y < 0)
+ windows->image.y=0;
+ else
+ if ((int) (windows->image.y+windows->image.height) >
+ windows->image.ximage->height)
+ windows->image.y=windows->image.ximage->height-windows->image.height;
+ /*
+ Refresh Image window.
+ */
+ FormatString(text," %ux%u%+d%+d ",windows->image.width,
+ windows->image.height,windows->image.x,windows->image.y);
+ MagickXInfoWidget(display,windows,text);
+ MagickXCheckRefreshWindows(display,windows);
+ MagickXDrawPanRectangle(display,windows);
+ MagickXRefreshWindow(display,&windows->image,(XEvent *) NULL);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X T r i m I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXTrimImage trims the edges from the Image window.
+%
+% The format of the MagickXTrimImage method is:
+%
+% unsigned int MagickXTrimImage(Display *display,MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXTrimImage returns True if the image is
+% cropped. False is returned is there is a memory shortage or if the
+% image fails to be cropped.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure.
+%
+%
+*/
+static unsigned int MagickXTrimImage(Display *display,MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *image)
+{
+ RectangleInfo
+ trim_info;
+
+ register int
+ x,
+ y;
+
+ unsigned long
+ background,
+ pixel;
+
+ /*
+ Trim edges from image.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ /*
+ Crop the left edge.
+ */
+ background=XGetPixel(windows->image.ximage,0,0);
+ trim_info.width=windows->image.ximage->width;
+ for (x=0; x < windows->image.ximage->width; x++)
+ {
+ for (y=0; y < windows->image.ximage->height; y++)
+ {
+ pixel=XGetPixel(windows->image.ximage,x,y);
+ if (pixel != background)
+ break;
+ }
+ if (y < windows->image.ximage->height)
+ break;
+ }
+ trim_info.x=x;
+ if (trim_info.x == (int) windows->image.ximage->width)
+ {
+ MagickXSetCursorState(display,windows,False);
+ return(False);
+ }
+ /*
+ Crop the right edge.
+ */
+ background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
+ for (x=windows->image.ximage->width-1; x > 0; x--)
+ {
+ for (y=0; y < windows->image.ximage->height; y++)
+ {
+ pixel=XGetPixel(windows->image.ximage,x,y);
+ if (pixel != background)
+ break;
+ }
+ if (y < windows->image.ximage->height)
+ break;
+ }
+ trim_info.width=x-trim_info.x+1;
+ /*
+ Crop the top edge.
+ */
+ background=XGetPixel(windows->image.ximage,0,0);
+ trim_info.height=windows->image.ximage->height;
+ for (y=0; y < windows->image.ximage->height; y++)
+ {
+ for (x=0; x < windows->image.ximage->width; x++)
+ {
+ pixel=XGetPixel(windows->image.ximage,x,y);
+ if (pixel != background)
+ break;
+ }
+ if (x < windows->image.ximage->width)
+ break;
+ }
+ trim_info.y=y;
+ /*
+ Crop the bottom edge.
+ */
+ background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
+ for (y=windows->image.ximage->height-1; y > 0; y--)
+ {
+ for (x=0; x < windows->image.ximage->width; x++)
+ {
+ pixel=XGetPixel(windows->image.ximage,x,y);
+ if (pixel != background)
+ break;
+ }
+ if (x < windows->image.ximage->width)
+ break;
+ }
+ trim_info.height=y-trim_info.y+1;
+ if (((unsigned int) trim_info.width != windows->image.width) ||
+ ((unsigned int) trim_info.height != windows->image.height))
+ {
+ /*
+ Reconfigure Image window as defined by the trimming rectangle.
+ */
+ MagickXSetCropGeometry(display,windows,&trim_info,image);
+ windows->image.window_changes.width=(unsigned int) trim_info.width;
+ windows->image.window_changes.height=(unsigned int) trim_info.height;
+ (void) MagickXConfigureImage(display,resource_info,windows,image);
+ }
+ MagickXSetCursorState(display,windows,False);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X V i s u a l D i r e c t o r y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXVisualDirectoryImage creates a Visual Image Directory.
+%
+% The format of the MagickXVisualDirectoryImage method is:
+%
+% Image *MagickXVisualDirectoryImage(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows)
+%
+% A description of each parameter follows:
+%
+% o nexus: Method MagickXVisualDirectoryImage returns a visual image
+% directory if it can be created successfully. Otherwise a null image
+% is returned.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+%
+*/
+static Image *MagickXVisualDirectoryImage(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows)
+{
+#define TileImageText " Scale image tiles... "
+#define XClientName "montage"
+
+ char
+ **filelist,
+ window_id[MaxTextExtent];
+
+ ExceptionInfo
+ exception;
+
+ Image
+ *image,
+ *montage_image,
+ *next_image,
+ *thumbnail_image;
+
+ ImageInfo
+ *clone_info;
+
+ int
+ number_files;
+
+ MonitorHandler
+ handler;
+
+ MontageInfo
+ *montage_info;
+
+ RectangleInfo
+ geometry;
+
+ register int
+ i;
+
+ static char
+ filename[MaxTextExtent] = "\0",
+ filenames[MaxTextExtent] = "*";
+
+ unsigned int
+ backdrop,
+ status;
+
+ MagickXResourceInfo
+ background_resources;
+
+ /*
+ Request file name from user.
+ */
+ MagickXFileBrowserWidget(display,windows,"Directory",filenames);
+ if (*filenames == '\0')
+ return((Image *) NULL);
+ /*
+ Expand the filenames.
+ */
+ filelist=MagickAllocateMemory(char **,sizeof(char *));
+ if (filelist == (char **) NULL)
+ {
+ MagickError(ResourceLimitError,MemoryAllocationFailed,(char *) NULL);
+ return((Image *) NULL);
+ }
+ number_files=1;
+ filelist[0]=filenames;
+ status=ExpandFilenames(&number_files,&filelist);
+ if ((status == False) || (number_files == 0))
+ {
+ if (number_files == 0)
+ MagickError(ImageError,NoImagesWereFound,filenames);
+ else
+ MagickError(ResourceLimitError,MemoryAllocationFailed,filenames);
+ for (i=0; i < number_files; i++)
+ if (filelist[i] != filenames)
+ MagickFreeMemory(filelist[i]);
+ MagickFreeMemory(filelist);
+ return((Image *) NULL);
+ }
+ /*
+ Set image background resources.
+ */
+ background_resources=(*resource_info);
+ background_resources.window_id=window_id;
+ FormatString(background_resources.window_id,"0x%lx",windows->image.id);
+ background_resources.backdrop=True;
+ /*
+ Read each image and convert them to a tile.
+ */
+ backdrop=(windows->visual_info->class == TrueColor) ||
+ (windows->visual_info->class == DirectColor);
+ clone_info=CloneImageInfo(resource_info->image_info);
+ if (clone_info == (ImageInfo *) NULL)
+ return((Image *) NULL);
+ image=(Image *) NULL;
+ GetExceptionInfo(&exception);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ for (i=0; i < number_files; i++)
+ {
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ (void) strlcpy(clone_info->filename,filelist[i],MaxTextExtent);
+ *clone_info->magick='\0';
+ (void) CloneString(&clone_info->size,DefaultTileGeometry);
+ DestroyExceptionInfo(&exception);
+ GetExceptionInfo(&exception);
+ next_image=ReadImage(clone_info,&exception);
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (filelist[i] != filenames)
+ MagickFreeMemory(filelist[i]);
+ if (next_image != (Image *) NULL)
+ {
+ (void) SetImageAttribute(next_image,"label",(char *) NULL);
+ (void) SetImageAttribute(next_image,"label",DefaultTileLabel);
+ SetGeometry(next_image,&geometry);
+ (void) GetMagickGeometry(clone_info->size,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ thumbnail_image=ThumbnailImage(next_image,geometry.width,
+ geometry.height,&exception);
+ if (thumbnail_image != (Image *) NULL)
+ {
+ DestroyImage(next_image);
+ next_image=thumbnail_image;
+ }
+ if (backdrop)
+ {
+ (void) MagickXDisplayBackgroundImage(display,&background_resources,
+ next_image);
+ MagickXSetCursorState(display,windows,True);
+ }
+ if (image == (Image *) NULL)
+ image=next_image;
+ else
+ {
+ image->next=next_image;
+ image->next->previous=image;
+ image=image->next;
+ }
+ }
+ (void) SetMonitorHandler(handler);
+ if (!MagickMonitorFormatted(i,number_files,&image->exception,
+ LoadImagesText,image->filename))
+ break;
+ }
+ DestroyImageInfo(clone_info);
+ MagickFreeMemory(filelist);
+ if (image == (Image *) NULL)
+ {
+ MagickXSetCursorState(display,windows,False);
+ MagickError(ImageError,NoImagesWereLoaded,filenames);
+ return((Image *) NULL);
+ }
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ /*
+ Create the Visual Image Directory.
+ */
+ montage_info=CloneMontageInfo(resource_info->image_info,(MontageInfo *) NULL);
+ if (resource_info->font != (char *) NULL)
+ (void) CloneString(&montage_info->font,resource_info->font);
+ (void) strlcpy(montage_info->filename,filename,MaxTextExtent);
+ montage_image=MontageImages(image,montage_info,&image->exception);
+ DestroyMontageInfo(montage_info);
+ DestroyImageList(image);
+ MagickXSetCursorState(display,windows,False);
+ if (montage_image == (Image *) NULL)
+ return(montage_image);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_next_image,CurrentTime);
+ return(montage_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D i s p l a y B a c k g r o u n d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXDisplayBackgroundImage() displays an image in the background of a window.
+%
+% The format of the MagickXDisplayBackgroundImage method is:
+%
+% unsigned int MagickXDisplayBackgroundImage(Display *display,
+% MagickXResourceInfo *resource_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport unsigned int MagickXDisplayBackgroundImage(Display *display,
+ MagickXResourceInfo *resource_info,Image *image)
+{
+ char
+ geometry[MaxTextExtent],
+ visual_type[MaxTextExtent];
+
+ long
+ x,
+ y;
+
+ static MagickXPixelInfo
+ pixel;
+
+ static XStandardColormap
+ *map_info;
+
+ static XVisualInfo
+ *visual_info = (XVisualInfo *) NULL;
+
+ static MagickXWindowInfo
+ window_info;
+
+ unsigned int
+ status;
+
+ unsigned int
+ height,
+ width;
+
+ Window
+ root_window;
+
+ XGCValues
+ context_values;
+
+ MagickXResourceInfo
+ resources;
+
+ XWindowAttributes
+ window_attributes;
+
+ /*
+ Determine target window.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ resources=(*resource_info);
+ window_info.id=(Window) NULL;
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ if (LocaleCompare(resources.window_id,"root") == 0)
+ window_info.id=root_window;
+ else
+ {
+ if (isdigit((int) *resources.window_id))
+ window_info.id=MagickXWindowByID(display,root_window,
+ (Window) strtol((char *) resources.window_id,(char **) NULL,0));
+ if (window_info.id == (Window) NULL)
+ window_info.id=
+ MagickXWindowByName(display,root_window,resources.window_id);
+ }
+ if (window_info.id == (Window) NULL)
+ {
+ MagickError(XServerError,NoWindowWithSpecifiedIDExists,
+ resources.window_id);
+ return(False);
+ }
+ /*
+ Determine window visual id.
+ */
+ window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
+ window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
+ (void) strcpy(visual_type,"default");
+ status=XGetWindowAttributes(display,window_info.id,&window_attributes);
+ if (status != False)
+ FormatString(visual_type,"0x%lx",
+ XVisualIDFromVisual(window_attributes.visual));
+ if (visual_info == (XVisualInfo *) NULL)
+ {
+ /*
+ Allocate standard colormap.
+ */
+ map_info=XAllocStandardColormap();
+ if (map_info == (XStandardColormap *) NULL)
+ MagickFatalError(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(XServerFatalError,UnableToCreateStandardColormap));
+ map_info->colormap=(Colormap) NULL;
+ pixel.pixels=(unsigned long *) NULL;
+ /*
+ Initialize visual info.
+ */
+ resources.map_type=(char *) NULL;
+ resources.visual_type=visual_type;
+ visual_info=MagickXBestVisualInfo(display,map_info,&resources);
+ if (visual_info == (XVisualInfo *) NULL)
+ MagickFatalError(XServerFatalError,UnableToGetVisual,
+ resources.visual_type);
+ /*
+ Initialize window info.
+ */
+ window_info.ximage=(XImage *) NULL;
+ window_info.matte_image=(XImage *) NULL;
+ window_info.pixmap=(Pixmap) NULL;
+ window_info.matte_pixmap=(Pixmap) NULL;
+ }
+ /*
+ Free previous root colors.
+ */
+ if (window_info.id == root_window)
+ (void) MagickXDestroyWindowColors(display,root_window);
+ /*
+ Initialize Standard Colormap.
+ */
+ resources.colormap=SharedColormap;
+ MagickXMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel);
+ /*
+ Graphic context superclass.
+ */
+ context_values.background=pixel.background_color.pixel;
+ context_values.foreground=pixel.foreground_color.pixel;
+ pixel.annotate_context=XCreateGC(display,window_info.id,GCBackground |
+ GCForeground,&context_values);
+ if (pixel.annotate_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ /*
+ Initialize Image window attributes.
+ */
+ MagickXGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
+ &resources,&window_info);
+ /*
+ Create the X image.
+ */
+ window_info.width=(unsigned int) image->columns;
+ window_info.height=(unsigned int) image->rows;
+ FormatString(geometry,"%ux%u+0+0>",window_attributes.width,
+ window_attributes.height);
+ width=window_info.width;
+ height=window_info.height;
+ x=window_info.x;
+ y=window_info.y;
+ {
+ unsigned long
+ geometry_width=width,
+ geometry_height=height;
+
+ (void) GetMagickGeometry(geometry,&x,&y,&geometry_width,&geometry_height);
+ width=(unsigned int) geometry_width;
+ height=(unsigned int) geometry_height;
+ }
+ window_info.width=(unsigned int) width;
+ window_info.height=(unsigned int) height;
+ window_info.x=(int) x;
+ window_info.y=(int) y;
+ status=MagickXMakeImage(display,&resources,&window_info,image,window_info.width,
+ window_info.height);
+ if (status == False)
+ MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
+ window_info.x=0;
+ window_info.y=0;
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Image: %.1024s[%lu] %lux%lu ",image->filename,image->scene,
+ image->columns,image->rows);
+ if (image->colors != 0)
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%uc ",image->colors);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",image->magick);
+ }
+ /*
+ Adjust image dimensions as specified by backdrop or geometry options.
+ */
+ width=window_info.width;
+ height=window_info.height;
+ if (resources.backdrop)
+ {
+ /*
+ Center image on window.
+ */
+ window_info.x=(window_attributes.width/2)-
+ (window_info.ximage->width/2);
+ window_info.y=(window_attributes.height/2)-
+ (window_info.ximage->height/2);
+ width=window_attributes.width;
+ height=window_attributes.height;
+ }
+ if (resources.image_geometry != (char *) NULL)
+ {
+ char
+ default_geometry[MaxTextExtent];
+
+ int
+ flags,
+ gravity;
+
+ XSizeHints
+ *size_hints;
+
+ /*
+ User specified geometry.
+ */
+ size_hints=XAllocSizeHints();
+ if (size_hints == (XSizeHints *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToDisplayImage);
+ size_hints->flags=(long) NULL;
+ FormatString(default_geometry,"%ux%u",width,height);
+ flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
+ default_geometry,window_info.border_width,size_hints,&window_info.x,
+ &window_info.y,(int *) &width,(int *) &height,&gravity);
+ if (flags & (XValue | YValue))
+ {
+ width=window_attributes.width;
+ height=window_attributes.height;
+ }
+ (void) XFree((void *) size_hints);
+ }
+ /*
+ Create the X pixmap.
+ */
+ window_info.pixmap=XCreatePixmap(display,window_info.id,(unsigned int) width,
+ (unsigned int) height,window_info.depth);
+ if (window_info.pixmap == (Pixmap) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateXPixmap,(char *) NULL);
+ /*
+ Display pixmap on the window.
+ */
+ if (((unsigned int) width > window_info.width) ||
+ ((unsigned int) height > window_info.height))
+ (void) XFillRectangle(display,window_info.pixmap,
+ window_info.annotate_context,0,0,(unsigned int) width,
+ (unsigned int) height);
+ (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
+ window_info.ximage,0,0,window_info.x,window_info.y,
+ (unsigned int) window_info.width,(unsigned int) window_info.height);
+ (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
+ (void) XClearWindow(display,window_info.id);
+ MagickXDelay(display,10*image->delay);
+ (void) XSync(display,False);
+ return(window_info.id == root_window);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D i s p l a y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXDisplayImage() displays an image via X11. A new image is created and
+% returned if the user interactively transforms the displayed image.
+%
+% The format of the MagickXDisplayImage method is:
+%
+% Image *MagickXDisplayImage(Display *display,MagickXResourceInfo *resource_info,
+% char **argv,int argc,Image **image,unsigned long *state)
+%
+% A description of each parameter follows:
+%
+% o nexus: Method MagickXDisplayImage returns an image when the
+% user chooses 'Open Image' from the command menu or picks a tile
+% from the image directory. Otherwise a null image is returned.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o argv: Specifies the application's argument list.
+%
+% o argc: Specifies the number of arguments.
+%
+% o image: Specifies an address to an address of an Image structure;
+% returned from ReadImage.
+%
+%
+*/
+#define MagnifySize 256 /* must be a power of 2 */
+#define MagickMenus 10
+#define MagickTitle "Commands"
+#define DestroyWindowsImage(windows,subwindow) \
+{ \
+ if ((windows->subwindow.image != (Image *) NULL) && \
+ (windows->subwindow.destroy == True)) \
+ { \
+ DestroyImage(windows->subwindow.image); \
+ windows->subwindow.image=(Image *) NULL; \
+ } \
+}
+
+MagickExport Image *
+MagickXDisplayImage(Display *display,MagickXResourceInfo *resource_info,
+ char *argv[],int argc,Image **image,unsigned long *state)
+{
+
+ static const char
+ *CommandMenu[]=
+ {
+ "File",
+ "Edit",
+ "View",
+ "Transform",
+ "Enhance",
+ "Effects",
+ "F/X",
+ "Image Edit",
+ "Miscellany",
+ "Help",
+ (char *) NULL
+ },
+ *FileMenu[]=
+ {
+ "Open...",
+ "Next",
+ "Former",
+ "Select...",
+ "Save...",
+ "Print...",
+ "Delete...",
+ "New...",
+ "Visual Directory...",
+ "Quit",
+ (char *) NULL
+ },
+ *EditMenu[]=
+ {
+ "Undo",
+ "Redo",
+ "Cut",
+ "Copy",
+ "Paste",
+ (char *) NULL
+ },
+ *ViewMenu[]=
+ {
+ "Half Size",
+ "Original Size",
+ "Double Size",
+ "Resize...",
+ "Apply",
+ "Refresh",
+ "Restore",
+ (char *) NULL
+ },
+ *TransformMenu[]=
+ {
+ "Crop",
+ "Chop",
+ "Flop",
+ "Flip",
+ "Rotate Right",
+ "Rotate Left",
+ "Rotate...",
+ "Shear...",
+ "Roll...",
+ "Trim Edges",
+ (char *) NULL
+ },
+ *EnhanceMenu[]=
+ {
+ "Hue...",
+ "Saturation...",
+ "Brightness...",
+ "Gamma...",
+ "Spiff",
+ "Dull",
+ "Equalize",
+ "Normalize",
+ "Negate",
+ "Grayscale",
+ "Map...",
+ "Quantize...",
+ (char *) NULL
+ },
+ *EffectsMenu[]=
+ {
+ "Despeckle",
+ "Emboss",
+ "Reduce Noise",
+ "Add Noise...",
+ "Sharpen...",
+ "Blur...",
+ "Threshold...",
+ "Edge Detect...",
+ "Spread...",
+ "Shade...",
+ "Raise...",
+ "Segment...",
+ (char *) NULL
+ },
+ *FXMenu[]=
+ {
+ "Solarize...",
+ "Swirl...",
+ "Implode...",
+ "Wave...",
+ "Oil Paint...",
+ "Charcoal Draw...",
+ (char *) NULL
+ },
+ *ImageEditMenu[]=
+ {
+ "Annotate...",
+ "Draw...",
+ "Color...",
+ "Matte...",
+ "Composite...",
+ "Add Border...",
+ "Add Frame...",
+ "Comment...",
+ "Launch...",
+ "Region of Interest...",
+ (char *) NULL
+ },
+ *MiscellanyMenu[]=
+ {
+ "Image Info",
+ "Zoom Image",
+ "Show Preview...",
+ "Show Histogram",
+ "Show Matte",
+ "Background...",
+ "Slide Show...",
+ "Preferences...",
+ (char *) NULL
+ },
+ *HelpMenu[]=
+ {
+ "Overview",
+ "Browse Documentation",
+ "About Display",
+ (char *) NULL
+ },
+ *ShortCutsMenu[]=
+ {
+ "Next",
+ "Former",
+ "Open...",
+ "Save...",
+ "Print...",
+ "Undo",
+ "Restore",
+ "Image Info",
+ "Quit",
+ (char *) NULL
+ },
+ *ImmutableMenu[]=
+ {
+ "Image Info",
+ "Print",
+ "Next",
+ "Quit",
+ (char *) NULL
+ };
+
+ static const char
+ **Menus[MagickMenus]=
+ {
+ FileMenu,
+ EditMenu,
+ ViewMenu,
+ TransformMenu,
+ EnhanceMenu,
+ EffectsMenu,
+ FXMenu,
+ ImageEditMenu,
+ MiscellanyMenu,
+ HelpMenu
+ };
+
+ static CommandType
+ CommandMenus[]=
+ {
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ NullCommand,
+ },
+ FileCommands[]=
+ {
+ OpenCommand,
+ NextCommand,
+ FormerCommand,
+ SelectCommand,
+ SaveCommand,
+ PrintCommand,
+ DeleteCommand,
+ NewCommand,
+ VisualDirectoryCommand,
+ QuitCommand
+ },
+ EditCommands[]=
+ {
+ UndoCommand,
+ RedoCommand,
+ CutCommand,
+ CopyCommand,
+ PasteCommand
+ },
+ ViewCommands[]=
+ {
+ HalfSizeCommand,
+ OriginalSizeCommand,
+ DoubleSizeCommand,
+ ResizeCommand,
+ ApplyCommand,
+ RefreshCommand,
+ RestoreCommand
+ },
+ TransformCommands[]=
+ {
+ CropCommand,
+ ChopCommand,
+ FlopCommand,
+ FlipCommand,
+ RotateRightCommand,
+ RotateLeftCommand,
+ RotateCommand,
+ ShearCommand,
+ RollCommand,
+ TrimCommand
+ },
+ EnhanceCommands[]=
+ {
+ HueCommand,
+ SaturationCommand,
+ BrightnessCommand,
+ GammaCommand,
+ SpiffCommand,
+ DullCommand,
+ EqualizeCommand,
+ NormalizeCommand,
+ NegateCommand,
+ GrayscaleCommand,
+ MapCommand,
+ QuantizeCommand
+ },
+ EffectsCommands[]=
+ {
+ DespeckleCommand,
+ EmbossCommand,
+ ReduceNoiseCommand,
+ AddNoiseCommand,
+ SharpenCommand,
+ BlurCommand,
+ ThresholdCommand,
+ EdgeDetectCommand,
+ SpreadCommand,
+ ShadeCommand,
+ RaiseCommand,
+ SegmentCommand
+ },
+ FXCommands[]=
+ {
+ SolarizeCommand,
+ SwirlCommand,
+ ImplodeCommand,
+ WaveCommand,
+ OilPaintCommand,
+ CharcoalDrawCommand
+ },
+ ImageEditCommands[]=
+ {
+ AnnotateCommand,
+ DrawCommand,
+ ColorCommand,
+ MatteCommand,
+ CompositeCommand,
+ AddBorderCommand,
+ AddFrameCommand,
+ CommentCommand,
+ LaunchCommand,
+ RegionofInterestCommand
+ },
+ MiscellanyCommands[]=
+ {
+ InfoCommand,
+ ZoomCommand,
+ ShowPreviewCommand,
+ ShowHistogramCommand,
+ ShowMatteCommand,
+ BackgroundCommand,
+ SlideShowCommand,
+ PreferencesCommand
+ },
+ HelpCommands[]=
+ {
+ HelpCommand,
+ BrowseDocumentationCommand,
+ VersionCommand
+ },
+ ShortCutsCommands[]=
+ {
+ NextCommand,
+ FormerCommand,
+ OpenCommand,
+ SaveCommand,
+ PrintCommand,
+ UndoCommand,
+ RestoreCommand,
+ InfoCommand,
+ QuitCommand
+ },
+ ImmutableCommands[]=
+ {
+ InfoCommand,
+ PrintCommand,
+ NextCommand,
+ QuitCommand
+ };
+
+ static CommandType
+ *Commands[MagickMenus]=
+ {
+ FileCommands,
+ EditCommands,
+ ViewCommands,
+ TransformCommands,
+ EnhanceCommands,
+ EffectsCommands,
+ FXCommands,
+ ImageEditCommands,
+ MiscellanyCommands,
+ HelpCommands
+ };
+
+ char
+ command[MaxTextExtent],
+ geometry[MaxTextExtent],
+ resource_name[MaxTextExtent];
+
+ CommandType
+ command_type;
+
+ Image
+ *display_image,
+ *nexus;
+
+ int
+ entry,
+ id,
+ status;
+
+ long
+ x,
+ y;
+
+ KeySym
+ key_symbol;
+
+ MonitorHandler
+ handler,
+ monitor_handler;
+
+ register int
+ i;
+
+ static char
+ working_directory[MaxTextExtent];
+
+ static XPoint
+ vid_info;
+
+ static MagickXWindowInfo
+ *magick_windows[MaxXWindows];
+
+ static unsigned int
+ number_windows;
+
+ MagickStatStruct_t
+ file_info;
+
+ time_t
+ timer,
+ timestamp,
+ update_time;
+
+ unsigned int
+ context_mask;
+
+ unsigned long
+ height,
+ width;
+
+ WarningHandler
+ warning_handler;
+
+ Window
+ root_window;
+
+ XClassHint
+ *class_hints;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XGCValues
+ context_values;
+
+ MagickXPixelInfo
+ *icon_pixel,
+ *pixel;
+
+ MagickXResourceInfo
+ *icon_resources;
+
+ XStandardColormap
+ *icon_map,
+ *map_info;
+
+ XVisualInfo
+ *icon_visual,
+ *visual_info;
+
+ XWindowChanges
+ window_changes;
+
+ MagickXWindows
+ *windows;
+
+ XWMHints
+ *manager_hints;
+
+ assert(image != (Image **) NULL);
+ assert((*image)->signature == MagickSignature);
+ display_image=(*image);
+ (void) TransformColorspace(display_image,RGBColorspace);
+ monitor_handler=(MonitorHandler) NULL;
+ warning_handler=(WarningHandler) NULL;
+ windows=MagickXSetWindows((MagickXWindows *) ~0);
+ if (windows != (MagickXWindows *) NULL)
+ {
+ /*
+ Change to the working directory.
+ */
+ if (('\0' != working_directory[0]) && (chdir(working_directory) != 0))
+ {
+ MagickXNoticeWidget(display,windows,"Unable to restore directory:",
+ working_directory);
+ MagickFatalError(ConfigureFatalError,UnableToChangeToWorkingDirectory,
+ NULL);
+ }
+ /*
+ Set the progress monitor if progress monitoring is requested.
+ */
+ if (resource_info->image_info->progress)
+ monitor_handler=SetMonitorHandler(MagickXMagickMonitor);
+ /*
+ Set the warning and signal handlers.
+ */
+ warning_handler=resource_info->display_warnings ?
+ SetErrorHandler(MagickXWarning) : SetErrorHandler((ErrorHandler) NULL);
+ warning_handler=resource_info->display_warnings ?
+ SetWarningHandler(MagickXWarning) : SetWarningHandler((WarningHandler) NULL);
+ }
+ else
+ {
+ /*
+ Allocate windows structure.
+ */
+ resource_info->colors=display_image->colors;
+ windows=MagickXSetWindows(MagickXInitializeWindows(display,resource_info));
+ if (windows == (MagickXWindows *) NULL)
+ MagickFatalError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateXWindow);
+ /*
+ Initialize window id's.
+ */
+ number_windows=0;
+ magick_windows[number_windows++]=(&windows->icon);
+ magick_windows[number_windows++]=(&windows->backdrop);
+ magick_windows[number_windows++]=(&windows->image);
+ magick_windows[number_windows++]=(&windows->info);
+ magick_windows[number_windows++]=(&windows->command);
+ magick_windows[number_windows++]=(&windows->widget);
+ magick_windows[number_windows++]=(&windows->popup);
+ magick_windows[number_windows++]=(&windows->magnify);
+ magick_windows[number_windows++]=(&windows->pan);
+ magick_windows[number_windows]=(MagickXWindowInfo *) NULL;
+ for (i=0; i < (int) number_windows; i++)
+ magick_windows[i]->id=(Window) NULL;
+ vid_info.x=0;
+ vid_info.y=0;
+ }
+ /*
+ Initialize font info.
+ */
+ if (windows->font_info != (XFontStruct *) NULL)
+ (void) XFreeFont(display,windows->font_info);
+ windows->font_info=MagickXBestFont(display,resource_info,False);
+ if (windows->font_info == (XFontStruct *) NULL)
+ MagickFatalError(XServerFatalError,UnableToLoadFont,resource_info->font);
+ /*
+ Initialize Standard Colormap.
+ */
+ map_info=windows->map_info;
+ icon_map=windows->icon_map;
+ visual_info=windows->visual_info;
+ icon_visual=windows->icon_visual;
+ pixel=windows->pixel_info;
+ icon_pixel=windows->icon_pixel;
+ font_info=windows->font_info;
+ icon_resources=windows->icon_resources;
+ class_hints=windows->class_hints;
+ manager_hints=windows->manager_hints;
+ root_window=XRootWindow(display,visual_info->screen);
+ nexus=(Image *) NULL;
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Image: %.1024s[%lu] %lux%lu ",display_image->filename,
+ display_image->scene,display_image->columns,display_image->rows);
+ if (display_image->colors != 0)
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%uc ",
+ display_image->colors);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
+ display_image->magick);
+ }
+ MagickXMakeStandardColormap(display,visual_info,resource_info,display_image,
+ map_info,pixel);
+ display_image->taint=False;
+ /*
+ Initialize graphic context.
+ */
+ windows->context.id=(Window) NULL;
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->context);
+ class_hints->res_name=(char *) "superclass";
+ class_hints->res_class=(char *) "Display";
+ manager_hints->flags=InputHint | StateHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=WithdrawnState;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->context);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (context)",
+ windows->context.id);
+ (void) memset(&context_values,0,sizeof(context_values));
+ context_values.background=pixel->background_color.pixel;
+ context_values.font=font_info->fid;
+ context_values.foreground=pixel->foreground_color.pixel;
+ context_values.graphics_exposures=False;
+ context_mask=GCBackground | GCFont | GCForeground | GCGraphicsExposures;
+ if (pixel->annotate_context != (GC) NULL)
+ (void) XFreeGC(display,pixel->annotate_context);
+ pixel->annotate_context=
+ XCreateGC(display,windows->context.id,context_mask,&context_values);
+ if (pixel->annotate_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ context_values.background=pixel->depth_color.pixel;
+ if (pixel->widget_context != (GC) NULL)
+ (void) XFreeGC(display,pixel->widget_context);
+ pixel->widget_context=
+ XCreateGC(display,windows->context.id,context_mask,&context_values);
+ if (pixel->widget_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ context_values.background=pixel->foreground_color.pixel;
+ context_values.foreground=pixel->background_color.pixel;
+ context_values.plane_mask=
+ context_values.background ^ context_values.foreground;
+ if (pixel->highlight_context != (GC) NULL)
+ (void) XFreeGC(display,pixel->highlight_context);
+ pixel->highlight_context=XCreateGC(display,windows->context.id,
+ context_mask | GCPlaneMask,&context_values);
+ if (pixel->highlight_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ (void) XDestroyWindow(display,windows->context.id);
+ /*
+ Initialize icon window.
+ */
+ MagickXGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
+ icon_resources,&windows->icon);
+ windows->icon.geometry=resource_info->icon_geometry;
+ MagickXBestIconSize(display,&windows->icon,display_image);
+ windows->icon.attributes.colormap=
+ XDefaultColormap(display,icon_visual->screen);
+ windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
+ class_hints->res_name=(char *) "icon";
+ manager_hints->flags=InputHint | StateHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=IconicState;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->icon);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (icon)",
+ windows->icon.id);
+ /*
+ Initialize graphic context for icon window.
+ */
+ if (icon_pixel->annotate_context != (GC) NULL)
+ (void) XFreeGC(display,icon_pixel->annotate_context);
+ context_values.background=icon_pixel->background_color.pixel;
+ context_values.foreground=icon_pixel->foreground_color.pixel;
+ icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
+ GCBackground | GCForeground,&context_values);
+ if (icon_pixel->annotate_context == (GC) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
+ (char *) NULL);
+ windows->icon.annotate_context=icon_pixel->annotate_context;
+ /*
+ Initialize Image window.
+ */
+ if (windows->image.id != (Window) NULL)
+ {
+ (void) CloneString(&windows->image.name,"");
+ (void) CloneString(&windows->image.icon_name,"");
+ }
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->image);
+ windows->image.shape=True; /* non-rectangular shape hint */
+ windows->image.shared_memory&=resource_info->use_shared_memory;
+ if ((resource_info->title != (char *) NULL) && !(*state & MontageImageState))
+ {
+ MagickFreeMemory(windows->image.name);
+ windows->image.name=TranslateText(resource_info->image_info,
+ display_image,resource_info->title);
+ MagickFreeMemory(windows->image.icon_name);
+ windows->image.icon_name=TranslateText(resource_info->image_info,
+ display_image,resource_info->title);
+ }
+ else
+ {
+ char
+ filename[MaxTextExtent];
+
+ register Image
+ *q;
+
+ unsigned long
+ count;
+
+ /*
+ Window name is the base of the filename.
+ */
+ (void ) CloneString(&windows->image.name,"");
+ (void ) CloneString(&windows->image.icon_name,"");
+ GetPathComponent(display_image->filename,TailPath,filename);
+ FormatString(windows->image.name,"%s: %.1024s[%lu]",MagickPackageName,
+ filename,display_image->scene);
+ q=display_image;
+ while (q->previous != (Image *) NULL)
+ q=q->previous;
+ for (count=1; q->next != (Image *) NULL; count++)
+ q=q->next;
+ FormatString(windows->image.name,"%s: %.1024s[%lu of %lu]",
+ MagickPackageName,filename,display_image->scene+1U,count);
+ if ((display_image->previous == (Image *) NULL) &&
+ (display_image->next == (Image *) NULL) &&
+ (display_image->scene == 0))
+ FormatString(windows->image.name,"%s: %.1024s",MagickPackageName,
+ filename);
+ (void) strlcpy(windows->image.icon_name,filename,MaxTextExtent);
+ }
+ if (resource_info->immutable)
+ windows->image.immutable=True;
+ windows->image.use_pixmap=resource_info->use_pixmap;
+ windows->image.geometry=resource_info->image_geometry;
+ FormatString(geometry,"%ux%u+0+0>!",
+ XDisplayWidth(display,visual_info->screen),
+ XDisplayHeight(display,visual_info->screen));
+ width=display_image->columns;
+ height=display_image->rows;
+ x=0;
+ y=0;
+ (void) GetMagickGeometry(geometry,&x,&y,&width,&height);
+ windows->image.width=(unsigned int) width;
+ windows->image.height=(unsigned int) height;
+ windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
+ KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
+ PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->backdrop);
+ if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
+ {
+ /*
+ Initialize backdrop window.
+ */
+ windows->backdrop.x=0;
+ windows->backdrop.y=0;
+ (void) CloneString(&windows->backdrop.name,"GraphicsMagick Backdrop");
+ windows->backdrop.flags=USSize | USPosition;
+ windows->backdrop.width=XDisplayWidth(display,visual_info->screen);
+ windows->backdrop.height=XDisplayHeight(display,visual_info->screen);
+ windows->backdrop.border_width=0;
+ windows->backdrop.immutable=True;
+ windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
+ ButtonReleaseMask;
+ windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
+ StructureNotifyMask;
+ windows->backdrop.attributes.override_redirect=True;
+ class_hints->res_name=(char *) "backdrop";
+ manager_hints->flags=IconWindowHint | InputHint | StateHint;
+ manager_hints->icon_window=windows->icon.id;
+ manager_hints->input=True;
+ manager_hints->initial_state=
+ resource_info->iconic ? IconicState : NormalState;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->backdrop);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Window id: 0x%lx (backdrop)",windows->backdrop.id);
+ (void) XMapWindow(display,windows->backdrop.id);
+ (void) XClearWindow(display,windows->backdrop.id);
+ if (windows->image.id != (Window) NULL)
+ {
+ (void) XDestroyWindow(display,windows->image.id);
+ windows->image.id=(Window) NULL;
+ }
+ /*
+ Position image in the center the backdrop.
+ */
+ windows->image.flags|=USPosition;
+ windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
+ (windows->image.width/2);
+ windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
+ (windows->image.height/2);
+ }
+ if (resource_info->name == (char *) NULL)
+ class_hints->res_name=resource_info->client_name;
+ else
+ class_hints->res_name=resource_info->name;
+ manager_hints->flags=IconWindowHint | InputHint | StateHint;
+ manager_hints->icon_window=windows->icon.id;
+ manager_hints->input=True;
+ manager_hints->initial_state=
+ resource_info->iconic ? IconicState : NormalState;
+ if (windows->group_leader.id != (Window) NULL)
+ {
+ /*
+ Follow the leader.
+ */
+ manager_hints->flags|=WindowGroupHint;
+ manager_hints->window_group=windows->group_leader.id;
+ (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Window id: 0x%lx (group leader)",windows->group_leader.id);
+ }
+ MagickXMakeWindow(display,
+ (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
+ argv,argc,class_hints,manager_hints,&windows->image);
+ (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
+ XA_STRING,8,PropModeReplace,(unsigned char *) NULL,0);
+ if (windows->group_leader.id != (Window) NULL)
+ (void) XSetTransientForHint(display,windows->image.id,
+ windows->group_leader.id);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (image)",
+ windows->image.id);
+ /*
+ Initialize Info widget.
+ */
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
+ &windows->info);
+ (void) CloneString(&windows->info.name,"Info");
+ (void) CloneString(&windows->info.icon_name,"Info");
+ windows->info.border_width=1;
+ windows->info.x=2;
+ windows->info.y=2;
+ windows->info.flags|=PPosition;
+ windows->info.attributes.win_gravity=UnmapGravity;
+ windows->info.attributes.event_mask=
+ ButtonPressMask | ExposureMask | StructureNotifyMask;
+ class_hints->res_name=(char *) "info";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
+ &windows->info);
+ windows->info.highlight_stipple=XCreateBitmapFromData(display,
+ windows->info.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight);
+ windows->info.shadow_stipple=XCreateBitmapFromData(display,
+ windows->info.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight);
+ (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
+ if (windows->image.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (info)",
+ windows->info.id);
+ /*
+ Initialize Command widget.
+ */
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->command);
+ windows->command.data=MagickMenus;
+ (void) MagickXCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
+ FormatString(resource_name,"%.1024s.command",resource_info->client_name);
+ windows->command.geometry=MagickXGetResourceClass(resource_info->resource_database,
+ resource_name,"geometry",(char *) NULL);
+ (void) CloneString(&windows->command.name,MagickTitle);
+ windows->command.border_width=0;
+ windows->command.flags|=PPosition;
+ windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
+ OwnerGrabButtonMask | StructureNotifyMask;
+ class_hints->res_name=(char *) "command";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->command);
+ windows->command.highlight_stipple=windows->info.highlight_stipple;
+ windows->command.shadow_stipple=windows->info.shadow_stipple;
+ (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
+ if (windows->command.mapped)
+ (void) XMapRaised(display,windows->command.id);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (command)",
+ windows->command.id);
+ /*
+ Initialize Widget window.
+ */
+ if (windows->widget.id != (Window) NULL)
+ (void) CloneString(&windows->widget.name,"");
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->widget);
+ FormatString(resource_name,"%.1024s.widget",resource_info->client_name);
+ windows->widget.geometry=MagickXGetResourceClass(resource_info->resource_database,
+ resource_name,"geometry",(char *) NULL);
+ (void ) CloneString(&windows->widget.name,"");
+ windows->widget.border_width=0;
+ windows->widget.flags|=PPosition;
+ windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
+ KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
+ StructureNotifyMask;
+ class_hints->res_name=(char *) "widget";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=True;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->widget);
+ windows->widget.highlight_stipple=windows->info.highlight_stipple;
+ windows->widget.shadow_stipple=windows->info.shadow_stipple;
+ (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (widget)",
+ windows->widget.id);
+ /*
+ Initialize popup window.
+ */
+ if (windows->popup.id != (Window) NULL)
+ (void) CloneString(&windows->popup.name,"");
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->popup);
+ (void) CloneString(&windows->popup.name,"");
+ windows->popup.border_width=0;
+ windows->popup.flags|=PPosition;
+ windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
+ KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
+ class_hints->res_name=(char *) "popup";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=True;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->popup);
+ windows->popup.highlight_stipple=windows->info.highlight_stipple;
+ windows->popup.shadow_stipple=windows->info.shadow_stipple;
+ (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (pop up)",
+ windows->popup.id);
+ /*
+ Initialize Magnify window and cursor.
+ */
+ if (windows->magnify.id != (Window) NULL)
+ (void) CloneString(&windows->magnify.name,"");
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->magnify);
+ windows->magnify.shared_memory&=resource_info->use_shared_memory;
+ FormatString(resource_name,"%.1024s.magnify",resource_info->client_name);
+ windows->magnify.geometry=MagickXGetResourceClass(resource_info->resource_database,
+ resource_name,"geometry",(char *) NULL);
+ (void) CloneString(&windows->magnify.name,"");
+ FormatString(windows->magnify.name,"Magnify %uX",resource_info->magnify);
+ windows->magnify.cursor=MagickXMakeCursor(display,windows->image.id,
+ map_info->colormap,resource_info->background_color,
+ resource_info->foreground_color);
+ if (windows->magnify.cursor == (Cursor) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateCursor,(char *) NULL);
+ windows->magnify.width=MagnifySize;
+ windows->magnify.height=MagnifySize;
+ windows->magnify.flags|=PPosition;
+ windows->magnify.min_width=MagnifySize;
+ windows->magnify.min_height=MagnifySize;
+ windows->magnify.width_inc=MagnifySize;
+ windows->magnify.height_inc=MagnifySize;
+ windows->magnify.data=resource_info->magnify;
+ windows->magnify.attributes.cursor=windows->magnify.cursor;
+ windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
+ ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
+ StructureNotifyMask;
+ class_hints->res_name=(char *) "magnify";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=True;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->magnify);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (magnify)",
+ windows->magnify.id);
+ (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
+ /*
+ Initialize panning window.
+ */
+ MagickXGetWindowInfo(display,visual_info,map_info,pixel,font_info,
+ resource_info,&windows->pan);
+ (void) CloneString(&windows->pan.name,"Pan Icon");
+ windows->pan.width=windows->icon.width;
+ windows->pan.height=windows->icon.height;
+ FormatString(resource_name,"%.1024s.pan",resource_info->client_name);
+ windows->pan.geometry=MagickXGetResourceClass(resource_info->resource_database,
+ resource_name,"geometry",(char *) NULL);
+ (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
+ &windows->pan.width,&windows->pan.height);
+ windows->pan.flags|=PPosition;
+ windows->pan.immutable=True;
+ windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
+ ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
+ StructureNotifyMask;
+ class_hints->res_name=(char *) "pan";
+ manager_hints->flags=InputHint | StateHint | WindowGroupHint;
+ manager_hints->input=False;
+ manager_hints->initial_state=NormalState;
+ manager_hints->window_group=windows->image.id;
+ MagickXMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
+ &windows->pan);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (pan)",
+ windows->pan.id);
+ (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (!windows->image.mapped || (windows->backdrop.id != (Window) NULL))
+ (void) XMapWindow(display,windows->image.id);
+ /*
+ Set progress monitor if progress monitoring requested.
+ */
+ if ((resource_info->image_info->progress) &&
+ (monitor_handler == (MonitorHandler) NULL))
+ monitor_handler=SetMonitorHandler(MagickXMagickMonitor);
+ /*
+ Set warning and signal handlers.
+ */
+ if (warning_handler == (WarningHandler) NULL)
+ {
+ warning_handler=resource_info->display_warnings ?
+ SetErrorHandler(MagickXWarning) : SetErrorHandler((ErrorHandler) NULL);
+ warning_handler=resource_info->display_warnings ?
+ SetWarningHandler(MagickXWarning) : SetWarningHandler((WarningHandler) NULL);
+ }
+ /*
+ Initialize Image and Magnify X images.
+ */
+ windows->image.x=0;
+ windows->image.y=0;
+ windows->magnify.shape=False;
+ status=MagickXMakeImage(display,resource_info,&windows->image,display_image,
+ (unsigned int) display_image->columns,(unsigned int) display_image->rows);
+ if (status == False)
+ MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
+ if (windows->image.mapped)
+ MagickXRefreshWindow(display,&windows->image,(XEvent *) NULL);
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ status=MagickXMakeImage(display,resource_info,&windows->magnify,(Image *) NULL,
+ windows->magnify.width,windows->magnify.height);
+ (void) SetMonitorHandler(handler);
+ if (status == False)
+ MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
+ if (windows->magnify.mapped)
+ {
+ (void) XMapRaised(display,windows->magnify.id);
+ MagickXMakeMagnifyImage(display,windows);
+ }
+ if (windows->image.mapped)
+ if (((int) windows->image.width < windows->image.ximage->width) ||
+ ((int) windows->image.height < windows->image.ximage->height))
+ (void) XMapRaised(display,windows->pan.id);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ (void) XSync(display,False);
+ /*
+ Respond to events.
+ */
+ if (resource_info->delay > 1)
+ display_image->delay=resource_info->delay;
+ update_time=0;
+ if (resource_info->update)
+ {
+ /*
+ Determine when file data was last modified.
+ */
+ status=MagickStat(display_image->filename,&file_info);
+ if (status == 0)
+ update_time=file_info.st_mtime;
+ if (resource_info->delay <= 1)
+ display_image->delay=resource_info->update*100;
+ }
+ timer=time((time_t *) NULL)+(long) display_image->delay/100+1;
+ *state&=(~FormerImageState);
+ *state&=(~MontageImageState);
+ *state&=(~NextImageState);
+ do
+ {
+ /*
+ Handle a window event.
+ */
+ if (windows->image.mapped && (display_image->delay > 1))
+ {
+ if (timer < time((time_t *) NULL))
+ {
+ if (!resource_info->update)
+ *state|=NextImageState | ExitState;
+ else
+ {
+ /*
+ Determine if image file was modified.
+ */
+ status=MagickStat(display_image->filename,&file_info);
+ if (status == 0)
+ if (update_time != file_info.st_mtime)
+ {
+ /*
+ Redisplay image.
+ */
+ FormatString(resource_info->image_info->filename,
+ "%.1024s:%.1024s",display_image->magick,
+ display_image->filename);
+ nexus=ReadImage(resource_info->image_info,
+ &display_image->exception);
+ if (display_image->exception.severity !=
+ UndefinedException)
+ MagickError2(display_image->exception.severity,
+ display_image->exception.reason,
+ display_image->exception.description);
+ if (nexus != (Image *) NULL)
+ *state|=NextImageState | ExitState;
+ }
+ timer=time((time_t *) NULL)+(long) display_image->delay/100+1;
+ }
+ }
+ if (XEventsQueued(display,QueuedAfterFlush) == 0)
+ {
+ /*
+ Do not block if delay > 0.
+ */
+ MagickXDelay(display,SuspendTime << 2);
+ continue;
+ }
+ }
+ timestamp=time((time_t *) NULL);
+ (void) XNextEvent(display,&event);
+ if (!windows->image.stasis)
+ windows->image.stasis=(time((time_t *) NULL)-timestamp) > 0;
+ if (!windows->magnify.stasis)
+ windows->magnify.stasis=(time((time_t *) NULL)-timestamp) > 0;
+ if (event.xany.window == windows->command.id)
+ {
+ /*
+ Select a command from the Command widget.
+ */
+ id=MagickXCommandWidget(display,windows,CommandMenu,&event);
+ if (id < 0)
+ continue;
+ (void) strlcpy(command,CommandMenu[id],MaxTextExtent);
+ command_type=CommandMenus[id];
+ if (id < MagickMenus)
+ {
+ /*
+ Select a command from a pop-up menu.
+ */
+ entry=MagickXMenuWidget(display,windows,CommandMenu[id],Menus[id],
+ command);
+ if (entry < 0)
+ continue;
+ (void) strlcpy(command,Menus[id][entry],MaxTextExtent);
+ command_type=Commands[id][entry];
+ }
+ if (command_type != NullCommand)
+ nexus=MagickXMagickCommand(display,resource_info,windows,command_type,
+ &display_image);
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
+ event.xbutton.button,event.xbutton.x,event.xbutton.y);
+ if ((event.xbutton.button == Button3) &&
+ (event.xbutton.state & Mod1Mask))
+ {
+ /*
+ Convert Alt-Button3 to Button2.
+ */
+ event.xbutton.button=Button2;
+ event.xbutton.state&=(~Mod1Mask);
+ }
+ if (event.xbutton.window == windows->backdrop.id)
+ {
+ (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
+ event.xbutton.time);
+ break;
+ }
+ if (event.xbutton.window == windows->image.id)
+ {
+ switch (event.xbutton.button)
+ {
+ case Button1:
+ {
+ if (resource_info->immutable)
+ {
+ /*
+ Select a command from the Immutable menu.
+ */
+ entry=MagickXMenuWidget(display,windows,"Commands",ImmutableMenu,
+ command);
+ if (entry >= 0)
+ nexus=MagickXMagickCommand(display,resource_info,windows,
+ ImmutableCommands[entry],&display_image);
+ break;
+ }
+ /*
+ Map/unmap Command widget.
+ */
+ if (windows->command.mapped)
+ (void) XWithdrawWindow(display,windows->command.id,
+ windows->command.screen);
+ else
+ {
+ (void) MagickXCommandWidget(display,windows,CommandMenu,
+ (XEvent *) NULL);
+ (void) XMapRaised(display,windows->command.id);
+ }
+ break;
+ }
+ case Button2:
+ {
+ /*
+ User pressed the image magnify button.
+ */
+ (void) MagickXMagickCommand(display,resource_info,windows,ZoomCommand,
+ &display_image);
+ MagickXMagnifyImage(display,windows,&event);
+ break;
+ }
+ case Button3:
+ {
+ if (resource_info->immutable)
+ {
+ /*
+ Select a command from the Immutable menu.
+ */
+ entry=MagickXMenuWidget(display,windows,"Commands",ImmutableMenu,
+ command);
+ if (entry >= 0)
+ nexus=MagickXMagickCommand(display,resource_info,windows,
+ ImmutableCommands[entry],&display_image);
+ break;
+ }
+ if (display_image->montage != (char *) NULL)
+ {
+ /*
+ Open or delete a tile from a visual image directory.
+ */
+ nexus=MagickXTileImage(display,resource_info,windows,
+ display_image,&event);
+ if (nexus != (Image *) NULL)
+ *state|=MontageImageState | NextImageState | ExitState;
+ vid_info.x=windows->image.x;
+ vid_info.y=windows->image.y;
+ break;
+ }
+ /*
+ Select a command from the Short Cuts menu.
+ */
+ entry=MagickXMenuWidget(display,windows,"Short Cuts",ShortCutsMenu,
+ command);
+ if (entry >= 0)
+ nexus=MagickXMagickCommand(display,resource_info,windows,
+ ShortCutsCommands[entry],&display_image);
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ if (event.xbutton.window == windows->magnify.id)
+ {
+ int
+ factor;
+
+ static const char
+ *MagnifyMenu[]=
+ {
+ "2",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "3",
+ (char *) NULL,
+ };
+
+ static KeySym
+ MagnifyCommands[]=
+ {
+ XK_2,
+ XK_4,
+ XK_5,
+ XK_6,
+ XK_7,
+ XK_8,
+ XK_9,
+ XK_3
+ };
+
+ /*
+ Select a magnify factor from the pop-up menu.
+ */
+ factor=MagickXMenuWidget(display,windows,"Magnify",MagnifyMenu,command);
+ if (factor >= 0)
+ MagickXMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor]);
+ break;
+ }
+ if (event.xbutton.window == windows->pan.id)
+ {
+ MagickXPanImage(display,windows,&event);
+ break;
+ }
+ timer=time((time_t *) NULL)+(long) display_image->delay/100+1;
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
+ event.xbutton.button,event.xbutton.x,event.xbutton.y);
+ break;
+ }
+ case ClientMessage:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Client Message: 0x%lx 0x%lx %d 0x%lx",event.xclient.window,
+ event.xclient.message_type,event.xclient.format,(unsigned long)
+ event.xclient.data.l[0]);
+ if (event.xclient.message_type == windows->im_protocols)
+ {
+ if (*event.xclient.data.l == (long) windows->im_update_widget)
+ {
+ (void) CloneString(&windows->command.name,MagickTitle);
+ windows->command.data=MagickMenus;
+ (void) MagickXCommandWidget(display,windows,CommandMenu,
+ (XEvent *) NULL);
+ break;
+ }
+ if (*event.xclient.data.l == (long) windows->im_update_colormap)
+ {
+ /*
+ Update graphic context and window colormap.
+ */
+ for (i=0; i < (int) number_windows; i++)
+ {
+ if (magick_windows[i]->id == windows->icon.id)
+ continue;
+ context_values.background=pixel->background_color.pixel;
+ context_values.foreground=pixel->foreground_color.pixel;
+ (void) XChangeGC(display,magick_windows[i]->annotate_context,
+ context_mask,&context_values);
+ (void) XChangeGC(display,magick_windows[i]->widget_context,
+ context_mask,&context_values);
+ context_values.background=pixel->foreground_color.pixel;
+ context_values.foreground=pixel->background_color.pixel;
+ context_values.plane_mask=
+ context_values.background ^ context_values.foreground;
+ (void) XChangeGC(display,magick_windows[i]->highlight_context,
+ context_mask | GCPlaneMask,&context_values);
+ magick_windows[i]->attributes.background_pixel=
+ pixel->background_color.pixel;
+ magick_windows[i]->attributes.border_pixel=
+ pixel->border_color.pixel;
+ magick_windows[i]->attributes.colormap=map_info->colormap;
+ (void) XChangeWindowAttributes(display,magick_windows[i]->id,
+ magick_windows[i]->mask,&magick_windows[i]->attributes);
+ }
+ if (windows->pan.mapped)
+ {
+ (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
+ windows->pan.pixmap);
+ (void) XClearWindow(display,windows->pan.id);
+ MagickXDrawPanRectangle(display,windows);
+ }
+ if (windows->backdrop.id != (Window) NULL)
+ (void) XInstallColormap(display,map_info->colormap);
+ break;
+ }
+ if (*event.xclient.data.l == (long) windows->im_former_image)
+ {
+ *state|=FormerImageState | ExitState;
+ break;
+ }
+ if (*event.xclient.data.l == (long) windows->im_next_image)
+ {
+ *state|=NextImageState | ExitState;
+ break;
+ }
+ if (*event.xclient.data.l == (long) windows->im_retain_colors)
+ {
+ *state|=RetainColorsState;
+ break;
+ }
+ if (*event.xclient.data.l == (long) windows->im_exit)
+ {
+ *state|=ExitState;
+ break;
+ }
+ break;
+ }
+ if (event.xclient.message_type == windows->dnd_protocols)
+ {
+ Atom
+ selection,
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ Display image named by the Drag-and-Drop selection.
+ */
+ if ((*event.xclient.data.l != 2) && (*event.xclient.data.l != 128))
+ break;
+ selection=XInternAtom(display,"DndSelection",False);
+ status=XGetWindowProperty(display,root_window,selection,0L,
+ MaxTextExtent-1,False,(Atom) AnyPropertyType,&type,&format,
+ &length,&after,&data);
+ if ((status != Success) || (length == 0))
+ break;
+ if (*event.xclient.data.l == 2)
+ {
+ /*
+ Offix DND.
+ */
+ (void) strlcpy(resource_info->image_info->filename,
+ (char *) data,MaxTextExtent);
+ }
+ else
+ {
+ /*
+ XDND.
+ */
+ if (strncmp((char *) data, "file:", 5) != 0)
+ {
+ (void) XFree((void *) data);
+ break;
+ }
+ (void) strlcpy(resource_info->image_info->filename,
+ ((char *) data)+5,MaxTextExtent);
+ }
+ nexus=
+ ReadImage(resource_info->image_info,&display_image->exception);
+ if (display_image->exception.severity != UndefinedException)
+ MagickError2(display_image->exception.severity,
+ display_image->exception.reason,
+ display_image->exception.description);
+ if (nexus != (Image *) NULL)
+ *state|=NextImageState | ExitState;
+ (void) XFree((void *) data);
+ break;
+ }
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l != (long) windows->wm_delete_window)
+ break;
+ (void) XWithdrawWindow(display,event.xclient.window,
+ visual_info->screen);
+ if (event.xclient.window == windows->image.id)
+ {
+ *state|=ExitState;
+ break;
+ }
+ if (event.xclient.window == windows->pan.id)
+ {
+ /*
+ Restore original image size when pan window is deleted.
+ */
+ windows->image.window_changes.width=windows->image.ximage->width;
+ windows->image.window_changes.height=windows->image.ximage->height;
+ (void) MagickXConfigureImage(display,resource_info,windows,
+ display_image);
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Configure Notify: 0x%lx %dx%d+%d+%d %d",event.xconfigure.window,
+ event.xconfigure.width,event.xconfigure.height,event.xconfigure.x,
+ event.xconfigure.y,event.xconfigure.send_event);
+ if (event.xconfigure.window == windows->image.id)
+ {
+ /*
+ Image window has a new configuration.
+ */
+ if (event.xconfigure.send_event != 0)
+ {
+ XWindowChanges
+ window_changes;
+
+ /*
+ Position the transient windows relative of the Image window.
+ */
+ if (windows->command.geometry == (char *) NULL)
+ if (!windows->command.mapped)
+ {
+ windows->command.x=
+ event.xconfigure.x-windows->command.width-25;
+ windows->command.y=event.xconfigure.y;
+ MagickXConstrainWindowPosition(display,&windows->command);
+ window_changes.x=windows->command.x;
+ window_changes.y=windows->command.y;
+ (void) XReconfigureWMWindow(display,windows->command.id,
+ windows->command.screen,CWX | CWY,&window_changes);
+ }
+ if (windows->widget.geometry == (char *) NULL)
+ if (!windows->widget.mapped)
+ {
+ windows->widget.x=
+ event.xconfigure.x+event.xconfigure.width/10;
+ windows->widget.y=
+ event.xconfigure.y+event.xconfigure.height/10;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,
+ windows->widget.screen,CWX | CWY,&window_changes);
+ }
+ if (windows->magnify.geometry == (char *) NULL)
+ if (!windows->magnify.mapped)
+ {
+ windows->magnify.x=
+ event.xconfigure.x+event.xconfigure.width+25;
+ windows->magnify.y=event.xconfigure.y;
+ MagickXConstrainWindowPosition(display,&windows->magnify);
+ window_changes.x=windows->magnify.x;
+ window_changes.y=windows->magnify.y;
+ (void) XReconfigureWMWindow(display,windows->magnify.id,
+ windows->magnify.screen,CWX | CWY,&window_changes);
+ }
+ if (windows->pan.geometry == (char *) NULL)
+ if (!windows->pan.mapped)
+ {
+ windows->pan.x=
+ event.xconfigure.x+event.xconfigure.width+25;
+ windows->pan.y=
+ event.xconfigure.y+windows->magnify.height+50;
+ MagickXConstrainWindowPosition(display,&windows->pan);
+ window_changes.x=windows->pan.x;
+ window_changes.y=windows->pan.y;
+ (void) XReconfigureWMWindow(display,windows->pan.id,
+ windows->pan.screen,CWX | CWY,&window_changes);
+ }
+ }
+ if ((event.xconfigure.width == (long) windows->image.width) &&
+ (event.xconfigure.height == (long) windows->image.height))
+ break;
+ windows->image.width=event.xconfigure.width;
+ windows->image.height=event.xconfigure.height;
+ windows->image.x=0;
+ windows->image.y=0;
+ if (display_image->montage != (char *) NULL)
+ {
+ windows->image.x=vid_info.x;
+ windows->image.y=vid_info.y;
+ }
+ if (windows->image.mapped && windows->image.stasis)
+ {
+ /*
+ Update Image window configuration.
+ */
+ windows->image.window_changes.width=event.xconfigure.width;
+ windows->image.window_changes.height=event.xconfigure.height;
+ (void) MagickXConfigureImage(display,resource_info,windows,
+ display_image);
+ }
+ if ((event.xconfigure.width < windows->image.ximage->width) ||
+ (event.xconfigure.height < windows->image.ximage->height))
+ {
+ (void) XMapRaised(display,windows->pan.id);
+ MagickXDrawPanRectangle(display,windows);
+ }
+ else
+ if (windows->pan.mapped)
+ (void) XWithdrawWindow(display,windows->pan.id,
+ windows->pan.screen);
+ break;
+ }
+ if (event.xconfigure.window == windows->magnify.id)
+ {
+ unsigned int
+ magnify;
+
+ /*
+ Magnify window has a new configuration.
+ */
+ windows->magnify.width=event.xconfigure.width;
+ windows->magnify.height=event.xconfigure.height;
+ if (!windows->magnify.mapped)
+ break;
+ magnify=1;
+ while ((int) magnify <= event.xconfigure.width)
+ magnify<<=1;
+ while ((int) magnify <= event.xconfigure.height)
+ magnify<<=1;
+ magnify>>=1;
+ if (((int) magnify != event.xconfigure.width) ||
+ ((int) magnify != event.xconfigure.height))
+ {
+ window_changes.width=magnify;
+ window_changes.height=magnify;
+ (void) XReconfigureWMWindow(display,windows->magnify.id,
+ windows->magnify.screen,CWWidth | CWHeight,&window_changes);
+ break;
+ }
+ if (windows->magnify.mapped && windows->magnify.stasis)
+ {
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ status=MagickXMakeImage(display,resource_info,&windows->magnify,
+ display_image,windows->magnify.width,windows->magnify.height);
+ MagickXMakeMagnifyImage(display,windows);
+ (void) SetMonitorHandler(handler);
+ }
+ break;
+ }
+ if (event.xconfigure.window == windows->pan.id)
+ {
+ /*
+ Pan icon window has a new configuration.
+ */
+ if (event.xconfigure.send_event != 0)
+ {
+ windows->pan.x=event.xconfigure.x;
+ windows->pan.y=event.xconfigure.y;
+ }
+ windows->pan.width=event.xconfigure.width;
+ windows->pan.height=event.xconfigure.height;
+ break;
+ }
+ if (event.xconfigure.window == windows->icon.id)
+ {
+ /*
+ Icon window has a new configuration.
+ */
+ windows->icon.width=event.xconfigure.width;
+ windows->icon.height=event.xconfigure.height;
+ break;
+ }
+ break;
+ }
+ case DestroyNotify:
+ {
+ /*
+ Group leader has exited.
+ */
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Destroy Notify: 0x%lx",
+ event.xdestroywindow.window);
+ if (event.xdestroywindow.window == windows->group_leader.id)
+ {
+ *state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case EnterNotify:
+ {
+ /*
+ Selectively install colormap.
+ */
+ if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
+ {
+ if (event.xcrossing.mode != NotifyUngrab)
+ {
+ XInductColormap(display,map_info->colormap);
+ }
+ }
+ break;
+ }
+ case Expose:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Expose: 0x%lx %dx%d+%d+%d",event.xexpose.window,
+ event.xexpose.width,event.xexpose.height,event.xexpose.x,
+ event.xexpose.y);
+ /*
+ Refresh windows that are now exposed.
+ */
+ if (event.xexpose.window == windows->image.id)
+ if (windows->image.mapped)
+ {
+ MagickXRefreshWindow(display,&windows->image,&event);
+ timer=time((time_t *) NULL)+(long) display_image->delay/100+1;
+ break;
+ }
+ if (event.xexpose.window == windows->magnify.id)
+ if (event.xexpose.count == 0)
+ if (windows->magnify.mapped)
+ {
+ MagickXMakeMagnifyImage(display,windows);
+ break;
+ }
+ if (event.xexpose.window == windows->pan.id)
+ if (event.xexpose.count == 0)
+ {
+ MagickXDrawPanRectangle(display,windows);
+ break;
+ }
+ if (event.xexpose.window == windows->icon.id)
+ if (event.xexpose.count == 0)
+ {
+ MagickXRefreshWindow(display,&windows->icon,&event);
+ break;
+ }
+ break;
+ }
+ case KeyPress:
+ {
+ int
+ length;
+
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Key press: %d 0x%lx (%.1024s)",event.xkey.state,key_symbol,
+ command);
+ if (event.xkey.window == windows->image.id)
+ {
+ command_type=MagickXImageWindowCommand(display,resource_info,windows,
+ event.xkey.state,key_symbol,&display_image);
+ if (command_type != NullCommand)
+ nexus=MagickXMagickCommand(display,resource_info,windows,command_type,
+ &display_image);
+ }
+ if (event.xkey.window == windows->magnify.id)
+ MagickXMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol);
+ if (event.xkey.window == windows->pan.id)
+ {
+ if (key_symbol == XK_q)
+ (void) XWithdrawWindow(display,windows->pan.id,
+ windows->pan.screen);
+ else
+ if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
+ MagickXTextViewWidget(display,resource_info,windows,False,
+ "Help Viewer - Image Pan",ImagePanHelp);
+ else
+ MagickXTranslateImage(display,windows,*image,key_symbol);
+ }
+ timer=time((time_t *) NULL)+(long) display_image->delay/100+1;
+ break;
+ }
+ case KeyRelease:
+ {
+ /*
+ Respond to a user key release.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Key release: 0x%lx (%c)",key_symbol,*command);
+ break;
+ }
+ case LeaveNotify:
+ {
+ /*
+ Selectively uninstall colormap.
+ */
+ if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
+ {
+ if (event.xcrossing.mode != NotifyUngrab)
+ {
+ XUninductColormap(display,map_info->colormap);
+ }
+ }
+ break;
+ }
+ case MapNotify:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Map Notify: 0x%lx",
+ event.xmap.window);
+ if (event.xmap.window == windows->backdrop.id)
+ {
+ (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
+ CurrentTime);
+ windows->backdrop.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->image.id)
+ {
+ if (windows->backdrop.id != (Window) NULL)
+ (void) XInstallColormap(display,map_info->colormap);
+ if (LocaleCompare(display_image->magick,"LOGO") == 0)
+ {
+ if (LocaleCompare(display_image->filename,"Untitled") == 0)
+ nexus=MagickXOpenImage(display,resource_info,windows,False);
+ else
+ *state|=NextImageState | ExitState;
+ }
+ if (((int) windows->image.width < windows->image.ximage->width) ||
+ ((int) windows->image.height < windows->image.ximage->height))
+ (void) XMapRaised(display,windows->pan.id);
+ windows->image.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->magnify.id)
+ {
+ MagickXMakeMagnifyImage(display,windows);
+ windows->magnify.mapped=True;
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ break;
+ }
+ if (event.xmap.window == windows->pan.id)
+ {
+ MagickXMakePanImage(display,resource_info,windows,display_image);
+ windows->pan.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->info.id)
+ {
+ windows->info.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->icon.id)
+ {
+ unsigned int
+ taint;
+
+ /*
+ Create an icon image.
+ */
+ taint=display_image->taint;
+ MagickXMakeStandardColormap(display,icon_visual,icon_resources,
+ display_image,icon_map,icon_pixel);
+ (void) MagickXMakeImage(display,icon_resources,&windows->icon,
+ display_image,windows->icon.width,windows->icon.height);
+ display_image->taint=taint;
+ (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
+ windows->icon.pixmap);
+ (void) XClearWindow(display,windows->icon.id);
+ (void) XWithdrawWindow(display,windows->info.id,
+ windows->info.screen);
+ windows->icon.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->command.id)
+ {
+ windows->command.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->popup.id)
+ {
+ windows->popup.mapped=True;
+ break;
+ }
+ if (event.xmap.window == windows->widget.id)
+ {
+ windows->widget.mapped=True;
+ break;
+ }
+ break;
+ }
+ case MappingNotify:
+ {
+ (void) XRefreshKeyboardMapping(&event.xmapping);
+ break;
+ }
+ case NoExpose:
+ break;
+ case PropertyNotify:
+ {
+ Atom
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Property Notify: 0x%lx 0x%lx %d",event.xproperty.window,
+ event.xproperty.atom,event.xproperty.state);
+ if (event.xproperty.atom != windows->im_remote_command)
+ break;
+ /*
+ Display image named by the remote command protocol.
+ */
+ status=XGetWindowProperty(display,event.xproperty.window,
+ event.xproperty.atom,0L,MaxTextExtent-1,False,(Atom) AnyPropertyType,
+ &type,&format,&length,&after,&data);
+ if ((status != Success) || (length == 0))
+ break;
+ (void) strlcpy(resource_info->image_info->filename,(char *) data,
+ MaxTextExtent);
+ nexus=ReadImage(resource_info->image_info,&display_image->exception);
+ if (display_image->exception.severity != UndefinedException)
+ MagickError2(display_image->exception.severity,
+ display_image->exception.reason,
+ display_image->exception.description);
+ if (nexus != (Image *) NULL)
+ *state|=NextImageState | ExitState;
+ (void) XFree((void *) data);
+ break;
+ }
+ case ReparentNotify:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "Reparent Notify: 0x%lx=>0x%lx",event.xreparent.parent,
+ event.xreparent.window);
+ break;
+ }
+ case UnmapNotify:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Unmap Notify: 0x%lx",
+ event.xunmap.window);
+ if (event.xunmap.window == windows->backdrop.id)
+ {
+ windows->backdrop.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->image.id)
+ {
+ windows->image.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->magnify.id)
+ {
+ windows->magnify.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->pan.id)
+ {
+ windows->pan.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->info.id)
+ {
+ windows->info.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->icon.id)
+ {
+ if (map_info->colormap == icon_map->colormap)
+ MagickXConfigureImageColormap(display,resource_info,windows,
+ display_image);
+ (void) MagickXFreeStandardColormap(display,icon_visual,icon_map,
+ icon_pixel);
+ windows->icon.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->command.id)
+ {
+ windows->command.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->popup.id)
+ {
+ if (windows->backdrop.id != (Window) NULL)
+ (void) XSetInputFocus(display,windows->image.id,RevertToParent,
+ CurrentTime);
+ windows->popup.mapped=False;
+ break;
+ }
+ if (event.xunmap.window == windows->widget.id)
+ {
+ if (windows->backdrop.id != (Window) NULL)
+ (void) XSetInputFocus(display,windows->image.id,RevertToParent,
+ CurrentTime);
+ windows->widget.mapped=False;
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ if (IsEventLogging())
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d",
+ event.type);
+ break;
+ }
+ }
+ }
+ while (!(*state & ExitState));
+ if (!(*state & ExitState))
+ (void) MagickXMagickCommand(display,resource_info,windows,FreeBuffersCommand,
+ &display_image);
+ else
+ {
+ /*
+ Query user if image has changed.
+ */
+ if (!resource_info->immutable && display_image->taint)
+ {
+ status=MagickXConfirmWidget(display,windows,"Your image changed.",
+ "Do you want to save it");
+ if (status == 0)
+ *state&=(~ExitState);
+ else
+ if (status > 0)
+ (void) MagickXMagickCommand(display,resource_info,windows,SaveCommand,
+ &display_image);
+ }
+ }
+ if ((windows->visual_info->class == GrayScale) ||
+ (windows->visual_info->class == PseudoColor) ||
+ (windows->visual_info->class == DirectColor))
+ {
+ /*
+ Withdraw pan and Magnify window.
+ */
+ if (windows->info.mapped)
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ if (windows->magnify.mapped)
+ (void) XWithdrawWindow(display,windows->magnify.id,
+ windows->magnify.screen);
+ if (windows->command.mapped)
+ (void) XWithdrawWindow(display,windows->command.id,
+ windows->command.screen);
+ }
+ if (windows->pan.mapped)
+ (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
+ if (!resource_info->backdrop)
+ if (windows->backdrop.mapped)
+ {
+ (void) XWithdrawWindow(display,windows->backdrop.id,
+ windows->backdrop.screen);
+ (void) XDestroyWindow(display,windows->backdrop.id);
+ windows->backdrop.id=(Window) NULL;
+ (void) XWithdrawWindow(display,windows->image.id,windows->image.screen);
+ (void) XDestroyWindow(display,windows->image.id);
+ windows->image.id=(Window) NULL;
+ }
+ /*
+ Enable application cursor if progress indication enabled.
+ */
+ if (resource_info->image_info->progress)
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ if (!resource_info->immutable || (display_image->next != (Image *) NULL))
+ if ((*state & FormerImageState) || (*state & NextImageState))
+ *state&=(~ExitState);
+ if (*state & ExitState)
+ {
+ /*
+ Free Standard Colormap.
+ */
+ (void) MagickXFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
+ if (resource_info->map_type == (char *) NULL)
+ (void) MagickXFreeStandardColormap(display,visual_info,map_info,pixel);
+ /*
+ Free X resources.
+ */
+ if (resource_info->backdrop)
+ (void) XFreeCursor(display,windows->backdrop.cursor);
+ if (resource_info->copy_image != (Image *) NULL)
+ {
+ DestroyImage(resource_info->copy_image);
+ resource_info->copy_image=(Image *) NULL;
+ }
+ MagickXDestroyXWindows(windows);
+ }
+
+ DestroyWindowsImage(windows,icon);
+ DestroyWindowsImage(windows,pan);
+ DestroyWindowsImage(windows,magnify);
+
+ (void) XSync(display,False);
+ /*
+ Restore our progress monitor and warning handlers.
+ */
+ (void) SetMonitorHandler(monitor_handler);
+ (void) SetErrorHandler(warning_handler);
+ (void) SetWarningHandler(warning_handler);
+ /*
+ Change to home directory.
+ */
+ if (getcwd(working_directory,MaxTextExtent-1) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+ if ((strlen(resource_info->home_directory) > 0) &&
+ (chdir(resource_info->home_directory) != 0))
+ {
+ MagickFatalError(ConfigureFatalError,UnableToRestoreCurrentDirectory,
+ resource_info->home_directory);
+ }
+ *image=display_image;
+ return(nexus);
+}
+#endif
diff --git a/magick/display.h b/magick/display.h
new file mode 100644
index 0000000..8c897fc
--- /dev/null
+++ b/magick/display.h
@@ -0,0 +1,1562 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Methods to Interactively Display and Edit an Image.
+*/
+#ifndef _MAGICK_DISPLAY_H
+#define _MAGICK_DISPLAY_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Define declarations.
+*/
+#define MaxColors Min(windows->visual_info->colormap_size,256)
+
+/*
+ Constant declarations.
+*/
+static const unsigned char
+ HighlightBitmap[8] =
+ {
+ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
+ },
+ ShadowBitmap[8] =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+static const char
+ *NoiseTypes[] =
+ {
+ "Uniform",
+ "Gaussian",
+ "Multiplicative",
+ "Impulse",
+ "Lapacian",
+ "Poisson",
+ (char *) NULL
+ },
+ *PageSizes[]=
+ {
+ "Letter",
+ "Tabloid",
+ "Ledger",
+ "Legal",
+ "Statement",
+ "Executive",
+ "A3",
+ "A4",
+ "A5",
+ "B4",
+ "B5",
+ "Folio",
+ "Quarto",
+ "10x14",
+ (char *) NULL
+ },
+ *PreviewTypes[] =
+ {
+ "Rotate",
+ "Shear",
+ "Roll",
+ "Hue",
+ "Saturation",
+ "Brightness",
+ "Gamma",
+ "Spiff",
+ "Dull",
+ "Grayscale",
+ "Quantize",
+ "Despeckle",
+ "Reduce Noise",
+ "Add Noise",
+ "Sharpen",
+ "Blur",
+ "Threshold",
+ "Edge Detect",
+ "Spread",
+ "Solarize",
+ "Shade",
+ "Raise",
+ "Segment",
+ "Swirl",
+ "Implode",
+ "Wave",
+ "Oil Paint",
+ "Charcoal Drawing",
+ "JPEG",
+ (char *) NULL
+ };
+
+/*
+ Help widget declarations.
+*/
+static const char
+ *ImageAnnotateHelp[]=
+ {
+ "In annotate mode, the Command widget has these options:",
+ "",
+ " Font Name",
+ " fixed",
+ " variable",
+ " 5x8",
+ " 6x10",
+ " 7x13bold",
+ " 8x13bold",
+ " 9x15bold",
+ " 10x20",
+ " 12x24",
+ " Browser...",
+ " Font Color",
+ " black",
+ " blue",
+ " cyan",
+ " green",
+ " gray",
+ " red",
+ " magenta",
+ " yellow",
+ " white",
+ " transparent",
+ " Browser...",
+ " Font Color",
+ " black",
+ " blue",
+ " cyan",
+ " green",
+ " gray",
+ " red",
+ " magenta",
+ " yellow",
+ " white",
+ " transparent",
+ " Browser...",
+ " Rotate Text",
+ " -90",
+ " -45",
+ " -30",
+ " 0",
+ " 30",
+ " 45",
+ " 90",
+ " 180",
+ " Dialog...",
+ " Help",
+ " Dismiss",
+ "",
+ "Choose a font name from the Font Name sub-menu. Additional",
+ "font names can be specified with the font browser. You can",
+ "change the menu names by setting the X resources font1",
+ "through font9.",
+ "",
+ "Choose a font color from the Font Color sub-menu.",
+ "Additional font colors can be specified with the color",
+ "browser. You can change the menu colors by setting the X",
+ "resources pen1 through pen9.",
+ "",
+ "If you select the color browser and press Grab, you can",
+ "choose the font color by moving the pointer to the desired",
+ "color on the screen and press any button.",
+ "",
+ "If you choose to rotate the text, choose Rotate Text from the",
+ "menu and select an angle. Typically you will only want to",
+ "rotate one line of text at a time. Depending on the angle you",
+ "choose, subsequent lines may end up overwriting each other.",
+ "",
+ "Choosing a font and its color is optional. The default font",
+ "is fixed and the default color is black. However, you must",
+ "choose a location to begin entering text and press button 1.",
+ "An underscore character will appear at the location of the",
+ "pointer. The cursor changes to a pencil to indicate you are",
+ "in text mode. To exit immediately, press Dismiss.",
+ "",
+ "In text mode, any key presses will display the character at",
+ "the location of the underscore and advance the underscore",
+ "cursor. Enter your text and once completed press Apply to",
+ "finish your image annotation. To correct errors press BACK",
+ "SPACE. To delete an entire line of text, press DELETE. Any",
+ "text that exceeds the boundaries of the image window is",
+ "automatically continued onto the next line.",
+ "",
+ "The actual color you request for the font is saved in the",
+ "image. However, the color that appears in your image window",
+ "may be different. For example, on a monochrome screen the",
+ "text will appear black or white even if you choose the color",
+ "red as the font color. However, the image saved to a file",
+ "with -write is written with red lettering. To assure the",
+ "correct color text in the final image, any PseudoClass image",
+ "is promoted to DirectClass (see miff(5)). To force a",
+ "PseudoClass image to remain PseudoClass, use -colors.",
+ (char *) NULL,
+ },
+ *ImageChopHelp[]=
+ {
+ "In chop mode, the Command widget has these options:",
+ "",
+ " Direction",
+ " horizontal",
+ " vertical",
+ " Help",
+ " Dismiss",
+ "",
+ "If the you choose the horizontal direction (this is the",
+ "default), the area of the image between the two horizontal",
+ "endpoints of the chop line is removed. Otherwise, the area",
+ "of the image between the two vertical endpoints of the chop",
+ "line is removed.",
+ "",
+ "Select a location within the image window to begin your chop,",
+ "press and hold any button. Next, move the pointer to",
+ "another location in the image. As you move a line will",
+ "connect the initial location and the pointer. When you",
+ "release the button, the area within the image to chop is",
+ "determined by which direction you choose from the Command",
+ "widget.",
+ "",
+ "To cancel the image chopping, move the pointer back to the",
+ "starting point of the line and release the button.",
+ (char *) NULL,
+ },
+ *ImageColorEditHelp[]=
+ {
+ "In color edit mode, the Command widget has these options:",
+ "",
+ " Method",
+ " point",
+ " replace",
+ " floodfill",
+ " filltoborder",
+ " reset",
+ " Pixel Color",
+ " black",
+ " blue",
+ " cyan",
+ " green",
+ " gray",
+ " red",
+ " magenta",
+ " yellow",
+ " white",
+ " Browser...",
+ " Border Color",
+ " black",
+ " blue",
+ " cyan",
+ " green",
+ " gray",
+ " red",
+ " magenta",
+ " yellow",
+ " white",
+ " Browser...",
+ " Fuzz",
+ " 0%",
+ " 2%",
+ " 5%",
+ " 10%",
+ " 15%",
+ " Dialog...",
+ " Undo",
+ " Help",
+ " Dismiss",
+ "",
+ "Choose a color editing method from the Method sub-menu",
+ "of the Command widget. The point method recolors any pixel",
+ "selected with the pointer until the button is released. The",
+ "replace method recolors any pixel that matches the color of",
+ "the pixel you select with a button press. Floodfill recolors",
+ "any pixel that matches the color of the pixel you select with",
+ "a button press and is a neighbor. Whereas filltoborder recolors",
+ "any neighbor pixel that is not the border color. Finally reset",
+ "changes the entire image to the designated color.",
+ "",
+ "Next, choose a pixel color from the Pixel Color sub-menu.",
+ "Additional pixel colors can be specified with the color",
+ "browser. You can change the menu colors by setting the X",
+ "resources pen1 through pen9.",
+ "",
+ "Now press button 1 to select a pixel within the image window",
+ "to change its color. Additional pixels may be recolored as",
+ "prescribed by the method you choose.",
+ "",
+ "If the Magnify widget is mapped, it can be helpful in positioning",
+ "your pointer within the image (refer to button 2).",
+ "",
+ "The actual color you request for the pixels is saved in the",
+ "image. However, the color that appears in your image window",
+ "may be different. For example, on a monochrome screen the",
+ "pixel will appear black or white even if you choose the",
+ "color red as the pixel color. However, the image saved to a",
+ "file with -write is written with red pixels. To assure the",
+ "correct color text in the final image, any PseudoClass image",
+ "is promoted to DirectClass (see miff(5)). To force a",
+ "PseudoClass image to remain PseudoClass, use -colors.",
+ (char *) NULL,
+ },
+ *ImageCompositeHelp[]=
+ {
+ "First a widget window is displayed requesting you to enter an",
+ "image name. Press Composite, Grab or type a file name.",
+ "Press Cancel if you choose not to create a composite image.",
+ "When you choose Grab, move the pointer to the desired window",
+ "and press any button.",
+ "",
+ "If the Composite image does not have any matte information,",
+ "you are informed and the file browser is displayed again.",
+ "Enter the name of a mask image. The image is typically",
+ "grayscale and the same size as the composite image. If the",
+ "image is not grayscale, it is converted to grayscale and the",
+ "resulting intensities are used as matte information.",
+ "",
+ "A small window appears showing the location of the cursor in",
+ "the image window. You are now in composite mode. To exit",
+ "immediately, press Dismiss. In composite mode, the Command",
+ "widget has these options:",
+ "",
+ " Operators",
+ " Over",
+ " In",
+ " Out",
+ " Atop",
+ " Xor",
+ " Plus",
+ " Minus",
+ " Add",
+ " Subtract",
+ " Difference",
+ " Multiply",
+ " Bumpmap",
+ " Copy",
+ " CopyRed",
+ " CopyGreen",
+ " CopyBlue",
+ " CopyOpacity",
+ " Clear",
+ " Dissolve",
+ " Displace",
+ " Help",
+ " Dismiss",
+ "",
+ "Choose a composite operation from the Operators sub-menu of",
+ "the Command widget. How each operator behaves is described",
+ "below. Image window is the image currently displayed on",
+ "your X server and image is the image obtained with the File",
+ "Browser widget.",
+ "",
+ "Over The result is the union of the two image shapes,",
+ " with image obscuring image window in the region of",
+ " overlap.",
+ "",
+ "In The result is simply image cut by the shape of",
+ " image window. None of the image data of image",
+ " window is in the result.",
+ "",
+ "Out The resulting image is image with the shape of",
+ " image window cut out.",
+ "",
+ "Atop The result is the same shape as image image window,",
+ " with image obscuring image window where the image",
+ " shapes overlap. Note this differs from over",
+ " because the portion of image outside image window's",
+ " shape does not appear in the result.",
+ "",
+ "Xor The result is the image data from both image and",
+ " image window that is outside the overlap region.",
+ " The overlap region is blank.",
+ "",
+ "Plus The result is just the sum of the image data.",
+ " Output values are cropped to 255 (no overflow).",
+ " This operation is independent of the matte",
+ " channels.",
+ "",
+ "Minus The result of image - image window, with underflow",
+ " cropped to zero. The matte channel is ignored (set",
+ " to 255, full coverage).",
+ "",
+ "Add The result of image + image window, with overflow",
+ " wrapping around (mod 256).",
+ "",
+ "Subtract The result of image - image window, with underflow",
+ " wrapping around (mod 256). The add and subtract",
+ " operators can be used to perform reversible",
+ " transformations.",
+ "",
+ "Difference",
+ " The result of abs(image - image window). This is",
+ " useful for comparing two very similar images.",
+ "",
+ "Multiply",
+ " The result of image * image window. This is",
+ " useful for the creation of drop-shadows.",
+ "",
+ "Bumpmap The result of surface normals from image * image",
+ " window.",
+ "",
+ "Copy The resulting image is image window replaced with",
+ " image. Here the matte information is ignored.",
+ "",
+ "CopyRed The red layer of the image window is replace with",
+ " the red layer of the image. The other layers are",
+ " untouched.",
+ "",
+ "CopyGreen",
+ " The green layer of the image window is replace with",
+ " the green layer of the image. The other layers are",
+ " untouched.",
+ "",
+ "CopyBlue The blue layer of the image window is replace with",
+ " the blue layer of the image. The other layers are",
+ " untouched.",
+ "",
+ "CopyOpacity",
+ " The matte layer of the image window is replace with",
+ " the matte layer of the image. The other layers are",
+ " untouched.",
+ "",
+ "The image compositor requires a matte, or alpha channel in",
+ "the image for some operations. This extra channel usually",
+ "defines a mask which represents a sort of a cookie-cutter",
+ "for the image. This is the case when matte is 255 (full",
+ "coverage) for pixels inside the shape, zero outside, and",
+ "between zero and 255 on the boundary. If image does not",
+ "have a matte channel, it is initialized with 0 for any pixel",
+ "matching in color to pixel location (0,0), otherwise 255.",
+ "",
+ "If you choose Dissolve, the composite operator becomes Over. The",
+ "image matte channel percent transparency is initialized to factor.",
+ "The image window is initialized to (100-factor). Where factor is the",
+ "value you specify in the Dialog widget.",
+ "",
+ "Displace shifts the image pixels as defined by a displacement",
+ "map. With this option, image is used as a displacement map.",
+ "Black, within the displacement map, is a maximum positive",
+ "displacement. White is a maximum negative displacement and",
+ "middle gray is neutral. The displacement is scaled to determine",
+ "the pixel shift. By default, the displacement applies in both the",
+ "horizontal and vertical directions. However, if you specify a mask,",
+ "image is the horizontal X displacement and mask the vertical Y",
+ "displacement.",
+ "",
+ "Note that matte information for image window is not retained",
+ "for colormapped X server visuals (e.g. StaticColor,",
+ "StaticColor, GrayScale, PseudoColor). Correct compositing",
+ "behavior may require a TrueColor or DirectColor visual or a",
+ "Standard Colormap.",
+ "",
+ "Choosing a composite operator is optional. The default",
+ "operator is replace. However, you must choose a location to",
+ "composite your image and press button 1. Press and hold the",
+ "button before releasing and an outline of the image will",
+ "appear to help you identify your location.",
+ "",
+ "The actual colors of the composite image is saved. However,",
+ "the color that appears in image window may be different.",
+ "For example, on a monochrome screen image window will appear",
+ "black or white even though your composited image may have",
+ "many colors. If the image is saved to a file it is written",
+ "with the correct colors. To assure the correct colors are",
+ "saved in the final image, any PseudoClass image is promoted",
+ "to DirectClass (see miff(5)). To force a PseudoClass image",
+ "to remain PseudoClass, use -colors.",
+ (char *) NULL,
+ },
+ *ImageCutHelp[]=
+ {
+ "In cut mode, the Command widget has these options:",
+ "",
+ " Help",
+ " Dismiss",
+ "",
+ "To define a cut region, press button 1 and drag. The",
+ "cut region is defined by a highlighted rectangle that",
+ "expands or contracts as it follows the pointer. Once you",
+ "are satisfied with the cut region, release the button.",
+ "You are now in rectify mode. In rectify mode, the Command",
+ "widget has these options:",
+ "",
+ " Cut",
+ " Help",
+ " Dismiss",
+ "",
+ "You can make adjustments by moving the pointer to one of the",
+ "cut rectangle corners, pressing a button, and dragging.",
+ "Finally, press Cut to commit your copy region. To",
+ "exit without cutting the image, press Dismiss.",
+ (char *) NULL,
+ },
+ *ImageCopyHelp[]=
+ {
+ "In copy mode, the Command widget has these options:",
+ "",
+ " Help",
+ " Dismiss",
+ "",
+ "To define a copy region, press button 1 and drag. The",
+ "copy region is defined by a highlighted rectangle that",
+ "expands or contracts as it follows the pointer. Once you",
+ "are satisfied with the copy region, release the button.",
+ "You are now in rectify mode. In rectify mode, the Command",
+ "widget has these options:",
+ "",
+ " Copy",
+ " Help",
+ " Dismiss",
+ "",
+ "You can make adjustments by moving the pointer to one of the",
+ "copy rectangle corners, pressing a button, and dragging.",
+ "Finally, press Copy to commit your copy region. To",
+ "exit without copying the image, press Dismiss.",
+ (char *) NULL,
+ },
+ *ImageCropHelp[]=
+ {
+ "In crop mode, the Command widget has these options:",
+ "",
+ " Help",
+ " Dismiss",
+ "",
+ "To define a cropping region, press button 1 and drag. The",
+ "cropping region is defined by a highlighted rectangle that",
+ "expands or contracts as it follows the pointer. Once you",
+ "are satisfied with the cropping region, release the button.",
+ "You are now in rectify mode. In rectify mode, the Command",
+ "widget has these options:",
+ "",
+ " Crop",
+ " Help",
+ " Dismiss",
+ "",
+ "You can make adjustments by moving the pointer to one of the",
+ "cropping rectangle corners, pressing a button, and dragging.",
+ "Finally, press Crop to commit your cropping region. To",
+ "exit without cropping the image, press Dismiss.",
+ (char *) NULL,
+ },
+ *ImageDrawHelp[]=
+ {
+ "The cursor changes to a crosshair to indicate you are in",
+ "draw mode. To exit immediately, press Dismiss. In draw mode,",
+ "the Command widget has these options:",
+ "",
+ " Element",
+ " point",
+ " line",
+ " rectangle",
+ " fill rectangle",
+ " circle",
+ " fill circle",
+ " ellipse",
+ " fill ellipse",
+ " polygon",
+ " fill polygon",
+ " Color",
+ " black",
+ " blue",
+ " cyan",
+ " green",
+ " gray",
+ " red",
+ " magenta",
+ " yellow",
+ " white",
+ " transparent",
+ " Browser...",
+ " Stipple",
+ " Brick",
+ " Diagonal",
+ " Scales",
+ " Vertical",
+ " Wavy",
+ " Translucent",
+ " Opaque",
+ " Open...",
+ " Width",
+ " 1",
+ " 2",
+ " 4",
+ " 8",
+ " 16",
+ " Dialog...",
+ " Undo",
+ " Help",
+ " Dismiss",
+ "",
+ "Choose a drawing primitive from the Element sub-menu.",
+ "",
+ "Choose a color from the Color sub-menu. Additional",
+ "colors can be specified with the color browser.",
+ "",
+ "If you choose the color browser and press Grab, you can",
+ "select the color by moving the pointer to the desired",
+ "color on the screen and press any button. The transparent",
+ "color updates the image matte channel and is useful for",
+ "image compositing.",
+ "",
+ "Choose a stipple, if appropriate, from the Stipple sub-menu.",
+ "Additional stipples can be specified with the file browser.",
+ "Stipples obtained from the file browser must be on disk in the",
+ "X11 bitmap format.",
+ "",
+ "Choose a width, if appropriate, from the Width sub-menu. To",
+ "choose a specific width select the Dialog widget.",
+ "",
+ "Choose a point in the Image window and press button 1 and",
+ "hold. Next, move the pointer to another location in the",
+ "image. As you move, a line connects the initial location and",
+ "the pointer. When you release the button, the image is",
+ "updated with the primitive you just drew. For polygons, the",
+ "image is updated when you press and release the button without",
+ "moving the pointer.",
+ "",
+ "To cancel image drawing, move the pointer back to the",
+ "starting point of the line and release the button.",
+ (char *) NULL,
+ },
+ *DisplayHelp[]=
+ {
+ "BUTTONS",
+ " The effects of each button press is described below. Three",
+ " buttons are required. If you have a two button mouse,",
+ " button 1 and 3 are returned. Press ALT and button 3 to",
+ " simulate button 2.",
+ "",
+ " 1 Press this button to map or unmap the Command widget.",
+ "",
+ " 2 Press and drag to define a region of the image to",
+ " magnify.",
+ "",
+ " 3 Press and drag to choose from a select set of commands.",
+ " This button behaves differently if the image being",
+ " displayed is a visual image directory. Here, choose a",
+ " particular tile of the directory and press this button and",
+ " drag to select a command from a pop-up menu. Choose from",
+ " these menu items:",
+ "",
+ " Open",
+ " Next",
+ " Former",
+ " Delete",
+ " Update",
+ "",
+ " If you choose Open, the image represented by the tile is",
+ " displayed. To return to the visual image directory, choose",
+ " Next from the Command widget. Next and Former moves to the",
+ " next or former image respectively. Choose Delete to delete",
+ " a particular image tile. Finally, choose Update to",
+ " synchronize all the image tiles with their respective",
+ " images.",
+ "",
+ "COMMAND WIDGET",
+ " The Command widget lists a number of sub-menus and commands.",
+ " They are",
+ "",
+ " File",
+ " Open...",
+ " Next",
+ " Former",
+ " Select...",
+ " Save...",
+ " Print...",
+ " Delete...",
+ " New...",
+ " Visual Directory...",
+ " Quit",
+ " Edit",
+ " Undo",
+ " Redo",
+ " Cut",
+ " Copy",
+ " Paste",
+ " View",
+ " Half Size",
+ " Original Size",
+ " Double Size",
+ " Resize...",
+ " Apply",
+ " Refresh",
+ " Restore",
+ " Transform",
+ " Crop",
+ " Chop",
+ " Flop",
+ " Flip",
+ " Rotate Right",
+ " Rotate Left",
+ " Rotate...",
+ " Shear...",
+ " Roll...",
+ " Trim Edges",
+ " Enhance",
+ " Brightness...",
+ " Saturation...",
+ " Hue...",
+ " Gamma...",
+ " Sharpen...",
+ " Dull",
+ " Equalize",
+ " Normalize",
+ " Negate",
+ " Grayscale",
+ " Map...",
+ " Quantize...",
+ " Effects",
+ " Despeckle",
+ " Emboss",
+ " Reduce Noise",
+ " Add Noise",
+ " Sharpen...",
+ " Blur...",
+ " Threshold...",
+ " Edge Detect...",
+ " Spread...",
+ " Shade...",
+ " Painting...",
+ " Segment...",
+ " F/X",
+ " Solarize...",
+ " Swirl...",
+ " Implode...",
+ " Wave...",
+ " Oil Painting...",
+ " Charcoal Drawing...",
+ " Image Edit",
+ " Annotate...",
+ " Draw...",
+ " Color...",
+ " Matte...",
+ " Composite...",
+ " Add Border...",
+ " Add Frame...",
+ " Comment...",
+ " Launch...",
+ " Region of Interest...",
+ " Miscellany",
+ " Image Info",
+ " Zoom Image",
+ " Show Preview...",
+ " Show Histogram",
+ " Show Matte",
+ " Background...",
+ " Slide Show",
+ " Preferences...",
+ " Help",
+ " Overview",
+ " Browse Documentation",
+ " About Display",
+ "",
+ " Menu items with a indented triangle have a sub-menu. They",
+ " are represented above as the indented items. To access a",
+ " sub-menu item, move the pointer to the appropriate menu and",
+ " press a button and drag. When you find the desired sub-menu",
+ " item, release the button and the command is executed. Move",
+ " the pointer away from the sub-menu if you decide not to",
+ " execute a particular command.",
+ "",
+ "KEYBOARD ACCELERATORS",
+ " Accelerators are one or two key presses that effect a",
+ " particular command. The keyboard accelerators that",
+ " display(1) understands is:",
+ "",
+ " Ctl+O Press to open an image from a file.",
+ "",
+ " space Press to display the next image.",
+ "",
+ " If the image is a multi-paged document such as a Postscript",
+ " document, you can skip ahead several pages by preceeding",
+ " this command with a number. For example to display the",
+ " fourth page beyond the current page, press 4n.",
+ "",
+ " backspace Press to display the former image.",
+ "",
+ " If the image is a multi-paged document such as a Postscript",
+ " document, you can skip behind several pages by preceeding",
+ " this command with a number. For example to display the",
+ " fourth page preceeding the current page, press 4space.",
+ "",
+ " Ctl+S Press to write the image to a file.",
+ "",
+ " Ctl+P Press to print the image to a Postscript printer.",
+ "",
+ " Ctl+D Press to delete an image file.",
+ "",
+ " Ctl+N Press to create a blank canvas.",
+ "",
+ " Ctl+Q Press to discard all images and exit program.",
+ "",
+ " Ctl+Z Press to undo last image transformation.",
+ "",
+ " Ctl+R Press to redo last image transformation.",
+ "",
+ " Ctl+X Press to cut a region of the image.",
+ "",
+ " Ctl+C Press to copy a region of the image.",
+ "",
+ " Ctl+V Press to paste a region to the image.",
+ "",
+ " < Press to half the image size.",
+ "",
+ " - Press to return to the original image size.",
+ "",
+ " > Press to double the image size.",
+ "",
+ " % Press to resize the image to a width and height you",
+ " specify.",
+ "",
+ "Cmd-A Press to make any image transformations permanent."
+ "",
+ " By default, any image size transformations are applied",
+ " to the original image to create the image displayed on",
+ " the X server. However, the transformations are not",
+ " permanent (i.e. the original image does not change",
+ " size only the X image does). For example, if you",
+ " press > the X image will appear to double in size,",
+ " but the original image will in fact remain the same size.",
+ " To force the original image to double in size, press >",
+ " followed by Cmd-A.",
+ "",
+ " @ Press to refresh the image window.",
+ "",
+ " C Press to crop the image.",
+ "",
+ " [ Press to chop the image.",
+ "",
+ " H Press to flop image in the horizontal direction.",
+ "",
+ " V Press to flip image in the vertical direction.",
+ "",
+ " / Press to rotate the image 90 degrees clockwise.",
+ "",
+ " \\ Press to rotate the image 90 degrees counter-clockwise.",
+ "",
+ " * Press to rotate the image the number of degrees you",
+ " specify.",
+ "",
+ " S Press to shear the image the number of degrees you",
+ " specify.",
+ "",
+ " R Press to roll the image.",
+ "",
+ " T Press to trim the image edges.",
+ "",
+ " Shft-H Press to vary the image hue.",
+ "",
+ " Shft-S Press to vary the color saturation.",
+ "",
+ " Shft-L Press to vary the color brightness.",
+ "",
+ " Shft-G Press to gamma correct the image.",
+ "",
+ " Shft-C Press to sharpen the image contrast.",
+ "",
+ " Shft-Z Press to dull the image contrast.",
+ "",
+ " = Press to perform histogram equalization on the image.",
+ "",
+ " Shft-N Press to perform histogram normalization on the image.",
+ "",
+ " Shft-~ Press to negate the colors of the image.",
+ "",
+ " . Press to convert the image colors to gray.",
+ "",
+ " Shft-# Press to set the maximum number of unique colors in the",
+ " image.",
+ "",
+ " F2 Press to reduce the speckles in an image.",
+ "",
+ " F3 Press to eliminate peak noise from an image.",
+ "",
+ " F4 Press to add noise to an image.",
+ "",
+ " F5 Press to sharpen an image.",
+ "",
+ " F6 Press to delete an image file.",
+ "",
+ " F7 Press to threshold the image.",
+ "",
+ " F8 Press to detect edges within an image.",
+ "",
+ " F9 Press to emboss an image.",
+ "",
+ " F10 Press to displace pixels by a random amount.",
+ "",
+ " F11 Press to negate all pixels above the threshold level.",
+ "",
+ " F12 Press to shade the image using a distant light source.",
+ "",
+ " F13 Press to lighten or darken image edges to create a 3-D effect.",
+ "",
+ " F14 Press to segment the image by color.",
+ "",
+ " Meta-S Press to swirl image pixels about the center.",
+ "",
+ " Meta-I Press to implode image pixels about the center.",
+ "",
+ " Meta-W Press to alter an image along a sine wave.",
+ "",
+ " Meta-P Press to simulate an oil painting.",
+ "",
+ " Meta-C Press to simulate a charcoal drawing.",
+ "",
+ " Alt-A Press to annotate the image with text.",
+ "",
+ " Alt-D Press to draw on an image.",
+ "",
+ " Alt-P Press to edit an image pixel color.",
+ "",
+ " Alt-M Press to edit the image matte information.",
+ "",
+ " Alt-V Press to composite the image with another.",
+ "",
+ " Alt-B Press to add a border to the image.",
+ "",
+ " Alt-F Press to add an ornamental border to the image.",
+ "",
+ " Alt-Shft-!",
+ " Press to add an image comment.",
+ "",
+ " Ctl-A Press to apply image processing techniques to a region",
+ " of interest.",
+ "",
+ " Shft-? Press to display information about the image.",
+ "",
+ " Shft-+ Press to map the zoom image window.",
+ "",
+ " Shft-P Press to preview an image enhancement, effect, or f/x.",
+ "",
+ " F1 Press to display helpful information about display(1).",
+ "",
+ " Find Press to browse documentation about ImageMagick.",
+ "",
+ " 1-9 Press to change the level of magnification.",
+ "",
+ " Use the arrow keys to move the image one pixel up, down,",
+ " left, or right within the magnify window. Be sure to first",
+ " map the magnify window by pressing button 2.",
+ "",
+ " Press ALT and one of the arrow keys to trim off one pixel",
+ " from any side of the image.",
+ (char *) NULL,
+ },
+ *ImageMatteEditHelp[]=
+ {
+ "Matte information within an image is useful for some",
+ "operations such as image compositing (See IMAGE",
+ "COMPOSITING). This extra channel usually defines a mask",
+ "which represents a sort of a cookie-cutter for the image.",
+ "This is the case when matte is 255 (full coverage) for",
+ "pixels inside the shape, zero outside, and between zero and",
+ "255 on the boundary.",
+ "",
+ "A small window appears showing the location of the cursor in",
+ "the image window. You are now in matte edit mode. To exit",
+ "immediately, press Dismiss. In matte edit mode, the Command",
+ "widget has these options:",
+ "",
+ " Method",
+ " point",
+ " replace",
+ " floodfill",
+ " filltoborder",
+ " reset",
+ " Border Color",
+ " black",
+ " blue",
+ " cyan",
+ " green",
+ " gray",
+ " red",
+ " magenta",
+ " yellow",
+ " white",
+ " Browser...",
+ " Fuzz",
+ " 0%",
+ " 2%",
+ " 5%",
+ " 10%",
+ " 15%",
+ " Dialog...",
+ " Matte",
+ " Opaque",
+ " Transparent",
+ " Dialog...",
+ " Undo",
+ " Help",
+ " Dismiss",
+ "",
+ "Choose a matte editing method from the Method sub-menu of",
+ "the Command widget. The point method changes the matte value",
+ "of any pixel selected with the pointer until the button is",
+ "is released. The replace method changes the matte value of",
+ "any pixel that matches the color of the pixel you select with",
+ "a button press. Floodfill changes the matte value of any pixel",
+ "that matches the color of the pixel you select with a button",
+ "press and is a neighbor. Whereas filltoborder changes the matte",
+ "value any neighbor pixel that is not the border color. Finally",
+ "reset changes the entire image to the designated matte value.",
+ "",
+ "Choose Matte Value and pick Opaque or Transarent. For other values",
+ "select the Dialog entry. Here a dialog appears requesting a matte",
+ "value. The value you select is assigned as the opacity value of the",
+ "selected pixel or pixels.",
+ "",
+ "Now, press any button to select a pixel within the image",
+ "window to change its matte value.",
+ "",
+ "If the Magnify widget is mapped, it can be helpful in positioning",
+ "your pointer within the image (refer to button 2).",
+ "",
+ "Matte information is only valid in a DirectClass image.",
+ "Therefore, any PseudoClass image is promoted to DirectClass",
+ "(see miff(5)). Note that matte information for PseudoClass",
+ "is not retained for colormapped X server visuals (e.g.",
+ "StaticColor, StaticColor, GrayScale, PseudoColor) unless you",
+ "immediately save your image to a file (refer to Write).",
+ "Correct matte editing behavior may require a TrueColor or",
+ "DirectColor visual or a Standard Colormap.",
+ (char *) NULL,
+ },
+ *ImagePanHelp[]=
+ {
+ "When an image exceeds the width or height of the X server",
+ "screen, display maps a small panning icon. The rectangle",
+ "within the panning icon shows the area that is currently",
+ "displayed in the the image window. To pan about the image,",
+ "press any button and drag the pointer within the panning",
+ "icon. The pan rectangle moves with the pointer and the",
+ "image window is updated to reflect the location of the",
+ "rectangle within the panning icon. When you have selected",
+ "the area of the image you wish to view, release the button.",
+ "",
+ "Use the arrow keys to pan the image one pixel up, down,",
+ "left, or right within the image window.",
+ "",
+ "The panning icon is withdrawn if the image becomes smaller",
+ "than the dimensions of the X server screen.",
+ (char *) NULL,
+ },
+ *ImagePasteHelp[]=
+ {
+ "A small window appears showing the location of the cursor in",
+ "the image window. You are now in paste mode. To exit",
+ "immediately, press Dismiss. In paste mode, the Command",
+ "widget has these options:",
+ "",
+ " Operators",
+ " over",
+ " in",
+ " out",
+ " atop",
+ " xor",
+ " plus",
+ " minus",
+ " add",
+ " subtract",
+ " difference",
+ " replace",
+ " Help",
+ " Dismiss",
+ "",
+ "Choose a composite operation from the Operators sub-menu of",
+ "the Command widget. How each operator behaves is described",
+ "below. Image window is the image currently displayed on",
+ "your X server and image is the image obtained with the File",
+ "Browser widget.",
+ "",
+ "Over The result is the union of the two image shapes,",
+ " with image obscuring image window in the region of",
+ " overlap.",
+ "",
+ "In The result is simply image cut by the shape of",
+ " image window. None of the image data of image",
+ " window is in the result.",
+ "",
+ "Out The resulting image is image with the shape of",
+ " image window cut out.",
+ "",
+ "Atop The result is the same shape as image image window,",
+ " with image obscuring image window where the image",
+ " shapes overlap. Note this differs from over",
+ " because the portion of image outside image window's",
+ " shape does not appear in the result.",
+ "",
+ "Xor The result is the image data from both image and",
+ " image window that is outside the overlap region.",
+ " The overlap region is blank.",
+ "",
+ "Plus The result is just the sum of the image data.",
+ " Output values are cropped to 255 (no overflow).",
+ " This operation is independent of the matte",
+ " channels.",
+ "",
+ "Minus The result of image - image window, with underflow",
+ " cropped to zero. The matte channel is ignored (set",
+ " to 255, full coverage).",
+ "",
+ "Add The result of image + image window, with overflow",
+ " wrapping around (mod 256).",
+ "",
+ "Subtract The result of image - image window, with underflow",
+ " wrapping around (mod 256). The add and subtract",
+ " operators can be used to perform reversible",
+ " transformations.",
+ "",
+ "Difference",
+ " The result of abs(image - image window). This is",
+ " useful for comparing two very similar images.",
+ "",
+ "Copy The resulting image is image window replaced with",
+ " image. Here the matte information is ignored.",
+ "",
+ "CopyRed The red layer of the image window is replace with",
+ " the red layer of the image. The other layers are",
+ " untouched.",
+ "",
+ "CopyGreen",
+ " The green layer of the image window is replace with",
+ " the green layer of the image. The other layers are",
+ " untouched.",
+ "",
+ "CopyBlue The blue layer of the image window is replace with",
+ " the blue layer of the image. The other layers are",
+ " untouched.",
+ "",
+ "CopyOpacity",
+ " The matte layer of the image window is replace with",
+ " the matte layer of the image. The other layers are",
+ " untouched.",
+ "",
+ "The image compositor requires a matte, or alpha channel in",
+ "the image for some operations. This extra channel usually",
+ "defines a mask which represents a sort of a cookie-cutter",
+ "for the image. This is the case when matte is 255 (full",
+ "coverage) for pixels inside the shape, zero outside, and",
+ "between zero and 255 on the boundary. If image does not",
+ "have a matte channel, it is initialized with 0 for any pixel",
+ "matching in color to pixel location (0,0), otherwise 255.",
+ "",
+ "Note that matte information for image window is not retained",
+ "for colormapped X server visuals (e.g. StaticColor,",
+ "StaticColor, GrayScale, PseudoColor). Correct compositing",
+ "behavior may require a TrueColor or DirectColor visual or a",
+ "Standard Colormap.",
+ "",
+ "Choosing a composite operator is optional. The default",
+ "operator is replace. However, you must choose a location to",
+ "paste your image and press button 1. Press and hold the",
+ "button before releasing and an outline of the image will",
+ "appear to help you identify your location.",
+ "",
+ "The actual colors of the pasted image is saved. However,",
+ "the color that appears in image window may be different.",
+ "For example, on a monochrome screen image window will appear",
+ "black or white even though your pasted image may have",
+ "many colors. If the image is saved to a file it is written",
+ "with the correct colors. To assure the correct colors are",
+ "saved in the final image, any PseudoClass image is promoted",
+ "to DirectClass (see miff(5)). To force a PseudoClass image",
+ "to remain PseudoClass, use -colors.",
+ (char *) NULL,
+ },
+ *ImageROIHelp[]=
+ {
+ "In region of interest mode, the Command widget has these",
+ "options:",
+ "",
+ " Help",
+ " Dismiss",
+ "",
+ "To define a region of interest, press button 1 and drag.",
+ "The region of interest is defined by a highlighted rectangle",
+ "that expands or contracts as it follows the pointer. Once",
+ "you are satisfied with the region of interest, release the",
+ "button. You are now in apply mode. In apply mode the",
+ "Command widget has these options:",
+ "",
+ " File",
+ " Save...",
+ " Print...",
+ " Edit",
+ " Undo",
+ " Redo",
+ " Transform",
+ " Flop",
+ " Flip",
+ " Rotate Right",
+ " Rotate Left",
+ " Enhance",
+ " Hue...",
+ " Saturation...",
+ " Brightness...",
+ " Gamma...",
+ " Spiff",
+ " Dull",
+ " Equalize",
+ " Normalize",
+ " Negate",
+ " Grayscale",
+ " Map...",
+ " Quantize...",
+ " Effects",
+ " Despeckle",
+ " Emboss",
+ " Reduce Noise",
+ " Sharpen...",
+ " Blur...",
+ " Threshold...",
+ " Edge Detect...",
+ " Spread...",
+ " Shade...",
+ " Raise...",
+ " Segment...",
+ " F/X",
+ " Solarize...",
+ " Swirl...",
+ " Implode...",
+ " Wave...",
+ " Oil Painting...",
+ " Charcoal Drawing...",
+ " Miscellany",
+ " Image Info",
+ " Zoom Image",
+ " Show Preview...",
+ " Show Histogram",
+ " Show Matte",
+ " Help",
+ " Dismiss",
+ "",
+ "You can make adjustments to the region of interest by moving",
+ "the pointer to one of the rectangle corners, pressing a",
+ "button, and dragging. Finally, choose an image processing",
+ "technique from the Command widget. You can choose more than",
+ "one image processing technique to apply to an area.",
+ "Alternatively, you can move the region of interest before",
+ "applying another image processing technique. To exit, press",
+ "Dismiss.",
+ (char *) NULL,
+ },
+ *ImageRotateHelp[]=
+ {
+ "In rotate mode, the Command widget has these options:",
+ "",
+ " Pixel Color",
+ " black",
+ " blue",
+ " cyan",
+ " green",
+ " gray",
+ " red",
+ " magenta",
+ " yellow",
+ " white",
+ " Browser...",
+ " Direction",
+ " horizontal",
+ " vertical",
+ " Help",
+ " Dismiss",
+ "",
+ "Choose a background color from the Pixel Color sub-menu.",
+ "Additional background colors can be specified with the color",
+ "browser. You can change the menu colors by setting the X",
+ "resources pen1 through pen9.",
+ "",
+ "If you choose the color browser and press Grab, you can",
+ "select the background color by moving the pointer to the",
+ "desired color on the screen and press any button.",
+ "",
+ "Choose a point in the image window and press this button and",
+ "hold. Next, move the pointer to another location in the",
+ "image. As you move a line connects the initial location and",
+ "the pointer. When you release the button, the degree of",
+ "image rotation is determined by the slope of the line you",
+ "just drew. The slope is relative to the direction you",
+ "choose from the Direction sub-menu of the Command widget.",
+ "",
+ "To cancel the image rotation, move the pointer back to the",
+ "starting point of the line and release the button.",
+ (char *) NULL,
+ };
+
+/*
+ Enumeration declarations.
+*/
+typedef enum
+{
+ CopyMode,
+ CropMode,
+ CutMode
+} ClipboardMode;
+
+typedef enum
+{
+ OpenCommand,
+ NextCommand,
+ FormerCommand,
+ SelectCommand,
+ SaveCommand,
+ PrintCommand,
+ DeleteCommand,
+ NewCommand,
+ VisualDirectoryCommand,
+ QuitCommand,
+ UndoCommand,
+ RedoCommand,
+ CutCommand,
+ CopyCommand,
+ PasteCommand,
+ HalfSizeCommand,
+ OriginalSizeCommand,
+ DoubleSizeCommand,
+ ResizeCommand,
+ ApplyCommand,
+ RefreshCommand,
+ RestoreCommand,
+ CropCommand,
+ ChopCommand,
+ FlopCommand,
+ FlipCommand,
+ RotateRightCommand,
+ RotateLeftCommand,
+ RotateCommand,
+ ShearCommand,
+ RollCommand,
+ TrimCommand,
+ HueCommand,
+ SaturationCommand,
+ BrightnessCommand,
+ GammaCommand,
+ SpiffCommand,
+ DullCommand,
+ EqualizeCommand,
+ NormalizeCommand,
+ NegateCommand,
+ GrayscaleCommand,
+ MapCommand,
+ QuantizeCommand,
+ DespeckleCommand,
+ EmbossCommand,
+ ReduceNoiseCommand,
+ AddNoiseCommand,
+ SharpenCommand,
+ BlurCommand,
+ ThresholdCommand,
+ EdgeDetectCommand,
+ SpreadCommand,
+ ShadeCommand,
+ RaiseCommand,
+ SegmentCommand,
+ SolarizeCommand,
+ SwirlCommand,
+ ImplodeCommand,
+ WaveCommand,
+ OilPaintCommand,
+ CharcoalDrawCommand,
+ AnnotateCommand,
+ DrawCommand,
+ ColorCommand,
+ MatteCommand,
+ CompositeCommand,
+ AddBorderCommand,
+ AddFrameCommand,
+ CommentCommand,
+ LaunchCommand,
+ RegionofInterestCommand,
+ ROIHelpCommand,
+ ROIDismissCommand,
+ InfoCommand,
+ ZoomCommand,
+ ShowPreviewCommand,
+ ShowHistogramCommand,
+ ShowMatteCommand,
+ BackgroundCommand,
+ SlideShowCommand,
+ PreferencesCommand,
+ HelpCommand,
+ BrowseDocumentationCommand,
+ VersionCommand,
+ SaveToUndoBufferCommand,
+ FreeBuffersCommand,
+ NullCommand
+} CommandType;
+
+typedef enum
+{
+ AnnotateNameCommand,
+ AnnotateFontColorCommand,
+ AnnotateBackgroundColorCommand,
+ AnnotateRotateCommand,
+ AnnotateHelpCommand,
+ AnnotateDismissCommand,
+ TextHelpCommand,
+ TextApplyCommand,
+ ChopDirectionCommand,
+ ChopHelpCommand,
+ ChopDismissCommand,
+ HorizontalChopCommand,
+ VerticalChopCommand,
+ ColorEditMethodCommand,
+ ColorEditColorCommand,
+ ColorEditBorderCommand,
+ ColorEditFuzzCommand,
+ ColorEditUndoCommand,
+ ColorEditHelpCommand,
+ ColorEditDismissCommand,
+ CompositeOperatorsCommand,
+ CompositeDissolveCommand,
+ CompositeDisplaceCommand,
+ CompositeHelpCommand,
+ CompositeDismissCommand,
+ CropHelpCommand,
+ CropDismissCommand,
+ RectifyCopyCommand,
+ RectifyHelpCommand,
+ RectifyDismissCommand,
+ DrawElementCommand,
+ DrawColorCommand,
+ DrawStippleCommand,
+ DrawWidthCommand,
+ DrawUndoCommand,
+ DrawHelpCommand,
+ DrawDismissCommand,
+ MatteEditMethod,
+ MatteEditBorderCommand,
+ MatteEditFuzzCommand,
+ MatteEditValueCommand,
+ MatteEditUndoCommand,
+ MatteEditHelpCommand,
+ MatteEditDismissCommand,
+ PasteOperatorsCommand,
+ PasteHelpCommand,
+ PasteDismissCommand,
+ RotateColorCommand,
+ RotateDirectionCommand,
+ RotateCropCommand,
+ RotateSharpenCommand,
+ RotateHelpCommand,
+ RotateDismissCommand,
+ HorizontalRotateCommand,
+ VerticalRotateCommand,
+ TileLoadCommand,
+ TileNextCommand,
+ TileFormerCommand,
+ TileDeleteCommand,
+ TileUpdateCommand
+} ModeType;
+
+/*
+ Stipples.
+*/
+#define BricksWidth 20
+#define BricksHeight 20
+#define DiagonalWidth 16
+#define DiagonalHeight 16
+#define HighlightWidth 8
+#define HighlightHeight 8
+#define ScalesWidth 16
+#define ScalesHeight 16
+#define ShadowWidth 8
+#define ShadowHeight 8
+#define VerticalWidth 16
+#define VerticalHeight 16
+#define WavyWidth 16
+#define WavyHeight 16
+
+static const unsigned char
+ BricksBitmap[] =
+ {
+ 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00,
+ 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01,
+ 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00,
+ 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f,
+ 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01
+ },
+ DiagonalBitmap[] =
+ {
+ 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88,
+ 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22,
+ 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22
+ },
+ ScalesBitmap[] =
+ {
+ 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3, 0x80, 0x80, 0x80, 0x80,
+ 0x41, 0x41, 0x3e, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3,
+ 0x80, 0x80, 0x80, 0x80, 0x41, 0x41, 0x3e, 0x3e
+ },
+ VerticalBitmap[] =
+ {
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
+ },
+ WavyBitmap[] =
+ {
+ 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfb, 0xff,
+ 0xe7, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xe7, 0xff, 0xdf, 0xff, 0xbf,
+ 0xff, 0xbf, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f
+ };
+
+/*
+ Function prototypes.
+*/
+static CommandType
+ MagickXImageWindowCommand(Display *,MagickXResourceInfo *,MagickXWindows *,const unsigned int,
+ KeySym,Image **);
+
+static Image
+ *MagickXMagickCommand(Display *,MagickXResourceInfo *,MagickXWindows *,const CommandType,
+ Image **),
+ *MagickXOpenImage(Display *,MagickXResourceInfo *,MagickXWindows *,const unsigned int),
+ *MagickXTileImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *,XEvent *),
+ *MagickXVisualDirectoryImage(Display *,MagickXResourceInfo *,MagickXWindows *);
+
+static unsigned int
+ MagickXAnnotateEditImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *),
+ MagickXDrawEditImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image **),
+ MagickXChopImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image **),
+ MagickXCropImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *,const ClipboardMode),
+ MagickXBackgroundImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image **),
+ MagickXColorEditImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image **),
+ MagickXCompositeImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *),
+ MagickXConfigureImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *),
+ MagickXMatteEditImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image **),
+ MagickXPasteImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *),
+ MagickXPrintImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *),
+ MagickXRotateImage(Display *,MagickXResourceInfo *,MagickXWindows *,double,Image **),
+ MagickXROIImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image **),
+ MagickXSaveImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *),
+ MagickXTrimImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *);
+
+static void
+ MagickXDrawPanRectangle(Display *,MagickXWindows *),
+ MagickXImageCache(Display *,MagickXResourceInfo *,MagickXWindows *,const CommandType,Image **),
+ MagickXMagnifyImage(Display *,MagickXWindows *,XEvent *),
+ MagickXMakePanImage(Display *,MagickXResourceInfo *,MagickXWindows *,Image *),
+ MagickXPanImage(Display *,MagickXWindows *,XEvent *),
+ MagickXMagnifyWindowCommand(Display *,MagickXWindows *,const unsigned int,const KeySym),
+ MagickXSetCropGeometry(Display *,MagickXWindows *,RectangleInfo *,Image *),
+ MagickXScreenEvent(Display *,MagickXWindows *,XEvent *),
+ MagickXTranslateImage(Display *,MagickXWindows *,Image *,const KeySym);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/draw.c b/magick/draw.c
new file mode 100644
index 0000000..8496865
--- /dev/null
+++ b/magick/draw.c
@@ -0,0 +1,5873 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD RRRR AAA W W %
+% D D R R A A W W %
+% D D RRRR AAAAA W W %
+% D D R R A A W W W %
+% DDDD R R A A W W %
+% %
+% %
+% GraphicsMagick Image Vector Drawing Methods %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% March 2002 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/draw.h"
+#include "magick/enum_strings.h"
+#include "magick/gem.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define DRAW_BINARY_IMPLEMENTATION 0
+
+#define ThrowDrawException(code,reason,description) \
+{ \
+ if (context->image->exception.severity > (long)code) \
+ ThrowException(&context->image->exception,code,reason,description); \
+ return; \
+}
+#define ThrowDrawException3(code,reason,description) \
+{ \
+ if (context->image->exception.severity > (long)code) \
+ ThrowException3(&context->image->exception,code,reason,description); \
+ return; \
+}
+
+#define CurrentContext (context->graphic_context[context->index])
+#define PixelPacketMatch(p,q) (((p)->red == (q)->red) && \
+ ((p)->green == (q)->green) && ((p)->blue == (q)->blue) && \
+ ((p)->opacity == (q)->opacity))
+
+/*
+ Typedef declarations.
+*/
+typedef enum
+{
+ PathDefaultOperation,
+ PathCloseOperation, /* Z|z (none) */
+ PathCurveToOperation, /* C|c (x1 y1 x2 y2 x y)+ */
+ PathCurveToQuadraticBezierOperation, /* Q|q (x1 y1 x y)+ */
+ PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */
+ PathCurveToSmoothOperation, /* S|s (x2 y2 x y)+ */
+ PathEllipticArcOperation, /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
+ PathLineToHorizontalOperation, /* H|h x+ */
+ PathLineToOperation, /* L|l (x y)+ */
+ PathLineToVerticalOperation, /* V|v y+ */
+ PathMoveToOperation /* M|m (x y)+ */
+} PathOperation;
+
+typedef enum
+{
+ DefaultPathMode,
+ AbsolutePathMode,
+ RelativePathMode
+} PathMode;
+
+struct _DrawContext
+{
+ /* Support structures */
+ Image
+ *image;
+
+ /* MVG output string and housekeeping */
+ char
+ *mvg; /* MVG data */
+
+ size_t
+ mvg_alloc, /* total allocated memory */
+ mvg_length; /* total MVG length */
+
+ unsigned int
+ mvg_width; /* current line length */
+
+ /* Pattern support */
+ char
+ *pattern_id;
+
+ RectangleInfo
+ pattern_bounds;
+
+ size_t
+ pattern_offset;
+
+ /* Graphic context */
+ unsigned int
+ index; /* array index */
+
+ DrawInfo
+ **graphic_context;
+
+ int
+ filter_off; /* true if not filtering attributes */
+
+ /* Pretty-printing depth */
+ unsigned int
+ indent_depth; /* number of left-hand pad characters */
+
+ /* Path operation support */
+ PathOperation
+ path_operation;
+
+ PathMode
+ path_mode;
+
+ /* Structure unique signature */
+ unsigned long
+ signature;
+};
+
+/* Vector table for invoking subordinate renderers */
+#if 0
+struct _DrawVTable
+{
+ void (*DrawAnnotation)
+ (DrawContext context, const double x, const double y,
+ const unsigned char *text);
+ void (*DrawArc)
+ (DrawContext context, const double sx, const double sy,
+ const double ex, const double ey, const double sd, const double ed);
+ void (*DrawBezier)
+ (DrawContext context, const unsigned long num_coords, const PointInfo *coordinates);
+ void (*DrawCircle)
+ (DrawContext context, const double ox, const double oy,
+ const double px, const double py);
+ void (*DrawColor)
+ (DrawContext context, const double x, const double y,
+ const PaintMethod paintMethod);
+ void (*DrawComment)
+ (DrawContext context,const char* comment);
+ void (*DrawDestroyContext)
+ (DrawContext context);
+ void (*DrawEllipse)
+ (DrawContext context, const double ox, const double oy,
+ const double rx, const double ry, const double start, const double end);
+ void (*DrawComposite)
+ (DrawContext context, const CompositeOperator composite_operator,
+ const double x, const double y, const double width, const double height,
+ const Image * image );
+ void (*DrawLine)
+ (DrawContext context, const double sx, const double sy,
+ const double ex, const double ey);
+ void (*DrawMatte)
+ (DrawContext context, const double x, const double y,
+ const PaintMethod paint_method);
+ void (*DrawPathClose)
+ (DrawContext context);
+ void (*DrawPathCurveToAbsolute)
+ (DrawContext context, const double x1, const double y1,
+ const double x2, const double y2, const double x, const double y);
+ void (*DrawPathCurveToRelative)
+ (DrawContext context, const double x1, const double y1,
+ const double x2, const double y2, const double x, const double y);
+ void (*DrawPathCurveToQuadraticBezierAbsolute)
+ (DrawContext context, const double x1, const double y1,
+ const double x, const double y);
+ void (*DrawPathCurveToQuadraticBezierRelative)
+ (DrawContext context, const double x1, const double y1,
+ const double x, const double y);
+ void (*DrawPathCurveToQuadraticBezierSmoothAbsolute)
+ (DrawContext context, const double x, const double y);
+ void (*DrawPathCurveToQuadraticBezierSmoothRelative)
+ (DrawContext context, const double x, const double y);
+ void (*DrawPathCurveToSmoothAbsolute)
+ (DrawContext context, const double x2, const double y2,
+ const double x, const double y);
+ void (*DrawPathCurveToSmoothRelative)
+ (DrawContext context, const double x2, const double y2,
+ const double x, const double y);
+ void (*DrawPathEllipticArcAbsolute)
+ (DrawContext context, const double rx, const double ry,
+ const double x_axis_rotation, unsigned int large_arc_flag,
+ unsigned int sweep_flag, const double x, const double y);
+ void (*DrawPathEllipticArcRelative)
+ (DrawContext context, const double rx, const double ry,
+ const double x_axis_rotation, unsigned int large_arc_flag,
+ unsigned int sweep_flag, const double x, const double y);
+ void (*DrawPathFinish)
+ (DrawContext context);
+ void (*DrawPathLineToAbsolute)
+ (DrawContext context, const double x, const double y);
+ void (*DrawPathLineToRelative)
+ (DrawContext context, const double x, const double y);
+ void (*DrawPathLineToHorizontalAbsolute)
+ (DrawContext context, const double x);
+ void (*DrawPathLineToHorizontalRelative)
+ (DrawContext context, const double x);
+ void (*DrawPathLineToVerticalAbsolute)
+ (DrawContext context, const double y);
+ void (*DrawPathLineToVerticalRelative)
+ (DrawContext context, const double y);
+ void (*DrawPathMoveToAbsolute)
+ (DrawContext context, const double x, const double y);
+ void (*DrawPathMoveToRelative)
+ (DrawContext context, const double x, const double y);
+ void (*DrawPathStart)
+ (DrawContext context);
+ void (*DrawPoint)
+ (DrawContext context, const double x, const double y);
+ void (*DrawPolygon)
+ (DrawContext context, const unsigned long num_coords, const PointInfo * coordinates);
+ void (*DrawPolyline)
+ (DrawContext context, const unsigned long num_coords, const PointInfo * coordinates);
+ void (*DrawPopClipPath)
+ (DrawContext context);
+ void (*DrawPopDefs)
+ (DrawContext context);
+ void (*DrawPopGraphicContext)
+ (DrawContext context);
+ void (*DrawPopPattern)
+ (DrawContext context);
+ void (*DrawPushClipPath)
+ (DrawContext context, const char *clip_path_id);
+ void (*DrawPushDefs)
+ (DrawContext context);
+ void (*DrawPushGraphicContext)
+ (DrawContext context);
+ void (*DrawPushPattern)
+ (DrawContext context, const char *pattern_id,
+ const double x, const double y, const double width, const double height);
+ void (*DrawRectangle)
+ (DrawContext context, const double x1, const double y1,
+ const double x2, const double y2);
+ void (*DrawRoundRectangle)
+ (DrawContext context, double x1, double y1,
+ double x2, double y2, double rx, double ry);
+ void (*DrawAffine)
+ (DrawContext context, const AffineMatrix *affine);
+ void (*DrawSetClipPath)
+ (DrawContext context, const char *clip_path);
+ void (*DrawSetClipRule)
+ (DrawContext context, const FillRule fill_rule);
+ void (*DrawSetClipUnits)
+ (DrawContext context, const ClipPathUnits clip_units);
+ void (*DrawSetFillColor)
+ (DrawContext context, const PixelPacket * fill_color);
+ void (*DrawSetFillOpacity)
+ (DrawContext context, const double fill_opacity);
+ void (*DrawSetFillRule)
+ (DrawContext context, const FillRule fill_rule);
+ void (*DrawSetFillPatternURL)
+ (DrawContext context, const char* fill_url);
+ void (*DrawSetFont)
+ (DrawContext context, const char *font_name);
+ void (*DrawSetFontFamily)
+ (DrawContext context, const char *font_family);
+ void (*DrawSetFontSize)
+ (DrawContext context, const double font_pointsize);
+ void (*DrawSetFontStretch)
+ (DrawContext context, const StretchType font_stretch);
+ void (*DrawSetFontStyle)
+ (DrawContext context, const StyleType font_style);
+ void (*DrawSetFontWeight)
+ (DrawContext context, const unsigned long font_weight);
+ void (*DrawSetGravity)
+ (DrawContext context, const GravityType gravity);
+ void (*DrawRotate)
+ (DrawContext context, const double degrees);
+ void (*DrawScale)
+ (DrawContext context, const double x, const double y);
+ void (*DrawSkewX)
+ (DrawContext context, const double degrees);
+ void (*DrawSkewY)
+ (DrawContext context, const double degrees);
+/* void (*DrawSetStopColor) */
+/* (DrawContext context, const PixelPacket * color, const double offset); */
+ void (*DrawSetStrokeAntialias)
+ (DrawContext context, const unsigned int true_false);
+ void (*DrawSetStrokeColor)
+ (DrawContext context, const PixelPacket * stroke_color);
+ void (*DrawSetStrokeDashArray)
+ (DrawContext context,const double *dasharray);
+ void (*DrawSetStrokeDashOffset)
+ (DrawContext context,const double dashoffset);
+ void (*DrawSetStrokeLineCap)
+ (DrawContext context, const LineCap linecap);
+ void (*DrawSetStrokeLineJoin)
+ (DrawContext context, const LineJoin linejoin);
+ void (*DrawSetStrokeMiterLimit)
+ (DrawContext context,const unsigned long miterlimit);
+ void (*DrawSetStrokeOpacity)
+ (DrawContext context, const double opacity);
+ void (*DrawSetStrokePatternURL)
+ (DrawContext context, const char* stroke_url);
+ void (*DrawSetStrokeWidth)
+ (DrawContext context, const double width);
+ void (*DrawSetTextAntialias)
+ (DrawContext context, const unsigned int true_false);
+ void (*DrawSetTextDecoration)
+ (DrawContext context, const DecorationType decoration);
+ void (*DrawSetTextUnderColor)
+ (DrawContext context, const PixelPacket * color);
+ void (*DrawTranslate)
+ (DrawContext context, const double x, const double y);
+ void (*DrawSetViewbox)
+ (DrawContext context, unsigned long x1, unsigned long y1,
+ unsigned long x2, unsigned long y2);
+};
+#endif
+
+/*
+ Forward declarations.
+*/
+static int
+ MvgPrintf(DrawContext context, const char *format, ...)
+#if defined(__GNUC__)
+MAGICK_ATTRIBUTE ((format (printf, 2, 3)))
+#endif
+,
+ MvgAutoWrapPrintf(DrawContext context, const char *format, ...)
+#if defined(__GNUC__)
+MAGICK_ATTRIBUTE ((format (printf, 2, 3)))
+#endif
+;
+static void
+ MvgAppendColor(DrawContext context, const PixelPacket *color);
+
+
+/* "Printf" for MVG commands */
+static int MvgPrintf(DrawContext context, const char *format, ...)
+{
+ const size_t
+ alloc_size = MaxTextExtent * 20; /* 40K */
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ /* Allocate initial memory */
+ if (context->mvg == (char*) NULL)
+ {
+ context->mvg = MagickAllocateMemory(char *,alloc_size);
+ if( context->mvg == (char*) NULL )
+ {
+ ThrowException3(&context->image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ return -1;
+ }
+
+ context->mvg_alloc = alloc_size;
+ context->mvg_length = 0;
+ if (context->mvg == 0)
+ {
+ ThrowException3(&context->image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ return -1;
+ }
+ }
+
+ /* Re-allocate additional memory if necessary (ensure 20K unused) */
+ if (context->mvg_alloc < (context->mvg_length + MaxTextExtent * 10))
+ {
+ size_t realloc_size = context->mvg_alloc + alloc_size;
+
+ MagickReallocMemory(char *, context->mvg, realloc_size);
+ if (context->mvg == NULL)
+ {
+ ThrowException3(&context->image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ return -1;
+ }
+ context->mvg_alloc = realloc_size;
+ }
+
+ /* Write to end of existing MVG string */
+ {
+ int
+ formatted_length; /* must be a signed type! */
+
+ va_list
+ argp;
+
+ /* Pretty-print indentation */
+ while(context->mvg_width < context->indent_depth)
+ {
+ context->mvg[context->mvg_length] = ' ';
+ ++context->mvg_length;
+ ++context->mvg_width;
+ }
+ context->mvg[context->mvg_length] = 0;
+
+ /*
+ According to C99, vsnprintf() returns the number of formatted
+ bytes which WOULD have been written (not including trailing
+ '\0') if there was sufficient space available. If an output
+ error occurs, then a negative value is returned.
+
+ Under Linux glibc 2.0.6 and earlier, -1 is returned when the
+ output has been truncated.
+ */
+ {
+ ssize_t
+ space_available;
+
+ space_available=(ssize_t) context->mvg_alloc - (ssize_t) context->mvg_length - 1;
+ formatted_length = -1;
+ if (space_available > 0)
+ {
+ va_start(argp, format);
+#if defined(HAVE_VSNPRINTF)
+ formatted_length =
+ vsnprintf(context->mvg + context->mvg_length,(size_t) space_available, format, argp);
+#else
+# if defined(HAVE_VSPRINTF)
+ formatted_length = vsprintf(context->mvg + context->mvg_length, format, argp);
+# else
+# error Neither vsnprintf or vsprintf is available.
+# endif
+#endif
+ va_end(argp);
+ }
+
+ if ((formatted_length < 0) || (formatted_length > space_available))
+ {
+ ThrowException(&context->image->exception,DrawError,UnableToPrint,
+ format);
+ }
+ else
+ {
+ context->mvg_length += formatted_length;
+ context->mvg_width += formatted_length;
+ }
+ }
+ context->mvg[context->mvg_length] = 0;
+
+ /* Re-evaluate mvg_width */
+ if( (context->mvg_length > 1) &&
+ (context->mvg[context->mvg_length-1] == '\n') )
+ context->mvg_width = 0;
+
+ assert(context->mvg_length + 1 < context->mvg_alloc);
+
+ return formatted_length;
+ }
+}
+
+/* "Printf" for MVG commands, with autowrap at 78 characters */
+static int MvgAutoWrapPrintf(DrawContext context, const char *format, ...)
+{
+ va_list
+ argp;
+
+ int
+ formatted_length;
+
+ char
+ buffer[MaxTextExtent];
+
+ va_start(argp, format);
+#if defined(HAVE_VSNPRINTF)
+ formatted_length = vsnprintf(buffer, sizeof(buffer) - 1, format, argp);
+#else
+# if defined(HAVE_VSPRINTF)
+ formatted_length = vsprintf(buffer, format, argp);
+# else
+# error Neither vsnprintf or vsprintf is available.
+# endif
+#endif
+ va_end(argp);
+ buffer[sizeof(buffer)-1]=0;
+
+ if (formatted_length < 0)
+ {
+ ThrowException(&context->image->exception,DrawError,UnableToPrint,
+ format);
+ }
+ else
+ {
+ if( ((context->mvg_width + formatted_length) > 78) &&
+ buffer[formatted_length-1] != '\n' )
+ (void) MvgPrintf(context, "\n");
+
+ (void) MvgPrintf(context, "%s", buffer);
+ }
+
+ return formatted_length;
+}
+
+static void MvgAppendColor(DrawContext context, const PixelPacket *color)
+{
+ if(color->red == 0U && color->green == 0U && color->blue == 0U &&
+ color->opacity == TransparentOpacity)
+ {
+ (void) MvgPrintf(context,"none");
+ }
+ else
+ {
+ char
+ tuple[MaxTextExtent];
+
+ GetColorTuple(color,context->image->depth,context->image->matte,True,
+ tuple);
+ (void) MvgPrintf(context,"%.1024s",tuple);
+ }
+}
+
+static void MvgAppendPointsCommand(DrawContext context, const char* command,
+ const unsigned long num_coords,
+ const PointInfo * coordinates)
+{
+ const PointInfo
+ *coordinate;
+
+ size_t
+ i;
+
+ (void) MvgPrintf(context, "%.1024s", command);
+ for (i = num_coords, coordinate = coordinates; i; i--)
+ {
+ (void) MvgAutoWrapPrintf(context," %g,%g", coordinate->x, coordinate->y);
+ ++coordinate;
+ }
+
+ (void) MvgPrintf(context, "\n");
+}
+
+static void AdjustAffine(DrawContext context, const AffineMatrix *affine)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
+ (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
+ {
+ AffineMatrix
+ current;
+
+ current = CurrentContext->affine;
+ CurrentContext->affine.sx=current.sx*affine->sx+current.ry*affine->rx;
+ CurrentContext->affine.rx=current.rx*affine->sx+current.sy*affine->rx;
+ CurrentContext->affine.ry=current.sx*affine->ry+current.ry*affine->sy;
+ CurrentContext->affine.sy=current.rx*affine->ry+current.sy*affine->sy;
+ CurrentContext->affine.tx=current.sx*affine->tx+current.ry*affine->ty+current.tx;
+ CurrentContext->affine.ty=current.rx*affine->tx+current.sy*affine->ty+current.ty;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w A n n o t a t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawAnnotation() draws text on the image.
+%
+% The format of the DrawAnnotation method is:
+%
+% void DrawAnnotation(DrawContext context,
+% const double x, const double y,
+% const unsigned char *text)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: x ordinate to left of text
+%
+% o y: y ordinate to text baseline
+%
+% o text: text to draw
+%
+*/
+MagickExport void DrawAnnotation(DrawContext context,
+ const double x, const double y,
+ const unsigned char *text)
+{
+ char
+ *escaped_text;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(text != (const unsigned char *) NULL);
+
+ escaped_text=EscapeString((const char*)text,'\'');
+ if (escaped_text != (char *) NULL)
+ {
+ (void) MvgPrintf(context, "text %g,%g '%s'\n", x, y, escaped_text);
+ MagickFreeMemory(escaped_text);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w A f f i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawAffine() adjusts the current affine transformation matrix with
+% the specified affine transformation matrix. Note that the current affine
+% transform is adjusted rather than replaced.
+%
+% The format of the DrawAffine method is:
+%
+% void DrawAffine(DrawContext context, const AffineMatrix *affine)
+%
+% A description of each parameter follows:
+%
+% o context: Drawing context
+%
+% o affine: Affine matrix parameters
+%
+*/
+MagickExport void DrawAffine(DrawContext context, const AffineMatrix *affine)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(affine != (const AffineMatrix *)NULL);
+
+ AdjustAffine( context, affine );
+
+ (void) MvgPrintf(context, "affine %.6g,%.6g,%.6g,%.6g,%.6g,%.6g\n",
+ affine->sx, affine->rx, affine->ry, affine->sy,
+ affine->tx, affine->ty);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w A l l o c a t e C o n t e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawAllocateContext() allocates an initial drawing context which is an
+% opaque handle required by the remaining drawing methods.
+%
+% The format of the DrawAllocateContext method is:
+%
+% DrawContext DrawAllocateContext(const DrawInfo *draw_info,
+% Image *image)
+%
+% A description of each parameter follows:
+%
+% o draw_info: Initial drawing defaults. Set to NULL to use
+% GraphicsMagick defaults.
+%
+% o image: The image to draw on.
+%
+*/
+MagickExport DrawContext DrawAllocateContext(const DrawInfo *draw_info,
+ Image *image)
+{
+ DrawContext
+ context;
+
+ /* Allocate initial drawing context */
+ context = MagickAllocateMemory(DrawContext,sizeof(struct _DrawContext));
+ if(context == (DrawContext) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateDrawContext);
+
+ /* Support structures */
+ context->image = image;
+
+ /* MVG output string and housekeeping */
+ context->mvg = NULL;
+ context->mvg_alloc = 0;
+ context->mvg_length = 0;
+ context->mvg_width = 0;
+
+ /* Pattern support */
+ context->pattern_id = NULL;
+ context->pattern_offset = 0;
+
+ context->pattern_bounds.x = 0;
+ context->pattern_bounds.y = 0;
+ context->pattern_bounds.width = 0;
+ context->pattern_bounds.height = 0;
+
+ /* Graphic context */
+ context->index = 0;
+ context->graphic_context=MagickAllocateMemory(DrawInfo **,sizeof(DrawInfo *));
+ if(context->graphic_context == (DrawInfo **) NULL)
+ {
+ ThrowException3(&context->image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ return (DrawContext) NULL;
+ }
+ CurrentContext=CloneDrawInfo((ImageInfo*)NULL,draw_info);
+ if(CurrentContext == (DrawInfo*) NULL)
+ {
+ ThrowException3(&context->image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ return (DrawContext) NULL;
+ }
+
+ context->filter_off = False;
+
+ /* Pretty-printing depth */
+ context->indent_depth = 0;
+
+ /* Path operation support */
+ context->path_operation = PathDefaultOperation;
+ context->path_mode = DefaultPathMode;
+
+ /* Structure unique signature */
+ context->signature = MagickSignature;
+
+ return context;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w A r c %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawArc() draws an arc falling within a specified bounding rectangle on the
+% image.
+%
+% The format of the DrawArc method is:
+%
+% void DrawArc(DrawContext context,
+% const double sx, const double sy,
+% const double ex, const double ey,
+% const double sd, const double ed)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o sx: starting x ordinate of bounding rectangle
+%
+% o sy: starting y ordinate of bounding rectangle
+%
+% o ex: ending x ordinate of bounding rectangle
+%
+% o ey: ending y ordinate of bounding rectangle
+%
+% o sd: starting degrees of rotation
+%
+% o ed: ending degrees of rotation
+%
+*/
+MagickExport void DrawArc(DrawContext context,
+ const double sx, const double sy,
+ const double ex, const double ey,
+ const double sd, const double ed)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "arc %g,%g %g,%g %g,%g\n",
+ sx, sy, ex, ey, sd, ed);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w B e z i e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawBezier() draws a bezier curve through a set of points on the image.
+%
+% The format of the DrawBezier method is:
+%
+% void DrawBezier(DrawContext context, const unsigned long num_coords,
+% const PointInfo *coordinates)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o num_coords: number of coordinates
+%
+% o coordinates: coordinates
+%
+*/
+MagickExport void DrawBezier(DrawContext context, const unsigned long num_coords,
+ const PointInfo *coordinates)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(coordinates != (const PointInfo *) NULL);
+
+ MvgAppendPointsCommand(context,"bezier",num_coords,coordinates);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C i r c l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawCircle() draws a circle on the image.
+%
+% The format of the DrawCircle method is:
+%
+% void DrawCircle(DrawContext context, const double ox,
+% const double oy, const double px, const double py)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o ox: origin x ordinate
+%
+% o oy: origin y ordinate
+%
+% o px: perimeter x ordinate
+%
+% o py: perimeter y ordinate
+%
+*/
+MagickExport void DrawCircle(DrawContext context, const double ox,
+ const double oy, const double px, const double py)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "circle %g,%g %g,%g\n", ox, oy, px, py);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetClipPath() obtains the current clipping path ID. The value returned
+% must be deallocated by the user when it is no longer needed.
+%
+% The format of the DrawGetClipPath method is:
+%
+% char *DrawGetClipPath(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport char *DrawGetClipPath(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if (CurrentContext->clip_path != (char *) NULL)
+ return (char *)AllocateString(CurrentContext->clip_path);
+ else
+ return (char *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetClipPath() associates a named clipping path with the image. Only
+% the areas drawn on by the clipping path will be modified as long as it
+% remains in effect.
+%
+% The format of the DrawSetClipPath method is:
+%
+% void DrawSetClipPath(DrawContext context, const char *clip_path)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o clip_path: name of clipping path to associate with image
+%
+*/
+MagickExport void DrawSetClipPath(DrawContext context, const char *clip_path)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(clip_path != (const char *) NULL);
+
+ if( CurrentContext->clip_path == NULL || context->filter_off ||
+ LocaleCompare(CurrentContext->clip_path,clip_path) != 0)
+ {
+ (void) CloneString(&CurrentContext->clip_path,clip_path);
+ if(CurrentContext->clip_path == (char*)NULL)
+ ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage);
+
+#if DRAW_BINARY_IMPLEMENTATION
+ (void) DrawClipPath(context->image,CurrentContext,CurrentContext->clip_path);
+#endif
+
+ (void) MvgPrintf(context, "clip-path url(#%s)\n", clip_path);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t C l i p R u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetClipRule() returns the current polygon fill rule to be used by the
+% clipping path.
+%
+% The format of the DrawGetClipRule method is:
+%
+% FillRule DrawGetClipRule(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport FillRule DrawGetClipRule(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->fill_rule;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t C l i p R u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
+%
+% The format of the DrawSetClipRule method is:
+%
+% void DrawSetClipRule(DrawContext context,
+% const FillRule fill_rule)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
+%
+*/
+MagickExport void DrawSetClipRule(DrawContext context,
+ const FillRule fill_rule)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->fill_rule != fill_rule))
+ {
+ CurrentContext->fill_rule = fill_rule;
+
+ switch (fill_rule)
+ {
+ case EvenOddRule:
+ p = "evenodd";
+ break;
+ case NonZeroRule:
+ p = "nonzero";
+ break;
+ default:
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "clip-rule %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t C l i p U n i t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetClipUnits() returns the interpretation of clip path units.
+%
+% The format of the DrawGetClipUnits method is:
+%
+% ClipPathUnits DrawGetClipUnits(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport ClipPathUnits DrawGetClipUnits(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->clip_units;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t C l i p U n i t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetClipUnits() sets the interpretation of clip path units.
+%
+% The format of the DrawSetClipUnits method is:
+%
+% void DrawSetClipUnits(DrawContext context,
+% const ClipPathUnits clip_units)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o clip_units: units to use (UserSpace, UserSpaceOnUse, or ObjectBoundingBox)
+%
+*/
+MagickExport void DrawSetClipUnits(DrawContext context,
+ const ClipPathUnits clip_units)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->clip_units != clip_units))
+ {
+ CurrentContext->clip_units = clip_units;
+
+ if ( clip_units == ObjectBoundingBox )
+ {
+ AffineMatrix
+ affine;
+
+ IdentityAffine(&affine);
+
+ affine.sx=CurrentContext->bounds.x2;
+ affine.sy=CurrentContext->bounds.y2;
+ affine.tx=CurrentContext->bounds.x1;
+ affine.ty=CurrentContext->bounds.y1;
+
+ AdjustAffine( context, &affine );
+ }
+
+ switch (clip_units)
+ {
+ case UserSpace:
+ p = "userSpace";
+ break;
+ case UserSpaceOnUse:
+ p = "userSpaceOnUse";
+ break;
+ case ObjectBoundingBox:
+ p = "objectBoundingBox";
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "clip-units %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawColor() draws color on image using the current fill color, starting at
+% specified position, and using specified paint method. The available paint
+% methods are:
+%
+% PointMethod: Recolors the target pixel
+% ReplaceMethod: Recolor any pixel that matches the target pixel.
+% FloodfillMethod: Recolors target pixels and matching neighbors.
+% FillToBorderMethod: Recolor target pixels and neighbors not matching border color.
+% ResetMethod: Recolor all pixels.
+%
+% The format of the DrawColor method is:
+%
+% void DrawColor(DrawContext context,
+% const double x, const double y,
+% const PaintMethod paintMethod)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: x ordinate
+%
+% o y: y ordinate
+%
+% o paintMethod: paint method
+%
+*/
+MagickExport void DrawColor(DrawContext context,
+ const double x, const double y,
+ const PaintMethod paintMethod)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ switch (paintMethod)
+ {
+ case PointMethod:
+ p = "point";
+ break;
+ case ReplaceMethod:
+ p = "replace";
+ break;
+ case FloodfillMethod:
+ p = "floodfill";
+ break;
+ case FillToBorderMethod:
+ p = "filltoborder";
+ break;
+ case ResetMethod:
+ p = "reset";
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "color %g,%g %s\n", x, y, p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C o m m e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawComment() adds a comment to a vector output stream.
+%
+% The format of the DrawComment method is:
+%
+% void DrawComment(DrawContext context,const char* comment)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o comment: comment text
+%
+*/
+MagickExport void DrawComment(DrawContext context,const char* comment)
+{
+ /* FIXME: should handle multi-line comments by inserting # before
+ new lines */
+ (void) MvgPrintf(context, "#%s\n", comment);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w D e s t r o y C o n t e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawDestroyContext() frees all resources associated with the drawing
+% context. Once the drawing context has been freed, it should not be used
+% any further unless it re-allocated.
+%
+% The format of the DrawDestroyContext method is:
+%
+% void DrawDestroyContext(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context to destroy
+%
+*/
+MagickExport void DrawDestroyContext(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ /* Path operation support */
+ context->path_operation = PathDefaultOperation;
+ context->path_mode = DefaultPathMode;
+
+ /* Pretty-printing depth */
+ context->indent_depth = 0;
+
+ /* Graphic context */
+ for ( ; context->index != 0; context->index--)
+ {
+ DestroyDrawInfo(CurrentContext);
+ CurrentContext = (DrawInfo*) NULL;
+ }
+ DestroyDrawInfo(CurrentContext);
+ CurrentContext = (DrawInfo*) NULL;
+ MagickFreeMemory(context->graphic_context);
+
+ /* Pattern support */
+ MagickFreeMemory(context->pattern_id);
+ context->pattern_offset = 0;
+
+ context->pattern_bounds.x = 0;
+ context->pattern_bounds.y = 0;
+ context->pattern_bounds.width = 0;
+ context->pattern_bounds.height = 0;
+
+ /* MVG output string and housekeeping */
+ MagickFreeMemory(context->mvg);
+ context->mvg_alloc = 0;
+ context->mvg_length = 0;
+
+ /* Support structures */
+ context->image = (Image*)NULL;
+
+ /* Context itself */
+ context->signature = 0;
+ MagickFreeMemory(context);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w E l l i p s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawEllipse() draws an ellipse on the image.
+%
+% The format of the DrawEllipse method is:
+%
+% void DrawEllipse(DrawContext context,
+% const double ox, const double oy,
+% const double rx, const double ry,
+% const double start, const double end)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o ox: origin x ordinate
+%
+% o oy: origin y ordinate
+%
+% o rx: radius in x
+%
+% o ry: radius in y
+%
+% o start: starting rotation in degrees
+%
+% o end: ending rotation in degrees
+%
+*/
+MagickExport void DrawEllipse(DrawContext context,
+ const double ox, const double oy,
+ const double rx, const double ry,
+ const double start, const double end)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "ellipse %g,%g %g,%g %g,%g\n",
+ ox, oy, rx, ry, start, end);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F i l l C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFillColor() returns the fill color used for drawing filled objects.
+%
+% The format of the DrawGetFillColor method is:
+%
+% PixelPacket DrawGetFillColor(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport PixelPacket DrawGetFillColor(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->fill;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillColor() sets the fill color to be used for drawing filled objects.
+%
+% The format of the DrawSetFillColor method is:
+%
+% void DrawSetFillColor(DrawContext context,
+% const PixelPacket * fill_color)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o fill_color: fill color
+%
+*/
+MagickExport void DrawSetFillColor(DrawContext context,
+ const PixelPacket *fill_color)
+{
+ PixelPacket
+ *current_fill,
+ new_fill;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(fill_color != (const PixelPacket *) NULL);
+
+ new_fill = *fill_color;
+
+ /* Inherit base opacity */
+ if(new_fill.opacity == OpaqueOpacity)
+ new_fill.opacity = CurrentContext->opacity;
+
+ current_fill = &CurrentContext->fill;
+ if( context->filter_off || !(PixelPacketMatch(current_fill,&new_fill)) )
+ {
+ CurrentContext->fill = new_fill;
+
+ (void) MvgPrintf(context, "fill '");
+ MvgAppendColor(context, fill_color);
+ (void) MvgPrintf(context, "'\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l C o l o r S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillColorString() sets the fill color to be used for drawing filled
+% objects.
+%
+% The format of the DrawSetFillColorString method is:
+%
+% void DrawSetFillColorString(DrawContext context, const char* fill_color)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o fill_color: fill color
+%
+*/
+MagickExport void DrawSetFillColorString(DrawContext context,
+ const char* fill_color)
+{
+ PixelPacket
+ pixel_packet;
+
+ if(QueryColorDatabase(fill_color,&pixel_packet,&context->image->exception))
+ DrawSetFillColor(context,&pixel_packet);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l P a t t e r n U R L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
+% objects. Only local URLs ("#identifier") are supported at this time. These
+% local URLs are normally created by defining a named fill pattern with
+% DrawPushPattern/DrawPopPattern.
+%
+% The format of the DrawSetFillPatternURL method is:
+%
+% void DrawSetFillPatternURL(DrawContext context, const char* fill_url)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o fill_url: URL to use to obtain fill pattern.
+%
+*/
+MagickExport void DrawSetFillPatternURL(DrawContext context, const char* fill_url)
+{
+ char
+ pattern[MaxTextExtent];
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(fill_url != NULL);
+
+ if(fill_url[0] != '#')
+ ThrowDrawException(DrawWarning,NotARelativeURL, fill_url);
+
+ FormatString(pattern,"[%.1024s]",fill_url+1);
+
+ if (GetImageAttribute(context->image,pattern) == (ImageAttribute *) NULL)
+ {
+ ThrowDrawException(DrawWarning,URLNotFound, fill_url)
+ }
+ else
+ {
+ char
+ pattern_spec[MaxTextExtent];
+
+ FormatString(pattern_spec,"url(%.1024s)",fill_url);
+#if DRAW_BINARY_IMPLEMENTATION
+ DrawPatternPath(context->image,CurrentContext,pattern_spec,&CurrentContext->fill_pattern);
+#endif
+ /* Inherit base opacity */
+ if (CurrentContext->fill.opacity != TransparentOpacity)
+ CurrentContext->fill.opacity=CurrentContext->opacity;
+
+ (void) MvgPrintf(context, "fill %s\n",pattern_spec);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F i l l O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFillOpacity() returns the opacity used when drawing using the fill
+% color or fill texture. Fully opaque is 1.0.
+%
+% The format of the DrawGetFillOpacity method is:
+%
+% double DrawGetFillOpacity(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport double DrawGetFillOpacity(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return (((double)(MaxRGB-CurrentContext->fill.opacity))/MaxRGB);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillOpacity() sets the opacity to use when drawing using the fill
+% color or fill texture. Fully opaque is 1.0.
+%
+% The format of the DrawSetFillOpacity method is:
+%
+% void DrawSetFillOpacity(DrawContext context, const double fill_opacity)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o fill_opacity: fill opacity
+%
+*/
+MagickExport void DrawSetFillOpacity(DrawContext context,
+ const double fill_opacity)
+{
+ Quantum
+ quantum_opacity;
+
+ double
+ validated_opacity;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ validated_opacity=(fill_opacity < 0.0 ? 0.0 : (fill_opacity > 1.0 ? 1.0 : fill_opacity));
+ quantum_opacity = (Quantum) (((double) MaxRGB*(1.0-validated_opacity))+0.5);
+
+ if (context->filter_off || (CurrentContext->fill.opacity != quantum_opacity))
+ {
+ CurrentContext->fill.opacity = quantum_opacity;
+ (void) (void) MvgPrintf(context, "fill-opacity %g\n", validated_opacity);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F i l l R u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFillRule() returns the fill rule used while drawing polygons.
+%
+% The format of the DrawGetFillRule method is:
+%
+% FillRule DrawGetFillRule(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport FillRule DrawGetFillRule(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->fill_rule;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l R u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillRule() sets the fill rule to use while drawing polygons.
+%
+% The format of the DrawSetFillRule method is:
+%
+% void DrawSetFillRule(DrawContext context, const FillRule fill_rule)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
+%
+*/
+MagickExport void DrawSetFillRule(DrawContext context,
+ const FillRule fill_rule)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->fill_rule != fill_rule))
+ {
+ CurrentContext->fill_rule = fill_rule;
+
+ switch (fill_rule)
+ {
+ case EvenOddRule:
+ p = "evenodd";
+ break;
+ case NonZeroRule:
+ p = "nonzero";
+ break;
+ default:
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "fill-rule %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFont() returns a null-terminaged string specifying the font used
+% when annotating with text. The value returned must be freed by the user
+% when no longer needed.
+%
+% The format of the DrawGetFont method is:
+%
+% char *DrawGetFont(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport char *DrawGetFont(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if (CurrentContext->font != (char *) NULL)
+ return AllocateString(CurrentContext->font);
+ else
+ return (char *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFont() sets the fully-sepecified font to use when annotating with
+% text.
+%
+% The format of the DrawSetFont method is:
+%
+% void DrawSetFont(DrawContext context, const char *font_name)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o font_name: font name
+%
+*/
+MagickExport void DrawSetFont(DrawContext context, const char *font_name)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(font_name != (const char *) NULL);
+
+ if(context->filter_off || (CurrentContext->font == NULL) ||
+ LocaleCompare(CurrentContext->font,font_name) != 0)
+ {
+ (void) CloneString(&CurrentContext->font,font_name);
+ if(CurrentContext->font == (char*)NULL)
+ ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage);
+ (void) MvgPrintf(context, "font '%s'\n", font_name);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t F a m i l y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontFamily() returns the font family to use when annotating with text.
+% The value returned must be freed by the user when it is no longer needed.
+%
+% The format of the DrawGetFontFamily method is:
+%
+% char *DrawGetFontFamily(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport char *DrawGetFontFamily(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if (CurrentContext->family != NULL)
+ return AllocateString(CurrentContext->family);
+ else
+ return (char *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t F a m i l y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontFamily() sets the font family to use when annotating with text.
+%
+% The format of the DrawSetFontFamily method is:
+%
+% void DrawSetFontFamily(DrawContext context, const char *font_family)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o font_family: font family
+%
+*/
+MagickExport void DrawSetFontFamily(DrawContext context,
+ const char *font_family)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(font_family != (const char *) NULL);
+
+ if(context->filter_off || (CurrentContext->family == NULL) ||
+ LocaleCompare(CurrentContext->family,font_family) != 0)
+ {
+ (void) CloneString(&CurrentContext->family,font_family);
+ if(CurrentContext->family == (char*)NULL)
+ ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage);
+ (void) MvgPrintf(context, "font-family '%s'\n", font_family);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontSize() returns the font pointsize used when annotating with text.
+%
+% The format of the DrawGetFontSize method is:
+%
+% double DrawGetFontSize(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport double DrawGetFontSize(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->pointsize;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontSize() sets the font pointsize to use when annotating with text.
+%
+% The format of the DrawSetFontSize method is:
+%
+% void DrawSetFontSize(DrawContext context, const double pointsize)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o pointsize: text pointsize
+%
+*/
+MagickExport void DrawSetFontSize(DrawContext context,
+ const double pointsize)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off ||
+ (AbsoluteValue(CurrentContext->pointsize-pointsize) > MagickEpsilon))
+ {
+ CurrentContext->pointsize=pointsize;
+
+ (void) MvgPrintf(context, "font-size %g\n", pointsize);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t S t r e t c h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontStretch() returns the font stretch used when annotating with text.
+%
+% The format of the DrawGetFontStretch method is:
+%
+% StretchType DrawGetFontStretch(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport StretchType DrawGetFontStretch(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->stretch;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t S t r e t c h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontStretch() sets the font stretch to use when annotating with text.
+% The AnyStretch enumeration acts as a wild-card "don't care" option.
+%
+% The format of the DrawSetFontStretch method is:
+%
+% void DrawSetFontStretch(DrawContext context,
+% const StretchType font_stretch)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
+% CondensedStretch, SemiCondensedStretch,
+% SemiExpandedStretch, ExpandedStretch,
+% ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
+%
+*/
+MagickExport void DrawSetFontStretch(DrawContext context,
+ const StretchType font_stretch)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->stretch != font_stretch))
+ {
+ CurrentContext->stretch=font_stretch;
+
+ switch (font_stretch)
+ {
+ case NormalStretch:
+ p = "normal";
+ break;
+ case UltraCondensedStretch:
+ p = "ultra-condensed";
+ break;
+ case ExtraCondensedStretch:
+ p = "extra-condensed";
+ break;
+ case CondensedStretch:
+ p = "condensed";
+ break;
+ case SemiCondensedStretch:
+ p = "semi-condensed";
+ break;
+ case SemiExpandedStretch:
+ p = "semi-expanded";
+ break;
+ case ExpandedStretch:
+ p = "expanded";
+ break;
+ case ExtraExpandedStretch:
+ p = "extra-expanded";
+ break;
+ case UltraExpandedStretch:
+ p = "ultra-expanded";
+ break;
+ case AnyStretch:
+ p = "all";
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "font-stretch '%s'\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t S t y l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontStyle() returns the font style used when annotating with text.
+%
+% The format of the DrawGetFontStyle method is:
+%
+% StyleType DrawGetFontStyle(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport StyleType DrawGetFontStyle(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->style;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t S t y l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontStyle() sets the font style to use when annotating with text.
+% The AnyStyle enumeration acts as a wild-card "don't care" option.
+%
+% The format of the DrawSetFontStyle method is:
+%
+% void DrawSetFontStyle(DrawContext context, const StyleType style)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
+%
+*/
+MagickExport void DrawSetFontStyle(DrawContext context,
+ const StyleType style)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->style != style))
+ {
+ CurrentContext->style=style;
+
+ switch (style)
+ {
+ case NormalStyle:
+ p = "normal";
+ break;
+ case ItalicStyle:
+ p = "italic";
+ break;
+ case ObliqueStyle:
+ p = "oblique";
+ break;
+ case AnyStyle:
+ p = "all";
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "font-style '%s'\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t W e i g h t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontWeight() returns the font weight used when annotating with text.
+%
+% The format of the DrawGetFontWeight method is:
+%
+% unsigned long DrawGetFontWeight(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport unsigned long DrawGetFontWeight(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->weight;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t W e i g h t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontWeight() sets the font weight to use when annotating with text.
+%
+% The format of the DrawSetFontWeight method is:
+%
+% void DrawSetFontWeight(DrawContext context,
+% const unsigned long font_weight)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o font_weight: font weight (valid range 100-900)
+%
+*/
+MagickExport void DrawSetFontWeight(DrawContext context,
+ const unsigned long font_weight)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->weight != font_weight))
+ {
+ CurrentContext->weight=font_weight;
+ (void) MvgPrintf(context, "font-weight %lu\n", font_weight);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t G r a v i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetGravity() returns the text placement gravity used when annotating
+% with text.
+%
+% The format of the DrawGetGravity method is:
+%
+% GravityType DrawGetGravity(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport GravityType DrawGetGravity(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->gravity;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t G r a v i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetGravity() sets the text placement gravity to use when annotating
+% with text.
+%
+% The format of the DrawSetGravity method is:
+%
+% void DrawSetGravity(DrawContext context, const GravityType gravity)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o gravity: positioning gravity (NorthWestGravity, NorthGravity,
+% NorthEastGravity, WestGravity, CenterGravity,
+% EastGravity, SouthWestGravity, SouthGravity,
+% SouthEastGravity)
+%
+*/
+MagickExport void DrawSetGravity(DrawContext context,
+ const GravityType gravity)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->gravity != gravity))
+ {
+ CurrentContext->gravity=gravity;
+
+ switch (gravity)
+ {
+ case NorthWestGravity:
+ p = "NorthWest";
+ break;
+ case NorthGravity:
+ p = "North";
+ break;
+ case NorthEastGravity:
+ p = "NorthEast";
+ break;
+ case WestGravity:
+ p = "West";
+ break;
+ case CenterGravity:
+ p = "Center";
+ break;
+ case EastGravity:
+ p = "East";
+ break;
+ case SouthWestGravity:
+ p = "SouthWest";
+ break;
+ case SouthGravity:
+ p = "South";
+ break;
+ case SouthEastGravity:
+ p = "SouthEast";
+ break;
+ case StaticGravity:
+ case ForgetGravity:
+ {
+ }
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "gravity %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C o m p o s i t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawComposite() composites an image onto the current image, using the
+% specified composition operator, specified position, and at the specified
+% size.
+%
+% The format of the DrawComposite method is:
+%
+% void DrawComposite(DrawContext context,
+% const CompositeOperator composite_operator,
+% const double x, const double y,
+% const double width, const double height,
+% const Image * image )
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o composite_operator: composition operator
+%
+% o x: x ordinate of top left corner
+%
+% o y: y ordinate of top left corner
+%
+% o width: Width to resize image to prior to compositing. Specify zero to
+% use existing width.
+%
+% o height: Height to resize image to prior to compositing. Specify zero
+% to use existing height.
+%
+% o image: Image to composite
+%
+*/
+MagickExport void DrawComposite(DrawContext context,
+ const CompositeOperator composite_operator,
+ const double x, const double y,
+ const double width, const double height,
+ const Image * image )
+
+{
+ ImageInfo
+ *image_info;
+
+ Image
+ *clone_image;
+
+ char
+ *media_type = NULL,
+ *base64 = NULL;
+
+ const char
+ *mode = NULL;
+
+ unsigned char
+ *blob = (unsigned char*)NULL;
+
+ size_t
+ blob_length = 2048,
+ encoded_length = 0;
+
+ MonitorHandler
+ handler;
+
+ assert(context != (DrawContext)NULL);
+ assert(image != (Image *) NULL);
+ assert(width != 0);
+ assert(height != 0);
+ assert(*image->magick != '\0');
+
+/* LogMagickEvent(CoderEvent,GetMagickModule(),"DrawComposite columns=%ld rows=%ld magick=%s ", */
+/* image->columns, image->rows, image->magick ); */
+
+ clone_image = CloneImage(image,0,0,True,&context->image->exception);
+ if(!clone_image)
+ return;
+
+ image_info = CloneImageInfo((ImageInfo*)NULL);
+ if(!image_info)
+ ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage);
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ blob = (unsigned char*)ImageToBlob( image_info, clone_image, &blob_length,
+ &context->image->exception );
+ (void) SetMonitorHandler(handler);
+ DestroyImageInfo(image_info);
+ DestroyImageList(clone_image);
+ if(!blob)
+ return;
+
+ base64 = Base64Encode(blob,blob_length,&encoded_length);
+ MagickFreeMemory(blob);
+ if(!base64)
+ {
+ char
+ buffer[MaxTextExtent];
+
+ FormatString(buffer,"%" MAGICK_SIZE_T_F "d bytes", (4L*blob_length/3L+4L));
+ ThrowDrawException(ResourceLimitWarning,MemoryAllocationFailed,buffer)
+ }
+
+ mode = CompositeOperatorToString(composite_operator);
+ media_type = MagickToMime( image->magick );
+
+ if( media_type != NULL )
+ {
+ char
+ *str;
+
+ int
+ remaining;
+
+ (void) MvgPrintf(context, "image %s %g,%g %g,%g 'data:%s;base64,\n",
+ mode, x, y, width, height, media_type);
+
+ remaining = (int)encoded_length;
+ str = base64;
+ while( remaining > 0 )
+ {
+ (void) MvgPrintf(context,"%.76s", str);
+ remaining -= 76;
+ str += 76;
+ if(remaining > 0)
+ (void) MvgPrintf(context,"\n");
+ }
+
+ (void) MvgPrintf(context,"'\n");
+ }
+
+ MagickFreeMemory(base64);
+ MagickFreeMemory(media_type);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w L i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawLine() draws a line on the image using the current stroke color,
+% stroke opacity, and stroke width.
+%
+% The format of the DrawLine method is:
+%
+% void DrawLine(DrawContext context,
+% const double sx, const double sy,
+% const double ex, const double ey)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o sx: starting x ordinate
+%
+% o sy: starting y ordinate
+%
+% o ex: ending x ordinate
+%
+% o ey: ending y ordinate
+%
+*/
+MagickExport void DrawLine(DrawContext context,
+ const double sx, const double sy,
+ const double ex, const double ey)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "line %g,%g %g,%g\n", sx, sy, ex, ey);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w M a t t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawMatte() paints on the image's opacity channel in order to set effected
+% pixels to transparent. The available paint methods are:
+%
+% PointMethod: Select the target pixel
+% ReplaceMethod: Select any pixel that matches the target pixel.
+% FloodfillMethod: Select the target pixel and matching neighbors.
+% FillToBorderMethod: Select the target pixel and neighbors not matching
+% border color.
+% ResetMethod: Select all pixels.
+%
+% The format of the DrawMatte method is:
+%
+% void DrawMatte(DrawContext context,
+% const double x, const double y,
+% const PaintMethod paint_method)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: x ordinate
+%
+% o y: y ordinate
+%
+% o paint_method:
+%
+*/
+MagickExport void DrawMatte(DrawContext context,
+ const double x, const double y,
+ const PaintMethod paint_method)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ switch (paint_method)
+ {
+ case PointMethod:
+ p = "point";
+ break;
+ case ReplaceMethod:
+ p = "replace";
+ break;
+ case FloodfillMethod:
+ p = "floodfill";
+ break;
+ case FillToBorderMethod:
+ p = "filltoborder";
+ break;
+ case ResetMethod:
+ p = "reset";
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "matte %g,%g %s\n", x, y, p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C l o s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathClose() adds a path element to the current path which closes the
+% current subpath by drawing a straight line from the current point to the
+% current subpath's most recent starting point (usually, the most recent
+% moveto point).
+%
+% The format of the DrawPathClose method is:
+%
+% void DrawPathClose(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPathClose(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgAutoWrapPrintf(context, "%s", context->path_mode == AbsolutePathMode ? "Z" : "z");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToAbsolute() draws a cubic Bzier curve from the current
+% point to (x,y) using (x1,y1) as the control point at the beginning of
+% the curve and (x2,y2) as the control point at the end of the curve using
+% absolute coordinates. At the end of the command, the new current point
+% becomes the final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToAbsolute method is:
+%
+% void DrawPathCurveToAbsolute(DrawContext context,
+% const double x1, const double y1,
+% const double x2, const double y2,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x1: x ordinate of control point for curve beginning
+%
+% o y1: y ordinate of control point for curve beginning
+%
+% o x2: x ordinate of control point for curve ending
+%
+% o y2: y ordinate of control point for curve ending
+%
+% o x: x ordinate of the end of the curve
+%
+% o y: y ordinate of the end of the curve
+%
+*/
+static void DrawPathCurveTo(DrawContext context,
+ const PathMode mode,
+ const double x1, const double y1,
+ const double x2, const double y2,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathCurveToOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathCurveToOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g,%g %g,%g %g,%g",
+ mode == AbsolutePathMode ? 'C' : 'c',
+ x1, y1, x2, y2, x, y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g,%g %g,%g %g,%g",
+ x1, y1, x2, y2, x, y);
+}
+MagickExport void DrawPathCurveToAbsolute(DrawContext context,
+ const double x1, const double y1,
+ const double x2, const double y2,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathCurveTo(context, AbsolutePathMode, x1, y1, x2, y2, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToRelative() draws a cubic Bzier curve from the current
+% point to (x,y) using (x1,y1) as the control point at the beginning of
+% the curve and (x2,y2) as the control point at the end of the curve using
+% relative coordinates. At the end of the command, the new current point
+% becomes the final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToRelative method is:
+%
+% void DrawPathCurveToRelative(DrawContext context,
+% const double x1, const double y1,
+% const double x2, const double y2,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x1: x ordinate of control point for curve beginning
+%
+% o y1: y ordinate of control point for curve beginning
+%
+% o x2: x ordinate of control point for curve ending
+%
+% o y2: y ordinate of control point for curve ending
+%
+% o x: x ordinate of the end of the curve
+%
+% o y: y ordinate of the end of the curve
+%
+*/
+MagickExport void DrawPathCurveToRelative(DrawContext context,
+ const double x1, const double y1,
+ const double x2, const double y2,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathCurveTo(context, RelativePathMode, x1, y1, x2, y2, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bzier curve
+% from the current point to (x,y) using (x1,y1) as the control point using
+% absolute coordinates. At the end of the command, the new current point
+% becomes the final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
+%
+% void DrawPathCurveToQuadraticBezierAbsolute(DrawContext context,
+% const double x1,
+% const double y1,
+% const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x1: x ordinate of the control point
+%
+% o y1: y ordinate of the control point
+%
+% o x: x ordinate of final point
+%
+% o y: y ordinate of final point
+%
+*/
+static void DrawPathCurveToQuadraticBezier(DrawContext context,
+ const PathMode mode,
+ const double x1, double y1,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathCurveToQuadraticBezierOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathCurveToQuadraticBezierOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g,%g %g,%g",
+ mode == AbsolutePathMode ? 'Q' : 'q', x1, y1, x, y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g,%g %g,%g", x1, y1, x, y);
+}
+MagickExport void DrawPathCurveToQuadraticBezierAbsolute(DrawContext context,
+ const double x1,
+ const double y1,
+ const double x,
+ const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathCurveToQuadraticBezier(context, AbsolutePathMode, x1, y1, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bzier curve
+% from the current point to (x,y) using (x1,y1) as the control point using
+% relative coordinates. At the end of the command, the new current point
+% becomes the final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToQuadraticBezierRelative method is:
+%
+% void DrawPathCurveToQuadraticBezierRelative(DrawContext context,
+% const double x1,
+% const double y1,
+% const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x1: x ordinate of the control point
+%
+% o y1: y ordinate of the control point
+%
+% o x: x ordinate of final point
+%
+% o y: y ordinate of final point
+%
+*/
+MagickExport void DrawPathCurveToQuadraticBezierRelative(DrawContext context,
+ const double x1,
+ const double y1,
+ const double x,
+ const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathCurveToQuadraticBezier(context, RelativePathMode, x1, y1, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
+% Bzier curve (using absolute coordinates) from the current point to
+% (x,y). The control point is assumed to be the reflection of the
+% control point on the previous command relative to the current
+% point. (If there is no previous command or if the previous command was
+% not a DrawPathCurveToQuadraticBezierAbsolute,
+% DrawPathCurveToQuadraticBezierRelative,
+% DrawPathCurveToQuadraticBezierSmoothAbsolut or
+% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
+% is coincident with the current point.). At the end of the command, the
+% new current point becomes the final (x,y) coordinate pair used in the
+% polybezier.
+%
+% The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
+%
+% void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawContext
+% context,
+% const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: x ordinate of final point
+%
+% o y: y ordinate of final point
+%
+*/
+static void DrawPathCurveToQuadraticBezierSmooth(DrawContext context,
+ const PathMode mode,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathCurveToQuadraticBezierSmoothOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathCurveToQuadraticBezierSmoothOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g,%g",
+ mode == AbsolutePathMode ? 'T' : 't', x, y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g,%g", x, y);
+}
+MagickExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawContext
+ context,
+ const double x,
+ const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathCurveToQuadraticBezierSmooth(context, AbsolutePathMode, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
+% Bzier curve (using relative coordinates) from the current point to
+% (x,y). The control point is assumed to be the reflection of the
+% control point on the previous command relative to the current
+% point. (If there is no previous command or if the previous command was
+% not a DrawPathCurveToQuadraticBezierAbsolute,
+% DrawPathCurveToQuadraticBezierRelative,
+% DrawPathCurveToQuadraticBezierSmoothAbsolut or
+% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
+% is coincident with the current point.). At the end of the command, the
+% new current point becomes the final (x,y) coordinate pair used in the
+% polybezier.
+%
+% The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
+%
+% void DrawPathCurveToQuadraticBezierSmoothRelative(DrawContext
+% context,
+% const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: x ordinate of final point
+%
+% o y: y ordinate of final point
+%
+%
+*/
+MagickExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawContext
+ context,
+ const double x,
+ const double y)
+{
+ DrawPathCurveToQuadraticBezierSmooth(context, RelativePathMode, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o S m o o t h A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToSmoothAbsolute() draws a cubic Bzier curve from the
+% current point to (x,y) using absolute coordinates. The first control
+% point is assumed to be the reflection of the second control point on
+% the previous command relative to the current point. (If there is no
+% previous command or if the previous command was not an
+% DrawPathCurveToAbsolute, DrawPathCurveToRelative,
+% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
+% the first control point is coincident with the current point.) (x2,y2)
+% is the second control point (i.e., the control point at the end of the
+% curve). At the end of the command, the new current point becomes the
+% final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToSmoothAbsolute method is:
+%
+% void DrawPathCurveToSmoothAbsolute(DrawContext context,
+% const double x2, const double y2,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x2: x ordinate of second control point
+%
+% o y2: y ordinate of second control point
+%
+% o x: x ordinate of termination point
+%
+% o y: y ordinate of termination point
+%
+%
+*/
+static void DrawPathCurveToSmooth(DrawContext context, const PathMode mode,
+ const double x2, const double y2,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathCurveToSmoothOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathCurveToSmoothOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g,%g %g,%g",
+ mode == AbsolutePathMode ? 'S' : 's', x2, y2, x, y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g,%g %g,%g", x2, y2, x, y);
+}
+MagickExport void DrawPathCurveToSmoothAbsolute(DrawContext context,
+ const double x2, const double y2,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathCurveToSmooth(context, AbsolutePathMode, x2, y2, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o S m o o t h R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToSmoothRelative() draws a cubic Bzier curve from the
+% current point to (x,y) using relative coordinates. The first control
+% point is assumed to be the reflection of the second control point on
+% the previous command relative to the current point. (If there is no
+% previous command or if the previous command was not an
+% DrawPathCurveToAbsolute, DrawPathCurveToRelative,
+% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
+% the first control point is coincident with the current point.) (x2,y2)
+% is the second control point (i.e., the control point at the end of the
+% curve). At the end of the command, the new current point becomes the
+% final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToSmoothRelative method is:
+%
+% void DrawPathCurveToSmoothRelative(DrawContext context,
+% const double x2, const double y2,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x2: x ordinate of second control point
+%
+% o y2: y ordinate of second control point
+%
+% o x: x ordinate of termination point
+%
+% o y: y ordinate of termination point
+%
+%
+*/
+MagickExport void DrawPathCurveToSmoothRelative(DrawContext context,
+ const double x2, const double y2,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathCurveToSmooth(context, RelativePathMode, x2, y2, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h E l l i p t i c A r c A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathEllipticArcAbsolute() draws an elliptical arc from the current
+% point to (x, y) using absolute coordinates. The size and orientation
+% of the ellipse are defined by two radii (rx, ry) and an
+% xAxisRotation, which indicates how the ellipse as a whole is rotated
+% relative to the current coordinate system. The center (cx, cy) of the
+% ellipse is calculated automatically to satisfy the constraints imposed
+% by the other parameters. largeArcFlag and sweepFlag contribute to the
+% automatic calculations and help determine how the arc is drawn. If
+% largeArcFlag is true then draw the larger of the available arcs. If
+% sweepFlag is true, then draw the arc matching a clock-wise rotation.
+%
+% The format of the DrawPathEllipticArcAbsolute method is:
+%
+% void DrawPathEllipticArcAbsolute(DrawContext context,
+% const double rx, const double ry,
+% const double x_axis_rotation,
+% unsigned int large_arc_flag,
+% unsigned int sweep_flag,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o rx: x radius
+%
+% o ry: y radius
+%
+% o x_axis_rotation: indicates how the ellipse as a whole is rotated
+% relative to the current coordinate system
+%
+% o large_arc_flag: If non-zero (true) then draw the larger of the
+% available arcs
+%
+% o sweep_flag: If non-zero (true) then draw the arc matching a
+% clock-wise rotation
+%
+%
+*/
+static void DrawPathEllipticArc(DrawContext context, const PathMode mode,
+ const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag,
+ unsigned int sweep_flag,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathEllipticArcOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathEllipticArcOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g,%g %g %u %u %g,%g",
+ mode == AbsolutePathMode ? 'A' : 'a', rx, ry, x_axis_rotation,
+ large_arc_flag, sweep_flag, x, y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g,%g %g %u %u %g,%g", rx, ry,
+ x_axis_rotation, large_arc_flag, sweep_flag, x, y);
+}
+MagickExport void DrawPathEllipticArcAbsolute(DrawContext context,
+ const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag,
+ unsigned int sweep_flag,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathEllipticArc(context, AbsolutePathMode, rx, ry, x_axis_rotation,
+ large_arc_flag, sweep_flag, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h E l l i p t i c A r c R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathEllipticArcRelative() draws an elliptical arc from the current
+% point to (x, y) using relative coordinates. The size and orientation
+% of the ellipse are defined by two radii (rx, ry) and an
+% xAxisRotation, which indicates how the ellipse as a whole is rotated
+% relative to the current coordinate system. The center (cx, cy) of the
+% ellipse is calculated automatically to satisfy the constraints imposed
+% by the other parameters. largeArcFlag and sweepFlag contribute to the
+% automatic calculations and help determine how the arc is drawn. If
+% largeArcFlag is true then draw the larger of the available arcs. If
+% sweepFlag is true, then draw the arc matching a clock-wise rotation.
+%
+% The format of the DrawPathEllipticArcRelative method is:
+%
+% void DrawPathEllipticArcRelative(DrawContext context,
+% const double rx, const double ry,
+% const double x_axis_rotation,
+% unsigned int large_arc_flag,
+% unsigned int sweep_flag,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o rx: x radius
+%
+% o ry: y radius
+%
+% o x_axis_rotation: indicates how the ellipse as a whole is rotated
+% relative to the current coordinate system
+%
+% o large_arc_flag: If non-zero (true) then draw the larger of the
+% available arcs
+%
+% o sweep_flag: If non-zero (true) then draw the arc matching a
+% clock-wise rotation
+%
+*/
+MagickExport void DrawPathEllipticArcRelative(DrawContext context,
+ const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag,
+ unsigned int sweep_flag,
+ const double x, const double y)
+{
+ DrawPathEllipticArc(context, RelativePathMode, rx, ry, x_axis_rotation,
+ large_arc_flag, sweep_flag, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h F i n i s h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathFinish() terminates the current path.
+%
+% The format of the DrawPathFinish method is:
+%
+% void DrawPathFinish(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPathFinish(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "'\n");
+ context->path_operation = PathDefaultOperation;
+ context->path_mode = DefaultPathMode;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToAbsolute() draws a line path from the current point to the
+% given coordinate using absolute coordinates. The coordinate then becomes
+% the new current point.
+%
+% The format of the DrawPathLineToAbsolute method is:
+%
+% void DrawPathLineToAbsolute(DrawContext context,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: target x ordinate
+%
+% o y: target y ordinate
+%
+*/
+static void DrawPathLineTo(DrawContext context,
+ const PathMode mode,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathLineToOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathLineToOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g,%g",
+ mode == AbsolutePathMode ? 'L' : 'l', x, y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g,%g", x, y);
+}
+MagickExport void DrawPathLineToAbsolute(DrawContext context,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathLineTo(context, AbsolutePathMode, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToRelative() draws a line path from the current point to the
+% given coordinate using relative coordinates. The coordinate then becomes
+% the new current point.
+%
+% The format of the DrawPathLineToRelative method is:
+%
+% void DrawPathLineToRelative(DrawContext context,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: target x ordinate
+%
+% o y: target y ordinate
+%
+*/
+MagickExport void DrawPathLineToRelative(DrawContext context,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathLineTo(context, RelativePathMode, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o H o r i z o n t a l A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
+% current point to the target point using absolute coordinates. The target
+% point then becomes the new current point.
+%
+% The format of the DrawPathLineToHorizontalAbsolute method is:
+%
+% void DrawPathLineToHorizontalAbsolute(DrawContext context,
+% const double x)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: target x ordinate
+%
+*/
+
+static void DrawPathLineToHorizontal(DrawContext context,
+ const PathMode mode, const double x)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathLineToHorizontalOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathLineToHorizontalOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g",
+ mode == AbsolutePathMode ? 'H' : 'h', x);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g", x);
+}
+MagickExport void DrawPathLineToHorizontalAbsolute(DrawContext context,
+ const double x)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathLineToHorizontal(context, AbsolutePathMode, x);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o H o r i z o n t a l R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToHorizontalRelative() draws a horizontal line path from the
+% current point to the target point using relative coordinates. The target
+% point then becomes the new current point.
+%
+% The format of the DrawPathLineToHorizontalRelative method is:
+%
+% void DrawPathLineToHorizontalRelative(DrawContext context, const double x)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: target x ordinate
+%
+*/
+MagickExport void DrawPathLineToHorizontalRelative(DrawContext context,
+ const double x)
+{
+ DrawPathLineToHorizontal(context, RelativePathMode, x);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o V e r t i c a l A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToVerticalAbsolute() draws a vertical line path from the
+% current point to the target point using absolute coordinates. The target
+% point then becomes the new current point.
+%
+% The format of the DrawPathLineToVerticalAbsolute method is:
+%
+% void DrawPathLineToVerticalAbsolute(DrawContext context,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o y: target y ordinate
+%
+*/
+static void DrawPathLineToVertical(DrawContext context, const PathMode mode,
+ const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathLineToVerticalOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathLineToVerticalOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g",
+ mode == AbsolutePathMode ? 'V' : 'v', y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g", y);
+}
+MagickExport void DrawPathLineToVerticalAbsolute(DrawContext context,
+ const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathLineToVertical(context, AbsolutePathMode, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o V e r t i c a l R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToVerticalRelative() draws a vertical line path from the
+% current point to the target point using relative coordinates. The target
+% point then becomes the new current point.
+%
+% The format of the DrawPathLineToVerticalRelative method is:
+%
+% void DrawPathLineToVerticalRelative(DrawContext context,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o y: target y ordinate
+%
+*/
+MagickExport void DrawPathLineToVerticalRelative(DrawContext context,
+ const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathLineToVertical(context, RelativePathMode, y);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h M o v e T o A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
+% using absolute coordinates. The current point then becomes the
+% specified coordinate.
+%
+% The format of the DrawPathMoveToAbsolute method is:
+%
+% void DrawPathMoveToAbsolute(DrawContext context, const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: target x ordinate
+%
+% o y: target y ordinate
+%
+*/
+ static void DrawPathMoveTo(DrawContext context, const PathMode mode,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if ((context->path_operation != PathMoveToOperation)
+ || (context->path_mode != mode))
+ {
+ context->path_operation = PathMoveToOperation;
+ context->path_mode = mode;
+ (void) MvgAutoWrapPrintf(context, "%c%g,%g",
+ mode == AbsolutePathMode ? 'M' : 'm', x, y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(context, " %g,%g", x, y);
+}
+
+MagickExport void DrawPathMoveToAbsolute(DrawContext context, const double x,
+ const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathMoveTo(context, AbsolutePathMode, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h M o v e T o R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathMoveToRelative() starts a new sub-path at the given coordinate
+% using relative coordinates. The current point then becomes the
+% specified coordinate.
+%
+% The format of the DrawPathMoveToRelative method is:
+%
+% void DrawPathMoveToRelative(DrawContext context,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: target x ordinate
+%
+% o y: target y ordinate
+%
+*/
+MagickExport void DrawPathMoveToRelative(DrawContext context,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ DrawPathMoveTo(context, RelativePathMode, x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h S t a r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathStart() declares the start of a path drawing list which is terminated
+% by a matching DrawPathFinish() command. All other DrawPath commands must
+% be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
+% is because path drawing commands are subordinate commands and they do not
+% function by themselves.
+%
+% The format of the DrawPathStart method is:
+%
+% void DrawPathStart(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPathStart(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "path '");
+ context->path_operation = PathDefaultOperation;
+ context->path_mode = DefaultPathMode;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P e e k G r a p h i c C o n t e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPeekGraphicContext() returns a copy of the the DrawInfo structure at
+% the head of the drawing context stack. The user is responsible for
+% deallocating the returned object using DestroyDrawInfo.
+%
+% The format of the DrawPeekGraphicContext method is:
+%
+% DrawInfo *DrawPeekGraphicContext(const DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport DrawInfo *DrawPeekGraphicContext(const DrawContext context)
+{
+ DrawInfo
+ *draw_info;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
+ (void) CloneString(&draw_info->primitive,context->mvg);
+ CurrentContext->primitive=context->mvg;
+ return(draw_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o i n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPoint() draws a point using the current stroke color and stroke
+% thickness at the specified coordinates.
+%
+% The format of the DrawPoint method is:
+%
+% void DrawPoint(DrawContext context, const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: target x coordinate
+%
+% o y: target y coordinate
+%
+*/
+MagickExport void DrawPoint(DrawContext context,
+ const double x, const double y)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "point %g,%g\n", x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o l y g o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPolygon() draws a polygon using the current stroke, stroke width, and
+% fill color or texture, using the specified array of coordinates.
+%
+% The format of the DrawPolygon method is:
+%
+% void DrawPolygon(DrawContext context,
+% const unsigned long num_coords,
+% const PointInfo * coordinates)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o num_coords: number of coordinates
+%
+% o coordinates: coordinate array
+%
+*/
+MagickExport void DrawPolygon(DrawContext context,
+ const unsigned long num_coords,
+ const PointInfo * coordinates)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ MvgAppendPointsCommand(context,"polygon",num_coords,coordinates);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o l y l i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPolyline() draws a polyline using the current stroke, stroke width, and
+% fill color or texture, using the specified array of coordinates.
+%
+% The format of the DrawPolyline method is:
+%
+% void DrawPolyline(DrawContext context,
+% const unsigned long num_coords,
+% const PointInfo * coordinates)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o num_coords: number of coordinates
+%
+% o coordinates: coordinate array
+%
+*/
+MagickExport void DrawPolyline(DrawContext context,
+ const unsigned long num_coords,
+ const PointInfo * coordinates)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ MvgAppendPointsCommand(context,"polyline",num_coords,coordinates);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o p C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPopClipPath() terminates a clip path definition.
+%
+% The format of the DrawPopClipPath method is:
+%
+% void DrawPopClipPath(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPopClipPath(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->indent_depth != 0)
+ context->indent_depth--;
+ (void) MvgPrintf(context, "pop clip-path\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o p D e f s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPopDefs() terminates a definition list
+%
+% The format of the DrawPopDefs method is:
+%
+% void DrawPopDefs(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPopDefs(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->indent_depth != 0)
+ context->indent_depth--;
+ (void) MvgPrintf(context, "pop defs\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o p G r a p h i c C o n t e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPopGraphicContext() destroys the current context returning to the
+% previously pushed context. Multiple contexts may exist. It is an error
+% to attempt to pop more contexts than have been pushed, and it is proper
+% form to pop all contexts which have been pushed.
+%
+% The format of the DrawPopGraphicContext method is:
+%
+% void DrawPopGraphicContext(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPopGraphicContext(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->index != 0)
+ {
+ /* Destroy clip path if not same in preceding context */
+#if DRAW_BINARY_IMPLEMENTATION
+ if (CurrentContext->clip_path != (char *) NULL)
+ if (LocaleCompare(CurrentContext->clip_path,
+ context->graphic_context[context->index-1]->clip_path) != 0)
+ (void) SetImageClipMask(context->image,(Image *) NULL);
+#endif
+
+ DestroyDrawInfo(CurrentContext);
+ CurrentContext=(DrawInfo*)NULL;
+ context->index--;
+
+ if(context->indent_depth != 0)
+ context->indent_depth--;
+ (void) MvgPrintf(context, "pop graphic-context\n");
+ }
+ else
+ {
+ ThrowDrawException(DrawError,UnbalancedGraphicContextPushPop,NULL)
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o p P a t t e r n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPopPattern() terminates a pattern definition.
+%
+% The format of the DrawPopPattern method is:
+%
+% void DrawPopPattern(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPopPattern(DrawContext context)
+{
+ char
+ geometry[MaxTextExtent],
+ key[MaxTextExtent];
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if( context->pattern_id == NULL )
+ ThrowDrawException(DrawWarning,NotCurrentlyPushingPatternDefinition,NULL);
+
+ FormatString(key,"[%.1024s]",context->pattern_id);
+
+ (void) SetImageAttribute(context->image,key,context->mvg+context->pattern_offset);
+ FormatString(geometry,"%lux%lu%+ld%+ld",
+ context->pattern_bounds.width,context->pattern_bounds.height,
+ context->pattern_bounds.x,context->pattern_bounds.y);
+ (void) SetImageAttribute(context->image,key,geometry);
+
+ MagickFreeMemory(context->pattern_id);
+ context->pattern_offset = 0;
+
+ context->pattern_bounds.x = 0;
+ context->pattern_bounds.y = 0;
+ context->pattern_bounds.width = 0;
+ context->pattern_bounds.height = 0;
+
+ context->filter_off = False;
+
+ if(context->indent_depth != 0)
+ context->indent_depth--;
+ (void) MvgPrintf(context, "pop pattern\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P u s h C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPushClipPath() starts a clip path definition which is comprized of
+% any number of drawing commands and terminated by a DrawPopClipPath()
+% command.
+%
+% The format of the DrawPushClipPath method is:
+%
+% void DrawPushClipPath(DrawContext context, const char *clip_path_id)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o clip_path_id: string identifier to associate with the clip path for
+% later use.
+%
+*/
+MagickExport void DrawPushClipPath(DrawContext context,
+ const char *clip_path_id)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(clip_path_id != (const char *) NULL);
+
+ (void) MvgPrintf(context, "push clip-path %s\n", clip_path_id);
+ context->indent_depth++;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P u s h D e f s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
+% command create named elements (e.g. clip-paths, textures, etc.) which
+% may safely be processed earlier for the sake of efficiency.
+%
+% The format of the DrawPushDefs method is:
+%
+% void DrawPushDefs(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPushDefs(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "push defs\n");
+ context->indent_depth++;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P u s h G r a p h i c C o n t e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPushGraphicContext() clones the current drawing context to create a
+% new drawing context. The original drawing context(s) may be returned to
+% by invoking DrawPopGraphicContext(). The contexts are stored on a context
+% stack. For every Pop there must have already been an equivalent Push.
+%
+% The format of the DrawPushGraphicContext method is:
+%
+% void DrawPushGraphicContext(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport void DrawPushGraphicContext(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ context->index++;
+ MagickReallocMemory(DrawInfo **,context->graphic_context,
+ (context->index+1)*sizeof(DrawInfo *));
+ if (context->graphic_context == (DrawInfo **) NULL)
+ {
+ context->index--;
+ ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage)
+ }
+ CurrentContext=
+ CloneDrawInfo((ImageInfo *) NULL,context->graphic_context[context->index-1]);
+ (void) MvgPrintf(context, "push graphic-context\n");
+ context->indent_depth++;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P u s h P a t t e r n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPushPattern() indicates that subsequent commands up to a
+% DrawPopPattern() command comprise the definition of a named pattern.
+% The pattern space is assigned top left corner coordinates, a width
+% and height, and becomes its own drawing space. Anything which can
+% be drawn may be used in a pattern definition.
+% Named patterns may be used as stroke or brush definitions.
+%
+% The format of the DrawPushPattern method is:
+%
+% void DrawPushPattern(DrawContext context,
+% const char *pattern_id,
+% const double x, const double y,
+% const double width, const double height)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o pattern_id: pattern identification for later reference
+%
+% o x: x ordinate of top left corner
+%
+% o y: y ordinate of top left corner
+%
+% o width: width of pattern space
+%
+% o height: height of pattern space
+%
+*/
+MagickExport void DrawPushPattern(DrawContext context,
+ const char *pattern_id,
+ const double x, const double y,
+ const double width, const double height)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(pattern_id != (const char *) NULL);
+
+ if( context->pattern_id != NULL )
+ ThrowDrawException(DrawError,AlreadyPushingPatternDefinition,
+ context->pattern_id);
+
+ context->filter_off = True;
+
+ (void) MvgPrintf(context, "push pattern %s %g,%g %g,%g\n",
+ pattern_id, x, y, width, height);
+ context->indent_depth++;
+
+ /* Record current pattern ID, bounds, and start position in MVG */
+ context->pattern_id = AllocateString(pattern_id);
+ context->pattern_bounds.x = (long) ceil(x-0.5);
+ context->pattern_bounds.y = (long) ceil(y-0.5);
+ context->pattern_bounds.width = (unsigned long) floor(width+0.5);
+ context->pattern_bounds.height = (unsigned long) floor(height+0.5);
+ context->pattern_offset = context->mvg_length;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w R e c t a n g l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawRectangle() draws a rectangle given two coordinates and using
+% the current stroke, stroke width, and fill settings.
+%
+% The format of the DrawRectangle method is:
+%
+% void DrawRectangle(DrawContext context,
+% const double x1, const double y1,
+% const double x2, const double y2)
+%
+% A description of each parameter follows:
+%
+% o x1: x ordinate of first coordinate
+%
+% o y1: y ordinate of first coordinate
+%
+% o x2: x ordinate of second coordinate
+%
+% o y2: y ordinate of second coordinate
+%
+*/
+MagickExport void DrawRectangle(DrawContext context,
+ const double x1, const double y1,
+ const double x2, const double y2)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ (void) MvgPrintf(context, "rectangle %g,%g %g,%g\n", x1, y1, x2, y2);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w R e n d e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawRender() renders all preceding drawing commands onto the image.
+%
+% The format of the DrawRender method is:
+%
+% int DrawRender(const DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport int DrawRender(const DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ CurrentContext->primitive = context->mvg;
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),"MVG:\n'%s'\n",context->mvg);
+ (void) DrawImage(context->image, CurrentContext);
+ CurrentContext->primitive = (char *) NULL;
+
+ return True;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w R o t a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawRotate() applies the specified rotation to the current coordinate
+% space.
+%
+% The format of the DrawRotate method is:
+%
+% void DrawRotate(DrawContext context, const double degrees)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o degrees: degrees of rotation
+%
+*/
+MagickExport void DrawRotate(DrawContext context, const double degrees)
+{
+ AffineMatrix
+ affine;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ IdentityAffine(&affine);
+ affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
+ AdjustAffine( context, &affine );
+
+ (void) MvgPrintf(context, "rotate %g\n", degrees);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w R o u n d R e c t a n g l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawRoundRectangle() draws a rounted rectangle given two coordinates,
+% x & y corner radiuses and using the current stroke, stroke width,
+% and fill settings.
+%
+% The format of the DrawRoundRectangle method is:
+%
+% void DrawRoundRectangle(DrawContext context,
+% double x1, double y1,
+% double x2, double y2,
+% double rx, double ry)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x1: x ordinate of first coordinate
+%
+% o y1: y ordinate of first coordinate
+%
+% o x2: x ordinate of second coordinate
+%
+% o y2: y ordinate of second coordinate
+%
+% o rx: radius of corner in horizontal direction
+%
+% o ry: radius of corner in vertical direction
+%
+*/
+MagickExport void DrawRoundRectangle(DrawContext context,
+ double x1, double y1,
+ double x2, double y2,
+ double rx, double ry)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "roundrectangle %g,%g %g,%g %g,%g\n",
+ x1, y1, x2, y2, rx, ry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S c a l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawScale() adjusts the scaling factor to apply in the horizontal and
+% vertical directions to the current coordinate space.
+%
+% The format of the DrawScale method is:
+%
+% void DrawScale(DrawContext context, const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: horizontal scale factor
+%
+% o y: vertical scale factor
+%
+*/
+MagickExport void DrawScale(DrawContext context,
+ const double x, const double y)
+{
+ AffineMatrix
+ affine;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ IdentityAffine(&affine);
+ affine.sx=x;
+ affine.sy=y;
+ AdjustAffine( context, &affine );
+
+ (void) MvgPrintf(context, "scale %g,%g\n", x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S k e w X %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSkewX() skews the current coordinate system in the horizontal
+% direction.
+%
+% The format of the DrawSkewX method is:
+%
+% void DrawSkewX(DrawContext context, const double degrees)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o degrees: number of degrees to skew the coordinates
+%
+*/
+MagickExport void DrawSkewX(DrawContext context, const double degrees)
+{
+ AffineMatrix
+ affine;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ IdentityAffine(&affine);
+ affine.ry=tan(DegreesToRadians(fmod(degrees,360.0)));
+ AdjustAffine(context,&affine);
+
+ (void) MvgPrintf(context, "skewX %g\n", degrees);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S k e w Y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSkewY() skews the current coordinate system in the vertical
+% direction.
+%
+% The format of the DrawSkewY method is:
+%
+% void DrawSkewY(DrawContext context, const double degrees)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o degrees: number of degrees to skew the coordinates
+%
+*/
+MagickExport void DrawSkewY(DrawContext context, const double degrees)
+{
+ AffineMatrix
+ affine;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ IdentityAffine(&affine);
+ affine.rx=tan(DegreesToRadians(fmod(degrees,360.0)));
+ DrawAffine(context,&affine);
+
+ (void) MvgPrintf(context, "skewY %g\n", degrees);
+}
+
+#if 0
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t o p C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStopColor() sets the stop color and offset for gradients
+%
+% The format of the DrawSetStopColor method is:
+%
+% void DrawSetStopColor(DrawContext context,
+% const PixelPacket * stop_color,
+% const double offset)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o stop_color:
+%
+% o offset:
+%
+*/
+/* This is gradient stuff so it shouldn't be supported yet */
+MagickExport void DrawSetStopColor(DrawContext context,
+ const PixelPacket * stop_color,
+ const double offset)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(stop_color != (const PixelPacket *) NULL);
+
+
+ (void) MvgPrintf(context, "stop-color ");
+ MvgAppendColor(context, stop_color);
+ (void) MvgPrintf(context, "\n");
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeColor() returns the color used for stroking object outlines.
+%
+% The format of the DrawGetStrokeColor method is:
+%
+% PixelPacket DrawGetStrokeColor(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport PixelPacket DrawGetStrokeColor(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->stroke;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeColor() sets the color used for stroking object outlines.
+%
+% The format of the DrawSetStrokeColor method is:
+%
+% void DrawSetStrokeColor(DrawContext context,
+% const PixelPacket * stroke_color)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o stroke_color: stroke color
+%
+*/
+MagickExport void DrawSetStrokeColor(DrawContext context,
+ const PixelPacket * stroke_color)
+{
+ PixelPacket
+ *current_stroke,
+ new_stroke;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(stroke_color != (const PixelPacket *) NULL);
+
+ new_stroke = *stroke_color;
+
+ /* Inherit base opacity */
+ if(new_stroke.opacity == OpaqueOpacity)
+ new_stroke.opacity = CurrentContext->opacity;
+
+ current_stroke = &CurrentContext->stroke;
+ if( context->filter_off || !(PixelPacketMatch(current_stroke,&new_stroke)) )
+ {
+ CurrentContext->stroke = new_stroke;
+
+ (void) MvgPrintf(context, "stroke '");
+ MvgAppendColor(context, stroke_color);
+ (void) MvgPrintf(context, "'\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e C o l o r S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeColorString() sets the color used for stroking object outlines.
+%
+% The format of the DrawSetStrokeColorString method is:
+%
+% void DrawSetStrokeColorString(DrawContext context,
+% const char* stroke_color)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o stroke_color: stroke color
+%
+*/
+MagickExport void DrawSetStrokeColorString(DrawContext context,
+ const char* stroke_color)
+{
+ PixelPacket
+ pixel_packet;
+
+ if(QueryColorDatabase(stroke_color,&pixel_packet,&context->image->exception))
+ DrawSetStrokeColor(context,&pixel_packet);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e P a t t e r n U R L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
+%
+% The format of the DrawSetStrokePatternURL method is:
+%
+% void DrawSetStrokePatternURL(DrawContext context, const char* stroke_url)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
+%
+*/
+MagickExport void DrawSetStrokePatternURL(DrawContext context,
+ const char* stroke_url)
+{
+ char
+ pattern[MaxTextExtent];
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(stroke_url != NULL);
+
+ if(stroke_url[0] != '#')
+ ThrowDrawException(DrawWarning, NotARelativeURL, stroke_url);
+
+ FormatString(pattern,"[%.1024s]",stroke_url+1);
+
+ if (GetImageAttribute(context->image,pattern) == (ImageAttribute *) NULL)
+ {
+ ThrowDrawException(DrawWarning, URLNotFound, stroke_url)
+ }
+ else
+ {
+ char
+ pattern_spec[MaxTextExtent];
+
+ FormatString(pattern_spec,"url(%.1024s)",stroke_url);
+#if DRAW_BINARY_IMPLEMENTATION
+ DrawPatternPath(context->image,CurrentContext,pattern_spec,&CurrentContext->stroke_pattern);
+#endif
+ /* Inherit base opacity */
+ if (CurrentContext->stroke.opacity == OpaqueOpacity)
+ CurrentContext->stroke.opacity=CurrentContext->opacity;
+
+ (void) MvgPrintf(context, "stroke %s\n",pattern_spec);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e A n t i a l i a s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeAntialias() returns the current stroke antialias setting.
+% Stroked outlines are antialiased by default. When antialiasing is disabled
+% stroked pixels are thresholded to determine if the stroke color or
+% underlying canvas color should be used.
+%
+% The format of the DrawGetStrokeAntialias method is:
+%
+% unsigned int DrawGetStrokeAntialias(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport unsigned int DrawGetStrokeAntialias(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->stroke_antialias;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e A n t i a l i a s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
+% Stroked outlines are antialiased by default. When antialiasing is disabled
+% stroked pixels are thresholded to determine if the stroke color or
+% underlying canvas color should be used.
+%
+% The format of the DrawSetStrokeAntialias method is:
+%
+% void DrawSetStrokeAntialias(DrawContext context,
+% const unsigned int stroke_antialias)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o stroke_antialias: set to false (zero) to disable antialiasing
+%
+*/
+MagickExport void DrawSetStrokeAntialias(DrawContext context,
+ const unsigned int stroke_antialias)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->stroke_antialias != stroke_antialias))
+ {
+ CurrentContext->stroke_antialias = stroke_antialias;
+
+ (void) MvgPrintf(context, "stroke-antialias %i\n", stroke_antialias ? 1 : 0);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e D a s h A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeDashArray() returns an array representing the pattern of
+% dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
+% array must be freed once it is no longer required by the user.
+%
+% The format of the DrawGetStrokeDashArray method is:
+%
+% double *DrawGetStrokeDashArray(DrawContext context,unsigned long *num_elems)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o num_elems: address to place number of elements in dash array
+%
+% */
+MagickExport double *DrawGetStrokeDashArray(DrawContext context,
+ unsigned long *num_elems)
+{
+ register const double
+ *p;
+
+ register double
+ *q;
+
+ double
+ *dasharray;
+
+ unsigned int
+ i,
+ n = 0;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(num_elems != (unsigned long *)NULL);
+
+ p = CurrentContext->dash_pattern;
+ if( p != (const double *) NULL )
+ while( *p++ != 0.0)
+ n++;
+
+ *num_elems = n;
+ dasharray = (double *)NULL;
+ if (n != 0)
+ {
+ dasharray = MagickAllocateArray(double *, n+1, sizeof(double));
+ p = CurrentContext->dash_pattern;
+ q = dasharray;
+ i = n;
+ while( i-- )
+ *q++ = *p++;
+ *q=0.0;
+ }
+ return dasharray;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e D a s h A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
+% stroke paths. The strokeDashArray represents an array of numbers that
+% specify the lengths of alternating dashes and gaps in pixels. If an odd
+% number of values is provided, then the list of values is repeated to yield
+% an even number of values. To remove an existing dash array, pass a zero
+% num_elems argument and null dasharray. A typical stroke dash array might
+% contain the members 5 3 2.
+%
+% The format of the DrawSetStrokeDashArray method is:
+%
+% void DrawSetStrokeDashArray(DrawContext context,
+% const unsigned long num_elems,
+% const double *dasharray)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o num_elems: number of elements in dash array
+%
+% o dasharray: dash array values
+%
+% */
+MagickExport void DrawSetStrokeDashArray(DrawContext context,
+ const unsigned long num_elems,
+ const double *dasharray)
+{
+ register const double
+ *p;
+
+ register double
+ *q;
+
+ unsigned long
+ i,
+ n_new = num_elems,
+ n_old = 0;
+
+ MagickBool
+ updated = MagickFalse;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if (dasharray == (const double *) NULL)
+ n_new = 0;
+ q = CurrentContext->dash_pattern;
+ if( q != (const double *) NULL )
+ while( *q++ != 0.0)
+ n_old++;
+
+ if( (n_old == 0) && (n_new == 0) )
+ {
+ updated = MagickFalse;
+ }
+ else if( n_old != n_new )
+ {
+ updated = MagickTrue;
+ }
+ else if((CurrentContext->dash_pattern != (double*)NULL)
+ && (dasharray != (double*)NULL))
+ {
+ p = dasharray;
+ q = CurrentContext->dash_pattern;
+ i = n_new;
+ while( i-- )
+ {
+ if(AbsoluteValue(*p - *q) > MagickEpsilon)
+ {
+ updated = MagickTrue;
+ break;
+ }
+ ++p;
+ ++q;
+ }
+ }
+
+ if( context->filter_off || updated )
+ {
+ if(CurrentContext->dash_pattern != (double*)NULL)
+ MagickFreeMemory(CurrentContext->dash_pattern);
+
+ if( n_new != 0 )
+ {
+ CurrentContext->dash_pattern = MagickAllocateArray(double *,
+ (n_new+1),
+ sizeof(double));
+ if(CurrentContext->dash_pattern)
+ {
+ for (i=0; i < n_new; i++)
+ CurrentContext->dash_pattern[i]=dasharray[i];
+ CurrentContext->dash_pattern[n_new]=0.0;
+ }
+ else
+ {
+ ThrowDrawException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage)
+ }
+ }
+
+ (void) MvgPrintf(context, "stroke-dasharray ");
+ if ( n_new == 0 )
+ (void) MvgPrintf(context, "none");
+ else
+ {
+ for (i=0; i < n_new; i++)
+ {
+ if (i != 0)
+ (void) MvgPrintf(context, ",");
+ (void) MvgPrintf(context, "%g", dasharray[i]);
+ }
+ }
+ (void) MvgPrintf(context, "\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e D a s h O f f s e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeDashOffset() returns the offset into the dash pattern to
+% start the dash.
+%
+% The format of the DrawGetStrokeDashOffset method is:
+%
+% double DrawGetStrokeDashOffset(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport double DrawGetStrokeDashOffset(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->dash_offset;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e D a s h O f f s e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
+% start the dash.
+%
+% The format of the DrawSetStrokeDashOffset method is:
+%
+% void DrawSetStrokeDashOffset(DrawContext context,
+% const double dash_offset)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o dash_offset: dash offset
+%
+*/
+MagickExport void DrawSetStrokeDashOffset(DrawContext context,
+ const double dash_offset)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off ||
+ (AbsoluteValue(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
+ {
+ CurrentContext->dash_offset = dash_offset;
+
+ (void) MvgPrintf(context, "stroke-dashoffset %g\n", dash_offset);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e L i n e C a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeLineCap() returns the shape to be used at the end of
+% open subpaths when they are stroked. Values of LineCap are
+% UndefinedCap, ButtCap, RoundCap, and SquareCap.
+%
+% The format of the DrawGetStrokeLineCap method is:
+%
+% LineCap DrawGetStrokeLineCap(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% */
+MagickExport LineCap DrawGetStrokeLineCap(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->linecap;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e L i n e C a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeLineCap() specifies the shape to be used at the end of
+% open subpaths when they are stroked. Values of LineCap are
+% UndefinedCap, ButtCap, RoundCap, and SquareCap.
+%
+% The format of the DrawSetStrokeLineCap method is:
+%
+% void DrawSetStrokeLineCap(DrawContext context,
+% const LineCap linecap)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o linecap: linecap style
+%
+% */
+MagickExport void DrawSetStrokeLineCap(DrawContext context,
+ const LineCap linecap)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->linecap != linecap))
+ {
+ const char
+ *p = NULL;
+
+ CurrentContext->linecap = linecap;
+
+ switch (linecap)
+ {
+ case ButtCap:
+ p = "butt";
+ break;
+ case RoundCap:
+ p = "round";
+ break;
+ case SquareCap:
+ p = "square";
+ break;
+ default:
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "stroke-linecap %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e L i n e J o i n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeLineJoin() returns the shape to be used at the
+% corners of paths (or other vector shapes) when they are
+% stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
+% and BevelJoin.
+%
+% The format of the DrawGetStrokeLineJoin method is:
+%
+% LineJoin DrawGetStrokeLineJoin(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% */
+MagickExport LineJoin DrawGetStrokeLineJoin(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->linejoin;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e L i n e J o i n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeLineJoin() specifies the shape to be used at the
+% corners of paths (or other vector shapes) when they are
+% stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
+% and BevelJoin.
+%
+% The format of the DrawSetStrokeLineJoin method is:
+%
+% void DrawSetStrokeLineJoin(DrawContext context, const LineJoin linejoin)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o linejoin: line join style
+%
+% */
+MagickExport void DrawSetStrokeLineJoin(DrawContext context,
+ const LineJoin linejoin)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(context->filter_off || (CurrentContext->linejoin != linejoin))
+ {
+ const char
+ *p = NULL;
+
+ CurrentContext->linejoin = linejoin;
+
+ switch (linejoin)
+ {
+ case MiterJoin:
+ p = "miter";
+ break;
+ case RoundJoin:
+ p = "round";
+ break;
+ case BevelJoin:
+ p = "bevel";
+ break;
+ default:
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "stroke-linejoin %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e M i t e r L i m i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeMiterLimit() returns the miter limit. When two line
+% segments meet at a sharp angle and miter joins have been specified for
+% 'lineJoin', it is possible for the miter to extend far beyond the
+% thickness of the line stroking the path. The miterLimit' imposes a
+% limit on the ratio of the miter length to the 'lineWidth'.
+%
+% The format of the DrawGetStrokeMiterLimit method is:
+%
+% unsigned long DrawGetStrokeMiterLimit(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% */
+MagickExport unsigned long DrawGetStrokeMiterLimit(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->miterlimit;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e M i t e r L i m i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeMiterLimit() specifies the miter limit. When two line
+% segments meet at a sharp angle and miter joins have been specified for
+% 'lineJoin', it is possible for the miter to extend far beyond the
+% thickness of the line stroking the path. The miterLimit' imposes a
+% limit on the ratio of the miter length to the 'lineWidth'.
+%
+% The format of the DrawSetStrokeMiterLimit method is:
+%
+% void DrawSetStrokeMiterLimit(DrawContext context,
+% const unsigned long miterlimit)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o miterlimit: miter limit
+%
+% */
+MagickExport void DrawSetStrokeMiterLimit(DrawContext context,
+ const unsigned long miterlimit)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if(CurrentContext->miterlimit != miterlimit)
+ {
+ CurrentContext->miterlimit = miterlimit;
+
+ (void) MvgPrintf(context, "stroke-miterlimit %lu\n", miterlimit);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
+%
+% The format of the DrawGetStrokeOpacity method is:
+%
+% double DrawGetStrokeOpacity(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+*/
+MagickExport double DrawGetStrokeOpacity(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return (((double)(MaxRGB-CurrentContext->stroke.opacity))/MaxRGB);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
+%
+% The format of the DrawSetStrokeOpacity method is:
+%
+% void DrawSetStrokeOpacity(DrawContext context,
+% const double stroke_opacity)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o stroke_opacity: stroke opacity. The value 1.0 is opaque.
+%
+*/
+MagickExport void DrawSetStrokeOpacity(DrawContext context,
+ const double stroke_opacity)
+{
+ Quantum
+ quantum_opacity;
+
+ double
+ validated_opacity;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ validated_opacity=(stroke_opacity < 0.0 ? 0.0 : (stroke_opacity > 1.0 ? 1.0 : stroke_opacity));
+ quantum_opacity = (Quantum) (((double) MaxRGB*(1.0-validated_opacity))+0.5);
+
+ if (context->filter_off || (CurrentContext->stroke.opacity != quantum_opacity))
+ {
+ CurrentContext->stroke.opacity = quantum_opacity;
+ (void) MvgPrintf(context, "stroke-opacity %g\n", validated_opacity);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e W i d t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeWidth() returns the width of the stroke used to draw object
+% outlines.
+%
+% The format of the DrawGetStrokeWidth method is:
+%
+% double DrawGetStrokeWidth(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport double DrawGetStrokeWidth(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->stroke_width;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e W i d t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeWidth() sets the width of the stroke used to draw object
+% outlines.
+%
+% The format of the DrawSetStrokeWidth method is:
+%
+% void DrawSetStrokeWidth(DrawContext context, const double stroke_width)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o stroke_width: stroke width
+%
+*/
+MagickExport void DrawSetStrokeWidth(DrawContext context,
+ const double stroke_width)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if (context->filter_off ||
+ (AbsoluteValue(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
+ {
+ CurrentContext->stroke_width = stroke_width;
+
+ (void) MvgPrintf(context, "stroke-width %g\n", stroke_width);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t T e x t A n t i a l i a s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetTextAntialias() returns the current text antialias setting, which
+% determines whether text is antialiased. Text is antialiased by default.
+%
+% The format of the DrawGetTextAntialias method is:
+%
+% unsigned int DrawGetTextAntialias(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport unsigned int DrawGetTextAntialias(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->text_antialias;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t A n t i a l i a s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextAntialias() controls whether text is antialiased. Text is
+% antialiased by default.
+%
+% The format of the DrawSetTextAntialias method is:
+%
+% void DrawSetTextAntialias(DrawContext context,
+% const unsigned int text_antialias)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o text_antialias: antialias boolean. Set to false (0) to disable
+% antialiasing.
+%
+*/
+MagickExport void DrawSetTextAntialias(DrawContext context,
+ const unsigned int text_antialias)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if (context->filter_off || (CurrentContext->text_antialias != text_antialias))
+ {
+ CurrentContext->text_antialias = text_antialias;
+
+ (void) MvgPrintf(context, "text-antialias %i\n", text_antialias ? 1 : 0);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t T e x t D e c o r a t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetTextDecoration() returns the decoration applied when annotating with
+% text.
+%
+% The format of the DrawGetTextDecoration method is:
+%
+% DecorationType DrawGetTextDecoration(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport DecorationType DrawGetTextDecoration(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->decorate;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t D e c o r a t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextDecoration() specifies a decoration to be applied when
+% annotating with text.
+%
+% The format of the DrawSetTextDecoration method is:
+%
+% void DrawSetTextDecoration(DrawContext context,
+% const DecorationType decoration)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
+% OverlineDecoration, or LineThroughDecoration
+%
+*/
+MagickExport void DrawSetTextDecoration(DrawContext context,
+ const DecorationType decoration)
+{
+ const char
+ *p = NULL;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if (context->filter_off || (CurrentContext->decorate != decoration))
+ {
+ CurrentContext->decorate = decoration;
+
+ switch (decoration)
+ {
+ case NoDecoration:
+ p = "none";
+ break;
+ case UnderlineDecoration:
+ p = "underline";
+ break;
+ case OverlineDecoration:
+ p = "overline";
+ break;
+ case LineThroughDecoration:
+ p = "line-through";
+ break;
+ }
+
+ if (p != NULL)
+ (void) MvgPrintf(context, "decorate %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t T e x t E n c o d i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetTextEncoding() returns a null-terminated string which specifies the
+% code set used for text annotations. The string must be freed by the user
+% once it is no longer required.
+%
+% The format of the DrawGetTextEncoding method is:
+%
+% char *DrawGetTextEncoding(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% */
+MagickExport char *DrawGetTextEncoding(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ if (CurrentContext->encoding != (char *)NULL)
+ return (char *) AllocateString(CurrentContext->encoding);
+ else
+ return (char *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t E n c o d i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextEncoding() specifies specifies the code set to use for
+% text annotations. The only character encoding which may be specified
+% at this time is "UTF-8" for representing Unicode as a sequence of
+% bytes. Specify an empty string to set text encoding to the system's
+% default. Successful text annotation using Unicode may require fonts
+% designed to support Unicode.
+%
+% The format of the DrawSetTextEncoding method is:
+%
+% void DrawSetTextEncoding(DrawContext context, const char* encoding)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o encoding: character string specifying text encoding
+%
+*/
+MagickExport void DrawSetTextEncoding(DrawContext context, const char* encoding)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(encoding != (char *) NULL);
+
+ if (context->filter_off || (CurrentContext->encoding == (char *) NULL) ||
+ (LocaleCompare(CurrentContext->encoding,encoding) != 0))
+ {
+ (void) CloneString(&CurrentContext->encoding,encoding);
+
+ (void) MvgPrintf(context, "encoding '%s'\n", encoding);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t T e x t U n d e r C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetTextUnderColor() returns the color of a background rectangle
+% to place under text annotations.
+%
+% The format of the DrawGetTextUnderColor method is:
+%
+% PixelPacket DrawGetTextUnderColor(DrawContext context)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+*/
+MagickExport PixelPacket DrawGetTextUnderColor(DrawContext context)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ return CurrentContext->undercolor;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t U n d e r C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextUnderColor() specifies the color of a background rectangle
+% to place under text annotations.
+%
+% The format of the DrawSetTextUnderColor method is:
+%
+% void DrawSetTextUnderColor(DrawContext context,
+% const PixelPacket *under_color)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o under_color: text under color
+%
+*/
+MagickExport void DrawSetTextUnderColor(DrawContext context,
+ const PixelPacket *under_color)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+ assert(under_color != (const PixelPacket *)NULL);
+
+ if (context->filter_off || !(PixelPacketMatch(&CurrentContext->undercolor, under_color)))
+ {
+ CurrentContext->undercolor = *under_color;
+ (void) MvgPrintf(context, "text-undercolor '");
+ MvgAppendColor(context, under_color);
+ (void) MvgPrintf(context, "'\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t U n d e r C o l o r S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextUnderColorString() specifies the color of a background rectangle
+% to place under text annotations.
+%
+% The format of the DrawSetTextUnderColorString method is:
+%
+% void DrawSetTextUnderColorString(DrawContext context,
+% const char* under_color)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o under_color: text under color
+%
+*/
+MagickExport void DrawSetTextUnderColorString(DrawContext context,
+ const char* under_color)
+{
+ PixelPacket
+ pixel_packet;
+
+ if(QueryColorDatabase(under_color,&pixel_packet,&context->image->exception))
+ DrawSetTextUnderColor(context,&pixel_packet);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w T r a n s l a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawTranslate() applies a translation to the current coordinate
+% system which moves the coordinate system origin to the specified
+% coordinate.
+%
+% The format of the DrawTranslate method is:
+%
+% void DrawTranslate(DrawContext context,
+% const double x, const double y)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x: new x ordinate for coordinate system origin
+%
+% o y: new y ordinate for coordinate system origin
+%
+*/
+MagickExport void DrawTranslate(DrawContext context,
+ const double x, const double y)
+{
+ AffineMatrix
+ affine;
+
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ IdentityAffine(&affine);
+ affine.tx=x;
+ affine.ty=y;
+ AdjustAffine( context, &affine );
+
+ (void) MvgPrintf(context, "translate %g,%g\n", x, y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t V i e w b o x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetViewbox() sets the overall canvas size to be recorded with the
+% drawing vector data. Usually this will be specified using the same
+% size as the canvas image. When the vector data is saved to SVG or MVG
+% formats, the viewbox is use to specify the size of the canvas image that
+% a viewer will render the vector data on.
+%
+% The format of the DrawSetViewbox method is:
+%
+% void DrawSetViewbox(DrawContext context,
+% unsigned long x1, unsigned long y1,
+% unsigned long x2, unsigned long y2)
+%
+% A description of each parameter follows:
+%
+% o context: drawing context
+%
+% o x1: left x ordinate
+%
+% o y1: top y ordinate
+%
+% o x2: right x ordinate
+%
+% o y2: bottom y ordinate
+%
+*/
+MagickExport void DrawSetViewbox(DrawContext context,
+ unsigned long x1, unsigned long y1,
+ unsigned long x2, unsigned long y2)
+{
+ assert(context != (DrawContext)NULL);
+ assert(context->signature == MagickSignature);
+
+ (void) MvgPrintf(context, "viewbox %lu %lu %lu %lu\n", x1, y1, x2, y2);
+}
diff --git a/magick/draw.h b/magick/draw.h
new file mode 100644
index 0000000..76bfdc6
--- /dev/null
+++ b/magick/draw.h
@@ -0,0 +1,262 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Drawing API.
+
+ Usage synopsis:
+
+ DrawContext context;
+ context = DrawAllocateContext((DrawInfo*)NULL, image);
+ [ any number of drawing commands ]
+ DrawSetStrokeColorString(context,"black");
+ DrawSetFillColorString(context,"#ff00ff");
+ DrawSetStrokeWidth(context,4);
+ DrawRectangle(context,72,72,144,144);
+ DrawRender(context);
+ DrawDestroyContext(context);
+
+*/
+#ifndef _MAGICK_DRAW_H
+#define _MAGICK_DRAW_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "magick/render.h"
+
+
+typedef struct _DrawContext *DrawContext;
+
+extern MagickExport ClipPathUnits
+ DrawGetClipUnits(DrawContext context);
+
+extern MagickExport DrawInfo
+ *DrawPeekGraphicContext(const DrawContext context);
+
+extern MagickExport DecorationType
+ DrawGetTextDecoration(DrawContext context);
+
+extern MagickExport DrawContext
+ DrawAllocateContext(const DrawInfo *draw_info, Image *image);
+
+extern MagickExport FillRule
+ DrawGetClipRule(DrawContext context),
+ DrawGetFillRule(DrawContext context);
+
+extern MagickExport GravityType
+ DrawGetGravity(DrawContext context);
+
+extern MagickExport LineCap
+ DrawGetStrokeLineCap(DrawContext context);
+
+extern MagickExport LineJoin
+ DrawGetStrokeLineJoin(DrawContext context);
+
+extern MagickExport PixelPacket
+ DrawGetFillColor(DrawContext context),
+ DrawGetStrokeColor(DrawContext context),
+ DrawGetTextUnderColor(DrawContext context);
+
+extern MagickExport StretchType
+ DrawGetFontStretch(DrawContext context);
+
+extern MagickExport StyleType
+ DrawGetFontStyle(DrawContext context);
+
+extern MagickExport char
+ *DrawGetClipPath(DrawContext context),
+ *DrawGetFont(DrawContext context),
+ *DrawGetFontFamily(DrawContext context),
+ *DrawGetTextEncoding(DrawContext context);
+
+extern MagickExport int
+ DrawRender(const DrawContext context);
+
+extern MagickExport unsigned int
+ DrawGetStrokeAntialias(DrawContext context),
+ DrawGetTextAntialias(DrawContext context);
+
+extern MagickExport unsigned long
+ DrawGetFontWeight(DrawContext context),
+ DrawGetStrokeMiterLimit(DrawContext context);
+
+extern MagickExport double
+ DrawGetFillOpacity(DrawContext context),
+ DrawGetFontSize(DrawContext context),
+ *DrawGetStrokeDashArray(DrawContext context, unsigned long *num_elems),
+ DrawGetStrokeDashOffset(DrawContext context),
+ DrawGetStrokeOpacity(DrawContext context),
+ DrawGetStrokeWidth(DrawContext context);
+
+extern MagickExport void
+ DrawAffine(DrawContext context, const AffineMatrix *affine),
+ DrawAnnotation(DrawContext context,
+ const double x, const double y,
+ const unsigned char *text),
+ DrawArc(DrawContext context,
+ const double sx, const double sy,
+ const double ex, const double ey,
+ const double sd, const double ed),
+ DrawBezier(DrawContext context,
+ const unsigned long num_coords, const PointInfo * coordinates),
+ DrawCircle(DrawContext context,
+ const double ox, const double oy,
+ const double px, const double py),
+ DrawColor(DrawContext context,
+ const double x, const double y,
+ const PaintMethod paintMethod),
+ DrawComment(DrawContext context,const char* comment),
+ DrawDestroyContext(DrawContext context),
+ DrawEllipse(DrawContext context,
+ const double ox, const double oy,
+ const double rx, const double ry,
+ const double start, const double end),
+ DrawComposite(DrawContext context,
+ const CompositeOperator composite_operator,
+ const double x, const double y,
+ const double width, const double height,
+ const Image * image ),
+ DrawLine(DrawContext context,
+ const double sx, const double sy,
+ const double ex, const double ey),
+ DrawMatte(DrawContext context,
+ const double x, const double y,
+ const PaintMethod paint_method),
+ DrawPathClose(DrawContext context),
+ DrawPathCurveToAbsolute(DrawContext context,
+ const double x1, const double y1,
+ const double x2, const double y2,
+ const double x, const double y),
+ DrawPathCurveToRelative(DrawContext context,
+ const double x1, const double y1,
+ const double x2, const double y2,
+ const double x, const double y),
+ DrawPathCurveToQuadraticBezierAbsolute(DrawContext context,
+ const double x1, const double y1,
+ const double x, const double y),
+ DrawPathCurveToQuadraticBezierRelative(DrawContext context,
+ const double x1, const double y1,
+ const double x, const double y),
+ DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawContext context,
+ const double x, const double y),
+ DrawPathCurveToQuadraticBezierSmoothRelative(DrawContext context,
+ const double x, const double y),
+ DrawPathCurveToSmoothAbsolute(DrawContext context,
+ const double x2, const double y2,
+ const double x, const double y),
+ DrawPathCurveToSmoothRelative(DrawContext context,
+ const double x2, const double y2,
+ const double x, const double y),
+ DrawPathEllipticArcAbsolute(DrawContext context,
+ const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag,
+ unsigned int sweep_flag,
+ const double x, const double y),
+ DrawPathEllipticArcRelative(DrawContext context,
+ const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag,
+ unsigned int sweep_flag,
+ const double x, const double y),
+ DrawPathFinish(DrawContext context),
+ DrawPathLineToAbsolute(DrawContext context,
+ const double x, const double y),
+ DrawPathLineToRelative(DrawContext context,
+ const double x, const double y),
+ DrawPathLineToHorizontalAbsolute(DrawContext context, const double x),
+ DrawPathLineToHorizontalRelative(DrawContext context, const double x),
+ DrawPathLineToVerticalAbsolute(DrawContext context, const double y),
+ DrawPathLineToVerticalRelative(DrawContext context, const double y),
+ DrawPathMoveToAbsolute(DrawContext context,
+ const double x, const double y),
+ DrawPathMoveToRelative(DrawContext context,
+ const double x, const double y),
+ DrawPathStart(DrawContext context),
+ DrawPoint(DrawContext context, const double x, const double y),
+ DrawPolygon(DrawContext context,
+ const unsigned long num_coords, const PointInfo * coordinates),
+ DrawPolyline(DrawContext context,
+ const unsigned long num_coords, const PointInfo * coordinates),
+ DrawPopClipPath(DrawContext context),
+ DrawPopDefs(DrawContext context),
+ DrawPopGraphicContext(DrawContext context),
+ DrawPopPattern(DrawContext context),
+ DrawPushClipPath(DrawContext context, const char *clip_path_id),
+ DrawPushDefs(DrawContext context),
+ DrawPushGraphicContext(DrawContext context),
+ DrawPushPattern(DrawContext context,
+ const char *pattern_id,
+ const double x, const double y,
+ const double width, const double height),
+ DrawRectangle(DrawContext context,
+ const double x1, const double y1,
+ const double x2, const double y2),
+ DrawRoundRectangle(DrawContext context,
+ double x1, double y1,
+ double x2, double y2,
+ double rx, double ry),
+ DrawScale(DrawContext context, const double x, const double y),
+ DrawSetClipPath(DrawContext context, const char *clip_path),
+ DrawSetClipRule(DrawContext context, const FillRule fill_rule),
+ DrawSetClipUnits(DrawContext context, const ClipPathUnits clip_units),
+ DrawSetFillColor(DrawContext context, const PixelPacket *fill_color),
+ DrawSetFillColorString(DrawContext context, const char *fill_color),
+ DrawSetFillOpacity(DrawContext context, const double fill_opacity),
+ DrawSetFillRule(DrawContext context, const FillRule fill_rule),
+ DrawSetFillPatternURL(DrawContext context, const char *fill_url),
+ DrawSetFont(DrawContext context, const char *font_name),
+ DrawSetFontFamily(DrawContext context, const char *font_family),
+ DrawSetFontSize(DrawContext context, const double font_pointsize),
+ DrawSetFontStretch(DrawContext context, const StretchType font_stretch),
+ DrawSetFontStyle(DrawContext context, const StyleType font_style),
+ DrawSetFontWeight(DrawContext context, const unsigned long font_weight),
+ DrawSetGravity(DrawContext context, const GravityType gravity),
+ DrawRotate(DrawContext context, const double degrees),
+ DrawSkewX(DrawContext context, const double degrees),
+ DrawSkewY(DrawContext context, const double degrees),
+ /*
+ DrawSetStopColor(DrawContext context, const PixelPacket * color,
+ const double offset),
+ */
+ DrawSetStrokeAntialias(DrawContext context, const unsigned int true_false),
+ DrawSetStrokeColor(DrawContext context, const PixelPacket *stroke_color),
+ DrawSetStrokeColorString(DrawContext context, const char *stroke_color),
+ DrawSetStrokeDashArray(DrawContext context, const unsigned long num_elems,
+ const double *dasharray),
+ DrawSetStrokeDashOffset(DrawContext context,const double dashoffset),
+ DrawSetStrokeLineCap(DrawContext context, const LineCap linecap),
+ DrawSetStrokeLineJoin(DrawContext context, const LineJoin linejoin),
+ DrawSetStrokeMiterLimit(DrawContext context,const unsigned long miterlimit),
+ DrawSetStrokeOpacity(DrawContext context, const double opacity),
+ DrawSetStrokePatternURL(DrawContext context, const char* stroke_url),
+ DrawSetStrokeWidth(DrawContext context, const double width),
+ DrawSetTextAntialias(DrawContext context, const unsigned int true_false),
+ DrawSetTextDecoration(DrawContext context, const DecorationType decoration),
+ DrawSetTextEncoding(DrawContext context, const char *encoding),
+ DrawSetTextUnderColor(DrawContext context, const PixelPacket *color),
+ DrawSetTextUnderColorString(DrawContext context, const char *under_color),
+ DrawSetViewbox(DrawContext context,
+ unsigned long x1, unsigned long y1,
+ unsigned long x2, unsigned long y2),
+ DrawTranslate(DrawContext context, const double x, const double y);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/effect.c b/magick/effect.c
new file mode 100644
index 0000000..382a38f
--- /dev/null
+++ b/magick/effect.c
@@ -0,0 +1,4692 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% EEEEE FFFFF FFFFF EEEEE CCCC TTTTT %
+% E F F E C T %
+% EEE FFF FFF EEE C T %
+% E F F E C T %
+% EEEEE F F EEEEE CCCC T %
+% %
+% %
+% GraphicsMagick Image Effects Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% October 1996 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/channel.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/enum_strings.h"
+#include "magick/gem.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/omp_data_view.h"
+#include "magick/operator.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/random-private.h"
+#include "magick/random.h"
+#include "magick/render.h"
+#include "magick/shear.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% A d a p t i v e T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AdaptiveThresholdImage() selects an individual threshold for each pixel
+% based on the range of intensity values in its local neighborhood. This
+% allows for thresholding of an image whose global intensity histogram
+% doesn't contain distinctive peaks.
+%
+% The format of the AdaptiveThresholdImage method is:
+%
+% Image *AdaptiveThresholdImage(Image *image,const unsigned long width,
+% const unsigned long height,const unsigned long unsigned long,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o width: The width of the local neighborhood.
+%
+% o height: The height of the local neighborhood.
+%
+% o offset: The mean offset.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define AdaptiveThresholdImageText "[%s] Adaptive threshold..."
+/* Macros for accessing dynamic preprocess buffer */
+#define PRE(X,Y) ((Y + height + 2) % (height + 2)) * (image->columns + (width << 1)) + X
+
+MagickExport Image *AdaptiveThresholdImage(const Image * image,
+ const unsigned long width,
+ const unsigned long height,
+ const double offset,
+ ExceptionInfo * exception)
+{
+ const PixelPacket * restrict
+ p = (const PixelPacket *) NULL;
+
+ Image
+ * restrict threshold_image;
+
+ LongPixelPacket
+ * restrict dyn_process;
+
+ const unsigned long
+ local_area = width * height;
+
+ unsigned long
+ int i;
+
+ /*
+ * allocates pre processing buffer,
+ *
+ * (window height + 2) * (image width + 2 * width), filled with zero
+ */
+ const unsigned long
+ dyn_process_size = (height + 2) * (image->columns + (width << 1));
+
+ unsigned long
+ row_count = 0UL;
+
+ unsigned long
+ x,
+ y;
+
+ const LongPixelPacket
+ long_zero = { 0UL, 0UL, 0UL, 0UL };
+
+ const long
+ long_offset = (long) (offset*MaxMap/MaxRGB + 0.5);
+
+ const MagickBool
+ is_monochrome = image->is_monochrome,
+ is_grayscale = image->is_grayscale;
+
+ MagickPassFail
+ status;
+
+ const MagickBool
+ matte = ((image->matte)
+ || (image->colorspace == CMYKColorspace));
+
+ unsigned long
+ overflow_mask = 0x1UL << (sizeof(dyn_process[0].red)*8-1);
+
+ MagickBool
+ overflow_eminent;
+
+ /*
+ Initialize thresholded image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ if ((image->columns < width) || (image->rows < height))
+ ThrowImageException3(OptionError, UnableToThresholdImage,
+ ImageSmallerThanRadius);
+
+ threshold_image = CloneImage(image, 0, 0, MagickTrue, exception);
+ if (threshold_image == (Image *) NULL)
+ return ((Image *) NULL);
+ if (is_monochrome)
+ return threshold_image;
+ (void) SetImageType(threshold_image, TrueColorType);
+ status = MagickPass;
+
+#if 0
+ fprintf(stderr,"overflow_mask=%lx\n",overflow_mask);
+ fprintf(stderr,"overflow pixels=%lu\n",(((~0UL) >> 1)/MaxMap));
+#endif
+ /*
+ Adaptive threshold image.
+ */
+ dyn_process = MagickAllocateArray(LongPixelPacket *,dyn_process_size,
+ sizeof(LongPixelPacket));
+ if (dyn_process == (LongPixelPacket *) NULL)
+ {
+ DestroyImage(threshold_image);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToThresholdImage);
+ }
+ (void) memset(dyn_process,0,dyn_process_size*sizeof(LongPixelPacket));
+
+ overflow_eminent = MagickFalse;
+
+ for (y = 0; y < (image->rows + height/2 + height + 1); y++)
+ {
+ PixelPacket
+ *restrict q = ((PixelPacket *) NULL);
+
+ /*
+ * for each window height + 2 rows, redefine reading area for
+ * preprocess and avoid sum overflow
+ */
+ if (PRE(0, y) == 0)
+ {
+ p = AcquireImagePixels(image, -(long) width, (long) y - (long) height,
+ image->columns + (width << 1), height + 2,
+ exception);
+
+ if (p == (const PixelPacket *) NULL)
+ {
+ status = MagickFail;
+ break; /* Breaks overall 'y' loop '*/
+ }
+
+ /*
+ * this is the code for sum overflow avoidance in
+ * preprocessing it's only used for really large images.
+ * and it can be highly optimized. I couldn't properly
+ * test it this code...
+ */
+ if (overflow_eminent)
+ {
+ LongPixelPacket
+ min_sum;
+
+ if (image->logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "LAT: overflow handling activated "
+ "(y=%lu)!",y);
+ min_sum.red = dyn_process[0].red;
+ min_sum.green = dyn_process[0].green;
+ min_sum.blue = dyn_process[0].blue;
+ min_sum.opacity = dyn_process[0].opacity;
+
+ for (i = 0; i < dyn_process_size; i++)
+ {
+ dyn_process[i].red -= min_sum.red;
+ dyn_process[i].green -= min_sum.green;
+ dyn_process[i].blue -= min_sum.blue;
+ dyn_process[i].opacity -= min_sum.opacity;
+ }
+ overflow_eminent = MagickFalse;
+ }
+ } /* if (PRE(0, y) == 0) */
+
+ /* load line for writing */
+ if (y > (height/2 + height))
+ {
+ q = GetImagePixelsEx(threshold_image, 0, y - height/2 - height - 1,
+ threshold_image->columns, 1, exception);
+
+ if (q == (PixelPacket *) NULL)
+ {
+ status = MagickFail;
+ break;
+ }
+ }
+
+ for (x = 2; x < (image->columns + (width << 1)); x++)
+ {
+ LongPixelPacket * restrict current_pre;
+
+ if (p == (const PixelPacket *) NULL)
+ {
+ status = MagickFail;
+ break; /* Breaks only immediate 'x' loop */
+ }
+
+ /* preprocess (x,y) */
+ current_pre = &dyn_process[PRE(x, y)];
+
+ /* red / gray */
+ current_pre->red =
+ ScaleQuantumToMap(p[PRE(x, y)].red) +
+ dyn_process[PRE(x, y - 1)].red +
+ dyn_process[PRE(x - 1, y)].red -
+ dyn_process[PRE(x - 1, y - 1)].red;
+ overflow_eminent |= (current_pre->red & overflow_mask);
+
+ if (!is_grayscale)
+ {
+ /* green */
+ current_pre->green =
+ ScaleQuantumToMap(p[PRE(x, y)].green) +
+ dyn_process[PRE(x, y - 1)].green +
+ dyn_process[PRE(x - 1, y)].green -
+ dyn_process[PRE(x - 1, y - 1)].green;
+ overflow_eminent |= (current_pre->green & overflow_mask);
+
+ /* blue */
+ current_pre->blue =
+ ScaleQuantumToMap(p[PRE(x, y)].blue) +
+ dyn_process[PRE(x, y - 1)].blue +
+ dyn_process[PRE(x - 1, y)].blue -
+ dyn_process[PRE(x - 1, y - 1)].blue;
+ overflow_eminent |= (current_pre->blue & overflow_mask);
+ }
+ if (matte)
+ {
+ /* opacity */
+ current_pre->opacity =
+ ScaleQuantumToMap(p[PRE(x, y)].opacity) +
+ dyn_process[PRE(x, y - 1)].opacity +
+ dyn_process[PRE(x - 1, y)].opacity -
+ dyn_process[PRE(x - 1, y - 1)].opacity;
+ overflow_eminent |= (current_pre->opacity & overflow_mask);
+ }
+ /* END preprocess for (x,y) */
+
+ /*
+ * start computing threshold mean, with the
+ * pre-computed data and only for pixels inside valid
+ * domain
+ */
+ if ((y > (height/2 + height)) && (x >= width) &&
+ (x < (image->columns + width)))
+ {
+ /* Left, Right, Upper, Bottom coord. to calculate the
+ window's sum */
+ long
+ L,
+ R,
+ U,
+ B;
+
+ LongPixelPacket
+ long_sum;
+
+ L = x - width/2 - (width & 1); /* if is odd, subtract 1... */
+ R = x + width/2;
+ U = y - height - 1;
+ B = y - 1;
+
+ long_sum = long_zero;
+
+ if (L >= 0)
+ {
+ long_sum.red += dyn_process[PRE(L, U)].red;
+ long_sum.red -= dyn_process[PRE(L, B)].red;
+ }
+
+ long_sum.red += dyn_process[PRE(R, B)].red;
+ long_sum.red -= dyn_process[PRE(R, U)].red;
+ if (!is_grayscale)
+ {
+ if (L >= 0)
+ {
+ long_sum.green += dyn_process[PRE(L, U)].green;
+ long_sum.green -= dyn_process[PRE(L, B)].green;
+ long_sum.blue += dyn_process[PRE(L, U)].blue;
+ long_sum.blue -= dyn_process[PRE(L, B)].blue;
+ }
+
+ long_sum.green += dyn_process[PRE(R, B)].green;
+ long_sum.green -= dyn_process[PRE(R, U)].green;
+ long_sum.blue += dyn_process[PRE(R, B)].blue;
+ long_sum.blue -= dyn_process[PRE(R, U)].blue;
+ }
+ if (matte)
+ {
+ if (L >= 0)
+ {
+ long_sum.opacity += dyn_process[PRE(L, U)].opacity;
+ long_sum.opacity -= dyn_process[PRE(L, B)].opacity;
+ }
+
+ long_sum.opacity += dyn_process[PRE(R, B)].opacity;
+ long_sum.opacity -= dyn_process[PRE(R, U)].opacity;
+ }
+
+ /*
+ * Avoid overflow at mean. We were able to do
+ * this by using some bitwise operations but there
+ * was no speedup and the code get pretty hard to
+ * read...
+ */
+ if ((long) (long_sum.red / local_area) + long_offset > (long) MaxMap)
+ long_sum.red = MaxMap;
+ else if ((long) (long_sum.red / local_area) + long_offset < (long) 0L)
+ long_sum.red = 0UL;
+ else
+ long_sum.red = ((long) (long_sum.red / local_area)) + long_offset;
+
+ /* grayscale and red */
+ q[x - width].red = (ScaleQuantumToMap(q[x - width].red) <= long_sum.red ? 0U : MaxRGB);
+
+ if (!is_grayscale)
+ {
+ if ((long) (long_sum.green / local_area) + long_offset > (long) MaxMap)
+ long_sum.green = MaxMap;
+ else if ((long) (long_sum.green / local_area) + long_offset < (long) 0L)
+ long_sum.green = 0UL;
+ else
+ long_sum.green = ((long) (long_sum.green / local_area)) + long_offset;
+
+ if ((long) (long_sum.blue / local_area) + long_offset > (long) MaxMap)
+ long_sum.blue = MaxMap;
+ else if ((long) (long_sum.blue / local_area) + long_offset < (long) 0L)
+ long_sum.blue = 0UL;
+ else
+ long_sum.blue = ((long) (long_sum.blue / local_area)) + long_offset;
+
+ q[x - width].green = (ScaleQuantumToMap(q[x - width].green) <= long_sum.green ? 0U : MaxRGB);
+ q[x - width].blue = (ScaleQuantumToMap(q[x - width].blue) <= long_sum.blue ? 0U : MaxRGB);
+
+ }
+ if (matte)
+ {
+ if ((long) (long_sum.opacity / local_area) + long_offset > (long) MaxMap)
+ long_sum.opacity = MaxMap;
+ else if ((long) (long_sum.opacity / local_area) + long_offset < (long) 0)
+ long_sum.opacity = 0UL;
+ else
+ long_sum.opacity = (long_sum.opacity / local_area) + long_offset;
+
+ q[x - width].opacity =
+ (ScaleQuantumToMap(q[x - width].opacity) <= long_sum.opacity ? 0U : MaxRGB);
+ }
+
+ if (is_grayscale)
+ q[x - width].green = q[x - width].blue = q[x - width].red;
+ } /* if (y ... */
+ } /* for (x ... */
+ if (status == MagickFail)
+ break; /* Breaks overall 'y' loop '*/
+ if (q != (const PixelPacket *) NULL)
+ {
+ if (!SyncImagePixelsEx(threshold_image, exception))
+ {
+ status = MagickFail;
+ break; /* Breaks overall 'y' loop '*/
+ }
+ }
+ row_count++;
+ if (QuantumTick(row_count, image->rows))
+ if (!MagickMonitorFormatted(row_count, image->rows, exception,
+ AdaptiveThresholdImageText, image->filename))
+ {
+ status = MagickFail;
+ break; /* Breaks overall 'y' loop '*/
+ }
+ } /* for (y ... */
+
+ MagickFreeMemory(dyn_process);
+
+ if (MagickFail == status)
+ {
+ DestroyImage(threshold_image);
+ threshold_image = (Image *) NULL;
+ }
+ else if (is_grayscale)
+ {
+ threshold_image->is_monochrome = MagickTrue;
+ threshold_image->is_grayscale = MagickTrue;
+ }
+ return (threshold_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% A d d N o i s e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AddNoiseImage() adds random noise to the image.
+%
+% The format of the AddNoiseImage method is:
+%
+% Image *AddNoiseImage(const Image *image,const NoiseType noise_type,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o noise_type: The type of noise: Uniform, Gaussian, Multiplicative,
+% Impulse, Laplacian, Poisson, or Random.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *
+AddNoiseImage(const Image *image,const NoiseType noise_type,
+ ExceptionInfo *exception)
+{
+ return AddNoiseImageChannel(image,AllChannels,noise_type,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% A d d N o i s e I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AddNoiseImageChannel() adds random noise to one image channel.
+%
+% The format of the AddNoiseImageChannel method is:
+%
+% Image *AddNoiseImageChannel(const Image *image,
+% const ChannelType channel, const NoiseType noise_type,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: The image channel to apply noise to.
+%
+% o noise_type: The type of noise: Uniform, Gaussian, Multiplicative,
+% Impulse, Laplacian, Poisson, or Random.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *
+AddNoiseImageChannel(const Image *image,const ChannelType channel,
+ const NoiseType noise_type,
+ ExceptionInfo *exception)
+{
+ QuantumOperator
+ quantum_operator;
+
+ Image
+ *noise_image;
+
+ noise_image=CloneImage(image,0,0,True,exception);
+ if (noise_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ switch (noise_type)
+ {
+ case GaussianNoise:
+ quantum_operator=NoiseGaussianQuantumOp;
+ break;
+ case ImpulseNoise:
+ quantum_operator=NoiseImpulseQuantumOp;
+ break;
+ case LaplacianNoise:
+ quantum_operator=NoiseLaplacianQuantumOp;
+ break;
+ case MultiplicativeGaussianNoise:
+ quantum_operator=NoiseMultiplicativeQuantumOp;
+ break;
+ case PoissonNoise:
+ quantum_operator=NoisePoissonQuantumOp;
+ break;
+ case RandomNoise:
+ quantum_operator=NoiseRandomQuantumOp;
+ break;
+ case UniformNoise:
+ quantum_operator=NoiseUniformQuantumOp;
+ break;
+ default:
+ quantum_operator=UndefinedQuantumOp;
+ break;
+ }
+
+ (void) QuantumOperatorImage(noise_image,channel,quantum_operator,
+ MaxRGBDouble,exception);
+ return noise_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% B l a c k T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BlackThresholdImage() adjusts the levels of image channels such that
+% values below a specified threshold are set to the minimum value (black)
+% while the remaining pixels are unchanged.
+%
+% The format of the BlackThresholdImage method is:
+%
+% MagickPassFail BlackThresholdImage(Image *image,const char *thresholds)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o thresholds: Channel thresholds which are specified as a comma delimited
+% list containing the thresholds for red, green, blue, and opacity. If
+% the list contains a percent symbol (%) then all values are treated as
+% a percentage of MaxRGB.
+%
+*/
+MagickExport MagickPassFail BlackThresholdImage(Image *image,const char *thresholds)
+{
+ return QuantumOperatorImageMultivalue(image,ThresholdBlackQuantumOp,thresholds);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% B l u r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BlurImage() blurs an image. We convolve the image with a Gaussian
+% operator of the given radius and standard deviation (sigma).
+% For reasonable results, the radius should be larger than sigma. Use a
+% radius of 0 and BlurImage() selects a suitable radius for you.
+%
+% The format of the BlurImage method is:
+%
+% Image *BlurImage(const Image *image,const double radius,
+% const double sigma,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define BlurImageColumnsText "[%s] Blur columns: order %lu..."
+#define BlurImageRowsText "[%s] Blur rows: order %lu... "
+static void
+BlurScanline(const double *kernel,const unsigned long width,
+ const PixelPacket *source,PixelPacket *destination,
+ const unsigned long columns, const MagickBool matte)
+{
+ double
+ scale;
+
+ const DoublePixelPacket
+ zero = { 0.0, 0.0, 0.0, 0.0 };
+
+ DoublePixelPacket
+ aggregate;
+
+ register const double
+ *p;
+
+ register const PixelPacket
+ *q;
+
+ register long
+ i,
+ x;
+
+ if (width > columns)
+ {
+ for (x=0; x < (long) columns; x++)
+ {
+ aggregate=zero;
+ scale=0.0;
+ p=kernel;
+ q=source;
+ for (i=0; i < (long) columns; i++)
+ {
+ if ((i >= (x-(long) width/2)) && (i <= (x+(long) width/2)))
+ {
+ /* This region is the big CPU burner for the whole function */
+ aggregate.red+=(*p)*q->red;
+ aggregate.green+=(*p)*q->green;
+ aggregate.blue+=(*p)*q->blue;
+ if (matte)
+ aggregate.opacity+=(*p)*q->opacity;
+ }
+ if (((i+(long)(width/2)-x) >= 0) && ((i+width/2-x) < width))
+ scale+=kernel[i+width/2-x];
+ p++;
+ q++;
+ }
+ scale=1.0/scale;
+ destination[x].red=(Quantum) (scale*(aggregate.red+0.5));
+ destination[x].green=(Quantum) (scale*(aggregate.green+0.5));
+ destination[x].blue=(Quantum) (scale*(aggregate.blue+0.5));
+ if (matte)
+ destination[x].opacity=(Quantum) (scale*(aggregate.opacity+0.5));
+ }
+ return;
+ }
+ /*
+ Blur scanline.
+ */
+ for (x=0; x < (long) (width/2); x++)
+ {
+ aggregate=zero;
+ scale=0.0;
+ p=kernel+width/2-x;
+ q=source;
+ for (i=width/2-x; i < (long) width; i++)
+ {
+ aggregate.red+=(*p)*q->red;
+ aggregate.green+=(*p)*q->green;
+ aggregate.blue+=(*p)*q->blue;
+ if (matte)
+ aggregate.opacity+=(*p)*q->opacity;
+ scale+=(*p);
+ p++;
+ q++;
+ }
+ scale=1.0/scale;
+ destination[x].red=(Quantum) (scale*(aggregate.red+0.5));
+ destination[x].green=(Quantum) (scale*(aggregate.green+0.5));
+ destination[x].blue=(Quantum) (scale*(aggregate.blue+0.5));
+ if (matte)
+ destination[x].opacity=(Quantum) (scale*(aggregate.opacity+0.5));
+ }
+ for ( ; x < (long) (columns-width/2); x++)
+ {
+ aggregate=zero;
+ p=kernel;
+ q=source+(x-width/2);
+ for (i=0; i < (long) width; i++)
+ {
+ aggregate.red+=(*p)*q->red;
+ aggregate.green+=(*p)*q->green;
+ aggregate.blue+=(*p)*q->blue;
+ if (matte)
+ aggregate.opacity+=(*p)*q->opacity;
+ p++;
+ q++;
+ }
+ destination[x].red=(Quantum) (aggregate.red+0.5);
+ destination[x].green=(Quantum) (aggregate.green+0.5);
+ destination[x].blue=(Quantum) (aggregate.blue+0.5);
+ if (matte)
+ destination[x].opacity=(Quantum) (aggregate.opacity+0.5);
+ }
+ for ( ; x < (long) columns; x++)
+ {
+ aggregate=zero;
+ scale=0;
+ p=kernel;
+ q=source+(x-width/2);
+ for (i=0; i < (long) (columns-x+width/2); i++)
+ {
+ aggregate.red+=(*p)*q->red;
+ aggregate.green+=(*p)*q->green;
+ aggregate.blue+=(*p)*q->blue;
+ if (matte)
+ aggregate.opacity+=(*p)*q->opacity;
+ scale+=(*p);
+ p++;
+ q++;
+ }
+ scale=1.0/scale;
+ destination[x].red=(Quantum) (scale*(aggregate.red+0.5));
+ destination[x].green=(Quantum) (scale*(aggregate.green+0.5));
+ destination[x].blue=(Quantum) (scale*(aggregate.blue+0.5));
+ if (matte)
+ destination[x].opacity=(Quantum) (scale*(aggregate.opacity+0.5));
+ }
+}
+
+static int GetBlurKernel(unsigned long width,const double sigma,double **kernel)
+{
+#define KernelRank 3
+
+ double
+ alpha,
+ normalize;
+
+ int
+ bias;
+
+ register long
+ i;
+
+ /*
+ Generate a 1-D convolution matrix. Calculate the kernel at higher
+ resolution than needed and average the results as a form of numerical
+ integration to get the best accuracy.
+ */
+ if (width == 0)
+ width=3;
+ *kernel=MagickAllocateMemory(double *,width*sizeof(double));
+ if (*kernel == (double *) NULL)
+ return(0);
+ for (i=0; i < (long) width; i++)
+ (*kernel)[i]=0.0;
+ bias=KernelRank*width/2;
+ for (i=(-bias); i <= bias; i++)
+ {
+ alpha=exp(-((double) i*i)/(2.0*KernelRank*KernelRank*sigma*sigma));
+ (*kernel)[(i+bias)/KernelRank]+=alpha/(MagickSQ2PI*sigma);
+ }
+ normalize=0;
+ for (i=0; i < (long) width; i++)
+ normalize+=(*kernel)[i];
+ for (i=0; i < (long) width; i++)
+ (*kernel)[i]/=normalize;
+ return(width);
+}
+
+static MagickPassFail BlurImageScanlines(Image *image,const double *kernel,
+ const unsigned long width,
+ const char *format,
+ ExceptionInfo *exception)
+{
+ ThreadViewDataSet
+ *data_set;
+
+ MagickBool
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ const MagickBool
+ matte=((image->matte) || (image->colorspace == CMYKColorspace));
+
+ is_grayscale=image->is_grayscale;
+
+ data_set=AllocateThreadViewDataArray(image,exception,image->columns,sizeof(PixelPacket));
+ if (data_set == (ThreadViewDataSet *) NULL)
+ status=MagickFail;
+
+ if (status != MagickFail)
+ {
+ unsigned long
+ row_count=0;
+
+ long
+ y;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register PixelPacket
+ *q;
+
+ PixelPacket
+ *scanline;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_BlurImageScanlines)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ scanline=AccessThreadViewData(data_set);
+ q=GetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ unsigned long
+ i=0;
+
+ scanline[i]=q[i];
+ i++;
+ for ( ; i < image->columns; i++)
+ {
+ if (NotPixelMatch(&scanline[i-1],&q[i],matte))
+ break;
+ scanline[i]=q[i];
+ }
+ if (i != image->columns)
+ {
+ (void) memcpy(&scanline[i],&q[i],
+ (image->columns-i)*sizeof(PixelPacket));
+ BlurScanline(kernel,width,scanline,q,image->columns,matte);
+ if (!SyncImagePixelsEx(image,exception))
+ thread_status=MagickFail;
+ }
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_BlurImageScanlines)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ format,image->filename,width))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+
+ DestroyThreadViewDataSet(data_set);
+ image->is_grayscale=is_grayscale;
+
+ return status;
+}
+
+MagickExport Image *
+BlurImage(const Image *original_image,const double radius,
+ const double sigma,ExceptionInfo *exception)
+{
+
+ double
+ *kernel;
+
+ Image
+ *blur_image;
+
+ int
+ width;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Get convolution matrix for the specified standard-deviation.
+ */
+ assert(original_image != (Image *) NULL);
+ assert(original_image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ kernel=(double *) NULL;
+ if (radius > 0)
+ width=GetBlurKernel((int) (2*ceil(radius)+1),sigma,&kernel);
+ else
+ {
+ double
+ *last_kernel;
+
+ last_kernel=(double *) NULL;
+ width=GetBlurKernel(3,sigma,&kernel);
+ while ((long) (MaxRGB*kernel[0]) > 0)
+ {
+ if (last_kernel != (double *)NULL)
+ MagickFreeMemory(last_kernel);
+ last_kernel=kernel;
+ kernel=(double *) NULL;
+ width=GetBlurKernel(width+2,sigma,&kernel);
+ }
+ if (last_kernel != (double *) NULL)
+ {
+ MagickFreeMemory(kernel);
+ width-=2;
+ kernel=last_kernel;
+ }
+ }
+ if (width < 3)
+ {
+ MagickFreeMemory(kernel);
+ ThrowImageException3(OptionError,UnableToBlurImage,
+ KernelRadiusIsTooSmall);
+ }
+
+ blur_image=RotateImage(original_image,90,exception);
+ if (blur_image == (Image *) NULL)
+ status=MagickFail;
+
+ if (status != MagickFail)
+ blur_image->storage_class=DirectClass;
+
+ if (status != MagickFail)
+ status&=BlurImageScanlines(blur_image,kernel,width,BlurImageColumnsText,
+ exception);
+
+ if (status != MagickFail)
+ {
+ Image
+ *rotate_image;
+
+ rotate_image=RotateImage(blur_image,-90,exception);
+ if (rotate_image == (Image *) NULL)
+ status=MagickFail;
+
+ if (status != MagickFail)
+ {
+ DestroyImage(blur_image);
+ blur_image=rotate_image;
+ }
+ }
+
+ if (status != MagickFail)
+ status&=BlurImageScanlines(blur_image,kernel,width,BlurImageRowsText,
+ exception);
+
+ MagickFreeMemory(kernel);
+
+ if (status != MagickFail)
+ blur_image->is_grayscale=original_image->is_grayscale;
+
+ return(blur_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% B l u r I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BlurImageChannel() blurs the specified image channel. We convolve the
+% image channel with a Gaussian operator of the given radius and standard
+% deviation (sigma). For reasonable results, the radius should be larger
+% than sigma. Use a radius of 0 and BlurImageChannel() selects a suitable
+% radius for you.
+%
+% The format of the BlurImageChannel method is:
+%
+% Image *BlurImageChannel(const Image *image,const ChannelType channel,
+% const double radius,const double sigma,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o channel: The channel to blur.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *
+BlurImageChannel(const Image *image,const ChannelType channel,
+ const double radius,const double sigma,
+ ExceptionInfo *exception)
+{
+ Image
+ *blur_image;
+
+ blur_image=BlurImage(image,radius,sigma,exception);
+ if (blur_image != (Image *) NULL)
+ (void) ImportImageChannelsMasked(image,blur_image,channel);
+
+ return blur_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C h a n n e l T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ChannelThresholdImage() changes the value of individual pixels based on
+% the level of each pixel channel. The result sets the affected channels
+% to the minimum or maximum channel value. A negative threshold value
+% disables thresholding for that channel. Append a percent symbol to
+% have threshold values automatically scaled from a percentage to MaxRGB.
+%
+% Invoked by the '-threshold' option.
+%
+% The format of the ChannelThresholdImage method is:
+%
+% MagickPassFail ChannelThresholdImage(Image *image,const char *threshold)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o threshold: define the threshold values, <red>{<green>,<blue>,<opacity>}{%}.
+%
+%
+*/
+typedef struct _ChannelThresholdOptions_t
+{
+ PixelPacket
+ thresholds;
+
+ MagickBool
+ red_enabled,
+ green_enabled,
+ blue_enabled,
+ opacity_enabled;
+} ChannelThresholdOptions_t;
+
+static MagickPassFail
+ChannelThresholdPixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Threshold channels
+ */
+ const ChannelThresholdOptions_t
+ *options = (const ChannelThresholdOptions_t *) immutable_data;
+
+ register long
+ i;
+
+ const PixelPacket
+ *thresholds=&options->thresholds;
+
+ const MagickBool
+ red_enabled=options->red_enabled,
+ green_enabled=options->green_enabled,
+ blue_enabled=options->blue_enabled,
+ opacity_enabled=options->opacity_enabled;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ if (red_enabled)
+ pixels[i].red=(pixels[i].red <= thresholds->red ? 0U : MaxRGB);
+ if (green_enabled)
+ pixels[i].green=(pixels[i].green <= thresholds->green ? 0U : MaxRGB);
+ if (blue_enabled)
+ pixels[i].blue=(pixels[i].blue <= thresholds->blue ? 0U : MaxRGB);
+ if (opacity_enabled)
+ pixels[i].opacity=(pixels[i].opacity <= thresholds->opacity ? 0U : MaxRGB);
+ }
+ return MagickPass;
+}
+
+#define ChannelThresholdImageText "[%s] Channel threshold..."
+MagickExport MagickPassFail ChannelThresholdImage(Image *image,
+ const char *threshold)
+{
+ DoublePixelPacket
+ double_threshold;
+
+ ChannelThresholdOptions_t
+ options;
+
+ int
+ count;
+
+ unsigned int
+ is_grayscale=image->is_grayscale;
+
+ MagickPassFail
+ status = MagickPass;
+
+ /*
+ Threshold image.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (threshold == (const char *) NULL)
+ return(MagickFail);
+
+ options.thresholds.red = 0U;
+ options.thresholds.green = 0U;
+ options.thresholds.blue = 0U;
+ options.thresholds.opacity = 0U;
+
+ options.red_enabled = MagickFalse;
+ options.green_enabled = MagickFalse;
+ options.blue_enabled = MagickFalse;
+ options.opacity_enabled = MagickFalse;
+
+ double_threshold.red = -1.0;
+ double_threshold.green = -1.0;
+ double_threshold.blue = -1.0;
+ double_threshold.opacity = -1.0;
+ count=sscanf(threshold,"%lf%*[/,%%]%lf%*[/,%%]%lf%*[/,%%]%lf",
+ &double_threshold.red,
+ &double_threshold.green,
+ &double_threshold.blue,
+ &double_threshold.opacity);
+
+ if ((count > 3) && (double_threshold.opacity >= 0.0))
+ options.opacity_enabled = MagickTrue;
+ if ((count > 2) && (double_threshold.blue >= 0.0))
+ options.blue_enabled = MagickTrue;
+ if ((count > 1) && (double_threshold.green >= 0.0))
+ options.green_enabled = MagickTrue;
+ if ((count > 0) && (double_threshold.red >= 0.0))
+ options.red_enabled = MagickTrue;
+
+ if (strchr(threshold,'%') != (char *) NULL)
+ {
+ if (options.red_enabled)
+ double_threshold.red *= MaxRGB/100.0;
+ if (options.green_enabled)
+ double_threshold.green *= MaxRGB/100.0;
+ if (options.blue_enabled)
+ double_threshold.blue *= MaxRGB/100.0;
+ if (options.opacity_enabled)
+ double_threshold.opacity *= MaxRGB/100.0;
+ }
+
+ if (options.red_enabled)
+ options.thresholds.red = RoundDoubleToQuantum(double_threshold.red);
+ if (options.green_enabled)
+ options.thresholds.green = RoundDoubleToQuantum(double_threshold.green);
+ if (options.blue_enabled)
+ options.thresholds.blue = RoundDoubleToQuantum(double_threshold.blue);
+ if (options.opacity_enabled)
+ options.thresholds.opacity = RoundDoubleToQuantum(double_threshold.opacity);
+
+ (void) SetImageType(image,TrueColorType);
+
+ status=PixelIterateMonoModify(ChannelThresholdPixels,
+ NULL,
+ ChannelThresholdImageText,
+ NULL,&options,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+
+ if (is_grayscale && options.red_enabled && options.green_enabled && options.blue_enabled)
+ {
+ image->is_monochrome=True;
+ image->is_grayscale=True;
+ }
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C o n v o l v e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ConvolveImage() applies a custom convolution kernel to the image.
+%
+% The format of the ConvolveImage method is:
+%
+% Image *ConvolveImage(const Image *image,const unsigned int order,
+% const double *kernel,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o order: The number of columns and rows in the filter kernel.
+%
+% o kernel: An array of double representing the convolution kernel.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define ConvolveImageText "[%s] Convolve: order %u..."
+MagickExport Image *ConvolveImage(const Image *image,const unsigned int order,
+ const double *kernel,ExceptionInfo *exception)
+{
+#if QuantumDepth < 32
+ typedef float float_quantum_t;
+ typedef FloatPixelPacket float_packet_t;
+# define RoundFloatQuantumToIntQuantum(value) RoundFloatToQuantum(value)
+#else
+ typedef double float_quantum_t;
+ typedef DoublePixelPacket float_packet_t;
+# define RoundFloatQuantumToIntQuantum(value) RoundDoubleToQuantum(value)
+#endif
+
+ float_quantum_t
+ * restrict normal_kernel;
+
+ Image
+ *convolve_image;
+
+ long
+ width,
+ y;
+
+ MagickPassFail
+ status;
+
+ const MagickBool
+ is_grayscale = image->is_grayscale;
+
+ const MagickBool
+ matte=((image->matte) || (image->colorspace == CMYKColorspace));
+
+ /*
+ Initialize convolve image attributes.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ width=(long) order;
+ if ((width % 2) == 0)
+ ThrowImageException3(OptionError,UnableToConvolveImage,
+ KernelWidthMustBeAnOddNumber);
+ if (((long) image->columns < width) || ((long) image->rows < width))
+ ThrowImageException3(OptionError,UnableToConvolveImage,
+ ImageSmallerThanKernelWidth);
+ convolve_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
+ if (convolve_image == (Image *) NULL)
+ return((Image *) NULL);
+ convolve_image->storage_class=DirectClass;
+ {
+ /*
+ Build normalized kernel.
+
+ 0x0.25 --> 3x3
+ 0x0.5 --> 5x5
+ 0x1 --> 9x9
+ 0x2 --> 17x17
+ 0x3 --> 25x25
+ 0x4 --> 33x33
+ 0x5 --> 41x41
+ 0x6 --> 49x49
+ */
+ double
+ normalize;
+
+ register long
+ i;
+
+ normal_kernel=MagickAllocateAlignedMemory(float_quantum_t *,
+ MAGICK_CACHE_LINE_SIZE,
+ width*width*sizeof(float_quantum_t));
+ if (normal_kernel == (float_quantum_t *) NULL)
+ {
+ DestroyImage(convolve_image);
+ ThrowImageException(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(OptionError,UnableToConvolveImage));
+ }
+ normalize=0.0;
+ for (i=0; i < (width*width); i++)
+ normalize+=kernel[i];
+ if (AbsoluteValue(normalize) <= MagickEpsilon)
+ normalize=1.0;
+ normalize=1.0/normalize;
+ for (i=0; i < (width*width); i++)
+ {
+ normal_kernel[i]=normalize*kernel[i];
+ }
+ }
+
+ if (LogMagickEvent(TransformEvent,GetMagickModule(),
+ " ConvolveImage with %ldx%ld kernel:",width,width))
+ {
+ /*
+ Log convolution matrix.
+ */
+ char
+ cell_text[MaxTextExtent],
+ row_text[MaxTextExtent];
+
+ const double
+ *k;
+
+ long
+ u,
+ v;
+
+ k=kernel;
+ for (v=0; v < width; v++)
+ {
+ *row_text='\0';
+ for (u=0; u < width; u++)
+ {
+ FormatString(cell_text,"%#12.4g",*k++);
+ (void) strlcat(row_text,cell_text,sizeof(row_text));
+ if (u%5 == 4)
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ " %.64s", row_text);
+ *row_text='\0';
+ }
+ }
+ if (u > 5)
+ (void) strlcat(row_text,"\n",sizeof(row_text));
+ if (row_text[0] != '\0')
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ " %s", row_text);
+ }
+ }
+
+ status=MagickPass;
+ /*
+ Convolve image.
+ */
+ {
+ unsigned long
+ row_count=0;
+
+ float_packet_t
+ zero;
+
+ (void) memset(&zero,0,sizeof(float_packet_t));
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(guided) shared(row_count, status)
+# endif
+# endif
+#endif
+ for (y=0; y < (long) convolve_image->rows; y++)
+ {
+ const PixelPacket
+ * restrict p;
+
+ PixelPacket
+ * restrict q;
+
+ long
+ x;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ConvolveImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ /*
+ Acquire rectangle of columns+width high, and width tall.
+ */
+ p=AcquireImagePixels(image,-width/2,y-width/2,image->columns+width,width,
+ exception);
+ /*
+ Set one row.
+ */
+ q=SetImagePixelsEx(convolve_image,0,y,convolve_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ for (x=0; x < (long) convolve_image->columns; x++)
+ {
+ float_packet_t
+ pixel;
+
+
+ const PixelPacket
+ * restrict r;
+
+ long
+ u,
+ v;
+
+ const float_quantum_t
+ * restrict k;
+
+ r=p;
+ pixel=zero;
+ k=normal_kernel;
+ if (is_grayscale && !matte)
+ {
+ /* G */
+ for (v=0; v < width; v++)
+ {
+ for (u=0; u < width; u++)
+ pixel.red+=k[u]*r[u].red;
+ k+= width;
+ r+=image->columns+width;
+ }
+ q->red=q->green=q->blue=RoundFloatQuantumToIntQuantum(pixel.red);
+ q->opacity=OpaqueOpacity;
+ }
+ else if (!matte)
+ {
+ /* RGB */
+ for (v=0; v < width; v++)
+ {
+ for (u=0; u < width; u++)
+ {
+ pixel.red+=k[u]*r[u].red;
+ pixel.green+=k[u]*r[u].green;
+ pixel.blue+=k[u]*r[u].blue;
+ }
+ k+=width;
+ r+=image->columns+width;
+ }
+ q->red=RoundFloatQuantumToIntQuantum(pixel.red);
+ q->green=RoundFloatQuantumToIntQuantum(pixel.green);
+ q->blue=RoundFloatQuantumToIntQuantum(pixel.blue);
+ q->opacity=OpaqueOpacity;
+ }
+ else
+ {
+ /* RGBA */
+ for (v=0; v < width; v++)
+ {
+ for (u=0; u < width; u++)
+ {
+ pixel.red+=k[u]*r[u].red;
+ pixel.green+=k[u]*r[u].green;
+ pixel.blue+=k[u]*r[u].blue;
+ pixel.opacity+=k[u]*r[u].opacity;
+ }
+ k+=width;
+ r+=image->columns+width;
+ }
+ q->red=RoundFloatQuantumToIntQuantum(pixel.red);
+ q->green=RoundFloatQuantumToIntQuantum(pixel.green);
+ q->blue=RoundFloatQuantumToIntQuantum(pixel.blue);
+ q->opacity=RoundFloatQuantumToIntQuantum(pixel.opacity);
+ }
+ p++;
+ q++;
+ }
+ if (!SyncImagePixelsEx(convolve_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ConvolveImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ ConvolveImageText,
+ convolve_image->filename,
+ order))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ MagickFreeAlignedMemory(normal_kernel);
+ if (MagickFail == status)
+ {
+ DestroyImage(convolve_image);
+ convolve_image=(Image *) NULL;
+ }
+ else
+ {
+ convolve_image->is_grayscale=is_grayscale;
+ }
+ return(convolve_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% D e s p e c k l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Despeckle() reduces the speckle noise in an image while preserving the
+% edges of the original image.
+%
+% The format of the DespeckleImage method is:
+%
+% Image *DespeckleImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *DespeckleImage(const Image *image,ExceptionInfo *exception)
+{
+#define DespeckleImageText "[%s] Despeckle..."
+
+ Image
+ *despeckle_image;
+
+ Quantum
+ *buffer = (Quantum *) NULL,
+ *pixels = (Quantum *) NULL;
+
+ unsigned long
+ progress=0UL,
+ progress_span;
+
+ int
+ layer,
+ min_layer,
+ max_layer;
+
+ size_t
+ length;
+
+ ImageCharacteristics
+ characteristics;
+
+ static const int
+ X[4]=
+ {
+ 0, 1, 1,-1
+ };
+
+ static const int
+ Y[4]=
+ {
+ 1, 0, 1, 1
+ };
+
+ MagickPassFail
+ status = MagickPass;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ /*
+ Analyze image.
+ */
+ if (!GetImageCharacteristics(image,&characteristics,MagickFalse,exception))
+ return ((Image *) NULL);
+
+ if (characteristics.opaque)
+ min_layer=1;
+ else
+ min_layer=0;
+ if (characteristics.grayscale)
+ max_layer=2;
+ else
+ max_layer=4;
+
+ progress_span=4*(max_layer-min_layer);
+
+ /*
+ Compute buffer size
+ */
+ length=(image->columns+2)*(image->rows+2);
+
+ /*
+ Allocate planar working buffers
+ */
+ pixels=MagickAllocateArray(Quantum *,length,sizeof(*pixels));
+ if (pixels == (Quantum *) NULL)
+ {
+ ThrowException3(exception,ResourceLimitError,MemoryAllocationFailed,
+ UnableToDespeckleImage);
+ return ((Image *) NULL);
+ }
+ buffer=MagickAllocateArray(Quantum *,length,sizeof(*buffer));
+ if (buffer == (Quantum *) NULL)
+ {
+ MagickFreeMemory(pixels);
+ ThrowException3(exception,ResourceLimitError,MemoryAllocationFailed,
+ UnableToDespeckleImage);
+ return ((Image *) NULL);
+ }
+
+ /*
+ Allocate despeckled image.
+ */
+ despeckle_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (despeckle_image == (Image *) NULL)
+ {
+ MagickFreeMemory(pixels);
+ MagickFreeMemory(buffer);
+ return ((Image *) NULL);
+ }
+ despeckle_image->storage_class=DirectClass;
+
+ /*
+ Reduce speckle in the image.
+ */
+ for (layer=min_layer; layer < max_layer; layer++)
+ {
+ long
+ j,
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+
+ /*
+ Export image channel
+ */
+ (void) memset(pixels,0,length*sizeof(Quantum));
+ j=(long) image->columns+2;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ j++;
+
+ switch (layer)
+ {
+ case 0:
+ for (x=(long) image->columns; x > 0; x--)
+ pixels[j++]=p++->opacity;
+ break;
+ case 1:
+ for (x=(long) image->columns; x > 0; x--)
+ pixels[j++]=p++->red;
+ break;
+ case 2:
+ for (x=(long) image->columns; x > 0; x--)
+ pixels[j++]=p++->green;
+ break;
+ case 3:
+ for (x=(long) image->columns; x > 0; x--)
+ pixels[j++]=p++->blue;
+ break;
+ default:
+ break;
+ }
+
+ j++;
+ }
+ if (status == MagickFail)
+ break;
+
+ (void) memset(buffer,0,length*sizeof(Quantum));
+ for (i=0; i < 4; i++)
+ {
+ progress++;
+ if (!MagickMonitorFormatted(progress,progress_span,exception,
+ DespeckleImageText,
+ despeckle_image->filename))
+ {
+ status=MagickFail;
+ break;
+ }
+ Hull(X[i],Y[i],image->columns,image->rows,pixels,buffer,1);
+ Hull(-X[i],-Y[i],image->columns,image->rows,pixels,buffer,1);
+ Hull(-X[i],-Y[i],image->columns,image->rows,pixels,buffer,-1);
+ Hull(X[i],Y[i],image->columns,image->rows,pixels,buffer,-1);
+ }
+ if (status == MagickFail)
+ break;
+
+ /*
+ Import image channel
+ */
+ j=(long) image->columns+2;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=SetImagePixelsEx(despeckle_image,0,y,despeckle_image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ j++;
+
+ switch (layer)
+ {
+ case 0:
+ for (x=(long) image->columns; x > 0; x--)
+ q++->opacity=pixels[j++];
+ break;
+ case 1:
+ if (characteristics.grayscale)
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ q->red=q->green=q->blue=pixels[j++];
+ q++;
+ }
+ }
+ else
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ q++->red=pixels[j++];
+ }
+ break;
+ case 2:
+ for (x=(long) image->columns; x > 0; x--)
+ q++->green=pixels[j++];
+ break;
+ case 3:
+ for (x=(long) image->columns; x > 0; x--)
+ q++->blue=pixels[j++];
+ break;
+ default:
+ break;
+ }
+
+ if (!SyncImagePixelsEx(despeckle_image,exception))
+ {
+ status=MagickFail;
+ break;
+ }
+ j++;
+ }
+ }
+
+ MagickFreeMemory(pixels);
+ MagickFreeMemory(buffer);
+
+ if (status == MagickFail)
+ {
+ DestroyImage(despeckle_image);
+ return (Image *) NULL;
+ }
+
+ despeckle_image->is_grayscale=image->is_grayscale;
+ return(despeckle_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% E d g e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EdgeImage() finds edges in an image. Radius defines the radius of the
+% convolution filter. Use a radius of 0 and Edge() selects a suitable
+% radius for you.
+%
+% The format of the EdgeImage method is:
+%
+% Image *EdgeImage(const Image *image,const double radius,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: the radius of the pixel neighborhood.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *EdgeImage(const Image *image,const double radius,
+ ExceptionInfo *exception)
+{
+ double
+ *kernel;
+
+ Image
+ *edge_image;
+
+ int
+ width;
+
+ register long
+ i;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ width=GetOptimalKernelWidth(radius,0.5);
+ if (((long) image->columns < width) || ((long) image->rows < width))
+ ThrowImageException3(OptionError,UnableToEdgeImage,
+ ImageSmallerThanRadius);
+ kernel=MagickAllocateMemory(double *,width*width*sizeof(double));
+ if (kernel == (double *) NULL)
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToEdgeImage);
+ for (i=0; i < (width*width); i++)
+ kernel[i]=(-1.0);
+ kernel[i/2]=width*width-1.0;
+ edge_image=ConvolveImage(image,width,kernel,exception);
+ MagickFreeMemory(kernel);
+ edge_image->is_grayscale=image->is_grayscale;
+ return(edge_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% E m b o s s I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EmbossImage() returns a grayscale image with a three-dimensional effect.
+% We convolve the image with a Gaussian operator of the given radius and
+% standard deviation (sigma). For reasonable results, radius should be
+% larger than sigma. Use a radius of 0 and Emboss() selects a suitable
+% radius for you.
+%
+% The format of the EmbossImage method is:
+%
+% Image *EmbossImage(const Image *image,const double radius,
+% const double sigma,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: the radius of the pixel neighborhood.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *EmbossImage(const Image *image,const double radius,
+ const double sigma,ExceptionInfo *exception)
+{
+ double
+ alpha,
+ *kernel;
+
+ Image
+ *emboss_image;
+
+ int
+ j,
+ width;
+
+ register long
+ i,
+ u,
+ v;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ width=GetOptimalKernelWidth(radius,0.5);
+ kernel=MagickAllocateMemory(double *,width*width*sizeof(double));
+ if (kernel == (double *) NULL)
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToEmbossImage);
+ i=0;
+ j=width/2;
+ for (v=(-width/2); v <= (width/2); v++)
+ {
+ for (u=(-width/2); u <= (width/2); u++)
+ {
+ alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
+ kernel[i]=((u < 0) || (v < 0) ? -8.0 : 8.0)*
+ alpha/(2.0*MagickPI*sigma*sigma);
+ if (u == j)
+ kernel[i]=v == j ? 1.0 : 0.0;
+ i++;
+ }
+ j--;
+ }
+ emboss_image=ConvolveImage(image,width,kernel,exception);
+ if (emboss_image != (Image *) NULL)
+ (void) EqualizeImage(emboss_image);
+ MagickFreeMemory(kernel);
+ if (emboss_image != (Image *) NULL)
+ emboss_image->is_grayscale=image->is_grayscale;
+ return(emboss_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% E n h a n c e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EnhanceImage() applies a digital filter to the image color channels that
+% improves the quality of a noisy image. The opacity channel is preserved
+% but is otherwise ignored.
+%
+% The format of the EnhanceImage method is:
+%
+% Image *EnhanceImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define EnhanceImageText "[%s] Enhance... "
+
+MagickExport Image *EnhanceImage(const Image *image,ExceptionInfo *exception)
+{
+ static const double
+ Weights[5][5] =
+ {
+ { 5.0, 8.0, 10.0, 8.0, 5.0 },
+ { 8.0, 20.0, 40.0, 20.0, 8.0 },
+ { 10.0, 40.0, 80.0, 40.0, 10.0 },
+ { 8.0, 20.0, 40.0, 20.0, 8.0 },
+ { 5.0, 8.0, 10.0, 8.0, 5.0 }
+ };
+
+ Image
+ *enhance_image;
+
+ long
+ y;
+
+ /*
+ Initialize enhanced image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if ((image->columns < 5) || (image->rows < 5))
+ return((Image *) NULL);
+ enhance_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (enhance_image == (Image *) NULL)
+ return((Image *) NULL);
+ enhance_image->storage_class=DirectClass;
+ /*
+ Enhance image.
+ */
+ {
+ unsigned long
+ row_count=0;
+
+ DoublePixelPacket
+ zero;
+
+ MagickPassFail
+ status=MagickPass;
+
+ (void) memset(&zero,0,sizeof(DoublePixelPacket));
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(guided) shared(row_count, status)
+# endif
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q;
+
+ register long
+ x;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_EnhanceImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ /*
+ Read another scan line.
+ */
+ p=AcquireImagePixels(image,0,y-2,image->columns,5,exception);
+ q=SetImagePixelsEx(enhance_image,0,y,enhance_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ DoublePixelPacket
+ aggregate;
+
+ double
+ pixel_red,
+ pixel_green,
+ pixel_blue,
+ total_weight;
+
+ register const PixelPacket
+ *r;
+
+ double
+ distance,
+ distance_squared,
+ mean;
+
+ unsigned long
+ i,
+ j;
+
+ /*
+ Transfer first 2 pixels of the scanline.
+ */
+ *q++=(*(p+2*image->columns));
+ *q++=(*(p+2*image->columns+1));
+ for (x=2; x < (long) (image->columns-2); x++)
+ {
+ /*
+ Compute weighted average of target pixel color components.
+ */
+ aggregate=zero;
+ total_weight=0.0;
+ r=p+2*image->columns+2;
+ pixel_red=r->red;
+ pixel_green=r->green;
+ pixel_blue=r->blue;
+
+ for (i=0 ; i < 5; i++)
+ {
+ r=p+i*image->columns;
+ for (j = 0; j < 5; j++)
+ {
+ const double red = (double) r->red;
+ const double green = (double) r->green;
+ const double blue = (double) r->blue;
+ mean=(red+pixel_red)/2.0;
+ distance=red-pixel_red;
+ distance_squared=(2.0*(MaxRGBDouble+1.0)+mean)*distance*
+ distance/MaxRGBDouble;
+ mean=(green+pixel_green)/2.0;
+ distance=green-pixel_green;
+ distance_squared+=4.0*distance*distance;
+ mean=(blue+pixel_blue)/2.0;
+ distance=blue-pixel_blue;
+ distance_squared+=
+ (3.0*(MaxRGBDouble+1.0)-1.0-mean)*distance*distance/MaxRGBDouble;
+ if (distance_squared < ((MaxRGBDouble*MaxRGBDouble/25.0)))
+ {
+ const double weight = Weights[i][j];
+ aggregate.red+=weight*red;
+ aggregate.green+=weight*green;
+ aggregate.blue+=weight*blue;
+ total_weight+=weight;
+ }
+ r++;
+ }
+ }
+ q->red=(Quantum) ((aggregate.red+(total_weight/2.0)-1.0)/total_weight);
+ q->green=(Quantum) ((aggregate.green+(total_weight/2.0)-1.0)/total_weight);
+ q->blue=(Quantum) ((aggregate.blue+(total_weight/2.0)-1.0)/total_weight);
+ q->opacity=p->opacity;
+ p++;
+ q++;
+ }
+ p++;
+ *q++=(*p++);
+ *q++=(*p++);
+ if (!SyncImagePixelsEx(enhance_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_EnhanceImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ EnhanceImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ enhance_image->is_grayscale=image->is_grayscale;
+ return(enhance_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% G a u s s i a n B l u r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GaussianBlurImage() blurs an image. We convolve the image with a
+% Gaussian operator of the given radius and standard deviation (sigma).
+% For reasonable results, the radius should be larger than sigma. Use a
+% radius of 0 and GaussianBlurImage() selects a suitable radius for you
+%
+% The format of the GaussianBlurImage method is:
+%
+% Image *GaussianBlurImage(const Image *image,const double radius,
+% const double sigma,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o blur_image: Method GaussianBlurImage returns a pointer to the image
+% after it is blur. A null image is returned if there is a memory
+% shortage.
+%
+% o image: Image to blur.
+%
+% o radius: the radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: the standard deviation of the Gaussian, in pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *GaussianBlurImage(const Image *image,const double radius,
+ const double sigma,ExceptionInfo *exception)
+{
+ double
+ alpha,
+ *kernel;
+
+ Image
+ *blur_image;
+
+ int
+ width;
+
+ register long
+ i,
+ u,
+ v;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ width=GetOptimalKernelWidth2D(radius,sigma);
+ if (((long) image->columns < width) || ((long) image->rows < width))
+ ThrowImageException3(OptionError,UnableToBlurImage,
+ ImageSmallerThanRadius);
+ kernel=MagickAllocateMemory(double *,width*width*sizeof(double));
+ if (kernel == (double *) NULL)
+ ThrowImageException(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(OptionError,UnableToBlurImage));
+ i=0;
+ for (v=(-width/2); v <= (width/2); v++)
+ {
+ for (u=(-width/2); u <= (width/2); u++)
+ {
+ alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
+ kernel[i]=alpha/(2.0*MagickPI*sigma*sigma);
+ i++;
+ }
+ }
+ blur_image=ConvolveImage(image,width,kernel,exception);
+ MagickFreeMemory(kernel);
+ blur_image->is_grayscale=image->is_grayscale;
+ return(blur_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% G a u s s i a n B l u r I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GaussianBlurImageChannel() blurs an image channel. We convolve the image
+% with a Gaussian operator of the given radius and standard deviation
+% (sigma). For reasonable results, the radius should be larger than sigma.
+% Use a radius of 0 and GaussianBlurImage() selects a suitable radius for
+% you.
+%
+% The format of the GaussianBlurImageChannel method is:
+%
+% Image *GaussianBlurImageChannel(const Image *image,
+% const ChannelType channel,const double radius,
+% const double sigma,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o blur_image: Method GaussianBlurImage returns a pointer to the image
+% after it is blur. A null image is returned if there is a memory
+% shortage.
+%
+% o image: Image to blur.
+%
+% o channel: Channel to blur in image.
+%
+% o radius: the radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: the standard deviation of the Gaussian, in pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *GaussianBlurImageChannel(const Image *image,
+ const ChannelType channel,const double radius,const double sigma,
+ ExceptionInfo *exception)
+{
+ Image
+ *blur_image;
+
+ blur_image=GaussianBlurImage(image,radius,sigma,exception);
+ if (blur_image != (Image *) NULL)
+ (void) ImportImageChannelsMasked(image,blur_image,channel);
+
+ return blur_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M e d i a n F i l t e r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MedianFilterImage() applies a digital filter that improves the quality
+% of a noisy image. Each pixel is replaced by the median in a set of
+% neighboring pixels as defined by radius.
+%
+% The algorithm was contributed by Mike Edmonds and implements an insertion
+% sort for selecting median color-channel values. For more on this algorithm
+% see "Skip Lists: A probabilistic Alternative to Balanced Trees" by William
+% Pugh in the June 1990 of Communications of the ACM.
+%
+% The format of the MedianFilterImage method is:
+%
+% Image *MedianFilterImage(const Image *image,const double radius,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: The radius of the pixel neighborhood.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+typedef struct _MedianListNode
+{
+ unsigned int
+ next[9],
+ count,
+ signature;
+} MedianListNode;
+
+typedef struct _MedianSkipList
+{
+ MedianListNode
+ *nodes;
+
+ int
+ level;
+} MedianSkipList;
+
+typedef struct _MedianPixelList
+{
+ MedianSkipList
+ lists[4];
+
+ unsigned int
+ center,
+ seed,
+ signature;
+} MedianPixelList;
+
+static void AddNodeMedianList(MedianPixelList *pixel_list,
+ const unsigned int channel,
+ const unsigned int color)
+{
+ register MedianSkipList
+ *list;
+
+ register int
+ level;
+
+ unsigned int
+ search,
+ update[9];
+
+ /*
+ Initialize the node.
+ */
+ list=pixel_list->lists+channel;
+ list->nodes[color].signature=pixel_list->signature;
+ list->nodes[color].count=1;
+ /*
+ Determine where it belongs in the list.
+ This loop consumes most of the time.
+ */
+ search=65536UL;
+ for (level=list->level; level >= 0; level--)
+ {
+ while (list->nodes[search].next[level] < color)
+ search=list->nodes[search].next[level];
+ update[level]=search;
+ }
+ /*
+ Generate a pseudo-random level for this node.
+ */
+ for (level=0; ; level++)
+ {
+ pixel_list->seed=(pixel_list->seed*42893621U)+1U;
+ if ((pixel_list->seed & 0x300) != 0x300)
+ break;
+ }
+ if (level > 8)
+ level=8;
+ if (level > (list->level+2))
+ level=list->level+2;
+ /*
+ If we're raising the list's level, link back to the root node.
+ */
+ while (level > list->level)
+ {
+ list->level++;
+ update[list->level]=65536U;
+ }
+ /*
+ Link the node into the skip-list.
+ */
+ do
+ {
+ list->nodes[color].next[level]=list->nodes[update[level]].next[level];
+ list->nodes[update[level]].next[level]=color;
+ }
+ while (level-- > 0);
+}
+
+static void GetMedianList(MedianPixelList * restrict pixel_list,PixelPacket *median_pixel)
+{
+ register MedianSkipList
+ *list;
+
+ register unsigned int
+ channel;
+
+ unsigned int
+ center,
+ color,
+ count;
+
+ unsigned short
+ channels[4];
+
+ /*
+ Find the median value for each of the colors.
+ */
+ center=pixel_list->center;
+ for (channel=0; channel < 4U; channel++)
+ {
+ list=pixel_list->lists+channel;
+ color=65536L;
+ count=0;
+ do
+ {
+ color=list->nodes[color].next[0];
+ count+=list->nodes[color].count;
+ }
+ while (count <= center); /* IM now uses count <= (center >> 1) */
+ channels[channel]=color;
+ }
+ median_pixel->red=ScaleShortToQuantum(channels[0]);
+ median_pixel->green=ScaleShortToQuantum(channels[1]);
+ median_pixel->blue=ScaleShortToQuantum(channels[2]);
+ median_pixel->opacity=ScaleShortToQuantum(channels[3]);
+}
+
+static inline void InsertMedianListChannel(MedianPixelList *pixel_list,
+ const unsigned int channel,
+ const Quantum quantum)
+{
+ register unsigned int
+ index;
+
+ index=ScaleQuantumToShort(quantum);
+ if (pixel_list->lists[channel].nodes[index].signature == pixel_list->signature)
+ pixel_list->lists[channel].nodes[index].count++;
+ else
+ AddNodeMedianList(pixel_list,channel,index);
+}
+
+static inline void InsertMedianList(MedianPixelList *pixel_list,
+ const PixelPacket *pixel)
+{
+ InsertMedianListChannel(pixel_list,0,pixel->red);
+ InsertMedianListChannel(pixel_list,1,pixel->green);
+ InsertMedianListChannel(pixel_list,2,pixel->blue);
+ InsertMedianListChannel(pixel_list,3,pixel->opacity);
+}
+
+static void ResetMedianList(MedianPixelList *pixel_list)
+{
+ register MedianListNode
+ *root;
+
+ register MedianSkipList
+ *list;
+
+ register long
+ channel;
+
+ int
+ level;
+
+ /*
+ Reset the skip-list.
+ */
+ for (channel=0; channel < 4; channel++)
+ {
+ list=pixel_list->lists+channel;
+ root=list->nodes+65536UL;
+ list->level=0;
+ for (level=0; level < 9; level++)
+ root->next[level]=65536UL;
+ }
+ pixel_list->seed=pixel_list->signature++;
+}
+
+static void DestroyMedianList(void *pixel_list)
+{
+ MedianPixelList
+ *skiplist;
+
+ skiplist=(MedianPixelList *) pixel_list;
+
+ if (skiplist != (void *) NULL)
+ {
+ unsigned int
+ i;
+
+ for (i=0; i < 4U; i++)
+ MagickFreeAlignedMemory(skiplist->lists[i].nodes);
+ }
+ MagickFreeAlignedMemory(skiplist);
+}
+
+static MedianPixelList *AllocateMedianList(const long width)
+{
+ MedianPixelList
+ *skiplist;
+
+ skiplist=MagickAllocateAlignedMemory(MedianPixelList *,
+ MAGICK_CACHE_LINE_SIZE,
+ sizeof(MedianPixelList));
+ if (skiplist != (MedianPixelList *) NULL)
+ {
+ unsigned int
+ i;
+
+ const size_t
+ node_list_size = 65537U*sizeof(MedianListNode);
+
+ (void) memset(skiplist,0,sizeof(MedianPixelList));
+ skiplist->center=width*width/2;
+ skiplist->signature=MagickSignature;
+ for (i=0; i < 4U; i++)
+ {
+ skiplist->lists[i].nodes =
+ MagickAllocateAlignedMemory(MedianListNode *,MAGICK_CACHE_LINE_SIZE,
+ node_list_size);
+ if (skiplist->lists[i].nodes == (MedianListNode *) NULL)
+ {
+ DestroyMedianList(skiplist);
+ skiplist=(MedianPixelList *) NULL;
+ break;
+ }
+ (void) memset(skiplist->lists[i].nodes,0,node_list_size);
+ }
+ }
+ return skiplist;
+}
+
+MagickExport Image *MedianFilterImage(const Image *image,const double radius,
+ ExceptionInfo *exception)
+{
+#define MedianFilterImageText "[%s] Filter with neighborhood ranking..."
+
+ Image
+ *median_image;
+
+ long
+ width,
+ y;
+
+ ThreadViewDataSet
+ *data_set;
+
+ unsigned long
+ row_count=0;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize median image attributes.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ width=GetOptimalKernelWidth2D(radius,0.5);
+ if (((long) image->columns < width) || ((long) image->rows < width))
+ ThrowImageException3(OptionError,UnableToFilterImage,
+ ImageSmallerThanRadius);
+ median_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
+ if (median_image == (Image *) NULL)
+ return ((Image *) NULL);
+
+ median_image->storage_class=DirectClass;
+ /*
+ Allocate skip-lists.
+ */
+ data_set=AllocateThreadViewDataSet(DestroyMedianList,image,exception);
+ if (data_set != (ThreadViewDataSet *) NULL)
+ {
+ unsigned int
+ i,
+ views;
+
+ views=GetThreadViewDataSetAllocatedViews(data_set);
+ for (i=0; i < views; i++)
+ {
+ MedianPixelList
+ *skiplist;
+
+ skiplist=AllocateMedianList(width);
+ if (skiplist != (MedianPixelList *) NULL)
+ {
+ AssignThreadViewData(data_set,i,skiplist);
+ continue;
+ }
+
+ DestroyThreadViewDataSet(data_set);
+ data_set=(ThreadViewDataSet *) NULL;
+ break;
+ }
+ }
+ if (data_set == (ThreadViewDataSet *) NULL)
+ {
+ DestroyImage(median_image);
+ return ((Image *) NULL);
+ }
+ {
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) median_image->rows; y++)
+ {
+ register MedianPixelList
+ *skiplist;
+
+ const PixelPacket
+ *p;
+
+ PixelPacket
+ *q;
+
+ long
+ x;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_MedianFilterImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ skiplist=AccessThreadViewData(data_set);
+ p=AcquireImagePixels(image,-width/2,y-width/2,
+ image->columns+width,width,exception);
+ q=SetImagePixelsEx(median_image,0,y,median_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for (x=0; x < (long) median_image->columns; x++)
+ {
+ register const PixelPacket
+ *r;
+
+ register long
+ u,
+ v;
+
+ ResetMedianList(skiplist);
+ r=&p[x];
+ for (v=0; v < width; v++)
+ {
+ for (u=0; u < width; u++)
+ InsertMedianList(skiplist,&r[u]);
+ r+=image->columns+width;
+ }
+ GetMedianList(skiplist,&q[x]);
+ }
+ if (!SyncImagePixelsEx(median_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_MedianFilterImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,median_image->rows))
+ if (!MagickMonitorFormatted(row_count,median_image->rows,exception,
+ MedianFilterImageText,
+ median_image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ DestroyThreadViewDataSet(data_set);
+ median_image->is_grayscale=image->is_grayscale;
+ return(median_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M o t i o n B l u r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MotionBlurImage() simulates motion blur. We convolve the image with a
+% Gaussian operator of the given radius and standard deviation (sigma).
+% For reasonable results, radius should be larger than sigma. Use a
+% radius of 0 and MotionBlurImage() selects a suitable radius for you.
+% Angle gives the angle of the blurring motion (direction object appears
+% to be coming from).
+%
+% Andrew Protano contributed this effect.
+%
+% The format of the MotionBlurImage method is:
+%
+% Image *MotionBlurImage(const Image *image,const double radius,
+% const double sigma,const double angle,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting
+% the center pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o angle: Apply the effect along this angle.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+static double *AllocateMotionBlurKernel(const int width,const double sigma)
+{
+#define KernelRank 3
+
+ double
+ *kernel;
+
+ /*
+ Generate a 1-D convolution matrix. Calculate the kernel at higher
+ resolution than needed and average the results as a form of numerical
+ integration to get the best accuracy.
+ */
+ kernel=MagickAllocateMemory(double *,width*sizeof(double));
+ if (kernel != (double *) NULL)
+ {
+ double
+ alpha,
+ normalize;
+
+ int
+ bias;
+
+ register long
+ i;
+
+ for (i=0; i < width; i++)
+ kernel[i]=0.0;
+ bias=KernelRank*width;
+ for (i=0; i < bias; i++)
+ {
+ alpha=exp(-((double) i*i)/(2.0*KernelRank*KernelRank*sigma*sigma));
+ kernel[i/KernelRank]+=alpha/(MagickSQ2PI*sigma);
+ }
+ normalize=0;
+ for (i=0; i < width; i++)
+ normalize+=kernel[i];
+ for (i=0; i < width; i++)
+ kernel[i]/=normalize;
+ }
+
+ return kernel;
+}
+
+typedef struct _BlurOffsetInfo
+{
+ int
+ x,
+ y;
+} BlurOffsetInfo;
+#define MotionBlurImageText "[%s] Motion blur..."
+MagickExport Image *MotionBlurImage(const Image *image,const double radius,
+ const double sigma,const double angle,
+ ExceptionInfo *exception)
+{
+ double
+ *kernel;
+
+ Image
+ *blur_image;
+
+ int
+ width;
+
+ BlurOffsetInfo
+ *offsets;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ width=GetOptimalKernelWidth1D(radius,sigma);
+ if (width < 3)
+ ThrowImageException3(OptionError,UnableToBlurImage,
+ KernelRadiusIsTooSmall);
+ kernel=AllocateMotionBlurKernel(width,sigma);
+ if (kernel == (double *) NULL)
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToMotionBlurImage);
+ {
+ long
+ x;
+
+ long
+ y;
+
+ register long
+ i;
+
+ /*
+ Allocate and initialize offsets.
+ */
+ offsets=MagickAllocateMemory(BlurOffsetInfo *,width*sizeof(BlurOffsetInfo));
+ if (offsets == (BlurOffsetInfo *) NULL)
+ {
+ MagickFreeMemory(kernel);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToMotionBlurImage);
+ }
+ x=(long) (width*sin(DegreesToRadians(angle+90)));
+ y=(long) (width*cos(DegreesToRadians(angle+90)));
+ for (i=0; i < width; i++)
+ {
+ offsets[i].x=(int) (i*x/sqrt(x*x+y*y)+0.5);
+ offsets[i].y=(int) (i*y/sqrt(x*x+y*y)+0.5);
+ }
+ }
+ /*
+ Allocate blur image.
+ */
+ blur_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
+ if (blur_image == (Image *) NULL)
+ {
+ MagickFreeMemory(kernel);
+ MagickFreeMemory(offsets);
+ return((Image *) NULL);
+ }
+ blur_image->storage_class=DirectClass;
+ {
+ /*
+ Motion blur image.
+ */
+ unsigned long
+ row_count=0;
+
+ long
+ y;
+
+ DoublePixelPacket
+ zero;
+
+ MagickPassFail
+ status;
+
+ status=MagickPass;
+ (void) memset(&zero,0,sizeof(DoublePixelPacket));
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register PixelPacket
+ *q;
+
+ register long
+ x;
+
+ MagickBool
+ matte=blur_image->matte;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_MotionBlurImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ q=SetImagePixelsEx(blur_image,0,y,blur_image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ DoublePixelPacket
+ aggregate;
+
+ PixelPacket
+ pixel;
+
+ register long
+ i;
+
+ aggregate=zero;
+ for (i=0; i < width; i++)
+ {
+ if (AcquireOnePixelByReference(image,&pixel,
+ (long) x+offsets[i].x,
+ (long) y+offsets[i].y,
+ exception)
+ == MagickFail)
+ {
+ thread_status=MagickFail;
+ }
+
+ aggregate.red+=kernel[i]*pixel.red;
+ aggregate.green+=kernel[i]*pixel.green;
+ aggregate.blue+=kernel[i]*pixel.blue;
+ if (matte)
+ aggregate.opacity+=kernel[i]*pixel.opacity;
+ }
+ if (thread_status == MagickFail)
+ break;
+ q->red=(Quantum) aggregate.red;
+ q->green=(Quantum) aggregate.green;
+ q->blue=(Quantum) aggregate.blue;
+ if (matte)
+ q->opacity=(Quantum) aggregate.opacity;
+ q++;
+ }
+ if (!SyncImagePixelsEx(blur_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_MotionBlurImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ MotionBlurImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ MagickFreeMemory(kernel);
+ MagickFreeMemory(offsets);
+ blur_image->is_grayscale=image->is_grayscale;
+ return(blur_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% R a n d o m C h a n n e l T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RandomChannelThresholdImage() changes the value of individual pixels based
+% on the intensity of each pixel compared to a random threshold. The result
+% is a low-contrast, two color image.
+%
+% The format of the RandomChannelThresholdImage method is:
+%
+% unsigned int RandomChannelThresholdImage(Image *image,
+% const char *channel, const char *thresholds,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: The channel or channels to be thresholded.
+%
+% o thresholds: a geometry string containing LOWxHIGH thresholds.
+% If the string contains 2x2, 3x3, 4x4, 5x5, 6x6, or 7x7, then
+% an ordered dither of order 2, 3, 4, 5, 6, or 7 will be performed
+% instead.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickPassFail
+RandomChannelThresholdImage(Image *image,const char *channel,
+ const char *thresholds,ExceptionInfo *exception)
+{
+#define RandomChannelThresholdImageText "[%s] Random-channel threshold... "
+
+ const double
+ o2[4]={1.0, 3.0,
+ 4.0, 2.0};
+
+ const double
+ o3[9]={1.0, 6.0, 3.0,
+ 7.0, 5.0, 8.0,
+ 4.0, 9.0, 2.0};
+
+ const double
+ o4[16]={ 1.0, 9.0, 3.0, 11.0,
+ 13.0, 5.0, 15.0, 7.0,
+ 4.0, 12.0, 2.0, 10.0,
+ 16.0, 8.0, 14.0, 6.0};
+
+ const double
+ o5[25]={ 1.0, 5.0, 16.0, 15.0, 4.0,
+ 6.0, 17.0, 20.0, 19.0, 14.0,
+ 7.0, 21.0, 25.0, 24.0, 13.0,
+ 8.0, 18.0, 22.0, 23.0, 12.0,
+ 2.0, 9.0, 10.0, 11.0, 3.0};
+
+ const double
+ o6[36]={ 1.0, 5.0, 14.0, 13.0, 12.0, 4.0,
+ 6.0, 22.0, 28.0, 27.0, 21.0, 11.0,
+ 15.0, 29.0, 35.0, 34.0, 26.0, 20.0,
+ 16.0, 30.0, 36.0, 33.0, 25.0, 19.0,
+ 7.0, 23.0, 31.0, 32.0, 24.0, 10.0,
+ 2.0, 8.0, 17.0, 18.0, 9.0, 3.0};
+
+ const double
+ o7[49]={ 2.0, 7.0, 17.0, 26.0, 15.0, 6.0, 1.0,
+ 8.0, 16.0, 33.0, 39.0, 32.0, 13.0, 5.0,
+ 18.0, 34.0, 44.0, 48.0, 43.0, 31.0, 14.0,
+ 27.0, 40.0, 45.0, 49.0, 47.0, 38.0, 25.0,
+ 20.0, 35.0, 41.0, 46.0, 42.0, 30.0, 24.0,
+ 9.0, 19.0, 36.0, 37.0, 29.0, 22.0, 12.0,
+ 3.0, 10.0, 21.0, 28.0, 23.0, 11.0, 4.0};
+
+
+ Quantum
+ matrix[49];
+
+ Quantum
+ lower_threshold=0U,
+ upper_threshold=MaxRGB;
+
+ long
+ count;
+
+ unsigned int
+ i,
+ order;
+
+ const MagickBool
+ is_grayscale=image->is_grayscale,
+ is_monochrome=image->is_monochrome;
+
+ MagickBool
+ logging;
+
+ ChannelType
+ channel_type;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Threshold image.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ if (image->is_monochrome && !image->matte)
+ return(True);
+ if (thresholds == (const char *) NULL)
+ return(True);
+
+ if (LocaleCompare(thresholds,"2x2") == 0)
+ order=2;
+ else if (LocaleCompare(thresholds,"3x3") == 0)
+ order=3;
+ else if (LocaleCompare(thresholds,"4x4") == 0)
+ order=4;
+ else if (LocaleCompare(thresholds,"5x5") == 0)
+ order=5;
+ else if (LocaleCompare(thresholds,"6x6") == 0)
+ order=6;
+ else if (LocaleCompare(thresholds,"7x7") == 0)
+ order=7;
+ else
+ {
+ double
+ lower,
+ upper;
+
+ order=1;
+ lower=0.0;
+ upper=0.0;
+ count=sscanf(thresholds,"%lf[/x%%]%lf",
+ &lower,&upper);
+
+ if (strchr(thresholds,'%') != (char *) NULL)
+ {
+ upper*=(0.01*MaxRGB);
+ lower*=(0.01*MaxRGB);
+ }
+ if (count == 1)
+ upper=MaxRGBDouble-lower;
+ lower_threshold=RoundDoubleToQuantum(lower);
+ upper_threshold=RoundDoubleToQuantum(upper);
+ }
+
+ logging=LogMagickEvent(TransformEvent,GetMagickModule(),
+ " RandomChannelThresholdImage: channel type=%s",channel);
+ if (logging)
+ (void)LogMagickEvent(TransformEvent,GetMagickModule(),
+ " Thresholds: %s (%lux%lu)",
+ thresholds,(unsigned long) lower_threshold,
+ (unsigned long) upper_threshold);
+
+ channel_type=StringToChannelType(channel);
+ if (UndefinedChannel == channel_type)
+ ThrowBinaryException3(OptionError, UnableToThresholdImage,
+ UnrecognizedChannelType);
+
+ if ((AllChannels == channel_type) ||
+ (GrayChannel == channel_type))
+ if (!AllocateImageColormap(image,2))
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToThresholdImage);
+
+ {
+ double
+ value;
+
+ /*
+ Pre-scale the ordered dither matrix.
+ */
+ if (2 == order)
+ for (i=0;i < (sizeof(o2)/sizeof(double)); i++)
+ {
+ value=o2[i]*(MaxRGBDouble/5.0);
+ matrix[i]=RoundDoubleToQuantum(value);
+ }
+ else if (3 == order)
+ for (i=0;i < (sizeof(o3)/sizeof(double)); i++)
+ {
+ value=o3[i]*(MaxRGBDouble/10.0);
+ matrix[i]=RoundDoubleToQuantum(value);
+ }
+ else if (4 == order)
+ for (i=0;i < (sizeof(o4)/sizeof(double)); i++)
+ {
+ value=o4[i]*(MaxRGBDouble/17.0);
+ matrix[i]=RoundDoubleToQuantum(value);
+ }
+ else if (5 == order)
+ for (i=0;i < (sizeof(o5)/sizeof(double)); i++)
+ {
+ value=o5[i]*(MaxRGBDouble/26.0);
+ matrix[i]=RoundDoubleToQuantum(value);
+ }
+ else if (6 == order)
+ for (i=0;i < (sizeof(o6)/sizeof(double)); i++)
+ {
+ value=o6[i]*(MaxRGBDouble/37.0);
+ matrix[i]=RoundDoubleToQuantum(value);
+ }
+ else if (7 == order)
+ for (i=0;i < (sizeof(o7)/sizeof(double)); i++)
+ {
+ value=o7[i]*(MaxRGBDouble/50.0);
+ matrix[i]=RoundDoubleToQuantum(value);
+ }
+ else
+ {
+ for (i=0;i < (sizeof(matrix)/sizeof(Quantum)); i++)
+ matrix[i]=0U;
+ }
+ }
+
+ {
+ unsigned long
+ row_count=0;
+
+ long
+ y;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ Quantum
+ intensity,
+ threshold=0U;
+
+ register IndexPacket
+ *indexes;
+
+ register PixelPacket
+ *q;
+
+ register IndexPacket
+ index;
+
+ register unsigned long
+ x;
+
+ MagickRandomKernel
+ *random_kernel;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_RandomChannelThresholdImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ random_kernel=AcquireMagickRandomKernel();
+ q=GetImagePixelsEx(image,0,y,image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ indexes=AccessMutableIndexes(image);
+ if (((AllChannels == channel_type) ||
+ (GrayChannel == channel_type)) &&
+ (!is_monochrome))
+ {
+ switch (order)
+ {
+ case 1:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ intensity=(is_grayscale ?
+ q->red : PixelIntensityToQuantum(q));
+ if (intensity < lower_threshold)
+ threshold=lower_threshold;
+ else if (intensity > upper_threshold)
+ threshold=upper_threshold;
+ else
+ threshold=(Quantum) (MaxRGBDouble*MagickRandomRealInlined(random_kernel));
+ index=intensity <= threshold ? 0U : 1U;
+ *indexes++=index;
+ q->red=q->green=q->blue=image->colormap[index].red;
+ q++;
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ intensity=(is_grayscale ?
+ q->red : PixelIntensityToQuantum(q));
+ threshold=matrix[(x%order)+order*(y%order)];
+ index=intensity <= threshold ? 0U : 1U;
+ *indexes++=index;
+ q->red=q->green=q->blue=image->colormap[index].red;
+ q++;
+ }
+ break;
+ }
+ }
+ if ((OpacityChannel == channel_type) ||
+ (AllChannels == channel_type) ||
+ (MatteChannel == channel_type) ||
+ (BlackChannel == channel_type))
+ {
+ if (image->matte)
+ switch (order)
+ {
+ case 1:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (q->opacity < lower_threshold)
+ threshold=lower_threshold;
+ else if (q->opacity > upper_threshold)
+ threshold=upper_threshold;
+ else
+ threshold=(Quantum) (MaxRGBDouble*MagickRandomRealInlined(random_kernel));
+ q->opacity=(q->opacity <= threshold ? 0U : MaxRGB);
+ q++;
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ threshold=matrix[(x%order)+order*(y%order)];
+ q->opacity=(q->opacity <= threshold ? 0U : MaxRGB);
+ q++;
+ }
+ break;
+ }
+ }
+
+ if ((RedChannel == channel_type) ||
+ (CyanChannel == channel_type))
+ {
+ switch (order)
+ {
+ case 1:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (q->red < lower_threshold)
+ threshold=lower_threshold;
+ else if (q->red > upper_threshold)
+ threshold=upper_threshold;
+ else
+ threshold=(Quantum) (MaxRGBDouble*MagickRandomRealInlined(random_kernel));
+ q->red=(q->red <= threshold ? 0U : MaxRGB);
+ q++;
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ threshold=matrix[(x%order)+order*(y%order)];
+ q->red=(q->red <= threshold ? 0U : MaxRGB);
+ q++;
+ }
+ break;
+ }
+ }
+
+ if ((GreenChannel == channel_type) ||
+ (MagentaChannel == channel_type))
+ {
+ switch (order)
+ {
+ case 1:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (q->green < lower_threshold)
+ threshold=lower_threshold;
+ else if (q->green > upper_threshold)
+ threshold=upper_threshold;
+ else
+ threshold=(Quantum) (MaxRGBDouble*MagickRandomRealInlined(random_kernel));
+ q->green=(q->green <= threshold ? 0U : MaxRGB);
+ q++;
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ threshold=matrix[(x%order)+order*(y%order)];
+ q->green=(q->green <= threshold ? 0U : MaxRGB);
+ q++;
+ }
+ break;
+ }
+ }
+
+ if ((BlueChannel == channel_type) ||
+ (YellowChannel == channel_type))
+ {
+ switch (order)
+ {
+ case 1:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ if (q->blue < lower_threshold)
+ threshold=lower_threshold;
+ else if (q->blue > upper_threshold)
+ threshold=upper_threshold;
+ else
+ threshold=(Quantum) (MaxRGBDouble*MagickRandomRealInlined(random_kernel));
+ q->blue=(q->blue <= threshold ? 0U : MaxRGB);
+ q++;
+ }
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ threshold=matrix[(x%order)+order*(y%order)];
+ q->blue=(q->blue <= threshold ? 0U : MaxRGB);
+ q++;
+ }
+ break;
+ }
+ }
+
+ if (!SyncImagePixelsEx(image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_RandomChannelThresholdImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ RandomChannelThresholdImageText,
+ image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ if ((AllChannels == channel_type) ||
+ (GrayChannel == channel_type))
+ {
+ image->is_monochrome=True;
+ image->is_grayscale=True;
+ }
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% R e d u c e N o i s e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReduceNoiseImage() smooths the contours of an image while still preserving
+% edge information. The algorithm works by replacing each pixel with its
+% neighbor closest in value. A neighbor is defined by radius. Use a radius
+% of 0 and ReduceNoise() selects a suitable radius for you.
+%
+% The format of the ReduceNoiseImage method is:
+%
+% Image *ReduceNoiseImage(const Image *image,const double radius,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: The radius of the pixel neighborhood.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+static PixelPacket GetNonpeakMedianList(MedianPixelList *pixel_list)
+{
+ PixelPacket
+ pixel;
+
+ register MedianSkipList
+ *list;
+
+ register long
+ channel;
+
+ unsigned long
+ channels[4],
+ center,
+ color,
+ count,
+ previous,
+ next;
+
+ /*
+ Finds the median value for each of the color.
+ */
+ center=pixel_list->center;
+ for (channel=0; channel < 4; channel++)
+ {
+ list=pixel_list->lists+channel;
+ color=65536L;
+ next=list->nodes[color].next[0];
+ count=0;
+ do
+ {
+ previous=color;
+ color=next;
+ next=list->nodes[color].next[0];
+ count+=list->nodes[color].count;
+ }
+ while (count <= center);
+ if ((previous == 65536L) && (next != 65536L))
+ color=next;
+ else
+ if ((previous != 65536L) && (next == 65536L))
+ color=previous;
+ channels[channel]=color;
+ }
+ pixel.red=ScaleShortToQuantum(channels[0]);
+ pixel.green=ScaleShortToQuantum(channels[1]);
+ pixel.blue=ScaleShortToQuantum(channels[2]);
+ pixel.opacity=ScaleShortToQuantum(channels[3]);
+ return(pixel);
+}
+
+MagickExport Image *ReduceNoiseImage(const Image *image,const double radius,
+ ExceptionInfo *exception)
+{
+#define ReduceNoiseImageText "[%s] Reduce noise... "
+
+ Image
+ *noise_image;
+
+ long
+ width,
+ y;
+
+ ThreadViewDataSet
+ *data_set;
+
+ unsigned long
+ row_count=0;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize noise image attributes.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ width=GetOptimalKernelWidth2D(radius,0.5);
+ if (((long) image->columns < width) || ((long) image->rows < width))
+ ThrowImageException3(OptionError,UnableToFilterImage,
+ ImageSmallerThanRadius);
+ noise_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (noise_image == (Image *) NULL)
+ return ((Image *) NULL);
+
+ noise_image->storage_class=DirectClass;
+ /*
+ Allocate and initialize skip-lists.
+ */
+ data_set=AllocateThreadViewDataSet(DestroyMedianList,image,exception);
+ if (data_set != (ThreadViewDataSet *) NULL)
+ {
+ unsigned int
+ i,
+ views;
+
+ views=GetThreadViewDataSetAllocatedViews(data_set);
+ for (i=0; i < views; i++)
+ {
+ MedianPixelList
+ *skiplist;
+
+ skiplist=AllocateMedianList(width);
+ if (skiplist != (MedianPixelList *) NULL)
+ {
+ AssignThreadViewData(data_set,i,skiplist);
+ continue;
+ }
+
+ DestroyThreadViewDataSet(data_set);
+ data_set=(ThreadViewDataSet *) NULL;
+ break;
+ }
+ }
+ if (data_set == (ThreadViewDataSet *) NULL)
+ {
+ DestroyImage(noise_image);
+ return ((Image *) NULL);
+ }
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) noise_image->rows; y++)
+ {
+ const PixelPacket
+ *p;
+
+ PixelPacket
+ *q;
+
+ long
+ x;
+
+ MedianPixelList
+ *skiplist;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ReduceNoiseImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ skiplist=AccessThreadViewData(data_set);
+ p=AcquireImagePixels(image,-width/2,y-width/2,
+ image->columns+width,width,exception);
+ q=SetImagePixelsEx(noise_image,0,y,noise_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for (x=0; x < (long) noise_image->columns; x++)
+ {
+ register const PixelPacket
+ *r;
+
+ register long
+ u,
+ v;
+
+ r=p;
+ ResetMedianList(skiplist);
+ for (v=width; v > 0; v--)
+ {
+ for (u=0; u < width; u++)
+ InsertMedianList(skiplist,&r[u]);
+ r+=image->columns+width;
+ }
+ q[x]=GetNonpeakMedianList(skiplist);
+ p++;
+ }
+ if (!SyncImagePixelsEx(noise_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ReduceNoiseImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,noise_image->rows))
+ if (!MagickMonitorFormatted(row_count,noise_image->rows,exception,
+ ReduceNoiseImageText,
+ noise_image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ DestroyThreadViewDataSet(data_set);
+ noise_image->is_grayscale=image->is_grayscale;
+ return(noise_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% S h a d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ShadeImage() shines a distant light on an image to create a
+% three-dimensional effect. You control the positioning of the light with
+% azimuth and elevation; azimuth is measured in degrees off the x axis
+% and elevation is measured in pixels above the Z axis.
+%
+% The format of the ShadeImage method is:
+%
+% Image *ShadeImage(const Image *image,const unsigned int gray,
+% double azimuth,double elevation,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o gray: A value other than zero shades the intensity of each pixel.
+%
+% o azimuth, elevation: Define the light source direction.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+MagickExport Image *ShadeImage(const Image *image,const unsigned int gray,
+ double azimuth,double elevation,ExceptionInfo *exception)
+{
+#define ShadeImageText "[%s] Shade..."
+
+ Image
+ *shade_image;
+
+ long
+ y;
+
+ PrimaryInfo
+ light;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize shaded image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ shade_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (shade_image == (Image *) NULL)
+ return((Image *) NULL);
+ shade_image->storage_class=DirectClass;
+ /*
+ Compute the light vector.
+ */
+ azimuth=DegreesToRadians(azimuth);
+ elevation=DegreesToRadians(elevation);
+ light.x=(double) MaxRGBDouble*cos(azimuth)*cos(elevation);
+ light.y=(double) MaxRGBDouble*sin(azimuth)*cos(elevation);
+ light.z=(double) MaxRGBDouble*sin(elevation);
+ /*
+ Shade image.
+ */
+ {
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ PrimaryInfo
+ normal;
+
+ register const PixelPacket
+ *p,
+ *s0,
+ *s1,
+ *s2;
+
+ register PixelPacket
+ *q;
+
+ register long
+ x;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ShadeImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ normal.z=2.0*MaxRGBDouble; /* constant Z of surface normal */
+
+ p=AcquireImagePixels(image,-1,y-1,image->columns+2,3,exception);
+ q=SetImagePixelsEx(shade_image,0,y,shade_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+ /*
+ Shade this row of pixels.
+ */
+ if (thread_status != MagickFail)
+ {
+ s0=p+1;
+ s1=s0+image->columns+2;
+ s2=s1+image->columns+2;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ double
+ distance,
+ normal_distance,
+ shade;
+
+ /*
+ Determine the surface normal and compute shading.
+ */
+ normal.x=PixelIntensityToDouble(s0-1)+ PixelIntensityToDouble(s1-1)+
+ PixelIntensityToDouble(s2-1)-PixelIntensityToDouble(s0+1)-
+ PixelIntensityToDouble(s1+1)-PixelIntensityToDouble(s2+1);
+ normal.y=PixelIntensityToDouble(s2-1)+PixelIntensityToDouble(s2)+
+ PixelIntensityToDouble(s2+1)-PixelIntensityToDouble(s0-1)-
+ PixelIntensityToDouble(s0)-PixelIntensityToDouble(s0+1);
+ if ((normal.x == 0.0) && (normal.y == 0.0))
+ shade=light.z;
+ else
+ {
+ shade=0.0;
+ distance=normal.x*light.x+normal.y*light.y+normal.z*light.z;
+ if (distance > MagickEpsilon)
+ {
+ normal_distance=
+ normal.x*normal.x+normal.y*normal.y+normal.z*normal.z;
+ if (normal_distance > (MagickEpsilon*MagickEpsilon))
+ shade=distance/sqrt(normal_distance);
+ }
+ }
+ if (gray)
+ {
+ q->red=(Quantum) shade;
+ q->green=(Quantum) shade;
+ q->blue=(Quantum) shade;
+ }
+ else
+ {
+ q->red=(Quantum) ((shade*s1->red)/MaxRGBDouble+0.5);
+ q->green=(Quantum) ((shade*s1->green)/MaxRGBDouble+0.5);
+ q->blue=(Quantum) ((shade*s1->blue)/MaxRGBDouble+0.5);
+ }
+ q->opacity=s1->opacity;
+ s0++;
+ s1++;
+ s2++;
+ q++;
+ }
+ if (!SyncImagePixelsEx(shade_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ShadeImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ ShadeImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ shade_image->is_grayscale=image->is_grayscale;
+ if (gray)
+ shade_image->is_grayscale=True;
+ return(shade_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% S h a r p e n I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SharpenImage() sharpens an image. We convolve the image with a
+% Gaussian operator of the given radius and standard deviation (sigma).
+% For reasonable results, radius should be larger than sigma. Use a
+% radius of 0 and SharpenImage() selects a suitable radius for you.
+%
+% The format of the SharpenImage method is:
+%
+% Image *SharpenImage(const Image *image,const double radius,
+% const double sigma,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Laplacian, in pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *SharpenImage(const Image *image,const double radius,
+ const double sigma,ExceptionInfo *exception)
+{
+ double
+ alpha,
+ *kernel,
+ normalize;
+
+ Image
+ *sharp_image;
+
+ long
+ width;
+
+ register long
+ i,
+ u,
+ v;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ width=GetOptimalKernelWidth(radius,sigma);
+ if (((long) image->columns < width) || ((long) image->rows < width))
+ ThrowImageException3(OptionError,UnableToSharpenImage,
+ ImageSmallerThanRadius);
+ kernel=MagickAllocateMemory(double *,width*width*sizeof(double));
+ if (kernel == (double *) NULL)
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToSharpenImage);
+ i=0;
+ normalize=0.0;
+ for (v=(-width/2); v <= (width/2); v++)
+ {
+ for (u=(-width/2); u <= (width/2); u++)
+ {
+ alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
+ kernel[i]=alpha/(2.0*MagickPI*sigma*sigma);
+ normalize+=kernel[i];
+ i++;
+ }
+ }
+ kernel[i/2]=(-2.0)*normalize;
+ sharp_image=ConvolveImage(image,width,kernel,exception);
+ MagickFreeMemory(kernel);
+ sharp_image->is_grayscale=image->is_grayscale;
+ return(sharp_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% S h a r p e n I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SharpenImageChannel() sharpens an image channel. We convolve the image
+% channel with a Gaussian operator of the given radius and standard
+% deviation (sigma). For reasonable results, radius should be larger than
+% sigma. Use a radius of 0 and SharpenImageChannel() selects a suitable
+% radius for you.
+%
+% The format of the SharpenImageChannel method is:
+%
+% Image *SharpenImageChannel(const Image *image, const ChannelType channel,
+% const double radius,const double sigma, ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: The channel to sharpen.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Laplacian, in pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *SharpenImageChannel(const Image *image,
+ const ChannelType channel,const double radius,const double sigma,
+ ExceptionInfo *exception)
+{
+ Image
+ *sharp_image;
+
+ sharp_image=SharpenImage(image,radius,sigma,exception);
+ if (sharp_image != (Image *) NULL)
+ (void) ImportImageChannelsMasked(image,sharp_image,channel);
+
+ return sharp_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% S p r e a d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SpreadImage() is a special effects method that randomly displaces each
+% pixel in a block defined by the radius parameter.
+%
+% The format of the SpreadImage method is:
+%
+% Image *SpreadImage(const Image *image,const unsigned int radius,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: Choose a random pixel in a neighborhood of this extent.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *SpreadImage(const Image *image,const unsigned int radius,
+ ExceptionInfo *exception)
+{
+#define SpreadImageText "[%s] Spread..."
+#define OFFSETS_ENTRIES 5009U /* prime number is best */
+
+ Image
+ *spread_image;
+
+ int
+ *offsets;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if ((image->columns < 3) || (image->rows < 3))
+ return((Image *) NULL);
+ /*
+ Initialize spread image attributes.
+ */
+ spread_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (spread_image == (Image *) NULL)
+ return((Image *) NULL);
+ spread_image->storage_class=DirectClass;
+
+ /*
+ Initialize random offsets cache
+ */
+ {
+ MagickRandomKernel
+ *random_kernel;
+
+ unsigned int
+ x;
+
+ random_kernel=AcquireMagickRandomKernel();
+ offsets=MagickAllocateMemory(int *,OFFSETS_ENTRIES*sizeof(int));
+ if (offsets == (int *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,NULL);
+ return (Image *) NULL;
+ }
+ for (x=0; x < OFFSETS_ENTRIES; x++)
+ {
+ offsets[x]=(((2*(double) radius+1)*MagickRandomRealInlined(random_kernel))
+ -((int) radius));
+ }
+ }
+
+ /*
+ Spread each row.
+ */
+ {
+ unsigned long
+ row_count=0;
+
+ long
+ y;
+
+ MagickPassFail
+ status=MagickPass;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,8) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register PixelPacket
+ *q;
+
+ const PixelPacket
+ *neighbors;
+
+ register long
+ x;
+
+ long
+ y_min,
+ y_max;
+
+ long
+ x_distance,
+ y_distance;
+
+ unsigned int
+ offsets_index;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_SpreadImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ offsets_index=(y*image->columns) % OFFSETS_ENTRIES;
+ q=SetImagePixelsEx(spread_image,0,y,spread_image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (radius > (unsigned int) y)
+ y_min=0;
+ else
+ y_min=y-radius;
+
+ if (((unsigned long) y+radius) >= image->rows)
+ y_max=image->rows-1;
+ else
+ y_max=y+radius;
+
+ neighbors=AcquireImagePixels(image,0,y_min,image->columns,y_max-y_min,exception);
+ if (neighbors == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ unsigned int
+ tries;
+
+ tries=0;
+ do
+ {
+ x_distance=offsets[offsets_index++];
+ if (offsets_index == OFFSETS_ENTRIES)
+ {
+ if (tries++)
+ {
+ x_distance=0;
+ break;
+ }
+ offsets_index=0;
+ }
+ } while (((x+x_distance) < 0) ||
+ ((x+x_distance) >= (long) image->columns));
+ tries=0;
+ do
+ {
+ y_distance=offsets[offsets_index++];
+ if (offsets_index == OFFSETS_ENTRIES)
+ {
+ if (tries++)
+ {
+ y_distance=0;
+ break;
+ }
+ offsets_index=0;
+ }
+ } while (((y+y_distance) < 0) ||
+ ((y+y_distance) >= (long) image->rows));
+ *q=*(neighbors+(x+x_distance)+((y+y_distance-y_min)*image->columns));
+ q++;
+ }
+ if (!SyncImagePixelsEx(spread_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_SpreadImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ EnhanceImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ MagickFreeMemory(offsets);
+ spread_image->is_grayscale=image->is_grayscale;
+ spread_image->is_monochrome=image->is_monochrome;
+ return(spread_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ThresholdImage() changes the value of individual pixels based on
+% the intensity of each pixel compared to a specified threshold. Values
+% greater than the threshold are set to the maximum quantum value, and
+% values equal to or below the threshold are set to the minimum quantum
+% value. The result is a high-contrast, two color image.
+%
+% The format of the ThresholdImage method is:
+%
+% MagickPassFail ThresholdImage(Image *image,const double threshold)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o threshold: Define the threshold value
+%
+%
+*/
+MagickExport MagickPassFail ThresholdImage(Image *image,const double threshold)
+{
+#define ThresholdImageText "[%s] Threshold..."
+
+ long
+ y;
+
+ Quantum
+ quantum_threshold;
+
+ MagickBool
+ grayscale,
+ initialize_indexes;
+
+ /*
+ Threshold image.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ initialize_indexes=(image->storage_class == PseudoClass ? MagickFalse : MagickTrue);
+ grayscale=image->is_grayscale;
+ quantum_threshold=RoundDoubleToQuantum(threshold);
+
+ /*
+ Check if image is already in desired state.
+ */
+ if ((quantum_threshold != MaxRGB) && (image->storage_class == PseudoClass)
+ && (image->colors == 2))
+ {
+ if (IsBlackPixel(image->colormap[0]) && (IsWhitePixel(image->colormap[1])))
+ {
+ image->is_monochrome=MagickTrue;
+ image->is_grayscale=MagickTrue;
+ return MagickPass;
+ }
+ }
+
+ if (!AllocateImageColormap(image,2))
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToThresholdImage);
+
+ {
+ MagickPassFail
+ status=MagickPass;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,8) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register unsigned long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register IndexPacket
+ index;
+
+ register IndexPacket
+ *indexes;
+
+ MagickBool
+ modified;
+
+ Quantum
+ intensity;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ThresholdImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ q=GetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ indexes=AccessMutableIndexes(image);
+ modified=MagickFalse;
+
+ for (x=0; x < image->columns; x++)
+ {
+ if (grayscale)
+ intensity=q[x].red;
+ else
+ intensity=PixelIntensityToQuantum(&q[x]);
+ index=(intensity <= quantum_threshold ? 0U : 1U);
+ if ((initialize_indexes) || (index != indexes[x]))
+ {
+ modified=MagickTrue;
+ indexes[x]=index;
+ }
+ if (NotColorMatch(&image->colormap[index],&q[x]))
+ {
+ modified=MagickTrue;
+ q[x].red=q[x].green=q[x].blue=image->colormap[index].red;
+ }
+ }
+ if (modified)
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ThresholdImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,&image->exception,
+ ThresholdImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ image->is_monochrome=MagickTrue;
+ image->is_grayscale=MagickTrue;
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% U n s h a r p M a s k I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% UnsharpMaskImage() sharpens an image. We convolve the image with a
+% Gaussian operator of the given radius and standard deviation (sigma).
+% For reasonable results, radius should be larger than sigma. Use a radius
+% of 0 and UnsharpMaskImage() selects a suitable radius for you.
+%
+% The format of the UnsharpMaskImage method is:
+%
+% Image *UnsharpMaskImage(const Image *image,const double radius,
+% const double sigma,const double amount,const double threshold,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o amount: The percentage of the difference between the original and the
+% blur image that is added back into the original.
+%
+% o threshold: The threshold in pixels needed to apply the diffence amount.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+typedef struct _UnsharpMaskOptions_t
+{
+ double amount; /* Difference multiplier */
+ double threshold; /* Scaled to MaxRGB/2 */
+} UnsharpMaskOptions_t;
+
+static inline Quantum UnsharpQuantum(const Quantum original, const Quantum sharpened,
+ const UnsharpMaskOptions_t* options)
+{
+ double
+ value;
+
+ Quantum
+ quantum;
+
+ quantum=original;
+ value=original-(double) sharpened;
+ if (AbsoluteValue(value) >= options->threshold)
+ {
+ value=original+(value*options->amount);
+ quantum=RoundDoubleToQuantum(value);
+ }
+
+ return quantum;
+}
+
+static MagickPassFail
+UnsharpMaskPixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ const UnsharpMaskOptions_t
+ *options = (const UnsharpMaskOptions_t *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(source_image);
+ ARG_NOT_USED(source_indexes);
+ ARG_NOT_USED(update_image);
+ ARG_NOT_USED(update_indexes);
+ ARG_NOT_USED(exception);
+ for (i=0; i < npixels; i++)
+ {
+ update_pixels[i].red=UnsharpQuantum(source_pixels[i].red,
+ update_pixels[i].red,
+ options);
+ update_pixels[i].green=UnsharpQuantum(source_pixels[i].green,
+ update_pixels[i].green,
+ options);
+ update_pixels[i].blue=UnsharpQuantum(source_pixels[i].blue,
+ update_pixels[i].blue,
+ options);
+ update_pixels[i].opacity=UnsharpQuantum(source_pixels[i].opacity,
+ update_pixels[i].opacity,
+ options);
+ }
+ return MagickPass;
+}
+
+MagickExport Image *UnsharpMaskImage(const Image *image,const double radius,
+ const double sigma,const double amount,const double threshold,
+ ExceptionInfo *exception)
+{
+ UnsharpMaskOptions_t
+ options;
+
+ Image
+ *sharp_image;
+
+ char
+ message[MaxTextExtent];
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ sharp_image=BlurImage(image,radius,sigma,exception);
+ if (sharp_image == (Image *) NULL)
+ return((Image *) NULL);
+ options.amount=amount;
+ options.threshold=(MaxRGBFloat*threshold)/2.0;
+ FormatString(message,"[%%s] Unsharp mask: amount %g, threshold %g...",
+ amount,threshold);
+ (void) PixelIterateDualModify(UnsharpMaskPixels,NULL,
+ message,NULL,&options,
+ image->columns,image->rows,image,0,0,
+ sharp_image,
+ 0,0,exception);
+ sharp_image->is_grayscale=image->is_grayscale;
+ return(sharp_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% U n s h a r p M a s k I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% UnsharpMaskImageChannel() sharpens an image channel. We convolve the
+% image channel with a Gaussian operator of the given radius and standard
+% deviation (sigma). For reasonable results, radius should be larger than
+% sigma. Use a radius of 0 and UnsharpMaskImage() selects a suitable
+% radius for you.
+%
+% The format of the UnsharpMaskImageChannel method is:
+%
+% Image *UnsharpMaskImageChannel(const Image *image,
+% const ChannelType channel,const double radius,const double sigma,
+% const double amount,const double threshold,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: The channel to sharpen.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o amount: The percentage of the difference between the original and the
+% blur image that is added back into the original.
+%
+% o threshold: The threshold in pixels needed to apply the diffence amount.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *UnsharpMaskImageChannel(const Image *image,
+ const ChannelType channel,const double radius,const double sigma,
+ const double amount,const double threshold,
+ ExceptionInfo *exception)
+{
+ Image
+ *sharp_image;
+
+ sharp_image=UnsharpMaskImage(image,radius,sigma,amount,threshold,exception);
+ if (sharp_image != (Image *) NULL)
+ (void) ImportImageChannelsMasked(image,sharp_image,channel);
+
+ return sharp_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% W h i t e T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WhiteThresholdImage() adjusts the levels of image channels such that
+% values above a specified threshold are set to the maximum value (white)
+% while the remaining pixels are unchanged.
+%
+% The format of the WhiteThresholdImage method is:
+%
+% MagickPassFail WhiteThresholdImage(Image *image,const char *thresholds)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o thresholds: Channel thresholds which are specified as a comma delimited
+% list containing the thresholds for red, green, blue, and opacity. If
+% the list contains a percent symbol (%) then all values are treated as
+% a percentage of MaxRGB.
+%
+*/
+MagickExport MagickPassFail WhiteThresholdImage(Image *image,const char *thresholds)
+{
+ return QuantumOperatorImageMultivalue(image,ThresholdWhiteQuantumOp,thresholds);
+}
diff --git a/magick/effect.h b/magick/effect.h
new file mode 100644
index 0000000..b371a34
--- /dev/null
+++ b/magick/effect.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2003-2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Image Effect Methods.
+*/
+#ifndef _MAGICK_EFFECT_H
+#define _MAGICK_EFFECT_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport Image
+ *AdaptiveThresholdImage(const Image *,const unsigned long,const unsigned long,
+ const double,ExceptionInfo *),
+ *AddNoiseImage(const Image *,const NoiseType,ExceptionInfo *),
+ *AddNoiseImageChannel(const Image *image,const ChannelType channel,
+ const NoiseType noise_type,ExceptionInfo *exception),
+ *BlurImage(const Image *,const double,const double,ExceptionInfo *),
+ *BlurImageChannel(const Image *image,const ChannelType channel,
+ const double radius,const double sigma,ExceptionInfo *exception),
+ *ConvolveImage(const Image *,const unsigned int,const double *,
+ ExceptionInfo *),
+ *DespeckleImage(const Image *,ExceptionInfo *),
+ *EdgeImage(const Image *,const double,ExceptionInfo *),
+ *EmbossImage(const Image *,const double,const double,ExceptionInfo *),
+ *EnhanceImage(const Image *,ExceptionInfo *),
+ *GaussianBlurImage(const Image *,const double,const double,ExceptionInfo *),
+ *GaussianBlurImageChannel(const Image *image,
+ const ChannelType channel,const double radius,const double sigma,
+ ExceptionInfo *exception),
+ *MedianFilterImage(const Image *,const double,ExceptionInfo *),
+ *MotionBlurImage(const Image *,const double,const double,const double,
+ ExceptionInfo *),
+ *ReduceNoiseImage(const Image *,const double,ExceptionInfo *),
+ *ShadeImage(const Image *,const unsigned int,double,double,ExceptionInfo *),
+ *SharpenImage(const Image *,const double,const double,ExceptionInfo *),
+ *SharpenImageChannel(const Image *image,const ChannelType channel,
+ const double radius,const double sigma,ExceptionInfo *exception),
+ *SpreadImage(const Image *,const unsigned int,ExceptionInfo *),
+ *UnsharpMaskImage(const Image *,const double,const double,const double,
+ const double,ExceptionInfo *),
+ *UnsharpMaskImageChannel(const Image *image,
+ const ChannelType channel,const double radius,const double sigma,
+ const double amount,const double threshold,
+ ExceptionInfo *exception);
+
+extern MagickExport MagickPassFail
+ BlackThresholdImage(Image *image,const char *thresholds),
+ ChannelThresholdImage(Image *,const char *),
+ RandomChannelThresholdImage(Image *,const char *,const char *,
+ ExceptionInfo *exception),
+ ThresholdImage(Image *,const double),
+ WhiteThresholdImage(Image *image,const char *thresholds);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_EFFECT_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/enhance.c b/magick/enhance.c
new file mode 100644
index 0000000..a26ffe6
--- /dev/null
+++ b/magick/enhance.c
@@ -0,0 +1,1456 @@
+/*
+% Copyright (C) 2003 - 2010 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% EEEEE N N H H AAA N N CCCC EEEEE %
+% E NN N H H A A NN N C E %
+% EEE N N N HHHHH AAAAA N N N C EEE %
+% E N NN H H A A N NN C E %
+% EEEEE N N H H A A N N CCCC EEEEE %
+% %
+% %
+% GraphicsMagick Image Enhancement Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% Re-Written %
+% Bob Friesenhahn %
+% May 2008 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/color.h"
+#include "magick/enhance.h"
+#include "magick/gem.h"
+#include "magick/pixel_iterator.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+static MagickPassFail
+BuildChannelHistogramsCB(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *const_image, /* Input image */
+ const PixelPacket *pixels, /* Pixel row */
+ const IndexPacket *indexes, /* Pixel indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ /*
+ Built an image histogram in the supplied table.
+
+ Should be executed by just one thread in order to avoid contention
+ for the histogram table.
+ */
+ DoublePixelPacket
+ *histogram = (DoublePixelPacket *) mutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ histogram[ScaleQuantumToMap(pixels[i].red)].red++;
+ histogram[ScaleQuantumToMap(pixels[i].green)].green++;
+ histogram[ScaleQuantumToMap(pixels[i].blue)].blue++;
+ if (const_image->matte)
+ histogram[ScaleQuantumToMap(pixels[i].opacity)].opacity++;
+ }
+
+ return MagickPass;
+}
+
+static DoublePixelPacket *
+BuildChannelHistograms(const Image *image, ExceptionInfo *exception)
+{
+ MagickPassFail
+ status = MagickPass;
+
+ DoublePixelPacket
+ *histogram;
+
+ histogram=MagickAllocateArray(DoublePixelPacket *,(MaxMap+1),
+ sizeof(DoublePixelPacket));
+ if (histogram == (DoublePixelPacket *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ return (DoublePixelPacket *) NULL;
+ }
+
+ (void) memset(histogram,0,(MaxMap+1)*sizeof(DoublePixelPacket));
+
+ {
+ PixelIteratorOptions
+ iterator_options;
+
+ InitializePixelIteratorOptions(&iterator_options,exception);
+ iterator_options.max_threads=1;
+ status=PixelIterateMonoRead(BuildChannelHistogramsCB,
+ &iterator_options,
+ "[%s] Building histogram...",
+ histogram,NULL,
+ 0,0,image->columns,image->rows,
+ image,exception);
+ }
+
+ if (status == MagickFail)
+ MagickFreeMemory(histogram);
+
+ return histogram;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C o n t r a s t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ContrastImage() enhances the intensity differences between the lighter and
+% darker elements of the image. Set sharpen to a value other than 0 to
+% increase the image contrast otherwise the contrast is reduced.
+%
+% The format of the ContrastImage method is:
+%
+% unsigned int ContrastImage(Image *image,const unsigned int sharpen)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o sharpen: Increase or decrease image contrast.
+%
+%
+*/
+static MagickPassFail
+ContrastImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Modulate pixels contrast.
+ */
+ const double
+ sign = *((const double *) immutable_data);
+
+ static const double
+ alpha=0.5+MagickEpsilon;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ brightness,
+ hue,
+ saturation;
+
+ TransformHSL(pixels[i].red,pixels[i].green,pixels[i].blue,
+ &hue,&saturation,&brightness);
+ brightness+=
+ alpha*sign*(alpha*(sin(MagickPI*(brightness-alpha))+1.0)-brightness);
+ if (brightness > 1.0)
+ brightness=1.0;
+ if (brightness < 0.0)
+ brightness=0.0;
+ HSLTransform(hue,saturation,brightness,&pixels[i].red,
+ &pixels[i].green,&pixels[i].blue);
+ }
+
+ return MagickPass;
+}
+#define DullContrastImageText "[%s] Dulling contrast..."
+#define SharpenContrastImageText "[%s] Sharpening contrast..."
+MagickExport MagickPassFail ContrastImage(Image *image,const unsigned int sharpen)
+{
+ double
+ sign;
+
+ const char
+ *progress_message;
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ is_grayscale=image->is_grayscale;
+ sign=sharpen ? 1.0 : -1.0;
+ progress_message=sharpen ? SharpenContrastImageText : DullContrastImageText;
+ if (image->storage_class == PseudoClass)
+ {
+ (void) ContrastImagePixels(NULL,&sign,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(ContrastImagePixels,NULL,
+ progress_message,
+ NULL,&sign,0,0,image->columns,image->rows,
+ image,&image->exception);
+ }
+ image->is_grayscale=is_grayscale;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% E q u a l i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EqualizeImage() applies a histogram equalization to the image.
+%
+% The format of the EqualizeImage method is:
+%
+% unsigned int EqualizeImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+*/
+typedef struct _ApplyLevelsOptions_t
+{
+ PixelPacket
+ *map;
+
+ MagickBool
+ level_red,
+ level_green,
+ level_blue,
+ level_opacity;
+} ApplyLevels_t;
+
+static MagickPassFail
+ApplyLevels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Apply a levels transformation based on a supplied look-up table.
+ */
+ const ApplyLevels_t
+ *options = (const ApplyLevels_t *) immutable_data;
+
+ register long
+ i;
+
+ PixelPacket
+ *map=options->map;
+
+ MagickBool
+ level_red=options->level_red,
+ level_green=options->level_green,
+ level_blue=options->level_blue,
+ level_opacity=options->level_opacity;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ if (level_red)
+ pixels[i].red=map[ScaleQuantumToMap(pixels[i].red)].red;
+ if (level_green)
+ pixels[i].green=map[ScaleQuantumToMap(pixels[i].green)].green;
+ if (level_blue)
+ pixels[i].blue=map[ScaleQuantumToMap(pixels[i].blue)].blue;
+ if (level_opacity)
+ pixels[i].opacity=map[ScaleQuantumToMap(pixels[i].opacity)].opacity;
+ }
+ return MagickPass;
+}
+
+#define EqualizeImageText "Equalize... "
+MagickExport MagickPassFail EqualizeImage(Image *image)
+{
+ DoublePixelPacket
+ high,
+ *histogram,
+ intensity,
+ low,
+ *map;
+
+ ApplyLevels_t
+ levels;
+
+ register long
+ i;
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Allocate and initialize arrays.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ is_grayscale=image->is_grayscale;
+ map=MagickAllocateMemory(DoublePixelPacket *,(MaxMap+1)*sizeof(DoublePixelPacket));
+ levels.map=MagickAllocateMemory(PixelPacket *,(MaxMap+1)*sizeof(PixelPacket));
+ if ((map == (DoublePixelPacket *) NULL) ||
+ (levels.map == (PixelPacket *) NULL))
+ {
+ MagickFreeMemory(map);
+ MagickFreeMemory(levels.map);
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(OptionError,UnableToEqualizeImage));
+ }
+ /*
+ Build histogram.
+ */
+ histogram=BuildChannelHistograms(image,&image->exception);
+ if (histogram == (DoublePixelPacket *) NULL)
+ {
+ MagickFreeMemory(map);
+ MagickFreeMemory(levels.map);
+ return MagickFail;
+ }
+ /*
+ Integrate the histogram to get the equalization map.
+ */
+ (void) memset(&intensity,0,sizeof(DoublePixelPacket));
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ intensity.red+=histogram[i].red;
+ intensity.green+=histogram[i].green;
+ intensity.blue+=histogram[i].blue;
+ if (image->matte)
+ intensity.opacity+=histogram[i].opacity;
+ map[i]=intensity;
+ }
+ low=map[0];
+ high=map[MaxMap];
+ (void) memset(levels.map,0,(MaxMap+1)*sizeof(PixelPacket));
+ levels.level_red = (low.red != high.red);
+ levels.level_green = (low.green != high.green);
+ levels.level_blue = (low.blue != high.blue);
+ levels.level_opacity= (image->matte && (low.opacity != high.opacity));
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ if (levels.level_red)
+ levels.map[i].red=ScaleMapToQuantum(
+ (MaxMap*(map[i].red-low.red))/(high.red-low.red));
+ if (levels.level_green)
+ levels.map[i].green=ScaleMapToQuantum(
+ (MaxMap*(map[i].green-low.green))/(high.green-low.green));
+ if (levels.level_blue)
+ levels.map[i].blue=ScaleMapToQuantum(
+ (MaxMap*(map[i].blue-low.blue))/(high.blue-low.blue));
+ if (levels.level_opacity)
+ levels.map[i].opacity=ScaleMapToQuantum(
+ (MaxMap*(map[i].opacity-low.opacity))/(high.opacity-low.opacity));
+ }
+ MagickFreeMemory(histogram);
+ MagickFreeMemory(map);
+ /*
+ Stretch the histogram based on the map.
+ */
+ if (image->storage_class == PseudoClass)
+ {
+ (void) ApplyLevels(NULL,&levels,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(ApplyLevels,
+ NULL,
+ "[%s] Applying histogram equalization...",
+ NULL,&levels,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ MagickFreeMemory(levels.map);
+ image->is_grayscale=is_grayscale;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% G a m m a I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use GammaImage() to gamma-correct an image. The same image viewed on
+% different devices will have perceptual differences in the way the
+% image's intensities are represented on the screen. Specify individual
+% gamma levels for the red, green, and blue channels (e.g. "1.0,2.2,0.45"),
+% or adjust all three with a single gamma parameter. Values typically range
+% from 0.45 to 2.6.
+%
+% You can also reduce the influence of a particular channel with a gamma
+% value of 0.
+%
+% The format of the GammaImage method is:
+%
+% MagickPassFail GammaImage(Image *image,const char *level)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o level: Define the level of gamma correction.
+%
+%
+*/
+#if MaxMap == MaxRGB
+typedef struct _ApplyLevelsDiscrete_t
+{
+ Quantum
+ * restrict color, /* red, green, & blue */
+ * restrict red, /* red */
+ * restrict green, /* green */
+ * restrict blue, /* blue */
+ * restrict opacity; /* Opacity */
+} ApplyLevelsDiscrete_t;
+
+static MagickPassFail
+ApplyLevelsDiscrete(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket * restrict pixels, /* Pixel row */
+ IndexPacket * restrict indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Apply a levels transformation based on a supplied look-up table.
+ */
+ const ApplyLevelsDiscrete_t
+ levels = *(const ApplyLevelsDiscrete_t *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ if (levels.color)
+ {
+ pixels[i].red=levels.color[ScaleQuantumToMap(pixels[i].red)];
+ pixels[i].green=levels.color[ScaleQuantumToMap(pixels[i].green)];
+ pixels[i].blue=levels.color[ScaleQuantumToMap(pixels[i].blue)];
+ }
+ else
+ {
+ if (levels.red)
+ pixels[i].red=levels.red[ScaleQuantumToMap(pixels[i].red)];
+ if (levels.green)
+ pixels[i].green=levels.green[ScaleQuantumToMap(pixels[i].green)];
+ if (levels.blue)
+ pixels[i].blue=levels.blue[ScaleQuantumToMap(pixels[i].blue)];
+ }
+ if (levels.opacity)
+ pixels[i].opacity=levels.opacity[ScaleQuantumToMap(pixels[i].opacity)];
+ }
+
+ return MagickPass;
+}
+#endif /* if MaxMap == MaxRGB */
+
+/*
+ Gamma correct value in range of 0.0 to 1.0
+*/
+static inline double
+GammaCorrect(const double value, const double gamma)
+{
+ return pow(value,1.0/gamma);
+}
+
+#if MaxMap != MaxRGB
+typedef DoublePixelPacket GammaCorrectPixelsOptions_t;
+
+static MagickPassFail
+GammaCorrectPixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket * restrict pixels, /* Pixel row */
+ IndexPacket * restrict indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Apply a gamma transformation based on slow accurate math.
+ */
+ const GammaCorrectPixelsOptions_t
+ options = *(const GammaCorrectPixelsOptions_t *) immutable_data;
+
+ register long
+ i;
+
+ MagickBool
+ red_flag,
+ green_flag,
+ blue_flag;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ red_flag=(options.red != 1.0);
+ green_flag=(options.green != 1.0);
+ blue_flag=(options.blue != 1.0);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ value;
+
+ if (red_flag)
+ {
+ value=MaxRGBDouble*GammaCorrect(pixels[i].red/MaxRGBDouble,options.red);
+ pixels[i].red=RoundDoubleToQuantum(value);
+ }
+ if (green_flag)
+ {
+ value=MaxRGBDouble*GammaCorrect(pixels[i].green/MaxRGBDouble,options.green);
+ pixels[i].green=RoundDoubleToQuantum(value);
+ }
+ if (blue_flag)
+ {
+ value=MaxRGBDouble*GammaCorrect(pixels[i].blue/MaxRGBDouble,options.blue);
+ pixels[i].blue=RoundDoubleToQuantum(value);
+ }
+ }
+
+ return MagickPass;
+}
+#endif /* MaxMap != MaxRGB */
+
+MagickExport MagickPassFail GammaImage(Image *image,const char *level)
+{
+ double
+#if MaxMap == MaxRGB
+ gamma_color=0.0,
+#endif /* if MaxMap == MaxRGB */
+ gamma_red=1.0,
+ gamma_green=1.0,
+ gamma_blue=1.0;
+
+ long
+ count;
+
+ unsigned int
+ is_grayscale;
+
+ MagickBool
+ level_color=MagickFalse,
+ level_red=MagickFalse,
+ level_green=MagickFalse,
+ level_blue=MagickFalse,
+ unity_gamma;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (level == (char *) NULL)
+ return(MagickFail);
+ count=sscanf(level,"%lf%*[,/]%lf%*[,/]%lf",&gamma_red,&gamma_green,
+ &gamma_blue);
+ if (count == 1)
+ {
+ gamma_green=gamma_red;
+ gamma_blue=gamma_red;
+ }
+
+ unity_gamma=((gamma_red == gamma_green) && (gamma_green == gamma_blue));
+
+ if ((unity_gamma) && (gamma_red != 1.0))
+ {
+#if MaxMap == MaxRGB
+ gamma_color=gamma_red;
+#endif /* if MaxMap == MaxRGB */
+ level_color = MagickTrue;
+ }
+ else
+ {
+ level_red = ((gamma_red != 0.0) && (gamma_red != 1.0));
+ level_green = ((gamma_green != 0.0) && (gamma_green != 1.0));
+ level_blue = ((gamma_blue != 0.0) && (gamma_blue != 1.0));
+ }
+
+ is_grayscale=((image->is_grayscale) && (unity_gamma));
+
+ if (!level_color && !level_red && !level_green && !level_blue)
+ return(MagickPass);
+
+#if MaxMap == MaxRGB
+ {
+ ApplyLevelsDiscrete_t
+ levels;
+
+ register long
+ i;
+
+ /*
+ Allocate and initialize gamma maps.
+ */
+ (void) memset(&levels,0,sizeof(levels));
+ if (level_color)
+ levels.color=MagickAllocateArray(Quantum *,(MaxMap+1),sizeof(Quantum));
+ if (level_red)
+ levels.red=MagickAllocateArray(Quantum *,(MaxMap+1),sizeof(Quantum));
+ if (level_green)
+ levels.green=MagickAllocateArray(Quantum *,(MaxMap+1),sizeof(Quantum));
+ if (level_blue)
+ levels.blue=MagickAllocateArray(Quantum *,(MaxMap+1),sizeof(Quantum));
+ if ((level_color && !levels.color) ||
+ (level_red && !levels.red) ||
+ (level_green && !levels.green) ||
+ (level_blue && !levels.blue))
+ {
+ MagickFreeMemory(levels.color);
+ MagickFreeMemory(levels.red);
+ MagickFreeMemory(levels.green);
+ MagickFreeMemory(levels.blue);
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToGammaCorrectImage);
+ }
+#if (MaxMap > 256) && defined(HAVE_OPENMP)
+# pragma omp parallel for
+#endif
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ if (levels.color)
+ levels.color[i]=
+ ScaleMapToQuantum(MaxMap*GammaCorrect((double) i/MaxMap,gamma_color));
+ if (levels.red)
+ levels.red[i]=
+ ScaleMapToQuantum(MaxMap*GammaCorrect((double) i/MaxMap,gamma_red));
+ if (levels.green)
+ levels.green[i]=
+ ScaleMapToQuantum(MaxMap*GammaCorrect((double) i/MaxMap,gamma_green));
+ if (levels.blue)
+ levels.blue[i]=
+ ScaleMapToQuantum(MaxMap*GammaCorrect((double) i/MaxMap,gamma_blue));
+ }
+ /*
+ Apply gamma.
+ */
+ if (image->storage_class == PseudoClass)
+ {
+ (void) ApplyLevelsDiscrete(NULL,&levels,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(ApplyLevelsDiscrete,
+ NULL,
+ "[%s] Applying gamma correction...",
+ NULL,&levels,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ MagickFreeMemory(levels.color);
+ MagickFreeMemory(levels.red);
+ MagickFreeMemory(levels.green);
+ MagickFreeMemory(levels.blue);
+ }
+#else /* if MaxMap == MaxRGB */
+ {
+ GammaCorrectPixelsOptions_t
+ levels;
+
+ levels.red=gamma_red;
+ levels.green=gamma_green;
+ levels.blue=gamma_blue;
+ levels.opacity=OpaqueOpacity;
+
+ /*
+ Apply gamma.
+ */
+ if (image->storage_class == PseudoClass)
+ {
+ (void) GammaCorrectPixels(NULL,&levels,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(GammaCorrectPixels,
+ NULL,
+ "[%s] Applying gamma correction...",
+ NULL,&levels,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ }
+
+#endif/* if MaxMap != MaxRGB */
+
+ if (image->gamma != 0.0)
+ image->gamma*=(gamma_red+gamma_green+gamma_blue)/3.0;
+ image->is_grayscale=is_grayscale;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% L e v e l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% LevelImage() adjusts the levels of an image by scaling the colors falling
+% between specified white and black points to the full available quantum
+% range. The parameters provided represent the black, mid (gamma), and white
+% points. The black point specifies the darkest color in the image. Colors
+% darker than the black point are set to zero. Mid point specifies a gamma
+% correction to apply to the image. White point specifies the lightest color
+% in the image. Colors brighter than the white point are set to the maximum
+% quantum value.
+%
+% The format of the LevelImage method is:
+%
+% unsigned int LevelImage(Image *image,const char *level)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o levels: Specify the levels as a string of the form "black/mid/white"
+% (e.g. "10,1.0,65000) where black and white have the range of 0-MaxRGB,
+% and mid has the range 0-10.
+%
+%
+*/
+#define LevelImageText "Level... "
+MagickExport MagickPassFail LevelImage(Image *image,const char *levels)
+{
+ double
+ black_point,
+ mid_point,
+ white_point;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(levels != (char *) NULL);
+
+ {
+ /*
+ Parse levels argument.
+ */
+ char
+ buffer[MaxTextExtent];
+
+ MagickBool
+ percent = MagickFalse;
+
+ int
+ count;
+
+ register long
+ i;
+
+ const char
+ *lp;
+
+ char
+ *cp;
+
+ black_point=0.0;
+ mid_point=1.0;
+ white_point=MaxRGB;
+
+ cp=buffer;
+ lp=levels;
+ for (i=sizeof(buffer)-1 ; (*lp != 0) && (i != 0) ; lp++)
+ {
+ if (*lp == '%')
+ {
+ percent = MagickTrue;
+ }
+ else
+ {
+ *cp++=*lp;
+ i--;
+ }
+ }
+ *cp=0;
+
+ count=sscanf(buffer,"%lf%*[,/]%lf%*[,/]%lf",&black_point,&mid_point,
+ &white_point);
+ if (percent)
+ {
+ if (count > 0)
+ black_point*=MaxRGB/100.0;
+ if (count > 2)
+ white_point*=MaxRGB/100.0;
+ }
+ black_point=ConstrainToQuantum(black_point);
+ white_point=ConstrainToQuantum(white_point);
+ if (count == 1)
+ white_point=MaxRGB-black_point;
+ }
+
+ status=LevelImageChannel(image,AllChannels,black_point,mid_point,white_point);
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% L e v e l I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% LevelImageChannel() adjusts the levels of one or more channels by
+% scaling the colors falling between specified white and black points to
+% the full available quantum range. The parameters provided represent the
+% black, mid (gamma), and white points. The black point specifies the
+% darkest color in the image. Colors darker than the black point are set to
+% zero. Mid point specifies a gamma correction to apply to the image.
+% White point specifies the lightest color in the image. Colors brighter
+% than the white point are set to the maximum quantum value.
+%
+% The format of the LevelImage method is:
+%
+% MagickPassFail LevelImageChannel(Image *image,
+% const ChannelType channel,
+% const double black_point,
+% const double mid_point,
+% const double white_point)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: Identify which channel to level: Red, Cyan, Green, Magenta,
+% Blue, Yellow, Opacity, or All.
+%
+% o black_point, mid_point, white_point: Specify the levels where the black
+% and white points have the range of 0-MaxRGB, and mid has the range 0-10.
+%
+%
+*/
+MagickExport MagickPassFail LevelImageChannel(Image *image,
+ const ChannelType channel,const double black_point,const double mid_point,
+ const double white_point)
+{
+ double
+ black,
+ value,
+ white;
+
+ ApplyLevels_t
+ levels;
+
+ unsigned int
+ is_grayscale = MagickFalse;
+
+ register long
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Allocate and initialize levels map.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ levels.map=MagickAllocateArray(PixelPacket *,(MaxMap+1),sizeof(PixelPacket));
+ if (levels.map == (PixelPacket *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToLevelImage);
+ /*
+ Determine which channels to operate on.
+ */
+ levels.level_red=MagickFalse;
+ levels.level_green=MagickFalse;
+ levels.level_blue=MagickFalse;
+ levels.level_opacity=MagickFalse;
+ switch (channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ levels.level_red=MagickTrue;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ levels.level_green=MagickTrue;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ levels.level_blue=MagickTrue;
+ break;
+ case OpacityChannel:
+ case BlackChannel:
+ levels.level_opacity=MagickTrue;
+ break;
+ case AllChannels:
+ levels.level_red=MagickTrue;
+ levels.level_green=MagickTrue;
+ levels.level_blue=MagickTrue;
+ is_grayscale=image->is_grayscale;
+ break;
+ default:
+ break;
+ }
+ /*
+ Build leveling map.
+ */
+ black=ScaleQuantumToMap(black_point);
+ white=ScaleQuantumToMap(white_point);
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ if (i < black)
+ {
+ levels.map[i].red=levels.map[i].green=levels.map[i].blue=levels.map[i].opacity=0;
+ continue;
+ }
+ if (i > white)
+ {
+ levels.map[i].red=levels.map[i].green=levels.map[i].blue=levels.map[i].opacity=MaxRGB;
+ continue;
+ }
+ value=MaxRGB*(pow(((double) i-black)/(white-black),1.0/mid_point));
+ levels.map[i].red=levels.map[i].green=levels.map[i].blue=levels.map[i].opacity=
+ RoundDoubleToQuantum(value);
+ }
+ /*
+ Apply levels
+ */
+ if (image->storage_class == PseudoClass)
+ {
+ (void) ApplyLevels(NULL,&levels,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(ApplyLevels,
+ NULL,
+ "[%s] Leveling channels...",
+ NULL,&levels,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ MagickFreeMemory(levels.map);
+
+ image->is_grayscale=is_grayscale;
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M o d u l a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ModulateImage() lets you control the brightness, saturation, and hue
+% of an image. Modulate represents the brightness, saturation, and hue
+% as one parameter (e.g. 90,150,100).
+%
+% The format of the ModulateImage method is:
+%
+% unsigned int ModulateImage(Image *image,const char *modulate)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o modulate: Define the percent change in brightness, saturation, and
+% hue.
+%
+%
+*/
+typedef struct _ModulateImageParameters_t
+{
+ double
+ percent_brightness,
+ percent_hue,
+ percent_saturation;
+} ModulateImageParameters_t;
+
+static MagickPassFail
+ModulateImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Modulate image pixels according to options.
+ */
+ const ModulateImageParameters_t
+ param = *(const ModulateImageParameters_t *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ double
+ brightness,
+ hue,
+ saturation;
+
+ TransformHSL(pixels[i].red,pixels[i].green,pixels[i].blue,
+ &hue,&saturation,&brightness);
+ brightness*=(0.01+MagickEpsilon)*param.percent_brightness;
+ if (brightness > 1.0)
+ brightness=1.0;
+ saturation*=(0.01+MagickEpsilon)*param.percent_saturation;
+ if (saturation > 1.0)
+ saturation=1.0;
+
+ hue += (param.percent_hue/200.0 - 0.5);
+ while (hue < 0.0)
+ hue += 1.0;
+ while (hue > 1.0)
+ hue -= 1.0;
+ HSLTransform(hue,saturation,brightness,
+ &pixels[i].red,&pixels[i].green,&pixels[i].blue);
+ }
+
+ return MagickPass;
+}
+
+MagickExport MagickPassFail ModulateImage(Image *image,const char *modulate)
+{
+ char
+ progress_message[MaxTextExtent];
+
+ ModulateImageParameters_t
+ param;
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (modulate == (char *) NULL)
+ return(MagickFail);
+ is_grayscale=image->is_grayscale;
+ param.percent_brightness=100.0;
+ param.percent_saturation=100.0;
+ param.percent_hue=100.0;
+ (void) sscanf(modulate,"%lf%*[,/]%lf%*[,/]%lf",&param.percent_brightness,
+ &param.percent_saturation,&param.percent_hue);
+ /*
+ Ensure that adjustment values are positive so they don't need to
+ be checked in Modulate.
+ */
+ param.percent_brightness=AbsoluteValue(param.percent_brightness);
+ param.percent_saturation=AbsoluteValue(param.percent_saturation);
+ param.percent_hue=AbsoluteValue(param.percent_hue);
+
+ FormatString(progress_message,"[%%s] Modulate %g/%g/%g...",
+ param.percent_brightness,param.percent_saturation,
+ param.percent_hue);
+ TransformColorspace(image,RGBColorspace);
+ if (image->storage_class == PseudoClass)
+ {
+ (void) ModulateImagePixels(NULL,&param,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=MagickMonitorFormatted(image->colors,image->colors+1,&image->exception,
+ progress_message,image->filename);
+ status&=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(ModulateImagePixels,NULL,progress_message,
+ NULL,&param,0,0,image->columns,image->rows,
+ image,&image->exception);
+ }
+
+ image->is_grayscale=is_grayscale;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% N e g a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NegateImage negates the colors in the reference image. The
+% Grayscale option means that only grayscale values within the image are
+% negated.
+%
+% The format of the NegateImage method is:
+%
+% unsigned int NegateImage(Image *image,const unsigned int grayscale)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+static MagickPassFail
+NegateImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Negate the pixels.
+ */
+ const unsigned int
+ grayscale = *((const unsigned int *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ if (grayscale)
+ {
+ /* Process only the non-gray pixels */
+ for (i=0; i < npixels; i++)
+ {
+ if (!IsGray(pixels[i]))
+ continue;
+ pixels[i].red=(~pixels[i].red);
+ pixels[i].green=(~pixels[i].green);
+ pixels[i].blue=(~pixels[i].blue);
+ if (image->colorspace == CMYKColorspace)
+ pixels[i].opacity=(~pixels[i].opacity);
+ }
+ }
+ else
+ {
+ /* Process all pixels */
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=(~pixels[i].red);
+ pixels[i].green=(~pixels[i].green);
+ pixels[i].blue=(~pixels[i].blue);
+ if (image->colorspace == CMYKColorspace)
+ pixels[i].opacity=(~pixels[i].opacity);
+ }
+ }
+
+ return MagickPass;
+}
+
+#define NegateImageText "[%s] Negate..."
+MagickExport MagickPassFail NegateImage(Image *image,const unsigned int grayscale)
+{
+ unsigned int
+ non_gray = grayscale;
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ is_grayscale=image->is_grayscale;
+ if (image->clip_mask)
+ image->storage_class=DirectClass;
+
+ if (image->storage_class == PseudoClass)
+ {
+ (void) NegateImagePixels(NULL,&non_gray,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(NegateImagePixels,NULL,NegateImageText,
+ NULL,&non_gray,0,0,image->columns,image->rows,
+ image,&image->exception);
+ }
+
+ image->is_grayscale=is_grayscale;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% N o r m a l i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The NormalizeImage() method enhances the contrast of a color image by
+% adjusting the pixels color to span the entire range of colors available.
+%
+% The format of the NormalizeImage method is:
+%
+% unsigned int NormalizeImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+#define MaxRange(color) ScaleQuantumToMap(color)
+/*
+ Find histogram bounds based on a minimum threshold value.
+*/
+#define FindHistogramBoundsAlg(Q,threshold,low,high,histogram) \
+ { \
+ double \
+ intensity; \
+ \
+ intensity=0.0; \
+ for (low.Q=0.0; low.Q < MaxMapDouble; low.Q += 1.0) \
+ { \
+ intensity+=histogram[(long) low.Q].Q; \
+ if (intensity > threshold) \
+ break; \
+ } \
+ intensity=0.0; \
+ for (high.Q=MaxMapDouble; high.Q >= 1.0; high.Q -= 1.0) \
+ { \
+ intensity+=histogram[(long) high.Q].Q; \
+ if (intensity > threshold) \
+ break; \
+ } \
+}
+/*
+ Find histogram bounds, but with additional fallback in case
+ contrast is not reasonable.
+*/
+#define FindHistogramBounds(Q,threshold,low,high,histogram) \
+ { \
+ FindHistogramBoundsAlg(Q,threshold,low,high,histogram); \
+ if (low.red == high.red) \
+ FindHistogramBoundsAlg(Q,0.0,low,high,histogram); \
+}
+/*
+ Compute levels map entry for a quantum.
+*/
+#define ComputeHistogramMapQuantum(Q,levels,low,high) \
+{ \
+ if (i < (long) low.Q) \
+ levels.map[i].Q=0; \
+ else \
+ if (i > (long) high.Q) \
+ levels.map[i].Q=MaxRGB; \
+ else \
+ if (low.Q != high.Q) \
+ levels.map[i].Q= \
+ ScaleMapToQuantum((MaxMapDouble*(i-low.Q))/(high.Q-low.Q)); \
+}
+MagickExport MagickPassFail NormalizeImage(Image *image)
+{
+ DoublePixelPacket
+ high,
+ *histogram,
+ low;
+
+ ApplyLevels_t
+ levels;
+
+ register long
+ i;
+
+ unsigned int
+ is_grayscale;
+
+ double
+ threshold,
+ threshold_percent;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Allocate histogram and normalize map.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ is_grayscale=image->is_grayscale;
+ levels.map=MagickAllocateMemory(PixelPacket *,(MaxMap+1)*sizeof(PixelPacket));
+ if (levels.map == (PixelPacket *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToNormalizeImage);
+ /*
+ Form histogram.
+ */
+ histogram=BuildChannelHistograms(image,&image->exception);
+ if (histogram == (DoublePixelPacket *) NULL)
+ {
+ MagickFreeMemory(levels.map);
+ return MagickFail;
+ }
+ /*
+ Find the histogram boundaries by locating the 0.1 percent levels.
+ */
+ threshold_percent=0.1;
+ MagickAttributeToDouble(image,"histogram-threshold",threshold_percent);
+ threshold=(long) ((double) image->columns*image->rows*0.01*threshold_percent);
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Histogram Threshold = %g%% (%g)", threshold_percent, threshold);
+ FindHistogramBounds(red,threshold,low,high,histogram);
+ FindHistogramBounds(green,threshold,low,high,histogram);
+ FindHistogramBounds(blue,threshold,low,high,histogram);
+ high.opacity=0.0;
+ low.opacity=0.0;
+ if (image->matte)
+ FindHistogramBounds(opacity,threshold,low,high,histogram);
+
+ MagickFreeMemory(histogram);
+
+ /*
+ Stretch the histogram to create the normalized image mapping.
+ */
+ (void) memset(levels.map,0,(MaxMap+1)*sizeof(PixelPacket));
+
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ ComputeHistogramMapQuantum(red,levels,low,high);
+ ComputeHistogramMapQuantum(green,levels,low,high);
+ ComputeHistogramMapQuantum(blue,levels,low,high);
+ levels.map[i].opacity=OpaqueOpacity;
+ if (image->matte)
+ ComputeHistogramMapQuantum(opacity,levels,low,high);
+ }
+
+ /*
+ Normalize the image.
+ */
+ levels.level_red = (low.red != high.red);
+ levels.level_green = (low.green != high.green);
+ levels.level_blue = (low.blue != high.blue);
+ levels.level_opacity= (image->matte && (low.opacity != high.opacity));
+ if (image->storage_class == PseudoClass)
+ {
+ (void) ApplyLevels(NULL,&levels,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(ApplyLevels,
+ NULL,
+ "[%s] Applying histogram normalization...",
+ NULL,&levels,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+ MagickFreeMemory(levels.map);
+ image->is_grayscale=is_grayscale;
+ return(status);
+}
diff --git a/magick/enhance.h b/magick/enhance.h
new file mode 100644
index 0000000..b10b32b
--- /dev/null
+++ b/magick/enhance.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Image Enhancement Methods.
+*/
+#ifndef _MAGICK_ENHANCE_H
+#define _MAGICK_ENHANCE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport MagickPassFail
+ ContrastImage(Image *,const unsigned int),
+ EqualizeImage(Image *),
+ GammaImage(Image *,const char *),
+ LevelImage(Image *,const char *),
+ LevelImageChannel(Image *,const ChannelType,const double,const double,
+ const double),
+ ModulateImage(Image *,const char *),
+ NegateImage(Image *,const unsigned int),
+ NormalizeImage(Image *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_ENHANCE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/enum_strings.c b/magick/enum_strings.c
new file mode 100644
index 0000000..90f117f
--- /dev/null
+++ b/magick/enum_strings.c
@@ -0,0 +1,1756 @@
+/*
+% Copyright (C) 2008 - 2016 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% Interfaces to convert to and from the string form of enumeration values.
+%
+% Written by Bob Friesenhahn, June 2008.
+%
+*/
+
+#include "magick/studio.h"
+#include "magick/enum_strings.h"
+#include "magick/utility.h"
+
+/*
+ BlobMode
+*/
+MagickExport const char *BlobModeToString(BlobMode blob_mode)
+{
+ const char
+ *mode_string="?";
+
+ switch (blob_mode)
+ {
+ case UndefinedBlobMode:
+ mode_string="Undefined";
+ break;
+ case ReadBlobMode:
+ mode_string="Read";
+ break;
+ case ReadBinaryBlobMode:
+ mode_string="ReadBinary";
+ break;
+ case WriteBlobMode:
+ mode_string="Write";
+ break;
+ case WriteBinaryBlobMode:
+ mode_string="WriteBinary";
+ break;
+ }
+ return mode_string;
+}
+
+/*
+ ChannelType
+*/
+MagickExport const char *ChannelTypeToString(const ChannelType channel)
+{
+ const char
+ *channel_type="?";
+
+ switch (channel)
+ {
+ case UndefinedChannel:
+ channel_type="undefined";
+ break;
+ case RedChannel:
+ channel_type="red";
+ break;
+ case CyanChannel:
+ channel_type="cyan";
+ break;
+ case GreenChannel:
+ channel_type="green";
+ break;
+ case MagentaChannel:
+ channel_type="magenta";
+ break;
+ case BlueChannel:
+ channel_type="blue";
+ break;
+ case YellowChannel:
+ channel_type="yellow";
+ break;
+ case OpacityChannel:
+ channel_type="opacity";
+ break;
+ case BlackChannel:
+ channel_type="black";
+ break;
+ case MatteChannel:
+ channel_type="matte";
+ break;
+ case AllChannels:
+ channel_type="all";
+ break;
+ case GrayChannel:
+ channel_type="gray";
+ break;
+ }
+
+ return channel_type;
+}
+MagickExport ChannelType StringToChannelType(const char *option)
+{
+ ChannelType
+ channel;
+
+ channel=UndefinedChannel;
+ if (LocaleCompare("Red",option) == 0)
+ channel=RedChannel;
+ else if (LocaleCompare("Cyan",option) == 0)
+ channel=CyanChannel;
+ else if (LocaleCompare("Green",option) == 0)
+ channel=GreenChannel;
+ else if (LocaleCompare("Magenta",option) == 0)
+ channel=MagentaChannel;
+ else if (LocaleCompare("Blue",option) == 0)
+ channel=BlueChannel;
+ else if (LocaleCompare("Yellow",option) == 0)
+ channel=YellowChannel;
+ else if (LocaleCompare("Opacity",option) == 0)
+ channel=OpacityChannel;
+ else if (LocaleCompare("Black",option) == 0)
+ channel=BlackChannel;
+ else if (LocaleCompare("Matte",option) == 0)
+ channel=MatteChannel;
+ else if (LocaleCompare("All",option) == 0)
+ channel=AllChannels;
+ else if ((LocaleCompare("Gray",option) == 0) ||
+ (LocaleCompare("Intensity",option) == 0))
+ channel=GrayChannel;
+
+ return channel;
+}
+
+/*
+ ClassType
+*/
+MagickExport const char* ClassTypeToString(const ClassType class_type)
+{
+ const char
+ *log_class_type="?";
+
+ switch (class_type)
+ {
+ case UndefinedClass:
+ log_class_type="Undefined";
+ break;
+ case DirectClass:
+ log_class_type="DirectClass";
+ break;
+ case PseudoClass:
+ log_class_type="PseudoClass";
+ break;
+ }
+ return log_class_type;
+}
+
+/*
+ ColorspaceType
+*/
+MagickExport const char *ColorspaceTypeToString(const ColorspaceType colorspace)
+{
+ const char
+ *colorspace_type = "?";
+
+ switch (colorspace)
+ {
+ case UndefinedColorspace:
+ colorspace_type="Undefined";
+ break;
+ case CineonLogRGBColorspace:
+ colorspace_type="CineonLogRGB";
+ break;
+ case RGBColorspace:
+ colorspace_type="RGB";
+ break;
+ case GRAYColorspace:
+ colorspace_type="Gray";
+ break;
+ case Rec601LumaColorspace:
+ colorspace_type="Rec601Luma";
+ break;
+ case Rec709LumaColorspace:
+ colorspace_type="Rec709Luma";
+ break;
+ case TransparentColorspace:
+ colorspace_type="Transparent";
+ break;
+ case OHTAColorspace:
+ colorspace_type="OHTA";
+ break;
+ case XYZColorspace:
+ colorspace_type="XYZ";
+ break;
+ case Rec601YCbCrColorspace:
+ colorspace_type="Rec601YCbCr";
+ break;
+ case Rec709YCbCrColorspace:
+ colorspace_type="Rec709YCbCr";
+ break;
+ case YCCColorspace:
+ colorspace_type="PhotoCD YCC";
+ break;
+ case YIQColorspace:
+ colorspace_type="YIQ";
+ break;
+ case YPbPrColorspace:
+ colorspace_type="YPbPr";
+ break;
+ case YUVColorspace:
+ colorspace_type="YUV";
+ break;
+ case CMYKColorspace:
+ colorspace_type="CMYK";
+ break;
+ case sRGBColorspace:
+ colorspace_type="PhotoCD sRGB";
+ break;
+ case HSLColorspace:
+ colorspace_type="HSL";
+ break;
+ case HWBColorspace:
+ colorspace_type="HWB";
+ break;
+ case LABColorspace:
+ colorspace_type="LAB";
+ break;
+ }
+ return colorspace_type;
+}
+MagickExport ColorspaceType StringToColorspaceType(const char *option)
+{
+ ColorspaceType
+ colorspace;
+
+ colorspace=UndefinedColorspace;
+
+ if (LocaleCompare("cineonlog",option) == 0)
+ colorspace=CineonLogRGBColorspace;
+ else if (LocaleCompare("cmyk",option) == 0)
+ colorspace=CMYKColorspace;
+ else if (LocaleCompare("gray",option) == 0)
+ colorspace=GRAYColorspace;
+ else if (LocaleCompare("hsl",option) == 0)
+ colorspace=HSLColorspace;
+ else if (LocaleCompare("hwb",option) == 0)
+ colorspace=HWBColorspace;
+ else if (LocaleCompare("ohta",option) == 0)
+ colorspace=OHTAColorspace;
+ else if (LocaleCompare("rec601luma",option) == 0)
+ colorspace=Rec601LumaColorspace;
+ else if (LocaleCompare("rec709luma",option) == 0)
+ colorspace=Rec709LumaColorspace;
+ else if (LocaleCompare("rgb",option) == 0)
+ colorspace=RGBColorspace;
+ else if (LocaleCompare("srgb",option) == 0)
+ colorspace=sRGBColorspace;
+ else if (LocaleCompare("transparent",option) == 0)
+ colorspace=TransparentColorspace;
+ else if (LocaleCompare("xyz",option) == 0)
+ colorspace=XYZColorspace;
+ else if (LocaleCompare("ycbcr",option) == 0)
+ colorspace=YCbCrColorspace;
+ else if (LocaleCompare("rec601ycbcr",option) == 0)
+ colorspace=Rec601YCbCrColorspace;
+ else if (LocaleCompare("rec709ycbcr",option) == 0)
+ colorspace=Rec709YCbCrColorspace;
+ else if (LocaleCompare("ycc",option) == 0)
+ colorspace=YCCColorspace;
+ else if (LocaleCompare("yiq",option) == 0)
+ colorspace=YIQColorspace;
+ else if (LocaleCompare("ypbpr",option) == 0)
+ colorspace=YPbPrColorspace;
+ else if (LocaleCompare("yuv",option) == 0)
+ colorspace=YUVColorspace;
+
+ return colorspace;
+}
+
+/*
+ CompositeOperator
+*/
+MagickExport const char *CompositeOperatorToString(const CompositeOperator composite_op)
+{
+ const char
+ *composite_op_text = "?";
+
+ switch (composite_op)
+ {
+ case UndefinedCompositeOp:
+ composite_op_text = "Undefined";
+ break;
+ case OverCompositeOp:
+ composite_op_text = "Over";
+ break;
+ case InCompositeOp:
+ composite_op_text = "In";
+ break;
+ case OutCompositeOp:
+ composite_op_text = "Out";
+ break;
+ case AtopCompositeOp:
+ composite_op_text = "Atop";
+ break;
+ case XorCompositeOp:
+ composite_op_text = "Xor";
+ break;
+ case PlusCompositeOp:
+ composite_op_text = "Plus";
+ break;
+ case MinusCompositeOp:
+ composite_op_text = "Minus";
+ break;
+ case AddCompositeOp:
+ composite_op_text = "Add";
+ break;
+ case SubtractCompositeOp:
+ composite_op_text = "Subtract";
+ break;
+ case DifferenceCompositeOp:
+ composite_op_text = "Difference";
+ break;
+ case MultiplyCompositeOp:
+ composite_op_text = "Multiply";
+ break;
+ case BumpmapCompositeOp:
+ composite_op_text = "Bumpmap";
+ break;
+ case CopyCompositeOp:
+ composite_op_text = "Copy";
+ break;
+ case CopyRedCompositeOp:
+ composite_op_text = "CopyRed";
+ break;
+ case CopyGreenCompositeOp:
+ composite_op_text = "CopyGreen";
+ break;
+ case CopyBlueCompositeOp:
+ composite_op_text = "CopyBlue";
+ break;
+ case CopyOpacityCompositeOp:
+ composite_op_text = "CopyOpacity";
+ break;
+ case ClearCompositeOp:
+ composite_op_text = "Clear";
+ break;
+ case DissolveCompositeOp:
+ composite_op_text = "Dissolve";
+ break;
+ case DisplaceCompositeOp:
+ composite_op_text = "Displace";
+ break;
+ case ModulateCompositeOp:
+ composite_op_text = "Modulate";
+ break;
+ case ThresholdCompositeOp:
+ composite_op_text = "Threshold";
+ break;
+ case NoCompositeOp:
+ composite_op_text = "No";
+ break;
+ case DarkenCompositeOp:
+ composite_op_text = "Darken";
+ break;
+ case LightenCompositeOp:
+ composite_op_text = "Lighten";
+ break;
+ case HueCompositeOp:
+ composite_op_text = "Hue";
+ break;
+ case SaturateCompositeOp:
+ composite_op_text = "Saturate";
+ break;
+ case ColorizeCompositeOp:
+ composite_op_text = "Colorize";
+ break;
+ case LuminizeCompositeOp:
+ composite_op_text = "Luminize";
+ break;
+ case ScreenCompositeOp:
+ composite_op_text = "Screen";
+ break;
+ case OverlayCompositeOp:
+ composite_op_text = "Overlay";
+ break;
+ case CopyCyanCompositeOp:
+ composite_op_text = "CopyCyan";
+ break;
+ case CopyMagentaCompositeOp:
+ composite_op_text = "CopyMagenta";
+ break;
+ case CopyYellowCompositeOp:
+ composite_op_text = "CopyYellow";
+ break;
+ case CopyBlackCompositeOp:
+ composite_op_text = "CopyBlack";
+ break;
+ case DivideCompositeOp:
+ composite_op_text = "Divide";
+ break;
+ case HardLightCompositeOp:
+ composite_op_text = "HardLight";
+ break;
+ case ExclusionCompositeOp:
+ composite_op_text = "Exclusion";
+ break;
+ case ColorDodgeCompositeOp:
+ composite_op_text = "ColorDodge";
+ break;
+ case ColorBurnCompositeOp:
+ composite_op_text = "ColorBurn";
+ break;
+ case SoftLightCompositeOp:
+ composite_op_text = "SoftLight";
+ break;
+ case LinearBurnCompositeOp:
+ composite_op_text = "LinearBurn";
+ break;
+ case LinearDodgeCompositeOp:
+ composite_op_text = "LinearDodge";
+ break;
+ case LinearLightCompositeOp:
+ composite_op_text = "LinearLight";
+ break;
+ case VividLightCompositeOp:
+ composite_op_text = "VividLight";
+ break;
+ case PinLightCompositeOp:
+ composite_op_text = "PinLight";
+ break;
+ case HardMixCompositeOp:
+ composite_op_text = "HardMix";
+ break;
+ }
+
+ return composite_op_text;
+}
+MagickExport CompositeOperator StringToCompositeOperator(const char *option)
+{
+ static const struct
+ {
+ const CompositeOperator op;
+ const char *str;
+ } composite_operators[] =
+ {
+ { UndefinedCompositeOp, "Undefined" },
+ { OverCompositeOp, "Over" },
+ { OverCompositeOp, "SrcOver" },
+ { InCompositeOp , "In" },
+ { InCompositeOp , "SrcIn" },
+ { OutCompositeOp, "Out" },
+ { OutCompositeOp, "SrcOut" },
+ { AtopCompositeOp, "Atop" },
+ { AtopCompositeOp, "SrcAtop" },
+ { XorCompositeOp, "Xor" },
+ { PlusCompositeOp, "Plus" },
+ { MinusCompositeOp, "Minus" },
+ { AddCompositeOp, "Add" },
+ { SubtractCompositeOp, "Subtract" },
+ { DifferenceCompositeOp, "Difference" },
+ { MultiplyCompositeOp, "Multiply" },
+ { BumpmapCompositeOp, "Bumpmap" },
+ { CopyCompositeOp, "Copy" },
+ { CopyRedCompositeOp, "CopyRed" },
+ { CopyGreenCompositeOp, "CopyGreen" },
+ { CopyBlueCompositeOp, "CopyBlue" },
+ { CopyOpacityCompositeOp, "CopyOpacity" },
+ { ClearCompositeOp, "Clear" },
+ { DissolveCompositeOp, "Dissolve" },
+ { DisplaceCompositeOp, "Displace" },
+ { ModulateCompositeOp, "Modulate" },
+ { ThresholdCompositeOp, "Threshold" },
+ { NoCompositeOp, "No" },
+ { DarkenCompositeOp, "Darken" },
+ { LightenCompositeOp, "Lighten" },
+ { HueCompositeOp, "Hue" },
+ { SaturateCompositeOp, "Saturate" },
+ { ColorizeCompositeOp, "Colorize" },
+ { LuminizeCompositeOp, "Luminize" },
+ { ScreenCompositeOp, "Screen" },
+ { OverlayCompositeOp, "Overlay" },
+ { CopyCyanCompositeOp, "CopyCyan" },
+ { CopyMagentaCompositeOp, "CopyMagenta" },
+ { CopyYellowCompositeOp, "CopyYellow" },
+ { CopyBlackCompositeOp, "CopyBlack" },
+ { DivideCompositeOp, "Divide" },
+ { HardLightCompositeOp, "HardLight" },
+ { ExclusionCompositeOp, "Exclusion" },
+ { ColorDodgeCompositeOp, "ColorDodge" },
+ { ColorBurnCompositeOp, "ColorBurn" },
+ { SoftLightCompositeOp, "SoftLight" },
+ { LinearBurnCompositeOp, "LinearBurn" },
+ { LinearDodgeCompositeOp, "LinearDodge" },
+ { LinearLightCompositeOp, "LinearLight" },
+ { VividLightCompositeOp, "VividLight" },
+ { PinLightCompositeOp, "PinLight" },
+ { HardMixCompositeOp, "HardMix" }
+ /* Apparently missing IM operators */
+ /* ChangeMask */
+ /* DivideDst */
+ /* Dst */
+ /* DstAtop */
+ /* DstIn */
+ /* DstOut */
+ /* DstOver */
+ /* MinusDst */
+ /* PegtopLight */
+ /* Src */
+ };
+
+ CompositeOperator
+ composite_op = UndefinedCompositeOp;
+
+ unsigned int
+ index,
+ mindex;
+
+ char
+ c;
+
+ char
+ match_string[MaxTextExtent];
+
+ /*
+ Handle dash or underscore separated values like the major brand by
+ stripping them out.
+ */
+ for (index = 0, mindex =0; option[index] != 0; index++)
+ {
+ c=option[index];
+ if ((c != '_') && (c != '-'))
+ if (mindex < sizeof(match_string)-2)
+ match_string[mindex++]=c;
+ }
+ match_string[mindex]='\0';
+
+ /*
+ Find a match
+ */
+ for (index = 0;
+ index < sizeof(composite_operators)/sizeof(composite_operators[0]);
+ index++)
+ {
+ if (LocaleCompare(composite_operators[index].str, match_string) == 0)
+ {
+ composite_op = composite_operators[index].op;
+ break;
+ }
+ }
+
+ return composite_op;
+}
+
+/*
+ CompressionType
+*/
+MagickExport const char* CompressionTypeToString(const CompressionType compression_type)
+{
+ const char
+ *compression_string="?";
+
+ switch (compression_type)
+ {
+ case UndefinedCompression:
+ compression_string="Undefined";
+ break;
+ case NoCompression:
+ compression_string="No";
+ break;
+ case BZipCompression:
+ compression_string="BZip";
+ break;
+ case FaxCompression:
+ compression_string="Fax";
+ break;
+ case Group4Compression:
+ compression_string="Group4";
+ break;
+ case JPEGCompression:
+ compression_string="JPEG";
+ break;
+ case LosslessJPEGCompression:
+ compression_string="Lossless JPEG";
+ break;
+ case LZWCompression:
+ compression_string="LZW";
+ break;
+ case RLECompression:
+ compression_string="RLE";
+ break;
+ case ZipCompression:
+ compression_string="Zip";
+ break;
+ case LZMACompression:
+ compression_string="LZMA";
+ break;
+ case JPEG2000Compression:
+ compression_string="JPEG2000";
+ break;
+ case JBIG1Compression:
+ compression_string="JBIG1";
+ break;
+ case JBIG2Compression:
+ compression_string="JBIG2";
+ break;
+ }
+ return compression_string;
+}
+MagickExport CompressionType StringToCompressionType(const char *option)
+{
+ CompressionType
+ compression_type = UndefinedCompression;
+
+ if (LocaleCompare("None",option) == 0)
+ compression_type=NoCompression;
+ else if (LocaleCompare("BZip",option) == 0)
+ compression_type=BZipCompression;
+ else if (LocaleCompare("BZip2",option) == 0)
+ compression_type=BZipCompression;
+ else if (LocaleCompare("BZ2",option) == 0)
+ compression_type=BZipCompression;
+ else if (LocaleCompare("Fax",option) == 0)
+ compression_type=FaxCompression;
+ else if (LocaleCompare("Group3",option) == 0)
+ compression_type=Group3Compression;
+ else if (LocaleCompare("Group4",option) == 0)
+ compression_type=Group4Compression;
+ else if (LocaleCompare("JPEG",option) == 0)
+ compression_type=JPEGCompression;
+ else if (LocaleCompare("Lossless",option) == 0)
+ compression_type=LosslessJPEGCompression;
+ else if (LocaleCompare("LZW",option) == 0)
+ compression_type=LZWCompression;
+ else if (LocaleCompare("RLE",option) == 0)
+ compression_type=RLECompression;
+ else if (LocaleCompare("Zip",option) == 0)
+ compression_type=ZipCompression;
+ else if (LocaleCompare("GZip",option) == 0)
+ compression_type=ZipCompression;
+ else if ((LocaleCompare("LZMA",option) == 0) ||
+ (LocaleCompare("LZMA2",option) == 0))
+ compression_type=LZMACompression;
+ else if (LocaleCompare("JPEG2000",option) == 0)
+ compression_type=JPEG2000Compression;
+ else if ((LocaleCompare("JBIG",option) == 0) ||
+ (LocaleCompare("JBIG1",option) == 0))
+ compression_type=JBIG1Compression;
+ else if (LocaleCompare("JBIG2",option) == 0)
+ compression_type=JBIG2Compression;
+
+ return compression_type;
+}
+
+/*
+ ConfirmAccessMode
+*/
+MagickExport const char *ConfirmAccessModeToString(const ConfirmAccessMode access_mode)
+{
+ const char
+ *mode_string="?";
+
+ switch(access_mode)
+ {
+ case UndefinedConfirmAccessMode:
+ mode_string="Undefined";
+ break;
+ case FileExecuteConfirmAccessMode:
+ mode_string="Execute";
+ break;
+ case FileReadConfirmAccessMode:
+ mode_string="Read";
+ break;
+ case FileWriteConfirmAccessMode:
+ mode_string="Write";
+ break;
+ case URLGetFTPConfirmAccessMode:
+ mode_string="FTP Get";
+ break;
+ case URLGetFileConfirmAccessMode:
+ mode_string="FILE Get";
+ break;
+ case URLGetHTTPConfirmAccessMode:
+ mode_string="HTTP Get";
+ break;
+ }
+
+ return mode_string;
+}
+
+/*
+ EndianType
+*/
+MagickExport const char *EndianTypeToString(const EndianType endian_type)
+{
+ const char
+ *endian_string="?";
+
+ switch (endian_type)
+ {
+ case UndefinedEndian:
+ endian_string="Undefined";
+ break;
+ case LSBEndian:
+ endian_string="LSB";
+ break;
+ case MSBEndian:
+ endian_string="MSB";
+ break;
+ case NativeEndian:
+ endian_string="Native";
+ break;
+ }
+
+ return endian_string;
+}
+MagickExport EndianType StringToEndianType(const char *option)
+{
+ EndianType
+ endian_type = UndefinedEndian;
+
+ if (LocaleCompare("LSB",option) == 0)
+ endian_type=LSBEndian;
+ else if (LocaleCompare("MSB",option) == 0)
+ endian_type=MSBEndian;
+ else if (LocaleCompare("NATIVE",option) == 0)
+ {
+#if defined(WORDS_BIGENDIAN)
+ endian_type=MSBEndian;
+#else
+ endian_type=LSBEndian;
+#endif
+ }
+
+ return endian_type;
+}
+
+/*
+ FilterTypes
+*/
+MagickExport FilterTypes StringToFilterTypes(const char *option)
+{
+ FilterTypes
+ filter = UndefinedFilter;
+
+ if (LocaleCompare("Point",option) == 0)
+ filter=PointFilter;
+ else if (LocaleCompare("Box",option) == 0)
+ filter=BoxFilter;
+ else if (LocaleCompare("Triangle",option) == 0)
+ filter=TriangleFilter;
+ else if (LocaleCompare("Hermite",option) == 0)
+ filter=HermiteFilter;
+ else if (LocaleCompare("Hanning",option) == 0)
+ filter=HanningFilter;
+ else if (LocaleCompare("Hamming",option) == 0)
+ filter=HammingFilter;
+ else if (LocaleCompare("Blackman",option) == 0)
+ filter=BlackmanFilter;
+ else if (LocaleCompare("Gaussian",option) == 0)
+ filter=GaussianFilter;
+ else if (LocaleCompare("Quadratic",option) == 0)
+ filter=QuadraticFilter;
+ else if (LocaleCompare("Cubic",option) == 0)
+ filter=CubicFilter;
+ else if (LocaleCompare("Catrom",option) == 0)
+ filter=CatromFilter;
+ else if (LocaleCompare("Mitchell",option) == 0)
+ filter=MitchellFilter;
+ else if (LocaleCompare("Lanczos",option) == 0)
+ filter=LanczosFilter;
+ else if (LocaleCompare("Bessel",option) == 0)
+ filter=BesselFilter;
+ else if (LocaleCompare("Sinc",option) == 0)
+ filter=SincFilter;
+
+ return filter;
+}
+
+/*
+ GravityType
+*/
+MagickExport GravityType StringToGravityType(const char *option)
+{
+ GravityType
+ gravity_type=ForgetGravity;
+
+ if (LocaleCompare("Forget",option) == 0)
+ gravity_type=ForgetGravity;
+ else if (LocaleCompare("NorthWest",option) == 0)
+ gravity_type=NorthWestGravity;
+ else if (LocaleCompare("North",option) == 0)
+ gravity_type=NorthGravity;
+ else if (LocaleCompare("NorthEast",option) == 0)
+ gravity_type=NorthEastGravity;
+ else if (LocaleCompare("West",option) == 0)
+ gravity_type=WestGravity;
+ else if (LocaleCompare("Center",option) == 0)
+ gravity_type=CenterGravity;
+ else if (LocaleCompare("East",option) == 0)
+ gravity_type=EastGravity;
+ else if (LocaleCompare("SouthWest",option) == 0)
+ gravity_type=SouthWestGravity;
+ else if (LocaleCompare("South",option) == 0)
+ gravity_type=SouthGravity;
+ else if (LocaleCompare("SouthEast",option) == 0)
+ gravity_type=SouthEastGravity;
+ else if (LocaleCompare("Static",option) == 0)
+ gravity_type=StaticGravity;
+
+ return gravity_type;
+}
+
+/*
+ HighlightStyle
+*/
+MagickExport const char *
+HighlightStyleToString(const HighlightStyle difference_style)
+{
+ const char
+ *style="?";
+
+ switch(difference_style)
+ {
+ case UndefinedHighlightStyle:
+ style="Undefined";
+ break;
+ case AssignHighlightStyle:
+ style="Assign";
+ break;
+ case ThresholdHighlightStyle:
+ style="Threshold";
+ break;
+ case TintHighlightStyle:
+ style="Tint";
+ break;
+ case XorHighlightStyle:
+ style="XOR";
+ }
+
+ return style;
+}
+MagickExport HighlightStyle
+StringToHighlightStyle(const char *option)
+{
+ HighlightStyle
+ style=UndefinedHighlightStyle;
+
+ if (LocaleCompare("Assign",option) == 0)
+ style=AssignHighlightStyle;
+ else if (LocaleCompare("Threshold",option) == 0)
+ style=ThresholdHighlightStyle;
+ else if (LocaleCompare("Tint",option) == 0)
+ style=TintHighlightStyle;
+ else if (LocaleCompare("XOR",option) == 0)
+ style=XorHighlightStyle;
+
+ return style;
+}
+
+/*
+ ImageType
+*/
+MagickExport const char *ImageTypeToString(const ImageType image_type)
+{
+ const char
+ *p = "?";
+
+ switch (image_type)
+ {
+ case UndefinedType:
+ p="Undefined";
+ break;
+ case BilevelType:
+ p="Bilevel";
+ break;
+ case GrayscaleType:
+ p="Grayscale";
+ break;
+ case GrayscaleMatteType:
+ p="GrayscaleMatte";
+ break;
+ case PaletteType:
+ p="Palette";
+ break;
+ case PaletteMatteType:
+ p="PaletteMatte";
+ break;
+ case TrueColorType:
+ p="TrueColor";
+ break;
+ case TrueColorMatteType:
+ p="TrueColorMatte";
+ break;
+ case ColorSeparationType:
+ p="ColorSeparation";
+ break;
+ case ColorSeparationMatteType:
+ p="ColorSeparationMatte";
+ break;
+ case OptimizeType:
+ p="Optimize";
+ break;
+ }
+
+ return p;
+}
+MagickExport ImageType StringToImageType(const char *option)
+{
+ ImageType
+ image_type = UndefinedType;
+
+ if (LocaleCompare("Bilevel",option) == 0)
+ image_type=BilevelType;
+ else if (LocaleCompare("Grayscale",option) == 0)
+ image_type=GrayscaleType;
+ else if (LocaleCompare("GrayscaleMatte",option) == 0)
+ image_type=GrayscaleMatteType;
+ else if (LocaleCompare("Palette",option) == 0)
+ image_type=PaletteType;
+ else if (LocaleCompare("PaletteMatte",option) == 0)
+ image_type=PaletteMatteType;
+ else if (LocaleCompare("TrueColor",option) == 0)
+ image_type=TrueColorType;
+ else if (LocaleCompare("TrueColorMatte",option) == 0)
+ image_type=TrueColorMatteType;
+ else if (LocaleCompare("ColorSeparation",option) == 0)
+ image_type=ColorSeparationType;
+ else if (LocaleCompare("ColorSeparationMatte",option) == 0)
+ image_type=ColorSeparationMatteType;
+ else if (LocaleCompare("Optimize",option) == 0)
+ image_type=OptimizeType;
+
+ return image_type;
+}
+
+/*
+ InterlaceType
+*/
+MagickExport const char *InterlaceTypeToString(const InterlaceType interlace_type)
+{
+ const char
+ *interlace_string = "?";
+
+ switch (interlace_type)
+ {
+ case UndefinedInterlace:
+ interlace_string = "Undefined";
+ break;
+ case NoInterlace:
+ interlace_string = "No";
+ break;
+ case LineInterlace:
+ interlace_string = "Line";
+ break;
+ case PlaneInterlace:
+ interlace_string = "Plane";
+ break;
+ case PartitionInterlace:
+ interlace_string = "Partition";
+ break;
+ }
+
+ return interlace_string;
+}
+MagickExport InterlaceType StringToInterlaceType(const char *option)
+{
+ InterlaceType
+ interlace_type = UndefinedInterlace;
+
+ if (LocaleCompare("None",option) == 0)
+ interlace_type=NoInterlace;
+ else if (LocaleCompare("Line",option) == 0)
+ interlace_type=LineInterlace;
+ else if (LocaleCompare("Plane",option) == 0)
+ interlace_type=PlaneInterlace;
+ else if (LocaleCompare("Partition",option) == 0)
+ interlace_type=PartitionInterlace;
+
+ return interlace_type;
+}
+
+/*
+ MapMode
+*/
+MagickExport const char *MapModeToString(MapMode map_mode)
+{
+ char
+ *mode_string="?";
+
+ switch (map_mode)
+ {
+ case ReadMode:
+ mode_string="Read";
+ break;
+ case WriteMode:
+ mode_string="Write";
+ break;
+ case IOMode:
+ mode_string="IO";
+ break;
+ }
+ return mode_string;
+}
+
+/*
+ MetricType
+*/
+MagickExport const char *MetricTypeToString(MetricType metric)
+{
+ char
+ *metric_string="Undefined";
+
+ switch (metric)
+ {
+ case UndefinedMetric:
+ metric_string="Undefined";
+ break;
+ case MeanAbsoluteErrorMetric:
+ metric_string="MeanAbsoluteError";
+ break;
+ case MeanSquaredErrorMetric:
+ metric_string="MeanSquaredError";
+ break;
+ case PeakAbsoluteErrorMetric:
+ metric_string="PeakAbsoluteError";
+ break;
+ case PeakSignalToNoiseRatioMetric:
+ metric_string="PeakSignalToNoiseRatio";
+ break;
+ case RootMeanSquaredErrorMetric:
+ metric_string="RootMeanSquaredError";
+ break;
+ }
+
+ return metric_string;
+}
+MagickExport MetricType StringToMetricType(const char *option)
+{
+ MetricType
+ metric_type=UndefinedMetric;
+
+ if ((LocaleCompare("MAE",option) == 0) ||
+ (LocaleCompare("MeanAbsoluteError",option) == 0))
+ metric_type=MeanAbsoluteErrorMetric;
+ else if ((LocaleCompare("MSE",option) == 0) ||
+ (LocaleCompare("MeanSquaredError",option) == 0))
+ metric_type=MeanSquaredErrorMetric;
+ else if ((LocaleCompare("PAE",option) == 0) ||
+ (LocaleCompare("PeakAbsoluteError",option) == 0))
+ metric_type=PeakAbsoluteErrorMetric;
+ else if ((LocaleCompare("PSNR",option) == 0) ||
+ (LocaleCompare("PeakSignalToNoiseRatio",option) == 0))
+ metric_type=PeakSignalToNoiseRatioMetric;
+ else if ((LocaleCompare("RMSE",option) == 0) ||
+ (LocaleCompare("RootMeanSquaredError",option) == 0))
+ metric_type=RootMeanSquaredErrorMetric;
+
+ return metric_type;
+}
+
+/*
+ NoiseType
+*/
+MagickExport const char *NoiseTypeToString(NoiseType noise_type)
+{
+ char
+ *noise_string="Undefined";
+
+ switch (noise_type)
+ {
+ case UniformNoise:
+ noise_string="Uniform";
+ break;
+ case GaussianNoise:
+ noise_string="Gaussian";
+ break;
+ case MultiplicativeGaussianNoise:
+ noise_string="Multiplicative";
+ break;
+ case ImpulseNoise:
+ noise_string="Impulse";
+ break;
+ case LaplacianNoise:
+ noise_string="Laplacian";
+ break;
+ case PoissonNoise:
+ noise_string="Poisson";
+ break;
+ case RandomNoise:
+ noise_string="Random";
+ break;
+ case UndefinedNoise:
+ noise_string="Undefined";
+ break;
+ }
+
+ return noise_string;
+}
+MagickExport NoiseType StringToNoiseType(const char *option)
+{
+ NoiseType
+ noise_type=UndefinedNoise;
+
+ if (LocaleCompare("Uniform",option) == 0)
+ noise_type=UniformNoise;
+ else if (LocaleCompare("Gaussian",option) == 0)
+ noise_type=GaussianNoise;
+ else if (LocaleCompare("Multiplicative",option) == 0)
+ noise_type=MultiplicativeGaussianNoise;
+ else if (LocaleCompare("Impulse",option) == 0)
+ noise_type=ImpulseNoise;
+ else if (LocaleCompare("Laplacian",option) == 0)
+ noise_type=LaplacianNoise;
+ else if (LocaleCompare("Poisson",option) == 0)
+ noise_type=PoissonNoise;
+ else if (LocaleCompare("Random",option) == 0)
+ noise_type=RandomNoise;
+ else if (LocaleCompare("Undefined",option) == 0)
+ noise_type=UndefinedNoise;
+ return noise_type;
+}
+
+/*
+ OrientationType
+*/
+MagickExport const char *OrientationTypeToString(const OrientationType orientation_type)
+{
+ const char *
+ orientation = "?";
+
+ switch (orientation_type)
+ {
+ case UndefinedOrientation:
+ orientation = "Unknown";
+ break;
+ case TopLeftOrientation:
+ orientation = "TopLeft";
+ break;
+ case TopRightOrientation:
+ orientation = "TopRight";
+ break;
+ case BottomRightOrientation:
+ orientation = "BottomRight";
+ break;
+ case BottomLeftOrientation:
+ orientation = "BottomLeft";
+ break;
+ case LeftTopOrientation:
+ orientation = "LeftTop";
+ break;
+ case RightTopOrientation:
+ orientation = "RightTop";
+ break;
+ case RightBottomOrientation:
+ orientation = "RightBottom";
+ break;
+ case LeftBottomOrientation:
+ orientation = "LeftBottom";
+ break;
+ }
+
+ return orientation;
+}
+
+MagickExport OrientationType StringToOrientationType(const char *option)
+{
+ OrientationType
+ orientation_type = UndefinedOrientation;
+
+ if ((LocaleCompare("Unknown",option) == 0) ||
+ (LocaleCompare("undefined",option) == 0))
+ orientation_type=UndefinedOrientation;
+ else if ((LocaleCompare("TopLeft",option) == 0) ||
+ (LocaleCompare("top-left",option) == 0))
+ orientation_type=TopLeftOrientation;
+ else if ((LocaleCompare("TopRight",option) == 0) ||
+ (LocaleCompare("top-right",option) == 0))
+ orientation_type=TopRightOrientation;
+ else if ((LocaleCompare("BottomRight",option) == 0) ||
+ (LocaleCompare("bottom-right",option) == 0))
+ orientation_type=BottomRightOrientation;
+ else if ((LocaleCompare("BottomLeft",option) == 0) ||
+ (LocaleCompare("bottom-left",option) == 0))
+ orientation_type=BottomLeftOrientation;
+ else if ((LocaleCompare("LeftTop",option) == 0) ||
+ (LocaleCompare("left-top",option) == 0))
+ orientation_type=LeftTopOrientation;
+ else if ((LocaleCompare("RightTop",option) == 0) ||
+ (LocaleCompare("right-top",option) == 0))
+ orientation_type=RightTopOrientation;
+ else if ((LocaleCompare("RightBottom",option) == 0) ||
+ (LocaleCompare("right-bottom",option) == 0))
+ orientation_type=RightBottomOrientation;
+ else if ((LocaleCompare("LeftBottom",option) == 0) ||
+ (LocaleCompare("left-bottom",option) == 0))
+ orientation_type=LeftBottomOrientation;
+
+ return orientation_type;
+}
+
+/*
+ PreviewType
+*/
+MagickExport PreviewType StringToPreviewType(const char *option)
+{
+ PreviewType
+ preview_type = UndefinedPreview;
+
+ if (LocaleCompare("Rotate",option) == 0)
+ preview_type=RotatePreview;
+ else if (LocaleCompare("Shear",option) == 0)
+ preview_type=ShearPreview;
+ else if (LocaleCompare("Roll",option) == 0)
+ preview_type=RollPreview;
+ else if (LocaleCompare("Hue",option) == 0)
+ preview_type=HuePreview;
+ else if (LocaleCompare("Saturation",option) == 0)
+ preview_type=SaturationPreview;
+ else if (LocaleCompare("Brightness",option) == 0)
+ preview_type=BrightnessPreview;
+ else if (LocaleCompare("Gamma",option) == 0)
+ preview_type=GammaPreview;
+ else if (LocaleCompare("Spiff",option) == 0)
+ preview_type=SpiffPreview;
+ else if (LocaleCompare("Dull",option) == 0)
+ preview_type=DullPreview;
+ else if (LocaleCompare("Grayscale",option) == 0)
+ preview_type=GrayscalePreview;
+ else if (LocaleCompare("Quantize",option) == 0)
+ preview_type=QuantizePreview;
+ else if (LocaleCompare("Despeckle",option) == 0)
+ preview_type=DespecklePreview;
+ else if (LocaleCompare("ReduceNoise",option) == 0)
+ preview_type=ReduceNoisePreview;
+ else if (LocaleCompare("AddNoise",option) == 0)
+ preview_type=AddNoisePreview;
+ else if (LocaleCompare("Sharpen",option) == 0)
+ preview_type=SharpenPreview;
+ else if (LocaleCompare("Blur",option) == 0)
+ preview_type=BlurPreview;
+ else if (LocaleCompare("Threshold",option) == 0)
+ preview_type=ThresholdPreview;
+ else if (LocaleCompare("EdgeDetect",option) == 0)
+ preview_type=EdgeDetectPreview;
+ else if (LocaleCompare("Spread",option) == 0)
+ preview_type=SpreadPreview;
+ else if (LocaleCompare("Shade",option) == 0)
+ preview_type=ShadePreview;
+ else if (LocaleCompare("Raise",option) == 0)
+ preview_type=RaisePreview;
+ else if (LocaleCompare("Segment",option) == 0)
+ preview_type=SegmentPreview;
+ else if (LocaleCompare("Solarize",option) == 0)
+ preview_type=SolarizePreview;
+ else if (LocaleCompare("Swirl",option) == 0)
+ preview_type=SwirlPreview;
+ else if (LocaleCompare("Implode",option) == 0)
+ preview_type=ImplodePreview;
+ else if (LocaleCompare("Wave",option) == 0)
+ preview_type=WavePreview;
+ else if (LocaleCompare("OilPaint",option) == 0)
+ preview_type=OilPaintPreview;
+ else if (LocaleCompare("CharcoalDrawing",option) == 0)
+ preview_type=CharcoalDrawingPreview;
+ else if (LocaleCompare("JPEG",option) == 0)
+ preview_type=JPEGPreview;
+
+ return preview_type;
+}
+
+
+/*
+ QuantumOperator
+*/
+MagickExport QuantumOperator StringToQuantumOperator(const char *option)
+{
+ QuantumOperator
+ quantum_operator;
+
+ quantum_operator=UndefinedQuantumOp;
+ if (LocaleCompare("add",option) == 0)
+ quantum_operator=AddQuantumOp;
+ else if (LocaleCompare("and",option) == 0)
+ quantum_operator=AndQuantumOp;
+ else if ((LocaleCompare("assign",option) == 0) ||
+ (LocaleCompare("Set",option) == 0))
+ quantum_operator=AssignQuantumOp;
+ else if (LocaleCompare("divide",option) == 0)
+ quantum_operator=DivideQuantumOp;
+ else if ((LocaleCompare("lshift",option) == 0) ||
+ (LocaleCompare("LeftShift",option) == 0))
+ quantum_operator=LShiftQuantumOp;
+ else if (LocaleCompare("multiply",option) == 0)
+ quantum_operator=MultiplyQuantumOp;
+ else if (LocaleCompare("or",option) == 0)
+ quantum_operator=OrQuantumOp;
+ else if ((LocaleCompare("rshift",option) == 0) ||
+ (LocaleCompare("RightShift",option) == 0))
+ quantum_operator=RShiftQuantumOp;
+ else if (LocaleCompare("subtract",option) == 0)
+ quantum_operator=SubtractQuantumOp;
+ else if (LocaleCompare("threshold",option) == 0)
+ quantum_operator=ThresholdQuantumOp;
+ else if ((LocaleCompare("threshold-black",option) == 0) ||
+ (LocaleCompare("ThresholdBlack",option) == 0))
+ quantum_operator=ThresholdBlackQuantumOp;
+ else if ((LocaleCompare("threshold-white",option) == 0) ||
+ (LocaleCompare("ThresholdWhite",option) == 0))
+ quantum_operator=ThresholdWhiteQuantumOp;
+ else if ((LocaleCompare("threshold-black-negate",option) == 0) ||
+ (LocaleCompare("ThresholdBlackNegate",option) == 0))
+ quantum_operator=ThresholdBlackNegateQuantumOp;
+ else if ((LocaleCompare("threshold-white-negate",option) == 0) ||
+ (LocaleCompare("ThresholdWhiteNegate",option) == 0))
+ quantum_operator=ThresholdWhiteNegateQuantumOp;
+ else if (LocaleCompare("xor",option) == 0)
+ quantum_operator=XorQuantumOp;
+ else if ((LocaleCompare("noise-gaussian",option) == 0) ||
+ (LocaleCompare("GaussianNoise",option) == 0))
+ quantum_operator=NoiseGaussianQuantumOp;
+ else if ((LocaleCompare("noise-impulse",option) == 0) ||
+ (LocaleCompare("ImpulseNoise",option) == 0))
+ quantum_operator=NoiseImpulseQuantumOp;
+ else if ((LocaleCompare("noise-laplacian",option) == 0) ||
+ (LocaleCompare("LaplacianNoise",option) == 0))
+ quantum_operator=NoiseLaplacianQuantumOp;
+ else if ((LocaleCompare("noise-multiplicative",option) == 0) ||
+ (LocaleCompare("MultiplicativeNoise",option) == 0))
+ quantum_operator=NoiseMultiplicativeQuantumOp;
+ else if ((LocaleCompare("noise-poisson",option) == 0) ||
+ (LocaleCompare("PoissonNoise",option) == 0))
+ quantum_operator=NoisePoissonQuantumOp;
+ else if ((LocaleCompare("noise-random",option) == 0) ||
+ (LocaleCompare("RandomNoise",option) == 0))
+ quantum_operator=NoiseRandomQuantumOp;
+ else if ((LocaleCompare("noise-uniform",option) == 0) ||
+ (LocaleCompare("UniformNoise",option) == 0))
+ quantum_operator=NoiseUniformQuantumOp;
+ else if (LocaleCompare("negate",option) == 0)
+ quantum_operator=NegateQuantumOp;
+ else if (LocaleCompare("gamma",option) == 0)
+ quantum_operator=GammaQuantumOp;
+ else if (LocaleCompare("depth",option) == 0)
+ quantum_operator=DepthQuantumOp;
+ else if (LocaleCompare("log",option) == 0)
+ quantum_operator=LogQuantumOp;
+ else if (LocaleCompare("max",option) == 0)
+ quantum_operator=MaxQuantumOp;
+ else if (LocaleCompare("min",option) == 0)
+ quantum_operator=MinQuantumOp;
+ else if (LocaleCompare("pow",option) == 0)
+ quantum_operator=PowQuantumOp;
+
+ return quantum_operator;
+}
+MagickExport const char *QuantumOperatorToString(const QuantumOperator quantum_operator)
+{
+ const char
+ *operator_text = "?";
+
+ switch (quantum_operator)
+ {
+ case UndefinedQuantumOp:
+ operator_text="undefined";
+ break;
+ case AddQuantumOp:
+ operator_text="add";
+ break;
+ case AndQuantumOp:
+ operator_text="and";
+ break;
+ case AssignQuantumOp:
+ operator_text="assign";
+ break;
+ case DivideQuantumOp:
+ operator_text="divide";
+ break;
+ case LShiftQuantumOp:
+ operator_text="lshift";
+ break;
+ case MultiplyQuantumOp:
+ operator_text="multiply";
+ break;
+ case OrQuantumOp:
+ operator_text="or";
+ break;
+ case RShiftQuantumOp:
+ operator_text="rshift";
+ break;
+ case SubtractQuantumOp:
+ operator_text="subtract";
+ break;
+ case ThresholdQuantumOp:
+ operator_text="threshold";
+ break;
+ case ThresholdBlackQuantumOp:
+ operator_text="threshold-black";
+ break;
+ case ThresholdWhiteQuantumOp:
+ operator_text="threshold-white";
+ break;
+ case ThresholdBlackNegateQuantumOp:
+ operator_text="threshold-black-negate";
+ break;
+ case ThresholdWhiteNegateQuantumOp:
+ operator_text="threshold-white-negate";
+ break;
+ case XorQuantumOp:
+ operator_text="xor";
+ break;
+ case NoiseGaussianQuantumOp:
+ operator_text="noise-gaussian";
+ break;
+ case NoiseImpulseQuantumOp:
+ operator_text="noise-impulse";
+ break;
+ case NoiseLaplacianQuantumOp:
+ operator_text="noise-laplacian";
+ break;
+ case NoiseMultiplicativeQuantumOp:
+ operator_text="noise-multiplicative";
+ break;
+ case NoisePoissonQuantumOp:
+ operator_text="noise-poisson";
+ break;
+ case NoiseUniformQuantumOp:
+ operator_text="noise-uniform";
+ break;
+ case NegateQuantumOp:
+ operator_text="negate";
+ break;
+ case GammaQuantumOp:
+ operator_text="gamma";
+ break;
+ case DepthQuantumOp:
+ operator_text="depth";
+ break;
+ case LogQuantumOp:
+ operator_text="log";
+ break;
+ case MaxQuantumOp:
+ operator_text="max";
+ break;
+ case MinQuantumOp:
+ operator_text="min";
+ break;
+ case PowQuantumOp:
+ operator_text="pow";
+ break;
+ case NoiseRandomQuantumOp:
+ operator_text="noise-random";
+ break;
+ }
+
+ return operator_text;
+}
+
+/*
+ FilterTypes
+*/
+MagickExport const char *ResizeFilterToString(const FilterTypes filter)
+{
+ const char *
+ filter_string = "?";
+
+ switch (filter)
+ {
+ case UndefinedFilter:
+ filter_string="Undefined";
+ break;
+ case PointFilter:
+ filter_string="Point";
+ break;
+ case BoxFilter:
+ filter_string="Box";
+ break;
+ case TriangleFilter:
+ filter_string="Triangle";
+ break;
+ case HermiteFilter:
+ filter_string="Hermite";
+ break;
+ case HanningFilter:
+ filter_string="Hanning";
+ break;
+ case HammingFilter:
+ filter_string="Hamming";
+ break;
+ case BlackmanFilter:
+ filter_string="Blackman";
+ break;
+ case GaussianFilter:
+ filter_string="Gaussian";
+ break;
+ case QuadraticFilter:
+ filter_string="Quadratic";
+ break;
+ case CubicFilter:
+ filter_string="Cubi";
+ break;
+ case CatromFilter:
+ filter_string="Catrom";
+ break;
+ case MitchellFilter:
+ filter_string="Mitchell";
+ break;
+ case LanczosFilter:
+ filter_string="Lanczos";
+ break;
+ case BesselFilter:
+ filter_string="Bessel";
+ break;
+ case SincFilter:
+ filter_string="Sinc";
+ break;
+ }
+
+ return filter_string;
+}
+
+/*
+ ResolutionType
+*/
+MagickExport ResolutionType StringToResolutionType(const char *option)
+{
+ ResolutionType
+ resolution_type = UndefinedResolution;
+
+ if (LocaleCompare("PixelsPerInch",option) == 0)
+ resolution_type=PixelsPerInchResolution;
+ else if (LocaleCompare("PixelsPerCentimeter",option) == 0)
+ resolution_type=PixelsPerCentimeterResolution;
+
+ return resolution_type;
+}
+MagickExport const char *ResolutionTypeToString(const ResolutionType resolution_type)
+{
+ switch (resolution_type)
+ {
+ case UndefinedResolution: return ("Undefined");
+ case PixelsPerInchResolution: return ("PixelsPerInch");
+ case PixelsPerCentimeterResolution: return ("PixelsPerCentimeter");
+ }
+ return ("unknown");
+}
+
+/*
+ ResourceType
+*/
+MagickExport ResourceType StringToResourceType(const char *option)
+{
+ ResourceType
+ resource_type = UndefinedResource;
+
+ if (LocaleCompare("Disk",option) == 0)
+ resource_type=DiskResource;
+ else if (LocaleCompare("File",option) == 0)
+ resource_type=FileResource;
+ else if (LocaleCompare("Files",option) == 0)
+ resource_type=FileResource;
+ else if (LocaleCompare("Map",option) == 0)
+ resource_type=MapResource;
+ else if (LocaleCompare("Memory",option) == 0)
+ resource_type=MemoryResource;
+ else if (LocaleCompare("Pixels",option) == 0)
+ resource_type=PixelsResource;
+ else if (LocaleCompare("Threads",option) == 0)
+ resource_type=ThreadsResource;
+ else if (LocaleCompare("Width",option) == 0)
+ resource_type=WidthResource;
+ else if (LocaleCompare("Height",option) == 0)
+ resource_type=HeightResource;
+ return resource_type;
+}
+
+/*
+ StorageType
+*/
+MagickExport const char *StorageTypeToString(const StorageType storage_type)
+{
+ const char
+ *p = "?";
+
+ switch (storage_type)
+ {
+ case CharPixel:
+ p="CharPixel";
+ break;
+ case ShortPixel:
+ p="ShortPixel";
+ break;
+ case IntegerPixel:
+ p="IntegerPixel";
+ break;
+ case LongPixel:
+ p="LongPixel";
+ break;
+ case FloatPixel:
+ p="FloatPixel";
+ break;
+ case DoublePixel:
+ p="DoublePixel";
+ break;
+ }
+
+ return p;
+}
+
+/*
+ QuantumSampleType
+*/
+MagickExport const char *QuantumSampleTypeToString(const QuantumSampleType sample_type)
+{
+ const char
+ *p = "?";
+
+ switch (sample_type)
+ {
+ case UndefinedQuantumSampleType:
+ p="UndefinedQuantumSampleType";
+ break;
+ case UnsignedQuantumSampleType:
+ p="UnsignedQuantumSampleType";
+ break;
+ case FloatQuantumSampleType:
+ p="FloatQuantumSampleType";
+ break;
+ }
+
+ return p;
+}
+
+/*
+ StretchType
+*/
+MagickExport const char *StretchTypeToString(StretchType stretch)
+{
+ switch(stretch)
+ {
+ case NormalStretch: return("normal");
+ case UltraCondensedStretch: return("ultra-condensed");
+ case ExtraCondensedStretch: return("extra-condensed");
+ case CondensedStretch: return("condensed");
+ case SemiCondensedStretch: return("semi-condensed");
+ case SemiExpandedStretch: return("semi-expanded");
+ case ExpandedStretch: return("expanded");
+ case ExtraExpandedStretch: return("extra-expanded");
+ case UltraExpandedStretch: return("ultra-expanded");
+ case AnyStretch: return("any");
+ default: break;
+ }
+ return("unknown");
+}
+
+/*
+ StyleType
+*/
+MagickExport const char *StyleTypeToString(StyleType style)
+{
+ switch(style)
+ {
+ case NormalStyle: return("normal");
+ case ItalicStyle: return("italic");
+ case ObliqueStyle: return("oblique");
+ case AnyStyle: return("any");
+ default: break;
+ }
+ return("unknown");
+}
+
+/*
+ QuantumType
+*/
+MagickExport const char *QuantumTypeToString(const QuantumType quantum_type)
+{
+ const char
+ *p = "?";
+
+ switch (quantum_type)
+ {
+ case UndefinedQuantum:
+ p="UndefinedQuantum";
+ break;
+ case IndexQuantum:
+ p="IndexQuantum";
+ break;
+ case GrayQuantum:
+ p="GrayQuantum";
+ break;
+ case IndexAlphaQuantum:
+ p="IndexAlphaQuantum";
+ break;
+ case GrayAlphaQuantum:
+ p="GrayAlphaQuantum";
+ break;
+ case RedQuantum:
+ p="RedQuantum";
+ break;
+ case CyanQuantum:
+ p="CyanQuantum";
+ break;
+ case GreenQuantum:
+ p="GreenQuantum";
+ break;
+ case YellowQuantum:
+ p="YellowQuantum";
+ break;
+ case BlueQuantum:
+ p="BlueQuantum";
+ break;
+ case MagentaQuantum:
+ p="MagentaQuantum";
+ break;
+ case AlphaQuantum:
+ p="AlphaQuantum";
+ break;
+ case BlackQuantum:
+ p="BlackQuantum";
+ break;
+ case RGBQuantum:
+ p="RGBQuantum";
+ break;
+ case RGBAQuantum:
+ p="RGBAQuantum";
+ break;
+ case CMYKQuantum:
+ p="CMYKQuantum";
+ break;
+ case CMYKAQuantum:
+ p="CMYKAQuantum";
+ break;
+ case CIEYQuantum:
+ p="CIEYQuantum";
+ break;
+ case CIEXYZQuantum:
+ p="CIEXYZQuantum";
+ break;
+ }
+
+ return p;
+}
+
+/*
+ VirtualPixelMethod
+*/
+MagickExport VirtualPixelMethod StringToVirtualPixelMethod(const char *option)
+{
+ VirtualPixelMethod
+ virtual_pixel_method = UndefinedVirtualPixelMethod;
+
+ if (LocaleCompare("Constant",option) == 0)
+ virtual_pixel_method=ConstantVirtualPixelMethod;
+ else if (LocaleCompare("Edge",option) == 0)
+ virtual_pixel_method=EdgeVirtualPixelMethod;
+ else if (LocaleCompare("Mirror",option) == 0)
+ virtual_pixel_method=MirrorVirtualPixelMethod;
+ else if (LocaleCompare("Tile",option) == 0)
+ virtual_pixel_method=TileVirtualPixelMethod;
+
+ return virtual_pixel_method;
+}
diff --git a/magick/enum_strings.h b/magick/enum_strings.h
new file mode 100644
index 0000000..e66b7fa
--- /dev/null
+++ b/magick/enum_strings.h
@@ -0,0 +1,85 @@
+/*
+% Copyright (C) 2008 - 2014 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% Interfaces to convert to and from the string form of enumeration values.
+%
+% Written by Bob Friesenhahn, June 2008.
+%
+*/
+
+#ifndef _ENUM_STRINGS_H
+#define _ENUM_STRINGS_H
+
+#include "magick/image.h"
+#include "magick/blob.h"
+#include "magick/compare.h"
+#include "magick/confirm_access.h"
+#include "magick/constitute.h"
+#include "magick/operator.h"
+#include "magick/pixel_cache.h"
+#include "magick/render.h"
+#include "magick/resource.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+ extern MagickExport ChannelType StringToChannelType(const char *option);
+ extern MagickExport ColorspaceType StringToColorspaceType(const char *colorspace_string);
+ extern MagickExport CompositeOperator StringToCompositeOperator(const char *option);
+ extern MagickExport CompressionType StringToCompressionType(const char *option);
+ extern MagickExport EndianType StringToEndianType(const char *option);
+ extern MagickExport FilterTypes StringToFilterTypes(const char *option);
+ extern MagickExport GravityType StringToGravityType(const char *option);
+ extern MagickExport HighlightStyle StringToHighlightStyle(const char *option);
+ extern MagickExport ImageType StringToImageType(const char *option);
+ extern MagickExport InterlaceType StringToInterlaceType(const char *option);
+ extern MagickExport MetricType StringToMetricType(const char *option);
+ extern MagickExport NoiseType StringToNoiseType(const char *option);
+ extern MagickExport OrientationType StringToOrientationType(const char *option);
+ extern MagickExport PreviewType StringToPreviewType(const char *option);
+ extern MagickExport ResolutionType StringToResolutionType(const char *option);
+ extern MagickExport QuantumOperator StringToQuantumOperator(const char *option);
+ extern MagickExport ResourceType StringToResourceType(const char *option);
+ extern MagickExport VirtualPixelMethod StringToVirtualPixelMethod(const char *option); extern MagickExport const char *BlobModeToString(BlobMode blob_mode);
+ extern MagickExport const char *ChannelTypeToString(const ChannelType channel);
+ extern MagickExport const char *ClassTypeToString(const ClassType class_type);
+ extern MagickExport const char *ColorspaceTypeToString(const ColorspaceType colorspace);
+ extern MagickExport const char *CompositeOperatorToString(const CompositeOperator composite_op);
+ extern MagickExport const char *CompressionTypeToString(const CompressionType compression_type);
+ extern MagickExport const char *ConfirmAccessModeToString(const ConfirmAccessMode access_mode);
+ extern MagickExport const char *EndianTypeToString(const EndianType endian_type);
+ extern MagickExport const char *HighlightStyleToString(const HighlightStyle difference_algorithm);
+ extern MagickExport const char *ImageTypeToString(const ImageType image_type);
+ extern MagickExport const char *InterlaceTypeToString(const InterlaceType interlace_type);
+ extern MagickExport const char *MapModeToString(MapMode map_mode);
+ extern MagickExport const char *MetricTypeToString(MetricType metric);
+ extern MagickExport const char *NoiseTypeToString(NoiseType noise_type);
+ extern MagickExport const char *OrientationTypeToString(const OrientationType orientation_type);
+ extern MagickExport const char *QuantumOperatorToString(const QuantumOperator quantum_operator);
+ extern MagickExport const char *QuantumSampleTypeToString(const QuantumSampleType sample_type);
+ extern MagickExport const char *QuantumTypeToString(const QuantumType quantum_type);
+ extern MagickExport const char *ResizeFilterToString(const FilterTypes filter);
+ extern MagickExport const char *ResolutionTypeToString(const ResolutionType resolution_type);
+ extern MagickExport const char *StorageTypeToString(const StorageType storage_type);
+ extern MagickExport const char *StretchTypeToString(StretchType stretch);
+ extern MagickExport const char *StyleTypeToString(StyleType style);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ENUM_STRINGS_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/error.c b/magick/error.c
new file mode 100644
index 0000000..617e69d
--- /dev/null
+++ b/magick/error.c
@@ -0,0 +1,954 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% EEEEE RRRR RRRR OOO RRRR %
+% E R R R R O O R R %
+% EEE RRRR RRRR O O RRRR %
+% E R R R R O O R R %
+% EEEEE R R R R OOO R R %
+% %
+% %
+% GraphicsMagick Exception Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1993 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+
+/*
+ Forward declarations.
+*/
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static void
+ DefaultErrorHandler(const ExceptionType,const char *,const char *),
+ DefaultFatalErrorHandler(const ExceptionType,const char *,const char *) MAGICK_FUNC_NORETURN,
+ DefaultWarningHandler(const ExceptionType,const char *,const char *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+/*
+ Global declarations.
+*/
+static ErrorHandler
+ error_handler = DefaultErrorHandler;
+
+static FatalErrorHandler
+ fatal_error_handler = DefaultFatalErrorHandler;
+
+static WarningHandler
+ warning_handler = DefaultWarningHandler;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C a t c h E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CatchException() returns if no exceptions is found otherwise it reports
+% the exception as a warning, error, or fatal depending on the severity.
+%
+% The format of the CatchException method is:
+%
+% CatchException(const ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o exception: The exception info.
+%
+%
+*/
+MagickExport void CatchException(const ExceptionInfo *exception)
+{
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if (exception->severity == UndefinedException)
+ return;
+ errno=exception->error_number; /* Shabby work-around for parameter limits */
+ if ((exception->severity >= WarningException) &&
+ (exception->severity < ErrorException))
+ {
+ MagickWarning2(exception->severity,exception->reason,
+ exception->description);
+ return;
+ }
+ if ((exception->severity >= ErrorException) &&
+ (exception->severity < FatalErrorException))
+ {
+ MagickError2(exception->severity,exception->reason,exception->description);
+ return;
+ }
+ if (exception->severity >= FatalErrorException)
+ {
+ MagickFatalError2(exception->severity,exception->reason,
+ exception->description);
+ return;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o p y E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CopyException() copies exception data from one ExceptionInfo structure
+% to another.
+%
+% The format of the CopyException method is:
+%
+% void CopyException(ExceptionInfo *copy, const ExceptionInfo *original)
+%
+% A description of each parameter follows:
+%
+% o copy: The exception to copy to.
+%
+% o original: The exception to copy from.
+%
+*/
+MagickExport void CopyException(ExceptionInfo *copy, const ExceptionInfo *original)
+{
+ assert(copy != (ExceptionInfo *) NULL);
+ assert(copy->signature == MagickSignature);
+ assert(original != (ExceptionInfo *) NULL);
+ assert(original->signature == MagickSignature);
+ copy->severity=original->severity;
+ MagickFreeMemory(copy->reason);
+ if (original->reason)
+ copy->reason=AcquireString(original->reason);
+ MagickFreeMemory(copy->description);
+ if (original->description)
+ copy->description=AcquireString(original->description);
+ copy->error_number=original->error_number;
+ MagickFreeMemory(copy->module);
+ if (original->module)
+ copy->module=AcquireString(original->module);
+ MagickFreeMemory(copy->function);
+ if (original->function)
+ copy->function=AcquireString(original->function);
+ copy->line=original->line;
+ return;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e f a u l t E r r o r H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DefaultErrorHandler displays an error reason.
+%
+% The format of the DefaultErrorHandler method is:
+%
+% void DefaultMagickError(const ExceptionType severity,
+% const char *reason, const char *description)
+%
+% A description of each parameter follows:
+%
+% o severity: Specifies the numeric error category.
+%
+% o reason: Specifies the reason to display before terminating the
+% program.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+
+static const char *GetErrorMessageString(const int error_number)
+{
+ const char
+ *message;
+
+ message=strerror(error_number);
+ if (message == (const char *) NULL)
+ return("Error number is out of range");
+ return(message);
+}
+
+static void DefaultErrorHandler(const ExceptionType severity,const char *reason,
+ const char *description)
+{
+ if (reason == (char *) NULL)
+ return;
+
+ (void) fprintf(stderr,"%.1024s: ",GetClientName());
+ if (strstr(reason,"%s") && description)
+ {
+ /*
+ Reason contains printf specification. %s in reason string
+ is substituted with description.
+ */
+ (void) fprintf(stderr,reason,description);
+ }
+ else
+ {
+ (void) fprintf(stderr,"%.1024s",reason);
+ if (description != (char *) NULL)
+ (void) fprintf(stderr," (%.1024s)",description);
+ }
+ if ((severity != OptionError) && errno)
+ (void) fprintf(stderr," [%.1024s]",GetErrorMessageString(errno));
+ (void) fprintf(stderr,".\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e f a u l t F a t a l E r r o r H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DefaultFatalErrorHandler displays an error reason and then terminates
+% the program.
+%
+% The format of the DefaultFatalErrorHandler method is:
+%
+% void DefaultMagickFatalError(const ExceptionType severity,
+% const char *reason, const char *description)
+%
+% A description of each parameter follows:
+%
+% o severity: Specifies the numeric error category.
+%
+% o reason: Specifies the reason to display before terminating the
+% program.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+static void DefaultFatalErrorHandler(const ExceptionType severity,
+ const char *reason,const char *description)
+{
+ if (reason != (char *) NULL)
+ {
+ (void) fprintf(stderr,"%.1024s: %.1024s",GetClientName(),reason);
+ if (description != (char *) NULL)
+ (void) fprintf(stderr," (%.1024s)",description);
+ if ((severity != OptionError) && errno)
+ (void) fprintf(stderr," [%.1024s]",GetErrorMessageString(errno));
+ (void) fprintf(stderr,".\n");
+ }
+ /*
+ Release persistent resources
+ */
+ PanicDestroyMagick();
+ /*
+ Program quits
+ */
+ Exit(severity);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e f a u l t W a r n i n g H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DefaultWarningHandler displays a warning reason.
+%
+% The format of the DefaultWarningHandler method is:
+%
+% void DefaultWarningHandler(const ExceptionType warning,
+% const char *reason,const char *description)
+%
+% A description of each parameter follows:
+%
+% o warning: Specifies the numeric warning category.
+%
+% o reason: Specifies the reason to display before terminating the
+% program.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+static void DefaultWarningHandler(const ExceptionType severity,
+ const char *reason,const char *description)
+{
+ if (reason == (char *) NULL)
+ return;
+ (void) fprintf(stderr,"%.1024s: %.1024s",GetClientName(),reason);
+ if (description != (char *) NULL)
+ (void) fprintf(stderr," (%.1024s)",description);
+ if ((severity != OptionWarning) && errno)
+ (void) fprintf(stderr," [%.1024s]",GetErrorMessageString(errno));
+ (void) fprintf(stderr,".\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y E x c e p t i o n I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyExceptionInfo() deallocates memory associated with exception.
+%
+% The format of the DestroyExceptionInfo method is:
+%
+% void DestroyExceptionInfo(ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o exception: The exception info.
+%
+%
+*/
+MagickExport void DestroyExceptionInfo(ExceptionInfo *exception)
+{
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ exception->severity=UndefinedException;
+ MagickFreeMemory(exception->reason);
+ MagickFreeMemory(exception->description);
+ exception->error_number=0;
+ MagickFreeMemory(exception->module);
+ MagickFreeMemory(exception->function);
+ exception->line=0UL;
+ exception->signature=0UL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t E x c e p t i o n I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetExceptionInfo() initializes an exception to default values.
+%
+% The format of the GetExceptionInfo method is:
+%
+% GetExceptionInfo(ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o exception: The exception info.
+%
+%
+*/
+MagickExport void GetExceptionInfo(ExceptionInfo *exception)
+{
+ assert(exception != (ExceptionInfo *) NULL);
+ exception->severity=UndefinedException;
+ exception->reason=0;
+ exception->description=0;
+ exception->error_number=0;
+ exception->module=0;
+ exception->function=0;
+ exception->line=0UL;
+ exception->signature=MagickSignature;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t L o c a l e E x c e p t i o n M e s s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetLocaleExceptionMessage() converts a enumerated exception severity and tag
+% to a message in the current locale.
+%
+% The format of the GetLocaleExceptionMessage method is:
+%
+% const char *GetLocaleExceptionMessage(const ExceptionType severity,
+% const char *tag)
+%
+% A description of each parameter follows:
+%
+% o severity: the severity of the exception.
+%
+% o tag: the message tag.
+%
+%
+%
+*/
+
+static const char *ExceptionSeverityToTag(const ExceptionType severity)
+{
+ switch (severity)
+ {
+ case UndefinedException: return("Unknown/Error/");
+ case ResourceLimitWarning: return("Resource/Limit/Warning/");
+ case TypeWarning: return("Type/Warning/");
+ case OptionWarning: return("Option/Warning/");
+ case DelegateWarning: return("Delegate/Warning/");
+ case MissingDelegateWarning: return("Missing/Delegate/Warning/");
+ case CorruptImageWarning: return("Corrupt/Image/Warning/");
+ case FileOpenWarning: return("File/Open/Warning/");
+ case BlobWarning: return("Blob/Warning/");
+ case StreamWarning: return("Stream/Warning/");
+ case CacheWarning: return("Cache/Warning/");
+ case CoderWarning: return("Coder/Warning/");
+ case ModuleWarning: return("Module/Warning/");
+ case DrawWarning: return("Draw/Warning/");
+ case ImageWarning: return("Image/Warning/");
+ case WandWarning: return("Wand/Warning/");
+ case XServerWarning: return("XServer/Warning/");
+ case MonitorWarning: return("Monitor/Warning/");
+ case RegistryWarning: return("Registry/Warning/");
+ case ConfigureWarning: return("Configure/Warning/");
+ case ResourceLimitError: return("Resource/Limit/Error/");
+ case TypeError: return("Type/Error/");
+ case OptionError: return("Option/Error/");
+ case DelegateError: return("Delegate/Error/");
+ case MissingDelegateError: return("Missing/Delegate/Error/");
+ case CorruptImageError: return("Corrupt/Image/Error/");
+ case FileOpenError: return("File/Open/Error/");
+ case BlobError: return("Blob/Error/");
+ case StreamError: return("Stream/Error/");
+ case CacheError: return("Cache/Error/");
+ case CoderError: return("Coder/Error/");
+ case ModuleError: return("Module/Error/");
+ case DrawError: return("Draw/Error/");
+ case ImageError: return("Image/Error/");
+ case WandError: return("Wand/Error/");
+ case XServerError: return("XServer/Error/");
+ case MonitorError: return("Monitor/Error/");
+ case RegistryError: return("Registry/Error/");
+ case ConfigureError: return("Configure/Error/");
+ case ResourceLimitFatalError: return("Resource/Limit/FatalError/");
+ case TypeFatalError: return("Type/FatalError/");
+ case OptionFatalError: return("Option/FatalError/");
+ case DelegateFatalError: return("Delegate/FatalError/");
+ case MissingDelegateFatalError: return("Missing/Delegate/FatalError/");
+ case CorruptImageFatalError: return("Corrupt/Image/FatalError/");
+ case FileOpenFatalError: return("File/Open/FatalError/");
+ case BlobFatalError: return("Blob/FatalError/");
+ case StreamFatalError: return("Stream/FatalError/");
+ case CacheFatalError: return("Cache/FatalError/");
+ case CoderFatalError: return("Coder/FatalError/");
+ case ModuleFatalError: return("Module/FatalError/");
+ case DrawFatalError: return("Draw/FatalError/");
+ case ImageFatalError: return("Image/FatalError/");
+ case WandFatalError: return("Wand/FatalError/");
+ case XServerFatalError: return("XServer/FatalError/");
+ case MonitorFatalError: return("Monitor/FatalError/");
+ case RegistryFatalError: return("Registry/FatalError/");
+ case ConfigureFatalError: return("Configure/FatalError/");
+ default: break;
+ }
+ return("");
+}
+
+MagickExport const char *GetLocaleExceptionMessage(const ExceptionType severity,
+ const char *tag)
+{
+ char
+ message[MaxTextExtent];
+
+ const char
+ *locale_message;
+
+ /* protect against NULL lookups */
+ if (tag != (char *) NULL)
+ {
+ /* This is a hack that depends on the fact that tag can never have spaces in
+ them. If a space is found then it means we are being asked to translate a
+ message that has already been translated. A big waste of time. The reason
+ this happens is that messages are translated at the point of an exception
+ and then again when the exception is caught and processed via the default
+ error and warning handlers
+ */
+ if (strrchr(tag, ' '))
+ return tag;
+ FormatString(message,"%.1024s%.1024s",ExceptionSeverityToTag(severity),tag);
+ locale_message=GetLocaleMessage(message);
+ if (locale_message == message)
+ return(tag);
+ return(locale_message);
+ }
+ return(tag);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k E r r o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickError calls the error handler methods with an error reason.
+%
+% The format of the MagickError method is:
+%
+% void MagickError(const ExceptionType error,const char *reason,
+% const char *description)
+%
+% A description of each parameter follows:
+%
+% o exception: Specifies the numeric error category.
+%
+% o reason: Specifies the reason to display before terminating the
+% program.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+#if defined(MagickError)
+MagickExport void _MagickError(const ExceptionType error,const char *reason,
+ const char *description)
+{
+ if (error_handler != (ErrorHandler) NULL)
+ (*error_handler)(error,GetLocaleExceptionMessage(error,reason),
+ GetLocaleExceptionMessage(error,description));
+}
+#endif
+#if !defined(PREFIX_MAGICK_SYMBOLS)
+#undef MagickError
+MagickExport void MagickError(const ExceptionType error,const char *reason,
+ const char *description)
+{
+ if (error_handler != (ErrorHandler) NULL)
+ (*error_handler)(error,GetLocaleExceptionMessage(error,reason),
+ GetLocaleExceptionMessage(error,description));
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F a t a l E r r o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFatalError() calls the fatal error handler methods with an error
+% reason. The fatal error handler is not expected to return!
+%
+% The format of the MagickError method is:
+%
+% void MagickFatalError(const ExceptionType error,const char *reason,
+% const char *description)
+%
+% A description of each parameter follows:
+%
+% o exception: Specifies the numeric error category.
+%
+% o reason: Specifies the reason to display before terminating the
+% program.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+#if defined(MagickFatalError)
+MagickExport void _MagickFatalError(const ExceptionType error,const char *reason,
+ const char *description)
+{
+ if (fatal_error_handler != (ErrorHandler) NULL)
+ (*fatal_error_handler)(error,GetLocaleExceptionMessage(error,reason),
+ GetLocaleExceptionMessage(error,description));
+ errno=0;
+ abort();
+}
+#endif
+#if !defined(PREFIX_MAGICK_SYMBOLS)
+#undef MagickFatalError
+MagickExport void MagickFatalError(const ExceptionType error,const char *reason,
+ const char *description)
+{
+ if (fatal_error_handler != (ErrorHandler) NULL)
+ (*fatal_error_handler)(error,GetLocaleExceptionMessage(error,reason),
+ GetLocaleExceptionMessage(error,description));
+ errno=0;
+ abort();
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W a r n i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickWarning calls the warning handler methods with a warning
+% reason.
+%
+% The format of the MagickWarning method is:
+%
+% void MagickWarning(const ExceptionType warning,const char *reason,
+% const char *description)
+%
+% A description of each parameter follows:
+%
+% o warning: The warning severity.
+%
+% o reason: Define the reason for the warning.
+%
+% o description: Describe the warning.
+%
+%
+*/
+#if defined(MagickWarning)
+MagickExport void _MagickWarning(const ExceptionType warning,const char *reason,
+ const char *description)
+{
+ if (warning_handler != (WarningHandler) NULL)
+ (*warning_handler)(warning,GetLocaleExceptionMessage(warning,reason),
+ GetLocaleExceptionMessage(warning,description));
+}
+#endif
+#if !defined(PREFIX_MAGICK_SYMBOLS)
+#undef MagickWarning
+MagickExport void MagickWarning(const ExceptionType warning,const char *reason,
+ const char *description)
+{
+ if (warning_handler != (WarningHandler) NULL)
+ (*warning_handler)(warning,GetLocaleExceptionMessage(warning,reason),
+ GetLocaleExceptionMessage(warning,description));
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t E r r o r H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetErrorHandler() sets the error handler to the specified method
+% and returns the previous error handler.
+%
+% The format of the SetErrorHandler method is:
+%
+% ErrorHandler SetErrorHandler(ErrorHandler handler)
+%
+% A description of each parameter follows:
+%
+% o handler: The method to handle errors.
+%
+%
+*/
+MagickExport ErrorHandler SetErrorHandler(ErrorHandler handler)
+{
+ ErrorHandler
+ previous_handler;
+
+ previous_handler=error_handler;
+ error_handler=handler;
+ return(previous_handler);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t E x c e p t i o n I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetExceptionInfo() set the exception severity.
+%
+% The format of the SetExceptionInfo method is:
+%
+% SetExceptionInfo(ExceptionInfo *exception,ExceptionType severity)
+%
+% A description of each parameter follows:
+%
+% o exception: The exception info.
+%
+% o severity: The exception severity.
+%
+%
+*/
+MagickExport void SetExceptionInfo(ExceptionInfo *exception,
+ ExceptionType severity)
+{
+ assert(exception != (ExceptionInfo *) NULL);
+ exception->severity=severity;
+ errno=0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t F a t a l E r r o r H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetFatalErrorHandler() sets the fatal error handler to the specified method
+% and returns the previous fatal error handler.
+%
+% The format of the SetFatalErrorHandler method is:
+%
+% FatalErrorHandler SetFatalErrorHandler(FatalErrorHandler handler)
+%
+% A description of each parameter follows:
+%
+% o handler: The method to handle errors.
+%
+%
+*/
+MagickExport FatalErrorHandler SetFatalErrorHandler(FatalErrorHandler handler)
+{
+ FatalErrorHandler
+ previous_handler;
+
+ previous_handler=fatal_error_handler;
+ fatal_error_handler=handler;
+ return(previous_handler);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t W a r n i n g H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetWarningHandler() sets the warning handler to the specified method
+% and returns the previous warning handler.
+%
+% The format of the SetWarningHandler method is:
+%
+% ErrorHandler SetWarningHandler(ErrorHandler handler)
+%
+% A description of each parameter follows:
+%
+% o handler: The method to handle warnings.
+%
+%
+*/
+MagickExport WarningHandler SetWarningHandler(WarningHandler handler)
+{
+ WarningHandler
+ previous_handler;
+
+ previous_handler=warning_handler;
+ warning_handler=handler;
+ return(previous_handler);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T h r o w E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ThrowException() throws an exception with the specified severity code,
+% reason, and optional description.
+%
+% The format of the ThrowException method is:
+%
+% void ThrowException(ExceptionInfo *exception,
+% const ExceptionType severity,const char *reason,
+% const char *description)
+%
+% A description of each parameter follows:
+%
+% o exception: The exception.
+%
+% o severity: The severity of the exception.
+%
+% o reason: The reason of the exception.
+%
+% o description: The exception description.
+%
+%
+*/
+#if !defined(PREFIX_MAGICK_SYMBOLS)
+#undef ThrowException
+MagickExport void ThrowException(ExceptionInfo *exception,
+ const ExceptionType severity,const char *reason,const char *description)
+{
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ exception->severity=(ExceptionType) severity;
+ MagickFreeMemory(exception->reason);
+ if (reason)
+ exception->reason=
+ AcquireString(GetLocaleExceptionMessage(severity,reason));
+ MagickFreeMemory(exception->description);
+ if (description)
+ exception->description=
+ AcquireString(GetLocaleExceptionMessage(severity,description));
+ exception->error_number=errno;
+ MagickFreeMemory(exception->module);
+ MagickFreeMemory(exception->function);
+ exception->line=0UL;
+ exception->signature=0UL;
+ return;
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T h r o w L o g g e d E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ThrowLoggedException() throws an exception with the specified severity code,
+% reason, optional description, source filename, function name, and line
+% number. If logging is enabled, the exception is also logged.
+%
+% The format of the ThrowLoggedException method is:
+%
+% void ThrowLoggedException(ExceptionInfo *exception,
+% const ExceptionType severity,const char *reason,
+% const char *description,const char *module,
+% const char *function,const unsigned long line
+%
+% A description of each parameter follows:
+%
+% o exception: The exception.
+%
+% o severity: The severity of the exception.
+%
+% o reason: The reason of the exception.
+%
+% o description: The exception description.
+%
+% o filename: The source module filename.
+%
+% o function: The function name.
+%
+% o line: The line number of the source module.
+%
+%
+*/
+MagickExport void ThrowLoggedException(ExceptionInfo *exception,
+ const ExceptionType severity,const char *reason,const char *description,
+ const char *module,const char *function,const unsigned long line)
+{
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ exception->severity=(ExceptionType) severity;
+ MagickFreeMemory(exception->reason);
+ if (reason)
+ exception->reason=
+ AcquireString(GetLocaleExceptionMessage(severity,reason));
+ MagickFreeMemory(exception->description);
+ if (description)
+ exception->description=
+ AcquireString(GetLocaleExceptionMessage(severity,description));
+ exception->error_number=errno;
+ MagickFreeMemory(exception->module);
+ if (module)
+ exception->module=AcquireString(module);
+ MagickFreeMemory(exception->function);
+ if (function)
+ exception->function=AcquireString(function);
+ exception->line=line;
+ if (exception->reason)
+ {
+ if (exception->description)
+ (void) LogMagickEvent(severity,module,function,line,"%.1024s (%.1024s)",
+ exception->reason,exception->description );
+ else
+ (void) LogMagickEvent(severity,module,function,line,"%.1024s",
+ exception->reason);
+ }
+ else
+ {
+ (void) LogMagickEvent(severity,module,function,line,
+ "exception contains no reason!");
+ }
+ return;
+}
diff --git a/magick/error.h b/magick/error.h
new file mode 100644
index 0000000..c1ecc35
--- /dev/null
+++ b/magick/error.h
@@ -0,0 +1,481 @@
+/*
+ Copyright (C) 2003, 2004 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Exception Methods.
+*/
+#ifndef _MAGICK_ERROR_H
+#define _MAGICK_ERROR_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ UndefinedExceptionBase = 0,
+ ExceptionBase = 1,
+ ResourceBase = 2,
+ ResourceLimitBase = 2,
+ TypeBase = 5,
+ AnnotateBase = 5,
+ OptionBase = 10,
+ DelegateBase = 15,
+ MissingDelegateBase = 20,
+ CorruptImageBase = 25,
+ FileOpenBase = 30,
+ BlobBase = 35,
+ StreamBase = 40,
+ CacheBase = 45,
+ CoderBase = 50,
+ ModuleBase = 55,
+ DrawBase = 60,
+ RenderBase = 60,
+ ImageBase = 65,
+ WandBase = 67,
+ TemporaryFileBase = 70,
+ TransformBase = 75,
+ XServerBase = 80,
+ X11Base = 81,
+ UserBase = 82,
+ MonitorBase = 85,
+ LocaleBase = 86,
+ DeprecateBase = 87,
+ RegistryBase = 90,
+ ConfigureBase = 95
+} ExceptionBaseType;
+
+typedef enum
+{
+ UndefinedException = 0,
+ EventException = 100,
+ ExceptionEvent = EventException + ExceptionBase,
+ ResourceEvent = EventException + ResourceBase,
+ ResourceLimitEvent = EventException + ResourceLimitBase,
+ TypeEvent = EventException + TypeBase,
+ AnnotateEvent = EventException + AnnotateBase,
+ OptionEvent = EventException + OptionBase,
+ DelegateEvent = EventException + DelegateBase,
+ MissingDelegateEvent = EventException + MissingDelegateBase,
+ CorruptImageEvent = EventException + CorruptImageBase,
+ FileOpenEvent = EventException + FileOpenBase,
+ BlobEvent = EventException + BlobBase,
+ StreamEvent = EventException + StreamBase,
+ CacheEvent = EventException + CacheBase,
+ CoderEvent = EventException + CoderBase,
+ ModuleEvent = EventException + ModuleBase,
+ DrawEvent = EventException + DrawBase,
+ RenderEvent = EventException + RenderBase,
+ ImageEvent = EventException + ImageBase,
+ WandEvent = EventException + WandBase,
+ TemporaryFileEvent = EventException + TemporaryFileBase,
+ TransformEvent = EventException + TransformBase,
+ XServerEvent = EventException + XServerBase,
+ X11Event = EventException + X11Base,
+ UserEvent = EventException + UserBase,
+ MonitorEvent = EventException + MonitorBase,
+ LocaleEvent = EventException + LocaleBase,
+ DeprecateEvent = EventException + DeprecateBase,
+ RegistryEvent = EventException + RegistryBase,
+ ConfigureEvent = EventException + ConfigureBase,
+
+ WarningException = 300,
+ ExceptionWarning = WarningException + ExceptionBase,
+ ResourceWarning = WarningException + ResourceBase,
+ ResourceLimitWarning = WarningException + ResourceLimitBase,
+ TypeWarning = WarningException + TypeBase,
+ AnnotateWarning = WarningException + AnnotateBase,
+ OptionWarning = WarningException + OptionBase,
+ DelegateWarning = WarningException + DelegateBase,
+ MissingDelegateWarning = WarningException + MissingDelegateBase,
+ CorruptImageWarning = WarningException + CorruptImageBase,
+ FileOpenWarning = WarningException + FileOpenBase,
+ BlobWarning = WarningException + BlobBase,
+ StreamWarning = WarningException + StreamBase,
+ CacheWarning = WarningException + CacheBase,
+ CoderWarning = WarningException + CoderBase,
+ ModuleWarning = WarningException + ModuleBase,
+ DrawWarning = WarningException + DrawBase,
+ RenderWarning = WarningException + RenderBase,
+ ImageWarning = WarningException + ImageBase,
+ WandWarning = WarningException + WandBase,
+ TemporaryFileWarning = WarningException + TemporaryFileBase,
+ TransformWarning = WarningException + TransformBase,
+ XServerWarning = WarningException + XServerBase,
+ X11Warning = WarningException + X11Base,
+ UserWarning = WarningException + UserBase,
+ MonitorWarning = WarningException + MonitorBase,
+ LocaleWarning = WarningException + LocaleBase,
+ DeprecateWarning = WarningException + DeprecateBase,
+ RegistryWarning = WarningException + RegistryBase,
+ ConfigureWarning = WarningException + ConfigureBase,
+
+ ErrorException = 400,
+ ExceptionError = ErrorException + ExceptionBase,
+ ResourceError = ErrorException + ResourceBase,
+ ResourceLimitError = ErrorException + ResourceLimitBase,
+ TypeError = ErrorException + TypeBase,
+ AnnotateError = ErrorException + AnnotateBase,
+ OptionError = ErrorException + OptionBase,
+ DelegateError = ErrorException + DelegateBase,
+ MissingDelegateError = ErrorException + MissingDelegateBase,
+ CorruptImageError = ErrorException + CorruptImageBase,
+ FileOpenError = ErrorException + FileOpenBase,
+ BlobError = ErrorException + BlobBase,
+ StreamError = ErrorException + StreamBase,
+ CacheError = ErrorException + CacheBase,
+ CoderError = ErrorException + CoderBase,
+ ModuleError = ErrorException + ModuleBase,
+ DrawError = ErrorException + DrawBase,
+ RenderError = ErrorException + RenderBase,
+ ImageError = ErrorException + ImageBase,
+ WandError = ErrorException + WandBase,
+ TemporaryFileError = ErrorException + TemporaryFileBase,
+ TransformError = ErrorException + TransformBase,
+ XServerError = ErrorException + XServerBase,
+ X11Error = ErrorException + X11Base,
+ UserError = ErrorException + UserBase,
+ MonitorError = ErrorException + MonitorBase,
+ LocaleError = ErrorException + LocaleBase,
+ DeprecateError = ErrorException + DeprecateBase,
+ RegistryError = ErrorException + RegistryBase,
+ ConfigureError = ErrorException + ConfigureBase,
+
+ FatalErrorException = 700,
+ ExceptionFatalError = FatalErrorException + ExceptionBase,
+ ResourceFatalError = FatalErrorException + ResourceBase,
+ ResourceLimitFatalError = FatalErrorException + ResourceLimitBase,
+ TypeFatalError = FatalErrorException + TypeBase,
+ AnnotateFatalError = FatalErrorException + AnnotateBase,
+ OptionFatalError = FatalErrorException + OptionBase,
+ DelegateFatalError = FatalErrorException + DelegateBase,
+ MissingDelegateFatalError = FatalErrorException + MissingDelegateBase,
+ CorruptImageFatalError = FatalErrorException + CorruptImageBase,
+ FileOpenFatalError = FatalErrorException + FileOpenBase,
+ BlobFatalError = FatalErrorException + BlobBase,
+ StreamFatalError = FatalErrorException + StreamBase,
+ CacheFatalError = FatalErrorException + CacheBase,
+ CoderFatalError = FatalErrorException + CoderBase,
+ ModuleFatalError = FatalErrorException + ModuleBase,
+ DrawFatalError = FatalErrorException + DrawBase,
+ RenderFatalError = FatalErrorException + RenderBase,
+ ImageFatalError = FatalErrorException + ImageBase,
+ WandFatalError = FatalErrorException + WandBase,
+ TemporaryFileFatalError = FatalErrorException + TemporaryFileBase,
+ TransformFatalError = FatalErrorException + TransformBase,
+ XServerFatalError = FatalErrorException + XServerBase,
+ X11FatalError = FatalErrorException + X11Base,
+ UserFatalError = FatalErrorException + UserBase,
+ MonitorFatalError = FatalErrorException + MonitorBase,
+ LocaleFatalError = FatalErrorException + LocaleBase,
+ DeprecateFatalError = FatalErrorException + DeprecateBase,
+ RegistryFatalError = FatalErrorException + RegistryBase,
+ ConfigureFatalError = FatalErrorException + ConfigureBase
+} ExceptionType;
+
+/*
+ Typedef declarations.
+*/
+
+/*
+ ExceptionInfo is used to report exceptions to higher level routines,
+ and to the user.
+*/
+typedef struct _ExceptionInfo
+{
+ /*
+ Exception severity, reason, and description
+ */
+ ExceptionType
+ severity;
+
+ char
+ *reason,
+ *description;
+
+ /*
+ Value of errno (or equivalent) when exception was thrown.
+ */
+ int
+ error_number;
+
+ /*
+ Reporting source module, function (if available), and source
+ module line.
+ */
+ char
+ *module,
+ *function;
+
+ unsigned long
+ line;
+
+ /*
+ Structure sanity check
+ */
+ unsigned long
+ signature;
+} ExceptionInfo;
+
+/*
+ Exception typedef declarations.
+*/
+typedef void
+ (*ErrorHandler)(const ExceptionType,const char *,const char *);
+
+typedef void
+ (*FatalErrorHandler)(const ExceptionType,const char *,const char *);
+
+typedef void
+ (*WarningHandler)(const ExceptionType,const char *,const char *);
+
+/*
+ Exception declarations.
+*/
+extern MagickExport const char
+ *GetLocaleExceptionMessage(const ExceptionType,const char *),
+ *GetLocaleMessage(const char *);
+
+extern MagickExport ErrorHandler
+ SetErrorHandler(ErrorHandler);
+
+extern MagickExport FatalErrorHandler
+ SetFatalErrorHandler(FatalErrorHandler);
+
+extern MagickExport void
+ CatchException(const ExceptionInfo *),
+ CopyException(ExceptionInfo *copy, const ExceptionInfo *original),
+ DestroyExceptionInfo(ExceptionInfo *),
+ GetExceptionInfo(ExceptionInfo *),
+ MagickError(const ExceptionType,const char *,const char *),
+ MagickFatalError(const ExceptionType,const char *,const char *) MAGICK_FUNC_NORETURN,
+ MagickWarning(const ExceptionType,const char *,const char *),
+ _MagickError(const ExceptionType,const char *,const char *),
+ _MagickFatalError(const ExceptionType,const char *,const char *) MAGICK_FUNC_NORETURN,
+ _MagickWarning(const ExceptionType,const char *,const char *),
+ SetExceptionInfo(ExceptionInfo *,ExceptionType),
+ ThrowException(ExceptionInfo *,const ExceptionType,const char *,const char *),
+ ThrowLoggedException(ExceptionInfo *exception, const ExceptionType severity,
+ const char *reason,const char *description,const char *module,
+ const char *function,const unsigned long line);
+
+extern MagickExport WarningHandler
+ SetWarningHandler(WarningHandler);
+
+/*
+ Exception define definitions.
+*/
+
+#include <magick/log.h>
+
+#if defined(MAGICK_IMPLEMENTATION)
+# if defined(MAGICK_IDBASED_MESSAGES)
+
+# define MagickMsg(severity_,msg_) GetLocaleMessageFromID(MGK_##severity_##msg_)
+
+/* Severity ID translated. */
+# define ThrowException(exception_,severity_,reason_,description_) \
+ (ThrowLoggedException(exception_,severity_,GetLocaleMessageFromID(\
+ MGK_##severity_##reason_),description_,GetMagickModule()))
+
+/* No IDs translated */
+# define ThrowException2(exception_,severity_,reason_,description_) \
+ (ThrowLoggedException(exception_,severity_,reason_,description_,\
+ GetMagickModule()))
+
+/* Severity and description IDs translated */
+# define ThrowException3(exception_,severity_,reason_,description_) \
+ (ThrowLoggedException(exception_,severity_,GetLocaleMessageFromID(\
+ MGK_##severity_##reason_),GetLocaleMessageFromID(\
+ MGK_##severity_##description_),GetMagickModule()))
+
+# define MagickError(severity_,reason_,description_) \
+ (_MagickError(severity_,GetLocaleMessageFromID(MGK_##severity_##reason_),\
+ description_))
+
+# define MagickFatalError(severity_,reason_,description_) \
+ (_MagickFatalError(severity_,GetLocaleMessageFromID(\
+ MGK_##severity_##reason_),description_))
+
+# define MagickWarning(severity_,reason_,description_) \
+ (_MagickWarning(severity_,GetLocaleMessageFromID(MGK_##severity_##reason_),\
+ description_))
+
+# define MagickError2(severity_,reason_,description_) \
+ (_MagickError(severity_,reason_,description_))
+
+# define MagickFatalError2(severity_,reason_,description_) \
+ (_MagickFatalError(severity_,reason_,description_))
+
+# define MagickWarning2(severity_,reason_,description_) \
+ (_MagickWarning(severity_,reason_,description_))
+
+# define MagickError3(severity_,reason_,description_) \
+ (_MagickError(severity_,GetLocaleMessageFromID(MGK_##severity_##reason_),\
+ GetLocaleMessageFromID(MGK_##severity_##description_)))
+
+# define MagickFatalError3(severity_,reason_,description_) \
+ (_MagickFatalError(severity_,GetLocaleMessageFromID(MGK_##severity_##reason_),\
+ GetLocaleMessageFromID(MGK_##severity_##description_)))
+
+# define MagickWarning3(severity_,reason_,description_) \
+ (_MagickWarning(severity_,GetLocaleMessageFromID(MGK_##severity_##reason_),\
+ GetLocaleMessageFromID(MGK_##severity_##description_)))
+/* end #if defined(MAGICK_IDBASED_MESSAGES) */
+# else
+
+# define MagickMsg(severity_,msg_) GetLocaleExceptionMessage(severity_,#msg_)
+
+# define ThrowException(exception_,severity_,reason_,description_) \
+ (ThrowLoggedException(exception_,severity_,#reason_,description_,GetMagickModule()))
+
+# define ThrowException2(exception_,severity_,reason_,description_) \
+ (ThrowLoggedException(exception_,severity_,reason_,description_,GetMagickModule()))
+
+# define ThrowException3(exception_,severity_,reason_,description_) \
+ (ThrowLoggedException(exception_,severity_,#reason_,#description_,GetMagickModule()))
+
+# define MagickError(severity_,reason_,description_) \
+ (_MagickError(severity_,#reason_,description_))
+
+# define MagickFatalError(severity_,reason_,description_) \
+ (_MagickFatalError(severity_,#reason_,description_))
+
+# define MagickWarning(severity_,reason_,description_) \
+ (_MagickWarning(severity_,#reason_,description_))
+
+# define MagickError2(severity_,reason_,description_) \
+ (_MagickError(severity_,reason_,description_))
+
+# define MagickFatalError2(severity_,reason_,description_) \
+ (_MagickFatalError(severity_,reason_,description_))
+
+# define MagickWarning2(severity_,reason_,description_) \
+ (_MagickWarning(severity_,reason_,description_))
+
+# define MagickError3(severity_,reason_,description_) \
+ (_MagickError(severity_,#reason_,#description_))
+
+# define MagickFatalError3(severity_,reason_,description_) \
+ (_MagickFatalError(severity_,#reason_,#description_))
+
+# define MagickWarning3(severity_,reason_,description_) \
+ (_MagickWarning(severity_,#reason_,#description_))
+
+# endif
+
+#define ThrowBinaryException(severity_,reason_,description_) \
+do { \
+ if (image != (Image *) NULL) \
+ { \
+ ThrowException(&image->exception,severity_,reason_,description_); \
+ } \
+ return(MagickFail); \
+} while (0);
+
+#define ThrowBinaryException2(severity_,reason_,description_) \
+do { \
+ if (image != (Image *) NULL) \
+ { \
+ ThrowException2(&image->exception,severity_,reason_,description_); \
+ } \
+ return(MagickFail); \
+} while (0);
+
+#define ThrowBinaryException3(severity_,reason_,description_) \
+do { \
+ if (image != (Image *) NULL) \
+ { \
+ ThrowException3(&image->exception,severity_,reason_,description_); \
+ } \
+ return(MagickFail); \
+} while (0);
+
+#define ThrowImageException(code_,reason_,description_) \
+do { \
+ ThrowException(exception,code_,reason_,description_); \
+ return((Image *) NULL); \
+} while (0);
+
+#define ThrowImageException2(code_,reason_,description_) \
+do { \
+ ThrowException2(exception,code_,reason_,description_); \
+ return((Image *) NULL); \
+} while (0);
+
+#define ThrowImageException3(code_,reason_,description_) \
+do { \
+ ThrowException3(exception,code_,reason_,description_); \
+ return((Image *) NULL); \
+} while (0);
+
+#define ThrowReaderException(code_,reason_,image_) \
+do { \
+ if (code_ > exception->severity) \
+ { \
+ ThrowException(exception,code_,reason_,image_ ? (image_)->filename : 0); \
+ } \
+ if (image_) \
+ { \
+ CloseBlob(image_); \
+ DestroyImageList(image_); \
+ } \
+ return((Image *) NULL); \
+} while (0);
+
+#define ThrowWriterException(code_,reason_,image_) \
+do { \
+ assert(image_ != (Image *) NULL); \
+ ThrowException(&(image_)->exception,code_,reason_,(image_)->filename); \
+ if (image_info->adjoin) \
+ while ((image_)->previous != (Image *) NULL) \
+ (image_)=(image_)->previous; \
+ CloseBlob(image_); \
+ return(MagickFail); \
+} while (0);
+
+#define ThrowWriterException2(code_,reason_,image_) \
+do { \
+ assert(image_ != (Image *) NULL); \
+ ThrowException2(&(image_)->exception,code_,reason_,(image_)->filename); \
+ if (image_info->adjoin) \
+ while ((image_)->previous != (Image *) NULL) \
+ (image_)=(image_)->previous; \
+ CloseBlob(image_); \
+ return(MagickFail); \
+} while (0);
+
+#define ThrowWriterException3(code_,reason_,image_) \
+do { \
+ assert(image_ != (Image *) NULL); \
+ ThrowException3(&(image_)->exception,code_,reason_,(image_)->filename); \
+ if (image_info->adjoin) \
+ while ((image_)->previous != (Image *) NULL) \
+ (image_)=(image_)->previous; \
+ CloseBlob(image_); \
+ return(MagickFail); \
+} while (0);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* !defined(_MAGICK_ERROR_H) */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/export.c b/magick/export.c
new file mode 100644
index 0000000..5247bc3
--- /dev/null
+++ b/magick/export.c
@@ -0,0 +1,3333 @@
+/*
+ Copyright (C) 2003 - 2015 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Methods to export image pixels to common representations
+
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/bit_stream.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/floats.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+
+/*
+ Type definitions
+*/
+
+/*
+ Forward declarations.
+*/
+
+
+/*
+ Macros
+*/
+
+#if defined(WORDS_BIGENDIAN)
+# define MyEndianType MSBEndian
+#else
+# define MyEndianType LSBEndian
+#endif
+
+#if 0
+#define ExportModulo8Quantum(q,quantum_size,quantum) \
+ { \
+ register unsigned int \
+ shift=quantum_size; \
+ \
+ do \
+ { \
+ shift -= 8U; \
+ *q++=(unsigned char) \
+ (((unsigned int) quantum) >> shift); \
+ } while( shift > 0U); \
+ }
+#endif
+#define ExportUInt8Quantum(q,quantum) \
+ { \
+ *q++=(quantum); \
+ }
+#define ExportUInt16Quantum(endian,q,quantum) \
+ { \
+ register unsigned int value_ = (quantum); \
+ if (LSBEndian != endian) \
+ { \
+ *q++=(unsigned char) (value_ >> 8); \
+ *q++=(unsigned char) value_; \
+ } \
+ else \
+ { \
+ *q++=(unsigned char) value_; \
+ *q++=(unsigned char) (value_ >> 8); \
+ } \
+}
+#define ExportUInt32Quantum(endian,q,quantum) \
+ { \
+ register unsigned int value_ = (quantum); \
+ if (LSBEndian != endian) \
+ { \
+ *q++=(unsigned char) (value_ >> 24); \
+ *q++=(unsigned char) (value_ >> 16); \
+ *q++=(unsigned char) (value_ >> 8); \
+ *q++=(unsigned char) value_; \
+ } \
+ else \
+ { \
+ *q++=(unsigned char) value_; \
+ *q++=(unsigned char) (value_ >> 8); \
+ *q++=(unsigned char) (value_ >> 16); \
+ *q++=(unsigned char) (value_ >> 24); \
+ } \
+ }
+/*
+ Export a 32-bit unsigned quantum into a 64-bit storage size. This
+ approach is used since 64-bits is not supported internally and some
+ CPUs may perform poorly if the quantum is a 64-bit type.
+*/
+#define ExportUInt64Quantum(endian,q,quantum) \
+ { \
+ register unsigned int value_ = (quantum); \
+ if (LSBEndian != endian) \
+ { \
+ *q++=(unsigned char) (value_ >> 24); \
+ *q++=(unsigned char) (value_ >> 16); \
+ *q++=(unsigned char) (value_ >> 8); \
+ *q++=(unsigned char) value_; \
+ *q++=(unsigned char) (value_ >> 24); \
+ *q++=(unsigned char) (value_ >> 16); \
+ *q++=(unsigned char) (value_ >> 8); \
+ *q++=(unsigned char) value_; \
+ } \
+ else \
+ { \
+ *q++=(unsigned char) value_; \
+ *q++=(unsigned char) (value_ >> 8); \
+ *q++=(unsigned char) (value_ >> 16); \
+ *q++=(unsigned char) (value_ >> 24); \
+ *q++=(unsigned char) value_; \
+ *q++=(unsigned char) (value_ >> 8); \
+ *q++=(unsigned char) (value_ >> 16); \
+ *q++=(unsigned char) (value_ >> 24); \
+ } \
+ }
+#define ExportFloat16Quantum(endian,q,quantum) \
+ { \
+ float float_val; \
+ unsigned char c[2]; \
+ \
+ float_val=(float) (quantum); \
+ (void) _Gm_convert_fp32_to_fp16(&float_val, \
+ (fp_16bits *)c, \
+ RANGE_LIMITED); \
+ if (MyEndianType == endian) \
+ { \
+ *q++=c[0]; \
+ *q++=c[1]; \
+ } \
+ else \
+ { \
+ *q++=c[1]; \
+ *q++=c[0]; \
+ } \
+ }
+#define ExportFloat24Quantum(endian,q,quantum) \
+ { \
+ float float_val; \
+ unsigned char c[3]; \
+ \
+ float_val=(float) (quantum); \
+ (void) _Gm_convert_fp32_to_fp24(&float_val, \
+ (fp_24bits *)c, \
+ RANGE_LIMITED); \
+ if (MyEndianType == endian) \
+ { \
+ *q++=c[0]; \
+ *q++=c[1]; \
+ *q++=c[2]; \
+ } \
+ else \
+ { \
+ *q++=c[2]; \
+ *q++=c[1]; \
+ *q++=c[0]; \
+ } \
+ }
+#define ExportFloat32Quantum(endian,q,quantum) \
+ { \
+ if (MyEndianType == endian) \
+ { \
+ *((float *) q) = (float) (quantum); \
+ q += sizeof(float); \
+ } \
+ else \
+ { \
+ union \
+ { \
+ float f; \
+ unsigned char c[4]; \
+ } fu_; \
+ \
+ fu_.f=(float) (quantum); \
+ *q++=fu_.c[3]; \
+ *q++=fu_.c[2]; \
+ *q++=fu_.c[1]; \
+ *q++=fu_.c[0]; \
+ } \
+ }
+#define ExportFloat64Quantum(endian,q,quantum) \
+ { \
+ if (MyEndianType == endian) \
+ { \
+ *((double *) q) = ((double) quantum); \
+ q += sizeof(double); \
+ } \
+ else \
+ { \
+ union \
+ { \
+ double d; \
+ unsigned char c[8]; \
+ } du_; \
+ \
+ du_.d = (double) (quantum); \
+ *q++=du_.c[7]; \
+ *q++=du_.c[6]; \
+ *q++=du_.c[5]; \
+ *q++=du_.c[4]; \
+ *q++=du_.c[3]; \
+ *q++=du_.c[2]; \
+ *q++=du_.c[1]; \
+ *q++=du_.c[0]; \
+ } \
+ }
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x p o r t I m a g e P i x e l A r e a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ExportImagePixelArea() transfers one or more pixel components from the
+% default image pixel cache view to a user supplied buffer. By default,
+% values are written in network (big-endian) byte/bit order. By setting
+% the 'endian' member of ExportPixelAreaOptions, 16, 32 and 64-bit values
+% may be output as little (LSBEndian), big (MSBEndian), or host native
+% (NativeEndian) endian values. This function is quite powerful in that
+% besides common native CPU type sizes, it can support any integer bit
+% depth from 1 to 32 (e.g. 13), 64-bits as well as 32 and 64-bit float.
+%
+%
+% MagickPass is returned if the pixels are successfully transferred,
+% otherwise MagickFail.
+%
+% The format of the ExportImagePixelArea method is:
+%
+% MagickPassFail ExportImagePixelArea(const Image *image,
+% const QuantumType quantum_type,
+% unsigned int quantum_size,
+% unsigned char *destination,
+% const ExportPixelAreaOptions *options,
+% ExportPixelAreaInfo *export_info)
+%
+% A description of each parameter follows:
+%
+% o status: Returns MagickPass if the pixels are successfully transferred,
+% otherwise MagickFail.
+%
+% o image: The image.
+%
+% o quantum_type: Declare which pixel components to transfer (AlphaQuantum,
+% BlackQuantum, BlueQuantum, CMYKAQuantum, CMYKQuantum, CyanQuantum,
+% GrayAlphaQuantum, GrayQuantum, GreenQuantum, IndexAlphaQuantum,
+% IndexQuantum, MagentaQuantum, RGBAQuantum, RGBQuantum,
+% RedQuantum, YellowQuantum)
+%
+% o quantum_size: Bits per quantum sample (range 1-32, and 64).
+%
+% o destination: The components are transferred to this buffer. The user
+% is responsible for ensuring that the destination buffer is large
+% enough.
+%
+% o options: Additional options specific to quantum_type (may be NULL).
+%
+% o export_info : Populated with information regarding the pixels
+% exported (may be NULL)
+%
+*/
+MagickExport MagickPassFail ExportImagePixelArea(const Image *image,
+ const QuantumType quantum_type,const unsigned int quantum_size,
+ unsigned char *destination,const ExportPixelAreaOptions *options,
+ ExportPixelAreaInfo *export_info)
+{
+ return ExportViewPixelArea(AccessDefaultCacheView(image),
+ quantum_type,quantum_size,
+ destination,options,export_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x p o r t V i e w P i x e l A r e a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ExportViewPixelArea() transfers one or more pixel components from the
+% specified image pixel cache view to a user supplied buffer. By default,
+% values are written in network (big-endian) byte/bit order. By setting the
+% 'endian' member of ExportPixelAreaOptions, 16, 32 and 64-bit values may be
+% output as little (LSBEndian), big (MSBEndian), or host native
+% (NativeEndian) endian values. This function is quite powerful in that
+% besides common native CPU type sizes, it can support any integer bit depth
+% from 1 to 32 (e.g. 13), 64-bits as well as 32 and 64-bit float.
+%
+%
+% MagickPass is returned if the pixels are successfully transferred,
+% otherwise MagickFail.
+%
+% The format of the ExportViewPixelArea method is:
+%
+% MagickPassFail ExportViewPixelArea(const ViewInfo *view,
+% const QuantumType quantum_type,
+% unsigned int quantum_size,
+% unsigned char *destination,
+% const ExportPixelAreaOptions *options,
+% ExportPixelAreaInfo *export_info)
+%
+% A description of each parameter follows:
+%
+% o status: Returns MagickPass if the pixels are successfully transferred,
+% otherwise MagickFail.
+%
+% o view: The image pixel cache view.
+%
+% o quantum_type: Declare which pixel components to transfer (AlphaQuantum,
+% BlackQuantum, BlueQuantum, CMYKAQuantum, CMYKQuantum, CyanQuantum,
+% GrayAlphaQuantum, GrayQuantum, GreenQuantum, IndexAlphaQuantum,
+% IndexQuantum, MagentaQuantum, RGBAQuantum, RGBQuantum,
+% RedQuantum, YellowQuantum)
+%
+% o quantum_size: Bits per quantum sample (range 1-32, and 64).
+%
+% o destination: The components are transferred to this buffer. The user
+% is responsible for ensuring that the destination buffer is large
+% enough.
+%
+% o options: Additional options specific to quantum_type (may be NULL).
+%
+% o export_info : Populated with information regarding the pixels
+% exported (may be NULL)
+%
+*/
+static MagickPassFail
+ExportIndexQuantumType(unsigned char * restrict destination,
+ const IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const Image *image,
+ unsigned long *bytes_exported)
+{
+ register unsigned long
+ x;
+
+ register unsigned char
+ *q;
+
+ q=destination;
+
+ assert(indexes != (const IndexPacket *) NULL);
+ assert(image->colors <= MaxColormapSize);
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 1:
+ {
+ /*
+ Special "fast" support for two-color PsudeoClass.
+ */
+ register unsigned int
+ bit=0,
+ byte=0;
+
+ for (x = number_pixels; x != 0; --x)
+ {
+ byte<<=1;
+ byte |= (*indexes++ ? 1U : 0U);
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ {
+ *q++=byte << (8-bit);
+ }
+ break;
+ }
+ case 4:
+ {
+ /*
+ Special "fast" support for four-color PsudeoClass.
+ */
+ register unsigned int
+ state = 0;
+
+ for (x = number_pixels ; x != 0 ; --x )
+ {
+ state ^= 1; /* Produces 1 0 1 0 ... */
+ if (state)
+ {
+ *q = ((*indexes & 0xf) << 4);
+ }
+ else
+ {
+ *q |= ((*indexes & 0xf));
+ q++;
+ }
+ indexes++;
+ }
+ if (1 == state)
+ {
+ q++;
+ }
+ break;
+ }
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,*indexes);
+ indexes++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,*indexes);
+ indexes++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,*indexes);
+ indexes++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,*indexes);
+ indexes++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,*indexes);
+ indexes++;
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportIndexAlphaQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const Image *image,
+ unsigned long *bytes_exported)
+{
+
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ register unsigned int
+ unsigned_value;
+
+ assert(image->colors <= MaxColormapSize);
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,*indexes);
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetOpacitySample(p)));
+ indexes++;
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,*indexes);
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetOpacitySample(p)));
+ indexes++;
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,*indexes);
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ indexes++;
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,*indexes);
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ indexes++;
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,*indexes);
+ unsigned_value=MaxRGB-GetOpacitySample(p);
+ if (QuantumDepth > quantum_size)
+ unsigned_value /= unsigned_scale;
+ else if (QuantumDepth < quantum_size)
+ unsigned_value *= unsigned_scale;
+ MagickBitStreamMSBWrite(&stream,quantum_size,unsigned_value);
+ indexes++;
+ p++;
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportGrayQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const MagickBool grayscale_miniswhite,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ const Image *image,
+ unsigned long *bytes_exported)
+{
+
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ register unsigned int
+ unsigned_value;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 1:
+ {
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Special "fast" support for two-color PsudeoClass.
+ */
+ register unsigned int
+ bit=0U,
+ byte=0U,
+ polarity;
+
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2U)
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+ PixelIntensityToQuantum(&image->colormap[1]);
+ if (grayscale_miniswhite)
+ polarity=!polarity;
+
+ for (x = number_pixels; x != 0UL; --x)
+ {
+ byte <<= 1U;
+ if (*indexes++ == polarity)
+ byte |= 1U;
+ bit++;
+ if (bit == 8U)
+ {
+ *q++=byte;
+ bit=0U;
+ byte=0U;
+ }
+ }
+ if (bit != 0U)
+ {
+ *q++=byte << (8U-bit);
+ }
+ }
+ else
+ {
+ /*
+ Special "fast" support for bi-level gray.
+ Performs 50% thresholding for best appearance.
+ */
+ register unsigned int
+ bit=0U,
+ byte=0U,
+ black=0U,
+ white=1U;
+
+ if (grayscale_miniswhite)
+ {
+ black=1U;
+ white=0U;
+ }
+
+ for (x = number_pixels ; x != 0UL ; --x )
+ {
+ if (image->is_grayscale)
+ unsigned_value=GetGraySample(p);
+ else
+ unsigned_value=PixelIntensityToQuantum(p);
+ byte <<= 1;
+ byte |= ((unsigned_value > MaxRGB/2U) ? white : black);
+ bit++;
+ if (bit == 8U)
+ {
+ *q++=byte;
+ bit=0U;
+ byte=0U;
+ }
+ p++;
+ }
+ if (bit != 0)
+ {
+ *q++=byte << (8-bit);
+ }
+ }
+ break;
+ }
+ case 8:
+ {
+ if (image->is_grayscale)
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetGraySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetGraySample(p)));
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-PixelIntensityToQuantum(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(PixelIntensityToQuantum(p)));
+ p++;
+ }
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ if (image->is_grayscale)
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetGraySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetGraySample(p)));
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-PixelIntensityToQuantum(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(PixelIntensityToQuantum(p)));
+ p++;
+ }
+ }
+ }
+ break;
+ }
+ case 32:
+ {
+ if (image->is_grayscale)
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetGraySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetGraySample(p)));
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-PixelIntensityToQuantum(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(PixelIntensityToQuantum(p)));
+ p++;
+ }
+ }
+ }
+ break;
+ }
+ case 64:
+ {
+ if (image->is_grayscale)
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetGraySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetGraySample(p)));
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-PixelIntensityToQuantum(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(PixelIntensityToQuantum(p)));
+ p++;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if(QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ if (image->is_grayscale)
+ unsigned_value=GetGraySample(p);
+ else
+ unsigned_value=PixelIntensityToQuantum(p);
+ if (grayscale_miniswhite)
+ unsigned_value=MaxRGB-unsigned_value;
+ MagickBitStreamMSBWrite(&stream,quantum_size,unsigned_value);
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ if (image->is_grayscale)
+ unsigned_value=GetGraySample(p);
+ else
+ unsigned_value=PixelIntensityToQuantum(p);
+ if (grayscale_miniswhite)
+ unsigned_value=MaxRGB-unsigned_value;
+ unsigned_value /= unsigned_scale;
+ MagickBitStreamMSBWrite(&stream,quantum_size,unsigned_value);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ if (image->is_grayscale)
+ unsigned_value=GetGraySample(p);
+ else
+ unsigned_value=PixelIntensityToQuantum(p);
+ if (grayscale_miniswhite)
+ unsigned_value=MaxRGB-unsigned_value;
+ unsigned_value *= unsigned_scale;
+ MagickBitStreamMSBWrite(&stream,quantum_size,unsigned_value);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,PixelIntensity(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,PixelIntensity(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,PixelIntensity(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,PixelIntensity(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportGrayAlphaQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const MagickBool grayscale_miniswhite,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ const Image *image,
+ unsigned long *bytes_exported)
+{
+
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ register unsigned int
+ unsigned_value;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ if (image->is_grayscale)
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetRedSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetRedSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-PixelIntensityToQuantum(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(PixelIntensityToQuantum(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ if (image->is_grayscale)
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetRedSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetRedSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-PixelIntensityToQuantum(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(PixelIntensityToQuantum(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ }
+ break;
+ }
+ case 32:
+ {
+ if (image->is_grayscale)
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetRedSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetRedSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-PixelIntensityToQuantum(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(PixelIntensityToQuantum(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ }
+ break;
+ }
+ case 64:
+ {
+ if (image->is_grayscale)
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetRedSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetRedSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-PixelIntensityToQuantum(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(PixelIntensityToQuantum(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ if (image->is_grayscale)
+ unsigned_value=GetRedSample(p);
+ else
+ unsigned_value=PixelIntensityToQuantum(p);
+ if (grayscale_miniswhite)
+ unsigned_value=MaxRGB-unsigned_value;
+ MagickBitStreamMSBWrite(&stream,quantum_size,unsigned_value);
+ MagickBitStreamMSBWrite(&stream,quantum_size,MaxRGB-GetOpacitySample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ if (image->is_grayscale)
+ unsigned_value=GetRedSample(p);
+ else
+ unsigned_value=PixelIntensityToQuantum(p);
+ if (grayscale_miniswhite)
+ unsigned_value=MaxRGB-unsigned_value;
+ unsigned_value /= unsigned_scale;
+ MagickBitStreamMSBWrite(&stream,quantum_size,unsigned_value);
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-GetOpacitySample(p))/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ if (image->is_grayscale)
+ unsigned_value=GetRedSample(p);
+ else
+ unsigned_value=PixelIntensityToQuantum(p);
+ if (grayscale_miniswhite)
+ unsigned_value=MaxRGB-unsigned_value;
+ unsigned_value *= unsigned_scale;
+ MagickBitStreamMSBWrite(&stream,quantum_size,unsigned_value);
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-GetOpacitySample(p))*unsigned_scale);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,PixelIntensity(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,(((double) MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue));
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,PixelIntensity(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,(((double) MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,PixelIntensity(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,(((double) MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,PixelIntensity(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportRedQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ unsigned long *bytes_exported)
+{
+
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ /*
+ Modulo-8 sample sizes
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetRedSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetRedSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetRedSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetRedSample(p)));
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetRedSample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetRedSample(p)/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetRedSample(p)*unsigned_scale);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportGreenQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ unsigned long *bytes_exported)
+{
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ /*
+ Modulo-8 sample sizes
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetGreenSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetGreenSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetGreenSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetGreenSample(p)));
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetGreenSample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetGreenSample(p)/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetGreenSample(p)*unsigned_scale);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportBlueQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ unsigned long *bytes_exported)
+{
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ /*
+ Modulo-8 sample sizes
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetBlueSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetBlueSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetBlueSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetBlueSample(p)));
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetBlueSample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetBlueSample(p)/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetBlueSample(p)*unsigned_scale);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportAlphaQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ const Image *image,
+ unsigned long *bytes_exported)
+{
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (image->colorspace == CMYKColorspace)
+ {
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-*indexes));
+ indexes++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-*indexes));
+ indexes++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-*indexes));
+ indexes++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-*indexes));
+ indexes++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ MaxRGB-*indexes);
+ indexes++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-*indexes)/unsigned_scale);
+ indexes++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-*indexes)*unsigned_scale);
+ indexes++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,(MaxRGB-*indexes)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,(MaxRGB-*indexes)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,(MaxRGB-*indexes)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,(MaxRGB-*indexes)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ MaxRGB-GetOpacitySample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-GetOpacitySample(p))/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-GetOpacitySample(p))*unsigned_scale);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportBlackQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ unsigned long *bytes_exported)
+{
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetBlackSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetBlackSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetBlackSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetBlackSample(p)));
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetBlackSample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetBlackSample(p)/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ GetBlackSample(p)*unsigned_scale);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportRGBQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ unsigned long *bytes_exported)
+{
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetRedSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetGreenSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetBlueSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetRedSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetGreenSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetBlueSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetRedSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetGreenSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetBlueSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetRedSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetGreenSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetBlueSample(p)));
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetRedSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetGreenSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlueSample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetRedSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetGreenSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlueSample(p)/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetRedSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetGreenSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlueSample(p)*unsigned_scale);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportRGBAQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ unsigned long *bytes_exported)
+{
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetRedSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetGreenSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetBlueSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetRedSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetGreenSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetBlueSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetRedSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetGreenSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetBlueSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetRedSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetGreenSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetBlueSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-GetOpacitySample(p)));
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if(QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetRedSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetGreenSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlueSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,MaxRGB-GetOpacitySample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetRedSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetGreenSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlueSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-GetOpacitySample(p))/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetRedSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetGreenSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlueSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-GetOpacitySample(p))*unsigned_scale);
+ p++;
+
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,GetRedSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetGreenSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetBlueSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,(MaxRGB-GetOpacitySample(p))*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportCMYKQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ unsigned long *bytes_exported)
+{
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetCyanSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetMagentaSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetYellowSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetBlackSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetCyanSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetMagentaSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetYellowSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetBlackSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetCyanSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetMagentaSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetYellowSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetBlackSample(p)));
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetCyanSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetMagentaSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetYellowSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetBlackSample(p)));
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if(QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetCyanSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetMagentaSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetYellowSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlackSample(p));
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetCyanSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetMagentaSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetYellowSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlackSample(p)/unsigned_scale);
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetCyanSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetMagentaSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetYellowSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlackSample(p)*unsigned_scale);
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,GetCyanSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetMagentaSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetYellowSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,GetCyanSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetMagentaSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetYellowSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,GetCyanSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetMagentaSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetYellowSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,GetCyanSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetMagentaSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetYellowSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ExportCMYKAQuantumType(unsigned char * restrict destination,
+ const PixelPacket * restrict pixels,
+ const IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ const unsigned int unsigned_scale,
+ const unsigned int sample_bits,
+ const double double_minvalue,
+ const double double_scale,
+ unsigned long *bytes_exported)
+{
+ register unsigned char
+ *q = destination;
+
+ register const PixelPacket
+ *p = pixels;
+
+ register unsigned long
+ x;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetCyanSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetMagentaSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetYellowSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(GetBlackSample(p)));
+ ExportUInt8Quantum(q,ScaleQuantumToChar(MaxRGB-*indexes));
+ indexes++;
+ p++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetCyanSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetMagentaSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetYellowSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(GetBlackSample(p)));
+ ExportUInt16Quantum(endian,q,ScaleQuantumToShort(MaxRGB-*indexes));
+ indexes++;
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetCyanSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetMagentaSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetYellowSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(GetBlackSample(p)));
+ ExportUInt32Quantum(endian,q,ScaleQuantumToLong(MaxRGB-*indexes));
+ indexes++;
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetCyanSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetMagentaSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetYellowSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(GetBlackSample(p)));
+ ExportUInt64Quantum(endian,q,ScaleQuantumToLong(MaxRGB-*indexes));
+ indexes++;
+ p++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamWriteHandle
+ stream;
+
+ MagickBitStreamInitializeWrite(&stream,q);
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetCyanSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetMagentaSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetYellowSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlackSample(p));
+ MagickBitStreamMSBWrite(&stream,quantum_size,MaxRGB-*indexes);
+ indexes++;
+ p++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetCyanSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetMagentaSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetYellowSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlackSample(p)/unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-*indexes)/unsigned_scale);
+ indexes++;
+ p++;
+ }
+ }
+ else
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetCyanSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetMagentaSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetYellowSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,GetBlackSample(p)*unsigned_scale);
+ MagickBitStreamMSBWrite(&stream,quantum_size,
+ (MaxRGB-*indexes)*unsigned_scale);
+ indexes++;
+ p++;
+ }
+ }
+ q=stream.bytes;
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat16Quantum(endian,q,GetCyanSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetMagentaSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetYellowSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ ExportFloat16Quantum(endian,q,(MaxRGB-*indexes)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat24Quantum(endian,q,GetCyanSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetMagentaSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetYellowSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ ExportFloat24Quantum(endian,q,(MaxRGB-*indexes)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat32Quantum(endian,q,GetCyanSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetMagentaSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetYellowSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ ExportFloat32Quantum(endian,q,(MaxRGB-*indexes)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ExportFloat64Quantum(endian,q,GetCyanSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetMagentaSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetYellowSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,GetBlackSample(p)*double_scale+double_minvalue);
+ ExportFloat64Quantum(endian,q,(MaxRGB-*indexes)*double_scale+double_minvalue);
+ p++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /*
+ Collect bytes exported
+ */
+ *bytes_exported=(q-destination);
+
+ return MagickPass;
+}
+
+MagickExport MagickPassFail
+ExportViewPixelArea(const ViewInfo *view,
+ const QuantumType quantum_type,
+ const unsigned int quantum_size,
+ unsigned char *destination,
+ const ExportPixelAreaOptions *options,
+ ExportPixelAreaInfo *export_info)
+{
+ const Image
+ *image;
+
+ register const IndexPacket
+ * restrict indexes;
+
+ register const PixelPacket
+ * restrict pixels;
+
+ register unsigned char
+ * restrict q;
+
+ register unsigned long
+ x;
+
+ register unsigned int
+ unsigned_scale = 1U;
+
+ MagickBool
+ grayscale_miniswhite = MagickFalse;
+
+ QuantumSampleType
+ sample_type = UnsignedQuantumSampleType;
+
+ unsigned int
+ unsigned_maxvalue=MaxRGB,
+ sample_bits;
+
+ unsigned long
+ bytes_exported = 0L,
+ number_pixels;
+
+ double
+ double_maxvalue=1.0,
+ double_minvalue=0.0,
+ double_scale;
+
+ EndianType
+ endian=MSBEndian;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(view != (ViewInfo *) NULL);
+ assert(destination != (unsigned char *) NULL);
+ assert(quantum_size > 0U);
+ assert((quantum_size <= 32U) || (quantum_size == 64U));
+ assert((options == (const ExportPixelAreaOptions *) NULL) ||
+ (options->signature == MagickSignature));
+
+ /*
+ Transfer any special options.
+ */
+ sample_bits=quantum_size;
+ if (options)
+ {
+ sample_type=options->sample_type;
+ double_minvalue=options->double_minvalue;
+ double_maxvalue=options->double_maxvalue;
+ grayscale_miniswhite=options->grayscale_miniswhite;
+
+ switch (options->endian)
+ {
+ case MSBEndian:
+ case UndefinedEndian:
+ {
+ endian=MSBEndian;
+ break;
+ }
+ case LSBEndian:
+ {
+ endian=LSBEndian;
+ break;
+ }
+ case NativeEndian:
+ {
+#if defined(WORDS_BIGENDIAN)
+ endian=MSBEndian;
+#else
+ endian=LSBEndian;
+#endif
+ break;
+ }
+ }
+ }
+
+ if (export_info)
+ {
+ export_info->bytes_exported=0;
+ }
+
+ /* printf("quantum_type=%d quantum_size=%u endian=%s\n",(int) quantum_type, quantum_size, EndianTypeToString(endian)); */
+
+ double_scale=(double) (double_maxvalue-double_minvalue)/MaxRGB;
+ if ((sample_type != FloatQuantumSampleType) && (sample_bits <= 32U))
+ {
+ /* Maximum value which may be represented by a sample */
+ unsigned_maxvalue=MaxValueGivenBits(sample_bits);
+
+ if (QuantumDepth == sample_bits)
+ {
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Divide to scale down */
+ unsigned_scale=(MaxRGB / (MaxRGB >> (QuantumDepth-sample_bits)));
+ }
+ else if (QuantumDepth < sample_bits)
+ {
+ /* Multiply to scale up */
+ unsigned_scale=(unsigned_maxvalue/MaxRGB);
+ }
+ }
+
+ image=GetCacheViewImage(view);
+ number_pixels=(unsigned long) GetCacheViewArea(view);
+ pixels=AccessCacheViewPixels(view);
+ indexes=AcquireCacheViewIndexes(view);
+ q=destination;
+ switch (quantum_type)
+ {
+ case UndefinedQuantum:
+ {
+ status=MagickFail;
+ break;
+ }
+ case IndexQuantum:
+ {
+ status=ExportIndexQuantumType(destination,indexes,number_pixels,
+ quantum_size,sample_type,endian,
+ image,&bytes_exported);
+ break;
+ }
+ case IndexAlphaQuantum:
+ {
+ status=ExportIndexAlphaQuantumType(destination,pixels,indexes,number_pixels,
+ quantum_size,sample_type,endian,unsigned_scale,
+ image,&bytes_exported);
+ break;
+ }
+ case GrayQuantum:
+ {
+ status=ExportGrayQuantumType(destination,pixels,indexes,number_pixels,quantum_size,
+ sample_type,endian,unsigned_scale,grayscale_miniswhite,
+ sample_bits,double_minvalue,double_scale,image,
+ &bytes_exported);
+ break;
+ }
+ case GrayAlphaQuantum:
+ {
+ status=ExportGrayAlphaQuantumType(destination,pixels,number_pixels,quantum_size,
+ sample_type,endian,unsigned_scale,grayscale_miniswhite,
+ sample_bits,double_minvalue,double_scale,
+ image,&bytes_exported);
+ break;
+ }
+ case RedQuantum:
+ case CyanQuantum:
+ {
+ status=ExportRedQuantumType(destination,pixels,number_pixels,quantum_size,
+ sample_type,endian,unsigned_scale,sample_bits,
+ double_minvalue,double_scale,&bytes_exported);
+ break;
+ }
+ case GreenQuantum:
+ case MagentaQuantum:
+ {
+ status=ExportGreenQuantumType(destination,pixels,number_pixels,quantum_size,
+ sample_type,endian,unsigned_scale,sample_bits,
+ double_minvalue,double_scale,&bytes_exported);
+ break;
+ }
+ case BlueQuantum:
+ case YellowQuantum:
+ {
+ status=ExportBlueQuantumType(destination,pixels,number_pixels,quantum_size,sample_type,
+ endian,unsigned_scale,sample_bits,double_minvalue,double_scale,
+ &bytes_exported);
+ break;
+ }
+ case AlphaQuantum:
+ {
+ status=ExportAlphaQuantumType(destination,pixels,indexes,number_pixels,quantum_size,
+ sample_type,endian,unsigned_scale,sample_bits,
+ double_minvalue,double_scale,image,&bytes_exported);
+ break;
+ }
+ case BlackQuantum:
+ {
+ status=ExportBlackQuantumType(destination,pixels,number_pixels,quantum_size,sample_type,
+ endian,unsigned_scale,sample_bits,double_minvalue,double_scale,
+ &bytes_exported);
+ break;
+ }
+ case RGBQuantum:
+ {
+ status=ExportRGBQuantumType(destination,pixels,number_pixels,quantum_size,sample_type,
+ endian,unsigned_scale,sample_bits,double_minvalue,double_scale,
+ &bytes_exported);
+ break;
+ }
+ case RGBAQuantum:
+ {
+ status=ExportRGBAQuantumType(destination,pixels,number_pixels,quantum_size,sample_type,
+ endian,unsigned_scale,sample_bits,double_minvalue,double_scale,
+ &bytes_exported);
+ break;
+ }
+ case CMYKQuantum:
+ {
+ status=ExportCMYKQuantumType(destination,pixels,number_pixels,quantum_size,sample_type,
+ endian,unsigned_scale,sample_bits,double_minvalue,double_scale,
+ &bytes_exported);
+ break;
+ }
+ case CMYKAQuantum:
+ {
+ status=ExportCMYKAQuantumType(destination,pixels,indexes,number_pixels,quantum_size,
+ sample_type,endian,unsigned_scale,sample_bits,double_minvalue,
+ double_scale,&bytes_exported);
+ break;
+ }
+ case CIEYQuantum:
+ case CIEXYZQuantum:
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+
+ /*
+ Appended any requested padding bytes.
+ */
+ if ((options) && (options->pad_bytes > 0))
+ {
+ q=(destination+bytes_exported);
+ for (x = options->pad_bytes; x != 0; --x)
+ *q++=options->pad_value;
+ bytes_exported=(q-destination);
+ }
+
+ /*
+ Collect export info.
+ */
+ if (export_info)
+ {
+ export_info->bytes_exported=bytes_exported;
+ }
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x p o r t P i x e l A r e a O p t i o n s I n i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ExportPixelAreaOptionsInit() initializes the options structure which is
+% optionally passed to ExportPixelArea()
+%
+% The format of the ExportPixelAreaOptionsInit method is:
+%
+% void ExportPixelAreaOptionsInit(ExportPixelAreaOptions *options)
+%
+% A description of each parameter follows:
+%
+% o options: Options structure to initialize.
+%
+*/
+MagickExport void ExportPixelAreaOptionsInit(ExportPixelAreaOptions *options)
+{
+ assert(options != (ExportPixelAreaOptions *) NULL);
+ (void) memset((void *) options, 0, sizeof(ExportPixelAreaOptions));
+ options->sample_type=UnsignedQuantumSampleType;
+ options->double_minvalue=0.0;
+ options->double_maxvalue=1.0;
+ options->grayscale_miniswhite=MagickFalse;
+ options->pad_bytes=0;
+ options->pad_value=0;
+ options->endian=MSBEndian;
+ options->signature=MagickSignature;
+}
diff --git a/magick/floats.c b/magick/floats.c
new file mode 100644
index 0000000..3600266
--- /dev/null
+++ b/magick/floats.c
@@ -0,0 +1,966 @@
+/*
+ Copyright (C) 2008 - 2015 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ 16/24 bit floating point conversion functions
+
+ Written by Richard Nolde, 2008
+
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/floats.h"
+
+#define FP16_MANT_BITS 10
+#define FP24_MANT_BITS 16
+#define FP32_MANT_BITS 23
+#define FP64_MANT_BITS 52
+
+MagickExport
+int _Gm_convert_fp16_to_fp32 (const fp_16bits *fp16, float *fp32)
+{
+ unsigned char sbit; /* sign bit */
+ unsigned char expt; /* exponent bits */
+ unsigned char m2, m1; /* MSB to LSB of mantissa */
+ unsigned char new_expt;
+ unsigned char new_m3, new_m2, new_m1;
+ unsigned char *src;
+ unsigned char *dst;
+
+#ifdef DEBUG32
+ /* Debugging variables */
+ int i, j, bit;
+ unsigned int mant;
+ double test = 0.0;
+ double test2 = 0.0;
+ double accum = 0.0;
+
+ errno = 0;
+#endif
+
+ assert (sizeof(int) == 4);
+ if ((fp16 == NULL) || (fp32 == NULL))
+ {
+ fprintf (stderr, "Invalid src or destination pointers\n");
+ return (1);
+ }
+ sbit=0;
+ src = (unsigned char *)fp16;
+ dst = (unsigned char *)fp32;
+ new_expt = expt = 0;
+ new_m3 = new_m2 = new_m1 = m2 = m1 = 0;
+
+ /* For zero, all bits except possibly sbit are zero */
+ if ((src[0] | src[1]) != 0U)
+ {
+#if !defined(WORDS_BIGENDIAN)
+ {
+ sbit = *(src + 1) & 0x80;
+ expt = (*(src + 1) & 0x7F) >> 2;
+ m2 = *(src + 1) & 0x03;
+ m1 = *src;
+ }
+#else
+ {
+ sbit = *src & 0x80;
+ expt = (*src & 0x7F) >> 2;
+ m2 = *src & 0x03;
+ m1 = *(src + 1);
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+
+ if (expt != 0)
+ new_expt = expt - 15 + 127;
+ new_m3 = (m2 << 5) | (m1 & 0xF8) >> 3;
+ new_m2 = (m1 & 7) << 5;
+ new_m1 = 0;
+ }
+#if !defined(WORDS_BIGENDIAN)
+ {
+ *dst = new_m1;
+ *(dst + 1) = new_m2;
+ *(dst + 2) = ((new_expt & 1) << 7) | new_m3;
+ *(dst + 3) = sbit | (new_expt >> 1);
+ }
+#else
+ {
+ *dst = sbit | (new_expt >> 1);
+ *(dst + 1) = ((new_expt & 1) << 7) | new_m3;
+ *(dst + 2) = new_m2;
+ *(dst + 3) = new_m1;
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+
+ /* Underflow and overflow will not be a problem
+ * since target has more significant bits that
+ * the source.
+ */
+#ifdef DEBUG32
+ /* Debugging code for display only */
+ mant = ((unsigned int)new_m3 << 16) | ((unsigned int)new_m2 << 8) | (unsigned int)new_m1;
+ if (new_expt == 0)
+ {
+ test = 0.0;
+ test2 = 0.0;
+ accum = 0.0;
+ }
+ else
+ {
+ accum = 0.0;
+ for (i = 22, j = 1; i >= 0; i--, j++)
+ {
+ bit = mant & ((unsigned int)1 << i);
+ if (bit)
+ accum += (1.0 / ((unsigned int)1 << j));
+ }
+ accum += 1.0;
+ test = pow (2.0, 1.0 * (new_expt - 127));
+ switch (errno)
+ {
+ case 0: break;
+ case EDOM:
+ case ERANGE:
+ default: perror ("Invalid value");
+ break;
+ }
+ test2 = accum * test;
+ if (sbit)
+ test2 *= -1.0;
+ }
+ printf (" Sign bit: %u, Expt biased to %5u, 2^%-5d = %8.1f * %10.8f = %18.10f\n\n",
+ sbit > 0 ? 1 : 0, new_expt, new_expt > 0 ? new_expt - 127 : 0, test, accum, test2);
+#endif
+ return (0);
+} /* end convertfp16_to_fp32 */
+
+MagickExport
+int _Gm_convert_fp32_to_fp16 (const float *fp32, fp_16bits *fp16, const int mode)
+{
+ int i, bit, rbits, rshift;
+ unsigned char sbit = 0; /* sign bit */
+ unsigned char expt = 0; /* exponent bits */
+ unsigned char m3, m2, m1; /* MSB to LSB of mantissa */
+ signed short new_expt;
+ unsigned short new_mant;
+ unsigned short mant;
+ unsigned char *src;
+ unsigned char *dst;
+ unsigned char *mp;
+
+#ifdef DEBUG16
+ int j, k;
+ double test = 0.0;
+ double test2 = 0.0;
+ double accum = 0.0;
+ double roundup = 0.0;
+
+ errno = 0;
+#endif
+
+ assert (sizeof(int) == 4);
+ if ((fp32 == NULL) || (fp16 == NULL))
+ {
+ fprintf (stderr, "Invalid src or destination pointers\n");
+ return (1);
+ }
+
+ src = (unsigned char *)fp32;
+ dst = (unsigned char *)fp16;
+ mp = (unsigned char *)&mant;
+
+ new_expt = expt = 0;
+ mant = new_mant = 0;
+ m2 = m1 = 0;
+ rbits = 0;
+
+ /* For zero, all bits except possibly sbit are zero */
+ if (*fp32 == 0)
+ *dst = 0;
+ else
+ {
+#if !defined(WORDS_BIGENDIAN)
+ {
+ sbit = *(src + 3) & 0x80;
+ expt = ((*(src + 3) & 0x7F) << 1) |
+ ((*(src + 2) & 0x80) >> 7);
+ /* Extract mantissa and left align bits */
+ m3 = (((*(src + 2) & 0x7F)) << 1) |
+ ((*(src + 1) & 0x80) >> 7);
+ m2 = (((*(src + 1) & 0x7F)) << 1) |
+ ((*src & 0x80) >> 7);
+ m1 = (*src & 0x7F) << 1;
+ }
+#else
+ {
+ sbit = *src & 0x80;
+ expt = ((*src & 0x7F) << 1) |
+ ((*(src + 1) & 0x80) >> 7);
+ /* Extract mantissa and left align bits */
+ m3 = (((*(src + 1) & 0x7F)) << 1) |
+ ((*(src + 2) & 0x80) >> 7);
+ m2 = (((*(src + 2) & 0x7F)) << 1) |
+ ((*(src + 3) & 0x80) >> 7);
+ m1 = (*(src + 3) & 0x7F) << 1;
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+
+ /* Extract the 16 MSB from the mantissa */
+ mant = (m3 << 8) | m2;
+ if (expt != 0) /* Normal number */
+ new_expt = expt - 127 + 15;
+
+ /* Even if the new exponent is too small to represent,
+ * the mantissa could have signficant digits that can
+ * be represented in the new value as a subnormal.
+ */
+ if (new_expt <= 0) /* Underflow */
+ {
+ rshift = 1 - new_expt;
+ switch (mode)
+ {
+ case STRICT_IEEE: /* NaN has all 1s in exponent plus 2 bits in Mantissa */
+ if (rshift > FP16_MANT_BITS)
+ {
+ new_expt = 31;
+ new_mant = 513;
+ errno = ERANGE;
+ fflush (stdout);
+ fprintf (stderr, "Underflow. Result clipped\n");
+ fflush (stderr);
+ return (1); /* The number cannot be represented as fp16 */
+ }
+ break;
+ case RANGE_LIMITED: /* Clamp to smallest subnormal */
+ new_expt = 0;
+ new_mant = mant >> rshift;;
+ mp = (unsigned char *)&new_mant;
+#ifdef DEBUG16
+ if (mant != 0)
+ {
+ fflush (stdout);
+ fprintf (stderr, "Underflow. %18.10f Result clippped to subnormal value\n", *fp32);
+ fflush (stderr);
+ }
+#endif
+ break;
+ case ZERO_LIMITED: /* Clamp to zero instead of using a subnormal */
+ new_expt = 0;
+ new_mant = 0;
+ mp = (unsigned char *)&new_mant;
+#ifdef DEBUG16
+ if (mant != 0)
+ {
+ fflush (stdout);
+ fprintf (stderr, "Underflow. %18.10f Result clippped to zero\n", *fp32);
+ fflush (stderr);
+ }
+#endif
+ break;
+ }
+ }
+ else /* Take the MSB from the old mantissa and left justify them */
+ {
+ if (new_expt > 30) /* Overflow */
+ {
+ switch (mode)
+ {
+ case STRICT_IEEE: /* NaN has all 1s in exponent plus 2 bits in Mantissa */
+ new_expt = 31;
+ new_mant = 513;
+ errno = ERANGE;
+ fflush (stdout);
+ fprintf (stderr, "Overflow. %18.10f Result clipped\n", *fp32);
+ fflush (stderr);
+ return (1);
+ case ZERO_LIMITED:
+ case RANGE_LIMITED: /* Clamp to maximum allowed value for fp16 */
+ new_expt = 30;
+ new_mant = 1023;
+ mp = (unsigned char *)&new_mant;
+#ifdef DEBUG16
+ fflush (stdout);
+ fprintf (stderr, "Overflow. %18.10f Result clippped\n", *fp32);
+ fflush (stderr);
+#endif
+ break;
+ }
+ }
+ else /* Normal value within range of target type */
+ {
+ /* Check bits to the right of unit in last signficant place
+ * for destination, eg first digit that cannot be stored.
+ * Rounding of least significant retained bit falls to value
+ * which will produce a zero in the LSB if the bounding values
+ * are equidistant from the unrounded value.
+ */
+ rbits = mant & 0x3F;
+ if (rbits >= 0x20) /* Greater than or equal to 0.5 times LSB */
+ {
+ if (rbits > 0x20) /* Rbits is greater than half of LSB */
+ {
+ /* Round up to next higher value of LSB */
+ for (i = 6; i < 16; i++)
+ {
+ bit = mant & (1 << i);
+ if (bit == 0)
+ {
+ new_mant = (mant | ((unsigned short)1 << i)) & (0xFFFF << i);
+ mp = (unsigned char *)&new_mant;
+ break;
+ }
+ }
+ }
+ else /* Rbits is exactly half of LSB */
+ {
+ if ((mant & 0x40)) /* LSB is one so we round up */
+ {
+ /* Round up to next higher value of LSB */
+ for (i = 6; i < 10; i++)
+ {
+ bit = mant & (1 << i);
+ if (bit == 0)
+ {
+ new_mant = (mant | ((unsigned short)1 << i)) & (0xFFFF << i);
+ mp = (unsigned char *)&new_mant;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Extract bits into contiguous positions in bytes */
+#if !defined(WORDS_BIGENDIAN)
+ {
+ m2 = (*(mp + 1) & 0xC0) >> 6;
+ m1 = ((*(mp + 1) & 0x3F) << 2) |
+ ((*mp & 0xC0) >> 6);
+ *dst = m1;
+ *(dst + 1) = sbit | ((new_expt & 0x1F) << 2) | m2;
+ }
+#else
+ {
+ m2 = (*mp & 0xC0) >> 6;
+ m1 = ((*mp & 0x3F) << 2) |
+ ((*(mp + 1) & 0xC0) >> 6);
+ *dst = sbit | ((new_expt & 0x1F) << 2) | m2;
+ *(dst + 1) = m1;
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+ }
+
+#ifdef DEBUG16
+ /* Debugging code to display the result */
+ new_mant = (m2 << 8) | m1;
+ printf ("%10.10f mant%s ", *fp32, (rbits & 0x20) ? "+" : "-");
+ for (j = 0, k = 15; j < 16; j++, k--)
+ {
+ bit = mant & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ if (j == 9)
+ printf (" ");
+ if (bit && (j > 9))
+ roundup += (1.0 / (double)(1 << (j - 9)));
+ }
+ if (new_mant == 0)
+ {
+ printf (" Fract: %8.6f m2m1 ", roundup);
+ for (j = 0, k = 1; j < 2; j++, k--)
+ {
+ bit = m2 & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ }
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = m1 & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ }
+ }
+ else
+ {
+ printf (" Fract: %8.6f Rbits Mant ", roundup);
+ for (j = 0, k = 9; j < 10; j++, k--)
+ {
+ bit = new_mant & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ }
+ }
+ printf (" Sbit + Exp ");
+#if !defined(WORDS_BIGENDIAN)
+ {
+ for (i = 1; i >= 0; i--)
+ {
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = *(dst + i) & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ if (i == 1 && j == 5)
+ printf (" Mant: ");
+ }
+ }
+ }
+#else
+ {
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = *(dst + i) & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ if (i == 0 && j == 5)
+ printf (" Mant: ");
+ }
+ }
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+ printf ("\n");
+
+ mant = ((unsigned short)m2 << 8) | (unsigned short)m1;
+ if (*fp32 == 0)
+ {
+ test = 0.0;
+ test2 = 0.0;
+ accum = 0.0;
+ }
+ else
+ {
+ accum = 0.0;
+ for (i = 9, j = 1; i >= 0; i--, j++)
+ {
+ bit = mant & ((unsigned int)1 << i);
+ if (bit)
+ accum += (1.0 / ((unsigned int)1 << j));
+ }
+ if (new_expt == 0)
+ {
+ accum += 2.0;
+ test = pow (2.0, 1.0 * (-15 - rshift));
+ }
+ else
+ {
+ accum += 1.0;
+ test = pow (2.0, 1.0 * (new_expt - 15));
+ }
+ switch (errno)
+ {
+ case 0: break;
+ case EDOM:
+ case ERANGE:
+ default: perror ("Invalid value");
+ break;
+ }
+ test2 = accum * test;
+ if (sbit)
+ test2 *= -1.0;
+ }
+ printf (" Sign bit: %u, Expt biased to %5u, 2^%-5d = %8.10f * %10.8f = %18.10f\n\n",
+ sbit > 0 ? 1 : 0, new_expt, new_expt > 0 ? new_expt - 15 : 0, test, accum, test2);
+#endif
+ return (0);
+} /* end _Gm_convert_fp32_to_fp16 */
+
+MagickExport
+int _Gm_convert_fp24_to_fp32 (const fp_24bits *fp24, float *fp32, const int mode)
+{
+ unsigned char sbit = 0; /* sign bit */
+ unsigned char expt = 0, new_expt; /* exponent bits */
+ unsigned char m2, m1; /* MSB to LSB of mantissa */
+ unsigned char new_m3, new_m2, new_m1;
+ /* unsigned short mant; */
+ /* unsigned int new_mant; */
+ /* unsigned char *mp; */
+ unsigned char *src;
+ unsigned char *dst;
+
+#ifdef DEBUG32
+ int i, j, k, bit;
+ double test = 0.0;
+ double test2 = 0.0;
+ double accum = 0.0;
+ errno = 0;
+#endif
+
+ (void) mode;
+ assert (sizeof(int) == 4);
+ if ((fp24 == NULL) || (fp32 == NULL))
+ {
+ fprintf (stderr, "Invalid src or destination pointers\n");
+ return (1);
+ }
+
+ src = (unsigned char *)fp24;
+ dst = (unsigned char *)fp32;
+ /* mp = (unsigned char *)&mant; */
+
+ new_expt = expt = 0;
+ /* new_mant = mant = 0; */
+ new_m3 = new_m2 = new_m1 = m2 = m1 = 0;
+
+ /* For zero, all bits except possibly sbit are zero */
+ if ((src[0] | src[1] | src[2]) == 0U)
+ {
+ *dst = 0;
+ *(dst + 1) = 0;
+ *(dst + 2) = 0;
+ *(dst + 3) = 0;
+ }
+ else
+ {
+#if !defined(WORDS_BIGENDIAN)
+ {
+ sbit = *(src + 2) & 0x80;
+ expt = *(src + 2) & 0x7F;
+ m2 = *(src + 1);
+ m1 = *src;
+ }
+#else
+ {
+ sbit = *src & 0x80;
+ expt = *src & 0x7F;
+ m2 = *(src + 1);
+ m1 = *(src + 2);
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+
+ if (expt != 0)
+ new_expt = expt - 63 + 127;
+ /* mant = (m2 << 8) | m1; */
+ new_m3 = (m2 & 0xFE) >> 1;
+ new_m2 = ((m2 & 0x01) << 7) | ((m1 & 0xFE) >> 1);
+ new_m1 = (m1 & 0x01) << 7;
+ }
+ /* We do not have to worry about underflow or overflow
+ * since the target has more significant bits in the
+ * exponent and the significand.
+ */
+#if !defined(WORDS_BIGENDIAN)
+ {
+ *dst = new_m1;
+ *(dst + 1) = new_m2;
+ *(dst + 2) = ((new_expt & 1) << 7) | new_m3;
+ *(dst + 3) = sbit | (new_expt >> 1);
+ }
+#else
+ {
+ *dst = sbit | (new_expt >> 1);
+ *(dst + 1) = ((new_expt & 1) << 7) | new_m3;
+ *(dst + 2) = new_m2;
+ *(dst + 3) = new_m1;
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+
+#ifdef DEBUG32
+ /* Debugging code for display only */
+ new_mant = (new_m3 << 16) | (new_m2 << 8) | new_m1;
+ printf (" mant ");
+ for (j = 0, k = 15; j < 16; j++, k--)
+ {
+ bit = mant & (1 << k);
+ if ((j % 8) == 0)
+ printf(" ");
+ printf ("%d", bit ? 1 : 0);
+ }
+
+ printf (" New Mant ");
+ for (j = 0, k = 22; j < 23; j++, k--)
+ {
+ bit = new_mant & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ if ((k % 8) == 0)
+ printf(" ");
+ }
+
+ printf (" Sbit + Exp ");
+#if !defined(WORDS_BIGENDIAN)
+ {
+ for (i = 3; i >= 0; i--)
+ {
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = *(dst + i) & (1 << k);
+ if (i == 2 && j == 1)
+ printf (" Mant: ");
+ printf ("%d", bit ? 1 : 0);
+ }
+ }
+ }
+#else
+ {
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = *(dst + i) & (1 << k);
+ if (i == 1 && j == 1)
+ printf (" Mant: ");
+ printf ("%d", bit ? 1 : 0);
+ }
+ }
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+ printf ("\n");
+
+ new_mant = ((unsigned int)new_m3 << 16) | ((unsigned int)new_m2 << 8) | new_m1;
+ if ((int)*fp24 == 0.0)
+ {
+ test = 0.0;
+ test2 = 0.0;
+ accum = 0.0;
+ }
+ else
+ {
+ accum = 0.0;
+ for (i = 22, j = 1; i >= 0; i--, j++)
+ {
+ bit = new_mant & ((unsigned int)1 << i);
+ if (bit)
+ accum += (1.0 / ((unsigned int)1 << j));
+ }
+ accum += 1.0;
+ test = pow (2.0, 1.0 * (new_expt - 127));
+ switch (errno)
+ {
+ case 0: break;
+ case EDOM:
+ case ERANGE:
+ default: perror ("Invalid value");
+ break;
+ }
+ test2 = accum * test;
+ if (sbit)
+ test2 *= -1.0;
+ }
+ printf (" Sign bit: %u, Expt biased to %5u, 2^%-5d = %8.1f * %10.8f = %18.10f\n\n",
+ sbit > 0 ? 1 : 0, new_expt, new_expt > 0 ? new_expt - 127 : 0, test, accum, test2);
+#endif
+
+ return (0);
+} /* end convertfp24_to_fp32 */
+
+MagickExport
+int _Gm_convert_fp32_to_fp24 (const float *fp32, fp_24bits *fp24, const int mode)
+{
+ int i = 1;
+ int rbits, rshift, bit;
+ unsigned char sbit = 0; /* sign bit */
+ unsigned char expt = 0; /* exponent bits */
+ unsigned char m3; /* high order bits of mantissa */
+ unsigned char m2;
+ unsigned char m1; /* low order bits of mantissa */
+ unsigned char new_m2, new_m1;
+ signed short new_expt;
+ unsigned int mant, new_mant;
+ unsigned char *mp;
+ unsigned char *src;
+ unsigned char *dst;
+
+#ifdef DEBUG24
+ int j, k;
+ double test = 0.0;
+ double test2 = 0.0;
+ double accum = 0.0;
+ double roundup = 0.0;
+#endif
+
+ errno = 0;
+ assert (sizeof(int) == 4);
+ if ((fp32 == NULL) || (fp24 == NULL))
+ {
+ fprintf (stderr, "Invalid src or destination pointers\n");
+ return (1);
+ }
+
+ src = (unsigned char *)fp32;
+ dst = (unsigned char *)fp24;
+ mp = (unsigned char *)&mant;
+
+ new_expt = expt = 0;
+ mant = new_mant = 0;
+ m2 = m1 = 0;
+ rbits = 0;
+
+ if (*fp32 != 0)
+ {
+#if !defined(WORDS_BIGENDIAN)
+ {
+ sbit = *(src + 3) & 0x80;
+ expt = ((*(src + 3) & 0x7F) << 1) |
+ ((*(src + 2) & 0x80) >> 7);
+ m3 = (((*(src + 2) & 0x7F)) << 1) |
+ ((*(src + 1) & 0x80) >> 7);
+ m2 = (((*(src + 1) & 0x7F)) << 1) |
+ ((*src & 0x80) >> 7);
+ m1 = (*src & 0x7F) << 1;
+ }
+#else
+ {
+ sbit = *src & 0x80;
+ expt = ((*src & 0x7F) << 1) |
+ ((*(src + 1) & 0x80) >> 7);
+ m3 = (((*(src + 1) & 0x7F)) << 1) |
+ ((*(src + 2) & 0x80) >> 7);
+ m2 = (((*(src + 2) & 0x7F)) << 1) |
+ ((*(src + 3) & 0x80) >> 7);
+ m1 = (*(src + 3) & 0x7F) << 1;
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+
+ mant = (m3 << 24) | (m2 << 16) |( m1 << 8);
+ if (expt != 0)
+ new_expt = expt - 127 + 63;
+
+ /* Even if the new exponent is too small to represent,
+ * the mantissa could have signficant digits that can
+ * be represented in the new value as a subnormal.
+ */
+ if (new_expt <= 0) /* Underflow */
+ {
+ rshift = 0 - new_expt;
+ switch (mode)
+ {
+ case STRICT_IEEE: /* NaN has all 1s in exponent plus 2 bits in Mantissa */
+ if (rshift > FP24_MANT_BITS)
+ {
+ new_expt = 0x7F;
+ new_mant = 0x80010000;
+ errno = ERANGE;
+ fflush (stdout);
+ fprintf (stderr, "Underflow. %18.10f Result clipped\n", *fp32);
+ fflush (stderr);
+ return (1); /* The number cannot be represented as fp24 */
+ }
+ break;
+ case RANGE_LIMITED: /* Clamp to smallest subnormal */
+ new_expt = 0;
+ new_mant = mant >> rshift;;
+ mp = (unsigned char *)&new_mant;
+#ifdef DEBUG24
+ fflush (stdout);
+ fprintf (stderr, "Underflow. %18.10f Result clippped to subnormal value\n", *fp32);
+ fflush (stderr);
+#endif
+ break;
+ case ZERO_LIMITED: /* Clamp to zero instead of using a subnormal */
+ new_expt = 0;
+ new_mant = 0;
+ mp = (unsigned char *)&new_mant;
+#ifdef DEBUG24
+ fflush (stdout);
+ fprintf (stderr, "Underflow. %18.10f Result clippped to zero\n", *fp32);
+ fflush (stderr);
+#endif
+ break;
+ }
+ }
+ else /* Take the MSB from the old mantissa and left justify them */
+ {
+ if (new_expt > 126) /* Overflow */
+ {
+ switch (mode)
+ {
+ case STRICT_IEEE: /* NaN has all 1s in exponent plus 2 bits in Mantissa */
+ new_expt = 0x7F;
+ mant = 0x80010000;
+ errno = ERANGE;
+ fflush (stdout);
+ fprintf (stderr, "Overflow. Result clipped\n");
+ fflush (stderr);
+ return (1);
+ case ZERO_LIMITED:
+ case RANGE_LIMITED: /* Clamp to maximum allowed value for fp24 */
+ new_expt = 126;
+ new_mant = 0xFFFF0000;
+ mp = (unsigned char *)&new_mant;
+#ifdef DEBUG24
+ fflush (stdout);
+ fprintf (stderr, "Overflow. Result clippped\n");
+ fflush (stderr);
+#endif
+ break;
+ }
+ }
+ else /* Normal value within range of target type */
+ { /* Remove the bits to the left of the binary point
+ * by shifting the fractional bits into the leftmost position
+ */
+ /* Check bits to the right of Unit in last signficant place.
+ * Rounding of least significant retained bit falls to value
+ * which will produce a zero in the LSB if the bounding values
+ * are equidistant from the unrounded value.
+ */
+
+ rbits = mant & 0x0000FFFF;
+ if (rbits >= 0x8000) /* Greater than or equal to 0.5 times LSB */
+ {
+ if (rbits > 0x8000) /* Rbits is greater than half of LSB */
+ {
+ /* Round up to next higher value of LSB */
+ for (i = 16; i < 32; i++)
+ {
+ bit = mant & (1 << i);
+ if (bit == 0)
+ {
+ /* Round up by inserting a 1 at first zero and
+ * clearing bits to the right
+ */
+ new_mant = (mant | ((unsigned int)1 << i)) &
+ (0xFFFF << i);
+ mp = (unsigned char *)&new_mant;
+ break;
+ }
+ }
+ }
+ else /* Rbits is exactly half of LSB */
+ {
+ if ((mant & 0x010000)) /* LSB is one so we round up */
+ {
+ /* Round up to next higher value of LSB */
+ for (i = 16; i < 32; i++)
+ {
+ bit = mant & (1 << i);
+ if (bit == 0)
+ {
+ new_mant = (mant | ((unsigned int)1 << i)) &
+ (0xFFFF << i);
+ mp = (unsigned char *)&new_mant;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#if !defined(WORDS_BIGENDIAN)
+ {
+ new_m2 = *(mp + 3);
+ new_m1 = *(mp + 2);
+ *dst = new_m1;
+ *(dst + 1) = new_m2;
+ *(dst + 2) = sbit | (new_expt & 0x7F);
+ }
+#else
+ {
+ new_m2 = *mp;
+ new_m1 = *(mp + 1);
+ *dst = sbit | (new_expt & 0x7F);
+ *(dst + 1) = new_m2;
+ *(dst + 2) = new_m1;
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+
+#ifdef DEBUG24
+ /* Debugging code for display only */
+ printf ("%10.10f mant%s ", *fp32, (rbits & 0x8000) ? "+" : "-");
+ for (j = 0, k = 31; j < 23; j++, k--)
+ {
+ bit = mant & (1 << k);
+ if ((j % 8) == 0)
+ printf(" ");
+ printf ("%d", bit ? 1 : 0);
+ if (bit && (j > 15))
+ roundup += (1.0 / (double)(1 << (j - 15)));
+ }
+
+ if (new_mant == 0)
+ {
+ printf (" Fract: %8.6f m2m1 ", roundup);
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = new_m2 & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ }
+ printf(" ");
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = new_m1 & (1 << k);
+ printf ("%d", bit ? 1 : 0);
+ }
+ }
+ else
+ {
+ printf (" Fract: %8.6f Rbits Mant ", roundup);
+ for (j = 0, k = 31; j < 16; j++, k--)
+ {
+ bit = new_mant & (1 << k);
+ if (j == 8)
+ printf(" ");
+ printf ("%d", bit ? 1 : 0);
+ }
+ }
+ printf (" Sbit + Exp ");
+#if !defined(WORDS_BIGENDIAN)
+ {
+ for (i = 2; i >= 0; i--)
+ {
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = *(dst + i) & (1 << k);
+ if (i == 1 && j == 0)
+ printf (" Mant: ");
+ printf ("%d", bit ? 1 : 0);
+ }
+ }
+ }
+#else
+ {
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0, k = 7; j < 8; j++, k--)
+ {
+ bit = *(dst + i) & (1 << k);
+ if (i == 1 && j == 0)
+ printf (" Mant: ");
+ printf ("%d", bit ? 1 : 0);
+ }
+ }
+ }
+#endif /* !defined(WORDS_BIGENDIAN) */
+ printf ("\n");
+
+ mant = ((unsigned int)new_m2 << 8) | (unsigned int)new_m1;
+ if (*fp32 == 0.0)
+ {
+ test = 0.0;
+ test2 = 0.0;
+ accum = 0.0;
+ }
+ else
+ {
+ accum = 0.0;
+ for (i = 15, j = 1; i >= 0; i--, j++)
+ {
+ bit = mant & ((unsigned int)1 << i);
+ if (bit)
+ accum += (1.0 / ((unsigned int)1 << j));
+ }
+ if (new_expt != 0)
+ accum += 1.0;
+ test = pow (2.0, 1.0 * (new_expt - 63));
+ switch (errno)
+ {
+ case 0: break;
+ case EDOM:
+ case ERANGE:
+ default: perror ("Invalid value");
+ break;
+ }
+ test2 = accum * test;
+ if (sbit)
+ test2 *= -1.0;
+ }
+ printf (" Sign bit: %u, Expt biased to %5u, 2^%-5d = %8.10f * %10.8f = %18.10f\n\n",
+ sbit > 0 ? 1 : 0, new_expt, new_expt > 0 ? new_expt - 63 : 0, test, accum, test2);
+#endif
+
+ return (0);
+} /* end convertfp32_to_fp24 */
diff --git a/magick/floats.h b/magick/floats.h
new file mode 100644
index 0000000..0d2d27b
--- /dev/null
+++ b/magick/floats.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2008 - 2011 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ 16/24 bit floating point conversion functions.
+
+ Written by Richard Nolde, 2008
+
+*/
+
+#ifndef _MAGICK_FLOATS_H
+#define _MAGICK_FLOATS_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#define RANGE_LIMITED 0
+#define ZERO_LIMITED 1
+#define STRICT_IEEE 2
+
+typedef unsigned char fp_16bits[2];
+typedef unsigned char fp_24bits[3];
+
+extern MagickExport int _Gm_convert_fp16_to_fp32 (const fp_16bits *fp16, float *fp32);
+
+extern MagickExport int _Gm_convert_fp32_to_fp16 (const float *fp32, fp_16bits *fp16, const int mode);
+
+extern MagickExport int _Gm_convert_fp24_to_fp32 (const fp_24bits *fp24, float *fp32, const int mode);
+
+extern MagickExport int _Gm_convert_fp32_to_fp24 (const float *fp32, fp_24bits *fp24, const int mode);
+
+#endif /* ifndef _MAGICK_FLOATS_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/forward.h b/magick/forward.h
new file mode 100644
index 0000000..93a29a0
--- /dev/null
+++ b/magick/forward.h
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2007 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Forward declarations for types used in public structures.
+
+*/
+#ifndef _MAGICK_FORWARD_H
+#define _MAGICK_FORWARD_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+typedef struct _Image *ImagePtr;
+
+typedef struct _Ascii85Info* _Ascii85InfoPtr_;
+
+typedef struct _BlobInfo* _BlobInfoPtr_;
+
+typedef struct _CacheInfo* _CacheInfoPtr_;
+
+typedef struct _ImageAttribute* _ImageAttributePtr_;
+
+typedef struct _SemaphoreInfo* _SemaphoreInfoPtr_;
+
+typedef struct _ThreadViewSet* _ThreadViewSetPtr_;
+
+typedef void *ViewInfo;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_FORWARD_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/fx.c b/magick/fx.c
new file mode 100644
index 0000000..69fb676
--- /dev/null
+++ b/magick/fx.c
@@ -0,0 +1,1788 @@
+/*
+% Copyright (C) 2003-2009 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% FFFFF X X %
+% F X X %
+% FFF X %
+% F X X %
+% F X X %
+% %
+% %
+% GraphicsMagick Image Special Effects Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% October 1996 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/color.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/fx.h"
+#include "magick/gem.h"
+#include "magick/log.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/monitor.h"
+#include "magick/resize.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C h a r c o a l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method CharcoalImage creates a new image that is a copy of an existing
+% one with the edge highlighted. It allocates the memory necessary for the
+% new Image structure and returns a pointer to the new image.
+%
+% The format of the CharcoalImage method is:
+%
+% Image *CharcoalImage(const Image *image,const double radius,
+% const double sigma,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o charcoal_image: Method CharcoalImage returns a pointer to the image
+% after it is embossed. A null image is returned if there is a memory
+% shortage.
+%
+% o image: The image.
+%
+% o radius: the radius of the pixel neighborhood.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *CharcoalImage(const Image *image,const double radius,
+ const double sigma,ExceptionInfo *exception)
+{
+ Image
+ *blur_image,
+ *charcoal_image,
+ *edge_image;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ charcoal_image=CloneImage(image,0,0,True,exception);
+ if (charcoal_image == (Image *) NULL)
+ return((Image *) NULL);
+ (void) SetImageType(charcoal_image,GrayscaleType);
+ edge_image=EdgeImage(charcoal_image,radius,exception);
+ if (edge_image == (Image *) NULL)
+ return((Image *) NULL);
+ DestroyImage(charcoal_image);
+ blur_image=BlurImage(edge_image,radius,sigma,exception);
+ if (blur_image == (Image *) NULL)
+ return((Image *) NULL);
+ DestroyImage(edge_image);
+ (void) NormalizeImage(blur_image);
+ (void) NegateImage(blur_image,False);
+ (void) SetImageType(blur_image,GrayscaleType);
+ return(blur_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C o l o r i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ColorizeImage() blends the fill color with each pixel in the image.
+% A percentage blend is specified with opacity. Control the application
+% of different color components by specifying a different percentage for
+% each component (e.g. 90/100/10 is 90% red, 100% green, and 10% blue).
+%
+% The format of the ColorizeImage method is:
+%
+% Image *ColorizeImage(const Image *image,const char *opacity,
+% const PixelPacket target,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o opacity: A character string indicating the level of opacity as a
+% percentage.
+%
+% o target: A color value.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+typedef struct _ColorizeImagePixelsOptions
+{
+ DoublePixelPacket amount;
+ DoublePixelPacket color;
+} ColorizeImagePixelsOptions;
+static MagickPassFail
+ColorizeImagePixelsCB(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *new_image, /* New image */
+ PixelPacket *new_pixels, /* Pixel row in new image */
+ IndexPacket *new_indexes, /* Pixel row indexes in new image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ ColorizeImagePixelsOptions
+ options = *((const ColorizeImagePixelsOptions *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(source_image);
+ ARG_NOT_USED(source_indexes);
+ ARG_NOT_USED(new_image);
+ ARG_NOT_USED(new_indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ new_pixels[i].red=(Quantum)
+ ((source_pixels[i].red*(100.0-options.amount.red)+
+ options.color.red*options.amount.red)/100.0);
+ new_pixels[i].green=(Quantum)
+ ((source_pixels[i].green*(100.0-options.amount.green)+
+ options.color.green*options.amount.green)/100.0);
+ new_pixels[i].blue=(Quantum)
+ ((source_pixels[i].blue*(100.0-options.amount.blue)+
+ options.color.blue*options.amount.blue)/100.0);
+ new_pixels[i].opacity=(Quantum)
+ ((source_pixels[i].opacity*(100.0-options.amount.opacity)+
+ options.color.opacity*options.amount.opacity)/100.0);
+ }
+
+ return MagickPass;
+}
+MagickExport Image *ColorizeImage(const Image *image,const char *opacity,
+ const PixelPacket target,ExceptionInfo *exception)
+{
+#define ColorizeImageText "[%s] Colorize..."
+
+ ColorizeImagePixelsOptions
+ options;
+
+ Image
+ *colorize_image;
+
+ long
+ count;
+
+ unsigned int
+ is_grayscale;
+
+ /*
+ Allocate colorized image.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ is_grayscale=image->is_grayscale;
+ colorize_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (colorize_image == (Image *) NULL)
+ return((Image *) NULL);
+ (void) SetImageType(colorize_image,TrueColorType);
+ if (opacity == (const char *) NULL)
+ return(colorize_image);
+ /*
+ Determine percentage RGB values of the pen color.
+ */
+ options.amount.red=100.0;
+ options.amount.green=100.0;
+ options.amount.blue=100.0;
+ options.amount.opacity=0.0;
+ count=sscanf(opacity,"%lf%*[/,]%lf%*[/,]%lf%*[/,]%lf",
+ &options.amount.red,&options.amount.green,&options.amount.blue,&options.amount.opacity);
+ if (count == 1)
+ {
+ if (options.amount.red == 0.0)
+ return(colorize_image);
+ options.amount.green=options.amount.red;
+ options.amount.blue=options.amount.red;
+ options.amount.opacity=options.amount.red;
+ }
+ options.color.red=target.red;
+ options.color.green=target.green;
+ options.color.blue=target.blue;
+ options.color.opacity=target.opacity;
+ /*
+ Colorize DirectClass image.
+ */
+ (void) PixelIterateDualNew(ColorizeImagePixelsCB,NULL,
+ ColorizeImageText,NULL,&options,
+ image->columns,image->rows,image,0,0,
+ colorize_image,0,0,&colorize_image->exception);
+ colorize_image->is_grayscale=(is_grayscale && IsGray(target));
+ return(colorize_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C o l o r M a t r i x I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ColorMatrixImage() applies a color matrix to the image channels. The
+% user supplied matrix may be of order 1 to 5 (1x1 through 5x5) and is
+% used to update the default identity matrix:
+%
+% 1 0 0 0 0
+% 0 1 0 0 0
+% 0 0 1 0 0
+% 0 0 0 1 0
+% 0 0 0 0 1
+%
+% where the first four columns represent the ratio of the color (red,
+% green, blue) and opacity components incorporated in the output summation.
+% The first four rows represent the summations for red, green, blue, and
+% opacity. The last row is a dummy row and is not used. The last column
+% represents a constant value (expressed as a ratio of MaxRGB) to be
+% added to the row summation. The following is a summary of how the
+% matrix is applied:
+%
+% r' = r*m[0,0] + g*m[1,0] + b*m[2,0] + o*m[3,0] + MaxRGB*m[4,0]
+% g' = r*m[0,1] + g*m[1,1] + b*m[2,1] + o*m[3,1] + MaxRGB*m[4,1]
+% b' = r*m[0,2] + g*m[1,2] + b*m[2,2] + o*m[3,2] + MaxRGB*m[4,2]
+% o' = r*m[0,3] + g*m[1,3] + b*m[2,3] + o*m[3,3] + MaxRGB*m[4,3]
+%
+% The format of the ColorMatrixImage method is:
+%
+% MagickPassFail ColorMatrixImage(Image *image,
+% const unsigned int order,
+% const double *color_matrix)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o order: The number of columns and rows in the filter kernel.
+%
+% o matrix: An array of double representing the matrix
+%
+%
+*/
+typedef struct _ColorMatrixImageOptions_t
+{
+ const double
+ *matrix[5];
+
+} ColorMatrixImageOptions_t;
+
+static MagickPassFail
+ColorMatrixImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Color matrix image pixels.
+ */
+ const ColorMatrixImageOptions_t
+ *options = (const ColorMatrixImageOptions_t *) immutable_data;
+
+ long
+ i;
+
+ double
+ column[5],
+ sums[4];
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < (long) (sizeof(sums)/sizeof(sums[0])); i++)
+ sums[i] = 0.0;
+
+ column[3] = MaxRGBDouble;
+ column[4] = MaxRGBDouble;
+
+ for (i=0; i < npixels; i++)
+ {
+ unsigned int
+ row;
+
+ /*
+ Accumulate float input pixel
+ */
+ column[0]=(double) pixels[i].red;
+ column[1]=(double) pixels[i].green;
+ column[2]=(double) pixels[i].blue;
+ if (image->matte)
+ column[3]=(MaxRGBDouble-(double) pixels[i].opacity);
+
+ /*
+ Compute row sums.
+ */
+ for (row=0; row < 4; row++)
+ {
+ const double
+ *m;
+
+ if ((m = options->matrix[row]) != (const double *) NULL)
+ sums[row]=m[0]*column[0] + m[1]*column[1] + m[2]*column[2] +
+ m[3]*column[3] + m[4]*column[4];
+ }
+
+ /*
+ Assign results.
+ */
+ for (row=0; row < 4; row++)
+ {
+ if (options->matrix[row] != (const double *) NULL)
+ {
+ switch (row)
+ {
+ case 0:
+ pixels[i].red = RoundDoubleToQuantum(sums[row]);
+ break;
+ case 1:
+ pixels[i].green = RoundDoubleToQuantum(sums[row]);
+ break;
+ case 2:
+ pixels[i].blue = RoundDoubleToQuantum(sums[row]);
+ break;
+ case 3:
+ sums[row]=(MaxRGBDouble-sums[row]);
+ pixels[i].opacity = RoundDoubleToQuantum(sums[row]);
+ break;
+ }
+ }
+ }
+ }
+
+ return MagickPass;
+}
+
+#define ColorMatrixImageText "[%s] Color matrix..."
+MagickExport MagickPassFail
+ColorMatrixImage(Image *image,const unsigned int order,const double *color_matrix)
+{
+ double
+ matrix[] =
+ {
+ 1.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 1.0
+ };
+
+ unsigned int
+ i;
+
+ int
+ width = 5;
+
+ ColorMatrixImageOptions_t
+ options;
+
+ MagickPassFail
+ status = MagickPass;
+
+ if ((order < 1) || (order > 5))
+ ThrowBinaryException(OptionError,MatrixOrderOutOfRange,
+ MagickMsg(OptionError,UnableToColorMatrixImage));
+
+ assert(color_matrix != (const double *) NULL);
+
+ for (i=0; i < sizeof(options.matrix)/sizeof(options.matrix[0]); i++)
+ options.matrix[i] = (double *) NULL;
+
+ {
+ double
+ *d;
+
+ const double
+ *u;
+
+ unsigned int
+ j;
+
+ u = color_matrix;
+ for (i=0; i < order; i++)
+ {
+ d = &matrix[i*5];
+ for (j=0; j < order; j++)
+ {
+ if (d[j] != *u)
+ {
+ d[j]=*u;
+ options.matrix[i]=&matrix[i*5];
+ }
+ u++;
+ }
+ }
+
+ /*
+ Add opacity channel if we will be updating opacity.
+ */
+ if ((!image->matte) && (options.matrix[3] != (double *) NULL))
+ SetImageOpacity(image,OpaqueOpacity);
+ }
+
+ if (LogMagickEvent(TransformEvent,GetMagickModule(),
+ " ColorMatrix with %dx%d matrix:",width,width))
+ {
+ /*
+ Log matrix.
+ */
+ char
+ cell_text[MaxTextExtent],
+ row_text[MaxTextExtent];
+
+ const double
+ *k;
+
+ long
+ u,
+ v;
+
+ k=matrix;
+ for (v=0; v < width; v++)
+ {
+ *row_text='\0';
+ for (u=0; u < width; u++)
+ {
+ FormatString(cell_text,"%#12.4g",*k++);
+ (void) strlcat(row_text,cell_text,sizeof(row_text));
+ if (u%5 == 4)
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ " %.64s", row_text);
+ *row_text='\0';
+ }
+ }
+ if (u > 5)
+ (void) strlcat(row_text,"\n",sizeof(row_text));
+ if (row_text[0] != '\0')
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ " %s", row_text);
+ }
+ }
+
+ if ((options.matrix[0] != (double *) NULL) ||
+ (options.matrix[1] != (double *) NULL) ||
+ (options.matrix[2] != (double *) NULL) ||
+ (options.matrix[3] != (double *) NULL))
+ {
+ image->storage_class=DirectClass;
+ /*
+ We don't currently handle CMYK(A) colorspaces, although
+ manipulation in other alternate colorspaces may be useful.
+ */
+ if (image->colorspace == CMYKColorspace)
+ (void) TransformColorspace(image,RGBColorspace);
+ status=PixelIterateMonoModify(ColorMatrixImagePixels,
+ NULL,
+ ColorMatrixImageText,
+ NULL,&options,
+ 0,0,image->columns,image->rows,
+ image,
+ &image->exception);
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% I m p l o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ImplodeImage creates a new image that is a copy of an existing
+% one with the image pixels "implode" by the specified percentage. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the ImplodeImage method is:
+%
+% Image *ImplodeImage(const Image *image,const double amount,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o implode_image: Method ImplodeImage returns a pointer to the image
+% after it is implode. A null image is returned if there is a memory
+% shortage.
+%
+% o image: The image.
+%
+% o amount: Define the extent of the implosion.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *ImplodeImage(const Image *image,const double amount,
+ ExceptionInfo *exception)
+{
+#define ImplodeImageText "[%s] Implode..."
+
+ double
+ radius,
+ x_center,
+ x_scale,
+ y_center,
+ y_scale;
+
+ Image
+ *implode_image;
+
+ long
+ y;
+
+
+ /*
+ Initialize implode image attributes.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ implode_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (implode_image == (Image *) NULL)
+ return((Image *) NULL);
+ (void) SetImageType(implode_image,implode_image->background_color.opacity !=
+ OpaqueOpacity ? TrueColorMatteType : TrueColorType);
+ /*
+ Compute scaling factor.
+ */
+ x_scale=1.0;
+ y_scale=1.0;
+ x_center=0.5*image->columns;
+ y_center=0.5*image->rows;
+ radius=x_center;
+ if (image->columns > image->rows)
+ y_scale=(double) image->columns/image->rows;
+ else
+ if (image->columns < image->rows)
+ {
+ x_scale=(double) image->rows/image->columns;
+ radius=y_center;
+ }
+ /*
+ Implode each row.
+ */
+ {
+ MagickPassFail
+ status = MagickPass;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ double
+ distance,
+ x_distance,
+ y_distance;
+
+ ViewInfo
+ *image_view;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ImplodeImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ image_view=AccessDefaultCacheView(image);
+ q=SetImagePixelsEx(implode_image,0,y,implode_image->columns,1,
+ exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ y_distance=y_scale*(y-y_center);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ /*
+ Determine if the pixel is within an ellipse.
+ */
+ x_distance=x_scale*(x-x_center);
+ distance=x_distance*x_distance+y_distance*y_distance;
+ if (distance >= (radius*radius))
+ (void) AcquireOneCacheViewPixel(image_view,q,x,y,exception);
+ else
+ {
+ double
+ factor;
+
+ /*
+ Implode the pixel.
+ */
+ factor=1.0;
+ if (distance > 0.0)
+ factor=pow(sin(MagickPI*sqrt(distance)/radius/2),-amount);
+ InterpolateViewColor(image_view,q,
+ factor*x_distance/x_scale+x_center,
+ factor*y_distance/y_scale+y_center,
+ exception);
+ }
+ q++;
+ }
+ if (!SyncImagePixelsEx(implode_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_ImplodeImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ ImplodeImageText,implode_image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ implode_image->is_grayscale=image->is_grayscale;
+ return(implode_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M o r p h I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The MorphImages() method requires a minimum of two images. The first
+% image is transformed into the second by a number of intervening images
+% as specified by frames.
+%
+% The format of the MorphImage method is:
+%
+% Image *MorphImages(const Image *image,const unsigned long number_frames,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o number_frames: Define the number of in-between image to generate.
+% The more in-between frames, the smoother the morph.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+typedef struct _MorphImagePixelsOptions
+{
+ double alpha;
+ double beta;
+} MorphImagePixelsOptions;
+static MagickPassFail
+MorphImagePixelsCB(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *new_image, /* New image */
+ PixelPacket *new_pixels, /* Pixel row in new image */
+ IndexPacket *new_indexes, /* Pixel row indexes in new image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ )
+{
+ MorphImagePixelsOptions
+ options = *((const MorphImagePixelsOptions *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(source_image);
+ ARG_NOT_USED(source_indexes);
+ ARG_NOT_USED(new_image);
+ ARG_NOT_USED(new_indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ new_pixels[i].red=(Quantum) (options.alpha*new_pixels[i].red+
+ options.beta*source_pixels[i].red+0.5);
+ new_pixels[i].green=(Quantum) (options.alpha*new_pixels[i].green+
+ options.beta*source_pixels[i].green+0.5);
+ new_pixels[i].blue=(Quantum) (options.alpha*new_pixels[i].blue+
+ options.beta*source_pixels[i].blue+0.5);
+ new_pixels[i].opacity=(Quantum) (options.alpha*new_pixels[i].opacity+
+ options.beta*source_pixels[i].opacity+0.5);
+ }
+
+ return MagickPass;
+}
+MagickExport Image *MorphImages(const Image *image,
+ const unsigned long number_frames,ExceptionInfo *exception)
+{
+#define MorphImageText "[%s] Morph sequence..."
+
+ MorphImagePixelsOptions
+ options;
+
+ Image
+ *clone_image,
+ *morph_image,
+ *morph_images;
+
+ MonitorHandler
+ handler;
+
+ register const Image
+ *next;
+
+ register long
+ i;
+
+ unsigned long
+ scene;
+
+ /*
+ Clone first frame in sequence.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ morph_images=CloneImage(image,0,0,True,exception);
+ if (morph_images == (Image *) NULL)
+ return((Image *) NULL);
+ if (image->next == (Image *) NULL)
+ {
+ /*
+ Morph single image.
+ */
+ for (i=1; i < (long) number_frames; i++)
+ {
+ morph_images->next=CloneImage(image,0,0,True,exception);
+ if (morph_images->next == (Image *) NULL)
+ {
+ DestroyImageList(morph_images);
+ return((Image *) NULL);
+ }
+ morph_images->next->previous=morph_images;
+ morph_images=morph_images->next;
+ if (!MagickMonitorFormatted(i,number_frames,exception,
+ MorphImageText,image->filename))
+ break;
+ }
+ while (morph_images->previous != (Image *) NULL)
+ morph_images=morph_images->previous;
+ return(morph_images);
+ }
+ /*
+ Morph image sequence.
+ */
+ scene=0;
+ for (next=image; next->next != (Image *) NULL; next=next->next)
+ {
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ for (i=0; i < (long) number_frames; i++)
+ {
+ options.beta=((double) i+1.0)/(number_frames+1.0);
+ options.alpha=1.0-options.beta;
+ clone_image=CloneImage(next,0,0,True,exception);
+ if (clone_image == (Image *) NULL)
+ break;
+ morph_images->next=ZoomImage(clone_image,
+ (unsigned long) (options.alpha*next->columns+options.beta*next->next->columns+0.5),
+ (unsigned long) (options.alpha*next->rows+options.beta*next->next->rows+0.5),exception);
+ DestroyImage(clone_image);
+ if (morph_images->next == (Image *) NULL)
+ break;
+ morph_images->next->previous=morph_images;
+ morph_images=morph_images->next;
+ clone_image=CloneImage(next->next,0,0,True,exception);
+ if (clone_image == (Image *) NULL)
+ break;
+ morph_image=ZoomImage(clone_image,morph_images->columns,
+ morph_images->rows,exception);
+ DestroyImage(clone_image);
+ if (morph_image == (Image *) NULL)
+ break;
+ (void) SetImageType(morph_images,TrueColorType);
+ (void) PixelIterateDualNew(MorphImagePixelsCB,NULL,
+ MorphImageText,NULL,&options,
+ morph_images->columns,morph_images->rows,morph_image,0,0,
+ morph_images,0,0,exception);
+ DestroyImage(morph_image);
+ }
+ if (i < (long) number_frames)
+ break;
+ /*
+ Clone last frame in sequence.
+ */
+ morph_images->next=CloneImage(next->next,0,0,True,exception);
+ if (morph_images->next == (Image *) NULL)
+ break;
+ morph_images->next->previous=morph_images;
+ morph_images=morph_images->next;
+ (void) SetMonitorHandler(handler);
+ if (!MagickMonitorFormatted(scene,GetImageListLength(image),exception,
+ MorphImageText,image->filename))
+ break;
+ scene++;
+ }
+ while (morph_images->previous != (Image *) NULL)
+ morph_images=morph_images->previous;
+ if (next->next != (Image *) NULL)
+ {
+ DestroyImageList(morph_images);
+ return((Image *) NULL);
+ }
+ return(morph_images);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% O i l P a i n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% OilPaintImage() applies a special effect filter that simulates an oil
+% painting. Each pixel is replaced by the most frequent color occurring
+% in a circular region defined by radius.
+%
+% The format of the OilPaintImage method is:
+%
+% Image *OilPaintImage(const Image *image,const double radius,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o radius: The radius of the circular neighborhood.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define PaintHistSize 256
+MagickExport Image *OilPaintImage(const Image *image,const double radius,
+ ExceptionInfo *exception)
+{
+#define OilPaintImageText "[%s] OilPaint..."
+
+ Image
+ *paint_image;
+
+ long
+ width,
+ y;
+
+ unsigned long
+ row_count=0;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize painted image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ width=GetOptimalKernelWidth(radius,0.5);
+ if (((long) image->columns < width) || ((long) image->rows < width))
+ ThrowImageException3(OptionError,UnableToPaintImage,
+ ImageSmallerThanRadius);
+
+ paint_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (paint_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ (void) SetImageType(paint_image,TrueColorType);
+
+ /*
+ Paint each row of the image.
+ */
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ const PixelPacket
+ *p,
+ *r;
+
+ PixelPacket
+ *q;
+
+ long
+ x;
+
+ const PixelPacket
+ *s;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_OilPaintImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,-width/2,y-width/2,image->columns+width,width,
+ exception);
+ q=SetImagePixelsEx(paint_image,0,y,paint_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ long
+ v;
+
+ unsigned long
+ count;
+
+ unsigned int
+ histogram[PaintHistSize];
+
+ /*
+ Determine most frequent color.
+ */
+ count=0;
+ (void) memset(histogram,0,sizeof(histogram));
+ r=p++;
+ s=r;
+ for (v=width; v > 0; v--)
+ {
+ register long
+ u;
+
+ register const PixelPacket
+ *ru;
+
+ ru=r;
+ for (u=width; u > 0; u--)
+ {
+ register unsigned int
+ *hp;
+
+ Quantum
+ intensity;
+
+ if (image->is_grayscale)
+ intensity=ru->red;
+ else
+ intensity=PixelIntensityToQuantum(ru);
+
+ hp=histogram+ScaleQuantumToChar(intensity);
+ (*hp)++;
+ if (*hp > count)
+ {
+ s=ru;
+ count=*hp;
+ }
+ ru++;
+ }
+ r+=image->columns+width;
+ }
+ *q++=(*s);
+ }
+ if (!SyncImagePixelsEx(paint_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_OilPaintImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ OilPaintImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ paint_image->is_grayscale=image->is_grayscale;
+ return(paint_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% S o l a r i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SolarizeImage() applies a special effect to the image, similar to the effect
+% achieved in a photo darkroom by selectively exposing areas of photo
+% sensitive paper to light. Threshold ranges from 0 to MaxRGB and is a
+% measure of the extent of the solarization. False is returned if an error
+% is encountered.
+%
+% The format of the SolarizeImage method is:
+%
+% unsigned int SolarizeImage(Image *image,const double threshold)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o threshold: Define the extent of the solarization.
+%
+%
+*/
+static MagickPassFail
+SolarizeImagePixelsCB(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+
+ const Quantum
+ threshold = *((const double *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=(pixels[i].red > threshold ?
+ MaxRGB-pixels[i].red : pixels[i].red);
+ pixels[i].green=(pixels[i].green > threshold ?
+ MaxRGB-pixels[i].green : pixels[i].green);
+ pixels[i].blue=(pixels[i].blue > threshold ?
+ MaxRGB-pixels[i].blue : pixels[i].blue);
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail SolarizeImage(Image *image,const double threshold)
+{
+#define SolarizeImageText "[%s] Solarize..."
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ is_grayscale=image->is_grayscale;
+ switch (image->storage_class)
+ {
+ case DirectClass:
+ default:
+ {
+ /*
+ Solarize DirectClass packets.
+ */
+ status=PixelIterateMonoModify(SolarizeImagePixelsCB,
+ NULL,
+ SolarizeImageText,
+ NULL,&threshold,0,0,image->columns,image->rows,
+ image,&image->exception);
+ break;
+ }
+ case PseudoClass:
+ {
+ /*
+ Solarize PseudoClass packets.
+ */
+ SolarizeImagePixelsCB(0,
+ &threshold,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+ status &= SyncImage(image);
+ break;
+ }
+ }
+ image->is_grayscale=is_grayscale;
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S t e g a n o I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use SteganoImage() to hide a digital watermark within the image.
+% Recover the hidden watermark later to prove that the authenticity of
+% an image. Offset defines the start position within the image to hide
+% the watermark.
+%
+% The format of the SteganoImage method is:
+%
+% Image *SteganoImage(const Image *image,Image *watermark,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o watermark: The watermark image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define GetBit(a,i) (((a) >> (i)) & 0x01)
+#define SetBit(a,i,set) \
+ a=(Quantum) ((set) ? (a) | (1UL << (i)) : (a) & ~(1UL << (i)))
+#define SteganoImageText "[%s] Stegano..."
+MagickExport Image *SteganoImage(const Image *image,const Image *watermark,
+ ExceptionInfo *exception)
+{
+
+ Image
+ *stegano_image;
+
+ long
+ c,
+ i,
+ j,
+ k,
+ y;
+
+ PixelPacket
+ pixel;
+
+ register long
+ x;
+
+ unsigned int
+ is_grayscale;
+
+ register PixelPacket
+ *q;
+
+ /*
+ Initialize steganographic image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(watermark != (const Image *) NULL);
+ assert(watermark->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ is_grayscale=(image->is_grayscale && watermark->is_grayscale);
+ stegano_image=CloneImage(image,0,0,True,exception);
+ if (stegano_image == (Image *) NULL)
+ return((Image *) NULL);
+ (void) SetImageType(stegano_image,TrueColorType);
+ stegano_image->depth=QuantumDepth;
+ /*
+ Hide watermark in low-order bits of image.
+ */
+ c=0;
+ i=0;
+ j=0;
+ k=image->offset;
+ for (i=QuantumDepth-1; (i >= 0) && (j < QuantumDepth); i--)
+ {
+ for (y=0; (y < (long) watermark->rows) && (j < QuantumDepth); y++)
+ {
+ for (x=0; (x < (long) watermark->columns) && (j < QuantumDepth); x++)
+ {
+ (void) AcquireOnePixelByReference(watermark,&pixel,x,y,exception);
+ q=GetImagePixels(stegano_image,k % (long) stegano_image->columns,
+ k/(long) stegano_image->columns,1,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ switch ((int) c)
+ {
+ case 0:
+ {
+ SetBit(q->red,j,GetBit(PixelIntensityToQuantum(&pixel),i));
+ break;
+ }
+ case 1:
+ {
+ SetBit(q->green,j,GetBit(PixelIntensityToQuantum(&pixel),i));
+ break;
+ }
+ case 2:
+ {
+ SetBit(q->blue,j,GetBit(PixelIntensityToQuantum(&pixel),i));
+ break;
+ }
+ }
+ (void) SyncImage(stegano_image);
+ c++;
+ if (c == 3)
+ c=0;
+ k++;
+ if (k == (long) (stegano_image->columns*stegano_image->columns))
+ k=0;
+ if (k == image->offset)
+ j++;
+ }
+ }
+ if (QuantumTick(i,QuantumDepth))
+ if (!MagickMonitorFormatted(i,QuantumDepth,exception,
+ SteganoImageText,image->filename))
+ break;
+ }
+ if (stegano_image->storage_class == PseudoClass)
+ (void) SyncImage(stegano_image);
+ stegano_image->is_grayscale=is_grayscale;
+ return(stegano_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S t e r e o I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% StereoImage() combines two images and produces a single image that is the
+% composite of a left and right image of a stereo pair. Special red-green
+% stereo glasses are required to view this effect.
+%
+% The format of the StereoImage method is:
+%
+% Image *StereoImage(const Image *image,const Image *offset_image,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o stereo_image: Method StereoImage returns a pointer to the stereo
+% image. A null image is returned if there is a memory shortage.
+%
+% o image: The image.
+%
+% o offset_image: Another image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *StereoImage(const Image *image,const Image *offset_image,
+ ExceptionInfo *exception)
+{
+#define StereoImageText "[%s] Stereo..."
+
+ Image
+ *stereo_image;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p,
+ *q;
+
+ register long
+ x;
+
+ register PixelPacket
+ *r;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ assert(offset_image != (const Image *) NULL);
+ if ((image->columns != offset_image->columns) ||
+ (image->rows != offset_image->rows))
+ ThrowImageException3(ImageError,UnableToCreateStereoImage,
+ LeftAndRightImageSizesDiffer);
+ /*
+ Initialize stereo image attributes.
+ */
+ stereo_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (stereo_image == (Image *) NULL)
+ return((Image *) NULL);
+ (void) SetImageType(stereo_image,TrueColorType);
+ /*
+ Copy left image to red channel and right image to blue channel.
+ */
+ for (y=0; y < (long) stereo_image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ q=AcquireImagePixels(offset_image,0,y,offset_image->columns,1,exception);
+ r=SetImagePixels(stereo_image,0,y,stereo_image->columns,1);
+ if ((p == (PixelPacket *) NULL) || (q == (PixelPacket *) NULL) ||
+ (r == (PixelPacket *) NULL))
+ break;
+ for (x=0; x < (long) stereo_image->columns; x++)
+ {
+ r->red=p->red;
+ r->green=q->green;
+ r->blue=q->blue;
+ r->opacity=(p->opacity+q->opacity)/2;
+ p++;
+ q++;
+ r++;
+ }
+ if (!SyncImagePixels(stereo_image))
+ break;
+ if (QuantumTick(y,stereo_image->rows))
+ if (!MagickMonitorFormatted(y,stereo_image->rows,exception,
+ StereoImageText,image->filename))
+ break;
+ }
+ return(stereo_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% S w i r l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SwirlImage() swirls the pixels about the center of the image, where
+% degrees indicates the sweep of the arc through which each pixel is moved.
+% You get a more dramatic effect as the degrees move from 1 to 360.
+%
+% The format of the SwirlImage method is:
+%
+% Image *SwirlImage(const Image *image,double degrees,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o degrees: Define the tightness of the swirling effect.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *SwirlImage(const Image *image,double degrees,
+ ExceptionInfo *exception)
+{
+#define SwirlImageText "[%s] Swirl..."
+
+ double
+ radius,
+ x_center,
+ x_scale,
+ y_center,
+ y_scale;
+
+ long
+ y;
+
+ Image
+ *swirl_image;
+
+ /*
+ Initialize swirl image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ swirl_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (swirl_image == (Image *) NULL)
+ return((Image *) NULL);
+ (void) SetImageType(swirl_image,swirl_image->background_color.opacity !=
+ OpaqueOpacity ? TrueColorMatteType : TrueColorType);
+ /*
+ Compute scaling factor.
+ */
+ x_center=image->columns/2.0;
+ y_center=image->rows/2.0;
+ radius=Max(x_center,y_center);
+ x_scale=1.0;
+ y_scale=1.0;
+ if (image->columns > image->rows)
+ y_scale=(double) image->columns/image->rows;
+ else
+ if (image->columns < image->rows)
+ x_scale=(double) image->rows/image->columns;
+ degrees=DegreesToRadians(degrees);
+ /*
+ Swirl each row.
+ */
+ {
+ MagickPassFail
+ status = MagickPass;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,8) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register PixelPacket
+ *q;
+
+ register long
+ x;
+
+ double
+ x_distance,
+ y_distance,
+ distance;
+
+ ViewInfo
+ *image_view;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_SwirlImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ image_view=AccessDefaultCacheView(image);
+ q=SetImagePixelsEx(swirl_image,0,y,swirl_image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ y_distance=y_scale*(y-y_center);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ /*
+ Determine if the pixel is within an ellipse.
+ */
+ x_distance=x_scale*(x-x_center);
+ distance=x_distance*x_distance+y_distance*y_distance;
+ if (distance >= (radius*radius))
+ (void) AcquireOneCacheViewPixel(image_view,q,x,y,exception);
+ else
+ {
+ double
+ cosine,
+ factor,
+ sine;
+
+ /*
+ Swirl the pixel.
+ */
+ factor=1.0-sqrt(distance)/radius;
+ sine=sin(degrees*factor*factor);
+ cosine=cos(degrees*factor*factor);
+ InterpolateViewColor(image_view,q,
+ (cosine*x_distance-sine*y_distance)/x_scale+x_center,
+ (sine*x_distance+cosine*y_distance)/y_scale+y_center,
+ exception);
+ }
+ q++;
+ }
+ if (!SyncImagePixelsEx(swirl_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_SwirlImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ SwirlImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ swirl_image->is_grayscale=image->is_grayscale;
+ return(swirl_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% W a v e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The WaveImage() filter creates a "ripple" effect in the image by shifting
+% the pixels vertically along a sine wave whose amplitude and wavelength
+% is specified by the given parameters.
+%
+% The format of the WaveImage method is:
+%
+% Image *WaveImage(const Image *image,const double amplitude,
+% const double wave_length,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o amplitude, frequency: Define the amplitude and wave_length of the
+% sine wave.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *WaveImage(const Image *image,const double amplitude,
+ const double wave_length,ExceptionInfo *exception)
+{
+#define WaveImageText "[%s] Wave..."
+
+ VirtualPixelMethod
+ virtual_pixel_method;
+
+ double
+ *sine_map;
+
+ Image
+ *wave_image;
+
+ long
+ y;
+
+ /*
+ Initialize wave image attributes.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ wave_image=CloneImage(image,image->columns,(long)
+ (image->rows+2.0*fabs(amplitude)),MagickFalse,exception);
+ if (wave_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ wave_image->storage_class=DirectClass;
+
+ /*
+ If background color is non-opaque, then initialize matte channel.
+ */
+ if ((wave_image->background_color.opacity != OpaqueOpacity) &&
+ (!wave_image->matte))
+ SetImageOpacity(wave_image,OpaqueOpacity);
+
+ /*
+ Allocate and initialize sine map.
+ */
+ {
+ register long
+ x;
+
+ sine_map=MagickAllocateMemory(double *,wave_image->columns*sizeof(double));
+ if (sine_map == (double *) NULL)
+ {
+ DestroyImage(wave_image);
+ ThrowImageException(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(OptionError,UnableToWaveImage));
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp parallel for schedule(static,256)
+#endif
+ for (x=0; x < (long) wave_image->columns; x++)
+ sine_map[x]=fabs(amplitude)+amplitude*sin((2*MagickPI*x)/wave_length);
+ }
+ /*
+ Set virtual pixel method.
+ */
+
+ virtual_pixel_method=GetImageVirtualPixelMethod(image);
+ if (virtual_pixel_method == UndefinedVirtualPixelMethod)
+ (void) SetImageVirtualPixelMethod(image,ConstantVirtualPixelMethod);
+ /*
+ Wave image.
+ */
+ {
+ MagickPassFail
+ status = MagickPass;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) wave_image->rows; y++)
+ {
+ register PixelPacket
+ *q;
+
+ register long
+ x;
+
+ ViewInfo
+ *image_view;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_WaveImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ image_view=AccessDefaultCacheView(image);
+ q=SetImagePixelsEx(wave_image,0,y,wave_image->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for (x=0; x < (long) wave_image->columns; x++)
+ {
+ InterpolateViewColor(image_view,&q[x],(double) x,
+ (double) y-sine_map[x],
+ exception);
+ }
+ if (!SyncImagePixelsEx(wave_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_WaveImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,wave_image->rows))
+ if (!MagickMonitorFormatted(row_count,wave_image->rows,exception,
+ WaveImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ /*
+ Restore virtual pixel method.
+ */
+ (void) SetImageVirtualPixelMethod(image,virtual_pixel_method);
+ MagickFreeMemory(sine_map);
+ wave_image->is_grayscale=(image->is_grayscale && IsGray(wave_image->background_color));
+ return(wave_image);
+}
diff --git a/magick/fx.h b/magick/fx.h
new file mode 100644
index 0000000..1810c4b
--- /dev/null
+++ b/magick/fx.h
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 2003-2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Image FX Methods.
+*/
+#ifndef _MAGICK_FX_H
+#define _MAGICK_FX_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport Image
+ *CharcoalImage(const Image *,const double,const double,ExceptionInfo *),
+ *ColorizeImage(const Image *,const char *,const PixelPacket,ExceptionInfo *),
+ *ImplodeImage(const Image *,const double,ExceptionInfo *),
+ *MorphImages(const Image *,const unsigned long,ExceptionInfo *),
+ *OilPaintImage(const Image *,const double,ExceptionInfo *),
+ *SteganoImage(const Image *,const Image *,ExceptionInfo *),
+ *StereoImage(const Image *,const Image *,ExceptionInfo *),
+ *SwirlImage(const Image *,double,ExceptionInfo *),
+ *WaveImage(const Image *,const double,const double,ExceptionInfo *);
+
+extern MagickExport MagickPassFail
+ ColorMatrixImage(Image *image,const unsigned int order,const double *matrix),
+ SolarizeImage(Image *,const double);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_FX_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/gem.c b/magick/gem.c
new file mode 100644
index 0000000..fc5fcc4
--- /dev/null
+++ b/magick/gem.c
@@ -0,0 +1,1006 @@
+/*
+% Copyright (C) 2003-2012 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% GGGG EEEEE M M %
+% G E MM MM %
+% G GG EEE M M M %
+% G G E M M %
+% GGGG EEEEE M M %
+% %
+% %
+% Graphic Gems - Graphic Support Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% August 1996 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/gem.h"
+#include "magick/random-private.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o n s t r a s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Contrast enhances the intensity differences between the lighter
+% and darker elements of the image.
+%
+% The format of the Contrast method is:
+%
+% void Contrast(const int sign,Quantum *red,Quantum *green,Quantum *blue)
+%
+% A description of each parameter follows:
+%
+% o sign: A positive value enhances the contrast otherwise it is reduced.
+%
+% o red, green, blue: A pointer to a pixel component of type Quantum.
+%
+%
+*/
+MagickExport void Contrast(const int sign,Quantum *red,Quantum *green,
+ Quantum *blue)
+{
+ static const double
+ alpha=0.5+MagickEpsilon;
+
+ double
+ brightness,
+ hue,
+ saturation;
+
+ /*
+ Enhance contrast: dark color become darker, light color become lighter.
+ */
+ assert(red != (Quantum *) NULL);
+ assert(green != (Quantum *) NULL);
+ assert(blue != (Quantum *) NULL);
+ TransformHSL(*red,*green,*blue,&hue,&saturation,&brightness);
+ brightness+=
+ alpha*sign*(alpha*(sin(MagickPI*(brightness-alpha))+1.0)-brightness);
+ if (brightness > 1.0)
+ brightness=1.0;
+ if (brightness < 0.0)
+ brightness=0.0;
+ HSLTransform(hue,saturation,brightness,red,green,blue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x p a n d A f f i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ExpandAffine computes the affine's expansion factor, i.e. the
+% square root of the factor by which the affine transform affects area. In an
+% affine transform composed of scaling, rotation, shearing, and translation,
+% returns the amount of scaling.
+%
+% The format of the ExpandAffine method is:
+%
+% double ExpandAffine(const AffineMatrix *affine)
+%
+% A description of each parameter follows:
+%
+% o expansion: Method ExpandAffine returns the affine's expansion factor.
+%
+% o affine: A pointer the the affine transform of type AffineMatrix.
+%
+%
+*/
+MagickExport double ExpandAffine(const AffineMatrix *affine)
+{
+ double
+ expand;
+
+ assert(affine != (const AffineMatrix *) NULL);
+ expand=fabs(affine->sx*affine->sy)-fabs(affine->rx*affine->ry);
+ if (fabs(expand) < MagickEpsilon)
+ return(1.0);
+ return(sqrt(fabs(expand)));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e n e r a t e D i f f e r e n t i a l N o i s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GenerateDifferentialNoise generates a differential floating-point
+% noise value which will produce the final result when added to the
+% original pixel. The floating point differential value is useful since
+% it allows scaling without loss of precision and avoids clipping.
+%
+% The format of the GenerateDifferentialNoise method is:
+%
+% double GenerateDifferentialNoise(const Quantum pixel,
+% const NoiseType noise_type,
+% MagickRandomKernel *kernel)
+%
+% A description of each parameter follows:
+%
+% o pixel: A structure of type Quantum.
+%
+% o noise_type: The type of noise: Uniform, gaussian,
+% multiplicative Gaussian, impulse, laplacian, or Poisson.
+%
+% o kernel: Kernel for random number generator.
+%
+*/
+#define NoiseEpsilon 1.0e-5
+#define SigmaUniform 4.0
+#define SigmaGaussian 4.0
+#define SigmaImpulse 0.10
+#define SigmaLaplacian 10.0
+#define SigmaMultiplicativeGaussian 0.5
+#define SigmaPoisson 0.05
+#define TauGaussian 20.0
+
+MagickExport double GenerateDifferentialNoise(const Quantum quantum_pixel,
+ const NoiseType noise_type,
+ MagickRandomKernel *kernel)
+{
+ double
+ alpha,
+ beta,
+ pixel,
+ sigma,
+ value;
+
+ pixel=(double) quantum_pixel;
+
+#if QuantumDepth > 8
+ pixel /= MaxRGBDouble/255.0;
+#endif
+
+ alpha=MagickRandomRealInlined(kernel);
+ if (alpha == 0.0)
+ alpha=1.0;
+ switch (noise_type)
+ {
+ case UniformNoise:
+ default:
+ {
+ value=SigmaUniform*(alpha-0.5);
+ break;
+ }
+ case GaussianNoise:
+ {
+ double
+ tau;
+
+ beta=MagickRandomRealInlined(kernel);
+ sigma=sqrt(-2.0*log(alpha))*cos(2.0*MagickPI*beta);
+ tau=sqrt(-2.0*log(alpha))*sin(2.0*MagickPI*beta);
+ value=sqrt((double) pixel)*SigmaGaussian*sigma+TauGaussian*tau;
+ break;
+ }
+ case MultiplicativeGaussianNoise:
+ {
+ if (alpha <= NoiseEpsilon)
+ sigma=255.0;
+ else
+ sigma=sqrt(-2.0*log(alpha));
+ beta=MagickRandomRealInlined(kernel);
+ value=pixel*SigmaMultiplicativeGaussian*sigma*cos(2.0*MagickPI*beta);
+ break;
+ }
+ case ImpulseNoise:
+ {
+ if (alpha < (SigmaImpulse/2.0))
+ value=-pixel;
+ else
+ if (alpha >= (1.0-(SigmaImpulse/2.0)))
+ value=255.0-pixel;
+ else
+ value=0.0;
+ break;
+ }
+ case LaplacianNoise:
+ {
+ if (alpha <= 0.5)
+ {
+ if (alpha <= NoiseEpsilon)
+ value=-255.0;
+ else
+ value=SigmaLaplacian*log(2.0*alpha);
+ break;
+ }
+ beta=1.0-alpha;
+ if (beta <= (0.5*NoiseEpsilon))
+ value=255.0;
+ else
+ value=-(SigmaLaplacian*log(2.0*beta));
+ break;
+ }
+ case PoissonNoise:
+ {
+ double
+ limit;
+
+ register long
+ i;
+
+ limit=exp(-SigmaPoisson*(double) pixel);
+ for (i=0; alpha > limit; i++)
+ {
+ beta=MagickRandomRealInlined(kernel);
+ alpha=alpha*beta;
+ }
+ value=pixel-((double) i/SigmaPoisson);
+ break;
+ }
+ case RandomNoise:
+ {
+ /* Range is approximately -MaxRGB/2.0 to +MaxRGB/2.0 */
+ value=257.0*(0.5-MagickRandomRealInlined(kernel));
+ break;
+ }
+ }
+ /* printf("value = %g\n",value); */
+
+#if QuantumDepth > 8
+ value *= (MaxRGBFloat/255.0);
+#endif
+
+ return value;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e n e r a t e N o i s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GenerateNoise adds noise to a pixel.
+%
+% The format of the GenerateNoise method is:
+%
+% Quantum GenerateNoise(const Quantum pixel,const NoiseType noise_type)
+%
+% A description of each parameter follows:
+%
+% o pixel: A structure of type Quantum.
+%
+% o noise_type: The type of noise: Uniform, gaussian,
+% multiplicative Gaussian, impulse, laplacian, or Poisson.
+%
+%
+*/
+MagickExport Quantum GenerateNoise(const Quantum pixel,
+ const NoiseType noise_type)
+{
+ double
+ value;
+
+ value=(double) pixel+GenerateDifferentialNoise(pixel,noise_type,
+ AcquireMagickRandomKernel());
+ return (RoundDoubleToQuantum(value));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t O p t i m a l K e r n e l W i d t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetOptimalKernelWidth computes the optimal kernel radius for a
+% convolution filter. Start with the minimum value of 3 pixels and walk out
+% until we drop below the threshold of one pixel numerical accuracy,
+%
+% The format of the GetOptimalKernelWidth method is:
+%
+% int GetOptimalKernelWidth(const double radius,const double sigma)
+%
+% A description of each parameter follows:
+%
+% o width: Method GetOptimalKernelWidth returns the optimal width of
+% a convolution kernel.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+%
+*/
+
+MagickExport int GetOptimalKernelWidth1D(const double radius,const double sigma)
+{
+ double
+ epsilon,
+ normalize,
+ value;
+
+ long
+ width;
+
+ register long
+ u;
+
+ if (radius > 0.0)
+ return((int) (2.0*ceil(radius)+1.0));
+ epsilon=1.0/MaxRGBDouble;
+ if (epsilon < MagickEpsilon)
+ epsilon=MagickEpsilon;
+ for (width=5; ;)
+ {
+ normalize=0.0;
+ for (u=(-width/2); u <= (width/2); u++)
+ normalize+=exp(-((double) u*u)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma);
+ u=width/2;
+ value=exp(-((double) u*u)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma)/normalize;
+ if (value < epsilon)
+ break;
+ width+=2;
+ }
+ return(width-2);
+}
+
+MagickExport int GetOptimalKernelWidth2D(const double radius,const double sigma)
+{
+ double
+ alpha,
+ epsilon,
+ normalize,
+ value;
+
+ long
+ width;
+
+ register long
+ u,
+ v;
+
+ if (radius > 0.0)
+ return((int) (2.0*ceil(radius)+1.0));
+ epsilon=1.0/MaxRGBDouble;
+ if (epsilon < MagickEpsilon)
+ epsilon=MagickEpsilon;
+ for (width=5; ;)
+ {
+ normalize=0.0;
+ for (v=(-width/2); v <= (width/2); v++)
+ {
+ for (u=(-width/2); u <= (width/2); u++)
+ {
+ alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
+ normalize+=alpha/(2.0*MagickPI*sigma*sigma);
+ }
+ }
+ v=width/2;
+ value=exp(-((double) v*v)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma)/normalize;
+ if (value < epsilon)
+ break;
+ width+=2;
+ }
+ return(width-2);
+}
+
+MagickExport int GetOptimalKernelWidth(const double radius,const double sigma)
+{
+ return(GetOptimalKernelWidth1D(radius,sigma));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H S L T r a n s f o r m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method HSLTransform converts a floating point (hue, saturation,
+% luminosity) with range 0.0 to 1.0 to a (red, green, blue) triple
+% with range 0 to MaxRGB.
+%
+% The format of the HSLTransformImage method is:
+%
+% void HSLTransform(const double hue,const double saturation,
+% const double luminosity,Quantum *red,Quantum *green,Quantum *blue)
+%
+% A description of each parameter follows:
+%
+% o hue, saturation, luminosity: A double value representing a
+% component of the HSL color space.
+%
+% o red, green, blue: A pointer to a pixel component of type Quantum.
+%
+%
+*/
+MagickExport void HSLTransform(const double hue,const double saturation,
+ const double luminosity,Quantum *red,Quantum *green,Quantum *blue)
+{
+ /*
+ Convert HSL to RGB colorspace.
+ */
+ assert(red != (Quantum *) NULL);
+ assert(green != (Quantum *) NULL);
+ assert(blue != (Quantum *) NULL);
+ if (saturation == 0.0)
+ {
+ double l = MaxRGBDouble*luminosity;
+ *red=*green=*blue= RoundDoubleToQuantum(l);
+ }
+ else
+ {
+ double
+ b,
+ g,
+ r,
+ v,
+ x,
+ y,
+ z,
+ hue_times_six,
+ hue_fract,
+ vsf;
+
+ int
+ sextant;
+
+ v=(luminosity <= 0.5) ? (luminosity*(1.0+saturation)) :
+ (luminosity+saturation-luminosity*saturation);
+
+ hue_times_six=6.0*hue;
+ sextant=(int) hue_times_six;
+ hue_fract=hue_times_six-(double) sextant;
+
+ y=luminosity+luminosity-v;
+ vsf=(v-y)*hue_fract;
+ x=y+vsf;
+ z=v-vsf;
+
+ switch (sextant)
+ {
+ case 0: r=v; g=x; b=y; break;
+ case 1: r=z; g=v; b=y; break;
+ case 2: r=y; g=v; b=x; break;
+ case 3: r=y; g=z; b=v; break;
+ case 4: r=x; g=y; b=v; break;
+ case 5: r=v; g=y; b=z; break;
+ default: r=v; g=x; b=y; break;
+ }
+ r *= MaxRGBDouble;
+ *red=RoundDoubleToQuantum(r);
+ g *= MaxRGBDouble;
+ *green=RoundDoubleToQuantum(g);
+ b *= MaxRGBDouble;
+ *blue=RoundDoubleToQuantum(b);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H W B T r a n s f o r m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method HWBTransform converts a (hue, whiteness, blackness) to a
+% (red, green, blue) triple.
+%
+% Algorithm derived from "HWB: A more intuitive hue-based color model."
+% Alvy Ray Smith and Eric Ray Lyons, Journal of Graphics Tools, Volume 1
+% Number 1, 1996. http://www.acm.org/jgt/papers/SmithLyons96/
+%
+% The format of the HWBTransformImage method is:
+%
+% void HWBTransform(const double hue,const double whiteness,
+% const double blackness,Quantum *red,Quantum *green,Quantum *blue)
+%
+% A description of each parameter follows:
+%
+% o hue, whiteness, blackness: A double value representing a
+% component of the HWB color space.
+%
+% o red, green, blue: A pointer to a pixel component of type Quantum.
+%
+%
+*/
+MagickExport void HWBTransform(const double hue,const double whiteness,
+ const double blackness,Quantum *red,Quantum *green,Quantum *blue)
+{
+ double
+ b,
+ f,
+ g,
+ n,
+ r,
+ v;
+
+ register unsigned int
+ i;
+
+ /*
+ Convert HWB to RGB colorspace.
+ */
+ assert(red != (Quantum *) NULL);
+ assert(green != (Quantum *) NULL);
+ assert(blue != (Quantum *) NULL);
+ v=1.0-blackness;
+ if (hue == 0.0)
+ {
+ v *= MaxRGBDouble;
+ *red=*green=*blue=RoundDoubleToQuantum(v);
+ return;
+ }
+ i=(unsigned int) (6.0*hue);
+ f=6.0*hue-i;
+ if (i & 0x01)
+ f=1.0-f;
+ n=whiteness+f*(v-whiteness); /* linear interpolation */
+ switch (i)
+ {
+ default:
+ case 6:
+ case 0: r=v; g=n; b=whiteness; break;
+ case 1: r=n; g=v; b=whiteness; break;
+ case 2: r=whiteness; g=v; b=n; break;
+ case 3: r=whiteness; g=n; b=v; break;
+ case 4: r=n; g=whiteness; b=v; break;
+ case 5: r=v; g=whiteness; b=n; break;
+ }
+ r *= MaxRGBDouble;
+ g *= MaxRGBDouble;
+ b *= MaxRGBDouble;
+ *red=RoundDoubleToQuantum(r);
+ *green=RoundDoubleToQuantum(g);
+ *blue=RoundDoubleToQuantum(b);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H u l l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Hull implements the eight hull algorithm described in Applied
+% Optics, Vol. 24, No. 10, 15 May 1985, "Geometric filter for Speckle
+% Reduction", by Thomas R Crimmins. Each pixel in the image is replaced by
+% one of its eight of its surrounding pixels using a polarity and negative
+% hull function.
+%
+% The format of the Hull method is:
+%
+% void Hull(const long x_offset,const long y_offset,
+% const unsigned long columns,const unsigned long rows,Quantum *f,
+% Quantum *g,const int polarity)
+%
+% A description of each parameter follows:
+%
+% o x_offset, y_offset: An integer value representing the offset of the
+% current pixel within the image.
+%
+% o columns, rows: Specifies the number of rows and columns in the image.
+%
+% o polarity: An integer value declaring the polarity (+,-).
+%
+% o f, g: A pointer to an image pixel and one of it's neighbor.
+%
+%
+*/
+
+MagickExport void Hull(const long x_offset,const long y_offset,
+ const unsigned long columns,const unsigned long rows,Quantum *f,Quantum *g,
+ const int polarity)
+{
+#if QuantumDepth > 16
+ typedef double SignedQuantum;
+#else
+ typedef int SignedQuantum;
+#endif
+
+ long
+ y;
+
+ Quantum
+ *p,
+ *q,
+ *r,
+ *s;
+
+ assert(f != (Quantum *) NULL);
+ assert(g != (Quantum *) NULL);
+ p=f+(columns+2);
+ q=g+(columns+2);
+ r=p+(y_offset*((long) columns+2)+x_offset);
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static)
+# else
+# pragma omp parallel for schedule(guided)
+# endif
+# endif
+#endif
+ for (y=0; y < (long) rows; y++)
+ {
+ SignedQuantum
+ v;
+
+ unsigned long
+ x;
+
+ unsigned int
+ index;
+
+ index=(2*y+1)+y*columns;
+ if (polarity > 0)
+ {
+ for (x=columns ; x != 0; x--)
+ {
+ v=(p[index]);
+ if (r[index] >= (v+ScaleCharToQuantum(2)))
+ v+=ScaleCharToQuantum(1);
+ q[index]=(Quantum) v;
+ index++;
+ }
+ }
+ else
+ {
+ for (x=columns ; x != 0; x--)
+ {
+ v=(p[index]);
+ if (r[index] <= (v-(long) ScaleCharToQuantum(2)))
+ v-=(long) ScaleCharToQuantum(1);
+ q[index]=(Quantum) v;
+ index++;
+ }
+ }
+ }
+ p=f+(columns+2);
+ q=g+(columns+2);
+ r=q+(y_offset*((long) columns+2)+x_offset);
+ s=q-(y_offset*((long) columns+2)+x_offset);
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static)
+# else
+# pragma omp parallel for schedule(guided)
+# endif
+# endif
+#endif
+ for (y=0; y < (long) rows; y++)
+ {
+ SignedQuantum
+ v;
+
+ unsigned long
+ x;
+
+ unsigned int
+ index;
+
+ index=(2*y+1)+y*columns;
+ if (polarity > 0)
+ {
+ for (x=columns ; x != 0; x--)
+ {
+ v=(q[index]);
+ if ((s[index] >= (v+ScaleCharToQuantum(2))) && (r[index] > v))
+ v+=ScaleCharToQuantum(1);
+ p[index]=(Quantum) v;
+ index++;
+ }
+ }
+ else
+ {
+ for (x=columns ; x != 0; x--)
+ {
+ v=(q[index]);
+ if ((s[index] <= (v-(long) ScaleCharToQuantum(2))) && (r[index] < v))
+ v-=(long) ScaleCharToQuantum(1);
+ p[index]=(Quantum) v;
+ index++;
+ }
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I d e n t i t y A f f i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IdentityAffine initializes the affine transform to the identity
+% matrix.
+%
+% The format of the IdentityAffine method is:
+%
+% IdentityAffine(AffineMatrix *affine)
+%
+% A description of each parameter follows:
+%
+% o affine: A pointer the the affine transform of type AffineMatrix.
+%
+%
+*/
+MagickExport void IdentityAffine(AffineMatrix *affine)
+{
+ assert(affine != (AffineMatrix *) NULL);
+ (void) memset(affine,0,sizeof(AffineMatrix));
+ affine->sx=1.0;
+ affine->sy=1.0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o d u l a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Modulate modulates the hue, saturation, and brightness of an
+% image. Brightness and saturation are expressed as a ratio of the
+% existing value. Hue is expressed as a ratio of rotation from the current
+% position in that 1.0 results in the existing position, 0.5 results in a
+% counter-clockwise rotation of 90 degrees, 1.5 results in a clockwise
+% rotation of 90 degrees, and 0 and 2.0 obtain a 180 degree rotation.
+%
+% The format of the Modulate method is:
+%
+% void Modulate(const double percent_hue,const double percent_saturation,
+% const double percent_brightness,Quantum *red,Quantum *green,
+% Quantum *blue)
+%
+% A description of each parameter follows:
+%
+% o percent_hue, percent_saturation, percent_brightness: A double value
+% representing the percent change in a component of the HSL color space.
+%
+% o red, green, blue: A pointer to a pixel component of type Quantum.
+%
+%
+*/
+MagickExport void Modulate(const double percent_hue,
+ const double percent_saturation,const double percent_brightness,
+ Quantum *red,Quantum *green,Quantum *blue)
+{
+ double
+ brightness,
+ hue,
+ saturation;
+
+ /*
+ Increase or decrease color brightness, saturation, or hue.
+ */
+ assert(red != (Quantum *) NULL);
+ assert(green != (Quantum *) NULL);
+ assert(blue != (Quantum *) NULL);
+ TransformHSL(*red,*green,*blue,&hue,&saturation,&brightness);
+ brightness*=(0.01+MagickEpsilon)*percent_brightness;
+ if (brightness > 1.0)
+ brightness=1.0;
+ saturation*=(0.01+MagickEpsilon)*percent_saturation;
+ if (saturation > 1.0)
+ saturation=1.0;
+
+ hue += (percent_hue/200.0 - 0.5);
+ while (hue < 0.0)
+ hue += 1.0;
+ while (hue > 1.0)
+ hue -= 1.0;
+ HSLTransform(hue,saturation,brightness,red,green,blue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T r a n s f o r m H S L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method TransformHSL converts a (red, green, blue) to a (hue, saturation,
+% luminosity) triple with values in range 0.0 to 1.0.
+%
+% The format of the TransformHSL method is:
+%
+% void TransformHSL(const Quantum red,const Quantum green,
+% const Quantum blue,double *hue,double *saturation,double *luminosity)
+%
+% A description of each parameter follows:
+%
+% o red, green, blue: A Quantum value representing the red, green, and
+% blue component of a pixel..
+%
+% o hue, saturation, luminosity: A pointer to a double value representing a
+% component of the HSL color space.
+%
+%
+*/
+MagickExport void TransformHSL(const Quantum red,const Quantum green,
+ const Quantum blue,double *hue_result,double *saturation_result,double *luminosity_result)
+{
+ double
+ hue,
+ saturation,
+ luminosity,
+ b,
+ delta,
+ g,
+ max,
+ min,
+ r;
+
+ /*
+ Convert RGB to HSL colorspace.
+ */
+ assert(hue_result != (double *) NULL);
+ assert(saturation_result != (double *) NULL);
+ assert(luminosity_result != (double *) NULL);
+
+ r=(double) red/MaxRGBDouble;
+ g=(double) green/MaxRGBDouble;
+ b=(double) blue/MaxRGBDouble;
+ max=Max(r,Max(g,b));
+ min=Min(r,Min(g,b));
+ hue=0.0;
+ saturation=0.0;
+ luminosity=(min+max)/2.0;
+ delta=max-min;
+ if (delta != 0.0)
+ {
+ saturation=delta/((luminosity <= 0.5) ? (min+max) : (2.0-max-min));
+ if (r == max)
+ hue=(g == min ? 5.0+(max-b)/delta : 1.0-(max-g)/delta);
+ else
+ if (g == max)
+ hue=(b == min ? 1.0+(max-r)/delta : 3.0-(max-b)/delta);
+ else
+ hue=(r == min ? 3.0+(max-g)/delta : 5.0-(max-r)/delta);
+ hue/=6.0;
+ }
+
+ *hue_result=ConstrainToRange(0.0,1.0,hue);
+ *saturation_result=ConstrainToRange(0.0,1.0,saturation);
+ *luminosity_result=ConstrainToRange(0.0,1.0,luminosity);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T r a n s f o r m H W B %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method TransformHWB converts a (red, green, blue) to a
+% (hue, whiteness, blackness) triple.
+%
+% Algorithm derived from "HWB: A more intuitive hue-based color model."
+% Alvy Ray Smith and Eric Ray Lyons, Journal of Graphics Tools, Volume 1
+% Number 1, 1996. http://www.acm.org/jgt/papers/SmithLyons96/
+%
+% The format of the TransformHWB method is:
+%
+% void TransformHWB(const Quantum red,const Quantum green,
+% const Quantum blue,double *hue,double *whiteness,double *blackness)
+%
+% A description of each parameter follows:
+%
+% o red, green, blue: A Quantum value representing the red, green, and
+% blue component of a pixel.
+%
+% o hue, whiteness, blackness: A pointer to a double value representing a
+% component of the HWB color space.
+%
+%
+*/
+MagickExport void TransformHWB(const Quantum red,const Quantum green, const Quantum blue,
+ double *hue,double *whiteness,double *blackness)
+{
+ double
+ f,
+ v,
+ w;
+
+ register long
+ i;
+
+ /*
+ Convert RGB to HWB colorspace.
+ */
+ assert(hue != (double *) NULL);
+ assert(whiteness != (double *) NULL);
+ assert(blackness != (double *) NULL);
+ w=(double) Min(red,Min(green,blue));
+ v=(double) Max(red,Max(green,blue));
+ *blackness=((double) MaxRGBDouble-v)/MaxRGBDouble;
+ if (v == w)
+ {
+ *hue=0.0;
+ *whiteness=1.0-(*blackness);
+ }
+ else
+ {
+ f=(red == w) ? (double) green-blue :
+ ((green == w) ? (double) blue-red :
+ (double) red-green);
+ i=(red == w) ? 3 : ((green == w) ? 5 : 1);
+ *hue=((double) i-f/(v-w))/6.0;
+ *whiteness=((double) w/MaxRGBDouble);
+ }
+}
diff --git a/magick/gem.h b/magick/gem.h
new file mode 100644
index 0000000..b6c5d89
--- /dev/null
+++ b/magick/gem.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2003-2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Graphic Gems - Graphic Support Methods.
+*/
+#ifndef _MAGICK_GEM_H
+#define _MAGICK_GEM_H
+
+#include "magick/random.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Graphic gems define declarations.
+*/
+extern MagickExport double
+ ExpandAffine(const AffineMatrix *),
+ GenerateDifferentialNoise(const Quantum pixel,const NoiseType noise_type,
+ MagickRandomKernel *kernel);
+
+extern MagickExport int
+ GetOptimalKernelWidth(const double,const double),
+ GetOptimalKernelWidth1D(const double,const double),
+ GetOptimalKernelWidth2D(const double,const double);
+
+
+extern MagickExport Quantum
+ GenerateNoise(const Quantum,const NoiseType);
+
+extern MagickExport void
+ Contrast(const int,Quantum *,Quantum *,Quantum *),
+ HSLTransform(const double,const double,const double,Quantum *,Quantum *,
+ Quantum *),
+ HWBTransform(const double,const double,const double,Quantum *,Quantum *,
+ Quantum *),
+ Hull(const long,const long,const unsigned long,const unsigned long,Quantum *,
+ Quantum *,const int),
+ IdentityAffine(AffineMatrix *),
+ Modulate(const double,const double,const double,Quantum *,Quantum *,
+ Quantum *),
+ TransformHSL(const Quantum,const Quantum,const Quantum,double *,double *,
+ double *),
+ TransformHWB(const Quantum,const Quantum,const Quantum,double *,double *,
+ double *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/gradient.c b/magick/gradient.c
new file mode 100644
index 0000000..0e47133
--- /dev/null
+++ b/magick/gradient.c
@@ -0,0 +1,142 @@
+/*
+% Copyright (C) 2003 - 2014 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% GraphicsMagick Gradient Image Methods.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/color.h"
+#include "magick/gradient.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
++ G r a d i e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GradientImage() applies a continuously smooth color transitions along a
+% vector from one color to another.
+%
+% Note, the interface of this method will change in the future to support
+% more than one transistion.
+%
+% The format of the GradientImage method is:
+%
+% MagickPassFail GradientImage(Image *image,
+% const PixelPacket *start_color,
+% const PixelPacket *stop_color)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o start_color: The start color.
+%
+% o stop_color: The stop color.
+%
+%
+*/
+
+#define GradientImageText "[%s] Gradient..."
+MagickExport MagickPassFail GradientImage(Image *image,
+ const PixelPacket *start_color,
+ const PixelPacket *stop_color)
+{
+ const unsigned long
+ image_rows=image->rows,
+ image_columns=image->columns;
+
+ long
+ y;
+
+ unsigned long
+ row_count=0;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Determine (Hue, Saturation, Brightness) gradient.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(start_color != (const PixelPacket *) NULL);
+ assert(stop_color != (const PixelPacket *) NULL);
+
+ /*
+ Generate gradient pixels.
+ */
+#if defined(HAVE_OPENMP)
+# pragma omp parallel for shared(row_count, status)
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ MagickPassFail
+ thread_status;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GradientImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ q=SetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (q != (PixelPacket *) NULL)
+ {
+ for (x=0; x < (long) image->columns; x++)
+ {
+ BlendCompositePixel(&q[x],start_color,stop_color,(double)
+ MaxRGB*(y*image_columns+x)/(image_columns*image_rows));
+ }
+
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GradientImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,&image->exception,
+ GradientImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ if (IsGray(*start_color) && IsGray(*stop_color))
+ image->is_grayscale=MagickTrue;
+ if (IsMonochrome(*start_color) && ColorMatch(start_color,stop_color))
+ image->is_monochrome=MagickTrue;
+ return(status);
+}
diff --git a/magick/gradient.h b/magick/gradient.h
new file mode 100644
index 0000000..39181a1
--- /dev/null
+++ b/magick/gradient.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Gradient Image Methods.
+*/
+#ifndef _MAGICK_GRADIENT_H
+#define _MAGICK_GRADIENT_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/image.h"
+
+extern MagickExport MagickPassFail
+ GradientImage(Image *,const PixelPacket *,const PixelPacket *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_GRADIENT_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/hclut.c b/magick/hclut.c
new file mode 100644
index 0000000..7d6eba1
--- /dev/null
+++ b/magick/hclut.c
@@ -0,0 +1,273 @@
+/*
+% Copyright (C) 2009 GraphicsMagick Group
+% Copyright (C) 2005 Eskil Steenberg. All rights reserved.
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/hclut.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% H a l d C l u t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The HaldClutImage() method apply a color lookup table (Hald CLUT) to the
+% image. The fundamental principle of the Hald CLUT algorithm is that
+% application of an identity CLUT causes no change to the input image,
+% but an identity CLUT image which has had its colors transformed in
+% some way (e.g. in Adobe Photoshop) may be used to implement an identical
+% transform on any other image.
+%
+% The minimum CLUT level is 2, and the maximum depends on available memory
+% (largest successfully tested is 24). A CLUT image is required to have equal
+% width and height. A CLUT of level 8 is an image of dimension 512x512, a CLUT
+% of level 16 is an image of dimension 4096x4096. Interpolation is used so
+% extremely large CLUT images are not required.
+%
+% GraphicsMagick provides an 'identity' coder which may be used to generate
+% identity HLUTs. For example, reading from "identity:8" creates an identity
+% CLUT of order 8.
+%
+% The Hald CLUT algorithm has been developed by Eskil Steenberg as described
+% at http://www.quelsolaar.com/technology/clut.html, and was adapted for
+% GraphicsMagick by Clment Follet with support from Cdric Lejeune of
+% Workflowers.
+%
+% The format of the HaldClutImage method is:
+%
+% MagickPassFail HaldClutImage(Image *image,const Image *clut)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o clut: The color lookup table image
+%
+%
+*/
+
+typedef struct _HaldClutImageParameters_t
+{
+ unsigned int
+ level;
+
+ const PixelPacket
+ *ppcl;
+
+} HaldClutImageParameters_t;
+
+static MagickPassFail
+HaldClutImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+
+ const HaldClutImageParameters_t *
+ param = (const HaldClutImageParameters_t *) immutable_data;
+
+ unsigned int
+ level = param->level;
+
+ const PixelPacket
+ *clut = param->ppcl;
+
+ unsigned int
+ color;
+
+ unsigned int
+ blueaxis,
+ greenaxis,
+ redaxis;
+
+ register long
+ i,
+ k;
+
+ double
+ sums[9],
+ r,
+ g,
+ b,
+ value;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ level *= level;
+
+ for(k = 0; k < npixels ; k++)
+ {
+ /*
+ Calculate the position of each 3D axis pixel level.
+ */
+ redaxis = (unsigned int) (((double) pixels[k].red/MaxRGBDouble) * (level-1));
+ if (redaxis > level - 2)
+ redaxis = level - 2;
+ greenaxis = (unsigned int) (((double) pixels[k].green/MaxRGBDouble) * (level-1));
+ if(greenaxis > level - 2)
+ greenaxis = level - 2;
+ blueaxis = (unsigned int) (((double) pixels[k].blue/MaxRGBDouble) * (level-1));
+ if(blueaxis > level - 2)
+ blueaxis = level - 2;
+
+ /*
+ Convert between the value and the equivalent value position.
+ */
+ r = ((double) pixels[k].red/MaxRGBDouble) * (level - 1) - redaxis;
+ g = ((double) pixels[k].green/MaxRGBDouble) * (level - 1) - greenaxis;
+ b = ((double) pixels[k].blue/MaxRGBDouble) * (level - 1) - blueaxis;
+
+ color = redaxis + greenaxis * level + blueaxis * level * level;
+
+ i = color;
+ sums[0] = ((double) clut[i].red) * (1 - r);
+ sums[1] = ((double) clut[i].green) * (1 - r);
+ sums[2] = ((double) clut[i].blue) * (1 - r);
+ i++;
+ sums[0] += ((double) clut[i].red) * r;
+ sums[1] += ((double) clut[i].green) * r;
+ sums[2] += ((double) clut[i].blue) * r;
+
+ i = (color + level);
+ sums[3] = ((double) clut[i].red) * (1 - r);
+ sums[4] = ((double) clut[i].green) * (1 - r);
+ sums[5] = ((double) clut[i].blue) * (1 - r);
+ i++;
+ sums[3] += ((double) clut[i].red) * r;
+ sums[4] += ((double) clut[i].green) * r;
+ sums[5] += ((double) clut[i].blue) * r;
+
+ sums[6] = sums[0] * (1 - g) + sums[3] * g;
+ sums[7] = sums[1] * (1 - g) + sums[4] * g;
+ sums[8] = sums[2] * (1 - g) + sums[5] * g;
+
+ i = (color + level * level);
+ sums[0] = ((double) clut[i].red) * (1 - r);
+ sums[1] = ((double) clut[i].green) * (1 - r);
+ sums[2] = ((double) clut[i].blue) * (1 - r);
+ i++;
+ sums[0] += ((double) clut[i].red) * r;
+ sums[1] += ((double) clut[i].green) * r;
+ sums[2] += ((double) clut[i].blue) * r;
+
+ i = (color + level * level + level);
+ sums[3] = ((double) clut[i].red) * (1 - r);
+ sums[4] = ((double) clut[i].green) * (1 - r);
+ sums[5] = ((double) clut[i].blue) * (1 - r);
+ i++;
+ sums[3] += ((double) clut[i].red) * r;
+ sums[4] += ((double) clut[i].green) * r;
+ sums[5] += ((double) clut[i].blue) * r;
+
+ sums[0] = sums[0] * (1 - g) + sums[3] * g;
+ sums[1] = sums[1] * (1 - g) + sums[4] * g;
+ sums[2] = sums[2] * (1 - g) + sums[5] * g;
+
+ value=(sums[6] * (1 - b) + sums[0] * b);
+ pixels[k].red = RoundDoubleToQuantum(value);
+
+ value=(sums[7] * (1 - b) + sums[1] * b);
+ pixels[k].green = RoundDoubleToQuantum(value);
+
+ value=(sums[8] * (1 - b) + sums[2] * b);
+ pixels[k].blue = RoundDoubleToQuantum(value);
+ }
+
+ return MagickPass;
+}
+
+
+MagickExport MagickPassFail
+HaldClutImage(Image *image, const Image *clut)
+{
+ unsigned int
+ level;
+
+ char
+ progress_message[MaxTextExtent];
+
+ HaldClutImageParameters_t
+ param;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ /*
+ Hald CLUT images are square.
+ */
+ if(clut->rows != clut->columns)
+ {
+ ThrowBinaryException(OptionError,HaldClutImageDimensionsInvalid,
+ clut->filename);
+ }
+
+ /*
+ Calculate the level of the Hald CLUT
+ */
+ for(level = 1; level * level * level < clut->rows; level++);
+ if((level * level * level > clut->rows) || (level < 2))
+ {
+ ThrowBinaryException(OptionError,HaldClutImageDimensionsInvalid,
+ clut->filename);
+ }
+
+ param.level = level;
+
+ /*
+ We acquire all of the pixels at once, which is the limiting factor
+ on maximum Hald CLUT size.
+ */
+ param.ppcl=AcquireImagePixels(clut,0,0,clut->columns,clut->rows,&image->exception);
+ if (param.ppcl == (const PixelPacket *) NULL)
+ return MagickFail;
+
+ FormatString(progress_message,
+ "[%%s] Applying Hald CLUT level %u (%lux%lu) ...",
+ param.level,clut->columns,clut->rows);
+
+ if (!IsRGBCompatibleColorspace(image->colorspace))
+ TransformColorspace(image,RGBColorspace);
+ if (image->storage_class == PseudoClass)
+ {
+ (void) HaldClutImagePixels(NULL,&param,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status=SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(HaldClutImagePixels,NULL,progress_message,
+ NULL,&param,0,0,image->columns,image->rows,
+ image,&image->exception);
+ }
+
+ return(status);
+}
+
diff --git a/magick/hclut.h b/magick/hclut.h
new file mode 100644
index 0000000..d1858d7
--- /dev/null
+++ b/magick/hclut.h
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2009 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Hald CLUT implementation
+
+*/
+#ifndef _MAGICK_HCLUT_H
+#define _MAGICK_HCLUT_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport MagickPassFail
+ HaldClutImage(Image *,const Image * clut);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_HCLUT_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/image.c b/magick/image.c
new file mode 100644
index 0000000..29593aa
--- /dev/null
+++ b/magick/image.c
@@ -0,0 +1,3480 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% IIIII M M AAA GGGG EEEEE %
+% I MM MM A A G E %
+% I M M M AAAAA G GG EEE %
+% I M M A A G G E %
+% IIIII M M A A GGGG EEEEE %
+% %
+% %
+% GraphicsMagick Image Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/channel.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/composite.h"
+#include "magick/compress.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/enum_strings.h"
+#include "magick/gem.h"
+#include "magick/log.h"
+#include "magick/magic.h"
+#include "magick/magick.h"
+#include "magick/map.h"
+#include "magick/monitor.h"
+#include "magick/module.h"
+#include "magick/omp_data_view.h"
+#include "magick/operator.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/quantize.h"
+#include "magick/render.h"
+#include "magick/random.h"
+#include "magick/profile.h"
+#include "magick/semaphore.h"
+#include "magick/signature.h"
+#include "magick/statistics.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#include "magick/xwindow.h"
+
+/*
+ Constant declaration.
+*/
+const char
+ *BackgroundColor = "#ffffffffffff", /* white */
+ *BorderColor = "#dfdfdfdfdfdf", /* gray */
+ *DefaultTileFrame = "15x15+3+3",
+ *DefaultTileGeometry = "120x120+4+3>",
+ *DefaultTileLabel = "%f\n%wx%h\n%b",
+ *ForegroundColor = "#000000000000", /* black */
+ *HighlightColor = "#f1f100001e1e", /* light red */
+ *MatteColor = "#bdbdbdbdbdbd", /* gray */
+ *PSDensityGeometry = "72.0x72.0",
+ *PSPageGeometry = "612x792>";
+
+const unsigned long
+ DefaultCompressionQuality = 75;
+
+static MagickPassFail
+MagickParseSubImageSpecification(const char *subimage_spec,
+ unsigned long *subimage_ptr,
+ unsigned long *subrange_ptr,
+ MagickBool allow_geometry);
+
+/* Round floating value to an integer */
+#define RndToInt(value) ((int)((value)+0.5))
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c c e s s D e f i n i t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AccessDefinition() searches the definitions for an entry matching the
+% specified magick and key. NULL is returned if no matching entry is found.
+%
+% The format of the AccessDefinition method is:
+%
+% const char *AccessDefinition(const ImageInfo *image_info,
+% const char *magick, const char *key)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o magick: Format ID. This is usually the same as the coder name.
+%
+% o key: Key to search for.
+%
+*/
+MagickExport const char *AccessDefinition(const ImageInfo *image_info,
+ const char *magick, const char *key)
+{
+ const char
+ *value = 0;
+
+ char
+ search_key[MaxTextExtent];
+
+ if (image_info->definitions)
+ {
+ FormatString(search_key, "%.60s:%.1024s", magick, key);
+ value=(const char*) MagickMapAccessEntry((MagickMap) image_info->definitions,search_key,0);
+ }
+ return value;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A d d D e f i n i t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AddDefinition() adds a key/value definition to the current map of
+% definitions in ImageInfo. Definitions may be used by coders/decoders
+% that read and write images.
+%
+% The format of the AddDefinition method is:
+%
+% MagickPassFail AddDefinition(ImageInfo *image_info,const char *magick,
+% const char *key, const char *value,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o magick: format/classification identifier
+%
+% o key: subidentifier within format/classification
+%
+% o value: definition value
+%
+% o exception: Errors result in updates to this structure.
+%
+*/
+MagickExport MagickPassFail
+AddDefinition(ImageInfo *image_info,const char *magick, const char *key,
+ const char *value, ExceptionInfo *exception)
+{
+ MagickPassFail
+ status = MagickFail;
+
+ char
+ search_key[MaxTextExtent];
+
+ if (image_info->definitions == 0)
+ image_info->definitions=MagickMapAllocateMap(MagickMapCopyString,
+ MagickMapDeallocateString);
+ if (image_info->definitions != 0)
+ {
+ /*
+ Format string like "magick:key"
+ */
+ FormatString(search_key, "%.60s:%.1024s", magick, key);
+
+ /*
+ Add entry to map
+ */
+ status = MagickMapAddEntry((MagickMap) image_info->definitions,search_key,value,0,exception);
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A d d D e f i n i t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AddDefinitions() adds definitions from a key/value based string to the current
+% map of definitions in ImageInfo. Definitions may be used by coders/decoders
+% that read and write images.
+%
+% The format of the AddDefinitions method is:
+%
+% MagickPassFail AddDefinitions(ImageInfo *image_info,const char *options)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o options: List of key/value pairs to put in the definitions map. The
+% format of the string is "key1[=[value1]],key2[=[value2]],...". A missing
+% value argument (with or without the equal sign) inserts an empty, zero
+% length string as value for a key.
+%
+% o exception: Errors result in updates to this structure.
+%
+*/
+MagickExport MagickPassFail
+AddDefinitions(ImageInfo *image_info,const char *definitions,
+ ExceptionInfo *exception)
+{
+ char
+ key[MaxTextExtent],
+ value[MaxTextExtent];
+
+ MagickPassFail
+ status;
+
+ unsigned int
+ i,
+ j;
+
+ size_t
+ length;
+
+ status=MagickPass;
+
+ if (image_info->definitions == 0)
+ image_info->definitions=MagickMapAllocateMap(MagickMapCopyString,
+ MagickMapDeallocateString);
+ if (image_info->definitions == 0)
+ return MagickFail;
+
+ length=strlen(definitions);
+ i=0;
+ while (i < length)
+ {
+ unsigned int
+ has_value;
+
+ for (j=0; (i < length) && (definitions[i] != '=') && (definitions[i] != ','); i++,j++)
+ key[j]=definitions[i];
+ key[j]='\0';
+ has_value=(i < length) && (definitions[i] == '='); /* Could be 0-length value */
+ i++;
+
+ j=0;
+ if (has_value)
+ {
+ for (; (i < length) && (definitions[i] != ','); i++,j++)
+ value[j]=definitions[i];
+ i++;
+ }
+ value[j]='\0';
+ if (strlen(key) != 0)
+ {
+ status &= MagickMapAddEntry((MagickMap) image_info->definitions,key,value,0,exception);
+ }
+ else
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A l l o c a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AllocateImage() returns a pointer to an image structure initialized to
+% default values.
+%
+% The format of the AllocateImage method is:
+%
+% Image *AllocateImage(const ImageInfo *image_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: Many of the image default values are set from this
+% structure. For example, filename, compression, depth, background color,
+% and others.
+%
+%
+*/
+MagickExport Image *AllocateImage(const ImageInfo *image_info)
+{
+ Image
+ *allocate_image;
+
+ /*
+ Allocate image structure.
+ */
+ allocate_image=MagickAllocateMemory(Image *,sizeof(Image));
+ if (allocate_image == (Image *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateImage);
+ (void) memset(allocate_image,0,sizeof(Image));
+ /*
+ Initialize Image structure.
+ */
+ (void) strcpy(allocate_image->magick,"MIFF");
+ allocate_image->storage_class=DirectClass;
+ allocate_image->depth=QuantumDepth;
+ allocate_image->interlace=NoInterlace;
+ allocate_image->colorspace=RGBColorspace;
+ allocate_image->compose=OverCompositeOp;
+ allocate_image->blur=1.0;
+ GetExceptionInfo(&allocate_image->exception);
+ (void) QueryColorDatabase(BackgroundColor,&allocate_image->background_color,
+ &allocate_image->exception);
+ (void) QueryColorDatabase(BorderColor,&allocate_image->border_color,
+ &allocate_image->exception);
+ (void) QueryColorDatabase(MatteColor,&allocate_image->matte_color,
+ &allocate_image->exception);
+ allocate_image->orientation=UndefinedOrientation;
+ GetTimerInfo(&allocate_image->timer);
+ GetCacheInfo(&allocate_image->cache);
+ allocate_image->blob=CloneBlobInfo((BlobInfo *) NULL);
+ allocate_image->logging=IsEventLogging();
+ allocate_image->is_monochrome=MagickTrue;
+ allocate_image->is_grayscale=MagickTrue;
+ allocate_image->semaphore=AllocateSemaphoreInfo();
+ LockSemaphoreInfo((SemaphoreInfo *) allocate_image->semaphore);
+ allocate_image->reference_count=1;
+ UnlockSemaphoreInfo((SemaphoreInfo *) allocate_image->semaphore);
+ allocate_image->signature=MagickSignature;
+ allocate_image->default_views=AllocateThreadViewSet(allocate_image,
+ &allocate_image->exception);
+ if (image_info == (ImageInfo *) NULL)
+ return(allocate_image);
+ /*
+ Transfer image info.
+ */
+ SetBlobClosable(allocate_image,(image_info->file == NULL));
+ (void) strlcpy(allocate_image->filename,image_info->filename,MaxTextExtent);
+ (void) strlcpy(allocate_image->magick_filename,image_info->filename,
+ MaxTextExtent);
+ (void) strlcpy(allocate_image->magick,image_info->magick,MaxTextExtent);
+ if (image_info->size != (char *) NULL)
+ {
+ (void) GetGeometry(image_info->size,
+ &allocate_image->tile_info.x,
+ &allocate_image->tile_info.y,
+ &allocate_image->columns,
+ &allocate_image->rows);
+ allocate_image->offset=allocate_image->tile_info.x;
+ allocate_image->tile_info.width=allocate_image->columns;
+ allocate_image->tile_info.height=allocate_image->rows;
+ }
+ if (image_info->tile != (char *) NULL)
+ if (!IsSubimage(image_info->tile,False))
+ {
+ (void) GetGeometry(image_info->tile,
+ &allocate_image->tile_info.x,
+ &allocate_image->tile_info.y,
+ &allocate_image->tile_info.width,
+ &allocate_image->tile_info.height);
+ if (0 == allocate_image->columns)
+ allocate_image->columns=allocate_image->tile_info.width;
+ if (0 == allocate_image->rows)
+ allocate_image->rows=allocate_image->tile_info.height;
+ }
+ allocate_image->compression=image_info->compression;
+ allocate_image->dither=image_info->dither;
+ allocate_image->interlace=image_info->interlace;
+ allocate_image->units=image_info->units;
+ if (image_info->density != (char *) NULL)
+ {
+ int
+ count;
+
+ count=GetMagickDimension(image_info->density,&allocate_image->x_resolution,
+ &allocate_image->y_resolution,NULL,NULL);
+ if (count != 2)
+ allocate_image->y_resolution=allocate_image->x_resolution;
+ }
+ if (image_info->page != (char *) NULL)
+ {
+ char
+ *geometry;
+
+ allocate_image->page=allocate_image->tile_info;
+ geometry=GetPageGeometry(image_info->page);
+ (void) GetGeometry(geometry,&allocate_image->page.x,
+ &allocate_image->page.y,&allocate_image->page.width,
+ &allocate_image->page.height);
+ MagickFreeMemory(geometry);
+ }
+ allocate_image->depth=image_info->depth;
+ allocate_image->background_color=image_info->background_color;
+ allocate_image->border_color=image_info->border_color;
+ allocate_image->matte_color=image_info->matte_color;
+ allocate_image->client_data=image_info->client_data;
+ allocate_image->ping=image_info->ping;
+
+ if (image_info->attributes != (Image *) NULL)
+ (void) CloneImageAttributes(allocate_image,image_info->attributes);
+
+ return(allocate_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A l l o c a t e N e x t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use AllocateNextImage() to initialize the next image in a sequence to
+% default values. The next member of image points to the newly allocated
+% image. If there is a memory shortage, next is assigned NULL.
+%
+% The format of the AllocateNextImage method is:
+%
+% void AllocateNextImage(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o image_info: Many of the image default values are set from this
+% structure. For example, filename, compression, depth, background color,
+% and others.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void AllocateNextImage(const ImageInfo *image_info,Image *image)
+{
+ /*
+ Allocate image structure.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ image->next=AllocateImage(image_info);
+ if (image->next == (Image *) NULL)
+ return;
+ (void) strlcpy(image->next->filename,image->filename,MaxTextExtent);
+ if (image_info != (ImageInfo *) NULL)
+ (void) strlcpy(image->next->filename,image_info->filename,MaxTextExtent);
+ DestroyBlob(image->next);
+ image->next->blob=ReferenceBlob(image->blob);
+ image->next->scene=image->scene+1;
+ image->next->previous=image;
+}
+
+#if defined(HasX11)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A n i m a t e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AnimateImages() repeatedly displays an image sequence to any X window
+% screen. It returns a value other than 0 if successful. Check the
+% exception member of image to determine the reason for any failure.
+%
+% The format of the AnimateImages method is:
+%
+% unsigned int AnimateImages(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport MagickPassFail AnimateImages(const ImageInfo *image_info,
+ Image *image)
+{
+ const char
+ *client_name;
+
+ Display
+ *display;
+
+ XrmDatabase
+ resource_database;
+
+ MagickXResourceInfo
+ resource;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ display=XOpenDisplay((char *) NULL);
+ if (display == (Display *) NULL)
+ return(False);
+ (void) XSetErrorHandler(MagickXError);
+ client_name=GetClientName();
+ resource_database=MagickXGetResourceDatabase(display,client_name);
+ MagickXGetResourceInfo(resource_database,client_name,&resource);
+ resource.image_info=CloneImageInfo(image_info);
+ resource.immutable=True;
+ (void) MagickXAnimateImages(display,&resource,(char **) &client_name,
+ 1,image);
+ (void) XCloseDisplay(display);
+ DestroyImageInfo(resource.image_info);
+ return(image->exception.severity == UndefinedException);
+}
+#else
+MagickExport MagickPassFail AnimateImages(const ImageInfo *image_info,
+ Image *image)
+{
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ ThrowBinaryException(MissingDelegateError,XWindowLibraryIsNotAvailable,
+ image->filename);
+ return(False);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A p p e n d I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The AppendImages() method takes a set of images and appends them to each
+% other top-to-bottom if the stack parameter is true, otherwise left-to-right.
+%
+% The format of the AppendImage method is:
+%
+% Image *AppendImages(const Image *image,const unsigned int stack,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image sequence.
+%
+% o stack: A value other than 0 stacks the images top-to-bottom.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *AppendImages(const Image *image,const unsigned int stack,
+ ExceptionInfo *exception)
+{
+#define AppendImageText "[%s] Append sequence..."
+
+ Image
+ *append_image;
+
+ register const Image
+ *next;
+
+ register long
+ x,
+ y;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ height,
+ scene,
+ width;
+
+ /*
+ Ensure the image have the same column width.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if (image->next == (Image *) NULL)
+ return CloneImage(image,0,0,MagickTrue,exception);
+
+ width=image->columns;
+ height=image->rows;
+ for (next=image->next; next != (Image *) NULL; next=next->next)
+ {
+ if (stack)
+ {
+ if (next->columns > width)
+ width=next->columns;
+ height+=next->rows;
+ continue;
+ }
+ width+=next->columns;
+ if (next->rows > height)
+ height=next->rows;
+ }
+ /*
+ Initialize append next attributes.
+ */
+ append_image=CloneImage(image,width,height,MagickTrue,exception);
+ if (append_image == (Image *) NULL)
+ return((Image *) NULL);
+ scene=0;
+ append_image->storage_class=DirectClass;
+ if (stack)
+ {
+ /*
+ Stack top-to-bottom.
+ */
+ y=0;
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ (void) CompositeImage(append_image,CopyCompositeOp,next,0,y);
+ if (append_image->columns > next->columns)
+ SetImageColorRegion(append_image,next->columns,y,
+ append_image->columns-next->columns,next->rows,
+ &append_image->background_color);
+ y+=next->rows;
+ status=MagickMonitorFormatted(scene,GetImageListLength(image),
+ exception,AppendImageText,
+ image->filename);
+ if (status == MagickFail)
+ break;
+ scene++;
+ }
+ return(append_image);
+ }
+ /*
+ Stack left-to-right.
+ */
+ x=0;
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ (void) CompositeImage(append_image,CopyCompositeOp,next,x,0);
+ if (append_image->rows > next->rows)
+ SetImageColorRegion(append_image,x,next->rows,
+ next->columns,
+ append_image->rows-next->rows,
+ &append_image->background_color);
+ x+=next->columns;
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ exception,AppendImageText,
+ image->filename);
+ if (status == MagickFail)
+ break;
+ }
+ return(append_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C a t c h I m a g e E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CatchImageException() returns if no exceptions are found in the image
+% sequence, otherwise it determines the most severe exception and reports
+% it as a warning or error depending on the severity.
+%
+% The format of the CatchImageException method is:
+%
+% ExceptionType CatchImageException(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: An image sequence.
+%
+%
+*/
+MagickExport ExceptionType CatchImageException(Image *image)
+{
+ ExceptionInfo
+ exception;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ GetExceptionInfo(&exception);
+ GetImageException(image,&exception);
+ CatchException(&exception);
+ DestroyExceptionInfo(&exception);
+ return(exception.severity);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l i p P a t h I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ClipPathImage() sets the image clip mask based any clipping path information
+% if it exists.
+%
+% The format of the ClipPathImage method is:
+%
+% unsigned int ClipPathImage(Image *image,const char *pathname,
+% const unsigned int inside)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o pathname: name of clipping path resource. If name is preceded by #, use
+% clipping path numbered by name.
+%
+% o inside: if non-zero, later operations take effect inside clipping path.
+% Otherwise later operations take effect outside clipping path.
+%
+%
+*/
+MagickExport MagickPassFail ClipImage(Image *image)
+{
+ return(ClipPathImage(image,"#1",True));
+}
+
+#define ClipPathImageText "[%s] Creating clip mask..."
+static MagickPassFail
+ClipPathImageCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Force all pixels to be either black or white (opaque or transparent)
+ to remove any unintended antialiasing effects created by the SVG
+ renderer.
+ */
+ const MagickBool
+ inside = *((MagickBool *) immutable_data);
+
+ register Quantum
+ intensity;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ for (i=0; i < npixels; i++)
+ {
+ intensity=PixelIntensityToQuantum(&pixels[i]);
+ if (inside)
+ intensity=(intensity == TransparentOpacity ? TransparentOpacity :
+ OpaqueOpacity);
+ else
+ intensity=(intensity == TransparentOpacity ? OpaqueOpacity :
+ TransparentOpacity);
+ pixels[i].red=intensity;
+ pixels[i].green=intensity;
+ pixels[i].blue=intensity;
+ pixels[i].opacity=intensity;
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail ClipPathImage(Image *image,const char *pathname,
+ const MagickBool inside)
+{
+
+ char
+ key[MaxTextExtent];
+
+ const ImageAttribute
+ *attribute;
+
+ Image
+ *clip_mask;
+
+ ImageInfo
+ *image_info;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(pathname != NULL);
+ FormatString(key,"8BIM:1999,2998:%s",pathname);
+ attribute=GetImageAttribute(image,key);
+ if (attribute == (const ImageAttribute *) NULL)
+ return(MagickFail);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ (void) QueryColorDatabase("#ffffffff",&image_info->background_color,
+ &image->exception);
+ clip_mask=BlobToImage(image_info,attribute->value,strlen(attribute->value),
+ &image->exception);
+ DestroyImageInfo(image_info);
+ if (clip_mask == (Image *) NULL)
+ return (MagickFail);
+ if (clip_mask->storage_class == PseudoClass)
+ {
+ if (SyncImage(clip_mask) == MagickFail)
+ return (MagickFail);
+ clip_mask->storage_class=DirectClass;
+ }
+ clip_mask->matte=True;
+ /*
+ Force all pixels to be either black or white (opaque or transparent)
+ to remove any unintended antialiasing effects created by the SVG
+ renderer.
+ */
+ status=PixelIterateMonoModify(ClipPathImageCallBack,NULL,
+ ClipPathImageText,
+ NULL,&inside,0,0,clip_mask->columns,clip_mask->rows,
+ clip_mask,&image->exception);
+ /*
+ Overload magick_filename to keep name of path that created image.
+ This is needed so we can get the path as postscript for PS coders
+ to create a postscript vector based clipping path.
+ */
+ FormatString(clip_mask->magick_filename,"8BIM:1999,2998:%s\nPS",pathname);
+
+ clip_mask->is_grayscale=True;
+ clip_mask->is_monochrome=True;
+ (void) SetImageClipMask(image,clip_mask);
+ DestroyImage(clip_mask);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneImage() copies an image and returns the copy as a new image object.
+% If the specified columns and rows is 0, an exact copy of the image is
+% returned, otherwise the pixel data is undefined and must be initialized
+% with the SetImagePixels() and SyncImagePixels() methods. On failure,
+% a NULL image is returned and exception describes the reason for the
+% failure.
+%
+% The format of the CloneImage method is:
+%
+% Image *CloneImage(const Image *image,const unsigned long columns,
+% const unsigned long rows,const unsigned int orphan,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o columns: The number of columns in the cloned image.
+%
+% o rows: The number of rows in the cloned image.
+%
+% o orphan: With a value other than 0, the cloned image is an orphan. An
+% orphan is a stand-alone image that is not assocated with an image list.
+% In effect, the next and previous members of the cloned image is set to
+% NULL.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *CloneImage(const Image *image,const unsigned long columns,
+ const unsigned long rows,const unsigned int orphan,ExceptionInfo *exception)
+{
+ Image
+ *clone_image;
+
+ size_t
+ length;
+
+ /*
+ Clone the image.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ clone_image=MagickAllocateMemory(Image *,sizeof(Image));
+ if (clone_image == (Image *) NULL)
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCloneImage);
+ (void) memset(clone_image,0,sizeof(Image));
+ clone_image->storage_class=image->storage_class;
+ clone_image->colorspace=image->colorspace;
+ clone_image->compression=image->compression;
+ clone_image->dither=image->dither;
+ clone_image->taint=image->taint;
+ clone_image->is_grayscale=image->is_grayscale;
+ clone_image->is_monochrome=image->is_monochrome;
+ clone_image->matte=image->matte;
+ clone_image->columns=image->columns;
+ clone_image->rows=image->rows;
+ clone_image->depth=image->depth;
+ if (image->colormap != (PixelPacket *) NULL)
+ {
+ /*
+ Allocate and copy the image colormap.
+ */
+ clone_image->colors=image->colors;
+ length=image->colors*sizeof(PixelPacket);
+ clone_image->colormap=MagickAllocateMemory(PixelPacket *,length);
+ if (clone_image->colormap == (PixelPacket *) NULL)
+ {
+ DestroyImage(clone_image);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCloneImage);
+ }
+ length=image->colors*sizeof(PixelPacket);
+ (void) memcpy(clone_image->colormap,image->colormap,length);
+ }
+ clone_image->background_color=image->background_color;
+ clone_image->border_color=image->border_color;
+ clone_image->matte_color=image->matte_color;
+ clone_image->gamma=image->gamma;
+ clone_image->chromaticity=image->chromaticity;
+ /*
+ Clone attached profiles.
+ */
+ if (image->profiles)
+ clone_image->profiles=MagickMapCloneMap(image->profiles,exception);
+ clone_image->orientation=image->orientation;
+ clone_image->rendering_intent=image->rendering_intent;
+ clone_image->units=image->units;
+ clone_image->montage=(char *) NULL;
+ clone_image->directory=(char *) NULL;
+ clone_image->geometry=(char *) NULL;
+ clone_image->offset=image->offset;
+ clone_image->x_resolution=image->x_resolution;
+ clone_image->y_resolution=image->y_resolution;
+ clone_image->page=image->page;
+ clone_image->tile_info=image->tile_info;
+ clone_image->blur=image->blur;
+ clone_image->fuzz=image->fuzz;
+ clone_image->filter=image->filter;
+ clone_image->interlace=image->interlace;
+ clone_image->endian=image->endian;
+ clone_image->gravity=image->gravity;
+ clone_image->compose=image->compose;
+ clone_image->signature=MagickSignature;
+ (void) CloneImageAttributes(clone_image,image);
+ clone_image->scene=image->scene;
+ clone_image->dispose=image->dispose;
+ clone_image->delay=image->delay;
+ clone_image->iterations=image->iterations;
+ clone_image->total_colors=image->total_colors;
+ clone_image->error=image->error;
+ clone_image->semaphore=AllocateSemaphoreInfo();
+ clone_image->logging=image->logging;
+ clone_image->timer=image->timer;
+ GetExceptionInfo(&clone_image->exception);
+ CopyException(&clone_image->exception,&image->exception);
+ clone_image->client_data=image->client_data;
+ clone_image->start_loop=image->start_loop;
+ clone_image->ascii85=0; /* Don't copy ascii85 huffman support structure */
+ clone_image->magick_columns=image->magick_columns;
+ clone_image->magick_rows=image->magick_rows;
+ (void) strlcpy(clone_image->magick_filename,image->magick_filename,
+ MaxTextExtent);
+ (void) strlcpy(clone_image->magick,image->magick,MaxTextExtent);
+ (void) strlcpy(clone_image->filename,image->filename,MaxTextExtent);
+ LockSemaphoreInfo((SemaphoreInfo *) clone_image->semaphore);
+ clone_image->reference_count=1;
+ UnlockSemaphoreInfo((SemaphoreInfo *) clone_image->semaphore);
+ clone_image->previous=(Image *) NULL;
+ clone_image->list=(Image *) NULL;
+ clone_image->next=(Image *) NULL;
+ clone_image->clip_mask=(Image *) NULL;
+ if (orphan)
+ clone_image->blob=CloneBlobInfo((BlobInfo *) NULL);
+ else
+ {
+ /*
+ Clone image while retaining list pointers and referencing
+ original blob (with reference count). New image does not
+ supplant existing image in list. Note that now two images may
+ be referring to the same next and previous images in the list
+ so they are in parallel and must be treated accordingly.
+
+ This path is not used within GraphicsMagick.
+ */
+ clone_image->blob=ReferenceBlob(image->blob);
+ clone_image->next=image->next;
+ clone_image->previous=image->previous;
+ }
+ if ((columns == 0) && (rows == 0))
+ {
+ if (image->montage != (char *) NULL)
+ (void) CloneString(&clone_image->montage,image->montage);
+ if (image->directory != (char *) NULL)
+ (void) CloneString(&clone_image->directory,image->directory);
+ if (image->clip_mask != (Image *) NULL)
+ clone_image->clip_mask=CloneImage(image->clip_mask,0,0,True,exception);
+ clone_image->ping=image->ping;
+ clone_image->cache=ReferenceCache(image->cache);
+ clone_image->default_views=AllocateThreadViewSet(clone_image,exception);
+ if (((image->montage != (char *) NULL) &&
+ (clone_image->montage == ((char *) NULL))) ||
+ ((image->directory != (char *) NULL) &&
+ (clone_image->directory == (char *) NULL)) ||
+ ((image->clip_mask != (Image *) NULL) &&
+ (clone_image->clip_mask == (Image *) NULL)) ||
+ (clone_image->cache == (_CacheInfoPtr_) NULL) ||
+ (clone_image->default_views == (_ThreadViewSetPtr_) NULL))
+ {
+ DestroyImage(clone_image);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCloneImage);
+ }
+ return(clone_image);
+ }
+ clone_image->page.width=columns;
+ clone_image->page.height=rows;
+ if (clone_image->columns > 0)
+ clone_image->page.x=(long) columns*image->page.x/(long) clone_image->columns;
+ if (clone_image->rows > 0)
+ clone_image->page.y=(long) rows*image->page.y/(long) clone_image->rows;
+ clone_image->columns=columns;
+ clone_image->rows=rows;
+ clone_image->ping=image->ping;
+ GetCacheInfo(&clone_image->cache);
+ clone_image->default_views=AllocateThreadViewSet(clone_image,exception);
+ if ((clone_image->cache == (_CacheInfoPtr_) NULL) ||
+ (clone_image->default_views == (_ThreadViewSetPtr_) NULL))
+ {
+ DestroyImage(clone_image);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCloneImage);
+ }
+ return(clone_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e I m a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneImageInfo() makes a copy of the given image info structure. If
+% NULL is specified, a new image info structure is created initialized to
+% default values.
+%
+% The format of the CloneImageInfo method is:
+%
+% ImageInfo *CloneImageInfo(const ImageInfo *image_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+%
+*/
+MagickExport ImageInfo *CloneImageInfo(const ImageInfo *image_info)
+{
+ ImageInfo
+ *clone_info;
+
+ clone_info=MagickAllocateMemory(ImageInfo *,sizeof(ImageInfo));
+ if (clone_info == (ImageInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToCloneImageInfo);
+ GetImageInfo(clone_info);
+ if (image_info == (ImageInfo *) NULL)
+ return(clone_info);
+ clone_info->compression=image_info->compression;
+ clone_info->temporary=image_info->temporary;
+ clone_info->adjoin=image_info->adjoin;
+ clone_info->antialias=image_info->antialias;
+ clone_info->subimage=image_info->subimage;
+ clone_info->subrange=image_info->subrange;
+ clone_info->depth=image_info->depth;
+ if (image_info->size != (char *) NULL)
+ clone_info->size=AllocateString(image_info->size);
+ if (image_info->tile != (char *) NULL)
+ clone_info->tile=AllocateString(image_info->tile);
+ if (image_info->page != (char *) NULL)
+ clone_info->page=AllocateString(image_info->page);
+ clone_info->interlace=image_info->interlace;
+ clone_info->endian=image_info->endian;
+ clone_info->units=image_info->units;
+ clone_info->quality=image_info->quality;
+ if (image_info->sampling_factor != (char *) NULL)
+ clone_info->sampling_factor=AllocateString(image_info->sampling_factor);
+ if (image_info->server_name != (char *) NULL)
+ clone_info->server_name=AllocateString(image_info->server_name);
+ if (image_info->font != (char *) NULL)
+ clone_info->font=AllocateString(image_info->font);
+ if (image_info->texture != (char *) NULL)
+ clone_info->texture=AllocateString(image_info->texture);
+ if (image_info->density != (char *) NULL)
+ clone_info->density=AllocateString(image_info->density);
+ clone_info->pointsize=image_info->pointsize;
+ clone_info->fuzz=image_info->fuzz;
+ clone_info->pen=image_info->pen;
+ clone_info->background_color=image_info->background_color;
+ clone_info->border_color=image_info->border_color;
+ clone_info->matte_color=image_info->matte_color;
+ clone_info->dither=image_info->dither;
+ clone_info->progress=image_info->progress;
+ clone_info->monochrome=image_info->monochrome;
+ clone_info->colorspace=image_info->colorspace;
+ clone_info->type=image_info->type;
+ clone_info->preview_type=image_info->preview_type;
+ clone_info->group=image_info->group;
+ clone_info->ping=image_info->ping;
+ clone_info->verbose=image_info->verbose;
+ if (image_info->view != (char *) NULL)
+ clone_info->view=AllocateString(image_info->view);
+ if (image_info->authenticate != (char *) NULL)
+ clone_info->authenticate=AllocateString(image_info->authenticate);
+ if (image_info->attributes != (Image *) NULL)
+ clone_info->attributes=CloneImage(image_info->attributes,0,0,True,
+ &image_info->attributes->exception);
+ if (image_info->definitions != (MagickMap) NULL)
+ clone_info->definitions=MagickMapCloneMap((MagickMap) image_info->definitions,0);
+ clone_info->client_data=image_info->client_data;
+ clone_info->cache=image_info->cache;
+ if (image_info->cache != (void *) NULL)
+ clone_info->cache=ReferenceCache(image_info->cache);
+ clone_info->file=image_info->file;
+ clone_info->blob=image_info->blob;
+ clone_info->length=image_info->length;
+ (void) strlcpy(clone_info->magick,image_info->magick,MaxTextExtent);
+ (void) strlcpy(clone_info->unique,image_info->unique,MaxTextExtent);
+ (void) strlcpy(clone_info->zero,image_info->zero,MaxTextExtent);
+ (void) strlcpy(clone_info->filename,image_info->filename,MaxTextExtent);
+ clone_info->signature=image_info->signature;
+ return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyImage() dereferences an image, deallocating memory associated with
+% the image if the reference count becomes zero.
+%
+% The format of the DestroyImage method is:
+%
+% void DestroyImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void DestroyImage(Image *image)
+{
+ int
+ destroy;
+
+ if (image == (Image *) NULL)
+ return;
+
+ /*
+ Dereference image.
+ */
+ assert(image->signature == MagickSignature);
+ destroy=False;
+ LockSemaphoreInfo((SemaphoreInfo *) image->semaphore);
+ image->reference_count--;
+ if (image->reference_count == 0)
+ destroy=True;
+ UnlockSemaphoreInfo((SemaphoreInfo *) image->semaphore);
+ if (!destroy)
+ return;
+ /*
+ Ensure that this image is not referenced by another image
+ */
+#if 0
+ if (image->previous)
+ assert(image->previous->next != image);
+ if (image->next)
+ assert(image->next->previous != image);
+#endif
+ /*
+ Destroy default views.
+ */
+ if (image->default_views != (_ThreadViewSetPtr_) NULL)
+ DestroyThreadViewSet(image->default_views);
+ image->default_views=(_ThreadViewSetPtr_) NULL;
+ /*
+ Destroy image pixel cache.
+ */
+ DestroyImagePixels(image);
+ if (image->clip_mask != (Image *) NULL)
+ DestroyImage(image->clip_mask);
+ image->clip_mask=(Image *) NULL;
+ MagickFreeMemory(image->montage);
+ MagickFreeMemory(image->directory);
+ MagickFreeMemory(image->colormap);
+ if (image->profiles)
+ {
+ MagickMapDeallocateMap(image->profiles);
+ image->profiles=0;
+ }
+ DestroyImageAttributes(image);
+ DestroyExceptionInfo(&image->exception);
+ MagickFreeMemory(image->ascii85);
+ DestroyBlob(image);
+ DestroySemaphoreInfo((SemaphoreInfo **) &image->semaphore);
+ MagickFreeMemory(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y I m a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyImageInfo() deallocates memory associated with a ImageInfo
+% structure.
+%
+% The format of the DestroyImageInfo method is:
+%
+% void DestroyImageInfo(ImageInfo *image_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+%
+*/
+MagickExport void DestroyImageInfo(ImageInfo *image_info)
+{
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ MagickFreeMemory(image_info->size);
+ MagickFreeMemory(image_info->tile);
+ MagickFreeMemory(image_info->page);
+ MagickFreeMemory(image_info->sampling_factor);
+ MagickFreeMemory(image_info->server_name);
+ MagickFreeMemory(image_info->font);
+ MagickFreeMemory(image_info->texture);
+ MagickFreeMemory(image_info->density);
+ MagickFreeMemory(image_info->view);
+ MagickFreeMemory(image_info->authenticate);
+ if (image_info->attributes != (Image *) NULL)
+ DestroyImage(image_info->attributes);
+ if (image_info->cache != (void *) NULL)
+ DestroyCacheInfo(image_info->cache);
+ if (image_info->definitions != (MagickMap) NULL)
+ MagickMapDeallocateMap((MagickMap) image_info->definitions);
+ MagickFreeMemory(image_info);
+}
+
+#if defined(HasX11)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D i s p l a y I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DisplayImages() displays an image sequence to any X window screen. It
+% returns a value other than 0 if successful. Check the exception member
+% of image to determine the reason for any failure.
+%
+% The format of the DisplayImages method is:
+%
+% unsigned int DisplayImages(const ImageInfo *image_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport MagickPassFail DisplayImages(const ImageInfo *image_info,
+ Image *image)
+{
+ const char
+ *client_name;
+
+ Display
+ *display;
+
+ Image
+ *next;
+
+ unsigned long
+ state;
+
+ XrmDatabase
+ resource_database;
+
+ MagickXResourceInfo
+ resource_info;
+
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ display=XOpenDisplay((char *) NULL);
+ if (display == (Display *) NULL)
+ return(MagickFail);
+ (void) XSetErrorHandler(MagickXError);
+ client_name=GetClientName();
+ resource_database=MagickXGetResourceDatabase(display,client_name);
+ MagickXGetResourceInfo(resource_database,client_name,&resource_info);
+ if (image_info->page != (char *) NULL)
+ resource_info.image_geometry=AcquireString(image_info->page);
+ resource_info.immutable=True;
+ for (next=image; next; next=next->next)
+ {
+ state=DefaultState;
+ (void) MagickXDisplayImage(display,&resource_info,(char **) &client_name,
+ 1,&next,&state);
+ if (state & ExitState)
+ break;
+ }
+ if (resource_database != (XrmDatabase) NULL)
+ {
+ /* It seems that recent X11 libraries (as found in FreeBSD 5.4)
+ automatically destroy the resource database associated with
+ the display and there are double-frees if we destroy the
+ resource database ourselves. */
+ /* XrmDestroyDatabase(resource_database); */
+ resource_database=(XrmDatabase) NULL;
+ }
+ MagickXDestroyResourceInfo(&resource_info);
+ MagickXDestroyX11Resources();
+ (void) XCloseDisplay(display);
+ return(image->exception.severity != UndefinedException);
+}
+#else
+MagickExport unsigned int DisplayImages(const ImageInfo *image_info,
+ Image *image)
+{
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ ThrowBinaryException(MissingDelegateError,XWindowLibraryIsNotAvailable,
+ image->filename);
+ return(MagickFail);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e C l i p M a s k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageClipMask returns a reference-counted copy of the current image
+% clip mask. This copy must be deallocated using DestroyImage() once it is
+% no longer needed. If the image does not have an associated clip mask,
+% then NULL is returned. Use SetImageClipMask() to add a clip mask to an
+% image, or remove a clip mask.
+%
+% If a component of the clip mask is set to TransparentOpacity (maximum
+% value) then the corresponding image pixel component will not be updated
+% when SyncImagePixels() is applied. The clip mask may be used to constrain
+% the results of an image processing operation to a region of the image.
+% Regions outside those allowed by the clip mask may be processed, but only
+% pixel quantums allowed by the clip mask will actually be updated.
+%
+% The clip mask protects the DirectClass pixels and PseudoClass pixel indexes
+% from modification. The clip mask does *not* protect the image colormap since
+% the image colormap is globally shared by all pixels in a PseudoClass image.
+%
+% The format of the GetImageClipMask method is
+%
+% Image *GetImageClipMask(const Image *image, ExceptionInfo *exception)
+%
+% A descripton of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Reason for failure.
+%
+*/
+MagickExport Image *GetImageClipMask(const Image *image, ExceptionInfo *exception)
+{
+ if (image->clip_mask)
+ return CloneImage(image->clip_mask,0,0,True,exception);
+
+ ThrowException3(exception,ImageError,UnableToGetClipMask,NoImagesWereFound);
+ return ((Image *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageException() traverses an image sequence and returns any
+% error more severe than noted by the exception parameter.
+%
+% The format of the GetImageException method is:
+%
+% void GetImageException(Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Specifies a pointer to a list of one or more images.
+%
+% o exception: return the highest severity exception.
+%
+%
+*/
+MagickExport void GetImageException(Image *image,ExceptionInfo *exception)
+{
+ register Image
+ *next;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ if (next->exception.severity == UndefinedException)
+ continue;
+ if (next->exception.severity > exception->severity)
+ CopyException(exception,&next->exception);
+ next->exception.severity=UndefinedException;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageGeometry() returns a region as defined by the geometry string with
+% respect to the image and its gravity.
+%
+% The format of the GetImageGeometry method is:
+%
+% int GetImageGeometry(const Image *image,const char *geometry,
+% const unsigned int size_to_fit,RectangleInfo *region_info)
+%
+% A description of each parameter follows:
+%
+% o flags: Method GetImageGeometry returns a bitmask that indicates
+% which of the four values were located in the geometry string.
+%
+% o geometry: The geometry (e.g. 100x100+10+10).
+%
+% o size_to_fit: A value other than 0 means to scale the region so it
+% fits within the specified width and height.
+%
+% o region_info: The region as defined by the geometry string with
+% respect to the image and its gravity.
+%
+%
+*/
+MagickExport int GetImageGeometry(const Image *image,const char *geometry,
+ const unsigned int size_to_fit,RectangleInfo *region_info)
+{
+ char
+ region_geometry[MaxTextExtent];
+
+ int
+ flags;
+
+ region_info->width=image->columns;
+ region_info->height=image->rows;
+ region_info->x=0;
+ region_info->y=0;
+ (void) strlcpy(region_geometry,geometry,MaxTextExtent);
+ if (!size_to_fit)
+ (void) strlcat(region_geometry,"!",MaxTextExtent);
+ flags=GetMagickGeometry(region_geometry,&region_info->x,&region_info->y,
+ &region_info->width,&region_info->height);
+ switch (image->gravity)
+ {
+ case ForgetGravity:
+ case NorthWestGravity:
+ break;
+ case NorthGravity:
+ {
+ region_info->x+=(long) (image->columns/2-region_info->width/2);
+ break;
+ }
+ case NorthEastGravity:
+ {
+ region_info->x=(long) (image->columns-region_info->width-region_info->x);
+ break;
+ }
+ case WestGravity:
+ {
+ region_info->y+=(long) (image->rows/2-region_info->height/2);
+ break;
+ }
+ case StaticGravity:
+ case CenterGravity:
+ default:
+ {
+ region_info->x+=(long) (image->columns/2-region_info->width/2);
+ region_info->y+=(long) (image->rows/2-region_info->height/2);
+ break;
+ }
+ case EastGravity:
+ {
+ region_info->x=(long) (image->columns-region_info->width-region_info->x);
+ region_info->y+=(long) (image->rows/2-region_info->height/2);
+ break;
+ }
+ case SouthWestGravity:
+ {
+ region_info->y=(long) (image->rows-region_info->height-region_info->y);
+ break;
+ }
+ case SouthGravity:
+ {
+ region_info->x+=(long) (image->columns/2-region_info->width/2);
+ region_info->y=(long) (image->rows-region_info->height-region_info->y);
+ break;
+ }
+ case SouthEastGravity:
+ {
+ region_info->x=(long) (image->columns-region_info->width-region_info->x);
+ region_info->y=(long) (image->rows-region_info->height-region_info->y);
+ break;
+ }
+ }
+ return(flags);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageInfo() initializes image_info to default values.
+%
+% The format of the GetImageInfo method is:
+%
+% void GetImageInfo(ImageInfo *image_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+%
+*/
+MagickExport void GetImageInfo(ImageInfo *image_info)
+{
+ ExceptionInfo
+ exception;
+
+ /*
+ File and image dimension members.
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ (void) memset(image_info,0,sizeof(ImageInfo));
+ image_info->adjoin=MagickTrue;
+ image_info->depth=QuantumDepth;
+ image_info->interlace=UndefinedInterlace;
+ image_info->quality=DefaultCompressionQuality;
+ image_info->antialias=True;
+ image_info->pointsize=12;
+ image_info->dither=True;
+ image_info->progress=True;
+ GetExceptionInfo(&exception);
+ (void) QueryColorDatabase(BackgroundColor,&image_info->background_color,
+ &exception);
+ (void) QueryColorDatabase(BorderColor,&image_info->border_color,&exception);
+ (void) QueryColorDatabase(MatteColor,&image_info->matte_color,&exception);
+ DestroyExceptionInfo(&exception);
+ image_info->signature=MagickSignature;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I s S u b i m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsSubimage returns True if the specification string is a valid
+% subimage specification (e.g. [1], [1-9], [1,7,4]). Subimage
+% specifications may appear between brackets in filename specifications
+% similar to filename[specification] and this function checks the
+% validity of the specification part.
+%
+% The format of the IsSubimage method is:
+%
+% MagickBool IsSubimage(const char *specification,
+% const MagickBool allow_geometry)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsSubimage returns True if the geometry is a valid
+% subimage specification otherwise False is returned.
+%
+% o specification: Subimage specification string
+%
+% o allow_geometry: A value other than 0 also allows the
+$ specification to be in the form of a geometry string (WxH+x+y).
+%
+%
+*/
+MagickExport MagickBool IsSubimage(const char *spec,
+ const MagickBool allow_geometry)
+{
+ unsigned long
+ subimage,
+ subrange;
+
+ if (spec == (const char *) NULL)
+ return False;
+ return MagickParseSubImageSpecification(spec,
+ &subimage,
+ &subrange,
+ allow_geometry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s T a i n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsTaintImage() returns a value other than 0 if any pixel in the image
+% has been altered since it was first constituted.
+%
+% The format of the IsTaintImage method is:
+%
+% unsigned int IsTaintImage(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport unsigned int IsTaintImage(const Image *image)
+{
+ char
+ magick[MaxTextExtent],
+ filename[MaxTextExtent];
+
+ register const Image
+ *p;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ (void) strlcpy(magick,image->magick,MaxTextExtent);
+ (void) strlcpy(filename,image->filename,MaxTextExtent);
+ for (p=image; p != (Image *) NULL; p=p->next)
+ {
+ if (p->taint)
+ return(True);
+ if (LocaleCompare(p->magick,magick) != 0)
+ return(True);
+ if (LocaleCompare(p->filename,filename) != 0)
+ return(True);
+ }
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o d i f y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ModifyImage() ensures that there is only a single reference to the image
+% to be modified, updating the provided image pointer to point to a clone of
+% the original image if necessary.
+%
+% The format of the ModifyImage method is:
+%
+% ModifyImage(Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport void ModifyImage(Image **image,ExceptionInfo *exception)
+{
+ Image
+ *clone_image;
+
+ unsigned int
+ clone;
+
+ assert(image != (Image **) NULL);
+ assert(*image != (Image *) NULL);
+ assert((*image)->signature == MagickSignature);
+ clone=False;
+ LockSemaphoreInfo((SemaphoreInfo *) (*image)->semaphore);
+ if ((*image)->reference_count > 1)
+ clone=True;
+ UnlockSemaphoreInfo((SemaphoreInfo *) (*image)->semaphore);
+ if (!clone)
+ return;
+ clone_image=CloneImage(*image,0,0,True,exception);
+ LockSemaphoreInfo((SemaphoreInfo *) (*image)->semaphore);
+ (*image)->reference_count--;
+ UnlockSemaphoreInfo((SemaphoreInfo *) (*image)->semaphore);
+ *image=clone_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e f e r e n c e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReferenceImage() increments the reference count associated with an image
+% returning a pointer to the image.
+%
+% The format of the ReferenceImage method is:
+%
+% Image *ReferenceImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport Image *ReferenceImage(Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ LockSemaphoreInfo((SemaphoreInfo *) image->semaphore);
+ image->reference_count++;
+ UnlockSemaphoreInfo((SemaphoreInfo *) image->semaphore);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e m o v e D e f i n i t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RemoveDefinitions() removes definitions from the current map of definitions
+% in ImageInfo. Definitions may be used by coders/decoders that read and
+% write images. RemoveDefinitions() returns true only if the specified keys
+% are present in the map and are actually removed.
+%
+% The format of the RemoveDefinitions method is:
+%
+% void RemoveDefinitions(ImageInfo *image_info,const char *options)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o keys: List of keys to remove from the definitions map. The
+% format of the string is "key1,key2,...". A special key, '*', removes
+% all the key/value pairs in the definitions map. This key always
+% succeeds.
+%
+% o exception: Errors result in updates to this structure.
+%
+*/
+MagickExport MagickPassFail
+RemoveDefinitions(const ImageInfo *image_info,const char *keys)
+{
+ char
+ key[MaxTextExtent];
+
+ unsigned int
+ status;
+
+ unsigned int
+ i,
+ j;
+
+ size_t
+ length;
+
+ if (image_info->definitions == 0)
+ return(False);
+
+ status=MagickPass;
+
+ /*
+ TODO: update to accept GlobExpression as argument names list.
+ That would require the iterator to know we're manipulating
+ the map or a remove method on the map iterator itself.
+ Until then we accept a simple "*" to mean clear the whole map.
+ */
+ length=strlen(keys);
+ i=0;
+ while (i < length)
+ {
+ for (j=0; (i < length) && (keys[i] != ','); i++,j++)
+ key[j]=keys[i];
+ key[j]='\0';
+ i++;
+ if (strlen(key) != 0)
+ {
+ if ((key[0] == '*') && (key[1] == '\0'))
+ MagickMapClearMap((MagickMap) image_info->definitions);
+ else
+ status &= MagickMapRemoveEntry((MagickMap) image_info->definitions,key);
+ }
+ else
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e s e t I m a g e P a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ResetImagePage adjusts the current page canvas and position based on a
+% relative page specification.
+%
+% The format of the ResetImagePage method is:
+%
+% MagickPassFail ResetImagePage(Image *image,const char *page)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o page: Relative page offset adjustment
+%
+*/
+MagickExport MagickPassFail
+ResetImagePage(Image *image,const char *page)
+{
+ RectangleInfo
+ page_geometry;
+
+ int
+ flags;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ /* Parse page geometry */
+ page_geometry.x=0;
+ page_geometry.y=0;
+ page_geometry.width=0;
+ page_geometry.height=0;
+ flags=GetGeometry(page,&page_geometry.x,&page_geometry.y,
+ &page_geometry.width,&page_geometry.height);
+
+ /* If no values were parsed, then return failed status */
+ if (NoValue == flags)
+ return MagickFail;
+
+ /* If width was provided */
+ if (flags & WidthValue)
+ {
+ /* If height was not provided, then default it to width */
+ if (!(flags & HeightValue))
+ page_geometry.height=page_geometry.width;
+ image->page.width=page_geometry.width;
+ image->page.height=page_geometry.height;
+ }
+ /* If values are absolute, then only adjust the page offset
+ values */
+ if (flags & AspectValue) /* ! */
+ {
+ if (flags & XValue)
+ image->page.x+=page_geometry.x;
+ if (flags & YValue)
+ image->page.y+=page_geometry.y;
+ }
+ else
+ {
+ /* If values are not absolute, then use offset values, and page
+ width and height based on image width and height plus page
+ offsets */
+ if (flags & XValue)
+ {
+ image->page.x=page_geometry.x;
+ if ((image->page.width == 0) && (page_geometry.x > 0))
+ image->page.width=image->columns+page_geometry.x;
+ }
+ if (flags & YValue)
+ {
+ image->page.y=page_geometry.y;
+ if ((image->page.height == 0) && (page_geometry.y > 0))
+ image->page.height=image->rows+page_geometry.y;
+ }
+ }
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e E x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageEx() sets the red, green, and blue components of each pixel to
+% the image background color and the opacity component to the specified
+% level of transparency. The background color is defined by the
+% background_color member of the image.
+%
+% The format of the SetImageEx method is:
+%
+% void SetImageEx(Image *image,const Quantum opacity,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o opacity: Set each pixel to this level of transparency.
+%
+% o exception: Report any exception here.
+%
+*/
+#define SetImageColorText "[%s] Set color..."
+static MagickPassFail
+SetImageColorCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Assign color to pixels.
+ */
+ const PixelPacket
+ background_color = *(const PixelPacket *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ Set DirectClass pixels
+ */
+ for (i=0; i < npixels; i++)
+ pixels[i]=background_color;
+
+ if ((image->storage_class == PseudoClass) ||
+ (image->colorspace == CMYKColorspace))
+ {
+ /*
+ Set PseudoClass pixel indexes.
+ */
+ (void) memset(indexes,0,npixels*sizeof(IndexPacket));
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail SetImageEx(Image *image,const Quantum opacity,
+ ExceptionInfo *exception)
+{
+ PixelPacket
+ background_color;
+
+ MagickPassFail
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=MagickPass;
+ background_color=image->background_color;
+ if (opacity != OpaqueOpacity)
+ background_color.opacity=opacity;
+ if (background_color.opacity != OpaqueOpacity)
+ {
+ image->matte=True;
+ image->colorspace=RGBColorspace;
+ image->storage_class=DirectClass;
+ }
+
+ status=PixelIterateMonoSet(SetImageColorCallBack,NULL,
+ SetImageColorText,
+ NULL,&background_color,0,0,
+ image->columns,image->rows,
+ image,exception);
+
+ image->is_grayscale=IsGray(image->background_color);
+ image->is_monochrome=IsMonochrome(image->background_color);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImage() sets the red, green, and blue components of each pixel to
+% the image background color and the opacity component to the specified
+% level of transparency. The background color is defined by the
+% background_color member of the image. Any exception is reported to
+% the image.
+%
+% The format of the SetImage method is:
+%
+% void SetImage(Image *image,const Quantum opacity)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o opacity: Set each pixel to this level of transparency.
+%
+%
+*/
+MagickExport MagickPassFail SetImage(Image *image,const Quantum opacity)
+{
+ return SetImageEx(image,opacity,&image->exception);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageColor() sets the red, green, blue and opacity components of each
+% pixel to those from a specified pixel value.
+%
+% The format of the SetImageColor method is:
+%
+% MagickPassFail SetImageColor(Image *image,const PixelPacket *pixel)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o pixel: Set each pixel in the image to this pixel's color and transparency.
+%
+%
+*/
+MagickExport MagickPassFail SetImageColor(Image *image,
+ const PixelPacket *pixel)
+{
+ image->is_grayscale=IsGray(*pixel);
+ image->is_monochrome=IsMonochrome(*pixel);
+ return SetImageColorRegion(image,0,0,image->columns,image->rows,pixel);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e C o l o r R e g i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageColorRegion() sets the red, green, blue and opacity components
+% of each pixel in the specified region to those from a specified pixel
+% value. Please note that it is assumed that the pixel value is in
+% the same colorspace as the image.
+%
+% The format of the SetImageColorRegion method is:
+%
+% MagickPassFail SetImageColorRegion(Image *image,
+% long x,
+% long y,
+% unsigned long width,
+% unsigned long height,
+% const PixelPacket *pixel)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o pixel: Set each pixel in the image to this pixel's color and transparency.
+%
+%
+*/
+MagickExport MagickPassFail
+SetImageColorRegion(Image *image,
+ long x,
+ long y,
+ unsigned long width,
+ unsigned long height,
+ const PixelPacket *pixel)
+{
+ MagickPassFail
+ status;
+
+ MagickBool
+ is_grayscale;
+
+ MagickBool
+ is_monochrome;
+
+ assert(image != (Image *) NULL);
+ assert(pixel != (PixelPacket *) NULL);
+ assert(image->signature == MagickSignature);
+ status=MagickPass;
+
+ is_grayscale=(image->is_grayscale && IsGray(*pixel));
+ is_monochrome=(image->is_monochrome && IsMonochrome(*pixel));
+
+ if (pixel->opacity != OpaqueOpacity)
+ image->matte=MagickTrue;
+ image->storage_class=DirectClass;
+
+ status=PixelIterateMonoModify(SetImageColorCallBack,NULL,
+ SetImageColorText,
+ NULL,pixel,x,y,
+ width,height,
+ image,&image->exception);
+
+ image->is_grayscale=is_grayscale;
+ image->is_monochrome=is_monochrome;
+ return status;
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e C l i p M a s k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageClipMask() associates a clip mask with the image. The clip mask
+% must be the same dimensions as the image.
+%
+% If a component of the clip mask is set to TransparentOpacity (maximum
+% value) then the corresponding image pixel component will not be updated
+% when SyncImagePixels() is applied. The clip mask may be used to constrain
+% the results of an image processing operation to a region of the image.
+% Regions outside those allowed by the clip mask may be processed, but only
+% pixel quantums allowed by the clip mask will actually be updated.
+%
+% The clip mask protects the DirectClass pixels and PseudoClass pixel indexes
+% from modification. The clip mask does *not* protect the image colormap since
+% the image colormap is globally shared by all pixels in a PseudoClass image.
+%
+% The format of the SetImageClipMask method is:
+%
+% unsigned int SetImageClipMask(Image *image,const Image *clip_mask)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o clip_mask: The image clip mask.
+%
+%
+*/
+MagickExport MagickPassFail SetImageClipMask(Image *image,const Image *clip_mask)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (clip_mask != (const Image *) NULL)
+ if ((clip_mask->columns != image->columns) ||
+ (clip_mask->rows != image->rows))
+ ThrowBinaryException3(ImageError,UnableToSetClipMask,ImageSizeDiffers);
+ if (image->clip_mask != (Image *) NULL)
+ DestroyImage(image->clip_mask);
+ image->clip_mask=(Image *) NULL;
+ if (clip_mask == (Image *) NULL)
+ return(MagickPass);
+ image->clip_mask=CloneImage(clip_mask,0,0,True,&image->exception);
+ if (image->clip_mask)
+ return (MagickPass);
+ return (MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageDepth() translates the pixel quantums across all of the channels
+% so that if they are later divided to fit within the specified bit
+% depth, that no additional information is lost (i.e. no remainder will
+% result from the division). Note that any subsequent image processing is
+% likely to increase the effective depth of the image channels. A non-zero
+% value is returned if the operation is successful. Check the exception
+% member of image to determine the cause for any failure.
+%
+% The format of the SetImageDepth method is:
+%
+% unsigned int SetImageDepth(Image *image,const unsigned long depth)
+%
+% A description of each parameter follows:
+%
+% o image: The image to update.
+%
+% o depth: Desired image depth (range 1 to QuantumDepth)
+%
+%
+*/
+MagickExport MagickPassFail SetImageDepth(Image *image,const unsigned long depth)
+{
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+
+ status=QuantumOperatorImage(image,AllChannels,DepthQuantumOp,(double) depth,
+ &image->exception);
+ if ((image->matte) && (MagickFail != status))
+ status=QuantumOperatorImage(image,OpacityChannel,DepthQuantumOp,(double) depth,
+ &image->exception);
+ image->depth=Min(depth,QuantumDepth);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S e t I m a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageInfo() inspects the filename field of the ImageInfo
+% structure. Based on what it finds, it may update the `affirm',
+% `filename', `magick', `subimage', `subrange', `temporary', and
+% `tile' fields in the ImageInfo structure, and may even allocate a
+% temporary file. This is a powerful, mysterious, and anchient
+% function which supports the many special features associated with
+% input and output file specifications, and is intended for use only
+% within GraphicsMagick code.
+%
+% If the file will be read and the file specification includes an
+% index enclosed in brackets after the file name and the file exists,
+% then it is assumed to specify a subimage of a multi-resolution image
+% format like Photo CD (e.g. img0001.pcd[4]). The `tile' `subimage',
+% and `subrange' fields will be updated. The filename specification
+% is then truncated to remove the subimage specification.
+%
+% The filename is inspected for an image format prefix. For example,
+% `ps:image' returns PS indicating a Postscript image. If a format
+% prefix was found, then `filename' is updated to remove it. The
+% `magick' field is set to the specified format and the `affirm' field
+% is set to indicate an explicit user request for the format (which
+% will not be overridden).
+%
+% If the format is not yet known, the filename is inspected for an
+% image format extension. If format support exists for this
+% extension, then the official format designator for that format is
+% written into the `magick' field. For example, "JPEG" is set in the
+% `magick' field for the filename: `image.jpg'. Some file extensions
+% are intentionally ignored due to potential confusion or security
+% issues. The file extension is used as a strong hint of the file
+% format but is not authoritative.
+%
+% If the file will be read, then its content is inspected for its
+% type. If the input is not seekable, then its content is copied to a
+% temporary file, `filename` is updated with the name of the temporary
+% file, and `temporary' is set to true so that the temporary file may
+% be automatically deleted later. The `magick' field is updated if
+% file header matches a known type.
+%
+% MagickFail is returned if an error is encountered.
+%
+% The format of the SetImageInfo method is:
+%
+% MagickPassFail SetImageInfo(ImageInfo *image_info,
+% const unsigned int flags,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info..
+%
+% o flags: Flag options based on an OR of SETMAGICK_READ, SETMAGICK_WRITE,
+% and SETMAGICK_RECTIFY. SETMAGICK_READ indicates that the file is to
+% be read, SETMAGICK_WRITE indicates that the the file will be written,
+% and SETMAGICK_RECTIFY indicates that the file specification should be
+% inspected for an embedded scene specification, and adjust the 'ajoin'
+% accordingly.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail
+MagickParseSubImageSpecification(const char *subimage_spec,
+ unsigned long *subimage_ptr,
+ unsigned long *subrange_ptr,
+ MagickBool allow_geometry)
+{
+ char
+ spec[MaxTextExtent];
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Example of supported formats (as per documentation):
+
+ 4
+ 2,7,4
+ 4-7
+ 320x256+50+50 (only if allow_geometry)
+ */
+
+ assert(subimage_spec != (const char *) NULL);
+ assert(subimage_ptr != (unsigned long *) NULL);
+ assert(subrange_ptr != (unsigned long *) NULL);
+
+ (void) strlcpy(spec,subimage_spec,sizeof(spec));
+
+ do
+ {
+ const char
+ *digits;
+
+ char
+ *q;
+
+ unsigned long
+ subimage=0,
+ subrange=0;
+
+ unsigned long
+ first,
+ last;
+
+ long
+ value;
+
+ digits=spec;
+ q=0;
+ value=strtol(digits,&q,10);
+ if (q <= digits) /* Parse error */
+ {
+ status=MagickFail;
+ break;
+ }
+
+ subimage=value;
+ subrange=subimage;
+
+ for (q=spec; *q != '\0'; )
+ {
+ while (isspace((int)(unsigned char) *q) || (*q == ','))
+ q++;
+ digits=q;
+ value=strtol(digits,&q,10);
+ if (q <= digits) /* Parse error */
+ break;
+ first=value;
+ last=first;
+ while (isspace((int)(unsigned char) *q))
+ q++;
+ if (*q == '-')
+ {
+ digits=q+1;
+ value=strtol(digits,&q,10);
+ if (q <= digits) /* Parse error */
+ break;
+ last=value;
+ }
+ else if ((*q != ',') && (*q != '\0'))
+ {
+ break; /* Parse error */
+ }
+ if (first > last)
+ Swap(first,last);
+ if (first < subimage)
+ subimage=first;
+ if (last > subrange)
+ subrange=last;
+ }
+ if (*q == '\0')
+ {
+ subrange -= subimage-1;
+ *subimage_ptr=subimage;
+ *subrange_ptr=subrange;
+ status=MagickPass;
+ }
+ else if (allow_geometry)
+ {
+ long
+ x,
+ y;
+
+ unsigned int
+ flags;
+
+ unsigned long
+ height,
+ width;
+
+ /* Require Width and Height */
+ flags=GetGeometry((char *) spec,&x,&y,&width,&height);
+ if ((flags & WidthValue) && (flags & HeightValue))
+ status=MagickPass;
+ else
+ status=MagickFail;
+ }
+ else
+ {
+ status=MagickFail;
+ }
+ } while (0);
+
+ return status;
+}
+static MagickPassFail
+ParseSubImageFileSpecification(char *filename,
+ char **tile_ptr,
+ unsigned long *subimage_ptr,
+ unsigned long *subrange_ptr,
+ ExceptionInfo *exception)
+{
+ char
+ *spec_start,
+ *spec_end;
+
+ size_t
+ filename_length;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(filename != (const char *) NULL);
+ assert(tile_ptr != (char **) NULL);
+ assert(subimage_ptr != (unsigned long *) NULL);
+ assert(subrange_ptr != (unsigned long *) NULL);
+ assert(exception != (ExceptionInfo*) NULL);
+
+ MagickFreeMemory(*tile_ptr);
+ filename_length=strlen(filename);
+ if ((filename_length > 2) &&
+ (filename_length < MaxTextExtent) &&
+ (filename[filename_length-1] == ']') &&
+ ((spec_start=strrchr(filename,'[')) != (const char *) NULL))
+ {
+ char
+ spec[MaxTextExtent];
+
+ /*
+ Example of supported formats (as per documentation):
+
+ 4
+ 2,7,4
+ 4-7
+ 320x256+50+50
+ */
+
+ spec_end=&filename[filename_length-1];
+ spec_start++;
+ (void) strlcpy(spec,spec_start,sizeof(spec));
+ spec[spec_end-spec_start]='\0';
+ if (MagickParseSubImageSpecification(spec,subimage_ptr,subrange_ptr,
+ MagickTrue))
+ {
+ status=MagickPass;
+ }
+ else
+ {
+ status=MagickFail;
+ ThrowException(exception,OptionError,
+ InvalidSubimageSpecification,spec);
+ }
+ if (status == MagickPass)
+ {
+ /* Truncate filename */
+ *(spec_start-1)='\0';
+ (void) CloneString(tile_ptr,spec);
+ }
+#if 0
+ fprintf(stderr,"subimage=%lu subrange=%lu tile=\"%s\"\n",
+ *subimage_ptr,*subrange_ptr,
+ (*tile_ptr ? *tile_ptr : "(null)"));
+#endif
+ }
+
+ return status;
+}
+
+MagickExport MagickPassFail
+SetImageInfo(ImageInfo *image_info,const unsigned int flags,
+ ExceptionInfo *exception)
+{
+ static const char
+ *virtual_delegates[] =
+ {
+ "AUTOTRACE",
+ "BROWSE",
+ "EDIT",
+ "GS-COLOR",
+ "GS-COLOR+ALPHA",
+ "GS-GRAY",
+ "GS-MONO",
+ "LAUNCH",
+ "MPEG-ENCODE",
+ "PRINT",
+ "SCAN",
+ "SHOW",
+ "TMP",
+ "WIN",
+ NULL
+ };
+
+ char
+ filename[MaxTextExtent],
+ magic[MaxTextExtent],
+ *q;
+
+ Image
+ *image;
+
+ register char
+ *p;
+
+ const MagickInfo
+ *magick_info;
+
+ size_t
+ magick_length;
+
+ unsigned int
+ lflags;
+
+ unsigned char
+ magick[2*MaxTextExtent];
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image_info != (ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+
+ /*
+ Ensure backward compatiblity with previous flags which used
+ True/False logic.
+ */
+ lflags=flags;
+ if (MagickFalse == flags)
+ lflags=SETMAGICK_WRITE;
+ else if (MagickTrue == flags)
+ lflags=(SETMAGICK_WRITE | SETMAGICK_RECTIFY);
+
+#if 0
+ fprintf(stderr,"SetImageInfo \"%s\" Read=%d Write=%d Rectify=%d\n",
+ image_info->filename,
+ ((lflags & SETMAGICK_READ) > 0),
+ ((lflags & SETMAGICK_WRITE) > 0),
+ ((lflags & SETMAGICK_RECTIFY) > 0));
+#endif
+
+ *magic='\0';
+
+ if (lflags & SETMAGICK_READ)
+ {
+ /*
+ Look for sub-image specification (e.g. img0001.pcd[4]).
+ */
+ p=image_info->filename+Max((long) strlen(image_info->filename)-1,0);
+ /*
+ Sometimes the provided argument is a real file and we need to
+ account for that. If it is not a real file and the argument ends
+ with ']' then the trailing part is likely a sub-image or size
+ specification.
+ */
+ if (*p == ']' && !IsAccessibleNoLogging(image_info->filename))
+ {
+ (void) ParseSubImageFileSpecification(image_info->filename,
+ &image_info->tile,
+ &image_info->subimage,
+ &image_info->subrange,
+ exception);
+ }
+ }
+
+ /*
+ Look for explicit 'format:image' in filename.
+ */
+ image_info->affirm=False;
+ if ((image_info->filename[0]) &&
+ (!IsAccessibleNoLogging(image_info->filename)))
+ {
+ p=image_info->filename;
+ while (isalnum((int) *p))
+ p++;
+ if ((p != image_info->filename) && (*p == ':') &&
+ ((p-image_info->filename) < (long) sizeof(magic)))
+ {
+ char
+ format[MaxTextExtent];
+
+ /*
+ User specified image format.
+ */
+ (void) strncpy(format,image_info->filename,p-image_info->filename);
+ format[p-image_info->filename]='\0';
+
+ /*
+ Backward compatability and interoperability namimg
+ */
+ if (LocaleCompare(format,"GRADATION") == 0)
+ (void) strcpy(format,"GRADIENT");
+
+ if (LocaleCompare(format,"MAGICK") == 0)
+ (void) strcpy(format,"IMAGE");
+
+ LocaleUpper(format);
+ /*
+ If format does not conflict with a Windows logical drive
+ */
+ if (!IsMagickConflict(format))
+ {
+ /*
+ Strip off image format prefix.
+ */
+ char base_filename[MaxTextExtent];
+ p++;
+ (void) strlcpy(base_filename,p,MaxTextExtent);
+ (void) strcpy(image_info->filename,base_filename);
+ (void) strlcpy(magic,format,MaxTextExtent);
+ (void) strlcpy(image_info->magick,magic,MaxTextExtent);
+ if (LocaleCompare(magic,"TMP") != 0)
+ image_info->affirm=MagickTrue;
+ }
+ }
+ }
+
+ /*
+ If we have not set the magic yet then set magic based on file
+ extension. Some extensions are intentionally not recognized
+ because they are confusing or dangerous.
+ */
+ if (*magic == '\0')
+ {
+ /* Restore p to end of modified filename */
+ p=image_info->filename+Max((long) strlen(image_info->filename)-1,0);
+
+ while ((*p != '.') && (p > (image_info->filename+1)))
+ p--;
+ if ((LocaleCompare(p,".gz") == 0) ||
+ (LocaleCompare(p,".Z") == 0) ||
+ (LocaleCompare(p,".bz2") == 0))
+ do
+ {
+ p--;
+ } while ((*p != '.') && (p > (image_info->filename+1)));
+ if ((*p == '.') && (strlen(p) < (long) sizeof(magic)))
+ {
+ /*
+ User specified image format.
+ */
+ unsigned int
+ i;
+
+ MagickBool
+ exclude;
+
+ (void) strlcpy(magic,p+1,MaxTextExtent);
+ for (q=magic; *q != '\0'; q++)
+ if (*q == '.')
+ {
+ *q='\0';
+ break;
+ }
+ LocaleUpper(magic);
+
+ exclude=MagickFalse;
+
+ /*
+ SGI and RGB are ambiguous.
+ */
+ if ((LocaleNCompare(image_info->magick,"SGI",3) == 0) &&
+ (LocaleCompare(magic,"RGB") == 0))
+ exclude=MagickTrue;
+
+ /*
+ Ignore extensions which match virtual delegates.
+ */
+ i=0;
+ while ((!exclude) && (virtual_delegates[i] != NULL))
+ {
+ if ((magic[0] == (virtual_delegates[i])[0]) &&
+ (LocaleCompare(magic,virtual_delegates[i]) == 0))
+ {
+ exclude=MagickTrue;
+ }
+ i++;
+ }
+
+ /*
+ Check to see if there is a coder definition for this
+ format and if the extension should be ignored, or is the
+ sole authority for this format.
+ */
+ magick_info=GetMagickInfo(magic,exception);
+ if (magick_info != (const MagickInfo *) NULL)
+ {
+ if (magick_info->extension_treatment == IgnoreExtensionTreatment)
+ exclude=MagickTrue;
+ else if (magick_info->extension_treatment == ObeyExtensionTreatment)
+ image_info->affirm=MagickTrue;
+ }
+
+ if ((!exclude) || (image_info->affirm))
+ (void) strlcpy(image_info->magick,magic,MaxTextExtent);
+ }
+ }
+
+ if (image_info->affirm)
+ return(MagickPass);
+ if (lflags & SETMAGICK_READ)
+ {
+ /*
+ Determine the file format from the first few bytes of the
+ file.
+ */
+ image=AllocateImage(image_info);
+ if (image == (Image *) NULL)
+ return(MagickFail);
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ {
+ DestroyImage(image);
+ return(MagickFail);
+ }
+ if (!BlobIsSeekable(image))
+ {
+ /*
+ Copy standard input or pipe to temporary file.
+ */
+ if(!AcquireTemporaryFileName(filename))
+ {
+ CloseBlob(image);
+ DestroyImage(image);
+ return(MagickFail);
+ }
+ (void) ImageToFile(image,filename,exception);
+ CloseBlob(image);
+ (void) strcpy(image->filename,filename);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFail)
+ {
+ DestroyImage(image);
+ return(MagickFail);
+ }
+ (void) strcpy(image_info->filename,filename);
+ image_info->temporary=MagickTrue;
+ }
+ magick[0]='\0';
+ magick_length = ReadBlob(image,2*MaxTextExtent,magick);
+ (void) SeekBlob(image,-(magick_off_t) magick_length,SEEK_CUR);
+ CloseBlob(image);
+ DestroyImage(image);
+ /*
+ Check format using magic.mgk configuration file. Use of an
+ external config file is absolutely necessary when using loadable
+ modules since otherwise the code necessary to perform the test
+ might not be available yet.
+ */
+ if (GetMagickFileFormat(magick,magick_length,image_info->magick,
+ MaxTextExtent,exception))
+ return(MagickPass);
+ }
+
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageOpacity() attenuates the opacity channel of an image. If the
+% image pixels are opaque, they are set to the specified opacity level.
+% Otherwise, the pixel opacity values are blended with the supplied
+% transparency value.
+%
+% The format of the SetImageOpacity method is:
+%
+% void SetImageOpacity(Image *image,const unsigned int opacity)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o opacity: The level of transparency: 0 is fully opaque and MaxRGB is
+% fully transparent.
+%
+%
+*/
+static MagickPassFail
+ModulateImageOpacityCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ const magick_uint32_t
+ opacity = *((const unsigned int *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ if (image->colorspace == CMYKColorspace)
+ {
+ for (i=0; i < npixels; i++)
+ indexes[i]=(IndexPacket) BlendQuantumOpacity(indexes[i],opacity);
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity=(Quantum) BlendQuantumOpacity(pixels[i].opacity,opacity);
+ }
+ return MagickPass;
+}
+static MagickPassFail
+SetImageOpacityCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ const unsigned int
+ opacity = *((const unsigned int *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(exception);
+
+ if (image->colorspace == CMYKColorspace)
+ {
+ for (i=0; i < npixels; i++)
+ indexes[i]=opacity;
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity=opacity;
+ }
+ return MagickPass;
+}
+MagickExport void SetImageOpacity(Image *image,const unsigned int opacity_val)
+{
+ const unsigned int
+ opacity = opacity_val;
+
+ MagickBool
+ is_grayscale,
+ is_monochrome;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ is_grayscale=image->is_grayscale;
+ is_monochrome=image->is_monochrome;
+ image->storage_class=DirectClass;
+ if (image->matte && (opacity != OpaqueOpacity) &&
+ (opacity != TransparentOpacity))
+ {
+ /*
+ Attenuate existing opacity channel
+ */
+ (void) PixelIterateMonoModify(ModulateImageOpacityCallBack,NULL,
+ "[%s] Modulate opacity...",
+ NULL,&opacity,0,0,image->columns,image->rows,
+ image,&image->exception);
+ }
+ else
+ {
+ /*
+ Add new opacity channel or make existing opacity channel opaque
+ */
+ image->matte=True;
+ (void) PixelIterateMonoModify(SetImageOpacityCallBack,NULL,
+ "[%s] Set opacity...",
+ NULL,&opacity,0,0,image->columns,image->rows,
+ image,&image->exception);
+ }
+ image->is_grayscale=is_grayscale;
+ image->is_monochrome=is_monochrome;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e T y p e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% (void) SetImageType() sets the type of image. Choose from these types:
+%
+% BilevelType, GrayscaleType, GrayscaleMatteType, PaletteType,
+% PaletteMatteType, TrueColorType, TrueColorMatteType,
+% ColorSeparationType, ColorSeparationMatteType, OptimizeType
+%
+% The format of the (void) SetImageType method is:
+%
+% (void) SetImageType(Image *image,const ImageType image_type)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o image_type: Image type.
+%
+%
+*/
+MagickExport MagickPassFail SetImageType(Image *image,const ImageType image_type)
+{
+ QuantizeInfo
+ quantize_info;
+
+ unsigned int
+ status = MagickPass;
+
+ MagickBool
+ logging;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ logging=IsEventLogging();
+ switch (image_type)
+ {
+ case BilevelType:
+ {
+ MagickBool
+ is_monochrome;
+
+ if (!IsRGBColorspace(image->colorspace))
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(Bilevel) Transforming to RGB colorspace ...");
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+
+ is_monochrome=image->is_monochrome;
+ if (!is_monochrome && image->dither)
+ is_monochrome=IsMonochromeImage(image,&image->exception);
+ if (is_monochrome || image->is_grayscale)
+ image->colorspace=GRAYColorspace;
+
+ if (!image->dither || is_monochrome)
+ {
+ if (!is_monochrome || (image->storage_class != PseudoClass))
+ {
+ /*
+ Threshold image to bilevel
+ */
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(Bilevel) Smashing to bilevel using Threshold method ...");
+ (void) ThresholdImage(image,(double)MaxRGB/2);
+ (void) AllocateImageColormap(image,2);
+ }
+ }
+ else
+ {
+ /*
+ Dither image to bilevel (very slow!)
+ */
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.colorspace=GRAYColorspace;
+ quantize_info.dither=image->dither;
+ quantize_info.tree_depth=8;
+ quantize_info.number_colors=2;
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(Bilevel) Dithering to bilevel using Quantize method ...");
+ (void) QuantizeImage(&quantize_info,image);
+ }
+ image->colorspace=GRAYColorspace;
+ image->is_grayscale=True;
+ image->is_monochrome=True;
+ break;
+ }
+ case GrayscaleType:
+ {
+ if (!IsRGBColorspace(image->colorspace))
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(Grayscale) Transforming to RGB colorspace ...");
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+ if (!image->is_grayscale)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(Grayscale) Transforming to gray colorspace ...");
+ (void) TransformColorspace(image,GRAYColorspace);
+ }
+ image->colorspace=GRAYColorspace;
+ image->is_grayscale=True;
+ break;
+ }
+ case GrayscaleMatteType:
+ {
+ if (!IsRGBColorspace(image->colorspace))
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(GrayscaleMatte) Transforming to RGB colorspace ...");
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+ if (!image->is_grayscale)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(GrayscaleMatte) Transforming to gray colorspace ...");
+ (void) TransformColorspace(image,GRAYColorspace);
+ }
+ if (!image->matte)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(GrayscaleMatte) Adding opaque matte channel ...");
+ SetImageOpacity(image,OpaqueOpacity);
+ }
+ image->colorspace=GRAYColorspace;
+ image->is_grayscale=True;
+ break;
+ }
+ case PaletteType:
+ {
+ if (!IsRGBColorspace(image->colorspace))
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(Palette) Transforming to RGB colorspace ...");
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+ if (image->storage_class != PseudoClass)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(Palette) Using Quantize method ...");
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.dither=image->dither;
+ (void) QuantizeImage(&quantize_info,image);
+ }
+ break;
+ }
+ case PaletteMatteType:
+ {
+ if (!IsRGBColorspace(image->colorspace))
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(PaletteMatte) Transforming to RGB colorspace ...");
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+ if (!image->matte)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(PaletteMatte) Adding opaque matte channel ...");
+ SetImageOpacity(image,OpaqueOpacity);
+ }
+ if (image->storage_class != PseudoClass)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(PaletteMatteType) Using Quantize method ...");
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.colorspace=TransparentColorspace;
+ quantize_info.dither=image->dither;
+ (void) QuantizeImage(&quantize_info,image);
+ }
+ break;
+ }
+ case TrueColorType:
+ {
+ if (!IsRGBColorspace(image->colorspace))
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(TrueColor) Transforming to RGB colorspace ...");
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+ image->storage_class=DirectClass;
+ break;
+ }
+ case TrueColorMatteType:
+ {
+
+ if (!IsRGBColorspace(image->colorspace))
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(TrueColorMatte) Transforming to RGB colorspace ...");
+ (void) TransformColorspace(image,RGBColorspace);
+ }
+ image->storage_class=DirectClass;
+ if (!image->matte)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(TrueColorMatte) Adding opaque matte channel ...");
+ SetImageOpacity(image,OpaqueOpacity);
+ }
+ break;
+ }
+ case ColorSeparationType:
+ {
+ if (image->colorspace != CMYKColorspace)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(ColorSeparation) Transforming to CMYK colorspace ...");
+ (void) TransformColorspace(image,CMYKColorspace);
+ }
+ break;
+ }
+ case ColorSeparationMatteType:
+ {
+ if (image->colorspace != CMYKColorspace)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(ColorSeparationMatte) Transforming to CMYK colorspace ...");
+ (void) TransformColorspace(image,CMYKColorspace);
+ }
+ if (!image->matte)
+ {
+ if (logging)
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "SetImageType(ColorSeparationMatte) Adding opaque matte channel ...");
+ SetImageOpacity(image,OpaqueOpacity);
+ }
+ break;
+ }
+ case OptimizeType:
+ default:
+ break;
+ }
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S t r i p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% StripImage removes all profiles and text attributes from the image.
+%
+% The format of the StripImage method is:
+%
+% MagickPassFail StripImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+*/
+MagickExport MagickPassFail
+StripImage(Image *image)
+{
+ /* Text attributes to strip. List is NULL terminated. */
+ static const char *strip_attributes[] =
+ {
+ "artist",
+ "comment",
+ "copyright",
+ "hostcomputer",
+ "label",
+ "make",
+ "model",
+ "timestamp",
+ (const char *) NULL
+ };
+
+ unsigned int
+ i;
+
+ assert(image != (Image *) NULL);
+
+ /* Strip all profiles */
+ (void) ProfileImage(image,"*",NULL,0,MagickFalse);
+
+ /* Strip common text attributes */
+ for (i=0; strip_attributes[i] != NULL; i++)
+ (void) SetImageAttribute(image,strip_attributes[i],(char *) NULL);
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S y n c I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SyncImage initializes the red, green, and blue intensities of each
+% pixel as defined by the colormap index.
+%
+% The format of the SyncImage method is:
+%
+% MagickPassFail SyncImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+#define SyncImageText "[%s] Synchronizing pixels..."
+static MagickPassFail
+SyncImageCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ /*
+ Synchronize DirectClass pixels with Indexes and colormap.
+ */
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(immutable_data);
+ ARG_NOT_USED(exception);
+
+ if (image->matte)
+ {
+ register const PixelPacket
+ *p;
+
+ for (i=0; i < npixels; i++)
+ {
+ VerifyColormapIndex(image,indexes[i]);
+ /*
+ Explicit member assignment is used in order to support a colormap
+ simultaneous with with pixel opacity.
+ */
+ p=&image->colormap[indexes[i]];
+ pixels[i].red=p->red;
+ pixels[i].green=p->green;
+ pixels[i].blue=p->blue;
+ }
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ {
+ VerifyColormapIndex(image,indexes[i]);
+ /*
+ Use structure assignment for improved performance.
+ Trash whatever is in the opacity channel.
+ */
+ pixels[i]=image->colormap[indexes[i]];
+ }
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail SyncImage(Image *image)
+{
+ MagickBool
+ is_grayscale,
+ is_monochrome;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (image->storage_class == DirectClass)
+ return (status);
+ assert(image->colormap != (PixelPacket *) NULL);
+ is_grayscale=image->is_grayscale;
+ is_monochrome=image->is_monochrome;
+ status=PixelIterateMonoModify(SyncImageCallBack,NULL,
+ SyncImageText,
+ NULL,NULL,0,0,image->columns,image->rows,
+ image,&image->exception);
+ image->is_grayscale=is_grayscale;
+ image->is_monochrome=is_monochrome;
+ return (status);
+}
diff --git a/magick/image.h b/magick/image.h
new file mode 100644
index 0000000..3672d93
--- /dev/null
+++ b/magick/image.h
@@ -0,0 +1,1090 @@
+/*
+ Copyright (C) 2003 - 2015 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Image Methods.
+*/
+#ifndef _MAGICK_IMAGE_H
+#define _MAGICK_IMAGE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/forward.h"
+#include "magick/colorspace.h"
+#include "magick/error.h"
+#include "magick/timer.h"
+
+/*
+ Define declarations.
+*/
+#if !defined(QuantumDepth)
+# define QuantumDepth 16
+#endif
+
+/*
+ Maximum unsigned RGB value which fits in the specified bits
+*/
+#define MaxValueGivenBits(bits) ((unsigned long) (0x01UL << (bits-1)) +((0x01UL << (bits-1))-1))
+
+#if (QuantumDepth == 8)
+# define MaxColormapSize 256U
+# define MaxMap 255U
+# define MaxMapDepth 8
+# define MaxMapFloat 255.0f
+# define MaxMapDouble 255.0
+# define MaxRGB 255U
+# define MaxRGBFloat 255.0f
+# define MaxRGBDouble 255.0
+# define ScaleCharToMap(value) ((unsigned char) (value))
+# define ScaleCharToQuantum(value) ((Quantum) (value))
+# define ScaleLongToQuantum(value) ((Quantum) ((value)/16843009UL))
+# define ScaleMapToChar(value) ((unsigned int) (value))
+# define ScaleMapToQuantum(value) ((Quantum) (value))
+# define ScaleQuantum(quantum) ((unsigned long) (quantum))
+# define ScaleQuantumToChar(quantum) ((unsigned char) (quantum))
+# define ScaleQuantumToLong(quantum) ((unsigned long) (16843009UL*(quantum)))
+# define ScaleQuantumToMap(quantum) ((unsigned char) (quantum))
+# define ScaleQuantumToShort(quantum) ((unsigned short) (257U*(quantum)))
+# define ScaleShortToQuantum(value) ((Quantum) ((value)/257U))
+# define ScaleToQuantum(value) ((unsigned long) (value))
+# define ScaleQuantumToIndex(value) ((unsigned char) (value))
+ typedef unsigned char Quantum;
+#elif (QuantumDepth == 16)
+# define MaxColormapSize 65536U
+# define MaxMap 65535U
+# define MaxMapDepth 16
+# define MaxMapFloat 65535.0f
+# define MaxMapDouble 65535.0
+# define MaxRGB 65535U
+# define MaxRGBFloat 65535.0f
+# define MaxRGBDouble 65535.0
+# define ScaleCharToMap(value) ((unsigned short) (257U*(value)))
+# define ScaleCharToQuantum(value) ((Quantum) (257U*(value)))
+# define ScaleLongToQuantum(value) ((Quantum) ((value)/65537UL))
+# define ScaleMapToChar(value) ((unsigned int) ((value)/257U))
+# define ScaleMapToQuantum(value) ((Quantum) (value))
+# define ScaleQuantum(quantum) ((unsigned long) ((quantum)/257UL))
+# define ScaleQuantumToChar(quantum) ((unsigned char) ((quantum)/257U))
+# define ScaleQuantumToLong(quantum) ((unsigned long) (65537UL*(quantum)))
+# define ScaleQuantumToMap(quantum) ((unsigned short) (quantum))
+# define ScaleQuantumToShort(quantum) ((unsigned short) (quantum))
+# define ScaleShortToQuantum(value) ((Quantum) (value))
+# define ScaleToQuantum(value) ((unsigned long) (257UL*(value)))
+# define ScaleQuantumToIndex(value) ((unsigned short) (value))
+ typedef unsigned short Quantum;
+#elif (QuantumDepth == 32)
+# define MaxColormapSize 65536U
+# define MaxRGB 4294967295U
+# define MaxRGBFloat 4294967295.0f
+# define MaxRGBDouble 4294967295.0
+# define ScaleCharToQuantum(value) ((Quantum) (16843009U*(value)))
+# define ScaleLongToQuantum(value) ((Quantum) ((value)))
+# define ScaleQuantum(quantum) ((unsigned long) ((quantum)/16843009UL))
+# define ScaleQuantumToChar(quantum) ((unsigned char) ((quantum)/16843009U))
+# define ScaleQuantumToLong(quantum) ((unsigned long) (quantum))
+# define ScaleQuantumToShort(quantum) ((unsigned short) ((quantum)/65537U))
+# define ScaleShortToQuantum(value) ((Quantum) (65537U*(value)))
+# define ScaleToQuantum(value) ((unsigned long) (16843009UL*(value)))
+# define ScaleQuantumToIndex(value) ((unsigned short) ((value)/65537U))
+
+/*
+ MaxMap defines the maximum index value for algorithms which depend
+ on lookup tables (e.g. colorspace transformations and
+ normalization). When MaxMap is less than MaxRGB it is necessary to
+ downscale samples to fit the range of MaxMap. The number of bits
+ which are effectively preserved depends on the size of MaxMap.
+ MaxMap should be a multiple of 255 and no larger than MaxRGB. Note
+ that tables can become quite large and as the tables grow larger it
+ may take more time to compute the table than to process the image.
+*/
+#define MaxMap 65535U
+#define MaxMapDepth 16
+#define MaxMapFloat 65535.0f
+#define MaxMapDouble 65535.0
+#if MaxMap == 65535U
+# define ScaleCharToMap(value) ((unsigned short) (257U*(value)))
+# define ScaleMapToChar(value) ((unsigned int) ((value)/257U))
+# define ScaleMapToQuantum(value) ((Quantum) (65537U*(value)))
+# define ScaleQuantumToMap(quantum) ((unsigned short) ((quantum)/65537U))
+#else
+# define ScaleCharToMap(value) ((unsigned short) ((MaxMap/255U)*(value)))
+# define ScaleMapToChar(value) ((unsigned int) ((value)/(MaxMap/255U)))
+# define ScaleMapToQuantum(value) ((Quantum) ((MaxRGB/MaxMap)*(value)))
+# define ScaleQuantumToMap(quantum) ((unsigned short) ((quantum)/(MaxRGB/MaxMap)))
+#endif
+typedef unsigned int Quantum;
+#else
+# error "Specified value of QuantumDepth is not supported"
+#endif
+
+#define OpaqueOpacity 0UL
+#define TransparentOpacity MaxRGB
+#define RoundDoubleToQuantum(value) ((Quantum) (value < 0.0 ? 0U : \
+ (value > MaxRGBDouble) ? MaxRGB : value + 0.5))
+#define RoundFloatToQuantum(value) ((Quantum) (value < 0.0f ? 0U : \
+ (value > MaxRGBFloat) ? MaxRGB : value + 0.5f))
+#define ConstrainToRange(min,max,value) (value < min ? min : \
+ (value > max) ? max : value)
+#define ConstrainToQuantum(value) ConstrainToRange(0,MaxRGB,value)
+#define ScaleAnyToQuantum(x,max_value) \
+ ((Quantum) (((double) MaxRGBDouble*x)/max_value+0.5))
+#define MagickBoolToString(value) (value != MagickFalse ? "True" : "False")
+
+/*
+ Return MagickTrue if channel is enabled in channels. Allows using
+ code to adapt if ChannelType enumeration is changed to bit masks.
+*/
+#define MagickChannelEnabled(channels,channel) ((channels == AllChannels) || (channels == channel))
+
+/*
+ Deprecated defines.
+*/
+#define RunlengthEncodedCompression RLECompression
+#define RoundSignedToQuantum(value) RoundDoubleToQuantum(value)
+#define RoundToQuantum(value) RoundDoubleToQuantum(value)
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ UnspecifiedAlpha,
+ AssociatedAlpha,
+ UnassociatedAlpha
+} AlphaType;
+
+typedef enum
+{
+ UndefinedChannel,
+ RedChannel, /* RGB Red channel */
+ CyanChannel, /* CMYK Cyan channel */
+ GreenChannel, /* RGB Green channel */
+ MagentaChannel, /* CMYK Magenta channel */
+ BlueChannel, /* RGB Blue channel */
+ YellowChannel, /* CMYK Yellow channel */
+ OpacityChannel, /* Opacity channel */
+ BlackChannel, /* CMYK Black (K) channel */
+ MatteChannel, /* Same as Opacity channel (deprecated) */
+ AllChannels, /* Color channels */
+ GrayChannel /* Color channels represent an intensity. */
+} ChannelType;
+
+typedef enum
+{
+ UndefinedClass,
+ DirectClass,
+ PseudoClass
+} ClassType;
+
+typedef enum
+{
+ UndefinedCompositeOp = 0,
+ OverCompositeOp,
+ InCompositeOp,
+ OutCompositeOp,
+ AtopCompositeOp,
+ XorCompositeOp,
+ PlusCompositeOp,
+ MinusCompositeOp,
+ AddCompositeOp,
+ SubtractCompositeOp,
+ DifferenceCompositeOp,
+ MultiplyCompositeOp,
+ BumpmapCompositeOp,
+ CopyCompositeOp,
+ CopyRedCompositeOp,
+ CopyGreenCompositeOp,
+ CopyBlueCompositeOp,
+ CopyOpacityCompositeOp,
+ ClearCompositeOp,
+ DissolveCompositeOp,
+ DisplaceCompositeOp,
+ ModulateCompositeOp,
+ ThresholdCompositeOp,
+ NoCompositeOp,
+ DarkenCompositeOp,
+ LightenCompositeOp,
+ HueCompositeOp,
+ SaturateCompositeOp,
+ ColorizeCompositeOp,
+ LuminizeCompositeOp,
+ ScreenCompositeOp,
+ OverlayCompositeOp,
+ CopyCyanCompositeOp,
+ CopyMagentaCompositeOp,
+ CopyYellowCompositeOp,
+ CopyBlackCompositeOp,
+ DivideCompositeOp,
+ HardLightCompositeOp,
+ ExclusionCompositeOp,
+ ColorDodgeCompositeOp,
+ ColorBurnCompositeOp,
+ SoftLightCompositeOp,
+ LinearBurnCompositeOp,
+ LinearDodgeCompositeOp,
+ LinearLightCompositeOp,
+ VividLightCompositeOp,
+ PinLightCompositeOp,
+ HardMixCompositeOp
+} CompositeOperator;
+
+typedef enum
+{
+ UndefinedCompression,
+ NoCompression,
+ BZipCompression,
+ FaxCompression,
+ Group3Compression = FaxCompression,
+ Group4Compression,
+ JPEGCompression,
+ LosslessJPEGCompression,
+ LZWCompression,
+ RLECompression,
+ ZipCompression,
+ LZMACompression, /* Lempel-Ziv-Markov chain algorithm */
+ JPEG2000Compression, /* ISO/IEC std 15444-1 */
+ JBIG1Compression, /* ISO/IEC std 11544 / ITU-T rec T.82 */
+ JBIG2Compression /* ISO/IEC std 14492 / ITU-T rec T.88 */
+} CompressionType;
+
+typedef enum
+{
+ UndefinedDispose,
+ NoneDispose,
+ BackgroundDispose,
+ PreviousDispose
+} DisposeType;
+
+typedef enum
+{
+ UndefinedEndian,
+ LSBEndian, /* "little" endian */
+ MSBEndian, /* "big" endian */
+ NativeEndian /* native endian */
+} EndianType;
+
+typedef enum
+{
+ UndefinedFilter,
+ PointFilter,
+ BoxFilter,
+ TriangleFilter,
+ HermiteFilter,
+ HanningFilter,
+ HammingFilter,
+ BlackmanFilter,
+ GaussianFilter,
+ QuadraticFilter,
+ CubicFilter,
+ CatromFilter,
+ MitchellFilter,
+ LanczosFilter,
+ BesselFilter,
+ SincFilter
+} FilterTypes;
+
+typedef enum
+{
+#undef NoValue
+ NoValue = 0x00000,
+#undef XValue
+ XValue = 0x00001,
+#undef YValue
+ YValue = 0x00002,
+#undef WidthValue
+ WidthValue = 0x00004,
+#undef HeightValue
+ HeightValue = 0x00008,
+#undef AllValues
+ AllValues = 0x0000F,
+#undef XNegative
+ XNegative = 0x00010,
+#undef YNegative
+ YNegative = 0x00020,
+ PercentValue = 0x01000, /* % */
+ AspectValue = 0x02000, /* ! */
+ LessValue = 0x04000, /* < */
+ GreaterValue = 0x08000, /* > */
+ AreaValue = 0x10000, /* @ */
+ MinimumValue = 0x20000 /* ^ */
+} GeometryFlags;
+
+typedef enum
+{
+#undef ForgetGravity
+ ForgetGravity,
+#undef NorthWestGravity
+ NorthWestGravity,
+#undef NorthGravity
+ NorthGravity,
+#undef NorthEastGravity
+ NorthEastGravity,
+#undef WestGravity
+ WestGravity,
+#undef CenterGravity
+ CenterGravity,
+#undef EastGravity
+ EastGravity,
+#undef SouthWestGravity
+ SouthWestGravity,
+#undef SouthGravity
+ SouthGravity,
+#undef SouthEastGravity
+ SouthEastGravity,
+#undef StaticGravity
+ StaticGravity
+} GravityType;
+
+typedef enum
+{
+ UndefinedType,
+ BilevelType,
+ GrayscaleType,
+ GrayscaleMatteType,
+ PaletteType,
+ PaletteMatteType,
+ TrueColorType,
+ TrueColorMatteType,
+ ColorSeparationType,
+ ColorSeparationMatteType,
+ OptimizeType
+} ImageType;
+
+typedef enum
+{
+ UndefinedInterlace,
+ NoInterlace,
+ LineInterlace,
+ PlaneInterlace,
+ PartitionInterlace
+} InterlaceType;
+
+typedef enum
+{
+ UndefinedMode,
+ FrameMode,
+ UnframeMode,
+ ConcatenateMode
+} MontageMode;
+
+typedef enum
+{
+ UniformNoise,
+ GaussianNoise,
+ MultiplicativeGaussianNoise,
+ ImpulseNoise,
+ LaplacianNoise,
+ PoissonNoise,
+ /* Below added on 2012-03-17 */
+ RandomNoise,
+ UndefinedNoise
+} NoiseType;
+
+/*
+ Image orientation. Based on TIFF standard values (also EXIF).
+*/
+typedef enum /* Line direction / Frame Direction */
+{ /* -------------- / --------------- */
+ UndefinedOrientation, /* Unknown / Unknown */
+ TopLeftOrientation, /* Left to right / Top to bottom */
+ TopRightOrientation, /* Right to left / Top to bottom */
+ BottomRightOrientation, /* Right to left / Bottom to top */
+ BottomLeftOrientation, /* Left to right / Bottom to top */
+ LeftTopOrientation, /* Top to bottom / Left to right */
+ RightTopOrientation, /* Top to bottom / Right to left */
+ RightBottomOrientation, /* Bottom to top / Right to left */
+ LeftBottomOrientation /* Bottom to top / Left to right */
+} OrientationType;
+
+typedef enum
+{
+ UndefinedPreview = 0,
+ RotatePreview,
+ ShearPreview,
+ RollPreview,
+ HuePreview,
+ SaturationPreview,
+ BrightnessPreview,
+ GammaPreview,
+ SpiffPreview,
+ DullPreview,
+ GrayscalePreview,
+ QuantizePreview,
+ DespecklePreview,
+ ReduceNoisePreview,
+ AddNoisePreview,
+ SharpenPreview,
+ BlurPreview,
+ ThresholdPreview,
+ EdgeDetectPreview,
+ SpreadPreview,
+ SolarizePreview,
+ ShadePreview,
+ RaisePreview,
+ SegmentPreview,
+ SwirlPreview,
+ ImplodePreview,
+ WavePreview,
+ OilPaintPreview,
+ CharcoalDrawingPreview,
+ JPEGPreview
+} PreviewType;
+
+typedef enum
+{
+ UndefinedIntent,
+ SaturationIntent,
+ PerceptualIntent,
+ AbsoluteIntent,
+ RelativeIntent
+} RenderingIntent;
+
+typedef enum
+{
+ UndefinedResolution,
+ PixelsPerInchResolution,
+ PixelsPerCentimeterResolution
+} ResolutionType;
+
+/*
+ Typedef declarations.
+*/
+typedef struct _AffineMatrix
+{
+ double
+ sx,
+ rx,
+ ry,
+ sy,
+ tx,
+ ty;
+} AffineMatrix;
+
+typedef struct _PrimaryInfo
+{
+ double
+ x,
+ y,
+ z;
+} PrimaryInfo;
+
+typedef struct _ChromaticityInfo
+{
+ PrimaryInfo
+ red_primary,
+ green_primary,
+ blue_primary,
+ white_point;
+} ChromaticityInfo;
+
+#if defined(MAGICK_IMPLEMENTATION)
+/*
+ Useful macros for accessing PixelPacket members in a generic way.
+*/
+# define GetRedSample(p) ((p)->red)
+# define GetGreenSample(p) ((p)->green)
+# define GetBlueSample(p) ((p)->blue)
+# define GetOpacitySample(p) ((p)->opacity)
+
+# define SetRedSample(q,value) ((q)->red=(value))
+# define SetGreenSample(q,value) ((q)->green=(value))
+# define SetBlueSample(q,value) ((q)->blue=(value))
+# define SetOpacitySample(q,value) ((q)->opacity=(value))
+
+# define GetGraySample(p) ((p)->red)
+# define SetGraySample(q,value) ((q)->red=(q)->green=(q)->blue=(value))
+
+# define GetYSample(p) ((p)->red)
+# define GetCbSample(p) ((p)->green)
+# define GetCrSample(p) ((p)->blue)
+
+# define SetYSample(q,value) ((q)->red=(value))
+# define SetCbSample(q,value) ((q)->green=(value))
+# define SetCrSample(q,value) ((q)->blue=(value))
+
+# define GetCyanSample(p) ((p)->red)
+# define GetMagentaSample(p) ((p)->green)
+# define GetYellowSample(p) ((p)->blue)
+# define GetBlackSample(p) ((p)->opacity)
+
+# define SetCyanSample(q,value) ((q)->red=(value))
+# define SetMagentaSample(q,value) ((q)->green=(value))
+# define SetYellowSample(q,value) ((q)->blue=(value))
+# define SetBlackSample(q,value) ((q)->opacity=(value))
+
+# define ClearPixelPacket(q) ((q)->red=(q)->green=(q)->blue=(q)->opacity=0)
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+typedef struct _PixelPacket
+{
+#if defined(WORDS_BIGENDIAN)
+ /* RGBA */
+#define MAGICK_PIXELS_RGBA 1
+ Quantum
+ red,
+ green,
+ blue,
+ opacity;
+#else
+ /* BGRA (as used by Microsoft Windows DIB) */
+#define MAGICK_PIXELS_BGRA 1
+ Quantum
+ blue,
+ green,
+ red,
+ opacity;
+#endif
+} PixelPacket;
+
+typedef struct _DoublePixelPacket
+{
+ double
+ red,
+ green,
+ blue,
+ opacity;
+} DoublePixelPacket;
+
+typedef struct _FloatPixelPacket
+{
+ float
+ red,
+ green,
+ blue,
+ opacity;
+} FloatPixelPacket;
+
+/*
+ ErrorInfo is used to record statistical difference (error)
+ information based on computed Euclidean distance in RGB space.
+*/
+typedef struct _ErrorInfo
+{
+ double
+ mean_error_per_pixel, /* Average error per pixel (absolute range) */
+ normalized_mean_error, /* Average error per pixel (normalized to 1.0) */
+ normalized_maximum_error; /* Maximum error encountered (normalized to 1.0) */
+} ErrorInfo;
+
+typedef struct _FrameInfo
+{
+ unsigned long
+ width,
+ height;
+
+ long
+ x,
+ y,
+ inner_bevel,
+ outer_bevel;
+} FrameInfo;
+
+typedef Quantum IndexPacket;
+
+typedef struct _LongPixelPacket
+{
+ unsigned long
+ red,
+ green,
+ blue,
+ opacity;
+} LongPixelPacket;
+
+typedef struct _MontageInfo
+{
+ char
+ *geometry,
+ *tile,
+ *title,
+ *frame,
+ *texture,
+ *font;
+
+ double
+ pointsize;
+
+ unsigned long
+ border_width;
+
+ unsigned int
+ shadow;
+
+ PixelPacket
+ fill,
+ stroke,
+ background_color,
+ border_color,
+ matte_color;
+
+ GravityType
+ gravity;
+
+ char
+ filename[MaxTextExtent];
+
+ unsigned long
+ signature;
+} MontageInfo;
+
+typedef struct _ProfileInfo
+{
+ size_t
+ length;
+
+ char
+ *name;
+
+ unsigned char
+ *info;
+} ProfileInfo;
+
+typedef struct _RectangleInfo
+{
+ unsigned long
+ width,
+ height;
+
+ long
+ x,
+ y;
+} RectangleInfo;
+
+typedef struct _SegmentInfo
+{
+ double
+ x1,
+ y1,
+ x2,
+ y2;
+} SegmentInfo;
+
+typedef struct _Image
+{
+ ClassType
+ storage_class; /* DirectClass (TrueColor) or PseudoClass (colormapped) */
+
+ ColorspaceType
+ colorspace; /* Current image colorspace/model */
+
+ CompressionType
+ compression; /* Compression algorithm to use when encoding image */
+
+ MagickBool
+ dither, /* True if image is to be dithered */
+ matte; /* True if image has an opacity (alpha) channel */
+
+ unsigned long
+ columns, /* Number of image columns */
+ rows; /* Number of image rows */
+
+ unsigned int
+ colors, /* Current number of colors in PseudoClass colormap */
+ depth; /* Bits of precision to preserve in color quantum */
+
+ PixelPacket
+ *colormap; /* Pseudoclass colormap array */
+
+ PixelPacket
+ background_color, /* Background color */
+ border_color, /* Border color */
+ matte_color; /* Matte (transparent) color */
+
+ double
+ gamma; /* Image gamma (e.g. 0.45) */
+
+ ChromaticityInfo
+ chromaticity; /* Red, green, blue, and white chromaticity values */
+
+ OrientationType
+ orientation; /* Image orientation */
+
+ RenderingIntent
+ rendering_intent; /* Rendering intent */
+
+ ResolutionType
+ units; /* Units of image resolution (density) */
+
+ char
+ *montage, /* Tile size and offset within an image montage */
+ *directory, /* Tile names from within an image montage */
+ *geometry; /* Composite/Crop options */
+
+ long
+ offset; /* Offset to start of image data */
+
+ double
+ x_resolution, /* Horizontal resolution (also see units) */
+ y_resolution; /* Vertical resolution (also see units) */
+
+ RectangleInfo
+ page, /* Offset to apply when placing image */
+ tile_info; /* Subregion tile dimensions and offset */
+
+ double
+ blur, /* Amount of blur to apply when zooming image */
+ fuzz; /* Colors within this distance match target color */
+
+ FilterTypes
+ filter; /* Filter to use when zooming image */
+
+ InterlaceType
+ interlace; /* Interlace pattern to use when writing image */
+
+ EndianType
+ endian; /* Byte order to use when writing image */
+
+ GravityType
+ gravity; /* Image placement gravity */
+
+ CompositeOperator
+ compose; /* Image placement composition (default OverCompositeOp) */
+
+ DisposeType
+ dispose; /* GIF disposal option */
+
+ unsigned long
+ scene, /* Animation frame scene number */
+ delay, /* Animation frame scene delay */
+ iterations, /* Animation iterations */
+ total_colors; /* Number of unique colors. See GetNumberColors() */
+
+ long
+ start_loop; /* Animation frame number to start looping at */
+
+ ErrorInfo
+ error; /* Computed image comparison or quantization error */
+
+ TimerInfo
+ timer; /* Operation micro-timer */
+
+ void
+ *client_data; /* User specified opaque data pointer */
+
+ /*
+ Output file name.
+
+ A colon delimited format identifier may be prepended to the file
+ name in order to force a particular output format. Otherwise the
+ file extension is used. If no format prefix or file extension is
+ present, then the output format is determined by the 'magick'
+ field.
+ */
+ char
+ filename[MaxTextExtent];
+
+ /*
+ Original file name (name of input image file)
+ */
+ char
+ magick_filename[MaxTextExtent];
+
+ /*
+ File format of the input file, and the default output format.
+
+ The precedence when selecting the output format is:
+ 1) magick prefix to file name (e.g. "jpeg:foo).
+ 2) file name extension. (e.g. "foo.jpg")
+ 3) content of this magick field.
+
+ */
+ char
+ magick[MaxTextExtent];
+
+ /*
+ Original image width (before transformations)
+ */
+ unsigned long
+ magick_columns;
+
+ /*
+ Original image height (before transformations)
+ */
+ unsigned long
+ magick_rows;
+
+ ExceptionInfo
+ exception; /* Any error associated with this image frame */
+
+ struct _Image
+ *previous, /* Pointer to previous frame */
+ *next; /* Pointer to next frame */
+
+ /*
+ To be added here for a later release:
+
+ quality?
+ subsampling
+ video black/white setup levels (ReferenceBlack/ReferenceWhite)
+ sample format (integer/float)
+ */
+
+ /*
+ Only private members appear past this point
+ */
+
+ void /* Private, Embedded profiles */
+ *profiles;
+
+ unsigned int
+ is_monochrome, /* Private, True if image is known to be monochrome */
+ is_grayscale, /* Private, True if image is known to be grayscale */
+ taint; /* Private, True if image has not been modifed */
+
+ struct _Image
+ *clip_mask; /* Private, Clipping mask to apply when updating pixels */
+
+ MagickBool
+ ping; /* Private, if true, pixels are undefined */
+
+ _CacheInfoPtr_
+ cache; /* Private, image pixel cache */
+
+ _ThreadViewSetPtr_
+ default_views; /* Private, default cache views */
+
+ _ImageAttributePtr_
+ attributes; /* Private, Image attribute list */
+
+ _Ascii85InfoPtr_
+ ascii85; /* Private, supports huffman encoding */
+
+ _BlobInfoPtr_
+ blob; /* Private, file I/O object */
+
+ long
+ reference_count; /* Private, Image reference count */
+
+ _SemaphoreInfoPtr_
+ semaphore; /* Private, Per image lock (for reference count) */
+
+ unsigned int
+ logging; /* Private, True if logging is enabled */
+
+ struct _Image
+ *list; /* Private, used only by display */
+
+ unsigned long
+ signature; /* Private, Unique code to validate structure */
+} Image;
+
+typedef struct _ImageInfo
+{
+ CompressionType
+ compression; /* Image compression to use while decoding */
+
+ MagickBool
+ temporary, /* Remove file "filename" once it has been read. */
+ adjoin, /* If True, join multiple frames into one file */
+ antialias; /* If True, antialias while rendering */
+
+ unsigned long
+ subimage, /* Starting image scene ID to select */
+ subrange, /* Span of image scene IDs (from starting scene) to select */
+ depth; /* Number of quantum bits to preserve while encoding */
+
+ char
+ *size, /* Desired/known dimensions to use when decoding image */
+ *tile, /* Deprecated, name of image to tile on background */
+ *page; /* Output page size & offset */
+
+ InterlaceType
+ interlace; /* Interlace scheme to use when decoding image */
+
+ EndianType
+ endian; /* Select MSB/LSB endian output for TIFF format */
+
+ ResolutionType
+ units; /* Units to apply when evaluating the density option */
+
+ unsigned long
+ quality; /* Compression quality factor (format specific) */
+
+ char
+ *sampling_factor, /* JPEG, MPEG, and YUV chroma downsample factor */
+ *server_name, /* X11 server display specification */
+ *font, /* Font name to use for text annotations */
+ *texture, /* Name of texture image to use for background fills */
+ *density; /* Image resolution (also see units) */
+
+ double
+ pointsize; /* Font pointsize */
+
+ double
+ fuzz; /* Colors within this distance are a match */
+
+ PixelPacket
+ pen, /* Stroke or fill color while drawing */
+ background_color, /* Background color */
+ border_color, /* Border color (color surrounding frame) */
+ matte_color; /* Matte color (frame color) */
+
+ MagickBool
+ dither, /* If true, dither image while writing */
+ monochrome, /* If true, use monochrome format */
+ progress; /* If true, show progress indication */
+
+ ColorspaceType
+ colorspace; /* Colorspace representations of image pixels */
+
+ ImageType
+ type; /* Desired image type (used while reading or writing) */
+
+ long
+ group; /* X11 window group ID */
+
+ unsigned int
+ verbose; /* If non-zero, display high-level processing */
+
+ char
+ *view, /* FlashPIX view specification */
+ *authenticate; /* Password used to decrypt file */
+
+ void
+ *client_data; /* User-specified data to pass to coder */
+
+ FILE
+ *file; /* If not null, stdio FILE * to read image from
+ (fopen mode "rb") or write image to (fopen
+ mode "rb+"). */
+
+ char
+ magick[MaxTextExtent], /* File format to read. Overrides file extension */
+ filename[MaxTextExtent]; /* File name to read */
+
+ /*
+ Only private members appear past this point
+ */
+
+ _CacheInfoPtr_
+ cache; /* Private. Used to pass image via open cache */
+
+ void
+ *definitions; /* Private. Map of coder specific options passed by user.
+ Use AddDefinitions, RemoveDefinitions, & AccessDefinition
+ to access and manipulate this data. */
+
+ Image
+ *attributes; /* Private. Image attribute list */
+
+ MagickBool
+ ping; /* Private, if true, read file header only */
+
+ PreviewType
+ preview_type; /* Private, used by PreviewImage */
+
+ MagickBool
+ affirm; /* Private, when true do not intuit image format */
+
+ _BlobInfoPtr_
+ blob; /* Private, used to pass in open blob */
+
+ size_t
+ length; /* Private, used to pass in open blob length */
+
+ char
+ unique[MaxTextExtent], /* Private, passes temporary filename to TranslateText */
+ zero[MaxTextExtent]; /* Private, passes temporary filename to TranslateText */
+
+ unsigned long
+ signature; /* Private, used to validate structure */
+} ImageInfo;
+
+/*
+ Image utilities methods.
+*/
+
+extern MagickExport ExceptionType
+ CatchImageException(Image *);
+
+extern MagickExport Image
+ *AllocateImage(const ImageInfo *),
+ *AppendImages(const Image *,const unsigned int,ExceptionInfo *),
+ *CloneImage(const Image *,const unsigned long,const unsigned long,
+ const unsigned int,ExceptionInfo *),
+ *GetImageClipMask(const Image *,ExceptionInfo *),
+ *ReferenceImage(Image *);
+
+extern MagickExport ImageInfo
+ *CloneImageInfo(const ImageInfo *);
+
+extern MagickExport const char
+ *AccessDefinition(const ImageInfo *image_info,const char *magick,
+ const char *key);
+
+extern MagickExport int
+ GetImageGeometry(const Image *,const char *,const unsigned int,
+ RectangleInfo *);
+
+/* Functions which return unsigned int as a True/False boolean value */
+extern MagickExport MagickBool
+ IsTaintImage(const Image *),
+ IsSubimage(const char *,const MagickBool);
+
+/* Functions which return unsigned int to indicate operation pass/fail */
+extern MagickExport MagickPassFail
+ AddDefinition(ImageInfo *image_info,const char *magick, const char *key,
+ const char *value, ExceptionInfo *exception),
+ AddDefinitions(ImageInfo *image_info,const char *options,
+ ExceptionInfo *exception),
+ AnimateImages(const ImageInfo *image_info,Image *image),
+ ClipImage(Image *image),
+ ClipPathImage(Image *image,const char *pathname,const MagickBool inside),
+ DisplayImages(const ImageInfo *image_info,Image *image),
+ RemoveDefinitions(const ImageInfo *image_info,const char *options),
+ ResetImagePage(Image *image,const char *page),
+ SetImage(Image *image,const Quantum),
+ SetImageEx(Image *image,const Quantum opacity,ExceptionInfo *exception),
+ SetImageColor(Image *image,const PixelPacket *pixel),
+ SetImageColorRegion(Image *image,long x,long y,unsigned long width,
+ unsigned long height,const PixelPacket *pixel),
+ SetImageClipMask(Image *image,const Image *clip_mask),
+ SetImageDepth(Image *image,const unsigned long),
+ SetImageInfo(ImageInfo *image_info,const unsigned int flags,ExceptionInfo *exception),
+ SetImageType(Image *image,const ImageType),
+ StripImage(Image *image),
+ SyncImage(Image *image);
+
+extern MagickExport void
+ AllocateNextImage(const ImageInfo *,Image *),
+ DestroyImage(Image *),
+ DestroyImageInfo(ImageInfo *),
+ GetImageException(Image *,ExceptionInfo *),
+ GetImageInfo(ImageInfo *),
+ ModifyImage(Image **,ExceptionInfo *),
+ SetImageOpacity(Image *,const unsigned int);
+
+#if defined(MAGICK_IMPLEMENTATION)
+ /*
+ SetImageInfo flags specification.
+ */
+# define SETMAGICK_FALSE 0x00000 /* MagickFalse ("read") */
+# define SETMAGICK_TRUE 0x00001 /* MagickTrue ("write+rectify") */
+# define SETMAGICK_READ 0x00002 /* Filespec will be read */
+# define SETMAGICK_WRITE 0x00004 /* Filespec will be written */
+# define SETMAGICK_RECTIFY 0x00008 /* Look for adjoin in filespec */
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_IMAGE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/import.c b/magick/import.c
new file mode 100644
index 0000000..1f2f8c4
--- /dev/null
+++ b/magick/import.c
@@ -0,0 +1,3740 @@
+/*
+ Copyright (C) 2003 - 2012 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Methods to import image pixels from common representations
+
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/bit_stream.h"
+#include "magick/colormap.h"
+#include "magick/constitute.h"
+#include "magick/floats.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/utility.h"
+
+/*
+ Type definitions
+*/
+static const PixelPacket BlackPixel = {0, 0, 0, OpaqueOpacity};
+
+static const PixelPacket WhitePixel = {MaxRGB, MaxRGB, MaxRGB, OpaqueOpacity};
+
+/*
+ Macros
+*/
+
+#if defined(WORDS_BIGENDIAN)
+# define MyEndianType MSBEndian
+#else
+# define MyEndianType LSBEndian
+#endif
+
+#define ImportModulo8Quantum(quantum,quantum_size,p) \
+ { \
+ register unsigned int \
+ shift; \
+ \
+ quantum=0; \
+ if (LSBEndian != endian) \
+ { \
+ shift=quantum_size; \
+ do \
+ { \
+ shift -= 8U; \
+ quantum |= (*p++ << shift); \
+ } while( shift > 0U); \
+ } \
+ else \
+ { \
+ shift=0U; \
+ while ( shift < quantum_size ) \
+ { \
+ quantum |= (*p++ << shift); \
+ shift += 8U; \
+ } \
+ } \
+ }
+#define ImportUInt8Quantum(quantum,p) \
+ { \
+ quantum=*p++; \
+ }
+#define ImportUInt16Quantum(endian,quantum,p) \
+ { \
+ if (LSBEndian != endian) \
+ { \
+ quantum=(*p++ << 8); \
+ quantum|=(*p++); \
+ } \
+ else \
+ { \
+ quantum=(*p++); \
+ quantum|=(*p++ << 8); \
+ } \
+ }
+/*
+ This algorithm has been compared with several others and did best
+ overall on SPARC, PowerPC, and Intel Xeon.
+*/
+#define ImportUInt32Quantum(endian,quantum,p) \
+ { \
+ if (LSBEndian != endian) \
+ { \
+ quantum=(*p++ << 24); \
+ quantum|=(*p++ << 16); \
+ quantum|=(*p++ << 8); \
+ quantum|=(*p++); \
+ } \
+ else \
+ { \
+ quantum=(*p++); \
+ quantum|=(*p++ << 8); \
+ quantum|=(*p++ << 16); \
+ quantum|=(*p++ << 24); \
+ } \
+ }
+/*
+ Import a 64-bit unsigned value into a 32-bit quantum type. This
+ approach is used since 64-bits is not supported internally and some
+ CPUs may perform poorly when using a true 64-bit type. In this case
+ the least significant 32 bits are entirely ignored.
+*/
+#define ImportUInt64Quantum(endian,quantum,p) \
+ { \
+ if (LSBEndian != endian) \
+ { \
+ quantum=(*p++ << 24); \
+ quantum|=(*p++ << 16); \
+ quantum|=(*p++ << 8); \
+ quantum|=(*p++); \
+ p+=4; \
+ } \
+ else \
+ { \
+ p+=4; \
+ quantum=(*p++); \
+ quantum|=(*p++ << 8); \
+ quantum|=(*p++ << 16); \
+ quantum|=(*p++ << 24); \
+ } \
+ }
+#define ImportFloat16Quantum(endian,value,p) \
+ { \
+ float float_value; \
+ unsigned char c[2]; \
+ if (MyEndianType == endian) \
+ { \
+ c[0]=*p++; \
+ c[1]=*p++; \
+ } \
+ else \
+ { \
+ c[1]=*p++; \
+ c[0]=*p++; \
+ } \
+ (void) _Gm_convert_fp16_to_fp32((const fp_16bits *)c, \
+ &float_value); \
+ value=float_value; \
+ }
+#define ImportFloat24Quantum(endian,value,p) \
+ { \
+ float float_value; \
+ unsigned char c[3]; \
+ if (MyEndianType == endian) \
+ { \
+ c[0]=*p++; \
+ c[1]=*p++; \
+ c[2]=*p++; \
+ } \
+ else \
+ { \
+ c[2]=*p++; \
+ c[1]=*p++; \
+ c[0]=*p++; \
+ } \
+ (void) _Gm_convert_fp24_to_fp32((const fp_24bits *)c, \
+ &float_value, \
+ RANGE_LIMITED); \
+ value=float_value; \
+}
+#define ImportFloat32Quantum(endian,value,p) \
+ { \
+ if (MyEndianType == endian) \
+ { \
+ value=*((float *) p); \
+ p += sizeof(float); \
+ } \
+ else \
+ { \
+ union \
+ { \
+ float f; \
+ unsigned char c[4]; \
+ } fu_; \
+ \
+ fu_.c[3]=*p++; \
+ fu_.c[2]=*p++; \
+ fu_.c[1]=*p++; \
+ fu_.c[0]=*p++; \
+ value=fu_.f; \
+ } \
+ }
+#define ImportFloat64Quantum(endian,value,p) \
+ { \
+ if (MyEndianType == endian) \
+ { \
+ value=*((double *) p); \
+ p += sizeof(double); \
+ } \
+ else \
+ { \
+ union \
+ { \
+ double d; \
+ unsigned char c[8]; \
+ } du_; \
+ \
+ du_.c[7]=*p++; \
+ du_.c[6]=*p++; \
+ du_.c[5]=*p++; \
+ du_.c[4]=*p++; \
+ du_.c[3]=*p++; \
+ du_.c[2]=*p++; \
+ du_.c[1]=*p++; \
+ du_.c[0]=*p++; \
+ value=du_.d; \
+ } \
+ }
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m p o r t I m a g e P i x e l A r e a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImportImagePixelArea() transfers one or more pixel components from a user
+% supplied buffer into the default image pixel cache view. By default,
+% values are read in network (big-endian) byte/bit order. By setting the
+% 'endian' member of ExportPixelAreaOptions, 16, 32 and 64-bit values may
+% be output as little (LSBEndian), big (MSBEndian), or host native
+% (NativeEndian) endian values. This function is quite powerful in that
+% besides common native CPU type sizes, it can support any integer bit
+% depth from 1 to 32 (e.g. 13), 64-bits, as well as 32 and 64-bit float.
+%
+% MagickPass is returned if the pixels are successfully transferred,
+% otherwise MagickFail.
+%
+% The format of the ImportImagePixelArea method is:
+%
+% MagickPassFail ImportImagePixelArea(Image *image,
+% const QuantumType quantum_type,
+% const unsigned int quantum_size,
+% const unsigned char *source,
+% const ImportPixelAreaOptions *options,
+% ImportPixelAreaInfo *import_info)
+%
+% A description of each parameter follows:
+%
+% o status: Method PushImagePixels returns MagickPass if the pixels are
+% successfully transferred, otherwise MagickFail.
+%
+% o image: The image.
+%
+% o quantum_type: Declare which pixel components to transfer (AlphaQuantum,
+% BlackQuantum, BlueQuantum, CMYKAQuantum, CMYKQuantum, CyanQuantum,
+% GrayAlphaQuantum, GrayQuantum, GreenQuantum, IndexAlphaQuantum,
+% IndexQuantum, MagentaQuantum, RGBAQuantum, RGBQuantum,
+% RedQuantum, YellowQuantum)
+%
+% o quantum_size: Bits per quantum sample (range 1-32, and 64).
+%
+% o source: The pixel components are transferred from this buffer.
+%
+% o options: Additional options specific to quantum_type (may be NULL).
+%
+% o import_info : Populated with information regarding the pixels
+% imported (may be NULL)
+%
+*/
+MagickExport MagickPassFail ImportImagePixelArea(Image *image,
+ const QuantumType quantum_type,const unsigned int quantum_size,
+ const unsigned char *source,const ImportPixelAreaOptions *options,
+ ImportPixelAreaInfo *import_info)
+{
+ return ImportViewPixelArea(AccessDefaultCacheView(image),
+ quantum_type,quantum_size,
+ source,options,import_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m p o r t V i e w P i x e l A r e a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImportViewPixelArea() transfers one or more pixel components from a user
+% supplied buffer into the specified image pixel cache view of an image. By
+% default, values are read in network (big-endian) byte/bit order. By
+% setting the 'endian' member of ExportPixelAreaOptions, 16, 32 and 64-bit
+% values may be output as little (LSBEndian), big (MSBEndian), or host
+% native (NativeEndian) endian values. This function is quite powerful in
+% that besides common native CPU type sizes, it can support any integer bit
+% depth from 1 to 32 (e.g. 13), 64-bits, as well as 32 and 64-bit float.
+%
+% MagickPass is returned if the pixels are successfully transferred,
+% otherwise MagickFail.
+%
+% The format of the ImportViewPixelArea method is:
+%
+% MagickPassFail ImportViewPixelArea(ViewInfo *view,
+% const QuantumType quantum_type,
+% const unsigned int quantum_size,
+% const unsigned char *source,
+% const ImportPixelAreaOptions *options,
+% ImportPixelAreaInfo *import_info)
+%
+% A description of each parameter follows:
+%
+% o status: Method PushImagePixels returns MagickPass if the pixels are
+% successfully transferred, otherwise MagickFail.
+%
+% o view: The pixel view to import pixels into.
+%
+% o quantum_type: Declare which pixel components to transfer (AlphaQuantum,
+% BlackQuantum, BlueQuantum, CMYKAQuantum, CMYKQuantum, CyanQuantum,
+% GrayAlphaQuantum, GrayQuantum, GreenQuantum, IndexAlphaQuantum,
+% IndexQuantum, MagentaQuantum, RGBAQuantum, RGBQuantum,
+% RedQuantum, YellowQuantum)
+%
+% o quantum_size: Bits per quantum sample (range 1-32, and 64).
+%
+% o source: The pixel components are transferred from this buffer.
+%
+% o options: Additional options specific to quantum_type (may be NULL).
+%
+% o import_info : Populated with information regarding the pixels
+% imported (may be NULL)
+%
+*/
+static MagickPassFail
+ImportIndexQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_maxvalue,
+ const EndianType endian,
+ Image *image,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ register unsigned int
+ index;
+
+ assert(image->colors <= MaxColormapSize);
+ assert(image->colors != 0);
+ assert(indexes != (IndexPacket *) NULL);
+
+ p=source;
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 1:
+ {
+ /*
+ Special fast support for two colors.
+ */
+ register unsigned int
+ bit = 8U;
+
+ for (x = number_pixels ; x != 0 ; --x )
+ {
+ --bit;
+ index=(*p >> bit) & 0x01;
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q++=image->colormap[index];
+ if (bit == 0)
+ {
+ bit=8;
+ p++;
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+ /*
+ Special fast support for 16 colors.
+ */
+ register unsigned int
+ state = 0;
+
+ for (x = number_pixels ; x != 0 ; --x )
+ {
+ state ^= 1; /* Produces 1 0 1 0 ... */
+ index=(IndexPacket) ((state ? (*p >> 4) : (*p++)) & 0xf);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ case 8:
+ {
+ if (unsigned_maxvalue <= (unsigned int) (image->colors-1))
+ {
+ /*
+ Special case for when it is impossible to
+ overflow the colormap range.
+ */
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt8Quantum(index,p);
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt8Quantum(index,p);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ for (x = number_pixels; x != 0; --x)
+ {
+ index=MagickBitStreamMSBRead(&stream,quantum_size);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportIndexAlphaQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const EndianType endian,
+ Image *image,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ register unsigned int
+ index,
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ assert(image->colors <= MaxColormapSize);
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch(quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt8Quantum(index,p);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q=image->colormap[index];
+
+ ImportUInt8Quantum(unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q=image->colormap[index];
+
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleShortToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q=image->colormap[index];
+
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q=image->colormap[index];
+
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ for (x = number_pixels; x != 0; --x)
+ {
+ index=MagickBitStreamMSBRead(&stream,quantum_size);
+ VerifyColormapIndex(image,index);
+ *indexes++=index;
+ *q=image->colormap[index];
+
+ unsigned_value=MagickBitStreamMSBRead(&stream,quantum_size);
+ if (QuantumDepth > sample_bits)
+ unsigned_value *= unsigned_scale;
+ else if (QuantumDepth < sample_bits)
+ unsigned_value /= unsigned_scale;
+ SetOpacitySample(q,MaxRGB-unsigned_value);
+ q++;
+ }
+ break;
+ }
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportGrayQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const unsigned int unsigned_maxvalue,
+ const MagickBool grayscale_miniswhite,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ Image *image,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ index,
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ if (DirectClass == image->storage_class)
+ {
+ /*
+ DirectClass representation.
+ */
+ switch (quantum_size)
+ {
+ case 1:
+ {
+ /*
+ Special fast support for bi-level gray.
+ */
+ register int
+ bit = 8;
+
+ PixelPacket
+ min_val,
+ max_val;
+
+ if (grayscale_miniswhite)
+ {
+ min_val=WhitePixel;
+ max_val=BlackPixel;
+ }
+ else
+ {
+ min_val=BlackPixel;
+ max_val=WhitePixel;
+ }
+
+ for (x = number_pixels ; x != 0 ; --x )
+ {
+ --bit;
+ *q++=(((*p >> bit) & 0x01) ? max_val : min_val);
+ if (bit == 0)
+ {
+ bit=8;
+ p++;
+ }
+ }
+ if (bit != 8)
+ p++;
+ break;
+ }
+ case 8:
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetGraySample(q,MaxRGB-ScaleCharToQuantum(*p++));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetGraySample(q,ScaleCharToQuantum(*p++));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetGraySample(q,MaxRGB-ScaleShortToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetGraySample(q,ScaleShortToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ break;
+ }
+ case 32:
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetGraySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetGraySample(q,ScaleLongToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ break;
+ }
+ case 64:
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetGraySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetGraySample(q,ScaleLongToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ for (x = number_pixels; x != 0; --x)
+ {
+ unsigned_value=MagickBitStreamMSBRead(&stream,quantum_size);
+ if (QuantumDepth > sample_bits)
+ unsigned_value *= unsigned_scale;
+ else if (QuantumDepth < sample_bits)
+ unsigned_value /= unsigned_scale;
+ if (grayscale_miniswhite)
+ unsigned_value = MaxRGB-unsigned_value;
+ SetGraySample(q,unsigned_value);
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ PseudoClass representation.
+
+ Note that this implementation assumes that the
+ colormap is written in ascending levels of intensity
+ as produced by AllocateImageColormap(). Some old
+ code may assume that 'miniswhite' inverts the
+ colormap order as well.
+ */
+ assert(image->colors <= MaxColormapSize);
+
+ switch (quantum_size)
+ {
+ case 1:
+ {
+ /*
+ Special fast support for bi-level gray.
+ */
+ register int
+ bit = 8;
+
+ for (x = number_pixels ; x != 0 ; --x )
+ {
+ --bit;
+ index=(*p >> bit) & 0x01;
+ if (grayscale_miniswhite)
+ index ^= 0x01;
+ *indexes++=index;
+ *q++=image->colormap[index];
+ if (bit == 0)
+ {
+ bit=8;
+ p++;
+ }
+ }
+ if (bit != 8)
+ p++;
+ break;
+ }
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt8Quantum(index,p);
+ VerifyColormapIndex(image,index);
+ if (grayscale_miniswhite)
+ index=(image->colors-1)-index;
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ if (grayscale_miniswhite)
+ index=(image->colors-1)-index;
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ if (grayscale_miniswhite)
+ index=(image->colors-1)-index;
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,index,p);
+ VerifyColormapIndex(image,index);
+ if (grayscale_miniswhite)
+ index=(image->colors-1)-index;
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ register unsigned int
+ indexes_scale = 1U;
+
+ if (unsigned_maxvalue > (image->colors-1))
+ indexes_scale=(unsigned_maxvalue/(image->colors-1));
+
+ MagickBitStreamInitializeRead(&stream,p);
+ for (x = number_pixels; x != 0; --x)
+ {
+ index=MagickBitStreamMSBRead(&stream,quantum_size);
+ index /= indexes_scale;
+ VerifyColormapIndex(image,index);
+ if (grayscale_miniswhite)
+ index=(image->colors-1)-index;
+ *indexes++=index;
+ *q++=image->colormap[index];
+ }
+ break;
+ }
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGraySample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGraySample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGraySample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGraySample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportGrayAlphaQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const unsigned int unsigned_maxvalue,
+ const MagickBool grayscale_miniswhite,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ Image *image,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ index,
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ if (DirectClass == image->storage_class)
+ {
+ /*
+ DirectClass representation.
+ */
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt8Quantum(unsigned_value,p);
+ SetGraySample(q,MaxRGB-ScaleCharToQuantum(unsigned_value));
+ ImportUInt8Quantum(unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(unsigned_value));
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt8Quantum(unsigned_value,p);
+ SetGraySample(q,ScaleCharToQuantum(unsigned_value));
+ ImportUInt8Quantum(unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(unsigned_value));
+ q++;
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetGraySample(q,MaxRGB-ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleShortToQuantum(unsigned_value));
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetGraySample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleShortToQuantum(unsigned_value));
+ q++;
+ }
+ }
+ break;
+ }
+ case 32:
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetGraySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetGraySample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ }
+ break;
+ }
+ case 64:
+ {
+ if (grayscale_miniswhite)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetGraySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetGraySample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary Depth.
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ for (x = number_pixels; x != 0; --x)
+ {
+ unsigned_value=MagickBitStreamMSBRead(&stream,quantum_size);
+ if (QuantumDepth > sample_bits)
+ unsigned_value *= unsigned_scale;
+ else if (QuantumDepth < sample_bits)
+ unsigned_value /= unsigned_scale;
+ if (grayscale_miniswhite)
+ unsigned_value = MaxRGB-unsigned_value;
+ SetGraySample(q,unsigned_value);
+
+ unsigned_value=MagickBitStreamMSBRead(&stream,quantum_size);
+ if (QuantumDepth > sample_bits)
+ unsigned_value *= unsigned_scale;
+ else if (QuantumDepth < sample_bits)
+ unsigned_value /= unsigned_scale;
+ SetOpacitySample(q,MaxRGB-unsigned_value);
+ q++;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ PseudoClass representation.
+ */
+ /*
+ Input is organized as a gray level followed by opacity level
+ Colormap array is pre-stuffed with ascending or descending gray
+ levels according to the gray quantum representation.
+ */
+ register unsigned int
+ indexes_scale = 1U;
+
+ assert(image->colors <= MaxColormapSize);
+
+ if (unsigned_maxvalue > (image->colors-1))
+ indexes_scale=(unsigned_maxvalue/(image->colors-1));
+
+ if ( (quantum_size >= 8) && (quantum_size % 8U == 0U) )
+ {
+ /*
+ Modulo-8 sample sizes
+ */
+ if (indexes_scale == 1U)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportModulo8Quantum(index,quantum_size,p);
+ VerifyColormapIndex(image,index);
+ if (grayscale_miniswhite)
+ index=(image->colors-1)-index;
+ *indexes++=index;
+ *q=image->colormap[index];
+
+ ImportModulo8Quantum(unsigned_value,quantum_size,p);
+ if (QuantumDepth > sample_bits)
+ unsigned_value *= unsigned_scale;
+ else if (QuantumDepth < sample_bits)
+ unsigned_value /= unsigned_scale;
+ SetOpacitySample(q,MaxRGB-unsigned_value);
+ q++;
+ }
+ }
+ else
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportModulo8Quantum(index,quantum_size,p);
+ index /= indexes_scale;
+ VerifyColormapIndex(image,index);
+ if (grayscale_miniswhite)
+ index=(image->colors-1)-index;
+ *indexes++=index;
+ *q=image->colormap[index];
+
+ ImportModulo8Quantum(unsigned_value,quantum_size,p);
+ if (QuantumDepth > sample_bits)
+ unsigned_value *= unsigned_scale;
+ else if (QuantumDepth < sample_bits)
+ unsigned_value /= unsigned_scale;
+ SetOpacitySample(q,MaxRGB-unsigned_value);
+ q++;
+ }
+ }
+ }
+ else
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ for (x = number_pixels; x != 0; --x)
+ {
+ index=MagickBitStreamMSBRead(&stream,quantum_size);
+ index /= indexes_scale;
+ VerifyColormapIndex(image,index);
+ if (grayscale_miniswhite)
+ index=(image->colors-1)-index;
+ *indexes++=index;
+ *q=image->colormap[index];
+
+ unsigned_value=MagickBitStreamMSBRead(&stream,quantum_size);
+ if (QuantumDepth > sample_bits)
+ unsigned_value *= unsigned_scale;
+ else if (QuantumDepth < sample_bits)
+ unsigned_value /= unsigned_scale;
+ SetOpacitySample(q,MaxRGB-unsigned_value);
+ q++;
+ }
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGraySample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGraySample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGraySample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGraySample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportRedQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetRedSample(q,ScaleCharToQuantum(*p++));
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleShortToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetRedSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ q++;
+ }
+ }
+ else
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetRedSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ q++;
+ }
+ }
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportGreenQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetGreenSample(q,ScaleCharToQuantum(*p++));
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleShortToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetGreenSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ q++;
+ }
+ }
+ else
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetGreenSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ q++;
+ }
+ }
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportBlueQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetBlueSample(q,ScaleCharToQuantum(*p++));
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleShortToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetBlueSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ q++;
+ }
+ }
+ else
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetBlueSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ q++;
+ }
+ }
+ break;
+ }
+ }
+
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportAlphaQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ Image *image,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (image->colorspace == CMYKColorspace)
+ {
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ if ( (quantum_size >= 8) && (quantum_size % 8U == 0U) )
+ {
+ /*
+ Modulo-8 sample sizes
+ */
+ if( QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportModulo8Quantum(unsigned_value,quantum_size,p);
+ *indexes++=(IndexPacket) MaxRGB-unsigned_value;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportModulo8Quantum(unsigned_value,quantum_size,p);
+ *indexes++=(IndexPacket) MaxRGB-unsigned_value*unsigned_scale;
+ }
+ }
+ else
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportModulo8Quantum(unsigned_value,quantum_size,p);
+ *indexes++=(IndexPacket) MaxRGB-unsigned_value/unsigned_scale;
+ }
+ }
+ }
+ else
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ *indexes++=(IndexPacket) MaxRGB-MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale;
+ }
+ }
+ else
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ *indexes++=(IndexPacket) MaxRGB-MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale;
+ }
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ *indexes++=(IndexPacket) MaxRGB-RoundDoubleToQuantum(double_value);
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ *indexes++=(IndexPacket) MaxRGB-RoundDoubleToQuantum(double_value);
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ *indexes++=(IndexPacket) MaxRGB-RoundDoubleToQuantum(double_value);
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ *indexes++=(IndexPacket) MaxRGB-RoundDoubleToQuantum(double_value);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* RGB */
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ if ( (quantum_size >= 8) && (quantum_size % 8U == 0U) )
+ {
+ /*
+ Modulo-8 sample sizes
+ */
+ if(QuantumDepth == sample_bits)
+ {
+ /* Unity scale */
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportModulo8Quantum(unsigned_value,quantum_size,p);
+ SetOpacitySample(q,MaxRGB-unsigned_value);
+ q++;
+ }
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportModulo8Quantum(unsigned_value,quantum_size,p);
+ SetOpacitySample(q,MaxRGB-unsigned_value*unsigned_scale);
+ q++;
+ }
+ }
+ else
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportModulo8Quantum(unsigned_value,quantum_size,p);
+ SetOpacitySample(q,MaxRGB-unsigned_value/unsigned_scale);
+ q++;
+ }
+ }
+ }
+ else
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetOpacitySample(q,MaxRGB-MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ q++;
+ }
+ }
+ else
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetOpacitySample(q,MaxRGB-MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ q++;
+ }
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportBlackQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetBlackSample(q,ScaleCharToQuantum(*p++));
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,ScaleShortToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetBlackSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ q++;
+ }
+ }
+ else
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetBlackSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ q++;
+ }
+ }
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportRGBQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt8Quantum(unsigned_value,p);
+ SetRedSample(q,ScaleCharToQuantum(unsigned_value));
+ ImportUInt8Quantum(unsigned_value,p);
+ SetGreenSample(q,ScaleCharToQuantum(unsigned_value));
+ ImportUInt8Quantum(unsigned_value,p);
+ SetBlueSample(q,ScaleCharToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleShortToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleLongToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleLongToQuantum(unsigned_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetRedSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetGreenSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetBlueSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ else if (QuantumDepth < sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetRedSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetGreenSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetBlueSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportRGBAQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetRedSample(q,ScaleCharToQuantum(*p++));
+ SetGreenSample(q,ScaleCharToQuantum(*p++));
+ SetBlueSample(q,ScaleCharToQuantum(*p++));
+ SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(*p++));
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleShortToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetRedSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetGreenSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetBlueSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetOpacitySample(q,MaxRGB-ScaleLongToQuantum(unsigned_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetRedSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetGreenSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetBlueSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetOpacitySample(q,MaxRGB-MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ q++;
+ }
+ }
+ else if (QuantumDepth < sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetRedSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetGreenSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetBlueSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetOpacitySample(q,MaxRGB-MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ q++;
+ }
+ }
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetRedSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetGreenSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlueSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportCMYKQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetCyanSample(q,ScaleCharToQuantum(*p++));
+ SetMagentaSample(q,ScaleCharToQuantum(*p++));
+ SetYellowSample(q,ScaleCharToQuantum(*p++));
+ SetBlackSample(q,ScaleCharToQuantum(*p++));
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetCyanSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetMagentaSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetYellowSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,unsigned_value);
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetCyanSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetMagentaSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetYellowSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,unsigned_value);
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetCyanSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetMagentaSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetYellowSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,unsigned_value);
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetCyanSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetMagentaSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetYellowSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetBlackSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ *indexes++=OpaqueOpacity;
+ q++;
+ }
+ }
+ else if (QuantumDepth < sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetCyanSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetMagentaSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetYellowSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetBlackSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ *indexes++=OpaqueOpacity;
+ q++;
+ }
+ }
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetCyanSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetMagentaSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetYellowSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ *indexes++=OpaqueOpacity;
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetCyanSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetMagentaSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetYellowSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ *indexes++=OpaqueOpacity;
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetCyanSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetMagentaSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetYellowSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ *indexes++=OpaqueOpacity;
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetCyanSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetMagentaSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetYellowSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ *indexes++=OpaqueOpacity;
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportCMYKAQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ IndexPacket * restrict indexes,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const unsigned int unsigned_scale,
+ const double double_minvalue,
+ const double double_scale,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ register unsigned int
+ unsigned_value;
+
+ unsigned int
+ sample_bits;
+
+ sample_bits=quantum_size;
+ p=source;
+
+ if (sample_type == UnsignedQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 8:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetCyanSample(q,ScaleCharToQuantum(*p++));
+ SetMagentaSample(q,ScaleCharToQuantum(*p++));
+ SetYellowSample(q,ScaleCharToQuantum(*p++));
+ SetBlackSample(q,ScaleCharToQuantum(*p++));
+ *indexes++=(IndexPacket) MaxRGB-ScaleCharToQuantum(*p++);
+ q++;
+ }
+ break;
+ }
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetCyanSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetMagentaSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetYellowSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,ScaleShortToQuantum(unsigned_value));
+ ImportUInt16Quantum(endian,unsigned_value,p);
+ *indexes++=(IndexPacket) MaxRGB-ScaleShortToQuantum(unsigned_value);
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetCyanSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetMagentaSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetYellowSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt32Quantum(endian,unsigned_value,p);
+ *indexes++=(IndexPacket) MaxRGB-ScaleLongToQuantum(unsigned_value);
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetCyanSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetMagentaSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetYellowSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ SetBlackSample(q,ScaleLongToQuantum(unsigned_value));
+ ImportUInt64Quantum(endian,unsigned_value,p);
+ *indexes++=(IndexPacket) MaxRGB-ScaleLongToQuantum(unsigned_value);
+ q++;
+ }
+ break;
+ }
+ default:
+ {
+ /*
+ Arbitrary sample size
+ */
+ BitStreamReadHandle
+ stream;
+
+ MagickBitStreamInitializeRead(&stream,p);
+ if (QuantumDepth >= sample_bits)
+ {
+ /* Scale up */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetCyanSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetMagentaSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetYellowSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ SetBlackSample(q,MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale);
+ *indexes++=(IndexPacket) MaxRGB-MagickBitStreamMSBRead(&stream,quantum_size)*unsigned_scale;
+ q++;
+ }
+ }
+ else if (QuantumDepth < sample_bits)
+ {
+ /* Scale down */
+ for (x = number_pixels; x != 0; --x)
+ {
+ SetCyanSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetMagentaSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetYellowSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ SetBlackSample(q,MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale);
+ *indexes++=(IndexPacket) MaxRGB-MagickBitStreamMSBRead(&stream,quantum_size)/unsigned_scale;
+ q++;
+ }
+ }
+ break;
+ }
+ }
+ }
+ else if (sample_type == FloatQuantumSampleType)
+ {
+ switch (quantum_size)
+ {
+ case 16:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetCyanSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetMagentaSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetYellowSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat16Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ *indexes++=(IndexPacket) MaxRGB-RoundDoubleToQuantum(double_value);
+ q++;
+ }
+ break;
+ }
+ case 24:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetCyanSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetMagentaSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetYellowSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat24Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ *indexes++=(IndexPacket) MaxRGB-RoundDoubleToQuantum(double_value);
+ q++;
+ }
+ break;
+ }
+ case 32:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetCyanSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetMagentaSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetYellowSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat32Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ *indexes++=(IndexPacket) MaxRGB-RoundDoubleToQuantum(double_value);
+ q++;
+ }
+ break;
+ }
+ case 64:
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetCyanSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetMagentaSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetYellowSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ SetBlackSample(q,RoundDoubleToQuantum(double_value));
+ ImportFloat64Quantum(endian,double_value,p);
+ double_value -= double_minvalue;
+ double_value *= double_scale;
+ *indexes++=(IndexPacket) MaxRGB-RoundDoubleToQuantum(double_value);
+ q++;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportCIEXYZQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ p=source;
+
+ if (sample_type == FloatQuantumSampleType)
+ {
+ double
+ red,
+ green,
+ blue,
+ x_sample,
+ y_sample,
+ z_sample;
+
+ for (x = number_pixels; x != 0; --x)
+ {
+ switch (quantum_size)
+ {
+ default:
+ case 32:
+ {
+ ImportFloat32Quantum(endian,x_sample,p);
+ ImportFloat32Quantum(endian,y_sample,p);
+ ImportFloat32Quantum(endian,z_sample,p);
+ break;
+ }
+ case 64:
+ {
+ ImportFloat64Quantum(endian,x_sample,p);
+ ImportFloat64Quantum(endian,y_sample,p);
+ ImportFloat64Quantum(endian,z_sample,p);
+ break;
+ }
+ }
+
+ /* Assume CCIR-709 primaries */
+ red = 2.690*x_sample + -1.276*y_sample + -0.414*z_sample;
+ green = -1.022*x_sample + 1.978*y_sample + 0.044*z_sample;
+ blue = 0.061*x_sample + -0.224*y_sample + 1.163*z_sample;
+
+ /* assume 2.0 gamma for speed */
+ SetRedSample(q,(Quantum) ((red <= 0.0) ? 0.0 : (red >= 1.0) ? MaxRGB :
+ ((MaxRGB * sqrt(red))+0.5)));
+ SetGreenSample(q,(Quantum) ((green <= 0.0) ? 0.0 : (green >= 1.0) ? MaxRGB :
+ ((MaxRGB * sqrt(green))+0.5)));
+ SetBlueSample(q,(Quantum) ((blue <= 0.0) ? 0.0 : (blue >= 1.0) ? MaxRGB :
+ ((MaxRGB * sqrt(blue))+0.5)));
+ SetOpacitySample(q,OpaqueOpacity);
+ q++;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+static MagickPassFail
+ImportCIEYQuantumType(const unsigned char *source,
+ PixelPacket* restrict q,
+ const unsigned long number_pixels,
+ const unsigned int quantum_size,
+ const QuantumSampleType sample_type,
+ const EndianType endian,
+ ImportPixelAreaInfo *import_info)
+{
+ const unsigned char * restrict
+ p;
+
+ register unsigned long
+ x;
+
+ double
+ double_value;
+
+ p=source;
+
+ if (sample_type == FloatQuantumSampleType)
+ {
+ for (x = number_pixels; x != 0; --x)
+ {
+ switch (quantum_size)
+ {
+ default:
+ case 32:
+ {
+ ImportFloat32Quantum(endian,double_value,p);
+ break;
+ }
+ case 64:
+ {
+ ImportFloat64Quantum(endian,double_value,p);
+ break;
+ }
+ }
+ /* assume 2.0 gamma for speed */
+ SetGraySample(q,(Quantum) ((double_value <= 0.0) ? 0.0 :
+ (double_value >= 1.0) ? MaxRGB :
+ ((MaxRGB * sqrt(double_value))+0.5)));
+ q++;
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=p-source;
+ }
+
+ return MagickPass;
+}
+
+MagickExport MagickPassFail
+ImportViewPixelArea(ViewInfo *view,
+ const QuantumType quantum_type,
+ const unsigned int quantum_size,
+ const unsigned char *source,
+ const ImportPixelAreaOptions *options,
+ ImportPixelAreaInfo *import_info)
+{
+ Image
+ *image;
+
+ unsigned int
+ unsigned_scale = 1U;
+
+ IndexPacket
+ * restrict indexes;
+
+ PixelPacket
+ * restrict q;
+
+ MagickBool
+ grayscale_miniswhite = MagickFalse;
+
+ QuantumSampleType
+ sample_type = UnsignedQuantumSampleType;
+
+ unsigned int
+ unsigned_maxvalue=MaxRGB,
+ sample_bits;
+
+ unsigned long
+ number_pixels;
+
+ double
+ double_maxvalue=1.0,
+ double_minvalue=0.0,
+ double_scale;
+
+ EndianType
+ endian=MSBEndian;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(view != (ViewInfo *) NULL);
+ assert(source != (const unsigned char *) NULL);
+ assert((options == (const ImportPixelAreaOptions *) NULL) ||
+ (options->signature == MagickSignature));
+
+ if ((quantum_size == 0U) ||
+ ((quantum_size > 32U) && (quantum_size != 64U)))
+ {
+ char quantum_size_str[MaxTextExtent];
+ FormatString(quantum_size_str,"%u",quantum_size);
+ status=0;
+ ThrowException(&GetCacheViewImage(view)->exception,CoderError,
+ UnsupportedBitsPerSample,quantum_size_str);
+ return MagickFail;
+ }
+
+ /*
+ Transfer any special options.
+ */
+ sample_bits=quantum_size;
+ if (options)
+ {
+ sample_type=options->sample_type;
+ double_minvalue=options->double_minvalue;
+ double_maxvalue=options->double_maxvalue;
+ grayscale_miniswhite=options->grayscale_miniswhite;
+
+ switch (options->endian)
+ {
+ case MSBEndian:
+ case UndefinedEndian:
+ {
+ endian=MSBEndian;
+ break;
+ }
+ case LSBEndian:
+ {
+ endian=LSBEndian;
+ break;
+ }
+ case NativeEndian:
+ {
+#if defined(WORDS_BIGENDIAN)
+ endian=MSBEndian;
+#else
+ endian=LSBEndian;
+#endif
+ break;
+ }
+ }
+ }
+
+ if (import_info)
+ {
+ import_info->bytes_imported=0;
+ }
+
+ /* printf("quantum_type=%d quantum_size=%u\n",(int) quantum_type, quantum_size); */
+
+ /* Maximum value which may be represented by a sample */
+ unsigned_maxvalue=MaxValueGivenBits(sample_bits);
+ double_scale=(double) MaxRGB/(double_maxvalue-double_minvalue);
+ if ((sample_type != FloatQuantumSampleType) && (sample_bits <= 32U))
+ {
+ if (QuantumDepth == sample_bits)
+ {
+ }
+ else if (QuantumDepth > sample_bits)
+ {
+ /* Multiply to scale up */
+ unsigned_scale=(MaxRGB / (MaxRGB >> (QuantumDepth-sample_bits)));
+ }
+ else if (QuantumDepth < sample_bits)
+ {
+ /* Divide to scale down */
+ unsigned_scale=(unsigned_maxvalue/MaxRGB);
+ }
+ }
+
+ image=GetCacheViewImage(view);
+ number_pixels=(long) GetCacheViewArea(view);
+ q=AccessCacheViewPixels(view);
+ indexes=GetCacheViewIndexes(view);
+ switch (quantum_type)
+ {
+ case UndefinedQuantum:
+ {
+ status=MagickFail;
+ break;
+ }
+ case IndexQuantum:
+ {
+ status=ImportIndexQuantumType(source,q,indexes,number_pixels,quantum_size,
+ sample_type,unsigned_maxvalue,endian,image,
+ import_info);
+ break;
+ }
+ case IndexAlphaQuantum:
+ {
+ status=ImportIndexAlphaQuantumType(source,q,indexes,number_pixels,
+ quantum_size,sample_type,unsigned_scale,
+ endian,
+ image,
+ import_info);
+ break;
+ }
+ case GrayQuantum:
+ {
+ status=ImportGrayQuantumType(source,q,indexes,number_pixels,quantum_size,
+ sample_type,unsigned_scale,unsigned_maxvalue,
+ grayscale_miniswhite,double_minvalue,
+ double_scale,endian,image,import_info);
+ break;
+ }
+ case GrayAlphaQuantum:
+ {
+ status=ImportGrayAlphaQuantumType(source,q,indexes,number_pixels,quantum_size,
+ sample_type,unsigned_scale,unsigned_maxvalue,
+ grayscale_miniswhite,double_minvalue,double_scale,
+ endian,image,import_info);
+ break;
+ }
+ case RedQuantum:
+ case CyanQuantum:
+ {
+ status=ImportRedQuantumType(source,q,number_pixels,quantum_size,sample_type,
+ unsigned_scale,double_minvalue,double_scale,endian,
+ import_info);
+
+ break;
+ }
+ case GreenQuantum:
+ case MagentaQuantum:
+ {
+ status=ImportGreenQuantumType(source,q,number_pixels,quantum_size,sample_type,
+ unsigned_scale,double_minvalue,double_scale,endian,
+ import_info);
+ break;
+ }
+ case BlueQuantum:
+ case YellowQuantum:
+ {
+ status=ImportBlueQuantumType(source,q,number_pixels,quantum_size,sample_type,
+ unsigned_scale,double_minvalue,double_scale,endian,
+ import_info);
+ break;
+ }
+ case AlphaQuantum:
+ {
+ status=ImportAlphaQuantumType(source,q,indexes,number_pixels,quantum_size,
+ sample_type,unsigned_scale,double_minvalue,
+ double_scale,endian,image,import_info);
+ break;
+ }
+ case BlackQuantum:
+ {
+ status=ImportBlackQuantumType(source,q,number_pixels,quantum_size,sample_type,
+ unsigned_scale,double_minvalue,double_scale,endian,
+ import_info);
+ break;
+ }
+ case RGBQuantum:
+ {
+ status=ImportRGBQuantumType(source,q,number_pixels,quantum_size,sample_type,
+ unsigned_scale,double_minvalue,double_scale,endian,
+ import_info);
+ break;
+ }
+ case RGBAQuantum:
+ {
+ status=ImportRGBAQuantumType(source,q,number_pixels,quantum_size,sample_type,
+ unsigned_scale,double_minvalue,double_scale,endian,
+ import_info);
+ break;
+ }
+ case CMYKQuantum:
+ {
+ status=ImportCMYKQuantumType(source,q,indexes,number_pixels,quantum_size,
+ sample_type,unsigned_scale,double_minvalue,
+ double_scale,endian,import_info);
+ break;
+ }
+ case CMYKAQuantum:
+ {
+ status=ImportCMYKAQuantumType(source,q,indexes,number_pixels,quantum_size,
+ sample_type,unsigned_scale,double_minvalue,
+ double_scale,endian,import_info);
+ break;
+ }
+ case CIEXYZQuantum:
+ {
+ status=ImportCIEXYZQuantumType(source,q,number_pixels,quantum_size,sample_type,
+ endian,import_info);
+ break;
+ }
+ case CIEYQuantum:
+ {
+ status=ImportCIEYQuantumType(source,q,number_pixels,quantum_size,sample_type,
+ endian,import_info);
+ break;
+ }
+ }
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m p o r t P i x e l A r e a O p t i o n s I n i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImportPixelAreaOptionsInit() initializes the options structure which is
+% optionally passed to ImportPixelArea()
+%
+% The format of the ImportPixelAreaOptionsInit method is:
+%
+% void ImportPixelAreaOptionsInit(ImportPixelAreaOptions *options)
+%
+% A description of each parameter follows:
+%
+% o options: Options structure to initialize.
+%
+*/
+MagickExport void ImportPixelAreaOptionsInit(ImportPixelAreaOptions *options)
+{
+ assert(options != (ImportPixelAreaOptions *) NULL);
+ (void) memset((void *) options, 0, sizeof(ImportPixelAreaOptions));
+ options->sample_type=UnsignedQuantumSampleType;
+ options->double_minvalue=0.0;
+ options->double_maxvalue=1.0;
+ options->grayscale_miniswhite=MagickFalse;
+ options->endian=MSBEndian;
+ options->signature=MagickSignature;
+}
diff --git a/magick/list.c b/magick/list.c
new file mode 100644
index 0000000..8568d01
--- /dev/null
+++ b/magick/list.c
@@ -0,0 +1,946 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002, 2003 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L IIIII SSSSS TTTTT %
+% L I SS T %
+% L I SSS T %
+% L I SS T %
+% LLLLL IIIII SSSSS T %
+% %
+% %
+% GraphicsMagick Image List Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% January 2003 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/list.h"
+#include "magick/blob.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A p p e n d I m a g e T o L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AppendImageToList() appends an image to the end of the list.
+%
+% The format of the AppendImageToList method is:
+%
+% AppendImageToList(Image **images,Image *image)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void AppendImageToList(Image **images,Image *image)
+{
+ register Image
+ *p;
+
+ assert(images != (Image **) NULL);
+ if (image == (Image *) NULL)
+ return;
+ assert(image->signature == MagickSignature);
+ if ((*images) == (Image *) NULL)
+ {
+ *images=image;
+ return;
+ }
+ assert((*images)->signature == MagickSignature);
+ for (p=(*images); p->next != (Image *) NULL; p=p->next);
+ p->next=image;
+ image->previous=p;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e I m a g e L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneImageList() returns a duplicate of the image list.
+%
+% The format of the CloneImageList method is:
+%
+% Image *CloneImageList(const Image *images,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *CloneImageList(const Image *images,ExceptionInfo *exception)
+{
+ Image
+ *clone,
+ *image;
+
+ register Image
+ *p;
+
+ if (images == (Image *) NULL)
+ return((Image *) NULL);
+ assert(images->signature == MagickSignature);
+ while (images->previous != (Image *) NULL)
+ images=images->previous;
+ image=(Image *) NULL;
+ for (p=(Image *) NULL; images != (Image *) NULL; images=images->next)
+ {
+ clone=CloneImage(images,0,0,True,exception);
+ if (clone == (Image *) NULL)
+ {
+ if (image != (Image *) NULL)
+ DestroyImageList(image);
+ return((Image *) NULL);
+ }
+ if (image == (Image *) NULL)
+ {
+ image=clone;
+ p=image;
+ continue;
+ }
+ p->next=clone;
+ clone->previous=p;
+ p=p->next;
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e l e t e I m a g e F r o m L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DeleteImageFromList() deletes an image from the list.
+%
+% The format of the DeleteImageFromList method is:
+%
+% DeleteImageFromList(Image **images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport void DeleteImageFromList(Image **images)
+{
+ register Image
+ *p;
+
+ assert(images != (Image **) NULL);
+ if ((*images) == (Image *) NULL)
+ return;
+ assert((*images)->signature == MagickSignature);
+ p=(*images);
+ if ((p->previous == (Image *) NULL) && (p->next == (Image *) NULL))
+ *images=(Image *) NULL;
+ else
+ {
+ if (p->previous != (Image *) NULL)
+ {
+ p->previous->next=p->next;
+ *images=p->previous;
+ }
+ if (p->next != (Image *) NULL)
+ {
+ p->next->previous=p->previous;
+ *images=p->next;
+ }
+ }
+ DestroyImage(p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y I m a g e L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyImageList() destroys an image list.
+%
+% The format of the DestroyImageList method is:
+%
+% void DestroyImageList(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image sequence.
+%
+%
+*/
+MagickExport void DestroyImageList(Image *images)
+{
+ register Image
+ *p;
+
+ if (images == (Image *) NULL)
+ return;
+ assert(images->signature == MagickSignature);
+ for (p=images; p->previous != (Image *) NULL; p=p->previous);
+ for (images=p; p != (Image *) NULL; images=p)
+ {
+ p=p->next;
+ images->next=0;
+ if(p)
+ p->previous=0;
+ DestroyImage(images);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t F i r s t I m a g e I n L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetFirstImageInList() returns a pointer to the first image in the list
+%
+% The format of the GetFirstImageInList method is:
+%
+% Image *GetFirstImageInList(const Image *images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+*/
+MagickExport Image *GetFirstImageInList(const Image *images)
+{
+ register const Image
+ *p;
+
+ if (images == (Image *) NULL)
+ return((Image *) NULL);
+ assert(images->signature == MagickSignature);
+ for (p=images; p->previous != (Image *) NULL; p=p->previous);
+ return((Image *) p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e F r o m L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageFromList() returns an image at the specified offset from the list.
+%
+% The format of the GetImageFromList method is:
+%
+% Image *GetImageFromList(const Image *images,const long offset)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+% o offset: The position within the list.
+%
+%
+*/
+MagickExport Image *GetImageFromList(const Image *images,const long offset)
+{
+ register const Image
+ *p;
+
+ register long
+ i;
+
+ if (images == (Image *) NULL)
+ return((Image *) NULL);
+ assert(images->signature == MagickSignature);
+ for (p=images; p->previous != (Image *) NULL; p=p->previous);
+ for (i=0; p != (Image *) NULL; p=p->next)
+ if (i++ == offset)
+ break;
+ if (p == (Image *) NULL)
+ return((Image *) NULL);
+ return((Image *) p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e I n d e x I n L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageIndexInList() returns the offset in the list of the specified image.
+%
+% The format of the GetImageIndexInList method is:
+%
+% long GetImageIndexInList(const Image *images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport long GetImageIndexInList(const Image *images)
+{
+ register long
+ i;
+
+ if (images == (const Image *) NULL)
+ return(-1);
+ assert(images->signature == MagickSignature);
+ for (i=0; images->previous != (Image *) NULL; i++)
+ images=images->previous;
+ return(i);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e L i s t L e n g t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageListLength() returns the length of the list (the number of images in
+% the list).
+%
+% The format of the GetImageListLength method is:
+%
+% unsigned long GetImageListLength(const Image *images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport unsigned long GetImageListLength(const Image *images)
+{
+ register long
+ i;
+
+ if (images == (Image *) NULL)
+ return(0);
+ assert(images->signature == MagickSignature);
+ while (images->previous != (Image *) NULL)
+ images=images->previous;
+ for (i=0; images != (Image *) NULL; images=images->next)
+ i++;
+ return(i);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t L a s t I m a g e I n L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetLastImageInList() returns a pointer to the last image in the list
+%
+% The format of the GetLastImageInList method is:
+%
+% Image *GetLastImageInList(const Image *images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+*/
+MagickExport Image *GetLastImageInList(const Image *images)
+{
+ register const Image
+ *p;
+
+ if (images == (Image *) NULL)
+ return((Image *) NULL);
+ assert(images->signature == MagickSignature);
+ for (p=images; p->next != (Image *) NULL; p=p->next);
+ return((Image *) p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t N e x t I m a g e I n L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetNextImageInList() returns the next image in the list.
+%
+% The format of the GetNextImageInList method is:
+%
+% Image *GetNextImageInList(const Image *images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport Image *GetNextImageInList(const Image *images)
+{
+ if (images == (Image *) NULL)
+ return((Image *) NULL);
+ assert(images->signature == MagickSignature);
+ return(images->next);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t P r e v i o u s I m a g e I n L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetPreviousImageInList() returns the previous image in the list.
+%
+% The format of the GetPreviousImageInList method is:
+%
+% Image *GetPreviousImageInList(const Image *images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport Image *GetPreviousImageInList(const Image *images)
+{
+ if (images == (Image *) NULL)
+ return((Image *) NULL);
+ assert(images->signature == MagickSignature);
+ return(images->previous);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% I m a g e L i s t T o A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImageListToArray() is a convenience method that converts an image list to
+% a sequential array. For example,
+%
+% group = ImageListToArray(images, exception);
+% for (i = 0; i < n; i++)
+% puts(group[i]->filename);
+%
+% The format of the ImageListToArray method is:
+%
+% Image **ImageListToArray(const Image *images,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image list.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image **ImageListToArray(const Image *images,
+ ExceptionInfo *exception)
+{
+ Image
+ **group;
+
+ register long
+ i;
+
+ if (images == (Image *) NULL)
+ return((Image **) NULL);
+ assert(images->signature == MagickSignature);
+ group=MagickAllocateMemory(Image **,(GetImageListLength(images)+1)*sizeof(Image *));
+ if (group == (Image **) NULL)
+ {
+ ThrowException3(exception,ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateImageGroup);
+ return((Image **) NULL);
+ }
+ while (images->previous != (Image *) NULL)
+ images=images->previous;
+ for (i=0; images != (Image *) NULL; images=images->next)
+ group[i++]=(Image *) images;
+ group[i] = (Image *) NULL;
+ return(group);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n s e r t I m a g e I n L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InsertImageInList() inserts an image in the list.
+%
+% The format of the InsertImageInList method is:
+%
+% InsertImageInList(Image **images,Image *image)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void InsertImageInList(Image **images,Image *image)
+{
+ Image
+ *split;
+
+ assert(images != (Image **) NULL);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if ((*images) == (Image *) NULL)
+ return;
+ assert((*images)->signature == MagickSignature);
+ split=SplitImageList(*images);
+ if (split == (Image *) NULL)
+ return;
+ AppendImageToList(images,image);
+ AppendImageToList(images,split);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N e w I m a g e L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NewImageList() creates an empty image list.
+%
+% The format of the NewImageList method is:
+%
+% Image *NewImageList(void)
+%
+*/
+MagickExport Image *NewImageList(void)
+{
+ return((Image *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P r e p e n d I m a g e T o L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PrependImageToList() prepends the image to the beginning of the list.
+%
+% The format of the PrependImageToList method is:
+%
+% PrependImageToList(Image *images,Image *image)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void PrependImageToList(Image **images,Image *image)
+{
+ AppendImageToList(&image,*images);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e m o v e F i r s t I m a g e F r o m L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RemoveFirstImageFromList() removes an image from the beginning of the list.
+%
+% The format of the RemoveFirstImageFromList method is:
+%
+% Image *RemoveFirstImageFromList(Image **images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport Image *RemoveFirstImageFromList(Image **images)
+{
+ Image
+ *image;
+
+ assert(images != (Image **) NULL);
+ if ((*images) == (Image *) NULL)
+ return((Image *) NULL);
+ assert((*images)->signature == MagickSignature);
+ image=(*images);
+ while (image->previous != (Image *) NULL)
+ image=image->previous;
+ if (image == *images)
+ *images=(*images)->next;
+ if (image->next != (Image *) NULL)
+ {
+ image->next->previous=(Image *) NULL;
+ image->next=(Image *) NULL;
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e m o v e L a s t I m a g e F r o m L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RemoveLastImageFromList() removes the last image from the list.
+%
+% The format of the RemoveLastImageFromList method is:
+%
+% Image *RemoveLastImageFromList(Image **images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport Image *RemoveLastImageFromList(Image **images)
+{
+ Image
+ *image;
+
+ assert(images != (Image **) NULL);
+ if ((*images) == (Image *) NULL)
+ return((Image *) NULL);
+ assert((*images)->signature == MagickSignature);
+ image=(*images);
+ while (image->next != (Image *) NULL)
+ image=image->next;
+ if (image == *images)
+ *images=(*images)->previous;
+ if (image->previous != (Image *) NULL)
+ {
+ image->previous->next=(Image *) NULL;
+ image->previous=(Image *) NULL;
+ }
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e p l a c e I m a g e I n L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReplaceImageInList() replaces an image in the list.
+%
+% The format of the ReplaceImageInList method is:
+%
+% ReplaceImageInList(Image **images,Image *image)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void ReplaceImageInList(Image **images,Image *image)
+{
+ assert(images != (Image **) NULL);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if ((*images) == (Image *) NULL)
+ return;
+ assert((*images)->signature == MagickSignature);
+ image->next=(*images)->next;
+ if (image->next != (Image *) NULL)
+ image->next->previous=image;
+ image->previous=(*images)->previous;
+ if (image->previous != (Image *) NULL)
+ image->previous->next=image;
+ DestroyImage(*images);
+ (*images)=image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e v e r s e I m a g e L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReverseImageList() reverses the image list.
+%
+% The format of the ReverseImageList method is:
+%
+% ReverseImageList(const Image **images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport void ReverseImageList(Image **images)
+{
+ Image
+ *next;
+
+ register Image
+ *p;
+
+ assert(images != (Image **) NULL);
+ if ((*images) == (Image *) NULL)
+ return;
+ assert((*images)->signature == MagickSignature);
+ for (p=(*images); p->next != (Image *) NULL; p=p->next);
+ *images=p;
+ for ( ; p != (Image *) NULL; p=p->next)
+ {
+ next=p->next;
+ p->next=p->previous;
+ p->previous=next;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S p l i c e I m a g e I n t o L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SpliceImageIntoList() removes 'length' images from the list and replaces
+% them with the specified splice.
+%
+% The format of the SpliceImageIntoList method is:
+%
+% SpliceImageIntoList(Image **images,const unsigned long length,
+% Image *splice)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+% o length: The length of the image list to remove.
+%
+% o splice: Replace the removed image list with this list.
+%
+%
+*/
+MagickExport void SpliceImageIntoList(Image **images,const unsigned long length,
+ Image *splice)
+{
+ Image
+ *split;
+
+ register long
+ i;
+
+ assert(images != (Image **) NULL);
+ assert(splice != (Image *) NULL);
+ assert(splice->signature == MagickSignature);
+ if ((*images) == (Image *) NULL)
+ return;
+ assert((*images)->signature == MagickSignature);
+ split=SplitImageList(*images);
+ if (split == (Image *) NULL)
+ return;
+ AppendImageToList(images,splice);
+ for (i=0; (i < (long) length) && (split != (Image *) NULL); i++)
+ (void) DeleteImageFromList(&split);
+ AppendImageToList(images,split);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S p l i t I m a g e L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SplitImageList() splits an image into two lists.
+%
+% The format of the SplitImageList method is:
+%
+% Image *SplitImageList(Image *images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport Image *SplitImageList(Image *images)
+{
+ if ((images == (Image *) NULL) || (images->next == (Image *) NULL))
+ return((Image *) NULL);
+ images=images->next;
+ images->previous->next=(Image *) NULL;
+ images->previous=(Image *) NULL;
+ return(images);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S y n c N e x t I m a g e I n L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SyncNextImageInList() returns the next image in the list after the blob
+% referenced is synchronized with the current image.
+%
+% The format of the SyncNextImageInList method is:
+%
+% Image *SyncNextImageInList(const Image *images)
+%
+% A description of each parameter follows:
+%
+% o images: The image list.
+%
+%
+*/
+MagickExport Image *SyncNextImageInList(const Image *images)
+{
+ if (images == (Image *) NULL)
+ return((Image *) NULL);
+ assert(images->signature == MagickSignature);
+ if (images->next == (Image *) NULL)
+ return((Image *) NULL);
+ if (images->blob != images->next->blob)
+ {
+ DestroyBlob(images->next);
+ images->next->blob=ReferenceBlob(images->blob);
+ }
+ return(images->next);
+}
diff --git a/magick/list.h b/magick/list.h
new file mode 100644
index 0000000..e611f53
--- /dev/null
+++ b/magick/list.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Image List Methods.
+*/
+#ifndef _MAGICK_LIST_H
+#define _MAGICK_LIST_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+extern MagickExport Image
+ *CloneImageList(const Image *,ExceptionInfo *),
+ *GetFirstImageInList(const Image *),
+ *GetImageFromList(const Image *,const long),
+ *GetLastImageInList(const Image *),
+ *GetNextImageInList(const Image *),
+ *GetPreviousImageInList(const Image *),
+ **ImageListToArray(const Image *,ExceptionInfo *),
+ *NewImageList(void),
+ *RemoveLastImageFromList(Image **),
+ *RemoveFirstImageFromList(Image **),
+ *SplitImageList(Image *),
+ *SyncNextImageInList(const Image *);
+
+extern MagickExport long
+ GetImageIndexInList(const Image *);
+
+extern MagickExport unsigned long
+ GetImageListLength(const Image *);
+
+extern MagickExport void
+ AppendImageToList(Image **,Image *),
+ DeleteImageFromList(Image **),
+ DestroyImageList(Image *),
+ InsertImageInList(Image **,Image *),
+ PrependImageToList(Image **,Image *),
+ ReplaceImageInList(Image **images,Image *image),
+ ReverseImageList(Image **),
+ SpliceImageIntoList(Image **,const unsigned long,Image *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/locale.c b/magick/locale.c
new file mode 100644
index 0000000..3d6b2a1
--- /dev/null
+++ b/magick/locale.c
@@ -0,0 +1,343 @@
+/*
+% Copyright (C) 2003, 2004 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L OOO CCCC AAA L EEEEE %
+% L O O C A A L E %
+% L O O C AAAAA L EEE %
+% L O O C A A L E %
+% LLLLL OOO CCCC A A LLLLL EEEEE %
+% %
+% %
+% GraphicsMagick Locale Message Methods %
+% %
+% %
+% Software Design %
+% William T. Radcliffe %
+% July 2003 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "studio.h"
+#include "utility.h"
+#define _INCLUDE_CATEGORYMAP_TABLE_
+#define _INCLUDE_SEVERITYMAP_TABLE_
+#define _INCLUDE_TAGMAP_TABLE_
+#if defined(MAGICK_WINDOWS_MESSAGE_TABLES)
+# include "spinlock.h"
+#else
+# define _INCLUDE_MESSAGE_TABLE_
+#endif
+#include "locale_c.h"
+
+/*
+ Static declaractions.
+*/
+#if defined(MAGICK_WINDOWS_MESSAGE_TABLES)
+#define MAX_CACHE_SIZE 32
+
+static char
+ cache[MaxTextExtent * MAX_CACHE_SIZE];
+
+static const char *
+AllocateManagedString(const char *s)
+{
+ char
+ *cs;
+
+ static int
+ index = -1;
+
+ SPINLOCK_WAIT;
+ index++;
+ if (index >= MAX_CACHE_SIZE)
+ index=0;
+ cs=&cache[MaxTextExtent * index];
+ (void) strlcpy(cs,s,MaxTextExtent);
+ SPINLOCK_RELEASE;
+ return cs;
+}
+
+static const char *
+NTFormatMessage(DWORD id, ...)
+{
+ va_list
+ args;
+
+ const char
+ *result;
+
+ char
+ temp[MaxTextExtent];
+
+ HMODULE
+ handle;
+
+ int
+ status;
+
+ LPVOID
+ buffer;
+
+ va_start( args, id );
+
+ buffer = (LPVOID) NULL; /* stop compiler from complaining */
+ FormatString(temp,"%.1024s%.1024s%.1024s",SetClientPath((char *) NULL),
+ DirectorySeparator,SetClientFilename((char *) NULL));
+ if (IsAccessibleNoLogging(temp))
+ handle=GetModuleHandle(temp);
+ else
+ handle=GetModuleHandle(0);
+ if (handle)
+ {
+ /*
+ Sample of how to change threads locale explicitly to English.
+ you can use this same API call to switch locales on a thread
+ by thread basis and extract the correct localized message
+ */
+ /*
+ SetThreadLocale( MAKELCID( MAKELANGID( 0x0409, SUBLANG_NEUTRAL
+ ), SORT_DEFAULT ) );
+ */
+ status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_HMODULE,
+ handle,
+ id,
+ MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
+ (LPTSTR) &buffer,
+ 0,
+ &args
+ );
+ if (!status)
+ {
+ FormatString(temp,"Undefined message %ld (0x%08lx)",(long) id,
+ (long) id);
+ result=AllocateManagedString(temp);
+ }
+ else
+ {
+ char
+ *s;
+
+ int
+ len;
+
+ s = buffer;
+ len = strlen(s);
+ if (len > 1)
+ {
+ /*
+ The string that is stored in the resource has a CR LF
+ on the end, so we need to zap this off before
+ returning it
+ */
+ s[len-1]='\0';
+ s[len-2]='\0';
+ }
+ result=AllocateManagedString(s);
+ LocalFree(buffer);
+ }
+ }
+ else
+ {
+ FormatString(temp,"Undefined message %ld (0x%08lx)",(long) id, (long) id);
+ result=AllocateManagedString(temp);
+ }
+ return(result);
+}
+#endif /* defined(MAGICK_WINDOWS_MESSAGE_TABLES) */
+
+static void
+ChopLocaleComponents(char *path,const unsigned long components)
+{
+ long
+ count;
+
+ register char
+ *p;
+
+ if (*path == '\0')
+ return;
+ p=path+strlen(path)-1;
+ if (*p == '/')
+ *p='\0';
+ for (count=0; (count < (long) components) && (p > path); p--)
+ if (*p == '/')
+ {
+ *p='\0';
+ count++;
+ }
+}
+
+static const char *
+GetLocaleMessageFromTag(const char *tag)
+{
+#if defined(_INCLUDE_TAGMAP_TABLE_)
+ char
+ category[MaxTextExtent],
+ severity[MaxTextExtent];
+
+ register int
+ i,
+ j,
+ k;
+
+ (void) strlcpy(category,tag,MaxTextExtent);
+ ChopLocaleComponents(category,2);
+ for (k=0; category_map[k].name != 0; k++)
+ {
+ if (LocaleCompare(category,category_map[k].name) == 0)
+ {
+ (void) strlcpy(severity,tag,MaxTextExtent);
+ ChopLocaleComponents(severity,1);
+ for (j=category_map[k].offset; j < category_map[k+1].offset; j++)
+ {
+ if (LocaleCompare(severity,severity_map[j].name) == 0)
+ {
+ for (i=severity_map[j].offset; i < severity_map[j+1].offset; i++)
+ {
+ size_t
+ prefix,
+ taglen;
+
+ prefix=strlen(severity);
+ taglen=strlen(tag);
+ if ((prefix > 0) && (prefix < taglen) &&
+ LocaleCompare(&tag[prefix+1],message_map[i].name) == 0)
+ {
+#if defined(_INCLUDE_MESSAGE_TABLE_)
+ return message_dat[message_map[i].messageid];
+#else
+# if defined(MAGICK_WINDOWS_MESSAGE_TABLES)
+ return NTFormatMessage(message_map[i].messageid);
+# else
+ return tag;
+# endif /* defined(MAGICK_WINDOWS_MESSAGE_TABLES) */
+#endif /* defined(_INCLUDE_MESSAGE_TABLE_) */
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+ return tag;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t L o c a l e M e s s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetLocaleMessage() returns a message in the current locale that matches the
+% supplied tag.
+%
+% The format of the GetLocaleMessage method is:
+%
+% const char *GetLocaleMessage(const char *tag)
+%
+% A description of each parameter follows:
+%
+% o tag: Return a message that matches this tag in the current locale.
+%
+%
+*/
+MagickExport const char *
+GetLocaleMessage(const char *tag)
+{
+ return GetLocaleMessageFromTag(tag);
+}
+
+/*
+ This routine translates a severity code to it's string value. It is
+ slow but the idea is to eventually move away from using strings to
+ lookup any messages and use binary codes instead.
+ */
+#if 0 /* not currently used */
+static const char *
+SeverityToTag(const ExceptionType severity)
+{
+ register int
+ i;
+
+ for (i=0; severity_map[i].name != 0; i++)
+ {
+ if (severity == severity_map[i].severityid)
+ return severity_map[i].name;
+ }
+ return("");
+}
+
+/*
+ This routine is intended to be a replacement for
+ GetLocaleExceptionMessage in the code, but using the data from the
+ locale MGK files to do it's job rather then some hard coded case
+ statement.
+ */
+static const char *
+GetLocaleMessageFromSeverityAndTag(const ExceptionType severity,
+ const char *tag)
+{
+ char
+ message[MaxTextExtent];
+
+ const char
+ *locale_message;
+
+ /*
+ This is a hack that depends on the fact that tag can never have
+ spaces in them. If a space is found then it means we are being
+ asked to translate a message that has already been translated. A
+ big waste of time. The reason this happens is that messages are
+ translated at the point of an exception and then again when the
+ exception is caught and processed via the default error and
+ warning handlers
+ */
+ if (strrchr(tag, ' '))
+ return(tag);
+ FormatString(message,"%.1024s%.1024s",SeverityToTag(severity),tag);
+ locale_message=GetLocaleMessage(message);
+ if (locale_message == message)
+ return(tag);
+ return(locale_message);
+}
+#endif /* not currently used */
+
+/*
+ This routine is used to lookup a message directly form an id pulled
+ from the header file generated by the coders\local.c header file
+ coder.
+ */
+MagickExport const char *
+GetLocaleMessageFromID(const int id)
+{
+ if ((id > 0) && (id <= MAX_LOCALE_MSGS))
+ {
+#if defined(MAGICK_WINDOWS_MESSAGE_TABLES)
+ return NTFormatMessage(id);
+#else
+ return message_dat[id];
+#endif
+ }
+ return (const char *) NULL;
+}
diff --git a/magick/locale_c.h b/magick/locale_c.h
new file mode 100644
index 0000000..b3d422b
--- /dev/null
+++ b/magick/locale_c.h
@@ -0,0 +1,1800 @@
+#ifndef _LOCAL_C_H
+#define _LOCAL_C_H
+
+extern MagickExport const char *GetLocaleMessageFromID(const int);
+
+#define MAX_LOCALE_MSGS 557
+
+#define MGK_BlobErrorUnableToCreateBlob 1
+#define MGK_BlobErrorUnableToObtainOffset 2
+#define MGK_BlobErrorUnableToOpenFile 3
+#define MGK_BlobErrorUnableToReadFile 4
+#define MGK_BlobErrorUnableToReadToOffset 5
+#define MGK_BlobErrorUnableToSeekToOffset 6
+#define MGK_BlobErrorUnableToWriteBlob 7
+#define MGK_BlobErrorUnrecognizedImageFormat 8
+#define MGK_BlobFatalErrorDefault 9
+#define MGK_BlobWarningDefault 10
+#define MGK_CacheErrorInconsistentPersistentCacheDepth 11
+#define MGK_CacheErrorPixelCacheIsNotOpen 12
+#define MGK_CacheErrorUnableToAllocateCacheView 13
+#define MGK_CacheErrorUnableToCloneCache 14
+#define MGK_CacheErrorUnableToExtendCache 15
+#define MGK_CacheErrorUnableToGetCacheNexus 16
+#define MGK_CacheErrorUnableToGetPixelsFromCache 17
+#define MGK_CacheErrorUnableToOpenCache 18
+#define MGK_CacheErrorUnableToPeristPixelCache 19
+#define MGK_CacheErrorUnableToReadPixelCache 20
+#define MGK_CacheErrorUnableToSyncCache 21
+#define MGK_CacheFatalErrorDiskAllocationFailed 22
+#define MGK_CacheFatalErrorUnableToExtendPixelCache 23
+#define MGK_CacheWarningDefault 24
+#define MGK_CoderErrorColormapTooLarge 25
+#define MGK_CoderErrorColormapTypeNotSupported 26
+#define MGK_CoderErrorColorspaceModelIsNotSupported 27
+#define MGK_CoderErrorColorTypeNotSupported 28
+#define MGK_CoderErrorCompressionNotValid 29
+#define MGK_CoderErrorDataEncodingSchemeIsNotSupported 30
+#define MGK_CoderErrorDataStorageTypeIsNotSupported 31
+#define MGK_CoderErrorDeltaPNGNotSupported 32
+#define MGK_CoderErrorEncryptedWPGImageFileNotSupported 33
+#define MGK_CoderErrorFractalCompressionNotSupported 34
+#define MGK_CoderErrorImageColumnOrRowSizeIsNotSupported 35
+#define MGK_CoderErrorImageDoesNotHaveAMatteChannel 36
+#define MGK_CoderErrorImageIsNotTiled 37
+#define MGK_CoderErrorImageTypeNotSupported 38
+#define MGK_CoderErrorIncompatibleSizeOfDouble 39
+#define MGK_CoderErrorIrregularChannelGeometryNotSupported 40
+#define MGK_CoderErrorJNGCompressionNotSupported 41
+#define MGK_CoderErrorJPEGCompressionNotSupported 42
+#define MGK_CoderErrorJPEGEmbeddingFailed 43
+#define MGK_CoderErrorLocationTypeIsNotSupported 44
+#define MGK_CoderErrorMapStorageTypeIsNotSupported 45
+#define MGK_CoderErrorMSBByteOrderNotSupported 46
+#define MGK_CoderErrorMultidimensionalMatricesAreNotSupported 47
+#define MGK_CoderErrorMultipleRecordListNotSupported 48
+#define MGK_CoderErrorNo8BIMDataIsAvailable 49
+#define MGK_CoderErrorNoAPP1DataIsAvailable 50
+#define MGK_CoderErrorNoBitmapOnClipboard 51
+#define MGK_CoderErrorNoColorProfileAvailable 52
+#define MGK_CoderErrorNoDataReturned 53
+#define MGK_CoderErrorNoImageVectorGraphics 54
+#define MGK_CoderErrorNoIPTCInfoWasFound 55
+#define MGK_CoderErrorNoIPTCProfileAvailable 56
+#define MGK_CoderErrorNumberOfImagesIsNotSupported 57
+#define MGK_CoderErrorOnlyContinuousTonePictureSupported 58
+#define MGK_CoderErrorOnlyLevelZerofilesSupported 59
+#define MGK_CoderErrorPNGCompressionNotSupported 60
+#define MGK_CoderErrorPNGLibraryTooOld 61
+#define MGK_CoderErrorRLECompressionNotSupported 62
+#define MGK_CoderErrorSubsamplingRequiresEvenWidth 63
+#define MGK_CoderErrorUnableToCopyProfile 64
+#define MGK_CoderErrorUnableToCreateADC 65
+#define MGK_CoderErrorUnableToCreateBitmap 66
+#define MGK_CoderErrorUnableToDecompressImage 67
+#define MGK_CoderErrorUnableToInitializeFPXLibrary 68
+#define MGK_CoderErrorUnableToOpenBlob 69
+#define MGK_CoderErrorUnableToReadAspectRatio 70
+#define MGK_CoderErrorUnableToReadCIELABImages 71
+#define MGK_CoderErrorUnableToReadSummaryInfo 72
+#define MGK_CoderErrorUnableToSetAffineMatrix 73
+#define MGK_CoderErrorUnableToSetAspectRatio 74
+#define MGK_CoderErrorUnableToSetColorTwist 75
+#define MGK_CoderErrorUnableToSetContrast 76
+#define MGK_CoderErrorUnableToSetFilteringValue 77
+#define MGK_CoderErrorUnableToSetImageComments 78
+#define MGK_CoderErrorUnableToSetImageTitle 79
+#define MGK_CoderErrorUnableToSetJPEGLevel 80
+#define MGK_CoderErrorUnableToSetRegionOfInterest 81
+#define MGK_CoderErrorUnableToSetSummaryInfo 82
+#define MGK_CoderErrorUnableToTranslateText 83
+#define MGK_CoderErrorUnableToWriteMPEGParameters 84
+#define MGK_CoderErrorUnableToWriteTemporaryFile 85
+#define MGK_CoderErrorUnableToZipCompressImage 86
+#define MGK_CoderErrorUnsupportedBitsPerSample 87
+#define MGK_CoderErrorUnsupportedCellTypeInTheMatrix 88
+#define MGK_CoderErrorWebPDecodingFailedUserAbort 89
+#define MGK_CoderErrorWebPEncodingFailed 90
+#define MGK_CoderErrorWebPEncodingFailedBadDimension 91
+#define MGK_CoderErrorWebPEncodingFailedBadWrite 92
+#define MGK_CoderErrorWebPEncodingFailedBitstreamOutOfMemory 93
+#define MGK_CoderErrorWebPEncodingFailedFileTooBig 94
+#define MGK_CoderErrorWebPEncodingFailedInvalidConfiguration 95
+#define MGK_CoderErrorWebPEncodingFailedNULLParameter 96
+#define MGK_CoderErrorWebPEncodingFailedOutOfMemory 97
+#define MGK_CoderErrorWebPEncodingFailedPartition0Overflow 98
+#define MGK_CoderErrorWebPEncodingFailedPartitionOverflow 99
+#define MGK_CoderErrorWebPEncodingFailedUserAbort 100
+#define MGK_CoderErrorWebPInvalidConfiguration 101
+#define MGK_CoderErrorWebPInvalidParameter 102
+#define MGK_CoderErrorZipCompressionNotSupported 103
+#define MGK_CoderFatalErrorDefault 104
+#define MGK_CoderWarningLosslessToLossyJPEGConversion 105
+#define MGK_ConfigureErrorIncludeElementNestedTooDeeply 106
+#define MGK_ConfigureErrorRegistryKeyLookupFailed 107
+#define MGK_ConfigureErrorStringTokenLengthExceeded 108
+#define MGK_ConfigureErrorUnableToAccessConfigureFile 109
+#define MGK_ConfigureErrorUnableToAccessFontFile 110
+#define MGK_ConfigureErrorUnableToAccessLogFile 111
+#define MGK_ConfigureErrorUnableToAccessModuleFile 112
+#define MGK_ConfigureFatalErrorDefault 113
+#define MGK_ConfigureFatalErrorUnableToChangeToWorkingDirectory 114
+#define MGK_ConfigureFatalErrorUnableToGetCurrentDirectory 115
+#define MGK_ConfigureFatalErrorUnableToRestoreCurrentDirectory 116
+#define MGK_ConfigureWarningDefault 117
+#define MGK_CorruptImageErrorAnErrorHasOccurredReadingFromFile 118
+#define MGK_CorruptImageErrorAnErrorHasOccurredWritingToFile 119
+#define MGK_CorruptImageErrorColormapExceedsColorsLimit 120
+#define MGK_CorruptImageErrorCompressionNotValid 121
+#define MGK_CorruptImageErrorCorruptImage 122
+#define MGK_CorruptImageErrorImageFileDoesNotContainAnyImageData 123
+#define MGK_CorruptImageErrorImageTypeNotSupported 124
+#define MGK_CorruptImageErrorImproperImageHeader 125
+#define MGK_CorruptImageErrorInsufficientImageDataInFile 126
+#define MGK_CorruptImageErrorInvalidColormapIndex 127
+#define MGK_CorruptImageErrorInvalidFileFormatVersion 128
+#define MGK_CorruptImageErrorLengthAndFilesizeDoNotMatch 129
+#define MGK_CorruptImageErrorMissingImageChannel 130
+#define MGK_CorruptImageErrorNegativeOrZeroImageSize 131
+#define MGK_CorruptImageErrorNonOS2HeaderSizeError 132
+#define MGK_CorruptImageErrorNotEnoughTiles 133
+#define MGK_CorruptImageErrorStaticPlanesValueNotEqualToOne 134
+#define MGK_CorruptImageErrorSubsamplingRequiresEvenWidth 135
+#define MGK_CorruptImageErrorTooMuchImageDataInFile 136
+#define MGK_CorruptImageErrorUnableToReadColormapFromDumpFile 137
+#define MGK_CorruptImageErrorUnableToReadColorProfile 138
+#define MGK_CorruptImageErrorUnableToReadExtensionBlock 139
+#define MGK_CorruptImageErrorUnableToReadGenericProfile 140
+#define MGK_CorruptImageErrorUnableToReadImageData 141
+#define MGK_CorruptImageErrorUnableToReadImageHeader 142
+#define MGK_CorruptImageErrorUnableToReadIPTCProfile 143
+#define MGK_CorruptImageErrorUnableToReadPixmapFromDumpFile 144
+#define MGK_CorruptImageErrorUnableToReadSubImageData 145
+#define MGK_CorruptImageErrorUnableToReadVIDImage 146
+#define MGK_CorruptImageErrorUnableToReadWindowNameFromDumpFile 147
+#define MGK_CorruptImageErrorUnableToRunlengthDecodeImage 148
+#define MGK_CorruptImageErrorUnableToUncompressImage 149
+#define MGK_CorruptImageErrorUnexpectedEndOfFile 150
+#define MGK_CorruptImageErrorUnexpectedSamplingFactor 151
+#define MGK_CorruptImageErrorUnknownPatternType 152
+#define MGK_CorruptImageErrorUnrecognizedBitsPerPixel 153
+#define MGK_CorruptImageErrorUnrecognizedImageCompression 154
+#define MGK_CorruptImageErrorUnrecognizedNumberOfColors 155
+#define MGK_CorruptImageErrorUnrecognizedXWDHeader 156
+#define MGK_CorruptImageErrorUnsupportedBitsPerSample 157
+#define MGK_CorruptImageErrorUnsupportedNumberOfPlanes 158
+#define MGK_CorruptImageFatalErrorUnableToPersistKey 159
+#define MGK_CorruptImageWarningCompressionNotValid 160
+#define MGK_CorruptImageWarningCorruptImage 161
+#define MGK_CorruptImageWarningImproperImageHeader 162
+#define MGK_CorruptImageWarningInvalidColormapIndex 163
+#define MGK_CorruptImageWarningLengthAndFilesizeDoNotMatch 164
+#define MGK_CorruptImageWarningNegativeOrZeroImageSize 165
+#define MGK_CorruptImageWarningNonOS2HeaderSizeError 166
+#define MGK_CorruptImageWarningSkipToSyncByte 167
+#define MGK_CorruptImageWarningStaticPlanesValueNotEqualToOne 168
+#define MGK_CorruptImageWarningUnrecognizedBitsPerPixel 169
+#define MGK_CorruptImageWarningUnrecognizedImageCompression 170
+#define MGK_DelegateErrorDelegateFailed 171
+#define MGK_DelegateErrorFailedToAllocateArgumentList 172
+#define MGK_DelegateErrorFailedToAllocateGhostscriptInterpreter 173
+#define MGK_DelegateErrorFailedToComputeOutputSize 174
+#define MGK_DelegateErrorFailedToFindGhostscript 175
+#define MGK_DelegateErrorFailedToRenderFile 176
+#define MGK_DelegateErrorFailedToScanFile 177
+#define MGK_DelegateErrorNoTagFound 178
+#define MGK_DelegateErrorPostscriptDelegateFailed 179
+#define MGK_DelegateErrorUnableToCreateImage 180
+#define MGK_DelegateErrorUnableToCreateImageComponent 181
+#define MGK_DelegateErrorUnableToDecodeImageFile 182
+#define MGK_DelegateErrorUnableToEncodeImageFile 183
+#define MGK_DelegateErrorUnableToInitializeFPXLibrary 184
+#define MGK_DelegateErrorUnableToInitializeWMFLibrary 185
+#define MGK_DelegateErrorUnableToManageJP2Stream 186
+#define MGK_DelegateErrorUnableToWriteSVGFormat 187
+#define MGK_DelegateErrorWebPABIMismatch 188
+#define MGK_DelegateFatalErrorDefault 189
+#define MGK_DelegateWarningDefault 190
+#define MGK_DrawErrorAlreadyPushingPatternDefinition 191
+#define MGK_DrawErrorDrawingRecursionDetected 192
+#define MGK_DrawErrorFloatValueConversionError 193
+#define MGK_DrawErrorIntegerValueConversionError 194
+#define MGK_DrawErrorInvalidPrimitiveArgument 195
+#define MGK_DrawErrorNonconformingDrawingPrimitiveDefinition 196
+#define MGK_DrawErrorPrimitiveArithmeticOverflow 197
+#define MGK_DrawErrorTooManyCoordinates 198
+#define MGK_DrawErrorUnableToPrint 199
+#define MGK_DrawErrorUnbalancedGraphicContextPushPop 200
+#define MGK_DrawErrorUnreasonableGradientSize 201
+#define MGK_DrawErrorVectorPathTruncated 202
+#define MGK_DrawFatalErrorDefault 203
+#define MGK_DrawWarningNotARelativeURL 204
+#define MGK_DrawWarningNotCurrentlyPushingPatternDefinition 205
+#define MGK_DrawWarningURLNotFound 206
+#define MGK_FileOpenErrorUnableToCreateTemporaryFile 207
+#define MGK_FileOpenErrorUnableToOpenFile 208
+#define MGK_FileOpenErrorUnableToWriteFile 209
+#define MGK_FileOpenFatalErrorDefault 210
+#define MGK_FileOpenWarningDefault 211
+#define MGK_ImageErrorAngleIsDiscontinuous 212
+#define MGK_ImageErrorColorspaceColorProfileMismatch 213
+#define MGK_ImageErrorImageColorspaceDiffers 214
+#define MGK_ImageErrorImageColorspaceMismatch 215
+#define MGK_ImageErrorImageDifferenceExceedsLimit 216
+#define MGK_ImageErrorImageDoesNotContainResolution 217
+#define MGK_ImageErrorImageOpacityDiffers 218
+#define MGK_ImageErrorImageSequenceIsRequired 219
+#define MGK_ImageErrorImageSizeDiffers 220
+#define MGK_ImageErrorInvalidColormapIndex 221
+#define MGK_ImageErrorLeftAndRightImageSizesDiffer 222
+#define MGK_ImageErrorNoImagesWereFound 223
+#define MGK_ImageErrorNoImagesWereLoaded 224
+#define MGK_ImageErrorNoLocaleImageAttribute 225
+#define MGK_ImageErrorTooManyClusters 226
+#define MGK_ImageErrorUnableToAppendImage 227
+#define MGK_ImageErrorUnableToAssignProfile 228
+#define MGK_ImageErrorUnableToAverageImage 229
+#define MGK_ImageErrorUnableToCoalesceImage 230
+#define MGK_ImageErrorUnableToCompareImages 231
+#define MGK_ImageErrorUnableToCreateImageMosaic 232
+#define MGK_ImageErrorUnableToCreateStereoImage 233
+#define MGK_ImageErrorUnableToDeconstructImageSequence 234
+#define MGK_ImageErrorUnableToFlattenImage 235
+#define MGK_ImageErrorUnableToGetClipMask 236
+#define MGK_ImageErrorUnableToHandleImageChannel 237
+#define MGK_ImageErrorUnableToResizeImage 238
+#define MGK_ImageErrorUnableToSegmentImage 239
+#define MGK_ImageErrorUnableToSetClipMask 240
+#define MGK_ImageErrorUnableToShearImage 241
+#define MGK_ImageErrorWidthOrHeightExceedsLimit 242
+#define MGK_ImageFatalErrorUnableToPersistKey 243
+#define MGK_ImageWarningDefault 244
+#define MGK_MissingDelegateErrorDPSLibraryIsNotAvailable 245
+#define MGK_MissingDelegateErrorFPXLibraryIsNotAvailable 246
+#define MGK_MissingDelegateErrorFreeTypeLibraryIsNotAvailable 247
+#define MGK_MissingDelegateErrorJPEGLibraryIsNotAvailable 248
+#define MGK_MissingDelegateErrorLCMSLibraryIsNotAvailable 249
+#define MGK_MissingDelegateErrorLZWEncodingNotEnabled 250
+#define MGK_MissingDelegateErrorNoDecodeDelegateForThisImageFormat 251
+#define MGK_MissingDelegateErrorNoEncodeDelegateForThisImageFormat 252
+#define MGK_MissingDelegateErrorTIFFLibraryIsNotAvailable 253
+#define MGK_MissingDelegateErrorXMLLibraryIsNotAvailable 254
+#define MGK_MissingDelegateErrorXWindowLibraryIsNotAvailable 255
+#define MGK_MissingDelegateErrorZipLibraryIsNotAvailable 256
+#define MGK_MissingDelegateFatalErrorDefault 257
+#define MGK_MissingDelegateWarningDefault 258
+#define MGK_ModuleErrorFailedToCloseModule 259
+#define MGK_ModuleErrorFailedToFindSymbol 260
+#define MGK_ModuleErrorUnableToLoadModule 261
+#define MGK_ModuleErrorUnableToRegisterImageFormat 262
+#define MGK_ModuleErrorUnrecognizedModule 263
+#define MGK_ModuleFatalErrorUnableToInitializeModuleLoader 264
+#define MGK_ModuleWarningDefault 265
+#define MGK_MonitorErrorDefault 266
+#define MGK_MonitorFatalErrorDefault 267
+#define MGK_MonitorFatalErrorUserRequestedTerminationBySignal 268
+#define MGK_MonitorWarningDefault 269
+#define MGK_OptionErrorBevelWidthIsNegative 270
+#define MGK_OptionErrorColorSeparatedImageRequired 271
+#define MGK_OptionErrorFrameIsLessThanImageSize 272
+#define MGK_OptionErrorGeometryDimensionsAreZero 273
+#define MGK_OptionErrorGeometryDoesNotContainImage 274
+#define MGK_OptionErrorHaldClutImageDimensionsInvalid 275
+#define MGK_OptionErrorImagesAreNotTheSameSize 276
+#define MGK_OptionErrorImageSizeMustExceedBevelWidth 277
+#define MGK_OptionErrorImageSmallerThanKernelWidth 278
+#define MGK_OptionErrorImageSmallerThanRadius 279
+#define MGK_OptionErrorImageWidthsOrHeightsDiffer 280
+#define MGK_OptionErrorInputImagesAlreadySpecified 281
+#define MGK_OptionErrorInvalidSubimageSpecification 282
+#define MGK_OptionErrorKernelRadiusIsTooSmall 283
+#define MGK_OptionErrorKernelWidthMustBeAnOddNumber 284
+#define MGK_OptionErrorMatrixIsNotSquare 285
+#define MGK_OptionErrorMatrixOrderOutOfRange 286
+#define MGK_OptionErrorMissingAnImageFilename 287
+#define MGK_OptionErrorMissingArgument 288
+#define MGK_OptionErrorMustSpecifyAnImageName 289
+#define MGK_OptionErrorMustSpecifyImageSize 290
+#define MGK_OptionErrorNoBlobDefined 291
+#define MGK_OptionErrorNoImagesDefined 292
+#define MGK_OptionErrorNonzeroWidthAndHeightRequired 293
+#define MGK_OptionErrorNoProfileNameWasGiven 294
+#define MGK_OptionErrorNullBlobArgument 295
+#define MGK_OptionErrorReferenceImageRequired 296
+#define MGK_OptionErrorReferenceIsNotMyType 297
+#define MGK_OptionErrorRegionAreaExceedsLimit 298
+#define MGK_OptionErrorRequestDidNotReturnAnImage 299
+#define MGK_OptionErrorSteganoImageRequired 300
+#define MGK_OptionErrorStereoImageRequired 301
+#define MGK_OptionErrorSubimageSpecificationReturnsNoImages 302
+#define MGK_OptionErrorUnableToAddOrRemoveProfile 303
+#define MGK_OptionErrorUnableToAverageImageSequence 304
+#define MGK_OptionErrorUnableToBlurImage 305
+#define MGK_OptionErrorUnableToChopImage 306
+#define MGK_OptionErrorUnableToColorMatrixImage 307
+#define MGK_OptionErrorUnableToConstituteImage 308
+#define MGK_OptionErrorUnableToConvolveImage 309
+#define MGK_OptionErrorUnableToEdgeImage 310
+#define MGK_OptionErrorUnableToEqualizeImage 311
+#define MGK_OptionErrorUnableToFilterImage 312
+#define MGK_OptionErrorUnableToFormatImageMetadata 313
+#define MGK_OptionErrorUnableToFrameImage 314
+#define MGK_OptionErrorUnableToOilPaintImage 315
+#define MGK_OptionErrorUnableToPaintImage 316
+#define MGK_OptionErrorUnableToRaiseImage 317
+#define MGK_OptionErrorUnableToSharpenImage 318
+#define MGK_OptionErrorUnableToThresholdImage 319
+#define MGK_OptionErrorUnableToWaveImage 320
+#define MGK_OptionErrorUnrecognizedAttribute 321
+#define MGK_OptionErrorUnrecognizedChannelType 322
+#define MGK_OptionErrorUnrecognizedColor 323
+#define MGK_OptionErrorUnrecognizedColormapType 324
+#define MGK_OptionErrorUnrecognizedColorspace 325
+#define MGK_OptionErrorUnrecognizedCommand 326
+#define MGK_OptionErrorUnrecognizedComposeOperator 327
+#define MGK_OptionErrorUnrecognizedDisposeMethod 328
+#define MGK_OptionErrorUnrecognizedElement 329
+#define MGK_OptionErrorUnrecognizedEndianType 330
+#define MGK_OptionErrorUnrecognizedGravityType 331
+#define MGK_OptionErrorUnrecognizedHighlightStyle 332
+#define MGK_OptionErrorUnrecognizedImageCompression 333
+#define MGK_OptionErrorUnrecognizedImageFilter 334
+#define MGK_OptionErrorUnrecognizedImageFormat 335
+#define MGK_OptionErrorUnrecognizedImageMode 336
+#define MGK_OptionErrorUnrecognizedImageType 337
+#define MGK_OptionErrorUnrecognizedIntentType 338
+#define MGK_OptionErrorUnrecognizedInterlaceType 339
+#define MGK_OptionErrorUnrecognizedListType 340
+#define MGK_OptionErrorUnrecognizedMetric 341
+#define MGK_OptionErrorUnrecognizedModeType 342
+#define MGK_OptionErrorUnrecognizedNoiseType 343
+#define MGK_OptionErrorUnrecognizedOperator 344
+#define MGK_OptionErrorUnrecognizedOption 345
+#define MGK_OptionErrorUnrecognizedPerlMagickMethod 346
+#define MGK_OptionErrorUnrecognizedPixelMap 347
+#define MGK_OptionErrorUnrecognizedPreviewType 348
+#define MGK_OptionErrorUnrecognizedResourceType 349
+#define MGK_OptionErrorUnrecognizedType 350
+#define MGK_OptionErrorUnrecognizedUnitsType 351
+#define MGK_OptionErrorUnrecognizedVirtualPixelMethod 352
+#define MGK_OptionErrorUnsupportedSamplingFactor 353
+#define MGK_OptionErrorUsageError 354
+#define MGK_OptionFatalErrorInvalidColorspaceType 355
+#define MGK_OptionFatalErrorInvalidEndianType 356
+#define MGK_OptionFatalErrorInvalidImageType 357
+#define MGK_OptionFatalErrorInvalidInterlaceType 358
+#define MGK_OptionFatalErrorMissingAnImageFilename 359
+#define MGK_OptionFatalErrorMissingArgument 360
+#define MGK_OptionFatalErrorNoImagesWereLoaded 361
+#define MGK_OptionFatalErrorOptionLengthExceedsLimit 362
+#define MGK_OptionFatalErrorRequestDidNotReturnAnImage 363
+#define MGK_OptionFatalErrorUnableToOpenXServer 364
+#define MGK_OptionFatalErrorUnableToPersistKey 365
+#define MGK_OptionFatalErrorUnrecognizedColormapType 366
+#define MGK_OptionFatalErrorUnrecognizedColorspaceType 367
+#define MGK_OptionFatalErrorUnrecognizedDisposeMethod 368
+#define MGK_OptionFatalErrorUnrecognizedEndianType 369
+#define MGK_OptionFatalErrorUnrecognizedFilterType 370
+#define MGK_OptionFatalErrorUnrecognizedImageCompressionType 371
+#define MGK_OptionFatalErrorUnrecognizedImageType 372
+#define MGK_OptionFatalErrorUnrecognizedInterlaceType 373
+#define MGK_OptionFatalErrorUnrecognizedOption 374
+#define MGK_OptionFatalErrorUnrecognizedResourceType 375
+#define MGK_OptionFatalErrorUnrecognizedVirtualPixelMethod 376
+#define MGK_OptionWarningUnrecognizedColor 377
+#define MGK_RegistryErrorImageExpected 378
+#define MGK_RegistryErrorImageInfoExpected 379
+#define MGK_RegistryErrorStructureSizeMismatch 380
+#define MGK_RegistryErrorUnableToGetRegistryID 381
+#define MGK_RegistryErrorUnableToLocateImage 382
+#define MGK_RegistryErrorUnableToSetRegistry 383
+#define MGK_RegistryFatalErrorDefault 384
+#define MGK_RegistryWarningDefault 385
+#define MGK_ResourceLimitErrorCacheResourcesExhausted 386
+#define MGK_ResourceLimitErrorImagePixelHeightLimitExceeded 387
+#define MGK_ResourceLimitErrorImagePixelLimitExceeded 388
+#define MGK_ResourceLimitErrorImagePixelWidthLimitExceeded 389
+#define MGK_ResourceLimitErrorMemoryAllocationFailed 390
+#define MGK_ResourceLimitErrorNoPixelsDefinedInCache 391
+#define MGK_ResourceLimitErrorPixelCacheAllocationFailed 392
+#define MGK_ResourceLimitErrorUnableToAddColorProfile 393
+#define MGK_ResourceLimitErrorUnableToAddGenericProfile 394
+#define MGK_ResourceLimitErrorUnableToAddIPTCProfile 395
+#define MGK_ResourceLimitErrorUnableToAllocateCoefficients 396
+#define MGK_ResourceLimitErrorUnableToAllocateColormap 397
+#define MGK_ResourceLimitErrorUnableToAllocateICCProfile 398
+#define MGK_ResourceLimitErrorUnableToAllocateImage 399
+#define MGK_ResourceLimitErrorUnableToAllocateString 400
+#define MGK_ResourceLimitErrorUnableToAnnotateImage 401
+#define MGK_ResourceLimitErrorUnableToAverageImageSequence 402
+#define MGK_ResourceLimitErrorUnableToCloneDrawingWand 403
+#define MGK_ResourceLimitErrorUnableToCloneImage 404
+#define MGK_ResourceLimitErrorUnableToComputeImageSignature 405
+#define MGK_ResourceLimitErrorUnableToConstituteImage 406
+#define MGK_ResourceLimitErrorUnableToConvertFont 407
+#define MGK_ResourceLimitErrorUnableToConvertStringToTokens 408
+#define MGK_ResourceLimitErrorUnableToCreateColormap 409
+#define MGK_ResourceLimitErrorUnableToCreateColorTransform 410
+#define MGK_ResourceLimitErrorUnableToCreateCommandWidget 411
+#define MGK_ResourceLimitErrorUnableToCreateImageGroup 412
+#define MGK_ResourceLimitErrorUnableToCreateImageMontage 413
+#define MGK_ResourceLimitErrorUnableToCreateXWindow 414
+#define MGK_ResourceLimitErrorUnableToCropImage 415
+#define MGK_ResourceLimitErrorUnableToDespeckleImage 416
+#define MGK_ResourceLimitErrorUnableToDetermineImageClass 417
+#define MGK_ResourceLimitErrorUnableToDetermineTheNumberOfImageColors 418
+#define MGK_ResourceLimitErrorUnableToDitherImage 419
+#define MGK_ResourceLimitErrorUnableToDrawOnImage 420
+#define MGK_ResourceLimitErrorUnableToEdgeImage 421
+#define MGK_ResourceLimitErrorUnableToEmbossImage 422
+#define MGK_ResourceLimitErrorUnableToEnhanceImage 423
+#define MGK_ResourceLimitErrorUnableToFloodfillImage 424
+#define MGK_ResourceLimitErrorUnableToGammaCorrectImage 425
+#define MGK_ResourceLimitErrorUnableToGetBestIconSize 426
+#define MGK_ResourceLimitErrorUnableToGetFromRegistry 427
+#define MGK_ResourceLimitErrorUnableToGetPackageInfo 428
+#define MGK_ResourceLimitErrorUnableToLevelImage 429
+#define MGK_ResourceLimitErrorUnableToMagnifyImage 430
+#define MGK_ResourceLimitErrorUnableToManageColor 431
+#define MGK_ResourceLimitErrorUnableToMapImage 432
+#define MGK_ResourceLimitErrorUnableToMapImageSequence 433
+#define MGK_ResourceLimitErrorUnableToMedianFilterImage 434
+#define MGK_ResourceLimitErrorUnableToMotionBlurImage 435
+#define MGK_ResourceLimitErrorUnableToNoiseFilterImage 436
+#define MGK_ResourceLimitErrorUnableToNormalizeImage 437
+#define MGK_ResourceLimitErrorUnableToOpenColorProfile 438
+#define MGK_ResourceLimitErrorUnableToQuantizeImage 439
+#define MGK_ResourceLimitErrorUnableToQuantizeImageSequence 440
+#define MGK_ResourceLimitErrorUnableToReadTextChunk 441
+#define MGK_ResourceLimitErrorUnableToReadXImage 442
+#define MGK_ResourceLimitErrorUnableToReadXServerColormap 443
+#define MGK_ResourceLimitErrorUnableToResizeImage 444
+#define MGK_ResourceLimitErrorUnableToRotateImage 445
+#define MGK_ResourceLimitErrorUnableToSampleImage 446
+#define MGK_ResourceLimitErrorUnableToScaleImage 447
+#define MGK_ResourceLimitErrorUnableToSelectImage 448
+#define MGK_ResourceLimitErrorUnableToSharpenImage 449
+#define MGK_ResourceLimitErrorUnableToShaveImage 450
+#define MGK_ResourceLimitErrorUnableToShearImage 451
+#define MGK_ResourceLimitErrorUnableToSortImageColormap 452
+#define MGK_ResourceLimitErrorUnableToThresholdImage 453
+#define MGK_ResourceLimitErrorUnableToTransformColorspace 454
+#define MGK_ResourceLimitFatalErrorMemoryAllocationFailed 455
+#define MGK_ResourceLimitFatalErrorSemaporeOperationFailed 456
+#define MGK_ResourceLimitFatalErrorUnableToAllocateAscii85Info 457
+#define MGK_ResourceLimitFatalErrorUnableToAllocateCacheInfo 458
+#define MGK_ResourceLimitFatalErrorUnableToAllocateCacheView 459
+#define MGK_ResourceLimitFatalErrorUnableToAllocateColorInfo 460
+#define MGK_ResourceLimitFatalErrorUnableToAllocateDashPattern 461
+#define MGK_ResourceLimitFatalErrorUnableToAllocateDelegateInfo 462
+#define MGK_ResourceLimitFatalErrorUnableToAllocateDerivatives 463
+#define MGK_ResourceLimitFatalErrorUnableToAllocateDrawContext 464
+#define MGK_ResourceLimitFatalErrorUnableToAllocateDrawInfo 465
+#define MGK_ResourceLimitFatalErrorUnableToAllocateDrawingWand 466
+#define MGK_ResourceLimitFatalErrorUnableToAllocateGammaMap 467
+#define MGK_ResourceLimitFatalErrorUnableToAllocateImage 468
+#define MGK_ResourceLimitFatalErrorUnableToAllocateImagePixels 469
+#define MGK_ResourceLimitFatalErrorUnableToAllocateLogInfo 470
+#define MGK_ResourceLimitFatalErrorUnableToAllocateMagicInfo 471
+#define MGK_ResourceLimitFatalErrorUnableToAllocateMagickInfo 472
+#define MGK_ResourceLimitFatalErrorUnableToAllocateModuleInfo 473
+#define MGK_ResourceLimitFatalErrorUnableToAllocateMontageInfo 474
+#define MGK_ResourceLimitFatalErrorUnableToAllocateQuantizeInfo 475
+#define MGK_ResourceLimitFatalErrorUnableToAllocateRandomKernel 476
+#define MGK_ResourceLimitFatalErrorUnableToAllocateRegistryInfo 477
+#define MGK_ResourceLimitFatalErrorUnableToAllocateSemaphoreInfo 478
+#define MGK_ResourceLimitFatalErrorUnableToAllocateString 479
+#define MGK_ResourceLimitFatalErrorUnableToAllocateTypeInfo 480
+#define MGK_ResourceLimitFatalErrorUnableToAllocateWand 481
+#define MGK_ResourceLimitFatalErrorUnableToAnimateImageSequence 482
+#define MGK_ResourceLimitFatalErrorUnableToCloneBlobInfo 483
+#define MGK_ResourceLimitFatalErrorUnableToCloneCacheInfo 484
+#define MGK_ResourceLimitFatalErrorUnableToCloneImage 485
+#define MGK_ResourceLimitFatalErrorUnableToCloneImageInfo 486
+#define MGK_ResourceLimitFatalErrorUnableToConcatenateString 487
+#define MGK_ResourceLimitFatalErrorUnableToConvertText 488
+#define MGK_ResourceLimitFatalErrorUnableToCreateColormap 489
+#define MGK_ResourceLimitFatalErrorUnableToDestroySemaphore 490
+#define MGK_ResourceLimitFatalErrorUnableToDisplayImage 491
+#define MGK_ResourceLimitFatalErrorUnableToEscapeString 492
+#define MGK_ResourceLimitFatalErrorUnableToInitializeSemaphore 493
+#define MGK_ResourceLimitFatalErrorUnableToInterpretMSLImage 494
+#define MGK_ResourceLimitFatalErrorUnableToLockSemaphore 495
+#define MGK_ResourceLimitFatalErrorUnableToObtainRandomEntropy 496
+#define MGK_ResourceLimitFatalErrorUnableToUnlockSemaphore 497
+#define MGK_ResourceLimitWarningMemoryAllocationFailed 498
+#define MGK_StreamErrorImageDoesNotContainTheStreamGeometry 499
+#define MGK_StreamErrorNoStreamHandlerIsDefined 500
+#define MGK_StreamErrorPixelCacheIsNotOpen 501
+#define MGK_StreamErrorUnableToAcquirePixelStream 502
+#define MGK_StreamErrorUnableToSetPixelStream 503
+#define MGK_StreamErrorUnableToSyncPixelStream 504
+#define MGK_StreamFatalErrorDefault 505
+#define MGK_StreamWarningDefault 506
+#define MGK_TypeErrorFontSubstitutionRequired 507
+#define MGK_TypeErrorUnableToGetTypeMetrics 508
+#define MGK_TypeErrorUnableToInitializeFreetypeLibrary 509
+#define MGK_TypeErrorUnableToReadFont 510
+#define MGK_TypeErrorUnrecognizedFontEncoding 511
+#define MGK_TypeFatalErrorDefault 512
+#define MGK_TypeWarningDefault 513
+#define MGK_WandErrorInvalidColormapIndex 514
+#define MGK_WandErrorWandAPINotImplemented 515
+#define MGK_WandErrorWandContainsNoImageIndexs 516
+#define MGK_WandErrorWandContainsNoImages 517
+#define MGK_XServerErrorColorIsNotKnownToServer 518
+#define MGK_XServerErrorNoWindowWithSpecifiedIDExists 519
+#define MGK_XServerErrorStandardColormapIsNotInitialized 520
+#define MGK_XServerErrorUnableToConnectToRemoteDisplay 521
+#define MGK_XServerErrorUnableToCreateBitmap 522
+#define MGK_XServerErrorUnableToCreateColormap 523
+#define MGK_XServerErrorUnableToCreatePixmap 524
+#define MGK_XServerErrorUnableToCreateProperty 525
+#define MGK_XServerErrorUnableToCreateStandardColormap 526
+#define MGK_XServerErrorUnableToDisplayImageInfo 527
+#define MGK_XServerErrorUnableToGetProperty 528
+#define MGK_XServerErrorUnableToGetStandardColormap 529
+#define MGK_XServerErrorUnableToGetVisual 530
+#define MGK_XServerErrorUnableToGrabMouse 531
+#define MGK_XServerErrorUnableToLoadFont 532
+#define MGK_XServerErrorUnableToMatchVisualToStandardColormap 533
+#define MGK_XServerErrorUnableToOpenXServer 534
+#define MGK_XServerErrorUnableToReadXAttributes 535
+#define MGK_XServerErrorUnableToReadXWindowImage 536
+#define MGK_XServerErrorUnrecognizedColormapType 537
+#define MGK_XServerErrorUnrecognizedGravityType 538
+#define MGK_XServerErrorUnrecognizedVisualSpecifier 539
+#define MGK_XServerFatalErrorUnableToAllocateXHints 540
+#define MGK_XServerFatalErrorUnableToCreateCursor 541
+#define MGK_XServerFatalErrorUnableToCreateGraphicContext 542
+#define MGK_XServerFatalErrorUnableToCreateStandardColormap 543
+#define MGK_XServerFatalErrorUnableToCreateTextProperty 544
+#define MGK_XServerFatalErrorUnableToCreateXImage 545
+#define MGK_XServerFatalErrorUnableToCreateXPixmap 546
+#define MGK_XServerFatalErrorUnableToCreateXWindow 547
+#define MGK_XServerFatalErrorUnableToDisplayImage 548
+#define MGK_XServerFatalErrorUnableToDitherImage 549
+#define MGK_XServerFatalErrorUnableToGetPixelInfo 550
+#define MGK_XServerFatalErrorUnableToGetVisual 551
+#define MGK_XServerFatalErrorUnableToLoadFont 552
+#define MGK_XServerFatalErrorUnableToMakeXWindow 553
+#define MGK_XServerFatalErrorUnableToOpenXServer 554
+#define MGK_XServerFatalErrorUnableToViewFonts 555
+#define MGK_XServerWarningUnableToGetVisual 556
+#define MGK_XServerWarningUsingDefaultVisual 557
+
+#endif
+
+#if defined(_INCLUDE_CATEGORYMAP_TABLE_)
+typedef struct _CategoryInfo{
+ const char *name;
+ int offset;
+} CategoryInfo;
+
+static const CategoryInfo category_map[] =
+ {
+ { "Blob", 0 },
+ { "Cache", 3 },
+ { "Coder", 6 },
+ { "Configure", 9 },
+ { "Corrupt/Image", 12 },
+ { "Delegate", 15 },
+ { "Draw", 18 },
+ { "File/Open", 21 },
+ { "Image", 24 },
+ { "Missing/Delegate", 27 },
+ { "Module", 30 },
+ { "Monitor", 33 },
+ { "Option", 36 },
+ { "Registry", 39 },
+ { "Resource/Limit", 42 },
+ { "Stream", 45 },
+ { "Type", 48 },
+ { "Wand", 51 },
+ { "XServer", 52 },
+ { 0, 54 }
+ };
+#endif
+
+#if defined(_INCLUDE_SEVERITYMAP_TABLE_)
+typedef struct _SeverityInfo{
+ const char *name;
+ int offset;
+ ExceptionType severityid;
+} SeverityInfo;
+
+static const SeverityInfo severity_map[] =
+ {
+ { "Blob/Error", 0, BlobError },
+ { "Blob/FatalError", 8, BlobFatalError },
+ { "Blob/Warning", 9, BlobWarning },
+ { "Cache/Error", 10, CacheError },
+ { "Cache/FatalError", 21, CacheFatalError },
+ { "Cache/Warning", 23, CacheWarning },
+ { "Coder/Error", 24, CoderError },
+ { "Coder/FatalError", 103, CoderFatalError },
+ { "Coder/Warning", 104, CoderWarning },
+ { "Configure/Error", 105, ConfigureError },
+ { "Configure/FatalError", 112, ConfigureFatalError },
+ { "Configure/Warning", 116, ConfigureWarning },
+ { "Corrupt/Image/Error", 117, CorruptImageError },
+ { "Corrupt/Image/FatalError", 158, CorruptImageFatalError },
+ { "Corrupt/Image/Warning", 159, CorruptImageWarning },
+ { "Delegate/Error", 170, DelegateError },
+ { "Delegate/FatalError", 188, DelegateFatalError },
+ { "Delegate/Warning", 189, DelegateWarning },
+ { "Draw/Error", 190, DrawError },
+ { "Draw/FatalError", 202, DrawFatalError },
+ { "Draw/Warning", 203, DrawWarning },
+ { "File/Open/Error", 206, FileOpenError },
+ { "File/Open/FatalError", 209, FileOpenFatalError },
+ { "File/Open/Warning", 210, FileOpenWarning },
+ { "Image/Error", 211, ImageError },
+ { "Image/FatalError", 242, ImageFatalError },
+ { "Image/Warning", 243, ImageWarning },
+ { "Missing/Delegate/Error", 244, MissingDelegateError },
+ { "Missing/Delegate/FatalError", 256, MissingDelegateFatalError },
+ { "Missing/Delegate/Warning", 257, MissingDelegateWarning },
+ { "Module/Error", 258, ModuleError },
+ { "Module/FatalError", 263, ModuleFatalError },
+ { "Module/Warning", 264, ModuleWarning },
+ { "Monitor/Error", 265, MonitorError },
+ { "Monitor/FatalError", 266, MonitorFatalError },
+ { "Monitor/Warning", 268, MonitorWarning },
+ { "Option/Error", 269, OptionError },
+ { "Option/FatalError", 354, OptionFatalError },
+ { "Option/Warning", 376, OptionWarning },
+ { "Registry/Error", 377, RegistryError },
+ { "Registry/FatalError", 383, RegistryFatalError },
+ { "Registry/Warning", 384, RegistryWarning },
+ { "Resource/Limit/Error", 385, ResourceLimitError },
+ { "Resource/Limit/FatalError", 454, ResourceLimitFatalError },
+ { "Resource/Limit/Warning", 497, ResourceLimitWarning },
+ { "Stream/Error", 498, StreamError },
+ { "Stream/FatalError", 504, StreamFatalError },
+ { "Stream/Warning", 505, StreamWarning },
+ { "Type/Error", 506, TypeError },
+ { "Type/FatalError", 511, TypeFatalError },
+ { "Type/Warning", 512, TypeWarning },
+ { "Wand/Error", 513, WandError },
+ { "XServer/Error", 517, XServerError },
+ { "XServer/FatalError", 539, XServerFatalError },
+ { "XServer/Warning", 555, XServerWarning },
+ { 0, 557, UndefinedException }
+ };
+#endif
+
+#if defined(_INCLUDE_TAGMAP_TABLE_)
+typedef struct _MessageInfo
+{
+ const char *name;
+ int messageid;
+} MessageInfo;
+
+static const MessageInfo message_map[] =
+ {
+ { "UnableToCreateBlob", 1 },
+ { "UnableToObtainOffset", 2 },
+ { "UnableToOpenFile", 3 },
+ { "UnableToReadFile", 4 },
+ { "UnableToReadToOffset", 5 },
+ { "UnableToSeekToOffset", 6 },
+ { "UnableToWriteBlob", 7 },
+ { "UnrecognizedImageFormat", 8 },
+ { "Default", 9 },
+ { "Default", 10 },
+ { "InconsistentPersistentCacheDepth", 11 },
+ { "PixelCacheIsNotOpen", 12 },
+ { "UnableToAllocateCacheView", 13 },
+ { "UnableToCloneCache", 14 },
+ { "UnableToExtendCache", 15 },
+ { "UnableToGetCacheNexus", 16 },
+ { "UnableToGetPixelsFromCache", 17 },
+ { "UnableToOpenCache", 18 },
+ { "UnableToPeristPixelCache", 19 },
+ { "UnableToReadPixelCache", 20 },
+ { "UnableToSyncCache", 21 },
+ { "DiskAllocationFailed", 22 },
+ { "UnableToExtendPixelCache", 23 },
+ { "Default", 24 },
+ { "ColormapTooLarge", 25 },
+ { "ColormapTypeNotSupported", 26 },
+ { "ColorspaceModelIsNotSupported", 27 },
+ { "ColorTypeNotSupported", 28 },
+ { "CompressionNotValid", 29 },
+ { "DataEncodingSchemeIsNotSupported", 30 },
+ { "DataStorageTypeIsNotSupported", 31 },
+ { "DeltaPNGNotSupported", 32 },
+ { "EncryptedWPGImageFileNotSupported", 33 },
+ { "FractalCompressionNotSupported", 34 },
+ { "ImageColumnOrRowSizeIsNotSupported", 35 },
+ { "ImageDoesNotHaveAMatteChannel", 36 },
+ { "ImageIsNotTiled", 37 },
+ { "ImageTypeNotSupported", 38 },
+ { "IncompatibleSizeOfDouble", 39 },
+ { "IrregularChannelGeometryNotSupported", 40 },
+ { "JNGCompressionNotSupported", 41 },
+ { "JPEGCompressionNotSupported", 42 },
+ { "JPEGEmbeddingFailed", 43 },
+ { "LocationTypeIsNotSupported", 44 },
+ { "MapStorageTypeIsNotSupported", 45 },
+ { "MSBByteOrderNotSupported", 46 },
+ { "MultidimensionalMatricesAreNotSupported", 47 },
+ { "MultipleRecordListNotSupported", 48 },
+ { "No8BIMDataIsAvailable", 49 },
+ { "NoAPP1DataIsAvailable", 50 },
+ { "NoBitmapOnClipboard", 51 },
+ { "NoColorProfileAvailable", 52 },
+ { "NoDataReturned", 53 },
+ { "NoImageVectorGraphics", 54 },
+ { "NoIPTCInfoWasFound", 55 },
+ { "NoIPTCProfileAvailable", 56 },
+ { "NumberOfImagesIsNotSupported", 57 },
+ { "OnlyContinuousTonePictureSupported", 58 },
+ { "OnlyLevelZerofilesSupported", 59 },
+ { "PNGCompressionNotSupported", 60 },
+ { "PNGLibraryTooOld", 61 },
+ { "RLECompressionNotSupported", 62 },
+ { "SubsamplingRequiresEvenWidth", 63 },
+ { "UnableToCopyProfile", 64 },
+ { "UnableToCreateADC", 65 },
+ { "UnableToCreateBitmap", 66 },
+ { "UnableToDecompressImage", 67 },
+ { "UnableToInitializeFPXLibrary", 68 },
+ { "UnableToOpenBlob", 69 },
+ { "UnableToReadAspectRatio", 70 },
+ { "UnableToReadCIELABImages", 71 },
+ { "UnableToReadSummaryInfo", 72 },
+ { "UnableToSetAffineMatrix", 73 },
+ { "UnableToSetAspectRatio", 74 },
+ { "UnableToSetColorTwist", 75 },
+ { "UnableToSetContrast", 76 },
+ { "UnableToSetFilteringValue", 77 },
+ { "UnableToSetImageComments", 78 },
+ { "UnableToSetImageTitle", 79 },
+ { "UnableToSetJPEGLevel", 80 },
+ { "UnableToSetRegionOfInterest", 81 },
+ { "UnableToSetSummaryInfo", 82 },
+ { "UnableToTranslateText", 83 },
+ { "UnableToWriteMPEGParameters", 84 },
+ { "UnableToWriteTemporaryFile", 85 },
+ { "UnableToZipCompressImage", 86 },
+ { "UnsupportedBitsPerSample", 87 },
+ { "UnsupportedCellTypeInTheMatrix", 88 },
+ { "WebPDecodingFailedUserAbort", 89 },
+ { "WebPEncodingFailed", 90 },
+ { "WebPEncodingFailedBadDimension", 91 },
+ { "WebPEncodingFailedBadWrite", 92 },
+ { "WebPEncodingFailedBitstreamOutOfMemory", 93 },
+ { "WebPEncodingFailedFileTooBig", 94 },
+ { "WebPEncodingFailedInvalidConfiguration", 95 },
+ { "WebPEncodingFailedNULLParameter", 96 },
+ { "WebPEncodingFailedOutOfMemory", 97 },
+ { "WebPEncodingFailedPartition0Overflow", 98 },
+ { "WebPEncodingFailedPartitionOverflow", 99 },
+ { "WebPEncodingFailedUserAbort", 100 },
+ { "WebPInvalidConfiguration", 101 },
+ { "WebPInvalidParameter", 102 },
+ { "ZipCompressionNotSupported", 103 },
+ { "Default", 104 },
+ { "LosslessToLossyJPEGConversion", 105 },
+ { "IncludeElementNestedTooDeeply", 106 },
+ { "RegistryKeyLookupFailed", 107 },
+ { "StringTokenLengthExceeded", 108 },
+ { "UnableToAccessConfigureFile", 109 },
+ { "UnableToAccessFontFile", 110 },
+ { "UnableToAccessLogFile", 111 },
+ { "UnableToAccessModuleFile", 112 },
+ { "Default", 113 },
+ { "UnableToChangeToWorkingDirectory", 114 },
+ { "UnableToGetCurrentDirectory", 115 },
+ { "UnableToRestoreCurrentDirectory", 116 },
+ { "Default", 117 },
+ { "AnErrorHasOccurredReadingFromFile", 118 },
+ { "AnErrorHasOccurredWritingToFile", 119 },
+ { "ColormapExceedsColorsLimit", 120 },
+ { "CompressionNotValid", 121 },
+ { "CorruptImage", 122 },
+ { "ImageFileDoesNotContainAnyImageData", 123 },
+ { "ImageTypeNotSupported", 124 },
+ { "ImproperImageHeader", 125 },
+ { "InsufficientImageDataInFile", 126 },
+ { "InvalidColormapIndex", 127 },
+ { "InvalidFileFormatVersion", 128 },
+ { "LengthAndFilesizeDoNotMatch", 129 },
+ { "MissingImageChannel", 130 },
+ { "NegativeOrZeroImageSize", 131 },
+ { "NonOS2HeaderSizeError", 132 },
+ { "NotEnoughTiles", 133 },
+ { "StaticPlanesValueNotEqualToOne", 134 },
+ { "SubsamplingRequiresEvenWidth", 135 },
+ { "TooMuchImageDataInFile", 136 },
+ { "UnableToReadColormapFromDumpFile", 137 },
+ { "UnableToReadColorProfile", 138 },
+ { "UnableToReadExtensionBlock", 139 },
+ { "UnableToReadGenericProfile", 140 },
+ { "UnableToReadImageData", 141 },
+ { "UnableToReadImageHeader", 142 },
+ { "UnableToReadIPTCProfile", 143 },
+ { "UnableToReadPixmapFromDumpFile", 144 },
+ { "UnableToReadSubImageData", 145 },
+ { "UnableToReadVIDImage", 146 },
+ { "UnableToReadWindowNameFromDumpFile", 147 },
+ { "UnableToRunlengthDecodeImage", 148 },
+ { "UnableToUncompressImage", 149 },
+ { "UnexpectedEndOfFile", 150 },
+ { "UnexpectedSamplingFactor", 151 },
+ { "UnknownPatternType", 152 },
+ { "UnrecognizedBitsPerPixel", 153 },
+ { "UnrecognizedImageCompression", 154 },
+ { "UnrecognizedNumberOfColors", 155 },
+ { "UnrecognizedXWDHeader", 156 },
+ { "UnsupportedBitsPerSample", 157 },
+ { "UnsupportedNumberOfPlanes", 158 },
+ { "UnableToPersistKey", 159 },
+ { "CompressionNotValid", 160 },
+ { "CorruptImage", 161 },
+ { "ImproperImageHeader", 162 },
+ { "InvalidColormapIndex", 163 },
+ { "LengthAndFilesizeDoNotMatch", 164 },
+ { "NegativeOrZeroImageSize", 165 },
+ { "NonOS2HeaderSizeError", 166 },
+ { "SkipToSyncByte", 167 },
+ { "StaticPlanesValueNotEqualToOne", 168 },
+ { "UnrecognizedBitsPerPixel", 169 },
+ { "UnrecognizedImageCompression", 170 },
+ { "DelegateFailed", 171 },
+ { "FailedToAllocateArgumentList", 172 },
+ { "FailedToAllocateGhostscriptInterpreter", 173 },
+ { "FailedToComputeOutputSize", 174 },
+ { "FailedToFindGhostscript", 175 },
+ { "FailedToRenderFile", 176 },
+ { "FailedToScanFile", 177 },
+ { "NoTagFound", 178 },
+ { "PostscriptDelegateFailed", 179 },
+ { "UnableToCreateImage", 180 },
+ { "UnableToCreateImageComponent", 181 },
+ { "UnableToDecodeImageFile", 182 },
+ { "UnableToEncodeImageFile", 183 },
+ { "UnableToInitializeFPXLibrary", 184 },
+ { "UnableToInitializeWMFLibrary", 185 },
+ { "UnableToManageJP2Stream", 186 },
+ { "UnableToWriteSVGFormat", 187 },
+ { "WebPABIMismatch", 188 },
+ { "Default", 189 },
+ { "Default", 190 },
+ { "AlreadyPushingPatternDefinition", 191 },
+ { "DrawingRecursionDetected", 192 },
+ { "FloatValueConversionError", 193 },
+ { "IntegerValueConversionError", 194 },
+ { "InvalidPrimitiveArgument", 195 },
+ { "NonconformingDrawingPrimitiveDefinition", 196 },
+ { "PrimitiveArithmeticOverflow", 197 },
+ { "TooManyCoordinates", 198 },
+ { "UnableToPrint", 199 },
+ { "UnbalancedGraphicContextPushPop", 200 },
+ { "UnreasonableGradientSize", 201 },
+ { "VectorPathTruncated", 202 },
+ { "Default", 203 },
+ { "NotARelativeURL", 204 },
+ { "NotCurrentlyPushingPatternDefinition", 205 },
+ { "URLNotFound", 206 },
+ { "UnableToCreateTemporaryFile", 207 },
+ { "UnableToOpenFile", 208 },
+ { "UnableToWriteFile", 209 },
+ { "Default", 210 },
+ { "Default", 211 },
+ { "AngleIsDiscontinuous", 212 },
+ { "ColorspaceColorProfileMismatch", 213 },
+ { "ImageColorspaceDiffers", 214 },
+ { "ImageColorspaceMismatch", 215 },
+ { "ImageDifferenceExceedsLimit", 216 },
+ { "ImageDoesNotContainResolution", 217 },
+ { "ImageOpacityDiffers", 218 },
+ { "ImageSequenceIsRequired", 219 },
+ { "ImageSizeDiffers", 220 },
+ { "InvalidColormapIndex", 221 },
+ { "LeftAndRightImageSizesDiffer", 222 },
+ { "NoImagesWereFound", 223 },
+ { "NoImagesWereLoaded", 224 },
+ { "NoLocaleImageAttribute", 225 },
+ { "TooManyClusters", 226 },
+ { "UnableToAppendImage", 227 },
+ { "UnableToAssignProfile", 228 },
+ { "UnableToAverageImage", 229 },
+ { "UnableToCoalesceImage", 230 },
+ { "UnableToCompareImages", 231 },
+ { "UnableToCreateImageMosaic", 232 },
+ { "UnableToCreateStereoImage", 233 },
+ { "UnableToDeconstructImageSequence", 234 },
+ { "UnableToFlattenImage", 235 },
+ { "UnableToGetClipMask", 236 },
+ { "UnableToHandleImageChannel", 237 },
+ { "UnableToResizeImage", 238 },
+ { "UnableToSegmentImage", 239 },
+ { "UnableToSetClipMask", 240 },
+ { "UnableToShearImage", 241 },
+ { "WidthOrHeightExceedsLimit", 242 },
+ { "UnableToPersistKey", 243 },
+ { "Default", 244 },
+ { "DPSLibraryIsNotAvailable", 245 },
+ { "FPXLibraryIsNotAvailable", 246 },
+ { "FreeTypeLibraryIsNotAvailable", 247 },
+ { "JPEGLibraryIsNotAvailable", 248 },
+ { "LCMSLibraryIsNotAvailable", 249 },
+ { "LZWEncodingNotEnabled", 250 },
+ { "NoDecodeDelegateForThisImageFormat", 251 },
+ { "NoEncodeDelegateForThisImageFormat", 252 },
+ { "TIFFLibraryIsNotAvailable", 253 },
+ { "XMLLibraryIsNotAvailable", 254 },
+ { "XWindowLibraryIsNotAvailable", 255 },
+ { "ZipLibraryIsNotAvailable", 256 },
+ { "Default", 257 },
+ { "Default", 258 },
+ { "FailedToCloseModule", 259 },
+ { "FailedToFindSymbol", 260 },
+ { "UnableToLoadModule", 261 },
+ { "UnableToRegisterImageFormat", 262 },
+ { "UnrecognizedModule", 263 },
+ { "UnableToInitializeModuleLoader", 264 },
+ { "Default", 265 },
+ { "Default", 266 },
+ { "Default", 267 },
+ { "UserRequestedTerminationBySignal", 268 },
+ { "Default", 269 },
+ { "BevelWidthIsNegative", 270 },
+ { "ColorSeparatedImageRequired", 271 },
+ { "FrameIsLessThanImageSize", 272 },
+ { "GeometryDimensionsAreZero", 273 },
+ { "GeometryDoesNotContainImage", 274 },
+ { "HaldClutImageDimensionsInvalid", 275 },
+ { "ImagesAreNotTheSameSize", 276 },
+ { "ImageSizeMustExceedBevelWidth", 277 },
+ { "ImageSmallerThanKernelWidth", 278 },
+ { "ImageSmallerThanRadius", 279 },
+ { "ImageWidthsOrHeightsDiffer", 280 },
+ { "InputImagesAlreadySpecified", 281 },
+ { "InvalidSubimageSpecification", 282 },
+ { "KernelRadiusIsTooSmall", 283 },
+ { "KernelWidthMustBeAnOddNumber", 284 },
+ { "MatrixIsNotSquare", 285 },
+ { "MatrixOrderOutOfRange", 286 },
+ { "MissingAnImageFilename", 287 },
+ { "MissingArgument", 288 },
+ { "MustSpecifyAnImageName", 289 },
+ { "MustSpecifyImageSize", 290 },
+ { "NoBlobDefined", 291 },
+ { "NoImagesDefined", 292 },
+ { "NonzeroWidthAndHeightRequired", 293 },
+ { "NoProfileNameWasGiven", 294 },
+ { "NullBlobArgument", 295 },
+ { "ReferenceImageRequired", 296 },
+ { "ReferenceIsNotMyType", 297 },
+ { "RegionAreaExceedsLimit", 298 },
+ { "RequestDidNotReturnAnImage", 299 },
+ { "SteganoImageRequired", 300 },
+ { "StereoImageRequired", 301 },
+ { "SubimageSpecificationReturnsNoImages", 302 },
+ { "UnableToAddOrRemoveProfile", 303 },
+ { "UnableToAverageImageSequence", 304 },
+ { "UnableToBlurImage", 305 },
+ { "UnableToChopImage", 306 },
+ { "UnableToColorMatrixImage", 307 },
+ { "UnableToConstituteImage", 308 },
+ { "UnableToConvolveImage", 309 },
+ { "UnableToEdgeImage", 310 },
+ { "UnableToEqualizeImage", 311 },
+ { "UnableToFilterImage", 312 },
+ { "UnableToFormatImageMetadata", 313 },
+ { "UnableToFrameImage", 314 },
+ { "UnableToOilPaintImage", 315 },
+ { "UnableToPaintImage", 316 },
+ { "UnableToRaiseImage", 317 },
+ { "UnableToSharpenImage", 318 },
+ { "UnableToThresholdImage", 319 },
+ { "UnableToWaveImage", 320 },
+ { "UnrecognizedAttribute", 321 },
+ { "UnrecognizedChannelType", 322 },
+ { "UnrecognizedColor", 323 },
+ { "UnrecognizedColormapType", 324 },
+ { "UnrecognizedColorspace", 325 },
+ { "UnrecognizedCommand", 326 },
+ { "UnrecognizedComposeOperator", 327 },
+ { "UnrecognizedDisposeMethod", 328 },
+ { "UnrecognizedElement", 329 },
+ { "UnrecognizedEndianType", 330 },
+ { "UnrecognizedGravityType", 331 },
+ { "UnrecognizedHighlightStyle", 332 },
+ { "UnrecognizedImageCompression", 333 },
+ { "UnrecognizedImageFilter", 334 },
+ { "UnrecognizedImageFormat", 335 },
+ { "UnrecognizedImageMode", 336 },
+ { "UnrecognizedImageType", 337 },
+ { "UnrecognizedIntentType", 338 },
+ { "UnrecognizedInterlaceType", 339 },
+ { "UnrecognizedListType", 340 },
+ { "UnrecognizedMetric", 341 },
+ { "UnrecognizedModeType", 342 },
+ { "UnrecognizedNoiseType", 343 },
+ { "UnrecognizedOperator", 344 },
+ { "UnrecognizedOption", 345 },
+ { "UnrecognizedPerlMagickMethod", 346 },
+ { "UnrecognizedPixelMap", 347 },
+ { "UnrecognizedPreviewType", 348 },
+ { "UnrecognizedResourceType", 349 },
+ { "UnrecognizedType", 350 },
+ { "UnrecognizedUnitsType", 351 },
+ { "UnrecognizedVirtualPixelMethod", 352 },
+ { "UnsupportedSamplingFactor", 353 },
+ { "UsageError", 354 },
+ { "InvalidColorspaceType", 355 },
+ { "InvalidEndianType", 356 },
+ { "InvalidImageType", 357 },
+ { "InvalidInterlaceType", 358 },
+ { "MissingAnImageFilename", 359 },
+ { "MissingArgument", 360 },
+ { "NoImagesWereLoaded", 361 },
+ { "OptionLengthExceedsLimit", 362 },
+ { "RequestDidNotReturnAnImage", 363 },
+ { "UnableToOpenXServer", 364 },
+ { "UnableToPersistKey", 365 },
+ { "UnrecognizedColormapType", 366 },
+ { "UnrecognizedColorspaceType", 367 },
+ { "UnrecognizedDisposeMethod", 368 },
+ { "UnrecognizedEndianType", 369 },
+ { "UnrecognizedFilterType", 370 },
+ { "UnrecognizedImageCompressionType", 371 },
+ { "UnrecognizedImageType", 372 },
+ { "UnrecognizedInterlaceType", 373 },
+ { "UnrecognizedOption", 374 },
+ { "UnrecognizedResourceType", 375 },
+ { "UnrecognizedVirtualPixelMethod", 376 },
+ { "UnrecognizedColor", 377 },
+ { "ImageExpected", 378 },
+ { "ImageInfoExpected", 379 },
+ { "StructureSizeMismatch", 380 },
+ { "UnableToGetRegistryID", 381 },
+ { "UnableToLocateImage", 382 },
+ { "UnableToSetRegistry", 383 },
+ { "Default", 384 },
+ { "Default", 385 },
+ { "CacheResourcesExhausted", 386 },
+ { "ImagePixelHeightLimitExceeded", 387 },
+ { "ImagePixelLimitExceeded", 388 },
+ { "ImagePixelWidthLimitExceeded", 389 },
+ { "MemoryAllocationFailed", 390 },
+ { "NoPixelsDefinedInCache", 391 },
+ { "PixelCacheAllocationFailed", 392 },
+ { "UnableToAddColorProfile", 393 },
+ { "UnableToAddGenericProfile", 394 },
+ { "UnableToAddIPTCProfile", 395 },
+ { "UnableToAllocateCoefficients", 396 },
+ { "UnableToAllocateColormap", 397 },
+ { "UnableToAllocateICCProfile", 398 },
+ { "UnableToAllocateImage", 399 },
+ { "UnableToAllocateString", 400 },
+ { "UnableToAnnotateImage", 401 },
+ { "UnableToAverageImageSequence", 402 },
+ { "UnableToCloneDrawingWand", 403 },
+ { "UnableToCloneImage", 404 },
+ { "UnableToComputeImageSignature", 405 },
+ { "UnableToConstituteImage", 406 },
+ { "UnableToConvertFont", 407 },
+ { "UnableToConvertStringToTokens", 408 },
+ { "UnableToCreateColormap", 409 },
+ { "UnableToCreateColorTransform", 410 },
+ { "UnableToCreateCommandWidget", 411 },
+ { "UnableToCreateImageGroup", 412 },
+ { "UnableToCreateImageMontage", 413 },
+ { "UnableToCreateXWindow", 414 },
+ { "UnableToCropImage", 415 },
+ { "UnableToDespeckleImage", 416 },
+ { "UnableToDetermineImageClass", 417 },
+ { "UnableToDetermineTheNumberOfImageColors", 418 },
+ { "UnableToDitherImage", 419 },
+ { "UnableToDrawOnImage", 420 },
+ { "UnableToEdgeImage", 421 },
+ { "UnableToEmbossImage", 422 },
+ { "UnableToEnhanceImage", 423 },
+ { "UnableToFloodfillImage", 424 },
+ { "UnableToGammaCorrectImage", 425 },
+ { "UnableToGetBestIconSize", 426 },
+ { "UnableToGetFromRegistry", 427 },
+ { "UnableToGetPackageInfo", 428 },
+ { "UnableToLevelImage", 429 },
+ { "UnableToMagnifyImage", 430 },
+ { "UnableToManageColor", 431 },
+ { "UnableToMapImage", 432 },
+ { "UnableToMapImageSequence", 433 },
+ { "UnableToMedianFilterImage", 434 },
+ { "UnableToMotionBlurImage", 435 },
+ { "UnableToNoiseFilterImage", 436 },
+ { "UnableToNormalizeImage", 437 },
+ { "UnableToOpenColorProfile", 438 },
+ { "UnableToQuantizeImage", 439 },
+ { "UnableToQuantizeImageSequence", 440 },
+ { "UnableToReadTextChunk", 441 },
+ { "UnableToReadXImage", 442 },
+ { "UnableToReadXServerColormap", 443 },
+ { "UnableToResizeImage", 444 },
+ { "UnableToRotateImage", 445 },
+ { "UnableToSampleImage", 446 },
+ { "UnableToScaleImage", 447 },
+ { "UnableToSelectImage", 448 },
+ { "UnableToSharpenImage", 449 },
+ { "UnableToShaveImage", 450 },
+ { "UnableToShearImage", 451 },
+ { "UnableToSortImageColormap", 452 },
+ { "UnableToThresholdImage", 453 },
+ { "UnableToTransformColorspace", 454 },
+ { "MemoryAllocationFailed", 455 },
+ { "SemaporeOperationFailed", 456 },
+ { "UnableToAllocateAscii85Info", 457 },
+ { "UnableToAllocateCacheInfo", 458 },
+ { "UnableToAllocateCacheView", 459 },
+ { "UnableToAllocateColorInfo", 460 },
+ { "UnableToAllocateDashPattern", 461 },
+ { "UnableToAllocateDelegateInfo", 462 },
+ { "UnableToAllocateDerivatives", 463 },
+ { "UnableToAllocateDrawContext", 464 },
+ { "UnableToAllocateDrawInfo", 465 },
+ { "UnableToAllocateDrawingWand", 466 },
+ { "UnableToAllocateGammaMap", 467 },
+ { "UnableToAllocateImage", 468 },
+ { "UnableToAllocateImagePixels", 469 },
+ { "UnableToAllocateLogInfo", 470 },
+ { "UnableToAllocateMagicInfo", 471 },
+ { "UnableToAllocateMagickInfo", 472 },
+ { "UnableToAllocateModuleInfo", 473 },
+ { "UnableToAllocateMontageInfo", 474 },
+ { "UnableToAllocateQuantizeInfo", 475 },
+ { "UnableToAllocateRandomKernel", 476 },
+ { "UnableToAllocateRegistryInfo", 477 },
+ { "UnableToAllocateSemaphoreInfo", 478 },
+ { "UnableToAllocateString", 479 },
+ { "UnableToAllocateTypeInfo", 480 },
+ { "UnableToAllocateWand", 481 },
+ { "UnableToAnimateImageSequence", 482 },
+ { "UnableToCloneBlobInfo", 483 },
+ { "UnableToCloneCacheInfo", 484 },
+ { "UnableToCloneImage", 485 },
+ { "UnableToCloneImageInfo", 486 },
+ { "UnableToConcatenateString", 487 },
+ { "UnableToConvertText", 488 },
+ { "UnableToCreateColormap", 489 },
+ { "UnableToDestroySemaphore", 490 },
+ { "UnableToDisplayImage", 491 },
+ { "UnableToEscapeString", 492 },
+ { "UnableToInitializeSemaphore", 493 },
+ { "UnableToInterpretMSLImage", 494 },
+ { "UnableToLockSemaphore", 495 },
+ { "UnableToObtainRandomEntropy", 496 },
+ { "UnableToUnlockSemaphore", 497 },
+ { "MemoryAllocationFailed", 498 },
+ { "ImageDoesNotContainTheStreamGeometry", 499 },
+ { "NoStreamHandlerIsDefined", 500 },
+ { "PixelCacheIsNotOpen", 501 },
+ { "UnableToAcquirePixelStream", 502 },
+ { "UnableToSetPixelStream", 503 },
+ { "UnableToSyncPixelStream", 504 },
+ { "Default", 505 },
+ { "Default", 506 },
+ { "FontSubstitutionRequired", 507 },
+ { "UnableToGetTypeMetrics", 508 },
+ { "UnableToInitializeFreetypeLibrary", 509 },
+ { "UnableToReadFont", 510 },
+ { "UnrecognizedFontEncoding", 511 },
+ { "Default", 512 },
+ { "Default", 513 },
+ { "InvalidColormapIndex", 514 },
+ { "WandAPINotImplemented", 515 },
+ { "WandContainsNoImageIndexs", 516 },
+ { "WandContainsNoImages", 517 },
+ { "ColorIsNotKnownToServer", 518 },
+ { "NoWindowWithSpecifiedIDExists", 519 },
+ { "StandardColormapIsNotInitialized", 520 },
+ { "UnableToConnectToRemoteDisplay", 521 },
+ { "UnableToCreateBitmap", 522 },
+ { "UnableToCreateColormap", 523 },
+ { "UnableToCreatePixmap", 524 },
+ { "UnableToCreateProperty", 525 },
+ { "UnableToCreateStandardColormap", 526 },
+ { "UnableToDisplayImageInfo", 527 },
+ { "UnableToGetProperty", 528 },
+ { "UnableToGetStandardColormap", 529 },
+ { "UnableToGetVisual", 530 },
+ { "UnableToGrabMouse", 531 },
+ { "UnableToLoadFont", 532 },
+ { "UnableToMatchVisualToStandardColormap", 533 },
+ { "UnableToOpenXServer", 534 },
+ { "UnableToReadXAttributes", 535 },
+ { "UnableToReadXWindowImage", 536 },
+ { "UnrecognizedColormapType", 537 },
+ { "UnrecognizedGravityType", 538 },
+ { "UnrecognizedVisualSpecifier", 539 },
+ { "UnableToAllocateXHints", 540 },
+ { "UnableToCreateCursor", 541 },
+ { "UnableToCreateGraphicContext", 542 },
+ { "UnableToCreateStandardColormap", 543 },
+ { "UnableToCreateTextProperty", 544 },
+ { "UnableToCreateXImage", 545 },
+ { "UnableToCreateXPixmap", 546 },
+ { "UnableToCreateXWindow", 547 },
+ { "UnableToDisplayImage", 548 },
+ { "UnableToDitherImage", 549 },
+ { "UnableToGetPixelInfo", 550 },
+ { "UnableToGetVisual", 551 },
+ { "UnableToLoadFont", 552 },
+ { "UnableToMakeXWindow", 553 },
+ { "UnableToOpenXServer", 554 },
+ { "UnableToViewFonts", 555 },
+ { "UnableToGetVisual", 556 },
+ { "UsingDefaultVisual", 557 },
+ { 0, 0 }
+ };
+#endif
+
+#if defined(_INCLUDE_MESSAGE_TABLE_)
+static const char *message_dat[] =
+ {
+ "%1",
+ "Unable to create blob",
+ "Unable to obtain current offset",
+ "Unable to open file",
+ "Unable to read file",
+ "Unable to read to offset",
+ "Unable to seek to offset",
+ "Unable to write blob",
+ "Unrecognized image format",
+ "default error",
+ "default warning",
+ "Inconsistent persistent cache depth",
+ "Pixel cache is not open",
+ "Unable to allocate cache view",
+ "Unable to clone cache",
+ "Unable to extend cache",
+ "Unable to get cache nexus",
+ "Unable to get pixels from cache",
+ "Unable to open cache",
+ "Unable to persist pixel cache",
+ "Unable to read pixel cache",
+ "Unable to sync cache (check temporary file disk space)",
+ "disk allocation failed",
+ "Unable to extend pixel cache",
+ "default warning",
+ "Colormap size exceeds limit",
+ "Colormap type not supported",
+ "Colorspace model is not supported",
+ "Color type not supported",
+ "Compression not valid",
+ "Data encoding scheme is not supported",
+ "Data storage type is not supported",
+ "Delta-PNG is not supported",
+ "Encrypted WPG image file not supported",
+ "Fractal compression not supported",
+ "Image column or row size is not supported",
+ "Image does not have a matte channel",
+ "Image is not tiles",
+ "Image type not supported",
+ "Incompatible size of double",
+ "Irregular channel geometry not supported",
+ "JNG compression is not supported",
+ "JPEG compression is not supported",
+ "JPEG embedding failed",
+ "Location type is not supported",
+ "Map storage type is not supported",
+ "MSB order not supported bitmap",
+ "Multi-dimensional matrices are not supported",
+ "Multiple record list not supported",
+ "No 8BIM data is available",
+ "No APP1 data is available",
+ "No bitmap on clipboard",
+ "No color profile available",
+ "No data returned",
+ "No image vector graphics",
+ "No IPTC info was found",
+ "No IPTC profile available",
+ "Number of images is not supported",
+ "Only continuous tone picture supported",
+ "Only level zero files Supported",
+ "PNG compression is not supported",
+ "PNG library is too old",
+ "RLE compression not supported",
+ "Subsampling requires that image width be evenly divisible by two",
+ "Unable to copy profile",
+ "Unable to create a DC",
+ "Unable to create bitmap",
+ "Unable to decompress image",
+ "Unable to Initialize FPX library",
+ "Unable to open blob",
+ "Unable to read aspect ratio",
+ "Unable to read CIELAB images",
+ "Unable to read summary info",
+ "Unable to set affine matrix",
+ "Unable to set aspect ratio",
+ "Unable to set color twist",
+ "Unable to set contrast",
+ "Unable to set filtering value",
+ "Unable to set image comment",
+ "Unable to set image title",
+ "Unable to set JPEG level",
+ "Unable to set region of interest",
+ "Unable to set summary info",
+ "Unable to translate text",
+ "Unable to write MPEG parameters",
+ "Unable to write to temporary file",
+ "Unable to zip-compress image",
+ "Unsupported bits per sample",
+ "Unsupported cell type in the matrix",
+ "WebP decoding failed: user abort",
+ "WebP encoding failed: unknown reason",
+ "WebP encoding failed: bad dimension",
+ "WebP encoding failed: bad write",
+ "WebP encoding failed: bitstream out of memory",
+ "WebP encoding failed: File too big (> 4GB)",
+ "WebP encoding failed: invalid configuration",
+ "WebP encoding failed: null parameter",
+ "WebP encoding failed: out of memory",
+ "WebP encoding failed: partition 0 overflow (> 512K)",
+ "WebP encoding failed: partition overflow (> 16M)",
+ "WebP encoding failed: user abort",
+ "Invalid WebP configuration parameters supplied",
+ "WebP failed: invalid parameter",
+ "ZIP compression is not supported",
+ "default error",
+ "Lossless to lossy JPEG conversion",
+ "include element nested too deeply",
+ "Registry key lookup failed. Package is not properly installed on this machine.",
+ "String token maximum length exceeded",
+ "Unable to access configuration file",
+ "Unable to access font file",
+ "Unable to access log configuration file",
+ "Unable to access module file",
+ "default error",
+ "Unable to change to working directory",
+ "Unable to get current working directory",
+ "Unable to restore current working directory",
+ "default warning",
+ "An error has occurred reading from file",
+ "An error has occurred writing to file",
+ "Colormap exceeded colors limit",
+ "Compression not valid",
+ "Corrupt image",
+ "Image file or blob does not contain any image data",
+ "Image type not supported",
+ "Improper image header",
+ "Insufficient image data in file",
+ "Invalid colormap index",
+ "invalid file format version",
+ "Length and filesize do not match",
+ "Missing a required image channel",
+ "Negative or zero image size",
+ "Non OS2 BMP header size less than 40",
+ "Not enough tiles found in level",
+ "Static planes value not equal to 1",
+ "Subsampling requires that image width be evenly divisible by two",
+ "Too much image data in file",
+ "Unable to read colormap from dump file",
+ "Unable to read color profile",
+ "Unable to read extension block",
+ "Unable to read generic profile",
+ "Unable to read image data",
+ "Unable to read image header",
+ "Unable to read IPTC profile",
+ "Unable to read pixmap from dump file",
+ "Unable to read sub image data",
+ "Unable to read VID image",
+ "Unable to read window name from dump file",
+ "Unable to runlength decode image",
+ "Unable to uncompress image",
+ "Unexpected end-of-file",
+ "Unexpected sampling factor",
+ "Unknown pattern type",
+ "Unrecognized bits per pixel",
+ "Unrecognized compression",
+ "Unrecognized number of colors",
+ "Unrecognized XWD header",
+ "Unsupported bits per sample",
+ "Unsupported number of planes",
+ "Unable to persist key",
+ "Compression not valid",
+ "Corrupt image (some data returned)",
+ "Improper image header",
+ "Invalid colormap index",
+ "Length and filesize do not match",
+ "Negative or zero image size",
+ "Non OS2 header size error",
+ "Corrupt PCD image, skipping to sync byte",
+ "Static planes value not equal to one",
+ "Unrecognized bits per pixel",
+ "Unrecognized image compression",
+ "Delegate failed",
+ "Failed to allocate argument list.",
+ "Failed to allocate Ghostscript interpreter.",
+ "Failed to compute output size",
+ "Failed to find Ghostscript (not installed?).",
+ "Failed to render file",
+ "Failed to scan file",
+ "No tag found",
+ "Postscript delegate failed",
+ "Unable to create image",
+ "Unable to create image component",
+ "Unable to decode image file",
+ "Unable to encode image file",
+ "Unable to initialize FPX library",
+ "Unable to initialize WMF library",
+ "Unable to manage JP2 stream",
+ "Unable to write SVG format",
+ "WebP library ABI does not match header ABI (build issue!)",
+ "default error",
+ "default warning",
+ "Already pushing pattern definition",
+ "drawing recursion detected",
+ "text value does not convert to float",
+ "text value does not convert to integer",
+ "invalid primitive argument",
+ "Non-conforming drawing primitive definition",
+ "primitive arithmetic overflow",
+ "too many coordinates",
+ "Unable to print",
+ "unbalanced graphic context push-pop",
+ "unreasonable gradient image size",
+ "vector path truncated",
+ "default error",
+ "Not a relative URL",
+ "Not currently pushing pattern definition",
+ "URL not found",
+ "Unable to create temporary file",
+ "Unable to open file",
+ "Unable to write file",
+ "default error",
+ "default warning",
+ "angle is discontinuous",
+ "Colorspace color profile mismatch",
+ "image colorspace differs",
+ "image colorspace mismatch",
+ "image difference exceeds limit (%s)",
+ "image does not contain resolution",
+ "image opacity differs",
+ "Image sequence is required",
+ "image size differs",
+ "Invalid colormap index",
+ "left and right image sizes differ",
+ "no images were found",
+ "no images were loaded",
+ "no [LOCALE] image attribute",
+ "too many cluster",
+ "unable to append image",
+ "Unable to assign profile",
+ "unable to average image",
+ "unable to coalesce image",
+ "unable to compare images",
+ "unable to create image mosaic",
+ "unable to create stereo image",
+ "unable to deconstruct image sequence",
+ "unable to flatten image",
+ "Unable to get clip mask",
+ "unable to handle image channel",
+ "unable to resize image",
+ "unable to segment image",
+ "Unable to set clip mask",
+ "unable to shear image",
+ "width or height exceeds limit",
+ "Unable to persist key",
+ "default warning",
+ "DPS library is not available",
+ "FPX library is not available",
+ "FreeType library is not available",
+ "JPEG compression library is not available",
+ "LCMS encoding not enabled",
+ "LZW encoding not enabled",
+ "No decode delegate for this image format",
+ "No encode delegate for this image format",
+ "TIFF library is not available",
+ "XML library is not available",
+ "X Window library is not available",
+ "ZLIB compression library is not available",
+ "default error",
+ "default warning",
+ "Failed to close module",
+ "Failed to find symbol",
+ "Unable to load module",
+ "Unable to register image format",
+ "Unrecognized module",
+ "Unable to initialize module loader",
+ "default warning",
+ "default error",
+ "default error",
+ "User requested termination (via signal)",
+ "default warning",
+ "bevel width is negative",
+ "color separated image required",
+ "frame is less than image size",
+ "geometry dimensions are zero",
+ "geometry does not contain image",
+ "hald clut image dimensions are invalid",
+ "images are not the same size",
+ "size must exceed bevel width",
+ "image smaller than kernel width",
+ "image smaller than radius",
+ "image widths or heights differ",
+ "input images already specified",
+ "Invalid subimage specification",
+ "kernel radius is too small",
+ "kernel width must be an odd number",
+ "Matrix is not square (%s elements)",
+ "Matrix size is out of range",
+ "Missing an image filename",
+ "Option '%s' requires an argument or argument is malformed",
+ "Must specify a image name",
+ "Must specify image size",
+ "No Binary Large OBjects defined",
+ "No images defined",
+ "Non-zero width and height required",
+ "No profile name was given",
+ "Null blob argument",
+ "Reference image required",
+ "Reference is not my type",
+ "Region area exceeds implementation limit",
+ "Request did not return an image",
+ "Stegano image required",
+ "Stereo image required",
+ "Subimage specification returns no images",
+ "Unable to add or remove profile",
+ "unable to average image sequence",
+ "unable to blur image",
+ "unable to chop image",
+ "Unable to color matrix image",
+ "Unable to constitute image",
+ "Unable to convolve image",
+ "Unable to edge image",
+ "Unable to equalize image",
+ "Unable to filter image",
+ "unable to format image meta data",
+ "Unable to frame image",
+ "unable to oil paint image",
+ "Unable to paint image",
+ "Unable to raise image",
+ "Unable to sharpen image",
+ "Unable to threshold image",
+ "Unable to wave image",
+ "Unrecognized attribute",
+ "Unrecognized channel type",
+ "Unrecognized color",
+ "Unrecognized colormap type",
+ "Unrecognized image colorspace",
+ "Unrecognized command '%s'. Use -help for a usage summary or see manual.",
+ "Unrecognized compose operator",
+ "Unrecognized dispose method",
+ "Unrecognized element",
+ "Unrecognized endian type",
+ "Unrecognized gravity type",
+ "Unrecognized highlight style",
+ "Unrecognized image compression",
+ "Unrecognized image filter",
+ "Unrecognized image format",
+ "Unrecognized image mode",
+ "Unrecognized image type",
+ "Unrecognized intent type",
+ "Unrecognized interlace type",
+ "Unrecognized list type",
+ "Unrecognized error metric",
+ "Unrecognized mode type",
+ "Unrecognized noise type",
+ "Unrecognized operator",
+ "Unrecognized option",
+ "Unrecognized PerlMagick method",
+ "Unrecognized pixel map",
+ "Unrecognized preview type",
+ "Unrecognized resource type",
+ "Unrecognized type",
+ "Unrecognized units type",
+ "Unrecognized virtual pixel method",
+ "Unsupported sampling factor",
+ "Improper arguments supplied, please see manual",
+ "Invalid colorspace type",
+ "Invalid endian type",
+ "Invalid image type",
+ "Invalid interlace type",
+ "Missing an image filename",
+ "Option '%s' requires an argument or argument is malformed",
+ "No images were loaded",
+ "Option length exceeds limit",
+ "Request did not return an image",
+ "Unable to open XServer",
+ "Unable to persist key",
+ "Unrecognized colormap type",
+ "Unrecognized colorspace type",
+ "unrecognized dispose method",
+ "Unrecognized endian type",
+ "Unrecognized filter type",
+ "unrecognized compression type",
+ "Unrecognized image type",
+ "Unrecognized interlace type",
+ "Unrecognized option",
+ "Unrecognized resource type",
+ "Unrecognized virtual pixel method",
+ "Unrecognized color",
+ "image expected",
+ "image info expected",
+ "structure size mismatch",
+ "Unable to get registry ID",
+ "Unable to locate image",
+ "Unable to set registry",
+ "default error",
+ "default warning",
+ "Disk space limit exceeded (see -limit Disk)",
+ "Image pixel height limit exceeded (see -limit Height)",
+ "Image pixel limit exceeded (see -limit Pixels)",
+ "Image pixel width limit exceeded (see -limit Width)",
+ "Memory allocation failed",
+ "No pixels defined in cache",
+ "Pixel cache allocation failed",
+ "unable to add ICC Color profile",
+ "unable to add generic profile",
+ "unable to add IPTC profile",
+ "unable to allocate coefficients",
+ "Unable to allocate colormap",
+ "unable to allocate ICC profile",
+ "Unable to allocate image",
+ "unable to allocate string",
+ "Unable to annotate image",
+ "unable to average image sequence",
+ "unable to clone drawing wand",
+ "unable to clone image",
+ "unable to compute image signature",
+ "unable to constitute image",
+ "unable to convert font",
+ "unable to convert strings to tokens",
+ "Unable to create colormap",
+ "unable to create color transform",
+ "unable to create command widget",
+ "unable to create image group",
+ "Unable to create image montage",
+ "unable to create X window",
+ "unable to crop image",
+ "unable to despeckle image",
+ "unable to determine image class",
+ "unable to determine the number of image colors",
+ "unable to dither image",
+ "unable to draw on image",
+ "unable to edge image",
+ "unable to emboss image",
+ "unable to enhance image",
+ "unable to floodfill image",
+ "unable to gamma correct image",
+ "unable to get best icon size",
+ "unable to get from registry",
+ "Unable to get package info",
+ "unable to level image",
+ "unable to magnify image",
+ "Unable to manage color",
+ "Unable to map image",
+ "Unable to map image sequence",
+ "unable to median filter image",
+ "unable to motion blur image",
+ "unable to noise filter image",
+ "unable to normalize image",
+ "unable to open color profile",
+ "unable to quantize image",
+ "unable to quantize image sequence",
+ "unable to read text chunk",
+ "unable to read X image",
+ "unable to read X server colormap",
+ "unable to resize image",
+ "unable to rotate image",
+ "unable to sample image",
+ "unable to scale image",
+ "unable to select image",
+ "unable to sharpen image",
+ "unable to shave image",
+ "unable to shear image",
+ "unable to sort image colormap",
+ "unable to threshold image",
+ "unable to transform colorspace",
+ "Memory allocation failed",
+ "Semaphore operation failed",
+ "unable to allocate ascii85 info",
+ "unable to allocate cache info",
+ "unable to allocate cache view",
+ "unable to allocate color info",
+ "unable to allocate dash pattern",
+ "unable to allocate delegate info",
+ "unable to allocate derivates",
+ "unable to allocate draw context",
+ "unable to allocate draw info",
+ "unable to allocate drawing wand",
+ "unable to allocate gamma map",
+ "unable to allocate image",
+ "unable to allocate image pixels",
+ "unable to allocate log info",
+ "unable to allocate magic info",
+ "unable to allocate magick info",
+ "unable to allocate module info",
+ "unable to allocate montage info",
+ "unable to allocate quantize info",
+ "unable to allocate random kernel",
+ "unable to allocate registry info",
+ "unable to allocate semaphore info",
+ "unable to allocate string",
+ "unable to allocate type info",
+ "unable to allocate wand",
+ "unable to animate image sequence",
+ "unable to clone blob info",
+ "unable to clone cache info",
+ "unable to clone image",
+ "unable to clone image info",
+ "unable to concatenate string",
+ "unable to convert text",
+ "unable to create colormap",
+ "unable to destroy semaphore",
+ "unable to display image",
+ "unable to escape string",
+ "unable to initialize semaphore",
+ "unable to interpret MSL image",
+ "unable to lock semaphore",
+ "unable to obtain random bytes from operating system",
+ "unable to unlock semaphore",
+ "Memory allocation failed",
+ "image does not contain the stream geometry",
+ "no stream handler is defined",
+ "Pixel cache is not open",
+ "Unable to acquire pixel stream",
+ "Unable to set pixel stream",
+ "Unable to sync pixel stream",
+ "default error",
+ "default warning",
+ "Font substitution required",
+ "Unable to get type metrics",
+ "Unable to initialize freetype library",
+ "Unable to read font",
+ "Unrecognized font encoding",
+ "default error",
+ "default warning",
+ "invalid colormap index `%.1024s",
+ "Wand API not implemented `%.1024s",
+ "Wand contains no image indices `%.1024s",
+ "Wand contains no images `%.1024s",
+ "Color is not known to server",
+ "No window with specified ID exists",
+ "Standard Colormap is not initialized",
+ "Unable to connect to remote display",
+ "Unable to create bitmap",
+ "Unable to create colormap",
+ "Unable to create pixmap",
+ "Unable to create property",
+ "Unable to create standard colormap",
+ "Unable to display image info",
+ "Unable to get property",
+ "Unable to get Standard Colormap",
+ "Unable to get visual",
+ "Unable to grab mouse",
+ "Unable to load font",
+ "Unable to match visual to Standard Colormap",
+ "Unable to open X server",
+ "Unable to read X attributes",
+ "Unable to read X window image",
+ "Unrecognized colormap type",
+ "Unrecognized gravity type",
+ "Unrecognized visual specifier",
+ "Unable to allocate X hints",
+ "Unable to create X cursor",
+ "Unable to create graphic context",
+ "unable to create standard colormap",
+ "Unable to create text property",
+ "Unable to create X image",
+ "Unable to create X pixmap",
+ "Unable to create X window",
+ "unable to display image",
+ "unable to dither image",
+ "Unable to get pixel info",
+ "Unable to get visual",
+ "Unable to load font",
+ "Unable to make X window",
+ "Unable to open X server",
+ "Unable to view fonts",
+ "Unable to get visual",
+ "UsingDefaultVisual",
+ 0
+ };
+#endif
diff --git a/magick/log.c b/magick/log.c
new file mode 100644
index 0000000..c50d924
--- /dev/null
+++ b/magick/log.c
@@ -0,0 +1,1243 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L OOO GGGG %
+% L O O G %
+% L O O G GG %
+% L O O G G %
+% LLLLL OOO GGG %
+% %
+% %
+% Log GraphicsMagick Events %
+% %
+% %
+% Software Design %
+% John Cristy %
+% September 2002 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+# include "magick/nt_feature.h"
+#endif
+#include "magick/blob.h"
+#include "magick/log.h"
+#include "magick/semaphore.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+
+/*
+ Define declarations.
+*/
+#define MagickLogFilename "log.mgk"
+
+/*
+ Typedef declarations.
+*/
+typedef enum
+{
+ DisabledOutput = 0x0000,
+ UndefinedOutput = 0x0000,
+ StdoutOutput = 0x0001,
+ StderrOutput = 0x0002,
+ XMLFileOutput = 0x0004,
+ TXTFileOutput = 0x0008,
+ Win32DebugOutput = 0x0010,
+ Win32EventlogOutput = 0x0020,
+ MethodOutput = 0x0040
+} LogOutputType;
+
+typedef struct _OutputInfo
+{
+ const char *name;
+ LogOutputType mask;
+} OutputInfo;
+
+typedef struct _LogInfo
+{
+ FILE
+ *file;
+
+ TimerInfo
+ timer;
+
+ unsigned long
+ generations,
+ limit,
+ generation,
+ count;
+
+ LogEventType
+ events;
+
+ LogOutputType
+ output_type;
+
+ LogMethod
+ method; /* Logger callback function */
+
+ char
+ path[256],
+ filename[256],
+ format[200];
+
+} LogInfo;
+
+typedef struct _EventInfo
+{
+ const char *name;
+ LogEventType mask;
+ int start_type;
+ int end_type;
+} EventInfo;
+
+/*
+ This table maps between masks and the various event id's that can occur
+ This following id's are not represented in this table yet, since each of
+ them would require a bit in the bitmask and none of these are actually
+ used in the code at this point.
+
+ DelegateBase
+ MissingDelegateBase
+ CorruptImageBase
+ FileOpenBase
+ StreamBase
+ ModuleBase
+ ImageBase
+ MonitorBase
+ RegistryBase
+
+ */
+static const EventInfo eventmask_map[] =
+ {
+ { "none", NoEventsMask, 0, 0 },
+ { "information", InformationEventMask, EventException, EventException+99 },
+ { "warning", WarningEventMask, WarningException, WarningException+99 },
+ { "error", ErrorEventMask, ErrorException, ErrorException+99 },
+ { "fatalerror", FatalErrorEventMask, FatalErrorException, FatalErrorException+99 },
+ { "configure", ConfigureEventMask, ConfigureBase, ConfigureBase },
+ { "annotate", AnnotateEventMask, AnnotateBase, AnnotateBase },
+ { "render", RenderEventMask, RenderBase, RenderBase },
+ { "transform", TransformEventMask, TransformBase, TransformBase },
+ { "locale", LocaleEventMask, LocaleBase, LocaleBase },
+ { "coder", CoderEventMask, CoderBase, CoderBase },
+ { "x11", X11EventMask, X11Base, UserBase },
+ { "cache", CacheEventMask, CacheBase, CacheBase },
+ { "blob", BlobEventMask, BlobBase, BlobBase },
+ { "deprecate", DeprecateEventMask, DeprecateBase, DeprecateBase },
+ { "user", UserEventMask, UserBase, UserBase },
+ { "resource", ResourceEventMask, ResourceBase, ResourceBase },
+ { "temporaryfile", TemporaryFileEventMask, TemporaryFileBase, TemporaryFileBase },
+ /* this one is actually not used anymore */
+ { "exception", ExceptionEventMask, ExceptionBase, ExceptionBase },
+ { "option", OptionEventMask, OptionBase, OptionBase },
+ { "all", AllEventsMask, 0, 0 },
+ { 0, NoEventsMask, 0, 0 }
+ };
+
+static const OutputInfo output_map[] =
+ {
+ { "none", UndefinedOutput },
+ { "disabled", DisabledOutput },
+ { "stdout", StdoutOutput },
+ { "stderr", StderrOutput },
+ { "xmlfile", XMLFileOutput },
+ { "txtfile", TXTFileOutput },
+ { "win32debug", Win32DebugOutput },
+ { "win32eventlog", Win32EventlogOutput },
+ { 0, UndefinedOutput }
+ };
+
+/*
+ Static declarations.
+*/
+static volatile unsigned int
+ log_configured = False;
+
+static LogInfo
+ log_info;
+
+static SemaphoreInfo
+ *log_semaphore = (SemaphoreInfo *) NULL;
+
+/*
+ Forward declarations.
+*/
+static MagickPassFail
+ ReadLogConfigureFile(const char *,const unsigned int,ExceptionInfo *);
+
+/*
+ Parse an event specification string and return the equivalent bits.
+*/
+static LogEventType ParseEvents(const char *event_string)
+{
+ const char
+ *p;
+
+ unsigned int
+ i;
+
+ LogEventType
+ events=NoEventsMask;
+
+ for (p=event_string; p != 0; p=strchr(p,','))
+ {
+ while ((*p != 0) && (isspace((int)(*p)) || *p == ','))
+ p++;
+
+ for (i=0; eventmask_map[i].name != 0; i++)
+ {
+ if (LocaleNCompare(p,eventmask_map[i].name,
+ strlen(eventmask_map[i].name)) == 0)
+ {
+ events = (LogEventType) ((unsigned int) events |
+ (unsigned int) eventmask_map[i].mask);
+ break;
+ }
+ }
+ }
+
+ return events;
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y L o g I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyLogInfo deallocates memory associated with the log list.
+%
+% The format of the DestroyLogInfo method is:
+%
+% DestroyLogInfo(void)
+%
+%
+*/
+MagickExport void DestroyLogInfo(void)
+{
+
+ LockSemaphoreInfo(log_semaphore);
+
+ if (log_info.file != (FILE *) NULL)
+ if ((log_info.file != stdout) && (log_info.file != stderr))
+ {
+ (void) fprintf(log_info.file,"</log>\n");
+ (void) fclose(log_info.file);
+ log_info.file=(FILE *) NULL;
+ }
+ log_configured=False;
+
+ UnlockSemaphoreInfo(log_semaphore);
+
+ DestroySemaphoreInfo(&log_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e L o g I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeLogInfo initializes the logging facility. This function
+% is invoked by InitializeMagick(), which must be invoked before using any
+% other APIs. A memory-allocation failure in this function results in a
+% fatal error for the whole program. All of the allocations performed by
+% this function are released by DestroyLogInfo().
+%
+% The format of the InitializeLogInfo method is:
+%
+% MagickPassFail InitializeLogInfo(void)
+%
+%
+*/
+MagickPassFail
+InitializeLogInfo(void)
+{
+ const char
+ *p;
+
+ /*
+ Initialize logging semaphore
+ */
+ assert(log_semaphore == (SemaphoreInfo *) NULL);
+ log_semaphore=AllocateSemaphoreInfo();
+
+ /*
+ Initialize LogInfo
+ */
+ (void) memset(&log_info,0,sizeof(LogInfo));
+
+ /*
+ Lock for access (to make Coverity happy)
+ */
+#if defined(__COVERITY__)
+ LockSemaphoreInfo(log_semaphore);
+#endif /* defined(__COVERITY__) */
+
+ (void) strlcpy(log_info.path,"(default)",sizeof(log_info.path));
+ (void) strlcpy(log_info.filename,"Magick-%d.log",sizeof(log_info.filename));
+ log_info.generations=3;
+ log_info.limit=2000;
+ (void) strlcpy(log_info.format,"%t %r %u %p %m/%f/%l/%d:\n %e",
+ sizeof(log_info.format));
+ log_info.file=(FILE *) NULL;
+ log_info.generation=0;
+ log_info.count=0;
+ log_info.events=NoEventsMask;
+#if defined(MSWINDOWS)
+ log_info.output_type=Win32EventlogOutput;
+#else
+ log_info.output_type=StderrOutput;
+#endif
+ GetTimerInfo(&log_info.timer);
+
+#if defined(__COVERITY__)
+ UnlockSemaphoreInfo(log_semaphore);
+#endif /* defined(__COVERITY__) */
+
+ /*
+ Set initial logging flags using the value of MAGICK_DEBUG if it is
+ set in the environment. We do this here so it is possible to
+ debug the loading of the log configuration file.
+ */
+ if ((p=getenv("MAGICK_DEBUG")) != (const char *) NULL)
+ (void) SetLogEventMask(p);
+
+#if UseInstalledMagick
+ /*
+ Try to read the log configuration file.
+ */
+ {
+ ExceptionInfo
+ exception;
+
+ GetExceptionInfo(&exception);
+ (void) ReadLogConfigureFile(MagickLogFilename,0,&exception);
+ DestroyExceptionInfo(&exception);
+ }
+
+ /*
+ Set override logging flags using the value of MAGICK_DEBUG if it
+ is set in the environment.
+ */
+ if ((p=getenv("MAGICK_DEBUG")) != (const char *) NULL)
+ (void) SetLogEventMask(p);
+#endif /* UseInstalledMagick */
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e L o g I n f o P o s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeLogInfoPost finishes initialization of the logging
+% facility after the installation path is known. This function
+% is invoked by InitializeMagick(), which must be invoked before using any
+% other APIs. All of the allocations performed by this function are
+% released by DestroyLogInfo().
+%
+% The format of the InitializeLogInfoPost method is:
+%
+% MagickPassFail InitializeLogInfoPost(void)
+%
+%
+*/
+MagickPassFail
+InitializeLogInfoPost(void)
+{
+ const char
+ *p;
+
+ /*
+ Try to read the log configuration file.
+ */
+ if (!log_configured)
+ {
+ ExceptionInfo
+ exception;
+
+ GetExceptionInfo(&exception);
+ (void) ReadLogConfigureFile(MagickLogFilename,0,&exception);
+ DestroyExceptionInfo(&exception);
+
+ /*
+ Set override logging flags using the value of MAGICK_DEBUG if it
+ is set in the environment.
+ */
+ if ((p=getenv("MAGICK_DEBUG")) != (const char *) NULL)
+ (void) SetLogEventMask(p);
+ }
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s E v e n t L o g g i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsEventLogging() returns True if logging of events is enabled otherwise
+% False.
+%
+% The format of the IsEventLogging method is:
+%
+% unsigned int IsEventLogging(void)
+%
+%
+*/
+MagickExport MagickBool IsEventLogging(void)
+{
+ return (log_info.events != NoEventsMask);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L o g M a g i c k E v e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% LogMagickEvent() logs an event as determined by the log configuration file.
+% If an error occurs, False is returned otherwise True.
+%
+% The format of the LogMagickEvent method is:
+%
+% unsigned int LogMagickEvent(const LogEventType type,const char *module,
+% const char *function,const unsigned long line,const char *format,...)
+%
+% A description of each parameter follows:
+%
+% o type: The event type.
+%
+% o filename: The source module filename.
+%
+% o function: The function name.
+%
+% o line: The line number of the source module.
+%
+% o format: The output format.
+%
+%
+*/
+MagickExport unsigned int LogMagickEventList(const ExceptionType type,
+ const char *module,const char *function,const unsigned long line,
+ const char *format,va_list operands)
+{
+ char
+ *domain,
+ *severity,
+#if defined(MSWINDOWS)
+ nteventtype,
+#endif
+ event[MaxTextExtent],
+ srcname[MaxTextExtent],
+ timestamp[MaxTextExtent];
+
+ double
+ elapsed_time,
+ user_time;
+
+ register const char
+ *p;
+
+ struct tm
+ *time_meridian;
+
+ time_t
+ seconds;
+
+ if (!IsEventLogging())
+ return(False);
+
+ if (log_info.events != AllEventsMask)
+ {
+ unsigned int
+ i;
+
+ unsigned int
+ enabled;
+
+ /* first translate the base type of the event to a mask */
+ enabled=False;
+ for (i=0; eventmask_map[i].name != 0; i++)
+ {
+ /* if the range in the table is above 100 it represents raw
+ event id's. These entry types are to look for specific
+ severity codes.
+ */
+ if (eventmask_map[i].start_type > 99)
+ {
+ if (((int) type >= eventmask_map[i].start_type) &&
+ ((int) type <= eventmask_map[i].end_type))
+ {
+ if (((unsigned int) log_info.events) &
+ ((unsigned int) eventmask_map[i].mask))
+ {
+ enabled=True;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* these ranges are for id's with the severity stripped
+ off and represent a category instead.
+ */
+ if ((((int) type % 100) >= eventmask_map[i].start_type) &&
+ (((int) type % 100) <= eventmask_map[i].end_type))
+ {
+ if (((unsigned int) log_info.events) &
+ ((unsigned int) eventmask_map[i].mask))
+ {
+ enabled=True;
+ break;
+ }
+ }
+ }
+ }
+ if (!enabled)
+ return(True);
+ }
+
+ /* fixup module info to just include the filename - and not the
+ whole path to the file. This makes the log huge for no good
+ reason */
+ GetPathComponent(module,TailPath,srcname);
+
+ LockSemaphoreInfo(log_semaphore);
+ switch (((unsigned int) type) % 100)
+ {
+ case UndefinedException: domain=(char *) "Undefined"; break;
+ case ExceptionBase: domain=(char *) "Exception"; break;
+ case ResourceBase: domain=(char *) "Resource"; break;
+ /* case ResourceLimitBase: domain=(char *) "ResourceLimit"; break; */
+ case TypeBase: domain=(char *) "Type"; break;
+ /* case AnnotateBase: domain=(char *) "Annotate"; break; */
+ case OptionBase: domain=(char *) "Option"; break;
+ case DelegateBase: domain=(char *) "Delegate"; break;
+ case MissingDelegateBase: domain=(char *) "MissingDelegate"; break;
+ case CorruptImageBase: domain=(char *) "CorruptImage"; break;
+ case FileOpenBase: domain=(char *) "FileOpen"; break;
+ case BlobBase: domain=(char *) "Blob"; break;
+ case StreamBase: domain=(char *) "Stream"; break;
+ case CacheBase: domain=(char *) "Cache"; break;
+ case CoderBase: domain=(char *) "Coder"; break;
+ case ModuleBase: domain=(char *) "Module"; break;
+ case DrawBase: domain=(char *) "Draw"; break;
+ /* case RenderBase: domain=(char *) "Render"; break; */
+ case ImageBase: domain=(char *) "image"; break;
+ case TemporaryFileBase: domain=(char *) "TemporaryFile"; break;
+ case TransformBase: domain=(char *) "Transform"; break;
+ case XServerBase: domain=(char *) "XServer"; break;
+ case X11Base: domain=(char *) "X11"; break;
+ case UserBase: domain=(char *) "User"; break;
+ case MonitorBase: domain=(char *) "Monitor"; break;
+ case LocaleBase: domain=(char *) "Locale"; break;
+ case DeprecateBase: domain=(char *) "Deprecate"; break;
+ case RegistryBase: domain=(char *) "Registry"; break;
+ case ConfigureBase: domain=(char *) "Configure"; break;
+ default: domain=(char *) "UnknownEvent"; break;
+ }
+ switch ((((unsigned int) type) / 100) * 100)
+ {
+ case EventException: severity=(char *) "Event"; break;
+ case WarningException: severity=(char *) "Warning"; break;
+ case ErrorException: severity=(char *) "Error"; break;
+ case FatalErrorException: severity=(char *) "FatalError"; break;
+ default: severity=(char *) "Unknown"; break;
+ }
+#if defined(MSWINDOWS)
+ switch ((type / 100) * 100)
+ {
+ case EventException: nteventtype=EVENTLOG_INFORMATION_TYPE; break;
+ case WarningException: nteventtype=EVENTLOG_WARNING_TYPE; break;
+ case ErrorException: nteventtype=EVENTLOG_ERROR_TYPE; break;
+ case FatalErrorException: nteventtype=EVENTLOG_ERROR_TYPE; break;
+ default: nteventtype=EVENTLOG_INFORMATION_TYPE; break;
+ }
+#endif
+#if defined(HAVE_VSNPRINTF)
+ (void) vsnprintf(event,MaxTextExtent,format,operands);
+#else
+# if defined(HAVE_VSPRINTF)
+ (void) vsprintf(event,format,operands);
+# else
+# error Neither vsnprintf or vsprintf is available.
+# endif
+#endif
+ seconds=time((time_t *) NULL);
+ time_meridian=localtime(&seconds);
+ elapsed_time=GetElapsedTime(&log_info.timer);
+ user_time=GetUserTime(&log_info.timer);
+ (void) ContinueTimer((TimerInfo *) &log_info.timer);
+ FormatString(timestamp,"%04d%02d%02d%02d%02d%02d",time_meridian->tm_year+
+ 1900,time_meridian->tm_mon+1,time_meridian->tm_mday,
+ time_meridian->tm_hour,time_meridian->tm_min,time_meridian->tm_sec);
+ if (((unsigned int) log_info.output_type) & XMLFileOutput)
+ {
+ /*
+ Log to a file in the XML format.
+ */
+ log_info.count++;
+ if (log_info.count >= log_info.limit)
+ {
+ (void) fprintf(log_info.file,"</log>\n");
+ (void) fclose(log_info.file);
+ log_info.file=(FILE *) NULL;
+ log_info.count=0;
+ }
+ if (log_info.file == (FILE *) NULL)
+ {
+ char
+ filename[MaxTextExtent];
+
+ (void) MagickSceneFileName(filename,log_info.filename,".%lu",
+ MagickFalse,log_info.generation);
+ log_info.file=fopen(filename,"w");
+ if (log_info.file == (FILE *) NULL)
+ {
+ UnlockSemaphoreInfo(log_semaphore);
+ return(False);
+ }
+ (void) fprintf(log_info.file,"<?xml version=\"1.0\"?>\n");
+ (void) fprintf(log_info.file,"<log>\n");
+ log_info.generation++;
+ if (log_info.generation >= log_info.generations)
+ log_info.generation=0;
+ }
+ (void) fprintf(log_info.file,"<record>\n");
+ (void) fprintf(log_info.file," <timestamp>%.1024s</timestamp>\n",
+ timestamp);
+ (void) fprintf(log_info.file,
+ " <elapsed-time>%ld:%02ld</elapsed-time>\n",
+ (long) (elapsed_time/60.0),(long) ceil(fmod(elapsed_time,60.0)));
+ (void) fprintf(log_info.file," <user-time>%0.3f</user-time>\n",
+ user_time);
+ (void) fprintf(log_info.file," <pid>%ld</pid>\n",(long) getpid());
+ (void) fprintf(log_info.file," <module>%.1024s</module>\n",srcname);
+ (void) fprintf(log_info.file," <function>%.1024s</function>\n",
+ function);
+ (void) fprintf(log_info.file," <line>%lu</line>\n",line);
+ (void) fprintf(log_info.file," <domain>%.1024s</domain>\n",domain);
+ (void) fprintf(log_info.file," <severity>%.1024s</severity>\n",severity);
+ (void) fprintf(log_info.file," <event>%.1024s</event>\n",event);
+ (void) fprintf(log_info.file,"</record>\n");
+ (void) fflush(log_info.file);
+ UnlockSemaphoreInfo(log_semaphore);
+ return(True);
+ }
+ if (((unsigned int) log_info.output_type) & TXTFileOutput)
+ {
+ /*
+ Log to a file in the TXT format.
+ */
+ log_info.count++;
+ if (log_info.count >= log_info.limit)
+ {
+ (void) fclose(log_info.file);
+ log_info.file=(FILE *) NULL;
+ log_info.count=0;
+ }
+ if (log_info.file == (FILE *) NULL)
+ {
+ char
+ filename[MaxTextExtent];
+
+ (void) MagickSceneFileName(filename,log_info.filename,".%lu",
+ MagickFalse,log_info.generation);
+ log_info.file=fopen(filename,"w");
+ if (log_info.file == (FILE *) NULL)
+ {
+ UnlockSemaphoreInfo(log_semaphore);
+ return(False);
+ }
+ log_info.generation++;
+ if (log_info.generation >= log_info.generations)
+ log_info.generation=0;
+ }
+ (void) fprintf(log_info.file,
+ "%.1024s %ld:%02ld %0.3f %ld %.1024s %.1024s %lu"
+ " %.1024s %.1024s %.1024s\n",
+ timestamp, (long) (elapsed_time/60.0),
+ (long) ceil(fmod(elapsed_time,60.0)),
+ user_time, (long) getpid(), srcname, function, line, domain,
+ severity, event);
+ (void) fflush(log_info.file);
+ UnlockSemaphoreInfo(log_semaphore);
+ return(True);
+ }
+#if defined(MSWINDOWS)
+ if (log_info.output_type & Win32DebugOutput)
+ {
+ char
+ buffer[MaxTextExtent];
+
+ FormatString(buffer,
+ "%.1024s %ld:%02ld %0.3f %ld %.1024s %.1024s %lu %.1024s"
+ " %.1024s %.1024s\n",
+ timestamp, (long) (elapsed_time/60.0),
+ (long) ceil(fmod(elapsed_time,60.0)),
+ user_time, (long) getpid(), srcname, function, line,
+ domain, severity, event);
+ OutputDebugString(buffer);
+ }
+ if (log_info.output_type & Win32EventlogOutput)
+ {
+#define LOGGING_ERROR_CODE 0
+ char
+ buffer[MaxTextExtent];
+
+ LPCSTR
+ szList[1];
+
+ HANDLE
+ hSource;
+
+ FormatString(buffer,
+ "%.1024s %ld:%02ld %0.3f %ld %.1024s %.1024s %lu %.1024s"
+ " %.1024s %.1024s\n",
+ timestamp, (long) (elapsed_time/60.0),
+ (long) ceil(fmod(elapsed_time,60.0)),
+ user_time, (long) getpid(), srcname, function, line,
+ domain, severity, event);
+ hSource = RegisterEventSource(NULL, MagickPackageName);
+ if (hSource != NULL)
+ {
+ szList[0]=buffer;
+ ReportEvent(hSource,nteventtype,0,LOGGING_ERROR_CODE,NULL,1,0,szList,NULL);
+ DeregisterEventSource(hSource);
+ }
+ }
+#endif
+ if ((((unsigned int) log_info.output_type) & StdoutOutput) ||
+ (((unsigned int) log_info.output_type) & StderrOutput))
+ {
+ FILE
+ *file;
+ /*
+ Log to stdout in a "human readable" format.
+ */
+ file = stdout;
+ if (((unsigned int) log_info.output_type) & StderrOutput)
+ file = stderr;
+ for (p=log_info.format; *p != '\0'; p++)
+ {
+ /*
+ Process formatting characters in text.
+ */
+ if ((*p == '\\') && (*(p+1) == 'r'))
+ {
+ (void) fprintf(file,"\r");
+ p++;
+ continue;
+ }
+ if ((*p == '\\') && (*(p+1) == 'n'))
+ {
+ (void) fprintf(file,"\n");
+ p++;
+ continue;
+ }
+ if (*p != '%')
+ {
+ (void) fprintf(file,"%c",*p);
+ continue;
+ }
+ p++;
+ switch (*p)
+ {
+ case 'd':
+ {
+ (void) fprintf(file,"%.1024s",domain);
+ break;
+ }
+ case 'e':
+ {
+ (void) fprintf(file,"%.1024s",event);
+ break;
+ }
+ case 'f':
+ {
+ (void) fprintf(file,"%.1024s",function);
+ break;
+ }
+ case 'l':
+ {
+ (void) fprintf(file,"%lu",line);
+ break;
+ }
+ case 'm':
+ {
+ register const char
+ *lp;
+
+ for (lp=srcname+strlen(srcname)-1; lp > srcname; lp--)
+ if (*lp == *DirectorySeparator)
+ {
+ lp++;
+ break;
+ }
+ (void) fprintf(file,"%.1024s",lp);
+ break;
+ }
+ case 'p':
+ {
+ (void) fprintf(file,"%ld",(long) getpid());
+ break;
+ }
+ case 'r':
+ {
+ (void) fprintf(file,"%ld:%02ld",(long) (elapsed_time/60.0),
+ (long) ceil(fmod(elapsed_time,60.0)));
+ break;
+ }
+ case 's':
+ {
+ (void) fprintf(file,"%.1024s",severity);
+ break;
+ }
+ case 't':
+ {
+ (void) fprintf(file,"%02d:%02d:%02d",time_meridian->tm_hour,
+ time_meridian->tm_min,time_meridian->tm_sec);
+ break;
+ }
+ case 'u':
+ {
+ (void) fprintf(file,"%0.3fu",user_time);
+ break;
+ }
+ default:
+ {
+ (void) fprintf(file,"%%");
+ (void) fprintf(file,"%c",*p);
+ break;
+ }
+ }
+ }
+ (void) fprintf(file,"\n");
+ (void) fflush(file);
+ }
+ if ((log_info.output_type & MethodOutput) &&
+ (log_info.method != (LogMethod) NULL))
+ {
+ char
+ buffer[MaxTextExtent];
+
+ FormatString(buffer,
+ "%.1024s %ld:%02ld %0.3f %ld %.1024s %.1024s %lu %.1024s"
+ " %.1024s %.1024s\n",
+ timestamp, (long) (elapsed_time/60.0),
+ (long) ceil(fmod(elapsed_time,60.0)),
+ user_time, (long) getpid(), srcname, function, line,
+ domain, severity, event);
+ log_info.method(type,buffer);
+ }
+ UnlockSemaphoreInfo(log_semaphore);
+ return(True);
+}
+MagickExport unsigned int LogMagickEvent(const ExceptionType type,
+ const char *module,const char *function,const unsigned long line,
+ const char *format,...)
+{
+ unsigned int
+ count;
+
+ va_list
+ operands;
+
+ va_start(operands,format);
+ count=LogMagickEventList(type, module, function, line, format, operands);
+ va_end(operands);
+ return (count);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d C o n f i g u r e F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadLogConfigureFile() reads the log configuration file.
+%
+% The format of the ReadLogConfigureFile method is:
+%
+% unsigned int ReadLogConfigureFile(const char *basename,
+% const unsigned int depth,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: ReadLogConfigureFile() returns True if at least one log entry
+% is defined otherwise False.
+%
+% o basename: The log configuration filename.
+%
+% o depth: depth of <include /> statements.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail ReadLogConfigureFile(const char *basename,
+ const unsigned int depth,ExceptionInfo *exception)
+{
+ char
+ keyword[MaxTextExtent],
+ path[MaxTextExtent],
+ *q,
+ *token,
+ *xml;
+
+ size_t
+ length=0,
+ token_max_length;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Read the log configure file.
+ */
+ (void) strlcpy(path,basename,sizeof(path));
+ if (depth == 0)
+ {
+ /*
+ Load top configuration file based on configure search path.
+ */
+ xml=(char *) GetConfigureBlob(basename,path,&length,exception);
+ }
+ else
+ {
+ /*
+ Load subordinate configuration file based on path specified
+ by parent configuration file.
+ */
+ xml=(char *) FileToBlob(basename,&length,exception);
+ }
+ if (xml == (char *) NULL)
+ return MagickFail;
+ token=AllocateString(xml);
+ token_max_length=strlen(token);
+ for (q=xml; *q != '\0'; )
+ {
+ /*
+ Interpret Coder.
+ */
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == '\0')
+ break;
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ if (LocaleNCompare(keyword,"<!--",4) == 0)
+ {
+ /*
+ Comment element.
+ */
+ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
+ MagickGetToken(q,&q,token,token_max_length);
+ continue;
+ }
+ if (LocaleCompare(keyword,"<include") == 0)
+ {
+ /*
+ Include element.
+ */
+ while ((*token != '>') && (*q != '\0'))
+ {
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(keyword,"file") == 0)
+ {
+ if (depth > 200)
+ (void) fprintf(stderr,"%.1024s: <include /> nested too deeply",
+ path);
+ else
+ {
+ char
+ filename[MaxTextExtent];
+
+ GetPathComponent(path,HeadPath,filename);
+ if (*filename != '\0')
+ (void) strlcat(filename,DirectorySeparator,MaxTextExtent);
+ (void) strlcat(filename,token,MaxTextExtent);
+ status &= ReadLogConfigureFile(filename,depth+1,exception);
+ if (status != MagickPass)
+ {
+ MagickFreeMemory(token);
+ MagickFreeMemory(xml);
+ return (status);
+ }
+ }
+ }
+ }
+ continue;
+ }
+ if (LocaleCompare(keyword,"<magicklog>") == 0)
+ {
+ (void) strlcpy(log_info.path,path,sizeof(log_info.path));
+ continue;
+ }
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ switch (*keyword)
+ {
+ case 'E':
+ case 'e':
+ {
+ if (LocaleCompare((char *) keyword,"events") == 0)
+ log_info.events = (LogEventType) ((unsigned int) log_info.events |
+ (unsigned int) ParseEvents(token));
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare((char *) keyword,"filename") == 0)
+ {
+ (void) strlcpy(log_info.filename,token,sizeof(log_info.filename));
+ break;
+ }
+ if (LocaleCompare((char *) keyword,"format") == 0)
+ {
+ (void) strlcpy(log_info.format,token,sizeof(log_info.format));
+ break;
+ }
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare((char *) keyword,"generations") == 0)
+ {
+ log_info.generations=MagickAtoL(token);
+ break;
+ }
+ break;
+ }
+ case 'L':
+ case 'l':
+ {
+ if (LocaleCompare((char *) keyword,"limit") == 0)
+ {
+ log_info.limit=MagickAtoL(token);
+ break;
+ }
+ break;
+ }
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare((char *) keyword,"output") == 0)
+ {
+ int i;
+
+ for (i=0; output_map[i].name != 0; i++)
+ {
+ if (LocaleNCompare(token,output_map[i].name,
+ strlen(output_map[i].name)) == 0)
+ {
+ /* We do not OR these flags despite the fact that
+ they are bit masks because they are still
+ mutually exclusive implementations. Asking for
+ XML and TXT format files each use the file handle
+ field and others to do their work, so they can
+ not be used together */
+
+ LockSemaphoreInfo(log_semaphore);
+
+ log_info.output_type=output_map[i].mask;
+
+ UnlockSemaphoreInfo(log_semaphore);
+
+ break;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ MagickFreeMemory(token);
+ MagickFreeMemory(xml);
+
+ if ((depth == 0) && (status == MagickPass))
+ log_configured=True;
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t L o g E v e n t M a s k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetLogEventMask() accepts a comma-delimited list that determines which
+% events to log. All other events are ignored. By default, no logging is
+% enabled. This method returns the updated log event mask.
+%
+% The format of the AcquireString method is:
+%
+% unsigned long SetLogEventMask(const char *events)
+%
+% A description of each parameter follows:
+%
+% o events: log these events.
+%
+%
+*/
+MagickExport unsigned long SetLogEventMask(const char *events)
+{
+ LogEventType
+ event_flags=NoEventsMask;
+
+ LockSemaphoreInfo(log_semaphore);
+
+ if (events != NULL)
+ {
+ event_flags=ParseEvents(events);
+ log_info.events=event_flags;
+ }
+
+ event_flags=log_info.events;
+
+ UnlockSemaphoreInfo(log_semaphore);
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Set log event mask: %s", events ? events : "None");
+
+ return (event_flags);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t L o g F o r m a t %
+% %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetLogFormat() sets the format for the "human readable" log record.
+%
+% The format of the LogMagickFormat method is:
+%
+% SetLogFormat(const char *format)
+%
+% A description of each parameter follows:
+%
+% o format: The log record format.
+%
+%
+*/
+MagickExport void SetLogFormat(const char *format)
+{
+ LockSemaphoreInfo(log_semaphore);
+
+ (void) strlcpy(log_info.format,format,sizeof(log_info.format));
+
+ UnlockSemaphoreInfo(log_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t L o g M e t h o d %
+% %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetLogMethod() sets the method that should be called when logging.
+%
+% The format of the SetLogMethod method is:
+%
+% SetLogFormat(LogMethod)
+%
+% A description of each parameter follows:
+%
+% o method: pointer to a method that will be called when LogMagickEvent is
+% being called.
+%
+%
+*/
+MagickExport void SetLogMethod(LogMethod method)
+{
+ LockSemaphoreInfo(log_semaphore);
+
+ log_info.output_type=(LogOutputType) (log_info.output_type |
+ MethodOutput);
+ log_info.method=method;
+
+ UnlockSemaphoreInfo(log_semaphore);
+}
diff --git a/magick/log.h b/magick/log.h
new file mode 100644
index 0000000..0a01cf6
--- /dev/null
+++ b/magick/log.h
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 2003 - 2014 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Log methods.
+*/
+#ifndef _MAGICK_LOG_H
+#define _MAGICK_LOG_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ /*
+ Define declarations.
+ */
+#define MagickLogFilename "log.mgk"
+
+ /*
+ Obtain the current C function name (if possible)
+ */
+# if !defined(GetCurrentFunction)
+# if (((defined(__cplusplus) || defined(c_plusplus)) && defined(HAS_CPP__func__)) || \
+ (!(defined(__cplusplus) || defined(c_plusplus)) && defined(HAS_C__func__)))
+# define GetCurrentFunction() (__func__)
+# elif defined(_VISUALC_) && defined(__FUNCTION__)
+# define GetCurrentFunction() (__FUNCTION__)
+# else
+# define GetCurrentFunction() ("unknown")
+# endif
+# endif
+
+ /*
+ Obtain current source file, function name, and source file line,
+ in a form acceptable for use with LogMagickEvent.
+ */
+# if !defined(GetMagickModule)
+# define GetMagickModule() __FILE__,GetCurrentFunction(),__LINE__
+# endif
+
+
+/* NOTE: any changes to this effect PerlMagick */
+typedef enum
+{
+ UndefinedEventMask = 0x00000000,
+ NoEventsMask = 0x00000000,
+ ConfigureEventMask = 0x00000001,
+ AnnotateEventMask = 0x00000002,
+ RenderEventMask = 0x00000004,
+ TransformEventMask = 0x00000008,
+ LocaleEventMask = 0x00000010,
+ CoderEventMask = 0x00000020,
+ X11EventMask = 0x00000040,
+ CacheEventMask = 0x00000080,
+ BlobEventMask = 0x00000100,
+ DeprecateEventMask = 0x00000200,
+ UserEventMask = 0x00000400,
+ ResourceEventMask = 0x00000800,
+ TemporaryFileEventMask = 0x00001000,
+ /* ExceptionEventMask = WarningEventMask | ErrorEventMask | FatalErrorEventMask */
+ ExceptionEventMask = 0x00070000,
+ OptionEventMask = 0x00004000,
+ InformationEventMask = 0x00008000,
+ WarningEventMask = 0x00010000,
+ ErrorEventMask = 0x00020000,
+ FatalErrorEventMask = 0x00040000,
+ AllEventsMask = 0x7FFFFFFF
+} LogEventType;
+
+typedef void
+ (*LogMethod)(const ExceptionType,const char *);
+
+/*
+ Method declarations.
+*/
+extern MagickExport MagickBool
+ IsEventLogging(void),
+ LogMagickEvent(const ExceptionType type,
+ const char *module,const char *function,const unsigned long line,
+ const char *format,...) MAGICK_ATTRIBUTE((__format__ (__printf__,5,6))),
+ LogMagickEventList(const ExceptionType type,
+ const char *module,const char *function,const unsigned long line,
+ const char *format,va_list operands);
+
+extern MagickExport unsigned long
+ SetLogEventMask(const char *events);
+
+extern MagickExport void
+ SetLogFormat(const char *format),
+ SetLogMethod(LogMethod);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+extern MagickExport void
+ DestroyLogInfo(void);
+
+extern MagickPassFail
+ InitializeLogInfo(void);
+
+extern MagickPassFail
+ InitializeLogInfoPost(void);
+
+#endif /* MAGICK_IMPLEMENTATION */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_LOG_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/magic.c b/magick/magic.c
new file mode 100644
index 0000000..e439a41
--- /dev/null
+++ b/magick/magic.c
@@ -0,0 +1,381 @@
+/*
+% Copyright (C) 2003 - 2009 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M M AAA GGGG IIIII CCCC %
+% MM MM A A G I C %
+% M M M AAAAA G GGG I C %
+% M M A A G G I C %
+% M M A A GGGG IIIII CCCC %
+% %
+% %
+% GraphicsMagick Image Magic Methods %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% July 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/magic.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+
+/*
+ Static declarations.
+*/
+static const struct
+{
+ char
+ *name;
+
+ unsigned char
+ *magic;
+
+ unsigned int
+ length,
+ offset;
+}
+StaticMagic[] =
+{
+#define MAGIC(name,offset,magic) {name,(unsigned char *)magic,sizeof(magic)-1,offset}
+ MAGIC("WEBP", 8, "WEBP"),
+ /* MAGIC("AVI", 0, "RIFF"), */
+ MAGIC("8BIMWTEXT", 0, "8\000B\000I\000M\000#"),
+ MAGIC("8BIMTEXT", 0, "8BIM#"),
+ MAGIC("8BIM", 0, "8BIM"),
+ MAGIC("BMP", 0, "BA"),
+ MAGIC("BMP", 0, "BM"),
+ MAGIC("BMP", 0, "CI"),
+ MAGIC("BMP", 0, "CP"),
+ MAGIC("BMP", 0, "IC"),
+ MAGIC("BMP", 0, "PI"),
+ MAGIC("CALS", 21, "version: MIL-STD-1840"),
+ MAGIC("CALS", 0, "srcdocid:"),
+ MAGIC("CALS", 9, "srcdocid:"),
+ MAGIC("CALS", 8, "rorient:"),
+ MAGIC("CGM", 0, "BEGMF"),
+ MAGIC("CIN", 0, "\200\052\137\327"),
+ MAGIC("DCM", 128, "DICM"),
+ MAGIC("DCX", 0, "\261\150\336\72"),
+ MAGIC("DIB", 0, "\050\000"),
+ MAGIC("DOT", 0, "digraph"),
+ MAGIC("DPX", 0, "SDPX"),
+ MAGIC("DPX", 0, "XPDS"),
+ MAGIC("EMF", 40, "\040\105\115\106\000\000\001\000"),
+ MAGIC("EPT", 0, "\305\320\323\306"),
+ MAGIC("FAX", 0, "DFAX"),
+ MAGIC("FIG", 0, "#FIG"),
+ MAGIC("FITS", 0, "IT0"),
+ MAGIC("FITS", 0, "SIMPLE"),
+ MAGIC("FPX", 0, "\320\317\021\340"),
+ MAGIC("GIF", 0, "GIF8"),
+ MAGIC("HDF", 1, "HDF"),
+ MAGIC("HPGL", 0, "IN;"),
+ MAGIC("HPGL", 0, "\033E\033"),
+ MAGIC("HTML", 1, "HTML"),
+ MAGIC("HTML", 1, "html"),
+ MAGIC("ILBM", 8, "ILBM"),
+ MAGIC("IPTCWTEXT", 0, "\062\000#\000\060\000=\000\042\000&\000#\000\060\000;\000&\000#\000\062\000;\000\042\000"),
+ MAGIC("IPTCTEXT", 0, "2#0=\042&#0;&#2;\042"),
+ MAGIC("IPTC", 0, "\034\002"),
+ MAGIC("JNG", 0, "\213JNG\r\n\032\n"),
+ MAGIC("JPEG", 0, "\377\330\377"),
+ MAGIC("JPC", 0, "\377\117"),
+ MAGIC("JP2", 4, "\152\120\040\040\015"),
+ MAGIC("MAT", 0, "MATLAB 5.0 MAT-file,"),
+ MAGIC("MIFF", 0, "Id=ImageMagick"),
+ MAGIC("MIFF", 0, "id=ImageMagick"),
+ MAGIC("MNG", 0, "\212MNG\r\n\032\n"),
+ MAGIC("MPC", 0, "id=MagickCache"),
+ MAGIC("MPEG", 0, "\000\000\001\263"),
+ MAGIC("PCD", 2048, "PCD_"),
+ MAGIC("PCL", 0, "\033E\033"),
+ MAGIC("PCX", 0, "\012\002"),
+ MAGIC("PCX", 0, "\012\005"),
+ MAGIC("PDB", 60, "vIMGView"),
+ MAGIC("PDF", 0, "%PDF-"),
+ MAGIC("PFA", 0, "%!PS-AdobeFont-1.0"),
+ MAGIC("PFB", 6, "%!PS-AdobeFont-1.0"),
+ MAGIC("PGX", 0, "PG ML"),
+ MAGIC("PGX", 0, "PG LM"),
+ MAGIC("PICT", 522, "\000\021\002\377\014\000"),
+ MAGIC("PNG", 0, "\211PNG\r\n\032\n"),
+ MAGIC("PBM", 0, "P1"),
+ MAGIC("PGM", 0, "P2"),
+ MAGIC("PPM", 0, "P3"),
+ MAGIC("PBM", 0, "P4"),
+ MAGIC("PGM", 0, "P5"),
+ MAGIC("PPM", 0, "P6"),
+ MAGIC("P7", 0, "P7 332"), /* XV Thumbnail */
+ MAGIC("PAM", 0, "P7"), /* Should be listed after "P7 332" */
+ MAGIC("PS", 0, "%!"),
+ MAGIC("PS", 0, "\004%!"),
+ MAGIC("PS", 0, "\305\320\323\306"),
+ MAGIC("PSD", 0, "8BPS"),
+ MAGIC("PWP", 0, "SFW95"),
+ MAGIC("RAD", 0, "#?RADIANCE"),
+ MAGIC("RAD", 0, "VIEW= "),
+ MAGIC("RLE", 0, "\122\314"),
+ MAGIC("SCT", 0, "CT"),
+ MAGIC("SFW", 0, "SFW94"),
+ MAGIC("SGI", 0, "\001\332"),
+ MAGIC("SUN", 0, "\131\246\152\225"),
+ MAGIC("SVG", 1, "?XML"),
+ MAGIC("SVG", 1, "?xml"),
+ MAGIC("TIFF", 0, "\115\115\000\052"),
+ MAGIC("TIFF", 0, "\111\111\052\000"),
+ MAGIC("BIGTIFF", 0, "\115\115\000\053\000\010\000\000"),
+ MAGIC("BIGTIFF", 0, "\111\111\053\000\010\000\000\000"),
+ MAGIC("VICAR", 0, "LBLSIZE"),
+ MAGIC("VICAR", 0, "NJPL1I"),
+ MAGIC("VIFF", 0, "\253\001"),
+ MAGIC("WMF", 0, "\327\315\306\232"),
+ MAGIC("WMF", 0, "\001\000\011\000"),
+ MAGIC("WPG", 0, "\377WPC"),
+ MAGIC("XBM", 0, "#define"),
+ MAGIC("XCF", 0, "gimp xcf"),
+ MAGIC("XPM", 1, "* XPM *"),
+ MAGIC("XWD", 4, "\007\000\000"),
+ MAGIC("XWD", 5, "\000\000\007")
+};
+
+/*
+ Forward declarations.
+*/
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y M a g i c I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyMagicInfo deallocates memory associated with the magic list.
+%
+% The format of the DestroyMagicInfo method is:
+%
+% DestroyMagicInfo(void)
+%
+%
+*/
+MagickExport void
+DestroyMagicInfo(void)
+{
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t M a g i c k F i l e F o r m a t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetMagickFileFormat inspects the provided image file/blob header
+% bytes and sets/updates the provided file format string buffer. The value
+% MagickPass is returned if the format was successfully identified. The
+% value MagickFail is returned if the format was not identified or an
+% exception occured.
+%
+%
+% The format of the GetMagickFileFormat method is:
+%
+% MagickPassFail GetMagickFileFormat(
+% const unsigned char *header, const size_t header_length,
+% char *postulate, const size_t postulate_length,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o header: A binary string representing the first several
+% thousand bytes of the file/blob header to test.
+%
+% o header_length: The length of the binary signature. Currently
+% 2*MaxTextExtent (4106 bytes).
+%
+% o format: Format buffer. Updated with actual format if it can be
+% determined.
+%
+% o format_length: Format buffer length.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail
+GetMagickFileFormat(const unsigned char *header, const size_t header_length,
+ char *format, const size_t format_length,
+ ExceptionInfo *exception)
+{
+ register unsigned int
+ i;
+
+ MagickPassFail
+ status=MagickFail;
+
+ ARG_NOT_USED(exception);
+
+ if (!((header == (const unsigned char *) NULL) || (header_length == 0) ||
+ (format_length < 2)))
+ {
+ /*
+ Search for requested magic.
+ */
+ for (i=0; i < sizeof(StaticMagic)/sizeof(StaticMagic[0]); i++)
+ {
+ if (StaticMagic[i].offset+StaticMagic[i].length <= header_length)
+ {
+ if ((header[StaticMagic[i].offset] == StaticMagic[i].magic[0]) &&
+ (memcmp(header+StaticMagic[i].offset,StaticMagic[i].magic,
+ StaticMagic[i].length) == 0))
+ {
+ if (strlcpy(format,StaticMagic[i].name,format_length) < format_length)
+ status=MagickPass;
+ break;
+ }
+ }
+ }
+ }
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e M a g i c I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeMagicInfo initializes the file header magic detection
+% facility.
+%
+% The format of the InitializeMagicInfo method is:
+%
+% MagickPassFail InitializeMagicInfo(void)
+%
+%
+*/
+MagickExport MagickPassFail
+InitializeMagicInfo(void)
+{
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t M a g i c I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ListMagicInfo lists the magic info to a file.
+%
+% The format of the ListMagicInfo method is:
+%
+% unsigned int ListMagicInfo(FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o file: An pointer to a FILE.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail
+ListMagicInfo(FILE *file,ExceptionInfo *exception)
+{
+ register unsigned int
+ i,
+ j;
+
+ ARG_NOT_USED(exception);
+
+ if (file == (const FILE *) NULL)
+ file=stdout;
+
+ (void) fprintf(file,"Name Offset Target\n");
+ (void) fprintf(file,"-------------------------------------------------"
+ "------------------------------\n");
+ for (i=0; i < sizeof(StaticMagic)/sizeof(StaticMagic[0]); i++)
+ {
+ register const unsigned char
+ *c;
+
+ (void) fprintf(file,"%.1024s",StaticMagic[i].name);
+ for (j= (unsigned int) strlen(StaticMagic[i].name); j <= 9; j++)
+ (void) fprintf(file," ");
+ (void) fprintf(file,"%6u ",StaticMagic[i].offset);
+
+ (void) fprintf(file,"\"");
+ c=StaticMagic[i].magic;
+ for (j=0; j < StaticMagic[i].length; j++)
+ {
+/* else if ('\b' == c[j]) */
+/* (void) fprintf(file,"\\b"); */
+/* else if ('\f' == c[j]) */
+/* (void) fprintf(file,"\\f"); */
+ if ('\n' == c[j])
+ (void) fprintf(file,"\\n");
+ else if ('\r' == c[j])
+ (void) fprintf(file,"\\r");
+ else if ('\t' == c[j])
+ (void) fprintf(file,"\\t");
+/* else if ('\v' == c[j]) */
+/* (void) fprintf(file,"\\v"); */
+/* else if ('\a' == c[j]) */
+/* (void) fprintf(file,"\\a"); */
+ else if ('\\' == c[j])
+ (void) fprintf(file,"\\");
+ else if ('\?' == c[j])
+ (void) fprintf(file,"\\?");
+ else if ('"' == c[j])
+ (void) fprintf(file,"\\\"");
+ else if (isprint((int) c[j]))
+ (void) fprintf(file,"%c",(int) c[j]);
+ else
+ {
+ (void) fprintf(file,"\\%03o",c[j]);
+ }
+ }
+ (void) fprintf(file,"\"\n");
+ }
+ (void) fflush(file);
+ return(MagickPass);
+}
diff --git a/magick/magic.h b/magick/magic.h
new file mode 100644
index 0000000..5bb5711
--- /dev/null
+++ b/magick/magic.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Magic methods.
+*/
+#ifndef _MAGICK_MAGIC_H
+#define _MAGICK_MAGIC_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Method declarations.
+*/
+extern MagickExport MagickPassFail
+ GetMagickFileFormat(const unsigned char *header,const size_t header_length,
+ char *format,const size_t format_length,ExceptionInfo *exception),
+ ListMagicInfo(FILE *file,ExceptionInfo *exception);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+extern MagickExport MagickPassFail
+ InitializeMagicInfo(void);
+
+extern MagickExport void
+ DestroyMagicInfo(void);
+
+#endif /* MAGICK_IMPLEMENTATION */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_MAGIC_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/magick.c b/magick/magick.c
new file mode 100644
index 0000000..0d2d7c0
--- /dev/null
+++ b/magick/magick.c
@@ -0,0 +1,1783 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M AAA GGGG IIIII CCCC K K %
+% MM MM A A G I C K K %
+% M M M AAAAA G GGG I C KKK %
+% M M A A G G I C K K %
+% M M A A GGGG IIIII CCCC K K %
+% %
+% %
+% Methods to Read or List GraphicsMagick Image formats %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% John Cristy %
+% November 1998 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+# include "magick/nt_feature.h"
+#endif
+#include "magick/blob.h"
+#include "magick/color_lookup.h"
+#include "magick/command.h"
+#include "magick/constitute.h"
+#include "magick/delegate.h"
+#include "magick/log.h"
+#include "magick/magic.h"
+#include "magick/magick.h"
+#include "magick/module.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/random.h"
+#include "magick/registry.h"
+#include "magick/resource.h"
+#include "magick/render.h"
+#include "magick/semaphore.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#if defined(HasX11)
+#include "magick/xwindow.h"
+#endif
+/* watch out here - this include code for simple spinlock semaphore */
+#include "magick/spinlock.h"
+
+/*
+ Global declarations.
+*/
+typedef enum {
+ InitDefault,
+ InitUninitialized,
+ InitInitialized
+} MagickInitializationState;
+
+static void
+ DestroyMagickInfoList(void);
+
+static SemaphoreInfo
+ *magick_semaphore = (SemaphoreInfo *) NULL;
+
+#if defined(SupportMagickModules)
+static SemaphoreInfo
+ *module_semaphore = (SemaphoreInfo *) NULL;
+#endif /* #if defined(SupportMagickModules) */
+
+static MagickInfo
+ *magick_list = (MagickInfo *) NULL;
+
+static unsigned int panic_signal_handler_call_count = 0;
+static unsigned int quit_signal_handler_call_count = 0;
+
+static MagickInitializationState MagickInitialized = InitDefault;
+static CoderClass MinimumCoderClass = UnstableCoderClass;
+
+static void DestroyMagickInfo(MagickInfo** magick_info);
+static void DestroyMagickInfoList(void);
+
+static MagickPassFail InitializeMagickInfoList(void);
+
+/*
+ Block size to use when accessing filesystem.
+
+ Adjust via MAGICK_IOBUF_SIZE environment variable.
+*/
+
+static size_t filesystem_blocksize=16384;
+
+/*
+ Get blocksize to use when accessing the filesystem.
+*/
+size_t
+MagickGetFileSystemBlockSize(void)
+{
+ return filesystem_blocksize;
+}
+
+/*
+ Set blocksize to use when accessing the filesystem.
+*/
+void
+MagickSetFileSystemBlockSize(const size_t block_size)
+{
+ assert(block_size > 0);
+ filesystem_blocksize=block_size;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y M a g i c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyMagick() destroys the GraphicsMagick environment, releasing all
+% allocated semaphores, memory, and temporary files. This function
+% should be invoked in the primary (original) thread of the application's
+% process while shutting down, and only after any threads which might be
+% using GraphicsMagick functions have terminated. Since GraphicsMagick
+% uses threads internally via OpenMP, it is also necessary for any function
+% calls into GraphicsMagick to have already returned so that OpenMP worker
+% threads are quiesced and won't be accessing any semaphores or data
+% structures which are destroyed by this function.
+%
+% The format of the DestroyMagick function is:
+%
+% DestroyMagick(void)
+%
+%
+*/
+MagickExport void
+DestroyMagick(void)
+{
+ /* Acquire destruction lock */
+ SPINLOCK_WAIT;
+
+ if (MagickInitialized == InitUninitialized)
+ {
+ /* Release destruction lock */
+ SPINLOCK_RELEASE;
+ return;
+ }
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Destroy Magick");
+
+ MagickDestroyCommandInfo(); /* Command parser */
+#if defined(HasX11)
+ MagickXDestroyX11Resources();
+#endif
+ DestroyColorInfo(); /* Color database */
+ DestroyDelegateInfo(); /* External delegate information */
+ DestroyTypeInfo(); /* Font information */
+ DestroyMagicInfo(); /* File format detection */
+ DestroyMagickInfoList(); /* Coder registrations + modules */
+ DestroyConstitute(); /* Constitute semaphore */
+ DestroyMagickRegistry(); /* Registered images */
+ DestroyMagickResources(); /* Resource semaphore */
+ DestroyMagickRandomGenerator(); /* Random number generator */
+ DestroyTemporaryFiles(); /* Temporary files */
+#if defined(MSWINDOWS)
+ NTGhostscriptUnLoadDLL(); /* Ghostscript DLL */
+#endif /* defined(MSWINDOWS) */
+ /*
+ Destroy logging last since some components log their destruction.
+ */
+ DestroyLogInfo(); /* Logging configuration */
+ DestroySemaphore(); /* Semaphores framework */
+
+ /* Now uninitialized */
+ MagickInitialized=InitUninitialized;
+
+ /* Release destruction lock */
+ SPINLOCK_RELEASE;
+}
+/*
+ Destroy MagickInfo structure.
+*/
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y M a g i c k I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyMagickInfo() destroys a MagickInfo structure.
+%
+% The format of the DestroyMagickInfoList method is:
+%
+% void DestroyMagickInfo(MagickInfo** magick_info)
+%
+*/
+static void
+DestroyMagickInfo(MagickInfo** magick_info)
+{
+ MagickInfo
+ *p;
+
+ p=*magick_info;
+ if (p)
+ {
+ p->name=0;
+ p->description=0;
+ p->version=0;
+ p->note=0;
+ p->module=0;
+ MagickFreeMemory(p);
+ *magick_info=p;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y M a g i c k I n f o L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyMagickInfo() deallocates memory associated with the MagickInfo list.
+%
+% The format of the DestroyMagickInfoList method is:
+%
+% void DestroyMagickInfoList(void)
+%
+*/
+static void
+DestroyMagickInfoList(void)
+{
+ MagickInfo
+ *magick_info;
+
+ register MagickInfo
+ *p;
+
+#if defined(SupportMagickModules)
+ DestroyMagickModules();
+#endif /* defined(SupportMagickModules) */
+
+#if !defined(BuildMagickModules)
+ UnregisterStaticModules();
+#endif /* !defined(BuildMagickModules) */
+
+ /*
+ At this point, the list should be empty, but check for remaining
+ entries anyway.
+ */
+#if defined(BuildMagickModules)
+ if (magick_list != (MagickInfo *) NULL)
+ (void) printf("Warning: module registrations are still present!\n");
+#endif /* defined(BuildMagickModules) */
+ for (p=magick_list; p != (MagickInfo *) NULL; )
+ {
+ magick_info=p;
+ p=p->next;
+
+#if !defined(BuildMagickModules)
+ (void) printf("Warning: module registration for \"%s\" from module \"%s\" still present!\n",
+ magick_info->name, magick_info->module);
+#endif /* !defined(BuildMagickModules) */
+ DestroyMagickInfo(&magick_info);
+ }
+ magick_list=(MagickInfo *) NULL;
+ DestroySemaphoreInfo(&magick_semaphore);
+
+#if defined(SupportMagickModules)
+ DestroySemaphoreInfo(&module_semaphore);
+#endif /* #if defined(SupportMagickModules) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e M a g i c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageMagick() searches for an image format that matches the specified
+% magick string. If one is found the name is returned otherwise NULL.
+%
+% The format of the GetImageMagick method is:
+%
+% const char *GetImageMagick(const unsigned char *magick,
+% const size_t length)
+%
+% A description of each parameter follows:
+%
+% o magick: The image format we are searching for.
+%
+% o length: The length of the binary string.
+%
+%
+*/
+MagickExport const char *
+GetImageMagick(const unsigned char *magick,const size_t length)
+{
+ register MagickInfo
+ *p;
+
+ assert(magick != (const unsigned char *) NULL);
+ LockSemaphoreInfo(magick_semaphore);
+ for (p=magick_list; p != (MagickInfo *) NULL; p=p->next)
+ if (p->magick && p->magick(magick,length))
+ break;
+ UnlockSemaphoreInfo(magick_semaphore);
+ if (p != (MagickInfo *) NULL)
+ return(p->name);
+ return((char *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M a g i c k I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickInfo() returns a pointer MagickInfo structure that matches
+% the specified name. If name is NULL, the head of the image format list
+% is returned. It is not safe to traverse the list by using the previous and
+% next pointers in the MagickInfo structure since the list contents or order
+% may be altered while the list is being traversed. If the list must be
+% traversed, access it via the GetMagickInfoArray function instead.
+%
+% If GraphicsMagick has not been initialized via InitializeMagick()
+% then this function will not work.
+%
+% The format of the GetMagickInfo method is:
+%
+% const MagickInfo *GetMagickInfo(const char *name,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o name: The image format we are looking for.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickInfo *
+GetMagickInfoEntryLocked(const char *name)
+{
+ register MagickInfo
+ *p;
+
+ LockSemaphoreInfo(magick_semaphore);
+
+ p=magick_list;
+
+ if ((name != (const char *) NULL) && (name[0] != '*'))
+ {
+ for (p=magick_list; p != (MagickInfo *) NULL; p=p->next)
+ if (LocaleCompare(p->name,name) == 0)
+ break;
+
+ if (p != (MagickInfo *) NULL)
+ if (p != magick_list)
+ {
+ /*
+ Self-adjusting list.
+ */
+ if (p->previous != (MagickInfo *) NULL)
+ p->previous->next=p->next;
+ if (p->next != (MagickInfo *) NULL)
+ p->next->previous=p->previous;
+ p->previous=(MagickInfo *) NULL;
+ p->next=magick_list;
+ magick_list->previous=p;
+ magick_list=p;
+ }
+ }
+
+ UnlockSemaphoreInfo(magick_semaphore);
+
+ return p;
+}
+MagickExport const MagickInfo *
+GetMagickInfo(const char *name,ExceptionInfo *exception)
+{
+ const MagickInfo
+ *magick_info=(const MagickInfo *) NULL;
+
+#if defined(SupportMagickModules)
+ if ((name != (const char *) NULL) &&
+ (name[0] != '\0'))
+ {
+ LockSemaphoreInfo(module_semaphore);
+ if (name[0] == '*')
+ {
+ /*
+ If all modules are requested, then use OpenModules to load all
+ modules.
+ */
+ (void) OpenModules(exception);
+ }
+ else
+ {
+ magick_info=GetMagickInfoEntryLocked(name);
+ if (magick_info == (const MagickInfo *) NULL)
+ {
+ /*
+ Try to load a supporting module.
+ */
+ (void) OpenModule(name,exception);
+ }
+ }
+ UnlockSemaphoreInfo(module_semaphore);
+ }
+#else
+ ARG_NOT_USED(exception);
+#endif /* #if defined(SupportMagickModules) */
+
+ /*
+ Return whatever we've got
+ */
+ if (magick_info == (const MagickInfo *) NULL)
+ magick_info=GetMagickInfoEntryLocked(name);
+
+ return magick_info;
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M a g i c k I n f o A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickInfoArray() returns a sorted null-terminated array of MagickInfo
+% pointers corresponding to the available format registrations. If necessarly
+% all modules are loaded in order to return a complete list. This function
+% should be used to access the entire list rather than GetMagickInfo since
+% the list returned by GetMagickInfo may be re-ordered every time it is
+% invoked. Once the returned array is no longer needed, the allocated array
+% should be deallocated. Do not attempt to deallocate the MagickInfo
+% structures based on pointers in the array!
+%
+% The format of the GetMagickList method is:
+%
+% MagickInfo **GetMagickInfoArray(ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+/*
+ Compare two MagickInfo structures based on their name
+*/
+static int
+MagickInfoCompare(const void *x, const void *y)
+{
+ const MagickInfo
+ *xx=*((const MagickInfo **) x),
+ *yy=*((const MagickInfo **) y);
+
+ return (strcmp(xx->name, yy->name));
+}
+MagickExport MagickInfo **
+GetMagickInfoArray(ExceptionInfo *exception)
+{
+ MagickInfo
+ **array;
+
+ MagickInfo
+ *p;
+
+ MagickInfo
+ *list;
+
+ size_t
+ entries=0;
+
+ int
+ i;
+
+ /*
+ Load all modules and obtain pointer to head of list
+ */
+ (void) GetMagickInfo("*",exception);
+ if (!magick_list)
+ return ((MagickInfo **) NULL);
+
+ LockSemaphoreInfo(magick_semaphore);
+
+ list=magick_list;
+
+ /*
+ Count number of list entries
+ */
+ for (p=list; p != 0; p=p->next)
+ entries++;
+
+ /*
+ Allocate array memory
+ */
+ array=MagickAllocateArray(MagickInfo **,sizeof(MagickInfo *),(entries+1));
+ if (!array)
+ {
+ UnlockSemaphoreInfo(magick_semaphore);
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,0);
+ return ((MagickInfo **) NULL);
+ }
+
+ /*
+ Add entries to array
+ */
+ i=0;
+ for (p=list; p != 0; p=p->next)
+ array[i++]=p;
+ array[i]=(MagickInfo *) NULL;
+
+ UnlockSemaphoreInfo(magick_semaphore);
+
+ /*
+ Sort array entries
+ */
+ qsort((void *) array, entries, sizeof(MagickInfo *), MagickInfoCompare);
+
+ return (array);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n i t i a l i z e M a g i c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializeMagick() initializes the GraphicsMagick environment.
+% InitializeMagick() MUST be invoked by the using program before making
+% use of GraphicsMagick functions or else the library will be unusable.
+%
+% This function should be invoked in the primary (original) thread of the
+% application's process, and before starting any OpenMP threads, as part
+% of program initialization.
+%
+% The format of the InitializeMagick function is:
+%
+% InitializeMagick(const char *path)
+%
+% A description of each parameter follows:
+%
+% o path: The execution path of the current GraphicsMagick client.
+%
+%
+*/
+
+/*
+ Due to legacy compilers, POSIX.1 actually allows the signal function
+ to return 'int' or 'void'. The compiler is not so lenient so we must
+ ensure that the return type matches the prototype in the headers.
+*/
+#if !defined(RETSIGTYPE)
+# define RETSIGTYPE void
+#endif
+typedef RETSIGTYPE Sigfunc(int);
+
+#if !defined(SIG_ERR)
+# define SIG_ERR (Sigfunc *)-1
+#endif
+#if !defined(SIG_DFL)
+# define SIG_DFL (Sigfunc *)0
+#endif
+
+static RETSIGTYPE MagickPanicSignalHandler(int signo);
+static RETSIGTYPE MagickSignalHandler(int signo);
+
+/*
+ Signal function which prevents interrupted system calls from
+ automatically being restarted. From W. Richard Stevens "Advanced
+ Programming in the UNIX Environment", Chapter 10.14.
+*/
+static Sigfunc *
+MagickSignal(int signo, Sigfunc *func)
+{
+#if defined(HAVE_SIGACTION) && defined(HAVE_SIGEMPTYSET)
+ struct sigaction
+ act,
+ oact;
+
+ act.sa_handler=func;
+ (void) sigemptyset(&act.sa_mask);
+ act.sa_flags=0;
+# if defined(SA_INTERRUPT) /* SunOS */
+ act.sa_flags |= SA_INTERRUPT;
+# endif
+ if (sigaction(signo, &act, &oact) < 0)
+ return (SIG_ERR);
+ return (oact.sa_handler);
+#else
+ return signal(signo, func);
+#endif
+}
+
+/*
+ Signal function which only sets the signal handler if it its handling
+ is still set to SIG_DFL. This ensures that signal handlers are not
+ registered for signals which are being ignored, or that the API
+ user has already registered before invoking InitializeMagick.
+
+ If an API user registers its own signal hander, then it is responsible
+ for invoking DestroyMagick when a signal is received.
+*/
+static Sigfunc *
+MagickCondSignal(int signo, Sigfunc *func)
+{
+ Sigfunc *
+ o_handler;
+
+ if ((o_handler=MagickSignal(signo,func)) != SIG_ERR)
+ {
+ /*
+ If handler is not the default, then restore the previous
+ setting.
+ */
+ if (o_handler != SIG_DFL)
+ (void) MagickSignal(signo,o_handler);
+ else
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Registered signal handler for signal ID %d",signo);
+ }
+ return (o_handler);
+}
+
+/*
+ Signal handler which does nothing.
+*/
+#if 0
+static RETSIGTYPE
+MagickIgnoreSignalHandler(int signo)
+{
+ fprintf(stderr,"Caught ignored signal %d\n", signo);
+}
+#endif
+
+/*
+ Write a message about the signal to stderr.
+*/
+static void
+MagickSignalHandlerMessage(const int signo, const char *subtext)
+{
+ /*
+ Signals we might handle, to map to their common description.
+
+ May use strsignal() on POSIX.1-2008-compliant systems, but it is
+ not documented to be async-safe.
+
+ */
+ static const struct {
+ const int signo;
+ const char *name;
+ const char *descr;
+ } signal_descr[] = {
+#if defined(SIGHUP)
+ { SIGHUP, "SIGHUP","Hangup" },
+#endif
+#if defined(SIGINT)
+ { SIGINT, "SIGINT", "Interrupt" },
+#endif
+#if defined(SIGQUIT)
+ { SIGQUIT, "SIGQUIT", "Quit" },
+#endif
+#if defined(SIGILL)
+ { SIGILL, "SIGILL", "Illegal Instruction" },
+#endif
+#if defined(SIGABRT)
+ { SIGABRT, "SIGABRT", "Abort" },
+#endif
+#if defined(SIGFPE)
+ { SIGFPE, "SIGFPE", "Arithmetic Exception" },
+#endif
+#if defined(SIGBUS)
+ { SIGBUS, "SIGBUS", "Bus Error" },
+#endif
+#if defined(SIGSEGV)
+ { SIGSEGV, "SIGSEGV", "Segmentation Fault" },
+#endif
+#if defined(SIGPIPE)
+ { SIGPIPE, "SIGPIPE", "Broken Pipe" },
+#endif
+#if defined(SIGALRM)
+ { SIGALRM, "SIGALRM", "Alarm Clock" },
+#endif
+#if defined(SIGTERM)
+ { SIGTERM, "SIGTERM", "Terminated" },
+#endif
+#if defined(SIGCHLD)
+ { SIGCHLD, "SIGCHLD", "Child Status Changed" },
+#endif
+#if defined(SIGXCPU)
+ { SIGXCPU, "SIGXCPU", "CPU time limit exceeded" },
+#endif
+#if defined(SIGXFSZ)
+ { SIGXFSZ, "SIGXFSZ", "File size limit exceeded" }
+#endif
+ };
+
+ static char
+ message[128];
+
+ size_t
+ i;
+
+ int
+ num=signo;
+
+ /*
+ Output messages like:
+
+ gm convert: quitting due to signal 2 (SIGINT) "Interrupt"...
+ gm convert: abort due to signal 11 (SIGSEGV) "Segmentation Fault"...
+ */
+ (void) strlcpy(message, GetClientName(), sizeof(message));
+ (void) strlcat(message,": ", sizeof(message));
+ (void) strlcat(message,subtext,sizeof(message));
+ (void) strlcat(message," due to signal ",sizeof(message));
+ i=strlen(message);
+ for ( ; (num != 0) && (i < sizeof(message)-1) ; i++)
+ {
+ int rem = num % 10;
+ message[i] = rem + '0';
+ num = num/10;
+ }
+ message[i] = '\0';
+ for ( i=0; i < (sizeof(signal_descr)/sizeof(signal_descr[0])); i++)
+ {
+ if (signo == signal_descr[i].signo)
+ {
+ (void) strlcat(message," (",sizeof(message));
+ (void) strlcat(message,signal_descr[i].name,sizeof(message));
+ (void) strlcat(message,") \"",sizeof(message));
+ (void) strlcat(message,signal_descr[i].descr,sizeof(message));
+ (void) strlcat(message,"\"",sizeof(message));
+ }
+ }
+ (void) strlcat(message,"...\n",sizeof(message));
+
+ if (write(STDERR_FILENO,message,
+ (MAGICK_POSIX_IO_SIZE_T) strlen(message)) == -1)
+ {
+ /* Exists to quench warning */
+ }
+}
+
+
+/*
+ Signal handler to ensure that DestroyMagick is invoked in case the
+ user aborts the program.
+
+ The WIN32 documentation says that SIGINT is not supported under any
+ version of Windows. It also says that a new thread is created to
+ handle the interrupt caused by CNTRL+C. The Windows signal
+ documentation also says that it is unsafe to do anything useful from
+ within a signal handler. This means that malloc/free and any system
+ call should not be executed. Theoretically DestroyMagick() should
+ not be executed since its purpose is to invoke unsafe functions.
+ SIGILL, SIGSEGV, and SIGTERM are documented to never be generated by
+ Windows NT.
+
+ While support for signal is definitely broken under Windows, the good
+ news is that it seems to be unlikely to generate a signal we care about.
+*/
+
+static RETSIGTYPE
+MagickPanicSignalHandler(int signo)
+{
+ ARG_NOT_USED(signo);
+
+ panic_signal_handler_call_count++;
+
+ /*
+ Only handle signal one time.
+ */
+ if (1 == panic_signal_handler_call_count)
+ {
+ /*
+ Release persistent resources
+ */
+ PanicDestroyMagick();
+
+ /*
+ Produce a useful message for the user
+ */
+ MagickSignalHandlerMessage(signo,"abort");
+
+ /*
+ Call abort so that we quit with core dump.
+ */
+ abort();
+ }
+}
+
+static MagickBool QuitProgressMonitor(const char *task,
+ const magick_int64_t quantum,
+ const magick_uint64_t span,
+ ExceptionInfo *exception)
+{
+ ARG_NOT_USED(task);
+ ARG_NOT_USED(quantum);
+ ARG_NOT_USED(span);
+
+ /* Report an error message */
+ if (exception->severity < FatalErrorException)
+ ThrowException(exception,MonitorFatalError,UserRequestedTerminationBySignal,0);
+
+ return MagickFail;
+}
+
+static RETSIGTYPE
+MagickSignalHandler(int signo)
+{
+ /* fprintf(stderr,"Caught signal %d\n", signo); */
+
+ quit_signal_handler_call_count++;
+
+ /*
+ Only handle signal one time.
+ */
+ if (1 == quit_signal_handler_call_count)
+ {
+ if (MagickInitialized == InitInitialized)
+ {
+
+ /*
+ Set progress monitor handler to one which always returns
+ MagickFail.
+ */
+ (void) SetMonitorHandler(QuitProgressMonitor);
+
+ /*
+ Release persistent resources
+ */
+ PanicDestroyMagick();
+
+ /*
+ Produce a useful message for the user
+ */
+ if (signo != SIGINT)
+ MagickSignalHandlerMessage(signo,"quitting");
+ }
+
+ /*
+ Invoke _exit(signo) (or equivalent) which avoids invoking
+ registered atexit() functions.
+ */
+ SignalHandlerExit(signo);
+ }
+}
+
+/*
+ The goal of this routine is to determine whether the passed
+ string is a valid and complete path to a file within the
+ filesystem
+ */
+#if !defined(UseInstalledMagick)
+static unsigned int
+IsValidFilesystemPath(const char *path)
+{
+ if ((path != (const char *) NULL) && (*path != '\0'))
+ {
+#if defined(POSIX)
+ /* For POSIX we check the first character to see of it is a file
+ system path seperator. If not then we ignore the passed data
+ */
+ if ((*path == *DirectorySeparator))
+ return IsAccessibleNoLogging(path);
+#elif defined(MSWINDOWS)
+ /* For Windows we check to see if the path passed seems to be a
+ pathof any kind (contains delimiters) or seem to be either UNC
+ path or one with a drive letter spec in it: \\Server\share, C:\
+ */
+ if (((*path == *DirectorySeparator) && (*(path+1) == *DirectorySeparator)) ||
+ (*(path+1) == ':') ||
+ (strchr(path,*DirectorySeparator) != (char *) NULL))
+ return IsAccessibleNoLogging(path);
+#else
+ /* In any other case, we just look to see if it has path delimiters */
+ if ((strchr(path,*DirectorySeparator) != (char *) NULL))
+ return IsAccessibleNoLogging(path);
+#endif
+ }
+ return False;
+}
+#endif /* !defined(UseInstalledMagick) */
+
+/*
+ Try and figure out the path and name of the client
+ */
+MagickExport void
+InitializeMagickClientPathAndName(const char *path)
+{
+#if !defined(UseInstalledMagick)
+ const char
+ *spath;
+
+ char
+ execution_path[MaxTextExtent];
+
+ /* the following is to make the logging more readable later on */
+ spath = path;
+ if (spath == (char *) NULL)
+ spath = "NULL";
+ if (*spath == '\0')
+ spath = "EMPTY";
+
+ *execution_path='\0';
+ if (!IsValidFilesystemPath(path))
+ {
+ /*
+ If the path passed is NULL or invalid then we try to ask the
+ OS what the name of the executable is. Callers will often pass
+ NULL in order to invoke this functionality.
+ */
+ if (GetExecutionPath(execution_path))
+ {
+ /*
+ The call to the OS worked so we can do all the settings
+ */
+ (void) DefineClientPathAndName(execution_path);
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Invalid path \"%s\" passed - asking OS worked: \"%s\"",spath,
+ execution_path);
+ }
+ else
+ {
+ /*
+ The call to the OS failed so we try to compute a usable
+ path based on the current working directory or by
+ searching the executable search path.
+ */
+ if (path)
+ (void) strlcpy(execution_path,path,MaxTextExtent);
+ if (GetExecutionPathUsingName(execution_path))
+ {
+ (void) DefineClientPathAndName(execution_path);
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Invalid path \"%s\" passed - asking OS failed, getcwd worked: \"%s\"",spath,
+ execution_path);
+ }
+ else
+ {
+ /*
+ At this point we are totally hosed and have nothing to
+ go on for the path, so all we can do is log the error
+ */
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Invalid path \"%s\" passed - asking OS failed, getcwd also failed",spath);
+ }
+ }
+ }
+ else
+ {
+ /*
+ This is the easy one. The caller gave us the correct and
+ working path to the application, so we just use it
+ */
+ (void) strlcpy(execution_path,path,MaxTextExtent);
+ (void) DefineClientPathAndName(execution_path);
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Valid path \"%s\"",spath);
+ }
+#else
+ ARG_NOT_USED(path);
+#endif
+}
+
+/*
+ Establish signal handlers for common signals
+
+*/
+MagickExport void
+InitializeMagickSignalHandlers(void)
+{
+#if 0
+ /* termination of child process */
+#if defined(SIGCHLD)
+ (void) MagickCondSignal(SIGCHLD,MagickIgnoreSignalHandler);
+#endif
+#endif
+
+ /* hangup, default terminate */
+#if defined(SIGHUP)
+ (void) MagickCondSignal(SIGHUP,MagickSignalHandler);
+#endif
+ /* interrupt (CONTROL-c), default terminate */
+#if defined(SIGINT)
+ (void) MagickCondSignal(SIGINT,MagickSignalHandler);
+#endif
+ /* quit (CONTROL-\), default terminate with core */
+#if defined(SIGQUIT)
+ (void) MagickCondSignal(SIGQUIT,MagickPanicSignalHandler);
+#endif
+ /* software-triggered abort, default terminate with core */
+#if defined(SIGABRT)
+ (void) MagickCondSignal(SIGABRT,MagickPanicSignalHandler);
+#endif
+ /* floating point exception, default terminate with core */
+#if defined(SIGFPE)
+ (void) MagickCondSignal(SIGFPE,MagickPanicSignalHandler);
+#endif
+ /* software termination signal from kill, default terminate */
+#if defined(SIGTERM)
+ (void) MagickCondSignal(SIGTERM,MagickSignalHandler);
+#endif
+ /* Bus Error */
+#if defined(SIGBUS)
+ (void) MagickCondSignal(SIGBUS,MagickPanicSignalHandler);
+#endif
+ /* segmentation fault */
+#if defined(SIGSEGV)
+ (void) MagickCondSignal(SIGSEGV,MagickPanicSignalHandler);
+#endif
+ /* exceeded cpu limit, default terminate with core */
+#if defined(SIGXCPU)
+ (void) MagickCondSignal(SIGXCPU,MagickPanicSignalHandler);
+#endif
+ /* exceeded file size limit, default terminate with core */
+#if defined(SIGXFSZ)
+ (void) MagickCondSignal(SIGXFSZ,MagickPanicSignalHandler);
+#endif
+}
+
+MagickExport void
+InitializeMagick(const char *path)
+{
+ /*
+ NOTE: This routine sets up the path to the client which needs to
+ be determined before almost anything else works right. This also
+ includes logging!!! So we can't start logging until the path is
+ actually saved. As soon as we know what the path is we make the
+ same call to DefineClientSettings to set it up. Please make sure
+ that this rule is followed in any future updates the this code!!!
+ */
+
+ const char
+ *p;
+
+ /* Acquire initialization lock */
+ SPINLOCK_WAIT;
+
+ if (MagickInitialized == InitInitialized)
+ {
+ /* Release initialization lock */
+ SPINLOCK_RELEASE;
+ return;
+ }
+
+#if defined(MSWINDOWS)
+# if defined(_DEBUG) && !defined(__BORLANDC__)
+ {
+ int
+ debug;
+
+ debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ debug|=_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF |
+ _CRTDBG_LEAK_CHECK_DF;
+ /* debug=_CrtSetDbgFlag(debug); */
+ /* _ASSERTE(_CrtCheckMemory()); */
+ }
+# endif /* defined(_DEBUG) */
+#endif /* defined(MSWINDOWS) */
+
+ /* Initialize semaphores */
+ InitializeSemaphore();
+
+ /* Initialize logging */
+ InitializeLogInfo();
+
+ /* Initialize our random number generator */
+ InitializeMagickRandomGenerator();
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Initialize Magick");
+
+ /*
+ Set the filesystem block size.
+ */
+ {
+ size_t
+ block_size=16384;
+
+ if ((p=getenv("MAGICK_IOBUF_SIZE")) != (const char *) NULL)
+ {
+ long
+ block_size_long;
+
+ block_size_long = MagickAtoL(p);
+ if ((block_size_long > 0L) && (block_size_long <= 2097152L))
+ block_size=(size_t) block_size_long;
+ else
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Ignoring unreasonable MAGICK_IOBUF_SIZE of "
+ "%ld bbytes", block_size_long);
+ }
+
+ MagickSetFileSystemBlockSize(block_size);
+ }
+
+ /*
+ Establish the path, filename, and display name of the client app
+ */
+ InitializeMagickClientPathAndName(path);
+ /*
+ If the client name did not get setup for any reason, we take one
+ last shot at it using the data the caller passed us.
+ */
+ if (GetClientName() == (const char *) NULL)
+ DefineClientName(path);
+
+ /*
+ Initialize any logging configuration which could not complete
+ since we did not know the installation directory yet
+ */
+ InitializeLogInfoPost();
+
+ /*
+ Adjust minimum coder class if requested.
+ */
+ if ((p=getenv("MAGICK_CODER_STABILITY")) != (const char *) NULL)
+ {
+ if (LocaleCompare(p,"BROKEN") == 0)
+ MinimumCoderClass=BrokenCoderClass;
+ else if (LocaleCompare(p,"UNSTABLE") == 0)
+ MinimumCoderClass=UnstableCoderClass;
+ else if (LocaleCompare(p,"STABLE") == 0)
+ MinimumCoderClass=StableCoderClass;
+ else if (LocaleCompare(p,"PRIMARY") == 0)
+ MinimumCoderClass=PrimaryCoderClass;
+ }
+
+#if defined(MSWINDOWS)
+ NTInitializeExceptionHandlers(); /* WIN32 Exceptions */
+#endif /* defined(MSWINDOWS) */
+ InitializeMagickSignalHandlers(); /* Signal handlers */
+ InitializeTemporaryFiles(); /* Temporary files */
+ InitializeMagickResources(); /* Resources */
+ InitializeMagickRegistry(); /* Image/blob registry */
+ InitializeConstitute(); /* Constitute semaphore */
+ InitializeMagickInfoList(); /* Coder registrations + modules */
+ InitializeMagicInfo(); /* File format detection */
+ InitializeTypeInfo(); /* Font information */
+ InitializeDelegateInfo(); /* External delegate information */
+ InitializeColorInfo(); /* Color database */
+ MagickInitializeCommandInfo(); /* Command parser */
+
+ /* Let's log the three important setting as we exit this routine */
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Path: \"%s\" Name: \"%s\" Filename: \"%s\"",
+ GetClientPath(),GetClientName(),GetClientFilename());
+
+ /* Now initialized */
+ MagickInitialized=InitInitialized;
+
+ /* Release initialization lock */
+ SPINLOCK_RELEASE;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e M a g i c k I n f o L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeMagickInfoList initializes the magick info facility
+%
+% The format of the InitializeMagickInfoList method is:
+%
+% MagickPassFail InitializeMagickInfoList(void)
+%
+%
+*/
+MagickPassFail
+InitializeMagickInfoList(void)
+{
+ assert(magick_semaphore == (SemaphoreInfo *) NULL);
+ magick_semaphore=AllocateSemaphoreInfo();
+
+#if defined(SupportMagickModules)
+ assert(module_semaphore == (SemaphoreInfo *) NULL);
+ module_semaphore=AllocateSemaphoreInfo();
+#endif /* #if defined(SupportMagickModules) */
+
+#if !defined(BuildMagickModules)
+ RegisterStaticModules(); /* Register all static modules */
+#endif /* !defined(BuildMagickModules) */
+
+#if defined(SupportMagickModules)
+ InitializeMagickModules(); /* Module loader */
+#endif /* defined(SupportMagickModules) */
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M a g i c k C o n f l i c t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsMagickConflict returns true if the image format conflicts with
+% a logical drive (.e.g. X:).
+%
+% The format of the IsMagickConflict method is:
+%
+% MagickBool IsMagickConflict(const char *magick)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsMagickConflict returns true if the image format
+% conflicts with a logical drive.
+%
+% o magick: Specifies the image format.
+%
+%
+*/
+MagickExport MagickBool
+IsMagickConflict(const char *magick)
+{
+ assert(magick != (char *) NULL);
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+ return(NTIsMagickConflict(magick));
+#endif
+ return(MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t M a g i c k I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ListMagickInfo() lists the image formats to a file.
+%
+% The format of the ListMagickInfo method is:
+%
+% MagickPassFail ListMagickInfo(FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o file: A file handle.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail
+ListMagickInfo(FILE *file,ExceptionInfo *exception)
+{
+
+ MagickInfo
+ **magick_array;
+
+ int
+ i;
+
+ if (file == (FILE *) NULL)
+ file=stdout;
+
+ magick_array=GetMagickInfoArray(exception);
+ if (!magick_array)
+ return False;
+
+ (void) fprintf(file," Format L Mode Description\n");
+ (void) fprintf(file,"--------------------------------------------------------"
+ "------------------------\n");
+ for (i=0; magick_array[i] != 0; i++)
+ {
+ if (magick_array[i]->stealth)
+ continue;
+ (void) fprintf(file,"%9s %c %c%c%c",
+ magick_array[i]->name ? magick_array[i]->name : "",
+ (magick_array[i]->coder_class == PrimaryCoderClass ? 'P' :
+ (magick_array[i]->coder_class == StableCoderClass ? 'S' :
+ 'U')),
+ (magick_array[i]->decoder ? 'r' : '-'),
+ (magick_array[i]->encoder ? 'w' : '-'),
+ ((magick_array[i]->encoder && magick_array[i]->adjoin) ? '+' : '-'));
+ if (magick_array[i]->description != (char *) NULL)
+ (void) fprintf(file," %.1024s",magick_array[i]->description);
+ if (magick_array[i]->version != (char *) NULL)
+ (void) fprintf(file," (%.1024s)",magick_array[i]->version);
+ (void) fprintf(file,"\n");
+ if (magick_array[i]->note != (char *) NULL)
+ {
+ char
+ **text;
+
+ text=StringToList(magick_array[i]->note);
+ if (text != (char **) NULL)
+ {
+ register long
+ j;
+
+ for (j=0; text[j] != (char *) NULL; j++)
+ {
+ (void) fprintf(file," %.1024s\n",text[j]);
+ MagickFreeMemory(text[j]);
+ }
+ MagickFreeMemory(text);
+ }
+ }
+ }
+ (void) fprintf(file,"\n Meaning of 'L': P=Primary, S=Stable, U=Unstable\n");
+ (void) fflush(file);
+ MagickFreeMemory(magick_array);
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t M o d u l e M a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ListModuleMap lists the module alias info to a file in the XML
+% format used by modules.mgk. True is returned on success.
+%
+% The format of the ListModuleMap method is:
+%
+% MagickPassFail ListModuleMap(FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o file: An pointer to a FILE.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail
+ListModuleMap(FILE *file,ExceptionInfo *exception)
+{
+ MagickInfo
+ **magick_array;
+
+ int
+ i;
+
+ if (file == (const FILE *) NULL)
+ file=stdout;
+
+ magick_array=GetMagickInfoArray(exception);
+ if (!magick_array)
+ return MagickFail;
+
+ (void) fprintf(file, "<?xml version=\"1.0\"?>\n");
+ (void) fprintf(file, "<!-- %s -->\n",GetMagickCopyright());
+ (void) fprintf(file, "<!-- Magick Module Alias Map (modules.mgk) -->\n");
+ (void) fprintf(file, "<modulemap>\n");
+
+ for (i=0; magick_array[i] != 0; i++)
+ {
+ if (LocaleCompare(magick_array[i]->name,magick_array[i]->module) != 0)
+ {
+ (void) fprintf(file, " <module magick=\"%s\" name=\"%s\" />\n",
+ magick_array[i]->name,
+ (magick_array[i]->module == NULL ? "(null)" :
+ magick_array[i]->module));
+ }
+ }
+ (void) fprintf(file, "</modulemap>\n");
+ (void) fflush(file);
+
+ MagickFreeMemory(magick_array);
+
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k T o M i m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickToMime returns the officially registered (or de facto) MIME
+% media-type corresponding to a magick string. If there is no registered
+% media-type, then the string "image/x-magick" (all lower case) is returned.
+% The returned string must be deallocated by the user.
+%
+% The format of the MagickToMime method is:
+%
+% char *MagickToMime(const char *magick)
+%
+% A description of each parameter follows.
+%
+% o magick: GraphicsMagick format specification "magick" tag.
+%
+%
+*/
+MagickExport char *
+MagickToMime(const char *magick)
+{
+ typedef struct _MediaType
+ {
+ const char
+ *magick,
+ *media;
+ } MediaType;
+
+ char
+ media[MaxTextExtent];
+
+ MediaType
+ *entry;
+
+ static MediaType
+ MediaTypes[] =
+ {
+ { "avi", "video/avi" },
+ { "cgm", "image/cgm;Version=4;ProfileId=WebCGM" }, /* W3 WebCGM */
+ { "dcm", "application/dicom" }, /* Incomplete. See RFC 3240 */
+ { "epdf", "application/pdf" },
+ { "epi", "application/postscript" },
+ { "eps", "application/postscript" },
+ { "eps2", "application/postscript" },
+ { "eps3", "application/postscript" },
+ { "epsf", "application/postscript" },
+ { "ept", "application/postscript" },
+ { "fax", "image/g3fax" },
+ { "fpx", "image/vnd.fpx" },
+ { "g3", "image/g3fax" },
+ { "gif", "image/gif" },
+ { "gif87", "image/gif" },
+ { "jpeg", "image/jpeg" },
+ { "mng", "video/x-mng" },
+ { "mpeg", "video/mpeg" },
+ { "png", "image/png" },
+ { "pdf", "application/pdf" },
+ { "ps", "application/postscript" },
+ { "ps2", "application/postscript" },
+ { "ps3", "application/postscript" },
+ { "svg", "image/svg+xml" },
+ { "tif", "image/tiff" },
+ { "tiff", "image/tiff" },
+ { "wbmp", "image/vnd.wap.wbmp" },
+ { (char *) NULL, (char *) NULL }
+ };
+
+ for (entry=MediaTypes; entry->magick != (char *) NULL; entry++)
+ if (LocaleCompare(entry->magick,magick) == 0)
+ return(AllocateString(entry->media));
+ FormatString(media,"image/x-%.1024s",magick);
+ LocaleLower(media+8);
+ return(AllocateString(media));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M a g i c k I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RegisterMagickInfo() adds attributes for a particular image format to the
+% list of supported formats. The attributes include the image format name,
+% a method to read and/or write the format, whether the format supports the
+% saving of more than one frame to the same file or blob, whether the format
+% supports native in-memory I/O, and a brief description of the format.
+%
+% The format of the RegisterMagickInfo method is:
+%
+% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
+%
+% A description of each parameter follows:
+%
+% o magick_info: The magick info.
+%
+*/
+MagickExport MagickInfo *
+RegisterMagickInfo(MagickInfo *magick_info)
+{
+ assert(magick_info != (MagickInfo *) NULL);
+ assert(magick_info->signature == MagickSignature);
+
+ /*
+ Remove any existing entry.
+ */
+ (void) UnregisterMagickInfo(magick_info->name);
+
+ /*
+ Verify that coder stability level is sufficient.
+ */
+ if (magick_info->coder_class >= MinimumCoderClass)
+ {
+ /*
+ Add to front of list.
+ */
+ LockSemaphoreInfo(magick_semaphore);
+ magick_info->previous=(MagickInfo *) NULL;
+ magick_info->next=magick_list;
+ if (magick_info->next != (MagickInfo *) NULL)
+ magick_info->next->previous=magick_info;
+ magick_list=magick_info;
+ UnlockSemaphoreInfo(magick_semaphore);
+ return(magick_info);
+ }
+
+ /*
+ Discard registration and return NULL.
+ */
+ DestroyMagickInfo(&magick_info);
+ return(magick_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P a n i c D e s t r o y M a g i c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PanicDestroyMagick() destroys only persistent allocations such as
+% temporary files. Other allocations (e.g. semaphores and heap memory)
+% remain allocated. This function is an alternative to DestroyMagick()
+% which is async-safe so it may be invoked from signal handers, and
+% may be invoked from thread context. No semaphores are taken and no
+% additional heap memory is allocated by this function. The program
+% must quit immediately after invoking this function.
+%
+% The format of the PanicDestroyMagick function is:
+%
+% void PanicDestroyMagick(void)
+%
+%
+*/
+/*
+ Set to 1 to break the memory allocation functions. This is a
+ debugging aid. In a multi-threaded program, other threads may
+ still be allocating and deallocating memory while a signal
+ handler is called.
+*/
+#define MAGICK_BREAK_HEAP 0
+#if MAGICK_BREAK_HEAP
+static void
+PanicFreeFunc(void *ptr)
+{
+ char err_str[] = "Attempt to free memory in PanicDestroyMagick()\n";
+ ARG_NOT_USED(ptr);
+ if (write(STDERR_FILENO,err_str,sizeof(err_str)-1) == -1)
+ {
+ /* Exists to quench warning */
+ }
+}
+static void *
+PanicMallocFunc(size_t size)
+{
+ char err_str[] = "Attempt to malloc memory in PanicDestroyMagick()\n";
+ ARG_NOT_USED(size);
+ if (write(STDERR_FILENO,err_str,sizeof(err_str)-1) == -1)
+ {
+ /* Exists to quench warning */
+ }
+ return (void *) NULL;
+}
+static void *
+PanicReallocFunc(void *ptr, size_t size)
+{
+ char err_str[] = "Attempt to realloc memory in PanicDestroyMagick()\n";
+ ARG_NOT_USED(ptr);
+ ARG_NOT_USED(size);
+ if (write(STDERR_FILENO,err_str,sizeof(err_str)-1) == -1)
+ {
+ /* Exists to quench warning */
+ }
+ return (void *) NULL;
+}
+#endif /* if MAGICK_BREAK_HEAP */
+MagickExport void
+PanicDestroyMagick(void)
+{
+ if (MagickInitialized == InitInitialized)
+ {
+#if MAGICK_BREAK_HEAP
+ /*
+ Enforce that we don't use the memory allocation functions by
+ setting them all to dummy functions.
+ */
+ MagickAllocFunctions(PanicFreeFunc,PanicMallocFunc,PanicReallocFunc);
+#endif /* if MAGICK_BREAK_HEAP */
+ /*
+ Release persistent resources
+ */
+ PurgeTemporaryFilesAsyncSafe();
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t M a g i c k I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SetMagickInfo allocates a MagickInfo structure and initializes the
+% members to default values.
+%
+% The format of the SetMagickInfo method is:
+%
+% MagickInfo *SetMagickInfo(const char *name)
+%
+% A description of each parameter follows:
+%
+% o magick_info: Method SetMagickInfo returns the allocated and initialized
+% MagickInfo structure.
+%
+% o name: a character string that represents the image format associated
+% with the MagickInfo structure.
+%
+%
+*/
+MagickExport MagickInfo *
+SetMagickInfo(const char *name)
+{
+ MagickInfo
+ *magick_info;
+
+ assert(name != (const char *) NULL);
+ magick_info=MagickAllocateMemory(MagickInfo *,sizeof(MagickInfo));
+ if (magick_info == (MagickInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateMagickInfo);
+ (void) memset(magick_info,0,sizeof(MagickInfo));
+ magick_info->name=name;
+ magick_info->adjoin=MagickTrue;
+ magick_info->raw=MagickFalse;
+ magick_info->stealth=MagickFalse;
+ magick_info->seekable_stream=MagickFalse;
+ magick_info->blob_support=MagickTrue;
+ magick_info->thread_support=MagickTrue;
+ magick_info->coder_class=StableCoderClass;
+ magick_info->extension_treatment=HintExtensionTreatment;
+ magick_info->signature=MagickSignature;
+ return(magick_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M a g i c k I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnregisterMagickInfo removes a name from the magick info list. It
+% returns MagickFail if the name does not exist in the list otherwise
+% MagickPass.
+%
+% The format of the UnregisterMagickInfo method is:
+%
+% unsigned int UnregisterMagickInfo(const char *name)
+%
+% A description of each parameter follows:
+%
+% o status: Method UnregisterMagickInfo returns False if the name does not
+% exist in the list otherwise True.
+%
+% o name: a character string that represents the image format we are
+% looking for.
+%
+*/
+MagickExport MagickPassFail
+UnregisterMagickInfo(const char *name)
+{
+ MagickInfo
+ *magick_info;
+
+ register MagickInfo
+ *p;
+
+ unsigned int
+ status;
+
+ assert(name != (const char *) NULL);
+ status=MagickFail;
+ LockSemaphoreInfo(magick_semaphore);
+ for (p=magick_list; p != (MagickInfo *) NULL; p=p->next)
+ {
+ if (LocaleCompare(p->name,name) != 0)
+ continue;
+ if (p->next != (MagickInfo *) NULL)
+ p->next->previous=p->previous;
+ if (p->previous != (MagickInfo *) NULL)
+ p->previous->next=p->next;
+ else
+ magick_list=p->next;
+ magick_info=p;
+ DestroyMagickInfo(&magick_info);
+ status=MagickPass;
+ break;
+ }
+ UnlockSemaphoreInfo(magick_semaphore);
+ return(status);
+}
diff --git a/magick/magick.h b/magick/magick.h
new file mode 100644
index 0000000..08f51ef
--- /dev/null
+++ b/magick/magick.h
@@ -0,0 +1,161 @@
+/*
+ Copyright (C) 2003 - 2014 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Application Programming Interface declarations.
+*/
+#ifndef _MAGICK_MAGICK_H
+#define _MAGICK_MAGICK_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+typedef Image
+ *(*DecoderHandler)(const ImageInfo *,ExceptionInfo *);
+
+typedef unsigned int
+ (*EncoderHandler)(const ImageInfo *,Image *),
+ (*MagickHandler)(const unsigned char *,const size_t);
+
+/*
+ Stability and usefulness of the coder.
+*/
+typedef enum
+{
+ BrokenCoderClass = -1, /* Known to sometimes/often not work properly or
+ might not be useful at all */
+ UnstableCoderClass = 0, /* Weak implementation, poorly designed file
+ format, and/or hardly ever used */
+ StableCoderClass, /* Well maintained, but not often used */
+ PrimaryCoderClass /* Well maintained and commonly used */
+} CoderClass;
+
+/*
+ How the file extension should be treated (e.g. in SetImageInfo()).
+*/
+typedef enum
+{
+ HintExtensionTreatment = 0, /* Extension is a useful hint to indicate format */
+ ObeyExtensionTreatment, /* Extension must be obeyed as format indicator */
+ IgnoreExtensionTreatment /* Format has no associated extension */
+} ExtensionTreatment;
+
+typedef struct _MagickInfo
+{
+ struct _MagickInfo
+ *next, /* private, next member in list */
+ *previous; /* private, previous member in list */
+
+ const char
+ *name; /* format ID ("magick") */
+
+ const char
+ *description, /* format description */
+ *note, /* usage note for user */
+ *version, /* support library version */
+ *module; /* name of loadable module */
+
+ DecoderHandler
+ decoder; /* function vector to decoding routine */
+
+ EncoderHandler
+ encoder; /* function vector to encoding routine */
+
+ MagickHandler
+ magick; /* function vector to format test routine */
+
+ void
+ *client_data; /* arbitrary user supplied data */
+
+ MagickBool
+ adjoin, /* coder may read/write multiple frames (default True) */
+ raw, /* coder requires that size be set (default False) */
+ stealth, /* coder should not appear in formats listing (default MagickFalse) */
+ seekable_stream, /* coder requires BLOB "seek" and "tell" APIs (default MagickFalse)
+ * Note that SetImageInfo() currently always copies input
+ * from a pipe, .gz, or .bz2 file, to a temporary file so
+ * that it can retrieve a bit of the file header in order to
+ * support the file header magic logic.
+ */
+ blob_support, /* coder uses BLOB APIs (default True) */
+ thread_support; /* coder is thread safe (default True) */
+
+ CoderClass
+ coder_class; /* Coder usefulness/stability level */
+
+ ExtensionTreatment
+ extension_treatment; /* How much faith should be placed on file extension? */
+
+ unsigned long
+ signature; /* private, structure validator */
+
+} MagickInfo;
+
+/*
+ Magick method declaractions.
+*/
+extern MagickExport char
+ *MagickToMime(const char *magick);
+
+extern MagickExport const char
+ *GetImageMagick(const unsigned char *magick,const size_t length);
+
+extern MagickExport MagickBool
+ IsMagickConflict(const char *magick);
+
+extern MagickExport MagickPassFail
+ ListModuleMap(FILE *file,ExceptionInfo *exception),
+ ListMagickInfo(FILE *file,ExceptionInfo *exception),
+ UnregisterMagickInfo(const char *name);
+
+extern MagickExport void
+ DestroyMagick(void),
+ InitializeMagick(const char *path),
+ PanicDestroyMagick(void);
+
+extern MagickExport const MagickInfo
+ *GetMagickInfo(const char *name,ExceptionInfo *exception);
+
+extern MagickExport MagickInfo
+ **GetMagickInfoArray(ExceptionInfo *exception);
+
+extern MagickExport MagickInfo
+ *RegisterMagickInfo(MagickInfo *magick_info),
+ *SetMagickInfo(const char *name);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+ /*
+ Get blocksize to use when accessing the filesystem.
+ */
+ extern size_t
+ MagickGetFileSystemBlockSize(void);
+
+ /*
+ Set blocksize to use when accessing the filesystem.
+ */
+ extern void
+ MagickSetFileSystemBlockSize(const size_t block_size);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_MAGICK_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/magick_config.h.in b/magick/magick_config.h.in
new file mode 100644
index 0000000..b5df198
--- /dev/null
+++ b/magick/magick_config.h.in
@@ -0,0 +1,682 @@
+/* magick/magick_config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define if coders and filters are to be built as modules. */
+#undef BuildMagickModules
+
+/* Disable OpenMP for algorithms which sometimes run slower */
+#undef DisableSlowOpenMP
+
+/* Enable broken/dangerous file formats support */
+#undef EnableBrokenCoders
+
+/* C compiler used for compilation */
+#undef GM_BUILD_CC
+
+/* CFLAGS used for C compilation */
+#undef GM_BUILD_CFLAGS
+
+/* arguments passed to configure */
+#undef GM_BUILD_CONFIGURE_ARGS
+
+/* CPPFLAGS used for preprocessing */
+#undef GM_BUILD_CPPFLAGS
+
+/* C++ compiler used for compilation */
+#undef GM_BUILD_CXX
+
+/* CXXFLAGS used for C++ compilation */
+#undef GM_BUILD_CXXFLAGS
+
+/* Host identification triplet */
+#undef GM_BUILD_HOST
+
+/* LDFLAGS used for linking */
+#undef GM_BUILD_LDFLAGS
+
+/* LIBS used for linking */
+#undef GM_BUILD_LIBS
+
+/* Define if C++ compiler supports __func__ */
+#undef HAS_CPP__func__
+
+/* Define if C compiler supports __func__ */
+#undef HAS_C__func__
+
+/* Define to 1 if you have the `atoll' function. */
+#undef HAVE_ATOLL
+
+/* define if bool is a built-in type */
+#undef HAVE_BOOL
+
+/* Define to 1 if you have the `clock_getres' function. */
+#undef HAVE_CLOCK_GETRES
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
+/* define if the compiler supports const_cast<> */
+#undef HAVE_CONST_CAST
+
+/* Define to 1 if you have the `CryptGenRandom' function. */
+#undef HAVE_CRYPTGENRANDOM
+
+/* Define to 1 if you have the `ctime_r' function. */
+#undef HAVE_CTIME_R
+
+/* Define to 1 if you have the declaration of `pread', and to 0 if you don't.
+ */
+#undef HAVE_DECL_PREAD
+
+/* Define to 1 if you have the declaration of `pwrite', and to 0 if you don't.
+ */
+#undef HAVE_DECL_PWRITE
+
+/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you
+ don't. */
+#undef HAVE_DECL_STRLCPY
+
+/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_VSNPRINTF
+
+/* define if the compiler supports default template parameters */
+#undef HAVE_DEFAULT_TEMPLATE_PARAMETERS
+
+/* Have a /dev/urandom device for producing random bytes */
+#undef HAVE_DEV_URANDOM
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* define if the compiler supports exceptions */
+#undef HAVE_EXCEPTIONS
+
+/* define if the compiler supports the explicit keyword */
+#undef HAVE_EXPLICIT
+
+/* Define to 1 if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#undef HAVE_FSEEKO
+
+/* Define to 1 if you have the `fstatvfs' function. */
+#undef HAVE_FSTATVFS
+
+/* Define to 1 if you have the <ft2build.h> header file. */
+#undef HAVE_FT2BUILD_H
+
+/* Define to 1 if you have the `ftime' function. */
+#undef HAVE_FTIME
+
+/* Define to 1 if you have the `getc_unlocked' function. */
+#undef HAVE_GETC_UNLOCKED
+
+/* Define to 1 if you have the `getexecname' function. */
+#undef HAVE_GETEXECNAME
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getpid' function. */
+#undef HAVE_GETPID
+
+/* Define to 1 if you have the `getrlimit' function. */
+#undef HAVE_GETRLIMIT
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have the <lcms2.h> header file. */
+#undef HAVE_LCMS2_H
+
+/* Define if you have the <lcms2/lcms2.h> header file. */
+#undef HAVE_LCMS2_LCMS2_H
+
+/* Define to 1 if you have the `lltostr' function. */
+#undef HAVE_LLTOSTR
+
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define to 1 if the type `long double' works and has more range or precision
+ than `double'. */
+#undef HAVE_LONG_DOUBLE_WIDER
+
+/* Define to 1 if you have the <machine/param.h> header file. */
+#undef HAVE_MACHINE_PARAM_H
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+#undef HAVE_MACH_O_DYLD_H
+
+/* Define to 1 if you have the `madvise' function. */
+#undef HAVE_MADVISE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have a `mmap' system call which handles coherent file
+ I/O. */
+#undef HAVE_MMAP_FILEIO
+
+/* define if the compiler supports the mutable keyword */
+#undef HAVE_MUTABLE
+
+/* define if the compiler implements namespaces */
+#undef HAVE_NAMESPACES
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* define if the compiler accepts the new for scoping rules */
+#undef HAVE_NEW_FOR_SCOPING
+
+/* Define to 1 if you have the `pclose' function. */
+#undef HAVE_PCLOSE
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define to 1 if you have the `popen' function. */
+#undef HAVE_POPEN
+
+/* Define to 1 if you have the `posix_fadvise' function. */
+#undef HAVE_POSIX_FADVISE
+
+/* Define to 1 if you have the `posix_fallocate' function. */
+#undef HAVE_POSIX_FALLOCATE
+
+/* Define to 1 if you have the `posix_madvise' function. */
+#undef HAVE_POSIX_MADVISE
+
+/* Define to 1 if you have the `posix_memalign' function. */
+#undef HAVE_POSIX_MEMALIGN
+
+/* Define to 1 if you have the `posix_spawnp' function. */
+#undef HAVE_POSIX_SPAWNP
+
+/* Define to 1 if you have the `pread' function. */
+#undef HAVE_PREAD
+
+/* Define to 1 if you have the <process.h> header file. */
+#undef HAVE_PROCESS_H
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the `putc_unlocked' function. */
+#undef HAVE_PUTC_UNLOCKED
+
+/* Define to 1 if you have the `pwrite' function. */
+#undef HAVE_PWRITE
+
+/* Define to 1 if you have the `qsort_r' function. */
+#undef HAVE_QSORT_R
+
+/* Define to 1 if you have the `raise' function. */
+#undef HAVE_RAISE
+
+/* Define to 1 if you have the `rand_r' function. */
+#undef HAVE_RAND_R
+
+/* Define to 1 if you have the `readdir_r' function. */
+#undef HAVE_READDIR_R
+
+/* Define to 1 if you have the `readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
+/* Define to 1 if you have the `seekdir' function. */
+#undef HAVE_SEEKDIR
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the `setrlimit' function. */
+#undef HAVE_SETRLIMIT
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the `sigemptyset' function. */
+#undef HAVE_SIGEMPTYSET
+
+/* Define to 1 if you have the `spawnvp' function. */
+#undef HAVE_SPAWNVP
+
+/* define if the compiler supports static_cast<> */
+#undef HAVE_STATIC_CAST
+
+/* define if the compiler supports ISO C++ standard library */
+#undef HAVE_STD
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* define if the compiler supports Standard Template Library */
+#undef HAVE_STL
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strerror_r' function. */
+#undef HAVE_STRERROR_R
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlcat' function. */
+#undef HAVE_STRLCAT
+
+/* Define to 1 if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define to 1 if you have the <sun_prefetch.h> header file. */
+#undef HAVE_SUN_PREFETCH_H
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the `telldir' function. */
+#undef HAVE_TELLDIR
+
+/* define if the compiler supports basic templates */
+#undef HAVE_TEMPLATES
+
+/* Define to 1 if you have the <tiffconf.h> header file. */
+#undef HAVE_TIFFCONF_H
+
+/* Define to 1 if you have the `TIFFIsCODECConfigured' function. */
+#undef HAVE_TIFFISCODECCONFIGURED
+
+/* Define to 1 if you have the `TIFFMergeFieldInfo' function. */
+#undef HAVE_TIFFMERGEFIELDINFO
+
+/* Define to 1 if you have the `TIFFSetErrorHandlerExt' function. */
+#undef HAVE_TIFFSETERRORHANDLEREXT
+
+/* Define to 1 if you have the `TIFFSetTagExtender' function. */
+#undef HAVE_TIFFSETTAGEXTENDER
+
+/* Define to 1 if you have the `TIFFSetWarningHandlerExt' function. */
+#undef HAVE_TIFFSETWARNINGHANDLEREXT
+
+/* Define to 1 if you have the `TIFFSwabArrayOfTriples' function. */
+#undef HAVE_TIFFSWABARRAYOFTRIPLES
+
+/* Define to 1 if you have the `times' function. */
+#undef HAVE_TIMES
+
+/* Define to 1 if you have the `ulltostr' function. */
+#undef HAVE_ULLTOSTR
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the `vsprintf' function. */
+#undef HAVE_VSPRINTF
+
+/* Define to 1 if you have the <wincrypt.h> header file. */
+#undef HAVE_WINCRYPT_H
+
+/* Define to 1 if you have the `_exit' function. */
+#undef HAVE__EXIT
+
+/* Define to 1 if you have the `_NSGetExecutablePath' function. */
+#undef HAVE__NSGETEXECUTABLEPATH
+
+/* Define to 1 if you have the `_pclose' function. */
+#undef HAVE__PCLOSE
+
+/* Define to 1 if you have the `_popen' function. */
+#undef HAVE__POPEN
+
+/* Define if you have the bzip2 library */
+#undef HasBZLIB
+
+/* Define if you have Display Postscript */
+#undef HasDPS
+
+/* Define if you have FlashPIX library */
+#undef HasFPX
+
+/* Define if you have Ghostscript library */
+#undef HasGS
+
+/* Define if you have JBIG library */
+#undef HasJBIG
+
+/* Define if you have JPEG version 2 "Jasper" library */
+#undef HasJP2
+
+/* Define if you have JPEG library */
+#undef HasJPEG
+
+/* Define if you have LCMS (v2.0 or later) library */
+#undef HasLCMS
+
+/* Define if using libltdl to support dynamically loadable modules */
+#undef HasLTDL
+
+/* Define if you have lzma compression library */
+#undef HasLZMA
+
+/* Define if you have PNG library */
+#undef HasPNG
+
+/* X11 server supports shape extension */
+#undef HasShape
+
+/* X11 server supports shared memory extension */
+#undef HasSharedMemory
+
+/* Define if you have TIFF library */
+#undef HasTIFF
+
+/* Define if you have TRIO vsnprintf replacement library */
+#undef HasTRIO
+
+/* Define if you have FreeType (TrueType font) library */
+#undef HasTTF
+
+/* Define if you have umem memory allocation library */
+#undef HasUMEM
+
+/* Define if you have WEBP library */
+#undef HasWEBP
+
+/* Define to use the Windows GDI32 library */
+#undef HasWINGDI32
+
+/* Define if you have wmflite library */
+#undef HasWMFlite
+
+/* Define if you have X11 library */
+#undef HasX11
+
+/* Define if you have XML library */
+#undef HasXML
+
+/* Define if you have zlib compression library */
+#undef HasZLIB
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Define to prepend to default font search path. */
+#undef MAGICK_FONT_PATH
+
+/* Command which returns total physical memory in bytes */
+#undef MAGICK_PHYSICAL_MEMORY_COMMAND
+
+/* Target Host CPU */
+#undef MAGICK_TARGET_CPU
+
+/* Target Host OS */
+#undef MAGICK_TARGET_OS
+
+/* Target Host Vendor */
+#undef MAGICK_TARGET_VENDOR
+
+/* define if the compiler lacks ios::binary */
+#undef MISSING_STD_IOS_BINARY
+
+/* Directory where executables are installed. */
+#undef MagickBinPath
+
+/* Location of coder modules */
+#undef MagickCoderModulesPath
+
+/* Subdirectory of lib where coder modules are installed */
+#undef MagickCoderModulesSubdir
+
+/* Location of filter modules */
+#undef MagickFilterModulesPath
+
+/* Subdirectory of lib where filter modules are installed */
+#undef MagickFilterModulesSubdir
+
+/* Directory where architecture-dependent configuration files live. */
+#undef MagickLibConfigPath
+
+/* Subdirectory of lib where architecture-dependent configuration files live.
+ */
+#undef MagickLibConfigSubDir
+
+/* Directory where architecture-dependent files live. */
+#undef MagickLibPath
+
+/* Subdirectory of lib where GraphicsMagick architecture dependent files are
+ installed */
+#undef MagickLibSubdir
+
+/* Directory where architecture-independent configuration files live. */
+#undef MagickShareConfigPath
+
+/* Subdirectory of lib where architecture-independent configuration files
+ live. */
+#undef MagickShareConfigSubDir
+
+/* Directory where architecture-independent files live. */
+#undef MagickSharePath
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Prefix Magick library symbols with a common string. */
+#undef PREFIX_MAGICK_SYMBOLS
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Number of bits in a pixel Quantum (8/16/32) */
+#undef QuantumDepth
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* The size of `off_t', as computed by sizeof. */
+#undef SIZEOF_OFF_T
+
+/* The size of `signed int', as computed by sizeof. */
+#undef SIZEOF_SIGNED_INT
+
+/* The size of `signed long', as computed by sizeof. */
+#undef SIZEOF_SIGNED_LONG
+
+/* The size of `signed long long', as computed by sizeof. */
+#undef SIZEOF_SIGNED_LONG_LONG
+
+/* The size of `signed short', as computed by sizeof. */
+#undef SIZEOF_SIGNED_SHORT
+
+/* The size of `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The size of `unsigned int', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The size of `unsigned int*', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_INTP
+
+/* The size of `unsigned long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The size of `unsigned long long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG_LONG
+
+/* The size of `unsigned short', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_SHORT
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* GraphicsMagick is formally installed under prefix */
+#undef UseInstalledMagick
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Location of X11 configure files */
+#undef X11ConfigurePath
+
+/* Define to 1 if the X Window System is missing or not being used. */
+#undef X_DISPLAY_MISSING
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#undef _LARGEFILE_SOURCE
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to 1 if type `char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+# undef __CHAR_UNSIGNED__
+#endif
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
+/* Define to `long int' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to the equivalent of the C99 'restrict' keyword, or to
+ nothing if this is not supported. Do not define if restrict is
+ supported directly. */
+#undef restrict
+/* Work around a bug in Sun C++: it does not support _Restrict or
+ __restrict__, even though the corresponding Sun C compiler ends up with
+ "#define restrict _Restrict" or "#define restrict __restrict__" in the
+ previous line. Perhaps some future version of Sun C++ will work with
+ restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
+#if defined __SUNPRO_CC && !defined __RESTRICT
+# define _Restrict
+# define __restrict__
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
diff --git a/magick/magick_config_api.h.in b/magick/magick_config_api.h.in
new file mode 100644
index 0000000..1579354
--- /dev/null
+++ b/magick/magick_config_api.h.in
@@ -0,0 +1,20 @@
+/* Defines required by <magick/api.h> */
+
+/* Define if you have X11 library */
+#undef HasX11
+
+/* Number of bits in a pixel Quantum (8/16/32) */
+#undef QuantumDepth
+
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Prefix Magick library symbols with a common string. */
+#undef PREFIX_MAGICK_SYMBOLS
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
diff --git a/magick/magick_endian.c b/magick/magick_endian.c
new file mode 100644
index 0000000..508c28f
--- /dev/null
+++ b/magick/magick_endian.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "magick/studio.h"
+#include "magick/magick_endian.h"
+
+MagickExport void
+MagickSwabUInt16(magick_uint16_t* wp)
+{
+ register unsigned char* cp = (unsigned char*) wp;
+ unsigned char t;
+
+ t = cp[1]; cp[1] = cp[0]; cp[0] = t;
+}
+
+MagickExport void
+MagickSwabUInt32(magick_uint32_t* lp)
+{
+ register unsigned char* cp = (unsigned char*) lp;
+ unsigned char t;
+
+ t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+ t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+}
+
+MagickExport void
+MagickSwabArrayOfUInt16(magick_uint16_t* wp, register size_t n)
+{
+ register unsigned char* cp;
+ register unsigned char t;
+
+ while (n-- > 0) {
+ cp = (unsigned char*) wp;
+ t = cp[1]; cp[1] = cp[0]; cp[0] = t;
+ wp++;
+ }
+}
+
+MagickExport void
+MagickSwabArrayOfUInt32(register magick_uint32_t* lp, register size_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+
+ while (n-- > 0) {
+ cp = (unsigned char *)lp;
+ t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+ t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+ lp++;
+ }
+}
+
+MagickExport void
+MagickSwabFloat(float *fp)
+{
+ MagickSwabUInt32((magick_uint32_t *) fp);
+}
+
+MagickExport void
+MagickSwabArrayOfFloat(float *fp, size_t n)
+{
+ MagickSwabArrayOfUInt32((magick_uint32_t *) fp, n);
+}
+
+MagickExport void
+MagickSwabDouble(double *dp)
+{
+ register magick_uint32_t* lp = (magick_uint32_t*) dp;
+ magick_uint32_t t;
+
+ MagickSwabArrayOfUInt32(lp, 2);
+ t = lp[0]; lp[0] = lp[1]; lp[1] = t;
+}
+
+MagickExport void
+MagickSwabArrayOfDouble(double* dp, register size_t n)
+{
+ register magick_uint32_t* lp = (magick_uint32_t*) dp;
+ register magick_uint32_t t;
+
+ MagickSwabArrayOfUInt32(lp, n + n);
+ while (n-- > 0) {
+ t = lp[0]; lp[0] = lp[1]; lp[1] = t;
+ lp += 2;
+ }
+}
+
+/*
+ * Bit reversal tables. MagickBitRevTable[<byte>] gives
+ * the bit reversed value of <byte>. Used in various
+ * places in the library when the FillOrder requires
+ * bit reversal of byte values (e.g. CCITT Fax 3
+ * encoding/decoding). MagickNoBitRevTable is provided
+ * for algorithms that want an equivalent table that
+ * do not reverse bit values.
+ */
+static const unsigned char MagickBitRevTable[256] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+static const unsigned char MagickNoBitRevTable[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+
+MagickExport const unsigned char*
+MagickGetBitRevTable(int reversed)
+{
+ return (reversed ? MagickBitRevTable : MagickNoBitRevTable);
+}
+
+MagickExport void
+MagickReverseBits(register unsigned char* cp, register size_t n)
+{
+ for (; n > 8; n -= 8) {
+ cp[0] = MagickBitRevTable[cp[0]];
+ cp[1] = MagickBitRevTable[cp[1]];
+ cp[2] = MagickBitRevTable[cp[2]];
+ cp[3] = MagickBitRevTable[cp[3]];
+ cp[4] = MagickBitRevTable[cp[4]];
+ cp[5] = MagickBitRevTable[cp[5]];
+ cp[6] = MagickBitRevTable[cp[6]];
+ cp[7] = MagickBitRevTable[cp[7]];
+ cp += 8;
+ }
+ while (n-- > 0)
+ *cp = MagickBitRevTable[*cp], cp++;
+}
diff --git a/magick/magick_endian.h b/magick/magick_endian.h
new file mode 100644
index 0000000..fb0a6e0
--- /dev/null
+++ b/magick/magick_endian.h
@@ -0,0 +1,30 @@
+/*
+ Copyright (C) 2005 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Word-swapping functions.
+*/
+extern MagickExport void
+ MagickReverseBits(unsigned char *cp, size_t n),
+ MagickSwabArrayOfDouble(double *dp, size_t n),
+ MagickSwabArrayOfFloat(float *fp, size_t n),
+ MagickSwabArrayOfUInt16(magick_uint16_t *wp, size_t n),
+ MagickSwabArrayOfUInt32(magick_uint32_t *lp, size_t n),
+ MagickSwabDouble(double *dp),
+ MagickSwabFloat(float *fp),
+ MagickSwabUInt16(magick_uint16_t *wp),
+ MagickSwabUInt32(magick_uint32_t *lp);
+
+extern MagickExport const unsigned char
+ *MagickGetBitRevTable(int);
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/magick_types.h b/magick/magick_types.h
new file mode 100644
index 0000000..cab7550
--- /dev/null
+++ b/magick/magick_types.h
@@ -0,0 +1,133 @@
+/*
+ Copyright (C) 2003 - 2013 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick types typedefs.
+
+ GraphicsMagick is expected to compile with any C '89 ANSI C compiler
+ supporting at least 16-bit 'short', 32-bit 'int', and 32-bit 'long'.
+ It is also expected to take advantage of 64-bit LP64 and Windows
+ WIN64 LLP64. We use C '99 style types but declare our own types so
+ as to not depend on C '99 header files, and take care to depend only
+ on C '89 library functions, POSIX, or well-known extensions. Any C
+ '99 syntax used is removed if the compiler does not support it.
+*/
+
+#ifndef _MAGICK_TYPES_H
+#define _MAGICK_TYPES_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Assign ANSI C stdint.h-like typedefs based on the sizes of native types
+ magick_int8_t -- -128 to 127
+ magick_uint8_t -- 0 to 255
+ magick_int16_t -- -32,768 to 32,767
+ magick_uint16_t -- 0 to 65,535
+ magick_int32_t -- -2,147,483,648 to 2,147,483,647
+ magick_uint32_t -- 0 to 4,294,967,295
+ magick_int64_t -- -9,223,372,036,854,775,807 to 9,223,372,036,854,775,807
+ magick_uint64_t -- 0 to 18,446,744,073,709,551,615
+
+ magick_uintmax_t -- largest native unsigned integer type ("%ju")
+ 0 to UINTMAX_MAX
+ UINTMAX_C(value) declares constant value
+ magick_uintptr_t -- unsigned type for storing a pointer value ("%tu")
+ 0 to UINTPTR_MAX
+
+ ANSI C '99 stddef.h-like types
+ size_t -- unsigned type representing sizes of objects ("%zu")
+ 0 to SIZE_MAX
+ magick_ptrdiff_t -- signed type for subtracting two pointers ("%td")
+ PTRDIFF_MIN to PTRDIFF_MAX
+
+ EEE Std 1003.1, 2004 types
+ ssize_t -- signed type for a count of bytes or an error indication ("%zd")
+ ? to SSIZE_MAX
+*/
+
+#if (defined(WIN32) || defined(WIN64)) && \
+ !defined(__MINGW32__) && !defined(__MINGW64__)
+
+ /* The following typedefs are used for WIN32 & WIN64 (without
+ configure) */
+ typedef signed char magick_int8_t;
+ typedef unsigned char magick_uint8_t;
+
+ typedef signed short magick_int16_t;
+ typedef unsigned short magick_uint16_t;
+
+ typedef signed int magick_int32_t;
+# define MAGICK_INT32_F ""
+ typedef unsigned int magick_uint32_t;
+# define MAGICK_UINT32_F ""
+
+ typedef signed __int64 magick_int64_t;
+# define MAGICK_INT64_F "I64"
+ typedef unsigned __int64 magick_uint64_t;
+# define MAGICK_UINT64_F "I64"
+
+ typedef magick_uint64_t magick_uintmax_t;
+
+# if defined(WIN64)
+ /* WIN64 uses the LLP64 model */
+ typedef unsigned long long magick_uintptr_t;
+# define MAGICK_SIZE_T_F "I64"
+# define MAGICK_SIZE_T unsigned __int64
+# define MAGICK_SSIZE_T_F "I64"
+# define MAGICK_SSIZE_T signed __int64
+# else
+ typedef unsigned long magick_uintptr_t;
+# define MAGICK_SIZE_T_F "l"
+# define MAGICK_SIZE_T unsigned long
+# define MAGICK_SSIZE_T_F "l"
+# define MAGICK_SSIZE_T long
+# endif // defined(WIN64)
+
+#else
+
+ /* The following typedefs are subtituted when using Unixish configure */
+ typedef signed char magick_int8_t;
+ typedef unsigned char magick_uint8_t;
+
+ typedef signed short magick_int16_t;
+ typedef unsigned short magick_uint16_t;
+
+ typedef signed int magick_int32_t;
+# define MAGICK_INT32_F ""
+ typedef unsigned int magick_uint32_t;
+# define MAGICK_UINT32_F ""
+
+ typedef signed long magick_int64_t;
+# define MAGICK_INT64_F "l"
+ typedef unsigned long magick_uint64_t;
+# define MAGICK_UINT64_F "l"
+
+ typedef unsigned long magick_uintmax_t;
+# define MAGICK_UINTMAX_F "l"
+
+ typedef unsigned long magick_uintptr_t;
+# define MAGICK_UINTPTR_F "l"
+
+# define MAGICK_SIZE_T_F "l"
+# define MAGICK_SIZE_T unsigned long
+
+# define MAGICK_SSIZE_T_F "l"
+# define MAGICK_SSIZE_T signed long
+
+#endif
+
+ /* 64-bit file and blob offset type */
+ typedef magick_int64_t magick_off_t;
+#define MAGICK_OFF_F MAGICK_INT64_F
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_TYPES_H */
diff --git a/magick/magick_types.h.in b/magick/magick_types.h.in
new file mode 100644
index 0000000..1f24a58
--- /dev/null
+++ b/magick/magick_types.h.in
@@ -0,0 +1,133 @@
+/*
+ Copyright (C) 2003 - 2013 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick types typedefs.
+
+ GraphicsMagick is expected to compile with any C '89 ANSI C compiler
+ supporting at least 16-bit 'short', 32-bit 'int', and 32-bit 'long'.
+ It is also expected to take advantage of 64-bit LP64 and Windows
+ WIN64 LLP64. We use C '99 style types but declare our own types so
+ as to not depend on C '99 header files, and take care to depend only
+ on C '89 library functions, POSIX, or well-known extensions. Any C
+ '99 syntax used is removed if the compiler does not support it.
+*/
+
+#ifndef _MAGICK_TYPES_H
+#define _MAGICK_TYPES_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Assign ANSI C stdint.h-like typedefs based on the sizes of native types
+ magick_int8_t -- -128 to 127
+ magick_uint8_t -- 0 to 255
+ magick_int16_t -- -32,768 to 32,767
+ magick_uint16_t -- 0 to 65,535
+ magick_int32_t -- -2,147,483,648 to 2,147,483,647
+ magick_uint32_t -- 0 to 4,294,967,295
+ magick_int64_t -- -9,223,372,036,854,775,807 to 9,223,372,036,854,775,807
+ magick_uint64_t -- 0 to 18,446,744,073,709,551,615
+
+ magick_uintmax_t -- largest native unsigned integer type ("%ju")
+ 0 to UINTMAX_MAX
+ UINTMAX_C(value) declares constant value
+ magick_uintptr_t -- unsigned type for storing a pointer value ("%tu")
+ 0 to UINTPTR_MAX
+
+ ANSI C '99 stddef.h-like types
+ size_t -- unsigned type representing sizes of objects ("%zu")
+ 0 to SIZE_MAX
+ magick_ptrdiff_t -- signed type for subtracting two pointers ("%td")
+ PTRDIFF_MIN to PTRDIFF_MAX
+
+ EEE Std 1003.1, 2004 types
+ ssize_t -- signed type for a count of bytes or an error indication ("%zd")
+ ? to SSIZE_MAX
+*/
+
+#if (defined(WIN32) || defined(WIN64)) && \
+ !defined(__MINGW32__) && !defined(__MINGW64__)
+
+ /* The following typedefs are used for WIN32 & WIN64 (without
+ configure) */
+ typedef signed char magick_int8_t;
+ typedef unsigned char magick_uint8_t;
+
+ typedef signed short magick_int16_t;
+ typedef unsigned short magick_uint16_t;
+
+ typedef signed int magick_int32_t;
+# define MAGICK_INT32_F ""
+ typedef unsigned int magick_uint32_t;
+# define MAGICK_UINT32_F ""
+
+ typedef signed __int64 magick_int64_t;
+# define MAGICK_INT64_F "I64"
+ typedef unsigned __int64 magick_uint64_t;
+# define MAGICK_UINT64_F "I64"
+
+ typedef magick_uint64_t magick_uintmax_t;
+
+# if defined(WIN64)
+ /* WIN64 uses the LLP64 model */
+ typedef unsigned long long magick_uintptr_t;
+# define MAGICK_SIZE_T_F "I64"
+# define MAGICK_SIZE_T unsigned __int64
+# define MAGICK_SSIZE_T_F "I64"
+# define MAGICK_SSIZE_T signed __int64
+# else
+ typedef unsigned long magick_uintptr_t;
+# define MAGICK_SIZE_T_F "l"
+# define MAGICK_SIZE_T unsigned long
+# define MAGICK_SSIZE_T_F "l"
+# define MAGICK_SSIZE_T long
+# endif // defined(WIN64)
+
+#else
+
+ /* The following typedefs are subtituted when using Unixish configure */
+ typedef @INT8_T@ magick_int8_t;
+ typedef @UINT8_T@ magick_uint8_t;
+
+ typedef @INT16_T@ magick_int16_t;
+ typedef @UINT16_T@ magick_uint16_t;
+
+ typedef @INT32_T@ magick_int32_t;
+# define MAGICK_INT32_F @INT32_F@
+ typedef @UINT32_T@ magick_uint32_t;
+# define MAGICK_UINT32_F @UINT32_F@
+
+ typedef @INT64_T@ magick_int64_t;
+# define MAGICK_INT64_F @INT64_F@
+ typedef @UINT64_T@ magick_uint64_t;
+# define MAGICK_UINT64_F @UINT64_F@
+
+ typedef @UINTMAX_T@ magick_uintmax_t;
+# define MAGICK_UINTMAX_F @UINTMAX_F@
+
+ typedef @UINTPTR_T@ magick_uintptr_t;
+# define MAGICK_UINTPTR_F @UINTPTR_F@
+
+# define MAGICK_SIZE_T_F @MAGICK_SIZE_T_F@
+# define MAGICK_SIZE_T @MAGICK_SIZE_T@
+
+# define MAGICK_SSIZE_T_F @MAGICK_SSIZE_T_F@
+# define MAGICK_SSIZE_T @MAGICK_SSIZE_T@
+
+#endif
+
+ /* 64-bit file and blob offset type */
+ typedef magick_int64_t magick_off_t;
+#define MAGICK_OFF_F MAGICK_INT64_F
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_TYPES_H */
diff --git a/magick/map.c b/magick/map.c
new file mode 100644
index 0000000..633642b
--- /dev/null
+++ b/magick/map.c
@@ -0,0 +1,1180 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% Key,value associative map interface
+% Written by Bob Friesenhahn, September 2003
+%
+*/
+
+#include "magick/studio.h"
+#include "magick/map.h"
+#include "magick/utility.h"
+#include "magick/semaphore.h"
+
+/*
+ Structure to represent a contained object
+*/
+typedef struct _MagickMapObject
+{
+ /* Object key value */
+ char
+ *key;
+
+ /* Pointer to stored object */
+ void
+ *object;
+
+ /* Object size. Optional. May be set to zero depending on needs of
+ object type */
+ size_t
+ object_size;
+
+ /* Function which clones (copies) contained objects */
+ MagickMapObjectClone
+ clone_function;
+
+ /* Function which deallocates contained object */
+ MagickMapObjectDeallocator
+ deallocate_function;
+
+ /* Number of references to this object. */
+ long
+ reference_count;
+
+ struct _MagickMapObject
+ *previous,
+ *next;
+
+ unsigned long
+ signature;
+
+} MagickMapObject;
+
+/*
+ Structure to act as the user handle to a key,value map
+*/
+typedef struct _MagickMapHandle
+{
+ /* Function which clones (copies) contained objects */
+ MagickMapObjectClone
+ clone_function;
+
+ /* Function which deallocates contained object */
+ MagickMapObjectDeallocator
+ deallocate_function;
+
+ /* Global semaphore for all operations pertaining to this map */
+ SemaphoreInfo
+ *semaphore;
+
+ /* Number of references to this object. */
+ long
+ reference_count;
+
+ MagickMapObject
+ *list;
+
+ unsigned long
+ signature;
+
+} MagickMapHandle;
+
+/*
+ Iterator position. Used to manage iterator state.
+*/
+typedef enum
+{
+ InListPosition,
+ FrontPosition,
+ BackPosition
+} MagickMapIteratorPosition;
+
+/*
+ Structure to act as a map iterator
+*/
+typedef struct _MagickMapIteratorHandle
+{
+ /* Pointer to base map */
+ MagickMap
+ map;
+
+ /* Pointer to member of map */
+ const MagickMapObject
+ *member;
+
+ /* Iterator position */
+ MagickMapIteratorPosition
+ position;
+
+ unsigned long
+ signature;
+} MagickMapIteratorHandle;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p A l l o c a t e O b j e c t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapAllocateObject() allocates a new object for inclusion in
+% the map.
+%
+% The format of the MagickMapAllocateObject method is:
+%
+% MagickMapObject *MagickMapAllocateObject(const char *key,
+% const void *object, const size_t object_size,
+% MagickMapObjectClone clone, MagickMapObjectDeallocator deallocate)
+%
+% A description of each parameter follows:
+%
+% o key: object unique key.
+%
+% o object: Object value
+%
+% o object_size: Object size. Optional. May be set to zero if the
+% object size is known through some other means.
+%
+% o clone: function to create a copy of this object type.
+%
+% o deallocate: function to deallocate this object type.
+%
+*/
+static MagickMapObject *
+MagickMapAllocateObject(const char *key, const void *object,
+ const size_t object_size, MagickMapObjectClone clone,
+ MagickMapObjectDeallocator deallocate)
+{
+ MagickMapObject *
+ map_object;
+
+ assert(key != 0);
+ assert(object != 0);
+ assert(clone != 0);
+ assert(deallocate != 0);
+
+ map_object=MagickAllocateMemory(MagickMapObject *,sizeof(MagickMapObject));
+ if (map_object)
+ {
+ map_object->key=AcquireString(key);
+ map_object->object=(clone)(object,object_size);
+ map_object->object_size=object_size;
+ map_object->clone_function=clone;
+ map_object->deallocate_function=deallocate;
+ map_object->reference_count=1;
+ map_object->previous=0;
+ map_object->next=0;
+ map_object->signature=MagickSignature;
+ }
+
+ return map_object;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p D e s t r o y O b j e c t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapDestroyObject deallocates a map object by invoking the
+% object's embedded deallocation function.
+%
+% The format of the MagickMapDestroyObject method is:
+%
+% void MagickMapDestroyObject(MagickMapObject *object)
+%
+% A description of each parameter follows:
+%
+% o object: Pointer to object to destroy.
+%
+*/
+static void
+MagickMapDestroyObject(MagickMapObject *object)
+{
+ assert(object != 0);
+ assert(object->signature == MagickSignature);
+
+ object->reference_count--;
+ assert(object->reference_count == 0);
+
+ MagickFreeMemory(object->key);
+ (object->deallocate_function)(object->object);
+
+ (void) memset((void *)object,0xbf,sizeof(MagickMapObject));
+ MagickFreeMemory(object);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p A c c e s s E n t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapAccessEntry() searches for an object in the map identified
+% by the specified key. If a matching object is found, then a const
+% pointer to the object data is returned, and the object_size
+% argument is updated with the object size. Null is returned if no
+% matching object is found.
+%
+% An object is not required to contain a size so object_size may be
+% updated to zero. If the object size is known to not be required by
+% this object type, then a null object_size pointer may be passed.
+%
+% The format of the MagickMapAccessEntry method is:
+%
+% const void *MagickMapAccessEntry(MagickMap map,const char *key,
+% size_t *object_size)
+%
+% A description of each parameter follows:
+%
+% o map: map context
+%
+% o key: unique key to match
+%
+% o object_size: Pointer to where object size is to be saved.
+%
+*/
+MagickExport const void *
+MagickMapAccessEntry(MagickMap map,const char *key, size_t *object_size)
+{
+ MagickMapObject
+ *p;
+
+ assert(map != 0);
+ assert(map->signature == MagickSignature);
+ assert(key != 0);
+
+ if (object_size)
+ *object_size=0;
+
+ (void) LockSemaphoreInfo(map->semaphore);
+
+ for (p=map->list; p != 0; p=p->next)
+ if (LocaleCompare(key,p->key) == 0)
+ {
+ if (object_size)
+ *object_size=p->object_size;
+ (void) UnlockSemaphoreInfo(map->semaphore);
+ return(p->object);
+ }
+
+ (void) UnlockSemaphoreInfo(map->semaphore);
+
+ return 0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p A d d E n t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapAddEntry() adds a new entry to a map, or replaces an existing
+% matching entry. True is returned on success. If False is returned, then
+% the exception argument describes the reason for failure.
+%
+% The format of the MagickMapAddEntry method is:
+%
+% void MagickMapAddEntry(MagickMap map,const char *key,
+% const void *object, const size_t object_size)
+%
+% A description of each parameter follows:
+%
+% o map: map context
+%
+% o key: unique key
+%
+% o object: pointer to object data to copy.
+%
+% o object_size: size of object data. If the copy function does not
+% require the object size, then the value zero may be used.
+%
+% o exception: check this argument for error information if False is
+% returned.
+%
+*/
+MagickExport unsigned int
+MagickMapAddEntry(MagickMap map,const char *key, const void *object,
+ const size_t object_size, ExceptionInfo *exception)
+{
+ MagickMapObject
+ *new_object;
+
+ assert(map != 0);
+ assert(map->signature == MagickSignature);
+ assert(key != 0);
+ assert(object != 0);
+
+ new_object=MagickMapAllocateObject(key, object, object_size,
+ map->clone_function,
+ map->deallocate_function);
+
+ if (!new_object)
+ {
+ if (exception)
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ NULL);
+ return (False);
+ }
+
+ (void) LockSemaphoreInfo(map->semaphore);
+
+ if (!map->list)
+ {
+ /*
+ If list is empty, object becomes new list.
+ */
+ map->list=new_object;
+ }
+ else
+ {
+ MagickMapObject
+ *last_object=0,
+ *p;
+
+ MagickBool
+ spliced_in=MagickFalse;
+
+ /*
+ Search for, and replace any existing object with
+ same key.
+ */
+
+ for (p=map->list; p != 0; p=p->next)
+ {
+ last_object=p;
+ if (LocaleCompare(key,p->key) == 0)
+ {
+ /*
+ Splice in new object
+ */
+ new_object->previous=p->previous;
+ new_object->next=p->next;
+ if (new_object->previous)
+ new_object->previous->next=new_object;
+ if (new_object->next)
+ new_object->next->previous=new_object;
+ if (map->list == p)
+ map->list=new_object;
+ p->previous=0;
+ p->next=0;
+ spliced_in=MagickTrue;
+
+ /*
+ Remove old object
+ */
+ MagickMapDestroyObject(p);
+ break;
+ }
+ }
+
+ if (!spliced_in)
+ {
+ /*
+ No existing matching object was found. The last_object
+ pointer points to the last object in the list. Append new
+ object to end of list.
+ */
+ new_object->previous=last_object;
+ last_object->next=new_object;
+ }
+ }
+
+ (void) UnlockSemaphoreInfo(map->semaphore);
+
+ return (True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p A l l o c a t e M a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapAllocateMap() allocates a new map context. The address of
+% the functions required to copy and deallocate contained object data
+% are provided when the map context is constructed. Objects contained
+% in a map are all of the same type. A null map context is returned if
+% the map construction fails.
+%
+% The format of the MagickMapAllocateMap method is:
+%
+% MagickMap MagickMapAllocateMap(MagickMapObjectClone clone,
+% MagickMapObjectDeallocator deallocate)
+%
+% A description of each parameter follows:
+%
+% o clone: Pointer to function which copies contained object data.
+%
+% o deallocate: Pointer to function which deallocates contained object
+% data.
+%
+*/
+MagickExport MagickMap
+MagickMapAllocateMap(MagickMapObjectClone clone,
+ MagickMapObjectDeallocator deallocate)
+{
+ MagickMap
+ map;
+
+ assert(clone != 0);
+ assert(deallocate != 0);
+
+ map=MagickAllocateMemory(MagickMap,sizeof(MagickMapHandle));
+ if (map)
+ {
+ map->clone_function=clone;
+ map->deallocate_function=deallocate;
+ map->semaphore=AllocateSemaphoreInfo();
+ (void) LockSemaphoreInfo(map->semaphore);
+ map->reference_count=1;
+ map->list=0;
+ (void) UnlockSemaphoreInfo(map->semaphore);
+ map->signature=MagickSignature;
+ }
+
+ return map;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p C l o n e M a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapCloneMap() duplicates an existing map. If the duplication fails,
+% zero is returned and the error argument is updated.
+%
+% The format of the MagickMapCloneMap method is:
+%
+% MagickMap MagickMapCloneMap(MagickMap map)
+%
+% A description of each parameter follows:
+%
+% o map: map context to duplicate
+%
+% o exception: check this structure for error details if null is returned.
+%
+*/
+MagickExport MagickMap
+MagickMapCloneMap(MagickMap map,ExceptionInfo *exception)
+{
+ MagickMap map_clone;
+ MagickMapIterator iterator;
+ size_t size;
+ const char *key;
+
+ assert(map != 0);
+ assert(map->signature == MagickSignature);
+
+ /*
+ Don't lock. Iterator locks the map. PTHREADS doesn't
+ allow one thread multiple locks on one semaphore.
+ */
+ /* LockSemaphoreInfo(map->semaphore); */
+
+ map_clone=MagickMapAllocateMap(map->clone_function,map->deallocate_function);
+ iterator=MagickMapAllocateIterator(map);
+ while(MagickMapIterateNext(iterator,&key))
+ {
+ const void *object=MagickMapDereferenceIterator(iterator,&size);
+ /* Add clones key and object on insertion */
+ if (MagickMapAddEntry(map_clone,key,object,size,exception) == False)
+ {
+ MagickMapDeallocateIterator(iterator);
+ MagickMapDeallocateMap(map_clone);
+ return 0;
+ }
+ }
+ MagickMapDeallocateIterator(iterator);
+
+ return map_clone;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p C l e a r M a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapClearMap() removes all entries from a map. The deallocator
+% function for each contained object is invoked when it is removed.
+%
+% The format of the MagickMapClearMap method is:
+%
+% void MagickMapClearMap(MagickMap map)
+%
+% A description of each parameter follows:
+%
+% o map: map context to clear
+%
+*/
+MagickExport void
+MagickMapClearMap(MagickMap map)
+{
+ assert(map != 0);
+ assert(map->signature == MagickSignature);
+
+ (void) LockSemaphoreInfo(map->semaphore);
+ if (map->list)
+ {
+ register MagickMapObject
+ *current,
+ *p;
+
+ for (p=map->list; p != 0; )
+ {
+ current=p;
+ p=p->next;
+ MagickMapDestroyObject(current);
+ }
+ map->list=0;
+ }
+ (void) UnlockSemaphoreInfo(map->semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p A l l o c a t e I t e r a t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapAllocateIterator allocates an iterator which may be used to
+% traverse all the entries in the map. The iterator initially points to
+% the front of the map.
+%
+% The format of the MagickMapAllocateIterator method is:
+%
+% MagickMapIterator MagickMapAllocateIterator(MagickMap map)
+%
+% A description of each parameter follows:
+%
+% o map: map context
+%
+*/
+MagickExport MagickMapIterator
+MagickMapAllocateIterator(MagickMap map)
+{
+ MagickMapIterator
+ iterator;
+
+ assert(map != 0);
+ assert(map->signature == MagickSignature);
+
+ LockSemaphoreInfo(map->semaphore);
+
+ iterator=MagickAllocateMemory(MagickMapIterator,
+ sizeof(MagickMapIteratorHandle));
+ if (iterator)
+ {
+ iterator->map=map;
+ iterator->member=0;
+ iterator->position=FrontPosition;
+ iterator->map->reference_count++;
+ iterator->signature=MagickSignature;
+ }
+
+ UnlockSemaphoreInfo(map->semaphore);
+
+ return iterator;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p D e a l l o c a t e M a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapDeallocateMap() deallocates a map, invoking the map deallocation
+% function on each entry contained in the map.
+%
+% The format of the MagickMapDeallocateMap method is:
+%
+% void MagickMapDeallocateMap(MagickMap map)
+%
+% A description of each parameter follows:
+%
+% o map: map context to destroy
+%
+*/
+MagickExport void
+MagickMapDeallocateMap(MagickMap map)
+{
+ assert(map != 0);
+ assert(map->signature == MagickSignature);
+
+ (void) LockSemaphoreInfo(map->semaphore);
+
+ map->reference_count--;
+
+ /* For the moment, do not allow outstanding references */
+ assert(map->reference_count == 0);
+
+ if (map->list)
+ {
+ register MagickMapObject
+ *current,
+ *p;
+
+ for (p=map->list; p != 0; )
+ {
+ current=p;
+ p=p->next;
+ MagickMapDestroyObject(current);
+ }
+ }
+
+ (void) UnlockSemaphoreInfo(map->semaphore);
+ DestroySemaphoreInfo(&map->semaphore);
+
+ (void) memset((void *)map,0xbf,sizeof(MagickMapHandle));
+ MagickFreeMemory(map);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p D e a l l o c a t e I t e r a t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapDeallocateIterator() deallocates a map iterator
+%
+% The format of the MagickMapDeallocateIterator method is:
+%
+% void MagickMapDeallocateIterator(MagickMapIterator iterator)
+%
+% A description of each parameter follows:
+%
+% o iterator: iterator context to destroy
+%
+*/
+MagickExport void
+MagickMapDeallocateIterator(MagickMapIterator iterator)
+{
+ assert(iterator != 0);
+ assert(iterator->signature == MagickSignature);
+
+ (void) LockSemaphoreInfo(iterator->map->semaphore);
+
+ iterator->map->reference_count--;
+
+ (void) UnlockSemaphoreInfo(iterator->map->semaphore);
+
+ (void) memset((void *)iterator,0xbf,sizeof(MagickMapIteratorHandle));
+ MagickFreeMemory(iterator);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p D e r e f e r e n c e I t e r a t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapDereferenceIterator() dereferences a map iterator, providing
+% access to the contained data and its size. The object_size parameter may
+% be passed a null pointer if the object size is not required.
+%
+% The format of the MagickMapDereferenceIterator method is:
+%
+% const void *MagickMapDereferenceIterator(
+% const MagickMapIterator iterator, size_t *object_size)
+%
+% A description of each parameter follows:
+%
+% o iterator: iterator context
+%
+% o object_size: contained object size (if provided)
+%
+*/
+MagickExport const void *
+MagickMapDereferenceIterator(const MagickMapIterator iterator,
+ size_t *object_size)
+{
+ const void
+ *value=0;
+
+ assert(iterator != 0);
+ assert(iterator->signature == MagickSignature);
+ assert(iterator->member != 0);
+
+ if (object_size)
+ *object_size=0;
+
+ if (iterator->member)
+ {
+ value=iterator->member->object;
+ if (object_size)
+ *object_size=iterator->member->object_size;
+ }
+
+ return value;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p I t e r a t e T o B a c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapIterateToBack() sets the iterator to one position beyond the
+% last element in the map. The MagickMapIteratePrevious() function must
+% be executed once to access the last element in the map.
+%
+% The format of the MagickMapIterateToBack method is:
+%
+% void MagickMapIterateToBack(MagickMapIterator iterator)
+%
+% A description of each parameter follows:
+%
+% o iterator: iterator context
+%
+*/
+MagickExport void
+MagickMapIterateToBack(MagickMapIterator iterator)
+{
+ assert(iterator != 0);
+ assert(iterator->signature == MagickSignature);
+
+ iterator->member=0;
+ iterator->position=BackPosition;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p I t e r a t e T o F r o n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapIterateToFront() sets the iterator to one position before the
+% first element in the map. The MagickMapIterateNext() function must
+% be executed once to access the first element in the map.
+%
+% The format of the MagickMapIterateToFront method is:
+%
+% void MagickMapIterateToFront(MagickMapIterator iterator)
+%
+% A description of each parameter follows:
+%
+% o iterator: iterator context
+%
+*/
+MagickExport void
+MagickMapIterateToFront(MagickMapIterator iterator)
+{
+ assert(iterator != 0);
+ assert(iterator->signature == MagickSignature);
+
+ iterator->member=0;
+ iterator->position=FrontPosition;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p I t e r a t e N e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapIterateNext() advances the iterator by one element. True is
+% returned if there are remaining entries in the map. The key argument
+% is updated to point to the element key.
+%
+% The format of the MagickMapIterateNext method is:
+%
+% void MagickMapIterateToFront(MagickMapIterator iterator)
+%
+% A description of each parameter follows:
+%
+% o iterator: iterator context
+%
+% o key: pointer to location to store a pointer to the key
+%
+*/
+MagickExport unsigned int
+MagickMapIterateNext(MagickMapIterator iterator,const char **key)
+{
+ assert(iterator != 0);
+ assert(iterator->signature == MagickSignature);
+ assert(key != 0);
+
+ LockSemaphoreInfo(iterator->map->semaphore);
+
+ *key=(const char *) NULL;
+ switch (iterator->position)
+ {
+ case FrontPosition:
+ iterator->member=iterator->map->list;
+ if (iterator->member)
+ iterator->position=InListPosition;
+ break;
+ case InListPosition:
+ assert(iterator->member != 0);
+ iterator->member=iterator->member->next;
+ if (!iterator->member)
+ iterator->position=BackPosition;
+ break;
+ case BackPosition:
+ break;
+ }
+
+ if (iterator->member)
+ *key=iterator->member->key;
+
+ UnlockSemaphoreInfo(iterator->map->semaphore);
+
+ return (iterator->member != 0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p I t e r a t e P r e v i o u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapIteratePrevious() moves the iterator by one element in the
+% reverse direction. True is returned if there are remaining entries
+% in the map prior to the entry. The key argument is updated to point
+% to the element key.
+%
+% The format of the MagickMapIteratePrevious method is:
+%
+% void MagickMapIterateToPrevious(MagickMapIterator iterator)
+%
+% A description of each parameter follows:
+%
+% o iterator: iterator context
+%
+% o key: pointer to location to store a pointer to the key
+%
+*/
+MagickExport unsigned int
+MagickMapIteratePrevious(MagickMapIterator iterator,const char **key)
+{
+ assert(iterator != 0);
+ assert(iterator->signature == MagickSignature);
+ assert(key != 0);
+
+ LockSemaphoreInfo(iterator->map->semaphore);
+
+ switch (iterator->position)
+ {
+ case FrontPosition:
+ break;
+ case InListPosition:
+ assert(iterator->member != 0);
+ iterator->member=iterator->member->previous;
+ if (!iterator->member)
+ iterator->position=FrontPosition;
+ break;
+ case BackPosition:
+ {
+ for (iterator->member=iterator->map->list;
+ (iterator->member != 0) && (iterator->member->next != 0);
+ iterator->member=iterator->member->next);
+ if (iterator->member)
+ iterator->position=InListPosition;
+ }
+ break;
+ }
+
+ if (iterator->member)
+ *key=iterator->member->key;
+
+ UnlockSemaphoreInfo(iterator->map->semaphore);
+
+ return (iterator->member != 0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p R e m o v e E n t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapRemoveEntry() removes (destroys) an entry from the map. The
+% deallocate function is invoked on the entry data. False is returned if
+% a matching key doesn't exist.
+%
+% The format of the MagickMapRemoveEntry method is:
+%
+% unsigned int MagickMapRemoveEntry(MagickMap map,const char *key)
+%
+% A description of each parameter follows:
+%
+% o map: map context
+%
+% o key: key corresponding to the entry to remove
+%
+*/
+MagickExport unsigned int
+MagickMapRemoveEntry(MagickMap map,const char *key)
+{
+ unsigned int
+ status = False;
+
+ assert(map != 0);
+ assert(map->signature == MagickSignature);
+ assert(key != 0);
+
+ LockSemaphoreInfo(map->semaphore);
+
+ if (map->list)
+ {
+ MagickMapObject
+ *p;
+
+ for (p=map->list; p != 0; p=p->next)
+ {
+ if (LocaleCompare(key,p->key) == 0)
+ {
+ if (p == map->list)
+ {
+ if (!p->next)
+ {
+ map->list=0;
+ }
+ else
+ {
+ map->list=p->next;
+ p->next->previous=0;
+ }
+ }
+ else
+ {
+ if (p->previous)
+ p->previous->next=p->next;
+
+ if (p->next)
+ p->next->previous=p->previous;
+ }
+
+ MagickMapDestroyObject(p);
+ status=True;
+ break;
+ }
+ }
+ }
+
+ UnlockSemaphoreInfo(map->semaphore);
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p C o p y S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapCopyString() copies a string. It is intended for use as the
+% clone function for strings so that C strings may easily be stored in
+% a map.
+%
+% The format of the MagickMapCopyString method is:
+%
+% void *MagickMapCopyString(const void *string, const size_t size)
+%
+% A description of each parameter follows:
+%
+% o string: pointer to string data
+%
+% o size: ignored by this method.
+%
+*/
+MagickExport void *
+MagickMapCopyString(const void *string, const size_t size)
+{
+ ARG_NOT_USED(size);
+ if (string)
+ return (void *) AcquireString((const char *)string);
+ return 0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p D e a l l o c a t e S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapDeallocateString() deallocates a string. It is intended for
+% use as the deallocate function for strings so that C strings may easily
+% be stored in a map.
+%
+% The format of the MagickMapDeallocateString method is:
+%
+% void MagickMapDeallocateString(void *string)
+%
+% A description of each parameter follows:
+%
+% o string: pointer to string data to deallocate
+%
+*/
+extern MagickExport void
+MagickMapDeallocateString(void *string)
+{
+ MagickFreeMemory(string);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p C o p y B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapCopyBlob() copies a BLOB. It is intended for use as the
+% clone function for BLOBs so that BLOB may easily be stored in
+% a map.
+%
+% The format of the MagickMapCopyBlob method is:
+%
+% void *MagickMapCopyBlob(const void *blob, const size_t size)
+%
+% A description of each parameter follows:
+%
+% o blob: pointer to BLOB data
+%
+% o size: BLOB size
+%
+*/
+MagickExport void *
+MagickMapCopyBlob(const void *blob, const size_t size)
+{
+ if (blob)
+ {
+ void
+ *memory;
+
+ memory=MagickAllocateMemory(void *,size);
+ if (memory)
+ (void) memcpy(memory,blob,size);
+ return (memory);
+ }
+ return 0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a p D e a l l o c a t e B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapDeallocateBlob() deallocates a BLOB. It is intended for
+% use as the deallocate function for BLOBs so that BLOBs may easily
+% be stored in a map.
+%
+% The format of the MagickMapDeallocateBlob method is:
+%
+% void MagickMapDeallocateBlob(void *blob)
+%
+% A description of each parameter follows:
+%
+% o blob: pointer to BLOB data to deallocate
+%
+*/
+extern MagickExport void
+MagickMapDeallocateBlob(void *blob)
+{
+ MagickFreeMemory(blob);
+}
diff --git a/magick/map.h b/magick/map.h
new file mode 100644
index 0000000..92b0ae5
--- /dev/null
+++ b/magick/map.h
@@ -0,0 +1,179 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+*/
+#ifndef _MAGICK_MAP_H
+#define _MAGICK_MAP_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+
+typedef struct _MagickMapHandle *MagickMap;
+typedef struct _MagickMapIteratorHandle *MagickMapIterator;
+
+/*
+ Function prototype for a function to clone (copy) an object
+*/
+typedef void * (*MagickMapObjectClone)(const void *object_,
+ const size_t object_size);
+
+/*
+ Function prototype for a function to destroy a contained object
+ (similar to free())
+*/
+typedef void (*MagickMapObjectDeallocator)(void *object_);
+
+
+/*
+ MagickExported text map methods.
+*/
+
+/*
+ Allocate a Magick Map
+ All objects contained in the map need to be of the same type.
+ Copy specifies a function to copy objects into the map.
+ Deallocate specifies a function to destroy a contained object.
+*/
+extern MagickExport MagickMap
+ MagickMapAllocateMap(MagickMapObjectClone clone,
+ MagickMapObjectDeallocator deallocate);
+
+/*
+ Destroy a Magick Map (and any contained objects)
+*/
+extern MagickExport void
+ MagickMapDeallocateMap(MagickMap map);
+
+/*
+ Deallocate (clear) all objects in the map.
+*/
+extern MagickExport void
+ MagickMapClearMap(MagickMap map);
+
+/*
+ Deep clone Magick Map (and any contained objects)
+*/
+extern MagickExport MagickMap
+ MagickMapCloneMap(MagickMap map,ExceptionInfo *exception);
+
+/*
+ Add an entry to the Magick Map.
+ Argument is copied into the map.
+*/
+extern MagickExport unsigned int
+ MagickMapAddEntry(MagickMap map,const char *key, const void *object,
+ const size_t object_size, ExceptionInfo *exception);
+
+/*
+ Remove (destroy) an entry from the Magick Map. False is returned if
+ the object doesn't exist.
+*/
+extern MagickExport unsigned int
+ MagickMapRemoveEntry(MagickMap map,const char *key);
+
+/*
+ Access an entry
+ Object_size is updated with the object size.
+*/
+extern MagickExport const void
+ *MagickMapAccessEntry(MagickMap map,const char *key,
+ size_t *object_size);
+
+/*
+ Allocate an iterator
+*/
+extern MagickExport MagickMapIterator
+ MagickMapAllocateIterator(MagickMap map);
+
+/*
+ Deallocate an iterator
+*/
+extern MagickExport void
+ MagickMapDeallocateIterator(MagickMapIterator iterator);
+
+/*
+ Position the iterator to one-before the first element (default
+ position). The MagickMapIterateNext() function must be executed
+ once to access the first element.
+*/
+extern MagickExport void
+ MagickMapIterateToFront(MagickMapIterator iterator);
+
+/*
+ Position the iterator to one-beyond the last element
+ The MagickMapIteratePrevious() function must be executed once
+ to access the last element.
+*/
+extern MagickExport void
+ MagickMapIterateToBack(MagickMapIterator iterator);
+
+/*
+ Iterate to next element
+ Key is updated with pointer to element key
+ True is returned if not pointing to end of list.
+*/
+extern MagickExport unsigned int
+ MagickMapIterateNext(MagickMapIterator iterator,const char **key);
+
+/*
+ Iterate to previous element
+ Key is updated with pointer to element key
+ True is returned if not pointing to beginning of list.
+*/
+extern MagickExport unsigned int
+ MagickMapIteratePrevious(MagickMapIterator iterator,const char **key);
+
+/*
+ Access an element via the iterator
+ Object_size is updated with the object size.
+*/
+extern MagickExport const void
+ *MagickMapDereferenceIterator(const MagickMapIterator iterator,
+ size_t *object_size);
+
+/*
+ Function to copy a string
+*/
+extern MagickExport void *
+ MagickMapCopyString(const void *string, const size_t size);
+
+/*
+ Function to deallocate a string
+*/
+extern MagickExport void
+ MagickMapDeallocateString(void *string);
+
+/*
+ Function to copy a BLOB
+*/
+extern MagickExport void *
+ MagickMapCopyBlob(const void *blob, const size_t size);
+
+/*
+ Function to deallocate a BLOB
+*/
+extern MagickExport void
+ MagickMapDeallocateBlob(void *blob);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_MAP_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/memory.c b/magick/memory.c
new file mode 100644
index 0000000..757b852
--- /dev/null
+++ b/magick/memory.c
@@ -0,0 +1,553 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M EEEEE M M OOO RRRR Y Y %
+% MM MM E MM MM O O R R Y Y %
+% M M M EEE M M M O O RRRR Y %
+% M M E M M O O R R Y %
+% M M EEEEE M M OOO R R Y %
+% %
+% %
+% GraphicsMagick Memory Allocation Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1998 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/utility.h"
+
+/*
+ Static variables.
+*/
+MagickFreeFunc FreeFunc = free;
+MagickMallocFunc MallocFunc = malloc;
+MagickReallocFunc ReallocFunc = realloc;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A l l o c F u n c t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAllocFunctions() provides a way for the user to supply a preferred
+% free(), malloc(), and realloc() functions. Otherwise the default system
+% versions are used. If an alternative allocator is to be used, this
+% function should be invoked prior to invoking InitializeMagick().
+%
+% The format of the MagickAllocFunctions method is:
+%
+% void MagickAllocFunctions(MagickFreeFunc free_func,
+% MagickMallocFunc malloc_func,
+% MagickReallocFunc realloc_func)
+%
+% A description of each parameter follows:
+%
+% o free_func: Function to free memory.
+%
+% o malloc_func: Function to allocate memory.
+%
+% o realloc_func: Function to reallocate memory.
+%
+*/
+MagickExport void MagickAllocFunctions(MagickFreeFunc free_func,
+ MagickMallocFunc malloc_func,
+ MagickReallocFunc realloc_func)
+{
+ FreeFunc = free_func;
+ MallocFunc = malloc_func;
+ ReallocFunc = realloc_func;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k A r r a y Si z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickArraySize() returnes the size of an array given two size_t arguments.
+% Zero is returned if the computed result overflows the size_t type.
+%
+% The format of the MagickArraySize method is:
+%
+% size_t MagickArraySize(const size_t count, const size_t size);
+%
+% A description of each parameter follows:
+%
+% o count: The number of elements in the array.
+%
+% o size: The size of one array element.
+%
+*/
+MagickExport size_t MagickArraySize(const size_t count, const size_t size)
+{
+ size_t
+ allocation_size;
+
+ allocation_size = size * count;
+ if ((count != 0) && (size != allocation_size/count))
+ allocation_size = 0;
+
+ return allocation_size;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M a l l o c %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMalloc() returns a pointer to a block of memory of at least size
+% bytes suitably aligned for any use. NULL is returned if insufficient
+% memory is available or the requested size is zero.
+%
+% The format of the MagickMalloc method is:
+%
+% void * MagickMalloc(const size_t size)
+%
+% A description of each parameter follows:
+%
+% o size: The size of the memory in bytes to allocate.
+%
+%
+*/
+MagickExport void * MagickMalloc(const size_t size)
+{
+ if (size == 0)
+ return ((void *) NULL);
+
+ return (MallocFunc)(size);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M a l l o c A l i g n e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMallocAligned() allocates memory and returns a pointer to a
+% block of memory capable of storing at least size bytes with the
+% allocation's base address being an even multiple of alignment.
+% The size of the buffer allocation is rounded up as required in
+% order to consume a block of memory starting at least at the requested
+% alignment and ending at at least the requested alignment.
+%
+% The requested alignment should be a power of 2 at least as large as
+% sizeof a void pointer.
+%
+% NULL is returned if insufficient memory is available, the requested
+% size is zero, or integer overflow was detected.
+%
+% This function is intended for allocating special-purpose buffers
+% which benefit from specific alignment.
+%
+% The allocated memory should only be freed using MagickFreeAligned()
+% and may not be reallocated.
+%
+% The format of the MagickMallocAligned method is:
+%
+% void * MagickMallocAligned(size_t alignment, const size_t size)
+%
+% A description of each parameter follows:
+%
+%
+% o alignment: The alignment of the base and size of the allocated
+% memory.
+%
+% o size: The size of the memory in bytes to allocate.
+%
+%
+*/
+MagickExport void * MagickMallocAligned(const size_t alignment,const size_t size)
+{
+ size_t
+ alligned_size;
+
+ void
+ *alligned_p = 0;
+
+ alligned_size=RoundUpToAlignment(size,alignment);
+
+ if ((size == 0) || (alignment < sizeof(void *)) || (alligned_size < size))
+ return ((void *) NULL);
+
+#if defined(HAVE_POSIX_MEMALIGN)
+ if (posix_memalign(&alligned_p, alignment, alligned_size) != 0)
+ alligned_p=0;
+#elif defined(HAVE__ALIGNED_MALLOC)
+ alligned_p=_aligned_malloc(alligned_size,alignment);
+#else
+ {
+ void
+ *alloc_p;
+
+ size_t
+ alloc_size;
+
+ alloc_size=(size+alignment-1)+sizeof(void *);
+ if (alloc_size > size)
+ {
+ if ((alloc_p = (MagickMalloc(alloc_size))) != NULL)
+ {
+ alligned_p=(void*) RoundUpToAlignment((magick_uintptr_t)alloc_p+
+ sizeof(void *),alignment);
+ *((void **)alligned_p-1)=alloc_p;
+ }
+ }
+ }
+#endif
+
+ return alligned_p;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a l l o c A l i g n e d A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMallocAlignedArray() returns a pointer to a block of memory of
+% sufficient size to support an array of elements of a specified size.
+% The allocation's base address is an even multiple of the specified
+% alignment. The size of the buffer allocation is rounded up as required
+% in order to consume a block of memory starting at least at the requested
+% alignment and ending at at least the requested alignment.
+%
+% NULL is returned if the required memory exceeds the range of size_t,
+% the computed size is zero, or there is insufficient memory available.
+%
+% This function is intended for allocating special-purpose buffers
+% which benefit from specific alignment.
+%
+% The allocated memory should only be freed using MagickFreeAligned()
+% and may not be reallocated.
+%
+% The format of the MagickMallocArray method is:
+%
+% void *MagickMallocAlignedArray(const size_t alignment,
+% const size_t count,
+% const size_t size);
+%
+% A description of each parameter follows:
+%
+% o alignment: The alignment of the base and size of the allocated
+% memory.
+%
+% o count: The number of elements in the array.
+%
+% o size: The size of one array element.
+%
+*/
+MagickExport void *MagickMallocAlignedArray(const size_t alignment,
+ const size_t count,
+ const size_t size)
+{
+ size_t
+ allocation_size;
+
+ void
+ *allocation;
+
+ allocation = (void *) NULL;
+ allocation_size=MagickArraySize(count,size);
+
+ if (allocation_size)
+ allocation = MagickMallocAligned(alignment,allocation_size);
+
+ return allocation;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k M a l l o c A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMallocArray() returns a pointer to a block of memory of
+% sufficient size to support an array of elements of a specified size.
+% The returned memory is suitably aligned for any use. NULL is returned
+% if the required memory exceeds the range of size_t, the specified size
+% is zero, or there is insufficient memory available.
+%
+% The format of the MagickMallocArray method is:
+%
+% void *MagickMallocArray(const size_t count, const size_t size);
+%
+% A description of each parameter follows:
+%
+% o count: The number of elements in the array.
+%
+% o size: The size of one array element.
+%
+*/
+MagickExport void *MagickMallocArray(const size_t count,const size_t size)
+{
+ size_t
+ allocation_size;
+
+ void
+ *allocation;
+
+ allocation = (void *) NULL;
+ allocation_size=MagickArraySize(count,size);
+
+ if (allocation_size)
+ allocation = MagickMalloc(allocation_size);
+ return allocation;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M a l l o c C l e a r e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMallocCleared() returns a pointer to a block of memory of at least
+% size bytes suitably aligned for any use. NULL is returned if insufficient
+% memory is available or the requested size is zero. This version differs
+% from MagickMalloc in that the allocated bytes are cleared to zero.
+%
+% The format of the MagickMallocCleared method is:
+%
+% void * MagickMallocCleared(const size_t size)
+%
+% A description of each parameter follows:
+%
+% o size: The size of the memory in bytes to allocate.
+%
+%
+*/
+MagickExport void * MagickMallocCleared(const size_t size)
+{
+ void
+ *p = (void *) NULL;
+
+ if (size != 0)
+ {
+ p=MagickMalloc(size);
+
+ if (p != (void *) NULL)
+ (void) memset(p,0,size);
+ }
+
+ return p;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C l o n e M e m o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCloneMemory() copies size bytes from memory area source to the
+% destination. Copying between objects that overlap will take place
+% correctly. It returns destination.
+%
+% The format of the MagickCloneMemory method is:
+%
+% void *MagickCloneMemory(void *destination,const void *source,
+% const size_t size)
+%
+% A description of each parameter follows:
+%
+% o size: The size of the memory in bytes to allocate.
+%
+%
+*/
+MagickExport void *MagickCloneMemory(void *destination,const void *source,
+ const size_t size)
+{
+ unsigned char
+ *d=(unsigned char*) destination;
+
+ const unsigned char
+ *s=(const unsigned char*) source;
+
+ assert(destination != (void *) NULL);
+ assert(source != (const void *) NULL);
+
+ if (((d+size) < s) || (d > (s+size)))
+ return(memcpy(destination,source,size));
+
+ return(memmove(destination,source,size));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e a l l o c %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRealloc() changes the size of the memory and returns a pointer to
+% the (possibly moved) block. The contents will be unchanged up to the
+% lesser of the new and old sizes. If size is zero, then the memory is
+% freed and a NULL value is returned. If the memory allocation fails, then
+% the existing memory is freed, and a NULL value is returned.
+%
+% The format of the MagickRealloc method is:
+%
+% void *MagickRealloc(void *memory,const size_t size)
+%
+% A description of each parameter follows:
+%
+% o memory: A pointer to a memory allocation.
+%
+% o size: The new size of the allocated memory.
+%
+*/
+MagickExport void *MagickRealloc(void *memory,const size_t size)
+{
+ void
+ *new_memory = (void *) NULL;
+
+ if ((void *) NULL == memory)
+ new_memory = (MallocFunc)(size);
+ else
+ new_memory = (ReallocFunc)(memory,size);
+ if ((new_memory == 0) && (memory != 0) && (size != 0))
+ MagickFree(memory);
+
+ return new_memory;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F r e e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFree() frees memory that has already been allocated by
+% MagickMalloc() or other other other allocators directly compatible
+% with the currently defined memory allocator (which defaults to the
+% system malloc()). For convenience, a NULL argument is ignored.
+%
+% The format of the MagickFree method is:
+%
+% void MagickFree(void *memory)
+%
+% A description of each parameter follows:
+%
+% o memory: A pointer to a block of memory to free for reuse.
+%
+%
+*/
+MagickExport void MagickFree(void *memory)
+{
+ if (memory != (void *) NULL)
+ (FreeFunc)(memory);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F r e e A l i g n e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFreeAligned() frees aligned memory that has previously been
+% allocated via MagickMallocAligned(). For convenience, a NULL argument is
+% ignored.
+%
+% This function exists in case the pointer allocated by
+% MagickMallocAligned() can not be used directly with MagickFree().
+%
+% The format of the MagickFreeAligned method is:
+%
+% void MagickFreeAligned(void *memory)
+%
+% A description of each parameter follows:
+%
+% o memory: A pointer to a block of memory to free for reuse.
+%
+%
+*/
+MagickExport void MagickFreeAligned(void *memory)
+{
+ if (memory != (void *) NULL)
+ {
+#if defined (HAVE_POSIX_MEMALIGN)
+ MagickFree(memory);
+#elif defined(HAVE__ALIGNED_MALLOC)
+ /* Windows Studio .NET 2003 or later */
+ _aligned_free(memory);
+#else
+ MagickFree(*((void **)memory-1));
+#endif
+ }
+}
diff --git a/magick/memory.h b/magick/memory.h
new file mode 100644
index 0000000..3a5eda0
--- /dev/null
+++ b/magick/memory.h
@@ -0,0 +1,115 @@
+/*
+ Copyright (C) 2003-2013 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Memory Allocation Methods.
+*/
+#ifndef _MAGICK_MEMORY_H
+#define _MAGICK_MEMORY_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+typedef void *(*MagickMallocFunc)(size_t size) MAGICK_FUNC_ALLOC_SIZE_1ARG(1);
+typedef void (*MagickFreeFunc)(void *ptr);
+typedef void *(*MagickReallocFunc)(void *ptr, size_t size) MAGICK_FUNC_ALLOC_SIZE_1ARG(2);
+
+extern MagickExport void
+ MagickAllocFunctions(MagickFreeFunc free_func,MagickMallocFunc malloc_func,
+ MagickReallocFunc realloc_func),
+ *MagickMalloc(const size_t size) MAGICK_FUNC_MALLOC MAGICK_FUNC_ALLOC_SIZE_1ARG(1),
+ *MagickMallocAligned(const size_t alignment, const size_t size) MAGICK_FUNC_MALLOC MAGICK_FUNC_ALLOC_SIZE_1ARG(2),
+ *MagickMallocCleared(const size_t size) MAGICK_FUNC_MALLOC MAGICK_FUNC_ALLOC_SIZE_1ARG(1),
+ *MagickCloneMemory(void *destination,const void *source,const size_t size) MAGICK_FUNC_NONNULL,
+ *MagickRealloc(void *memory,const size_t size) MAGICK_FUNC_MALLOC MAGICK_FUNC_ALLOC_SIZE_1ARG(2),
+ MagickFree(void *memory),
+ MagickFreeAligned(void *memory);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+extern MagickExport void
+ *MagickMallocAlignedArray(const size_t alignment,const size_t count,const size_t size),
+ *MagickMallocArray(const size_t count,const size_t size) MAGICK_FUNC_MALLOC MAGICK_FUNC_ALLOC_SIZE_2ARG(1,2);
+
+extern MagickExport size_t
+ MagickArraySize(const size_t count,const size_t size);
+
+/*
+ Allocate memory
+*/
+
+#define MagickAllocateMemory(type,size) \
+ ((((size) != ((size_t) (size))) || (size == 0)) ? ((type) 0) : \
+ ((type) MagickMalloc((size_t) (size))))
+
+#define MagickAllocateArray(type,count,size) \
+ ( (type) MagickMallocArray(count,size) )
+
+/*
+ Free memory and set pointer to NULL
+*/
+#define MagickFreeMemory(memory) \
+{ \
+ void *_magick_mp=memory; \
+ MagickFree(_magick_mp); \
+ memory=0; \
+}
+
+/*
+ Reallocate memory using provided pointer. If reallocation fails
+ then free memory, setting pointer to null. If size is 0 and memory
+ is not a null pointer, then free memory. This interface behaves
+ similar to realloc() except that memory is always freed (and pointer
+ set to null) if a memory allocation failure occurs.
+*/
+#define MagickReallocMemory(type,memory,size) \
+{ \
+ size_t _new_size = (size_t) (size); \
+ void *_magick_mp = MagickRealloc(memory,_new_size); \
+ memory=(type) _magick_mp; \
+}
+
+/*
+ Allocate memory aligned to a specified alignment boundary
+*/
+#define MagickAllocateAlignedMemory(type,alignment,size) \
+ ((((size) != ((size_t) (size))) || (size == 0)) ? ((type) 0) : \
+ ((type) MAGICK_ASSUME_ALIGNED(MagickMallocAligned((size_t) alignment, (size_t) (size)),alignment)))
+
+/*
+ Allocate array aligned to a specified alignment boundary
+*/
+#define MagickAllocateAlignedArray(type,alignment,count,size) \
+ ((((size) != ((size_t) (size))) || (size == 0)) ? ((type) 0) : \
+ ((type) MAGICK_ASSUME_ALIGNED(MagickMallocAlignedArray((size_t) alignment, (size_t) (count), (size_t) (size)),alignment)))
+
+/*
+ Free aligned memory (from MagickAllocateAlignedMemory()) and set pointer to
+ NULL
+*/
+#define MagickFreeAlignedMemory(memory) \
+{ \
+ void *_magick_mp=memory; \
+ MagickFreeAligned(_magick_mp); \
+ memory=0; \
+}
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/module.c b/magick/module.c
new file mode 100644
index 0000000..012e3c5
--- /dev/null
+++ b/magick/module.c
@@ -0,0 +1,2283 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M OOO DDDD U U L EEEEE %
+% MM MM O O D D U U L E %
+% M M M O D D U U L EEE %
+% M M O O D D U U L E %
+% M M OOO DDDD UUU LLLLL EEEEE %
+% %
+% %
+% Module Loader %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% March 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#if defined(SupportMagickModules)
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+# include "magick/nt_feature.h"
+#endif
+#include "magick/blob.h"
+#include "magick/log.h"
+#include "magick/magic.h"
+#include "magick/magick.h"
+#include "magick/map.h"
+#include "magick/module.h"
+#include "magick/utility.h"
+#if defined(HasLTDL)
+# include "ltdl.h"
+ typedef lt_dlhandle ModuleHandle;
+#else
+ typedef void *ModuleHandle;
+#endif
+
+/*
+ Define declarations.
+*/
+#define MAX_MODULES 511 /* Maximum number of modules supported by build. */
+#define ModuleFilename "modules.mgk"
+#if defined(HasLTDL)
+# define ModuleGlobExpression "*.la"
+#else
+# if defined(_DEBUG)
+# define ModuleGlobExpression "IM_MOD_DB_*.dll"
+# else
+# define ModuleGlobExpression "IM_MOD_RL_*.dll"
+# endif
+#endif
+
+typedef enum
+{
+ MagickCoderModule,
+ MagickFilterModule
+} MagickModuleType;
+
+/*
+ Declare module map.
+*/
+static const char
+ *BuiltInPath="[Built In]";
+
+static const struct
+{
+ char
+ *magick,
+ *name;
+}
+ModuleAliases[] =
+{
+#define MODULEALIAS(magick,name) {magick,name}
+ MODULEALIAS("3FR","DCRAW"),
+ MODULEALIAS("8BIM","META"),
+ MODULEALIAS("8BIMTEXT","META"),
+ MODULEALIAS("8BIMWTEXT","META"),
+ MODULEALIAS("APP1","META"),
+ MODULEALIAS("APP1JPEG","META"),
+ MODULEALIAS("ARW","DCRAW"),
+ MODULEALIAS("B","GRAY"),
+ MODULEALIAS("BIE","JBIG"),
+ MODULEALIAS("BIGTIFF","TIFF"),
+ MODULEALIAS("BMP2","BMP"),
+ MODULEALIAS("BMP3","BMP"),
+ MODULEALIAS("C","GRAY"),
+ MODULEALIAS("CAL","CALS"),
+ MODULEALIAS("CIN","CINEON"),
+ MODULEALIAS("CMYKA","CMYK"),
+ MODULEALIAS("CR2","DCRAW"),
+ MODULEALIAS("CRW","DCRAW"),
+ MODULEALIAS("CUR","ICON"),
+ MODULEALIAS("DCR","DCRAW"),
+ MODULEALIAS("DCX","PCX"),
+ MODULEALIAS("DNG","DCRAW"),
+ MODULEALIAS("EPDF","PDF"),
+ MODULEALIAS("EPI","PS"),
+ MODULEALIAS("EPS","PS"),
+ MODULEALIAS("EPS2","PS2"),
+ MODULEALIAS("EPS3","PS3"),
+ MODULEALIAS("EPSF","PS"),
+ MODULEALIAS("EPSI","PS"),
+ MODULEALIAS("EPT2","EPT"),
+ MODULEALIAS("EPT3","EPT"),
+ MODULEALIAS("ERF","DCRAW"),
+ MODULEALIAS("EXIF","META"),
+ MODULEALIAS("FILE","URL"),
+ MODULEALIAS("FRACTAL","PLASMA"),
+ MODULEALIAS("FTP","URL"),
+ MODULEALIAS("G","GRAY"),
+ MODULEALIAS("G3","FAX"),
+ MODULEALIAS("GIF87","GIF"),
+ MODULEALIAS("GRANITE","LOGO"),
+ MODULEALIAS("GRAYA","GRAY"),
+ MODULEALIAS("GROUP4RAW","TIFF"),
+ MODULEALIAS("H","LOGO"),
+ MODULEALIAS("HTM","HTML"),
+ MODULEALIAS("HTTP","URL"),
+ MODULEALIAS("ICB","TGA"),
+ MODULEALIAS("ICC","META"),
+ MODULEALIAS("ICM","META"),
+ MODULEALIAS("ICO","ICON"),
+ MODULEALIAS("IMAGE","LOGO"),
+ MODULEALIAS("IPTC","META"),
+ MODULEALIAS("IPTCTEXT","META"),
+ MODULEALIAS("IPTCWTEXT","META"),
+ MODULEALIAS("J2C","JP2"),
+ MODULEALIAS("JBG","JBIG"),
+ MODULEALIAS("JNG","PNG"),
+ MODULEALIAS("JPC","JP2"),
+ MODULEALIAS("JPG","JPEG"),
+ MODULEALIAS("K","GRAY"),
+ MODULEALIAS("K25","DCRAW"),
+ MODULEALIAS("KDC","DCRAW"),
+ MODULEALIAS("LOCALEC","LOCALE"),
+ MODULEALIAS("LOCALEH","LOCALE"),
+ MODULEALIAS("LOCALEMC","LOCALE"),
+ MODULEALIAS("M","GRAY"),
+ MODULEALIAS("M2V","MPEG"),
+ MODULEALIAS("MEF","DCRAW"),
+ MODULEALIAS("MNG","PNG"),
+ MODULEALIAS("MPG","MPEG"),
+ MODULEALIAS("MRW","DCRAW"),
+ MODULEALIAS("NEF","DCRAW"),
+ MODULEALIAS("NETSCAPE","LOGO"),
+ MODULEALIAS("O","GRAY"),
+ MODULEALIAS("ORF","DCRAW"),
+ MODULEALIAS("P7","PNM"),
+ MODULEALIAS("PAL","UYVY"),
+ MODULEALIAS("PAM","PNM"),
+ MODULEALIAS("PATTERN","LOGO"),
+ MODULEALIAS("PBM","PNM"),
+ MODULEALIAS("PCDS","PCD"),
+ MODULEALIAS("PCT","PICT"),
+ MODULEALIAS("PEF","DCRAW"),
+ MODULEALIAS("PFA","TTF"),
+ MODULEALIAS("PFB","TTF"),
+ MODULEALIAS("PGM","PNM"),
+ MODULEALIAS("PGX","JP2"),
+ MODULEALIAS("PICON","XPM"),
+ MODULEALIAS("PM","XPM"),
+ MODULEALIAS("PNG24","PNG"),
+ MODULEALIAS("PNG32","PNG"),
+ MODULEALIAS("PNG8","PNG"),
+ MODULEALIAS("PPM","PNM"),
+ MODULEALIAS("PTIF","TIFF"),
+ MODULEALIAS("R","GRAY"),
+ MODULEALIAS("RAF","DCRAW"),
+ MODULEALIAS("RAS","SUN"),
+ MODULEALIAS("RGBA","RGB"),
+ MODULEALIAS("ROSE","LOGO"),
+ MODULEALIAS("SHTML","HTML"),
+ MODULEALIAS("SR2","DCRAW"),
+ MODULEALIAS("SRF","DCRAW"),
+ MODULEALIAS("SVGZ","SVG"),
+ MODULEALIAS("TEXT","TXT"),
+ MODULEALIAS("TIF","TIFF"),
+ MODULEALIAS("VDA","TGA"),
+ MODULEALIAS("VST","TGA"),
+ MODULEALIAS("X3F","DCRAW"),
+ MODULEALIAS("XMP","META"),
+ MODULEALIAS("XTRNARRAY","XTRN"),
+ MODULEALIAS("XTRNBLOB","XTRN"),
+ MODULEALIAS("XTRNFILE","XTRN"),
+ MODULEALIAS("XTRNIMAGE","XTRN"),
+ MODULEALIAS("XV","VIFF"),
+ MODULEALIAS("Y","GRAY")
+};
+
+/*
+ Coder module list
+ Maintains a loader handle corresponding to each module tag.
+ Used to support coder_list, which is initialized as coders are
+ loaded, and used to obtain the handle when the coder is unloaded.
+*/
+typedef struct _CoderInfo
+{
+ /* Module ID tag */
+ char
+ *tag;
+
+ /* libltdl handle */
+ void
+ *handle;
+
+ /* Time that module was loaded */
+ time_t
+ load_time;
+
+ /* Address of module register function */
+ void (*register_function)(void);
+
+ /* Address of module unregister function */
+ void (*unregister_function)(void);
+
+ /* Structure validation signature */
+ unsigned long
+ signature;
+
+ struct _CoderInfo
+ *previous,
+ *next;
+} CoderInfo;
+
+
+/*
+ Global declarations.
+*/
+static CoderInfo
+ *coder_list = (CoderInfo *) NULL;
+
+static ModuleInfo
+ *module_list = (ModuleInfo *) NULL;
+
+/*
+ List of directories to search for coder modules
+*/
+static MagickMap
+ coder_path_map = (MagickMap) NULL;
+
+/*
+ List of directories to search for filter modules
+*/
+static MagickMap
+ filter_path_map = (MagickMap) NULL;
+
+/*
+ Set to True if libltdl has been initialized.
+*/
+static unsigned int
+ ltdl_initialized=False;
+
+/*
+ Forward declarations.
+*/
+static void
+ TagToCoderModuleName(const char *tag,char *module_name),
+ TagToFilterModuleName(const char *tag, char *module_name),
+ TagToFunctionName(const char *tag,const char *format,char *function);
+
+static unsigned int
+ FindMagickModule(const char *filename,MagickModuleType module_type,
+ char *path,ExceptionInfo *exception);
+
+static CoderInfo
+ *RegisterModule(CoderInfo *,ExceptionInfo *),
+ *SetCoderInfo(const char *);
+
+#if 0
+static const CoderInfo
+ *GetCoderInfo(const char *,ExceptionInfo *);
+#endif
+
+static unsigned int
+ InitializeModuleSearchPath(MagickModuleType module_type,ExceptionInfo *exception),
+ ReadModuleConfigureFile(const char *,const unsigned int,ExceptionInfo *),
+ UnloadModule(const CoderInfo *,ExceptionInfo *),
+ UnregisterModule(const char *,ExceptionInfo *);
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y M a g i c k M o d u l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyMagickResources() destroys the resource environment.
+%
+% The format of the DestroyMagickResources() method is:
+%
+% DestroyMagickResources(void)
+%
+%
+*/
+MagickExport void
+DestroyMagickModules(void)
+{
+ DestroyModuleInfo();
+
+ if (coder_path_map != (MagickMap) NULL)
+ {
+ MagickMapDeallocateMap(coder_path_map);
+ coder_path_map = (MagickMap) NULL;
+ }
+
+ if (filter_path_map != (MagickMap) NULL)
+ {
+ MagickMapDeallocateMap(filter_path_map);
+ filter_path_map = (MagickMap) NULL;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y M o d u l e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyModuleInfo() deallocates memory associated with the ModuleInfo list.
+%
+% The format of the DestroyModuleInfo method is:
+%
+% void DestroyModuleInfo(void)
+%
+*/
+static void
+DestroyModuleInfoEntry(ModuleInfo *entry)
+{
+ if (entry->previous)
+ entry->previous->next=entry->next;
+ if (entry->next)
+ entry->next->previous=entry->previous;
+ if (entry == module_list)
+ module_list=entry->next;
+ if ((entry->path[0] != BuiltInPath[0]) &&
+ (LocaleCompare(entry->path,BuiltInPath) != 0))
+ {
+ MagickFreeMemory(entry->path);
+ MagickFreeMemory(entry->magick);
+ MagickFreeMemory(entry->name);
+ }
+ MagickFreeMemory(entry);
+}
+
+MagickExport void
+DestroyModuleInfo(void)
+{
+ CoderInfo
+ *coder_info;
+
+ ExceptionInfo
+ exception;
+
+ ModuleInfo
+ *module_info;
+
+ register CoderInfo
+ *p;
+
+ register ModuleInfo
+ *q;
+
+ GetExceptionInfo(&exception);
+ /*
+ Free coder list.
+ */
+ for (p=coder_list; p != (CoderInfo *) NULL; )
+ {
+ coder_info=p;
+ p=p->next;
+ if( UnregisterModule(coder_info->tag,&exception) == False)
+ CatchException(&exception);
+ }
+ DestroyExceptionInfo(&exception);
+ coder_list=(CoderInfo *) NULL;
+
+ /*
+ Free module alias list.
+ */
+ for (q=module_list; q != (ModuleInfo *) NULL; )
+ {
+ module_info=q;
+ q=q->next;
+ DestroyModuleInfoEntry(module_info);
+ }
+ module_list=(ModuleInfo *) NULL;
+ /*
+ Destroy the libltdl environment unless Jasper is used since Jasper
+ sometimes registers an atexit() handler to destroy itself and this
+ causes a crash if the Jasper library is already unloaded.
+ */
+ if (ltdl_initialized)
+ {
+#if !defined(HasJP2)
+ (void) lt_dlexit();
+#endif
+ ltdl_initialized=False;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x e c u t e M o d u l e P r o c e s s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ExecuteModuleProcess executes a dynamic modules. It is passed the
+% specified parameters and returns True on success otherwise False.
+%
+% The format of the ExecuteModuleProcess method is:
+%
+% unsigned int ExecuteModuleProcess(const char *tag,Image **image,
+% const int argc,char **argv)
+%
+% A description of each parameter follows:
+%
+% o status: ExecuteModuleProcess() returns True if the dynamic module is
+% loaded and returns successfully, otherwise False.
+%
+% o tag: a character string that represents the name of the particular
+% module.
+%
+% o image: The image.
+%
+% o argc: Specifies a pointer to an integer describing the number of
+% elements in the argument vector.
+%
+% o argv: Specifies a pointer to a text array containing the command line
+% arguments.
+%
+*/
+MagickExport MagickPassFail
+ExecuteModuleProcess(const char *tag,Image **image,
+ const int argc,char **argv)
+{
+ ModuleHandle
+ handle;
+
+ unsigned int
+ status;
+
+ assert(image != (Image **) NULL);
+ assert((*image)->signature == MagickSignature);
+ status=MagickFail;
+
+#if !defined(BuildMagickModules)
+ /*
+ Try to locate and execute a static module.
+ */
+ status=ExecuteStaticModuleProcess(tag,image,argc,argv);
+ if (status != MagickFail)
+ return (status);
+#endif
+
+ {
+ char
+ module_name[MaxTextExtent],
+ module_path[MaxTextExtent];
+
+ /* Find the module */
+ TagToFilterModuleName(tag,module_name);
+ if (!FindMagickModule(module_name,MagickFilterModule,module_path,
+ &(*image)->exception))
+ return(MagickFail);
+
+ /* Open the module */
+ handle=lt_dlopen(module_path);
+ if (handle == (ModuleHandle) NULL)
+ {
+ char
+ message[MaxTextExtent];
+
+ FormatString(message,"\"%.256s: %.256s\"",module_path,lt_dlerror());
+ ThrowException(&(*image)->exception,ModuleError,UnableToLoadModule,
+ message);
+ return(status);
+ }
+ }
+ {
+ char
+ method_name[MaxTextExtent];
+
+ unsigned int
+ (*method)(Image **,const int,char **);
+
+ /* Locate module method */
+#if defined(PREFIX_MAGICK_SYMBOLS)
+ FormatString(method_name,"Gm%.64sImage",tag);
+#else
+ FormatString(method_name,"%.64sImage",tag);
+#endif
+ method=(unsigned int (*)(Image **,const int,char **))
+ lt_dlsym(handle,method_name);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Invoking \"%.1024s\" filter module",tag);
+
+ /* Execute module method */
+ if (method != (unsigned int (*)(Image **,const int,char **)) NULL)
+ status=(*method)(image,argc,argv);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returned from \"%.1024s\" filter module",tag);
+
+ }
+ /* Close the module */
+ (void) lt_dlclose(handle);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C o d e r I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetCoderInfo() returns a pointer to a CoderInfo structure that matches the
+% specified tag. If tag is NULL, the head of the module list is returned. If
+% no modules are loaded, or the requested module is not found, NULL is
+% returned.
+%
+% The format of the GetCoderInfo method is:
+%
+% const CoderInfo *GetCoderInfo(const char *tag,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o coder_list: Method GetCoderInfo returns a pointer CoderInfo
+% structure that matches the specified tag.
+%
+% o tag: a character string that represents the image format we are
+% looking for.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#if 0
+static const CoderInfo *
+GetCoderInfo(const char *tag, ExceptionInfo *exception)
+{
+ register CoderInfo
+ *p;
+
+ (void) InitializeMagicInfo(exception);
+ (void) GetModuleInfo(tag,exception);
+ if ((tag == (const char *) NULL) || (LocaleCompare(tag,"*") == 0))
+ return((const CoderInfo *) coder_list);
+ for (p=coder_list; p != (CoderInfo *) NULL; p=p->next)
+ if (LocaleCompare(p->tag,tag) == 0)
+ break;
+ if (p == (CoderInfo *) NULL)
+ ThrowException(exception,ModuleError,UnrecognizedModule,tag);
+ else
+ if (p != coder_list)
+ {
+ /*
+ Self-adjusting list.
+ */
+ if (p->previous != (CoderInfo *) NULL)
+ p->previous->next=p->next;
+ if (p->next != (CoderInfo *) NULL)
+ p->next->previous=p->previous;
+ p->previous=(CoderInfo *) NULL;
+ p->next=coder_list;
+ coder_list->previous=p;
+ coder_list=p;
+ }
+ return((const CoderInfo *) p);
+}
+#endif /* FUNCTION_UNUSED */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F i n d M a g i c k M o d u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FindMagickModule() finds a module with the specified module type and
+% file name. The buffer pointed to by 'path' is updated with the file path
+% if the file is found. MagickPass is returned if the module is found or
+% MagickFail is returned if the module can not be located.
+%
+% The format of the FindMagickModule method is:
+%
+% MagickPassFail FindMagickModule(const char *filename,
+% MagickModuleType module_type,char *path,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o filename: The module file name.
+%
+% o module_type: The module type (MagickCoderModule or MagickFilterModule)
+%
+% o path: A pointer to the buffer to place the path to the module file. The
+% buffer must be at least MaxTextExtent characters in size.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+static MagickPassFail
+FindMagickModule(const char *filename,MagickModuleType module_type,
+ char *path,ExceptionInfo *exception)
+{
+ MagickMap
+ path_map = (MagickMap) NULL;
+
+ MagickMapIterator
+ path_map_iterator = (MagickMapIterator) NULL;
+
+ const char
+ *key;
+
+ MagickPassFail
+ status=MagickFail;
+
+ assert(filename != (const char *) NULL);
+ assert(path != (char *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+ (void) strlcpy(path,filename,MaxTextExtent);
+
+ if (InitializeModuleSearchPath(module_type,exception) == MagickFail)
+ return (status);
+
+ switch (module_type)
+ {
+ case MagickCoderModule:
+ default:
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Searching for coder module file \"%s\" ...",
+ filename);
+ path_map=coder_path_map;
+ break;
+ }
+ case MagickFilterModule:
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Searching for filter module file \"%s\" ...",
+ filename);
+ path_map=filter_path_map;
+ break;
+ }
+ }
+
+ path_map_iterator=MagickMapAllocateIterator(path_map);
+
+ if (IsEventLogging())
+ {
+ char
+ list_seperator[2],
+ *search_path=0;
+
+ list_seperator[0]=DirectoryListSeparator;
+ list_seperator[1]='\0';
+ while(MagickMapIterateNext(path_map_iterator,&key))
+ {
+ if (search_path)
+ (void) ConcatenateString(&search_path,list_seperator);
+ (void) ConcatenateString(&search_path,
+ MagickMapDereferenceIterator(path_map_iterator,0));
+ }
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Searching for module file \"%s\" in path \"%s\"",
+ filename,search_path);
+
+ MagickFreeMemory(search_path);
+ MagickMapIterateToFront(path_map_iterator);
+ }
+
+ while(MagickMapIterateNext(path_map_iterator,&key))
+ {
+ FormatString(path,"%.1024s%.256s",
+ (const char *)MagickMapDereferenceIterator(path_map_iterator,0),
+ filename);
+
+ if (IsAccessible(path))
+ {
+ status=MagickPass;
+ break;
+ }
+ }
+
+ if (status == MagickFail)
+ path[0]='\0';
+
+ MagickMapDeallocateIterator(path_map_iterator);
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M o d u l e L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetModuleList() returns a list containing the names of modules which may be
+% loaded.
+%
+% The format of the GetModuleList function is:
+%
+% char **GetModuleList(ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o module_list: Method GetModuleList returns a list of available modules.
+% If an error occurs a NULL list is returned.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+static MagickPassFail
+GetModuleListForDirectory(const char *path, /* Directory to scan. */
+ char **list, /* List to extend. */
+ unsigned long *max_entries, /* Allocated list entries. */
+ ExceptionInfo *exception ) /* Any exception. */
+{
+ char
+ module_tag[MaxTextExtent];
+
+ DIR
+ *directory;
+
+ register long
+ i,
+ j;
+
+ struct dirent
+ *entry;
+
+ assert( path != (char *) NULL );
+ assert( list != (char **) NULL );
+ assert( max_entries != (unsigned long *) NULL );
+ assert( exception != (ExceptionInfo *) NULL );
+
+ directory=opendir(path);
+ if (directory == (const DIR *) NULL)
+ return(MagickFail);
+
+ /*
+ Find number of entries in list.
+ */
+ for (i=0; list[i] != (char *) NULL; i++);
+
+ entry=readdir(directory);
+ while ((entry != (struct dirent *) NULL) && (i < (long) *max_entries))
+ {
+ if (!GlobExpression(entry->d_name,ModuleGlobExpression))
+ {
+ entry=readdir(directory);
+ continue;
+ }
+ /*
+ Determine module tag
+ */
+ module_tag[0]='\0';
+ GetPathComponent(entry->d_name,BasePath,module_tag);
+ LocaleUpper(module_tag);
+ /*
+ Following is Windows VisualStudio build specific
+ */
+ if (LocaleNCompare("IM_MOD_",module_tag,7) == 0)
+ {
+ size_t
+ l,
+ o;
+
+ o=10;
+ for (l=0;
+ (l+o < sizeof(module_tag)) && (module_tag[l+o] != '\0');
+ l++)
+ module_tag[l] = module_tag[l+o];
+ module_tag[l]='\0';
+ module_tag[strlen(module_tag)-1]='\0';
+ }
+
+ /*
+ Add module tag to list if it is not already in list.
+ */
+ for (j=0; list[j] != (char *) NULL; j++)
+ {
+ if (LocaleCompare(module_tag,list[j]) == 0)
+ break;
+ }
+ if (list[j] == (char *) NULL)
+ {
+ list[i]=AllocateString(module_tag);
+ i++;
+ list[i]=(char *) NULL;
+ }
+
+ /*
+ Read next directory entry and continue
+ */
+ entry=readdir(directory);
+ }
+ (void) closedir(directory);
+ return(MagickPass);
+}
+static char **
+GetModuleList(ExceptionInfo *exception)
+{
+ MagickMap
+ path_map = (MagickMap) NULL;
+
+ MagickMapIterator
+ path_map_iterator = (MagickMapIterator) NULL;
+
+ const char
+ *key;
+
+ char
+ **modules;
+
+ unsigned long
+ max_entries;
+
+ if (InitializeModuleSearchPath(MagickCoderModule,exception) == MagickFail)
+ return ((char **) NULL);
+
+ max_entries=MAX_MODULES;
+ modules=MagickAllocateMemory(char **,(max_entries+1)*sizeof(char *));
+ if (modules == (char **) NULL)
+ return((char **) NULL);
+ modules[0]=(char *) NULL;
+
+ path_map=coder_path_map;
+ path_map_iterator=MagickMapAllocateIterator(path_map);
+
+ while(MagickMapIterateNext(path_map_iterator,&key))
+ {
+ const char
+ *path;
+
+ path=(const char *) MagickMapDereferenceIterator(path_map_iterator,0);
+ (void) GetModuleListForDirectory(path,modules,&max_entries,exception);
+ }
+
+ MagickMapDeallocateIterator(path_map_iterator);
+
+ return(modules);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e M a g i c k M o d u l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializeMagickModules() initializes the module loader.
+%
+% The format of the InitializeMagickModules() method is:
+%
+% InitializeMagickModules(void)
+%
+%
+*/
+MagickExport void
+InitializeMagickModules(void)
+{
+ ExceptionInfo
+ exception;
+
+ GetExceptionInfo(&exception);
+
+ if (module_list == (const ModuleInfo *) NULL)
+ {
+ /*
+ Read module aliases file.
+ */
+ if (!ltdl_initialized)
+ {
+ if (lt_dlinit() != 0)
+ MagickFatalError(ModuleFatalError,
+ UnableToInitializeModuleLoader,lt_dlerror());
+ ltdl_initialized=True;
+ }
+ (void) ReadModuleConfigureFile(ModuleFilename,0,&exception);
+ }
+ (void) InitializeModuleSearchPath(MagickCoderModule,&exception);
+ (void) InitializeModuleSearchPath(MagickFilterModule,&exception);
+
+ DestroyExceptionInfo(&exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n i t i a l i z e M o d u l e S e a r c h P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializeModuleSearchPath() initializes the module search path for the
+% specified type of module.
+%
+% The format of the InitializeModuleSearchPath method is:
+%
+% MagickPassFail InitializeModuleSearchPath(MagickModuleType module_type,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o module_type: The module type (MagickCoderModule or MagickFilterModule)
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+static void
+AddModulePath(MagickMap path_map, unsigned int *path_index,
+ const char *path,ExceptionInfo *exception)
+{
+ char
+ key[MaxTextExtent];
+
+ FormatString(key,"%u",*path_index);
+ (void) MagickMapAddEntry(path_map,key,(void *)path,0,exception);
+ (*path_index)++;
+}
+
+#if !defined(UseInstalledMagick) && defined(POSIX)
+static void
+ChopPathComponents(char *path,const unsigned long components)
+{
+ long
+ count;
+
+ register char
+ *p;
+
+ if (*path == '\0')
+ return;
+ p=path+strlen(path);
+ if (*p == *DirectorySeparator)
+ *p='\0';
+ for (count=0; (count < (long) components) && (p > path); p--)
+ if (*p == *DirectorySeparator)
+ {
+ *p='\0';
+ count++;
+ }
+}
+#endif /* !defined(UseInstalledMagick) && defined(POSIX) */
+
+MagickPassFail
+InitializeModuleSearchPath(MagickModuleType module_type,
+ ExceptionInfo *exception)
+{
+ MagickMap
+ path_map = (MagickMap) NULL;
+
+ MagickPassFail
+ status=MagickPass;
+
+ unsigned int
+ path_index=0;
+
+#if !defined(UseInstalledMagick)
+ char
+ path[MaxTextExtent];
+#endif /* !defined(UseInstalledMagick) */
+
+ const char
+ *module_path = NULL;
+
+ assert(exception != (ExceptionInfo *) NULL);
+
+ switch (module_type)
+ {
+ case MagickCoderModule:
+ default:
+ {
+ if (coder_path_map != (MagickMap) NULL)
+ {
+ /*
+ Already initialized.
+ */
+ return (status);
+ }
+ coder_path_map=MagickMapAllocateMap(MagickMapCopyString,MagickMapDeallocateString);
+ path_map=coder_path_map;
+ module_path = getenv("MAGICK_CODER_MODULE_PATH");
+ break;
+ }
+ case MagickFilterModule:
+ {
+ if (filter_path_map != (MagickMap) NULL)
+ {
+ /*
+ Already initialized.
+ */
+ return (status);
+ }
+ filter_path_map=MagickMapAllocateMap(MagickMapCopyString,MagickMapDeallocateString);
+ path_map=filter_path_map;
+ module_path = getenv("MAGICK_FILTER_MODULE_PATH");
+ break;
+ }
+ }
+
+ /*
+ Allow the module search path to be explicitly specified.
+ */
+ if ( module_path )
+ {
+ const char
+ *end = NULL,
+ *start = module_path;
+
+ end=start+strlen(start);
+ while ( start < end )
+ {
+ char
+ buffer[MaxTextExtent];
+
+ const char
+ *seperator;
+
+ int
+ length;
+
+ seperator = strchr(start,DirectoryListSeparator);
+ if (seperator)
+ length=seperator-start;
+ else
+ length=end-start;
+ if (length > MaxTextExtent-1)
+ length = MaxTextExtent-1;
+ (void) strncpy(buffer,start,length);
+ buffer[length]='\0';
+ if (buffer[length-1] != DirectorySeparator[0])
+ (void) strcat(buffer,DirectorySeparator);
+ AddModulePath(path_map,&path_index,buffer,exception);
+ start += length+1;
+ }
+ }
+
+#if defined(UseInstalledMagick)
+# if defined(MagickCoderModulesPath)
+ {
+ /*
+ Search hard coded paths.
+ */
+ char
+ *module_directory=NULL;
+
+ switch (module_type)
+ {
+ case MagickCoderModule:
+ default:
+ module_directory=MagickCoderModulesPath;
+ break;
+ case MagickFilterModule:
+ module_directory=MagickFilterModulesPath;
+ break;
+ }
+
+ AddModulePath(path_map,&path_index,module_directory,exception);
+ return (status);
+ }
+# else
+# if defined(MSWINDOWS)
+ {
+ /*
+ Locate path via registry key.
+ */
+ char
+ *key=NULL,
+ *key_value;
+
+ switch (module_type)
+ {
+ case MagickCoderModule:
+ default:
+ key="CoderModulesPath";
+ break;
+ case MagickFilterModule:
+ key="FilterModulesPath";
+ break;
+ }
+
+ key_value=NTRegistryKeyLookup(key);
+ if (key_value == (char *) NULL)
+ {
+ ThrowException(exception,ConfigureError,RegistryKeyLookupFailed,key);
+ return (MagickFail);
+ }
+
+ FormatString(path,"%.512s%s",key_value,DirectorySeparator);
+ AddModulePath(path_map,&path_index,path,exception);
+ return (status);
+ }
+# endif /* defined(MSWINDOWS) */
+# endif /* !defined(MagickCoderModulesPath) */
+# if !defined(MagickCoderModulesPath) && !defined(MSWINDOWS)
+# error MagickCoderModulesPath or MSWINDOWS must be defined when UseInstalledMagick is defined
+# endif
+#else /* end defined(UseInstalledMagick) */
+ if (getenv("MAGICK_HOME") != (char *) NULL)
+ {
+ /*
+ Search MAGICK_HOME.
+ */
+# if defined(POSIX)
+ char
+ *subdir=NULL;
+
+ switch (module_type)
+ {
+ case MagickCoderModule:
+ default:
+ subdir=MagickCoderModulesSubdir;
+ break;
+ case MagickFilterModule:
+ subdir=MagickFilterModulesSubdir;
+ break;
+ }
+
+ FormatString(path,"%.512s/lib/%s/",getenv("MAGICK_HOME"),subdir);
+# else
+ FormatString(path,"%.512s%s",getenv("MAGICK_HOME"),
+ DirectorySeparator);
+# endif /* !POSIX */
+ AddModulePath(path_map,&path_index,path,exception);
+ }
+ if (*SetClientPath((char *) NULL) != '\0')
+ {
+ /*
+ Search based on executable directory if directory is known.
+ */
+# if defined(POSIX)
+ char
+ *module_subdir=NULL,
+ prefix[MaxTextExtent];
+
+ switch (module_type)
+ {
+ case MagickCoderModule:
+ default:
+ module_subdir="coders";
+ break;
+ case MagickFilterModule:
+ module_subdir="filters";
+ break;
+ }
+
+ (void) strlcpy(prefix,SetClientPath((char *) NULL),MaxTextExtent);
+ ChopPathComponents(prefix,1);
+ FormatString(path,"%.512s/lib/%s/modules-Q%d/%s/",prefix,
+ MagickLibSubdir,QuantumDepth,module_subdir);
+# else /* end defined(POSIX) */
+ FormatString(path,"%.512s%s",SetClientPath((char *) NULL),
+ DirectorySeparator);
+# endif /* !POSIX */
+ AddModulePath(path_map,&path_index,path,exception);
+ }
+ if (getenv("HOME") != (char *) NULL)
+ {
+ /*
+ Search $HOME/.magick.
+ */
+ FormatString(path,"%.512s%s%s",getenv("HOME"),
+ *getenv("HOME") == '/' ? "/.magick" : "",DirectorySeparator);
+ AddModulePath(path_map,&path_index,path,exception);
+ }
+ /*
+ Search current directory.
+ */
+ strcpy(path,"");
+ AddModulePath(path_map,&path_index,path,exception);
+
+ return (status);
+#endif /* End defined(UseInstalledMagick) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M o d u l e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetModuleInfo() returns a pointer to a ModuleInfo structure that matches
+% the specified tag. If tag is NULL or "*", the head of the module alias
+% list is returned. If no modules are loaded, or the requested alias is not
+% found, NULL is returned.
+%
+% If GraphicsMagick has not been initialized via InitializeMagick()
+% then this function will not work.
+%
+% The format of the GetModuleInfo method is:
+%
+% const ModuleInfo *GetModuleInfo(const char *name,
+% ExceptionMagick *exception)
+%
+% A description of each parameter follows:
+%
+% o module_info: GetModuleInfo() returns a pointer to a ModuleInfo
+% structure that matches the specified tag.
+%
+% o name: a character string that represents the module alias we are
+% looking for.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const ModuleInfo *
+GetModuleInfo(const char *name,ExceptionInfo *exception)
+{
+ const ModuleInfo
+ *module_info=(const ModuleInfo *) NULL;
+
+ ARG_NOT_USED(exception);
+
+ if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
+ {
+ module_info=module_list;
+ }
+ else
+ {
+ register ModuleInfo
+ *p;
+
+ for (p=module_list; p != (ModuleInfo *) NULL; p=p->next)
+ if (LocaleCompare(p->name,name) == 0)
+ break;
+
+ if (p != (ModuleInfo *) NULL)
+ {
+ module_info=p;
+ if (p != module_list)
+ {
+ /*
+ Self-adjusting list.
+ */
+ if (p->previous != (ModuleInfo *) NULL)
+ p->previous->next=p->next;
+ if (p->next != (ModuleInfo *) NULL)
+ p->next->previous=p->previous;
+ p->previous=(ModuleInfo *) NULL;
+ p->next=module_list;
+ module_list->previous=p;
+ module_list=p;
+ }
+ }
+ }
+ return (module_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t M o d u l e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ListModuleInfo lists the module info to a file.
+%
+% The format of the ListModuleInfo method is:
+%
+% unsigned int ListModuleInfo(FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o file: An pointer to a FILE.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport unsigned int
+ListModuleInfo(FILE *file,ExceptionInfo *exception)
+{
+ register const ModuleInfo
+ *p;
+
+ register long
+ i;
+
+ if (file == (const FILE *) NULL)
+ file=stdout;
+ (void) GetModuleInfo("*",exception);
+ for (p=module_list; p != (ModuleInfo *) NULL; p=p->next)
+ {
+ if ((p->previous == (ModuleInfo *) NULL) ||
+ (LocaleCompare(p->path,p->previous->path) != 0))
+ {
+ if (p->previous != (ModuleInfo *) NULL)
+ (void) fprintf(file,"\n");
+ if (p->path != (char *) NULL)
+ (void) fprintf(file,"Path: %.1024s\n\n",p->path);
+ (void) fprintf(file,"Magick Module\n");
+ (void) fprintf(file,"-------------------------------------------------"
+ "------------------------------\n");
+ }
+ if (p->stealth)
+ continue;
+
+ (void) fprintf(file,"%.1024s",p->magick);
+ for (i=(long) strlen(p->magick); i <= 10; i++)
+ (void) fprintf(file," ");
+ (void) fprintf(file,"%.1024s",(p->name ? p->name : "(null)"));
+ (void) fprintf(file,"\n");
+ }
+ (void) fflush(file);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% O p e n M o d u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% OpenModule() loads a module, and invokes its registration method. It
+% returns MagickPass on success, and MagickFail if there is an error.
+%
+% The format of the OpenModule method is:
+%
+% MagickPassFail OpenModule(const char *module,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method OpenModule returns MagickPass if the specified module is
+% loaded, otherwise MagickFail.
+%
+% o module: a character string that indicates the module to load.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail
+OpenModule(const char *module,ExceptionInfo *exception)
+{
+ {
+ char
+ message[MaxTextExtent],
+ module_file[MaxTextExtent],
+ module_name[MaxTextExtent],
+ name[MaxTextExtent],
+ path[MaxTextExtent];
+
+ CoderInfo
+ *coder_info;
+
+ ModuleHandle
+ handle;
+
+ register ModuleInfo
+ *p;
+
+ /*
+ Assign module name from alias.
+ */
+ assert(module != (const char *) NULL);
+ (void) strlcpy(module_name,module,MaxTextExtent);
+ if (module_list != (ModuleInfo *) NULL)
+ for (p=module_list; p != (ModuleInfo *) NULL; p=p->next)
+ if (LocaleCompare(p->magick,module) == 0)
+ {
+ (void) strlcpy(module_name,p->name,MaxTextExtent);
+ break;
+ }
+
+ /*
+ Ignore already loaded modules.
+ */
+ for (coder_info=coder_list; coder_info != (CoderInfo *) NULL;
+ coder_info=coder_info->next)
+ if (LocaleCompare(coder_info->tag,module_name) == 0)
+ break;
+ if (coder_info != (CoderInfo *) NULL)
+ return MagickPass;
+
+ /*
+ Find module file.
+ */
+ handle=(ModuleHandle) NULL;
+ TagToCoderModuleName(module_name,module_file);
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Searching for module \"%s\" using file name \"%s\"",
+ module_name, module_file);
+
+ *path='\0';
+#if 1
+ /*
+ FindMagickModule returns a ConfigureError if the module is not
+ found.
+ */
+ if (!FindMagickModule(module_file,MagickCoderModule,path,exception))
+ return(False);
+#else
+ if ((module_list != (ModuleInfo *) NULL) &&
+ (module_list->path != (char *) NULL))
+ GetPathComponent(module_list->path,HeadPath,path);
+ (void) strlcat(path,DirectorySeparator,MaxTextExtent);
+ (void) strlcat(path,module_file,MaxTextExtent);
+#endif
+ /*
+ Load module
+ */
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Opening module at path \"%s\" ...", path);
+
+ handle=lt_dlopen(path);
+ if (handle == (ModuleHandle) NULL)
+ {
+ FormatString(message,"\"%.1024s: %.1024s\"",path,lt_dlerror());
+ ThrowException(exception,ModuleError,UnableToLoadModule,message);
+ return(MagickFail);
+ }
+ /*
+ Add module to coder module list.
+ */
+ coder_info=SetCoderInfo(module_name);
+ if (coder_info == (CoderInfo*) NULL)
+ {
+ (void) lt_dlclose(handle);
+ return(MagickFail);
+ }
+ coder_info->handle=handle;
+ (void) time(&coder_info->load_time);
+ if (!RegisterModule(coder_info,exception))
+ return(False);
+ /*
+ Locate and record RegisterFORMATImage function
+ */
+ TagToFunctionName(module_name,"Register%sImage",name);
+ coder_info->register_function=(void (*)(void)) lt_dlsym(handle,name);
+ if (coder_info->register_function == (void (*)(void)) NULL)
+ {
+ FormatString(message,"\"%.1024s: %.1024s\"",module_name,lt_dlerror());
+ ThrowException(exception,ModuleError,UnableToRegisterImageFormat,
+ message);
+ return(MagickFail);
+ }
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Function \"%s\" in module \"%s\" at address %p", name,
+ module_name, coder_info->register_function);
+
+ /*
+ Locate and record UnregisterFORMATImage function
+ */
+ TagToFunctionName(module_name,"Unregister%sImage",name);
+ coder_info->unregister_function=(void (*)(void)) lt_dlsym(handle,name);
+ if (coder_info->unregister_function == (void (*)(void)) NULL)
+ {
+ FormatString(message,"\"%.1024s: %.1024s\"",module_name,lt_dlerror());
+ ThrowException(exception,ModuleError,UnableToRegisterImageFormat,
+ message);
+ return(MagickFail);
+ }
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Function \"%s\" in module \"%s\" at address %p", name,
+ module_name, coder_info->unregister_function);
+
+ /*
+ Execute RegisterFORMATImage function
+ */
+ coder_info->register_function();
+ }
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% O p e n M o d u l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method OpenModules loads all available modules.
+%
+% The format of the OpenModules method is:
+%
+% MagickPassFail OpenModules(ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method OpenModules returns True if the modules are loaded,
+% otherwise False.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickPassFail
+OpenModules(ExceptionInfo *exception)
+{
+ (void) GetMagickInfo((char *) NULL,exception);
+ {
+ char
+ **modules;
+
+ register char
+ **p;
+
+ register long
+ i;
+
+ /*
+ Load all modules.
+ */
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Loading all modules ...");
+ modules=GetModuleList(exception);
+ if ((modules == (char **) NULL) || (*modules == NULL))
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "GetModuleList did not return any modules");
+ MagickFreeMemory(modules);
+ return(False);
+ }
+ for (p=modules; *p != (char *) NULL; p++)
+ (void) OpenModule(*p,exception);
+ /*
+ Free resources.
+ */
+ for (i=0; modules[i]; i++)
+ MagickFreeMemory(modules[i]);
+ MagickFreeMemory(modules);
+ }
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d M o d u l e C o n f i g u r e F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ReadModuleConfigureFile reads the module configuration file which
+% maps format names to a module name.
+%
+% The format of the ReadModuleConfigureFile method is:
+%
+% MagickPassFail ReadModuleConfigureFile(const char *basename,
+% const unsigned long depth,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: ReadModuleConfigureFile() returns True if at least one
+% mapping is defined otherwise False.
+%
+% o basename: The color configuration filename.
+%
+% o depth: depth of <include /> statements.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail
+ReadModuleConfigureFile(const char *basename,
+ const unsigned int depth,
+ ExceptionInfo *exception)
+{
+ size_t
+ length;
+
+ char
+ path[MaxTextExtent],
+ *xml;
+
+ if (depth == 0)
+ {
+ size_t
+ i;
+
+ /*
+ Load default set of module aliases from the static aliases table.
+ */
+ for (i=0 ; i < sizeof(ModuleAliases)/sizeof(ModuleAliases[0]); i++)
+ {
+ ModuleInfo
+ *module_info;
+
+ module_info=MagickAllocateMemory(ModuleInfo *,sizeof(ModuleInfo));
+ if (module_info == (ModuleInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateModuleInfo);
+ module_info->path=(char *) BuiltInPath;
+ module_info->magick=(char *) ModuleAliases[i].magick;
+ module_info->name=(char *) ModuleAliases[i].name;
+ module_info->stealth=MagickFalse;
+ module_info->signature=MagickSignature;
+ module_info->previous=(ModuleInfo *) NULL;
+ module_info->next=(ModuleInfo *) NULL;
+ if (module_list == (ModuleInfo *) NULL)
+ {
+ module_list=module_info;
+ continue;
+ }
+ module_list->next=module_info;
+ module_info->previous=module_list;
+ module_list=module_list->next;
+ }
+ }
+
+ /*
+ Read the module configure file (if any).
+ */
+ (void) strlcpy(path,basename,sizeof(path));
+ if (depth == 0)
+ {
+ ExceptionInfo
+ exception_local;
+
+ GetExceptionInfo(&exception_local);
+ xml=(char *) GetConfigureBlob(basename,path,&length,&exception_local);
+ if (exception_local.severity != ConfigureError)
+ CopyException(exception,&exception_local);
+ DestroyExceptionInfo(&exception_local);
+ }
+ else
+ {
+ xml=(char *) FileToBlob(basename,&length,exception);
+ }
+ if (xml != (char *) NULL)
+ {
+ char
+ keyword[MaxTextExtent],
+ *q,
+ *token;
+
+ MagickBool
+ in_entry;
+
+ size_t
+ token_max_length;
+
+ token=AcquireString(xml);
+ token_max_length=strlen(token);
+ in_entry=MagickFalse;
+ for (q=xml; *q != '\0'; )
+ {
+ /*
+ Interpret XML.
+ */
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == '\0')
+ break;
+ (void) strlcpy(keyword,token,sizeof(keyword));
+ if (LocaleNCompare(keyword,"<!--",4) == 0)
+ {
+ /*
+ Comment element.
+ */
+ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
+ MagickGetToken(q,&q,token,token_max_length);
+ continue;
+ }
+ if (LocaleCompare(keyword,"<include") == 0)
+ {
+ /*
+ Include element.
+ */
+ while ((*token != '>') && (*q != '\0'))
+ {
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(keyword,"file") == 0)
+ {
+ if (depth > 200)
+ ThrowException(exception,ConfigureError,
+ IncludeElementNestedTooDeeply,path);
+ else
+ {
+ char
+ filename[MaxTextExtent];
+
+ GetPathComponent(path,HeadPath,filename);
+ if (*filename != '\0')
+ (void) strlcat(filename,DirectorySeparator,sizeof(filename));
+ (void) strlcat(filename,token,sizeof(filename));
+ (void) ReadModuleConfigureFile(filename,depth+1,exception);
+ }
+ if (module_list != (ModuleInfo *) NULL)
+ while (module_list->next != (ModuleInfo *) NULL)
+ module_list=module_list->next;
+ }
+ }
+ continue;
+ }
+ if (LocaleCompare(keyword,"<module") == 0)
+ {
+ ModuleInfo
+ *module_info;
+
+ /*
+ Allocate memory for the module list.
+ */
+ in_entry=MagickTrue;
+ module_info=MagickAllocateMemory(ModuleInfo *,sizeof(ModuleInfo));
+ if (module_info == (ModuleInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateModuleInfo);
+ (void) memset(module_info,0,sizeof(ModuleInfo));
+ module_info->path=AcquireString(path);
+ module_info->signature=MagickSignature;
+ if (module_list == (ModuleInfo *) NULL)
+ {
+ module_list=module_info;
+ continue;
+ }
+ module_list->next=module_info;
+ module_info->previous=module_list;
+ module_list=module_list->next;
+ continue;
+ }
+ if (LocaleCompare(keyword,"/>") == 0)
+ {
+ /*
+ Closing a module alias specification.
+ */
+ if (in_entry)
+ {
+ /*
+ Remove any existing entry with same name (last one wins).
+ */
+ {
+ ModuleInfo
+ *module_info;
+
+ for (module_info=module_list->previous;
+ module_info != (ModuleInfo *) NULL;
+ module_info=module_info->previous)
+ {
+ if (LocaleCompare(module_list->magick,module_info->magick) == 0)
+ {
+ DestroyModuleInfoEntry(module_info);
+ break;
+ }
+ }
+ }
+ in_entry=MagickFalse;
+ }
+ }
+ if (module_list == (ModuleInfo *) NULL)
+ continue;
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ switch (*keyword)
+ {
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare((char *) keyword,"magick") == 0)
+ {
+ module_list->magick=AcquireString(token);
+ break;
+ }
+ break;
+ }
+ case 'N':
+ case 'n':
+ {
+ if (LocaleCompare((char *) keyword,"name") == 0)
+ {
+ module_list->name=AcquireString(token);
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare((char *) keyword,"stealth") == 0)
+ {
+ module_list->stealth=LocaleCompare(token,"True") == 0;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ MagickFreeMemory(token);
+ MagickFreeMemory(xml);
+ }
+ if (module_list == (ModuleInfo *) NULL)
+ return(MagickFail);
+ while (module_list->previous != (ModuleInfo *) NULL)
+ module_list=module_list->previous;
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r M o d u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RegisterModule() adds an entry to the module list. It returns a pointer to
+% the registered entry on success.
+%
+% The format of the RegisterModule method is:
+%
+% CoderInfo *RegisterModule(CoderInfo *entry,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o info: a pointer to the registered entry is returned.
+%
+% o entry: a pointer to the CoderInfo structure to register.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static CoderInfo *
+RegisterModule(CoderInfo *entry,ExceptionInfo *exception)
+{
+ register CoderInfo
+ *p;
+
+ ARG_NOT_USED(exception);
+
+ /*
+ Delete any existing tag.
+ */
+ assert(entry != (CoderInfo *) NULL);
+ assert(entry->signature == MagickSignature);
+ entry->previous=(CoderInfo *) NULL;
+ entry->next=(CoderInfo *) NULL;
+ if (coder_list == (CoderInfo *) NULL)
+ {
+ /*
+ Start module list.
+ */
+ coder_list=entry;
+ return(entry);
+ }
+ /*
+ Tag is added in lexographic order.
+ */
+ for (p=coder_list; p->next != (CoderInfo *) NULL; p=p->next)
+ if (LocaleCompare(p->tag,entry->tag) >= 0)
+ break;
+ if (LocaleCompare(p->tag,entry->tag) == 0)
+ {
+ /*
+ Module already registered.
+ */
+ return(entry);
+ }
+ if (LocaleCompare(p->tag,entry->tag) < 0)
+ {
+ /*
+ Add entry after target.
+ */
+ entry->next=p->next;
+ p->next=entry;
+ entry->previous=p;
+ if (entry->next != (CoderInfo *) NULL)
+ entry->next->previous=entry;
+ return(entry);
+ }
+ /*
+ Add entry before target.
+ */
+ entry->next=p;
+ entry->previous=p->previous;
+ p->previous=entry;
+ if (entry->previous != (CoderInfo *) NULL)
+ entry->previous->next=entry;
+ if (p == coder_list)
+ coder_list=entry;
+ return(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t C o d e r I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetCoderInfo() allocates a CoderInfo structure and initializes the members
+% to default values.
+%
+% The format of the SetCoderInfo method is:
+%
+% CoderInfo *SetCoderInfo(const char *tag)
+%
+% A description of each parameter follows:
+%
+% o coder_list: SetCoderInfo() returns the allocated and initialized
+% CoderInfo structure.
+%
+% o tag: a character string that represents the image format associated
+% with the CoderInfo structure.
+%
+%
+*/
+static CoderInfo *
+SetCoderInfo(const char *tag)
+{
+ CoderInfo
+ *entry;
+
+ assert(tag != (const char *) NULL);
+ entry=MagickAllocateMemory(CoderInfo *,sizeof(CoderInfo));
+ if (entry == (CoderInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateModuleInfo);
+ (void) memset(entry,0,sizeof(CoderInfo));
+ entry->tag=AcquireString(tag);
+ entry->signature=MagickSignature;
+ return(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T a g T o C o d e r M o d u l e N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TagToCoderModuleName() takes a module tag and obtains the filename of the
+% corresponding coder module.
+%
+% The format of the TagToCoderModuleName method is:
+%
+% char *TagToCoderModuleName(const char *tag)
+%
+% A description of each parameter follows:
+%
+% o tag: a character string representing the module tag.
+%
+% o module_name: A buffer to write the module name. Should be at least
+% MaxTextExtent long.
+%
+*/
+static void
+TagToCoderModuleName(const char *tag,char *module_name)
+{
+ assert(tag != (char *) NULL);
+ assert(module_name != (char *) NULL);
+#if defined(HasLTDL)
+ (void) FormatString(module_name,"%.1024s.la",tag);
+ (void) LocaleLower(module_name);
+#else
+#if defined(MSWINDOWS)
+ if (LocaleNCompare("IM_MOD_",tag,7) == 0)
+ (void) strlcpy(module_name,tag,MaxTextExtent);
+ else
+ {
+# if defined(_DEBUG)
+ FormatString(module_name,"IM_MOD_DB_%.1024s_.dll",tag);
+# else
+ FormatString(module_name,"IM_MOD_RL_%.1024s_.dll",tag);
+# endif /* defined(_DEBUG) */
+ }
+#endif /* defined(MSWINDOWS) */
+#endif /* defined(HasLTDL) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T a g T o F i l t e r M o d u l e N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TagToFilterModuleName takes a module tag and returns the filename of the
+% corresponding filter module.
+%
+% The format of the TagToFilterModuleName method is:
+%
+% void TagToFilterModuleName(const char *tag)
+%
+% A description of each parameter follows:
+%
+% o tag: a character string representing the module tag.
+%
+*/
+static void
+TagToFilterModuleName(const char *tag, char *module_name)
+{
+ assert(tag != (char *) NULL);
+ assert(module_name != (char *) NULL);
+#if defined(HasLTDL)
+ (void) FormatString(module_name,"%.1024s.la",tag);
+ (void) LocaleLower(module_name);
+#else
+ (void) FormatString(module_name,"%.1024s.dll",tag);
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T a g T o F u n c t i o n N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TagToFunctionName() formats the module tag name to a string using the
+% upper-case tag name as the input string, and a user-provided format.
+% This function is used to prepare the RegisterTAGImage and UnregisterTAGImage
+% function names passed lt_dlsym.
+%
+% The format of the TagToFunctionName method is:
+%
+% TagToFunctionName(const char *tag, const char *format, char *function)
+%
+% A description of each parameter follows:
+%
+% o tag: the module tag.
+%
+% o format: a sprintf-compatible format string containing %s where the
+% upper-case tag name is to be inserted.
+%
+% o function: pointer to a destination buffer for the formatted result.
+%
+*/
+static void
+TagToFunctionName(const char *tag,const char *format,char *function)
+{
+ char
+ extended_format[MaxTextExtent],
+ function_name[MaxTextExtent];
+
+ assert(tag != (const char *) NULL);
+ assert(format != (const char *) NULL);
+ assert(function != (char *) NULL);
+ (void) strlcpy(function_name,tag,MaxTextExtent);
+ LocaleUpper(function_name);
+
+#if defined(PREFIX_MAGICK_SYMBOLS)
+ (void) strlcpy(extended_format,"Gm",MaxTextExtent);
+ (void) strlcat(extended_format,format,MaxTextExtent);
+#else
+ (void) strlcpy(extended_format,format,MaxTextExtent);
+#endif
+ FormatString(function,extended_format,function_name);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n l o a d M o d u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% UnloadModule() unloads a module, and invokes its de-registration method.
+% Returns True on success, and False if there is an error.
+%
+% The format of the UnloadModule method is:
+%
+% unsigned int UnloadModule(const CoderInfo *coder_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o coder_info: The coder info.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static unsigned int
+UnloadModule(const CoderInfo *coder_info,ExceptionInfo *exception)
+{
+ char
+ message[MaxTextExtent];
+
+ unsigned int
+ status=True;
+
+ assert(coder_info != (const CoderInfo *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Unloading \"%s\" module ...", coder_info->tag);
+
+ /*
+ Invoke module unregister (UnregisterFORMATImage) function
+ */
+ if (coder_info->unregister_function != (void (*)(void)) NULL)
+ coder_info->unregister_function();
+
+ /*
+ Close module. Don't close JP2 module since it uses atexit().
+ */
+ if ( strcmp("JP2",coder_info->tag) != 0 )
+ {
+ if (lt_dlclose((ModuleHandle) coder_info->handle))
+ {
+ FormatString(message,"\"%.1024s: %.1024s\"",coder_info->tag,
+ lt_dlerror());
+ ThrowException(exception,ModuleError,FailedToCloseModule,message);
+ status=False;
+ }
+ }
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r M o d u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% UnregisterModule() removes a tag from the module info list. It returns
+% False if the tag does not exist in the list otherwise True.
+%
+% The format of the UnregisterModule method is:
+%
+% unsigned int UnregisterModule(const char *tag,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: Method UnregisterModule returns False if the tag does not
+% exist in the list otherwise it returns True.
+%
+% o tag: a character string that represents the image format we are
+% looking for.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static unsigned int
+UnregisterModule(const char *tag,ExceptionInfo *exception)
+{
+ CoderInfo
+ *coder_info;
+
+ register CoderInfo
+ *p;
+
+ unsigned int
+ status=False;
+
+ assert(tag != (const char *) NULL);
+ for (p=coder_list; p != (CoderInfo *) NULL; p=p->next)
+ {
+ if (LocaleCompare(p->tag,tag) != 0)
+ continue;
+ status=UnloadModule((CoderInfo *) p,exception);
+ MagickFreeMemory(p->tag);
+ if (p->previous != (CoderInfo *) NULL)
+ p->previous->next=p->next;
+ else
+ {
+ coder_list=p->next;
+ if (p->next != (CoderInfo *) NULL)
+ p->next->previous=(CoderInfo *) NULL;
+ }
+ if (p->next != (CoderInfo *) NULL)
+ p->next->previous=p->previous;
+ coder_info=p;
+ MagickFreeMemory(coder_info);
+ break;
+ }
+ return (status);
+}
+
+#endif /* defined(SupportMagickModules) */
diff --git a/magick/module.h b/magick/module.h
new file mode 100644
index 0000000..e0f5d76
--- /dev/null
+++ b/magick/module.h
@@ -0,0 +1,84 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Modules Methods.
+*/
+#ifndef _MAGICK_MODULE_H
+#define _MAGICK_MODULE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Modules declarations.
+*/
+
+extern MagickExport MagickPassFail
+ ListModuleInfo(FILE *file,ExceptionInfo *exception);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+/*
+ Module alias list entry
+ Maintains modules.mgk path, and the module name corresponding
+ to each magick tag.
+ Used to support module_list, which is intialized by reading modules.mgk,
+*/
+typedef struct _ModuleInfo
+{
+ char
+ *path, /* Path to modules.mgk which created alias */
+ *magick, /* Format name */
+ *name; /* Name of module supporting format. */
+
+ unsigned int
+ stealth; /* If true, hide when printing module list */
+
+ unsigned long
+ signature;
+
+ struct _ModuleInfo
+ *previous,
+ *next;
+} ModuleInfo;
+
+extern MagickExport const ModuleInfo
+ *GetModuleInfo(const char *,ExceptionInfo *);
+
+extern MagickExport MagickPassFail
+ ExecuteModuleProcess(const char *tag,Image **image,
+ const int argc,char **argv),
+ ExecuteStaticModuleProcess(const char *,Image **,const int,char **),
+ ListModuleInfo(FILE *file,ExceptionInfo *exception),
+ OpenModule(const char *module,ExceptionInfo *exception),
+ OpenModules(ExceptionInfo *exception);
+
+extern MagickExport void
+ DestroyModuleInfo(void),
+ DestroyMagickModules(void),
+ InitializeMagickModules(void),
+ RegisterStaticModules(void),
+ UnregisterStaticModules(void);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/monitor.c b/magick/monitor.c
new file mode 100644
index 0000000..be8da4a
--- /dev/null
+++ b/magick/monitor.c
@@ -0,0 +1,196 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M OOO N N IIIII TTTTT OOO RRRR %
+% MM MM O O NN N I T O O R R %
+% M M M O O N N N I T O O RRRR %
+% M M O O N NN I T O O R R %
+% M M OOO N N IIIII T OOO R R %
+% %
+% %
+% GraphicsMagick Progress Monitor Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% December 1995 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/monitor.h"
+#include "magick/utility.h"
+
+/*
+ Global declarations.
+*/
+static MonitorHandler
+ monitor_handler = (MonitorHandler) NULL;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M o n i t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMonitor() calls the monitor handler method with a text string that
+% describes the task and a measure of completion. The method returns True
+% on success otherwise False if an error is encountered, e.g. if there was a
+% user interrupt.
+%
+% The format of the MagickMonitor method is:
+%
+% MagickPassFail MagickMonitor(const char *text,
+% const magick_int64_t quantum,const magick_uint64_t span,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o text: Description of the task being performed.
+%
+% o quantum: The position relative to the span parameter which represents
+% how much progress has been made toward completing a task.
+%
+% o span: The span relative to completing a task.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickPassFail
+MagickMonitor(const char *text,
+ const magick_int64_t quantum,
+ const magick_uint64_t span,
+ ExceptionInfo *exception)
+{
+ MagickPassFail
+ status;
+
+ assert(text != (const char *) NULL);
+ ProcessPendingEvents(text);
+ status=MagickPass;
+ if (monitor_handler != (MonitorHandler) NULL)
+ status=(*monitor_handler)(text,quantum,span,exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M o n i t o r F o r m a t t e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMonitorFormatted() calls the monitor handler method with a
+% printf type format specification and variable argument list. Also
+% passed are quantum and span values which provide a measure of
+% completion. The method returns True on success otherwise False if
+% an error is encountered, e.g. if there was a user interrupt.
+%
+% The format of the MagickMonitorFormatted method is:
+%
+% MagickPassFail MagickMonitorFormatted(const magick_int64_t quantum,
+% const magick_uint64_t span,ExceptionInfo *exception,
+% const char *format,...)
+%
+% A description of each parameter follows:
+%
+% o quantum: The position relative to the span parameter which represents
+% how much progress has been made toward completing a task.
+%
+% o span: The span relative to completing a task.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+% o format: A string describing the format to use to write the remaining
+% arguments.
+%
+*/
+MagickExport MagickPassFail
+MagickMonitorFormatted(const magick_int64_t quantum,
+ const magick_uint64_t span,
+ ExceptionInfo *exception,
+ const char *format,...)
+{
+ MagickPassFail
+ status;
+
+
+ status=MagickPass;
+ if (monitor_handler != (MonitorHandler) NULL)
+ {
+ va_list
+ operands;
+
+ char
+ text[MaxTextExtent];
+
+ va_start(operands,format);
+ FormatStringList(text,format,operands);
+ va_end(operands);
+ status=MagickMonitor(text,quantum,span,exception);
+ }
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t M o n i t o r H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetMonitorHandler() sets the monitor handler to the specified method
+% and returns the previous monitor handler.
+%
+% The format of the SetMonitorHandler method is:
+%
+% MonitorHandler SetMonitorHandler(MonitorHandler handler)
+%
+% A description of each parameter follows:
+%
+% o handler: Specifies a pointer to a method to handle monitors.
+%
+%
+*/
+MagickExport MonitorHandler
+SetMonitorHandler(MonitorHandler handler)
+{
+ MonitorHandler
+ previous_handler;
+
+ previous_handler=monitor_handler;
+ monitor_handler=handler;
+ return(previous_handler);
+}
diff --git a/magick/monitor.h b/magick/monitor.h
new file mode 100644
index 0000000..5315428
--- /dev/null
+++ b/magick/monitor.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2003 - 2012 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Progress Monitor Methods.
+*/
+#ifndef _MAGICK_MONITOR_H
+#define _MAGICK_MONITOR_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ /*
+ Monitor typedef declarations.
+ */
+ typedef MagickPassFail
+ (*MonitorHandler)(const char *text,const magick_int64_t quantum,
+ const magick_uint64_t span,ExceptionInfo *exception);
+
+ /*
+ Monitor declarations.
+ */
+ extern MagickExport MonitorHandler
+ SetMonitorHandler(MonitorHandler handler);
+
+ extern MagickExport MagickPassFail
+ MagickMonitor(const char *text,
+ const magick_int64_t quantum,const magick_uint64_t span,
+ ExceptionInfo *exception);
+
+ extern MagickExport MagickPassFail
+ MagickMonitorFormatted(const magick_int64_t quantum,
+ const magick_uint64_t span,
+ ExceptionInfo *exception,
+ const char *format,...) MAGICK_ATTRIBUTE((__format__ (__printf__,4,5)));
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/montage.c b/magick/montage.c
new file mode 100644
index 0000000..7807064
--- /dev/null
+++ b/magick/montage.c
@@ -0,0 +1,792 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M OOO N N TTTTT AAA GGGG EEEEE %
+% MM MM O O NN N T A A G E %
+% M M M O O N N N T AAAAA G GG EEE %
+% M M O O N NN T A A G G E %
+% M M OOO N N T A A GGG EEEEE %
+% %
+% %
+% GraphicsMagick Methods to Create Image Thumbnails %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/composite.h"
+#include "magick/constitute.h"
+#include "magick/decorate.h"
+#include "magick/gem.h"
+#include "magick/monitor.h"
+#include "magick/montage.h"
+#include "magick/pixel_cache.h"
+#include "magick/render.h"
+#include "magick/resize.h"
+#include "magick/texture.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e M o n t a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneMontageInfo() makes a copy of the given montage info structure. If
+% NULL is specified, a new image info structure is created initialized to
+% default values.
+%
+% The format of the CloneMontageInfo method is:
+%
+% MontageInfo *CloneMontageInfo(const ImageInfo *image_info,
+% const MontageInfo *montage_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o montage_info: The montage info.
+%
+%
+*/
+MagickExport MontageInfo *CloneMontageInfo(const ImageInfo *image_info,
+ const MontageInfo *montage_info)
+{
+ MontageInfo
+ *clone_info;
+
+ clone_info=MagickAllocateMemory(MontageInfo *,sizeof(MontageInfo));
+ if (clone_info == (MontageInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateMontageInfo);
+ GetMontageInfo(image_info,clone_info);
+ if (montage_info == (MontageInfo *) NULL)
+ return(clone_info);
+ if (montage_info->geometry != (char *) NULL)
+ clone_info->geometry=AllocateString(montage_info->geometry);
+ if (montage_info->tile != (char *) NULL)
+ clone_info->tile=AllocateString(montage_info->tile);
+ if (montage_info->title != (char *) NULL)
+ clone_info->title=AllocateString(montage_info->title);
+ if (montage_info->frame != (char *) NULL)
+ clone_info->frame=AllocateString(montage_info->frame);
+ if (montage_info->texture != (char *) NULL)
+ clone_info->texture=AllocateString(montage_info->texture);
+ if (montage_info->font != (char *) NULL)
+ clone_info->font=AllocateString(montage_info->font);
+ clone_info->pointsize=montage_info->pointsize;
+ clone_info->border_width=montage_info->border_width;
+ clone_info->shadow=montage_info->shadow;
+ clone_info->fill=montage_info->fill;
+ clone_info->stroke=montage_info->stroke;
+ clone_info->background_color=montage_info->background_color;
+ clone_info->border_color=montage_info->border_color;
+ clone_info->matte_color=montage_info->matte_color;
+ clone_info->gravity=montage_info->gravity;
+ (void) strlcpy(clone_info->filename,montage_info->filename,MaxTextExtent);
+ return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y M o n t a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyMontageInfo() deallocates memory associated with montage_info.
+%
+% The format of the DestroyMontageInfo method is:
+%
+% void DestroyMontageInfo(MontageInfo *montage_info)
+%
+% A description of each parameter follows:
+%
+% o montage_info: Specifies a pointer to an MontageInfo structure.
+%
+%
+*/
+MagickExport void DestroyMontageInfo(MontageInfo *montage_info)
+{
+ assert(montage_info != (MontageInfo *) NULL);
+ assert(montage_info->signature == MagickSignature);
+ if (montage_info->geometry != (char *) NULL)
+ MagickFreeMemory(montage_info->geometry);
+ if (montage_info->tile != (char *) NULL)
+ MagickFreeMemory(montage_info->tile);
+ if (montage_info->title != (char *) NULL)
+ MagickFreeMemory(montage_info->title);
+ if (montage_info->frame != (char *) NULL)
+ MagickFreeMemory(montage_info->frame);
+ if (montage_info->texture != (char *) NULL)
+ MagickFreeMemory(montage_info->texture);
+ if (montage_info->font != (char *) NULL)
+ MagickFreeMemory(montage_info->font);
+ MagickFreeMemory(montage_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M o n t a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMontageInfo() initializes montage_info to default values.
+%
+% The format of the GetMontageInfo method is:
+%
+% void GetMontageInfo(const ImageInfo *image_info,
+% MontageInfo *montage_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: a structure of type ImageInfo.
+%
+% o montage_info: Specifies a pointer to a MontageInfo structure.
+%
+%
+*/
+MagickExport void GetMontageInfo(const ImageInfo *image_info,
+ MontageInfo *montage_info)
+{
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickSignature);
+ assert(montage_info != (MontageInfo *) NULL);
+ (void) memset(montage_info,0,sizeof(MontageInfo));
+ (void) strlcpy(montage_info->filename,image_info->filename,MaxTextExtent);
+ montage_info->geometry=AllocateString(DefaultTileGeometry);
+ montage_info->gravity=CenterGravity;
+ montage_info->tile=AllocateString("6x4");
+ if (image_info->font != (char *) NULL)
+ montage_info->font=AllocateString(image_info->font);
+ montage_info->pointsize=image_info->pointsize;
+ montage_info->fill.opacity=OpaqueOpacity;
+ montage_info->stroke.opacity=TransparentOpacity;
+ montage_info->background_color=image_info->background_color;
+ montage_info->border_color=image_info->border_color;
+ montage_info->matte_color=image_info->matte_color;
+ montage_info->signature=MagickSignature;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o n t a g e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Montageimages() is a layout manager that lets you tile one or more
+% thumbnails across an image canvas.
+%
+% The format of the MontageImages method is:
+%
+% Image *MontageImages(const Image *images,const MontageInfo *montage_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o images: Specifies a pointer to an array of Image structures.
+%
+% o montage_info: Specifies a pointer to a MontageInfo structure.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+static int SceneCompare(const void *x,const void *y)
+{
+ Image
+ **image_1,
+ **image_2;
+
+ image_1=(Image **) x;
+ image_2=(Image **) y;
+ return((int) ((*image_1)->scene-(*image_2)->scene));
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+MagickExport Image *MontageImages(const Image *images,
+ const MontageInfo *montage_info,ExceptionInfo *exception)
+{
+#define MontageImageText "[%s] Create visual image directory..."
+#define TileImageText "[%s] Create image tiles..."
+
+ char
+ tile_geometry[MaxTextExtent],
+ *title = 0;
+
+ const ImageAttribute
+ *attribute;
+
+ DrawInfo
+ *draw_info;
+
+ FrameInfo
+ frame_info;
+
+ Image
+ *image,
+ **image_list,
+ **master_list,
+ *montage,
+ *texture,
+ *tile_image,
+ *thumbnail;
+
+ ImageInfo
+ *image_info;
+
+ int
+ flags;
+
+ long
+ x,
+ x_offset,
+ y,
+ y_offset;
+
+ MonitorHandler
+ handler;
+
+ register long
+ i;
+
+ register PixelPacket
+ *q;
+
+ RectangleInfo
+ bounds,
+ geometry,
+ tile_info;
+
+ TypeMetric
+ metrics;
+
+ unsigned int
+ concatenate;
+
+ unsigned long
+ bevel_width,
+ border_width,
+ count,
+ height,
+ images_per_page,
+ max_height,
+ number_lines,
+ number_images,
+ tile,
+ tiles,
+ tiles_per_column,
+ tiles_per_page,
+ tiles_per_row,
+ title_offset,
+ total_tiles,
+ width;
+
+ /*
+ Create image tiles.
+ */
+ assert(images != (Image *) NULL);
+ assert(images->signature == MagickSignature);
+ assert(montage_info != (MontageInfo *) NULL);
+ assert(montage_info->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ number_images=GetImageListLength(images);
+ master_list=ImageListToArray(images,exception);
+ if (master_list == (Image **) NULL)
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateImageMontage);
+ image_list=master_list;
+ thumbnail=(Image *) NULL;
+ for (i=0; i < (long) number_images; i++)
+ {
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ image=image_list[i];
+ SetGeometry(image,&geometry);
+ /* flags= */ (void) GetMagickGeometry(montage_info->geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ /*
+ Use ThumbnailImage() rather than ZoomImage() to resize montage
+ thumbnails provided that the user has not specified an image
+ filter, and the montage thumbnail is smaller than the
+ image. This should lead to faster montages for large images.
+ */
+ if ((image->filter != UndefinedFilter) ||
+ (geometry.width>image->columns) || (geometry.height>image->rows))
+ thumbnail=ZoomImage(image,geometry.width,geometry.height,exception);
+ else
+ thumbnail=ThumbnailImage(image,geometry.width,geometry.height,exception);
+ if (thumbnail == (Image *) NULL)
+ break;
+ image_list[i]=thumbnail;
+ (void) SetMonitorHandler(handler);
+ if (!MagickMonitorFormatted(i,number_images,&image->exception,
+ TileImageText,image->filename))
+ break;
+ }
+ if (i < (long) number_images)
+ {
+ if (!thumbnail)
+ --i;
+
+ for (tile=0; (long) tile <= i; tile++)
+ if (image_list[tile])
+ DestroyImage(image_list[tile]);
+ MagickFreeMemory(master_list);
+ return((Image *) NULL);
+ }
+ /*
+ Sort image list by increasing tile number.
+ */
+ for (i=0; i < (long) number_images; i++)
+ if (image_list[i]->scene == 0)
+ break;
+ if (i == (long) number_images)
+ qsort((void *) image_list,number_images,sizeof(Image *),SceneCompare);
+ /*
+ Determine tiles per row and column.
+ */
+ tiles_per_row=1;
+ tiles_per_column=1;
+ while ((tiles_per_row*tiles_per_column) < number_images)
+ {
+ tiles_per_row++;
+ tiles_per_column++;
+ }
+ if (montage_info->tile != (char *) NULL)
+ {
+ x=0;
+ y=0;
+ tiles_per_column=number_images;
+ /* flags= */ (void) GetGeometry(montage_info->tile,&x,&y,&tiles_per_row,
+ &tiles_per_column);
+ }
+ /*
+ Determine tile sizes.
+ */
+ concatenate=False;
+ SetGeometry(image_list[0],&tile_info);
+ tile_info.x=(long) montage_info->border_width;
+ tile_info.y=(long) montage_info->border_width;
+ if (montage_info->geometry != (char *) NULL)
+ {
+ /*
+ Initialize tile geometry.
+ */
+ flags=GetGeometry(montage_info->geometry,&tile_info.x,&tile_info.y,
+ &tile_info.width,&tile_info.height);
+ if ((tile_info.x == 0) && (tile_info.y == 0))
+ concatenate=!((flags & WidthValue) || (flags & HeightValue));
+ }
+ border_width=montage_info->border_width;
+ bevel_width=0;
+ if (montage_info->frame != (char *) NULL)
+ {
+ char
+ absolute_geometry[MaxTextExtent];
+
+ (void) memset(&frame_info,0,sizeof(FrameInfo));
+ frame_info.width=tile_info.width;
+ frame_info.height=tile_info.height;
+ FormatString(absolute_geometry,"%.1024s!",montage_info->frame);
+ flags=GetMagickGeometry(absolute_geometry,&frame_info.outer_bevel,
+ &frame_info.inner_bevel,&frame_info.width,&frame_info.height);
+ if ((flags & HeightValue) == 0)
+ frame_info.height=frame_info.width;
+ if ((flags & XValue) == 0)
+ frame_info.outer_bevel=(long) (frame_info.width >> 2)+1;
+ if ((flags & YValue) == 0)
+ frame_info.inner_bevel=frame_info.outer_bevel;
+ frame_info.x=(long) frame_info.width;
+ frame_info.y=(long) frame_info.height;
+ bevel_width=Max(frame_info.inner_bevel,frame_info.outer_bevel);
+ border_width=Max(frame_info.width,frame_info.height);
+ }
+ for (i=1; i < (long) number_images; i++)
+ {
+ if (image_list[i]->columns > tile_info.width)
+ tile_info.width=image_list[i]->columns;
+ if (image_list[i]->rows > tile_info.height)
+ tile_info.height=image_list[i]->rows;
+ }
+ /*
+ Initialize draw attributes.
+ */
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ image_info->background_color=montage_info->background_color;
+ image_info->border_color=montage_info->border_color;
+ draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
+ if (montage_info->font != (char *) NULL)
+ (void) CloneString(&draw_info->font,montage_info->font);
+ draw_info->pointsize=montage_info->pointsize;
+ draw_info->gravity=NorthGravity;
+ draw_info->stroke=montage_info->stroke;
+ draw_info->fill=montage_info->fill;
+ draw_info->text=AllocateString("");
+ (void) GetTypeMetrics(image_list[0],draw_info,&metrics);
+ texture=(Image *) NULL;
+ if (montage_info->texture != (char *) NULL)
+ {
+ (void) strlcpy(image_info->filename,montage_info->texture,
+ MaxTextExtent);
+ texture=ReadImage(image_info,exception);
+ }
+ /*
+ Determine the number of lines in an next label.
+ */
+ title=TranslateText(image_info,image_list[0],montage_info->title);
+ title_offset=0;
+ if (montage_info->title != (char *) NULL)
+ title_offset=(unsigned long) (2*(metrics.ascent-metrics.descent)*
+ MultilineCensus(title)+2*tile_info.y);
+ number_lines=0;
+ for (i=0; i < (long) number_images; i++)
+ {
+ attribute=GetImageAttribute(image_list[i],"label");
+ if (attribute == (ImageAttribute *) NULL)
+ continue;
+ if (MultilineCensus(attribute->value) > number_lines)
+ number_lines=MultilineCensus(attribute->value);
+ }
+ /*
+ Allocate next structure.
+ */
+ tile_image=AllocateImage(NULL);
+ montage=AllocateImage(image_info);
+ montage->scene=1;
+ images_per_page=(number_images-1)/(tiles_per_row*tiles_per_column)+1;
+ tiles=0;
+ total_tiles=number_images;
+ for (i=0; i < (long) images_per_page; i++)
+ {
+ /*
+ Determine bounding box.
+ */
+ tiles_per_page=Min(number_images,tiles_per_row*tiles_per_column);
+ x_offset=0;
+ y_offset=(long) title_offset;
+ max_height=0;
+ bounds.width=0;
+ bounds.height=0;
+ for (tile=0; tile < tiles_per_page; tile++)
+ {
+ width=concatenate ? image_list[tile]->columns : tile_info.width;
+ x_offset+=width+(tile_info.x+border_width)*2;
+ if (x_offset > (long) bounds.width)
+ bounds.width=x_offset;
+ if (image_list[tile]->rows > max_height)
+ max_height=image_list[tile]->rows;
+ if (((tile+1) == tiles_per_page) || (((tile+1) % tiles_per_row) == 0))
+ {
+ x_offset=0;
+ height=concatenate ? max_height : tile_info.height;
+ y_offset+=(unsigned long) (height+(tile_info.y+border_width)*2+
+ (metrics.ascent-metrics.descent+4)*number_lines+
+ (montage_info->shadow ? 4 : 0));
+ if (y_offset > (long) bounds.height)
+ bounds.height=y_offset;
+ max_height=0;
+ }
+ }
+ /*
+ Initialize montage image.
+ */
+ (void) strlcpy(montage->filename,montage_info->filename,MaxTextExtent);
+ montage->columns=bounds.width;
+ montage->rows=bounds.height;
+ (void) SetImage(montage,OpaqueOpacity);
+ /*
+ Set montage geometry.
+ */
+ montage->montage=AllocateString((char *) NULL);
+ count=1;
+ for (tile=0; tile < tiles_per_page; tile++)
+ count+=(unsigned long) strlen(image_list[tile]->filename)+1;
+ montage->directory=MagickAllocateMemory(char *,count);
+ if ((montage->montage == (char *) NULL) ||
+ (montage->directory == (char *) NULL))
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateImageMontage);
+ x_offset=0;
+ y_offset=(long) title_offset;
+ FormatString(montage->montage,"%ldx%ld%+ld%+ld",
+ (long) (tile_info.width+(tile_info.x+border_width)*2),
+ (long) (tile_info.height+(tile_info.y+border_width)*2+(metrics.ascent-
+ metrics.descent+4)*number_lines+(montage_info->shadow ? 4 : 0)),x_offset,
+ y_offset);
+ *montage->directory='\0';
+ for (tile=0; tile < tiles_per_page; tile++)
+ {
+ (void) strlcat(montage->directory,image_list[tile]->filename,
+ MaxTextExtent);
+ (void) strcat(montage->directory,"\n");
+ }
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ if (texture != (Image *) NULL)
+ (void) TextureImage(montage,texture);
+ if (montage_info->title != (char *) NULL)
+ {
+ char
+ geometry[MaxTextExtent];
+
+ /*
+ Annotate composite image with title.
+ */
+ FormatString(geometry,"%lux%lu%+ld%+ld",montage->columns,(unsigned long)
+ (2*(metrics.ascent-metrics.descent)),0L,(long) ((metrics.ascent-
+ metrics.descent)+tile_info.y+4+metrics.ascent));
+ (void) CloneString(&draw_info->geometry,geometry);
+ (void) CloneString(&draw_info->text,title);
+ (void) AnnotateImage(montage,draw_info);
+ }
+ (void) SetMonitorHandler(handler);
+ /*
+ Copy tile to the composite.
+ */
+ x_offset=tile_info.x;
+ y_offset=(long) title_offset+tile_info.y;
+ max_height=0;
+ for (tile=0; tile < tiles_per_page; tile++)
+ {
+ /*
+ Copy this tile to the composite.
+ */
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ image=CloneImage(image_list[tile],0,0,True,exception);
+ width=concatenate ? image->columns : tile_info.width;
+ if (image->rows > max_height)
+ max_height=image->rows;
+ height=concatenate ? max_height : tile_info.height;
+ if (border_width != 0)
+ {
+ Image
+ *border_image;
+
+ RectangleInfo
+ border_info;
+
+ /*
+ Put a border around the image.
+ */
+ border_info.width=border_width;
+ border_info.height=border_width;
+ if (montage_info->frame != (char *) NULL)
+ {
+ border_info.width=(width-image->columns+1)/2;
+ border_info.height=(height-image->rows+1)/2;
+ }
+ border_image=BorderImage(image,&border_info,exception);
+ if (border_image != (Image *) NULL)
+ {
+ DestroyImage(image);
+ image=border_image;
+ }
+ }
+ /*
+ Gravitate as specified by the tile gravity.
+ */
+ tile_image->columns=width;
+ tile_image->rows=height;
+ tile_image->gravity=montage_info->gravity;
+ if (image->gravity != ForgetGravity)
+ tile_image->gravity=image->gravity;
+ FormatString(tile_geometry,"%lux%lu+0+0",image->columns,image->rows);
+ flags=GetImageGeometry(tile_image,tile_geometry,False,&geometry);
+ x=(long) (geometry.x+border_width);
+ y=(long) (geometry.y+border_width);
+ if ((montage_info->frame != (char *) NULL) && (bevel_width != 0))
+ {
+ FrameInfo
+ tile_info;
+
+ Image
+ *frame_image;
+
+ /*
+ Put an ornamental border around this tile.
+ */
+ tile_info=frame_info;
+ tile_info.width=width+2*frame_info.width;
+ tile_info.height=height+2*frame_info.height;
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ tile_info.height+=(unsigned long) ((metrics.ascent-metrics.descent+
+ 4)*MultilineCensus(attribute->value));
+ frame_image=FrameImage(image,&tile_info,exception);
+ if (frame_image != (Image *) NULL)
+ {
+ DestroyImage(image);
+ image=frame_image;
+ }
+ x=0;
+ y=0;
+ }
+ if (LocaleCompare(image->magick,"NULL") != 0)
+ {
+ /*
+ Composite background with tile.
+ */
+ (void) CompositeImage(montage,image->compose,image,x_offset+x,
+ y_offset+y);
+ if (montage_info->shadow)
+ {
+ register long
+ columns,
+ rows;
+
+ /*
+ Put a shadow under the tile to show depth.
+ */
+ for (rows=0; rows < ((long) image->rows-4); rows++)
+ {
+ q=GetImagePixels(montage,(long) (x+x_offset+image->columns),
+ (long) (y+y_offset+rows+4),Min(tile_info.x,4),1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (columns=0; columns < Min(tile_info.x,4); columns++)
+ {
+ Modulate(0.0,0.0,53.0,&q->red,&q->green,&q->blue);
+ q++;
+ }
+ if (!SyncImagePixels(montage))
+ break;
+ }
+ for (rows=0; rows < Min(tile_info.y,4); rows++)
+ {
+ q=GetImagePixels(montage,x+x_offset+4,y+y_offset+
+ (long) image->rows+rows,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (columns=0; columns < (long) image->columns; columns++)
+ {
+ Modulate(0.0,0.0,53.0,&q->red,&q->green,&q->blue);
+ q++;
+ }
+ if (!SyncImagePixels(montage))
+ break;
+ }
+ }
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (const ImageAttribute *) NULL)
+ {
+ char
+ geometry[MaxTextExtent];
+
+ /*
+ Annotate composite tile with label.
+ */
+ FormatString(geometry,"%lux%lu%+ld%+ld",
+ (montage_info->frame ? image->columns : width)-2*border_width,
+ (unsigned long) (metrics.ascent-metrics.descent+4)*
+ MultilineCensus(attribute->value),x_offset+border_width,
+ (montage_info->frame ? y_offset+height+border_width+2 :
+ y_offset+tile_info.height+border_width+(montage_info->shadow ?
+ 4 : 0))+(long) (metrics.ascent-metrics.descent));
+ (void) CloneString(&draw_info->geometry,geometry);
+ (void) CloneString(&draw_info->text,attribute->value);
+ (void) AnnotateImage(montage,draw_info);
+ }
+ }
+ x_offset+=width+(tile_info.x+border_width)*2;
+ if (((tile+1) == tiles_per_page) || (((tile+1) % tiles_per_row) == 0))
+ {
+ x_offset=tile_info.x;
+ y_offset+=(unsigned long) (height+(tile_info.y+border_width)*2+
+ (metrics.ascent-metrics.descent+4)*number_lines+
+ (montage_info->shadow ? 4 : 0));
+ max_height=0;
+ }
+ DestroyImage(image_list[tile]);
+ image_list[tile]=(Image *) NULL;
+ (void) SetMonitorHandler(handler);
+ if (!MagickMonitorFormatted(tiles,total_tiles,&image->exception,
+ MontageImageText,image->filename))
+ {
+ DestroyImage(image);
+ image=(Image *) NULL;
+ break;
+ }
+ DestroyImage(image);
+ image=(Image *) NULL;
+ tiles++;
+ }
+ if ((i+1) < (long) images_per_page)
+ {
+ /*
+ Allocate next image structure.
+ */
+ AllocateNextImage(image_info,montage);
+ if (montage->next == (Image *) NULL)
+ {
+ DestroyImageList(montage);
+ montage=(Image *) NULL;
+ return((Image *) NULL);
+ }
+ montage=montage->next;
+ image_list+=tiles_per_page;
+ number_images-=tiles_per_page;
+ }
+ }
+ MagickFreeMemory(title);
+ DestroyImage(tile_image);
+ if (texture != (Image *) NULL)
+ DestroyImage(texture);
+ MagickFreeMemory(master_list);
+ DestroyDrawInfo(draw_info);
+ DestroyImageInfo(image_info);
+ while (montage->previous != (Image *) NULL)
+ montage=montage->previous;
+ return(montage);
+}
diff --git a/magick/montage.h b/magick/montage.h
new file mode 100644
index 0000000..a9ebe7c
--- /dev/null
+++ b/magick/montage.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Image Montage Methods.
+*/
+#ifndef _MAGICK_MONTAGE_H
+#define _MAGICK_MONTAGE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport Image
+ *MontageImages(const Image *,const MontageInfo *,ExceptionInfo *);
+
+extern MagickExport MontageInfo
+ *CloneMontageInfo(const ImageInfo *,const MontageInfo *);
+
+extern MagickExport void
+ DestroyMontageInfo(MontageInfo *),
+ GetMontageInfo(const ImageInfo *,MontageInfo *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_MONTAGE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/nt_base.c b/magick/nt_base.c
new file mode 100644
index 0000000..fe78297
--- /dev/null
+++ b/magick/nt_base.c
@@ -0,0 +1,2681 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N N TTTTT %
+% NN N T %
+% N N N T %
+% N NN T %
+% N N T %
+% %
+% %
+% Windows NT Utility Methods for GraphicsMagick %
+% %
+% %
+% Software Design %
+% John Cristy %
+% December 1996 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+#include "magick/studio.h"
+#if defined(MSWINDOWS)
+/*
+ Include declarations.
+*/
+#include <sys/types.h>
+#include <sys/utime.h>
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#if defined(HasLTDL)
+# include "ltdl.h"
+#endif /* defined(HasLTDL) */
+#include "magick/nt_base.h"
+
+/*
+ Static declarations.
+*/
+#if !defined(HasLTDL)
+static char
+ *NTslsearchpath = (char *) NULL;
+#endif
+static void
+ *gs_dll_handle = (void *)NULL;
+static GhostscriptVectors
+ gs_vectors;
+
+static MagickPassFail NTstrerror_r(LONG errnum, char *strerrbuf, size_t buflen);
+
+/*
+ External declarations.
+*/
+#if !defined(MSWINDOWS)
+extern "C" BOOL WINAPI
+ DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved);
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T c l o s e d i r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTclosedir closes the named directory stream and frees the DIR
+% structure.
+%
+% The format of the NTclosedir method is:
+%
+% void NTclosedir(DIR *entry)
+%
+% A description of each parameter follows:
+%
+% o entry: Specifies a pointer to a DIR structure.
+%
+%
+*/
+MagickExport int NTclosedir(DIR *entry)
+{
+ assert(entry != (DIR *) NULL);
+ FindClose(entry->hSearch);
+ MagickFreeMemory(entry);
+ return 0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DllMain %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DllMain is an entry point to the DLL which is called when processes
+% and threads are initialized and terminated, or upon calls to the
+% Windows LoadLibrary and FreeLibrary functions.
+%
+% The function returns TRUE of it succeeds, or FALSE if initialization fails.
+%
+% The format of the DllMain method is:
+%
+% BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+%
+% A description of each parameter follows:
+%
+% o hinstDLL: handle to the DLL module
+%
+% o fdwReason: reason for calling function.
+%
+% May have values:
+% DLL_PROCESS_ATTACH - DLL is being loaded into virtual address
+% space of current process.
+% DLL_THREAD_ATTACH - Indicates that the current process is
+% creating a new thread. Called under the
+% context of the new thread.
+% DLL_THREAD_DETACH - Indicates that the thread is exiting.
+% Called under the context of the exiting
+% thread.
+% DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
+% from the virtual address space of the
+% current process.
+%
+% o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
+% and DLL_PROCESS_DETACH.
+%
+*/
+#if defined(_DLL) && defined( ProvideDllMain )
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ switch ( fdwReason )
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+#define ENV_VAR_MAX 32767 /* environment variable max is 32,767 bytes */
+#define DLL_PATH_MAX 1024
+
+ char
+ dll_path[DLL_PATH_MAX],
+ current_path[ENV_VAR_MAX];
+
+ long count;
+
+ count = GetModuleFileName(hinstDLL,dll_path,DLL_PATH_MAX);
+ if (count) {
+ for ( ; count>0 ; --count)
+ {
+ if (dll_path[count]=='\\')
+ {
+ dll_path[count+1]='\0';
+ break;
+ }
+ }
+ InitializeMagick(dll_path);
+ count = GetEnvironmentVariable("PATH",current_path,ENV_VAR_MAX);
+ if (strstr(current_path,dll_path) == NULL)
+ {
+ if (strlen(dll_path)+count+1 < ENV_VAR_MAX-1)
+ {
+ char
+ new_path[ENV_VAR_MAX];
+
+ FormatString(new_path,"%.*s;%.*s",DLL_PATH_MAX,dll_path,
+ ENV_VAR_MAX-DLL_PATH_MAX-1,current_path);
+ SetEnvironmentVariable("PATH",new_path);
+ }
+ }
+ break;
+ }
+ /* If we get here, then GetModuleFileName must have failed */
+ return FALSE;
+ break;
+ }
+ case DLL_PROCESS_DETACH:
+ DestroyMagick();
+ break;
+ default:
+ {
+ /* Do nothing */
+ }
+ }
+ return TRUE;
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Exit calls TerminateProcess for Win95. Should quit the program
+% and not return.
+%
+% The format of the Exit method is:
+%
+% void Exit(int status)
+%
+% A description of each parameter follows:
+%
+% o status: an integer value representing the status of the terminating
+% process.
+%
+%
+*/
+MagickExport void Exit(int status)
+{
+ if (IsWindows95())
+ TerminateProcess(GetCurrentProcess(),(unsigned int) status);
+ exit(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t M M U P a g e S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetMMUPageSize() returns the VM pagesize used by the MMU. The VM
+% pagesize is the number of bytes retrieved due to one page fault.
+%
+% The format of the MagickGetMMUPageSize method is:
+%
+% long MagickGetMMUPageSize()
+%
+*/
+MagickExport long MagickGetMMUPageSize()
+{
+ return 4096;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t F i l e A t t r i b u t e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetFileAttributes() returns the file attributes for a specified
+% file in a structure of type MagickStatStruct_t.
+%
+% The format of the MagickGetFileAttributes method is:
+%
+% int MagickGetFileAttributes(const char *filename,
+% MagickStatStruct_t *statbuf)
+%
+% A description of each parameter follows:
+%
+% o filename: Path to the file
+%
+% o statbuf: A structure of type MagickStatStruct_t to populate.
+%
+%
+*/
+MagickExport int MagickGetFileAttributes(const char *filename,
+ MagickStatStruct_t *statbuf)
+{
+ if (MagickStat(filename, statbuf) != 0)
+ return -1;
+
+ return 0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t F i l e A t t r i b u t e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetFileAttributes() sets the access and modification time file
+% attributes based on values provided via in a structure of type
+% MagickStatStruct_t.
+%
+% The format of the MagickGetFileAttributes method is:
+%
+% int MagickSetFileAttributes(const char *filename,
+% const MagickStatStruct_t *statbuf)
+%
+% A description of each parameter follows:
+%
+% o filename: Path to the file
+%
+% o statbuf: A structure of type MagickStatStruct_t to populate.
+%
+%
+*/
+MagickExport int MagickSetFileAttributes(const char *filename,
+ const MagickStatStruct_t *statbuf)
+{
+ /*
+ Setting file timestamps on Windows is actually almost the same as on POSIX systems.
+ https://msdn.microsoft.com/en-us/library/4wacf567.aspx
+ */
+ struct _utimbuf
+ ut;
+
+ ut.actime = statbuf->st_atime;
+ ut.modtime = statbuf->st_mtime;
+
+ if (_utime(filename, &ut) == -1)
+ return -1;
+
+ return 0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s W i n d o w s 9 5 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsWindows95 returns true if the system is Windows 95.
+%
+% The format of the IsWindows95 method is:
+%
+% int IsWindows95()
+%
+% A description of each parameter follows:
+%
+% o status: an integer value representing the status of the terminating
+% process.
+%
+%
+*/
+MagickExport MagickBool IsWindows95()
+{
+ OSVERSIONINFO
+ version_info;
+
+ version_info.dwOSVersionInfoSize=sizeof(version_info);
+ if (GetVersionEx(&version_info) &&
+ (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
+ return(MagickTrue);
+ return(MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% InitializeWIN32ExceptionHandlers %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeWIN32ExceptionHandlers registers a handler for WIN32
+% exceptions (similar to POSIX signals but different).
+%
+% The format of the InitializeWIN32ExceptionHandlers method is:
+%
+% void InitializeWIN32ExceptionHandlers()
+%
+%
+*/
+static LONG WINAPI
+MagickUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *info)
+{
+ /*
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms680634%28v=vs.85%29.aspx
+
+ http://www.codeproject.com/Articles/11132/Walking-the-callstack
+
+ http://www.microsoft.com/msj/0197/exception/exception.aspx
+
+ Return values:
+
+ EXCEPTION_EXECUTE_HANDLER (0x1)
+
+ Return from UnhandledExceptionFilter and execute the associated
+ exception handler. This usually results in process termination.
+
+ EXCEPTION_CONTINUE_EXECUTION (0xffffffff)
+
+ Return from UnhandledExceptionFilter and continue execution from
+ the point of the exception. Note that the filter function is
+ free to modify the continuation state by modifying the exception
+ information supplied through its LPEXCEPTION_POINTERS parameter.
+
+ EXCEPTION_CONTINUE_SEARCH (0x0)
+
+ Proceed with normal execution of UnhandledExceptionFilter. That
+ means obeying the SetErrorMode flags, or invoking the
+ Application Error pop-up message box.
+
+ The EXCEPTION_POINTERS structure has the definition:
+
+ https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082%28v=vs.85%29.aspx
+ typedef struct _EXCEPTION_RECORD {
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ struct _EXCEPTION_RECORD *ExceptionRecord;
+ PVOID ExceptionAddress;
+ DWORD NumberParameters;
+ ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+ } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
+
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms679284%28v=vs.85%29.aspx
+ We don't care about PCONTEXT because it is processor-specific and includes low level
+ details such as register contents.
+
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms679331%28v=vs.85%29.aspx
+ typedef struct _EXCEPTION_POINTERS {
+ PEXCEPTION_RECORD ExceptionRecord;
+ PCONTEXT ContextRecord;
+ } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
+
+ */
+ static const struct {
+ DWORD code;
+ const char *text;
+ }
+ except_descr[] =
+ {
+ /*
+ The thread tried to read from or write to a virtual address
+ for which it does not have the appropriate access.
+ */
+#if defined(EXCEPTION_ACCESS_VIOLATION)
+ { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
+#endif
+ /*
+ The thread tried to access an array element that is out of
+ bounds and the underlying hardware supports bounds checking.
+ */
+#if defined(EXCEPTION_ARRAY_BOUNDS_EXCEEDED)
+ { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
+#endif
+ /*
+ The thread tried to read or write data that is misaligned on
+ hardware that does not provide alignment. For example,
+ 16-bit values must be aligned on 2-byte boundaries; 32-bit
+ values on 4-byte boundaries, and so on.
+ */
+#if defined(EXCEPTION_DATATYPE_MISALIGNMENT)
+ { EXCEPTION_DATATYPE_MISALIGNMENT, "Datatype misalignment" },
+#endif
+ /*
+ One of the operands in a floating-point operation is
+ denormal. A denormal value is one that is too small to
+ represent as a standard floating-point value.
+ */
+#if defined(EXCEPTION_FLT_DENORMAL_OPERAND)
+ { EXCEPTION_FLT_DENORMAL_OPERAND, "Float - denormal operand" },
+#endif
+ /*
+ The thread tried to divide a floating-point value by a
+ floating-point divisor of zero.
+ */
+#if defined(EXCEPTION_FLT_DIVIDE_BY_ZERO)
+ { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Float - divide by zero" },
+#endif
+ /*
+ This exception represents any floating-point exception not
+ included in this list.
+ */
+#if defined(EXCEPTION_FLT_INVALID_OPERATION)
+ { EXCEPTION_FLT_INVALID_OPERATION, "Float - invalid operation" },
+#endif
+ /*
+ The exponent of a floating-point operation is greater than the
+ magnitude allowed by the corresponding type.
+ */
+#if defined(EXCEPTION_FLT_OVERFLOW)
+ { EXCEPTION_FLT_OVERFLOW, "Float overflow" },
+#endif
+ /*
+ The stack overflowed or underflowed as the result of a
+ floating-point operation.
+ */
+#if defined(EXCEPTION_FLT_STACK_CHECK)
+ { EXCEPTION_FLT_STACK_CHECK, "Float - stack under/overflow" },
+#endif
+ /*
+ The exponent of a floating-point operation is less than the
+ magnitude allowed by the corresponding type.
+ */
+#if defined(EXCEPTION_FLT_UNDERFLOW)
+ { EXCEPTION_FLT_UNDERFLOW, "Float - underflow" },
+#endif
+ /*
+ The thread tried to execute an invalid instruction.
+ */
+#if defined(EXCEPTION_ILLEGAL_INSTRUCTION)
+ { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
+#endif
+ /*
+ The thread tried to access a page that was not present, and
+ the system was unable to load the page. For example, this
+ exception might occur if a network connection is lost while
+ running a program over the network.
+ */
+#if defined(EXCEPTION_IN_PAGE_ERROR)
+ { EXCEPTION_IN_PAGE_ERROR, "MMU page-in error" },
+#endif
+ /*
+ The thread tried to divide an integer value by an integer
+ divisor of zero.
+ */
+#if defined(EXCEPTION_INT_DIVIDE_BY_ZERO)
+ { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
+#endif
+ /*
+ The result of an integer operation caused a carry out of the
+ most significant bit of the result.
+ */
+#if defined(EXCEPTION_INT_OVERFLOW)
+ { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
+#endif
+ /*
+ The thread tried to execute an instruction whose operation is
+ not allowed in the current machine mode.
+ */
+#if defined(EXCEPTION_PRIV_INSTRUCTION)
+ { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
+#endif
+ /*
+ The thread used up its stack.
+ */
+#if defined(EXCEPTION_STACK_OVERFLOW)
+ { EXCEPTION_STACK_OVERFLOW, "Stack overflow" }
+#endif
+ };
+
+ char
+ message[MaxTextExtent];
+
+ const char
+ *text = NULL;
+
+ size_t
+ i;
+
+ DWORD
+ code = info->ExceptionRecord->ExceptionCode;
+
+ /*
+ Linear search for explanation of error code.
+ */
+ for (i=0; i < sizeof(except_descr)/sizeof(except_descr[0]); i++)
+ if (except_descr[i].code == code)
+ {
+ text = except_descr[i].text;
+ break;
+ }
+
+ /*
+ If this is an exception we handle
+ */
+ if (text != NULL)
+ {
+ /*
+ Release persistent resources
+ */
+ PanicDestroyMagick();
+
+ /*
+ Output messages like:
+
+ gm.exe identify: caught exception 0xC0000005 "Access violation"...
+ */
+ FormatString(message,
+ "%s: caught exception 0x%08X \"%s\"...",
+ GetClientName(), (unsigned int) code, text);
+ if (write(STDERR_FILENO,message,
+ (MAGICK_POSIX_IO_SIZE_T) strlen(message)) == -1)
+ {
+ /* Exists to quench warning */
+ }
+
+ /*
+ Return from UnhandledExceptionFilter and execute the
+ associated exception handler. This usually results in process
+ termination.
+ */
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+
+ /*
+ Can also look at ExceptionFlags and check for EXCEPTION_NONCONTINUABLE.
+ */
+
+ /*
+ Proceed with normal execution of UnhandledExceptionFilter. That
+ means obeying the SetErrorMode flags, or invoking the Application
+ Error pop-up message box.
+ */
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+MagickExport void
+NTInitializeExceptionHandlers()
+{
+
+ (void) SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+ (void) SetUnhandledExceptionFilter(MagickUnhandledExceptionFilter);
+}
+
+#if !defined(HasLTDL)
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T d l c l o s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTdlclose unloads the module associated with the passed handle.
+% Zero is returned on success.
+%
+% The format of the NTdlclose method is:
+%
+% void NTdlclose(void *handle)
+%
+% A description of each parameter follows:
+%
+% o handle: Specifies a handle to a previously loaded dynamic module.
+%
+*/
+MagickExport int NTdlclose(void *handle)
+{
+ /* FreeLibrary returns zero for failure */
+ return (!(FreeLibrary(handle)));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T d l e r r o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTdlerror returns a pointer to a string describing the last error
+% associated with a NTdl* function. Note that this function is not thread
+% safe so it should only be used under the protection of a lock.
+%
+% The format of the NTdlerror method is:
+%
+% const char * NTdlerror(void)
+%
+% A description of each parameter follows:
+%
+*/
+MagickExport const char *NTdlerror(void)
+{
+ static char
+ last_error[MaxTextExtent];
+
+ char
+ *error;
+
+ last_error[0]='\0';
+ error=NTGetLastError();
+ if (error)
+ strlcpy(last_error,error,MaxTextExtent);
+ MagickFreeMemory(error);
+ return (last_error);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T d l e x i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NTdlexit() exits the dynamic module loading subsystem.
+%
+% The format of the NTdlexit method is:
+%
+% int NTdlexit(void)
+%
+*/
+MagickExport int NTdlexit(void)
+{
+ return(0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T d l i n i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTdlinit initializes the dynamic module loading subsystem.
+%
+% The format of the NTdlinit method is:
+%
+% int NTdlinit(void)
+%
+*/
+MagickExport int NTdlinit(void)
+{
+ return(0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T d l o p e n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTdlopen loads a dynamic module into memory and returns a handle
+% that can be used to access the various procedures in the module.
+%
+% The format of the NTdlopen method is:
+%
+% void *NTdlopen(const char *filename)
+%
+% A description of each parameter follows:
+%
+% o path: Specifies a pointer to string representing dynamic module that
+% is to be loaded.
+%
+*/
+MagickExport void *NTdlopen(const char *filename)
+{
+#define MaxPathElements 31
+
+ char
+ buffer[MaxTextExtent];
+
+ int
+ index;
+
+ register char
+ *p,
+ *q;
+
+ register int
+ i;
+
+ void
+ *handle;
+
+ UINT
+ errorMode;
+
+ // Set error mode so that dialog box is not displayed on error.
+ errorMode=SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+
+ // Load library via name
+ handle=(void *) LoadLibrary(filename);
+
+ // If library failed to load, but a search path is defined, then
+ // attempt to load library via search path.
+ if ((handle == (void *) NULL) && (NTslsearchpath != NULL))
+ {
+ p=NTslsearchpath;
+ index=0;
+ while (index < MaxPathElements)
+ {
+ q=strchr(p,DirectoryListSeparator);
+ if (q == (char *) NULL)
+ {
+ (void) strlcpy(buffer,p,MaxTextExtent);
+ (void) strlcat(buffer,"\\",MaxTextExtent);
+ (void) strlcat(buffer,filename,MaxTextExtent);
+ handle=(void *) LoadLibrary(buffer);
+ break;
+ }
+ i=q-p;
+ (void) strncpy(buffer,p,i);
+ buffer[i]='\0';
+ (void) strlcat(buffer,"\\",MaxTextExtent);
+ (void) strlcat(buffer,filename,MaxTextExtent);
+ handle=(void *) LoadLibrary(buffer);
+ if (handle)
+ break;
+ p=q+1;
+ }
+ }
+
+ // Restore original error handling mode.
+ SetErrorMode(errorMode);
+
+ return(handle);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T d l s e t s e a r c h p a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTdlsetsearchpath sets the current locations that the subsystem
+% should look at to find dynamically loadable modules.
+%
+% The format of the NTdlsetsearchpath method is:
+%
+% int NTdlsetsearchpath(char *path)
+%
+% A description of each parameter follows:
+%
+% o path: Specifies a pointer to string representing the search path
+% for DLL's that can be dynamically loaded.
+%
+*/
+MagickExport int NTdlsetsearchpath(const char *path)
+{
+ if (NTslsearchpath)
+ {
+ MagickFreeMemory(NTslsearchpath);
+ NTslsearchpath=(char *) NULL;
+ }
+ if (path != (char *) NULL)
+ NTslsearchpath=AllocateString(path);
+ return (0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T d l s y m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTdlsym retrieve the procedure address of the procedure specified
+% by the passed character string.
+%
+% The format of the NTdlsym method is:
+%
+% void *NTdlsym(void *handle,const char *name)
+%
+% A description of each parameter follows:
+%
+% o handle: Specifies a handle to the previously loaded dynamic module.
+%
+% o name: Specifies the procedure entry point to be returned.
+%
+*/
+MagickExport void *NTdlsym(void *handle,const char *name)
+{
+ LPFNDLLFUNC1
+ lpfnDllFunc1;
+
+ lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress(handle,name);
+ if (!lpfnDllFunc1)
+ return((void *) NULL);
+ return((void *) lpfnDllFunc1);
+}
+#endif /* !defined(HasLTDL) */
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ N T m u n m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTmunmap emulates the POSIX munmap function.
+%
+% The format of the NTmunmap method is:
+%
+% int NTmunmap(void *map,size_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Method NTmunmap returns 0 on success; otherwise, it
+% returns -1 and sets errno to indicate the error.
+%
+% o map: The address of the binary large object.
+%
+% o length: The length of the binary large object.
+%
+%
+*/
+MagickExport int NTmunmap(void *map,size_t length)
+{
+ ARG_NOT_USED(length);
+
+ if (!UnmapViewOfFile(map))
+ return(-1);
+ return(0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T E l a p s e d T i m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTElapsedTime returns the elapsed time (in seconds) since the last
+% call to StartTimer().
+%
+% The format of the ElapsedTime method is:
+%
+% double NTElapsedTime(void)
+%
+%
+*/
+MagickExport double NTElapsedTime(void)
+{
+ union
+ {
+ FILETIME
+ filetime;
+
+ __int64
+ filetime64;
+ } elapsed_time;
+
+ SYSTEMTIME
+ system_time;
+
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
+ return((double) 1.0e-7*elapsed_time.filetime64);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ N T E r r o r H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTErrorHandler displays an error reason and then terminates
+% the program.
+%
+% The format of the NTErrorHandler method is:
+%
+% void NTErrorHandler(const ExceptionType error,const char *reason,
+% const char *description)
+%
+% A description of each parameter follows:
+%
+% o error: Specifies the numeric error category.
+%
+% o reason: Specifies the reason to display before terminating the
+% program.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+MagickExport void NTErrorHandler(const ExceptionType error,const char *reason,
+ const char *description)
+{
+ char
+ buffer[3*MaxTextExtent];
+
+ ARG_NOT_USED(error);
+
+ if (reason == (char *) NULL)
+ {
+ DestroyMagick();
+ Exit(0);
+ }
+ if ((description != (char *) NULL) && errno)
+ FormatString(buffer,"%.1024s: %.1024s (%.1024s) [%.1024s].\n",
+ GetClientName(),reason,description,strerror(errno));
+ else
+ if (description != (char *) NULL)
+ FormatString(buffer,"%.1024s: %.1024s (%.1024s).\n",
+ GetClientName(),reason,description);
+ else
+ if (errno)
+ FormatString(buffer,"%.1024s: %.1024s [%.1024s].\n",
+ GetClientName(),reason,strerror(errno));
+ else
+ FormatString(buffer,"%.1024s: %.1024s.\n",GetClientName(),
+ reason);
+ (void) MessageBox(NULL,buffer,"GraphicsMagick Exception",MB_OK | MB_TASKMODAL |
+ MB_SETFOREGROUND | MB_ICONEXCLAMATION);
+ DestroyMagick();
+ Exit(0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G e t E x e c u t i o n P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGetExecutionPath returns the execution path of a program.
+%
+% The format of the GetExecutionPath method is:
+%
+% unsigned int NTGetExecutionPath(char *path)
+%
+%
+*/
+MagickExport MagickPassFail NTGetExecutionPath(char *path)
+{
+ GetModuleFileName(0,path,MaxTextExtent);
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G e t L a s t E r r o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGetLastError returns the last error that occurred.
+%
+% The format of the NTGetLastError method is:
+%
+% char *NTGetLastError(void)
+%
+% A description of each parameter follows:
+%
+*/
+char *NTGetLastError(void)
+{
+ char
+ *reason;
+
+ int
+ status;
+
+ LPVOID
+ buffer;
+
+ status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
+ MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
+ if (!status)
+ reason=AllocateString("An unknown error occurred");
+ else
+ {
+ reason=AllocateString((const char *)buffer);
+ LocalFree(buffer);
+ }
+ return(reason);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G h o s t s c r i p t D L L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGhostscriptDLL obtains the path to the latest Ghostscript DLL.
+% The method returns False if a value is not obtained.
+%
+% The format of the NTGhostscriptDLL method is:
+%
+% int NTGhostscriptDLL(char *path, int path_length)
+%
+% A description of each parameter follows:
+%
+% o path: Pointer to buffer in which to return result.
+%
+% o path_length: Length of buffer
+%
+*/
+/*
+ Get a named registry value.
+ Key = hkeyroot\\key, named value = name.
+ */
+static int
+NTGetRegistryValue(HKEY hkeyroot, const char *key, const char *name,
+ char *ptr, int *plen)
+{
+ HKEY
+ hkey;
+
+ DWORD
+ cbData,
+ keytype;
+
+ BYTE
+ b,
+ *bptr = (BYTE *)ptr;
+
+ LONG
+ rc;
+
+ if (RegOpenKeyExA(hkeyroot, key, 0, KEY_READ, &hkey)
+ == ERROR_SUCCESS)
+ {
+ keytype = REG_SZ;
+ cbData = *plen;
+ if (bptr == (BYTE *) NULL)
+ bptr = &b; /* Registry API won't return ERROR_MORE_DATA */
+ /* if ptr is NULL */
+ rc = RegQueryValueExA(hkey, (char *)name, 0, &keytype, bptr, &cbData);
+ RegCloseKey(hkey);
+ if (rc == ERROR_SUCCESS)
+ {
+ *plen = cbData;
+ return 0; /* found environment variable and copied it */
+ }
+ else
+ if (rc == ERROR_MORE_DATA)
+ {
+ /* buffer wasn't large enough */
+ *plen = cbData;
+ return -1;
+ }
+ }
+ return 1; /* not found */
+}
+
+/*
+ Find the latest version of Ghostscript installed on the system (if
+ any).
+*/
+static MagickPassFail
+NTGhostscriptFind(const char **gs_productfamily,
+ int *gs_major_version,
+ int *gs_minor_version)
+{
+ /*
+ These are the Ghostscript product versions we will search for.
+ */
+ const char *products[4] =
+ {
+ "GPL Ghostscript",
+ "GNU Ghostscript",
+ "AFPL Ghostscript",
+ "Aladdin Ghostscript"
+ };
+
+ unsigned int
+ product_index;
+
+ MagickPassFail
+ status;
+
+ status=MagickFail;
+ *gs_productfamily=NULL;
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Searching for Ghostscript...");
+
+ /* Minimum version of Ghostscript is 5.50 */
+ *gs_major_version=5;
+ *gs_minor_version=49;
+ for (product_index=0; product_index < sizeof(products)/sizeof(products[0]);
+ ++product_index)
+ {
+ HKEY
+ hkey,
+ hkeyroot;
+
+ LONG
+ winstatus;
+
+ REGSAM
+ open_key_mode;
+
+ char
+ key[MaxTextExtent],
+ last_error_msg[MaxTextExtent];
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ " Searching for %s...",
+ products[product_index]);
+ FormatString(key,"SOFTWARE\\%s",products[product_index]);
+ hkeyroot = HKEY_LOCAL_MACHINE;
+ /*
+ long WINAPI RegOpenKeyEx(const HKEY hKey, const LPCTSTR
+ lpSubKey, const DWORD ulOptions, const REGSAM samDesired,
+ PHKEY phkResult)
+ */
+ open_key_mode=KEY_READ;
+ if ((winstatus=RegOpenKeyExA(hkeyroot, key, 0, open_key_mode, &hkey))
+ == ERROR_SUCCESS)
+ {
+ DWORD
+ cbData;
+
+ int
+ n;
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ " RegOpenKeyExA() opened "
+ "\"HKEY_LOCAL_MACHINE\\%s\"",
+ key);
+ /* Now enumerate the keys */
+ cbData = sizeof(key) / sizeof(char);
+ n=0;
+ /*
+ LONG WINAPI RegEnumKeyEx(HKEY hKey, DWORD dwIndex, LPTSTR
+ lpName, LPDWORD lpcName, LPDWORD lpReserved, LPTSTR
+ lpClass, LPDWORD lpcClass, PFILETIME lpftLastWriteTime)
+
+ Enumerates the subkeys of the specified open registry key.
+
+ RegEnumKeyA is is provided only for compatibility with
+ 16-bit versions of Windows.
+ */
+ while ((winstatus=RegEnumKeyA(hkey, n, key, cbData)) == ERROR_SUCCESS)
+ {
+ int
+ major_version,
+ minor_version;
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ " RegEnumKeyA enumerated \"%s\"",key);
+ n++;
+ major_version=0;
+ minor_version=0;
+ if (sscanf(key,"%d.%d",&major_version,&minor_version) != 2)
+ continue;
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ " Found Ghostscript (%s) version %d.%02d",
+ products[product_index],
+ major_version,
+ minor_version);
+
+ if ((major_version > *gs_major_version) ||
+ ((major_version == *gs_major_version) &&
+ (minor_version > *gs_minor_version)))
+ {
+ *gs_productfamily=products[product_index];
+ *gs_major_version=major_version;
+ *gs_minor_version=minor_version;
+ status=MagickPass;
+ }
+ }
+ if (winstatus != ERROR_NO_MORE_ITEMS)
+ {
+ (void) NTstrerror_r(winstatus,last_error_msg,sizeof(last_error_msg));
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ " RegEnumKeyA (%s)",
+ last_error_msg);
+ }
+ /*
+ LONG WINAPI RegCloseKey(HKEY hKey)
+
+ Close the registry key.
+ */
+ winstatus=RegCloseKey(hkey);
+ }
+ else
+ {
+ /*
+ If the function fails, the return value is a nonzero error
+ code defined in Winerror.h. You can use the FormatMessage
+ function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a
+ generic description of the error.
+ */
+ (void) NTstrerror_r(winstatus,last_error_msg,sizeof(last_error_msg));
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ " RegOpenKeyExA() failed to open "
+ "\"HKEY_LOCAL_MACHINE\\%s\" (%s)",
+ key,last_error_msg);
+ }
+ }
+ if (status != MagickFail)
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Selected Ghostscript (%s) version %d.%02d",
+ *gs_productfamily,*gs_major_version,
+ *gs_minor_version);
+ }
+ else
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Failed to find Ghostscript!");
+ *gs_major_version=0;
+ *gs_minor_version=0;
+ }
+
+ return status;
+}
+
+
+/*
+ Obtain a string from the installed Ghostscript (if any).
+*/
+static MagickPassFail
+NTGhostscriptGetString(const char *name, char *ptr, const size_t len)
+{
+ static const char
+ *gs_productfamily=NULL;
+
+ static int
+ gs_major_version=0,
+ gs_minor_version=0;
+
+ struct
+ {
+ const HKEY hkey;
+ const char *name;
+ }
+ hkeys[2] =
+ {
+ { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
+ { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
+ };
+
+ unsigned int
+ i;
+
+ int
+ length;
+
+ char
+ key[MaxTextExtent];
+
+ ptr[0]='\0';
+
+ if (NULL == gs_productfamily)
+ (void) NTGhostscriptFind(&gs_productfamily,&gs_major_version,
+ &gs_minor_version);
+
+ if (NULL == gs_productfamily)
+ return MagickFail;
+
+ FormatString(key,"SOFTWARE\\%s\\%d.%02d",gs_productfamily,
+ gs_major_version, gs_minor_version);
+
+ for (i=0; i < sizeof(hkeys)/sizeof(hkeys[0]); ++i)
+ {
+ length = (int) len;
+ if (NTGetRegistryValue(hkeys[i].hkey, key, name, ptr, &length) == 0)
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Registry: \"%s\\%s\\%s\"=\"%s\"",
+ hkeys[i].name,key,name,ptr);
+ return MagickPass;
+ }
+ else
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Failed lookup: \"%s\\%s\\%s\"",
+ hkeys[i].name,key,name);
+ }
+ }
+
+ return MagickFail;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G h o s t s c r i p t D L L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGhostscriptDLL obtains the path to the latest Ghostscript DLL.
+% The method returns False if a value is not obtained.
+%
+% The format of the NTGhostscriptDLL method is:
+%
+% int NTGhostscriptDLL( char *path, int path_length)
+%
+% A description of each parameter follows:
+%
+% o path: Pointer to path buffer to update
+%
+% o path_length: Allocation size of path buffer.
+%%
+*/
+MagickExport int NTGhostscriptDLL(char *path, int path_length)
+{
+ static char
+ cache[MaxTextExtent],
+ *result=NULL;
+
+ path[0]='\0';
+
+ if (NULL == result)
+ {
+ const char
+ *directory;
+
+ directory=getenv("MAGICK_GHOSTSCRIPT_PATH");
+ if (directory != (const char *) NULL)
+ {
+ FormatString(cache, "%.1024s%sgsdll%u.dll", directory,
+ DirectorySeparator, (unsigned int) sizeof(directory)*8);
+ if (IsAccessibleAndNotEmpty(cache))
+ result=cache;
+ else
+ (void) LogMagickEvent(ConfigureEvent, GetMagickModule(),
+ "Unable to find ghostscript library: \"%s\"", cache);
+ }
+ else if (NTGhostscriptGetString("GS_DLL", cache, sizeof(cache)))
+ {
+ result=cache;
+ }
+ }
+
+ if (result)
+ {
+ (void) strlcpy(path, result, path_length);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G h o s t s c r i p t D L L V e c t o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGhostscriptDLLVectors returns a GhostscriptVectors structure
+% containing function vectors to invoke Ghostscript DLL functions. A null
+% pointer is returned if there is an error with loading the DLL or
+% retrieving the function vectors.
+%
+% The format of the NTGhostscriptDLLVectors method is:
+%
+% const GhostscriptVectors *NTGhostscriptDLLVectors( void )
+%
+%%
+*/
+MagickExport const GhostscriptVectors *NTGhostscriptDLLVectors( void )
+{
+ if (NTGhostscriptLoadDLL())
+ return &gs_vectors;
+
+ return (GhostscriptVectors*) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G h o s t s c r i p t E X E %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGhostscriptEXE obtains the path to the latest Ghostscript
+% executable. The method returns TRUE if path is updated, otherwise
+% FALSE. When the full path value is not obtained, then the value
+% "gswin32c.exe" or "gswin64c.exe" is used.
+%
+% The format of the NTGhostscriptEXE method is:
+%
+% int NTGhostscriptEXE(char *path, int path_length)
+%
+% A description of each parameter follows:
+%
+% o path: Pointer to buffer in which to return result.
+%
+% o path_length: Length of buffer
+%
+*/
+MagickExport int NTGhostscriptEXE(char *path, int path_length)
+{
+ static char
+ cache[MaxTextExtent],
+ *result=NULL;
+
+ if (NULL == result)
+ {
+ char
+ gsexe[MaxTextExtent];
+
+ char
+ *p;
+
+ /* Ensure a suitable default. */
+ (void) FormatString(gsexe,"gswin%uc.exe",(unsigned int) sizeof(p)*8);
+ (void) strlcpy(cache,gsexe,sizeof(cache));
+
+ if (NTGhostscriptDLL(cache,sizeof(cache)))
+ {
+ p = strrchr(cache, '\\');
+ if (p) {
+ p++;
+ *p = 0;
+ (void) strlcat(cache,gsexe,sizeof(cache));
+ }
+ }
+ result=cache;
+ }
+
+ if (result)
+ {
+ (void) strlcpy(path,result, path_length);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G h o s t s c r i p t F o n t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGhostscriptFonts obtains the path to the Ghostscript fonts.
+% The method returns False if a value is not obtained.
+%
+% The format of the NTGhostscriptFonts method is:
+%
+% int NTGhostscriptFonts(char *path, int path_length)
+%
+% A description of each parameter follows:
+%
+% o path: Pointer to buffer in which to return result.
+%
+% o path_length: Length of buffer
+%
+*/
+MagickExport int NTGhostscriptFonts(char *path, int path_length)
+{
+ char
+ gs_lib_path[MaxTextExtent];
+
+ path[0]='\0';
+
+ if (!NTGhostscriptGetString("GS_LIB", gs_lib_path,sizeof(gs_lib_path)))
+ return FALSE;
+
+ /*
+ The format of the GS_LIB string is a path similar to
+
+ "C:\Program Files\gs\gs9.10\bin;C:\Program Files\gs\gs9.10\lib;C:\Program Files\gs\gs9.10\fonts"
+
+ Ghostscript 7.0X does not include the Resource entry.
+
+ Search path used by GPL Ghostscript 9.10 (2013-08-30):
+ C:\Program Files\gs\gs9.10\bin ; C:\Program Files\gs\gs9.10\lib ;
+ C:\Program Files\gs\gs9.10\fonts ; %rom%Resource/Init/ ; %rom%lib/ ;
+ c:/gs/gs9.10/Resource/Init ; c:/gs/gs9.10/lib ;
+ c:/gs/gs9.10/Resource/Font ; c:/gs/fonts
+
+ */
+ {
+ const char
+ *end = NULL,
+ *start = gs_lib_path;
+
+ end=start+strlen(start);
+ while ( start < end )
+ {
+ char
+ font_dir[MaxTextExtent],
+ font_dir_file[MaxTextExtent];
+
+ const char
+ *separator;
+
+ int
+ length;
+
+ separator = strchr(start,DirectoryListSeparator);
+ if (separator)
+ length=separator-start;
+ else
+ length=end-start;
+ (void) strlcpy(font_dir,start,Min(length+1,MaxTextExtent));
+ (void) strlcpy(font_dir_file,font_dir,MaxTextExtent);
+ (void) strlcat(font_dir_file,DirectorySeparator,MaxTextExtent);
+ (void) strlcat(font_dir_file,"fonts.dir",MaxTextExtent);
+ if (IsAccessible(font_dir_file))
+ {
+ (void) strlcpy(path,font_dir,path_length);
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Ghostscript fonts in directory \"%s\"",
+ path);
+ return TRUE;
+ }
+ start += length+1;
+ }
+ }
+ {
+ /*
+ Check "c:/gs/fonts" since Ghostscript also looks there. This
+ may be a more convenient place to put fonts since it would be
+ used by every Ghostscript installation on the system.
+
+ This part of the path to check is hard-coded in the Ghostscript
+ binary via AROOTDIR=c:/gs in base/msvclib.mak and it is highly
+ unlikely that Windows users will use a Ghostscript built with a
+ different GS_LIB_DEFAULT (which includes AROOTDIR) definition.
+ */
+
+ const char *
+ gs_font_dir = "c:\\gs\\fonts";
+
+ char
+ font_dir_file[MaxTextExtent];
+
+ (void) strlcpy(font_dir_file,gs_font_dir,MaxTextExtent);
+ (void) strlcat(font_dir_file,DirectorySeparator,MaxTextExtent);
+ (void) strlcat(font_dir_file,"fonts.dir",MaxTextExtent);
+ if (IsAccessible(font_dir_file))
+ {
+ (void) strlcpy(path,gs_font_dir,path_length);
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Ghostscript fonts in directory \"%s\"",
+ path);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G h o s t s c r i p t L o a d D L L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGhostscriptLoadDLL attempts to load the Ghostscript DLL
+% and returns True if it succeeds.
+%
+% The format of the NTGhostscriptLoadDLL method is:
+%
+% int NTGhostscriptLoadDLL(void)
+%
+%%
+*/
+MagickExport int NTGhostscriptLoadDLL(void)
+{
+ char
+ dll_path[MaxTextExtent];
+
+ if (gs_dll_handle != (void *) NULL)
+ return True;
+
+ if (!NTGhostscriptDLL(dll_path,sizeof(dll_path)))
+ return False;
+
+ gs_dll_handle = lt_dlopen(dll_path);
+ if (gs_dll_handle == (void *) NULL)
+ return False;
+
+ memset((void*)&gs_vectors, 0, sizeof(GhostscriptVectors));
+
+ gs_vectors.exit=(int (MagickDLLCall *)(gs_main_instance*))
+ lt_dlsym(gs_dll_handle,"gsapi_exit");
+ gs_vectors.init_with_args=(int (MagickDLLCall *)(gs_main_instance *, int, char **))
+ (lt_dlsym(gs_dll_handle,"gsapi_init_with_args"));
+ gs_vectors.new_instance=(int (MagickDLLCall *)(gs_main_instance **, void *))
+ (lt_dlsym(gs_dll_handle,"gsapi_new_instance"));
+ gs_vectors.run_string=(int (MagickDLLCall *)(gs_main_instance *, const char *, int, int *))
+ (lt_dlsym(gs_dll_handle,"gsapi_run_string"));
+ gs_vectors.delete_instance=(void (MagickDLLCall *)(gs_main_instance *))
+ (lt_dlsym(gs_dll_handle,"gsapi_delete_instance"));
+
+ if ((gs_vectors.exit==NULL) ||
+ (gs_vectors.init_with_args==NULL) ||
+ (gs_vectors.new_instance==NULL) ||
+ (gs_vectors.run_string==NULL) ||
+ (gs_vectors.delete_instance==NULL))
+ return False;
+
+ return True;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T G h o s t s c r i p t U n L o a d D L L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGhostscriptUnLoadDLL unloads the Ghostscript DLL if it is loaded.
+%
+% The format of the NTGhostscriptUnLoadDLL method is:
+%
+% int NTGhostscriptUnLoadDLL(void)
+%
+%%
+*/
+MagickExport int NTGhostscriptUnLoadDLL(void)
+{
+ if (gs_dll_handle != (void *) NULL)
+ {
+ lt_dlclose(gs_dll_handle);
+ gs_dll_handle=(void *) NULL;
+ memset((void*)&gs_vectors, 0, sizeof(GhostscriptVectors));
+ return True;
+ }
+
+ return False;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T K e r n e l A P I S u p p o r t e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTKernelAPISupported tests to see if an API symbol is defined in
+% kernel32.dll. If it is defined, then presumably the interface can safely
+% be used without crashing.
+%
+% The format of the NTKernelAPISupported method is:
+%
+% MagickBool NTKernelAPISupported(const char *name)
+%
+% A description of each parameter follows:
+%
+% o return: MagickTrue if the symbol is defined, otherwise MagickFalse.
+%
+% o name: Symbol name.
+%
+*/
+MagickExport MagickBool NTKernelAPISupported(const char *name)
+{
+ return (GetProcAddress(GetModuleHandle("kernel32.dll"),name) == NULL ?
+ MagickFalse : MagickTrue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T R e g i s t r y K e y L o o k u p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTRegistryKeyLookup returns package installation path settings
+% stored in the Windows Registry. Path settings are specific to the
+% installed package version so that multiple package installations may
+% coexist.
+%
+% Values are stored in the registry under a base path path similar to
+% "HKEY_LOCAL_MACHINE/SOFTWARE\GraphicsMagick\1.0\Q:8". The provided subkey
+% is appended to this base path to form the full key.
+%
+% The format of the NTRegistryKeyLookup method is:
+%
+% char *NTRegistryKeyLookup(const char *subkey)
+%
+% A description of each parameter follows:
+%
+% o return: Returns an allocated string containing the value of the key.
+% This allocation should be freed by the user once it is no longer
+% needed.
+%
+% o key: Specifies a string that identifies the registry object.
+% Currently supported sub-keys include: "BinPath", "ConfigurePath",
+% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
+%
+*/
+MagickExport unsigned char *NTRegistryKeyLookup(const char *subkey)
+{
+ static HKEY
+ reg_key = (HKEY) INVALID_HANDLE_VALUE;
+
+ /*
+ Look-up base-key for first access only
+ */
+ if (reg_key == (HKEY) INVALID_HANDLE_VALUE)
+ {
+ char
+ package_key[MaxTextExtent];
+
+ LONG
+ res;
+
+ FormatString(package_key,"SOFTWARE\\%s\\%s\\Q:%d", MagickPackageName,
+ MagickLibVersionText,QuantumDepth);
+
+ res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, package_key, 0, KEY_READ,
+ &reg_key);
+
+ if (res != ERROR_SUCCESS)
+ {
+ reg_key = (HKEY) INVALID_HANDLE_VALUE;
+ return 0;
+ }
+ }
+
+ /*
+ Look-up sub-key
+ */
+ {
+ unsigned char
+ *dest;
+
+ DWORD
+ size,
+ type;
+
+ LONG
+ res;
+
+ size = 32;
+ dest = MagickAllocateMemory(unsigned char *,size);
+
+ res = RegQueryValueExA (reg_key, subkey, 0, &type, dest, &size);
+ if (res == ERROR_MORE_DATA && type == REG_SZ)
+ {
+ MagickReallocMemory(unsigned char *,dest,size);
+ res = RegQueryValueExA (reg_key, subkey, 0, &type, dest, &size);
+ }
+
+ if (type != REG_SZ || res != ERROR_SUCCESS)
+ {
+ MagickFreeMemory(dest);
+ }
+
+ return dest;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T R e s o u r c e T o B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTResourceToBlob returns a blob containing the contents of the
+% resource in the current executable specified by the id parameter. This
+% is currently used to retrieve MGK files tha have been embedded into
+% the various command line utilities.
+%
+% The format of the telldir method is:
+%
+% unsigned char *NTResourceToBlob(const char *id)
+%
+% A description of each parameter follows:
+%
+% o id: Specifies a string that identifies the resource.
+%
+%
+*/
+MagickExport unsigned char *NTResourceToBlob(const char *id)
+{
+ char
+ directory[MaxTextExtent];
+
+ DWORD
+ length;
+
+ HGLOBAL
+ global;
+
+ HMODULE
+ handle;
+
+ HRSRC
+ resource;
+
+ unsigned char
+ *blob,
+ *value;
+
+ assert(id != (const char *) NULL);
+#ifdef MagickLibName
+ handle=GetModuleHandle(MagickLibName);
+#else
+ FormatString(directory,"%.1024s%.1024s%.1024s",GetClientPath(),
+ DirectorySeparator,GetClientFilename());
+ if (IsAccessible(directory))
+ handle=GetModuleHandle(directory);
+ else
+ handle=GetModuleHandle(0);
+#endif
+ if (!handle)
+ return((unsigned char *) NULL);
+ /*
+ Locate a resource matching the specified type and name in the
+ specified module.
+ */
+ resource=FindResource(handle,id,"IMAGEMAGICK");
+ if (!resource)
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Tried: windows resource \"%.1024s\"",id);
+ return((unsigned char *) NULL);
+ }
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Found: windows resource \"%.1024s\"",id);
+ /*
+ Load resource into global memory (in WIN32, resources are already
+ in memory).
+ */
+ global=LoadResource(handle,resource);
+ if (!global)
+ return((unsigned char *) NULL);
+ /*
+ Obtain the size (in bytes) of the specified resource.
+ */
+ length=SizeofResource(handle,resource);
+ /*
+ Lock the resource in memory (really just dereferences an object
+ permanently in memory).
+ */
+ value=(unsigned char *) LockResource(global);
+ if (!value)
+ {
+ return((unsigned char *) NULL);
+ }
+ blob=MagickAllocateMemory(unsigned char *,length+1);
+ if (blob != (unsigned char *) NULL)
+ {
+ (void) memcpy(blob,value,length);
+ blob[length]='\0';
+ }
+ return(blob);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ N T s t r e r r o r _ r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTstrerror_r formats a returned Windows error code into a
+% message string in a thread-safe manner. MagickFail is returned if a
+% message could not be found corresponding to the error code, otherwise
+% MagickPass is returned.
+%
+% The format of the NTstrerror_r method is:
+%
+% MagickPassFail NTstrerror_r(LONG errnum, char *strerrbuf, size_t buflen)
+%
+% A description of each parameter follows:
+%
+% o errnum: Windows error number
+%
+% o strerrbuf: A buffer in which to write the message.
+%
+% o buflen: The allocation length of the buffer.
+%
+*/
+static MagickPassFail
+NTstrerror_r(LONG errnum, char *strerrbuf, size_t buflen)
+{
+ MagickPassFail
+ status;
+
+ LPVOID
+ buffer;
+
+ status=MagickFail;
+ if (buflen > 0)
+ strerrbuf[0]='\0';
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,NULL,errnum,
+ MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
+ (LPTSTR) &buffer,0,NULL))
+ {
+ if (strlcpy(strerrbuf,buffer,buflen) < buflen)
+ {
+ size_t
+ index;
+
+ for (index=0; strerrbuf[index] != 0; index++)
+ if (strerrbuf[index] == '\015')
+ strerrbuf[index]='\0';
+ status=MagickPass;
+ }
+ LocalFree(buffer);
+ }
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T S y s t e m C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTSystemComman executes the specified command and waits until it
+% terminates. The returned value is the exit status of the command.
+%
+% The format of the NTSystemComman method is:
+%
+% int NTSystemComman(const char *command)
+%
+% A description of each parameter follows:
+%
+% o command: This string is the command to execute.
+%
+%
+*/
+MagickExport int NTSystemComman(const char *command)
+{
+ char
+ local_command[MaxTextExtent];
+
+ DWORD
+ child_status;
+
+ int
+ status;
+
+ PROCESS_INFORMATION
+ process_info;
+
+ STARTUPINFO
+ startup_info;
+
+ unsigned int
+ background_process;
+
+ if (command == (char *) NULL)
+ return(-1);
+ GetStartupInfo(&startup_info);
+ startup_info.dwFlags=STARTF_USESHOWWINDOW;
+ startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
+ (void) strlcpy(local_command,command,MaxTextExtent);
+ background_process=command[strlen(command)-1] == '&';
+ if (background_process)
+ local_command[strlen(command)-1]='\0';
+ if (command[strlen(command)-1] == '|')
+ local_command[strlen(command)-1]='\0';
+ else
+ startup_info.wShowWindow=SW_SHOWDEFAULT;
+ status=CreateProcess((LPCTSTR) NULL,local_command,
+ (LPSECURITY_ATTRIBUTES) NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE,
+ (DWORD) NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
+ &process_info);
+ if (status == 0)
+ return(-1);
+ if (background_process)
+ return(status == 0);
+
+#if 1
+ // This code has been used for years, but supposedly may
+ // cause problems in GUIs.
+ status=WaitForSingleObject(process_info.hProcess,INFINITE);
+ if (status != WAIT_OBJECT_0)
+ return (status);
+#else
+ // Following code doesn't work correctly yet
+ while(1)
+ {
+ // Wait for state change or message received
+ DWORD result=MsgWaitForMultipleObjects(1, &process_info.hProcess, FALSE,
+ INFINITE, QS_ALLEVENTS);
+ // Loop if return was due to message received (which we don't care about).
+ if (result == (WAIT_OBJECT_0+1))
+ continue;
+ // If return was due to handle state change, then object is available.
+ if ((result - WAIT_OBJECT_0) == 0)
+ break;
+ }
+#endif
+
+ status=GetExitCodeProcess(process_info.hProcess,&child_status);
+ if (status == 0)
+ return(-1);
+ CloseHandle(process_info.hProcess);
+ CloseHandle(process_info.hThread);
+ return((int) child_status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T U s e r T i m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTUserTime returns the total time the process has been scheduled (i
+% seconds) since the last call to StartTimer().
+%
+% The format of the UserTime method is:
+%
+% double NTUserTime(void)
+%
+%
+*/
+MagickExport double NTUserTime(void)
+{
+ DWORD
+ status;
+
+ FILETIME
+ create_time,
+ exit_time;
+
+ OSVERSIONINFO
+ OsVersionInfo;
+
+ union
+ {
+ FILETIME
+ filetime;
+
+ __int64
+ filetime64;
+ } kernel_time;
+
+ union
+ {
+ FILETIME
+ filetime;
+
+ __int64
+ filetime64;
+ } user_time;
+
+ OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
+ GetVersionEx(&OsVersionInfo);
+ if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ return(NTElapsedTime());
+ status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
+ &kernel_time.filetime,&user_time.filetime);
+ if (status != TRUE)
+ return(0.0);
+ return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T W a r n i n g H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTWarningHandler displays a warning reason.
+%
+% The format of the NTWarningHandler method is:
+%
+% void NTWarningHandler(const ExceptionType warning,const char *reason,
+% const char *description)
+%
+% A description of each parameter follows:
+%
+% o warning: Specifies the numeric warning category.
+%
+% o reason: Specifies the reason to display before terminating the
+% program.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+MagickExport void NTWarningHandler(const ExceptionType warning,
+ const char *reason,const char *description)
+{
+ char
+ buffer[2*MaxTextExtent];
+
+ ARG_NOT_USED(warning);
+
+ if (reason == (char *) NULL)
+ return;
+ if (description == (char *) NULL)
+ FormatString(buffer,"%.1024s: %.1024s.\n",
+ GetClientName(),reason);
+ else
+ FormatString(buffer,"%.1024s: %.1024s (%.1024s).\n",
+ GetClientName(),reason,description);
+ (void) MessageBox(NULL,buffer,"GraphicsMagick Warning",MB_OK | MB_TASKMODAL |
+ MB_SETFOREGROUND | MB_ICONINFORMATION);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T f t r u n c a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTftruncate truncates a file to the specified size. If the file is
+% longer than the specified size, it is shortened to the specified size. If
+% the file is shorter than the specified size, it is extended to the
+% specified size by filling with zeros.
+% This is a POSIX compatability function.
+%
+% The format of the NTftruncate method is:
+%
+% int NTftruncate(int filedes, off_t length)
+%
+% A description of each parameter follows:
+%
+% o status: Zero is returned on successful completion. Otherwise -1
+% is returned and errno is set to indicate the error.
+%
+% o filedes: File descriptor from the _open() call.
+%
+% o length: Desired file length.
+%
+*/
+MagickExport int NTftruncate(int filedes, off_t length)
+{
+ int
+ status;
+
+ magick_off_t
+ current_pos;
+
+ status=0;
+ current_pos=MagickTell(filedes);
+
+ /*
+ Truncate file to size, filling any extension with nulls.
+ Notice that this interface is limited to 2GB due to its
+ use of a 'long' offset. Ftruncate also has this shortcoming
+ if off_t is a 'long'.
+
+ A way to support more than 2GB is to use SetFilePointerEx()
+ to set the file position followed by SetEndOfFile() to set
+ the file EOF to the current file position. This approach does
+ not ensure that bytes in the extended portion are null.
+
+ The CreateFileMapping() function may also be used to extend a
+ file's length. The filler byte values are not defined in the
+ documentation.
+ */
+ status=chsize(filedes,length);
+
+ /*
+ It is not documented if _chsize preserves the seek
+ position, so restore the seek position like ftruncate
+ does
+ */
+ if (!status)
+ status=MagickSeek(filedes,current_pos,SEEK_SET);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ N T m m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTmmap emulates POSIX mmap. Supports PROT_READ, PROT_WRITE
+% protection options, and MAP_SHARED, MAP_PRIVATE, MAP_ANON flags.
+% Passing a file descriptor of -1 along with the MAP_ANON flag option returns
+% a memory allocation from the system page file with the specified allocated
+% length.
+%
+% The format of the NTmmap method is:
+%
+% MagickExport void *NTmmap(char *address, size_t length, int protection,
+% int flags, int file, magick_off_t offset)
+%
+%
+*/
+MagickExport void *NTmmap(char *address,size_t length,int protection,int flags,
+ int file,magick_off_t offset)
+{
+ void
+ *map;
+
+ HANDLE
+ file_handle,
+ shmem_handle;
+
+ DWORD
+ length_low,
+ length_high,
+ offset_low,
+ offset_high;
+
+ DWORD
+ access_mode=0,
+ protection_mode=0;
+
+ ARG_NOT_USED(address);
+
+ map=(void *) NULL;
+ shmem_handle=INVALID_HANDLE_VALUE;
+ file_handle=INVALID_HANDLE_VALUE;
+
+ offset_low=(DWORD) (offset & 0xFFFFFFFFUL);
+ offset_high=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
+
+ length_low=(DWORD) (length & 0xFFFFFFFFUL);
+ length_high=(DWORD) ((((magick_off_t) length) >> 32) & 0xFFFFFFFFUL);
+
+ if (protection & PROT_WRITE)
+ {
+ access_mode=FILE_MAP_WRITE;
+ if (flags & MAP_PRIVATE)
+ {
+ // Copy on write (updates are private)
+ access_mode=FILE_MAP_COPY;
+ protection_mode=PAGE_WRITECOPY;
+ }
+ else
+ {
+ // Updates are shared
+ protection_mode=PAGE_READWRITE;
+ }
+ }
+ else if (protection & PROT_READ)
+ {
+ access_mode=FILE_MAP_READ;
+ protection_mode=PAGE_READONLY;
+ }
+
+ if ((file == -1) && (flags & MAP_ANON))
+ // Similar to using mmap on /dev/zero to allocate memory from paging area.
+ file_handle=INVALID_HANDLE_VALUE;
+ else
+ file_handle=(HANDLE) _get_osfhandle(file);
+
+ shmem_handle=CreateFileMapping(file_handle,0,protection_mode,length_high,
+ length_low,0);
+ if (shmem_handle)
+ {
+ map=(void *) MapViewOfFile(shmem_handle,access_mode,offset_high,
+ offset_low,length);
+ CloseHandle(shmem_handle);
+ }
+
+ if (map == (void *) NULL)
+ return((void *) MAP_FAILED);
+ return((void *) ((char *) map));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ N T m s y n c %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTmsync emulates the Unix msync function except that the flags
+% argument is ignored. Windows page sync behaves mostly like MS_SYNC
+% except that if the file is accessed over a network, the updates are not
+% fully synchronous unless a special flag is provided when the file is
+% opened. It is not clear if flushing a range invalidates copy pages
+% like Unix msync does.
+%
+% The format of the NTmsync method is:
+%
+% int NTmsync(void *addr, size_t len, int flags)
+%
+% A description of each parameter follows:
+%
+% o status: Method NTmsync returns 0 on success; otherwise, it
+% returns -1 and sets errno to indicate the error.
+%
+% o addr: The address of the binary large object.
+%
+% o len: The length of the binary large object.
+%
+% o flags: Option flags (ignored for Windows)
+%
+%
+*/
+MagickExport int NTmsync(void *addr, size_t len, int flags)
+{
+ ARG_NOT_USED(flags);
+ if (!FlushViewOfFile(addr,len))
+ return(-1);
+ return(0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T o p e n d i r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTopendir opens the directory named by filename and associates
+% a directory stream with it.
+%
+% The format of the opendir method is:
+%
+% DIR *NTopendir(const char *path)
+%
+% A description of each parameter follows:
+%
+% o entry: Specifies a pointer to a DIR structure.
+%
+%
+*/
+MagickExport DIR *NTopendir(const char *path)
+{
+ char
+ file_specification[MaxTextExtent];
+
+ DIR
+ *entry;
+
+ assert(path != (char *) NULL);
+ if (strlcpy(file_specification,path,MaxTextExtent) >= MaxTextExtent)
+ return (DIR *) NULL;;
+ if (strlcat(file_specification,DirectorySeparator,MaxTextExtent) >= MaxTextExtent)
+ return (DIR *) NULL;;
+ entry=MagickAllocateMemory(DIR *,sizeof(DIR));
+ if (entry != (DIR *) NULL)
+ {
+ entry->firsttime=TRUE;
+ entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
+ }
+ if (entry->hSearch == INVALID_HANDLE_VALUE)
+ {
+ if (strlcat(file_specification,"\\*.*",MaxTextExtent) >= MaxTextExtent)
+ {
+ MagickFreeMemory(entry);
+ return (DIR *) NULL;
+ }
+ entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
+ if (entry->hSearch == INVALID_HANDLE_VALUE)
+ {
+ MagickFreeMemory(entry);
+ return (DIR *) NULL;
+ }
+ }
+ return(entry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T r e a d d i r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTreaddir returns a pointer to a structure representing the
+% directory entry at the current position in the directory stream to
+% which entry refers.
+%
+% The format of the readdir
+%
+% NTreaddir(entry)
+%
+% A description of each parameter follows:
+%
+% o entry: Specifies a pointer to a DIR structure.
+%
+%
+*/
+MagickExport struct dirent *NTreaddir(DIR *entry)
+{
+ int
+ status;
+
+ if (entry == (DIR *) NULL)
+ return ((struct dirent *) NULL);
+ if (!entry->firsttime)
+ {
+ status=FindNextFile(entry->hSearch,&entry->Win32FindData);
+ if (status == 0)
+ return ((struct dirent *) NULL);
+ }
+ if (strlcpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
+ sizeof(entry->file_info.d_name)) >=
+ sizeof(entry->file_info.d_name))
+ return ((struct dirent *) NULL);
+ entry->firsttime=FALSE;
+ entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
+ return (&entry->file_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T s e e k d i r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTseekdir sets the position of the next NTreaddir() operation
+% on the directory stream.
+%
+% The format of the NTseekdir method is:
+%
+% void NTseekdir(DIR *entry,long position)
+%
+% A description of each parameter follows:
+%
+% o entry: Specifies a pointer to a DIR structure.
+%
+% o position: specifies the position associated with the directory
+% stream.
+%
+%
+%
+*/
+MagickExport void NTseekdir(DIR *entry,long position)
+{
+ ARG_NOT_USED(position);
+ assert(entry != (DIR *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N T t e l l d i r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTtelldir returns the current location associated with the
+% named directory stream.
+%
+% The format of the NTtelldir method is:
+%
+% long NTtelldir(DIR *entry)
+%
+% A description of each parameter follows:
+%
+% o entry: Specifies a pointer to a DIR structure.
+%
+%
+*/
+MagickExport long NTtelldir(DIR *entry)
+{
+ assert(entry != (DIR *) NULL);
+ return(0);
+}
+#endif
diff --git a/magick/nt_base.h b/magick/nt_base.h
new file mode 100644
index 0000000..077db06
--- /dev/null
+++ b/magick/nt_base.h
@@ -0,0 +1,468 @@
+/*
+ Copyright (C) 2003 - 2016 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Windows NT Utility Methods for GraphicsMagick.
+*/
+#ifndef _MAGICK_NTBASE_H
+#define _MAGICK_NTBASE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "magick/delegate.h"
+
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+#include <windows.h>
+#include <winuser.h>
+#include <wingdi.h>
+#include <io.h>
+#include <process.h>
+#include <errno.h>
+#include <malloc.h>
+#if defined(_DEBUG)
+#include <crtdbg.h>
+#endif
+
+/*
+ Define declarations.
+*/
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define RW_OK 6
+#define HAVE_VSNPRINTF 1
+#define HAVE_RAISE 1
+#define HAVE_SPAWNVP 1
+#define HAVE_PROCESS_H 1
+
+#if defined(_VISUALC_)
+# define HAVE_CRYPTGENRANDOM 1
+# define HAVE_WINCRYPT_H 1
+#endif
+
+/*
+ POSIX definitions for standard file numbers for use with _read() or _write()
+*/
+#if !defined(STDIN_FILENO)
+# define STDIN_FILENO 0
+#endif
+#if !defined(STDOUT_FILENO)
+# define STDOUT_FILENO 1
+#endif
+#if !defined(STDERR_FILENO)
+# define STDERR_FILENO 2
+#endif
+
+/*
+ Size type passed to read/write
+*/
+#define MAGICK_POSIX_IO_SIZE_T unsigned int
+
+/*
+ libtiff features.
+*/
+
+/* Define to 1 if you have the <tiffconf.h> header file. */
+#define HAVE_TIFFCONF_H 1
+
+/* Define to 1 if you have the `TIFFIsCODECConfigured' function. */
+#define HAVE_TIFFISCODECCONFIGURED 1
+
+/* Define to 1 if you have the `TIFFMergeFieldInfo' function. */
+#define HAVE_TIFFMERGEFIELDINFO 1
+
+/* Define to 1 if you have the `TIFFSetErrorHandlerExt' function. */
+#define HAVE_TIFFSETERRORHANDLEREXT 1
+
+/* Define to 1 if you have the `TIFFSetTagExtender' function. */
+#define HAVE_TIFFSETTAGEXTENDER 1
+
+/* Define to 1 if you have the `TIFFSetWarningHandlerExt' function. */
+#define HAVE_TIFFSETWARNINGHANDLEREXT 1
+
+/* Define to 1 if you have the `TIFFSwabArrayOfTriples' function. */
+#define HAVE_TIFFSWABARRAYOFTRIPLES 1
+
+/* Define to 1 if you have the <ft2build.h> header file. */
+#define HAVE_FT2BUILD_H 1
+
+// Define to support memory mapping files for improved performance
+#define HAVE_MMAP_FILEIO 1
+
+// Use Visual C++ C inline method extension to improve performance
+#if !defined(inline)
+# define inline __inline
+#endif
+
+// Visual C++ does not usually seem to support the C'99 restrict keyword
+// Maybe it will be added in some version.
+#if defined(_VISUALC_) /* && (_MSC_VER <= 1500) */
+# define restrict /* nothing */
+#endif
+
+#if !defined(chsize)
+# if defined(__BORLANDC__)
+# define chsize(file,length) chsize(file,length)
+# else
+# define chsize(file,length) _chsize(file,length)
+# endif
+#endif
+
+#if !defined(hypot)
+# define hypot _hypot
+#endif
+
+#if !defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER < 1500)
+#define vsnprintf _vsnprintf
+#endif
+
+#if defined(_MT) && defined(MSWINDOWS)
+#define SAFE_GLOBAL __declspec(thread)
+#else
+#define SAFE_GLOBAL
+#endif
+
+/*
+ With Visual C++, Popen and pclose are available via _popen and _pclose.
+ These are documented to work for console applications only.
+*/
+#define HAVE_POPEN 1
+#define HAVE__POPEN 1
+#if !defined(popen)
+# define popen(command,mode) _popen(command,mode)
+#endif /* !defined(popen) */
+#define HAVE_PCLOSE 1
+#define HAVE__PCLOSE 1
+#if !defined(pclose)
+# define pclose(stream) _pclose(stream)
+#endif /* !defined(pclose) */
+
+/*
+ Visual C++ 7.0 supports GlobalMemoryStatusEx but MinGW headers and
+ Visual C++ 6.0 lack support for it.
+
+ _MSC_VER values:
+ 1100 MSVC 5.0
+ 1200 MSVC 6.0
+ 1300 MSVC 7.0 Visual C++ .NET 2002
+ 1310 Visual c++ .NET 2003
+ 1400 Visual C++ 2005
+ 1500 Visual C++ 2008
+ 1600 Visual C++ 2010
+ 1700 Visual C++ 2012
+ 1800 Visual C++ 2013
+ 1900 Visual C++ 2015
+
+ Should look at __CLR_VER ("Defines the version of the common language
+ runtime used when the application was compiled.") as well.
+*/
+#if defined(_VISUALC_) && (_MSC_VER >= 1310)
+# define HAVE_GLOBALMEMORYSTATUSEX 1
+#endif
+
+/*
+ _aligned_malloc was introduced in Visual Studio .NET 2003.
+ The feature is is introduced in msvcr71.dll and is capable of
+ working on Windows '98 given that the correct run-time libraries
+ are installed.
+*/
+#if ((defined(_VISUALC_) && (_MSC_VER >= 1310)) || \
+ (defined(__MINGW32__) && (__MSVCRT_VERSION__ >= 0x0700)))
+# define HAVE__ALIGNED_MALLOC 1
+#endif
+
+/*
+ Windows provides Unix-style access() via _access()
+ */
+#define HAVE_ACCESS 1
+#define access(path,mode) _access(path,mode)
+
+/*
+ Windows provides Unix-style mkdir() via _mkdir() but it does not
+ seem to accept a 'mode' argument.
+ */
+#define mkdir(path,mode) _mkdir(path)
+
+/*
+ Windows provides _commit() as a substitute for fsync()
+*/
+#define fsync(fd) _commit(fd)
+
+#if !defined(isatty)
+# define isatty(x) _isatty(x)
+#endif
+
+#if !defined(fileno)
+# define fileno(x) _fileno(x)
+#endif
+
+#if !defined(unlink)
+# define unlink(path) _unlink(path)
+#endif /* !defined(unlink) */
+
+
+/*
+ I/O defines.
+*/
+#if !defined(Windows95) && !defined(__BORLANDC__)
+ /* Windows '95 and Borland C do not support _lseeki64 */
+# define MagickSeek(fildes,offset,whence) _lseeki64(fildes,/* __int64 */ offset,whence)
+# define MagickTell(fildes) /* __int64 */ _telli64(fildes)
+#else
+# define MagickSeek(fildes,offset,whence) lseek(fildes,offset,whence)
+# define MagickTell(fildes) (MagickSeek(fildes,0,SEEK_CUR))
+#endif
+
+
+#if !defined(Windows95) && !defined(__BORLANDC__) && \
+ !(defined(_MSC_VER) && _MSC_VER < 1400) && \
+ !(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800)
+
+ /*
+ Windows '95 and Borland C do not support _lseeki64
+ Visual Studio does not support _fseeki64 and _ftelli64 until the 2005 release.
+ Without these interfaces, files over 2GB in size are not supported for Windows.
+ */
+# define MagickFseek(stream,offset,whence) _fseeki64(stream,/* __int64 */ offset,whence)
+# define MagickFstat(fildes,stat_buff) _fstati64(fildes,/* struct _stati64 */ stat_buff)
+# define MagickFtell(stream) /* __int64 */ _ftelli64(stream)
+# define MagickStatStruct_t struct _stati64
+# define MagickStat(path,stat_buff) _stati64(path,/* struct _stati64 */ stat_buff)
+#else
+# define MagickFseek(stream,offset,whence) fseek(stream,offset,whence)
+# define MagickFstat(fildes,stat_buff) fstat(fildes,stat_buff)
+# define MagickFtell(stream) ftell(stream)
+# define MagickStatStruct_t struct stat
+# define MagickStat(path,stat_buff) stat(path,stat_buff)
+#endif
+
+/*
+ Typedef declarations.
+*/
+typedef UINT (CALLBACK *LPFNDLLFUNC1)(DWORD,UINT);
+
+#if !defined(XS_VERSION) /* Not in Perl extension */
+
+/*
+ For POSIX, ssize_t is the type returned by _read and _write.
+ Recent MinGW compilers include this typedef by default.
+
+ Note that under WIN64 read/write appear to still return 'int' and use
+ 'unsigned int' rather than 'size_t' to specify the I/O size. This really
+ sucks!
+ */
+#if !defined(ssize_t) && !defined(__MINGW32__) && !defined(__MINGW64__)
+# if defined(WIN64)
+ typedef __int64 ssize_t;
+# else
+ typedef int ssize_t;
+# endif
+#endif /* !defined(ssize_t) && !defined(__MINGW32__) && !defined(__MINGW64__)*/
+
+#endif /* !defined(XS_VERSION) */
+
+/*
+ Bzlib is strange in that symbols from bzlib.h are DLL-exported by
+ default rather than imported. This feels like a bug to me.
+*/
+#if defined(HasBZLIB)
+# if defined(_WIN32)
+# define BZ_IMPORT 1
+# endif
+#endif /* defined(HasBZLIB) */
+
+
+/*
+ NT utilities routines.
+*/
+
+extern MagickExport char
+ *NTGetLastError(void);
+
+/*
+ Ghostscript DLL support.
+*/
+extern MagickExport int
+ NTGhostscriptDLL(char *path, int path_length),
+ NTGhostscriptEXE(char *path, int path_length),
+ NTGhostscriptFonts(char *path, int path_length),
+ NTGhostscriptLoadDLL(void),
+ NTGhostscriptUnLoadDLL(void);
+
+#if defined(MAGICK_IMPLEMENTATION)
+extern MagickExport const GhostscriptVectors
+ *NTGhostscriptDLLVectors( void );
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+/*
+ Directory access functions
+*/
+#if !defined(HAVE_DIRENT_H) || defined(__MINGW32__) || defined(__MINGW64__)
+struct dirent
+{
+ char
+ d_name[2048];
+
+ int
+ d_namlen;
+};
+
+typedef struct _DIR
+{
+ HANDLE
+ hSearch;
+
+ WIN32_FIND_DATA
+ Win32FindData;
+
+ BOOL
+ firsttime;
+
+ struct dirent
+ file_info;
+} DIR;
+
+extern MagickExport long
+ NTtelldir(DIR *);
+
+extern MagickExport struct dirent
+ *NTreaddir(DIR *);
+
+extern MagickExport DIR
+ *NTopendir(const char *);
+
+extern MagickExport int
+ NTclosedir(DIR *);
+
+extern MagickExport void
+ NTseekdir(DIR *,long);
+
+#define closedir(dir) NTclosedir(dir)
+#define opendir(path) NTopendir(path)
+#define readdir(entry) NTreaddir(entry)
+#define seekdir(entry,position) NTseekdir(entry,position)
+#define telldir(entry) NTtelldir(entry)
+#endif /* !defined(HAVE_DIRENT_H) */
+
+/*
+ System functions.
+*/
+extern MagickExport int
+ NTSystemComman(const char *);
+
+#if !defined(XS_VERSION) /* Not in Perl extension */
+
+/*
+ Precision timing functions.
+*/
+extern MagickExport double
+ NTElapsedTime(void),
+ NTUserTime(void);
+
+/*
+ Memory mapped file support.
+*/
+#define PROT_NONE 0x0 // pages can not be accessed
+#define PROT_READ 0x1 // pages can be read
+#define PROT_WRITE 0x2 // pages can be written
+#define MAP_SHARED 0x1 // share changes
+#define MAP_PRIVATE 0x2 // changes are private
+#define MAP_NORESERVE 0x4 // do not reserve paging space
+#define MAP_ANON 0x8 // anonymous mapping
+#if !defined(MAP_FAILED)
+# define MAP_FAILED ((void *) -1) // returned on error by mmap
+#endif
+#define MS_ASYNC 0x0 // asynchronous page sync
+#define MS_SYNC 0x1 // synchronous page sync
+
+extern MagickExport void
+ Exit(int) MAGICK_FUNC_NORETURN,
+ *NTmmap(char *address,size_t length,int protection,int access,int file,
+ magick_off_t offset);
+
+extern MagickExport int
+ NTftruncate(int filedes, off_t length),
+ NTmsync(void *addr, size_t len, int flags),
+ NTmunmap(void *addr, size_t len);
+
+extern MagickExport int
+ MagickGetFileAttributes(const char *filename, MagickStatStruct_t *statbuf);
+
+extern MagickExport int
+ MagickSetFileAttributes(const char *filename, const MagickStatStruct_t *statbuf);
+
+#define MagickMmap(address,length,protection,access,file,offset) \
+ NTmmap(address,length,protection,access,file,offset)
+#define MagickMsync(addr,len,flags) NTmsync(addr,len,flags)
+#define MagickMunmap(addr,len) NTmunmap(addr,len)
+#define MagickFtruncate(filedes,length) NTftruncate(filedes,length)
+
+/*
+ libltdl-like module loader wrappers
+*/
+#if !defined(HasLTDL)
+extern MagickExport void
+ *NTdlopen(const char *filename),
+ *NTdlsym(void *handle, const char *name);
+
+extern MagickExport int
+ NTdlclose(void *handle),
+ NTdlexit(void),
+ NTdlinit(void),
+ NTdlsetsearchpath(const char *);
+
+extern MagickExport const char
+ *NTdlerror(void);
+
+#define lt_dlclose(handle) NTdlclose(handle)
+#define lt_dlerror() NTdlerror()
+#define lt_dlexit() NTdlexit()
+#define lt_dlinit() NTdlinit()
+#define lt_dlopen(filename) NTdlopen(filename)
+#define lt_dlsetsearchpath(path) NTdlsetsearchpath(path)
+#define lt_dlsym(handle,name) NTdlsym(handle,name)
+#endif /* !defined(HasLTDL) */
+
+extern MagickExport unsigned char
+ *NTResourceToBlob(const char *);
+
+extern MagickExport MagickPassFail
+ NTGetExecutionPath(char *path);
+
+extern MagickExport MagickBool
+ IsWindows95(),
+ NTKernelAPISupported(const char *name);
+
+extern MagickExport void
+ NTErrorHandler(const ExceptionType,const char *,const char *),
+ NTWarningHandler(const ExceptionType,const char *,const char *);
+
+extern MagickExport long
+ MagickGetMMUPageSize();
+
+extern MagickExport void
+ NTInitializeExceptionHandlers();
+
+#endif /* !XS_VERSION */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* !C++ */
+
+#endif /* !_MAGICK_NTBASE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/nt_feature.c b/magick/nt_feature.c
new file mode 100644
index 0000000..30d698e
--- /dev/null
+++ b/magick/nt_feature.c
@@ -0,0 +1,696 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% %
+% N N TTTTT %
+% NN N T %
+% N N N T %
+% N NN T %
+% N N T %
+% %
+% %
+% Windows NT Feature Methods for GraphicsMagick %
+% %
+% %
+% Software Design %
+% John Cristy %
+% December 1996 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+#include "magick/studio.h"
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+/*
+ Include declarations.
+*/
+#include "magick/confirm_access.h"
+#include "magick/utility.h"
+#include "magick/monitor.h"
+#include "magick/nt_feature.h"
+#include "magick/pixel_cache.h"
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+#include <windows.h>
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C r o p I m a g e T o H B i t m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method CropImageToHBITMAP extracts a specified region of the image and
+% returns it as a Windows HBITMAP. While the same functionality can be
+% accomplished by invoking CropImage() followed by ImageToHBITMAP(), this
+% method is more efficient since it copies pixels directly to the HBITMAP.
+%
+% The format of the CropImageToHBITMAP method is:
+%
+% HBITMAP CropImageToHBITMAP(Image* image,const RectangleInfo *geometry,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o geometry: Define the region of the image to crop with members
+% x, y, width, and height.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport void *CropImageToHBITMAP(Image *image,
+ const RectangleInfo *geometry,ExceptionInfo *exception)
+{
+#define CropImageText "[%s] Crop to bitmap... "
+
+ long
+ y;
+
+ RectangleInfo
+ page;
+
+ register const PixelPacket
+ *p;
+
+ BITMAP
+ bitmap;
+
+ HBITMAP
+ bitmapH;
+
+ HANDLE
+ bitmap_bitsH;
+
+ register RGBQUAD
+ *q;
+
+ RGBQUAD
+ *bitmap_bits;
+
+ /*
+ Check crop geometry.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(geometry != (const RectangleInfo *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if (((geometry->x+(long) geometry->width) < 0) ||
+ ((geometry->y+(long) geometry->height) < 0) ||
+ (geometry->x >= (long) image->columns) ||
+ (geometry->y >= (long) image->rows))
+ ThrowImageException(OptionError,GeometryDoesNotContainImage,
+ MagickMsg(ResourceLimitError,UnableToCropImage));
+ page=(*geometry);
+ if ((page.x+(long) page.width) > (long) image->columns)
+ page.width=image->columns-page.x;
+ if ((page.y+(long) page.height) > (long) image->rows)
+ page.height=image->rows-page.y;
+ if (page.x < 0)
+ {
+ page.width+=page.x;
+ page.x=0;
+ }
+ if (page.y < 0)
+ {
+ page.height+=page.y;
+ page.y=0;
+ }
+
+ if ((page.width == 0) || (page.height == 0))
+ ThrowImageException(OptionError,GeometryDimensionsAreZero,
+ MagickMsg(ResourceLimitError,UnableToCropImage));
+ /*
+ Initialize crop image attributes.
+ */
+ bitmap.bmType = 0;
+ bitmap.bmWidth = page.width;
+ bitmap.bmHeight = page.height;
+ bitmap.bmWidthBytes = bitmap.bmWidth * 4;
+ bitmap.bmPlanes = 1;
+ bitmap.bmBitsPixel = 32;
+ bitmap.bmBits = NULL;
+
+ bitmap_bitsH = (HANDLE) GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE,
+ page.width*page.height*bitmap.bmBitsPixel);
+ if (bitmap_bitsH == NULL)
+ return( NULL );
+
+ bitmap_bits = (RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH);
+
+ if ( bitmap.bmBits == NULL )
+ bitmap.bmBits = bitmap_bits;
+
+ if (image->colorspace != RGBColorspace)
+ (void) TransformColorspace(image,RGBColorspace);
+
+ /*
+ Extract crop image.
+ */
+ q = bitmap_bits;
+
+ for (y=0; y < (long) page.height; y++)
+ {
+ p=AcquireImagePixels(image,page.x,page.y+y,page.width,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+
+#if QuantumDepth == 8
+ /* Form of PixelPacket is identical to RGBQUAD when QuantumDepth==8 */
+ memcpy((void*)q,(const void*)p,page.width*sizeof(PixelPacket));
+ q += page.width;
+
+#else /* 16 or 32 bit Quantum */
+ {
+ long
+ x;
+
+ /* Transfer pixels, scaling to Quantum */
+ for( x=page.width ; x> 0 ; x-- )
+ {
+ q->rgbRed = ScaleQuantumToChar(p->red);
+ q->rgbGreen = ScaleQuantumToChar(p->green);
+ q->rgbBlue = ScaleQuantumToChar(p->blue);
+ q->rgbReserved = 0;
+ ++q;
+ ++p;
+ }
+ }
+#endif
+ if (QuantumTick(y,page.height))
+ if (!MagickMonitorFormatted(y,page.height-1,exception,CropImageText,
+ image->filename))
+ break;
+ }
+ if (y < (long) page.height)
+ {
+ GlobalUnlock((HGLOBAL) bitmap_bitsH);
+ GlobalFree((HGLOBAL) bitmap_bitsH);
+ return((void *) NULL);
+ }
+
+ bitmap.bmBits = bitmap_bits;
+ bitmapH = CreateBitmapIndirect( &bitmap );
+
+ GlobalUnlock((HGLOBAL) bitmap_bitsH);
+ GlobalFree((HGLOBAL) bitmap_bitsH);
+
+ return (void *)bitmapH;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s M a g i c k C o n f l i c t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsMagickConflict returns true if the image format conflicts with
+% a logical drive (.e.g. X:).
+%
+% The format of the IsMagickConflict method is:
+%
+% unsigned int IsMagickConflict(const char *magick)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsMagickConflict returns true if the image format
+% conflicts with a logical drive.
+%
+% o magick: Specifies the image format.
+%
+%
+*/
+MagickExport unsigned int NTIsMagickConflict(const char *magick)
+{
+ assert(magick != (char *) NULL);
+ if (strlen(magick) > 2)
+ return(False);
+ if ((strlen(magick) > 1) && (magick[1] != ':'))
+ return(False);
+ return((GetLogicalDrives()) & (1 << ((toupper((int) (*magick)))-'A')));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ N T G e t T y pe L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method NTGetTypeList returns a TypeInfo list corresponding to installed
+% Windows TrueType fonts. The user is responsible for destroying the
+% returned list once it is no longer needed. NULL is returned if a fatal
+% error is encountered.
+%
+% The format of the NTGetTypeList method is:
+%
+% TypeInfo* NTGetTypeList( void )
+%
+% A description of each parameter follows:
+%
+% o returns: A linked list of TypeInfo structures is returned.
+%
+*/
+static int TypeInfoCompare(const void *x,const void *y)
+{
+ TypeInfo
+ **info_1,
+ **info_2;
+
+ info_1=(TypeInfo **) x;
+ info_2=(TypeInfo **) y;
+ return( strcmp((*info_1)->name, (*info_2)->name) );
+}
+MagickExport TypeInfo* NTGetTypeList( void )
+{
+ TypeInfo
+ *type_list;
+
+ HKEY
+ reg_key = (HKEY) INVALID_HANDLE_VALUE;
+
+ LONG
+ res;
+
+
+ int
+ list_entries = 0;
+
+ char
+ buffer[MaxTextExtent],
+ font_root[MaxTextExtent];
+
+ type_list = (TypeInfo*) NULL;
+
+ res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
+ 0, KEY_READ | KEY_ENUMERATE_SUB_KEYS, &reg_key);
+
+ if (res != ERROR_SUCCESS)
+ res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts",
+ 0, KEY_READ | KEY_ENUMERATE_SUB_KEYS, &reg_key);
+
+ if (res != ERROR_SUCCESS)
+ return (TypeInfo *) type_list;
+
+ *font_root='\0';
+ if ( getenv("SystemRoot") != (char *) NULL)
+ {
+ strlcpy(buffer,getenv("SystemRoot"),sizeof(buffer));
+ strlcat(buffer,"\\fonts\\arial.ttf",sizeof(buffer));
+ if (IsAccessible(buffer))
+ {
+ strlcpy(font_root,getenv("SystemRoot"),sizeof(buffer));
+ strlcat(font_root,"\\fonts\\",sizeof(buffer));
+ }
+ else
+ {
+ strlcpy(font_root,getenv("SystemRoot"),sizeof(buffer));
+ strlcat(font_root,"\\",sizeof(buffer));
+ }
+ }
+
+ {
+ TypeInfo
+ *type_info;
+
+ DWORD
+ registry_index = 0,
+ type,
+ value_data_size,
+ value_name_length;
+
+ char
+ value_data[MaxTextExtent],
+ value_name[MaxTextExtent];
+
+ res = ERROR_SUCCESS;
+
+ while ( (res != ERROR_NO_MORE_ITEMS) && (res == ERROR_SUCCESS) )
+ {
+ char
+ *family_extent,
+ token[MaxTextExtent],
+ *pos,
+ *q;
+
+ value_name_length = sizeof(value_name) - 1;
+ value_data_size = sizeof(value_data) - 1;
+ res = RegEnumValueA ( reg_key, registry_index, value_name, &value_name_length,
+ 0, &type, (BYTE*)value_data, &value_data_size);
+ registry_index++;
+ if ( (pos = strstr(value_name, " (TrueType)")) == (char*) NULL )
+ continue;
+ *pos='\0'; /* Remove (TrueType) from string */
+
+ type_info=MagickAllocateMemory(TypeInfo *,sizeof(TypeInfo));
+ if (type_info == (TypeInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateTypeInfo);
+ (void) memset(type_info,0,sizeof(TypeInfo));
+
+ type_info->path=AcquireString("Windows Fonts");
+ type_info->signature=MagickSignature;
+
+ /* Name */
+ strlcpy(buffer,value_name,MaxTextExtent);
+ for(pos = buffer; *pos != 0 ; pos++)
+ if (*pos == ' ')
+ *pos = '-';
+ type_info->name=AcquireString(buffer);
+
+ /* Fullname */
+ type_info->description=AcquireString(value_name);
+
+ /* Format */
+ type_info->format=AcquireString("truetype");
+
+ /* Glyphs */
+ if (strchr(value_data,'\\') == (char *) NULL)
+ {
+ strlcpy(buffer,font_root,MaxTextExtent);
+ strlcat(buffer,value_data,MaxTextExtent);
+ }
+ else
+ strlcpy(buffer,value_data,MaxTextExtent);
+
+ LocaleLower(buffer);
+ type_info->glyphs=AcquireString(buffer);
+
+ type_info->stretch=NormalStretch;
+ type_info->style=NormalStyle;
+ type_info->weight=400;
+
+ /* Some fonts are known to require special encodings */
+ if ( (LocaleCompare(type_info->name, "Symbol") == 0 ) ||
+ (LocaleCompare(type_info->name, "Wingdings") == 0 ) ||
+ (LocaleCompare(type_info->name, "Wingdings-2") == 0 ) ||
+ (LocaleCompare(type_info->name, "Wingdings-3") == 0 ) )
+ type_info->encoding=AcquireString("AppleRoman");
+
+ family_extent=value_name;
+
+ for (q=value_name; *q != '\0'; )
+ {
+ MagickGetToken(q,&q,token,MaxTextExtent);
+ if (*token == '\0')
+ break;
+
+ if (LocaleCompare(token,"Italic") == 0)
+ {
+ type_info->style=ItalicStyle;
+ }
+
+ else if (LocaleCompare(token,"Oblique") == 0)
+ {
+ type_info->style=ObliqueStyle;
+ }
+
+ else if (LocaleCompare(token,"Bold") == 0)
+ {
+ type_info->weight=700;
+ }
+
+ else if (LocaleCompare(token,"Thin") == 0)
+ {
+ type_info->weight=100;
+ }
+
+ else if ( (LocaleCompare(token,"ExtraLight") == 0) ||
+ (LocaleCompare(token,"UltraLight") == 0) )
+ {
+ type_info->weight=200;
+ }
+
+ else if (LocaleCompare(token,"Light") == 0)
+ {
+ type_info->weight=300;
+ }
+
+ else if ( (LocaleCompare(token,"Normal") == 0) ||
+ (LocaleCompare(token,"Regular") == 0) )
+ {
+ type_info->weight=400;
+ }
+
+ else if (LocaleCompare(token,"Medium") == 0)
+ {
+ type_info->weight=500;
+ }
+
+ else if ( (LocaleCompare(token,"SemiBold") == 0) ||
+ (LocaleCompare(token,"DemiBold") == 0) )
+ {
+ type_info->weight=600;
+ }
+
+ else if ( (LocaleCompare(token,"ExtraBold") == 0) ||
+ (LocaleCompare(token,"UltraBold") == 0) )
+ {
+ type_info->weight=800;
+ }
+
+ else if ( (LocaleCompare(token,"Heavy") == 0) ||
+ (LocaleCompare(token,"Black") == 0) )
+ {
+ type_info->weight=900;
+ }
+
+ else if (LocaleCompare(token,"Condensed") == 0)
+ {
+ type_info->stretch = CondensedStretch;
+ }
+
+ else if (LocaleCompare(token,"Expanded") == 0)
+ {
+ type_info->stretch = ExpandedStretch;
+ }
+
+ else if (LocaleCompare(token,"ExtraCondensed") == 0)
+ {
+ type_info->stretch = ExtraCondensedStretch;
+ }
+
+ else if (LocaleCompare(token,"ExtraExpanded") == 0)
+ {
+ type_info->stretch = ExtraExpandedStretch;
+ }
+
+ else if (LocaleCompare(token,"SemiCondensed") == 0)
+ {
+ type_info->stretch = SemiCondensedStretch;
+ }
+
+ else if (LocaleCompare(token,"SemiExpanded") == 0)
+ {
+ type_info->stretch = SemiExpandedStretch;
+ }
+
+ else if (LocaleCompare(token,"UltraCondensed") == 0)
+ {
+ type_info->stretch = UltraCondensedStretch;
+ }
+
+ else if (LocaleCompare(token,"UltraExpanded") == 0)
+ {
+ type_info->stretch = UltraExpandedStretch;
+ }
+
+ else
+ {
+ family_extent=q;
+ }
+ }
+
+ strncpy(buffer,value_name,family_extent-value_name+1);
+ buffer[family_extent-value_name]='\0';
+ type_info->family=AcquireString(buffer);
+
+ list_entries++;
+ if (type_list == (TypeInfo *) NULL)
+ {
+ type_list=type_info;
+ continue;
+ }
+ type_list->next=type_info;
+ type_info->previous=type_list;
+ type_list=type_list->next;
+ continue;
+ }
+ }
+
+ RegCloseKey ( reg_key );
+
+ /* Sort entries */
+ {
+ TypeInfo
+ **type_array;
+
+ int
+ array_index = 0;
+
+ type_array = MagickAllocateMemory(TypeInfo**,sizeof(TypeInfo*)*list_entries);
+
+ while (type_list->previous != (TypeInfo *) NULL)
+ type_list=type_list->previous;
+
+ for (array_index=0; array_index< list_entries; array_index++)
+ {
+ type_array[array_index] = type_list;
+ type_list=type_list->next;
+ }
+
+ qsort((void *) type_array, list_entries, sizeof(TypeInfo *),TypeInfoCompare);
+
+ type_list=type_array[0];
+ type_list->previous=(TypeInfo *) NULL;
+ for(array_index=1; array_index < list_entries; array_index++)
+ {
+ type_array[array_index-1]->next = type_array[array_index];
+ type_array[array_index]->previous = type_array[array_index-1];
+ type_array[array_index]->next=(TypeInfo *) NULL;
+ }
+
+ MagickFreeMemory(type_array);
+ }
+
+ return (TypeInfo *) type_list;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m a g e T o H B i t m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ImageToHBITMAP creates a Windows HBITMAP from an IM Image
+%
+% The format of the ImageToHBITMAP method is:
+%
+% HBITMAP ImageToHBITMAP(Image* image)
+%
+% A description of each parameter follows:
+%
+% o image: the image to convert.
+%
+%
+*/
+MagickExport void *ImageToHBITMAP(Image* image)
+{
+ unsigned long
+ nPixels,
+ row;
+
+ long
+ memSize;
+
+ const PixelPacket
+ *pPixels;
+
+ BITMAP
+ bitmap;
+
+ HBITMAP
+ bitmapH;
+
+ HANDLE
+ bitmap_bitsH;
+
+ RGBQUAD
+ *pDestPixel,
+ *bitmap_bits;
+
+ nPixels = image->columns * image->rows;
+
+ bitmap.bmType = 0;
+ bitmap.bmWidth = image->columns;
+ bitmap.bmHeight = image->rows;
+ bitmap.bmWidthBytes = bitmap.bmWidth * 4;
+ bitmap.bmPlanes = 1;
+ bitmap.bmBitsPixel = 32;
+ bitmap.bmBits = NULL;
+
+ memSize = nPixels * bitmap.bmBitsPixel;
+ bitmap_bitsH = (HANDLE) GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, memSize);
+
+ if (bitmap_bitsH == NULL)
+ return( NULL );
+
+ bitmap_bits = (RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH);
+ pDestPixel = bitmap_bits;
+
+ if ( bitmap.bmBits == NULL )
+ bitmap.bmBits = bitmap_bits;
+
+ (void) TransformColorspace(image,RGBColorspace);
+ for( row = 0 ; row < image->rows ; row++ )
+ {
+ pPixels = AcquireImagePixels(image,0,row,image->columns,1,
+ &image->exception);
+#if QuantumDepth == 8
+ /* Form of PixelPacket is identical to RGBQUAD when QuantumDepth==8 */
+ memcpy((void*)pDestPixel,(const void*)pPixels,
+ sizeof(PixelPacket)*image->columns);
+ pDestPixel += image->columns;
+
+#else /* 16 or 32 bit Quantum */
+ {
+ unsigned long nPixelCount;
+
+ /* Transfer pixels, scaling to Quantum */
+ for( nPixelCount = image->columns; nPixelCount ; nPixelCount-- )
+ {
+ pDestPixel->rgbRed = ScaleQuantumToChar(pPixels->red);
+ pDestPixel->rgbGreen = ScaleQuantumToChar(pPixels->green);
+ pDestPixel->rgbBlue = ScaleQuantumToChar(pPixels->blue);
+ pDestPixel->rgbReserved = 0;
+ ++pDestPixel;
+ ++pPixels;
+ }
+ }
+#endif
+ }
+
+ bitmap.bmBits = bitmap_bits;
+ bitmapH = CreateBitmapIndirect( &bitmap );
+
+ GlobalUnlock((HGLOBAL) bitmap_bitsH);
+ GlobalFree((HGLOBAL) bitmap_bitsH);
+
+ return (void *)bitmapH;
+}
+
+#endif
diff --git a/magick/nt_feature.h b/magick/nt_feature.h
new file mode 100644
index 0000000..9a8a758
--- /dev/null
+++ b/magick/nt_feature.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Windows NT Utility Methods for ImageMagick.
+*/
+#ifndef _MAGICK_NTFEATURE_H
+#define _MAGICK_NTFEATURE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "magick/render.h"
+
+/*
+ NT features routines.
+*/
+extern MagickExport char
+ *NTRegistryKeyLookup(const char *key);
+
+extern MagickExport void
+ *CropImageToHBITMAP(Image *,const RectangleInfo *,ExceptionInfo *),
+ *ImageToHBITMAP(Image* image);
+
+#if !defined(XS_VERSION)
+
+extern MagickExport unsigned int
+ NTIsMagickConflict(const char *);
+
+extern MagickExport TypeInfo
+ * NTGetTypeList( void );
+
+#endif /* !XS_VERSION */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* !C++ */
+
+#endif /* !_MAGICK_NTFEATURE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/omp_data_view.c b/magick/omp_data_view.c
new file mode 100644
index 0000000..d033d60
--- /dev/null
+++ b/magick/omp_data_view.c
@@ -0,0 +1,212 @@
+/*
+% Copyright (C) 2008 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% GraphicsMagick OpenMP Data View Methods %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% September 2008 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/utility.h"
+#include "magick/omp_data_view.h"
+
+
+/*
+ Declare OpenMP data view interfaces.
+*/
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+/*
+ Destroy a thread view data set.
+*/
+MagickExport void
+DestroyThreadViewDataSet(ThreadViewDataSet *data_set)
+{
+ unsigned int
+ i;
+
+ if (data_set != (ThreadViewDataSet *) NULL)
+ {
+ if (data_set->view_data != (void *) NULL)
+ {
+ if (data_set->destructor != (MagickFreeFunc) NULL)
+ {
+ for (i=0; i < data_set->nviews; i++)
+ {
+ (data_set->destructor)(data_set->view_data[i]);
+ data_set->view_data[i]=(void *) NULL;
+ }
+ }
+ MagickFreeMemory(data_set->view_data);
+ }
+ data_set->nviews=0;
+ MagickFreeMemory(data_set);
+ }
+}
+
+/*
+ Allocate an empty thread view data set.
+*/
+MagickExport ThreadViewDataSet *
+AllocateThreadViewDataSet(const MagickFreeFunc destructor,
+ const Image *image,
+ ExceptionInfo *exception)
+{
+ ThreadViewDataSet
+ *data_set;
+
+ MagickPassFail
+ status=MagickPass;
+
+ data_set=MagickAllocateMemory(ThreadViewDataSet *,sizeof(ThreadViewDataSet));
+ if (data_set == (ThreadViewDataSet *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateCacheView);
+ data_set->destructor=destructor;
+ data_set->nviews=omp_get_max_threads();
+ data_set->view_data=MagickAllocateArray(void *,data_set->nviews,sizeof(void *));
+ if (data_set->view_data == (void *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ status=MagickFail;
+ }
+
+ if (data_set->view_data != (void *) NULL)
+ (void) memset(data_set->view_data,0,data_set->nviews*sizeof(void *));
+
+ if (status == MagickFail)
+ {
+ DestroyThreadViewDataSet(data_set);
+ data_set=(ThreadViewDataSet *) NULL;
+ }
+
+ return data_set;
+}
+
+/*
+ Allocate a thread view data set containing data elements with
+ allocation size dictated by 'count' and 'size'.
+ The allocated data is initialized to zero.
+*/
+MagickExport ThreadViewDataSet *
+AllocateThreadViewDataArray(const Image *image,
+ ExceptionInfo *exception,
+ size_t count,size_t size)
+{
+ /*
+ Allocate per-thread-view memory.
+ */
+ ThreadViewDataSet
+ *data_set;
+
+ MagickPassFail
+ alloc_status=MagickFail;
+
+ data_set=AllocateThreadViewDataSet(MagickFree,image,exception);
+ if (data_set != (ThreadViewDataSet *) NULL)
+ {
+ unsigned int
+ allocated_views;
+
+ unsigned int
+ i;
+
+ alloc_status=MagickPass;
+ allocated_views=GetThreadViewDataSetAllocatedViews(data_set);
+
+ for (i=0; i < allocated_views; i++)
+ {
+ unsigned char
+ *data;
+
+ data=MagickAllocateArray(unsigned char *,count,size);
+ if (data == (unsigned char *) NULL)
+ {
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ alloc_status=MagickFail;
+ break;
+ }
+ (void) memset(data,0,count*size);
+ AssignThreadViewData(data_set,i,data);
+ }
+ if (alloc_status == MagickFail)
+ {
+ DestroyThreadViewDataSet(data_set);
+ data_set=(ThreadViewDataSet *) NULL;
+ }
+ }
+
+ return data_set;
+}
+
+/*
+ Access allocated thread data.
+*/
+MagickExport void *
+AccessThreadViewData(ThreadViewDataSet *data_set)
+{
+ unsigned int
+ index=0;
+
+ index=omp_get_thread_num();
+ assert(index < data_set->nviews);
+ return data_set->view_data[index];
+}
+
+MagickExport void *
+AccessThreadViewDataById(ThreadViewDataSet *data_set,
+ unsigned int index)
+{
+ assert(index < data_set->nviews);
+ return data_set->view_data[index];
+}
+
+/*
+ Associate data with a thread data view.
+*/
+MagickExport void AssignThreadViewData
+(ThreadViewDataSet *data_set, unsigned int index, void *data)
+{
+ assert(index < data_set->nviews);
+ MagickFreeMemory(data_set->view_data[index]);
+ data_set->view_data[index]=data;
+}
+
+/*
+ Obtain the nuber of thread data views.
+*/
+MagickExport unsigned int
+GetThreadViewDataSetAllocatedViews
+(ThreadViewDataSet *data_set)
+{
+ return data_set->nviews;
+}
diff --git a/magick/omp_data_view.h b/magick/omp_data_view.h
new file mode 100644
index 0000000..9c78ffb
--- /dev/null
+++ b/magick/omp_data_view.h
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2008 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick OpenMP Thread-Specific Data Methods.
+*/
+#ifndef _MAGICK_OMP_DATA_VIEW
+#define _MAGICK_OMP_DATA_VIEW
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+ /****
+ *
+ * Simplified support for OpenMP thread-specific data
+ * These interfaces are subject to change.
+ *
+ ****/
+
+ typedef struct _ThreadViewDataSet
+ {
+ void
+ **view_data;
+
+ MagickFreeFunc
+ destructor;
+
+ unsigned int
+ nviews;
+ } ThreadViewDataSet;
+
+ extern MagickExport void
+ DestroyThreadViewDataSet(ThreadViewDataSet *data_set);
+
+ extern MagickExport ThreadViewDataSet
+ *AllocateThreadViewDataSet(const MagickFreeFunc destructor,
+ const Image *image,
+ ExceptionInfo *exception);
+
+ extern MagickExport ThreadViewDataSet *
+ AllocateThreadViewDataArray(const Image *image,
+ ExceptionInfo *exception,
+ size_t count,size_t size);
+
+ extern MagickExport unsigned int
+ GetThreadViewDataSetAllocatedViews(ThreadViewDataSet *data_set);
+
+ extern MagickExport void
+ *AccessThreadViewData(ThreadViewDataSet *data_set);
+
+ extern MagickExport void
+ *AccessThreadViewDataById(ThreadViewDataSet *data_set,
+ unsigned int index);
+
+ extern MagickExport void
+ AssignThreadViewData(ThreadViewDataSet *data_set, unsigned int index,
+ void *data);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_OMP_DATA_VIEW */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/operator.c b/magick/operator.c
new file mode 100644
index 0000000..7cec131
--- /dev/null
+++ b/magick/operator.c
@@ -0,0 +1,2444 @@
+/*
+% Copyright (C) 2004 - 2014 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% Interfaces to support quantum operators.
+% Written by Bob Friesenhahn, March 2004.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/enum_strings.h"
+#include "magick/gem.h"
+#include "magick/pixel_iterator.h"
+#include "magick/random-private.h"
+#include "magick/random.h"
+#include "magick/utility.h"
+#include "magick/operator.h"
+
+/*
+ Types.
+*/
+typedef struct _QuantumImmutableContext
+{
+ ChannelType channel;
+ Quantum quantum_value;
+ double double_value;
+} QuantumImmutableContext;
+
+typedef struct _QuantumMutableContext
+{
+ Quantum *channel_lut;
+} QuantumMutableContext;
+
+typedef struct _ChannelOptions_t
+{
+ DoublePixelPacket
+ values;
+
+ MagickBool
+ red_enabled,
+ green_enabled,
+ blue_enabled,
+ opacity_enabled;
+} ChannelOptions_t;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Q u a n t u m O p e r a t o r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% QuantumOperatorImage() performs the requested arithmetic,
+% bitwise-logical, or value operation on the selected channels of
+% the entire image. The AllChannels channel option operates on all
+% color channels whereas the GrayChannel channel option treats the
+% color channels as a grayscale intensity.
+%
+% These operations are on the DirectClass pixels of the image and do not
+% update pixel indexes or colormap.
+%
+% The format of the QuantumOperatorImage method is:
+%
+% MagickPassFail QuantumOperatorImage(Image *image,
+% ChannelType channel, QuantumOperator operator,
+% double rvalue)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: Channel to operate on (RedChannel, CyanChannel,
+% GreenChannel, MagentaChannel, BlueChannel, YellowChannel,
+% OpacityChannel, BlackChannel, MatteChannel, AllChannels,
+% GrayChannel). The AllChannels type only updates color
+% channels. The GrayChannel type treats the color channels
+% as if they represent an intensity.
+%
+% o quantum_operator: Operator to use (AddQuantumOp, AndQuantumOp,
+% AssignQuantumOp, DepthQuantumOp, DivideQuantumOp, GammaQuantumOp,
+% LShiftQuantumOp, MultiplyQuantumOp, NegateQuantumOp,
+% NoiseGaussianQuantumOp, NoiseImpulseQuantumOp,
+% NoiseLaplacianQuantumOp, NoiseMultiplicativeQuantumOp,
+% NoisePoissonQuantumOp, NoiseRandomQuantumOp, NoiseUniformQuantumOp,
+% OrQuantumOp, RShiftQuantumOp, SubtractQuantumOp,
+% ThresholdBlackQuantumOp, ThresholdQuantumOp, ThresholdWhiteQuantumOp,
+% ThresholdBlackNegateQuantumOp, ThresholdWhiteNegateQuantumOp,
+% XorQuantumOp).
+%
+% o rvalue: Operator argument.
+%
+% o exception: Updated with error description.
+%
+*/
+MagickExport MagickPassFail QuantumOperatorImage(Image *image,
+ const ChannelType channel,const QuantumOperator quantum_operator,
+ const double rvalue,ExceptionInfo *exception)
+{
+ return QuantumOperatorRegionImage(image,0,0,image->columns,image->rows,
+ channel,quantum_operator,rvalue,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ Q u a n t u m O p e r a t o r I m a g e M u l t i v a l u e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% QuantumOperatorImageMultivalue() is a semi-private implementation
+% fuction which accepts a comma delimited string of per-channel values
+% and applies a specified operator to the channels of the image. The
+% main reason for this function to exist is to support
+% ChannelThresholdPixels(), BlackThresholdImage(), WhiteThresholdImage(),
+% or any other legacy style function which needs to be implemented.
+%
+% The format of the QuantumOperatorImageMultivalue method is:
+%
+% MagickPassFail QuantumOperatorImageMultivalue(
+% Image *image,
+% const QuantumOperator quantum_operator,
+% const char *values)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o values: define the rvalues, <red>{<green>,<blue>,<opacity>}{%}.
+%
+*/
+MagickExport MagickPassFail
+QuantumOperatorImageMultivalue(Image *image,
+ const QuantumOperator quantum_operator,
+ const char *values)
+{
+ ChannelOptions_t
+ options;
+
+ int
+ count;
+
+ MagickPassFail
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (values == (const char *) NULL)
+ return MagickFail;;
+
+ options.red_enabled = MagickFalse;
+ options.green_enabled = MagickFalse;
+ options.blue_enabled = MagickFalse;
+ options.opacity_enabled = MagickFalse;
+
+ options.values.red = -1.0;
+ options.values.green = -1.0;
+ options.values.blue = -1.0;
+ options.values.opacity = -1.0;
+ count=sscanf(values,"%lf%*[/,%%]%lf%*[/,%%]%lf%*[/,%%]%lf",
+ &options.values.red,
+ &options.values.green,
+ &options.values.blue,
+ &options.values.opacity);
+
+ if ((count > 3) && (options.values.opacity >= 0.0))
+ options.opacity_enabled = MagickTrue;
+ if ((count > 2) && (options.values.blue >= 0.0))
+ options.blue_enabled = MagickTrue;
+ if ((count > 1) && (options.values.green >= 0.0))
+ options.green_enabled = MagickTrue;
+ if ((count > 0) && (options.values.red >= 0.0))
+ options.red_enabled = MagickTrue;
+
+ if (strchr(values,'%') != (char *) NULL)
+ {
+ if (options.red_enabled)
+ options.values.red *= MaxRGB/100.0;
+ if (options.green_enabled)
+ options.values.green *= MaxRGB/100.0;
+ if (options.blue_enabled)
+ options.values.blue *= MaxRGB/100.0;
+ if (options.opacity_enabled)
+ options.values.opacity *= MaxRGB/100.0;
+ }
+
+ status=MagickPass;
+
+ if ((IsRGBColorspace(image->colorspace)) &&
+ ((count == 1) ||
+ ((options.values.red == options.values.green) &&
+ (options.values.green == options.values.blue))))
+ {
+ /*
+ Apply operation to all channels in gray or RGB space.
+ */
+ if (IsGrayColorspace(image->colorspace))
+ status=QuantumOperatorImage(image,GrayChannel,quantum_operator,
+ options.values.red,&image->exception);
+ else
+ status=QuantumOperatorImage(image,AllChannels,quantum_operator,
+ options.values.red,&image->exception);
+ }
+ else
+ {
+ /*
+ Apply operator to individual RGB(A) channels.
+ */
+ if ((MagickPass == status) && (options.red_enabled))
+ {
+ status=QuantumOperatorImage(image,RedChannel,quantum_operator,
+ options.values.red,&image->exception);
+ }
+
+ if ((MagickPass == status) && (options.green_enabled))
+ {
+ status=QuantumOperatorImage(image,GreenChannel,quantum_operator,
+ options.values.green,&image->exception);
+ }
+
+ if ((MagickPass == status) && (options.blue_enabled))
+ {
+ status=QuantumOperatorImage(image,BlueChannel,quantum_operator,
+ options.values.blue,&image->exception);
+ }
+
+ if ((MagickPass == status) && (options.opacity_enabled))
+ {
+ status=QuantumOperatorImage(image,OpacityChannel,quantum_operator,
+ options.values.opacity,&image->exception);
+ }
+ }
+
+ if ((MagickPass == status) && (options.opacity_enabled))
+ {
+ status=QuantumOperatorImage(image,OpacityChannel,quantum_operator,
+ options.values.opacity,&image->exception);
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Q u a n t u m O p e r a t o r R e g i o n I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% QuantumOperatorRegionImage() performs the requested arithmetic,
+% bitwise-logical, or value operation on the selected channels of
+% the image over the specified region. The AllChannels channel option
+% operates on all color channels whereas the GrayChannel channel option
+% treats the color channels as a grayscale intensity.
+%
+% These operations are on the DirectClass pixels of the image and do not
+% update pixel indexes or colormap.
+%
+% The format of the QuantumOperatorRegionImage method is:
+%
+% MagickPassFail QuantumOperatorRegionImage(Image *image,
+% long x, long y, unsigned long columns, unsigned long rows,
+% ChannelType channel, QuantumOperator quantum_operator,
+% double rvalue)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o channel: Channel to operate on (RedChannel, CyanChannel,
+% GreenChannel, MagentaChannel, BlueChannel, YellowChannel,
+% OpacityChannel, BlackChannel, MatteChannel, AllChannels,
+% GrayChannel). The AllChannels type only updates color
+% channels. The GrayChannel type treats the color channels
+% as if they represent an intensity.
+%
+% o x: Ordinate of left row of region.
+%
+% o y: Orginate of top column of region.
+%
+% o columns: Width of region.
+%
+% o rows: Height of region.
+%
+% o quantum_operator: Operator to use (AddQuantumOp,AndQuantumOp,
+% AssignQuantumOp, DepthQuantumOp, DivideQuantumOp, GammaQuantumOp,
+% LShiftQuantumOp, MultiplyQuantumOp, NegateQuantumOp,
+% NoiseGaussianQuantumOp, NoiseImpulseQuantumOp,
+% NoiseLaplacianQuantumOp, NoiseMultiplicativeQuantumOp,
+% NoisePoissonQuantumOp, NoiseRandomQuantumOp, NoiseUniformQuantumOp,
+% OrQuantumOp, RShiftQuantumOp, SubtractQuantumOp,
+% ThresholdBlackQuantumOp, ThresholdQuantumOp, ThresholdWhiteQuantumOp,
+% XorQuantumOp).
+%
+% o rvalue: Operator argument.
+%
+% o exception: Updated with error description.
+%
+*/
+
+#define ApplyArithmeticOperator(lvalue,op,rvalue) \
+{ \
+ double \
+ result; \
+ \
+ result=(double) lvalue op (double) rvalue; \
+ lvalue=RoundDoubleToQuantum(result); \
+}
+
+static MagickPassFail
+QuantumAddCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].red,+,context->double_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].green,+,context->double_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].blue,+,context->double_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].opacity,+,context->double_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ ApplyArithmeticOperator(pixels[i].red,+,context->double_value);
+ ApplyArithmeticOperator(pixels[i].green,+,context->double_value);
+ ApplyArithmeticOperator(pixels[i].blue,+,context->double_value);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ ApplyArithmeticOperator(intensity,+,context->double_value);
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+static MagickPassFail
+QuantumAndCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red &= context->quantum_value;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green &= context->quantum_value;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue &= context->quantum_value;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity &= context->quantum_value;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red &= context->quantum_value;
+ pixels[i].green &= context->quantum_value;
+ pixels[i].blue &= context->quantum_value;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity &= context->quantum_value;
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+static MagickPassFail
+QuantumAssignCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red = context->quantum_value;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green = context->quantum_value;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue = context->quantum_value;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity = context->quantum_value;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red = context->quantum_value;
+ pixels[i].green = context->quantum_value;
+ pixels[i].blue = context->quantum_value;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red = pixels[i].green = pixels[i].blue =
+ context->quantum_value;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+#define ApplyChannelDepth(parameter) \
+ { \
+ for (i=0; i < npixels; i++) \
+ parameter=scale*((parameter)/scale); \
+ }
+#if MaxRGB > MaxMap
+# define CrushChannelDepth(parameter) (scale*((parameter)/scale))
+#else
+# define CrushChannelDepth(parameter) (mutable_context->channel_lut[ScaleQuantumToMap(parameter)])
+#endif
+static MagickPassFail
+QuantumDepthCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ QuantumMutableContext
+ *mutable_context=(QuantumMutableContext *) mutable_data;
+
+ const QuantumImmutableContext
+ *immutable_context=(const QuantumImmutableContext *) immutable_data;
+
+ unsigned int
+ depth;
+
+ register unsigned int
+ scale;
+
+ register long
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(exception);
+
+ depth=immutable_context->quantum_value;
+ if (depth < 1)
+ depth=1;
+ else if (depth > QuantumDepth)
+ depth=QuantumDepth;
+
+ if (depth < QuantumDepth)
+ {
+ scale=MaxRGB / (MaxRGB >> (QuantumDepth-depth));
+
+ /*
+ Build LUT for Q8 and Q16 builds
+ */
+#if MaxRGB <= MaxMap
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_QuantumDepthCB)
+# endif
+ if (mutable_context->channel_lut == (Quantum *) NULL)
+ {
+ mutable_context->channel_lut=MagickAllocateArray(Quantum *, MaxMap+1,sizeof(Quantum));
+ if (mutable_context->channel_lut == (Quantum *) NULL)
+ status=MagickFail;
+
+ if (mutable_context->channel_lut != (Quantum *) NULL)
+ {
+ for (i=0; i <= (long) MaxMap; i++)
+ mutable_context->channel_lut[i] = scale*(i/scale);
+ }
+ }
+#else
+ ARG_NOT_USED(*mutable_context);
+#endif
+
+ if (MagickFail == status)
+ return status;
+
+ switch (immutable_context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red=CrushChannelDepth(pixels[i].red);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green=CrushChannelDepth(pixels[i].green);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue=CrushChannelDepth(pixels[i].blue);
+ break;
+ case MatteChannel:
+ case OpacityChannel:
+ if (image->colorspace == CMYKColorspace)
+ for (i=0; i < npixels; i++)
+ indexes[i]=CrushChannelDepth(indexes[i]);
+ else
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity=CrushChannelDepth(pixels[i].opacity);
+ break;
+ case BlackChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity=CrushChannelDepth(pixels[i].opacity);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=CrushChannelDepth(pixels[i].red);
+ pixels[i].green=CrushChannelDepth(pixels[i].green);
+ pixels[i].blue=CrushChannelDepth(pixels[i].blue);
+ if (image->colorspace == CMYKColorspace)
+ pixels[i].opacity=CrushChannelDepth(pixels[i].opacity);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity=CrushChannelDepth(intensity);
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+ }
+
+ return MagickPass;
+}
+static MagickPassFail
+QuantumDivideCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].red,/,context->double_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].green,/,context->double_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].blue,/,context->double_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].opacity,/,context->double_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ ApplyArithmeticOperator(pixels[i].red,/,context->double_value);
+ ApplyArithmeticOperator(pixels[i].green,/,context->double_value);
+ ApplyArithmeticOperator(pixels[i].blue,/,context->double_value);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ ApplyArithmeticOperator(intensity,/,context->double_value);
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+#if MaxRGB > MaxMap
+# define GammaAdjustQuantum(quantum) (MaxRGBDouble*pow(quantum/MaxRGBDouble,1.0/immutable_context->double_value)+0.5)
+#else
+# define GammaAdjustQuantum(quantum) (mutable_context->channel_lut[ScaleQuantumToMap(quantum)])
+#endif
+static MagickPassFail
+QuantumGammaCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ QuantumMutableContext
+ *mutable_context=(QuantumMutableContext *) mutable_data;
+
+ const QuantumImmutableContext
+ *immutable_context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ Build LUT for Q8 and Q16 builds
+ */
+#if MaxRGB <= MaxMap
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_QuantumGammaCB)
+# endif
+ if (mutable_context->channel_lut == (Quantum *) NULL)
+ {
+ mutable_context->channel_lut=MagickAllocateArray(Quantum *, MaxMap+1,sizeof(Quantum));
+ if (mutable_context->channel_lut == (Quantum *) NULL)
+ status=MagickFail;
+
+ if (mutable_context->channel_lut != (Quantum *) NULL)
+ {
+ for (i=0; i <= (long) MaxMap; i++)
+ mutable_context->channel_lut[i] =
+ ScaleMapToQuantum(MaxMap*pow((double) i/MaxMap,
+ 1.0/immutable_context->double_value));
+ }
+ }
+#else
+ ARG_NOT_USED(*mutable_context);
+#endif
+ if (MagickFail == status)
+ return status;
+
+ switch (immutable_context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red=GammaAdjustQuantum(pixels[i].red);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green=GammaAdjustQuantum(pixels[i].green);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue=GammaAdjustQuantum(pixels[i].blue);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity=GammaAdjustQuantum(pixels[i].opacity);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=GammaAdjustQuantum(pixels[i].red);
+ pixels[i].green=GammaAdjustQuantum(pixels[i].green);
+ pixels[i].blue=GammaAdjustQuantum(pixels[i].blue);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity = GammaAdjustQuantum(intensity);
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return status;
+}
+static MagickPassFail
+QuantumNegateCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red=MaxRGB-pixels[i].red;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green=MaxRGB-pixels[i].green;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue=MaxRGB-pixels[i].blue;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity=MaxRGB-pixels[i].opacity;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=MaxRGB-pixels[i].red;
+ pixels[i].green=MaxRGB-pixels[i].green;
+ pixels[i].blue=MaxRGB-pixels[i].blue;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity = MaxRGB-intensity;
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+/* log(quantum*value+1)/log(value+1) */
+#if MaxRGB > MaxMap
+# define LogAdjustQuantum(quantum) \
+ ((MaxRGBDouble*log((quantum/MaxRGBDouble)*immutable_context->double_value+1.0)/ \
+ log(immutable_context->double_value+1.0))+0.5)
+#else
+# define LogAdjustQuantum(quantum) (mutable_context->channel_lut[ScaleQuantumToMap(quantum)])
+#endif
+static MagickPassFail
+QuantumLogCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ QuantumMutableContext
+ *mutable_context=(QuantumMutableContext *) mutable_data;
+
+ const QuantumImmutableContext
+ *immutable_context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ Build LUT for Q8 and Q16 builds
+ */
+#if MaxRGB <= MaxMap
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_QuantumLogCB)
+# endif
+ if (mutable_context->channel_lut == (Quantum *) NULL)
+ {
+ mutable_context->channel_lut=MagickAllocateArray(Quantum *, MaxMap+1,sizeof(Quantum));
+ if (mutable_context->channel_lut == (Quantum *) NULL)
+ status=MagickFail;
+
+ if (mutable_context->channel_lut != (Quantum *) NULL)
+ {
+ for (i=0; i <= (long) MaxMap; i++)
+ {
+ double
+ value;
+
+ value=MaxRGBDouble*(log((ScaleMapToQuantum(i)/MaxRGBDouble)*
+ immutable_context->double_value+1.0)/
+ log(immutable_context->double_value+1.0));
+ mutable_context->channel_lut[i] = RoundDoubleToQuantum(value);
+ }
+ }
+ }
+#else
+ ARG_NOT_USED(*mutable_context);
+#endif
+ if (MagickFail == status)
+ return status;
+
+ switch (immutable_context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red=LogAdjustQuantum(pixels[i].red);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green=LogAdjustQuantum(pixels[i].green);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue=LogAdjustQuantum(pixels[i].blue);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity=LogAdjustQuantum(pixels[i].opacity);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=LogAdjustQuantum(pixels[i].red);
+ pixels[i].green=LogAdjustQuantum(pixels[i].green);
+ pixels[i].blue=LogAdjustQuantum(pixels[i].blue);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity = LogAdjustQuantum(intensity);
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return status;
+}
+static MagickPassFail
+QuantumLShiftCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red <<= context->quantum_value;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green <<= context->quantum_value;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue <<= context->quantum_value;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity <<= context->quantum_value;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red <<= context->quantum_value;
+ pixels[i].green <<= context->quantum_value;
+ pixels[i].blue <<= context->quantum_value;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity <<= context->quantum_value;
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+static MagickPassFail
+QuantumMaxCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ if (context->quantum_value > pixels[i].red)
+ pixels[i].red = context->quantum_value;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ if (context->quantum_value > pixels[i].green)
+ pixels[i].green = context->quantum_value;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ if (context->quantum_value > pixels[i].blue)
+ pixels[i].blue = context->quantum_value;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ if (context->quantum_value > pixels[i].opacity)
+ pixels[i].opacity = context->quantum_value;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ if (context->quantum_value > pixels[i].red)
+ pixels[i].red = context->quantum_value;
+ if (context->quantum_value > pixels[i].green)
+ pixels[i].green = context->quantum_value;
+ if (context->quantum_value > pixels[i].blue)
+ pixels[i].blue = context->quantum_value;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ if (context->quantum_value > intensity)
+ intensity = context->quantum_value;
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+static MagickPassFail
+QuantumMinCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ if (context->quantum_value < pixels[i].red)
+ pixels[i].red = context->quantum_value;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ if (context->quantum_value < pixels[i].green)
+ pixels[i].green = context->quantum_value;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ if (context->quantum_value < pixels[i].blue)
+ pixels[i].blue = context->quantum_value;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ if (context->quantum_value < pixels[i].opacity)
+ pixels[i].opacity = context->quantum_value;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ if (context->quantum_value < pixels[i].red)
+ pixels[i].red = context->quantum_value;
+ if (context->quantum_value < pixels[i].green)
+ pixels[i].green = context->quantum_value;
+ if (context->quantum_value < pixels[i].blue)
+ pixels[i].blue = context->quantum_value;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ if (context->quantum_value < intensity)
+ intensity = context->quantum_value;
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+static MagickPassFail
+QuantumMultiplyCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].red,*,context->double_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].green,*,context->double_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].blue,*,context->double_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].opacity,*,context->double_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ ApplyArithmeticOperator(pixels[i].red,*,context->double_value);
+ ApplyArithmeticOperator(pixels[i].green,*,context->double_value);
+ ApplyArithmeticOperator(pixels[i].blue,*,context->double_value);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ ApplyArithmeticOperator(intensity,*,context->double_value);
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+
+static inline Quantum
+GenerateQuantumNoise(const Quantum quantum,const NoiseType noise_type,
+ const double factor,MagickRandomKernel *kernel)
+{
+ double
+ value;
+
+ value = (double) quantum+
+ factor*GenerateDifferentialNoise((double) quantum,noise_type,kernel);
+ return RoundDoubleToQuantum(value);
+}
+
+static MagickPassFail
+QuantumNoiseCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception,
+ const NoiseType noise_type
+ )
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ double
+ factor;
+
+ MagickRandomKernel
+ *kernel;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ kernel=AcquireMagickRandomKernel();
+ factor=context->double_value/MaxRGBDouble;
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red = GenerateQuantumNoise(pixels[i].red,noise_type,factor,kernel);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green = GenerateQuantumNoise(pixels[i].green,noise_type,factor,kernel);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue = GenerateQuantumNoise(pixels[i].blue,noise_type,factor,kernel);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity = GenerateQuantumNoise(pixels[i].opacity,noise_type,factor,kernel);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red = GenerateQuantumNoise(pixels[i].red,noise_type,factor,kernel);
+ pixels[i].green = GenerateQuantumNoise(pixels[i].green,noise_type,factor,kernel);
+ pixels[i].blue = GenerateQuantumNoise(pixels[i].blue,noise_type,factor,kernel);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ pixels[i].red = pixels[i].green = pixels[i].blue =
+ GenerateQuantumNoise(intensity,noise_type,factor,kernel);
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+static MagickPassFail
+QuantumNoiseGaussianCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ return
+ QuantumNoiseCB(mutable_data,immutable_data,image,pixels,indexes,npixels,exception,GaussianNoise);
+}
+static MagickPassFail
+QuantumNoiseImpulseCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ return
+ QuantumNoiseCB(mutable_data,immutable_data,image,pixels,indexes,npixels,exception,ImpulseNoise);
+}
+static MagickPassFail
+QuantumNoiseLaplacianCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ return
+ QuantumNoiseCB(mutable_data,immutable_data,image,pixels,indexes,npixels,exception,LaplacianNoise);
+}
+static MagickPassFail
+QuantumNoiseMultiplicativeCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ return
+ QuantumNoiseCB(mutable_data,immutable_data,image,pixels,indexes,npixels,
+ exception,MultiplicativeGaussianNoise);
+}
+static MagickPassFail
+QuantumNoisePoissonCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ return
+ QuantumNoiseCB(mutable_data,immutable_data,image,pixels,indexes,npixels,exception,PoissonNoise);
+}
+
+
+static MagickPassFail
+QuantumNoiseRandomCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ return
+ QuantumNoiseCB(mutable_data,immutable_data,image,pixels,indexes,npixels,exception,RandomNoise);
+}
+
+static MagickPassFail
+QuantumNoiseUniformCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ return
+ QuantumNoiseCB(mutable_data,immutable_data,image,pixels,indexes,npixels,exception,UniformNoise);
+}
+static MagickPassFail
+QuantumOrCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red |= context->quantum_value;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green |= context->quantum_value;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue |= context->quantum_value;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity |= context->quantum_value;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red |= context->quantum_value;
+ pixels[i].green |= context->quantum_value;
+ pixels[i].blue |= context->quantum_value;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity |= context->quantum_value;
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+#if MaxRGB > MaxMap
+# define PowAdjustQuantum(quantum) (MaxRGBDouble*pow(quantum/MaxRGBDouble,immutable_context->double_value)+0.5)
+#else
+# define PowAdjustQuantum(quantum) (mutable_context->channel_lut[ScaleQuantumToMap(quantum)])
+#endif
+static MagickPassFail
+QuantumPowCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ QuantumMutableContext
+ *mutable_context=(QuantumMutableContext *) mutable_data;
+
+ const QuantumImmutableContext
+ *immutable_context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ /*
+ Build LUT for Q8 and Q16 builds
+ */
+#if MaxRGB <= MaxMap
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_QuantumPowCB)
+# endif
+ if (mutable_context->channel_lut == (Quantum *) NULL)
+ {
+ mutable_context->channel_lut=MagickAllocateArray(Quantum *, MaxMap+1,sizeof(Quantum));
+ if (mutable_context->channel_lut == (Quantum *) NULL)
+ status=MagickFail;
+
+ if (mutable_context->channel_lut != (Quantum *) NULL)
+ {
+ for (i=0; i <= (long) MaxMap; i++)
+ mutable_context->channel_lut[i] =
+ ScaleMapToQuantum(MaxMap*pow((double) i/MaxMap,
+ immutable_context->double_value));
+ }
+ }
+#else
+ ARG_NOT_USED(*mutable_context);
+#endif
+ if (MagickFail == status)
+ return status;
+
+ switch (immutable_context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red=PowAdjustQuantum(pixels[i].red);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green=PowAdjustQuantum(pixels[i].green);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue=PowAdjustQuantum(pixels[i].blue);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity=PowAdjustQuantum(pixels[i].opacity);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red=PowAdjustQuantum(pixels[i].red);
+ pixels[i].green=PowAdjustQuantum(pixels[i].green);
+ pixels[i].blue=PowAdjustQuantum(pixels[i].blue);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity = PowAdjustQuantum(intensity);
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return status;
+}
+static MagickPassFail
+QuantumRShiftCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red >>= context->quantum_value;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green >>= context->quantum_value;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue >>= context->quantum_value;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity >>= context->quantum_value;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red >>= context->quantum_value;
+ pixels[i].green >>= context->quantum_value;
+ pixels[i].blue >>= context->quantum_value;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity >>= context->quantum_value;
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+static MagickPassFail
+QuantumSubtractCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].red,-,context->double_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].green,-,context->double_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].blue,-,context->double_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ ApplyArithmeticOperator(pixels[i].opacity,-,context->double_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ ApplyArithmeticOperator(pixels[i].red,-,context->double_value);
+ ApplyArithmeticOperator(pixels[i].green,-,context->double_value);
+ ApplyArithmeticOperator(pixels[i].blue,-,context->double_value);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ ApplyArithmeticOperator(intensity,-,context->double_value);
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+
+ return (MagickPass);
+}
+
+static inline Quantum ApplyThresholdOperator(const Quantum quantum,
+ const Quantum threshold)
+{
+ Quantum
+ result;
+
+ if (quantum > threshold)
+ result=MaxRGB;
+ else
+ result=0U;
+
+ return result;
+}
+static MagickPassFail
+QuantumThresholdCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red = ApplyThresholdOperator(pixels[i].red,context->quantum_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green = ApplyThresholdOperator(pixels[i].green,context->quantum_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue = ApplyThresholdOperator(pixels[i].blue,context->quantum_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity = ApplyThresholdOperator(pixels[i].opacity,context->quantum_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ pixels[i].red = pixels[i].green = pixels[i].blue =
+ ApplyThresholdOperator(intensity,context->quantum_value);
+ }
+ break;
+ }
+ return (MagickPass);
+}
+
+static inline Quantum ApplyThresholdBlackOperator(const Quantum quantum,
+ const Quantum threshold)
+{
+ Quantum
+ result;
+
+ if (quantum < threshold)
+ result=0U;
+ else
+ result=quantum;
+
+ return result;
+}
+static MagickPassFail
+QuantumThresholdBlackCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red = ApplyThresholdBlackOperator(pixels[i].red,context->quantum_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green = ApplyThresholdBlackOperator(pixels[i].green,context->quantum_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue = ApplyThresholdBlackOperator(pixels[i].blue,context->quantum_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity = ApplyThresholdBlackOperator(pixels[i].opacity,context->quantum_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ /*
+ For the all-channels case we bend the rules a bit and only
+ threshold to black if the computed intensity of the color
+ channels is less than the threshold. This allows black
+ thresholding to work without causing a color shift. If
+ individual channels need to be thresholded, then per-channel
+ thresholding will be required for each channel to be
+ thresholded.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ if (0U == ApplyThresholdBlackOperator(intensity,context->quantum_value))
+ pixels[i].red=pixels[i].green=pixels[i].blue=0U;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ pixels[i].red = pixels[i].green = pixels[i].blue =
+ ApplyThresholdBlackOperator(intensity,context->quantum_value);
+ }
+ break;
+ }
+ return (MagickPass);
+}
+
+static inline Quantum ApplyThresholdWhiteOperator(const Quantum quantum,
+ const Quantum threshold)
+{
+ Quantum
+ result;
+
+ if (quantum > threshold)
+ result=MaxRGB;
+ else
+ result=quantum;
+
+ return result;
+}
+static MagickPassFail
+QuantumThresholdWhiteCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red = ApplyThresholdWhiteOperator(pixels[i].red,context->quantum_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green = ApplyThresholdWhiteOperator(pixels[i].green,context->quantum_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue = ApplyThresholdWhiteOperator(pixels[i].blue,context->quantum_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity = ApplyThresholdWhiteOperator(pixels[i].opacity,context->quantum_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ /*
+ For the all-channels case we bend the rules a bit and only
+ threshold to white if the computed intensity of the color
+ channels exceeds the threshold. This allows white
+ thresholding to work without causing a color shift. If
+ individual channels need to be thresholded, then per-channel
+ thresholding will be required for each channel to be
+ thresholded.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ if (MaxRGB == ApplyThresholdWhiteOperator(intensity,context->quantum_value))
+ pixels[i].red=pixels[i].green=pixels[i].blue=MaxRGB;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ pixels[i].red = pixels[i].green = pixels[i].blue =
+ ApplyThresholdWhiteOperator(intensity,context->quantum_value);
+ }
+ break;
+ }
+ return (MagickPass);
+}
+
+static inline Quantum ApplyThresholdBlackNegateOperator(const Quantum intensity,
+ const Quantum quantum,
+ const Quantum threshold)
+{
+ Quantum
+ result;
+
+ if (intensity < threshold)
+ result=MaxRGB;
+ else
+ result=quantum;
+
+ return result;
+}
+static MagickPassFail
+QuantumThresholdBlackNegateCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red = ApplyThresholdBlackNegateOperator(pixels[i].red,pixels[i].red,context->quantum_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green = ApplyThresholdBlackNegateOperator(pixels[i].green,pixels[i].green,context->quantum_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue = ApplyThresholdBlackNegateOperator(pixels[i].blue,pixels[i].blue,context->quantum_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity = ApplyThresholdBlackNegateOperator(pixels[i].opacity,pixels[i].opacity,context->quantum_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ /*
+ For the all-channels case we bend the rules a bit and only
+ threshold to black if the computed intensity of the color
+ channels is less than the threshold. This allows black
+ thresholding to work without causing a color shift. If
+ individual channels need to be thresholded, then per-channel
+ thresholding will be required for each channel to be
+ thresholded.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ pixels[i].red=ApplyThresholdBlackNegateOperator(intensity,pixels[i].red,context->quantum_value);
+ pixels[i].green=ApplyThresholdBlackNegateOperator(intensity,pixels[i].green,context->quantum_value);
+ pixels[i].blue=ApplyThresholdBlackNegateOperator(intensity,pixels[i].blue,context->quantum_value);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ pixels[i].red = pixels[i].green = pixels[i].blue =
+ ApplyThresholdBlackNegateOperator(intensity,intensity,context->quantum_value);
+ }
+ break;
+ }
+ return (MagickPass);
+}
+
+static inline Quantum ApplyThresholdWhiteNegateOperator(const Quantum intensity,
+ const Quantum quantum,
+ const Quantum threshold)
+{
+ Quantum
+ result;
+
+ if (intensity > threshold)
+ result=0U;
+ else
+ result=quantum;
+
+ return result;
+}
+static MagickPassFail
+QuantumThresholdWhiteNegateCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red = ApplyThresholdWhiteNegateOperator(pixels[i].red,pixels[i].red,context->quantum_value);
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green = ApplyThresholdWhiteNegateOperator(pixels[i].green,pixels[i].green,context->quantum_value);
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue = ApplyThresholdWhiteNegateOperator(pixels[i].blue,pixels[i].blue,context->quantum_value);
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity = ApplyThresholdWhiteNegateOperator(pixels[i].opacity,pixels[i].opacity,context->quantum_value);
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ /*
+ For the all-channels case we bend the rules a bit and only
+ threshold to white if the computed intensity of the color
+ channels exceeds the threshold. This allows white
+ thresholding to work without causing a color shift. If
+ individual channels need to be thresholded, then per-channel
+ thresholding will be required for each channel to be
+ thresholded.
+ */
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ pixels[i].red = ApplyThresholdWhiteNegateOperator(intensity,pixels[i].red,context->quantum_value);
+ pixels[i].green = ApplyThresholdWhiteNegateOperator(intensity,pixels[i].green,context->quantum_value);
+ pixels[i].blue = ApplyThresholdWhiteNegateOperator(intensity,pixels[i].blue,context->quantum_value);
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ pixels[i].red = pixels[i].green = pixels[i].blue =
+ ApplyThresholdWhiteNegateOperator(intensity,intensity,context->quantum_value);
+ }
+ break;
+ }
+ return (MagickPass);
+}
+
+static MagickPassFail
+QuantumXorCB(void *mutable_data,
+ const void *immutable_data,
+ Image *image,
+ PixelPacket *pixels,
+ IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ const QuantumImmutableContext
+ *context=(const QuantumImmutableContext *) immutable_data;
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ switch (context->channel)
+ {
+ case RedChannel:
+ case CyanChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].red ^= context->quantum_value;
+ break;
+ case GreenChannel:
+ case MagentaChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].green ^= context->quantum_value;
+ break;
+ case BlueChannel:
+ case YellowChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].blue ^= context->quantum_value;
+ break;
+ case BlackChannel:
+ case MatteChannel:
+ case OpacityChannel:
+ for (i=0; i < npixels; i++)
+ pixels[i].opacity ^= context->quantum_value;
+ break;
+ case UndefinedChannel:
+ case AllChannels:
+ for (i=0; i < npixels; i++)
+ {
+ pixels[i].red ^= context->quantum_value;
+ pixels[i].green ^= context->quantum_value;
+ pixels[i].blue ^= context->quantum_value;
+ }
+ break;
+ case GrayChannel:
+ for (i=0; i < npixels; i++)
+ {
+ Quantum
+ intensity;
+
+ intensity = PixelIntensity(&pixels[i]);
+ intensity ^= context->quantum_value;
+ pixels[i].red = pixels[i].green = pixels[i].blue = intensity;
+ }
+ break;
+ }
+ return (MagickPass);
+}
+MagickExport MagickPassFail
+QuantumOperatorRegionImage(Image *image,
+ const long x,const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ const ChannelType channel,
+ const QuantumOperator quantum_operator,
+ const double rvalue,
+ ExceptionInfo *exception)
+{
+ char
+ description[MaxTextExtent];
+
+ QuantumImmutableContext
+ immutable_context;
+
+ QuantumMutableContext
+ mutable_context;
+
+ MagickPassFail
+ status = MagickFail;
+
+ PixelIteratorMonoModifyCallback
+ call_back = 0;
+
+ image->storage_class=DirectClass;
+
+ immutable_context.channel=channel;
+ immutable_context.double_value=rvalue;
+ immutable_context.quantum_value=RoundDoubleToQuantum(rvalue);
+
+ mutable_context.channel_lut=(Quantum *) NULL;
+
+ switch (quantum_operator)
+ {
+ case UndefinedQuantumOp:
+ break;
+ case AddQuantumOp:
+ call_back=QuantumAddCB;
+ break;
+ case AndQuantumOp:
+ call_back=QuantumAndCB;
+ break;
+ case AssignQuantumOp:
+ call_back=QuantumAssignCB;
+ break;
+ case DivideQuantumOp:
+ call_back=QuantumDivideCB;
+ break;
+ case LShiftQuantumOp:
+ call_back=QuantumLShiftCB;
+ break;
+ case MultiplyQuantumOp:
+ call_back=QuantumMultiplyCB;
+ break;
+ case OrQuantumOp:
+ call_back=QuantumOrCB;
+ break;
+ case RShiftQuantumOp:
+ call_back=QuantumRShiftCB;
+ break;
+ case SubtractQuantumOp:
+ call_back=QuantumSubtractCB;
+ break;
+ case ThresholdQuantumOp:
+ call_back=QuantumThresholdCB;
+ break;
+ case ThresholdBlackQuantumOp:
+ call_back=QuantumThresholdBlackCB;
+ break;
+ case ThresholdWhiteQuantumOp:
+ call_back=QuantumThresholdWhiteCB;
+ break;
+ case ThresholdBlackNegateQuantumOp:
+ call_back=QuantumThresholdBlackNegateCB;
+ break;
+ case ThresholdWhiteNegateQuantumOp:
+ call_back=QuantumThresholdWhiteNegateCB;
+ break;
+ case XorQuantumOp:
+ call_back=QuantumXorCB;
+ break;
+ case NoiseGaussianQuantumOp:
+ call_back=QuantumNoiseGaussianCB;
+ break;
+ case NoiseImpulseQuantumOp:
+ call_back=QuantumNoiseImpulseCB;
+ break;
+ case NoiseLaplacianQuantumOp:
+ call_back=QuantumNoiseLaplacianCB;
+ break;
+ case NoiseMultiplicativeQuantumOp:
+ call_back=QuantumNoiseMultiplicativeCB;
+ break;
+ case NoisePoissonQuantumOp:
+ call_back=QuantumNoisePoissonCB;
+ break;
+ case NoiseUniformQuantumOp:
+ call_back=QuantumNoiseUniformCB;
+ break;
+ case NegateQuantumOp:
+ call_back=QuantumNegateCB;
+ break;
+ case GammaQuantumOp:
+ call_back=QuantumGammaCB;
+ break;
+ case DepthQuantumOp:
+ call_back=QuantumDepthCB;
+ break;
+ case LogQuantumOp:
+ call_back=QuantumLogCB;
+ break;
+ case MaxQuantumOp:
+ call_back=QuantumMaxCB;
+ break;
+ case MinQuantumOp:
+ call_back=QuantumMinCB;
+ break;
+ case PowQuantumOp:
+ call_back=QuantumPowCB;
+ break;
+ case NoiseRandomQuantumOp:
+ call_back=QuantumNoiseRandomCB;
+ break;
+ }
+
+ if (call_back)
+ {
+ FormatString(description,"[%%s] Apply operator '%s %g (%g%%%%)' to channel '%s'...",
+ QuantumOperatorToString(quantum_operator),rvalue,
+ ((rvalue/MaxRGBFloat)*100),
+ ChannelTypeToString(channel));
+ status=PixelIterateMonoModify(call_back,
+ NULL,
+ description,
+ &mutable_context,&immutable_context,x,y,columns,rows,
+ image,exception);
+
+ /*
+ Free any channel LUT.
+ */
+ MagickFreeMemory(mutable_context.channel_lut);
+
+ /*
+ If we are assigning all the color channels in the entire image
+ then set monochrome and grayscale flags.
+ */
+ if ((quantum_operator == AssignQuantumOp) &&
+ (channel == AllChannels) && (x == 0) && (y == 0) &&
+ (columns == image->columns) && (rows == image->rows))
+ {
+ image->is_monochrome=MagickTrue;
+ image->is_grayscale=MagickTrue;
+ }
+ }
+ return (status);
+}
diff --git a/magick/operator.h b/magick/operator.h
new file mode 100644
index 0000000..312eb35
--- /dev/null
+++ b/magick/operator.h
@@ -0,0 +1,84 @@
+/*
+% Copyright (C) 2004 - 2012 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% Interfaces to support quantum operators.
+% Written by Bob Friesenhahn, March 2004.
+%
+*/
+#ifndef _MAGICK_OPERATOR_H
+#define _MAGICK_OPERATOR_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+typedef enum
+{
+ UndefinedQuantumOp = 0,
+ AddQuantumOp, /* Add value */
+ AndQuantumOp, /* Bitwise AND value */
+ AssignQuantumOp, /* Direct value assignment */
+ DivideQuantumOp, /* Divide by value */
+ LShiftQuantumOp, /* Bitwise left-shift value N bits */
+ MultiplyQuantumOp, /* Multiply by value */
+ OrQuantumOp, /* Bitwise OR value */
+ RShiftQuantumOp, /* Bitwise right shift value */
+ SubtractQuantumOp, /* Subtract value */
+ ThresholdQuantumOp, /* Above threshold white, otherwise black */
+ ThresholdBlackQuantumOp, /* Below threshold is black */
+ ThresholdWhiteQuantumOp, /* Above threshold is white */
+ XorQuantumOp, /* Bitwise XOR value */
+ NoiseGaussianQuantumOp, /* Gaussian noise */
+ NoiseImpulseQuantumOp, /* Impulse noise */
+ NoiseLaplacianQuantumOp, /* Laplacian noise */
+ NoiseMultiplicativeQuantumOp, /* Multiplicative gaussian noise */
+ NoisePoissonQuantumOp, /* Poisson noise */
+ NoiseUniformQuantumOp, /* Uniform noise */
+ NegateQuantumOp, /* Negate (invert) channel, ignore value */
+ GammaQuantumOp, /* Adjust image gamma */
+ DepthQuantumOp, /* Adjust image depth */
+ /* Below added on 2008-12-13 */
+ LogQuantumOp, /* log(quantum*value+1)/log(value+1) */
+ MaxQuantumOp, /* Assign value if > quantum */
+ MinQuantumOp, /* Assign value if < quantum */
+ PowQuantumOp, /* Power function: pow(quantum,value) */
+ /* Below added on 2012-03-17 */
+ NoiseRandomQuantumOp, /* Random noise */
+ /* Below added on 2014-05-17 */
+ ThresholdBlackNegateQuantumOp, /* Below threshold is set to white */
+ ThresholdWhiteNegateQuantumOp /* Above threshold is set to black */
+
+ } QuantumOperator;
+
+extern MagickExport MagickPassFail
+ QuantumOperatorImage(Image *image,const ChannelType channel,
+ const QuantumOperator quantum_operator,const double rvalue,
+ ExceptionInfo *exception),
+ QuantumOperatorImageMultivalue(Image *image,
+ const QuantumOperator quantum_operator,
+ const char *values),
+ QuantumOperatorRegionImage(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ const ChannelType channel,const QuantumOperator quantum_operator,
+ const double rvalue,ExceptionInfo *exception);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/paint.c b/magick/paint.c
new file mode 100644
index 0000000..8f37362
--- /dev/null
+++ b/magick/paint.c
@@ -0,0 +1,815 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% PPPP AAA IIIII N N TTTTT %
+% P P A A I NN N T %
+% PPPP AAAAA I N N N T %
+% P A A I N NN T %
+% P A A IIIII N N T %
+% %
+% %
+% Methods to Paint on an Image %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1998 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/color.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/render.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define FuzzyOpacityMatch(color,target,fuzz) \
+ (((color)->opacity == (target)->opacity) && \
+ FuzzyColorMatch(color,target,fuzz))
+#define MaxStacksize (1 << 15)
+#define Push(up,left,right,delta) \
+ if ((s < (segment_stack+MaxStacksize)) && (((up)+(delta)) >= 0) && \
+ (((up)+(delta)) < (long) image->rows)) \
+ { \
+ s->y1=(up); \
+ s->x1=(left); \
+ s->x2=(right); \
+ s->y2=(delta); \
+ s++; \
+ }
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o l o r F l o o d f i l l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ColorFloodfill() changes the color value of any pixel that matches
+% target and is an immediate neighbor. If the method FillToBorderMethod is
+% specified, the color value is changed for any neighbor pixel that does not
+% match the bordercolor member of image.
+%
+% By default target must match a particular pixel color exactly.
+% However, in many cases two colors may differ by a small amount. The
+% fuzz member of image defines how much tolerance is acceptable to
+% consider two colors as the same. For example, set fuzz to 10 and the
+% color red at intensities of 100 and 102 respectively are now
+% interpreted as the same color for the purposes of the floodfill.
+%
+% The format of the ColorFloodfillImage method is:
+%
+% unsigned int ColorFloodfillImage(Image *image,const DrawInfo *draw_info,
+% const PixelPacket target,const long x_offset,const long y_offset,
+% const PaintMethod method)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o target: The RGB value of the target color.
+%
+% o x,y: The starting location of the operation.
+%
+% o method: Choose either FloodfillMethod or FillToBorderMethod.
+%
+%
+*/
+
+MagickExport MagickPassFail ColorFloodfillImage(Image *image,
+ const DrawInfo *draw_info,const PixelPacket target,const long x_offset,
+ const long y_offset,const PaintMethod method)
+{
+ Image
+ *pattern;
+
+ int
+ skip;
+
+ long
+ offset,
+ start,
+ x1,
+ x2,
+ y;
+
+ PixelPacket
+ color;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register SegmentInfo
+ *s;
+
+ SegmentInfo
+ *segment_stack;
+
+ unsigned char
+ *floodplane;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Check boundary conditions.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(draw_info != (DrawInfo *) NULL);
+ assert(draw_info->signature == MagickSignature);
+ if ((x_offset < 0) || (x_offset >= (long) image->columns))
+ return(MagickFail);
+ if ((y_offset < 0) || (y_offset >= (long) image->rows))
+ return(MagickFail);
+ /*
+ Set floodfill color.
+ */
+ if (FuzzyColorMatch(&draw_info->fill,&target,image->fuzz))
+ return(MagickFail);
+ floodplane=MagickAllocateMemory(unsigned char *,image->columns*image->rows);
+ segment_stack=MagickAllocateMemory(SegmentInfo *,MaxStacksize*sizeof(SegmentInfo));
+ if ((floodplane== (unsigned char *) NULL) ||
+ (segment_stack == (SegmentInfo *) NULL))
+ {
+ MagickFreeMemory(floodplane);
+ MagickFreeMemory(segment_stack);
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToFloodfillImage);
+ }
+ (void) memset(floodplane,False,image->columns*image->rows);
+ /*
+ Push initial segment on stack.
+ */
+ image->storage_class=DirectClass;
+ x=x_offset;
+ y=y_offset;
+ start=0;
+ s=segment_stack;
+ Push(y,x,x,1);
+ Push(y+1,x,x,-1);
+ while (s > segment_stack)
+ {
+ /*
+ Pop segment off stack.
+ */
+ s--;
+ x1=(long) s->x1;
+ x2=(long) s->x2;
+ offset=(long) s->y2;
+ y=(long) s->y1+offset;
+ /*
+ Recolor neighboring pixels.
+ */
+ q=GetImagePixels(image,0,y,x1+1,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ q+=x1;
+ for (x=x1; x >= 0; x--)
+ {
+ if (method == FloodfillMethod)
+ {
+ if (!FuzzyColorMatch(q,&target,image->fuzz))
+ break;
+ }
+ else
+ if (FuzzyColorMatch(q,&target,image->fuzz) ||
+ FuzzyColorMatch(q,&draw_info->fill,image->fuzz))
+ break;
+ floodplane[y*image->columns+x]=True;
+ *q=draw_info->fill;
+ q--;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ skip=x >= x1;
+ if (!skip)
+ {
+ start=x+1;
+ if (start < x1)
+ Push(y,start,x1-1,-offset);
+ x=x1+1;
+ }
+ do
+ {
+ if (!skip)
+ {
+ if (x < (long) image->columns)
+ {
+ q=GetImagePixels(image,x,y,image->columns-x,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for ( ; x < (long) image->columns; x++)
+ {
+ if (method == FloodfillMethod)
+ {
+ if (!FuzzyColorMatch(q,&target,image->fuzz))
+ break;
+ }
+ else
+ if (FuzzyColorMatch(q,&target,image->fuzz) ||
+ FuzzyColorMatch(q,&draw_info->fill,image->fuzz))
+ break;
+ floodplane[y*image->columns+x]=True;
+ *q=draw_info->fill;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ Push(y,start,x-1,offset);
+ if (x > (x2+1))
+ Push(y,x2+1,x-1,-offset);
+ }
+ skip=False;
+ x++;
+ if (x <= x2)
+ {
+ q=GetImagePixels(image,x,y,x2-x+1,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for ( ; x <= x2; x++)
+ {
+ if (method == FloodfillMethod)
+ {
+ if (FuzzyColorMatch(q,&target,image->fuzz))
+ break;
+ }
+ else
+ if (!FuzzyColorMatch(q,&target,image->fuzz) &&
+ !FuzzyColorMatch(q,&draw_info->fill,image->fuzz))
+ break;
+ q++;
+ }
+ }
+ start=x;
+ } while (x <= x2);
+ }
+ pattern=draw_info->fill_pattern;
+ if (pattern == (Image *) NULL)
+ for (y=0; y < (long) image->rows; y++)
+ {
+ /*
+ Tile fill color onto floodplane.
+ */
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (floodplane[y*image->columns+x])
+ *q=draw_info->fill;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ else
+ {
+ /*
+ Tile image onto floodplane.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (floodplane[y*image->columns+x])
+ {
+ (void) AcquireOnePixelByReference(pattern,&color,(long) ((unsigned long)
+ (x-pattern->tile_info.x) % pattern->columns),(long)
+ ((unsigned long) (y-pattern->tile_info.y) % pattern->rows),
+ &image->exception);
+ if (!pattern->matte)
+ color.opacity=OpaqueOpacity;
+ if (color.opacity != TransparentOpacity)
+ AlphaCompositePixel(q,&color,color.opacity,q,q->opacity);
+ }
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ }
+ MagickFreeMemory(segment_stack);
+ MagickFreeMemory(floodplane);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a t t e F l o o d f i l l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MatteFloodfill() changes the transparency value of any pixel that matches
+% target and is an immediate neighbor. If the method FillToBorderMethod
+% is specified, the transparency value is changed for any neighbor pixel
+% that does not match the bordercolor member of image.
+%
+% By default target must match a particular pixel transparency exactly.
+% However, in many cases two transparency values may differ by a
+% small amount. The fuzz member of image defines how much tolerance is
+% acceptable to consider two transparency values as the same. For example,
+% set fuzz to 10 and the opacity values of 100 and 102 respectively are
+% now interpreted as the same value for the purposes of the floodfill.
+%
+% The format of the MatteFloodfillImage method is:
+%
+% unsigned int MatteFloodfillImage(Image *image,const PixelPacket target,
+% const unsigned int opacity,const long x_offset,const long y_offset,
+% const PaintMethod method)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o target: The RGB value of the target color.
+%
+% o opacity: The level of transparency: 0 is fully opaque and MaxRGB is
+% fully transparent.
+%
+% o x,y: The starting location of the operation.
+%
+% o method: Choose either FloodfillMethod or FillToBorderMethod.
+%
+%
+*/
+MagickExport MagickPassFail MatteFloodfillImage(Image *image,
+ const PixelPacket target,const unsigned int opacity,const long x_offset,
+ const long y_offset,const PaintMethod method)
+{
+ int
+ skip;
+
+ long
+ offset,
+ start,
+ x1,
+ x2,
+ y;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ register SegmentInfo
+ *s;
+
+ SegmentInfo
+ *segment_stack;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Check boundary conditions.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if ((x_offset < 0) || (x_offset >= (long) image->columns))
+ return(MagickFail);
+ if ((y_offset < 0) || (y_offset >= (long) image->rows))
+ return(MagickFail);
+ if (target.opacity == opacity)
+ return(MagickFail);
+ q=GetImagePixels(image,x_offset,y_offset,1,1);
+ if (q == (PixelPacket *) NULL)
+ return(MagickFail);
+ if (q->opacity == opacity)
+ return(MagickFail);
+ /*
+ Allocate segment stack.
+ */
+ segment_stack=MagickAllocateMemory(SegmentInfo *,MaxStacksize*sizeof(SegmentInfo));
+ if (segment_stack == (SegmentInfo *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToFloodfillImage);
+ /*
+ Push initial segment on stack.
+ */
+ (void) SetImageType(image,TrueColorMatteType);
+ x=x_offset;
+ y=y_offset;
+ start=0;
+ s=segment_stack;
+ Push(y,x,x,1);
+ Push(y+1,x,x,-1);
+ while (s > segment_stack)
+ {
+ /*
+ Pop segment off stack.
+ */
+ s--;
+ x1=(long) s->x1;
+ x2=(long) s->x2;
+ offset=(long) s->y2;
+ y=(long) s->y1+offset;
+ /*
+ Recolor neighboring points.
+ */
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ q+=x1;
+ for (x=x1; x >= 0; x--)
+ {
+ if (method == FloodfillMethod)
+ {
+ if (!FuzzyOpacityMatch(q,&target,image->fuzz))
+ break;
+ }
+ else
+ if (FuzzyOpacityMatch(q,&target,image->fuzz) || (q->opacity == opacity))
+ break;
+ q->opacity=opacity;
+ q--;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ skip=x >= x1;
+ if (!skip)
+ {
+ start=x+1;
+ if (start < x1)
+ Push(y,start,x1-1,-offset);
+ x=x1+1;
+ }
+ do
+ {
+ if (!skip)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ q+=x;
+ for ( ; x < (long) image->columns; x++)
+ {
+ if (method == FloodfillMethod)
+ {
+ if (!FuzzyOpacityMatch(q,&target,image->fuzz))
+ break;
+ }
+ else
+ if (FuzzyOpacityMatch(q,&target,image->fuzz) ||
+ (q->opacity == opacity))
+ break;
+ q->opacity=opacity;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ Push(y,start,x-1,offset);
+ if (x > (x2+1))
+ Push(y,x2+1,x-1,-offset);
+ }
+ skip=False;
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ q+=x;
+ for (x++; x <= x2; x++)
+ {
+ q++;
+ if (method == FloodfillMethod)
+ {
+ if (FuzzyOpacityMatch(q,&target,image->fuzz))
+ break;
+ }
+ else
+ if (!FuzzyOpacityMatch(q,&target,image->fuzz) &&
+ (q->opacity != opacity))
+ break;
+ }
+ start=x;
+ } while (x <= x2);
+ }
+ MagickFreeMemory(segment_stack);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% O p a q u e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% OpaqueImage() changes any pixel that matches color with the color
+% defined by fill.
+%
+% By default color must match a particular pixel color exactly. However,
+% in many cases two colors may differ by a small amount. Fuzz defines
+% how much tolerance is acceptable to consider two colors as the same.
+% For example, set fuzz to 10 and the color red at intensities of 100 and
+% 102 respectively are now interpreted as the same color.
+%
+% The format of the OpaqueImage method is:
+%
+% unsigned int OpaqueImage(Image *image,const PixelPacket target,
+% const PixelPacket fill)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o target: The RGB value of the target color.
+%
+% o fill: The replacement color.
+%
+%
+*/
+typedef struct _OpaqueImageOptions_t
+{
+ double fuzz;
+ PixelPacket fill;
+ PixelPacket target;
+} OpaqueImageOptions_t;
+static MagickPassFail
+OpaqueImageCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ const OpaqueImageOptions_t
+ options = *((const OpaqueImageOptions_t *) immutable_data);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ if (options.fuzz == 0.0)
+ {
+ for (i=0; i < npixels; i++)
+ {
+ if (ColorMatch(&pixels[i],&options.target))
+ pixels[i]=options.fill;
+ }
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ {
+ if (FuzzyColorMatch(&pixels[i],&options.target,options.fuzz))
+ pixels[i]=options.fill;
+ }
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail
+OpaqueImage(Image *image,const PixelPacket target,const PixelPacket fill)
+{
+#define OpaqueImageText "[%s] Setting opaque color..."
+
+ OpaqueImageOptions_t
+ options;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Make image color opaque.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ options.fuzz=image->fuzz;
+ options.fill=fill;
+ options.target=target;
+ if (image->storage_class == PseudoClass)
+ {
+ assert(image->colormap != (PixelPacket *) NULL);
+ (void) OpaqueImageCallBack(0,&options,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status &= SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(OpaqueImageCallBack,NULL,
+ OpaqueImageText,NULL,&options,0,0,
+ image->columns,image->rows,
+ image,&image->exception);
+ }
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% T r a n s p a r e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TransparentImage() changes the opacity value associated with any pixel
+% that matches color to the value defined by opacity.
+%
+% By default color must match a particular pixel color exactly. However,
+% in many cases two colors may differ by a small amount. Fuzz defines
+% how much tolerance is acceptable to consider two colors as the same.
+% For example, set fuzz to 10 and the color red at intensities of 100 and
+% 102 respectively are now interpreted as the same color.
+%
+% The format of the TransparentImage method is:
+%
+% unsigned int TransparentImage(Image *image,const PixelPacket target,
+% const unsigned int opacity)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o target: The RGB value of the target color.
+%
+% o opacity: The replacement opacity value.
+%
+%
+*/
+typedef struct _TransparentImageOptions_t
+{
+ double fuzz;
+ PixelPacket target;
+ unsigned int opacity;
+} TransparentImageOptions_t;
+static MagickPassFail
+TransparentImageCallBack(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ const TransparentImageOptions_t
+ options = *((const TransparentImageOptions_t *) immutable_data);
+
+ const MagickBool
+ clear_matte = (!image->matte);
+
+ register long
+ i;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ if (options.fuzz == 0.0)
+ {
+ for (i=0; i < npixels; i++)
+ {
+ if (ColorMatch(&pixels[i],&options.target))
+ pixels[i].opacity=options.opacity;
+ else if (clear_matte)
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ }
+ else
+ {
+ for (i=0; i < npixels; i++)
+ {
+ if (FuzzyColorMatch(&pixels[i],&options.target,options.fuzz))
+ pixels[i].opacity=options.opacity;
+ else if (clear_matte)
+ pixels[i].opacity=OpaqueOpacity;
+ }
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail
+TransparentImage(Image *image,const PixelPacket target,
+ const unsigned int opacity)
+{
+#define TransparentImageText "[%s] Setting transparent color... "
+
+ TransparentImageOptions_t
+ options;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Make image color transparent.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ options.fuzz=image->fuzz;
+ options.opacity=opacity;
+ options.target=target;
+ if (image->storage_class == PseudoClass)
+ {
+ assert(image->colormap != (PixelPacket *) NULL);
+ (void) TransparentImageCallBack(0,&options,image,image->colormap,
+ (IndexPacket *) NULL,image->colors,
+ &image->exception);
+ status &= SyncImage(image);
+ }
+ else
+ {
+ status=PixelIterateMonoModify(TransparentImageCallBack,NULL,
+ TransparentImageText,NULL,&options,0,0,
+ image->columns,image->rows,
+ image,&image->exception);
+ }
+ image->matte=MagickTrue;
+
+ return(status);
+}
diff --git a/magick/paint.h b/magick/paint.h
new file mode 100644
index 0000000..0e83104
--- /dev/null
+++ b/magick/paint.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Image Paint Methods.
+*/
+#ifndef _MAGICK_PAINT_H
+#define _MAGICK_PAINT_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "magick/render.h"
+
+extern MagickExport unsigned int
+ ColorFloodfillImage(Image *,const DrawInfo *,const PixelPacket,const long,
+ const long,const PaintMethod),
+ MatteFloodfillImage(Image *,const PixelPacket,const unsigned int,const long,
+ const long,const PaintMethod);
+
+extern MagickExport unsigned int
+ OpaqueImage(Image *,const PixelPacket,const PixelPacket),
+ TransparentImage(Image *,const PixelPacket,const unsigned int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/pixel_cache.c b/magick/pixel_cache.c
new file mode 100644
index 0000000..3e753fd
--- /dev/null
+++ b/magick/pixel_cache.c
@@ -0,0 +1,4788 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% GraphicsMagick Pixel Cache Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1999 %
+% Re-Designed %
+% Bob Friesenhahn %
+% October 2008 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/blob.h"
+#include "magick/constitute.h"
+#include "magick/list.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/resource.h"
+#include "magick/pixel_cache.h"
+#include "magick/semaphore.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+#if defined(HasZLIB)
+#include "zlib.h"
+#endif
+
+/*
+ Define declarations.
+*/
+/* Maximum read/write size. Should be no more than INT_MAX */
+#define MAGICK_IO_MAX INT_MAX
+
+#if defined(POSIX) && defined(S_IRUSR)
+# define S_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
+#elif defined (MSWINDOWS)
+# define S_MODE (_S_IREAD | _S_IWRITE)
+#else
+# define S_MODE 0644
+#endif
+
+/*
+ Windows open extensions
+*/
+#if defined(__BORLANDC__)
+/* These do not appear to work with Borland C++ */
+# undef _O_RANDOM
+# undef _O_SEQUENTIAL
+# undef _O_SHORT_LIVED
+# undef _O_TEMPORARY
+#endif
+
+#if !defined(_O_RANDOM)
+# define _O_RANDOM 0
+#endif
+#if !defined(_O_SEQUENTIAL)
+# define _O_SEQUENTIAL 0
+#endif
+#if !defined(_O_SHORT_LIVED)
+# define _O_SHORT_LIVED 0
+#endif
+#if !defined(_O_TEMPORARY)
+# define _O_TEMPORARY 0
+#endif
+
+
+/*
+ Declare pixel cache interfaces.
+*/
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ typedef magick_off_t pixel_off_t;
+
+ /*
+ Read only access to a linear pixel region.
+ */
+ MagickExport const PixelPacket
+ *AcquireImagePixelsDirect(const Image *image,
+ const pixel_off_t offset,
+ const unsigned long length,
+ ExceptionInfo *exception);
+
+ /*
+ Read/write access to a linear pixel region (existing data read and
+ updated).
+ */
+ extern MagickExport PixelPacket
+ *GetImagePixelsDirect(Image *image,
+ const pixel_off_t offset,
+ const unsigned long length,
+ ExceptionInfo *exception);
+
+ /*
+ Write access to a linear pixel region (existing data ignored).
+ */
+ extern MagickExport PixelPacket
+ *SetImagePixelsDirect(Image *image,
+ const pixel_off_t offset,
+ const unsigned long length,
+ ExceptionInfo *exception);
+
+
+/*
+ Enum declaractions.
+*/
+typedef enum
+{
+ UndefinedCache, /* Cache is not opened */
+ PingCache, /* Cache is ignored */
+ MemoryCache, /* Cache is a heap memory allocation */
+ DiskCache, /* Cache is a file accessed via read/write */
+ MapCache /* Cache is a file accessed via memory map */
+} CacheType;
+
+/*
+ CacheInfo represents the underlying raster image.
+*/
+typedef struct _CacheInfo
+{
+ /* Image width */
+ unsigned long columns;
+
+ /* Image height */
+ unsigned long rows;
+
+ /* Offset to pixels in cache file */
+ magick_off_t offset;
+
+ /* Length of pixels region */
+ magick_off_t length;
+
+ /* Image pixels if memory resident */
+ PixelPacket *pixels;
+
+ /* Image indexes if memory resident */
+ IndexPacket *indexes;
+
+ /* Ping, Memory, Disk, Map */
+ CacheType type;
+
+ /* Image indexes are valid */
+ MagickBool indexes_valid;
+
+ /* The number of Image structures referencing this cache */
+ long reference_count;
+
+ /* True if cache is read only */
+ MagickBool read_only;
+
+ /* Lock for updating reference count */
+ SemaphoreInfo *reference_semaphore;
+
+ /* Lock for file I/O access */
+ SemaphoreInfo *file_semaphore;
+
+ /* DirectClass/PseudoClass */
+ ClassType storage_class;
+
+ /* CMYKColorspace special due to indexes */
+ ColorspaceType colorspace;
+
+ /* Method for dealing with pixels requested outside the image
+ boundaries. */
+ VirtualPixelMethod virtual_pixel_method;
+
+ /* Open file handle for disk cache */
+ int file;
+
+ /* Image file name in form "filename[index]" (for use in logging) */
+ char filename[MaxTextExtent];
+
+ /* Pixel cache file name */
+ char cache_filename[MaxTextExtent];
+
+ /* Unique number for structure validation */
+ unsigned long signature;
+} CacheInfo;
+
+/*
+ NexusInfo represents a selected region of pixels.
+*/
+typedef struct _NexusInfo
+{
+ /* Points to staging or cache_info->pixels+offset */
+ PixelPacket *pixels;
+
+ /* Points into staging or cache_info->indexes+offset */
+ IndexPacket *indexes;
+
+ /* Allocated copy of pixel data appended by indexes */
+ PixelPacket *staging;
+
+ /* Allocation size (in bytes) of pixel staging area */
+ size_t staging_length;
+
+ /* Selected region (width, height, x, y) */
+ RectangleInfo region;
+
+ /* Nexus pixels are non-strided and in core */
+ MagickBool in_core;
+
+#if 0
+ /* FIXME, use: Region starting offset in pixels */
+ /* offset=nexus_info->region.y*(magick_off_t) cache_info->columns+nexus_info->region.x */
+ magick_off_t region_offset;
+
+ /* FIXME, use: Region linear length in pixels */
+ /* length=(nexus_info->region.height-1)*cache_info->columns+nexus_info->region.width-1 */
+ magick_uint64_t region_length;
+
+ /* FIXME, use: Pixels are accessed linearly (rather than as a rectangle) */
+ MagickBool direct_flag;
+#endif
+
+ /* Unique number for structure validation */
+ unsigned long signature;
+} NexusInfo;
+
+/*
+ View is a handle for a cache nexus as well as remembering which
+ image it was allocated from.
+*/
+typedef struct _View
+{
+ /* Image that view was allocated from */
+ Image *image;
+
+ /* View data */
+ NexusInfo *nexus_info;
+
+ /* Validation signature */
+ unsigned long signature;
+} View;
+
+/*
+ A vector of thread views.
+*/
+typedef struct _ThreadViewSet
+{
+ ViewInfo
+ *views;
+
+ unsigned int
+ nviews;
+} ThreadViewSet;
+
+static const PixelPacket
+ *AcquireCacheNexus(const Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,NexusInfo *nexus_info,
+ ExceptionInfo *exception);
+
+static MagickPassFail
+ OpenCache(Image *image,const MapMode mode,ExceptionInfo *exception),
+ SyncCacheNexus(Image *image,const NexusInfo *nexus_info,ExceptionInfo *exception);
+
+static NexusInfo
+ *AllocateCacheNexus(void);
+
+static void
+ DestroyCacheNexus(NexusInfo *nexus_info);
+
+/*
+ Cache view interfaces.
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+/*
+ Forward declaration.
+*/
+static PixelPacket
+ *GetCacheNexus(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ NexusInfo *nexus_info,ExceptionInfo *exception),
+ *SetCacheNexus(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ NexusInfo *nexus_info,ExceptionInfo *exception),
+ *SetNexus(const Image *image,const RectangleInfo *region,
+ NexusInfo *nexus_info,ExceptionInfo *exception);
+
+static MagickPassFail
+ ReadCacheIndexes(const Cache cache,const NexusInfo *nexus_info,ExceptionInfo *exception),
+ ReadCachePixels(const Cache cache,const NexusInfo *nexus_info,ExceptionInfo *exception),
+ WriteCacheIndexes(Cache cache,const NexusInfo *nexus_info),
+ WriteCachePixels(Cache cache,const NexusInfo *nexus_info);
+
+/*
+
+ Read data into buffer 'buffer', with size 'length', from file
+ descriptor 'file' at offset 'offset'. Care is taken to make sure
+ that all data requested is read if system calls are interrupted by
+ signals.
+
+*/
+static ssize_t
+FilePositionRead(int file, void *buffer, size_t length,magick_off_t offset)
+{
+ register ssize_t
+ count=0;
+
+ register size_t
+ total_count;
+
+ MAGICK_POSIX_IO_SIZE_T
+ io_size;
+
+#if !HAVE_PREAD
+ if ((MagickSeek(file,offset,SEEK_SET)) < 0)
+ return (ssize_t)-1;
+#endif
+
+ for (total_count=0; total_count < length; total_count+=count)
+ {
+ char
+ *io_buff_address;
+
+ size_t
+ requested_io_size;
+
+#if HAVE_PREAD
+ off_t
+ io_file_offset;
+#endif
+
+ requested_io_size=length-total_count;
+ io_buff_address=(char *) buffer+total_count;
+ if (requested_io_size > MAGICK_IO_MAX)
+ io_size=MAGICK_IO_MAX;
+ else
+ io_size=(MAGICK_POSIX_IO_SIZE_T) requested_io_size;
+#if HAVE_PREAD
+ io_file_offset=offset+total_count;
+ count=pread(file,io_buff_address,io_size,io_file_offset);
+#else
+ count=read(file,io_buff_address,io_size);
+#endif
+ if (count <= 0)
+ break;
+ }
+ if (count < 0)
+ return (ssize_t)-1;
+ return (ssize_t) total_count;
+}
+/*
+
+ Write data pointed to by 'buffer', with size 'length', to file
+ descriptor 'file' at specified offset 'offset'. Care is taken to
+ make sure that all data is written if system calls are interrupted
+ by signals.
+
+*/
+static ssize_t
+FilePositionWrite(int file, const void *buffer,size_t length,magick_off_t offset)
+{
+ register ssize_t
+ count=0;
+
+ register size_t
+ total_count;
+
+ MAGICK_POSIX_IO_SIZE_T
+ io_size;
+
+#if !HAVE_PWRITE
+ if ((MagickSeek(file,offset,SEEK_SET)) < 0)
+ return (ssize_t)-1;
+#endif /* !HAVE_PWRITE */
+ for (total_count=0; total_count < length; total_count+=count)
+ {
+ char
+ *io_buff_address;
+
+ size_t
+ requested_io_size;
+
+#if HAVE_PWRITE
+ off_t
+ io_file_offset;
+#endif
+
+ io_buff_address=(char *) buffer+total_count;
+ requested_io_size=length-total_count;
+ if (requested_io_size > MAGICK_IO_MAX)
+ io_size=MAGICK_IO_MAX;
+ else
+ io_size=(MAGICK_POSIX_IO_SIZE_T) requested_io_size;
+#if HAVE_PWRITE
+ io_file_offset=offset+total_count;
+ count=pwrite(file,io_buff_address,io_size,io_file_offset);
+#else
+ count=write(file,io_buff_address,io_size);
+#endif
+ if (count <= 0)
+ break;
+ }
+ if (count < 0)
+ return (ssize_t)-1;
+ return (ssize_t) total_count;
+}
+
+MagickExport void
+DestroyThreadViewSet(ThreadViewSet *view_set)
+{
+ unsigned int
+ i;
+
+ if (view_set != (ThreadViewSet *) NULL)
+ {
+ if (view_set->views != (ViewInfo *) NULL)
+ {
+ for (i=0; i < view_set->nviews; i++)
+ {
+ if (view_set->views[i] != (ViewInfo *) NULL)
+ {
+ CloseCacheView(view_set->views[i]);
+ view_set->views[i]=(ViewInfo *) NULL;
+ }
+ }
+ }
+ view_set->nviews=0;
+ MagickFreeAlignedMemory(view_set->views);
+ MagickFreeAlignedMemory(view_set);
+ }
+}
+MagickExport ThreadViewSet *
+AllocateThreadViewSet(Image *image,ExceptionInfo *exception)
+{
+ ThreadViewSet
+ *view_set;
+
+ unsigned int
+ i;
+
+ MagickPassFail
+ status=MagickPass;
+
+ view_set=MagickAllocateAlignedMemory(ThreadViewSet *,MAGICK_CACHE_LINE_SIZE,
+ sizeof(ThreadViewSet));
+ if (view_set == (ThreadViewSet *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateCacheView);
+ view_set->nviews=omp_get_max_threads();
+ view_set->views=MagickAllocateAlignedMemory(ViewInfo *,MAGICK_CACHE_LINE_SIZE,
+ view_set->nviews*sizeof(ViewInfo *));
+ if (view_set->views == (ViewInfo *) NULL)
+ {
+ ThrowException(exception,CacheError,UnableToAllocateCacheView,
+ image->filename);
+ status=MagickFail;
+ }
+
+ if (view_set->views != (ViewInfo *) NULL)
+ for (i=0; i < view_set->nviews; i++)
+ {
+ view_set->views[i]=OpenCacheView(image);
+ if (view_set->views[i] == (ViewInfo *) NULL)
+ {
+ ThrowException(exception,CacheError,UnableToAllocateCacheView,
+ image->filename);
+ status=MagickFail;
+ }
+ }
+
+ if (status == MagickFail)
+ {
+ DestroyThreadViewSet(view_set);
+ view_set=(ThreadViewSet *) NULL;
+ }
+
+ return view_set;
+}
+
+/*
+ Obtain the view corresponding to the current thread from the thread
+ view set. The compiler should normally automatically inline this
+ function when used in this module. Since we don't trust that, we
+ also provide a static inlined version along with a macro to remap
+ code from this module to use the inline version.
+*/
+MagickExport ViewInfo
+*AccessDefaultCacheView(const Image *image)
+{
+ return image->default_views->views[omp_get_thread_num()];
+}
+static inline ViewInfo
+*AccessDefaultCacheViewInlined(const Image *image)
+{
+ return image->default_views->views[omp_get_thread_num()];
+}
+#if !defined(AccessDefaultCacheView)
+# define AccessDefaultCacheView(image) AccessDefaultCacheViewInlined(image)
+#endif
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I s N e x u s I n C o r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsNexusInCore() returns true if the pixels associated with the specified
+% cache nexus is non-strided and in core.
+%
+% The format of the IsNexusInCore() method is:
+%
+% MagickPassFail IsNexusInCore(const Cache cache,
+% const NexusInfo *nexus_info)
+%
+% A description of each parameter follows:
+%
+% o status: IsNexusInCore() returns MagickPass if the pixels are
+% non-strided and in core, otherwise MagickFail.
+%
+% o cache: Specifies the pixel cache to use.
+%
+% o nexus_info: specifies cache nexus to test.
+%
+%
+*/
+static inline MagickPassFail
+IsNexusInCore(const CacheInfo *cache_info,const NexusInfo *nexus_info)
+{
+ MagickPassFail
+ status=MagickFail;
+
+ if (cache_info->type == PingCache)
+ {
+ /*
+ Some coders *do* read the pixels in 'ping' mode. Skip sync on
+ such pixels.
+ */
+ status=MagickPass;
+ }
+ else
+ {
+ magick_off_t
+ offset;
+
+ offset=nexus_info->region.y*
+ (magick_off_t) cache_info->columns+nexus_info->region.x;
+ if (nexus_info->pixels == (cache_info->pixels+offset))
+ status=MagickPass;
+ }
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c c e s s C a c h e V i e w P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method AccessCacheViewPixels returns writeable pixels associated with
+% the specified view.
+%
+% The format of the AccessCacheViewPixels method is:
+%
+% PixelPacket *AccessCacheViewPixels(const ViewInfo *view)
+%
+% A description of each parameter follows:
+%
+% o indexes: Method AccessCacheViewPixels returns the pixels associated with
+% the specified view.
+%
+% o view: The address of a structure of type ViewInfo.
+%
+%
+*/
+MagickExport PixelPacket *
+AccessCacheViewPixels(const ViewInfo *view)
+{
+ const View
+ * restrict view_info = (const View *) view;
+
+ assert(view_info != (View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ return view_info->nexus_info->pixels;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c c e s s I m m u t a b l e I n d e x e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AccessImmutableIndexes() returns the colormap indexes associated with
+% the last call to AcquireImagePixels(). NULL is returned if colormap
+% indexes are not available.
+%
+% The format of the AccessImmutableIndexes() method is:
+%
+% const IndexPacket *AccessImmutableIndexes(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o indexes: The indexes associated with the last call to
+% AcquireImagePixels().
+%
+% o image: The image.
+%
+%
+*/
+MagickExport const IndexPacket *
+AccessImmutableIndexes(const Image *image)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return GetCacheViewIndexes(AccessDefaultCacheView(image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c c e s s M u t a b l e I n d e x e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AccessMutableIndexes() returns the colormap indexes associated with
+% the last call to SetImagePixels() or GetImagePixels(). NULL is returned
+% if colormap indexes are not available.
+%
+% The format of the AccessMutagleIndexes() method is:
+%
+% IndexPacket *AccessMutableIndexes(Image *image)
+%
+% A description of each parameter follows:
+%
+% o indexes: The indexes associated with the last call to
+% AcquireImagePixels().
+%
+% o image: The image.
+%
+%
+*/
+MagickExport IndexPacket *
+AccessMutableIndexes(Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return GetCacheViewIndexes(AccessDefaultCacheView(image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c c e s s M u t a b l e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AccessMutablePixels() returns the pixels associated with the last call to
+% SetImagePixels() or GetImagePixels(). This is useful in order to access
+% an already selected region without passing the geometry of the region.
+%
+% The format of the GetPixels() method is:
+%
+% PixelPacket *AccessMutablePixels(Image image)
+%
+% A description of each parameter follows:
+%
+% o pixels: The pixels associated with the last call to SetImagePixels()
+% or GetImagePixels().
+%
+% o image: The image.
+%
+%
+*/
+MagickExport PixelPacket *
+AccessMutablePixels(Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return AccessCacheViewPixels(AccessDefaultCacheView(image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ A c q u i r e C a c h e N e x u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireCacheNexus() acquires pixels from the in-memory or disk pixel cache
+% as defined by the geometry parameters. A pointer to the pixels is
+% returned if the pixels are transferred, otherwise a NULL is returned.
+%
+% The format of the AcquireCacheNexus() method is:
+%
+% PixelPacket *AcquireCacheNexus(const Image *image,const long x,
+% const long y,const unsigned long columns,const unsigned long rows,
+% NexusInfo *nexus_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: AcquireCacheNexus() returns a pointer to the pixels if they
+% are transferred, otherwise a NULL is returned.
+%
+% o image: The image.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o nexus: specifies which cache nexus to acquire.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#define EdgeX(x) ((x) < 0 ? 0 : (x) >= (long) cache_info->columns ? \
+ (long) cache_info->columns-1 : (x))
+#define EdgeY(y) ((y) < 0 ? 0 : (y) >= (long) cache_info->rows ? \
+ (long) cache_info->rows-1 : (y))
+#define MirrorX(x) ((((x) >= 0) && (x) < (long) cache_info->columns) ? \
+ (x) : (long) cache_info->columns-TileX(x)-1L)
+#define MirrorY(y) ((((y) >= 0) && (y) < (long) cache_info->rows) ? \
+ (y) : (long) cache_info->rows-TileY(y)-1L)
+#define TileX(x) (((x) >= 0) ? ((x) % (long) cache_info->columns) : \
+ (long) cache_info->columns-(-(x) % (long) cache_info->columns))
+#define TileY(y) (((y) >= 0) ? ((y) % (long) cache_info->rows) : \
+ (long) cache_info->rows-(-(y) % (long) cache_info->rows))
+
+static const PixelPacket *
+AcquireCacheNexus(const Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ NexusInfo *nexus_info,ExceptionInfo *exception)
+{
+ CacheInfo
+ * restrict cache_info;
+
+ magick_uint64_t
+ number_pixels;
+
+ magick_off_t
+ offset;
+
+ IndexPacket
+ * restrict indexes,
+ * restrict nexus_indexes;
+
+ PixelPacket
+ * restrict pixels,
+ virtual_pixel;
+
+ RectangleInfo
+ region;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ u,
+ v;
+
+ register PixelPacket
+ *q;
+
+ size_t
+ length;
+
+ NexusInfo
+ * restrict image_nexus;
+
+ /*
+ Acquire pixels.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->cache != (Cache) NULL);
+ cache_info=(CacheInfo *) image->cache;
+ if (cache_info->type == UndefinedCache)
+ {
+ ThrowException(exception,CacheError,PixelCacheIsNotOpen,
+ image->filename);
+ return((const PixelPacket *) NULL);
+ }
+ region.x=x;
+ region.y=y;
+ region.width=columns;
+ region.height=rows;
+ pixels=SetNexus(image,&region,nexus_info,exception);
+ if (pixels == (PixelPacket *) NULL)
+ return((const PixelPacket *) NULL);
+ offset=region.y*(magick_off_t) cache_info->columns+region.x;
+ length=(region.height-1)*cache_info->columns+region.width-1;
+ number_pixels=(magick_uint64_t) cache_info->columns*cache_info->rows;
+ if ((offset >= 0) && (((magick_uint64_t) offset+length) < number_pixels))
+ if ((x >= 0) && ((x+columns) <= cache_info->columns) &&
+ (y >= 0) && ((y+rows) <= cache_info->rows))
+ {
+ /*
+ Pixel request is inside cache extents.
+ */
+ if (!nexus_info->in_core)
+ {
+ MagickPassFail
+ status;
+
+ status=ReadCachePixels(cache_info,nexus_info,exception);
+ if (cache_info->indexes_valid)
+ status &= ReadCacheIndexes(cache_info,nexus_info,exception);
+ if (status == MagickFail)
+ {
+ ThrowException(exception,CacheError,UnableToReadPixelCache,
+ image->filename);
+ pixels = (PixelPacket *) NULL;
+ }
+ }
+ return(pixels);
+ }
+ /*
+ Pixel request is outside cache extents.
+ */
+ indexes=nexus_info->indexes;
+ image_nexus=AllocateCacheNexus();
+ if (image_nexus == (NexusInfo *) NULL)
+ {
+ ThrowException(exception,CacheError,UnableToGetCacheNexus,
+ image->filename);
+ return((const PixelPacket *) NULL);
+ }
+ virtual_pixel=image->background_color;
+ q=pixels;
+ for (v=0; v < (long) rows; v++)
+ {
+ for (u=0; u < (long) columns; u+=(long) length)
+ {
+ length=Min(cache_info->columns-(x+u),columns-u);
+ if ((((x+u) < 0) || ((x+u) >= (long) cache_info->columns)) ||
+ (((y+v) < 0) || ((y+v) >= (long) cache_info->rows)) || (length == 0))
+ {
+ /*
+ Transfer a single pixel.
+ */
+ length=1;
+ p=(const PixelPacket *) NULL;
+ switch (cache_info->virtual_pixel_method)
+ {
+ case ConstantVirtualPixelMethod:
+ {
+ (void) AcquireCacheNexus(image,EdgeX(x+u),EdgeY(y+v),1,1,
+ image_nexus,exception);
+ p=(&virtual_pixel);
+ break;
+ }
+ case EdgeVirtualPixelMethod:
+ default:
+ {
+ p=AcquireCacheNexus(image,EdgeX(x+u),EdgeY(y+v),1,1,
+ image_nexus,exception);
+ break;
+ }
+ case MirrorVirtualPixelMethod:
+ {
+ p=AcquireCacheNexus(image,MirrorX(x+u),MirrorY(y+v),1,1,
+ image_nexus,exception);
+ break;
+ }
+ case TileVirtualPixelMethod:
+ {
+ p=AcquireCacheNexus(image,TileX(x+u),TileY(y+v),1,1,
+ image_nexus,exception);
+ break;
+ }
+ }
+ if (p == (const PixelPacket *) NULL)
+ break;
+ *q++=(*p);
+ if (indexes == (IndexPacket *) NULL)
+ continue;
+ nexus_indexes=image_nexus->indexes;
+ if (nexus_indexes == (IndexPacket *) NULL)
+ continue;
+ *indexes++=(*nexus_indexes);
+ continue;
+ }
+ /*
+ Transfer a run of pixels.
+ */
+ p=AcquireCacheNexus(image,x+u,y+v,(const unsigned long) length,1,image_nexus,exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) memcpy(q,p,length*sizeof(PixelPacket));
+ q+=length;
+ if (indexes == (IndexPacket *) NULL)
+ continue;
+ nexus_indexes=image_nexus->indexes;
+ if (nexus_indexes == (IndexPacket *) NULL)
+ continue;
+ (void) memcpy(indexes,nexus_indexes,length*sizeof(IndexPacket));
+ indexes+=length;
+ }
+ }
+ DestroyCacheNexus(image_nexus);
+ return(pixels);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e C a c h e V i e w P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method AcquireCacheViewPixels gets pixels from the in-memory or disk pixel
+% cache as defined by the geometry parameters for read-only access. A
+% pointer to the pixels is returned if the pixels are transferred, otherwise
+% NULL is returned.
+%
+% The format of the AcquireCacheViewPixels method is:
+%
+% const PixelPacket *AcquireCacheViewPixels(const ViewInfo *view,
+% const long x,const long y,const unsigned long columns,
+% const unsigned long rows,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o pixels: Method AcquireCacheViewPixels returns a null pointer if an error
+% occurs, otherwise a pointer to the view pixels.
+%
+% o view: The address of a structure of type ViewInfo.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const PixelPacket *
+AcquireCacheViewPixels(const ViewInfo *view,
+ const long x,const long y,const unsigned long columns,
+ const unsigned long rows,ExceptionInfo *exception)
+{
+ const View
+ * restrict view_info = (const View *) view;
+
+ assert(view_info != (const View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ return AcquireCacheNexus(view_info->image,x,y,columns,rows,
+ view_info->nexus_info,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e C a c h e V i e w I n d e x e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method AcquireCacheViewIndexes returns read-only indexes associated with
+% the specified view.
+%
+% The format of the AcquireCacheViewIndexes method is:
+%
+% const IndexPacket *AcquireCacheViewIndexes(const ViewInfo *view)
+%
+% A description of each parameter follows:
+%
+% o indexes: Method AcquireCacheViewIndexes returns the indexes
+% associated with the specified view.
+%
+% o view: The address of a structure of type ViewInfo.
+%
+%
+*/
+MagickExport const IndexPacket *
+AcquireCacheViewIndexes(const ViewInfo *view)
+{
+ const View
+ * restrict view_info = (const View *) view;
+
+ assert(view_info != (const View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ return view_info->nexus_info->indexes;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireImagePixels() obtains a pixel region for read-only access. If the
+% region is successfully accessed, a pointer to it is returned, otherwise
+% NULL is returned. The returned pointer may point to a temporary working
+% copy of the pixels or it may point to the original pixels in memory.
+% Performance is maximized if the selected area is part of one row, or one
+% or more full rows, since then there is opportunity to access the pixels
+% in-place (without a copy) if the image is in RAM, or in a memory-mapped
+% file. The returned pointer should *never* be deallocated by the user.
+%
+% Pixels accessed via the returned pointer represent a simple array of type
+% PixelPacket. If the image storage class is PsudeoClass, call GetIndexes()
+% after invoking GetImagePixels() to obtain the colormap indexes (of type
+% IndexPacket) corresponding to the region.
+%
+% If you plan to modify the pixels, use GetImagePixels() instead.
+%
+% The format of the AcquireImagePixels() method is:
+%
+% const PixelPacket *AcquireImagePixels(const Image *image,const long x,
+% const long y,const unsigned long columns,const unsigned long rows,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: AcquireImagePixels() returns a pointer to the pixels if they
+% are transferred, otherwise a NULL is returned.
+%
+% o image: The image.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const PixelPacket *
+AcquireImagePixels(const Image *image,
+ const long x,const long y,const unsigned long columns,
+ const unsigned long rows,ExceptionInfo *exception)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return AcquireCacheViewPixels(AccessDefaultCacheView(image),
+ x,y,columns,rows,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e O n e C a c h e V i e w P i x e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method AcquireOneCacheViewPixel gets one pixel from the in-memory or disk
+% pixel cache as defined by the geometry parameters for read-only access.
+% The image background color is returned if there is an error retrieving
+% the pixel.
+%
+% The format of the AcquireOneCacheViewPixel method is:
+%
+% MagickPassFail AcquireOneCacheViewPixel(const ViewInfo *view,
+% PixelPacket *pixel,const long x,const long y,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o view: The address of a structure of type ViewInfo.
+%
+% o pixel: Pointer to PixelPacket to update.
+%
+% o x,y: Coordinate of pixel to retrieve
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static inline MagickPassFail
+AcquireOneCacheViewPixelInlined(const View *view_info,
+ PixelPacket *pixel,
+ const long x,const long y,
+ ExceptionInfo *exception)
+{
+ const Image
+ *image=view_info->image;
+
+ const CacheInfo
+ * restrict cache_info=(const CacheInfo *) image->cache;
+
+ MagickPassFail
+ status=MagickFail;
+
+ if (((MemoryCache == cache_info->type) || (MapCache == cache_info->type)) &&
+ ((x >= 0) && (y >= 0) &&
+ ((unsigned long) x < cache_info->columns) &&
+ ((unsigned long) y < cache_info->rows)))
+ {
+ magick_off_t
+ offset;
+
+ offset=y*(magick_off_t) cache_info->columns+x;
+ if ((cache_info->indexes_valid) && (PseudoClass == image->storage_class))
+ *pixel=image->colormap[cache_info->indexes[offset]];
+ else
+ *pixel=cache_info->pixels[offset];
+ status=MagickPass;
+ }
+ else
+ {
+ const PixelPacket
+ *pixels;
+
+ if ((pixels=AcquireCacheNexus(image,x,y,1,1,view_info->nexus_info,
+ exception)) != (const PixelPacket *) NULL)
+ {
+ *pixel=pixels[0];
+ status=MagickPass;
+ }
+ else
+ {
+ *pixel=image->background_color;
+ }
+ }
+
+ return status;
+}
+
+MagickExport MagickPassFail
+AcquireOneCacheViewPixel(const ViewInfo *view,PixelPacket *pixel,
+ const long x,const long y,
+ ExceptionInfo *exception)
+{
+ return AcquireOneCacheViewPixelInlined((const View *) view,pixel,x,y,
+ exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e O n e P i x e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireOnePixel() returns a single pixel at the specified (x,y) location.
+% The image background color is returned if an error occurs. If errors
+% are to be returned to the image, use GetOnePixel() instead. This function
+% is convenient but performance will be poor if it is used too often.
+%
+% The format of the AcquireOnePixel() method is:
+%
+% PixelPacket AcquireOnePixel(const Image image,const long x,
+% const long y,ExceptionInfo exception)
+%
+% A description of each parameter follows:
+%
+% o pixels: AcquireOnePixel() returns a pixel at the specified (x,y)
+% location.
+%
+% o image: The image.
+%
+% o x,y: These values define the location of the pixel to return.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport PixelPacket
+AcquireOnePixel(const Image *image,const long x,const long y,
+ ExceptionInfo *exception)
+{
+ PixelPacket
+ pixel;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ (void) AcquireOneCacheViewPixel(AccessDefaultCacheView(image),
+ &pixel,x,y,exception);
+ return pixel;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e O n e P i x e l B y R e f e r e n c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireOnePixelByReference() returns a single pixel at the specified (x,y)
+% location. The image background color is returned if an error occurs. This
+% function is convenient but performance will be poor if it is used too
+% often.
+%
+% The format of the AcquireOnePixelByReference() method is:
+%
+% MagickPassFail AcquireOnePixelByReference(const Image *image,
+% PixelPacket *pixel,
+% const long x,const long y,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o pixels: AcquireOnePixel() returns a pixel at the specified (x,y)
+% location.
+%
+% o image: The image.
+%
+% o pixel: A reference to the pixel to update.
+%
+% o x,y: These values define the location of the pixel to return.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail
+AcquireOnePixelByReference(const Image *image,PixelPacket *pixel,
+ const long x,const long y,
+ ExceptionInfo *exception)
+{
+ return
+ AcquireOneCacheViewPixelInlined((const View *) AccessDefaultCacheView(image),
+ pixel,x,y,
+ exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C h e c k I m a g e P i x e l L i m i t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CheckImagePixelLimits() verifies that image dimensions are within current
+% limits. Returns MagickPass if image dimensions are within limits, or
+% MagickFail (and updates exception) if dimensions exceed a limit.
+%
+% While this function is used within the pixel cache to prevent allocating
+% an image which exceeds the limits, it may also be used to validate image
+% dimensions obtained from file headers prior to allocating memory or doing
+% further processing of the image. Such additional limits should be after
+% any 'ping' mode processing so that the image dimensions can still be
+% shown by 'identify'.
+%
+% The format of the CheckImagePixelLimits() method is:
+%
+% MagickPassFail CheckImagePixelLimits(const Image *image,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: Image to verify rows/columns.
+%
+% o exception: Throw exception into this ExceptionInfo structure.
+%
+%
+*/
+MagickExport MagickPassFail
+CheckImagePixelLimits(const Image *image, ExceptionInfo *exception)
+{
+ if ((image->columns == 0) ||
+ (AcquireMagickResource(WidthResource,image->columns)
+ != MagickPass))
+ {
+ char
+ message[MaxTextExtent];
+
+ errno=0;
+ FormatString(message,"%lu > %" MAGICK_INT64_F "u \"%.1024s\"",
+ image->columns,
+ GetMagickResourceLimit(WidthResource),image->filename);
+ ThrowException(exception,ResourceLimitError,ImagePixelWidthLimitExceeded,
+ message);
+ return MagickFail;
+ }
+
+ if ((image->rows == 0) ||
+ (AcquireMagickResource(HeightResource,image->rows)
+ != MagickPass))
+ {
+ char
+ message[MaxTextExtent];
+
+ errno=0;
+ FormatString(message,"%lu > %" MAGICK_INT64_F "u \"%.1024s\"",
+ image->rows,
+ GetMagickResourceLimit(HeightResource),image->filename);
+ ThrowException(exception,ResourceLimitError,ImagePixelHeightLimitExceeded,
+ message);
+ return MagickFail;
+ }
+
+ {
+ magick_int64_t
+ total_pixels;
+
+ total_pixels=image->columns*image->rows;
+ if (AcquireMagickResource(PixelsResource,total_pixels)
+ != MagickPass)
+ {
+ char
+ message[MaxTextExtent];
+
+ errno=0;
+ FormatString(message,
+ "%" MAGICK_INT64_F "d > %" MAGICK_INT64_F "u \"%.1024s\"",
+ total_pixels,
+ GetMagickResourceLimit(PixelsResource),image->filename);
+ ThrowException(exception,ResourceLimitError,ImagePixelLimitExceeded,
+ message);
+ return MagickFail;
+ }
+ }
+
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l i p C a c h e N e x u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ClipCacheNexus() clips the image pixels of the in-memory or disk cache as
+% defined by the image clip mask. The method returns MagickPass if the
+% pixel region is clipped, otherwise MagickFail.
+%
+% The format of the ClipCacheNexus() method is:
+%
+% MagickPassFail ClipCacheNexus(Image *image,const NexusInfo *nexus_info)
+%
+% A description of each parameter follows:
+%
+% o status: ClipCacheNexus() returns MagickPass if the image pixels are
+% clipped, otherwise MagickFail.
+%
+% o image: The image.
+%
+% o nexusinfo: specifies which cache nexus to clip.
+%
+%
+*/
+static MagickPassFail
+ClipCacheNexus(Image *image,const NexusInfo *nexus_info)
+{
+ long
+ y;
+
+ register const PixelPacket
+ *r;
+
+ register long
+ x;
+
+ register PixelPacket
+ *p,
+ *q;
+
+ NexusInfo
+ *image_nexus,
+ *mask_nexus;
+
+ /*
+ Apply clip mask.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ image_nexus=AllocateCacheNexus();
+ mask_nexus=AllocateCacheNexus();
+ if ((image_nexus == (NexusInfo *) NULL) || (mask_nexus == (NexusInfo *) NULL))
+ {
+ DestroyCacheNexus(image_nexus);
+ DestroyCacheNexus(mask_nexus);
+ ThrowBinaryException(CacheError,UnableToGetCacheNexus,image->filename);
+ }
+ p=GetCacheNexus(image,nexus_info->region.x,nexus_info->region.y,
+ nexus_info->region.width,nexus_info->region.height,
+ image_nexus,&image->exception);
+ q=nexus_info->pixels;
+ r=AcquireCacheNexus(image->clip_mask,nexus_info->region.x,nexus_info->region.y,
+ nexus_info->region.width,nexus_info->region.height,mask_nexus,
+ &image->exception);
+ if ((p != (PixelPacket *) NULL) && (r != (const PixelPacket *) NULL))
+ for (y=0; y < (long) nexus_info->region.height; y++)
+ {
+ for (x=0; x < (long) nexus_info->region.width; x++)
+ {
+ if (r->red == TransparentOpacity)
+ q->red=p->red;
+ if (r->green == TransparentOpacity)
+ q->green=p->green;
+ if (r->blue == TransparentOpacity)
+ q->blue=p->blue;
+ if (r->opacity == TransparentOpacity)
+ q->opacity=p->opacity;
+ p++;
+ q++;
+ r++;
+ }
+ }
+ DestroyCacheNexus(image_nexus);
+ DestroyCacheNexus(mask_nexus);
+ return((p != (PixelPacket *) NULL) && (q != (PixelPacket *) NULL));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l o n e P i x e l C a c h e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ClonePixelCache() clones the pixel cache pixels from one cache to another.
+%
+% The format of the ClonePixelCache() method is:
+%
+% MagickPassFail ClonePixelCache(Image *image,Image *clone_image)
+%
+% A description of each parameter follows:
+%
+% o image: Image to clone from (the master).
+%
+% o clone_image: Image to clone to (the copy).
+%
+%
+*/
+static MagickPassFail
+ClonePixelCache(Image *image,Image *clone_image,ExceptionInfo *exception)
+{
+#define MaxBufferSize 65541
+
+ CacheInfo
+ *cache_info,
+ *clone_info;
+
+ char
+ *buffer;
+
+ ssize_t
+ count;
+
+ int
+ cache_file,
+ clone_file;
+
+ register magick_off_t
+ offset;
+
+ size_t
+ length;
+
+ MagickPassFail
+ status;
+
+ cache_info=(CacheInfo *) image->cache;
+ clone_info=(CacheInfo *) clone_image->cache;
+ if (cache_info->length != clone_info->length)
+ {
+ Image
+ *clip_mask;
+
+ ViewInfo
+ *clone_view,
+ *image_view;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register IndexPacket
+ *clone_indexes;
+
+ register PixelPacket
+ *q;
+
+ /*
+ Unoptimized pixel cache clone.
+ */
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"unoptimized clone");
+ clip_mask=clone_image->clip_mask;
+ clone_image->clip_mask=(Image *) NULL;
+ length=Min(image->columns,clone_image->columns);
+ y=0;
+ image_view=OpenCacheView(image);
+ clone_view=OpenCacheView(clone_image);
+ if ((image_view != (ViewInfo *) NULL) &&
+ (clone_view != (ViewInfo *) NULL))
+ {
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireCacheViewPixels(image_view,0,y,image->columns,1,
+ exception);
+ q=SetCacheViewPixels(clone_view,0,y,image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) ||
+ (q == (PixelPacket *) NULL))
+ break;
+ (void) memcpy(q,p,length*sizeof(PixelPacket));
+ indexes=AcquireCacheViewIndexes(image_view);
+ clone_indexes=GetCacheViewIndexes(clone_view);
+ if ((indexes != (const IndexPacket *) NULL) &&
+ (clone_indexes != (IndexPacket *) NULL))
+ (void) memcpy(clone_indexes,indexes,
+ length*sizeof(IndexPacket));
+ if (!SyncCacheViewPixels(clone_view,exception))
+ break;
+ }
+ }
+ clone_image->clip_mask=clip_mask;
+ CloseCacheView(image_view);
+ CloseCacheView(clone_view);
+ return(y == (long) image->rows);
+ }
+ /*
+ Optimized pixel cache clone.
+ */
+ if ((cache_info->type != DiskCache) && (clone_info->type != DiskCache))
+ {
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "memory => memory clone");
+ (void) memcpy(clone_info->pixels,cache_info->pixels,
+ (size_t) cache_info->length);
+ return(MagickPass);
+ }
+ LockSemaphoreInfo(cache_info->file_semaphore);
+ LockSemaphoreInfo(clone_info->file_semaphore);
+ status=MagickPass;
+ cache_file=cache_info->file;
+ if (cache_info->type == DiskCache)
+ {
+ if (cache_info->file == -1)
+ {
+ /* FIXME: open */
+ cache_file=open(cache_info->cache_filename,O_RDONLY | O_BINARY);
+ if (cache_file == -1)
+ {
+ status=MagickFail;
+ ThrowException(exception,FileOpenError,UnableToOpenFile,
+ cache_info->cache_filename);
+ goto clone_pixel_cache_done;
+ }
+ }
+ (void) MagickSeek(cache_file,cache_info->offset,SEEK_SET);
+ if (clone_info->type != DiskCache)
+ {
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "disk => memory clone");
+ for (offset=0; offset < cache_info->length; offset+=count)
+ {
+ size_t
+ requested_io_size;
+
+ unsigned int
+ io_size;
+
+ requested_io_size=(size_t) (cache_info->length-offset);
+ if (requested_io_size > MAGICK_IO_MAX)
+ io_size=MAGICK_IO_MAX;
+ else
+ io_size=(unsigned int) requested_io_size;
+
+ count=read(cache_file,(char *) clone_info->pixels+offset,
+ io_size);
+ if (count <= 0)
+ break;
+ }
+ if (cache_info->file == -1)
+ (void) close(cache_file);
+ if (offset < cache_info->length)
+ {
+ status=MagickFail;
+ ThrowException(exception,CacheError,UnableToCloneCache,
+ image->filename);
+ goto clone_pixel_cache_done;
+ }
+ goto clone_pixel_cache_done;
+ }
+ }
+ clone_file=clone_info->file;
+ if (clone_info->type == DiskCache)
+ {
+ if (clone_info->file == -1)
+ {
+ /* FIXME: open */
+ clone_file=open(clone_info->cache_filename,O_WRONLY | O_BINARY |
+ O_EXCL,S_MODE);
+ if (clone_file == -1)
+ clone_file=open(clone_info->cache_filename,O_WRONLY | O_BINARY,
+ S_MODE);
+ if (clone_file == -1)
+ {
+ if (cache_info->file == -1)
+ (void) close(cache_file);
+ status=MagickFail;
+ ThrowException(exception,FileOpenError,UnableToOpenFile,
+ clone_info->cache_filename);
+ goto clone_pixel_cache_done;
+ }
+ }
+ (void) MagickSeek(clone_file,cache_info->offset,SEEK_SET);
+ if (cache_info->type != DiskCache)
+ {
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "memory => disk clone");
+ for (offset=0L; offset < clone_info->length; offset+=count)
+ {
+ size_t
+ requested_io_size;
+
+ MAGICK_POSIX_IO_SIZE_T
+ io_size;
+
+ requested_io_size=(size_t) (clone_info->length-offset);
+ if (requested_io_size > MAGICK_IO_MAX)
+ io_size=MAGICK_IO_MAX;
+ else
+ io_size=(MAGICK_POSIX_IO_SIZE_T) requested_io_size;
+
+ count=write(clone_file,(char *) cache_info->pixels+offset,
+ io_size);
+ if (count <= 0)
+ break;
+ }
+ if (clone_info->file == -1)
+ (void) close(clone_file);
+ if (offset < clone_info->length)
+ {
+ status=MagickFail;
+ ThrowException(exception,CacheError,UnableToCloneCache,
+ image->filename);
+ }
+ goto clone_pixel_cache_done;
+ }
+ }
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"disk => disk clone");
+ buffer=MagickAllocateMemory(char *,MaxBufferSize);
+ if (buffer == (char *) NULL)
+ {
+ if (cache_info->file == -1)
+ (void) close(cache_file);
+ if (clone_info->file == -1)
+ (void) close(clone_file);
+ status=MagickFail;
+ ThrowException3(exception,ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToCloneImage);
+ goto clone_pixel_cache_done;
+ }
+ (void) MagickSeek(cache_file,cache_info->offset,SEEK_SET);
+ (void) MagickSeek(clone_file,cache_info->offset,SEEK_SET);
+
+ for (offset=0, length=0; (count=read(cache_file,buffer,MaxBufferSize)) > 0; )
+ {
+ length=(size_t) count;
+ for (offset=0; offset < (magick_off_t) length; offset+=count)
+ {
+ size_t
+ requested_io_size;
+
+ MAGICK_POSIX_IO_SIZE_T
+ io_size;
+
+ requested_io_size=(size_t) (length-offset);
+ if (requested_io_size > MAGICK_IO_MAX)
+ io_size=MAGICK_IO_MAX;
+ else
+ io_size=(MAGICK_POSIX_IO_SIZE_T) requested_io_size;
+
+ count=write(clone_file,buffer+offset,io_size);
+ if (count <= 0)
+ break;
+ }
+ if (offset < (magick_off_t) length)
+ break;
+ }
+ if (cache_info->file == -1)
+ (void) close(cache_file);
+ if (clone_info->file == -1)
+ (void) close(clone_file);
+
+ MagickFreeMemory(buffer);
+ if (offset < (magick_off_t) length)
+ {
+ status=MagickFail;
+ ThrowException(exception,CacheError,UnableToCloneCache,image->filename);
+ goto clone_pixel_cache_done;
+ }
+ clone_pixel_cache_done:
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
+ UnlockSemaphoreInfo(clone_info->file_semaphore);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l o s e C a c h e V i e w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloseCacheView() closes the specified view returned by a previous call
+% to OpenCacheView().
+%
+% The format of the CloseCacheView method is:
+%
+% void CloseCacheView(ViewInfo *view)
+%
+% A description of each parameter follows:
+%
+% o view: The address of a structure of type ViewInfo.
+%
+*/
+MagickExport void
+CloseCacheView(ViewInfo *view)
+{
+ if (view != (ViewInfo *) NULL)
+ {
+ View
+ *view_info = (View *) view;
+
+ assert(view_info->signature == MagickSignature);
+ assert(view_info->nexus_info->signature == MagickSignature);
+ DestroyCacheNexus(view_info->nexus_info);
+ view_info->nexus_info=(NexusInfo *) NULL;
+ MagickFreeAlignedMemory(view_info);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y C a c h e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyCacheInfo() deallocates memory associated with the pixel cache.
+%
+% The format of the DestroyCacheInfo() method is:
+%
+% void DestroyCacheInfo(Cache cache)
+%
+% A description of each parameter follows:
+%
+% o cache: Specifies a pointer to a Cache structure.
+%
+%
+*/
+void
+DestroyCacheInfo(Cache cache_info)
+{
+ assert(cache_info != (Cache) NULL);
+ assert(cache_info->signature == MagickSignature);
+ LockSemaphoreInfo(cache_info->reference_semaphore);
+ cache_info->reference_count--;
+ if (cache_info->reference_count > 0)
+ {
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "destroy skipped (still referenced %ld times) %.1024s",
+ cache_info->reference_count,
+ cache_info->filename);
+ UnlockSemaphoreInfo(cache_info->reference_semaphore);
+ return;
+ }
+ UnlockSemaphoreInfo(cache_info->reference_semaphore);
+ switch (cache_info->type)
+ {
+ default:
+ {
+ if (cache_info->pixels == (PixelPacket *) NULL)
+ break;
+ }
+ case MemoryCache:
+ {
+ MagickFreeMemory(cache_info->pixels);
+ LiberateMagickResource(MemoryResource,cache_info->length);
+ break;
+ }
+ case MapCache:
+ {
+ (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
+ LiberateMagickResource(MapResource,cache_info->length);
+ }
+ case DiskCache:
+ {
+ if (cache_info->file != -1)
+ {
+ (void) close(cache_info->file);
+ LiberateMagickResource(FileResource,1);
+ }
+ cache_info->file=(-1);
+ (void) LiberateTemporaryFile(cache_info->cache_filename);
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "remove %.1024s (%.1024s)",cache_info->filename,
+ cache_info->cache_filename);
+ LiberateMagickResource(DiskResource,cache_info->length);
+ break;
+ }
+ }
+ DestroySemaphoreInfo(&cache_info->file_semaphore);
+ DestroySemaphoreInfo(&cache_info->reference_semaphore);
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"destroy cache %.1024s",
+ cache_info->filename);
+ cache_info->signature=0;
+ MagickFreeAlignedMemory(cache_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y C a c h e N e x u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyCacheNexus() destroys a cache nexus which was allocated via
+% AllocateCacheNexus().
+%
+% The format of the DestroyCacheNexus() method is:
+%
+% void DestroyCacheNexus(NexusInfo *nexus_info)
+%
+% A description of each parameter follows:
+%
+% o nexus_info: cache nexus to destroy.
+%
+%
+*/
+static void
+DestroyCacheNexus(NexusInfo *nexus_info)
+{
+ if (nexus_info != (NexusInfo *) NULL)
+ {
+ MagickFreeAlignedMemory(nexus_info->staging);
+ MagickFreeAlignedMemory(nexus_info);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyImagePixels() deallocates memory associated with the pixel cache.
+%
+% The format of the DestroyImagePixels() method is:
+%
+% void DestroyImagePixels(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void
+DestroyImagePixels(Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (image->cache != (void *) NULL)
+ DestroyCacheInfo(image->cache);
+ image->cache=(Cache) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t C a c h e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetCacheInfo() initializes the Cache structure.
+%
+% The format of the GetCacheInfo() method is:
+%
+% void GetCacheInfo(Cache *cache)
+%
+% A description of each parameter follows:
+%
+% o cache: Specifies a pointer to a Cache structure.
+%
+%
+*/
+void
+GetCacheInfo(Cache *cache)
+{
+ CacheInfo
+ *cache_info;
+
+ assert(cache != (Cache*) NULL);
+ cache_info=MagickAllocateAlignedMemory(CacheInfo *,
+ MAGICK_CACHE_LINE_SIZE,
+ sizeof(CacheInfo));
+ if (cache_info == (CacheInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateCacheInfo);
+ (void) memset(cache_info,0,sizeof(CacheInfo));
+ cache_info->colorspace=RGBColorspace;
+ cache_info->reference_semaphore=AllocateSemaphoreInfo();
+ LockSemaphoreInfo(cache_info->reference_semaphore);
+ cache_info->reference_count=1;
+ UnlockSemaphoreInfo(cache_info->reference_semaphore);
+ cache_info->file=(-1);
+ if (cache_info->reference_semaphore == (SemaphoreInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateCacheInfo);
+ cache_info->file_semaphore=AllocateSemaphoreInfo();
+ if (cache_info->file_semaphore == (SemaphoreInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateCacheInfo);
+ cache_info->signature=MagickSignature;
+ *cache=cache_info;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t C a c h e N e x u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetCacheNexus() gets pixels from the in-memory or disk pixel cache as
+% defined by the geometry parameters. A pointer to the pixels is returned
+% if the pixels are transferred, otherwise a NULL is returned.
+%
+% The format of the GetCacheNexus() method is:
+%
+% PixelPacket *GetCacheNexus(Image *image,const long x,const long y,
+% const unsigned long columns,const unsigned long rows,
+% NexusInfo *nexus_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: GetCacheNexus() returns a pointer to the pixels if they are
+% transferred, otherwise a NULL is returned.
+%
+% o image: The image.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o nexus_info: specifies cache nexus to update
+%
+%
+*/
+static PixelPacket *
+GetCacheNexus(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ NexusInfo *nexus_info,ExceptionInfo *exception)
+{
+ PixelPacket
+ *pixels;
+
+ /*
+ Transfer pixels from the cache.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ /*
+ SetCacheNexus() invokes ModifyCache() which may replace the
+ current image cache so we obtain the cache *after* invoking
+ SetCacheNexus().
+ */
+ pixels=SetCacheNexus(image,x,y,columns,rows,nexus_info,exception);
+ if (pixels != (PixelPacket *) NULL)
+ {
+ CacheInfo
+ *cache_info;
+
+ cache_info=(CacheInfo *) image->cache;
+ assert(cache_info->signature == MagickSignature);
+ /*
+ If underlying image pixels are not already suited for being
+ updated in-place, then make a working copy in our cache view
+ buffer.
+ */
+ if (!nexus_info->in_core)
+ {
+ MagickPassFail
+ status;
+
+ status=ReadCachePixels(cache_info,nexus_info,exception);
+ if (cache_info->indexes_valid)
+ status&=ReadCacheIndexes(cache_info,nexus_info,exception);
+ if (status == MagickFail)
+ {
+ ThrowException(exception,CacheError,UnableToGetPixelsFromCache,
+ image->filename);
+ pixels=(PixelPacket *) NULL;
+ }
+ }
+ }
+ return(pixels);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t C a c h e V i e w A r e a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetCacheViewArea() returns the area (width * height in pixels) consumed by
+% the pixel cache view
+%
+% The format of the GetCacheViewArea() method is:
+%
+% magick_off_t GetCacheViewArea(const ViewInfo *view)
+%
+% A description of each parameter follows:
+%
+% o view: The view.
+%
+%
+*/
+MagickExport magick_off_t
+GetCacheViewArea(const ViewInfo *view)
+{
+ const View
+ * restrict view_info = (const View *) view;
+
+ register NexusInfo
+ * restrict nexus_info;
+
+ assert(view_info != (const View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ nexus_info=view_info->nexus_info;
+ return((magick_off_t) nexus_info->region.width*nexus_info->region.height);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C a c h e V i e w P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetCacheViewPixels() gets writeable pixels from the in-memory or disk pixel
+% cache as defined by the geometry parameters. A pointer to the pixels
+% is returned if the pixels are transferred, otherwise a NULL is returned.
+%
+% The format of the GetCacheViewPixels method is:
+%
+% PixelPacket *GetCacheViewPixels(ViewInfo *view,const long x,
+% const long y,const unsigned long columns,const unsigned long rows,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o pixels: Method GetCacheViewPixels returns a null pointer if an error
+% occurs, otherwise a pointer to the view pixels.
+%
+% o view: The address of a structure of type ViewInfo.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o exception: Any errors are reported here.
+%
+*/
+MagickExport PixelPacket *
+GetCacheViewPixels(const ViewInfo *view,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ ExceptionInfo *exception)
+{
+ const View
+ *view_info = (const View *) view;
+
+ PixelPacket
+ *pixels;
+
+ assert(view_info != (const View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ pixels=GetCacheNexus(view_info->image,x,y,columns,rows,view_info->nexus_info,
+ exception);
+ return pixels;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C a c h e V i e w I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetCacheViewImage returns the image which allocated the view.
+%
+% The format of the GetCacheViewImage method is:
+%
+% Image *GetCacheViewImage(const ViewInfo *view)
+%
+% A description of each parameter follows:
+%
+% o image: Method GetCacheViewImage returns the image which allocated
+% the view.
+%
+% o view: The address of a structure of type ViewInfo.
+%
+%
+*/
+extern Image *
+GetCacheViewImage(const ViewInfo *view)
+{
+ const View
+ * restrict view_info = (const View *) view;
+
+ assert(view_info != (View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ return view_info->image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t C a c h e V i e w I n d e x e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetCacheViewIndexes returns writeable indexes associated with
+% the specified view.
+%
+% The format of the GetCacheViewIndexes method is:
+%
+% IndexPacket *GetCacheViewIndexes(const ViewInfo *view)
+%
+% A description of each parameter follows:
+%
+% o indexes: Method GetCacheViewIndexes returns the indexes associated with
+% the specified view.
+%
+% o view: The address of a structure of type ViewInfo.
+%
+%
+*/
+MagickExport IndexPacket *
+GetCacheViewIndexes(const ViewInfo *view)
+{
+ const View
+ *view_info = (const View *) view;
+
+ assert(view_info != (View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ return view_info->nexus_info->indexes;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t C a c h e V i e w R e g i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetCacheViewRegion() returns the bounded region for the pixel cache view.
+%
+% The format of the GetCacheViewRegion() method is:
+%
+% RectangleInfo GetCacheViewRegion(const ViewInfo *view)
+%
+% A description of each parameter follows:
+%
+% o view: The view.
+%
+%
+*/
+MagickExport RectangleInfo
+GetCacheViewRegion(const ViewInfo *view)
+{
+ const View
+ *view_info = (const View *) view;
+
+ NexusInfo
+ *nexus_info;
+
+ assert(view_info != (View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ nexus_info=view_info->nexus_info;
+ assert(nexus_info != (NexusInfo *) NULL);
+ assert(nexus_info->signature == MagickSignature);
+ return nexus_info->region;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImagePixels() obtains a pixel region for read/write access. If the
+% region is successfully accessed, a pointer to a PixelPacket array
+% representing the region is returned, otherwise NULL is returned.
+%
+% The returned pointer may point to a temporary working copy of the pixels
+% or it may point to the original pixels in memory. Performance is maximized
+% if the selected area is part of one row, or one or more full rows, since
+% then there is opportunity to access the pixels in-place (without a copy)
+% if the image is in RAM, or in a memory-mapped file. The returned pointer
+% should *never* be deallocated by the user.
+%
+% Pixels accessed via the returned pointer represent a simple array of type
+% PixelPacket. If the image storage class is PsudeoClass, call GetIndexes()
+% after invoking GetImagePixels() to obtain the colormap indexes (of type
+% IndexPacket) corresponding to the region. Once the PixelPacket (and/or
+% IndexPacket) array has been updated, the changes must be saved back to
+% the underlying image using SyncImagePixels() or they may be lost.
+%
+% The format of the GetImagePixels() method is:
+%
+% PixelPacket *GetImagePixels(Image *image,const long x,const long y,
+% const unsigned long columns,const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o status: GetImagePixels() returns a pointer to the pixels if they are
+% transferred, otherwise a NULL is returned.
+%
+% o image: The image.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+%
+*/
+MagickExport PixelPacket *
+GetImagePixels(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return GetCacheViewPixels(AccessDefaultCacheView(image),
+ x,y,columns,rows,&image->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e P i x e l s E x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImagePixelsEx() obtains a pixel region for read/write access. It is
+% similar to GetImagePixels() except that it reports any error information
+% to a user provided exception structure.
+%
+% The format of the GetImagePixelsEx() method is:
+%
+% PixelPacket *GetImagePixelsEx(Image *image,const long x,const long y,
+% const unsigned long columns,const unsigned long rows,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: GetImagePixelsEx() returns a pointer to the pixels if they are
+% transferred, otherwise a NULL is returned.
+%
+% o image: The image.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o exception: Any error details are reported here.
+%
+%
+*/
+MagickExport PixelPacket *
+GetImagePixelsEx(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ ExceptionInfo *exception)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return GetCacheViewPixels(AccessDefaultCacheView(image),
+ x,y,columns,rows,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e V i r t u a l P i x e l M e t h o d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageVirtualPixelMethod() gets the "virtual pixels" method for the
+% image. A virtual pixel is any pixel access that is outside the boundaries
+% of the image cache.
+%
+% The format of the GetImageVirtualPixelMethod() method is:
+%
+% VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport VirtualPixelMethod
+GetImageVirtualPixelMethod(const Image *image)
+{
+ CacheInfo
+ *cache_info;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->cache != (Cache) NULL);
+ cache_info=(CacheInfo *) image->cache;
+ assert(cache_info->signature == MagickSignature);
+ return(cache_info->virtual_pixel_method);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I n d e x e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetIndexes() returns the colormap indexes associated with the last call to
+% SetImagePixels() or GetImagePixels(). NULL is returned if colormap indexes
+% are not available.
+%
+% The format of the GetIndexes() method is:
+%
+% IndexPacket *GetIndexes(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o indexes: GetIndexes() returns the indexes associated with the last
+% call to SetImagePixels() or GetImagePixels().
+%
+% o image: The image.
+%
+%
+*/
+MagickExport IndexPacket *
+GetIndexes(const Image *image)
+{
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return GetCacheViewIndexes(AccessDefaultCacheView(image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ A l l o c a t e C a c h e N e x u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AllocateCacheNexus() allocates a cache nexus. The cache nexus is
+% deallocated via DestroyCacheNexus(). NULL is returned on failure.
+%
+% The format of the AllocateCacheNexus() method is:
+%
+% NexusInfo *AllocateCacheNexus(void)
+%
+% A description of each parameter follows:
+%
+%
+%
+*/
+static NexusInfo *
+AllocateCacheNexus(void)
+{
+ NexusInfo
+ *nexus_info;
+
+ nexus_info=MagickAllocateAlignedMemory(NexusInfo *,MAGICK_CACHE_LINE_SIZE,
+ sizeof(NexusInfo));
+ if (nexus_info != ((NexusInfo *) NULL))
+ {
+ (void) memset(nexus_info,0,sizeof(NexusInfo));
+ nexus_info->signature=MagickSignature;
+ }
+ return nexus_info;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t O n e P i x e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetOnePixel() returns a single pixel at the specified (x,y) location.
+% The image background color is returned if an error occurs. This function
+% is convenient but performance will be poor if it is used too often.
+% GetOnePixel() is identical to AcquireOnePixel() except that exceptions
+% are implicitly delivered to the image.
+%
+% The format of the GetOnePixel() method is:
+%
+% PixelPacket GetOnePixel(const Image image,const long x,const long y)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o x,y: These values define the location of the pixel to return.
+%
+*/
+MagickExport PixelPacket
+GetOnePixel(Image *image,const long x,const long y)
+{
+ PixelPacket
+ pixel;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ (void) AcquireOneCacheViewPixel(AccessDefaultCacheView(image),
+ &pixel,x,y,&image->exception);
+
+ return pixel;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetPixels() returns the pixels associated with the last call to
+% SetImagePixels() or GetImagePixels(). This is useful in order to access
+% an already selected region without passing the geometry of the region.
+%
+% The format of the GetPixels() method is:
+%
+% PixelPacket *GetPixels(const Image image)
+%
+% A description of each parameter follows:
+%
+% o pixels: GetPixels() returns the pixels associated with the last call
+% to SetImagePixels() or GetImagePixels().
+%
+% o image: The image.
+%
+%
+*/
+MagickExport PixelPacket *
+GetPixels(const Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return AccessCacheViewPixels(AccessDefaultCacheView(image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t P i x e l C a c h e A r e a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetPixelCacheArea() returns the area (width * height in pixels) consumed by
+% the current pixel cache.
+%
+% The format of the GetPixelCacheArea() method is:
+%
+% magick_off_t GetPixelCacheArea(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport magick_off_t
+GetPixelCacheArea(const Image *image)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return GetCacheViewArea(AccessDefaultCacheView(image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t P i x e l C a c h e I n C o r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetPixelCacheInCore() tests to see the pixel cache is based on allocated
+% memory and therefore supports efficient random access.
+%
+% The format of the GetPixelCacheInCore() method is:
+%
+% MagickBool GetPixelCacheInCore(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: Specifies a pointer to an Image structure.
+%
+%
+*/
+extern MagickBool
+GetPixelCacheInCore(const Image *image)
+{
+
+ MagickBool
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ status = MagickFalse;
+ if (image->cache != (Cache) NULL)
+ {
+ CacheInfo
+ *cache_info;
+
+ cache_info=(CacheInfo *) image->cache;
+ assert(cache_info->signature == MagickSignature);
+
+ if ((image->cache->type == MemoryCache) ||
+ ((image->cache->type == MapCache) && (image->cache->read_only)))
+ status=MagickTrue;
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t P i x e l C a c h e P r e s e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetPixelCachePresent() tests to see the pixel cache is present
+% and contains pixels.
+%
+% The format of the GetPixelCachePresent() method is:
+%
+% MagickBool GetPixelCachePresent(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: Specifies a pointer to an Image structure.
+%
+%
+*/
+extern MagickExport MagickBool
+GetPixelCachePresent(const Image *image)
+{
+ CacheInfo
+ *cache_info;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (image->cache == (Cache) NULL)
+ return MagickFalse;
+
+ cache_info=(CacheInfo *) image->cache;
+ assert(cache_info->signature == MagickSignature);
+ if ((cache_info->columns == 0) ||
+ (cache_info->rows == 0))
+ return MagickFalse;
+
+ return MagickTrue;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n t e r p o l a t e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InterpolateColor applies bi-linear interpolation between a pixel and
+% it's neighbors.
+%
+% The format of the InterpolateColor method is:
+%
+% PixelPacket InterpolateColor(const Image *image,const double x_offset,
+% const double y_offset,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o x_offset,y_offset: A double representing the current (x,y) position of
+% the pixel.
+%
+%
+*/
+MagickExport void
+InterpolateViewColor(const ViewInfo *view,
+ PixelPacket *color,
+ const double x_offset,
+ const double y_offset,
+ ExceptionInfo *exception)
+{
+ register const PixelPacket
+ *p;
+
+ const Image
+ *image = ((const View *) view)->image;
+
+ register MagickBool
+ matte;
+
+ double
+ alpha,
+ beta,
+ one_minus_alpha,
+ one_minus_beta,
+ p0_area,
+ p1_area,
+ p2_area,
+ p3_area,
+ p_area;
+
+ p=AcquireCacheViewPixels(view,(long) x_offset,(long) y_offset,2,2,exception);
+ if (p == (const PixelPacket *) NULL)
+ return;
+
+ matte = image->matte && IsRGBColorspace(image->colorspace);
+
+ alpha=x_offset-floor(x_offset);
+ beta=y_offset-floor(y_offset);
+ one_minus_alpha=1.0-alpha;
+ one_minus_beta=1.0-beta;
+ p0_area = ((!matte) || (p[0].opacity != TransparentOpacity)
+ ? one_minus_beta * one_minus_alpha : 0.0);
+ p1_area = ((!matte) || (p[1].opacity != TransparentOpacity)
+ ? one_minus_beta * alpha : 0.0);
+ p2_area = ((!matte) || (p[2].opacity != TransparentOpacity)
+ ? beta * one_minus_alpha : 0.0);
+ p3_area = ((!matte) || (p[3].opacity != TransparentOpacity)
+ ? beta * alpha : 0.0);
+ p_area = p0_area + p1_area + p2_area + p3_area;
+ if (p_area <= 0.5/MaxRGBDouble)
+ {
+ color->red=0;
+ color->green=0;
+ color->blue=0;
+ color->opacity=TransparentOpacity;
+ }
+ else
+ {
+ color->red=(Quantum)
+ (((p0_area*p[0].red+p1_area*p[1].red+
+ p2_area*p[2].red+p3_area*p[3].red)/p_area)+0.5);
+ color->green=(Quantum)
+ (((p0_area*p[0].green+p1_area*p[1].green+
+ p2_area*p[2].green+p3_area*p[3].green)/p_area)+0.5);
+ color->blue=(Quantum)
+ (((p0_area*p[0].blue+p1_area*p[1].blue+
+ p2_area*p[2].blue+p3_area*p[3].blue)/p_area)+0.5);
+ if (!matte)
+ color->opacity=OpaqueOpacity;
+ else
+ color->opacity=(Quantum)
+ (one_minus_beta*(one_minus_alpha*p[0].opacity+alpha*p[1].opacity)+
+ beta*(one_minus_alpha*p[2].opacity+alpha*p[3].opacity)+0.5);
+ }
+}
+MagickExport PixelPacket InterpolateColor(const Image *image,
+ const double x_offset,const double y_offset,ExceptionInfo *exception)
+{
+ PixelPacket
+ color;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ InterpolateViewColor(AccessDefaultCacheView(image),&color,
+ x_offset,y_offset,exception);
+ return color;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o d i f y C a c h e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ModifyCache() ensures that there is only a single reference to the pixel
+% cache to be modified, updating the provided cache pointer to point to
+% a clone of the original pixel cache if necessary. This is used to
+% implement copy on write.
+%
+% The format of the ModifyCache method is:
+%
+% MagickPassFail ModifyCache(Image *image, ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Errors are reported here.
+%
+*/
+MagickPassFail
+ModifyCache(Image *image, ExceptionInfo *exception)
+{
+ CacheInfo
+ *cache_info;
+
+ MagickPassFail
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ status=MagickPass;
+
+ /*
+ Note that this function is normally executed for each and every
+ scanline which is read/updated so it represents constant locking
+ overhead.
+ */
+ LockSemaphoreInfo(image->semaphore);
+ {
+ MagickBool
+ destroy_cache=MagickFalse;
+
+ assert(image->cache != (Cache) NULL);
+ cache_info=(CacheInfo *) image->cache;
+
+ LockSemaphoreInfo(cache_info->reference_semaphore);
+ {
+ if ((cache_info->reference_count > 1) || (cache_info->read_only))
+ {
+ Image
+ clone_image;
+
+ /* fprintf(stderr,"ModifyCache: Thread %d enters (cache_info = %p)\n",
+ omp_get_thread_num(),image->cache); */
+ clone_image=(*image);
+ /*
+ Semaphore and reference count need to be initialized for the temporary
+ Image copy since otherwise there may be deadlock in ClonePixelCache.
+ */
+ clone_image.semaphore=AllocateSemaphoreInfo();
+ clone_image.reference_count=1;
+
+ GetCacheInfo(&clone_image.cache);
+ status=OpenCache(&clone_image,IOMode,exception);
+ if (status != MagickFail)
+ {
+ /*
+ Clone the pixel cache.
+ */
+ status=ClonePixelCache(image,&clone_image,exception);
+ }
+ DestroySemaphoreInfo(&clone_image.semaphore);
+
+ if (status != MagickFail)
+ {
+ destroy_cache=MagickTrue;
+ image->cache=clone_image.cache;
+ }
+ if (status == MagickFail)
+ fprintf(stderr,"ModifyCache failed!\n");
+ /* fprintf(stderr,"ModifyCache: Thread %d exits (cache_info = %p)\n",
+ omp_get_thread_num(),image->cache); */
+ }
+ }
+ UnlockSemaphoreInfo(cache_info->reference_semaphore);
+
+ /*
+ Decrement the cache reference count, and destroys the origin
+ cache if necessary.
+ */
+ if (destroy_cache)
+ DestroyCacheInfo(cache_info);
+
+ if (status != MagickFail)
+ {
+ /*
+ Indicate that image will be (possibly) modified, and unset
+ grayscale/monocrome flags.
+ */
+ image->taint=MagickTrue;
+ image->is_grayscale=MagickFalse;
+ image->is_monochrome=MagickFalse;
+
+ /*
+ Make sure that pixel cache reflects key image parameters
+ such as storage class and colorspace. Re-open cache if
+ necessary.
+ */
+ cache_info=(CacheInfo *) image->cache;
+ status=(((image->storage_class == cache_info->storage_class) &&
+ (image->colorspace == cache_info->colorspace)) ||
+ (OpenCache(image,IOMode,exception)));
+ }
+ }
+ UnlockSemaphoreInfo(image->semaphore);
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ O p e n C a c h e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% OpenCache() allocates the pixel cache. This includes defining the cache
+% dimensions, allocating space for the image pixels and optionally the
+% colormap indexes, and memory mapping the cache if it is disk based. The
+% cache nexus array is initialized as well.
+%
+% The format of the OpenCache() method is:
+%
+% MagickPass int OpenCache(Image *image,const MapMode mode,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: OpenCache() returns MagickPass if the pixel cache is initialized
+% successfully otherwise MagickFail.
+%
+% o image: The image.
+%
+% o mode: ReadMode, WriteMode, or IOMode.
+%
+% o exception: Errors are reported here.
+%
+%
+*/
+
+static MagickPassFail
+ExtendCache(int file,magick_off_t length)
+{
+ ssize_t
+ count;
+
+ magick_off_t
+ offset;
+
+ offset=MagickSeek(file,0,SEEK_END);
+ if (offset < 0)
+ return(MagickFail);
+ if (offset >= length)
+ return(MagickPass);
+ offset=MagickSeek(file,length-1,SEEK_SET);
+ if (offset < 0)
+ return(MagickFail);
+ count=write(file,(void *) "",1);
+ if (count != 1)
+ return(MagickFail);
+ return(MagickPass);
+}
+
+static MagickPassFail
+OpenCache(Image *image,const MapMode mode,ExceptionInfo *exception)
+{
+ char
+ format[MaxTextExtent];
+
+ CacheInfo
+ *cache_info;
+
+ magick_uint64_t
+ number_pixels;
+
+ magick_off_t
+ offset;
+
+ int
+ file;
+
+ PixelPacket
+ *pixels;
+
+ size_t
+ packet_size;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->cache != (void *) NULL);
+ if ((image->columns == 0) || (image->rows == 0))
+ {
+ if (image->exception.severity < ResourceLimitError)
+ ThrowException(exception,ResourceLimitError,NoPixelsDefinedInCache,
+ image->filename);
+ return MagickFail;
+ }
+
+ cache_info=(CacheInfo *) image->cache;
+ assert(cache_info->signature == MagickSignature);
+ FormatString(cache_info->filename,"%.1024s[%ld]",image->filename,
+ GetImageIndexInList(image));
+ cache_info->rows=image->rows;
+ cache_info->columns=image->columns;
+ number_pixels=(magick_uint64_t) cache_info->columns*cache_info->rows;
+ if (cache_info->storage_class != UndefinedClass)
+ {
+ /*
+ Free cache resources.
+ */
+ switch (cache_info->type)
+ {
+ case UndefinedCache:
+ {
+ break;
+ }
+ case PingCache:
+ {
+ break;
+ }
+ case MemoryCache:
+ {
+ LiberateMagickResource(MemoryResource,cache_info->length);
+ break;
+ }
+ case DiskCache:
+ {
+ LiberateMagickResource(DiskResource,cache_info->length);
+ if (cache_info->file == -1)
+ break;
+ (void) close(cache_info->file);
+ cache_info->file=(-1);
+ LiberateMagickResource(FileResource,1);
+ break;
+ }
+ case MapCache:
+ {
+ (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
+ LiberateMagickResource(MapResource,cache_info->length);
+ break;
+ }
+ }
+ }
+
+ /*
+ Save the open mode.
+ */
+ cache_info->read_only = (mode == ReadMode ? MagickTrue : MagickFalse);
+
+ /*
+ Indexes are valid if the image storage class is PseudoClass or the
+ colorspace is CMYK.
+ */
+ cache_info->indexes_valid=((image->storage_class == PseudoClass) ||
+ (image->colorspace == CMYKColorspace));
+
+ if (image->ping)
+ {
+ cache_info->storage_class=image->storage_class;
+ cache_info->colorspace=image->colorspace;
+ cache_info->type=PingCache;
+ cache_info->pixels=(PixelPacket *) NULL;
+ cache_info->indexes=(IndexPacket *) NULL;
+ cache_info->length=0;
+ return(MagickPass);
+ }
+
+ /*
+ Ensure that image dimensions are within limits.
+ */
+ if (CheckImagePixelLimits(image,exception) == MagickFail)
+ return MagickFail;
+
+ /*
+ Compute storage sizes. Make sure that sizes fit within our
+ numeric limits.
+ */
+ packet_size=sizeof(PixelPacket);
+ if (cache_info->indexes_valid)
+ packet_size+=sizeof(IndexPacket);
+ offset=number_pixels*packet_size;
+ if (cache_info->columns != (offset/cache_info->rows/packet_size))
+ {
+ ThrowException(exception,ResourceLimitError,PixelCacheAllocationFailed,
+ image->filename);
+ return MagickFail;
+ }
+ cache_info->length=offset;
+ /*
+ Attempt to create pixel cache in memory
+ */
+ offset=number_pixels*(sizeof(PixelPacket)+sizeof(IndexPacket)); /* FIXME */
+ if ((offset == (magick_off_t) ((size_t) offset)) &&
+ ((cache_info->type == UndefinedCache) ||
+ (cache_info->type == MemoryCache)) &&
+ (AcquireMagickResource(MemoryResource,offset)))
+ {
+ MagickReallocMemory(PixelPacket *,cache_info->pixels,(size_t) offset);
+ pixels=cache_info->pixels;
+ if (pixels == (PixelPacket *) NULL)
+ LiberateMagickResource(MemoryResource,offset);
+ else
+ {
+ /*
+ Create in-memory pixel cache.
+ */
+ cache_info->length=offset;
+ cache_info->storage_class=image->storage_class;
+ cache_info->colorspace=image->colorspace;
+ cache_info->type=MemoryCache;
+ cache_info->pixels=pixels;
+ cache_info->indexes=(IndexPacket *) NULL;
+ if (cache_info->indexes_valid)
+ cache_info->indexes=(IndexPacket *) (pixels+number_pixels);
+ FormatSize(cache_info->length,format);
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "open %.1024s (%.1024s)",cache_info->filename,
+ format);
+ return(MagickPass);
+ }
+ }
+ /*
+ Create pixel cache on disk.
+ */
+ if (!AcquireMagickResource(DiskResource,cache_info->length))
+ {
+ ThrowException(exception,ResourceLimitError,CacheResourcesExhausted,
+ image->filename);
+ return MagickFail;
+ }
+ if (*cache_info->cache_filename == '\0')
+ if(!AcquireTemporaryFileName(cache_info->cache_filename))
+ {
+ LiberateMagickResource(DiskResource,cache_info->length);
+ ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,
+ cache_info->cache_filename);
+ return MagickFail;
+ }
+ switch (mode)
+ {
+ case ReadMode:
+ {
+ /* FIXME: open */
+ file=open(cache_info->cache_filename,O_RDONLY | O_BINARY | _O_SEQUENTIAL);
+ break;
+ }
+ case WriteMode:
+ {
+ /* FIXME: open */
+ file=open(cache_info->cache_filename,O_WRONLY | O_CREAT | O_BINARY |
+ O_EXCL | _O_SEQUENTIAL,S_MODE);
+ if (file == -1)
+ file=open(cache_info->cache_filename,O_WRONLY | O_BINARY,S_MODE);
+ break;
+ }
+ case IOMode:
+ default:
+ {
+ /* FIXME: open */
+ file=open(cache_info->cache_filename,O_RDWR | O_CREAT | O_BINARY |
+ O_EXCL | _O_SEQUENTIAL, S_MODE);
+ if (file == -1)
+ file=open(cache_info->cache_filename,O_RDWR | O_BINARY | _O_RANDOM,
+ S_MODE);
+ break;
+ }
+ }
+ if (file == -1)
+ {
+ LiberateMagickResource(DiskResource,cache_info->length);
+ ThrowException(exception,CacheError,UnableToOpenCache,image->filename);
+ return MagickFail;
+ }
+ if (!ExtendCache(file,cache_info->offset+cache_info->length))
+ {
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "Unable to extend pixel cache from %"
+ MAGICK_OFF_F "d bytes "
+ "by %" MAGICK_OFF_F "d bytes "
+ "to %" MAGICK_OFF_F "d bytes",
+ cache_info->length,
+ cache_info->offset,
+ cache_info->offset+cache_info->length);
+ (void) close(file);
+ (void) LiberateTemporaryFile(cache_info->cache_filename);
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "remove %.1024s (%.1024s)",cache_info->filename,
+ cache_info->cache_filename);
+ LiberateMagickResource(DiskResource,cache_info->length);
+ ThrowException(exception,CacheError,UnableToExtendCache,image->filename);
+ return MagickFail;
+ }
+ cache_info->storage_class=image->storage_class;
+ cache_info->colorspace=image->colorspace;
+ cache_info->type=DiskCache;
+ if ((cache_info->length > MinBlobExtent) &&
+ (cache_info->length == (magick_off_t) ((size_t) cache_info->length)) &&
+ AcquireMagickResource(MapResource,cache_info->length))
+ {
+ pixels=(PixelPacket *) MapBlob(file,mode,(off_t) cache_info->offset,
+ (size_t) cache_info->length);
+ if (pixels == (PixelPacket *) NULL)
+ LiberateMagickResource(MapResource,cache_info->length);
+ else
+ {
+ /*
+ Create memory-mapped pixel cache.
+ */
+ (void) close(file);
+ cache_info->type=MapCache;
+ cache_info->pixels=pixels;
+ cache_info->indexes=(IndexPacket *) NULL;
+ if (cache_info->indexes_valid)
+ cache_info->indexes=(IndexPacket *) (pixels+number_pixels);
+ }
+ }
+ if (cache_info->type == DiskCache)
+ {
+ if (AcquireMagickResource(FileResource,1))
+ cache_info->file=file;
+ else
+ (void) close(file);
+ }
+#if defined(SIGBUS)
+ /* (void) signal(SIGBUS,CacheSignalHandler); */
+#endif
+ FormatSize(cache_info->length,format);
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "open %.1024s (%.1024s[%d], %.1024s, %.1024s)",
+ cache_info->filename,cache_info->cache_filename,
+ cache_info->file,
+ cache_info->type == MapCache ? "memory-mapped" : "disk",
+ format);
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% O p e n C a c h e V i e w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% OpenCacheView() opens a view into the pixel cache.
+%
+% The format of the OpenCacheView method is:
+%
+% ViewInfo *OpenCacheView(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport ViewInfo *
+OpenCacheView(Image *image)
+{
+ View
+ *view=(View *) NULL;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ view=MagickAllocateAlignedMemory(View *,MAGICK_CACHE_LINE_SIZE,
+ sizeof(View));
+ if (view == (View *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateCacheView);
+ (void) memset(view,0,sizeof(View));
+ view->nexus_info=AllocateCacheNexus();
+ if (view->nexus_info == ((NexusInfo *) NULL))
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateCacheView);
+ view->image=image;
+ view->signature=MagickSignature;
+
+ return ((ViewInfo *) view);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ P e r s i s t C a c h e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PersistCache() attaches to or initializes a persistent pixel cache. A
+% persistent pixel cache is one that resides on disk and is not destroyed
+% when the program exits.
+%
+% The format of the PersistCache() method is:
+%
+% MagickPassFail PersistCache(Image *image,const char *filename,
+% const MagickBool attach,magick_off_t *offset,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: PersistCache() returns MagickPass if the persistent pixel cache is
+% attached or initialized successfully otherwise MagickFail.
+%
+% o image: The image.
+%
+% o filename: The persistent pixel cache filename.
+%
+% o attach: A value other than zero initializes the persistent pixel
+% cache.
+%
+% o offset: The offset in the persistent cache to store pixels.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail
+PersistCache(Image *image,const char *filename,
+ const MagickBool attach,magick_off_t *offset,
+ ExceptionInfo *exception)
+{
+ CacheInfo
+ *cache_info;
+
+ Image
+ *clone_image;
+
+
+ long
+ pagesize,
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q;
+
+ MagickPassFail
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->cache != (void *) NULL);
+ assert(filename != (const char *) NULL);
+ assert(offset != (magick_off_t *) NULL);
+ pagesize=MagickGetMMUPageSize();
+ cache_info=(CacheInfo *) image->cache;
+ if (attach)
+ {
+ /*
+ Attach persistent pixel cache.
+ */
+ (void) strlcpy(cache_info->cache_filename,filename,MaxTextExtent);
+ cache_info->type=DiskCache;
+ cache_info->offset=(*offset);
+ if (!OpenCache(image,ReadMode,exception))
+ return(MagickFail);
+ *offset+=cache_info->length+pagesize-(cache_info->length % pagesize);
+ cache_info->read_only=MagickTrue;
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "Attach persistent cache %.1024s",
+ cache_info->filename);
+ return(MagickPass);
+ }
+ LockSemaphoreInfo(cache_info->reference_semaphore);
+ if ((cache_info->reference_count == 1) &&
+ (cache_info->type != MemoryCache))
+ {
+ /*
+ Usurp resident persistent pixel cache.
+ */
+ status=rename(cache_info->cache_filename,filename);
+ if (status == 0)
+ {
+ (void) strlcpy(cache_info->cache_filename,filename,MaxTextExtent);
+ UnlockSemaphoreInfo(cache_info->reference_semaphore);
+ cache_info=(CacheInfo*) ReferenceCache(cache_info);
+ *offset+=cache_info->length+pagesize-(cache_info->length % pagesize);
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "Usurp resident persistent cache");
+ return(MagickPass);
+ }
+ }
+ UnlockSemaphoreInfo(cache_info->reference_semaphore);
+ /*
+ Clone persistent pixel cache.
+ */
+ clone_image=CloneImage(image,image->columns,image->rows,MagickPass,exception);
+ if (clone_image == (Image *) NULL)
+ return(MagickFail);
+ cache_info=(CacheInfo *) clone_image->cache;
+ (void) strlcpy(cache_info->cache_filename,filename,MaxTextExtent);
+ cache_info->type=DiskCache;
+ cache_info->offset=(*offset);
+ if (!OpenCache(clone_image,IOMode,exception))
+ return(MagickFail);
+ y=0;
+ {
+ ViewInfo
+ *clone_view,
+ *image_view;
+
+ const IndexPacket
+ *indexes;
+
+ IndexPacket
+ *clone_indexes;
+
+ image_view=OpenCacheView(image);
+ clone_view=OpenCacheView(clone_image);
+ if ((image_view != (ViewInfo *) NULL) &&
+ (clone_view != (ViewInfo *) NULL))
+ {
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireCacheViewPixels(image_view,0,y,image->columns,1,exception);
+ q=SetCacheViewPixels(clone_view,0,y,clone_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ break;
+ (void) memcpy(q,p,image->columns*sizeof(PixelPacket));
+ clone_indexes=GetCacheViewIndexes(clone_view);
+ indexes=AcquireCacheViewIndexes(image_view);
+ if ((clone_indexes != (IndexPacket *) NULL) &&
+ (indexes != (const IndexPacket *) NULL))
+ (void) memcpy(clone_indexes,indexes,image->columns*sizeof(IndexPacket));
+ if (!SyncCacheViewPixels(clone_view,exception))
+ break;
+ }
+ }
+ CloseCacheView(image_view);
+ CloseCacheView(clone_view);
+ }
+ cache_info=(CacheInfo*) ReferenceCache(cache_info);
+ DestroyImage(clone_image);
+ if (y < (long) image->rows)
+ return(MagickFail);
+ *offset+=cache_info->length+pagesize-(cache_info->length % pagesize);
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"Clone persistent cache");
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d C a c h e I n d e x e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadCacheIndexes() reads colormap indexes from the specified region of the
+% pixel cache.
+%
+% The format of the ReadCacheIndexes() method is:
+%
+% MagickPassFail ReadCacheIndexes(const Cache cache,
+% const NexusInfo *nexus_info)
+%
+% A description of each parameter follows:
+%
+% o status: ReadCacheIndexes returns MagickPass if the colormap indexes are
+% successfully read from the pixel cache, otherwise MagickFail.
+%
+% o cache: Specifies a pointer to a CacheInfo structure.
+%
+% o nexus: specifies which cache nexus to read the colormap indexes.
+%
+%
+*/
+static MagickPassFail
+ReadCacheIndexes(const Cache cache,const NexusInfo *nexus_info,
+ ExceptionInfo *exception)
+{
+ CacheInfo
+ *cache_info;
+
+ magick_uint64_t
+ number_pixels;
+
+ magick_off_t
+ offset;
+
+ int
+ file;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ y;
+
+ size_t
+ length;
+
+ unsigned long
+ rows;
+
+ ARG_NOT_USED(exception);
+ assert(cache != (Cache) NULL);
+ cache_info=(CacheInfo *) cache;
+ assert(cache_info->signature == MagickSignature);
+ if (!cache_info->indexes_valid)
+ return(MagickFail);
+ if (nexus_info->in_core)
+ return(MagickPass);
+ offset=nexus_info->region.y*(magick_off_t) cache_info->columns+nexus_info->region.x;
+ length=nexus_info->region.width*sizeof(IndexPacket);
+ rows=nexus_info->region.height;
+ number_pixels=(magick_uint64_t) length*rows;
+ if ((cache_info->columns == nexus_info->region.width) &&
+ (number_pixels == (size_t) number_pixels))
+ {
+ length=number_pixels;
+ rows=1;
+ }
+ y=0;
+ indexes=nexus_info->indexes;
+ if (cache_info->type != DiskCache)
+ {
+ /*
+ Read indexes from memory.
+ */
+ register const IndexPacket
+ *cache_indexes;
+
+ cache_indexes=cache_info->indexes+offset;
+ if (length < 257)
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ register long
+ x;
+
+ for (x=0; x < (long) nexus_info->region.width; x++)
+ *indexes++=cache_indexes[x];
+ cache_indexes+=cache_info->columns;
+ }
+ }
+ else
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ (void) memcpy(indexes,cache_indexes,length);
+ indexes+=nexus_info->region.width;
+ cache_indexes+=cache_info->columns;
+ }
+ }
+ return(MagickPass);
+ }
+ /*
+ Read indexes from disk.
+ */
+ LockSemaphoreInfo(cache_info->file_semaphore);
+ {
+ file=(cache_info->file != -1 ? cache_info->file :
+ open(cache_info->cache_filename,O_RDONLY | O_BINARY));
+ if (file != -1)
+ {
+ number_pixels=(magick_uint64_t) cache_info->columns*cache_info->rows;
+ for (y=0; y < (long) rows; y++)
+ {
+ if ((FilePositionRead(file,indexes,length,cache_info->offset+
+ number_pixels*sizeof(PixelPacket)+offset*
+ sizeof(IndexPacket))) <= 0)
+ break;
+ indexes+=nexus_info->region.width;
+ offset+=cache_info->columns;
+ }
+ if (cache_info->file == -1)
+ (void) close(file);
+ if (QuantumTick(nexus_info->region.y,cache_info->rows))
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%lux%lu%+ld%+ld",
+ nexus_info->region.width,nexus_info->region.height,
+ nexus_info->region.x,nexus_info->region.y);
+ }
+ }
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
+ if (file == -1)
+ return(MagickFail);
+ return(y == (long) rows);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d C a c h e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadCachePixels() reads pixels from the specified region of the pixel cache.
+%
+% The format of the ReadCachePixels() method is:
+%
+% MagickPassFail ReadCachePixels(const Cache cache,
+% const NexusInfo *nexus_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: ReadCachePixels() returns MagickPass if the pixels are
+% successfully read from the pixel cache, otherwise MagickFail.
+%
+% o cache: Specifies a pointer to a CacheInfo structure.
+%
+% o nexus_info: specifies which cache nexus to read the pixels.
+%
+% o exception: any exception is reported here.
+%
+%
+*/
+static MagickPassFail
+ReadCachePixels(const Cache cache,const NexusInfo *nexus_info,
+ ExceptionInfo *exception)
+{
+ CacheInfo
+ *cache_info;
+
+ magick_uint64_t
+ number_pixels;
+
+ magick_off_t
+ offset;
+
+ int
+ file;
+
+ register long
+ y;
+
+ register PixelPacket
+ *pixels;
+
+ size_t
+ length;
+
+ unsigned long
+ rows;
+
+ ARG_NOT_USED(exception);
+ assert(cache != (Cache) NULL);
+ /* printf("ReadCachePixels\n"); */
+ cache_info=(CacheInfo *) cache;
+ assert(cache_info->signature == MagickSignature);
+ if (nexus_info->in_core)
+ return(MagickPass);
+ offset=nexus_info->region.y*(magick_off_t) cache_info->columns;
+ if ((long) (offset/cache_info->columns) != nexus_info->region.y)
+ return MagickFail;
+ offset += nexus_info->region.x;
+ length=nexus_info->region.width*sizeof(PixelPacket);
+ if (length/sizeof(PixelPacket) != nexus_info->region.width)
+ return MagickFail;
+ rows=nexus_info->region.height;
+ number_pixels=(magick_uint64_t) length*rows;
+ if ((length ==0) || (number_pixels/length != rows))
+ return MagickFail;
+ if ((cache_info->columns == nexus_info->region.width) &&
+ (number_pixels == (size_t) number_pixels))
+ {
+ length=number_pixels;
+ rows=1;
+ }
+ y=0;
+ pixels=nexus_info->pixels;
+ if (cache_info->type != DiskCache)
+ {
+ /*
+ Read pixels from memory.
+ */
+ register const PixelPacket
+ *cache_pixels;
+
+ cache_pixels=cache_info->pixels+offset;
+ if (length < 257)
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ register long
+ x;
+
+ for (x=0; x < (long) nexus_info->region.width; x++)
+ *pixels++=cache_pixels[x];
+ cache_pixels+=cache_info->columns;
+ }
+ }
+ else
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ (void) memcpy(pixels,cache_pixels,length);
+ pixels+=nexus_info->region.width;
+ cache_pixels+=cache_info->columns;
+ }
+ }
+ return(MagickPass);
+ }
+ /*
+ Read pixels from disk.
+ */
+ LockSemaphoreInfo(cache_info->file_semaphore);
+ {
+ file=(cache_info->file != -1 ? cache_info->file :
+ open(cache_info->cache_filename,O_RDONLY | O_BINARY));
+ if (file != -1)
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ if ((FilePositionRead(file,pixels,length,
+ cache_info->offset+offset*
+ sizeof(PixelPacket))) < (ssize_t) length)
+ break;
+ pixels+=nexus_info->region.width;
+ offset+=cache_info->columns;
+ }
+ if (cache_info->file == -1)
+ (void) close(file);
+ if (QuantumTick(nexus_info->region.y,cache_info->rows))
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%lux%lu%+ld%+ld",
+ nexus_info->region.width,nexus_info->region.height,
+ nexus_info->region.x,nexus_info->region.y);
+ }
+ }
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
+ if (file == -1)
+ return(MagickFail);
+ return(y == (long) rows);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e f e r e n c e C a c h e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReferenceCache() increments the reference count associated with the pixel
+% cache returning a pointer to the cache.
+%
+% The format of the ReferenceCache method is:
+%
+% Cache ReferenceCache(Cache cache_info)
+%
+% A description of each parameter follows:
+%
+% o cache_info: The cache_info.
+%
+%
+*/
+Cache
+ReferenceCache(Cache cache_info)
+{
+ assert(cache_info != (_CacheInfoPtr_) NULL);
+ assert(cache_info->signature == MagickSignature);
+ LockSemaphoreInfo(cache_info->reference_semaphore);
+ cache_info->reference_count++;
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "reference (reference count now %ld) %.1024s",
+ cache_info->reference_count, cache_info->filename);
+ UnlockSemaphoreInfo(cache_info->reference_semaphore);
+ return(cache_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S e t C a c h e N e x u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetCacheNexus() allocates an area to store image pixels as defined by the
+% region rectangle and returns a pointer to the area. This area is
+% subsequently transferred from the pixel cache with SyncCacheNexus(). A
+% pointer to the pixels is returned if the pixels are transferred, otherwise
+% a NULL is returned.
+%
+% The format of the SetCacheNexus() method is:
+%
+% PixelPacket *SetCacheNexus(Image *image,const long x,const long y,
+% const unsigned long columns,const unsigned long rows,
+% NexusInfo *nexus_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o pixels: SetCacheNexus() returns a pointer to the pixels if they are
+% transferred, otherwise a NULL is returned.
+%
+% o image: The image.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o nexus_info: specifies which cache nexus to set.
+%
+% o exception: any error is reported here.
+%
+*/
+static PixelPacket *
+SetCacheNexus(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ NexusInfo *nexus_info,ExceptionInfo *exception)
+{
+ PixelPacket
+ *pixels;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ pixels=(PixelPacket *) NULL;
+ if (ModifyCache(image,exception) != MagickFail)
+ {
+ magick_off_t
+ offset;
+
+ CacheInfo
+ *cache_info;
+
+ /*
+ Validate pixel cache geometry.
+ */
+ assert(image->cache != (Cache) NULL);
+ cache_info=(CacheInfo *) image->cache;
+ offset=y*(magick_off_t) cache_info->columns+x;
+ if (offset >= 0)
+ {
+ magick_uint64_t
+ number_pixels;
+ number_pixels=(magick_uint64_t) cache_info->columns*cache_info->rows;
+ offset+=(rows-1)*(magick_off_t) cache_info->columns+columns-1;
+ if ((magick_uint64_t) offset < number_pixels)
+ {
+ RectangleInfo
+ region;
+
+ /*
+ Return pixel cache.
+ */
+ region.x=x;
+ region.y=y;
+ region.width=columns;
+ region.height=rows;
+ pixels=SetNexus(image,&region,nexus_info,exception);
+ }
+ }
+ }
+ return pixels;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t C a c h e V i e w P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetCacheViewPixels() gets pixels from the in-memory or disk pixel cache as
+% defined by the geometry parameters. A pointer to the pixels is returned
+% if the pixels are transferred, otherwise a NULL is returned.
+%
+% The format of the SetCacheViewPixels method is:
+%
+% PixelPacket *SetCacheViewPixels(const ViewInfo *view,const long x,
+% const long y,const unsigned long columns,const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o view: The address of a structure of type ViewInfo.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o exception: Any errors are reported here.
+%
+*/
+MagickExport PixelPacket *
+SetCacheViewPixels(const ViewInfo *view,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ ExceptionInfo *exception)
+{
+ const View
+ *view_info = (const View *) view;
+
+ assert(view_info != (const View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ return SetCacheNexus(view_info->image,x,y,columns,rows,
+ view_info->nexus_info,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImagePixels() initializes a pixel region for write-only access.
+% If the region is successfully intialized a pointer to a PixelPacket
+% array representing the region is returned, otherwise NULL is returned.
+% The returned pointer may point to a temporary working buffer for the
+% pixels or it may point to the final location of the pixels in memory.
+%
+% Write-only access means that any existing pixel values corresponding to
+% the region are ignored. This is useful while the initial image is being
+% created from scratch, or if the existing pixel values are to be
+% completely replaced without need to refer to their pre-existing values.
+% The application is free to read and write the pixel buffer returned by
+% SetImagePixels() any way it pleases. SetImagePixels() does not initialize
+% the pixel array values. Initializing pixel array values is the
+% application's responsibility.
+%
+% Performance is maximized if the selected area is part of one row, or
+% one or more full rows, since then there is opportunity to access the
+% pixels in-place (without a copy) if the image is in RAM, or in a
+% memory-mapped file. The returned pointer should *never* be deallocated
+% by the user.
+%
+% Pixels accessed via the returned pointer represent a simple array of type
+% PixelPacket. If the image storage class is PsudeoClass, call GetIndexes()
+% after invoking GetImagePixels() to obtain the colormap indexes (of type
+% IndexPacket) corresponding to the region. Once the PixelPacket (and/or
+% IndexPacket) array has been updated, the changes must be saved back to
+% the underlying image using SyncCacheNexus() or they may be lost.
+%
+% The format of the SetImagePixels() method is:
+%
+% PixelPacket *SetImagePixels(Image *image,const long x,const long y,
+% const unsigned long columns,const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o pixels: SetImagePixels returns a pointer to the pixels if they are
+% transferred, otherwise a NULL is returned.
+%
+% o image: The image.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+%
+*/
+MagickExport PixelPacket *
+SetImagePixels(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return SetCacheViewPixels(AccessDefaultCacheView(image),
+ x,y,columns,rows,&image->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e P i x e l s E x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImagePixelsEx() initializes a pixel region for write-only access.
+% It is similar to SetImagePixels() except that any exception information
+% is written to a user provided exception structure.
+%
+% The format of the SetImagePixelsEx() method is:
+%
+% PixelPacket *SetImagePixelsEx(Image *image,const long x,const long y,
+% const unsigned long columns,const unsigned long rows,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o pixels: SetImagePixelsEx returns a pointer to the pixels if they are
+% transferred, otherwise a NULL is returned.
+%
+% o image: The image.
+%
+% o x,y,columns,rows: These values define the perimeter of a region of
+% pixels.
+%
+% o exception: Any error details are reported here.
+%
+%
+*/
+MagickExport PixelPacket *
+SetImagePixelsEx(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ ExceptionInfo *exception)
+{
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return SetCacheViewPixels(AccessDefaultCacheView(image),
+ x,y,columns,rows,exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e V i r t u a l P i x e l M e t h o d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageVirtualPixelMethod() sets the "virtual pixels" method for the
+% image. A virtual pixel is any pixel access that is outside the boundaries
+% of the image cache.
+%
+% The format of the SetImageVirtualPixelMethod() method is:
+%
+% SetImageVirtualPixelMethod(const Image *image,
+% const VirtualPixelMethod method)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o type: choose from these access types:
+%
+% EdgeVPType: the edge pixels of the image extend infinitely.
+% Any pixel outside the image is assigned the same value as the
+% pixel at the edge closest to it.
+%
+% TileVPType: the image extends periodically or tiled. The pixels
+% wrap around the edges of the image.
+%
+% MirrorVPType: mirror the image at the boundaries.
+%
+% ConstantVPType: every value outside the image is a constant as
+% defines by the pixel parameter.
+%
+%
+*/
+MagickExport MagickPassFail
+SetImageVirtualPixelMethod(const Image *image,
+ const VirtualPixelMethod method)
+{
+ CacheInfo
+ *cache_info;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(image->cache != (Cache) NULL);
+ cache_info=(CacheInfo *) image->cache;
+ assert(cache_info->signature == MagickSignature);
+ cache_info->virtual_pixel_method=method;
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S e t N e x u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetNexus() defines the region of the cache for the specified cache nexus.
+%
+% The format of the SetNexus() method is:
+%
+% PixelPacket *SetNexus(const Image *image,const RectangleInfo *region,
+% NexusInfo *nexus_info,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o pixels: SetNexus() returns a pointer to the pixels associated with
+% the specified cache nexus.
+%
+% o image: The image.
+%
+% o nexus_info: specifies which cache nexus to set.
+%
+% o region: A pointer to the RectangleInfo structure that defines the
+% region of this particular cache nexus.
+%
+% o exception: any error is reported here.
+%
+%
+*/
+static PixelPacket *
+SetNexus(const Image *image,const RectangleInfo *region,
+ NexusInfo *nexus_info,ExceptionInfo *exception)
+{
+ const CacheInfo
+ * restrict cache_info;
+
+ magick_uint64_t
+ number_pixels;
+
+ size_t
+ length,
+ packet_size;
+
+ ARG_NOT_USED(exception);
+ assert(image != (const Image *) NULL);
+ cache_info=(const CacheInfo *) image->cache;
+ assert(cache_info->signature == MagickSignature);
+ nexus_info->region=*region;
+ if ((cache_info->type != PingCache) && (cache_info->type != DiskCache) &&
+ (image->clip_mask == (const Image *) NULL))
+ {
+ magick_off_t
+ offset;
+
+ offset=nexus_info->region.y*(magick_off_t) cache_info->columns+nexus_info->region.x;
+ length=(nexus_info->region.height-1)*cache_info->columns+nexus_info->region.width-1;
+ number_pixels=(magick_uint64_t) cache_info->columns*cache_info->rows;
+ if ((offset >= 0) && (((magick_uint64_t) offset+length) < number_pixels))
+ if ((((nexus_info->region.x+nexus_info->region.width) <= cache_info->columns) &&
+ (nexus_info->region.height == 1)) ||
+ ((nexus_info->region.x == 0) &&
+ ((nexus_info->region.width % cache_info->columns) == 0)))
+ {
+ /*
+ Pixels are accessed directly from memory.
+ */
+ nexus_info->pixels=cache_info->pixels+offset;
+ nexus_info->indexes=(IndexPacket *) NULL;
+ if (cache_info->indexes_valid)
+ nexus_info->indexes=cache_info->indexes+offset;
+ nexus_info->in_core=IsNexusInCore(cache_info,nexus_info);
+ return(nexus_info->pixels);
+ }
+ }
+ /*
+ Pixels are stored in a staging area until they are synced to the cache.
+ */
+ number_pixels=(magick_uint64_t)
+ Max(nexus_info->region.width*nexus_info->region.height,cache_info->columns);
+ packet_size=sizeof(PixelPacket);
+ if (cache_info->indexes_valid)
+ packet_size+=sizeof(IndexPacket);
+ length=number_pixels*packet_size;
+ if ((length/packet_size == number_pixels) &&
+ ((nexus_info->staging == (PixelPacket *) NULL) ||
+ (nexus_info->staging_length < length)))
+ {
+ nexus_info->staging_length=0;
+ MagickFreeAlignedMemory(nexus_info->staging);
+ nexus_info->staging=MagickAllocateAlignedMemory(PixelPacket *,
+ MAGICK_CACHE_LINE_SIZE,
+ length);
+ if (nexus_info->staging != (PixelPacket *) NULL)
+ {
+ nexus_info->staging_length=length;
+ (void) memset((void *) nexus_info->staging,0,nexus_info->staging_length);
+ }
+ }
+ nexus_info->pixels=nexus_info->staging;
+ nexus_info->indexes=(IndexPacket *) NULL;
+ if ((cache_info->indexes_valid) &&
+ (nexus_info->pixels != (PixelPacket *) NULL))
+ nexus_info->indexes=(IndexPacket *) (nexus_info->pixels+number_pixels);
+ if (nexus_info->pixels == (PixelPacket *) NULL)
+ {
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "Failed to allocate %" MAGICK_SIZE_T_F
+ "u bytes for nexus staging "
+ "(number pixels=%" MAGICK_OFF_F "u, region width=%lu, "
+ "region height=%lu, cache columns=%lu)!",
+ (MAGICK_SIZE_T) length,
+ number_pixels,
+ nexus_info->region.width,
+ nexus_info->region.height,
+ cache_info->columns);
+ ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ }
+ nexus_info->in_core=IsNexusInCore(cache_info,nexus_info);
+
+ return(nexus_info->pixels);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S y n c C a c h e N e x u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SyncCacheNexus() saves the image pixels to the in-memory or disk cache.
+% The method returns MagickPass if the pixel region is synced, otherwise
+% MagickFail.
+%
+% The format of the SyncCacheNexus() method is:
+%
+% MagickPassFail SyncCacheNexus(Image *image,const NexusInfo *nexus_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: SyncCacheNexus() returns MagickPass if the image pixels are
+% transferred to the in-memory or disk cache otherwise MagickFail.
+%
+% o image: The image.
+%
+% o nexus: specifies which cache nexus to sync.
+%
+% o exception: any error is reported here.
+%
+*/
+static MagickPassFail
+SyncCacheNexus(Image *image,const NexusInfo *nexus_info,
+ ExceptionInfo *exception)
+{
+ MagickPassFail
+ status=MagickPass;
+
+ CacheInfo
+ *cache_info;
+
+ /*
+ Transfer pixels to the cache.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ cache_info=(CacheInfo *) image->cache;
+ if (cache_info == (CacheInfo *) NULL)
+ {
+ ThrowException(exception,CacheError,PixelCacheIsNotOpen,image->filename);
+ status=MagickFail;
+ }
+ else if (nexus_info->in_core)
+ {
+ status=MagickPass;
+ }
+ else
+ {
+ if (image->clip_mask != (Image *) NULL)
+ if (!ClipCacheNexus(image,nexus_info))
+ status=MagickFail;
+
+ if (status != MagickFail)
+ if ((status=WriteCachePixels(cache_info,nexus_info)) == MagickFail)
+ ThrowException(exception,CacheError,UnableToSyncCache,
+ image->filename);
+
+ if (status != MagickFail)
+ if (cache_info->indexes_valid)
+ if ((status=WriteCacheIndexes(cache_info,nexus_info)) == MagickFail)
+ ThrowException(exception,CacheError,UnableToSyncCache,
+ image->filename);
+ }
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S y n c C a c h e V i e w P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SyncCacheViewPixels() saves the view pixels to the in-memory or disk cache.
+% The method returns MagickPass if the pixel region is synced, otherwise
+% MagickFail.
+%
+% The format of the SyncCacheViewPixels method is:
+%
+% MagickPassFail SyncCacheViewPixels(const ViewInfo *view,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o view: The address of a structure of type ViewInfo.
+%
+% o exception: Any errors are reported here.
+%
+*/
+MagickExport MagickPassFail
+SyncCacheViewPixels(const ViewInfo *view,ExceptionInfo *exception)
+{
+ View
+ *view_info = (View *) view;
+
+ MagickPassFail
+ status;
+
+ assert(view_info != (View *) NULL);
+ assert(view_info->signature == MagickSignature);
+ status=SyncCacheNexus(view_info->image,view_info->nexus_info,exception);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S y n c I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SyncImagePixels() saves the image pixels to the in-memory or disk cache.
+% The method returns MagickPass if the pixel region is synced, otherwise MagickFail.
+%
+% The format of the SyncImagePixels() method is:
+%
+% MagickPassFail SyncImagePixels(Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: SyncImagePixels() returns MagickPass if the image pixels are
+% transferred to the in-memory or disk cache otherwise MagickFail.
+%
+% o image: The image.
+%
+*/
+MagickExport MagickPassFail
+SyncImagePixels(Image *image)
+{
+ assert (image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return SyncCacheViewPixels(AccessDefaultCacheView(image),
+ &image->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S y n c I m a g e P i x e l s E x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SyncImagePixelsEx() saves the image pixels to the in-memory or disk cache.
+% The method returns MagickPass if the pixel region is synced, otherwise
+% MagickFail.
+%
+% The format of the SyncImagePixelsEx() method is:
+%
+% MagickPassFail SyncImagePixelsEx(Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: SyncImagePixelsEx() returns MagickPass if the image pixels are
+% transferred to the in-memory or disk cache otherwise MagickFail.
+%
+% o image: The image.
+%
+% o exception: Any error details are reported here.
+%
+*/
+MagickExport MagickPassFail
+SyncImagePixelsEx(Image *image,ExceptionInfo *exception)
+{
+ assert (image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ return SyncCacheViewPixels(AccessDefaultCacheView(image),exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e C a c h e I n d e x e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteCacheIndexes() writes the colormap indexes to the specified region of
+% the pixel cache.
+%
+% The format of the WriteCacheIndexes() method is:
+%
+% MagickPassFail WriteCacheIndexes(Cache cache,const NexusInfo *nexus_info)
+%
+% A description of each parameter follows:
+%
+% o status: WriteCacheIndexes() returns MagickPass if the indexes are
+% successfully written to the pixel cache, otherwise MagickFail.
+%
+% o cache: Specifies a pointer to a CacheInfo structure.
+%
+% o nexus: specifies which cache nexus to write the colormap indexes.
+%
+%
+*/
+static MagickPassFail
+WriteCacheIndexes(Cache cache,const NexusInfo *nexus_info)
+{
+ CacheInfo
+ *cache_info;
+
+ magick_uint64_t
+ number_pixels;
+
+ magick_off_t
+ offset;
+
+ int
+ file;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ y;
+
+ size_t
+ length;
+
+ unsigned long
+ rows;
+
+ assert(cache != (Cache) NULL);
+ cache_info=(CacheInfo *) cache;
+ assert(cache_info->signature == MagickSignature);
+ if (!cache_info->indexes_valid)
+ return(MagickFail);
+ if (nexus_info->in_core)
+ return(MagickPass);
+ offset=nexus_info->region.y*(magick_off_t) cache_info->columns+nexus_info->region.x;
+ length=nexus_info->region.width*sizeof(IndexPacket);
+ rows=nexus_info->region.height;
+ number_pixels=(magick_uint64_t) length*rows;
+ y=0;
+ indexes=nexus_info->indexes;
+ if (cache_info->type != DiskCache)
+ {
+ register IndexPacket
+ *cache_indexes;
+
+ /*
+ Coalesce rows into larger write request if possible.
+ */
+ if ((cache_info->columns == nexus_info->region.width) &&
+ (number_pixels == (size_t) number_pixels))
+ {
+ length=number_pixels;
+ rows=1;
+ }
+
+ /*
+ Write indexes to memory.
+ */
+ cache_indexes=cache_info->indexes+offset;
+ if (length < 257)
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ register long
+ x;
+
+ for (x=0; x < (long) nexus_info->region.width; x++)
+ cache_indexes[x]=*indexes++;
+ cache_indexes+=cache_info->columns;
+ }
+ }
+ else
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ (void) memcpy(cache_indexes,indexes,length);
+ indexes+=nexus_info->region.width;
+ cache_indexes+=cache_info->columns;
+ }
+ }
+ return(MagickPass);
+ }
+ /*
+ Write indexes to disk.
+ */
+ LockSemaphoreInfo(cache_info->file_semaphore);
+ {
+ file=cache_info->file;
+ if (cache_info->file == -1)
+ {
+ /* FIXME: open */
+ file=open(cache_info->cache_filename,O_WRONLY | O_BINARY | O_EXCL,S_MODE);
+ if (file == -1)
+ file=open(cache_info->cache_filename,O_WRONLY | O_BINARY,S_MODE);
+ }
+ if (file != -1)
+ {
+ magick_off_t
+ row_offset;
+
+ ssize_t
+ bytes_written;
+
+ number_pixels=(magick_uint64_t) cache_info->columns*cache_info->rows;
+ row_offset=cache_info->offset+number_pixels*sizeof(PixelPacket)+offset
+ *sizeof(IndexPacket);
+ for (y=0; y < (long) rows; y++)
+ {
+ if ((bytes_written=FilePositionWrite(file,indexes,length,row_offset))
+ < (long) length)
+ {
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "Failed to write row %ld at file offset %" MAGICK_OFF_F
+ "d. Wrote %" MAGICK_SSIZE_T_F "d rather than %"
+ MAGICK_SIZE_T_F "u bytes (%s).",
+ y,
+ row_offset,
+ (MAGICK_SSIZE_T) bytes_written,
+ (MAGICK_SIZE_T) length,
+ strerror(errno));
+ break;
+ }
+ indexes+=nexus_info->region.width;
+ offset+=cache_info->columns;
+ }
+ if (cache_info->file == -1)
+ (void) close(file);
+ if (QuantumTick(nexus_info->region.y,cache_info->rows))
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%lux%lu%+ld%+ld",
+ nexus_info->region.width,nexus_info->region.height,
+ nexus_info->region.x,nexus_info->region.y);
+ }
+ }
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
+ if (file == -1)
+ return MagickFail;
+ return(y == (long) rows);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ W r i t e C a c h e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% WriteCachePixels() writes image pixels to the specified region of the pixel
+% cache.
+%
+% The format of the WriteCachePixels() method is:
+%
+% MagickPassFail WriteCachePixels(Cache cache,const NexusInfo *nexus_info)
+%
+% A description of each parameter follows:
+%
+% o status: WriteCachePixels() returns MagickPass if the pixels are
+% successfully written to the cache, otherwise MagickFail.
+%
+% o cache: Specifies a pointer to a Cache structure.
+%
+% o nexus: specifies which cache nexus to write the pixels.
+%
+%
+*/
+static MagickPassFail
+WriteCachePixels(Cache cache,const NexusInfo *nexus_info)
+{
+ CacheInfo
+ *cache_info;
+
+ magick_uint64_t
+ number_pixels;
+
+ magick_off_t
+ offset;
+
+ int
+ file;
+
+ register long
+ y;
+
+ register PixelPacket
+ *pixels;
+
+ size_t
+ length;
+
+ unsigned long
+ rows;
+
+ assert(cache != (Cache) NULL);
+ cache_info=(CacheInfo *) cache;
+ assert(cache_info->signature == MagickSignature);
+ if (nexus_info->in_core)
+ return(MagickPass);
+ offset=nexus_info->region.y*(magick_off_t) cache_info->columns+nexus_info->region.x;
+ length=nexus_info->region.width*sizeof(PixelPacket);
+ rows=nexus_info->region.height;
+ number_pixels=(magick_uint64_t) length*rows;
+ y=0;
+ pixels=nexus_info->pixels;
+ if (cache_info->type != DiskCache)
+ {
+ register PixelPacket
+ *cache_pixels;
+
+ /*
+ Coalesce rows into larger write request if possible.
+ */
+ if ((cache_info->columns == nexus_info->region.width) &&
+ (number_pixels == (size_t) number_pixels))
+ {
+ length=number_pixels;
+ rows=1;
+ }
+
+ /*
+ Write pixels to memory.
+ */
+ cache_pixels=cache_info->pixels+offset;
+ if (length < 257)
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ register long
+ x;
+
+ for (x=0; x < (long) nexus_info->region.width; x++)
+ cache_pixels[x]=*pixels++;
+ cache_pixels+=cache_info->columns;
+ }
+ }
+ else
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ (void) memcpy(cache_pixels,pixels,length);
+ pixels+=nexus_info->region.width;
+ cache_pixels+=cache_info->columns;
+ }
+ }
+ return(MagickPass);
+ }
+ /*
+ Write pixels to disk.
+ */
+ LockSemaphoreInfo(cache_info->file_semaphore);
+ {
+ file=cache_info->file;
+ if (cache_info->file == -1)
+ {
+ file=open(cache_info->cache_filename,O_WRONLY | O_BINARY | O_EXCL,S_MODE);
+ if (file == -1)
+ file=open(cache_info->cache_filename,O_WRONLY | O_BINARY,S_MODE);
+ }
+ if (file != -1)
+ {
+ for (y=0; y < (long) rows; y++)
+ {
+ magick_off_t
+ row_offset;
+
+ ssize_t
+ bytes_written;
+
+ row_offset=cache_info->offset+offset*sizeof(PixelPacket);
+ if ((bytes_written=FilePositionWrite(file,pixels,length,row_offset))
+ < (ssize_t) length)
+ {
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),
+ "Failed to write row %ld at file offset %"
+ MAGICK_OFF_F "d. Wrote %"
+ MAGICK_SSIZE_T_F "d rather than %"
+ MAGICK_SIZE_T_F "u bytes (%s).",
+ y,
+ row_offset,
+ (MAGICK_SSIZE_T) bytes_written,
+ (MAGICK_SIZE_T) length,
+ strerror(errno));
+ break;
+ }
+ pixels+=nexus_info->region.width;
+ offset+=cache_info->columns;
+ }
+ if (cache_info->file == -1)
+ (void) close(file);
+ if (QuantumTick(nexus_info->region.y,cache_info->rows))
+ (void) LogMagickEvent(CacheEvent,GetMagickModule(),"%lux%lu%+ld%+ld",
+ nexus_info->region.width,nexus_info->region.height,
+ nexus_info->region.x,nexus_info->region.y);
+ }
+ }
+ UnlockSemaphoreInfo(cache_info->file_semaphore);
+ if (file == -1)
+ return(MagickFail);
+ return(y == (long) rows);
+}
diff --git a/magick/pixel_cache.h b/magick/pixel_cache.h
new file mode 100644
index 0000000..959006a
--- /dev/null
+++ b/magick/pixel_cache.h
@@ -0,0 +1,391 @@
+/*
+ Copyright (C) 2003 - 2015 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Pixel Cache Methods.
+*/
+#ifndef _MAGICK_CACHE_H
+#define _MAGICK_CACHE_H
+
+#include "magick/forward.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ /*
+ Enum declaractions.
+ */
+
+ typedef enum
+ {
+ UndefinedVirtualPixelMethod,
+ ConstantVirtualPixelMethod,
+ EdgeVirtualPixelMethod,
+ MirrorVirtualPixelMethod,
+ TileVirtualPixelMethod
+ } VirtualPixelMethod;
+
+ /*
+ Typedef declaractions.
+ */
+ typedef _CacheInfoPtr_ Cache;
+
+ /*****
+ *
+ * Default View interfaces
+ *
+ *****/
+
+ /*
+ Read only access to a rectangular pixel region.
+ */
+ MagickExport const PixelPacket
+ *AcquireImagePixels(const Image *image,const long x,const long y,
+ const unsigned long columns,
+ const unsigned long rows,ExceptionInfo *exception);
+
+ /*
+ AccessImmutableIndexes() returns the read-only indexes
+ associated with a rectangular pixel region already selected via
+ AcquireImagePixels().
+ */
+ extern MagickExport const IndexPacket
+ *AccessImmutableIndexes(const Image *image);
+
+ /*
+ Return one DirectClass pixel at the the specified (x,y) location.
+ Similar function as GetOnePixel(). Note that the value returned
+ by GetIndexes() may or may not be influenced by this function.
+ */
+ extern MagickExport PixelPacket
+ AcquireOnePixel(const Image *image,const long x,const long y,
+ ExceptionInfo *exception);
+
+
+ /*
+ GetImagePixels() and GetImagePixelsEx() obtains a pixel region for
+ read/write access.
+ */
+ extern MagickExport PixelPacket
+ *GetImagePixels(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows);
+ extern MagickExport PixelPacket
+ *GetImagePixelsEx(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ ExceptionInfo *exception);
+
+ /*
+ GetImageVirtualPixelMethod() gets the "virtual pixels" method for
+ the image.
+ */
+ extern MagickExport VirtualPixelMethod
+ GetImageVirtualPixelMethod(const Image *image);
+
+ /*
+ GetPixels() and AccessMutablePixels() return the pixels associated
+ with the last call to SetImagePixels() or GetImagePixels().
+ */
+ extern MagickExport PixelPacket
+ *GetPixels(const Image *image);
+ extern MagickExport PixelPacket
+ *AccessMutablePixels(Image *image);
+
+ /*
+ GetIndexes() and AccessMutableIndexes() return the colormap
+ indexes associated with the last call to SetImagePixels() or
+ GetImagePixels().
+ */
+ extern MagickExport IndexPacket
+ *GetIndexes(const Image *image);
+ extern MagickExport IndexPacket
+ *AccessMutableIndexes(Image *image);
+
+ /*
+ GetOnePixel() returns a single DirectClass pixel at the specified
+ (x,y) location. Similar to AcquireOnePixel(). It is preferred to
+ use AcquireOnePixel() since it allows reporting to a specified
+ exception structure. Note that the value returned by GetIndexes()
+ is not reliably influenced by this function.
+ */
+ extern MagickExport PixelPacket
+ GetOnePixel(Image *image,const long x,const long y);
+
+ /*
+ GetPixelCacheArea() returns the area (width * height in pixels)
+ consumed by the current pixel cache.
+ */
+ extern MagickExport magick_off_t
+ GetPixelCacheArea(const Image *image);
+
+ /*
+ SetImagePixels() and SetImagePixelsEx() initialize a pixel region
+ for write-only access.
+ */
+ extern MagickExport PixelPacket
+ *SetImagePixels(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows);
+ extern MagickExport PixelPacket
+ *SetImagePixelsEx(Image *image,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ ExceptionInfo *exception);
+
+ /*
+ SetImageVirtualPixelMethod() sets the "virtual pixels" method for
+ the image.
+ */
+ extern MagickExport MagickPassFail
+ SetImageVirtualPixelMethod(const Image *image,
+ const VirtualPixelMethod method);
+
+ /*
+ SyncImagePixels() and SyncImagePixelsEx() save the image pixels to
+ the in-memory or disk cache.
+ */
+ extern MagickExport MagickPassFail
+ SyncImagePixels(Image *image);
+ extern MagickExport MagickPassFail
+ SyncImagePixelsEx(Image *image,ExceptionInfo *exception);
+
+ /****
+ *
+ * Cache view interfaces
+ *
+ ****/
+
+ /*
+ OpenCacheView() opens a cache view.
+ */
+ extern MagickExport ViewInfo
+ *OpenCacheView(Image *image);
+
+ /*
+ CloseCacheView() closes a cache view.
+ */
+ extern MagickExport void
+ CloseCacheView(ViewInfo *view);
+
+
+ /*
+ AccessCacheViewPixels() returns the pixels associated with the
+ last request to select a view pixel region
+ (i.e. AcquireCacheViewPixels() or GetCacheViewPixels()).
+ */
+ extern MagickExport PixelPacket
+ *AccessCacheViewPixels(const ViewInfo *view);
+
+ /*
+ AcquireCacheViewIndexes() returns read-only indexes associated
+ with a cache view.
+ */
+ extern MagickExport const IndexPacket
+ *AcquireCacheViewIndexes(const ViewInfo *view);
+
+ /*
+ AcquireCacheViewPixels() obtains a pixel region from a cache view
+ for read-only access.
+ */
+ extern MagickExport const PixelPacket
+ *AcquireCacheViewPixels(const ViewInfo *view,
+ const long x,const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ ExceptionInfo *exception);
+
+ /*
+ AcquireOneCacheViewPixel() returns one DirectClass pixel from a
+ cache view. Note that the value returned by GetCacheViewIndexes()
+ is not reliably influenced by this function.
+ */
+ extern MagickExport MagickPassFail
+ AcquireOneCacheViewPixel(const ViewInfo *view,PixelPacket *pixel,
+ const long x,const long y,ExceptionInfo *exception);
+
+ /*
+ GetCacheViewArea() returns the area (width * height in pixels)
+ currently consumed by the pixel cache view.
+ */
+ extern MagickExport magick_off_t
+ GetCacheViewArea(const ViewInfo *view);
+
+ /*
+ GetCacheViewImage() obtains the image used to allocate the cache view.
+ */
+ extern Image *
+ GetCacheViewImage(const ViewInfo *view);
+
+ /*
+ GetCacheViewIndexes() returns the indexes associated with a cache view.
+ */
+ extern MagickExport IndexPacket
+ *GetCacheViewIndexes(const ViewInfo *view);
+
+ /*
+ GetCacheViewPixels() obtains a pixel region from a cache view for
+ read/write access.
+ */
+ extern MagickExport PixelPacket
+ *GetCacheViewPixels(const ViewInfo *view,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ ExceptionInfo *exception);
+
+ /*
+ Obtain the offset and size of the selected region.
+ */
+ extern MagickExport RectangleInfo
+ GetCacheViewRegion(const ViewInfo *view);
+
+
+ /*
+ SetCacheViewPixels() gets blank writeable pixels from the pixel
+ cache view.
+ */
+ extern MagickExport PixelPacket
+ *SetCacheViewPixels(const ViewInfo *view,const long x,const long y,
+ const unsigned long columns,const unsigned long rows,
+ ExceptionInfo *exception);
+
+ /*
+ SyncCacheViewPixels() saves any changes to the pixel cache view.
+ */
+ extern MagickExport MagickPassFail
+ SyncCacheViewPixels(const ViewInfo *view,ExceptionInfo *exception);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+ /****
+ *
+ * Private interfaces.
+ *
+ ****/
+
+ /*
+ Access the default view
+ */
+ extern MagickExport ViewInfo
+ *AccessDefaultCacheView(const Image *image);
+
+ /*
+ Destroy a thread view set.
+ */
+ extern MagickExport void
+ DestroyThreadViewSet(_ThreadViewSetPtr_ view_set);
+
+ /*
+ Allocate a thread view set.
+ */
+ extern MagickExport _ThreadViewSetPtr_
+ AllocateThreadViewSet(Image *image,ExceptionInfo *exception);
+
+ /*
+ Return one pixel at the the specified (x,y) location via a pointer
+ reference.
+ */
+ extern MagickExport MagickPassFail
+ AcquireOnePixelByReference(const Image *image,PixelPacket *pixel,
+ const long x,const long y,
+ ExceptionInfo *exception);
+
+ /*
+ DestroyImagePixels() deallocates memory associated with the pixel cache.
+
+ Used only by DestroyImage().
+ */
+ extern MagickExport void
+ DestroyImagePixels(Image *image);
+
+ /*
+ DestroyCacheInfo() deallocates memory associated with the pixel
+ cache.
+
+ Used only by DestroyImageInfo() to destroy a pixel cache
+ associated with ImageInfo.
+ */
+ extern void
+ DestroyCacheInfo(Cache cache);
+
+ /*
+ GetCacheInfo() initializes the Cache structure.
+
+ Used only by AllocateImage() and CloneImage().
+ */
+ extern void
+ GetCacheInfo(Cache *cache);
+
+ /*
+ GetPixelCacheInCore() tests to see the pixel cache is based on
+ allocated memory and therefore supports efficient random access.
+ */
+ extern MagickBool
+ GetPixelCacheInCore(const Image *image);
+
+ /*
+ GetPixelCachePresent() tests to see the pixel cache is present
+ and contains pixels.
+ */
+ extern MagickExport MagickBool
+ GetPixelCachePresent(const Image *image);
+
+ /*
+ Obtain an interpolated pixel value via bi-linear interpolation.
+ */
+ extern MagickExport PixelPacket
+ InterpolateColor(const Image *image,const double x_offset,
+ const double y_offset,ExceptionInfo *exception)
+ MAGICK_FUNC_DEPRECATED;
+
+ extern MagickExport void
+ InterpolateViewColor(const ViewInfo *view,PixelPacket *color,
+ const double x_offset,const double y_offset,
+ ExceptionInfo *exception);
+
+ /*
+ Modify cache ensures that there is only one reference to the
+ pixel cache so that it may be safely modified.
+ */
+ extern MagickPassFail
+ ModifyCache(Image *image, ExceptionInfo *exception);
+
+ /*
+ PersistCache() attaches to or initializes a persistent pixel cache.
+
+ Used only by ReadMPCImage() and WriteMPCImage().
+ */
+ extern MagickExport MagickPassFail
+ PersistCache(Image *image,const char *filename,const MagickBool attach,
+ magick_off_t *offset,ExceptionInfo *exception);
+
+ /*
+ ReferenceCache() increments the reference count associated with
+ the pixel cache. Thread safe.
+
+ Used only by CloneImage() and CloneImageInfo().
+ */
+ extern Cache
+ ReferenceCache(Cache cache);
+
+ /*
+ Check image dimensions to see if they exceed current limits.
+ */
+ extern MagickExport MagickPassFail
+ CheckImagePixelLimits(const Image *image, ExceptionInfo *exception);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_CACHE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/pixel_iterator.c b/magick/pixel_iterator.c
new file mode 100644
index 0000000..e11e612
--- /dev/null
+++ b/magick/pixel_iterator.c
@@ -0,0 +1,1320 @@
+/*
+ Copyright (C) 2004-2016 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Interfaces to support simple iterative pixel read/update access
+ within an image or between two images. These interfaces exist in
+ order to eliminate large amounts of redundant code and to allow
+ changing the underlying implementation without changing the using
+ code. These interfaces intentionally omit any pixel position
+ information in order to not constrain the implementation and to
+ improve performance.
+
+ User-provided callbacks must be thread-safe (preferably re-entrant) since
+ they may be invoked by multiple threads.
+
+ These interfaces have proven to be future safe (since implemented)
+ and may be safely used by other applications/libraries.
+
+ Written by Bob Friesenhahn, March 2004, Updated for rows 2008.
+
+*/
+
+#include "magick/studio.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/pixel_iterator.h"
+#include "magick/utility.h"
+
+/*
+ Obtain the maximum numer of threads to use based on image storage
+ type, region size, and user options. The maximum number of threads
+ which may be used is that reported by omp_get_max_threads(). The
+ number of threads to be used is returned.
+*/
+#if defined(HAVE_OPENMP)
+static int
+GetRegionThreads(const PixelIteratorOptions *options,
+ const MagickBool in_core,
+ const unsigned long columns,
+ const unsigned long rows)
+{
+ static const unsigned long
+ tiny_region_metric = 64;
+
+ int
+ max_threads,
+ region_threads;
+
+ max_threads=omp_get_max_threads();
+ region_threads=max_threads;
+
+ if (((columns <= tiny_region_metric && rows <= tiny_region_metric)) ||
+ ((magick_uint64_t) columns*rows <= tiny_region_metric*tiny_region_metric) ||
+ (MagickFalse == in_core))
+ {
+ /*
+ Run tiny or non-memory-based regions single threaded.
+ */
+ region_threads=1;
+ }
+ else if ((options) && (options->max_threads > 0))
+ {
+ /*
+ Allow the user to specify the number of threads, up to the
+ current limit.
+ */
+ region_threads=Min(max_threads,options->max_threads);
+ }
+
+ return region_threads;
+}
+#endif
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n i t i a l i z e P i x e l I t e r a t o r O p t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializePixelIteratorOptions() assigns default options to a user-provided
+% PixelIteratorOptions structure. This function should always be used
+% to initialize the PixelIteratorOptions structure prior to making any
+% changes to it.
+%
+% The format of the InitializePixelIteratorOptions method is:
+%
+% void InitializePixelIteratorOptions(PixelIteratorOptions *options,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o options: pointer to PixelIteratorOptions structure to initialize.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport void
+InitializePixelIteratorOptions(PixelIteratorOptions *options,
+ ExceptionInfo *exception)
+{
+ ARG_NOT_USED(exception);
+ assert(options != (PixelIteratorOptions *) NULL);
+ options->max_threads=0;
+ options->signature=MagickSignature;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l I t e r a t e M o n o R e a d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelIterateMonoRead() iterates through a region of an image and invokes a
+% user-provided callback function (of type PixelRowIteratorMonoReadCallback)
+% for a row of pixels. This is useful to support simple operations such as
+% statistics computation.
+%
+% The format of the PixelIterateMonoRead method is:
+%
+% MagickPassFail PixelIterateMonoRead(
+% PixelIteratorMonoReadCallback call_back,
+% const PixelIteratorOptions *options,
+% const char *description,
+% void *mutable_data,
+% const void *immutable_data,
+% const long x,
+% const long y,
+% const unsigned long columns,
+% const unsigned long rows,
+% const Image *image,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o call_back: A user-provided C callback function which is passed the
+% address of pixels from the image.
+%
+% o options: Pixel iterator execution options (may be NULL).
+%
+% o description: textual description of operation being performed.
+%
+% o mutable_data: User-provided mutable context data.
+%
+% o immutable_data: User-provided immutable context data.
+%
+% o x: The horizontal ordinate of the top left corner of the region.
+%
+% o y: The vertical ordinate of the top left corner of the region.
+%
+% o columns: Width of pixel region
+%
+% o rows: Height of pixel region
+%
+% o image: The address of the Image.
+%
+% o exception: If an error is reported, this argument is updated with the reason.
+%
+*/
+MagickExport MagickPassFail
+PixelIterateMonoRead(PixelIteratorMonoReadCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const long x,
+ const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *image,
+ ExceptionInfo *exception)
+{
+ MagickPassFail
+ status = MagickPass;
+
+ register long
+ row;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+ int num_threads=GetRegionThreads(options,GetPixelCacheInCore(image),columns,rows);
+#else
+ (void) options;
+#endif /* defined(HAVE_OPENMP) */
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(static,1) shared(row_count, status)
+# endif
+#endif
+ for (row=y; row < (long) (y+rows); row++)
+ {
+ MagickPassFail
+ thread_status;
+
+ const PixelPacket
+ * restrict pixels;
+
+ const IndexPacket
+ * restrict indexes;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateMonoRead)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ pixels=AcquireImagePixels(image,x, row, columns, 1, exception);
+ if (!pixels)
+ thread_status=MagickFail;
+ indexes=AccessImmutableIndexes(image);
+
+ if (thread_status != MagickFail)
+ thread_status=(call_back)(mutable_data,immutable_data,image,pixels,indexes,columns,exception);
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateMonoRead)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,rows))
+ if (!MagickMonitorFormatted(row_count,rows,exception,
+ description,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l I t e r a t e M o n o S e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelIterateMonoSet() iterates through a region of an image and invokes
+% a user-provided callback function (of type PixelIteratorMonoModifyCallback)
+% to initialize a region of pixels from scratch. The difference from
+% PixelIterateMonoModify() is that the output pixels are not initialized
+% from the underlying store so it is more efficient when outputting a new
+% image or when the existing pixels are intentionally discarded. This is
+% useful for operations such as setting the pixel color.
+%
+% The format of the PixelIterateMonoSet method is:
+%
+% MagickPassFail PixelIterateMonoSet(
+% PixelIteratorMonoModifyback call_back,
+% const PixelIteratorOptions *options,
+% const char *description,
+% void *mutable_data,
+% const void *immutable_data,
+% const long x,
+% const long y,
+% const unsigned long columns,
+% const unsigned long rows,
+% Image *image,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o call_back: A user-provided C callback function which is passed the
+% address of pixels to be initialized in the image.
+%
+% o options: Pixel iterator execution options (may be NULL).
+%
+% o description: textual description of operation being performed.
+%
+% o mutable_data: User-provided mutable context data.
+%
+% o immutable_data: User-provided immutable context data.
+%
+% o x: The horizontal ordinate of the top left corner of the region.
+%
+% o y: The vertical ordinate of the top left corner of the region.
+%
+% o columns: Width of pixel region
+%
+% o rows: Height of pixel region
+%
+% o image: The address of the Image.
+%
+% o exception: If an error is reported, this argument is updated with the reason.
+%
+*/
+static MagickPassFail
+PixelIterateMonoModifyImplementation(PixelIteratorMonoModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const long x,
+ const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ Image *image,
+ ExceptionInfo *exception,
+ MagickBool set)
+{
+ MagickPassFail
+ status = MagickPass;
+
+ register long
+ row;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+ int num_threads=GetRegionThreads(options,GetPixelCacheInCore(image),columns,rows);
+#else
+ (void) options;
+#endif /* defined(HAVE_OPENMP) */
+
+ if (ModifyCache(image,exception) == MagickFail)
+ return MagickFail;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(static,1) shared(row_count, status)
+# endif
+#endif
+ for (row=y; row < (long) (y+rows); row++)
+ {
+ MagickBool
+ thread_status;
+
+ PixelPacket
+ * restrict pixels;
+
+ IndexPacket
+ * restrict indexes;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateMonoModify)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ if (set)
+ pixels=SetImagePixelsEx(image, x, row, columns, 1, exception);
+ else
+ pixels=GetImagePixelsEx(image, x, row, columns, 1, exception);
+ if (!pixels)
+ thread_status=MagickFail;
+ indexes=AccessMutableIndexes(image);
+
+ if (thread_status != MagickFail)
+ thread_status=(call_back)(mutable_data,immutable_data,image,pixels,indexes,columns,exception);
+
+ if (thread_status != MagickFail)
+ if (!SyncImagePixelsEx(image,exception))
+ thread_status=MagickFail;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateMonoModify)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,rows))
+ if (!MagickMonitorFormatted(row_count,rows,exception,
+ description,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ return (status);
+}
+
+MagickExport MagickPassFail
+PixelIterateMonoSet(PixelIteratorMonoModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const long x,
+ const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ Image *image,
+ ExceptionInfo *exception)
+{
+ return PixelIterateMonoModifyImplementation(call_back,
+ options,
+ description,
+ mutable_data,
+ immutable_data,
+ x,
+ y,
+ columns,
+ rows,
+ image,
+ exception,
+ MagickTrue);
+ }
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l I t e r a t e M o n o M o d i f y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelIterateMonoModify() iterates through a region of an image and invokes
+% a user-provided callback function (of type PixelIteratorMonoModifyCallback)
+% to modify a region of pixels. This is useful to support simple operations
+% such as level shifting, colorspace translation, or thresholding.
+%
+% The format of the PixelIterateMonoModify method is:
+%
+% MagickPassFail PixelIterateMonoModify(
+% PixelIteratorMonoModifyCallback call_back,
+% const PixelIteratorOptions *options,
+% const char *description,
+% void *mutable_data,
+% const void *immutable_data,
+% const long x,
+% const long y,
+% const unsigned long columns,
+% const unsigned long rows,
+% Image *image,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o call_back: A user-provided C callback function which is passed the
+% address of pixels from the image.
+%
+% o options: Pixel iterator execution options (may be NULL).
+%
+% o description: textual description of operation being performed.
+%
+% o mutable_data: User-provided mutable context data.
+%
+% o immutable_data: User-provided immutable context data.
+%
+% o x: The horizontal ordinate of the top left corner of the region.
+%
+% o y: The vertical ordinate of the top left corner of the region.
+%
+% o columns: Width of pixel region
+%
+% o rows: Height of pixel region
+%
+% o image: The address of the Image.
+%
+% o exception: If an error is reported, this argument is updated with the reason.
+%
+*/
+MagickExport MagickPassFail
+PixelIterateMonoModify(PixelIteratorMonoModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const long x,
+ const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ Image *image,
+ ExceptionInfo *exception)
+{
+ return PixelIterateMonoModifyImplementation(call_back,
+ options,
+ description,
+ mutable_data,
+ immutable_data,
+ x,
+ y,
+ columns,
+ rows,
+ image,
+ exception,
+ MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l I t e r a t e D u a l R e a d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelIterateDualRead() iterates through pixel regions of two images and
+% invokes a user-provided callback function (of type
+% PixelIteratorDualReadCallback) for each row of pixels. This is useful to
+% support operations such as image comparison.
+%
+% The format of the PixelIterateDualRead method is:
+%
+% MagickPassFail PixelIterateDualRead(
+% PixelIteratorDualReadCallback call_back,
+% const PixelIteratorOptions *options,
+% const char *description,
+% void *mutable_data,
+% const void *immutable_data,
+% const unsigned long columns,
+% const unsigned long rows,
+% const Image *first_image,
+% const long first_x,
+% const long first_y,
+% const Image *second_image,
+% const long second_x,
+% const long second_y,
+% ExceptionInfo *exception);
+%
+% A description of each parameter follows:
+%
+% o call_back: A user-provided C callback function which is passed the
+% address of pixels from each image.
+%
+% o options: Pixel iterator execution options (may be NULL).
+%
+% o description: textual description of operation being performed.
+%
+% o mutable_data: User-provided mutable context data.
+%
+% o immutable_data: User-provided immutable context data.
+%
+% o columns: Width of pixel region
+%
+% o rows: Height of pixel region
+%
+% o first_image: The address of the first Image.
+%
+% o first_x: The horizontal ordinate of the top left corner of the first region.
+%
+% o first_y: The vertical ordinate of the top left corner of the first region.
+%
+% o second_image: The address of the second Image.
+%
+% o second_x: The horizontal ordinate of the top left corner of the second region.
+%
+% o second_y: The vertical ordinate of the top left corner of the second region.
+%
+% o exception: If an error is reported, this argument is updated with the reason.
+%
+*/
+MagickExport MagickPassFail
+PixelIterateDualRead(PixelIteratorDualReadCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *first_image,
+ const long first_x,
+ const long first_y,
+ const Image *second_image,
+ const long second_x,
+ const long second_y,
+ ExceptionInfo *exception)
+{
+ MagickPassFail
+ status = MagickPass;
+
+ register long
+ row;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+ int num_threads=GetRegionThreads(options,
+ (GetPixelCacheInCore(first_image) &&
+ GetPixelCacheInCore(second_image)),
+ columns,rows);
+#else
+ (void) options;
+#endif /* defined(HAVE_OPENMP) */
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(static,1) shared(row_count, status)
+# endif
+#endif
+ for (row=0; row < (long) rows; row++)
+ {
+ MagickBool
+ thread_status;
+
+ long
+ first_row,
+ second_row;
+
+ const PixelPacket
+ * restrict first_pixels,
+ * restrict second_pixels;
+
+ const IndexPacket
+ * restrict first_indexes,
+ * restrict second_indexes;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateDualRead)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ first_row=first_y+row;
+ second_row=second_y+row;
+
+ first_pixels=AcquireImagePixels(first_image, first_x, first_row,
+ columns, 1, exception);
+ if (!first_pixels)
+ thread_status=MagickFail;
+ first_indexes=AccessImmutableIndexes(first_image);
+
+ second_pixels=AcquireImagePixels(second_image, second_x, second_row,
+ columns, 1, exception);
+ if (!second_pixels)
+ thread_status=MagickFail;
+ second_indexes=AccessImmutableIndexes(second_image);
+
+ if (thread_status != MagickFail)
+ thread_status=(call_back)(mutable_data,immutable_data,
+ first_image,first_pixels,first_indexes,
+ second_image,second_pixels,second_indexes,
+ columns, exception);
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateDualRead)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,rows))
+ if (!MagickMonitorFormatted(row_count,rows,exception,
+ description,first_image->filename,
+ second_image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l I t e r a t e D u a l M o d i f y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelIterateDualModify() iterates through pixel regions of two images and
+% invokes a user-provided callback function (of type
+% PixelIteratorDualModifyCallback) for each row of pixels. This is useful to
+% support operations such as composition.
+%
+% The format of the PixelIterateDualModify method is:
+%
+% MagickPassFail PixelIterateDualModify(
+% PixelIteratorDualModifyCallback call_back,
+% const PixelIteratorOptions *options,
+% const char *description,
+% void *mutable_data,
+% const void *immutable_data,
+% const unsigned long columns,
+% const unsigned long rows,
+% const Image *source_image,
+% const long source_x,
+% const long source_y,
+% Image *update_image,
+% const long update_x,
+% const long update_y,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o call_back: A user-provided C callback function which reads from
+% a region of source pixels and updates a region of destination pixels.
+%
+% o options: Pixel iterator execution options (may be NULL).
+%
+% o description: textual description of operation being performed.
+%
+% o mutable_data: User-provided mutable context data.
+%
+% o immutable_data: User-provided immutable context data.
+%
+% o columns: Width of pixel region
+%
+% o rows: Height of pixel region
+%
+% o source_image: The address of the constant source Image.
+%
+% o source_x: The horizontal ordinate of the top left corner of the source region.
+%
+% o source_y: The vertical ordinate of the top left corner of the source region.
+%
+% o update_image: The address of the update Image.
+%
+% o update_x: The horizontal ordinate of the top left corner of the update region.
+%
+% o update_y: The vertical ordinate of the top left corner of the update region.
+%
+% o exception: If an error is reported, this argument is updated with the reason.
+%
+*/
+static MagickPassFail
+PixelIterateDualImplementation(PixelIteratorDualModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source_image,
+ const long source_x,
+ const long source_y,
+ Image *update_image,
+ const long update_x,
+ const long update_y,
+ ExceptionInfo *exception,
+ MagickBool set)
+{
+ MagickPassFail
+ status = MagickPass;
+
+ register long
+ row;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+ int num_threads=GetRegionThreads(options,
+ (GetPixelCacheInCore(source_image) &&
+ GetPixelCacheInCore(update_image)),
+ columns,rows);
+#else
+ (void) options;
+#endif /* defined(HAVE_OPENMP) */
+
+ if (ModifyCache(update_image,exception) == MagickFail)
+ return MagickFail;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(static,1) shared(row_count, status)
+# endif
+#endif
+ for (row=0; row < (long) rows; row++)
+ {
+ MagickBool
+ thread_status;
+
+ const PixelPacket
+ * restrict source_pixels;
+
+ const IndexPacket
+ * restrict source_indexes;
+
+ PixelPacket
+ * restrict update_pixels;
+
+ IndexPacket
+ * restrict update_indexes;
+
+ register long
+ source_row,
+ update_row;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateDualImplementation)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ source_row=source_y+row;
+ update_row=update_y+row;
+
+ source_pixels=AcquireImagePixels(source_image, source_x, source_row,
+ columns, 1, exception);
+ if (!source_pixels)
+ thread_status=MagickFail;
+ source_indexes=AccessImmutableIndexes(source_image);
+
+ if (set)
+ update_pixels=SetImagePixelsEx(update_image, update_x, update_row,
+ columns, 1, exception);
+ else
+ update_pixels=GetImagePixelsEx(update_image, update_x, update_row,
+ columns, 1, exception);
+ if (!update_pixels)
+ thread_status=MagickFail;
+ update_indexes=AccessMutableIndexes(update_image);
+
+ if (thread_status != MagickFail)
+ thread_status=(call_back)(mutable_data,immutable_data,
+ source_image,source_pixels,source_indexes,
+ update_image,update_pixels,update_indexes,
+ columns,exception);
+
+ if (thread_status != MagickFail)
+ if (!SyncImagePixelsEx(update_image,exception))
+ thread_status=MagickFail;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateDualImplementation)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,rows))
+ if (!MagickMonitorFormatted(row_count,rows,exception,
+ description,source_image->filename,
+ update_image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ return (status);
+}
+
+MagickExport MagickPassFail
+PixelIterateDualModify(PixelIteratorDualModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source_image,
+ const long source_x,
+ const long source_y,
+ Image *update_image,
+ const long update_x,
+ const long update_y,
+ ExceptionInfo *exception)
+{
+ return PixelIterateDualImplementation
+ (call_back,options,description,mutable_data,immutable_data,columns,rows,
+ source_image,source_x,source_y,update_image,update_x,update_y,exception,
+ MagickFalse);
+}
+
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l I t e r a t e D u a l N e w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelIterateDualNew() iterates through pixel regions of two images and
+% invokes a user-provided callback function (of type
+% PixelIteratorDualNewCallback) for each row of pixels. This is used if a
+% new output image is created based on an input image. The difference from
+% PixelIterateDualModify() is that the output pixels are not initialized so
+% it is more efficient when outputting a new image.
+%
+% The format of the PixelIterateDualNew method is:
+%
+% MagickPassFail PixelIterateDualNew(
+% PixelIteratorDualNewCallback call_back,
+% const PixelIteratorOptions *options,
+% const char *description,
+% void *mutable_data,
+% const void *immutable_data,
+% const unsigned long columns,
+% const unsigned long rows,
+% const Image *source_image,
+% const long source_x,
+% const long source_y,
+% Image *new_image,
+% const long new_x,
+% const long new_y,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o call_back: A user-provided C callback function which reads from
+% a region of source pixels and initializes a region of destination pixels.
+%
+% o options: Pixel iterator execution options (may be NULL).
+%
+% o description: textual description of operation being performed.
+%
+% o mutable_data: User-provided mutable context data.
+%
+% o immutable_data: User-provided immutable context data.
+%
+% o columns: Width of pixel region
+%
+% o rows: Height of pixel region
+%
+% o source_image: The address of the constant source Image.
+%
+% o source_x: The horizontal ordinate of the top left corner of the source region.
+%
+% o source_y: The vertical ordinate of the top left corner of the source region.
+%
+% o new_image: The address of the new Image.
+%
+% o new_x: The horizontal ordinate of the top left corner of the new region.
+%
+% o new_y: The vertical ordinate of the top left corner of the new region.
+%
+% o exception: If an error is reported, this argument is updated with the reason.
+%
+*/
+MagickExport MagickPassFail
+PixelIterateDualNew(PixelIteratorDualNewCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source_image,
+ const long source_x,
+ const long source_y,
+ Image *new_image,
+ const long new_x,
+ const long new_y,
+ ExceptionInfo *exception)
+{
+ return PixelIterateDualImplementation
+ (call_back,options,description,mutable_data,immutable_data,columns,rows,
+ source_image,source_x,source_y,new_image,new_x,new_y,exception,
+ MagickTrue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l I t e r a t e T r i p l e M o d i f y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelIterateTripleModify() iterates through pixel regions of three images
+% and invokes a user-provided callback function (of type
+% PixelIteratorTripleModifyCallback) for each row of pixels. The first two
+% images are read-only, while the third image is read-write for update.
+% Access of the first two images is done lock-step using the same coordinates.
+% This is useful to support operations such as image differencing.
+%
+% The format of the PixelIterateTripleModify method is:
+%
+% MagickPassFail PixelIterateTripleModify(
+% PixelIteratorTripleModifyCallback call_back,
+% const PixelIteratorOptions *options,
+% const char *description,
+% void *mutable_data,
+% const void *immutable_data,
+% const unsigned long columns,
+% const unsigned long rows,
+% const Image *source1_image,
+% const Image *source2_image,
+% const long source_x,
+% const long source_y,
+% Image *update_image,
+% const long update_x,
+% const long update_y,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o call_back: A user-provided C callback function which reads from
+% a region of source pixels and updates a region of destination pixels.
+%
+% o options: Pixel iterator execution options (may be NULL).
+%
+% o description: textual description of operation being performed.
+%
+% o mutable_data: User-provided mutable context data.
+%
+% o immutable_data: User-provided immutable context data.
+%
+% o columns: Width of pixel region
+%
+% o rows: Height of pixel region
+%
+% o source1_image: The address of the constant source 1 Image.
+%
+% o source2_image: The address of the constant source 2 Image.
+%
+% o source_x: The horizontal ordinate of the top left corner of the source regions.
+%
+% o source_y: The vertical ordinate of the top left corner of the source regions.
+%
+% o update_image: The address of the update Image.
+%
+% o update_x: The horizontal ordinate of the top left corner of the update region.
+%
+% o update_y: The vertical ordinate of the top left corner of the update region.
+%
+% o exception: If an error is reported, this argument is updated with the reason.
+%
+*/
+static MagickPassFail
+PixelIterateTripleImplementation(PixelIteratorTripleModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source1_image,
+ const Image *source2_image,
+ const long source_x,
+ const long source_y,
+ Image *update_image,
+ const long update_x,
+ const long update_y,
+ ExceptionInfo *exception,
+ MagickBool set)
+{
+ MagickPassFail
+ status = MagickPass;
+
+ register long
+ row;
+
+ unsigned long
+ row_count=0;
+
+#if defined(HAVE_OPENMP)
+ int num_threads=GetRegionThreads(options,
+ (GetPixelCacheInCore(source1_image) &&
+ GetPixelCacheInCore(source2_image) &&
+ GetPixelCacheInCore(update_image)),
+ columns,rows);
+#else
+ (void) options;
+#endif /* defined(HAVE_OPENMP) */
+
+ if (ModifyCache(update_image,exception) == MagickFail)
+ return MagickFail;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for if(num_threads > 1) num_threads(num_threads) schedule(static,1) shared(row_count, status)
+#endif
+#endif
+ for (row=0; row < (long) rows; row++)
+ {
+ MagickBool
+ thread_status;
+
+ const PixelPacket
+ * restrict source1_pixels,
+ * restrict source2_pixels;
+
+ const IndexPacket
+ * restrict source1_indexes,
+ * restrict source2_indexes;
+
+ PixelPacket
+ * restrict update_pixels;
+
+ IndexPacket
+ * restrict update_indexes;
+
+ long
+ source_row,
+ update_row;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateTripleImplementation)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ source_row=source_y+row;
+ update_row=update_y+row;
+
+ /*
+ First image (read only).
+ */
+ source1_pixels=AcquireImagePixels(source1_image, source_x, source_row,
+ columns, 1, exception);
+ if (!source1_pixels)
+ thread_status=MagickFail;
+ source1_indexes=AccessImmutableIndexes(source1_image);
+
+ /*
+ Second image (read only).
+ */
+ source2_pixels=AcquireImagePixels(source2_image, source_x, source_row,
+ columns, 1, exception);
+ if (!source2_pixels)
+ thread_status=MagickFail;
+ source2_indexes=AccessImmutableIndexes(source2_image);
+
+ /*
+ Third image (read/write).
+ */
+ if (set)
+ update_pixels=SetImagePixelsEx(update_image, update_x, update_row,
+ columns, 1, exception);
+ else
+ update_pixels=GetImagePixelsEx(update_image, update_x, update_row,
+ columns, 1, exception);
+ if (!update_pixels)
+ {
+ thread_status=MagickFail;
+ CopyException(exception,&update_image->exception);
+ }
+ update_indexes=AccessMutableIndexes(update_image);
+
+ if (thread_status != MagickFail)
+ thread_status=(call_back)(mutable_data,immutable_data,
+ source1_image,source1_pixels,source1_indexes,
+ source2_image,source2_pixels,source2_indexes,
+ update_image,update_pixels,update_indexes,
+ columns,exception);
+
+ if (thread_status != MagickFail)
+ if (!SyncImagePixelsEx(update_image,exception))
+ thread_status=MagickFail;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_PixelIterateTripleImplementation)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,rows))
+ if (!MagickMonitorFormatted(row_count,rows,exception,description,
+ source1_image->filename,
+ source2_image->filename,
+ update_image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ return (status);
+}
+
+MagickExport MagickPassFail
+PixelIterateTripleModify(PixelIteratorTripleModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source1_image,
+ const Image *source2_image,
+ const long source_x,
+ const long source_y,
+ Image *update_image,
+ const long update_x,
+ const long update_y,
+ ExceptionInfo *exception)
+{
+ return PixelIterateTripleImplementation
+ (call_back,options,description,mutable_data,immutable_data,columns,rows,
+ source1_image,source2_image,source_x,source_y,
+ update_image,update_x,update_y,
+ exception,MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l I t e r a t e T r i p l e N e w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelIterateTripleNew() iterates through pixel regions of three images
+% and invokes a user-provided callback function (of type
+% PixelIteratorTripleNewCallback) for each row of pixels. The first two
+% images are read-only, while the third image is read-write for update.
+% Access of the first two images is done lock-step using the same coordinates.
+% This is used if a new output image is created based on two input images.
+% The difference from PixelIterateTripleModify() is that the output pixels
+% are not initialized so it is more efficient when outputting a new image.
+%
+% The format of the PixelIterateTripleNew method is:
+%
+% MagickPassFail PixelIterateTripleNew(
+% PixelIteratorTripleNewCallback call_back,
+% const PixelIteratorOptions *options,
+% const char *description,
+% void *mutable_data,
+% const void *immutable_data,
+% const unsigned long columns,
+% const unsigned long rows,
+% const Image *source1_image,
+% const Image *source2_image,
+% const long source_x,
+% const long source_y,
+% Image *new_image,
+% const long new_x,
+% const long new_y,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o call_back: A user-provided C callback function which reads from
+% a region of source pixels and initializes a region of destination pixels.
+%
+% o options: Pixel iterator execution options (may be NULL).
+%
+% o description: textual description of operation being performed.
+%
+% o mutable_data: User-provided mutable context data.
+%
+% o immutable_data: User-provided immutable context data.
+%
+% o columns: Width of pixel region
+%
+% o rows: Height of pixel region
+%
+% o source1_image: The address of the constant source 1 Image.
+%
+% o source2_image: The address of the constant source 2 Image.
+%
+% o source_x: The horizontal ordinate of the top left corner of the source regions.
+%
+% o source_y: The vertical ordinate of the top left corner of the source regions.
+%
+% o new_image: The address of the new Image.
+%
+% o new_x: The horizontal ordinate of the top left corner of the new region.
+%
+% o new_y: The vertical ordinate of the top left corner of the new region.
+%
+% o exception: If an error is reported, this argument is updated with the reason.
+%
+*/
+MagickExport MagickPassFail
+PixelIterateTripleNew(PixelIteratorTripleNewCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source1_image,
+ const Image *source2_image,
+ const long source_x,
+ const long source_y,
+ Image *new_image,
+ const long new_x,
+ const long new_y,
+ ExceptionInfo *exception)
+{
+ return PixelIterateTripleImplementation
+ (call_back,options,description,mutable_data,immutable_data,columns,rows,
+ source1_image,source2_image,source_x,source_y,
+ new_image,new_x,new_y,
+ exception,MagickTrue);
+}
diff --git a/magick/pixel_iterator.h b/magick/pixel_iterator.h
new file mode 100644
index 0000000..749f286
--- /dev/null
+++ b/magick/pixel_iterator.h
@@ -0,0 +1,289 @@
+/*
+ Copyright (C) 2004-2016 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Interfaces to support simple iterative pixel read/update access within an
+ image or between two images. These interfaces exist in order to eliminate
+ large amounts of redundant code and to allow changing the underlying
+ implementation without changing the using code. These interfaces
+ intentionally omit any pixel position information in order to not constrain
+ the implementation and to improve performance.
+
+ User-provided callbacks must be thread-safe (preferably re-entrant) since
+ they may be invoked by multiple threads.
+
+ These interfaces have proven to be future safe (since implemented) and may
+ be safely used by other applications/libraries.
+
+ Written by Bob Friesenhahn, March 2004, Updated for regions 2008.
+
+*/
+#ifndef _PIXEL_ROW_ITERATOR_H
+#define _PIXEL_ROW_ITERATOR_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+ /*
+ Pixel iterator options.
+ */
+ typedef struct _PixelIteratorOptions
+ {
+ int max_threads; /* Desired number of threads */
+ unsigned long signature;
+ } PixelIteratorOptions;
+
+
+ /*
+ Initialize pixel iterator options with defaults.
+ */
+ extern MagickExport void
+ InitializePixelIteratorOptions(PixelIteratorOptions *options,
+ ExceptionInfo *exception);
+
+ /*
+ Read-only access across pixel region.
+ */
+
+ typedef MagickPassFail (*PixelIteratorMonoReadCallback)
+ (
+ void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *const_image, /* Input image */
+ const PixelPacket *pixels, /* Pixel row */
+ const IndexPacket *indexes, /* Pixel indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ );
+
+ extern MagickExport MagickPassFail
+ PixelIterateMonoRead(PixelIteratorMonoReadCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const long x,
+ const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *image,
+ ExceptionInfo *exception);
+
+
+ typedef MagickPassFail (*PixelIteratorMonoModifyCallback)
+ (
+ void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ );
+
+ /*
+ Write access across pixel region.
+ */
+ extern MagickExport MagickPassFail
+ PixelIterateMonoSet(PixelIteratorMonoModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const long x,
+ const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ Image *image,
+ ExceptionInfo *exception);
+
+ /*
+ Read-write access across pixel region.
+ */
+ extern MagickExport MagickPassFail
+ PixelIterateMonoModify(PixelIteratorMonoModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const long x,
+ const long y,
+ const unsigned long columns,
+ const unsigned long rows,
+ Image *image,
+ ExceptionInfo *exception);
+
+ /*
+ Read-only access across pixel regions of two images.
+ */
+
+ typedef MagickPassFail (*PixelIteratorDualReadCallback)
+ (
+ void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *first_image, /* First Input image */
+ const PixelPacket *first_pixels, /* Pixel row in first image */
+ const IndexPacket *first_indexes, /* Pixel row indexes in first image */
+ const Image *second_image, /* Second Input image */
+ const PixelPacket *second_pixels, /* Pixel row in second image */
+ const IndexPacket *second_indexes, /* Pixel row indexes in second image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ );
+
+ extern MagickExport MagickPassFail
+ PixelIterateDualRead(PixelIteratorDualReadCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *first_image,
+ const long first_x,
+ const long first_y,
+ const Image *second_image,
+ const long second_x,
+ const long second_y,
+ ExceptionInfo *exception);
+
+ /*
+ Read-write access across pixel regions of two images. The first
+ (source) image is accessed read-only while the second (update)
+ image is accessed as read-write.
+ */
+
+ typedef MagickPassFail (*PixelIteratorDualModifyCallback)
+ (
+ void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source_image, /* Source image */
+ const PixelPacket *source_pixels, /* Pixel row in source image */
+ const IndexPacket *source_indexes, /* Pixel row indexes in source image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ );
+
+ extern MagickExport MagickPassFail
+ PixelIterateDualModify(PixelIteratorDualModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source_image,
+ const long source_x,
+ const long source_y,
+ Image *update_image,
+ const long update_x,
+ const long update_y,
+ ExceptionInfo *exception);
+
+ /*
+ Read-write access across pixel regions of two images. The first
+ (source) image is accessed read-only while the second (new)
+ image is accessed for write (uninitialized pixels).
+ */
+ typedef PixelIteratorDualModifyCallback PixelIteratorDualNewCallback;
+
+ extern MagickExport MagickPassFail
+ PixelIterateDualNew(PixelIteratorDualNewCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source_image,
+ const long source_x,
+ const long source_y,
+ Image *new_image,
+ const long new_x,
+ const long new_y,
+ ExceptionInfo *exception);
+
+ /*
+ Read-read-write access across pixel regions of three images. The
+ first two images are accessed read-only while the third is
+ accessed as read-write.
+ */
+
+ typedef MagickPassFail (*PixelIteratorTripleModifyCallback)
+ (
+ void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ const Image *source1_image, /* Source 1 image */
+ const PixelPacket *source1_pixels, /* Pixel row in source 1 image */
+ const IndexPacket *source1_indexes, /* Pixel row indexes in source 1 image */
+ const Image *source2_image, /* Source 2 image */
+ const PixelPacket *source2_pixels, /* Pixel row in source 2 image */
+ const IndexPacket *source2_indexes, /* Pixel row indexes in source 2 image */
+ Image *update_image, /* Update image */
+ PixelPacket *update_pixels, /* Pixel row in update image */
+ IndexPacket *update_indexes, /* Pixel row indexes in update image */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception /* Exception report */
+ );
+
+ extern MagickExport MagickPassFail
+ PixelIterateTripleModify(PixelIteratorTripleModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source1_image,
+ const Image *source2_image,
+ const long source_x,
+ const long source_y,
+ Image *update_image,
+ const long update_x,
+ const long update_y,
+ ExceptionInfo *exception);
+
+ /*
+ Read-write access across pixel regions of two images. The first
+ (source) image is accessed read-only while the second (new)
+ image is accessed for write (uninitialized pixels).
+ */
+ typedef PixelIteratorTripleModifyCallback PixelIteratorTripleNewCallback;
+
+ extern MagickExport MagickPassFail
+ PixelIterateTripleNew(PixelIteratorTripleNewCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description,
+ void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns,
+ const unsigned long rows,
+ const Image *source1_image,
+ const Image *source2_image,
+ const long source_x,
+ const long source_y,
+ Image *new_image,
+ const long new_x,
+ const long new_y,
+ ExceptionInfo *exception);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _PIXEL_ROW_ITERATOR_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/plasma.c b/magick/plasma.c
new file mode 100644
index 0000000..6c50e90
--- /dev/null
+++ b/magick/plasma.c
@@ -0,0 +1,222 @@
+/*
+% Copyright (C) 2003 - 2009 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% GraphicsMagick Plasma Methods.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/random.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% P l a s m a I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PlasmaImage() initializes an image with plasma fractal values. The image
+% must be initialized with a base color and the random number generator
+% seeded before this method is called.
+%
+% The format of the PlasmaImage method is:
+%
+% MagickPassFail PlasmaImage(Image *image,const SegmentInfo *segment,
+% unsigned long attenuate,unsigned long depth)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o segment: Define the region to apply plasma fractals values.
+%
+% o attenuate: Define the plasma attenuation factor.
+%
+% o depth: Limit the plasma recursion depth.
+%
+%
+*/
+
+static Quantum PlasmaPixel(const double pixel,const double noise)
+{
+ double
+ value;
+
+ value=pixel+noise*MagickRandomReal()-noise/2;
+ if (value <= 0.0)
+ return(0);
+ if (value >= MaxRGB)
+ return(MaxRGB);
+ return((Quantum) (value+0.5));
+}
+
+MagickExport MagickPassFail PlasmaImage(Image *image,const SegmentInfo *segment,
+ unsigned long attenuate,unsigned long depth)
+{
+ double
+ plasma;
+
+ long
+ x,
+ x_mid,
+ y,
+ y_mid;
+
+ PixelPacket
+ u,
+ v;
+
+ register PixelPacket
+ *q;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(segment != (SegmentInfo *) NULL);
+ if (depth != 0)
+ {
+ SegmentInfo
+ local_info;
+
+ /*
+ Divide the area into quadrants and recurse.
+ */
+ depth--;
+ attenuate++;
+ x_mid=(long) (segment->x1+segment->x2+0.5)/2;
+ y_mid=(long) (segment->y1+segment->y2+0.5)/2;
+ local_info=(*segment);
+ local_info.x2=x_mid;
+ local_info.y2=y_mid;
+ (void) PlasmaImage(image,&local_info,attenuate,depth);
+ local_info=(*segment);
+ local_info.y1=y_mid;
+ local_info.x2=x_mid;
+ (void) PlasmaImage(image,&local_info,attenuate,depth);
+ local_info=(*segment);
+ local_info.x1=x_mid;
+ local_info.y2=y_mid;
+ (void) PlasmaImage(image,&local_info,attenuate,depth);
+ local_info=(*segment);
+ local_info.x1=x_mid;
+ local_info.y1=y_mid;
+ return(PlasmaImage(image,&local_info,attenuate,depth));
+ }
+ if ((image->colorspace != RGBColorspace) ||
+ (image->storage_class != DirectClass))
+ {
+ (void) SetImageType(image,TrueColorType);
+ }
+ x_mid=(long) (segment->x1+segment->x2+0.5)/2;
+ y_mid=(long) (segment->y1+segment->y2+0.5)/2;
+ if ((segment->x1 == x_mid) && (segment->x2 == x_mid) &&
+ (segment->y1 == y_mid) && (segment->y2 == y_mid))
+ return(False);
+ /*
+ Average pixels and apply plasma.
+ */
+ plasma=MaxRGB/(2.0*attenuate);
+ if ((segment->x1 != x_mid) || (segment->x2 != x_mid))
+ {
+ /*
+ Left pixel.
+ */
+ x=(long) (segment->x1+0.5);
+ (void) AcquireOnePixelByReference(image,&u,x,(long) (segment->y1+0.5),&image->exception);
+ (void) AcquireOnePixelByReference(image,&v,x,(long) (segment->y2+0.5),&image->exception);
+ q=SetImagePixels(image,x,y_mid,1,1);
+ if (q == (PixelPacket *) NULL)
+ return(True);
+ q->red=PlasmaPixel(((double) u.red+v.red)/2,plasma);
+ q->green=PlasmaPixel(((double) u.green+v.green)/2,plasma);
+ q->blue=PlasmaPixel(((double) u.blue+v.blue)/2,plasma);
+ (void) SyncImagePixels(image);
+ if (segment->x1 != segment->x2)
+ {
+ /*
+ Right pixel.
+ */
+ x=(long) (segment->x2+0.5);
+ (void) AcquireOnePixelByReference(image,&u,x,(long) (segment->y1+0.5),&image->exception);
+ (void) AcquireOnePixelByReference(image,&v,x,(long) (segment->y2+0.5),&image->exception);
+ q=SetImagePixels(image,x,y_mid,1,1);
+ if (q == (PixelPacket *) NULL)
+ return(True);
+ q->red=PlasmaPixel(((double) u.red+v.red)/2,plasma);
+ q->green=PlasmaPixel(((double) u.green+v.green)/2,plasma);
+ q->blue=PlasmaPixel(((double) u.blue+v.blue)/2,plasma);
+ (void) SyncImagePixels(image);
+ }
+ }
+ if ((segment->y1 != y_mid) || (segment->y2 != y_mid))
+ {
+ if ((segment->x1 != x_mid) || (segment->y2 != y_mid))
+ {
+ /*
+ Bottom pixel.
+ */
+ y=(long) (segment->y2+0.5);
+ (void) AcquireOnePixelByReference(image,&u,(long) (segment->x1+0.5),y,&image->exception);
+ (void) AcquireOnePixelByReference(image,&v,(long) (segment->x2+0.5),y,&image->exception);
+ q=SetImagePixels(image,x_mid,y,1,1);
+ if (q == (PixelPacket *) NULL)
+ return(True);
+ q->red=PlasmaPixel(((double) u.red+v.red)/2,plasma);
+ q->green=PlasmaPixel(((double) u.green+v.green)/2,plasma);
+ q->blue=PlasmaPixel(((double) u.blue+v.blue)/2,plasma);
+ (void) SyncImagePixels(image);
+ }
+ if (segment->y1 != segment->y2)
+ {
+ /*
+ Top pixel.
+ */
+ y=(long) (segment->y1+0.5);
+ (void) AcquireOnePixelByReference(image,&u,(long) (segment->x1+0.5),y,&image->exception);
+ (void) AcquireOnePixelByReference(image,&v,(long) (segment->x2+0.5),y,&image->exception);
+ q=SetImagePixels(image,x_mid,y,1,1);
+ if (q == (PixelPacket *) NULL)
+ return(True);
+ q->red=PlasmaPixel(((double) u.red+v.red)/2,plasma);
+ q->green=PlasmaPixel(((double) u.green+v.green)/2,plasma);
+ q->blue=PlasmaPixel(((double) u.blue+v.blue)/2,plasma);
+ (void) SyncImagePixels(image);
+ }
+ }
+ if ((segment->x1 != segment->x2) || (segment->y1 != segment->y2))
+ {
+ /*
+ Middle pixel.
+ */
+ x=(long) (segment->x1+0.5);
+ y=(long) (segment->y1+0.5);
+ (void) AcquireOnePixelByReference(image,&u,x,y,&image->exception);
+ x=(long) (segment->x2+0.5);
+ y=(long) (segment->y2+0.5);
+ (void) AcquireOnePixelByReference(image,&v,x,y,&image->exception);
+ q=SetImagePixels(image,x_mid,y_mid,1,1);
+ if (q == (PixelPacket *) NULL)
+ return(True);
+ q->red=PlasmaPixel(((double) u.red+v.red)/2,plasma);
+ q->green=PlasmaPixel(((double) u.green+v.green)/2,plasma);
+ q->blue=PlasmaPixel(((double) u.blue+v.blue)/2,plasma);
+ (void) SyncImagePixels(image);
+ }
+ if (((segment->x2-segment->x1) < 3.0) && ((segment->y2-segment->y1) < 3.0))
+ return(True);
+ return(False);
+}
diff --git a/magick/plasma.h b/magick/plasma.h
new file mode 100644
index 0000000..9ce1470
--- /dev/null
+++ b/magick/plasma.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Plasma Methods.
+*/
+#ifndef _MAGICK_PLASMA_H
+#define _MAGICK_PLASMA_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/image.h"
+
+extern MagickExport MagickPassFail
+PlasmaImage(Image *image,const SegmentInfo *segment,
+ unsigned long attenuate,unsigned long depth);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_PLASMA_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/prefetch.h b/magick/prefetch.h
new file mode 100644
index 0000000..845441b
--- /dev/null
+++ b/magick/prefetch.h
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2010 - 2011 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+*/
+
+#ifndef _MAGICK_PREFETCH_H
+#define _MAGICK_PREFETCH_H
+
+/*
+ Prefetching pragmas and instrinsics support.
+
+ http://blogs.sun.com/solarisdev/entry/new_article_prefetching
+ http://gcc.gnu.org/projects/prefetch.html
+
+ http://blog.metawrap.com/blog/x86CachePrefetch.aspx
+ http://scripts.mit.edu/~birge/blog/accelerating-code-using-gccs-prefetch-extension/
+ http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Other-Builtins.html
+ http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html
+ http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Other-Builtins.html#Other-Builtins
+ http://docs.sun.com/app/docs/doc/820-7598/bjapp?a=view
+*/
+
+#if defined(HAVE_SUN_PREFETCH_H)
+# include <sun_prefetch.h>
+#endif /* defined(HAVE_SUN_PREFETCH_H) */
+
+/* Prefetch data that is likely to be read more than once */
+#if defined(sun_prefetch_read_many)
+# define MAGICK_PREFETCH_READ_MANY(address) sun_prefetch_read_many(address)
+#endif
+#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ >= 4)
+# define MAGICK_PREFETCH_READ_MANY(address) __builtin_prefetch(address,0,3)
+#endif
+
+/* Prefetch data that is likely to be read only once */
+#if defined(sun_prefetch_read_once)
+# define MAGICK_PREFETCH_READ_ONCE(address) sun_prefetch_read_once(address)
+#endif
+#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ >= 4)
+# define MAGICK_PREFETCH_READ_ONCE(address) __builtin_prefetch(address,0,0)
+#endif
+
+/* Prefetch data that is likely to be written more than once */
+#if defined(sun_prefetch_write_many)
+# define MAGICK_PREFETCH_WRITE_MANY(address) sun_prefetch_write_many(address)
+#endif
+#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ >= 4)
+# define MAGICK_PREFETCH_WRITE_MANY(address) __builtin_prefetch(address,1,3)
+#endif
+
+/* Prefetch data that is likely to be written only once */
+#if defined(sun_prefetch_write_once)
+# define MAGICK_PREFETCH_WRITE_ONCE(address) sun_prefetch_write_once(address)
+#endif
+#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ >= 4)
+# define MAGICK_PREFETCH_WRITE_ONCE(address) __builtin_prefetch(address,1,0)
+#endif
+
+#endif /* _MAGICK_PREFETCH_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/profile.c b/magick/profile.c
new file mode 100644
index 0000000..cfda041
--- /dev/null
+++ b/magick/profile.c
@@ -0,0 +1,1264 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP RRRR OOO FFFFF IIIII L EEEEE %
+% P P R R O O F I L E %
+% PPPP RRRR O O FFF I L EEE %
+% P R R O O F I L E %
+% P R R OOO F IIIII LLLLL EEEEE %
+% %
+% GraphicsMagick Image Profile Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% Bill Radcliffe %
+% Bob Friesenhahn %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/color.h"
+#include "magick/composite.h"
+#include "magick/log.h"
+#include "magick/map.h"
+#include "magick/monitor.h"
+#include "magick/omp_data_view.h"
+#include "magick/pixel_iterator.h"
+#include "magick/profile.h"
+#include "magick/quantize.h"
+#include "magick/resize.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#if defined(HasLCMS)
+# if defined(HAVE_LCMS2_LCMS2_H)
+# include <lcms2/lcms2.h>
+# elif defined(HAVE_LCMS2_H)
+# include <lcms2.h>
+# else
+# error "LCMS 2 header missing!"
+# endif
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A l l o c a t e I m a g e P r o f i l e I t e r a t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AllocateImageProfileIterator allocates an iterator to traverse the
+% image profile list. It is an error (i.e. will surely crash) to invoke
+% DeleteImageProfile() on the profile that the iterator is currently
+% referencing. However, it is safe to delete a profile that the iterator
+% is not currently referencing. Inserting additional profiles does not
+% invalidate the current iterator.
+%
+%
+% The format of the AllocateImageProfileIterator method is:
+%
+% ImageProfileIterator AllocateImageProfileIterator(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+*/
+MagickExport ImageProfileIterator
+AllocateImageProfileIterator(const Image *image)
+{
+ if (!image->profiles)
+ return 0;
+
+ return (ImageProfileIterator) MagickMapAllocateIterator(image->profiles);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A p p e n d I m a g e P r o f i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AppendImageProfile adds a named profile to the image. If a profile with the
+% same name already exists, then the new profile data is appended to the
+% existing profile. If a null profile address is supplied, then an existing
+% profile is removed. The profile is copied into the image. Note that this
+% function does not execute CMS color profiles. Any existing CMS color
+% profile is simply added/updated. Use the ProfileImage() function in order
+% to execute a CMS color profile.
+%
+% The format of the AppendImageProfile method is:
+%
+% MaickPassFail AppendImageProfile(Image *image,const char *name,
+% const unsigned char *profile_chunk,
+% const size_t chunk_length)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o name: Profile name. Valid names are "8BIM", "ICM", "IPTC", XMP, or any
+% unique text string.
+%
+% o profile_chunk: Address of profile chunk to add or append. Pass zero
+% to remove an existing profile.
+%
+% o length: The length of the profile chunk to add or append.
+%
+*/
+MagickExport MagickPassFail
+AppendImageProfile(Image *image,
+ const char *name,
+ const unsigned char *profile_chunk,
+ const size_t chunk_length)
+{
+ const unsigned char
+ *existing_profile;
+
+ size_t
+ existing_length;
+
+ MagickPassFail
+ status;
+
+ status=MagickFail;
+ existing_length=0;
+ existing_profile=(const unsigned char *) NULL;
+ if (profile_chunk != (const unsigned char *) NULL)
+ existing_profile=GetImageProfile(image,name,&existing_length);
+
+ if ((profile_chunk == (const unsigned char *) NULL) ||
+ (existing_profile == (const unsigned char *) NULL))
+ {
+ status=SetImageProfile(image,name,profile_chunk,chunk_length);
+ }
+ else
+ {
+ unsigned char
+ *profile;
+
+ size_t
+ profile_length;
+
+ profile_length=existing_length+chunk_length;
+ if ((profile_length < existing_length) ||
+ ((profile=MagickAllocateMemory(unsigned char *,(size_t) profile_length)) ==
+ (unsigned char *) NULL))
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ (char *) NULL);
+ (void) memcpy(profile,existing_profile,existing_length);
+ (void) memcpy(profile+existing_length,profile_chunk,chunk_length);
+ status=SetImageProfile(image,name,profile,profile_length);
+ MagickFreeMemory(profile);
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e a l l o c a t e I m a g e P r o f i l e I t e r a t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DeallocateImageProfileIterator deallocates an image profile iterator.
+%
+% The format of the DeallocateImageProfileIterator method is:
+%
+% void DeallocateImageProfileIterator(ImageProfileIterator profile_iterator)
+%
+% A description of each parameter follows:
+%
+% o profile_iterator: Profile iterator to deallocate.
+%
+*/
+MagickExport void
+DeallocateImageProfileIterator(ImageProfileIterator profile_iterator)
+{
+ if (profile_iterator != 0)
+ MagickMapDeallocateIterator((MagickMapIterator) profile_iterator);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e l e t e I m a g e P r o f i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DeleteImageProfile removes a named profile from the image.
+%
+% The format of the DeleteImageProfile method is:
+%
+% unsigned int DeleteImageProfile(Image *image,const char *name)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o name: Profile name. Valid names are "8BIM", "ICM", & "IPTC" or a
+% generic profile name.
+%
+*/
+MagickExport MagickPassFail
+DeleteImageProfile(Image *image,const char *name)
+{
+ return(SetImageProfile(image,name,0,0));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e P r o f i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageProfile returns a pointer to the named image profile if it is
+% present. A null pointer is returned if the named profile is not present.
+%
+% Older versions of this function stored profiles named "8BIM" and "IPTC"
+% in the same storage location. This is no longer the case. However,
+% GetImageProfile() will try the alternate name if the specifically
+% requested profile name is not available.
+%
+% The format of the GetImageProfile method is:
+%
+% const unsigned char *GetImageProfile(const Image* image,
+% const char *name, size_t *length)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o name: Profile name. Valid names are "8BIM", "ICM", "IPTC", "XMP" or any
+% unique text string.
+%
+% o length: Updated with profile length if profile is present. Set to NULL
+% if length is not needed.
+%
+*/
+MagickExport const unsigned char *
+GetImageProfile(const Image* image, const char *name, size_t *length)
+{
+ const unsigned char
+ *profile = 0;
+
+ size_t
+ profile_length=0;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(name != NULL);
+
+ if (length)
+ *length=0;
+
+ if (!image->profiles)
+ return 0;
+
+ profile=MagickMapAccessEntry(image->profiles,name,&profile_length);
+
+ if (!profile)
+ {
+ /*
+ Support common alias names and work-alikes.
+ */
+ if (LocaleCompare("ICC",name) == 0)
+ profile=MagickMapAccessEntry(image->profiles,"ICM",&profile_length);
+ else if (LocaleCompare("ICM",name) == 0)
+ profile=MagickMapAccessEntry(image->profiles,"ICC",&profile_length);
+ else if (LocaleCompare("IPTC",name) == 0)
+ profile=MagickMapAccessEntry(image->profiles,"8BIM",&profile_length);
+ else if (LocaleCompare("8BIM",name) == 0)
+ profile=MagickMapAccessEntry(image->profiles,"IPTC",&profile_length);
+ }
+
+ if (length)
+ *length=profile_length;
+
+ return profile;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N e x t I m a g e P r o f i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NextImageProfile iterates forward to the next image profile. The profile
+% name is returned along with the profile data, and length. If there are
+% no more entries in the list, then MagickFail is returned.
+%
+% The format of the AllocateImageProfileIterator method is:
+%
+% MagickPassFail NextImageProfile(ImageProfileIterator profile_iterator,
+% const char **name, const unsigned char **profile,
+% size_t *length)
+%
+% A description of each parameter follows:
+%
+% o profile_iterator: Profile iterator.
+%
+% o name: Address of pointer to update with address of name.
+%
+% o profile: Address of pointer to update with location of profile data.
+%
+% o length: Address of parameter to update with profile length.
+%
+*/
+MagickExport MagickPassFail
+NextImageProfile(ImageProfileIterator profile_iterator,
+ const char **name,
+ const unsigned char **profile,
+ size_t *length)
+{
+ MagickMapIterator
+ map_iterator;
+
+ MagickPassFail
+ status;
+
+ assert(name != (const char **) NULL);
+ assert(length != (size_t *) NULL);
+
+ if (profile_iterator == 0)
+ return (MagickFail);
+
+ map_iterator=(MagickMapIterator) profile_iterator;
+ status=MagickMapIterateNext(map_iterator,name);
+ if (status != MagickFail)
+ *profile=MagickMapDereferenceIterator(map_iterator,length);
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P r o f i l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ProfileImage() adds, applies, or removes a ICM, IPTC, or generic profile
+% from an image. If the profile is NULL, it is removed from the image
+% otherwise added (or applied). Use a name of '*' and a profile of NULL to
+% remove all profiles from the image. Ownership of the profile is
+% transferred to GraphicsMagick (it should not be altered or deallocated)
+% unless the clone option is set to True.
+%
+% ICC ICM profiles are a special case and are handled as follows:
+%
+% If there is no ICM profile currently associated with the image, then
+% the profile is simply associated with the image and the image pixels
+% are not altered.
+%
+% If there is already a ICM profile associated with the image, then
+% the colorspace transform described by the existing and new profiles
+% is applied to the image pixels, and the new profile is associated
+% with the image.
+%
+% The format of the ProfileImage method is:
+%
+% unsigned int ProfileImage(Image *image,const char *name,
+% unsigned char *profile,const size_t length,unsigned int clone)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o name: Name of profile to add or remove: ICM, IPTC, or generic profile.
+%
+% o profile: The profile. Can not be 'const' due to 'clone' option but
+% is treated as 'const' if 'clone' is set to MagickTrue.
+%
+% o length: The length of the profile.
+%
+% o clone: If set True, then copy the profile rather than taking
+% ownership of it.
+%
+%
+*/
+#if defined(HasLCMS)
+
+typedef struct _ProfilePacket
+{
+ unsigned short
+ red,
+ green,
+ blue,
+ black;
+} ProfilePacket;
+
+typedef struct _TransformInfo
+{
+ Image *image; /* image handle */
+ cmsHPROFILE source_profile; /* input profile */
+ cmsHPROFILE target_profile; /* output profile */
+ cmsUInt32Number source_type; /* input pixel format */
+ cmsUInt32Number target_type; /* output pixel format */
+ int intent; /* rendering intent */
+ cmsUInt32Number flags; /* create transform flags */
+ ThreadViewDataSet *transform; /* Thread-specific transforms */
+ ColorspaceType source_colorspace; /* source image transform colorspace */
+ ColorspaceType target_colorspace; /* target image transform colorspace */
+ unsigned long signature; /* structure validation signature */
+} TransformInfo;
+
+static void
+lcmsReplacementErrorHandler(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *ErrorText)
+{
+ TransformInfo
+ *xform;
+
+ ExceptionType
+ type=TransformError;
+
+ xform=(TransformInfo *) ContextID;
+
+ switch(ErrorCode)
+ {
+ default:
+ type=TransformWarning;
+ break;
+ }
+
+ (void) LogMagickEvent(type,GetMagickModule(),"lcms: #%u, %s",
+ ErrorCode,(ErrorText != (char *) NULL) ? ErrorText : "No error text");
+
+ if (xform != (TransformInfo *) NULL)
+ {
+ ThrowException2(&xform->image->exception,type,"UnableToTransformColorspace",
+ (ErrorText != (char *) NULL) ? ErrorText : "No error text");
+ }
+}
+
+static MagickPassFail
+ProfileImagePixels(void *mutable_data, /* User provided mutable data */
+ const void *immutable_data, /* User provided immutable data */
+ Image *image, /* Modify image */
+ PixelPacket *pixels, /* Pixel row */
+ IndexPacket *indexes, /* Pixel row indexes */
+ const long npixels, /* Number of pixels in row */
+ ExceptionInfo *exception) /* Exception report */
+{
+ const TransformInfo
+ *xform = (const TransformInfo *) immutable_data;
+
+ register long
+ i;
+
+ cmsHTRANSFORM
+ transform;
+
+ const ColorspaceType
+ source_colorspace = xform->source_colorspace;
+
+ const ColorspaceType
+ target_colorspace = xform->target_colorspace;
+
+ ProfilePacket
+ alpha,
+ beta;
+
+ ARG_NOT_USED(mutable_data);
+ ARG_NOT_USED(exception);
+
+ transform=(cmsHTRANSFORM) AccessThreadViewData(xform->transform);
+
+ /*
+ TODO: This may be optimized to use PixelPackets instead
+ of moving PixelPacket components to and from ProfilePackets.
+ The transform types below, then, must match #ifdef's in the
+ PixelPacket struct definition and should be optimized
+ based on Quantum size. Some (if not all?) YCbCr and LUV
+ profiles are (TIFF) scanline oriented, so transforming
+ one pixel at a time does not work for those profiles.
+
+ Notice that the performance penalty of transforming only
+ one pixel at a time is very small and probably not worth
+ optimizing.
+ */
+
+ for (i=0; i < npixels; i++)
+ {
+ alpha.red=ScaleQuantumToShort(pixels[i].red);
+ if (source_colorspace != GRAYColorspace)
+ {
+ alpha.green=ScaleQuantumToShort(pixels[i].green);
+ alpha.blue=ScaleQuantumToShort(pixels[i].blue);
+ if (source_colorspace == CMYKColorspace)
+ alpha.black=ScaleQuantumToShort(pixels[i].opacity);
+ }
+ cmsDoTransform(transform,&alpha,&beta,1);
+ pixels[i].red=ScaleShortToQuantum(beta.red);
+ if (IsGrayColorspace(target_colorspace))
+ {
+ pixels[i].green=pixels[i].red;
+ pixels[i].blue=pixels[i].red;
+ }
+ else
+ {
+ pixels[i].green=ScaleShortToQuantum(beta.green);
+ pixels[i].blue=ScaleShortToQuantum(beta.blue);
+ }
+ if (image->matte)
+ {
+ if ((source_colorspace == CMYKColorspace) &&
+ (target_colorspace != CMYKColorspace))
+ pixels[i].opacity=indexes[i];
+ else
+ if ((source_colorspace != CMYKColorspace) &&
+ (target_colorspace == CMYKColorspace))
+ indexes[i]=pixels[i].opacity;
+ }
+ if (target_colorspace == CMYKColorspace)
+ pixels[i].opacity=ScaleShortToQuantum(beta.black);
+ }
+
+ return MagickPass;
+}
+
+static void MagickFreeCMSTransform(void * cmsTransformVoid)
+{
+ cmsHTRANSFORM
+ cmsTransform=(cmsHTRANSFORM) cmsTransformVoid;
+
+ if (cmsTransform != (cmsHTRANSFORM) NULL)
+ cmsDeleteTransform(cmsTransform);
+}
+
+static const char *
+PixelTypeToString(int pixel_type)
+{
+const char *
+ result="";
+
+ switch (pixel_type)
+ {
+ case PT_ANY: result="ANY" ; break;
+ case PT_GRAY: result="GRAY" ; break;
+ case PT_RGB: result="RGB" ; break;
+ case PT_CMY: result="CMY" ; break;
+ case PT_CMYK: result="CMYK" ; break;
+ case PT_YCbCr: result="YCbCr" ; break;
+ case PT_YUV: result="YUV (Lu'v')"; break;
+ case PT_XYZ: result="XYZ" ; break;
+ case PT_Lab: result="Lab" ; break;
+ case PT_YUVK: result="YUVK (Lu'v'K)" ; break;
+ case PT_HSV: result="HSV" ; break;
+ case PT_HLS: result="HLS" ; break;
+ case PT_Yxy: result="Yxy" ; break;
+
+#if defined(PT_HiFi)
+ case PT_HiFi: result="HiFi" ; break;
+#endif
+#if defined(PT_HiFi7)
+ case PT_HiFi7: result="HiFi7" ; break;
+#endif
+#if defined(PT_HiFi8)
+ case PT_HiFi8: result="HiFi8" ; break;
+#endif
+#if defined(PT_HiFi9)
+ case PT_HiFi9: result="HiFi9" ; break;
+#endif
+#if defined(PT_HiFi10)
+ case PT_HiFi10: result="HiFi10"; break;
+#endif
+#if defined(PT_HiFi11)
+ case PT_HiFi11: result="HiFi11"; break;
+#endif
+#if defined(PT_HiFi12)
+ case PT_HiFi12: result="HiFi12"; break;
+#endif
+#if defined(PT_HiFi13)
+ case PT_HiFi13: result="HiFi13"; break;
+#endif
+#if defined(PT_HiFi14)
+ case PT_HiFi14: result="HiFi14"; break;
+#endif
+#if defined(PT_HiFi15)
+ case PT_HiFi15: result="HiFi15"; break;
+#endif
+
+#if defined(PT_MCH1)
+ case PT_MCH1: result="MCH1" ; break;
+#endif
+#if defined(PT_MCH2)
+ case PT_MCH2: result="MCH2" ; break;
+#endif
+#if defined(PT_MCH3)
+ case PT_MCH3: result="MCH3" ; break;
+#endif
+#if defined(PT_MCH4)
+ case PT_MCH4: result="MCH4" ; break;
+#endif
+#if defined(PT_MCH5)
+ case PT_MCH5: result="MCH5" ; break;
+#endif
+#if defined(PT_MCH6)
+ case PT_MCH6: result="MCH6" ; break;
+#endif
+#if defined(PT_MCH7)
+ case PT_MCH7: result="MCH7" ; break;
+#endif
+#if defined(PT_MCH8)
+ case PT_MCH8: result="MCH8" ; break;
+#endif
+#if defined(PT_MCH9)
+ case PT_MCH9: result="MCH9" ; break;
+#endif
+#if defined(PT_MCH10)
+ case PT_MCH10: result="MCH10" ; break;
+#endif
+#if defined(PT_MCH11)
+ case PT_MCH11: result="MCH11" ; break;
+#endif
+#if defined(PT_MCH12)
+ case PT_MCH12: result="MCH12" ; break;
+#endif
+#if defined(PT_MCH13)
+ case PT_MCH13: result="MCH13" ; break;
+#endif
+#if defined(PT_MCH14)
+ case PT_MCH14: result="MCH14" ; break;
+#endif
+#if defined(PT_MCH15)
+ case PT_MCH15: result="MCH15" ; break;
+#endif
+#if defined(PT_LabV2)
+ case PT_LabV2: result="LabV2" ; break;
+#endif
+ }
+
+ return result;
+}
+
+#endif /* defined(HasLCMS) */
+
+#define ProfileImageText "[%s] Color Transform Pixels..."
+MagickExport MagickPassFail
+ProfileImage(Image *image,const char *name,unsigned char *profile,
+ const size_t length,MagickBool clone)
+{
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (name == (const char *) NULL)
+ ThrowBinaryException3(OptionError,NoProfileNameWasGiven,
+ UnableToAddOrRemoveProfile);
+ if ((profile == (const unsigned char *) NULL) || (length == 0))
+ {
+ /*
+ Remove an ICM, IPTC, or generic profile from the image.
+ */
+ char
+ arg_string[MaxTextExtent],
+ profile_remove[MaxTextExtent];
+
+ const char
+ *profile_name;
+
+ size_t
+ profile_length;
+
+ const unsigned char *
+ profile_info;
+
+ ImageProfileIterator
+ profile_iterator;
+
+ char
+ **argv;
+
+ int
+ argc;
+
+ long
+ i;
+
+ (void) strlcpy(arg_string,name,sizeof(arg_string));
+ LocaleUpper(arg_string);
+ for (i=0; arg_string[i] != '\0'; i++)
+ if (arg_string[i] == ',')
+ arg_string[i] = ' ';
+ argv=StringToArgv(arg_string,&argc);
+ profile_iterator=AllocateImageProfileIterator(image);
+ profile_remove[0]=0;
+ while(NextImageProfile(profile_iterator,&profile_name,&profile_info,
+ &profile_length) != MagickFail)
+ {
+ if (strlen(profile_remove))
+ {
+ (void) DeleteImageProfile(image,profile_remove);
+ profile_remove[0]=0;
+ }
+ for (i=1 ; i < argc ; i++)
+ {
+ if ((*argv[i] == '!') && (LocaleCompare(profile_name,argv[i]+1) == 0))
+ break;
+ if (GlobExpression(profile_name,argv[i]))
+ {
+ (void) strlcpy(profile_remove,profile_name,sizeof(profile_remove));
+ break;
+ }
+ }
+ }
+ DeallocateImageProfileIterator(profile_iterator);
+ if (strlen(profile_remove))
+ (void) DeleteImageProfile(image,profile_remove);
+
+ for(i=0; argv[i] != NULL; i++)
+ MagickFreeMemory(argv[i]);
+ MagickFreeMemory(argv);
+
+ return(MagickPass);
+ }
+ /*
+ Add a ICM, IPTC, or generic profile to the image.
+ */
+ if ((LocaleCompare("8bim",name) == 0) || (LocaleCompare("iptc",name) == 0))
+ {
+ if (clone)
+ {
+ (void) SetImageProfile(image,name,profile,length);
+ }
+ else
+ {
+ (void) SetImageProfile(image,name,profile,length);
+ MagickFreeMemory(profile);
+ }
+ return(MagickPass);
+ }
+ if (LocaleCompare("icm",name) == 0)
+ {
+ const unsigned char
+ *existing_profile;
+
+ size_t
+ existing_profile_length=0;
+
+ /* Check for identical input and output profiles. Return on identity. */
+ existing_profile=GetImageProfile(image,"ICM",&existing_profile_length);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "New Profile: %lu bytes, Existing Profile: %lu bytes",
+ (unsigned long) length,
+ (unsigned long) existing_profile_length);
+
+ if ((length != 0) && (length == existing_profile_length) &&
+ (memcmp(existing_profile,profile,length) == 0))
+ {
+ return(MagickPass);
+ }
+
+ /* Convert to new colors if we have both an old and a new profile. */
+ if ((existing_profile_length != 0) && (length != 0))
+ {
+#if defined(HasLCMS)
+
+ TransformInfo
+ xform;
+
+ MagickBool
+ transform_colormap;
+
+ /*
+ Transform pixel colors as defined by the color profiles.
+ */
+ (void) memset(&xform,0,sizeof(xform));
+ xform.signature=MagickSignature;
+ xform.image=image;
+ cmsSetLogErrorHandler(lcmsReplacementErrorHandler);
+
+ xform.source_profile=cmsOpenProfileFromMemTHR((cmsContext) &xform,
+ (unsigned char *) existing_profile,
+ (cmsUInt32Number) existing_profile_length);
+ xform.target_profile=cmsOpenProfileFromMemTHR((cmsContext) &xform,
+ (unsigned char *) profile,
+ (cmsUInt32Number) length);
+ if ((xform.source_profile == (cmsHPROFILE) NULL) ||
+ (xform.target_profile == (cmsHPROFILE) NULL))
+ ThrowBinaryException3(ResourceLimitError,UnableToManageColor,
+ UnableToOpenColorProfile);
+
+ switch (cmsGetColorSpace(xform.source_profile))
+ {
+ case cmsSigXYZData:
+ {
+ xform.source_colorspace=XYZColorspace;
+ xform.source_type=TYPE_XYZ_16;
+ break;
+ }
+ case cmsSigLabData:
+ {
+ xform.source_colorspace=LABColorspace;
+ xform.source_type=TYPE_Lab_16;
+ break;
+ }
+ case cmsSigCmykData:
+ {
+ xform.source_colorspace=CMYKColorspace;
+ xform.source_type=TYPE_CMYK_16;
+ break;
+ }
+ case cmsSigYCbCrData:
+ {
+ xform.source_colorspace=YCbCrColorspace;
+ xform.source_type=TYPE_YCbCr_16;
+ break;
+ }
+ case cmsSigLuvData:
+ {
+ xform.source_colorspace=YUVColorspace;
+ xform.source_type=TYPE_YUV_16;
+ break;
+ }
+ case cmsSigGrayData:
+ {
+ xform.source_colorspace=GRAYColorspace;
+ xform.source_type=TYPE_GRAY_16;
+ break;
+ }
+ case cmsSigRgbData:
+ {
+ xform.source_colorspace=RGBColorspace;
+ xform.source_type=TYPE_RGB_16;
+ break;
+ }
+ default:
+ {
+ xform.source_colorspace=UndefinedColorspace;
+ xform.source_type=TYPE_RGB_16;
+ break;
+ }
+ }
+ switch (cmsGetColorSpace(xform.target_profile))
+ {
+ case cmsSigXYZData:
+ {
+ xform.target_colorspace=XYZColorspace;
+ xform.target_type=TYPE_XYZ_16;
+ break;
+ }
+ case cmsSigLabData:
+ {
+ xform.target_colorspace=LABColorspace;
+ xform.target_type=TYPE_Lab_16;;
+ break;
+ }
+ case cmsSigCmykData:
+ {
+ xform.target_colorspace=CMYKColorspace;
+ xform.target_type=TYPE_CMYK_16;
+ break;
+ }
+ case cmsSigYCbCrData:
+ {
+ xform.target_colorspace=YCbCrColorspace;
+ xform.target_type=TYPE_YCbCr_16;
+ break;
+ }
+ case cmsSigLuvData:
+ {
+ xform.target_colorspace=YUVColorspace;
+ xform.target_type=TYPE_YUV_16;
+ break;
+ }
+ case cmsSigGrayData:
+ {
+ xform.target_colorspace=GRAYColorspace;
+ xform.target_type=TYPE_GRAY_16;
+ break;
+ }
+ case cmsSigRgbData:
+ {
+ xform.target_colorspace=RGBColorspace;
+ xform.target_type=TYPE_RGB_16;
+ break;
+ }
+ default:
+ {
+ xform.target_colorspace=UndefinedColorspace;
+ xform.target_type=TYPE_RGB_16;
+ break;
+ }
+ }
+
+ /* Colorspace undefined */
+ if ((xform.source_colorspace == UndefinedColorspace) ||
+ (xform.target_colorspace == UndefinedColorspace))
+ {
+ (void) cmsCloseProfile(xform.source_profile);
+ (void) cmsCloseProfile(xform.target_profile);
+ ThrowBinaryException3(ImageError,UnableToAssignProfile,
+ ColorspaceColorProfileMismatch);
+ }
+ /* Gray colorspace */
+ if (IsGrayColorspace(xform.source_colorspace) &&
+ !IsGrayImage(image,&image->exception))
+ {
+ (void) cmsCloseProfile(xform.source_profile);
+ (void) cmsCloseProfile(xform.target_profile);
+ ThrowBinaryException3(ImageError,UnableToAssignProfile,
+ ColorspaceColorProfileMismatch);
+ }
+ /* CMYK colorspace */
+ if (IsCMYKColorspace(xform.source_colorspace) &&
+ !IsCMYKColorspace(image->colorspace))
+ {
+ (void) cmsCloseProfile(xform.source_profile);
+ (void) cmsCloseProfile(xform.target_profile);
+ ThrowBinaryException3(ImageError,UnableToAssignProfile,
+ ColorspaceColorProfileMismatch);
+ }
+ /* YCbCr colorspace */
+ if (IsYCbCrColorspace(xform.source_colorspace) &&
+ !IsYCbCrColorspace(image->colorspace))
+ {
+ (void) cmsCloseProfile(xform.source_profile);
+ (void) cmsCloseProfile(xform.target_profile);
+ ThrowBinaryException3(ImageError,UnableToAssignProfile,
+ ColorspaceColorProfileMismatch);
+ }
+ /* Verify that source colorspace type is supported */
+ if (!IsGrayColorspace(xform.source_colorspace) &&
+ !IsCMYKColorspace(xform.source_colorspace) &&
+ !IsLABColorspace(xform.source_colorspace) &&
+ !IsYCbCrColorspace(xform.source_colorspace) &&
+ !IsRGBColorspace(image->colorspace))
+ {
+ (void) cmsCloseProfile(xform.source_profile);
+ (void) cmsCloseProfile(xform.target_profile);
+ ThrowBinaryException3(ImageError,UnableToAssignProfile,
+ ColorspaceColorProfileMismatch);
+ }
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Source pixel format: COLORSPACE=%s SWAPFIRST=%d "
+ "FLAVOR=%d PLANAR=%d ENDIAN16=%d DOSWAP=%d "
+ "EXTRA=%d CHANNELS=%d BYTES=%d",
+ PixelTypeToString((int) T_COLORSPACE(xform.source_type)),
+ (int) T_SWAPFIRST(xform.source_type),
+ (int) T_FLAVOR(xform.source_type),
+ (int) T_PLANAR(xform.source_type),
+ (int) T_ENDIAN16(xform.source_type),
+ (int) T_DOSWAP(xform.source_type),
+ (int) T_EXTRA(xform.source_type),
+ (int) T_CHANNELS(xform.source_type),
+ (int) T_BYTES(xform.source_type));
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Target pixel format: COLORSPACE=%s SWAPFIRST=%d "
+ "FLAVOR=%d PLANAR=%d ENDIAN16=%d DOSWAP=%d "
+ "EXTRA=%d CHANNELS=%d BYTES=%d",
+ PixelTypeToString((int) T_COLORSPACE(xform.target_type)),
+ (int) T_SWAPFIRST(xform.target_type),
+ (int) T_FLAVOR(xform.target_type),
+ (int) T_PLANAR(xform.target_type),
+ (int) T_ENDIAN16(xform.target_type),
+ (int) T_DOSWAP(xform.target_type),
+ (int) T_EXTRA(xform.target_type),
+ (int) T_CHANNELS(xform.target_type),
+ (int) T_BYTES(xform.target_type));
+
+ switch (image->rendering_intent)
+ {
+ case AbsoluteIntent:
+ xform.intent=INTENT_ABSOLUTE_COLORIMETRIC;
+ break;
+ case PerceptualIntent:
+ xform.intent=INTENT_PERCEPTUAL;
+ break;
+ case RelativeIntent:
+ xform.intent=INTENT_RELATIVE_COLORIMETRIC;
+ break;
+ case SaturationIntent:
+ xform.intent=INTENT_SATURATION;
+ break;
+ default:
+ xform.intent=INTENT_PERCEPTUAL;
+ break;
+ }
+
+ /*
+ Transform just the colormap if the image is colormapped and we're
+ not transforming from gray to RGB/CMYK. A gray to RGB/CMYK
+ transformation must create a direct class image for the new image
+ to match the color profile even if the new image only has gray
+ colors. CMYK images are never color mapped.
+ */
+ transform_colormap=(image->storage_class == PseudoClass) &&
+ (xform.target_colorspace != CMYKColorspace) &&
+ ((xform.source_colorspace != GRAYColorspace) ||
+ (xform.source_colorspace == xform.target_colorspace));
+
+ /* build pre-computed transforms? */
+ xform.flags=(transform_colormap ? cmsFLAGS_NOOPTIMIZE : 0);
+
+ xform.transform=AllocateThreadViewDataSet(MagickFreeCMSTransform,
+ image,&image->exception);
+ if (xform.transform == (ThreadViewDataSet *) NULL)
+ status=MagickFail;
+ if (status != MagickFail)
+ {
+ cmsHTRANSFORM
+ transform;
+
+ unsigned int
+ index;
+
+ for (index=0 ; index < GetThreadViewDataSetAllocatedViews(xform.transform); index++)
+ {
+ transform=cmsCreateTransformTHR((cmsContext) &xform,/* transform handle */
+ xform.source_profile, /* input profile */
+ xform.source_type, /* input pixel format */
+ xform.target_profile, /* output profile */
+ xform.target_type, /* output pixel format */
+ xform.intent, /* rendering intent */
+ xform.flags /* pre-computed transforms? */
+ );
+ if (transform == (cmsHTRANSFORM) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ AssignThreadViewData(xform.transform,index,transform);
+ }
+ }
+ (void) cmsCloseProfile(xform.source_profile);
+ (void) cmsCloseProfile(xform.target_profile);
+ if (status == MagickFail)
+ {
+ DestroyThreadViewDataSet(xform.transform);
+ ThrowBinaryException3(ResourceLimitError,UnableToManageColor,
+ UnableToCreateColorTransform);
+ }
+
+ if (transform_colormap)
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Performing pseudo class color conversion");
+
+ (void) ProfileImagePixels(NULL,
+ &xform,
+ image,
+ image->colormap,
+ (IndexPacket *) NULL,
+ image->colors,
+ &image->exception);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Completed pseudo class color conversion");
+ status &= SyncImage(image);
+ }
+ else
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Performing direct class color conversion");
+ if (image->storage_class == PseudoClass)
+ {
+ status &= SyncImage(image);
+ image->storage_class=DirectClass;
+ }
+ if (xform.target_colorspace == CMYKColorspace)
+ image->colorspace=xform.target_colorspace;
+
+ status=PixelIterateMonoModify(ProfileImagePixels,
+ NULL,
+ ProfileImageText,
+ NULL,&xform,0,0,image->columns,image->rows,
+ image,&image->exception);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Completed direct class color conversion");
+
+ }
+ image->colorspace=xform.target_colorspace;
+ /*
+ We can't be sure black and white stays exactly black and white
+ and that gray colors transform to gray colors.
+ */
+ image->is_grayscale=IsGrayColorspace(xform.target_colorspace);
+ image->is_monochrome=False;
+ DestroyThreadViewDataSet(xform.transform);
+
+ /*
+ Throw away the old profile after conversion before we
+ assign a new one.
+ */
+ DeleteImageProfile(image,"ICM");
+#else
+ ThrowBinaryException(MissingDelegateError,LCMSLibraryIsNotAvailable,
+ image->filename);
+#endif
+ }
+
+ /*
+ TODO: If the image *did not* already have a color profile,
+ verify that the colorspace of the new profile is valid for the
+ colorspace of the image. If LCMS is not available we should
+ refuse to assign a new profile (just like we're refusing a
+ conversion above) as we can't be sure the assigment is valid.
+ We might be trying to assign a CMYK profile to an RGB image,
+ for instance.
+ */
+
+ (void) SetImageProfile(image,"ICM",profile,length);
+ if (!clone)
+ MagickFreeMemory(profile);
+ return(status);
+ }
+
+ status &= SetImageProfile(image,name,profile,length);
+ if (!clone)
+ MagickFreeMemory(profile);
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e P r o f i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageProfile adds a named profile to the image. If a profile with the
+% same name already exists, then it is replaced. If a null profile address
+% is supplied, then an existing profile is removed. The profile is copied
+% into the image. Note that this function does not execute CMS color
+% profiles. Any existing CMS color profile is simply replaced. Use the
+% ProfileImage() function in order to execute a CMS color profile.
+%
+% Older versions of this function stored profiles named "8BIM" and "IPTC"
+% in the same storage location. This is no longer the case. However,
+% GetImageProfile() will try the alternate name if the specifically
+% requested profile name is not available. Note that when trying to remove
+% a profile, it may be necessary to remove both names in order for an
+% "IPTC" profile to no longer be included in output file formats.
+%
+% The format of the SetImageProfile method is:
+%
+% unsigned int SetImageProfile(Image *image,const char *name,
+% const unsigned char *profile,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o name: Profile name. Valid names are "8BIM", "ICM", "IPTC", XMP, or any
+% unique text string.
+%
+% o profile: Address of profile to add. Pass zero to remove an existing
+% profile.
+%
+% o length: The length of the profile.
+%
+*/
+MagickExport MagickPassFail
+SetImageProfile(Image *image,const char *name, const unsigned char *profile,
+ const size_t length)
+{
+ char
+ ucase_name[MaxTextExtent];
+
+ unsigned int
+ status = MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(name != NULL);
+
+ if (strlcpy(ucase_name,name,sizeof(ucase_name)) >= sizeof(ucase_name))
+ {
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Profile name too long! (%s)",name);
+ return MagickFail;
+ }
+ LocaleUpper(ucase_name);
+
+ if ((profile == 0) && (image->profiles != 0))
+ {
+ /*
+ Remove existing entry.
+ */
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Removing %s profile",name);
+ status &= MagickMapRemoveEntry(image->profiles,name);
+ }
+ else
+ {
+ /*
+ Add or replace entry.
+ */
+ if (image->profiles == 0)
+ image->profiles=MagickMapAllocateMap(MagickMapCopyBlob,
+ MagickMapDeallocateBlob);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Adding %s profile with length %ld bytes",name,
+ (unsigned long) length);
+ if (profile != 0)
+ {
+ status &= MagickMapAddEntry(image->profiles,name,profile,length,
+ &image->exception);
+ }
+ }
+ return (status);
+}
diff --git a/magick/profile.h b/magick/profile.h
new file mode 100644
index 0000000..e19bec9
--- /dev/null
+++ b/magick/profile.h
@@ -0,0 +1,90 @@
+/*
+ Copyright (C) 2004 - 2009 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Methods For Manipulating Embedded Image Profiles.
+*/
+#ifndef _MAGICK_PROFILE_H
+#define _MAGICK_PROFILE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+/*
+ Retrieve a profile from the image by name.
+*/
+extern MagickExport const unsigned char
+ *GetImageProfile(const Image* image, const char *name, size_t *length);
+
+/*
+ Remove a profile from the image by name.
+*/
+extern MagickExport MagickPassFail
+ DeleteImageProfile(Image *image,const char *name);
+
+/*
+ Apply (or add) a profile to the image.
+*/
+extern MagickExport MagickPassFail
+ ProfileImage(Image *image,const char *name,unsigned char *profile,
+ const size_t length,MagickBool clone);
+
+/*
+ Add (or replace) profile to the image by name.
+*/
+extern MagickExport MagickPassFail
+ SetImageProfile(Image *image,const char *name,const unsigned char *profile,
+ const size_t length);
+
+/*
+ Add (or append) profile to the image by name.
+ */
+ extern MagickExport MagickPassFail
+ AppendImageProfile(Image *image,const char *name,
+ const unsigned char *profile_chunk,
+ const size_t chunk_length);
+
+/*
+ Generic iterator for traversing profiles.
+*/
+typedef void *ImageProfileIterator;
+
+/*
+ Allocate an image profile iterator which points to one before the
+ list so NextImageProfile() must be used to advance to first entry.
+*/
+extern MagickExport ImageProfileIterator
+ AllocateImageProfileIterator(const Image *image);
+
+/*
+ Advance to next image profile. Name, profile, and length are
+ updated with information on current profile. MagickFail is returned
+ when there are no more entries.
+*/
+extern MagickExport MagickPassFail
+ NextImageProfile(ImageProfileIterator profile_iterator,const char **name,
+ const unsigned char **profile,size_t *length);
+
+/*
+ Deallocate profile iterator.
+*/
+extern MagickExport void
+ DeallocateImageProfileIterator(ImageProfileIterator profile_iterator);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_PROFILE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/quantize.c b/magick/quantize.c
new file mode 100644
index 0000000..3a3de08
--- /dev/null
+++ b/magick/quantize.c
@@ -0,0 +1,2776 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% QQQ U U AAA N N TTTTT IIIII ZZZZZ EEEEE %
+% Q Q U U A A NN N T I ZZ E %
+% Q Q U U AAAAA N N N T I ZZZ EEEEE %
+% Q QQ U U A A N NN T I ZZ E %
+% QQQQ UUU A A N N T IIIII ZZZZZ EEEEE %
+% %
+% %
+% Methods to Reduce the Number of Unique Colors in an Image %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Realism in computer graphics typically requires using 24 bits/pixel to
+% generate an image. Yet many graphic display devices do not contain the
+% amount of memory necessary to match the spatial and color resolution of
+% the human eye. The Quantize methods takes a 24 bit image and reduces
+% the number of colors so it can be displayed on raster device with less
+% bits per pixel. In most instances, the quantized image closely
+% resembles the original reference image.
+%
+% A reduction of colors in an image is also desirable for image
+% transmission and real-time animation.
+%
+% QuantizeImage() takes a standard RGB or monochrome images and quantizes
+% them down to some fixed number of colors.
+%
+% For purposes of color allocation, an image is a set of n pixels, where
+% each pixel is a point in RGB space. RGB space is a 3-dimensional
+% vector space, and each pixel, Pi, is defined by an ordered triple of
+% red, green, and blue coordinates, (Ri, Gi, Bi).
+%
+% Each primary color component (red, green, or blue) represents an
+% intensity which varies linearly from 0 to a maximum value, Cmax, which
+% corresponds to full saturation of that color. Color allocation is
+% defined over a domain consisting of the cube in RGB space with opposite
+% vertices at (0,0,0) and (Cmax, Cmax, Cmax). QUANTIZE requires Cmax =
+% 255.
+%
+% The algorithm maps this domain onto a tree in which each node
+% represents a cube within that domain. In the following discussion
+% these cubes are defined by the coordinate of two opposite vertices:
+% The vertex nearest the origin in RGB space and the vertex farthest from
+% the origin.
+%
+% The tree's root node represents the the entire domain, (0,0,0) through
+% (Cmax,Cmax,Cmax). Each lower level in the tree is generated by
+% subdividing one node's cube into eight smaller cubes of equal size.
+% This corresponds to bisecting the parent cube with planes passing
+% through the midpoints of each edge.
+%
+% The basic algorithm operates in three phases: Classification,
+% Reduction, and Assignment. Classification builds a color description
+% tree for the image. Reduction collapses the tree until the number it
+% represents, at most, the number of colors desired in the output image.
+% Assignment defines the output image's color map and sets each pixel's
+% color by restorage_class in the reduced tree. Our goal is to minimize
+% the numerical discrepancies between the original colors and quantized
+% colors (quantization error).
+%
+% Classification begins by initializing a color description tree of
+% sufficient depth to represent each possible input color in a leaf.
+% However, it is impractical to generate a fully-formed color description
+% tree in the storage_class phase for realistic values of Cmax. If
+% colors components in the input image are quantized to k-bit precision,
+% so that Cmax= 2k-1, the tree would need k levels below the root node to
+% allow representing each possible input color in a leaf. This becomes
+% prohibitive because the tree's total number of nodes is 1 +
+% sum(i=1, k, 8k).
+%
+% A complete tree would require 19,173,961 nodes for k = 8, Cmax = 255.
+% Therefore, to avoid building a fully populated tree, QUANTIZE: (1)
+% Initializes data structures for nodes only as they are needed; (2)
+% Chooses a maximum depth for the tree as a function of the desired
+% number of colors in the output image (currently log2(colormap size)).
+%
+% For each pixel in the input image, storage_class scans downward from
+% the root of the color description tree. At each level of the tree it
+% identifies the single node which represents a cube in RGB space
+% containing the pixel's color. It updates the following data for each
+% such node:
+%
+% n1: Number of pixels whose color is contained in the RGB cube which
+% this node represents;
+%
+% n2: Number of pixels whose color is not represented in a node at
+% lower depth in the tree; initially, n2 = 0 for all nodes except
+% leaves of the tree.
+%
+% Sr, Sg, Sb: Sums of the red, green, and blue component values for all
+% pixels not classified at a lower depth. The combination of these sums
+% and n2 will ultimately characterize the mean color of a set of
+% pixels represented by this node.
+%
+% E: The distance squared in RGB space between each pixel contained
+% within a node and the nodes' center. This represents the
+% quantization error for a node.
+%
+% Reduction repeatedly prunes the tree until the number of nodes with n2
+% > 0 is less than or equal to the maximum number of colors allowed in
+% the output image. On any given iteration over the tree, it selects
+% those nodes whose E count is minimal for pruning and merges their color
+% statistics upward. It uses a pruning threshold, Ep, to govern node
+% selection as follows:
+%
+% Ep = 0
+% while number of nodes with (n2 > 0) > required maximum number of colors
+% prune all nodes such that E <= Ep
+% Set Ep to minimum E in remaining nodes
+%
+% This has the effect of minimizing any quantization error when merging
+% two nodes together.
+%
+% When a node to be pruned has offspring, the pruning procedure invokes
+% itself recursively in order to prune the tree from the leaves upward.
+% n2, Sr, Sg, and Sb in a node being pruned are always added to the
+% corresponding data in that node's parent. This retains the pruned
+% node's color characteristics for later averaging.
+%
+% For each node, n2 pixels exist for which that node represents the
+% smallest volume in RGB space containing those pixel's colors. When n2
+% > 0 the node will uniquely define a color in the output image. At the
+% beginning of reduction, n2 = 0 for all nodes except a the leaves of
+% the tree which represent colors present in the input image.
+%
+% The other pixel count, n1, indicates the total number of colors within
+% the cubic volume which the node represents. This includes n1 - n2
+% pixels whose colors should be defined by nodes at a lower level in the
+% tree.
+%
+% Assignment generates the output image from the pruned tree. The output
+% image consists of two parts: (1) A color map, which is an array of
+% color descriptions (RGB triples) for each color present in the output
+% image; (2) A pixel array, which represents each pixel as an index
+% into the color map array.
+%
+% First, the assignment phase makes one pass over the pruned color
+% description tree to establish the image's color map. For each node
+% with n2 > 0, it divides Sr, Sg, and Sb by n2 . This produces the mean
+% color of all pixels that classify no lower than this node. Each of
+% these colors becomes an entry in the color map.
+%
+% Finally, the assignment phase reclassifies each pixel in the pruned
+% tree to identify the deepest node containing the pixel's color. The
+% pixel's value in the pixel array becomes the index of this node's mean
+% color in the color map.
+%
+% This method is based on a similar algorithm written by Paul Raveling.
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/color.h"
+#include "magick/colormap.h"
+#include "magick/enhance.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/quantize.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define CacheShift (QuantumDepth-6)
+#define ExceptionQueueLength 16
+#define MaxNodes 266817
+#define MaxTreeDepth 8
+#define NodesInAList 1536
+
+#define ColorToNodeId(red,green,blue,index) ((unsigned int) \
+ (((ScaleQuantumToChar(red) >> index) & 0x01) << 2 | \
+ ((ScaleQuantumToChar(green) >> index) & 0x01) << 1 | \
+ ((ScaleQuantumToChar(blue) >> index) & 0x01)))
+
+/*
+ Typedef declarations.
+*/
+#if QuantumDepth > 16 && defined(HAVE_LONG_DOUBLE_WIDER)
+ typedef long double ErrorSumType;
+#else
+ typedef double ErrorSumType;
+#endif
+
+typedef struct _NodeInfo
+{
+ struct _NodeInfo
+ *parent,
+ *child[MaxTreeDepth];
+
+ double
+ number_unique;
+
+ double /* was ErrorSumType */
+ total_red,
+ total_green,
+ total_blue;
+
+ ErrorSumType
+ quantize_error;
+
+ unsigned long
+ color_number;
+
+ unsigned char
+ id,
+ level;
+} NodeInfo;
+
+typedef struct _Nodes
+{
+ NodeInfo
+ *nodes;
+
+ struct _Nodes
+ *next;
+} Nodes;
+
+typedef struct _CubeInfo
+{
+ NodeInfo
+ *root;
+
+ unsigned long
+ colors;
+
+ DoublePixelPacket
+ color;
+
+ double /* was ErrorSumType */
+ distance;
+
+ ErrorSumType
+ pruning_threshold,
+ next_threshold;
+
+ unsigned long
+ nodes,
+ free_nodes,
+ color_number;
+
+ NodeInfo
+ *next_node;
+
+ Nodes
+ *node_queue;
+
+ long
+ *cache;
+
+ DoublePixelPacket
+ error[ExceptionQueueLength];
+
+ double
+ weights[ExceptionQueueLength];
+
+ const QuantizeInfo
+ *quantize_info;
+
+ long
+ x,
+ y;
+
+ unsigned long
+ depth;
+} CubeInfo;
+
+/*
+ Method prototypes.
+*/
+static void
+ ClosestColor(Image *,CubeInfo *,const NodeInfo *);
+
+static NodeInfo
+ *GetNodeInfo(CubeInfo *,const unsigned int,const unsigned int,NodeInfo *);
+
+static unsigned int
+ DitherImage(CubeInfo *,Image *);
+
+static void
+ DefineImageColormap(Image *,NodeInfo *),
+ HilbertCurve(CubeInfo *,Image *,const unsigned long,const unsigned int),
+ PruneLevel(CubeInfo *,const NodeInfo *),
+ PruneToCubeDepth(CubeInfo *,const NodeInfo *),
+ ReduceImageColors(const char *filename,CubeInfo *,const unsigned long,ExceptionInfo *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ A s s i g n I m a g e C o l o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AssignImageColors() generates the output image from the pruned tree. The
+% output image consists of two parts: (1) A color map, which is an array
+% of color descriptions (RGB triples) for each color present in the
+% output image; (2) A pixel array, which represents each pixel as an
+% index into the color map array.
+%
+% First, the assignment phase makes one pass over the pruned color
+% description tree to establish the image's color map. For each node
+% with n2 > 0, it divides Sr, Sg, and Sb by n2 . This produces the mean
+% color of all pixels that classify no lower than this node. Each of
+% these colors becomes an entry in the color map.
+%
+% Finally, the assignment phase reclassifies each pixel in the pruned
+% tree to identify the deepest node containing the pixel's color. The
+% pixel's value in the pixel array becomes the index of this node's mean
+% color in the color map.
+%
+% The format of the AssignImageColors() method is:
+%
+% unsigned int AssignImageColors(CubeInfo *cube_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static MagickPassFail AssignImageColors(CubeInfo *cube_info,Image *image)
+{
+#define AssignImageText "[%s] Assign colors..."
+
+ IndexPacket
+ index;
+
+ long
+ count,
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register const NodeInfo
+ *node_info;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ dither;
+
+ unsigned int
+ id,
+ is_grayscale,
+ is_monochrome;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Allocate image colormap.
+ */
+ if (!AllocateImageColormap(image,cube_info->colors))
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToQuantizeImage);
+ image->colors=0;
+ is_grayscale=image->is_grayscale;
+ is_monochrome=image->is_monochrome;
+ DefineImageColormap(image,cube_info->root);
+ if (cube_info->quantize_info->colorspace == TransparentColorspace)
+ image->storage_class=DirectClass;
+ /*
+ Create a reduced color image.
+ */
+ dither=cube_info->quantize_info->dither;
+ if (dither)
+ dither=DitherImage(cube_info,image);
+ if (!dither)
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x+=count)
+ {
+ /*
+ Identify the deepest node containing the pixel's color.
+ */
+ for (count=1; (x+count) < (long) image->columns; count++)
+ if (NotColorMatch(q,q+count))
+ break;
+ node_info=cube_info->root;
+ for (index=MaxTreeDepth-1; (long) index > 0; index--)
+ {
+ id=ColorToNodeId(q->red,q->green,q->blue,index);
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ break;
+ node_info=node_info->child[id];
+ }
+ /*
+ Find closest color among siblings and their children.
+ */
+ cube_info->color.red=q->red;
+ cube_info->color.green=q->green;
+ cube_info->color.blue=q->blue;
+ cube_info->distance=3.0*((double) MaxRGB+1.0)*((double) MaxRGB+1.0);
+ ClosestColor(image,cube_info,node_info->parent);
+ index=(IndexPacket) cube_info->color_number;
+ for (i=0; i < count; i++)
+ {
+ if (image->storage_class == PseudoClass)
+ indexes[x+i]=index;
+ if (!cube_info->quantize_info->measure_error)
+ {
+ q->red=image->colormap[index].red;
+ q->green=image->colormap[index].green;
+ q->blue=image->colormap[index].blue;
+ }
+ q++;
+ }
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ AssignImageText,image->filename))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if ((cube_info->quantize_info->number_colors == 2) &&
+ (IsGrayColorspace(cube_info->quantize_info->colorspace)))
+ {
+ Quantum
+ intensity;
+
+ /*
+ Monochrome image.
+ */
+ is_monochrome=True;
+ q=image->colormap;
+ for (i=(long) image->colors; i > 0; i--)
+ {
+ intensity=(Quantum) (PixelIntensityToQuantum(q) <
+ (MaxRGB/2) ? 0 : MaxRGB);
+ q->red=intensity;
+ q->green=intensity;
+ q->blue=intensity;
+ q++;
+ }
+ }
+ if (cube_info->quantize_info->measure_error)
+ (void) GetImageQuantizeError(image);
+ status &= SyncImage(image);
+ image->is_grayscale=is_grayscale;
+ image->is_monochrome=is_monochrome;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l a s s i f y I m a g e C o l o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ClassifyImageColors() begins by initializing a color description tree
+% of sufficient depth to represent each possible input color in a leaf.
+% However, it is impractical to generate a fully-formed color
+% description tree in the storage_class phase for realistic values of
+% Cmax. If colors components in the input image are quantized to k-bit
+% precision, so that Cmax= 2k-1, the tree would need k levels below the
+% root node to allow representing each possible input color in a leaf.
+% This becomes prohibitive because the tree's total number of nodes is
+% 1 + sum(i=1,k,8k).
+%
+% A complete tree would require 19,173,961 nodes for k = 8, Cmax = 255.
+% Therefore, to avoid building a fully populated tree, QUANTIZE: (1)
+% Initializes data structures for nodes only as they are needed; (2)
+% Chooses a maximum depth for the tree as a function of the desired
+% number of colors in the output image (currently log2(colormap size)).
+%
+% For each pixel in the input image, storage_class scans downward from
+% the root of the color description tree. At each level of the tree it
+% identifies the single node which represents a cube in RGB space
+% containing It updates the following data for each such node:
+%
+% n1 : Number of pixels whose color is contained in the RGB cube
+% which this node represents;
+%
+% n2 : Number of pixels whose color is not represented in a node at
+% lower depth in the tree; initially, n2 = 0 for all nodes except
+% leaves of the tree.
+%
+% Sr, Sg, Sb : Sums of the red, green, and blue component values for
+% all pixels not classified at a lower depth. The combination of
+% these sums and n2 will ultimately characterize the mean color of a
+% set of pixels represented by this node.
+%
+% E: The distance squared in RGB space between each pixel contained
+% within a node and the nodes' center. This represents the quantization
+% error for a node.
+%
+% The format of the ClassifyImageColors() method is:
+%
+% unsigned int ClassifyImageColorsCubeInfo *cube_info,const Image *image,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+
+static MagickPassFail ClassifyImageColors(CubeInfo *cube_info,const Image *image,
+ ExceptionInfo *exception)
+{
+#define ClassifyImageText "[%s] Classify colors..."
+
+ double
+ bisect;
+
+ DoublePixelPacket
+ mid,
+ pixel;
+
+ long
+ count,
+ y;
+
+ NodeInfo
+ *node_info;
+
+ register long
+ x;
+
+ register const PixelPacket
+ *p;
+
+ unsigned long
+ index,
+ level;
+
+ unsigned int
+ id;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Classify the first 256 colors to a tree depth of 8.
+ */
+ for (y=0; (y < (long) image->rows) && (cube_info->colors < 256); y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (cube_info->nodes > MaxNodes)
+ {
+ /*
+ Prune one level if the color tree is too large.
+ */
+ PruneLevel(cube_info,cube_info->root);
+ cube_info->depth--;
+ }
+ for (x=0; x < (long) image->columns; x+=count)
+ {
+ /*
+ Start at the root and descend the color cube tree.
+ */
+ for (count=1; (x+count) < (long) image->columns; count++)
+ if (NotColorMatch(p,p+count))
+ break;
+ index=MaxTreeDepth-1;
+ bisect=((double) MaxRGB+1.0)/2.0;
+ mid.red=MaxRGB/2.0;
+ mid.green=MaxRGB/2.0;
+ mid.blue=MaxRGB/2.0;
+ node_info=cube_info->root;
+ for (level=1; level <= 8; level++)
+ {
+ bisect/=2;
+ id=ColorToNodeId(p->red,p->green,p->blue,index);
+ mid.red+=id & 4 ? bisect : -bisect;
+ mid.green+=id & 2 ? bisect : -bisect;
+ mid.blue+=id & 1 ? bisect : -bisect;
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ {
+ /*
+ Set colors of new node to contain pixel.
+ */
+ node_info->child[id]=GetNodeInfo(cube_info,id,level,node_info);
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ ThrowException3(exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToQuantizeImage);
+ if (level == MaxTreeDepth)
+ cube_info->colors++;
+ }
+ /*
+ Approximate the quantization error represented by this node.
+ */
+ node_info=node_info->child[id];
+ pixel.red=p->red-mid.red;
+ pixel.green=p->green-mid.green;
+ pixel.blue=p->blue-mid.blue;
+ node_info->quantize_error+=count*pixel.red*pixel.red+
+ count*pixel.green*pixel.green+count*pixel.blue*pixel.blue;
+ cube_info->root->quantize_error+=node_info->quantize_error;
+ index--;
+ }
+ /*
+ Sum RGB for this leaf for later derivation of the mean cube color.
+ */
+ node_info->number_unique+=count;
+ node_info->total_red+=(double) count*p->red;
+ node_info->total_green+=(double) count*p->green;
+ node_info->total_blue+=(double) count*p->blue;
+ p+=count;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ ClassifyImageText,image->filename))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (y == (long) image->rows)
+ return(True);
+ /*
+ More than 256 colors; classify to the cube_info->depth tree depth.
+ */
+ PruneToCubeDepth(cube_info,cube_info->root);
+ for ( ; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (cube_info->nodes > MaxNodes)
+ {
+ /*
+ Prune one level if the color tree is too large.
+ */
+ PruneLevel(cube_info,cube_info->root);
+ cube_info->depth--;
+ }
+ for (x=0; x < (long) image->columns; x+=count)
+ {
+ /*
+ Start at the root and descend the color cube tree.
+ */
+ for (count=1; (x+count) < (long) image->columns; count++)
+ if (NotColorMatch(p,p+count))
+ break;
+ index=MaxTreeDepth-1;
+ bisect=((double) MaxRGB+1.0)/2.0;
+ mid.red=MaxRGB/2.0;
+ mid.green=MaxRGB/2.0;
+ mid.blue=MaxRGB/2.0;
+ node_info=cube_info->root;
+ for (level=1; level <= cube_info->depth; level++)
+ {
+ bisect/=2;
+ id=ColorToNodeId(p->red,p->green,p->blue,index);
+ mid.red+=id & 4 ? bisect : -bisect;
+ mid.green+=id & 2 ? bisect : -bisect;
+ mid.blue+=id & 1 ? bisect : -bisect;
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ {
+ /*
+ Set colors of new node to contain pixel.
+ */
+ node_info->child[id]=GetNodeInfo(cube_info,id,level,node_info);
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ ThrowException3(exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToQuantizeImage);
+ if (level == cube_info->depth)
+ cube_info->colors++;
+ }
+ /*
+ Approximate the quantization error represented by this node.
+ */
+ node_info=node_info->child[id];
+ pixel.red=p->red-mid.red;
+ pixel.green=p->green-mid.green;
+ pixel.blue=p->blue-mid.blue;
+ node_info->quantize_error+=count*pixel.red*pixel.red+
+ count*pixel.green*pixel.green+count*pixel.blue*pixel.blue;
+ cube_info->root->quantize_error+=node_info->quantize_error;
+ index--;
+ }
+ /*
+ Sum RGB for this leaf for later derivation of the mean cube color.
+ */
+ node_info->number_unique+=count;
+ node_info->total_red+=(double) count*p->red;
+ node_info->total_green+=(double) count*p->green;
+ node_info->total_blue+=(double) count*p->blue;
+ p+=count;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ ClassifyImageText,image->filename))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e Q u a n t i z e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneQuantizeInfo() makes a duplicate of the given quantize info structure,
+% or if quantize info is NULL, a new one.
+%
+% The format of the CloneQuantizeInfo method is:
+%
+% QuantizeInfo *CloneQuantizeInfo(const QuantizeInfo *quantize_info)
+%
+% A description of each parameter follows:
+%
+% o clone_info: Method CloneQuantizeInfo returns a duplicate of the given
+% quantize info, or if image info is NULL a new one.
+%
+% o quantize_info: a structure of type info.
+%
+%
+*/
+MagickExport QuantizeInfo *CloneQuantizeInfo(const QuantizeInfo *quantize_info)
+{
+ QuantizeInfo
+ *clone_info;
+
+ clone_info=MagickAllocateMemory(QuantizeInfo *,sizeof(QuantizeInfo));
+ if (clone_info == (QuantizeInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateQuantizeInfo);
+ GetQuantizeInfo(clone_info);
+ if (quantize_info == (QuantizeInfo *) NULL)
+ return(clone_info);
+ clone_info->number_colors=quantize_info->number_colors;
+ clone_info->tree_depth=quantize_info->tree_depth;
+ clone_info->dither=quantize_info->dither;
+ clone_info->colorspace=quantize_info->colorspace;
+ clone_info->measure_error=quantize_info->measure_error;
+ return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l o s e s t C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ClosestColor() traverses the color cube tree at a particular node and
+% determines which colormap entry best represents the input color.
+%
+% The format of the ClosestColor method is:
+%
+% void ClosestColor(Image *image,CubeInfo *cube_info,
+% const NodeInfo *node_info)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o node_info: The address of a structure of type NodeInfo which points to a
+% node in the color cube tree that is to be pruned.
+%
+%
+*/
+static void ClosestColor(Image *image,CubeInfo *cube_info,
+ const NodeInfo *node_info)
+{
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < MaxTreeDepth; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ ClosestColor(image,cube_info,node_info->child[id]);
+ if (node_info->number_unique != 0)
+ {
+ double
+ distance;
+
+ DoublePixelPacket
+ pixel;
+
+ register PixelPacket
+ *color;
+
+ /*
+ Determine if this color is "closest".
+ */
+ color=image->colormap+node_info->color_number;
+ pixel.red=color->red-cube_info->color.red;
+ distance=pixel.red*pixel.red;
+ if (distance < cube_info->distance)
+ {
+ pixel.green=color->green-cube_info->color.green;
+ distance+=pixel.green*pixel.green;
+ if (distance < cube_info->distance)
+ {
+ pixel.blue=color->blue-cube_info->color.blue;
+ distance+=pixel.blue*pixel.blue;
+ if (distance < cube_info->distance)
+ {
+ cube_info->distance=distance;
+ cube_info->color_number=node_info->color_number;
+ }
+ }
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o m p r e s s I m a g e C o l o r m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CompressImageColormap() compresses an image colormap by removing any
+% duplicate or unused color entries.
+%
+% The format of the CompressImageColormap method is:
+%
+% void CompressImageColormap(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+MagickExport void CompressImageColormap(Image *image)
+{
+ QuantizeInfo
+ quantize_info;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (!IsPaletteImage(image,&image->exception))
+ return;
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.number_colors=image->colors;
+ quantize_info.tree_depth=MaxTreeDepth;
+ (void) QuantizeImage(&quantize_info,image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e f i n e I m a g e C o l o r m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DefineImageColormap() traverses the color cube tree and notes each colormap
+% entry. A colormap entry is any node in the color cube tree where the
+% of unique colors is not zero.
+%
+% The format of the DefineImageColormap method is:
+%
+% DefineImageColormap(Image *image,NodeInfo *node_info)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o node_info: The address of a structure of type NodeInfo which points to a
+% node in the color cube tree that is to be pruned.
+%
+%
+*/
+static void DefineImageColormap(Image *image,NodeInfo *node_info)
+{
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < MaxTreeDepth; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ DefineImageColormap(image,node_info->child[id]);
+ if (node_info->number_unique != 0)
+ {
+ register double
+ number_unique;
+
+ /*
+ Colormap entry is defined by the mean color in this cube.
+ */
+ number_unique=node_info->number_unique;
+ image->colormap[image->colors].red=(Quantum)
+ (node_info->total_red/number_unique+0.5);
+ image->colormap[image->colors].green=(Quantum)
+ (node_info->total_green/number_unique+0.5);
+ image->colormap[image->colors].blue=(Quantum)
+ (node_info->total_blue/number_unique+0.5);
+ node_info->color_number=image->colors++;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y C u b e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyCubeInfo() deallocates memory associated with an image.
+%
+% The format of the DestroyCubeInfo method is:
+%
+% DestroyCubeInfo(CubeInfo *cube_info)
+%
+% A description of each parameter follows:
+%
+% o cube_info: The address of a structure of type CubeInfo.
+%
+%
+*/
+static void DestroyCubeInfo(CubeInfo *cube_info)
+{
+ register Nodes
+ *nodes;
+
+ /*
+ Release color cube tree storage.
+ */
+ do
+ {
+ nodes=cube_info->node_queue->next;
+ MagickFreeMemory(cube_info->node_queue->nodes);
+ MagickFreeMemory(cube_info->node_queue);
+ cube_info->node_queue=nodes;
+ } while (cube_info->node_queue != (Nodes *) NULL);
+ if (cube_info->quantize_info->dither)
+ MagickFreeMemory(cube_info->cache);
+ MagickFreeMemory(cube_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y Q u a n t i z e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyQuantizeInfo() deallocates memory associated with an QuantizeInfo
+% structure.
+%
+% The format of the DestroyQuantizeInfo method is:
+%
+% DestroyQuantizeInfo(QuantizeInfo *quantize_info)
+%
+% A description of each parameter follows:
+%
+% o quantize_info: Specifies a pointer to an QuantizeInfo structure.
+%
+%
+*/
+MagickExport void DestroyQuantizeInfo(QuantizeInfo *quantize_info)
+{
+ assert(quantize_info != (QuantizeInfo *) NULL);
+ assert(quantize_info->signature == MagickSignature);
+ MagickFreeMemory(quantize_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D i t h e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Dither() distributes the difference between an original image and the
+% corresponding color reduced algorithm to neighboring pixels along a Hilbert
+% curve.
+%
+% The format of the Dither method is:
+%
+% unsigned int Dither(CubeInfo *cube_info,Image *image,
+% const unsigned int direction)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o direction: This unsigned direction describes which direction
+% to move to next to follow the Hilbert curve.
+%
+*/
+static MagickPassFail Dither(CubeInfo *cube_info,Image *image,
+ const unsigned int direction)
+{
+ DoublePixelPacket
+ error;
+
+ IndexPacket
+ index;
+
+ PixelPacket
+ pixel;
+
+ register CubeInfo
+ *p;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i;
+
+ register PixelPacket
+ *q;
+
+ p=cube_info;
+ if ((p->x >= 0) && (p->x < (long) image->columns) &&
+ (p->y >= 0) && (p->y < (long) image->rows))
+ {
+ /*
+ Distribute error.
+ */
+ q=GetImagePixels(image,p->x,p->y,1,1);
+ if (q == (PixelPacket *) NULL)
+ return(MagickFail);
+ indexes=AccessMutableIndexes(image);
+ error.red=q->red;
+ error.green=q->green;
+ error.blue=q->blue;
+ for (i=0; i < ExceptionQueueLength; i++)
+ {
+ error.red+=p->error[i].red*p->weights[i];
+ error.green+=p->error[i].green*p->weights[i];
+ error.blue+=p->error[i].blue*p->weights[i];
+ }
+
+ pixel.red=RoundDoubleToQuantum(error.red);
+ pixel.green=RoundDoubleToQuantum(error.green);
+ pixel.blue=RoundDoubleToQuantum(error.blue);
+
+ i=(pixel.blue >> CacheShift) << 12 | (pixel.green >> CacheShift) << 6 |
+ (pixel.red >> CacheShift);
+ if (p->cache[i] < 0)
+ {
+ register NodeInfo
+ *node_info;
+
+ register unsigned int
+ id;
+
+ /*
+ Identify the deepest node containing the pixel's color.
+ */
+ node_info=p->root;
+ for (index=MaxTreeDepth-1; (long) index > 0; index--)
+ {
+ id=ColorToNodeId(pixel.red,pixel.green,pixel.blue,index);
+ if (node_info->child[id] == (NodeInfo *) NULL)
+ break;
+ node_info=node_info->child[id];
+ }
+ /*
+ Find closest color among siblings and their children.
+ */
+ p->color.red=pixel.red;
+ p->color.green=pixel.green;
+ p->color.blue=pixel.blue;
+ p->distance=3.0*((double) MaxRGB+1.0)*((double) MaxRGB+1.0);
+ ClosestColor(image,p,node_info->parent);
+ p->cache[i]=(long) p->color_number;
+ }
+ /*
+ Assign pixel to closest colormap entry.
+ */
+ index=(IndexPacket) p->cache[i];
+ if (image->storage_class == PseudoClass)
+ *indexes=index;
+ if (!cube_info->quantize_info->measure_error)
+ {
+ q->red=image->colormap[index].red;
+ q->green=image->colormap[index].green;
+ q->blue=image->colormap[index].blue;
+ }
+ if (!SyncImagePixels(image))
+ return(MagickFail);
+ /*
+ Propagate the error as the last entry of the error queue.
+ */
+ for (i=0; i < (ExceptionQueueLength-1); i++)
+ p->error[i]=p->error[i+1];
+ p->error[i].red=pixel.red-(double) image->colormap[index].red;
+ p->error[i].green=pixel.green-(double) image->colormap[index].green;
+ p->error[i].blue=pixel.blue-(double) image->colormap[index].blue;
+ }
+ switch (direction)
+ {
+ case WestGravity: p->x--; break;
+ case EastGravity: p->x++; break;
+ case NorthGravity: p->y--; break;
+ case SouthGravity: p->y++; break;
+ }
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D i t h e r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DitherImage() distributes the difference between an original image and the
+% corresponding color reduced algorithm to neighboring pixels along a Hilbert
+% curve. DitherImage returns True if the image is dithered otherwise False.
+%
+% This algorithm is strongly based on a similar algorithm by Thiadmer
+% Riemersma.
+%
+% The format of the DitherImage method is:
+%
+% unsigned int DitherImage(CubeInfo *cube_info,Image *image)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+static MagickPassFail DitherImage(CubeInfo *cube_info,Image *image)
+{
+ register unsigned long
+ i;
+
+ unsigned long
+ depth;
+
+ /*
+ Initialize error queue.
+ */
+ for (i=0; i < ExceptionQueueLength; i++)
+ {
+ cube_info->error[i].red=0.0;
+ cube_info->error[i].green=0.0;
+ cube_info->error[i].blue=0.0;
+ }
+ /*
+ Distribute quantization error along a Hilbert curve.
+ */
+ cube_info->x=0;
+ cube_info->y=0;
+ i=image->columns > image->rows ? image->columns : image->rows;
+ for (depth=1; i != 0; depth++)
+ i>>=1;
+ HilbertCurve(cube_info,image,depth-1,NorthGravity);
+ (void) Dither(cube_info,image,ForgetGravity);
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t C u b e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetCubeInfo() initialize the Cube data structure.
+%
+% The format of the GetCubeInfo method is:
+%
+% CubeInfo GetCubeInfo(const QuantizeInfo *quantize_info,
+% unsigned int depth)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o quantize_info: Specifies a pointer to an QuantizeInfo structure.
+%
+% o depth: Normally, this integer value is zero or one. A zero or
+% one tells Quantize to choose a optimal tree depth of Log4(number_colors).
+% A tree of this depth generally allows the best representation of the
+% reference image with the least amount of memory and the fastest
+% computational speed. In some cases, such as an image with low color
+% dispersion (a few number of colors), a value other than
+% Log4(number_colors) is required. To expand the color tree completely,
+% use a value of 8.
+%
+%
+*/
+static CubeInfo *GetCubeInfo(const QuantizeInfo *quantize_info,
+ unsigned long depth)
+{
+ CubeInfo
+ *cube_info;
+
+ double
+ sum,
+ weight;
+
+ register long
+ i;
+
+ /*
+ Initialize tree to describe color cube_info.
+ */
+ cube_info=MagickAllocateMemory(CubeInfo *,sizeof(CubeInfo));
+ if (cube_info == (CubeInfo *) NULL)
+ return((CubeInfo *) NULL);
+ (void) memset(cube_info,0,sizeof(CubeInfo));
+ if (depth > MaxTreeDepth)
+ depth=MaxTreeDepth;
+ if (depth < 2)
+ depth=2;
+ cube_info->depth=depth;
+ /*
+ Initialize root node.
+ */
+ cube_info->root=GetNodeInfo(cube_info,0,0,(NodeInfo *) NULL);
+ if (cube_info->root == (NodeInfo *) NULL)
+ return((CubeInfo *) NULL);
+ cube_info->root->parent=cube_info->root;
+ cube_info->quantize_info=quantize_info;
+ if (!cube_info->quantize_info->dither)
+ return(cube_info);
+ /*
+ Initialize dither resources.
+ */
+ cube_info->cache=MagickAllocateMemory(long *,(1 << 18)*sizeof(long));
+ if (cube_info->cache == (long *) NULL)
+ return((CubeInfo *) NULL);
+ /*
+ Initialize color cache.
+ */
+ for (i=0; i < (1 << 18); i++)
+ cube_info->cache[i]=(-1);
+ /*
+ Distribute weights along a curve of exponential decay.
+ */
+ weight=1.0;
+ for (i=0; i < ExceptionQueueLength; i++)
+ {
+ cube_info->weights[ExceptionQueueLength-i-1]=1.0/weight;
+ weight*=exp(log(((double) MaxRGB+1.0))/(ExceptionQueueLength-1.0));
+ }
+ /*
+ Normalize the weighting factors.
+ */
+ weight=0.0;
+ for (i=0; i < ExceptionQueueLength; i++)
+ weight+=cube_info->weights[i];
+ sum=0.0;
+ for (i=0; i < ExceptionQueueLength; i++)
+ {
+ cube_info->weights[i]/=weight;
+ sum+=cube_info->weights[i];
+ }
+ cube_info->weights[0]+=1.0-sum;
+ return(cube_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t N o d e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetNodeInfo() allocates memory for a new node in the color cube tree and
+% presets all fields to zero.
+%
+% The format of the GetNodeInfo method is:
+%
+% NodeInfo *GetNodeInfo(CubeInfo *cube_info,const unsigned int id,
+% const unsigned int level,NodeInfo *parent)
+%
+% A description of each parameter follows.
+%
+% o node: The GetNodeInfo method returns this integer address.
+%
+% o id: Specifies the child number of the node.
+%
+% o level: Specifies the level in the storage_class the node resides.
+%
+%
+*/
+static NodeInfo *GetNodeInfo(CubeInfo *cube_info,const unsigned int id,
+ const unsigned int level,NodeInfo *parent)
+{
+ NodeInfo
+ *node_info;
+
+ if (cube_info->free_nodes == 0)
+ {
+ Nodes
+ *nodes;
+
+ /*
+ Allocate a new nodes of nodes.
+ */
+ nodes=MagickAllocateMemory(Nodes *,sizeof(Nodes));
+ if (nodes == (Nodes *) NULL)
+ return((NodeInfo *) NULL);
+ nodes->nodes=MagickAllocateMemory(NodeInfo *,(NodesInAList*sizeof(NodeInfo)));
+ if (nodes->nodes == (NodeInfo *) NULL)
+ return((NodeInfo *) NULL);
+ nodes->next=cube_info->node_queue;
+ cube_info->node_queue=nodes;
+ cube_info->next_node=nodes->nodes;
+ cube_info->free_nodes=NodesInAList;
+ }
+ cube_info->nodes++;
+ cube_info->free_nodes--;
+ node_info=cube_info->next_node++;
+ (void) memset(node_info,0,sizeof(NodeInfo));
+ node_info->parent=parent;
+ node_info->id=id;
+ node_info->level=level;
+ return(node_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e Q u a n t i z e E r r o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageQuantizeError() measures the difference between the original
+% and quantized images. This difference is the total quantization error.
+% The error is computed by summing over all pixels in an image the distance
+% squared in RGB space between each reference pixel value and its quantized
+% value. These values are computed:
+%
+% o mean_error_per_pixel: This value is the mean error for any single
+% pixel in the image.
+%
+% o normalized_mean_square_error: This value is the normalized mean
+% quantization error for any single pixel in the image. This distance
+% measure is normalized to a range between 0 and 1. It is independent
+% of the range of red, green, and blue values in the image.
+%
+% o normalized_maximum_square_error: This value is the normalized
+% maximum quantization error for any single pixel in the image. This
+% distance measure is normalized to a range between 0 and 1. It is
+% independent of the range of red, green, and blue values in your image.
+%
+%
+% The format of the GetImageQuantizeError method is:
+%
+% unsigned int GetImageQuantizeError(Image *image)
+%
+% A description of each parameter follows.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport MagickPassFail GetImageQuantizeError(Image *image)
+{
+ double
+ distance,
+ maximum_error_per_pixel,
+ normalize;
+
+ DoublePixelPacket
+ pixel;
+
+ IndexPacket
+ index;
+
+ long
+ y;
+
+ ErrorSumType
+ total_error;
+
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize measurement.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ image->total_colors=GetNumberColors(image,(FILE *) NULL,&image->exception);
+ (void) memset(&image->error,0,sizeof(ErrorInfo));
+ if (image->storage_class == DirectClass)
+ return(MagickFail);
+ /*
+ For each pixel, collect error statistics.
+ */
+ maximum_error_per_pixel=0;
+ total_error=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=indexes[x];
+ pixel.red=p->red-(double) image->colormap[index].red;
+ pixel.green=p->green-(double) image->colormap[index].green;
+ pixel.blue=p->blue-(double) image->colormap[index].blue;
+ distance=pixel.red*pixel.red+pixel.green*pixel.green+
+ pixel.blue*pixel.blue;
+ total_error+=distance;
+ if (distance > maximum_error_per_pixel)
+ maximum_error_per_pixel=distance;
+ p++;
+ }
+ }
+ /*
+ Compute final error statistics.
+ */
+ normalize=3.0*((double) MaxRGB+1.0)*((double) MaxRGB+1.0);
+ image->error.mean_error_per_pixel=total_error/image->columns/image->rows;
+ image->error.normalized_mean_error=
+ image->error.mean_error_per_pixel/normalize;
+ image->error.normalized_maximum_error=maximum_error_per_pixel/normalize;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t Q u a n t i z e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetQuantizeInfo() initializes the QuantizeInfo structure.
+%
+% The format of the GetQuantizeInfo method is:
+%
+% GetQuantizeInfo(QuantizeInfo *quantize_info)
+%
+% A description of each parameter follows:
+%
+% o quantize_info: Specifies a pointer to a QuantizeInfo structure.
+%
+%
+*/
+MagickExport void GetQuantizeInfo(QuantizeInfo *quantize_info)
+{
+ assert(quantize_info != (QuantizeInfo *) NULL);
+ (void) memset(quantize_info,0,sizeof(QuantizeInfo));
+ quantize_info->number_colors=256;
+ quantize_info->dither=True;
+ quantize_info->colorspace=RGBColorspace;
+ quantize_info->signature=MagickSignature;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G r a y s c a l e P s e u d o C l a s s I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GrayscalePseudoClassImage converts an image to a PseudoClass
+% grayscale representation with an (optionally) compressed and sorted
+% colormap. Colormap is ordered by increasing intensity.
+%
+% The format of the GrayscalePseudoClassImage method is:
+%
+% void GrayscalePseudoClassImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o optimize_colormap: If true, produce an optimimal (compact) colormap.
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int IntensityCompare(const void *x,const void *y)
+{
+ long
+ intensity;
+
+ PixelPacket
+ *color_1,
+ *color_2;
+
+ color_1=(PixelPacket *) x;
+ color_2=(PixelPacket *) y;
+ intensity=PixelIntensityToQuantum(color_1)-
+ (long) PixelIntensityToQuantum(color_2);
+ return(intensity);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+MagickExport void GrayscalePseudoClassImage(Image *image,
+ unsigned int optimize_colormap)
+{
+ long
+ y;
+
+ register long
+ x;
+
+ register IndexPacket
+ *indexes;
+
+ register const PixelPacket
+ *q;
+
+ register unsigned int
+ i;
+
+ int
+ *colormap_index=(int *) NULL;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (!image->is_grayscale)
+ (void) TransformColorspace(image,GRAYColorspace);
+
+ if (image->storage_class != PseudoClass)
+ {
+ /*
+ Allocate maximum sized grayscale image colormap
+ */
+ if (!AllocateImageColormap(image,MaxColormapSize))
+ {
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToSortImageColormap);
+ return;
+ }
+
+ if (optimize_colormap)
+ {
+ /*
+ Use minimal colormap method.
+ */
+
+ /*
+ Allocate memory for colormap index
+ */
+ colormap_index=MagickAllocateMemory(int *,MaxColormapSize*sizeof(int));
+ if (colormap_index == (int *) NULL)
+ {
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToSortImageColormap);
+ return;
+ }
+
+ /*
+ Initial colormap index value is -1 so we can tell if it
+ is initialized.
+ */
+ for (i=0; i < MaxColormapSize; i++)
+ colormap_index[i]=-1;
+
+ image->colors=0;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ register int
+ intensity;
+
+ /*
+ If index is new, create index to colormap
+ */
+ intensity=ScaleQuantumToMap(q->red);
+ if (colormap_index[intensity] < 0)
+ {
+ colormap_index[intensity]=image->colors;
+ image->colormap[image->colors]=*q;
+ image->colors++;
+ }
+ *indexes++=colormap_index[intensity];
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ {
+ MagickFreeMemory(colormap_index);
+ return;
+ }
+ }
+ }
+ else
+ {
+ /*
+ Use fast-cut linear colormap method.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *indexes=ScaleQuantumToIndex(q->red);
+ q++;
+ indexes++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ image->is_grayscale=True;
+ return;
+ }
+ }
+
+ if (optimize_colormap)
+ {
+ /*
+ Sort and compact the colormap
+ */
+
+ /*
+ Allocate memory for colormap index
+ */
+ if (colormap_index == (int *) NULL)
+ {
+ colormap_index=MagickAllocateArray(int *,MaxColormapSize,sizeof(int));
+ if (colormap_index == (int *) NULL)
+ {
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToSortImageColormap);
+ return;
+ }
+ }
+
+ /*
+ Assign index values to colormap entries.
+ */
+ for (i=0; i < image->colors; i++)
+ image->colormap[i].opacity=(unsigned short) i;
+ /*
+ Sort image colormap by increasing intensity.
+ */
+ qsort((void *) image->colormap,image->colors,sizeof(PixelPacket),
+ IntensityCompare);
+ /*
+ Create mapping between original indexes and reduced/sorted
+ colormap.
+ */
+ {
+ PixelPacket
+ *new_colormap;
+
+ int
+ j;
+
+ new_colormap=MagickAllocateMemory(PixelPacket *,image->colors*sizeof(PixelPacket));
+ if (new_colormap == (PixelPacket *) NULL)
+ {
+ MagickFreeMemory(colormap_index);
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToSortImageColormap);
+ return;
+ }
+
+ j=0;
+ new_colormap[j]=image->colormap[0];
+ for (i=0; i < image->colors; i++)
+ {
+ if (NotColorMatch(&new_colormap[j],&image->colormap[i]))
+ {
+ j++;
+ new_colormap[j]=image->colormap[i];
+ }
+
+ colormap_index[image->colormap[i].opacity]=j;
+ }
+ image->colors=j+1;
+ MagickFreeMemory(image->colormap);
+ image->colormap=new_colormap;
+ }
+
+ /*
+ Reassign image colormap indexes
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *indexes=colormap_index[*indexes];
+ indexes++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ MagickFreeMemory(colormap_index);
+ }
+ image->is_monochrome=IsMonochromeImage(image,&image->exception);
+ image->is_grayscale=True;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ H i l b e r t C u r v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% HilbertCurve() s a space filling curve that visits every point in a square
+% grid with any power of 2. Hilbert is useful in dithering due to the
+% coherence between neighboring pixels. Here, the quantization error is
+% distributed along the Hilbert curve.
+%
+% The format of the HilbertCurve method is:
+%
+% void HilbertCurve(CubeInfo *cube_info,Image *image,
+% const unsigned long level,const unsigned int direction)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o direction: This unsigned direction describes which direction
+% to move to next to follow the Hilbert curve.
+%
+%
+*/
+static void HilbertCurve(CubeInfo *cube_info,Image *image,
+ const unsigned long level,const unsigned int direction)
+{
+ if (level == 1)
+ {
+ switch (direction)
+ {
+ case WestGravity:
+ {
+ (void) Dither(cube_info,image,EastGravity);
+ (void) Dither(cube_info,image,SouthGravity);
+ (void) Dither(cube_info,image,WestGravity);
+ break;
+ }
+ case EastGravity:
+ {
+ (void) Dither(cube_info,image,WestGravity);
+ (void) Dither(cube_info,image,NorthGravity);
+ (void) Dither(cube_info,image,EastGravity);
+ break;
+ }
+ case NorthGravity:
+ {
+ (void) Dither(cube_info,image,SouthGravity);
+ (void) Dither(cube_info,image,EastGravity);
+ (void) Dither(cube_info,image,NorthGravity);
+ break;
+ }
+ case SouthGravity:
+ {
+ (void) Dither(cube_info,image,NorthGravity);
+ (void) Dither(cube_info,image,WestGravity);
+ (void) Dither(cube_info,image,SouthGravity);
+ break;
+ }
+ default:
+ break;
+ }
+ return;
+ }
+ switch (direction)
+ {
+ case WestGravity:
+ {
+ HilbertCurve(cube_info,image,level-1,NorthGravity);
+ (void) Dither(cube_info,image,EastGravity);
+ HilbertCurve(cube_info,image,level-1,WestGravity);
+ (void) Dither(cube_info,image,SouthGravity);
+ HilbertCurve(cube_info,image,level-1,WestGravity);
+ (void) Dither(cube_info,image,WestGravity);
+ HilbertCurve(cube_info,image,level-1,SouthGravity);
+ break;
+ }
+ case EastGravity:
+ {
+ HilbertCurve(cube_info,image,level-1,SouthGravity);
+ (void) Dither(cube_info,image,WestGravity);
+ HilbertCurve(cube_info,image,level-1,EastGravity);
+ (void) Dither(cube_info,image,NorthGravity);
+ HilbertCurve(cube_info,image,level-1,EastGravity);
+ (void) Dither(cube_info,image,EastGravity);
+ HilbertCurve(cube_info,image,level-1,NorthGravity);
+ break;
+ }
+ case NorthGravity:
+ {
+ HilbertCurve(cube_info,image,level-1,WestGravity);
+ (void) Dither(cube_info,image,SouthGravity);
+ HilbertCurve(cube_info,image,level-1,NorthGravity);
+ (void) Dither(cube_info,image,EastGravity);
+ HilbertCurve(cube_info,image,level-1,NorthGravity);
+ (void) Dither(cube_info,image,NorthGravity);
+ HilbertCurve(cube_info,image,level-1,EastGravity);
+ break;
+ }
+ case SouthGravity:
+ {
+ HilbertCurve(cube_info,image,level-1,EastGravity);
+ (void) Dither(cube_info,image,NorthGravity);
+ HilbertCurve(cube_info,image,level-1,SouthGravity);
+ (void) Dither(cube_info,image,WestGravity);
+ HilbertCurve(cube_info,image,level-1,SouthGravity);
+ (void) Dither(cube_info,image,SouthGravity);
+ HilbertCurve(cube_info,image,level-1,WestGravity);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MapImage() replaces the colors of an image with the closest color from a
+% reference image.
+%
+% The format of the MapImage method is:
+%
+% unsigned int MapImage(Image *image,const Image *map_image,
+% const unsigned int dither)
+%
+% A description of each parameter follows:
+%
+% o image: Specifies a pointer to an Image structure.
+%
+% o map_image: Specifies a pointer to an Image structure. Reduce
+% image to a set of colors represented by this image.
+%
+% o dither: Set this integer value to something other than zero to
+% dither the quantized image.
+%
+%
+*/
+MagickExport MagickPassFail MapImage(Image *image,const Image *map_image,
+ const unsigned int dither)
+{
+ CubeInfo
+ *cube_info;
+
+ QuantizeInfo
+ quantize_info;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize color cube.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(map_image != (Image *) NULL);
+ assert(map_image->signature == MagickSignature);
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.dither=dither;
+ quantize_info.colorspace=
+ image->matte ? TransparentColorspace : RGBColorspace;
+ cube_info=GetCubeInfo(&quantize_info,MaxTreeDepth);
+ if (cube_info == (CubeInfo *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToMapImage);
+ status=ClassifyImageColors(cube_info,map_image,&image->exception);
+ if (status != MagickFail)
+ {
+ /*
+ Classify image colors from the reference image.
+ */
+ quantize_info.number_colors=cube_info->colors;
+ status=AssignImageColors(cube_info,image);
+ }
+ DestroyCubeInfo(cube_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a p I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MapImages() replaces the colors of a sequence of images with the closest
+% color from a reference image. If the reference image does not contain a
+% colormap, then a colormap will be created based on existing colors in the
+% reference image. The order and number of colormap entries does not match
+% the reference image. If the order and number of colormap entries needs to
+% match the reference image, then the ReplaceImageColormap() function may be
+% used after invoking MapImages() in order to apply the reference colormap.
+%
+% The format of the MapImage method is:
+%
+% unsigned int MapImages(Image *images,Image *map_image,
+% const unsigned int dither)
+%
+% A description of each parameter follows:
+%
+% o image: Specifies a pointer to a set of Image structures.
+%
+% o map_image: Specifies a pointer to an Image structure. Reduce
+% image to a set of colors represented by this image.
+%
+% o dither: Set this integer value to something other than zero to
+% dither the quantized image.
+%
+%
+*/
+MagickExport MagickPassFail MapImages(Image *images,const Image *map_image,
+ const unsigned int dither)
+{
+ CubeInfo
+ *cube_info;
+
+ Image
+ *image;
+
+ QuantizeInfo
+ quantize_info;
+
+ MagickPassFail
+ status;
+
+ assert(images != (Image *) NULL);
+ assert(images->signature == MagickSignature);
+ GetQuantizeInfo(&quantize_info);
+ quantize_info.dither=dither;
+ image=images;
+ if (map_image == (Image *) NULL)
+ {
+ /*
+ Create a global colormap for an image sequence.
+ */
+ for ( ; image != (Image *) NULL; image=image->next)
+ if (image->matte)
+ quantize_info.colorspace=TransparentColorspace;
+ status=QuantizeImages(&quantize_info,images);
+ return(status);
+ }
+ /*
+ Classify image colors from the reference image.
+ */
+ cube_info=GetCubeInfo(&quantize_info,8);
+ if (cube_info == (CubeInfo *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToMapImageSequence);
+ status=ClassifyImageColors(cube_info,map_image,&image->exception);
+ if (status != MagickFail)
+ {
+ /*
+ Classify image colors from the reference image.
+ */
+ quantize_info.number_colors=cube_info->colors;
+ for (image=images; image != (Image *) NULL; image=image->next)
+ {
+ quantize_info.colorspace=image->matte ? TransparentColorspace :
+ RGBColorspace;
+ status=AssignImageColors(cube_info,image);
+ if (status == MagickFail)
+ break;
+ }
+ }
+ DestroyCubeInfo(cube_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% O r d e r e d D i t h e r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% OrderedDitherImage() uses the ordered dithering technique of reducing color
+% images to monochrome using positional information to retain as much
+% information as possible.
+%
+% The format of the OrderedDitherImage method is:
+%
+% unsigned int OrderedDitherImage(Image *image)
+%
+% A description of each parameter follows.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport MagickPassFail OrderedDitherImage(Image *image)
+{
+#define DitherImageText "[%s] Ordered dither..."
+
+ static Quantum
+ DitherMatrix[8][8] =
+ {
+ { 0, 192, 48, 240, 12, 204, 60, 252 },
+ { 128, 64, 176, 112, 140, 76, 188, 124 },
+ { 32, 224, 16, 208, 44, 236, 28, 220 },
+ { 160, 96, 144, 80, 172, 108, 156, 92 },
+ { 8, 200, 56, 248, 4, 196, 52, 244 },
+ { 136, 72, 184, 120, 132, 68, 180, 116 },
+ { 40, 232, 24, 216, 36, 228, 20, 212 },
+ { 168, 104, 152, 88, 164, 100, 148, 84 }
+ };
+
+ IndexPacket
+ index;
+
+ long
+ y;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize colormap.
+ */
+ (void) NormalizeImage(image);
+ if (!AllocateImageColormap(image,2))
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDitherImage);
+ /*
+ Dither image with the ordered dithering technique.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ index=(Quantum) (PixelIntensityToQuantum(q) >
+ ScaleCharToQuantum(DitherMatrix[y & 0x07][x & 0x07]) ? 1 : 0);
+ indexes[x]=index;
+ q->red=image->colormap[index].red;
+ q->green=image->colormap[index].green;
+ q->blue=image->colormap[index].blue;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ {
+ status=MagickFail;
+ break;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ DitherImageText,image->filename))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ P r u n e C h i l d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PruneChild() deletes the given node and merges its statistics into its
+% parent.
+%
+% The format of the PruneSubtree method is:
+%
+% PruneChild(CubeInfo *cube_info,const NodeInfo *node_info)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o node_info: pointer to node in color cube tree that is to be pruned.
+%
+%
+*/
+static void PruneChild(CubeInfo *cube_info,const NodeInfo *node_info)
+{
+ NodeInfo
+ *parent;
+
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < MaxTreeDepth; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ PruneChild(cube_info,node_info->child[id]);
+ /*
+ Merge color statistics into parent.
+ */
+ parent=node_info->parent;
+ parent->number_unique+=node_info->number_unique;
+ parent->total_red+=node_info->total_red;
+ parent->total_green+=node_info->total_green;
+ parent->total_blue+=node_info->total_blue;
+ parent->child[node_info->id]=(NodeInfo *) NULL;
+ cube_info->nodes--;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ P r u n e L e v e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PruneLevel() deletes all nodes at the bottom level of the color tree merging
+% their color statistics into their parent node.
+%
+% The format of the PruneLevel method is:
+%
+% PruneLevel(CubeInfo *cube_info,const NodeInfo *node_info)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o node_info: pointer to node in color cube tree that is to be pruned.
+%
+%
+*/
+static void PruneLevel(CubeInfo *cube_info,const NodeInfo *node_info)
+{
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < MaxTreeDepth; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ PruneLevel(cube_info,node_info->child[id]);
+ if (node_info->level == cube_info->depth)
+ PruneChild(cube_info,node_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ P r u n e T o C u b e D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PruneToCubeDepth() deletes any nodes ar a depth greater than
+% cube_info->depth while merging their color statistics into their parent
+% node.
+%
+% The format of the PruneToCubeDepth method is:
+%
+% PruneToCubeDepth(CubeInfo *cube_info,const NodeInfo *node_info)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o node_info: pointer to node in color cube tree that is to be pruned.
+%
+%
+*/
+static void PruneToCubeDepth(CubeInfo *cube_info,const NodeInfo *node_info)
+{
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < MaxTreeDepth; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ PruneToCubeDepth(cube_info,node_info->child[id]);
+ if (node_info->level > cube_info->depth)
+ PruneChild(cube_info,node_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Q u a n t i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% QuantizeImage() analyzes the colors within a reference image and chooses a
+% fixed number of colors to represent the image. The goal of the algorithm
+% is to minimize the color difference between the input and output image while
+% minimizing the processing time.
+%
+% The format of the QuantizeImage method is:
+%
+% unsigned int QuantizeImage(const QuantizeInfo *quantize_info,
+% Image *image)
+%
+% A description of each parameter follows:
+%
+% o quantize_info: Specifies a pointer to an QuantizeInfo structure.
+%
+% o image: Specifies a pointer to an Image structure.
+%
+*/
+MagickExport MagickPassFail QuantizeImage(const QuantizeInfo *quantize_info,
+ Image *image)
+{
+ CubeInfo
+ *cube_info;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ depth,
+ number_colors;
+
+ assert(quantize_info != (const QuantizeInfo *) NULL);
+ assert(quantize_info->signature == MagickSignature);
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ number_colors=quantize_info->number_colors;
+ if (number_colors == 0)
+ number_colors=MaxColormapSize;
+ if (number_colors > MaxColormapSize)
+ number_colors=MaxColormapSize;
+ /*
+ For grayscale images, use a fast translation to PseudoClass,
+ which assures that the maximum number of colors is equal to, or
+ less than MaxColormapSize.
+ */
+ if (IsGrayColorspace(quantize_info->colorspace))
+ (void) TransformColorspace(image,quantize_info->colorspace);
+ if (IsGrayImage(image,&image->exception))
+ GrayscalePseudoClassImage(image,True);
+ /*
+ If the image colors do not require further reduction, then simply
+ return.
+ */
+ if ((image->storage_class == PseudoClass) &&
+ (image->colors <= number_colors))
+ return(MagickPass);
+ depth=quantize_info->tree_depth;
+ if (depth == 0)
+ {
+ unsigned long
+ colors;
+
+ /*
+ Depth of color tree is: Log4(colormap size)+2.
+ */
+ colors=number_colors;
+ for (depth=1; colors != 0; depth++)
+ colors>>=2;
+ if (quantize_info->dither)
+ depth--;
+ if (image->storage_class == PseudoClass)
+ depth+=2;
+ }
+ /*
+ Initialize color cube.
+ */
+ cube_info=GetCubeInfo(quantize_info,depth);
+ if (cube_info == (CubeInfo *) NULL)
+ ThrowBinaryException3(ResourceLimitError,
+ MemoryAllocationFailed,UnableToQuantizeImage);
+ if (quantize_info->colorspace != RGBColorspace)
+ (void) TransformColorspace(image,quantize_info->colorspace);
+ status=ClassifyImageColors(cube_info,image,&image->exception);
+ if (status != MagickFail)
+ {
+ /*
+ Reduce the number of colors in the image.
+ */
+ ReduceImageColors(image->filename,cube_info,number_colors,&image->exception);
+ status=AssignImageColors(cube_info,image);
+ if (quantize_info->colorspace != RGBColorspace)
+ (void) TransformColorspace(image,quantize_info->colorspace);
+ }
+ DestroyCubeInfo(cube_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Q u a n t i z e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% QuantizeImages() analyzes the colors within a set of reference images and
+% chooses a fixed number of colors to represent the set. The goal of the
+% algorithm is to minimize the color difference between the input and output
+% images while minimizing the processing time.
+%
+% The format of the QuantizeImages method is:
+%
+% unsigned int QuantizeImages(const QuantizeInfo *quantize_info,
+% Image *images)
+%
+% A description of each parameter follows:
+%
+% o quantize_info: Specifies a pointer to an QuantizeInfo structure.
+%
+% o images: Specifies a pointer to a list of Image structures.
+%
+%
+*/
+MagickExport MagickPassFail QuantizeImages(const QuantizeInfo *quantize_info,
+ Image *images)
+{
+ CubeInfo
+ *cube_info;
+
+ int
+ depth;
+
+ MonitorHandler
+ handler;
+
+ Image
+ *image;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ unsigned long
+ number_colors,
+ number_images;
+
+ assert(quantize_info != (const QuantizeInfo *) NULL);
+ assert(quantize_info->signature == MagickSignature);
+ assert(images != (Image *) NULL);
+ assert(images->signature == MagickSignature);
+ if (images->next == (Image *) NULL)
+ {
+ /*
+ Handle a single image with QuantizeImage.
+ */
+ status=QuantizeImage(quantize_info,images);
+ return(status);
+ }
+ status=False;
+ image=images;
+ number_colors=quantize_info->number_colors;
+ if (number_colors == 0)
+ number_colors=MaxColormapSize;
+ if (number_colors > MaxColormapSize)
+ number_colors=MaxColormapSize;
+ depth=quantize_info->tree_depth;
+ if (depth == 0)
+ {
+ int
+ pseudo_class;
+
+ unsigned long
+ colors;
+
+ /*
+ Depth of color tree is: Log4(colormap size)+2.
+ */
+ colors=number_colors;
+ for (depth=1; colors != 0; depth++)
+ colors>>=2;
+ if (quantize_info->dither)
+ depth--;
+ pseudo_class=True;
+ for (image=images; image != (Image *) NULL; image=image->next)
+ pseudo_class|=(image->storage_class == PseudoClass);
+ if (pseudo_class)
+ depth+=2;
+ }
+ /*
+ Initialize color cube.
+ */
+ cube_info=GetCubeInfo(quantize_info,depth);
+ if (cube_info == (CubeInfo *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToQuantizeImageSequence);
+ image=images;
+ for (i=0; image != (Image *) NULL; i++)
+ {
+ if (quantize_info->colorspace != RGBColorspace)
+ (void) TransformColorspace(image,quantize_info->colorspace);
+ image=image->next;
+ }
+ number_images=i;
+ image=images;
+ for (i=0; image != (Image *) NULL; i++)
+ {
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ status=ClassifyImageColors(cube_info,image,&image->exception);
+ if (status == MagickFail)
+ break;
+ image=image->next;
+ (void) SetMonitorHandler(handler);
+ if ((image != (Image *) NULL) &&
+ (!MagickMonitorFormatted(i,number_images,&image->exception,
+ ClassifyImageText,image->filename)))
+ break;
+ }
+ if (status != MagickFail)
+ {
+ /*
+ Reduce the number of colors in an image sequence.
+ */
+ ReduceImageColors(image->filename,cube_info,number_colors,&image->exception);
+ image=images;
+ for (i=0; image != (Image *) NULL; i++)
+ {
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ status=AssignImageColors(cube_info,image);
+ if (status == MagickFail)
+ break;
+ if (quantize_info->colorspace != RGBColorspace)
+ (void) TransformColorspace(image,quantize_info->colorspace);
+ image=image->next;
+ (void) SetMonitorHandler(handler);
+ if ((image != (Image *) NULL) &&
+ (!MagickMonitorFormatted(i,number_images,&image->exception,
+ AssignImageText,image->filename)))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ }
+ DestroyCubeInfo(cube_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e d u c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Reduce() traverses the color cube tree and prunes any node whose
+% quantization error falls below a particular threshold.
+%
+% The format of the Reduce method is:
+%
+% Reduce(CubeInfo *cube_info,const NodeInfo *node_info)
+%
+% A description of each parameter follows.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o node_info: pointer to node in color cube tree that is to be pruned.
+%
+%
+*/
+static void Reduce(CubeInfo *cube_info,const NodeInfo *node_info)
+{
+ register unsigned int
+ id;
+
+ /*
+ Traverse any children.
+ */
+ for (id=0; id < MaxTreeDepth; id++)
+ if (node_info->child[id] != (NodeInfo *) NULL)
+ Reduce(cube_info,node_info->child[id]);
+ if (node_info->quantize_error <= cube_info->pruning_threshold)
+ PruneChild(cube_info,node_info);
+ else
+ {
+ /*
+ Find minimum pruning threshold.
+ */
+ if (node_info->number_unique > 0)
+ cube_info->colors++;
+ if (node_info->quantize_error < cube_info->next_threshold)
+ cube_info->next_threshold=node_info->quantize_error;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e d u c e I m a g e C o l o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReduceImageColors() repeatedly prunes the tree until the number of nodes
+% with n2 > 0 is less than or equal to the maximum number of colors allowed
+% in the output image. On any given iteration over the tree, it selects
+% those nodes whose E value is minimal for pruning and merges their
+% color statistics upward. It uses a pruning threshold, Ep, to govern
+% node selection as follows:
+%
+% Ep = 0
+% while number of nodes with (n2 > 0) > required maximum number of colors
+% prune all nodes such that E <= Ep
+% Set Ep to minimum E in remaining nodes
+%
+% This has the effect of minimizing any quantization error when merging
+% two nodes together.
+%
+% When a node to be pruned has offspring, the pruning procedure invokes
+% itself recursively in order to prune the tree from the leaves upward.
+% n2, Sr, Sg, and Sb in a node being pruned are always added to the
+% corresponding data in that node's parent. This retains the pruned
+% node's color characteristics for later averaging.
+%
+% For each node, n2 pixels exist for which that node represents the
+% smallest volume in RGB space containing those pixel's colors. When n2
+% > 0 the node will uniquely define a color in the output image. At the
+% beginning of reduction, n2 = 0 for all nodes except a the leaves of
+% the tree which represent colors present in the input image.
+%
+% The other pixel count, n1, indicates the total number of colors
+% within the cubic volume which the node represents. This includes n1 -
+% n2 pixels whose colors should be defined by nodes at a lower level in
+% the tree.
+%
+% The format of the ReduceImageColors method is:
+%
+% ReduceImageColors(const char *filename, CubeInfo *cube_info,
+% const unsigned int number_colors, ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o filename: Filename for use in progress messages.
+%
+% o cube_info: A pointer to the Cube structure.
+%
+% o number_colors: This integer value indicates the maximum number of
+% colors in the quantized image or colormap. The actual number of
+% colors allocated to the colormap may be less than this value, but
+% never more.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+static void ReduceImageColors(const char *filename,CubeInfo *cube_info,
+ const unsigned long number_colors,ExceptionInfo *exception)
+{
+#define ReduceImageText "[%s] Reduce colors: %lu..."
+
+ unsigned int
+ status;
+
+ unsigned long
+ span;
+
+ span=cube_info->colors;
+ cube_info->next_threshold=0.0;
+ while (cube_info->colors > number_colors)
+ {
+ cube_info->pruning_threshold=cube_info->next_threshold;
+ cube_info->next_threshold=cube_info->root->quantize_error-1;
+ cube_info->colors=0;
+ Reduce(cube_info,cube_info->root);
+ status=MagickMonitorFormatted(span-cube_info->colors,
+ span-number_colors+1,exception,
+ ReduceImageText,
+ filename,
+ number_colors);
+ if (status == False)
+ break;
+ }
+}
diff --git a/magick/quantize.h b/magick/quantize.h
new file mode 100644
index 0000000..89a76cf
--- /dev/null
+++ b/magick/quantize.h
@@ -0,0 +1,81 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Methods to Reduce the Number of Unique Colors in an Image.
+*/
+#ifndef _MAGICK_QUANTIZE_H
+#define _MAGICK_QUANTIZE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Define declarations.
+*/
+#define MaxTreeDepth 8
+#define NodesInAList 1536
+
+/*
+ Typedef declarations.
+*/
+typedef struct _QuantizeInfo
+{
+ unsigned long
+ number_colors;
+
+ unsigned int
+ tree_depth,
+ dither;
+
+ ColorspaceType
+ colorspace;
+
+ unsigned int
+ measure_error;
+
+ unsigned long
+ signature;
+} QuantizeInfo;
+
+/*
+ Quantization utilities methods.
+*/
+extern MagickExport QuantizeInfo
+ *CloneQuantizeInfo(const QuantizeInfo *);
+
+extern MagickExport unsigned int
+ GetImageQuantizeError(Image *),
+ MapImage(Image *,const Image *,const unsigned int),
+ MapImages(Image *,const Image *,const unsigned int),
+ OrderedDitherImage(Image *),
+ QuantizeImage(const QuantizeInfo *,Image *),
+ QuantizeImages(const QuantizeInfo *,Image *),
+ SegmentImage(Image *,const ColorspaceType,const unsigned int,const double,
+ const double);
+
+extern MagickExport void
+ CompressImageColormap(Image *),
+ DestroyQuantizeInfo(QuantizeInfo *),
+ GetQuantizeInfo(QuantizeInfo *),
+ GrayscalePseudoClassImage(Image *,unsigned int);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/random-private.h b/magick/random-private.h
new file mode 100644
index 0000000..2ceb899
--- /dev/null
+++ b/magick/random-private.h
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2009, 2014 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Random number generator (private not-installed parts).
+
+ Currently based on George Marsaglia's multiply-with-carry generator.
+ This is a k=2 generator with a period >2^60.
+*/
+#ifndef _MAGICK_RANDOM_PRIVATE_H
+#define _MAGICK_RANDOM_PRIVATE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+#include "magick/random.h"
+
+ /*
+ You may replace the following two constants MAGICK_RANDOM_ZC and
+ MAGICK_RANDOM_WC by any pair of distinct constants from this list:
+
+ 18000 18030 18273 18513 18879 19074 19098 19164 19215 19584
+ 19599 19950 20088 20508 20544 20664 20814 20970 21153 21243
+ 21423 21723 21954 22125 22188 22293 22860 22938 22965 22974
+ 23109 23124 23163 23208 23508 23520 23553 23658 23865 24114
+ 24219 24660 24699 24864 24948 25023 25308 25443 26004 26088
+ 26154 26550 26679 26838 27183 27258 27753 27795 27810 27834
+ 27960 28320 28380 28689 28710 28794 28854 28959 28980 29013
+ 29379 29889 30135 30345 30459 30714 30903 30963 31059 31083
+
+ (or any other 16-bit constants k for which both k*2^16-1 and
+ k*2^15-1 are prime).
+ */
+#define MAGICK_RANDOM_ZC 36969
+#define MAGICK_RANDOM_WC 18000
+
+ /*
+ Generate a random integer value
+ */
+ static inline magick_uint32_t MagickRandomIntegerInlined(MagickRandomKernel *kernel)
+ {
+ kernel->z = MAGICK_RANDOM_ZC * (kernel->z & 65535U) + (kernel->z >> 16U);
+ kernel->w = MAGICK_RANDOM_WC * (kernel->w & 65535U) + (kernel->w >> 16U);
+ return (kernel->z << 16U) + (kernel->w & 65535U);
+ }
+
+ /*
+ Generate a random double value (0.0 to 1.0)
+ */
+ static inline double MagickRandomRealInlined(MagickRandomKernel *kernel)
+ {
+ double result = MagickRandomIntegerInlined(kernel) * 2.3283064370807974e-10;
+ if (result > 1.0)
+ result=1.0;
+ return result;
+ }
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* ifndef _MAGICK_RANDOM_PRIVATE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/random.c b/magick/random.c
new file mode 100644
index 0000000..be4af22
--- /dev/null
+++ b/magick/random.c
@@ -0,0 +1,231 @@
+/*
+% Copyright (C) 2009-2015 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% Random number generator.
+%
+% Currently based on George Marsaglia's multiply-with-carry generator.
+% This is a k=2 generator with a period >2^60.
+%
+*/
+
+#include "magick/studio.h"
+#include "magick/random-private.h"
+#include "magick/random.h"
+#include "magick/semaphore.h"
+#include "magick/tsd.h"
+#include "magick/utility.h"
+
+#if defined(HAVE_PTHREAD)
+# define USE_POSIX_THREADS 1
+#elif defined(MSWINDOWS)
+# define USE_WIN32_THREADS 1
+#endif
+
+#if defined(USE_POSIX_THREADS)
+# include <pthread.h>
+#endif
+#if defined(USE_WIN32_THREADS)
+# include <windows.h>
+#endif
+#if defined(MSWINDOWS) && HAVE_CRYPTGENRANDOM && HAVE_WINCRYPT_H
+# include <wincrypt.h>
+#endif
+
+
+static MagickBool initialized = MagickFalse;
+static SemaphoreInfo *semaphore = (SemaphoreInfo *) 0;
+static MagickTsdKey_t kernel_key = (MagickTsdKey_t) 0;
+
+/*
+ Acquire the default random number kernel. Memory is owned by
+ library and should not be freed.
+*/
+MagickExport MagickRandomKernel* AcquireMagickRandomKernel()
+{
+ MagickRandomKernel
+ *kernel;
+
+ if (!initialized)
+ InitializeMagickRandomGenerator();
+
+ kernel=(MagickRandomKernel *) MagickTsdGetSpecific(kernel_key);
+ if (kernel == (MagickRandomKernel *) NULL)
+ {
+ kernel=MagickAllocateAlignedMemory(MagickRandomKernel *,
+ MAGICK_CACHE_LINE_SIZE,
+ sizeof(MagickRandomKernel));
+ if (kernel == (MagickRandomKernel *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateRandomKernel);
+ InitializeMagickRandomKernel(kernel);
+ MagickTsdSetSpecific(kernel_key,(const void *) kernel);
+ }
+
+ return kernel;
+}
+
+/*
+ Initialize the random number generator system.
+*/
+void InitializeMagickRandomGenerator()
+{
+ assert(semaphore == (SemaphoreInfo *) NULL);
+ semaphore=AllocateSemaphoreInfo();
+
+ if (!initialized)
+ {
+ MagickTsdKeyCreate2(&kernel_key,MagickFreeAligned);
+ initialized=MagickTrue;
+ }
+}
+
+/*
+ Destroy the random number generator system.
+*/
+void DestroyMagickRandomGenerator()
+{
+ if (initialized)
+ {
+ MagickRandomKernel
+ *kernel;
+
+ /* FIXME: This only frees memory associated with one thread */
+ kernel=(MagickRandomKernel *) MagickTsdGetSpecific(kernel_key);
+ MagickFreeAlignedMemory(kernel);
+ (void) MagickTsdSetSpecific(kernel_key,kernel);
+ MagickTsdKeyDelete(kernel_key);
+ }
+ kernel_key=(MagickTsdKey_t) 0;
+ initialized=MagickFalse;
+ DestroySemaphoreInfo(&semaphore);
+}
+
+/*
+ Initialize the random kernel with suitable entropy
+*/
+MagickExport void
+InitializeMagickRandomKernel(MagickRandomKernel *kernel)
+{
+ MagickBool
+ done = MagickFalse;
+
+ kernel->z = 0U;
+ kernel->w = 0U;
+#if defined(POSIX) && HAVE_DEV_URANDOM
+ /*
+ Read from /dev/urandom
+
+ MinGW's MSYS emulates /dev/random in its shell so a configure
+ test for it produces an invalid result.
+ */
+ {
+ int
+ file;
+
+ if ((file=open("/dev/urandom",O_RDONLY | O_BINARY)) != -1)
+ {
+ if (read(file,(void *) kernel,sizeof(*kernel)) == sizeof(*kernel))
+ done=MagickTrue;
+ (void) close(file);
+ }
+ if (!done)
+ MagickFatalError(ResourceLimitFatalError,UnableToObtainRandomEntropy,
+ NULL);
+ }
+#elif defined(MSWINDOWS) && HAVE_CRYPTGENRANDOM
+ /*
+ Use Windows advapi32.lib CryptGenRandom
+
+ Is claimed to be supported under Windows XP
+ */
+ {
+ HCRYPTPROV
+ hProvider = 0;
+
+ if (CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ {
+ /* Returns zero (FALSE) on failure */
+ if (CryptGenRandom(hProvider, (DWORD) sizeof(*kernel), (BYTE *) kernel))
+ done=MagickTrue;
+ (void) CryptReleaseContext(hProvider, 0);
+ }
+ if (!done)
+ MagickFatalError(ResourceLimitFatalError,UnableToObtainRandomEntropy,
+ NULL);
+ }
+#else
+ /*
+ Fallback implementation
+ */
+
+ /*
+ Initial time of day.
+ */
+ kernel->z ^= (magick_uint32_t) time(0);
+
+ /*
+ Let's hash with the address of kernel as well.
+ */
+ kernel->z ^= (magick_uint32_t) ((magick_uintptr_t) kernel & 4294967295UL);
+
+ /*
+ Process ID
+ */
+ kernel->w ^= (magick_uint32_t) getpid();
+
+ /*
+ Thread ID
+ */
+#if defined(USE_POSIX_THREADS)
+ {
+ union
+ {
+ pthread_t thread_id;
+ magick_uint32_t intval;
+ } pthread_union;
+
+ pthread_union.intval=0U;
+ pthread_union.thread_id=pthread_self();
+ kernel->w ^= pthread_union.intval;
+ }
+#elif defined(USE_WIN32_THREADS)
+ kernel->w ^= ((magick_uint32_t) GetCurrentThreadId());
+#endif
+
+ /*
+ It is quite likely that multiple threads will invoke this function
+ during the same second so we also tap into the default random
+ number generator to help produce a more random seed.
+ */
+ kernel->w ^= (magick_uint32_t) rand();
+#endif
+}
+
+/*
+ Generate a random integer value
+*/
+MagickExport magick_uint32_t MagickRandomInteger(void)
+{
+ MagickRandomKernel
+ *kernel;
+
+ kernel=AcquireMagickRandomKernel();
+ return MagickRandomIntegerInlined(kernel);
+}
+
+/*
+ Generate a random double value
+*/
+MagickExport double MagickRandomReal(void)
+{
+ MagickRandomKernel
+ *kernel;
+
+ kernel=AcquireMagickRandomKernel();
+ return MagickRandomRealInlined(kernel);
+}
diff --git a/magick/random.h b/magick/random.h
new file mode 100644
index 0000000..6ccb38c
--- /dev/null
+++ b/magick/random.h
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2009, 2014 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Random number generator (semi-public interfaces).
+
+ Currently based on George Marsaglia's multiply-with-carry generator.
+ This is a k=2 generator with a period >2^60.
+*/
+
+#ifndef _MAGICK_RANDOM_H
+#define _MAGICK_RANDOM_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+typedef struct _MagickRandomKernel
+{
+ magick_uint32_t z;
+ magick_uint32_t w;
+} MagickRandomKernel;
+
+#define MAGICK_RANDOM_MAX 4294967295
+
+ /*
+ Generate a random integer value (0 - MAGICK_RANDOM_MAX)
+ */
+ MagickExport magick_uint32_t MagickRandomInteger(void);
+
+ /*
+ Generate a random double value (0.0 - 1.0)
+ */
+ MagickExport double MagickRandomReal(void);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+ /*
+ Initialize the random kernel with suitable entropy
+ */
+ MagickExport void InitializeMagickRandomKernel(MagickRandomKernel *kernel);
+
+ /*
+ Acquire the default random number kernel. Memory is owned by
+ library and should not be freed.
+ */
+ MagickExport MagickRandomKernel* AcquireMagickRandomKernel();
+
+ /*
+ Initialize the random number generator system.
+ */
+ extern void InitializeMagickRandomGenerator();
+
+ /*
+ Destroy the random number generator system.
+ */
+ extern void DestroyMagickRandomGenerator();
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* ifndef _MAGICK_RANDOM_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/registry.c b/magick/registry.c
new file mode 100644
index 0000000..3b98a1c
--- /dev/null
+++ b/magick/registry.c
@@ -0,0 +1,514 @@
+/*
+% Copyright (C) 2003-2009 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% RRRR EEEEE GGG IIIII SSSSS TTTTT RRRR Y Y %
+% R R E G I SS T R R Y Y %
+% RRRR EEE G GGG I SSS T RRRR Y %
+% R R E G G I SS T R R Y %
+% R R EEEEE GGG IIIII SSSSS T R R Y %
+% %
+% %
+% GraphicsMagick Registry. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% October 2001 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/registry.h"
+#include "magick/semaphore.h"
+#include "magick/utility.h"
+/*
+ Typedef declarations.
+*/
+typedef struct _RegistryInfo
+{
+ long
+ id;
+
+ RegistryType
+ type;
+
+ void
+ *blob;
+
+ size_t
+ length;
+
+ unsigned long
+ signature;
+
+ struct _RegistryInfo
+ *previous,
+ *next;
+} RegistryInfo;
+
+/*
+ Global declarations.
+*/
+static SemaphoreInfo
+ *registry_semaphore = (SemaphoreInfo *) NULL;
+
+static long
+ current_id = 0;
+
+static RegistryInfo
+ *registry_list = (RegistryInfo *) NULL;
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e l e t e M a g i c k R e g i s t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DeleteMagickRegistry() deletes an entry in the registry as defined by the
+% id. It returns MagickPass if the entry is deleted otherwise MagickFail if
+% no entry is found in the registry that matches the id.
+%
+% The format of the DeleteMagickRegistry method is:
+%
+% MagickPassFail DeleteMagickRegistry(const long id)
+%
+% A description of each parameter follows:
+%
+% o id: The registry id.
+%
+%
+*/
+MagickExport MagickPassFail DeleteMagickRegistry(const long id)
+{
+ register RegistryInfo
+ *p;
+
+ RegistryInfo
+ *registry_info;
+
+ LockSemaphoreInfo(registry_semaphore);
+ for (p=registry_list; p != (RegistryInfo *) NULL; p=p->next)
+ {
+ if (id != p->id)
+ continue;
+ registry_info=p;
+ switch (registry_info->type)
+ {
+ case ImageRegistryType:
+ {
+ DestroyImage((Image *) registry_info->blob);
+ break;
+ }
+ case ImageInfoRegistryType:
+ {
+ DestroyImageInfo((ImageInfo *) registry_info->blob);
+ break;
+ }
+ default:
+ {
+ MagickFreeMemory(registry_info->blob);
+ break;
+ }
+ }
+ if (registry_info == registry_list)
+ registry_list=registry_info->next;
+ if (registry_info->previous != (RegistryInfo *) NULL)
+ registry_info->previous->next=registry_info->next;
+ if (registry_info->next != (RegistryInfo *) NULL)
+ registry_info->next->previous=registry_info->previous;
+ MagickFreeMemory(registry_info);
+ registry_info=(RegistryInfo *) NULL;
+ break;
+ }
+ UnlockSemaphoreInfo(registry_semaphore);
+ return ((p != (RegistryInfo *) NULL) ? MagickPass : MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y M a g i c k R e g i s t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyMagickRegistry() deallocates memory associated the magick registry.
+%
+% The format of the DestroyMagickRegistry method is:
+%
+% void DestroyMagickRegistry(void)
+%
+%
+*/
+void DestroyMagickRegistry(void)
+{
+ register RegistryInfo
+ *p;
+
+ RegistryInfo
+ *registry_info;
+
+ for (p=registry_list; p != (RegistryInfo *) NULL; )
+ {
+ registry_info=p;
+ p=p->next;
+ switch (registry_info->type)
+ {
+ case ImageRegistryType:
+ {
+ DestroyImage((Image *) registry_info->blob);
+ break;
+ }
+ case ImageInfoRegistryType:
+ {
+ DestroyImageInfo((ImageInfo *) registry_info->blob);
+ break;
+ }
+ default:
+ {
+ MagickFreeMemory(registry_info->blob);
+ break;
+ }
+ }
+ MagickFreeMemory(registry_info);
+ }
+ registry_list=(RegistryInfo *) NULL;
+ current_id = 0;
+ DestroySemaphoreInfo(&registry_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e F r o m M a g i c k R e g i s t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageFromMagickRegistry() gets an image from the registry as defined by
+% its name. If the blob that matches the name is not found, NULL is returned.
+%
+% The format of the GetImageFromMagickRegistry method is:
+%
+% Image *GetImageFromMagickRegistry(const char *name,long *id,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o name: The name of the image to retrieve from the registry.
+%
+% o id: The registry id.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *GetImageFromMagickRegistry(const char *name,long *id,
+ ExceptionInfo *exception)
+{
+ Image
+ *image;
+
+ register RegistryInfo
+ *p;
+
+ *id=(-1);
+ image=(Image *) NULL;
+ LockSemaphoreInfo(registry_semaphore);
+ for (p=registry_list; p != (RegistryInfo *) NULL; p=p->next)
+ {
+ if (p->type != ImageRegistryType)
+ continue;
+ if (LocaleCompare(((Image *) p->blob)->filename,name) == 0)
+ {
+ *id=p->id;
+ image=CloneImageList((Image *) p->blob,exception);
+ break;
+ }
+ }
+ UnlockSemaphoreInfo(registry_semaphore);
+ if (image == (Image *) NULL)
+ ThrowException(exception,RegistryError,UnableToLocateImage,name);
+ return (image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M a g i c k R e g i s t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickRegistry() gets a blob from the registry as defined by the id. If
+% the blob that matches the id is not found, NULL is returned.
+%
+% The format of the GetMagickRegistry method is:
+%
+% const void *GetMagickRegistry(const long id,RegistryType *type,
+% size_t *length,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o id: The registry id.
+%
+% o type: The registry type.
+%
+% o length: The blob length in number of bytes.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport void *GetMagickRegistry(const long id,RegistryType *type,
+ size_t *length,ExceptionInfo *exception)
+{
+ register RegistryInfo
+ *p;
+
+ void
+ *blob;
+
+ RegistryInfo
+ *registry_info;
+
+ blob=(void *) NULL;
+ *type=UndefinedRegistryType;
+ *length=0;
+ LockSemaphoreInfo(registry_semaphore);
+ for (p=registry_list; p != (RegistryInfo *) NULL; p=p->next)
+ {
+ if (id != p->id)
+ continue;
+ registry_info=p;
+ switch (registry_info->type)
+ {
+ case ImageRegistryType:
+ {
+ Image
+ *image;
+
+ image=(Image *) registry_info->blob;
+ blob=(void *) CloneImageList(image,exception);
+ break;
+ }
+ case ImageInfoRegistryType:
+ {
+ ImageInfo
+ *image_info;
+
+ image_info=(ImageInfo *) registry_info->blob;
+ blob=(void *) CloneImageInfo(image_info);
+ break;
+ }
+ default:
+ {
+ blob=MagickAllocateMemory(void *,registry_info->length);
+ if (blob == (void *) NULL)
+ {
+ ThrowException3(exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToGetFromRegistry);
+ break;
+ }
+ (void) memcpy(blob,registry_info->blob,registry_info->length);
+ break;
+ }
+ }
+ *type=registry_info->type;
+ *length=registry_info->length;
+ break;
+ }
+ UnlockSemaphoreInfo(registry_semaphore);
+ if (blob == (void *) NULL)
+ {
+ char
+ description[MaxTextExtent];
+
+ FormatString(description,"id=%ld",id);
+ ThrowException(exception,RegistryError,UnableToLocateImage,
+ description);
+ }
+ return(blob);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e M a g i c k R e g i s t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializeMagickRegistry() ensures that the magick registry is ready for
+% use.
+%
+% The format of the InitializeMagickRegistry method is:
+%
+% void InitializeMagickRegistry(void)
+%
+%
+*/
+void InitializeMagickRegistry(void)
+{
+ assert(registry_semaphore == (SemaphoreInfo *) NULL);
+ registry_semaphore=AllocateSemaphoreInfo();
+ current_id = 0;
+ registry_list = (RegistryInfo *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t M a g i c k R e g i s t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetMagickRegistry() sets a blob into the registry and returns a unique ID.
+% If an error occurs, -1 is returned.
+%
+% The format of the SetMagickRegistry method is:
+%
+% long SetMagickRegistry(const RegistryType type,const void *blob,
+% const size_t length,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o type: The registry type.
+%
+% o blob: The address of a Binary Large OBject.
+%
+% o length: For a registry type of ImageRegistryType use sizeof(Image)
+% otherise the blob length in number of bytes.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport long SetMagickRegistry(const RegistryType type,const void *blob,
+ const size_t length,ExceptionInfo *exception)
+{
+ RegistryInfo
+ *registry_info;
+
+ void
+ *clone_blob;
+
+ switch (type)
+ {
+ case ImageRegistryType:
+ {
+ Image
+ *image;
+
+ image=(Image *) blob;
+ if (length != sizeof(Image))
+ {
+ ThrowException3(exception,RegistryError,UnableToSetRegistry,
+ StructureSizeMismatch);
+ return(-1);
+ }
+ if (image->signature != MagickSignature)
+ {
+ ThrowException3(exception,RegistryError,UnableToSetRegistry,
+ ImageExpected);
+ return(-1);
+ }
+ clone_blob=(void *) CloneImageList(image,exception);
+ if (clone_blob == (void *) NULL)
+ return(-1);
+ break;
+ }
+ case ImageInfoRegistryType:
+ {
+ ImageInfo
+ *image_info;
+
+ image_info=(ImageInfo *) blob;
+ if (length != sizeof(ImageInfo))
+ {
+ ThrowException3(exception,RegistryError,UnableToSetRegistry,
+ StructureSizeMismatch);
+ return(-1);
+ }
+ if (image_info->signature != MagickSignature)
+ {
+ ThrowException3(exception,RegistryError,UnableToSetRegistry,
+ ImageInfoExpected);
+ return(-1);
+ }
+ clone_blob=(void *) CloneImageInfo(image_info);
+ if (clone_blob == (void *) NULL)
+ return(-1);
+ break;
+ }
+ default:
+ {
+ clone_blob=MagickAllocateMemory(void *,length);
+ if (clone_blob == (void *) NULL)
+ return(-1);
+ (void) memcpy(clone_blob,blob,length);
+ }
+ }
+ registry_info=MagickAllocateMemory(RegistryInfo *,sizeof(RegistryInfo));
+ if (registry_info == (RegistryInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateRegistryInfo);
+ (void) memset(registry_info,0,sizeof(RegistryInfo));
+ registry_info->type=type;
+ registry_info->blob=clone_blob;
+ registry_info->length=length;
+ registry_info->signature=MagickSignature;
+ LockSemaphoreInfo(registry_semaphore);
+ registry_info->id=current_id++;
+ if (registry_list == (RegistryInfo *) NULL)
+ registry_list=registry_info;
+ else
+ {
+ register RegistryInfo
+ *p;
+
+ for (p=registry_list; p->next != (RegistryInfo *) NULL; p=p->next);
+ registry_info->previous=p;
+ p->next=registry_info;
+ }
+ UnlockSemaphoreInfo(registry_semaphore);
+ return (registry_info->id);
+}
diff --git a/magick/registry.h b/magick/registry.h
new file mode 100644
index 0000000..4ce9245
--- /dev/null
+++ b/magick/registry.h
@@ -0,0 +1,66 @@
+/*
+ Copyright (C) 2003-2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Magick registry methods.
+*/
+#ifndef _MAGICK_REGISTRY_H
+#define _MAGICK_REGISTRY_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ UndefinedRegistryType,
+ ImageRegistryType,
+ ImageInfoRegistryType
+} RegistryType;
+
+/*
+ Magick registry methods.
+*/
+extern MagickExport Image
+ *GetImageFromMagickRegistry(const char *name,long *id,
+ ExceptionInfo *exception);
+
+extern MagickExport long
+ SetMagickRegistry(const RegistryType type,const void *blob,
+ const size_t length,ExceptionInfo *exception);
+
+extern MagickExport MagickPassFail
+ DeleteMagickRegistry(const long id);
+
+extern MagickExport void
+ *GetMagickRegistry(const long id,RegistryType *type,size_t *length,
+ ExceptionInfo *exception);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+extern void
+ DestroyMagickRegistry(void),
+ InitializeMagickRegistry(void);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/render.c b/magick/render.c
new file mode 100644
index 0000000..5f3b2d8
--- /dev/null
+++ b/magick/render.c
@@ -0,0 +1,6152 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% RRRR EEEEE N N DDDD EEEEE RRRR %
+% R R E NN N D D E R R %
+% RRRR EEE N N N D D EEE RRRR %
+% R R E N NN D D E R R %
+% R R EEEEE N N DDDD EEEEE R R %
+% %
+% %
+% GraphicsMagick Image Drawing Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1998 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Bill Radcliffe of Corbis (www.corbis.com) contributed the polygon
+% rendering code based on Paul Heckbert's "Concave Polygon Scan Conversion",
+% Graphics Gems, 1990. Leonard Rosenthal and David Harr of Appligent
+% (www.appligent.com) contributed the dash pattern, linecap stroking
+% algorithm, and minor rendering improvements.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/constitute.h"
+#include "magick/enhance.h"
+#include "magick/enum_strings.h"
+#include "magick/gem.h"
+#include "magick/gradient.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/omp_data_view.h"
+#include "magick/paint.h"
+#include "magick/pixel_cache.h"
+#include "magick/render.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define BezierQuantum 200
+
+/*
+ Typedef declarations.
+*/
+
+typedef struct _EdgeInfo
+{
+ SegmentInfo
+ bounds;
+
+ double
+ scanline;
+
+ PointInfo
+ *points;
+
+ long
+ number_points,
+ direction,
+ highwater;
+
+ MagickBool
+ ghostline;
+
+} EdgeInfo;
+
+typedef struct _PolygonInfo
+{
+ EdgeInfo
+ *edges;
+
+ long
+ number_edges;
+} PolygonInfo;
+
+typedef enum
+{
+ MoveToCode,
+ OpenCode,
+ GhostlineCode,
+ LineToCode,
+ EndCode
+} PathInfoCode;
+
+typedef struct _PathInfo
+{
+ PointInfo
+ point;
+
+ PathInfoCode
+ code;
+} PathInfo;
+
+/*
+ Forward declarations.
+*/
+static PrimitiveInfo
+ *TraceStrokePolygon(const DrawInfo *,const PrimitiveInfo *);
+
+static MagickPassFail
+ DrawPrimitive(Image *,const DrawInfo *,const PrimitiveInfo *),
+ DrawStrokePolygon(Image *,const DrawInfo *,const PrimitiveInfo *);
+
+static unsigned long
+ TracePath(Image *image, PrimitiveInfo *,const char *);
+
+static void
+#if 0
+ DestroyGradientInfo(GradientInfo *),
+#endif
+ DestroyPolygonInfo(void *polygon_info_void),
+ TraceArc(PrimitiveInfo *,const PointInfo,const PointInfo,const PointInfo),
+ TraceArcPath(PrimitiveInfo *,const PointInfo,const PointInfo,const PointInfo,
+ const double,const unsigned int,const unsigned int),
+ TraceBezier(PrimitiveInfo *,const unsigned long),
+ TraceCircle(PrimitiveInfo *,const PointInfo,const PointInfo),
+ TraceEllipse(PrimitiveInfo *,const PointInfo,const PointInfo,const PointInfo),
+ TraceLine(PrimitiveInfo *,const PointInfo,const PointInfo),
+ TracePoint(PrimitiveInfo *,const PointInfo),
+ TraceRectangle(PrimitiveInfo *,const PointInfo,const PointInfo),
+ TraceRoundRectangle(PrimitiveInfo *,const PointInfo,const PointInfo,
+ PointInfo),
+ TraceSquareLinecap(PrimitiveInfo *,const unsigned long,const double);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e D r a w I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneDrawInfo() makes a copy of the given draw info structure. If NULL
+% is specified, a new DrawInfo structure is created initialized to
+% default values.
+%
+% The format of the CloneDrawInfo method is:
+%
+% DrawInfo *CloneDrawInfo(const ImageInfo *image_info,
+% const DrawInfo *draw_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info.
+%
+% o draw_info: The draw info.
+%
+%
+*/
+MagickExport DrawInfo *
+CloneDrawInfo(const ImageInfo *image_info,const DrawInfo *draw_info)
+{
+ DrawInfo
+ *clone_info;
+
+ clone_info=MagickAllocateMemory(DrawInfo *,sizeof(DrawInfo));
+ if (clone_info == (DrawInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateDrawInfo);
+ GetDrawInfo(image_info,clone_info);
+ if (draw_info == (DrawInfo *) NULL)
+ return(clone_info);
+ if (clone_info->primitive != (char *) NULL)
+ (void) CloneString(&clone_info->primitive,draw_info->primitive);
+ if (draw_info->geometry != (char *) NULL)
+ clone_info->geometry=AllocateString(draw_info->geometry);
+ clone_info->affine=draw_info->affine;
+ clone_info->gravity=draw_info->gravity;
+ clone_info->fill=draw_info->fill;
+ clone_info->stroke=draw_info->stroke;
+ clone_info->stroke_width=draw_info->stroke_width;
+ if (draw_info->fill_pattern != (Image *) NULL)
+ clone_info->fill_pattern=CloneImage(draw_info->fill_pattern,0,0,True,
+ &draw_info->fill_pattern->exception);
+ else
+ if (draw_info->tile != (Image *) NULL)
+ clone_info->fill_pattern=CloneImage(draw_info->tile,0,0,True,
+ &draw_info->tile->exception);
+ clone_info->tile=(Image *) NULL; /* tile is deprecated */
+ if (draw_info->stroke_pattern != (Image *) NULL)
+ clone_info->stroke_pattern=CloneImage(draw_info->stroke_pattern,0,0,True,
+ &draw_info->stroke_pattern->exception);
+ clone_info->stroke_antialias=draw_info->stroke_antialias;
+ clone_info->text_antialias=draw_info->text_antialias;
+ clone_info->fill_rule=draw_info->fill_rule;
+ clone_info->linecap=draw_info->linecap;
+ clone_info->linejoin=draw_info->linejoin;
+ clone_info->miterlimit=draw_info->miterlimit;
+ clone_info->dash_offset=draw_info->dash_offset;
+ clone_info->decorate=draw_info->decorate;
+ clone_info->compose=draw_info->compose;
+ if (draw_info->text != (char *) NULL)
+ clone_info->text=AllocateString(draw_info->text);
+ if (draw_info->font != (char *) NULL)
+ (void) CloneString(&clone_info->font,draw_info->font);
+ if (draw_info->family != (char *) NULL)
+ clone_info->family=AllocateString(draw_info->family);
+ clone_info->style=draw_info->style;
+ clone_info->stretch=draw_info->stretch;
+ clone_info->weight=draw_info->weight;
+ if (draw_info->encoding != (char *) NULL)
+ clone_info->encoding=AllocateString(draw_info->encoding);
+ clone_info->pointsize=draw_info->pointsize;
+ if (draw_info->density != (char *) NULL)
+ (void) CloneString(&clone_info->density,draw_info->density);
+ clone_info->align=draw_info->align;
+ clone_info->undercolor=draw_info->undercolor;
+ clone_info->border_color=draw_info->border_color;
+ if (draw_info->server_name != (char *) NULL)
+ (void) CloneString(&clone_info->server_name,draw_info->server_name);
+ if (draw_info->dash_pattern != (double *) NULL)
+ {
+ register long
+ x;
+
+ for (x=0; draw_info->dash_pattern[x] != 0.0; x++);
+ clone_info->dash_pattern=
+ MagickAllocateArray(double *,(x+1),sizeof(double));
+ if (clone_info->dash_pattern == (double *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateDashPattern);
+ (void) memcpy(clone_info->dash_pattern,draw_info->dash_pattern,
+ (x+1)*sizeof(double));
+ }
+ if (draw_info->clip_path != (char *) NULL)
+ clone_info->clip_path=AllocateString(draw_info->clip_path);
+ clone_info->bounds=draw_info->bounds;
+ clone_info->clip_units=draw_info->clip_units;
+ clone_info->render=draw_info->render;
+ clone_info->opacity=draw_info->opacity;
+ clone_info->element_reference=draw_info->element_reference;
+ return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C o n v e r t P a t h T o P o l y g o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ConvertPathToPolygon converts a path to the more efficient sorted
+% rendering form.
+%
+% The format of the ConvertPathToPolygon method is:
+%
+% PolygonInfo *ConvertPathToPolygon(const DrawInfo *draw_info,
+% const PathInfo *path_info)
+%
+% A description of each parameter follows:
+%
+% o Method ConvertPathToPolygon returns the path in a more efficient sorted
+% rendering form of type PolygonInfo.
+%
+% o draw_info: Specifies a pointer to an DrawInfo structure.
+%
+% o path_info: Specifies a pointer to an PathInfo structure.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int
+CompareEdges(const void *x,const void *y)
+{
+ register const EdgeInfo
+ *p,
+ *q;
+
+ /*
+ Compare two edges.
+ */
+ p=(const EdgeInfo *) x;
+ q=(const EdgeInfo *) y;
+ if ((p->points[0].y-MagickEpsilon) > q->points[0].y)
+ return(1);
+ if ((p->points[0].y+MagickEpsilon) < q->points[0].y)
+ return(-1);
+ if ((p->points[0].x-MagickEpsilon) > q->points[0].x)
+ return(1);
+ if ((p->points[0].x+MagickEpsilon) < q->points[0].x)
+ return(-1);
+ if (((p->points[1].x-p->points[0].x)*(q->points[1].y-q->points[0].y)-
+ (p->points[1].y-p->points[0].y)*(q->points[1].x-q->points[0].x)) > 0.0)
+ return(1);
+ return(-1);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+static void
+LogPolygonInfo(const PolygonInfo *polygon_info)
+{
+ register EdgeInfo
+ *p;
+
+ register long
+ i,
+ j;
+
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," begin active-edge");
+ p=polygon_info->edges;
+ for (i=0; i < polygon_info->number_edges; i++)
+ {
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," edge %lu:",i);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," direction: %s",
+ p->direction ? "down" : "up");
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," ghostline: %s",
+ p->ghostline ? "transparent" : "opaque");
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ " bounds: %g,%g - %g,%g",p->bounds.x1,p->bounds.y1,p->bounds.x2,
+ p->bounds.y2);
+ for (j=0; j < p->number_points; j++)
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," %g,%g",
+ p->points[j].x,p->points[j].y);
+ p++;
+ }
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," end active-edge");
+}
+
+static void
+ReversePoints(PointInfo *points,const int number_points)
+{
+ PointInfo
+ point;
+
+ register long
+ i;
+
+ for (i=0; i < (number_points >> 1); i++)
+ {
+ point=points[i];
+ points[i]=points[number_points-(i+1)];
+ points[number_points-(i+1)]=point;
+ }
+}
+
+static PolygonInfo *
+ConvertPathToPolygon(const PathInfo *path_info)
+{
+ long
+ direction,
+ edge,
+ next_direction,
+ number_edges,
+ number_points;
+
+ PointInfo
+ point,
+ *points;
+
+ PolygonInfo
+ *polygon_info;
+
+ SegmentInfo
+ bounds;
+
+ register long
+ i,
+ n;
+
+ MagickBool
+ ghostline;
+
+ /*
+ Convert a path to the more efficient sorted rendering form.
+ */
+ polygon_info=MagickAllocateMemory(PolygonInfo *,sizeof(PolygonInfo));
+ if (polygon_info == (PolygonInfo *) NULL)
+ return((PolygonInfo *) NULL);
+ number_edges=16;
+ polygon_info->edges=
+ MagickAllocateArray(EdgeInfo *,number_edges,sizeof(EdgeInfo));
+ if (polygon_info->edges == (EdgeInfo *) NULL)
+ {
+ DestroyPolygonInfo(polygon_info);
+ return((PolygonInfo *) NULL);
+ }
+ direction=0;
+ edge=0;
+ ghostline=MagickFalse;
+ n=0;
+ number_points=0;
+ points=(PointInfo *) NULL;
+ (void) memset(&point,0,sizeof(PointInfo));
+ (void) memset(&bounds,0,sizeof(SegmentInfo));
+ polygon_info->edges[edge].number_points=n;
+ polygon_info->edges[edge].scanline=0.0;
+ polygon_info->edges[edge].highwater=0;
+ polygon_info->edges[edge].ghostline=ghostline;
+ polygon_info->edges[edge].direction=direction;
+ polygon_info->edges[edge].points=points;
+ polygon_info->edges[edge].bounds=bounds;
+ polygon_info->number_edges=0;
+ for (i=0; path_info[i].code != EndCode; i++)
+ {
+ if ((path_info[i].code == MoveToCode) || (path_info[i].code == OpenCode) ||
+ (path_info[i].code == GhostlineCode))
+ {
+ /*
+ Move to.
+ */
+ if ((points != (PointInfo *) NULL) && (n >= 2))
+ {
+ if (edge == number_edges)
+ {
+ number_edges<<=1;
+ MagickReallocMemory(EdgeInfo *,polygon_info->edges,
+ MagickArraySize(number_edges,sizeof(EdgeInfo)));
+ if (polygon_info->edges == (EdgeInfo *) NULL)
+ {
+ DestroyPolygonInfo(polygon_info);
+ return((PolygonInfo *) NULL);
+ }
+ }
+ polygon_info->edges[edge].number_points=n;
+ polygon_info->edges[edge].scanline=(-1.0);
+ polygon_info->edges[edge].highwater=0;
+ polygon_info->edges[edge].ghostline=ghostline;
+ polygon_info->edges[edge].direction=direction > 0;
+ if (direction < 0)
+ ReversePoints(points,n);
+ polygon_info->edges[edge].points=points;
+ polygon_info->edges[edge].bounds=bounds;
+ polygon_info->edges[edge].bounds.y1=points[0].y;
+ polygon_info->edges[edge].bounds.y2=points[n-1].y;
+ points=(PointInfo *) NULL;
+ ghostline=MagickFalse;
+ edge++;
+ }
+ if (points == (PointInfo *) NULL)
+ {
+ number_points=16;
+ points=
+ MagickAllocateArray(PointInfo *,number_points,sizeof(PointInfo));
+ if (points == (PointInfo *) NULL)
+ {
+ DestroyPolygonInfo(polygon_info);
+ return((PolygonInfo *) NULL);
+ }
+ }
+ ghostline=path_info[i].code == GhostlineCode ? MagickTrue : MagickFalse;
+ point=path_info[i].point;
+ points[0]=point;
+ bounds.x1=point.x;
+ bounds.x2=point.x;
+ direction=0;
+ n=1;
+ continue;
+ }
+ /*
+ Line to.
+ */
+ next_direction=((path_info[i].point.y > point.y) ||
+ ((path_info[i].point.y == point.y) &&
+ (path_info[i].point.x > point.x))) ? 1 : -1;
+ if ((points != (PointInfo *) NULL) && (direction != 0) &&
+ (direction != next_direction))
+ {
+ /*
+ New edge.
+ */
+ point=points[n-1];
+ if (edge == number_edges)
+ {
+ number_edges<<=1;
+ MagickReallocMemory(EdgeInfo *,polygon_info->edges,
+ MagickArraySize(number_edges,sizeof(EdgeInfo)));
+ if (polygon_info->edges == (EdgeInfo *) NULL)
+ {
+ DestroyPolygonInfo(polygon_info);
+ return((PolygonInfo *) NULL);
+ }
+ }
+ polygon_info->edges[edge].number_points=n;
+ polygon_info->edges[edge].scanline=(-1.0);
+ polygon_info->edges[edge].highwater=0;
+ polygon_info->edges[edge].ghostline=ghostline;
+ polygon_info->edges[edge].direction=direction > 0;
+ if (direction < 0)
+ ReversePoints(points,n);
+ polygon_info->edges[edge].points=points;
+ polygon_info->edges[edge].bounds=bounds;
+ polygon_info->edges[edge].bounds.y1=points[0].y;
+ polygon_info->edges[edge].bounds.y2=points[n-1].y;
+ number_points=16;
+ points=
+ MagickAllocateArray(PointInfo *,number_points,sizeof(PointInfo));
+ if (points == (PointInfo *) NULL)
+ {
+ DestroyPolygonInfo(polygon_info);
+ return((PolygonInfo *) NULL);
+ }
+ n=1;
+ ghostline=MagickFalse;
+ points[0]=point;
+ bounds.x1=point.x;
+ bounds.x2=point.x;
+ edge++;
+ }
+ direction=next_direction;
+ if (points == (PointInfo *) NULL)
+ continue;
+ if (n == number_points)
+ {
+ number_points<<=1;
+ MagickReallocMemory(PointInfo *,points,MagickArraySize(number_points,sizeof(PointInfo)));
+ if (points == (PointInfo *) NULL)
+ {
+ DestroyPolygonInfo(polygon_info);
+ return((PolygonInfo *) NULL);
+ }
+ }
+ point=path_info[i].point;
+ points[n]=point;
+ if (point.x < bounds.x1)
+ bounds.x1=point.x;
+ if (point.x > bounds.x2)
+ bounds.x2=point.x;
+ n++;
+ }
+ if (points != (PointInfo *) NULL)
+ {
+ if (n < 2)
+ {
+ MagickFreeMemory(points);
+ }
+ else
+ {
+ if (edge == number_edges)
+ {
+ number_edges<<=1;
+ MagickReallocMemory(EdgeInfo *,polygon_info->edges,
+ MagickArraySize(number_edges,sizeof(EdgeInfo)));
+ if (polygon_info->edges == (EdgeInfo *) NULL)
+ {
+ DestroyPolygonInfo(polygon_info);
+ return((PolygonInfo *) NULL);
+ }
+ }
+ polygon_info->edges[edge].number_points=n;
+ polygon_info->edges[edge].scanline=(-1.0);
+ polygon_info->edges[edge].highwater=0;
+ polygon_info->edges[edge].ghostline=ghostline;
+ polygon_info->edges[edge].direction=direction > 0;
+ if (direction < 0)
+ ReversePoints(points,n);
+ polygon_info->edges[edge].points=points;
+ polygon_info->edges[edge].bounds=bounds;
+ polygon_info->edges[edge].bounds.y1=points[0].y;
+ polygon_info->edges[edge].bounds.y2=points[n-1].y;
+ ghostline=MagickFalse;
+ edge++;
+ }
+ }
+ polygon_info->number_edges=edge;
+ qsort(polygon_info->edges,polygon_info->number_edges,sizeof(EdgeInfo),
+ CompareEdges);
+ if (IsEventLogging())
+ LogPolygonInfo(polygon_info);
+ return(polygon_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C o n v e r t P r i m i t i v e T o P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ConvertPrimitiveToPath converts a PrimitiveInfo structure into a
+% vector path structure.
+%
+% The format of the ConvertPrimitiveToPath method is:
+%
+% PathInfo *ConvertPrimitiveToPath(const DrawInfo *draw_info,
+% const PrimitiveInfo *primitive_info)
+%
+% A description of each parameter follows:
+%
+% o Method ConvertPrimitiveToPath returns a vector path structure of type
+% PathInfo.
+%
+% o draw_info: a structure of type DrawInfo.
+%
+% o primitive_info: Specifies a pointer to an PrimitiveInfo structure.
+%
+%
+*/
+
+static void
+LogPathInfo(const PathInfo *path_info)
+{
+ register const PathInfo
+ *p;
+
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," begin vector-path");
+ for (p=path_info; p->code != EndCode; p++)
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ " %g,%g %s",p->point.x,p->point.y,p->code == GhostlineCode ?
+ "moveto ghostline" : p->code == OpenCode ? "moveto open" :
+ p->code == MoveToCode ? "moveto" : p->code == LineToCode ? "lineto" :
+ "?");
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," end vector-path");
+}
+
+static PathInfo *
+ConvertPrimitiveToPath(const DrawInfo *draw_info,
+ const PrimitiveInfo *primitive_info)
+{
+ PathInfo
+ *path_info;
+
+ PathInfoCode
+ code;
+
+ PointInfo
+ p,
+ q;
+
+ register long
+ i,
+ n;
+
+ long
+ coordinates,
+ start;
+
+ ARG_NOT_USED(draw_info);
+
+ /*
+ Converts a PrimitiveInfo structure into a vector path structure.
+ */
+ switch (primitive_info->primitive)
+ {
+ case PointPrimitive:
+ case ColorPrimitive:
+ case MattePrimitive:
+ case TextPrimitive:
+ case ImagePrimitive:
+ return((PathInfo *) NULL);
+ default:
+ break;
+ }
+ for (i=0; primitive_info[i].primitive != UndefinedPrimitive; i++);
+ path_info=MagickAllocateArray(PathInfo *,(2*i+3),sizeof(PathInfo));
+ if (path_info == (PathInfo *) NULL)
+ return((PathInfo *) NULL);
+ coordinates=0;
+ n=0;
+ p.x=(-1.0);
+ p.y=(-1.0);
+ q.x=(-1.0);
+ q.y=(-1.0);
+ start=0;
+ for (i=0; primitive_info[i].primitive != UndefinedPrimitive; i++)
+ {
+ code=LineToCode;
+ if (coordinates <= 0)
+ {
+ coordinates=(long) primitive_info[i].coordinates;
+ p=primitive_info[i].point;
+ start=n;
+ code=MoveToCode;
+ }
+ coordinates--;
+ /*
+ Eliminate duplicate points.
+ */
+ if ((i == 0) || (fabs(q.x-primitive_info[i].point.x) > MagickEpsilon) ||
+ (fabs(q.y-primitive_info[i].point.y) > MagickEpsilon))
+ {
+ path_info[n].code=code;
+ path_info[n].point=primitive_info[i].point;
+ q=primitive_info[i].point;
+ n++;
+ }
+ if (coordinates > 0)
+ continue;
+ if ((fabs(p.x-primitive_info[i].point.x) <= MagickEpsilon) &&
+ (fabs(p.y-primitive_info[i].point.y) <= MagickEpsilon))
+ continue;
+ /*
+ Mark the p point as open if it does not match the q.
+ */
+ path_info[start].code=OpenCode;
+ path_info[n].code=GhostlineCode;
+ path_info[n].point=primitive_info[i].point;
+ n++;
+ path_info[n].code=LineToCode;
+ path_info[n].point=p;
+ n++;
+ }
+ path_info[n].code=EndCode;
+ path_info[n].point.x=0.0;
+ path_info[n].point.y=0.0;
+ if (IsEventLogging())
+ LogPathInfo(path_info);
+ return(path_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y D r a w I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyDrawInfo() deallocates memory associated with an DrawInfo
+% structure.
+%
+% The format of the DestroyDrawInfo method is:
+%
+% void DestroyDrawInfo(DrawInfo *draw_info)
+%
+% A description of each parameter follows:
+%
+% o draw_info: The draw info.
+%
+%
+*/
+MagickExport void
+DestroyDrawInfo(DrawInfo *draw_info)
+{
+ assert(draw_info != (DrawInfo *) NULL);
+ assert(draw_info->signature == MagickSignature);
+ MagickFreeMemory(draw_info->primitive);
+ MagickFreeMemory(draw_info->text);
+ MagickFreeMemory(draw_info->geometry);
+ if (draw_info->tile != 0)
+ DestroyImage(draw_info->tile);
+ if (draw_info->fill_pattern != (Image *) NULL)
+ DestroyImage(draw_info->fill_pattern);
+ if (draw_info->stroke_pattern != (Image *) NULL)
+ DestroyImage(draw_info->stroke_pattern);
+ MagickFreeMemory(draw_info->font);
+ MagickFreeMemory(draw_info->family);
+ MagickFreeMemory(draw_info->encoding);
+ MagickFreeMemory(draw_info->density);
+ MagickFreeMemory(draw_info->server_name);
+ MagickFreeMemory(draw_info->dash_pattern);
+ MagickFreeMemory(draw_info->clip_path);
+ (void) memset((void *)draw_info,0xbf,sizeof(DrawInfo));
+ MagickFreeMemory(draw_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y E d g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyEdge destroys the specified polygon edge.
+%
+% The format of the DestroyEdge method is:
+%
+% long DestroyEdge(PolygonInfo *polygon_info,const int edge)
+%
+% A description of each parameter follows:
+%
+% o polygon_info: Specifies a pointer to an PolygonInfo structure.
+%
+% o edge: the polygon edge number to destroy.
+%
+%
+*/
+static long
+DestroyEdge(PolygonInfo * restrict polygon_info,const long edge)
+{
+ assert(edge >= 0);
+ assert(edge < polygon_info->number_edges);
+ MagickFreeMemory(polygon_info->edges[edge].points);
+ polygon_info->number_edges--;
+ if (edge < polygon_info->number_edges)
+ (void) memmove(polygon_info->edges+edge,polygon_info->edges+edge+1,
+ (polygon_info->number_edges-edge)*sizeof(EdgeInfo));
+ return(polygon_info->number_edges);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y G r a d i e n t I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyGradientInfo() deallocates memory associated with the GradientInfo
+% list.
+%
+% The format of the DestroyGradientInfo method is:
+%
+% DestroyGradientInfo(GradientInfo *gradient_info)
+%
+% A description of each parameter follows:
+%
+% o gradient_info: The gradient info.
+%
+%
+*/
+#if 0
+static void
+DestroyGradientInfo(GradientInfo *gradient_info)
+{
+ register GradientInfo
+ *p;
+
+ if (gradient_info == (GradientInfo *) NULL)
+ return;
+ assert(gradient_info->signature == MagickSignature);
+ for (p=gradient_info; p->previous != (GradientInfo *) NULL; p=p->previous);
+ for (gradient_info=p; p != (GradientInfo *) NULL; gradient_info=p)
+ {
+ p=p->next;
+ MagickFreeMemory(gradient_info);
+ }
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y P o l y g o n I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyPolygonInfo destroys the PolygonInfo data structure.
+%
+% The format of the DestroyPolygonInfo method is:
+%
+% void DestroyPolygonInfo(PolygonInfo *polygon_info)
+%
+% A description of each parameter follows:
+%
+% o polygon_info: Specifies a pointer to an PolygonInfo structure.
+%
+%
+*/
+static void
+DestroyPolygonInfo(void *polygon_info_void)
+{
+ PolygonInfo
+ *polygon_info = (PolygonInfo *) polygon_info_void;
+
+ if (polygon_info != (PolygonInfo *) NULL)
+ {
+ register long
+ i;
+
+ for (i=0; i < polygon_info->number_edges; i++)
+ MagickFreeMemory(polygon_info->edges[i].points);
+ MagickFreeMemory(polygon_info->edges);
+ MagickFreeMemory(polygon_info);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% D r a w A f f i n e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawAffineImage() composites the source over the destination image as
+% dictated by the affine transform.
+%
+% The format of the DrawAffineImage method is:
+%
+% unsigned int DrawAffineImage(Image *image,const Image *composite,
+% const AffineMatrix *affine)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o image: The composite image.
+%
+% o affine: The affine transform.
+%
+%
+*/
+
+static SegmentInfo
+AffineEdge(const Image *image,const AffineMatrix *affine,
+ const long y,const SegmentInfo *edge)
+{
+ double
+ intercept,
+ z;
+
+ register long
+ x;
+
+ SegmentInfo
+ inverse_edge;
+
+ /*
+ Determine left and right edges.
+ */
+ inverse_edge.x1=edge->x1;
+ inverse_edge.y1=0;
+ inverse_edge.x2=edge->x2;
+ inverse_edge.y2=0;
+ z=affine->ry*(y+0.5)+affine->tx;
+ if (affine->sx > MagickEpsilon)
+ {
+ intercept=(-z/affine->sx);
+ x=(long) ceil(intercept+MagickEpsilon-0.5);
+ if (x > inverse_edge.x1)
+ inverse_edge.x1=x;
+ intercept=(-z+image->columns)/affine->sx;
+ x=(long) ceil(intercept-MagickEpsilon-0.5);
+ if (x < inverse_edge.x2)
+ inverse_edge.x2=x;
+ }
+ else
+ if (affine->sx < -MagickEpsilon)
+ {
+ intercept=(-z+image->columns)/affine->sx;
+ x=(long) ceil(intercept+MagickEpsilon-0.5);
+ if (x > inverse_edge.x1)
+ inverse_edge.x1=x;
+ intercept=(-z/affine->sx);
+ x=(long) ceil(intercept-MagickEpsilon-0.5);
+ if (x < inverse_edge.x2)
+ inverse_edge.x2=x;
+ }
+ else
+ if ((z < 0.0) || (z >= image->columns))
+ {
+ inverse_edge.x2=edge->x1;
+ return(inverse_edge);
+ }
+ /*
+ Determine top and bottom edges.
+ */
+ z=affine->sy*(y+0.5)+affine->ty;
+ if (affine->rx > MagickEpsilon)
+ {
+ intercept=(-z /affine->rx);
+ x=(long) ceil(intercept+MagickEpsilon-0.5);
+ if (x > inverse_edge.x1)
+ inverse_edge.x1=x;
+ intercept=(-z+image->rows)/affine->rx;
+ x=(long) ceil(intercept-MagickEpsilon-0.5);
+ if (x < inverse_edge.x2)
+ inverse_edge.x2=x;
+ }
+ else
+ if (affine->rx < -MagickEpsilon)
+ {
+ intercept=(-z+image->rows)/affine->rx;
+ x=(long) ceil(intercept+MagickEpsilon-0.5);
+ if (x > inverse_edge.x1)
+ inverse_edge.x1=x;
+ intercept=(-z/affine->rx);
+ x=(long) ceil(intercept-MagickEpsilon-0.5);
+ if (x < inverse_edge.x2)
+ inverse_edge.x2=x;
+ }
+ else
+ if ((z < 0) || (z >= image->rows))
+ {
+ inverse_edge.x2=edge->x1;
+ return(inverse_edge);
+ }
+ return(inverse_edge);
+}
+
+static AffineMatrix
+InverseAffineMatrix(const AffineMatrix *affine)
+{
+ AffineMatrix
+ inverse_affine;
+
+ double
+ determinant;
+
+ determinant=1.0/(affine->sx*affine->sy-affine->rx*affine->ry);
+ inverse_affine.sx=determinant*affine->sy;
+ inverse_affine.rx=determinant*(-affine->rx);
+ inverse_affine.ry=determinant*(-affine->ry);
+ inverse_affine.sy=determinant*affine->sx;
+ inverse_affine.tx=
+ (-affine->tx)*inverse_affine.sx-affine->ty*inverse_affine.ry;
+ inverse_affine.ty=
+ (-affine->tx)*inverse_affine.rx-affine->ty*inverse_affine.sy;
+ return(inverse_affine);
+}
+
+#define AffineDrawImageText "[%s] Affine composite..."
+MagickExport MagickPassFail
+DrawAffineImage(Image *image,const Image *composite,
+ const AffineMatrix *affine)
+{
+ MagickPassFail
+ status = MagickPass;
+
+ unsigned long
+ row_count=0;
+
+ AffineMatrix
+ inverse_affine;
+
+ long
+ y,
+ y_max,
+ y_min;
+
+ PointInfo
+ extent[4],
+ min,
+ max;
+
+ register long
+ i;
+
+ SegmentInfo
+ edge;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(composite != (const Image *) NULL);
+ assert(composite->signature == MagickSignature);
+ assert(affine != (AffineMatrix *) NULL);
+
+ /*
+ Determine bounding box.
+ */
+ extent[0].x=0;
+ extent[0].y=0;
+ extent[1].x=composite->columns;
+ extent[1].y=0;
+ extent[2].x=composite->columns;
+ extent[2].y=composite->rows;
+ extent[3].x=0;
+ extent[3].y=composite->rows;
+ for (i=0; i < 4; i++)
+ {
+ register long
+ x;
+
+ x=(long) extent[i].x;
+ y=(long) extent[i].y;
+ extent[i].x=x*affine->sx+y*affine->ry+affine->tx;
+ extent[i].y=x*affine->rx+y*affine->sy+affine->ty;
+ }
+ min=extent[0];
+ max=extent[0];
+ for (i=1; i < 4; i++)
+ {
+ if (min.x > extent[i].x)
+ min.x=extent[i].x;
+ if (min.y > extent[i].y)
+ min.y=extent[i].y;
+ if (max.x < extent[i].x)
+ max.x=extent[i].x;
+ if (max.y < extent[i].y)
+ max.y=extent[i].y;
+ }
+ /*
+ Affine transform image.
+ */
+ (void) SetImageType(image,TrueColorType);
+ edge.x1=min.x;
+ edge.y1=min.y;
+ edge.x2=max.x;
+ edge.y2=max.y;
+ inverse_affine=InverseAffineMatrix(affine);
+ if (edge.y1 < 0)
+ edge.y1=0.0;
+ if (edge.y2 > image->rows - 1)
+ edge.y2=image->rows-1;
+ y_min=(long) ceil(edge.y1-0.5);
+ y_max=(long) floor(edge.y2+0.5);
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static) shared(row_count, status)
+# endif
+#endif
+ for (y=y_min; y <= y_max; y++)
+ {
+ MagickBool
+ thread_status;
+
+ long
+ start,
+ stop;
+
+ SegmentInfo
+ inverse_edge;
+
+ register PixelPacket
+ *q;
+
+ register long
+ x;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_DrawAffineImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ inverse_edge=AffineEdge(composite,&inverse_affine,y,&edge);
+ if (inverse_edge.x2 < inverse_edge.x1)
+ continue;
+ if (inverse_edge.x1 < 0)
+ inverse_edge.x1=0.0;
+ if (inverse_edge.x2 > image->columns-1)
+ inverse_edge.x2=image->columns-1;
+ start=(long) ceil(inverse_edge.x1-0.5);
+ stop=(long) floor(inverse_edge.x2+0.5);
+ if (stop >= start)
+ x=start;
+ else
+ x=stop;
+ q=GetImagePixelsEx(image,x,y,stop-x+1,1,&image->exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for ( ; x <= stop; x++)
+ {
+ PointInfo
+ point;
+
+ PixelPacket
+ pixel;
+
+ point.x=x*inverse_affine.sx+y*inverse_affine.ry+inverse_affine.tx;
+ point.y=x*inverse_affine.rx+y*inverse_affine.sy+inverse_affine.ty;
+ InterpolateViewColor(AccessDefaultCacheView(composite),&pixel,
+ point.x,
+ point.y,
+ &image->exception);
+ if (!composite->matte)
+ pixel.opacity=OpaqueOpacity;
+ AlphaCompositePixel(q,&pixel,pixel.opacity,q,q->opacity);
+ q++;
+ }
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_DrawAffineImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,y_max-y_min+1))
+ if (!MagickMonitorFormatted(row_count,y_max-y_min+1,&image->exception,
+ AffineDrawImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D r a w B o u n d i n g R e c t a n g l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DrawBoundingRectangles draws the bounding rectangles on the image.
+% This is only useful for developers debugging the rendering algorithm.
+%
+% The format of the DrawBoundingRectangles method is:
+%
+% void DrawBoundingRectangles(Image *image,const DrawInfo *draw_info,
+% PolygonInfo *polygon_info)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o polygon_info: Specifies a pointer to a PolygonInfo structure.
+%
+%
+*/
+static void
+DrawBoundingRectangles(Image *image,const DrawInfo *draw_info,
+ const PolygonInfo *polygon_info)
+{
+ DrawInfo
+ *clone_info;
+
+ double
+ mid;
+
+ PointInfo
+ end,
+ resolution,
+ start;
+
+ PrimitiveInfo
+ primitive_info[6];
+
+ register long
+ i;
+
+ SegmentInfo
+ bounds;
+
+ long
+ coordinates;
+
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ (void) QueryColorDatabase("#000000ff",&clone_info->fill,&image->exception);
+ resolution.x=72.0;
+ resolution.y=72.0;
+ if (clone_info->density != (char *) NULL)
+ {
+ int
+ count;
+
+ count=GetMagickDimension(clone_info->density,&resolution.x,&resolution.y,NULL,NULL);
+ if (count != 2)
+ resolution.y=resolution.x;
+ }
+ mid=(resolution.x/72.0)*ExpandAffine(&clone_info->affine)*
+ clone_info->stroke_width/2.0;
+ bounds.x1=0.0;
+ bounds.y1=0.0;
+ bounds.x2=0.0;
+ bounds.y2=0.0;
+ if (polygon_info != (PolygonInfo *) NULL)
+ {
+ bounds=polygon_info->edges[0].bounds;
+ for (i=1; i < polygon_info->number_edges; i++)
+ {
+ if (polygon_info->edges[i].bounds.x1 < bounds.x1)
+ bounds.x1=polygon_info->edges[i].bounds.x1;
+ if (polygon_info->edges[i].bounds.y1 < bounds.y1)
+ bounds.y1=polygon_info->edges[i].bounds.y1;
+ if (polygon_info->edges[i].bounds.x2 > bounds.x2)
+ bounds.x2=polygon_info->edges[i].bounds.x2;
+ if (polygon_info->edges[i].bounds.y2 > bounds.y2)
+ bounds.y2=polygon_info->edges[i].bounds.y2;
+ }
+ bounds.x1-=mid;
+ bounds.x1=bounds.x1 < 0.0 ? 0.0 :
+ bounds.x1 >= image->columns ? image->columns-1 : bounds.x1;
+ bounds.y1-=mid;
+ bounds.y1=bounds.y1 < 0.0 ? 0.0 :
+ bounds.y1 >= image->rows ? image->rows-1 : bounds.y1;
+ bounds.x2+=mid;
+ bounds.x2=bounds.x2 < 0.0 ? 0.0 :
+ bounds.x2 >= image->columns ? image->columns-1 : bounds.x2;
+ bounds.y2+=mid;
+ bounds.y2=bounds.y2 < 0.0 ? 0.0 :
+ bounds.y2 >= image->rows ? image->rows-1 : bounds.y2;
+ for (i=0; i < polygon_info->number_edges; i++)
+ {
+ if (polygon_info->edges[i].direction)
+ (void) QueryColorDatabase("red",&clone_info->stroke,
+ &image->exception);
+ else
+ (void) QueryColorDatabase("green",&clone_info->stroke,
+ &image->exception);
+ start.x=polygon_info->edges[i].bounds.x1-mid;
+ start.y=polygon_info->edges[i].bounds.y1-mid;
+ end.x=polygon_info->edges[i].bounds.x2+mid;
+ end.y=polygon_info->edges[i].bounds.y2+mid;
+ primitive_info[0].primitive=RectanglePrimitive;
+ TraceRectangle(primitive_info,start,end);
+ primitive_info[0].method=ReplaceMethod;
+ coordinates=(long) primitive_info[0].coordinates;
+ primitive_info[coordinates].primitive=UndefinedPrimitive;
+ (void) DrawPrimitive(image,clone_info,primitive_info);
+ }
+ }
+ (void) QueryColorDatabase("blue",&clone_info->stroke,&image->exception);
+ start.x=bounds.x1-mid;
+ start.y=bounds.y1-mid;
+ end.x=bounds.x2+mid;
+ end.y=bounds.y2+mid;
+ primitive_info[0].primitive=RectanglePrimitive;
+ TraceRectangle(primitive_info,start,end);
+ primitive_info[0].method=ReplaceMethod;
+ coordinates=(long) primitive_info[0].coordinates;
+ primitive_info[coordinates].primitive=UndefinedPrimitive;
+ (void) DrawPrimitive(image,clone_info,primitive_info);
+ DestroyDrawInfo(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawClipPath() draws the clip path on the image mask.
+%
+% The format of the DrawClipPath method is:
+%
+% MagickPassFail DrawClipPath(Image *image,const DrawInfo *draw_info,
+% const char *name)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o name: The name of the clip path.
+%
+%
+*/
+MagickExport MagickPassFail
+DrawClipPath(Image *image,const DrawInfo *draw_info, const char *name)
+{
+ char
+ clip_path[MaxTextExtent];
+
+ const ImageAttribute
+ *attribute;
+
+ DrawInfo
+ *clone_info;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(draw_info != (const DrawInfo *) NULL);
+ FormatString(clip_path,"[%.1024s]",name);
+ attribute=GetImageAttribute(image,clip_path);
+ if (attribute == (ImageAttribute *) NULL)
+ return(MagickFail);
+ if (image->clip_mask == (Image *) NULL)
+ {
+ Image
+ *clip_mask;
+
+ clip_mask=CloneImage(image,image->columns,image->rows,MagickTrue,
+ &image->exception);
+ if (clip_mask == (Image *) NULL)
+ return(MagickFail);
+ (void) SetImageClipMask(image,clip_mask);
+ DestroyImage(clip_mask);
+ }
+ (void) QueryColorDatabase("none",&image->clip_mask->background_color,
+ &image->exception);
+ (void) SetImage(image->clip_mask,TransparentOpacity);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ "\nbegin clip-path %.1024s",draw_info->clip_path);
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ (void) CloneString(&clone_info->primitive,attribute->value);
+ (void) QueryColorDatabase("white",&clone_info->fill,&image->exception);
+ MagickFreeMemory(clone_info->clip_path);
+ status&=DrawImage(image->clip_mask,clone_info);
+ status&=NegateImage(image->clip_mask,False);
+ DestroyDrawInfo(clone_info);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),"end clip-path");
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D r a w D a s h P o l y g o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DrawDashPolygon draws a dashed polygon (line, rectangle, ellipse)
+% on the image while respecting the dash offset and dash pattern attributes.
+%
+% The format of the DrawDashPolygon method is:
+%
+% MagickPassFail DrawDashPolygon(const DrawInfo *draw_info,
+% const PrimitiveInfo *primitive_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o draw_info: The draw info.
+%
+% o primitive_info: Specifies a pointer to a PrimitiveInfo structure.
+%
+% o image: The image.
+%
+%
+*/
+static MagickPassFail
+DrawDashPolygon(const DrawInfo *draw_info,const PrimitiveInfo *primitive_info,
+ Image *image)
+{
+ DrawInfo
+ *clone_info;
+
+ double
+ length,
+ maximum_length,
+ offset,
+ scale,
+ total_length;
+
+ MagickPassFail
+ status;
+
+ PrimitiveInfo
+ *dash_polygon;
+
+ register long
+ i;
+
+ register double
+ dx,
+ dy;
+
+ int
+ number_vertices;
+
+ int
+ j,
+ n;
+
+ assert(draw_info != (const DrawInfo *) NULL);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," begin draw-dash");
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ if (clone_info == (DrawInfo *) NULL)
+ return(MagickFail);
+ clone_info->miterlimit=0;
+ for (i=0; primitive_info[i].primitive != UndefinedPrimitive; i++);
+ number_vertices=i;
+ dash_polygon=MagickAllocateArray(PrimitiveInfo *,
+ (size_t) 2*number_vertices+1,
+ sizeof(PrimitiveInfo));
+ if (dash_polygon == (PrimitiveInfo *) NULL)
+ {
+ DestroyDrawInfo(clone_info);
+ return(MagickFail);
+ }
+ dash_polygon[0]=primitive_info[0];
+ scale=ExpandAffine(&draw_info->affine);
+ length=scale*draw_info->dash_pattern[0];
+ offset=draw_info->dash_offset != 0.0 ? scale*draw_info->dash_offset : 0.0;
+ j=1;
+ for (n=0; offset > 0.0; j=0)
+ {
+ if (draw_info->dash_pattern[n] <= 0.0)
+ break;
+ length=scale*draw_info->dash_pattern[n];
+ if (offset > length)
+ {
+ offset-=length;
+ n++;
+ length=scale*draw_info->dash_pattern[n];
+ continue;
+ }
+ if (offset < length)
+ {
+ length-=offset;
+ offset=0.0;
+ break;
+ }
+ offset=0.0;
+ n++;
+ }
+ status=MagickPass;
+ maximum_length=0.0;
+ total_length=0.0;
+ for (i=1; (i < number_vertices) && (length >= 0.0); i++)
+ {
+ dx=primitive_info[i].point.x-primitive_info[i-1].point.x;
+ dy=primitive_info[i].point.y-primitive_info[i-1].point.y;
+ maximum_length=sqrt(dx*dx+dy*dy+MagickEpsilon);
+ if (length == 0.0)
+ {
+ n++;
+ if (draw_info->dash_pattern[n] == 0.0)
+ n=0;
+ length=scale*draw_info->dash_pattern[n];
+ }
+ for (total_length=0.0; (length >= 0.0) && (maximum_length >= (length+total_length)); )
+ {
+ total_length+=length;
+ if (n & 0x01)
+ {
+ dash_polygon[0]=primitive_info[0];
+ dash_polygon[0].point.x=primitive_info[i-1].point.x+
+ dx*total_length/maximum_length;
+ dash_polygon[0].point.y=primitive_info[i-1].point.y+
+ dy*total_length/maximum_length;
+ j=1;
+ }
+ else
+ {
+ if (j+1 > number_vertices)
+ break;
+ dash_polygon[j]=primitive_info[i-1];
+ dash_polygon[j].point.x=primitive_info[i-1].point.x+
+ dx*total_length/maximum_length;
+ dash_polygon[j].point.y=primitive_info[i-1].point.y+
+ dy*total_length/maximum_length;
+ dash_polygon[j].coordinates=1;
+ j++;
+ dash_polygon[0].coordinates=j;
+ dash_polygon[j].primitive=UndefinedPrimitive;
+ status&=DrawStrokePolygon(image,clone_info,dash_polygon);
+ }
+ n++;
+ if (draw_info->dash_pattern[n] == 0.0)
+ n=0;
+ length=scale*draw_info->dash_pattern[n];
+ }
+ length-=(maximum_length-total_length);
+ if (n & 0x01)
+ continue;
+ dash_polygon[j]=primitive_info[i];
+ dash_polygon[j].coordinates=1;
+ j++;
+ }
+ if ((total_length < maximum_length) && ((n & 0x01) == 0) && (j > 1))
+ {
+ dash_polygon[j]=primitive_info[i-1];
+ dash_polygon[j].point.x+=MagickEpsilon;
+ dash_polygon[j].point.y+=MagickEpsilon;
+ dash_polygon[j].coordinates=1;
+ j++;
+ dash_polygon[0].coordinates=(size_t) j;
+ dash_polygon[j].primitive=UndefinedPrimitive;
+ status&=DrawStrokePolygon(image,clone_info,dash_polygon);
+ }
+ MagickFreeMemory(dash_polygon);
+ DestroyDrawInfo(clone_info);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," end draw-dash");
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use DrawImage() to draw a graphic primitive on your image. The primitive
+% may be represented as a string or filename. Precede the filename with an
+% "at" sign (@) and the contents of the file are drawn on the image. You
+% can affect how text is drawn by setting one or more members of the draw
+% info structure.
+%
+% Note that this is a legacy interface. Authors of new code should consider
+% using the Draw* methods defined by magick/draw.h since they are better
+% documented and less error prone.
+%
+% The format of the DrawImage method is:
+%
+% MagickPassFail DrawImage(Image *image,const DrawInfo *draw_info)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+%
+*/
+static inline MagickBool
+IsPoint(const char *point)
+{
+ char
+ *p;
+
+ long
+ value;
+
+ value=strtol(point,&p,10);
+ (void) value;
+ return(p != point);
+}
+
+static const char *recursion_key ="[DrawImageRecursion]";
+static long DrawImageGetCurrentRecurseLevel(Image *image)
+{
+ const ImageAttribute
+ *attribute;
+
+ long
+ recurse_level=0;
+
+ if ((attribute=GetImageAttribute(image,recursion_key)) != (ImageAttribute *) NULL)
+ recurse_level=MagickAtoL(attribute->value);
+
+ return recurse_level;
+}
+static void DrawImageSetCurrentRecurseLevel(Image *image,const long recurse_level)
+{
+ char
+ recursion_str[MaxTextExtent];
+
+ FormatString(recursion_str,"%ld",recurse_level);
+ (void) SetImageAttribute(image,recursion_key,NULL);
+ (void) SetImageAttribute(image,recursion_key,recursion_str);
+}
+static MagickPassFail DrawImageRecurseIn(Image *image)
+{
+ long
+ recurse_level;
+
+ recurse_level=DrawImageGetCurrentRecurseLevel(image);
+ recurse_level++;
+ DrawImageSetCurrentRecurseLevel(image,recurse_level);
+
+ if ((recurse_level < 0) || (recurse_level > 100))
+ {
+ char
+ recursion_str[MaxTextExtent];
+ FormatString(recursion_str,"%ld",recurse_level);
+ ThrowException(&image->exception,DrawError,DrawingRecursionDetected,
+ recursion_str);
+ return MagickFail;
+ }
+
+ return MagickPass;
+}
+static void DrawImageRecurseOut(Image *image)
+{
+ long
+ recurse_level=0;
+
+ recurse_level=DrawImageGetCurrentRecurseLevel(image);
+ recurse_level--;
+ DrawImageSetCurrentRecurseLevel(image,recurse_level);
+}
+
+MagickExport MagickPassFail
+DrawImage(Image *image,const DrawInfo *draw_info)
+{
+#define RenderImageText "[%s] Render..."
+
+ AffineMatrix
+ affine,
+ current;
+
+ char
+ key[2*MaxTextExtent],
+ keyword[MaxTextExtent],
+ geometry[MaxTextExtent],
+ name[MaxTextExtent],
+ pattern[MaxTextExtent],
+ *primitive,
+ *q,
+ *token;
+
+ double
+ angle,
+ factor,
+ points_length,
+ primitive_extent;
+
+ DrawInfo
+ **graphic_context;
+
+ long
+ j,
+ k,
+ n;
+
+ PointInfo
+ point;
+
+ PixelPacket
+ start_color;
+
+ PrimitiveInfo
+ *primitive_info;
+
+ PrimitiveType
+ primitive_type;
+
+ register char
+ *p;
+
+ register long
+ i,
+ x;
+
+ SegmentInfo
+ bounds;
+
+ size_t
+ length,
+ token_max_length;
+
+ MagickPassFail
+ status;
+
+ size_t
+ number_points;
+
+ /*
+ Ensure the annotation info is valid.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(draw_info != (DrawInfo *) NULL);
+ assert(draw_info->signature == MagickSignature);
+ assert(draw_info->primitive != (char *) NULL);
+ /*
+ Check for DrawImage recursion
+ */
+ if (DrawImageRecurseIn(image) == MagickFail)
+ return MagickFail;
+
+ if (*draw_info->primitive == '\0')
+ return(MagickFail);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),"begin draw-image");
+ if (*draw_info->primitive != '@')
+ primitive=AllocateString(draw_info->primitive);
+ else
+ primitive=(char *)
+ FileToBlob(draw_info->primitive+1,&length,&image->exception);
+ if (primitive == (char *) NULL)
+ return(MagickFail);
+ primitive_extent=strlen(primitive);
+ (void) SetImageAttribute(image,"[MVG]",primitive);
+ if (getenv("MAGICK_SKIP_RENDERING") != NULL)
+ {
+ MagickFreeMemory(primitive);
+ return MagickPass;
+ }
+ n=0;
+ /*
+ Allocate primitive info memory.
+ */
+ graphic_context=MagickAllocateMemory(DrawInfo **,sizeof(DrawInfo *));
+ if (graphic_context == (DrawInfo **) NULL)
+ {
+ MagickFreeMemory(primitive);
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage)
+ }
+ number_points=6553;
+ primitive_info=
+ MagickAllocateArray(PrimitiveInfo *,number_points,sizeof(PrimitiveInfo));
+ if (primitive_info == (PrimitiveInfo *) NULL)
+ {
+ MagickFreeMemory(primitive);
+ for ( ; n >= 0; n--)
+ DestroyDrawInfo(graphic_context[n]);
+ MagickFreeMemory(graphic_context);
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage)
+ }
+ graphic_context[n]=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ token=AllocateString(primitive);
+ token_max_length=strlen(token);
+ (void) QueryColorDatabase("black",&start_color,&image->exception);
+ (void) SetImageType(image,TrueColorType);
+ status=MagickPass;
+ for (q=primitive; *q != '\0'; )
+ {
+ /*
+ Interpret graphic primitive.
+ */
+ if (MagickGetToken(q,&q,keyword,MaxTextExtent) < 1)
+ break;
+ if (*keyword == '\0')
+ break;
+ if (*keyword == '#')
+ {
+ /*
+ Comment.
+ */
+ while ((*q != '\n') && (*q != '\0'))
+ q++;
+ continue;
+ }
+ p=q-strlen(keyword);
+ primitive_type=UndefinedPrimitive;
+ current=graphic_context[n]->affine;
+ IdentityAffine(&affine);
+ switch (*keyword)
+ {
+ case ';':
+ break;
+ case 'a':
+ case 'A':
+ {
+ if (LocaleCompare("affine",keyword) == 0)
+ {
+ MagickBool affine_args_good = MagickFalse;
+ do
+ {
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (MagickAtoFChk(token,&affine.sx) != MagickPass)
+ break;
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (*token == ',')
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (MagickAtoFChk(token,&affine.rx) != MagickPass)
+ break;
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (*token == ',')
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (MagickAtoFChk(token,&affine.ry) != MagickPass)
+ break;
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (*token == ',')
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (MagickAtoFChk(token,&affine.sy) != MagickPass)
+ break;
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (*token == ',')
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (MagickAtoFChk(token,&affine.tx) != MagickPass)
+ break;
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (*token == ',')
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ break;
+ if (MagickAtoFChk(token,&affine.ty) != MagickPass)
+ break;
+ affine_args_good=MagickTrue;
+ } while (0);
+ if (affine_args_good != MagickTrue)
+ {
+ status=MagickFail;
+ }
+ break;
+ }
+ if (LocaleCompare("arc",keyword) == 0)
+ {
+ primitive_type=ArcPrimitive;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'b':
+ case 'B':
+ {
+ if (LocaleCompare("bezier",keyword) == 0)
+ {
+ primitive_type=BezierPrimitive;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'c':
+ case 'C':
+ {
+ if (LocaleCompare("clip-path",keyword) == 0)
+ {
+ /*
+ Create clip mask.
+ */
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ {
+ status=MagickFail;
+ break;
+ }
+ (void) CloneString(&graphic_context[n]->clip_path,token);
+ (void) DrawClipPath(image,graphic_context[n],
+ graphic_context[n]->clip_path);
+ break;
+ }
+ if (LocaleCompare("clip-rule",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("evenodd",token) == 0)
+ {
+ graphic_context[n]->fill_rule=EvenOddRule;
+ break;
+ }
+ if (LocaleCompare("nonzero",token) == 0)
+ {
+ graphic_context[n]->fill_rule=NonZeroRule;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("clip-units",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("userSpace",token) == 0)
+ {
+ graphic_context[n]->clip_units=UserSpace;
+ break;
+ }
+ if (LocaleCompare("userSpaceOnUse",token) == 0)
+ {
+ graphic_context[n]->clip_units=UserSpaceOnUse;
+ break;
+ }
+ if (LocaleCompare("objectBoundingBox",token) == 0)
+ {
+ graphic_context[n]->clip_units=ObjectBoundingBox;
+ IdentityAffine(&current);
+ affine.sx=draw_info->bounds.x2;
+ affine.sy=draw_info->bounds.y2;
+ affine.tx=draw_info->bounds.x1;
+ affine.ty=draw_info->bounds.y1;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("circle",keyword) == 0)
+ {
+ primitive_type=CirclePrimitive;
+ break;
+ }
+ if (LocaleCompare("color",keyword) == 0)
+ {
+ primitive_type=ColorPrimitive;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'd':
+ case 'D':
+ {
+ if (LocaleCompare("decorate",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("underline",token) == 0)
+ {
+ graphic_context[n]->decorate=UnderlineDecoration;
+ break;
+ }
+ if (LocaleCompare("overline",token) == 0)
+ {
+ graphic_context[n]->decorate=OverlineDecoration;
+ break;
+ }
+ if (LocaleCompare("line-through",token) == 0)
+ {
+ graphic_context[n]->decorate=LineThroughDecoration;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'e':
+ case 'E':
+ {
+ if (LocaleCompare("ellipse",keyword) == 0)
+ {
+ primitive_type=EllipsePrimitive;
+ break;
+ }
+ if (LocaleCompare("encoding",keyword) == 0)
+ {
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ {
+ status=MagickFail;
+ break;
+ }
+ (void) CloneString(&graphic_context[n]->encoding,token);
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'f':
+ case 'F':
+ {
+ if (LocaleCompare("fill",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(pattern,"[%.1024s]",token);
+ if (GetImageAttribute(image,pattern) == (ImageAttribute *) NULL)
+ (void) QueryColorDatabase(token,&graphic_context[n]->fill,
+ &image->exception);
+ else
+ (void) DrawPatternPath(image,draw_info,token,
+ &graphic_context[n]->fill_pattern);
+ if (graphic_context[n]->fill.opacity != TransparentOpacity)
+ graphic_context[n]->fill.opacity=graphic_context[n]->opacity;
+ break;
+ }
+ if (LocaleCompare("fill-rule",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("evenodd",token) == 0)
+ {
+ graphic_context[n]->fill_rule=EvenOddRule;
+ break;
+ }
+ if (LocaleCompare("nonzero",token) == 0)
+ {
+ graphic_context[n]->fill_rule=NonZeroRule;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("fill-opacity",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
+ if (graphic_context[n]->fill.opacity != TransparentOpacity)
+ {
+ double opacity;
+ if ((MagickAtoFChk(token,&opacity) != MagickPass) ||
+ (opacity < 0.0))
+ {
+ status=MagickFail;
+ break;
+ }
+ graphic_context[n]->fill.opacity=(Quantum)
+ ((double) MaxRGB*(1.0-factor*opacity));
+ }
+ break;
+ }
+ if (LocaleCompare("font",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) CloneString(&graphic_context[n]->font,token);
+ if (LocaleCompare("none",token) == 0)
+ MagickFreeMemory(graphic_context[n]->font);
+ break;
+ }
+ if (LocaleCompare("font-family",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) CloneString(&graphic_context[n]->family,token);
+ break;
+ }
+ if (LocaleCompare("font-size",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&graphic_context[n]->pointsize)
+ != MagickPass)
+ {
+ status=MagickFail;
+ }
+ break;
+ }
+ if (LocaleCompare("font-stretch",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(token,"all") == 0)
+ graphic_context[n]->stretch=AnyStretch;
+ if (LocaleCompare(token,"condensed") == 0)
+ graphic_context[n]->stretch=CondensedStretch;
+ if (LocaleCompare(token,"expanded") == 0)
+ graphic_context[n]->stretch=ExpandedStretch;
+ if (LocaleCompare(token,"extra-condensed") == 0)
+ graphic_context[n]->stretch=ExtraCondensedStretch;
+ if (LocaleCompare(token,"extra-expanded") == 0)
+ graphic_context[n]->stretch=ExtraExpandedStretch;
+ if (LocaleCompare(token,"normal") == 0)
+ graphic_context[n]->stretch=NormalStretch;
+ if (LocaleCompare(token,"semi-condensed") == 0)
+ graphic_context[n]->stretch=SemiCondensedStretch;
+ if (LocaleCompare(token,"semi-expanded") == 0)
+ graphic_context[n]->stretch=SemiExpandedStretch;
+ if (LocaleCompare(token,"ultra-condensed") == 0)
+ graphic_context[n]->stretch=UltraCondensedStretch;
+ if (LocaleCompare(token,"ultra-expanded") == 0)
+ graphic_context[n]->stretch=UltraExpandedStretch;
+ break;
+ }
+ if (LocaleCompare("font-style",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(token,"all") == 0)
+ graphic_context[n]->style=AnyStyle;
+ if (LocaleCompare(token,"italic") == 0)
+ graphic_context[n]->style=ItalicStyle;
+ if (LocaleCompare(token,"normal") == 0)
+ graphic_context[n]->style=NormalStyle;
+ if (LocaleCompare(token,"oblique") == 0)
+ graphic_context[n]->style=ObliqueStyle;
+ break;
+ }
+ if (LocaleCompare("font-weight",keyword) == 0)
+ {
+ if (MagickGetToken(q,&q,token,token_max_length) < 1)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare(token,"all") == 0)
+ graphic_context[n]->weight=0;
+ else if (LocaleCompare(token,"bold") == 0)
+ graphic_context[n]->weight=700;
+ else if (LocaleCompare(token,"bolder") == 0)
+ {
+ if (graphic_context[n]->weight <= 800)
+ graphic_context[n]->weight+=100;
+ }
+ else if (LocaleCompare(token,"lighter") == 0)
+ {
+ if (graphic_context[n]->weight >= 100)
+ graphic_context[n]->weight-=100;
+ }
+ else if (LocaleCompare(token,"normal") == 0)
+ graphic_context[n]->weight=400;
+ else if (MagickAtoULChk(token,&graphic_context[n]->weight) != MagickPass)
+ status=MagickFail;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'g':
+ case 'G':
+ {
+ if (LocaleCompare("gradient-units",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ if (LocaleCompare("gravity",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ graphic_context[n]->gravity=StringToGravityType(token);
+ if (ForgetGravity != graphic_context[n]->gravity)
+ break;
+ status=MagickFail;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'i':
+ case 'I':
+ {
+ if (LocaleCompare("image",keyword) == 0)
+ {
+ primitive_type=ImagePrimitive;
+ MagickGetToken(q,&q,token,token_max_length);
+ graphic_context[n]->compose=StringToCompositeOperator(token);
+ if (UndefinedCompositeOp == graphic_context[n]->compose)
+ status=MagickFail;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'l':
+ case 'L':
+ {
+ if (LocaleCompare("line",keyword) == 0)
+ {
+ primitive_type=LinePrimitive;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'm':
+ case 'M':
+ {
+ if (LocaleCompare("matte",keyword) == 0)
+ {
+ primitive_type=MattePrimitive;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'o':
+ case 'O':
+ {
+ if (LocaleCompare("offset",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ if (LocaleCompare("opacity",keyword) == 0)
+ {
+ double opacity;
+ MagickGetToken(q,&q,token,token_max_length);
+ factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
+ if (MagickAtoFChk(token,&opacity) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ graphic_context[n]->opacity=(Quantum) ((double) MaxRGB*(1.0-((1.0-
+ graphic_context[n]->opacity/MaxRGB)*factor*opacity))+0.5);
+ graphic_context[n]->fill.opacity=graphic_context[n]->opacity;
+ graphic_context[n]->stroke.opacity=graphic_context[n]->opacity;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'p':
+ case 'P':
+ {
+ if (LocaleCompare("path",keyword) == 0)
+ {
+ primitive_type=PathPrimitive;
+ break;
+ }
+ if (LocaleCompare("point",keyword) == 0)
+ {
+ primitive_type=PointPrimitive;
+ break;
+ }
+ if (LocaleCompare("polyline",keyword) == 0)
+ {
+ primitive_type=PolylinePrimitive;
+ break;
+ }
+ if (LocaleCompare("polygon",keyword) == 0)
+ {
+ primitive_type=PolygonPrimitive;
+ break;
+ }
+ if (LocaleCompare("pop",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("clip-path",token) == 0)
+ break;
+ if (LocaleCompare("defs",token) == 0)
+ break;
+ if (LocaleCompare("gradient",token) == 0)
+ break;
+ if (LocaleCompare("graphic-context",token) == 0)
+ {
+ if (n <= 0)
+ {
+ ThrowException(&image->exception,DrawError,UnbalancedGraphicContextPushPop,token);
+ status=MagickFail;
+ break;
+ }
+ if (graphic_context[n]->clip_path != (char *) NULL)
+ if (LocaleCompare(graphic_context[n]->clip_path,
+ graphic_context[n-1]->clip_path) != 0)
+ (void) SetImageClipMask(image,(Image *) NULL);
+ DestroyDrawInfo(graphic_context[n]);
+ n--;
+ break;
+ }
+ if (LocaleCompare("pattern",token) == 0)
+ break;
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("push",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("clip-path",token) == 0)
+ {
+ char
+ name[MaxTextExtent];
+
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(name,"[%.1024s]",token);
+ for (p=q; *q != '\0'; )
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(token,"pop") != 0)
+ continue;
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (LocaleCompare(token,"clip-path") != 0)
+ continue;
+ break;
+ }
+ (void) strncpy(token,p,q-p-4);
+ token[q-p-4]='\0';
+ (void) SetImageAttribute(image,name,token);
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ if (LocaleCompare("gradient",token) == 0)
+ {
+ char
+ key[2*MaxTextExtent],
+ name[MaxTextExtent],
+ type[MaxTextExtent];
+
+ SegmentInfo
+ segment;
+
+ magick_int64_t
+ gradient_width,
+ gradient_height;
+
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) strlcpy(name,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) strlcpy(type,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&segment.x1) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&segment.y1) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&segment.x2) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&segment.y2) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare(type,"radial") == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ }
+ for (p=q; *q != '\0'; )
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(token,"pop") != 0)
+ continue;
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (LocaleCompare(token,"gradient") != 0)
+ continue;
+ break;
+ }
+ (void) strncpy(token,p,q-p-4);
+ token[q-p-4]='\0';
+ bounds.x1=graphic_context[n]->affine.sx*segment.x1+
+ graphic_context[n]->affine.ry*segment.y1+
+ graphic_context[n]->affine.tx;
+ bounds.y1=graphic_context[n]->affine.rx*segment.x1+
+ graphic_context[n]->affine.sy*segment.y1+
+ graphic_context[n]->affine.ty;
+ bounds.x2=graphic_context[n]->affine.sx*segment.x2+
+ graphic_context[n]->affine.ry*segment.y2+
+ graphic_context[n]->affine.tx;
+ bounds.y2=graphic_context[n]->affine.rx*segment.x2+
+ graphic_context[n]->affine.sy*segment.y2+
+ graphic_context[n]->affine.ty;
+ /*
+ Validate gradient image size
+ */
+ gradient_width=(magick_int64_t) Max(AbsoluteValue(bounds.x2-bounds.x1+1),1);
+ gradient_height=(magick_int64_t) Max(AbsoluteValue(bounds.y2-bounds.y1+1),1);
+ {
+ char resource_str[MaxTextExtent];
+ const magick_int64_t width_resource_limit = GetMagickResourceLimit(WidthResource);
+ const magick_int64_t hight_resource_limit = GetMagickResourceLimit(HeightResource);
+ const magick_int64_t pixels_resource_limit = GetMagickResourceLimit(PixelsResource);
+ if ((width_resource_limit > 0) && (gradient_width > width_resource_limit))
+ {
+ FormatString(resource_str,"%" MAGICK_INT64_F "d", width_resource_limit);
+ ThrowException(&image->exception,ResourceLimitError,
+ ImagePixelWidthLimitExceeded,resource_str);
+ status=MagickFail;
+ break;
+ }
+ if ((hight_resource_limit > 0) && (gradient_height > hight_resource_limit))
+ {
+ FormatString(resource_str,"%" MAGICK_INT64_F "d", hight_resource_limit);
+ ThrowException(&image->exception,ResourceLimitError,
+ ImagePixelHeightLimitExceeded,resource_str);
+ status=MagickFail;
+ break;
+ }
+ if ((pixels_resource_limit > 0) && (gradient_width*gradient_height > pixels_resource_limit))
+ {
+ FormatString(resource_str,"%" MAGICK_INT64_F "d", pixels_resource_limit);
+ ThrowException(&image->exception,ResourceLimitError,
+ ImagePixelLimitExceeded,resource_str);
+ status=MagickFail;
+ break;
+ }
+ }
+ /*
+ Apply an arbitrary limit to gradient size requests
+ since gradient images can take a lot of memory.
+ Some tiny SVGs request huge gradients. This is here
+ to avoid denial of service.
+ */
+ if (gradient_width*gradient_height > 5000*5000 /*10000*10000*/)
+ {
+ char gradient_size_str[MaxTextExtent];
+ FormatString(gradient_size_str,"%" MAGICK_INT64_F "dx%" MAGICK_INT64_F "d",
+ gradient_width,gradient_height);
+ ThrowException(&image->exception,DrawError,
+ UnreasonableGradientSize,gradient_size_str);
+ status=MagickFail;
+ break;
+ }
+ FormatString(key,"[%.1024s]",name);
+ (void) SetImageAttribute(image,key,token);
+ FormatString(key,"[%.1024s-geometry]",name);
+ FormatString(geometry,"%gx%g%+g%+g",
+ Max(AbsoluteValue(bounds.x2-bounds.x1+1),1),
+ Max(AbsoluteValue(bounds.y2-bounds.y1+1),1),
+ bounds.x1,bounds.y1);
+ (void) SetImageAttribute(image,key,geometry);
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ if (LocaleCompare("pattern",token) == 0)
+ {
+ double
+ ordinate;
+ RectangleInfo
+ bounds;
+
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) strlcpy(name,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&ordinate) == MagickFail)
+ {
+ status=MagickFail;
+ break;
+ }
+ bounds.x=(long) ceil(ordinate-0.5);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&ordinate) == MagickFail)
+ {
+ status=MagickFail;
+ break;
+ }
+ bounds.y=(long) ceil(ordinate-0.5);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ if ((MagickAtoFChk(token,&ordinate) == MagickFail) ||
+ (ordinate < 0.0))
+ {
+ status=MagickFail;
+ break;
+ }
+ bounds.width=(unsigned long) floor(ordinate+0.5);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ if ((MagickAtoFChk(token,&ordinate) == MagickFail) ||
+ (ordinate < 0.0))
+ {
+ status=MagickFail;
+ break;
+ }
+ bounds.height=(unsigned long) floor(ordinate+0.5);
+ for (p=q; *q != '\0'; )
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(token,"pop") != 0)
+ continue;
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (LocaleCompare(token,"pattern") != 0)
+ continue;
+ break;
+ }
+ (void) strncpy(token,p,q-p-4);
+ token[q-p-4]='\0';
+ FormatString(key,"[%.1024s]",name);
+ (void) SetImageAttribute(image,key,token);
+ FormatString(key,"[%.1024s-geometry]",name);
+ FormatString(geometry,"%lux%lu%+ld%+ld",bounds.width,
+ bounds.height,bounds.x,bounds.y);
+ (void) SetImageAttribute(image,key,geometry);
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ if (LocaleCompare("graphic-context",token) == 0)
+ {
+ n++;
+ MagickReallocMemory(DrawInfo **,graphic_context,
+ MagickArraySize((n+1),sizeof(DrawInfo *)));
+ if (graphic_context == (DrawInfo **) NULL)
+ {
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ break;
+ }
+ graphic_context[n]=
+ CloneDrawInfo((ImageInfo *) NULL,graphic_context[n-1]);
+ break;
+ }
+ if (LocaleCompare("defs",token) == 0)
+ break;
+ status=MagickFail;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'r':
+ case 'R':
+ {
+ if (LocaleCompare("rectangle",keyword) == 0)
+ {
+ primitive_type=RectanglePrimitive;
+ break;
+ }
+ if (LocaleCompare("rotate",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&angle) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ if (LocaleCompare("roundRectangle",keyword) == 0)
+ {
+ primitive_type=RoundRectanglePrimitive;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 's':
+ case 'S':
+ {
+ if (LocaleCompare("scale",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&affine.sx) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&affine.sy) != MagickPass)
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("skewX",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&angle) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ if (LocaleCompare("skewY",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&angle) != MagickPass)
+ {
+ status=MagickFail;
+ break;
+ }
+ affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
+ break;
+ }
+ if (LocaleCompare("stop-color",keyword) == 0)
+ {
+ PixelPacket
+ stop_color;
+
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) QueryColorDatabase(token,&stop_color,&image->exception);
+ (void) GradientImage(image,&start_color,&stop_color);
+ start_color=stop_color;
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ if (LocaleCompare("stroke",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ FormatString(pattern,"[%.1024s]",token);
+ if (GetImageAttribute(image,pattern) == (ImageAttribute *) NULL)
+ (void) QueryColorDatabase(token,&graphic_context[n]->stroke,
+ &image->exception);
+ else
+ (void) DrawPatternPath(image,draw_info,token,
+ &graphic_context[n]->stroke_pattern);
+ if (graphic_context[n]->stroke.opacity != TransparentOpacity)
+ graphic_context[n]->stroke.opacity=graphic_context[n]->opacity;
+ break;
+ }
+ if (LocaleCompare("stroke-antialias",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoUIChk(token,&graphic_context[n]->stroke_antialias)
+ != MagickPass)
+ {
+ status=MagickFail;
+ }
+ break;
+ }
+ if (LocaleCompare("stroke-dasharray",keyword) == 0)
+ {
+ MagickFreeMemory(graphic_context[n]->dash_pattern);
+ if (IsPoint(q))
+ {
+ char
+ *p;
+
+ p=q;
+ MagickGetToken(p,&p,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(p,&p,token,token_max_length);
+ for (x=0; IsPoint(token); x++)
+ {
+ MagickGetToken(p,&p,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(p,&p,token,token_max_length);
+ }
+ graphic_context[n]->dash_pattern=
+ MagickAllocateArray(double *,(2*x+1),sizeof(double));
+ if (graphic_context[n]->dash_pattern == (double *) NULL)
+ {
+ status=MagickFail;
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ break;
+ }
+ for (j=0; j < x; j++)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ if ((MagickAtoFChk(token,&graphic_context[n]->dash_pattern[j])
+ == MagickFail) ||
+ (graphic_context[n]->dash_pattern[j] < 0.0))
+ status=MagickFail;
+ }
+ if (status == MagickFail)
+ {
+ MagickFreeMemory(graphic_context[n]->dash_pattern);
+ break;
+ }
+ if (x & 0x01)
+ for ( ; j < (2*x); j++)
+ graphic_context[n]->dash_pattern[j]=
+ graphic_context[n]->dash_pattern[j-x];
+ graphic_context[n]->dash_pattern[j]=0.0;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ if (LocaleCompare("stroke-dashoffset",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (MagickAtoFChk(token,&graphic_context[n]->dash_offset)
+ == MagickFail)
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("stroke-linecap",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("butt",token) == 0)
+ {
+ graphic_context[n]->linecap=ButtCap;
+ break;
+ }
+ if (LocaleCompare("round",token) == 0)
+ {
+ graphic_context[n]->linecap=RoundCap;
+ break;
+ }
+ if (LocaleCompare("square",token) == 0)
+ {
+ graphic_context[n]->linecap=SquareCap;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("stroke-linejoin",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("bevel",token) == 0)
+ {
+ graphic_context[n]->linejoin=BevelJoin;
+ break;
+ }
+ if (LocaleCompare("miter",token) == 0)
+ {
+ graphic_context[n]->linejoin=MiterJoin;
+ break;
+ }
+ if (LocaleCompare("round",token) == 0)
+ {
+ graphic_context[n]->linejoin=RoundJoin;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("stroke-miterlimit",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if ((MagickAtoULChk(token,&graphic_context[n]->miterlimit)
+ != MagickPass) || (graphic_context[n]->miterlimit < 1))
+ status=MagickFail;
+ break;
+ }
+ if (LocaleCompare("stroke-opacity",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
+ if (graphic_context[n]->stroke.opacity != TransparentOpacity)
+ {
+ double opacity;
+ if ((MagickAtoFChk(token,&opacity) != MagickPass) ||
+ opacity < 0.0)
+ {
+ status=MagickFail;
+ break;
+ }
+ graphic_context[n]->stroke.opacity=(Quantum)
+ ((double) MaxRGB*(1.0-factor*opacity));
+ }
+ break;
+ }
+ if (LocaleCompare("stroke-width",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if ((MagickAtoFChk(token,&graphic_context[n]->stroke_width)
+ == MagickFail) ||
+ (graphic_context[n]->stroke_width < 0.0))
+ status=MagickFail;
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 't':
+ case 'T':
+ {
+ if (LocaleCompare("text",keyword) == 0)
+ {
+ primitive_type=TextPrimitive;
+ break;
+ }
+ if (LocaleCompare("text-align",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(token,"left") == 0)
+ graphic_context[n]->align=LeftAlign;
+ if (LocaleCompare(token,"center") == 0)
+ graphic_context[n]->align=CenterAlign;
+ if (LocaleCompare(token,"right") == 0)
+ graphic_context[n]->align=RightAlign;
+ break;
+ }
+ if (LocaleCompare("text-anchor",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(token,"start") == 0)
+ graphic_context[n]->align=LeftAlign;
+ if (LocaleCompare(token,"middle") == 0)
+ graphic_context[n]->align=CenterAlign;
+ if (LocaleCompare(token,"end") == 0)
+ graphic_context[n]->align=RightAlign;
+ break;
+ }
+ if (LocaleCompare("text-antialias",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ graphic_context[n]->text_antialias=MagickAtoI(token);
+ break;
+ }
+ if (LocaleCompare("text-undercolor",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) QueryColorDatabase(token,&graphic_context[n]->undercolor,
+ &image->exception);
+ break;
+ }
+ if (LocaleCompare("translate",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) MagickAtoFChk(token,&affine.tx);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) MagickAtoFChk(token,&affine.ty);
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ case 'v':
+ case 'V':
+ {
+ if (LocaleCompare("viewbox",keyword) == 0)
+ {
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ break;
+ }
+ status=MagickFail;
+ break;
+ }
+ default:
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (status == MagickFail)
+ break;
+ if ((affine.sx != 1.0) || (affine.rx != 0.0) || (affine.ry != 0.0) ||
+ (affine.sy != 1.0) || (affine.tx != 0.0) || (affine.ty != 0.0))
+ {
+ graphic_context[n]->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+ graphic_context[n]->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+ graphic_context[n]->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+ graphic_context[n]->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+ graphic_context[n]->affine.tx=
+ current.sx*affine.tx+current.ry*affine.ty+current.tx;
+ graphic_context[n]->affine.ty=
+ current.rx*affine.tx+current.sy*affine.ty+current.ty;
+ }
+ if (primitive_type == UndefinedPrimitive)
+ {
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," %.*s",
+ (int) (q-p),p);
+ continue;
+ }
+ /*
+ Parse the primitive attributes.
+ */
+ i=0;
+ j=0;
+ primitive_info[0].point.x=0.0;
+ primitive_info[0].point.y=0.0;
+ primitive_info[0].coordinates=0;
+ primitive_info[0].method=FloodfillMethod;
+ for (x=0; *q != '\0'; x++)
+ {
+ /*
+ Define points.
+ */
+ if (!IsPoint(q))
+ break;
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) MagickAtoFChk(token,&point.x);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ (void) MagickAtoFChk(token,&point.y);
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (*token == ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ assert(i < (long) number_points);
+ primitive_info[i].primitive=primitive_type;
+ primitive_info[i].point=point;
+ primitive_info[i].coordinates=0;
+ primitive_info[i].method=FloodfillMethod;
+ i++;
+ if (i < (long) number_points)
+ continue;
+ number_points<<=1;
+ MagickReallocMemory(PrimitiveInfo *,primitive_info,
+ MagickArraySize(number_points,sizeof(PrimitiveInfo)));
+ if (primitive_info == (PrimitiveInfo *) NULL)
+ {
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ break;
+ }
+ }
+ assert(j < (long) number_points);
+ primitive_info[j].primitive=primitive_type;
+ primitive_info[j].coordinates=x;
+ primitive_info[j].method=FloodfillMethod;
+ primitive_info[j].text=(char *) NULL;
+ /*
+ Circumscribe primitive within a circle.
+ */
+ bounds.x1=primitive_info[j].point.x;
+ bounds.y1=primitive_info[j].point.y;
+ bounds.x2=primitive_info[j].point.x;
+ bounds.y2=primitive_info[j].point.y;
+ for (k=1; k < (long) primitive_info[j].coordinates; k++)
+ {
+ assert(j+k < (long) number_points);
+ point=primitive_info[j+k].point;
+ if (point.x < bounds.x1)
+ bounds.x1=point.x;
+ if (point.y < bounds.y1)
+ bounds.y1=point.y;
+ if (point.x > bounds.x2)
+ bounds.x2=point.x;
+ if (point.y > bounds.y2)
+ bounds.y2=point.y;
+ }
+ /*
+ Estimate how many points will be required for the primitive.
+ */
+ points_length=primitive_info[j].coordinates;
+ switch (primitive_type)
+ {
+ case RectanglePrimitive:
+ {
+ points_length*=5;
+ break;
+ }
+ case RoundRectanglePrimitive:
+ {
+ /*
+ Round rectangle is rectangle plus elipse
+ */
+ double
+ alpha,
+ beta,
+ radius;
+
+ alpha=bounds.x2-bounds.x1;
+ beta=bounds.y2-bounds.y1;
+ radius=hypot((double) alpha,(double) beta);
+ points_length*=5;
+ points_length+=2*((size_t) ceil((double) MagickPI*radius))+6*BezierQuantum+360;
+ break;
+ }
+ case BezierPrimitive:
+ {
+ if (primitive_info[j].coordinates > 107)
+ (void) ThrowException(&image->exception,DrawError,
+ TooManyCoordinates,token);
+ points_length=primitive_info[j].coordinates*BezierQuantum;
+ break;
+ }
+ case PathPrimitive:
+ {
+ char
+ *s,
+ *t;
+
+ MagickGetToken(q,&q,token,token_max_length);
+ points_length=1;
+ t=token;
+ for (s=token; *s != '\0'; s=t)
+ {
+ double
+ value;
+
+ value=strtod(s,&t);
+ (void) value;
+ if (s == t)
+ {
+ t++;
+ continue;
+ }
+ points_length++;
+ }
+ points_length=points_length*BezierQuantum;
+ break;
+ }
+ case CirclePrimitive:
+ case ArcPrimitive:
+ case EllipsePrimitive:
+ {
+ double
+ alpha,
+ beta,
+ radius;
+
+ alpha=bounds.x2-bounds.x1;
+ beta=bounds.y2-bounds.y1;
+ radius=hypot(alpha,beta);
+ points_length=2*(ceil(MagickPI*radius))+6*BezierQuantum+360;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (((size_t) points_length) < points_length)
+ {
+ status=MagickFail;
+ ThrowException(&image->exception,DrawError,
+ PrimitiveArithmeticOverflow,keyword);
+ }
+
+ if (status == MagickFail)
+ break;
+
+ if ((i+points_length) >= number_points)
+ {
+ double new_number_points = ceil(number_points+points_length+1);
+ if (((size_t) new_number_points) != new_number_points)
+ {
+ status=MagickFail;
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ break;
+ }
+
+ number_points=new_number_points;
+ MagickReallocMemory(PrimitiveInfo *,primitive_info,
+ MagickArraySize(number_points,sizeof(PrimitiveInfo)));
+ if (primitive_info == (PrimitiveInfo *) NULL)
+ {
+ status=MagickFail;
+ ThrowException3(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ break;
+ }
+ }
+
+ assert(j < (long) number_points);
+
+ /*
+ Trace points
+ */
+ switch (primitive_type)
+ {
+ case PointPrimitive:
+ default:
+ {
+ if (primitive_info[j].coordinates != 1)
+ {
+ status=MagickFail;
+ break;
+ }
+ TracePoint(primitive_info+j,primitive_info[j].point);
+ i=(long) (j+primitive_info[j].coordinates);
+ break;
+ }
+ case LinePrimitive:
+ {
+ if (primitive_info[j].coordinates != 2)
+ {
+ status=MagickFail;
+ break;
+ }
+ TraceLine(primitive_info+j,primitive_info[j].point,
+ primitive_info[j+1].point);
+ i=(long) (j+primitive_info[j].coordinates);
+ break;
+ }
+ case RectanglePrimitive:
+ {
+ /*
+ Rectangle requires 2 primitives.
+ */
+ if (primitive_info[j].coordinates != 2)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Negative width is an error
+ */
+ if ((primitive_info[j+1].point.x - primitive_info[j].point.x) < 0.0)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Negative height is an error
+ */
+ if ((primitive_info[j+1].point.y - primitive_info[j].point.y) < 0.0)
+ {
+ status=MagickFail;
+ break;
+ }
+ TraceRectangle(/*start*/primitive_info+j,
+ /*end*/primitive_info[j].point,
+ primitive_info[j+1].point);
+ i=(long) (j+primitive_info[j].coordinates);
+ break;
+ }
+ case RoundRectanglePrimitive:
+ {
+ /*
+ Round rectangle requires 3 primitives.
+ */
+ if (primitive_info[j].coordinates != 3)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Negative radius values are an error.
+ */
+ if ((primitive_info[j+2].point.x < 0.0) || (primitive_info[j+2].point.y < 0.0))
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Negative width is an error
+ */
+ if ((primitive_info[j+1].point.x - primitive_info[j].point.x) < 0.0)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Negative height is an error
+ */
+ if ((primitive_info[j+1].point.y - primitive_info[j].point.y) < 0.0)
+ {
+ status=MagickFail;
+ break;
+ }
+ TraceRoundRectangle(primitive_info+j,
+ /*start*/primitive_info[j].point,
+ /*end*/primitive_info[j+1].point,
+ /*arc*/primitive_info[j+2].point);
+ i=(long) (j+primitive_info[j].coordinates);
+ break;
+ }
+ case ArcPrimitive:
+ {
+ if (primitive_info[j].coordinates != 3)
+ {
+ primitive_type=UndefinedPrimitive;
+ break;
+ }
+ TraceArc(primitive_info+j,primitive_info[j].point,
+ primitive_info[j+1].point,primitive_info[j+2].point);
+ i=(long) (j+primitive_info[j].coordinates);
+ break;
+ }
+ case EllipsePrimitive:
+ {
+ if (primitive_info[j].coordinates != 3)
+ {
+ status=MagickFail;
+ break;
+ }
+ /*
+ Negative radius values are an error.
+ */
+ if ((primitive_info[j+1].point.x < 0.0) ||
+ (primitive_info[j+1].point.y < 0.0))
+ {
+ status=MagickFail;
+ break;
+ }
+ TraceEllipse(primitive_info+j,
+ /*start*/primitive_info[j].point, /*centerX,centerY*/
+ /*stop*/primitive_info[j+1].point, /*radiusX,radiusY*/
+ /*degrees*/primitive_info[j+2].point); /*arcStart,arcEnd*/
+ i=(long) (j+primitive_info[j].coordinates);
+ break;
+ }
+ case CirclePrimitive:
+ {
+ if (primitive_info[j].coordinates != 2)
+ {
+ status=MagickFail;
+ break;
+ }
+ TraceCircle(primitive_info+j,primitive_info[j].point,
+ primitive_info[j+1].point);
+ i=(long) (j+primitive_info[j].coordinates);
+ break;
+ }
+ case PolylinePrimitive:
+ {
+ if (primitive_info[j].coordinates < 2)
+ {
+ status=MagickFail;
+ break;
+ }
+ break;
+ }
+ case PolygonPrimitive:
+ {
+ /*
+ Polygon requires at least three points.
+ */
+ if (primitive_info[j].coordinates < 3)
+ {
+ status=MagickFail;
+ break;
+ }
+ primitive_info[i]=primitive_info[j];
+ primitive_info[i].coordinates=0;
+ primitive_info[j].coordinates++;
+ i++;
+ break;
+ }
+ case BezierPrimitive:
+ {
+ if (primitive_info[j].coordinates < 3)
+ {
+ status=MagickFail;
+ break;
+ }
+ TraceBezier(primitive_info+j,primitive_info[j].coordinates);
+ i=(long) (j+primitive_info[j].coordinates);
+ break;
+ }
+ case PathPrimitive:
+ {
+ i=(long) (j+TracePath(image,primitive_info+j,token));
+ break;
+ }
+ case ColorPrimitive:
+ case MattePrimitive:
+ {
+ if (primitive_info[j].coordinates != 1)
+ {
+ status=MagickFail;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare("point",token) == 0)
+ primitive_info[j].method=PointMethod;
+ if (LocaleCompare("replace",token) == 0)
+ primitive_info[j].method=ReplaceMethod;
+ if (LocaleCompare("floodfill",token) == 0)
+ primitive_info[j].method=FloodfillMethod;
+ if (LocaleCompare("filltoborder",token) == 0)
+ primitive_info[j].method=FillToBorderMethod;
+ if (LocaleCompare("reset",token) == 0)
+ primitive_info[j].method=ResetMethod;
+ break;
+ }
+ case TextPrimitive:
+ {
+ if (primitive_info[j].coordinates != 1)
+ {
+ status=MagickFail;
+ break;
+ }
+ if (*token != ',')
+ MagickGetToken(q,&q,token,token_max_length);
+ primitive_info[j].text=AllocateString(token);
+ break;
+ }
+ case ImagePrimitive:
+ {
+ if (primitive_info[j].coordinates != 2)
+ {
+ status=MagickFail;
+ break;
+ }
+ MagickGetToken(q,&q,token,token_max_length);
+ primitive_info[j].text=AllocateString(token);
+ break;
+ }
+ }
+
+ if (primitive_info == (PrimitiveInfo *) NULL)
+ break;
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," %.*s",(int) (q-p),p);
+ if (status == MagickFail)
+ break;
+ assert(i < (long) number_points);
+ primitive_info[i].primitive=UndefinedPrimitive;
+ if (i == 0)
+ continue;
+ /*
+ Transform points.
+ */
+ for (i=0; primitive_info[i].primitive != UndefinedPrimitive; i++)
+ {
+ assert((unsigned long) i < number_points);
+ point=primitive_info[i].point;
+ primitive_info[i].point.x=graphic_context[n]->affine.sx*point.x+
+ graphic_context[n]->affine.ry*point.y+graphic_context[n]->affine.tx;
+ primitive_info[i].point.y=graphic_context[n]->affine.rx*point.x+
+ graphic_context[n]->affine.sy*point.y+graphic_context[n]->affine.ty;
+ point=primitive_info[i].point;
+ if (point.x < graphic_context[n]->bounds.x1)
+ graphic_context[n]->bounds.x1=point.x;
+ if (point.y < graphic_context[n]->bounds.y1)
+ graphic_context[n]->bounds.y1=point.y;
+ if (point.x > graphic_context[n]->bounds.x2)
+ graphic_context[n]->bounds.x2=point.x;
+ if (point.y > graphic_context[n]->bounds.y2)
+ graphic_context[n]->bounds.y2=point.y;
+ if (primitive_info[i].primitive == ImagePrimitive)
+ break;
+ }
+ if (graphic_context[n]->render)
+ {
+ if ((n != 0) && (graphic_context[n]->clip_path != (char *) NULL) &&
+ (LocaleCompare(graphic_context[n]->clip_path,
+ graphic_context[n-1]->clip_path) != 0))
+ if (DrawClipPath(image,graphic_context[n],
+ graphic_context[n]->clip_path) == MagickFail)
+ status=MagickFail;
+ if (DrawPrimitive(image,graphic_context[n],primitive_info)
+ == MagickFail)
+ status=MagickFail;
+ }
+ if (primitive_info->text != (char *) NULL)
+ MagickFreeMemory(primitive_info->text);
+ if (MagickMonitorFormatted(q-primitive,
+ (magick_uint64_t) primitive_extent,
+ &image->exception,
+ RenderImageText,image->filename) == MagickFail)
+ status=MagickFail;
+ if (status == MagickFail)
+ break;
+ }
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),"end draw-image");
+ /*
+ Free resources.
+ */
+ DrawImageRecurseOut(image);
+ MagickFreeMemory(token);
+ MagickFreeMemory(primitive_info);
+ MagickFreeMemory(primitive);
+ for ( ; n >= 0; n--)
+ DestroyDrawInfo(graphic_context[n]);
+ MagickFreeMemory(graphic_context);
+ if ((status == MagickFail) &&
+ (image->exception.severity < ErrorException))
+ ThrowBinaryException(DrawError,NonconformingDrawingPrimitiveDefinition,
+ keyword);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t t e r n P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPatternPath() draws a pattern.
+%
+% The format of the DrawPatternPath method is:
+%
+% MagickPassFail DrawPatternPath(Image *image,const DrawInfo *draw_info,
+% const char *name,Image **pattern)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o name: The pattern name.
+%
+% o image: The image.
+%
+%
+*/
+MagickExport MagickPassFail
+DrawPatternPath(Image *image,const DrawInfo *draw_info,const char *name,
+ Image **pattern)
+{
+ char
+ attribute[MaxTextExtent];
+
+ const ImageAttribute
+ *geometry,
+ *path;
+
+ DrawInfo
+ *clone_info;
+
+ ImageInfo
+ *image_info;
+
+ MagickPassFail
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(draw_info != (const DrawInfo *) NULL);
+ assert(name != (const char *) NULL);
+ FormatString(attribute,"[%.1024s]",name);
+ path=GetImageAttribute(image,attribute);
+ if (path == (ImageAttribute *) NULL)
+ return(MagickFail);
+ FormatString(attribute,"[%.1024s-geometry]",name);
+ geometry=GetImageAttribute(image,attribute);
+ if (geometry == (ImageAttribute *) NULL)
+ return(MagickFail);
+ if ((*pattern) != (Image *) NULL)
+ DestroyImage(*pattern);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ image_info->size=AllocateString(geometry->value);
+ *pattern=AllocateImage(image_info);
+ DestroyImageInfo(image_info);
+ (void) QueryColorDatabase("none",&(*pattern)->background_color,
+ &image->exception);
+ (void) SetImage(*pattern,OpaqueOpacity);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ "begin pattern-path %.1024s %.1024s",name,geometry->value);
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ clone_info->fill_pattern=(Image *) NULL;
+ clone_info->stroke_pattern=(Image *) NULL;
+ (void) CloneString(&clone_info->primitive,path->value);
+ status=DrawImage(*pattern,clone_info);
+ DestroyDrawInfo(clone_info);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),"end pattern-path");
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D r a w P o l y g o n P r i m i t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DrawPolygonPrimitive draws a polygon on the image.
+%
+% The format of the DrawPolygonPrimitive method is:
+%
+% unsigned int DrawPolygonPrimitive(Image *image,const DrawInfo *draw_info,
+% const PrimitiveInfo *primitive_info)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o primitive_info: Specifies a pointer to a PrimitiveInfo structure.
+%
+%
+*/
+
+static double
+GetPixelOpacity(PolygonInfo * restrict polygon_info,const double mid,
+ const unsigned int fill,const FillRule fill_rule,const long x,
+ const long y,double * restrict stroke_opacity)
+{
+ double
+ alpha,
+ beta,
+ distance,
+ subpath_opacity;
+
+ int
+ winding_number;
+
+ register double
+ dx,
+ dy;
+
+ register EdgeInfo
+ *p;
+
+ register const PointInfo
+ *q;
+
+ register long
+ i;
+
+ long
+ j;
+
+ /*
+ Compute fill & stroke opacity for this (x,y) point.
+ */
+ *stroke_opacity=0.0;
+ subpath_opacity=0.0;
+ p=polygon_info->edges;
+ for (j=0; j < polygon_info->number_edges; j++)
+ {
+ if (y <= (p->bounds.y1-mid-0.5))
+ break;
+ if (y > (p->bounds.y2+mid+0.5))
+ {
+ (void) DestroyEdge(polygon_info,j);
+ p++;
+ continue;
+ }
+ if (x <= (p->bounds.x1-mid-0.5))
+ {
+ p++;
+ continue;
+ }
+ if (x > (p->bounds.x2+mid+0.5))
+ {
+ p++;
+ continue;
+ }
+ for (i=Max(p->highwater,1); i < p->number_points; i++)
+ {
+ if (y <= (p->points[i-1].y-mid-0.5))
+ break;
+ if (y > (p->points[i].y+mid+0.5))
+ continue;
+ if (p->scanline != y)
+ {
+ p->scanline=y;
+ p->highwater=i;
+ }
+ /*
+ Compute distance between a point and an edge.
+ */
+ q=p->points+i-1;
+ dx=(q+1)->x-q->x,
+ dy=(q+1)->y-q->y;
+ beta=dx*(x-q->x)+dy*(y-q->y);
+ if (beta < 0.0)
+ {
+ dx=x-q->x;
+ dy=y-q->y;
+ distance=dx*dx+dy*dy;
+ }
+ else
+ {
+ alpha=dx*dx+dy*dy;
+ if (beta > alpha)
+ {
+ dx=x-(q+1)->x;
+ dy=y-(q+1)->y;
+ distance=dx*dx+dy*dy;
+ }
+ else
+ {
+ alpha=1.0/alpha;
+ beta=dx*(y-q->y)-dy*(x-q->x);
+ distance=alpha*beta*beta;
+ }
+ }
+ /*
+ Compute stroke & subpath opacity.
+ */
+ beta=0.0;
+ if (!p->ghostline)
+ {
+ alpha=mid+0.5;
+ if ((*stroke_opacity < 1.0) &&
+ (distance <= ((alpha+0.25)*(alpha+0.25))))
+ {
+ alpha=mid-0.5;
+ if (distance <= ((alpha+0.25)*(alpha+0.25)))
+ *stroke_opacity=1.0;
+ else
+ {
+ beta=1.0;
+ if (distance != 1.0)
+ beta=sqrt(distance);
+ alpha=beta-mid-0.5;
+ if (*stroke_opacity < ((alpha-0.25)*(alpha-0.25)))
+ *stroke_opacity=(alpha-0.25)*(alpha-0.25);
+ }
+ }
+ }
+ if (!fill || (distance > 1.0) || (subpath_opacity >= 1.0))
+ continue;
+ if (distance <= 0.0)
+ {
+ subpath_opacity=1.0;
+ continue;
+ }
+ if (distance > 1.0)
+ continue;
+ if (beta == 0.0)
+ {
+ beta=1.0;
+ if (distance != 1.0)
+ beta=sqrt(distance);
+ }
+ alpha=beta-1.0;
+ if (subpath_opacity < (alpha*alpha))
+ subpath_opacity=alpha*alpha;
+ }
+ p++;
+ }
+ /*
+ Compute fill opacity.
+ */
+ if (!fill)
+ return(0.0);
+ if (subpath_opacity >= 1.0)
+ return(1.0);
+ /*
+ Determine winding number.
+ */
+ winding_number=0;
+ p=polygon_info->edges;
+ for (j=0; j < polygon_info->number_edges; j++)
+ {
+ if (y <= p->bounds.y1)
+ break;
+ if (y > p->bounds.y2)
+ {
+ p++;
+ continue;
+ }
+ if (x <= p->bounds.x1)
+ {
+ p++;
+ continue;
+ }
+ if (x > p->bounds.x2)
+ {
+ winding_number+=p->direction ? 1 : -1;
+ p++;
+ continue;
+ }
+ for (i=Max(p->highwater,1); i < p->number_points; i++)
+ if (y <= p->points[i].y)
+ break;
+ q=p->points+i-1;
+ dx=(q+1)->x-q->x;
+ dy=(q+1)->y-q->y;
+ if ((dx*(y-q->y)) <= (dy*(x-q->x)))
+ winding_number+=p->direction ? 1 : -1;
+ p++;
+ }
+ if (fill_rule != NonZeroRule)
+ {
+ if (AbsoluteValue(winding_number) & 0x01)
+ return(1.0);
+ }
+ else
+ if (AbsoluteValue(winding_number) > 0)
+ return(1.0);
+ return(subpath_opacity);
+}
+
+static MagickPassFail
+DrawPolygonPrimitive(Image *image,const DrawInfo *draw_info,
+ const PrimitiveInfo *primitive_info)
+{
+ double
+ mid;
+
+ SegmentInfo
+ bounds;
+
+ ThreadViewDataSet
+ * restrict polygon_set;
+
+ MagickPassFail
+ status = MagickPass;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(draw_info != (DrawInfo *) NULL);
+ assert(draw_info->signature == MagickSignature);
+ assert(primitive_info != (PrimitiveInfo *) NULL);
+ /*
+ Nothing to do.
+ */
+ if (primitive_info->coordinates == 0)
+ return(MagickPass);
+
+ {
+ /*
+ Allocate and initialize thread-specific polygon sets.
+ */
+ PathInfo
+ * restrict path_info;
+
+ unsigned int
+ index;
+
+ polygon_set=(ThreadViewDataSet *) NULL;
+ path_info=(PathInfo *) NULL;
+ if ((path_info=ConvertPrimitiveToPath(draw_info,primitive_info))
+ != (PathInfo *) NULL)
+ {
+ if ((polygon_set=AllocateThreadViewDataSet(DestroyPolygonInfo,image,
+ &image->exception))
+ != (ThreadViewDataSet *) NULL)
+ {
+ /*
+ Assign polygon for each worker thread.
+ */
+ for (index=0; index < GetThreadViewDataSetAllocatedViews(polygon_set); index++)
+ AssignThreadViewData(polygon_set,index,(void *) ConvertPathToPolygon(path_info));
+
+ /*
+ Verify worker thread allocations.
+ */
+ for (index=0; index < GetThreadViewDataSetAllocatedViews(polygon_set); index++)
+ if (AccessThreadViewDataById(polygon_set,index) == (void *) NULL)
+ {
+ DestroyThreadViewDataSet(polygon_set);
+ polygon_set=(ThreadViewDataSet *) NULL;
+ break;
+ }
+ }
+
+ MagickFreeMemory(path_info);
+ }
+ if (polygon_set == (ThreadViewDataSet *) NULL)
+ return MagickFail;
+ }
+
+ /*
+ Compute bounding box.
+ */
+ {
+ const PolygonInfo
+ * restrict polygon_info;
+
+ register long
+ i;
+
+ polygon_info=(const PolygonInfo *) AccessThreadViewData(polygon_set);
+ bounds=polygon_info->edges[0].bounds;
+
+ if (0) /* DEBUG ??? */
+ DrawBoundingRectangles(image,draw_info,polygon_info);
+
+ for (i=1; i < polygon_info->number_edges; i++)
+ {
+ register const EdgeInfo
+ *p;
+
+ p=polygon_info->edges+i;
+ if (p->bounds.x1 < bounds.x1)
+ bounds.x1=p->bounds.x1;
+ if (p->bounds.y1 < bounds.y1)
+ bounds.y1=p->bounds.y1;
+ if (p->bounds.x2 > bounds.x2)
+ bounds.x2=p->bounds.x2;
+ if (p->bounds.y2 > bounds.y2)
+ bounds.y2=p->bounds.y2;
+ }
+ mid=ExpandAffine(&draw_info->affine)*draw_info->stroke_width/2.0;
+ bounds.x1-=(mid+1.0);
+ bounds.x1=bounds.x1 < 0.0 ? 0.0 : bounds.x1 >= image->columns ?
+ image->columns-1 : bounds.x1;
+ bounds.y1-=(mid+1.0);
+ bounds.y1=bounds.y1 < 0.0 ? 0.0 : bounds.y1 >= image->rows ?
+ image->rows-1 : bounds.y1;
+ bounds.x2+=(mid+1.0);
+ bounds.x2=bounds.x2 < 0.0 ? 0.0 : bounds.x2 >= image->columns ?
+ image->columns-1 : bounds.x2;
+ bounds.y2+=(mid+1.0);
+ bounds.y2=bounds.y2 < 0.0 ? 0.0 : bounds.y2 >= image->rows ?
+ image->rows-1 : bounds.y2;
+ }
+
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," begin draw-polygon");
+
+ if (primitive_info->coordinates == 1)
+ {
+ /*
+ Draw point.
+ */
+ long
+ x_start,
+ x_stop,
+ y_start,
+ y_stop,
+ y;
+
+ PixelPacket
+ stroke_color;
+
+ stroke_color=draw_info->stroke;
+ x_start=(long) ceil(bounds.x1-0.5);
+ x_stop=(long) floor(bounds.x2+0.5);
+ y_start=(long) ceil(bounds.y1-0.5);
+ y_stop=(long) floor(bounds.y2+0.5);
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(status)
+# else
+# pragma omp parallel for schedule(static) shared(status)
+# endif
+#endif
+ for (y=y_start; y <= y_stop; y++)
+ {
+ long
+ x;
+
+ PixelPacket
+ * restrict q;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_DrawPolygonPrimitive_Status)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ x=x_start;
+ q=GetImagePixelsEx(image,x,y,x_stop-x+1,1,&image->exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for ( ; x <= x_stop; x++)
+ {
+ if ((x == (long) ceil(primitive_info->point.x-0.5)) &&
+ (y == (long) ceil(primitive_info->point.y-0.5)))
+ *q=stroke_color;
+ q++;
+ }
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+ }
+ if (thread_status == MagickFail)
+ {
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_DrawPolygonPrimitive_Status)
+#endif
+ status=thread_status;
+ }
+ }
+ } /* if (primitive_info->coordinates == 1) */
+ else
+ {
+ /*
+ Draw polygon or line.
+ */
+ long
+ x_start,
+ x_stop,
+ y_start,
+ y_stop,
+ y;
+
+ const Image
+ *fill_pattern=draw_info->fill_pattern,
+ *stroke_pattern=draw_info->stroke_pattern;
+
+ unsigned int
+ fill;
+
+ fill=(primitive_info->method == FillToBorderMethod) ||
+ (primitive_info->method == FloodfillMethod);
+
+ x_start=(long) ceil(bounds.x1-0.5);
+ x_stop=(long) floor(bounds.x2+0.5);
+ y_start=(long) ceil(bounds.y1-0.5);
+ y_stop=(long) floor(bounds.y2+0.5);
+#if 1
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(status)
+# else
+# pragma omp parallel for schedule(static) shared(status)
+# endif
+#endif
+#endif
+ for (y=y_start; y <= y_stop; y++)
+ {
+ PixelPacket
+ fill_color,
+ stroke_color;
+
+ double
+ fill_opacity,
+ stroke_opacity;
+
+ long
+ x;
+
+ PolygonInfo
+ * restrict polygon_info;
+
+ PixelPacket
+ * restrict q;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_DrawPolygonPrimitive_Status)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ polygon_info=(PolygonInfo *) AccessThreadViewData(polygon_set);
+ fill_color=draw_info->fill;
+ stroke_color=draw_info->stroke;
+ x=x_start;
+ q=GetImagePixelsEx(image,x,y,x_stop-x+1,1,&image->exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ for ( ; x <= x_stop; x++)
+ {
+ /*
+ Fill and/or stroke.
+ */
+ fill_opacity=GetPixelOpacity(polygon_info,mid,fill,
+ draw_info->fill_rule,
+ x,y,&stroke_opacity);
+ if (!draw_info->stroke_antialias)
+ {
+ /* When stroke antialiasing is disabled, only draw for
+ opacities >= 0.99 in order to ensure that lines are not
+ drawn wider than requested. */
+ if (fill_opacity < 0.99)
+ fill_opacity=0.0;
+ if (stroke_opacity < 0.99)
+ stroke_opacity=0.0;
+ }
+ if ((fill_pattern != (Image *) NULL) &&
+ (fill_pattern->columns != 0) &&
+ (fill_pattern->rows != 0))
+ (void) AcquireOnePixelByReference
+ (fill_pattern,&fill_color,
+ (long) (x-fill_pattern->tile_info.x) % fill_pattern->columns,
+ (long) (y-fill_pattern->tile_info.y) % fill_pattern->rows,
+ &image->exception);
+ fill_opacity=MaxRGBDouble-fill_opacity*
+ (MaxRGBDouble-(double) fill_color.opacity);
+ AlphaCompositePixel(q,&fill_color,fill_opacity,q,
+ (q->opacity == TransparentOpacity)
+ ? OpaqueOpacity : q->opacity);
+ if ((stroke_pattern != (Image *) NULL) &&
+ (stroke_pattern->columns != 0) &&
+ (stroke_pattern->rows != 0))
+ (void) AcquireOnePixelByReference
+ (stroke_pattern,&stroke_color,
+ (long) (x-stroke_pattern->tile_info.x) % stroke_pattern->columns,
+ (long) (y-stroke_pattern->tile_info.y) % stroke_pattern->rows,
+ &image->exception);
+ stroke_opacity=MaxRGBDouble-stroke_opacity*
+ (MaxRGBDouble-(double)stroke_color.opacity);
+ AlphaCompositePixel(q,&stroke_color,stroke_opacity,q,
+ (q->opacity == TransparentOpacity)
+ ? OpaqueOpacity : q->opacity);
+ q++;
+ } /* for ( ; x <= x_stop; x++) */
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ {
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_DrawPolygonPrimitive_Status)
+#endif
+ status=thread_status;
+ }
+ }
+ }
+ }
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," end draw-polygon");
+ DestroyThreadViewDataSet(polygon_set);
+
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D r a w P r i m i t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DrawPrimitive draws a primitive (line, rectangle, ellipse) on the
+% image.
+%
+% The format of the DrawPrimitive method is:
+%
+% void DrawPrimitive(Image *image,const DrawInfo *draw_info,
+% PrimitiveInfo *primitive_info)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o primitive_info: Specifies a pointer to a PrimitiveInfo structure.
+%
+%
+*/
+
+static void
+LogPrimitiveInfo(const PrimitiveInfo *primitive_info)
+{
+ char
+ *methods[] =
+ {
+ (char *) "point",
+ (char *) "replace",
+ (char *) "floodfill",
+ (char *) "filltoborder",
+ (char *) "reset",
+ (char *) "?"
+ };
+
+ long
+ coordinates,
+ y;
+
+ PointInfo
+ p={0,0},
+ q,
+ point;
+
+ register long
+ i,
+ x;
+
+ x=(long) ceil(primitive_info->point.x-0.5);
+ y=(long) ceil(primitive_info->point.y-0.5);
+ switch (primitive_info->primitive)
+ {
+ case PointPrimitive:
+ {
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ "PointPrimitive %ld,%ld %s",x,y,methods[primitive_info->method]);
+ return;
+ }
+ case ColorPrimitive:
+ {
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ "ColorPrimitive %ld,%ld %s",x,y,methods[primitive_info->method]);
+ return;
+ }
+ case MattePrimitive:
+ {
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ "MattePrimitive %ld,%ld %s",x,y,methods[primitive_info->method]);
+ return;
+ }
+ case TextPrimitive:
+ {
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ "TextPrimitive %ld,%ld",x,y);
+ return;
+ }
+ case ImagePrimitive:
+ {
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ "ImagePrimitive %ld,%ld",x,y);
+ return;
+ }
+ default:
+ break;
+ }
+ coordinates=0;
+ q.x=(-1.0);
+ q.y=(-1.0);
+ for (i=0; primitive_info[i].primitive != UndefinedPrimitive; i++)
+ {
+ point=primitive_info[i].point;
+ if (coordinates <= 0)
+ {
+ coordinates=(long) primitive_info[i].coordinates;
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ " begin open (%ld)",coordinates);
+ p=point;
+ }
+ point=primitive_info[i].point;
+ if ((fabs(q.x-point.x) > MagickEpsilon) ||
+ (fabs(q.y-point.y) > MagickEpsilon))
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," %ld: %g,%g",
+ coordinates,point.x,point.y);
+ else
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ " %ld: %g,%g (duplicate)",coordinates,point.x,point.y);
+ q=point;
+ coordinates--;
+ if (coordinates > 0)
+ continue;
+ if ((fabs(p.x-point.x) > MagickEpsilon) ||
+ (fabs(p.y-point.y) > MagickEpsilon))
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," end last (%ld)",
+ coordinates);
+ else
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," end open (%ld)",
+ coordinates);
+ }
+}
+
+static MagickPassFail
+DrawPrimitive(Image *image,const DrawInfo *draw_info,
+ const PrimitiveInfo *primitive_info)
+{
+ long
+ y;
+
+ MonitorHandler
+ handler;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ MagickPassFail
+ status=MagickPass;
+
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," begin draw-primitive");
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ " affine: %g,%g,%g,%g,%g,%g",draw_info->affine.sx,draw_info->affine.rx,
+ draw_info->affine.ry,draw_info->affine.sy,draw_info->affine.tx,
+ draw_info->affine.ty);
+ status &= ModifyCache(image,&image->exception);
+ if (status == MagickFail)
+ {
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," end draw-primitive");
+ return status;
+ }
+ x=(long) ceil(primitive_info->point.x-0.5);
+ y=(long) ceil(primitive_info->point.y-0.5);
+ switch (primitive_info->primitive)
+ {
+ case PointPrimitive:
+ {
+ if ((q=GetImagePixels(image,x,y,1,1)) != (PixelPacket *) NULL)
+ {
+ *q=draw_info->fill;
+ status&=SyncImagePixels(image);
+ }
+ break;
+ }
+ case ColorPrimitive:
+ {
+ switch (primitive_info->method)
+ {
+ case PointMethod:
+ default:
+ {
+ if ((q=GetImagePixels(image,x,y,1,1)) != (PixelPacket *) NULL)
+ {
+ *q=draw_info->fill;
+ status&=SyncImagePixels(image);
+ }
+ break;
+ }
+ case ReplaceMethod:
+ {
+ Image
+ *pattern;
+
+ PixelPacket
+ color,
+ target;
+
+ color=draw_info->fill;
+ if (AcquireOnePixelByReference(image,&target,x,y,
+ &image->exception) == MagickFail)
+ break;
+ pattern=draw_info->fill_pattern;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if (!FuzzyColorMatch(q,&target,image->fuzz))
+ {
+ q++;
+ continue;
+ }
+ if (pattern != (Image *) NULL)
+ {
+ if (AcquireOnePixelByReference(pattern,&color,
+ (long) (x-pattern->tile_info.x) % pattern->columns,
+ (long) (y-pattern->tile_info.y) % pattern->rows,
+ &image->exception) == MagickFail)
+ break;
+ if (!pattern->matte)
+ color.opacity=OpaqueOpacity;
+ }
+ if (color.opacity != TransparentOpacity)
+ AlphaCompositePixel(q,&color,color.opacity,q,q->opacity);
+ q++;
+ }
+ status&=SyncImagePixels(image);
+ if (status == MagickFail)
+ break;
+ }
+ break;
+ }
+ case FloodfillMethod:
+ case FillToBorderMethod:
+ {
+ PixelPacket
+ border_color,
+ target;
+
+ if (AcquireOnePixelByReference(image,&target,x,y,
+ &image->exception) == MagickFail)
+ break;
+ if (primitive_info->method == FillToBorderMethod)
+ {
+ border_color=draw_info->border_color;
+ target=border_color;
+ }
+ status&=ColorFloodfillImage(image,draw_info,target,x,y,
+ primitive_info->method);
+ break;
+ }
+ case ResetMethod:
+ {
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ *q=draw_info->fill;
+ q++;
+ }
+ status&=SyncImagePixels(image);
+ if (status == MagickFail)
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case MattePrimitive:
+ {
+ if (!image->matte)
+ SetImageOpacity(image,OpaqueOpacity);
+ switch (primitive_info->method)
+ {
+ case PointMethod:
+ default:
+ {
+ q=GetImagePixels(image,x,y,1,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ q->opacity=TransparentOpacity;
+ status&=SyncImagePixels(image);
+ break;
+ }
+ case ReplaceMethod:
+ {
+ PixelPacket
+ target;
+
+ if (AcquireOnePixelByReference(image,&target,x,y,
+ &image->exception) == MagickFail)
+ break;
+ status&=TransparentImage(image,target,TransparentOpacity);
+ break;
+ }
+ case FloodfillMethod:
+ case FillToBorderMethod:
+ {
+ PixelPacket
+ border_color,
+ target;
+
+ if (AcquireOnePixelByReference(image,&target,x,y,
+ &image->exception) == MagickFail)
+ break;
+ if (primitive_info->method == FillToBorderMethod)
+ {
+ border_color=draw_info->border_color;
+ target=border_color;
+ }
+ status&=MatteFloodfillImage(image,target,TransparentOpacity,x,y,
+ primitive_info->method);
+ break;
+ }
+ case ResetMethod:
+ {
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ q->opacity=draw_info->fill.opacity;
+ q++;
+ }
+ status&=SyncImagePixels(image);
+ if (status == MagickFail)
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case TextPrimitive:
+ {
+ char
+ geometry[MaxTextExtent];
+
+ DrawInfo
+ *clone_info;
+
+ if (primitive_info->text == (char *) NULL)
+ break;
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ (void) CloneString(&clone_info->text,primitive_info->text);
+ FormatString(geometry,"%+g%+g",primitive_info->point.x,
+ primitive_info->point.y);
+ (void) CloneString(&clone_info->geometry,geometry);
+ /*
+ FIXME: AnnotateImage sometimes returns error status here
+ without throwing exception and under conditions which should
+ be ok when rendering (e.g. off-canvas drawing).
+ */
+ status&=AnnotateImage(image,clone_info);
+ DestroyDrawInfo(clone_info);
+ break;
+ }
+ case ImagePrimitive:
+ {
+ AffineMatrix
+ affine;
+
+ Image
+ *composite_image=(Image *) NULL;
+
+ ImageInfo
+ *clone_info;
+
+ if (primitive_info->text == (char *) NULL)
+ break;
+ clone_info=CloneImageInfo((ImageInfo *) NULL);
+ if (LocaleNCompare(primitive_info->text,"data:",5) == 0)
+ composite_image=ReadInlineImage(clone_info,primitive_info->text,
+ &image->exception);
+ else
+ {
+ /*
+ Sanity check URL/path before passing it to ReadImage()
+
+ This is a temporary fix until suitable flags can be passed
+ to keep SetImageInfo() from doing potentially dangerous
+ magick things.
+ */
+#define VALID_PREFIX(str,url) (LocaleNCompare(str,url,sizeof(str)-1) == 0)
+ if (!VALID_PREFIX("http://", primitive_info->text) &&
+ !VALID_PREFIX("https://", primitive_info->text) &&
+ !VALID_PREFIX("ftp://", primitive_info->text) &&
+ !(IsAccessibleNoLogging(primitive_info->text))
+ )
+ {
+ ThrowException(&image->exception,FileOpenError,UnableToOpenFile,primitive_info->text);
+ status=MagickFail;
+ }
+ else
+ {
+ (void) strlcpy(clone_info->filename,primitive_info->text,
+ MaxTextExtent);
+ composite_image=ReadImage(clone_info,&image->exception);
+ }
+ }
+ if (image->exception.severity != UndefinedException)
+ MagickError2(image->exception.severity,image->exception.reason,
+ image->exception.description);
+ DestroyImageInfo(clone_info);
+ if (composite_image == (Image *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ if ((primitive_info[1].point.x != composite_image->columns) &&
+ (primitive_info[1].point.y != composite_image->rows))
+ {
+ char
+ geometry[MaxTextExtent];
+
+ /*
+ Resize image.
+ */
+ FormatString(geometry,"%gx%g!",primitive_info[1].point.x,
+ primitive_info[1].point.y);
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ TransformImage(&composite_image,(char *) NULL,geometry);
+ (void) SetMonitorHandler(handler);
+ }
+ if (!composite_image->matte)
+ SetImageOpacity(composite_image,OpaqueOpacity);
+ if (draw_info->opacity != OpaqueOpacity)
+ SetImageOpacity(composite_image,draw_info->opacity);
+ affine=draw_info->affine;
+ affine.tx=x;
+ affine.ty=y;
+ status&=DrawAffineImage(image,composite_image,&affine);
+ DestroyImage(composite_image);
+ break;
+ }
+ default:
+ {
+ double
+ mid,
+ scale;
+
+ DrawInfo
+ *clone_info;
+
+ if (IsEventLogging())
+ LogPrimitiveInfo(primitive_info);
+ scale=ExpandAffine(&draw_info->affine);
+ if ((draw_info->dash_pattern != (double *) NULL) &&
+ (draw_info->dash_pattern[0] != 0.0) &&
+ ((scale*draw_info->stroke_width) > MagickEpsilon) &&
+ (draw_info->stroke.opacity != TransparentOpacity))
+ {
+ /*
+ Draw dash polygon.
+ */
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ clone_info->stroke_width=0.0;
+ clone_info->stroke.opacity=TransparentOpacity;
+ status&=DrawPolygonPrimitive(image,clone_info,primitive_info);
+ DestroyDrawInfo(clone_info);
+ status&=DrawDashPolygon(draw_info,primitive_info,image);
+ break;
+ }
+ mid=ExpandAffine(&draw_info->affine)*draw_info->stroke_width/2.0;
+ if ((mid > 1.0) && (draw_info->stroke.opacity != TransparentOpacity))
+ {
+ unsigned int
+ closed_path;
+
+ /*
+ Draw strokes while respecting line cap/join attributes.
+ */
+ for (i=0; primitive_info[i].primitive != UndefinedPrimitive; i++);
+ closed_path=
+ (primitive_info[i-1].point.x == primitive_info[0].point.x) &&
+ (primitive_info[i-1].point.y == primitive_info[0].point.y);
+ i=(long) primitive_info[0].coordinates;
+ if ((((draw_info->linecap == RoundCap) || closed_path) &&
+ (draw_info->linejoin == RoundJoin)) ||
+ (primitive_info[i].primitive != UndefinedPrimitive))
+ {
+ status&=DrawPolygonPrimitive(image,draw_info,primitive_info);
+ break;
+ }
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ clone_info->stroke_width=0.0;
+ clone_info->stroke.opacity=TransparentOpacity;
+ status&=DrawPolygonPrimitive(image,clone_info,primitive_info);
+ DestroyDrawInfo(clone_info);
+ status&=DrawStrokePolygon(image,draw_info,primitive_info);
+ break;
+ }
+ status&=DrawPolygonPrimitive(image,draw_info,primitive_info);
+ break;
+ }
+ }
+ (void) LogMagickEvent(RenderEvent,GetMagickModule()," end draw-primitive");
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D r a w S t r o k e P o l y g o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DrawStrokePolygon draws a stroked polygon (line, rectangle, ellipse)
+% on the image while respecting the line cap and join attributes.
+%
+% The format of the DrawStrokePolygon method is:
+%
+% unsigned int DrawStrokePolygon(Image *image,const DrawInfo *draw_info,
+% const PrimitiveInfo *primitive_info)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o draw_info: The draw info.
+%
+% o primitive_info: Specifies a pointer to a PrimitiveInfo structure.
+%
+%
+*/
+
+static void
+DrawRoundLinecap(Image *image,const DrawInfo *draw_info,
+ const PrimitiveInfo *primitive_info)
+{
+ PrimitiveInfo
+ linecap[5];
+
+ register long
+ i;
+
+ for (i=0; i < 4; i++)
+ linecap[i]=(*primitive_info);
+ linecap[0].coordinates=4;
+ linecap[1].point.x+=10.0*MagickEpsilon;
+ linecap[2].point.x+=10.0*MagickEpsilon;
+ linecap[2].point.y+=10.0*MagickEpsilon;
+ linecap[3].point.y+=10.0*MagickEpsilon;
+ linecap[4].primitive=UndefinedPrimitive;
+ (void) DrawPolygonPrimitive(image,draw_info,linecap);
+}
+
+static MagickPassFail
+DrawStrokePolygon(Image *image,const DrawInfo *draw_info,
+ const PrimitiveInfo *primitive_info)
+{
+ DrawInfo
+ *clone_info;
+
+ MagickBool
+ closed_path;
+
+ MagickPassFail
+ status;
+
+ PrimitiveInfo
+ *stroke_polygon;
+
+ register const PrimitiveInfo
+ *p,
+ *q;
+
+ /*
+ Draw stroked polygon.
+ */
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ " begin draw-stroke-polygon");
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ clone_info->fill=draw_info->stroke;
+ if (clone_info->fill_pattern != (Image *) NULL)
+ {
+ DestroyImage(clone_info->fill_pattern);
+ clone_info->fill_pattern= (Image *) NULL;
+ }
+ if (clone_info->stroke_pattern != (Image *) NULL)
+ clone_info->fill_pattern=CloneImage(clone_info->stroke_pattern,0,0,
+ MagickTrue,&clone_info->stroke_pattern->exception);
+ clone_info->stroke.opacity=TransparentOpacity;
+ clone_info->stroke_width=0.0;
+ clone_info->fill_rule=NonZeroRule;
+ status=MagickPass;
+ for (p=primitive_info; p->primitive != UndefinedPrimitive; p+=p->coordinates)
+ {
+ stroke_polygon=TraceStrokePolygon(draw_info,p);
+ status&=DrawPolygonPrimitive(image,clone_info,stroke_polygon);
+ MagickFreeMemory(stroke_polygon);
+ if (status == MagickFail)
+ break;
+ q=p+p->coordinates-1;
+ closed_path=(q->point.x == p->point.x) && (q->point.y == p->point.y);
+ if ((draw_info->linecap == RoundCap) && !closed_path)
+ {
+ DrawRoundLinecap(image,draw_info,p);
+ DrawRoundLinecap(image,draw_info,q);
+ }
+ }
+ DestroyDrawInfo(clone_info);
+ (void) LogMagickEvent(RenderEvent,GetMagickModule(),
+ " end draw-stroke-polygon");
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t D r a w I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetDrawInfo initializes draw_info to default values.
+%
+% The format of the GetDrawInfo method is:
+%
+% void GetDrawInfo(const ImageInfo *image_info,DrawInfo *draw_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info..
+%
+% o draw_info: The draw info.
+%
+%
+*/
+MagickExport void
+GetDrawInfo(const ImageInfo *image_info,DrawInfo *draw_info)
+{
+ ImageInfo
+ *clone_info;
+
+ /*
+ Initialize draw attributes.
+ */
+ assert(draw_info != (DrawInfo *) NULL);
+ (void) memset(draw_info,0,sizeof(DrawInfo));
+ clone_info=CloneImageInfo(image_info);
+ IdentityAffine(&draw_info->affine);
+ draw_info->gravity=NorthWestGravity;
+ draw_info->opacity=OpaqueOpacity; /* 0UL */
+ draw_info->fill.opacity=OpaqueOpacity; /* 0UL */
+ draw_info->stroke.opacity=TransparentOpacity; /* MaxRGB */
+ draw_info->stroke_antialias=clone_info->antialias;
+ draw_info->stroke_width=1.0;
+ draw_info->fill_rule=EvenOddRule;
+ draw_info->linecap=ButtCap;
+ draw_info->linejoin=MiterJoin;
+ draw_info->miterlimit=10;
+ draw_info->decorate=NoDecoration;
+ if (clone_info->font != (char *) NULL)
+ draw_info->font=AllocateString(clone_info->font);
+ if (clone_info->density != (char *) NULL)
+ draw_info->density=AllocateString(clone_info->density);
+ draw_info->text_antialias=clone_info->antialias;
+ draw_info->pointsize=clone_info->pointsize;
+ draw_info->undercolor.opacity=TransparentOpacity;
+ draw_info->border_color=clone_info->border_color;
+ draw_info->compose=CopyCompositeOp;
+ if (clone_info->server_name != (char *) NULL)
+ draw_info->server_name=AllocateString(clone_info->server_name);
+ draw_info->render=True;
+ draw_info->signature=MagickSignature;
+ DestroyImageInfo(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ P e r m u t a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Permutate()
+%
+% The format of the Permutate method is:
+%
+% void Permutate(long n,long k)
+%
+% A description of each parameter follows:
+%
+% o n:
+%
+% o k:
+%
+%
+*/
+static inline double
+Permutate(const long n,const long k)
+{
+ double
+ r;
+
+ register long
+ i;
+
+ r=1.0;
+ for (i=k+1; i <= n; i++)
+ r*=i;
+ for (i=1; i <= (n-k); i++)
+ r/=i;
+ return(r);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ T r a c e P r i m i t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TracePrimitive is a collection of methods for generating graphic
+% primitives such as arcs, ellipses, paths, etc.
+%
+%
+*/
+
+static void
+TraceArc(PrimitiveInfo *primitive_info,const PointInfo start,
+ const PointInfo end,const PointInfo arc)
+{
+ PointInfo
+ center,
+ radius;
+
+ center.x=0.5*(end.x+start.x);
+ center.y=0.5*(end.y+start.y);
+ radius.x=fabs(center.x-start.x);
+ radius.y=fabs(center.y-start.y);
+ TraceEllipse(primitive_info,center,radius,arc);
+}
+
+static void
+TraceArcPath(PrimitiveInfo *primitive_info,const PointInfo start,
+ const PointInfo end,const PointInfo arc,const double angle,
+ const unsigned int large_arc,const unsigned int sweep)
+{
+ double
+ alpha,
+ beta,
+ delta,
+ factor,
+ gamma,
+ theta;
+
+ PointInfo
+ center,
+ points[3],
+ radii;
+
+ register double
+ cosine,
+ sine;
+
+ register PrimitiveInfo
+ *p;
+
+ register long
+ i;
+
+ unsigned long
+ arc_segments;
+
+ if ((start.x == end.x) && (start.y == end.y))
+ return;
+ radii.x=fabs(arc.x);
+ radii.y=fabs(arc.y);
+ if ((radii.x == 0.0) || (radii.y == 0.0))
+ {
+ TraceLine(primitive_info,start,end);
+ return;
+ }
+ cosine=cos(DegreesToRadians(fmod(angle,360.0)));
+ sine=sin(DegreesToRadians(fmod(angle,360.0)));
+ center.x=cosine*(end.x-start.x)/2+sine*(end.y-start.y)/2;
+ center.y=cosine*(end.y-start.y)/2-sine*(end.x-start.x)/2;
+ delta=(center.x*center.x)/(radii.x*radii.x)+
+ (center.y*center.y)/(radii.y*radii.y);
+ if (delta > 1.0)
+ {
+ radii.x*=sqrt(delta);
+ radii.y*=sqrt(delta);
+ }
+ points[0].x=cosine*start.x/radii.x+sine*start.y/radii.x;
+ points[0].y=cosine*start.y/radii.y-sine*start.x/radii.y;
+ points[1].x=cosine*end.x/radii.x+sine*end.y/radii.x;
+ points[1].y=cosine*end.y/radii.y-sine*end.x/radii.y;
+ alpha=points[1].x-points[0].x;
+ beta=points[1].y-points[0].y;
+ factor=1.0/(alpha*alpha+beta*beta)-0.25;
+ if (factor <= 0.0)
+ factor=0.0;
+ else
+ {
+ factor=sqrt(factor);
+ if (sweep == large_arc)
+ factor=(-factor);
+ }
+ center.x=(points[0].x+points[1].x)/2-factor*beta;
+ center.y=(points[0].y+points[1].y)/2+factor*alpha;
+ alpha=atan2(points[0].y-center.y,points[0].x-center.x);
+ theta=atan2(points[1].y-center.y,points[1].x-center.x)-alpha;
+ if ((theta < 0.0) && sweep)
+ theta+=2.0*MagickPI;
+ else
+ if ((theta > 0.0) && !sweep)
+ theta-=2.0*MagickPI;
+ arc_segments=(long) ceil(fabs(theta/(0.5*MagickPI+MagickEpsilon)));
+ p=primitive_info;
+ for (i=0; i < (long) arc_segments; i++)
+ {
+ beta=0.5*((alpha+(i+1)*theta/arc_segments)-(alpha+i*theta/arc_segments));
+ gamma=(8.0/3.0)*sin(fmod(0.5*beta,DegreesToRadians(360.0)))*
+ sin(fmod(0.5*beta,DegreesToRadians(360.0)))/
+ sin(fmod(beta,DegreesToRadians(360.0)));
+ points[0].x=center.x+
+ cos(fmod(alpha+i*theta/arc_segments,DegreesToRadians(360.0)))-gamma*
+ sin(fmod(alpha+i*theta/arc_segments,DegreesToRadians(360.0)));
+ points[0].y=center.y+
+ sin(fmod(alpha+i*theta/arc_segments,DegreesToRadians(360.0)))+gamma*
+ cos(fmod(alpha+i*theta/arc_segments,DegreesToRadians(360.0)));
+ points[2].x=center.x+
+ cos(fmod(alpha+(i+1)*theta/arc_segments,DegreesToRadians(360.0)));
+ points[2].y=center.y+
+ sin(fmod(alpha+(i+1)*theta/arc_segments,DegreesToRadians(360.0)));
+ points[1].x=points[2].x+gamma*
+ sin(fmod(alpha+(i+1)*theta/arc_segments,DegreesToRadians(360.0)));
+ points[1].y=points[2].y-gamma*
+ cos(fmod(alpha+(i+1)*theta/arc_segments,DegreesToRadians(360.0)));
+ p->point.x=(p == primitive_info) ? start.x : (p-1)->point.x;
+ p->point.y=(p == primitive_info) ? start.y : (p-1)->point.y;
+ (p+1)->point.x=cosine*radii.x*points[0].x-sine*radii.y*points[0].y;
+ (p+1)->point.y=sine*radii.x*points[0].x+cosine*radii.y*points[0].y;
+ (p+2)->point.x=cosine*radii.x*points[1].x-sine*radii.y*points[1].y;
+ (p+2)->point.y=sine*radii.x*points[1].x+cosine*radii.y*points[1].y;
+ (p+3)->point.x=cosine*radii.x*points[2].x-sine*radii.y*points[2].y;
+ (p+3)->point.y=sine*radii.x*points[2].x+cosine*radii.y*points[2].y;
+ if (i == (long) (arc_segments-1))
+ (p+3)->point=end;
+ TraceBezier(p,4);
+ p+=p->coordinates;
+ }
+ primitive_info->coordinates=p-primitive_info;
+ for (i=0; i < (long) primitive_info->coordinates; i++)
+ {
+ p->primitive=primitive_info->primitive;
+ p--;
+ }
+}
+
+static void
+TraceBezier(PrimitiveInfo *primitive_info,
+ const unsigned long number_coordinates)
+{
+ double
+ alpha,
+ *coefficients,
+ weight;
+
+ PointInfo
+ end,
+ point,
+ *points;
+
+ register PrimitiveInfo
+ *p;
+
+ register long
+ i,
+ j;
+
+ unsigned long
+ control_points,
+ quantum;
+
+ /*
+ Allocate coeficients.
+ */
+ quantum=number_coordinates;
+ for (i=0; i < (long) number_coordinates; i++)
+ {
+ for (j=i+1; j < (long) number_coordinates; j++)
+ {
+ alpha=fabs(primitive_info[j].point.x-primitive_info[i].point.x);
+ if (alpha > quantum)
+ quantum=(unsigned long) alpha;
+ alpha=fabs(primitive_info[j].point.y-primitive_info[i].point.y);
+ if (alpha > quantum)
+ quantum=(unsigned long) alpha;
+ }
+ }
+ quantum=Min(quantum/number_coordinates,BezierQuantum);
+ control_points=quantum*number_coordinates;
+ coefficients=MagickAllocateArray(double *,number_coordinates,sizeof(double));
+ points=MagickAllocateArray(PointInfo *,control_points,sizeof(PointInfo));
+ if ((coefficients == (double *) NULL) || (points == (PointInfo *) NULL))
+ MagickFatalError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDrawOnImage);
+ /*
+ Compute bezier points.
+ */
+ end=primitive_info[number_coordinates-1].point;
+ weight=0.0;
+ for (i=0; i < (long) number_coordinates; i++)
+ coefficients[i]=Permutate((long) number_coordinates-1,i);
+ for (i=0; i < (long) control_points; i++)
+ {
+ p=primitive_info;
+ point.x=0;
+ point.y=0;
+ alpha=pow((double) (1.0-weight),(double) number_coordinates-1);
+ for (j=0; j < (long) number_coordinates; j++)
+ {
+ point.x+=alpha*coefficients[j]*p->point.x;
+ point.y+=alpha*coefficients[j]*p->point.y;
+ alpha*=weight/(1.0-weight);
+ p++;
+ }
+ points[i]=point;
+ weight+=1.0/quantum/number_coordinates;
+ }
+ /*
+ Bezier curves are just short segmented polys.
+ */
+ p=primitive_info;
+ for (i=0; i < (long) control_points; i++)
+ {
+ TracePoint(p,points[i]);
+ p+=p->coordinates;
+ }
+ TracePoint(p,end);
+ p+=p->coordinates;
+ primitive_info->coordinates=p-primitive_info;
+ for (i=0; i < (long) primitive_info->coordinates; i++)
+ {
+ p->primitive=primitive_info->primitive;
+ p--;
+ }
+ MagickFreeMemory(points);
+ MagickFreeMemory(coefficients);
+}
+
+static void
+TraceCircle(PrimitiveInfo *primitive_info,const PointInfo start,
+ const PointInfo end)
+{
+ double
+ alpha,
+ beta,
+ radius;
+
+ PointInfo
+ offset,
+ degrees;
+
+ alpha=end.x-start.x;
+ beta=end.y-start.y;
+ radius=sqrt(alpha*alpha+beta*beta);
+ offset.x=radius;
+ offset.y=radius;
+ degrees.x=0.0;
+ degrees.y=360.0;
+ TraceEllipse(primitive_info,start,offset,degrees);
+}
+
+static void
+TraceEllipse(PrimitiveInfo *primitive_info,const PointInfo start,
+ const PointInfo stop,const PointInfo degrees)
+{
+ double
+ delta,
+ step,
+ y;
+
+ PointInfo
+ angle,
+ point;
+
+ register PrimitiveInfo
+ *p;
+
+ register long
+ i;
+
+ /*
+ Ellipses are just short segmented polys.
+ */
+ if (stop.x == 0.0 || stop.y == 0.0)
+ return;
+ delta=2.0/Max(stop.x,stop.y);
+ step=MagickPI/8.0;
+ if (delta < (MagickPI/8.0))
+ step=MagickPI/(4*ceil(MagickPI/delta/2));
+ angle.x=DegreesToRadians(degrees.x);
+ y=degrees.y;
+ while (y < degrees.x)
+ y+=360.0;
+ angle.y=DegreesToRadians(y);
+ for (p=primitive_info; angle.x < angle.y; angle.x+=step)
+ {
+ point.x=cos(fmod(angle.x,DegreesToRadians(360.0)))*stop.x+start.x;
+ point.y=sin(fmod(angle.x,DegreesToRadians(360.0)))*stop.y+start.y;
+ TracePoint(p,point);
+ p+=p->coordinates;
+ }
+ point.x=cos(fmod(angle.y,DegreesToRadians(360.0)))*stop.x+start.x;
+ point.y=sin(fmod(angle.y,DegreesToRadians(360.0)))*stop.y+start.y;
+ TracePoint(p,point);
+ p+=p->coordinates;
+ primitive_info->coordinates=p-primitive_info;
+ for (i=0; i < (long) primitive_info->coordinates; i++)
+ {
+ p->primitive=primitive_info->primitive;
+ p--;
+ }
+}
+
+static void
+TraceLine(PrimitiveInfo *primitive_info,const PointInfo start,
+ const PointInfo end)
+{
+ TracePoint(primitive_info,start);
+ if ((AbsoluteValue(start.x-end.x) <= MagickEpsilon) &&
+ (AbsoluteValue(start.y-end.y) <= MagickEpsilon))
+ {
+ primitive_info->primitive=PointPrimitive;
+ primitive_info->coordinates=1;
+ return;
+ }
+ TracePoint(primitive_info+1,end);
+ (primitive_info+1)->primitive=primitive_info->primitive;
+ primitive_info->coordinates=2;
+}
+
+/*
+ Special wrapper macros around strtod(), strtol(), and
+ MagickGetToken() to support TracePath() parsing error detection and
+ reporting.
+*/
+#define MagickTracePathAtoF(str,value) \
+ do { \
+ if (MagickAtoFChk(str,value) != MagickPass) \
+ { \
+ ThrowException(&image->exception,DrawError,FloatValueConversionError,str); \
+ return 0; \
+ } \
+ } while(0)
+
+#define MagickTracePathAtoI(str,value) \
+ do { \
+ if (MagickAtoIChk(str,value) != MagickPass) \
+ { \
+ ThrowException(&image->exception,DrawError,IntegerValueConversionError,str); \
+ return 0; \
+ } \
+ } while(0)
+
+#define MagickTracePathAtoUI(str,value) \
+ do { \
+ if (MagickAtoUIChk(str,value) != MagickPass) \
+ { \
+ ThrowException(&image->exception,DrawError,IntegerValueConversionError,str); \
+ return 0; \
+ } \
+ } while(0)
+
+#define MagickGetTracePathToken(p,ep,token,extent) \
+ do { \
+ if (MagickGetToken(p,ep,token,extent) < 1) \
+ { \
+ ThrowException(&image->exception,DrawError,VectorPathTruncated,p); \
+ return 0; \
+ } \
+ } while(0)
+
+
+static unsigned long
+TracePath(Image *image,PrimitiveInfo *primitive_info,const char *path)
+{
+ char
+ token[MaxTextExtent];
+
+ char
+ *p;
+
+ int
+ attribute,
+ last_attribute;
+
+ double
+ x,
+ y;
+
+ PointInfo
+ end={0,0},
+ points[4]={{0,0},{0,0},{0,0},{0,0}},
+ point={0,0},
+ start={0,0};
+
+ PrimitiveType
+ primitive_type;
+
+ register PrimitiveInfo
+ *q;
+
+ register long
+ i;
+
+ unsigned long
+ number_coordinates,
+ z_count;
+
+ attribute=0;
+ number_coordinates=0;
+ z_count=0;
+ primitive_type=primitive_info->primitive;
+ q=primitive_info;
+ for (p=(char *) path; *p != '\0'; )
+ {
+ while (isspace((int) *p))
+ p++;
+ if (*p == '\0')
+ break;
+ last_attribute=attribute;
+ attribute=(*p++);
+ switch (attribute)
+ {
+ /*
+ Elliptical arc
+ */
+ case 'a':
+ case 'A':
+ {
+ MagickBool
+ large_arc = MagickFalse,
+ sweep = MagickFalse;
+
+ double
+ angle = 0.0;
+
+ PointInfo
+ arc = {0,0};
+
+ /*
+ Compute arc points.
+ */
+ do
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&arc.x);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&arc.y);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&angle);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoUI(token,&large_arc);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoUI(token,&sweep);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&x);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&y);
+ end.x=attribute == 'A' ? x : point.x+x;
+ end.y=attribute == 'A' ? y : point.y+y;
+ TraceArcPath(q,point,end,arc,angle,large_arc,sweep);
+ q+=q->coordinates;
+ point=end;
+ while (isspace((int) ((unsigned char) *p)) != 0)
+ p++;
+ if (*p == ',')
+ p++;
+ } while (IsPoint(p) != MagickFalse);
+ break;
+ }
+ /*
+ Cubic Bézier curve
+ */
+ case 'c':
+ case 'C':
+ {
+ /*
+ Compute bezier points.
+ */
+ do
+ {
+ points[0]=point;
+ for (i=1; i < 4; i++)
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&x);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&y);
+ end.x=attribute == 'C' ? x : point.x+x;
+ end.y=attribute == 'C' ? y : point.y+y;
+ points[i]=end;
+ }
+ for (i=0; i < 4; i++)
+ (q+i)->point=points[i];
+ TraceBezier(q,4);
+ q+=q->coordinates;
+ point=end;
+ } while (IsPoint(p));
+ break;
+ }
+ case 'H':
+ case 'h':
+ {
+ do
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&x);
+ point.x=attribute == 'H' ? x: point.x+x;
+ TracePoint(q,point);
+ q+=q->coordinates;
+ } while (IsPoint(p));
+ break;
+ }
+ /*
+ Line to
+ */
+ case 'l':
+ case 'L':
+ {
+ do
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&x);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&y);
+ point.x=attribute == 'L' ? x : point.x+x;
+ point.y=attribute == 'L' ? y : point.y+y;
+ TracePoint(q,point);
+ q+=q->coordinates;
+ } while (IsPoint(p));
+ break;
+ }
+ /*
+ Move to
+ */
+ case 'M':
+ case 'm':
+ {
+ if (q != primitive_info)
+ {
+ primitive_info->coordinates=q-primitive_info;
+ number_coordinates+=primitive_info->coordinates;
+ primitive_info=q;
+ }
+ i=0;
+ do
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&x);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&y);
+ point.x=attribute == 'M' ? x : point.x+x;
+ point.y=attribute == 'M' ? y : point.y+y;
+ if (i == 0)
+ start=point;
+ i++;
+ TracePoint(q,point);
+ q+=q->coordinates;
+ if ((i != 0) && (attribute == 'M'))
+ {
+ TracePoint(q,point);
+ q+=q->coordinates;
+ }
+ } while (IsPoint(p));
+ break;
+ }
+ /*
+ Quadratic Bézier curve
+ */
+ case 'q':
+ case 'Q':
+ {
+ /*
+ Compute bezier points.
+ */
+ do
+ {
+ points[0]=point;
+ for (i=1; i < 3; i++)
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&x);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&y);
+ if (*p == ',')
+ p++;
+ end.x=attribute == 'Q' ? x : point.x+x;
+ end.y=attribute == 'Q' ? y : point.y+y;
+ points[i]=end;
+ }
+ for (i=0; i < 3; i++)
+ (q+i)->point=points[i];
+ TraceBezier(q,3);
+ q+=q->coordinates;
+ point=end;
+ } while (IsPoint(p));
+ break;
+ }
+ /*
+ Cubic Bézier curve
+ */
+ case 's':
+ case 'S':
+ {
+ /*
+ Compute bezier points.
+ */
+ do
+ {
+ points[0]=points[3];
+ points[1].x=2.0*points[3].x-points[2].x;
+ points[1].y=2.0*points[3].y-points[2].y;
+ for (i=2; i < 4; i++)
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&x);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&y);
+ if (*p == ',')
+ p++;
+ end.x=attribute == 'S' ? x : point.x+x;
+ end.y=attribute == 'S' ? y : point.y+y;
+ points[i]=end;
+ }
+ if (strchr("CcSs",last_attribute) == (char *) NULL)
+ {
+ points[0]=point;
+ points[1]=point;
+ }
+ for (i=0; i < 4; i++)
+ (q+i)->point=points[i];
+ TraceBezier(q,4);
+ q+=q->coordinates;
+ point=end;
+ } while (IsPoint(p));
+ break;
+ }
+ /*
+ Quadratic Bézier curve
+ */
+ case 't':
+ case 'T':
+ {
+ /*
+ Compute bezier points.
+ */
+ do
+ {
+ points[0]=points[2];
+ points[1].x=2.0*points[2].x-points[1].x;
+ points[1].y=2.0*points[2].y-points[1].y;
+ for (i=2; i < 3; i++)
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&x);
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&y);
+ end.x=attribute == 'T' ? x : point.x+x;
+ end.y=attribute == 'T' ? y : point.y+y;
+ points[i]=end;
+ }
+ if (strchr("QqTt",last_attribute) == (char *) NULL)
+ {
+ points[0]=point;
+ points[1]=point;
+ }
+ for (i=0; i < 3; i++)
+ (q+i)->point=points[i];
+ TraceBezier(q,3);
+ q+=q->coordinates;
+ point=end;
+ } while (IsPoint(p));
+ break;
+ }
+ /*
+ Line to
+ */
+ case 'v':
+ case 'V':
+ {
+ do
+ {
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ if (*token == ',')
+ MagickGetTracePathToken(p,&p,token,MaxTextExtent);
+ MagickTracePathAtoF(token,&y);
+ point.y=attribute == 'V' ? y : point.y+y;
+ TracePoint(q,point);
+ q+=q->coordinates;
+ } while (IsPoint(p));
+ break;
+ }
+ /*
+ Close path
+ */
+ case 'z':
+ case 'Z':
+ {
+ point=start;
+ TracePoint(q,point);
+ q+=q->coordinates;
+ primitive_info->coordinates=q-primitive_info;
+ number_coordinates+=primitive_info->coordinates;
+ primitive_info=q;
+ z_count++;
+ break;
+ }
+ default:
+ {
+ if (isalpha((int) attribute))
+ (void) fprintf(stderr,"attribute not recognized: %c\n",attribute);
+ break;
+ }
+ }
+ }
+
+ primitive_info->coordinates=q-primitive_info;
+ number_coordinates+=primitive_info->coordinates;
+ for (i=0; i < (long) number_coordinates; i++)
+ {
+ q--;
+ q->primitive=primitive_type;
+ if (z_count > 1)
+ q->method=FillToBorderMethod;
+ }
+ q=primitive_info;
+ return(number_coordinates);
+}
+
+static void
+TracePoint(PrimitiveInfo *primitive_info,const PointInfo point)
+{
+ primitive_info->coordinates=1;
+ primitive_info->point=point;
+}
+
+static void
+TraceRectangle(PrimitiveInfo *primitive_info,const PointInfo start,
+ const PointInfo end)
+{
+ PointInfo
+ point;
+
+ register PrimitiveInfo
+ *p;
+
+ register long
+ i;
+
+ p=primitive_info;
+ TracePoint(p,start);
+ p+=p->coordinates;
+ point.x=start.x;
+ point.y=end.y;
+ TracePoint(p,point);
+ p+=p->coordinates;
+ TracePoint(p,end);
+ p+=p->coordinates;
+ point.x=end.x;
+ point.y=start.y;
+ TracePoint(p,point);
+ p+=p->coordinates;
+ TracePoint(p,start);
+ p+=p->coordinates;
+ primitive_info->coordinates=p-primitive_info;
+ for (i=0; i < (long) primitive_info->coordinates; i++)
+ {
+ p->primitive=primitive_info->primitive;
+ p--;
+ }
+}
+
+static void
+TraceRoundRectangle(PrimitiveInfo *primitive_info,
+ const PointInfo start,const PointInfo end,PointInfo arc)
+{
+ PointInfo
+ degrees,
+ offset,
+ point;
+
+ register PrimitiveInfo
+ *p;
+
+ register long
+ i;
+
+ p=primitive_info;
+ offset.x=AbsoluteValue(end.x-start.x);
+ offset.y=AbsoluteValue(end.y-start.y);
+ if (arc.x > (0.5*offset.x))
+ arc.x=0.5*offset.x;
+ if (arc.y > (0.5*offset.y))
+ arc.y=0.5*offset.y;
+ point.x=start.x+offset.x-arc.x;
+ point.y=start.y+arc.y;
+ degrees.x=270.0;
+ degrees.y=360.0;
+ TraceEllipse(p,point,arc,degrees);
+ p+=p->coordinates;
+ point.x=start.x+offset.x-arc.x;
+ point.y=start.y+offset.y-arc.y;
+ degrees.x=0.0;
+ degrees.y=90.0;
+ TraceEllipse(p,point,arc,degrees);
+ p+=p->coordinates;
+ point.x=start.x+arc.x;
+ point.y=start.y+offset.y-arc.y;
+ degrees.x=90.0;
+ degrees.y=180.0;
+ TraceEllipse(p,point,arc,degrees);
+ p+=p->coordinates;
+ point.x=start.x+arc.x;
+ point.y=start.y+arc.y;
+ degrees.x=180.0;
+ degrees.y=270.0;
+ TraceEllipse(p,point,arc,degrees);
+ p+=p->coordinates;
+ TracePoint(p,primitive_info->point);
+ p+=p->coordinates;
+ primitive_info->coordinates=p-primitive_info;
+ for (i=0; i < (long) primitive_info->coordinates; i++)
+ {
+ p->primitive=primitive_info->primitive;
+ p--;
+ }
+}
+
+static void
+TraceSquareLinecap(PrimitiveInfo *primitive_info,
+ const unsigned long number_vertices,const double offset)
+{
+ double
+ distance;
+
+ register double
+ dx,
+ dy;
+
+ register long
+ i;
+
+ long
+ j;
+
+ dx=0.0;
+ dy=0.0;
+ for (i=1; i < (long) number_vertices; i++)
+ {
+ dx=primitive_info[0].point.x-primitive_info[i].point.x;
+ dy=primitive_info[0].point.y-primitive_info[i].point.y;
+ if ((fabs(dx) >= MagickEpsilon) || (fabs(dy) >= MagickEpsilon))
+ break;
+ }
+ if (i == (long) number_vertices)
+ i=number_vertices-1;
+ distance=sqrt(dx*dx+dy*dy+MagickEpsilon);
+ primitive_info[0].point.x=primitive_info[i].point.x+
+ dx*(distance+offset)/distance;
+ primitive_info[0].point.y=primitive_info[i].point.y+
+ dy*(distance+offset)/distance;
+ for (j=(long) number_vertices-2; j >= 0; j--)
+ {
+ dx=primitive_info[number_vertices-1].point.x-primitive_info[j].point.x;
+ dy=primitive_info[number_vertices-1].point.y-primitive_info[j].point.y;
+ if ((fabs(dx) >= MagickEpsilon) || (fabs(dy) >= MagickEpsilon))
+ break;
+ }
+ distance=sqrt(dx*dx+dy*dy+MagickEpsilon);
+ primitive_info[number_vertices-1].point.x=primitive_info[j].point.x+
+ dx*(distance+offset)/distance;
+ primitive_info[number_vertices-1].point.y=primitive_info[j].point.y+
+ dy*(distance+offset)/distance;
+}
+
+static PrimitiveInfo *
+TraceStrokePolygon(const DrawInfo *draw_info,
+ const PrimitiveInfo *primitive_info)
+{
+ typedef struct _LineSegment
+ {
+ double
+ p,
+ q;
+ } LineSegment;
+
+ LineSegment
+ dx={0,0},
+ dy={0,0},
+ inverse_slope={0,0},
+ slope={0,0},
+ theta={0,0};
+
+ MagickBool
+ closed_path;
+
+ double
+ delta_theta,
+ dot_product,
+ mid,
+ miterlimit;
+
+ PointInfo
+ box_p[5],
+ box_q[5],
+ center,
+ offset,
+ *path_p,
+ *path_q;
+
+ PrimitiveInfo
+ *polygon_primitive,
+ *stroke_polygon;
+
+ register long
+ i;
+
+ unsigned long
+ arc_segments,
+ max_strokes,
+ number_vertices;
+
+ unsigned long
+ j,
+ n,
+ p,
+ q;
+
+ /*
+ Allocate paths.
+ */
+ number_vertices=primitive_info->coordinates;
+ max_strokes=2*number_vertices+6*BezierQuantum+360;
+ path_p=MagickAllocateArray(PointInfo *,max_strokes,sizeof(PointInfo));
+ if (path_p == (PointInfo *) NULL)
+ return((PrimitiveInfo *) NULL);
+ path_q=MagickAllocateArray(PointInfo *,max_strokes,sizeof(PointInfo));
+ if (path_q == (PointInfo *) NULL)
+ {
+ MagickFreeMemory(path_p);
+ return((PrimitiveInfo *) NULL);
+ }
+ polygon_primitive=
+ MagickAllocateArray(PrimitiveInfo *,(number_vertices+2),
+ sizeof(PrimitiveInfo));
+ if (polygon_primitive == (PrimitiveInfo *) NULL)
+ {
+ MagickFreeMemory(path_p);
+ MagickFreeMemory(path_q);
+ return((PrimitiveInfo *) NULL);
+ }
+ (void) memcpy(polygon_primitive,primitive_info,number_vertices*
+ sizeof(PrimitiveInfo));
+ closed_path=
+ (primitive_info[number_vertices-1].point.x == primitive_info[0].point.x) &&
+ (primitive_info[number_vertices-1].point.y == primitive_info[0].point.y);
+ if ((draw_info->linejoin == RoundJoin) ||
+ ((draw_info->linejoin == MiterJoin) && closed_path))
+ {
+ polygon_primitive[number_vertices]=primitive_info[1];
+ number_vertices++;
+ }
+ polygon_primitive[number_vertices].primitive=UndefinedPrimitive;
+ /*
+ Compute the slope for the first line segment, p.
+ */
+ for (n=1; n < number_vertices; n++)
+ {
+ dx.p=polygon_primitive[n].point.x-polygon_primitive[0].point.x;
+ dy.p=polygon_primitive[n].point.y-polygon_primitive[0].point.y;
+ if ((fabs(dx.p) >= MagickEpsilon) || (fabs(dy.p) >= MagickEpsilon))
+ break;
+ }
+ if (n == number_vertices)
+ n=number_vertices-1;
+ slope.p=0.0;
+ inverse_slope.p=0.0;
+ if (fabs(dx.p) <= MagickEpsilon)
+ {
+ if (dx.p >= 0.0)
+ slope.p=dy.p < 0.0 ? -1.0/MagickEpsilon : 1.0/MagickEpsilon;
+ else
+ slope.p=dy.p < 0.0 ? 1.0/MagickEpsilon : -1.0/MagickEpsilon;
+ }
+ else
+ if (fabs(dy.p) <= MagickEpsilon)
+ {
+ if (dy.p >= 0.0)
+ inverse_slope.p=dx.p < 0.0 ? -1.0/MagickEpsilon : 1.0/MagickEpsilon;
+ else
+ inverse_slope.p=dx.p < 0.0 ? 1.0/MagickEpsilon : -1.0/MagickEpsilon;
+ }
+ else
+ {
+ slope.p=dy.p/dx.p;
+ inverse_slope.p=(-1.0/slope.p);
+ }
+ mid=ExpandAffine(&draw_info->affine)*draw_info->stroke_width/2.0;/* FIXME: 'mid' BLOWS UP */
+ miterlimit=draw_info->miterlimit*draw_info->miterlimit*mid*mid;
+ if ((draw_info->linecap == SquareCap) && !closed_path)
+ TraceSquareLinecap(polygon_primitive,number_vertices,mid);
+ offset.x=sqrt(mid*mid/(inverse_slope.p*inverse_slope.p+1.0));
+ offset.y=offset.x*inverse_slope.p;
+ if ((dy.p*offset.x-dx.p*offset.y) > 0.0)
+ {
+ box_p[0].x=polygon_primitive[0].point.x-offset.x;
+ box_p[0].y=polygon_primitive[0].point.y-offset.x*inverse_slope.p;
+ box_p[1].x=polygon_primitive[n].point.x-offset.x;
+ box_p[1].y=polygon_primitive[n].point.y-offset.x*inverse_slope.p;
+ box_q[0].x=polygon_primitive[0].point.x+offset.x;
+ box_q[0].y=polygon_primitive[0].point.y+offset.x*inverse_slope.p;
+ box_q[1].x=polygon_primitive[n].point.x+offset.x;
+ box_q[1].y=polygon_primitive[n].point.y+offset.x*inverse_slope.p;
+ }
+ else
+ {
+ box_p[0].x=polygon_primitive[0].point.x+offset.x;
+ box_p[0].y=polygon_primitive[0].point.y+offset.y;
+ box_p[1].x=polygon_primitive[n].point.x+offset.x;
+ box_p[1].y=polygon_primitive[n].point.y+offset.y;
+ box_q[0].x=polygon_primitive[0].point.x-offset.x;
+ box_q[0].y=polygon_primitive[0].point.y-offset.y;
+ box_q[1].x=polygon_primitive[n].point.x-offset.x;
+ box_q[1].y=polygon_primitive[n].point.y-offset.y;
+ }
+ /*
+ Create strokes for the line join attribute: bevel, miter, round.
+ */
+ p=0;
+ q=0;
+ path_q[p++]=box_q[0];
+ path_p[q++]=box_p[0];
+ for (i=(long) n+1; i < (long) number_vertices; i++)
+ {
+ /*
+ Compute the slope for this line segment, q.
+ */
+ dx.q=polygon_primitive[i].point.x-polygon_primitive[n].point.x;
+ dy.q=polygon_primitive[i].point.y-polygon_primitive[n].point.y;
+ dot_product=dx.q*dx.q+dy.q*dy.q;
+ if (dot_product < 0.25)
+ continue;
+ slope.q=0.0;
+ inverse_slope.q=0.0;
+ if (fabs(dx.q) < MagickEpsilon)
+ {
+ if (dx.q >= 0.0)
+ slope.q=dy.q < 0.0 ? -1.0/MagickEpsilon : 1.0/MagickEpsilon;
+ else
+ slope.q=dy.q < 0.0 ? 1.0/MagickEpsilon : -1.0/MagickEpsilon;
+ }
+ else
+ if (fabs(dy.q) <= MagickEpsilon)
+ {
+ if (dy.q >= 0.0)
+ inverse_slope.q=dx.q < 0.0 ? -1.0/MagickEpsilon : 1.0/MagickEpsilon;
+ else
+ inverse_slope.q=dx.q < 0.0 ? 1.0/MagickEpsilon : -1.0/MagickEpsilon;
+ }
+ else
+ {
+ slope.q=dy.q/dx.q;
+ inverse_slope.q=(-1.0/slope.q);
+ }
+ offset.x=sqrt(mid*mid/(inverse_slope.q*inverse_slope.q+1.0));
+ offset.y=offset.x*inverse_slope.q;
+ dot_product=dy.q*offset.x-dx.q*offset.y;
+ if (dot_product > 0.0)
+ {
+ box_p[2].x=polygon_primitive[n].point.x-offset.x;
+ box_p[2].y=polygon_primitive[n].point.y-offset.y;
+ box_p[3].x=polygon_primitive[i].point.x-offset.x;
+ box_p[3].y=polygon_primitive[i].point.y-offset.y;
+ box_q[2].x=polygon_primitive[n].point.x+offset.x;
+ box_q[2].y=polygon_primitive[n].point.y+offset.y;
+ box_q[3].x=polygon_primitive[i].point.x+offset.x;
+ box_q[3].y=polygon_primitive[i].point.y+offset.y;
+ }
+ else
+ {
+ box_p[2].x=polygon_primitive[n].point.x+offset.x;
+ box_p[2].y=polygon_primitive[n].point.y+offset.y;
+ box_p[3].x=polygon_primitive[i].point.x+offset.x;
+ box_p[3].y=polygon_primitive[i].point.y+offset.y;
+ box_q[2].x=polygon_primitive[n].point.x-offset.x;
+ box_q[2].y=polygon_primitive[n].point.y-offset.y;
+ box_q[3].x=polygon_primitive[i].point.x-offset.x;
+ box_q[3].y=polygon_primitive[i].point.y-offset.y;
+ }
+ if (fabs(slope.p-slope.q) <= MagickEpsilon)
+ {
+ box_p[4]=box_p[1];
+ box_q[4]=box_q[1];
+ }
+ else
+ {
+ box_p[4].x=(slope.p*box_p[0].x-box_p[0].y-slope.q*box_p[3].x+
+ box_p[3].y)/(slope.p-slope.q);
+ box_p[4].y=slope.p*(box_p[4].x-box_p[0].x)+box_p[0].y;
+ box_q[4].x=(slope.p*box_q[0].x-box_q[0].y-slope.q*box_q[3].x+
+ box_q[3].y)/(slope.p-slope.q);
+ box_q[4].y=slope.p*(box_q[4].x-box_q[0].x)+box_q[0].y;
+ }
+ if (q >= (max_strokes-6*BezierQuantum-360))
+ {
+ max_strokes+=6*BezierQuantum+360;
+ MagickReallocMemory(PointInfo *,path_p,MagickArraySize(max_strokes,sizeof(PointInfo)));
+ MagickReallocMemory(PointInfo *,path_q,MagickArraySize(max_strokes,sizeof(PointInfo)));
+ if ((path_p == (PointInfo *) NULL) || (path_q == (PointInfo *) NULL))
+ {
+ MagickFreeMemory(path_p);
+ MagickFreeMemory(path_q);
+ MagickFreeMemory(polygon_primitive);
+ return((PrimitiveInfo *) NULL);
+ }
+ }
+ dot_product=dx.q*dy.p-dx.p*dy.q;
+ if (dot_product <= 0.0)
+ switch (draw_info->linejoin)
+ {
+ case BevelJoin:
+ {
+ path_q[q++]=box_q[1];
+ path_q[q++]=box_q[2];
+ dot_product=(box_q[4].x-box_p[4].x)*(box_q[4].x-box_p[4].x)+
+ (box_q[4].y-box_p[4].y)*(box_q[4].y-box_p[4].y);
+ if (dot_product <= miterlimit)
+ path_p[p++]=box_p[4];
+ else
+ {
+ path_p[p++]=box_p[1];
+ path_p[p++]=box_p[2];
+ }
+ break;
+ }
+ case MiterJoin:
+ {
+ dot_product=(box_q[4].x-box_p[4].x)*(box_q[4].x-box_p[4].x)+
+ (box_q[4].y-box_p[4].y)*(box_q[4].y-box_p[4].y);
+ if (dot_product > miterlimit)
+ {
+ path_q[q++]=box_q[1];
+ path_q[q++]=box_q[2];
+ path_p[p++]=box_p[1];
+ path_p[p++]=box_p[2];
+ }
+ else
+ {
+ path_q[q++]=box_q[4];
+ path_p[p++]=box_p[4];
+ }
+ break;
+ }
+ case RoundJoin:
+ {
+ dot_product=(box_q[4].x-box_p[4].x)*(box_q[4].x-box_p[4].x)+
+ (box_q[4].y-box_p[4].y)*(box_q[4].y-box_p[4].y);
+ if (dot_product <= miterlimit)
+ path_p[p++]=box_p[4];
+ else
+ {
+ path_p[p++]=box_p[1];
+ path_p[p++]=box_p[2];
+ }
+ center=polygon_primitive[n].point;
+ theta.p=atan2(box_q[1].y-center.y,box_q[1].x-center.x);
+ theta.q=atan2(box_q[2].y-center.y,box_q[2].x-center.x);
+ if (theta.q < theta.p)
+ theta.q+=2.0*MagickPI;
+ arc_segments=(long) ceil((theta.q-theta.p)/(2.0*sqrt(1.0/mid)));
+ path_q[q].x=box_q[1].x;
+ path_q[q].y=box_q[1].y;
+ q++;
+ for (j=1; j < arc_segments; j++)
+ {
+ delta_theta=j*(theta.q-theta.p)/arc_segments;
+ path_q[q].x=center.x+mid*
+ cos(fmod(theta.p+delta_theta,DegreesToRadians(360.0)));
+ path_q[q].y=center.y+mid*
+ sin(fmod(theta.p+delta_theta,DegreesToRadians(360.0)));
+ q++;
+ }
+ path_q[q++]=box_q[2];
+ break;
+ }
+ default:
+ break;
+ }
+ else
+ switch (draw_info->linejoin)
+ {
+ case BevelJoin:
+ {
+ path_p[p++]=box_p[1];
+ path_p[p++]=box_p[2];
+ dot_product=(box_q[4].x-box_p[4].x)*(box_q[4].x-box_p[4].x)+
+ (box_q[4].y-box_p[4].y)*(box_q[4].y-box_p[4].y);
+ if (dot_product <= miterlimit)
+ path_q[q++]=box_q[4];
+ else
+ {
+ path_q[q++]=box_q[1];
+ path_q[q++]=box_q[2];
+ }
+ break;
+ }
+ case MiterJoin:
+ {
+ dot_product=(box_q[4].x-box_p[4].x)*(box_q[4].x-box_p[4].x)+
+ (box_q[4].y-box_p[4].y)*(box_q[4].y-box_p[4].y);
+ if (dot_product <= miterlimit)
+ {
+ path_q[q++]=box_q[4];
+ path_p[p++]=box_p[4];
+ }
+ else
+ {
+ path_q[q++]=box_q[1];
+ path_q[q++]=box_q[2];
+ path_p[p++]=box_p[1];
+ path_p[p++]=box_p[2];
+ }
+ break;
+ }
+ case RoundJoin:
+ {
+ dot_product=(box_q[4].x-box_p[4].x)*(box_q[4].x-box_p[4].x)+
+ (box_q[4].y-box_p[4].y)*(box_q[4].y-box_p[4].y);
+ if (dot_product <= miterlimit)
+ path_q[q++]=box_q[4];
+ else
+ {
+ path_q[q++]=box_q[1];
+ path_q[q++]=box_q[2];
+ }
+ center=polygon_primitive[n].point;
+ theta.p=atan2(box_p[1].y-center.y,box_p[1].x-center.x);
+ theta.q=atan2(box_p[2].y-center.y,box_p[2].x-center.x);
+ if (theta.p < theta.q)
+ theta.p+=2.0*MagickPI;
+ arc_segments=(long) ceil((theta.p-theta.q)/(2.0*sqrt(1.0/mid)));
+ path_p[p++]=box_p[1];
+ for (j=1; j < arc_segments; j++)
+ {
+ delta_theta=j*(theta.q-theta.p)/arc_segments;
+ path_p[p].x=center.x+mid*
+ cos(fmod(theta.p+delta_theta,DegreesToRadians(360.0)));
+ path_p[p].y=center.y+mid*
+ sin(fmod(theta.p+delta_theta,DegreesToRadians(360.0)));
+ p++;
+ }
+ path_p[p++]=box_p[2];
+ break;
+ }
+ default:
+ break;
+ }
+ slope.p=slope.q;
+ inverse_slope.p=inverse_slope.q;
+ box_p[0]=box_p[2];
+ box_p[1]=box_p[3];
+ box_q[0]=box_q[2];
+ box_q[1]=box_q[3];
+ dx.p=dx.q;
+ dy.p=dy.q;
+ n=i;
+ }
+ path_p[p++]=box_p[1];
+ path_q[q++]=box_q[1];
+ /*
+ Trace stroked polygon.
+ */
+ stroke_polygon=
+ MagickAllocateArray(PrimitiveInfo *,(p+q+2*closed_path+2),
+ sizeof(PrimitiveInfo));
+ if (stroke_polygon != (PrimitiveInfo *) NULL)
+ {
+ for (i=0; i < (long) p; i++)
+ {
+ stroke_polygon[i]=polygon_primitive[0];
+ stroke_polygon[i].point=path_p[i];
+ }
+ if (closed_path)
+ {
+ stroke_polygon[i]=polygon_primitive[0];
+ stroke_polygon[i].point=stroke_polygon[0].point;
+ i++;
+ }
+ for ( ; i < (long) (p+q+closed_path); i++)
+ {
+ stroke_polygon[i]=polygon_primitive[0];
+ stroke_polygon[i].point=path_q[p+q+closed_path-(i+1)];
+ }
+ if (closed_path)
+ {
+ stroke_polygon[i]=polygon_primitive[0];
+ stroke_polygon[i].point=stroke_polygon[p+closed_path].point;
+ i++;
+ }
+ stroke_polygon[i]=polygon_primitive[0];
+ stroke_polygon[i].point=stroke_polygon[0].point;
+ i++;
+ stroke_polygon[i].primitive=UndefinedPrimitive;
+ stroke_polygon[0].coordinates=p+q+2*closed_path+1;
+ }
+ MagickFreeMemory(path_p);
+ MagickFreeMemory(path_q);
+ MagickFreeMemory(polygon_primitive);
+ return(stroke_polygon);
+}
diff --git a/magick/render.h b/magick/render.h
new file mode 100644
index 0000000..c131029
--- /dev/null
+++ b/magick/render.h
@@ -0,0 +1,363 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Drawing methods.
+*/
+#ifndef _MAGICK_RENDER_H
+#define _MAGICK_RENDER_H
+
+#include "magick/type.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ UndefinedAlign,
+ LeftAlign,
+ CenterAlign,
+ RightAlign
+} AlignType;
+
+typedef enum
+{
+ UserSpace,
+ UserSpaceOnUse,
+ ObjectBoundingBox
+} ClipPathUnits;
+
+typedef enum
+{
+ NoDecoration,
+ UnderlineDecoration,
+ OverlineDecoration,
+ LineThroughDecoration
+} DecorationType;
+
+typedef enum
+{
+ UndefinedRule,
+#undef EvenOddRule
+ EvenOddRule,
+ NonZeroRule
+} FillRule;
+
+typedef enum
+{
+ UndefinedGradient,
+ LinearGradient,
+ RadialGradient
+} GradientType;
+
+typedef enum
+{
+ UndefinedCap,
+ ButtCap,
+ RoundCap,
+ SquareCap
+} LineCap;
+
+typedef enum
+{
+ UndefinedJoin,
+ MiterJoin,
+ RoundJoin,
+ BevelJoin
+} LineJoin;
+
+typedef enum
+{
+ PointMethod = 0,
+ ReplaceMethod,
+ FloodfillMethod,
+ FillToBorderMethod,
+ ResetMethod
+} PaintMethod;
+
+typedef enum
+{
+ UndefinedPrimitive = 0,
+ PointPrimitive,
+ LinePrimitive,
+ RectanglePrimitive,
+ RoundRectanglePrimitive,
+ ArcPrimitive,
+ EllipsePrimitive,
+ CirclePrimitive,
+ PolylinePrimitive,
+ PolygonPrimitive,
+ BezierPrimitive,
+ ColorPrimitive,
+ MattePrimitive,
+ TextPrimitive,
+ ImagePrimitive,
+ PathPrimitive
+} PrimitiveType;
+
+typedef enum
+{
+ UndefinedReference,
+ GradientReference
+} ReferenceType;
+
+typedef enum
+{
+ UndefinedSpread,
+ PadSpread,
+ ReflectSpead,
+ RepeatSpread
+} SpreadMethod;
+
+/*
+ Typedef declarations.
+*/
+typedef struct _GradientInfo
+{
+ GradientType
+ type;
+
+ PixelPacket
+ color;
+
+ SegmentInfo
+ stop;
+
+ unsigned long
+ length;
+
+ SpreadMethod
+ spread;
+
+ unsigned long
+ signature;
+
+ struct _GradientInfo
+ *previous,
+ *next;
+} GradientInfo;
+
+typedef struct _ElementReference
+{
+ char
+ *id;
+
+ ReferenceType
+ type;
+
+ GradientInfo
+ gradient;
+
+ unsigned long
+ signature;
+
+ struct _ElementReference
+ *previous,
+ *next;
+} ElementReference;
+
+typedef struct _DrawInfo
+{
+ char
+ *primitive,
+ *geometry;
+
+ AffineMatrix
+ affine;
+
+ GravityType
+ gravity;
+
+ PixelPacket
+ fill,
+ stroke;
+
+ double
+ stroke_width;
+
+ GradientInfo
+ gradient;
+
+ Image
+ *fill_pattern,
+ *tile,
+ *stroke_pattern;
+
+ unsigned int
+ stroke_antialias,
+ text_antialias;
+
+ FillRule
+ fill_rule;
+
+ LineCap
+ linecap;
+
+ LineJoin
+ linejoin;
+
+ unsigned long
+ miterlimit;
+
+ double
+ dash_offset;
+
+ DecorationType
+ decorate;
+
+ CompositeOperator
+ compose;
+
+ char
+ *text,
+ *font,
+ *family;
+
+ StyleType
+ style;
+
+ StretchType
+ stretch;
+
+ unsigned long
+ weight;
+
+ char
+ *encoding;
+
+ double
+ pointsize;
+
+ char
+ *density;
+
+ AlignType
+ align;
+
+ PixelPacket
+ undercolor,
+ border_color;
+
+ char
+ *server_name;
+
+ double
+ *dash_pattern; /* Terminated by value 0.0 (i.e. < MagickEpsilon)*/
+
+ char
+ *clip_path;
+
+ SegmentInfo
+ bounds;
+
+ ClipPathUnits
+ clip_units;
+
+ Quantum
+ opacity;
+
+ unsigned int
+ render,
+ unused1; /* Spare. Was long-deprecated 'debug' */
+
+ ElementReference
+ element_reference;
+
+ unsigned long
+ signature;
+} DrawInfo;
+
+typedef struct _ElementInfo
+{
+ double
+ cx,
+ cy,
+ major,
+ minor,
+ angle;
+} ElementInfo;
+
+typedef struct _PointInfo
+{
+ double
+ x,
+ y;
+} PointInfo;
+
+typedef struct _PrimitiveInfo
+{
+ PointInfo
+ point;
+
+ unsigned long
+ coordinates;
+
+ PrimitiveType
+ primitive;
+
+ PaintMethod
+ method;
+
+ char
+ *text;
+} PrimitiveInfo;
+
+typedef struct _TypeMetric
+{
+ PointInfo
+ pixels_per_em;
+
+ double
+ ascent,
+ descent,
+ width,
+ height,
+ max_advance;
+
+ SegmentInfo
+ bounds;
+
+ double
+ underline_position,
+ underline_thickness;
+} TypeMetric;
+
+/*
+ Method declarations.
+*/
+extern MagickExport DrawInfo
+ *CloneDrawInfo(const ImageInfo *,const DrawInfo *);
+
+extern MagickExport MagickPassFail
+ AnnotateImage(Image *,const DrawInfo *),
+ DrawAffineImage(Image *,const Image *,const AffineMatrix *),
+ DrawClipPath(Image *,const DrawInfo *,const char *),
+ DrawImage(Image *,const DrawInfo *),
+ DrawPatternPath(Image *,const DrawInfo *,const char *,Image **),
+ GetTypeMetrics(Image *,const DrawInfo *,TypeMetric *);
+
+extern MagickExport void
+ DestroyDrawInfo(DrawInfo *),
+ GetDrawInfo(const ImageInfo *,DrawInfo *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_RENDER_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/resize.c b/magick/resize.c
new file mode 100644
index 0000000..fc7b7e5
--- /dev/null
+++ b/magick/resize.c
@@ -0,0 +1,2072 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% RRRR EEEEE SSSSS IIIII ZZZZZ EEEEE %
+% R R E SS I ZZ E %
+% RRRR EEE SSS I ZZZ EEE %
+% R R E SS I ZZ E %
+% R R EEEEE SSSSS IIIII ZZZZZ EEEEE %
+% %
+% GraphicsMagick Image Resize Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/enum_strings.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/omp_data_view.h"
+#include "magick/pixel_cache.h"
+#include "magick/resize.h"
+#include "magick/utility.h"
+
+/*
+ Typedef declarations.
+*/
+typedef struct _ContributionInfo
+{
+ double
+ weight;
+
+ long
+ pixel;
+} ContributionInfo;
+
+typedef struct _FilterInfo
+{
+ double
+ (*function)(const double,const double),
+ support;
+} FilterInfo;
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ B e s s e l O r d e r O n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% BesselOrderOne() computes the Bessel function of x of the first kind of
+% order 0:
+%
+% Reduce x to |x| since j1(x)= -j1(-x), and for x in (0,8]
+%
+% j1(x) = x*j1(x);
+%
+% For x in (8,inf)
+%
+% j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
+%
+% where x1 = x-3*pi/4. Compute sin(x1) and cos(x1) as follow:
+%
+% cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+% = 1/sqrt(2) * (sin(x) - cos(x))
+% sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+% = -1/sqrt(2) * (sin(x) + cos(x))
+%
+% The format of the BesselOrderOne method is:
+%
+% double BesselOrderOne(double x)
+%
+% A description of each parameter follows:
+%
+% o value: Method BesselOrderOne returns the Bessel function of x of the
+% first kind of orders 1.
+%
+% o x: double value.
+%
+%
+*/
+
+static double J1(double x)
+{
+ double
+ p,
+ q;
+
+ register long
+ i;
+
+ static const double
+ Pone[] =
+ {
+ 0.581199354001606143928050809e+21,
+ -0.6672106568924916298020941484e+20,
+ 0.2316433580634002297931815435e+19,
+ -0.3588817569910106050743641413e+17,
+ 0.2908795263834775409737601689e+15,
+ -0.1322983480332126453125473247e+13,
+ 0.3413234182301700539091292655e+10,
+ -0.4695753530642995859767162166e+7,
+ 0.270112271089232341485679099e+4
+ },
+ Qone[] =
+ {
+ 0.11623987080032122878585294e+22,
+ 0.1185770712190320999837113348e+20,
+ 0.6092061398917521746105196863e+17,
+ 0.2081661221307607351240184229e+15,
+ 0.5243710262167649715406728642e+12,
+ 0.1013863514358673989967045588e+10,
+ 0.1501793594998585505921097578e+7,
+ 0.1606931573481487801970916749e+4,
+ 0.1e+1
+ };
+
+ p=Pone[8];
+ q=Qone[8];
+ for (i=7; i >= 0; i--)
+ {
+ p=p*x*x+Pone[i];
+ q=q*x*x+Qone[i];
+ }
+ return(p/q);
+}
+
+static double P1(double x)
+{
+ double
+ p,
+ q;
+
+ register long
+ i;
+
+ static const double
+ Pone[] =
+ {
+ 0.352246649133679798341724373e+5,
+ 0.62758845247161281269005675e+5,
+ 0.313539631109159574238669888e+5,
+ 0.49854832060594338434500455e+4,
+ 0.2111529182853962382105718e+3,
+ 0.12571716929145341558495e+1
+ },
+ Qone[] =
+ {
+ 0.352246649133679798068390431e+5,
+ 0.626943469593560511888833731e+5,
+ 0.312404063819041039923015703e+5,
+ 0.4930396490181088979386097e+4,
+ 0.2030775189134759322293574e+3,
+ 0.1e+1
+ };
+
+ p=Pone[5];
+ q=Qone[5];
+ for (i=4; i >= 0; i--)
+ {
+ p=p*(8.0/x)*(8.0/x)+Pone[i];
+ q=q*(8.0/x)*(8.0/x)+Qone[i];
+ }
+ return(p/q);
+}
+
+static double Q1(double x)
+{
+ double
+ p,
+ q;
+
+ register long
+ i;
+
+ static const double
+ Pone[] =
+ {
+ 0.3511751914303552822533318e+3,
+ 0.7210391804904475039280863e+3,
+ 0.4259873011654442389886993e+3,
+ 0.831898957673850827325226e+2,
+ 0.45681716295512267064405e+1,
+ 0.3532840052740123642735e-1
+ },
+ Qone[] =
+ {
+ 0.74917374171809127714519505e+4,
+ 0.154141773392650970499848051e+5,
+ 0.91522317015169922705904727e+4,
+ 0.18111867005523513506724158e+4,
+ 0.1038187585462133728776636e+3,
+ 0.1e+1
+ };
+
+ p=Pone[5];
+ q=Qone[5];
+ for (i=4; i >= 0; i--)
+ {
+ p=p*(8.0/x)*(8.0/x)+Pone[i];
+ q=q*(8.0/x)*(8.0/x)+Qone[i];
+ }
+ return(p/q);
+}
+
+static double BesselOrderOne(double x)
+{
+ double
+ p,
+ q;
+
+ if (x == 0.0)
+ return(0.0);
+ p=x;
+ if (x < 0.0)
+ x=(-x);
+ if (x < 8.0)
+ return(p*J1(x));
+ q=sqrt(2.0/(MagickPI*x))*(P1(x)*(1.0/sqrt(2.0)*(sin(x)-cos(x)))-8.0/x*Q1(x)*
+ (-1.0/sqrt(2.0)*(sin(x)+cos(x))));
+ if (p < 0.0)
+ q=(-q);
+ return(q);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g n i f y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagnifyImage() is a convenience method that scales an image proportionally
+% to twice its size.
+%
+% The format of the MagnifyImage method is:
+%
+% Image *MagnifyImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *MagnifyImage(const Image *image,ExceptionInfo *exception)
+{
+#define MagnifyImageText "[%s] Magnify... "
+
+ Image
+ *magnify_image;
+
+ long
+ rows,
+ y;
+
+ PixelPacket
+ *scanline;
+
+ register long
+ x;
+
+ register PixelPacket
+ *p,
+ *q,
+ *r;
+
+ /*
+ Initialize magnify image attributes.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ magnify_image=CloneImage(image,2*image->columns,2*image->rows,True,exception);
+ if (magnify_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Magnifying image of size %lux%lu to %lux%lu",
+ image->columns,image->rows,magnify_image->columns,magnify_image->rows);
+
+ magnify_image->storage_class=DirectClass;
+ /*
+ Allocate image buffer and scanline buffer for 4 rows of the image.
+ */
+ scanline=MagickAllocateArray(PixelPacket *,
+ magnify_image->columns,sizeof(PixelPacket));
+ if (scanline == (PixelPacket *) NULL)
+ {
+ DestroyImage(magnify_image);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToMagnifyImage)
+ }
+ /*
+ Initialize magnify image pixels.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ const PixelPacket
+ *pixels;
+
+ pixels=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ q=SetImagePixels(magnify_image,0,y,magnify_image->columns,1);
+ if ((pixels == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ break;
+ (void) memcpy(q,pixels,image->columns*sizeof(PixelPacket));
+ if (!SyncImagePixels(magnify_image))
+ break;
+ }
+ /*
+ Magnify each row.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=GetImagePixels(magnify_image,0,(long) (image->rows-y-1),
+ magnify_image->columns,1);
+ if (p == (PixelPacket *) NULL)
+ break;
+ (void) memcpy(scanline,p,magnify_image->columns*sizeof(PixelPacket));
+ q=GetImagePixels(magnify_image,0,(long) (2*(image->rows-y-1)),
+ magnify_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ p=scanline+image->columns-1;
+ q+=2*(image->columns-1);
+ *q=(*p);
+ *(q+1)=(*(p));
+ for (x=1; x < (long) image->columns; x++)
+ {
+ p--;
+ q-=2;
+ *q=(*p);
+ (q+1)->red=(Quantum) (((double) p->red+(double) (p+1)->red)/2.0+0.5);
+ (q+1)->green=(Quantum) (((double) p->green+(double) (p+1)->green)/2.0+0.5);
+ (q+1)->blue=(Quantum) (((double) p->blue+(double) (p+1)->blue)/2.0+0.5);
+ (q+1)->opacity=(Quantum)
+ (((double) p->opacity+(double) (p+1)->opacity)/2.0+0.5);
+ }
+ if (!SyncImagePixels(magnify_image))
+ break;
+ }
+
+ for (y=0; y < (long) image->rows; y++)
+ {
+ rows=(long) Min(image->rows-y,3);
+ p=GetImagePixels(magnify_image,0,2*y,magnify_image->columns,rows);
+ if (p == (PixelPacket *) NULL)
+ break;
+ q=p;
+ if (rows > 1)
+ q=p+magnify_image->columns;
+ r=p;
+ if (rows > 2)
+ r=q+magnify_image->columns;
+ for (x=0; x < (long) (image->columns-1); x++)
+ {
+ q->red=(Quantum) (((double) p->red+(double) r->red)/2.0+0.5);
+ q->green=(Quantum) (((double) p->green+(double) r->green)/2.0+0.5);
+ q->blue=(Quantum) (((double) p->blue+(double) r->blue)/2.0+0.5);
+ q->opacity=(Quantum) (((double) p->opacity+(double) r->opacity)/2.0+0.5);
+ (q+1)->red=(Quantum) (((double) p->red+(double) (p+2)->red+
+ (double) r->red+(double) (r+2)->red)/4.0+0.5);
+ (q+1)->green=(Quantum) (((double) p->green+(double) (p+2)->green+
+ (double) r->green+(double) (r+2)->green)/4.0+0.5);
+ (q+1)->blue=(Quantum) (((double) p->blue+(double) (p+2)->blue+
+ (double) r->blue+(double) (r+2)->blue)/4.0+0.5);
+ (q+1)->opacity=(Quantum) (((double) p->opacity+(double) (p+2)->opacity+
+ (double) r->opacity+(double) (r+2)->opacity)/4.0+0.5);
+ q+=2;
+ p+=2;
+ r+=2;
+ }
+ q->red=(Quantum) (((double) p->red+(double) r->red)/2.0+0.5);
+ q->green=(Quantum) (((double) p->green+(double) r->green)/2.0+0.5);
+ q->blue=(Quantum) (((double) p->blue+(double) r->blue)/2.0+0.5);
+ q->opacity=(Quantum) (((double) p->opacity+(double) r->opacity)/2.0+0.5);
+ p++;
+ q++;
+ r++;
+ q->red=(Quantum) (((double) p->red+(double) r->red)/2.0+0.5);
+ q->green=(Quantum) (((double) p->green+(double) r->green)/2.0+0.5);
+ q->blue=(Quantum) (((double) p->blue+(double) r->blue)/2.0+0.5);
+ q->opacity=(Quantum) (((double) p->opacity+(double) r->opacity)/2.0+0.5);
+ if (!SyncImagePixels(magnify_image))
+ break;
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,exception,
+ MagnifyImageText,image->filename))
+ break;
+ }
+ p=GetImagePixels(magnify_image,0,(long) (2*image->rows-2),
+ magnify_image->columns,1);
+ if (p != (PixelPacket *) NULL)
+ (void) memcpy(scanline,p,magnify_image->columns*sizeof(PixelPacket));
+ q=GetImagePixels(magnify_image,0,(long) (2*image->rows-1),
+ magnify_image->columns,1);
+ if (q != (PixelPacket *) NULL)
+ (void) memcpy(q,scanline,magnify_image->columns*sizeof(PixelPacket));
+ (void) SyncImagePixels(magnify_image);
+ MagickFreeMemory(scanline);
+ magnify_image->is_grayscale=image->is_grayscale;
+ return(magnify_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M i n i f y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MinifyImage() is a convenience method that scales an image proportionally
+% to half its size.
+%
+% The format of the MinifyImage method is:
+%
+% Image *MinifyImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *MinifyImage(const Image *image,ExceptionInfo *exception)
+{
+#define Minify(weight) \
+ total.red+=(weight)*(r->red); \
+ total.green+=(weight)*(r->green); \
+ total.blue+=(weight)*(r->blue); \
+ total.opacity+=(weight)*(r->opacity); \
+ r++;
+#define MinifyImageText "[%s] Minify..."
+
+ Image
+ *minify_image;
+
+ long
+ y;
+
+ /*
+ Initialize minified image.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ minify_image=CloneImage(image,Max(image->columns/2,1),Max(image->rows/2,1),
+ True,exception);
+ if (minify_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Minifying image of size %lux%lu to %lux%lu",
+ image->columns,image->rows,
+ minify_image->columns,minify_image->rows);
+
+ minify_image->storage_class=DirectClass;
+ /*
+ Reduce each row.
+ */
+ {
+ unsigned long
+ row_count=0;
+
+ DoublePixelPacket
+ zero;
+
+ MagickPassFail
+ status=MagickPass;
+
+ (void) memset(&zero,0,sizeof(DoublePixelPacket));
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(guided) shared(row_count, status)
+# endif
+# endif
+#endif
+ for (y=0; y < (long) minify_image->rows; y++)
+ {
+ DoublePixelPacket
+ total;
+
+ register const PixelPacket
+ *p,
+ *r;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_MinifyImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,-2,2*(y-1),image->columns+4,4,exception);
+ q=SetImagePixelsEx(minify_image,0,y,minify_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ for (x=0; x < (long) minify_image->columns; x++)
+ {
+ /*
+ Compute weighted average of target pixel color components.
+ */
+ total=zero;
+ r=p;
+ Minify(3.0); Minify(7.0); Minify(7.0); Minify(3.0);
+ r=p+(image->columns+4);
+ Minify(7.0); Minify(15.0); Minify(15.0); Minify(7.0);
+ r=p+2*(image->columns+4);
+ Minify(7.0); Minify(15.0); Minify(15.0); Minify(7.0);
+ r=p+3*(image->columns+4);
+ Minify(3.0); Minify(7.0); Minify(7.0); Minify(3.0);
+ q->red=(Quantum) (total.red/128.0+0.5);
+ q->green=(Quantum) (total.green/128.0+0.5);
+ q->blue=(Quantum) (total.blue/128.0+0.5);
+ q->opacity=(Quantum) (total.opacity/128.0+0.5);
+ p+=2;
+ q++;
+ }
+ if (!SyncImagePixelsEx(minify_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_MinifyImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ MinifyImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ minify_image->is_grayscale=image->is_grayscale;
+ return(minify_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e s i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ResizeImage() scales an image to the desired dimensions with one of these
+% filters:
+%
+% Bessel Blackman Box
+% Catrom Cubic Gaussian
+% Hanning Hermite Lanczos
+% Mitchell Point Quandratic
+% Sinc Triangle
+%
+% Most of the filters are FIR (finite impulse response), however, Bessel,
+% Gaussian, and Sinc are IIR (infinite impulse response). Bessel and Sinc
+% are windowed (brought down to zero) with the Blackman filter.
+%
+% ResizeImage() was inspired by Paul Heckbert's zoom program.
+%
+% The format of the ResizeImage method is:
+%
+% Image *ResizeImage(Image *image,const unsigned long columns,
+% const unsigned long rows,const FilterTypes filter,const double blur,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o columns: The number of columns in the scaled image.
+%
+% o rows: The number of rows in the scaled image.
+%
+% o filter: Image filter to use.
+%
+% o blur: The blur factor where > 1 is blurry, < 1 is sharp.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+static double Bessel(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ if (x == 0.0)
+ return(MagickPI/4.0);
+ return(BesselOrderOne(MagickPI*x)/(2.0*x));
+}
+
+static double Sinc(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ if (x == 0.0)
+ return(1.0);
+ return(sin(MagickPI*x)/(MagickPI*x));
+}
+
+static double Blackman(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ return(0.42+0.5*cos(MagickPI*x)+0.08*cos(2*MagickPI*x));
+}
+
+static double BlackmanBessel(const double x,const double support)
+{
+ return(Blackman(x/support,support)*Bessel(x,support));
+}
+
+static double BlackmanSinc(const double x,const double support)
+{
+ return(Blackman(x/support,support)*Sinc(x,support));
+}
+
+static double Box(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ if (x < -0.5)
+ return(0.0);
+ if (x < 0.5)
+ return(1.0);
+ return(0.0);
+}
+
+static double Catrom(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ if (x < -2.0)
+ return(0.0);
+ if (x < -1.0)
+ return(0.5*(4.0+x*(8.0+x*(5.0+x))));
+ if (x < 0.0)
+ return(0.5*(2.0+x*x*(-5.0-3.0*x)));
+ if (x < 1.0)
+ return(0.5*(2.0+x*x*(-5.0+3.0*x)));
+ if (x < 2.0)
+ return(0.5*(4.0+x*(-8.0+x*(5.0-x))));
+ return(0.0);
+}
+
+static double Cubic(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ if (x < -2.0)
+ return(0.0);
+ if (x < -1.0)
+ return((2.0+x)*(2.0+x)*(2.0+x)/6.0);
+ if (x < 0.0)
+ return((4.0+x*x*(-6.0-3.0*x))/6.0);
+ if (x < 1.0)
+ return((4.0+x*x*(-6.0+3.0*x))/6.0);
+ if (x < 2.0)
+ return((2.0-x)*(2.0-x)*(2.0-x)/6.0);
+ return(0.0);
+}
+
+static double Gaussian(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ return(exp(-2.0*x*x)*sqrt(2.0/MagickPI));
+}
+
+static double Hanning(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ return(0.5+0.5*cos(MagickPI*x));
+}
+
+static double Hamming(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ return(0.54+0.46*cos(MagickPI*x));
+}
+
+static double Hermite(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ if (x < -1.0)
+ return(0.0);
+ if (x < 0.0)
+ return((2.0*(-x)-3.0)*(-x)*(-x)+1.0);
+ if (x < 1.0)
+ return((2.0*x-3.0)*x*x+1.0);
+ return(0.0);
+}
+
+static double Lanczos(const double x,const double support)
+{
+ if (x < -3.0)
+ return(0.0);
+ if (x < 0.0)
+ return(Sinc(-x,support)*Sinc(-x/3.0,support));
+ if (x < 3.0)
+ return(Sinc(x,support)*Sinc(x/3.0,support));
+ return(0.0);
+}
+
+static double Mitchell(const double x,const double support)
+{
+#define B (1.0/3.0)
+#define C (1.0/3.0)
+#define P0 (( 6.0- 2.0*B )/6.0)
+#define P2 ((-18.0+12.0*B+ 6.0*C)/6.0)
+#define P3 (( 12.0- 9.0*B- 6.0*C)/6.0)
+#define Q0 (( 8.0*B+24.0*C)/6.0)
+#define Q1 (( -12.0*B-48.0*C)/6.0)
+#define Q2 (( 6.0*B+30.0*C)/6.0)
+#define Q3 (( - 1.0*B- 6.0*C)/6.0)
+
+ ARG_NOT_USED(support);
+ if (x < -2.0)
+ return(0.0);
+ if (x < -1.0)
+ return(Q0-x*(Q1-x*(Q2-x*Q3)));
+ if (x < 0.0)
+ return(P0+x*x*(P2-x*P3));
+ if (x < 1.0)
+ return(P0+x*x*(P2+x*P3));
+ if (x < 2.0)
+ return(Q0+x*(Q1+x*(Q2+x*Q3)));
+ return(0.0);
+}
+
+static double Quadratic(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ if (x < -1.5)
+ return(0.0);
+ if (x < -0.5)
+ return(0.5*(x+1.5)*(x+1.5));
+ if (x < 0.5)
+ return(0.75-x*x);
+ if (x < 1.5)
+ return(0.5*(x-1.5)*(x-1.5));
+ return(0.0);
+}
+
+static double Triangle(const double x,const double support)
+{
+ ARG_NOT_USED(support);
+ if (x < -1.0)
+ return(0.0);
+ if (x < 0.0)
+ return(1.0+x);
+ if (x < 1.0)
+ return(1.0-x);
+ return(0.0);
+}
+
+static MagickPassFail
+HorizontalFilter(const Image *source,Image *destination,
+ const double x_factor,const FilterInfo *filter_info,
+ const double blur,ThreadViewDataSet *view_data_set,
+ const size_t span,unsigned long *quantum,
+ ExceptionInfo *exception)
+{
+#define ResizeImageText "[%s] Resize..."
+
+ double
+ scale,
+ support;
+
+ DoublePixelPacket
+ zero;
+
+ long
+ x;
+
+ MagickPassFail
+ status=MagickPass;
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Enter HorizontalFilter() ...");
+
+ scale=blur*Max(1.0/x_factor,1.0);
+ support=scale*filter_info->support;
+ destination->storage_class=source->storage_class;
+ if (support > 0.5)
+ destination->storage_class=DirectClass;
+ else
+ {
+ /*
+ Reduce to point sampling.
+ */
+ support=0.5+MagickEpsilon;
+ scale=1.0;
+ }
+ scale=1.0/scale;
+ (void) memset(&zero,0,sizeof(DoublePixelPacket));
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(status)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static) shared(status)
+# else
+# pragma omp parallel for schedule(guided) shared(status)
+# endif
+# endif
+#endif
+ for (x=0; x < (long) destination->columns; x++)
+ {
+ double
+ center,
+ density;
+
+ ContributionInfo
+ *contribution;
+
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q = (PixelPacket *) NULL;
+
+ const IndexPacket
+ *source_indexes;
+
+ IndexPacket
+ *indexes;
+
+ long
+ n,
+ start,
+ stop,
+ y;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_HorizontalFilter)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ contribution=AccessThreadViewData(view_data_set);
+ /* fprintf(stderr,"Thread %d contribution %p\n",omp_get_thread_num(),contribution); */
+ center=(double) (x+0.5)/x_factor;
+ start=(long) Max(center-support+0.5,0);
+ stop=(long) Min(center+support+0.5,source->columns);
+ density=0.0;
+ for (n=0; n < (stop-start); n++)
+ {
+ contribution[n].pixel=start+n;
+ contribution[n].weight=
+ filter_info->function(scale*(start+n-center+0.5),filter_info->support);
+ density+=contribution[n].weight;
+ }
+ if ((density != 0.0) && (density != 1.0))
+ {
+ /*
+ Normalize.
+ */
+ long
+ i;
+
+ density=1.0/density;
+ for (i=0; i < n; i++)
+ contribution[i].weight*=density;
+ }
+
+ p=AcquireImagePixels(source,contribution[0].pixel,0,
+ contribution[n-1].pixel-contribution[0].pixel+1,
+ source->rows,exception);
+ if (p == (const PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ q=SetImagePixelsEx(destination,x,0,1,destination->rows,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ source_indexes=AccessImmutableIndexes(source);
+ indexes=AccessMutableIndexes(destination);
+ for (y=0; y < (long) destination->rows; y++)
+ {
+ double
+ weight;
+
+ DoublePixelPacket
+ pixel;
+
+ long
+ j;
+
+ register long
+ i;
+
+ pixel=zero;
+ if ((destination->matte) || (destination->colorspace == CMYKColorspace))
+ {
+ double
+ transparency_coeff,
+ normalize;
+
+ normalize=0.0;
+ for (i=0; i < n; i++)
+ {
+ j=y*(contribution[n-1].pixel-contribution[0].pixel+1)+
+ (contribution[i].pixel-contribution[0].pixel);
+ weight=contribution[i].weight;
+ transparency_coeff = weight * (1 - ((double) p[j].opacity/TransparentOpacity));
+ pixel.red+=transparency_coeff*p[j].red;
+ pixel.green+=transparency_coeff*p[j].green;
+ pixel.blue+=transparency_coeff*p[j].blue;
+ pixel.opacity+=weight*p[j].opacity;
+ normalize += transparency_coeff;
+ }
+ normalize = 1.0 / (AbsoluteValue(normalize) <= MagickEpsilon ? 1.0 : normalize);
+ pixel.red *= normalize;
+ pixel.green *= normalize;
+ pixel.blue *= normalize;
+ q[y].red=RoundDoubleToQuantum(pixel.red);
+ q[y].green=RoundDoubleToQuantum(pixel.green);
+ q[y].blue=RoundDoubleToQuantum(pixel.blue);
+ q[y].opacity=RoundDoubleToQuantum(pixel.opacity);
+ }
+ else
+ {
+ for (i=0; i < n; i++)
+ {
+ j=(long) (y*(contribution[n-1].pixel-contribution[0].pixel+1)+
+ (contribution[i].pixel-contribution[0].pixel));
+ weight=contribution[i].weight;
+ pixel.red+=weight*p[j].red;
+ pixel.green+=weight*p[j].green;
+ pixel.blue+=weight*p[j].blue;
+ }
+ q[y].red=RoundDoubleToQuantum(pixel.red);
+ q[y].green=RoundDoubleToQuantum(pixel.green);
+ q[y].blue=RoundDoubleToQuantum(pixel.blue);
+ q[y].opacity=OpaqueOpacity;
+ }
+
+ if ((indexes != (IndexPacket *) NULL) &&
+ (source_indexes != (IndexPacket *) NULL))
+ {
+ i=Min(Max((long) (center+0.5),start),stop-1);
+ j=y*(contribution[n-1].pixel-contribution[0].pixel+1)+
+ (contribution[i-start].pixel-contribution[0].pixel);
+ indexes[y]=source_indexes[j];
+ }
+ }
+ if (!SyncImagePixelsEx(destination,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_HorizontalFilter)
+#endif
+ {
+ if (QuantumTick(*quantum,span))
+ if (!MagickMonitorFormatted(*quantum,span,exception,
+ ResizeImageText,source->filename))
+ thread_status=MagickFail;
+
+ (*quantum)++;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "%s exit HorizontalFilter()",
+ (status == MagickFail ? "Error" : "Normal"));
+
+ return (status);
+}
+
+static MagickPassFail
+VerticalFilter(const Image *source,Image *destination,
+ const double y_factor,const FilterInfo *filter_info,
+ const double blur,ThreadViewDataSet *view_data_set,
+ const size_t span,unsigned long *quantum,
+ ExceptionInfo *exception)
+{
+ double
+ scale,
+ support;
+
+ DoublePixelPacket
+ zero;
+
+ long
+ y;
+
+ MagickPassFail
+ status=MagickPass;
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Enter VerticalFilter() ...");
+
+ /*
+ Apply filter to resize vertically from source to destination.
+ */
+ scale=blur*Max(1.0/y_factor,1.0);
+ support=scale*filter_info->support;
+ destination->storage_class=source->storage_class;
+ if (support > 0.5)
+ destination->storage_class=DirectClass;
+ else
+ {
+ /*
+ Reduce to point sampling.
+ */
+ support=0.5+MagickEpsilon;
+ scale=1.0;
+ }
+ scale=1.0/scale;
+ (void) memset(&zero,0,sizeof(DoublePixelPacket));
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(status)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static) shared(status)
+# else
+# pragma omp parallel for schedule(guided) shared(status)
+# endif
+# endif
+#endif
+ for (y=0; y < (long) destination->rows; y++)
+ {
+ double
+ center,
+ density;
+
+ ContributionInfo
+ *contribution;
+
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q = (PixelPacket *) NULL;
+
+ const IndexPacket
+ *source_indexes;
+
+ IndexPacket
+ *indexes;
+
+ long
+ n,
+ start,
+ stop,
+ x;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_VerticalFilter)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ contribution=AccessThreadViewData(view_data_set);
+ center=(double) (y+0.5)/y_factor;
+ start=(long) Max(center-support+0.5,0);
+ stop=(long) Min(center+support+0.5,source->rows);
+ density=0.0;
+ for (n=0; n < (stop-start); n++)
+ {
+ contribution[n].pixel=start+n;
+ contribution[n].weight=
+ filter_info->function(scale*(start+n-center+0.5),filter_info->support);
+ density+=contribution[n].weight;
+ }
+ if ((density != 0.0) && (density != 1.0))
+ {
+ /*
+ Normalize.
+ */
+ long
+ i;
+
+ density=1.0/density;
+ for (i=0; i < n; i++)
+ contribution[i].weight*=density;
+ }
+
+ p=AcquireImagePixels(source,0,contribution[0].pixel,source->columns,
+ contribution[n-1].pixel-contribution[0].pixel+1,
+ exception);
+ if (p == (const PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ q=SetImagePixelsEx(destination,0,y,destination->columns,1,exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ source_indexes=AccessImmutableIndexes(source);
+ indexes=AccessMutableIndexes(destination);
+ for (x=0; x < (long) destination->columns; x++)
+ {
+ double
+ weight;
+
+ DoublePixelPacket
+ pixel;
+
+ long
+ j;
+
+ register long
+ i;
+
+ pixel=zero;
+ if ((source->matte) || (source->colorspace == CMYKColorspace))
+ {
+ double
+ transparency_coeff,
+ normalize;
+
+ normalize=0.0;
+ for (i=0; i < n; i++)
+ {
+ j=(long) ((contribution[i].pixel-contribution[0].pixel)*
+ source->columns+x);
+ weight=contribution[i].weight;
+ transparency_coeff = weight * (1 - ((double) p[j].opacity/TransparentOpacity));
+ pixel.red+=transparency_coeff*p[j].red;
+ pixel.green+=transparency_coeff*p[j].green;
+ pixel.blue+=transparency_coeff*p[j].blue;
+ pixel.opacity+=weight*p[j].opacity;
+ normalize += transparency_coeff;
+ }
+
+ normalize = 1.0 / (AbsoluteValue(normalize) <= MagickEpsilon ? 1.0 : normalize);
+ pixel.red *= normalize;
+ pixel.green *= normalize;
+ pixel.blue *= normalize;
+ q[x].red=RoundDoubleToQuantum(pixel.red);
+ q[x].green=RoundDoubleToQuantum(pixel.green);
+ q[x].blue=RoundDoubleToQuantum(pixel.blue);
+ q[x].opacity=RoundDoubleToQuantum(pixel.opacity);
+ }
+ else
+ {
+ for (i=0; i < n; i++)
+ {
+ j=(long) ((contribution[i].pixel-contribution[0].pixel)*
+ source->columns+x);
+ weight=contribution[i].weight;
+ pixel.red+=weight*p[j].red;
+ pixel.green+=weight*p[j].green;
+ pixel.blue+=weight*p[j].blue;
+ }
+ q[x].red=RoundDoubleToQuantum(pixel.red);
+ q[x].green=RoundDoubleToQuantum(pixel.green);
+ q[x].blue=RoundDoubleToQuantum(pixel.blue);
+ q[x].opacity=OpaqueOpacity;
+ }
+
+ if ((indexes != (IndexPacket *) NULL) &&
+ (source_indexes != (IndexPacket *) NULL))
+ {
+ i=Min(Max((long) (center+0.5),start),stop-1);
+ j=(long) ((contribution[i-start].pixel-contribution[0].pixel)*
+ source->columns+x);
+ indexes[x]=source_indexes[j];
+ }
+ }
+ if (!SyncImagePixelsEx(destination,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_VerticalFilter)
+#endif
+ {
+ if (QuantumTick(*quantum,span))
+ if (!MagickMonitorFormatted(*quantum,span,exception,
+ ResizeImageText,source->filename))
+ thread_status=MagickFail;
+
+ (*quantum)++;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "%s exit VerticalFilter()",
+ (status == MagickFail ? "Error" : "Normal"));
+
+ return (status);
+}
+
+MagickExport Image *ResizeImage(const Image *image,const unsigned long columns,
+ const unsigned long rows,const FilterTypes filter,
+ const double blur,
+ ExceptionInfo *exception)
+{
+ ThreadViewDataSet
+ *view_data_set;
+
+ double
+ support,
+ x_factor,
+ x_support,
+ y_factor,
+ y_support;
+
+ Image
+ *source_image,
+ *resize_image;
+
+ register long
+ i;
+
+ static const FilterInfo
+ filters[SincFilter+1] =
+ {
+ { Box, 0.0 },
+ { Box, 0.0 },
+ { Box, 0.5 },
+ { Triangle, 1.0 },
+ { Hermite, 1.0 },
+ { Hanning, 1.0 },
+ { Hamming, 1.0 },
+ { Blackman, 1.0 },
+ { Gaussian, 1.25 },
+ { Quadratic, 1.5 },
+ { Cubic, 2.0 },
+ { Catrom, 2.0 },
+ { Mitchell, 2.0 },
+ { Lanczos, 3.0 },
+ { BlackmanBessel, 3.2383 },
+ { BlackmanSinc, 4.0 }
+ };
+
+ size_t
+ span;
+
+ MagickPassFail
+ status;
+
+ unsigned long
+ quantum;
+
+ MagickBool
+ order;
+
+ /*
+ Initialize resize image attributes.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ assert(((int) filter >= 0) && ((int) filter <= SincFilter));
+
+ if ((image->columns == 0UL) || (image->rows == 0UL) ||
+ (columns == 0UL) || (rows == 0UL))
+ ThrowImageException(ImageError,UnableToResizeImage,
+ MagickMsg(OptionError,NonzeroWidthAndHeightRequired));
+
+ if ((columns == image->columns) && (rows == image->rows) && (blur == 1.0))
+ return (CloneImage(image,0,0,True,exception));
+
+ resize_image=CloneImage(image,columns,rows,True,exception);
+ if (resize_image == (Image *) NULL)
+ return ((Image *) NULL);
+
+ order=(((double) columns*(image->rows+rows)) >
+ ((double) rows*(image->columns+columns)));
+ if (order)
+ source_image=CloneImage(resize_image,columns,image->rows,True,exception);
+ else
+ source_image=CloneImage(resize_image,image->columns,rows,True,exception);
+ if (source_image == (Image *) NULL)
+ return ((Image *) NULL);
+
+ /*
+ Allocate filter contribution info.
+ */
+ x_factor=(double) resize_image->columns/image->columns;
+ y_factor=(double) resize_image->rows/image->rows;
+ i=(long) DefaultResizeFilter;
+ if (filter != UndefinedFilter)
+ i=(long) filter;
+ else
+ if ((image->storage_class == PseudoClass) || image->matte ||
+ ((x_factor*y_factor) > 1.0))
+ i=(long) MitchellFilter;
+
+ if (IsEventLogging())
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Resizing image of size %lux%lu to %lux%lu using %s filter",
+ image->columns,image->rows,columns,rows,
+ ResizeFilterToString((FilterTypes)i));
+
+ x_support=blur*Max(1.0/x_factor,1.0)*filters[i].support;
+ y_support=blur*Max(1.0/y_factor,1.0)*filters[i].support;
+ support=Max(x_support,y_support);
+ if (support < filters[i].support)
+ support=filters[i].support;
+ /*
+ Allocate view data set.
+ */
+ view_data_set=AllocateThreadViewDataArray(image,exception,
+ (size_t) (2.0*Max(support,0.5)+3),
+ sizeof(ContributionInfo));
+ if (view_data_set == (ThreadViewDataSet *) NULL)
+ {
+ DestroyImage(resize_image);
+ DestroyImage(source_image);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToResizeImage);
+ }
+ /*
+ Resize image.
+ */
+ status=MagickPass;
+ quantum=0;
+ if (order)
+ {
+ span=source_image->columns+resize_image->rows;
+ status=HorizontalFilter(image,source_image,x_factor,&filters[i],blur,
+ view_data_set,span,&quantum,exception);
+ if (status != MagickFail)
+ status=VerticalFilter(source_image,resize_image,y_factor,&filters[i],
+ blur,view_data_set,span,&quantum,exception);
+ }
+ else
+ {
+ span=resize_image->columns+source_image->rows;
+ status=VerticalFilter(image,source_image,y_factor,&filters[i],blur,
+ view_data_set,span,&quantum,exception);
+ if (status != MagickFail)
+ status=HorizontalFilter(source_image,resize_image,x_factor,&filters[i],
+ blur,view_data_set,span,&quantum,exception);
+ }
+ /*
+ Free allocated memory.
+ */
+ DestroyThreadViewDataSet(view_data_set);
+ DestroyImage(source_image);
+ if (status == MagickFail)
+ {
+ DestroyImage(resize_image);
+ return((Image *) NULL);
+ }
+ resize_image->is_grayscale=image->is_grayscale;
+ return(resize_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S a m p l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SampleImage() scales an image to the desired dimensions with pixel
+% sampling. Unlike other scaling methods, this method does not introduce
+% any additional color into the scaled image.
+%
+% The format of the SampleImage method is:
+%
+% Image *SampleImage(const Image *image,const unsigned long columns,
+% const unsigned long rows,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o columns: The number of columns in the sampled image.
+%
+% o rows: The number of rows in the sampled image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *
+SampleImage(const Image *image,const unsigned long columns,
+ const unsigned long rows,ExceptionInfo *exception)
+{
+ double
+ *x_offset,
+ *y_offset;
+
+ Image
+ *sample_image;
+
+ long
+ j,
+ y;
+
+ PixelPacket
+ *pixels;
+
+ /*
+ Initialize sampled image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if ((columns == 0) || (rows == 0))
+ ThrowImageException(ImageError,UnableToResizeImage,
+ MagickMsg(CorruptImageError,
+ NegativeOrZeroImageSize));
+ if ((columns == image->columns) && (rows == image->rows))
+ return(CloneImage(image,0,0,True,exception));
+ sample_image=CloneImage(image,columns,rows,True,exception);
+ if (sample_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Sampling image of size %lux%lu to %lux%lu",
+ image->columns,image->rows,sample_image->columns,
+ sample_image->rows);
+ /*
+ Allocate scan line buffer and column offset buffers.
+ */
+ pixels=MagickAllocateArray(PixelPacket *,image->columns,sizeof(PixelPacket));
+ x_offset=MagickAllocateArray(double *,sample_image->columns,sizeof(double));
+ y_offset=MagickAllocateArray(double *,sample_image->rows,sizeof(double));
+ if ((pixels == (PixelPacket *) NULL) ||
+ (x_offset == (double *) NULL) ||
+ (y_offset == (double *) NULL))
+ {
+ MagickFreeMemory(y_offset);
+ MagickFreeMemory(x_offset);
+ MagickFreeMemory(pixels);
+ DestroyImage(sample_image);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToSampleImage);
+ }
+ /*
+ Initialize pixel offsets.
+ */
+ {
+ long
+ x;
+
+ for (x=0; x < (long) sample_image->columns; x++)
+ x_offset[x]=(double) x*image->columns/(double) sample_image->columns;
+ for (y=0; y < (long) sample_image->rows; y++)
+ y_offset[y]=(double) y*image->rows/(double) sample_image->rows;
+ }
+ /*
+ Sample each row.
+ This algorithm will not benefit from OpenMP.
+ */
+ j=(-1);
+ for (y=0; y < (long) sample_image->rows; y++)
+ {
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q;
+
+ register const IndexPacket
+ *indexes;
+
+ register IndexPacket
+ *sample_indexes;
+
+ register long
+ x;
+
+ q=SetImagePixels(sample_image,0,y,sample_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (j != (long) y_offset[y])
+ {
+ /*
+ Read a scan line.
+ */
+ j=(long) y_offset[y];
+ p=AcquireImagePixels(image,0,j,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ (void) memcpy(pixels,p,image->columns*sizeof(PixelPacket));
+ }
+ /*
+ Sample each column.
+ */
+ for (x=0; x < (long) sample_image->columns; x++)
+ *q++=pixels[(long) x_offset[x]];
+ indexes=AccessImmutableIndexes(image);
+ sample_indexes=AccessMutableIndexes(sample_image);
+ if ((indexes != (IndexPacket *) NULL) &&
+ (sample_indexes != (IndexPacket *) NULL))
+ for (x=0; x < (long) sample_image->columns; x++)
+ sample_indexes[x]=indexes[(long) x_offset[x]];
+ if (!SyncImagePixels(sample_image))
+ break;
+ if (QuantumTick(y,sample_image->rows))
+ if (!MagickMonitorFormatted(y,sample_image->rows,exception,
+ "[%s] Sample (%lux%lu --> %lux%lu) image...",
+ image->filename,image->columns,image->rows,
+ sample_image->columns, sample_image->rows))
+ break;
+ }
+ MagickFreeMemory(y_offset);
+ MagickFreeMemory(x_offset);
+ MagickFreeMemory(pixels);
+ /*
+ Sampling does not change the image properties.
+ */
+ sample_image->is_monochrome=image->is_monochrome;
+ sample_image->is_grayscale=image->is_grayscale;
+ return(sample_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S c a l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ScaleImage() changes the size of an image to the given dimensions.
+%
+% The format of the ScaleImage method is:
+%
+% Image *ScaleImage(const Image *image,const unsigned long columns,
+% const unsigned long rows,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o columns: The number of columns in the scaled image.
+%
+% o rows: The number of rows in the scaled image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *ScaleImage(const Image *image,const unsigned long columns,
+ const unsigned long rows,ExceptionInfo *exception)
+{
+#define ScaleImageText "[%s] Scale..."
+
+ double
+ x_scale,
+ x_span,
+ y_scale,
+ y_span;
+
+ DoublePixelPacket
+ pixel,
+ *scale_scanline = (DoublePixelPacket *) NULL,
+ *scanline = (DoublePixelPacket *) NULL,
+ *x_vector = (DoublePixelPacket *) NULL,
+ *y_vector = (DoublePixelPacket *) NULL,
+ zero;
+
+ Image
+ *scale_image;
+
+ long
+ number_rows,
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ register DoublePixelPacket
+ *s,
+ *t;
+
+ unsigned int
+ next_column,
+ next_row;
+
+ /*
+ Initialize scaled image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if ((columns == 0) || (rows == 0) ||
+ (image->columns == 0) || (image->rows == 0))
+ {
+ ThrowImageException(ImageError,UnableToResizeImage,
+ MagickMsg(OptionError,NonzeroWidthAndHeightRequired));
+ return((Image *) NULL);
+ }
+ if ((columns == image->columns) && (rows == image->rows))
+ scale_image=CloneImage(image,0,0,True,exception);
+ else
+ scale_image=CloneImage(image,columns,rows,True,exception);
+
+ if (scale_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Scaling image of size %lux%lu to %lux%lu",
+ image->columns,image->rows,scale_image->columns,
+ scale_image->rows);
+
+ if ((columns == image->columns) && (rows == image->rows))
+ return scale_image;
+
+ scale_image->storage_class=DirectClass;
+ /*
+ Allocate memory.
+ */
+ x_vector=MagickAllocateMemory(DoublePixelPacket *,
+ image->columns*sizeof(DoublePixelPacket));
+ scanline=x_vector;
+ if (image->rows != scale_image->rows)
+ scanline=MagickAllocateMemory(DoublePixelPacket *,
+ image->columns*sizeof(DoublePixelPacket));
+ scale_scanline=MagickAllocateMemory(DoublePixelPacket *,
+ scale_image->columns*sizeof(DoublePixelPacket));
+ y_vector=MagickAllocateMemory(DoublePixelPacket *,
+ image->columns*sizeof(DoublePixelPacket));
+ if ((scanline == (DoublePixelPacket *) NULL) ||
+ (scale_scanline == (DoublePixelPacket *) NULL) ||
+ (x_vector == (DoublePixelPacket *) NULL) ||
+ (y_vector == (DoublePixelPacket *) NULL))
+ {
+ if (scanline == x_vector)
+ scanline=(DoublePixelPacket *) NULL;
+ MagickFreeMemory(scanline);
+ MagickFreeMemory(scale_scanline);
+ MagickFreeMemory(x_vector);
+ MagickFreeMemory(y_vector);
+ DestroyImage(scale_image);
+ ThrowImageException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToScaleImage);
+ }
+ /*
+ Scale image.
+ */
+ number_rows=0;
+ next_row=True;
+ y_span=1.0;
+ y_scale=(double) scale_image->rows/image->rows;
+ (void) memset(y_vector,0,image->columns*sizeof(DoublePixelPacket));
+ (void) memset(&zero,0,sizeof(DoublePixelPacket));
+ i=0;
+ for (y=0; y < (long) scale_image->rows; y++)
+ {
+ q=SetImagePixels(scale_image,0,y,scale_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ if (scale_image->rows == image->rows)
+ {
+ /*
+ Read a new scanline.
+ */
+ p=AcquireImagePixels(image,0,i++,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ x_vector[x].red=p->red;
+ x_vector[x].green=p->green;
+ x_vector[x].blue=p->blue;
+ x_vector[x].opacity=p->opacity;
+ p++;
+ }
+ }
+ else
+ {
+ /*
+ Scale Y direction.
+ */
+ while (y_scale < y_span)
+ {
+ if (next_row && (number_rows < (long) image->rows))
+ {
+ /*
+ Read a new scanline.
+ */
+ p=AcquireImagePixels(image,0,i++,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ x_vector[x].red=p->red;
+ x_vector[x].green=p->green;
+ x_vector[x].blue=p->blue;
+ x_vector[x].opacity=p->opacity;
+ p++;
+ }
+ number_rows++;
+ }
+ for (x=0; x < (long) image->columns; x++)
+ {
+ y_vector[x].red+=y_scale*x_vector[x].red;
+ y_vector[x].green+=y_scale*x_vector[x].green;
+ y_vector[x].blue+=y_scale*x_vector[x].blue;
+ y_vector[x].opacity+=y_scale*x_vector[x].opacity;
+ }
+ y_span-=y_scale;
+ y_scale=(double) scale_image->rows/image->rows;
+ next_row=True;
+ }
+ if (next_row && (number_rows < (long) image->rows))
+ {
+ /*
+ Read a new scanline.
+ */
+ p=AcquireImagePixels(image,0,i++,image->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ x_vector[x].red=p->red;
+ x_vector[x].green=p->green;
+ x_vector[x].blue=p->blue;
+ x_vector[x].opacity=p->opacity;
+ p++;
+ }
+ number_rows++;
+ next_row=False;
+ }
+ s=scanline;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel.red=y_vector[x].red+y_span*x_vector[x].red;
+ pixel.green=y_vector[x].green+y_span*x_vector[x].green;
+ pixel.blue=y_vector[x].blue+y_span*x_vector[x].blue;
+ pixel.opacity=y_vector[x].opacity+y_span*x_vector[x].opacity;
+ s->red=pixel.red > MaxRGBDouble ? MaxRGBDouble : pixel.red;
+ s->green=pixel.green > MaxRGBDouble ? MaxRGBDouble : pixel.green;
+ s->blue=pixel.blue > MaxRGBDouble ? MaxRGBDouble : pixel.blue;
+ s->opacity=pixel.opacity > MaxRGBDouble ? MaxRGBDouble : pixel.opacity;
+ s++;
+ y_vector[x].red=0;
+ y_vector[x].green=0;
+ y_vector[x].blue=0;
+ y_vector[x].opacity=0;
+ }
+ y_scale-=y_span;
+ if (y_scale <= 0)
+ {
+ y_scale=(double) scale_image->rows/image->rows;
+ next_row=True;
+ }
+ y_span=1.0;
+ }
+ if (scale_image->columns == image->columns)
+ {
+ /*
+ Transfer scanline to scaled image.
+ */
+ s=scanline;
+ for (x=0; x < (long) scale_image->columns; x++)
+ {
+ q->red=(Quantum) (s->red+0.5);
+ q->green=(Quantum) (s->green+0.5);
+ q->blue=(Quantum) (s->blue+0.5);
+ q->opacity=(Quantum) (s->opacity+0.5);
+ q++;
+ s++;
+ }
+ }
+ else
+ {
+ /*
+ Scale X direction.
+ */
+ pixel=zero;
+ next_column=False;
+ x_span=1.0;
+ s=scanline;
+ t=scale_scanline;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ x_scale=(double) scale_image->columns/image->columns;
+ while (x_scale >= x_span)
+ {
+ if (next_column)
+ {
+ pixel=zero;
+ t++;
+ }
+ pixel.red+=x_span*s->red;
+ pixel.green+=x_span*s->green;
+ pixel.blue+=x_span*s->blue;
+ pixel.opacity+=x_span*s->opacity;
+ t->red=pixel.red > MaxRGBDouble ? MaxRGBDouble : pixel.red;
+ t->green=pixel.green > MaxRGBDouble ? MaxRGBDouble : pixel.green;
+ t->blue=pixel.blue > MaxRGBDouble ? MaxRGBDouble : pixel.blue;
+ t->opacity=pixel.opacity > MaxRGBDouble ? MaxRGBDouble : pixel.opacity;
+ x_scale-=x_span;
+ x_span=1.0;
+ next_column=True;
+ }
+ if (x_scale > 0.0)
+ {
+ if (next_column)
+ {
+ pixel=zero;
+ next_column=False;
+ t++;
+ }
+ pixel.red+=x_scale*s->red;
+ pixel.green+=x_scale*s->green;
+ pixel.blue+=x_scale*s->blue;
+ pixel.opacity+=x_scale*s->opacity;
+ x_span-=x_scale;
+ }
+ s++;
+ }
+ if (x_span > 0.0)
+ {
+ s--;
+ pixel.red+=x_span*s->red;
+ pixel.green+=x_span*s->green;
+ pixel.blue+=x_span*s->blue;
+ pixel.opacity+=x_span*s->opacity;
+ }
+ if (!next_column && ((t-scale_scanline) < (long) scale_image->columns))
+ {
+ t->red=pixel.red > MaxRGBDouble ? MaxRGBDouble : pixel.red;
+ t->green=pixel.green > MaxRGBDouble ? MaxRGBDouble : pixel.green;
+ t->blue=pixel.blue > MaxRGBDouble ? MaxRGBDouble : pixel.blue;
+ t->opacity=pixel.opacity > MaxRGBDouble ? MaxRGBDouble : pixel.opacity;
+ }
+ /*
+ Transfer scanline to scaled image.
+ */
+ t=scale_scanline;
+ for (x=0; x < (long) scale_image->columns; x++)
+ {
+ q->red=(Quantum) (t->red+0.5);
+ q->green=(Quantum) (t->green+0.5);
+ q->blue=(Quantum) (t->blue+0.5);
+ q->opacity=(Quantum) (t->opacity+0.5);
+ q++;
+ t++;
+ }
+ }
+ if (!SyncImagePixels(scale_image))
+ break;
+ if (QuantumTick(y,scale_image->rows))
+ if (!MagickMonitorFormatted(y,scale_image->rows,exception,
+ ScaleImageText,image->filename))
+ break;
+ }
+ /*
+ Free allocated memory.
+ */
+ if (scanline == x_vector)
+ scanline=(DoublePixelPacket *) NULL;
+ MagickFreeMemory(scanline);
+ MagickFreeMemory(scale_scanline);
+ MagickFreeMemory(x_vector);
+ MagickFreeMemory(y_vector);
+ scale_image->is_grayscale=image->is_grayscale;
+ return(scale_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T h u m b n a i l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ThumbnailImage() changes the size of an image to the given dimensions.
+% This method was designed by Bob Friesenhahn as a low cost thumbnail
+% generator.
+%
+% The format of the ThumbnailImage method is:
+%
+% Image *ThumbnailImage(const Image *image,const unsigned long columns,
+% const unsigned long rows,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o columns: The number of columns in the scaled image.
+%
+% o rows: The number of rows in the scaled image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *ThumbnailImage(const Image *image,
+ const unsigned long columns,const unsigned long rows,ExceptionInfo *exception)
+{
+ double
+ x_factor,
+ y_factor;
+
+ Image
+ *sample_image,
+ *thumbnail_image;
+
+ FilterTypes
+ resize_filter;
+
+ /*
+ Thumbnailing defaults to a fast box filter, but allow user to
+ overide the filter used.
+ */
+ if (UndefinedFilter != image->filter)
+ resize_filter=image->filter;
+ else
+ resize_filter=DefaultThumbnailFilter;
+
+ x_factor=(double) columns/image->columns;
+ y_factor=(double) rows/image->rows;
+ if ((x_factor*y_factor) > 0.1)
+ return(ResizeImage(image,columns,rows,resize_filter,image->blur,exception));
+ sample_image=SampleImage(image,5*columns,5*rows,exception);
+ if (sample_image == (Image *) NULL)
+ return((Image *) NULL);
+ thumbnail_image=ResizeImage(sample_image,columns,rows,resize_filter,
+ sample_image->blur,exception);
+ DestroyImage(sample_image);
+ return(thumbnail_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ Z o o m I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ZoomImage() creates a new image that is a scaled size of an existing one.
+% It allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image. The Point filter gives fast pixel replication,
+% Triangle is equivalent to bi-linear interpolation, and Mitchel giver slower,
+% very high-quality results. See Graphic Gems III for details on this
+% algorithm.
+%
+% The filter member of the Image structure specifies which image filter to
+% use. Blur specifies the blur factor where > 1 is blurry, < 1 is sharp.
+%
+% The format of the ZoomImage method is:
+%
+% Image *ZoomImage(const Image *image,const unsigned long columns,
+% const unsigned long rows,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o zoom_image: Method ZoomImage returns a pointer to the image after
+% scaling. A null image is returned if there is a memory shortage.
+%
+% o image: The image.
+%
+% o columns: An integer that specifies the number of columns in the zoom
+% image.
+%
+% o rows: An integer that specifies the number of rows in the scaled
+% image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *ZoomImage(const Image *image,const unsigned long columns,
+ const unsigned long rows,ExceptionInfo *exception)
+{
+ Image
+ *zoom_image;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ zoom_image=ResizeImage(image,columns,rows,image->filter,image->blur,
+ exception);
+ return(zoom_image);
+}
diff --git a/magick/resize.h b/magick/resize.h
new file mode 100644
index 0000000..e00f42c
--- /dev/null
+++ b/magick/resize.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2003 - 2012 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Image Resize Methods.
+*/
+#ifndef _MAGICK_RESIZE_H
+#define _MAGICK_RESIZE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#define DefaultResizeFilter LanczosFilter
+#define DefaultThumbnailFilter BoxFilter
+
+extern MagickExport Image
+ *MagnifyImage(const Image *,ExceptionInfo *),
+ *MinifyImage(const Image *,ExceptionInfo *),
+ *ResizeImage(const Image *,const unsigned long,const unsigned long,
+ const FilterTypes,const double,ExceptionInfo *),
+ *SampleImage(const Image *,const unsigned long,const unsigned long,
+ ExceptionInfo *),
+ *ScaleImage(const Image *,const unsigned long,const unsigned long,
+ ExceptionInfo *),
+ *ThumbnailImage(const Image *,const unsigned long,const unsigned long,
+ ExceptionInfo *),
+ *ZoomImage(const Image *,const unsigned long,const unsigned long,
+ ExceptionInfo *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_RESIZE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/resource.c b/magick/resource.c
new file mode 100644
index 0000000..f5664e9
--- /dev/null
+++ b/magick/resource.c
@@ -0,0 +1,940 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% RRRR EEEEE SSSSS OOO U U RRRR CCCC EEEEE %
+% R R E SS O O U U R R C E %
+% RRRR EEE SSS O O U U RRRR C EEE %
+% R R E SS O O U U R R C E %
+% R R EEEEE SSSSS OOO UUU R R CCCC EEEEE %
+% %
+% %
+% Get/Set ImageMagick Resources. %
+% %
+% %
+% Software Design %
+% John Cristy %
+% September 2002 %
+% %
+% Completely Re-written %
+% Bob Friesenhahn %
+% April 2008 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/log.h"
+#include "magick/resource.h"
+#include "magick/semaphore.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define ResourceInfinity (-1)
+#define ResourceInfoMaxIndex ((unsigned int) (sizeof(resource_info)/sizeof(resource_info[0])-1))
+
+/*
+ Typedef declarations.
+*/
+typedef enum
+{
+ AbsoluteLimit,
+ SummationLimit
+} LimitType;
+
+/*
+ Definition of a resource. We intentionally use signed types to
+ store 'value' and 'limit'.
+*/
+typedef struct _ResourceInfo
+{
+ const char
+ *name,
+ *units,
+ *env;
+
+ magick_int64_t
+ value;
+
+ magick_int64_t
+ minimum,
+ maximum;
+
+ LimitType
+ limit_type;
+
+} ResourceInfo;
+
+/*
+ Global declarations.
+*/
+static SemaphoreInfo
+ *resource_semaphore = (SemaphoreInfo *) NULL;
+
+/*
+ Array must be in same order as ResourceType enum
+*/
+#define PIXEL_LIMIT (INT_MAX/(sizeof(PixelPacket)))
+static ResourceInfo
+ resource_info[] =
+ {
+ { "", "", "", 0, 0, ResourceInfinity, SummationLimit },
+ { "disk", "B", "MAGICK_LIMIT_DISK", 0, 0, ResourceInfinity, SummationLimit },
+ { "files", "", "MAGICK_LIMIT_FILES", 0, 32, 256, SummationLimit },
+ { "map", "B", "MAGICK_LIMIT_MAP", 0, 0, ResourceInfinity, SummationLimit },
+ { "memory", "B", "MAGICK_LIMIT_MEMORY", 0, 0, ResourceInfinity, SummationLimit },
+ { "pixels", "P", "MAGICK_LIMIT_PIXELS", 0, 1, ResourceInfinity, AbsoluteLimit },
+ { "threads", "", "OMP_NUM_THREADS", 1, 1, ResourceInfinity, AbsoluteLimit },
+ { "width", "P", "MAGICK_LIMIT_WIDTH", 0, 1, PIXEL_LIMIT, AbsoluteLimit },
+ { "height", "P", "MAGICK_LIMIT_HEIGHT", 0, 1, PIXEL_LIMIT, AbsoluteLimit }
+ };
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e M a g i c k R e s o u r c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireMagickResource() acquires resources of the specified type. True is
+% returned if the specified resource is available otherwise False.
+%
+% The format of the AcquireMagickResource() method is:
+%
+% MagickPassFail AcquireMagickResource(const ResourceType type,
+% const magick_int64_t size)
+%
+% A description of each parameter follows:
+%
+% o type: The type of resource.
+%
+% o size: The number of bytes needed from for this resource.
+%
+%
+*/
+static ResourceInfo *GetResourceInfo(const ResourceType type)
+{
+ ResourceInfo
+ *info;
+
+ unsigned int
+ index;
+
+ info = (ResourceInfo *) NULL;
+ index = type;
+ if (index <= ResourceInfoMaxIndex)
+ info = &resource_info[index];
+
+ return info;
+}
+
+MagickExport MagickPassFail
+AcquireMagickResource(const ResourceType type,
+ const magick_uint64_t size)
+{
+ magick_uint64_t
+ value;
+
+ ResourceInfo
+ *info;
+
+ MagickPassFail
+ status;
+
+ status=MagickPass;
+
+ LockSemaphoreInfo(resource_semaphore);
+
+ if ((info=GetResourceInfo(type)))
+ {
+ switch(info->limit_type)
+ {
+ case AbsoluteLimit:
+ {
+ /*
+ Limit depends only on the currently requested size.
+ */
+ if ((info->maximum != ResourceInfinity) &&
+ (size > (magick_uint64_t) info->maximum))
+ status=MagickFail;
+ break;
+ }
+ case SummationLimit:
+ {
+ /*
+ Limit depends on sum of previous allocations as well as
+ the currently requested size.
+ */
+ value=info->value+size;
+ if ((info->maximum != ResourceInfinity) &&
+ (value > (magick_uint64_t) info->maximum))
+ status=MagickFail;
+ else
+ info->value=value;
+
+ break;
+ }
+ }
+
+ if (IsEventLogging())
+ {
+ char
+ f_limit[MaxTextExtent],
+ f_size[MaxTextExtent],
+ f_value[MaxTextExtent];
+
+ if (info->maximum == ResourceInfinity)
+ {
+ strlcpy(f_limit,"Unlimited",sizeof(f_limit));
+ }
+ else
+ {
+ FormatSize(info->maximum, f_limit);
+ strlcat(f_limit,info->units,sizeof(f_limit));
+ }
+
+ FormatSize(size, f_size);
+ strlcat(f_size,info->units,sizeof(f_size));
+
+ if (info->limit_type == AbsoluteLimit)
+ {
+ strlcpy(f_value,"----",sizeof(f_value));
+ }
+ else
+ {
+ FormatSize(info->value, f_value);
+ strlcat(f_value,info->units,sizeof(f_value));
+ }
+
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "%s %s%s/%s/%s",
+ info->name,
+ (status ? "+" : "!"),
+ f_size,
+ f_value,
+ f_limit);
+ }
+ }
+
+ UnlockSemaphoreInfo(resource_semaphore);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y M a g i c k R e s o u r c e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyMagickResources() destroys the resource environment.
+%
+% The format of the DestroyMagickResources() method is:
+%
+% DestroyMagickResources(void)
+%
+%
+*/
+MagickExport void DestroyMagickResources(void)
+{
+ DestroySemaphoreInfo(&resource_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M a g i c k R e s o u r c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickResource() returns the current consumption level for the
+% specified resource type.
+%
+% The format of the GetMagickResource() method is:
+%
+% magick_uint64_t GetMagickResource(const ResourceType type)
+%
+% A description of each parameter follows:
+%
+% o type: The type of resource.
+%
+%
+*/
+MagickExport magick_int64_t GetMagickResource(const ResourceType type)
+{
+ ResourceInfo
+ *info;
+
+ magick_int64_t
+ resource;
+
+ resource=0;
+ LockSemaphoreInfo(resource_semaphore);
+
+ if ((info=GetResourceInfo(type)))
+ resource=info->value;
+
+ UnlockSemaphoreInfo(resource_semaphore);
+ return(resource);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M a g i c k R e s o u r c e L i m i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickResourceLimit() returns the current maximum limit for the
+% specified resource type.
+%
+% The format of the GetMagickResourceLimit() method is:
+%
+% magick_uint64_t GetMagickResourceLimit(const ResourceType type)
+%
+% A description of each parameter follows:
+%
+% o type: The type of resource.
+%
+%
+*/
+MagickExport magick_int64_t GetMagickResourceLimit(const ResourceType type)
+{
+ ResourceInfo
+ *info;
+
+ magick_int64_t
+ resource;
+
+ resource=0;
+ LockSemaphoreInfo(resource_semaphore);
+
+ if ((info=GetResourceInfo(type)))
+ resource=info->maximum;
+
+ UnlockSemaphoreInfo(resource_semaphore);
+ return(resource);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e M a g i c k R e s o u r c e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% InitializeMagickResources() initializes the resource environment.
+%
+% The format of the InitializeMagickResources() method is:
+%
+% InitializeMagickResources(void)
+%
+%
+*/
+MagickExport void InitializeMagickResources(void)
+{
+ magick_int64_t
+ max_disk=-1,
+ max_files=256,
+ max_map=4096,
+ max_memory=1024,
+ max_pixels=-1,
+ max_threads=1,
+ max_width=-1,
+ max_height=-1;
+
+ /*
+ Allocate semaphore.
+ */
+ assert(resource_semaphore == (SemaphoreInfo *) NULL);
+ resource_semaphore=AllocateSemaphoreInfo();
+
+ /*
+ Set Magick resource limits.
+ */
+#if defined(POSIX)
+ {
+ unsigned long
+ total_memory=0;
+
+# if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
+ {
+ long
+ pagesize=-1,
+ pages=-1;
+ /*
+ Compute total physical memory based on number of memory pages,
+ and page size.
+ */
+ pages=sysconf(_SC_PHYS_PAGES);
+ pagesize = MagickGetMMUPageSize();
+
+ if (pages > 0 && pagesize > 0)
+ total_memory=((pages+512)/1024)*((pagesize+512)/1024);
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "Total physical memory %ld MB (%ld pages and %ld bytes per page)",
+ total_memory, pages, pagesize);
+ }
+# elif defined(MAGICK_PHYSICAL_MEMORY_COMMAND) && defined(HAVE_POPEN)
+ {
+ double
+ bytes=0;
+
+ FILE
+ *command;
+ /*
+ Execute the external command defined by
+ MAGICK_PHYSICAL_MEMORY_COMMAND to obtain the total physical
+ memory in bytes. This external command should be quite speedy
+ or else it will impact the time to start GraphicsMagick.
+ */
+ if ((command = popen(MAGICK_PHYSICAL_MEMORY_COMMAND, "r")) != NULL)
+ {
+ if (fscanf(command,"%lf",&bytes) == 1)
+ total_memory=(bytes/(1024*1024));
+ (void) pclose(command);
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "Total physical memory %ld MB",total_memory);
+ }
+ }
+# endif
+
+ if (total_memory > 0)
+ {
+ /*
+ We are not able to use more than size_t worth of address
+ space. On 32 bit systems, we can usually only use half or
+ three quarters of it. Regardless, we need address space
+ for more than just image data.
+ */
+ size_t
+ size_t_max = (size_t) ~0UL;
+
+ size_t_max /= (1024U*1024U);
+ max_memory = Min(size_t_max/2-100,total_memory);
+ max_map = Min(size_t_max/2-100,2*total_memory);
+ }
+ }
+#endif /* defined(POSIX) */
+
+#if defined(MSWINDOWS)
+ {
+ long
+ total_physical_memory=0,
+ total_virtual_memory=0;
+
+ /*
+ GlobalMemoryStatusEx is necessary to handle results for
+ large-memory (>4GB) machines (and to provide accurate results
+ for 2 to 4 GB of memory), but it is not available on older
+ versions of Windows. Windows 32-bit applications are still
+ usually limited to addressing only 2 GB of memory even if the
+ system provides more (except for certain server versions of
+ Windows with applications linked with the /LARGEADDRESSAWARE
+ option). Test for API existence prior to using it. MinGW
+ headers currently lack support for this API so compilation of
+ supportive code is made optional.
+ */
+#if defined(HAVE_GLOBALMEMORYSTATUSEX)
+ if (NTKernelAPISupported("GlobalMemoryStatusEx"))
+ {
+ MEMORYSTATUSEX
+ stat_ex;
+
+ (void) memset(&stat_ex,0,sizeof(stat_ex));
+ stat_ex.dwLength=sizeof(stat_ex);
+ if (GlobalMemoryStatusEx(&stat_ex))
+ {
+ total_physical_memory=(long)(stat_ex.ullTotalPhys/1048576UL);
+ total_virtual_memory=(long)(stat_ex.ullTotalVirtual/1048576UL);
+ }
+ else
+ {
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "GlobalMemoryStatusEx() call failed! (error %ld)",GetLastError());
+ }
+ }
+#endif
+
+ if (total_physical_memory == 0)
+ {
+ MEMORYSTATUS
+ stat;
+
+ GlobalMemoryStatus(&stat);
+ total_physical_memory=stat.dwTotalPhys/1048576;
+ total_virtual_memory=stat.dwTotalVirtual/1048576;
+ }
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "Total physical memory %ld MB, Total virtual memory %ld MB",
+ total_physical_memory, total_virtual_memory);
+
+ max_memory=Min(total_physical_memory,total_virtual_memory);
+ /*
+ We will default to using at most 80% of available memory for image data.
+ */
+ max_memory=(long)(0.8*max_memory);
+ /*
+ Use the maximum memory as our default memory map limit. Memory
+ mapping files larger than available RAM can cause VM thrashing.
+ This implies that memory mapping won't get used much. However,
+ it is possible for heap memory allocations to fail (due to heap
+ fragmentation) whereas memory mapping still succeeds.
+ */
+ max_map=max_memory;
+
+ /*
+ Windows lowio level supports up to 2048 open files.
+ Reserve 512 handles for other uses.
+ */
+ max_files=2048-512;
+ }
+#endif /* defined(MSWINDOWS) */
+
+ /*
+ Compute fundamental limits based on build parameters. Image size
+ is fundamentally limited by how many pixels may reside in one row.
+ */
+ if (sizeof(size_t) == 4)
+ max_pixels=(magick_int64_t) ((unsigned long) ULONG_MAX/(5*sizeof(Quantum)));
+
+
+ /*
+ Disk, map, and memory are in units of MB and need to be scaled up.
+ */
+ /* if (max_disk > 0) */
+ /* max_disk *= 1024UL*1024UL; */
+ if (max_map > 0)
+ max_map *= 1024UL*1024UL;
+ if (max_memory > 0)
+ max_memory *= 1024UL*1024UL;
+
+ /*
+ Support using environment variables to set limits
+ */
+ {
+ const char
+ *envp;
+
+ if ((envp=getenv("MAGICK_LIMIT_DISK")))
+ max_disk=MagickSizeStrToInt64(envp,1024);
+
+ if ((envp=getenv("MAGICK_LIMIT_FILES")))
+ max_files=MagickSizeStrToInt64(envp,1024);
+
+ if ((envp=getenv("MAGICK_LIMIT_MAP")))
+ max_map=MagickSizeStrToInt64(envp,1024);
+
+ if ((envp=getenv("MAGICK_LIMIT_MEMORY")))
+ max_memory=MagickSizeStrToInt64(envp,1024);
+
+ if ((envp=getenv("MAGICK_LIMIT_PIXELS")))
+ max_pixels=MagickSizeStrToInt64(envp,1024);
+
+ if ((envp=getenv("MAGICK_LIMIT_WIDTH")))
+ max_width=MagickSizeStrToInt64(envp,1024);
+
+ if ((envp=getenv("MAGICK_LIMIT_HEIGHT")))
+ max_height=MagickSizeStrToInt64(envp,1024);
+
+#if defined(HAVE_OPENMP)
+ max_threads=omp_get_num_procs();
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "%i CPU cores are available",(int) max_threads);
+ if ((envp=getenv("OMP_NUM_THREADS")))
+ {
+ max_threads=MagickSizeStrToInt64(envp,1024);
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "OMP_NUM_THREADS requests %i threads",(int) max_threads);
+ }
+ if (max_threads < 1)
+ max_threads=1;
+ omp_set_num_threads((int) max_threads);
+ max_threads=omp_get_max_threads();
+#endif /* HAVE_OPENMP */
+ }
+
+#if defined(POSIX)
+# if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
+ {
+ struct rlimit
+ rlimits;
+
+ rlim_t
+ margin,
+ target;
+
+ margin=128;
+ target=(rlim_t) max_files+margin;
+ if (getrlimit(RLIMIT_NOFILE, &rlimits) != -1)
+ {
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "System file open limits are %lu soft,"
+ " %lu hard",
+ (unsigned long) rlimits.rlim_cur,
+ (unsigned long) rlimits.rlim_max);
+# if defined(HAVE_SETRLIMIT)
+ if (rlimits.rlim_max < target)
+ rlimits.rlim_cur=rlimits.rlim_max;
+ if (rlimits.rlim_cur < target)
+ {
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "Increasing file open soft limit from %lu "
+ "to %lu",
+ (unsigned long) rlimits.rlim_cur,
+ (unsigned long) target);
+ rlimits.rlim_cur=target;
+ (void) setrlimit(RLIMIT_NOFILE, &rlimits);
+ }
+ if (getrlimit(RLIMIT_NOFILE, &rlimits) != -1)
+ {
+ if (rlimits.rlim_cur < target)
+ {
+ if (rlimits.rlim_cur > margin*2)
+ max_files=rlimits.rlim_cur-margin;
+ else
+ max_files=rlimits.rlim_cur/2;
+ }
+ }
+# endif
+ }
+ }
+# elif defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
+ {
+ long
+ margin,
+ open_max,
+ target;
+
+ margin=128;
+ target=max_files+margin;
+ open_max=sysconf(_SC_OPEN_MAX);
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "System file open limit is %lu",
+ (unsigned long) open_max);
+ if (open_max < target)
+ {
+ if (open_max > margin*2)
+ max_files=open_max-margin;
+ else
+ max_files=open_max/2;
+ }
+ }
+# endif
+
+#endif
+
+ if (max_disk >= 0)
+ (void) SetMagickResourceLimit(DiskResource,max_disk);
+ if (max_files >= 0)
+ (void) SetMagickResourceLimit(FileResource,max_files);
+ if (max_map >= 0)
+ (void) SetMagickResourceLimit(MapResource,max_map);
+ if (max_memory >= 0)
+ (void) SetMagickResourceLimit(MemoryResource,max_memory);
+ if (max_pixels >= 0)
+ (void) SetMagickResourceLimit(PixelsResource,max_pixels);
+ if (max_threads >= 0)
+ (void) SetMagickResourceLimit(ThreadsResource,max_threads);
+ if (max_width >= 0)
+ (void) SetMagickResourceLimit(WidthResource,max_width);
+ if (max_height >= 0)
+ (void) SetMagickResourceLimit(HeightResource,max_height);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i b e r a t e M a g i c k R e s o u r c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% LiberateMagickResource() liberates resources of the specified type.
+%
+% The format of the LiberateMagickResource() method is:
+%
+% void LiberateMagickResource(const ResourceType type,
+% const magick_int64_t size)
+%
+% A description of each parameter follows:
+%
+% o type: The type of resource.
+%
+% o size: The size of the resource.
+%
+%
+*/
+MagickExport void LiberateMagickResource(const ResourceType type,
+ const magick_uint64_t size)
+{
+ ResourceInfo
+ *info;
+
+ LockSemaphoreInfo(resource_semaphore);
+
+ if ((info=GetResourceInfo(type)))
+ {
+ switch(info->limit_type)
+ {
+ case AbsoluteLimit:
+ {
+ /*
+ Limit depends only on the currently requested size.
+ */
+ info->value=0;
+ break;
+ }
+ case SummationLimit:
+ {
+ /*
+ Limit depends on sum of previous allocations as well as
+ the currently requested size.
+ */
+ info->value-=size;
+ break;
+ }
+ }
+
+
+ if (IsEventLogging())
+ {
+ char
+ f_limit[MaxTextExtent],
+ f_size[MaxTextExtent],
+ f_value[MaxTextExtent];
+
+ if (info->maximum == ResourceInfinity)
+ {
+ strlcpy(f_limit,"Unlimited",sizeof(f_limit));
+ }
+ else
+ {
+ FormatSize(info->maximum, f_limit);
+ strlcat(f_limit,info->units,sizeof(f_limit));
+ }
+
+ FormatSize(size, f_size);
+ strlcat(f_size,info->units,sizeof(f_size));
+
+ if (info->limit_type == AbsoluteLimit)
+ {
+ strlcpy(f_value,"----",sizeof(f_value));
+ }
+ else
+ {
+ FormatSize(info->value, f_value);
+ strlcat(f_value,info->units,sizeof(f_value));
+ }
+
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "%s %s%s/%s/%s",
+ info->name,
+ "-",
+ f_size,
+ f_value,
+ f_limit);
+ }
+ }
+
+ UnlockSemaphoreInfo(resource_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t M a g i c k R e s o u r c e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ListMagickResourceInfo lists the resource info to a file.
+%
+% The format of the ListMagickResourceInfo method is:
+%
+% unsigned int ListMagickResourceInfo(FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o file: An pointer to a FILE.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport MagickPassFail ListMagickResourceInfo(FILE *file,
+ ExceptionInfo *exception)
+{
+ unsigned int
+ index;
+
+ ARG_NOT_USED(exception);
+
+ LockSemaphoreInfo(resource_semaphore);
+ if (file == (const FILE *) NULL)
+ file=stdout;
+
+ fprintf(file,"Resource Limits (Q%d, %d bits/pixel, %dbit address)\n",
+ QuantumDepth,4*QuantumDepth,
+ (sizeof(PixelPacket *) > 4 ? 64 : 32));
+ fprintf(file,"----------------------------------------------------\n");
+ for (index=1 ; index <= ResourceInfoMaxIndex; index++)
+ {
+ char
+ environment[MaxTextExtent],
+ heading[MaxTextExtent],
+ limit[MaxTextExtent];
+
+ if (resource_info[index].maximum == ResourceInfinity)
+ {
+ strlcpy(limit,"Unlimited",sizeof(limit));
+ }
+ else
+ {
+ FormatSize(resource_info[index].maximum,limit);
+ strlcat(limit,resource_info[index].units,sizeof(limit));
+ }
+ FormatString(heading,"%c%s",toupper((int) resource_info[index].name[0]),
+ resource_info[index].name+1);
+
+ (void) strlcpy(environment,resource_info[index].env,sizeof(environment));
+
+ fprintf(file,"%8s: %10s (%s)\n", heading, limit, environment);
+ }
+ fprintf(file,
+ "\n"
+ " IEC Binary Ranges:\n"
+ " Ki = \"kibi\" (2^10)\n"
+ " Mi = \"mebi\" (2^20)\n"
+ " Gi = \"gibi\" (2^30)\n"
+ " Ti = \"tebi\" (2^40)\n"
+ " Pi = \"pebi\" (2^50)\n"
+ " Ei = \"exbi\" (2^60)\n"
+ );
+
+ (void) fflush(file);
+
+ UnlockSemaphoreInfo(resource_semaphore);
+ return(MagickPass);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t M a g i c k R e s o u r c e L i m i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetMagickResourceLimit() sets the limit for a particular resource. The
+% units for resource types are as follows:
+%
+% DiskResource -- Bytes
+% FileResource -- Open files
+% MapResource -- Bytes
+% MemoryResource -- Bytes
+% PixelsResource -- Pixels
+% ThreadsResource -- Threads
+% WidthResource -- Pixels
+% HeightResource -- Pixels
+%
+% The format of the SetMagickResourceLimit() method is:
+%
+% void SetMagickResourceLimit(const ResourceType type,
+% const unsigned long limit)
+%
+% A description of each parameter follows:
+%
+% o type: The type of resource.
+%
+% o limit: The maximum limit for the resource.
+%
+%
+*/
+MagickExport MagickPassFail SetMagickResourceLimit(const ResourceType type,
+ const magick_int64_t limit)
+{
+ ResourceInfo
+ *info;
+
+ MagickPassFail
+ status;
+
+ status=MagickFail;
+
+ LockSemaphoreInfo(resource_semaphore);
+ if ((info=GetResourceInfo(type)))
+ {
+ if (limit >= info->minimum)
+ {
+ char
+ f_limit[MaxTextExtent];
+
+
+ FormatSize((magick_int64_t) limit, f_limit);
+ info->maximum = limit;
+#if defined(HAVE_OPENMP)
+ if (ThreadsResource == type)
+ omp_set_num_threads((int) limit);
+#endif /* HAVE_OPENMP */
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "Set %s resource limit to %s%s",
+ info->name,f_limit,info->units);
+ status=MagickPass;
+ }
+ else
+ {
+ (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
+ "Ignored bogus request to set %s resource limit to %ld%s",
+ info->name,(long) limit,info->units);
+ }
+ }
+ UnlockSemaphoreInfo(resource_semaphore);
+
+ return(status);
+}
diff --git a/magick/resource.h b/magick/resource.h
new file mode 100644
index 0000000..ae7b5d1
--- /dev/null
+++ b/magick/resource.h
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2003 - 2015 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Resource methods.
+*/
+#ifndef _MAGICK_RESOURCE_H
+#define _MAGICK_RESOURCE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Typedef declarations.
+*/
+typedef enum
+{
+ UndefinedResource=0, /* Undefined value */
+ DiskResource, /* Pixel cache total disk space (Gigabytes) */
+ FileResource, /* Pixel cache number of open files (Files) */
+ MapResource, /* Pixel cache total file memory-mapping (Megabytes) */
+ MemoryResource, /* Maximum pixel cache heap memory allocations (Megabytes) */
+ PixelsResource, /* Maximum number of pixels in single image (Pixels) */
+ ThreadsResource, /* Maximum number of worker threads */
+ WidthResource, /* Maximum pixel width of an image (Pixels) */
+ HeightResource /* Maximum pixel height of an image (Pixels) */
+} ResourceType;
+
+/*
+ Method declarations.
+*/
+extern MagickExport MagickPassFail
+ AcquireMagickResource(const ResourceType type,const magick_uint64_t size),
+ ListMagickResourceInfo(FILE *file,ExceptionInfo *exception),
+ SetMagickResourceLimit(const ResourceType type,const magick_int64_t limit);
+
+extern MagickExport magick_int64_t
+ GetMagickResource(const ResourceType type),
+ GetMagickResourceLimit(const ResourceType type);
+
+extern MagickExport void
+ DestroyMagickResources(void),
+ InitializeMagickResources(void),
+ LiberateMagickResource(const ResourceType type,const magick_uint64_t size);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/segment.c b/magick/segment.c
new file mode 100644
index 0000000..7ec5952
--- /dev/null
+++ b/magick/segment.c
@@ -0,0 +1,1794 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS EEEEE GGGG M M EEEEE N N TTTTT %
+% SS E G MM MM E NN N T %
+% SSS EEE G GGG M M M EEE N N N T %
+% SS E G G M M E N NN T %
+% SSSSS EEEEE GGGG M M EEEEE N N T %
+% %
+% %
+% Methods to Segment an Image with Thresholding Fuzzy c-Means %
+% %
+% %
+% Software Design %
+% John Cristy %
+% April 1993 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Segment segments an image by analyzing the histograms of the color
+% components and identifying units that are homogeneous with the fuzzy
+% c-means technique. The scale-space filter analyzes the histograms of
+% the three color components of the image and identifies a set of classes.
+% The extents of each class is used to coarsely segment the image with
+% thresholding. The color associated with each class is determined by
+% the mean color of all pixels within the extents of a particular class.
+% Finally, any unclassified pixels are assigned to the closest class with
+% the fuzzy c-means technique.
+%
+% The fuzzy c-Means algorithm can be summarized as follows:
+%
+% o Build a histogram, one for each color component of the image.
+%
+% o For each histogram, successively apply the scale-space
+% filter and build an interval tree of zero crossings in
+% the second derivative at each scale. Analyze this
+% scale-space ``fingerprint'' to determine which peaks and
+% valleys in the histogram are most predominant.
+%
+% o The fingerprint defines intervals on the axis of the
+% histogram. Each interval contains either a minima or a
+% maxima in the original signal. If each color component
+% lies within the maxima interval, that pixel is considered
+% ``classified'' and is assigned an unique class number.
+%
+% o Any pixel that fails to be classified in the above
+% thresholding pass is classified using the fuzzy
+% c-Means technique. It is assigned to one of the classes
+% discovered in the histogram analysis phase.
+%
+% The fuzzy c-Means technique attempts to cluster a pixel by finding
+% the local minima of the generalized within group sum of squared error
+% objective function. A pixel is assigned to the closest class of which
+% the fuzzy membership has a maximum value.
+%
+% Segment is strongly based on software written by Andy Gallo, University
+% of Delaware.
+%
+% The following reference was used in creating this program:
+%
+% Young Won Lim, Sang Uk Lee, "On The Color Image Segmentation Algorithm
+% Based on the Thresholding and the Fuzzy c-Means Techniques", Pattern
+% Recognition, Volume 23, Number 9, pages 935-952, 1990.
+%
+%
+*/
+
+#include "magick/studio.h"
+#include "magick/color.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/quantize.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define MaxDimension 3
+#define DeltaTau 0.5f
+#define Tau 5.2f
+
+/*
+ Set SquaredClassify to 1 to shortcut use of expensive pow() in the
+ classification code.
+*/
+#define SquaredClassify 1
+
+/* 2 is optimum performance, 2.5 may be better quality */
+#if SquaredClassify
+# define WeightingExponent 2
+#else
+# define WeightingExponent 2.5
+#endif
+
+
+/*
+ Typedef declarations.
+*/
+typedef struct _ExtentPacket
+{
+ double
+ center;
+
+ int
+ index,
+ left,
+ right;
+} ExtentPacket;
+
+typedef struct _IntervalTree
+{
+ double
+ tau;
+
+ int
+ left,
+ right;
+
+ double
+ mean_stability,
+ stability;
+
+ struct _IntervalTree
+ *sibling,
+ *child;
+} IntervalTree;
+
+typedef struct _ZeroCrossing
+{
+ double
+ tau,
+ histogram[256];
+
+ short
+ crossings[256];
+} ZeroCrossing;
+
+/*
+ Constant declarations.
+*/
+static const int
+ Blue = 2,
+ Green = 1,
+ Red = 0,
+ SafeMargin = 3,
+ TreeLength = 600;
+
+/*
+ Method prototypes.
+*/
+static int
+ DefineRegion(const short *,ExtentPacket *);
+
+static void
+ ScaleSpace(const long *,const double,double *),
+ ZeroCrossHistogram(double *,const double,short *);
+
+#if 0
+static void
+DumpDerivativeArray(FILE *stream,const unsigned int entries,
+ const double *derivative)
+{
+ unsigned int
+ i;
+
+ for (i=0; i < entries; i++)
+ fprintf(stream," %03u: %g\n", i, derivative[i]);
+}
+#endif
+static void
+DumpExtremaArray(FILE *stream,const unsigned int entries,
+ const short *extrema)
+{
+ unsigned int
+ i;
+
+ for (i=0; i < entries; i++)
+ fprintf(stream," %03u: %d\n", i, (int) extrema[i]);
+}
+static void
+DumpHistogramArray(FILE *stream,const unsigned int entries,
+ const long *histogram)
+{
+ unsigned int
+ i;
+
+ for (i=0; i < entries; i++)
+ fprintf(stream," %03u: %ld\n", i, histogram[i]);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l a s s i f y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Method Classify defines one or more classes. Each pixel is thresholded
+% to determine which class it belongs to. If no class is identified it
+% is assigned to the closest class based on the fuzzy c-Means technique.
+%
+% The format of the Classify method is:
+%
+% MagickPassFail Classify(Image *image,short **extrema,
+% const double cluster_threshold,
+% const double weighting_exponent,
+% const unsigned int verbose)
+%
+% A description of each parameter follows.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o extrema: Specifies a pointer to an array of integers. They
+% represent the peaks and valleys of the histogram for each color
+% component.
+%
+% o cluster_threshold: The minimum number of total pixels contained
+% in a hexahedra before it can be considered valid (expressed as a
+% percentage of total pixels). This is used to eliminate seldom
+% used colors.
+%
+% o weighting_exponent: Specifies the membership weighting exponent.
+%
+% o verbose: A value greater than zero prints detailed information about
+% the identified classes.
+%
+%
+*/
+#define SegmentImageText "[%s] Segment..."
+
+typedef struct _Cluster
+{
+ struct _Cluster
+ *next;
+
+ ExtentPacket
+ red,
+ green,
+ blue;
+
+ magick_int64_t
+ count;
+
+ short
+ id;
+} Cluster;
+
+static MagickPassFail
+Classify(Image *image,short **extrema,
+ const double cluster_threshold,
+ const double weighting_exponent,
+ const unsigned int verbose)
+{
+ Cluster
+ *cluster=0,
+ **cluster_array=0,
+ *head=0,
+ *last_cluster,
+ *next_cluster=0;
+
+ double
+ *squares_array=0,
+ threshold,
+ total_vectors;
+
+ ExtentPacket
+ blue = { 0.0, 0, 0, 0},
+ green = { 0.0, 0, 0, 0},
+ red = { 0.0, 0, 0, 0};
+
+ unsigned long
+ count;
+
+ long
+ y;
+
+ PixelPacket
+ *colormap=0;
+
+ register const PixelPacket
+ *p;
+
+ register double
+ *squares;
+
+ register IndexPacket
+ *indexes;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ unsigned long
+ number_clusters;
+
+ unsigned long
+ row_count=0;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Form clusters.
+ */
+ cluster=(Cluster *) NULL;
+ head=(Cluster *) NULL;
+ red.index=0;
+ while (DefineRegion(extrema[Red],&red))
+ {
+ green.index=0;
+ while (DefineRegion(extrema[Green],&green))
+ {
+ blue.index=0;
+ while (DefineRegion(extrema[Blue],&blue))
+ {
+ /*
+ Allocate a new class.
+ */
+ if (head != (Cluster *) NULL)
+ {
+ cluster->next=MagickAllocateMemory(Cluster *,sizeof(Cluster));
+ cluster=cluster->next;
+ }
+ else
+ {
+ cluster=MagickAllocateMemory(Cluster *,sizeof(Cluster));
+ head=cluster;
+ }
+ if (cluster == (Cluster *) NULL)
+ {
+ ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ goto classify_error_exit;
+ }
+ /*
+ Initialize a new class.
+ */
+ (void) memset(cluster,0,sizeof(Cluster));
+ cluster->count=0;
+ cluster->red=red;
+ cluster->green=green;
+ cluster->blue=blue;
+ cluster->next=(Cluster *) NULL;
+ }
+ }
+ }
+ if (head == (Cluster *) NULL)
+ {
+ /*
+ No classes were identified-- create one.
+ */
+ cluster=MagickAllocateMemory(Cluster *,sizeof(Cluster));
+ if (cluster == (Cluster *) NULL)
+ {
+ ThrowException(&image->exception,ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ goto classify_error_exit;
+ }
+ /*
+ Initialize a new class.
+ */
+ (void) memset(cluster,0,sizeof(Cluster));
+ cluster->count=0;
+ cluster->red=red;
+ cluster->green=green;
+ cluster->blue=blue;
+ cluster->next=(Cluster *) NULL;
+ head=cluster;
+ }
+ /*
+ Build an array representation of the clusters.
+ */
+ number_clusters=0;
+ for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next)
+ number_clusters++;
+ cluster_array=MagickAllocateArray(Cluster **,number_clusters,sizeof(Cluster *));
+ number_clusters=0;
+ for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next)
+ cluster_array[number_clusters++]=cluster;
+ /*
+ Count the pixels for each cluster.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ status=MagickFail;
+ break;
+ }
+ for (x=(long) image->columns; x != 0; x--)
+ {
+ double
+ r,
+ g,
+ b;
+
+ r=(double) ScaleQuantumToChar(p->red);
+ g=(double) ScaleQuantumToChar(p->green);
+ b=(double) ScaleQuantumToChar(p->blue);
+
+ for (count=0 ; count < number_clusters; count++)
+ {
+ if ((r >= (cluster_array[count]->red.left-SafeMargin)) &&
+ (r <= (cluster_array[count]->red.right+SafeMargin)) &&
+ (g >= (cluster_array[count]->green.left-SafeMargin)) &&
+ (g <= (cluster_array[count]->green.right+SafeMargin)) &&
+ (b >= (cluster_array[count]->blue.left-SafeMargin)) &&
+ (b <= (cluster_array[count]->blue.right+SafeMargin)))
+ {
+ /*
+ Count this pixel.
+ */
+ cluster_array[count]->count++;
+ cluster_array[count]->red.center+=r;
+ cluster_array[count]->green.center+=g;
+ cluster_array[count]->blue.center+=b;
+
+ if ((count > 0) &&
+ (cluster_array[count]->count > cluster_array[count-1]->count))
+ {
+ Cluster
+ *tmp_cluster;
+
+ tmp_cluster=cluster_array[count-1];
+ cluster_array[count-1]=cluster_array[count];
+ cluster_array[count]=tmp_cluster;
+ }
+ break;
+ }
+ }
+ p++;
+ }
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows << 1,&image->exception,
+ SegmentImageText,image->filename))
+ {
+ status=MagickFail;
+ break;
+ }
+ }
+ if (status == MagickFail)
+ goto classify_error_exit;
+
+ /*
+ Remove clusters that do not meet minimum cluster threshold.
+ */
+ total_vectors=0.0;
+ for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next)
+ total_vectors+=(double) cluster->count;
+ threshold=cluster_threshold*0.01*total_vectors;
+ count=0;
+ last_cluster=head;
+ next_cluster=head;
+ for (cluster=head; cluster != (Cluster *) NULL; cluster=next_cluster)
+ {
+ next_cluster=cluster->next;
+ if ((cluster->count > 0) &&
+ ((double) cluster->count >= threshold))
+ {
+ /*
+ Initialize cluster.
+ */
+ cluster->id=count;
+ cluster->red.center=(cluster->red.center/((double) cluster->count));
+ cluster->green.center=(cluster->green.center/((double) cluster->count));
+ cluster->blue.center=(cluster->blue.center/((double) cluster->count));
+ count++;
+ last_cluster=cluster;
+ }
+ else
+ {
+ /*
+ Delete cluster.
+ */
+ if (cluster == head)
+ head=next_cluster;
+ else
+ last_cluster->next=next_cluster;
+
+ if (image->logging)
+ (void) LogMagickEvent
+ (TransformEvent,GetMagickModule(),
+ "Removing Cluster (usage count %lu, %.5f%%) %d-%d %d-%d %d-%d",
+ (unsigned long) cluster->count,
+ (((double) cluster->count/total_vectors) * 100.0),
+ cluster->red.left,cluster->red.right,
+ cluster->green.left,cluster->green.right,
+ cluster->blue.left,cluster->blue.right);
+ MagickFreeMemory(cluster);
+ }
+ }
+ number_clusters=count;
+ if (verbose && (head != (Cluster *) NULL))
+ {
+ /*
+ Print cluster statistics.
+ */
+ (void) fprintf(stdout,"===============================================\n");
+ (void) fprintf(stdout," Fuzzy c-Means Statistics\n");
+ (void) fprintf(stdout,"===============================================\n");
+ (void) fprintf(stdout,"Cluster Threshold = %g%%\n", cluster_threshold);
+ (void) fprintf(stdout,"Weighting Exponent = %g\n", weighting_exponent);
+ (void) fprintf(stdout,"Total Number of Clusters = %lu\n",
+ number_clusters);
+ (void) fprintf(stdout,"Total Number of Vectors = %g\n",
+ total_vectors);
+ (void) fprintf(stdout,"Cluster Threshold = %g vectors\n\n",
+ threshold);
+ /*
+ Print the total number of points per cluster.
+ */
+ (void) fprintf(stdout,"Cluster Usage Extents Center\n");
+ (void) fprintf(stdout,"======= ==================== ======================= =====================\n");
+ for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next)
+ {
+ PixelPacket
+ color;
+
+ char
+ tuple[MaxTextExtent];
+
+ color.red=ScaleCharToQuantum((unsigned int) (cluster->red.center + 0.5));
+ color.green=ScaleCharToQuantum((unsigned int) (cluster->green.center + 0.5));
+ color.blue=ScaleCharToQuantum((unsigned int) (cluster->blue.center + 0.5));
+ color.opacity=OpaqueOpacity;
+ /* (void) QueryColorname(image,&color,X11Compliance,colorname,&image->exception); */
+ GetColorTuple(&color,8,MagickFalse,MagickTrue,tuple);
+ (void) fprintf(stdout," %3d %10lu (%6.3f%%) %03d-%03d %03d-%03d %03d-%03d %03.0f %03.0f %03.0f (%s)\n",
+ cluster->id,
+ (unsigned long) cluster->count,
+ (((double) cluster->count/total_vectors) * 100.0),
+ cluster->red.left,cluster->red.right,
+ cluster->green.left,cluster->green.right,
+ cluster->blue.left,cluster->blue.right,
+ cluster->red.center,
+ cluster->green.center,
+ cluster->blue.center,
+ tuple);
+ }
+ }
+ if ((number_clusters > 256) || (number_clusters == 0))
+ {
+ ThrowException3(&image->exception,ImageError,UnableToSegmentImage,TooManyClusters);
+ goto classify_error_exit;
+ }
+ /*
+ Speed up distance calculations.
+ */
+ squares_array=MagickAllocateMemory(double *,513*sizeof(double));
+ if (squares_array == (double *) NULL)
+ {
+ ThrowException(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,image->filename);
+ goto classify_error_exit;
+ }
+ squares=squares_array+255;
+#if defined(HAVE_OPENMP)
+# pragma omp parallel for
+#endif
+ for (i=(-255); i <= 255; i++)
+ squares[i]=i*i;
+ /*
+ Allocate image colormap.
+ */
+ colormap=MagickAllocateMemory(PixelPacket *,number_clusters*sizeof(PixelPacket));
+ if (colormap == (PixelPacket *) NULL)
+ {
+ ThrowException(&image->exception,ResourceLimitError,
+ MemoryAllocationFailed,image->filename);
+ goto classify_error_exit;
+ }
+ image->matte=False;
+ image->storage_class=PseudoClass;
+ MagickFreeMemory(image->colormap);
+ image->colormap=colormap;
+ image->colors=number_clusters;
+ i=0;
+ for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next)
+ {
+ image->colormap[i].red=ScaleCharToQuantum((unsigned int) (cluster->red.center + 0.5));
+ image->colormap[i].green=ScaleCharToQuantum((unsigned int) (cluster->green.center + 0.5));
+ image->colormap[i].blue=ScaleCharToQuantum((unsigned int) (cluster->blue.center + 0.5));
+ image->colormap[i].opacity=OpaqueOpacity;
+ i++;
+ }
+ /*
+ Rebuild cluster array.
+ */
+ number_clusters=0;
+ for (cluster=head; cluster != (Cluster *) NULL; cluster=cluster->next)
+ cluster_array[number_clusters++]=cluster;
+ /*
+ Do course grain storage_class.
+ */
+ row_count=0;
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status) private(count,indexes,p,q,x)
+# else
+# pragma omp parallel for schedule(static,8) shared(row_count, status) private(count,indexes,p,q,x)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ MagickBool
+ thread_status;
+
+ int
+ num_threads;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_Classify)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ num_threads=omp_get_num_threads();
+ q=GetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+ if (q == (PixelPacket *) NULL)
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ MagickBool
+ classified=MagickFalse;
+
+ long
+ r,
+ g,
+ b;
+
+ r=(long) ScaleQuantumToChar(q[x].red);
+ g=(long) ScaleQuantumToChar(q[x].green);
+ b=(long) ScaleQuantumToChar(q[x].blue);
+
+ for (count=0; count < number_clusters; count++)
+ if ((r >= (cluster_array[count]->red.left-SafeMargin)) &&
+ (r <= (cluster_array[count]->red.right+SafeMargin)) &&
+ (g >= (cluster_array[count]->green.left-SafeMargin)) &&
+ (g <= (cluster_array[count]->green.right+SafeMargin)) &&
+ (b >= (cluster_array[count]->blue.left-SafeMargin)) &&
+ (b <= (cluster_array[count]->blue.right+SafeMargin)))
+ {
+ /*
+ Classify this pixel.
+ */
+ indexes[x]=(IndexPacket) cluster_array[count]->id;
+ q[x]=image->colormap[indexes[x]];
+ classified=MagickTrue;
+
+ /*
+ Re-sort array so that most frequent occurs first.
+
+ Updating cluster_array causes a multithread race
+ condition so this chunk is only enabled in the
+ case of one thread.
+ */
+ if ((num_threads == 1) && (count > 0) &&
+ (cluster_array[count]->count > cluster_array[count-1]->count))
+ {
+ Cluster
+ *tmp_cluster;
+
+ tmp_cluster=cluster_array[count-1];
+ cluster_array[count-1]=cluster_array[count];
+ cluster_array[count]=tmp_cluster;
+ }
+
+ break;
+ }
+ if (classified == MagickFalse)
+ {
+ double
+ local_minima,
+ sum;
+
+ long
+ j,
+ k;
+
+ /*
+ Compute fuzzy membership.
+ */
+ local_minima=0.0;
+ for (j=0; j < (long) image->colors; j++)
+ {
+ double
+ distance_squared,
+ numerator,
+ ratio_squared;
+
+ sum=0.0;
+ p=image->colormap+j;
+ distance_squared=
+ squares[r-(long) ScaleQuantumToChar(p->red)]+
+ squares[g-(long) ScaleQuantumToChar(p->green)]+
+ squares[b-(long) ScaleQuantumToChar(p->blue)];
+ numerator=distance_squared;
+ for (k=0; k < (long) image->colors; k++)
+ {
+ p=image->colormap+k;
+ distance_squared=
+ squares[r-(long) ScaleQuantumToChar(p->red)]+
+ squares[g-(long) ScaleQuantumToChar(p->green)]+
+ squares[b-(long) ScaleQuantumToChar(p->blue)];
+ ratio_squared=numerator/distance_squared;;
+#if SquaredClassify
+ /*
+ Since SquaredClassify (using a weighting
+ exponent of 2.0) is normally defined to be
+ true, this is the normally active code.
+ Otherwise execution is even slower since
+ pow() is excruciatingly slow.
+ */
+ sum+=ratio_squared;
+#else
+ sum+=pow(ratio_squared,((double) (1.0/(weighting_exponent-1.0))));
+#endif
+ }
+ if ((sum != 0.0) && ((1.0/sum) > local_minima))
+ {
+ /*
+ Classify this pixel.
+ */
+ local_minima=1.0/sum;
+ indexes[x]=(IndexPacket) j;
+ q[x]=image->colormap[indexes[x]];
+ }
+ }
+ }
+ }
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_Classify)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count+image->rows,image->rows << 1,
+ &image->exception,
+ SegmentImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ /*
+ Free memory.
+ */
+ classify_error_exit:
+ for (cluster=head; cluster != (Cluster *) NULL; cluster=next_cluster)
+ {
+ next_cluster=cluster->next;
+ MagickFreeMemory(cluster);
+ head=(Cluster *) NULL;
+ }
+ MagickFreeMemory(cluster_array);
+ MagickFreeMemory(squares_array);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C o n s o l i d a t e C r o s s i n g s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Method ConsolidateCrossings guarantees that an even number of zero
+% crossings always lie between two crossings.
+%
+% The format of the ConsolidateCrossings method is:
+%
+% ConsolidateCrossings(zero_crossing,number_crossings)
+%
+% A description of each parameter follows.
+%
+% o zero_crossing: Specifies an array of structures of type ZeroCrossing.
+%
+% o number_crossings: This unsigned int specifies the number of elements
+% in the zero_crossing array.
+%
+%
+*/
+static void
+ConsolidateCrossings(ZeroCrossing *zero_crossing,
+ const unsigned int number_crossings)
+{
+ int
+ center,
+ correct,
+ count,
+ left,
+ right;
+
+ register long
+ i,
+ j,
+ k,
+ l;
+
+ /*
+ Consolidate zero crossings.
+ */
+ for (i=(long) number_crossings-1; i >= 0; i--)
+ for (j=0; j <= 255; j++)
+ {
+ if (zero_crossing[i].crossings[j] == 0)
+ continue;
+ /*
+ Find the entry that is closest to j and still preserves the
+ property that there are an even number of crossings between
+ intervals.
+ */
+ for (k=j-1; k > 0; k--)
+ if (zero_crossing[i+1].crossings[k] != 0)
+ break;
+ left=Max(k,0);
+ center=j;
+ for (k=j+1; k < 255; k++)
+ if (zero_crossing[i+1].crossings[k] != 0)
+ break;
+ right=Min(k,255);
+ /*
+ K is the zero crossing just left of j.
+ */
+ for (k=j-1; k > 0; k--)
+ if (zero_crossing[i].crossings[k] != 0)
+ break;
+ if (k < 0)
+ k=0;
+ /*
+ Check center for an even number of crossings between k and j.
+ */
+ correct=(-1);
+ if (zero_crossing[i+1].crossings[j] != 0)
+ {
+ count=0;
+ for (l=k+1; l < center; l++)
+ if (zero_crossing[i+1].crossings[l] != 0)
+ count++;
+ if ((count % 2) == 0)
+ if (center != k)
+ correct=center;
+ }
+ /*
+ Check left for an even number of crossings between k and j.
+ */
+ if (correct == -1)
+ {
+ count=0;
+ for (l=k+1; l < left; l++)
+ if (zero_crossing[i+1].crossings[l] != 0)
+ count++;
+ if ((count % 2) == 0)
+ if (left != k)
+ correct=left;
+ }
+ /*
+ Check right for an even number of crossings between k and j.
+ */
+ if (correct == -1)
+ {
+ count=0;
+ for (l=k+1; l < right; l++)
+ if (zero_crossing[i+1].crossings[l] != 0)
+ count++;
+ if ((count % 2) == 0)
+ if (right != k)
+ correct=right;
+ }
+ l=zero_crossing[i].crossings[j];
+ zero_crossing[i].crossings[j]=0;
+ if (correct != -1)
+ zero_crossing[i].crossings[correct]=(short) l;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e f i n e R e g i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Method DefineRegion defines the left and right boundaries of a peak
+% region.
+%
+% The format of the DefineRegion method is:
+%
+% int DefineRegion(const short *extrema,ExtentPacket *extents)
+%
+% A description of each parameter follows.
+%
+% o extrema: Specifies a pointer to an array of integers. They
+% represent the peaks and valleys of the histogram for each color
+% component.
+%
+% o extents: This pointer to an ExtentPacket represent the extends
+% of a particular peak or valley of a color component.
+%
+%
+*/
+static int
+DefineRegion(const short *extrema,ExtentPacket *extents)
+{
+ /*
+ Initialize to default values.
+ */
+ extents->left=0;
+ extents->center=0;
+ extents->right=255;
+ /*
+ Find the left side (maxima).
+ */
+ for ( ; extents->index <= 255; extents->index++)
+ if (extrema[extents->index] > 0)
+ break;
+ if (extents->index > 255)
+ return(False); /* no left side - no region exists */
+ extents->left=extents->index;
+ /*
+ Find the right side (minima).
+ */
+ for ( ; extents->index <= 255; extents->index++)
+ if (extrema[extents->index] < 0)
+ break;
+ extents->right=extents->index-1;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e r i v a t i v e H i s t o g r a m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Method DerivativeHistogram determines the derivative of the histogram
+% using central differencing.
+%
+% The format of the DerivativeHistogram method is:
+%
+% DerivativeHistogram(const double *histogram,double *derivative
+%
+% A description of each parameter follows.
+%
+% o histogram: Specifies an array of doubles representing the number of
+% pixels for each intensity of a particular color component.
+%
+% o derivative: This array of doubles is initialized by DerivativeHistogram
+% to the derivative of the histogram using central differencing.
+%
+%
+*/
+static void
+DerivativeHistogram(const double *histogram,double *derivative)
+{
+ register long
+ i,
+ n;
+
+ /*
+ Compute endpoints using second order polynomial interpolation.
+ */
+ n=255;
+ derivative[0]=(-1.5*histogram[0]+2.0*histogram[1]-0.5*histogram[2]);
+ derivative[n]=(0.5*histogram[n-2]-2.0*histogram[n-1]+1.5*histogram[n]);
+ /*
+ Compute derivative using central differencing.
+ */
+ for (i=1; i < n; i++)
+ derivative[i]=((double) histogram[i+1]-histogram[i-1])/2.0;
+ return;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e H i s t o g r a m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeHistogram computes the histogram for an image.
+%
+% The format of the InitializeHistogram method is:
+%
+% InitializeHistogram(Image *image,long **histogram)
+%
+% A description of each parameter follows.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o histogram: Specifies an array of integers representing the number
+% of pixels for each intensity of a particular color component.
+%
+%
+*/
+static void
+InitializeHistogram(Image *image,long **histogram)
+{
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ /*
+ Initialize histogram.
+ */
+ for (i=0; i <= 255; i++)
+ {
+ histogram[Red][i]=0;
+ histogram[Green][i]=0;
+ histogram[Blue][i]=0;
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ histogram[Red][ScaleQuantumToChar(p->red)]++;
+ histogram[Green][ScaleQuantumToChar(p->green)]++;
+ histogram[Blue][ScaleQuantumToChar(p->blue)]++;
+ p++;
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e I n t e r v a l T r e e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Method InitializeIntervalTree initializes an interval tree from the
+% lists of zero crossings.
+%
+% The format of the InitializeIntervalTree method is:
+%
+% InitializeIntervalTree(const ZeroCrossing *zero_crossing,
+% const unsigned int number_crossings)
+%
+% A description of each parameter follows.
+%
+% o zero_crossing: Specifies an array of structures of type ZeroCrossing.
+%
+% o number_crossings: This unsigned int specifies the number of elements
+% in the zero_crossing array.
+%
+%
+*/
+
+static void
+InitializeList(IntervalTree **list,int *number_nodes,IntervalTree *node)
+{
+ if (node == (IntervalTree *) NULL)
+ return;
+ if (node->child == (IntervalTree *) NULL)
+ list[(*number_nodes)++]=node;
+ InitializeList(list,number_nodes,node->sibling);
+ InitializeList(list,number_nodes,node->child);
+}
+
+static void
+MeanStability(register IntervalTree *node)
+{
+ register IntervalTree
+ *child;
+
+ if (node == (IntervalTree *) NULL)
+ return;
+ node->mean_stability=0.0;
+ child=node->child;
+ if (child != (IntervalTree *) NULL)
+ {
+ register double
+ sum;
+
+ register long
+ count;
+
+ sum=0.0;
+ count=0;
+ for ( ; child != (IntervalTree *) NULL; child=child->sibling)
+ {
+ sum+=child->stability;
+ count++;
+ }
+ node->mean_stability=sum/count;
+ }
+ MeanStability(node->sibling);
+ MeanStability(node->child);
+}
+
+static void Stability(register IntervalTree *node)
+{
+ if (node == (IntervalTree *) NULL)
+ return;
+ if (node->child == (IntervalTree *) NULL)
+ node->stability=0.0;
+ else
+ node->stability=node->tau-(node->child)->tau;
+ Stability(node->sibling);
+ Stability(node->child);
+}
+
+static IntervalTree *
+InitializeIntervalTree(const ZeroCrossing *zero_crossing,
+ const unsigned int number_crossings)
+{
+ int
+ left,
+ number_nodes;
+
+ IntervalTree
+ *head,
+ **list,
+ *node,
+ *root;
+
+ register long
+ i,
+ j,
+ k;
+
+ /*
+ Allocate interval tree.
+ */
+ list=MagickAllocateMemory(IntervalTree **,TreeLength*sizeof(IntervalTree *));
+ if (list == (IntervalTree **) NULL)
+ return((IntervalTree *) NULL);
+ /*
+ The root is the entire histogram.
+ */
+ root=MagickAllocateMemory(IntervalTree *,sizeof(IntervalTree));
+ root->child=(IntervalTree *) NULL;
+ root->sibling=(IntervalTree *) NULL;
+ root->tau=0.0;
+ root->left=0;
+ root->right=255;
+ for (i=(-1); i < (long) number_crossings; i++)
+ {
+ /*
+ Initialize list with all nodes with no children.
+ */
+ number_nodes=0;
+ InitializeList(list,&number_nodes,root);
+ /*
+ Split list.
+ */
+ for (j=0; j < number_nodes; j++)
+ {
+ head=list[j];
+ left=head->left;
+ node=head;
+ for (k=head->left+1; k < head->right; k++)
+ {
+ if (zero_crossing[i+1].crossings[k] != 0)
+ {
+ if (node == head)
+ {
+ node->child=MagickAllocateMemory(IntervalTree *,
+ sizeof(IntervalTree));
+ node=node->child;
+ }
+ else
+ {
+ node->sibling=MagickAllocateMemory(IntervalTree *,
+ sizeof(IntervalTree));
+ node=node->sibling;
+ }
+ node->tau=zero_crossing[i+1].tau;
+ node->child=(IntervalTree *) NULL;
+ node->sibling=(IntervalTree *) NULL;
+ node->left=left;
+ node->right=k;
+ left=k;
+ }
+ }
+ if (left != head->left)
+ {
+ node->sibling=MagickAllocateMemory(IntervalTree *,sizeof(IntervalTree));
+ node=node->sibling;
+ node->tau=zero_crossing[i+1].tau;
+ node->child=(IntervalTree *) NULL;
+ node->sibling=(IntervalTree *) NULL;
+ node->left=left;
+ node->right=head->right;
+ }
+ }
+ }
+ /*
+ Determine the stability: difference between a nodes tau and its child.
+ */
+ Stability(root->child);
+ MeanStability(root->child);
+ MagickFreeMemory(list);
+ return(root);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ O p t i m a l T a u %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Method OptimalTau finds the optimal tau for each band of the histogram.
+%
+% The format of the OptimalTau method is:
+%
+% double OptimalTau(const long *histogram,const double max_tau,
+% const double min_tau,const double delta_tau,
+% const double smoothing_threshold,
+% short *extrema)
+%
+% A description of each parameter follows.
+%
+% o histogram: Specifies an array of integers representing the number
+% of pixels for each intensity of a particular color component.
+%
+% o max_tau: (current 5.2f)
+%
+% o min_tau: (current 0.2)
+%
+% o delta_tau: (current 0.5f)
+%
+% o smoothing_threshold: If the absolute value of a second derivative
+% point is less than smoothing_threshold then that derivative point
+% is ignored (i.e. set to 0) while evaluating zero crossings. This
+% causes small variations (could be noise) to be ignored.
+%
+% o extrema: Specifies a pointer to an array of integers. They
+% represent the peaks and valleys of the histogram for each color
+% component.
+%
+%
+*/
+
+static void
+ActiveNodes(IntervalTree **list,int *number_nodes,IntervalTree *node)
+{
+ if (node == (IntervalTree *) NULL)
+ return;
+ if (node->stability >= node->mean_stability)
+ {
+ list[(*number_nodes)++]=node;
+ ActiveNodes(list,number_nodes,node->sibling);
+ }
+ else
+ {
+ ActiveNodes(list,number_nodes,node->sibling);
+ ActiveNodes(list,number_nodes,node->child);
+ }
+}
+
+static void
+FreeNodes(IntervalTree *node)
+{
+ if (node == (IntervalTree *) NULL)
+ return;
+ FreeNodes(node->sibling);
+ FreeNodes(node->child);
+ MagickFreeMemory(node);
+}
+
+static double
+OptimalTau(const long *histogram,const double max_tau,
+ const double min_tau,const double delta_tau,
+ const double smoothing_threshold,
+ short *extrema)
+{
+ double
+ average_tau,
+ *derivative,
+ *second_derivative,
+ tau,
+ value;
+
+ int
+ index,
+ number_nodes,
+ peak,
+ x;
+
+ IntervalTree
+ **list,
+ *node,
+ *root;
+
+ register long
+ i,
+ j,
+ k;
+
+ unsigned long
+ count,
+ number_crossings;
+
+ ZeroCrossing
+ *zero_crossing;
+
+ /*
+ Allocate interval tree.
+ */
+ list=MagickAllocateMemory(IntervalTree **,TreeLength*sizeof(IntervalTree *));
+ if (list == (IntervalTree **) NULL)
+ return(0.0);
+ /*
+ Allocate zero crossing list.
+ */
+ count=(unsigned long) ((max_tau-min_tau)/delta_tau)+2;
+ zero_crossing=MagickAllocateMemory(ZeroCrossing *,count*sizeof(ZeroCrossing));
+ if (zero_crossing == (ZeroCrossing *) NULL)
+ return(0.0);
+ for (i=0; i < (long) count; i++)
+ zero_crossing[i].tau=(-1);
+ /*
+ Initialize zero crossing list.
+ */
+ derivative=MagickAllocateMemory(double *,256*sizeof(double));
+ second_derivative=MagickAllocateMemory(double *,256*sizeof(double));
+ if ((derivative == (double *) NULL) || (second_derivative == (double *) NULL))
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateDerivatives);
+ i=0;
+ for (tau=max_tau; tau >= min_tau; tau-=delta_tau)
+ {
+ zero_crossing[i].tau=tau;
+ ScaleSpace(histogram,tau,zero_crossing[i].histogram);
+ DerivativeHistogram(zero_crossing[i].histogram,derivative);
+ DerivativeHistogram(derivative,second_derivative);
+ ZeroCrossHistogram(second_derivative,smoothing_threshold,
+ zero_crossing[i].crossings);
+ i++;
+ }
+ /*
+ Add an entry for the original histogram.
+ */
+ zero_crossing[i].tau=0.0;
+ for (j=0; j <= 255; j++)
+ zero_crossing[i].histogram[j]=(double) histogram[j];
+ DerivativeHistogram(zero_crossing[i].histogram,derivative);
+ DerivativeHistogram(derivative,second_derivative);
+ ZeroCrossHistogram(second_derivative,smoothing_threshold,
+ zero_crossing[i].crossings);
+ number_crossings=i;
+ MagickFreeMemory(derivative);
+ MagickFreeMemory(second_derivative);
+ /*
+ Ensure the scale-space fingerprints form lines in scale-space, not loops.
+ */
+ ConsolidateCrossings(zero_crossing,number_crossings);
+ /*
+ Force endpoints to be included in the interval.
+ */
+ for (i=0; i <= (long) number_crossings; i++)
+ {
+ for (j=0; j < 255; j++)
+ if (zero_crossing[i].crossings[j] != 0)
+ break;
+ zero_crossing[i].crossings[0]=(-zero_crossing[i].crossings[j]);
+ for (j=255; j > 0; j--)
+ if (zero_crossing[i].crossings[j] != 0)
+ break;
+ zero_crossing[i].crossings[255]=
+ (-zero_crossing[i].crossings[j]);
+ }
+ /*
+ Initialize interval tree.
+ */
+ root=InitializeIntervalTree(zero_crossing,number_crossings);
+ if (root == (IntervalTree *) NULL)
+ return(0.0);
+ /*
+ Find active nodes: stability is greater (or equal) to the mean stability of
+ its children.
+ */
+ number_nodes=0;
+ ActiveNodes(list,&number_nodes,root->child);
+ /*
+ Initialize extrema.
+ */
+ for (i=0; i <= 255; i++)
+ extrema[i]=0;
+ for (i=0; i < number_nodes; i++)
+ {
+ /*
+ Find this tau in zero crossings list.
+ */
+ k=0;
+ node=list[i];
+ for (j=0; j <= (long) number_crossings; j++)
+ if (zero_crossing[j].tau == node->tau)
+ k=j;
+ /*
+ Find the value of the peak.
+ */
+ peak=zero_crossing[k].crossings[node->right] == -1;
+ index=node->left;
+ value=zero_crossing[k].histogram[index];
+ for (x=node->left; x <= node->right; x++)
+ {
+ if (peak)
+ {
+ if (zero_crossing[k].histogram[x] > value)
+ {
+ value=zero_crossing[k].histogram[x];
+ index=x;
+ }
+ }
+ else
+ if (zero_crossing[k].histogram[x] < value)
+ {
+ value=zero_crossing[k].histogram[x];
+ index=x;
+ }
+ }
+ for (x=node->left; x <= node->right; x++)
+ {
+ if (index == 0)
+ index=256;
+ if (peak)
+ extrema[x]=index;
+ else
+ extrema[x]=(-index);
+ }
+ }
+ /*
+ Determine the average tau.
+ */
+ average_tau=0.0;
+ for (i=0; i < number_nodes; i++)
+ average_tau+=list[i]->tau;
+ average_tau/=(double) number_nodes;
+ /*
+ Free memory.
+ */
+ FreeNodes(root);
+ MagickFreeMemory(zero_crossing);
+ MagickFreeMemory(list);
+ return(average_tau);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S c a l e S p a c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Method ScaleSpace performs a scale-space filter on the 1D histogram.
+%
+% The format of the ScaleSpace method is:
+%
+% ScaleSpace(const long *histogram,const double tau,
+% double *scaled_histogram)
+%
+% A description of each parameter follows.
+%
+% o histogram: Specifies an array of doubles representing the number of
+% pixels for each intensity of a particular color component.
+%
+% o tau:
+%
+% o scaled_histogram:
+%
+*/
+static void
+ScaleSpace(const long *histogram,const double tau,double *scaled_histogram)
+{
+ double
+ alpha,
+ beta,
+ *gamma,
+ sum;
+
+ register long
+ u,
+ x;
+
+ gamma=MagickAllocateMemory(double *,256*sizeof(double));
+ if (gamma == (double *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateGammaMap);
+ alpha=1.0/(tau*sqrt(2.0*MagickPI));
+ beta=(-1.0/(2.0*tau*tau));
+ for (x=0; x <= 255; x++)
+ gamma[x]=0.0;
+ for (x=0; x <= 255; x++)
+ {
+ gamma[x]=exp(beta*x*x);
+ if (gamma[x] < MagickEpsilon)
+ break;
+ }
+ for (x=0; x <= 255; x++)
+ {
+ sum=0.0;
+ for (u=0; u <= 255; u++)
+ sum+=(double) histogram[u]*gamma[AbsoluteValue(x-u)];
+ scaled_histogram[x]=alpha*sum;
+ }
+ MagickFreeMemory(gamma);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ Z e r o C r o s s H i s t o g r a m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% Method ZeroCrossHistogram find the zero crossings in a histogram and
+% marks directions as: 1 is negative to positive; 0 is zero crossing; and
+% -1 is positive to negative.
+%
+% The format of the ZeroCrossHistogram method is:
+%
+% ZeroCrossHistogram(double *second_derivative,
+% const double smoothing_threshold,short *crossings)
+%
+% A description of each parameter follows.
+%
+% o second_derivative: Specifies an array of doubles representing the
+% second derivative of the histogram of a particular color component.
+%
+% o smoothing_threshold: If the absolute value of a second derivative
+% point is less than smoothing_threshold then that derivative point
+% is ignored (i.e. set to 0) while evaluating zero crossings. This
+% causes small variations (could be noise) to be ignored.
+%
+% o crossings: This array of integers is initialized with
+% -1, 0, or 1 representing the slope of the first derivative of the
+% of a particular color component.
+%
+%
+*/
+static void
+ZeroCrossHistogram(double *second_derivative,const double smoothing_threshold,
+ short *crossings)
+{
+ int
+ parity;
+
+ register long
+ i;
+
+ /*
+ Merge low numbers to zero to help prevent noise.
+ */
+ for (i=0; i <= 255; i++)
+ if ((second_derivative[i] < smoothing_threshold) &&
+ (second_derivative[i] >= -smoothing_threshold))
+ second_derivative[i]=0.0;
+ /*
+ Mark zero crossings.
+ */
+ parity=0;
+ for (i=0; i <= 255; i++)
+ {
+ crossings[i]=0;
+ if (second_derivative[i] < 0.0)
+ {
+ if (parity > 0)
+ crossings[i]=(-1);
+ parity=1;
+ }
+ else
+ if (second_derivative[i] > 0.0)
+ {
+ if (parity < 0)
+ crossings[i]=1;
+ parity=(-1);
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e g m e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SegmentImage segment an image by analyzing the histograms of the
+% color components and identifying units that are homogeneous with the fuzzy
+% c-means technique.
+%
+% Specify cluster threshold as the number of pixels in each cluster must
+% exceed the the cluster threshold to be considered valid. Smoothing
+% threshold eliminates noise in the second derivative of the histogram.
+% As the value is increased, you can expect a smoother second derivative.
+% The default is 1.5.
+%
+% The format of the SegmentImage method is:
+%
+% MagickPassFail SegmentImage(Image *image,const ColorspaceType colorspace,
+% const unsigned int verbose,const double cluster_threshold,
+% const double smoothing_threshold)
+%
+% A description of each parameter follows.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o colorspace: An unsigned integer value that indicates the colorspace.
+% Empirical evidence suggests that distances in YUV or YIQ correspond to
+% perceptual color differences more closely than do distances in RGB
+% space. The image is then returned to RGB colorspace after color
+% reduction.
+%
+% o verbose: A value greater than zero prints detailed information about
+% the identified classes.
+%
+% o cluster_threshold: The minimum number of total pixels contained
+% in a hexahedra before it can be considered valid (expressed as a
+% percentage of total pixels). This is used to eliminate seldom
+% used colors.
+%
+% o smoothing_threshold: If the absolute value of a second derivative
+% point is less than smoothing_threshold then that derivative point
+% is ignored (i.e. set to 0) while evaluating zero crossings. This
+% causes small variations (could be noise) to be ignored.
+%
+*/
+MagickExport MagickPassFail
+SegmentImage(Image *image,
+ const ColorspaceType colorspace,
+ const unsigned int verbose,
+ const double cluster_threshold,
+ const double smoothing_threshold)
+{
+
+ long
+ *histogram[MaxDimension];
+
+ register long
+ i;
+
+ short
+ *extrema[MaxDimension];
+
+ MagickPassFail
+ status;
+
+ /*
+ Allocate histogram and extrema.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ for (i=0; i < MaxDimension; i++)
+ {
+ histogram[i]=MagickAllocateMemory(long *,256*sizeof(long));
+ extrema[i]=MagickAllocateMemory(short *,256*sizeof(short));
+ if ((histogram[i] == (long *) NULL) || (extrema[i] == (short *) NULL))
+ {
+ for (i-- ; i >= 0; i--)
+ {
+ MagickFreeMemory(extrema[i]);
+ MagickFreeMemory(histogram[i]);
+ }
+ ThrowBinaryException(ResourceLimitError,MemoryAllocationFailed,
+ image->filename);
+ }
+ }
+ (void) TransformColorspace(image,colorspace);
+ /*
+ Initialize histogram.
+ */
+ InitializeHistogram(image,histogram);
+ (void) OptimalTau(histogram[Red],Tau,0.2,DeltaTau,smoothing_threshold,
+ extrema[Red]);
+ (void) OptimalTau(histogram[Green],Tau,0.2,DeltaTau,smoothing_threshold,
+ extrema[Green]);
+ (void) OptimalTau(histogram[Blue],Tau,0.2,DeltaTau,smoothing_threshold,
+ extrema[Blue]);
+ if (verbose > 1)
+ {
+ FILE
+ *stream;
+
+ stream=stdout;
+
+ fprintf(stream,"Red Histogram:\n");
+ DumpHistogramArray(stream,256,histogram[Red]);
+ fprintf(stream,"Green Histogram:\n");
+ DumpHistogramArray(stream,256,histogram[Green]);
+ fprintf(stream,"Blue Histogram:\n");
+ DumpHistogramArray(stream,256,histogram[Blue]);
+
+ fprintf(stream,"Red Extrema:\n");
+ DumpExtremaArray(stream,256,extrema[Red]);
+ fprintf(stream,"Green Extrema:\n");
+ DumpExtremaArray(stream,256,extrema[Green]);
+ fprintf(stream,"Blue Extrema:\n");
+ DumpExtremaArray(stream,256,extrema[Blue]);
+ }
+ /*
+ Classify using the fuzzy c-Means technique.
+ */
+ status=Classify(image,extrema,cluster_threshold,(double)WeightingExponent,verbose);
+ (void) TransformColorspace(image,RGBColorspace);
+ /*
+ Free memory.
+ */
+ for (i=0; i < MaxDimension; i++)
+ {
+ MagickFreeMemory(extrema[i]);
+ MagickFreeMemory(histogram[i]);
+ }
+ return(status);
+}
diff --git a/magick/semaphore.c b/magick/semaphore.c
new file mode 100644
index 0000000..bccfe6b
--- /dev/null
+++ b/magick/semaphore.c
@@ -0,0 +1,651 @@
+/*
+% Copyright (C) 2003-2012 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% SSSSS EEEEE M M AAA PPPP H H OOO RRRR EEEEE %
+% SS E MM MM A A P P H H O O R R E %
+% SSS EEE M M M AAAAA PPPP HHHHH O O RRRR EEE %
+% SS E M M A A P H H O O R R E %
+% SSSSS EEEEE M M A A P H H OOO R R EEEEE %
+% %
+% %
+% GraphicsMagick Semaphore Methods %
+% %
+% %
+% Software Design %
+% William Radcliffe %
+% John Cristy %
+% June 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/utility.h"
+
+#if defined(HAVE_PTHREAD)
+# define USE_PTHREAD_LOCKS 1
+#elif defined(MSWINDOWS)
+# define USE_WIN32_LOCKS 1
+#elif defined(HAVE_OPENMP)
+# define USE_OPENMP_LOCKS 1
+#endif
+
+#if defined(USE_PTHREAD_LOCKS)
+# include <pthread.h>
+# define PTHREAD_MUTEX_DESTROY(semaphore_mutex) \
+ { \
+ int \
+ err_status; \
+ \
+ if ((err_status = pthread_mutex_destroy(semaphore_mutex)) != 0) \
+ { \
+ errno=err_status; \
+ MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
+ UnableToDestroySemaphore); \
+ } \
+ }
+# define PTHREAD_MUTEXATTR_DESTROY(mutexattr) \
+ { \
+ int \
+ err_status; \
+ \
+ if ((err_status = pthread_mutexattr_destroy(mutexattr)) != 0) \
+ { \
+ errno=err_status; \
+ MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
+ UnableToDestroySemaphore); \
+ } \
+ }
+# define PTHREAD_MUTEXATTR_INIT(mutexattr) \
+ { \
+ int \
+ err_status; \
+ \
+ if ((err_status = pthread_mutexattr_init(mutexattr)) != 0) \
+ { \
+ errno=err_status; \
+ MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
+ UnableToInitializeSemaphore); \
+ } \
+ }
+# define PTHREAD_MUTEXATTR_SETTYPE(mutexattr,mutexattrtype) \
+ { \
+ int \
+ err_status; \
+ \
+ if ((err_status = pthread_mutexattr_settype(mutexattr,mutexattrtype)) != 0) \
+ { \
+ errno=err_status; \
+ MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
+ UnableToInitializeSemaphore); \
+ } \
+ }
+# define PTHREAD_MUTEX_INIT(semaphore_mutex,mutexattr) \
+ { \
+ int \
+ err_status; \
+ \
+ if ((err_status = pthread_mutex_init(semaphore_mutex,mutexattr)) != 0) \
+ { \
+ errno=err_status; \
+ MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
+ UnableToInitializeSemaphore); \
+ } \
+ }
+# define PTHREAD_MUTEX_LOCK(semaphore_mutex) \
+ { \
+ int \
+ err_status; \
+ \
+ if ((err_status = pthread_mutex_lock(semaphore_mutex)) != 0) \
+ { \
+ errno=err_status; \
+ MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
+ UnableToLockSemaphore); \
+ } \
+ }
+# define PTHREAD_MUTEX_UNLOCK(semaphore_mutex) \
+ { \
+ int \
+ err_status; \
+ \
+ if ((err_status = pthread_mutex_unlock(semaphore_mutex)) != 0) \
+ { \
+ errno=err_status; \
+ MagickFatalError3(ResourceLimitFatalError,SemaporeOperationFailed, \
+ UnableToUnlockSemaphore); \
+ } \
+ }
+#endif
+
+#if defined(USE_WIN32_LOCKS)
+# include <windows.h>
+# define USE_SPINLOCKS
+# define SPINLOCK_DELAY_MILLI_SECS 10
+#endif
+
+#include "magick/semaphore.h"
+
+/*
+ Struct declaractions.
+*/
+struct _SemaphoreInfo
+{
+#if defined(USE_OPENMP_LOCKS)
+ omp_lock_t
+ mutex; /* OpenMP lock */
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ pthread_mutex_t
+ mutex; /* POSIX thread mutex */
+#endif /* if defined(USE_PTHREAD_LOCKS) */
+#if defined(USE_WIN32_LOCKS)
+ CRITICAL_SECTION
+ mutex; /* Windows critical section */
+#endif /* defined(USE_WIN32_LOCKS) */
+
+ unsigned long
+ signature; /* Used to validate structure */
+};
+
+/*
+ Static declaractions.
+*/
+#if defined(USE_OPENMP_LOCKS)
+static omp_lock_t
+ semaphore_mutex;
+
+static unsigned int
+ active_semaphore = MagickFalse;
+#endif /* defined(USE_OPENMP_LOCKS) */
+
+#if defined(USE_PTHREAD_LOCKS)
+static pthread_mutex_t
+ semaphore_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif /* defined(USE_PTHREAD_LOCKS) */
+
+#if defined(USE_WIN32_LOCKS)
+#if !defined(USE_SPINLOCKS)
+static CRITICAL_SECTION
+ semaphore_mutex;
+
+static unsigned int
+ active_semaphore = MagickFalse;
+#else
+static LONG
+ semaphore_mutex = 0;
+/* Wait for spin lock */
+static void spinlock_wait (LONG volatile *sl)
+{
+ /*
+ InterlockedCompareExchange performs an atomic comparison of the
+ specified 32-bit values and exchanges them, based on the outcome of
+ the comparison. Requires Windows XP, Windows 2000 Professional,
+ Windows NT Workstation 4.0, Windows Me, or Windows 98.
+ */
+
+ while (InterlockedCompareExchange (sl, 1L, 0L) != 0)
+ {
+ /* slight delay - just in case OS does not giveup CPU */
+ Sleep (SPINLOCK_DELAY_MILLI_SECS);
+ }
+}
+/* Release spin lock */
+static void spinlock_release (LONG volatile *sl)
+{
+ /*
+ InterlockedExchange atomically exchanges a pair of 32-bit
+ values. Requires Windows XP, Windows 2000 Professional, Windows NT
+ Workstation 3.5 and later, Windows Me, Windows 98, or Windows 95.
+ */
+ InterlockedExchange (sl, 0L);
+}
+#endif
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e S e m a p h o r e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireSemaphoreInfo() locks a semaphore, initializing it first if
+% necessary.
+%
+% This function is deprecated, should not be used for new code, and should
+% be removed when possible from existing code.
+%
+% The format of the AcquireSemaphoreInfo method is:
+%
+% void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
+%
+% A description of each parameter follows:
+%
+% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
+%
+%
+*/
+MagickExport void AcquireSemaphoreInfo(SemaphoreInfo **semaphore_info)
+{
+ assert(semaphore_info != (SemaphoreInfo **) NULL);
+#if defined(USE_OPENMP_LOCKS)
+ if (!active_semaphore)
+ {
+ omp_init_lock(&semaphore_mutex);
+ active_semaphore=MagickTrue;
+ }
+ omp_set_lock(&semaphore_mutex);
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ PTHREAD_MUTEX_LOCK(&semaphore_mutex);
+#endif /* defined(USE_PTHREAD_LOCKS) */
+#if defined(USE_WIN32_LOCKS)
+# if !defined(USE_SPINLOCKS)
+ if (!active_semaphore)
+ {
+ InitializeCriticalSection(&semaphore_mutex);
+ active_semaphore=MagickTrue;
+ }
+ EnterCriticalSection(&semaphore_mutex);
+# else
+ spinlock_wait(&semaphore_mutex);
+# endif
+#endif /* defined(USE_WIN32_LOCKS) */
+ if (*semaphore_info == (SemaphoreInfo *) NULL)
+ *semaphore_info=AllocateSemaphoreInfo();
+#if defined(USE_OPENMP_LOCKS)
+ omp_unset_lock(&semaphore_mutex);
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ PTHREAD_MUTEX_UNLOCK(&semaphore_mutex);
+#endif /* defined(USE_PTHREAD_LOCKS) */
+#if defined(USE_WIN32_LOCKS)
+#if !defined(USE_SPINLOCKS)
+ LeaveCriticalSection(&semaphore_mutex);
+#else
+ spinlock_release(&semaphore_mutex);
+#endif
+#endif
+ (void) LockSemaphoreInfo(*semaphore_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A l l o c a t e S e m a p h o r e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method AllocateSemaphoreInfo initializes the SemaphoreInfo structure.
+%
+% The format of the AllocateSemaphoreInfo method is:
+%
+% SemaphoreInfo *AllocateSemaphoreInfo(void)
+%
+% A description of each parameter follows:
+%
+% o semaphore_info: Method AllocateSemaphoreInfo returns a pointer to an
+% initialized SemaphoreInfo structure.
+%
+%
+*/
+MagickExport SemaphoreInfo *AllocateSemaphoreInfo(void)
+{
+ SemaphoreInfo
+ *semaphore_info;
+
+ /*
+ Allocate semaphore.
+ */
+ semaphore_info=MagickAllocateAlignedMemory(SemaphoreInfo *,
+ MAGICK_CACHE_LINE_SIZE,
+ sizeof(SemaphoreInfo));
+ if (semaphore_info == (SemaphoreInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateSemaphoreInfo);
+ (void) memset(semaphore_info,0,sizeof(SemaphoreInfo));
+ /*
+ Initialize the semaphore.
+ */
+#if defined(USE_OPENMP_LOCKS)
+ omp_init_lock(&semaphore_info->mutex);
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ {
+ pthread_mutexattr_t
+ mutexattr;
+
+ PTHREAD_MUTEXATTR_INIT(&mutexattr);
+
+ /*
+ If MAGICK_DEBUG is defined then enable pthread mutex error
+ checks.
+ */
+#if MAGICK_DEBUG
+#if defined(PTHREAD_MUTEX_ERRORCHECK)
+ PTHREAD_MUTEXATTR_SETTYPE(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
+#endif /* PTHREAD_MUTEX_ERRORCHECK */
+#endif /* MAGICK_DEBUG */
+
+ PTHREAD_MUTEX_INIT(&semaphore_info->mutex,&mutexattr);
+ PTHREAD_MUTEXATTR_DESTROY(&mutexattr);
+ }
+#endif
+#if defined(USE_WIN32_LOCKS)
+ InitializeCriticalSection(&semaphore_info->mutex);
+#endif
+
+ semaphore_info->signature=MagickSignature;
+ return(semaphore_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y S e m a p h o r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroySemaphore() destroys the semaphore environment.
+%
+% The format of the DestroySemaphore method is:
+%
+% void DestroySemaphore(void)
+%
+%
+*/
+MagickExport void DestroySemaphore(void)
+{
+#if defined(USE_OPENMP_LOCKS)
+ if (active_semaphore)
+ {
+ omp_destroy_lock(&semaphore_mutex);
+ active_semaphore=MagickFalse;
+ }
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ /*
+ We use static pthread mutex initialization with
+ PTHREAD_MUTEX_INITIALIZER so semaphore mutex should not be
+ destroyed.
+ */
+ /* PTHREAD_MUTEX_DESTROY(&semaphore_mutex); */
+#endif
+#if defined(USE_WIN32_LOCKS)
+#if !defined(USE_SPINLOCKS)
+ if (active_semaphore)
+ {
+ DeleteCriticalSection(&semaphore_mutex);
+ active_semaphore=MagickFalse;
+ }
+#endif
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y S e m a p h o r e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroySemaphoreInfo destroys a semaphore.
+%
+% The format of the DestroySemaphoreInfo method is:
+%
+% void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
+%
+% A description of each parameter follows:
+%
+% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
+%
+%
+*/
+MagickExport void DestroySemaphoreInfo(SemaphoreInfo **semaphore_info)
+{
+ assert(semaphore_info != (SemaphoreInfo **) NULL);
+ if (*semaphore_info == (SemaphoreInfo *) NULL)
+ return;
+ assert((*semaphore_info)->signature == MagickSignature);
+#if defined(USE_OPENMP_LOCKS)
+ if (!active_semaphore)
+ {
+ omp_init_lock(&semaphore_mutex);
+ active_semaphore=MagickTrue;
+ }
+ omp_set_lock(&semaphore_mutex);
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ PTHREAD_MUTEX_LOCK(&semaphore_mutex);
+#endif
+#if defined(USE_WIN32_LOCKS)
+#if !defined(USE_SPINLOCKS)
+ if (!active_semaphore)
+ {
+ InitializeCriticalSection(&semaphore_mutex);
+ active_semaphore=MagickTrue;
+ }
+ EnterCriticalSection(&semaphore_mutex);
+#else
+ spinlock_wait(&semaphore_mutex);
+#endif
+#endif
+#if defined(USE_OPENMP_LOCKS)
+ omp_destroy_lock(&(*semaphore_info)->mutex);
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ PTHREAD_MUTEX_DESTROY(&(*semaphore_info)->mutex);
+#endif
+#if defined(USE_WIN32_LOCKS)
+ DeleteCriticalSection(&(*semaphore_info)->mutex);
+#endif
+ (void) memset((void *) *semaphore_info,0xbf,sizeof(SemaphoreInfo));
+ MagickFreeAlignedMemory((*semaphore_info));
+#if defined(USE_OPENMP_LOCKS)
+ omp_unset_lock(&semaphore_mutex);
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ PTHREAD_MUTEX_UNLOCK(&semaphore_mutex);
+#endif
+#if defined(USE_WIN32_LOCKS)
+#if !defined(USE_SPINLOCKS)
+ LeaveCriticalSection(&semaphore_mutex);
+#else
+ spinlock_release(&semaphore_mutex);
+#endif
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I n i t i a l i z e S e m a p h o r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeSemaphore initializes the semaphore environment.
+%
+% The format of the InitializeSemaphore method is:
+%
+% void InitializeSemaphore(void)
+%
+%
+*/
+MagickExport void InitializeSemaphore(void)
+{
+#if defined(USE_OPENMP_LOCKS)
+ if (!active_semaphore)
+ {
+ omp_init_lock(&semaphore_mutex);
+ active_semaphore=MagickTrue;
+ }
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ /*
+ We use static pthread mutex initialization with
+ PTHREAD_MUTEX_INITIALIZER so explicit runtime initialization is
+ not required.
+ */
+/* (void) pthread_mutex_init(&semaphore_mutex, */
+/* (const pthread_mutexattr_t *) NULL); */
+#endif
+#if defined(USE_WIN32_LOCKS)
+#if !defined(USE_SPINLOCKS)
+ if (!active_semaphore)
+ {
+ InitializeCriticalSection(&semaphore_mutex);
+ active_semaphore=MagickTrue;
+ }
+#endif
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i b e r a t e S e m a p h o r e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method LiberateSemaphoreInfo unlocks the semaphore if it has been allocated.
+%
+% This function is deprecated, should not be used for new code, and should
+% be removed when possible from existing code.
+%
+% The format of the LiberateSemaphoreInfo method is:
+%
+% void LiberateSemaphoreInfo(SemaphoreInfo **semaphore_info)
+%
+% A description of each parameter follows:
+%
+% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
+%
+%
+*/
+MagickExport void LiberateSemaphoreInfo(SemaphoreInfo **semaphore_info)
+{
+ assert(semaphore_info != (SemaphoreInfo **) NULL);
+ if (*semaphore_info != (SemaphoreInfo *) NULL)
+ {
+ assert((*semaphore_info)->signature == MagickSignature);
+ (void) UnlockSemaphoreInfo(*semaphore_info);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L o c k S e m a p h o r e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method LockSemaphoreInfo locks a semaphore.
+%
+% The format of the LockSemaphoreInfo method is:
+%
+% void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
+%
+% A description of each parameter follows:
+%
+% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
+%
+%
+*/
+MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
+{
+ assert(semaphore_info != (SemaphoreInfo *) NULL);
+ assert(semaphore_info->signature == MagickSignature);
+#if defined(USE_OPENMP_LOCKS)
+ omp_set_lock(&semaphore_info->mutex);
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ PTHREAD_MUTEX_LOCK(&semaphore_info->mutex);
+#endif /* defined(USE_PTHREAD_LOCKS) */
+#if defined(USE_WIN32_LOCKS)
+ EnterCriticalSection(&semaphore_info->mutex);
+#endif /* defined(USE_WIN32_LOCKS) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n l o c k S e m a p h o r e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UnlockSemaphoreInfo unlocks a semaphore.
+%
+% The format of the LockSemaphoreInfo method is:
+%
+% void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
+%
+% A description of each parameter follows:
+%
+% o semaphore_info: Specifies a pointer to an SemaphoreInfo structure.
+%
+%
+*/
+MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
+{
+ assert(semaphore_info != (SemaphoreInfo *) NULL);
+ assert(semaphore_info->signature == MagickSignature);
+
+#if defined(USE_OPENMP_LOCKS)
+ omp_unset_lock(&semaphore_info->mutex);
+#endif /* defined(USE_OPENMP_LOCKS) */
+#if defined(USE_PTHREAD_LOCKS)
+ PTHREAD_MUTEX_UNLOCK(&semaphore_info->mutex);
+#endif /* defined(USE_PTHREAD_LOCKS) */
+#if defined(USE_WIN32_LOCKS)
+ LeaveCriticalSection(&semaphore_info->mutex);
+#endif /* defined(USE_WIN32_LOCKS) */
+}
diff --git a/magick/semaphore.h b/magick/semaphore.h
new file mode 100644
index 0000000..c413b44
--- /dev/null
+++ b/magick/semaphore.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2003-2010 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Methods to lock and unlock semaphores.
+*/
+#ifndef _MAGICK_SEMAPHORE_H
+#define _MAGICK_SEMAPHORE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+typedef struct _SemaphoreInfo SemaphoreInfo;
+
+extern MagickExport SemaphoreInfo
+ *AllocateSemaphoreInfo(void);
+
+extern MagickExport void
+ DestroySemaphoreInfo(SemaphoreInfo **),
+ LockSemaphoreInfo(SemaphoreInfo *),
+ UnlockSemaphoreInfo(SemaphoreInfo *);
+
+
+/*
+ These are deprecated.
+*/
+extern MagickExport void
+ AcquireSemaphoreInfo(SemaphoreInfo **) MAGICK_FUNC_DEPRECATED,
+ LiberateSemaphoreInfo(SemaphoreInfo **) MAGICK_FUNC_DEPRECATED;
+
+/*
+ These should not be MagickExport.
+*/
+extern MagickExport void
+ DestroySemaphore(void),
+ InitializeSemaphore(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/shear.c b/magick/shear.c
new file mode 100644
index 0000000..3a228ea
--- /dev/null
+++ b/magick/shear.c
@@ -0,0 +1,1874 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS H H EEEEE AAA RRRR %
+% SS H H E A A R R %
+% SSS HHHHH EEE AAAAA RRRR %
+% SS H H E A A R R %
+% SSSSS H H EEEEE A A R R %
+% %
+% %
+% Methods to Shear or Rotate an Image by an Arbitrary Angle %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RotateImage, XShearImage, and YShearImage is based on the paper
+% "A Fast Algorithm for General Raster Rotation" by Alan W. Paeth,
+% Graphics Interface '86 (Vancouver). RotateImage is adapted from a similar
+% method based on the Paeth paper written by Michael Halle of the Spatial
+% Imaging Group, MIT Media Lab.
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/attribute.h"
+#include "magick/color.h"
+#include "magick/decorate.h"
+#include "magick/log.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/render.h"
+#include "magick/shear.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% A f f i n e T r a n s f o r m I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AffineTransformImage() transforms an image as dictated by the affine matrix.
+% It allocates the memory necessary for the new Image structure and returns
+% a pointer to the new image.
+%
+% The format of the AffineTransformImage method is:
+%
+% Image *AffineTransformImage(const Image *image,
+% AffineMatrix *affine,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o affine: The affine transform.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *
+AffineTransformImage(const Image *image,const AffineMatrix *affine,
+ ExceptionInfo *exception)
+{
+ AffineMatrix
+ transform;
+
+ Image
+ *affine_image;
+
+ long
+ y;
+
+ PointInfo
+ extent[4],
+ min,
+ max;
+
+ register long
+ i,
+ x;
+
+ /*
+ Determine bounding box.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(affine != (AffineMatrix *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ extent[0].x=0;
+ extent[0].y=0;
+ extent[1].x=image->columns;
+ extent[1].y=0;
+ extent[2].x=image->columns;
+ extent[2].y=image->rows;
+ extent[3].x=0;
+ extent[3].y=image->rows;
+ for (i=0; i < 4; i++)
+ {
+ x=(long) (extent[i].x+0.5);
+ y=(long) (extent[i].y+0.5);
+ extent[i].x=x*affine->sx+y*affine->ry+affine->tx;
+ extent[i].y=x*affine->rx+y*affine->sy+affine->ty;
+ }
+ min=extent[0];
+ max=extent[0];
+ for (i=1; i < 4; i++)
+ {
+ if (min.x > extent[i].x)
+ min.x=extent[i].x;
+ if (min.y > extent[i].y)
+ min.y=extent[i].y;
+ if (max.x < extent[i].x)
+ max.x=extent[i].x;
+ if (max.y < extent[i].y)
+ max.y=extent[i].y;
+ }
+ /*
+ Affine transform image.
+ */
+ affine_image=CloneImage(image,(unsigned long) ceil(max.x-min.x-0.5),
+ (unsigned long) ceil(max.y-min.y-0.5),True,exception);
+ if (affine_image == (Image *) NULL)
+ return((Image *) NULL);
+ (void) SetImage(affine_image,TransparentOpacity);
+ transform.sx=affine->sx;
+ transform.rx=affine->rx;
+ transform.ry=affine->ry;
+ transform.sy=affine->sy;
+ transform.tx=(-min.x);
+ transform.ty=(-min.y);
+ (void) DrawAffineImage(affine_image,image,&transform);
+ return(affine_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A u t o O r i e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AutoOrientImage() returns an image adjusted so that its orientation is
+% suitable for viewing (i.e. top-left orientation).
+%
+% The format of the AutoOrientImage method is:
+%
+% Image *AutoOrientImage(const Image *image,
+% const OrientationType current_orientation,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o current_orientation: Current image orientation (normally same as
+% image->orientation).
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *
+AutoOrientImage(const Image *image,
+ const OrientationType current_orientation,
+ ExceptionInfo *exception)
+{
+ Image
+ *orient_image;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ orient_image=(Image *) NULL;
+
+ /*
+ 1 2 3 4 5 6 7 8
+
+ 888888 888888 88 88 8888888888 88 88 8888888888
+ 88 88 88 88 88 88 88 88 88 88 88 88
+ 8888 8888 8888 8888 88 8888888888 8888888888 88
+ 88 88 88 88
+ 88 88 888888 888888
+ */
+
+ switch(current_orientation)
+ {
+ case UndefinedOrientation:
+ case TopLeftOrientation: /* 1 */
+ default:
+ {
+ orient_image=CloneImage(image,0,0,MagickTrue,exception);
+ break;
+ }
+ case TopRightOrientation: /* 2 */
+ {
+ orient_image=FlopImage(image,exception);
+ break;
+ }
+ case BottomRightOrientation: /* 3 */
+ {
+ orient_image=RotateImage(image,180.0,exception);
+ break;
+ }
+ case BottomLeftOrientation: /* 4 */
+ {
+ orient_image=FlipImage(image,exception);
+ break;
+ }
+ case LeftTopOrientation: /* 5 */
+ {
+ Image
+ *rotate_image;
+
+ rotate_image=RotateImage(image,90,exception);
+ if (rotate_image != (Image *) NULL)
+ {
+ orient_image=FlopImage(rotate_image,exception);
+ DestroyImage(rotate_image);
+ }
+
+ break;
+ }
+ case RightTopOrientation: /* 6 */
+ {
+ orient_image=RotateImage(image,90.0,exception);
+ break;
+ }
+ case RightBottomOrientation: /* 7 */
+ {
+ Image
+ *rotate_image;
+
+ rotate_image=RotateImage(image,270,exception);
+ if (rotate_image != (Image *) NULL)
+ {
+ orient_image=FlopImage(rotate_image,exception);
+ DestroyImage(rotate_image);
+ }
+ break;
+ }
+ case LeftBottomOrientation: /* 8 */
+ {
+ orient_image=RotateImage(image,270.0,exception);
+ break;
+ }
+ };
+
+ if (orient_image != (Image *) NULL)
+ {
+ orient_image->orientation=TopLeftOrientation;
+ SetImageAttribute(orient_image, "EXIF:Orientation", "1");
+ }
+
+ return orient_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C r o p T o F i t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method CropToFitImage crops the sheared image as determined by the bounding
+% box as defined by width and height and shearing angles.
+%
+% The format of the CropToFitImage method is:
+%
+% MagickPassFail CropToFitImage(Image **image,const double x_shear,
+% const double x_shear,const double width,const double height,
+% const unsigne int rotate,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o image: The address of a structure of type Image.
+%
+% o x_shear, y_shear, width, height: Defines a region of the image to crop.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail
+CropToFitImage(Image **image,
+ const double x_shear,const double y_shear,
+ const double width,const double height,
+ const unsigned int rotate,ExceptionInfo *exception)
+{
+ Image
+ *crop_image;
+
+ PointInfo
+ extent[4],
+ min,
+ max;
+
+ RectangleInfo
+ geometry;
+
+ register long
+ i;
+
+ /*
+ Calculate the rotated image size.
+ */
+ extent[0].x=(-width/2.0);
+ extent[0].y=(-height/2.0);
+ extent[1].x=width/2.0;
+ extent[1].y=(-height/2.0);
+ extent[2].x=(-width/2.0);
+ extent[2].y=height/2.0;
+ extent[3].x=width/2.0;
+ extent[3].y=height/2.0;
+ for (i=0; i < 4; i++)
+ {
+ extent[i].x+=x_shear*extent[i].y;
+ extent[i].y+=y_shear*extent[i].x;
+ if (rotate)
+ extent[i].x+=x_shear*extent[i].y;
+ extent[i].x+=(double) (*image)->columns/2.0;
+ extent[i].y+=(double) (*image)->rows/2.0;
+ }
+ min=extent[0];
+ max=extent[0];
+ for (i=1; i < 4; i++)
+ {
+ if (min.x > extent[i].x)
+ min.x=extent[i].x;
+ if (min.y > extent[i].y)
+ min.y=extent[i].y;
+ if (max.x < extent[i].x)
+ max.x=extent[i].x;
+ if (max.y < extent[i].y)
+ max.y=extent[i].y;
+ }
+ geometry.width=(unsigned long) floor(max.x-min.x+0.5);
+ geometry.height=(unsigned long) floor(max.y-min.y+0.5);
+ geometry.x=(long) ceil(min.x-0.5);
+ geometry.y=(long) ceil(min.y-0.5);
+ crop_image=CropImage(*image,&geometry,exception);
+ if (crop_image != (Image *) NULL)
+ crop_image->page=(*image)->page;
+ DestroyImage(*image);
+ *image=crop_image;
+
+ return (*image != (Image *) NULL ? MagickPass : MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n t e g r a l R o t a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IntegralRotateImage rotates the image an integral of 90 degrees.
+% It allocates the memory necessary for the new Image structure and returns
+% a pointer to the rotated image.
+%
+% The format of the IntegralRotateImage method is:
+%
+% Image *IntegralRotateImage(const Image *image,unsigned int rotations,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o rotate_image: Method IntegralRotateImage returns a pointer to the
+% rotated image. A null image is returned if there is a a memory shortage.
+%
+% o image: The image.
+%
+% o rotations: Specifies the number of 90 degree rotations.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+#if 1
+#if !defined(DisableSlowOpenMP)
+# define IntegralRotateImageUseOpenMP
+# define RotateThreads (Min(2,omp_get_max_threads()))
+#endif
+#endif
+static Image *
+IntegralRotateImage(const Image *image,unsigned int rotations,
+ ExceptionInfo *exception)
+{
+ char
+ message[MaxTextExtent];
+
+ Image
+ *rotate_image;
+
+ RectangleInfo
+ page;
+
+ long
+ tile_width_max,
+ tile_height_max;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize rotated image attributes.
+ */
+ assert(image != (Image *) NULL);
+ page=image->page;
+ rotations%=4;
+
+ {
+ /*
+ Clone appropriately to create rotate image.
+ */
+ unsigned long
+ clone_columns=0,
+ clone_rows=0;
+
+ switch (rotations)
+ {
+ case 0:
+ clone_columns=0;
+ clone_rows=0;
+ break;
+ case 2:
+ clone_columns=image->columns;
+ clone_rows=image->rows;
+ break;
+ case 1:
+ case 3:
+ clone_columns=image->rows;
+ clone_rows=image->columns;
+ break;
+ }
+ rotate_image=CloneImage(image,clone_columns,clone_rows,True,exception);
+ if (rotate_image == (Image *) NULL)
+ return((Image *) NULL);
+ if (rotations != 0)
+ if (ModifyCache(rotate_image,exception) != MagickPass)
+ {
+ DestroyImage(rotate_image);
+ return (Image *) NULL;
+ }
+ }
+
+ tile_height_max=tile_width_max=2048/sizeof(PixelPacket); /* 2k x 2k = 4MB */
+ if ((rotations == 1) || (rotations == 3))
+ {
+ /*
+ Allow override of tile geometry for testing.
+ */
+ const char *
+ value;
+
+ if (!GetPixelCacheInCore(image) || !GetPixelCacheInCore(rotate_image))
+ tile_height_max=tile_width_max=8192/sizeof(PixelPacket); /* 8k x 8k = 64MB */
+
+ if ((value=getenv("MAGICK_ROTATE_TILE_GEOMETRY")))
+ {
+ double
+ width,
+ height;
+
+ if (GetMagickDimension(value,&width,&height,NULL,NULL) == 2)
+ {
+ tile_height_max=(unsigned long) height;
+ tile_width_max=(unsigned long) width;
+ }
+ }
+ }
+
+ /*
+ Integral rotate the image.
+ */
+ switch (rotations)
+ {
+ case 0:
+ {
+ /*
+ Rotate 0 degrees (nothing more to do).
+ */
+ (void) strlcpy(message,"[%s] Rotate: 0 degrees...",sizeof(message));
+ if (!MagickMonitorFormatted(image->rows-1,image->rows,exception,
+ message,image->filename))
+ status=MagickFail;
+ break;
+ }
+ case 1:
+ {
+ /*
+ Rotate 90 degrees.
+ */
+ magick_int64_t
+ tile;
+
+ magick_uint64_t
+ total_tiles;
+
+ long
+ tile_y;
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+ int
+ rotate_threads = RotateThreads;
+# endif
+#endif
+
+ (void) strlcpy(message,"[%s] Rotate: 90 degrees...",sizeof(message));
+ total_tiles=(((image->rows/tile_height_max)+1)*
+ ((image->columns/tile_width_max)+1));
+ tile=0;
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(status, tile)
+# else
+# pragma omp parallel for num_threads(rotate_threads) schedule(static,1) shared(status, tile)
+# endif
+# endif
+#endif
+ for (tile_y=0; tile_y < (long) image->rows; tile_y+=tile_height_max)
+ {
+ long
+ tile_x;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_IntegralRotateImage)
+# endif
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ for (tile_x=0; tile_x < (long) image->columns; tile_x+=tile_width_max)
+ {
+ long
+ dest_tile_x,
+ dest_tile_y;
+
+ long
+ tile_width,
+ tile_height;
+
+ const PixelPacket
+ *tile_pixels;
+
+ long
+ y;
+
+ /*
+ Compute image region corresponding to tile.
+ */
+ if ((unsigned long) tile_x+tile_width_max > image->columns)
+ tile_width=(tile_width_max-(tile_x+tile_width_max-image->columns));
+ else
+ tile_width=tile_width_max;
+ if ((unsigned long) tile_y+tile_height_max > image->rows)
+ tile_height=(tile_height_max-(tile_y+tile_height_max-image->rows));
+ else
+ tile_height=tile_height_max;
+ /*
+ Acquire tile
+ */
+ tile_pixels=AcquireImagePixels(image,tile_x,tile_y,
+ tile_width,tile_height,exception);
+ if (tile_pixels == (const PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ /*
+ Compute destination tile coordinates.
+ */
+ dest_tile_x=rotate_image->columns-(tile_y+tile_height);
+ dest_tile_y=tile_x;
+ /*
+ Rotate tile
+ */
+ for (y=0; y < tile_width; y++)
+ {
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q;
+
+ register const IndexPacket
+ *indexes;
+
+ IndexPacket
+ *rotate_indexes;
+
+ register long
+ x;
+
+ q=SetImagePixelsEx(rotate_image,dest_tile_x,dest_tile_y+y,
+ tile_height,1,exception);
+ if (q == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ /*
+ DirectClass pixels
+ */
+ p=tile_pixels+(tile_height-1)*tile_width + y;
+ for (x=tile_height; x != 0; x--)
+ {
+ *q = *p;
+ q++;
+ p-=tile_width;
+ }
+ /*
+ Indexes
+ */
+ indexes=AccessImmutableIndexes(image);
+ if (indexes != (IndexPacket *) NULL)
+ {
+ rotate_indexes=AccessMutableIndexes(rotate_image);
+ if (rotate_indexes != (IndexPacket *) NULL)
+ {
+ register IndexPacket
+ *iq;
+
+ register const IndexPacket
+ *ip;
+
+ iq=rotate_indexes;
+ ip=indexes+(tile_height-1)*tile_width + y;
+ for (x=tile_height; x != 0; x--)
+ {
+ *iq = *ip;
+ iq++;
+ ip -= tile_width;
+ }
+ }
+ }
+ if (!SyncImagePixelsEx(rotate_image,exception))
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ }
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_IntegralRotateImage)
+# endif
+#endif
+ {
+ tile++;
+ if (QuantumTick(tile,total_tiles))
+ if (!MagickMonitorFormatted(tile,total_tiles,exception,
+ message,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ }
+ Swap(page.width,page.height);
+ Swap(page.x,page.y);
+ page.x=(long) (page.width-rotate_image->columns-page.x);
+ break;
+ }
+ case 2:
+ {
+ /*
+ Rotate 180 degrees.
+ */
+ long
+ y;
+
+ unsigned long
+ row_count=0;
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+ int
+ rotate_threads = RotateThreads;
+# endif
+#endif
+
+ (void) strlcpy(message,"[%s] Rotate: 180 degrees...",sizeof(message));
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for num_threads(rotate_threads) schedule(static,8) shared(row_count, status)
+# endif
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q;
+
+ register const IndexPacket
+ *indexes;
+
+ IndexPacket
+ *rotate_indexes;
+
+ register long
+ x;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_IntegralRotateImage)
+# endif
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ q=SetImagePixelsEx(rotate_image,0,(long) (image->rows-y-1),
+ image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+ if (thread_status != MagickFail)
+ {
+ q+=image->columns;
+ indexes=AccessImmutableIndexes(image);
+ rotate_indexes=AccessMutableIndexes(rotate_image);
+ if ((indexes != (IndexPacket *) NULL) &&
+ (rotate_indexes != (IndexPacket *) NULL))
+ for (x=0; x < (long) image->columns; x++)
+ rotate_indexes[image->columns-x-1]=indexes[x];
+ for (x=0; x < (long) image->columns; x++)
+ *--q=(*p++);
+ if (!SyncImagePixelsEx(rotate_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_IntegralRotateImage)
+# endif
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,exception,
+ message,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ page.x=(long) (page.width-rotate_image->columns-page.x);
+ page.y=(long) (page.height-rotate_image->rows-page.y);
+ break;
+ }
+ case 3:
+ {
+ /*
+ Rotate 270 degrees.
+ */
+
+ magick_int64_t
+ tile;
+
+ magick_uint64_t
+ total_tiles;
+
+ long
+ tile_y;
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+ int
+ rotate_threads = RotateThreads;
+# endif
+#endif
+
+ (void) strlcpy(message,"[%s] Rotate: 270 degrees...",sizeof(message));
+ total_tiles=(((image->rows/tile_height_max)+1)*
+ ((image->columns/tile_width_max)+1));
+ tile=0;
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(status, tile)
+# else
+# pragma omp parallel for num_threads(rotate_threads) schedule(static,1) shared(status, tile)
+# endif
+# endif
+#endif
+ for (tile_y=0; tile_y < (long) image->rows; tile_y+=tile_height_max)
+ {
+ long
+ tile_x;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_IntegralRotateImage)
+# endif
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ for (tile_x=0; tile_x < (long) image->columns; tile_x+=tile_width_max)
+ {
+ long
+ tile_width,
+ tile_height;
+
+ long
+ dest_tile_x,
+ dest_tile_y;
+
+ long
+ y;
+
+ const PixelPacket
+ *tile_pixels;
+
+ /*
+ Compute image region corresponding to tile.
+ */
+ if ((unsigned long) tile_x+tile_width_max > image->columns)
+ tile_width=(tile_width_max-(tile_x+tile_width_max-image->columns));
+ else
+ tile_width=tile_width_max;
+ if ((unsigned long) tile_y+tile_height_max > image->rows)
+ tile_height=(tile_height_max-(tile_y+tile_height_max-image->rows));
+ else
+ tile_height=tile_height_max;
+ /*
+ Acquire tile
+ */
+ tile_pixels=AcquireImagePixels(image,tile_x,tile_y,
+ tile_width,tile_height,exception);
+ if (tile_pixels == (const PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ /*
+ Compute destination tile coordinates.
+ */
+ dest_tile_x=tile_y;
+ dest_tile_y=rotate_image->rows-(tile_x+tile_width);
+ /*
+ Rotate tile
+ */
+ for (y=0; y < tile_width; y++)
+ {
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q;
+
+ register const IndexPacket
+ *indexes;
+
+ register long
+ x;
+
+ IndexPacket
+ *rotate_indexes;
+
+ q=SetImagePixelsEx(rotate_image,dest_tile_x,dest_tile_y+y,
+ tile_height,1,exception);
+ if (q == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ /*
+ DirectClass pixels
+ */
+ p=tile_pixels+(tile_width-1-y);
+ for (x=tile_height; x != 0; x--)
+ {
+ *q = *p;
+ q++;
+ p += tile_width;
+ }
+ /*
+ Indexes
+ */
+ indexes=AccessImmutableIndexes(image);
+ if (indexes != (IndexPacket *) NULL)
+ {
+ rotate_indexes=AccessMutableIndexes(rotate_image);
+ if (rotate_indexes != (IndexPacket *) NULL)
+ {
+ register IndexPacket
+ *iq;
+
+ register const IndexPacket
+ *ip;
+
+ iq=rotate_indexes;
+ ip=indexes+(tile_width-1-y);
+ for (x=tile_height; x != 0; x--)
+ {
+ *iq = *ip;
+ iq++;
+ ip += tile_width;
+ }
+ }
+ }
+ if (!SyncImagePixelsEx(rotate_image,exception))
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ }
+
+#if defined(IntegralRotateImageUseOpenMP)
+# if defined(HAVE_OPENMP)
+# pragma omp critical (GM_IntegralRotateImage)
+# endif
+#endif
+ {
+ tile++;
+ if (QuantumTick(tile,total_tiles))
+ if (!MagickMonitorFormatted(tile,total_tiles,exception,
+ message,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+
+ if (thread_status == MagickFail)
+ break;
+ }
+ }
+ Swap(page.width,page.height);
+ Swap(page.x,page.y);
+ page.y=(long) (page.height-rotate_image->rows-page.y);
+ break;
+ }
+ }
+
+ rotate_image->page=page;
+ rotate_image->is_grayscale=image->is_grayscale;
+ rotate_image->is_monochrome=image->is_monochrome;
+ return(rotate_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X S h e a r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure XShearImage shears the image in the X direction with a shear angle
+% of 'degrees'. Positive angles shear counter-clockwise (right-hand rule),
+% and negative angles shear clockwise. Angles are measured relative to a
+% vertical Y-axis. X shears will widen an image creating 'empty' triangles
+% on the left and right sides of the source image.
+%
+% The format of the XShearImage method is:
+%
+% MagickPassFail XShearImage(Image *image,const double degrees,
+% const unsigned long width,const unsigned long height,
+% const long x_offset,long y_offset,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o degrees: A double representing the shearing angle along the X axis.
+%
+% o width, height, x_offset, y_offset: Defines a region of the image
+% to shear.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+
+static MagickPassFail
+XShearImage(Image *image,const double degrees,
+ const unsigned long width,const unsigned long height,
+ const long x_offset,long y_offset,ExceptionInfo *exception)
+{
+#define XShearImageText "[%s] X Shear: %+g degrees, region %lux%lu%+ld%+ld... "
+
+ long
+ y,
+ xr_offset;
+
+ unsigned long
+ row_count=0;
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ is_grayscale=image->is_grayscale;
+
+ assert(x_offset >= 0);
+ assert(x_offset < (long) image->columns);
+ assert(y_offset >= 0);
+ assert(y_offset < (long) image->rows);
+ assert(width <= (image->columns-(unsigned long) x_offset));
+ assert(height <= (image->rows-(unsigned long) y_offset));
+ xr_offset=image->columns-width-x_offset;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(dynamic) shared(row_count, status)
+# endif
+# endif
+#endif
+ for (y=0; y < (long) height; y++)
+ {
+ double
+ alpha,
+ displacement;
+
+ long
+ step,
+ skip;
+
+ PixelPacket
+ pixel;
+
+ register long
+ i;
+
+ register PixelPacket
+ *p,
+ *q;
+
+ enum
+ {
+ LEFT,
+ RIGHT
+ } direction;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_XShearImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ displacement=degrees*(y-height/2.0);
+ if (displacement == 0.0)
+ continue;
+ if (displacement > 0.0)
+ direction=RIGHT;
+ else
+ {
+ displacement*=(-1.0);
+ direction=LEFT;
+ }
+ step=(long) floor(displacement);
+ alpha=MaxRGBDouble*(displacement-step);
+ if (alpha == 0.0)
+ {
+ /*
+ No fractional displacement-- just copy.
+ */
+ switch (direction)
+ {
+ case LEFT:
+ {
+ /*
+ Transfer pixels left-to-right.
+ */
+ skip = (step > x_offset) ? step - x_offset : 0;
+ p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,exception);
+ if (p == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ p+=x_offset+skip;
+ q=p-step;
+ (void) memcpy(q,p,(width-(unsigned long)skip)*sizeof(PixelPacket));
+ q+=width;
+ for (i=0; i < step; i++)
+ *q++=image->background_color;
+ break;
+ }
+ case RIGHT:
+ {
+ /*
+ Transfer pixels right-to-left.
+ */
+ skip = (step > xr_offset) ? step - xr_offset : 0;
+ p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,exception);
+ if (p == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ p+=x_offset+width-skip;
+ q=p+step;
+ for (i=0; i < ((long) width - skip); i++)
+ *--q=(*--p);
+ for (i=0; i < step; i++)
+ *--q=image->background_color;
+ break;
+ }
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ thread_status=MagickFail;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_XShearImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,height))
+ if (!MagickMonitorFormatted(row_count,height,exception,
+ XShearImageText,image->filename,
+ degrees,width,height,
+ x_offset,y_offset))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+
+ continue;
+ }
+ /*
+ Fractional displacement.
+ */
+ step++;
+ pixel=image->background_color;
+ switch (direction)
+ {
+ case LEFT:
+ {
+ /*
+ Transfer pixels left-to-right.
+ */
+ p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,exception);
+ if (p == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ p+=x_offset;
+ q=p-step;
+ for (i=0; i < (long) width; i++)
+ {
+ if ((x_offset+i) < step)
+ {
+ pixel=(*++p);
+ q++;
+ continue;
+ }
+ BlendCompositePixel(q,&pixel,p,alpha);
+ q++;
+ pixel=(*p++);
+ }
+ BlendCompositePixel(q,&pixel,&image->background_color,alpha);
+ q++;
+ for (i=0; i < (step-1); i++)
+ *q++=image->background_color;
+ break;
+ }
+ case RIGHT:
+ {
+ /*
+ Transfer pixels right-to-left.
+ */
+ p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,exception);
+ if (p == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ p+=x_offset+width;
+ q=p+step;
+ for (i=0; i < (long) width; i++)
+ {
+ p--;
+ q--;
+ if ((x_offset+width+step-i) > image->columns)
+ continue;
+ BlendCompositePixel(q,&pixel,p,alpha);
+ pixel=(*p);
+ }
+ --q;
+ BlendCompositePixel(q,&pixel,&image->background_color,alpha);
+ for (i=0; i < (step-1); i++)
+ *--q=image->background_color;
+ break;
+ }
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ thread_status=MagickFail;
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_XShearImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,height))
+ if (!MagickMonitorFormatted(row_count,height,exception,
+ XShearImageText,image->filename,
+ degrees,width,height,
+ x_offset,y_offset))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ if (is_grayscale && IsGray(image->background_color))
+ image->is_grayscale=True;
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ Y S h e a r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure YShearImage shears the image in the Y direction with a shear
+% angle of 'degrees'. Positive angles shear counter-clockwise (right-hand
+% rule), and negative angles shear clockwise. Angles are measured relative
+% to a horizontal X-axis. Y shears will increase the height of an image
+% creating 'empty' triangles on the top and bottom of the source image.
+%
+% The format of the YShearImage method is:
+%
+% MagickPassFail YShearImage(Image *image,const double degrees,
+% const unsigned long width,const unsigned long height,long x_offset,
+% const long y_offset,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o image: The image.
+%
+% o degrees: A double representing the shearing angle along the Y axis.
+%
+% o width, height, x_offset, y_offset: Defines a region of the image
+% to shear.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static MagickPassFail
+YShearImage(Image *image,const double degrees,
+ const unsigned long width,const unsigned long height,long x_offset,
+ const long y_offset,ExceptionInfo *exception)
+{
+#define YShearImageText "[%s] Y Shear: %+g degrees, region %lux%lu%+ld%+ld... "
+
+ long
+ x,
+ yr_offset;
+
+ unsigned long
+ row_count=0;
+
+ unsigned int
+ is_grayscale;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(image != (Image *) NULL);
+ is_grayscale=image->is_grayscale;
+
+ assert(x_offset >= 0);
+ assert(x_offset < (long) image->columns);
+ assert(y_offset >= 0);
+ assert(y_offset < (long) image->rows);
+ assert(width <= (image->columns-(unsigned long) x_offset));
+ assert(height <= (image->rows-(unsigned long) y_offset));
+ yr_offset=image->rows-height-y_offset;
+
+#if defined(HAVE_OPENMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# if defined(USE_STATIC_SCHEDULING_ONLY)
+# pragma omp parallel for schedule(static) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(dynamic) shared(row_count, status)
+# endif
+# endif
+#endif
+ for (x=0; x < (long) width; x++)
+ {
+ double
+ alpha,
+ displacement;
+
+ enum
+ {
+ UP,
+ DOWN
+ } direction;
+
+ long
+ step,
+ skip;
+
+ register PixelPacket
+ *p,
+ *q;
+
+ register long
+ i;
+
+ PixelPacket
+ pixel;
+
+ MagickPassFail
+ thread_status;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_YShearImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ displacement=degrees*(x-width/2.0);
+ if (displacement == 0.0)
+ continue;
+ if (displacement > 0.0)
+ direction=DOWN;
+ else
+ {
+ displacement*=(-1.0);
+ direction=UP;
+ }
+ step=(long) floor(displacement);
+ alpha=(double) MaxRGB*(displacement-step);
+ if (alpha == 0.0)
+ {
+ /*
+ No fractional displacement-- just copy the pixels.
+ */
+ switch (direction)
+ {
+ case UP:
+ {
+ /*
+ Transfer pixels top-to-bottom.
+ */
+ skip = (step > y_offset) ? step - y_offset : 0;
+ p=GetImagePixelsEx(image,x+x_offset,0,1,image->rows,exception);
+ if (p == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ p+=y_offset+skip;
+ q=p-step;
+ (void) memcpy(q,p,(height-(unsigned long)skip)*sizeof(PixelPacket));
+ q+=height;
+ for (i=0; i < (long) step; i++)
+ *q++=image->background_color;
+ break;
+ }
+ case DOWN:
+ {
+ /*
+ Transfer pixels bottom-to-top.
+ */
+ skip = (step > yr_offset) ? step - yr_offset : 0;
+ p=GetImagePixelsEx(image,x+x_offset,0,1,image->rows,exception);
+ if (p == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ p+=y_offset+height-skip;
+ q=p+step;
+ for (i=0; i < ((long) height - skip); i++)
+ *--q=(*--p);
+ for (i=0; i < step; i++)
+ *--q=image->background_color;
+ break;
+ }
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ thread_status=MagickFail;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_YShearImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,width))
+ if (!MagickMonitorFormatted(row_count,width,exception,
+ YShearImageText,image->filename,
+ degrees,width,height,
+ x_offset,y_offset))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+
+ continue;
+ }
+ /*
+ Fractional displacment.
+ */
+ step++;
+ pixel=image->background_color;
+ switch (direction)
+ {
+ case UP:
+ {
+ /*
+ Transfer pixels top-to-bottom.
+ */
+ p=GetImagePixelsEx(image,x+x_offset,0,1,image->rows,exception);
+ if (p == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ p+=y_offset;
+ q=p-step;
+ for (i=0; i < (long) height; i++)
+ {
+ if ((y_offset+i) < step)
+ {
+ pixel=(*++p);
+ q++;
+ continue;
+ }
+ BlendCompositePixel(q,&pixel,p,alpha);
+ q++;
+ pixel=(*p++);
+ }
+ BlendCompositePixel(q,&pixel,&image->background_color,alpha);
+ q++;
+ for (i=0; i < (step-1); i++)
+ *q++=image->background_color;
+ break;
+ }
+ case DOWN:
+ {
+ /*
+ Transfer pixels bottom-to-top.
+ */
+ p=GetImagePixelsEx(image,x+x_offset,0,1,image->rows,exception);
+ if (p == (PixelPacket *) NULL)
+ {
+ thread_status=MagickFail;
+ break;
+ }
+ p+=y_offset+height;
+ q=p+step;
+ for (i=0; i < (long) height; i++)
+ {
+ p--;
+ q--;
+ if ((y_offset+height+step-i) > image->rows)
+ continue;
+ BlendCompositePixel(q,&pixel,p,alpha);
+ pixel=(*p);
+ }
+ --q;
+ BlendCompositePixel(q,&pixel,&image->background_color,alpha);
+ for (i=0; i < (step-1); i++)
+ *--q=image->background_color;
+ break;
+ }
+ }
+ if (!SyncImagePixelsEx(image,exception))
+ thread_status=MagickFail;
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_YShearImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,width))
+ if (!MagickMonitorFormatted(row_count,width,exception,
+ YShearImageText,image->filename,
+ degrees,width,height,
+ x_offset,y_offset))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ if (is_grayscale && IsGray(image->background_color))
+ image->is_grayscale=True;
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R o t a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method RotateImage creates a new image that is a rotated copy of an
+% existing one. Positive angles rotate counter-clockwise (right-hand rule),
+% while negative angles rotate clockwise. Rotated images are usually larger
+% than the originals and have 'empty' triangular corners. X axis. Empty
+% triangles left over from shearing the image are filled with the color
+% specified by the image background_color. RotateImage allocates the memory
+% necessary for the new Image structure and returns a pointer to the new
+% image.
+%
+% Method RotateImage is based on the paper "A Fast Algorithm for General
+% Raster Rotatation" by Alan W. Paeth. RotateImage is adapted from a similar
+% method based on the Paeth paper written by Michael Halle of the Spatial
+% Imaging Group, MIT Media Lab.
+%
+% The format of the RotateImage method is:
+%
+% Image *RotateImage(const Image *image,const double degrees,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o status: Method RotateImage returns a pointer to the image after
+% rotating. A null image is returned if there is a memory shortage.
+%
+% o image: The image; returned from
+% ReadImage.
+%
+% o degrees: Specifies the number of degrees to rotate the image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *
+RotateImage(const Image *image,const double degrees,ExceptionInfo *exception)
+{
+ double
+ angle;
+
+ Image
+ *integral_image = (Image *) NULL,
+ *rotate_image = (Image *) NULL;
+
+ long
+ x_offset,
+ y_offset;
+
+ PointInfo
+ shear;
+
+ RectangleInfo
+ border_info;
+
+ unsigned long
+ height,
+ rotations,
+ width,
+ shear1_width,
+ shear2_height,
+ shear3_width,
+ max_width,
+ max_height;
+
+ /*
+ Adjust rotation angle.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ angle=degrees;
+ while (angle < -45.0)
+ angle+=360.0;
+ for (rotations=0; angle > 45.0; rotations++)
+ angle-=90.0;
+ rotations%=4;
+ /*
+ Calculate shear equations.
+ */
+ integral_image=IntegralRotateImage(image,rotations,exception);
+ if (integral_image == (Image *) NULL)
+ goto rotate_image_exception;
+
+ shear.x=(-tan(DegreesToRadians(angle)/2.0));
+ shear.y=sin(DegreesToRadians(angle));
+ if ((shear.x == 0.0) || (shear.y == 0.0))
+ return(integral_image);
+ /*
+ Compute image size.
+ */
+ width=integral_image->columns;
+ height=integral_image->rows;
+ shear1_width=(unsigned long) floor(fabs(height*shear.x)+width+0.5);
+ shear2_height=(unsigned long) floor(fabs(shear1_width*shear.y)+height+0.5);
+ shear3_width=(unsigned long) floor(fabs(shear2_height*shear.x)+shear1_width+0.5);
+ /*
+ Compute maximum bounds to perform 3 shear operations.
+ Add extra pixels to account for fractional displacement
+ */
+ max_width = ((shear3_width > shear1_width) ? shear3_width : shear1_width) + 2;
+ max_height = shear2_height + 2;
+ x_offset = (long) floor((max_width-width)/2.0+0.5);
+ y_offset = (long) floor((max_height-height)/2.0+0.5);
+ /*
+ Surround image with a border.
+ */
+ integral_image->border_color=integral_image->background_color;
+ border_info.width=x_offset;
+ border_info.height=y_offset;
+ rotate_image=BorderImage(integral_image,&border_info,exception);
+ DestroyImage(integral_image);
+ integral_image=(Image *) NULL;
+ if (rotate_image == (Image *) NULL)
+ goto rotate_image_exception;
+
+ /*
+ Rotate the image.
+ */
+ rotate_image->storage_class=DirectClass;
+ rotate_image->matte|=rotate_image->background_color.opacity != OpaqueOpacity;
+
+ if (XShearImage(rotate_image,shear.x,width,height,
+ x_offset,y_offset,exception) != MagickPass)
+ goto rotate_image_exception;
+
+ if (YShearImage(rotate_image,shear.y,shear1_width,height,
+ (long) (rotate_image->columns-shear1_width)/2,y_offset,exception)
+ != MagickPass)
+ goto rotate_image_exception;
+
+ if (XShearImage(rotate_image,shear.x,shear1_width,shear2_height,
+ (long) (rotate_image->columns-shear1_width)/2,
+ (long) (rotate_image->rows-shear2_height)/2,exception)
+ != MagickPass)
+ goto rotate_image_exception;
+
+ if (CropToFitImage(&rotate_image,shear.x,shear.y,width,height,True,exception)
+ != MagickPass)
+ goto rotate_image_exception;
+
+ rotate_image->page.width=0;
+ rotate_image->page.height=0;
+ return(rotate_image);
+
+ rotate_image_exception:
+
+ if (rotate_image != (Image *) NULL)
+ DestroyImage(rotate_image);
+ return (Image *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S h e a r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ShearImage creates a new image that is a shear_image copy of an
+% existing one. Shearing slides one edge of an image along the X or Y
+% axis, creating a parallelogram. An X direction shear slides an edge
+% along the X axis, while a Y direction shear slides an edge along the Y
+% axis. The amount of the shear is controlled by a shear angle. For X
+% direction shears, x_shear is measured relative to the Y axis, and
+% similarly, for Y direction shears y_shear is measured relative to the
+% X axis. Empty triangles left over from shearing the image are filled
+% with the color defined by the pixel at location (0,0). ShearImage
+% allocates the memory necessary for the new Image structure and returns
+% a pointer to the new image.
+%
+% Method ShearImage is based on the paper "A Fast Algorithm for General
+% Raster Rotatation" by Alan W. Paeth.
+%
+% The format of the ShearImage method is:
+%
+% Image *ShearImage(const Image *image,const double x_shear,
+% const double y_shear,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o status: Method ShearImage returns a pointer to the image after
+% rotating. A null image is returned if there is a memory shortage.
+%
+% o image: The image; returned from
+% ReadImage.
+%
+% o x_shear, y_shear: Specifies the number of degrees to shear the image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *
+ShearImage(const Image *image,const double x_shear,
+ const double y_shear,ExceptionInfo *exception)
+{
+ Image
+ *integral_image = (Image *) NULL,
+ *shear_image = (Image *) NULL;
+
+ long
+ x_offset,
+ y_offset;
+
+ PointInfo
+ shear;
+
+ RectangleInfo
+ border_info;
+
+ unsigned long
+ y_width;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if ((x_shear == 180.0) || (y_shear == 180.0))
+ ThrowImageException3(ImageError,UnableToShearImage,AngleIsDiscontinuous);
+
+ /*
+ Initialize shear angle.
+ */
+ integral_image=IntegralRotateImage(image,0,exception);
+ if (integral_image == (Image *) NULL)
+ goto shear_image_exception;
+ shear.x=(-tan(DegreesToRadians(x_shear)/2.0));
+ shear.y=sin(DegreesToRadians(y_shear));
+ (void) LogMagickEvent(TransformEvent,GetMagickModule(),
+ "Shear angles x,y: %g,%g degrees", shear.x, shear.y);
+ if ((shear.x == 0.0) && (shear.y == 0.0))
+ return(integral_image);
+
+ /*
+ Compute image size.
+ */
+ x_offset=(long) ceil(fabs(2.0*image->rows*shear.x)-0.5);
+ y_width=(unsigned long) floor(fabs(image->rows*shear.x)+image->columns+0.5);
+ y_offset=(long) ceil(fabs(y_width*shear.y)-0.5);
+ /*
+ Surround image with border.
+ */
+ integral_image->border_color=integral_image->background_color;
+ border_info.width=x_offset;
+ border_info.height=y_offset;
+ shear_image=BorderImage(integral_image,&border_info,exception);
+ DestroyImage(integral_image);
+ integral_image=(Image *) NULL;
+ if (shear_image == (Image *) NULL)
+ goto shear_image_exception;
+ /*
+ Shear the image.
+ */
+ shear_image->storage_class=DirectClass;
+ shear_image->matte|=shear_image->background_color.opacity != OpaqueOpacity;
+
+ if (XShearImage(shear_image,shear.x,image->columns,image->rows,x_offset,
+ (long) (shear_image->rows-image->rows)/2,exception)
+ != MagickPass)
+ goto shear_image_exception;
+
+ if (YShearImage(shear_image,shear.y,y_width,image->rows,
+ (long) (shear_image->columns-y_width)/2,y_offset,exception)
+ != MagickPass)
+ goto shear_image_exception;
+
+ if (CropToFitImage(&shear_image,shear.x,shear.y,image->columns,image->rows,
+ False,exception) != MagickPass)
+ goto shear_image_exception;
+
+ shear_image->page.width=0;
+ shear_image->page.height=0;
+
+ return(shear_image);
+
+ shear_image_exception:
+
+ DestroyImage(integral_image);
+ DestroyImage(shear_image);
+ return (Image *) NULL;
+}
diff --git a/magick/shear.h b/magick/shear.h
new file mode 100644
index 0000000..865b5f8
--- /dev/null
+++ b/magick/shear.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2003-2012 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Image Shear Methods.
+*/
+#ifndef _MAGICK_SHEAR_H
+#define _MAGICK_SHEAR_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport Image
+ *AffineTransformImage(const Image *,const AffineMatrix *,ExceptionInfo *),
+ *AutoOrientImage(const Image *image,const OrientationType current_orientation,
+ ExceptionInfo *exception),
+ *RotateImage(const Image *,const double,ExceptionInfo *),
+ *ShearImage(const Image *,const double,const double,ExceptionInfo *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_SHEAR_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/signature.c b/magick/signature.c
new file mode 100644
index 0000000..cc71ccf
--- /dev/null
+++ b/magick/signature.c
@@ -0,0 +1,514 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% SSSSS IIIII GGGG N N AAA TTTTT U U RRRR EEEEE %
+% SS I G NN N A A T U U R R E %
+% SSS I G GG N N N AAAAA T U U RRRR EEE %
+% SS I G G N NN A A T U U R R E %
+% SSSSS IIIII GGG N N A A T UUU R R EEEEE %
+% %
+% %
+% Methods to Compute a Message Digest for an Image %
+% %
+% %
+% Software Design %
+% John Cristy %
+% December 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/signature.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define Trunc32(x) ((x) & 0xffffffffUL)
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F i n a l i z e S i g n a t u r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method FinalizeSignature finalizes the SHA message digest computation.
+%
+% The format of the FinalizeSignature method is:
+%
+% FinalizeSignature(SignatureInfo *signature_info)
+%
+% A description of each parameter follows:
+%
+% o signature_info: The address of a structure of type SignatureInfo.
+%
+%
+*/
+MagickExport void FinalizeSignature(SignatureInfo *signature_info)
+{
+ long
+ count;
+
+ unsigned long
+ high_order,
+ low_order;
+
+ /*
+ Finalize computing the SHA digest.
+ */
+ low_order=signature_info->low_order;
+ high_order=signature_info->high_order;
+ count=(long) ((low_order >> 3) & 0x3f);
+ signature_info->message[count++]=0x80;
+ if (count <= (SignatureSize-8))
+ (void) memset(signature_info->message+count,0,SignatureSize-8-count);
+ else
+ {
+ (void) memset(signature_info->message+count,0,SignatureSize-count);
+ TransformSignature(signature_info);
+ (void) memset(signature_info->message,0,SignatureSize-8);
+ }
+ signature_info->message[56]=(unsigned char) (high_order >> 24);
+ signature_info->message[57]=(unsigned char) (high_order >> 16);
+ signature_info->message[58]=(unsigned char) (high_order >> 8);
+ signature_info->message[59]=(unsigned char) high_order;
+ signature_info->message[60]=(unsigned char) (low_order >> 24);
+ signature_info->message[61]=(unsigned char) (low_order >> 16);
+ signature_info->message[62]=(unsigned char) (low_order >> 8);
+ signature_info->message[63]=(unsigned char) low_order;
+ TransformSignature(signature_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t S i g n a t u r e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetSignatureInfo initializes the SHA message digest structure.
+%
+% The format of the GetSignatureInfo method is:
+%
+% GetSignatureInfo(SignatureInfo *signature_info)
+%
+% A description of each parameter follows:
+%
+% o signature_info: The address of a structure of type SignatureInfo.
+%
+%
+*/
+MagickExport void GetSignatureInfo(SignatureInfo *signature_info)
+{
+ (void) memset(signature_info,0,sizeof(SignatureInfo));
+ signature_info->digest[0]=0x6a09e667UL;
+ signature_info->digest[1]=0xbb67ae85UL;
+ signature_info->digest[2]=0x3c6ef372UL;
+ signature_info->digest[3]=0xa54ff53aUL;
+ signature_info->digest[4]=0x510e527fUL;
+ signature_info->digest[5]=0x9b05688cUL;
+ signature_info->digest[6]=0x1f83d9abUL;
+ signature_info->digest[7]=0x5be0cd19UL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S i g n a t u r e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SignatureImage() computes a message digest from an image pixel stream with
+% an implementation of the NIST SHA-256 Message Digest algorithm. This
+% signature uniquely identifies the image and is convenient for determining
+% if an image has been modified or whether two images are identical.
+%
+% The format of the SignatureImage method is:
+%
+% unsigned int SignatureImage(Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+%
+*/
+#define SignatureImageText "[%s] Compute SHA-256 signature..."
+MagickExport unsigned int SignatureImage(Image *image)
+{
+ char
+ signature[MaxTextExtent];
+
+ const IndexPacket
+ *indexes;
+
+ long
+ y;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register unsigned char
+ *q;
+
+ SignatureInfo
+ signature_info;
+
+ unsigned char
+ *message;
+
+ unsigned long
+ quantum;
+
+ /*
+ Allocate memory for digital signature.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ message=MagickAllocateMemory(unsigned char *,20*image->columns);
+ if (message == (unsigned char *) NULL)
+ ThrowBinaryException3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToComputeImageSignature);
+ /*
+ Compute image digital signature.
+ */
+ GetSignatureInfo(&signature_info);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ q=message;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ quantum=ScaleQuantumToLong(p->red);
+ *q++=(unsigned char) (quantum >> 24);
+ *q++=(unsigned char) (quantum >> 16);
+ *q++=(unsigned char) (quantum >> 8);
+ *q++=(unsigned char) quantum;
+ quantum=ScaleQuantumToLong(p->green);
+ *q++=(unsigned char) (quantum >> 24);
+ *q++=(unsigned char) (quantum >> 16);
+ *q++=(unsigned char) (quantum >> 8);
+ *q++=(unsigned char) quantum;
+ quantum=ScaleQuantumToLong(p->blue);
+ *q++=(unsigned char) (quantum >> 24);
+ *q++=(unsigned char) (quantum >> 16);
+ *q++=(unsigned char) (quantum >> 8);
+ *q++=(unsigned char) quantum;
+ if (!image->matte)
+ {
+ if (image->colorspace == CMYKColorspace)
+ {
+ quantum=ScaleQuantumToLong(p->opacity);
+ *q++=(unsigned char) (quantum >> 24);
+ *q++=(unsigned char) (quantum >> 16);
+ *q++=(unsigned char) (quantum >> 8);
+ *q++=(unsigned char) quantum;
+ }
+ quantum=ScaleQuantumToLong(OpaqueOpacity);
+ *q++=(unsigned char) (quantum >> 24);
+ *q++=(unsigned char) (quantum >> 16);
+ *q++=(unsigned char) (quantum >> 8);
+ *q++=(unsigned char) quantum;
+ }
+ else
+ {
+ quantum=ScaleQuantumToLong(p->opacity);
+ *q++=(unsigned char) (quantum >> 24);
+ *q++=(unsigned char) (quantum >> 16);
+ *q++=(unsigned char) (quantum >> 8);
+ *q++=(unsigned char) quantum;
+ if (image->colorspace == CMYKColorspace)
+ {
+ quantum=ScaleQuantumToLong(indexes[x]);
+ *q++=(unsigned char) (quantum >> 24);
+ *q++=(unsigned char) (quantum >> 16);
+ *q++=(unsigned char) (quantum >> 8);
+ *q++=(unsigned char) quantum;
+ }
+ }
+ p++;
+ }
+ UpdateSignature(&signature_info,message,q-message);
+ if (QuantumTick(y,image->rows))
+ if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+ SignatureImageText,image->filename))
+ break;
+ }
+ FinalizeSignature(&signature_info);
+ MagickFreeMemory(message);
+ /*
+ Convert digital signature to a 64 character hex string.
+ */
+ FormatString(signature,"%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
+ signature_info.digest[0],signature_info.digest[1],signature_info.digest[2],
+ signature_info.digest[3],signature_info.digest[4],signature_info.digest[5],
+ signature_info.digest[6],signature_info.digest[7]);
+ (void) SetImageAttribute(image,"signature",(char *) NULL);
+ (void) SetImageAttribute(image,"signature",signature);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T r a n s f o r m S i g n a t u r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TransformSignature() transforms the SHA message digest.
+%
+% The format of the TransformSignature method is:
+%
+% TransformSignature(SignatureInfo *signature_info)
+%
+% A description of each parameter follows:
+%
+% o signature_info: The address of a structure of type SignatureInfo.
+%
+%
+*/
+MagickExport void TransformSignature(SignatureInfo *signature_info)
+{
+#define Ch(x,y,z) (((x) & (y))^(~(x) & (z)))
+#define Maj(x,y,z) (((x) & (y))^((x) & (z))^((y) & (z)))
+#define Rot32(x,n) Trunc32(((x >> n) | (x << (32-n))))
+#define Sigma0(x) (Rot32(x,7)^Rot32(x,18)^Trunc32(x >> 3))
+#define Sigma1(x) (Rot32(x,17)^Rot32(x,19)^Trunc32(x >> 10))
+#define Suma0(x) (Rot32(x,2)^Rot32(x,13)^Rot32(x,22))
+#define Suma1(x) (Rot32(x,6)^Rot32(x,11)^Rot32(x,25))
+
+ static unsigned long
+ K[64] =
+ {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+ 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+ 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+ 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+ 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+ 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+ 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+ 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+ 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+ 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+ }; /* 32-bit fractional part of the cube root of the first 64 primes */
+
+ int
+ j,
+ shift;
+
+ register long
+ i;
+
+ register unsigned char
+ *p;
+
+ unsigned long
+ A,
+ B,
+ C,
+ D,
+ E,
+ F,
+ G,
+ H,
+ lsb_first,
+ T,
+ T1,
+ T2,
+ W[64];
+
+ shift=32;
+ p=signature_info->message;
+ lsb_first=1;
+ if (*(char *) &lsb_first)
+ {
+ if (sizeof(lsb_first) > 4)
+ for (i=0; i < 16; i+=2)
+ {
+ T=(*((unsigned long *) p));
+ p+=8;
+ W[i]=((T << 24) & 0xff000000U) | ((T << 8) & 0x00ff0000U) |
+ ((T >> 8) & 0x0000ff00U) | ((T >> 24) & 0x000000ffU);
+ T>>=shift;
+ W[i+1]=((T << 24) & 0xff000000U) | ((T << 8) & 0x00ff0000U) |
+ ((T >> 8) & 0x0000ff00U) | ((T >> 24) & 0x000000ffU);
+ }
+ else
+ for (i=0; i < 16; i++)
+ {
+ T=(*((unsigned long *) p));
+ p+=4;
+ W[i]=((T << 24) & 0xff000000U) | ((T << 8) & 0x00ff0000U) |
+ ((T >> 8) & 0x0000ff00U) | ((T >> 24) & 0x000000ffU);
+ }
+ }
+ else
+ {
+ if (sizeof(lsb_first) > 4)
+ for (i=0; i < 16; i+=2)
+ {
+ T=(*((unsigned long *) p));
+ p+=8;
+ W[i]=Trunc32(T >> shift);
+ W[i+1]=Trunc32(T);
+ }
+ else
+ for (i=0; i < 16; i++)
+ {
+ T=(*((unsigned long *) p));
+ p+=4;
+ W[i]=Trunc32(T);
+ }
+ }
+ A=signature_info->digest[0];
+ B=signature_info->digest[1];
+ C=signature_info->digest[2];
+ D=signature_info->digest[3];
+ E=signature_info->digest[4];
+ F=signature_info->digest[5];
+ G=signature_info->digest[6];
+ H=signature_info->digest[7];
+ for (i=16; i < 64; i++)
+ W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
+ for (j=0; j < 64; j++)
+ {
+ T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
+ T2=Trunc32(Suma0(A)+Maj(A,B,C));
+ H=G;
+ G=F;
+ F=E;
+ E=Trunc32(D+T1);
+ D=C;
+ C=B;
+ B=A;
+ A=Trunc32(T1+T2);
+ }
+ signature_info->digest[0]=Trunc32(signature_info->digest[0]+A);
+ signature_info->digest[1]=Trunc32(signature_info->digest[1]+B);
+ signature_info->digest[2]=Trunc32(signature_info->digest[2]+C);
+ signature_info->digest[3]=Trunc32(signature_info->digest[3]+D);
+ signature_info->digest[4]=Trunc32(signature_info->digest[4]+E);
+ signature_info->digest[5]=Trunc32(signature_info->digest[5]+F);
+ signature_info->digest[6]=Trunc32(signature_info->digest[6]+G);
+ signature_info->digest[7]=Trunc32(signature_info->digest[7]+H);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U p d a t e S i g n a t u r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% UpdateSignature() updates the SHA message digest.
+%
+% The format of the UpdateSignature method is:
+%
+% UpdateSignature(SignatureInfo *signature_info,
+% const unsigned char *message,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o signature_info: The address of a structure of type SignatureInfo.
+%
+% o message: the message
+%
+% o length: The length of the message.
+%
+%
+*/
+MagickExport void UpdateSignature(SignatureInfo *signature_info,
+ const unsigned char *message,const size_t length)
+{
+ register long
+ i;
+
+ size_t
+ n;
+
+ unsigned long
+ count;
+
+ /*
+ Update the SHA digest.
+ */
+ n=length;
+ count=Trunc32(signature_info->low_order+((unsigned char) n << 3));
+ if (n < signature_info->low_order)
+ signature_info->high_order++;
+ signature_info->low_order=count;
+ signature_info->high_order+=(unsigned char) (n >> 29);
+ if (signature_info->offset)
+ {
+ i=SignatureSize-signature_info->offset;
+ if (i > (long) n)
+ i=(long) n;
+ (void) memcpy(signature_info->message+signature_info->offset,message,i);
+ n-=i;
+ message+=i;
+ signature_info->offset+=i;
+ if (signature_info->offset != SignatureSize)
+ return;
+ TransformSignature(signature_info);
+ }
+ while (n >= SignatureSize)
+ {
+ (void) memcpy(signature_info->message,message,SignatureSize);
+ message+=SignatureSize;
+ n-=SignatureSize;
+ TransformSignature(signature_info);
+ }
+ (void) memcpy(signature_info->message,message,n);
+ signature_info->offset=(long) n;
+}
diff --git a/magick/signature.h b/magick/signature.h
new file mode 100644
index 0000000..f466ee2
--- /dev/null
+++ b/magick/signature.h
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Digital signature methods.
+*/
+#ifndef _MAGICK_SIGNATURE_H
+#define _MAGICK_SIGNATURE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Define declarations.
+*/
+#define SignatureSize 64
+
+/*
+ Typedef declarations.
+*/
+typedef struct _SignatureInfo
+{
+ unsigned long
+ digest[8],
+ low_order,
+ high_order;
+
+ long
+ offset;
+
+ unsigned char
+ message[SignatureSize];
+} SignatureInfo;
+
+/*
+ Method declarations.
+*/
+extern MagickExport unsigned int
+ SignatureImage(Image *);
+
+extern MagickExport void
+ FinalizeSignature(SignatureInfo *),
+ GetSignatureInfo(SignatureInfo *),
+ TransformSignature(SignatureInfo *),
+ UpdateSignature(SignatureInfo *,const unsigned char *,const size_t);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/spinlock.h b/magick/spinlock.h
new file mode 100644
index 0000000..3aa7a18
--- /dev/null
+++ b/magick/spinlock.h
@@ -0,0 +1,95 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Spinlock Methods. These are highly lightweight functions that
+ are used to prevent deadlocks on access to global data when the normal
+ semaphore system has not yet been initialized. They are intended to only
+ be used to protect operations that are very fast - like a flag that tells
+ you that something has been inited, or bumping a counter. Do NOT use this
+ for protecting an operation that will take any significant amount of time.
+*/
+#ifndef _SPINLOCKS_H
+#define _SPINLOCKS_H
+
+#if defined(MSWINDOWS)
+
+#define SPINLOCK_DELAY_MILLI_SECS 10
+
+static LONG volatile
+ spinlock_mutex = 0;
+
+/* Wait for spin lock */
+static void _spinlock_wait (LONG volatile *sl)
+{
+ /*
+ LONG InterlockedCompareExchange(LONG volatile* dest, LONG xchg,
+ LONG compare)
+
+ Performs an atomic compare-and-exchange operation on the specified
+ values. The function compares two specified 32-bit values and
+ exchanges with another 32-bit value based on the outcome of the
+ comparison.
+
+ If you are exchanging pointer values, this function has been
+ superseded by the InterlockedCompareExchangePointer function.
+
+ To operate on 64-bit values, use the InterlockedCompareExchange64
+ function.
+ */
+ while (InterlockedCompareExchange (sl, 1L, 0L) != 0)
+ {
+ /* slight delay - just in case OS does not giveup CPU */
+ Sleep (SPINLOCK_DELAY_MILLI_SECS);
+ }
+}
+/* Release spin lock */
+static void _spinlock_release (LONG volatile *sl)
+{
+ /*
+ LONG InterlockedExchange (LONG volatile* dest, LONG val)
+
+ Sets a 32-bit variable to the specified value as an atomic
+ operation.
+
+ To operate on a pointer variable, use the
+ InterlockedExchangePointer function.
+
+ To operate on a 64-bit variable, use the InterlockedExchange64
+ function.
+ */
+ InterlockedExchange (sl, 0L);
+}
+#define SPINLOCK_WAIT _spinlock_wait(&spinlock_mutex)
+#define SPINLOCK_RELEASE _spinlock_release(&spinlock_mutex)
+
+#else /* not MSWINDOWS */
+
+#if defined(HAVE_PTHREAD)
+
+static pthread_mutex_t
+ spinlock_mutex = PTHREAD_MUTEX_INITIALIZER;
+#define SPINLOCK_WAIT (void) pthread_mutex_lock(&spinlock_mutex)
+#define SPINLOCK_RELEASE (void) pthread_mutex_unlock(&spinlock_mutex)
+
+#else /* not HAVE_PTHREAD */
+
+#define SPINLOCK_WAIT
+#define SPINLOCK_RELEASE
+
+#endif /* HAVE_PTHREAD */
+
+#endif /* MSWINDOWS */
+#endif /* _SPINLOCKS_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/static.c b/magick/static.c
new file mode 100644
index 0000000..fd140a9
--- /dev/null
+++ b/magick/static.c
@@ -0,0 +1,429 @@
+/*
+% Copyright (C) 2003-2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% SSSSS TTTTT AAA TTTTT IIIII CCCC %
+% SS T A A T I C %
+% SSS T AAAAA T I C %
+% SS T A A T I C %
+% SSSSS T A A T IIIII CCCC %
+% %
+% %
+% GraphicsMagick Static Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% March 2000 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/module.h"
+#include "magick/static.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x e c u t e S t a t i c M o d u l e P r o c e s s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ExecuteStaticModuleProcess() is just a template method. This version is
+% only used for static and moby builds. See the version in module.c for
+% module-only builds. This function takes the place of ExecuteModuleProcess
+% for builds which do not support loading modules.
+%
+% The format of the ExecuteStaticModuleProcess method is:
+%
+% unsigned int ExecuteStaticModuleProcess(const char *tag,
+% Image **image,const int argc,char **argv)
+%
+% A description of each parameter follows:
+%
+% o tag: The module tag.
+%
+% o image: The image.
+%
+% o argc: The number of elements in the argument vector.
+%
+% o argv: A text array containing the command line arguments.
+%
+*/
+#if defined(SupportMagickModules)
+MagickExport unsigned int ExecuteStaticModuleProcess(const char *tag,
+ Image **image,const int argc,char **argv)
+#else
+MagickExport unsigned int ExecuteModuleProcess(const char *tag,
+ Image **image,const int argc,char **argv)
+#endif /* defined(SupportMagickModules) */
+{
+ unsigned int
+ status = False;
+
+#if !defined(BuildMagickModules)
+ unsigned int
+ (*method)(Image **,const int,char **) = 0;
+
+ if (LocaleCompare("analyze",tag) == 0)
+ method=AnalyzeImage;
+
+ if (method)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Invoking \"%.1024s\" filter module",tag);
+
+ status=(*method)(image,argc,argv);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Returned from \"%.1024s\" filter module",tag);
+ }
+#else
+ ARG_NOT_USED(tag);
+ ARG_NOT_USED(image);
+ ARG_NOT_USED(argc);
+ ARG_NOT_USED(argv);
+#endif /* !defined(BuildMagickModules) */
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e g i s t e r S t a t i c M o d u l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+RegisterStaticModules() statically registers all the available module
+% handlers.
+%
+% The format of the RegisterStaticModules method is:
+%
+% RegisterStaticModules(void)
+%
+%
+*/
+MagickExport void RegisterStaticModules(void)
+{
+#if !defined(BuildMagickModules)
+ RegisterARTImage();
+ RegisterAVSImage();
+ RegisterBMPImage();
+ RegisterCALSImage();
+ RegisterCAPTIONImage();
+ RegisterCINEONImage();
+#if defined(HasWINGDI32)
+ RegisterCLIPBOARDImage();
+#endif
+ RegisterCMYKImage();
+ RegisterCUTImage();
+ RegisterDCMImage();
+ RegisterDCRAWImage();
+ RegisterDIBImage();
+#if defined(HasDPS)
+ RegisterDPSImage();
+#endif
+ RegisterDPXImage();
+#if defined(HasWINGDI32)
+ RegisterEMFImage();
+#endif
+#if defined(HasTIFF)
+ RegisterEPTImage();
+#endif
+ RegisterFAXImage();
+ RegisterFITSImage();
+#if defined(HasFPX)
+ RegisterFPXImage();
+#endif
+ RegisterGIFImage();
+ RegisterGRAYImage();
+ RegisterGRADIENTImage();
+ RegisterHISTOGRAMImage();
+ RegisterHRZImage();
+ RegisterHTMLImage();
+ RegisterICONImage();
+ RegisterIDENTITYImage();
+ RegisterINFOImage();
+#if defined(HasJBIG)
+ RegisterJBIGImage();
+#endif
+#if defined(HasJPEG)
+ RegisterJNXImage();
+#endif
+#if defined(HasJPEG)
+ RegisterJPEGImage();
+#endif
+#if defined(HasJP2)
+ RegisterJP2Image();
+#endif
+ RegisterLABELImage();
+ RegisterLOCALEImage();
+ RegisterLOGOImage();
+ RegisterMACImage();
+ RegisterMAPImage();
+ RegisterMATImage();
+ RegisterMATTEImage();
+ RegisterMETAImage();
+ RegisterMIFFImage();
+ RegisterMONOImage();
+ RegisterMPCImage();
+ RegisterMPEGImage();
+ RegisterMPRImage();
+ RegisterMSLImage();
+ RegisterMTVImage();
+ RegisterMVGImage();
+ RegisterNULLImage();
+ RegisterOTBImage();
+ RegisterPALMImage();
+ RegisterPCDImage();
+ RegisterPCLImage();
+ RegisterPCXImage();
+ RegisterPDBImage();
+ RegisterPDFImage();
+ RegisterPICTImage();
+ RegisterPIXImage();
+ RegisterPLASMAImage();
+#if defined(HasPNG)
+ RegisterPNGImage();
+#endif
+ RegisterPNMImage();
+ RegisterPREVIEWImage();
+ RegisterPSImage();
+ RegisterPS2Image();
+ RegisterPS3Image();
+#if defined(EnableBrokenCoders) && EnableBrokenCoders
+ RegisterPSDImage();
+#endif /* defined(EnableBrokenCoders) && EnableBrokenCoders */
+ RegisterPWPImage();
+ RegisterRGBImage();
+ RegisterRLAImage();
+ RegisterRLEImage();
+ RegisterSCTImage();
+ RegisterSFWImage();
+ RegisterSGIImage();
+ RegisterSTEGANOImage();
+ RegisterSUNImage();
+ RegisterSVGImage();
+ RegisterTGAImage();
+#if defined(HasTIFF)
+ RegisterTIFFImage();
+#endif
+ RegisterTILEImage();
+ RegisterTIMImage();
+ RegisterTOPOLImage();
+ RegisterTTFImage();
+ RegisterTXTImage();
+ RegisterUILImage();
+ RegisterURLImage();
+ RegisterUYVYImage();
+ RegisterVICARImage();
+ RegisterVIDImage();
+ RegisterVIFFImage();
+ RegisterWBMPImage();
+#if defined(HasWEBP)
+ RegisterWEBPImage();
+#endif
+ RegisterWMFImage();
+ RegisterWPGImage();
+#if defined(HasX11)
+ RegisterXImage();
+#endif /* defined(HasX11) */
+ RegisterXBMImage();
+ RegisterXCImage();
+ RegisterXCFImage();
+ RegisterXPMImage();
+#if defined(_VISUALC_)
+ RegisterXTRNImage();
+#endif /* defined(_VISUALC_) */
+#if defined(HasX11)
+ RegisterXWDImage();
+#endif /* defined(HasX11) */
+ RegisterYUVImage();
+#endif /* !defined(BuildMagickModules) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U n r e g i s t e r S t a t i c M o d u l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% UnregisterStaticModules() statically unregisters all the available module
+% handlers. This allows allocated resources to be freed.
+%
+% The format of the UnRegisterStaticModules method is:
+%
+% UnRegisterStaticModules(void)
+%
+%
+*/
+MagickExport void UnregisterStaticModules(void)
+{
+#if !defined(BuildMagickModules)
+ UnregisterARTImage();
+ UnregisterAVSImage();
+ UnregisterBMPImage();
+ UnregisterCALSImage();
+ UnregisterCAPTIONImage();
+ UnregisterCINEONImage();
+#if defined(HasWINGDI32)
+ UnregisterCLIPBOARDImage();
+#endif
+ UnregisterCMYKImage();
+ UnregisterCUTImage();
+ UnregisterDCMImage();
+ UnregisterDCRAWImage();
+ UnregisterDIBImage();
+#if defined(HasDPS)
+ UnregisterDPSImage();
+#endif
+ UnregisterDPXImage();
+#if defined(HasWINGDI32)
+ UnregisterEMFImage();
+#endif
+#if defined(HasTIFF)
+ UnregisterEPTImage();
+#endif
+ UnregisterFAXImage();
+ UnregisterFITSImage();
+#if defined(HasFPX)
+ UnregisterFPXImage();
+#endif
+ UnregisterGIFImage();
+ UnregisterGRAYImage();
+ UnregisterGRADIENTImage();
+ UnregisterHISTOGRAMImage();
+ UnregisterHRZImage();
+ UnregisterHTMLImage();
+ UnregisterICONImage();
+ UnregisterIDENTITYImage();
+ UnregisterINFOImage();
+#if defined(HasJBIG)
+ UnregisterJBIGImage();
+#endif
+#if defined(HasJPEG)
+ UnregisterJNXImage();
+#endif
+#if defined(HasJPEG)
+ UnregisterJPEGImage();
+#endif
+#if defined(HasJP2)
+ UnregisterJP2Image();
+#endif
+ UnregisterLABELImage();
+ UnregisterLOCALEImage();
+ UnregisterLOGOImage();
+ UnregisterMACImage();
+ UnregisterMAPImage();
+ UnregisterMATImage();
+ UnregisterMATTEImage();
+ UnregisterMETAImage();
+ UnregisterMIFFImage();
+ UnregisterMONOImage();
+ UnregisterMPCImage();
+ UnregisterMPEGImage();
+ UnregisterMPRImage();
+ UnregisterMSLImage();
+ UnregisterMTVImage();
+ UnregisterMVGImage();
+ UnregisterNULLImage();
+ UnregisterOTBImage();
+ UnregisterPALMImage();
+ UnregisterPCDImage();
+ UnregisterPCLImage();
+ UnregisterPCXImage();
+ UnregisterPDBImage();
+ UnregisterPDFImage();
+ UnregisterPICTImage();
+ UnregisterPIXImage();
+ UnregisterPLASMAImage();
+#if defined(HasPNG)
+ UnregisterPNGImage();
+#endif
+ UnregisterPNMImage();
+ UnregisterPREVIEWImage();
+ UnregisterPSImage();
+ UnregisterPS2Image();
+ UnregisterPS3Image();
+#if defined(EnableBrokenCoders) && EnableBrokenCoders
+ UnregisterPSDImage();
+#endif /* defined(EnableBrokenCoders) && EnableBrokenCoders */
+ UnregisterPWPImage();
+ UnregisterRGBImage();
+ UnregisterRLAImage();
+ UnregisterRLEImage();
+ UnregisterSCTImage();
+ UnregisterSFWImage();
+ UnregisterSGIImage();
+ UnregisterSTEGANOImage();
+ UnregisterSUNImage();
+ UnregisterSVGImage();
+ UnregisterTGAImage();
+#if defined(HasTIFF)
+ UnregisterTIFFImage();
+#endif
+ UnregisterTILEImage();
+ UnregisterTIMImage();
+ UnregisterTOPOLImage();
+ UnregisterTTFImage();
+ UnregisterTXTImage();
+ UnregisterUILImage();
+ UnregisterURLImage();
+ UnregisterUYVYImage();
+ UnregisterVICARImage();
+ UnregisterVIDImage();
+ UnregisterVIFFImage();
+ UnregisterWBMPImage();
+#if defined(HasWEBP)
+ UnregisterWEBPImage();
+#endif
+ UnregisterWMFImage();
+ UnregisterWPGImage();
+#if defined(HasX11)
+ UnregisterXImage();
+#endif /* defined(HasX11) */
+ UnregisterXBMImage();
+ UnregisterXCImage();
+ UnregisterXCFImage();
+ UnregisterXPMImage();
+#if defined(_VISUALC_)
+ UnregisterXTRNImage();
+#endif /* defined(_VISUALC_) */
+#if defined(HasX11)
+ UnregisterXWDImage();
+#endif /* defined(HasX11) */
+ UnregisterYUVImage();
+#endif /* !defined(BuildMagickModules) */
+}
diff --git a/magick/static.h b/magick/static.h
new file mode 100644
index 0000000..8de6d06
--- /dev/null
+++ b/magick/static.h
@@ -0,0 +1,316 @@
+/*
+ Copyright (C) 2003-2010 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Coder Registration Methods.
+*/
+#ifndef _MAGICK_STATIC_H
+#define _MAGICK_STATIC_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if !defined(BuildMagickModules)
+extern ModuleExport void
+ RegisterARTImage(void),
+ RegisterAVIImage(void),
+ RegisterAVSImage(void),
+ RegisterBIEImage(void),
+ RegisterBMPImage(void),
+ RegisterCALSImage(void),
+ RegisterCAPTIONImage(void),
+ RegisterCINEONImage(void),
+ RegisterCLIPBOARDImage(void),
+ RegisterCMYKImage(void),
+ RegisterCUTImage(void),
+ RegisterDCMImage(void),
+ RegisterDCRAWImage(void),
+ RegisterDCXImage(void),
+ RegisterDIBImage(void),
+ RegisterDPSImage(void),
+ RegisterDPXImage(void),
+ RegisterEMFImage(void),
+ RegisterEPDFImage(void),
+ RegisterEPIImage(void),
+ RegisterEPSImage(void),
+ RegisterEPS2Image(void),
+ RegisterEPSFImage(void),
+ RegisterEPSIImage(void),
+ RegisterEPTImage(void),
+ RegisterFAXImage(void),
+ RegisterFITSImage(void),
+ RegisterFPXImage(void),
+ RegisterG3Image(void),
+ RegisterGIFImage(void),
+ RegisterGIF87Image(void),
+ RegisterGRADIENTImage(void),
+ RegisterGRANITEImage(void),
+ RegisterGRAYImage(void),
+ RegisterHImage(void),
+ RegisterHISTOGRAMImage(void),
+ RegisterHRZImage(void),
+ RegisterHTMImage(void),
+ RegisterHTMLImage(void),
+ RegisterICBImage(void),
+ RegisterICONImage(void),
+ RegisterIDENTITYImage(void),
+ RegisterINFOImage(void),
+ RegisterJBGImage(void),
+ RegisterJBIGImage(void),
+ RegisterJNXImage(void),
+ RegisterJPGImage(void),
+ RegisterJPEGImage(void),
+ RegisterJP2Image(void),
+ RegisterLABELImage(void),
+ RegisterLOCALEImage(void),
+ RegisterLOGOImage(void),
+ RegisterMACImage(void),
+ RegisterMAPImage(void),
+ RegisterMATImage(void),
+ RegisterMATTEImage(void),
+ RegisterMETAImage(void),
+ RegisterMIFFImage(void),
+ RegisterMNGImage(void),
+ RegisterMONOImage(void),
+ RegisterMPCImage(void),
+ RegisterMPEGImage(void),
+ RegisterMPRImage(void),
+ RegisterMSLImage(void),
+ RegisterMTVImage(void),
+ RegisterMVGImage(void),
+ RegisterNETSCAPEImage(void),
+ RegisterNULLImage(void),
+ RegisterP7Image(void),
+ RegisterPBMImage(void),
+ RegisterOTBImage(void),
+ RegisterPALMImage(void),
+ RegisterPCDImage(void),
+ RegisterPCDSImage(void),
+ RegisterPCLImage(void),
+ RegisterPCTImage(void),
+ RegisterPCXImage(void),
+ RegisterPDBImage(void),
+ RegisterPDFImage(void),
+ RegisterPICImage(void),
+ RegisterPICTImage(void),
+ RegisterPIXImage(void),
+ RegisterPLASMAImage(void),
+ RegisterPGMImage(void),
+ RegisterPMImage(void),
+ RegisterPNGImage(void),
+ RegisterPNMImage(void),
+ RegisterPPMImage(void),
+ RegisterPREVIEWImage(void),
+ RegisterPSImage(void),
+ RegisterPS2Image(void),
+ RegisterPS3Image(void),
+ RegisterPSDImage(void),
+ RegisterPTIFImage(void),
+ RegisterPWPImage(void),
+ RegisterRASImage(void),
+ RegisterRGBImage(void),
+ RegisterRGBAImage(void),
+ RegisterRLAImage(void),
+ RegisterRLEImage(void),
+ RegisterSCTImage(void),
+ RegisterSFWImage(void),
+ RegisterSGIImage(void),
+ RegisterSHTMLImage(void),
+ RegisterSTEGANOImage(void),
+ RegisterSUNImage(void),
+ RegisterSVGImage(void),
+ RegisterTEXTImage(void),
+ RegisterTGAImage(void),
+ RegisterTIFImage(void),
+ RegisterTIFFImage(void),
+ RegisterTILEImage(void),
+ RegisterTIMImage(void),
+ RegisterTOPOLImage(void),
+ RegisterTTFImage(void),
+ RegisterTXTImage(void),
+ RegisterUILImage(void),
+ RegisterURLImage(void),
+ RegisterUYVYImage(void),
+ RegisterVDAImage(void),
+ RegisterVICARImage(void),
+ RegisterVIDImage(void),
+ RegisterVIFFImage(void),
+ RegisterVSTImage(void),
+ RegisterWBMPImage(void),
+ RegisterWEBPImage(void),
+ RegisterWMFImage(void),
+ RegisterWPGImage(void),
+ RegisterXImage(void),
+ RegisterXBMImage(void),
+ RegisterXCImage(void),
+ RegisterXCFImage(void),
+ RegisterXPMImage(void),
+ RegisterXVImage(void),
+#if defined(_VISUALC_)
+ RegisterXTRNImage(void),
+#endif
+ RegisterXWDImage(void),
+ RegisterYUVImage(void),
+ UnregisterARTImage(void),
+ UnregisterAVIImage(void),
+ UnregisterAVSImage(void),
+ UnregisterBIEImage(void),
+ UnregisterBMPImage(void),
+ UnregisterCALSImage(void),
+ UnregisterCAPTIONImage(void),
+ UnregisterCINEONImage(void),
+ UnregisterCLIPBOARDImage(void),
+ UnregisterCMYKImage(void),
+ UnregisterCUTImage(void),
+ UnregisterDCMImage(void),
+ UnregisterDCRAWImage(void),
+ UnregisterDCXImage(void),
+ UnregisterDIBImage(void),
+ UnregisterDPSImage(void),
+ UnregisterDPXImage(void),
+ UnregisterEMFImage(void),
+ UnregisterEPDFImage(void),
+ UnregisterEPIImage(void),
+ UnregisterEPSImage(void),
+ UnregisterEPS2Image(void),
+ UnregisterEPSFImage(void),
+ UnregisterEPSIImage(void),
+ UnregisterEPTImage(void),
+ UnregisterFAXImage(void),
+ UnregisterFITSImage(void),
+ UnregisterFPXImage(void),
+ UnregisterG3Image(void),
+ UnregisterGIFImage(void),
+ UnregisterGIF87Image(void),
+ UnregisterGRADIENTImage(void),
+ UnregisterGRANITEImage(void),
+ UnregisterGRAYImage(void),
+ UnregisterHImage(void),
+ UnregisterHISTOGRAMImage(void),
+ UnregisterHRZImage(void),
+ UnregisterHTMImage(void),
+ UnregisterHTMLImage(void),
+ UnregisterICBImage(void),
+ UnregisterICONImage(void),
+ UnregisterIDENTITYImage(void),
+ UnregisterINFOImage(void),
+ UnregisterJBGImage(void),
+ UnregisterJBIGImage(void),
+ UnregisterJNXImage(void),
+ UnregisterJPGImage(void),
+ UnregisterJPEGImage(void),
+ UnregisterJP2Image(void),
+ UnregisterLABELImage(void),
+ UnregisterLOCALEImage(void),
+ UnregisterLOGOImage(void),
+ UnregisterMACImage(void),
+ UnregisterMAPImage(void),
+ UnregisterMATImage(void),
+ UnregisterMATTEImage(void),
+ UnregisterMETAImage(void),
+ UnregisterMIFFImage(void),
+ UnregisterMNGImage(void),
+ UnregisterMONOImage(void),
+ UnregisterMPCImage(void),
+ UnregisterMPEGImage(void),
+ UnregisterMPRImage(void),
+ UnregisterMSLImage(void),
+ UnregisterMTVImage(void),
+ UnregisterMVGImage(void),
+ UnregisterNETSCAPEImage(void),
+ UnregisterNULLImage(void),
+ UnregisterP7Image(void),
+ UnregisterPBMImage(void),
+ UnregisterOTBImage(void),
+ UnregisterPALMImage(void),
+ UnregisterPCDImage(void),
+ UnregisterPCDSImage(void),
+ UnregisterPCLImage(void),
+ UnregisterPCTImage(void),
+ UnregisterPCXImage(void),
+ UnregisterPDBImage(void),
+ UnregisterPDFImage(void),
+ UnregisterPICImage(void),
+ UnregisterPICTImage(void),
+ UnregisterPIXImage(void),
+ UnregisterPLASMAImage(void),
+ UnregisterPGMImage(void),
+ UnregisterPMImage(void),
+ UnregisterPNGImage(void),
+ UnregisterPNMImage(void),
+ UnregisterPPMImage(void),
+ UnregisterPREVIEWImage(void),
+ UnregisterPSImage(void),
+ UnregisterPS2Image(void),
+ UnregisterPS3Image(void),
+ UnregisterPSDImage(void),
+ UnregisterPTIFImage(void),
+ UnregisterPWPImage(void),
+ UnregisterRASImage(void),
+ UnregisterRGBImage(void),
+ UnregisterRGBAImage(void),
+ UnregisterRLAImage(void),
+ UnregisterRLEImage(void),
+ UnregisterSCTImage(void),
+ UnregisterSFWImage(void),
+ UnregisterSGIImage(void),
+ UnregisterSHTMLImage(void),
+ UnregisterSTEGANOImage(void),
+ UnregisterSUNImage(void),
+ UnregisterSVGImage(void),
+ UnregisterTEXTImage(void),
+ UnregisterTGAImage(void),
+ UnregisterTIFImage(void),
+ UnregisterTIFFImage(void),
+ UnregisterTILEImage(void),
+ UnregisterTIMImage(void),
+ UnregisterTOPOLImage(void),
+ UnregisterTTFImage(void),
+ UnregisterTXTImage(void),
+ UnregisterUILImage(void),
+ UnregisterURLImage(void),
+ UnregisterUYVYImage(void),
+ UnregisterVDAImage(void),
+ UnregisterVICARImage(void),
+ UnregisterVIDImage(void),
+ UnregisterVIFFImage(void),
+ UnregisterVSTImage(void),
+ UnregisterWBMPImage(void),
+ UnregisterWEBPImage(void),
+ UnregisterWMFImage(void),
+ UnregisterWPGImage(void),
+ UnregisterXImage(void),
+ UnregisterXBMImage(void),
+ UnregisterXCImage(void),
+ UnregisterXCFImage(void),
+ UnregisterXPMImage(void),
+ UnregisterXVImage(void),
+#if defined(_VISUALC_)
+ UnregisterXTRNImage(void),
+#endif
+ UnregisterXWDImage(void),
+ UnregisterYUVImage(void);
+
+extern unsigned int
+ AnalyzeImage(Image **,const int,char**);
+
+#endif /* !defined(BuildMagickModules) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_STATIC_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/statistics.c b/magick/statistics.c
new file mode 100644
index 0000000..a9b3d0c
--- /dev/null
+++ b/magick/statistics.c
@@ -0,0 +1,295 @@
+/*
+% Copyright (C) 2003 - 2014 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% GraphicsMagick Image Statistics Methods.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/pixel_iterator.h"
+#include "magick/statistics.h"
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t I m a g e S t a t i s t i c s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageStatistics computes common statistics (currently maximum, minimum,
+% mean and standard deviation) for the available image channels. The
+% per-channel values are returned in an ImageStatistics structure. Statistics
+% are normalized to the range 0.0 to 1.0. Multiply values by MaxRGB to obtain
+% the statistics in quantum units. Statistics for non-existent channels are
+% set to zero.
+%
+% The format of the GetImageStatistics method is:
+%
+% MagickPassFail GetImageStatistics(const Image *image,
+% ImageStatistics *statistics
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o statistics: An ImageStatistics structure to update with statistics.
+%
+% o exception: Any errors are reported here.
+%
+*/
+typedef struct _StatisticsContext {
+ double samples;
+ double variance_divisor;
+} StatisticsContext;
+static MagickPassFail GetImageStatisticsMean(void *mutable_data,
+ const void *immutable_data,
+ const Image *image,
+ const PixelPacket *pixel,
+ const IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ ImageStatistics
+ lstatistics,
+ *statistics=(ImageStatistics *) mutable_data;
+
+ const StatisticsContext
+ *context=(const StatisticsContext *) immutable_data;
+
+ double
+ normalized;
+
+ register long
+ i;
+
+ const MagickBool
+ process_opacity=((image->matte) ||
+ (image->colorspace == CMYKColorspace));
+
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ (void) memset(&lstatistics, 0, sizeof(ImageStatistics));
+ lstatistics.red.minimum=1.0;
+ lstatistics.green.minimum=1.0;
+ lstatistics.blue.minimum=1.0;
+ if (process_opacity)
+ lstatistics.opacity.minimum=1.0;
+
+ for (i=0; i < npixels; i++)
+ {
+ normalized=(double) pixel[i].red/MaxRGB;
+ lstatistics.red.mean += normalized/context->samples;
+ if (normalized > lstatistics.red.maximum)
+ lstatistics.red.maximum=normalized;
+ if (normalized < lstatistics.red.minimum)
+ lstatistics.red.minimum=normalized;
+
+ normalized=(double) pixel[i].green/MaxRGB;
+ lstatistics.green.mean += normalized/context->samples;
+ if (normalized > lstatistics.green.maximum)
+ lstatistics.green.maximum=normalized;
+ if (normalized < lstatistics.green.minimum)
+ lstatistics.green.minimum=normalized;
+
+ normalized=(double) pixel[i].blue/MaxRGB;
+ lstatistics.blue.mean += normalized/context->samples;
+ if (normalized > lstatistics.blue.maximum)
+ lstatistics.blue.maximum=normalized;
+ if (normalized < lstatistics.blue.minimum)
+ lstatistics.blue.minimum=normalized;
+
+ if (process_opacity)
+ {
+ normalized=(double) pixel[i].opacity/MaxRGB;
+ lstatistics.opacity.mean += normalized/context->samples;
+ if (normalized > lstatistics.opacity.maximum)
+ lstatistics.opacity.maximum=normalized;
+ if (normalized < lstatistics.opacity.minimum)
+ lstatistics.opacity.minimum=normalized;
+ }
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageStatisticsMean)
+#endif
+ {
+ statistics->red.mean += lstatistics.red.mean;
+ if (lstatistics.red.maximum > statistics->red.maximum)
+ statistics->red.maximum=lstatistics.red.maximum;
+ if (lstatistics.red.minimum < statistics->red.minimum)
+ statistics->red.minimum=lstatistics.red.minimum;
+
+ statistics->green.mean += lstatistics.green.mean;
+ if (lstatistics.green.maximum > statistics->green.maximum)
+ statistics->green.maximum=lstatistics.green.maximum;
+ if (lstatistics.green.minimum < statistics->green.minimum)
+ statistics->green.minimum=lstatistics.green.minimum;
+
+ statistics->blue.mean += lstatistics.blue.mean;
+ if (lstatistics.blue.maximum > statistics->blue.maximum)
+ statistics->blue.maximum=lstatistics.blue.maximum;
+ if (lstatistics.blue.minimum < statistics->blue.minimum)
+ statistics->blue.minimum=lstatistics.blue.minimum;
+
+ if (process_opacity)
+ {
+ statistics->opacity.mean += lstatistics.opacity.mean;
+ if (lstatistics.opacity.maximum > statistics->opacity.maximum)
+ statistics->opacity.maximum=lstatistics.opacity.maximum;
+ if (lstatistics.opacity.minimum < statistics->opacity.minimum)
+ statistics->opacity.minimum=lstatistics.opacity.minimum;
+ }
+ }
+
+ return MagickPass;
+}
+#define Square(x) ((x)*(x))
+static MagickPassFail GetImageStatisticsVariance(void *mutable_data,
+ const void *immutable_data,
+ const Image *image,
+ const PixelPacket *pixel,
+ const IndexPacket *indexes,
+ const long npixels,
+ ExceptionInfo *exception)
+{
+ ImageStatistics
+ lstatistics,
+ *statistics=(ImageStatistics *) mutable_data;
+
+ const StatisticsContext
+ *context=(const StatisticsContext *) immutable_data;
+
+ double
+ normalized;
+
+ register long
+ i;
+
+ const MagickBool
+ process_opacity=((image->matte) ||
+ (image->colorspace == CMYKColorspace));
+
+ ARG_NOT_USED(indexes);
+ ARG_NOT_USED(exception);
+
+ (void) memset(&lstatistics, 0, sizeof(ImageStatistics));
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageStatisticsVariance)
+#endif
+ {
+ lstatistics.red.mean=statistics->red.mean;
+ lstatistics.green.mean=statistics->green.mean;
+ lstatistics.blue.mean=statistics->blue.mean;
+ lstatistics.opacity.mean=statistics->opacity.mean;
+ }
+
+ for (i=0; i < npixels; i++)
+ {
+ normalized=(double) pixel[i].red/MaxRGB;
+ lstatistics.red.variance +=
+ Square(normalized-lstatistics.red.mean)/context->variance_divisor;
+
+ normalized=(double) pixel[i].green/MaxRGB;
+ lstatistics.green.variance +=
+ Square(normalized-lstatistics.green.mean)/context->variance_divisor;
+
+ normalized=(double) pixel[i].blue/MaxRGB;
+ lstatistics.blue.variance +=
+ Square(normalized-lstatistics.blue.mean)/context->variance_divisor;
+
+ if (process_opacity)
+ {
+ normalized=(double) pixel[i].opacity/MaxRGB;
+ lstatistics.opacity.variance +=
+ Square(normalized-lstatistics.opacity.mean)/context->variance_divisor;
+ }
+ }
+
+#if defined(HAVE_OPENMP)
+# pragma omp critical (GM_GetImageStatisticsVariance)
+#endif
+ {
+ statistics->red.variance += lstatistics.red.variance;
+ statistics->green.variance += lstatistics.green.variance;
+ statistics->blue.variance += lstatistics.blue.variance;
+ statistics->opacity.variance += lstatistics.opacity.variance;
+ }
+
+ return MagickPass;
+}
+MagickExport MagickPassFail GetImageStatistics(const Image *image,
+ ImageStatistics *statistics,
+ ExceptionInfo *exception)
+{
+ StatisticsContext
+ context;
+
+ MagickPassFail
+ status=MagickPass;
+
+ double
+ samples;
+
+ const MagickBool
+ process_opacity=((image->matte) ||
+ (image->colorspace == CMYKColorspace));
+
+ (void) memset((void *) statistics, 0, sizeof(ImageStatistics));
+ statistics->red.minimum=1.0;
+ statistics->green.minimum=1.0;
+ statistics->blue.minimum=1.0;
+ if (process_opacity)
+ statistics->opacity.minimum=1.0;
+
+ samples=(double) image->rows*image->columns;
+ context.samples=samples;
+ context.variance_divisor=samples-1;
+
+ /*
+ Compute Mean, Max, and Min
+ */
+ status = PixelIterateMonoRead(GetImageStatisticsMean,
+ NULL,
+ "[%s] Compute image mean, max, min...",
+ statistics,&context,0,0,image->columns,
+ image->rows,image,exception);
+ /*
+ Compute Variance
+ */
+ if (status == MagickPass)
+ status = PixelIterateMonoRead(GetImageStatisticsVariance,
+ NULL,
+ "[%s] Compute image variance...",
+ statistics,&context,0,0,image->columns,
+ image->rows,image,exception);
+ /*
+ Compute Standard Deviation
+ */
+ if (status == MagickPass)
+ {
+ statistics->red.standard_deviation=sqrt(statistics->red.variance);
+ statistics->green.standard_deviation=sqrt(statistics->green.variance);
+ statistics->blue.standard_deviation=sqrt(statistics->blue.variance);
+ if (process_opacity)
+ statistics->opacity.standard_deviation=sqrt(statistics->opacity.variance);
+ }
+
+ return status;
+}
+
diff --git a/magick/statistics.h b/magick/statistics.h
new file mode 100644
index 0000000..7fea1bb
--- /dev/null
+++ b/magick/statistics.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Image Statistics Methods.
+*/
+#ifndef _MAGICK_STATISTICS_H
+#define _MAGICK_STATISTICS_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/image.h"
+#include "magick/error.h"
+
+typedef struct _ImageChannelStatistics
+ {
+ /* Minimum value observed */
+ double maximum;
+ /* Maximum value observed */
+ double minimum;
+ /* Average (mean) value observed */
+ double mean;
+ /* Standard deviation, sqrt(variance) */
+ double standard_deviation;
+ /* Variance */
+ double variance;
+ } ImageChannelStatistics;
+
+typedef struct _ImageStatistics
+ {
+ ImageChannelStatistics red;
+ ImageChannelStatistics green;
+ ImageChannelStatistics blue;
+ ImageChannelStatistics opacity;
+ } ImageStatistics;
+
+extern MagickExport MagickPassFail
+ GetImageStatistics(const Image *image,ImageStatistics *statistics,
+ ExceptionInfo *exception);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_STATISTICS_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/studio.h b/magick/studio.h
new file mode 100644
index 0000000..bf31c2f
--- /dev/null
+++ b/magick/studio.h
@@ -0,0 +1,509 @@
+/*
+ Copyright (C) 2003 - 2016 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Application Programming Interface declarations.
+*/
+#ifndef _MAGICK_STUDIO_H
+#define _MAGICK_STUDIO_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ This define is not used by GraphicsMagick and it causes some headers
+ from other installed packages (e.g. MinGW libpthread) to misbehave.
+*/
+#undef HAVE_CONFIG_H
+
+/*
+ Note that the WIN32 and WIN64 definitions are provided by the build
+ configuration rather than the compiler. Definitions available from the
+ Windows compiler are _WIN32 and _WIN64. Note that _WIN32 is defined if
+ _WIN64 is defined.
+*/
+#if defined(WIN32) || defined(WIN64)
+# define MSWINDOWS
+#endif /* defined(WIN32) || defined(WIN64) */
+
+#if !defined(MSWINDOWS)
+# define POSIX
+#endif /* !defined(MSWINDOWS) */
+
+/*
+ Private functions and types which are not part of the published API
+ should only be exposed when MAGICK_IMPLEMENTATION is defined.
+*/
+#define MAGICK_IMPLEMENTATION 1
+
+#include "magick/magick_config.h"
+#if defined(__cplusplus) || defined(c_plusplus)
+# undef inline
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+/*
+ Allow configuration of cache line size. If smaller than actual cache line
+ size, then performance may suffer due to false cache line sharing between
+ threads. Most CPUs have cache lines of 32 or 64 bytes. IBM Power CPUs have
+ cache lines of 128 bytes.
+*/
+/* C pre-processor does not support comparing strings. */
+#if defined(__powerpc__)
+# define MAGICK_CACHE_LINE_SIZE 128
+#else
+# define MAGICK_CACHE_LINE_SIZE 64
+#endif
+
+
+/*
+ Support library symbol prefixing
+*/
+#if defined(PREFIX_MAGICK_SYMBOLS)
+# include "magick/symbols.h"
+#endif /* defined(PREFIX_MAGICK_SYMBOLS) */
+
+#if !defined(const)
+ /*
+ For some stupid reason the zlib headers define 'const' to nothing
+ under AIX unless STDC is defined.
+ */
+# define STDC
+#endif /* !defined(const) */
+
+/*
+ For the Windows Visual C++ DLL build, use a Windows resource based
+ message lookup table (i.e. use FormatMessage()).
+ */
+#if 0
+ /*
+ Currently disabled since feature only seems to work from
+ a DLL
+ */
+# if ((defined(MSWINDOWS) && defined(_DLL)) && !defined(__MINGW32__))
+# define MAGICK_WINDOWS_MESSAGE_TABLES 1
+# endif
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#if defined(MSWINDOWS) && defined(_DEBUG)
+# define _CRTDBG_MAP_ALLOC
+#endif
+#include <stdlib.h>
+#if !defined(MSWINDOWS)
+# include <unistd.h>
+#else
+# include <direct.h>
+# include <io.h>
+# if !defined(HAVE_STRERROR)
+# define HAVE_STRERROR
+# endif
+#endif
+
+/*
+ Use fseeko() and ftello() if they are available since they use
+ 'off_t' rather than 'long'. It is wrong to use fseeko() and
+ ftello() only on systems with special LFS support since some systems
+ (e.g. FreeBSD) support a 64-bit off_t by default.
+*/
+#if defined(HAVE_FSEEKO)
+# define fseek fseeko
+# define ftell ftello
+#endif
+
+#if !defined(ExtendedSignedIntegralType)
+# define ExtendedSignedIntegralType magick_int64_t
+#endif
+#if !defined(ExtendedUnsignedIntegralType)
+# define ExtendedUnsignedIntegralType magick_uint64_t
+#endif
+
+#include <string.h>
+#include <ctype.h>
+#include <locale.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <time.h>
+#include <limits.h>
+#include <signal.h>
+#include <assert.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined(HAVE_FTIME)
+# include <sys/timeb.h>
+#endif
+
+#if defined(HAVE_STDINT_H)
+# include <stdint.h>
+#endif
+
+#if defined(POSIX)
+# if defined(HAVE_SYS_NDIR_H) || defined(HAVE_SYS_DIR_H) || defined(HAVE_NDIR_H)
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if defined(HAVE_SYS_NDIR_H)
+# include <sys/ndir.h>
+# endif
+# if defined(HAVE_SYS_DIR_H)
+# include <sys/dir.h>
+# endif
+# if defined(HAVE_NDIR_H)
+# include <ndir.h>
+# endif
+# else
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+# endif
+# include <sys/wait.h>
+# if defined(HAVE_SYS_RESOURCE_H)
+# include <sys/resource.h>
+# endif /* defined(HAVE_SYS_RESOURCE_H) */
+# if defined(HAVE_SYS_MMAN_H)
+# include <sys/mman.h>
+# endif /* defined(HAVE_SYS_MMAN_H) */
+# include <pwd.h>
+#endif
+
+#if !defined(S_ISDIR)
+# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+
+#if !defined(S_ISREG)
+# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+#endif
+
+/*
+ Avoid shadowing system library globals and functions.
+*/
+#undef gamma
+#define gamma gamma_magick
+#undef swab
+#define swab swab_magick
+#undef y1
+#define y1 y1_magick
+
+/*
+ Include common bits shared with api.h
+*/
+#include "magick/common.h"
+/*
+ Enable use of numeric message IDs and a translation table in order
+ to support multiple locales.
+ */
+#define MAGICK_IDBASED_MESSAGES 1
+#if defined(MAGICK_IDBASED_MESSAGES)
+# include "magick/locale_c.h"
+#endif
+#include "magick/magick_types.h"
+#include "magick/image.h"
+#include "magick/list.h"
+#include "magick/memory.h"
+
+#if !defined(MSWINDOWS)
+# include <sys/time.h>
+# if defined(HAVE_SYS_TIMES_H)
+# include <sys/times.h>
+# endif
+#endif
+
+#if defined(POSIX)
+# include "magick/unix_port.h"
+#endif /* defined(POSIX) */
+
+#if defined(MSWINDOWS)
+# include "magick/nt_base.h"
+#endif /* defined(MSWINDOWS) */
+
+#if defined(HAVE_MMAP_FILEIO) && !defined(MSWINDOWS)
+# include <sys/mman.h>
+#endif
+
+#if defined(HAVE_PTHREAD)
+# include <pthread.h>
+#endif
+
+#if defined(HAVE_POLL)
+# include <sys/poll.h>
+#endif
+
+/*
+ Work around OpenMP implementation bugs noticed in the Open64 5.0 compiler
+ These workarounds will be removed once the bugs have been fixed in a release.
+ Open64 5.0 provides these definitions:
+ __OPENCC__ 5 -- OpenCC major version
+ __OPENCC_MINOR__ 0 -- OpenCC minor version
+ __OPEN64__ "5.0" -- OpenCC stringified version
+*/
+#if defined(__OPENCC__)
+# undef USE_STATIC_SCHEDULING_ONLY
+# define USE_STATIC_SCHEDULING_ONLY 1
+#endif
+
+/*
+ OpenMP support requires version 2.0 (March 2002) or later.
+*/
+#if defined(_OPENMP) && ((_OPENMP >= 200203) || defined(__OPENCC__))
+# include <omp.h>
+# define HAVE_OPENMP 1
+#endif
+
+#undef index
+#undef pipe
+
+/*
+ If TRIO library is used, remap snprintf and vsnprintf to TRIO equivalents.
+*/
+#if defined(HasTRIO)
+# include <trio.h>
+# define snprintf trio_snprintf
+# define HAVE_SNPRINTF 1
+# define vsnprintf trio_vsnprintf
+# define HAVE_VSNPRINTF 1
+#endif
+
+/*
+ Provide prototypes for several functions which are detected to be
+ available, but which do not provide a prototype due to interface
+ standards conformance (or a bug).
+*/
+
+#if defined(HAVE_PREAD) && defined(HAVE_DECL_PREAD) && !HAVE_DECL_PREAD
+ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
+#endif
+
+#if defined(HAVE_PWRITE) && defined(HAVE_DECL_PWRITE) && !HAVE_DECL_PWRITE
+ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+#endif
+
+#if defined(HAVE_STRLCPY) && defined(HAVE_DECL_STRLCPY) && !HAVE_DECL_STRLCPY
+extern size_t strlcpy(char *dst, const char *src, size_t dstsize);
+#endif
+
+#if defined(HAVE_VSNPRINTF) && defined(HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF
+extern int vsnprintf(char *s, size_t n, const char *format, va_list ap);
+#endif
+
+/*
+ Some 64-bit int support.
+*/
+#if defined(HAVE_STRTOLL) && (SIZEOF_SIGNED_LONG < 8)
+# define MagickStrToL64(str,endptr,base) (strtoll(str,endptr,base))
+#else
+# define MagickStrToL64(str,endptr,base) ((magick_int64_t) strtol(str,endptr,base))
+#endif
+#if defined(HAVE_ATOLL) && (SIZEOF_SIGNED_LONG < 8)
+# define MagickAtoL64(str) (atoll(str))
+#else
+# define MagickAtoL64(str) ((magick_int64_t) atol(str))
+#endif
+
+/*
+ Review these platform specific definitions.
+*/
+#if defined(POSIX)
+# define DirectorySeparator "/"
+# define DirectoryListSeparator ':'
+# define EditorOptions " -title \"Edit Image Comment\" -e vi"
+# define Exit exit
+# define IsBasenameSeparator(c) ((c) == '/')
+# define PreferencesDefaults "~/."
+# define ProcessPendingEvents(text)
+# define ReadCommandlLine(argc,argv)
+# define SetNotifyHandlers
+# define MagickSleep(seconds) sleep(seconds)
+#endif
+
+#if defined(MSWINDOWS)
+# define DirectorySeparator "\\"
+# define DirectoryListSeparator ';'
+# define EditorOptions ""
+# define IsBasenameSeparator(c) (((c) == '/') || ((c) == '\\'))
+# define ProcessPendingEvents(text)
+# if !defined(PreferencesDefaults)
+# define PreferencesDefaults "~\\."
+# endif /* PreferencesDefaults */
+# define ReadCommandlLine(argc,argv)
+# define SetNotifyHandlers \
+ SetErrorHandler(NTErrorHandler); \
+ SetWarningHandler(NTWarningHandler)
+# define MagickSleep(seconds) Sleep(seconds*1000)
+# if !defined(HAVE_TIFFCONF_H)
+# define HAVE_TIFFCONF_H
+# endif
+#endif /* defined(MSWINDOWS) */
+
+
+/*
+ Define declarations.
+*/
+#define AbsoluteValue(x) ((x) < 0 ? -(x) : (x))
+#define False 0
+#define DegreesToRadians(x) (MagickPI*(x)/180.0)
+#define MagickIncarnate(x) InitializeMagick(x)
+#define MagickEpsilon 1.0e-12
+#define MagickPI 3.14159265358979323846264338327950288419716939937510
+#define MagickSQ2PI 2.50662827463100024161235523934010416269302368164062
+#if !defined(INFINITY) /* C'99 provides INFINITY but C'89 does not */
+# define INFINITY (log(0))
+#endif
+#define Max(x,y) (((x) > (y)) ? (x) : (y))
+#define Min(x,y) (((x) < (y)) ? (x) : (y))
+#define NumberOfObjectsInArray(octets,size) ((octets+size-1)/size)
+#define QuantumTick(i,span) \
+ ((((i) % ((Max(101,span)-1)/100)) == 0) || \
+ ((magick_int64_t) (i) == ((magick_int64_t) (span)-1)))
+#define RadiansToDegrees(x) (180.0*(x)/MagickPI)
+#define RoundUpToAlignment(offset,alignment) \
+ (((offset)+((alignment)-1)) & ~((alignment)-1))
+#define AssertAlignment(offset,alignment) \
+ (assert((((size_t) offset) % (size_t) alignment) == (size_t) 0))
+#define NormalizeDepthToOctet(depth) (depth < 8 ? 8 : \
+ (depth < 16 ? 16 : (depth < 32 ? 32 : depth)))
+#define ScaleColor5to8(x) (((x) << 3) | ((x) >> 2))
+#define ScaleColor6to8(x) (((x) << 2) | ((x) >> 4))
+#define Swap(x,y) ((x)^=(y), (y)^=(x), (x)^=(y))
+#define True 1
+
+#define DefineNameToString(value) #value
+#define DefineValueToString(define) DefineNameToString(define)
+
+/*
+ atof(), atoi(), and atol() are legacy functions which might not be
+ thread safe, might not enforce reasonable limits, and should not be
+ used for new code. So we implement them via strtod and strtol.
+*/
+#define MagickAtoF(str) (strtod(str, (char **)NULL))
+#define MagickAtoI(str) ((int) strtol(str, (char **)NULL, 10))
+#define MagickAtoL(str) (strtol(str, (char **)NULL, 10))
+
+/*
+ 3D effects.
+*/
+#define AccentuateModulate ScaleCharToQuantum(80)
+#define HighlightModulate ScaleCharToQuantum(125)
+#define ShadowModulate ScaleCharToQuantum(135)
+#define DepthModulate ScaleCharToQuantum(185)
+#define TroughModulate ScaleCharToQuantum(110)
+
+/*
+ Define system symbols if not already defined.
+*/
+#if !defined(STDIN_FILENO)
+# define STDIN_FILENO 0x00
+#endif
+
+#if !defined(O_BINARY)
+# define O_BINARY 0x00
+#endif
+
+#if !defined(MAP_FAILED)
+# define MAP_FAILED ((void *) -1)
+#endif
+
+#if !defined(PATH_MAX)
+# define PATH_MAX 4096
+#endif
+
+#if defined(HasLTDL) || ( defined(MSWINDOWS) && defined(_DLL) )
+# define SupportMagickModules
+#endif
+
+#if defined(_MAGICKMOD_)
+# undef BuildMagickModules
+# define BuildMagickModules
+#endif
+
+/*
+ C99 isblank() is not portable enough yet.
+*/
+#define MagickIsBlank(c) (c== ' ' || c == '\t')
+
+#if !defined(MagickMmap)
+# define MagickMmap(address,length,protection,access,file,offset) \
+ mmap(address,length,protection,access,file,offset)
+#endif
+#if !defined(MagickMsync)
+# define MagickMsync(addr,len,flags) msync(addr,len,flags)
+#endif
+#if !defined(MagickMunmap)
+# define MagickMunmap(addr,len) munmap(addr,len)
+#endif
+#if !defined(MagickFtruncate)
+# define MagickFtruncate(filedes,length) ftruncate(filedes,length)
+#endif
+
+#if !defined(HAVE_POPEN) && defined(HAVE__POPEN)
+# define HAVE_POPEN 1
+# define popen _popen
+#endif /* !defined(HAVE_POPEN) && defined(HAVE__POPEN) */
+
+#if !defined(HAVE_PCLOSE) && defined(HAVE__PCLOSE)
+# define HAVE_PCLOSE 1
+# define pclose _pclose
+#endif /* !defined(HAVE_PCLOSE) && defined(HAVE__PCLOSE) */
+
+#if defined(HAVE__EXIT)
+# define SignalHandlerExit _exit
+#else
+# define SignalHandlerExit Exit
+#endif /* defined(HAVE__EXIT) */
+
+/*
+ OpenMP function null replacements if not using OpenMP.
+*/
+#if !defined(HAVE_OPENMP)
+# undef omp_get_max_threads
+# define omp_get_max_threads() 1
+# undef omp_get_num_threads
+# define omp_get_num_threads() 1
+# undef omp_get_thread_num
+# define omp_get_thread_num() 0
+# undef omp_set_num_threads
+# define omp_set_num_threads(nthreads)
+#endif /* !defined(HAVE_OPENMP) */
+
+
+/*
+ Image const declarations.
+*/
+extern MagickExport const char
+ *BackgroundColor,
+ *BorderColor,
+ *DefaultTileFrame,
+ *DefaultTileGeometry,
+ *DefaultTileLabel,
+ *ForegroundColor,
+ *HighlightColor,
+ *MatteColor,
+ *PSDensityGeometry,
+ *PSPageGeometry;
+
+#define LoadImageText "[%s] Loading image: %lux%lu... "
+#define SaveImageText "[%s] Saving image: %lux%lu... "
+#define LoadImagesText "[%s] Loading images... "
+#define SaveImagesText "[%s] Saving images... "
+
+extern MagickExport const unsigned long
+ DefaultCompressionQuality;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* ifndef _MAGICK_STUDIO_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/symbols.h b/magick/symbols.h
new file mode 100644
index 0000000..d6f76c2
--- /dev/null
+++ b/magick/symbols.h
@@ -0,0 +1,1121 @@
+/*
+ Copyright (C) 2003 - 2016 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Library symbol name-scoping support.
+
+ Obtained via:
+
+ nm -p magick/.libs/libGraphicsMagick.a | grep ' T ' | egrep -vi '(Gm)|(lt_)' | \
+ egrep -v '(MagickError)|(MagickFatalError)|(MagickWarning)|(ThrowException)' | \
+ awk '{ printf("#define %s Gm%s\n", $3, $3); }' | sort
+
+*/
+
+#if !defined(_MAGICK_SYMBOLS_H)
+#define _MAGICK_SYMBOLS_H
+
+#if defined(PREFIX_MAGICK_SYMBOLS)
+
+#define AccessCacheViewPixels GmAccessCacheViewPixels
+#define AccessDefaultCacheView GmAccessDefaultCacheView
+#define AccessDefinition GmAccessDefinition
+#define AccessImmutableIndexes GmAccessImmutableIndexes
+#define AccessMutableIndexes GmAccessMutableIndexes
+#define AccessMutablePixels GmAccessMutablePixels
+#define AccessThreadViewData GmAccessThreadViewData
+#define AccessThreadViewDataById GmAccessThreadViewDataById
+#define AcquireCacheView GmAcquireCacheView
+#define AcquireCacheViewIndexes GmAcquireCacheViewIndexes
+#define AcquireCacheViewPixels GmAcquireCacheViewPixels
+#define AcquireImagePixels GmAcquireImagePixels
+#define AcquireMagickRandomKernel GmAcquireMagickRandomKernel
+#define AcquireMagickResource GmAcquireMagickResource
+#define AcquireMemory GmAcquireMemory
+#define AcquireOneCacheViewPixel GmAcquireOneCacheViewPixel
+#define AcquireOnePixel GmAcquireOnePixel
+#define AcquireOnePixelByReference GmAcquireOnePixelByReference
+#define AcquireSemaphoreInfo GmAcquireSemaphoreInfo
+#define AcquireString GmAcquireString
+#define AcquireTemporaryFileDescriptor GmAcquireTemporaryFileDescriptor
+#define AcquireTemporaryFileName GmAcquireTemporaryFileName
+#define AcquireTemporaryFileStream GmAcquireTemporaryFileStream
+#define AdaptiveThresholdImage GmAdaptiveThresholdImage
+#define AddDefinition GmAddDefinition
+#define AddDefinitions GmAddDefinitions
+#define AddNoiseImage GmAddNoiseImage
+#define AddNoiseImageChannel GmAddNoiseImageChannel
+#define AffineTransformImage GmAffineTransformImage
+#define AllocateImage GmAllocateImage
+#define AllocateImageColormap GmAllocateImageColormap
+#define AllocateImageProfileIterator GmAllocateImageProfileIterator
+#define AllocateNextImage GmAllocateNextImage
+#define AllocateSemaphoreInfo GmAllocateSemaphoreInfo
+#define AllocateString GmAllocateString
+#define AllocateThreadViewDataArray GmAllocateThreadViewDataArray
+#define AllocateThreadViewDataSet GmAllocateThreadViewDataSet
+#define AllocateThreadViewSet GmAllocateThreadViewSet
+#define AnalyzeImage GmAnalyzeImage
+#define AnimateImageCommand GmAnimateImageCommand
+#define AnimateImages GmAnimateImages
+#define AnnotateImage GmAnnotateImage
+#define AppendImageFormat GmAppendImageFormat
+#define AppendImageProfile GmAppendImageProfile
+#define AppendImageToList GmAppendImageToList
+#define AppendImages GmAppendImages
+#define Ascii85Encode GmAscii85Encode
+#define Ascii85Flush GmAscii85Flush
+#define Ascii85Initialize GmAscii85Initialize
+#define Ascii85WriteByteHook GmAscii85WriteByteHook
+#define AssignThreadViewData GmAssignThreadViewData
+#define AttachBlob GmAttachBlob
+#define AutoOrientImage GmAutoOrientImage
+#define AverageImages GmAverageImages
+#define BackgroundColor GmBackgroundColor
+#define Base64Decode GmBase64Decode
+#define Base64Encode GmBase64Encode
+#define BenchmarkImageCommand GmBenchmarkImageCommand
+#define BlackThresholdImage GmBlackThresholdImage
+#define BlobIsSeekable GmBlobIsSeekable
+#define BlobModeToString GmBlobModeToString
+#define BlobReserveSize GmBlobReserveSize
+#define BlobToFile GmBlobToFile
+#define BlobToImage GmBlobToImage
+#define BlobWriteByteHook GmBlobWriteByteHook
+#define BlurImage GmBlurImage
+#define BlurImageChannel GmBlurImageChannel
+#define BorderColor GmBorderColor
+#define BorderImage GmBorderImage
+#define CatchException GmCatchException
+#define CatchImageException GmCatchImageException
+#define CdlImage GmCdlImage
+#define ChannelImage GmChannelImage
+#define ChannelThresholdImage GmChannelThresholdImage
+#define ChannelTypeToString GmChannelTypeToString
+#define CharcoalImage GmCharcoalImage
+#define CheckImagePixelLimits GmCheckImagePixelLimits
+#define ChopImage GmChopImage
+#define ClassTypeToString GmClassTypeToString
+#define ClipImage GmClipImage
+#define ClipPathImage GmClipPathImage
+#define CloneBlobInfo GmCloneBlobInfo
+#define CloneDrawInfo GmCloneDrawInfo
+#define CloneImage GmCloneImage
+#define CloneImageAttributes GmCloneImageAttributes
+#define CloneImageInfo GmCloneImageInfo
+#define CloneImageList GmCloneImageList
+#define CloneMemory GmCloneMemory
+#define CloneMontageInfo GmCloneMontageInfo
+#define CloneQuantizeInfo GmCloneQuantizeInfo
+#define CloneString GmCloneString
+#define CloseBlob GmCloseBlob
+#define CloseCacheView GmCloseCacheView
+#define CoalesceImages GmCoalesceImages
+#define ColorFloodfillImage GmColorFloodfillImage
+#define ColorMatrixImage GmColorMatrixImage
+#define ColorizeImage GmColorizeImage
+#define ColorspaceTypeToString GmColorspaceTypeToString
+#define CompareImageCommand GmCompareImageCommand
+#define CompositeImage GmCompositeImage
+#define CompositeImageCommand GmCompositeImageCommand
+#define CompositeImageRegion GmCompositeImageRegion
+#define CompositeOperatorToString GmCompositeOperatorToString
+#define CompressImageColormap GmCompressImageColormap
+#define CompressionTypeToString GmCompressionTypeToString
+#define ConcatenateString GmConcatenateString
+#define ConfirmAccessModeToString GmConfirmAccessModeToString
+#define ConjureImageCommand GmConjureImageCommand
+#define ConstituteImage GmConstituteImage
+#define ConstituteTextureImage GmConstituteTextureImage
+#define ContinueTimer GmContinueTimer
+#define Contrast GmContrast
+#define ContrastImage GmContrastImage
+#define ConvertImageCommand GmConvertImageCommand
+#define ConvolveImage GmConvolveImage
+#define CopyException GmCopyException
+#define CropImage GmCropImage
+#define CycleColormapImage GmCycleColormapImage
+#define DCM_SetRescaling GmDCM_SetRescaling
+#define DeallocateImageProfileIterator GmDeallocateImageProfileIterator
+#define DeconstructImages GmDeconstructImages
+#define DefaultTileFrame GmDefaultTileFrame
+#define DefaultTileGeometry GmDefaultTileGeometry
+#define DefaultTileLabel GmDefaultTileLabel
+#define DefineClientName GmDefineClientName
+#define DefineClientPathAndName GmDefineClientPathAndName
+#define DeleteImageFromList GmDeleteImageFromList
+#define DeleteImageProfile GmDeleteImageProfile
+#define DeleteMagickRegistry GmDeleteMagickRegistry
+#define DescribeImage GmDescribeImage
+#define DespeckleImage GmDespeckleImage
+#define DestroyBlob GmDestroyBlob
+#define DestroyBlobInfo GmDestroyBlobInfo
+#define DestroyCacheInfo GmDestroyCacheInfo
+#define DestroyColorInfo GmDestroyColorInfo
+#define DestroyConstitute GmDestroyConstitute
+#define DestroyDelegateInfo GmDestroyDelegateInfo
+#define DestroyDrawInfo GmDestroyDrawInfo
+#define DestroyExceptionInfo GmDestroyExceptionInfo
+#define DestroyImage GmDestroyImage
+#define DestroyImageAttributes GmDestroyImageAttributes
+#define DestroyImageInfo GmDestroyImageInfo
+#define DestroyImageList GmDestroyImageList
+#define DestroyImagePixels GmDestroyImagePixels
+#define DestroyLogInfo GmDestroyLogInfo
+#define DestroyMagicInfo GmDestroyMagicInfo
+#define DestroyMagick GmDestroyMagick
+#define DestroyMagickRandomGenerator GmDestroyMagickRandomGenerator
+#define DestroyMagickRegistry GmDestroyMagickRegistry
+#define DestroyMagickResources GmDestroyMagickResources
+#define DestroyMontageInfo GmDestroyMontageInfo
+#define DestroyQuantizeInfo GmDestroyQuantizeInfo
+#define DestroySemaphore GmDestroySemaphore
+#define DestroySemaphoreInfo GmDestroySemaphoreInfo
+#define DestroyTemporaryFiles GmDestroyTemporaryFiles
+#define DestroyThreadViewDataSet GmDestroyThreadViewDataSet
+#define DestroyThreadViewSet GmDestroyThreadViewSet
+#define DestroyTypeInfo GmDestroyTypeInfo
+#define DetachBlob GmDetachBlob
+#define DifferenceImage GmDifferenceImage
+#define DispatchImage GmDispatchImage
+#define DisplayImageCommand GmDisplayImageCommand
+#define DisplayImages GmDisplayImages
+#define DrawAffine GmDrawAffine
+#define DrawAffineImage GmDrawAffineImage
+#define DrawAllocateContext GmDrawAllocateContext
+#define DrawAnnotation GmDrawAnnotation
+#define DrawArc GmDrawArc
+#define DrawBezier GmDrawBezier
+#define DrawCircle GmDrawCircle
+#define DrawClipPath GmDrawClipPath
+#define DrawColor GmDrawColor
+#define DrawComment GmDrawComment
+#define DrawComposite GmDrawComposite
+#define DrawDestroyContext GmDrawDestroyContext
+#define DrawEllipse GmDrawEllipse
+#define DrawGetClipPath GmDrawGetClipPath
+#define DrawGetClipRule GmDrawGetClipRule
+#define DrawGetClipUnits GmDrawGetClipUnits
+#define DrawGetFillColor GmDrawGetFillColor
+#define DrawGetFillOpacity GmDrawGetFillOpacity
+#define DrawGetFillRule GmDrawGetFillRule
+#define DrawGetFont GmDrawGetFont
+#define DrawGetFontFamily GmDrawGetFontFamily
+#define DrawGetFontSize GmDrawGetFontSize
+#define DrawGetFontStretch GmDrawGetFontStretch
+#define DrawGetFontStyle GmDrawGetFontStyle
+#define DrawGetFontWeight GmDrawGetFontWeight
+#define DrawGetGravity GmDrawGetGravity
+#define DrawGetStrokeAntialias GmDrawGetStrokeAntialias
+#define DrawGetStrokeColor GmDrawGetStrokeColor
+#define DrawGetStrokeDashArray GmDrawGetStrokeDashArray
+#define DrawGetStrokeDashOffset GmDrawGetStrokeDashOffset
+#define DrawGetStrokeLineCap GmDrawGetStrokeLineCap
+#define DrawGetStrokeLineJoin GmDrawGetStrokeLineJoin
+#define DrawGetStrokeMiterLimit GmDrawGetStrokeMiterLimit
+#define DrawGetStrokeOpacity GmDrawGetStrokeOpacity
+#define DrawGetStrokeWidth GmDrawGetStrokeWidth
+#define DrawGetTextAntialias GmDrawGetTextAntialias
+#define DrawGetTextDecoration GmDrawGetTextDecoration
+#define DrawGetTextEncoding GmDrawGetTextEncoding
+#define DrawGetTextUnderColor GmDrawGetTextUnderColor
+#define DrawImage GmDrawImage
+#define DrawLine GmDrawLine
+#define DrawMatte GmDrawMatte
+#define DrawPathClose GmDrawPathClose
+#define DrawPathCurveToAbsolute GmDrawPathCurveToAbsolute
+#define DrawPathCurveToQuadraticBezierAbsolute GmDrawPathCurveToQuadraticBezierAbsolute
+#define DrawPathCurveToQuadraticBezierRelative GmDrawPathCurveToQuadraticBezierRelative
+#define DrawPathCurveToQuadraticBezierSmoothAbsolute GmDrawPathCurveToQuadraticBezierSmoothAbsolute
+#define DrawPathCurveToQuadraticBezierSmoothRelative GmDrawPathCurveToQuadraticBezierSmoothRelative
+#define DrawPathCurveToRelative GmDrawPathCurveToRelative
+#define DrawPathCurveToSmoothAbsolute GmDrawPathCurveToSmoothAbsolute
+#define DrawPathCurveToSmoothRelative GmDrawPathCurveToSmoothRelative
+#define DrawPathEllipticArcAbsolute GmDrawPathEllipticArcAbsolute
+#define DrawPathEllipticArcRelative GmDrawPathEllipticArcRelative
+#define DrawPathFinish GmDrawPathFinish
+#define DrawPathLineToAbsolute GmDrawPathLineToAbsolute
+#define DrawPathLineToHorizontalAbsolute GmDrawPathLineToHorizontalAbsolute
+#define DrawPathLineToHorizontalRelative GmDrawPathLineToHorizontalRelative
+#define DrawPathLineToRelative GmDrawPathLineToRelative
+#define DrawPathLineToVerticalAbsolute GmDrawPathLineToVerticalAbsolute
+#define DrawPathLineToVerticalRelative GmDrawPathLineToVerticalRelative
+#define DrawPathMoveToAbsolute GmDrawPathMoveToAbsolute
+#define DrawPathMoveToRelative GmDrawPathMoveToRelative
+#define DrawPathStart GmDrawPathStart
+#define DrawPatternPath GmDrawPatternPath
+#define DrawPeekGraphicContext GmDrawPeekGraphicContext
+#define DrawPoint GmDrawPoint
+#define DrawPolygon GmDrawPolygon
+#define DrawPolyline GmDrawPolyline
+#define DrawPopClipPath GmDrawPopClipPath
+#define DrawPopDefs GmDrawPopDefs
+#define DrawPopGraphicContext GmDrawPopGraphicContext
+#define DrawPopPattern GmDrawPopPattern
+#define DrawPushClipPath GmDrawPushClipPath
+#define DrawPushDefs GmDrawPushDefs
+#define DrawPushGraphicContext GmDrawPushGraphicContext
+#define DrawPushPattern GmDrawPushPattern
+#define DrawRectangle GmDrawRectangle
+#define DrawRender GmDrawRender
+#define DrawRotate GmDrawRotate
+#define DrawRoundRectangle GmDrawRoundRectangle
+#define DrawScale GmDrawScale
+#define DrawSetClipPath GmDrawSetClipPath
+#define DrawSetClipRule GmDrawSetClipRule
+#define DrawSetClipUnits GmDrawSetClipUnits
+#define DrawSetFillColor GmDrawSetFillColor
+#define DrawSetFillColorString GmDrawSetFillColorString
+#define DrawSetFillOpacity GmDrawSetFillOpacity
+#define DrawSetFillPatternURL GmDrawSetFillPatternURL
+#define DrawSetFillRule GmDrawSetFillRule
+#define DrawSetFont GmDrawSetFont
+#define DrawSetFontFamily GmDrawSetFontFamily
+#define DrawSetFontSize GmDrawSetFontSize
+#define DrawSetFontStretch GmDrawSetFontStretch
+#define DrawSetFontStyle GmDrawSetFontStyle
+#define DrawSetFontWeight GmDrawSetFontWeight
+#define DrawSetGravity GmDrawSetGravity
+#define DrawSetStrokeAntialias GmDrawSetStrokeAntialias
+#define DrawSetStrokeColor GmDrawSetStrokeColor
+#define DrawSetStrokeColorString GmDrawSetStrokeColorString
+#define DrawSetStrokeDashArray GmDrawSetStrokeDashArray
+#define DrawSetStrokeDashOffset GmDrawSetStrokeDashOffset
+#define DrawSetStrokeLineCap GmDrawSetStrokeLineCap
+#define DrawSetStrokeLineJoin GmDrawSetStrokeLineJoin
+#define DrawSetStrokeMiterLimit GmDrawSetStrokeMiterLimit
+#define DrawSetStrokeOpacity GmDrawSetStrokeOpacity
+#define DrawSetStrokePatternURL GmDrawSetStrokePatternURL
+#define DrawSetStrokeWidth GmDrawSetStrokeWidth
+#define DrawSetTextAntialias GmDrawSetTextAntialias
+#define DrawSetTextDecoration GmDrawSetTextDecoration
+#define DrawSetTextEncoding GmDrawSetTextEncoding
+#define DrawSetTextUnderColor GmDrawSetTextUnderColor
+#define DrawSetTextUnderColorString GmDrawSetTextUnderColorString
+#define DrawSetViewbox GmDrawSetViewbox
+#define DrawSkewX GmDrawSkewX
+#define DrawSkewY GmDrawSkewY
+#define DrawTranslate GmDrawTranslate
+#define EOFBlob GmEOFBlob
+#define EdgeImage GmEdgeImage
+#define EmbossImage GmEmbossImage
+#define EndianTypeToString GmEndianTypeToString
+#define EnhanceImage GmEnhanceImage
+#define EqualizeImage GmEqualizeImage
+#define EscapeString GmEscapeString
+#define ExecuteModuleProcess GmExecuteModuleProcess
+#define ExpandAffine GmExpandAffine
+#define ExpandFilename GmExpandFilename
+#define ExpandFilenames GmExpandFilenames
+#define ExportImageChannel GmExportImageChannel
+#define ExportImagePixelArea GmExportImagePixelArea
+#define ExportPixelAreaOptionsInit GmExportPixelAreaOptionsInit
+#define ExportViewPixelArea GmExportViewPixelArea
+#define ExtentImage GmExtentImage
+#define FileToBlob GmFileToBlob
+#define FinalizeSignature GmFinalizeSignature
+#define FlattenImages GmFlattenImages
+#define FlipImage GmFlipImage
+#define FlopImage GmFlopImage
+#define ForegroundColor GmForegroundColor
+#define FormatSize GmFormatSize
+#define FormatString GmFormatString
+#define FormatStringList GmFormatStringList
+#define FrameImage GmFrameImage
+#define FuzzyColorMatch GmFuzzyColorMatch
+#define GammaImage GmGammaImage
+#define GaussianBlurImage GmGaussianBlurImage
+#define GaussianBlurImageChannel GmGaussianBlurImageChannel
+#define GenerateDifferentialNoise GmGenerateDifferentialNoise
+#define GenerateNoise GmGenerateNoise
+#define GetBlobFileHandle GmGetBlobFileHandle
+#define GetBlobInfo GmGetBlobInfo
+#define GetBlobIsOpen GmGetBlobIsOpen
+#define GetBlobSize GmGetBlobSize
+#define GetBlobStatus GmGetBlobStatus
+#define GetBlobStreamData GmGetBlobStreamData
+#define GetBlobTemporary GmGetBlobTemporary
+#define GetCacheInfo GmGetCacheInfo
+#define GetCacheView GmGetCacheView
+#define GetCacheViewArea GmGetCacheViewArea
+#define GetCacheViewImage GmGetCacheViewImage
+#define GetCacheViewIndexes GmGetCacheViewIndexes
+#define GetCacheViewPixels GmGetCacheViewPixels
+#define GetCacheViewRegion GmGetCacheViewRegion
+#define GetClientFilename GmGetClientFilename
+#define GetClientName GmGetClientName
+#define GetClientPath GmGetClientPath
+#define GetColorHistogram GmGetColorHistogram
+#define GetColorInfo GmGetColorInfo
+#define GetColorInfoArray GmGetColorInfoArray
+#define GetColorList GmGetColorList
+#define GetColorTuple GmGetColorTuple
+#define GetConfigureBlob GmGetConfigureBlob
+#define GetDelegateCommand GmGetDelegateCommand
+#define GetDelegateInfo GmGetDelegateInfo
+#define GetDrawInfo GmGetDrawInfo
+#define GetElapsedTime GmGetElapsedTime
+#define GetExceptionInfo GmGetExceptionInfo
+#define GetExecutionPath GmGetExecutionPath
+#define GetExecutionPathUsingName GmGetExecutionPathUsingName
+#define GetFirstImageInList GmGetFirstImageInList
+#define GetGeometry GmGetGeometry
+#define GetImageAttribute GmGetImageAttribute
+#define GetImageBoundingBox GmGetImageBoundingBox
+#define GetImageChannelDepth GmGetImageChannelDepth
+#define GetImageChannelDifference GmGetImageChannelDifference
+#define GetImageChannelDistortion GmGetImageChannelDistortion
+#define GetImageCharacteristics GmGetImageCharacteristics
+#define GetImageClipMask GmGetImageClipMask
+#define GetImageClippingPathAttribute GmGetImageClippingPathAttribute
+#define GetImageDepth GmGetImageDepth
+#define GetImageDistortion GmGetImageDistortion
+#define GetImageException GmGetImageException
+#define GetImageFromList GmGetImageFromList
+#define GetImageFromMagickRegistry GmGetImageFromMagickRegistry
+#define GetImageGeometry GmGetImageGeometry
+#define GetImageIndexInList GmGetImageIndexInList
+#define GetImageInfo GmGetImageInfo
+#define GetImageInfoAttribute GmGetImageInfoAttribute
+#define GetImageListLength GmGetImageListLength
+#define GetImageMagick GmGetImageMagick
+#define GetImagePixels GmGetImagePixels
+#define GetImagePixelsEx GmGetImagePixelsEx
+#define GetImageProfile GmGetImageProfile
+#define GetImageQuantizeError GmGetImageQuantizeError
+#define GetImageStatistics GmGetImageStatistics
+#define GetImageType GmGetImageType
+#define GetImageVirtualPixelMethod GmGetImageVirtualPixelMethod
+#define GetIndexes GmGetIndexes
+#define GetLastImageInList GmGetLastImageInList
+#define GetLocaleExceptionMessage GmGetLocaleExceptionMessage
+#define GetLocaleMessage GmGetLocaleMessage
+#define GetLocaleMessageFromID GmGetLocaleMessageFromID
+#define GetMagickCopyright GmGetMagickCopyright
+#define GetMagickDimension GmGetMagickDimension
+#define GetMagickFileFormat GmGetMagickFileFormat
+#define GetMagickGeometry GmGetMagickGeometry
+#define GetMagickInfo GmGetMagickInfo
+#define GetMagickInfoArray GmGetMagickInfoArray
+#define GetMagickRegistry GmGetMagickRegistry
+#define GetMagickResource GmGetMagickResource
+#define GetMagickResourceLimit GmGetMagickResourceLimit
+#define GetMagickVersion GmGetMagickVersion
+#define GetMagickWebSite GmGetMagickWebSite
+#define GetMontageInfo GmGetMontageInfo
+#define GetNextImageInList GmGetNextImageInList
+#define GetNumberColors GmGetNumberColors
+#define GetOnePixel GmGetOnePixel
+#define GetOptimalKernelWidth GmGetOptimalKernelWidth
+#define GetOptimalKernelWidth1D GmGetOptimalKernelWidth1D
+#define GetOptimalKernelWidth2D GmGetOptimalKernelWidth2D
+#define GetPageGeometry GmGetPageGeometry
+#define GetPathComponent GmGetPathComponent
+#define GetPixelCacheArea GmGetPixelCacheArea
+#define GetPixelCacheInCore GmGetPixelCacheInCore
+#define GetPixelCachePresent GmGetPixelCachePresent
+#define GetPixels GmGetPixels
+#define GetPostscriptDelegateInfo GmGetPostscriptDelegateInfo
+#define GetPreviousImageInList GmGetPreviousImageInList
+#define GetQuantizeInfo GmGetQuantizeInfo
+#define GetSignatureInfo GmGetSignatureInfo
+#define GetThreadViewDataSetAllocatedViews GmGetThreadViewDataSetAllocatedViews
+#define GetTimerInfo GmGetTimerInfo
+#define GetTimerResolution GmGetTimerResolution
+#define GetToken GmGetToken
+#define GetTypeInfo GmGetTypeInfo
+#define GetTypeInfoByFamily GmGetTypeInfoByFamily
+#define GetTypeList GmGetTypeList
+#define GetTypeMetrics GmGetTypeMetrics
+#define GetUserTime GmGetUserTime
+#define GlobExpression GmGlobExpression
+#define GradientImage GmGradientImage
+#define GrayscalePseudoClassImage GmGrayscalePseudoClassImage
+#define HSLTransform GmHSLTransform
+#define HWBTransform GmHWBTransform
+#define HaldClutImage GmHaldClutImage
+#define HighlightStyleToString GmHighlightStyleToString
+#define HuffmanDecodeImage GmHuffmanDecodeImage
+#define HuffmanEncode2Image GmHuffmanEncode2Image
+#define HuffmanEncodeImage GmHuffmanEncodeImage
+#define Hull GmHull
+#define IdentifyImageCommand GmIdentifyImageCommand
+#define IdentityAffine GmIdentityAffine
+#define ImageListToArray GmImageListToArray
+#define ImageToBlob GmImageToBlob
+#define ImageToFile GmImageToFile
+#define ImageToHuffman2DBlob GmImageToHuffman2DBlob
+#define ImageToJPEGBlob GmImageToJPEGBlob
+#define ImageTypeToString GmImageTypeToString
+#define ImplodeImage GmImplodeImage
+#define ImportImageChannel GmImportImageChannel
+#define ImportImageChannelsMasked GmImportImageChannelsMasked
+#define ImportImageCommand GmImportImageCommand
+#define ImportImagePixelArea GmImportImagePixelArea
+#define ImportPixelAreaOptionsInit GmImportPixelAreaOptionsInit
+#define ImportViewPixelArea GmImportViewPixelArea
+#define InitializeColorInfo GmInitializeColorInfo
+#define InitializeConstitute GmInitializeConstitute
+#define InitializeDelegateInfo GmInitializeDelegateInfo
+#define InitializeDifferenceImageOptions GmInitializeDifferenceImageOptions
+#define InitializeDifferenceStatistics GmInitializeDifferenceStatistics
+#define InitializeLogInfo GmInitializeLogInfo
+#define InitializeMagicInfo GmInitializeMagicInfo
+#define InitializeMagick GmInitializeMagick
+#define InitializeMagickClientPathAndName GmInitializeMagickClientPathAndName
+#define InitializeMagickRandomGenerator GmInitializeMagickRandomGenerator
+#define InitializeMagickRandomKernel GmInitializeMagickRandomKernel
+#define InitializeMagickRegistry GmInitializeMagickRegistry
+#define InitializeMagickResources GmInitializeMagickResources
+#define InitializeMagickSignalHandlers GmInitializeMagickSignalHandlers
+#define InitializePixelIteratorOptions GmInitializePixelIteratorOptions
+#define InitializeSemaphore GmInitializeSemaphore
+#define InitializeTemporaryFiles GmInitializeTemporaryFiles
+#define InitializeTypeInfo GmInitializeTypeInfo
+#define InsertImageInList GmInsertImageInList
+#define InsertRowHDU GmInsertRowHDU
+#define InterlaceTypeToString GmInterlaceTypeToString
+#define InterpolateColor GmInterpolateColor
+#define InterpolateViewColor GmInterpolateViewColor
+#define InvokeDelegate GmInvokeDelegate
+#define InvokePostscriptDelegate GmInvokePostscriptDelegate
+#define IsAccessible GmIsAccessible
+#define IsAccessibleAndNotEmpty GmIsAccessibleAndNotEmpty
+#define IsAccessibleNoLogging GmIsAccessibleNoLogging
+#define IsEventLogging GmIsEventLogging
+#define IsGeometry GmIsGeometry
+#define IsGlob GmIsGlob
+#define IsGrayImage GmIsGrayImage
+#define IsImagesEqual GmIsImagesEqual
+#define IsMagickConflict GmIsMagickConflict
+#define IsMonochromeImage GmIsMonochromeImage
+#define IsOpaqueImage GmIsOpaqueImage
+#define IsPaletteImage GmIsPaletteImage
+#define IsSubimage GmIsSubimage
+#define IsTaintImage GmIsTaintImage
+#define IsWriteable GmIsWriteable
+#define LZWEncode2Image GmLZWEncode2Image
+#define LZWEncodeImage GmLZWEncodeImage
+#define LevelImage GmLevelImage
+#define LevelImageChannel GmLevelImageChannel
+#define LiberateMagickResource GmLiberateMagickResource
+#define LiberateMemory GmLiberateMemory
+#define LiberateSemaphoreInfo GmLiberateSemaphoreInfo
+#define LiberateTemporaryFile GmLiberateTemporaryFile
+#define ListColorInfo GmListColorInfo
+#define ListDelegateInfo GmListDelegateInfo
+#define ListFiles GmListFiles
+#define ListMagicInfo GmListMagicInfo
+#define ListMagickInfo GmListMagickInfo
+#define ListMagickResourceInfo GmListMagickResourceInfo
+#define ListModuleMap GmListModuleMap
+#define ListTypeInfo GmListTypeInfo
+#define LocaleCompare GmLocaleCompare
+#define LocaleLower GmLocaleLower
+#define LocaleNCompare GmLocaleNCompare
+#define LocaleUpper GmLocaleUpper
+#define LockSemaphoreInfo GmLockSemaphoreInfo
+#define LogMagickEvent GmLogMagickEvent
+#define LogMagickEventList GmLogMagickEventList
+#define MatteColor GmMatteColor
+#define MSBOrderLong GmMSBOrderLong
+#define MSBOrderShort GmMSBOrderShort
+#define MagickAllocFunctions GmMagickAllocFunctions
+#define MagickArraySize GmMagickArraySize
+#define MagickBitStreamInitializeRead GmMagickBitStreamInitializeRead
+#define MagickBitStreamInitializeWrite GmMagickBitStreamInitializeWrite
+#define MagickBitStreamMSBRead GmMagickBitStreamMSBRead
+#define MagickBitStreamMSBWrite GmMagickBitStreamMSBWrite
+#define MagickCloneMemory GmMagickCloneMemory
+#define MagickCommand GmMagickCommand
+#define MagickCompositeImageUnderColor GmMagickCompositeImageUnderColor
+#define MagickConfirmAccess GmMagickConfirmAccess
+#define MagickConstrainColormapIndex GmMagickConstrainColormapIndex
+#define MagickCreateDirectoryPath GmMagickCreateDirectoryPath
+#define MagickDestroyCommandInfo GmMagickDestroyCommandInfo
+#define MagickFindRawImageMinMax GmMagickFindRawImageMinMax
+#define MagickFormatString GmMagickFormatString
+#define MagickFormatStringList GmMagickFormatStringList
+#define MagickFree GmMagickFree
+#define MagickFreeAligned GmMagickFreeAligned
+#define MagickFmin GmMagickFmin
+#define MagickFmax GmMagickFmax
+#define MagickGetBitRevTable GmMagickGetBitRevTable
+#define MagickGetFileSystemBlockSize GmMagickGetFileSystemBlockSize
+#define MagickGetMMUPageSize GmMagickGetMMUPageSize
+#define MagickGetQuantumSamplesPerPixel GmMagickGetQuantumSamplesPerPixel
+#define MagickInitializeCommandInfo GmMagickInitializeCommandInfo
+#define MagickIsTrue GmMagickIsTrue
+#define MagickMalloc GmMagickMalloc
+#define MagickMallocAligned GmMagickMallocAligned
+#define MagickMallocAlignedArray GmMagickMallocAlignedArray
+#define MagickMallocArray GmMagickMallocArray
+#define MagickMallocCleared GmMagickMallocCleared
+#define MagickMapAccessEntry GmMagickMapAccessEntry
+#define MagickMapAddEntry GmMagickMapAddEntry
+#define MagickMapAllocateIterator GmMagickMapAllocateIterator
+#define MagickMapAllocateMap GmMagickMapAllocateMap
+#define MagickMapClearMap GmMagickMapClearMap
+#define MagickMapCloneMap GmMagickMapCloneMap
+#define MagickMapCopyBlob GmMagickMapCopyBlob
+#define MagickMapCopyString GmMagickMapCopyString
+#define MagickMapDeallocateBlob GmMagickMapDeallocateBlob
+#define MagickMapDeallocateIterator GmMagickMapDeallocateIterator
+#define MagickMapDeallocateMap GmMagickMapDeallocateMap
+#define MagickMapDeallocateString GmMagickMapDeallocateString
+#define MagickMapDereferenceIterator GmMagickMapDereferenceIterator
+#define MagickMapIterateNext GmMagickMapIterateNext
+#define MagickMapIteratePrevious GmMagickMapIteratePrevious
+#define MagickMapIterateToBack GmMagickMapIterateToBack
+#define MagickMapIterateToFront GmMagickMapIterateToFront
+#define MagickMapRemoveEntry GmMagickMapRemoveEntry
+#define MagickMonitor GmMagickMonitor
+#define MagickMonitorFormatted GmMagickMonitorFormatted
+#define MagickRandNewSeed GmMagickRandNewSeed
+#define MagickRandReentrant GmMagickRandReentrant
+#define MagickRandomInteger GmMagickRandomInteger
+#define MagickRandomReal GmMagickRandomReal
+#define MagickRealloc GmMagickRealloc
+#define MagickReverseBits GmMagickReverseBits
+#define MagickSceneFileName GmMagickSceneFileName
+#define MagickSetConfirmAccessHandler GmMagickSetConfirmAccessHandler
+#define MagickSetFileSystemBlockSize GmMagickSetFileSystemBlockSize
+#define MagickSizeStrToInt64 GmMagickSizeStrToInt64
+#define MagickSpawnVP GmMagickSpawnVP
+#define MagickStripSpacesFromString GmMagickStripSpacesFromString
+#define MagickStrlCat GmMagickStrlCat
+#define MagickStrlCpy GmMagickStrlCpy
+#define MagickStrlCpyTrunc GmMagickStrlCpyTrunc
+#define MagickSwabArrayOfDouble GmMagickSwabArrayOfDouble
+#define MagickSwabArrayOfFloat GmMagickSwabArrayOfFloat
+#define MagickSwabArrayOfUInt16 GmMagickSwabArrayOfUInt16
+#define MagickSwabArrayOfUInt32 GmMagickSwabArrayOfUInt32
+#define MagickSwabDouble GmMagickSwabDouble
+#define MagickSwabFloat GmMagickSwabFloat
+#define MagickSwabUInt16 GmMagickSwabUInt16
+#define MagickSwabUInt32 GmMagickSwabUInt32
+#define MagickToMime GmMagickToMime
+#define MagickTsdGetSpecific GmMagickTsdGetSpecific
+#define MagickTsdKeyCreate GmMagickTsdKeyCreate
+#define MagickTsdKeyCreate2 GmMagickTsdKeyCreate2
+#define MagickTsdKeyDelete GmMagickTsdKeyDelete
+#define MagickTsdSetSpecific GmMagickTsdSetSpecific
+#define MagickWordStreamInitializeRead GmMagickWordStreamInitializeRead
+#define MagickWordStreamInitializeWrite GmMagickWordStreamInitializeWrite
+#define MagickWordStreamLSBRead GmMagickWordStreamLSBRead
+#define MagickWordStreamLSBWrite GmMagickWordStreamLSBWrite
+#define MagickWordStreamLSBWriteFlush GmMagickWordStreamLSBWriteFlush
+#define MagickXAnimateBackgroundImage GmMagickXAnimateBackgroundImage
+#define MagickXAnimateImages GmMagickXAnimateImages
+#define MagickXAnnotateImage GmMagickXAnnotateImage
+#define MagickXBestFont GmMagickXBestFont
+#define MagickXBestIconSize GmMagickXBestIconSize
+#define MagickXBestPixel GmMagickXBestPixel
+#define MagickXBestVisualInfo GmMagickXBestVisualInfo
+#define MagickXCheckRefreshWindows GmMagickXCheckRefreshWindows
+#define MagickXClientMessage GmMagickXClientMessage
+#define MagickXColorBrowserWidget GmMagickXColorBrowserWidget
+#define MagickXCommandWidget GmMagickXCommandWidget
+#define MagickXConfigureImageColormap GmMagickXConfigureImageColormap
+#define MagickXConfirmWidget GmMagickXConfirmWidget
+#define MagickXConstrainWindowPosition GmMagickXConstrainWindowPosition
+#define MagickXDelay GmMagickXDelay
+#define MagickXDestroyResourceInfo GmMagickXDestroyResourceInfo
+#define MagickXDestroyWindowColors GmMagickXDestroyWindowColors
+#define MagickXDestroyX11Resources GmMagickXDestroyX11Resources
+#define MagickXDestroyXWindowInfo GmMagickXDestroyXWindowInfo
+#define MagickXDestroyXWindows GmMagickXDestroyXWindows
+#define MagickXDialogWidget GmMagickXDialogWidget
+#define MagickXDisplayBackgroundImage GmMagickXDisplayBackgroundImage
+#define MagickXDisplayImage GmMagickXDisplayImage
+#define MagickXDisplayImageInfo GmMagickXDisplayImageInfo
+#define MagickXDrawImage GmMagickXDrawImage
+#define MagickXError GmMagickXError
+#define MagickXFileBrowserWidget GmMagickXFileBrowserWidget
+#define MagickXFontBrowserWidget GmMagickXFontBrowserWidget
+#define MagickXFreeResources GmMagickXFreeResources
+#define MagickXFreeStandardColormap GmMagickXFreeStandardColormap
+#define MagickXGetAnnotateInfo GmMagickXGetAnnotateInfo
+#define MagickXGetImportInfo GmMagickXGetImportInfo
+#define MagickXGetMapInfo GmMagickXGetMapInfo
+#define MagickXGetPixelPacket GmMagickXGetPixelPacket
+#define MagickXGetResourceClass GmMagickXGetResourceClass
+#define MagickXGetResourceDatabase GmMagickXGetResourceDatabase
+#define MagickXGetResourceInfo GmMagickXGetResourceInfo
+#define MagickXGetResourceInstance GmMagickXGetResourceInstance
+#define MagickXGetScreenDensity GmMagickXGetScreenDensity
+#define MagickXGetWindowColor GmMagickXGetWindowColor
+#define MagickXGetWindowInfo GmMagickXGetWindowInfo
+#define MagickXHighlightEllipse GmMagickXHighlightEllipse
+#define MagickXHighlightLine GmMagickXHighlightLine
+#define MagickXHighlightRectangle GmMagickXHighlightRectangle
+#define MagickXImportImage GmMagickXImportImage
+#define MagickXInfoWidget GmMagickXInfoWidget
+#define MagickXInitializeWindows GmMagickXInitializeWindows
+#define MagickXListBrowserWidget GmMagickXListBrowserWidget
+#define MagickXMagickMonitor GmMagickXMagickMonitor
+#define MagickXMakeCursor GmMagickXMakeCursor
+#define MagickXMakeImage GmMagickXMakeImage
+#define MagickXMakeMagnifyImage GmMagickXMakeMagnifyImage
+#define MagickXMakeStandardColormap GmMagickXMakeStandardColormap
+#define MagickXMakeWindow GmMagickXMakeWindow
+#define MagickXMenuWidget GmMagickXMenuWidget
+#define MagickXMonitorWidget GmMagickXMonitorWidget
+#define MagickXNoticeWidget GmMagickXNoticeWidget
+#define MagickXPreferencesWidget GmMagickXPreferencesWidget
+#define MagickXQueryColorDatabase GmMagickXQueryColorDatabase
+#define MagickXQueryPosition GmMagickXQueryPosition
+#define MagickXRefreshWindow GmMagickXRefreshWindow
+#define MagickXRemoteCommand GmMagickXRemoteCommand
+#define MagickXRetainWindowColors GmMagickXRetainWindowColors
+#define MagickXSetCursorState GmMagickXSetCursorState
+#define MagickXSetWindows GmMagickXSetWindows
+#define MagickXSignalHandler GmMagickXSignalHandler
+#define MagickXTextViewWidget GmMagickXTextViewWidget
+#define MagickXUserPreferences GmMagickXUserPreferences
+#define MagickXWarning GmMagickXWarning
+#define MagickXWindowByID GmMagickXWindowByID
+#define MagickXWindowByName GmMagickXWindowByName
+#define MagickXWindowByProperty GmMagickXWindowByProperty
+#define MagnifyImage GmMagnifyImage
+#define MapBlob GmMapBlob
+#define MapImage GmMapImage
+#define MapImages GmMapImages
+#define MapModeToString GmMapModeToString
+#define MatteFloodfillImage GmMatteFloodfillImage
+#define MedianFilterImage GmMedianFilterImage
+#define MetricTypeToString GmMetricTypeToString
+#define MinifyImage GmMinifyImage
+#define ModifyCache GmModifyCache
+#define ModifyImage GmModifyImage
+#define Modulate GmModulate
+#define ModulateImage GmModulateImage
+#define MogrifyImage GmMogrifyImage
+#define MogrifyImageCommand GmMogrifyImageCommand
+#define MogrifyImages GmMogrifyImages
+#define MontageImageCommand GmMontageImageCommand
+#define MontageImages GmMontageImages
+#define MorphImages GmMorphImages
+#define MosaicImages GmMosaicImages
+#define MotionBlurImage GmMotionBlurImage
+#define MultilineCensus GmMultilineCensus
+#define NegateImage GmNegateImage
+#define NewImageList GmNewImageList
+#define NextImageProfile GmNextImageProfile
+#define NoiseTypeToString GmNoiseTypeToString
+#define NormalizeImage GmNormalizeImage
+#define OilPaintImage GmOilPaintImage
+#define OpaqueImage GmOpaqueImage
+#define OpenBlob GmOpenBlob
+#define OpenCacheView GmOpenCacheView
+#define OrderedDitherImage GmOrderedDitherImage
+#define OrientationTypeToString GmOrientationTypeToString
+#define PackbitsEncode2Image GmPackbitsEncode2Image
+#define PackbitsEncodeImage GmPackbitsEncodeImage
+#define PanicDestroyMagick GmPanicDestroyMagick
+#define PersistCache GmPersistCache
+#define PingBlob GmPingBlob
+#define PingImage GmPingImage
+#define PixelIterateDualModify GmPixelIterateDualModify
+#define PixelIterateDualNew GmPixelIterateDualNew
+#define PixelIterateDualRead GmPixelIterateDualRead
+#define PixelIterateMonoModify GmPixelIterateMonoModify
+#define PixelIterateMonoSet GmPixelIterateMonoSet
+#define PixelIterateMonoRead GmPixelIterateMonoRead
+#define PixelIterateTripleModify GmPixelIterateTripleModify
+#define PixelIterateTripleNew GmPixelIterateTripleNew
+#define PlasmaImage GmPlasmaImage
+#define PopImagePixels GmPopImagePixels
+#define PrependImageToList GmPrependImageToList
+#define ProfileImage GmProfileImage
+#define PSDensityGeometry GmPSDensityGeometry
+#define PSPageGeometry GmPSPageGeometry
+#define PurgeTemporaryFiles GmPurgeTemporaryFiles
+#define PurgeTemporaryFilesAsyncSafe GmPurgeTemporaryFilesAsyncSafe
+#define PushImagePixels GmPushImagePixels
+#define QuantizeImage GmQuantizeImage
+#define QuantizeImages GmQuantizeImages
+#define QuantumOperatorImage GmQuantumOperatorImage
+#define QuantumOperatorImageMultivalue GmQuantumOperatorImageMultivalue
+#define QuantumOperatorRegionImage GmQuantumOperatorRegionImage
+#define QuantumOperatorToString GmQuantumOperatorToString
+#define QuantumSampleTypeToString GmQuantumSampleTypeToString
+#define QuantumTypeToString GmQuantumTypeToString
+#define QueryColorDatabase GmQueryColorDatabase
+#define QueryColorname GmQueryColorname
+#define RGBTransformImage GmRGBTransformImage
+#define RaiseImage GmRaiseImage
+#define RandomChannelThresholdImage GmRandomChannelThresholdImage
+#define ReacquireMemory GmReacquireMemory
+#define ReadBlob GmReadBlob
+#define ReadBlobByte GmReadBlobByte
+#define ReadBlobByteFromBuffer GmReadBlobByteFromBuffer
+#define ReadBlobLSBDouble GmReadBlobLSBDouble
+#define ReadBlobLSBDoubles GmReadBlobLSBDoubles
+#define ReadBlobLSBFloat GmReadBlobLSBFloat
+#define ReadBlobLSBFloats GmReadBlobLSBFloats
+#define ReadBlobLSBLong GmReadBlobLSBLong
+#define ReadBlobLSBLongs GmReadBlobLSBLongs
+#define ReadBlobLSBShort GmReadBlobLSBShort
+#define ReadBlobLSBShortFromBuffer GmReadBlobLSBShortFromBuffer
+#define ReadBlobLSBShorts GmReadBlobLSBShorts
+#define ReadBlobMSBDouble GmReadBlobMSBDouble
+#define ReadBlobMSBDoubles GmReadBlobMSBDoubles
+#define ReadBlobMSBFloat GmReadBlobMSBFloat
+#define ReadBlobMSBFloats GmReadBlobMSBFloats
+#define ReadBlobMSBLong GmReadBlobMSBLong
+#define ReadBlobMSBLongs GmReadBlobMSBLongs
+#define ReadBlobMSBShort GmReadBlobMSBShort
+#define ReadBlobMSBShorts GmReadBlobMSBShorts
+#define ReadBlobString GmReadBlobString
+#define ReadBlobZC GmReadBlobZC
+#define ReadImage GmReadImage
+#define ReadInlineImage GmReadInlineImage
+#define ReduceNoiseImage GmReduceNoiseImage
+#define ReferenceBlob GmReferenceBlob
+#define ReferenceCache GmReferenceCache
+#define ReferenceImage GmReferenceImage
+#define RegisterARTImage GmRegisterARTImage
+#define RegisterAVIImage GmRegisterAVIImage
+#define RegisterAVSImage GmRegisterAVSImage
+#define RegisterBMPImage GmRegisterBMPImage
+#define RegisterCALSImage GmRegisterCALSImage
+#define RegisterCAPTIONImage GmRegisterCAPTIONImage
+#define RegisterCINEONImage GmRegisterCINEONImage
+#define RegisterCMYKImage GmRegisterCMYKImage
+#define RegisterCUTImage GmRegisterCUTImage
+#define RegisterDCMImage GmRegisterDCMImage
+#define RegisterDCRAWImage GmRegisterDCRAWImage
+#define RegisterDIBImage GmRegisterDIBImage
+#define RegisterDPXImage GmRegisterDPXImage
+#define RegisterEPTImage GmRegisterEPTImage
+#define RegisterFAXImage GmRegisterFAXImage
+#define RegisterFITSImage GmRegisterFITSImage
+#define RegisterGIFImage GmRegisterGIFImage
+#define RegisterGRADIENTImage GmRegisterGRADIENTImage
+#define RegisterGRAYImage GmRegisterGRAYImage
+#define RegisterHISTOGRAMImage GmRegisterHISTOGRAMImage
+#define RegisterHRZImage GmRegisterHRZImage
+#define RegisterHTMLImage GmRegisterHTMLImage
+#define RegisterICONImage GmRegisterICONImage
+#define RegisterIDENTITYImage GmRegisterIDENTITYImage
+#define RegisterINFOImage GmRegisterINFOImage
+#define RegisterJNXImage GmRegisterJNXImage
+#define RegisterJP2Image GmRegisterJP2Image
+#define RegisterJPEGImage GmRegisterJPEGImage
+#define RegisterLABELImage GmRegisterLABELImage
+#define RegisterLOCALEImage GmRegisterLOCALEImage
+#define RegisterLOGOImage GmRegisterLOGOImage
+#define RegisterMACImage GmRegisterMACImage
+#define RegisterMAPImage GmRegisterMAPImage
+#define RegisterMATImage GmRegisterMATImage
+#define RegisterMATTEImage GmRegisterMATTEImage
+#define RegisterMETAImage GmRegisterMETAImage
+#define RegisterMIFFImage GmRegisterMIFFImage
+#define RegisterMONOImage GmRegisterMONOImage
+#define RegisterMPCImage GmRegisterMPCImage
+#define RegisterMPEGImage GmRegisterMPEGImage
+#define RegisterMPRImage GmRegisterMPRImage
+#define RegisterMSLImage GmRegisterMSLImage
+#define RegisterMTVImage GmRegisterMTVImage
+#define RegisterMVGImage GmRegisterMVGImage
+#define RegisterMagickInfo GmRegisterMagickInfo
+#define RegisterNULLImage GmRegisterNULLImage
+#define RegisterOTBImage GmRegisterOTBImage
+#define RegisterPALMImage GmRegisterPALMImage
+#define RegisterPCDImage GmRegisterPCDImage
+#define RegisterPCLImage GmRegisterPCLImage
+#define RegisterPCXImage GmRegisterPCXImage
+#define RegisterPDBImage GmRegisterPDBImage
+#define RegisterPDFImage GmRegisterPDFImage
+#define RegisterPICTImage GmRegisterPICTImage
+#define RegisterPIXImage GmRegisterPIXImage
+#define RegisterPLASMAImage GmRegisterPLASMAImage
+#define RegisterPNGImage GmRegisterPNGImage
+#define RegisterPNMImage GmRegisterPNMImage
+#define RegisterPREVIEWImage GmRegisterPREVIEWImage
+#define RegisterPS2Image GmRegisterPS2Image
+#define RegisterPS3Image GmRegisterPS3Image
+#define RegisterPSDImage GmRegisterPSDImage
+#define RegisterPSImage GmRegisterPSImage
+#define RegisterPWPImage GmRegisterPWPImage
+#define RegisterRGBImage GmRegisterRGBImage
+#define RegisterRLAImage GmRegisterRLAImage
+#define RegisterRLEImage GmRegisterRLEImage
+#define RegisterSCTImage GmRegisterSCTImage
+#define RegisterSFWImage GmRegisterSFWImage
+#define RegisterSGIImage GmRegisterSGIImage
+#define RegisterSTEGANOImage GmRegisterSTEGANOImage
+#define RegisterSUNImage GmRegisterSUNImage
+#define RegisterSVGImage GmRegisterSVGImage
+#define RegisterStaticModules GmRegisterStaticModules
+#define RegisterTGAImage GmRegisterTGAImage
+#define RegisterTIFFImage GmRegisterTIFFImage
+#define RegisterTILEImage GmRegisterTILEImage
+#define RegisterTIMImage GmRegisterTIMImage
+#define RegisterTOPOLImage GmRegisterTOPOLImage
+#define RegisterTTFImage GmRegisterTTFImage
+#define RegisterTXTImage GmRegisterTXTImage
+#define RegisterUILImage GmRegisterUILImage
+#define RegisterURLImage GmRegisterURLImage
+#define RegisterUYVYImage GmRegisterUYVYImage
+#define RegisterVICARImage GmRegisterVICARImage
+#define RegisterVIDImage GmRegisterVIDImage
+#define RegisterVIFFImage GmRegisterVIFFImage
+#define RegisterWBMPImage GmRegisterWBMPImage
+#define RegisterWMFImage GmRegisterWMFImage
+#define RegisterWPGImage GmRegisterWPGImage
+#define RegisterXBMImage GmRegisterXBMImage
+#define RegisterXCFImage GmRegisterXCFImage
+#define RegisterXCImage GmRegisterXCImage
+#define RegisterXImage GmRegisterXImage
+#define RegisterXPMImage GmRegisterXPMImage
+#define RegisterXWDImage GmRegisterXWDImage
+#define RegisterYUVImage GmRegisterYUVImage
+#define RemoveDefinitions GmRemoveDefinitions
+#define RemoveFirstImageFromList GmRemoveFirstImageFromList
+#define RemoveLastImageFromList GmRemoveLastImageFromList
+#define ReplaceImageColormap GmReplaceImageColormap
+#define ReplaceImageInList GmReplaceImageInList
+#define ResetImagePage GmResetImagePage
+#define ResetTimer GmResetTimer
+#define ResizeFilterToString GmResizeFilterToString
+#define ResizeImage GmResizeImage
+#define ResolutionTypeToString GmResolutionTypeToString
+#define ReverseImageList GmReverseImageList
+#define RollImage GmRollImage
+#define RotateImage GmRotateImage
+#define SampleImage GmSampleImage
+#define ScaleImage GmScaleImage
+#define SeekBlob GmSeekBlob
+#define SegmentImage GmSegmentImage
+#define SetBlobClosable GmSetBlobClosable
+#define SetBlobTemporary GmSetBlobTemporary
+#define SetCacheView GmSetCacheView
+#define SetCacheViewPixels GmSetCacheViewPixels
+#define SetClientFilename GmSetClientFilename
+#define SetClientName GmSetClientName
+#define SetClientPath GmSetClientPath
+#define SetDelegateInfo GmSetDelegateInfo
+#define SetErrorHandler GmSetErrorHandler
+#define SetExceptionInfo GmSetExceptionInfo
+#define SetFatalErrorHandler GmSetFatalErrorHandler
+#define SetGeometry GmSetGeometry
+#define SetImage GmSetImage
+#define SetImageEx GmSetImageEx
+#define SetImageAttribute GmSetImageAttribute
+#define SetImageChannelDepth GmSetImageChannelDepth
+#define SetImageClipMask GmSetImageClipMask
+#define SetImageColor GmSetImageColor
+#define SetImageColorRegion GmSetImageColorRegion
+#define SetImageDepth GmSetImageDepth
+#define SetImageInfo GmSetImageInfo
+#define SetImageOpacity GmSetImageOpacity
+#define SetImagePixels GmSetImagePixels
+#define SetImagePixelsEx GmSetImagePixelsEx
+#define SetImageProfile GmSetImageProfile
+#define SetImageType GmSetImageType
+#define SetImageVirtualPixelMethod GmSetImageVirtualPixelMethod
+#define SetLogEventMask GmSetLogEventMask
+#define SetLogFormat GmSetLogFormat
+#define SetLogMethod GmSetLogMethod
+#define SetMagickInfo GmSetMagickInfo
+#define SetMagickRegistry GmSetMagickRegistry
+#define SetMagickResourceLimit GmSetMagickResourceLimit
+#define SetMonitorHandler GmSetMonitorHandler
+#define SetWarningHandler GmSetWarningHandler
+#define ShadeImage GmShadeImage
+#define SharpenImage GmSharpenImage
+#define SharpenImageChannel GmSharpenImageChannel
+#define ShaveImage GmShaveImage
+#define ShearImage GmShearImage
+#define SignatureImage GmSignatureImage
+#define SolarizeImage GmSolarizeImage
+#define SortColormapByIntensity GmSortColormapByIntensity
+#define SpliceImageIntoList GmSpliceImageIntoList
+#define SplitImageList GmSplitImageList
+#define SpreadImage GmSpreadImage
+#define SteganoImage GmSteganoImage
+#define StereoImage GmStereoImage
+#define StorageTypeToString GmStorageTypeToString
+#define StretchTypeToString GmStretchTypeToString
+#define StringToArgv GmStringToArgv
+#define StringToChannelType GmStringToChannelType
+#define StringToColorspaceType GmStringToColorspaceType
+#define StringToCompositeOperator GmStringToCompositeOperator
+#define StringToCompressionType GmStringToCompressionType
+#define StringToDouble GmStringToDouble
+#define StringToEndianType GmStringToEndianType
+#define StringToFilterTypes GmStringToFilterTypes
+#define StringToGravityType GmStringToGravityType
+#define StringToHighlightStyle GmStringToHighlightStyle
+#define StringToImageType GmStringToImageType
+#define StringToInterlaceType GmStringToInterlaceType
+#define StringToList GmStringToList
+#define StringToMetricType GmStringToMetricType
+#define StringToNoiseType GmStringToNoiseType
+#define StringToPreviewType GmStringToPreviewType
+#define StringToQuantumOperator GmStringToQuantumOperator
+#define StringToResolutionType GmStringToResolutionType
+#define StringToResourceType GmStringToResourceType
+#define StringToVirtualPixelMethod GmStringToVirtualPixelMethod
+#define Strip GmStrip
+#define StripImage GmStripImage
+#define StyleTypeToString GmStyleTypeToString
+#define SubstituteString GmSubstituteString
+#define SwirlImage GmSwirlImage
+#define SyncCacheView GmSyncCacheView
+#define SyncCacheViewPixels GmSyncCacheViewPixels
+#define SyncImage GmSyncImage
+#define SyncImagePixels GmSyncImagePixels
+#define SyncImagePixelsEx GmSyncImagePixelsEx
+#define SyncNextImageInList GmSyncNextImageInList
+#define SystemCommand GmSystemCommand
+#define TellBlob GmTellBlob
+#define TextureImage GmTextureImage
+#define ThresholdImage GmThresholdImage
+#define ThrowLoggedException GmThrowLoggedException
+#define ThumbnailImage GmThumbnailImage
+#define TimeImageCommand GmTimeImageCommand
+#define Tokenizer GmTokenizer
+#define TransformColorspace GmTransformColorspace
+#define TransformHSL GmTransformHSL
+#define TransformHWB GmTransformHWB
+#define TransformImage GmTransformImage
+#define TransformRGBImage GmTransformRGBImage
+#define TransformSignature GmTransformSignature
+#define TranslateText GmTranslateText
+#define TranslateTextEx GmTranslateTextEx
+#define TransparentImage GmTransparentImage
+#define UnlockSemaphoreInfo GmUnlockSemaphoreInfo
+#define UnmapBlob GmUnmapBlob
+#define UnregisterARTImage GmUnregisterARTImage
+#define UnregisterAVIImage GmUnregisterAVIImage
+#define UnregisterAVSImage GmUnregisterAVSImage
+#define UnregisterBMPImage GmUnregisterBMPImage
+#define UnregisterCALSImage GmUnregisterCALSImage
+#define UnregisterCAPTIONImage GmUnregisterCAPTIONImage
+#define UnregisterCINEONImage GmUnregisterCINEONImage
+#define UnregisterCMYKImage GmUnregisterCMYKImage
+#define UnregisterCUTImage GmUnregisterCUTImage
+#define UnregisterDCMImage GmUnregisterDCMImage
+#define UnregisterDCRAWImage GmUnregisterDCRAWImage
+#define UnregisterDIBImage GmUnregisterDIBImage
+#define UnregisterDPXImage GmUnregisterDPXImage
+#define UnregisterEPTImage GmUnregisterEPTImage
+#define UnregisterFAXImage GmUnregisterFAXImage
+#define UnregisterFITSImage GmUnregisterFITSImage
+#define UnregisterGIFImage GmUnregisterGIFImage
+#define UnregisterGRADIENTImage GmUnregisterGRADIENTImage
+#define UnregisterGRAYImage GmUnregisterGRAYImage
+#define UnregisterHISTOGRAMImage GmUnregisterHISTOGRAMImage
+#define UnregisterHRZImage GmUnregisterHRZImage
+#define UnregisterHTMLImage GmUnregisterHTMLImage
+#define UnregisterICONImage GmUnregisterICONImage
+#define UnregisterIDENTITYImage GmUnregisterIDENTITYImage
+#define UnregisterINFOImage GmUnregisterINFOImage
+#define UnregisterJNXImage GmUnregisterJNXImage
+#define UnregisterJP2Image GmUnregisterJP2Image
+#define UnregisterJPEGImage GmUnregisterJPEGImage
+#define UnregisterLABELImage GmUnregisterLABELImage
+#define UnregisterLOCALEImage GmUnregisterLOCALEImage
+#define UnregisterLOGOImage GmUnregisterLOGOImage
+#define UnregisterMACImage GmUnregisterMACImage
+#define UnregisterMAPImage GmUnregisterMAPImage
+#define UnregisterMATImage GmUnregisterMATImage
+#define UnregisterMATTEImage GmUnregisterMATTEImage
+#define UnregisterMETAImage GmUnregisterMETAImage
+#define UnregisterMIFFImage GmUnregisterMIFFImage
+#define UnregisterMONOImage GmUnregisterMONOImage
+#define UnregisterMPCImage GmUnregisterMPCImage
+#define UnregisterMPEGImage GmUnregisterMPEGImage
+#define UnregisterMPRImage GmUnregisterMPRImage
+#define UnregisterMSLImage GmUnregisterMSLImage
+#define UnregisterMTVImage GmUnregisterMTVImage
+#define UnregisterMVGImage GmUnregisterMVGImage
+#define UnregisterMagickInfo GmUnregisterMagickInfo
+#define UnregisterNULLImage GmUnregisterNULLImage
+#define UnregisterOTBImage GmUnregisterOTBImage
+#define UnregisterPALMImage GmUnregisterPALMImage
+#define UnregisterPCDImage GmUnregisterPCDImage
+#define UnregisterPCLImage GmUnregisterPCLImage
+#define UnregisterPCXImage GmUnregisterPCXImage
+#define UnregisterPDBImage GmUnregisterPDBImage
+#define UnregisterPDFImage GmUnregisterPDFImage
+#define UnregisterPICTImage GmUnregisterPICTImage
+#define UnregisterPIXImage GmUnregisterPIXImage
+#define UnregisterPLASMAImage GmUnregisterPLASMAImage
+#define UnregisterPNGImage GmUnregisterPNGImage
+#define UnregisterPNMImage GmUnregisterPNMImage
+#define UnregisterPREVIEWImage GmUnregisterPREVIEWImage
+#define UnregisterPS2Image GmUnregisterPS2Image
+#define UnregisterPS3Image GmUnregisterPS3Image
+#define UnregisterPSDImage GmUnregisterPSDImage
+#define UnregisterPSImage GmUnregisterPSImage
+#define UnregisterPWPImage GmUnregisterPWPImage
+#define UnregisterRGBImage GmUnregisterRGBImage
+#define UnregisterRLAImage GmUnregisterRLAImage
+#define UnregisterRLEImage GmUnregisterRLEImage
+#define UnregisterSCTImage GmUnregisterSCTImage
+#define UnregisterSFWImage GmUnregisterSFWImage
+#define UnregisterSGIImage GmUnregisterSGIImage
+#define UnregisterSTEGANOImage GmUnregisterSTEGANOImage
+#define UnregisterSUNImage GmUnregisterSUNImage
+#define UnregisterSVGImage GmUnregisterSVGImage
+#define UnregisterStaticModules GmUnregisterStaticModules
+#define UnregisterTGAImage GmUnregisterTGAImage
+#define UnregisterTIFFImage GmUnregisterTIFFImage
+#define UnregisterTILEImage GmUnregisterTILEImage
+#define UnregisterTIMImage GmUnregisterTIMImage
+#define UnregisterTOPOLImage GmUnregisterTOPOLImage
+#define UnregisterTTFImage GmUnregisterTTFImage
+#define UnregisterTXTImage GmUnregisterTXTImage
+#define UnregisterUILImage GmUnregisterUILImage
+#define UnregisterURLImage GmUnregisterURLImage
+#define UnregisterUYVYImage GmUnregisterUYVYImage
+#define UnregisterVICARImage GmUnregisterVICARImage
+#define UnregisterVIDImage GmUnregisterVIDImage
+#define UnregisterVIFFImage GmUnregisterVIFFImage
+#define UnregisterWBMPImage GmUnregisterWBMPImage
+#define UnregisterWMFImage GmUnregisterWMFImage
+#define UnregisterWPGImage GmUnregisterWPGImage
+#define UnregisterXBMImage GmUnregisterXBMImage
+#define UnregisterXCFImage GmUnregisterXCFImage
+#define UnregisterXCImage GmUnregisterXCImage
+#define UnregisterXImage GmUnregisterXImage
+#define UnregisterXPMImage GmUnregisterXPMImage
+#define UnregisterXWDImage GmUnregisterXWDImage
+#define UnregisterYUVImage GmUnregisterYUVImage
+#define UnsharpMaskImage GmUnsharpMaskImage
+#define UnsharpMaskImageChannel GmUnsharpMaskImageChannel
+#define UpdateSignature GmUpdateSignature
+#define WaveImage GmWaveImage
+#define WhiteThresholdImage GmWhiteThresholdImage
+#define WriteBlob GmWriteBlob
+#define WriteBlobByte GmWriteBlobByte
+#define WriteBlobFile GmWriteBlobFile
+#define WriteBlobLSBLong GmWriteBlobLSBLong
+#define WriteBlobLSBShort GmWriteBlobLSBShort
+#define WriteBlobMSBLong GmWriteBlobMSBLong
+#define WriteBlobMSBShort GmWriteBlobMSBShort
+#define WriteBlobString GmWriteBlobString
+#define WriteBlobStringEOL GmWriteBlobStringEOL
+#define WriteBlobStringWithEOL GmWriteBlobStringWithEOL
+#define WriteImage GmWriteImage
+#define WriteImages GmWriteImages
+#define WriteImagesFile GmWriteImagesFile
+#define ZoomImage GmZoomImage
+
+#endif /* defined(PREFIX_MAGICK_SYMBOLS) */
+#endif /* defined(_MAGICK_SYMBOLS_H) */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/tempfile.c b/magick/tempfile.c
new file mode 100644
index 0000000..8ffd368
--- /dev/null
+++ b/magick/tempfile.c
@@ -0,0 +1,565 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% Temporary file allocation manager.
+%
+*/
+
+#include "magick/studio.h"
+#include "magick/error.h"
+#include "magick/log.h"
+#include "magick/random.h"
+#include "magick/semaphore.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#if defined(S_IRUSR) && defined(S_IWUSR)
+# define S_MODE (S_IRUSR | S_IWUSR)
+#elif defined (MSWINDOWS)
+# define S_MODE (_S_IREAD | _S_IWRITE)
+#else
+# define S_MODE 0600
+#endif
+
+#if defined(MSWINDOWS)
+# if defined(_P_tmpdir) && !defined(P_tmpdir)
+# define P_tmpdir _P_tmpdir
+# endif
+#endif
+
+/*
+ Type definitions
+*/
+typedef struct _TempfileInfo
+{
+ char
+ filename[MaxTextExtent];
+
+ struct _TempfileInfo
+ *next;
+} TempfileInfo;
+
+static TempfileInfo
+ *templist = 0;
+
+static SemaphoreInfo
+ *templist_semaphore = 0;
+
+/*
+ Add a temporary file to list
+*/
+static void AddTemporaryFileToList(const char *filename)
+{
+ (void) LogMagickEvent(TemporaryFileEvent,GetMagickModule(),
+ "Allocating temporary file \"%s\"",filename);
+ LockSemaphoreInfo(templist_semaphore);
+ {
+ TempfileInfo
+ *info;
+
+ info=MagickAllocateMemory(TempfileInfo *,sizeof(TempfileInfo));
+ if (info)
+ {
+ info->next=0;
+ (void) strlcpy(info->filename,filename,sizeof(info->filename));
+ if (!templist)
+ templist=info;
+ else
+ {
+ info->next=templist;
+ templist=info;
+ }
+ }
+ }
+ UnlockSemaphoreInfo(templist_semaphore);
+}
+
+/*
+ Remove a temporary file from the list.
+ Return MagickPass if removed or MagickFail if not found
+*/
+static MagickPassFail RemoveTemporaryFileFromList(const char *filename)
+{
+ MagickPassFail
+ status=MagickFail;
+
+ (void) LogMagickEvent(TemporaryFileEvent,GetMagickModule(),
+ "Deallocating temporary file \"%s\"",filename);
+
+ LockSemaphoreInfo(templist_semaphore);
+ {
+ TempfileInfo
+ *current,
+ *previous=0;
+
+ for (current=templist; current; current=current->next)
+ {
+ if (strcmp(current->filename,filename) == 0)
+ {
+ if (previous)
+ previous->next=current->next;
+ else
+ templist=current->next;
+ MagickFreeMemory(current);
+ status=MagickPass;
+ break;
+ }
+ previous=current;
+ }
+ }
+ UnlockSemaphoreInfo(templist_semaphore);
+ return status;
+}
+/*
+ Compose a temporary file name based a template string provided by
+ the user. Any 'X' characters are replaced with characters randomly
+ selected from a "safe" set of characters which are unlikely to
+ be interpreted by a shell or program and cause confusion.
+*/
+static void ComposeTemporaryFileName(char *name)
+{
+ static const char SafeChars[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+ char
+ *c;
+
+ assert(name != (char *) NULL);
+
+ for (c=name; *c; c++)
+ {
+ if (*c == 'X')
+ *c=SafeChars[MagickRandomInteger() % (sizeof(SafeChars)-1)];
+ }
+}
+
+/*
+ Validate a temporary directory path
+*/
+static MagickPassFail ValidateTemporaryFileDirectory(const char *tempdir)
+{
+ assert(tempdir != (char *) NULL);
+
+ if (tempdir[0] == '\0')
+ return MagickFail;
+ if (access(tempdir,W_OK) != 0)
+ return MagickFail;
+ return MagickPass;
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ A c q u i r e T e m p o r a r y F i l e N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireTemporaryFileName replaces the contents of the string buffer pointed
+% to by filename with a unique file name. MagickPass is returned if a file
+% name is allocated, or MagickFail is returned if there is a failure.
+% When the filename is allocated, a temporary file is created on disk with
+% zero length, and read/write permission by the user.
+% The allocated filename should be recovered via the LiberateTemporaryFile()
+% function once it is no longer required.
+%
+% The format of the AcquireTemporaryFileName method is:
+%
+% MagickPassFail AcquireTemporaryFileName(char *filename,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o status: MagickPass if a temporary file name is allocated and successfully
+% created on disk. MagickFail if the temporary file name or file
+% creation fails.
+%
+% o filename: Specifies a pointer to an array of characters. The unique
+% file name is returned in this array.
+%
+*/
+MagickExport MagickPassFail AcquireTemporaryFileName(char *filename)
+{
+ int
+ fd;
+
+ assert(filename != (char *) NULL);
+ if ((fd=AcquireTemporaryFileDescriptor(filename)) != -1)
+ {
+ (void) close(fd);
+ return (MagickPass);
+ }
+ return (MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ A c q u i r e T e m p o r a r y F i l e D e s c r i p t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireTemporaryFileDescriptor replaces the contents of the string buffer
+% pointed to by filename with a unique file name created on disk. A
+% read/write file descriptor (from open()) is returned on success, or -1 is
+% returned on failure. The temporary file is created on disk with read/write
+% permission by the user. The allocated temporary file should be deallocated
+% via the LiberateTemporaryFile() function once it is no longer required.
+%
+% The format of the AcquireTemporaryFileDescriptor method is:
+%
+% int AcquireTemporaryFileDescriptor(char *filename)
+%
+% A description of each parameter follows.
+%
+% o status: The file descriptor for an open file on success, or -1
+% on failure.
+%
+% o filename: Specifies a pointer to an array of characters with an
+% allocated length of at least MaxTextExtent. The unique
+% file name associated with the descriptor is returned in
+% this array.
+%
+*/
+MagickExport int AcquireTemporaryFileDescriptor(char *filename)
+{
+ static const char *env_strings[] =
+ {
+ "MAGICK_TMPDIR",
+#if defined(POSIX)
+ "TMPDIR",
+#endif /* defined(POSIX) */
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+ "TMP",
+ "TEMP",
+#endif
+ NULL
+ };
+
+ static const char *fixed_strings[] =
+ {
+#if defined(P_tmpdir)
+ P_tmpdir,
+#endif
+ NULL
+ };
+
+ char
+ tempdir[MaxTextExtent];
+
+ unsigned int
+ i;
+
+ int
+ fd=-1;
+
+ assert(filename != (char *) NULL);
+ filename[0]='\0';
+ tempdir[0]='\0';
+
+ for (i=0; i < sizeof(env_strings)/sizeof(env_strings[0]); i++)
+ {
+ const char
+ *env;
+
+ if (env_strings[i] == NULL)
+ break;
+ if ((env=getenv(env_strings[i])) != NULL)
+ {
+ const size_t copy_len = sizeof(tempdir)-16;
+ if (strlcpy(tempdir,env,copy_len) >= copy_len)
+ tempdir[0]='\0';
+ if ((tempdir[0] != '\0') &&
+ !ValidateTemporaryFileDirectory(tempdir))
+ tempdir[0]='\0';
+ if (tempdir[0] != '\0')
+ break;
+ }
+ }
+
+ if (tempdir[0] == '\0')
+ for (i=0; i < sizeof(fixed_strings)/sizeof(fixed_strings[0]); i++)
+ {
+ const size_t copy_len = sizeof(tempdir)-16;
+
+ if (fixed_strings[i] == NULL)
+ break;
+ if (strlcpy(tempdir,fixed_strings[i],copy_len) >= copy_len)
+ tempdir[0]='\0';
+ if ((tempdir[0] != '\0') &&
+ !ValidateTemporaryFileDirectory(tempdir))
+ tempdir[0]='\0';
+ if (tempdir[0] != '\0')
+ break;
+ }
+
+ if (tempdir[0] != '\0')
+ {
+ char
+ tempname[16];
+
+ int
+ tries=0;
+
+ for (tries=0; tries < 256; tries++)
+ {
+ (void) strlcpy(tempname,"gmXXXXXX",sizeof(tempname));
+ ComposeTemporaryFileName(tempname);
+ if (strlcpy(filename,tempdir,MaxTextExtent) >= MaxTextExtent)
+ break;
+ if (filename[strlen(filename)-1] != DirectorySeparator[0])
+ if (strlcat(filename,DirectorySeparator,MaxTextExtent) >=
+ MaxTextExtent)
+ break;
+ if (strlcat(filename,tempname,MaxTextExtent) >= MaxTextExtent)
+ break;
+ fd=open(filename,O_RDWR | O_CREAT | O_BINARY | O_EXCL, S_MODE);
+ if (fd != -1)
+ {
+ AddTemporaryFileToList(filename);
+ return (fd);
+ }
+ }
+ }
+
+ return fd;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ A c q u i r e T e m p o r a r y F i l e S t r e a m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireTemporaryFileStream replaces the contents of the string buffer
+% pointed to by filename with a unique file name. A pointer to an open
+% stdio FILE stream is returned on success, or a null pointer is returned
+% on failure. The temporary file is created on disk with read/write
+% permission by the user. The allocated temporary file should be deallocated
+% via the LiberateTemporaryFile() function once it is no longer required.
+%
+% The format of the AcquireTemporaryFile method is:
+%
+% FILE *AcquireTemporaryFileStream(char *filename,FileIOMode mode)
+%
+% A description of each parameter follows.
+%
+% o status: The file descriptor for an open file on success, or -1
+% on failure.
+%
+% o filename: Specifies a pointer to an array of characters. The unique
+% file name is returned in this array.
+%
+% o mode: Set to TextFileIOMode to open the file in text mode, otherwise
+% the file is opened in binary mode.
+%
+*/
+MagickExport FILE *AcquireTemporaryFileStream(char *filename,
+ FileIOMode mode)
+{
+ int
+ fd;
+
+ if ((fd=AcquireTemporaryFileDescriptor(filename)) != -1)
+ {
+ if (mode == TextFileIOMode)
+ return fdopen(fd,"w+");
+ return fdopen(fd,"wb+");
+ }
+
+ return (FILE *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y T e m p o r a r y F i l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyTemporaryFiles reclaims all currently allocated temporary files,
+% removing the files from the filesystem if they still exist. Also destroys
+% the associated semaphore so that temporary file system can not be used
+% again without invoking InitializeTemporaryFiles() to re-initialize it.
+%
+% void DestroyTemporaryFiles(void)
+%
+*/
+MagickExport void DestroyTemporaryFiles(void)
+{
+ PurgeTemporaryFiles();
+ DestroySemaphoreInfo(&templist_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e T e m p o r a r y F i l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeTemporaryFiles initializes the temporary file facility
+%
+% The format of the InitializeTemporaryFiles method is:
+%
+% MagickPassFail InitializeTemporaryFiles(void)
+%
+%
+*/
+MagickPassFail
+InitializeTemporaryFiles(void)
+{
+ assert(templist_semaphore == (SemaphoreInfo *) NULL);
+ templist_semaphore=AllocateSemaphoreInfo();
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ L i b e r a t e T e m p o r a r y F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% LiberateTemporaryFile deallocates the allocated temporary file, removing
+% the temporary file from the filesystem if it still exists. If the name
+% provided is a valid temporary file name, then the first position in the
+% string buffer is set to null in order to avoid accidental continued use.
+% If the name is not contained in the temporary file list, then it is left
+% unmodified.
+%
+% MagickPassFail LiberateTemporaryFile(char *filename)
+%
+% A description of each parameter follows.
+%
+% o filename: Specifies a pointer to an array of characters representing
+% the temporary file to reclaim.
+%
+*/
+MagickExport MagickPassFail LiberateTemporaryFile(char *filename)
+{
+ MagickPassFail
+ status = MagickFail;
+
+ if (RemoveTemporaryFileFromList(filename))
+ {
+ if ((remove(filename)) == 0)
+ status=MagickPass;
+ else
+ (void) LogMagickEvent(TemporaryFileEvent,GetMagickModule(),
+ "Temporary file removal failed \"%s\"",filename);
+ /* Erase name so it is not accidentally used again */
+ filename[0]='\0';
+ }
+ else
+ (void) LogMagickEvent(TemporaryFileEvent,GetMagickModule(),
+ "Temporary file \"%s\" to be removed not allocated!",filename);
+ return (status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ P u r g e T e m p o r a r y F i l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PurgeTemporaryFiles reclaims all currently allocated temporary files,
+% removing the files from the filesystem if they still exist. The temporary
+% file allocation system remains usable after this function is called.
+%
+% void PurgeTemporaryFiles(void)
+%
+*/
+MagickExport void PurgeTemporaryFiles(void)
+{
+ TempfileInfo
+ *member,
+ *liberate;
+
+ member=templist;
+ templist=0;
+ while(member)
+ {
+ liberate=member;
+ member=member->next;
+ (void) LogMagickEvent(TemporaryFileEvent,GetMagickModule(),
+ "Removing leaked temporary file \"%s\"",liberate->filename);
+ if ((remove(liberate->filename)) != 0)
+ (void) LogMagickEvent(TemporaryFileEvent,GetMagickModule(),
+ "Temporary file removal failed \"%s\"",liberate->filename);
+ liberate->next=0;
+ MagickFreeMemory(liberate);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ P u r g e T e m p o r a r y F i l e s A s y n c S a f e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PurgeTemporaryFiles reclaims all currently allocated temporary files,
+% removing the files from the filesystem if they still exist. This version
+% is similar to PurgeTemporaryFiles() except that it intentionally does
+% not release any memory (might use a mutex/semaphore) or invoke any
+% functions which are not async-safe. The only reason to call this function
+% is something has gone wrong and the program needs to quit immediately.
+%
+% void PurgeTemporaryFilesAsyncSafe(void)
+%
+*/
+MagickExport void PurgeTemporaryFilesAsyncSafe(void)
+{
+ const TempfileInfo
+ *member;
+
+ member=templist;
+ templist=0;
+ while(member)
+ {
+ (void) unlink(member->filename);
+ member=member->next;
+ }
+}
diff --git a/magick/tempfile.h b/magick/tempfile.h
new file mode 100644
index 0000000..4a8e386
--- /dev/null
+++ b/magick/tempfile.h
@@ -0,0 +1,87 @@
+/*
+ Copyright (C) 2003, 2004 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Temporary File Management
+*/
+
+#ifndef _MAGICK_TEMPFILE_H
+#define _MAGICK_TEMPFILE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+typedef enum
+{
+ BinaryFileIOMode,
+ TextFileIOMode
+} FileIOMode;
+
+
+MagickExport MagickPassFail
+ AcquireTemporaryFileName(char *filename),
+ LiberateTemporaryFile(char *filename);
+
+MagickExport int
+ AcquireTemporaryFileDescriptor(char *filename);
+
+MagickExport FILE *
+ AcquireTemporaryFileStream(char *filename,FileIOMode mode);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+#define ThrowReaderTemporaryFileException(filename) \
+{ \
+ if ((image) == (Image *) NULL) \
+ { \
+ ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile, \
+ filename); \
+ } \
+ else \
+ { \
+ ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile, \
+ filename); \
+ CloseBlob(image); \
+ DestroyImageList(image); \
+ } \
+ return((Image *) NULL); \
+}
+#define ThrowWriterTemporaryFileException(filename) \
+{ \
+ assert(image != (Image *) NULL); \
+ ThrowException(&(image)->exception,FileOpenError, \
+ UnableToCreateTemporaryFile,filename); \
+ if (image_info->adjoin) \
+ while ((image)->previous != (Image *) NULL) \
+ (image)=(image)->previous; \
+ CloseBlob(image); \
+ return(False); \
+}
+
+MagickExport void
+ DestroyTemporaryFiles(void),
+ PurgeTemporaryFiles(void),
+ PurgeTemporaryFilesAsyncSafe(void);
+
+extern MagickPassFail
+ InitializeTemporaryFiles(void);
+
+#endif /* MAGICK_IMPLEMENTATION */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_TEMPFILE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/texture.c b/magick/texture.c
new file mode 100644
index 0000000..e5f3298
--- /dev/null
+++ b/magick/texture.c
@@ -0,0 +1,348 @@
+/*
+% Copyright (C) 2003 - 2009 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+% GraphicsMagick Texture Methods.
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/alpha_composite.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/texture.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% C o n s t i t u t e T e x t u r e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ConstituteTextureImage() returns a new image canvas based on repeatedly
+% tiling the texture image across and down the new image canvas. The
+% returned image properties are similar to the texture image properties.
+%
+% The format of the TextureImage method is:
+%
+% Image *ConstituteTextureImage(unsigned long columns,unsigned long rows,
+% const Image *texture, ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o columns: The number of columns in the new image.
+%
+% o rows: The number of rows in the new image.
+%
+% o texture: The texture image to layer on the background.
+%
+% o exceptions: Any errors are reported here.
+%
+*/
+#define ConstituteTextureImageText "[%s] Generate texture... "
+MagickExport Image *ConstituteTextureImage(const unsigned long columns,
+ const unsigned long rows,
+ const Image *texture_image,
+ ExceptionInfo *exception)
+{
+ Image
+ *canvas_image;
+
+ long
+ y;
+
+ unsigned long
+ row_count=0;
+
+ MagickPassFail
+ status=MagickPass;
+
+ assert(texture_image != (Image *) NULL);
+ assert(texture_image->signature == MagickSignature);
+
+ canvas_image=CloneImage(texture_image,columns,rows,MagickTrue,exception);
+ if (canvas_image == (Image *) NULL)
+ return canvas_image;
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,16) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) canvas_image->rows; y++)
+ {
+ const PixelPacket
+ *texture_pixels;
+
+ PixelPacket
+ *canvas_pixels;
+
+ unsigned long
+ x;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ConstituteTextureImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ texture_pixels=AcquireImagePixels(texture_image,0,
+ y % texture_image->rows,
+ texture_image->columns,1,
+ exception);
+ canvas_pixels=SetImagePixelsEx(canvas_image,0,y,canvas_image->columns,
+ 1,exception);
+
+ if ((texture_pixels == (const PixelPacket *) NULL) ||
+ (canvas_pixels == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ const IndexPacket
+ *texture_indexes=(const IndexPacket *) NULL;
+
+ IndexPacket
+ *canvas_indexes=(IndexPacket *) NULL;;
+
+ if (texture_image->storage_class == PseudoClass)
+ texture_indexes=AccessImmutableIndexes(texture_image);
+ if (canvas_image->storage_class == PseudoClass)
+ canvas_indexes=AccessMutableIndexes(canvas_image);
+
+ for (x=0; x < canvas_image->columns; x+=texture_image->columns)
+ {
+ unsigned long
+ texture_width;
+
+ texture_width=texture_image->columns;
+ if ((x+texture_width) > canvas_image->columns)
+ texture_width=canvas_image->columns-x;
+
+ if ((texture_indexes != (const IndexPacket *) NULL) &&
+ (canvas_indexes != (const IndexPacket *) NULL))
+ {
+ (void) memcpy(canvas_indexes,texture_indexes,texture_width*sizeof(IndexPacket));
+ canvas_indexes += texture_width;
+ }
+ (void) memcpy(canvas_pixels,texture_pixels,texture_width*sizeof(PixelPacket));
+ canvas_pixels += texture_width;
+ }
+
+ if (!SyncImagePixelsEx(canvas_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ConstituteTextureImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,canvas_image->rows))
+ if (!MagickMonitorFormatted(row_count,canvas_image->rows,exception,
+ ConstituteTextureImageText,
+ texture_image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ if (status == MagickFail)
+ {
+ DestroyImage(canvas_image);
+ canvas_image=(Image *) NULL;
+ }
+
+ if (canvas_image != (Image *) NULL)
+ {
+ canvas_image->is_monochrome=texture_image->is_monochrome;
+ canvas_image->is_grayscale=texture_image->is_grayscale;
+ }
+
+ return canvas_image;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% T e x t u r e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TextureImage() repeatedly tiles the texture image across and down the image
+% canvas. If the image canvas includes a matte channel, then the tile is
+% alpha-composited "under" the image and the matte channel is removed.
+% MagickFail is returned if an error is encountered.
+%
+% The format of the TextureImage method is:
+%
+% MagickPassFail TextureImage(Image *image,const Image *texture)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o texture: This image is the texture to layer on the background.
+%
+%
+*/
+
+#define TextureImageText "[%s] Apply texture..."
+MagickExport MagickPassFail TextureImage(Image *image,const Image *texture)
+{
+ MagickPassFail
+ status=MagickPass;
+
+ long
+ y;
+
+ unsigned long
+ row_count=0;
+
+ MagickBool
+ get_pixels,
+ is_grayscale;
+
+ /*
+ Tile texture onto the image background.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (texture == (const Image *) NULL)
+ return MagickFail;
+
+ get_pixels=GetPixelCachePresent(image);
+ is_grayscale=image->is_grayscale;
+ image->storage_class=DirectClass;
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) image->rows; y++)
+ {
+ const PixelPacket
+ *pixels;
+
+ long
+ x;
+
+ register long
+ z;
+
+ register const PixelPacket
+ *p;
+
+ register PixelPacket
+ *q;
+
+ unsigned long
+ width;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_TextureImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(texture,0,y % texture->rows,
+ texture->columns,1,&image->exception);
+ if (get_pixels)
+ q=GetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+ else
+ q=SetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
+
+ if ((p == (const PixelPacket *) NULL) ||
+ (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ pixels=p;
+ for (x=0; x < (long) image->columns; x+=texture->columns)
+ {
+ width=texture->columns;
+ if ((x+width) > image->columns)
+ width=image->columns-x;
+ p=pixels;
+ if (image->matte)
+ {
+ for (z=(long) width; z != 0; z--)
+ {
+ AlphaCompositePixel(q,q,q->opacity,p,texture->matte != MagickFalse ?
+ p->opacity : OpaqueOpacity);
+ p++;
+ q++;
+ }
+ }
+ else
+ {
+ if (width*sizeof(PixelPacket) < 1024)
+ {
+ for (z=(long) width; z != 0; z--)
+ {
+ *q=(*p);
+ p++;
+ q++;
+ }
+ }
+ else
+ {
+ (void) memcpy(q,p,width*sizeof(PixelPacket));
+ q += width;
+ }
+ }
+ }
+ if (!SyncImagePixelsEx(image,&image->exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_TextureImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,image->rows))
+ if (!MagickMonitorFormatted(row_count,image->rows,&image->exception,
+ TextureImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+
+ if (image->matte)
+ image->is_grayscale=(is_grayscale && texture->is_grayscale);
+ else
+ image->is_grayscale=texture->is_grayscale;
+ if (image->matte)
+ image->matte=MagickFalse;
+ else
+ image->matte=texture->matte;
+ return (status);
+}
diff --git a/magick/texture.h b/magick/texture.h
new file mode 100644
index 0000000..804c517
--- /dev/null
+++ b/magick/texture.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Texture Methods.
+*/
+#ifndef _MAGICK_TEXTURE_H
+#define _MAGICK_TEXTURE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Include declarations.
+*/
+#include "magick/image.h"
+#include "magick/error.h"
+
+extern MagickExport Image
+ *ConstituteTextureImage(const unsigned long columns,const unsigned long rows,
+ const Image *texture,ExceptionInfo *exception);
+
+extern MagickExport MagickPassFail
+ TextureImage(Image *,const Image *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_TEXTURE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/timer.c b/magick/timer.c
new file mode 100644
index 0000000..719522d
--- /dev/null
+++ b/magick/timer.c
@@ -0,0 +1,439 @@
+/*
+% Copyright (C) 2003,2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT IIIII M M EEEEE RRRR %
+% T I MM MM E R R %
+% T I M M M EEE RRRR %
+% T I M M E R R %
+% T IIIII M M EEEEE R R %
+% %
+% %
+% GraphicsMagick Timing Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% January 1993 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Contributed by Bill Radcliffe and Bob Friesenhahn.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+
+/*
+ Define declarations.
+*/
+#if !defined(CLK_TCK)
+# define CLK_TCK sysconf(_SC_CLK_TCK)
+#endif
+#if defined(HAVE_CLOCK_GETTIME)
+# define NANOSECONDS_PER_SECOND 1000000000.0
+# if defined(CLOCK_HIGHRES) /* Solaris */
+# define CLOCK_ID CLOCK_HIGHRES
+# elif defined(CLOCK_MONOTONIC_RAW) /* Linux */
+# define CLOCK_ID CLOCK_MONOTONIC_RAW
+# elif defined(CLOCK_MONOTONIC_PRECISE) /* FreeBSD */
+# define CLOCK_ID CLOCK_MONOTONIC_PRECISE
+# elif defined(CLOCK_MONOTONIC) /* Linux & FreeBSD */
+# define CLOCK_ID CLOCK_MONOTONIC
+# else
+# define CLOCK_ID CLOCK_REALTIME /* Fallback */
+# endif
+#endif
+
+/*
+ Forward declarations.
+*/
+static double
+ UserTime(void);
+
+static void
+ StartTimer(TimerInfo *,const unsigned int),
+ StopTimer(TimerInfo *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o n t i n u e T i m e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ContinueTimer resumes a stopped stopwatch. The stopwatch continues
+% counting from the last StartTimer() onwards.
+%
+% The format of the ContinueTimer method is:
+%
+% unsigned int ContinueTimer(TimerInfo *time_info)
+%
+% A description of each parameter follows.
+%
+% o time_info: Time statistics structure.
+%
+*/
+MagickExport unsigned int ContinueTimer(TimerInfo *time_info)
+{
+ assert(time_info != (TimerInfo *) NULL);
+ assert(time_info->signature == MagickSignature);
+ if (time_info->state == UndefinedTimerState)
+ return(False);
+ if (time_info->state == StoppedTimerState)
+ {
+ time_info->user.total-=time_info->user.stop-time_info->user.start;
+ time_info->elapsed.total-=
+ time_info->elapsed.stop-time_info->elapsed.start;
+ }
+ time_info->state=RunningTimerState;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ E l a p s e d T i m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ElapsedTime returns the elapsed time (in seconds) since the last
+% call to StartTimer().
+%
+% The format of the ElapsedTime method is:
+%
+% double ElapsedTime()
+%
+*/
+static double ElapsedTime(void)
+{
+#if defined(HAVE_CLOCK_GETTIME)
+ struct timespec timer;
+ (void) clock_gettime(CLOCK_ID, &timer);
+
+ return((double) timer.tv_sec + timer.tv_nsec/NANOSECONDS_PER_SECOND);
+#elif defined(HAVE_TIMES)
+ struct tms
+ timer;
+
+ return((double) times(&timer)/CLK_TCK);
+#else
+#if defined(MSWINDOWS)
+ return(NTElapsedTime());
+#else
+ return((double) clock()/CLK_TCK);
+#endif
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t E l a p s e d T i m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetElapsedTime returns the elapsed time (in seconds) passed between
+% the start and stop events. If the stopwatch is still running, it is stopped
+% first.
+%
+% The format of the GetElapsedTime method is:
+%
+% double GetElapsedTime(TimerInfo *time_info)
+%
+% A description of each parameter follows.
+%
+% o time_info: Timer statistics structure.
+%
+*/
+MagickExport double GetElapsedTime(TimerInfo *time_info)
+{
+ assert(time_info != (TimerInfo *) NULL);
+ assert(time_info->signature == MagickSignature);
+ if (time_info->state == UndefinedTimerState)
+ return(0.0);
+ if (time_info->state == RunningTimerState)
+ StopTimer(time_info);
+ return(time_info->elapsed.total);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t T i m e r I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetTimerInfo initializes the TimerInfo structure.
+%
+% The format of the GetTimerInfo method is:
+%
+% void GetTimerInfo(TimerInfo *time_info)
+%
+% A description of each parameter follows.
+%
+% o time_info: Timer statistics structure.
+%
+*/
+MagickExport void GetTimerInfo(TimerInfo *time_info)
+{
+ /*
+ Create a stopwatch and start it.
+ */
+ assert(time_info != (TimerInfo *) NULL);
+ (void) memset(time_info,0,sizeof(TimerInfo));
+ time_info->state=UndefinedTimerState;
+ time_info->signature=MagickSignature;
+ StartTimer(time_info,True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t T i m e r R e s o l u t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Obtain the measurement resolution of the timer.
+%
+% The format of the GetTimerResolution method is:
+%
+% void GetTimerInfo(TimerInfo *time_info)
+%
+% A description of each parameter follows.
+%
+% o time_info: Timer statistics structure.
+%
+*/
+MagickExport double GetTimerResolution(void)
+{
+#if defined(HAVE_CLOCK_GETRES)
+ struct timespec timer;
+ (void) clock_getres(CLOCK_ID, &timer);
+
+ return((double) timer.tv_sec + (double) timer.tv_nsec/NANOSECONDS_PER_SECOND);
+#elif defined(MSWINDOWS)
+ return (0.02);
+#else
+ return (1.0/CLK_TCK);
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t U s e r T i m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetUserTime returns the User time (user and system) by the operating
+% system (in seconds) between the start and stop events. If the stopwatch is
+% still running, it is stopped first.
+%
+% The format of the GetUserTime method is:
+%
+% double GetUserTime(TimerInfo *time_info)
+%
+% A description of each parameter follows.
+%
+% o time_info: Timer statistics structure.
+%
+*/
+MagickExport double GetUserTime(TimerInfo *time_info)
+{
+ assert(time_info != (TimerInfo *) NULL);
+ assert(time_info->signature == MagickSignature);
+ if (time_info->state == UndefinedTimerState)
+ return(0.0);
+ if (time_info->state == RunningTimerState)
+ StopTimer(time_info);
+ return(time_info->user.total);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e s e t T i m e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ResetTimer resets the stopwatch.
+%
+% The format of the ResetTimer method is:
+%
+% void ResetTimer(TimerInfo *time_info)
+%
+% A description of each parameter follows.
+%
+% o time_info: Timer statistics structure.
+%
+*/
+MagickExport void ResetTimer(TimerInfo *time_info)
+{
+ assert(time_info != (TimerInfo *) NULL);
+ assert(time_info->signature == MagickSignature);
+ StopTimer(time_info);
+ time_info->elapsed.stop=0.0;
+ time_info->user.stop=0.0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S t a r t T i m e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method StartTimer starts the stopwatch.
+%
+% The format of the StartTimer method is:
+%
+% void StartTimer(TimerInfo *time_info,const unsigned int reset)
+%
+% A description of each parameter follows.
+%
+% o time_info: Timer statistics structure.
+%
+% o reset: If reset is True, then the stopwatch is reset prior to starting.
+% If reset is False, then timing is continued without resetting the
+% stopwatch.
+%
+*/
+static void StartTimer(TimerInfo *time_info,const unsigned int reset)
+{
+ assert(time_info != (TimerInfo *) NULL);
+ assert(time_info->signature == MagickSignature);
+ if (reset)
+ {
+ /*
+ Reset the stopwatch before starting it.
+ */
+ time_info->user.total=0.0;
+ time_info->elapsed.total=0.0;
+ }
+ if (time_info->state != RunningTimerState)
+ {
+ time_info->elapsed.start=ElapsedTime();
+ time_info->user.start=UserTime();
+ }
+ time_info->state=RunningTimerState;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S t o p T i m e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method StopTimer stops the stopwatch.
+%
+% The format of the StopTimer method is:
+%
+% void StopTimer(TimerInfo *time_info)
+%
+% A description of each parameter follows.
+%
+% o time_info: Timer statistics structure.
+%
+*/
+static void StopTimer(TimerInfo *time_info)
+{
+ assert(time_info != (TimerInfo *) NULL);
+ assert(time_info->signature == MagickSignature);
+ time_info->elapsed.stop=ElapsedTime();
+ time_info->user.stop=UserTime();
+ if (time_info->state == RunningTimerState)
+ {
+ time_info->user.total+=
+ time_info->user.stop-time_info->user.start+MagickEpsilon;
+ time_info->elapsed.total+=
+ time_info->elapsed.stop-time_info->elapsed.start+MagickEpsilon;
+ }
+ time_info->state=StoppedTimerState;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ U s e r T i m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method UserTime returns the total time the process has been scheduled (in
+% seconds) since the last call to StartTimer().
+%
+% The format of the UserTime method is:
+%
+% double UserTime()
+%
+*/
+static double UserTime(void)
+{
+#if defined(HAVE_TIMES)
+ struct tms
+ timer;
+
+ (void) times(&timer);
+ return((double) (timer.tms_utime+timer.tms_stime)/CLK_TCK);
+#else
+#if defined(MSWINDOWS)
+ return(NTUserTime());
+#else
+ return((double) clock()/CLK_TCK);
+#endif
+#endif
+}
diff --git a/magick/timer.h b/magick/timer.h
new file mode 100644
index 0000000..3dd42c2
--- /dev/null
+++ b/magick/timer.h
@@ -0,0 +1,79 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Timer Methods.
+*/
+#ifndef _MAGICK_TIMER_H
+#define _MAGICK_TIMER_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ UndefinedTimerState,
+ StoppedTimerState,
+ RunningTimerState
+} TimerState;
+
+/*
+ Typedef declarations.
+*/
+typedef struct _Timer
+{
+ double
+ start,
+ stop,
+ total;
+} Timer;
+
+typedef struct _TimerInfo
+{
+ Timer
+ user,
+ elapsed;
+
+ TimerState
+ state;
+
+ unsigned long
+ signature;
+} TimerInfo;
+
+/*
+ Timer methods.
+*/
+extern MagickExport double
+ GetElapsedTime(TimerInfo *),
+ GetUserTime(TimerInfo *),
+ GetTimerResolution(void);
+
+extern MagickExport unsigned int
+ ContinueTimer(TimerInfo *);
+
+extern MagickExport void
+ GetTimerInfo(TimerInfo *),
+ ResetTimer(TimerInfo *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/transform.c b/magick/transform.c
new file mode 100644
index 0000000..04d1c20
--- /dev/null
+++ b/magick/transform.c
@@ -0,0 +1,1675 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT RRRR AAA N N SSSSS FFFFF OOO RRRR M M %
+% T R R A A NN N SS F O O R R MM MM %
+% T RRRR AAAAA N N N SSS FFF O O RRRR M M M %
+% T R R A A N NN SS F O O R R M M %
+% T R R A A N N SSSSS F OOO R R M M %
+% %
+% %
+% GraphicsMagick Image Transform Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/color.h"
+#include "magick/composite.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/resize.h"
+#include "magick/texture.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#include "magick/log.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C h o p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Chop() removes a region of an image and collapses the image to occupy the
+% removed portion.
+%
+% The format of the ChopImage method is:
+%
+% Image *ChopImage(const Image *image,const RectangleInfo *chop_info
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o chop_info: Define the region of the image to chop.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *ChopImage(const Image *image,const RectangleInfo *chop_info,
+ ExceptionInfo *exception)
+{
+#define ChopImageText "[%s] Chop..."
+
+ Image
+ *chop_image;
+
+ unsigned long
+ row_count=0;
+
+ long
+ y;
+
+ RectangleInfo
+ clone_info;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Check chop geometry.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ assert(chop_info != (RectangleInfo *) NULL);
+ if (((chop_info->x+(long) chop_info->width) < 0) ||
+ ((chop_info->y+(long) chop_info->height) < 0) ||
+ (chop_info->x > (long) image->columns) ||
+ (chop_info->y > (long) image->rows))
+ ThrowImageException3(OptionError,GeometryDoesNotContainImage,
+ UnableToChopImage);
+ clone_info=(*chop_info);
+ if ((clone_info.x+(long) clone_info.width) > (long) image->columns)
+ clone_info.width=(unsigned long) ((long) image->columns-clone_info.x);
+ if ((clone_info.y+(long) clone_info.height) > (long) image->rows)
+ clone_info.height=(unsigned long) ((long) image->rows-clone_info.y);
+ if (clone_info.x < 0)
+ {
+ clone_info.width-=(unsigned long) (-clone_info.x);
+ clone_info.x=0;
+ }
+ if (clone_info.y < 0)
+ {
+ clone_info.height-=(unsigned long) (-clone_info.y);
+ clone_info.y=0;
+ }
+ /*
+ Initialize chop image attributes.
+ */
+ chop_image=CloneImage(image,image->columns-clone_info.width,
+ image->rows-clone_info.height,False,exception);
+ if (chop_image == (Image *) NULL)
+ return((Image *) NULL);
+
+ /*
+ Extract chop image.
+ */
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) clone_info.y; y++)
+ {
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register IndexPacket
+ *chop_indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ChopImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ q=SetImagePixelsEx(chop_image,0,y,chop_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ indexes=AccessImmutableIndexes(image);
+ chop_indexes=AccessMutableIndexes(chop_image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((x < clone_info.x) || (x >= (long) (clone_info.x+clone_info.width)))
+ {
+ if ((indexes != (const IndexPacket *) NULL) &&
+ (chop_indexes != (IndexPacket *) NULL))
+ *chop_indexes++=indexes[x];
+ *q=(*p);
+ q++;
+ }
+ p++;
+ }
+ if (!SyncImagePixelsEx(chop_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ChopImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,chop_image->rows))
+ if (!MagickMonitorFormatted(row_count,chop_image->rows,exception,
+ ChopImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ /*
+ Extract chop image.
+ */
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) (image->rows-(clone_info.y+clone_info.height)); y++)
+ {
+ register const PixelPacket
+ *p;
+
+ register const IndexPacket
+ *indexes;
+
+ register IndexPacket
+ *chop_indexes;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ChopImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,0,clone_info.y+clone_info.height+y,image->columns,1,exception);
+ q=SetImagePixelsEx(chop_image,0,clone_info.y+y,chop_image->columns,1,exception);
+ if ((p == (PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ indexes=AccessImmutableIndexes(image);
+ chop_indexes=AccessMutableIndexes(chop_image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ if ((x < clone_info.x) || (x >= (long) (clone_info.x+clone_info.width)))
+ {
+ if ((indexes != (const IndexPacket *) NULL) &&
+ (chop_indexes != (IndexPacket *) NULL))
+ *chop_indexes++=indexes[x];
+ *q=(*p);
+ q++;
+ }
+ p++;
+ }
+ if (!SyncImagePixelsEx(chop_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_ChopImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,chop_image->rows))
+ if (!MagickMonitorFormatted(row_count,chop_image->rows,exception,
+ ChopImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ if (row_count < chop_image->rows)
+ {
+ DestroyImage(chop_image);
+ return((Image *) NULL);
+ }
+ chop_image->is_grayscale=image->is_grayscale;
+ return(chop_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o a l e s c e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CoalesceImages() composites a set of images while respecting any page
+% offsets and disposal methods. GIF, MIFF, and MNG animation sequences
+% typically start with an image background and each subsequent image
+% varies in size and offset. CoalesceImages() returns a new sequence
+% where each image in the sequence is the same size as the first and
+% composited with the next image in the sequence.
+%
+% The format of the CoalesceImages method is:
+%
+% Image *CoalesceImages(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image sequence.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport Image *CoalesceImages(const Image *image,ExceptionInfo *exception)
+{
+ Image
+ *coalesce_image,
+ *previous_image;
+
+ register const Image
+ *next;
+
+ register long
+ i;
+
+ MagickBool
+ found_transparency=False;
+
+ /*
+ Coalesce the image sequence.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if (image->next == (Image *) NULL)
+ ThrowImageException3(ImageError,ImageSequenceIsRequired,
+ UnableToCoalesceImage);
+ /*
+ Clone first image in sequence.
+ */
+ coalesce_image=CloneImage(image,0,0,True,exception);
+ if (coalesce_image == (Image *) NULL)
+ return((Image *) NULL);
+ (void) memset(&coalesce_image->page,0,sizeof(RectangleInfo));
+ previous_image=coalesce_image;
+ /*
+ Coalesce image.
+ */
+ for (next=image->next; next != (Image *) NULL; next=next->next)
+ {
+ switch (next->dispose)
+ {
+ case UndefinedDispose:
+ case NoneDispose:
+ {
+ coalesce_image->next=CloneImage(coalesce_image,0,0,True,exception);
+ if (coalesce_image->next != (Image *) NULL)
+ previous_image=coalesce_image->next;
+ break;
+ }
+ case BackgroundDispose:
+ {
+ /*
+ Fill image with transparent color, if one exists.
+ */
+ coalesce_image->next=CloneImage(coalesce_image,0,0,True,exception);
+ if (coalesce_image->next != (Image *) NULL) {
+ for (i = 0; i < (long) coalesce_image->colors; i++) {
+ if (coalesce_image->colormap[i].opacity == TransparentOpacity) {
+ found_transparency = True;
+ (void) SetImageColor(coalesce_image->next,&coalesce_image->colormap[i]);
+ break;
+ }
+ }
+ if (!found_transparency)
+ (void) SetImage(coalesce_image->next,OpaqueOpacity);
+ }
+ break;
+ }
+ case PreviousDispose:
+ default:
+ {
+ coalesce_image->next=CloneImage(previous_image,0,0,True,exception);
+ break;
+ }
+ }
+ if (coalesce_image->next == (Image *) NULL)
+ {
+ DestroyImageList(coalesce_image);
+ return((Image *) NULL);
+ }
+ coalesce_image->next->previous=coalesce_image;
+ coalesce_image=coalesce_image->next;
+ coalesce_image->delay=next->delay;
+ coalesce_image->start_loop=next->start_loop;
+ (void) CompositeImage(coalesce_image,next->matte ? OverCompositeOp :
+ CopyCompositeOp,next,next->page.x,next->page.y);
+ }
+
+ while (coalesce_image->previous != (Image *) NULL)
+ coalesce_image=coalesce_image->previous;
+ return(coalesce_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C r o p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use CropImage() to extract a region of the image starting at the offset
+% defined by geometry. As a special feature, if the geometry "0x0" is
+% is passed, GetImageBoundingBox() is used to locate the edges of the
+% image and the image is cropped ("trimmed") to that boundary.
+%
+% The format of the CropImage method is:
+%
+% Image *CropImage(const Image *image,const RectangleInfo *geometry,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o geometry: Define the region of the image to crop with members
+% x, y, width, and height.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *CropImage(const Image *image,const RectangleInfo *geometry,
+ ExceptionInfo *exception)
+{
+ Image
+ *crop_image;
+
+ unsigned long
+ row_count=0;
+
+ long
+ y;
+
+ RectangleInfo
+ page;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Check crop geometry.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(geometry != (const RectangleInfo *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if ((geometry->width != 0) || (geometry->height != 0))
+ {
+ if (((geometry->x+(long) geometry->width) < 0) ||
+ ((geometry->y+(long) geometry->height) < 0) ||
+ (geometry->x >= (long) image->columns) ||
+ (geometry->y >= (long) image->rows))
+ ThrowImageException(OptionError,GeometryDoesNotContainImage,
+ MagickMsg(ResourceLimitError,UnableToCropImage));
+ }
+ page=(*geometry);
+ if ((page.width != 0) || (page.height != 0))
+ {
+ if ((page.x+(long) page.width) > (long) image->columns)
+ page.width=image->columns-page.x;
+ if ((page.y+(long) page.height) > (long) image->rows)
+ page.height=image->rows-page.y;
+ if (page.x < 0)
+ {
+ page.width+=page.x;
+ page.x=0;
+ }
+ if (page.y < 0)
+ {
+ page.height+=page.y;
+ page.y=0;
+ }
+ }
+ else
+ {
+ /*
+ Set bounding box to the image dimensions.
+ */
+ page=GetImageBoundingBox(image,exception);
+ page.width+=geometry->x*2;
+ page.height+=geometry->y*2;
+ page.x-=geometry->x;
+ if (page.x < 0)
+ page.x=0;
+ page.y-=geometry->y;
+ if (page.y < 0)
+ page.y=0;
+ if ((((long) page.width+page.x) > (long) image->columns) ||
+ (((long) page.height+page.y) > (long) image->rows))
+ ThrowImageException(OptionError,GeometryDoesNotContainImage,
+ MagickMsg(ResourceLimitError,UnableToCropImage));
+ }
+ if ((page.width == 0) || (page.height == 0))
+ ThrowImageException(OptionError,GeometryDimensionsAreZero,
+ MagickMsg(ResourceLimitError,UnableToCropImage));
+ if ((page.width == image->columns) && (page.height == image->rows) &&
+ (page.x == 0) && (page.y == 0))
+ return(CloneImage(image,0,0,True,exception));
+ /*
+ Initialize crop image attributes.
+ */
+ crop_image=CloneImage(image,page.width,page.height,True,exception);
+ if (crop_image == (Image *) NULL)
+ return((Image *) NULL);
+ /*
+ Extract crop image.
+ */
+ crop_image->page=page;
+ if ((geometry->width == 0) || (geometry->height == 0))
+ (void) memset(&crop_image->page,0,sizeof(RectangleInfo));
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) crop_image->rows; y++)
+ {
+ const PixelPacket
+ *p;
+
+ const IndexPacket
+ *indexes;
+
+ IndexPacket
+ *crop_indexes;
+
+ PixelPacket
+ *q;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_CropImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,page.x,page.y+y,crop_image->columns,1,exception);
+ q=SetImagePixelsEx(crop_image,0,y,crop_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ (void) memcpy(q,p,crop_image->columns*sizeof(PixelPacket));
+ indexes=AccessImmutableIndexes(image);
+ crop_indexes=AccessMutableIndexes(crop_image);
+ if ((indexes != (const IndexPacket *) NULL) &&
+ (crop_indexes != (IndexPacket *) NULL))
+ (void) memcpy(crop_indexes,indexes,crop_image->columns*
+ sizeof(IndexPacket));
+ if (!SyncImagePixelsEx(crop_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_CropImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,crop_image->rows))
+ if (!MagickMonitorFormatted(row_count,crop_image->rows,exception,
+ "[%s] Crop: %lux%lu+%ld+%ld...",
+ crop_image->filename,
+ crop_image->columns,crop_image->rows,
+ page.x,page.y))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ if (row_count < crop_image->rows)
+ {
+ DestroyImage(crop_image);
+ return((Image *) NULL);
+ }
+ crop_image->is_grayscale=image->is_grayscale;
+ return(crop_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e c o n s t r u c t I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DeconstructImages() compares each image with the next in a sequence and
+% returns the maximum bounding region of any pixel differences it discovers.
+%
+% The format of the DeconstructImages method is:
+%
+% Image *DeconstructImages(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *DeconstructImages(const Image *image,
+ ExceptionInfo *exception)
+{
+ Image
+ *crop_image,
+ *crop_next,
+ *deconstruct_image;
+
+ long
+ y;
+
+ RectangleInfo
+ *bounds;
+
+ register const Image
+ *next;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ i,
+ x;
+
+ register PixelPacket
+ *q;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ if (image->next == (Image *) NULL)
+ ThrowImageException3(ImageError,ImageSequenceIsRequired,
+ UnableToDeconstructImageSequence);
+ /*
+ Ensure the image are the same size.
+ */
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ if ((next->columns != image->columns) || (next->rows != image->rows))
+ ThrowImageException(OptionError,ImagesAreNotTheSameSize,
+ MagickMsg(ImageError,UnableToDeconstructImageSequence));
+ }
+ /*
+ Allocate memory.
+ */
+ bounds=MagickAllocateMemory(RectangleInfo *,
+ GetImageListLength(image)*sizeof(RectangleInfo));
+ if (bounds == (RectangleInfo *) NULL)
+ ThrowImageException(ResourceLimitError,MemoryAllocationFailed,
+ MagickMsg(ImageError,UnableToDeconstructImageSequence));
+ /*
+ Compute the bounding box for each next in the sequence.
+ */
+ i=0;
+ for (next=image->next; next != (const Image *) NULL; next=next->next)
+ {
+ /*
+ Set bounding box to the next dimensions.
+ */
+ for (x=0; x < (long) next->columns; x++)
+ {
+ p=AcquireImagePixels(next,x,0,1,next->rows,exception);
+ q=GetImagePixels(next->previous,x,0,1,next->previous->rows);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ break;
+ for (y=0; y < (long) next->rows; y++)
+ {
+ if (!FuzzyColorMatch(p,q,next->fuzz))
+ break;
+ p++;
+ q++;
+ }
+ if (y < (long) next->rows)
+ break;
+ }
+ bounds[i].x=x;
+ for (y=0; y < (long) next->rows; y++)
+ {
+ p=AcquireImagePixels(next,0,y,next->columns,1,exception);
+ q=GetImagePixels(next->previous,0,y,next->previous->columns,1);
+ if ((p == (PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ break;
+ for (x=0; x < (long) next->columns; x++)
+ {
+ if (!FuzzyColorMatch(p,q,next->fuzz))
+ break;
+ p++;
+ q++;
+ }
+ if (x < (long) next->columns)
+ break;
+ }
+ bounds[i].y=y;
+ for (x=(long) next->columns-1; x >= 0; x--)
+ {
+ p=AcquireImagePixels(next,x,0,1,next->rows,exception);
+ q=GetImagePixels(next->previous,x,0,1,next->previous->rows);
+ if ((p == (PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ break;
+ for (y=0; y < (long) next->rows; y++)
+ {
+ if (!FuzzyColorMatch(p,q,next->fuzz))
+ break;
+ p++;
+ q++;
+ }
+ if (y < (long) next->rows)
+ break;
+ }
+ bounds[i].width=x-bounds[i].x+1;
+ for (y=(long) next->rows-1; y >= 0; y--)
+ {
+ p=AcquireImagePixels(next,0,y,next->columns,1,exception);
+ q=GetImagePixels(next->previous,0,y,next->previous->columns,1);
+ if ((p == (PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ break;
+ for (x=0; x < (long) next->columns; x++)
+ {
+ if (!FuzzyColorMatch(p,q,next->fuzz))
+ break;
+ p++;
+ q++;
+ }
+ if (x < (long) next->columns)
+ break;
+ }
+ bounds[i].height=y-bounds[i].y+1;
+ i++;
+ }
+ /*
+ Clone first image in sequence.
+ */
+ deconstruct_image=CloneImage(image,0,0,True,exception);
+ if (deconstruct_image == (Image *) NULL)
+ {
+ MagickFreeMemory(bounds);
+ return((Image *) NULL);
+ }
+ /*
+ Deconstruct the image sequence.
+ */
+ i=0;
+ for (next=image->next; next != (Image *) NULL; next=next->next)
+ {
+ crop_image=CloneImage(next,0,0,True,exception);
+ if (crop_image == (Image *) NULL)
+ break;
+ crop_next=CropImage(crop_image,&bounds[i++],exception);
+ DestroyImage(crop_image);
+ if (crop_next == (Image *) NULL)
+ break;
+ deconstruct_image->next=crop_next;
+ crop_next->previous=deconstruct_image;
+ deconstruct_image=deconstruct_image->next;
+ }
+ MagickFreeMemory(bounds);
+ while (deconstruct_image->previous != (Image *) NULL)
+ deconstruct_image=deconstruct_image->previous;
+ if (next != (Image *) NULL)
+ {
+ DestroyImageList(deconstruct_image);
+ return((Image *) NULL);
+ }
+ return(deconstruct_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x t e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use ExtentImage() to change the image dimensions as specified by geometry
+% width and height. The existing image content is composited at the position
+% specified by geometry x and y using the image compose method. Existing
+% image content which falls outside the bounds of the new image dimensions
+% is discarded.
+%
+% The format of the ExtentImage method is:
+%
+% Image *ExtentImage(const Image *image,const RectangleInfo *geometry,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o geometry: Define the new image dimension with width and height, and
+% the top left coordinate to place the existing image content with
+% x and y.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *ExtentImage(const Image *image,const RectangleInfo *geometry,
+ ExceptionInfo *exception)
+{
+ Image
+ *extent_image;
+
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(geometry != (const RectangleInfo *) NULL);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ /*
+ Allocate canvas image
+ */
+ if ((extent_image=CloneImage(image,geometry->width,geometry->height,
+ MagickTrue,exception)) == (Image *) NULL)
+ return((Image *) NULL);
+
+ /*
+ Set canvas image color to background color
+ */
+ if ((SetImage(extent_image,image->background_color.opacity)) == MagickFail)
+ {
+ CopyException(exception,&extent_image->exception);
+ DestroyImage(extent_image);
+ return((Image *) NULL);
+ }
+
+ /*
+ Composite existing image at position using requested composition
+ operator.
+ */
+ if ((CompositeImage(extent_image,image->compose,image,geometry->x,
+ geometry->y)) == MagickFail)
+ {
+ CopyException(exception,&extent_image->exception);
+ DestroyImage(extent_image);
+ return((Image *) NULL);
+ }
+
+ return(extent_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F l a t t e n I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method FlattenImage merges a sequence of images. This is useful for
+% combining Photoshop layers into a single image.
+%
+% The format of the FlattenImage method is:
+%
+% Image *FlattenImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image sequence.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport Image *FlattenImages(const Image *image,ExceptionInfo *exception)
+{
+ Image
+ *flatten_image;
+
+ register const Image
+ *next;
+
+ /*
+ Flatten the image sequence.
+ */
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ /*
+ Clone first image in sequence to serve as canvas image
+ */
+ flatten_image=CloneImage(image,0,0,True,exception);
+
+ /*
+ Apply background color under image if it has a matte channel.
+ */
+ if ((flatten_image != (Image *) NULL) && (flatten_image->matte))
+ (void) MagickCompositeImageUnderColor(flatten_image,
+ &flatten_image->background_color,
+ exception);
+
+ if ((flatten_image != (Image *) NULL) &&
+ (image->next != (Image *) NULL))
+ {
+ /*
+ Flatten remaining images onto canvas
+ */
+ for (next=image->next; next != (Image *) NULL; next=next->next)
+ (void) CompositeImage(flatten_image,next->compose,next,next->page.x,
+ next->page.y);
+ }
+ return(flatten_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F l i p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FlipImage() creates a vertical mirror image by reflecting the pixels
+% around the central x-axis.
+%
+% The format of the FlipImage method is:
+%
+% Image *FlipImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *FlipImage(const Image *image,ExceptionInfo *exception)
+{
+#define FlipImageText "[%s] Flip..."
+
+ Image
+ *flip_image;
+
+ unsigned long
+ row_count=0;
+
+ long
+ y;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize flip image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ if ((image->columns == 0UL) || (image->rows == 0UL))
+ ThrowImageException(ImageError,UnableToResizeImage,
+ MagickMsg(OptionError,NonzeroWidthAndHeightRequired));
+
+ if (((((size_t) Max(sizeof(PixelPacket),sizeof(IndexPacket)))*image->columns)/
+ image->columns) != Max(sizeof(PixelPacket),sizeof(IndexPacket)))
+ ThrowImageException(ImageError,WidthOrHeightExceedsLimit,image->filename);
+
+ flip_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (flip_image == (Image *) NULL)
+ return((Image *) NULL);
+ /*
+ Flip each row.
+ */
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) flip_image->rows; y++)
+ {
+ const PixelPacket
+ *p;
+
+ const IndexPacket
+ *indexes;
+
+ IndexPacket
+ *flip_indexes;
+
+ PixelPacket
+ *q;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_FlipImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ q=SetImagePixelsEx(flip_image,0,(long) (flip_image->rows-y-1),
+ flip_image->columns,1,exception);
+ if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ (void) memcpy(q,p,flip_image->columns*sizeof(PixelPacket));
+ indexes=AccessImmutableIndexes(image);
+ flip_indexes=AccessMutableIndexes(flip_image);
+ if ((indexes != (IndexPacket *) NULL) &&
+ (flip_indexes != (IndexPacket *) NULL))
+ (void) memcpy(flip_indexes,indexes,image->columns*sizeof(IndexPacket));
+ if (!SyncImagePixelsEx(flip_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_FlipImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,flip_image->rows))
+ if (!MagickMonitorFormatted(row_count,flip_image->rows,exception,
+ FlipImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ if (row_count < flip_image->rows)
+ {
+ DestroyImage(flip_image);
+ return((Image *) NULL);
+ }
+ flip_image->is_grayscale=image->is_grayscale;
+ return(flip_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F l o p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FlopImage() creates a horizontal mirror image by reflecting the pixels
+% around the central y-axis.
+%
+% The format of the FlopImage method is:
+%
+% Image *FlopImage(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *FlopImage(const Image *image,ExceptionInfo *exception)
+{
+#define FlopImageText "[%s] Flop..."
+
+ Image
+ *flop_image;
+
+ unsigned long
+ row_count=0;
+
+ long
+ y;
+
+ MagickPassFail
+ status=MagickPass;
+
+ /*
+ Initialize flop image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ flop_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (flop_image == (Image *) NULL)
+ return((Image *) NULL);
+ /*
+ Flop each row.
+ */
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# if defined(TUNE_OPENMP)
+# pragma omp parallel for schedule(runtime) shared(row_count, status)
+# else
+# pragma omp parallel for schedule(static,4) shared(row_count, status)
+# endif
+#endif
+ for (y=0; y < (long) flop_image->rows; y++)
+ {
+ register const IndexPacket
+ *indexes;
+
+ register IndexPacket
+ *flop_indexes;
+
+ register const PixelPacket
+ *p;
+
+ register long
+ x;
+
+ register PixelPacket
+ *q;
+
+ MagickBool
+ thread_status;
+
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_FlopImage)
+#endif
+ thread_status=status;
+ if (thread_status == MagickFail)
+ continue;
+
+ p=AcquireImagePixels(image,0,y,image->columns,1,exception);
+ q=SetImagePixelsEx(flop_image,0,y,flop_image->columns,1,exception);
+ if ((p == (PixelPacket *) NULL) || (q == (PixelPacket *) NULL))
+ thread_status=MagickFail;
+
+ if (thread_status != MagickFail)
+ {
+ indexes=AccessImmutableIndexes(image);
+ flop_indexes=AccessMutableIndexes(flop_image);
+ q+=flop_image->columns;
+ for (x=0; x < (long) flop_image->columns; x++)
+ {
+ if ((indexes != (const IndexPacket *) NULL) &&
+ (flop_indexes != (IndexPacket *) NULL))
+ flop_indexes[flop_image->columns-x-1]=indexes[x];
+ q--;
+ *q=(*p);
+ p++;
+ }
+ if (!SyncImagePixelsEx(flop_image,exception))
+ thread_status=MagickFail;
+ }
+#if defined(HAVE_OPENMP) && !defined(DisableSlowOpenMP)
+# pragma omp critical (GM_FlopImage)
+#endif
+ {
+ row_count++;
+ if (QuantumTick(row_count,flop_image->rows))
+ if (!MagickMonitorFormatted(row_count,flop_image->rows,exception,
+ FlopImageText,image->filename))
+ thread_status=MagickFail;
+
+ if (thread_status == MagickFail)
+ status=MagickFail;
+ }
+ }
+ if (row_count < flop_image->rows)
+ {
+ DestroyImage(flop_image);
+ return((Image *) NULL);
+ }
+ flop_image->is_grayscale=image->is_grayscale;
+ return(flop_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t I m a g e M o s a i c D i m e n s i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetImageMosaicDimensions returns the bounding region of the canvas
+% which supports the images in the list as would be returned by
+% MosaicImages(). The bounding region is computed based on the image size
+% and page offsets of each image in the image list.
+%
+% The format of the GetImageMosaicDimensions method is:
+%
+% RectangleInfo GetImageMosaicDimensions(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o bounds: Method GetImageMosaicDimensions returns the bounding box of
+% the image canvas.
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static RectangleInfo GetImageMosaicDimensions(const Image *image)
+{
+ RectangleInfo
+ page;
+
+ register const Image
+ *next;
+
+ page.width=image->columns;
+ page.height=image->rows;
+ page.x=0;
+ page.y=0;
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ page.x=next->page.x;
+ page.y=next->page.y;
+ /*
+ Without casts, unsigned underflow can occur here if page offset
+ is negative and has greater magnitude than image size.
+ */
+ if (((long) next->columns+page.x) > (long) page.width)
+ page.width=(long) next->columns+page.x;
+ if (next->page.width > page.width)
+ page.width=next->page.width;
+ if (((long) next->rows+page.y) > (long) page.height)
+ page.height=(long) next->rows+page.y;
+ if (next->page.height > page.height)
+ page.height=next->page.height;
+ }
+
+ return page;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M o s a i c I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MosaicImages() inlays an image sequence to form a single coherent picture.
+% It returns a single image with each image in the sequence composited at
+% the location defined by the page member of the image structure.
+%
+% The format of the MosaicImage method is:
+%
+% Image *MosaicImages(const Image *image,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *MosaicImages(const Image *image,ExceptionInfo *exception)
+{
+#define MosaicImageText "[%s] Create mosaic..."
+
+ Image
+ *mosaic_image;
+
+ RectangleInfo
+ page;
+
+ register const Image
+ *next;
+
+ unsigned int
+ scene;
+
+ MagickBool
+ matte;
+
+ MagickPassFail
+ status;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+
+ /*
+ Determine mosaic bounding box.
+ */
+ page=GetImageMosaicDimensions(image);
+
+ /*
+ Allocate canvas image.
+ */
+ mosaic_image=AllocateImage((ImageInfo *) NULL);
+ if (mosaic_image == (Image *) NULL)
+ return((Image *) NULL);
+ mosaic_image->columns=page.width;
+ mosaic_image->rows=page.height;
+
+ /*
+ Canvas image supports transparency if any subordinate image uses
+ transparency.
+ */
+ matte=MagickTrue;
+ for (next=image; next != (Image *) NULL; next=next->next)
+ matte &= next->matte;
+ mosaic_image->matte=matte;
+
+ /*
+ Canvas color is copied from background color of first image in
+ list. Default canvas color is 'white' but opaque 'black' or
+ 'transparent' is often best for composition.
+ */
+ mosaic_image->background_color=image->background_color;
+ (void) SetImage(mosaic_image,OpaqueOpacity);
+
+ /*
+ Composite mosaic.
+ */
+ scene=0;
+ for (next=image; next != (Image *) NULL; next=next->next)
+ {
+ (void) CompositeImage(mosaic_image,next->compose,next,next->page.x,
+ next->page.y);
+ status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+ exception,MosaicImageText,image->filename);
+ if (status == MagickFail)
+ break;
+ }
+ return(mosaic_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R o l l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RollImage() offsets an image as defined by x_offset and y_offset.
+%
+% The format of the RollImage method is:
+%
+% Image *RollImage(const Image *image,const long x_offset,
+% const long y_offset,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o x_offset: The number of columns to roll in the horizontal direction.
+%
+% o y_offset: The number of rows to roll in the vertical direction.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *RollImage(const Image *image,const long x_offset,
+ const long y_offset,ExceptionInfo *exception)
+{
+ Image
+ *roll_image;
+
+ RectangleInfo
+ offset;
+
+ /*
+ Initialize roll image attributes.
+ */
+ assert(image != (const Image *) NULL);
+ assert(image->signature == MagickSignature);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ roll_image=CloneImage(image,image->columns,image->rows,True,exception);
+ if (roll_image == (Image *) NULL)
+ return((Image *) NULL);
+ /*
+ Roll image.
+ */
+ offset.x=x_offset;
+ offset.y=y_offset;
+ while (offset.x < 0)
+ offset.x+=image->columns;
+ while (offset.x >= (long) image->columns)
+ offset.x-=image->columns;
+ while (offset.y < 0)
+ offset.y+=image->rows;
+ while (offset.y >= (long) image->rows)
+ offset.y-=image->rows;
+
+ /* Top left quadrant */
+ (void) CompositeImageRegion(CopyCompositeOp,0,offset.x,offset.y,image,
+ image->columns-offset.x,image->rows-offset.y,
+ roll_image,0,0,exception);
+
+ /* Top right quadrant */
+ (void) CompositeImageRegion(CopyCompositeOp,0,image->columns-offset.x,offset.y,image,
+ 0,image->rows-offset.y,
+ roll_image,offset.x,0,exception);
+
+ /* Bottom left quadrant */
+ (void) CompositeImageRegion(CopyCompositeOp,0,offset.x,image->rows-offset.y,image,
+ image->columns-offset.x,0,
+ roll_image,0,offset.y,exception);
+
+ /* Bottom right quadrant */
+ (void) CompositeImageRegion(CopyCompositeOp,0,image->columns-offset.x,image->rows-offset.y,image,
+ 0,0,
+ roll_image,offset.x,offset.y,exception);
+
+ roll_image->is_grayscale=image->is_grayscale;
+ return(roll_image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S h a v e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ShaveImage shaves pixels from the image edges. It allocates the
+% memory necessary for the new Image structure and returns a pointer to the
+% new image.
+%
+% The format of the ShaveImage method is:
+%
+% Image *ShaveImage(const Image *image,const RectangleInfo *shave_info,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o shave_image: Method ShaveImage returns a pointer to the shaved
+% image. A null image is returned if there is a memory shortage or
+% if the image width or height is zero.
+%
+% o image: The image.
+%
+% o shave_info: Specifies a pointer to a RectangleInfo which defines the
+% region of the image to shave.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport Image *ShaveImage(const Image *image,
+ const RectangleInfo *shave_info,ExceptionInfo *exception)
+{
+ RectangleInfo
+ geometry;
+
+ if (((2*shave_info->width) >= image->columns) ||
+ ((2*shave_info->height) >= image->rows))
+ ThrowImageException(OptionError,GeometryDoesNotContainImage,
+ MagickMsg(ResourceLimitError,UnableToShaveImage));
+ SetGeometry(image,&geometry);
+ geometry.width-=2*shave_info->width;
+ geometry.height-=2*shave_info->height;
+ geometry.x=(long) shave_info->width;
+ geometry.y=(long) shave_info->height;
+ return(CropImage(image,&geometry,exception));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T r a n s f o r m I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% TransformImage() is a convenience method that behaves like ResizeImage() or
+% CropImage() but accepts scaling and/or cropping information as a region
+% geometry specification. If the operation fails, the original image handle
+% is returned.
+%
+% The format of the TransformImage method is:
+%
+% void TransformImage(Image **image,const char *crop_geometry,
+% const char *image_geometry)
+%
+% A description of each parameter follows:
+%
+% o image: The image The transformed image is returned as this parameter.
+%
+% o crop_geometry: A crop geometry string. This geometry defines a
+% subregion of the image to crop.
+%
+% o image_geometry: An image geometry string. This geometry defines the
+% final size of the image.
+%
+%
+*/
+MagickExport void TransformImage(Image **image,const char *crop_geometry,
+ const char *image_geometry)
+{
+ Image
+ *previous,
+ *resize_image,
+ *transform_image;
+
+ RectangleInfo
+ geometry;
+
+ int
+ flags;
+
+ assert(image != (Image **) NULL);
+ assert((*image)->signature == MagickSignature);
+ transform_image=(*image);
+ if (crop_geometry != (const char *) NULL)
+ {
+ Image
+ *crop_image;
+
+ /*
+ Crop image to a user specified size.
+ */
+ crop_image=(Image *) NULL;
+ flags=GetImageGeometry(transform_image,crop_geometry,False,&geometry);
+ if ((geometry.width == 0) || (geometry.height == 0) ||
+ ((flags & XValue) != 0) || ((flags & YValue) != 0) ||
+ (flags & PercentValue))
+ {
+ crop_image=CropImage(transform_image,&geometry,&(*image)->exception);
+ }
+ else
+ if ((transform_image->columns > geometry.width) ||
+ (transform_image->rows > geometry.height))
+ {
+ Image
+ *next;
+
+ long
+ x,
+ y;
+
+ unsigned long
+ height,
+ width;
+
+ /*
+ Crop repeatedly to create uniform subimages.
+ */
+ width=geometry.width;
+ height=geometry.height;
+ next=(Image *) NULL;
+ for (y=0; y < (long) transform_image->rows; y+=height)
+ {
+ for (x=0; x < (long) transform_image->columns; x+=width)
+ {
+ geometry.width=width;
+ geometry.height=height;
+ geometry.x=x;
+ geometry.y=y;
+ next=CropImage(transform_image,&geometry,&(*image)->exception);
+ if (next == (Image *) NULL)
+ break;
+ if (crop_image == (Image *) NULL)
+ crop_image=next;
+ else
+ {
+ next->previous=crop_image;
+ crop_image->next=next;
+ crop_image=crop_image->next;
+ }
+ }
+ if (next == (Image *) NULL)
+ break;
+ }
+ }
+ if (crop_image != (Image *) NULL)
+ {
+ previous=transform_image->previous;
+ crop_image->next=transform_image->next;
+ DestroyImage(transform_image);
+ transform_image=(Image *) NULL;
+ while (crop_image->previous != (Image *) NULL)
+ crop_image=crop_image->previous;
+ crop_image->previous=previous;
+ transform_image=crop_image;
+ }
+ *image=transform_image;
+ }
+ if (image_geometry == (const char *) NULL)
+ return;
+
+ /*
+ Scale image to a user specified size.
+ */
+ SetGeometry(transform_image,&geometry);
+ flags=GetMagickGeometry(image_geometry,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ if ((transform_image->columns == geometry.width) &&
+ (transform_image->rows == geometry.height))
+ return;
+
+ /*
+ Resize image.
+ */
+ resize_image=ZoomImage(transform_image,geometry.width,geometry.height,
+ &(*image)->exception);
+ if (resize_image == (Image *) NULL)
+ return;
+
+ previous=transform_image->previous;
+ resize_image->next=transform_image->next;
+ DestroyImage(transform_image);
+ transform_image=resize_image;
+ *image=transform_image;
+}
diff --git a/magick/transform.h b/magick/transform.h
new file mode 100644
index 0000000..a7f477f
--- /dev/null
+++ b/magick/transform.h
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2003 - 2010 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ ImageMagick Image Transform Methods.
+*/
+#ifndef _MAGICK_TRANSFORM_H
+#define _MAGICK_TRANSFORM_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+extern MagickExport Image
+ *ChopImage(const Image *image,const RectangleInfo *chop_info,ExceptionInfo *exception),
+ *CoalesceImages(const Image *image,ExceptionInfo *exception),
+ *CropImage(const Image *image,const RectangleInfo *geometry,ExceptionInfo *exception),
+ *DeconstructImages(const Image *image,ExceptionInfo *exception),
+ *ExtentImage(const Image *image,const RectangleInfo *geometry,ExceptionInfo *exception),
+ *FlattenImages(const Image *image,ExceptionInfo *exception),
+ *FlipImage(const Image *image,ExceptionInfo *exception),
+ *FlopImage(const Image *image,ExceptionInfo *exception),
+ *MosaicImages(const Image *image,ExceptionInfo *exception),
+ *RollImage(const Image *image,const long x_offset,const long y_offset,ExceptionInfo *exception),
+ *ShaveImage(const Image *image,const RectangleInfo *shave_info,ExceptionInfo *exception);
+
+extern MagickExport void
+ TransformImage(Image **,const char *,const char *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_TRANSFORM_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/tsd.c b/magick/tsd.c
new file mode 100644
index 0000000..24ed438
--- /dev/null
+++ b/magick/tsd.c
@@ -0,0 +1,154 @@
+/*
+ Copyright (C) 2005,2013,2014 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+*/
+
+/*
+ Thread specific data support.
+
+ The OpenMP case also compiles when OpenMP is not available.
+*/
+
+#include "magick/studio.h"
+#include "magick/utility.h"
+
+#if defined(HAVE_PTHREAD)
+/* Use pthreads TSD APIs */
+# define USE_PTHREAD_TSD 1
+#elif defined(MSWINDOWS)
+/* Use WIN32 TSD APIs */
+# define USE_WIN32_TSD 1
+#else
+/* Use OpenMP APIs or default to single threaded */
+# define USE_OPENMP_TSD 1
+#endif
+
+#if USE_PTHREAD_TSD
+#include <pthread.h>
+#endif /* USE_PTHREAD_TSD */
+#if USE_WIN32_TSD
+# include <windows.h>
+#endif /* USE_WIN32_TSD */
+#include "magick/tsd.h"
+
+#if USE_OPENMP_TSD
+typedef struct _MagickTsdKeyStorage_t
+{
+ void **values;
+ MagickFreeFunc destructor;
+ unsigned int nvalues;
+} MagickTsdKeyStorage_t;
+#endif /* USE_OPENMP_TSD */
+
+/*
+ Create a thread specific data key (with destructor).
+*/
+MagickExport MagickPassFail MagickTsdKeyCreate2(MagickTsdKey_t *key,
+ MagickFreeFunc destructor)
+{
+#if USE_PTHREAD_TSD
+ return ((pthread_key_create(key, destructor) == 0) ? MagickPass : MagickFail);
+#elif USE_WIN32_TSD
+ /* DWORD WINAPI TlsAlloc(void); */
+ ARG_NOT_USED(destructor); /* FIXME: No solution yet */
+ *key=TlsAlloc();
+ return ((*key != TLS_OUT_OF_INDEXES) ? MagickPass : MagickFail);
+#else
+ MagickTsdKeyStorage_t **keyd = (MagickTsdKeyStorage_t **) key;
+ MagickPassFail status = MagickPass;
+ *keyd=MagickAllocateMemory(MagickTsdKeyStorage_t *,sizeof(MagickTsdKeyStorage_t));
+ if (*keyd != (void *) NULL)
+ {
+ (*keyd)->nvalues=omp_get_max_threads();
+ (*keyd)->values=MagickAllocateArray(void *,sizeof(void *),(*keyd)->nvalues);
+ (*keyd)->destructor=destructor;
+ if ((*keyd)->values == (void *) NULL)
+ {
+ MagickFreeMemory(*keyd);
+ }
+ else
+ {
+ (void) memset((*keyd)->values,0,sizeof(void *)*(*keyd)->nvalues);
+ }
+ }
+ status = ((*keyd != (MagickTsdKeyStorage_t *) NULL) ? MagickPass : MagickFail);
+
+ return status;
+#endif
+}
+
+/*
+ Create a thread specific data key.
+*/
+MagickExport MagickPassFail MagickTsdKeyCreate(MagickTsdKey_t *key)
+{
+ return MagickTsdKeyCreate2(key,0);
+}
+
+/*
+ Delete a thread-specific data key, invoking the registered
+ destructor on any remaining non-NULL key values.
+*/
+MagickExport MagickPassFail MagickTsdKeyDelete(MagickTsdKey_t key)
+{
+#if USE_PTHREAD_TSD
+ return ((pthread_key_delete(key) == 0) ? MagickPass : MagickFail);
+#elif USE_WIN32_TSD
+ /* BOOL WINAPI TlsFree(DWORD dwTlsIndex) */
+ return ((TlsFree(key) != 0) ? MagickPass : MagickFail);
+#else
+ MagickTsdKeyStorage_t *keyd = (MagickTsdKeyStorage_t *) key;
+ if (keyd->destructor != (MagickFreeFunc) NULL)
+ {
+ unsigned int index;
+ for (index = 0; index < keyd->nvalues; index++)
+ {
+ if (keyd->values[index] != (void *) NULL)
+ {
+ keyd->destructor(keyd->values[index]);
+ keyd->values[index]=(void *) NULL;
+ }
+ }
+ }
+ MagickFreeMemory(keyd);
+ return MagickPass;
+#endif
+}
+
+/*
+ Set the thread-specific value associated with the key.
+*/
+MagickExport MagickPassFail MagickTsdSetSpecific(MagickTsdKey_t key, const void *value)
+{
+#if USE_PTHREAD_TSD
+ return ((pthread_setspecific(key, value) == 0) ? MagickPass : MagickFail);
+#elif USE_WIN32_TSD
+ /* BOOL WINAPI TlsSetValue(DWORD dwTlsIndex,LPVOID lpTlsValue) */
+ return ((TlsSetValue(key,(void *) value) != 0) ? MagickPass : MagickFail);
+#else
+ MagickTsdKeyStorage_t *keyd = (MagickTsdKeyStorage_t *) key;
+ unsigned int index=omp_get_thread_num();
+ keyd->values[index]=(void *) value;
+ return MagickPass;
+#endif
+}
+
+/*
+ Get the thread-specific value associated with the key.
+*/
+MagickExport void *MagickTsdGetSpecific(MagickTsdKey_t key)
+{
+#if USE_PTHREAD_TSD
+ return (pthread_getspecific(key));
+#elif USE_WIN32_TSD
+ /* LPVOID WINAPI TlsGetValue(DWORD dwTlsIndex) */
+ return TlsGetValue(key);
+#else
+ MagickTsdKeyStorage_t *keyd = (MagickTsdKeyStorage_t *) key;
+ unsigned int index=omp_get_thread_num();
+ return keyd->values[index];
+#endif
+}
diff --git a/magick/tsd.h b/magick/tsd.h
new file mode 100644
index 0000000..559fccf
--- /dev/null
+++ b/magick/tsd.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2005,2012 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+*/
+
+#ifndef _MAGICK_TSD_H
+#define _MAGICK_TSD_H
+
+/*
+ Thread specific data support.
+*/
+
+#if defined(HAVE_PTHREAD)
+typedef pthread_key_t MagickTsdKey_t;
+#elif defined(MSWINDOWS)
+typedef DWORD MagickTsdKey_t;
+#else
+typedef void *MagickTsdKey_t;
+#endif
+
+extern MagickExport MagickPassFail
+ MagickTsdKeyCreate2(MagickTsdKey_t *key,MagickFreeFunc destructor),
+ MagickTsdKeyCreate(MagickTsdKey_t *key),
+ MagickTsdKeyDelete(MagickTsdKey_t key),
+ MagickTsdSetSpecific(MagickTsdKey_t key, const void *value);
+
+extern MagickExport void
+ *MagickTsdGetSpecific(MagickTsdKey_t key);
+
+#endif /* _MAGICK_TSD_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/type.c b/magick/type.c
new file mode 100644
index 0000000..489f8d1
--- /dev/null
+++ b/magick/type.c
@@ -0,0 +1,916 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% TTTTT Y Y PPPP EEEEE %
+% T Y Y P P E %
+% T Y PPPP EEE %
+% T Y P E %
+% T Y P EEEEE %
+% %
+% %
+% GraphicsMagick Image Type Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% May 2001 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+# include "magick/nt_feature.h"
+#endif
+#include "magick/blob.h"
+#include "magick/enum_strings.h"
+#include "magick/log.h"
+#include "magick/render.h"
+#include "magick/semaphore.h"
+#include "magick/type.h"
+#include "magick/utility.h"
+
+/*
+ Define declarations.
+*/
+#define TypeFilename "type.mgk"
+
+/*
+ Declare type map.
+*/
+static char
+ *TypeMap = (char *)
+ "<?xml version=\"1.0\"?>"
+ "<typemap>"
+ " <type stealth=\"True\" />"
+ "</typemap>";
+
+/*
+ Static declarations.
+*/
+static SemaphoreInfo
+ *type_semaphore = (SemaphoreInfo *) NULL;
+
+static TypeInfo
+ *type_list = (TypeInfo *) NULL;
+
+/*
+ Forward declarations.
+*/
+static unsigned int
+ ReadTypeConfigureFile(const char *,const unsigned long,ExceptionInfo *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ D e s t r o y T y p e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method DestroyTypeInfo deallocates memory associated with the font list.
+%
+% The format of the DestroyTypeInfo method is:
+%
+% DestroyTypeInfo(void)
+%
+%
+*/
+MagickExport void DestroyTypeInfo(void)
+{
+ register TypeInfo
+ *p;
+
+ TypeInfo
+ *type_info;
+
+ for (p=type_list; p != (TypeInfo *) NULL; )
+ {
+ type_info=p;
+ p=p->next;
+ if (type_info->path != (char *) NULL)
+ MagickFreeMemory(type_info->path);
+ if (type_info->name != (char *) NULL)
+ MagickFreeMemory(type_info->name);
+ if (type_info->description != (char *) NULL)
+ MagickFreeMemory(type_info->description);
+ if (type_info->family != (char *) NULL)
+ MagickFreeMemory(type_info->family);
+ if (type_info->encoding != (char *) NULL)
+ MagickFreeMemory(type_info->encoding);
+ if (type_info->foundry != (char *) NULL)
+ MagickFreeMemory(type_info->foundry);
+ if (type_info->format != (char *) NULL)
+ MagickFreeMemory(type_info->format);
+ if (type_info->metrics != (char *) NULL)
+ MagickFreeMemory(type_info->metrics);
+ if (type_info->glyphs != (char *) NULL)
+ MagickFreeMemory(type_info->glyphs);
+ MagickFreeMemory(type_info);
+ }
+ type_list=(TypeInfo *) NULL;
+ DestroySemaphoreInfo(&type_semaphore);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t T y p e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetTypeInfo searches the type list for the specified name and if
+% found returns attributes for that type.
+%
+% The format of the GetTypeInfo method is:
+%
+% const TypeInfo *GetTypeInfo(const char *name,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o type_info: Method GetTypeInfo searches the type list for the specified
+% name and if found returns attributes for that type.
+%
+% o name: The type name.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const TypeInfo *GetTypeInfo(const char *name,
+ ExceptionInfo *exception)
+{
+ register TypeInfo
+ *p;
+
+ if (type_list == (TypeInfo *) NULL)
+ {
+ LockSemaphoreInfo(type_semaphore);
+ if (type_list == (TypeInfo *) NULL)
+ {
+ (void) ReadTypeConfigureFile(TypeFilename,0,exception);
+#if defined(MSWINDOWS) || defined(__CYGWIN__)
+ {
+ TypeInfo
+ *type_info;
+
+ type_info=NTGetTypeList();
+ if (type_info != (TypeInfo *) NULL)
+ {
+ if (type_list == (TypeInfo *) NULL)
+ type_list=type_info;
+ else
+ {
+ while (type_list->next != (TypeInfo *) NULL)
+ type_list=type_list->next;
+ type_list->next=type_info;
+ type_info->previous=type_list;
+ while (type_list->previous != (TypeInfo *) NULL)
+ type_list=type_list->previous;
+ }
+ }
+ }
+#endif
+ }
+ UnlockSemaphoreInfo(type_semaphore);
+ }
+ if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
+ return((const TypeInfo *) type_list);
+ /*
+ Search for requested type.
+ */
+ LockSemaphoreInfo(type_semaphore);
+ for (p=type_list; p != (TypeInfo *) NULL; p=p->next)
+ if ((p->name != (char *) NULL) && (LocaleCompare(p->name,name) == 0))
+ break;
+ if (p != (TypeInfo *) NULL)
+ if (p != type_list)
+ {
+ /*
+ Self-adjusting list.
+ */
+ if (p->previous != (TypeInfo *) NULL)
+ p->previous->next=p->next;
+ if (p->next != (TypeInfo *) NULL)
+ p->next->previous=p->previous;
+ p->previous=(TypeInfo *) NULL;
+ p->next=type_list;
+ type_list->previous=p;
+ type_list=p;
+ }
+ UnlockSemaphoreInfo(type_semaphore);
+ return((const TypeInfo *) p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t T y p e I n f o B y F a m i l y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetTypeInfoByFamily searches the type list for the specified family
+% and if found returns attributes for that type.
+%
+% Type substitution and scoring algorithm contributed by Bob Friesenhahn.
+%
+% The format of the GetTypeInfoByFamily method is:
+%
+% const TypeInfo *GetTypeInfoByFamily(const char *family,
+% const StyleType style,const StretchType stretch,
+% const unsigned long weight,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o type_info: Method GetTypeInfo searches the type list for the specified
+% name and if found returns attributes for that type.
+%
+% o family: The type family.
+%
+% o style: The type style.
+%
+% o stretch: The type stretch.
+%
+% o weight: The type weight.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+MagickExport const TypeInfo *GetTypeInfoByFamily(const char *family,
+ const StyleType style,const StretchType stretch,const unsigned long weight,
+ ExceptionInfo *exception)
+{
+ typedef struct _Fontmap
+ {
+ char
+ *name,
+ *substitute;
+ } Fontmap;
+
+ const TypeInfo
+ *type_info;
+
+ long
+ range;
+
+ register const TypeInfo
+ *p;
+
+ register long
+ i;
+
+ static Fontmap
+ fontmap[] =
+ {
+ { (char *) "fixed", (char *) "courier" },
+ { (char *) "modern",(char *) "courier" },
+ { (char *) "monotype corsiva", (char *) "courier" },
+ { (char *) "news gothic", (char *) "helvetica" },
+ { (char *) "system", (char *) "courier" },
+ { (char *) "terminal", (char *) "courier" },
+ { (char *) "wingdings", (char *) "symbol" },
+ { (char *) NULL, (char *) NULL }
+ };
+
+ unsigned long
+ max_score,
+ score;
+
+ /*
+ Check for an exact type match.
+ */
+ (void) GetTypeInfo("*",exception);
+ if (type_list == (TypeInfo *) NULL)
+ return((TypeInfo *) NULL);
+ for (p=type_list; p != (TypeInfo *) NULL; p=p->next)
+ {
+ if (p->family == (char *) NULL)
+ continue;
+ if (family == (const char *) NULL)
+ {
+ if ((LocaleCompare(p->family,"arial") != 0) &&
+ (LocaleCompare(p->family,"helvetica") != 0))
+ continue;
+ }
+ else
+ if (LocaleCompare(p->family,family) != 0)
+ continue;
+ if ((style != AnyStyle) && (p->style != style))
+ continue;
+ if ((stretch != AnyStretch) && (p->stretch != stretch))
+ continue;
+ if ((weight != 0) && (p->weight != weight))
+ continue;
+ return((TypeInfo *) p);
+ }
+ /*
+ Check for types in the same family.
+ */
+ max_score=0;
+ type_info=(TypeInfo *) NULL;
+ for (p=type_list; p != (TypeInfo *) NULL; p=p->next)
+ {
+ if (p->family == (char *) NULL)
+ continue;
+ if (family == (const char *) NULL)
+ {
+ if ((LocaleCompare(p->family,"arial") != 0) &&
+ (LocaleCompare(p->family,"helvetica") != 0))
+ continue;
+ }
+ else
+ if (LocaleCompare(p->family,family) != 0)
+ continue;
+ score=0;
+ if ((style == AnyStyle) || (p->style == style))
+ score+=32;
+ else
+ if (((style == ItalicStyle) || (style == ObliqueStyle)) &&
+ ((p->style == ItalicStyle) || (p->style == ObliqueStyle)))
+ score+=25;
+ if (weight == 0)
+ score+=16;
+ else
+ score+=(16*(800-((long) Max(Min(weight,900),p->weight)-
+ (long) Min(Min(weight,900),p->weight))))/800;
+ if (stretch == AnyStretch)
+ score+=8;
+ else
+ {
+ range=(long) UltraExpandedStretch-(long) NormalStretch;
+ score+=(8*(range-((long) Max(stretch,p->stretch)-
+ (long) Min(stretch,p->stretch))))/range;
+ }
+ if (score > max_score)
+ {
+ max_score=score;
+ type_info=p;
+ }
+ }
+ if (type_info != (TypeInfo *) NULL)
+ return((TypeInfo *) type_info);
+ /*
+ Check for table-based substitution match.
+ */
+ for (i=0; fontmap[i].name != (char *) NULL; i++)
+ {
+ if (family == (const char *) NULL)
+ {
+ if ((LocaleCompare(fontmap[i].name,"arial") != 0) &&
+ (LocaleCompare(fontmap[i].name,"helvetica") != 0))
+ continue;
+ }
+ else
+ if (LocaleCompare(fontmap[i].name,family) != 0)
+ continue;
+ type_info=GetTypeInfoByFamily(fontmap[i].substitute,style,stretch,weight,
+ exception);
+ break;
+ }
+ if (type_info != (TypeInfo *) NULL)
+ {
+ ThrowException(exception,TypeError,FontSubstitutionRequired,
+ type_info->family);
+ return((TypeInfo *) type_info);
+ }
+ if (family != (const char *) NULL)
+ type_info=GetTypeInfoByFamily((const char *) NULL,style,stretch,weight,
+ exception);
+ return((TypeInfo *) type_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t T y p e l i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetTypeList() returns any types that match the specified pattern.
+%
+% The format of the GetTypeList function is:
+%
+% char **GetTypeList(const char *pattern,unsigned long *number_types)
+%
+% A description of each parameter follows:
+%
+% o pattern: Specifies a pointer to a text string containing a pattern.
+%
+% o number_types: This integer returns the number of types in the list.
+%
+%
+*/
+MagickExport char **GetTypeList(const char *pattern,unsigned long *number_types)
+{
+ char
+ **typelist;
+
+ ExceptionInfo
+ exception;
+
+ register const TypeInfo
+ *p;
+
+ register long
+ i;
+
+ /*
+ Allocate type list.
+ */
+ assert(pattern != (char *) NULL);
+ assert(number_types != (unsigned long *) NULL);
+ *number_types=0;
+ GetExceptionInfo(&exception);
+ p=GetTypeInfo("*",&exception);
+ DestroyExceptionInfo(&exception);
+ if (p == (const TypeInfo *) NULL)
+ return((char **) NULL);
+ i=0;
+ for (p=type_list; p != (const TypeInfo *) NULL; p=p->next)
+ i++;
+ typelist=MagickAllocateMemory(char **,i*sizeof(char *));
+ if (typelist == (char **) NULL)
+ return((char **) NULL);
+ i=0;
+ for (p=type_list; p != (const TypeInfo *) NULL; p=p->next)
+ {
+ if (p->stealth)
+ continue;
+ if (GlobExpression(p->name,pattern))
+ typelist[i++]=AllocateString(p->name);
+ }
+ *number_types=i;
+ return(typelist);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I n i t i a l i z e T y p e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method InitializeTypeInfo initializes the type facility
+%
+% The format of the InitializeTypeInfo method is:
+%
+% MagickPassFail InitializeTypeInfo(void)
+%
+%
+*/
+MagickPassFail
+InitializeTypeInfo(void)
+{
+ assert(type_semaphore == (SemaphoreInfo *) NULL);
+ type_semaphore=AllocateSemaphoreInfo();
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t T y p e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ListTypeInfo lists the fonts to a file.
+%
+% The format of the ListTypeInfo method is:
+%
+% unsigned int ListTypeInfo(FILE *file,ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o file: An pointer to a FILE.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+
+MagickExport unsigned int ListTypeInfo(FILE *file,ExceptionInfo *exception)
+{
+ char
+ weight[MaxTextExtent];
+
+ const char
+ *family,
+ *name,
+ *stretch,
+ *style;
+
+ register const TypeInfo
+ *p;
+
+ if (file == (FILE *) NULL)
+ file=stdout;
+ (void) GetTypeInfo("*",exception);
+ LockSemaphoreInfo(type_semaphore);
+ for (p=type_list; p != (const TypeInfo *) NULL; p=p->next)
+ {
+ if ((p->previous == (TypeInfo *) NULL) ||
+ (LocaleCompare(p->path,p->previous->path) != 0))
+ {
+ if (p->previous != (TypeInfo *) NULL)
+ (void) fprintf(file,"\n");
+ if (p->path != (char *) NULL)
+ (void) fprintf(file,"Path: %.1024s\n\n",p->path);
+ (void) fprintf(file,"%-32.32s %-23.23s %-7.7s %-8s %-3s\n",
+ "Name","Family","Style","Stretch","Weight");
+ (void) fprintf(file,"--------------------------------------------------"
+ "------------------------------\n");
+ }
+ if (p->stealth)
+ continue;
+ name="unknown";
+ if (p->name != (char *) NULL)
+ name=p->name;
+ family="unknown";
+ if (p->family != (char *) NULL)
+ family=p->family;
+ style=StyleTypeToString(p->style);
+ stretch=StretchTypeToString(p->stretch);
+ FormatString(weight,"%lu",p->weight);
+ (void) fprintf(file,"%-32.32s %-23.23s %-7.7s %-9s %-3s\n",
+ name,family,style,stretch,weight);
+ }
+ (void) fflush(file);
+ UnlockSemaphoreInfo(type_semaphore);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ R e a d T y p e C o n f i g u r e F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ReadTypeConfigureFile() reads the type configuration file which provides
+% a mapping between type attributes and font files.
+%
+% The format of the ReadTypeConfigureFile method is:
+%
+% unsigned int ReadTypeConfigureFile(const char *basename,
+% const unsigned long depth,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o status: ReadTypeConfigureFile() returns True if at least one entry
+% is read, otherwise False is returned.
+%
+% o basename: The type configuration filename.
+%
+% o depth: depth of <include /> statements.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+static unsigned int ReadTypeConfigureFile(const char *basename,
+ const unsigned long depth,ExceptionInfo *exception)
+{
+ char
+ keyword[MaxTextExtent],
+ path[MaxTextExtent],
+ *q,
+ *token,
+ *xml;
+
+#if defined(MSWINDOWS)
+ char
+ GhostscriptFontDir[MaxTextExtent];
+#endif
+
+ size_t
+ length,
+ token_max_length;
+
+ /*
+ Read the type configure file.
+ */
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "File path=\"%.1024s\", recursion depth=%lu",basename,depth);
+ (void) strlcpy(path,basename,sizeof(path));
+#if defined(MSWINDOWS)
+ /*
+ For Windows, cache the location of the Ghostscript fonts.
+ */
+ GhostscriptFontDir[0]='\0';
+ if (NTGhostscriptFonts(GhostscriptFontDir,MaxTextExtent-2))
+ (void) strlcat(GhostscriptFontDir,DirectorySeparator,
+ sizeof(GhostscriptFontDir));
+#endif
+ if (depth == 0)
+ {
+ /*
+ Load top configuration file based on configure search path.
+ */
+ xml=(char *) GetConfigureBlob(basename,path,&length,exception);
+ if (xml == (char *) NULL)
+ xml=AllocateString(TypeMap);
+ }
+ else
+ {
+ /*
+ Load subordinate configuration file based on path specified
+ by parent configuration file.
+ */
+ if (IsAccessibleAndNotEmpty(basename))
+ xml=(char *) FileToBlob(basename,&length,exception);
+ else
+ {
+ GetPathComponent(basename,TailPath,path);
+ xml=(char *) GetConfigureBlob(path,keyword,&length,exception);
+ }
+ if (xml == (char *) NULL)
+ return (False);
+ }
+
+ token=AllocateString(xml);
+ token_max_length=strlen(token);
+ for (q=xml; *q != '\0'; )
+ {
+ /*
+ Interpret XML.
+ */
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token == '\0')
+ break;
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ if (LocaleNCompare(keyword,"<!--",4) == 0)
+ {
+ /*
+ Comment element.
+ */
+ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
+ MagickGetToken(q,&q,token,token_max_length);
+ continue;
+ }
+ if (LocaleCompare(keyword,"<include") == 0)
+ {
+ /*
+ Include element.
+ */
+ while ( (*token != '/' && *(token+1) != '>') && (*q != '\0'))
+ {
+ (void) strlcpy(keyword,token,MaxTextExtent);
+ MagickGetToken(q,&q,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ if (LocaleCompare(keyword,"file") == 0)
+ {
+ if (depth > 200)
+ ThrowException(exception,ConfigureError,IncludeElementNestedTooDeeply,path);
+ else
+ {
+ char
+ filename[MaxTextExtent];
+
+ GetPathComponent(path,HeadPath,filename);
+ if (filename[0] != '\0')
+ (void) strlcat(filename,DirectorySeparator,sizeof(filename));
+ (void) strlcat(filename,token,sizeof(filename));
+ (void) ReadTypeConfigureFile(filename,depth+1,exception);
+ }
+ if (type_list != (TypeInfo *) NULL)
+ while (type_list->next != (TypeInfo *) NULL)
+ type_list=type_list->next;
+ }
+ }
+ continue;
+ }
+ if (LocaleCompare(keyword,"<type") == 0)
+ {
+ TypeInfo
+ *type_info;
+
+ /*
+ Allocate memory for the type list.
+ */
+ type_info=MagickAllocateMemory(TypeInfo *,sizeof(TypeInfo));
+ if (type_info == (TypeInfo *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateTypeInfo);
+ (void) memset(type_info,0,sizeof(TypeInfo));
+ type_info->path=AcquireString(path);
+ type_info->signature=MagickSignature;
+ if (type_list == (TypeInfo *) NULL)
+ {
+ type_list=type_info;
+ continue;
+ }
+ /*
+ Append entry to end of type list
+ */
+ while (type_list->next != (TypeInfo *) NULL)
+ type_list=type_list->next;
+ type_list->next=type_info;
+ type_info->previous=type_list;
+ type_list=type_list->next;
+ continue;
+ }
+ if (type_list == (TypeInfo *) NULL)
+ continue;
+ MagickGetToken(q,(char **) NULL,token,token_max_length);
+ if (*token != '=')
+ continue;
+ MagickGetToken(q,&q,token,token_max_length);
+ MagickGetToken(q,&q,token,token_max_length);
+ switch (*keyword)
+ {
+ case 'E':
+ case 'e':
+ {
+ if (LocaleCompare((char *) keyword,"encoding") == 0)
+ {
+ type_list->encoding=AcquireString(token);
+ break;
+ }
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare((char *) keyword,"family") == 0)
+ {
+ type_list->family=AcquireString(token);
+ break;
+ }
+ if (LocaleCompare((char *) keyword,"format") == 0)
+ {
+ type_list->format=AcquireString(token);
+ break;
+ }
+ if (LocaleCompare((char *) keyword,"foundry") == 0)
+ {
+ type_list->foundry=AcquireString(token);
+ break;
+ }
+ if (LocaleCompare((char *) keyword,"fullname") == 0)
+ {
+ type_list->description=AcquireString(token);
+ break;
+ }
+ break;
+ }
+ case 'G':
+ case 'g':
+ {
+ if (LocaleCompare((char *) keyword,"glyphs") == 0)
+ {
+ char
+ *glyphs;
+
+ glyphs=(char *) NULL;
+ (void) CloneString(&glyphs,token);
+#if defined(MSWINDOWS)
+ if (strchr(glyphs,'@') != (char *) NULL)
+ SubstituteString(&glyphs,"@ghostscript_font_dir@",GhostscriptFontDir);
+#endif
+ type_list->glyphs=glyphs;
+ break;
+ }
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare((char *) keyword,"metrics") == 0)
+ {
+ char
+ *metrics;
+
+ metrics=AcquireString(token);
+#if defined(MSWINDOWS)
+ if (strchr(metrics,'@') != (char *) NULL)
+ SubstituteString(&metrics,"@ghostscript_font_dir@",GhostscriptFontDir);
+#endif
+ type_list->metrics=metrics;
+ break;
+ }
+ break;
+ }
+ case 'N':
+ case 'n':
+ {
+ if (LocaleCompare((char *) keyword,"name") == 0)
+ {
+ type_list->name=AcquireString(token);
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare((char *) keyword,"stealth") == 0)
+ {
+ type_list->stealth=LocaleCompare(token,"True") == 0;
+ break;
+ }
+ if (LocaleCompare((char *) keyword,"stretch") == 0)
+ {
+ if (LocaleCompare(token,"condensed") == 0)
+ type_list->stretch=CondensedStretch;
+ if (LocaleCompare(token,"expanded") == 0)
+ type_list->stretch=ExpandedStretch;
+ if (LocaleCompare(token,"extra-condensed") == 0)
+ type_list->stretch=ExtraCondensedStretch;
+ if (LocaleCompare(token,"extra-expanded") == 0)
+ type_list->stretch=ExtraExpandedStretch;
+ if (LocaleCompare(token,"normal") == 0)
+ type_list->stretch=NormalStretch;
+ if (LocaleCompare(token,"semi-condensed") == 0)
+ type_list->stretch=SemiCondensedStretch;
+ if (LocaleCompare(token,"semi-expanded") == 0)
+ type_list->stretch=SemiExpandedStretch;
+ if (LocaleCompare(token,"ultra-condensed") == 0)
+ type_list->stretch=UltraCondensedStretch;
+ if (LocaleCompare(token,"ultra-expanded") == 0)
+ type_list->stretch=UltraExpandedStretch;
+ break;
+ }
+ if (LocaleCompare((char *) keyword,"style") == 0)
+ {
+ if (LocaleCompare(token,"italic") == 0)
+ type_list->style=ItalicStyle;
+ if (LocaleCompare(token,"normal") == 0)
+ type_list->style=NormalStyle;
+ if (LocaleCompare(token,"oblique") == 0)
+ type_list->style=ObliqueStyle;
+ break;
+ }
+ break;
+ }
+ case 'W':
+ case 'w':
+ {
+ if (LocaleCompare((char *) keyword,"weight") == 0)
+ {
+ type_list->weight=MagickAtoL(token);
+ if (LocaleCompare(token,"bold") == 0)
+ type_list->weight=700;
+ if (LocaleCompare(token,"normal") == 0)
+ type_list->weight=400;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ MagickFreeMemory(token);
+ MagickFreeMemory(xml);
+ if (type_list == (TypeInfo *) NULL)
+ return(False);
+ while (type_list->previous != (TypeInfo *) NULL)
+ type_list=type_list->previous;
+ return(True);
+}
diff --git a/magick/type.h b/magick/type.h
new file mode 100644
index 0000000..4cbaa77
--- /dev/null
+++ b/magick/type.h
@@ -0,0 +1,117 @@
+/*
+ Copyright (C) 2003 - 2009 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Drawing methods.
+*/
+#ifndef _MAGICK_TYPE_H
+#define _MAGICK_TYPE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ NormalStretch,
+ UltraCondensedStretch,
+ ExtraCondensedStretch,
+ CondensedStretch,
+ SemiCondensedStretch,
+ SemiExpandedStretch,
+ ExpandedStretch,
+ ExtraExpandedStretch,
+ UltraExpandedStretch,
+ AnyStretch
+} StretchType;
+
+typedef enum
+{
+ NormalStyle,
+ ItalicStyle,
+ ObliqueStyle,
+ AnyStyle
+} StyleType;
+
+/*
+ Typedef declarations.
+*/
+typedef struct _TypeInfo
+{
+ char
+ *path,
+ *name,
+ *description,
+ *family;
+
+ StyleType
+ style;
+
+ StretchType
+ stretch;
+
+ unsigned long
+ weight;
+
+ char
+ *encoding,
+ *foundry,
+ *format,
+ *metrics,
+ *glyphs;
+
+ unsigned int
+ stealth;
+
+ unsigned long
+ signature;
+
+ struct _TypeInfo
+ *previous,
+ *next;
+} TypeInfo;
+
+/*
+ Method declarations.
+*/
+extern MagickExport char
+ **GetTypeList(const char *,unsigned long *);
+
+extern MagickExport MagickPassFail
+ ListTypeInfo(FILE *,ExceptionInfo *);
+
+extern MagickExport const TypeInfo
+ *GetTypeInfo(const char *,ExceptionInfo *),
+ *GetTypeInfoByFamily(const char *,const StyleType,const StretchType,
+ const unsigned long,ExceptionInfo *);
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+extern MagickExport void
+ DestroyTypeInfo(void);
+
+extern MagickPassFail
+ InitializeTypeInfo(void);
+
+#endif /* MAGICK_IMPLEMENTATION */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _MAGICK_TYPE_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/unix_port.c b/magick/unix_port.c
new file mode 100644
index 0000000..68c582b
--- /dev/null
+++ b/magick/unix_port.c
@@ -0,0 +1,169 @@
+/*
+% Copyright (C) 2007-2016 GraphicsMagick Group
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U U N N IIIII X X %
+% U U NN N I X X %
+% U U N N N I X %
+% U U N NN I X X %
+% UUU N N IIIII X X %
+% %
+% %
+% GraphicsMagick UNIX Methods %
+% %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% July 2007 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/confirm_access.h"
+#if defined(POSIX)
+/* some of these may have already been included by studio.h */
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <utime.h>
+#include "magick/utility.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t M M U P a g e S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetMMUPageSize() returns the VM pagesize used by the MMU. The VM
+% pagesize is the number of bytes retrieved due to one page fault.
+%
+% The format of the MagickGetMMUPageSize method is:
+%
+% long MagickGetMMUPageSize()
+%
+*/
+MagickExport long MagickGetMMUPageSize(void)
+{
+ static long
+ pagesize = -1;
+
+ if (pagesize <= 0)
+ {
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+ pagesize=sysconf(_SC_PAGE_SIZE);
+#endif /* defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) */
+#if defined(HAVE_GETPAGESIZE)
+ if (pagesize <= 0)
+ pagesize=getpagesize();
+#endif /* defined(HAVE_GETPAGESIZE) */
+ if (pagesize <= 0)
+ pagesize=16384;
+ }
+
+ return pagesize;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t F i l e A t t r i b u t e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetFileAttributes() returns the file attributes for a specified
+% file in a structure of type MagickStatStruct_t.
+%
+% The format of the MagickGetFileAttributes method is:
+%
+% int MagickGetFileAttributes(const char *filename,
+% MagickStatStruct_t *statbuf)
+%
+% A description of each parameter follows:
+%
+% o filename: Path to the file
+%
+% o statbuf: A structure of type MagickStatStruct_t to populate.
+%
+%
+*/
+MagickExport int MagickGetFileAttributes(const char *filename,
+ MagickStatStruct_t *statbuf)
+{
+ if (MagickStat(filename, statbuf) != 0)
+ return -1;
+
+ return 0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t F i l e A t t r i b u t e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetFileAttributes() sets the access and modification time file
+% attributes based on values provided via in a structure of type
+% MagickStatStruct_t.
+%
+% The format of the MagickGetFileAttributes method is:
+%
+% int MagickSetFileAttributes(const char *filename,
+% const MagickStatStruct_t *statbuf)
+%
+% A description of each parameter follows:
+%
+% o filename: Path to the file
+%
+% o statbuf: A structure of type MagickStatStruct_t to populate.
+%
+%
+*/
+MagickExport int MagickSetFileAttributes(const char *filename,
+ const MagickStatStruct_t *statbuf)
+{
+ struct utimbuf
+ utbuf;
+
+ utbuf.actime = statbuf->st_atime;
+ utbuf.modtime = statbuf->st_mtime;
+
+ if (utime(filename, &utbuf) != 0)
+ return -1;
+
+ return 0;
+}
+
+#endif /* defined(POSIX) */
diff --git a/magick/unix_port.h b/magick/unix_port.h
new file mode 100644
index 0000000..e65ff4e
--- /dev/null
+++ b/magick/unix_port.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2007-2016 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Interfaces specific to Unix.
+
+*/
+#ifndef _UNIX_PORT_H
+#define _UNIX_PORT_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+/*
+ I/O defines.
+*/
+#if defined(MSWINDOWS) && !defined(Windows95) && !defined(__BORLANDC__)
+ /* Windows '95 and Borland C do not support _lseeki64 */
+# define MagickSeek(fildes,offset,whence) _lseeki64(fildes,/* __int64 */ offset,whence)
+# define MagickTell(fildes) /* __int64 */ _telli64(fildes)
+#else
+# define MagickSeek(fildes,offset,whence) lseek(fildes,offset,whence)
+# define MagickTell(fildes) (MagickSeek(fildes,0,SEEK_CUR))
+#endif
+
+#define MagickFseek(stream,offset,whence) fseek(stream,offset,whence)
+#define MagickFstat(fildes,stat_buff) fstat(fildes,stat_buff)
+#define MagickFtell(stream) ftell(stream)
+#define MagickStatStruct_t struct stat
+#define MagickStat(path,stat_buff) stat(path,stat_buff)
+
+extern MagickExport long
+ MagickGetMMUPageSize(void);
+
+extern MagickExport int
+ MagickGetFileAttributes(const char *filename, struct stat *statbuf);
+
+extern MagickExport int
+ MagickSetFileAttributes(const char *filename, const struct stat *statbuf);
+
+/*
+ Size type passed to read/write
+*/
+#define MAGICK_POSIX_IO_SIZE_T size_t
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _UNIX_PORT_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/utility.c b/magick/utility.c
new file mode 100644
index 0000000..7f18dff
--- /dev/null
+++ b/magick/utility.c
@@ -0,0 +1,6383 @@
+/*
+% Copyright (C) 2003 - 2016 GraphicsMagick Group
+% Copyright (c) 2000 Markus Friedl. All rights reserved.
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% U U TTTTT IIIII L IIIII TTTTT Y Y %
+% U U T I L I T Y Y %
+% U U T I L I T Y %
+% U U T I L I T Y %
+% UUU T IIIII LLLLL IIIII T Y %
+% %
+% %
+% GraphicsMagick Utility Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% January 1993 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/confirm_access.h"
+#include "magick/enum_strings.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/pixel_cache.h"
+#include "magick/random.h"
+#include "magick/signature.h"
+#include "magick/tempfile.h"
+#include "magick/utility.h"
+
+#if defined(HAVE_MACH_O_DYLD_H)
+/* Needed for _NSGetExecutablePath */
+# include <mach-o/dyld.h>
+#endif
+
+#if defined(HAVE_SPAWNVP) && defined(HAVE_PROCESS_H)
+# include <process.h>
+#endif
+
+/*
+ Compute a value which is the next kilobyte power of 2 larger than
+ the requested value or MaxTextExtent, whichever is larger.
+
+ The objective is to round up the size quickly (and in repeatable
+ steps) in order to reduce the number of memory copies due to realloc
+ for strings which grow rapidly, while producing a reasonable size
+ for smaller strings.
+*/
+#define MagickRoundUpStringLength(size) \
+{ \
+ size_t \
+ _rounded; \
+ \
+ for (_rounded=256U; _rounded < (Max(size,256)); _rounded *= 2); \
+ size=_rounded; \
+}
+
+/*
+ Static declarations.
+*/
+static const char
+ Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static const unsigned char
+ AsciiMap[] =
+ {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
+ 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
+ 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
+ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
+ 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
+ 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
+ 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
+ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
+ 0xfc, 0xfd, 0xfe, 0xff,
+ };
+
+/*
+ Forward declaration.
+*/
+static int
+ IsDirectory(const char *);
+
+static int
+ MagickStrToD(const char *start,char **end,double *value);
+
+static MagickPassFail
+ MagickStrToInt64(const char *start,char **end,magick_int64_t *value);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A c q u i r e S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireString() allocates memory for a string and copies the source string
+% to that memory location (and returns it). This method is best used to
+% allocate constant strings since only enough memory to support the data
+% is allocated.
+%
+% The format of the AcquireString method is:
+%
+% char *AcquireString(const char *source)
+%
+% A description of each parameter follows:
+%
+% o allocated_string: Method AcquireString returns a copy of the source
+% string.
+%
+% o source: A character string.
+%
+%
+*/
+MagickExport char *AcquireString(const char *source)
+{
+ char
+ *destination;
+
+ size_t
+ length;
+
+ assert(source != (const char *) NULL);
+ length=strlen(source);
+ destination=MagickAllocateMemory(char *,length+1);
+ if (destination == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateString);
+ if (length != 0)
+ (void) memcpy(destination,source,length);
+ destination[length]='\0';
+ return(destination);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A l l o c a t e S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AllocateString() allocates memory for a string and copies the source string
+% to that memory location (and returns it). Additional memory is allocated
+% so that subsequent concatenations to the string are most efficient.
+%
+% The format of the AllocateString method is:
+%
+% char *AllocateString(const char *source)
+%
+% A description of each parameter follows:
+%
+% o allocated_string: Method AllocateString returns a copy of the source
+% string.
+%
+% o source: A character string.
+%
+%
+*/
+MagickExport char *AllocateString(const char *source)
+{
+ char
+ *destination;
+
+ size_t
+ allocation_length,
+ source_length;
+
+ allocation_length=MaxTextExtent;
+ source_length=0;
+ if (source != (char *) NULL)
+ {
+ source_length=strlen(source);
+ allocation_length=source_length+1;
+ MagickRoundUpStringLength(allocation_length);
+ }
+ destination=MagickAllocateMemory(char *,allocation_length);
+ if (destination == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateString);
+ if (source_length != 0)
+ (void) memcpy(destination,source,source_length);
+ destination[source_length]='\0';
+ return(destination);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% A p p e n d I m a g e F o r m a t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AppendImageFormat() appends the image format type to the filename. If an
+% extension to the file already exists, it is first removed.
+%
+% The format of the AppendImageFormat method is:
+%
+% void AppendImageFormat(const char *format,char *filename)
+%
+% A description of each parameter follows.
+%
+% o format: Specifies a pointer to an array of characters. This is the
+% format of the image.
+%
+% o filename: Specifies a pointer to an array of characters. The unique
+% file name is returned in this array.
+%
+%
+*/
+MagickExport void AppendImageFormat(const char *format,char *filename)
+{
+ char
+ root[MaxTextExtent];
+
+ assert(format != (char *) NULL);
+ assert(filename != (char *) NULL);
+ if ((*format == '\0') || (*filename == '\0'))
+ return;
+ if (LocaleCompare(filename,"-") == 0)
+ {
+ char
+ message[MaxTextExtent];
+
+ FormatString(message,"%.1024s:%.1024s",format,filename);
+ (void) strlcpy(filename,message,MaxTextExtent);
+ return;
+ }
+ GetPathComponent(filename,RootPath,root);
+ FormatString(filename,"%.1024s.%.1024s",root,format);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B a s e 6 4 D e c o d e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Base64Decode() decodes Base64-encoded text and returns its binary
+% equivalent. NULL is returned if the text is not valid base64 data, or a
+% memory allocation failure occurs.
+%
+% Contributed by Bob Friesenhahn.
+%
+% The format of the Base64Decode method is:
+%
+% unsigned char *Base64Decode(const char *source,length_t *length)
+%
+% A description of each parameter follows:
+%
+% o source: A pointer to a Base64-encoded string.
+%
+% o length: The number of bytes decoded.
+%
+*/
+MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
+{
+ int
+ state;
+
+ register const char
+ *p,
+ *q;
+
+ register size_t
+ i;
+
+ size_t
+ max_length;
+
+ unsigned char
+ *decode;
+
+ assert(source != (char *) NULL);
+ assert(length != (size_t *) NULL);
+ *length=0;
+ max_length=3*strlen(source)/4+1;
+ decode=MagickAllocateMemory(unsigned char *,max_length);
+ if (decode == (unsigned char *) NULL)
+ return((unsigned char *) NULL);
+ i=0;
+ state=0;
+ for (p=source; *p != '\0'; p++)
+ {
+ if (isspace((int)(unsigned char) *p))
+ continue;
+ if (*p == '=')
+ break;
+ q=strchr(Base64,*p);
+ if (q == (char *) NULL)
+ {
+ MagickFreeMemory(decode);
+ return((unsigned char *) NULL); /* non-base64 character */
+ }
+ switch (state)
+ {
+ case 0:
+ {
+ decode[i]=(q-Base64) << 2;
+ state++;
+ break;
+ }
+ case 1:
+ {
+ decode[i++]|=(q-Base64) >> 4;
+ decode[i]=((q-Base64) & 0x0f) << 4;
+ state++;
+ break;
+ }
+ case 2:
+ {
+ decode[i++]|=(q-Base64) >> 2;
+ decode[i]=((q-Base64) & 0x03) << 6;
+ state++;
+ break;
+ }
+ case 3:
+ {
+ decode[i++]|=(q-Base64);
+ state=0;
+ break;
+ }
+ }
+ }
+ /*
+ Verify Base-64 string has proper terminal characters.
+ */
+ if (*p != '=')
+ {
+ if (state != 0)
+ {
+ MagickFreeMemory(decode);
+ return((unsigned char *) NULL);
+ }
+ }
+ else
+ {
+ p++;
+ switch (state)
+ {
+ case 0:
+ case 1:
+ {
+ /*
+ Unrecognized '=' character.
+ */
+ MagickFreeMemory(decode);
+ return((unsigned char *) NULL);
+ }
+ case 2:
+ {
+ for ( ; *p != '\0'; p++)
+ if (!isspace((int)(unsigned char)*p))
+ break;
+ if (*p != '=')
+ {
+ MagickFreeMemory(decode);
+ return((unsigned char *) NULL);
+ }
+ p++;
+ break;
+ }
+ case 3:
+ {
+ for ( ; *p != '\0'; p++)
+ if (!isspace((int)(unsigned char) *p))
+ {
+ MagickFreeMemory(decode);
+ return((unsigned char *) NULL);
+ }
+ if (decode[i] != 0)
+ {
+ MagickFreeMemory(decode);
+ return((unsigned char *) NULL);
+ }
+ break;
+ }
+ }
+ }
+ *length=i;
+ assert(*length < max_length);
+ return(decode);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% B a s e 6 4 E n c o d e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Base64Encode() encodes arbitrary binary data to base64 encoded format as
+% described by the "Base64 Content-Transfer-Encoding" section of RFC 2045 and
+% returns the result as a null-terminated ASCII string. NULL is returned if
+% a memory allocation failure occurs.
+%
+% Contributed by Bob Friesenhahn.
+%
+% The format of the Base64Encode method is:
+%
+% char *Base64Encode(const unsigned char *blob,const size_t blob_length,
+% size_t *encode_length)
+%
+% A description of each parameter follows:
+%
+% o blob: A pointer to binary data to encode.
+%
+% o blob_length: The number of bytes to encode.
+%
+% o encode_length: The number of bytes encoded.
+%
+*/
+#define Index64(index) ((index) & 0x3f)
+MagickExport char *Base64Encode(const unsigned char *blob,
+ const size_t blob_length,size_t *encode_length)
+{
+ char
+ *encode;
+
+ register const unsigned char
+ *p;
+
+ register size_t
+ i;
+
+ size_t
+ max_length,
+ remaining;
+
+ assert(blob != (const unsigned char *) NULL);
+ assert(blob_length != 0);
+ assert(encode_length != (size_t *) NULL);
+ *encode_length=0;
+ max_length=MagickArraySize(4U,blob_length)/3U;
+ if (max_length)
+ max_length += 4U;
+ encode=MagickAllocateMemory(char *,max_length);
+ if (encode == (char *) NULL)
+ return((char *) NULL);
+ i=0;
+ for (p=blob; p < (blob+blob_length-2); p+=3)
+ {
+ encode[i++]=Base64[Index64(*p >> 2)];
+ encode[i++]=Base64[Index64(((*p & 0x03) << 4)+(*(p+1) >> 4))];
+ encode[i++]=Base64[Index64(((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
+ encode[i++]=Base64[Index64(*(p+2))];
+ }
+ remaining=blob_length % 3;
+ if (remaining != 0)
+ {
+ long
+ j;
+
+ unsigned char
+ code[3];
+
+ code[0]='\0';
+ code[1]='\0';
+ code[2]='\0';
+ for (j=0; j < (long) remaining; j++)
+ code[j]=(*p++);
+ encode[i++]=Base64[Index64(code[0] >> 2)];
+ encode[i++]=Base64[Index64(((code[0] & 0x03) << 4)+(code[1] >> 4))];
+ if (remaining == 1)
+ encode[i++]='=';
+ else
+ encode[i++]=Base64[Index64(((code[1] & 0x0f) << 2)+(code[2] >> 6))];
+ encode[i++]='=';
+ }
+ *encode_length=i;
+ encode[i++]='\0';
+ assert(i <= max_length);
+ return(encode);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method CloneString allocates memory for the destination string and copies
+% the source string to that memory location.
+%
+% The format of the CloneString method is:
+%
+% MagickPassFail CloneString(char **destination,const char *source)
+%
+% A description of each parameter follows:
+%
+% o status: Method CloneString returns MagickPass if the string is cloned,
+% otherwise MagickFail is returned.
+%
+% o destination: A pointer to a character string.
+%
+% o source: A character string.
+%
+%
+*/
+MagickExport MagickPassFail CloneString(char **destination,const char *source)
+{
+ size_t
+ allocation_length,
+ string_length;
+
+ assert(destination != (char **) NULL);
+ if (source == (const char *) NULL)
+ {
+ MagickFreeMemory(*destination);
+ return(MagickPass);
+ }
+ string_length=strlen(source);
+ allocation_length=string_length+1;
+ MagickRoundUpStringLength(allocation_length);
+ MagickReallocMemory(char *,*destination,allocation_length);
+ if (*destination == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateString);
+ if (0 != string_length)
+ (void) memcpy(*destination,source,string_length);
+ (*destination)[string_length]='\0';
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o n c a t e n a t e S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ConcatenateString appends a copy of string source, including
+% the terminating null character, to the end of string destination.
+%
+% The format of the ConcatenateString method is:
+%
+% MagickPassFail ConcatenateString(char **destination,const char *source)
+%
+% A description of each parameter follows:
+%
+% o status: Method ConcatenateString returns MagickPass if the string is cloned,
+% otherwise MagickFail is returned.
+%
+% o destination: A pointer to a character string.
+%
+% o source: A character string.
+%
+%
+*/
+MagickExport MagickPassFail ConcatenateString(char **destination,
+ const char *source)
+{
+ size_t
+ allocation_length,
+ destination_length=0,
+ source_length;
+
+ assert(destination != (char **) NULL);
+ if (source == (const char *) NULL)
+ return(MagickPass);
+ source_length=strlen(source);
+ if (*destination != (char *) NULL)
+ destination_length=strlen(*destination);
+ allocation_length=destination_length+source_length+1;
+ MagickRoundUpStringLength(allocation_length);
+ MagickReallocMemory(char *,(*destination),allocation_length);
+ if (*destination == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToConcatenateString);
+ if (0 != source_length)
+ (void) memcpy(&(*destination)[destination_length],source,source_length);
+ (*destination)[destination_length+source_length]='\0';
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e f i n e C l i e n t N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DefineClientName() this is a helper function that parses the passed string
+% in order to define the name of the client application.
+%
+% The format of the DefineClientName method is:
+%
+% void DefineClientName(const char *path)
+%
+% A description of each parameter follows:
+%
+% o path: A string that can also be a full path that contains the name of
+% application
+%
+*/
+MagickExport void DefineClientName(const char *path)
+{
+ if ((path != (char *) NULL) && (*path != '\0'))
+ {
+ char
+ component[MaxTextExtent];
+
+ GetPathComponent(path,BasePath,component);
+ (void) SetClientName(component);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e f i n e C l i e n t P a t h A n d N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DefineClientPathAndName() this is a helper function that parses the passed
+% string in order to define several global settings related to the location of
+% the application. It sets the path, the filename, and the display name of the
+% client application based on the input string which is assumed to be the full
+% and valid path to the client.
+%
+% The format of the DefineClientPathAndName method is:
+%
+% void DefineClientPathAndName(const char *path)
+%
+% A description of each parameter follows:
+%
+% o path: A string that must be a full path that contains the name of
+% application
+%
+*/
+MagickExport void DefineClientPathAndName(const char *path)
+{
+ if ((path != (char *) NULL) && (*path != '\0'))
+ {
+ char
+ component[MaxTextExtent];
+
+ /* This is the path only - inluding the parent folder */
+ GetPathComponent(path,HeadPath,component);
+ (void) SetClientPath(component);
+ /* This is the file name AND the extension - of present */
+ GetPathComponent(path,TailPath,component);
+ (void) SetClientFilename(component);
+ /* The last step is to define a human readable name for
+ the help and error logging systems. */
+ DefineClientName(component);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E s c a p e S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% EscapeString() allocates memory for a backslash-escaped version of a
+% source text string, copies the escaped version of the text to that
+% memory location while adding backslash characters, and returns the
+% escaped string.
+%
+% The format of the EscapeString method is:
+%
+% char *EscapeString(const char *source,const char escape)
+%
+% A description of each parameter follows:
+%
+% o allocated_string: Method EscapeString returns the escaped string.
+%
+% o source: A character string.
+%
+% o escape: The quoted string termination character to escape (e.g. '"').
+%
+*/
+MagickExport char *EscapeString(const char *source,const char escape)
+{
+ char
+ *destination;
+
+ register char
+ *q;
+
+ register const char
+ *p;
+
+ size_t
+ length;
+
+ assert(source != (const char *) NULL);
+
+ /*
+ Use dry-run method to compute required string length.
+ */
+ length=0;
+ for (p=source; *p; p++)
+ {
+ if ((*p == '\\') || (*p == escape))
+ length++;
+ length++;
+ }
+ destination=MagickAllocateMemory(char *,length+1);
+ if (destination == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToEscapeString);
+ *destination='\0';
+ q=destination;
+ for (p=source; *p; p++)
+ {
+ if ((*p == '\\') || (*p == escape))
+ *q++= '\\';
+ *q++=(*p);
+ }
+ *q=0;
+ return(destination);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x p a n d F i l e n a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ExpandFilename expands '~' in a filename.
+%
+% The format of the ExpandFilename function is:
+%
+% ExpandFilename(char *filename)
+%
+% A description of each parameter follows:
+%
+% o filename: Specifies a pointer to a character array that contains the
+% filename.
+%
+%
+*/
+MagickExport void ExpandFilename(char *filename)
+{
+ char
+ expanded_filename[MaxTextExtent];
+
+ register char
+ *p;
+
+ if (filename == (char *) NULL)
+ return;
+ if (*filename != '~')
+ return;
+ (void) strlcpy(expanded_filename,filename,MaxTextExtent);
+ if (*(filename+1) == '/')
+ {
+ /*
+ Substitute ~ with $HOME.
+ */
+ p=(char *) getenv("HOME");
+ if (p == (char *) NULL)
+ p=(char *) ".";
+ (void) strlcpy(expanded_filename,p,MaxTextExtent);
+ (void) strlcat(expanded_filename,filename+1,MaxTextExtent);
+ }
+ else
+ {
+#if defined(POSIX)
+ char
+ username[MaxTextExtent];
+
+ struct passwd
+ *entry;
+
+ /*
+ Substitute ~ with home directory from password file.
+ */
+ (void) strlcpy(username,filename+1,MaxTextExtent);
+ p=strchr(username,'/');
+ if (p != (char *) NULL)
+ *p='\0';
+ entry=getpwnam(username);
+ if (entry == (struct passwd *) NULL)
+ return;
+ (void) strncpy(expanded_filename,entry->pw_dir,MaxTextExtent-1);
+ if (p != (char *) NULL)
+ {
+ (void) strcat(expanded_filename,"/");
+ (void) strlcat(expanded_filename,p+1,MaxTextExtent);
+ }
+#endif
+ }
+ (void) strlcpy(filename,expanded_filename,MaxTextExtent);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% E x p a n d F i l e n a m e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ExpandFilenames checks each argument of the command line vector and
+% expands it if they have a wildcard character. For example, *.jpg might
+% expand to: bird.jpg rose.jpg tiki.jpg.
+%
+% The format of the ExpandFilenames function is:
+%
+% status=ExpandFilenames(int *argc,char ***argv)
+%
+% A description of each parameter follows:
+%
+% o argc: Specifies a pointer to an integer describing the number of
+% elements in the argument vector.
+%
+% o argv: Specifies a pointer to a text array containing the command line
+% arguments. The existing argument list is replaced.
+%
+%
+*/
+MagickExport MagickPassFail ExpandFilenames(int *argc,char ***argv)
+{
+ const
+ size_t prealloc_entries = 1024;
+
+ char
+ current_directory[MaxTextExtent],
+ *option,
+ **vector;
+
+ long
+ count,
+ number_files;
+
+ register long
+ i,
+ j;
+
+ MagickBool
+ first;
+
+ /*
+ Allocate argument vector.
+ */
+ assert(argc != (int *) NULL);
+ assert(argv != (char ***) NULL);
+ vector=MagickAllocateMemory(char **,(*argc+prealloc_entries)*sizeof(char *));
+ if (vector == (char **) NULL)
+ return(MagickFail);
+ /*
+ Expand any wildcard filenames.
+ */
+ current_directory[0]='\0';
+ count=0;
+ for (i=0; i < *argc; i++)
+ {
+ char
+ **filelist,
+ filename[MaxTextExtent],
+ magick[MaxTextExtent],
+ path[MaxTextExtent],
+ subimage[MaxTextExtent];
+
+ option=(*argv)[i];
+ /* Never throw options away, so copy here, then perhaps modify later */
+ vector[count++]=AcquireString(option);
+
+ /*
+ Don't expand or process any VID: argument since the VID coder
+ does its own expansion
+ */
+ if (LocaleNCompare("VID:",option,4) == 0)
+ continue;
+
+ /*
+ Don't attempt to expand the argument to these options.
+ */
+ if ((LocaleNCompare("+define",option,7) == 0) ||
+ (LocaleNCompare("+profile",option,8) == 0) ||
+ (LocaleNCompare("-comment",option,8) == 0) ||
+ (LocaleNCompare("-convolve",option,9) == 0) ||
+ (LocaleNCompare("-draw",option,5) == 0) ||
+ (LocaleNCompare("-font",option,5) == 0) ||
+ (LocaleNCompare("-format",option,7) == 0) ||
+ (LocaleNCompare("-label",option,6) == 0))
+ {
+ i++;
+ if (i == *argc)
+ continue;
+ option=(*argv)[i];
+ vector[count++]=AcquireString(option);
+ continue;
+ }
+
+ /* Pass quotes through to the command-line parser */
+ if ((*option == '"') || (*option == '\''))
+ continue;
+
+ /*
+ Expand @filename to a list of arguments.
+ */
+ j=0;
+ if (option[0] == '@')
+ {
+ FILE
+ *file;
+
+ file=fopen(option+1,"r");
+ if (file != (FILE *) NULL)
+ {
+
+ first=MagickTrue;
+ number_files=0;
+ while (fgets(filename,sizeof(filename),file) != (char *) NULL)
+ {
+ for (j=0; filename[j] != '\0'; j++)
+ if (filename[j] == '\n')
+ filename[j] = '\0';
+
+ if (filename[0] != '\0')
+ {
+ if ((number_files % prealloc_entries) == 0)
+ {
+ MagickReallocMemory(char **,vector,
+ (*argc+count+prealloc_entries)*
+ sizeof(char *));
+ if (vector == (char **) NULL)
+ {
+ fclose(file);
+ return(MagickFail);
+ }
+ }
+
+ if (first)
+ {
+ /* Deallocate original option assigned above */
+ --count;
+ MagickFreeMemory(vector[count]);
+ first=MagickFalse;
+ }
+ number_files++;
+ vector[count++]=AcquireString(filename);
+ }
+ }
+
+ fclose(file);
+ }
+ }
+
+ /*
+ Fast cycle options that are not expandable filename patterns.
+ ListFiles only expands patterns in the filename. We also check
+ if the full option resolves to a file since ListFiles() obtains
+ a list of all the files in the directory and is thus very slow
+ if there are thousands of files.
+ */
+ GetPathComponent(option,TailPath,filename);
+ if ((!IsGlob(filename)) || IsAccessibleNoLogging(option))
+ continue;
+
+ /* Chop the option to get its other filename components. */
+ GetPathComponent(option,MagickPath,magick);
+ GetPathComponent(option,HeadPath,path);
+ GetPathComponent(option,SubImagePath,subimage);
+
+ /* GetPathComponent throws away the colon */
+ if (*magick != '\0')
+ (void) strlcat(magick,":",sizeof(magick));
+ ExpandFilename(path);
+
+ if ('\0' == current_directory[0])
+ if (getcwd(current_directory,MaxTextExtent-1) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+
+ /* Get the list of matching file names. */
+ filelist=ListFiles(*path=='\0' ? current_directory : path,
+ filename,&number_files);
+
+ if (filelist != (char **) NULL)
+ for (j=0; j < number_files; j++)
+ if (IsDirectory(filelist[j]) <= 0)
+ break;
+
+ /* ListFiles() may change current directory without restoring. */
+ if ((strlen(current_directory) > 0) && (chdir(current_directory) != 0))
+ {
+ for (j=0; j < number_files; j++)
+ MagickFreeMemory(filelist[j]);
+ MagickFreeMemory(filelist);
+ MagickFatalError(ConfigureFatalError,UnableToRestoreCurrentDirectory,
+ NULL);
+ }
+
+ if (filelist == 0)
+ continue;
+
+ if (j == number_files)
+ {
+ /*
+ Bourne/Bash shells passes through unchanged any glob patterns
+ not matching anything (abc* and there's no file starting with
+ abc). Do the same for behaviour consistent with that.
+ */
+ for (j=0; j < number_files; j++)
+ MagickFreeMemory(filelist[j]);
+ MagickFreeMemory(filelist);
+ continue;
+ }
+
+ /*
+ There's at least one matching filename.
+ Transfer file list to argument vector.
+ */
+ MagickReallocMemory(char **,vector,
+ (*argc+count+number_files+prealloc_entries)*sizeof(char *));
+ if (vector == (char **) NULL)
+ return(MagickFail);
+
+ first=MagickTrue;
+ for (j=0; j < number_files; j++)
+ {
+ char
+ filename_buffer[MaxTextExtent];
+
+ *filename_buffer='\0';
+ if (strlcat(filename_buffer,path,sizeof(filename_buffer))
+ >= sizeof(filename_buffer))
+ MagickFatalError2(ResourceLimitFatalError,"Path buffer overflow",
+ filename_buffer);
+ if (*path != '\0')
+ {
+ if (strlcat(filename_buffer,DirectorySeparator,sizeof(filename_buffer))
+ >= sizeof(filename_buffer))
+ MagickFatalError2(ResourceLimitFatalError,"Path buffer overflow",
+ filename_buffer);
+ }
+ if (strlcat(filename_buffer,filelist[j],sizeof(filename_buffer))
+ >= sizeof(filename_buffer))
+ MagickFatalError2(ResourceLimitFatalError,"Path buffer overflow",
+ filename_buffer);
+ /* If it's a filename (not a directory) ... */
+ if (IsDirectory(filename_buffer) == 0)
+ {
+ char
+ formatted_buffer[MaxTextExtent];
+
+ *formatted_buffer='\0';
+ if (strlcat(formatted_buffer,magick,sizeof(formatted_buffer))
+ >= sizeof(formatted_buffer))
+ MagickFatalError2(ResourceLimitFatalError,"Path buffer overflow",
+ formatted_buffer);
+ if (strlcat(formatted_buffer,filename_buffer,sizeof(formatted_buffer))
+ >= sizeof(formatted_buffer))
+ MagickFatalError2(ResourceLimitFatalError,"Path buffer overflow",
+ formatted_buffer);
+ if (strlcat(formatted_buffer,subimage,sizeof(formatted_buffer))
+ >= sizeof(formatted_buffer))
+ MagickFatalError2(ResourceLimitFatalError,"Path buffer overflow",
+ formatted_buffer);
+ if (first)
+ {
+ /* Deallocate original option assigned above */
+ --count;
+ MagickFreeMemory(vector[count]);
+ first=MagickFalse;
+ }
+ vector[count++]=AcquireString(formatted_buffer);
+ }
+ MagickFreeMemory(filelist[j]);
+ }
+ MagickFreeMemory(filelist);
+ }
+ *argc=count;
+ *argv=vector;
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F o r m a t S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FormatSize() converts a size to a human readable format, for example,
+% 14kb, 234mb, 2.7gb, or 3.0tb. Scaling is done by repetitively dividing by
+% 1024.
+%
+% The format of the FormatSize method is:
+%
+% char *FormatSize(const magick_int64_t size,char *format)
+%
+% A description of each parameter follows:
+%
+% o size: convert this size to a human readable format.
+%
+% o format: human readable format.
+%
+%
+*/
+MagickExport void FormatSize(const magick_int64_t size,char *format)
+{
+ double
+ length;
+
+ register unsigned int
+ i;
+
+ length=size;
+ for (i=0; length > 1024; i++)
+ length/=1024.0;
+ if (i > 0)
+ FormatString(format,"%.1f",length);
+ else
+ FormatString(format,"%.0f",length);
+ switch (i)
+ {
+ default: break;
+ case 0: break;
+ case 1: (void) strcat(format,"Ki"); break; /* kilo, 10^3 */
+ case 2: (void) strcat(format,"Mi"); break; /* mega, 10^6 */
+ case 3: (void) strcat(format,"Gi"); break; /* giga, 10^9 */
+ case 4: (void) strcat(format,"Ti"); break; /* tera, 10^12 */
+ case 5: (void) strcat(format,"Pi"); break; /* peta, 10^15 */
+ case 6: (void) strcat(format,"Ei"); break; /* exa, 10^18 */
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F o r m a t S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method FormatString prints formatted output of a variable argument list.
+%
+% The format of the FormatString method is:
+%
+% void FormatString(char *string,const char *format,...)
+%
+% A description of each parameter follows.
+%
+% o string: Method FormatString returns the formatted string in this
+% character buffer. Buffer must be at least MaxTextExtent characters
+% in size.
+%
+% o format: A string describing the format to use to write the remaining
+% arguments.
+%
+%
+*/
+MagickExport void FormatStringList(char *string,const char *format,
+ va_list operands)
+{
+#if defined(HAVE_VSNPRINTF)
+ (void) vsnprintf(string,MaxTextExtent,format,operands);
+#else
+ (void) vsprintf(string,format,operands);
+#endif
+}
+MagickExport void FormatString(char *string,const char *format,...)
+{
+ va_list
+ operands;
+
+ va_start(operands,format);
+ FormatStringList(string, format, operands);
+ va_end(operands);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t E x e c u t i o n P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetExecutionPath() returns the pathname of the executable that started
+% the process. The user-supplied buffer must be at least MaxTextExtent
+% bytes long. On success True is returned, otherwise False.
+%
+% The format of the GetExecutionPath method is:
+%
+% unsigned int GetExecutionPath(char *path)
+%
+% A description of each parameter follows:
+%
+% o path: The pathname of the executable that started the process.
+%
+*/
+MagickExport MagickPassFail GetExecutionPath(char *path)
+{
+ *path='\0';
+#if defined(MSWINDOWS)
+ /*
+ Microsoft Windows provides an means to obtain the path to the
+ currently executing executable or DLL.
+ */
+ return(NTGetExecutionPath(path));
+#endif
+#if defined(HAVE_GETEXECNAME)
+ {
+ /*
+ Sun's Solaris provides a getexecname() for obtaining the path to
+ this executable.
+ */
+ const char
+ *execution_path;
+
+ execution_path=(const char *) getexecname();
+ if (execution_path != (const char *) NULL)
+ {
+ if (*execution_path != *DirectorySeparator)
+ {
+ if (getcwd(path,MaxTextExtent-1) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+ (void) strlcat(path,"/",MaxTextExtent);
+ }
+ (void) strlcat(path,execution_path,MaxTextExtent);
+ if (IsAccessible(path))
+ return(MagickPass);
+ }
+ }
+#endif
+#if defined(HAVE__NSGETEXECUTABLEPATH) && defined(HAVE_REALPATH)
+ {
+ /*
+ Apple OS-X provides a _NSGetExecutablePath function for
+ obtaining the path to the executable. The returned path may be
+ a symbolic link to the actual executable so use realpath() to
+ resolve the real path. It is claimed that _NSGetExecutablePath
+ could possibly return a path longer than MAXPATHLEN. Inspection
+ of <sys/param.h> on an OS-X system reveals that MAXPATHLEN is
+ defined to be PATH_MAX. So we will provide for PATH_MAX*2.
+ */
+ uint32_t
+ bufsize;
+
+ char
+ executable_path[PATH_MAX*2],
+ real_path[PATH_MAX+1];
+
+ bufsize=sizeof(executable_path);
+ if (_NSGetExecutablePath(executable_path,&bufsize) == 0)
+ if (realpath(executable_path,real_path) != NULL)
+ if (strlcpy(path,real_path,MaxTextExtent) < MaxTextExtent)
+ if (IsAccessible(path))
+ return(MagickPass);
+ }
+#endif
+#if defined(HAVE_GETPID) && defined(HAVE_READLINK)
+ {
+ /*
+ On Linux, the symbolic link "/proc/PID/exe" (where 'PID' is the
+ integer process ID) points to the physical executable. FreeBSD
+ is similar except that the link path is "/proc/PID/file". Maybe
+ some other systems use compatible schemes.
+ */
+ int
+ length;
+
+ long
+ pid;
+
+ char
+ link_path[MaxTextExtent],
+ real_path[PATH_MAX+1];
+
+ pid=(long) getpid();
+ /* Linux format */
+ FormatString(link_path,"/proc/%ld/exe",pid);
+ length=readlink(link_path, real_path, PATH_MAX);
+ if (length == -1)
+ {
+ /* Try FreeBSD format */
+ FormatString(link_path,"/proc/%ld/file",pid);
+ length=readlink(link_path, real_path, PATH_MAX);
+ }
+ if ((length > 0) && (length <= PATH_MAX))
+ {
+ real_path[length]=0;
+ if (strlcpy(path,real_path,MaxTextExtent) < MaxTextExtent)
+ if (IsAccessible(path))
+ return(MagickPass);
+ }
+ }
+#endif
+ return(MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t E x e c u t i o n P a t h U s i n g N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetExecutionPathUsingName() replaces the provided path with the full
+% path to the directory containing the executable. The replaced path
+% is terminated by a directory separator. The provided path may be
+% a bare executable name, a relative path to the executable, or the
+% full path to the executable. The provided path is usually obtained
+% from the argv[0] argument to main. If the path is a bare executable
+% name, then the executable is located via the executable search path.
+% If the path is replaced, then MagickPass is returned, otherwise
+% MagickFail is returned.
+%
+% The format of the GetExecutionPathUsingName method is:
+%
+% unsigned int GetExecutionPathUsingName(char *path)
+%
+% A description of each parameter follows:
+%
+% o path: The path (partial or complete) to the executable.
+%
+*/
+MagickExport MagickPassFail GetExecutionPathUsingName(char *path)
+{
+ char
+ execution_path[MaxTextExtent],
+ original_cwd[MaxTextExtent],
+ temporary_path[MaxTextExtent],
+ *p;
+
+ execution_path[0]='\0';
+
+ /*
+ Save original working directory so it can be restored later.
+ */
+ if (getcwd(original_cwd,sizeof(original_cwd)-1) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+
+ /*
+ Check to see if path is a valid relative path from current
+ directory.
+ */
+ if (IsAccessibleNoLogging(path))
+ {
+ /*
+ If we can change directory to the path, then capture the full
+ path to it. Otherwise, remove any trailing path component
+ (typically the program name) and try again.
+ */
+ if ((strlen(path) >0 ) && (chdir(path) == 0))
+ {
+ if (getcwd(execution_path,sizeof(execution_path)-2) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+ }
+ else
+ {
+ (void) strlcpy(temporary_path,path,sizeof(execution_path));
+ p=strrchr(temporary_path,DirectorySeparator[0]);
+ if (p)
+ *p='\0';
+ if ((strlen(temporary_path) > 0) && (chdir(temporary_path) == 0))
+ {
+ if (getcwd(execution_path,sizeof(execution_path)-2) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+ }
+ }
+ }
+ /*
+ Otherwise, check to see if bare program name is available via the
+ executable search path.
+ */
+ if ((execution_path[0] == 0) && (strchr(path,DirectorySeparator[0]) == NULL ))
+ {
+ const char
+ *search_path;
+
+ search_path=getenv("PATH");
+ if ( search_path )
+ {
+ const char
+ *end = NULL,
+ *start = search_path;
+
+ end=start+strlen(start);
+ while ( start < end )
+ {
+ const char
+ *separator;
+
+ int
+ length;
+
+ separator = strchr(start,DirectoryListSeparator);
+ if (separator)
+ length=separator-start;
+ else
+ length=end-start;
+ if (length > MaxTextExtent-1)
+ length = MaxTextExtent-1;
+ (void) strlcpy(temporary_path,start,length+1);
+ if ((strlen(temporary_path) > 0) && (chdir(temporary_path) == 0))
+ {
+ if (temporary_path[length-1] != DirectorySeparator[0])
+ (void) strlcat(temporary_path,DirectorySeparator,sizeof(temporary_path));
+ (void) strlcat(temporary_path,path,sizeof(temporary_path));
+ if (IsAccessibleNoLogging(temporary_path))
+ {
+ if (getcwd(execution_path,sizeof(execution_path)-2) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+ break;
+ }
+ }
+ start += length+1;
+ }
+ }
+ }
+
+ /*
+ Restore original working directory.
+ */
+ if ((strlen(original_cwd) > 0) && (chdir(original_cwd) != 0))
+ return(MagickFail);
+
+ if (execution_path[0] != '\0')
+ {
+ (void) strlcat(execution_path,DirectorySeparator,sizeof(execution_path));
+ (void) strlcpy(path,execution_path,MaxTextExtent);
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Path \"%.1024s\" is usable.",path);
+ errno=0;
+ return (MagickPass);
+ }
+
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Path \"%.1024s\" is not valid.",path);
+ return(MagickFail);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetGeometry() parses a geometry specification and returns the width
+% height, x, and y values. It also returns flags that indicates which
+% of the four values (width, height, x, y) were located in the string, and
+% whether the x and y values are negative. In addition, there are flags to
+% report any meta characters (%, !, <, >, @, and ^).
+%
+% The format of the GetGeometry method is:
+%
+% int GetGeometry(const char *image_geometry,long *x,long *y,
+% unsigned long *width,unsigned long *height)
+%
+% A description of each parameter follows:
+%
+% o flags: Method GetGeometry returns a bitmask that indicates
+% which of the four values were located in the geometry string.
+%
+% o image_geometry: Specifies a character string representing the geometry
+% specification.
+%
+% o x,y: The x and y offset as determined by the geometry specification is
+% returned here.
+%
+% o width,height: The width and height as determined by the geometry
+% specification is returned here.
+%
+%
+*/
+MagickExport int GetGeometry(const char *image_geometry,long *x,long *y,
+ unsigned long *width,unsigned long *height)
+{
+ const char
+ *c;
+
+ char
+ geometry[MaxTextExtent],
+ *p,
+ *q;
+
+ int
+ count,
+ flags,
+ i;
+
+ double
+ double_val;
+
+ RectangleInfo
+ bounds;
+
+ /*
+ Ensure the image geometry is valid.
+ */
+ assert(x != (long *) NULL);
+ assert(y != (long *) NULL);
+ assert(width != (unsigned long *) NULL);
+ assert(height != (unsigned long *) NULL);
+ if ((image_geometry == (char *) NULL) || (*image_geometry == '\0') ||
+ (strlen(image_geometry) > MaxTextExtent-1))
+ return(NoValue);
+
+ /*
+ Transfer base geometry while recording and stripping flags
+ */
+ i=0;
+ q=geometry;
+ flags=NoValue;
+
+ for (c=image_geometry; *c != 0 ; c++)
+ {
+ if (isspace((int)(unsigned char) (*c)))
+ {
+ continue;
+ }
+ else
+ switch (*c)
+ {
+ case '%':
+ {
+ flags|=PercentValue;
+ break;
+ }
+ case '!':
+ {
+ flags|=AspectValue;
+ break;
+ }
+ case '<':
+ {
+ flags|=LessValue;
+ break;
+ }
+ case '>':
+ {
+ flags|=GreaterValue;
+ break;
+ }
+ case '@':
+ {
+ flags|=AreaValue;
+ break;
+ }
+ case '^':
+ {
+ flags|=MinimumValue;
+ break;
+ }
+ case '+':
+ case '-':
+ case '.':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'X':
+ case 'x':
+ {
+ /* Check for too many characters. */
+ i++;
+ if (i == sizeof(geometry))
+ return NoValue;
+
+ *q=*c;
+ q++;
+ break;
+ }
+ default:
+ {
+ /* Illegal character fails entire geometry translation */
+ return NoValue;
+ }
+ }
+ }
+ *q='\0';
+
+ /*
+ Parse width/height/x/y. At this point resize qualifiers have been
+ truncated from the original geometry string.
+ */
+ bounds.width=0;
+ bounds.height=0;
+ bounds.x=0;
+ bounds.y=0;
+ p=geometry;
+ while (isspace((int)(unsigned char) *p))
+ p++;
+ if (*p == '\0')
+ return(flags);
+ if (*p == '=')
+ p++;
+ if ((*p != '+') && (*p != '-') && (*p != 'x') && (*p != 'X'))
+ {
+ /*
+ Parse width.
+ */
+ q=p;
+
+ count=MagickStrToD(p,&q,&double_val);
+ if (count)
+ {
+ bounds.width=(unsigned long) floor(double_val+0.5);
+ flags|=WidthValue;
+ }
+ if ((*q == 'x') || (*q == 'X') || ((flags & AreaValue) && (*q == '\0')))
+ p=q;
+ else
+ {
+ count=MagickStrToD(p,&p,&double_val);
+ if (count)
+ {
+ bounds.width=(unsigned long) floor(double_val+0.5);
+ bounds.height=bounds.width;
+ flags|=HeightValue;
+ }
+ }
+ }
+ if ((*p == 'x') || (*p == 'X'))
+ {
+ /*
+ Parse height.
+ */
+ p++;
+ q=p;
+ count=MagickStrToD(p,&p,&double_val);
+ if (count)
+ {
+ bounds.height=(unsigned long) floor(double_val+0.5);
+ flags|=HeightValue;
+ }
+ }
+ if ((*p == '+') || (*p == '-'))
+ {
+ /*
+ Parse x value.
+ */
+ if (*p == '+')
+ {
+ p++;
+ q=p;
+ count=MagickStrToD(p,&p,&double_val);
+ bounds.x=(long) ceil(double_val-0.5);
+ }
+ else
+ {
+ p++;
+ q=p;
+ count=MagickStrToD(p,&p,&double_val);
+ if (count)
+ {
+ bounds.x=(long) ceil(-double_val-0.5);
+ flags|=XNegative;
+ }
+ }
+ if (count)
+ flags|=XValue;
+ if ((*p == '+') || (*p == '-'))
+ {
+ /*
+ Parse y value.
+ */
+ if (*p == '+')
+ {
+ p++;
+ q=p;
+ count=MagickStrToD(p,&p,&double_val);
+ bounds.y=(long) ceil(double_val-0.5);
+ }
+ else
+ {
+ p++;
+ q=p;
+ count=MagickStrToD(p,&p,&double_val);
+ if (count)
+ {
+ bounds.y=(long) ceil(-double_val-0.5);
+ flags|=YNegative;
+ }
+ }
+ if (count)
+ flags|=YValue;
+ }
+ }
+ if (*p != '\0')
+ return(flags);
+ if (flags & XValue)
+ *x=bounds.x;
+ if (flags & YValue)
+ *y=bounds.y;
+ if (flags & WidthValue)
+ *width=bounds.width;
+ if (flags & HeightValue)
+ *height=bounds.height;
+ return(flags);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t M a g i c k D i m e n s i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickDimension() parses a string in the scanf form %lfx%lf+%lf+%lf
+% to obtain WIDTHxHEIGHT+XOFF+YOFF values and returns the number of values
+% successfully parsed. This function exists to overcome a new behavior of
+% ANSI C'99 which supports hex parsing.
+%
+% The format of the GetMagickDimension method is:
+%
+% int GetMagickDimension(const char *str,double *width,double *height,
+% double *xoff,double *yoff)
+%
+% A description of each parameter follows:
+%
+% o str: String to parse
+%
+% o width: First double value
+%
+% o height: Second double value
+%
+% o xoff: Third double value (usually "x offset"). May be NULL.
+%
+% o yoff: Fourth double value (usually "y offset"). May be NULL.
+%
+*/
+static int MagickStrToD(const char *start,char **end,double *value)
+{
+ const char
+ *p;
+
+ char
+ buff[MaxTextExtent],
+ *endptr;
+
+ int
+ i,
+ n=0;
+
+ p=start;
+
+ for (i=0; (*p != 0) && (*p != 'x') && (*p != ',') && (i < MaxTextExtent-2); i++)
+ buff[i]=*p++;
+ buff[i]=0;
+ errno=0;
+ *value=strtod(buff,&endptr);
+ if ((errno == 0) && (buff != endptr))
+ n++;
+ *end=(char *) start+(endptr-buff);
+
+ return (n);
+}
+MagickExport int
+GetMagickDimension(const char *str,double *width,double *height,
+ double *xoff,double *yoff)
+{
+ int
+ n,
+ parsed;
+
+ const char
+ *start=str;
+
+ char
+ *end;
+
+ n=MagickStrToD(start,&end,width);
+ if (n == 0)
+ return n;
+ start=end;
+ if (*start == '%')
+ start++;
+ if ((*start != 'x') && (*start != 'X'))
+ return n;
+ start++;
+ parsed = MagickStrToD(start,&end,height);
+ if (parsed == 0)
+ return n;
+ n += parsed;
+ start=end;
+ if (xoff != (double *) NULL)
+ {
+ if ((*start != '+') && (*start != '-'))
+ return n;
+ parsed = MagickStrToD(start,&end,xoff);
+ if (parsed == 0)
+ return n;
+ n += parsed;
+ if (*(start -1) == '-')
+ *xoff=-*xoff;
+ start=end;
+ }
+ if (yoff != (double *) NULL)
+ {
+ if ((*start != '+') && (*start != '-'))
+ return n;
+ parsed = MagickStrToD(start,&end,yoff);
+ if (parsed == 0)
+ return n;
+ n += parsed;
+ if (*(start -1) == '-')
+ *yoff=-*yoff;
+ start=end;
+ }
+
+ return (n);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t M a g i c k G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickGeometry() is similar to GetGeometry() except that existing
+% 'width', and 'height' input values are modified by the geometry
+% influenced by the meta characters: %, @, !, <, and >, as well as
+% +x, and +y offsets. The geometry string has the form:
+%
+% <width>x<height>{+-}<x>{+-}<y>{%}{@} {!}{<}{>}
+%
+% For example, the string "640x480>" is a valid geometry string.
+%
+% The interpretation of the extra geometry string parameters are as
+% follows:
+% %: (PercentValue) The geometry width and height parameters are
+% interpreted as a percentage of the supplied width and height
+% parameters.
+% @: (AreaValue) The geometry parameter represents the desired total
+% area (e.g. "307520@") or an area equivalent to a specified
+% width x height (e.g. "640x480@"), of the final image.
+% !: (AspectValue) Force the width and height values to be absolute
+% values. The original image aspect ratio is not maintained.
+% <: (LessValue) Update the provided width and height parameters if
+% its dimensions are less than the geometry specification.
+% >: (GreaterValue) Update the provided width and height parameters
+% if its dimensions are greater than the geometry specification.
+% ^: (MinimumValue) Width and height are increased as required to
+% preserve aspect ratio while ensuring that width and height are
+% no less than specified.
+%
+% Any supplied offset parameters are used to adjust the image width,
+% height, and x/y offset values as required to center the scaled image
+% into the region specified by the supplied width and height.
+%
+% If only the width is specified, the width assumes the value and the
+% height is chosen to maintain the aspect ratio of the image. Similarly,
+% if only the height is specified (e.g., -geometry x256), the width is
+% chosen to maintain the aspect ratio.
+%
+% The format of the GetMagickGeometry method is:
+%
+% int GetMagickGeometry(const char *geometry,long *x,long *y,
+% unsigned long *width,unsigned long *height)
+%
+% A description of each parameter follows:
+%
+% o flags: Method GetMagickGeometry returns a bitmask that indicates
+% which of the twelve values (XValue, YValue, WidthValue, HeightValue,
+% XNegative, YNegative, PercentValue, AspectValue, LessValue,
+% GreaterValue, AreaValue, MinimumValue) were located in the geometry
+% string.
+%
+% o image_geometry: Specifies a character string representing the geometry
+% specification.
+%
+% o x,y: A pointer to an integer. The x and y offset as determined by
+% the geometry specification is returned here.
+%
+% o width,height: A pointer to an unsigned integer. The width and height
+% as determined by the geometry specification is returned here.
+%
+%
+*/
+MagickExport int GetMagickGeometry(const char *geometry,long *x,long *y,
+ unsigned long *width,unsigned long *height)
+{
+ int
+ flags;
+
+ long
+ count;
+
+ unsigned long
+ former_height,
+ former_width;
+
+ /*
+ Ensure the image geometry is valid.
+ */
+ assert(x != (long *) NULL);
+ assert(y != (long *) NULL);
+ assert(width != (unsigned long *) NULL);
+ assert(height != (unsigned long *) NULL);
+ if ((geometry == (char *) NULL) || (*geometry == '\0'))
+ return(NoValue);
+ /*
+ Parse geometry using GetGeometry.
+ */
+ former_width=(*width);
+ former_height=(*height);
+ flags=GetGeometry(geometry,x,y,width,height);
+
+ if ((former_width == 0UL) || (former_height == 0UL))
+ return(flags);
+
+#if 0
+ fprintf(stderr,"WidthValue=%u, HeightValue=%u width=%lu, height=%lu\n",
+ flags & WidthValue ? 1 : 0,
+ flags & HeightValue ? 1 : 0,
+ *width,*height);
+#endif
+
+ if (flags & AreaValue) /* @ */
+ {
+ double
+ scale_factor,
+ original_area,
+ target_area;
+
+ MagickBool
+ resize;
+
+ /*
+ Geometry is an area in pixels.
+ */
+ target_area=0.0;
+ if (flags & WidthValue)
+ target_area=(double) (*width);
+ if (flags & HeightValue)
+ target_area *= (double) (*height);
+ original_area=(double) former_width*former_height;
+ resize=MagickFalse;
+ if (flags & GreaterValue)
+ {
+ /* Resize if image area greater than target */
+ if (original_area > target_area)
+ resize=MagickTrue;
+ }
+ else if (flags & LessValue)
+ {
+ /* Resize if image area less than target */
+ if (original_area < target_area)
+ resize=MagickTrue;
+ }
+ else
+ {
+ /* Always resize */
+ resize=MagickTrue;
+ }
+
+ if (resize)
+ {
+ scale_factor=1.0/sqrt(original_area/target_area);
+ *width=(unsigned long) floor(former_width*scale_factor+0.25);
+ *height=(unsigned long) floor(former_height*scale_factor+0.25);
+ }
+ else
+ {
+ *width=former_width;
+ *height=former_height;
+ }
+ }
+ else
+ {
+ /*
+ Deal with width or height being missing from geometry. Supply
+ missing value required to preserve current image aspect ratio.
+ */
+ if (((flags & WidthValue) && !(flags & HeightValue)))
+ *height=(unsigned long) floor(((double) former_height/former_width)*
+ (*width)+0.5);
+ else if ((!(flags & WidthValue) && (flags & HeightValue)))
+ *width=(unsigned long) floor(((double) former_width/former_height)*
+ (*height)+0.5);
+#if 0
+ fprintf(stderr,"Geometry Bounds: %lux%lu\n",*width,*height);
+#endif
+ if (flags & PercentValue)
+ {
+ double
+ x_scale,
+ y_scale;
+
+ /*
+ Geometry is a percentage of the image size.
+ */
+ x_scale=(*width);
+ y_scale=(*height);
+ count=GetMagickDimension(geometry,&x_scale,&y_scale,NULL,NULL);
+ if (count == 1)
+ y_scale=x_scale;
+ *width=(unsigned long) floor((x_scale*former_width/100.0)+0.5);
+ *height=(unsigned long) floor((y_scale*former_height/100.0)+0.5);
+ former_width=(*width);
+ former_height=(*height);
+ }
+ if (!(flags & AspectValue) && /* ! */
+ ((*width != former_width) || (*height != former_height)))
+ {
+ double
+ scale_factor;
+
+ /*
+ Respect aspect ratio of the image but assure that it is no
+ larger than specified.
+ */
+ if ((former_width == 0) || (former_height == 0))
+ {
+ scale_factor=1.0;
+ }
+ else
+ {
+ double
+ scale_height,
+ scale_width;
+
+ scale_height=(double) *height/former_height;
+ scale_width=(double) *width/former_width;
+
+ scale_factor=scale_width;
+ if ((flags & MinimumValue) != 0)
+ {
+ /* Width and height are minimum values */
+ if (scale_width < scale_height)
+ scale_factor=scale_height;
+ }
+ else
+ {
+ /* Width and height are maximum values */
+ if (scale_width > scale_height)
+ scale_factor=scale_height;
+ }
+ }
+ *width=(unsigned long) floor(scale_factor*former_width+0.5);
+ *height=(unsigned long) floor(scale_factor*former_height+0.5);
+ }
+ if (flags & GreaterValue) /* > */
+ {
+ if (former_width < *width)
+ *width=former_width;
+ if (former_height < *height)
+ *height=former_height;
+ }
+ if (flags & LessValue) /* < */
+ {
+ if (former_width > *width)
+ *width=former_width;
+ if (former_height > *height)
+ *height=former_height;
+ }
+ }
+
+ return(flags);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t P a g e G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetPageGeometry() returns a new geometry string, with any embedded page
+% mneumonic in the original geometry string replaced with the equivalent
+% size in picas. For example, the geometry string "A4+36+36" is translated
+% to "595x842+36+36" in the returned value.
+%
+% The format of the GetPageGeometry method is:
+%
+% char *GetPageGeometry(const char *page_geometry)
+%
+% A description of each parameter follows.
+%
+% o page_geometry: The geometry string to translate.
+%
+%
+*/
+MagickExport char *GetPageGeometry(const char *page_geometry)
+{
+#define PAGE_SIZE(name, geometry) { name, sizeof(name)-1, geometry }
+ static const struct
+ {
+ char
+ *name;
+
+ size_t
+ name_length;
+
+ char
+ *geometry;
+ }
+ PageSizes[] =
+ {
+ PAGE_SIZE("4x6", "288x432"),
+ PAGE_SIZE("5x7", "360x504"),
+ PAGE_SIZE("7x9", "504x648"),
+ PAGE_SIZE("8x10", "576x720"),
+ PAGE_SIZE("9x11", "648x792"),
+ PAGE_SIZE("9x12", "648x864"),
+ PAGE_SIZE("10x13", "720x936"),
+ PAGE_SIZE("10x14", "720x1008"),
+ PAGE_SIZE("11x17", "792x1224"),
+ PAGE_SIZE("A0", "2384x3370"),
+ PAGE_SIZE("A1", "1684x2384"),
+ PAGE_SIZE("A10", "73x105"),
+ PAGE_SIZE("A2", "1191x1684"),
+ PAGE_SIZE("A3", "842x1191"),
+ PAGE_SIZE("A4", "595x842"),
+ PAGE_SIZE("A4SMALL", "595x842"),
+ PAGE_SIZE("A5", "420x595"),
+ PAGE_SIZE("A6", "297x420"),
+ PAGE_SIZE("A7", "210x297"),
+ PAGE_SIZE("A8", "148x210"),
+ PAGE_SIZE("A9", "105x148"),
+ PAGE_SIZE("ARCHA", "648x864"),
+ PAGE_SIZE("ARCHB", "864x1296"),
+ PAGE_SIZE("ARCHC", "1296x1728"),
+ PAGE_SIZE("ARCHD", "1728x2592"),
+ PAGE_SIZE("ARCHE", "2592x3456"),
+ PAGE_SIZE("B0", "2920x4127"),
+ PAGE_SIZE("B1", "2064x2920"),
+ PAGE_SIZE("B10", "91x127"),
+ PAGE_SIZE("B2", "1460x2064"),
+ PAGE_SIZE("B3", "1032x1460"),
+ PAGE_SIZE("B4", "729x1032"),
+ PAGE_SIZE("B5", "516x729"),
+ PAGE_SIZE("B6", "363x516"),
+ PAGE_SIZE("B7", "258x363"),
+ PAGE_SIZE("B8", "181x258"),
+ PAGE_SIZE("B9", "127x181"),
+ PAGE_SIZE("C0", "2599x3676"),
+ PAGE_SIZE("C1", "1837x2599"),
+ PAGE_SIZE("C2", "1298x1837"),
+ PAGE_SIZE("C3", "918x1296"),
+ PAGE_SIZE("C4", "649x918"),
+ PAGE_SIZE("C5", "459x649"),
+ PAGE_SIZE("C6", "323x459"),
+ PAGE_SIZE("C7", "230x323"),
+ PAGE_SIZE("EXECUTIVE", "540x720"),
+ PAGE_SIZE("FLSA", "612x936"),
+ PAGE_SIZE("FLSE", "612x936"),
+ PAGE_SIZE("FOLIO", "612x936"),
+ PAGE_SIZE("HALFLETTER", "396x612"),
+ PAGE_SIZE("ISOB0", "2835x4008"),
+ PAGE_SIZE("ISOB1", "2004x2835"),
+ PAGE_SIZE("ISOB10", "88x125"),
+ PAGE_SIZE("ISOB2", "1417x2004"),
+ PAGE_SIZE("ISOB3", "1001x1417"),
+ PAGE_SIZE("ISOB4", "709x1001"),
+ PAGE_SIZE("ISOB5", "499x709"),
+ PAGE_SIZE("ISOB6", "354x499"),
+ PAGE_SIZE("ISOB7", "249x354"),
+ PAGE_SIZE("ISOB8", "176x249"),
+ PAGE_SIZE("ISOB9", "125x176"),
+ PAGE_SIZE("LEDGER", "1224x792"),
+ PAGE_SIZE("LEGAL", "612x1008"),
+ PAGE_SIZE("LETTER", "612x792"),
+ PAGE_SIZE("LETTERSMALL", "612x792"),
+ PAGE_SIZE("QUARTO", "610x780"),
+ PAGE_SIZE("STATEMENT", "396x612"),
+ PAGE_SIZE("TABLOID", "792x1224"),
+ };
+
+ char
+ page[MaxTextExtent];
+
+ register size_t
+ i;
+
+ assert(page_geometry != (char *) NULL);
+ strlcpy(page,page_geometry,MaxTextExtent);
+ for (i=0; i < sizeof(PageSizes)/sizeof(PageSizes[0]); i++)
+ if (LocaleNCompare(PageSizes[i].name,page_geometry,
+ PageSizes[i].name_length) == 0)
+ {
+ int
+ flags;
+
+ RectangleInfo
+ geometry;
+
+ /*
+ Replace mneumonic with the equivalent size in dots-per-inch.
+ */
+ FormatString(page,"%s%.80s", PageSizes[i].geometry,
+ page_geometry+PageSizes[i].name_length);
+ flags=GetGeometry(page,&geometry.x,&geometry.y,&geometry.width,
+ &geometry.height);
+ if (!(flags & GreaterValue))
+ (void) strcat(page,">");
+ break;
+ }
+ return (AcquireString(page));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t P a t h C o m p o n e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetPathComponent returns the parent directory name, filename,
+% basename, or extension of a file path. File paths are in the form:
+%
+% magick:base.ext[subimage]
+%
+% Similar to
+%
+% jpg:bar
+% jpg:foo.bar
+% pdf:foo.pdf[2-3]
+% foo.pdf[2-3]
+% C:\path\foo.bar
+% /path/foo.bar
+% pdf:C:\path\foo.pdf[2-3]
+%
+% Note that Windows drive letters may be part of paths on Windows systems
+% and such paths include a colon. Path components in real file paths may
+% include a colon and the file might not exist yet (or ever) so testing
+% for it is not reliable. This means that determination of the "magick"
+% part is ambiguous and not reliable.
+%
+% The format of the GetPathComponent function is:
+%
+% GetPathComponent(const char *path,PathType type,char *component)
+%
+% A description of each parameter follows:
+%
+% o path: Specifies a pointer to a character array that contains the
+% file path.
+%
+% o type: Specififies which file path component to return (RootPath,
+% HeadPath, TailPath, BasePath, ExtensionPath, MagickPath,
+% SubImagePath, or FullPath).
+%
+% o component: The selected file path component is returned here.
+%
+*/
+static inline unsigned int IsFrame(const char *point)
+{
+ char
+ *p;
+
+ long
+ long_val;
+
+ long_val = strtol(point,&p,10);
+ (void) long_val;
+ return(p != point);
+}
+
+MagickExport void GetPathComponent(const char *path,PathType type,
+ char *component)
+{
+ register char
+ *p;
+
+ char
+ magick[MaxTextExtent],
+ subimage[MaxTextExtent];
+
+ /*
+ Get basename of client.
+ */
+ assert(path != (const char *) NULL);
+ assert(component != (const char *) NULL);
+ if (strlcpy(component,path,MaxTextExtent) >= MaxTextExtent)
+ MagickFatalError2(ResourceLimitFatalError,"Path buffer overflow",
+ path);
+ if (*path == '\0')
+ return;
+ subimage[0]=magick[0]='\0';
+
+ /*
+ Remove magic and subimage spec. from the path to make
+ it easier to extract filename parts.
+ */
+ for (p=component; (*p != '\0') && (*p != ':'); p++)
+ ;
+ if (*p == ':')
+ {
+ (void) strncpy(magick,component,(size_t)(p-component)+1);
+ magick[p-component+1]='\0';
+ if (IsMagickConflict(magick))
+ {
+ magick[0]='\0';
+ }
+ else
+ {
+ register char
+ *q;
+
+ /*
+ Safe-copy the remaining component part on top of the magic part.
+ */
+ magick[p-component]='\0';
+ p++;
+ q=component;
+ while ((*q++=*p++))
+ ;
+ }
+ }
+
+ p=component+strlen(component);
+ if ((p > component) && (*--p == ']'))
+ {
+ /* Look for a '[' matching the ']' */
+ p--;
+ while ((p > component) &&
+ (*p != '[') &&
+ (strchr("0123456789xX,-+ ", (int)(unsigned char)*p) != 0) )
+ p--;
+
+ /* Copy to subimage and remove from component */
+ if ((p > component) && (*p == '[') && IsFrame(p+1))
+ {
+ (void) strlcpy(subimage, p,sizeof(subimage));
+ *p='\0';
+ }
+ }
+
+ /* first locate the spot were the filename begins */
+ for (p=component+strlen(component); p > component; p--)
+ if (IsBasenameSeparator(*p))
+ break;
+
+ switch (type)
+ {
+ case MagickPath:
+ {
+ /* this only includes the magick override prefix (if any) */
+ (void) strlcpy(component,magick,MaxTextExtent);
+ break;
+ }
+ case SubImagePath:
+ {
+ /* this returns only the subimage specification, including
+ bracketing '[]', (if any) */
+ (void) strlcpy(component,subimage,MaxTextExtent);
+ break;
+ }
+ case FullPath:
+ {
+ /* this returns the full path except magic and sub-image spec. */
+ break;
+ }
+ case RootPath:
+ {
+ /* this returns the path including the file part with no extension */
+ for (p=component+strlen(component); p > component; p--)
+ if (*p == '.')
+ break;
+ if (*p == '.')
+ *p='\0';
+ break;
+ }
+ case HeadPath:
+ {
+ /* this returns the path only with no trailing separator */
+ *p='\0';
+ break;
+ }
+ case TailPath:
+ {
+ /* this returns the filename and extension only */
+ if (IsBasenameSeparator(*p))
+ {
+ char
+ scratch[MaxTextExtent];
+
+ (void) strlcpy(scratch,p+1,MaxTextExtent);
+ (void) strlcpy(component,scratch,MaxTextExtent);
+ }
+ break;
+ }
+ case BasePath:
+ {
+ /* this returns just the filename with no extension */
+ if (IsBasenameSeparator(*p))
+ {
+ char
+ scratch[MaxTextExtent];
+
+ (void) strlcpy(scratch,p+1,MaxTextExtent);
+ (void) strlcpy(component,scratch,MaxTextExtent);
+ }
+ for (p=component+strlen(component); p > component; p--)
+ if (*p == '.')
+ {
+ *p='\0';
+ break;
+ }
+ break;
+ }
+ case ExtensionPath:
+ {
+ /* this returns the file extension only */
+ if (IsBasenameSeparator(*p))
+ {
+ char
+ scratch[MaxTextExtent];
+
+ (void) strlcpy(scratch,p+1,MaxTextExtent);
+ (void) strlcpy(component,scratch,MaxTextExtent);
+ }
+ for (p=component+strlen(component); p > component; p--)
+ if (*p == '.')
+ break;
+ *component='\0';
+ if (*p == '.')
+ {
+ char
+ scratch[MaxTextExtent];
+
+ (void) strlcpy(scratch,p+1,MaxTextExtent);
+ (void) strlcpy(component,scratch,MaxTextExtent);
+ }
+ break;
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ G e t T o k e n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GetToken gets a token from the token stream. A token is defined
+% as sequence of characters delimited by whitespace (e.g. clip-path), a
+% sequence delimited with quotes (.e.g "Quote me"), or a sequence enclosed
+% in parenthesis (e.g. rgb(0,0,0)). The output to token is constrained to
+% not overflow a buffer of size MaxTextExtent so it should be allocated with
+% that size.
+%
+% The format of the GetToken method is:
+%
+% void GetToken(const char *start,char **end,char *token)
+%
+% A description of each parameter follows:
+%
+% o start: the start of the token sequence.
+%
+% o end: point to the end of the token sequence (may be NULL).
+%
+% o token: copy the token to this buffer.
+%
+%
+*/
+MagickExport void GetToken(const char *start,char **end,char *token)
+{
+ (void) MagickGetToken(start,end,token, MaxTextExtent);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G l o b E x p r e s s i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method GlobExpression returns True if the expression matches the pattern.
+% The pattern specification syntax is roughly similar to that supported by
+% POSIX.2 glob().
+%
+% Please note that there is a conflict between glob patterns and subimage
+% specifications. For example, video.mpg[50] or video.mpg[50-75] might
+% refer to video.mpg (page 51, or pages 51-76) or there might be a file
+% named 'video.mpg[50]'. The IsSubimage() function is used to quickly test
+% if the specification may be a subimage specification. If the pattern is
+% ultimately determined to be a subimage specification, then globbing is
+% not performed.
+%
+%
+% The format of the GlobExpression function is:
+%
+% int GlobExpression(const char *expression,const char *pattern)
+%
+% A description of each parameter follows:
+%
+% o expression: Specifies a pointer to a text string containing a file name.
+%
+% o pattern: Specifies a pointer to a text string containing a pattern.
+% Patterns supported are roughly equivalent to those supported by
+% POSIX.2 glob().
+%
+%
+*/
+MagickExport int GlobExpression(const char *expression,const char *pattern)
+{
+ unsigned int
+ done;
+
+ /*
+ Return on empty pattern or '*'.
+ */
+ if (pattern == (char *) NULL)
+ return(True);
+ if (strlen(pattern) == 0)
+ return(True);
+ if (LocaleCompare(pattern,"*") == 0)
+ return(True);
+ /*
+ Evaluate glob expression.
+ */
+ done=False;
+ while ((*pattern != '\0') && !done)
+ {
+ if (*expression == '\0')
+ if ((*pattern != '{') && (*pattern != '*'))
+ break;
+ switch (*pattern)
+ {
+ case '\\':
+ {
+ pattern++;
+ if (*pattern != '\0')
+ pattern++;
+ break;
+ }
+ case '*':
+ {
+ int
+ status;
+
+ pattern++;
+ status=False;
+ while ((*expression != '\0') && !status)
+ status=GlobExpression((char *) expression++,pattern);
+ if (status)
+ {
+ while (*expression != '\0')
+ expression++;
+ while (*pattern != '\0')
+ pattern++;
+ }
+ break;
+ }
+ case '[':
+ {
+ char
+ c;
+
+ pattern++;
+ for ( ; ; )
+ {
+ if ((*pattern == '\0') || (*pattern == ']'))
+ {
+ done=True;
+ break;
+ }
+ if (*pattern == '\\')
+ {
+ pattern++;
+ if (*pattern == '\0')
+ {
+ done=True;
+ break;
+ }
+ }
+ if (*(pattern+1) == '-')
+ {
+ c=(*pattern);
+ pattern+=2;
+ if (*pattern == ']')
+ {
+ done=True;
+ break;
+ }
+ if (*pattern == '\\')
+ {
+ pattern++;
+ if (*pattern == '\0')
+ {
+ done=True;
+ break;
+ }
+ }
+ if ((*expression < c) || (*expression > *pattern))
+ {
+ pattern++;
+ continue;
+ }
+ }
+ else
+ if (*pattern != *expression)
+ {
+ pattern++;
+ continue;
+ }
+ pattern++;
+ while ((*pattern != ']') && (*pattern != '\0'))
+ {
+ if ((*pattern == '\\') && (*(pattern+1) != '\0'))
+ pattern++;
+ pattern++;
+ }
+ if (*pattern != '\0')
+ {
+ pattern++;
+ expression++;
+ }
+ break;
+ }
+ break;
+ }
+ case '?':
+ {
+ pattern++;
+ expression++;
+ break;
+ }
+ case '{':
+ {
+ int
+ match;
+
+ register const char
+ *p;
+
+ pattern++;
+ while ((*pattern != '}') && (*pattern != '\0'))
+ {
+ p=expression;
+ match=True;
+ while ((*p != '\0') && (*pattern != '\0') &&
+ (*pattern != ',') && (*pattern != '}') && match)
+ {
+ if (*pattern == '\\')
+ pattern++;
+ match=(*pattern == *p);
+ p++;
+ pattern++;
+ }
+ if (*pattern == '\0')
+ {
+ match=False;
+ done=True;
+ break;
+ }
+ else
+ if (match)
+ {
+ expression=p;
+ while ((*pattern != '}') && (*pattern != '\0'))
+ {
+ pattern++;
+ if (*pattern == '\\')
+ {
+ pattern++;
+ if (*pattern == '}')
+ pattern++;
+ }
+ }
+ }
+ else
+ {
+ while ((*pattern != '}') && (*pattern != ',') &&
+ (*pattern != '\0'))
+ {
+ pattern++;
+ if (*pattern == '\\')
+ {
+ pattern++;
+ if ((*pattern == '}') || (*pattern == ','))
+ pattern++;
+ }
+ }
+ }
+ if (*pattern != '\0')
+ pattern++;
+ }
+ break;
+ }
+ default:
+ {
+ if (*expression != *pattern)
+ done=True;
+ else
+ {
+ expression++;
+ pattern++;
+ }
+ }
+ }
+ }
+ while ((*pattern != '\0') && (*pattern == '*'))
+ pattern++;
+ return((*expression == '\0') && (*pattern == '\0'));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s A c c e s s i b l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsAccessible() returns MagickTrue if the file as defined by path exists
+% and is readable by the user.
+%
+% The format of the IsAccessible method is:
+%
+% MagickBool IsAccessible(const char *path)
+%
+% A description of each parameter follows.
+%
+% o status: Method IsAccessible returns MagickTrue if the file as defined by
+% path exists and is readable by the user, otherwise MagickFalse is returned.
+%
+% o path: A pointer to an array of characters containing the path.
+%
+%
+*/
+MagickExport MagickBool IsAccessible(const char *path)
+{
+ if ((path == (const char *) NULL) || (*path == '\0'))
+ return(MagickFalse);
+
+ if ((access(path,R_OK)) != 0)
+ {
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Tried: %.1024s [%.1024s]",path,strerror(errno));
+ return(MagickFalse);
+ }
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Found: %.1024s",path);
+ return (MagickTrue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s A c c e s s i b l e N o L o g g i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsAccessibleNoLogging() returns MagickTrue if the file as defined by path
+% exists and is accessable by the user. This version is used internally to
+% avoid using the error logging of the normal version.
+%
+% The format of the IsAccessibleNoLogging method is:
+%
+% MagickBool IsAccessibleNoLogging(const char *path)
+%
+% A description of each parameter follows.
+%
+% o status: Method IsAccessibleNoLogging returns MagickTrue if the file as
+% defined by path exists and is a regular file, otherwise Magick False is
+% returned.
+%
+% o path: A pointer to an array of characters containing the path.
+%
+%
+*/
+MagickExport MagickBool IsAccessibleNoLogging(const char *path)
+{
+ if ((path == (const char *) NULL) || (*path == '\0'))
+ return(MagickFalse);
+
+ if ((access(path,R_OK)) != 0)
+ return(MagickFalse);
+ return (MagickTrue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s A c c e s s i b l e A n d N o t E m p t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsAccessibleAndNotEmpty() returns MagickTrue if the file as defined by path
+% exists, is a regular file, and contains at least one byte of data.
+%
+% The format of the IsAccessibleAndNotEmpty method is:
+%
+% MagickBool IsAccessibleAndNotEmpty(const char *path)
+%
+% A description of each parameter follows.
+%
+% o status: Method IsAccessibleAndNotEmpty returns MagickTrue if the file as
+% defined by path exists, is a regular file, and contains content,
+% otherwise MagickFalse is returned.
+%
+% o path: A pointer to an array of characters containing the path.
+%
+%
+*/
+MagickExport MagickBool IsAccessibleAndNotEmpty(const char *path)
+{
+ int
+ status;
+
+ MagickStatStruct_t
+ file_info;
+
+ if ((path == (const char *) NULL) || (*path == '\0'))
+ return(MagickFalse);
+ status=MagickStat(path,&file_info);
+
+ if ((status == 0) && S_ISREG(file_info.st_mode) && (file_info.st_size > 0))
+ return (MagickTrue);
+
+ return (MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I s D i r e c t o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsDirectory() returns -1 if the path does not exist, 0 if the
+% path represents a file, and 1 if the path represents a directory.
+%
+% The format of the IsDirectory method is:
+%
+% int IsDirectory(const char *path)
+%
+% A description of each parameter follows.
+%
+% o status: Method IsDirectory returns -1 if the path does not exist,
+% 0 if the path represents a file, and 1 if the path represents
+% a directory.
+%
+% o path: Path to file or directory.
+%
+%
+*/
+static int IsDirectory(const char *path)
+{
+ MagickStatStruct_t
+ file_info;
+
+ if ((path == (const char *) NULL) || (*path == '\0'))
+ return(False);
+
+ if ((MagickStat(path,&file_info)) == 0)
+ {
+ if (S_ISREG(file_info.st_mode))
+ return 0;
+ if (S_ISDIR(file_info.st_mode))
+ return 1;
+ }
+ return -1;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ I s G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method IsGeometry returns MagickTrue if the geometry specification is valid
+% as determined by GetGeometry.
+%
+% The format of the IsGeometry method is:
+%
+% MagickBool IsGeometry(const char *geometry)
+%
+% A description of each parameter follows:
+%
+% o status: Method IsGeometry returns MagickTrue if the geometry specification
+% is valid otherwise MagickFalse is returned.
+%
+% o geometry: This string is the geometry specification.
+%
+%
+*/
+MagickExport MagickBool IsGeometry(const char *geometry)
+{
+ long
+ x,
+ y;
+
+ unsigned int
+ flags;
+
+ unsigned long
+ height,
+ width;
+
+ if (geometry == (const char *) NULL)
+ return(False);
+ flags=GetGeometry(geometry,&x,&y,&width,&height);
+ return(flags != NoValue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
++ I s G l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsGlob() returns MagickTrue if the path specification contains a globbing
+% pattern as supported by GlobExpression(). Glob patterns supported are
+% roughly equivalent to those supported by POSIX.2 glob().
+%
+% The format of the IsGlob method is:
+%
+% MagickBool IsGlob(const char *path)
+%
+% A description of each parameter follows:
+%
+% o status: Returns MagickTrue if the path specification contains
+% a globbing patten.
+%
+% o path: The path.
+%
+%
+*/
+MagickExport MagickBool IsGlob(const char *path)
+{
+ register const char
+ *p;
+
+ MagickBool
+ status = MagickFalse;
+
+ for (p = path; *p != '\0'; p++)
+ {
+ switch (*p)
+ {
+ case '*':
+ case '?':
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ {
+ status = MagickTrue;
+ break;
+ }
+ }
+ }
+
+ return status ;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I s W r i t a b l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% IsWritable() returns True if the file as defined by path exists
+% and is writeable by the user.
+%
+% The format of the IsWriteable method is:
+%
+% MagickBool IsWriteable(const char *path)
+%
+% A description of each parameter follows.
+%
+% o status: Method IsWriteable returns MagickTrue if the file as defined
+% by path exists and is writeable by the user, otherwise MagickFalse is
+% returned.
+%
+% o path: A pointer to an array of characters containing the path.
+%
+%
+*/
+MagickExport MagickBool IsWriteable(const char *path)
+{
+ if ((path == (const char *) NULL) || (*path == '\0'))
+ return(MagickFalse);
+
+ if ((access(path,W_OK)) != 0)
+ {
+ return(MagickFalse);
+ }
+ return (MagickTrue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L i s t F i l e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method ListFiles reads the directory specified and returns a list
+% of filenames contained in the directory sorted in ascending alphabetic
+% order.
+%
+% The format of the ListFiles function is:
+%
+% char **ListFiles(const char *directory,const char *pattern,
+% long *number_entries)
+%
+% A description of each parameter follows:
+%
+% o filelist: Method ListFiles returns a list of filenames contained
+% in the directory. If the directory specified cannot be read or it is
+% a file a NULL list is returned.
+%
+% o directory: Specifies a pointer to a text string containing a directory
+% name.
+%
+% o pattern: Specifies a pointer to a text string containing a pattern.
+%
+% o number_entries: This integer returns the number of filenames in the
+% list.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int FileCompare(const void *x,const void *y)
+{
+ register char
+ **p,
+ **q;
+
+ p=(char **) x;
+ q=(char **) y;
+ return(LocaleCompare(*p,*q));
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+MagickExport char **ListFiles(const char *directory,const char *pattern,
+ long *number_entries)
+{
+ char
+ **filelist,
+ filename[MaxTextExtent];
+
+ DIR
+ *current_directory;
+
+ int
+ status;
+
+ struct dirent
+ *entry;
+
+ unsigned int
+ max_entries;
+
+ /*
+ Open directory.
+ */
+ assert(directory != (const char *) NULL);
+ assert(pattern != (char *) NULL);
+ assert(number_entries != (long *) NULL);
+ *number_entries=0;
+ status=chdir(directory);
+ if (status != 0)
+ return((char **) NULL);
+ if (getcwd(filename,MaxTextExtent-1) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+ current_directory=opendir(filename);
+ if (current_directory == (DIR *) NULL)
+ return((char **) NULL);
+ if (chdir(filename) != 0)
+ {
+ (void) closedir(current_directory);
+ return((char **) NULL);
+ }
+ /*
+ Allocate filelist.
+ */
+ max_entries=2048U;
+ filelist=MagickAllocateArray(char **,max_entries,sizeof(char *));
+ if (filelist == (char **) NULL)
+ {
+ (void) closedir(current_directory);
+ return((char **) NULL);
+ }
+ /*
+ Save the current and change to the new directory.
+ */
+ entry=readdir(current_directory);
+ while (entry != (struct dirent *) NULL)
+ {
+ if (*entry->d_name == '.')
+ {
+ entry=readdir(current_directory);
+ continue;
+ }
+ if ((IsDirectory(entry->d_name) > 0) ||
+ GlobExpression(entry->d_name,pattern))
+ {
+ if (*number_entries >= (int) max_entries)
+ {
+ /*
+ Extend the file list.
+ */
+ max_entries<<=1;
+ MagickReallocMemory(char **,filelist,max_entries*sizeof(char *));
+ if (filelist == (char **) NULL)
+ {
+ (void) closedir(current_directory);
+ /*
+ We simply bail here since our memory reallocator has
+ just leaked lots of memory and returning does not
+ solve the problem.
+ */
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateString);
+ }
+ }
+ {
+ size_t
+ entry_length;
+
+ entry_length=strlen(entry->d_name)+1;
+ if (IsDirectory(entry->d_name) > 0)
+ entry_length+=strlen(DirectorySeparator);
+
+ filelist[*number_entries]=MagickAllocateMemory(char *,entry_length);
+ if (filelist[*number_entries] == (char *) NULL)
+ {
+ break;
+ }
+ (void) strlcpy(filelist[*number_entries],entry->d_name,entry_length);
+ if (IsDirectory(entry->d_name) > 0)
+ (void) strlcat(filelist[*number_entries],DirectorySeparator,entry_length);
+ }
+ (*number_entries)++;
+ }
+ entry=readdir(current_directory);
+ }
+ (void) closedir(current_directory);
+ /*
+ Sort filelist in ascending order.
+ */
+ qsort((void *) filelist,*number_entries,sizeof(filelist[0]),FileCompare);
+ return(filelist);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L o c a l e C o m p a r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method LocaleCompare performs a case-insensitive comparison of two strings
+% byte-by-byte, according to the ordering of the current locale encoding.
+% LocaleCompare returns an integer greater than, equal to, or less than 0,
+% if the string pointed to by p is greater than, equal to, or less than the
+% string pointed to by q respectively. The sign of a non-zero return value
+% is determined by the sign of the difference between the values of the first
+% pair of bytes that differ in the strings being compared.
+%
+% The format of the LocaleCompare method is:
+%
+% int LocaleCompare(const char *p,const char *q)
+%
+% A description of each parameter follows:
+%
+% o p: A pointer to a character string.
+%
+% o q: A pointer to a character string to compare to p.
+%
+%
+*/
+MagickExport int LocaleCompare(const char *p,const char *q)
+{
+ int
+ result=0;
+
+ register size_t
+ i;
+
+ if (p == (char *) NULL)
+ result=-1;
+ else if (q == (char *) NULL)
+ result=1;
+ else
+ for (i=0; ; i++)
+ {
+ if (((result=
+ AsciiMap[(unsigned int) ((unsigned char *) p)[i] & 0xff] -
+ AsciiMap[(unsigned int) ((unsigned char *) q)[i] & 0xff]) != 0)
+ || (p[i] == 0) || (q[i] == 0))
+ break;
+ }
+ return result;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L o c a l e L o w e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method LocaleLower transforms all of the characters in the supplied
+% null-terminated string, changing all uppercase letters to lowercase.
+%
+% The format of the LocaleLower method is:
+%
+% void LocaleLower(char *string)
+%
+% A description of each parameter follows:
+%
+% o string: A pointer to the string to convert to lower-case Locale.
+%
+%
+*/
+MagickExport void LocaleLower(char *string)
+{
+ register char
+ *q;
+
+ assert(string != (char *) NULL);
+ for (q=string; *q != '\0'; q++)
+ *q=(char) tolower((int) *q);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L o c a l e N C o m p a r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method LocaleNCompare performs a case-insensitive comparison of two
+% strings byte-by-byte, according to the ordering of the current locale
+% encoding. LocaleNCompare returns an integer greater than, equal to, or
+% less than 0, if the string pointed to by p is greater than, equal to, or
+% less than the string pointed to by q respectively. The sign of a non-zero
+% return value is determined by the sign of the difference between the
+% values of the first pair of bytes that differ in the strings being
+% compared. The LocaleNCompare method makes the same comparison as
+% LocaleCompare but looks at a maximum of n bytes. Bytes following a
+% null byte are not compared.
+%
+% The format of the LocaleNCompare method is:
+%
+% int LocaleNCompare(const char *p,const char *q,const size_t n)
+%
+% A description of each parameter follows:
+%
+% o p: A pointer to a character string.
+%
+% o q: A pointer to a character string to compare to p.
+%
+% o length: The number of characters to compare in strings p & q.
+%
+%
+*/
+MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
+{
+ int
+ result=0;
+
+ register size_t
+ i;
+
+ if (p == (char *) NULL)
+ result = -1;
+ else if (q == (char *) NULL)
+ result = 1;
+ else
+ for (i=0; i < length; i++)
+ {
+ if (((result=
+ AsciiMap[(unsigned int) ((unsigned char *) p)[i] & 0xff] -
+ AsciiMap[(unsigned int) ((unsigned char *) q)[i] & 0xff]) != 0)
+ || (p[i] == 0) || (q[i] == 0))
+ break;
+ }
+ return result;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% L o c a l e U p p e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method LocaleUpper transforms all of the characters in the supplied
+% null-terminated string, changing all lowercase letters to uppercase.
+%
+% The format of the LocaleUpper method is:
+%
+% void LocaleUpper(char *string)
+%
+% A description of each parameter follows:
+%
+% o string: A pointer to the string to convert to upper-case Locale.
+%
+%
+*/
+MagickExport void LocaleUpper(char *string)
+{
+ register char
+ *q;
+
+ assert(string != (char *) NULL);
+ for (q=string; *q != '\0'; q++)
+ *q=(char) toupper((int) *q);
+}
+
+MagickExport MagickPassFail MagickAtoFChk(const char *str, double *value)
+{
+ char *estr=0;
+ *value=strtod(str,&estr);
+ if (str == estr)
+ *value=0.0;
+ return (str == estr ? MagickFail : MagickPass);
+}
+
+MagickExport MagickPassFail MagickAtoIChk(const char *str, int *value)
+{
+ char *estr=0;
+ long lvalue;
+ lvalue=strtol(str,&estr, 10);
+ if ((str == estr) || ((int) lvalue != lvalue))
+ lvalue=0;
+ *value=(int) lvalue;
+ return (str == estr ? MagickFail : MagickPass);
+}
+
+MagickExport MagickPassFail MagickAtoUIChk(const char *str, unsigned int *value)
+{
+ char *estr=0;
+ long lvalue;
+ lvalue=strtol(str,&estr, 10);
+ if ((str == estr) || ((long) ((unsigned int) lvalue) != lvalue))
+ lvalue=0U;
+ *value=(unsigned int) lvalue;
+ return (((str == estr) || ((long) ((unsigned int) lvalue) != lvalue))
+ ? MagickFail : MagickPass);
+}
+
+MagickExport MagickPassFail MagickAtoLChk(const char *str, long *value)
+{
+ char *estr=0;
+ *value=strtol(str,&estr, 10);
+ if (str == estr)
+ *value=0L;
+ return (str == estr ? MagickFail : MagickPass);
+}
+
+MagickExport MagickPassFail MagickAtoULChk(const char *str, unsigned long *value)
+{
+ char *estr=0;
+ long lvalue;
+ lvalue=strtol(str,&estr, 10);
+ if ((str == estr) || ((long) ((unsigned long) lvalue) != lvalue))
+ lvalue=0L;
+ *value=(unsigned long) lvalue;
+ return (((str == estr) || ((long) ((unsigned long) lvalue) != lvalue)) ?
+ MagickFail : MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F m i n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickFmin emulates C'99 fmin(), which returns the minimum of two
+% double values. This is implemented as a function rather than a macro.
+%
+% The format of the MagickFmin method is:
+%
+% double MagickFmin(const double x, const double y)
+%
+% A description of each parameter follows.
+%
+% o x: first input value
+%
+% o y: second input value
+%
+% o returns: minimum of values x or y
+%
+%
+*/
+double MagickFmin(const double x, const double y)
+{
+ return Min(x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F m a x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickFmax emulates C'99 fmax(), which returns the maximum of two
+% double values. This is implemented as a function rather than a macro.
+%
+% The format of the MagickFmax method is:
+%
+% double MagickFmax(const double x, const double y)
+%
+% A description of each parameter follows.
+%
+% o x: first input value
+%
+% o y: second input value
+%
+% o returns: maximum of values x or y
+%
+%
+*/
+double MagickFmax(const double x, const double y)
+{
+ return Max(x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F o r m a t S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickFormatString prints formatted output of a variable
+% argument list buffer, limiting its output to a specified buffer size.
+%
+% The format of the MagickFormatString method is:
+%
+% void MagickFormatString(char *string,const size_t length,
+% const char *format,...)
+%
+% A description of each parameter follows.
+%
+% o string: Method FormatString returns the formatted string in this
+% character buffer. Buffer must be at least MaxTextExtent characters
+% in size.
+%
+% o length: Maximum number of characters to write into buffer, not
+% including a terminating null byte. The result is always terminated
+% with a null byte.
+%
+% o format: A string describing the format to use to write the remaining
+% arguments.
+%
+%
+*/
+MagickExport void MagickFormatStringList(char *string,
+ const size_t length,
+ const char *format,
+ va_list operands)
+{
+#if defined(HAVE_VSNPRINTF)
+ (void) vsnprintf(string,length,format,operands);
+#else
+ (void) vsprintf(string,format,operands);
+#endif
+}
+MagickExport void MagickFormatString(char *string,
+ const size_t length,
+ const char *format,...)
+{
+ va_list
+ operands;
+
+ va_start(operands,format);
+ MagickFormatStringList(string, length, format, operands);
+ va_end(operands);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k G e t T o k e n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickGetToken gets a token from the token stream. A token is defined
+% as sequence of characters delimited by whitespace (e.g. clip-path), a
+% sequence delimited with quotes (.e.g "Quote me"), or a sequence enclosed
+% in parenthesis (e.g. rgb(0,0,0)).
+%
+% The format of the MagickGetToken method is:
+%
+% void MagickGetToken(const char *start,char **end,char *token,
+% const size_t buffer_length)
+%
+% A description of each parameter follows:
+%
+% o start: the start of the token sequence.
+%
+% o end: point to the end of the token sequence (may be NULL).
+%
+% o token: copy the token to this buffer.
+%
+% o buffer_length: size of the token buffer. If the token exceeds
+% the buffer size, the token will be truncated, but the
+% parser will still update the end pointer as if the
+% truncation did not occur.
+%
+% o returns: Size of the consumed token, not including a terminating
+% null character. If this is larger or equal to the buffer
+% size then truncation has occured.
+%
+*/
+MagickExport size_t MagickGetToken(const char *start,char **end,char *token,
+ const size_t buffer_length)
+{
+ register char
+ *p;
+
+ register size_t
+ i;
+
+ register size_t
+ length = buffer_length - 1;
+
+ double
+ double_val;
+
+ assert(start != (const char *) NULL);
+ assert(token != (char *) NULL);
+
+ i=0;
+ p=(char *) start;
+
+ if (*p != '\0')
+ {
+ while (isspace((int)(unsigned char) (*p)) && (*p != '\0'))
+ p++;
+ switch (*p)
+ {
+ case '"':
+ case '\'':
+ case '{':
+ {
+ register char
+ escape;
+
+ escape=(*p);
+ if (escape == '{')
+ escape='}';
+ for (p++; *p != '\0'; p++)
+ {
+ if ((*p == '\\') && ((*(p+1) == escape) || (*(p+1) == '\\')))
+ p++;
+ else
+ if (*p == escape)
+ {
+ p++;
+ break;
+ }
+ if (i < length)
+ token[i++]=(*p);
+ }
+ break;
+ }
+ default:
+ {
+ char
+ *q;
+
+ double_val=strtod(p,&q);
+ (void) double_val;
+ if (p != q)
+ {
+ for ( ; p < q; p++)
+ if (i < length)
+ token[i++]=(*p);
+ if (*p == '%')
+ if (i < length)
+ {
+ token[i++]=(*p);
+ p++;
+ }
+ break;
+ }
+ if ((*p != '\0') && !isalpha((int) *p) &&
+ (*p != *DirectorySeparator) &&
+ (*p != '#') && (*p != '<'))
+ {
+ if (i < length)
+ {
+ token[i++]=(*p);
+ p++;
+ }
+ break;
+ }
+ for ( ; *p != '\0'; p++)
+ {
+ if ((isspace((int)(unsigned char) *p) ||
+ (*p == '=')) && (*(p-1) != '\\'))
+ break;
+ if (i < length)
+ token[i++]=(*p);
+ if (*p == '(')
+ {
+ for (p++; *p != '\0'; p++)
+ {
+ if (i < length)
+ token[i++]=(*p);
+ if ((*p == ')') && (*(p-1) != '\\'))
+ break;
+ }
+ }
+ if (*p == '\0')
+ break;
+ }
+ break;
+ }
+ }
+ }
+ token[i]='\0';
+ {
+ char
+ *r;
+
+ /*
+ Parse token in form "url(#%s)"
+ */
+ if ((LocaleNCompare(token,"url(#",5) == 0) &&
+ ((r = strrchr(token,')')) != NULL))
+ {
+ *r='\0';
+ (void) memmove(token,token+5,r-token+1);
+ }
+ }
+ if (end != (char **) NULL)
+ *end=p;
+ return (p-start+1);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R a n d R e e n t r a n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickRandReentrant() is a reentrant version of the standard
+% rand() function but which allows the user to pass a pointer to the
+% 'seed'. Values returned are in the range of 0 - RAND_MAX.
+%
+% This function is deprecated, and scheduled for eventual removal.
+%
+% The format of the MagickRandReentrant method is:
+%
+% int MagickRandReentrant(unsigned int *seed)
+%
+% A description of each parameter follows:
+%
+% o seed: The random sequence seed value. Initialized by the user
+% once (e.g. with output from MagickRandNewSeed()) and then
+% passed via pointer thereafter. If seed is NULL then
+% this function behaves identically to rand(), using the
+% global seed value set via srand().
+%
+*/
+MagickExport int MagickRandReentrant(unsigned int *seed)
+{
+ ARG_NOT_USED(seed);
+
+ return (int) ((double) RAND_MAX*MagickRandomReal()+0.5);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R a n d N e w S e e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickRandNewSeed() returns a semi-random initial seed value for
+% use with MagickRandReentrant() or rand().
+%
+% This function is deprecated, and scheduled for eventual removal.
+%
+% The format of the MagickRandNewSeed method is:
+%
+% unsigned int MagickRandNewSeed(void)
+%
+*/
+MagickExport unsigned int MagickRandNewSeed(void)
+{
+ return (unsigned int) MagickRandomInteger();
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S i z e S t r T o I n t 6 4 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSizeStrToInt64() converts a numeric string expressed using a scaling
+% suffix (e.g. "100K" is 100 kilo) to a 64-bit integer type. Even though
+% this function returns a signed type, it is intended to be used to obtain
+% positive size values so a negative return value indicates an error.
+% Specfically, -1 is returned if there is known to be an conversion error.
+%
+% Binary Prefixes: http://en.wikipedia.org/wiki/Binary_prefix
+%
+% SI Prefixes: http://en.wikipedia.org/wiki/SI_prefix
+%
+% The format of the MagickSizeStrToInt64 method is:
+%
+% magick_int64_t MagickSizeStrToInt64(const char *str,
+% const unsigned int kilo)
+%
+% A description of each parameter follows:
+%
+% o str: Input string to convert
+%
+% o kilo: The unit of "kilo". Should be either 1000 (SI units)
+% or 1024 (Binary units).
+%
+*/
+MagickExport magick_int64_t MagickSizeStrToInt64(const char *str,
+ const unsigned int kilo)
+{
+ char
+ *end;
+
+ magick_int64_t
+ result;
+
+ MagickPassFail
+ status;
+
+ result=-1;
+ end=(char *) NULL;
+ if ((status=MagickStrToInt64(str,&end,&result)) == MagickPass)
+ {
+ int
+ c,
+ mult;
+
+ c='\0';
+ if (end != (char *) NULL)
+ c=*end;
+ mult=0;
+
+ switch (tolower(c))
+ {
+ default: break;
+ case 'k': mult=1; break; /* kilo, 10^3 */
+ case 'm': mult=2; break; /* mega, 10^6 */
+ case 'g': mult=3; break; /* giga, 10^9 */
+ case 't': mult=4; break; /* tera, 10^12 */
+ case 'p': mult=5; break; /* peta, 10^15 */
+ case 'e': mult=6; break; /* exa, 10^18 */
+ }
+
+ while (mult-- > 0)
+ result *= kilo;
+ }
+
+ return result;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S p a w n V P %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSpawnVP() executes an external command with arguments provided by
+% an argument vector. The return status of the executed command is returned
+% if it is executed, or -1 is returned if the command could not be executed.
+% Executed commands will normally return zero if they execute without error.
+%
+% The format of the MagickSpawnVP method is:
+%
+% int MagickSpawnVP(const char *file, char *const argv[])
+%
+% A description of each parameter follows:
+%
+% o file: Name of the command to execute.
+%
+% o argv: Argument vector. First argument in the vector should be
+% the name of the command. The argument vector is terminated
+% via a NULL pointer.
+%
+*/
+MagickExport int
+MagickSpawnVP(const unsigned int verbose,const char *file, char *const argv[])
+{
+ int
+ status;
+
+ char
+ message[MaxTextExtent];
+
+
+ status = -1;
+ message[0]='\0';
+ errno=0;
+
+ assert(file != (const char *) NULL);
+
+ if (strlen(file) == 0)
+ return -1;
+
+ {
+ /*
+ Verify that we are allowed to run this program.
+ */
+ ExceptionInfo
+ exception;
+
+ GetExceptionInfo(&exception);
+ if (MagickConfirmAccess(FileExecuteConfirmAccessMode,argv[0],&exception)
+ == MagickFail)
+ {
+ errno=EPERM;
+ DestroyExceptionInfo(&exception);
+ return -1;
+ }
+ }
+
+#if defined(HAVE_SPAWNVP)
+ {
+ /* int spawnvp(int mode, const char *path, const char * const *argv); */
+ status = spawnvp(_P_WAIT, file, (const char * const *) argv);
+ }
+#else
+ {
+ pid_t
+ child_pid;
+
+ child_pid = fork( );
+ if ( (pid_t)-1 == child_pid)
+ {
+ /* Failed to fork, errno contains reason */
+ status = -1;
+ FormatString(message,"fork failed: %.1024s", strerror(errno));
+ }
+ else if ( 0 == child_pid )
+ {
+ /* We are the child process, exec program with arguments. */
+ status = execvp(file, argv);
+
+ /* If we get here, then execvp must have failed. */
+ (void) fprintf(stderr, "execvp failed, errno = %d (%s)\n",errno,strerror(errno));
+
+ /* If there is an execvp error, then call _exit() */
+ _exit(1);
+ }
+ else
+ {
+ /* We are the parent process, wait for child. */
+ pid_t waitpid_status;
+ int child_status = 0;
+ waitpid_status = waitpid(child_pid, &child_status, 0);
+ if ( (pid_t)-1 == waitpid_status )
+ {
+ /* Waitpid error */
+ status = -1;
+ FormatString(message, "waitpid failed: %.1024s", strerror(errno));
+ }
+ else if ( waitpid_status == child_pid )
+ {
+ /* Status is available for child process */
+ if ( WIFEXITED( child_status ) )
+ {
+ status = WEXITSTATUS( child_status );
+ }
+ else if ( WIFSIGNALED( child_status ) )
+ {
+ int sig_num = WTERMSIG( child_status );
+ status = -1;
+ FormatString(message, "child process quit due to signal %d", sig_num);
+ }
+ }
+ }
+ }
+#endif
+
+ /*
+ Provide a verbose/dignostic message in a form which is easy for
+ the user to understand.
+ */
+ if (verbose || (status != 0))
+ {
+ const char
+ *message_p = (const char *) NULL;
+
+ char
+ *command;
+
+ unsigned int
+ i;
+
+ command = AllocateString((const char*) NULL);
+ for (i = 0; argv[i] != (const char*) NULL; i++)
+ {
+ char
+ buffer[MaxTextExtent];
+
+ FormatString(buffer,"\"%.1024s\"", argv[i]);
+
+ if (0 != i)
+ (void) ConcatenateString(&command," ");
+
+ (void) ConcatenateString(&command,buffer);
+ }
+ if (message[0] != '\0')
+ message_p = message;
+ MagickError2(DelegateError,command,message_p);
+ MagickFreeMemory(command);
+ }
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S t r i p S p a c e s F r o m S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickStripSpacesFromString() compacts a NULL-terminated string in-place
+% by removing white space (space and tab) characters) from a string.
+%
+% The format of the MagickStripSpacesFromString method is:
+%
+% size_t MagickStripSpacesFromString(char *string)
+%
+% A description of each parameter follows:
+%
+% o string: String buffer to compact.
+%
+% o returns: New string length
+%
+*/
+MagickExport size_t
+MagickStripSpacesFromString(char *string)
+{
+ register char
+ *w;
+
+ register const char
+ *r;
+
+ for (w=string, r=string; *r != '\0'; )
+ {
+ if ((*r == ' ') || (*r == '\t'))
+ {
+ r++;
+ continue;
+ }
+ if (r != w)
+ *w = *r;
+ r++;
+ w++;
+ }
+ *w='\0';
+ return (size_t) (w - string);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S t r T o I n t 6 4 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickStrToInt64() converts a string to a 64-bit integer type. MagickPass
+% is returned if the conversion succeeds, and MagickFail is returned if
+% the conversion fails.
+%
+% The format of the MagickStrToInt64 method is:
+%
+% MagickPassFail MagickStrToInt64(const char *start,char **end,
+% magick_int64_t *value)
+%
+% A description of each parameter follows:
+%
+% o start: Start of string
+%
+% o end: Pointer to update with address where parsing stopped.
+%
+% o value: Pointer to value to update
+%
+*/
+static MagickPassFail MagickStrToInt64(const char *start,char **end,
+ magick_int64_t *value)
+{
+ magick_int64_t
+ result;
+
+ errno=0;
+ result=MagickStrToL64(start,end,10);
+ if (errno == 0)
+ *value=result;
+
+ return (errno == 0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C r e a t e D i r e c t o r y P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCreateDirectoryPath() creates the specified directory path, creating
+% parent directories as required. MagickPass is returned on success, and
+% MagickFail is returned if there is a failure, with error information set
+% in the user-provided ExceptionInfo structure.
+%
+% The format of the MagickCreateDirectoryPath method is:
+%
+% MagickPassFail MagickCreateDirectoryPath(const char *dir,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o dir: Path to create.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport MagickPassFail MagickCreateDirectoryPath(const char *dir,
+ ExceptionInfo *exception)
+{
+ char
+ path[MaxTextExtent];
+
+ size_t
+ dir_len;
+
+ int
+ status = MagickPass;
+
+ const char
+ *end,
+ *p;
+
+ unsigned int
+ directory_mode;
+
+#if defined(S_IRWXU)
+ directory_mode = S_IRWXU;
+#else
+ directory_mode = 0777;
+#endif
+#if defined(S_IRGRP)
+ directory_mode |= S_IRGRP;
+#endif
+#if defined(S_IXGRP)
+ directory_mode |= S_IXGRP;
+#endif
+#if defined(S_IROTH)
+ directory_mode |= S_IROTH;
+#endif
+#if defined(S_IXOTH)
+ directory_mode |= S_IXOTH;
+#endif
+
+ dir_len = strlen(dir);
+ end = dir + dir_len;
+
+ /*
+ Walk back to find part of path which already exists.
+ */
+ for (p = end; p > dir ; p--)
+ {
+ if ((p == end) || (DirectorySeparator[0] == *p))
+ {
+ (void) strlcpy(path,dir,p-dir+1);
+ if (IsAccessibleNoLogging(path))
+ break;
+ }
+ }
+
+ if (p != end)
+ {
+ /*
+ Create part of path which does not already exist.
+ */
+ for ( p++; p <= end ; p++)
+ {
+ if ((*p == '\0') || (DirectorySeparator[0] == *p))
+ {
+ (void) strlcpy(path,dir,p-dir+1);
+ if (-1 == mkdir(path,directory_mode))
+ {
+ if (EEXIST != errno)
+ {
+ /*
+ Throw exception.
+ */
+ ThrowException2(exception,FileOpenError,dir,strerror(errno));
+ status = MagickFail;
+ break;
+ }
+ }
+ errno = 0;
+ }
+ }
+ }
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S c e n e F i l e N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSceneFileName() uses a filename template and scene number
+% in order to produce a unique filename for the scene. If force is
+% MagickFalse, then a substition is only performed if the template
+% contains a valid substitution specification. If force is MagickTrue,
+% then the additional scene template is applied so that the generated
+% filename is assured to be distinguished by the scene number.
+%
+% The format of the MagickSceneFileName method is:
+%
+% MagickBool MagickSceneFileName(char *filename, const char* template,
+% unsigned long scene)
+%
+% A description of each parameter follows:
+%
+% o filename: Buffer to update with generated filename. Buffer must
+% be at least MaxTextExtent bytes long.
+%
+% o filename_template: Filename generation template (e.g. "image%02d.miff").
+%
+% o scene_template: Template for scene part which is appended to
+% template if template does not contain a scene format
+% specification (e.g. ".%lu" or "[%lu]").
+%
+% o force: If there is no embedded template in filename, then apply
+% the scene template.
+%
+% o scene: Scene number.
+%
+*/
+MagickExport MagickBool MagickSceneFileName(char *filename,
+ const char* filename_template,
+ const char* scene_template,
+ const MagickBool force,
+ unsigned long scene)
+{
+ const char
+ *p;
+
+ MagickBool
+ status;
+
+ status = MagickFalse;
+ (void) strlcpy(filename,filename_template,MaxTextExtent);
+ p=strchr(filename_template,'%');
+ if ((p != (char *) NULL) && ((strchr(p+1,'%') == (char *) NULL)))
+ {
+ for ( p=p+1; *p ; p++)
+ {
+ register const int c = *p;
+ if ('d' == c)
+ {
+ FormatString(filename,filename_template,scene);
+ break;
+ }
+ if (!isdigit(c))
+ {
+ status = MagickFalse;
+ break;
+ }
+ }
+ }
+
+ if ((force) && (LocaleCompare(filename,filename_template) == 0))
+ {
+ char format[MaxTextExtent];
+ (void) strlcpy(format,"%.1024s",sizeof(format));
+ (void) strlcat(format,scene_template,sizeof(format));
+ FormatString(filename,format,filename_template,scene);
+ }
+ if (LocaleCompare(filename,filename_template) != 0)
+ status = MagickTrue;
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S t r l C a t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickStrlCat appends the NULL-terminated string src to the end
+% of dst. It will append at most size - strlen(dst) - 1 bytes, NULL-
+% terminating the result. If size is zero, then the result is not NULL
+% terminated. The total length of the string which would have been created
+% given sufficient buffer size (may be longer than size) is returned. This
+% function substitutes for strlcat() which is available under FreeBSD,
+% Apple's OS-X, and Solaris 8.
+%
+% Buffer overflow can be checked as follows:
+%
+% if (MagickStrlCat(dst, src, dstsize) >= dstsize)
+% return -1;
+%
+% The format of the MagickStrlCat method is:
+%
+% size_t MagickStrlCat(char *dst, const char *src, size_t size)
+%
+% A description of each parameter follows.
+%
+% o dst: Destination string.
+%
+% o src: Source string.
+%
+% o size: Maximum string length, including the terminating null.
+%
+*/
+MagickExport size_t MagickStrlCat(char *dst, const char *src, const size_t size)
+{
+ size_t
+ length;
+
+ const char
+ *q;
+
+ assert(dst != NULL);
+ assert(src != (const char *) NULL);
+ assert(size >= 1);
+
+ length=strlen(dst);
+
+ /*
+ Copy remaining characters from src while constraining length to
+ size - 1.
+ */
+ q = src;
+ if (size >= 1)
+ {
+ char
+ *p;
+
+ for ( p = dst + length ;
+ (*q != 0) && (length < size - 1) ;
+ length++, p++, q++ )
+ *p = *q;
+
+ dst[length]='\0';
+ }
+
+ /*
+ Add remaining length of src to length.
+ */
+ while (*q++)
+ length++;
+
+ return length;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S t r l C p y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickStrlCpy copies up to size - 1 characters from the NULL-
+% terminated string src to dst, NULL-terminating the result. If size is
+% zero, then the result is not NULL terminated. The total length of the
+% string which would have been created given sufficient buffer size (may
+% be longer than size) is returned. This function is simlar to strlcpy()
+% which is available under FreeBSD, Apple's OS-X, and Solaris 8 except
+% that it is assured to work with overlapping objects. FreeBSD does not
+% document if strlcpy() handles overlapping objects, but Solaris strlcpy()
+% does not.
+%
+% Buffer overflow can be checked as follows:
+%
+% if (MagickStrlCpy(dst, src, dstsize) >= dstsize)
+% return -1;
+%
+% The format of the MagickStrlCpy method is:
+%
+% size_t MagickStrlCpy(char *dst, const char *src, size_t size)
+%
+% A description of each parameter follows.
+%
+% o dst: Destination string.
+%
+% o src: Source string.
+%
+% o size: Maximum string length, including the terminating null.
+%
+*/
+MagickExport size_t MagickStrlCpy(char *dst, const char *src, const size_t size)
+{
+ size_t
+ length;
+
+ const char
+ *q;
+
+ assert(dst != NULL);
+ assert(src != (const char *) NULL);
+ assert(size >= 1);
+ /* assert(((dst+size) <= src) || (dst >= (src+size))); */
+
+
+ /*
+ Copy src to dst within bounds of size-1.
+ */
+ length=0;
+ q=src;
+ if (size >= 1)
+ {
+ char
+ *p;
+
+ for ( p=dst ;
+ (*q != 0) && (length < size-1) ;
+ length++, p++, q++ )
+ *p = *q;
+
+ dst[length]='\0';
+ }
+
+ /*
+ Add remaining length of src to length.
+ */
+ while (*q++)
+ length++;
+
+ return length;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S t r l C p y T r u n c %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickStrlCpyTrunc copies up to size - 1 characters from the NULL-
+% terminated string src to dst, NULL-terminating the result. If size is
+% zero, then the result is not NULL terminated. The number of bytes copied
+% (not including the terminating NULL) is returned. This function is a
+% useful alternative to using MagickStrlCpy() when the actual size copied
+% is more useful than knowledge that truncation occured.
+%
+% The format of the MagickStrlCat method is:
+%
+% size_t MagickStrlCpyTrunc(char *dst, const char *src, size_t size)
+%
+% A description of each parameter follows.
+%
+% o dst: Destination string.
+%
+% o src: Source string.
+%
+% o size: Maximum string length, including the terminating null.
+%
+*/
+MagickExport size_t MagickStrlCpyTrunc(char *dst, const char *src, const size_t size)
+{
+ size_t
+ length;
+
+ const char
+ *q;
+
+ assert(dst != NULL);
+ assert(src != (const char *) NULL);
+ assert(size >= 1);
+
+ /*
+ Copy src to dst within bounds of size-1.
+ */
+ length=0;
+ if (size >= 1)
+ {
+ char
+ *p;
+
+ for ( p=dst, q=src;
+ (*q != 0) && (length < size-1) ;
+ length++, p++, q++ )
+ *p = *q;
+
+ dst[length]='\0';
+ }
+
+ return length;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M u l t i l i n e C e n s u s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MultilineCensus returns the number of lines within a label. A line
+% is represented by a \n character.
+%
+% The format of the MultilineCenus method is:
+%
+% unsigned long MultilineCensus(const char *label)
+%
+% A description of each parameter follows.
+%
+% o label: This character string is the label.
+%
+%
+*/
+MagickExport unsigned long MultilineCensus(const char *label)
+{
+ long
+ number_lines;
+
+ /*
+ Determine the number of lines within this label.
+ */
+ if (label == (char *) NULL)
+ return(0);
+ for (number_lines=1; *label != '\0'; label++)
+ if (*label == '\n')
+ number_lines++;
+ return(number_lines);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t C l i e n t F i l e n a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SetClientFilename sets the client filename if the name is specified.
+% Otherwise the current client filename is returned. On a UNIX system the
+% client name and filename are often the same since file extensions are not
+% very important, but on windows the distinction if very important.
+%
+% The format of the SetClientFilename method is:
+%
+% char *SetClientFilname(const char *name)
+%
+% A description of each parameter follows:
+%
+% o client_name: Method SetClientFilename returns the current client name.
+%
+% o status: Specifies the new client name.
+%
+%
+*/
+MagickExport const char *GetClientFilename(void)
+{
+ return(SetClientFilename((char *) NULL));
+}
+
+MagickExport const char *SetClientFilename(const char *name)
+{
+ static char
+ client_filename[MaxTextExtent] = "";
+
+ if ((name != (char *) NULL) && (*name != '\0'))
+ {
+ (void) strlcpy(client_filename,name,sizeof(client_filename));
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Client Filename was set to: %s",client_filename);
+ }
+ return(client_filename);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t C l i e n t N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SetClientName sets the client name if the name is specified.
+% Otherwise the current client name is returned.
+%
+% The format of the SetClientName method is:
+%
+% char *SetClientName(const char *name)
+%
+% A description of each parameter follows:
+%
+% o client_name: Method SetClientName returns the current client name.
+%
+% o status: Specifies the new client name.
+%
+%
+*/
+MagickExport const char *GetClientName(void)
+{
+ return(SetClientName((char *) NULL));
+}
+
+MagickExport const char *SetClientName(const char *name)
+{
+ static char
+ client_name[MaxTextExtent] = "Magick";
+
+ if ((name != (char *) NULL) && (*name != '\0'))
+ {
+ (void) strlcpy(client_name,name,sizeof(client_name));
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Client Name was set to: %s",client_name);
+ }
+ return(client_name);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t C l i e n t P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SetClientPath sets the client path if the name is specified.
+% Otherwise the current client path is returned. A zero-length string
+% is returned if the client path has never been set.
+%
+% The format of the SetClientPath method is:
+%
+% char *SetClientPath(const char *path)
+%
+% A description of each parameter follows:
+%
+% o client_path: Method SetClientPath returns the current client path.
+%
+% o status: Specifies the new client path.
+%
+%
+*/
+MagickExport const char *GetClientPath(void)
+{
+ return(SetClientPath((char *) NULL));
+}
+
+MagickExport const char *SetClientPath(const char *path)
+{
+ static char
+ client_path[MaxTextExtent] = "";
+
+ if ((path != (char *) NULL) && (*path != '\0'))
+ {
+ (void) strlcpy(client_path,path,sizeof(client_path));
+ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
+ "Client Path was set to: %s",path);
+ }
+ return(client_path);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetGeometry sets a grometry to its default values.
+%
+% The format of the SetGeometry method is:
+%
+% SetGeometry(const Image *image,RectangleInfo *geometry)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o geometry: The geometry.
+%
+%
+*/
+MagickExport void SetGeometry(const Image *image,RectangleInfo *geometry)
+{
+ assert(image != (Image *) NULL);
+ assert(geometry != (RectangleInfo *) NULL);
+ (void) memset(geometry,0,sizeof(RectangleInfo));
+ geometry->width=image->columns;
+ geometry->height=image->rows;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S t r i n g T o A r g v %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method StringToArgv converts a text string into command line arguments.
+%
+% The format of the StringToArgv method is:
+%
+% char **StringToArgv(const char *text,int *argc)
+%
+% A description of each parameter follows:
+%
+% o argv: Method StringToArgv returns the string list unless an error
+% occurs, otherwise NULL.
+%
+% o text: Specifies the string to segment into a list.
+%
+% o argc: This integer pointer returns the number of arguments in the
+% list.
+%
+%
+*/
+MagickExport char **StringToArgv(const char *text,int *argc)
+{
+ char
+ **argv;
+
+ register char
+ *p,
+ *q;
+
+ register long
+ i;
+
+ *argc=0;
+ if (text == (char *) NULL)
+ return((char **) NULL);
+ /*
+ Determine the number of arguments.
+ */
+ for (p=(char *) text; *p != '\0'; )
+ {
+ while (isspace((int)(unsigned char) (*p)))
+ p++;
+ (*argc)++;
+ if (*p == '"')
+ for (p++; (*p != '"') && (*p != '\0'); p++);
+ if (*p == '\'')
+ for (p++; (*p != '\'') && (*p != '\0'); p++);
+ while (!isspace((int)(unsigned char) (*p)) && (*p != '\0'))
+ p++;
+ }
+ (*argc)++;
+ argv=MagickAllocateMemory(char **,(*argc+1)*sizeof(char *));
+ if (argv == (char **) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToConvertStringToTokens);
+ return((char **) NULL);
+ }
+ /*
+ Convert string to an ASCII list.
+ */
+ argv[0]=AllocateString("magick");
+ p=(char *) text;
+ for (i=1; i < *argc; i++)
+ {
+ while (isspace((int)(unsigned char) (*p)))
+ p++;
+ q=p;
+ if (*q == '"')
+ {
+ p++;
+ for (q++; (*q != '"') && (*q != '\0'); q++);
+ }
+ else
+ if (*q == '\'')
+ {
+ for (q++; (*q != '\'') && (*q != '\0'); q++);
+ q++;
+ }
+ else
+ while (!isspace((int)(unsigned char) (*q)) && (*q != '\0'))
+ q++;
+ argv[i]=MagickAllocateMemory(char *,(size_t) (q-p+MaxTextExtent));
+ if (argv[i] == (char *) NULL)
+ {
+ int
+ j;
+
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToConvertStringToTokens);
+
+ /*
+ Deallocate allocated data and return.
+ */
+ for (j=0; j<i; j++)
+ MagickFreeMemory(argv[j]);
+ MagickFreeMemory(argv);
+ return((char **) NULL);
+ }
+ (void) strlcpy(argv[i],p,q-p+1);
+ p=q;
+ while (!isspace((int)(unsigned char) (*p)) && (*p != '\0'))
+ p++;
+ }
+ argv[i]=(char *) NULL;
+ return(argv);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S t r i n g T o D o u b l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method StringToDouble() converts a text string to a double. If the string
+% contains a percent sign (e.g. 50%) that percentage of the interval is
+% returned.
+%
+% The format of the StringToDouble method is:
+%
+% double StringToDouble(const char *text,const double interval)
+%
+% A description of each parameter follows:
+%
+% o value: Method StringToDouble returns the converted value.
+%
+% o text: Specifies the string to segment into a list.
+%
+% o interval: Specifies the interval; used for obtaining a percentage.
+%
+%
+*/
+MagickExport double StringToDouble(const char *text,const double interval)
+{
+ char
+ *q;
+
+ double
+ value;
+
+ if (MagickStrToD(text,&q,&value) == 0)
+ return 0.0;
+ if (strchr(q,'%') != (char *) NULL)
+ value*=interval/100.0;
+ return(value);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S t r i n g T o L i s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method StringToList converts a text string into a list by segmenting the
+% text string at each carriage return discovered. The list is converted to
+% HEX characters if any control characters are discovered within the text
+% string.
+%
+% The format of the StringToList method is:
+%
+% char **StringToList(const char *text)
+%
+% A description of each parameter follows:
+%
+% o list: Method StringToList returns the string list unless an error
+% occurs, otherwise NULL.
+%
+% o text: Specifies the string to segment into a list.
+%
+%
+*/
+MagickExport char **StringToList(const char *text)
+{
+ char
+ **textlist;
+
+ register char
+ *q;
+
+ register const char
+ *p;
+
+ register long
+ i;
+
+ size_t
+ lines;
+
+ if (text == (char *) NULL)
+ return((char **) NULL);
+ for (p=text; *p != '\0'; p++)
+ if (((unsigned char) *p < 32) && !isspace((int)(unsigned char) (*p)))
+ break;
+ if (*p == '\0')
+ {
+ /*
+ Convert string to an ASCII list.
+ */
+ lines=1;
+ for (p=text; *p != '\0'; p++)
+ if (*p == '\n')
+ lines++;
+ textlist=MagickAllocateMemory(char **,(lines+MaxTextExtent)*sizeof(char *));
+ if (textlist == (char **) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToConvertText);
+ p=text;
+ for (i=0; i < (long) lines; i++)
+ {
+ for (q=(char *) p; *q != '\0'; q++)
+ if ((*q == '\r') || (*q == '\n'))
+ break;
+ textlist[i]=MagickAllocateMemory(char *,(size_t) (q-p+MaxTextExtent));
+ if (textlist[i] == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToConvertText);
+ /*
+ Don't use strlcpy here because it spends too much time
+ looking for the trailing null in order to report the
+ characters not copied.
+ */
+ (void) strncpy(textlist[i],p,q-p);
+ textlist[i][q-p]='\0';
+ if (*q == '\r')
+ q++;
+ p=q+1;
+ }
+ }
+ else
+ {
+ char
+ hex_string[MaxTextExtent];
+
+ register long
+ j;
+
+ /*
+ Convert string to a HEX list.
+ */
+ lines=(strlen(text)/0x14)+1;
+ textlist=MagickAllocateMemory(char **,(lines+MaxTextExtent)*sizeof(char *));
+ if (textlist == (char **) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToConvertText);
+ p=text;
+ for (i=0; i < (long) lines; i++)
+ {
+ textlist[i]=MagickAllocateMemory(char *,2*MaxTextExtent);
+ if (textlist[i] == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToConvertText);
+ FormatString(textlist[i],"0x%08lx: ",0x14*i);
+ q=textlist[i]+strlen(textlist[i]);
+ for (j=1; j <= (long) Min(strlen(p),0x14); j++)
+ {
+ FormatString(hex_string,"%02x",*(p+j));
+ (void) strlcpy(q,hex_string,MaxTextExtent);
+ q+=2;
+ if ((j % 0x04) == 0)
+ *q++=' ';
+ }
+ for (; j <= 0x14; j++)
+ {
+ *q++=' ';
+ *q++=' ';
+ if ((j % 0x04) == 0)
+ *q++=' ';
+ }
+ *q++=' ';
+ for (j=1; j <= (long) Min(strlen(p),0x14); j++)
+ {
+ if (isprint((int)(unsigned char)(*p)))
+ *q++=(*p);
+ else
+ *q++='-';
+ p++;
+ }
+ *q='\0';
+ }
+ }
+ textlist[i]=(char *) NULL;
+ return(textlist);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S t r i p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Strip strips any whitespace or quotes from the beginning and end of
+% a string of characters.
+%
+% The format of the Strip method is:
+%
+% void Strip(char *message)
+%
+% A description of each parameter follows:
+%
+% o message: Specifies an array of characters.
+%
+%
+*/
+MagickExport void Strip(char *message)
+{
+ register char
+ *p,
+ *q;
+
+ assert(message != (char *) NULL);
+ if (*message == '\0')
+ return;
+ if (strlen(message) == 1)
+ return;
+ p=message;
+ while (isspace((int)(unsigned char) (*p)))
+ p++;
+ if ((*p == '\'') || (*p == '"'))
+ p++;
+ q=message+strlen(message)-1;
+ while (isspace((int)(unsigned char) (*q)) && (q > p))
+ q--;
+ if (q > p)
+ if ((*q == '\'') || (*q == '"'))
+ q--;
+ (void) memmove(message,p,q-p+1);
+ message[q-p+1]='\0';
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ S u b s t i t u t e S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SubstituteString() performs string substitution on a buffer, replacing
+% the buffer with the substituted version. Buffer must be allocated from
+% the heap since it may be reallocated (as required). MagickTrue is returned
+% if a replacement was made.
+%
+% The format of the SubstituteString method is:
+%
+% MagickBool SubstituteString(char **buffer,const char* search,
+% const char *replace)
+%
+% A description of each parameter follows:
+%
+% o buffer: The buffer to perform replacements on. Replaced with new
+% allocation if a replacement is made.
+%
+% o search: String to search for.
+%
+% o replace: Replacement string.
+%
+*/
+MagickExport MagickBool
+SubstituteString(char **buffer,const char *search,const char *replace)
+{
+ register char
+ *p=*buffer;
+
+ register size_t
+ i;
+
+ size_t
+ search_len=0,
+ replace_len=0;
+
+ MagickBool
+ replaced=MagickFalse;
+
+ search_len=strlen(search);
+ p=*buffer;
+ for (i=0; p[i] != '\0'; i++)
+ {
+ if ((p[i] == search[0]) && (strncmp(&p[i],search,search_len) == 0))
+ {
+ if (0 == replace_len)
+ replace_len=strlen(replace);
+ if (replace_len > search_len)
+ {
+ size_t
+ allocation_len;
+
+ allocation_len=strlen(p)+(replace_len-search_len)+1;
+ MagickRoundUpStringLength(allocation_len);
+ MagickReallocMemory(char *,p,allocation_len);
+ *buffer=p;
+ if (p == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,
+ MemoryAllocationFailed,
+ UnableToAllocateString);
+ }
+ if (search_len != replace_len)
+ (void) MagickCloneMemory(&p[i+replace_len],&p[i+search_len],
+ strlen(&p[i+search_len])+1);
+ (void) MagickCloneMemory(&p[i],replace,replace_len);
+ i += replace_len;
+ replaced=MagickTrue;
+ }
+ }
+ return replaced;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S y s t e m C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method SystemCommand executes the specified command and waits until it
+% terminates. The returned value is the exit status of the command.
+%
+% The format of the SystemCommand method is:
+%
+% int SystemCommand(const unsigned int verbose,const char *command)
+%
+% A description of each parameter follows:
+%
+% o status: Method SystemCommand returns False if the command is
+% executed successfully.
+%
+% o verbose: An unsigned integer other than 0 prints the executed
+% command before it is invoked.
+%
+% o command: This string is the command to execute.
+%
+%
+*/
+MagickExport int SystemCommand(const unsigned int verbose,const char *command)
+{
+ int
+ status;
+
+#if defined(POSIX)
+ char
+ message[MaxTextExtent];
+#endif /* POSIX */
+
+ const char
+ *message_p = (const char *) NULL;
+
+ {
+ /*
+ Verify that we are allowed to run this program.
+ */
+ ExceptionInfo
+ exception;
+
+ char
+ *end,
+ program[MaxTextExtent];
+
+ GetExceptionInfo(&exception);
+ end=(char *) NULL;
+ program[0]='\0';
+ MagickGetToken(command,&end,program,MaxTextExtent);
+ if (MagickConfirmAccess(FileExecuteConfirmAccessMode,program,&exception)
+ == MagickFail)
+ {
+ errno=EPERM;
+ DestroyExceptionInfo(&exception);
+ return -1;
+ }
+ }
+
+ errno=0;
+#if defined(POSIX)
+ status=system(command);
+ if (status == 1)
+ {
+ (void) strlcpy(message,strerror(status),sizeof(message));
+ message_p=message;
+ }
+ else if (WIFSIGNALED(status))
+ {
+ FormatString(message,"terminated due to signal %d",
+ WTERMSIG(status));
+ message[sizeof(message)-1]='\0';
+ message_p=message;
+ }
+#elif defined(MSWINDOWS)
+ status=NTSystemComman(command);
+ if (!status)
+ message_p=strerror(status);
+#else
+# error Do not know how to run system commands.
+#endif
+ if (verbose || (status != 0))
+ MagickError2(DelegateError,command,message_p);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T o k e n i z e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method Tokenizer is a generalized, finite state token parser. It extracts
+% tokens one at a time from a string of characters. The characters used for
+% white space, for break characters, and for quotes can be specified. Also,
+% characters in the string can be preceded by a specifiable escape character
+% which removes any special meaning the character may have.
+%
+% Here is some terminology:
+%
+% o token: A single unit of information in the form of a group of
+% characters.
+%
+% o white space: Space that gets ignored (except within quotes or when
+% escaped), like blanks and tabs. in addition, white space terminates a
+% non-quoted token.
+%
+% o break set: One or more characters that separates non-quoted tokens.
+% Commas are a common break character. The usage of break characters to
+% signal the end of a token is the same as that of white space, except
+% multiple break characters with nothing or only white space between
+% generate a null token for each two break characters together.
+%
+% For example, if blank is set to be the white space and comma is set to
+% be the break character, the line
+%
+% A, B, C , , DEF
+%
+% ... consists of 5 tokens:
+%
+% 1) "A"
+% 2) "B"
+% 3) "C"
+% 4) "" (the null string)
+% 5) "DEF"
+%
+% o Quote character: A character that, when surrounding a group of other
+% characters, causes the group of characters to be treated as a single
+% token, no matter how many white spaces or break characters exist in
+% the group. Also, a token always terminates after the closing quote.
+% For example, if ' is the quote character, blank is white space, and
+% comma is the break character, the following string
+%
+% A, ' B, CD'EF GHI
+%
+% ... consists of 4 tokens:
+%
+% 1) "A"
+% 2) " B, CD" (note the blanks & comma)
+% 3) "EF"
+% 4) "GHI"
+%
+% The quote characters themselves do not appear in the resultant
+% tokens. The double quotes are delimiters i use here for
+% documentation purposes only.
+%
+% o Escape character: A character which itself is ignored but which
+% causes the next character to be used as is. ^ and \ are often used
+% as escape characters. An escape in the last position of the string
+% gets treated as a "normal" (i.e., non-quote, non-white, non-break,
+% and non-escape) character. For example, assume white space, break
+% character, and quote are the same as in the above examples, and
+% further, assume that ^ is the escape character. Then, in the string
+%
+% ABC, ' DEF ^' GH' I ^ J K^ L ^
+%
+% ... there are 7 tokens:
+%
+% 1) "ABC"
+% 2) " DEF ' GH"
+% 3) "I"
+% 4) " " (a lone blank)
+% 5) "J"
+% 6) "K L"
+% 7) "^" (passed as is at end of line)
+%
+% The format of the Tokenizer method is:
+%
+% int Tokenizer(TokenInfo *token_info,unsigned flag,char *token,
+% size_t max_token_length,char *line,char *white,char *break_set,
+% char *quote,char escape,char *breaker,int *next,char *quoted)
+%
+% A description of each parameter follows:
+%
+% o flag: right now, only the low order 3 bits are used.
+%
+% 1 => convert non-quoted tokens to upper case
+% 2 => convert non-quoted tokens to lower case
+% 0 => do not convert non-quoted tokens
+%
+% o token: a character string containing the returned next token
+%
+% o max_token_length: the maximum size of "token". Characters beyond
+% "max_token_length" are truncated.
+%
+% o string: the string to be parsed.
+%
+% o white: a string of the valid white spaces. example:
+%
+% char whitesp[]={" \t"};
+%
+% blank and tab will be valid white space.
+%
+% o break: a string of the valid break characters. example:
+%
+% char breakch[]={";,"};
+%
+% semicolon and comma will be valid break characters.
+%
+% o quote: a string of the valid quote characters. An example would be
+%
+% char whitesp[]={"'\"");
+%
+% (this causes single and double quotes to be valid) Note that a
+% token starting with one of these characters needs the same quote
+% character to terminate it.
+%
+% for example:
+%
+% "ABC '
+%
+% is unterminated, but
+%
+% "DEF" and 'GHI'
+%
+% are properly terminated. Note that different quote characters
+% can appear on the same line; only for a given token do the quote
+% characters have to be the same.
+%
+% o escape: the escape character (NOT a string ... only one
+% allowed). Use zero if none is desired.
+%
+% o breaker: the break character used to terminate the current
+% token. If the token was quoted, this will be the quote used. If
+% the token is the last one on the line, this will be zero.
+%
+% o next: this variable points to the first character of the
+% next token. it gets reset by "tokenizer" as it steps through the
+% string. Set it to 0 upon initialization, and leave it alone
+% after that. You can change it if you want to jump around in the
+% string or re-parse from the beginning, but be careful.
+%
+% o quoted: set to True if the token was quoted and False
+% if not. You may need this information (for example: in C, a
+% string with quotes around it is a character string, while one
+% without is an identifier).
+%
+% o result: 0 if we haven't reached EOS (end of string), and 1
+% if we have.
+%
+*/
+
+#define IN_WHITE 0
+#define IN_TOKEN 1
+#define IN_QUOTE 2
+#define IN_OZONE 3
+
+static long sindex(char c,char *string)
+{
+ register char
+ *p;
+
+ for (p=string; *p; p++)
+ if (c == (*p))
+ return(p-string);
+ return(-1);
+}
+
+static void StoreToken(TokenInfo *token_info,char *string,
+ size_t max_token_length,char c)
+{
+ register long
+ i;
+
+ if ((token_info->offset < 0) ||
+ ((size_t) token_info->offset >= (max_token_length-1)))
+ return;
+ i=token_info->offset++;
+ string[i]=c;
+ if (token_info->state == IN_QUOTE)
+ return;
+ switch (token_info->flag & 0x03)
+ {
+ case 1:
+ {
+ string[i]=toupper((int) c);
+ break;
+ }
+ case 2:
+ {
+ string[i]=tolower((int) c);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+MagickExport int Tokenizer(TokenInfo *token_info,unsigned flag,char *token,
+ size_t max_token_length,char *line,char *white,char *break_set,char *quote,
+ char escape,char *breaker,int *next,char *quoted)
+{
+ char
+ c;
+
+ register long
+ i;
+
+ *breaker=False;
+ *quoted=False;
+ if (!line[*next])
+ return(1);
+ token_info->state=IN_WHITE;
+ token_info->quote=False;
+ token_info->flag=flag;
+ for (token_info->offset=0; line[*next] != 0; (*next)++)
+ {
+ c=line[*next];
+ i=sindex(c,break_set);
+ if (i >= 0)
+ {
+ switch (token_info->state)
+ {
+ case IN_WHITE:
+ case IN_TOKEN:
+ case IN_OZONE:
+ {
+ (*next)++;
+ *breaker=break_set[i];
+ token[token_info->offset]=0;
+ return(0);
+ }
+ case IN_QUOTE:
+ {
+ StoreToken(token_info,token,max_token_length,c);
+ break;
+ }
+ }
+ continue;
+ }
+ i=sindex(c,quote);
+ if (i >= 0)
+ {
+ switch(token_info->state)
+ {
+ case IN_WHITE:
+ {
+ token_info->state=IN_QUOTE;
+ token_info->quote=quote[i];
+ *quoted=True;
+ break;
+ }
+ case IN_QUOTE:
+ {
+ if (quote[i] != token_info->quote)
+ StoreToken(token_info,token,max_token_length,c);
+ else
+ {
+ token_info->state=IN_OZONE;
+ token_info->quote=0;
+ }
+ break;
+ }
+ case IN_TOKEN:
+ case IN_OZONE:
+ {
+ *breaker=c;
+ token[token_info->offset]=0;
+ return(0);
+ }
+ }
+ continue;
+ }
+ i=sindex(c,white);
+ if (i >= 0)
+ {
+ switch(token_info->state)
+ {
+ case IN_WHITE:
+ case IN_OZONE:
+ break;
+ case IN_TOKEN:
+ {
+ token_info->state=IN_OZONE;
+ break;
+ }
+ case IN_QUOTE:
+ {
+ StoreToken(token_info,token,max_token_length,c);
+ break;
+ }
+ }
+ continue;
+ }
+ if (c == escape)
+ {
+ if (line[(*next)+1] == 0)
+ {
+ *breaker=0;
+ StoreToken(token_info,token,max_token_length,c);
+ (*next)++;
+ token[token_info->offset]=0;
+ return(0);
+ }
+ switch(token_info->state)
+ {
+ case IN_WHITE:
+ {
+ (*next)--;
+ token_info->state=IN_TOKEN;
+ break;
+ }
+ case IN_TOKEN:
+ case IN_QUOTE:
+ {
+ (*next)++;
+ c=line[*next];
+ StoreToken(token_info,token,max_token_length,c);
+ break;
+ }
+ case IN_OZONE:
+ {
+ token[token_info->offset]=0;
+ return(0);
+ }
+ }
+ continue;
+ }
+ switch(token_info->state)
+ {
+ case IN_WHITE:
+ {
+ token_info->state=IN_TOKEN;
+ StoreToken(token_info,token,max_token_length,c);
+ break;
+ }
+ case IN_TOKEN:
+ case IN_QUOTE:
+ {
+ StoreToken(token_info,token,max_token_length,c);
+ break;
+ }
+ case IN_OZONE:
+ {
+ token[token_info->offset]=0;
+ return(0);
+ }
+ }
+ }
+ token[token_info->offset]=0;
+ return(0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T r a n s l a t e T e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method TranslateText replaces any embedded formatting characters with
+% the appropriate image attribute and returns the translated text. See
+% the documentation for TranslateTextEx() for the available translations.
+%
+% The format of the TranslateText method is:
+%
+% char *TranslateText(const ImageInfo *image_info,Image *image,
+% const char *formatted_text)
+%
+% A description of each parameter follows:
+%
+% o translated_text: Method TranslateText returns the translated
+% text string.
+%
+% o image_info: The imageInfo (may be NULL!).
+%
+% o image: The image.
+%
+% o formatted_text: The address of a character string containing the embedded
+% formatting characters.
+%
+*/
+
+MagickExport char *TranslateText(const ImageInfo *image_info,
+ Image *image,
+ const char *formatted_text)
+{
+ return TranslateTextEx(image_info,image,formatted_text,MagickStrlCpyTrunc);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% T r a n s l a t e T e x t E x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method TranslateTextEx replaces any embedded formatting characters with
+% the appropriate image attribute and returns the translated text, while
+% applying a text transformation for each substitution via a user provided
+% translation function. The translation function should behave similar to
+% strlcpy() but may translate text while it is copied.
+%
+% The currently supported translations are:
+%
+% %b file size
+% %c comment
+% %d directory
+% %e filename extension
+% %f filename
+% %g page dimensions and offsets
+% %h height
+% %i input filename
+% %k number of unique colors
+% %l label
+% %m magick
+% %n number of scenes
+% %o output filename
+% %p page number
+% %q image bit depth
+% %r image type description
+% %s scene number
+% %t top of filename
+% %u first unique temporary filename
+% %w width
+% %x horizontal resolution
+% %y vertical resolution
+% %z second unique temporary filename
+% %A transparency supported
+% %C compression type
+% %D GIF disposal method
+% %G Original width and height
+% %H page height
+% %M original filename specification
+% %O page offset (x,y)
+% %P page dimensions (width,height)
+% %Q compression quality
+% %T time delay (in centi-seconds)
+% %U resolution units
+% %W page width
+% %X page horizontal offset (x)
+% %Y page vertical offset (y)
+% %@ trim bounding box
+% %[a] named attribute 'a'
+% %# signature
+% \n newline
+% \r carriage return
+% %% % (literal)
+%
+% The format of the TranslateTextEx method is:
+%
+% char *TranslateTextEx(const ImageInfo *image_info,Image *image,
+% const char *formatted_text, MagickTextTranslate translate)
+%
+% A description of each parameter follows:
+%
+% o translated_text: Method TranslateText returns the translated
+% text string.
+%
+% o image_info: The imageInfo (may be NULL!).
+%
+% o image: The image.
+%
+% o formatted_text: The address of a character string containing the embedded
+% formatting characters.
+%
+% o translate: text translation callback function
+%
+*/
+MagickExport char *TranslateTextEx(const ImageInfo *image_info,
+ Image *image,
+ const char *formatted_text,
+ MagickTextTranslate translate)
+{
+ char
+ buffer[MaxTextExtent],
+ *text,
+ *translated_text;
+
+ const ImageAttribute
+ *attribute;
+
+ register char
+ *p,
+ *q;
+
+ register long
+ i;
+
+ size_t
+ length,
+ offset;
+
+ assert(image != (Image *) NULL);
+ if ((formatted_text == (const char *) NULL) || (*formatted_text == '\0'))
+ return((char *) NULL);
+ text=(char *) formatted_text;
+ /*
+ If text starts with '@' then try to replace it with the content of
+ the file name which follows.
+ */
+ if ((*text == '@') && IsAccessible(text+1))
+ {
+ text=(char *) FileToBlob(text+1,&length,&image->exception);
+ if (text == (char *) NULL)
+ return((char *) NULL);
+ }
+ /*
+ Translate any embedded format characters.
+ */
+ length=strlen(text)+MaxTextExtent;
+ translated_text=MagickAllocateMemory(char *,length);
+ if (translated_text == (char *) NULL)
+ return NULL;
+ /*
+ FIXME: Overlapping memory detected here where memory should not be overlapping.
+ */
+ (void) strlcpy(translated_text,text,length);
+ /* (void) memmove(translated_text,text,strlen(text)+1); */
+ p=text;
+ for (q=translated_text; *p != '\0'; p++)
+ {
+ *q='\0';
+ if ((size_t) (q-translated_text+MaxTextExtent) >= length)
+ {
+ length<<=1;
+ MagickReallocMemory(char *,translated_text,length);
+ if (translated_text == (char *) NULL)
+ break;
+ q=translated_text+strlen(translated_text);
+ }
+ /*
+ Process formatting characters in text.
+ */
+ if ((*p == '\\') && (*(p+1) == 'r'))
+ {
+ *q++='\r';
+ p++;
+ continue;
+ }
+ if ((*p == '\\') && (*(p+1) == 'n'))
+ {
+ *q++='\n';
+ p++;
+ continue;
+ }
+ if (*p != '%')
+ {
+ *q++=(*p);
+ continue;
+ }
+ p++;
+ switch (*p)
+ {
+ case 'b':
+ {
+ /* File size */
+ FormatSize(GetBlobSize(image),buffer);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'c':
+ {
+ /* Comment */
+ attribute=GetImageAttribute(image,"comment");
+ if (attribute != (ImageAttribute *) NULL)
+ {
+ /* Comments may be larger than MaxTextExtent so make sure
+ there is sufficient memory allocated. Make sure that
+ there is at least MaxTextExtent left available after we
+ have concatenated our part. */
+ offset=q-translated_text;
+ if ((size_t) (offset+attribute->length+1+MaxTextExtent) >= length)
+ {
+ length += (attribute->length+1+2*MaxTextExtent);
+ MagickReallocMemory(char *,translated_text,length);
+ if (translated_text == (char *) NULL)
+ break;
+ q=translated_text+offset;
+ }
+ q+=(translate)(q,attribute->value,attribute->length+1+MaxTextExtent);
+ }
+ break;
+ }
+ case 'd':
+ case 'e':
+ case 'f':
+ case 't':
+ {
+ /*
+ Label segment is the base of the filename.
+ */
+ if (strlen(image->magick_filename) != 0)
+ {
+ (void) strlcpy(buffer,"",MaxTextExtent);
+ switch (*p)
+ {
+ case 'd':
+ {
+ /* Directory */
+ GetPathComponent(image->magick_filename,HeadPath,buffer);
+ break;
+ }
+ case 'e':
+ {
+ /* Filename extension */
+ GetPathComponent(image->magick_filename,ExtensionPath,buffer);
+ break;
+ }
+ case 'f':
+ {
+ /* Filename */
+ GetPathComponent(image->magick_filename,TailPath,buffer);
+ break;
+ }
+ case 't':
+ {
+ /* Top of filename */
+ GetPathComponent(image->magick_filename,BasePath,buffer);
+ break;
+ }
+ }
+ q+=(translate)(q,buffer,MaxTextExtent);
+ }
+ break;
+ }
+ case 'g':
+ {
+ /* page dimensions and offsets */
+ FormatString(buffer,"%lux%lu%+ld%+ld",
+ image->page.width,image->page.height,
+ image->page.x,image->page.y);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'h':
+ {
+ /* Image height */
+ FormatString(buffer,"%lu",image->rows);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'i':
+ {
+ /* Input filename */
+ q+=(translate)(q,image->filename,MaxTextExtent);
+ break;
+ }
+ case 'k':
+ {
+ /* Number of unique colors */
+ if (GetPixelCachePresent(image))
+ {
+ FormatString(buffer,"%lu",GetNumberColors(image,(FILE *) NULL,
+ &image->exception));
+ q+=(translate)(q,buffer,MaxTextExtent);
+ }
+ else
+ {
+ *q++='%';
+ *q++=(*p);
+ }
+ break;
+ }
+ case 'l':
+ {
+ /* Label */
+ attribute=GetImageAttribute(image,"label");
+ if (attribute != (ImageAttribute *) NULL)
+ q+=(translate)(q,attribute->value,MaxTextExtent);
+ break;
+ }
+ case 'm':
+ {
+ /* File format "magick" */
+ q+=(translate)(q,image->magick,MaxTextExtent);
+ break;
+ }
+ case 'n':
+ {
+ /* Number of scenes */
+ FormatString(buffer,"%lu",(unsigned long) GetImageListLength(image));
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'o':
+ {
+ /* Output filename */
+ if (image_info != (const ImageInfo *) NULL)
+ q+=(translate)(q,image_info->filename,MaxTextExtent);
+ break;
+ }
+ case 'p':
+ {
+ /* Page number */
+ register const Image
+ *frame;
+
+ unsigned long
+ page;
+
+ frame=image;
+ for (page=1; frame->previous != (Image *) NULL; page++)
+ frame=frame->previous;
+ FormatString(buffer,"%lu",page);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'q':
+ {
+ /* Quantum depth */
+ if (GetPixelCachePresent(image))
+ FormatString(buffer,"%lu",GetImageDepth(image,&image->exception));
+ else
+ FormatString(buffer,"%u",image->depth);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'r':
+ {
+ /* Image type */
+ q+=(translate)(q,ImageTypeToString(GetImageType(image,&image->exception)),
+ MaxTextExtent);
+ break;
+ }
+ case 's':
+ {
+ /* Scene number */
+ FormatString(buffer,"%lu",image->scene);
+ if (image_info != (const ImageInfo *) NULL)
+ if (image_info->subrange != 0)
+ FormatString(buffer,"%lu",image_info->subimage);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'u':
+ {
+ /* Unique temporary filename */
+ if (image_info != (const ImageInfo *) NULL)
+ {
+ if (strlcpy(buffer,image_info->unique,MaxTextExtent) == 0)
+ if (!AcquireTemporaryFileName(buffer))
+ break;
+ q+=(translate)(q,buffer,MaxTextExtent);
+ }
+ break;
+ }
+ case 'w':
+ {
+ /* Image width */
+ FormatString(buffer,"%lu",image->columns);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'x':
+ {
+ /* Horizontal resolution */
+ FormatString(buffer,"%g",image->x_resolution);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'y':
+ {
+ /* Vertical resolution */
+ FormatString(buffer,"%g",image->y_resolution);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'z':
+ {
+ /* Second unique temporary filename */
+ if (image_info != (const ImageInfo *) NULL)
+ {
+ if (strlcpy(buffer,image_info->zero,MaxTextExtent) == 0)
+ if (!AcquireTemporaryFileName(buffer))
+ break;
+ q+=(translate)(q,buffer,MaxTextExtent);
+ }
+ break;
+ }
+ case 'A':
+ {
+ /* Transparency supported */
+ FormatString(buffer,"%s",image->matte? "true" : "false");
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'C':
+ {
+ /* Image compression type */
+ FormatString(buffer,"%s",CompressionTypeToString(image->compression));
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'D':
+ {
+ /* GIF disposal method */
+ FormatString(buffer,"%d",image->dispose);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'G':
+ {
+ /* Original image width and height */
+ FormatString(buffer,"%lux%lu",image->magick_columns,image->magick_rows);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'H':
+ {
+ /* page height */
+ FormatString(buffer,"%lu",image->page.height);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'M':
+ {
+ /* Original filename specification */
+ q+=(translate)(q,image->magick_filename,MaxTextExtent);
+ break;
+ }
+ case 'O':
+ {
+ /* page offset */
+ FormatString(buffer,"%+ld%+ld",image->page.x,image->page.y);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'P':
+ {
+ /* page dimensions */
+ FormatString(buffer,"%lux%lu",image->page.width,image->page.height);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'Q':
+ {
+ /* Compression quality */
+ attribute=GetImageAttribute(image,"JPEG-Quality");
+ if (attribute != (ImageAttribute *) NULL)
+ {
+ q+=(translate)(q,attribute->value,MaxTextExtent);
+ break;
+ }
+ if (image_info != (const ImageInfo *) NULL)
+ {
+ FormatString(buffer,"%lu",image_info->quality);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ FormatString(buffer,"%lu",DefaultCompressionQuality);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'T':
+ {
+ /* time delay (in centi-seconds) */
+ FormatString(buffer,"%lu",image->delay);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'U':
+ {
+ /* resolution units */
+ FormatString(buffer,"%s",ResolutionTypeToString(image->units));
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'W':
+ {
+ /* page width */
+ FormatString(buffer,"%lu",image->page.width);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'X':
+ {
+ /* page x offset */
+ FormatString(buffer,"%+ld",image->page.x);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case 'Y':
+ {
+ /* page y offset */
+ FormatString(buffer,"%+ld",image->page.y);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case '@':
+ {
+ /* trim bounding box */
+ RectangleInfo bounds = GetImageBoundingBox(image,
+ &image->exception);
+ FormatString(buffer,"%lux%lu%+ld%+ld",bounds.width,bounds.height,
+ bounds.x,bounds.y);
+ q+=(translate)(q,buffer,MaxTextExtent);
+ break;
+ }
+ case '[':
+ {
+ /* Image attribute */
+ char
+ key[MaxTextExtent];
+
+ /* Extract attribute key string. */
+ p++;
+ for (i=0; (i < MaxTextExtent) && (*p) && (*p != ']'); i++)
+ {
+ key[i]=(*p++);
+ }
+ if (']' != *p)
+ break;
+ key[i]='\0';
+
+ /* Try to get the attibute from image */
+ attribute=GetImageAttribute(image,key);
+
+ /* Try to get the attribute from image_info */
+ if (attribute == (const ImageAttribute *) NULL)
+ if (image_info != (const ImageInfo *) NULL)
+ attribute=GetImageInfoAttribute(image_info,image,key);
+
+ if (attribute != (const ImageAttribute *) NULL)
+ {
+ /* Attributes may be larger than MaxTextExtent so make
+ sure there is sufficient memory allocated. Make sure
+ that there is at least MaxTextExtent left available
+ after we have concatenated our part. */
+ offset=q-translated_text;
+ if ((size_t) (offset+attribute->length+1+MaxTextExtent) >= length)
+ {
+ length += (attribute->length+1+2*MaxTextExtent);
+ MagickReallocMemory(char *,translated_text,length);
+ if (translated_text == (char *) NULL)
+ break;
+ q=translated_text+offset;
+ }
+ q+=(translate)(q,attribute->value,attribute->length+1+MaxTextExtent);
+ }
+ break;
+ }
+ case '#':
+ {
+ if (GetPixelCachePresent(image))
+ {
+ (void) SignatureImage(image);
+ attribute=GetImageAttribute(image,"signature");
+ if (attribute != (ImageAttribute *) NULL)
+ q+=(translate)(q,attribute->value,MaxTextExtent);
+ }
+ else
+ {
+ *q++='%';
+ *q++=(*p);
+ }
+ break;
+ }
+ case '%':
+ {
+ /* Pass through literal % */
+ *q++=(*p);
+ break;
+ }
+ default:
+ {
+ /* Pass through unknown codes */
+ *q++='%';
+ *q++=(*p);
+ break;
+ }
+ }
+ if (*p == '\0')
+ break;
+ }
+ *q='\0';
+ if (text != (char *) formatted_text)
+ MagickFreeMemory(text);
+ return(translated_text);
+}
diff --git a/magick/utility.h b/magick/utility.h
new file mode 100644
index 0000000..1845d81
--- /dev/null
+++ b/magick/utility.h
@@ -0,0 +1,201 @@
+/*
+ Copyright (C) 2003 - 2016 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Utility Methods.
+*/
+#ifndef _MAGICK_UTILITY_H
+#define _MAGICK_UTILITY_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ RootPath,
+ HeadPath,
+ TailPath,
+ BasePath,
+ ExtensionPath,
+ MagickPath,
+ SubImagePath,
+ FullPath
+} PathType;
+
+/*
+ Typedef declarations.
+*/
+typedef struct _TokenInfo
+{
+ int
+ state;
+
+ unsigned int
+ flag;
+
+ long
+ offset;
+
+ char
+ quote;
+} TokenInfo;
+
+/*
+ Utilities methods.
+*/
+
+#undef ARG_NOT_USED
+#define ARG_NOT_USED(arg) (void) arg
+
+/*
+ A callback function which behaves similar to strlcpy() except which
+ optionally translates text while it is copied and always returns
+ the number of characters which were actually copied rather than
+ the number of characters which were available to copy.
+*/
+typedef size_t
+ (*MagickTextTranslate)(char *dst, const char *src, const size_t size);
+
+extern MagickExport char
+ *AcquireString(const char *),
+ *AllocateString(const char *),
+ *Base64Encode(const unsigned char *,const size_t,size_t *),
+ *EscapeString(const char *,const char),
+ *GetPageGeometry(const char *),
+ **ListFiles(const char *,const char *,long *),
+ **StringToArgv(const char *,int *),
+ **StringToList(const char *),
+ *TranslateText(const ImageInfo *,Image *,const char *),
+ *TranslateTextEx(const ImageInfo *,Image *,const char *,MagickTextTranslate);
+
+extern MagickExport const char
+ *GetClientFilename(void),
+ *GetClientName(void),
+ *GetClientPath(void),
+ *SetClientFilename(const char *),
+ *SetClientName(const char *),
+ *SetClientPath(const char *);
+
+extern MagickExport double
+ StringToDouble(const char *,const double);
+
+extern MagickExport int
+ GetGeometry(const char *,long *,long *,unsigned long *,unsigned long *),
+ GlobExpression(const char *,const char *),
+ LocaleNCompare(const char *,const char *,const size_t),
+ LocaleCompare(const char *,const char *),
+ GetMagickDimension(const char *str,double *width,double *height,double *xoff,double *yoff),
+ GetMagickGeometry(const char *geometry,long *x,long *y,unsigned long *width,
+ unsigned long *height),
+ MagickRandReentrant(unsigned int *seed) MAGICK_FUNC_DEPRECATED,
+ MagickSpawnVP(const unsigned int verbose, const char *file, char *const argv[]),
+ SystemCommand(const unsigned int,const char *),
+ Tokenizer(TokenInfo *,unsigned,char *,size_t,char *,char *,char *,char *,
+ char,char *,int *,char *);
+
+extern MagickExport unsigned int
+ MagickRandNewSeed(void) MAGICK_FUNC_DEPRECATED;
+
+extern MagickExport unsigned char
+ *Base64Decode(const char *, size_t *);
+
+extern MagickExport MagickPassFail
+ CloneString(char **,const char *),
+ ConcatenateString(char **,const char *),
+ ExpandFilenames(int *,char ***),
+ GetExecutionPath(char *),
+ GetExecutionPathUsingName(char *),
+ MagickCreateDirectoryPath(const char *dir,ExceptionInfo *exception);
+
+extern MagickExport MagickBool
+ IsAccessible(const char *),
+ IsAccessibleNoLogging(const char *),
+ IsAccessibleAndNotEmpty(const char *),
+ IsGeometry(const char *),
+ IsGlob(const char *),
+ IsWriteable(const char *),
+ MagickSceneFileName(char *filename,const char* filename_template,
+ const char* scene_template,const MagickBool force,unsigned long scene),
+ SubstituteString(char **buffer,const char *search,const char *replace);
+
+extern MagickExport unsigned long
+ MultilineCensus(const char *);
+
+extern MagickExport void
+ AppendImageFormat(const char *,char *),
+ DefineClientName(const char *),
+ DefineClientPathAndName(const char *),
+ ExpandFilename(char *),
+ FormatSize(const magick_int64_t size,char *format),
+ GetPathComponent(const char *,PathType,char *),
+ GetToken(const char *,char **,char *) MAGICK_FUNC_DEPRECATED,
+ LocaleLower(char *),
+ LocaleUpper(char *),
+ Strip(char *),
+ SetGeometry(const Image *,RectangleInfo *);
+
+extern MagickExport void
+ FormatString(char *string,const char *format,...) MAGICK_ATTRIBUTE((__format__ (__printf__,2,3))),
+ FormatStringList(char *string,const char *format,va_list operands),
+ MagickFormatString(char *string,const size_t length,const char *format,...) MAGICK_ATTRIBUTE((__format__ (__printf__,3,4))),
+ MagickFormatStringList(char *string,const size_t length,const char *format,va_list operands);
+
+extern MagickExport magick_int64_t
+ MagickSizeStrToInt64(const char *str,const unsigned int kilo);
+
+extern MagickExport size_t
+ MagickGetToken(const char *start,char **end,char *token,
+ const size_t buffer_length),
+ MagickStripSpacesFromString(char *string),
+ MagickStrlCat(char *dst, const char *src, const size_t size) MAGICK_FUNC_NONNULL,
+ MagickStrlCpy(char *dst, const char *src, const size_t size) MAGICK_FUNC_NONNULL,
+ MagickStrlCpyTrunc(char *dst, const char *src, const size_t size) MAGICK_FUNC_NONNULL;
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+/*
+ Force argument into range accepted by <ctype.h> functions.
+*/
+#define CTYPE_ARG(value) ((int) ((unsigned char) (value)))
+
+#if !defined(HAVE_STRLCAT)
+# define strlcat(dst,src,size) MagickStrlCat(dst,src,size)
+#endif
+
+#if !defined(HAVE_STRLCPY)
+# define strlcpy(dst,src,size) MagickStrlCpy(dst,src,size)
+#endif
+
+extern double MagickFmin(const double x, const double y) MAGICK_FUNC_CONST;
+extern double MagickFmax(const double x, const double y) MAGICK_FUNC_CONST;
+
+extern MagickExport MagickPassFail MagickAtoFChk(const char *str, double *value);
+extern MagickExport MagickPassFail MagickAtoIChk(const char *str, int *value);
+extern MagickExport MagickPassFail MagickAtoUIChk(const char *str, unsigned int *value);
+extern MagickExport MagickPassFail MagickAtoLChk(const char *str, long *value);
+extern MagickExport MagickPassFail MagickAtoULChk(const char *str, unsigned long *value);
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/version.c b/magick/version.c
new file mode 100644
index 0000000..e82b756
--- /dev/null
+++ b/magick/version.c
@@ -0,0 +1,113 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% V V EEEEE RRRR SSSSS IIIII OOO N N %
+% V V E R R SS I O O NN N %
+% V V EEE RRRR SSS I O O N N N %
+% V V E R R SS I O O N NN %
+% V EEEEE R R SSSSS IIIII OOO N N %
+% %
+% %
+% GraphicsMagick Version Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% September 2002 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+#include "magick/studio.h"
+#include "magick/version.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M a g i c k C o p y r i g h t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickCopyright() returns the GraphicsMagick API copyright as a string.
+%
+% The format of the GetMagickCopyright method is:
+%
+% const char *GetMagickCopyright(void)
+%
+%
+*/
+MagickExport const char *GetMagickCopyright(void)
+{
+ return(MagickCopyright);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M a g i c k V e r s i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickVersion() returns the GraphicsMagick API version as a string and
+% as a number.
+%
+% The format of the GetMagickVersion method is:
+%
+% const char *GetMagickVersion(unsigned long *version)
+%
+% A description of each parameter follows:
+%
+% o version: The GraphicsMagick version is returned as a number.
+%
+*/
+MagickExport const char *GetMagickVersion(unsigned long *version)
+{
+ if (version != (unsigned long *) NULL)
+ *version=MagickLibVersion;
+ return(MagickVersion);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% G e t M a g i c k W e b S i t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetMagickWebSite() returns the GraphicsMagick web site URL as a string.
+%
+% The format of the GetMagickWebSite method is:
+%
+% const char *GetMagickWebSite(void)
+%
+%
+*/
+MagickExport const char *GetMagickWebSite(void)
+{
+ return(MagickWebSite);
+}
diff --git a/magick/version.h b/magick/version.h
new file mode 100644
index 0000000..f5f1155
--- /dev/null
+++ b/magick/version.h
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2003 - 2016 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick version and copyright.
+*/
+#ifndef _MAGICK_VERSION_H
+#define _MAGICK_VERSION_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Define declarations.
+
+ MagickLibVersion and MagickLibVersionNumber are defined differently
+ than they are in ImageMagick. The three fields are based on library
+ interface versioning. Each field in MagickLibVersion is one byte.
+ The most significant field (third byte from the right) defines the
+ library major interface, which is incremented whenever the library
+ ABI changes incompatibly with preceding versions. The second field
+ identifies an interface (a span) in a series of upward-compatible
+ interfaces with the same major interface (such as when only new
+ functions have) been added. The least significant field specifies
+ the revision across 100% compatible interfaces.
+
+ MagickLibVersionText provides a simple human-readable string for
+ identifying the release.
+*/
+#define MagickPackageName "GraphicsMagick"
+#define MagickCopyright "Copyright (C) 2002-2017 GraphicsMagick Group.\nAdditional copyrights and licenses apply to this software.\nSee http://www.GraphicsMagick.org/www/Copyright.html for details."
+#define MagickLibVersion 0x191600
+#define MagickLibVersionText "1.3.26"
+#define MagickLibVersionNumber 19,16,0
+#define MagickChangeDate "20170704"
+#define MagickReleaseDate "2017-07-04"
+
+/*
+ The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines
+ provide both the newest and oldest interfaces supported by the
+ library. The 'newest' interface is incremented if new interfaces
+ are added to the library. The 'oldest' interface is reset to the
+ value of 'newest' if an existing interface is changed incompatibly,
+ or an interface is removed. This scheme is similar to that used by
+ ELF libraries.
+
+ Note that the values used are related to those in
+ MagickLibVersionNumber, but these are broken out and simplified so
+ that they can be easily used in C pre-processor logic.
+*/
+#define MagickLibInterfaceNewest 19
+#define MagickLibInterfaceOldest 3
+
+#if (QuantumDepth == 8)
+#define MagickQuantumDepth "Q8"
+#elif (QuantumDepth == 16)
+#define MagickQuantumDepth "Q16"
+#elif (QuantumDepth == 32)
+#define MagickQuantumDepth "Q32"
+#else
+# error Unsupported quantum depth.
+#endif
+
+#define MagickVersion MagickPackageName " " MagickLibVersionText " " \
+ MagickReleaseDate " " MagickQuantumDepth " " MagickWebSite
+#define MagickWebSite "http://www." MagickPackageName ".org/"
+
+/*
+ Method declarations.
+*/
+extern MagickExport const char
+ *GetMagickCopyright(void),
+ *GetMagickVersion(unsigned long *),
+ *GetMagickWebSite(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
diff --git a/magick/version.h.in b/magick/version.h.in
new file mode 100644
index 0000000..ad4ce36
--- /dev/null
+++ b/magick/version.h.in
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2003 - 2016 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick version and copyright.
+*/
+#ifndef _MAGICK_VERSION_H
+#define _MAGICK_VERSION_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Define declarations.
+
+ MagickLibVersion and MagickLibVersionNumber are defined differently
+ than they are in ImageMagick. The three fields are based on library
+ interface versioning. Each field in MagickLibVersion is one byte.
+ The most significant field (third byte from the right) defines the
+ library major interface, which is incremented whenever the library
+ ABI changes incompatibly with preceding versions. The second field
+ identifies an interface (a span) in a series of upward-compatible
+ interfaces with the same major interface (such as when only new
+ functions have) been added. The least significant field specifies
+ the revision across 100% compatible interfaces.
+
+ MagickLibVersionText provides a simple human-readable string for
+ identifying the release.
+*/
+#define MagickPackageName "@PACKAGE_NAME@"
+#define MagickCopyright "Copyright (C) 2002-2017 GraphicsMagick Group.\nAdditional copyrights and licenses apply to this software.\nSee http://www.GraphicsMagick.org/www/Copyright.html for details."
+#define MagickLibVersion @MAGICK_LIB_VERSION@
+#define MagickLibVersionText "@MAGICK_LIB_VERSION_TEXT@"
+#define MagickLibVersionNumber @MAGICK_LIB_VERSION_NUMBER@
+#define MagickChangeDate "@PACKAGE_CHANGE_DATE@"
+#define MagickReleaseDate "@PACKAGE_RELEASE_DATE@"
+
+/*
+ The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines
+ provide both the newest and oldest interfaces supported by the
+ library. The 'newest' interface is incremented if new interfaces
+ are added to the library. The 'oldest' interface is reset to the
+ value of 'newest' if an existing interface is changed incompatibly,
+ or an interface is removed. This scheme is similar to that used by
+ ELF libraries.
+
+ Note that the values used are related to those in
+ MagickLibVersionNumber, but these are broken out and simplified so
+ that they can be easily used in C pre-processor logic.
+*/
+#define MagickLibInterfaceNewest @MAGICK_LIB_INTERFACE_NEWEST@
+#define MagickLibInterfaceOldest @MAGICK_LIB_INTERFACE_OLDEST@
+
+#if (QuantumDepth == 8)
+#define MagickQuantumDepth "Q8"
+#elif (QuantumDepth == 16)
+#define MagickQuantumDepth "Q16"
+#elif (QuantumDepth == 32)
+#define MagickQuantumDepth "Q32"
+#else
+# error Unsupported quantum depth.
+#endif
+
+#define MagickVersion MagickPackageName " " MagickLibVersionText " " \
+ MagickReleaseDate " " MagickQuantumDepth " " MagickWebSite
+#define MagickWebSite "http://www." MagickPackageName ".org/"
+
+/*
+ Method declarations.
+*/
+extern MagickExport const char
+ *GetMagickCopyright(void),
+ *GetMagickVersion(unsigned long *),
+ *GetMagickWebSite(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
diff --git a/magick/widget.c b/magick/widget.c
new file mode 100644
index 0000000..10a3049
--- /dev/null
+++ b/magick/widget.c
@@ -0,0 +1,9462 @@
+/*
+% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+% Copyright 1991-1999 E. I. du Pont de Nemours and Company
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% %
+% W W IIIII DDDD GGGG EEEEE TTTTT %
+% W W I D D G E T %
+% W W W I D D G GG EEE T %
+% WW WW I D D G G E T %
+% W W IIIII DDDD GGGG EEEEE T %
+% %
+% %
+% X11 User Interface Methods for GraphicsMagick %
+% %
+% %
+% Software Design %
+% John Cristy %
+% September 1993 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/magick.h"
+#include "magick/utility.h"
+#include "magick/xwindow.h"
+#if defined(HasX11)
+
+/*
+ Define declarations.
+*/
+#define AreaIsActive(matte_info,position) \
+ ((position.y >= (int) (matte_info.y-matte_info.bevel_width)) && \
+ (position.y < (long) (matte_info.y+matte_info.height+matte_info.bevel_width)))
+#define Extent(s) ((int) strlen(s))
+#define MatteIsActive(matte_info,position) \
+ ((position.x >= (int) (matte_info.x-matte_info.bevel_width)) && \
+ (position.y >= (int) (matte_info.y-matte_info.bevel_width)) && \
+ (position.x < (long) (matte_info.x+matte_info.width+matte_info.bevel_width)) && \
+ (position.y < (long) (matte_info.y+matte_info.height+matte_info.bevel_width)))
+#define MaxTextWidth (255*XTextWidth(font_info,"_",1))
+#define MinTextWidth (26*XTextWidth(font_info,"_",1))
+#define QuantumMargin Max(font_info->max_bounds.width,12)
+#define WindowIsActive(window_info,position) \
+ ((position.x >= 0) && (position.y >= 0) && \
+ (position.x < (long) window_info.width) && \
+ (position.y < (long) window_info.height))
+
+/*
+ Variable declarations.
+*/
+static MagickXWidgetInfo
+ monitor_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ submenu_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ toggle_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+/*
+ Constant declarations.
+*/
+static const unsigned int
+ BorderOffset = 4,
+ DoubleClick = 250;
+
+/*
+ Method prototypes.
+*/
+static void
+ XDrawMatte(Display *,const MagickXWindowInfo *,const MagickXWidgetInfo *),
+ XSetBevelColor(Display *,const MagickXWindowInfo *,const unsigned int),
+ XSetMatteColor(Display *,const MagickXWindowInfo *,const unsigned int),
+ XSetTextColor(Display *,const MagickXWindowInfo *,const unsigned int);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w B e v e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawBevel "sets off" an area with a highlighted upper and
+% left bevel and a shadowed lower and right bevel. The highlighted and
+% shadowed bevels create a 3-D effect.
+%
+% The format of the XDrawBevel function is:
+%
+% XDrawBevel(display,window_info,bevel_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o bevel_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the bevel.
+%
+%
+*/
+static void XDrawBevel(Display *display,const MagickXWindowInfo *window_info,
+ const MagickXWidgetInfo *bevel_info)
+{
+ int
+ x1,
+ x2,
+ y1,
+ y2;
+
+ unsigned int
+ bevel_width;
+
+ XPoint
+ points[6];
+
+ /*
+ Draw upper and left beveled border.
+ */
+ x1=bevel_info->x;
+ y1=bevel_info->y+bevel_info->height;
+ x2=bevel_info->x+bevel_info->width;
+ y2=bevel_info->y;
+ bevel_width=bevel_info->bevel_width;
+ points[0].x=x1;
+ points[0].y=y1;
+ points[1].x=x1;
+ points[1].y=y2;
+ points[2].x=x2;
+ points[2].y=y2;
+ points[3].x=x2+bevel_width;
+ points[3].y=y2-bevel_width;
+ points[4].x=x1-bevel_width;
+ points[4].y=y2-bevel_width;
+ points[5].x=x1-bevel_width;
+ points[5].y=y1+bevel_width;
+ XSetBevelColor(display,window_info,bevel_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,6,Complex,CoordModeOrigin);
+ /*
+ Draw lower and right beveled border.
+ */
+ points[0].x=x1;
+ points[0].y=y1;
+ points[1].x=x2;
+ points[1].y=y1;
+ points[2].x=x2;
+ points[2].y=y2;
+ points[3].x=x2+bevel_width;
+ points[3].y=y2-bevel_width;
+ points[4].x=x2+bevel_width;
+ points[4].y=y1+bevel_width;
+ points[5].x=x1-bevel_width;
+ points[5].y=y1+bevel_width;
+ XSetBevelColor(display,window_info,(unsigned int) !bevel_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,6,Complex,CoordModeOrigin);
+ (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w B e v e l e d B u t t o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawBeveledButton draws a button with a highlighted upper and
+% left bevel and a shadowed lower and right bevel. The highlighted and
+% shadowed bevels create a 3-D effect.
+%
+% The format of the XDrawBeveledButton function is:
+%
+% XDrawBeveledButton(display,window_info,button_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o button_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the button.
+%
+%
+*/
+static void XDrawBeveledButton(Display *display,const MagickXWindowInfo *window_info,
+ const MagickXWidgetInfo *button_info)
+{
+ int
+ x,
+ y;
+
+ unsigned int
+ width;
+
+ XFontStruct
+ *font_info;
+
+ XRectangle
+ crop_info;
+
+ /*
+ Draw matte.
+ */
+ XDrawBevel(display,window_info,button_info);
+ XSetMatteColor(display,window_info,button_info->raised);
+ (void) XFillRectangle(display,window_info->id,window_info->widget_context,
+ button_info->x,button_info->y,button_info->width,button_info->height);
+ x=button_info->x-button_info->bevel_width-1;
+ y=button_info->y-button_info->bevel_width-1;
+ (void) XSetForeground(display,window_info->widget_context,
+ window_info->pixel_info->trough_color.pixel);
+ if (button_info->raised || (window_info->depth == 1))
+ (void) XDrawRectangle(display,window_info->id,window_info->widget_context,
+ x,y,button_info->width+(button_info->bevel_width << 1)+1,
+ button_info->height+(button_info->bevel_width << 1)+1);
+ if (button_info->text == (char *) NULL)
+ return;
+ /*
+ Set cropping region.
+ */
+ crop_info.width=button_info->width;
+ crop_info.height=button_info->height;
+ crop_info.x=button_info->x;
+ crop_info.y=button_info->y;
+ /*
+ Draw text.
+ */
+ font_info=window_info->font_info;
+ width=XTextWidth(font_info,button_info->text,Extent(button_info->text));
+ x=button_info->x+(QuantumMargin >> 1);
+ if (button_info->center)
+ x=button_info->x+(button_info->width >> 1)-(width >> 1);
+ y=button_info->y+((button_info->height-
+ (font_info->ascent+font_info->descent)) >> 1)+font_info->ascent;
+ if ((int) button_info->width == (QuantumMargin >> 1))
+ {
+ /*
+ Option button-- write label to right of button.
+ */
+ XSetTextColor(display,window_info,True);
+ x=button_info->x+button_info->width+button_info->bevel_width+
+ (QuantumMargin >> 1);
+ (void) XDrawString(display,window_info->id,window_info->widget_context,
+ x,y,button_info->text,Extent(button_info->text));
+ return;
+ }
+ (void) XSetClipRectangles(display,window_info->widget_context,0,0,&crop_info,
+ 1,Unsorted);
+ XSetTextColor(display,window_info,button_info->raised);
+ (void) XDrawString(display,window_info->id,window_info->widget_context,x,y,
+ button_info->text,Extent(button_info->text));
+ (void) XSetClipMask(display,window_info->widget_context,None);
+ if (!button_info->raised)
+ MagickXDelay(display,SuspendTime << 2);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w B e v e l e d M a t t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawBeveledMatte draws a matte with a shadowed upper and
+% left bevel and a highlighted lower and right bevel. The highlighted and
+% shadowed bevels create a 3-D effect.
+%
+% The format of the XDrawBeveledMatte function is:
+%
+% XDrawBeveledMatte(display,window_info,matte_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o matte_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the matte.
+%
+%
+*/
+static void XDrawBeveledMatte(Display *display,const MagickXWindowInfo *window_info,
+ const MagickXWidgetInfo *matte_info)
+{
+ /*
+ Draw matte.
+ */
+ XDrawBevel(display,window_info,matte_info);
+ XDrawMatte(display,window_info,matte_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w M a t t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawMatte fills a rectangular area with the matte color.
+%
+% The format of the XDrawMatte function is:
+%
+% XDrawMatte(display,window_info,matte_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o matte_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the matte.
+%
+%
+*/
+static void XDrawMatte(Display *display,const MagickXWindowInfo *window_info,
+ const MagickXWidgetInfo *matte_info)
+{
+ /*
+ Draw matte.
+ */
+ if (!matte_info->trough || (window_info->depth == 1))
+ (void) XFillRectangle(display,window_info->id,
+ window_info->highlight_context,matte_info->x,matte_info->y,
+ matte_info->width,matte_info->height);
+ else
+ {
+ (void) XSetForeground(display,window_info->widget_context,
+ window_info->pixel_info->trough_color.pixel);
+ (void) XFillRectangle(display,window_info->id,window_info->widget_context,
+ matte_info->x,matte_info->y,matte_info->width,matte_info->height);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w M a t t e T e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawMatteText draws a matte with text. If the text exceeds the
+% extents of the text, a portion of the text relative to the cursor is
+% displayed.
+%
+% The format of the XDrawMatteText function is:
+%
+% XDrawMatteText(display,window_info,text_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o text_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the text.
+%
+%
+*/
+static void XDrawMatteText(Display *display,const MagickXWindowInfo *window_info,
+ MagickXWidgetInfo *text_info)
+{
+ const char
+ *text;
+
+ int
+ n,
+ x,
+ y;
+
+ register int
+ i;
+
+ unsigned int
+ height,
+ width;
+
+ XFontStruct
+ *font_info;
+
+ XRectangle
+ crop_info;
+
+ /*
+ Clear the text area.
+ */
+ XSetMatteColor(display,window_info,False);
+ (void) XFillRectangle(display,window_info->id,window_info->widget_context,
+ text_info->x,text_info->y,text_info->width,text_info->height);
+ if (text_info->text == (char *) NULL)
+ return;
+ XSetTextColor(display,window_info,text_info->highlight);
+ font_info=window_info->font_info;
+ x=text_info->x+(QuantumMargin >> 2);
+ y=text_info->y+font_info->ascent+(text_info->height >> 2);
+ width=text_info->width-(QuantumMargin >> 1);
+ height=font_info->ascent+font_info->descent;
+ if (*text_info->text == '\0')
+ {
+ /*
+ No text-- just draw cursor.
+ */
+ (void) XDrawLine(display,window_info->id,window_info->annotate_context,
+ x,y+3,x,y-height+3);
+ return;
+ }
+ /*
+ Set cropping region.
+ */
+ crop_info.width=text_info->width;
+ crop_info.height=text_info->height;
+ crop_info.x=text_info->x;
+ crop_info.y=text_info->y;
+ /*
+ Determine beginning of the visible text.
+ */
+ if (text_info->cursor < text_info->marker)
+ text_info->marker=text_info->cursor;
+ else
+ {
+ text=text_info->marker;
+ if (XTextWidth(font_info,(char *) text,(int) (text_info->cursor-text)) >
+ (int) width)
+ {
+ text=text_info->text;
+ for (i=0; i < Extent(text); i++)
+ {
+ n=XTextWidth(font_info,(char *) text+i,(int)
+ (text_info->cursor-text-i));
+ if (n <= (int) width)
+ break;
+ }
+ text_info->marker=(char *) text+i;
+ }
+ }
+ /*
+ Draw text and cursor.
+ */
+ if (!text_info->highlight)
+ {
+ (void) XSetClipRectangles(display,window_info->widget_context,0,0,
+ &crop_info,1,Unsorted);
+ (void) XDrawString(display,window_info->id,window_info->widget_context,
+ x,y,text_info->marker,Extent(text_info->marker));
+ (void) XSetClipMask(display,window_info->widget_context,None);
+ }
+ else
+ {
+ (void) XSetClipRectangles(display,window_info->annotate_context,0,0,
+ &crop_info,1,Unsorted);
+ width=XTextWidth(font_info,text_info->marker,Extent(text_info->marker));
+ (void) XFillRectangle(display,window_info->id,
+ window_info->annotate_context,x,y-font_info->ascent,width,height);
+ (void) XSetClipMask(display,window_info->annotate_context,None);
+ (void) XSetClipRectangles(display,window_info->highlight_context,0,0,
+ &crop_info,1,Unsorted);
+ (void) XDrawString(display,window_info->id,
+ window_info->highlight_context,x,y,text_info->marker,
+ Extent(text_info->marker));
+ (void) XSetClipMask(display,window_info->highlight_context,None);
+ }
+ x+=XTextWidth(font_info,text_info->marker,(int)
+ (text_info->cursor-text_info->marker));
+ (void) XDrawLine(display,window_info->id,window_info->annotate_context,x,y+3,
+ x,y-height+3);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w T r i a n g l e E a s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawTriangleEast draws a triangle with a highlighted left
+% bevel and a shadowed right and lower bevel. The highlighted and
+% shadowed bevels create a 3-D effect.
+%
+% The format of the XDrawTriangleEast function is:
+%
+% XDrawTriangleEast(display,window_info,triangle_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o triangle_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the triangle.
+%
+%
+*/
+static void XDrawTriangleEast(Display *display,const MagickXWindowInfo *window_info,
+ const MagickXWidgetInfo *triangle_info)
+{
+ int
+ x1,
+ x2,
+ x3,
+ y1,
+ y2,
+ y3;
+
+ unsigned int
+ bevel_width;
+
+ XFontStruct
+ *font_info;
+
+ XPoint
+ points[4];
+
+ /*
+ Draw triangle matte.
+ */
+ x1=triangle_info->x;
+ y1=triangle_info->y;
+ x2=triangle_info->x+triangle_info->width;
+ y2=triangle_info->y+(triangle_info->height >> 1);
+ x3=triangle_info->x;
+ y3=triangle_info->y+triangle_info->height;
+ bevel_width=triangle_info->bevel_width;
+ points[0].x=x1;
+ points[0].y=y1;
+ points[1].x=x2;
+ points[1].y=y2;
+ points[2].x=x3;
+ points[2].y=y3;
+ XSetMatteColor(display,window_info,triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,3,Complex,CoordModeOrigin);
+ /*
+ Draw bottom bevel.
+ */
+ points[0].x=x2;
+ points[0].y=y2;
+ points[1].x=x3;
+ points[1].y=y3;
+ points[2].x=x3-bevel_width;
+ points[2].y=y3+bevel_width;
+ points[3].x=x2+bevel_width;
+ points[3].y=y2;
+ XSetBevelColor(display,window_info,(unsigned int) !triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ /*
+ Draw Left bevel.
+ */
+ points[0].x=x3;
+ points[0].y=y3;
+ points[1].x=x1;
+ points[1].y=y1;
+ points[2].x=x1-bevel_width+1;
+ points[2].y=y1-bevel_width;
+ points[3].x=x3-bevel_width+1;
+ points[3].y=y3+bevel_width;
+ XSetBevelColor(display,window_info,triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ /*
+ Draw top bevel.
+ */
+ points[0].x=x1;
+ points[0].y=y1;
+ points[1].x=x2;
+ points[1].y=y2;
+ points[2].x=x2+bevel_width;
+ points[2].y=y2;
+ points[3].x=x1-bevel_width;
+ points[3].y=y1-bevel_width;
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
+ if (triangle_info->text == (char *) NULL)
+ return;
+ /*
+ Write label to right of triangle.
+ */
+ font_info=window_info->font_info;
+ XSetTextColor(display,window_info,True);
+ x1=triangle_info->x+triangle_info->width+triangle_info->bevel_width+
+ (QuantumMargin >> 1);
+ y1=triangle_info->y+((triangle_info->height-
+ (font_info->ascent+font_info->descent)) >> 1)+font_info->ascent;
+ (void) XDrawString(display,window_info->id,window_info->widget_context,x1,y1,
+ triangle_info->text,Extent(triangle_info->text));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w T r i a n g l e N o r t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawTriangleNorth draws a triangle with a highlighted left
+% bevel and a shadowed right and lower bevel. The highlighted and
+% shadowed bevels create a 3-D effect.
+%
+% The format of the XDrawTriangleNorth function is:
+%
+% XDrawTriangleNorth(display,window_info,triangle_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o triangle_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the triangle.
+%
+%
+*/
+static void XDrawTriangleNorth(Display *display,const MagickXWindowInfo *window_info,
+ const MagickXWidgetInfo *triangle_info)
+{
+ int
+ x1,
+ x2,
+ x3,
+ y1,
+ y2,
+ y3;
+
+ unsigned int
+ bevel_width;
+
+ XPoint
+ points[4];
+
+ /*
+ Draw triangle matte.
+ */
+ x1=triangle_info->x;
+ y1=triangle_info->y+triangle_info->height;
+ x2=triangle_info->x+(triangle_info->width >> 1);
+ y2=triangle_info->y;
+ x3=triangle_info->x+triangle_info->width;
+ y3=triangle_info->y+triangle_info->height;
+ bevel_width=triangle_info->bevel_width;
+ points[0].x=x1;
+ points[0].y=y1;
+ points[1].x=x2;
+ points[1].y=y2;
+ points[2].x=x3;
+ points[2].y=y3;
+ XSetMatteColor(display,window_info,triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,3,Complex,CoordModeOrigin);
+ /*
+ Draw left bevel.
+ */
+ points[0].x=x1;
+ points[0].y=y1;
+ points[1].x=x2;
+ points[1].y=y2;
+ points[2].x=x2;
+ points[2].y=y2-bevel_width-2;
+ points[3].x=x1-bevel_width-1;
+ points[3].y=y1+bevel_width;
+ XSetBevelColor(display,window_info,triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ /*
+ Draw right bevel.
+ */
+ points[0].x=x2;
+ points[0].y=y2;
+ points[1].x=x3;
+ points[1].y=y3;
+ points[2].x=x3+bevel_width;
+ points[2].y=y3+bevel_width;
+ points[3].x=x2;
+ points[3].y=y2-bevel_width;
+ XSetBevelColor(display,window_info,(unsigned int) !triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ /*
+ Draw lower bevel.
+ */
+ points[0].x=x3;
+ points[0].y=y3;
+ points[1].x=x1;
+ points[1].y=y1;
+ points[2].x=x1-bevel_width;
+ points[2].y=y1+bevel_width;
+ points[3].x=x3+bevel_width;
+ points[3].y=y3+bevel_width;
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w T r i a n g l e S o u t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawTriangleSouth draws a border with a highlighted left and
+% right bevel and a shadowed lower bevel. The highlighted and shadowed
+% bevels create a 3-D effect.
+%
+% The format of the XDrawTriangleSouth function is:
+%
+% XDrawTriangleSouth(display,window_info,triangle_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o triangle_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the triangle.
+%
+%
+*/
+static void XDrawTriangleSouth(Display *display,const MagickXWindowInfo *window_info,
+ const MagickXWidgetInfo *triangle_info)
+{
+ int
+ x1,
+ x2,
+ x3,
+ y1,
+ y2,
+ y3;
+
+ unsigned int
+ bevel_width;
+
+ XPoint
+ points[4];
+
+ /*
+ Draw triangle matte.
+ */
+ x1=triangle_info->x;
+ y1=triangle_info->y;
+ x2=triangle_info->x+(triangle_info->width >> 1);
+ y2=triangle_info->y+triangle_info->height;
+ x3=triangle_info->x+triangle_info->width;
+ y3=triangle_info->y;
+ bevel_width=triangle_info->bevel_width;
+ points[0].x=x1;
+ points[0].y=y1;
+ points[1].x=x2;
+ points[1].y=y2;
+ points[2].x=x3;
+ points[2].y=y3;
+ XSetMatteColor(display,window_info,triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,3,Complex,CoordModeOrigin);
+ /*
+ Draw top bevel.
+ */
+ points[0].x=x3;
+ points[0].y=y3;
+ points[1].x=x1;
+ points[1].y=y1;
+ points[2].x=x1-bevel_width;
+ points[2].y=y1-bevel_width;
+ points[3].x=x3+bevel_width;
+ points[3].y=y3-bevel_width;
+ XSetBevelColor(display,window_info,triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ /*
+ Draw right bevel.
+ */
+ points[0].x=x2;
+ points[0].y=y2;
+ points[1].x=x3+1;
+ points[1].y=y3-bevel_width;
+ points[2].x=x3+bevel_width;
+ points[2].y=y3-bevel_width;
+ points[3].x=x2;
+ points[3].y=y2+bevel_width;
+ XSetBevelColor(display,window_info,(unsigned int) !triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ /*
+ Draw left bevel.
+ */
+ points[0].x=x1;
+ points[0].y=y1;
+ points[1].x=x2;
+ points[1].y=y2;
+ points[2].x=x2;
+ points[2].y=y2+bevel_width;
+ points[3].x=x1-bevel_width;
+ points[3].y=y1-bevel_width;
+ XSetBevelColor(display,window_info,triangle_info->raised);
+ (void) XFillPolygon(display,window_info->id,window_info->widget_context,
+ points,4,Complex,CoordModeOrigin);
+ (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X D r a w W i d g e t T e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDrawWidgetText first clears the widget and draws a text string
+% justifed left (or center) in the x-direction and centered within the
+% y-direction.
+%
+% The format of the XDrawWidgetText function is:
+%
+% XDrawWidgetText(display,window_info,text_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a XWindowText structure.
+%
+% o text_info: Specifies a pointer to MagickXWidgetInfo structure.
+%
+%
+*/
+static void XDrawWidgetText(Display *display,const MagickXWindowInfo *window_info,
+ MagickXWidgetInfo *text_info)
+{
+ GC
+ widget_context;
+
+ int
+ x,
+ y;
+
+ unsigned int
+ height,
+ width;
+
+ XFontStruct
+ *font_info;
+
+ XRectangle
+ crop_info;
+
+ /*
+ Clear the text area.
+ */
+ widget_context=window_info->annotate_context;
+ if (text_info->raised)
+ (void) XClearArea(display,window_info->id,text_info->x,text_info->y,
+ text_info->width,text_info->height,False);
+ else
+ {
+ (void) XFillRectangle(display,window_info->id,widget_context,text_info->x,
+ text_info->y,text_info->width,text_info->height);
+ widget_context=window_info->highlight_context;
+ }
+ if (text_info->text == (char *) NULL)
+ return;
+ if (*text_info->text == '\0')
+ return;
+ /*
+ Set cropping region.
+ */
+ font_info=window_info->font_info;
+ crop_info.width=text_info->width;
+ crop_info.height=text_info->height;
+ crop_info.x=text_info->x;
+ crop_info.y=text_info->y;
+ /*
+ Draw text.
+ */
+ width=XTextWidth(font_info,text_info->text,Extent(text_info->text));
+ x=text_info->x+(QuantumMargin >> 1);
+ if (text_info->center)
+ x=text_info->x+(text_info->width >> 1)-(width >> 1);
+ if (text_info->raised)
+ if (width > (text_info->width-QuantumMargin))
+ x+=(text_info->width-QuantumMargin-width);
+ height=font_info->ascent+font_info->descent;
+ y=text_info->y+((text_info->height-height) >> 1)+font_info->ascent;
+ (void) XSetClipRectangles(display,widget_context,0,0,&crop_info,1,Unsorted);
+ (void) XDrawString(display,window_info->id,widget_context,x,y,text_info->text,
+ Extent(text_info->text));
+ (void) XSetClipMask(display,widget_context,None);
+ if (x < text_info->x)
+ (void) XDrawLine(display,window_info->id,window_info->annotate_context,
+ text_info->x,text_info->y,text_info->x,text_info->y+text_info->height-1);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X E d i t T e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XEditText edits a text string as indicated by the key symbol.
+%
+% The format of the XEditText function is:
+%
+% XEditText(display,text_info,key_symbol,text,state)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o text_info: Specifies a pointer to a MagickXWidgetInfo structure. It
+% contains the extents of the text.
+%
+% o key_symbol: A X11 KeySym that indicates what editing function to
+% perform to the text.
+%
+% o text: A character string to insert into the text.
+%
+% o state: An unsigned long that indicates whether the key symbol is a
+% control character or not.
+%
+%
+*/
+static void XEditText(Display *display,MagickXWidgetInfo *text_info,
+ const KeySym key_symbol,char *text,const unsigned long state)
+{
+ switch ((int) key_symbol)
+ {
+ case XK_BackSpace:
+ case XK_Delete:
+ {
+ if (text_info->highlight)
+ {
+ /*
+ Erase the entire line of text.
+ */
+ *text_info->text='\0';
+ text_info->cursor=text_info->text;
+ text_info->marker=text_info->text;
+ text_info->highlight=False;
+ }
+ /*
+ Erase one character.
+ */
+ if (text_info->cursor != text_info->text)
+ {
+ text_info->cursor--;
+ (void) memmove(text_info->cursor,text_info->cursor+1,
+ strlen(text_info->cursor+1)+1);
+ text_info->highlight=False;
+ break;
+ }
+ }
+ case XK_Left:
+ case XK_KP_Left:
+ {
+ /*
+ Move cursor one position left.
+ */
+ if (text_info->cursor == text_info->text)
+ break;
+ text_info->cursor--;
+ break;
+ }
+ case XK_Right:
+ case XK_KP_Right:
+ {
+ /*
+ Move cursor one position right.
+ */
+ if (text_info->cursor == (text_info->text+Extent(text_info->text)))
+ break;
+ text_info->cursor++;
+ break;
+ }
+ default:
+ {
+ register char
+ *p,
+ *q;
+
+ register int
+ i;
+
+ if (state & ControlState)
+ break;
+ if (*text == '\0')
+ break;
+ if ((Extent(text_info->text)+1) >= MaxTextExtent)
+ (void) XBell(display,0);
+ else
+ {
+ if (text_info->highlight)
+ {
+ /*
+ Erase the entire line of text.
+ */
+ *text_info->text='\0';
+ text_info->cursor=text_info->text;
+ text_info->marker=text_info->text;
+ text_info->highlight=False;
+ }
+ /*
+ Insert a string into the text.
+ */
+ q=text_info->text+Extent(text_info->text)+strlen(text);
+ for (i=0; i <= Extent(text_info->cursor); i++)
+ {
+ *q=(*(q-Extent(text)));
+ q--;
+ }
+ p=text;
+ for (i=0; i < Extent(text); i++)
+ *text_info->cursor++=(*p++);
+ }
+ break;
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X G e t W i d g e t I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XGetWidgetInfo initializes the MagickXWidgetInfo structure.
+%
+% The format of the XGetWidgetInfo function is:
+%
+% XGetWidgetInfo(text,widget_info)
+%
+% A description of each parameter follows:
+%
+% o text: A string of characters associated with the widget.
+%
+% o widget_info: Specifies a pointer to a X11 MagickXWidgetInfo structure.
+%
+%
+*/
+static void XGetWidgetInfo(const char *text,MagickXWidgetInfo *widget_info)
+{
+ /*
+ Initialize widget info.
+ */
+ widget_info->id=(~0);
+ widget_info->bevel_width=3;
+ widget_info->width=1;
+ widget_info->height=1;
+ widget_info->x=0;
+ widget_info->y=0;
+ widget_info->min_y=0;
+ widget_info->max_y=0;
+ widget_info->raised=True;
+ widget_info->active=False;
+ widget_info->center=True;
+ widget_info->trough=False;
+ widget_info->highlight=False;
+ widget_info->text=(char *) text;
+ widget_info->cursor=(char *) text;
+ if (text != (char *) NULL)
+ widget_info->cursor+=Extent(text);
+ widget_info->marker=(char *) text;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X H i g h l i g h t W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XHighlightWidget draws a highlighted border around a window.
+%
+% The format of the XHighlightWidget function is:
+%
+% XHighlightWidget(display,window_info,x,y)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o x: Specifies an integer representing the rectangle offset in the
+% x-direction.
+%
+% o y: Specifies an integer representing the rectangle offset in the
+% y-direction.
+%
+%
+*/
+static void XHighlightWidget(Display *display,const MagickXWindowInfo *window_info,
+ const int x,const int y)
+{
+ /*
+ Draw the widget highlighting rectangle.
+ */
+ XSetBevelColor(display,window_info,True);
+ (void) XDrawRectangle(display,window_info->id,window_info->widget_context,x,y,
+ window_info->width-(x << 1),window_info->height-(y << 1));
+ (void) XDrawRectangle(display,window_info->id,window_info->widget_context,
+ x-1,y-1,window_info->width-(x << 1)+1,window_info->height-(y << 1)+1);
+ XSetBevelColor(display,window_info,False);
+ (void) XDrawRectangle(display,window_info->id,window_info->widget_context,
+ x-1,y-1,window_info->width-(x << 1),window_info->height-(y << 1));
+ (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X S c r e e n E v e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XScreenEvent returns True if the any event on the X server queue
+% is associated with the widget window.
+%
+% The format of the XScreenEvent function is:
+%
+% XScreenEvent(display,event,data)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o event: Specifies a pointer to a X11 XEvent structure.
+%
+% o data: Specifies a pointer to a MagickXWindows structure.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int XScreenEvent(Display *display,XEvent *event,char *data)
+{
+ MagickXWindows
+ *windows;
+
+ windows=(MagickXWindows *) data;
+ if (event->xany.window == windows->popup.id)
+ {
+ if (event->type == MapNotify)
+ windows->popup.mapped=True;
+ if (event->type == UnmapNotify)
+ windows->popup.mapped=False;
+ return(True);
+ }
+ if (event->xany.window == windows->widget.id)
+ {
+ if (event->type == MapNotify)
+ windows->widget.mapped=True;
+ if (event->type == UnmapNotify)
+ windows->widget.mapped=False;
+ return(True);
+ }
+ switch (event->type)
+ {
+ case ButtonPress:
+ {
+ if ((event->xbutton.button == Button3) &&
+ (event->xbutton.state & Mod1Mask))
+ {
+ /*
+ Convert Alt-Button3 to Button2.
+ */
+ event->xbutton.button=Button2;
+ event->xbutton.state&=(~Mod1Mask);
+ }
+ return(True);
+ }
+ case Expose:
+ {
+ if (event->xexpose.window == windows->image.id)
+ {
+ MagickXRefreshWindow(display,&windows->image,event);
+ break;
+ }
+ if (event->xexpose.window == windows->magnify.id)
+ if (event->xexpose.count == 0)
+ if (windows->magnify.mapped)
+ {
+ MagickXMakeMagnifyImage(display,windows);
+ break;
+ }
+ if (event->xexpose.window == windows->command.id)
+ if (event->xexpose.count == 0)
+ {
+ (void) MagickXCommandWidget(display,windows,(const char **) NULL,event);
+ break;
+ }
+ break;
+ }
+ case FocusOut:
+ {
+ /*
+ Set input focus for backdrop window.
+ */
+ if (event->xfocus.window == windows->image.id)
+ (void) XSetInputFocus(display,windows->image.id,RevertToNone,
+ CurrentTime);
+ return(True);
+ }
+ case ButtonRelease:
+ case KeyPress:
+ case KeyRelease:
+ case MotionNotify:
+ case SelectionNotify:
+ return(True);
+ default:
+ break;
+ }
+ return(False);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X S e t B e v e l C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XSetBevelColor sets the graphic context for drawing a beveled
+% border.
+%
+% The format of the XSetBevelColor function is:
+%
+% XSetBevelColor(display,window_info,raised)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o raised: A value other than zero indicates the color show be a
+% "highlight" color, otherwise the "shadow" color is set.
+%
+%
+*/
+static void XSetBevelColor(Display *display,const MagickXWindowInfo *window_info,
+ const unsigned int raised)
+{
+ if (window_info->depth == 1)
+ {
+ Pixmap
+ stipple;
+
+ /*
+ Monochrome window.
+ */
+ (void) XSetBackground(display,window_info->widget_context,
+ XBlackPixel(display,window_info->screen));
+ (void) XSetForeground(display,window_info->widget_context,
+ XWhitePixel(display,window_info->screen));
+ (void) XSetFillStyle(display,window_info->widget_context,
+ FillOpaqueStippled);
+ stipple=window_info->highlight_stipple;
+ if (!raised)
+ stipple=window_info->shadow_stipple;
+ (void) XSetStipple(display,window_info->widget_context,stipple);
+ }
+ else
+ if (raised)
+ (void) XSetForeground(display,window_info->widget_context,
+ window_info->pixel_info->highlight_color.pixel);
+ else
+ (void) XSetForeground(display,window_info->widget_context,
+ window_info->pixel_info->shadow_color.pixel);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X S e t M a t t e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XSetMatteColor sets the graphic context for drawing the matte.
+%
+% The format of the XSetMatteColor function is:
+%
+% XSetMatteColor(display,window_info,raised)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o raised: A value other than zero indicates the matte is active.
+%
+%
+*/
+static void XSetMatteColor(Display *display,const MagickXWindowInfo *window_info,
+ const unsigned int raised)
+{
+ if (window_info->depth == 1)
+ {
+ /*
+ Monochrome window.
+ */
+ if (raised)
+ (void) XSetForeground(display,window_info->widget_context,
+ XWhitePixel(display,window_info->screen));
+ else
+ (void) XSetForeground(display,window_info->widget_context,
+ XBlackPixel(display,window_info->screen));
+ }
+ else
+ if (raised)
+ (void) XSetForeground(display,window_info->widget_context,
+ window_info->pixel_info->matte_color.pixel);
+ else
+ (void) XSetForeground(display,window_info->widget_context,
+ window_info->pixel_info->depth_color.pixel);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ X S e t T e x t C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XSetTextColor sets the graphic context for drawing text on a
+% matte.
+%
+% The format of the XSetTextColor function is:
+%
+% XSetTextColor(display,window_info,raised)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+% o raised: A value other than zero indicates the color show be a
+% "highlight" color, otherwise the "shadow" color is set.
+%
+%
+*/
+static void XSetTextColor(Display *display,const MagickXWindowInfo *window_info,
+ const unsigned int raised)
+{
+ long
+ foreground,
+ matte;
+
+ if (window_info->depth == 1)
+ {
+ /*
+ Monochrome window.
+ */
+ if (raised)
+ (void) XSetForeground(display,window_info->widget_context,
+ XBlackPixel(display,window_info->screen));
+ else
+ (void) XSetForeground(display,window_info->widget_context,
+ XWhitePixel(display,window_info->screen));
+ return;
+ }
+ foreground=(long) PixelIntensity(&window_info->pixel_info->foreground_color);
+ matte=(long) PixelIntensity(&window_info->pixel_info->matte_color);
+ if (AbsoluteValue(foreground-matte) > (65535L >> 3))
+ (void) XSetForeground(display,window_info->widget_context,
+ window_info->pixel_info->foreground_color.pixel);
+ else
+ (void) XSetForeground(display,window_info->widget_context,
+ window_info->pixel_info->background_color.pixel);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X C o l o r B r o w s e r W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXColorBrowserWidget displays a Color Browser widget with a color
+% query to the user. The user keys a reply and presses the Action or Cancel
+% button to exit. The typed text is returned as the reply function parameter.
+%
+% The format of the MagickXColorBrowserWidget method is:
+%
+% void MagickXColorBrowserWidget(Display *display,MagickXWindows *windows,
+% const char *action,char *reply)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o action: Specifies a pointer to the action of this widget.
+%
+% o reply: The response from the user is returned in this parameter.
+%
+%
+*/
+MagickExport void MagickXColorBrowserWidget(Display *display,MagickXWindows *windows,
+ const char *action,char *reply)
+{
+#define CancelButtonText "Cancel"
+#define ColornameText "Name:"
+#define ColorPatternText "Pattern:"
+#define GrabButtonText "Grab"
+#define ResetButtonText "Reset"
+
+ char
+ **colorlist,
+ primary_selection[MaxTextExtent],
+ reset_pattern[MaxTextExtent],
+ text[MaxTextExtent];
+
+ int
+ height,
+ status,
+ text_width,
+ width,
+ x,
+ y;
+
+ register int
+ i;
+
+ static char
+ glob_pattern[MaxTextExtent] = "*";
+
+ static char
+ mask = CWWidth | CWHeight | CWX | CWY;
+
+ unsigned int
+ visible_colors;
+
+ unsigned long
+ colors,
+ delay,
+ state;
+
+ XColor
+ color;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ action_info,
+ cancel_info,
+ expose_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ grab_info,
+ list_info,
+ mode_info,
+ north_info,
+ reply_info,
+ reset_info,
+ scroll_info,
+ selection_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ slider_info,
+ south_info,
+ text_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Get color list and sort in ascending order.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(action != (char *) NULL);
+ assert(reply != (char *) NULL);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) strcpy(reset_pattern,"*");
+ colorlist=GetColorList(glob_pattern,&colors);
+ if (colorlist == (char **) NULL)
+ {
+ /*
+ Pattern failed, obtain all the colors.
+ */
+ (void) strcpy(glob_pattern,"*");
+ colorlist=GetColorList(glob_pattern,&colors);
+ if (colorlist == (char **) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to obtain colors names:",
+ glob_pattern);
+ (void) MagickXDialogWidget(display,windows,action,"Enter color name:",
+ reply);
+ return;
+ }
+ }
+ /*
+ Determine Color Browser widget attributes.
+ */
+ font_info=windows->widget.font_info;
+ text_width=0;
+ for (i=0; i < (long) colors; i++)
+ if (XTextWidth(font_info,colorlist[i],Extent(colorlist[i])) > text_width)
+ text_width=XTextWidth(font_info,colorlist[i],Extent(colorlist[i]));
+ width=XTextWidth(font_info,(char *) action,Extent(action));
+ if (XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)) > width)
+ width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText));
+ if (XTextWidth(font_info,ResetButtonText,Extent(ResetButtonText)) > width)
+ width=XTextWidth(font_info,ResetButtonText,Extent(ResetButtonText));
+ if (XTextWidth(font_info,GrabButtonText,Extent(GrabButtonText)) > width)
+ width=XTextWidth(font_info,GrabButtonText,Extent(GrabButtonText));
+ width+=QuantumMargin;
+ if (XTextWidth(font_info,ColorPatternText,Extent(ColorPatternText)) > width)
+ width=XTextWidth(font_info,ColorPatternText,Extent(ColorPatternText));
+ if (XTextWidth(font_info,ColornameText,Extent(ColornameText)) > width)
+ width=XTextWidth(font_info,ColornameText,Extent(ColornameText));
+ height=font_info->ascent+font_info->descent;
+ /*
+ Position Color Browser widget.
+ */
+ windows->widget.width=width+Min(text_width,MaxTextWidth)+6*QuantumMargin;
+ windows->widget.min_width=width+MinTextWidth+4*QuantumMargin;
+ if (windows->widget.width < windows->widget.min_width)
+ windows->widget.width=windows->widget.min_width;
+ windows->widget.height=((81*height) >> 2)+((13*QuantumMargin) >> 1)+4;
+ windows->widget.min_height=((23*height) >> 1)+((13*QuantumMargin) >> 1)+4;
+ if (windows->widget.height < windows->widget.min_height)
+ windows->widget.height=windows->widget.min_height;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map Color Browser widget.
+ */
+ (void) strcpy(windows->widget.name,"Browse and Select a Color");
+ status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->widget.id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
+ mask,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ /*
+ Respond to X events.
+ */
+ XGetWidgetInfo((char *) NULL,&slider_info);
+ XGetWidgetInfo((char *) NULL,&north_info);
+ XGetWidgetInfo((char *) NULL,&south_info);
+ visible_colors=0;
+ delay=SuspendTime << 2;
+ state=UpdateConfigurationState;
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ int
+ id;
+
+ /*
+ Initialize button information.
+ */
+ XGetWidgetInfo(CancelButtonText,&cancel_info);
+ cancel_info.width=width;
+ cancel_info.height=(3*height) >> 1;
+ cancel_info.x=windows->widget.width-cancel_info.width-QuantumMargin-2;
+ cancel_info.y=windows->widget.height-cancel_info.height-QuantumMargin;
+ XGetWidgetInfo(action,&action_info);
+ action_info.width=width;
+ action_info.height=(3*height) >> 1;
+ action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
+ (action_info.bevel_width << 1));
+ action_info.y=cancel_info.y;
+ XGetWidgetInfo(GrabButtonText,&grab_info);
+ grab_info.width=width;
+ grab_info.height=(3*height) >> 1;
+ grab_info.x=QuantumMargin;
+ grab_info.y=((5*QuantumMargin) >> 1)+height;
+ XGetWidgetInfo(ResetButtonText,&reset_info);
+ reset_info.width=width;
+ reset_info.height=(3*height) >> 1;
+ reset_info.x=QuantumMargin;
+ reset_info.y=grab_info.y+grab_info.height+QuantumMargin;
+ /*
+ Initialize reply information.
+ */
+ XGetWidgetInfo(reply,&reply_info);
+ reply_info.raised=False;
+ reply_info.bevel_width--;
+ reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
+ reply_info.height=height << 1;
+ reply_info.x=width+(QuantumMargin << 1);
+ reply_info.y=action_info.y-reply_info.height-QuantumMargin;
+ /*
+ Initialize mode information.
+ */
+ XGetWidgetInfo((char *) NULL,&mode_info);
+ mode_info.active=True;
+ mode_info.bevel_width=0;
+ mode_info.width=action_info.x-(QuantumMargin << 1);
+ mode_info.height=action_info.height;
+ mode_info.x=QuantumMargin;
+ mode_info.y=action_info.y;
+ /*
+ Initialize scroll information.
+ */
+ XGetWidgetInfo((char *) NULL,&scroll_info);
+ scroll_info.bevel_width--;
+ scroll_info.width=height;
+ scroll_info.height=reply_info.y-grab_info.y-(QuantumMargin >> 1);
+ scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
+ scroll_info.y=grab_info.y-reply_info.bevel_width;
+ scroll_info.raised=False;
+ scroll_info.trough=True;
+ north_info=scroll_info;
+ north_info.raised=True;
+ north_info.width-=(north_info.bevel_width << 1);
+ north_info.height=north_info.width-1;
+ north_info.x+=north_info.bevel_width;
+ north_info.y+=north_info.bevel_width;
+ south_info=north_info;
+ south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
+ south_info.height;
+ id=slider_info.id;
+ slider_info=north_info;
+ slider_info.id=id;
+ slider_info.width-=2;
+ slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
+ slider_info.bevel_width+2;
+ slider_info.height=
+ scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+2;
+ visible_colors=
+ (scroll_info.height-(height >> 3)-3)/((9*height) >> 3);
+ if (colors > visible_colors)
+ slider_info.height=(visible_colors*slider_info.height)/colors;
+ slider_info.max_y=south_info.y-south_info.bevel_width-
+ slider_info.bevel_width-2;
+ slider_info.x=scroll_info.x+slider_info.bevel_width+1;
+ slider_info.y=slider_info.min_y;
+ expose_info=scroll_info;
+ expose_info.y=slider_info.y;
+ /*
+ Initialize list information.
+ */
+ XGetWidgetInfo((char *) NULL,&list_info);
+ list_info.raised=False;
+ list_info.bevel_width--;
+ list_info.width=scroll_info.x-reply_info.x-(QuantumMargin >> 1);
+ list_info.height=scroll_info.height;
+ list_info.x=reply_info.x;
+ list_info.y=scroll_info.y;
+ if (!windows->widget.mapped)
+ state|=JumpListState;
+ /*
+ Initialize text information.
+ */
+ *text='\0';
+ XGetWidgetInfo(text,&text_info);
+ text_info.center=False;
+ text_info.width=reply_info.width;
+ text_info.height=height;
+ text_info.x=list_info.x-(QuantumMargin >> 1);
+ text_info.y=QuantumMargin;
+ /*
+ Initialize selection information.
+ */
+ XGetWidgetInfo((char *) NULL,&selection_info);
+ selection_info.center=False;
+ selection_info.width=list_info.width;
+ selection_info.height=(9*height) >> 3;
+ selection_info.x=list_info.x;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw Color Browser window.
+ */
+ x=QuantumMargin;
+ y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,ColorPatternText,
+ Extent(ColorPatternText));
+ (void) strlcpy(text_info.text,glob_pattern,MaxTextExtent);
+ XDrawWidgetText(display,&windows->widget,&text_info);
+ XDrawBeveledButton(display,&windows->widget,&grab_info);
+ XDrawBeveledButton(display,&windows->widget,&reset_info);
+ XDrawBeveledMatte(display,&windows->widget,&list_info);
+ XDrawBeveledMatte(display,&windows->widget,&scroll_info);
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ x=QuantumMargin;
+ y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,ColornameText,
+ Extent(ColornameText));
+ XDrawBeveledMatte(display,&windows->widget,&reply_info);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ selection_info.id=(~0);
+ state|=RedrawActionState;
+ state|=RedrawListState;
+ state&=(~RedrawWidgetState);
+ }
+ if (state & UpdateListState)
+ {
+ char
+ **checklist;
+
+ unsigned long
+ number_colors;
+
+ status=XParseColor(display,windows->widget.map_info->colormap,
+ glob_pattern,&color);
+ if ((status != 0) || (strchr(glob_pattern,'-') != (char *) NULL))
+ {
+ /*
+ Reply is a single color name-- exit.
+ */
+ (void) strlcpy(reply,glob_pattern,MaxTextExtent);
+ (void) strlcpy(glob_pattern,reset_pattern,MaxTextExtent);
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ /*
+ Update color list.
+ */
+ checklist=GetColorList(glob_pattern,&number_colors);
+ if (number_colors == 0)
+ {
+ MagickFreeMemory(checklist);
+ (void) strlcpy(glob_pattern,reset_pattern,MaxTextExtent);
+ (void) XBell(display,0);
+ }
+ else
+ {
+ for (i=0; i < (long) colors; i++)
+ MagickFreeMemory(colorlist[i]);
+ if (colorlist != (char **) NULL)
+ MagickFreeMemory(colorlist);
+ colorlist=checklist;
+ colors=number_colors;
+ }
+ /*
+ Sort color list in ascending order.
+ */
+ slider_info.height=
+ scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
+ if (colors > visible_colors)
+ slider_info.height=(visible_colors*slider_info.height)/colors;
+ slider_info.max_y=south_info.y-south_info.bevel_width-
+ slider_info.bevel_width-2;
+ slider_info.id=0;
+ slider_info.y=slider_info.min_y;
+ expose_info.y=slider_info.y;
+ selection_info.id=(~0);
+ list_info.id=(~0);
+ state|=RedrawListState;
+ /*
+ Redraw color name & reply.
+ */
+ *reply_info.text='\0';
+ reply_info.cursor=reply_info.text;
+ (void) strlcpy(text_info.text,glob_pattern,MaxTextExtent);
+ XDrawWidgetText(display,&windows->widget,&text_info);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ XDrawBeveledMatte(display,&windows->widget,&scroll_info);
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ state&=(~UpdateListState);
+ }
+ if (state & JumpListState)
+ {
+ /*
+ Jump scroll to match user color.
+ */
+ list_info.id=(~0);
+ for (i=0; i < (long) colors; i++)
+ if (LocaleCompare(colorlist[i],reply) >= 0)
+ {
+ list_info.id=LocaleCompare(colorlist[i],reply) == 0 ? i : ~0;
+ break;
+ }
+ if ((i < slider_info.id) ||
+ (i >= (int) (slider_info.id+visible_colors)))
+ slider_info.id=i-(visible_colors >> 1);
+ selection_info.id=(~0);
+ state|=RedrawListState;
+ state&=(~JumpListState);
+ }
+ if (state & RedrawListState)
+ {
+ /*
+ Determine slider id and position.
+ */
+ if (slider_info.id >= (int) (colors-visible_colors))
+ slider_info.id=(int) (colors-visible_colors);
+ if ((slider_info.id < 0) || (colors <= visible_colors))
+ slider_info.id=0;
+ slider_info.y=slider_info.min_y;
+ if (colors != 0)
+ slider_info.y+=
+ slider_info.id*(slider_info.max_y-slider_info.min_y+1)/colors;
+ if (slider_info.id != selection_info.id)
+ {
+ /*
+ Redraw scroll bar and file names.
+ */
+ selection_info.id=slider_info.id;
+ selection_info.y=list_info.y+(height >> 3)+2;
+ for (i=0; i < (int) visible_colors; i++)
+ {
+ selection_info.raised=(slider_info.id+i) != list_info.id;
+ selection_info.text=(char *) NULL;
+ if ((slider_info.id+i) < (long) colors)
+ selection_info.text=colorlist[slider_info.id+i];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ selection_info.y+=(int) selection_info.height;
+ }
+ /*
+ Update slider.
+ */
+ if (slider_info.y > expose_info.y)
+ {
+ expose_info.height=slider_info.y-expose_info.y;
+ expose_info.y=slider_info.y-expose_info.height-
+ slider_info.bevel_width-1;
+ }
+ else
+ {
+ expose_info.height=expose_info.y-slider_info.y;
+ expose_info.y=slider_info.y+slider_info.height+
+ slider_info.bevel_width+1;
+ }
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawMatte(display,&windows->widget,&expose_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ expose_info.y=slider_info.y;
+ }
+ state&=(~RedrawListState);
+ }
+ if (state & RedrawActionState)
+ {
+ static char
+ colorname[MaxTextExtent];
+
+ /*
+ Display the selected color in a drawing area.
+ */
+ color=windows->widget.pixel_info->matte_color;
+ (void) XParseColor(display,windows->widget.map_info->colormap,
+ reply_info.text,&windows->widget.pixel_info->matte_color);
+ MagickXBestPixel(display,windows->widget.map_info->colormap,(XColor *) NULL,
+ (unsigned int) windows->widget.visual_info->colormap_size,
+ &windows->widget.pixel_info->matte_color);
+ mode_info.text=colorname;
+ FormatString(mode_info.text,"#%02x%02x%02x",
+ windows->widget.pixel_info->matte_color.red,
+ windows->widget.pixel_info->matte_color.green,
+ windows->widget.pixel_info->matte_color.blue);
+ XDrawBeveledButton(display,&windows->widget,&mode_info);
+ windows->widget.pixel_info->matte_color=color;
+ state&=(~RedrawActionState);
+ }
+ /*
+ Wait for next event.
+ */
+ if (north_info.raised && south_info.raised)
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ else
+ {
+ /*
+ Brief delay before advancing scroll bar.
+ */
+ MagickXDelay(display,delay);
+ delay=SuspendTime;
+ (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
+ if (!north_info.raised)
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ slider_info.id--;
+ state|=RedrawListState;
+ }
+ if (!south_info.raised)
+ if (slider_info.id < (long) colors)
+ {
+ /*
+ Move slider down.
+ */
+ slider_info.id++;
+ state|=RedrawListState;
+ }
+ if (event.type != ButtonRelease)
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (MatteIsActive(slider_info,event.xbutton))
+ {
+ /*
+ Track slider.
+ */
+ slider_info.active=True;
+ break;
+ }
+ if (MatteIsActive(north_info,event.xbutton))
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ north_info.raised=False;
+ slider_info.id--;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(south_info,event.xbutton))
+ if (slider_info.id < (long) colors)
+ {
+ /*
+ Move slider down.
+ */
+ south_info.raised=False;
+ slider_info.id++;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(scroll_info,event.xbutton))
+ {
+ /*
+ Move slider.
+ */
+ if (event.xbutton.y < slider_info.y)
+ slider_info.id-=(visible_colors-1);
+ else
+ slider_info.id+=(visible_colors-1);
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(list_info,event.xbutton))
+ {
+ unsigned int
+ id;
+
+ /*
+ User pressed list matte.
+ */
+ id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
+ selection_info.height;
+ if (id >= colors)
+ break;
+ (void) strlcpy(reply_info.text,colorlist[id],MaxTextExtent);
+ reply_info.highlight=False;
+ reply_info.marker=reply_info.text;
+ reply_info.cursor=reply_info.text+Extent(reply_info.text);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=RedrawActionState;
+ if ((int) id == list_info.id)
+ {
+ (void) strlcpy(glob_pattern,reply_info.text,MaxTextExtent);
+ state|=UpdateListState;
+ }
+ selection_info.id=(~0);
+ list_info.id=id;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(grab_info,event.xbutton))
+ {
+ /*
+ User pressed Grab button.
+ */
+ grab_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&grab_info);
+ break;
+ }
+ if (MatteIsActive(reset_info,event.xbutton))
+ {
+ /*
+ User pressed Reset button.
+ */
+ reset_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&reset_info);
+ break;
+ }
+ if (MatteIsActive(mode_info,event.xbutton))
+ {
+ /*
+ User pressed mode button.
+ */
+ (void) strlcpy(reply_info.text,mode_info.text,MaxTextExtent);
+ (void) strlcpy(primary_selection,reply_info.text,MaxTextExtent);
+ (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
+ event.xbutton.time);
+ reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
+ windows->widget.id;
+ reply_info.marker=reply_info.text;
+ reply_info.cursor=reply_info.text+Extent(reply_info.text);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ break;
+ }
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ /*
+ User pressed action button.
+ */
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ /*
+ User pressed Cancel button.
+ */
+ cancel_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ if (!MatteIsActive(reply_info,event.xbutton))
+ break;
+ if (event.xbutton.button != Button2)
+ {
+ static Time
+ click_time;
+
+ /*
+ Move text cursor to position of button press.
+ */
+ x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
+ for (i=1; i <= Extent(reply_info.marker); i++)
+ if (XTextWidth(font_info,reply_info.marker,i) > x)
+ break;
+ reply_info.cursor=reply_info.marker+i-1;
+ if (event.xbutton.time > (click_time+DoubleClick))
+ reply_info.highlight=False;
+ else
+ {
+ /*
+ Become the XA_PRIMARY selection owner.
+ */
+ (void) strlcpy(primary_selection,reply_info.text,
+ MaxTextExtent);
+ (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
+ event.xbutton.time);
+ reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
+ windows->widget.id;
+ }
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ click_time=event.xbutton.time;
+ break;
+ }
+ /*
+ Request primary selection.
+ */
+ (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
+ windows->widget.id,event.xbutton.time);
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (!north_info.raised)
+ {
+ /*
+ User released up button.
+ */
+ delay=SuspendTime << 2;
+ north_info.raised=True;
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ }
+ if (!south_info.raised)
+ {
+ /*
+ User released down button.
+ */
+ delay=SuspendTime << 2;
+ south_info.raised=True;
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ }
+ if (slider_info.active)
+ {
+ /*
+ Stop tracking slider.
+ */
+ slider_info.active=False;
+ break;
+ }
+ if (!grab_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(grab_info,event.xbutton))
+ {
+ /*
+ Select a pen color from the X server.
+ */
+ (void) MagickXGetWindowColor(display,windows,reply_info.text);
+ reply_info.marker=reply_info.text;
+ reply_info.cursor=reply_info.text+Extent(reply_info.text);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=RedrawActionState;
+ }
+ grab_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&grab_info);
+ }
+ if (!reset_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(reset_info,event.xbutton))
+ {
+ (void) strlcpy(glob_pattern,reset_pattern,MaxTextExtent);
+ state|=UpdateListState;
+ }
+ reset_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&reset_info);
+ }
+ if (!action_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ {
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ if (*reply_info.text == '\0')
+ (void) XBell(display,0);
+ else
+ state|=ExitState;
+ }
+ }
+ action_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ }
+ if (!cancel_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ }
+ cancel_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ }
+ /* if (!MatteIsActive(reply_info,event.xbutton)) */
+ /* break; */
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == windows->widget.id)
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static int
+ length;
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if (AreaIsActive(scroll_info,event.xkey))
+ {
+ /*
+ Move slider.
+ */
+ switch ((int) key_symbol)
+ {
+ case XK_Home:
+ case XK_KP_Home:
+ {
+ slider_info.id=0;
+ break;
+ }
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ slider_info.id--;
+ break;
+ }
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ slider_info.id++;
+ break;
+ }
+ case XK_Prior:
+ case XK_KP_Prior:
+ {
+ slider_info.id-=visible_colors;
+ break;
+ }
+ case XK_Next:
+ case XK_KP_Next:
+ {
+ slider_info.id+=visible_colors;
+ break;
+ }
+ case XK_End:
+ case XK_KP_End:
+ {
+ slider_info.id=(int) colors;
+ break;
+ }
+ }
+ state|=RedrawListState;
+ break;
+ }
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ /*
+ Read new color or glob patterm.
+ */
+ if (*reply_info.text == '\0')
+ break;
+ (void) strlcpy(glob_pattern,reply_info.text,MaxTextExtent);
+ state|=UpdateListState;
+ break;
+ }
+ if (key_symbol == XK_Control_L)
+ {
+ state|=ControlState;
+ break;
+ }
+ if (state & ControlState)
+ switch ((int) key_symbol)
+ {
+ case XK_u:
+ case XK_U:
+ {
+ /*
+ Erase the entire line of text.
+ */
+ *reply_info.text='\0';
+ reply_info.cursor=reply_info.text;
+ reply_info.marker=reply_info.text;
+ reply_info.highlight=False;
+ break;
+ }
+ default:
+ break;
+ }
+ XEditText(display,&reply_info,key_symbol,command,state);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=JumpListState;
+ status=XParseColor(display,windows->widget.map_info->colormap,
+ reply_info.text,&color);
+ if (status != 0)
+ state|=RedrawActionState;
+ break;
+ }
+ case KeyRelease:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key release.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if (key_symbol == XK_Control_L)
+ state&=(~ControlState);
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MapNotify:
+ {
+ mask&=(~CWX);
+ mask&=(~CWY);
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (slider_info.active)
+ {
+ /*
+ Move slider matte.
+ */
+ slider_info.y=event.xmotion.y-
+ ((slider_info.height+slider_info.bevel_width) >> 1)+1;
+ if (slider_info.y < slider_info.min_y)
+ slider_info.y=slider_info.min_y;
+ if (slider_info.y > slider_info.max_y)
+ slider_info.y=slider_info.max_y;
+ slider_info.id=0;
+ if (slider_info.y != slider_info.min_y)
+ slider_info.id=(int) ((colors*(slider_info.y-slider_info.min_y+1))/
+ (slider_info.max_y-slider_info.min_y+1));
+ state|=RedrawListState;
+ break;
+ }
+ if (state & InactiveWidgetState)
+ break;
+ if (grab_info.raised == MatteIsActive(grab_info,event.xmotion))
+ {
+ /*
+ Grab button status changed.
+ */
+ grab_info.raised=!grab_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&grab_info);
+ break;
+ }
+ if (reset_info.raised == MatteIsActive(reset_info,event.xmotion))
+ {
+ /*
+ Reset button status changed.
+ */
+ reset_info.raised=!reset_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&reset_info);
+ break;
+ }
+ if (action_info.raised == MatteIsActive(action_info,event.xmotion))
+ {
+ /*
+ Action button status changed.
+ */
+ action_info.raised=!action_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
+ {
+ /*
+ Cancel button status changed.
+ */
+ cancel_info.raised=!cancel_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ break;
+ }
+ case SelectionClear:
+ {
+ reply_info.highlight=False;
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ break;
+ }
+ case SelectionNotify:
+ {
+ Atom
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ Obtain response from primary selection.
+ */
+ if (event.xselection.property == (Atom) None)
+ break;
+ status=XGetWindowProperty(display,event.xselection.requestor,
+ event.xselection.property,0L,2047L,True,XA_STRING,&type,&format,
+ &length,&after,&data);
+ if ((status != Success) || (type != XA_STRING) || (format == 32) ||
+ (length == 0))
+ break;
+ if ((Extent(reply_info.text)+length) >= MaxTextExtent)
+ (void) XBell(display,0);
+ else
+ {
+ /*
+ Insert primary selection in reply text.
+ */
+ *(data+length)='\0';
+ XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
+ state);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=JumpListState;
+ state|=RedrawActionState;
+ }
+ (void) XFree((void *) data);
+ break;
+ }
+ case SelectionRequest:
+ {
+ XSelectionEvent
+ notify;
+
+ XSelectionRequestEvent
+ *request;
+
+ if (!reply_info.highlight)
+ break;
+ /*
+ Set primary selection.
+ */
+ request=(&(event.xselectionrequest));
+ (void) XChangeProperty(request->display,request->requestor,
+ request->property,request->target,8,PropModeReplace,
+ (unsigned char *) primary_selection,Extent(primary_selection));
+ notify.type=SelectionNotify;
+ notify.send_event=True;
+ notify.display=request->display;
+ notify.requestor=request->requestor;
+ notify.selection=request->selection;
+ notify.target=request->target;
+ notify.time=request->time;
+ if (request->property == None)
+ notify.property=request->target;
+ else
+ notify.property=request->property;
+ (void) XSendEvent(request->display,request->requestor,False,NoEventMask,
+ (XEvent *) &notify);
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+ /*
+ Free color list.
+ */
+ for (i=0; i < (long) colors; i++)
+ MagickFreeMemory(colorlist[i]);
+ if (colorlist != (char **) NULL)
+ MagickFreeMemory(colorlist);
+ if ((*reply == '\0') || (strchr(reply,'-') != (char *) NULL))
+ return;
+ status=XParseColor(display,windows->widget.map_info->colormap,reply,&color);
+ if (status != 0)
+ return;
+ MagickXNoticeWidget(display,windows,"Color is unknown to X server:",reply);
+ (void) strcpy(reply,"gray");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X C o m m a n d W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXCommandWidget maps a menu and returns the command pointed to by
+% the user when the button is released.
+%
+% The format of the MagickXCommandWidget method is:
+%
+% int MagickXCommandWidget(Display *display,MagickXWindows *windows,
+% const char **selections,XEvent *event)
+%
+% A description of each parameter follows:
+%
+% o selection_number: Specifies the number of the selection that the
+% user choose.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o selections: Specifies a pointer to one or more strings that comprise
+% the choices in the menu.
+%
+% o event: Specifies a pointer to a X11 XEvent structure.
+%
+%
+*/
+MagickExport int MagickXCommandWidget(Display *display,MagickXWindows *windows,
+ const char **selections,XEvent *event)
+{
+ /*
+ GraphicsMagick monochrome logo for top of command bar.
+ */
+#define tile_width 112
+#define tile_height 64
+static unsigned char tile_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00,
+ 0x00, 0x1E, 0xF8, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE0, 0xC0, 0x87, 0x3F, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xE0, 0x8F, 0x73, 0xDC, 0xFC, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x71, 0x8E, 0x03, 0xDC, 0x7C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x71, 0x80, 0x1F, 0xEC, 0x76,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xC3, 0x71, 0x00, 0x7F,
+ 0x6E, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xC7, 0x73,
+ 0x18, 0x70, 0x6E, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
+ 0x8F, 0x73, 0xDC, 0x71, 0xEE, 0x3B, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xF8, 0x8F, 0xF3, 0x9F, 0x7F, 0xE7, 0x39, 0x3E, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x78, 0x9C, 0xE7, 0x0F, 0x3F, 0xE7, 0x19, 0x7C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1C, 0x87, 0x03, 0x00, 0xE6, 0x1C,
+ 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0x38, 0x07, 0x00, 0x00,
+ 0xE0, 0x9C, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE3, 0x38, 0x00,
+ 0x00, 0x00, 0x00, 0xCC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE7,
+ 0x39, 0x00, 0x00, 0x00, 0x00, 0xC8, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xF8, 0xCF, 0x01, 0x00, 0x00, 0x07, 0x00, 0xC0, 0x71, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3C, 0xCE, 0x03, 0x00, 0x81, 0x0D, 0x00, 0x80, 0x7F, 0x7C,
+ 0x00, 0x00, 0x00, 0x00, 0x3C, 0x9E, 0x00, 0x80, 0x87, 0x1E, 0x00, 0x00,
+ 0x3F, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1C, 0x00, 0xC0, 0xDC, 0x1F,
+ 0x00, 0x00, 0x38, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1E, 0x00, 0x40,
+ 0xF0, 0x38, 0x00, 0x00, 0x10, 0xC7, 0x01, 0x00, 0x00, 0x00, 0xF0, 0x0F,
+ 0x00, 0x40, 0x77, 0x30, 0x00, 0x00, 0x80, 0xC3, 0x03, 0x00, 0x00, 0xC0,
+ 0xE1, 0x01, 0x00, 0xC0, 0x2D, 0x30, 0x00, 0x00, 0xA0, 0xE3, 0x03, 0x00,
+ 0x00, 0xE0, 0xC7, 0x03, 0x00, 0xC0, 0x38, 0xF0, 0x00, 0x00, 0x30, 0xF7,
+ 0xC1, 0x00, 0x00, 0xF0, 0x8F, 0x07, 0x00, 0xC0, 0x18, 0xE0, 0x01, 0x00,
+ 0x70, 0xFE, 0xC0, 0x00, 0x00, 0x38, 0x3F, 0x0F, 0x00, 0x40, 0x10, 0x60,
+ 0x03, 0x00, 0x70, 0x7C, 0xD8, 0x01, 0x00, 0x98, 0x3D, 0x06, 0x00, 0x40,
+ 0x10, 0x74, 0x06, 0x00, 0xE0, 0x3E, 0x1E, 0x00, 0x00, 0xB8, 0x39, 0x02,
+ 0x00, 0xC0, 0x0C, 0x36, 0x04, 0x00, 0xC0, 0x0F, 0x3F, 0x00, 0x00, 0x98,
+ 0x08, 0x00, 0x00, 0xC0, 0x0C, 0x36, 0x0C, 0x00, 0x80, 0xC7, 0x0F, 0x00,
+ 0x00, 0xC0, 0x0D, 0x00, 0x00, 0xE0, 0x08, 0x1E, 0x08, 0x00, 0x00, 0xE0,
+ 0x03, 0x00, 0x00, 0xC2, 0x0F, 0x00, 0x00, 0xA0, 0x0C, 0x0C, 0x18, 0x00,
+ 0x00, 0xE0, 0x01, 0x00, 0x00, 0x87, 0x07, 0x00, 0x00, 0xD0, 0x1B, 0x04,
+ 0x30, 0x00, 0x00, 0x60, 0x78, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x78,
+ 0x10, 0x06, 0x60, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x38, 0xF0, 0x0F, 0x60, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x80, 0x07,
+ 0x00, 0x00, 0x00, 0x0C, 0x00, 0xFC, 0xF1, 0x00, 0x00, 0x00, 0x8F, 0x01,
+ 0x80, 0x1F, 0x00, 0x00, 0x00, 0x06, 0x00, 0xC0, 0xE3, 0x00, 0x00, 0x00,
+ 0x87, 0x03, 0x80, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x70, 0x60, 0xA3, 0x03,
+ 0x00, 0x00, 0x83, 0x03, 0x00, 0xFC, 0x00, 0x00, 0x80, 0x01, 0x70, 0x30,
+ 0x00, 0x07, 0x00, 0x00, 0x87, 0x03, 0x00, 0xE0, 0x00, 0x00, 0xC0, 0x0E,
+ 0x70, 0x18, 0x00, 0x06, 0x00, 0x00, 0x9F, 0x01, 0x10, 0x00, 0x00, 0x00,
+ 0x60, 0x0F, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x1E, 0x00, 0x9C, 0x1F,
+ 0x00, 0x00, 0x20, 0x06, 0x00, 0x06, 0x60, 0x06, 0x00, 0x00, 0x1C, 0x00,
+ 0x9E, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x38, 0x33, 0x60, 0x0C, 0x00, 0x00,
+ 0x00, 0x78, 0x9E, 0x3F, 0x00, 0x00, 0x60, 0x00, 0xB8, 0x71, 0x62, 0x08,
+ 0x02, 0x00, 0xF0, 0x7F, 0x8E, 0x39, 0x00, 0x00, 0xC0, 0x00, 0xE0, 0x30,
+ 0x0E, 0xFB, 0x0F, 0x00, 0xFC, 0x7F, 0xC6, 0x39, 0x00, 0x00, 0x80, 0x03,
+ 0x7C, 0x00, 0x1C, 0xFF, 0x18, 0x00, 0xFC, 0x07, 0x06, 0x38, 0x00, 0x00,
+ 0x00, 0xFF, 0x1F, 0x00, 0x72, 0x0E, 0x10, 0x00, 0xE8, 0x01, 0x0E, 0x38,
+ 0x00, 0x00, 0xC0, 0xFC, 0x01, 0x00, 0xC7, 0x00, 0x18, 0x00, 0xC0, 0x07,
+ 0x3E, 0x3C, 0x00, 0x00, 0xC0, 0x3E, 0x06, 0x03, 0xDC, 0x00, 0x18, 0x00,
+ 0xE0, 0x0F, 0xFE, 0x1F, 0x00, 0x00, 0x80, 0x63, 0x07, 0x87, 0x78, 0x00,
+ 0x0C, 0x00, 0xF8, 0x1D, 0xFC, 0x0F, 0x00, 0x00, 0x80, 0xC3, 0x07, 0xC7,
+ 0x69, 0x30, 0x06, 0x00, 0x78, 0x18, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x02,
+ 0x07, 0x80, 0x3D, 0x3C, 0x03, 0x00, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x1C, 0x00, 0x94, 0x97, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF8, 0x0F, 0xF0, 0xFF, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1E, 0x38, 0xF0, 0xFF, 0x0F, 0xD8, 0x3F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xE0, 0xF8, 0x10, 0x0E, 0x6C,
+ 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xF8, 0xFC, 0xBF,
+ 0x3D, 0x06, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0E,
+ 0x60, 0xFC, 0xFC, 0x1D, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFC, 0x01, 0x00, 0x3C, 0xFF, 0x79, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xC0, 0x00, 0x00, 0xFC, 0x67, 0x80, 0x1D, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x1A, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x00,
+ 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1C, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, };
+
+ int
+ id,
+ y;
+
+ register int
+ i;
+
+ static unsigned int
+ number_selections;
+
+ static MagickXWidgetInfo
+ *selection_info = (MagickXWidgetInfo *) NULL;
+
+ unsigned int
+ height;
+
+ unsigned long
+ state;
+
+ XFontStruct
+ *font_info;
+
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ font_info=windows->command.font_info;
+ height=font_info->ascent+font_info->descent;
+ id=(~0);
+ state=DefaultState;
+ if (event == (XEvent *) NULL)
+ {
+ unsigned int
+ width;
+
+ XTextProperty
+ window_name;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Determine command window attributes.
+ */
+ assert(selections != (const char **) NULL);
+ windows->command.width=0;
+ for (i=0; selections[i] != (char *) NULL; i++)
+ {
+ width=
+ XTextWidth(font_info,(char *) selections[i],Extent(selections[i]));
+ if (width > windows->command.width)
+ windows->command.width=width;
+ }
+ number_selections=i;
+ windows->command.width+=3*QuantumMargin+10;
+ if ((int) windows->command.width < (tile_width+QuantumMargin+10))
+ windows->command.width=tile_width+QuantumMargin+10;
+ windows->command.height=
+ number_selections*(((3*height) >> 1)+10)+tile_height+20;
+ windows->command.min_width=windows->command.width;
+ windows->command.min_height=windows->command.height;
+ MagickXConstrainWindowPosition(display,&windows->command);
+ if (windows->command.id != (Window) NULL)
+ {
+ int
+ status;
+
+ /*
+ Reconfigure command window.
+ */
+ status=XStringListToTextProperty(&windows->command.name,1,
+ &window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->command.id,&window_name);
+ XSetWMIconName(display,windows->command.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->command.width;
+ window_changes.height=windows->command.height;
+ (void) XReconfigureWMWindow(display,windows->command.id,
+ windows->command.screen,CWWidth | CWHeight,&window_changes);
+ }
+ /*
+ Allocate selection info memory.
+ */
+ if (selection_info != (MagickXWidgetInfo *) NULL)
+ MagickFreeMemory(selection_info);
+ selection_info=MagickAllocateMemory(MagickXWidgetInfo *,
+ number_selections*sizeof(MagickXWidgetInfo));
+ if (selection_info == (MagickXWidgetInfo *) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateCommandWidget);
+ return(id);
+ }
+ state|=UpdateConfigurationState | RedrawWidgetState;
+ }
+ /*
+ Wait for next event.
+ */
+ if (event != (XEvent *) NULL)
+ switch (event->type)
+ {
+ case ButtonPress:
+ {
+ for (i=0; i < (int) number_selections; i++)
+ {
+ if (!MatteIsActive(selection_info[i],event->xbutton))
+ continue;
+ if (i >= (int) windows->command.data)
+ {
+ selection_info[i].raised=False;
+ XDrawBeveledButton(display,&windows->command,&selection_info[i]);
+ break;
+ }
+ submenu_info=selection_info[i];
+ submenu_info.active=True;
+ toggle_info.y=
+ submenu_info.y+(submenu_info.height >> 1)-(toggle_info.height >> 1);
+ id=i;
+ (void) XCheckWindowEvent(display,windows->widget.id,LeaveWindowMask,
+ event);
+ break;
+ }
+ break;
+ }
+ case ButtonRelease:
+ {
+ for (i=0; i < (int) number_selections; i++)
+ {
+ if (!MatteIsActive(selection_info[i],event->xbutton))
+ continue;
+ id=i;
+ if (id >= (int) windows->command.data)
+ {
+ selection_info[id].raised=True;
+ XDrawBeveledButton(display,&windows->command,&selection_info[id]);
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, withdraw command widget.
+ */
+ if (event->xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event->xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ (void) XWithdrawWindow(display,windows->command.id,
+ windows->command.screen);
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event->xconfigure.window != windows->command.id)
+ break;
+ if (event->xconfigure.send_event != 0)
+ {
+ windows->command.x=event->xconfigure.x;
+ windows->command.y=event->xconfigure.y;
+ }
+ if ((event->xconfigure.width == (int) windows->command.width) &&
+ (event->xconfigure.height == (int) windows->command.height))
+ break;
+ windows->command.width=
+ Max(event->xconfigure.width,(int) windows->command.min_width);
+ windows->command.height=
+ Max(event->xconfigure.height,(int) windows->command.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case Expose:
+ {
+ if (event->xexpose.window != windows->command.id)
+ break;
+ if (event->xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Return the ID of the highlighted menu entry.
+ */
+ for ( ; ; )
+ {
+ for (i=0; i < (int) number_selections; i++)
+ {
+ if (i >= (int) windows->command.data)
+ {
+ if (selection_info[i].raised ==
+ MatteIsActive(selection_info[i],event->xmotion))
+ {
+ /*
+ Button status changed.
+ */
+ selection_info[i].raised=!selection_info[i].raised;
+ XDrawBeveledButton(display,&windows->command,
+ &selection_info[i]);
+ }
+ continue;
+ }
+ if (!MatteIsActive(selection_info[i],event->xmotion))
+ continue;
+ submenu_info=selection_info[i];
+ submenu_info.active=True;
+ toggle_info.raised=True;
+ toggle_info.y=submenu_info.y+(submenu_info.height >> 1)-
+ (toggle_info.height >> 1);
+ XDrawTriangleEast(display,&windows->command,&toggle_info);
+ id=i;
+ }
+ MagickXDelay(display,SuspendTime);
+ if (!XCheckMaskEvent(display,ButtonMotionMask,event))
+ break;
+ while (XCheckMaskEvent(display,ButtonMotionMask,event));
+ toggle_info.raised=False;
+ if (windows->command.data != 0)
+ XDrawTriangleEast(display,&windows->command,&toggle_info);
+ }
+ break;
+ }
+ case MapNotify:
+ {
+ windows->command.mapped=True;
+ break;
+ }
+ case UnmapNotify:
+ {
+ windows->command.mapped=False;
+ break;
+ }
+ default:
+ break;
+ }
+ if (state & UpdateConfigurationState)
+ {
+ /*
+ Initialize button information.
+ */
+ assert(selections != (const char **) NULL);
+ y=tile_height+20;
+ for (i=0; i < (int) number_selections; i++)
+ {
+ XGetWidgetInfo(selections[i],&selection_info[i]);
+ selection_info[i].center=False;
+ selection_info[i].bevel_width--;
+ selection_info[i].height=(3*height) >> 1;
+ selection_info[i].x=(QuantumMargin >> 1)+4;
+ selection_info[i].width=
+ windows->command.width-(selection_info[i].x << 1);
+ selection_info[i].y=y;
+ y+=selection_info[i].height+(selection_info[i].bevel_width << 1)+6;
+ }
+ XGetWidgetInfo((char *) NULL,&toggle_info);
+ toggle_info.bevel_width--;
+ toggle_info.width=((5*height) >> 3)-(toggle_info.bevel_width << 1);
+ toggle_info.height=toggle_info.width;
+ toggle_info.x=selection_info[0].x+selection_info[0].width-
+ toggle_info.width-(QuantumMargin >> 1);
+ if (windows->command.mapped)
+ (void) XClearWindow(display,windows->command.id);
+ }
+ if (state & RedrawWidgetState)
+ {
+ Pixmap
+ tile_pixmap;
+
+ /*
+ Draw command buttons.
+ */
+ tile_pixmap=XCreatePixmapFromBitmapData(display,windows->command.id,
+ (char *) tile_bits,tile_width,tile_height,1L,0L,1);
+ if (tile_pixmap != (Pixmap) NULL)
+ {
+ (void) XCopyPlane(display,tile_pixmap,windows->command.id,
+ windows->command.annotate_context,0,0,tile_width,tile_height,
+ (windows->command.width-tile_width) >> 1,10,1L);
+ (void) XFreePixmap(display,tile_pixmap);
+ }
+ for (i=0; i < (int) number_selections; i++)
+ {
+ XDrawBeveledButton(display,&windows->command,&selection_info[i]);
+ if (i >= (int) windows->command.data)
+ continue;
+ toggle_info.raised=i == id;
+ toggle_info.y=selection_info[i].y+
+ (selection_info[i].height >> 1)-(toggle_info.height >> 1);
+ XDrawTriangleEast(display,&windows->command,&toggle_info);
+ }
+ XHighlightWidget(display,&windows->command,BorderOffset,BorderOffset);
+ }
+ return(id);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X C o n f i r m W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXConfirmWidget displays a Confirm widget with a notice to the user.
+% The function returns -1 if Dismiss is pressed, 0 for Cancel, and 1 for
+% Yes.
+%
+% The format of the MagickXConfirmWidget method is:
+%
+% int MagickXConfirmWidget(Display *display,MagickXWindows *windows,
+% const char *reason,const char *description)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXConfirmWidget returns True if the user presses Yes
+% otherwise False is returned.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o reason: Specifies the message to display before terminating the
+% program.
+%
+% o description: Specifies any description to the message.
+%
+%
+*/
+MagickExport int MagickXConfirmWidget(Display *display,MagickXWindows *windows,
+ const char *reason,const char *description)
+{
+#define CancelButtonText "Cancel"
+#define DismissButtonText "Dismiss"
+#define YesButtonText "Yes"
+
+ int
+ confirm,
+ height,
+ status,
+ width,
+ x,
+ y;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ cancel_info,
+ dismiss_info,
+ yes_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Determine Confirm widget attributes.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(reason != (char *) NULL);
+ assert(description != (char *) NULL);
+ MagickXCheckRefreshWindows(display,windows);
+ font_info=windows->widget.font_info;
+ width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText));
+ if (XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText)) > width)
+ width=XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText));
+ if (XTextWidth(font_info,YesButtonText,Extent(YesButtonText)) > width)
+ width=XTextWidth(font_info,YesButtonText,Extent(YesButtonText));
+ width<<=1;
+ if (description != (char *) NULL)
+ if (XTextWidth(font_info,(char *) description,Extent(description)) > width)
+ width=XTextWidth(font_info,(char *) description,Extent(description));
+ if (description != (char *) NULL)
+ if (XTextWidth(font_info,(char *) description,Extent(description)) > width)
+ width=XTextWidth(font_info,(char *) description,Extent(description));
+ height=(font_info->ascent+font_info->descent);
+ /*
+ Position Confirm widget.
+ */
+ windows->widget.width=width+9*QuantumMargin;
+ windows->widget.min_width=9*QuantumMargin+
+ XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText))+
+ XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText))+
+ XTextWidth(font_info,YesButtonText,Extent(YesButtonText));
+ if (windows->widget.width < windows->widget.min_width)
+ windows->widget.width=windows->widget.min_width;
+ windows->widget.height=12*height;
+ windows->widget.min_height=7*height;
+ if (windows->widget.height < windows->widget.min_height)
+ windows->widget.height=windows->widget.min_height;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map Confirm widget.
+ */
+ (void) strcpy(windows->widget.name,"Confirm");
+ status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->widget.id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
+ CWWidth | CWHeight | CWX | CWY,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ /*
+ Respond to X events.
+ */
+ confirm=0;
+ state=UpdateConfigurationState;
+ MagickXSetCursorState(display,windows,True);
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ /*
+ Initialize button information.
+ */
+ XGetWidgetInfo(CancelButtonText,&cancel_info);
+ cancel_info.width=QuantumMargin+
+ XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText));
+ cancel_info.height=(3*height) >> 1;
+ cancel_info.x=windows->widget.width-cancel_info.width-QuantumMargin;
+ cancel_info.y=windows->widget.height-(cancel_info.height << 1);
+ dismiss_info=cancel_info;
+ dismiss_info.text=(char *) DismissButtonText;
+ if (LocaleCompare(description,"Do you want to save it") == 0)
+ dismiss_info.text=(char *) "Don't Save";
+ dismiss_info.width=QuantumMargin+
+ XTextWidth(font_info,dismiss_info.text,Extent(dismiss_info.text));
+ dismiss_info.x=(windows->widget.width >> 1)-(dismiss_info.width >> 1);
+ yes_info=cancel_info;
+ yes_info.text=(char *) YesButtonText;
+ if (LocaleCompare(description,"Do you want to save it") == 0)
+ yes_info.text=(char *) "Save";
+ yes_info.width=QuantumMargin+
+ XTextWidth(font_info,yes_info.text,Extent(yes_info.text));
+ if (yes_info.width < cancel_info.width)
+ yes_info.width=cancel_info.width;
+ yes_info.x=QuantumMargin;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw Confirm widget.
+ */
+ width=XTextWidth(font_info,(char *) reason,Extent(reason));
+ x=(windows->widget.width >> 1)-(width >> 1);
+ y=(windows->widget.height >> 1)-(height << 1);
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,(char *) reason,Extent(reason));
+ if (description != (char *) NULL)
+ {
+ char
+ question[MaxTextExtent];
+
+ (void) strlcpy(question,description,MaxTextExtent);
+ (void) strcat(question,"?");
+ width=XTextWidth(font_info,question,Extent(question));
+ x=(windows->widget.width >> 1)-(width >> 1);
+ y+=height;
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,question,Extent(question));
+ }
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ XDrawBeveledButton(display,&windows->widget,&yes_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ state&=(~RedrawWidgetState);
+ }
+ /*
+ Wait for next event.
+ */
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ /*
+ User pressed No button.
+ */
+ cancel_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ if (MatteIsActive(dismiss_info,event.xbutton))
+ {
+ /*
+ User pressed Dismiss button.
+ */
+ dismiss_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ break;
+ }
+ if (MatteIsActive(yes_info,event.xbutton))
+ {
+ /*
+ User pressed Yes button.
+ */
+ yes_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&yes_info);
+ break;
+ }
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (!cancel_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ confirm=0;
+ state|=ExitState;
+ }
+ cancel_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ }
+ if (!dismiss_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(dismiss_info,event.xbutton))
+ {
+ confirm=(-1);
+ state|=ExitState;
+ }
+ dismiss_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ }
+ if (!yes_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(yes_info,event.xbutton))
+ {
+ confirm=1;
+ state|=ExitState;
+ }
+ yes_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&yes_info);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == windows->widget.id)
+ {
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ yes_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&yes_info);
+ confirm=1;
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (state & InactiveWidgetState)
+ break;
+ if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
+ {
+ /*
+ Cancel button status changed.
+ */
+ cancel_info.raised=!cancel_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
+ {
+ /*
+ Dismiss button status changed.
+ */
+ dismiss_info.raised=!dismiss_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ break;
+ }
+ if (yes_info.raised == MatteIsActive(yes_info,event.xmotion))
+ {
+ /*
+ Yes button status changed.
+ */
+ yes_info.raised=!yes_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&yes_info);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+ return(confirm);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X D i a l o g W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXDialogWidget displays a Dialog widget with a query to the user.
+% The user keys a reply and presses the Ok or Cancel button to exit. The
+% typed text is returned as the reply function parameter.
+%
+% The format of the MagickXDialogWidget method is:
+%
+% int MagickXDialogWidget(Display *display,MagickXWindows *windows,const char *action,
+% const char *query,char *reply)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o action: Specifies a pointer to the action of this widget.
+%
+% o query: Specifies a pointer to the query to present to the user.
+%
+% o reply: The response from the user is returned in this parameter.
+%
+%
+*/
+MagickExport int MagickXDialogWidget(Display *display,MagickXWindows *windows,
+ const char *action,const char *query,char *reply)
+{
+#define CancelButtonText "Cancel"
+
+ char
+ primary_selection[MaxTextExtent];
+
+ int
+ height,
+ status,
+ width,
+ x;
+
+ register int
+ i;
+
+ static unsigned int
+ raised = False;
+
+ unsigned int
+ anomaly;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ action_info,
+ cancel_info,
+ reply_info,
+ special_info,
+ text_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Determine Dialog widget attributes.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(action != (char *) NULL);
+ assert(query != (char *) NULL);
+ assert(reply != (char *) NULL);
+ MagickXCheckRefreshWindows(display,windows);
+ font_info=windows->widget.font_info;
+ width=XTextWidth(font_info,(char *) action,Extent(action));
+ if (XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)) > width)
+ width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText));
+ width+=(3*QuantumMargin) >> 1;
+ height=font_info->ascent+font_info->descent;
+ /*
+ Position Dialog widget.
+ */
+ windows->widget.width=
+ Max(2*width,XTextWidth(font_info,(char *) query,Extent(query)));
+ if ((int) windows->widget.width < XTextWidth(font_info,reply,Extent(reply)))
+ windows->widget.width=XTextWidth(font_info,reply,Extent(reply));
+ windows->widget.width+=6*QuantumMargin;
+ windows->widget.min_width=
+ width+28*XTextWidth(font_info,"#",1)+4*QuantumMargin;
+ if (windows->widget.width < windows->widget.min_width)
+ windows->widget.width=windows->widget.min_width;
+ windows->widget.height=7*height+(QuantumMargin << 1);
+ windows->widget.min_height=windows->widget.height;
+ if (windows->widget.height < windows->widget.min_height)
+ windows->widget.height=windows->widget.min_height;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map Dialog widget.
+ */
+ (void) strcpy(windows->widget.name,"Dialog");
+ status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->widget.id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
+ CWWidth | CWHeight | CWX | CWY,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ /*
+ Respond to X events.
+ */
+ anomaly=(LocaleCompare(action,"Background") == 0) ||
+ (LocaleCompare(action,"New") == 0) ||
+ (LocaleCompare(action,"Quantize") == 0) ||
+ (LocaleCompare(action,"Resize") == 0) ||
+ (LocaleCompare(action,"Save") == 0) ||
+ (LocaleCompare(action,"Shade") == 0);
+ state=UpdateConfigurationState;
+ MagickXSetCursorState(display,windows,True);
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ /*
+ Initialize button information.
+ */
+ XGetWidgetInfo(CancelButtonText,&cancel_info);
+ cancel_info.width=width;
+ cancel_info.height=(3*height) >> 1;
+ cancel_info.x=
+ windows->widget.width-cancel_info.width-((3*QuantumMargin) >> 1);
+ cancel_info.y=
+ windows->widget.height-cancel_info.height-((3*QuantumMargin) >> 1);
+ XGetWidgetInfo(action,&action_info);
+ action_info.width=width;
+ action_info.height=(3*height) >> 1;
+ action_info.x=cancel_info.x-(cancel_info.width+QuantumMargin+
+ (action_info.bevel_width << 1));
+ action_info.y=cancel_info.y;
+ /*
+ Initialize reply information.
+ */
+ XGetWidgetInfo(reply,&reply_info);
+ reply_info.raised=False;
+ reply_info.bevel_width--;
+ reply_info.width=windows->widget.width-(3*QuantumMargin);
+ reply_info.height=height << 1;
+ reply_info.x=(3*QuantumMargin) >> 1;
+ reply_info.y=action_info.y-reply_info.height-QuantumMargin;
+ /*
+ Initialize option information.
+ */
+ XGetWidgetInfo("Dither",&special_info);
+ special_info.raised=raised;
+ special_info.bevel_width--;
+ special_info.width=QuantumMargin >> 1;
+ special_info.height=QuantumMargin >> 1;
+ special_info.x=reply_info.x;
+ special_info.y=action_info.y+action_info.height-special_info.height;
+ if (LocaleCompare(action,"Background") == 0)
+ special_info.text=(char *) "Backdrop";
+ if (LocaleCompare(action,"New") == 0)
+ special_info.text=(char *) "Gradation";
+ if (LocaleCompare(action,"Resize") == 0)
+ special_info.text=(char *) "Constrain ratio";
+ if (LocaleCompare(action,"Save") == 0)
+ special_info.text=(char *) "Non-progressive";
+ if (LocaleCompare(action,"Shade") == 0)
+ special_info.text=(char *) "Color shading";
+ /*
+ Initialize text information.
+ */
+ XGetWidgetInfo(query,&text_info);
+ text_info.width=reply_info.width;
+ text_info.height=height;
+ text_info.x=reply_info.x-(QuantumMargin >> 1);
+ text_info.y=QuantumMargin;
+ text_info.center=False;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw Dialog widget.
+ */
+ XDrawWidgetText(display,&windows->widget,&text_info);
+ XDrawBeveledMatte(display,&windows->widget,&reply_info);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ if (anomaly)
+ XDrawBeveledButton(display,&windows->widget,&special_info);
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ state&=(~RedrawWidgetState);
+ }
+ /*
+ Wait for next event.
+ */
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (anomaly)
+ if (MatteIsActive(special_info,event.xbutton))
+ {
+ /*
+ Option button status changed.
+ */
+ special_info.raised=!special_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&special_info);
+ break;
+ }
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ /*
+ User pressed Action button.
+ */
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ /*
+ User pressed Cancel button.
+ */
+ cancel_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ if (!MatteIsActive(reply_info,event.xbutton))
+ break;
+ if (event.xbutton.button != Button2)
+ {
+ static Time
+ click_time;
+
+ /*
+ Move text cursor to position of button press.
+ */
+ x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
+ for (i=1; i <= Extent(reply_info.marker); i++)
+ if (XTextWidth(font_info,reply_info.marker,i) > x)
+ break;
+ reply_info.cursor=reply_info.marker+i-1;
+ if (event.xbutton.time > (click_time+DoubleClick))
+ reply_info.highlight=False;
+ else
+ {
+ /*
+ Become the XA_PRIMARY selection owner.
+ */
+ (void) strlcpy(primary_selection,reply_info.text,
+ MaxTextExtent);
+ (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
+ event.xbutton.time);
+ reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
+ windows->widget.id;
+ }
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ click_time=event.xbutton.time;
+ break;
+ }
+ /*
+ Request primary selection.
+ */
+ (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
+ windows->widget.id,event.xbutton.time);
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (!action_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(action_info,event.xbutton))
+ state|=ExitState;
+ action_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ }
+ if (!cancel_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ }
+ cancel_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == windows->widget.id)
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static int
+ length;
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ state|=ExitState;
+ break;
+ }
+ if (key_symbol == XK_Control_L)
+ {
+ state|=ControlState;
+ break;
+ }
+ if (state & ControlState)
+ switch ((int) key_symbol)
+ {
+ case XK_u:
+ case XK_U:
+ {
+ /*
+ Erase the entire line of text.
+ */
+ *reply_info.text='\0';
+ reply_info.cursor=reply_info.text;
+ reply_info.marker=reply_info.text;
+ reply_info.highlight=False;
+ break;
+ }
+ default:
+ break;
+ }
+ XEditText(display,&reply_info,key_symbol,command,state);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ break;
+ }
+ case KeyRelease:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key release.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if (key_symbol == XK_Control_L)
+ state&=(~ControlState);
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (state & InactiveWidgetState)
+ break;
+ if (action_info.raised == MatteIsActive(action_info,event.xmotion))
+ {
+ /*
+ Action button status changed.
+ */
+ action_info.raised=!action_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
+ {
+ /*
+ Cancel button status changed.
+ */
+ cancel_info.raised=!cancel_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ break;
+ }
+ case SelectionClear:
+ {
+ reply_info.highlight=False;
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ break;
+ }
+ case SelectionNotify:
+ {
+ Atom
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ Obtain response from primary selection.
+ */
+ if (event.xselection.property == (Atom) None)
+ break;
+ status=XGetWindowProperty(display,event.xselection.requestor,
+ event.xselection.property,0L,2047L,True,XA_STRING,&type,&format,
+ &length,&after,&data);
+ if ((status != Success) || (type != XA_STRING) || (format == 32) ||
+ (length == 0))
+ break;
+ if ((Extent(reply_info.text)+length) >= MaxTextExtent)
+ (void) XBell(display,0);
+ else
+ {
+ /*
+ Insert primary selection in reply text.
+ */
+ *(data+length)='\0';
+ XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
+ state);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ }
+ (void) XFree((void *) data);
+ break;
+ }
+ case SelectionRequest:
+ {
+ XSelectionEvent
+ notify;
+
+ XSelectionRequestEvent
+ *request;
+
+ if (!reply_info.highlight)
+ break;
+ /*
+ Set primary selection.
+ */
+ request=(&(event.xselectionrequest));
+ (void) XChangeProperty(request->display,request->requestor,
+ request->property,request->target,8,PropModeReplace,
+ (unsigned char *) primary_selection,Extent(primary_selection));
+ notify.type=SelectionNotify;
+ notify.display=request->display;
+ notify.requestor=request->requestor;
+ notify.selection=request->selection;
+ notify.target=request->target;
+ notify.time=request->time;
+ if (request->property == None)
+ notify.property=request->target;
+ else
+ notify.property=request->property;
+ (void) XSendEvent(request->display,request->requestor,False,0,
+ (XEvent *) &notify);
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+ if (anomaly)
+ if (special_info.raised)
+ if (*reply != '\0')
+ raised=True;
+ return(!raised);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X F i l e B r o w s e r W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXFileBrowserWidget displays a File Browser widget with a file query
+% to the user. The user keys a reply and presses the Action or Cancel button
+% to exit. The typed text is returned as the reply function parameter.
+%
+% The format of the MagickXFileBrowserWidget method is:
+%
+% void MagickXFileBrowserWidget(Display *display,MagickXWindows *windows,
+% const char *action,char *reply)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o action: Specifies a pointer to the action of this widget.
+%
+% o reply: The response from the user is returned in this parameter.
+%
+%
+*/
+MagickExport void MagickXFileBrowserWidget(Display *display,MagickXWindows *windows,
+ const char *action,char *reply)
+{
+#define CancelButtonText "Cancel"
+#define DirectoryText "Directory:"
+#define FilenameText "File name:"
+#define GrabButtonText "Grab"
+#define FormatButtonText "Format"
+#define HomeButtonText "Home"
+#define UpButtonText "Up"
+
+ char
+ **filelist,
+ home_directory[MaxTextExtent],
+ primary_selection[MaxTextExtent],
+ text[MaxTextExtent],
+ working_directory[MaxTextExtent];
+
+ int
+ height,
+ status,
+ text_width,
+ width,
+ x,
+ y;
+
+ long
+ files;
+
+ register int
+ i;
+
+ static char
+ glob_pattern[MaxTextExtent] = "*",
+ format[MaxTextExtent] = "miff";
+
+ static char
+ mask = CWWidth | CWHeight | CWX | CWY;
+
+ unsigned int
+ anomaly,
+ visible_files;
+
+ unsigned long
+ delay,
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ action_info,
+ cancel_info,
+ expose_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ special_info,
+ list_info,
+ home_info,
+ north_info,
+ reply_info,
+ scroll_info,
+ selection_info,
+ slider_info,
+ south_info,
+ text_info,
+ up_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Read filelist from current directory.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(action != (char *) NULL);
+ assert(reply != (char *) NULL);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ if (getcwd(home_directory,MaxTextExtent-1) == NULL)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to get current directory:",
+ home_directory);
+ return;
+ }
+ (void) strlcpy(working_directory,home_directory,MaxTextExtent);
+ filelist=ListFiles(working_directory,glob_pattern,&files);
+ if (filelist == (char **) NULL)
+ {
+ /*
+ Directory read failed.
+ */
+ MagickXNoticeWidget(display,windows,"Unable to read directory:",
+ working_directory);
+ (void) MagickXDialogWidget(display,windows,action,"Enter filename:",reply);
+ return;
+ }
+ /*
+ Determine File Browser widget attributes.
+ */
+ font_info=windows->widget.font_info;
+ text_width=0;
+ for (i=0; i < files; i++)
+ if (XTextWidth(font_info,filelist[i],Extent(filelist[i])) > text_width)
+ text_width=XTextWidth(font_info,filelist[i],Extent(filelist[i]));
+ width=XTextWidth(font_info,(char *) action,Extent(action));
+ if (XTextWidth(font_info,GrabButtonText,Extent(GrabButtonText)) > width)
+ width=XTextWidth(font_info,GrabButtonText,Extent(GrabButtonText));
+ if (XTextWidth(font_info,FormatButtonText,Extent(FormatButtonText)) > width)
+ width=XTextWidth(font_info,FormatButtonText,Extent(FormatButtonText));
+ if (XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)) > width)
+ width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText));
+ if (XTextWidth(font_info,HomeButtonText,Extent(HomeButtonText)) > width)
+ width=XTextWidth(font_info,HomeButtonText,Extent(HomeButtonText));
+ if (XTextWidth(font_info,UpButtonText,Extent(UpButtonText)) > width)
+ width=XTextWidth(font_info,UpButtonText,Extent(UpButtonText));
+ width+=QuantumMargin;
+ if (XTextWidth(font_info,DirectoryText,Extent(DirectoryText)) > width)
+ width=XTextWidth(font_info,DirectoryText,Extent(DirectoryText));
+ if (XTextWidth(font_info,FilenameText,Extent(FilenameText)) > width)
+ width=XTextWidth(font_info,FilenameText,Extent(FilenameText));
+ height=font_info->ascent+font_info->descent;
+ /*
+ Position File Browser widget.
+ */
+ windows->widget.width=width+Min(text_width,MaxTextWidth)+6*QuantumMargin;
+ windows->widget.min_width=width+MinTextWidth+4*QuantumMargin;
+ if (windows->widget.width < windows->widget.min_width)
+ windows->widget.width=windows->widget.min_width;
+ windows->widget.height=((81*height) >> 2)+((13*QuantumMargin) >> 1)+4;
+ windows->widget.min_height=((23*height) >> 1)+((13*QuantumMargin) >> 1)+4;
+ if (windows->widget.height < windows->widget.min_height)
+ windows->widget.height=windows->widget.min_height;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map File Browser widget.
+ */
+ (void) strcpy(windows->widget.name,"Browse and Select a File");
+ status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->widget.id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,
+ windows->widget.screen,mask,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ /*
+ Respond to X events.
+ */
+ XGetWidgetInfo((char *) NULL,&slider_info);
+ XGetWidgetInfo((char *) NULL,&north_info);
+ XGetWidgetInfo((char *) NULL,&south_info);
+ visible_files=0;
+ anomaly=(LocaleCompare(action,"Composite") == 0) ||
+ (LocaleCompare(action,"Open") == 0) || (LocaleCompare(action,"Map") == 0);
+ delay=SuspendTime << 2;
+ state=UpdateConfigurationState;
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ int
+ id;
+
+ /*
+ Initialize button information.
+ */
+ XGetWidgetInfo(CancelButtonText,&cancel_info);
+ cancel_info.width=width;
+ cancel_info.height=(3*height) >> 1;
+ cancel_info.x=windows->widget.width-cancel_info.width-QuantumMargin-2;
+ cancel_info.y=windows->widget.height-cancel_info.height-QuantumMargin;
+ XGetWidgetInfo(action,&action_info);
+ action_info.width=width;
+ action_info.height=(3*height) >> 1;
+ action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
+ (action_info.bevel_width << 1));
+ action_info.y=cancel_info.y;
+ XGetWidgetInfo(GrabButtonText,&special_info);
+ special_info.width=width;
+ special_info.height=(3*height) >> 1;
+ special_info.x=action_info.x-(action_info.width+(QuantumMargin >> 1)+
+ (special_info.bevel_width << 1));
+ special_info.y=action_info.y;
+ if (!anomaly)
+ {
+ register char
+ *p;
+
+ special_info.text=(char *) FormatButtonText;
+ p=reply+Extent(reply)-1;
+ while ((p > (reply+1)) && (*(p-1) != '.'))
+ p--;
+ if ((p > (reply+1)) && (*(p-1) == '.'))
+ (void) strlcpy(format,p,MaxTextExtent);
+ }
+ XGetWidgetInfo(UpButtonText,&up_info);
+ up_info.width=width;
+ up_info.height=(3*height) >> 1;
+ up_info.x=QuantumMargin;
+ up_info.y=((5*QuantumMargin) >> 1)+height;
+ XGetWidgetInfo(HomeButtonText,&home_info);
+ home_info.width=width;
+ home_info.height=(3*height) >> 1;
+ home_info.x=QuantumMargin;
+ home_info.y=up_info.y+up_info.height+QuantumMargin;
+ /*
+ Initialize reply information.
+ */
+ XGetWidgetInfo(reply,&reply_info);
+ reply_info.raised=False;
+ reply_info.bevel_width--;
+ reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
+ reply_info.height=height << 1;
+ reply_info.x=width+(QuantumMargin << 1);
+ reply_info.y=action_info.y-reply_info.height-QuantumMargin;
+ /*
+ Initialize scroll information.
+ */
+ XGetWidgetInfo((char *) NULL,&scroll_info);
+ scroll_info.bevel_width--;
+ scroll_info.width=height;
+ scroll_info.height=reply_info.y-up_info.y-(QuantumMargin >> 1);
+ scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
+ scroll_info.y=up_info.y-reply_info.bevel_width;
+ scroll_info.raised=False;
+ scroll_info.trough=True;
+ north_info=scroll_info;
+ north_info.raised=True;
+ north_info.width-=(north_info.bevel_width << 1);
+ north_info.height=north_info.width-1;
+ north_info.x+=north_info.bevel_width;
+ north_info.y+=north_info.bevel_width;
+ south_info=north_info;
+ south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
+ south_info.height;
+ id=slider_info.id;
+ slider_info=north_info;
+ slider_info.id=id;
+ slider_info.width-=2;
+ slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
+ slider_info.bevel_width+2;
+ slider_info.height=
+ scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+2;
+ visible_files=(scroll_info.height-(height >> 3)-3)/((9*height) >> 3);
+ if (files > (int) visible_files)
+ slider_info.height=(visible_files*slider_info.height)/files;
+ slider_info.max_y=south_info.y-south_info.bevel_width-
+ slider_info.bevel_width-2;
+ slider_info.x=scroll_info.x+slider_info.bevel_width+1;
+ slider_info.y=slider_info.min_y;
+ expose_info=scroll_info;
+ expose_info.y=slider_info.y;
+ /*
+ Initialize list information.
+ */
+ XGetWidgetInfo((char *) NULL,&list_info);
+ list_info.raised=False;
+ list_info.bevel_width--;
+ list_info.width=scroll_info.x-reply_info.x-(QuantumMargin >> 1);
+ list_info.height=scroll_info.height;
+ list_info.x=reply_info.x;
+ list_info.y=scroll_info.y;
+ if (!windows->widget.mapped)
+ state|=JumpListState;
+ /*
+ Initialize text information.
+ */
+ *text='\0';
+ XGetWidgetInfo(text,&text_info);
+ text_info.center=False;
+ text_info.width=reply_info.width;
+ text_info.height=height;
+ text_info.x=list_info.x-(QuantumMargin >> 1);
+ text_info.y=QuantumMargin;
+ /*
+ Initialize selection information.
+ */
+ XGetWidgetInfo((char *) NULL,&selection_info);
+ selection_info.center=False;
+ selection_info.width=list_info.width;
+ selection_info.height=(9*height) >> 3;
+ selection_info.x=list_info.x;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw File Browser window.
+ */
+ x=QuantumMargin;
+ y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,DirectoryText,
+ Extent(DirectoryText));
+ FormatString(text_info.text,"%.1024s%.1024s%.1024s",working_directory,
+ DirectorySeparator,glob_pattern);
+ XDrawWidgetText(display,&windows->widget,&text_info);
+ XDrawBeveledButton(display,&windows->widget,&up_info);
+ XDrawBeveledButton(display,&windows->widget,&home_info);
+ XDrawBeveledMatte(display,&windows->widget,&list_info);
+ XDrawBeveledMatte(display,&windows->widget,&scroll_info);
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ x=QuantumMargin;
+ y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,FilenameText,
+ Extent(FilenameText));
+ XDrawBeveledMatte(display,&windows->widget,&reply_info);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ XDrawBeveledButton(display,&windows->widget,&special_info);
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ selection_info.id=(~0);
+ state|=RedrawListState;
+ state&=(~RedrawWidgetState);
+ }
+ if (state & UpdateListState)
+ {
+ char
+ **checklist;
+
+ long
+ number_files;
+
+ /*
+ Update file list.
+ */
+ checklist=ListFiles(working_directory,glob_pattern,&number_files);
+ if (checklist == (char **) NULL)
+ {
+ /*
+ Reply is a filename, exit.
+ */
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ for (i=0; i < files; i++)
+ MagickFreeMemory(filelist[i]);
+ if (filelist != (char **) NULL)
+ MagickFreeMemory(filelist);
+ filelist=checklist;
+ files=number_files;
+ /*
+ Update file list.
+ */
+ slider_info.height=
+ scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
+ if (files > (int) visible_files)
+ slider_info.height=(visible_files*slider_info.height)/files;
+ slider_info.max_y=south_info.y-south_info.bevel_width-
+ slider_info.bevel_width-2;
+ slider_info.id=0;
+ slider_info.y=slider_info.min_y;
+ expose_info.y=slider_info.y;
+ selection_info.id=(~0);
+ list_info.id=(~0);
+ state|=RedrawListState;
+ /*
+ Redraw directory name & reply.
+ */
+ if (!IsGlob(reply_info.text))
+ {
+ *reply_info.text='\0';
+ reply_info.cursor=reply_info.text;
+ }
+ FormatString(text_info.text,"%.1024s%.1024s%.1024s",working_directory,
+ DirectorySeparator,glob_pattern);
+ XDrawWidgetText(display,&windows->widget,&text_info);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ XDrawBeveledMatte(display,&windows->widget,&scroll_info);
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ state&=(~UpdateListState);
+ }
+ if (state & JumpListState)
+ {
+ /*
+ Jump scroll to match user filename.
+ */
+ list_info.id=(~0);
+ for (i=0; i < files; i++)
+ if (LocaleCompare(filelist[i],reply) >= 0)
+ {
+ list_info.id=LocaleCompare(filelist[i],reply) == 0 ? i : ~0;
+ break;
+ }
+ if ((i < slider_info.id) || (i >= (int) (slider_info.id+visible_files)))
+ slider_info.id=i-(visible_files >> 1);
+ selection_info.id=(~0);
+ state|=RedrawListState;
+ state&=(~JumpListState);
+ }
+ if (state & RedrawListState)
+ {
+ /*
+ Determine slider id and position.
+ */
+ if (slider_info.id >= (int) (files-visible_files))
+ slider_info.id=(int) (files-visible_files);
+ if ((slider_info.id < 0) || (files <= (int) visible_files))
+ slider_info.id=0;
+ slider_info.y=slider_info.min_y;
+ if (files > 0)
+ slider_info.y+=
+ slider_info.id*(slider_info.max_y-slider_info.min_y+1)/files;
+ if (slider_info.id != selection_info.id)
+ {
+ /*
+ Redraw scroll bar and file names.
+ */
+ selection_info.id=slider_info.id;
+ selection_info.y=list_info.y+(height >> 3)+2;
+ for (i=0; i < (int) visible_files; i++)
+ {
+ selection_info.raised=(slider_info.id+i) != list_info.id;
+ selection_info.text=(char *) NULL;
+ if ((slider_info.id+i) < files)
+ selection_info.text=filelist[slider_info.id+i];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ selection_info.y+=(int) selection_info.height;
+ }
+ /*
+ Update slider.
+ */
+ if (slider_info.y > expose_info.y)
+ {
+ expose_info.height=slider_info.y-expose_info.y;
+ expose_info.y=slider_info.y-expose_info.height-
+ slider_info.bevel_width-1;
+ }
+ else
+ {
+ expose_info.height=expose_info.y-slider_info.y;
+ expose_info.y=slider_info.y+slider_info.height+
+ slider_info.bevel_width+1;
+ }
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawMatte(display,&windows->widget,&expose_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ expose_info.y=slider_info.y;
+ }
+ state&=(~RedrawListState);
+ }
+ /*
+ Wait for next event.
+ */
+ if (north_info.raised && south_info.raised)
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ else
+ {
+ /*
+ Brief delay before advancing scroll bar.
+ */
+ MagickXDelay(display,delay);
+ delay=SuspendTime;
+ (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
+ if (!north_info.raised)
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ slider_info.id--;
+ state|=RedrawListState;
+ }
+ if (!south_info.raised)
+ if (slider_info.id < files)
+ {
+ /*
+ Move slider down.
+ */
+ slider_info.id++;
+ state|=RedrawListState;
+ }
+ if (event.type != ButtonRelease)
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (MatteIsActive(slider_info,event.xbutton))
+ {
+ /*
+ Track slider.
+ */
+ slider_info.active=True;
+ break;
+ }
+ if (MatteIsActive(north_info,event.xbutton))
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ north_info.raised=False;
+ slider_info.id--;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(south_info,event.xbutton))
+ if (slider_info.id < files)
+ {
+ /*
+ Move slider down.
+ */
+ south_info.raised=False;
+ slider_info.id++;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(scroll_info,event.xbutton))
+ {
+ /*
+ Move slider.
+ */
+ if (event.xbutton.y < slider_info.y)
+ slider_info.id-=(visible_files-1);
+ else
+ slider_info.id+=(visible_files-1);
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(list_info,event.xbutton))
+ {
+ unsigned int
+ id;
+
+ /*
+ User pressed file matte.
+ */
+ id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
+ selection_info.height;
+ if ((int) id >= files)
+ break;
+ (void) strlcpy(reply_info.text,filelist[id],MaxTextExtent);
+ reply_info.highlight=False;
+ reply_info.marker=reply_info.text;
+ reply_info.cursor=reply_info.text+Extent(reply_info.text);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ if ((int) id == list_info.id)
+ {
+ (void) strlcpy(working_directory,reply_info.text,
+ MaxTextExtent);
+ state|=UpdateListState;
+ }
+ selection_info.id=(~0);
+ list_info.id=id;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(up_info,event.xbutton))
+ {
+ /*
+ User pressed Up button.
+ */
+ up_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&up_info);
+ break;
+ }
+ if (MatteIsActive(home_info,event.xbutton))
+ {
+ /*
+ User pressed Home button.
+ */
+ home_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&home_info);
+ break;
+ }
+ if (MatteIsActive(special_info,event.xbutton))
+ {
+ /*
+ User pressed Special button.
+ */
+ special_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&special_info);
+ break;
+ }
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ /*
+ User pressed action button.
+ */
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ /*
+ User pressed Cancel button.
+ */
+ cancel_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ if (!MatteIsActive(reply_info,event.xbutton))
+ break;
+ if (event.xbutton.button != Button2)
+ {
+ static Time
+ click_time;
+
+ /*
+ Move text cursor to position of button press.
+ */
+ x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
+ for (i=1; i <= Extent(reply_info.marker); i++)
+ if (XTextWidth(font_info,reply_info.marker,i) > x)
+ break;
+ reply_info.cursor=reply_info.marker+i-1;
+ if (event.xbutton.time > (click_time+DoubleClick))
+ reply_info.highlight=False;
+ else
+ {
+ /*
+ Become the XA_PRIMARY selection owner.
+ */
+ (void) strlcpy(primary_selection,reply_info.text,
+ MaxTextExtent);
+ (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
+ event.xbutton.time);
+ reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
+ windows->widget.id;
+ }
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ click_time=event.xbutton.time;
+ break;
+ }
+ /*
+ Request primary selection.
+ */
+ (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
+ windows->widget.id,event.xbutton.time);
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (!north_info.raised)
+ {
+ /*
+ User released up button.
+ */
+ delay=SuspendTime << 2;
+ north_info.raised=True;
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ }
+ if (!south_info.raised)
+ {
+ /*
+ User released down button.
+ */
+ delay=SuspendTime << 2;
+ south_info.raised=True;
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ }
+ if (slider_info.active)
+ {
+ /*
+ Stop tracking slider.
+ */
+ slider_info.active=False;
+ break;
+ }
+ if (!up_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(up_info,event.xbutton))
+ {
+ (void) strcpy(working_directory,"..");
+ state|=UpdateListState;
+ }
+ up_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&up_info);
+ }
+ if (!home_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(home_info,event.xbutton))
+ {
+ (void) strlcpy(working_directory,home_directory,
+ MaxTextExtent);
+ state|=UpdateListState;
+ }
+ home_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&home_info);
+ }
+ if (!special_info.raised)
+ {
+ if (!anomaly)
+ {
+ char
+ **formats;
+
+ const MagickInfo
+ *magick_info;
+
+ ExceptionInfo
+ exception;
+
+ register const MagickInfo
+ *p;
+
+ /*
+ Let user select image format.
+ */
+ GetExceptionInfo(&exception);
+ magick_info=GetMagickInfo("*",&exception);
+ DestroyExceptionInfo(&exception);
+ i=0;
+ for (p=magick_info; p != (MagickInfo *) NULL; p=p->next)
+ i++;
+ formats=MagickAllocateMemory(char **,(i+1)*sizeof(char *));
+ i=0;
+ for (p=magick_info; p != (MagickInfo *) NULL; p=p->next)
+ {
+ if (p->stealth)
+ continue;
+ if (!p->encoder)
+ continue;
+ formats[i]=AllocateString(p->name);
+ LocaleLower((char *) formats[i]);
+ i++;
+ }
+ formats[i]=(char *) NULL;
+ (void) XDefineCursor(display,windows->widget.id,
+ windows->widget.busy_cursor);
+ windows->popup.x=windows->widget.x+60;
+ windows->popup.y=windows->widget.y+60;
+ MagickXListBrowserWidget(display,windows,&windows->popup,
+ (const char **)formats,"Select","Select image format type:",format);
+ MagickXSetCursorState(display,windows,True);
+ (void) XDefineCursor(display,windows->widget.id,
+ windows->widget.cursor);
+ AppendImageFormat(format,reply_info.text);
+ reply_info.cursor=reply_info.text+Extent(reply_info.text);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ special_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&special_info);
+ for (i=0; formats[i] != (char *) NULL; i++)
+ MagickFreeMemory(formats[i]);
+ MagickFreeMemory(formats);
+ break;
+ }
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(special_info,event.xbutton))
+ {
+ (void) strcpy(reply_info.text,"x:");
+ state|=ExitState;
+ }
+ special_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&special_info);
+ }
+ if (!action_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ {
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ if (*reply_info.text == '\0')
+ (void) XBell(display,0);
+ else
+ state|=ExitState;
+ }
+ }
+ action_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ }
+ if (!cancel_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ }
+ cancel_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == windows->widget.id)
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static int
+ length;
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if (AreaIsActive(scroll_info,event.xkey))
+ {
+ /*
+ Move slider.
+ */
+ switch ((int) key_symbol)
+ {
+ case XK_Home:
+ case XK_KP_Home:
+ {
+ slider_info.id=0;
+ break;
+ }
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ slider_info.id--;
+ break;
+ }
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ slider_info.id++;
+ break;
+ }
+ case XK_Prior:
+ case XK_KP_Prior:
+ {
+ slider_info.id-=visible_files;
+ break;
+ }
+ case XK_Next:
+ case XK_KP_Next:
+ {
+ slider_info.id+=visible_files;
+ break;
+ }
+ case XK_End:
+ case XK_KP_End:
+ {
+ slider_info.id=files;
+ break;
+ }
+ }
+ state|=RedrawListState;
+ break;
+ }
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ /*
+ Read new directory or glob patterm.
+ */
+ if (*reply_info.text == '\0')
+ break;
+ if (IsGlob(reply_info.text))
+ (void) strlcpy(glob_pattern,reply_info.text,MaxTextExtent);
+ else
+ {
+ (void) strlcpy(working_directory,reply_info.text,
+ MaxTextExtent);
+ if (*working_directory == '~')
+ ExpandFilename(working_directory);
+ }
+ state|=UpdateListState;
+ break;
+ }
+ if (key_symbol == XK_Control_L)
+ {
+ state|=ControlState;
+ break;
+ }
+ if (state & ControlState)
+ switch ((int) key_symbol)
+ {
+ case XK_u:
+ case XK_U:
+ {
+ /*
+ Erase the entire line of text.
+ */
+ *reply_info.text='\0';
+ reply_info.cursor=reply_info.text;
+ reply_info.marker=reply_info.text;
+ reply_info.highlight=False;
+ break;
+ }
+ default:
+ break;
+ }
+ XEditText(display,&reply_info,key_symbol,command,state);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=JumpListState;
+ break;
+ }
+ case KeyRelease:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key release.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if (key_symbol == XK_Control_L)
+ state&=(~ControlState);
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MapNotify:
+ {
+ mask&=(~CWX);
+ mask&=(~CWY);
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (slider_info.active)
+ {
+ /*
+ Move slider matte.
+ */
+ slider_info.y=event.xmotion.y-
+ ((slider_info.height+slider_info.bevel_width) >> 1)+1;
+ if (slider_info.y < slider_info.min_y)
+ slider_info.y=slider_info.min_y;
+ if (slider_info.y > slider_info.max_y)
+ slider_info.y=slider_info.max_y;
+ slider_info.id=0;
+ if (slider_info.y != slider_info.min_y)
+ slider_info.id=(files*(slider_info.y-slider_info.min_y+1))/
+ (slider_info.max_y-slider_info.min_y+1);
+ state|=RedrawListState;
+ break;
+ }
+ if (state & InactiveWidgetState)
+ break;
+ if (up_info.raised == MatteIsActive(up_info,event.xmotion))
+ {
+ /*
+ Up button status changed.
+ */
+ up_info.raised=!up_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&up_info);
+ break;
+ }
+ if (home_info.raised == MatteIsActive(home_info,event.xmotion))
+ {
+ /*
+ Home button status changed.
+ */
+ home_info.raised=!home_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&home_info);
+ break;
+ }
+ if (special_info.raised == MatteIsActive(special_info,event.xmotion))
+ {
+ /*
+ Grab button status changed.
+ */
+ special_info.raised=!special_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&special_info);
+ break;
+ }
+ if (action_info.raised == MatteIsActive(action_info,event.xmotion))
+ {
+ /*
+ Action button status changed.
+ */
+ action_info.raised=!action_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
+ {
+ /*
+ Cancel button status changed.
+ */
+ cancel_info.raised=!cancel_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ break;
+ }
+ case SelectionClear:
+ {
+ reply_info.highlight=False;
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ break;
+ }
+ case SelectionNotify:
+ {
+ Atom
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ Obtain response from primary selection.
+ */
+ if (event.xselection.property == (Atom) None)
+ break;
+ status=XGetWindowProperty(display,event.xselection.requestor,
+ event.xselection.property,0L,2047L,True,XA_STRING,&type,&format,
+ &length,&after,&data);
+ if ((status != Success) || (type != XA_STRING) || (format == 32) ||
+ (length == 0))
+ break;
+ if ((Extent(reply_info.text)+length) >= MaxTextExtent)
+ (void) XBell(display,0);
+ else
+ {
+ /*
+ Insert primary selection in reply text.
+ */
+ *(data+length)='\0';
+ XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
+ state);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=JumpListState;
+ state|=RedrawActionState;
+ }
+ (void) XFree((void *) data);
+ break;
+ }
+ case SelectionRequest:
+ {
+ XSelectionEvent
+ notify;
+
+ XSelectionRequestEvent
+ *request;
+
+ if (!reply_info.highlight)
+ break;
+ /*
+ Set primary selection.
+ */
+ request=(&(event.xselectionrequest));
+ (void) XChangeProperty(request->display,request->requestor,
+ request->property,request->target,8,PropModeReplace,
+ (unsigned char *) primary_selection,Extent(primary_selection));
+ notify.type=SelectionNotify;
+ notify.display=request->display;
+ notify.requestor=request->requestor;
+ notify.selection=request->selection;
+ notify.target=request->target;
+ notify.time=request->time;
+ if (request->property == None)
+ notify.property=request->target;
+ else
+ notify.property=request->property;
+ (void) XSendEvent(request->display,request->requestor,False,0,
+ (XEvent *) &notify);
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+ /*
+ Free file list.
+ */
+ for (i=0; i < files; i++)
+ MagickFreeMemory(filelist[i]);
+ MagickFreeMemory(filelist);
+ if (*reply == '~')
+ ExpandFilename(reply);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X F o n t B r o w s e r W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXFontBrowserWidget displays a Font Browser widget with a font query
+% to the user. The user keys a reply and presses the Action or Cancel button
+% to exit. The typed text is returned as the reply function parameter.
+%
+% The format of the MagickXFontBrowserWidget method is:
+%
+% void MagickXFontBrowserWidget(Display *display,MagickXWindows *windows,
+% const char *action,char *reply)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o action: Specifies a pointer to the action of this widget.
+%
+% o reply: The response from the user is returned in this parameter.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int FontCompare(const void *x,const void *y)
+{
+ register char
+ *p,
+ *q;
+
+ p=(char *) *((char **) x);
+ q=(char *) *((char **) y);
+ while ((*p != '\0') && (*q != '\0') && (*p == *q))
+ {
+ p++;
+ q++;
+ }
+ return(*p-(*q));
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+MagickExport void MagickXFontBrowserWidget(Display *display,MagickXWindows *windows,
+ const char *action,char *reply)
+{
+#define BackButtonText "Back"
+#define CancelButtonText "Cancel"
+#define FontnameText "Name:"
+#define FontPatternText "Pattern:"
+#define ResetButtonText "Reset"
+
+ char
+ back_pattern[MaxTextExtent],
+ **fontlist,
+ **listhead,
+ primary_selection[MaxTextExtent],
+ reset_pattern[MaxTextExtent],
+ text[MaxTextExtent];
+
+ int
+ fonts,
+ height,
+ status,
+ text_width,
+ width,
+ x,
+ y;
+
+ register int
+ i;
+
+ static char
+ glob_pattern[MaxTextExtent] = "*";
+
+ static char
+ mask = CWWidth | CWHeight | CWX | CWY;
+
+ unsigned int
+ visible_fonts;
+
+ unsigned long
+ delay,
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ action_info,
+ back_info,
+ cancel_info,
+ expose_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ list_info,
+ mode_info,
+ north_info,
+ reply_info,
+ reset_info,
+ scroll_info,
+ selection_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ slider_info,
+ south_info,
+ text_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Get font list and sort in ascending order.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(action != (char *) NULL);
+ assert(reply != (char *) NULL);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ (void) strlcpy(back_pattern,glob_pattern,MaxTextExtent);
+ (void) strcpy(reset_pattern,"*");
+ fontlist=XListFonts(display,glob_pattern,32767,&fonts);
+ if (fonts == 0)
+ {
+ /*
+ Pattern failed, obtain all the fonts.
+ */
+ MagickXNoticeWidget(display,windows,"Unable to obtain fonts names:",
+ glob_pattern);
+ (void) strcpy(glob_pattern,"*");
+ fontlist=XListFonts(display,glob_pattern,32767,&fonts);
+ if (fontlist == (char **) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to obtain fonts names:",
+ glob_pattern);
+ return;
+ }
+ }
+ /*
+ Sort font list in ascending order.
+ */
+ listhead=fontlist;
+ fontlist=MagickAllocateMemory(char **,fonts*sizeof(char *));
+ if (fontlist == (char **) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"MemoryAllocationFailed",
+ "UnableToViewFonts");
+ return;
+ }
+ for (i=0; i < fonts; i++)
+ fontlist[i]=listhead[i];
+ qsort((void *) fontlist,fonts,sizeof(char *),FontCompare);
+ /*
+ Determine Font Browser widget attributes.
+ */
+ font_info=windows->widget.font_info;
+ text_width=0;
+ for (i=0; i < fonts; i++)
+ if (XTextWidth(font_info,fontlist[i],Extent(fontlist[i])) > text_width)
+ text_width=XTextWidth(font_info,fontlist[i],Extent(fontlist[i]));
+ width=XTextWidth(font_info,(char *) action,Extent(action));
+ if (XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)) > width)
+ width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText));
+ if (XTextWidth(font_info,ResetButtonText,Extent(ResetButtonText)) > width)
+ width=XTextWidth(font_info,ResetButtonText,Extent(ResetButtonText));
+ if (XTextWidth(font_info,BackButtonText,Extent(BackButtonText)) > width)
+ width=XTextWidth(font_info,BackButtonText,Extent(BackButtonText));
+ width+=QuantumMargin;
+ if (XTextWidth(font_info,FontPatternText,Extent(FontPatternText)) > width)
+ width=XTextWidth(font_info,FontPatternText,Extent(FontPatternText));
+ if (XTextWidth(font_info,FontnameText,Extent(FontnameText)) > width)
+ width=XTextWidth(font_info,FontnameText,Extent(FontnameText));
+ height=font_info->ascent+font_info->descent;
+ /*
+ Position Font Browser widget.
+ */
+ windows->widget.width=width+Min(text_width,MaxTextWidth)+6*QuantumMargin;
+ windows->widget.min_width=width+MinTextWidth+4*QuantumMargin;
+ if (windows->widget.width < windows->widget.min_width)
+ windows->widget.width=windows->widget.min_width;
+ windows->widget.height=((85*height) >> 2)+((13*QuantumMargin) >> 1)+4;
+ windows->widget.min_height=((27*height) >> 1)+((13*QuantumMargin) >> 1)+4;
+ if (windows->widget.height < windows->widget.min_height)
+ windows->widget.height=windows->widget.min_height;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map Font Browser widget.
+ */
+ (void) strcpy(windows->widget.name,"Browse and Select a Font");
+ status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->widget.id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,
+ windows->widget.screen,mask,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ /*
+ Respond to X events.
+ */
+ XGetWidgetInfo((char *) NULL,&slider_info);
+ XGetWidgetInfo((char *) NULL,&north_info);
+ XGetWidgetInfo((char *) NULL,&south_info);
+ visible_fonts=0;
+ delay=SuspendTime << 2;
+ state=UpdateConfigurationState;
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ int
+ id;
+
+ /*
+ Initialize button information.
+ */
+ XGetWidgetInfo(CancelButtonText,&cancel_info);
+ cancel_info.width=width;
+ cancel_info.height=(3*height) >> 1;
+ cancel_info.x=windows->widget.width-cancel_info.width-QuantumMargin-2;
+ cancel_info.y=windows->widget.height-cancel_info.height-QuantumMargin;
+ XGetWidgetInfo(action,&action_info);
+ action_info.width=width;
+ action_info.height=(3*height) >> 1;
+ action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
+ (action_info.bevel_width << 1));
+ action_info.y=cancel_info.y;
+ XGetWidgetInfo(BackButtonText,&back_info);
+ back_info.width=width;
+ back_info.height=(3*height) >> 1;
+ back_info.x=QuantumMargin;
+ back_info.y=((5*QuantumMargin) >> 1)+height;
+ XGetWidgetInfo(ResetButtonText,&reset_info);
+ reset_info.width=width;
+ reset_info.height=(3*height) >> 1;
+ reset_info.x=QuantumMargin;
+ reset_info.y=back_info.y+back_info.height+QuantumMargin;
+ /*
+ Initialize reply information.
+ */
+ XGetWidgetInfo(reply,&reply_info);
+ reply_info.raised=False;
+ reply_info.bevel_width--;
+ reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
+ reply_info.height=height << 1;
+ reply_info.x=width+(QuantumMargin << 1);
+ reply_info.y=action_info.y-(action_info.height << 1)-QuantumMargin;
+ /*
+ Initialize mode information.
+ */
+ XGetWidgetInfo(reply,&mode_info);
+ mode_info.bevel_width=0;
+ mode_info.width=action_info.x-reply_info.x-QuantumMargin;
+ mode_info.height=action_info.height << 1;
+ mode_info.x=reply_info.x;
+ mode_info.y=action_info.y-action_info.height+action_info.bevel_width;
+ /*
+ Initialize scroll information.
+ */
+ XGetWidgetInfo((char *) NULL,&scroll_info);
+ scroll_info.bevel_width--;
+ scroll_info.width=height;
+ scroll_info.height=reply_info.y-back_info.y-(QuantumMargin >> 1);
+ scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
+ scroll_info.y=back_info.y-reply_info.bevel_width;
+ scroll_info.raised=False;
+ scroll_info.trough=True;
+ north_info=scroll_info;
+ north_info.raised=True;
+ north_info.width-=(north_info.bevel_width << 1);
+ north_info.height=north_info.width-1;
+ north_info.x+=north_info.bevel_width;
+ north_info.y+=north_info.bevel_width;
+ south_info=north_info;
+ south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
+ south_info.height;
+ id=slider_info.id;
+ slider_info=north_info;
+ slider_info.id=id;
+ slider_info.width-=2;
+ slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
+ slider_info.bevel_width+2;
+ slider_info.height=
+ scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+2;
+ visible_fonts=
+ (scroll_info.height-(height >> 3)-3)/((9*height) >> 3);
+ if (fonts > (int) visible_fonts)
+ slider_info.height=(visible_fonts*slider_info.height)/fonts;
+ slider_info.max_y=south_info.y-south_info.bevel_width-
+ slider_info.bevel_width-2;
+ slider_info.x=scroll_info.x+slider_info.bevel_width+1;
+ slider_info.y=slider_info.min_y;
+ expose_info=scroll_info;
+ expose_info.y=slider_info.y;
+ /*
+ Initialize list information.
+ */
+ XGetWidgetInfo((char *) NULL,&list_info);
+ list_info.raised=False;
+ list_info.bevel_width--;
+ list_info.width=scroll_info.x-reply_info.x-(QuantumMargin >> 1);
+ list_info.height=scroll_info.height;
+ list_info.x=reply_info.x;
+ list_info.y=scroll_info.y;
+ if (!windows->widget.mapped)
+ state|=JumpListState;
+ /*
+ Initialize text information.
+ */
+ *text='\0';
+ XGetWidgetInfo(text,&text_info);
+ text_info.center=False;
+ text_info.width=reply_info.width;
+ text_info.height=height;
+ text_info.x=list_info.x-(QuantumMargin >> 1);
+ text_info.y=QuantumMargin;
+ /*
+ Initialize selection information.
+ */
+ XGetWidgetInfo((char *) NULL,&selection_info);
+ selection_info.center=False;
+ selection_info.width=list_info.width;
+ selection_info.height=(9*height) >> 3;
+ selection_info.x=list_info.x;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw Font Browser window.
+ */
+ x=QuantumMargin;
+ y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,FontPatternText,
+ Extent(FontPatternText));
+ (void) strlcpy(text_info.text,glob_pattern,MaxTextExtent);
+ XDrawWidgetText(display,&windows->widget,&text_info);
+ XDrawBeveledButton(display,&windows->widget,&back_info);
+ XDrawBeveledButton(display,&windows->widget,&reset_info);
+ XDrawBeveledMatte(display,&windows->widget,&list_info);
+ XDrawBeveledMatte(display,&windows->widget,&scroll_info);
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ x=QuantumMargin;
+ y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,FontnameText,
+ Extent(FontnameText));
+ XDrawBeveledMatte(display,&windows->widget,&reply_info);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ selection_info.id=(~0);
+ state|=RedrawActionState;
+ state|=RedrawListState;
+ state&=(~RedrawWidgetState);
+ }
+ if (state & UpdateListState)
+ {
+ char
+ **checklist;
+
+ int
+ number_fonts;
+
+ /*
+ Update font list.
+ */
+ checklist=XListFonts(display,glob_pattern,32767,&number_fonts);
+ if (checklist == (char **) NULL)
+ {
+ if ((strchr(glob_pattern,'*') == (char *) NULL) &&
+ (strchr(glob_pattern,'?') == (char *) NULL))
+ {
+ /*
+ Might be a scaleable font-- exit.
+ */
+ (void) strlcpy(reply,glob_pattern,MaxTextExtent);
+ (void) strlcpy(glob_pattern,back_pattern,MaxTextExtent);
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ (void) strlcpy(glob_pattern,back_pattern,MaxTextExtent);
+ (void) XBell(display,0);
+ }
+ else
+ if (number_fonts == 1)
+ {
+ /*
+ Reply is a single font name-- exit.
+ */
+ (void) strlcpy(reply,checklist[0],MaxTextExtent);
+ (void) strlcpy(glob_pattern,back_pattern,MaxTextExtent);
+ (void) XFreeFontNames(checklist);
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ else
+ {
+ (void) XFreeFontNames(listhead);
+ MagickFreeMemory(fontlist);
+ fontlist=checklist;
+ fonts=number_fonts;
+ }
+ /*
+ Sort font list in ascending order.
+ */
+ listhead=fontlist;
+ fontlist=MagickAllocateMemory(char **,fonts*sizeof(char *));
+ if (fontlist == (char **) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"MemoryAllocationFailed",
+ "UnableToViewFonts");
+ return;
+ }
+ for (i=0; i < fonts; i++)
+ fontlist[i]=listhead[i];
+ qsort((void *) fontlist,fonts,sizeof(fontlist[0]),FontCompare);
+ slider_info.height=
+ scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
+ if (fonts > (int) visible_fonts)
+ slider_info.height=(visible_fonts*slider_info.height)/fonts;
+ slider_info.max_y=south_info.y-south_info.bevel_width-
+ slider_info.bevel_width-2;
+ slider_info.id=0;
+ slider_info.y=slider_info.min_y;
+ expose_info.y=slider_info.y;
+ selection_info.id=(~0);
+ list_info.id=(~0);
+ state|=RedrawListState;
+ /*
+ Redraw font name & reply.
+ */
+ *reply_info.text='\0';
+ reply_info.cursor=reply_info.text;
+ (void) strlcpy(text_info.text,glob_pattern,MaxTextExtent);
+ XDrawWidgetText(display,&windows->widget,&text_info);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ XDrawBeveledMatte(display,&windows->widget,&scroll_info);
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ state&=(~UpdateListState);
+ }
+ if (state & JumpListState)
+ {
+ /*
+ Jump scroll to match user font.
+ */
+ list_info.id=(~0);
+ for (i=0; i < fonts; i++)
+ if (LocaleCompare(fontlist[i],reply) >= 0)
+ {
+ list_info.id=LocaleCompare(fontlist[i],reply) == 0 ? i : ~0;
+ break;
+ }
+ if ((i < slider_info.id) || (i >= (int) (slider_info.id+visible_fonts)))
+ slider_info.id=i-(visible_fonts >> 1);
+ selection_info.id=(~0);
+ state|=RedrawListState;
+ state&=(~JumpListState);
+ }
+ if (state & RedrawListState)
+ {
+ /*
+ Determine slider id and position.
+ */
+ if (slider_info.id >= (int) (fonts-visible_fonts))
+ slider_info.id=fonts-visible_fonts;
+ if ((slider_info.id < 0) || (fonts <= (int) visible_fonts))
+ slider_info.id=0;
+ slider_info.y=slider_info.min_y;
+ if (fonts > 0)
+ slider_info.y+=
+ slider_info.id*(slider_info.max_y-slider_info.min_y+1)/fonts;
+ if (slider_info.id != selection_info.id)
+ {
+ /*
+ Redraw scroll bar and file names.
+ */
+ selection_info.id=slider_info.id;
+ selection_info.y=list_info.y+(height >> 3)+2;
+ for (i=0; i < (int) visible_fonts; i++)
+ {
+ selection_info.raised=(slider_info.id+i) != list_info.id;
+ selection_info.text=(char *) NULL;
+ if ((slider_info.id+i) < fonts)
+ selection_info.text=fontlist[slider_info.id+i];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ selection_info.y+=(int) selection_info.height;
+ }
+ /*
+ Update slider.
+ */
+ if (slider_info.y > expose_info.y)
+ {
+ expose_info.height=slider_info.y-expose_info.y;
+ expose_info.y=slider_info.y-expose_info.height-
+ slider_info.bevel_width-1;
+ }
+ else
+ {
+ expose_info.height=expose_info.y-slider_info.y;
+ expose_info.y=slider_info.y+slider_info.height+
+ slider_info.bevel_width+1;
+ }
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawMatte(display,&windows->widget,&expose_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ expose_info.y=slider_info.y;
+ }
+ state&=(~RedrawListState);
+ }
+ if (state & RedrawActionState)
+ {
+ XFontStruct
+ *save_info;
+
+ /*
+ Display the selected font in a drawing area.
+ */
+ save_info=windows->widget.font_info;
+ font_info=XLoadQueryFont(display,reply_info.text);
+ if (font_info != (XFontStruct *) NULL)
+ {
+ windows->widget.font_info=font_info;;
+ (void) XSetFont(display,windows->widget.widget_context,
+ font_info->fid);
+ }
+ XDrawBeveledButton(display,&windows->widget,&mode_info);
+ windows->widget.font_info=save_info;
+ if (font_info != (XFontStruct *) NULL)
+ {
+ (void) XSetFont(display,windows->widget.widget_context,
+ windows->widget.font_info->fid);
+ (void) XFreeFont(display,font_info);
+ }
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state&=(~RedrawActionState);
+ }
+ /*
+ Wait for next event.
+ */
+ if (north_info.raised && south_info.raised)
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ else
+ {
+ /*
+ Brief delay before advancing scroll bar.
+ */
+ MagickXDelay(display,delay);
+ delay=SuspendTime;
+ (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
+ if (!north_info.raised)
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ slider_info.id--;
+ state|=RedrawListState;
+ }
+ if (!south_info.raised)
+ if (slider_info.id < fonts)
+ {
+ /*
+ Move slider down.
+ */
+ slider_info.id++;
+ state|=RedrawListState;
+ }
+ if (event.type != ButtonRelease)
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (MatteIsActive(slider_info,event.xbutton))
+ {
+ /*
+ Track slider.
+ */
+ slider_info.active=True;
+ break;
+ }
+ if (MatteIsActive(north_info,event.xbutton))
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ north_info.raised=False;
+ slider_info.id--;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(south_info,event.xbutton))
+ if (slider_info.id < fonts)
+ {
+ /*
+ Move slider down.
+ */
+ south_info.raised=False;
+ slider_info.id++;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(scroll_info,event.xbutton))
+ {
+ /*
+ Move slider.
+ */
+ if (event.xbutton.y < slider_info.y)
+ slider_info.id-=(visible_fonts-1);
+ else
+ slider_info.id+=(visible_fonts-1);
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(list_info,event.xbutton))
+ {
+ unsigned int
+ id;
+
+ /*
+ User pressed list matte.
+ */
+ id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
+ selection_info.height;
+ if ((int) id >= fonts)
+ break;
+ (void) strlcpy(reply_info.text,fontlist[id],MaxTextExtent);
+ reply_info.highlight=False;
+ reply_info.marker=reply_info.text;
+ reply_info.cursor=reply_info.text+Extent(reply_info.text);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=RedrawActionState;
+ if ((int) id == list_info.id)
+ {
+ (void) strlcpy(glob_pattern,reply_info.text,MaxTextExtent);
+ state|=UpdateListState;
+ }
+ selection_info.id=(~0);
+ list_info.id=id;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(back_info,event.xbutton))
+ {
+ /*
+ User pressed Back button.
+ */
+ back_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&back_info);
+ break;
+ }
+ if (MatteIsActive(reset_info,event.xbutton))
+ {
+ /*
+ User pressed Reset button.
+ */
+ reset_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&reset_info);
+ break;
+ }
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ /*
+ User pressed action button.
+ */
+ action_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ /*
+ User pressed Cancel button.
+ */
+ cancel_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ if (!MatteIsActive(reply_info,event.xbutton))
+ break;
+ if (event.xbutton.button != Button2)
+ {
+ static Time
+ click_time;
+
+ /*
+ Move text cursor to position of button press.
+ */
+ x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
+ for (i=1; i <= Extent(reply_info.marker); i++)
+ if (XTextWidth(font_info,reply_info.marker,i) > x)
+ break;
+ reply_info.cursor=reply_info.marker+i-1;
+ if (event.xbutton.time > (click_time+DoubleClick))
+ reply_info.highlight=False;
+ else
+ {
+ /*
+ Become the XA_PRIMARY selection owner.
+ */
+ (void) strlcpy(primary_selection,reply_info.text,
+ MaxTextExtent);
+ (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
+ event.xbutton.time);
+ reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
+ windows->widget.id;
+ }
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ click_time=event.xbutton.time;
+ break;
+ }
+ /*
+ Request primary selection.
+ */
+ (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
+ windows->widget.id,event.xbutton.time);
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (!north_info.raised)
+ {
+ /*
+ User released up button.
+ */
+ delay=SuspendTime << 2;
+ north_info.raised=True;
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ }
+ if (!south_info.raised)
+ {
+ /*
+ User released down button.
+ */
+ delay=SuspendTime << 2;
+ south_info.raised=True;
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ }
+ if (slider_info.active)
+ {
+ /*
+ Stop tracking slider.
+ */
+ slider_info.active=False;
+ break;
+ }
+ if (!back_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(back_info,event.xbutton))
+ {
+ (void) strlcpy(glob_pattern,back_pattern,MaxTextExtent);
+ state|=UpdateListState;
+ }
+ back_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&back_info);
+ }
+ if (!reset_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(reset_info,event.xbutton))
+ {
+ (void) strlcpy(back_pattern,glob_pattern,MaxTextExtent);
+ (void) strlcpy(glob_pattern,reset_pattern,MaxTextExtent);
+ state|=UpdateListState;
+ }
+ reset_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&reset_info);
+ }
+ if (!action_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ {
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ if (*reply_info.text == '\0')
+ (void) XBell(display,0);
+ else
+ state|=ExitState;
+ }
+ }
+ action_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ }
+ if (!cancel_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ }
+ cancel_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == windows->widget.id)
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static int
+ length;
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if (AreaIsActive(scroll_info,event.xkey))
+ {
+ /*
+ Move slider.
+ */
+ switch ((int) key_symbol)
+ {
+ case XK_Home:
+ case XK_KP_Home:
+ {
+ slider_info.id=0;
+ break;
+ }
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ slider_info.id--;
+ break;
+ }
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ slider_info.id++;
+ break;
+ }
+ case XK_Prior:
+ case XK_KP_Prior:
+ {
+ slider_info.id-=visible_fonts;
+ break;
+ }
+ case XK_Next:
+ case XK_KP_Next:
+ {
+ slider_info.id+=visible_fonts;
+ break;
+ }
+ case XK_End:
+ case XK_KP_End:
+ {
+ slider_info.id=fonts;
+ break;
+ }
+ }
+ state|=RedrawListState;
+ break;
+ }
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ /*
+ Read new font or glob patterm.
+ */
+ if (*reply_info.text == '\0')
+ break;
+ (void) strlcpy(back_pattern,glob_pattern,MaxTextExtent);
+ (void) strlcpy(glob_pattern,reply_info.text,MaxTextExtent);
+ state|=UpdateListState;
+ break;
+ }
+ if (key_symbol == XK_Control_L)
+ {
+ state|=ControlState;
+ break;
+ }
+ if (state & ControlState)
+ switch ((int) key_symbol)
+ {
+ case XK_u:
+ case XK_U:
+ {
+ /*
+ Erase the entire line of text.
+ */
+ *reply_info.text='\0';
+ reply_info.cursor=reply_info.text;
+ reply_info.marker=reply_info.text;
+ reply_info.highlight=False;
+ break;
+ }
+ default:
+ break;
+ }
+ XEditText(display,&reply_info,key_symbol,command,state);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=JumpListState;
+ break;
+ }
+ case KeyRelease:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key release.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if (key_symbol == XK_Control_L)
+ state&=(~ControlState);
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MapNotify:
+ {
+ mask&=(~CWX);
+ mask&=(~CWY);
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (slider_info.active)
+ {
+ /*
+ Move slider matte.
+ */
+ slider_info.y=event.xmotion.y-
+ ((slider_info.height+slider_info.bevel_width) >> 1)+1;
+ if (slider_info.y < slider_info.min_y)
+ slider_info.y=slider_info.min_y;
+ if (slider_info.y > slider_info.max_y)
+ slider_info.y=slider_info.max_y;
+ slider_info.id=0;
+ if (slider_info.y != slider_info.min_y)
+ slider_info.id=(fonts*(slider_info.y-slider_info.min_y+1))/
+ (slider_info.max_y-slider_info.min_y+1);
+ state|=RedrawListState;
+ break;
+ }
+ if (state & InactiveWidgetState)
+ break;
+ if (back_info.raised == MatteIsActive(back_info,event.xmotion))
+ {
+ /*
+ Back button status changed.
+ */
+ back_info.raised=!back_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&back_info);
+ break;
+ }
+ if (reset_info.raised == MatteIsActive(reset_info,event.xmotion))
+ {
+ /*
+ Reset button status changed.
+ */
+ reset_info.raised=!reset_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&reset_info);
+ break;
+ }
+ if (action_info.raised == MatteIsActive(action_info,event.xmotion))
+ {
+ /*
+ Action button status changed.
+ */
+ action_info.raised=!action_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&action_info);
+ break;
+ }
+ if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
+ {
+ /*
+ Cancel button status changed.
+ */
+ cancel_info.raised=!cancel_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ break;
+ }
+ case SelectionClear:
+ {
+ reply_info.highlight=False;
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ break;
+ }
+ case SelectionNotify:
+ {
+ Atom
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ Obtain response from primary selection.
+ */
+ if (event.xselection.property == (Atom) None)
+ break;
+ status=XGetWindowProperty(display,event.xselection.requestor,
+ event.xselection.property,0L,2047L,True,XA_STRING,&type,&format,
+ &length,&after,&data);
+ if ((status != Success) || (type != XA_STRING) || (format == 32) ||
+ (length == 0))
+ break;
+ if ((Extent(reply_info.text)+length) >= MaxTextExtent)
+ (void) XBell(display,0);
+ else
+ {
+ /*
+ Insert primary selection in reply text.
+ */
+ *(data+length)='\0';
+ XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
+ state);
+ XDrawMatteText(display,&windows->widget,&reply_info);
+ state|=JumpListState;
+ state|=RedrawActionState;
+ }
+ (void) XFree((void *) data);
+ break;
+ }
+ case SelectionRequest:
+ {
+ XSelectionEvent
+ notify;
+
+ XSelectionRequestEvent
+ *request;
+
+ /*
+ Set XA_PRIMARY selection.
+ */
+ request=(&(event.xselectionrequest));
+ (void) XChangeProperty(request->display,request->requestor,
+ request->property,request->target,8,PropModeReplace,
+ (unsigned char *) primary_selection,Extent(primary_selection));
+ notify.type=SelectionNotify;
+ notify.display=request->display;
+ notify.requestor=request->requestor;
+ notify.selection=request->selection;
+ notify.target=request->target;
+ notify.time=request->time;
+ if (request->property == None)
+ notify.property=request->target;
+ else
+ notify.property=request->property;
+ (void) XSendEvent(request->display,request->requestor,False,0,
+ (XEvent *) &notify);
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+ /*
+ Free font list.
+ */
+ (void) XFreeFontNames(listhead);
+ MagickFreeMemory(fontlist);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X I n f o W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXInfoWidget displays text in the Info widget. The purpose is to
+% inform the user that what activity is currently being performed (e.g.
+% reading an image, rotating an image, etc.).
+%
+% The format of the MagickXInfoWidget method is:
+%
+% void MagickXInfoWidget(Display *display,MagickXWindows *windows,const char *activity)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o activity: This character string reflects the current activity and is
+% displayed in the Info widget.
+%
+%
+*/
+MagickExport void MagickXInfoWidget(Display *display,MagickXWindows *windows,
+ const char *activity)
+{
+ int
+ height,
+ width;
+
+ unsigned int
+ margin;
+
+ XFontStruct
+ *font_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Map Info widget.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(activity != (char *) NULL);
+ font_info=windows->info.font_info;
+ width=XTextWidth(font_info,(char *) activity,Extent(activity))+
+ ((3*QuantumMargin) >> 1)+4;
+ height=((6*(font_info->ascent+font_info->descent)) >> 2)+4;
+ if (((int) windows->info.width != width) ||
+ ((int) windows->info.height != height))
+ {
+ /*
+ Size Info widget to accommodate the activity text.
+ */
+ windows->info.width=width;
+ windows->info.height=height;
+ window_changes.width=width;
+ window_changes.height=height;
+ (void) XReconfigureWMWindow(display,windows->info.id,windows->info.screen,
+ CWWidth | CWHeight,&window_changes);
+ }
+ if (!windows->info.mapped)
+ {
+ (void) XMapRaised(display,windows->info.id);
+ windows->info.mapped=True;
+ }
+ /*
+ Initialize Info matte information.
+ */
+ height=font_info->ascent+font_info->descent;
+ XGetWidgetInfo(activity,&monitor_info);
+ monitor_info.bevel_width--;
+ margin=monitor_info.bevel_width+((windows->info.height-height) >> 1)-2;
+ monitor_info.center=False;
+ monitor_info.x=margin;
+ monitor_info.y=margin;
+ monitor_info.width=windows->info.width-(margin << 1);
+ monitor_info.height=windows->info.height-(margin << 1)+1;
+ /*
+ Draw Info widget.
+ */
+ monitor_info.raised=False;
+ XDrawBeveledMatte(display,&windows->info,&monitor_info);
+ monitor_info.raised=True;
+ XDrawWidgetText(display,&windows->info,&monitor_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X L i s t B r o w s e r W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXListBrowserWidget displays a List Browser widget with a query to
+% the user. The user keys a reply or select a reply from the list. Finally,
+% the user presses the Action or Cancel button to exit. The typed text is
+% returned as the reply function parameter.
+%
+% The format of the MagickXListBrowserWidget method is:
+%
+% void MagickXListBrowserWidget(Display *display,MagickXWindows *windows,
+% MagickXWindowInfo *window_info,const char **list,const char *action,
+% const char *query,char *reply)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o list: Specifies a pointer to an array of strings. The user can
+% select from these strings as a possible reply value.
+%
+% o action: Specifies a pointer to the action of this widget.
+%
+% o query: Specifies a pointer to the query to present to the user.
+%
+% o reply: The response from the user is returned in this parameter.
+%
+%
+*/
+MagickExport void MagickXListBrowserWidget(Display *display,MagickXWindows *windows,
+ MagickXWindowInfo *window_info,const char **list,const char *action,
+ const char *query,char *reply)
+{
+#define CancelButtonText "Cancel"
+
+ char
+ primary_selection[MaxTextExtent];
+
+ int
+ entries,
+ height,
+ status,
+ text_width,
+ width,
+ x;
+
+ static char
+ mask = CWWidth | CWHeight | CWX | CWY;
+
+ register int
+ i;
+
+ unsigned int
+ visible_entries;
+
+ unsigned long
+ delay,
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ action_info,
+ cancel_info,
+ expose_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ list_info,
+ north_info,
+ reply_info,
+ scroll_info,
+ selection_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ slider_info,
+ south_info,
+ text_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Count the number of entries in the list.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(window_info != (MagickXWindowInfo *) NULL);
+ assert(list != (const char **) NULL);
+ assert(action != (char *) NULL);
+ assert(query != (char *) NULL);
+ assert(reply != (char *) NULL);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ if (list == (const char **) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"No text to browse:",(char *) NULL);
+ return;
+ }
+ for (entries=0; ; entries++)
+ if (list[entries] == (char *) NULL)
+ break;
+ /*
+ Determine Font Browser widget attributes.
+ */
+ font_info=window_info->font_info;
+ text_width=XTextWidth(font_info,(char *) query,Extent(query));
+ for (i=0; i < entries; i++)
+ if (XTextWidth(font_info,(char *) list[i],Extent(list[i])) > text_width)
+ text_width=XTextWidth(font_info,(char *) list[i],Extent(list[i]));
+ width=XTextWidth(font_info,(char *) action,Extent(action));
+ if (XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)) > width)
+ width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText));
+ width+=QuantumMargin;
+ height=font_info->ascent+font_info->descent;
+ /*
+ Position List Browser widget.
+ */
+ window_info->width=Min(text_width,MaxTextWidth)+((9*QuantumMargin) >> 1);
+ window_info->min_width=MinTextWidth+4*QuantumMargin;
+ if (window_info->width < window_info->min_width)
+ window_info->width=window_info->min_width;
+ window_info->height=((81*height) >> 2)+((13*QuantumMargin) >> 1)+4;
+ window_info->min_height=((23*height) >> 1)+((13*QuantumMargin) >> 1)+4;
+ if (window_info->height < window_info->min_height)
+ window_info->height=window_info->min_height;
+ MagickXConstrainWindowPosition(display,window_info);
+ /*
+ Map List Browser widget.
+ */
+ (void) strcpy(window_info->name,"Browse");
+ status=XStringListToTextProperty(&window_info->name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,window_info->id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=window_info->width;
+ window_changes.height=window_info->height;
+ window_changes.x=window_info->x;
+ window_changes.y=window_info->y;
+ (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,mask,
+ &window_changes);
+ (void) XMapRaised(display,window_info->id);
+ window_info->mapped=False;
+ /*
+ Respond to X events.
+ */
+ XGetWidgetInfo((char *) NULL,&slider_info);
+ XGetWidgetInfo((char *) NULL,&north_info);
+ XGetWidgetInfo((char *) NULL,&south_info);
+ visible_entries=0;
+ delay=SuspendTime << 2;
+ state=UpdateConfigurationState;
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ int
+ id;
+
+ /*
+ Initialize button information.
+ */
+ XGetWidgetInfo(CancelButtonText,&cancel_info);
+ cancel_info.width=width;
+ cancel_info.height=(3*height) >> 1;
+ cancel_info.x=window_info->width-cancel_info.width-QuantumMargin-2;
+ cancel_info.y=window_info->height-cancel_info.height-QuantumMargin;
+ XGetWidgetInfo(action,&action_info);
+ action_info.width=width;
+ action_info.height=(3*height) >> 1;
+ action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
+ (action_info.bevel_width << 1));
+ action_info.y=cancel_info.y;
+ /*
+ Initialize reply information.
+ */
+ XGetWidgetInfo(reply,&reply_info);
+ reply_info.raised=False;
+ reply_info.bevel_width--;
+ reply_info.width=window_info->width-((4*QuantumMargin) >> 1);
+ reply_info.height=height << 1;
+ reply_info.x=QuantumMargin;
+ reply_info.y=action_info.y-reply_info.height-QuantumMargin;
+ /*
+ Initialize scroll information.
+ */
+ XGetWidgetInfo((char *) NULL,&scroll_info);
+ scroll_info.bevel_width--;
+ scroll_info.width=height;
+ scroll_info.height=reply_info.y-((6*QuantumMargin) >> 1)-height;
+ scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
+ scroll_info.y=((5*QuantumMargin) >> 1)+height-reply_info.bevel_width;
+ scroll_info.raised=False;
+ scroll_info.trough=True;
+ north_info=scroll_info;
+ north_info.raised=True;
+ north_info.width-=(north_info.bevel_width << 1);
+ north_info.height=north_info.width-1;
+ north_info.x+=north_info.bevel_width;
+ north_info.y+=north_info.bevel_width;
+ south_info=north_info;
+ south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
+ south_info.height;
+ id=slider_info.id;
+ slider_info=north_info;
+ slider_info.id=id;
+ slider_info.width-=2;
+ slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
+ slider_info.bevel_width+2;
+ slider_info.height=
+ scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+2;
+ visible_entries=
+ (scroll_info.height-(height >> 3)-3)/((9*height) >> 3);
+ if (entries > (int) visible_entries)
+ slider_info.height=(visible_entries*slider_info.height)/entries;
+ slider_info.max_y=south_info.y-south_info.bevel_width-
+ slider_info.bevel_width-2;
+ slider_info.x=scroll_info.x+slider_info.bevel_width+1;
+ slider_info.y=slider_info.min_y;
+ expose_info=scroll_info;
+ expose_info.y=slider_info.y;
+ /*
+ Initialize list information.
+ */
+ XGetWidgetInfo((char *) NULL,&list_info);
+ list_info.raised=False;
+ list_info.bevel_width--;
+ list_info.width=scroll_info.x-reply_info.x-(QuantumMargin >> 1);
+ list_info.height=scroll_info.height;
+ list_info.x=reply_info.x;
+ list_info.y=scroll_info.y;
+ if (!window_info->mapped)
+ for (i=0; i < entries; i++)
+ if (LocaleCompare(list[i],reply) == 0)
+ {
+ list_info.id=i;
+ slider_info.id=i-(visible_entries >> 1);
+ if (slider_info.id < 0)
+ slider_info.id=0;
+ }
+ /*
+ Initialize text information.
+ */
+ XGetWidgetInfo(query,&text_info);
+ text_info.width=reply_info.width;
+ text_info.height=height;
+ text_info.x=list_info.x-(QuantumMargin >> 1);
+ text_info.y=QuantumMargin;
+ /*
+ Initialize selection information.
+ */
+ XGetWidgetInfo((char *) NULL,&selection_info);
+ selection_info.center=False;
+ selection_info.width=list_info.width;
+ selection_info.height=(9*height) >> 3;
+ selection_info.x=list_info.x;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw List Browser window.
+ */
+ XDrawWidgetText(display,window_info,&text_info);
+ XDrawBeveledMatte(display,window_info,&list_info);
+ XDrawBeveledMatte(display,window_info,&scroll_info);
+ XDrawTriangleNorth(display,window_info,&north_info);
+ XDrawBeveledButton(display,window_info,&slider_info);
+ XDrawTriangleSouth(display,window_info,&south_info);
+ XDrawBeveledMatte(display,window_info,&reply_info);
+ XDrawMatteText(display,window_info,&reply_info);
+ XDrawBeveledButton(display,window_info,&action_info);
+ XDrawBeveledButton(display,window_info,&cancel_info);
+ XHighlightWidget(display,window_info,BorderOffset,BorderOffset);
+ selection_info.id=(~0);
+ state|=RedrawActionState;
+ state|=RedrawListState;
+ state&=(~RedrawWidgetState);
+ }
+ if (state & RedrawListState)
+ {
+ /*
+ Determine slider id and position.
+ */
+ if (slider_info.id >= (int) (entries-visible_entries))
+ slider_info.id=entries-visible_entries;
+ if ((slider_info.id < 0) || (entries <= (int) visible_entries))
+ slider_info.id=0;
+ slider_info.y=slider_info.min_y;
+ if (entries > 0)
+ slider_info.y+=
+ slider_info.id*(slider_info.max_y-slider_info.min_y+1)/entries;
+ if (slider_info.id != selection_info.id)
+ {
+ /*
+ Redraw scroll bar and file names.
+ */
+ selection_info.id=slider_info.id;
+ selection_info.y=list_info.y+(height >> 3)+2;
+ for (i=0; i < (int) visible_entries; i++)
+ {
+ selection_info.raised=(slider_info.id+i) != list_info.id;
+ selection_info.text=(char *) NULL;
+ if ((slider_info.id+i) < entries)
+ selection_info.text=(char *) list[slider_info.id+i];
+ XDrawWidgetText(display,window_info,&selection_info);
+ selection_info.y+=(int) selection_info.height;
+ }
+ /*
+ Update slider.
+ */
+ if (slider_info.y > expose_info.y)
+ {
+ expose_info.height=slider_info.y-expose_info.y;
+ expose_info.y=slider_info.y-expose_info.height-
+ slider_info.bevel_width-1;
+ }
+ else
+ {
+ expose_info.height=expose_info.y-slider_info.y;
+ expose_info.y=slider_info.y+slider_info.height+
+ slider_info.bevel_width+1;
+ }
+ XDrawTriangleNorth(display,window_info,&north_info);
+ XDrawMatte(display,window_info,&expose_info);
+ XDrawBeveledButton(display,window_info,&slider_info);
+ XDrawTriangleSouth(display,window_info,&south_info);
+ expose_info.y=slider_info.y;
+ }
+ state&=(~RedrawListState);
+ }
+ /*
+ Wait for next event.
+ */
+ if (north_info.raised && south_info.raised)
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ else
+ {
+ /*
+ Brief delay before advancing scroll bar.
+ */
+ MagickXDelay(display,delay);
+ delay=SuspendTime;
+ (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
+ if (!north_info.raised)
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ slider_info.id--;
+ state|=RedrawListState;
+ }
+ if (!south_info.raised)
+ if (slider_info.id < entries)
+ {
+ /*
+ Move slider down.
+ */
+ slider_info.id++;
+ state|=RedrawListState;
+ }
+ if (event.type != ButtonRelease)
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (MatteIsActive(slider_info,event.xbutton))
+ {
+ /*
+ Track slider.
+ */
+ slider_info.active=True;
+ break;
+ }
+ if (MatteIsActive(north_info,event.xbutton))
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ north_info.raised=False;
+ slider_info.id--;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(south_info,event.xbutton))
+ if (slider_info.id < entries)
+ {
+ /*
+ Move slider down.
+ */
+ south_info.raised=False;
+ slider_info.id++;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(scroll_info,event.xbutton))
+ {
+ /*
+ Move slider.
+ */
+ if (event.xbutton.y < slider_info.y)
+ slider_info.id-=(visible_entries-1);
+ else
+ slider_info.id+=(visible_entries-1);
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(list_info,event.xbutton))
+ {
+ unsigned int
+ id;
+
+ /*
+ User pressed list matte.
+ */
+ id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
+ selection_info.height;
+ if ((int) id >= entries)
+ break;
+ (void) strlcpy(reply_info.text,list[id],MaxTextExtent);
+ reply_info.highlight=False;
+ reply_info.marker=reply_info.text;
+ reply_info.cursor=reply_info.text+Extent(reply_info.text);
+ XDrawMatteText(display,window_info,&reply_info);
+ selection_info.id=(~0);
+ if ((int) id == list_info.id)
+ {
+ action_info.raised=False;
+ XDrawBeveledButton(display,window_info,&action_info);
+ state|=ExitState;
+ }
+ list_info.id=id;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ /*
+ User pressed action button.
+ */
+ action_info.raised=False;
+ XDrawBeveledButton(display,window_info,&action_info);
+ break;
+ }
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ /*
+ User pressed Cancel button.
+ */
+ cancel_info.raised=False;
+ XDrawBeveledButton(display,window_info,&cancel_info);
+ break;
+ }
+ if (!MatteIsActive(reply_info,event.xbutton))
+ break;
+ if (event.xbutton.button != Button2)
+ {
+ static Time
+ click_time;
+
+ /*
+ Move text cursor to position of button press.
+ */
+ x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
+ for (i=1; i <= Extent(reply_info.marker); i++)
+ if (XTextWidth(font_info,reply_info.marker,i) > x)
+ break;
+ reply_info.cursor=reply_info.marker+i-1;
+ if (event.xbutton.time > (click_time+DoubleClick))
+ reply_info.highlight=False;
+ else
+ {
+ /*
+ Become the XA_PRIMARY selection owner.
+ */
+ (void) strlcpy(primary_selection,reply_info.text,
+ MaxTextExtent);
+ (void) XSetSelectionOwner(display,XA_PRIMARY,window_info->id,
+ event.xbutton.time);
+ reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
+ window_info->id;
+ }
+ XDrawMatteText(display,window_info,&reply_info);
+ click_time=event.xbutton.time;
+ break;
+ }
+ /*
+ Request primary selection.
+ */
+ (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
+ window_info->id,event.xbutton.time);
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!window_info->mapped)
+ break;
+ if (!north_info.raised)
+ {
+ /*
+ User released up button.
+ */
+ delay=SuspendTime << 2;
+ north_info.raised=True;
+ XDrawTriangleNorth(display,window_info,&north_info);
+ }
+ if (!south_info.raised)
+ {
+ /*
+ User released down button.
+ */
+ delay=SuspendTime << 2;
+ south_info.raised=True;
+ XDrawTriangleSouth(display,window_info,&south_info);
+ }
+ if (slider_info.active)
+ {
+ /*
+ Stop tracking slider.
+ */
+ slider_info.active=False;
+ break;
+ }
+ if (!action_info.raised)
+ {
+ if (event.xbutton.window == window_info->id)
+ {
+ if (MatteIsActive(action_info,event.xbutton))
+ {
+ if (*reply_info.text == '\0')
+ (void) XBell(display,0);
+ else
+ state|=ExitState;
+ }
+ }
+ action_info.raised=True;
+ XDrawBeveledButton(display,window_info,&action_info);
+ }
+ if (!cancel_info.raised)
+ {
+ if (event.xbutton.window == window_info->id)
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ }
+ cancel_info.raised=True;
+ XDrawBeveledButton(display,window_info,&cancel_info);
+ }
+ /* if (!MatteIsActive(reply_info,event.xbutton)) */
+ /* break; */
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == window_info->id)
+ {
+ *reply_info.text='\0';
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != window_info->id)
+ break;
+ if ((event.xconfigure.width == (int) window_info->width) &&
+ (event.xconfigure.height == (int) window_info->height))
+ break;
+ window_info->width=
+ Max(event.xconfigure.width,(int) window_info->min_width);
+ window_info->height=
+ Max(event.xconfigure.height,(int) window_info->min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != window_info->id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != window_info->id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static int
+ length;
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != window_info->id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if (AreaIsActive(scroll_info,event.xkey))
+ {
+ /*
+ Move slider.
+ */
+ switch ((int) key_symbol)
+ {
+ case XK_Home:
+ case XK_KP_Home:
+ {
+ slider_info.id=0;
+ break;
+ }
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ slider_info.id--;
+ break;
+ }
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ slider_info.id++;
+ break;
+ }
+ case XK_Prior:
+ case XK_KP_Prior:
+ {
+ slider_info.id-=visible_entries;
+ break;
+ }
+ case XK_Next:
+ case XK_KP_Next:
+ {
+ slider_info.id+=visible_entries;
+ break;
+ }
+ case XK_End:
+ case XK_KP_End:
+ {
+ slider_info.id=entries;
+ break;
+ }
+ }
+ state|=RedrawListState;
+ break;
+ }
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ /*
+ Read new entry.
+ */
+ if (*reply_info.text == '\0')
+ break;
+ action_info.raised=False;
+ XDrawBeveledButton(display,window_info,&action_info);
+ state|=ExitState;
+ break;
+ }
+ if (key_symbol == XK_Control_L)
+ {
+ state|=ControlState;
+ break;
+ }
+ if (state & ControlState)
+ switch ((int) key_symbol)
+ {
+ case XK_u:
+ case XK_U:
+ {
+ /*
+ Erase the entire line of text.
+ */
+ *reply_info.text='\0';
+ reply_info.cursor=reply_info.text;
+ reply_info.marker=reply_info.text;
+ reply_info.highlight=False;
+ break;
+ }
+ default:
+ break;
+ }
+ XEditText(display,&reply_info,key_symbol,command,state);
+ XDrawMatteText(display,window_info,&reply_info);
+ break;
+ }
+ case KeyRelease:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != window_info->id)
+ break;
+ /*
+ Respond to a user key release.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if (key_symbol == XK_Control_L)
+ state&=(~ControlState);
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != window_info->id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MapNotify:
+ {
+ mask&=(~CWX);
+ mask&=(~CWY);
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (slider_info.active)
+ {
+ /*
+ Move slider matte.
+ */
+ slider_info.y=event.xmotion.y-
+ ((slider_info.height+slider_info.bevel_width) >> 1)+1;
+ if (slider_info.y < slider_info.min_y)
+ slider_info.y=slider_info.min_y;
+ if (slider_info.y > slider_info.max_y)
+ slider_info.y=slider_info.max_y;
+ slider_info.id=0;
+ if (slider_info.y != slider_info.min_y)
+ slider_info.id=(entries*(slider_info.y-slider_info.min_y+1))/
+ (slider_info.max_y-slider_info.min_y+1);
+ state|=RedrawListState;
+ break;
+ }
+ if (state & InactiveWidgetState)
+ break;
+ if (action_info.raised == MatteIsActive(action_info,event.xmotion))
+ {
+ /*
+ Action button status changed.
+ */
+ action_info.raised=!action_info.raised;
+ XDrawBeveledButton(display,window_info,&action_info);
+ break;
+ }
+ if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
+ {
+ /*
+ Cancel button status changed.
+ */
+ cancel_info.raised=!cancel_info.raised;
+ XDrawBeveledButton(display,window_info,&cancel_info);
+ break;
+ }
+ break;
+ }
+ case SelectionClear:
+ {
+ reply_info.highlight=False;
+ XDrawMatteText(display,window_info,&reply_info);
+ break;
+ }
+ case SelectionNotify:
+ {
+ Atom
+ type;
+
+ int
+ format;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ Obtain response from primary selection.
+ */
+ if (event.xselection.property == (Atom) None)
+ break;
+ status=XGetWindowProperty(display,event.xselection.requestor,
+ event.xselection.property,0L,2047L,True,XA_STRING,&type,&format,
+ &length,&after,&data);
+ if ((status != Success) || (type != XA_STRING) || (format == 32) ||
+ (length == 0))
+ break;
+ if ((Extent(reply_info.text)+length) >= MaxTextExtent)
+ (void) XBell(display,0);
+ else
+ {
+ /*
+ Insert primary selection in reply text.
+ */
+ *(data+length)='\0';
+ XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
+ state);
+ XDrawMatteText(display,window_info,&reply_info);
+ state|=RedrawActionState;
+ }
+ (void) XFree((void *) data);
+ break;
+ }
+ case SelectionRequest:
+ {
+ XSelectionEvent
+ notify;
+
+ XSelectionRequestEvent
+ *request;
+
+ if (!reply_info.highlight)
+ break;
+ /*
+ Set primary selection.
+ */
+ request=(&(event.xselectionrequest));
+ (void) XChangeProperty(request->display,request->requestor,
+ request->property,request->target,8,PropModeReplace,
+ (unsigned char *) primary_selection,Extent(primary_selection));
+ notify.type=SelectionNotify;
+ notify.send_event=True;
+ notify.display=request->display;
+ notify.requestor=request->requestor;
+ notify.selection=request->selection;
+ notify.target=request->target;
+ notify.time=request->time;
+ if (request->property == None)
+ notify.property=request->target;
+ else
+ notify.property=request->property;
+ (void) XSendEvent(request->display,request->requestor,False,NoEventMask,
+ (XEvent *) &notify);
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,window_info->id,window_info->screen);
+ MagickXCheckRefreshWindows(display,windows);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X M e n u W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMenuWidget maps a menu and returns the command pointed to by the
+% user when the button is released.
+%
+% The format of the MagickXMenuWidget method is:
+%
+% int MagickXMenuWidget(Display *display,MagickXWindows *windows,const char *title,
+% const char **selections,char *item)
+%
+% A description of each parameter follows:
+%
+% o selection_number: Specifies the number of the selection that the
+% user choose.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o title: Specifies a character string that describes the menu selections.
+%
+% o selections: Specifies a pointer to one or more strings that comprise
+% the choices in the menu.
+%
+% o item: Specifies a character array. The item selected from the menu
+% is returned here.
+%
+%
+*/
+MagickExport int MagickXMenuWidget(Display *display,MagickXWindows *windows,
+ const char *title,const char **selections,char *item)
+{
+ Cursor
+ cursor;
+
+ int
+ height,
+ id,
+ width,
+ x,
+ y;
+
+ unsigned int
+ number_selections,
+ title_height,
+ top_offset;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XSetWindowAttributes
+ window_attributes;
+
+ MagickXWidgetInfo
+ highlight_info,
+ menu_info,
+ selection_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Determine Menu widget attributes.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(title != (char *) NULL);
+ assert(selections != (const char **) NULL);
+ assert(item != (char *) NULL);
+ font_info=windows->widget.font_info;
+ windows->widget.width=!submenu_info.active ?
+ XTextWidth(font_info,(char *) title,Extent(title)) : 0;
+ for (id=0; selections[id] != (char *) NULL; id++)
+ {
+ width=XTextWidth(font_info,(char *) selections[id],Extent(selections[id]));
+ if (width > (int) windows->widget.width)
+ windows->widget.width=width;
+ }
+ number_selections=id;
+ XGetWidgetInfo((char *) NULL,&menu_info);
+ title_height=!submenu_info.active ?
+ (3*(font_info->descent+font_info->ascent) >> 1)+5 : 2;
+ width=XTextWidth(font_info,(char *) title,Extent(title));
+ height=(3*(font_info->ascent+font_info->descent)) >> 1;
+ /*
+ Position Menu widget.
+ */
+ windows->widget.width+=QuantumMargin+(menu_info.bevel_width << 1);
+ top_offset=title_height+menu_info.bevel_width-1;
+ windows->widget.height=top_offset+number_selections*height+4;
+ windows->widget.min_width=windows->widget.width;
+ windows->widget.min_height=windows->widget.height;
+ MagickXQueryPosition(display,windows->widget.root,&x,&y);
+ windows->widget.x=x-(QuantumMargin >> 1);
+ if (submenu_info.active)
+ {
+ windows->widget.x=
+ windows->command.x+windows->command.width-QuantumMargin;
+ toggle_info.raised=True;
+ XDrawTriangleEast(display,&windows->command,&toggle_info);
+ }
+ windows->widget.y=(!submenu_info.active ? ((int) (y-((3*title_height) >> 2))) : y);
+ if (submenu_info.active)
+ windows->widget.y=windows->command.y+submenu_info.y;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map Menu widget.
+ */
+ window_attributes.override_redirect=True;
+ (void) XChangeWindowAttributes(display,windows->widget.id,CWOverrideRedirect,
+ &window_attributes);
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
+ CWWidth | CWHeight | CWX | CWY,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ /*
+ Respond to X events.
+ */
+ selection_info.height=height;
+ cursor=XCreateFontCursor(display,XC_right_ptr);
+ (void) XDefineCursor(display,windows->image.id,cursor);
+ (void) XDefineCursor(display,windows->command.id,cursor);
+ (void) XDefineCursor(display,windows->widget.id,cursor);
+ state=UpdateConfigurationState;
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ /*
+ Initialize selection information.
+ */
+ XGetWidgetInfo((char *) NULL,&menu_info);
+ menu_info.bevel_width--;
+ menu_info.width=windows->widget.width-((menu_info.bevel_width) << 1);
+ menu_info.height=windows->widget.height-((menu_info.bevel_width) << 1);
+ menu_info.x=menu_info.bevel_width;
+ menu_info.y=menu_info.bevel_width;
+ XGetWidgetInfo((char *) NULL,&selection_info);
+ selection_info.center=False;
+ selection_info.width=menu_info.width;
+ selection_info.height=height;
+ selection_info.x=menu_info.x;
+ highlight_info=selection_info;
+ highlight_info.bevel_width--;
+ highlight_info.width-=(highlight_info.bevel_width << 1);
+ highlight_info.height-=(highlight_info.bevel_width << 1);
+ highlight_info.x+=highlight_info.bevel_width;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw Menu widget.
+ */
+ if (!submenu_info.active)
+ {
+ y=title_height;
+ XSetBevelColor(display,&windows->widget,False);
+ (void) XDrawLine(display,windows->widget.id,
+ windows->widget.widget_context,selection_info.x,y-1,
+ (int) selection_info.width,y-1);
+ XSetBevelColor(display,&windows->widget,True);
+ (void) XDrawLine(display,windows->widget.id,
+ windows->widget.widget_context,selection_info.x,y,
+ (int) selection_info.width,y);
+ (void) XSetFillStyle(display,windows->widget.widget_context,
+ FillSolid);
+ }
+ /*
+ Draw menu selections.
+ */
+ selection_info.center=True;
+ selection_info.y=menu_info.bevel_width;
+ selection_info.text=(char *) title;
+ if (!submenu_info.active)
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ selection_info.center=False;
+ selection_info.y=top_offset;
+ for (id=0; id < (int) number_selections; id++)
+ {
+ selection_info.text=(char *) selections[id];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ highlight_info.y=selection_info.y+highlight_info.bevel_width;
+ if (id == selection_info.id)
+ XDrawBevel(display,&windows->widget,&highlight_info);
+ selection_info.y+=(int) selection_info.height;
+ }
+ XDrawBevel(display,&windows->widget,&menu_info);
+ state&=(~RedrawWidgetState);
+ }
+ if (number_selections > 2)
+ {
+ /*
+ Redraw Menu line.
+ */
+ y=top_offset+selection_info.height*(number_selections-1);
+ XSetBevelColor(display,&windows->widget,False);
+ (void) XDrawLine(display,windows->widget.id,
+ windows->widget.widget_context,selection_info.x,y-1,
+ (int) selection_info.width,y-1);
+ XSetBevelColor(display,&windows->widget,True);
+ (void) XDrawLine(display,windows->widget.id,
+ windows->widget.widget_context,selection_info.x,y,
+ (int) selection_info.width,y);
+ (void) XSetFillStyle(display,windows->widget.widget_context,FillSolid);
+ }
+ /*
+ Wait for next event.
+ */
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (event.xbutton.window != windows->widget.id)
+ {
+ /*
+ Exit menu.
+ */
+ if (event.xbutton.window == windows->command.id)
+ (void) XPutBackEvent(display,&event);
+ selection_info.id=(~0);
+ *item='\0';
+ state|=ExitState;
+ break;
+ }
+ state&=(~InactiveWidgetState);
+ id=(event.xbutton.y-top_offset)/(int) selection_info.height;
+ selection_info.id=id;
+ if ((id < 0) || (id >= (int) number_selections))
+ break;
+ /*
+ Highlight this selection.
+ */
+ selection_info.y=top_offset+id*selection_info.height;
+ selection_info.text=(char *) selections[id];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ highlight_info.y=selection_info.y+highlight_info.bevel_width;
+ XDrawBevel(display,&windows->widget,&highlight_info);
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (event.xbutton.window == windows->command.id)
+ if (!(state & InactiveWidgetState))
+ break;
+ /*
+ Exit menu.
+ */
+ MagickXSetCursorState(display,windows,False);
+ *item='\0';
+ state|=ExitState;
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ if (event.xcrossing.state == 0)
+ break;
+ state&=(~InactiveWidgetState);
+ id=((event.xcrossing.y-top_offset)/(int) selection_info.height);
+ if ((selection_info.id >= 0) &&
+ (selection_info.id < (int) number_selections))
+ {
+ /*
+ Unhighlight last selection.
+ */
+ if (id == selection_info.id)
+ break;
+ selection_info.y=
+ top_offset+selection_info.id*selection_info.height;
+ selection_info.text=(char *) selections[selection_info.id];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ }
+ if ((id < 0) || (id >= (int) number_selections))
+ break;
+ /*
+ Highlight this selection.
+ */
+ selection_info.id=id;
+ selection_info.y=top_offset+selection_info.id*selection_info.height;
+ selection_info.text=(char *) selections[selection_info.id];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ highlight_info.y=selection_info.y+highlight_info.bevel_width;
+ XDrawBevel(display,&windows->widget,&highlight_info);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ id=selection_info.id;
+ if ((id < 0) || (id >= (int) number_selections))
+ break;
+ /*
+ Unhighlight last selection.
+ */
+ selection_info.y=top_offset+id*selection_info.height;
+ selection_info.id=(~0);
+ selection_info.text=(char *) selections[id];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (submenu_info.active)
+ if (event.xmotion.window == windows->command.id)
+ {
+ if (!(state & InactiveWidgetState))
+ {
+ if (!MatteIsActive(submenu_info,event.xmotion))
+ {
+ selection_info.id=(~0);
+ *item='\0';
+ state|=ExitState;
+ break;
+ }
+ }
+ else
+ if (WindowIsActive(windows->command,event.xmotion))
+ {
+ selection_info.id=(~0);
+ *item='\0';
+ state|=ExitState;
+ break;
+ }
+ }
+ if (event.xmotion.window != windows->widget.id)
+ break;
+ if (state & InactiveWidgetState)
+ break;
+ id=(event.xmotion.y-top_offset)/(int) selection_info.height;
+ if ((selection_info.id >= 0) &&
+ (selection_info.id < (int) number_selections))
+ {
+ /*
+ Unhighlight last selection.
+ */
+ if (id == selection_info.id)
+ break;
+ selection_info.y=
+ top_offset+selection_info.id*selection_info.height;
+ selection_info.text=(char *) selections[selection_info.id];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ }
+ selection_info.id=id;
+ if ((id < 0) || (id >= (int) number_selections))
+ break;
+ /*
+ Highlight this selection.
+ */
+ selection_info.y=top_offset+id*selection_info.height;
+ selection_info.text=(char *) selections[id];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ highlight_info.y=selection_info.y+highlight_info.bevel_width;
+ XDrawBevel(display,&windows->widget,&highlight_info);
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ (void) XFreeCursor(display,cursor);
+ window_attributes.override_redirect=False;
+ (void) XChangeWindowAttributes(display,windows->widget.id,CWOverrideRedirect,
+ &window_attributes);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+ if (submenu_info.active)
+ {
+ submenu_info.active=False;
+ toggle_info.raised=False;
+ XDrawTriangleEast(display,&windows->command,&toggle_info);
+ }
+ if ((selection_info.id < 0) || (selection_info.id >= (int) number_selections))
+ return(~0);
+ (void) strlcpy(item,selections[selection_info.id],MaxTextExtent);
+ return(selection_info.id);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X M o n i t o r W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMonitorWidget displays the progress a task is making in
+% completing a task. A span of zero toggles the active status. An inactive
+% state disables the progress monitor.
+%
+% The format of the MagickXMonitorWidget method is:
+%
+% void MagickXMonitorWidget(Display *display,MagickXWindows *windows,const char *task,
+% const magick_int64_t quantum,
+% const magick_uint64_t span)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o task: Identifies the task in progress.
+%
+% o quantum: Specifies the quantum position within the span which represents
+% how much progress has been made in completing a task.
+%
+% o span: Specifies the span relative to completing a task.
+%
+%
+*/
+MagickExport void MagickXMonitorWidget(Display *display,MagickXWindows *windows,
+ const char *task,const magick_int64_t quantum,
+ const magick_uint64_t span)
+{
+ unsigned int
+ width;
+
+ XEvent
+ event;
+
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(task != (const char *) NULL);
+ if (span == 0)
+ return;
+ /*
+ Update image windows if there is a pending expose event.
+ */
+ while (XCheckTypedWindowEvent(display,windows->command.id,Expose,&event))
+ (void) MagickXCommandWidget(display,windows,(const char **) NULL,&event);
+ while (XCheckTypedWindowEvent(display,windows->image.id,Expose,&event))
+ MagickXRefreshWindow(display,&windows->image,&event);
+ while (XCheckTypedWindowEvent(display,windows->info.id,Expose,&event))
+ if (monitor_info.text != (char *) NULL)
+ MagickXInfoWidget(display,windows,monitor_info.text);
+ /*
+ Draw progress monitor bar to represent percent completion of a task.
+ */
+ if (!windows->info.mapped || (task != monitor_info.text))
+ MagickXInfoWidget(display,windows,task);
+ width=(unsigned int) (((quantum+1)*(windows->info.width-
+ (2*monitor_info.x)))/span);
+ if (width < monitor_info.width)
+ {
+ monitor_info.raised=True;
+ XDrawWidgetText(display,&windows->info,&monitor_info);
+ monitor_info.raised=False;
+ }
+ monitor_info.width=width;
+ XDrawWidgetText(display,&windows->info,&monitor_info);
+ (void) XFlush(display);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X N o t i c e W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXNoticeWidget displays a Notice widget with a notice to the user.
+% The function returns when the user presses the "Dismiss" button.
+%
+% The format of the MagickXNoticeWidget method is:
+%
+% void MagickXNoticeWidget(Display *display,MagickXWindows *windows,
+% const char *reason,const char *description)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o reason: Specifies the message to display before terminating the
+% program.
+%
+% o description: Specifies any description to the message.
+%
+%
+*/
+MagickExport void MagickXNoticeWidget(Display *display,MagickXWindows *windows,
+ const char *reason,const char *description)
+{
+#define DismissButtonText "Dismiss"
+#define Timeout 8
+
+ const char
+ *text;
+
+ int
+ status,
+ x,
+ y;
+
+ time_t
+ timer;
+
+ unsigned int
+ height,
+ width;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ dismiss_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Determine Notice widget attributes.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(reason != (char *) NULL);
+ MagickXDelay(display,SuspendTime << 3); /* avoid surpise with delay */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ font_info=windows->widget.font_info;
+ width=XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText));
+ text=GetLocaleExceptionMessage(XServerError,reason);
+ if (text != (char *) NULL)
+ if (XTextWidth(font_info,(char *) text,Extent(text)) > (int) width)
+ width=XTextWidth(font_info,(char *) text,Extent(text));
+ text=GetLocaleExceptionMessage(XServerError,description);
+ if (text != (char *) NULL)
+ if (XTextWidth(font_info,(char *) text,Extent(text)) >
+ (int) width)
+ width=XTextWidth(font_info,(char *) text,Extent(text));
+ height=(font_info->ascent+font_info->descent);
+ /*
+ Position Notice widget.
+ */
+ windows->widget.width=width+4*QuantumMargin;
+ windows->widget.min_width=width+QuantumMargin;
+ if (windows->widget.width < windows->widget.min_width)
+ windows->widget.width=windows->widget.min_width;
+ windows->widget.height=12*height;
+ windows->widget.min_height=7*height;
+ if (windows->widget.height < windows->widget.min_height)
+ windows->widget.height=windows->widget.min_height;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map Notice widget.
+ */
+ (void) strcpy(windows->widget.name,"Notice");
+ status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->widget.id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
+ CWWidth | CWHeight | CWX | CWY,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ (void) XBell(display,0);
+ /*
+ Respond to X events.
+ */
+ timer=time((time_t *) NULL)+Timeout;
+ state=UpdateConfigurationState;
+ do
+ {
+ if (time((time_t *) NULL) > timer)
+ break;
+ if (state & UpdateConfigurationState)
+ {
+ /*
+ Initialize Dismiss button information.
+ */
+ XGetWidgetInfo(DismissButtonText,&dismiss_info);
+ dismiss_info.width=QuantumMargin+
+ XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText));
+ dismiss_info.height=(3*height) >> 1;
+ dismiss_info.x=(windows->widget.width >> 1)-(dismiss_info.width >> 1);
+ dismiss_info.y=windows->widget.height-(dismiss_info.height << 1);
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw Notice widget.
+ */
+ width=XTextWidth(font_info,(char *) reason,Extent(reason));
+ x=(windows->widget.width >> 1)-(width >> 1);
+ y=(windows->widget.height >> 1)-(height << 1);
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,(char *) reason,Extent(reason));
+ if (description != (char *) NULL)
+ {
+ width=XTextWidth(font_info,(char *) description,
+ Extent(description));
+ x=(windows->widget.width >> 1)-(width >> 1);
+ y+=height;
+ (void) XDrawString(display,windows->widget.id,
+ windows->widget.annotate_context,x,y,(char *) description,
+ Extent(description));
+ }
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ state&=(~RedrawWidgetState);
+ }
+ /*
+ Wait for next event.
+ */
+ if (!XCheckIfEvent(display,&event,XScreenEvent,(char *) windows))
+ {
+ /*
+ Do not block if delay > 0.
+ */
+ MagickXDelay(display,SuspendTime << 2);
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (MatteIsActive(dismiss_info,event.xbutton))
+ {
+ /*
+ User pressed Dismiss button.
+ */
+ dismiss_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ break;
+ }
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (!dismiss_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(dismiss_info,event.xbutton))
+ state|=ExitState;
+ dismiss_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == windows->widget.id)
+ {
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ dismiss_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (state & InactiveWidgetState)
+ break;
+ if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
+ {
+ /*
+ Dismiss button status changed.
+ */
+ dismiss_info.raised=!dismiss_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X P r e f e r e n c e s W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXPreferencesWidget displays a Preferences widget with program
+% preferences. If the user presses the Apply button, the preferences are
+% stored in a configuration file in the users' home directory.
+%
+% The format of the MagickXPreferencesWidget method is:
+%
+% unsigned int MagickXPreferencesWidget(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+%
+*/
+MagickExport unsigned int MagickXPreferencesWidget(Display *display,
+ MagickXResourceInfo *resource_info,MagickXWindows *windows)
+{
+#define ApplyButtonText "Apply"
+#define CacheButtonText "%lu mega-bytes of memory in the undo edit cache "
+#define CancelButtonText "Cancel"
+#define NumberPreferences 7
+
+ static char
+ *Preferences[] =
+ {
+ (char *) "display image centered on a backdrop",
+ (char *) "confirm on program exit",
+ (char *) "correct image for display gamma",
+ (char *) "display warning messages",
+ (char *) "apply Floyd/Steinberg error diffusion to image",
+ (char *) "use a shared colormap for colormapped X visuals",
+ (char *) "display images as an X server pixmap"
+ };
+
+ char
+ cache[MaxTextExtent];
+
+ int
+ height,
+ status,
+ text_width,
+ width,
+ x,
+ y;
+
+ register int
+ i;
+
+ unsigned long
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ apply_info,
+ cache_info,
+ cancel_info,
+ preferences_info[NumberPreferences];
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Determine Preferences widget attributes.
+ */
+ assert(display != (Display *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ MagickXCheckRefreshWindows(display,windows);
+ font_info=windows->widget.font_info;
+ text_width=XTextWidth(font_info,CacheButtonText,Extent(CacheButtonText));
+ for (i=0; i < NumberPreferences; i++)
+ if (XTextWidth(font_info,Preferences[i],Extent(Preferences[i])) > text_width)
+ text_width=XTextWidth(font_info,Preferences[i],Extent(Preferences[i]));
+ width=XTextWidth(font_info,ApplyButtonText,Extent(ApplyButtonText));
+ if (XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)) > width)
+ width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText));
+ width+=QuantumMargin;
+ height=(font_info->ascent+font_info->descent);
+ /*
+ Position Preferences widget.
+ */
+ windows->widget.width=Max((int) (width << 1),text_width)+6*QuantumMargin;
+ windows->widget.min_width=(width << 1)+QuantumMargin;
+ if (windows->widget.width < windows->widget.min_width)
+ windows->widget.width=windows->widget.min_width;
+ windows->widget.height=
+ 7*height+NumberPreferences*(height+(QuantumMargin >> 1));
+ windows->widget.min_height=
+ 7*height+NumberPreferences*(height+(QuantumMargin >> 1));
+ if (windows->widget.height < windows->widget.min_height)
+ windows->widget.height=windows->widget.min_height;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map Preferences widget.
+ */
+ (void) strcpy(windows->widget.name,"Preferences");
+ status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->widget.id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
+ CWWidth | CWHeight | CWX | CWY,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ /*
+ Respond to X events.
+ */
+ state=UpdateConfigurationState;
+ MagickXSetCursorState(display,windows,True);
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ /*
+ Initialize button information.
+ */
+ XGetWidgetInfo(CancelButtonText,&cancel_info);
+ cancel_info.width=width;
+ cancel_info.height=(3*height) >> 1;
+ cancel_info.x=windows->widget.width-cancel_info.width-
+ (QuantumMargin << 1);
+ cancel_info.y=windows->widget.height-cancel_info.height-QuantumMargin;
+ XGetWidgetInfo(ApplyButtonText,&apply_info);
+ apply_info.width=width;
+ apply_info.height=(3*height) >> 1;
+ apply_info.x=QuantumMargin << 1;
+ apply_info.y=cancel_info.y;
+ y=height << 1;
+ for (i=0; i < NumberPreferences; i++)
+ {
+ XGetWidgetInfo(Preferences[i],&preferences_info[i]);
+ preferences_info[i].bevel_width--;
+ preferences_info[i].width=QuantumMargin >> 1;
+ preferences_info[i].height=QuantumMargin >> 1;
+ preferences_info[i].x=QuantumMargin << 1;
+ preferences_info[i].y=y;
+ y+=height+(QuantumMargin >> 1);
+ }
+ preferences_info[0].raised=!resource_info->backdrop;
+ preferences_info[1].raised=!resource_info->confirm_exit;
+ preferences_info[2].raised=!resource_info->gamma_correct;
+ preferences_info[3].raised=!resource_info->display_warnings;
+ preferences_info[4].raised=!resource_info->quantize_info->dither;
+ preferences_info[5].raised=resource_info->colormap != SharedColormap;
+ preferences_info[6].raised=!resource_info->use_pixmap;
+ FormatString(cache,CacheButtonText,resource_info->undo_cache);
+ XGetWidgetInfo(cache,&cache_info);
+ cache_info.bevel_width--;
+ cache_info.width=QuantumMargin >> 1;
+ cache_info.height=QuantumMargin >> 1;
+ cache_info.x=QuantumMargin << 1;
+ cache_info.y=y;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw Preferences widget.
+ */
+ XDrawBeveledButton(display,&windows->widget,&apply_info);
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ for (i=0; i < NumberPreferences; i++)
+ XDrawBeveledButton(display,&windows->widget,&preferences_info[i]);
+ XDrawTriangleEast(display,&windows->widget,&cache_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ state&=(~RedrawWidgetState);
+ }
+ /*
+ Wait for next event.
+ */
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (MatteIsActive(apply_info,event.xbutton))
+ {
+ /*
+ User pressed Apply button.
+ */
+ apply_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&apply_info);
+ break;
+ }
+ if (MatteIsActive(cancel_info,event.xbutton))
+ {
+ /*
+ User pressed Cancel button.
+ */
+ cancel_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ for (i=0; i < NumberPreferences; i++)
+ if (MatteIsActive(preferences_info[i],event.xbutton))
+ {
+ /*
+ User pressed a Preferences button.
+ */
+ preferences_info[i].raised=!preferences_info[i].raised;
+ XDrawBeveledButton(display,&windows->widget,&preferences_info[i]);
+ break;
+ }
+ if (MatteIsActive(cache_info,event.xbutton))
+ {
+ /*
+ User pressed Cache button.
+ */
+ x=cache_info.x+cache_info.width+cache_info.bevel_width+
+ (QuantumMargin >> 1);
+ y=cache_info.y+((cache_info.height-height) >> 1);
+ width=XTextWidth(font_info,cache,Extent(cache));
+ (void) XClearArea(display,windows->widget.id,x,y,width,height,
+ False);
+ resource_info->undo_cache<<=1;
+ if (resource_info->undo_cache > 256)
+ resource_info->undo_cache=1;
+ FormatString(cache,CacheButtonText,resource_info->undo_cache);
+ cache_info.raised=False;
+ XDrawTriangleEast(display,&windows->widget,&cache_info);
+ break;
+ }
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (!apply_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(apply_info,event.xbutton))
+ state|=ExitState;
+ apply_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&apply_info);
+ apply_info.raised=False;
+ }
+ if (!cancel_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(cancel_info,event.xbutton))
+ state|=ExitState;
+ cancel_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ }
+ if (!cache_info.raised)
+ {
+ cache_info.raised=True;
+ XDrawTriangleEast(display,&windows->widget,&cache_info);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == windows->widget.id)
+ {
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ apply_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&apply_info);
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (state & InactiveWidgetState)
+ break;
+ if (apply_info.raised == MatteIsActive(apply_info,event.xmotion))
+ {
+ /*
+ Apply button status changed.
+ */
+ apply_info.raised=!apply_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&apply_info);
+ break;
+ }
+ if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
+ {
+ /*
+ Cancel button status changed.
+ */
+ cancel_info.raised=!cancel_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&cancel_info);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+ if (apply_info.raised)
+ return(False);
+ /*
+ Save user preferences to the client configuration file.
+ */
+ resource_info->backdrop=!preferences_info[0].raised;
+ resource_info->confirm_exit=!preferences_info[1].raised;
+ resource_info->gamma_correct=!preferences_info[2].raised;
+ resource_info->display_warnings=!preferences_info[3].raised;
+ resource_info->quantize_info->dither=!preferences_info[4].raised;
+ resource_info->colormap=SharedColormap;
+ if (preferences_info[5].raised)
+ resource_info->colormap=PrivateColormap;
+ resource_info->use_pixmap=!preferences_info[6].raised;
+ MagickXUserPreferences(resource_info);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X T e x t V i e w W i d g e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXTextViewWidget displays text in a Text View widget.
+%
+% The format of the MagickXTextViewWidget method is:
+%
+% void MagickXTextViewWidget(Display *display,const MagickXResourceInfo *resource_info,
+% MagickXWindows *windows,const unsigned int mono,const char *title,
+% const char **textlist)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o window: Specifies a pointer to a MagickXWindows structure.
+%
+% o mono: Use mono-spaced font when displaying text.
+%
+% o title: This character string is displayed at the top of the widget
+% window.
+%
+% o textlist: This string list is displayed within the Text View widget.
+%
+%
+*/
+MagickExport void MagickXTextViewWidget(Display *display,
+ const MagickXResourceInfo *resource_info,MagickXWindows *windows,const unsigned int mono,
+ const char *title,const char **textlist)
+{
+#define DismissButtonText "Dismiss"
+
+ char
+ primary_selection[MaxTextExtent];
+
+ int
+ status,
+ text_width;
+
+ register int
+ i;
+
+ static char
+ mask = CWWidth | CWHeight | CWX | CWY;
+
+ unsigned int
+ height,
+ lines,
+ visible_lines,
+ width;
+
+ unsigned long
+ delay,
+ state;
+
+ XEvent
+ event;
+
+ XFontStruct
+ *font_info,
+ *text_info;
+
+ XTextProperty
+ window_name;
+
+ MagickXWidgetInfo
+ dismiss_info,
+ expose_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ list_info,
+ north_info,
+ scroll_info,
+ selection_info =
+ {
+ (char *) NULL, (char *) NULL, (char *) NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ slider_info,
+ south_info;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Convert text string to a text list.
+ */
+ assert(display != (Display *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(title != (const char *) NULL);
+ assert(textlist != (const char **) NULL);
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ if (textlist == (const char **) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"No text to view:",(char *) NULL);
+ return;
+ }
+ /*
+ Determine Text View widget attributes.
+ */
+ font_info=windows->widget.font_info;
+ text_info=(XFontStruct *) NULL;
+ if (mono)
+ text_info=MagickXBestFont(display,resource_info,True);
+ if (text_info == (XFontStruct *) NULL)
+ text_info=windows->widget.font_info;
+ text_width=0;
+ for (i=0; textlist[i] != (char *) NULL; i++)
+ if (XTextWidth(text_info,(char *) textlist[i],Extent(textlist[i])) >
+ text_width)
+ text_width=XTextWidth(text_info,(char *) textlist[i],Extent(textlist[i]));
+ lines=i;
+ width=XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText));
+ width+=QuantumMargin;
+ height=text_info->ascent+text_info->descent;
+ /*
+ Position Text View widget.
+ */
+ windows->widget.width=Min((int) text_width,MaxTextWidth)+5*QuantumMargin;
+ windows->widget.min_width=MinTextWidth+4*QuantumMargin;
+ if (windows->widget.width < windows->widget.min_width)
+ windows->widget.width=windows->widget.min_width;
+ windows->widget.height=
+ Min(Max(lines,3),32)*height+((13*height) >> 1)+((9*QuantumMargin) >> 1);
+ windows->widget.min_height=
+ 3*height+((13*height) >> 1)+((9*QuantumMargin) >> 1);
+ if (windows->widget.height < windows->widget.min_height)
+ windows->widget.height=windows->widget.min_height;
+ MagickXConstrainWindowPosition(display,&windows->widget);
+ /*
+ Map Text View widget.
+ */
+ (void) strlcpy(windows->widget.name,title,MaxTextExtent);
+ status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->widget.id,&window_name);
+ XSetWMIconName(display,windows->widget.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ window_changes.width=windows->widget.width;
+ window_changes.height=windows->widget.height;
+ window_changes.x=windows->widget.x;
+ window_changes.y=windows->widget.y;
+ (void) XReconfigureWMWindow(display,windows->widget.id,
+ windows->widget.screen,mask,&window_changes);
+ (void) XMapRaised(display,windows->widget.id);
+ windows->widget.mapped=False;
+ /*
+ Respond to X events.
+ */
+ XGetWidgetInfo((char *) NULL,&slider_info);
+ XGetWidgetInfo((char *) NULL,&north_info);
+ XGetWidgetInfo((char *) NULL,&south_info);
+ visible_lines=0;
+ delay=SuspendTime << 2;
+ height=font_info->ascent+font_info->descent;
+ state=UpdateConfigurationState;
+ do
+ {
+ if (state & UpdateConfigurationState)
+ {
+ int
+ id;
+
+ /*
+ Initialize button information.
+ */
+ XGetWidgetInfo(DismissButtonText,&dismiss_info);
+ dismiss_info.width=width;
+ dismiss_info.height=(3*height) >> 1;
+ dismiss_info.x=windows->widget.width-dismiss_info.width-QuantumMargin-2;
+ dismiss_info.y=windows->widget.height-dismiss_info.height-QuantumMargin;
+ /*
+ Initialize scroll information.
+ */
+ XGetWidgetInfo((char *) NULL,&scroll_info);
+ scroll_info.bevel_width--;
+ scroll_info.width=height;
+ scroll_info.height=dismiss_info.y-((5*QuantumMargin) >> 1);
+ scroll_info.x=windows->widget.width-QuantumMargin-scroll_info.width;
+ scroll_info.y=(3*QuantumMargin) >> 1;
+ scroll_info.raised=False;
+ scroll_info.trough=True;
+ north_info=scroll_info;
+ north_info.raised=True;
+ north_info.width-=(north_info.bevel_width << 1);
+ north_info.height=north_info.width-1;
+ north_info.x+=north_info.bevel_width;
+ north_info.y+=north_info.bevel_width;
+ south_info=north_info;
+ south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
+ south_info.height;
+ id=slider_info.id;
+ slider_info=north_info;
+ slider_info.id=id;
+ slider_info.width-=2;
+ slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
+ slider_info.bevel_width+2;
+ slider_info.height=
+ scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+2;
+ visible_lines=(scroll_info.height-(height >> 3)-3)/
+ ((9*(text_info->ascent+text_info->descent)) >> 3);
+ if (lines > visible_lines)
+ slider_info.height=(visible_lines*slider_info.height)/lines;
+ slider_info.max_y=south_info.y-south_info.bevel_width-
+ slider_info.bevel_width-2;
+ slider_info.x=scroll_info.x+slider_info.bevel_width+1;
+ slider_info.y=slider_info.min_y;
+ expose_info=scroll_info;
+ expose_info.y=slider_info.y;
+ /*
+ Initialize list information.
+ */
+ XGetWidgetInfo((char *) NULL,&list_info);
+ list_info.raised=False;
+ list_info.bevel_width--;
+ list_info.width=scroll_info.x-((3*QuantumMargin) >> 1);
+ list_info.height=scroll_info.height;
+ list_info.x=QuantumMargin;
+ list_info.y=scroll_info.y;
+ /*
+ Initialize selection information.
+ */
+ XGetWidgetInfo((char *) NULL,&selection_info);
+ selection_info.center=False;
+ selection_info.width=list_info.width;
+ selection_info.height=(9*(text_info->ascent+text_info->descent)) >> 3;
+ selection_info.x=list_info.x;
+ state&=(~UpdateConfigurationState);
+ }
+ if (state & RedrawWidgetState)
+ {
+ /*
+ Redraw Text View window.
+ */
+ XDrawBeveledMatte(display,&windows->widget,&list_info);
+ XDrawBeveledMatte(display,&windows->widget,&scroll_info);
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
+ selection_info.id=(~0);
+ state|=RedrawListState;
+ state&=(~RedrawWidgetState);
+ }
+ if (state & RedrawListState)
+ {
+ /*
+ Determine slider id and position.
+ */
+ if (slider_info.id >= (int) (lines-visible_lines))
+ slider_info.id=lines-visible_lines;
+ if ((slider_info.id < 0) || (lines <= visible_lines))
+ slider_info.id=0;
+ slider_info.y=slider_info.min_y;
+ if (lines != 0)
+ slider_info.y+=
+ slider_info.id*(slider_info.max_y-slider_info.min_y+1)/lines;
+ if (slider_info.id != selection_info.id)
+ {
+ /*
+ Redraw scroll bar and text.
+ */
+ windows->widget.font_info=text_info;
+ (void) XSetFont(display,windows->widget.annotate_context,
+ text_info->fid);
+ (void) XSetFont(display,windows->widget.highlight_context,
+ text_info->fid);
+ selection_info.id=slider_info.id;
+ selection_info.y=list_info.y+(height >> 3)+2;
+ for (i=0; i < (int) visible_lines; i++)
+ {
+ selection_info.raised=(slider_info.id+i) != list_info.id;
+ selection_info.text=(char *) NULL;
+ if ((slider_info.id+i) < (int) lines)
+ selection_info.text=(char *) textlist[slider_info.id+i];
+ XDrawWidgetText(display,&windows->widget,&selection_info);
+ selection_info.y+=(int) selection_info.height;
+ }
+ windows->widget.font_info=font_info;
+ (void) XSetFont(display,windows->widget.annotate_context,
+ font_info->fid);
+ (void) XSetFont(display,windows->widget.highlight_context,
+ font_info->fid);
+ /*
+ Update slider.
+ */
+ if (slider_info.y > expose_info.y)
+ {
+ expose_info.height=slider_info.y-expose_info.y;
+ expose_info.y=slider_info.y-expose_info.height-
+ slider_info.bevel_width-1;
+ }
+ else
+ {
+ expose_info.height=expose_info.y-slider_info.y;
+ expose_info.y=slider_info.y+slider_info.height+
+ slider_info.bevel_width+1;
+ }
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ XDrawMatte(display,&windows->widget,&expose_info);
+ XDrawBeveledButton(display,&windows->widget,&slider_info);
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ expose_info.y=slider_info.y;
+ }
+ state&=(~RedrawListState);
+ }
+ /*
+ Wait for next event.
+ */
+ if (north_info.raised && south_info.raised)
+ (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
+ else
+ {
+ /*
+ Brief delay before advancing scroll bar.
+ */
+ MagickXDelay(display,delay);
+ delay=SuspendTime;
+ (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
+ if (!north_info.raised)
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ slider_info.id--;
+ state|=RedrawListState;
+ }
+ if (!south_info.raised)
+ if (slider_info.id < (int) lines)
+ {
+ /*
+ Move slider down.
+ */
+ slider_info.id++;
+ state|=RedrawListState;
+ }
+ if (event.type != ButtonRelease)
+ continue;
+ }
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ if (MatteIsActive(slider_info,event.xbutton))
+ {
+ /*
+ Track slider.
+ */
+ slider_info.active=True;
+ break;
+ }
+ if (MatteIsActive(north_info,event.xbutton))
+ if (slider_info.id > 0)
+ {
+ /*
+ Move slider up.
+ */
+ north_info.raised=False;
+ slider_info.id--;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(south_info,event.xbutton))
+ if (slider_info.id < (int) lines)
+ {
+ /*
+ Move slider down.
+ */
+ south_info.raised=False;
+ slider_info.id++;
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(scroll_info,event.xbutton))
+ {
+ /*
+ Move slider.
+ */
+ if (event.xbutton.y < slider_info.y)
+ slider_info.id-=(visible_lines-1);
+ else
+ slider_info.id+=(visible_lines-1);
+ state|=RedrawListState;
+ break;
+ }
+ if (MatteIsActive(dismiss_info,event.xbutton))
+ {
+ /*
+ User pressed Dismiss button.
+ */
+ dismiss_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ break;
+ }
+ if (MatteIsActive(list_info,event.xbutton))
+ {
+ unsigned int
+ id;
+
+ static Time
+ click_time;
+
+ /*
+ User pressed list matte.
+ */
+ id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
+ selection_info.height;
+ if (id >= lines)
+ break;
+ if ((int) id != list_info.id)
+ {
+ list_info.id=id;
+ click_time=event.xbutton.time;
+ break;
+ }
+ list_info.id=id;
+ if (event.xbutton.time >= (click_time+DoubleClick))
+ {
+ click_time=event.xbutton.time;
+ break;
+ }
+ click_time=event.xbutton.time;
+ /*
+ Become the XA_PRIMARY selection owner.
+ */
+ (void) strlcpy(primary_selection,textlist[list_info.id],
+ MaxTextExtent);
+ (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
+ event.xbutton.time);
+ if (XGetSelectionOwner(display,XA_PRIMARY) != windows->widget.id)
+ break;
+ selection_info.id=(~0);
+ list_info.id=id;
+ state|=RedrawListState;
+ break;
+ }
+ break;
+ }
+ case ButtonRelease:
+ {
+ if (!windows->widget.mapped)
+ break;
+ if (!north_info.raised)
+ {
+ /*
+ User released up button.
+ */
+ delay=SuspendTime << 2;
+ north_info.raised=True;
+ XDrawTriangleNorth(display,&windows->widget,&north_info);
+ }
+ if (!south_info.raised)
+ {
+ /*
+ User released down button.
+ */
+ delay=SuspendTime << 2;
+ south_info.raised=True;
+ XDrawTriangleSouth(display,&windows->widget,&south_info);
+ }
+ if (slider_info.active)
+ {
+ /*
+ Stop tracking slider.
+ */
+ slider_info.active=False;
+ break;
+ }
+ if (!dismiss_info.raised)
+ {
+ if (event.xbutton.window == windows->widget.id)
+ if (MatteIsActive(dismiss_info,event.xbutton))
+ state|=ExitState;
+ dismiss_info.raised=True;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ /*
+ If client window delete message, exit.
+ */
+ if (event.xclient.message_type != windows->wm_protocols)
+ break;
+ if (*event.xclient.data.l == (int) windows->wm_take_focus)
+ {
+ (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
+ event.xclient.data.l[1]);
+ break;
+ }
+ if (*event.xclient.data.l != (int) windows->wm_delete_window)
+ break;
+ if (event.xclient.window == windows->widget.id)
+ {
+ state|=ExitState;
+ break;
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ /*
+ Update widget configuration.
+ */
+ if (event.xconfigure.window != windows->widget.id)
+ break;
+ if ((event.xconfigure.width == (int) windows->widget.width) &&
+ (event.xconfigure.height == (int) windows->widget.height))
+ break;
+ windows->widget.width=
+ Max(event.xconfigure.width,(int) windows->widget.min_width);
+ windows->widget.height=
+ Max(event.xconfigure.height,(int) windows->widget.min_height);
+ state|=UpdateConfigurationState;
+ break;
+ }
+ case EnterNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state&=(~InactiveWidgetState);
+ break;
+ }
+ case Expose:
+ {
+ if (event.xexpose.window != windows->widget.id)
+ break;
+ if (event.xexpose.count != 0)
+ break;
+ state|=RedrawWidgetState;
+ break;
+ }
+ case KeyPress:
+ {
+ static char
+ command[MaxTextExtent];
+
+ static int
+ length;
+
+ static KeySym
+ key_symbol;
+
+ if (event.xkey.window != windows->widget.id)
+ break;
+ /*
+ Respond to a user key press.
+ */
+ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
+ &key_symbol,(XComposeStatus *) NULL);
+ *(command+length)='\0';
+ if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
+ {
+ dismiss_info.raised=False;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ state|=ExitState;
+ break;
+ }
+ if (AreaIsActive(scroll_info,event.xkey))
+ {
+ /*
+ Move slider.
+ */
+ switch ((int) key_symbol)
+ {
+ case XK_Home:
+ case XK_KP_Home:
+ {
+ slider_info.id=0;
+ break;
+ }
+ case XK_Up:
+ case XK_KP_Up:
+ {
+ slider_info.id--;
+ break;
+ }
+ case XK_Down:
+ case XK_KP_Down:
+ {
+ slider_info.id++;
+ break;
+ }
+ case XK_Prior:
+ case XK_KP_Prior:
+ {
+ slider_info.id-=visible_lines;
+ break;
+ }
+ case XK_Next:
+ case XK_KP_Next:
+ {
+ slider_info.id+=visible_lines;
+ break;
+ }
+ case XK_End:
+ case XK_KP_End:
+ {
+ slider_info.id=lines;
+ break;
+ }
+ }
+ state|=RedrawListState;
+ break;
+ }
+ break;
+ }
+ case KeyRelease:
+ break;
+ case LeaveNotify:
+ {
+ if (event.xcrossing.window != windows->widget.id)
+ break;
+ state|=InactiveWidgetState;
+ break;
+ }
+ case MapNotify:
+ {
+ mask&=(~CWX);
+ mask&=(~CWY);
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ if (slider_info.active)
+ {
+ /*
+ Move slider matte.
+ */
+ slider_info.y=event.xmotion.y-
+ ((slider_info.height+slider_info.bevel_width) >> 1)+1;
+ if (slider_info.y < slider_info.min_y)
+ slider_info.y=slider_info.min_y;
+ if (slider_info.y > slider_info.max_y)
+ slider_info.y=slider_info.max_y;
+ slider_info.id=0;
+ if (slider_info.y != slider_info.min_y)
+ slider_info.id=(lines*(slider_info.y-slider_info.min_y+1))/
+ (slider_info.max_y-slider_info.min_y+1);
+ state|=RedrawListState;
+ break;
+ }
+ if (state & InactiveWidgetState)
+ break;
+ if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
+ {
+ /*
+ Dismiss button status changed.
+ */
+ dismiss_info.raised=!dismiss_info.raised;
+ XDrawBeveledButton(display,&windows->widget,&dismiss_info);
+ break;
+ }
+ break;
+ }
+ case SelectionClear:
+ {
+ list_info.id=(~0);
+ selection_info.id=(~0);
+ state|=RedrawListState;
+ break;
+ }
+ case SelectionRequest:
+ {
+ XSelectionEvent
+ notify;
+
+ XSelectionRequestEvent
+ *request;
+
+ if (list_info.id == (~0))
+ break;
+ /*
+ Set primary selection.
+ */
+ request=(&(event.xselectionrequest));
+ (void) XChangeProperty(request->display,request->requestor,
+ request->property,request->target,8,PropModeReplace,
+ (unsigned char *) primary_selection,Extent(primary_selection));
+ notify.type=SelectionNotify;
+ notify.send_event=True;
+ notify.display=request->display;
+ notify.requestor=request->requestor;
+ notify.selection=request->selection;
+ notify.target=request->target;
+ notify.time=request->time;
+ if (request->property == None)
+ notify.property=request->target;
+ else
+ notify.property=request->property;
+ (void) XSendEvent(request->display,request->requestor,False,NoEventMask,
+ (XEvent *) &notify);
+ }
+ default:
+ break;
+ }
+ } while (!(state & ExitState));
+ if (text_info != windows->widget.font_info)
+ (void) XFreeFont(display,text_info);
+ MagickXSetCursorState(display,windows,False);
+ (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
+ MagickXCheckRefreshWindows(display,windows);
+}
+#endif
diff --git a/magick/widget.h b/magick/widget.h
new file mode 100644
index 0000000..6b40cbb
--- /dev/null
+++ b/magick/widget.h
@@ -0,0 +1,102 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+ Copyright 1991-1999 E. I. du Pont de Nemours and Company
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ X11 User Interface Methods for ImageMagick.
+*/
+#ifndef _MAGICK_WIDGET_H
+#define _MAGICK_WIDGET_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ Enum declarations.
+*/
+typedef enum
+{
+ ControlState = 0x0001,
+ InactiveWidgetState = 0x0004,
+ JumpListState = 0x0008,
+ RedrawActionState = 0x0010,
+ RedrawListState = 0x0020,
+ RedrawWidgetState = 0x0040,
+ UpdateListState = 0x0100
+} WidgetState;
+
+/*
+ Typedef declarations.
+*/
+typedef struct _MagickXWidgetInfo
+{
+ char
+ *cursor,
+ *text,
+ *marker;
+
+ int
+ id;
+
+ unsigned int
+ bevel_width,
+ width,
+ height;
+
+ int
+ x,
+ y,
+ min_y,
+ max_y;
+
+ unsigned int
+ raised,
+ active,
+ center,
+ trough,
+ highlight;
+} MagickXWidgetInfo;
+
+/*
+ X utilities routines.
+*/
+extern MagickExport int
+ MagickXCommandWidget(Display *,MagickXWindows *,const char **,XEvent *),
+ MagickXConfirmWidget(Display *,MagickXWindows *,const char *,const char *),
+ MagickXDialogWidget(Display *,MagickXWindows *,const char *,const char *,char *),
+ MagickXMenuWidget(Display *,MagickXWindows *,const char *,const char **,char *);
+
+extern MagickExport unsigned int
+ MagickXPreferencesWidget(Display *,MagickXResourceInfo *,MagickXWindows *);
+
+extern MagickExport void
+ MagickXColorBrowserWidget(Display *,MagickXWindows *,const char *,char *),
+ MagickXFileBrowserWidget(Display *,MagickXWindows *,const char *,char *),
+ MagickXFontBrowserWidget(Display *,MagickXWindows *,const char *,char *),
+ MagickXInfoWidget(Display *,MagickXWindows *,const char *),
+ MagickXListBrowserWidget(Display *,MagickXWindows *,MagickXWindowInfo *,const char **,
+ const char *,const char *,char *),
+ MagickXMonitorWidget(Display *display,MagickXWindows *windows,const char *task,
+ const magick_int64_t quantum,const magick_uint64_t span),
+ MagickXNoticeWidget(Display *,MagickXWindows *,const char *,const char *),
+ MagickXTextViewWidget(Display *,const MagickXResourceInfo *,MagickXWindows *,const unsigned int,
+ const char *,const char **);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/magick/xwindow.c b/magick/xwindow.c
new file mode 100644
index 0000000..bfcb2c9
--- /dev/null
+++ b/magick/xwindow.c
@@ -0,0 +1,9642 @@
+/*
+% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% X X W W IIIII N N DDDD OOO W W %
+% X X W W I NN N D D O O W W %
+% X W W I N N N D D O O W W %
+% X X W W W I N NN D D O O W W W %
+% X X W W IIIII N N DDDD OOO W W %
+% %
+% %
+% X11 Utility Methods for GraphicsMagick %
+% %
+% %
+% Software Design %
+% John Cristy %
+% July 1992 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/analyze.h"
+#include "magick/blob.h"
+#include "magick/color.h"
+#include "magick/color_lookup.h"
+#include "magick/colormap.h"
+#include "magick/composite.h"
+#include "magick/constitute.h"
+#include "magick/describe.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "magick/pixel_cache.h"
+#include "magick/resize.h"
+#include "magick/shear.h"
+#include "magick/tempfile.h"
+#include "magick/texture.h"
+#include "magick/transform.h"
+#include "magick/utility.h"
+#include "magick/version.h"
+#if defined(HasSharedMemory)
+# if defined(HAVE_MACHINE_PARAM_H)
+ /* Need by some *BSD systems in order to use shmget */
+# include <machine/param.h>
+# endif /* defined(HAVE_MACHINE_PARAM_H */
+# if defined(__FreeBSD__)
+# if __FreeBSD__ >= 5 && defined(_POSIX_C_SOURCE)
+ typedef unsigned short ushort; /* needed for sys/ipc.h at the moment */
+# endif
+# endif
+# include <sys/ipc.h>
+# include <sys/shm.h>
+#endif
+#include "magick/xwindow.h"
+#if defined(HasX11)
+# if defined(HasShape)
+# include <X11/extensions/shape.h>
+# endif
+#if defined(HasSharedMemory)
+# include <X11/extensions/XShm.h>
+#endif
+
+/*
+ X defines.
+*/
+#define MagickXBlueGamma(color) ((Quantum) (blue_gamma == 1.0 ? (color) : \
+ ((pow((double) (color)/MaxRGB,1.0/blue_gamma)*MaxRGB)+0.5)))
+#define MagickXGammaPixel(map,color) (unsigned long) (map->base_pixel+ \
+ ((ScaleQuantumToShort(MagickXRedGamma((color)->red))*map->red_max/65535L)* \
+ map->red_mult)+ \
+ ((ScaleQuantumToShort(MagickXGreenGamma((color)->green))*map->green_max/65535L)* \
+ map->green_mult)+ \
+ ((ScaleQuantumToShort(MagickXBlueGamma((color)->blue))*map->blue_max/65535L)* \
+ map->blue_mult))
+#define MagickXGreenGamma(color) ((Quantum) (green_gamma == 1.0 ? (color) : \
+ ((pow((double) (color)/MaxRGB,1.0/green_gamma)*MaxRGB)+0.5)))
+#define MagickXRedGamma(color) ((Quantum) (red_gamma == 1.0 ? (color) : \
+ ((pow((double) (color)/MaxRGB,1.0/red_gamma)*MaxRGB)+0.5)))
+#define MagickXStandardPixel(map,color) (unsigned long) (map->base_pixel+ \
+ (((color)->red*map->red_max/65535L)*map->red_mult)+ \
+ (((color)->green*map->green_max/65535L)*map->green_mult)+ \
+ (((color)->blue*map->blue_max/65535L)*map->blue_mult))
+
+/*
+ Constant declaractions.
+*/
+static unsigned int
+ xerror_alert = False;
+
+/*
+ Method prototypes.
+*/
+static char
+ *MagickXVisualClassName(const int);
+
+static double
+ blue_gamma = 1.0,
+ green_gamma = 1.0,
+ red_gamma = 1.0;
+
+static unsigned int
+ MagickXMakePixmap(Display *,const MagickXResourceInfo *,MagickXWindowInfo *);
+
+static void
+ MagickXMakeImageLSBFirst(const MagickXResourceInfo *,const MagickXWindowInfo *,Image *,
+ XImage *,XImage *),
+ MagickXMakeImageMSBFirst(const MagickXResourceInfo *,const MagickXWindowInfo *,Image *,
+ XImage *,XImage *);
+
+static Window
+ MagickXSelectWindow(Display *,RectangleInfo *);
+
+#if defined(HasSharedMemory)
+/*
+ Attach to shared memory.
+*/
+static void *
+MagickShmAt(int shmid, void *shmaddr, int shmflg)
+{
+ void *
+ address;
+
+ if ((address=shmat(shmid,shmaddr,shmflg)) == (void *) -1)
+ {
+ if (shmaddr)
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "shm attach to id %d failed (%s)", shmid, strerror(errno));
+ else
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "shm attach to id %d at address 0x%p failed (%s)", shmid, shmaddr,
+ strerror(errno));
+ }
+ else
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "shm attach to id %d at address 0x%p", shmid, address);
+ }
+
+
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "shm attach to id %d at address 0x%p, errno=%d", shmid, address, errno);
+ return (address);
+}
+/*
+ Shared memory control operations.
+*/
+static int
+MagickShmCtl(int shmid, int cmd, struct shmid_ds *buf)
+{
+ int status;
+ if ((status=shmctl(shmid, cmd, buf)) == -1)
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"shm control id=%d cmd=%s failed (%s)",
+ shmid, ((cmd == IPC_STAT) ? "IPC_STAT" :
+ (cmd == IPC_SET) ? "IPC_SET" :
+ (cmd == IPC_RMID) ? "IPC_RMID" : "Unknown"),
+ strerror(errno));
+ }
+ else
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"shm control id=%d cmd=%s",
+ shmid, ((cmd == IPC_STAT) ? "IPC_STAT" :
+ (cmd == IPC_SET) ? "IPC_SET" :
+ (cmd == IPC_RMID) ? "IPC_RMID" : "Unknown"));
+ }
+ return status;
+}
+/*
+ Detatch from shared memory.
+*/
+static int
+MagickShmDt(void *shmaddr)
+{
+ int result;
+ if ((result=shmdt(shmaddr)) == -1)
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "shm detatch at address 0x%p failed (%s)",
+ shmaddr,
+ strerror(errno));
+ }
+ else
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ "shm detatch at address 0x%p",
+ shmaddr);
+ }
+ return (result);
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D e s t r o y X 1 1 R e s o u r c e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXDestroyX11Resources() destroys all remaining allocations related
+% to X11, and closes the X11 display. It is intended to be invoked by
+% DestroyMagick().
+%
+% The format of the MagickXDestroyX11Resources method is:
+%
+% void MagickXDestroyX11Resources(void)
+%
+% A description of each parameter follows:
+%
+%
+*/
+MagickExport void
+MagickXDestroyX11Resources(void)
+{
+ MagickXWindows *windows = MagickXSetWindows((MagickXWindows *) ~0);
+ if (windows != (MagickXWindows *) NULL)
+ {
+ MagickXDestroyXWindows(windows);
+ (void) MagickXSetWindows((MagickXWindows *) NULL);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D e s t r o y X W i n d o w s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXDestroyXWindows() destroys existing allocations in an MagickXWindows
+% structure.
+%
+% The format of the MagickXDestroyXWindows method is:
+%
+% void MagickXDestroyXWindows(MagickXWindows *windows)
+%
+% A description of each parameter follows:
+%
+%
+*/
+MagickExport void
+MagickXDestroyXWindows(MagickXWindows *windows)
+{
+ if (windows == (MagickXWindows *) NULL ||
+ (windows->display == (Display *) NULL))
+ return;
+ MagickFreeMemory(windows->icon_resources);
+
+ if (windows->icon_pixel)
+ {
+ MagickFreeMemory(windows->icon_pixel->pixels);
+ if (windows->icon_pixel->annotate_context != (GC) NULL)
+ (void) XFreeGC(windows->display,windows->icon_pixel->annotate_context); /* Allocated by XCreateGC */
+ if (windows->icon_pixel->widget_context != (GC) NULL)
+ (void) XFreeGC(windows->display,windows->icon_pixel->widget_context); /* Allocated by XCreateGC */
+ if (windows->icon_pixel->highlight_context != (GC) NULL)
+ (void) XFreeGC(windows->display,windows->icon_pixel->highlight_context); /* Allocated by XCreateGC */
+ MagickFreeMemory(windows->icon_pixel);
+ }
+
+ if (windows->pixel_info)
+ {
+ MagickFreeMemory(windows->pixel_info->pixels);
+ if (windows->pixel_info->annotate_context != (GC) NULL)
+ (void) XFreeGC(windows->display,windows->pixel_info->annotate_context); /* Allocated by XCreateGC */
+ if (windows->pixel_info->widget_context != (GC) NULL)
+ (void) XFreeGC(windows->display,windows->pixel_info->widget_context); /* Allocated by XCreateGC */
+ if (windows->pixel_info->highlight_context != (GC) NULL)
+ (void) XFreeGC(windows->display,windows->pixel_info->highlight_context); /* Allocated by XCreateGC */
+ MagickFreeMemory(windows->pixel_info);
+ }
+
+ if (windows->font_info != (XFontStruct *) NULL)
+ {
+ (void) XFreeFont(windows->display,windows->font_info); /* Allocated by XLoadQueryFont */
+ windows->font_info=(XFontStruct *) NULL;
+ }
+
+ if (windows->class_hints != (XClassHint *) NULL)
+ {
+ (void) XFree(windows->class_hints); /* Allocated by XAllocClassHint */
+ windows->class_hints=(XClassHint *) NULL;
+ }
+
+ if (windows->manager_hints != (XWMHints *) NULL)
+ {
+ (void) XFree(windows->manager_hints); /* Allocated by XAllocWMHints */
+ windows->manager_hints=(XWMHints *) NULL;
+ }
+
+ if (windows->map_info != (XStandardColormap *) NULL)
+ {
+ (void) XFree(windows->map_info); /* Allocated by XAllocStandardColormap */
+ windows->map_info=(XStandardColormap *) NULL;
+ }
+
+ if(windows->icon_map != (XStandardColormap *) NULL)
+ {
+ (void) XFree(windows->icon_map); /* Allocated by XAllocStandardColormap */
+ windows->icon_map=(XStandardColormap *) NULL;
+ }
+
+ if (windows->visual_info != (XVisualInfo *) NULL)
+ {
+ (void) XFree(windows->visual_info); /* Allocated by XGetVisualInfo */
+ windows->visual_info=(XVisualInfo *) NULL;
+ }
+
+ if (windows->icon_visual != (XVisualInfo *) NULL)
+ {
+ (void) XFree(windows->icon_visual); /* Allocated by XGetVisualInfo */
+ windows->icon_visual=(XVisualInfo *) NULL;
+ }
+
+ MagickXDestroyXWindowInfo(windows->display,&windows->context);
+ MagickXDestroyXWindowInfo(windows->display,&windows->backdrop);
+ MagickXDestroyXWindowInfo(windows->display,&windows->icon);
+ MagickXDestroyXWindowInfo(windows->display,&windows->image);
+ MagickXDestroyXWindowInfo(windows->display,&windows->info);
+ MagickXDestroyXWindowInfo(windows->display,&windows->magnify);
+ MagickXDestroyXWindowInfo(windows->display,&windows->pan);
+ MagickXDestroyXWindowInfo(windows->display,&windows->command);
+ MagickXDestroyXWindowInfo(windows->display,&windows->widget);
+ MagickXDestroyXWindowInfo(windows->display,&windows->popup);
+ MagickXDestroyXWindowInfo(windows->display,&windows->group_leader);
+ windows->display=(Display *) NULL;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D e s t r o y X W i n d o w I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXDestroyXWindowInfo() destroys existing allocations in an
+% MagickXWindowInfo structure. The MagickXWindowInfo structure itself is
+% not freed.
+%
+% The format of the MagickXDestroyXWindowInfo method is:
+%
+% void MagickXDestroyXWindowInfo(Display *display,
+% MagickXWindowInfo *window)
+%
+% A description of each parameter follows:
+%
+% o display: Pointer to an X11 Display structure
+%
+% o window: Pointer to MagickXWindowInfo structure to destroy.
+*/
+MagickExport void
+MagickXDestroyXWindowInfo(Display *display,MagickXWindowInfo *window)
+{
+ if (window->mapped != False)
+ {
+ (void) XWithdrawWindow(display,window->id,
+ window->screen);
+ (void) XSync(display,False);
+ window->mapped=False;
+ }
+
+ MagickFreeMemory(window->name);
+
+ MagickFreeMemory(window->icon_name);
+
+ if (window->cursor != (Cursor) NULL)
+ {
+ (void) XFreeCursor(display,window->cursor);
+ window->cursor=(Cursor) NULL;
+ }
+
+ if (window->highlight_stipple != (Pixmap) NULL)
+ {
+ (void) XFreePixmap(display,window->highlight_stipple);
+ window->highlight_stipple=(Pixmap) NULL;
+ }
+
+ if (window->shadow_stipple != (Pixmap) NULL)
+ {
+ (void) XFreePixmap(display,window->shadow_stipple);
+ window->shadow_stipple=(Pixmap) NULL;
+ }
+
+ if (window->ximage != (XImage *) NULL)
+ {
+ XDestroyImage(window->ximage);
+ window->ximage=(XImage *) NULL;
+ }
+
+ if (window->matte_image != (XImage *) NULL)
+ {
+ /* MagickFreeMemory(window->matte_image->data); ???? */
+ XDestroyImage(window->matte_image);
+ window->matte_image=(XImage *) NULL;
+ }
+
+ if (window->pixmap != (Pixmap) NULL)
+ {
+ (void) XFreePixmap(display,window->pixmap);
+ window->pixmap=(Pixmap) NULL;
+ }
+
+ if (window->id != (Window) NULL)
+ {
+ (void) XDestroyWindow(display,window->id);
+ window->id=(Window) NULL;
+ }
+
+ if (window->destroy)
+ {
+ if (window->image != (Image *) NULL)
+ {
+ DestroyImage(window->image);
+ window->image=(Image *) NULL;
+ }
+ }
+
+ if (window->segment_info != (void *) NULL)
+ {
+#if defined(HasSharedMemory)
+ XShmSegmentInfo
+ *segment_info;
+
+ segment_info=(XShmSegmentInfo *) window->segment_info;
+ if (segment_info != (XShmSegmentInfo *) NULL)
+ {
+ if (segment_info[0].shmid >= 0)
+ {
+ if (segment_info[0].shmaddr != NULL)
+ (void) MagickShmDt(segment_info[0].shmaddr);
+ (void) MagickShmCtl(segment_info[0].shmid,IPC_RMID,0);
+ segment_info[0].shmaddr=NULL;
+ segment_info[0].shmid=(-1);
+ }
+ }
+#endif
+
+ MagickFreeMemory(window->segment_info);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k I s T r u e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickIsTrue returns True if the reason is "true", "on", "yes"
+% or "1".
+%
+% The format of the MagickIsTrue method is:
+%
+% unsigned int MagickIsTrue(const char *reason)
+%
+% A description of each parameter follows:
+%
+% o option: either True or False depending on the reason parameter.
+%
+% o reason: Specifies a pointer to a character array.
+%
+%
+*/
+MagickExport unsigned int
+MagickIsTrue(const char *reason)
+{
+ if (reason == (char *) NULL)
+ return(False);
+ if (LocaleCompare(reason,"true") == 0)
+ return(True);
+ if (LocaleCompare(reason,"on") == 0)
+ return(True);
+ if (LocaleCompare(reason,"yes") == 0)
+ return(True);
+ if (LocaleCompare(reason,"1") == 0)
+ return(True);
+ return(False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X A n n o t a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXAnnotateImage annotates the image with text.
+%
+% The format of the MagickXAnnotateImage method is:
+%
+% unsigned int MagickXAnnotateImage(Display *display,
+% const MagickXPixelInfo *pixel,MagickXAnnotateInfo *annotate_info,
+% Image *image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXAnnotateImage returns True if the image is
+% successfully annotated with text. False is returned is there is a
+% memory shortage.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o pixel: Specifies a pointer to a MagickXPixelInfo structure.
+%
+% o annotate_info: Specifies a pointer to a MagickXAnnotateInfo structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport unsigned int
+MagickXAnnotateImage(Display *display,
+ const MagickXPixelInfo *pixel,
+ MagickXAnnotateInfo *annotate_info,
+ Image *image)
+{
+ GC
+ annotate_context;
+
+ Image
+ *annotate_image;
+
+ int
+ x,
+ y;
+
+ Pixmap
+ annotate_pixmap;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ depth,
+ height,
+ matte,
+ width;
+
+ Window
+ root_window;
+
+ XGCValues
+ context_values;
+
+ XImage
+ *annotate_ximage;
+
+ /*
+ Initialize annotated image.
+ */
+ assert(display != (Display *) NULL);
+ assert(pixel != (MagickXPixelInfo *) NULL);
+ assert(annotate_info != (MagickXAnnotateInfo *) NULL);
+ assert(image != (Image *) NULL);
+ /*
+ Initialize annotated pixmap.
+ */
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ depth=XDefaultDepth(display,XDefaultScreen(display));
+ annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width,
+ annotate_info->height,(int) depth);
+ if (annotate_pixmap == (Pixmap) NULL)
+ return(False);
+ /*
+ Initialize graphics info.
+ */
+ context_values.background=0;
+ context_values.foreground=(unsigned long) (~0);
+ context_values.font=annotate_info->font_info->fid;
+ annotate_context=XCreateGC(display,root_window,GCBackground | GCFont |
+ GCForeground,&context_values);
+ if (annotate_context == (GC) NULL)
+ return(False);
+ /*
+ Draw text to pixmap.
+ */
+ (void) XDrawImageString(display,annotate_pixmap,annotate_context,0,
+ (int) annotate_info->font_info->ascent,annotate_info->text,
+ (int) strlen(annotate_info->text));
+ (void) XFreeGC(display,annotate_context);
+ /*
+ Initialize annotated X image.
+ */
+ annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width,
+ annotate_info->height,AllPlanes,ZPixmap);
+ if (annotate_ximage == (XImage *) NULL)
+ return(False);
+ (void) XFreePixmap(display,annotate_pixmap);
+ /*
+ Initialize annotated image.
+ */
+ annotate_image=AllocateImage((ImageInfo *) NULL);
+ if (annotate_image == (Image *) NULL)
+ return(False);
+ annotate_image->columns=annotate_info->width;
+ annotate_image->rows=annotate_info->height;
+ /*
+ Transfer annotated X image to image.
+ */
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ x=0;
+ y=0;
+ (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
+ (void) AcquireOnePixelByReference(image,&annotate_image->background_color,
+ x,y,&image->exception);
+ annotate_image->matte=annotate_info->stencil == ForegroundStencil;
+ for (y=0; y < (long) annotate_image->rows; y++)
+ {
+ q=GetImagePixels(annotate_image,0,y,annotate_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) annotate_image->columns; x++)
+ {
+ q->opacity=OpaqueOpacity;
+ if (XGetPixel(annotate_ximage,x,y) == 0)
+ {
+ /*
+ Set this pixel to the background color.
+ */
+ q->red=ScaleShortToQuantum(pixel->box_color.red);
+ q->green=ScaleShortToQuantum(pixel->box_color.green);
+ q->blue=ScaleShortToQuantum(pixel->box_color.blue);
+ if ((annotate_info->stencil == ForegroundStencil) ||
+ (annotate_info->stencil == OpaqueStencil))
+ q->opacity=TransparentOpacity;
+ }
+ else
+ {
+ /*
+ Set this pixel to the pen color.
+ */
+ q->red=ScaleShortToQuantum(pixel->pen_color.red);
+ q->green=ScaleShortToQuantum(pixel->pen_color.green);
+ q->blue=ScaleShortToQuantum(pixel->pen_color.blue);
+ if (annotate_info->stencil == BackgroundStencil)
+ q->opacity=TransparentOpacity;
+ }
+ q++;
+ }
+ if (!SyncImagePixels(annotate_image))
+ break;
+ }
+ XDestroyImage(annotate_ximage);
+ annotate_ximage=(XImage *) NULL;
+ /*
+ Determine annotate geometry.
+ */
+ (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
+ if ((width != (unsigned int) annotate_image->columns) ||
+ (height != (unsigned int) annotate_image->rows))
+ {
+ char
+ image_geometry[MaxTextExtent];
+
+ /*
+ Scale image.
+ */
+ FormatString(image_geometry,"%ux%u",width,height);
+ TransformImage(&annotate_image,(char *) NULL,image_geometry);
+ }
+ if (annotate_info->degrees != 0.0)
+ {
+ double
+ normalized_degrees;
+
+ Image
+ *rotate_image;
+
+ int
+ rotations;
+
+ /*
+ Rotate image.
+ */
+ rotate_image=
+ RotateImage(annotate_image,annotate_info->degrees,&image->exception);
+ if (rotate_image == (Image *) NULL)
+ return(False);
+ DestroyImage(annotate_image);
+ annotate_image=rotate_image;
+ /*
+ Annotation is relative to the degree of rotation.
+ */
+ normalized_degrees=annotate_info->degrees;
+ while (normalized_degrees < -45.0)
+ normalized_degrees+=360.0;
+ for (rotations=0; normalized_degrees > 45.0; rotations++)
+ normalized_degrees-=90.0;
+ switch (rotations % 4)
+ {
+ default:
+ case 0:
+ break;
+ case 1:
+ {
+ /*
+ Rotate 90 degrees.
+ */
+ x-=(int) annotate_image->columns/2;
+ y+=(int) annotate_image->columns/2;
+ break;
+ }
+ case 2:
+ {
+ /*
+ Rotate 180 degrees.
+ */
+ x=x-(int) annotate_image->columns;
+ break;
+ }
+ case 3:
+ {
+ /*
+ Rotate 270 degrees.
+ */
+ x=x-(int) annotate_image->columns/2;
+ y=y-(int) (annotate_image->rows-(annotate_image->columns/2));
+ break;
+ }
+ }
+ }
+ /*
+ Composite text onto the image.
+ */
+ (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
+ matte=image->matte;
+ (void) CompositeImage(image,annotate_image->matte ? OverCompositeOp :
+ CopyCompositeOp,annotate_image,x,y);
+ image->matte=matte;
+ DestroyImage(annotate_image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X B e s t F o n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXBestFont returns the "best" font. "Best" is defined as a font
+% specified in the X resource database or a font such that the text width
+% displayed with the font does not exceed the specified maximum width.
+%
+% The format of the MagickXBestFont method is:
+%
+% XFontStruct *MagickXBestFont(Display *display,
+% const MagickXResourceInfo *resource_info,const unsigned int text_font)
+%
+% A description of each parameter follows:
+%
+% o font: MagickXBestFont returns a pointer to a XFontStruct structure.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+% o text_font: True is font should be mono-spaced (typewriter style).
+%
+%
+*/
+static char **
+MagickFontToList(char *font)
+{
+ char
+ **fontlist;
+
+ register char
+ *p,
+ *q;
+
+ register int
+ i;
+
+ unsigned int
+ fonts;
+
+ if (font == (char *) NULL)
+ return((char **) NULL);
+ /*
+ Convert string to an ASCII list.
+ */
+ fonts=1;
+ for (p=font; *p != '\0'; p++)
+ if ((*p == ':') || (*p == ';') || (*p == ','))
+ fonts++;
+ fontlist=MagickAllocateArray(char **,(fonts+1),sizeof(char *));
+ if (fontlist == (char **) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToConvertFont);
+ return((char **) NULL);
+ }
+ p=font;
+ for (i=0; i < (int) fonts; i++)
+ {
+ for (q=p; *q != '\0'; q++)
+ if ((*q == ':') || (*q == ';') || (*q == ','))
+ break;
+ fontlist[i]=MagickAllocateMemory(char *,(size_t) (q-p+1));
+ if (fontlist[i] == (char *) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToConvertFont);
+ return((char **) NULL);
+ }
+ (void) strlcpy(fontlist[i],p,q-p+1);
+ p=q+1;
+ }
+ fontlist[i]=(char *) NULL;
+ return(fontlist);
+}
+
+MagickExport XFontStruct *
+MagickXBestFont(Display *display,
+ const MagickXResourceInfo *resource_info,
+ const unsigned int text_font)
+{
+ static const char
+ *Fonts[]=
+ {
+ "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
+ "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1",
+ "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15",
+ "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15",
+ "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*",
+ "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*",
+ "variable",
+ "fixed",
+ (char *) NULL
+ },
+ *TextFonts[]=
+ {
+ "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1",
+ "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15",
+ "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*",
+ "fixed",
+ (char *) NULL
+ };
+
+ char
+ *font_name;
+
+ register const char
+ **p;
+
+ XFontStruct
+ *font_info;
+
+ font_info=(XFontStruct *) NULL;
+ font_name=resource_info->font;
+ if (text_font)
+ font_name=resource_info->text_font;
+ if (font_name != (char *) NULL)
+ {
+ char
+ **fontlist;
+
+ register int
+ i;
+
+ /*
+ Load preferred font specified in the X resource database.
+ */
+ fontlist=MagickFontToList(font_name);
+ if (fontlist != (char **) NULL)
+ {
+ for (i=0; fontlist[i] != (char *) NULL; i++)
+ {
+ if (font_info == (XFontStruct *) NULL)
+ font_info=XLoadQueryFont(display,fontlist[i]);
+ MagickFreeMemory(fontlist[i]);
+ }
+ MagickFreeMemory(fontlist);
+ }
+ if (font_info == (XFontStruct *) NULL)
+ MagickError(XServerError,UnableToLoadFont,font_name);
+ }
+ /*
+ Load fonts from list of fonts until one is found.
+ */
+ p=Fonts;
+ if (text_font)
+ p=TextFonts;
+ if (XDisplayHeight(display,XDefaultScreen(display)) >= 748)
+ p++;
+ while (*p != (char *) NULL)
+ {
+ if (font_info != (XFontStruct *) NULL)
+ break;
+ font_info=XLoadQueryFont(display,(char *) *p);
+ p++;
+ }
+ return(font_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X B e s t I c o n S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXBestIconSize returns the "best" icon size. "Best" is
+% defined as an icon size that maintains the aspect ratio of the image.
+% If the window manager has preferred icon sizes, one of the preferred
+% sizes is used.
+%
+% The format of the MagickXBestIconSize method is:
+%
+% void MagickXBestIconSize(Display *display,MagickXWindowInfo *window,
+% Image *image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport void
+MagickXBestIconSize(Display *display,MagickXWindowInfo *window,
+ Image *image)
+{
+ double
+ scale_factor;
+
+ int
+ i,
+ number_sizes;
+
+ unsigned int
+ height,
+ icon_height,
+ icon_width,
+ width;
+
+ Window
+ root_window;
+
+ XIconSize
+ *icon_size,
+ *size_list;
+
+ /*
+ Determine if the window manager has specified preferred icon sizes.
+ */
+ assert(display != (Display *) NULL);
+ assert(window != (MagickXWindowInfo *) NULL);
+ assert(image != (Image *) NULL);
+ window->width=MaxIconSize;
+ window->height=MaxIconSize;
+ icon_size=(XIconSize *) NULL;
+ number_sizes=0;
+ root_window=XRootWindow(display,window->screen);
+ if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
+ if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
+ icon_size=size_list;
+ if (icon_size == (XIconSize *) NULL)
+ {
+ /*
+ Window manager does not restrict icon size.
+ */
+ icon_size=XAllocIconSize();
+ if (icon_size == (XIconSize *) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToGetBestIconSize);
+ return;
+ }
+ icon_size->min_width=1;
+ icon_size->max_width=MaxIconSize;
+ icon_size->min_height=1;
+ icon_size->max_height=MaxIconSize;
+ icon_size->width_inc=1;
+ icon_size->height_inc=1;
+ }
+ /*
+ Determine aspect ratio of image.
+ */
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ i=0;
+ if (window->crop_geometry)
+ (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height);
+ /*
+ Look for an icon size that maintains the aspect ratio of image.
+ */
+ scale_factor=(double) icon_size->max_width/width;
+ if (scale_factor > ((double) icon_size->max_height/height))
+ scale_factor=(double) icon_size->max_height/height;
+ icon_width=icon_size->min_width;
+ while ((int) icon_width < icon_size->max_width)
+ {
+ if (icon_width >= (scale_factor*width))
+ break;
+ icon_width+=icon_size->width_inc;
+ }
+ icon_height=icon_size->min_height;
+ while ((int) icon_height < icon_size->max_height)
+ {
+ if (icon_height >= (scale_factor*height))
+ break;
+ icon_height+=icon_size->height_inc;
+ }
+ (void) XFree((void *) icon_size);
+ window->width=icon_width;
+ window->height=icon_height;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X B e s t P i x e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXBestPixel returns a pixel from an array of pixels that is
+% closest to the requested color. If the color array is NULL, the colors
+% are obtained from the X server.
+%
+% The format of the MagickXBestPixel method is:
+%
+% void MagickXBestPixel(Display *display,const Colormap colormap,
+% XColor *colors,unsigned int number_colors,XColor *color)
+%
+% A description of each parameter follows:
+%
+% o pixel: MagickXBestPixel returns the pixel value closest to the requested
+% color.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o colormap: Specifies the ID of the X server colormap.
+%
+% o colors: Specifies an array of XColor structures.
+%
+% o number_colors: Specifies the number of XColor structures in the
+% color definition array.
+%
+% o color: Specifies the desired RGB value to find in the colors array.
+%
+%
+*/
+MagickExport void
+MagickXBestPixel(Display *display,const Colormap colormap,
+ XColor *colors,unsigned int number_colors,XColor *color)
+{
+ double
+ min_distance;
+
+ DoublePixelPacket
+ pixel;
+
+ int
+ query_server,
+ status;
+
+ register double
+ distance;
+
+ register int
+ i,
+ j;
+
+ /*
+ Find closest representation for the requested RGB color.
+ */
+ assert(display != (Display *) NULL);
+ assert(color != (XColor *) NULL);
+ status=XAllocColor(display,colormap,color);
+ if (status != 0)
+ return;
+ query_server=colors == (XColor *) NULL;
+ if (query_server)
+ {
+ /*
+ Read X server colormap.
+ */
+ colors=MagickAllocateArray(XColor *,number_colors,sizeof(XColor));
+ if (colors == (XColor *) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToReadXServerColormap);
+ return;
+ }
+ for (i=0; i < (int) number_colors; i++)
+ colors[i].pixel=(unsigned long) i;
+ if (number_colors > 256)
+ number_colors=256;
+ (void) XQueryColors(display,colormap,colors,number_colors);
+ }
+ min_distance=3.0*((double) MaxRGB+1.0)*((double) MaxRGB+1.0);
+ j=0;
+ for (i=0; i < (int) number_colors; i++)
+ {
+ pixel.red=colors[i].red-(double) color->red;
+ distance=pixel.red*pixel.red;
+ if (distance > min_distance)
+ continue;
+ pixel.green=colors[i].green-(double) color->green;
+ distance+=pixel.green*pixel.green;
+ if (distance > min_distance)
+ continue;
+ pixel.blue=colors[i].blue-(double) color->blue;
+ distance+=pixel.blue*pixel.blue;
+ if (distance > min_distance)
+ continue;
+ min_distance=distance;
+ color->pixel=colors[i].pixel;
+ j=i;
+ }
+ (void) XAllocColor(display,colormap,&colors[j]);
+ if (query_server)
+ MagickFreeMemory(colors);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X B e s t V i s u a l I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXBestVisualInfo returns visual information for a visual that is
+% the "best" the server supports. "Best" is defined as:
+%
+% 1. Restrict the visual list to those supported by the default screen.
+%
+% 2. If a visual type is specified, restrict the visual list to those of
+% that type.
+%
+% 3. If a map type is specified, choose the visual that matches the id
+% specified by the Standard Colormap.
+%
+% 4 From the list of visuals, choose one that can display the most
+% simultaneous colors. If more than one visual can display the same
+% number of simultaneous colors, one is chosen based on a rank.
+%
+% The format of the MagickXBestVisualInfo method is:
+%
+% XVisualInfo *MagickXBestVisualInfo(Display *display,
+% XStandardColormap *map_info,MagickXResourceInfo *resource_info)
+%
+% A description of each parameter follows:
+%
+% o visual_info: MagickXBestVisualInfo returns a pointer to a X11
+% XVisualInfo structure.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o map_info: If map_type is specified, this structure is initialized
+% with info from the Standard Colormap.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+%
+*/
+#define MaxStandardColormaps 7
+#define MagickXVisualColormapSize(visual_info) Min( (int) (\
+ ((visual_info->class == TrueColor) || (visual_info->class == DirectColor)) ? \
+ (int) (visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask) : \
+ visual_info->colormap_size),(1 << visual_info->depth))
+
+MagickExport XVisualInfo *
+MagickXBestVisualInfo(Display *display,
+ XStandardColormap *map_info,
+ MagickXResourceInfo *resource_info)
+{
+ char
+ *map_type,
+ *visual_type;
+
+ long
+ visual_mask;
+
+ register int
+ i;
+
+ static int
+ number_visuals;
+
+ static XVisualInfo
+ visual_template;
+
+ XVisualInfo
+ *visual_info,
+ *visual_list;
+
+ /*
+ Restrict visual search by screen number.
+ */
+ assert(display != (Display *) NULL);
+ assert(map_info != (XStandardColormap *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ map_type=resource_info->map_type;
+ visual_type=resource_info->visual_type;
+ visual_mask=VisualScreenMask;
+ visual_template.screen=XDefaultScreen(display);
+ visual_template.depth=XDefaultDepth(display,XDefaultScreen(display));
+ if (resource_info->immutable && (resource_info->colors != 0))
+ if (resource_info->colors <= (1UL << visual_template.depth))
+ visual_mask|=VisualDepthMask;
+ if (visual_type != (char *) NULL)
+ {
+ /*
+ Restrict visual search by class or visual id.
+ */
+ if (LocaleCompare("staticgray",visual_type) == 0)
+ {
+ visual_mask|=VisualClassMask;
+ visual_template.class=StaticGray;
+ }
+ else
+ if (LocaleCompare("grayscale",visual_type) == 0)
+ {
+ visual_mask|=VisualClassMask;
+ visual_template.class=GrayScale;
+ }
+ else
+ if (LocaleCompare("staticcolor",visual_type) == 0)
+ {
+ visual_mask|=VisualClassMask;
+ visual_template.class=StaticColor;
+ }
+ else
+ if (LocaleCompare("pseudocolor",visual_type) == 0)
+ {
+ visual_mask|=VisualClassMask;
+ visual_template.class=PseudoColor;
+ }
+ else
+ if (LocaleCompare("truecolor",visual_type) == 0)
+ {
+ visual_mask|=VisualClassMask;
+ visual_template.class=TrueColor;
+ }
+ else
+ if (LocaleCompare("directcolor",visual_type) == 0)
+ {
+ visual_mask|=VisualClassMask;
+ visual_template.class=DirectColor;
+ }
+ else
+ if (LocaleCompare("default",visual_type) == 0)
+ {
+ visual_mask|=VisualIDMask;
+ visual_template.visualid=XVisualIDFromVisual(
+ XDefaultVisual(display,XDefaultScreen(display)));
+ }
+ else
+ if (isdigit((int) (*visual_type)))
+ {
+ visual_mask|=VisualIDMask;
+ visual_template.visualid=
+ strtol(visual_type,(char **) NULL,0);
+ }
+ else
+ MagickError(XServerError,UnrecognizedVisualSpecifier,
+ visual_type);
+ }
+ /*
+ Get all visuals that meet our criteria so far.
+ */
+ number_visuals=0;
+ visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
+ &number_visuals);
+ visual_mask=VisualScreenMask | VisualIDMask;
+ if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
+ {
+ /*
+ Failed to get visual; try using the default visual.
+ */
+ MagickWarning(XServerWarning,UnableToGetVisual,visual_type);
+ visual_template.visualid=
+ XVisualIDFromVisual(XDefaultVisual(display,XDefaultScreen(display)));
+ visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
+ &number_visuals);
+ if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
+ return((XVisualInfo *) NULL);
+ MagickWarning(XServerWarning,UsingDefaultVisual,
+ MagickXVisualClassName(visual_list->class));
+ }
+ resource_info->color_recovery=False;
+ if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL))
+ {
+ Atom
+ map_property;
+
+ char
+ map_name[MaxTextExtent];
+
+ int
+ j,
+ number_maps,
+ status;
+
+ Window
+ root_window;
+
+ XStandardColormap
+ *map_list;
+
+ /*
+ Choose a visual associated with a standard colormap.
+ */
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ status=0;
+ if (LocaleCompare(map_type,"list") != 0)
+ {
+ /*
+ User specified Standard Colormap.
+ */
+ FormatString((char *) map_name,"RGB_%.1024s_MAP",map_type);
+ LocaleUpper(map_name);
+ map_property=XInternAtom(display,(char *) map_name,True);
+ if (map_property != (Atom) NULL)
+ status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
+ map_property);
+ }
+ else
+ {
+ static const char
+ *colormap[MaxStandardColormaps]=
+ {
+ "_HP_RGB_SMOOTH_MAP_LIST",
+ "RGB_BEST_MAP",
+ "RGB_DEFAULT_MAP",
+ "RGB_GRAY_MAP",
+ "RGB_RED_MAP",
+ "RGB_GREEN_MAP",
+ "RGB_BLUE_MAP",
+ };
+
+ /*
+ Choose a standard colormap from a list.
+ */
+ for (i=0; i < MaxStandardColormaps; i++)
+ {
+ map_property=XInternAtom(display,(char *) colormap[i],True);
+ if (map_property == (Atom) NULL)
+ continue;
+ status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
+ map_property);
+ if (status != 0)
+ break;
+ }
+ resource_info->color_recovery=(i == 0); /* _HP_RGB_SMOOTH_MAP_LIST */
+ }
+ if (status == 0)
+ {
+ MagickError(XServerError,UnableToGetStandardColormap,map_type);
+ return((XVisualInfo *) NULL);
+ }
+ /*
+ Search all Standard Colormaps and visuals for ids that match.
+ */
+ *map_info=map_list[0];
+#if !defined(PRE_R4_ICCCM)
+ visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual);
+ for (i=0; i < number_maps; i++)
+ for (j=0; j < number_visuals; j++)
+ if (map_list[i].visualid ==
+ XVisualIDFromVisual(visual_list[j].visual))
+ {
+ *map_info=map_list[i];
+ visual_template.visualid=
+ XVisualIDFromVisual(visual_list[j].visual);
+ break;
+ }
+ if (map_info->visualid != visual_template.visualid)
+ {
+ MagickError(XServerError,UnableToMatchVisualToStandardColormap,
+ map_type);
+ return((XVisualInfo *) NULL);
+ }
+#endif
+ if (map_info->colormap == (Colormap) NULL)
+ {
+ MagickError(XServerError,StandardColormapIsNotInitialized,map_type);
+ return((XVisualInfo *) NULL);
+ }
+ (void) XFree((void *) map_list);
+ }
+ else
+ {
+ static const unsigned int
+ rank[]=
+ {
+ StaticGray,
+ GrayScale,
+ StaticColor,
+ DirectColor,
+ TrueColor,
+ PseudoColor
+ };
+
+ XVisualInfo
+ *p;
+
+ /*
+ Pick one visual that displays the most simultaneous colors.
+ */
+ visual_info=visual_list;
+ p=visual_list;
+ for (i=1; i < number_visuals; i++)
+ {
+ p++;
+ if (MagickXVisualColormapSize(p) > MagickXVisualColormapSize(visual_info))
+ visual_info=p;
+ else
+ if (MagickXVisualColormapSize(p) == MagickXVisualColormapSize(visual_info))
+ if (rank[p->class] > rank[visual_info->class])
+ visual_info=p;
+ }
+ visual_template.visualid=XVisualIDFromVisual(visual_info->visual);
+ }
+ (void) XFree((void *) visual_list);
+ /*
+ Retrieve only one visual by its screen & id number.
+ */
+ visual_info=XGetVisualInfo(display,visual_mask,&visual_template,
+ &number_visuals);
+ if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL))
+ return((XVisualInfo *) NULL);
+ return(visual_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X C h e c k R e f r e s h W i n d o w s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXCheckRefreshWindows checks the X server for exposure events
+% for a particular window and updates the area associated with the exposure
+% event.
+%
+% The format of the MagickXCheckRefreshWindows method is:
+%
+% void MagickXCheckRefreshWindows(Display *display,
+% MagickXWindows *windows)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+%
+*/
+MagickExport void
+MagickXCheckRefreshWindows(Display *display,MagickXWindows *windows)
+{
+ XEvent
+ event;
+
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ MagickXDelay(display,SuspendTime);
+ while (XCheckTypedWindowEvent(display,windows->command.id,Expose,&event))
+ (void) MagickXCommandWidget(display,windows,(char const **) NULL,&event);
+ while (XCheckTypedWindowEvent(display,windows->image.id,Expose,&event))
+ MagickXRefreshWindow(display,&windows->image,&event);
+ MagickXDelay(display,SuspendTime << 1);
+ while (XCheckTypedWindowEvent(display,windows->command.id,Expose,&event))
+ (void) MagickXCommandWidget(display,windows,(char const **) NULL,&event);
+ while (XCheckTypedWindowEvent(display,windows->image.id,Expose,&event))
+ MagickXRefreshWindow(display,&windows->image,&event);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X C l i e n t M e s s a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXClientMessage sends a reason to a window with XSendEvent. The
+% reason is initialized with a particular protocol type and atom.
+%
+% The format of the MagickXClientMessage function is:
+%
+% MagickXClientMessage(display,window,protocol,reason,timestamp)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a Window structure.
+%
+% o protocol: Specifies an atom value.
+%
+% o reason: Specifies an atom value which is the reason to send.
+%
+% o timestamp: Specifies a value of type Time.
+%
+%
+*/
+MagickExport void
+MagickXClientMessage(Display *display,const Window window,
+ const Atom protocol,const Atom reason,const Time timestamp)
+{
+ XClientMessageEvent
+ client_event;
+
+ assert(display != (Display *) NULL);
+ client_event.type=ClientMessage;
+ client_event.window=window;
+ client_event.message_type=protocol;
+ client_event.format=32;
+ client_event.data.l[0]=(long) reason;
+ client_event.data.l[1]=(long) timestamp;
+ (void) XSendEvent(display,window,False,NoEventMask,(XEvent *) &client_event);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X C l i e n t W i n d o w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XClientWindow finds a window, at or below the specified window,
+% which has a WM_STATE property. If such a window is found, it is returned,
+% otherwise the argument window is returned.
+%
+% The format of the XClientWindow function is:
+%
+% client_window=XClientWindow(display,target_window)
+%
+% A description of each parameter follows:
+%
+% o client_window: XClientWindow returns a window, at or below the specified
+% window, which has a WM_STATE property otherwise the argument
+% target_window is returned.
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o target_window: Specifies the window to find a WM_STATE property.
+%
+%
+*/
+static Window
+MagickXClientWindow(Display *display,Window target_window)
+{
+ Atom
+ state,
+ type;
+
+ int
+ format,
+ status;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ number_items;
+
+ Window
+ client_window;
+
+ assert(display != (Display *) NULL);
+ state=XInternAtom(display,"WM_STATE",True);
+ if (state == (Atom) NULL)
+ return(target_window);
+ type=(Atom) NULL;
+ status=XGetWindowProperty(display,target_window,state,0L,0L,False,
+ (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
+ if ((status == Success) && (type != (Atom) NULL))
+ return(target_window);
+ client_window=MagickXWindowByProperty(display,target_window,state);
+ if (client_window == (Window) NULL)
+ return(target_window);
+ return(client_window);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X C o n f i g u r e I m a g e C o l o r m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXConfigureImageColormap creates a new X colormap.
+%
+% The format of the MagickXConfigureImageColormap method is:
+%
+% void MagickXConfigureImageColormap(Display *display,
+% MagickXResourceInfo *resource_info,MagickXWindows *windows,
+% Image *image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport void
+MagickXConfigureImageColormap(Display *display,
+ MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *image)
+{
+ Colormap
+ colormap;
+
+ /*
+ Make standard colormap.
+ */
+ MagickXSetCursorState(display,windows,True);
+ MagickXCheckRefreshWindows(display,windows);
+ MagickXMakeStandardColormap(display,windows->visual_info,resource_info,image,
+ windows->map_info,windows->pixel_info);
+ colormap=windows->map_info->colormap;
+ (void) XSetWindowColormap(display,windows->image.id,colormap);
+ (void) XSetWindowColormap(display,windows->command.id,colormap);
+ (void) XSetWindowColormap(display,windows->widget.id,colormap);
+ if (windows->magnify.mapped)
+ (void) XSetWindowColormap(display,windows->magnify.id,colormap);
+ if (windows->pan.mapped)
+ (void) XSetWindowColormap(display,windows->pan.id,colormap);
+ MagickXSetCursorState(display,windows,False);
+ MagickXClientMessage(display,windows->image.id,windows->im_protocols,
+ windows->im_update_colormap,CurrentTime);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X C o n s t r a i n W i n d o w P o s i t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXConstrainWindowPosition assures a window is positioned
+% within the X server boundaries.
+%
+% The format of the MagickXConstrainWindowPosition method is:
+%
+% void MagickXConstrainWindowPosition(Display *display,
+% MagickXWindowInfo *window_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o window_info: Specifies a pointer to a MagickXWindowInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXConstrainWindowPosition(Display *display,
+ MagickXWindowInfo *window_info)
+{
+ unsigned int
+ limit;
+
+ assert(display != (Display *) NULL);
+ assert(window_info != (MagickXWindowInfo *) NULL);
+ limit=XDisplayWidth(display,window_info->screen)-window_info->width;
+ if (window_info->x < 0)
+ window_info->x=0;
+ else
+ if (window_info->x > (int) limit)
+ window_info->x=limit;
+ limit=XDisplayHeight(display,window_info->screen)-window_info->height;
+ if (window_info->y < 0)
+ window_info->y=0;
+ else
+ if (window_info->y > (int) limit)
+ window_info->y=limit;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D e l a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXDelay suspends program execution for the number of
+% milliseconds specified.
+%
+% The format of the Delay method is:
+%
+% void MagickXDelay(Display *display,const unsigned long milliseconds)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o milliseconds: Specifies the number of milliseconds to delay before
+% returning.
+%
+%
+*/
+MagickExport void
+MagickXDelay(Display *display,const unsigned long milliseconds)
+{
+ assert(display != (Display *) NULL);
+ (void) XFlush(display);
+ if (milliseconds == 0)
+ return;
+#if defined(MSWINDOWS)
+ Sleep(milliseconds);
+#elif defined(HAVE_SELECT)
+ {
+ struct timeval
+ timer;
+
+ timer.tv_sec=(long) milliseconds/1000;
+ timer.tv_usec=(long) (milliseconds % 1000)*1000;
+ (void) select(0,(XFD_SET *) NULL,(XFD_SET *) NULL,(XFD_SET *) NULL,&timer);
+ }
+#elif defined(HAVE_POLL)
+ (void) poll((struct pollfd *) NULL,0,(int) milliseconds);
+#else
+# error "Time delay method not defined."
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D e s t r o y R e s o u r c e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXDestroyResourceInfo() frees memory associated with the
+% MagickXResourceInfo structure.
+%
+% The format of the MagickXDestroyResourceInfo method is:
+%
+% void MagickXDestroyResourceInfo(MagickXResourceInfo *resource_info)
+%
+% A description of each parameter follows:
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXDestroyResourceInfo(MagickXResourceInfo *resource_info)
+{
+ MagickFreeMemory(resource_info->image_geometry);
+ if (resource_info->image_info != (ImageInfo *) NULL)
+ {
+ DestroyImageInfo(resource_info->image_info);
+ resource_info->image_info=(ImageInfo *) NULL;
+ }
+ if (resource_info->quantize_info != (QuantizeInfo *) NULL)
+ {
+ DestroyQuantizeInfo(resource_info->quantize_info);
+ resource_info->quantize_info=(QuantizeInfo *) NULL;
+ }
+ MagickFreeMemory(resource_info->client_name);
+ MagickFreeMemory(resource_info->name);
+ (void) memset((void *) resource_info,0,sizeof(MagickXResourceInfo));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D e s t r o y W i n d o w C o l o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXDestroyWindowColors frees X11 color resources previously
+% saved on a window by MagickXRetainWindowColors or programs like xsetroot.
+%
+% The format of the MagickXDestroyWindowColors method is:
+%
+% void MagickXDestroyWindowColors(Display *display,Window window)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a Window structure.
+%
+%
+*/
+MagickExport void
+MagickXDestroyWindowColors(Display *display,Window window)
+{
+ Atom
+ property,
+ type;
+
+ int
+ format,
+ status;
+
+ unsigned char
+ *data;
+
+ unsigned long
+ after,
+ length;
+
+ /*
+ If there are previous resources on the root window, destroy them.
+ */
+ assert(display != (Display *) NULL);
+ property=XInternAtom(display,"_XSETROOT_ID",False);
+ if (property == (Atom) NULL)
+ {
+ MagickError(XServerError,UnableToCreateProperty,"_XSETROOT_ID");
+ return;
+ }
+ status=XGetWindowProperty(display,window,property,0L,1L,True,
+ (Atom) AnyPropertyType,&type,&format,&length,&after,&data);
+ if (status != Success)
+ return;
+ if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
+ {
+ (void) XKillClient(display,(XID) (*((Pixmap *) data)));
+ (void) XDeleteProperty(display,window,property);
+ }
+ if (type != None)
+ (void) XFree((void *) data);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D i s p l a y I m a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXDisplayImageInfo displays information about an X image.
+%
+% The format of the MagickXDisplayImageInfo method is:
+%
+% void MagickXDisplayImageInfo(Display *display,
+% const MagickXResourceInfo *resource_info,MagickXWindows *windows,
+% Image *undo_image,Image *image)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o undo_image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport void
+MagickXDisplayImageInfo(Display *display,
+ const MagickXResourceInfo *resource_info,
+ MagickXWindows *windows,Image *undo_image,
+ Image *image)
+{
+ char
+ filename[MaxTextExtent],
+ *text,
+ **textlist;
+
+ FILE
+ *file;
+
+ long
+ bytes;
+
+ register long
+ i;
+
+ size_t
+ length;
+
+ unsigned int
+ levels;
+
+ unsigned long
+ number_pixels;
+
+ /*
+ Write info about the X server to a file.
+ */
+ assert(display != (Display *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ assert(image != (Image *) NULL);
+ file=AcquireTemporaryFileStream(filename,TextFileIOMode);
+ if (file == (FILE *) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"Unable to create temporary file",
+ filename);
+ return;
+ }
+ if (resource_info->gamma_correct)
+ if (resource_info->display_gamma != (char *) NULL)
+ (void) fprintf(file,"Display\n gamma: %.1024s\n\n",
+ resource_info->display_gamma);
+ /*
+ Write info about the X image to a file.
+ */
+ (void) fprintf(file,"X\n visual: %.1024s\n",
+ MagickXVisualClassName(windows->image.storage_class));
+ (void) fprintf(file," depth: %d\n",windows->image.ximage->depth);
+ if (windows->visual_info->colormap_size != 0)
+ (void) fprintf(file," colormap size: %d\n",
+ windows->visual_info->colormap_size);
+ if (resource_info->colormap== SharedColormap)
+ (void) fprintf(file," colormap type: Shared\n");
+ else
+ (void) fprintf(file," colormap type: Private\n");
+ (void) fprintf(file," geometry: %dx%d\n",windows->image.ximage->width,
+ windows->image.ximage->height);
+ if (windows->image.crop_geometry != (char *) NULL)
+ (void) fprintf(file," crop geometry: %.1024s\n",
+ windows->image.crop_geometry);
+ if (windows->image.pixmap == (Pixmap) NULL)
+ (void) fprintf(file," type: X Image\n");
+ else
+ (void) fprintf(file," type: Pixmap\n");
+ if (windows->image.shape)
+ (void) fprintf(file," non-rectangular shape: True\n");
+ else
+ (void) fprintf(file," non-rectangular shape: False\n");
+ if (windows->image.shared_memory)
+ (void) fprintf(file," shared memory: True\n");
+ else
+ (void) fprintf(file," shared memory: False\n");
+ (void) fprintf(file,"\n");
+ if (resource_info->font != (char *) NULL)
+ (void) fprintf(file,"Font: %.1024s\n\n",resource_info->font);
+ if (resource_info->text_font != (char *) NULL)
+ (void) fprintf(file,"Text font: %.1024s\n\n",resource_info->text_font);
+ /*
+ Write info about the undo cache to a file.
+ */
+ bytes=0;
+ for (levels=0; undo_image != (Image *) NULL; levels++)
+ {
+ number_pixels=undo_image->list->columns*undo_image->list->rows;
+ bytes+=number_pixels*sizeof(PixelPacket);
+ undo_image=undo_image->previous;
+ }
+ (void) fprintf(file,"Undo Edit Cache\n levels: %u\n",levels);
+ (void) fprintf(file," bytes: %lumb\n",(bytes+(1 << 19)) >> 20);
+ (void) fprintf(file," limit: %lumb\n\n",resource_info->undo_cache);
+ /*
+ Write info about the image to a file.
+ */
+ (void) DescribeImage(image,file,True);
+ (void) fclose(file);
+ text=(char *) FileToBlob(filename,&length,&image->exception);
+ (void) LiberateTemporaryFile(filename);
+ if (text == (char *) NULL)
+ {
+ MagickXNoticeWidget(display,windows,"MemoryAllocationFailed",
+ "UnableToDisplayImageInfo");
+ return;
+ }
+ textlist=StringToList(text);
+ if (textlist != (char **) NULL)
+ {
+ char
+ title[MaxTextExtent];
+
+ /*
+ Display information about the image in the Text View widget.
+ */
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ FormatString(title,"Image Info: %.1024s",image->filename);
+ MagickXTextViewWidget(display,resource_info,windows,True,title,
+ (char const **) textlist);
+ for (i=0; textlist[i] != (char *) NULL; i++)
+ MagickFreeMemory(textlist[i]);
+ MagickFreeMemory(textlist);
+ }
+ MagickFreeMemory(text);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X D i t h e r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XDitherImage dithers the reference image as required by the HP
+% Color Recovery algorithm. The color values are quantized to 3 bits of red
+% and green, and 2 bits of blue (3/3/2) and can be used as indices into a
+% 8-bit X standard colormap.
+%
+% The format of the XDitherImage method is:
+%
+% void XDitherImage(Image *image,XImage *ximage)
+%
+% A description of each parameter follows:
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o ximage: Specifies a pointer to a XImage structure; returned from
+% XCreateImage.
+%
+%
+*/
+static void MagickXDitherImage(Image *image,XImage *ximage)
+{
+ static const short int
+ dither_red[2][16]=
+ {
+ {-16, 4, -1, 11,-14, 6, -3, 9,-15, 5, -2, 10,-13, 7, -4, 8},
+ { 15, -5, 0,-12, 13, -7, 2,-10, 14, -6, 1,-11, 12, -8, 3, -9}
+ },
+ dither_green[2][16]=
+ {
+ { 11,-15, 7, -3, 8,-14, 4, -2, 10,-16, 6, -4, 9,-13, 5, -1},
+ {-12, 14, -8, 2, -9, 13, -5, 1,-11, 15, -7, 3,-10, 12, -6, 0}
+ },
+ dither_blue[2][16]=
+ {
+ { -3, 9,-13, 7, -1, 11,-15, 5, -4, 8,-14, 6, -2, 10,-16, 4},
+ { 2,-10, 12, -8, 0,-12, 14, -6, 3, -9, 13, -7, 1,-11, 15, -5}
+ };
+
+ PixelPacket
+ color;
+
+ int
+ y;
+
+ long
+ value;
+
+ register char
+ *q;
+
+ register const PixelPacket
+ *p;
+
+ register int
+ i,
+ j,
+ x;
+
+ unsigned int
+ scanline_pad;
+
+ register unsigned long
+ pixel;
+
+ unsigned char
+ *blue_map[2][16],
+ *green_map[2][16],
+ *red_map[2][16];
+
+ /*
+ Allocate and initialize dither maps.
+ */
+ for (i=0; i < 2; i++)
+ for (j=0; j < 16; j++)
+ {
+ red_map[i][j]=MagickAllocateArray(unsigned char *,256,sizeof(unsigned char));
+ green_map[i][j]=MagickAllocateArray(unsigned char *,
+ 256,sizeof(unsigned char));
+ blue_map[i][j]=MagickAllocateArray(unsigned char *,256,sizeof(unsigned char));
+ if ((red_map[i][j] == (unsigned char *) NULL) ||
+ (green_map[i][j] == (unsigned char *) NULL) ||
+ (blue_map[i][j] == (unsigned char *) NULL))
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToDitherImage);
+ return;
+ }
+ }
+ /*
+ Initialize dither tables.
+ */
+ for (i=0; i < 2; i++)
+ for (j=0; j < 16; j++)
+ for (x=0; x < 256; x++)
+ {
+ value=x-16;
+ if (x < 48)
+ value=x/2+8;
+ value+=dither_red[i][j];
+ red_map[i][j][x]=(unsigned char)
+ ((value < 0) ? 0 : (value > 255) ? 255 : value);
+ value=x-16;
+ if (x < 48)
+ value=x/2+8;
+ value+=dither_green[i][j];
+ green_map[i][j][x]=(unsigned char)
+ ((value < 0) ? 0 : (value > 255) ? 255 : value);
+ value=x-32;
+ if (x < 112)
+ value=x/2+24;
+ value+=(dither_blue[i][j] << 1);
+ blue_map[i][j][x]=(unsigned char)
+ ((value < 0) ? 0 : (value > 255) ? 255 : value);
+ }
+ /*
+ Dither image.
+ */
+ scanline_pad=ximage->bytes_per_line-
+ ((ximage->width*ximage->bits_per_pixel) >> 3);
+ i=0;
+ j=0;
+ q=ximage->data;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ color.red=red_map[i][j][ScaleQuantumToChar(p->red)] << 8;
+ color.green=green_map[i][j][ScaleQuantumToChar(p->green)] << 8;
+ color.blue=blue_map[i][j][ScaleQuantumToChar(p->blue)] << 8;
+ pixel=(unsigned long) ((color.red & 0xe0) |
+ ((unsigned long) (color.green & 0xe0) >> 3) |
+ ((unsigned long) (color.blue & 0xc0) >> 6));
+ *q++=(unsigned char) pixel;
+ p++;
+ j++;
+ if (j == 16)
+ j=0;
+ }
+ q+=scanline_pad;
+ i++;
+ if (i == 2)
+ i=0;
+ }
+ /*
+ Free allocated memory.
+ */
+ for (i=0; i < 2; i++)
+ for (j=0; j < 16; j++)
+ {
+ MagickFreeMemory(green_map[i][j]);
+ MagickFreeMemory(blue_map[i][j]);
+ MagickFreeMemory(red_map[i][j]);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X D r a w I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXDrawImage draws a line on the image.
+%
+% The format of the MagickXDrawImage method is:
+%
+% status=MagickXDrawImage(display,pixel,draw_info,image)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXDrawImage returns True if the image is
+% successfully drawd with text. False is returned is there is a
+% memory shortage.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o pixel: Specifies a pointer to a MagickXPixelInfo structure.
+%
+% o draw_info: Specifies a pointer to a MagickXDrawInfo structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+%
+*/
+MagickExport unsigned int
+MagickXDrawImage(Display *display,const MagickXPixelInfo *pixel,
+ MagickXDrawInfo *draw_info,Image *image)
+{
+ GC
+ draw_context;
+
+ Image
+ *draw_image;
+
+ int
+ x,
+ y;
+
+ Pixmap
+ draw_pixmap;
+
+ register PixelPacket
+ *q;
+
+ unsigned int
+ depth,
+ height,
+ matte,
+ width;
+
+ Window
+ root_window;
+
+ XGCValues
+ context_values;
+
+ XImage
+ *draw_ximage;
+
+ /*
+ Initialize drawd image.
+ */
+ assert(display != (Display *) NULL);
+ assert(pixel != (MagickXPixelInfo *) NULL);
+ assert(draw_info != (MagickXDrawInfo *) NULL);
+ assert(image != (Image *) NULL);
+ /*
+ Initialize drawd pixmap.
+ */
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ depth=XDefaultDepth(display,XDefaultScreen(display));
+ draw_pixmap=XCreatePixmap(display,root_window,draw_info->width,
+ draw_info->height,(int) depth);
+ if (draw_pixmap == (Pixmap) NULL)
+ return(False);
+ /*
+ Initialize graphics info.
+ */
+ context_values.background=(unsigned long) (~0);
+ context_values.foreground=0;
+ context_values.line_width=draw_info->line_width;
+ draw_context=XCreateGC(display,root_window,GCBackground | GCForeground |
+ GCLineWidth,&context_values);
+ if (draw_context == (GC) NULL)
+ return(False);
+ /*
+ Clear pixmap.
+ */
+ (void) XFillRectangle(display,draw_pixmap,draw_context,0,0,draw_info->width,
+ draw_info->height);
+ /*
+ Draw line to pixmap.
+ */
+ (void) XSetBackground(display,draw_context,0);
+ (void) XSetForeground(display,draw_context,(unsigned long) (~0));
+ (void) XSetFillStyle(display,draw_context,FillOpaqueStippled);
+ (void) XSetStipple(display,draw_context,draw_info->stipple);
+ switch (draw_info->element)
+ {
+ case PointElement:
+ default:
+ {
+ (void) XDrawLines(display,draw_pixmap,draw_context,
+ draw_info->coordinate_info,draw_info->number_coordinates,
+ CoordModeOrigin);
+ break;
+ }
+ case LineElement:
+ {
+ (void) XDrawLine(display,draw_pixmap,draw_context,draw_info->line_info.x1,
+ draw_info->line_info.y1,draw_info->line_info.x2,
+ draw_info->line_info.y2);
+ break;
+ }
+ case RectangleElement:
+ {
+ (void) XDrawRectangle(display,draw_pixmap,draw_context,
+ (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
+ (unsigned int) draw_info->rectangle_info.width,
+ (unsigned int) draw_info->rectangle_info.height);
+ break;
+ }
+ case FillRectangleElement:
+ {
+ (void) XFillRectangle(display,draw_pixmap,draw_context,
+ (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
+ (unsigned int) draw_info->rectangle_info.width,
+ (unsigned int) draw_info->rectangle_info.height);
+ break;
+ }
+ case CircleElement:
+ case EllipseElement:
+ {
+ (void) XDrawArc(display,draw_pixmap,draw_context,
+ (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
+ (unsigned int) draw_info->rectangle_info.width,
+ (unsigned int) draw_info->rectangle_info.height,0,360*64);
+ break;
+ }
+ case FillCircleElement:
+ case FillEllipseElement:
+ {
+ (void) XFillArc(display,draw_pixmap,draw_context,
+ (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
+ (unsigned int) draw_info->rectangle_info.width,
+ (unsigned int) draw_info->rectangle_info.height,0,360*64);
+ break;
+ }
+ case PolygonElement:
+ {
+ XPoint
+ *coordinate_info;
+
+ coordinate_info=draw_info->coordinate_info;
+ (void) XDrawLines(display,draw_pixmap,draw_context,coordinate_info,
+ draw_info->number_coordinates,CoordModeOrigin);
+ (void) XDrawLine(display,draw_pixmap,draw_context,
+ coordinate_info[draw_info->number_coordinates-1].x,
+ coordinate_info[draw_info->number_coordinates-1].y,
+ coordinate_info[0].x,coordinate_info[0].y);
+ break;
+ }
+ case FillPolygonElement:
+ {
+ (void) XFillPolygon(display,draw_pixmap,draw_context,
+ draw_info->coordinate_info,draw_info->number_coordinates,Complex,
+ CoordModeOrigin);
+ break;
+ }
+ }
+ (void) XFreeGC(display,draw_context);
+ /*
+ Initialize X image.
+ */
+ draw_ximage=XGetImage(display,draw_pixmap,0,0,draw_info->width,
+ draw_info->height,AllPlanes,ZPixmap);
+ if (draw_ximage == (XImage *) NULL)
+ return(False);
+ (void) XFreePixmap(display,draw_pixmap);
+ /*
+ Initialize draw image.
+ */
+ draw_image=AllocateImage((ImageInfo *) NULL);
+ if (draw_image == (Image *) NULL)
+ return(False);
+ draw_image->columns=draw_info->width;
+ draw_image->rows=draw_info->height;
+ /*
+ Transfer drawn X image to image.
+ */
+ width=(unsigned int) image->columns;
+ height=(unsigned int) image->rows;
+ x=0;
+ y=0;
+ (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
+ (void) AcquireOnePixelByReference(image,&draw_image->background_color,x,y,&image->exception);
+ (void) SetImageType(draw_image,TrueColorMatteType);
+ for (y=0; y < (long) draw_image->rows; y++)
+ {
+ q=SetImagePixels(draw_image,0,y,draw_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) draw_image->columns; x++)
+ {
+ if (XGetPixel(draw_ximage,x,y) == 0)
+ {
+ /*
+ Set this pixel to the background color.
+ */
+ *q=draw_image->background_color;
+ q->opacity=(Quantum) (draw_info->stencil == OpaqueStencil ?
+ TransparentOpacity : OpaqueOpacity);
+ }
+ else
+ {
+ /*
+ Set this pixel to the pen color.
+ */
+ q->red=ScaleShortToQuantum(pixel->pen_color.red);
+ q->green=ScaleShortToQuantum(pixel->pen_color.green);
+ q->blue=ScaleShortToQuantum(pixel->pen_color.blue);
+ q->opacity=(Quantum) (draw_info->stencil == OpaqueStencil ?
+ OpaqueOpacity : TransparentOpacity);
+ }
+ q++;
+ }
+ if (!SyncImagePixels(draw_image))
+ break;
+ }
+ XDestroyImage(draw_ximage);
+ draw_ximage=(XImage *) NULL;
+ /*
+ Determine draw geometry.
+ */
+ (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
+ if ((width != (unsigned int) draw_image->columns) ||
+ (height != (unsigned int) draw_image->rows))
+ {
+ char
+ image_geometry[MaxTextExtent];
+
+ /*
+ Scale image.
+ */
+ FormatString(image_geometry,"%ux%u",width,height);
+ TransformImage(&draw_image,(char *) NULL,image_geometry);
+ }
+ if (draw_info->degrees != 0.0)
+ {
+ double
+ normalized_degrees;
+
+ Image
+ *rotate_image;
+
+ int
+ rotations;
+
+ /*
+ Rotate image.
+ */
+ rotate_image=RotateImage(draw_image,draw_info->degrees,&image->exception);
+ if (rotate_image == (Image *) NULL)
+ return(False);
+ DestroyImage(draw_image);
+ draw_image=rotate_image;
+ /*
+ Annotation is relative to the degree of rotation.
+ */
+ normalized_degrees=draw_info->degrees;
+ while (normalized_degrees < -45.0)
+ normalized_degrees+=360.0;
+ for (rotations=0; normalized_degrees > 45.0; rotations++)
+ normalized_degrees-=90.0;
+ switch (rotations % 4)
+ {
+ default:
+ case 0:
+ break;
+ case 1:
+ {
+ /*
+ Rotate 90 degrees.
+ */
+ x=x-(int) draw_image->columns/2;
+ y=y+(int) draw_image->columns/2;
+ break;
+ }
+ case 2:
+ {
+ /*
+ Rotate 180 degrees.
+ */
+ x=x-(int) draw_image->columns;
+ break;
+ }
+ case 3:
+ {
+ /*
+ Rotate 270 degrees.
+ */
+ x=x-(int) draw_image->columns/2;
+ y=y-(int) (draw_image->rows-(draw_image->columns/2));
+ break;
+ }
+ }
+ }
+ /*
+ Composite text onto the image.
+ */
+ for (y=0; y < (long) draw_image->rows; y++)
+ {
+ q=GetImagePixels(draw_image,0,y,draw_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) draw_image->columns; x++)
+ {
+ if (q->opacity != TransparentOpacity)
+ q->opacity=OpaqueOpacity;
+ q++;
+ }
+ if (!SyncImagePixels(draw_image))
+ break;
+ }
+ (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
+ if (draw_info->stencil == TransparentStencil)
+ (void) CompositeImage(image,CopyOpacityCompositeOp,draw_image,x,y);
+ else
+ {
+ matte=image->matte;
+ (void) CompositeImage(image,OverCompositeOp,draw_image,x,y);
+ image->matte=matte;
+ }
+ DestroyImage(draw_image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X E r r o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXError ignores BadWindow errors for XQueryTree and
+% XGetWindowAttributes, and ignores BadDrawable errors for XGetGeometry, and
+% ignores BadValue errors for XQueryColor. It returns False in those cases.
+% Otherwise it returns True.
+%
+% The format of the MagickXError function is:
+%
+% MagickXError(display,error)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o error: Specifies the error event.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+MagickExport int
+MagickXError(Display *display,XErrorEvent *error)
+{
+ assert(display != (Display *) NULL);
+ assert(error != (XErrorEvent *) NULL);
+ xerror_alert=True;
+ switch (error->request_code)
+ {
+ case X_GetGeometry:
+ {
+ if (error->error_code == BadDrawable)
+ return(False);
+ break;
+ }
+ case X_GetWindowAttributes:
+ case X_QueryTree:
+ {
+ if (error->error_code == BadWindow)
+ return(False);
+ break;
+ }
+ case X_QueryColors:
+ {
+ if (error->error_code == BadValue)
+ return(False);
+ break;
+ }
+ }
+ return(True);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X F r e e R e s o u r c e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXFreeResources frees X11 resources.
+%
+% The format of the MagickXFreeResources method is:
+%
+% void MagickXFreeResources(Display *display,XVisualInfo *visual_info,
+% XStandardColormap *map_info,MagickXPixelInfo *pixel,
+% XFontStruct *font_info,MagickXResourceInfo *resource_info,
+% MagickXWindowInfo *window_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
+% returned from XGetVisualInfo.
+%
+% o map_info: If map_type is specified, this structure is initialized
+% with info from the Standard Colormap.
+%
+% o pixel: Specifies a pointer to a MagickXPixelInfo structure.
+%
+% o font_info: Specifies a pointer to a XFontStruct structure.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXFreeResources(Display *display,
+ XVisualInfo *visual_info,
+ XStandardColormap *map_info,
+ MagickXPixelInfo *pixel,
+ XFontStruct *font_info,
+ MagickXResourceInfo *resource_info,
+ MagickXWindowInfo *window_info)
+{
+ assert(display != (Display *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ if (window_info != (MagickXWindowInfo *) NULL)
+ {
+ /*
+ Free X image.
+ */
+ if (window_info->ximage != (XImage *) NULL)
+ {
+ XDestroyImage(window_info->ximage);
+ window_info->ximage=(XImage *) NULL;
+ }
+ if (window_info->id != (Window) NULL)
+ {
+ /*
+ Free destroy window and free cursors.
+ */
+ if (window_info->id != XRootWindow(display,visual_info->screen))
+ (void) XDestroyWindow(display,window_info->id);
+ if (window_info->annotate_context != (GC) NULL)
+ (void) XFreeGC(display,window_info->annotate_context);
+ if (window_info->highlight_context != (GC) NULL)
+ (void) XFreeGC(display,window_info->highlight_context);
+ if (window_info->widget_context != (GC) NULL)
+ (void) XFreeGC(display,window_info->widget_context);
+ (void) XFreeCursor(display,window_info->cursor);
+ (void) XFreeCursor(display,window_info->busy_cursor);
+ }
+ }
+ /*
+ Free font.
+ */
+ if (font_info != (XFontStruct *) NULL)
+ (void) XFreeFont(display,font_info);
+ if (map_info != (XStandardColormap *) NULL)
+ {
+ /*
+ Free X Standard Colormap.
+ */
+ if (resource_info->map_type == (char *) NULL)
+ (void) MagickXFreeStandardColormap(display,visual_info,map_info,pixel);
+ (void) XFree((void *) map_info);
+ }
+ /*
+ Free X visual info.
+ */
+ if (visual_info != (XVisualInfo *) NULL)
+ (void) XFree((void *) visual_info);
+ if (resource_info->close_server)
+ (void) XCloseDisplay(display);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X F r e e S t a n d a r d C o l o r m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXFreeStandardColormap frees an X11 colormap.
+%
+% The format of the MagickXFreeStandardColormap method is:
+%
+% void MagickXFreeStandardColormap(Display *display,
+% const XVisualInfo *visual_info,XStandardColormap *map_info,
+% MagickXPixelInfo *pixel)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
+% returned from XGetVisualInfo.
+%
+% o map_info: If map_type is specified, this structure is initialized
+% with info from the Standard Colormap.
+%
+% o pixel: Specifies a pointer to a MagickXPixelInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXFreeStandardColormap(Display *display,
+ const XVisualInfo *visual_info,
+ XStandardColormap *map_info,
+ MagickXPixelInfo *pixel)
+{
+ /*
+ Free colormap.
+ */
+ assert(display != (Display *) NULL);
+ assert(visual_info != (XVisualInfo *) NULL);
+ assert(map_info != (XStandardColormap *) NULL);
+ (void) XFlush(display);
+ if (map_info->colormap != (Colormap) NULL)
+ {
+ if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
+ (void) XFreeColormap(display,map_info->colormap);
+ else
+ if (pixel != (MagickXPixelInfo *) NULL)
+ if ((visual_info->class != TrueColor) &&
+ (visual_info->class != DirectColor))
+ (void) XFreeColors(display,map_info->colormap,pixel->pixels,
+ (int) pixel->colors,0);
+ }
+ map_info->colormap=(Colormap) NULL;
+ if (pixel != (MagickXPixelInfo *) NULL)
+ {
+ if (pixel->pixels != (unsigned long *) NULL)
+ MagickFreeMemory(pixel->pixels);
+ pixel->pixels=(unsigned long *) NULL;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t A n n o t a t e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetAnnotateInfo initializes the AnnotateInfo structure.
+%
+% The format of the MagickXGetAnnotateInfo method is:
+%
+% void MagickXGetAnnotateInfo(MagickXAnnotateInfo *annotate_info)
+%
+% A description of each parameter follows:
+%
+% o annotate_info: Specifies a pointer to a MagickXAnnotateInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXGetAnnotateInfo(MagickXAnnotateInfo *annotate_info)
+{
+ /*
+ Initialize annotate structure.
+ */
+ assert(annotate_info != (MagickXAnnotateInfo *) NULL);
+ annotate_info->x=0;
+ annotate_info->y=0;
+ annotate_info->width=0;
+ annotate_info->height=0;
+ annotate_info->stencil=ForegroundStencil;
+ annotate_info->degrees=0.0;
+ annotate_info->font_info=(XFontStruct *) NULL;
+ annotate_info->text=(char *) NULL;
+ *annotate_info->geometry='\0';
+ annotate_info->previous=(MagickXAnnotateInfo *) NULL;
+ annotate_info->next=(MagickXAnnotateInfo *) NULL;
+ (void) XSupportsLocale();
+ (void) XSetLocaleModifiers("");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t M a p I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetMapInfo initializes the XStandardColormap structure.
+%
+% The format of the XStandardColormap method is:
+%
+% void MagickXGetMapInfo(const XVisualInfo *visual_info,
+% const Colormap colormap,XStandardColormap *map_info)
+%
+% A description of each parameter follows:
+%
+% o colormap: Specifies the ID of the X server colormap.
+%
+% o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
+% returned from XGetVisualInfo.
+%
+% o map_info: Specifies a pointer to a X11 XStandardColormap structure.
+%
+%
+*/
+MagickExport void
+MagickXGetMapInfo(const XVisualInfo *visual_info,
+ const Colormap colormap,XStandardColormap *map_info)
+{
+ /*
+ Initialize map info.
+ */
+ assert(visual_info != (XVisualInfo *) NULL);
+ assert(map_info != (XStandardColormap *) NULL);
+ map_info->colormap=colormap;
+ map_info->red_max=visual_info->red_mask;
+ map_info->red_mult=map_info->red_max != 0 ? 1 : 0;
+ if (map_info->red_max != 0)
+ while ((map_info->red_max & 0x01) == 0)
+ {
+ map_info->red_max>>=1;
+ map_info->red_mult<<=1;
+ }
+ map_info->green_max=visual_info->green_mask;
+ map_info->green_mult=map_info->green_max != 0 ? 1 : 0;
+ if (map_info->green_max != 0)
+ while ((map_info->green_max & 0x01) == 0)
+ {
+ map_info->green_max>>=1;
+ map_info->green_mult<<=1;
+ }
+ map_info->blue_max=visual_info->blue_mask;
+ map_info->blue_mult=map_info->blue_max != 0 ? 1 : 0;
+ if (map_info->blue_max != 0)
+ while ((map_info->blue_max & 0x01) == 0)
+ {
+ map_info->blue_max>>=1;
+ map_info->blue_mult<<=1;
+ }
+ map_info->base_pixel=0;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t I m a g e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetImportInfo initializes the MagickXImportInfo structure.
+%
+% The format of the MagickXGetImportInfo method is:
+%
+% void MagickXGetImportInfo(MagickXImportInfo *ximage_info)
+%
+% A description of each parameter follows:
+%
+% o ximage_info: Specifies a pointer to a ImageInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXGetImportInfo(MagickXImportInfo *ximage_info)
+{
+ assert(ximage_info != (MagickXImportInfo *) NULL);
+ ximage_info->frame=False;
+ ximage_info->borders=False;
+ ximage_info->screen=False;
+ ximage_info->descend=True;
+ ximage_info->silent=False;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t P i x e l P a c k e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetPixelPacket initializes the PixelPacket structure.
+%
+% The format of the MagickXGetPixelPacket method is:
+%
+% void MagickXGetPixelPacket(Display *display,
+% const XVisualInfo *visual_info,const XStandardColormap *map_info,
+% const MagickXResourceInfo *resource_info,Image *image,
+% MagickXPixelInfo *pixel)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
+% returned from XGetVisualInfo.
+%
+% o map_info: If map_type is specified, this structure is initialized
+% with info from the Standard Colormap.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o pixel: Specifies a pointer to a MagickXPixelInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXGetPixelPacket(Display *display,
+ const XVisualInfo *visual_info,
+ const XStandardColormap *map_info,
+ const MagickXResourceInfo *resource_info,
+ Image *image,
+ MagickXPixelInfo *pixel)
+{
+ static const char
+ *PenColors[MaxNumberPens]=
+ {
+ "#000000000000", /* black */
+ "#00000000ffff", /* blue */
+ "#0000ffffffff", /* cyan */
+ "#0000ffff0000", /* green */
+ "#bdbdbdbdbdbd", /* gray */
+ "#ffff00000000", /* red */
+ "#ffff0000ffff", /* magenta */
+ "#ffffffff0000", /* yellow */
+ "#ffffffffffff", /* white */
+ "#bdbdbdbdbdbd", /* gray */
+ "#bdbdbdbdbdbd" /* gray */
+ };
+
+ Colormap
+ colormap;
+
+ int
+ status;
+
+ register long
+ i;
+
+ unsigned int
+ packets;
+
+ /*
+ Initialize pixel info.
+ */
+ assert(display != (Display *) NULL);
+ assert(visual_info != (XVisualInfo *) NULL);
+ assert(map_info != (XStandardColormap *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(pixel != (MagickXPixelInfo *) NULL);
+ pixel->colors=0;
+ if (image != (Image *) NULL)
+ if (image->storage_class == PseudoClass)
+ pixel->colors=image->colors;
+ packets=Max((int) pixel->colors,visual_info->colormap_size)+MaxNumberPens;
+ if (pixel->pixels != (unsigned long *) NULL)
+ MagickFreeMemory(pixel->pixels);
+ pixel->pixels=
+ MagickAllocateArray(unsigned long *,packets,sizeof(unsigned long));
+ if (pixel->pixels == (unsigned long *) NULL)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(XServerFatalError,UnableToGetPixelInfo));
+ /*
+ Set foreground color.
+ */
+ colormap=map_info->colormap;
+ (void) XParseColor(display,colormap,(char *) ForegroundColor,
+ &pixel->foreground_color);
+ status=XParseColor(display,colormap,resource_info->foreground_color,
+ &pixel->foreground_color);
+ if (status == 0)
+ MagickError(XServerError,ColorIsNotKnownToServer,
+ resource_info->foreground_color);
+ pixel->foreground_color.pixel=
+ MagickXStandardPixel(map_info,&pixel->foreground_color);
+ pixel->foreground_color.flags=DoRed | DoGreen | DoBlue;
+ /*
+ Set background color.
+ */
+ (void) XParseColor(display,colormap,"#d6d6d6d6d6d6",
+ &pixel->background_color);
+ status=XParseColor(display,colormap,resource_info->background_color,
+ &pixel->background_color);
+ if (status == 0)
+ MagickError(XServerError,ColorIsNotKnownToServer,
+ resource_info->background_color);
+ pixel->background_color.pixel=
+ MagickXStandardPixel(map_info,&pixel->background_color);
+ pixel->background_color.flags=DoRed | DoGreen | DoBlue;
+ /*
+ Set border color.
+ */
+ (void) XParseColor(display,colormap,(char *) BorderColor,
+ &pixel->border_color);
+ status=XParseColor(display,colormap,resource_info->border_color,
+ &pixel->border_color);
+ if (status == 0)
+ MagickError(XServerError,ColorIsNotKnownToServer,
+ resource_info->border_color);
+ pixel->border_color.pixel=MagickXStandardPixel(map_info,&pixel->border_color);
+ pixel->border_color.flags=DoRed | DoGreen | DoBlue;
+ /*
+ Set matte color.
+ */
+ pixel->matte_color=pixel->background_color;
+ if (resource_info->matte_color != (char *) NULL)
+ {
+ /*
+ Matte color is specified as a X resource or command line argument.
+ */
+ status=XParseColor(display,colormap,resource_info->matte_color,
+ &pixel->matte_color);
+ if (status == 0)
+ MagickError(XServerError,ColorIsNotKnownToServer,
+ resource_info->matte_color);
+ pixel->matte_color.pixel=MagickXStandardPixel(map_info,&pixel->matte_color);
+ pixel->matte_color.flags=DoRed | DoGreen | DoBlue;
+ }
+ /*
+ Set highlight color.
+ */
+ pixel->highlight_color.red=(unsigned short) (((double)
+ pixel->matte_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+
+ (ScaleQuantumToShort((double) MaxRGB-HighlightModulate)));
+ pixel->highlight_color.green=(unsigned short) (((double)
+ pixel->matte_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+
+ (ScaleQuantumToShort((double) MaxRGB-HighlightModulate)));
+ pixel->highlight_color.blue=(unsigned short) (((double)
+ pixel->matte_color.blue*ScaleQuantumToShort(HighlightModulate))/65535L+
+ (ScaleQuantumToShort((double) MaxRGB-HighlightModulate)));
+ pixel->highlight_color.pixel=MagickXStandardPixel(map_info,&pixel->highlight_color);
+ pixel->highlight_color.flags=DoRed | DoGreen | DoBlue;
+ /*
+ Set shadow color.
+ */
+ pixel->shadow_color.red=(unsigned short) (((double)
+ pixel->matte_color.red*ScaleQuantumToShort(ShadowModulate))/65535L);
+ pixel->shadow_color.green=(unsigned short) (((double)
+ pixel->matte_color.green*ScaleQuantumToShort(ShadowModulate))/65535L);
+ pixel->shadow_color.blue=(unsigned short) (((double)
+ pixel->matte_color.blue*ScaleQuantumToShort(ShadowModulate))/65535L);
+ pixel->shadow_color.pixel=MagickXStandardPixel(map_info,&pixel->shadow_color);
+ pixel->shadow_color.flags=DoRed | DoGreen | DoBlue;
+ /*
+ Set depth color.
+ */
+ pixel->depth_color.red=(unsigned short) (((double)
+ pixel->matte_color.red*ScaleQuantumToShort(DepthModulate))/65535L);
+ pixel->depth_color.green=(unsigned short) (((double)
+ pixel->matte_color.green*ScaleQuantumToShort(DepthModulate))/65535L);
+ pixel->depth_color.blue=(unsigned short) (((double)
+ pixel->matte_color.blue*ScaleQuantumToShort(DepthModulate))/65535L);
+ pixel->depth_color.pixel=MagickXStandardPixel(map_info,&pixel->depth_color);
+ pixel->depth_color.flags=DoRed | DoGreen | DoBlue;
+ /*
+ Set trough color.
+ */
+ pixel->trough_color.red=(unsigned short) (((double)
+ pixel->matte_color.red*ScaleQuantumToShort(TroughModulate))/65535L);
+ pixel->trough_color.green=(unsigned short) (((double)
+ pixel->matte_color.green*ScaleQuantumToShort(TroughModulate))/65535L);
+ pixel->trough_color.blue=(unsigned short) (((double)
+ pixel->matte_color.blue*ScaleQuantumToShort(TroughModulate))/65535L);
+ pixel->trough_color.pixel=MagickXStandardPixel(map_info,&pixel->trough_color);
+ pixel->trough_color.flags=DoRed | DoGreen | DoBlue;
+ /*
+ Set pen color.
+ */
+ for (i=0; i < MaxNumberPens; i++)
+ {
+ (void) XParseColor(display,colormap,(char *) PenColors[i],
+ &pixel->pen_colors[i]);
+ status=XParseColor(display,colormap,resource_info->pen_colors[i],
+ &pixel->pen_colors[i]);
+ if (status == 0)
+ MagickError(XServerError,ColorIsNotKnownToServer,
+ resource_info->pen_colors[i]);
+ pixel->pen_colors[i].pixel=MagickXStandardPixel(map_info,&pixel->pen_colors[i]);
+ pixel->pen_colors[i].flags=DoRed | DoGreen | DoBlue;
+ }
+ pixel->box_color=pixel->background_color;
+ pixel->pen_color=pixel->foreground_color;
+ pixel->box_index=0;
+ pixel->pen_index=1;
+ if (image != (Image *) NULL)
+ {
+ if (resource_info->gamma_correct && (image->gamma != 0.0))
+ {
+ int
+ count;
+
+ /*
+ Initialize map relative to display and image gamma.
+ */
+ count=sscanf(resource_info->display_gamma,"%lf%*[,/]%lf%*[,/]%lf",
+ &red_gamma,&green_gamma,&blue_gamma);
+ if (count == 1)
+ {
+ green_gamma=red_gamma;
+ blue_gamma=red_gamma;
+ }
+ red_gamma*=image->gamma;
+ green_gamma*=image->gamma;
+ blue_gamma*=image->gamma;
+ }
+ if (image->storage_class == PseudoClass)
+ {
+ /*
+ Initialize pixel array for images of type PseudoClass.
+ */
+ for (i=0; i < (long) image->colors; i++)
+ pixel->pixels[i]=
+ MagickXGammaPixel(map_info,image->colormap+i);
+ for (i=0; i < MaxNumberPens; i++)
+ pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
+ pixel->colors+=MaxNumberPens;
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t R e s o u r c e C l a s s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetResourceClass queries the X server for the specified
+% resource name or class. If the resource name or class is not defined
+% in the database, the supplied default value is returned.
+%
+% The format of the MagickXGetResourceClass method is:
+%
+% char *MagickXGetResourceClass(XrmDatabase database,
+% const char *client_name,const char *keyword,char *resource_default)
+%
+% A description of each parameter follows:
+%
+% o value: Method MagickXGetResourceClass returns the resource value
+% associated with the name or class. If none is found, the supplied
+% default value is returned.
+%
+% o database: Specifies a resource database; returned from
+% XrmGetStringDatabase.
+%
+% o client_name: Specifies the application name used to retrieve resource
+% info from the X server database.
+%
+% o keyword: Specifies the keyword of the value being retrieved.
+%
+% o resource_default: Specifies the default value to return if the query
+% fails to find the specified keyword/class.
+%
+%
+*/
+MagickExport char *
+MagickXGetResourceClass(XrmDatabase database,
+ const char *client_name,const char *keyword,
+ char *resource_default)
+{
+ char
+ resource_class[MaxTextExtent],
+ resource_name[MaxTextExtent];
+
+ int
+ status;
+
+ static char
+ *resource_type;
+
+ XrmValue
+ resource_value;
+
+ if (database == (XrmDatabase) NULL)
+ return(resource_default);
+ *resource_name='\0';
+ *resource_class='\0';
+ if (keyword != (char *) NULL)
+ {
+ unsigned char
+ c,
+ k;
+
+ /*
+ Initialize resource keyword and class.
+ */
+ FormatString(resource_name,"%.1024s.%.1024s",client_name,keyword);
+ c=(*client_name);
+ if ((c >= XK_a) && (c <= XK_z))
+ c-=(XK_a-XK_A);
+ else
+ if ((c >= XK_agrave) && (c <= XK_odiaeresis))
+ c-=(XK_agrave-XK_Agrave);
+ else
+ if ((c >= XK_oslash) && (c <= XK_thorn))
+ c-=(XK_oslash-XK_Ooblique);
+ k=(*keyword);
+ if ((k >= XK_a) && (k <= XK_z))
+ k-=(XK_a-XK_A);
+ else
+ if ((k >= XK_agrave) && (k <= XK_odiaeresis))
+ k-=(XK_agrave-XK_Agrave);
+ else
+ if ((k >= XK_oslash) && (k <= XK_thorn))
+ k-=(XK_oslash-XK_Ooblique);
+ FormatString(resource_class,"%c%.1024s.%c%.1024s",c,client_name+1,k,
+ keyword+1);
+ }
+ status=XrmGetResource(database,resource_name,resource_class,&resource_type,
+ &resource_value);
+ if (status == False)
+ return(resource_default);
+ return(resource_value.addr);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t R e s o u r c e D a t a b a s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetResourceDatabase creates a new resource database and
+% initializes it.
+%
+% The format of the MagickXGetResourceDatabase method is:
+%
+% XrmDatabase MagickXGetResourceDatabase(Display *display,
+% const char *client_name)
+%
+% A description of each parameter follows:
+%
+% o database: Method MagickXGetResourceDatabase returns the database after
+% it is initialized.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o client_name: Specifies the application name used to retrieve resource
+% info from the X server database.
+%
+%
+*/
+MagickExport XrmDatabase
+MagickXGetResourceDatabase(Display *display,
+ const char *client_name)
+{
+ char
+ filename[MaxTextExtent];
+
+ register const char
+ *p;
+
+ unsigned char
+ c;
+
+ XrmDatabase
+ resource_database,
+ server_database;
+
+ if (display == (Display *) NULL)
+ return((XrmDatabase) NULL);
+ assert(client_name != (char *) NULL);
+ /*
+ Initialize resource database.
+ */
+ XrmInitialize();
+ (void) XGetDefault(display,(char *) client_name,(char *) "dummy");
+ resource_database=XrmGetDatabase(display);
+ /*
+ Combine application database.
+ */
+ if (client_name != (char *) NULL)
+ {
+ /*
+ Get basename of client.
+ */
+ p=client_name+(strlen(client_name)-1);
+ while ((p > client_name) && (*p != '/'))
+ p--;
+ if (*p == '/')
+ client_name=p+1;
+ }
+ c=(*client_name);
+ if ((c >= XK_a) && (c <= XK_z))
+ c-=(XK_a-XK_A);
+ else
+ if ((c >= XK_agrave) && (c <= XK_odiaeresis))
+ c-=(XK_agrave-XK_Agrave);
+ else
+ if ((c >= XK_oslash) && (c <= XK_thorn))
+ c-=(XK_oslash-XK_Ooblique);
+#if defined(ApplicationDefaults)
+ FormatString(filename,"%.1024s%c%.1024s",ApplicationDefaults,c,client_name+1);
+ (void) XrmCombineFileDatabase(filename,&resource_database,False);
+#endif
+ if (XResourceManagerString(display) != (char *) NULL)
+ {
+ /*
+ Combine server database.
+ */
+ server_database=XrmGetStringDatabase(XResourceManagerString(display));
+ XrmCombineDatabase(server_database,&resource_database,False);
+ }
+ /*
+ Merge user preferences database.
+ */
+#if defined(PreferencesDefaults)
+ FormatString(filename,"%.1024s%.1024src",PreferencesDefaults,client_name);
+ ExpandFilename(filename);
+ (void) XrmCombineFileDatabase(filename,&resource_database,False);
+#endif
+ return(resource_database);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t R e s o u r c e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetResourceInfo initializes the ResourceInfo structure.
+%
+% The format of the MagickXGetResourceInfo method is:
+%
+% void MagickXGetResourceInfo(XrmDatabase database,char *client_name,
+% MagickXResourceInfo *resource_info)
+%
+% A description of each parameter follows:
+%
+% o database: Specifies a resource database; returned from
+% XrmGetStringDatabase.
+%
+% o client_name: Specifies the application name used to retrieve
+% resource info from the X server database.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+%
+*/
+MagickExport void
+MagickXGetResourceInfo(XrmDatabase database,const char *client_name,
+ MagickXResourceInfo *resource_info)
+{
+ char
+ *resource_value;
+
+ /*
+ Initialize resource info fields.
+ */
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ (void) memset(resource_info,0,sizeof(MagickXResourceInfo));
+ resource_info->resource_database=database;
+ resource_info->image_info=CloneImageInfo((ImageInfo *) NULL);
+ resource_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
+ resource_info->close_server=True;
+ resource_info->client_name=AllocateString(client_name);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "backdrop",
+ (char *) "False");
+ resource_info->backdrop=MagickIsTrue(resource_value);
+ resource_info->background_color=MagickXGetResourceInstance(database,client_name,
+ (char *) "background","#d6d6d6d6d6d6");
+ resource_info->border_color=MagickXGetResourceInstance(database,client_name,
+ (char *) "borderColor",BorderColor);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "borderWidth",
+ (char *) "2");
+ resource_info->border_width=MagickAtoI(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "colormap",
+ (char *) "shared");
+ resource_info->colormap=UndefinedColormap;
+ if (LocaleCompare("private",resource_value) == 0)
+ resource_info->colormap=PrivateColormap;
+ if (LocaleCompare("shared",resource_value) == 0)
+ resource_info->colormap=SharedColormap;
+ if (resource_info->colormap == UndefinedColormap)
+ MagickError(OptionError,UnrecognizedColormapType,resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,
+ (char *) "colorRecovery",(char *) "False");
+ resource_info->color_recovery=MagickIsTrue(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "confirmExit",
+ (char *) "False");
+ resource_info->confirm_exit=MagickIsTrue(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "delay",
+ (char *) "1");
+ resource_info->delay=MagickAtoI(resource_value);
+ resource_info->display_gamma=MagickXGetResourceClass(database,client_name,
+ (char *) "displayGamma",(char *) "2.2");
+ resource_value=MagickXGetResourceClass(database,client_name,
+ (char *) "displayWarnings",(char *) "True");
+ resource_info->display_warnings=MagickIsTrue(resource_value);
+ resource_info->font=MagickXGetResourceClass(database,client_name,(char *) "font",
+ (char *) "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1");
+ resource_info->font=MagickXGetResourceClass(database,client_name,
+ (char *) "fontList",resource_info->font);
+ resource_info->font_name[0]=MagickXGetResourceClass(database,client_name,
+ (char *) "font1",(char *) "fixed");
+ resource_info->font_name[1]=MagickXGetResourceClass(database,client_name,
+ (char *) "font2",(char *) "variable");
+ resource_info->font_name[2]=MagickXGetResourceClass(database,client_name,
+ (char *) "font3",(char *) "5x8");
+ resource_info->font_name[3]=MagickXGetResourceClass(database,client_name,
+ (char *) "font4",(char *) "6x10");
+ resource_info->font_name[4]=MagickXGetResourceClass(database,client_name,
+ (char *) "font5",(char *) "7x13bold");
+ resource_info->font_name[5]=MagickXGetResourceClass(database,client_name,
+ (char *) "font6",(char *) "8x13bold");
+ resource_info->font_name[6]=MagickXGetResourceClass(database,client_name,
+ (char *) "font7",(char *) "9x15bold");
+ resource_info->font_name[7]=MagickXGetResourceClass(database,client_name,
+ (char *) "font8",(char *) "10x20");
+ resource_info->font_name[8]=MagickXGetResourceClass(database,client_name,
+ (char *) "font9",(char *) "12x24");
+ resource_info->font_name[9]=MagickXGetResourceClass(database,client_name,
+ (char *) "font0",(char *) "fixed");
+ resource_info->font_name[10]=MagickXGetResourceClass(database,client_name,
+ (char *) "font0",(char *) "fixed");
+ resource_info->foreground_color=MagickXGetResourceInstance(database,client_name,
+ "foreground",ForegroundColor);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "gammaCorrect",
+ (char *) "True");
+ resource_info->gamma_correct=MagickIsTrue(resource_value);
+ resource_info->image_geometry=MagickXGetResourceClass(database,client_name,
+ (char *) "geometry",(char *) NULL);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "gravity",
+ (char *) "Center");
+ resource_info->gravity=(-1);
+ if (LocaleCompare("Forget",resource_value) == 0)
+ resource_info->gravity=ForgetGravity;
+ if (LocaleCompare("NorthWest",resource_value) == 0)
+ resource_info->gravity=NorthWestGravity;
+ if (LocaleCompare("North",resource_value) == 0)
+ resource_info->gravity=NorthGravity;
+ if (LocaleCompare("NorthEast",resource_value) == 0)
+ resource_info->gravity=NorthEastGravity;
+ if (LocaleCompare("West",resource_value) == 0)
+ resource_info->gravity=WestGravity;
+ if (LocaleCompare("Center",resource_value) == 0)
+ resource_info->gravity=CenterGravity;
+ if (LocaleCompare("East",resource_value) == 0)
+ resource_info->gravity=EastGravity;
+ if (LocaleCompare("SouthWest",resource_value) == 0)
+ resource_info->gravity=SouthWestGravity;
+ if (LocaleCompare("South",resource_value) == 0)
+ resource_info->gravity=SouthGravity;
+ if (LocaleCompare("SouthEast",resource_value) == 0)
+ resource_info->gravity=SouthEastGravity;
+ if (LocaleCompare("Static",resource_value) == 0)
+ resource_info->gravity=StaticGravity;
+ if (resource_info->gravity == (-1))
+ {
+ MagickError(OptionError,UnrecognizedGravityType,resource_value);
+ resource_info->gravity=CenterGravity;
+ }
+ if (getcwd(resource_info->home_directory,MaxTextExtent-1) == NULL)
+ MagickFatalError(ConfigureFatalError,UnableToGetCurrentDirectory,
+ NULL);
+ resource_info->icon_geometry=MagickXGetResourceClass(database,client_name,
+ (char *) "iconGeometry",(char *) NULL);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "iconic",
+ (char *) "False");
+ resource_info->iconic=MagickIsTrue(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "immutable",
+ LocaleCompare(client_name,(char *) "PerlMagick") == 0 ? (char *) "True" :
+ (char *) "False");
+ resource_info->immutable=MagickIsTrue(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "magnify",
+ (char *) "3");
+ resource_info->magnify=MagickAtoI(resource_value);
+ resource_info->map_type=MagickXGetResourceClass(database,client_name,(char *) "map",
+ (char *) NULL);
+ resource_info->matte_color=MagickXGetResourceInstance(database,client_name,
+ (char *) "mattecolor",(char *) NULL);
+ resource_info->name=MagickXGetResourceClass(database,client_name,(char *) "name",
+ (char *) NULL);
+ resource_info->pen_colors[0]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen1",(char *) "black");
+ resource_info->pen_colors[1]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen2",(char *) "blue");
+ resource_info->pen_colors[2]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen3",(char *) "cyan");
+ resource_info->pen_colors[3]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen4",(char *) "green");
+ resource_info->pen_colors[4]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen5",(char *) "gray");
+ resource_info->pen_colors[5]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen6",(char *) "red");
+ resource_info->pen_colors[6]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen7",(char *) "magenta");
+ resource_info->pen_colors[7]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen8",(char *) "yellow");
+ resource_info->pen_colors[8]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen9",(char *) "white");
+ resource_info->pen_colors[9]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen0",(char *) "gray");
+ resource_info->pen_colors[10]=MagickXGetResourceClass(database,client_name,
+ (char *) "pen0",(char *) "gray");
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "pause",
+ (char *) "0");
+ resource_info->pause=MagickAtoI(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "quantum",
+ (char *) "1");
+ resource_info->quantum=MagickAtoI(resource_value);
+ resource_info->text_font=MagickXGetResourceClass(database,client_name,(char *)
+ "font",(char *) "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-iso8859-1");
+ resource_info->text_font=MagickXGetResourceClass(database,client_name,
+ (char *) "textFontList",resource_info->text_font);
+ resource_info->title=MagickXGetResourceClass(database,client_name,(char *) "title",
+ (char *) NULL);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "undoCache",
+ (char *) "16");
+ resource_info->undo_cache=MagickAtoL(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "update",
+ (char *) "False");
+ resource_info->update=MagickIsTrue(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "usePixmap",
+ (char *) "False");
+ resource_info->use_pixmap=MagickIsTrue(resource_value);
+ resource_value=MagickXGetResourceClass(database,client_name,(char *) "sharedMemory",
+ (char *) "True");
+ resource_info->use_shared_memory=MagickIsTrue(resource_value);
+ resource_info->visual_type=MagickXGetResourceClass(database,client_name,
+ (char *) "visual",(char *) NULL);
+ resource_info->window_group=MagickXGetResourceClass(database,client_name,
+ (char *) "windowGroup",(char *) NULL);
+ resource_info->window_id=MagickXGetResourceClass(database,client_name,
+ (char *) "window",(char *) NULL);
+ resource_info->write_filename=MagickXGetResourceClass(database,client_name,
+ (char *) "writeFilename",(char *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t R e s o u r c e I n s t a n c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetResourceInstance queries the X server for the specified
+% resource name. If the resource name is not defined in the database, the
+% supplied default value is returned.
+%
+% The format of the MagickXGetResourceInstance method is:
+%
+% char *MagickXGetResourceInstance(XrmDatabase database,
+% const char *client_name,const char *keyword,
+% const char *resource_default)
+%
+% A description of each parameter follows:
+%
+% o value: Method MagickXGetResourceInstance returns the resource value
+% associated with the name or class. If none is found, the supplied
+% default value is returned.
+%
+% o database: Specifies a resource database; returned from
+% XrmGetStringDatabase.
+%
+% o client_name: Specifies the application name used to retrieve
+% resource info from the X server database.
+%
+% o keyword: Specifies the keyword of the value being retrieved.
+%
+% o resource_default: Specifies the default value to return if the query
+% fails to find the specified keyword/class.
+%
+%
+*/
+MagickExport char *
+MagickXGetResourceInstance(XrmDatabase database,
+ const char *client_name,
+ const char *keyword,
+ const char *resource_default)
+{
+ char
+ *resource_type,
+ resource_name[MaxTextExtent];
+
+ int
+ status;
+
+ XrmValue
+ resource_value;
+
+ if (database == (XrmDatabase) NULL)
+ return((char *) resource_default);
+ *resource_name='\0';
+ if (keyword != (char *) NULL)
+ FormatString(resource_name,"%.1024s.%.1024s",client_name,keyword);
+ status=XrmGetResource(database,resource_name,"GraphicsMagick",
+ &resource_type,&resource_value);
+ if (status == False)
+ return((char *) resource_default);
+ return(resource_value.addr);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t S c r e e n D e n s i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetScreenDensity returns the density of the X server screen in
+% dots-per-inch.
+%
+% The format of the MagickXGetScreenDensity method is:
+%
+% char *MagickXGetScreenDensity(Display *display)
+%
+% A description of each parameter follows:
+%
+% o density: Method MagickXGetScreenDensity returns the density of the X
+% screen
+% in dots-per-inch.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+%
+*/
+MagickExport char *
+MagickXGetScreenDensity(Display *display)
+{
+ char
+ density[MaxTextExtent];
+
+ double
+ x_density,
+ y_density;
+
+ /*
+ Set density as determined by screen size.
+ */
+ x_density=((((double) DisplayWidth(display,XDefaultScreen(display)))*25.4)/
+ ((double) DisplayWidthMM(display,XDefaultScreen(display))));
+ y_density=((((double) DisplayHeight(display,XDefaultScreen(display)))*25.4)/
+ ((double) DisplayHeightMM(display,XDefaultScreen(display))));
+ FormatString(density,"%gx%g",x_density,y_density);
+ return(GetPageGeometry(density));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X G e t S u b w i n d o w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method XGetSubwindow returns the subwindow of a window chosen the
+% user with the pointer and a button press.
+%
+% The format of the XGetSubwindow method is:
+%
+% Window XGetSubwindow(Display *display,Window window,int x,int y)
+%
+% A description of each parameter follows:
+%
+% o subwindow: Method XGetSubwindow returns NULL if no subwindow is found
+% otherwise the subwindow is returned.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a Window.
+%
+% o x: the x coordinate of the pointer relative to the origin of the
+% window.
+%
+% o y: the y coordinate of the pointer relative to the origin of the
+% window.
+%
+%
+*/
+static Window
+MagickXGetSubwindow(Display *display,Window window,int x,int y)
+{
+ Window
+ source_window,
+ target_window;
+
+ int
+ status,
+ x_offset,
+ y_offset;
+
+ assert(display != (Display *) NULL);
+ source_window=XRootWindow(display,XDefaultScreen(display));
+ if (window == (Window) NULL)
+ return(source_window);
+ target_window=window;
+ for ( ; ; )
+ {
+ status=XTranslateCoordinates(display,source_window,window,x,y,
+ &x_offset,&y_offset,&target_window);
+ if (status != True)
+ break;
+ if (target_window == (Window) NULL)
+ break;
+ source_window=window;
+ window=target_window;
+ x=x_offset;
+ y=y_offset;
+ }
+ if (target_window == (Window) NULL)
+ target_window=window;
+ return(target_window);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t W i n d o w C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetWindowColor returns the color of a pixel interactively
+% chosen from the X server.
+%
+% The format of the MagickXGetWindowColor method is:
+%
+% unsigned int MagickXGetWindowColor(Display *display,
+% MagickXWindows *windows,char *name)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXGetWindowColor returns True if the color is
+% obtained from the X server. False is returned if any errors occurs.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o name: The name of of the color if found in the X Color Database is
+% returned in this character string.
+%
+%
+*/
+MagickExport unsigned int
+MagickXGetWindowColor(Display *display,MagickXWindows *windows,char *name)
+{
+ int
+ x,
+ y;
+
+ PixelPacket
+ pixel;
+
+ RectangleInfo
+ crop_info;
+
+ unsigned int
+ status;
+
+ Window
+ child,
+ client_window,
+ root_window,
+ target_window;
+
+ XColor
+ color;
+
+ XImage
+ *ximage;
+
+ XWindowAttributes
+ window_attributes;
+
+ /*
+ Choose a pixel from the X server.
+ */
+ assert(display != (Display *) NULL);
+ assert(name != (char *) NULL);
+ *name='\0';
+ target_window=MagickXSelectWindow(display,&crop_info);
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ client_window=target_window;
+ if (target_window != root_window)
+ {
+ unsigned int
+ d;
+
+ /*
+ Get client window.
+ */
+ status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d);
+ if (status != 0)
+ {
+ client_window=MagickXClientWindow(display,target_window);
+ target_window=client_window;
+ }
+ }
+ /*
+ Verify window is viewable.
+ */
+ status=XGetWindowAttributes(display,target_window,&window_attributes);
+ if ((status == False) || (window_attributes.map_state != IsViewable))
+ return(False);
+ /*
+ Get window X image.
+ */
+ (void) XTranslateCoordinates(display,root_window,target_window,
+ (int) crop_info.x,(int) crop_info.y,&x,&y,&child);
+ ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap);
+ if (ximage == (XImage *) NULL)
+ return(False);
+ color.pixel=XGetPixel(ximage,0,0);
+ XDestroyImage(ximage);
+ ximage=(XImage *) NULL;
+ /*
+ Match color against the color database.
+ */
+ (void) XQueryColor(display,window_attributes.colormap,&color);
+ pixel.red=ScaleShortToQuantum(color.red);
+ pixel.green=ScaleShortToQuantum(color.green);
+ pixel.blue=ScaleShortToQuantum(color.blue);
+ pixel.opacity=OpaqueOpacity;
+ (void) QueryColorname(windows->image.image,&pixel,X11Compliance,name,
+ &windows->image.image->exception);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X G e t W i n d o w I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetWindowImage reads an image from the target X window and
+% returns it. MagickXGetWindowImage optionally descends the window
+% hierarchy and overlays the target image with each child image in an
+% optimized fashion. Any child window that have the same visual, colormap,
+% and are contained by its parent are exempted.
+%
+% The format of the MagickXGetWindowImage method is:
+%
+% Image *MagickXGetWindowImage(Display *display,const Window window,
+% const unsigned int borders,const unsigned int level)
+%
+% A description of each parameter follows:
+%
+% o image: Method MagickXGetWindowImage returns a MIFF image if it can be
+% successfully read from the X window. A null image is returned if
+% any errors occurs.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies the window to obtain the image from.
+%
+% o borders: Specifies whether borders pixels are to be saved with
+% the image.
+%
+% o level: Specifies an unsigned integer representing the level of
+% decent in the window hierarchy. This value must be zero or one on
+% the initial call to MagickXGetWindowImage. A value of zero returns
+% after one call. A value of one causes the function to descend the
+% window hierarchy and overlay the target image with each subwindow image.
+%
+%
+*/
+static Image *
+MagickXGetWindowImage(Display *display,const Window window,
+ const unsigned int borders,const unsigned int level)
+{
+ typedef struct _ColormapInfo
+ {
+ Colormap
+ colormap;
+
+ XColor
+ *colors;
+
+ struct _ColormapInfo
+ *next;
+ } ColormapInfo;
+
+ typedef struct _WindowInfo
+ {
+ Window
+ window,
+ parent;
+
+ Visual
+ *visual;
+
+ Colormap
+ colormap;
+
+ XSegment
+ bounds;
+
+ RectangleInfo
+ crop_info;
+ } WindowInfo;
+
+ IndexPacket
+ index_packet;
+
+ int
+ display_height,
+ display_width,
+ id,
+ status,
+ x_offset,
+ y_offset;
+
+ RectangleInfo
+ crop_info;
+
+ register IndexPacket
+ *indexes;
+
+ register int
+ i;
+
+ static ColormapInfo
+ *colormap_info = (ColormapInfo *) NULL;
+
+ static int
+ max_windows = 0,
+ number_windows = 0;
+
+ static WindowInfo
+ *window_info;
+
+ Window
+ child,
+ root_window;
+
+ XWindowAttributes
+ window_attributes;
+
+ /*
+ Verify window is viewable.
+ */
+ assert(display != (Display *) NULL);
+ status=XGetWindowAttributes(display,window,&window_attributes);
+ if ((status == False) || (window_attributes.map_state != IsViewable))
+ return((Image *) NULL);
+ /*
+ Cropping rectangle is relative to root window.
+ */
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset,
+ &y_offset,&child);
+ crop_info.x=x_offset;
+ crop_info.y=y_offset;
+ crop_info.width=window_attributes.width;
+ crop_info.height=window_attributes.height;
+ if (borders)
+ {
+ /*
+ Include border in image.
+ */
+ crop_info.x-=window_attributes.border_width;
+ crop_info.y-=window_attributes.border_width;
+ crop_info.width+=window_attributes.border_width << 1;
+ crop_info.height+=window_attributes.border_width << 1;
+ }
+ /*
+ Crop to root window.
+ */
+ if (crop_info.x < 0)
+ {
+ crop_info.width+=crop_info.x;
+ crop_info.x=0;
+ }
+ if (crop_info.y < 0)
+ {
+ crop_info.height+=crop_info.y;
+ crop_info.y=0;
+ }
+ display_width=XDisplayWidth(display,XDefaultScreen(display));
+ if ((int) (crop_info.x+crop_info.width) > display_width)
+ crop_info.width=display_width-crop_info.x;
+ display_height=XDisplayHeight(display,XDefaultScreen(display));
+ if ((int) (crop_info.y+crop_info.height) > display_height)
+ crop_info.height=display_height-crop_info.y;
+ /*
+ Initialize window info attributes.
+ */
+ if (number_windows >= max_windows)
+ {
+ /*
+ Allocate or resize window info buffer.
+ */
+ max_windows+=1024;
+ if (window_info == (WindowInfo *) NULL)
+ window_info=MagickAllocateArray(WindowInfo *,
+ max_windows,sizeof(WindowInfo));
+ else
+ MagickReallocMemory(WindowInfo *,window_info,max_windows*sizeof(WindowInfo));
+ }
+ if (window_info == (WindowInfo *) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToReadXImage);
+ return((Image *) NULL);
+ }
+ id=number_windows++;
+ window_info[id].window=window;
+ window_info[id].visual=window_attributes.visual;
+ window_info[id].colormap=window_attributes.colormap;
+ window_info[id].bounds.x1=(short) crop_info.x;
+ window_info[id].bounds.y1=(short) crop_info.y;
+ window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1);
+ window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1);
+ crop_info.x-=x_offset;
+ crop_info.y-=y_offset;
+ window_info[id].crop_info=crop_info;
+ if (level != 0)
+ {
+ unsigned int
+ number_children;
+
+ Window
+ *children;
+
+ /*
+ Descend the window hierarchy.
+ */
+ status=XQueryTree(display,window,&root_window,&window_info[id].parent,
+ &children,&number_children);
+ for (i=0; i < id; i++)
+ if ((window_info[i].window == window_info[id].parent) &&
+ (window_info[i].visual == window_info[id].visual) &&
+ (window_info[i].colormap == window_info[id].colormap))
+ if ((window_info[id].bounds.x1 <= window_info[i].bounds.x1) ||
+ (window_info[id].bounds.x1 >= window_info[i].bounds.x2) ||
+ (window_info[id].bounds.y1 <= window_info[i].bounds.y1) ||
+ (window_info[id].bounds.y1 >= window_info[i].bounds.y2))
+ {
+ /*
+ Eliminate windows not circumscribed by their parent.
+ */
+ number_windows--;
+ break;
+ }
+ if ((status == True) && (number_children != 0))
+ {
+ for (i=0; i < (int) number_children; i++)
+ (void) MagickXGetWindowImage(display,children[i],False,level+1);
+ (void) XFree((void *) children);
+ }
+ }
+ if (level <= 1)
+ {
+ ColormapInfo
+ *next;
+
+ Image
+ *composite_image,
+ *image;
+
+ int
+ y;
+
+ register int
+ j,
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned long
+ pixel;
+
+ unsigned int
+ import,
+ number_colors;
+
+ XColor
+ *colors;
+
+ XImage
+ *ximage;
+
+ /*
+ Get X image for each window in the list.
+ */
+ image=(Image *) NULL;
+ for (id=0; id < number_windows; id++)
+ {
+ /*
+ Does target window intersect top level window?
+ */
+ import=(window_info[id].bounds.x2 >= window_info[0].bounds.x1) &&
+ (window_info[id].bounds.x1 <= window_info[0].bounds.x2) &&
+ (window_info[id].bounds.y2 >= window_info[0].bounds.y1) &&
+ (window_info[id].bounds.y1 <= window_info[0].bounds.y2);
+ /*
+ Is target window contained by another window with the same colormap?
+ */
+ for (j=0; j < id; j++)
+ if ((window_info[id].visual == window_info[j].visual) &&
+ (window_info[id].colormap == window_info[j].colormap) &&
+ (window_info[id].bounds.x1 >= window_info[j].bounds.x1) &&
+ (window_info[id].bounds.y1 >= window_info[j].bounds.y1) &&
+ (window_info[id].bounds.x2 <= window_info[j].bounds.x2) &&
+ (window_info[id].bounds.y2 <= window_info[j].bounds.y2))
+ import=False;
+ else
+ if ((window_info[id].visual != window_info[j].visual) ||
+ (window_info[id].colormap != window_info[j].colormap))
+ if ((window_info[id].bounds.x2 > window_info[j].bounds.x1) &&
+ (window_info[id].bounds.x1 < window_info[j].bounds.x2) &&
+ (window_info[id].bounds.y2 > window_info[j].bounds.y1) &&
+ (window_info[id].bounds.y1 < window_info[j].bounds.y2))
+ import=True;
+ if (!import)
+ continue;
+ /*
+ Get X image.
+ */
+ ximage=XGetImage(display,window_info[id].window,
+ (int) window_info[id].crop_info.x,(int) window_info[id].crop_info.y,
+ (unsigned int) window_info[id].crop_info.width,
+ (unsigned int) window_info[id].crop_info.height,AllPlanes,ZPixmap);
+ if (ximage == (XImage *) NULL)
+ continue;
+ /*
+ Initialize window colormap.
+ */
+ number_colors=0;
+ colors=(XColor *) NULL;
+ if (window_info[id].colormap != (Colormap) NULL)
+ {
+ ColormapInfo
+ *p;
+
+ /*
+ Search colormap list for window colormap.
+ */
+ number_colors=window_info[id].visual->map_entries;
+ for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next)
+ if (p->colormap == window_info[id].colormap)
+ break;
+ if (p == (ColormapInfo *) NULL)
+ {
+ /*
+ Get the window colormap.
+ */
+ colors=MagickAllocateArray(XColor *,number_colors,sizeof(XColor));
+ if (colors == (XColor *) NULL)
+ {
+ XDestroyImage(ximage);
+ ximage=(XImage *) NULL;
+ return((Image *) NULL);
+ }
+ if ((window_info[id].visual->class != DirectColor) &&
+ (window_info[id].visual->class != TrueColor))
+ for (i=0; i < (int) number_colors; i++)
+ {
+ colors[i].pixel=i;
+ colors[i].pad=0;
+ }
+ else
+ {
+ unsigned long
+ blue,
+ blue_bit,
+ green,
+ green_bit,
+ red,
+ red_bit;
+
+ /*
+ DirectColor or TrueColor visual.
+ */
+ red=0;
+ green=0;
+ blue=0;
+ red_bit=window_info[id].visual->red_mask &
+ (~(window_info[id].visual->red_mask)+1);
+ green_bit=window_info[id].visual->green_mask &
+ (~(window_info[id].visual->green_mask)+1);
+ blue_bit=window_info[id].visual->blue_mask &
+ (~(window_info[id].visual->blue_mask)+1);
+ for (i=0; i < (int) number_colors; i++)
+ {
+ colors[i].pixel=red | green | blue;
+ colors[i].pad=0;
+ red+=red_bit;
+ if (red > window_info[id].visual->red_mask)
+ red=0;
+ green+=green_bit;
+ if (green > window_info[id].visual->green_mask)
+ green=0;
+ blue+=blue_bit;
+ if (blue > window_info[id].visual->blue_mask)
+ blue=0;
+ }
+ }
+ (void) XQueryColors(display,window_info[id].colormap,colors,
+ (int) number_colors);
+ /*
+ Append colormap to colormap list.
+ */
+ p=MagickAllocateMemory(ColormapInfo *,sizeof(ColormapInfo));
+ if (p == (ColormapInfo *) NULL)
+ return((Image *) NULL);
+ p->colormap=window_info[id].colormap;
+ p->colors=colors;
+ p->next=colormap_info;
+ colormap_info=p;
+ }
+ colors=p->colors;
+ }
+ /*
+ Allocate image structure.
+ */
+ composite_image=AllocateImage((ImageInfo *) NULL);
+ if (composite_image == (Image *) NULL)
+ {
+ XDestroyImage(ximage);
+ ximage=(XImage *) NULL;
+ return((Image *) NULL);
+ }
+ /*
+ Convert X image to MIFF format.
+ */
+ if ((window_info[id].visual->class != TrueColor) &&
+ (window_info[id].visual->class != DirectColor))
+ composite_image->storage_class=PseudoClass;
+ composite_image->columns=ximage->width;
+ composite_image->rows=ximage->height;
+ switch (composite_image->storage_class)
+ {
+ case DirectClass:
+ default:
+ {
+ register unsigned long
+ color,
+ colormap_index;
+
+ unsigned long
+ blue_mask,
+ blue_shift,
+ green_mask,
+ green_shift,
+ red_mask,
+ red_shift;
+
+ /*
+ Determine shift and mask for red, green, and blue.
+ */
+ red_mask=window_info[id].visual->red_mask;
+ red_shift=0;
+ while ((red_mask & 0x01) == 0)
+ {
+ red_mask>>=1;
+ red_shift++;
+ }
+ green_mask=window_info[id].visual->green_mask;
+ green_shift=0;
+ while ((green_mask & 0x01) == 0)
+ {
+ green_mask>>=1;
+ green_shift++;
+ }
+ blue_mask=window_info[id].visual->blue_mask;
+ blue_shift=0;
+ while ((blue_mask & 0x01) == 0)
+ {
+ blue_mask>>=1;
+ blue_shift++;
+ }
+ /*
+ Convert X image to DirectClass packets.
+ */
+ if ((number_colors != 0) &&
+ (window_info[id].visual->class == DirectColor))
+ for (y=0; y < (long) composite_image->rows; y++)
+ {
+ q=SetImagePixels(composite_image,0,y,
+ composite_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) composite_image->columns; x++)
+ {
+ pixel=XGetPixel(ximage,x,y);
+ colormap_index=(pixel >> red_shift) & red_mask;
+ q->red=ScaleShortToQuantum(colors[colormap_index].red);
+ colormap_index=(pixel >> green_shift) & green_mask;
+ q->green=ScaleShortToQuantum(colors[colormap_index].green);
+ colormap_index=(pixel >> blue_shift) & blue_mask;
+ q->blue=ScaleShortToQuantum(colors[colormap_index].blue);
+ q++;
+ }
+ if (!SyncImagePixels(composite_image))
+ break;
+ }
+ else
+ for (y=0; y < (long) composite_image->rows; y++)
+ {
+ q=SetImagePixels(composite_image,0,y,
+ composite_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) composite_image->columns; x++)
+ {
+ pixel=XGetPixel(ximage,x,y);
+ color=(pixel >> red_shift) & red_mask;
+ q->red=ScaleShortToQuantum((65535L*color)/red_mask);
+ color=(pixel >> green_shift) & green_mask;
+ q->green=ScaleShortToQuantum((65535L*color)/green_mask);
+ color=(pixel >> blue_shift) & blue_mask;
+ q->blue=ScaleShortToQuantum((65535L*color)/blue_mask);
+ q++;
+ }
+ if (!SyncImagePixels(composite_image))
+ break;
+ }
+ break;
+ }
+ case PseudoClass:
+ {
+ /*
+ Create colormap.
+ */
+ if (!AllocateImageColormap(composite_image,number_colors))
+ {
+ XDestroyImage(ximage);
+ ximage=(XImage *) NULL;
+ DestroyImage(composite_image);
+ return((Image *) NULL);
+ }
+ for (i=0; i < (int) composite_image->colors; i++)
+ {
+ composite_image->colormap[colors[i].pixel].red=
+ ScaleShortToQuantum(colors[i].red);
+ composite_image->colormap[colors[i].pixel].green=
+ ScaleShortToQuantum(colors[i].green);
+ composite_image->colormap[colors[i].pixel].blue=
+ ScaleShortToQuantum(colors[i].blue);
+ }
+ /*
+ Convert X image to PseudoClass packets.
+ */
+ for (y=0; y < (long) composite_image->rows; y++)
+ {
+ q=SetImagePixels(composite_image,0,y,composite_image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(composite_image);
+ for (x=0; x < (long) composite_image->columns; x++)
+ {
+ index_packet=(IndexPacket) XGetPixel(ximage,x,y);
+ indexes[x]=index_packet;
+ *q++=composite_image->colormap[index_packet];
+ }
+ if (!SyncImagePixels(composite_image))
+ break;
+ }
+ break;
+ }
+ }
+ XDestroyImage(ximage);
+ ximage=(XImage *) NULL;
+
+ /*
+ Evaluate image depth.
+ */
+ composite_image->depth=GetImageDepth(composite_image,&composite_image->exception);
+ if (composite_image->depth < 8)
+ composite_image->depth=8;
+
+ if (image == (Image *) NULL)
+ {
+ image=composite_image;
+ continue;
+ }
+ /*
+ Composite any children in back-to-front order.
+ */
+ (void) XTranslateCoordinates(display,window_info[id].window,window,0,0,
+ &x_offset,&y_offset,&child);
+ x_offset-=(int) crop_info.x;
+ if (x_offset < 0)
+ x_offset=0;
+ y_offset-=(int) crop_info.y;
+ if (y_offset < 0)
+ y_offset=0;
+ (void) CompositeImage(image,CopyCompositeOp,composite_image,
+ x_offset,y_offset);
+ }
+ /*
+ Free resources.
+ */
+ while (colormap_info != (ColormapInfo *) NULL)
+ {
+ next=colormap_info->next;
+ MagickFreeMemory(colormap_info->colors);
+ MagickFreeMemory(colormap_info);
+ colormap_info=next;
+ }
+ /*
+ Free resources and restore initial state.
+ */
+ MagickFreeMemory(window_info);
+ window_info=(WindowInfo *) NULL;
+ max_windows=0;
+ number_windows=0;
+ colormap_info=(ColormapInfo *) NULL;
+ return(image);
+ }
+ return((Image *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X G e t W i n d o w I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXGetWindowInfo initializes the MagickXWindowInfo structure.
+%
+% The format of the MagickXGetWindowInfo method is:
+%
+% void MagickXGetWindowInfo(Display *display,XVisualInfo *visual_info,
+% XStandardColormap *map_info,MagickXPixelInfo *pixel,
+% XFontStruct *font_info,MagickXResourceInfo *resource_info,
+% MagickXWindowInfo *window)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
+% returned from XGetVisualInfo.
+%
+% o map_info: If map_type is specified, this structure is initialized
+% with info from the Standard Colormap.
+%
+% o pixel: Specifies a pointer to a MagickXPixelInfo structure.
+%
+% o font_info: Specifies a pointer to a XFontStruct structure.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+%
+*/
+MagickExport void
+MagickXGetWindowInfo(Display *display,
+ XVisualInfo *visual_info,
+ XStandardColormap *map_info,
+ MagickXPixelInfo *pixel,
+ XFontStruct *font_info,
+ MagickXResourceInfo *resource_info,
+ MagickXWindowInfo *window)
+{
+ /*
+ Initialize window info.
+ */
+ assert(display != (Display *) NULL);
+ assert(visual_info != (XVisualInfo *) NULL);
+ assert(map_info != (XStandardColormap *) NULL);
+ assert(pixel != (MagickXPixelInfo *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(window != (MagickXWindowInfo *) NULL);
+ if (window->id != (Window) NULL)
+ {
+ (void) XFreeCursor(display,window->cursor);
+ (void) XFreeCursor(display,window->busy_cursor);
+ if (window->highlight_stipple != (Pixmap) NULL)
+ (void) XFreePixmap(display,window->highlight_stipple);
+ if (window->shadow_stipple != (Pixmap) NULL)
+ (void) XFreePixmap(display,window->shadow_stipple);
+ }
+ else
+ {
+ /*
+ Initialize these attributes just once.
+ */
+ window->id=(Window) NULL;
+ window->x=XDisplayWidth(display,visual_info->screen) >> 1;
+ window->y=XDisplayWidth(display,visual_info->screen) >> 1;
+ window->ximage=(XImage *) NULL;
+ window->matte_image=(XImage *) NULL;
+ window->pixmap=(Pixmap) NULL;
+ window->matte_pixmap=(Pixmap) NULL;
+ window->mapped=False;
+ window->stasis=False;
+ window->shared_memory=True;
+ /* window->segment_info=0; */
+#if defined(HasSharedMemory)
+ {
+ XShmSegmentInfo
+ *segment_info;
+
+ if (window->segment_info == (void *) NULL)
+ window->segment_info=MagickAllocateArray(void *,2,sizeof(XShmSegmentInfo));
+ segment_info=(XShmSegmentInfo *) window->segment_info;
+ segment_info[0].shmid=(-1);
+ segment_info[0].shmaddr=NULL;
+ segment_info[1].shmid=(-1);
+ segment_info[1].shmaddr=NULL;
+ }
+#endif
+ }
+ /*
+ Initialize these attributes every time function is called.
+ */
+ window->screen=visual_info->screen;
+ window->root=XRootWindow(display,visual_info->screen);
+ window->visual=visual_info->visual;
+ window->storage_class=visual_info->class;
+ window->depth=visual_info->depth;
+ window->visual_info=visual_info;
+ window->map_info=map_info;
+ window->pixel_info=pixel;
+ window->font_info=font_info;
+ window->cursor=XCreateFontCursor(display,XC_left_ptr);
+ window->busy_cursor=XCreateFontCursor(display,XC_watch);
+ (void) CloneString(&window->name,(char *) NULL);
+ window->geometry=(char *) NULL;
+ (void) CloneString(&window->icon_name,(char *) NULL);
+ window->icon_geometry=resource_info->icon_geometry;
+ window->crop_geometry=(char *) NULL;
+ window->flags=PSize;
+ window->width=1;
+ window->height=1;
+ window->min_width=1;
+ window->min_height=1;
+ window->width_inc=1;
+ window->height_inc=1;
+ window->border_width=resource_info->border_width;
+ window->annotate_context=pixel->annotate_context;
+ window->highlight_context=pixel->highlight_context;
+ window->widget_context=pixel->widget_context;
+ window->shadow_stipple=(Pixmap) NULL;
+ window->highlight_stipple=(Pixmap) NULL;
+ window->use_pixmap=True;
+ window->immutable=False;
+ window->shape=False;
+ window->data=0;
+ window->mask=CWBackingStore | CWBackPixel | CWBackPixmap | CWBitGravity |
+ CWBorderPixel | CWColormap | CWCursor | CWDontPropagate | CWEventMask |
+ CWOverrideRedirect | CWSaveUnder | CWWinGravity;
+ window->attributes.background_pixel=pixel->background_color.pixel;
+ window->attributes.background_pixmap=(Pixmap) NULL;
+ window->attributes.bit_gravity=ForgetGravity;
+ window->attributes.backing_store=NotUseful;
+ window->attributes.save_under=False;
+ window->attributes.border_pixel=pixel->border_color.pixel;
+ window->attributes.colormap=map_info->colormap;
+ window->attributes.cursor=window->cursor;
+ window->attributes.do_not_propagate_mask=NoEventMask;
+ window->attributes.event_mask=NoEventMask;
+ window->attributes.override_redirect=False;
+ window->attributes.win_gravity=NorthWestGravity;
+ window->orphan=False;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X H i g h l i g h t E l l i p s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXHighlightEllipse puts a border on the X server around a region
+% defined by highlight_info.
+%
+% The format of the MagickXHighlightEllipse method is:
+%
+% void MagickXHighlightEllipse(Display *display,Window window,
+% GC annotate_context,const RectangleInfo *highlight_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a Window structure.
+%
+% o annotate_context: Specifies a pointer to a GC structure.
+%
+% o highlight_info: Specifies a pointer to a RectangleInfo structure. It
+% contains the extents of any highlighting rectangle.
+%
+%
+*/
+MagickExport void
+MagickXHighlightEllipse(Display *display,Window window,
+ GC annotate_context,
+ const RectangleInfo *highlight_info)
+{
+ assert(display != (Display *) NULL);
+ assert(window != (Window) NULL);
+ assert(annotate_context != (GC) NULL);
+ assert(highlight_info != (RectangleInfo *) NULL);
+ if ((highlight_info->width < 4) || (highlight_info->height < 4))
+ return;
+ (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x,
+ (int) highlight_info->y,(unsigned int) highlight_info->width-1,
+ (unsigned int) highlight_info->height-1,0,360*64);
+ (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x+1,
+ (int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
+ (unsigned int) highlight_info->height-3,0,360*64);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X H i g h l i g h t L i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXHighlightLine puts a border on the X server around a region
+% defined by highlight_info.
+%
+% The format of the MagickXHighlightLine method is:
+%
+% void MagickXHighlightLine(Display *display,Window window,
+% GC annotate_context,const XSegment *highlight_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a Window structure.
+%
+% o annotate_context: Specifies a pointer to a GC structure.
+%
+% o highlight_info: Specifies a pointer to a RectangleInfo structure. It
+% contains the extents of any highlighting rectangle.
+%
+%
+*/
+MagickExport void
+MagickXHighlightLine(Display *display,Window window,
+ GC annotate_context,const XSegment *highlight_info)
+{
+ assert(display != (Display *) NULL);
+ assert(window != (Window) NULL);
+ assert(annotate_context != (GC) NULL);
+ assert(highlight_info != (XSegment *) NULL);
+ (void) XDrawLine(display,window,annotate_context,highlight_info->x1,
+ highlight_info->y1,highlight_info->x2,highlight_info->y2);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X H i g h l i g h t R e c t a n g l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXHighlightRectangle puts a border on the X server around a
+% region defined by highlight_info.
+%
+% The format of the MagickXHighlightRectangle method is:
+%
+% void MagickXHighlightRectangle(Display *display,Window window,
+% GC annotate_context,const RectangleInfo *highlight_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a Window structure.
+%
+% o annotate_context: Specifies a pointer to a GC structure.
+%
+% o highlight_info: Specifies a pointer to a RectangleInfo structure. It
+% contains the extents of any highlighting rectangle.
+%
+%
+*/
+MagickExport void
+MagickXHighlightRectangle(Display *display,Window window,
+ GC annotate_context,
+ const RectangleInfo *highlight_info)
+{
+ assert(display != (Display *) NULL);
+ assert(window != (Window) NULL);
+ assert(annotate_context != (GC) NULL);
+ assert(highlight_info != (RectangleInfo *) NULL);
+ if ((highlight_info->width < 4) || (highlight_info->height < 4))
+ return;
+ (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x,
+ (int) highlight_info->y,(unsigned int) highlight_info->width-1,
+ (unsigned int) highlight_info->height-1);
+ (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x+
+ 1,(int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
+ (unsigned int) highlight_info->height-3);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X I m p o r t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Procedure MagickXImportImage reads an image from an X window.
+%
+% The format of the MagickXImportImage method is:
+%
+% Image *MagickXImportImage(const ImageInfo *image_info,
+% MagickXImportInfo *ximage_info)
+%
+% A description of each parameter follows:
+%
+% o image_info: The image info..
+%
+% o ximage_info: Specifies a pointer to an MagickXImportInfo structure.
+%
+%
+*/
+MagickExport Image *
+MagickXImportImage(const ImageInfo *image_info,
+ MagickXImportInfo *ximage_info)
+{
+ Colormap
+ *colormaps;
+
+ Display
+ *display;
+
+ Image
+ *image;
+
+ int
+ number_colormaps,
+ number_windows,
+ status,
+ x;
+
+ RectangleInfo
+ crop_info;
+
+ Window
+ *children,
+ client,
+ prior_target,
+ root,
+ target;
+
+ XTextProperty
+ window_name;
+
+ /*
+ Open X server connection.
+ */
+ assert(image_info != (ImageInfo *) NULL);
+ assert(ximage_info != (MagickXImportInfo *) NULL);
+ display=XOpenDisplay(image_info->server_name);
+ if (display == (Display *) NULL)
+ {
+ MagickError(XServerError,UnableToOpenXServer,
+ XDisplayName(image_info->server_name));
+ return((Image *) NULL);
+ }
+ /*
+ Set our forgiving error handler.
+ */
+ (void) XSetErrorHandler(MagickXError);
+ /*
+ Select target window.
+ */
+ crop_info.x=0;
+ crop_info.y=0;
+ crop_info.width=0;
+ crop_info.height=0;
+ root=XRootWindow(display,XDefaultScreen(display));
+ target=(Window) NULL;
+ if (image_info->filename[0] != '\0')
+ {
+ if (LocaleCompare(image_info->filename,"root") == 0)
+ target=root;
+ else
+ {
+ /*
+ Select window by ID or name.
+ */
+ if (isdigit((int) (*image_info->filename)))
+ target=MagickXWindowByID(display,root,(Window)
+ strtol(image_info->filename,(char **) NULL,0));
+ if (target == (Window) NULL)
+ target=MagickXWindowByName(display,root,image_info->filename);
+ if (target == (Window) NULL)
+ MagickError(XServerError,NoWindowWithSpecifiedIDExists,
+ image_info->filename);
+ }
+ }
+ /*
+ If target window is not defined, interactively select one.
+ */
+ prior_target=target;
+ if (target == (Window) NULL)
+ target=MagickXSelectWindow(display,&crop_info);
+ client=target; /* obsolete */
+ if (target != root)
+ {
+ unsigned int
+ d;
+
+ status=XGetGeometry(display,target,&root,&x,&x,&d,&d,&d,&d);
+ if (status != 0)
+ {
+ for ( ; ; )
+ {
+ Window
+ parent;
+
+ /*
+ Find window manager frame.
+ */
+ status=XQueryTree(display,target,&root,&parent,&children,&d);
+ if (status && (children != (Window *) NULL))
+ (void) XFree((char *) children);
+ if (!status || (parent == (Window) NULL) || (parent == root))
+ break;
+ target=parent;
+ }
+ /*
+ Get client window.
+ */
+ client=MagickXClientWindow(display,target);
+ if (!ximage_info->frame)
+ target=client;
+ if (!ximage_info->frame && prior_target)
+ target=prior_target;
+ (void) XRaiseWindow(display,target);
+ MagickXDelay(display,SuspendTime << 4);
+ }
+ }
+ if (ximage_info->screen)
+ {
+ int
+ y;
+
+ Window
+ child;
+
+ XWindowAttributes
+ window_attributes;
+
+ /*
+ Obtain window image directly from screen.
+ */
+ status=XGetWindowAttributes(display,target,&window_attributes);
+ if (status == False)
+ {
+ MagickError(XServerError,UnableToReadXAttributes,
+ image_info->filename);
+ (void) XCloseDisplay(display);
+ return((Image *) NULL);
+ }
+ (void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child);
+ crop_info.x=x;
+ crop_info.y=y;
+ crop_info.width=window_attributes.width;
+ crop_info.height=window_attributes.height;
+ if (ximage_info->borders)
+ {
+ /*
+ Include border in image.
+ */
+ crop_info.x-=window_attributes.border_width;
+ crop_info.y-=window_attributes.border_width;
+ crop_info.width+=window_attributes.border_width << 1;
+ crop_info.height+=window_attributes.border_width << 1;
+ }
+ target=root;
+ }
+ /*
+ If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend.
+ */
+ number_windows=0;
+ status=XGetWMColormapWindows(display,target,&children,&number_windows);
+ if ((status == True) && (number_windows > 0))
+ {
+ ximage_info->descend=True;
+ (void) XFree ((char *) children);
+ }
+ colormaps=XListInstalledColormaps(display,target,&number_colormaps);
+ if (number_colormaps > 0)
+ {
+ if (number_colormaps > 1)
+ ximage_info->descend=True;
+ (void) XFree((char *) colormaps);
+ }
+ /*
+ Alert the user not to alter the screen.
+ */
+ if (!ximage_info->silent)
+ (void) XBell(display,0);
+ /*
+ Get image by window id.
+ */
+ (void) XGrabServer(display);
+ image=MagickXGetWindowImage(display,target,ximage_info->borders,
+ ximage_info->descend ? 1 : 0);
+ (void) XUngrabServer(display);
+ if (image == (Image *) NULL)
+ MagickError(XServerError,UnableToReadXWindowImage,image_info->filename);
+ else
+ {
+ (void) strlcpy(image->filename,image_info->filename,MaxTextExtent);
+ if ((crop_info.width != 0) && (crop_info.height != 0))
+ {
+ Image
+ *clone_image,
+ *crop_image;
+
+ /*
+ Crop image as defined by the cropping rectangle.
+ */
+ clone_image=CloneImage(image,0,0,True,&image->exception);
+ if (clone_image != (Image *) NULL)
+ {
+ crop_image=CropImage(clone_image,&crop_info,&image->exception);
+ if (crop_image != (Image *) NULL)
+ {
+ DestroyImage(image);
+ image=crop_image;
+ }
+ }
+ }
+ status=XGetWMName(display,target,&window_name);
+ if (status == True)
+ {
+ if (image_info->filename[0] == '\0')
+ {
+ /*
+ Initialize image filename.
+ */
+ (void) strlcpy(image->filename,(char *) window_name.value,
+ (int) window_name.nitems+1);
+ image->filename[window_name.nitems]='\0';
+ }
+ (void) XFree((void *) window_name.value);
+ }
+ }
+ if (!ximage_info->silent)
+ {
+ /*
+ Alert the user we're done.
+ */
+ (void) XBell(display,0);
+ (void) XBell(display,0);
+ }
+ (void) XCloseDisplay(display);
+ return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X I n i t i a l i z e W i n d o w s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXInitializeWindows initializes the MagickXWindows structure.
+%
+% The format of the MagickXInitializeWindows method is:
+%
+% MagickXWindows *MagickXInitializeWindows(Display *display,
+% MagickXResourceInfo *resource_info)
+%
+% A description of each parameter follows:
+%
+% o windows: MagickXInitializeWindows returns a pointer to a
+% MagickXWindows structure.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+*/
+MagickExport MagickXWindows *
+MagickXInitializeWindows(Display *display,
+ MagickXResourceInfo *resource_info)
+{
+ Window
+ root_window;
+
+ MagickXWindows
+ *windows;
+
+ /*
+ Allocate windows structure.
+ */
+ windows=MagickAllocateMemory(MagickXWindows *,sizeof(MagickXWindows));
+ if (windows == (MagickXWindows *) NULL)
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateXWindow);
+ return((MagickXWindows *) NULL);
+ }
+ (void) memset(windows,0,sizeof(MagickXWindows));
+ windows->pixel_info=MagickAllocateMemory(MagickXPixelInfo *,sizeof(MagickXPixelInfo));
+ windows->icon_pixel=MagickAllocateMemory(MagickXPixelInfo *,sizeof(MagickXPixelInfo));
+ windows->icon_resources=MagickAllocateMemory(MagickXResourceInfo *,
+ sizeof(MagickXResourceInfo));
+ if ((windows->pixel_info == (MagickXPixelInfo *) NULL) ||
+ (windows->icon_pixel == (MagickXPixelInfo *) NULL) ||
+ (windows->icon_resources == (MagickXResourceInfo *) NULL))
+ {
+ MagickError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateXWindow);
+ return((MagickXWindows *) NULL);
+ }
+ /*
+ Initialize windows structure.
+ */
+ windows->display=display;
+ windows->wm_protocols=XInternAtom(display,"WM_PROTOCOLS",False);
+ windows->wm_delete_window=XInternAtom(display,"WM_DELETE_WINDOW",False);
+ windows->wm_take_focus=XInternAtom(display,"WM_TAKE_FOCUS",False);
+ windows->im_protocols=XInternAtom(display,"IM_PROTOCOLS",False);
+ windows->im_remote_command=XInternAtom(display,"IM_REMOTE_COMMAND",False);
+ windows->im_update_widget=XInternAtom(display,"IM_UPDATE_WIDGET",False);
+ windows->im_update_colormap=
+ XInternAtom(display,"IM_UPDATE_COLORMAP",False);
+ windows->im_former_image=XInternAtom(display,"IM_FORMER_IMAGE",False);
+ windows->im_next_image=XInternAtom(display,"IM_NEXT_IMAGE",False);
+ windows->im_retain_colors=XInternAtom(display,"IM_RETAIN_COLORS",False);
+ windows->im_exit=XInternAtom(display,"IM_EXIT",False);
+ windows->dnd_protocols=XInternAtom(display,"DndProtocol",False);
+#if defined(MSWINDOWS)
+ (void) XSynchronize(display,IsWindows95());
+#endif
+ if (IsEventLogging())
+ {
+ (void) XSynchronize(display,True);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %.1024s",
+ GetMagickVersion((unsigned long *) NULL));
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Protocols:");
+ (void) LogMagickEvent(X11Event,GetMagickModule()," Window Manager: 0x%lx",
+ windows->wm_protocols);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," delete window: 0x%lx",
+ windows->wm_delete_window);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," take focus: 0x%lx",
+ windows->wm_take_focus);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," GraphicsMagick: 0x%lx",
+ windows->im_protocols);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," remote command: 0x%lx",
+ windows->im_remote_command);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," update widget: 0x%lx",
+ windows->im_update_widget);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " update colormap: 0x%lx",windows->im_update_colormap);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," former image: 0x%lx",
+ windows->im_former_image);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," next image: 0x%lx",
+ windows->im_next_image);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," retain colors: 0x%lx",
+ windows->im_retain_colors);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," exit: 0x%lx",
+ windows->im_exit);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," Drag and Drop: 0x%lx",
+ windows->dnd_protocols);
+ }
+ /*
+ Allocate standard colormap.
+ */
+ windows->map_info=XAllocStandardColormap();
+ windows->icon_map=XAllocStandardColormap();
+ if ((windows->map_info == (XStandardColormap *) NULL) ||
+ (windows->icon_map == (XStandardColormap *) NULL))
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(XServerFatalError,UnableToCreateStandardColormap));
+ windows->map_info->colormap=(Colormap) NULL;
+ windows->icon_map->colormap=(Colormap) NULL;
+ (void) memset((void *) windows->pixel_info, 0, sizeof(MagickXPixelInfo));
+ windows->pixel_info->pixels=(unsigned long *) NULL;
+ windows->pixel_info->annotate_context=(GC) NULL;
+ windows->pixel_info->highlight_context=(GC) NULL;
+ windows->pixel_info->widget_context=(GC) NULL;
+ windows->font_info=(XFontStruct *) NULL;
+ (void) memset((void *) windows->icon_pixel, 0, sizeof(MagickXPixelInfo));
+ windows->icon_pixel->annotate_context=(GC) NULL;
+ windows->icon_pixel->pixels=(unsigned long *) NULL;
+ windows->icon_pixel->highlight_context=(GC) NULL;
+ /*
+ Allocate visual.
+ */
+ *windows->icon_resources=(*resource_info);
+ windows->icon_resources->map_type=(char *) NULL;
+ windows->icon_resources->visual_type=(char *) "default";
+ windows->icon_resources->colormap=SharedColormap;
+ windows->visual_info=
+ MagickXBestVisualInfo(display,windows->map_info,resource_info);
+ windows->icon_visual=
+ MagickXBestVisualInfo(display,windows->icon_map,windows->icon_resources);
+ if ((windows->visual_info == (XVisualInfo *) NULL) ||
+ (windows->icon_visual == (XVisualInfo *) NULL))
+ MagickFatalError(XServerFatalError,UnableToGetVisual,
+ resource_info->visual_type);
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Visual:");
+ (void) LogMagickEvent(X11Event,GetMagickModule()," visual id: 0x%lx",
+ windows->visual_info->visualid);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," class: %.1024s",
+ MagickXVisualClassName(windows->visual_info->class));
+ (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d planes",
+ windows->visual_info->depth);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " size of colormap: %d entries",windows->visual_info->colormap_size);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " red, green, blue masks: 0x%lx 0x%lx 0x%lx",
+ windows->visual_info->red_mask,windows->visual_info->green_mask,
+ windows->visual_info->blue_mask);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " significant bits in color: %d bits",
+ windows->visual_info->bits_per_rgb);
+ }
+ /*
+ Allocate class and manager hints.
+ */
+ windows->class_hints=XAllocClassHint();
+ windows->manager_hints=XAllocWMHints();
+ if ((windows->class_hints == (XClassHint *) NULL) ||
+ (windows->manager_hints == (XWMHints *) NULL))
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(XServerFatalError,UnableToAllocateXHints));
+ /*
+ Determine group leader if we have one.
+ */
+ root_window=XRootWindow(display,windows->visual_info->screen);
+ windows->group_leader.id=(Window) NULL;
+ if (resource_info->window_group != (char *) NULL)
+ {
+ if (isdigit((int) (*resource_info->window_group)))
+ windows->group_leader.id=MagickXWindowByID(display,root_window,(Window)
+ strtol((char *) resource_info->window_group,(char **) NULL,0));
+ if (windows->group_leader.id == (Window) NULL)
+ windows->group_leader.id=
+ MagickXWindowByName(display,root_window,resource_info->window_group);
+ }
+ return(windows);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X M a k e C u r s o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakeCursor creates a crosshairs X11 cursor.
+%
+% The format of the MagickXMakeCursor method is:
+%
+% Cursor MagickXMakeCursor(Display *display,Window window,
+% Colormap colormap,char *background_color,char *foreground_color)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies the ID of the window for which the cursor is
+% assigned.
+%
+% o colormap: Specifies the ID of the colormap from which the background
+% and foreground color will be retrieved.
+%
+% o background_color: Specifies the color to use for the cursor background.
+%
+% o foreground_color: Specifies the color to use for the cursor foreground.
+%
+%
+*/
+MagickExport Cursor
+MagickXMakeCursor(Display *display,Window window,
+ Colormap colormap,char *background_color,
+ char *foreground_color)
+{
+#define scope_height 17
+#define scope_x_hot 8
+#define scope_y_hot 8
+#define scope_width 17
+
+ static const unsigned char
+ scope_bits[] =
+ {
+ 0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
+ 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f,
+ 0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00,
+ 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
+ 0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00
+ },
+ scope_mask_bits[] =
+ {
+ 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
+ 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f,
+ 0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01,
+ 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
+ 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00
+ };
+
+ Cursor
+ cursor;
+
+ Pixmap
+ mask,
+ source;
+
+ XColor
+ background,
+ foreground;
+
+ assert(display != (Display *) NULL);
+ assert(window != (Window) NULL);
+ assert(colormap != (Colormap) NULL);
+ assert(background_color != (char *) NULL);
+ assert(foreground_color != (char *) NULL);
+ source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width,
+ scope_height);
+ mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits,
+ scope_width,scope_height);
+ if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
+ {
+ MagickError(XServerError,UnableToCreatePixmap,(char *) NULL);
+ return((Cursor) NULL);
+ }
+ (void) XParseColor(display,colormap,background_color,&background);
+ (void) XParseColor(display,colormap,foreground_color,&foreground);
+ cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
+ scope_x_hot,scope_y_hot);
+ (void) XFreePixmap(display,source);
+ (void) XFreePixmap(display,mask);
+ return(cursor);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X M a k e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakeImage creates an X11 image. If the image size differs
+% from the X11 image size, the image is first resized.
+%
+% The format of the MagickXMakeImage method is:
+%
+% unsigned int MagickXMakeImage(Display *display,
+% const MagickXResourceInfo *resource_info,MagickXWindowInfo *window,
+% Image *image,unsigned int width,unsigned int height)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXMakeImage returns True if the X image is
+% successfully created. False is returned is there is a memory shortage.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+% o window: Specifies a pointer to a MagickXWindowInfo structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o width: Specifies the width in pixels of the rectangular area to
+% display.
+%
+% o height: Specifies the height in pixels of the rectangular area to
+% display.
+%
+%
+*/
+static const char *
+MagickXImageFormatToString(int xformat)
+{
+ static const char
+ *formats[] =
+ {
+ "XYBitmap",
+ "XYPixmap",
+ "ZPixmap"
+ };
+
+ const char
+ *format = "Unknown";
+
+ if ((size_t) xformat < sizeof(formats)/sizeof(formats[0]))
+ format=formats[xformat];
+
+ return format;
+}
+static const char *
+MagickXByteOrderToString(int xbyte_order)
+{
+ static const char
+ *byte_orders[] =
+ {
+ "LSBFirst",
+ "MSBFirst"
+ };
+
+ const char
+ *byte_order = "Unknown";
+
+ if ((size_t) xbyte_order < sizeof(byte_orders)/sizeof(byte_orders[0]))
+ byte_order=byte_orders[xbyte_order];
+
+ return byte_order;
+}
+MagickExport unsigned int
+MagickXMakeImage(Display *display,
+ const MagickXResourceInfo *resource_info,
+ MagickXWindowInfo *window,
+ Image *image,
+ unsigned int width,unsigned int height)
+{
+ int
+ depth,
+ format;
+
+ size_t
+ length;
+
+ XImage
+ *matte_image,
+ *ximage;
+
+ assert(display != (Display *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(window != (MagickXWindowInfo *) NULL);
+ assert(width != 0);
+ assert(height != 0);
+ if ((window->width == 0) || (window->height == 0))
+ return(False);
+ /*
+ Apply user transforms to the image.
+ */
+ (void) XDefineCursor(display,window->id,window->busy_cursor);
+ (void) XFlush(display);
+ depth=window->depth;
+ if (window->destroy && window->image)
+ DestroyImage(window->image);
+ window->image=image;
+ window->destroy=False;
+ if (window->image != (Image *) NULL)
+ {
+ MonitorHandler
+ handler=(MonitorHandler) NULL;
+
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ if (window->crop_geometry)
+ {
+ Image
+ *crop_image;
+
+ RectangleInfo
+ crop_info;
+
+ /*
+ Crop image.
+ */
+ SetGeometry(window->image,&crop_info);
+ (void) GetGeometry(window->crop_geometry,&crop_info.x,&crop_info.y,
+ &crop_info.width,&crop_info.height);
+ crop_image=CropImage(window->image,&crop_info,&image->exception);
+ if (crop_image != (Image *) NULL)
+ {
+ if (window->image != image)
+ DestroyImage(window->image);
+ window->image=crop_image;
+ window->destroy=MagickTrue;
+ }
+ }
+ if ((width != (unsigned int) window->image->columns) ||
+ (height != (unsigned int) window->image->rows))
+ {
+ Image
+ *resize_image;
+
+ /*
+ Resize image.
+ */
+ resize_image=(Image *) NULL;
+ if ((window->pixel_info->colors != 0) ||
+ (window->image->rows > (unsigned long) XDisplayHeight(display,window->screen)) ||
+ (window->image->columns > (unsigned long) XDisplayWidth(display,window->screen)))
+ {
+ /*
+ The resized image should be in the same storage class
+ as the original (or bad things will happen).
+ */
+ if (window->image->storage_class == PseudoClass)
+ resize_image=SampleImage(window->image,width,height,
+ &image->exception);
+ else
+ resize_image=ThumbnailImage(window->image,width,height,
+ &image->exception);
+ }
+ else
+ {
+ resize_image=ZoomImage(window->image,width,height,
+ &image->exception);
+ }
+ if (resize_image != (Image *) NULL)
+ {
+ if (window->image != image)
+ DestroyImage(window->image);
+ window->image=resize_image;
+ window->destroy=MagickTrue;
+ }
+ }
+ if ((window->image->matte != MagickFalse) &&
+ (window->pixel_info->colors == 0)
+ /* && (window->immutable == MagickFalse) */)
+ {
+ Image
+ *texture;
+
+ /*
+ Tile background with texture according to opacity
+ */
+ strlcpy(resource_info->image_info->filename,"image:checkerboard",
+ sizeof(resource_info->image_info->filename));
+ texture=ReadImage(resource_info->image_info,&window->image->exception);
+ if (texture != (Image *) NULL)
+ {
+ Image
+ *textured_image;
+
+ textured_image=CloneImage(window->image,0,0,MagickTrue,
+ &window->image->exception);
+ if (textured_image != (Image *) NULL)
+ {
+ if (TextureImage(textured_image,texture) != MagickFail)
+ {
+ if (window->image != image)
+ DestroyImage(window->image);
+ window->image=textured_image;
+ window->destroy=MagickTrue;
+ }
+ else
+ {
+ DestroyImage(textured_image);
+ }
+ }
+ DestroyImage(texture);
+ texture=(Image *) NULL;
+ }
+ }
+ width=(unsigned int) window->image->columns;
+ assert(width == window->image->columns);
+ height=(unsigned int) window->image->rows;
+ assert(height == window->image->rows);
+ (void) SetMonitorHandler(handler);
+ }
+ /*
+ Create X image.
+ */
+ ximage=(XImage *) NULL;
+ format=(depth == 1) ? XYBitmap : ZPixmap;
+#if defined(HasSharedMemory)
+ window->shared_memory &= XShmQueryExtension(display);
+ if (window->shared_memory)
+ {
+ XShmSegmentInfo
+ *segment_info;
+
+ size_t
+ shm_extent;
+
+ segment_info=(XShmSegmentInfo *) window->segment_info;
+ segment_info[1].shmid=(-1);
+ segment_info[1].shmaddr=NULL;
+ ximage=XShmCreateImage(display,window->visual,depth,format,(char *) NULL,
+ &segment_info[1],width,height);
+ window->shared_memory &= (ximage != (XImage *) NULL);
+
+ if (window->shared_memory)
+ {
+ shm_extent=MagickArraySize(ximage->height,ximage->bytes_per_line);
+ window->shared_memory &= (shm_extent != 0);
+ }
+
+ if (window->shared_memory)
+ segment_info[1].shmid=shmget(IPC_PRIVATE,shm_extent,IPC_CREAT | 0777);
+ window->shared_memory &= (segment_info[1].shmid >= 0);
+
+ if (window->shared_memory)
+ segment_info[1].shmaddr=(char *) MagickShmAt(segment_info[1].shmid,0,0);
+ window->shared_memory &= (segment_info[1].shmaddr != NULL);
+
+ if (!window->shared_memory)
+ {
+ /*
+ Clean up if there is an error.
+ */
+ if (ximage != (XImage *) NULL)
+ {
+ XDestroyImage(ximage);
+ ximage=(XImage *) NULL;
+ }
+
+ if (segment_info[1].shmaddr)
+ {
+ (void) MagickShmDt(segment_info[1].shmaddr);
+ segment_info[1].shmaddr=NULL;
+ }
+
+ if (segment_info[1].shmid >= 0)
+ {
+ (void) MagickShmCtl(segment_info[1].shmid,IPC_RMID,0);
+ segment_info[1].shmid=(-1);
+ }
+ }
+ }
+#endif
+ /*
+ Allocate X image pixel data.
+ */
+#if defined(HasSharedMemory)
+ if (window->shared_memory)
+ {
+ XShmSegmentInfo
+ *segment_info;
+
+ Status
+ shm_attached;
+
+ (void) XSync(display,False);
+ xerror_alert=False;
+ segment_info=(XShmSegmentInfo *) window->segment_info;
+ ximage->data=segment_info[1].shmaddr;
+ segment_info[1].readOnly=False;
+ shm_attached=XShmAttach(display,&segment_info[1]);
+ if (shm_attached)
+ (void) XSync(display,False);
+ if (!shm_attached || xerror_alert)
+ {
+ window->shared_memory=False;
+ if (shm_attached)
+ (void) XShmDetach(display,&segment_info[1]);
+ ximage->data=NULL;
+ XDestroyImage(ximage);
+ ximage=(XImage *) NULL;
+ if (segment_info[1].shmid >= 0)
+ {
+ if (segment_info[1].shmaddr != NULL)
+ (void) MagickShmDt(segment_info[1].shmaddr);
+ (void) MagickShmCtl(segment_info[1].shmid,IPC_RMID,0);
+ segment_info[1].shmaddr=NULL;
+ segment_info[1].shmid=(-1);
+ }
+ }
+ }
+#endif
+ if (!window->shared_memory)
+ {
+ ximage=XCreateImage(display,window->visual,depth,format,0,(char *) NULL,
+ width,height,XBitmapPad(display),0);
+ }
+ if (ximage == (XImage *) NULL)
+ {
+ /*
+ Unable to create X image.
+ */
+ (void) XDefineCursor(display,window->id,window->cursor);
+ return(False);
+ }
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"XImage:");
+ (void) LogMagickEvent(X11Event,GetMagickModule()," width x height: %dx%d",
+ ximage->width,ximage->height);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," format: %s",
+ MagickXImageFormatToString(ximage->format));
+ (void) LogMagickEvent(X11Event,GetMagickModule()," byte order: %s",
+ MagickXByteOrderToString(ximage->byte_order));
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " bitmap unit, bit order, pad: %d %d %d",ximage->bitmap_unit,
+ ximage->bitmap_bit_order,ximage->bitmap_pad);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d",
+ ximage->depth);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," bytes per line: %d",
+ ximage->bytes_per_line);
+ (void) LogMagickEvent(X11Event,GetMagickModule()," bits per pixel: %d",
+ ximage->bits_per_pixel);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " red, green, blue masks: 0x%lx 0x%lx 0x%lx",ximage->red_mask,
+ ximage->green_mask,ximage->blue_mask);
+ }
+ if (!window->shared_memory)
+ {
+ if (ximage->format == XYBitmap)
+ ximage->data=
+ MagickAllocateArray(char *,
+ MagickArraySize(ximage->height,ximage->bytes_per_line),
+ ximage->depth);
+ else
+ ximage->data=
+ MagickAllocateArray(char *,ximage->height,ximage->bytes_per_line);
+ }
+ if (ximage->data == (char *) NULL)
+ {
+ /*
+ Unable to allocate pixel data.
+ */
+ XDestroyImage(ximage);
+ ximage=(XImage *) NULL;
+ (void) XDefineCursor(display,window->id,window->cursor);
+ return(False);
+ }
+ if (window->ximage != (XImage *) NULL)
+ {
+ /*
+ Destroy previous X image.
+ */
+ /* length=(size_t) window->ximage->bytes_per_line*window->ximage->height; */
+#if defined(HasSharedMemory)
+ if (window->segment_info != (XShmSegmentInfo *) NULL)
+ {
+ XShmSegmentInfo
+ *segment_info;
+
+ segment_info=(XShmSegmentInfo *) window->segment_info;
+ if (segment_info[0].shmid >= 0)
+ {
+ (void) XSync(display,False);
+ (void) XShmDetach(display,&segment_info[0]);
+ (void) XSync(display,False);
+ if (segment_info[0].shmaddr != NULL)
+ (void) MagickShmDt(segment_info[0].shmaddr);
+ (void) MagickShmCtl(segment_info[0].shmid,IPC_RMID,0);
+ segment_info[0].shmaddr=NULL;
+ segment_info[0].shmid=(-1);
+ window->ximage->data=(char *) NULL;
+ }
+ }
+#endif
+ MagickFreeMemory(window->ximage->data);
+ XDestroyImage(window->ximage);
+ window->ximage=(XImage *) NULL;
+ }
+#if defined(HasSharedMemory)
+ if (window->segment_info != (XShmSegmentInfo *) NULL)
+ {
+ XShmSegmentInfo
+ *segment_info;
+
+ segment_info=(XShmSegmentInfo *) window->segment_info;
+ segment_info[0]=segment_info[1];
+ }
+#endif
+ window->ximage=ximage;
+ matte_image=(XImage *) NULL;
+ if (window->shape && (window->image != (Image *) NULL))
+ if (window->image->matte &&
+ (width <= (unsigned int) XDisplayWidth(display,window->screen)) &&
+ (height <= (unsigned int) XDisplayHeight(display,window->screen)))
+ {
+ /*
+ Create matte image.
+ */
+ matte_image=XCreateImage(display,window->visual,1,XYBitmap,0,
+ (char *) NULL,width,height,XBitmapPad(display),0);
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Matte Image:");
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " width, height: %dx%d",matte_image->width,matte_image->height);
+ }
+ if (matte_image != (XImage *) NULL)
+ {
+ /*
+ Allocate matte image pixel data.
+ */
+ length=MagickArraySize(MagickArraySize(matte_image->bytes_per_line,
+ matte_image->height),
+ matte_image->depth);
+ matte_image->data=MagickAllocateMemory(char *,length);
+ if (matte_image->data == (char *) NULL)
+ {
+ XDestroyImage(matte_image);
+ matte_image=(XImage *) NULL;
+ }
+ }
+ }
+ if (window->matte_image != (XImage *) NULL)
+ {
+ /*
+ Free matte image.
+ */
+ MagickFreeMemory(window->matte_image->data);
+ XDestroyImage(window->matte_image);
+ window->matte_image=(XImage *) NULL;
+ }
+ window->matte_image=matte_image;
+ if (window->matte_pixmap != (Pixmap) NULL)
+ {
+ (void) XFreePixmap(display,window->matte_pixmap);
+ window->matte_pixmap=(Pixmap) NULL;
+#if defined(HasShape)
+ if (window->shape)
+ XShapeCombineMask(display,window->id,ShapeBounding,0,0,None,ShapeSet);
+#endif
+ }
+ window->stasis=False;
+ /*
+ Convert pixels to X image data.
+ */
+ if (window->image != (Image *) NULL)
+ {
+ if ((ximage->byte_order == LSBFirst) || ((ximage->format == XYBitmap) &&
+ (ximage->bitmap_bit_order == LSBFirst)))
+ MagickXMakeImageLSBFirst(resource_info,window,window->image,ximage,
+ matte_image);
+ else
+ MagickXMakeImageMSBFirst(resource_info,window,window->image,ximage,
+ matte_image);
+ }
+ if (window->matte_image != (XImage *) NULL)
+ {
+ /*
+ Create matte pixmap.
+ */
+ window->matte_pixmap=XCreatePixmap(display,window->id,width,height,1);
+ if (window->matte_pixmap != (Pixmap) NULL)
+ {
+ GC
+ graphics_context;
+
+ XGCValues
+ context_values;
+
+ /*
+ Copy matte image to matte pixmap.
+ */
+ context_values.background=1;
+ context_values.foreground=0;
+ graphics_context=XCreateGC(display,window->matte_pixmap,
+ GCBackground | GCForeground,&context_values);
+ (void) XPutImage(display,window->matte_pixmap,graphics_context,
+ window->matte_image,0,0,0,0,width,height);
+ (void) XFreeGC(display,graphics_context);
+#if defined(HasShape)
+ if (window->shape)
+ XShapeCombineMask(display,window->id,ShapeBounding,0,0,
+ window->matte_pixmap,ShapeSet);
+#endif
+ }
+ }
+ (void) MagickXMakePixmap(display,resource_info,window);
+ /*
+ Restore cursor.
+ */
+ (void) XDefineCursor(display,window->id,window->cursor);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X M a k e I m a g e L S B F i r s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakeImageLSBFirst initializes the pixel data of an X11 Image.
+% The X image pixels are copied in least-significant bit and byte first
+% order. The server's scanline pad is respected. Rather than using one or
+% two general cases, many special cases are found here to help speed up the
+% image conversion.
+%
+% The format of the MagickXMakeImageLSBFirst method is:
+%
+% void MagickXMakeMagnifyImage(Display *display,MagickXWindows *windows)
+%
+% A description of each parameter follows:
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo structure.
+%
+% o window: Specifies a pointer to a MagickXWindowInfo structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o ximage: Specifies a pointer to a XImage structure; returned from
+% XCreateImage.
+%
+% o matte_image: Specifies a pointer to a XImage structure; returned from
+% XCreateImage.
+%
+*/
+static void
+MagickXMakeImageLSBFirst(const MagickXResourceInfo *resource_info,
+ const MagickXWindowInfo *window,Image *image,
+ XImage *ximage,XImage *matte_image)
+{
+ int
+ y;
+
+ register const IndexPacket
+ *indexes;
+
+ register int
+ x;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ bit,
+ byte;
+
+ unsigned int
+ scanline_pad;
+
+ unsigned long
+ pixel,
+ *pixels;
+
+ XStandardColormap
+ *map_info;
+
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(window != (MagickXWindowInfo *) NULL);
+ assert(image != (Image *) NULL);
+ scanline_pad=ximage->bytes_per_line-
+ ((ximage->width*ximage->bits_per_pixel) >> 3);
+ map_info=window->map_info;
+ pixels=window->pixel_info->pixels;
+ q=(unsigned char *) ximage->data;
+ x=0;
+ if (ximage->format == XYBitmap)
+ {
+ register unsigned short
+ polarity;
+
+ unsigned char
+ background,
+ foreground;
+
+ /*
+ Convert image to big-endian bitmap.
+ */
+ background=(PixelIntensity(&window->pixel_info->foreground_color) <
+ PixelIntensity(&window->pixel_info->background_color) ? 0x80 : 0x00);
+ foreground=(PixelIntensity(&window->pixel_info->background_color) <
+ PixelIntensity(&window->pixel_info->foreground_color) ? 0x80 : 0x00);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensity(&image->colormap[0]) <
+ PixelIntensity(&image->colormap[1]);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte>>=1;
+ if (indexes[x] == polarity)
+ byte|=foreground;
+ else
+ byte|=background;
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ *q=byte >> (8-bit);
+ q+=scanline_pad;
+ }
+ }
+ else
+ if (window->pixel_info->colors != 0)
+ switch (ximage->bits_per_pixel)
+ {
+ case 2:
+ {
+ register unsigned int
+ nibble;
+
+ /*
+ Convert to 2 bit color-mapped X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ nibble=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=pixels[indexes[x]] & 0x0f;
+ switch (nibble)
+ {
+ case 0:
+ {
+ *q=(unsigned char) pixel;
+ nibble++;
+ break;
+ }
+ case 1:
+ {
+ *q|=(unsigned char) (pixel << 2);
+ nibble++;
+ break;
+ }
+ case 2:
+ {
+ *q|=(unsigned char) (pixel << 4);
+ nibble++;
+ break;
+ }
+ case 3:
+ {
+ *q|=(unsigned char) (pixel << 6);
+ q++;
+ nibble=0;
+ break;
+ }
+ }
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ case 4:
+ {
+ register unsigned int
+ nibble;
+
+ /*
+ Convert to 4 bit color-mapped X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ nibble=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=pixels[indexes[x]] & 0xf;
+ switch (nibble)
+ {
+ case 0:
+ {
+ *q=(unsigned char) pixel;
+ nibble++;
+ break;
+ }
+ case 1:
+ {
+ *q|=(unsigned char) (pixel << 4);
+ q++;
+ nibble=0;
+ break;
+ }
+ }
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ case 6:
+ case 8:
+ {
+ /*
+ Convert to 8 bit color-mapped X image.
+ */
+ if (resource_info->color_recovery &&
+ resource_info->quantize_info->dither)
+ {
+ MagickXDitherImage(image,ximage);
+ break;
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=pixels[indexes[x]];
+ *q++=(unsigned char) pixel;
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ default:
+ {
+ register int
+ k;
+
+ register unsigned int
+ bytes_per_pixel;
+
+ /*
+ Convert to multi-byte color-mapped X image.
+ */
+ bytes_per_pixel=ximage->bits_per_pixel >> 3;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=pixels[indexes[x]];
+ for (k=0; k < (int) bytes_per_pixel; k++)
+ {
+ *q++=(unsigned char) pixel;
+ pixel>>=8;
+ }
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ }
+ else
+ switch (ximage->bits_per_pixel)
+ {
+ case 2:
+ {
+ register unsigned int
+ nibble;
+
+ /*
+ Convert to contiguous 2 bit continuous-tone X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ nibble=0;
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=MagickXGammaPixel(map_info,p);
+ pixel&=0xf;
+ switch (nibble)
+ {
+ case 0:
+ {
+ *q=(unsigned char) pixel;
+ nibble++;
+ break;
+ }
+ case 1:
+ {
+ *q|=(unsigned char) (pixel << 2);
+ nibble++;
+ break;
+ }
+ case 2:
+ {
+ *q|=(unsigned char) (pixel << 4);
+ nibble++;
+ break;
+ }
+ case 3:
+ {
+ *q|=(unsigned char) (pixel << 6);
+ q++;
+ nibble=0;
+ break;
+ }
+ }
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ case 4:
+ {
+ register unsigned int
+ nibble;
+
+ /*
+ Convert to contiguous 4 bit continuous-tone X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ nibble=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=MagickXGammaPixel(map_info,p);
+ pixel&=0xf;
+ switch (nibble)
+ {
+ case 0:
+ {
+ *q=(unsigned char) pixel;
+ nibble++;
+ break;
+ }
+ case 1:
+ {
+ *q|=(unsigned char) (pixel << 4);
+ q++;
+ nibble=0;
+ break;
+ }
+ }
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ case 6:
+ case 8:
+ {
+ /*
+ Convert to contiguous 8 bit continuous-tone X image.
+ */
+ if (resource_info->color_recovery &&
+ resource_info->quantize_info->dither)
+ {
+ MagickXDitherImage(image,ximage);
+ break;
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=MagickXGammaPixel(map_info,p);
+ *q++=(unsigned char) pixel;
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ default:
+ {
+ if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
+ (map_info->green_max == 255) && (map_info->blue_max == 255) &&
+ (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
+ (map_info->blue_mult == 1))
+ {
+ /*
+ Convert to 32 bit continuous-tone X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
+ (blue_gamma != 1.0))
+ {
+ /*
+ Gamma correct image.
+ */
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *q++=ScaleQuantumToChar(MagickXBlueGamma(p->blue));
+ *q++=ScaleQuantumToChar(MagickXGreenGamma(p->green));
+ *q++=ScaleQuantumToChar(MagickXRedGamma(p->red));
+ *q++=0;
+ p++;
+ }
+ continue;
+ }
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *q++=ScaleQuantumToChar((Quantum) p->blue);
+ *q++=ScaleQuantumToChar((Quantum) p->green);
+ *q++=ScaleQuantumToChar((Quantum) p->red);
+ *q++=0;
+ p++;
+ }
+ }
+ }
+ else
+ if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
+ (map_info->green_max == 255) && (map_info->blue_max == 255) &&
+ (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
+ (map_info->blue_mult == 65536L))
+ {
+ /*
+ Convert to 32 bit continuous-tone X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
+ (blue_gamma != 1.0))
+ {
+ /*
+ Gamma correct image.
+ */
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *q++=ScaleQuantumToChar(MagickXRedGamma(p->red));
+ *q++=ScaleQuantumToChar(MagickXGreenGamma(p->green));
+ *q++=ScaleQuantumToChar(MagickXBlueGamma(p->blue));
+ *q++=0;
+ p++;
+ }
+ continue;
+ }
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *q++=ScaleQuantumToChar((Quantum) p->red);
+ *q++=ScaleQuantumToChar((Quantum) p->green);
+ *q++=ScaleQuantumToChar((Quantum) p->blue);
+ *q++=0;
+ p++;
+ }
+ }
+ }
+ else
+ {
+ register int
+ k;
+
+ register unsigned int
+ bytes_per_pixel;
+
+ /*
+ Convert to multi-byte continuous-tone X image.
+ */
+ bytes_per_pixel=ximage->bits_per_pixel >> 3;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ pixel=MagickXGammaPixel(map_info,p);
+ for (k=0; k < (int) bytes_per_pixel; k++)
+ {
+ *q++=(unsigned char) pixel;
+ pixel>>=8;
+ }
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ }
+ break;
+ }
+ }
+ if (matte_image != (XImage *) NULL)
+ {
+ /*
+ Initialize matte image.
+ */
+ scanline_pad=matte_image->bytes_per_line-
+ ((matte_image->width*matte_image->bits_per_pixel) >> 3);
+ q=(unsigned char *) matte_image->data;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ bit=0;
+ byte=0;
+ for (x=0; x < (long) image->columns; x++)
+ {
+ byte>>=1;
+ if (p->opacity == TransparentOpacity)
+ byte|=0x80;
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ p++;
+ }
+ if (bit != 0)
+ *q=byte >> (8-bit);
+ q+=scanline_pad;
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ M a g i c k X M a k e I m a g e M S B F i r s t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakeImageMSBFirst initializes the pixel data of an X11 Image.
+% The X image pixels are copied in most-significant bit and byte first order.
+% The server's scanline pad is also respected. Rather than using one or two
+% general cases, many special cases are found here to help speed up the image
+% conversion.
+%
+% The format of the MagickXMakeImageMSBFirst method is:
+%
+% MagickXMakeImageMSBFirst(resource_info,window,image,ximage,matte_image)
+%
+% A description of each parameter follows:
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+% o window: Specifies a pointer to a MagickXWindowInfo structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o ximage: Specifies a pointer to a XImage structure; returned from
+% XCreateImage.
+%
+% o matte_image: Specifies a pointer to a XImage structure; returned from
+% XCreateImage.
+%
+%
+*/
+static void
+MagickXMakeImageMSBFirst(const MagickXResourceInfo *resource_info,
+ const MagickXWindowInfo *window,Image *image,
+ XImage *ximage,XImage *matte_image)
+{
+ int
+ y;
+
+ register const IndexPacket
+ *indexes;
+
+ register int
+ x;
+
+ register const PixelPacket
+ *p;
+
+ register unsigned char
+ *q;
+
+ unsigned char
+ bit,
+ byte;
+
+ unsigned int
+ scanline_pad;
+
+ unsigned long
+ pixel,
+ *pixels;
+
+ XStandardColormap
+ *map_info;
+
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(window != (MagickXWindowInfo *) NULL);
+ assert(image != (Image *) NULL);
+ scanline_pad=ximage->bytes_per_line-
+ ((ximage->width*ximage->bits_per_pixel) >> 3);
+ map_info=window->map_info;
+ pixels=window->pixel_info->pixels;
+ q=(unsigned char *) ximage->data;
+ x=0;
+ if (ximage->format == XYBitmap)
+ {
+ register unsigned short
+ polarity;
+
+ unsigned char
+ background,
+ foreground;
+
+ /*
+ Convert image to big-endian bitmap.
+ */
+ background=(PixelIntensity(&window->pixel_info->foreground_color) <
+ PixelIntensity(&window->pixel_info->background_color) ? 0x01 : 0x00);
+ foreground=(PixelIntensity(&window->pixel_info->background_color) <
+ PixelIntensity(&window->pixel_info->foreground_color) ? 0x01 : 0x00);
+ polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+ if (image->colors == 2)
+ polarity=PixelIntensity(&image->colormap[0]) <
+ PixelIntensity(&image->colormap[1]);
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ bit=0;
+ byte=0;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ byte<<=1;
+ if (*indexes++ == polarity)
+ byte|=foreground;
+ else
+ byte|=background;
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ }
+ if (bit != 0)
+ *q=byte << (8-bit);
+ q+=scanline_pad;
+ }
+ }
+ else
+ if (window->pixel_info->colors != 0)
+ switch (ximage->bits_per_pixel)
+ {
+ case 2:
+ {
+ register unsigned int
+ nibble;
+
+ /*
+ Convert to 2 bit color-mapped X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ nibble=0;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ pixel=pixels[*indexes++] & 0xf;
+ switch (nibble)
+ {
+ case 0:
+ {
+ *q=(unsigned char) (pixel << 6);
+ nibble++;
+ break;
+ }
+ case 1:
+ {
+ *q|=(unsigned char) (pixel << 4);
+ nibble++;
+ break;
+ }
+ case 2:
+ {
+ *q|=(unsigned char) (pixel << 2);
+ nibble++;
+ break;
+ }
+ case 3:
+ {
+ *q|=(unsigned char) pixel;
+ q++;
+ nibble=0;
+ break;
+ }
+ }
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ case 4:
+ {
+ register unsigned int
+ nibble;
+
+ /*
+ Convert to 4 bit color-mapped X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ nibble=0;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ pixel=pixels[*indexes++] & 0xf;
+ switch (nibble)
+ {
+ case 0:
+ {
+ *q=(unsigned char) (pixel << 4);
+ nibble++;
+ break;
+ }
+ case 1:
+ {
+ *q|=(unsigned char) pixel;
+ q++;
+ nibble=0;
+ break;
+ }
+ }
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ case 6:
+ case 8:
+ {
+ /*
+ Convert to 8 bit color-mapped X image.
+ */
+ if (resource_info->color_recovery &&
+ resource_info->quantize_info->dither)
+ {
+ MagickXDitherImage(image,ximage);
+ break;
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=(long) image->columns; x > 0; x--)
+ *q++=(unsigned char) (pixels[*indexes++]);
+ q+=scanline_pad;
+ }
+ break;
+ }
+ default:
+ {
+ register int
+ k;
+
+ register unsigned int
+ bytes_per_pixel;
+
+ unsigned char
+ channel[sizeof(unsigned long)];
+
+ /*
+ Convert to 8 bit color-mapped X image.
+ */
+ bytes_per_pixel=ximage->bits_per_pixel >> 3;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ indexes=AccessImmutableIndexes(image);
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ pixel=pixels[*indexes++];
+ for (k=bytes_per_pixel-1; k >= 0; k--)
+ {
+ channel[k]=(unsigned char) pixel;
+ pixel>>=8;
+ }
+ for (k=0; k < (int) bytes_per_pixel; k++)
+ *q++=channel[k];
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ }
+ else
+ switch (ximage->bits_per_pixel)
+ {
+ case 2:
+ {
+ register unsigned int
+ nibble;
+
+ /*
+ Convert to 4 bit continuous-tone X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ nibble=0;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ pixel=MagickXGammaPixel(map_info,p);
+ pixel&=0xf;
+ switch (nibble)
+ {
+ case 0:
+ {
+ *q=(unsigned char) (pixel << 6);
+ nibble++;
+ break;
+ }
+ case 1:
+ {
+ *q|=(unsigned char) (pixel << 4);
+ nibble++;
+ break;
+ }
+ case 2:
+ {
+ *q|=(unsigned char) (pixel << 2);
+ nibble++;
+ break;
+ }
+ case 3:
+ {
+ *q|=(unsigned char) pixel;
+ q++;
+ nibble=0;
+ break;
+ }
+ }
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ case 4:
+ {
+ register unsigned int
+ nibble;
+
+ /*
+ Convert to 4 bit continuous-tone X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ nibble=0;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ pixel=MagickXGammaPixel(map_info,p);
+ pixel&=0xf;
+ switch (nibble)
+ {
+ case 0:
+ {
+ *q=(unsigned char) (pixel << 4);
+ nibble++;
+ break;
+ }
+ case 1:
+ {
+ *q|=(unsigned char) pixel;
+ q++;
+ nibble=0;
+ break;
+ }
+ }
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ case 6:
+ case 8:
+ {
+ /*
+ Convert to 8 bit continuous-tone X image.
+ */
+ if (resource_info->color_recovery &&
+ resource_info->quantize_info->dither)
+ {
+ MagickXDitherImage(image,ximage);
+ break;
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ pixel=MagickXGammaPixel(map_info,p);
+ *q++=(unsigned char) pixel;
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ break;
+ }
+ default:
+ {
+ if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
+ (map_info->green_max == 255) && (map_info->blue_max == 255) &&
+ (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
+ (map_info->blue_mult == 1))
+ {
+ /*
+ Convert to 32 bit continuous-tone X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
+ (blue_gamma != 1.0))
+ {
+ /*
+ Gamma correct image.
+ */
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *q++=0;
+ *q++=ScaleQuantumToChar(MagickXRedGamma(p->red));
+ *q++=ScaleQuantumToChar(MagickXGreenGamma(p->green));
+ *q++=ScaleQuantumToChar(MagickXBlueGamma(p->blue));
+ p++;
+ }
+ continue;
+ }
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *q++=0;
+ *q++=ScaleQuantumToChar((Quantum) p->red);
+ *q++=ScaleQuantumToChar((Quantum) p->green);
+ *q++=ScaleQuantumToChar((Quantum) p->blue);
+ p++;
+ }
+ }
+ }
+ else
+ if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
+ (map_info->green_max == 255) && (map_info->blue_max == 255) &&
+ (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
+ (map_info->blue_mult == 65536L))
+ {
+ /*
+ Convert to 32 bit continuous-tone X image.
+ */
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
+ (blue_gamma != 1.0))
+ {
+ /*
+ Gamma correct image.
+ */
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *q++=0;
+ *q++=ScaleQuantumToChar(MagickXBlueGamma(p->blue));
+ *q++=ScaleQuantumToChar(MagickXGreenGamma(p->green));
+ *q++=ScaleQuantumToChar(MagickXRedGamma(p->red));
+ p++;
+ }
+ continue;
+ }
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ *q++=0;
+ *q++=ScaleQuantumToChar((Quantum) p->blue);
+ *q++=ScaleQuantumToChar((Quantum) p->green);
+ *q++=ScaleQuantumToChar((Quantum) p->red);
+ p++;
+ }
+ }
+ }
+ else
+ {
+ register int
+ k;
+
+ register unsigned int
+ bytes_per_pixel;
+
+ unsigned char
+ channel[sizeof(unsigned long)];
+
+ /*
+ Convert to multi-byte continuous-tone X image.
+ */
+ bytes_per_pixel=ximage->bits_per_pixel >> 3;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,
+ &image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ pixel=MagickXGammaPixel(map_info,p);
+ for (k=bytes_per_pixel-1; k >= 0; k--)
+ {
+ channel[k]=(unsigned char) pixel;
+ pixel>>=8;
+ }
+ for (k=0; k < (int) bytes_per_pixel; k++)
+ *q++=channel[k];
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ }
+ break;
+ }
+ }
+ if (matte_image != (XImage *) NULL)
+ {
+ /*
+ Initialize matte image.
+ */
+ scanline_pad=matte_image->bytes_per_line-
+ ((matte_image->width*matte_image->bits_per_pixel) >> 3);
+ q=(unsigned char *) matte_image->data;
+ for (y=0; y < (long) image->rows; y++)
+ {
+ p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+ if (p == (const PixelPacket *) NULL)
+ break;
+ bit=0;
+ byte=0;
+ for (x=(long) image->columns; x > 0; x--)
+ {
+ byte<<=1;
+ if (p->opacity == TransparentOpacity)
+ byte|=0x01;
+ bit++;
+ if (bit == 8)
+ {
+ *q++=byte;
+ bit=0;
+ byte=0;
+ }
+ p++;
+ }
+ if (bit != 0)
+ *q=byte << (8-bit);
+ q+=scanline_pad;
+ }
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X M a k e M a g n i f y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakeMagnifyImage magnifies a region of an X image and
+% displays it.
+%
+% The format of the MagickXMakeMagnifyImage method is:
+%
+% MagickXMakeMagnifyImage(display,windows)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+%
+*/
+MagickExport void
+MagickXMakeMagnifyImage(Display *display,MagickXWindows *windows)
+{
+ char
+ tuple[MaxTextExtent];
+
+ int
+ y;
+
+ long
+ n;
+
+ register int
+ x;
+
+ register long
+ i;
+
+ register unsigned char
+ *p,
+ *q;
+
+ PixelPacket
+ color;
+
+ static char
+ text[MaxTextExtent];
+
+ static unsigned int
+ previous_magnify = 0;
+
+ static MagickXWindowInfo
+ magnify_window;
+
+ unsigned int
+ height,
+ j,
+ k,
+ l,
+ magnify,
+ scanline_pad,
+ width;
+
+ XImage
+ *ximage;
+
+ /*
+ Check boundary conditions.
+ */
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ magnify=1;
+ for (n=1; n < (long) windows->magnify.data; n++)
+ magnify<<=1;
+ while ((magnify*windows->image.ximage->width) < windows->magnify.width)
+ magnify<<=1;
+ while ((magnify*windows->image.ximage->height) < windows->magnify.height)
+ magnify<<=1;
+ while (magnify > windows->magnify.width)
+ magnify>>=1;
+ while (magnify > windows->magnify.height)
+ magnify>>=1;
+ if (magnify != previous_magnify)
+ {
+ unsigned int
+ status;
+
+ XTextProperty
+ window_name;
+
+ /*
+ New magnify factor: update magnify window name.
+ */
+ i=0;
+ while ((1 << i) <= (int) magnify)
+ i++;
+ FormatString(windows->magnify.name,"Magnify %luX",i);
+ status=XStringListToTextProperty(&windows->magnify.name,1,&window_name);
+ if (status != 0)
+ {
+ XSetWMName(display,windows->magnify.id,&window_name);
+ XSetWMIconName(display,windows->magnify.id,&window_name);
+ (void) XFree((void *) window_name.value);
+ }
+ }
+ previous_magnify=magnify;
+ ximage=windows->image.ximage;
+ width=windows->magnify.ximage->width;
+ height=windows->magnify.ximage->height;
+ if ((windows->magnify.x < 0) ||
+ (windows->magnify.x >= windows->image.ximage->width))
+ windows->magnify.x=windows->image.ximage->width >> 1;
+ x=windows->magnify.x-((width/magnify) >> 1);
+ if (x < 0)
+ x=0;
+ else
+ if (x > (int) (ximage->width-(width/magnify)))
+ x=ximage->width-width/magnify;
+ if ((windows->magnify.y < 0) ||
+ (windows->magnify.y >= windows->image.ximage->height))
+ windows->magnify.y=windows->image.ximage->height >> 1;
+ y=windows->magnify.y-((height/magnify) >> 1);
+ if (y < 0)
+ y=0;
+ else
+ if (y > (int) (ximage->height-(height/magnify)))
+ y=ximage->height-height/magnify;
+ q=(unsigned char *) windows->magnify.ximage->data;
+ scanline_pad=windows->magnify.ximage->bytes_per_line-
+ ((width*windows->magnify.ximage->bits_per_pixel) >> 3);
+ if (ximage->bits_per_pixel < 8)
+ {
+ register unsigned char
+ background,
+ byte,
+ foreground,
+ p_bit,
+ q_bit;
+
+ register unsigned int
+ plane;
+
+ MagickXPixelInfo
+ *pixel_info;
+
+ pixel_info=windows->magnify.pixel_info;
+ switch (ximage->bitmap_bit_order)
+ {
+ case LSBFirst:
+ {
+ /*
+ Magnify little-endian bitmap.
+ */
+ background=0x00;
+ foreground=0x80;
+ if (ximage->format == XYBitmap)
+ {
+ background=(PixelIntensity(&pixel_info->foreground_color) <
+ PixelIntensity(&pixel_info->background_color) ? 0x80 : 0x00);
+ foreground=(PixelIntensity(&pixel_info->background_color) <
+ PixelIntensity(&pixel_info->foreground_color) ? 0x80 : 0x00);
+ if (windows->magnify.depth > 1)
+ Swap(background,foreground);
+ }
+ for (i=0; i < (long) height; i+=magnify)
+ {
+ /*
+ Propogate pixel magnify rows.
+ */
+ for (j=0; j < magnify; j++)
+ {
+ p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
+ ((x*ximage->bits_per_pixel) >> 3);
+ p_bit=(x*ximage->bits_per_pixel) & 0x07;
+ q_bit=0;
+ byte=0;
+ for (k=0; k < width; k+=magnify)
+ {
+ /*
+ Propogate pixel magnify columns.
+ */
+ for (l=0; l < magnify; l++)
+ {
+ /*
+ Propogate each bit plane.
+ */
+ for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
+ {
+ byte>>=1;
+ if (*p & (0x01 << (p_bit+plane)))
+ byte|=foreground;
+ else
+ byte|=background;
+ q_bit++;
+ if (q_bit == 8)
+ {
+ *q++=byte;
+ q_bit=0;
+ byte=0;
+ }
+ }
+ }
+ p_bit+=ximage->bits_per_pixel;
+ if (p_bit == 8)
+ {
+ p++;
+ p_bit=0;
+ }
+ if (q_bit != 0)
+ *q=byte >> (8-q_bit);
+ q+=scanline_pad;
+ }
+ }
+ y++;
+ }
+ break;
+ }
+ case MSBFirst:
+ default:
+ {
+ /*
+ Magnify big-endian bitmap.
+ */
+ background=0x00;
+ foreground=0x01;
+ if (ximage->format == XYBitmap)
+ {
+ background=(PixelIntensity(&pixel_info->foreground_color) <
+ PixelIntensity(&pixel_info->background_color) ? 0x01 : 0x00);
+ foreground=(PixelIntensity(&pixel_info->background_color) <
+ PixelIntensity(&pixel_info->foreground_color) ? 0x01 : 0x00);
+ if (windows->magnify.depth > 1)
+ Swap(background,foreground);
+ }
+ for (i=0; i < (long) height; i+=magnify)
+ {
+ /*
+ Propogate pixel magnify rows.
+ */
+ for (j=0; j < magnify; j++)
+ {
+ p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
+ ((x*ximage->bits_per_pixel) >> 3);
+ p_bit=(x*ximage->bits_per_pixel) & 0x07;
+ q_bit=0;
+ byte=0;
+ for (k=0; k < width; k+=magnify)
+ {
+ /*
+ Propogate pixel magnify columns.
+ */
+ for (l=0; l < magnify; l++)
+ {
+ /*
+ Propogate each bit plane.
+ */
+ for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
+ {
+ byte<<=1;
+ if (*p & (0x80 >> (p_bit+plane)))
+ byte|=foreground;
+ else
+ byte|=background;
+ q_bit++;
+ if (q_bit == 8)
+ {
+ *q++=byte;
+ q_bit=0;
+ byte=0;
+ }
+ }
+ }
+ p_bit+=ximage->bits_per_pixel;
+ if (p_bit == 8)
+ {
+ p++;
+ p_bit=0;
+ }
+ if (q_bit != 0)
+ *q=byte << (8-q_bit);
+ q+=scanline_pad;
+ }
+ }
+ y++;
+ }
+ break;
+ }
+ }
+ }
+ else
+ switch (ximage->bits_per_pixel)
+ {
+ case 6:
+ case 8:
+ {
+ /*
+ Magnify 8 bit X image.
+ */
+ for (i=0; i < (long) height; i+=magnify)
+ {
+ /*
+ Propogate pixel magnify rows.
+ */
+ for (j=0; j < magnify; j++)
+ {
+ p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
+ ((x*ximage->bits_per_pixel) >> 3);
+ for (k=0; k < width; k+=magnify)
+ {
+ /*
+ Propogate pixel magnify columns.
+ */
+ for (l=0; l < magnify; l++)
+ *q++=(*p);
+ p++;
+ }
+ q+=scanline_pad;
+ }
+ y++;
+ }
+ break;
+ }
+ default:
+ {
+ register unsigned int
+ bytes_per_pixel,
+ m;
+
+ /*
+ Magnify multi-byte X image.
+ */
+ bytes_per_pixel=ximage->bits_per_pixel >> 3;
+ for (i=0; i < (long) height; i+=magnify)
+ {
+ /*
+ Propogate pixel magnify rows.
+ */
+ for (j=0; j < magnify; j++)
+ {
+ p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
+ ((x*ximage->bits_per_pixel) >> 3);
+ for (k=0; k < width; k+=magnify)
+ {
+ /*
+ Propogate pixel magnify columns.
+ */
+ for (l=0; l < magnify; l++)
+ for (m=0; m < bytes_per_pixel; m++)
+ *q++=(*(p+m));
+ p+=bytes_per_pixel;
+ }
+ q+=scanline_pad;
+ }
+ y++;
+ }
+ break;
+ }
+ }
+ /*
+ Copy X image to magnify pixmap.
+ */
+ x=windows->magnify.x-((width/magnify) >> 1);
+ if (x < 0)
+ x=(width >> 1)-windows->magnify.x*magnify;
+ else
+ if (x > (int) (ximage->width-(width/magnify)))
+ x=(ximage->width-windows->magnify.x)*magnify-(width >> 1);
+ else
+ x=0;
+ y=windows->magnify.y-((height/magnify) >> 1);
+ if (y < 0)
+ y=(height >> 1)-windows->magnify.y*magnify;
+ else
+ if (y > (int) (ximage->height-(height/magnify)))
+ y=(ximage->height-windows->magnify.y)*magnify-(height >> 1);
+ else
+ y=0;
+ if ((x != 0) || (y != 0))
+ (void) XFillRectangle(display,windows->magnify.pixmap,
+ windows->magnify.annotate_context,0,0,width,height);
+ (void) XPutImage(display,windows->magnify.pixmap,
+ windows->magnify.annotate_context,windows->magnify.ximage,0,0,x,y,width-x,
+ height-y);
+ if ((magnify > 1) && ((magnify <= (width >> 1)) &&
+ (magnify <= (height >> 1))))
+ {
+ RectangleInfo
+ highlight_info;
+
+ /*
+ Highlight center pixel.
+ */
+ highlight_info.x=(long) windows->magnify.width >> 1;
+ highlight_info.y=(long) windows->magnify.height >> 1;
+ highlight_info.width=magnify;
+ highlight_info.height=magnify;
+ (void) XDrawRectangle(display,windows->magnify.pixmap,
+ windows->magnify.highlight_context,(int) highlight_info.x,
+ (int) highlight_info.y,(unsigned int) highlight_info.width-1,
+ (unsigned int) highlight_info.height-1);
+ if (magnify > 2)
+ (void) XDrawRectangle(display,windows->magnify.pixmap,
+ windows->magnify.annotate_context,(int) highlight_info.x+1,
+ (int) highlight_info.y+1,(unsigned int) highlight_info.width-3,
+ (unsigned int) highlight_info.height-3);
+ }
+ /*
+ Show center pixel color.
+ */
+ (void) AcquireOnePixelByReference(windows->image.image,&color,windows->magnify.x,
+ windows->magnify.y,&windows->image.image->exception);
+ GetColorTuple(&color,windows->image.image->depth,windows->image.image->matte,
+ False,tuple);
+ FormatString(text," %+d%+d %.1024s ",windows->magnify.x,windows->magnify.y,
+ tuple);
+ height=windows->magnify.font_info->ascent+windows->magnify.font_info->descent;
+ x=windows->magnify.font_info->max_bounds.width >> 1;
+ y=windows->magnify.font_info->ascent+(height >> 2);
+ (void) XDrawImageString(display,windows->magnify.pixmap,
+ windows->magnify.annotate_context,x,y,text,(int) strlen(text));
+ y+=height;
+ (void) QueryColorname(windows->image.image,&color,X11Compliance,text,
+ &windows->image.image->exception);
+ (void) XDrawImageString(display,windows->magnify.pixmap,
+ windows->magnify.annotate_context,x,y,text,(int) strlen(text));
+ /*
+ Refresh magnify window.
+ */
+ magnify_window=windows->magnify;
+ magnify_window.x=0;
+ magnify_window.y=0;
+ MagickXRefreshWindow(display,&magnify_window,(XEvent *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X M a k e P i x m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakePixmap creates an X11 pixmap.
+%
+% The format of the MagickXMakePixmap method is:
+%
+% unsigned int MagickXMakePixmap(Display *display,
+% const MagickXResourceInfo *resource_info,
+% MagickXWindowInfo *window)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXMakePixmap returns True if the X pixmap is
+% successfully created. False is returned is there is a memory shortage.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindowInfo structure.
+%
+%
+*/
+static unsigned int
+MagickXMakePixmap(Display *display,
+ const MagickXResourceInfo *resource_info,
+ MagickXWindowInfo *window)
+{
+ unsigned int
+ height,
+ width;
+
+ assert(display != (Display *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(window != (MagickXWindowInfo *) NULL);
+ if (window->pixmap != (Pixmap) NULL)
+ {
+ /*
+ Destroy previous X pixmap.
+ */
+ (void) XFreePixmap(display,window->pixmap);
+ window->pixmap=(Pixmap) NULL;
+ }
+ if (!window->use_pixmap)
+ return(False);
+ if (window->ximage == (XImage *) NULL)
+ return(False);
+ /*
+ Display busy cursor.
+ */
+ (void) XDefineCursor(display,window->id,window->busy_cursor);
+ (void) XFlush(display);
+ /*
+ Create pixmap.
+ */
+ width=window->ximage->width;
+ height=window->ximage->height;
+ window->pixmap=XCreatePixmap(display,window->id,width,height,window->depth);
+ if (window->pixmap == (Pixmap) NULL)
+ {
+ /*
+ Unable to allocate pixmap.
+ */
+ (void) XDefineCursor(display,window->id,window->cursor);
+ return(False);
+ }
+ /*
+ Copy X image to pixmap.
+ */
+#if defined(HasSharedMemory)
+ if (window->shared_memory)
+ (void) XShmPutImage(display,window->pixmap,window->annotate_context,window->ximage,
+ 0,0,0,0,width,height,True);
+#endif
+ if (!window->shared_memory)
+ (void) XPutImage(display,window->pixmap,window->annotate_context,
+ window->ximage,0,0,0,0,width,height);
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Pixmap:");
+ (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %ux%u",
+ width,height);
+ }
+ /*
+ Restore cursor.
+ */
+ (void) XDefineCursor(display,window->id,window->cursor);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X M a k e S t a n d a r d C o l o r m a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakeStandardColormap creates an X11 Standard Colormap.
+%
+% The format of the MagickXMakeStandardColormap method is:
+%
+% MagickXMakeStandardColormap(display,visual_info,resource_info,image,
+% map_info,pixel)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
+% returned from XGetVisualInfo.
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+% o image: Specifies a pointer to an Image structure; returned from
+% ReadImage.
+%
+% o map_info: If a Standard Colormap type is specified, this structure is
+% initialized with info from the Standard Colormap.
+%
+% o pixel: Specifies a pointer to a MagickXPixelInfo structure.
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+static int IntensityCompare(const void *x,const void *y)
+{
+ DiversityPacket
+ *color_1,
+ *color_2;
+
+ color_1=(DiversityPacket *) x;
+ color_2=(DiversityPacket *) y;
+ return((int) (PixelIntensity(color_2)-PixelIntensity(color_1)));
+}
+
+static int PopularityCompare(const void *x,const void *y)
+{
+ DiversityPacket
+ *color_1,
+ *color_2;
+
+ color_1=(DiversityPacket *) x;
+ color_2=(DiversityPacket *) y;
+ return((int) color_2->count-(int) color_1->count);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+MagickExport void
+MagickXMakeStandardColormap(Display *display,
+ XVisualInfo *visual_info,
+ MagickXResourceInfo *resource_info,
+ Image *image,
+ XStandardColormap *map_info,
+ MagickXPixelInfo *pixel)
+{
+ Colormap
+ colormap;
+
+ int
+ status;
+
+ register IndexPacket
+ *indexes;
+
+ register PixelPacket
+ *q;
+
+ register long
+ i;
+
+ unsigned long
+ number_colors,
+ retain_colors;
+
+ unsigned short
+ gray_value;
+
+ XColor
+ color,
+ *colors,
+ *p;
+
+ assert(display != (Display *) NULL);
+ assert(visual_info != (XVisualInfo *) NULL);
+ assert(map_info != (XStandardColormap *) NULL);
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ assert(pixel != (MagickXPixelInfo *) NULL);
+ if (resource_info->map_type != (char *) NULL)
+ {
+ /*
+ Standard Colormap is already defined (i.e. xstdcmap).
+ */
+ MagickXGetPixelPacket(display,visual_info,map_info,resource_info,image,
+ pixel);
+ number_colors=(unsigned int) (map_info->base_pixel+
+ (map_info->red_max+1)*(map_info->green_max+1)*(map_info->blue_max+1));
+ if ((map_info->red_max*map_info->green_max*map_info->blue_max) != 0)
+ if (!image->matte && !resource_info->color_recovery &&
+ resource_info->quantize_info->dither &&
+ (number_colors < MaxColormapSize))
+ {
+ Image
+ *map_image;
+
+ /*
+ Improve image appearance with error diffusion.
+ */
+ map_image=AllocateImage((ImageInfo *) NULL);
+ if (map_image == (Image *) NULL)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(XServerFatalError,UnableToDitherImage));
+ map_image->columns=number_colors;
+ map_image->rows=1;
+ /*
+ Initialize colormap image.
+ */
+ q=SetImagePixels(map_image,0,0,map_image->columns,1);
+ if (q != (PixelPacket *) NULL)
+ {
+ for (i=0; i < (long) number_colors; i++)
+ {
+ q->red=0;
+ if (map_info->red_max != 0)
+ q->red=(Quantum) (((double) MaxRGB*
+ (i/map_info->red_mult))/map_info->red_max+0.5);
+ q->green=0;
+ if (map_info->green_max != 0)
+ q->green=(Quantum) (((double) MaxRGB*
+ ((i/map_info->green_mult) % (map_info->green_max+1)))/
+ map_info->green_max+0.5);
+ q->blue=0;
+ if (map_info->blue_max != 0)
+ q->blue=(Quantum) (((double) MaxRGB*
+ (i % map_info->green_mult))/map_info->blue_max+0.5);
+ q->opacity=TransparentOpacity;
+ q++;
+ }
+ (void) SyncImagePixels(map_image);
+ (void) MapImage(image,map_image,True);
+ }
+ MagickXGetPixelPacket(display,visual_info,map_info,resource_info,image,
+ pixel);
+ (void) SetImageType(image,TrueColorType);
+ DestroyImage(map_image);
+ }
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:");
+ (void) LogMagickEvent(X11Event,GetMagickModule()," colormap id: 0x%lx",
+ map_info->colormap);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " red, green, blue max: %lu %lu %lu",map_info->red_max,
+ map_info->green_max,map_info->blue_max);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
+ map_info->green_mult,map_info->blue_mult);
+ }
+ return;
+ }
+ if ((visual_info->class != DirectColor) &&
+ (visual_info->class != TrueColor))
+ if ((image->storage_class == DirectClass) ||
+ ((int) image->colors > visual_info->colormap_size))
+ {
+ QuantizeInfo
+ quantize_info;
+
+ /*
+ Image has more colors than the visual supports.
+ */
+ quantize_info=(*resource_info->quantize_info);
+ quantize_info.number_colors=visual_info->colormap_size;
+ (void) QuantizeImage(&quantize_info,image);
+ }
+ /*
+ Free previous and create new colormap.
+ */
+ (void) MagickXFreeStandardColormap(display,visual_info,map_info,pixel);
+ colormap=XDefaultColormap(display,visual_info->screen);
+ if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
+ colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen),
+ visual_info->visual,visual_info->class == DirectColor ?
+ AllocAll : AllocNone);
+ if (colormap == (Colormap) NULL)
+ MagickFatalError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateColormap);
+ /*
+ Initialize the map and pixel info structures.
+ */
+ MagickXGetMapInfo(visual_info,colormap,map_info);
+ MagickXGetPixelPacket(display,visual_info,map_info,resource_info,image,pixel);
+ /*
+ Allocating colors in server colormap is based on visual class.
+ */
+ switch (visual_info->class)
+ {
+ case StaticGray:
+ case StaticColor:
+ {
+ /*
+ Define Standard Colormap for StaticGray or StaticColor visual.
+ */
+ number_colors=image->colors;
+ colors=MagickAllocateArray(XColor *,
+ visual_info->colormap_size,sizeof(XColor));
+ if (colors == (XColor *) NULL)
+ MagickFatalError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateColormap);
+ p=colors;
+ color.flags=DoRed | DoGreen | DoBlue;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ color.red=ScaleQuantumToShort(MagickXRedGamma(image->colormap[i].red));
+ color.green=ScaleQuantumToShort(MagickXGreenGamma(image->colormap[i].green));
+ color.blue=ScaleQuantumToShort(MagickXBlueGamma(image->colormap[i].blue));
+ if (visual_info->class != StaticColor)
+ {
+ gray_value=(unsigned short) PixelIntensity(&color);
+ color.red=gray_value;
+ color.green=gray_value;
+ color.blue=gray_value;
+ }
+ status=XAllocColor(display,colormap,&color);
+ if (status == 0)
+ {
+ colormap=XCopyColormapAndFree(display,colormap);
+ (void) XAllocColor(display,colormap,&color);
+ }
+ pixel->pixels[i]=color.pixel;
+ *p++=color;
+ }
+ break;
+ }
+ case GrayScale:
+ case PseudoColor:
+ {
+ unsigned int
+ colormap_type;
+
+ /*
+ Define Standard Colormap for GrayScale or PseudoColor visual.
+ */
+ number_colors=image->colors;
+ colors=MagickAllocateArray(XColor *,
+ visual_info->colormap_size,sizeof(XColor));
+ if (colors == (XColor *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToCreateColormap);
+ /*
+ Preallocate our GUI colors.
+ */
+ (void) XAllocColor(display,colormap,&pixel->foreground_color);
+ (void) XAllocColor(display,colormap,&pixel->background_color);
+ (void) XAllocColor(display,colormap,&pixel->border_color);
+ (void) XAllocColor(display,colormap,&pixel->matte_color);
+ (void) XAllocColor(display,colormap,&pixel->highlight_color);
+ (void) XAllocColor(display,colormap,&pixel->shadow_color);
+ (void) XAllocColor(display,colormap,&pixel->depth_color);
+ (void) XAllocColor(display,colormap,&pixel->trough_color);
+ for (i=0; i < MaxNumberPens; i++)
+ (void) XAllocColor(display,colormap,&pixel->pen_colors[i]);
+ /*
+ Determine if image colors will "fit" into X server colormap.
+ */
+ colormap_type=resource_info->colormap;
+ status=XAllocColorCells(display,colormap,False,(unsigned long *) NULL,0,
+ pixel->pixels,(int) image->colors);
+ if (status != 0)
+ colormap_type=PrivateColormap;
+ if (colormap_type == SharedColormap)
+ {
+ DiversityPacket
+ *diversity;
+
+ int
+ y;
+
+ register int
+ x;
+
+ unsigned short
+ colormap_index;
+
+ XColor
+ *server_colors;
+
+ /*
+ Define Standard colormap for shared GrayScale or PseudoColor visual.
+ */
+ diversity=MagickAllocateArray(DiversityPacket *,
+ image->colors,sizeof(DiversityPacket));
+ if (diversity == (DiversityPacket *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToCreateColormap);
+ for (i=0; i < (long) image->colors; i++)
+ {
+ diversity[i].red=image->colormap[i].red;
+ diversity[i].green=image->colormap[i].green;
+ diversity[i].blue=image->colormap[i].blue;
+ diversity[i].index=(unsigned short) i;
+ diversity[i].count=0;
+ }
+ for (y=0; y < (long) image->rows; y++)
+ {
+ q=GetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ indexes=AccessMutableIndexes(image);
+ for (x=0; x < (long) image->columns; x++)
+ diversity[indexes[x]].count++;
+ }
+ /*
+ Sort colors by decreasing intensity.
+ */
+ qsort((void *) diversity,image->colors,sizeof(DiversityPacket),
+ IntensityCompare);
+ for (i=0; i < (long) image->colors; i+=Max(image->colors >> 4,2))
+ diversity[i].count<<=4; /* increase this colors popularity */
+ diversity[image->colors-1].count<<=4;
+ qsort((void *) diversity,image->colors,sizeof(DiversityPacket),
+ PopularityCompare);
+ /*
+ Allocate colors.
+ */
+ p=colors;
+ color.flags=DoRed | DoGreen | DoBlue;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ colormap_index=diversity[i].index;
+ color.red=
+ ScaleQuantumToShort(MagickXRedGamma(image->colormap[colormap_index].red));
+ color.green=
+ ScaleQuantumToShort(MagickXGreenGamma(image->colormap[colormap_index].green));
+ color.blue=
+ ScaleQuantumToShort(MagickXBlueGamma(image->colormap[colormap_index].blue));
+ if (visual_info->class != PseudoColor)
+ {
+ gray_value=(unsigned short) PixelIntensity(&color);
+ color.red=gray_value;
+ color.green=gray_value;
+ color.blue=gray_value;
+ }
+ status=XAllocColor(display,colormap,&color);
+ if (status == 0)
+ break;
+ pixel->pixels[colormap_index]=color.pixel;
+ *p++=color;
+ }
+ /*
+ Read X server colormap.
+ */
+ server_colors=MagickAllocateArray(XColor *,
+ visual_info->colormap_size,
+ sizeof(XColor));
+ if (server_colors == (XColor *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToCreateColormap);
+ for (x=0; x < visual_info->colormap_size; x++)
+ server_colors[x].pixel=(unsigned long) x;
+ (void) XQueryColors(display,colormap,server_colors,
+ (int) Min(visual_info->colormap_size,256));
+ /*
+ Select remaining colors from X server colormap.
+ */
+ for (; i < (long) image->colors; i++)
+ {
+ colormap_index=diversity[i].index;
+ color.red=
+ ScaleQuantumToShort(MagickXRedGamma(image->colormap[colormap_index].red));
+ color.green=
+ ScaleQuantumToShort(MagickXGreenGamma(image->colormap[colormap_index].green));
+ color.blue=
+ ScaleQuantumToShort(MagickXBlueGamma(image->colormap[colormap_index].blue));
+ if (visual_info->class != PseudoColor)
+ {
+ gray_value=(unsigned short) PixelIntensity(&color);
+ color.red=gray_value;
+ color.green=gray_value;
+ color.blue=gray_value;
+ }
+ MagickXBestPixel(display,colormap,server_colors,(unsigned int)
+ visual_info->colormap_size,&color);
+ pixel->pixels[colormap_index]=color.pixel;
+ *p++=color;
+ }
+ if ((int) image->colors < visual_info->colormap_size)
+ {
+ /*
+ Fill up colors array-- more choices for pen colors.
+ */
+ retain_colors=Min(visual_info->colormap_size-image->colors,256);
+ for (i=0; i < (long) retain_colors; i++)
+ *p++=server_colors[i];
+ number_colors+=retain_colors;
+ }
+ MagickFreeMemory(server_colors);
+ MagickFreeMemory(diversity);
+ break;
+ }
+ /*
+ Define Standard colormap for private GrayScale or PseudoColor visual.
+ */
+ if (status == 0)
+ {
+ /*
+ Not enough colormap entries in the colormap-- Create a new colormap.
+ */
+ colormap=XCreateColormap(display,
+ XRootWindow(display,visual_info->screen),visual_info->visual,
+ AllocNone);
+ if (colormap == (Colormap) NULL)
+ MagickFatalError3(ResourceLimitError,MemoryAllocationFailed,
+ UnableToCreateColormap);
+ map_info->colormap=colormap;
+ if ((int) image->colors < visual_info->colormap_size)
+ {
+ /*
+ Retain colors from the default colormap to help lessens the
+ effects of colormap flashing.
+ */
+ retain_colors=Min(visual_info->colormap_size-image->colors,256);
+ p=colors+image->colors;
+ for (i=0; i < (long) retain_colors; i++)
+ {
+ p->pixel=(unsigned long) i;
+ p++;
+ }
+ (void) XQueryColors(display,
+ XDefaultColormap(display,visual_info->screen),
+ colors+image->colors,(int) retain_colors);
+ /*
+ Transfer colors from default to private colormap.
+ */
+ (void) XAllocColorCells(display,colormap,False,(unsigned long *)
+ NULL,0,pixel->pixels,(int) retain_colors);
+ p=colors+image->colors;
+ for (i=0; i < (long) retain_colors; i++)
+ {
+ p->pixel=pixel->pixels[i];
+ p++;
+ }
+ (void) XStoreColors(display,colormap,colors+image->colors,
+ (int) retain_colors);
+ number_colors+=retain_colors;
+ }
+ (void) XAllocColorCells(display,colormap,False,(unsigned long *) NULL,
+ 0,pixel->pixels,(int) image->colors);
+ }
+ /*
+ Store the image colormap.
+ */
+ p=colors;
+ color.flags=DoRed | DoGreen | DoBlue;
+ for (i=0; i < (long) image->colors; i++)
+ {
+ color.red=ScaleQuantumToShort(MagickXRedGamma(image->colormap[i].red));
+ color.green=ScaleQuantumToShort(MagickXGreenGamma(image->colormap[i].green));
+ color.blue=ScaleQuantumToShort(MagickXBlueGamma(image->colormap[i].blue));
+ if (visual_info->class != PseudoColor)
+ {
+ gray_value=(unsigned short) PixelIntensity(&color);
+ color.red=gray_value;
+ color.green=gray_value;
+ color.blue=gray_value;
+ }
+ color.pixel=pixel->pixels[i];
+ *p++=color;
+ }
+ (void) XStoreColors(display,colormap,colors,(int) image->colors);
+ break;
+ }
+ case TrueColor:
+ case DirectColor:
+ default:
+ {
+ unsigned int
+ linear_colormap;
+
+ /*
+ Define Standard Colormap for TrueColor or DirectColor visual.
+ */
+ number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+
+ (map_info->green_max*map_info->green_mult)+
+ (map_info->blue_max*map_info->blue_mult)+1);
+ linear_colormap=(number_colors > 4096) ||
+ (((int) (map_info->red_max+1) == visual_info->colormap_size) &&
+ ((int) (map_info->green_max+1) == visual_info->colormap_size) &&
+ ((int) (map_info->blue_max+1) == visual_info->colormap_size));
+ if (linear_colormap)
+ number_colors=visual_info->colormap_size;
+ /*
+ Allocate color array.
+ */
+ colors=MagickAllocateArray(XColor *,number_colors,sizeof(XColor));
+ if (colors == (XColor *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToCreateColormap);
+ /*
+ Initialize linear color ramp.
+ */
+ p=colors;
+ color.flags=DoRed | DoGreen | DoBlue;
+ if (linear_colormap)
+ for (i=0; i < (long) number_colors; i++)
+ {
+ color.blue=(unsigned short) 0;
+ if (map_info->blue_max != 0)
+ color.blue=(unsigned short) ((unsigned long)
+ ((65535L*(i % map_info->green_mult))/map_info->blue_max));
+ color.green=color.blue;
+ color.red=color.blue;
+ color.pixel=MagickXStandardPixel(map_info,&color);
+ *p++=color;
+ }
+ else
+ for (i=0; i < (long) number_colors; i++)
+ {
+ color.red=(unsigned short) 0;
+ if (map_info->red_max != 0)
+ color.red=(unsigned short) ((unsigned long)
+ ((65535L*(i/map_info->red_mult))/map_info->red_max));
+ color.green=(unsigned int) 0;
+ if (map_info->green_max != 0)
+ color.green=(unsigned short) ((unsigned long)
+ ((65535L*((i/map_info->green_mult) % (map_info->green_max+1)))/
+ map_info->green_max));
+ color.blue=(unsigned short) 0;
+ if (map_info->blue_max != 0)
+ color.blue=(unsigned short) ((unsigned long)
+ ((65535L*(i % map_info->green_mult))/map_info->blue_max));
+ color.pixel=MagickXStandardPixel(map_info,&color);
+ *p++=color;
+ }
+ if ((visual_info->class == DirectColor) &&
+ (colormap != XDefaultColormap(display,visual_info->screen)))
+ (void) XStoreColors(display,colormap,colors,(int) number_colors);
+ else
+ for (i=0; i < (long) number_colors; i++)
+ (void) XAllocColor(display,colormap,&colors[i]);
+ break;
+ }
+ }
+ if ((visual_info->class != DirectColor) &&
+ (visual_info->class != TrueColor))
+ {
+ /*
+ Set foreground, background, border, etc. pixels.
+ */
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->foreground_color);
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->background_color);
+ if (pixel->background_color.pixel == pixel->foreground_color.pixel)
+ {
+ /*
+ Foreground and background colors must differ.
+ */
+ pixel->background_color.red=(~pixel->foreground_color.red);
+ pixel->background_color.green=
+ (~pixel->foreground_color.green);
+ pixel->background_color.blue=
+ (~pixel->foreground_color.blue);
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->background_color);
+ }
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->border_color);
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->matte_color);
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->highlight_color);
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->shadow_color);
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->depth_color);
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->trough_color);
+ for (i=0; i < MaxNumberPens; i++)
+ {
+ MagickXBestPixel(display,colormap,colors,(int) number_colors,
+ &pixel->pen_colors[i]);
+ pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
+ }
+ pixel->colors=image->colors+MaxNumberPens;
+ }
+ MagickFreeMemory(colors);
+ if (IsEventLogging())
+ {
+ (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:");
+ (void) LogMagickEvent(X11Event,GetMagickModule()," colormap id: 0x%lx",
+ map_info->colormap);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " red, green, blue max: %lu %lu %lu",map_info->red_max,
+ map_info->green_max,map_info->blue_max);
+ (void) LogMagickEvent(X11Event,GetMagickModule(),
+ " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
+ map_info->green_mult,map_info->blue_mult);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X M a k e W i n d o w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMakeWindow creates an X11 window.
+%
+% The format of the MagickXMakeWindow method is:
+%
+% void MagickXMakeWindow(Display *display,Window parent,char **argv,
+% int argc,XClassHint *class_hint,XWMHints *manager_hints,
+% MagickXWindowInfo *window_info)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o parent: Specifies the parent window_info.
+%
+% o argv: Specifies the application's argument list.
+%
+% o argc: Specifies the number of arguments.
+%
+% o class_hint: Specifies a pointer to a X11 XClassHint structure.
+%
+% o manager_hints: Specifies a pointer to a X11 XWMHints structure.
+%
+% o window_info: Specifies a pointer to a X11 MagickXWindowInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXMakeWindow(Display *display,Window parent,char **argv,
+ int argc,XClassHint *class_hint,XWMHints *manager_hints,
+ MagickXWindowInfo *window_info)
+{
+#define MinWindowSize 64
+
+ Atom
+ atom_list[2];
+
+ int
+ gravity,
+ status;
+
+ static XTextProperty
+ icon_name,
+ window_name;
+
+ XSizeHints
+ *size_hints;
+
+ /*
+ Set window info hints.
+ */
+ assert(display != (Display *) NULL);
+ assert(window_info != (MagickXWindowInfo *) NULL);
+ size_hints=XAllocSizeHints();
+ if (size_hints == (XSizeHints *) NULL)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ MagickMsg(XServerFatalError,UnableToMakeXWindow));
+ size_hints->flags=(long) window_info->flags;
+ size_hints->x=window_info->x;
+ size_hints->y=window_info->y;
+ size_hints->width=window_info->width;
+ size_hints->height=window_info->height;
+ if (window_info->immutable)
+ {
+ /*
+ Window size cannot be changed.
+ */
+ size_hints->min_width=size_hints->width;
+ size_hints->min_height=size_hints->height;
+ size_hints->max_width=size_hints->width;
+ size_hints->max_height=size_hints->height;
+ size_hints->flags|=PMinSize;
+ size_hints->flags|=PMaxSize;
+ }
+ else
+ {
+ /*
+ Window size can be changed.
+ */
+ size_hints->min_width=window_info->min_width;
+ size_hints->min_height=window_info->min_height;
+ size_hints->flags|=PResizeInc;
+ size_hints->width_inc=window_info->width_inc;
+ size_hints->height_inc=window_info->height_inc;
+#if !defined(PRE_R4_ICCCM)
+ size_hints->flags|=PBaseSize;
+ size_hints->base_width=size_hints->width_inc;
+ size_hints->base_height=size_hints->height_inc;
+#endif
+ }
+ gravity=NorthWestGravity;
+ if (window_info->geometry != (char *) NULL)
+ {
+ char
+ default_geometry[MaxTextExtent],
+ geometry[MaxTextExtent];
+
+ int
+ flags;
+
+ register char
+ *p;
+
+ /*
+ User specified geometry.
+ */
+ FormatString(default_geometry,"%dx%d",size_hints->width,
+ size_hints->height);
+ (void) strlcpy(geometry,window_info->geometry,MaxTextExtent);
+ p=geometry;
+ while (strlen(p) != 0)
+ {
+ if (!isspace((int) (*p)) && (*p != '%'))
+ p++;
+ else
+ (void) memmove(p,p+1,strlen(p+1)+1);
+ }
+ flags=XWMGeometry(display,window_info->screen,geometry,default_geometry,
+ window_info->border_width,size_hints,&size_hints->x,&size_hints->y,
+ &size_hints->width,&size_hints->height,&gravity);
+ if ((flags & WidthValue) && (flags & HeightValue))
+ size_hints->flags|=USSize;
+ if ((flags & XValue) && (flags & YValue))
+ {
+ size_hints->flags|=USPosition;
+ window_info->x=size_hints->x;
+ window_info->y=size_hints->y;
+ }
+ }
+#if !defined(PRE_R4_ICCCM)
+ size_hints->win_gravity=gravity;
+ size_hints->flags|=PWinGravity;
+#endif
+ if (window_info->id == (Window) NULL)
+ window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y,
+ window_info->width,window_info->height,window_info->border_width,
+ window_info->depth,InputOutput,window_info->visual,window_info->mask,
+ &window_info->attributes);
+ else
+ {
+ unsigned int
+ mask;
+
+ XEvent
+ sans_event;
+
+ XWindowChanges
+ window_changes;
+
+ /*
+ Window already exists; change relevant attributes.
+ */
+ (void) XChangeWindowAttributes(display,window_info->id,window_info->mask,
+ &window_info->attributes);
+ mask=ConfigureNotify;
+ while (XCheckTypedWindowEvent(display,window_info->id,mask,&sans_event));
+ window_changes.x=window_info->x;
+ window_changes.y=window_info->y;
+ window_changes.width=window_info->width;
+ window_changes.height=window_info->height;
+ mask=CWWidth | CWHeight;
+ if (window_info->flags & USPosition)
+ mask|=CWX | CWY;
+ (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,
+ mask,&window_changes);
+ }
+ if (window_info->id == (Window) NULL)
+ MagickFatalError(XServerFatalError,UnableToCreateXWindow,
+ window_info->name);
+ status=XStringListToTextProperty(&window_info->name,1,&window_name);
+ if (status == 0)
+ MagickFatalError(XServerFatalError,UnableToCreateTextProperty,
+ window_info->name);
+ status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name);
+ if (status == 0)
+ MagickFatalError(XServerFatalError,UnableToCreateTextProperty,
+ window_info->icon_name);
+ if (window_info->icon_geometry != (char *) NULL)
+ {
+ int
+ flags,
+ height,
+ width;
+
+ /*
+ User specified icon geometry.
+ */
+ size_hints->flags|=USPosition;
+ flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry,
+ (char *) NULL,0,size_hints,&manager_hints->icon_x,
+ &manager_hints->icon_y,&width,&height,&gravity);
+ if ((flags & XValue) && (flags & YValue))
+ manager_hints->flags|=IconPositionHint;
+ }
+ XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc,
+ size_hints,manager_hints,class_hint);
+ if (window_name.value != NULL)
+ {
+ (void) XFree((void *) window_name.value);
+ window_name.value = NULL;
+ window_name.nitems=0;
+ }
+ if (icon_name.value != NULL)
+ {
+ (void) XFree((void *) icon_name.value);
+ icon_name.value = NULL;
+ icon_name.nitems=0;
+ }
+ atom_list[0]=XInternAtom(display,"WM_DELETE_WINDOW",False);
+ atom_list[1]=XInternAtom(display,"WM_TAKE_FOCUS",False);
+ (void) XSetWMProtocols(display,window_info->id,atom_list,2);
+ (void) XFree((void *) size_hints);
+ if (window_info->shape)
+ {
+#if defined(HasShape)
+ int
+ error_base=0,
+ event_base=0;
+
+ /*
+ Can we apply a non-rectangular shaping mask?
+ */
+ window_info->shape&=XShapeQueryExtension(display,&error_base,&event_base);
+#else
+ window_info->shape=False;
+#endif
+ }
+ if (window_info->shared_memory)
+ {
+#if defined(HasSharedMemory)
+ /*
+ Can we we use shared memory with this window?
+ */
+ window_info->shared_memory&=XShmQueryExtension(display);
+#else
+ window_info->shared_memory=False;
+#endif
+ }
+ window_info->image=(Image *) NULL;
+ window_info->destroy=False;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X P r o g r e s s M o n i t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXMagickMonitor displays the progress a task is making in
+% completing a task.
+%
+% The format of the MagickXMagickMonitor method is:
+%
+% unsigned int MagickXMagickMonitor(const char *task,
+% const magick_int64_t quantum,const magick_uint64_t span,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o task: Identifies the task in progress.
+%
+% o quantum: Specifies the quantum position within the span which represents
+% how much progress has been made in completing a task.
+%
+% o span: Specifies the span relative to completing a task.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+*/
+MagickExport unsigned int
+MagickXMagickMonitor(const char *task,
+ const magick_int64_t quantum,const magick_uint64_t span,
+ ExceptionInfo *exception)
+{
+ MagickXWindows
+ *windows;
+
+ ARG_NOT_USED(exception);
+ windows=MagickXSetWindows((MagickXWindows *) ~0);
+ if (windows == (MagickXWindows *) NULL)
+ return(True);
+ MagickXMonitorWidget(windows->display,windows,task,quantum,span);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X Q u e r y C o l o r D a t a b a s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXQueryColorDatabase looks up a RGB values for a color given
+% in the target string.
+%
+% The format of the MagickXQueryColorDatabase method is:
+%
+% unsigned int MagickXQueryColorDatabase(const char *target,XColor *color)
+%
+% A description of each parameter follows:
+%
+% o status: Method MagickXQueryColorDatabase returns True if the RGB values
+% of the target color is defined, otherwise False is returned.
+%
+% o target: Specifies the color to lookup in the X color database.
+%
+% o color: A pointer to an PixelPacket structure. The RGB value of the target
+% color is returned as this value.
+%
+%
+*/
+MagickExport unsigned int
+MagickXQueryColorDatabase(const char *target,XColor *color)
+{
+ Colormap
+ colormap;
+
+ int
+ status;
+
+ static Display
+ *display = (Display *) NULL;
+
+ XColor
+ xcolor;
+
+ /*
+ Initialize color return value.
+ */
+ assert(color != (XColor *) NULL);
+ color->red=0;
+ color->green=0;
+ color->blue=0;
+ color->flags=DoRed | DoGreen | DoBlue;
+ if ((target == (char *) NULL) || (*target == '\0'))
+ target="#ffffffffffff";
+ /*
+ Let the X server define the color for us.
+ */
+ if (display == (Display *) NULL)
+ display=XOpenDisplay((char *) NULL);
+ if (display == (Display *) NULL)
+ {
+ MagickError(XServerError,ColorIsNotKnownToServer,target);
+ return(False);
+ }
+ colormap=XDefaultColormap(display,XDefaultScreen(display));
+ status=XParseColor(display,colormap,(char *) target,&xcolor);
+ if (status == False)
+ MagickError(XServerError,ColorIsNotKnownToServer,target);
+ else
+ {
+ color->red=xcolor.red;
+ color->green=xcolor.green;
+ color->blue=xcolor.blue;
+ color->flags=xcolor.flags;
+ }
+ return(status != 0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X Q u e r y P o s i t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXQueryPosition gets the pointer coordinates relative to a
+% window.
+%
+% The format of the MagickXQueryPosition method is:
+%
+% void MagickXQueryPosition(Display *display,const Window window,
+% int *x,int *y)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a Window.
+%
+% o x: Return the x coordinate of the pointer relative to the origin of the
+% window.
+%
+% o y: Return the y coordinate of the pointer relative to the origin of the
+% window.
+%
+%
+*/
+MagickExport void
+MagickXQueryPosition(Display *display,const Window window,int *x,int *y)
+{
+ int
+ x_root,
+ y_root;
+
+ unsigned int
+ mask;
+
+ Window
+ root_window;
+
+ assert(display != (Display *) NULL);
+ assert(window != (Window) NULL);
+ assert(x != (int *) NULL);
+ assert(y != (int *) NULL);
+ (void) XQueryPointer(display,window,&root_window,&root_window,&x_root,&y_root,
+ x,y,&mask);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X R e f r e s h W i n d o w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXRefreshWindow refreshes an image in a X window.
+%
+% The format of the MagickXRefreshWindow method is:
+%
+% void MagickXRefreshWindow(Display *display,
+% const MagickXWindowInfo *window,const XEvent *event)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindowInfo structure.
+%
+% o event: Specifies a pointer to a XEvent structure. If it is NULL,
+% the entire image is refreshed.
+%
+%
+*/
+MagickExport void
+MagickXRefreshWindow(Display *display,const MagickXWindowInfo *window,
+ const XEvent *event)
+{
+ int
+ x,
+ y;
+
+ unsigned int
+ height,
+ width;
+
+ assert(display != (Display *) NULL);
+ assert(window != (MagickXWindowInfo *) NULL);
+ if (window->ximage == (XImage *) NULL)
+ return;
+ if (event != (XEvent *) NULL)
+ {
+ /*
+ Determine geometry from expose event.
+ */
+ x=event->xexpose.x;
+ y=event->xexpose.y;
+ width=event->xexpose.width;
+ height=event->xexpose.height;
+ }
+ else
+ {
+ XEvent
+ sans_event;
+
+ /*
+ Refresh entire window; discard outstanding expose events.
+ */
+ x=0;
+ y=0;
+ width=window->width;
+ height=window->height;
+ while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event));
+ }
+ /*
+ Check boundary conditions.
+ */
+ if ((window->ximage->width-(x+window->x)) < (int) width)
+ width=window->ximage->width-(x+window->x);
+ if ((window->ximage->height-(y+window->y)) < (int) height)
+ height=window->ximage->height-(y+window->y);
+ /*
+ Refresh image.
+ */
+ (void) XSetClipMask(display,window->annotate_context,window->matte_pixmap);
+ if (window->pixmap != (Pixmap) NULL)
+ {
+ if (window->depth > 1)
+ (void) XCopyArea(display,window->pixmap,window->id,
+ window->annotate_context,x+window->x,y+window->y,width,height,x,y);
+ else
+ (void) XCopyPlane(display,window->pixmap,window->id,
+ window->highlight_context,x+window->x,y+window->y,width,height,
+ x,y,1L);
+ }
+ else
+ {
+#if defined(HasSharedMemory)
+ if (window->shared_memory)
+ (void) XShmPutImage(display,window->id,window->annotate_context,
+ window->ximage,x+window->x,y+window->y,x,y,width,height,True);
+#endif /* defined(HasSharedMemory) */
+ if (!window->shared_memory)
+ (void) XPutImage(display,window->id,window->annotate_context,
+ window->ximage,x+window->x,y+window->y,x,y,width,height);
+ }
+ (void) XSetClipMask(display,window->annotate_context,None);
+ (void) XFlush(display);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X R e m o t e C o m m a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickXRemoteCommand() forces a remote display(1) to display the specified
+% image filename.
+%
+% The format of the MagickXRemoteCommand method is:
+%
+% unsigned int MagickXRemoteCommand(Display *display,const char *window,
+% const char *filename)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies the name or id of an X window.
+%
+% o filename: The name of the image filename to display.
+%
+%
+*/
+MagickExport unsigned int
+MagickXRemoteCommand(Display *display,const char *window,
+ const char *filename)
+{
+ Atom
+ remote_atom;
+
+ Window
+ remote_window,
+ root_window;
+
+ assert(filename != (char *) NULL);
+ if (display == (Display *) NULL)
+ display=XOpenDisplay((char *) NULL);
+ if (display == (Display *) NULL)
+ {
+ MagickError(XServerError,UnableToOpenXServer,(char *) NULL);
+ return(False);
+ }
+ remote_atom=XInternAtom(display,"IM_PROTOCOLS",False);
+ remote_window=(Window) NULL;
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ if (window != (char *) NULL)
+ {
+ /*
+ Search window hierarchy and identify any clients by name or ID.
+ */
+ if (isdigit((int) (*window)))
+ remote_window=MagickXWindowByID(display,root_window,(Window)
+ strtol((char *) window,(char **) NULL,0));
+ if (remote_window == (Window) NULL)
+ remote_window=MagickXWindowByName(display,root_window,window);
+ }
+ if (remote_window == (Window) NULL)
+ remote_window=MagickXWindowByProperty(display,root_window,remote_atom);
+ if (remote_window == (Window) NULL)
+ {
+ MagickError(XServerError,UnableToConnectToRemoteDisplay,(char *) NULL);
+ return(False);
+ }
+ /*
+ Send remote command.
+ */
+ remote_atom=XInternAtom(display,"IM_REMOTE_COMMAND",False);
+ (void) XChangeProperty(display,remote_window,remote_atom,XA_STRING,8,
+ PropModeReplace,(unsigned char *) filename,(int) strlen(filename));
+ (void) XSync(display,False);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X R e t a i n W i n d o w C o l o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXRetainWindowColors sets X11 color resources on a window.
+% This preserves the colors associated with an image displayed on the window.
+%
+% The format of the MagickXRetainWindowColors method is:
+%
+% void MagickXRetainWindowColors(Display *display,const Window window)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o window: Specifies a pointer to a MagickXWindowInfo structure.
+%
+%
+*/
+MagickExport void
+MagickXRetainWindowColors(Display *display,const Window window)
+{
+ Atom
+ property;
+
+ Pixmap
+ pixmap;
+
+ /*
+ Put property on the window.
+ */
+ assert(display != (Display *) NULL);
+ assert(window != (Window) NULL);
+ property=XInternAtom(display,"_XSETROOT_ID",False);
+ if (property == (Atom) NULL)
+ {
+ MagickError(XServerError,UnableToCreateProperty,"_XSETROOT_ID");
+ return;
+ }
+ pixmap=XCreatePixmap(display,window,1,1,1);
+ if (pixmap == (Pixmap) NULL)
+ {
+ MagickError(XServerError,UnableToCreatePixmap,(char *) NULL);
+ return;
+ }
+ (void) XChangeProperty(display,window,property,XA_PIXMAP,32,PropModeReplace,
+ (unsigned char *) &pixmap,1);
+ (void) XSetCloseDownMode(display,RetainPermanent);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X S e l e c t W i n d o w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXSelectWindow allows a user to select a window using the
+% mouse. If the mouse moves, a cropping rectangle is drawn and the extents
+% of the rectangle is returned in the crop_info structure.
+%
+% The format of the MagickXSelectWindow function is:
+%
+% target_window=MagickXSelectWindow(display,crop_info)
+%
+% A description of each parameter follows:
+%
+% o window: MagickXSelectWindow returns the window id.
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o crop_info: Specifies a pointer to a RectangleInfo structure. It
+% contains the extents of any cropping rectangle.
+%
+%
+*/
+static Window
+MagickXSelectWindow(Display *display,RectangleInfo *crop_info)
+{
+#define MinimumCropArea (unsigned int) 9
+
+ Cursor
+ target_cursor;
+
+ GC
+ annotate_context;
+
+ int
+ presses,
+ status,
+ x_offset,
+ y_offset;
+
+ Window
+ root_window,
+ target_window;
+
+ XEvent
+ event;
+
+ XGCValues
+ context_values;
+
+ /*
+ Initialize graphic context.
+ */
+ assert(display != (Display *) NULL);
+ assert(crop_info != (RectangleInfo *) NULL);
+ root_window=XRootWindow(display,XDefaultScreen(display));
+ context_values.background=XBlackPixel(display,XDefaultScreen(display));
+ context_values.foreground=XWhitePixel(display,XDefaultScreen(display));
+ context_values.function=GXinvert;
+ context_values.plane_mask=
+ context_values.background ^ context_values.foreground;
+ context_values.subwindow_mode=IncludeInferiors;
+ annotate_context=XCreateGC(display,root_window,GCBackground | GCForeground |
+ GCFunction | GCSubwindowMode,&context_values);
+ if (annotate_context == (GC) NULL)
+ return(False);
+ /*
+ Grab the pointer using target cursor.
+ */
+ target_cursor=MagickXMakeCursor(display,root_window,XDefaultColormap(display,
+ XDefaultScreen(display)),(char *) "white",(char *) "black");
+ status=XGrabPointer(display,root_window,False,(unsigned int)
+ (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync,
+ GrabModeAsync,root_window,target_cursor,CurrentTime);
+ if (status != GrabSuccess)
+ {
+ MagickError(XServerError,UnableToGrabMouse,(char *) NULL);
+ return(False);
+ }
+ /*
+ Select a window.
+ */
+ crop_info->width=0;
+ crop_info->height=0;
+ presses=0;
+ target_window=(Window) NULL;
+ x_offset=0;
+ y_offset=0;
+ do
+ {
+ if ((crop_info->width*crop_info->height) >= MinimumCropArea)
+ (void) XDrawRectangle(display,root_window,annotate_context,
+ (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
+ (unsigned int) crop_info->height-1);
+ /*
+ Allow another event.
+ */
+ (void) XAllowEvents(display,SyncPointer,CurrentTime);
+ (void) XWindowEvent(display,root_window,ButtonPressMask |
+ ButtonReleaseMask | ButtonMotionMask,&event);
+ if ((crop_info->width*crop_info->height) >= MinimumCropArea)
+ (void) XDrawRectangle(display,root_window,annotate_context,
+ (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
+ (unsigned int) crop_info->height-1);
+ switch (event.type)
+ {
+ case ButtonPress:
+ {
+ target_window=MagickXGetSubwindow(display,event.xbutton.subwindow,
+ event.xbutton.x,event.xbutton.y);
+ if (target_window == (Window) NULL)
+ target_window=root_window;
+ x_offset=event.xbutton.x_root;
+ y_offset=event.xbutton.y_root;
+ crop_info->x=x_offset;
+ crop_info->y=y_offset;
+ crop_info->width=0;
+ crop_info->height=0;
+ presses++;
+ break;
+ }
+ case ButtonRelease:
+ {
+ presses--;
+ break;
+ }
+ case MotionNotify:
+ {
+ /*
+ Discard pending button motion events.
+ */
+ while (XCheckMaskEvent(display,ButtonMotionMask,&event));
+ crop_info->x=event.xmotion.x;
+ crop_info->y=event.xmotion.y;
+ /*
+ Check boundary conditions.
+ */
+ if ((int) crop_info->x < x_offset)
+ crop_info->width=(unsigned int) (x_offset-crop_info->x);
+ else
+ {
+ crop_info->width=(unsigned int) (crop_info->x-x_offset);
+ crop_info->x=x_offset;
+ }
+ if ((int) crop_info->y < y_offset)
+ crop_info->height=(unsigned int) (y_offset-crop_info->y);
+ else
+ {
+ crop_info->height=(unsigned int) (crop_info->y-y_offset);
+ crop_info->y=y_offset;
+ }
+ }
+ default:
+ break;
+ }
+ }
+ while ((target_window == (Window) NULL) || (presses > 0));
+ (void) XUngrabPointer(display,CurrentTime);
+ (void) XFreeCursor(display,target_cursor);
+ (void) XFreeGC(display,annotate_context);
+ if ((crop_info->width*crop_info->height) < MinimumCropArea)
+ {
+ crop_info->width=0;
+ crop_info->height=0;
+ }
+ if ((crop_info->width != 0) && (crop_info->height != 0))
+ target_window=root_window;
+ return(target_window);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X S i g n a l H a n d l e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXSignalHandler is called if the program execution is
+% interrupted.
+%
+% The format of the MagickXSignalHandler method is:
+%
+% void MagickXSetCursorState(Display *display,MagickXWindows *windows,
+% const unsigned int state)
+%
+%
+*/
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+MagickExport void
+MagickXSignalHandler(int status)
+{
+ DestroyMagick();
+ Exit(status);
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X S e t C u r s o r S t a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXSetCursorState sets the cursor state to busy, otherwise the
+% cursor are reset to their default.
+%
+% The format of the XMagickXSetCursorState method is:
+%
+% MagickXSetCursorState(display,windows,state)
+%
+% A description of each parameter follows:
+%
+% o display: Specifies a connection to an X server; returned from
+% XOpenDisplay.
+%
+% o windows: Specifies a pointer to a MagickXWindows structure.
+%
+% o state: An unsigned integer greater than 0 sets the cursor state
+% to busy, otherwise the cursor are reset to their default.
+%
+%
+*/
+MagickExport void
+MagickXSetCursorState(Display *display,
+ MagickXWindows *windows,
+ const unsigned int state)
+{
+ assert(display != (Display *) NULL);
+ assert(windows != (MagickXWindows *) NULL);
+ if (state)
+ {
+ (void) XDefineCursor(display,windows->image.id,
+ windows->image.busy_cursor);
+ (void) XDefineCursor(display,windows->pan.id,windows->pan.busy_cursor);
+ (void) XDefineCursor(display,windows->magnify.id,
+ windows->magnify.busy_cursor);
+ (void) XDefineCursor(display,windows->command.id,
+ windows->command.busy_cursor);
+ }
+ else
+ {
+ (void) XDefineCursor(display,windows->image.id,windows->image.cursor);
+ (void) XDefineCursor(display,windows->pan.id,windows->pan.cursor);
+ (void) XDefineCursor(display,windows->magnify.id,windows->magnify.cursor);
+ (void) XDefineCursor(display,windows->command.id,windows->command.cursor);
+ (void) XDefineCursor(display,windows->command.id,windows->widget.cursor);
+ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
+ }
+ windows->info.mapped=False;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X S e t W i n d o w s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXSetWindows sets the X windows structure if the windows info
+% is specified. Otherwise the current windows structure is returned.
+%
+% The format of the MagickXSetWindows method is:
+%
+% MagickXWindows *MagickXSetWindows(MagickXWindows *windows_info)
+%
+% A description of each parameter follows:
+%
+% o windows: Method MagickXSetWindows returns a pointer to the
+% MagickXWindows structure.
+%
+% o windows_info: Initialize the Windows structure with this information.
+%
+*/
+MagickExport MagickXWindows *
+MagickXSetWindows(MagickXWindows *windows_info)
+{
+ static MagickXWindows
+ *windows = (MagickXWindows *) NULL;
+
+ if (windows_info != (MagickXWindows *) ~0)
+ {
+ MagickFreeMemory(windows);
+ windows=windows_info;
+ }
+ return(windows);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X U s e r P r e f e r e n c e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXUserPreferences saves the preferences in a configuration
+% file in the users' home directory.
+%
+% The format of the MagickXUserPreferences method is:
+%
+% void MagickXUserPreferences(MagickXResourceInfo *resource_info)
+%
+% A description of each parameter follows:
+%
+% o resource_info: Specifies a pointer to a X11 MagickXResourceInfo
+% structure.
+%
+%
+*/
+MagickExport void
+MagickXUserPreferences(MagickXResourceInfo *resource_info)
+{
+#if defined(PreferencesDefaults)
+ const char
+ *client_name;
+
+ char
+ cache[MaxTextExtent],
+ filename[MaxTextExtent],
+ specifier[MaxTextExtent];
+
+ const char
+ *value;
+
+ XrmDatabase
+ preferences_database;
+
+ /*
+ Save user preferences to the client configuration file.
+ */
+ assert(resource_info != (MagickXResourceInfo *) NULL);
+ client_name=GetClientName();
+ preferences_database=XrmGetStringDatabase("");
+ FormatString(specifier,"%.1024s.backdrop",client_name);
+ value=MagickBoolToString(resource_info->backdrop);
+ XrmPutStringResource(&preferences_database,specifier,(char *) value);
+ FormatString(specifier,"%.1024s.colormap",client_name);
+ value=resource_info->colormap == SharedColormap ? "Shared" : "Private";
+ XrmPutStringResource(&preferences_database,specifier,(char *) value);
+ FormatString(specifier,"%.1024s.confirmExit",client_name);
+ value=MagickBoolToString(resource_info->confirm_exit);
+ XrmPutStringResource(&preferences_database,specifier,(char *) value);
+ FormatString(specifier,"%.1024s.displayWarnings",client_name);
+ value=MagickBoolToString(resource_info->display_warnings);
+ XrmPutStringResource(&preferences_database,specifier,(char *) value);
+ FormatString(specifier,"%.1024s.dither",client_name);
+ value=MagickBoolToString(resource_info->quantize_info->dither);
+ XrmPutStringResource(&preferences_database,specifier,(char *) value);
+ FormatString(specifier,"%.1024s.gammaCorrect",client_name);
+ value=MagickBoolToString(resource_info->gamma_correct);
+ XrmPutStringResource(&preferences_database,specifier,(char *) value);
+ FormatString(specifier,"%.1024s.undoCache",client_name);
+ FormatString(cache,"%lu",resource_info->undo_cache);
+ XrmPutStringResource(&preferences_database,specifier,cache);
+ FormatString(specifier,"%.1024s.usePixmap",client_name);
+ value=MagickBoolToString(resource_info->use_pixmap);
+ XrmPutStringResource(&preferences_database,specifier,(char *) value);
+ FormatString(filename,"%.1024s%.1024src",PreferencesDefaults,client_name);
+ ExpandFilename(filename);
+ XrmPutFileDatabase(preferences_database,filename);
+#endif /* defined(PreferencesDefaults) */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X V i s u a l C l a s s N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXVisualClassName returns the visual class name as a character
+% string.
+%
+% The format of the MagickXVisualClassName method is:
+%
+% char *MagickXVisualClassName(const int visual_class)
+%
+% A description of each parameter follows:
+%
+% o visual_type: MagickXVisualClassName returns the visual class as a
+% character string.
+%
+% o class: Specifies the visual class.
+%
+%
+*/
+static char *
+MagickXVisualClassName(const int visual_class)
+{
+ switch (visual_class)
+ {
+ case StaticGray: return((char *) "StaticGray");
+ case GrayScale: return((char *) "GrayScale");
+ case StaticColor: return((char *) "StaticColor");
+ case PseudoColor: return((char *) "PseudoColor");
+ case TrueColor: return((char *) "TrueColor");
+ case DirectColor: return((char *) "DirectColor");
+ }
+ return((char *) "unknown visual class");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X W a r n i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXWarning displays a warning reason in a Notice widget.
+%
+% The format of the MagickXWarning method is:
+%
+% void MagickXWarning(const unsigned int warning,const char *reason,
+% const char *description)
+%
+% A description of each parameter follows:
+%
+% o warning: Specifies the numeric warning category.
+%
+% o reason: Specifies the reason to display before terminating the
+% program.
+%
+% o description: Specifies any description to the reason.
+%
+%
+*/
+MagickExport void
+MagickXWarning(const ExceptionType warning,
+ const char *reason,const char *description)
+{
+ char
+ text[MaxTextExtent];
+
+ MagickXWindows
+ *windows;
+
+ ARG_NOT_USED(warning);
+ if (reason == (char *) NULL)
+ return;
+ (void) strlcpy(text,reason,MaxTextExtent);
+ (void) strlcat(text,":",MaxTextExtent);
+ windows=MagickXSetWindows((MagickXWindows *) ~0);
+ MagickXNoticeWidget(windows->display,windows,text,(char *) description);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X W i n d o w B y I D %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXWindowByID locates a child window with a given ID. If not
+% window with the given name is found, 0 is returned. Only the window
+% specified and its subwindows are searched.
+%
+% The format of the MagickXWindowByID function is:
+%
+% child=MagickXWindowByID(display,window,id)
+%
+% A description of each parameter follows:
+%
+% o child: MagickXWindowByID returns the window with the specified
+% id. If no windows are found, MagickXWindowByID returns 0.
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o id: Specifies the id of the window to locate.
+%
+%
+*/
+MagickExport Window
+MagickXWindowByID(Display *display,const Window root_window,
+ const unsigned long id)
+{
+ RectangleInfo
+ rectangle_info;
+
+ register int
+ i;
+
+ unsigned int
+ number_children;
+
+ Window
+ child,
+ *children,
+ window;
+
+ assert(display != (Display *) NULL);
+ assert(root_window != (Window) NULL);
+ if (id == 0)
+ return(MagickXSelectWindow(display,&rectangle_info));
+ if (root_window == id)
+ return(id);
+ if (!XQueryTree(display,root_window,&child,&child,&children,&number_children))
+ return((Window) NULL);
+ window=(Window) NULL;
+ for (i=0; i < (int) number_children; i++)
+ {
+ /*
+ Search each child and their children.
+ */
+ window=MagickXWindowByID(display,children[i],id);
+ if (window != (Window) NULL)
+ break;
+ }
+ if (children != (Window *) NULL)
+ (void) XFree((void *) children);
+ return(window);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X W i n d o w B y N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXWindowByName locates a window with a given name on a display.
+% If no window with the given name is found, 0 is returned. If more than
+% one window has the given name, the first one is returned. Only root and
+% its children are searched.
+%
+% The format of the MagickXWindowByName function is:
+%
+% window=MagickXWindowByName(display,root_window,name)
+%
+% A description of each parameter follows:
+%
+% o window: MagickXWindowByName returns the window id.
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o root_window: Specifies the id of the root window.
+%
+% o name: Specifies the name of the window to locate.
+%
+%
+*/
+MagickExport Window
+MagickXWindowByName(Display *display,const Window root_window,
+ const char *name)
+{
+ register int
+ i;
+
+ unsigned int
+ number_children;
+
+ Window
+ *children,
+ child,
+ window;
+
+ XTextProperty
+ window_name;
+
+ assert(display != (Display *) NULL);
+ assert(root_window != (Window) NULL);
+ assert(name != (char *) NULL);
+ if (XGetWMName(display,root_window,&window_name) != 0)
+ if (LocaleCompare((char *) window_name.value,name) == 0)
+ return(root_window);
+ if (!XQueryTree(display,root_window,&child,&child,&children,&number_children))
+ return((Window) NULL);
+ window=(Window) NULL;
+ for (i=0; i < (int) number_children; i++)
+ {
+ /*
+ Search each child and their children.
+ */
+ window=MagickXWindowByName(display,children[i],name);
+ if (window != (Window) NULL)
+ break;
+ }
+ if (children != (Window *) NULL)
+ (void) XFree((void *) children);
+ return(window);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k X W i n d o w B y P r o p e r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method MagickXWindowByProperty locates a child window with a given property.
+% If no window with the given name is found, 0 is returned. If more than
+% one window has the given property, the first one is returned. Only the
+% window specified and its subwindows are searched.
+%
+% The format of the MagickXWindowByProperty function is:
+%
+% child=MagickXWindowByProperty(display,window,property)
+%
+% A description of each parameter follows:
+%
+% o child: MagickXWindowByProperty returns the window id with the specified
+% property. If no windows are found, MagickXWindowByProperty returns 0.
+%
+% o display: Specifies a pointer to the Display structure; returned from
+% XOpenDisplay.
+%
+% o property: Specifies the property of the window to locate.
+%
+%
+*/
+MagickExport Window
+MagickXWindowByProperty(Display *display,const Window window,
+ const Atom property)
+{
+ Atom
+ type;
+
+ int
+ format,
+ status;
+
+ unsigned char
+ *data;
+
+ unsigned int
+ i,
+ number_children;
+
+ unsigned long
+ after,
+ number_items;
+
+ Window
+ child,
+ *children,
+ parent,
+ root;
+
+ assert(display != (Display *) NULL);
+ assert(window != (Window) NULL);
+ assert(property != (Atom) NULL);
+ status=XQueryTree(display,window,&root,&parent,&children,&number_children);
+ if (status == 0)
+ return((Window) NULL);
+ type=(Atom) NULL;
+ child=(Window) NULL;
+ for (i=0; (i < number_children) && (child == (Window) NULL); i++)
+ {
+ status=XGetWindowProperty(display,children[i],property,0L,0L,False,
+ (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
+ if (data != NULL)
+ (void) XFree((void *) data);
+ if ((status == Success) && (type != (Atom) NULL))
+ child=children[i];
+ }
+ for (i=0; (i < number_children) && (child == (Window) NULL); i++)
+ child=MagickXWindowByProperty(display,children[i],property);
+ if (children != (Window *) NULL)
+ (void) XFree((void *) children);
+ return(child);
+}
+#endif /* HasX11 */
diff --git a/magick/xwindow.h b/magick/xwindow.h
new file mode 100644
index 0000000..b66ff97
--- /dev/null
+++ b/magick/xwindow.h
@@ -0,0 +1,646 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+ Copyright (C) 2002 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ X11 Utility Methods for ImageMagick.
+*/
+#ifndef _MAGICK_XWINDOW_H
+#define _MAGICK_XWINDOW_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if defined(HasX11)
+
+#undef False
+#undef True
+#define XLIB_ILLEGAL_ACCESS 1
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include <X11/Xlocale.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include <X11/XWDFile.h>
+
+/*
+ Remove X11 defines so enums are used
+*/
+#undef ForgetGravity
+#undef NorthWestGravity
+#undef NorthGravity
+#undef NorthEastGravity
+#undef WestGravity
+#undef CenterGravity
+#undef EastGravity
+#undef SouthWestGravity
+#undef SouthGravity
+#undef SouthEastGravity
+#undef StaticGravity
+
+#include "magick/quantize.h"
+#include "magick/PreRvIcccm.h"
+
+#undef index
+#if defined(hpux9)
+# define XFD_SET int
+#else
+# define XFD_SET fd_set
+#endif
+
+/*
+ Define declarations.
+*/
+#define MaxNumberPens 11
+#define MaxNumberFonts 11
+#define MaxIconSize 96
+#define MaxXWindows 10
+
+/*
+ Enumeration declarations.
+*/
+typedef enum
+{
+#undef DoRed
+ DoRed = 0x0001,
+#undef DoGreen
+ DoGreen = 0x0002,
+#undef DoBlue
+ DoBlue = 0x0004,
+ DoMatte = 0x0008
+} MagickXColorFlags;
+
+typedef enum
+{
+ ForegroundStencil,
+ BackgroundStencil,
+ OpaqueStencil,
+ TransparentStencil
+} AnnotationStencil;
+
+typedef enum
+{
+ UndefinedElement = 0,
+ PointElement,
+ LineElement,
+ RectangleElement,
+ FillRectangleElement,
+ CircleElement,
+ FillCircleElement,
+ EllipseElement,
+ FillEllipseElement,
+ PolygonElement,
+ FillPolygonElement,
+ ColorElement,
+ MatteElement,
+ TextElement,
+ ImageElement
+} ElementType;
+
+typedef enum
+{
+ UndefinedColormap,
+ PrivateColormap,
+ SharedColormap
+} MagickXColormapType;
+
+typedef enum
+{
+ DefaultState = 0x0000,
+ EscapeState = 0x0001,
+ ExitState = 0x0002,
+ FormerImageState = 0x0004,
+ ModifierState = 0x0008,
+ MontageImageState = 0x0010,
+ NextImageState = 0x0020,
+ RetainColorsState = 0x0040,
+ SuspendTime = 50,
+ UpdateConfigurationState = 0x0080,
+ UpdateRegionState = 0x0100
+} MagickXState;
+
+/*
+ Typedef declarations.
+*/
+typedef struct _DiversityPacket
+{
+ Quantum
+ red,
+ green,
+ blue;
+
+ unsigned short
+ index;
+
+ unsigned long
+ count;
+} DiversityPacket;
+
+typedef struct _MagickXAnnotateInfo
+{
+ struct _MagickXAnnotateInfo
+ *previous,
+ *next;
+
+ int
+ x,
+ y;
+
+ unsigned int
+ width,
+ height;
+
+ double
+ degrees;
+
+ XFontStruct
+ *font_info;
+
+ char
+ *text;
+
+ AnnotationStencil
+ stencil;
+
+ char
+ geometry[MaxTextExtent];
+} MagickXAnnotateInfo;
+
+typedef struct _MagickXDrawInfo
+{
+ int
+ x,
+ y;
+
+ unsigned int
+ width,
+ height;
+
+ double
+ degrees;
+
+ AnnotationStencil
+ stencil;
+
+ ElementType
+ element;
+
+ Pixmap
+ stipple;
+
+ unsigned int
+ line_width;
+
+ XSegment
+ line_info;
+
+ unsigned int
+ number_coordinates;
+
+ RectangleInfo
+ rectangle_info;
+
+ XPoint
+ *coordinate_info;
+
+ char
+ geometry[MaxTextExtent];
+} MagickXDrawInfo;
+
+typedef struct _MagickXImportInfo
+{
+ unsigned int
+ frame,
+ borders,
+ screen,
+ descend,
+ silent;
+} MagickXImportInfo;
+
+typedef struct _MagickXPixelInfo
+{
+ unsigned long
+ colors,
+ *pixels;
+
+ XColor
+ foreground_color,
+ background_color,
+ border_color,
+ matte_color,
+ highlight_color,
+ shadow_color,
+ depth_color,
+ trough_color,
+ box_color,
+ pen_color,
+ pen_colors[MaxNumberPens];
+
+ GC
+ annotate_context,
+ highlight_context,
+ widget_context;
+
+ unsigned short
+ box_index,
+ pen_index;
+} MagickXPixelInfo;
+
+typedef struct _MagickXResourceInfo
+{
+ XrmDatabase
+ resource_database;
+
+ ImageInfo
+ *image_info;
+
+ QuantizeInfo
+ *quantize_info;
+
+ unsigned long
+ colors;
+
+ unsigned int
+ close_server,
+ backdrop;
+
+ char
+ *background_color,
+ *border_color;
+
+ char
+ *client_name;
+
+ MagickXColormapType
+ colormap;
+
+ unsigned int
+ border_width,
+ color_recovery,
+ confirm_exit,
+ delay;
+
+ char
+ *display_gamma;
+
+ char
+ *font,
+ *font_name[MaxNumberFonts],
+ *foreground_color;
+
+ unsigned int
+ display_warnings,
+ gamma_correct;
+
+ char
+ *icon_geometry;
+
+ unsigned int
+ iconic,
+ immutable;
+
+ char
+ *image_geometry;
+
+ char
+ *map_type,
+ *matte_color,
+ *name;
+
+ unsigned int
+ magnify,
+ pause;
+
+ char
+ *pen_colors[MaxNumberPens];
+
+ char
+ *text_font,
+ *title;
+
+ int
+ quantum;
+
+ unsigned int
+ update,
+ use_pixmap,
+ use_shared_memory;
+
+ unsigned long
+ undo_cache;
+
+ char
+ *visual_type,
+ *window_group,
+ *window_id,
+ *write_filename;
+
+ Image
+ *copy_image;
+
+ int
+ gravity;
+
+ char
+ home_directory[MaxTextExtent];
+} MagickXResourceInfo;
+
+typedef struct _MagickXWindowInfo
+{
+ Window
+ id;
+
+ Window
+ root;
+
+ Visual
+ *visual;
+
+ int
+ storage_class,
+ depth;
+
+ XVisualInfo
+ *visual_info;
+
+ XStandardColormap
+ *map_info;
+
+ MagickXPixelInfo
+ *pixel_info;
+
+ XFontStruct
+ *font_info;
+
+ GC
+ annotate_context,
+ highlight_context,
+ widget_context;
+
+ Cursor
+ cursor,
+ busy_cursor;
+
+ char
+ *name,
+ *geometry,
+ *icon_name,
+ *icon_geometry,
+ *crop_geometry;
+
+ unsigned long
+ data,
+ flags;
+
+ int
+ x,
+ y;
+
+ unsigned int
+ width,
+ height,
+ min_width,
+ min_height,
+ width_inc,
+ height_inc,
+ border_width,
+ use_pixmap,
+ immutable,
+ shape,
+ shared_memory;
+
+ int
+ screen;
+
+ XImage
+ *ximage,
+ *matte_image;
+
+ Pixmap
+ highlight_stipple,
+ shadow_stipple,
+ pixmap,
+ *pixmaps,
+ matte_pixmap,
+ *matte_pixmaps;
+
+ XSetWindowAttributes
+ attributes;
+
+ XWindowChanges
+ window_changes;
+
+ void
+ *segment_info;
+
+ int
+ mask;
+
+ unsigned int
+ orphan,
+ mapped,
+ stasis;
+
+ Image
+ *image;
+
+ unsigned int
+ destroy; /* If True, then destroy image */
+} MagickXWindowInfo;
+
+typedef struct _MagickXWindows
+{
+ Display
+ *display;
+
+ XStandardColormap
+ *map_info,
+ *icon_map;
+
+ XVisualInfo
+ *visual_info,
+ *icon_visual;
+
+ MagickXPixelInfo
+ *pixel_info,
+ *icon_pixel;
+
+ XFontStruct
+ *font_info;
+
+ MagickXResourceInfo
+ *icon_resources;
+
+ XClassHint
+ *class_hints;
+
+ XWMHints
+ *manager_hints;
+
+ MagickXWindowInfo
+ context,
+ group_leader,
+ backdrop,
+ icon,
+ image,
+ info,
+ magnify,
+ pan,
+ command,
+ widget,
+ popup;
+
+ Atom
+ wm_protocols,
+ wm_delete_window,
+ wm_take_focus,
+ im_protocols,
+ im_remote_command,
+ im_update_widget,
+ im_update_colormap,
+ im_former_image,
+ im_retain_colors,
+ im_next_image,
+ im_exit,
+ dnd_protocols;
+} MagickXWindows;
+
+/*
+ X utilities methods.
+*/
+extern MagickExport char
+ *MagickXGetResourceClass(XrmDatabase,const char *,const char *,char *),
+ *MagickXGetResourceInstance(XrmDatabase,const char *,const char *,const char *),
+ *MagickXGetScreenDensity(Display *);
+
+extern MagickExport Cursor
+ MagickXMakeCursor(Display *,Window,Colormap,char *,char *);
+
+extern MagickExport Image
+ *MagickXAnimateImages(Display *,MagickXResourceInfo *,char *[],const int,Image *),
+ *MagickXDisplayImage(Display *,MagickXResourceInfo *,char *[],int,Image **,
+ unsigned long *),
+ *MagickXImportImage(const ImageInfo *,MagickXImportInfo *);
+
+extern MagickExport int
+ MagickXError(Display *,XErrorEvent *);
+
+extern MagickExport unsigned int
+ MagickIsTrue(const char *),
+ MagickXAnnotateImage(Display *,const MagickXPixelInfo *,MagickXAnnotateInfo *,Image *),
+ MagickXDisplayBackgroundImage(Display *,MagickXResourceInfo *,Image *),
+ MagickXDrawImage(Display *,const MagickXPixelInfo *,MagickXDrawInfo *,Image *),
+ MagickXGetWindowColor(Display *,MagickXWindows *,char *),
+ MagickXMakeImage(Display *,const MagickXResourceInfo *,MagickXWindowInfo *,Image *,
+ unsigned int,unsigned int),
+ MagickXMagickMonitor(const char *task,const magick_int64_t quantum,
+ const magick_uint64_t span,ExceptionInfo *exception),
+ MagickXQueryColorDatabase(const char *,XColor *),
+ MagickXRemoteCommand(Display *,const char *,const char *);
+
+extern MagickExport void
+ MagickXAnimateBackgroundImage(Display *,MagickXResourceInfo *,Image *),
+ MagickXBestIconSize(Display *,MagickXWindowInfo *,Image *),
+ MagickXBestPixel(Display *,const Colormap,XColor *,unsigned int,XColor *),
+ MagickXCheckRefreshWindows(Display *,MagickXWindows *),
+ MagickXClientMessage(Display *,const Window,const Atom,const Atom,const Time),
+ MagickXConfigureImageColormap(Display *,MagickXResourceInfo *,MagickXWindows *,Image *),
+ MagickXConstrainWindowPosition(Display *,MagickXWindowInfo *),
+ MagickXDelay(Display *,const unsigned long),
+ MagickXDestroyResourceInfo(MagickXResourceInfo *resource_info),
+ MagickXDestroyX11Resources(void),
+ MagickXDestroyXWindows(MagickXWindows *windows),
+ MagickXDestroyXWindowInfo(Display *display,MagickXWindowInfo *window),
+ MagickXDestroyWindowColors(Display *,Window),
+ MagickXDisplayImageInfo(Display *,const MagickXResourceInfo *,MagickXWindows *,Image *,Image *),
+ MagickXFreeResources(Display *,XVisualInfo *,XStandardColormap *,MagickXPixelInfo *,
+ XFontStruct *,MagickXResourceInfo *,MagickXWindowInfo *),
+ MagickXFreeStandardColormap(Display *,const XVisualInfo *,XStandardColormap *,
+ MagickXPixelInfo *),
+ MagickXGetAnnotateInfo(MagickXAnnotateInfo *),
+ MagickXGetImportInfo(MagickXImportInfo *),
+ MagickXGetMapInfo(const XVisualInfo *,const Colormap,XStandardColormap *),
+ MagickXGetPixelPacket(Display *,const XVisualInfo *,const XStandardColormap *,
+ const MagickXResourceInfo *,Image *,MagickXPixelInfo *),
+ MagickXGetResourceInfo(XrmDatabase,const char *,MagickXResourceInfo *),
+ MagickXGetWindowInfo(Display *,XVisualInfo *,XStandardColormap *,MagickXPixelInfo *,
+ XFontStruct *,MagickXResourceInfo *,MagickXWindowInfo *),
+ MagickXHighlightEllipse(Display *,Window,GC,const RectangleInfo *),
+ MagickXHighlightLine(Display *,Window,GC,const XSegment *),
+ MagickXHighlightRectangle(Display *,Window,GC,const RectangleInfo *),
+ MagickXMakeMagnifyImage(Display *,MagickXWindows *),
+ MagickXMakeStandardColormap(Display *,XVisualInfo *,MagickXResourceInfo *,Image *,
+ XStandardColormap *,MagickXPixelInfo *),
+ MagickXMakeWindow(Display *,Window,char **,int,XClassHint *,XWMHints *,
+ MagickXWindowInfo *),
+ MagickXQueryPosition(Display *,const Window,int *,int *),
+ MagickXRefreshWindow(Display *,const MagickXWindowInfo *,const XEvent *),
+ MagickXRetainWindowColors(Display *,const Window),
+ MagickXSignalHandler(int) MAGICK_FUNC_NORETURN,
+ MagickXSetCursorState(Display *,MagickXWindows *,const unsigned int),
+ MagickXUserPreferences(MagickXResourceInfo *),
+ MagickXWarning(const ExceptionType,const char *,const char *);
+
+extern MagickExport Window
+ MagickXWindowByID(Display *,const Window,const unsigned long),
+ MagickXWindowByName(Display *,const Window,const char *),
+ MagickXWindowByProperty(Display *,const Window,const Atom);
+
+extern MagickExport XFontStruct
+ *MagickXBestFont(Display *,const MagickXResourceInfo *,const unsigned int);
+
+extern MagickExport XrmDatabase
+ MagickXGetResourceDatabase(Display *,const char *);
+
+extern MagickExport XVisualInfo
+ *MagickXBestVisualInfo(Display *,XStandardColormap *,MagickXResourceInfo *);
+
+extern MagickExport MagickXWindows
+ *MagickXInitializeWindows(Display *,MagickXResourceInfo *),
+ *MagickXSetWindows(MagickXWindows *);
+
+/*
+ Invoke pre-X11R6 ICCCM routines if XlibSpecificationRelease is not 6.
+*/
+#if XlibSpecificationRelease < 6
+#if !defined(PRE_R6_ICCCM)
+#define PRE_R6_ICCCM
+#endif
+#endif
+/*
+ Invoke pre-X11R5 ICCCM routines if XlibSpecificationRelease is not defined.
+*/
+#if !defined(XlibSpecificationRelease)
+#define PRE_R5_ICCCM
+#endif
+/*
+ Invoke pre-X11R4 ICCCM routines if PWinGravity is not defined.
+*/
+#if !defined(PWinGravity)
+#define PRE_R4_ICCCM
+#endif
+#include "magick/widget.h"
+
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..6fbe5e1
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,150 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2004-02-15.20
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage"
+ exit 0
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --version)
+ echo "$0 $scriptversion"
+ exit 0
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error. This is a problem when calling mkinstalldirs
+# from a parallel make. We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+ '')
+ if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ test -d ./-p && rmdir ./-p
+ test -d ./--version && rmdir ./--version
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+ test ! -d ./--version; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ else
+ # Clean up after NextStep and OpenStep mkdir.
+ for d in ./-m ./-p ./--version "./$dirmode";
+ do
+ test -d $d && rmdir $d
+ done
+ fi
+ ;;
+esac
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=""
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/rungm.sh.in b/rungm.sh.in
new file mode 100755
index 0000000..11f8a88
--- /dev/null
+++ b/rungm.sh.in
@@ -0,0 +1,37 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2003-2009 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Execute a program with the environment required to execute it using
+# files from the source and build directory. This helps avoid needing to
+# install GraphicsMagick before testing it.
+#
+# Written by Bob Friesenhahn <bfriesen@simple.dallas.tx.us> December 2003
+#
+
+top_srcdir='@abs_top_srcdir@'
+top_builddir='@abs_top_builddir@'
+
+MAGICK_CODER_MODULE_PATH="${top_builddir}/coders"
+MAGICK_CONFIGURE_SRC_PATH="${top_srcdir}/config"
+MAGICK_CONFIGURE_BUILD_PATH="${top_builddir}/config"
+MAGICK_FILTER_MODULE_PATH="${top_builddir}/filters"
+DIRSEP='@DIRSEP@'
+
+PATH="${top_builddir}/utilities:${PATH}"
+
+if test -n "$VERBOSE"
+then
+ echo "$@"
+fi
+env \
+ LD_LIBRARY_PATH="${top_builddir}/magick/.libs:${LD_LIBRARY_PATH}" \
+ MAGICK_CODER_MODULE_PATH="${MAGICK_CODER_MODULE_PATH}" \
+ MAGICK_CONFIGURE_PATH="${MAGICK_CONFIGURE_BUILD_PATH}${DIRSEP}${MAGICK_CONFIGURE_SRC_PATH}" \
+ MAGICK_FILTER_MODULE_PATH="${MAGICK_FILTER_MODULE_PATH}" \
+ PATH="${PATH}" \
+ "$@"
diff --git a/scripts/changelog2rst.sh b/scripts/changelog2rst.sh
new file mode 100755
index 0000000..4d5f268
--- /dev/null
+++ b/scripts/changelog2rst.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# Simple filter to filter a ChangeLog to something in reStructuredText.
+#
+sed -e 's/ \* / - /g ; s/ / / ; s/\*/\\*/g; s/\_/\\_/g'
diff --git a/scripts/docutils_htmldeco_writer.py b/scripts/docutils_htmldeco_writer.py
new file mode 100644
index 0000000..833d89d
--- /dev/null
+++ b/scripts/docutils_htmldeco_writer.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# vim:ts=4:sw=4:expandtab:tw=100:
+
+#* Author: Mark Mitchell
+#* Copyright 2005-2008 Mark Mitchell, All Rights Reserved
+#* License: see __license__ below.
+
+__doc__ = """
+A specialized subclass of the docutils html4css1 writer.
+
+It includes some additional HTML in the HTMLTranslator body_prefix and body_suffix
+so as to put a standard banner and navigation menus on the page.
+"""
+
+__copyright__ = "2005, 2008, Mark Mitchell"
+
+__license__ = """
+Copyright 2005, 2008, Mark Mitchell
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this oftware and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+The Software is provided "as is", without warranty of any kind,
+express or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and noninfringement.
+In no event shall the authors or copyright holders be liable for any
+claim, damages or other liability, whether in an action of contract,
+tort or otherwise, arising from, out of or in connection with Software
+or the use or other dealings in the Software.
+"""
+
+
+import sys
+
+from docutils.writers import html4css1
+from docutils import nodes
+# the html fragments for banner, navigation menu, and footer
+import html_fragments
+
+
+class Writer(html4css1.Writer):
+ '''My derived Writer class'''
+
+ super_init = html4css1.Writer.__init__
+ def __init__(self):
+ self.super_init()
+ self.translator_class = MmHtmlTranslator
+
+
+class MmHtmlTranslator(html4css1.HTMLTranslator):
+ """My HTML translator which alters body_prefix to include
+ some extra HTML after the body opening tag, and alters body_suffix
+ to include a bit more before the body closing tag."""
+
+ def __init__(self, document):
+ html4css1.HTMLTranslator.__init__(self, document)
+
+ self.body_prefix.append(html_fragments.banner)
+ self.body_prefix.append(html_fragments.nav)
+ #self.body_suffix = [html_fragments.footer, '</body>\n</html>\n']
+ self.body_suffix = ['</body>\n</html>\n']
+
diff --git a/scripts/format_c_api_doc.py b/scripts/format_c_api_doc.py
new file mode 100755
index 0000000..9a7c3d2
--- /dev/null
+++ b/scripts/format_c_api_doc.py
@@ -0,0 +1,603 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim: ts=4:sw=4:expandtab:
+
+# Copyright 2008 Mark Mitchell
+# License: see __license__ below.
+
+
+__doc__ = """
+Reads a GraphicsMagick source file and parses the specially formatted
+comment blocks which precede each function and writes the information
+obtained from the comment block into a reStructuredText file.
+
+Usage:
+ format_c_api_docs.py [options] SRCFILE OUTFILE
+
+ SRCFILE is the path to a Graphicsmagick API .c file.
+ For example: ./magick/animate.c
+
+ OUTFILE is the path where the reStructuredText file is written.
+
+ Options:
+
+ -h --help -- Print this help message
+ -w --whatis-file -- The path to a file containing "whatis" information for
+ the source files. The format of this file is:
+ * one line per source file
+ * source filename (without directory paths) and whatis text
+ are separated by whitespace
+ * blank lines are ignored
+ * lines starting with '#' are ignored
+ -i --include-rst -- Comma-separated list of file paths to be objects of reST
+ ..include:: directives inserted in OUTFILE.
+ The default is the single file 'api_hyperlinks.rst'
+
+Example of whatis file format:
+
+animate.c Interactively animate an image sequence
+annotate.c Annotate an image with text
+"""
+
+__copyright__ = "2008, Mark Mitchell"
+
+__license__ = """
+Copyright 2008, Mark Mitchell
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this Software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+The Software is provided "as is", without warranty of any kind,
+express or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and noninfringement.
+In no event shall the authors or copyright holders be liable for any
+claim, damages or other liability, whether in an action of contract,
+tort or otherwise, arising from, out of or in connection with Software
+or the use or other dealings in the Software.
+"""
+
+import sys
+import getopt
+import os, os.path
+import re
+import textwrap
+
+
+# Key words to replace with HTML links
+keywords = {
+ 'AffineMatrix' : '`AffineMatrix`_',
+ 'BlobInfo' : '`BlobInfo`_',
+ 'Cache' : '`Cache`_',
+ 'ChannelType' : '`ChannelType`_',
+ 'ChromaticityInfo' : '`ChromaticityInfo`_',
+ 'ClassType' : '`ClassType`_',
+ 'ClipPathUnits' : '`ClipPathUnits`_',
+ 'ColorPacket' : '`ColorPacket`_',
+ 'ColorspaceType' : '`ColorspaceType`_',
+ 'ComplianceType' : '`ComplianceType`_',
+ 'CompositeOperator' : '`CompositeOperator`_',
+ 'CompressionType' : '`CompressionType`_',
+ 'DecorationType' : '`DecorationType`_',
+ 'DrawContext' : '`DrawContext`_',
+ 'DrawInfo' : '`DrawInfo`_',
+ 'ErrorHandler' : '`ErrorHandler`_',
+ 'ExceptionInfo' : '`ExceptionInfo`_',
+ 'ExceptionType' : '`ExceptionType`_',
+ 'FillRule' : '`FillRule`_',
+ 'FilterTypes' : '`FilterTypes`_',
+ 'FrameInfo' : '`FrameInfo`_',
+ 'GravityType' : '`GravityType`_',
+ 'Image' : '`Image`_',
+ 'ImageInfo' : '`ImageInfo`_',
+ 'ImageType' : '`ImageType`_',
+ 'InterlaceType' : '`InterlaceType`_',
+ 'LayerType' : '`LayerType`_',
+ 'MagickInfo' : '`MagickInfo`_',
+ 'MonitorHandler' : '`MonitorHandler`_',
+ 'MontageInfo' : '`MontageInfo`_',
+ 'NoiseType' : '`NoiseType`_',
+ 'PaintMethod' : '`PaintMethod`_',
+ 'PixelPacket' : '`PixelPacket`_',
+ 'PointInfo' : '`PointInfo`_',
+ 'ProfileInfo' : '`ProfileInfo`_',
+ 'QuantizeInfo' : '`QuantizeInfo`_',
+ 'Quantum' : '`Quantum`_',
+ 'QuantumType' : '`QuantumType`_',
+ 'RectangleInfo' : '`RectangleInfo`_',
+ 'RegistryType' : '`RegistryType`_',
+ 'RenderingIntent' : '`RenderingIntent`_',
+ 'ResolutionType' : '`ResolutionType`_',
+ 'ResourceType' : '`ResourceType`_',
+ 'SegmentInfo' : '`SegmentInfo`_',
+ 'SignatureInfo' : '`SignatureInfo`_',
+ 'StorageType' : '`StorageType`_',
+ 'StreamHandler' : '`StreamHandler`_',
+ 'StretchType' : '`StretchType`_',
+ 'StyleType' : '`StyleType`_',
+ 'TypeMetric' : '`TypeMetric`_',
+ 'ViewInfo' : '`ViewInfo`_',
+ 'VirtualPixelMethod' : '`VirtualPixelMethod`_',
+ 'MagickXResourceInfo' : '`MagickXResourceInfo`_',
+ }
+
+
+state_init = 0
+state_found_fcncomment = 1
+state_found_fcntitle = 2
+state_found_fcndoc = 3
+state_more_prototype = 4
+state_found_prototype = 5
+state_found_private = 6
+state_parmdescr = 7
+
+def warn(msg):
+ print >> sys.stderr, msg
+
+def debugtrace(msg):
+ print >> sys.stdout, msg
+
+def nodebugtrace(msg):
+ pass
+
+dtrace = nodebugtrace
+#dtrace = debugtrace
+
+# extract and save function title. example:
+# + X M a g i c k C o m m a n d %
+# % X A n i m a t e B a c k g r o u n d I m a g e %
+# Lines starting with '+' are private APIs which should not appear in
+# in the output.
+re_func_title = re.compile(r'^[+|%]\s+((\w )+)\s*%')
+
+
+def proto_pretty(line):
+ """fixes up inconsistent spaces in C function prototypes"""
+ line = re.sub(r',', ' , ', line)
+ line = re.sub(r'\(', ' ( ', line)
+ line = re.sub(r'\)', ' ) ', line)
+ line = re.sub(r'\*', ' * ', line)
+ line = re.sub(r'\s+', ' ', line)
+
+ line = re.sub(r'\(\s+\*', '(*', line)
+ line = re.sub(r' ,', ',', line)
+ line = re.sub(r' \(', '(', line)
+ line = re.sub(r'\) ', ')', line)
+ line = re.sub(r' \* ', ' *', line)
+
+ line = re.sub('^\s*', '', line)
+ return line
+
+
+class Paragraph:
+ "Paragraphs consist of one or more lines of text."
+ def __init__(self):
+ self.lines = []
+
+ def __str__(self):
+ #return '\n'.join(self.lines)
+ return '\n'.join([line.strip() for line in self.lines])
+
+
+class Prototype:
+ def __init__(self):
+ self.lines = []
+
+ def __str__(self):
+ proto = ' '.join(self.lines)
+ proto = proto_pretty(proto)
+ # escape all the '*' chars
+ proto = re.sub(r'\*', '\\*', proto)
+ # escape all the '_' chars
+ proto = re.sub(r'_', '\\_', proto)
+ # now replace keywords with hyperlinks
+ for k,v in keywords.iteritems():
+ proto = re.sub(r'^%s ' % k, '%s ' % v, proto)
+ proto = re.sub(r' %s ' % k, ' %s ' % v, proto)
+
+ # make some attempt to wrap the text nicely
+ openparen_index = proto.find('(')
+ if openparen_index > 0:
+ fcn = proto[:openparen_index+1]
+ indent_len = len(fcn) + 3
+ toomuch = (2 * fcn.count('\\')) + (3 * fcn.count('`_'))
+ if toomuch > 0: # account for the space following the opening paren
+ toomuch -= 1
+ indent_len -= toomuch
+ params = proto[openparen_index+1:].split(',')
+ params = [p.strip() for p in params]
+ max_param_len = 0
+ for x in params:
+ if len(x) > max_param_len:
+ max_param_len = len(x)
+ wrap_width = max(96, max_param_len + indent_len)
+
+ proto_lines = []
+ line = fcn + ' '
+ while params:
+ x = params.pop(0)
+ if len(line) + len(x) > wrap_width:
+ proto_lines.append(line)
+ line = ' ' * indent_len
+
+ line += x
+ if params:
+ line += ', '
+
+ proto_lines.append(line)
+ proto = '\n '.join(proto_lines)
+ return ".. parsed-literal::\n\n %s" % proto
+
+
+class ListItem:
+ """List items are used for parameter descriptions, and consist of the
+ parameter name and one or more lines of description text."""
+ def __init__(self, name):
+ self.name = name
+ self.lines = []
+
+ def __str__(self):
+ s = []
+ s.append('%s:' % self.name)
+ for line in self.lines:
+ s.append(' %s' % line.strip())
+ return '\n'.join(s)
+
+
+class Function:
+ def __init__(self, name):
+ self.name = name
+ self.prototype = None
+ # Description is a list, the items of which are either Paragraph or
+ # ListItem or Prototype instances.
+ self.description = []
+
+ def __str__(self):
+ lines = []
+ lines.append('')
+ lines.append('')
+ lines.append(self.name)
+ lines.append('=' * len(self.name))
+ lines.append('')
+ lines.append('Synopsis')
+ lines.append('--------')
+ lines.append(str(self.prototype))
+ lines.append('')
+ lines.append('Description')
+ lines.append('-----------')
+ for item in self.description:
+ lines.append(str(item))
+ lines.append('')
+
+ return '\n'.join(lines)
+
+
+def parse(srcfilepath):
+ list_item = None
+ proto = None
+ para = None
+ func = None
+ functions = []
+ state = state_init
+ linecnt = 0
+ ftitle = None
+ f = file(srcfilepath, 'r')
+ for line in f:
+ linecnt += 1
+ if not (line.startswith('%') or line.startswith('+') or re.search(r'\*/', line)):
+ continue
+
+ line = line.strip()
+
+ if state == state_init:
+ # Find first line of function title/comment block
+ if line.startswith('%%%%%%%%'):
+ dtrace('Line %d: start of function comment block ############' % linecnt)
+ state = state_found_fcncomment
+ continue
+
+ elif state == state_found_fcncomment:
+ # Search for the function name, with spaces between each letter
+ if line.startswith('%%%%%%%%'):
+ warn('Line %d: WARNING: no function name found, found start of function comment block instead.' % linecnt)
+ state = state_init
+ continue
+
+ m = re_func_title.search(line)
+ if m:
+ if line.startswith('+'):
+ dtrace('Line %d: private API' % linecnt)
+ # private API, skip it
+ state = state_found_private
+ else:
+ # public API, process it
+ ftitle = re.sub(' ', '', m.group(1))
+ dtrace('Line %d: public API %s' % (linecnt, ftitle))
+ func = Function(ftitle)
+ functions.append(func)
+ state = state_found_fcntitle
+ continue
+
+ elif state == state_found_private:
+ # skip to end of function title block
+ if line.startswith('%%%%%%%%'):
+ dtrace('Line %d: end of private function comment block' % linecnt)
+ state = state_init
+ continue
+
+ elif state == state_found_fcntitle:
+ # skip to first line following end of function title block.
+ # lines of the function title block start with and end with '%'.
+ if not re.match(r'%.+%', line):
+ dtrace('Line %d: end of public function comment block %s' % (linecnt, ftitle))
+ state = state_found_fcndoc
+ # fall through
+ elif state == state_found_fcndoc:
+ # extract function prototype
+ if line.startswith('% '):
+ line = re.sub(r'^%\s{0,2}', '', line, 1)
+ # if empty args (), it's not the prototype, but the one-line summary
+ if re.search(r'%s\(\)' % ftitle, line):
+ if para is None:
+ dtrace('Line %d: found_fcndoc start paragraph ()' % linecnt)
+ para = Paragraph()
+ func.description.append(para)
+ para.lines.append(line)
+ # is this only line of prototype?
+ elif re.search(r'%s\([^)]+\)$' % ftitle, line):
+ if para:
+ dtrace('Line %d: found_fcndoc end paragraph by proto ()' % linecnt)
+ para = None
+ dtrace('Line %d: one-line prototype' % linecnt)
+ proto = Prototype()
+ proto.lines.append(line)
+ func.description.append(proto)
+ func.prototype = proto
+ proto = None
+ state = state_found_prototype
+ # is this first line of multiline prototype?
+ elif re.search(r'%s\([^)]*$' % ftitle, line):
+ if para:
+ dtrace('Line %d: found_fcndoc end paragraph by proto (' % linecnt)
+ para = None
+ dtrace('Line %d: first line of multi-line prototype' % linecnt)
+ proto = Prototype()
+ proto.lines.append(line)
+ func.description.append(proto)
+ func.prototype = proto
+ state = state_more_prototype
+ else:
+ if para is None:
+ dtrace('Line %d: found_fcndoc start paragraph' % linecnt)
+ para = Paragraph()
+ func.description.append(para)
+ para.lines.append(line)
+ else:
+ if line.startswith('%%%%%%%%'):
+ warn('Line %d: WARNING: no prototype found for %s, found start of function comment block instead.' % (linecnt, ftitle))
+ state = state_found_fcncomment
+ continue
+
+ if line.strip() == '%':
+ # empty line terminates paragraph
+ if para:
+ dtrace('Line %d: found_fcndoc end paragraph by blank line' % linecnt)
+ para = None
+ if proto:
+ dtrace('Line %d: found_fcndoc end proto by blank line' % linecnt)
+ proto = None
+
+ continue
+
+ elif state == state_more_prototype:
+ if re.match(r'%.+%', line):
+ # really this should raise a warning of "incomplete prototype"
+ continue
+ line = re.sub(r'^%\s{0,2}', '', line, 1)
+ if re.search(r'^\s*$', line):
+ dtrace('Line %d: end of more prototype' % linecnt)
+ state = state_found_prototype
+ else:
+ func.prototype.lines.append(line)
+ continue
+
+ elif state == state_found_prototype:
+ dtrace('Line %d: found prototype of function %s' % (linecnt, ftitle))
+ func.prototype.lines.append(';')
+
+ #print 'Function %s' % func.name
+ #print 'Synopsis'
+ #print ' '.join(func.prototype)
+ #print
+
+ # Process parm description.
+ # Description consists of two kinds of texts: paragraphs, and lists.
+ # Lists consist of list items. List items are one or more lines.
+ # List items are separated by blank lines. The first line of a list
+ # item starts with 'o '.
+ # Paragraphs consist of one or more lines which don't start with 'o '.
+ # Paragraphs are separated from each other and from adjacent list items
+ # by blank lines.
+ # In theory, a line which starts with 'o ' which is not preceded by a
+ # blank line is illegal syntax.
+ para = None
+ state = state_parmdescr
+ # fall through
+
+ elif state == state_parmdescr:
+ if line.endswith('*/'):
+ # end of function comment block
+ dtrace('Line %d: end of parmdescr ************' % linecnt)
+ if list_item:
+ func.description.append(list_item)
+ list_item = None
+ if para:
+ func.description.append(para)
+ dtrace('Line %d: parmdescr end paragraph ()' % linecnt)
+ para = None
+ func = None
+ state = state_init
+ continue
+
+ line = re.sub(r'^%\s{0,2}', '', line, 1)
+ if line:
+ # look for list item, which starts with 'o'
+ m = re.search(r'^\s+o\s+([^:]+:|o|[0-9]\.)\s(.*)', line)
+ if m:
+ # first line of list item
+ if list_item: # if blank lines separate list items, this should never evaluate true
+ dtrace('Line %d: surprising end of list item' % linecnt)
+ func.description.append(list_item)
+ list_item = None
+ dtrace('Line %d: start list item' % linecnt)
+ list_item = ListItem(m.group(1).strip().rstrip(':'))
+ list_item.lines.append(m.group(2))
+ else:
+ # either a line of paragraph or subsequent line of list item
+ if list_item:
+ # subsequent line of list item
+ list_item.lines.append(line)
+ else:
+ # line of paragraph
+ if list_item: # if blank lines after list items, this should never evaluate true
+ dtrace('Line %d: end of list item, end of list' % linecnt)
+ func.description.append(list_item)
+ list_item = None
+ if para is None:
+ dtrace('Line %d: parmdescr start paragraph' % linecnt)
+ para = Paragraph()
+ para.lines.append(line)
+
+ else:
+ # empty line, two cases:
+ # 1. terminate multi-line list item
+ # 2. terminate multi-line paragraph
+ if list_item:
+ dtrace('Line %d: parmdescr end of list item by blank line' % linecnt)
+ func.description.append(list_item)
+ list_item = None
+ elif para:
+ # terminate any paragraph
+ dtrace('Line %d: parmdescr end of paragraph by blank line' % linecnt)
+ func.description.append(para)
+ para = None
+
+ continue
+
+ f.close()
+ return functions
+
+
+
+def process_srcfile(srcfilepath, basename, whatis, outfile, include_rst):
+ """outfile is a file object open for writing"""
+ functions = parse(srcfilepath)
+ print >> outfile, "=" * len(basename)
+ print >> outfile, basename
+ print >> outfile, "=" * len(basename)
+ if whatis:
+ print >> outfile, "-" * len(whatis)
+ print >> outfile, whatis
+ print >> outfile, "-" * len(whatis)
+ print >> outfile
+ print >> outfile, '.. contents:: :depth: 1'
+ print >> outfile
+ for x in include_rst:
+ print >> outfile, '.. include:: %s' % x
+ print >> outfile
+
+ # print all functions found in this source file
+ for func in functions:
+ print >> outfile, func
+
+ #para = para.strip() # trim leading and trailing whitespace
+ #para = re.sub(r'\s+', ' ', para) # canonicalize inner whitespace
+ #para = re.sub(r"""([a-zA-Z0-9][.!?][)'"]*) """, '\1 ', para) # Fix sentence ends
+
+
+
+def find_val(key, keyval_file):
+ val = None
+ f = file(keyval_file, 'r')
+ cnt = 0
+ for line in f:
+ cnt += 1
+ if not line.strip():
+ continue
+ if line.startswith('#'):
+ continue
+ try:
+ k, v = line.split(None, 1)
+ except ValueError:
+ print >> sys.stderr, "Line %u of %s: improper format" % (cnt, keyval_file)
+ return None
+
+ if k == key:
+ val = v
+ break
+
+ f.close()
+ return val.strip()
+
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv[1:]
+
+ # parse command line options
+ try:
+ opts, posn_args = getopt.getopt(argv, 'hw:i:',
+ ['help',
+ 'whatis-file=',
+ 'include-rst=',
+ ])
+ except getopt.GetoptError, msg:
+ print msg
+ print __doc__
+ return 1
+
+ # process options
+ whatis_file = None
+ include_rst = ['api_hyperlinks.rst']
+
+ for opt, val in opts:
+ if opt in ("-h", "--help"):
+ print __doc__
+ return 0
+
+ if opt in ("-w", "--whatis-file"):
+ whatis_file = val
+
+ if opt in ("-i", "--include-rst"):
+ include_rst = [x for x in val.split(',') if x]
+
+ if len(posn_args) != 2:
+ print >> sys.stderr, 'Missing arguments'
+ print >> sys.stderr, __doc__
+ return 1
+
+ srcfile_path = posn_args[0]
+ outfile_path = posn_args[1]
+
+ srcfile = os.path.basename(srcfile_path)
+ base, ext = os.path.splitext(srcfile)
+ if whatis_file:
+ whatis = find_val(srcfile, whatis_file)
+ else:
+ whatis = None
+ fout = file(outfile_path, 'w')
+ process_srcfile(srcfile_path, base, whatis, fout, include_rst)
+ fout.close()
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
+
diff --git a/scripts/format_c_api_docs.py b/scripts/format_c_api_docs.py
new file mode 100755
index 0000000..d745329
--- /dev/null
+++ b/scripts/format_c_api_docs.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim: ts=4:sw=4:expandtab:
+
+# Copyright 2008 Mark Mitchell
+# License: Same as GraphicsMagick.
+
+__doc__ = """Runs format_c_api_doc.py on all files in the whatis list,
+producing reStructuredText files. Then runs rst2htmldeco.py on all the
+reStructuredText files, producing HTML files.
+
+Usage:
+ format_c_api_docs.py whatisfile [GMTOPDIR] [OUTDIR]
+
+ GMTOPDIR is used to construct filesystem paths to the 'magick'
+ directory of the .c input files, i.e. GMTOPDIR/magick.
+
+ If OUTDIR is not specified, it defaults to GMTOPDIR/www/api
+
+ Example:
+ ./format_c_api_docs.py whatis.txt /usr/local/src/GraphicsMagick/ ../www/api
+
+ would expect to find the .c files listed in whatis.txt in the
+ directory /usr/local/src/GraphicsMagick/magick, and will write
+ the HTML files into the directory ../www/api, which is relative
+ to the current working directory.
+
+ The value of --url-prefix passed to rst2htmldeco.py is hard-wired
+ as '../../', meaning this script assumes the standard GM directory
+ layout.
+
+ The value of --link-stylesheet passed to rst2htmldeco.py is hard-wired
+ as '../../www/docutils-api.css'.
+"""
+
+import sys
+import os, os.path
+import shutil
+
+import format_c_api_doc
+import rst2htmldeco
+
+
+# assume standard GM directory layout
+stylesheet_file = 'docutils-api.css'
+url_prefix = '../../'
+stylesheet_url = '%swww/%s' % (url_prefix, stylesheet_file)
+
+
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv
+
+ if len(argv) < 2:
+ print >> sys.stderr, __doc__
+ return 1
+
+ if argv[1] in ('-h', '--help'):
+ print __doc__
+ return 0
+
+ whatis_file = argv[1]
+
+ gm_topdir = None
+ if len(argv) >= 3:
+ gm_topdir = argv[2]
+
+ outfile_dir = None
+ if len(argv) >= 4:
+ outfile_dir = argv[3]
+
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+
+ if not gm_topdir:
+ # NOTE: the following is predicated on the directory structure of the
+ # GraphicsMagick source tree. It assumes this script resides in
+ # TOPDIR/scripts and the .c files referred to by the whatis file
+ # reside in TOPDIR/magick
+ gm_topdir = os.path.normpath(os.path.join(current_dir, '..'))
+
+ srcfile_dir = os.path.join(gm_topdir, 'magick')
+
+ if not outfile_dir:
+ outfile_dir = os.path.join(gm_topdir, 'www', 'api')
+
+ f = file(whatis_file, 'r')
+ cnt = 0
+ for line in f:
+ cnt += 1
+ if not line.strip():
+ continue
+ if line.startswith('#'):
+ continue
+ try:
+ cfile, whatis = line.split(None, 1)
+ except ValueError:
+ print >> sys.stderr, "Line %u of %s: improper format" % (cnt, whatis_file)
+ return 1
+
+ srcfile_path = os.path.join(srcfile_dir, cfile)
+ srcfile = os.path.basename(srcfile_path)
+ base, ext = os.path.splitext(srcfile)
+ rstfile = base + '.rst'
+ rstfile_path = os.path.join(outfile_dir, rstfile)
+ htmlfile = base + '.html'
+ htmlfile_path = os.path.join(outfile_dir, htmlfile)
+
+ args = ['-w', whatis_file, srcfile_path, rstfile_path]
+ print 'format_c_api_doc.py', ' '.join(args)
+ format_c_api_doc.main(args)
+
+ # Now generate HTML from the .rst files
+ args = ['--link-stylesheet=%s' % stylesheet_url,
+ '--url-prefix=%s' % url_prefix,
+ rstfile_path,
+ htmlfile_path]
+ print 'rst2htmldeco.py %s' % ' '.join(args)
+ rst2htmldeco.main(args)
+ print 'rm', rstfile_path
+ os.unlink(rstfile_path)
+ f.close()
+
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
+
diff --git a/scripts/html_fragments.py b/scripts/html_fragments.py
new file mode 100644
index 0000000..dcc983c
--- /dev/null
+++ b/scripts/html_fragments.py
@@ -0,0 +1,85 @@
+# vim:ts=4:sw=4:expandtab:tw=100:
+
+#* Author: Mark Mitchell
+#* License: Same as GraphicsMagick.
+
+__doc__ = """
+HTML fragments which are used as the banner and navigation menu in
+GraphicsMagick web site pages.
+"""
+
+
+url_mailinglist = "https://sourceforge.net/p/graphicsmagick/mailman/?source=navbar"
+url_sourceforge = "https://sourceforge.net/projects/graphicsmagick/"
+
+banner_logo = 'images/gm-107x76.png' # relative to top directory
+
+
+# banner_template and nav_template contain chunk which has to be created at
+# runtime: the path to the image directory, and the path to the top directory.
+# So, rst2htmldeco.py imports html_fragments and changes url_prefix to the
+# appropriate value. When docutils_htmldeco_writer imports html_fragments, this
+# url_prefix attribute should already be fixed up.
+
+url_prefix = '' # trailing slash always needed
+
+banner_template = """
+<div class="banner">
+<img src="%(url_prefix)s%(banner_logo)s" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+"""
+
+
+nav_template = """
+<div class="navmenu">
+<ul>
+<li><a href="%(url_prefix)sindex.html">Home</a></li>
+<li><a href="%(url_prefix)sproject.html">Project</a></li>
+<li><a href="%(url_prefix)sdownload.html">Download</a></li>
+<li><a href="%(url_prefix)sREADME.html">Install</a></li>
+<li><a href="%(url_prefix)sHg.html">Source</a></li>
+<li><a href="%(url_prefix)sNEWS.html">News</a> </li>
+<li><a href="%(url_prefix)sutilities.html">Utilities</a></li>
+<li><a href="%(url_prefix)sprogramming.html">Programming</a></li>
+<li><a href="%(url_prefix)sreference.html">Reference</a></li>
+</ul>
+</div>
+"""
+
+footer_template = """
+<hr class="divider">
+<div class="footer">
+ <p><a href="%(url_prefix)sCopyright.html">Copyright</a>GraphicsMagick Group 2002 - 2017</p>
+</div>
+"""
+
+def make_footer():
+ return footer_template % { 'url_prefix' : url_prefix,
+ }
+
+def make_banner():
+ return banner_template % { 'url_prefix' : url_prefix,
+ 'banner_logo' : banner_logo,
+ }
+
+def make_nav():
+ return nav_template % { 'url_mailinglist' : url_mailinglist,
+ 'url_sourceforge' : url_sourceforge,
+ 'url_prefix' : url_prefix,
+ }
+
+# These get fixed up by rst2htmldeco.py
+nav = None
+banner = None
+footer = None
+
+# test
+if __name__ == '__main__':
+ print make_banner()
+ print make_nav()
diff --git a/scripts/make_www.py b/scripts/make_www.py
new file mode 100755
index 0000000..c5ed9ba
--- /dev/null
+++ b/scripts/make_www.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim: ts=4:sw=4:expandtab:
+
+# Copyright 2008 Mark Mitchell
+# License: Same as GraphicsMagick.
+
+__doc__ = """Runs rst2htmldeco.py on all files in the rst_pagelist.txt list.
+
+Usage:
+ make_www.py rst_pagelist.txt [GMTOPDIR] [OUTDIR]
+
+ GMTOPDIR is prefixed to the path of the rst input file specified in
+ rst_pagelist.txt. If not specified, it defaults to the parent
+ directory of the directory in which this make_www.py script lives.
+
+ OUTDIR is prefixed to the path of the html output file specified in
+ rst_pagelist.txt. If not specified it defaults to GMTOPDIR.
+
+ The value of --link-stylesheet passed to rst2htmldeco.py is obtained
+ from rst_pagelist.txt column 3.
+
+ The value of --url-prefix passed to rst2htmldeco.py is obtained
+ from rst_pagelist.txt column 4.
+"""
+
+import sys
+import os, os.path
+
+import rst2htmldeco
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv
+
+ if len(argv) < 2:
+ print >> sys.stderr, __doc__
+ return 1
+
+ if argv[1] in ('-h', '--help'):
+ print >> sys.stdout, __doc__
+ return 0
+
+ rstlist_file = argv[1]
+
+ gm_topdir = None
+ if len(argv) >= 3:
+ gm_topdir = argv[2]
+
+ outfile_dir = None
+ if len(argv) >= 4:
+ outfile_dir = argv[3]
+
+ if not gm_topdir:
+ # NOTE: the following is predicated on the directory structure of the
+ # GraphicsMagick source tree. It assumes this script resides in
+ # TOPDIR/scripts and the .c files referred to by the whatis file
+ # reside in TOPDIR/magick
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+ gm_topdir = os.path.normpath(os.path.join(current_dir, '..'))
+
+ if not outfile_dir:
+ outfile_dir = gm_topdir
+
+ f = file(rstlist_file, 'r')
+ cnt = 0
+ for line in f:
+ cnt += 1
+ line = line.strip()
+ if not line:
+ continue
+ if line.startswith('#'):
+ continue
+ try:
+ rstfile, outfile, stylesheet_url, url_prefix = line.split(None, 3)
+ except ValueError:
+ print >> sys.stderr, "Line %u of %s: improper format" % (cnt, rstlist_file)
+ return 1
+
+ rstfile_path = os.path.join(gm_topdir, rstfile.strip())
+ outfile_path = os.path.join(outfile_dir, outfile.strip())
+ args = ['--link-stylesheet=%s' % stylesheet_url,
+ '--url-prefix=%s' % url_prefix,
+ rstfile_path,
+ outfile_path]
+ print 'rst2htmldeco.py %s' % ' '.join(args)
+ rst2htmldeco.main(args)
+
+ f.close()
+
+
+if __name__ == '__main__':
+ sys.exit(main())
+
diff --git a/scripts/named_colors.py b/scripts/named_colors.py
new file mode 100755
index 0000000..50e7618
--- /dev/null
+++ b/scripts/named_colors.py
@@ -0,0 +1,416 @@
+#!/usr/bin/env python
+# vim:ts=4:sw=4:expandtab
+
+#* Author: Mark Mitchell
+#* Copyright 2008 Mark Mitchell
+#* License: see __license__ below.
+
+import sys
+import re
+
+import html_fragments
+
+__doc__ = """Creates an HTML page with a table of named colors.
+
+Usage: named_colors.py path/to/color.mgk
+
+The HTML is written to stdout.
+
+In the GraphicsMagick source tree, the path is TOPDIR/config/colors.mgk
+"""
+
+__copyright__ = "2008, Mark Mitchell"
+
+__license__ = """
+Copyright 2008, Mark Mitchell
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this Software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+The Software is provided "as is", without warranty of any kind,
+express or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and noninfringement.
+In no event shall the authors or copyright holders be liable for any
+claim, damages or other liability, whether in an action of contract,
+tort or otherwise, arising from, out of or in connection with Software
+or the use or other dealings in the Software.
+"""
+
+
+builtin_named_colors_rgb = [
+ ('aliceblue', 240, 248, 255), #f0f8ff
+ ('antiquewhite', 250, 235, 215), #faebd7
+ ('aqua', 0, 255, 255), #00ffff
+ ('aquamarine', 127, 255, 212), #7fffd4
+ ('azure', 240, 255, 255), #f0ffff
+ ('beige', 245, 245, 220), #f5f5dc
+ ('bisque', 255, 228, 196), #ffe4c4
+ ('black', 0, 0, 0), #000000
+ ('blanchedalmond', 255, 235, 205), #ffebcd
+ ('blue', 0, 0, 255), #0000ff
+ ('blueviolet', 138, 43, 226), #8a2be2
+ ('brown', 165, 42, 42), #a52a2a
+ ('burlywood', 222, 184, 135), #deb887
+ ('cadetblue', 95, 158, 160), #5f9ea0
+ ('chartreuse', 127, 255, 0), #7fff00
+ ('chocolate', 210, 105, 30), #d2691e
+ ('coral', 255, 127, 80), #ff7f50
+ ('cornflowerblue', 100, 149, 237), #6495ed
+ ('cornsilk', 255, 248, 220), #fff8dc
+ ('crimson', 220, 20, 60), #dc143c
+ ('cyan', 0, 255, 255), #00ffff
+ ('darkblue', 0, 0, 139), #00008b
+ ('darkcyan', 0, 139, 139), #008b8b
+ ('darkgoldenrod', 184, 134, 11), #b8860b
+ ('darkgray', 169, 169, 169), #a9a9a9
+ ('darkgreen', 0, 100, 0), #006400
+ ('darkgrey', 169, 169, 169), #a9a9a9
+ ('darkkhaki', 189, 183, 107), #bdb76b
+ ('darkmagenta', 139, 0, 139), #8b008b
+ ('darkolivegreen', 85, 107, 47), #556b2f
+ ('darkorange', 255, 140, 0), #ff8c00
+ ('darkorchid', 153, 50, 204), #9932cc
+ ('darkred', 139, 0, 0), #8b0000
+ ('darksalmon', 233, 150, 122), #e9967a
+ ('darkseagreen', 143, 188, 143), #8fbc8f
+ ('darkslateblue', 72, 61, 139), #483d8b
+ ('darkslategray', 47, 79, 79), #2f4f4f
+ ('darkslategrey', 47, 79, 79), #2f4f4f
+ ('darkturquoise', 0, 206, 209), #00ced1
+ ('darkviolet', 148, 0, 211), #9400d3
+ ('deeppink', 255, 20, 147), #ff1493
+ ('deepskyblue', 0, 191, 255), #00bfff
+ ('dimgray', 105, 105, 105), #696969
+ ('dimgrey', 105, 105, 105), #696969
+ ('dodgerblue', 30, 144, 255), #1e90ff
+ ('firebrick', 178, 34, 34), #b22222
+ ('floralwhite', 255, 250, 240), #fffaf0
+ ('forestgreen', 34, 139, 34), #228b22
+ ('fractal', 128, 128, 128), #808080
+ ('fuchsia', 255, 0, 255), #ff00ff
+ ('gainsboro', 220, 220, 220), #dcdcdc
+ ('ghostwhite', 248, 248, 255), #f8f8ff
+ ('gold', 255, 215, 0), #ffd700
+ ('goldenrod', 218, 165, 32), #daa520
+ ('gray0', 0, 0, 0), #000000
+ ('gray1', 3, 3, 3), #030303
+ ('gray2', 5, 5, 5), #050505
+ ('gray3', 8, 8, 8), #080808
+ ('gray4', 10, 10, 10), #0a0a0a
+ ('gray5', 13, 13, 13), #0d0d0d
+ ('gray6', 15, 15, 15), #0f0f0f
+ ('gray7', 18, 18, 18), #121212
+ ('gray8', 20, 20, 20), #141414
+ ('gray9', 23, 23, 23), #171717
+ ('gray10', 26, 26, 26), #1a1a1a
+ ('gray11', 28, 28, 28), #1c1c1c
+ ('gray12', 31, 31, 31), #1f1f1f
+ ('gray13', 33, 33, 33), #212121
+ ('gray14', 36, 36, 36), #242424
+ ('gray15', 38, 38, 38), #262626
+ ('gray16', 41, 41, 41), #292929
+ ('gray17', 43, 43, 43), #2b2b2b
+ ('gray18', 46, 46, 46), #2e2e2e
+ ('gray19', 48, 48, 48), #303030
+ ('gray20', 51, 51, 51), #333333
+ ('gray21', 54, 54, 54), #363636
+ ('gray22', 56, 56, 56), #383838
+ ('gray23', 59, 59, 59), #3b3b3b
+ ('gray24', 61, 61, 61), #3d3d3d
+ ('gray25', 64, 64, 64), #404040
+ ('gray26', 66, 66, 66), #424242
+ ('gray27', 69, 69, 69), #454545
+ ('gray28', 71, 71, 71), #474747
+ ('gray29', 74, 74, 74), #4a4a4a
+ ('gray30', 77, 77, 77), #4d4d4d
+ ('gray31', 79, 79, 79), #4f4f4f
+ ('gray32', 82, 82, 82), #525252
+ ('gray33', 84, 84, 84), #545454
+ ('gray34', 87, 87, 87), #575757
+ ('gray35', 89, 89, 89), #595959
+ ('gray36', 92, 92, 92), #5c5c5c
+ ('gray37', 94, 94, 94), #5e5e5e
+ ('gray38', 97, 97, 97), #616161
+ ('gray39', 99, 99, 99), #636363
+ ('gray40', 102, 102, 102), #666666
+ ('gray41', 105, 105, 105), #696969
+ ('gray42', 107, 107, 107), #6b6b6b
+ ('gray43', 110, 110, 110), #6e6e6e
+ ('gray44', 112, 112, 112), #707070
+ ('gray45', 115, 115, 115), #737373
+ ('gray46', 117, 117, 117), #757575
+ ('gray47', 120, 120, 120), #787878
+ ('gray48', 122, 122, 122), #7a7a7a
+ ('gray49', 125, 125, 125), #7d7d7d
+ ('gray50', 127, 127, 127), #7f7f7f
+ ('gray51', 130, 130, 130), #828282
+ ('gray52', 133, 133, 133), #858585
+ ('gray53', 135, 135, 135), #878787
+ ('gray54', 138, 138, 138), #8a8a8a
+ ('gray55', 140, 140, 140), #8c8c8c
+ ('gray56', 143, 143, 143), #8f8f8f
+ ('gray57', 145, 145, 145), #919191
+ ('gray58', 148, 148, 148), #949494
+ ('gray59', 150, 150, 150), #969696
+ ('gray60', 153, 153, 153), #999999
+ ('gray61', 156, 156, 156), #9c9c9c
+ ('gray62', 158, 158, 158), #9e9e9e
+ ('gray63', 161, 161, 161), #a1a1a1
+ ('gray64', 163, 163, 163), #a3a3a3
+ ('gray65', 166, 166, 166), #a6a6a6
+ ('gray66', 168, 168, 168), #a8a8a8
+ ('gray67', 171, 171, 171), #ababab
+ ('gray68', 173, 173, 173), #adadad
+ ('gray69', 176, 176, 176), #b0b0b0
+ ('gray70', 179, 179, 179), #b3b3b3
+ ('gray71', 181, 181, 181), #b5b5b5
+ ('gray72', 184, 184, 184), #b8b8b8
+ ('gray73', 186, 186, 186), #bababa
+ ('gray74', 189, 189, 189), #bdbdbd
+ ('gray75', 191, 191, 191), #bfbfbf
+ ('gray76', 194, 194, 194), #c2c2c2
+ ('gray77', 196, 196, 196), #c4c4c4
+ ('gray78', 199, 199, 199), #c7c7c7
+ ('gray79', 201, 201, 201), #c9c9c9
+ ('gray80', 204, 204, 204), #cccccc
+ ('gray81', 207, 207, 207), #cfcfcf
+ ('gray82', 209, 209, 209), #d1d1d1
+ ('gray83', 212, 212, 212), #d4d4d4
+ ('gray84', 214, 214, 214), #d6d6d6
+ ('gray85', 217, 217, 217), #d9d9d9
+ ('gray86', 219, 219, 219), #dbdbdb
+ ('gray87', 222, 222, 222), #dedede
+ ('gray88', 224, 224, 224), #e0e0e0
+ ('gray89', 227, 227, 227), #e3e3e3
+ ('gray90', 229, 229, 229), #e5e5e5
+ ('gray91', 232, 232, 232), #e8e8e8
+ ('gray92', 235, 235, 235), #ebebeb
+ ('gray93', 237, 237, 237), #ededed
+ ('gray94', 240, 240, 240), #f0f0f0
+ ('gray95', 242, 242, 242), #f2f2f2
+ ('gray96', 245, 245, 245), #f5f5f5
+ ('gray97', 247, 247, 247), #f7f7f7
+ ('gray98', 250, 250, 250), #fafafa
+ ('gray99', 252, 252, 252), #fcfcfc
+ ('gray100', 255, 255, 255), #ffffff
+ ('gray', 126, 126, 126), #7e7e7e
+ ('green', 0, 128, 0), #008000
+ ('greenyellow', 173, 255, 47), #adff2f
+ ('grey', 128, 128, 128), #808080
+ ('honeydew', 240, 255, 240), #f0fff0
+ ('hotpink', 255, 105, 180), #ff69b4
+ ('indianred', 205, 92, 92), #cd5c5c
+ ('indigo', 75, 0, 130), #4b0082
+ ('ivory', 255, 255, 240), #fffff0
+ ('khaki', 240, 230, 140), #f0e68c
+ ('lavender', 230, 230, 250), #e6e6fa
+ ('lavenderblush', 255, 240, 245), #fff0f5
+ ('lawngreen', 124, 252, 0), #7cfc00
+ ('lemonchiffon', 255, 250, 205), #fffacd
+ ('lightblue', 173, 216, 230), #add8e6
+ ('lightcoral', 240, 128, 128), #f08080
+ ('lightcyan', 224, 255, 255), #e0ffff
+ ('lightgoldenrodyellow', 250, 250, 210), #fafad2
+ ('lightgray', 211, 211, 211), #d3d3d3
+ ('lightgreen', 144, 238, 144), #90ee90
+ ('lightgrey', 211, 211, 211), #d3d3d3
+ ('lightpink', 255, 182, 193), #ffb6c1
+ ('lightsalmon', 255, 160, 122), #ffa07a
+ ('lightseagreen', 32, 178, 170), #20b2aa
+ ('lightskyblue', 135, 206, 250), #87cefa
+ ('lightslategray', 119, 136, 153), #778899
+ ('lightslategrey', 119, 136, 153), #778899
+ ('lightsteelblue', 176, 196, 222), #b0c4de
+ ('lightyellow', 255, 255, 224), #ffffe0
+ ('lime', 0, 255, 0), #00ff00
+ ('limegreen', 50, 205, 50), #32cd32
+ ('linen', 250, 240, 230), #faf0e6
+ ('magenta', 255, 0, 255), #ff00ff
+ ('maroon', 128, 0, 0), #800000
+ ('mediumaquamarine', 102, 205, 170), #66cdaa
+ ('mediumblue', 0, 0, 205), #0000cd
+ ('mediumorchid', 186, 85, 211), #ba55d3
+ ('mediumpurple', 147, 112, 219), #9370db
+ ('mediumseagreen', 60, 179, 113), #3cb371
+ ('mediumslateblue', 123, 104, 238), #7b68ee
+ ('mediumspringgreen', 0, 250, 154), #00fa9a
+ ('mediumturquoise', 72, 209, 204), #48d1cc
+ ('mediumvioletred', 199, 21, 133), #c71585
+ ('midnightblue', 25, 25, 112), #191970
+ ('mintcream', 245, 255, 250), #f5fffa
+ ('mistyrose', 255, 228, 225), #ffe4e1
+ ('moccasin', 255, 228, 181), #ffe4b5
+ ('navajowhite', 255, 222, 173), #ffdead
+ ('navy', 0, 0, 128), #000080
+ ('none', 0, 0, 0), #000000
+ ('oldlace', 253, 245, 230), #fdf5e6
+ ('olive', 128, 128, 0), #808000
+ ('olivedrab', 107, 142, 35), #6b8e23
+ ('orange', 255, 165, 0), #ffa500
+ ('orangered', 255, 69, 0), #ff4500
+ ('orchid', 218, 112, 214), #da70d6
+ ('palegoldenrod', 238, 232, 170), #eee8aa
+ ('palegreen', 152, 251, 152), #98fb98
+ ('paleturquoise', 175, 238, 238), #afeeee
+ ('palevioletred', 219, 112, 147), #db7093
+ ('papayawhip', 255, 239, 213), #ffefd5
+ ('peachpuff', 255, 218, 185), #ffdab9
+ ('peru', 205, 133, 63), #cd853f
+ ('pink', 255, 192, 203), #ffc0cb
+ ('plum', 221, 160, 221), #dda0dd
+ ('powderblue', 176, 224, 230), #b0e0e6
+ ('purple', 128, 0, 128), #800080
+ ('red', 255, 0, 0), #ff0000
+ ('rosybrown', 188, 143, 143), #bc8f8f
+ ('royalblue', 65, 105, 225), #4169e1
+ ('saddlebrown', 139, 69, 19), #8b4513
+ ('salmon', 250, 128, 114), #fa8072
+ ('sandybrown', 244, 164, 96), #f4a460
+ ('seagreen', 46, 139, 87), #2e8b57
+ ('seashell', 255, 245, 238), #fff5ee
+ ('sienna', 160, 82, 45), #a0522d
+ ('silver', 192, 192, 192), #c0c0c0
+ ('skyblue', 135, 206, 235), #87ceeb
+ ('slateblue', 106, 90, 205), #6a5acd
+ ('slategray', 112, 128, 144), #708090
+ ('slategrey', 112, 128, 144), #708090
+ ('snow', 255, 250, 250), #fffafa
+ ('springgreen', 0, 255, 127), #00ff7f
+ ('steelblue', 70, 130, 180), #4682b4
+ ('tan', 210, 180, 140), #d2b48c
+ ('teal', 0, 128, 128), #008080
+ ('thistle', 216, 191, 216), #d8bfd8
+ ('tomato', 255, 99, 71), #ff6347
+ ('turquoise', 64, 224, 208), #40e0d0
+ ('violet', 238, 130, 238), #ee82ee
+ ('wheat', 245, 222, 179), #f5deb3
+ ('white', 255, 255, 255), #ffffff
+ ('whitesmoke', 245, 245, 245), #f5f5f5
+ ('yellow', 255, 255, 0), #ffff00
+ ('yellowgreen', 154, 205, 50), #9acd32
+]
+
+
+html_fragments.url_prefix = ''
+banner = html_fragments.make_banner()
+nav = html_fragments.make_nav()
+footer = html_fragments.make_footer()
+stylesheet_url = 'docutils-articles.css'
+
+
+head = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>GraphicsMagick Color Selections</title>
+ <meta name="description" content="GraphicsMagick is a robust collection of tools
+and libraries to read, write, and manipulate an image in any of the more
+popular image formats including GIF, JPEG, PNG, PDF, and Photo CD. With
+GraphicsMagick you can create GIFs dynamically making it suitable for Web
+applications. You can also resize, rotate, sharpen, color reduce, or add
+special effects to an image and save your completed work in the same or
+differing image format.">
+ <meta name="keywords" content="GraphicsMagick, Image Magick, Image
+Magic, PerlMagick, Perl Magick, Perl Magic, CineMagick, PixelMagick,
+Pixel Magic, WebMagick, Web Magic, visualization, image processing,
+software development, simulation, image, software, AniMagick, Animagic,
+Magick++">
+<link rel="stylesheet" href="%(stylesheet_url)s" type="text/css" />
+ <style>
+ <!--
+ body {font-family: sans-serif;}
+ table.named-colors th, table.named-colors td { padding : .5ex; }
+ table.named-colors th { background-color : #E0E0E0; }
+ table.named-colors td.dark { text-align : center; color : white; }
+ table.named-colors td.light { text-align : center; color : black; }
+ -->
+ </style>
+</head>
+<body>
+%(banner)s
+%(nav)s
+<div class="document" id="graphicsmagick-programming-interfaces">
+<hr>
+<p>Here are some example color selections to choose from or define
+your own. GraphicsMagick understands color names or hex values (.e.g.
+white or #ffffff).
+</p>
+<table class="named-colors">
+<colgroup>
+<col width="20%%" />
+<col width="40%%" />
+<col width="20%%" />
+<col width="20%%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Name</th>
+<th class="head">Color</th>
+<th class="head">RGB</th>
+<th class="head">Hex</th>
+</tr>
+</thead>
+<tbody valign="top">
+""" % { 'stylesheet_url' : stylesheet_url,
+ 'nav' : nav,
+ 'banner' : banner,
+ 'footer' : footer,
+ }
+
+tail = """
+</tbody>
+</table>
+</div>
+</body>
+</html>
+"""
+
+
+
+def from_magick_file():
+ f = file(sys.argv[1])
+ first_line = f.readline()
+ if not first_line.startswith('<?xml version='):
+ print >> sys.stderr, "'%s' does not seem like a color.mgk file"
+ sys.exit(1)
+
+ re_colors = re.compile(r'name="([^"]+)"\s+red="([^"]+)"\s+green="([^"]+)"\s+blue="([^"]+)"\s+')
+ magick_colors_rgb = []
+ for line in f:
+ line = line.strip()
+ if line.startswith('<color'):
+ m = re_colors.search(line)
+ if m:
+ name, r, g, b = m.group(1), m.group(2), m.group(3), m.group(4)
+ magick_colors_rgb.append((name, int(r), int(g), int(b)))
+ else:
+ pass
+ f.close()
+ return magick_colors_rgb
+
+
+
+if __name__ == '__main__':
+ if len(sys.argv) >= 2:
+ named_colors_rgb = from_magick_file()
+ else:
+ named_colors_rgb = builtin_named_colors_rgb
+
+ #<tr><td>Name</td><td>Color</td><td>R,G,B</td><td>Hex</td></tr>
+ tr = '<tr><td>%s</td><td class="%s" bgcolor="#%02x%02x%02x">%s</td><td>%s, %s, %s</td><td>#%02x%02x%02x</td></tr>'
+ print head
+ for name, r, g, b in named_colors_rgb:
+ if r+g+b < 320:
+ level = 'dark'
+ else:
+ level = 'light'
+ print tr % (name, level, r, g, b, name, r, g, b, r, g, b)
+ print tail
+
diff --git a/scripts/omp_decimal_align.py b/scripts/omp_decimal_align.py
new file mode 100755
index 0000000..40d6833
--- /dev/null
+++ b/scripts/omp_decimal_align.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim: ts=4:sw=4:expandtab:
+
+# Copyright 2008 Mark Mitchell
+# License: Same as GraphicsMagick.
+
+import sys
+import re
+
+try:
+ infilename = sys.argv[1]
+ infile = file(infilename, 'r')
+except IndexError:
+ infile = sys.stdin
+
+for line in infile:
+ line = re.sub(r'<td>(\d+\.\d+</td>)', r'<td class="decimal">\1', line)
+ sys.stdout.write(line)
diff --git a/scripts/pkginfo.sh b/scripts/pkginfo.sh
new file mode 100755
index 0000000..13dbff3
--- /dev/null
+++ b/scripts/pkginfo.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Print the package version based on content of $srcdir/version.sh.
+#
+# This script is expected to be run under the context of a configure
+# script (via AC_INIT) to dynamically determine the package version.
+me=$0
+info=$1
+srcdir=`dirname $0`/..
+value=
+nl='
+'
+. version.sh
+
+case "${info}" in
+ package_bugreport )
+ value="${PACKAGE_BUGREPORT}"
+ ;;
+ package_name )
+ value="${PACKAGE_NAME}"
+ ;;
+ package_version )
+ value="${PACKAGE_VERSION}${PACKAGE_VERSION_ADDENDUM}"
+ ;;
+ * )
+ echo "$me: Must supply argument {package_bugreport, package_name, package_version}"
+ exit 1
+ ;;
+esac
+
+# Omit the trailing newline, so that m4_esyscmd can use the result directly.
+echo "${value}" | tr -d "$nl"
diff --git a/scripts/relpath.py b/scripts/relpath.py
new file mode 100755
index 0000000..7ee56b4
--- /dev/null
+++ b/scripts/relpath.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim: ts=4:sw=4:expandtab:
+
+# Copyright 2008 Mark Mitchell
+# All rights reserved.
+# License: same as Python itself
+
+import sys
+import os, os.path
+
+__doc__ = """Given two paths, one being a "top" directory,
+and the other a file in a directory subordinate to the top directory,
+returns a relative path from subdir to topdir.
+
+Since this is intended for generating prefixes for constructing
+relative URLs, the path separator in the output string is always
+a forward slash, no matter what platform is used.
+
+Usage:
+ relpath.py topdir subdir/filename
+
+Examples:
+
+ args: foo foo/bar/plugh/index.html
+ returns: ../../
+
+ args: /usr/local/src/GraphicsMagick /usr/local/src/GraphicsMagick/www/index.html
+ returns: ../
+"""
+
+def rel_to_top(topdir, subdir):
+ if topdir == subdir:
+ return ''
+
+ head = subdir
+ count = 0
+ while True:
+ head, tail = os.path.split(head)
+ if head == topdir or tail == '':
+ break
+ count += 1
+
+ up = '/'.join(['..'] * count)
+ if up:
+ up += '/'
+
+ return up
+
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print __doc__
+ sys.exit(1)
+
+ topdir = os.path.abspath(sys.argv[1])
+ subdir = os.path.abspath(sys.argv[2])
+ prefix = os.path.commonprefix([topdir, subdir])
+ if prefix != topdir:
+ print >> sys.stderr, "'%s' is not a subordinate path of '%s'" % (subdir, topdir)
+ sys.exit(1)
+
+ print rel_to_top(topdir, subdir)
+ sys.exit(0)
diff --git a/scripts/rst2htmldeco.py b/scripts/rst2htmldeco.py
new file mode 100755
index 0000000..bd6dcba
--- /dev/null
+++ b/scripts/rst2htmldeco.py
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+# vim:ts=4:sw=4:expandtab
+
+#* Author: Mark Mitchell
+#* Copyright 2005-2008 Mark Mitchell, All Rights Reserved
+#* License: see __license__ below.
+
+
+__doc__ = """
+Renders reStructuredText files to HTML using the custom docutils writer
+docutils_htmldeco_writer, which inserts a common header and navigation menu at
+the top of all HTML pages. The header and navigation HTML blobs are
+kept in a separate python file, html_fragments.py.
+
+Usage:
+ rst2htmldeco.py [options] SRCFILE OUTFILE
+
+ SRCFILE is the path to a restructured text file.
+ For example: ./AUTHORS.txt
+
+ OUTFILE is the path where the HTML file is written.
+ For example: ./www/authors.html
+
+ Options:
+
+ -h --help Print this help message
+ -e --embed-stylesheet=<FILE>
+ The stylesheet will be embedded in the HTML.
+ -l --link-stylesheet=<URL>
+ The HTML file will Link to the stylesheet,
+ using the URL verbatim.
+ -r --url-prefix=<PATH>
+ The value of url-prefix is prefixed to all the URLs in the
+ path to get to the top directory from the OUTFILE
+ directory. Used to create working relative URLs in the custom
+ header and navigation menu. Defaults to empty.
+ Example: --url-prefix=../../
+
+
+ -e and -l are mutually excusive. If neither is specified, nothing
+ will work.
+
+ Note that images referenced from the stylesheet may require different
+ image-dir paths depending on whether the stylesheet is embedded or linked.
+ If linked, image URLs in the stylesheet are relative to the stylesheet's
+ location. If embedded, image URLs in the stylesheet are relative to the
+ HTML file's path.
+
+Embedding vs. linking stylesheet
+=================================
+
+Embedding stylesheet
+----------------------
+* The HTML file needs no additional files in particular locations in order
+ to render nicely.
+* The size of every HTML file is inflated. Download time is increased.
+
+Linking stylesheet
+-------------------
+* Best performance for files served via HTTP, as browsers will download the
+ stylesheet once and cache it, and individual HTML files will be more compact.
+
+* No need to regenerate every HTML file if the stylesheet is changed.
+
+* If the HTML file is detached from stylesheet, it will look very plain
+ when rendered by a browser.
+
+Images are always referenced (there's two, the logo and banner background),
+so will not be rendered if the HTML file is detached from the image files.
+"""
+
+__copyright__ = "2005, 2008, Mark Mitchell"
+
+__license__ = """
+Copyright 2005, 2008, Mark Mitchell
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this oftware and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+The Software is provided "as is", without warranty of any kind,
+express or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and noninfringement.
+In no event shall the authors or copyright holders be liable for any
+claim, damages or other liability, whether in an action of contract,
+tort or otherwise, arising from, out of or in connection with Software
+or the use or other dealings in the Software.
+"""
+
+import sys
+import os, os.path
+import locale
+import getopt
+
+import html_fragments
+
+
+try:
+ locale.setlocale(locale.LC_ALL, '')
+except:
+ pass
+
+from docutils.core import publish_cmdline, default_description
+
+
+# Python module name of the custom HTML writer, must be in sys.path
+rst_writer = 'docutils_htmldeco_writer'
+
+docutils_opts = [
+ '--cloak-email-addresses', # Obfusticate email addresses
+ '--no-generator', # no "Generated by Docutils" credit and link at the end of the document.
+ # '--date', # Include the date at the end of the document (UTC)
+ # '--time', # Include the time & date (UTC)
+ '--no-datestamp', # Do not include a datestamp of any kind
+ '--traceback', # Enable Python tracebacks when Docutils is halted.
+ '--rfc-references', # Recognize and link to standalone RFC references (like "RFC 822")
+ '--rfc-base-url=http://tools.ietf.org/html/', # Base URL for RFC references
+]
+
+
+def make_html(src, dest, embed_stylesheet=False,
+ stylesheet=None, url_prefix=''):
+
+ # Fix the url_prefix path in the banner HTML.
+ # This Python tricky business is necessary because the custom docutils
+ # writer, which inserts the HTML blobs, can't do it, because docutils
+ # doesn't provide any way to pass an argument such as image_dir to the
+ # writer.
+ # There must be a better way, but I haven't figured it out yet.
+ if url_prefix:
+ html_fragments.url_prefix = url_prefix.rstrip('/') + '/'
+ html_fragments.nav = html_fragments.make_nav()
+ html_fragments.banner = html_fragments.make_banner()
+ html_fragments.footer = html_fragments.make_footer()
+
+ args = list(docutils_opts)
+ if embed_stylesheet:
+ # for embedded stylesheet
+ args.append('--stylesheet-path=%s' % stylesheet)
+ args.append('--embed-stylesheet')
+ else:
+ # for linked stylesheet
+ args.append('--stylesheet=%s' % stylesheet)
+ args.append('--link-stylesheet')
+ if src is not None:
+ args.append(src)
+ if dest is not None:
+ args.append(dest)
+
+ # Invoke docutils processing of the reST document. This call
+ # to a docutils method ends up executing the custom HTML writer
+ # in docutils_htmldeco_writer.py
+ description = ('Generates (X)HTML documents from standalone reStructuredText '
+ 'sources, with custom banner and footer. ' + default_description)
+ publish_cmdline(writer_name=rst_writer,
+ description=description,
+ argv=args)
+
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv[1:]
+
+ # parse command line options
+ try:
+ opts, posn_args = getopt.getopt(argv, 'he:l:u:',
+ ['help',
+ 'embed-stylesheet=',
+ 'link-stylesheet=',
+ 'url-prefix=',
+ ])
+ except getopt.GetoptError, msg:
+ print msg
+ print __doc__
+ return 1
+
+ # process options
+ embed_stylesheet = False
+ link_stylesheet = True
+ stylesheet = None
+ url_prefix = ''
+
+ for opt, val in opts:
+ if opt in ("-h", "--help"):
+ print __doc__
+ return 0
+
+ if opt in ("-e", "--embed-stylesheet"):
+ link_stylesheet = False
+ embed_stylesheet = True
+ stylesheet = val
+
+ if opt in ("-l", "--link-stylesheet"):
+ embed_stylesheet = False
+ link_stylesheet = True
+ stylesheet = val
+
+ if opt in ("-u", "--url-prefix"):
+ url_prefix = val
+
+ #if len(posn_args) != 2:
+ # print >> sys.stderr, 'Missing arguments'
+ # print >> sys.stderr, __doc__
+ # return 1
+
+ try:
+ srcfile_path = posn_args[0]
+ except IndexError:
+ srcfile_path = None
+ try:
+ outfile_path = posn_args[1]
+ except IndexError:
+ outfile_path = None
+
+ make_html(srcfile_path, outfile_path, embed_stylesheet=embed_stylesheet,
+ stylesheet=stylesheet, url_prefix=url_prefix)
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
+
diff --git a/scripts/rst_pagelist.txt b/scripts/rst_pagelist.txt
new file mode 100755
index 0000000..9acaa90
--- /dev/null
+++ b/scripts/rst_pagelist.txt
@@ -0,0 +1,27 @@
+# reStructuredText files in the GraphicsMagick source tree, which get
+# converted to HTML files in the www/ subdirectory.
+
+# rst_file html_file stylesheet_url url_prefix
+AUTHORS.txt www/AUTHORS.html docutils-articles.css ../
+BENCHMARKS.txt www/BENCHMARKS.html docutils-articles.css ../
+BUGS.txt www/BUGS.html docutils-articles.css ../
+CONTRIBUTE.txt www/CONTRIBUTE.html docutils-articles.css ../
+CVS.txt www/CVS.html docutils-articles.css ../
+Copyright.txt www/Copyright.html docutils-articles.css ../
+DOWNLOAD.txt www/DOWNLOAD.html docutils-articles.css ../
+FAQ.txt www/FAQ.html docutils-articles.css ../
+INSTALL-unix.txt www/INSTALL-unix.html docutils-articles.css ../
+INSTALL-windows.txt www/INSTALL-windows.html docutils-articles.css ../
+LINKS.txt www/LINKS.html docutils-articles.css ../
+MISSION.txt www/MISSION.html docutils-articles.css ../
+NEWS.txt www/NEWS.html docutils-articles.css ../
+OpenMP.txt www/OpenMP.html docutils-articles.css ../
+PLATFORMS.txt www/PLATFORMS.html docutils-articles.css ../
+PROCESS.txt www/PROCESS.html docutils-articles.css ../
+PROGRAMMING.txt www/PROGRAMMING.html docutils-articles.css ../
+README.txt www/README.html docutils-articles.css ../
+UTILITIES.txt www/UTILITIES.html docutils-articles.css ../
+index-topdir.rst index.html www/docutils-articles.css ./
+index-wwwdir.rst www/index.html docutils-articles.css ../
+www/api.rst www/api.html docutils-articles.css ../
+www/perl.rst www/perl.html docutils-articles.css ../
diff --git a/scripts/tap-driver.sh b/scripts/tap-driver.sh
new file mode 100755
index 0000000..ee61fc1
--- /dev/null
+++ b/scripts/tap-driver.sh
@@ -0,0 +1,651 @@
+#! /bin/sh
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# 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, 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+scriptversion=2013-12-23.17; # UTC
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+me=tap-driver.sh
+
+fatal ()
+{
+ echo "$me: fatal: $*" >&2
+ exit 1
+}
+
+usage_error ()
+{
+ echo "$me: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ tap-driver.sh --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--ignore-exit]
+ [--diagnostic-string=STRING] [--merge|--no-merge]
+ [--comments|--no-comments] [--] TEST-COMMAND
+The '--test-name', '-log-file' and '--trs-file' options are mandatory.
+END
+}
+
+# TODO: better error handling in option parsing (in particular, ensure
+# TODO: $log_file, $trs_file and $test_name are defined).
+test_name= # Used for reporting.
+log_file= # Where to save the result and output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=0
+color_tests=0
+merge=0
+ignore_exit=0
+comments=0
+diag_string='#'
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "$me $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) shift;; # No-op.
+ --merge) merge=1;;
+ --no-merge) merge=0;;
+ --ignore-exit) ignore_exit=1;;
+ --comments) comments=1;;
+ --no-comments) comments=0;;
+ --diagnostic-string) diag_string=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ esac
+ shift
+done
+
+test $# -gt 0 || usage_error "missing test command"
+
+case $expect_failure in
+ yes) expect_failure=1;;
+ *) expect_failure=0;;
+esac
+
+if test $color_tests = yes; then
+ init_colors='
+ color_map["red"]="" # Red.
+ color_map["grn"]="" # Green.
+ color_map["lgn"]="" # Light green.
+ color_map["blu"]="" # Blue.
+ color_map["mgn"]="" # Magenta.
+ color_map["std"]="" # No color.
+ color_for_result["ERROR"] = "mgn"
+ color_for_result["PASS"] = "grn"
+ color_for_result["XPASS"] = "red"
+ color_for_result["FAIL"] = "red"
+ color_for_result["XFAIL"] = "lgn"
+ color_for_result["SKIP"] = "blu"'
+else
+ init_colors=''
+fi
+
+# :; is there to work around a bug in bash 3.2 (and earlier) which
+# does not always set '$?' properly on redirection failure.
+# See the Autoconf manual for more details.
+:;{
+ (
+ # Ignore common signals (in this subshell only!), to avoid potential
+ # problems with Korn shells. Some Korn shells are known to propagate
+ # to themselves signals that have killed a child process they were
+ # waiting for; this is done at least for SIGINT (and usually only for
+ # it, in truth). Without the `trap' below, such a behaviour could
+ # cause a premature exit in the current subshell, e.g., in case the
+ # test command it runs gets terminated by a SIGINT. Thus, the awk
+ # script we are piping into would never seen the exit status it
+ # expects on its last input line (which is displayed below by the
+ # last `echo $?' statement), and would thus die reporting an internal
+ # error.
+ # For more information, see the Autoconf manual and the threads:
+ # <http://lists.gnu.org/archive/html/bug-autoconf/2011-09/msg00004.html>
+ # <http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2009-February/004121.html>
+ trap : 1 3 2 13 15
+ if test $merge -gt 0; then
+ exec 2>&1
+ else
+ exec 2>&3
+ fi
+ "$@"
+ echo $?
+ ) | LC_ALL=C ${AM_TAP_AWK-awk} \
+ -v me="$me" \
+ -v test_script_name="$test_name" \
+ -v log_file="$log_file" \
+ -v trs_file="$trs_file" \
+ -v expect_failure="$expect_failure" \
+ -v merge="$merge" \
+ -v ignore_exit="$ignore_exit" \
+ -v comments="$comments" \
+ -v diag_string="$diag_string" \
+'
+# TODO: the usages of "cat >&3" below could be optimized when using
+# GNU awk, and/on on systems that supports /dev/fd/.
+
+# Implementation note: in what follows, `result_obj` will be an
+# associative array that (partly) simulates a TAP result object
+# from the `TAP::Parser` perl module.
+
+## ----------- ##
+## FUNCTIONS ##
+## ----------- ##
+
+function fatal(msg)
+{
+ print me ": " msg | "cat >&2"
+ exit 1
+}
+
+function abort(where)
+{
+ fatal("internal error " where)
+}
+
+# Convert a boolean to a "yes"/"no" string.
+function yn(bool)
+{
+ return bool ? "yes" : "no";
+}
+
+function add_test_result(result)
+{
+ if (!test_results_index)
+ test_results_index = 0
+ test_results_list[test_results_index] = result
+ test_results_index += 1
+ test_results_seen[result] = 1;
+}
+
+# Whether the test script should be re-run by "make recheck".
+function must_recheck()
+{
+ for (k in test_results_seen)
+ if (k != "XFAIL" && k != "PASS" && k != "SKIP")
+ return 1
+ return 0
+}
+
+# Whether the content of the log file associated to this test should
+# be copied into the "global" test-suite.log.
+function copy_in_global_log()
+{
+ for (k in test_results_seen)
+ if (k != "PASS")
+ return 1
+ return 0
+}
+
+function get_global_test_result()
+{
+ if ("ERROR" in test_results_seen)
+ return "ERROR"
+ if ("FAIL" in test_results_seen || "XPASS" in test_results_seen)
+ return "FAIL"
+ all_skipped = 1
+ for (k in test_results_seen)
+ if (k != "SKIP")
+ all_skipped = 0
+ if (all_skipped)
+ return "SKIP"
+ return "PASS";
+}
+
+function stringify_result_obj(result_obj)
+{
+ if (result_obj["is_unplanned"] || result_obj["number"] != testno)
+ return "ERROR"
+
+ if (plan_seen == LATE_PLAN)
+ return "ERROR"
+
+ if (result_obj["directive"] == "TODO")
+ return result_obj["is_ok"] ? "XPASS" : "XFAIL"
+
+ if (result_obj["directive"] == "SKIP")
+ return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL;
+
+ if (length(result_obj["directive"]))
+ abort("in function stringify_result_obj()")
+
+ return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL
+}
+
+function decorate_result(result)
+{
+ color_name = color_for_result[result]
+ if (color_name)
+ return color_map[color_name] "" result "" color_map["std"]
+ # If we are not using colorized output, or if we do not know how
+ # to colorize the given result, we should return it unchanged.
+ return result
+}
+
+function report(result, details)
+{
+ if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/)
+ {
+ msg = ": " test_script_name
+ add_test_result(result)
+ }
+ else if (result == "#")
+ {
+ msg = " " test_script_name ":"
+ }
+ else
+ {
+ abort("in function report()")
+ }
+ if (length(details))
+ msg = msg " " details
+ # Output on console might be colorized.
+ print decorate_result(result) msg
+ # Log the result in the log file too, to help debugging (this is
+ # especially true when said result is a TAP error or "Bail out!").
+ print result msg | "cat >&3";
+}
+
+function testsuite_error(error_message)
+{
+ report("ERROR", "- " error_message)
+}
+
+function handle_tap_result()
+{
+ details = result_obj["number"];
+ if (length(result_obj["description"]))
+ details = details " " result_obj["description"]
+
+ if (plan_seen == LATE_PLAN)
+ {
+ details = details " # AFTER LATE PLAN";
+ }
+ else if (result_obj["is_unplanned"])
+ {
+ details = details " # UNPLANNED";
+ }
+ else if (result_obj["number"] != testno)
+ {
+ details = sprintf("%s # OUT-OF-ORDER (expecting %d)",
+ details, testno);
+ }
+ else if (result_obj["directive"])
+ {
+ details = details " # " result_obj["directive"];
+ if (length(result_obj["explanation"]))
+ details = details " " result_obj["explanation"]
+ }
+
+ report(stringify_result_obj(result_obj), details)
+}
+
+# `skip_reason` should be empty whenever planned > 0.
+function handle_tap_plan(planned, skip_reason)
+{
+ planned += 0 # Avoid getting confused if, say, `planned` is "00"
+ if (length(skip_reason) && planned > 0)
+ abort("in function handle_tap_plan()")
+ if (plan_seen)
+ {
+ # Error, only one plan per stream is acceptable.
+ testsuite_error("multiple test plans")
+ return;
+ }
+ planned_tests = planned
+ # The TAP plan can come before or after *all* the TAP results; we speak
+ # respectively of an "early" or a "late" plan. If we see the plan line
+ # after at least one TAP result has been seen, assume we have a late
+ # plan; in this case, any further test result seen after the plan will
+ # be flagged as an error.
+ plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN)
+ # If testno > 0, we have an error ("too many tests run") that will be
+ # automatically dealt with later, so do not worry about it here. If
+ # $plan_seen is true, we have an error due to a repeated plan, and that
+ # has already been dealt with above. Otherwise, we have a valid "plan
+ # with SKIP" specification, and should report it as a particular kind
+ # of SKIP result.
+ if (planned == 0 && testno == 0)
+ {
+ if (length(skip_reason))
+ skip_reason = "- " skip_reason;
+ report("SKIP", skip_reason);
+ }
+}
+
+function extract_tap_comment(line)
+{
+ if (index(line, diag_string) == 1)
+ {
+ # Strip leading `diag_string` from `line`.
+ line = substr(line, length(diag_string) + 1)
+ # And strip any leading and trailing whitespace left.
+ sub("^[ \t]*", "", line)
+ sub("[ \t]*$", "", line)
+ # Return what is left (if any).
+ return line;
+ }
+ return "";
+}
+
+# When this function is called, we know that line is a TAP result line,
+# so that it matches the (perl) RE "^(not )?ok\b".
+function setup_result_obj(line)
+{
+ # Get the result, and remove it from the line.
+ result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0)
+ sub("^(not )?ok[ \t]*", "", line)
+
+ # If the result has an explicit number, get it and strip it; otherwise,
+ # automatically assing the next progresive number to it.
+ if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/)
+ {
+ match(line, "^[0-9]+")
+ # The final `+ 0` is to normalize numbers with leading zeros.
+ result_obj["number"] = substr(line, 1, RLENGTH) + 0
+ line = substr(line, RLENGTH + 1)
+ }
+ else
+ {
+ result_obj["number"] = testno
+ }
+
+ if (plan_seen == LATE_PLAN)
+ # No further test results are acceptable after a "late" TAP plan
+ # has been seen.
+ result_obj["is_unplanned"] = 1
+ else if (plan_seen && testno > planned_tests)
+ result_obj["is_unplanned"] = 1
+ else
+ result_obj["is_unplanned"] = 0
+
+ # Strip trailing and leading whitespace.
+ sub("^[ \t]*", "", line)
+ sub("[ \t]*$", "", line)
+
+ # This will have to be corrected if we have a "TODO"/"SKIP" directive.
+ result_obj["description"] = line
+ result_obj["directive"] = ""
+ result_obj["explanation"] = ""
+
+ if (index(line, "#") == 0)
+ return # No possible directive, nothing more to do.
+
+ # Directives are case-insensitive.
+ rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*"
+
+ # See whether we have the directive, and if yes, where.
+ pos = match(line, rx "$")
+ if (!pos)
+ pos = match(line, rx "[^a-zA-Z0-9_]")
+
+ # If there was no TAP directive, we have nothing more to do.
+ if (!pos)
+ return
+
+ # Let`s now see if the TAP directive has been escaped. For example:
+ # escaped: ok \# SKIP
+ # not escaped: ok \\# SKIP
+ # escaped: ok \\\\\# SKIP
+ # not escaped: ok \ # SKIP
+ if (substr(line, pos, 1) == "#")
+ {
+ bslash_count = 0
+ for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--)
+ bslash_count += 1
+ if (bslash_count % 2)
+ return # Directive was escaped.
+ }
+
+ # Strip the directive and its explanation (if any) from the test
+ # description.
+ result_obj["description"] = substr(line, 1, pos - 1)
+ # Now remove the test description from the line, that has been dealt
+ # with already.
+ line = substr(line, pos)
+ # Strip the directive, and save its value (normalized to upper case).
+ sub("^[ \t]*#[ \t]*", "", line)
+ result_obj["directive"] = toupper(substr(line, 1, 4))
+ line = substr(line, 5)
+ # Now get the explanation for the directive (if any), with leading
+ # and trailing whitespace removed.
+ sub("^[ \t]*", "", line)
+ sub("[ \t]*$", "", line)
+ result_obj["explanation"] = line
+}
+
+function get_test_exit_message(status)
+{
+ if (status == 0)
+ return ""
+ if (status !~ /^[1-9][0-9]*$/)
+ abort("getting exit status")
+ if (status < 127)
+ exit_details = ""
+ else if (status == 127)
+ exit_details = " (command not found?)"
+ else if (status >= 128 && status <= 255)
+ exit_details = sprintf(" (terminated by signal %d?)", status - 128)
+ else if (status > 256 && status <= 384)
+ # We used to report an "abnormal termination" here, but some Korn
+ # shells, when a child process die due to signal number n, can leave
+ # in $? an exit status of 256+n instead of the more standard 128+n.
+ # Apparently, both behaviours are allowed by POSIX (2008), so be
+ # prepared to handle them both. See also Austing Group report ID
+ # 0000051 <http://www.austingroupbugs.net/view.php?id=51>
+ exit_details = sprintf(" (terminated by signal %d?)", status - 256)
+ else
+ # Never seen in practice.
+ exit_details = " (abnormal termination)"
+ return sprintf("exited with status %d%s", status, exit_details)
+}
+
+function write_test_results()
+{
+ print ":global-test-result: " get_global_test_result() > trs_file
+ print ":recheck: " yn(must_recheck()) > trs_file
+ print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file
+ for (i = 0; i < test_results_index; i += 1)
+ print ":test-result: " test_results_list[i] > trs_file
+ close(trs_file);
+}
+
+BEGIN {
+
+## ------- ##
+## SETUP ##
+## ------- ##
+
+'"$init_colors"'
+
+# Properly initialized once the TAP plan is seen.
+planned_tests = 0
+
+COOKED_PASS = expect_failure ? "XPASS": "PASS";
+COOKED_FAIL = expect_failure ? "XFAIL": "FAIL";
+
+# Enumeration-like constants to remember which kind of plan (if any)
+# has been seen. It is important that NO_PLAN evaluates "false" as
+# a boolean.
+NO_PLAN = 0
+EARLY_PLAN = 1
+LATE_PLAN = 2
+
+testno = 0 # Number of test results seen so far.
+bailed_out = 0 # Whether a "Bail out!" directive has been seen.
+
+# Whether the TAP plan has been seen or not, and if yes, which kind
+# it is ("early" is seen before any test result, "late" otherwise).
+plan_seen = NO_PLAN
+
+## --------- ##
+## PARSING ##
+## --------- ##
+
+is_first_read = 1
+
+while (1)
+ {
+ # Involutions required so that we are able to read the exit status
+ # from the last input line.
+ st = getline
+ if (st < 0) # I/O error.
+ fatal("I/O error while reading from input stream")
+ else if (st == 0) # End-of-input
+ {
+ if (is_first_read)
+ abort("in input loop: only one input line")
+ break
+ }
+ if (is_first_read)
+ {
+ is_first_read = 0
+ nextline = $0
+ continue
+ }
+ else
+ {
+ curline = nextline
+ nextline = $0
+ $0 = curline
+ }
+ # Copy any input line verbatim into the log file.
+ print | "cat >&3"
+ # Parsing of TAP input should stop after a "Bail out!" directive.
+ if (bailed_out)
+ continue
+
+ # TAP test result.
+ if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/)
+ {
+ testno += 1
+ setup_result_obj($0)
+ handle_tap_result()
+ }
+ # TAP plan (normal or "SKIP" without explanation).
+ else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/)
+ {
+ # The next two lines will put the number of planned tests in $0.
+ sub("^1\\.\\.", "")
+ sub("[^0-9]*$", "")
+ handle_tap_plan($0, "")
+ continue
+ }
+ # TAP "SKIP" plan, with an explanation.
+ else if ($0 ~ /^1\.\.0+[ \t]*#/)
+ {
+ # The next lines will put the skip explanation in $0, stripping
+ # any leading and trailing whitespace. This is a little more
+ # tricky in truth, since we want to also strip a potential leading
+ # "SKIP" string from the message.
+ sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "")
+ sub("[ \t]*$", "");
+ handle_tap_plan(0, $0)
+ }
+ # "Bail out!" magic.
+ # Older versions of prove and TAP::Harness (e.g., 3.17) did not
+ # recognize a "Bail out!" directive when preceded by leading
+ # whitespace, but more modern versions (e.g., 3.23) do. So we
+ # emulate the latter, "more modern" behaviour.
+ else if ($0 ~ /^[ \t]*Bail out!/)
+ {
+ bailed_out = 1
+ # Get the bailout message (if any), with leading and trailing
+ # whitespace stripped. The message remains stored in `$0`.
+ sub("^[ \t]*Bail out![ \t]*", "");
+ sub("[ \t]*$", "");
+ # Format the error message for the
+ bailout_message = "Bail out!"
+ if (length($0))
+ bailout_message = bailout_message " " $0
+ testsuite_error(bailout_message)
+ }
+ # Maybe we have too look for dianogtic comments too.
+ else if (comments != 0)
+ {
+ comment = extract_tap_comment($0);
+ if (length(comment))
+ report("#", comment);
+ }
+ }
+
+## -------- ##
+## FINISH ##
+## -------- ##
+
+# A "Bail out!" directive should cause us to ignore any following TAP
+# error, as well as a non-zero exit status from the TAP producer.
+if (!bailed_out)
+ {
+ if (!plan_seen)
+ {
+ testsuite_error("missing test plan")
+ }
+ else if (planned_tests != testno)
+ {
+ bad_amount = testno > planned_tests ? "many" : "few"
+ testsuite_error(sprintf("too %s tests run (expected %d, got %d)",
+ bad_amount, planned_tests, testno))
+ }
+ if (!ignore_exit)
+ {
+ # Fetch exit status from the last line.
+ exit_message = get_test_exit_message(nextline)
+ if (exit_message)
+ testsuite_error(exit_message)
+ }
+ }
+
+write_test_results()
+
+exit 0
+
+} # End of "BEGIN" block.
+'
+
+# TODO: document that we consume the file descriptor 3 :-(
+} 3>"$log_file"
+
+test $? -eq 0 || fatal "I/O or internal error"
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/scripts/tap-functions.shi b/scripts/tap-functions.shi
new file mode 100644
index 0000000..040298f
--- /dev/null
+++ b/scripts/tap-functions.shi
@@ -0,0 +1,115 @@
+# -*- shell-script -*-
+#
+# Copyright (C) 2012 GraphicsMagick Group
+#
+# TAP-test implementation functions specific to GraphicsMagick.
+#
+test_count=0
+
+# Populate a set of shell variables with a variable per feature
+# This is used to implement a poor-man's hash map.
+for feature in ${MAGICK_FEATURES}
+do
+ eval MAGICK_FEATURE_${feature}=yes
+done
+
+# Report the number of TAP tests we will subsequently run
+#
+# Usage:
+# test_plan_fn integer
+test_plan_fn ()
+{
+ #set +x
+ tests_planned=$1
+ echo "1..${tests_planned}"
+ #set -x
+}
+
+# Report TAP test result and increment current test count
+#
+# Usage:
+# test_result_fn result description
+test_result_fn ()
+{
+ #set +x
+ test_result=$1
+ shift
+ #test_count=$(($test_count + 1))
+ test_count=`expr $test_count + 1`
+ test_output="${test_result} ${test_count}"
+ if test x"$*" != x
+ then
+ test_output="${test_output} - $*"
+ fi
+ printf '%s\n' "${test_output}"
+ #set -x
+}
+
+# Test a simple command where pass/fail depends on command exit status
+#
+# Usage:
+# test_command_fn description [ -F 'feat1 feat2 ...'] command
+#
+# Where:
+# description -- test description
+# -F -- optional space-delimited required features
+# command -- command to execute
+test_command_fn ()
+{
+ #set +x
+ test_description=$1
+ shift
+
+ # Parse any feature dependency specification (-F 'feat1 feat2 ...'
+ test_feature_spec=''
+ while test $# -gt 0
+ do
+ case $1 in
+ -F)
+ test_feature_spec=$2
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+ done
+
+ missing=''
+ for feature in ${test_feature_spec}
+ do
+ # Check if required feature is supported
+ if eval test \""\$MAGICK_FEATURE_${feature}"\" != yes
+ then
+ if test "${missing}x" = 'x'
+ then
+ missing=${feature}
+ else
+ missing="${missing} ${feature}"
+ fi
+ fi
+ done
+
+ # Determine if we expect this test to fail due to missing
+ # dependencies.
+ diagnosis=
+ if test "${missing}x" != 'x'
+ then
+ xfail='yes'
+ diagnosis=" # SKIP requires ${missing} support"
+ else
+ xfail='no'
+ diagnosis=
+ fi
+
+ # Execute the test and determine execution status
+ echo "EXEC: $@"
+ ("$@") && fail='no' || fail='yes'
+
+ test "${xfail}" = "${fail}" && test_result='ok' || test_result='not ok'
+
+ # Report results
+ test_result_fn "${test_result}" "${test_description}${diagnosis}"
+ #set -x
+}
diff --git a/scripts/whatis.txt b/scripts/whatis.txt
new file mode 100755
index 0000000..26259fc
--- /dev/null
+++ b/scripts/whatis.txt
@@ -0,0 +1,55 @@
+#
+# What is for API source files
+#
+animate.c Interactively animate an image sequence
+annotate.c Annotate an image with text
+attribute.c Access key,value image attributes
+average.c Image averaging functions
+blob.c Read or write formatted images in memory (BLOBs)
+cdl.c Apply ASC CDL transform to image
+channel.c Image channel functions
+color.c Color related functions
+colormap.c Colormap related functions
+constitute.c Read or write an image
+compare.c Compare images
+composite.c Merge image pixels using a specified algorithm
+confirm_access.c Access confirmation functions
+decorate.c Add decorative frames and borders
+deprecate.c Methods which should no longer be used
+describe.c Methods to describe an image
+display.c Interactively display and edit an image
+export.c Export image pixels into common representations
+render.c Low-level methods to draw on an image
+draw.c User-friendly methods to draw on an image
+effect.c Image effects methods
+fx.c Image special effects methods
+enhance.c Methods to enhance or adjust an image
+error.c Error reporting methods
+hclut.c Apply Hald CLUT to image
+image.c Miscellaneous image methods
+import.c Import image pixels from common representations
+list.c Image list support
+magick.c Image format support interfaces
+memory.c Memory allocation/deallocation functions
+monitor.c Progress monitor support
+montage.c Create a thumbnail image mosaic
+operator.c Methods to apply mathematic or boolean operators to pixels.
+paint.c Methods to fill image pixel regions
+pixel_cache.c Image pixel cache (working pixels).
+pixel_iterator.c Pixel iterator pattern support functions
+plasma.c Create a Plasma fractal image.
+profile.c Manipulate embedded profiles
+quantize.c Reduce the number of colors in an image
+registry.c In-memory image registration interface
+resource.c Set resource consumption limits (e.g. memory)
+segment.c Segment and image with thresholding using the fuzzy c-means method
+shear.c Rotate image, shear image, or apply a 2D affine transformation
+signature.c Add a digital signature to the image
+statistics.c Compute image statistics
+texture.c Image texture functions
+transform.c Crop, flip, flop, roll, coalesce, etc.
+resize.c Resize an image
+widget.c X11 Widgets
+drawing_wand.c Wand vector drawing interfaces
+magick_wand.c Wand image processing interfaces
+pixel_wand.c Wand pixel access interfaces
diff --git a/scripts/xsnap b/scripts/xsnap
new file mode 100644
index 0000000..e593a3b
--- /dev/null
+++ b/scripts/xsnap
@@ -0,0 +1,603 @@
+#!/bin/sh
+# \
+exec wish "$0" "$@"
+
+#
+# XSnap, X-Windows Snapshot. A GUI for the ImageMagick import command
+#
+# Software design, John Cristy (magick@dupont.com), March 1996
+#
+# Copyright (C) 2000 ImageMagick Studio, a non-profit organization
+# dedicated to making software imaging solutions freely available.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files
+# ("ImageMagick"), to deal in ImageMagick without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of ImageMagick,
+# and to permit persons to whom the ImageMagick is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of ImageMagick.
+#
+# The software is provided "as is", without warranty of any kind,
+# express or implied, including but not limited to the warranties of
+# merchantability, fitness for a particular purpose and
+# noninfringement. In no event shall ImageMagick Studio be liable for
+# any claim, damages or other liability, whether in an action of
+# contract, tort or otherwise, arising from, out of or in connection
+# with ImageMagick or the use or other dealings in ImageMagick.
+#
+# Except as contained in this notice, the name of the ImageMagick
+# Studio shall not be used in advertising or otherwise to promote the
+# sale, use or other dealings in ImageMagick without prior written
+# authorization from the ImageMagick Studio.
+#
+#
+
+#
+# Create an alert window and display a message to the user.
+#
+proc Alert {dograb message args} {
+ #
+ # Initialize alert window.
+ #
+ catch {destroy .alert}
+ toplevel .alert -class alert
+ wm title .alert Alert
+ wm iconname .alert alert
+ wm group .alert .
+ wm transient .alert .
+ wm geometry .alert \
+ +[expr {[winfo width .]+[winfo x .]+100}]+[expr {[winfo y .]+75}]
+ #
+ # Create alert window frame.
+ #
+ frame .alert.top -relief raised -border 1
+ frame .alert.bottom -relief raised -border 1
+ pack append .alert .alert.top {top fill expand} .alert.bottom \
+ {top fill expand}
+ message .alert.top.message -width 350 -justify left -text $message
+ pack append .alert.top .alert.top.message {top expand padx 5 pady 5}
+ if {[llength $args] > 0} {
+ #
+ # Create as many buttons as needed and arrange them from left to right.
+ #
+ set arg [lindex $args 0]
+ frame .alert.bottom.0 -relief sunken -border 1
+ pack append .alert.bottom .alert.bottom.0 {left expand padx 10 pady 10}
+ button .alert.bottom.0.button -text [lindex $arg 0] \
+ -command "[lindex $arg 1]; destroy .alert"
+ pack append .alert.bottom.0 .alert.bottom.0.button {expand padx 12 pady 12}
+ bind .alert <Return> "[lindex $arg 1]; destroy .alert"
+ focus .alert
+ set i 1
+ foreach arg [lrange $args 1 end] {
+ button .alert.bottom.$i -text [lindex $arg 0] \
+ -command "[lindex $arg 1]; destroy .alert"
+ pack append .alert.bottom .alert.bottom.$i {left expand padx 20}
+ set i [expr $i+1]
+ }
+ }
+ bind .alert <Any-Enter> [list focus .alert]
+ if {$dograb == "grab"} {
+ tkwait visibility .alert
+ grab set .alert
+ } else {
+ focus .alert
+ }
+}
+
+#
+# Proc AppendImageFormat appends the image format type to the filename.
+#
+proc AppendImageFormat {w} {
+ set snap(format) \
+ [$w.format.list get [lindex [$w.format.list curselection] 0]]
+ set filename [$w.file.entry get]
+ set extension [file extension $filename]
+ $w.file.entry delete \
+ [expr {[string length $filename]-[string length $extension]}] end
+ $w.file.entry insert end .
+ $w.file.entry insert end $snap(format)
+}
+
+#
+# Proc Options creates the options window.
+#
+proc Options {} {
+ #
+ # Initialize snap window.
+ #
+ catch {destroy .options}
+ toplevel .options -class Options
+ wm title .options "Set Image Options"
+ wm group .options .
+ wm transient .options .
+ wm geometry .options \
+ +[expr {[winfo width .]+[winfo x .]+25}]+[winfo y .]
+ #
+ # Create options window frame.
+ #
+ frame .options.input_title
+ label .options.input_title.label -text "Input"
+ pack .options.input_title.label
+ pack .options.input_title
+ frame .options.input -relief sunken -borderwidth 2
+ frame .options.input.checks
+ checkbutton .options.input.checks.border -text "Borders" -width 11 \
+ -anchor w -variable snap(border)
+ checkbutton .options.input.checks.frame -text "Frame" -width 11 \
+ -anchor w -variable snap(frame)
+ checkbutton .options.input.checks.screen -text "Screen" -width 11 \
+ -anchor w -variable snap(screen)
+ checkbutton .options.input.checks.descend -text "Descend" -anchor w \
+ -variable snap(descend)
+ pack .options.input.checks.border .options.input.checks.frame \
+ .options.input.checks.screen .options.input.checks.descend -side left
+ pack .options.input.checks
+ frame .options.input.delay
+ label .options.input.delay.label -text "Delay:" -width 9 -anchor w
+ scale .options.input.delay.scale -orient horizontal -length 11c \
+ -from 0 -to 120 -tickinterval 15 -variable snap(delay)
+ pack .options.input.delay.label .options.input.delay.scale -side left
+ pack .options.input.delay
+ frame .options.input.id
+ label .options.input.id.window -text "Window:" -width 9 -anchor w
+ entry .options.input.id.window_entry -width 18 -relief sunken \
+ -textvariable snap(window)
+ label .options.input.id.display -text "Display:"
+ entry .options.input.id.display_entry -width 18 -relief sunken \
+ -textvariable snap(display)
+ pack .options.input.id.window .options.input.id.window_entry \
+ .options.input.id.display .options.input.id.display_entry -side left
+ pack .options.input.checks .options.input.delay .options.input.id \
+ -padx 1m -anchor w
+ pack .options.input.id -pady 1m
+ pack .options.input -expand 1 -fill both
+ frame .options.processing_title
+ label .options.processing_title.label -text "Image Processing"
+ pack .options.processing_title.label
+ pack .options.processing_title
+ frame .options.processing -relief sunken -borderwidth 2
+ frame .options.processing.checks
+ checkbutton .options.processing.checks.dither -text "Dither" -width 11 \
+ -anchor w -variable snap(dither)
+ checkbutton .options.processing.checks.negate -text "Negate" -width 11 \
+ -anchor w -variable snap(negate)
+ checkbutton .options.processing.checks.monochrome -text "Monochrome" \
+ -width 11 -anchor w -variable snap(monochrome)
+ checkbutton .options.processing.checks.trim -text "Trim" -anchor w \
+ -variable snap(trim)
+ pack .options.processing.checks.dither .options.processing.checks.negate \
+ .options.processing.checks.monochrome .options.processing.checks.trim \
+ -side left
+ pack .options.processing.checks
+ frame .options.processing.colors
+ label .options.processing.colors.label -text "Colors:" -width 9 -anchor w
+ scale .options.processing.colors.scale -orient horizontal -length 11c \
+ -from 0 -to 256 -tickinterval 32 -variable snap(colors)
+ pack .options.processing.colors.label .options.processing.colors.scale \
+ -side left
+ pack .options.processing.colors
+ frame .options.processing.rotate
+ label .options.processing.rotate.label -text "Rotate:" -width 9 -anchor w
+ scale .options.processing.rotate.scale -orient horizontal -length 11c \
+ -from 0 -to 360 -tickinterval 45 -variable snap(degrees)
+ pack .options.processing.rotate.label .options.processing.rotate.scale \
+ -side left
+ pack .options.processing.rotate
+ pack .options.processing.checks .options.processing.colors \
+ .options.processing.rotate -padx 1m -anchor w
+ pack .options.processing -expand 1 -fill both
+ frame .options.output_title
+ label .options.output_title.label -text "Output"
+ pack .options.output_title.label
+ pack .options.output_title
+ frame .options.output -relief sunken -borderwidth 2
+ frame .options.output.checks
+ checkbutton .options.output.checks.compress -text "Compress" -width 11 \
+ -anchor w -variable snap(compress)
+ checkbutton .options.output.checks.interlace -text "Interlace" -width 11 \
+ -anchor w -variable snap(interlace)
+ checkbutton .options.output.checks.verbose -text "Verbose" -anchor w \
+ -variable snap(verbose)
+ pack .options.output.checks.compress .options.output.checks.interlace \
+ .options.output.checks.verbose -side left
+ pack .options.output.checks
+ frame .options.output.scene
+ label .options.output.scene.label -text "Scene:" -width 9 -anchor w
+ scale .options.output.scene.scale -orient horizontal -length 11c \
+ -from 0 -to 40 -tickinterval 5 -variable snap(scene)
+ pack .options.output.scene.label .options.output.scene.scale -side left
+ pack .options.output.scene
+ frame .options.output.comment
+ label .options.output.comment.label -text "Comment:" -width 9 -anchor w
+ entry .options.output.comment.entry -width 45 -relief sunken \
+ -textvariable snap(comment)
+ pack .options.output.comment.label .options.output.comment.entry \
+ -side left
+ pack .options.output.comment
+ frame .options.output.label
+ label .options.output.label.label -text "Label:" -width 9 -anchor w
+ entry .options.output.label.entry -width 45 -relief sunken \
+ -textvariable snap(label)
+ pack .options.output.label.label .options.output.label.entry -side left
+ pack .options.output.label
+ frame .options.output.id
+ label .options.output.id.page -text "Page:" -width 9 -anchor w
+ entry .options.output.id.page_entry -width 18 -relief sunken \
+ -textvariable snap(page)
+ label .options.output.id.density -text "Density:"
+ entry .options.output.id.density_entry -width 18 -relief sunken \
+ -textvariable snap(density)
+ pack .options.output.id.page .options.output.id.page_entry \
+ .options.output.id.density .options.output.id.density_entry -side left
+ pack .options.output.checks .options.output.scene \
+ .options.output.comment .options.output.label .options.output.id \
+ -padx 1m -anchor w
+ pack .options.output.id -pady 1m
+ pack .options.output -expand 1 -fill both
+ button .options.button -text Ok -command {destroy .options}
+ pack .options.button
+ bind .options <Return> {destroy .options}
+ #
+ # Map options window.
+ #
+ pack .options.input_title .options.input .options.processing_title \
+ .options.processing .options.output_title .options.output .options.button \
+ -side top -padx 2m -pady 1m
+}
+
+#
+# Proc Print prints the snapped image to a printer or command.
+#
+proc Print {} {
+ global snap
+
+ . configure -cursor watch
+ update
+ set command convert
+ set command [concat $command $snap(snapshot)]
+ set option +compress
+ if {$snap(compress)} {
+ set option "-compress zip"
+ }
+ set command [concat $command $option]
+ set command [concat $command -density \"$snap(density)\"]
+ set command [concat $command -page \"$snap(page)\"]
+ set command [concat $command \"ps:|$snap(printer)\"]
+ eval exec $command
+ . configure -cursor {}
+}
+
+#
+# Proc PrintImage allows the user to provide a command name to print with.
+#
+proc PrintImage {} {
+ #
+ # Initialize print window.
+ #
+ catch {destroy .print}
+ toplevel .print -class Print
+ wm title .print Print
+ wm group .print .
+ wm transient .print .
+ wm geometry .print \
+ +[expr {[winfo width .]+[winfo x .]+75}]+[expr {[winfo y .]+50}]
+ #
+ # Create print window frame.
+ #
+ frame .print.format
+ scrollbar .print.format.scroll -command ".print.format.list yview"
+ listbox .print.format.list -yscroll ".print.format.scroll set" -setgrid 1 \
+ -height 8
+ pack .print.format.scroll -side right -fill y
+ pack .print.format.list -side top -expand 1 -fill both
+ .print.format.list insert 0 \
+ Letter Tabloid Ledger Legal Statement Executive A3 A4 A5 B4 B5 Folio \
+ Quarto 10x14
+ .print.format.list selection set 0
+ pack .print.format
+ frame .print.file
+ entry .print.file.entry -width 18 -relief sunken -textvariable snap(printer)
+ pack .print.file.entry -side right -expand 1 -fill both
+ pack .print.file
+ frame .print.buttons
+ button .print.buttons.print -text Print -command Print
+ button .print.buttons.cancel -text Cancel -command {destroy .print}
+ pack .print.buttons.print .print.buttons.cancel -side left -expand 1 \
+ -fill both -padx 2m
+ pack .print.buttons
+ #
+ # Map print window.
+ #
+ pack .print.format .print.file .print.buttons -padx 2m -pady 2m -expand 1 \
+ -fill both
+ return
+}
+
+#
+# Proc Save saves the snapped image to disk.
+#
+proc Save {} {
+ global snap
+
+ if ![file readable $snap(snapshot)] {
+ Alert grab "You must snap an image before you can save it!" {" OK " {}}
+ tkwait window .alert
+ return
+ }
+ . configure -cursor watch
+ update
+ set command convert
+ set command [concat $command $snap(snapshot)]
+ set option +compress
+ if {$snap(compress)} {
+ set option "-compress zip"
+ }
+ set command [concat $command $option]
+ set command [concat $command -density \"$snap(density)\"]
+ set command [concat $command -page \"$snap(page)\"]
+ set filename $snap(filename)
+ if {$snap(format) != {}} {
+ set filename "$snap(format):$snap(filename)"
+ }
+ set command [concat $command $filename]
+ eval exec $command
+ . configure -cursor {}
+}
+
+proc SaveImage {} {
+ #
+ # Initialize save window.
+ #
+ catch {destroy .save}
+ toplevel .save -class Saves
+ wm title .save "Save As..."
+ wm group .save .
+ wm transient .save .
+ wm geometry .save \
+ +[expr {[winfo width .]+[winfo x .]+50}]+[expr {[winfo y .]+25}]
+ #
+ # Create save window frame.
+ #
+ frame .save.format
+ scrollbar .save.format.scroll -command ".save.format.list yview"
+ listbox .save.format.list -yscroll ".save.format.scroll set" -setgrid 1 \
+ -height 8
+ pack .save.format.scroll -side right -fill y
+ pack .save.format.list -side top -expand 1 -fill both
+ .save.format.list insert 0 \
+ ps avs bie bmp cmyk dcx eps epsf epsi fax fits gif gif87 gray g3 hdf \
+ histogram jbig jpeg jpg map matte miff mpg mtv pbm pcd pcx pdf pgm pict \
+ png ppm pnm ps2 ras rgb rle sgi sun tga tiff uyvy vid viff x xbm xpm \
+ xv xwd yuv yuv3
+ .save.format.list selection set 0
+ pack .save.format
+ frame .save.file
+ entry .save.file.entry -width 18 -relief sunken -textvariable snap(filename)
+ pack .save.file.entry -side right -expand 1 -fill both
+ pack .save.file
+ frame .save.buttons
+ button .save.buttons.save -text Save -command Save
+ button .save.buttons.cancel -text Cancel -command {destroy .save}
+ pack .save.buttons.save .save.buttons.cancel -side left -expand 1 \
+ -fill both -padx 2m
+ pack .save.buttons
+ #
+ # Bind buttons to print window.
+ #
+ bind .save.format.list <ButtonRelease-1> {
+ set snap(format) \
+ [.save.format.list get [lindex [.save.format.list curselection] 0]]
+ }
+ bind .save.format.list <Double-Button-1> {AppendImageFormat .save}
+ #
+ # Map save window.
+ #
+ pack .save.format .save.file .save.buttons -padx 2m -pady 2m -expand 1 \
+ -fill both
+ return
+}
+
+#
+# Proc ShowImage displays the full-sized snapped image in a top level window.
+#
+proc ShowImage { title name } {
+ catch {destroy .show}
+ toplevel .show -visual best
+ wm title .show $title
+ button .show.image -image $name -command {destroy .show}
+ pack .show.image
+}
+
+#
+# Proc Snap executes the ImageMagick import program to grab the image
+# from the X server screen.
+#
+proc Snap {} {
+ global snap
+
+ #
+ # Initialize import command.
+ #
+ set command import
+ set command [concat $command -depth 8]
+ set option +border
+ if {$snap(border)} {
+ set option -border
+ }
+ set command [concat $command $option]
+ if {$snap(colors)} {
+ set command [concat $command -colors $snap(colors)]
+ }
+ set command [concat $command -comment \"$snap(comment)\"]
+ set option +compress
+ if {$snap(compress)} {
+ set option "-compress zip"
+ }
+ set command [concat $command $option]
+ if {$snap(delay)} {
+ set command [concat $command -delay $snap(delay)]
+ }
+ set command [concat $command -density \"$snap(density)\"]
+ if {$snap(descend)} {
+ set command [concat $command -descend]
+ }
+ set command [concat $command -display \"$snap(display)\"]
+ set option +dither
+ if {$snap(dither)} {
+ set option -dither
+ }
+ set command [concat $command $option]
+ set option +frame
+ if {$snap(frame)} {
+ set option -frame
+ }
+ set command [concat $command $option]
+ set option +interlace
+ if {$snap(interlace)} {
+ set option "-interlace plane"
+ }
+ set command [concat $command $option]
+ set command [concat $command -label \"$snap(label)\"]
+ set option +monochrome
+ if {$snap(monochrome)} {
+ set option -monochrome
+ }
+ set command [concat $command $option]
+ set option +negate
+ if {$snap(negate)} {
+ set option -negate
+ }
+ set command [concat $command $option]
+ set command [concat $command -page \"$snap(page)\"]
+ if {$snap(degrees)} {
+ set command [concat $command -rotate $snap(degrees)]
+ }
+ if {$snap(scene)} {
+ set command [concat $command -scene $snap(scene)]
+ }
+ set option +screen
+ if {$snap(screen)} {
+ set option -screen
+ }
+ set command [concat $command $option]
+ if {$snap(trim)} {
+ set command [concat $command -crop 0x0]
+ }
+ set option +verbose
+ if {$snap(verbose)} {
+ set option -verbose
+ }
+ set command [concat $command $option]
+ set command [concat $command $snap(snapshot)]
+ #
+ # Import the image from the X server screen.
+ #
+ . configure -cursor watch
+ update
+ wm withdraw .
+ eval exec $command
+ wm deiconify .
+ update
+ catch {image delete snapshot}
+ image create photo snapshot -file $snap(snapshot)
+ #
+ # Convert to an image tile.
+ #
+ exec convert -geometry 320x320> $snap(snapshot) $snap(tile)
+ catch {image delete tile}
+ image create photo tile -file $snap(tile)
+ exec rm -f $snap(tile)
+ #
+ # Display tile image as a button.
+ #
+ if [winfo exists .canvas.label] {
+ destroy .canvas.label
+ destroy .canvas.button
+ }
+ label .canvas.label -text $snap(filename)
+ button .canvas.button -image tile -relief sunken -borderwidth 2 \
+ -command { ShowImage $snap(filename) snapshot }
+ pack .canvas.label .canvas.button -side top -expand 1 -fill both \
+ -padx 1m -pady 1m
+ bind . <Return> { ShowImage $snap(filename) snapshot }
+ . configure -cursor {}
+}
+
+#
+# Proc SnapWindow creates the top level window.
+#
+proc SnapWindow {} {
+ #
+ # Initialize snap window.
+ #
+ wm title . "X-Windows Snapshot"
+ wm iconname . "xsnap"
+ #
+ # Create snap window frame.
+ #
+ frame .toolbar -relief raised -bd 2
+ menubutton .toolbar.file -text "File" -menu .toolbar.file.menu -underline 0
+ menu .toolbar.file.menu
+ .toolbar.file.menu add command -label "Save" -command Save
+ .toolbar.file.menu add command -label "Save As ..." -command "SaveImage"
+ .toolbar.file.menu add command -label Print -command PrintImage
+ .toolbar.file.menu add separator
+ .toolbar.file.menu add command -label Quit \
+ -command { exec rm -f $snap(snapshot); exit }
+ pack .toolbar.file -side left
+ pack .toolbar -side top -fill x
+ canvas .canvas -width 256 -height 128
+ pack .canvas
+ frame .buttons
+ button .buttons.snap -text Snap -command Snap
+ button .buttons.options -text Options -command Options
+ pack .buttons.snap .buttons.options -side left -expand 1
+ pack .buttons -side bottom -fill x -padx 2m -pady 2m
+ #
+ # Map snap window.
+ #
+ pack .toolbar .canvas .buttons
+}
+
+#
+# Initalize snap options.
+#
+set snap(border) 0
+set snap(colors) 0
+set snap(comment) "Imported from %m image: %f"
+set snap(compress) 1
+set snap(degrees) 0
+set snap(delay) 0
+set snap(density) 72x72
+set snap(descend) 0
+set snap(display) :0
+if [info exists env(DISPLAY)] {
+ set snap(display) $env(DISPLAY)
+}
+set snap(dither) 1
+set snap(filename) magick.ps
+set snap(format) {}
+set snap(frame) 0
+set snap(interlace) 1
+set snap(label) "%f %wx%h"
+set snap(monochrome) 0
+set snap(negate) 0
+set snap(page) Letter
+set snap(printer) lp
+set snap(scene) 0
+set snap(screen) 0
+set snap(snapshot) /tmp/snap[pid].pnm
+set snap(tile) /tmp/tile[pid].pnm
+set snap(trim) 0
+set snap(verbose) 0
+#
+# Create top level snap window.
+#
+SnapWindow
+tkwait window .
+exec rm -f $snap(snapshot)
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..9c33393
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,69 @@
+# Copyright (C) 2004-2012 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for GraphicsMagick tests invoked via the C API
+#
+
+TESTS_CHECK_PGRMS = \
+ tests/bitstream \
+ tests/constitute \
+ tests/drawtest \
+ tests/maptest \
+ tests/rwblob \
+ tests/rwfile
+
+tests_bitstream_SOURCES = tests/bitstream.c
+tests_bitstream_LDADD = $(LIBMAGICK)
+tests_bitstream_CPPFLAGS = $(AM_CPPFLAGS)
+
+tests_constitute_SOURCES = tests/constitute.c
+tests_constitute_CPPFLAGS = $(AM_CPPFLAGS)
+tests_constitute_LDADD = $(LIBMAGICK)
+
+tests_maptest_SOURCES = tests/maptest.c
+tests_maptest_CPPFLAGS = $(AM_CPPFLAGS)
+tests_maptest_LDADD = $(LIBMAGICK)
+
+tests_rwblob_SOURCES = tests/rwblob.c
+tests_rwblob_CPPFLAGS = $(AM_CPPFLAGS)
+tests_rwblob_LDADD = $(LIBMAGICK)
+
+tests_rwfile_SOURCES = tests/rwfile.c
+tests_rwfile_CPPFLAGS = $(AM_CPPFLAGS)
+tests_rwfile_LDADD = $(LIBMAGICK)
+
+tests_drawtest_SOURCES = tests/drawtest.c
+tests_drawtest_CPPFLAGS = $(AM_CPPFLAGS)
+tests_drawtest_LDADD = $(LIBMAGICK)
+
+
+TESTS_XFAIL_TESTS =
+
+TESTS_TESTS = \
+ tests/constitute.tap \
+ tests/drawtests.tap \
+ tests/rwblob.tap \
+ tests/rwblob_sized.tap \
+ tests/rwfile.tap \
+ tests/rwfile_sized.tap \
+ tests/rwfile_miff.tap \
+ tests/rwfile_pdf.tap \
+ tests/rwfile_deep.tap
+
+TESTS_EXTRA_DIST = \
+ tests/common.shi \
+ tests/input_bilevel.miff \
+ tests/input_gray.miff \
+ tests/input_pallette.miff \
+ tests/input_truecolor_70x46.miff \
+ tests/input_truecolor.miff \
+ tests/input_truecolor10.dpx \
+ tests/input_truecolor12.dpx \
+ tests/input_truecolor16.dpx \
+ $(TESTS_TESTS)
+
+TESTS_CLEANFILES = \
+ tests/*out*.*
diff --git a/tests/bitstream.c b/tests/bitstream.c
new file mode 100644
index 0000000..deeb527
--- /dev/null
+++ b/tests/bitstream.c
@@ -0,0 +1,201 @@
+/*
+ Copyright (C) 2003, 2005, 2009 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Bitstream benchmarks and tests.
+ Written by Bob Friesenhahn, September 2003
+
+*/
+
+#include <magick/studio.h>
+#include <magick/bit_stream.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main ( int argc, char *argv[])
+{
+ const char
+ *mode;
+
+ register unsigned int
+ rep,
+ x;
+
+ register unsigned char
+ *bytes;
+
+ unsigned int
+ result=0;
+
+ unsigned int
+ quantum;
+
+ FILE
+ *file;
+
+ if (argc < 2)
+ {
+ (void) printf("usage: %s read/write/test args\n", argv[0]);
+ exit(1);
+ }
+
+ mode = argv[1];
+
+ file=fopen("/dev/null","wb+");
+ if (!file)
+ {
+ (void) printf("Failed to open file\n");
+ exit(1);
+ }
+
+ if (strcmp(mode,"read") == 0)
+ {
+ BitStreamReadHandle
+ read_stream;
+
+ unsigned int
+ bits;
+
+ unsigned int
+ reps;
+
+ if (argc != 4)
+ {
+ (void) printf("usage: %s read repetitions bits\n", argv[0]);
+ exit(1);
+ }
+
+ reps = atoi(argv[2]);
+ bits = atoi(argv[3]);
+
+ bytes=(unsigned char *)malloc(reps*2);
+ if (!bytes)
+ {
+ (void) printf("Failed to allocate %lu bytes\n", (unsigned long) reps*2);
+ exit(1);
+ }
+ for (rep=0; rep < reps*2; rep++)
+ bytes[rep]=(unsigned char) rep;
+
+ for (rep=reps; rep > 0; rep--)
+ {
+ MagickBitStreamInitializeRead(&read_stream,bytes);
+ for (x=reps; x > 0; x--)
+ {
+ quantum=MagickBitStreamMSBRead(&read_stream,bits);
+ result += quantum;
+ }
+ }
+
+ free(bytes);
+ }
+ else if (strcmp(mode,"write") == 0)
+ {
+ BitStreamWriteHandle
+ write_stream;
+
+ unsigned int
+ bits;
+
+ unsigned int
+ reps;
+
+ if (argc != 4)
+ {
+ (void) printf("usage: %s write repetitions bits\n", argv[0]);
+ exit(1);
+ }
+
+ reps = atoi(argv[2]);
+ bits = atoi(argv[3]);
+
+ bytes=(unsigned char *)malloc(reps*2);
+ if (!bytes)
+ {
+ (void) printf("Failed to allocate %lu bytes\n", (unsigned long) reps*2);
+ exit(1);
+ }
+ (void) memset(bytes,0,reps*2);
+
+ for (rep=reps; rep > 0; rep--)
+ {
+ MagickBitStreamInitializeWrite(&write_stream,bytes);
+ for (x=reps; x > 0; x--)
+ {
+ MagickBitStreamMSBWrite(&write_stream,bits,x);
+ result += bytes[x];
+ }
+ }
+ }
+ else if (strcmp(mode,"test") == 0)
+ {
+ BitStreamWriteHandle
+ write_stream;
+
+ BitStreamReadHandle
+ read_stream;
+
+ size_t
+ allocated_bytes;
+
+ unsigned int
+ bits,
+ max_bits,
+ max_quantum,
+ read_quantum,
+ write_quantum;
+
+ if (argc != 3)
+ {
+ (void) printf("usage: %s test max_bits\n", argv[0]);
+ exit(1);
+ }
+
+ max_bits = atoi(argv[2]);
+
+ for (bits=1 ; bits <= max_bits; bits++)
+ {
+ max_quantum=0x01 << bits;
+
+ allocated_bytes=max_quantum;
+ if (bits > 8)
+ allocated_bytes *= 2;
+ if (bits > 16)
+ allocated_bytes *= 2;
+
+ bytes=(unsigned char *)malloc(allocated_bytes);
+ if (!bytes)
+ {
+ (void) printf("Failed to allocate %lu bytes\n",(unsigned long) allocated_bytes);
+ exit(1);
+ }
+ (void) memset(bytes,0xff,allocated_bytes);
+
+ MagickBitStreamInitializeWrite(&write_stream,bytes);
+ MagickBitStreamInitializeRead(&read_stream,bytes);
+
+ for (write_quantum=0; write_quantum < max_quantum; write_quantum++)
+ {
+ MagickBitStreamMSBWrite(&write_stream,bits,write_quantum);
+ read_quantum=MagickBitStreamMSBRead(&read_stream,bits);
+ if (read_quantum != write_quantum)
+ {
+ (void) printf("mismatch: bits=%u write_quantum=%u read_quantum=%u\n",
+ bits,write_quantum,read_quantum);
+ }
+ }
+
+ free(bytes);
+ }
+ }
+
+ (void) fprintf(file,"result=%u\n",result);
+ (void) fclose(file);
+
+ return 0;
+}
diff --git a/tests/common.shi b/tests/common.shi
new file mode 100755
index 0000000..c456d80
--- /dev/null
+++ b/tests/common.shi
@@ -0,0 +1,5 @@
+# -*- shell-script -*-
+subdir=tests
+SRCDIR=${top_srcdir}/${subdir}
+. ${top_srcdir}/scripts/tap-functions.shi
+cd ${subdir} || exit 1
diff --git a/tests/constitute.c b/tests/constitute.c
new file mode 100644
index 0000000..5a5c4a7
--- /dev/null
+++ b/tests/constitute.c
@@ -0,0 +1,334 @@
+/*
+ *
+ * Test DispatchImage/ConstituteImage operations via
+ * write/read/write/read sequence to detect any data corruption
+ * problems.
+ *
+ * Written by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+ *
+ * The image returned by both reads must be identical in order for the
+ * test to pass.
+ *
+ */
+
+#include <magick/api.h>
+#include <magick/enum_strings.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main ( int argc, char **argv )
+{
+ Image
+ *final = (Image *) NULL,
+ *original = (Image *) NULL;
+
+ void
+ *pixels=0;
+
+ char
+ infile[MaxTextExtent],
+ map[MaxTextExtent];
+
+ int
+ arg = 1,
+ exit_status = 0,
+ rows = 0,
+ columns = 0,
+ pause = 0;
+
+ unsigned int
+ quantum_size=sizeof(unsigned char);
+
+ size_t
+ pixels_size;
+
+ double
+ fuzz_factor = 0.0;
+
+ ImageInfo
+ *imageInfo;
+
+ ExceptionInfo
+ exception;
+
+ StorageType
+ storage_type=CharPixel;
+
+ if (LocaleNCompare("constitute",argv[0],7) == 0)
+ InitializeMagick((char *) NULL);
+ else
+ InitializeMagick(*argv);
+
+ imageInfo=CloneImageInfo(0);
+ GetExceptionInfo( &exception );
+
+ for (arg=1; arg < argc; arg++)
+ {
+ char
+ *option = argv[arg];
+
+ if (*option == '-')
+ {
+ if (LocaleCompare("debug",option+1) == 0)
+ (void) SetLogEventMask(argv[++arg]);
+ else if (LocaleCompare("depth",option+1) == 0)
+ {
+ imageInfo->depth=QuantumDepth;
+ arg++;
+ if ((arg == argc) || !sscanf(argv[arg],"%ld",&imageInfo->depth))
+ {
+ (void) printf("-depth argument missing or not integer\n");
+ exit_status = 1;
+ goto program_exit;
+ }
+ if(imageInfo->depth != 8 && imageInfo->depth != 16 && imageInfo->depth != 32)
+ {
+ (void) printf("-depth (%ld) not 8, 16, or 32\n", imageInfo->depth);
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+ else if (LocaleCompare("log",option+1) == 0)
+ (void) SetLogFormat(argv[++arg]);
+ else if (LocaleCompare("pause",option+1) == 0)
+ pause=1;
+ else if (LocaleCompare("size",option+1) == 0)
+ {
+ arg++;
+ if ((arg == argc) || !IsGeometry(argv[arg]))
+ {
+ (void) printf("-size argument missing or not geometry\n");
+ exit_status = 1;
+ goto program_exit;
+ }
+ (void) CloneString(&imageInfo->size,argv[arg]);
+ }
+ else if (LocaleCompare("storagetype",option+1) == 0)
+ {
+ arg++;
+ if (arg == argc)
+ {
+ (void) printf("-storagetype argument missing\n");
+ exit_status = 1;
+ goto program_exit;
+ }
+ if (LocaleCompare("Char",argv[arg]) == 0)
+ {
+ storage_type=CharPixel;
+ quantum_size=sizeof(unsigned char);
+ }
+ else if (LocaleCompare("Short",argv[arg]) == 0)
+ {
+ storage_type=ShortPixel;
+ quantum_size=sizeof(unsigned short);
+ }
+ else if (LocaleCompare("Integer",argv[arg]) == 0)
+ {
+ storage_type=IntegerPixel;
+ quantum_size=sizeof(unsigned int);
+ }
+ else if (LocaleCompare("Long",argv[arg]) == 0)
+ {
+ storage_type=LongPixel;
+ quantum_size=sizeof(unsigned long);
+ }
+ else if (LocaleCompare("Float",argv[arg]) == 0)
+ {
+ storage_type=FloatPixel;
+ quantum_size=sizeof(float);
+#if (QuantumDepth > 16)
+ fuzz_factor=7.5e-06; // Float requires some slop for Q:32
+#endif
+ }
+ else if (LocaleCompare("Double",argv[arg]) == 0)
+ {
+ storage_type=DoublePixel;
+ quantum_size=sizeof(double);
+ }
+ else
+ {
+ (void) printf("Unrecognized storagetype argument %s\n",argv[arg]);
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+ }
+ else
+ break;
+ }
+ if (arg != argc-2)
+ {
+ (void) printf ( "Usage: %s -debug events -depth integer -log format -size geometry -storagetype type] infile map\n", argv[0] );
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ (void) strncpy(infile, argv[arg], MaxTextExtent-1 );
+ arg++;
+ (void) strncpy( map, argv[arg], MaxTextExtent-1 );
+
+/* for (arg=0; arg < argc; arg++) */
+/* (void) printf("%s ", argv[arg]); */
+/* (void) printf("\n"); */
+/* (void) fflush(stdout); */
+
+ /*
+ * Read original image
+ */
+ GetExceptionInfo( &exception );
+ imageInfo->dither = 0;
+ (void) strncpy( imageInfo->filename, infile, MaxTextExtent-1 );
+ (void) strcat( imageInfo->filename,"[0]" );
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading image %s", imageInfo->filename);
+ original = ReadImage ( imageInfo, &exception );
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if ( original == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read original image %s\n", imageInfo->filename );
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /* If a CMYK map is specified, make sure that input image is CMYK */
+ if (strchr(map,'c') || strchr(map,'C') || strchr(map,'m') || strchr(map,'M') ||
+ strchr(map,'y') || strchr(map,'y') || strchr(map,'k') || strchr(map,'k'))
+ (void) TransformColorspace(original,CMYKColorspace);
+
+ /*
+ * Obtain original image size if format requires it
+ */
+ rows = original->rows;
+ columns = original->columns;
+
+ /*
+ * Save image to array
+ */
+ pixels_size=quantum_size*strlen(map)*rows*columns;
+ pixels=MagickMalloc(pixels_size);
+ if( !pixels )
+ {
+ (void) printf ( "Failed to allocate memory for pixels\n");
+ exit_status = 1;
+ goto program_exit;
+ }
+ (void) memset((void *) pixels, 0, pixels_size);
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing image to pixel array");
+ if( !DispatchImage(original,0,0,original->columns,original->rows,map,
+ storage_type,pixels,&exception) )
+ {
+ (void) printf ( "DispatchImage returned error status\n");
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ DestroyImageList( original );
+ original = (Image*)NULL;
+
+ /*
+ * Read image back from pixel array
+ */
+
+ original = ConstituteImage(columns,rows,map,storage_type,pixels,&exception);
+ if ( original == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read image from pixels array\n" );
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /*
+ * Save image to pixel array
+ */
+ (void) memset((void *) pixels, 0, pixels_size);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing image to pixel array");
+ if( !DispatchImage(original,0,0,original->columns,original->rows,map,
+ storage_type,pixels,&exception) )
+ {
+ (void) printf ( "DispatchImage returned error status\n" );
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /*
+ * Read image back from pixel array
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading image from pixel array");
+ final = ConstituteImage(columns,rows,map,storage_type,pixels,&exception);
+ if ( final == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read image from pixels array\n" );
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ MagickFree(pixels);
+ pixels=0;
+
+ /*
+ * Check final output
+ */
+
+ if (original->colorspace != final->colorspace)
+ {
+ (void) printf("Original colorspace (%s) != final colorspace (%s)\n",
+ ColorspaceTypeToString(original->colorspace),
+ ColorspaceTypeToString(final->colorspace));
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ if ( !IsImagesEqual(original, final) )
+ {
+ CatchException(&original->exception);
+ CatchException(&final->exception);
+ if (original->error.normalized_mean_error > fuzz_factor)
+ {
+ exit_status = 1;
+ (void) printf( "Constitute check failed: %u/%g/%g\n",
+ (unsigned int) original->error.mean_error_per_pixel,
+ original->error.normalized_mean_error,
+ original->error.normalized_maximum_error);
+ }
+ goto program_exit;
+ }
+
+ program_exit:
+ (void) fflush(stdout);
+ if (original)
+ DestroyImage( original );
+ original = 0;
+ if (final)
+ {
+ if (getenv("SHOW_RESULT") != 0)
+ (void) DisplayImages( imageInfo, final );
+ DestroyImage( final );
+ }
+ final = 0;
+ MagickFree(pixels);
+ pixels=0;
+ if (imageInfo)
+ DestroyImageInfo(imageInfo);
+ imageInfo = 0;
+
+ DestroyMagick();
+
+ if (pause)
+ (void) getc(stdin);
+ return exit_status;
+}
diff --git a/tests/constitute.tap b/tests/constitute.tap
new file mode 100755
index 0000000..a72bf88
--- /dev/null
+++ b/tests/constitute.tap
@@ -0,0 +1,26 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test raw image encode/decode in memory.
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+num_tests=0
+storage_types='char short integer long float double'
+constitute_maps='bgr bgro bgrp rgb rgba rgbt rgbo prgb cmy cmyk i'
+for storage_type in ${storage_types}
+do
+ for map in ${constitute_maps}
+ do
+ num_tests=`expr ${num_tests} + 1`
+ done
+done
+infile=${SRCDIR}/input_truecolor.miff
+test_plan_fn ${num_tests}
+for storage_type in ${storage_types}
+do
+ for map in ${constitute_maps}
+ do
+ test_command_fn "${storage_type} ${map}" ${MEMCHECK} ./constitute -storagetype ${storage_type} ${infile} ${map}
+ done
+done
+:
diff --git a/tests/drawtest.c b/tests/drawtest.c
new file mode 100644
index 0000000..e4e16e0
--- /dev/null
+++ b/tests/drawtest.c
@@ -0,0 +1,406 @@
+/*
+ *
+ * Test program for C drawing API
+ * Written by Bob Friesenhahn
+ *
+ */
+
+#include <magick/api.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(True)
+# define True 1
+#endif
+
+#if !defined(False)
+# define False 0
+#endif
+static void ScribbleImage ( Image *image)
+{
+ DrawContext
+ context;
+/* SetLogEventMask("Render"); */
+ context = DrawAllocateContext((DrawInfo*)NULL, image);
+
+ DrawPushGraphicContext(context);
+ {
+ DrawSetViewbox(context,0,0,image->columns,image->rows);
+ DrawScale(context,1.101,1.08);
+ DrawTranslate(context,-23.69,-22.97);
+ DrawRotate(context,0);
+ DrawSetFillColorString(context,"#ffffff");
+ DrawRectangle(context,23.69,22.97,564.6,802.2);
+ DrawSetFillOpacity(context,1.0);
+ DrawSetFillColorString(context,"none");
+ DrawSetStrokeColorString(context,"none");
+
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+
+ DrawPushDefs(context);
+ {
+ DrawPushClipPath(context,"clip_1");
+ {
+ DrawPushGraphicContext(context);
+ {
+ DrawRectangle(context,0,0,595.3,841.9);
+ }
+ DrawPopGraphicContext(context);
+ }
+ DrawPopClipPath(context);
+ }
+ DrawPopDefs(context);
+
+ DrawPushGraphicContext(context);
+ {
+ DrawSetClipPath(context, "url(#clip_1)");
+
+ DrawPushGraphicContext(context);
+ {
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,4.032);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#ff0000");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#ff00ff");
+ DrawRectangle(context,72,72,144,144);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,9);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#00ff00");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#0080ff");
+ DrawRoundRectangle(context,72,216,360,432,9,9);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ const PointInfo points[37] =
+ {
+ { 378.1,81.72 }, { 381.1,79.56 }, { 384.3,78.12 }, { 387.6,77.33 },
+ { 391.1,77.11 }, { 394.6,77.62 }, { 397.8,78.77 }, { 400.9,80.57 },
+ { 403.6,83.02 }, { 523.9,216.8 }, { 526.2,219.7 }, { 527.6,223 },
+ { 528.4,226.4 }, { 528.6,229.8 }, { 528,233.3 }, { 526.9,236.5 },
+ { 525.1,239.5 }, { 522.6,242.2 }, { 495.9,266.3 }, { 493,268.5 },
+ { 489.7,269.9 }, { 486.4,270.8 }, { 482.9,270.9 }, { 479.5,270.4 },
+ { 476.2,269.3 }, { 473.2,267.5 }, { 470.4,265 }, { 350,131.2 },
+ { 347.8,128.3 }, { 346.4,125.1 }, { 345.6,121.7 }, {345.4,118.2 },
+ { 346,114.8 }, { 347.1,111.5 }, { 348.9,108.5 }, { 351.4,105.8 },
+ { 378.1,81.72 }
+ };
+
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,2.016);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#000080");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#c2c280");
+ DrawPolygon(context,37,points);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,3.024);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#000080");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#00ffff");
+ DrawEllipse(context,489.6,424.8,72,129.6,0,360);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ const PointInfo points[48] =
+ {
+ { 213.8,25.13}, { 216.7,24.48 }, {219.8,24.55 }, { 223.1,25.42 },
+ { 226.7,27 }, { 230.3,29.3 }, { 234.1,32.26 }, { 237.9,35.86 },
+ { 241.8,40.03 }, { 249.7,50.11 }, { 257.4,62.14 }, { 264.8,75.89 },
+ { 271.6,91.15 }, { 277.3,106.8 }, { 281.6,121.8 }, { 284.4,135.9 },
+ { 285.7,148.5 }, { 285.6,159.6 }, { 284.9,164.3 }, { 283.8,168.5 },
+ { 282.5,172.1 }, { 280.7,175 }, { 278.5,177.3 }, { 275.9,178.7 },
+ { 273,179.4 }, { 269.9,179.3 }, { 266.6,178.4 }, { 263.1,176.8 },
+ { 259.5,174.5}, { 255.7,171.6 }, { 251.9,168 }, { 248,163.8 },
+ { 244.1,159 }, { 240.1,153.7 }, { 232.3,141.7 }, { 225,127.9 },
+ { 218.2,112.7 }, { 212.5,97.06 }, { 208.2,82.01 }, { 205.4,67.97 },
+ { 204,55.3 }, { 204.3,44.35 }, { 204.9,39.6 }, { 205.9,35.42 },
+ { 207.4,31.82 }, { 209.2,28.87 }, { 211.3,26.64}, { 213.8,25.13 }
+ };
+
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,3.024);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#ff8000");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#00ffff");
+ DrawPolygon(context,48,points);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,12.02);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#4000c2");
+ DrawSetFillColorString(context,"none");
+ DrawArc(context,360,554.4,187.2,237.6,0,90);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,9);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#4000c2");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#800000");
+ DrawEllipse(context,388.8,626.4,100.8,122.4,0,90);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ const PointInfo points[6] =
+ {
+ { 180,504 }, { 282.7,578.6 }, { 243.5,699.4 }, { 116.5,699.4 },
+ { 77.26,578.6 }, { 180,504 }
+ };
+
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,9);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#4000c2");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#800000");
+ DrawPolygon(context,6,points);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ const PointInfo points[11] =
+ {
+ { 180,504 }, { 211.8,568.3 }, { 282.7,578.6 }, { 231.3,628.7 },
+ { 243.5,699.4 }, { 180,666 }, { 116.5,699.4 }, { 128.7,628.7 },
+ { 77.26,578.6 }, { 148.2,568.3 }, { 180,504 }
+ };
+
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,9);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#4000c2");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#800000");
+ DrawPolygon(context,11,points);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ const PointInfo points[15] =
+ {
+ { 540,288 }, { 561.6,216 }, { 547.2,43.2 }, { 280.8,36 },
+ { 302.4,194.4 }, { 331.2,64.8 }, { 504,64.8 }, { 475.2,115.2 },
+ { 525.6,93.6 }, { 496.8,158.4 }, { 532.8,136.8 }, { 518.4,180 },
+ { 540,172.8 }, { 540,223.2 }, { 540,288 }
+ };
+
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,5.976);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#4000c2");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#ffff00");
+ DrawPolygon(context,15,points);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ const PointInfo points[7] =
+ {
+ { 57.6,640.8 }, { 57.6,784.8 }, { 194.4,799.2 }, { 259.2,777.6 },
+ { 151.2,756 }, { 86.4,748.8 }, { 57.6,640.8 }
+ };
+
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,5.976);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#4000c2");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#ffff00");
+ DrawPolygon(context,7,points);
+ }
+ DrawPopGraphicContext(context);
+
+ DrawPushGraphicContext(context);
+ {
+ const PointInfo points[193] =
+ {
+ { 27.86,565.3 }, { 29.66,550.8 }, { 31.97,538.1 }, { 34.85,527.1 },
+ { 38.09,517.7 }, { 41.83,509.8 }, { 45.86,503.1 }, { 50.33,497.6 },
+ { 55.08,493.2 }, { 60.19,489.8 }, { 65.45,487.3 }, { 70.92,485.4 },
+ { 76.61,484.2 }, { 88.42,483 }, { 100.4,482.9 }, { 108.4,482.2 },
+ { 119.8,480.3 }, { 150.8,474.1 }, { 189.4,466.6 }, { 210.3,463 },
+ { 231.5,459.9 }, { 252.4,457.8 }, { 272.7,456.6 }, { 291.8,456.9 },
+ { 300.7,457.7 }, { 309.1,458.9 }, { 316.9,460.6 }, { 324.1,462.8 },
+ { 330.7,465.6 }, { 336.4,469 }, { 341.3,473 }, { 345.3,477.7 },
+ { 348.4,483.1 }, { 350.4,489.2}, { 352.4,495.4 }, { 355.2,500.9 },
+ { 358.8,505.8 }, { 363,510 }, { 367.8,513.6 }, { 373,516.8 },
+ { 378.6,519.6 }, { 384.3,521.8 }, { 396.4,525.4 }, { 408.2,527.9 },
+ { 428,531.2 }, { 434.6,532.9 }, { 436.7,533.8 }, { 437.8,534.9 },
+ { 437.8,536.2 }, { 436.8,537.8 }, { 434.5,539.6 }, { 430.9,541.8 },
+ { 419.3,547.6 }, { 401.3,555.2 }, { 342.4,577.9 }, {325.2,584.9 },
+ { 311,591.3 }, { 300,597.3 }, { 291.6,602.8 }, { 285.8,607.8 },
+ { 282.3,612.3 }, { 281.4,614.4 }, { 280.9,616.2 }, { 281.2,619.6 },
+ { 282.1,621.2 }, { 283.3,622.6 }, { 286.8,624.9 }, { 291.5,626.6 },
+ { 297.1,627.8 }, { 303.6,628.3 }, { 310.5,628.3 }, { 317.9,627.6 },
+ { 325.2,626.3 }, { 332.6,624.3 }, { 339.5,621.7 }, { 345.9,618.4 },
+ { 351.4,614.4 }, { 353.9,612.2 }, { 356,609.8 }, { 357.9,607.1 },
+ { 359.4,604.3 }, { 360.6,601.3 }, { 361.4,598.2 }, { 361.7,594.9 },
+ { 361.7,591.3 }, { 361.2,587.7 }, { 360.1,583.7 }, { 358.6,579.7 },
+ { 356.4,575.4 }, { 353.7,570.9 }, { 350.4,566.2 }, { 346.4,561.3 },
+ { 341.8,556.2 }, { 336.5,550.9 }, { 330.6,545.5 }, { 323.8,539.8 },
+ { 316.2,533.9 }, { 298.7,521.5 }, { 277.8,508.2 }, { 256.1,495.5 },
+ { 236,484.5 }, { 217.7,475.1 }, { 200.8,467.1 }, { 185.6,460.7 },
+ { 171.9,455.5 }, { 159.6,451.6 }, { 148.6,448.8 }, { 139,447 },
+ { 130.5,446.2 }, { 123.3,446.2 }, { 117.1,446.9 }, { 112,448.3 },
+ { 107.9,450.2 }, { 104.8,452.5 }, { 102.5,455.2 }, { 101,458.1 },
+ { 100.2,461.2 }, { 100.2,464.3 }, { 100.7,467.4 }, { 101.8,470.3 },
+ { 103.4,473 }, { 105.4,475.3 }, { 107.8,477.1 }, { 110.5,478.4 },
+ { 113.4,479.1 }, { 116.5,478.9 }, { 119.7,478 }, { 123,476.2 },
+ { 126.4,473.3 }, { 129.6,469.2 }, { 132.7,463.9 }, { 135.2,458.4 },
+ { 136.6,453.7 }, { 137,449.9 }, { 136.6,446.8 }, { 135.4,444.5 },
+ { 133.3,442.9 }, { 130.8,441.9 }, { 127.5,441.4 }, { 123.9,441.6 },
+ { 119.8,442.3 }, { 110.7,445.1 }, { 101.1,449.5 }, { 91.37,455.2 },
+ { 82.37,461.9 }, { 74.66,469.2 }, { 71.57,473 }, { 68.98,476.8 },
+ { 67.03,480.7 }, { 65.81,484.4 }, { 65.45,488.2 }, { 65.95,491.7 },
+ { 67.46,495.1 }, { 69.98,498.3 }, { 73.66,501.3 }, { 78.55,503.9 },
+ { 84.82,506.3 }, { 92.38,508.2 }, { 107.1,511.6 }, { 118.2,514.8 },
+ { 125.9,517.8 }, { 130.7,520.4 }, { 132.1,521.7 }, { 132.8,522.9 },
+ { 133,524.2 }, { 132.6,525.3 }, { 131.8,526.5 }, { 130.5,527.5 },
+ { 126.6,529.6 }, { 121.5,531.7 }, { 115.3,533.7 }, { 101.4,537.6 },
+ { 87.55,541.8 }, { 81.36,544 }, { 76.25,546.3 }, { 71.64,549.5 },
+ { 66.89,554.1 }, { 62.14,559.8 }, { 57.38,566.1 }, { 48.17,579.6 },
+ { 39.96,591.4 }, { 36.43,595.9 }, { 34.78,597.6 }, { 33.26,598.8 },
+ { 31.9,599.6 }, { 30.67,599.9 }, { 29.59,599.7 }, { 28.66,598.8 },
+ { 27.86,597.4 }, { 27.29,595.2 }, { 26.64,588.7 }, { 26.86,578.8 },
+ { 27.86,565.3 }
+ };
+
+ DrawSetStrokeAntialias(context,True);
+ DrawSetStrokeWidth(context,5.904);
+ DrawSetStrokeLineCap(context,RoundCap);
+ DrawSetStrokeLineJoin(context,RoundJoin);
+ DrawSetStrokeDashArray(context,0,(const double *)NULL);
+ DrawSetStrokeColorString(context,"#4000c2");
+ DrawSetFillRule(context,EvenOddRule);
+ DrawSetFillColorString(context,"#ffff00");
+ DrawPolygon(context,193,points);
+ }
+ DrawPopGraphicContext(context);
+ }
+ DrawPopGraphicContext(context);
+ }
+ DrawPopGraphicContext(context);
+
+ (void) DrawRender(context);
+ DrawDestroyContext(context);
+}
+
+int main ( int argc, char **argv )
+{
+ Image *canvas = (Image *)NULL;
+ char outfile[MaxTextExtent];
+ int rows, columns = 0;
+ char size[MaxTextExtent];
+ ImageInfo *image_info;
+ ExceptionInfo exception;
+
+ if ( argc != 2 )
+ {
+ (void) printf ( "Usage: %s filename\n", argv[0] );
+ exit( 1 );
+ }
+
+ outfile[MaxTextExtent-1]='\0';
+ (void) strncpy( outfile, argv[1], MaxTextExtent-1 );
+
+ if (LocaleNCompare("drawtest",argv[0],7) == 0)
+ InitializeMagick((char *) NULL);
+ else
+ InitializeMagick(*argv);
+
+ /*
+ * Create canvas image
+ */
+ columns=596;
+ rows=842;
+ image_info=CloneImageInfo((ImageInfo*)NULL);
+ GetExceptionInfo( &exception );
+ FormatString(size, "%dx%d", columns, rows);
+ (void) CloneString(&image_info->size, size);
+ (void) strcpy( image_info->filename, "xc:white");
+ canvas = ReadImage ( image_info, &exception );
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if ( canvas == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read canvas image %s\n", image_info->filename );
+ exit(1);
+ }
+
+ /*
+ * Scribble on image
+ */
+ ScribbleImage( canvas );
+
+ /*
+ * Save image to file
+ */
+ canvas->filename[MaxTextExtent-1]='\0';
+ (void) strncpy( canvas->filename, outfile, MaxTextExtent-1);
+ (void) WriteImage ( image_info, canvas );
+
+ DestroyExceptionInfo( &exception );
+ DestroyImage( canvas );
+ DestroyImageInfo( image_info );
+ DestroyMagick();
+ return 0;
+}
diff --git a/tests/drawtests.tap b/tests/drawtests.tap
new file mode 100755
index 0000000..9e3ee69
--- /dev/null
+++ b/tests/drawtests.tap
@@ -0,0 +1,9 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2010 GraphicsMagick Group
+# Test vector drawing.
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+test_plan_fn 1
+test_command_fn 'vector drawing' ${MEMCHECK} ./drawtest drawtest_out.miff
+:
diff --git a/tests/input_bilevel.miff b/tests/input_bilevel.miff
new file mode 100644
index 0000000..2f4ea87
--- /dev/null
+++ b/tests/input_bilevel.miff
Binary files differ
diff --git a/tests/input_gray.miff b/tests/input_gray.miff
new file mode 100644
index 0000000..c0b5f47
--- /dev/null
+++ b/tests/input_gray.miff
Binary files differ
diff --git a/tests/input_pallette.miff b/tests/input_pallette.miff
new file mode 100644
index 0000000..6777bc5
--- /dev/null
+++ b/tests/input_pallette.miff
Binary files differ
diff --git a/tests/input_truecolor.miff b/tests/input_truecolor.miff
new file mode 100644
index 0000000..6ecdffb
--- /dev/null
+++ b/tests/input_truecolor.miff
@@ -0,0 +1,16 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+iterations=0 delay=0
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+iterations=0 delay=0
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+iterations=0 delay=0
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/tests/input_truecolor10.dpx b/tests/input_truecolor10.dpx
new file mode 100644
index 0000000..bcc1b38
--- /dev/null
+++ b/tests/input_truecolor10.dpx
Binary files differ
diff --git a/tests/input_truecolor12.dpx b/tests/input_truecolor12.dpx
new file mode 100644
index 0000000..f4ee23e
--- /dev/null
+++ b/tests/input_truecolor12.dpx
Binary files differ
diff --git a/tests/input_truecolor16.dpx b/tests/input_truecolor16.dpx
new file mode 100644
index 0000000..33814bb
--- /dev/null
+++ b/tests/input_truecolor16.dpx
Binary files differ
diff --git a/tests/input_truecolor_70x46.miff b/tests/input_truecolor_70x46.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/tests/input_truecolor_70x46.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/tests/maptest.c b/tests/maptest.c
new file mode 100644
index 0000000..25f7f32
--- /dev/null
+++ b/tests/maptest.c
@@ -0,0 +1,129 @@
+/*
+ Copyright (C) 2003 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Test MagickMap key,value map functionality
+
+ Written by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+*/
+
+#include <magick/api.h>
+#include <magick/map.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct _KeyValMap
+{
+ char *key;
+ char *value;
+} KeyValMap;
+
+
+int main ( int argc, char **argv )
+{
+ int
+ exit_status = 0,
+ i;
+
+ ExceptionInfo
+ exception;
+
+ MagickMap
+ map;
+
+ MagickMapIterator
+ iterator;
+
+ const char
+ *key;
+
+ static const KeyValMap
+ KeyVal[] =
+ {
+ { "0", "number 0" },
+ { "1", "number 1" },
+ { "2", "number 2" },
+ { "3", "number 3" },
+ { "4", "number 4" },
+ { "5", "number 5" },
+ { "6", "number 6" },
+ { "7", "number 7" },
+ { "8", "number 8" },
+ { "9", "number 9" },
+ { 0, 0 }
+ };
+
+ (void) argc;
+ (void) argv;
+
+ GetExceptionInfo(&exception);
+ map=MagickMapAllocateMap(MagickMapCopyString,MagickMapDeallocateString);
+
+ (void) printf("Adding map entries ...\n");
+ for (i=0; KeyVal[i].key; i++)
+ {
+ (void) MagickMapAddEntry(map,KeyVal[i].key,(void *)KeyVal[i].value,0,&exception);
+ }
+
+
+ {
+ char
+ str_index[MaxTextExtent];
+
+ (void) printf("Keyed access ...\n");
+ for (i=0; KeyVal[i].key; i++)
+ {
+ FormatString(str_index,"%u",i);
+ (void) printf("key=\"%s\" value=\"%s\"\n", str_index,
+ (char *)MagickMapAccessEntry(map,str_index,0));
+ }
+ }
+
+ iterator=MagickMapAllocateIterator(map);
+ (void) printf("Iterate forward ...\n");
+ while(MagickMapIterateNext(iterator,&key))
+ (void) printf("key=%s value=%s\n",key,
+ (char *) MagickMapDereferenceIterator(iterator,0));
+
+ (void) printf("Iterate reverse ...\n");
+ while(MagickMapIteratePrevious(iterator,&key))
+ (void) printf("key=%s value=%s\n",key,
+ (char *) MagickMapDereferenceIterator(iterator,0));
+
+ i=2;
+ (void) printf("Remove entry for key \"%s\" and then iterate forward ...\n",
+ KeyVal[i].key);
+ (void) MagickMapRemoveEntry(map,KeyVal[i].key);
+ while(MagickMapIterateNext(iterator,&key))
+ (void) printf("key=%s value=%s\n",key,
+ (char *)MagickMapDereferenceIterator(iterator,0));
+
+ (void) printf("Iterate reverse ...\n");
+ while(MagickMapIteratePrevious(iterator,&key))
+ (void) printf("key=%s value=%s\n",key,
+ (char *)MagickMapDereferenceIterator(iterator,0));
+
+ MagickMapDeallocateIterator(iterator);
+
+ i=2;
+ (void) MagickMapAddEntry(map,KeyVal[i].key,(void *)KeyVal[i].value,0,&exception);
+ (void) printf("Add entry for key \"%s\" and then iterate forward ...\n",
+ KeyVal[i].key);
+
+ iterator=MagickMapAllocateIterator(map);
+ while(MagickMapIterateNext(iterator,&key))
+ (void) printf("key=%s value=%s\n",key,
+ (char *)MagickMapDereferenceIterator(iterator,0));
+
+ MagickMapDeallocateIterator(iterator);
+ MagickMapDeallocateMap(map);
+
+ DestroyExceptionInfo(&exception);
+ return exit_status;
+}
diff --git a/tests/rwblob.c b/tests/rwblob.c
new file mode 100644
index 0000000..9dd30a5
--- /dev/null
+++ b/tests/rwblob.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2003 - 2013 GraphicsMagick Group
+ * Copyright (C) 2003 ImageMagick Studio
+ * Copyright 1991-1999 E. I. du Pont de Nemours and Company
+ *
+ * This program is covered by multiple licenses, which are described in
+ * Copyright.txt. You should have received a copy of Copyright.txt with this
+ * package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+ *
+ * Test BLOB operations via write/read/write/read sequence to detect
+ * any data corruption problems. This does not verify that the image is
+ * correct, only that encode/decode process is repeatable.
+ *
+ * Written by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+ *
+ * The image returned by both reads must be identical in order for the
+ * test to pass.
+ *
+ */
+
+#include <magick/api.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main ( int argc, char **argv )
+{
+ Image
+ *final = (Image *) NULL,
+ *original = (Image *) NULL;
+
+ const MagickInfo
+ *magick_info;
+
+ size_t
+ blob_length = 0;
+
+ char
+ *blob = NULL,
+ infile[MaxTextExtent],
+ format[MaxTextExtent],
+ size[MaxTextExtent];
+
+ int
+ arg = 1,
+ exit_status = 0,
+ rows = 0,
+ columns = 0,
+ pause = 0;
+
+ unsigned long
+ original_frames;
+
+ MagickBool
+ check = MagickTrue,
+ check_for_added_frames = MagickTrue;
+
+ ImageInfo
+ *imageInfo;
+
+ ExceptionInfo
+ exception;
+
+ if (LocaleNCompare("rwblob",argv[0],7) == 0)
+ InitializeMagick((char *) NULL);
+ else
+ InitializeMagick(*argv);
+
+ imageInfo=CloneImageInfo(0);
+ GetExceptionInfo( &exception );
+
+ for (arg=1; arg < argc; arg++)
+ {
+ char
+ *option = argv[arg];
+
+ if (*option == '-')
+ {
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ arg++;
+ option=argv[arg];
+ imageInfo->compression=UndefinedCompression;
+ if (LocaleCompare("None",option) == 0)
+ imageInfo->compression=NoCompression;
+ if (LocaleCompare("BZip",option) == 0)
+ imageInfo->compression=BZipCompression;
+ if (LocaleCompare("Fax",option) == 0)
+ imageInfo->compression=FaxCompression;
+ if (LocaleCompare("Group4",option) == 0)
+ imageInfo->compression=Group4Compression;
+ if (LocaleCompare("JPEG",option) == 0)
+ imageInfo->compression=JPEGCompression;
+ if (LocaleCompare("Lossless",option) == 0)
+ imageInfo->compression=LosslessJPEGCompression;
+ if (LocaleCompare("LZW",option) == 0)
+ imageInfo->compression=LZWCompression;
+ if (LocaleCompare("RLE",option) == 0)
+ imageInfo->compression=RLECompression;
+ if (LocaleCompare("Zip",option) == 0)
+ imageInfo->compression=ZipCompression;
+ }
+ else if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask(argv[++arg]);
+ }
+ else if (LocaleCompare("depth",option+1) == 0)
+ {
+ imageInfo->depth=QuantumDepth;
+ arg++;
+ if ((arg == argc) || !sscanf(argv[arg],"%ld",&imageInfo->depth))
+ {
+ (void) printf("-depth argument missing or not integer\n");
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if(imageInfo->depth != 8 && imageInfo->depth != 16 &&
+ imageInfo->depth != 32)
+ {
+ (void) printf("-depth (%ld) not 8, 16, or 32\n",
+ imageInfo->depth);
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+ else if (LocaleCompare("define",option+1) == 0)
+ {
+ if (arg == argc)
+ {
+ (void) printf("-define argument missing\n");
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if (AddDefinitions(imageInfo,argv[++arg],&exception)
+ == MagickFail)
+ {
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+ else if (LocaleCompare("log",option+1) == 0)
+ {
+ (void) SetLogFormat(argv[++arg]);
+ }
+ else if (LocaleCompare("nocheck",option+1) == 0)
+ {
+ check=MagickFalse;
+ }
+ else if (LocaleCompare("pause",option+1) == 0)
+ {
+ pause=1;
+ }
+ else if (LocaleCompare("quality",option+1) == 0)
+ {
+ imageInfo->quality=atol(argv[++arg]);
+ }
+ else if (LocaleCompare("size",option+1) == 0)
+ {
+ arg++;
+ if ((arg == argc) || !IsGeometry(argv[arg]))
+ {
+ (void) printf("-size argument missing or not geometry\n");
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ (void) CloneString(&imageInfo->size,argv[arg]);
+ }
+ else if (LocaleCompare("verbose",option+1) == 0)
+ {
+ imageInfo->verbose+=1;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (arg != argc-2)
+ {
+ (void) printf("arg=%d, argc=%d\n", arg, argc);
+ (void) printf ( "Usage: %s [-compress algorithm -debug events -depth "
+ "integer -define value -log format -nocheck -quality quality "
+ "-size geometry -verbose] "
+ "infile format\n", argv[0] );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ (void) strncpy(infile, argv[arg], MaxTextExtent-1 );
+ arg++;
+ (void) strncpy( format, argv[arg], MaxTextExtent-1 );
+
+ magick_info=GetMagickInfo(format,&exception);
+ if (magick_info == (MagickInfo *) NULL)
+ {
+ fprintf(stderr, "No support for \"%s\" format.\n",format);
+ exit(1);
+ }
+
+ /*
+ Some formats intentionally modify the number of frames.
+ FAX & JBIG write multiple frames, but read only one frame.
+ */
+ if ((!strcmp( "FAX", format )) ||
+ (!strcmp( "JBIG", format )) ||
+ (!strcmp( "MNG", format )) ||
+ (!strcmp( "PSD", format )) ||
+ (!strcmp( "PTIF", format )) )
+ check_for_added_frames = MagickFalse;
+
+ /*
+ * Read original image
+ */
+ DestroyImageInfo( imageInfo );
+ imageInfo=CloneImageInfo(0);
+ GetExceptionInfo( &exception );
+ imageInfo->dither = 0;
+ (void) strncpy( imageInfo->filename, infile, MaxTextExtent-1 );
+
+ if (!magick_info->adjoin && !check_for_added_frames)
+ (void) strcat( imageInfo->filename, "[0]" );
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading image %s", imageInfo->filename);
+ original = ReadImage ( imageInfo, &exception );
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if ( original == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read original image %s\n",
+ imageInfo->filename );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /*
+ Save first input file number of frames for later verifications.
+ */
+ original_frames=GetImageListLength(original);
+
+ /*
+ * Obtain original image size if format requires it
+ */
+ rows = original->rows;
+ columns = original->columns;
+ size[0]='\0';
+ if (magick_info->raw)
+ FormatString( size, "%dx%d", columns, rows );
+
+ /*
+ * Save image to BLOB
+ */
+ blob_length = 8192;
+ (void) strncpy( original->magick, format, MaxTextExtent-1 );
+ (void) strcpy( imageInfo->filename, "" );
+ original->delay = 10;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing image to BLOB");
+ blob =(char *) ImageToBlob ( imageInfo, original, &blob_length, &exception );
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if ( blob == NULL )
+ {
+ (void) printf ( "Failed to write BLOB in format %s\n",
+ imageInfo->magick );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ imageInfo->depth=original->depth;
+ DestroyImageList( original );
+ original = (Image*)NULL;
+
+ /*
+ * Verify that we can 'ping' the BLOB.
+ */
+ {
+ Image
+ *ping_image;
+
+ MagickBool
+ ping_error = MagickFalse;
+
+ (void) strncpy( imageInfo->magick, format, MaxTextExtent-1 );
+ (void) strcpy( imageInfo->filename, "" );
+ if ( size[0] != '\0' )
+ (void) CloneString( &imageInfo->size, size );
+ ping_image = PingBlob(imageInfo, blob, blob_length, &exception );
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ (void) fflush(stderr);
+ ping_error = MagickTrue;
+ }
+ if ( ping_image == (Image *)NULL )
+ {
+ (void) printf ( "Failed to ping image from BLOB in format %s\n",
+ imageInfo->magick );
+ (void) fflush(stdout);
+ ping_error = MagickTrue;
+ }
+ else
+ {
+ /* Print a short description of the image to stdout */
+ DescribeImage( ping_image, stdout, MagickFalse );
+ (void) fflush(stdout);
+ DestroyImageList( ping_image );
+ }
+ if (ping_error)
+ {
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+
+ /*
+ * Read image back from BLOB
+ */
+ (void) strncpy( imageInfo->magick, format, MaxTextExtent-1 );
+ (void) strcpy( imageInfo->filename, "" );
+ if ( size[0] != '\0' )
+ (void) CloneString( &imageInfo->size, size );
+ original = BlobToImage( imageInfo, blob, blob_length, &exception );
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if ( original == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read image from BLOB in format %s\n",
+ imageInfo->magick );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ MagickFree(blob);
+ blob=0;
+
+ /*
+ * Save image to BLOB
+ */
+ blob_length = 8192;
+ (void) strncpy( original->magick, format, MaxTextExtent-1 );
+ (void) strcpy( imageInfo->filename, "" );
+ original->delay = 10;
+ blob = (char *) ImageToBlob ( imageInfo, original, &blob_length,
+ &exception );
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ imageInfo->depth=original->depth;
+ if ( blob == NULL )
+ {
+ (void) printf ( "Failed to write BLOB in format %s\n",
+ imageInfo->magick );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /*
+ * Read image back from BLOB
+ */
+ (void) strncpy( imageInfo->magick, format, MaxTextExtent-1 );
+ (void) strcpy( imageInfo->filename, "" );
+ if ( size[0] != '\0' )
+ (void) CloneString( &imageInfo->size, size );
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading image from BLOB");
+ final = BlobToImage( imageInfo, blob, blob_length, &exception );
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if ( final == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read image from BLOB in format %s\n",
+ imageInfo->magick );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ MagickFree(blob);
+ blob=0;
+
+ if (check)
+ {
+ /*
+ * Check final output
+ */
+ double
+ fuzz_factor = 0;
+
+ /*
+ Some formats are lossy.
+ */
+ if ((!strcmp( "CIN", format ) && (QuantumDepth == 8)) ||
+ (!strcmp( "CMYK", format )) ||
+ (!strcmp( "GRAY", format )) ||
+ (!strcmp( "JNG", format )) ||
+ (!strcmp( "JP2", format )) ||
+ (!strcmp( "JPEG", format )) ||
+ (!strcmp( "JPG", format )) ||
+ (!strcmp( "JPG24", format )) ||
+ (!strcmp( "PAL", format )) ||
+ (!strcmp( "PCD", format )) ||
+ (!strcmp( "PCDS", format )) ||
+ (!strcmp( "UYVY", format )) ||
+ (!strcmp( "WEBP", format )) ||
+ (!strcmp( "YUV", format )) ||
+ (final->compression == JPEGCompression))
+ fuzz_factor = 0.06;
+
+ {
+ Image
+ *o,
+ *f;
+
+ unsigned long
+ frame=0;
+
+ /*
+ Verify that frame pixels are identical (or close enough).
+ */
+ for (o=original, f=final, frame=0;
+ ((o != (Image *) NULL) && (f != (Image *) NULL)) ;
+ o = o->next, f = f->next, frame++)
+ {
+ printf("Checking frame %ld...\n",frame);
+ if ( !IsImagesEqual(o, f ) &&
+ (original->error.normalized_mean_error > fuzz_factor) )
+ {
+ (void) printf( "R/W file check for format \"%s\" failed "
+ "(frame = %ld): %.6f/%.6f/%.6fe\n",
+ format,frame,
+ original->error.mean_error_per_pixel,
+ original->error.normalized_mean_error,
+ original->error.normalized_maximum_error);
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+
+ if (check_for_added_frames)
+ {
+ /*
+ Verify that reads from BLOB R/W #1 and BLOB R/W #2 did
+ return the same number of frames.
+ */
+ if ((o != (Image *) NULL) && (f != (Image *) NULL))
+ {
+ (void) printf("R/W file check for format \"%s\" failed due to "
+ "differing number of returned frames (%ld vs %ld)\n",
+ format,
+ GetImageListLength(original),
+ GetImageListLength(final));
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /*
+ If format supports multiple frames, then we should expect
+ that frames are not lost (or spuriously added) due to
+ read/write of format.
+ */
+ if (magick_info->adjoin)
+ {
+ unsigned long
+ final_frames;
+
+ final_frames=GetImageListLength(final);
+ if (original_frames != final_frames)
+ {
+ (void) printf("R/W file check for format \"%s\" failed due "
+ "to differing number of returned frames (%ld "
+ "vs %ld) from original file\n",
+ format,original_frames,final_frames);
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+ }
+ }
+ }
+
+ program_exit:
+ if (original)
+ DestroyImageList( original );
+ original = (Image*)NULL;
+ if (final)
+ DestroyImageList( final );
+ final = (Image*)NULL;
+ if (blob)
+ MagickFree(blob);
+ blob=0;
+
+ DestroyExceptionInfo(&exception);
+ DestroyImageInfo( imageInfo );
+ DestroyMagick();
+
+ if (pause)
+ (void) getc(stdin);
+ return exit_status;
+}
diff --git a/tests/rwblob.tap b/tests/rwblob.tap
new file mode 100755
index 0000000..c78429a
--- /dev/null
+++ b/tests/rwblob.tap
@@ -0,0 +1,319 @@
+#!/bin/sh
+# Copyright (C) 2004-2015 GraphicsMagick Group
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+
+# Test program
+rwblob=./rwblob
+
+# Types we will test
+check_types='bilevel gray pallette truecolor'
+
+# Number of tests we plan to run
+test_plan_fn 204
+
+# ART format
+for type in ${check_types}
+do
+ test_command_fn "ART ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" ART
+done
+
+# AVS format
+for type in ${check_types}
+do
+ test_command_fn "AVS ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" AVS
+done
+
+# BMP format
+for type in ${check_types}
+do
+ test_command_fn "BMP ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" BMP
+done
+
+# BMP2 format
+for type in ${check_types}
+do
+ test_command_fn "BMP2 ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" BMP2
+done
+
+# BMP3 format
+for type in ${check_types}
+do
+ test_command_fn "BMP3 ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" BMP3
+done
+
+# CALS format
+for type in ${check_types}
+do
+ test_command_fn "CALS ${type}" -F TIFF ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" CALS
+done
+
+# CIN format
+for type in ${check_types}
+do
+ test_command_fn "CIN ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" CIN
+done
+
+# DIB format
+for type in ${check_types}
+do
+ test_command_fn "DIB ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" DIB
+done
+
+# DPX format
+for type in ${check_types}
+do
+ test_command_fn "DPX ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" DPX
+done
+
+# EPDF format
+for type in ${check_types}
+do
+ test_command_fn "EPDF ${type}" -F 'PS' ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" EPDF
+done
+
+# EPT format
+for type in ${check_types}
+do
+ test_command_fn "EPT ${type}" -F 'PS TIFF' ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" EPT
+done
+
+# FAX format
+for type in ${check_types}
+do
+ test_command_fn "FAX ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" FAX
+done
+
+# FPX format
+for type in ${check_types}
+do
+ test_command_fn "FPX ${type}" -F FPX ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" FPX
+done
+
+# G3 format
+for type in ${check_types}
+do
+ test_command_fn "G3 ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" G3
+done
+
+# FITS format
+for type in ${check_types}
+do
+ test_command_fn "FITS ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" FITS
+done
+
+# GIF format
+for type in ${check_types}
+do
+ test_command_fn "GIF ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" GIF
+done
+
+# GIF87 format
+for type in ${check_types}
+do
+ test_command_fn "GIF87 ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" GIF87
+done
+
+# JBIG format
+for type in ${check_types}
+do
+ test_command_fn "JBIG ${type}" -F JBIG ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" JBIG
+done
+
+# JPEG format
+for type in ${check_types}
+do
+ test_command_fn "JPEG ${type}" -F JPEG ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" JPEG
+done
+
+# JP2 format
+for type in ${check_types}
+do
+ test_command_fn "JP2 ${type}" -F JP2 ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" JP2
+done
+
+# MAT format
+for type in ${check_types}
+do
+ test_command_fn "MAT ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" MAT
+done
+
+# MIFF format
+for type in ${check_types}
+do
+ test_command_fn "MIFF ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" MIFF
+done
+
+# MNG format
+for type in ${check_types}
+do
+ test_command_fn "MNG ${type}" -F PNG ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" MNG
+done
+
+# MTV format
+for type in ${check_types}
+do
+ test_command_fn "MTV ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" MTV
+done
+
+# P7 format
+for type in ${check_types}
+do
+ test_command_fn "P7 ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" P7
+done
+
+# PBM format
+for type in ${check_types}
+do
+ test_command_fn "PBM ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PBM
+done
+
+# PCD format
+for type in ${check_types}
+do
+ test_command_fn "PCD ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PCD
+done
+
+# PCDS format
+for type in ${check_types}
+do
+ test_command_fn "PCDS ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PCDS
+done
+
+# PCX format
+for type in ${check_types}
+do
+ test_command_fn "PCX ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PCX
+done
+
+# PGM format
+for type in ${check_types}
+do
+ test_command_fn "PGM ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PGM
+done
+
+# PGX format
+for type in ${check_types}
+do
+ test_command_fn "PGX ${type}" -F JP2 ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PGX
+done
+
+# PICON format
+for type in ${check_types}
+do
+ test_command_fn "PICON ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PICON
+done
+
+# PICT format
+for type in ${check_types}
+do
+ test_command_fn "PICT ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PICT
+done
+
+# PNG format
+for type in ${check_types}
+do
+ test_command_fn "PNG ${type}" -F PNG ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PNG
+done
+
+# PPM format
+for type in ${check_types}
+do
+ test_command_fn "PPM ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" PPM
+done
+
+# RAS format
+for type in ${check_types}
+do
+ test_command_fn "RAS ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" RAS
+done
+
+# SGI format
+for type in ${check_types}
+do
+ test_command_fn "SGI ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" SGI
+done
+
+# SUN format
+for type in ${check_types}
+do
+ test_command_fn "SUN ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" SUN
+done
+
+# TGA format
+for type in ${check_types}
+do
+ test_command_fn "TGA ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" TGA
+done
+
+# TIFF format
+for type in ${check_types}
+do
+ test_command_fn "TIFF ${type}" -F TIFF ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" TIFF
+done
+
+# TXT format
+for type in ${check_types}
+do
+ test_command_fn "TXT ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" TXT
+done
+
+# VDA format
+for type in ${check_types}
+do
+ test_command_fn "VDA ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" VDA
+done
+
+# VICAR format
+for type in ${check_types}
+do
+ test_command_fn "VICAR ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" VICAR
+done
+
+# VIFF format
+for type in ${check_types}
+do
+ test_command_fn "VIFF ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" VIFF
+done
+
+# VST format
+for type in ${check_types}
+do
+ test_command_fn "VST ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" VST
+done
+
+# WBMP format
+for type in ${check_types}
+do
+ test_command_fn "WBMP ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" WBMP
+done
+
+# WEBP format
+for type in ${check_types}
+do
+ test_command_fn "WEBP ${type}" -F WEBP ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" WEBP
+done
+for type in ${check_types}
+do
+ test_command_fn "WEBP ${type} (lossless)" -F WEBP ${MEMCHECK} ${rwblob} -define webp:lossless=true "${SRCDIR}/input_${type}.miff" WEBP
+done
+
+# XBM format
+for type in ${check_types}
+do
+ test_command_fn "XBM ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" XBM
+done
+
+# XPM format
+for type in ${check_types}
+do
+ test_command_fn "XPM ${type}" ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" XPM
+done
+
+# XWD format
+for type in ${check_types}
+do
+ test_command_fn "XWD ${type}" -F X ${MEMCHECK} ${rwblob} "${SRCDIR}/input_${type}.miff" XWD
+done
+
+:
diff --git a/tests/rwblob_sized.tap b/tests/rwblob_sized.tap
new file mode 100755
index 0000000..14626c3
--- /dev/null
+++ b/tests/rwblob_sized.tap
@@ -0,0 +1,70 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+
+# Test program
+rwblob=./rwblob
+
+# Types we will test
+check_types='truecolor_70x46'
+
+# Number of tests we plan to run
+test_plan_fn 9
+
+# CMYK format
+for type in ${check_types}
+do
+ test_command_fn "CMYK ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" CMYK
+done
+
+# GRAY format
+for type in ${check_types}
+do
+ test_command_fn "GRAY ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" GRAY
+done
+
+# GRAYA format
+for type in ${check_types}
+do
+ test_command_fn "GRAYA ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" GRAYA
+done
+
+# MONO format
+for type in ${check_types}
+do
+ test_command_fn "MONO ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" MONO
+done
+
+# PAL format
+for type in ${check_types}
+do
+ test_command_fn "PAL ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" PAL
+done
+
+# RGB format
+for type in ${check_types}
+do
+ test_command_fn "RGB ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" RGB
+done
+
+# RGBA format
+for type in ${check_types}
+do
+ test_command_fn "RGBA ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" RGBA
+done
+
+# UYVY format
+for type in ${check_types}
+do
+ test_command_fn "UYVY ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" UYVY
+done
+
+# YUV format
+for type in ${check_types}
+do
+ test_command_fn "YUV ${type}" ${MEMCHECK} ${rwblob} -size 70x46 "${SRCDIR}/input_${type}.miff" YUV
+done
+
+:
diff --git a/tests/rwfile.c b/tests/rwfile.c
new file mode 100644
index 0000000..946688e
--- /dev/null
+++ b/tests/rwfile.c
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 2003 - 2013 GraphicsMagick Group
+ * Copyright (C) 2003 ImageMagick Studio
+ * Copyright 1991-1999 E. I. du Pont de Nemours and Company
+ *
+ * This program is covered by multiple licenses, which are described in
+ * Copyright.txt. You should have received a copy of Copyright.txt with this
+ * package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+ *
+ * Test file encode/decode operations via write/read/write/read
+ * sequence to detect any data corruption problems. This does not
+ * verify that the image is correct, only that encode/decode process
+ * is repeatable.
+ *
+ * Written by Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+ *
+ * The image returned by both reads must be identical (or deemed close
+ * enough) in order for the test to pass.
+ * */
+
+#include <magick/api.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main ( int argc, char **argv )
+{
+ Image
+ *final = (Image *) NULL,
+ *original = (Image *) NULL;
+
+ const MagickInfo
+ *magick_info;
+
+ char
+ basefilespec[MaxTextExtent],
+ filename[MaxTextExtent],
+ format[MaxTextExtent],
+ infile[MaxTextExtent],
+ size[MaxTextExtent],
+ filespec[MaxTextExtent];
+
+ int
+ arg = 1,
+ exit_status = 0,
+ pause = 0;
+
+ unsigned long
+ original_frames;
+
+ MagickBool
+ check = MagickTrue,
+ check_for_added_frames = MagickTrue,
+ use_stdio = MagickFalse;
+
+ ImageInfo
+ *imageInfo;
+
+ ExceptionInfo
+ exception;
+
+ (void) memset(basefilespec,0,sizeof(basefilespec));
+ (void) memset(filename,0,sizeof(filename));
+ (void) memset(format,0,sizeof(format));
+ (void) memset(infile,0,sizeof(infile));
+ (void) memset(size,0,sizeof(size));
+ (void) memset(filespec,0,sizeof(filespec));
+
+ if (LocaleNCompare("rwfile",argv[0],7) == 0)
+ InitializeMagick((char *) NULL);
+ else
+ InitializeMagick(*argv);
+
+ imageInfo=CloneImageInfo(0);
+ GetExceptionInfo( &exception );
+
+ (void) strcpy(basefilespec,"out_%d");
+
+ for (arg=1; arg < argc; arg++)
+ {
+ char
+ *option = argv[arg];
+
+ if (*option == '-')
+ {
+ if (LocaleCompare("compress",option+1) == 0)
+ {
+ arg++;
+ option=argv[arg];
+ imageInfo->compression=UndefinedCompression;
+ if (LocaleCompare("Undefined",option) == 0)
+ imageInfo->compression=UndefinedCompression;
+ if (LocaleCompare("None",option) == 0)
+ imageInfo->compression=NoCompression;
+ if (LocaleCompare("BZip",option) == 0)
+ imageInfo->compression=BZipCompression;
+ if (LocaleCompare("Fax",option) == 0)
+ imageInfo->compression=FaxCompression;
+ if (LocaleCompare("Group4",option) == 0)
+ imageInfo->compression=Group4Compression;
+ if (LocaleCompare("JPEG",option) == 0)
+ imageInfo->compression=JPEGCompression;
+ if (LocaleCompare("Lossless",option) == 0)
+ imageInfo->compression=LosslessJPEGCompression;
+ if (LocaleCompare("LZW",option) == 0)
+ imageInfo->compression=LZWCompression;
+ if (LocaleCompare("RLE",option) == 0)
+ imageInfo->compression=RLECompression;
+ if (LocaleCompare("Zip",option) == 0)
+ imageInfo->compression=ZipCompression;
+ }
+ else if (LocaleCompare("debug",option+1) == 0)
+ {
+ (void) SetLogEventMask(argv[++arg]);
+ }
+ else if (LocaleCompare("define",option+1) == 0)
+ {
+ if (arg == argc)
+ {
+ (void) printf("-define argument missing\n");
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if (AddDefinitions(imageInfo,argv[++arg],&exception)
+ == MagickFail)
+ {
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+ else if (LocaleCompare("depth",option+1) == 0)
+ {
+ imageInfo->depth=QuantumDepth;
+ arg++;
+ if ((arg == argc) || !sscanf(argv[arg],"%ld",&imageInfo->depth))
+ {
+ (void) printf("-depth argument missing or not integer\n");
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if(imageInfo->depth != 8 && imageInfo->depth != 16 &&
+ imageInfo->depth != 32)
+ {
+ (void) printf("-depth (%ld) not 8, 16, or 32\n",
+ imageInfo->depth);
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+ else if (LocaleCompare("filespec",option+1) == 0)
+ {
+ (void) strcpy(basefilespec,argv[++arg]);
+ }
+ else if (LocaleCompare("log",option+1) == 0)
+ {
+ (void) SetLogFormat(argv[++arg]);
+ }
+ else if (LocaleCompare("nocheck",option+1) == 0)
+ {
+ check=MagickFalse;
+ }
+ else if (LocaleCompare("pause",option+1) == 0)
+ {
+ pause=1;
+ }
+ else if (LocaleCompare("quality",option+1) == 0)
+ {
+ imageInfo->quality=atol(argv[++arg]);
+ }
+ else if (LocaleCompare("size",option+1) == 0)
+ {
+ arg++;
+ if ((arg == argc) || !IsGeometry(argv[arg]))
+ {
+ (void) printf("-size argument missing or not geometry\n");
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ (void) CloneString(&imageInfo->size,argv[arg]);
+ }
+ else if (LocaleCompare("stdio",option+1) == 0)
+ {
+ use_stdio=MagickTrue;
+ }
+ else if (LocaleCompare("verbose",option+1) == 0)
+ {
+ imageInfo->verbose+=1;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (arg != argc-2)
+ {
+ (void) printf("arg=%d, argc=%d\n", arg, argc);
+ (void) printf ( "Usage: %s [-compress algorithm] [-debug events]"
+ " [-depth integer] [-define value] [-filespec spec]"
+ " [-log format] [-nocheck] [-quality quality]"
+ " [-size geometry] -stdio -verbose]"
+ " infile format\n", argv[0] );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ (void) strncpy(infile, argv[arg], MaxTextExtent-1 );
+ arg++;
+ (void) strncpy( format, argv[arg], MaxTextExtent-1 );
+
+ magick_info=GetMagickInfo(format,&exception);
+ if (magick_info == (MagickInfo *) NULL)
+ {
+ fprintf(stderr, "No support for \"%s\" format.\n",format);
+ exit(1);
+ }
+
+ /*
+ Some formats intentionally modify the number of frames.
+ FAX & JBIG write multiple frames, but read only one frame.
+ */
+ if ((!strcmp( "FAX", format )) ||
+ (!strcmp( "JBIG", format )) ||
+ (!strcmp( "MNG", format )) ||
+ (!strcmp( "PSD", format )) ||
+ (!strcmp( "PTIF", format )) )
+ check_for_added_frames = MagickFalse;
+
+ /*
+ * Read original image
+ */
+
+ imageInfo->dither = 0;
+
+ strcpy(imageInfo->filename,"");
+ if (use_stdio)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading stdio image %s", infile);
+ imageInfo->file=fopen(infile,"rb");
+ }
+ else
+ {
+ (void) strncpy( imageInfo->filename, infile, MaxTextExtent-1 );
+ if (!magick_info->adjoin || !check_for_added_frames)
+ (void) strcat( imageInfo->filename, "[0]" );
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading image %s", imageInfo->filename);
+ }
+ original = ReadImage ( imageInfo, &exception );
+ if (use_stdio)
+ {
+ (void) fclose(imageInfo->file);
+ imageInfo->file = (FILE *) NULL;
+ }
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if ( original == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read original image %s\n",
+ imageInfo->filename );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /*
+ Save first input file number of frames for later verifications.
+ */
+ original_frames=GetImageListLength(original);
+
+ /*
+ Get file format information.
+ */
+ size[0] = '\0';
+ magick_info=GetMagickInfo(format,&exception);
+
+ if (magick_info->raw)
+ {
+ /*
+ * Specify original image size if format requires it
+ */
+ FormatString( size, "%lux%lu", original->columns, original->rows );
+ }
+ if (IgnoreExtensionTreatment == magick_info->extension_treatment)
+ {
+ /*
+ Prepend magic specifier if extension will be ignored.
+ */
+ (void) strcpy(filespec,format);
+ (void) strcat(filespec,":");
+ (void) strcat(filespec,basefilespec);
+ }
+ else
+ {
+ strcpy(filespec,basefilespec);
+ }
+
+ (void) strcat(filespec,".%s");
+ (void) sprintf( filename, filespec, 1, format );
+ (void) remove(filename);
+
+ /*
+ * Save image to file
+ */
+ (void) strncpy( original->magick, format, MaxTextExtent-1 );
+ (void) fflush(stdout);
+
+ strcpy(imageInfo->filename,"");
+ if (use_stdio)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing stdio image %s", filename);
+ imageInfo->file=fopen(filename,"wb+");
+ }
+ else
+ {
+ (void) strncpy( original->filename, filename, MaxTextExtent-1 );
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing image %s", original->filename);
+ }
+ original->delay = 10;
+ if (!WriteImage ( imageInfo, original ))
+ {
+ CatchException(&original->exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if (use_stdio)
+ {
+ (void) fclose(imageInfo->file);
+ imageInfo->file = (FILE *) NULL;
+ }
+ imageInfo->depth=original->depth;
+ DestroyImageList( original );
+ original = (Image*)NULL;
+
+ /*
+ * Verify that we can 'ping' the file
+ */
+ {
+ Image
+ *ping_image;
+
+ MagickBool
+ ping_error = MagickFalse;
+
+ strcpy(imageInfo->filename,"");
+ (void) strncpy( imageInfo->magick, format, MaxTextExtent-1 );
+ if (use_stdio)
+ {
+ imageInfo->file=fopen(filename,"rb");
+ }
+ else
+ {
+ strncpy( imageInfo->filename, filename, MaxTextExtent-1 );
+ }
+ if ( size[0] != '\0' )
+ (void) CloneString( &imageInfo->size, size );
+ (void) fflush(stdout);
+ ping_image = PingImage(imageInfo, &exception );
+ if (use_stdio)
+ {
+ (void) fclose(imageInfo->file);
+ imageInfo->file = (FILE *) NULL;
+ }
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ (void) fflush(stderr);
+ ping_error = MagickTrue;
+ }
+ if ( ping_image == (Image *)NULL )
+ {
+ (void) printf ( "Failed to ping image from file \"%s\" in format %s\n",
+ filename, imageInfo->magick );
+ (void) fflush(stdout);
+ ping_error = MagickTrue;
+ }
+ else
+ {
+ /* Print a short description of the image to stdout */
+ DescribeImage( ping_image, stdout, MagickFalse );
+ DestroyImageList( ping_image );
+ }
+ if (ping_error)
+ {
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+
+ /*
+ * Read image back from file
+ */
+ (void) strncpy( imageInfo->magick, format, MaxTextExtent-1 );
+ strcpy(imageInfo->filename,"");
+ if (use_stdio)
+ {
+ imageInfo->file=fopen(filename,"rb");
+ }
+ else
+ {
+ strncpy( imageInfo->filename, filename, MaxTextExtent-1 );
+ }
+ if ( size[0] != '\0' )
+ (void) CloneString( &imageInfo->size, size );
+ (void) fflush(stdout);
+ original = ReadImage ( imageInfo, &exception );
+ if (use_stdio)
+ {
+ (void) fclose(imageInfo->file);
+ imageInfo->file = (FILE *) NULL;
+ }
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if ( original == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read image from file in format %s\n",
+ imageInfo->magick );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /*
+ * Save image to file
+ */
+ (void) sprintf( filename, basefilespec, 2, format );
+ (void) remove(filename);
+
+ (void) sprintf( filename, filespec, 2, format );
+ (void) strncpy( original->magick, format, MaxTextExtent-1 );
+ strcpy(imageInfo->filename,"");
+ if (use_stdio)
+ {
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing stdio image %s", filename);
+ imageInfo->file=fopen(filename,"wb+");
+ }
+ else
+ {
+ (void) strncpy( original->filename, filename, MaxTextExtent-1 );
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Writing stdio image %s", original->filename);
+ }
+ original->delay = 10;
+ (void) fflush(stdout);
+ if(!WriteImage (imageInfo,original))
+ {
+ CatchException(&original->exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if (use_stdio)
+ {
+ (void) fclose(imageInfo->file);
+ imageInfo->file = (FILE *) NULL;
+ }
+
+ /*
+ * Read image back from file
+ */
+ (void) strncpy( imageInfo->magick, format, MaxTextExtent-1 );
+ strcpy(imageInfo->filename,"");
+ if (use_stdio)
+ {
+ imageInfo->file=fopen(filename,"rb");
+ }
+ else
+ {
+ (void) strncpy( imageInfo->filename, filename, MaxTextExtent-1 );
+ }
+ if ( size[0] != '\0' )
+ (void) CloneString( &imageInfo->size, size );
+ (void) fflush(stdout);
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Reading image %s", imageInfo->filename);
+ final = ReadImage ( imageInfo, &exception );
+ if (exception.severity != UndefinedException)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+ if ( final == (Image *)NULL )
+ {
+ (void) printf ( "Failed to read image from file in format %s\n",
+ imageInfo->magick );
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ if (check)
+ {
+ /*
+ * Check final output
+ */
+ double
+ fuzz_factor = 0;
+
+ /*
+ Some formats are lossy.
+ */
+ if ((!strcmp( "CIN", format ) && (QuantumDepth == 8)) ||
+ (!strcmp( "CMYK", format )) ||
+ (!strcmp( "GRAY", format )) ||
+ (!strcmp( "JNG", format )) ||
+ (!strcmp( "JP2", format )) ||
+ (!strcmp( "JPEG", format )) ||
+ (!strcmp( "JPG", format )) ||
+ (!strcmp( "JPG24", format )) ||
+ (!strcmp( "PAL", format )) ||
+ (!strcmp( "PCD", format )) ||
+ (!strcmp( "PCDS", format )) ||
+ (!strcmp( "UYVY", format )) ||
+ (!strcmp( "WEBP", format )) ||
+ (!strcmp( "YUV", format )) ||
+ (final->compression == JPEGCompression))
+ fuzz_factor = 0.06;
+
+ {
+ Image
+ *o,
+ *f;
+
+ unsigned long
+ frame=0;
+
+ /*
+ Verify that frame pixels are identical (or close enough).
+ */
+ for (o=original, f=final, frame=0;
+ ((o != (Image *) NULL) && (f != (Image *) NULL)) ;
+ o = o->next, f = f->next, frame++)
+ {
+ printf("Checking frame %ld...\n",frame);
+ if ( !IsImagesEqual(o, f ) &&
+ (original->error.normalized_mean_error > fuzz_factor) )
+ {
+ (void) printf( "R/W file check for format \"%s\" failed "
+ "(frame = %ld): %.6f/%.6f/%.6fe\n",
+ format,frame,
+ original->error.mean_error_per_pixel,
+ original->error.normalized_mean_error,
+ original->error.normalized_maximum_error);
+ (void) fflush(stdout);
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+
+ if (check_for_added_frames)
+ {
+ /*
+ Verify that reads from file R/W #1 and file R/W #2 did
+ return the same number of frames.
+ */
+ if ((o != (Image *) NULL) && (f != (Image *) NULL))
+ {
+ (void) printf("R/W file check for format \"%s\" failed due to "
+ "differing number of returned frames (%ld vs %ld)\n",
+ format,
+ GetImageListLength(original),
+ GetImageListLength(final));
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ /*
+ If format supports multiple frames, then we should expect
+ that frames are not lost (or spuriously added) due to
+ read/write of format.
+ */
+ if (magick_info->adjoin)
+ {
+ unsigned long
+ final_frames;
+
+ final_frames=GetImageListLength(final);
+ if (original_frames != final_frames)
+ {
+ (void) printf("R/W file check for format \"%s\" failed due "
+ "to differing number of returned frames (%ld "
+ "vs %ld) from original file\n",
+ format,original_frames,final_frames);
+ exit_status = 1;
+ goto program_exit;
+ }
+ }
+ }
+ }
+ }
+
+ program_exit:
+ if (original)
+ DestroyImageList( original );
+ original = (Image*)NULL;
+ if (final)
+ DestroyImageList( final );
+ final = (Image*)NULL;
+ if (imageInfo->file != (FILE *) NULL)
+ {
+ (void) fclose(imageInfo->file);
+ imageInfo->file = (FILE *) NULL;
+ }
+
+ DestroyExceptionInfo(&exception);
+ DestroyImageInfo( imageInfo );
+ DestroyMagick();
+
+ if (pause)
+ (void) getc(stdin);
+ return exit_status;
+}
diff --git a/tests/rwfile.tap b/tests/rwfile.tap
new file mode 100755
index 0000000..f86c3a0
--- /dev/null
+++ b/tests/rwfile.tap
@@ -0,0 +1,482 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2015 GraphicsMagick Group
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+
+# Test program
+rwfile=./rwfile
+
+# Types we will test
+check_types='bilevel gray pallette truecolor'
+
+# Number of tests we plan to run
+test_plan_fn 564
+
+# ART format
+for type in ${check_types}
+do
+ test_command_fn "ART ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" ART
+ test_command_fn "ART ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" ART
+done
+
+# AVS format
+for type in ${check_types}
+do
+ test_command_fn "AVS ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" AVS
+ test_command_fn "AVS ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" AVS
+done
+
+# BMP format
+for type in ${check_types}
+do
+ test_command_fn "BMP ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" BMP
+ test_command_fn "BMP ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" BMP
+done
+
+# BMP2 format
+for type in ${check_types}
+do
+ test_command_fn "BMP2 ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" BMP2
+ test_command_fn "BMP2 ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" BMP2
+done
+
+# BMP3 format
+for type in ${check_types}
+do
+ test_command_fn "BMP3 ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" BMP3
+ test_command_fn "BMP3 ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" BMP3
+done
+
+# CALS format
+for type in ${check_types}
+do
+ test_command_fn "CALS ${type}" -F TIFF ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" CALS
+ #test_command_fn "CALS ${type} (stdio)" -F TIFF ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" CALS
+done
+
+# CIN format
+for type in ${check_types}
+do
+ test_command_fn "CIN ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" CIN
+ test_command_fn "CIN ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" CIN
+done
+
+# DCX format
+for type in ${check_types}
+do
+ test_command_fn "DCX ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" DCX
+ test_command_fn "DCX ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" DCX
+done
+
+# DIB format
+for type in ${check_types}
+do
+ test_command_fn "DIB ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" DIB
+ test_command_fn "DIB ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" DIB
+done
+
+# DPX format
+for type in ${check_types}
+do
+ test_command_fn "DPX ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" DPX
+ test_command_fn "DPX ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" DPX
+done
+
+# EPDF format
+for type in ${check_types}
+do
+ test_command_fn "EPDF ${type}" -F 'PS' ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" EPDF
+ #test_command_fn "EPDF ${type} (stdio)" -F 'PS' ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" EPDF
+done
+
+# EPSF format
+for type in ${check_types}
+do
+ test_command_fn "EPSF ${type}" -F 'PS' ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" EPSF
+ #test_command_fn "EPSF ${type} (stdio)" -F 'PS' ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" EPSF
+done
+
+# EPSI format
+for type in ${check_types}
+do
+ test_command_fn "EPSI ${type}" -F 'PS' ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" EPSI
+ #test_command_fn "EPSI ${type} (stdio)" -F 'PS' ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" EPSI
+done
+
+# EPI format
+for type in ${check_types}
+do
+ test_command_fn "EPI ${type}" -F 'PS' ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" EPI
+ #test_command_fn "EPI ${type} (stdio)" -F 'PS' ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" EPI
+done
+
+# EPS format
+for type in ${check_types}
+do
+ test_command_fn "EPS ${type}" -F 'PS' ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" EPS
+ #test_command_fn "EPS ${type} (stdio)" -F 'PS' ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" EPS
+done
+
+# EPT format
+for type in ${check_types}
+do
+ test_command_fn "EPT ${type}" -F 'PS TIFF' ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" EPT
+ #test_command_fn "EPT ${type} (stdio)" -F 'PS TIFF' ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" EPT
+done
+
+# FAX format
+for type in ${check_types}
+do
+ test_command_fn "FAX ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" FAX
+ test_command_fn "FAX ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" FAX
+done
+
+# FITS format
+for type in ${check_types}
+do
+ test_command_fn "FITS ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" FITS
+ test_command_fn "FITS ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" FITS
+done
+
+# FPX format
+for type in ${check_types}
+do
+ test_command_fn "FPX ${type}" -F FPX ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" FPX
+ #test_command_fn "FPX ${type} (stdio)" -F FPX ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" FPX
+done
+
+# GIF format
+for type in ${check_types}
+do
+ test_command_fn "GIF ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" GIF
+ test_command_fn "GIF ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" GIF
+done
+
+# GRAY format
+for type in ${check_types}
+do
+ test_command_fn "GRAY ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" GRAY
+ test_command_fn "GRAY ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" GRAY
+done
+
+# ICB format
+for type in ${check_types}
+do
+ test_command_fn "ICB ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" ICB
+ test_command_fn "ICB ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" ICB
+done
+
+# JBIG format
+for type in ${check_types}
+do
+ test_command_fn "JBIG ${type}" -F JBIG ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" JBIG
+ test_command_fn "JBIG ${type} (stdio)" -F JBIG ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" JBIG
+done
+
+# JPEG format
+for type in ${check_types}
+do
+ test_command_fn "JPEG ${type}" -F JPEG ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" JPEG
+ test_command_fn "JPEG ${type} (stdio)" -F JPEG ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" JPEG
+done
+
+# JP2 format
+for type in ${check_types}
+do
+ test_command_fn "JP2 ${type}" -F JP2 ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" JP2
+ test_command_fn "JP2 ${type} (stdio)" -F JP2 ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" JP2
+done
+
+# MAT format
+for type in ${check_types}
+do
+ test_command_fn "MAT ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" MAT
+ test_command_fn "MAT ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" MAT
+done
+
+# MIFF format
+for type in ${check_types}
+do
+ test_command_fn "MIFF ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" MIFF
+ test_command_fn "MIFF ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" MIFF
+done
+
+# MNG format
+for type in ${check_types}
+do
+ test_command_fn "MNG ${type}" -F PNG ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" MNG
+ test_command_fn "MNG ${type} (stdio)" -F PNG ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" MNG
+done
+
+# MPR (Magick Persistent Registry). There is no such format but file names are required.
+for type in ${check_types}
+do
+ test_command_fn "MPR ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" MPR
+done
+
+# MTV format
+for type in ${check_types}
+do
+ test_command_fn "MTV ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" MTV
+ test_command_fn "MTV ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" MTV
+done
+
+# P7 format
+for type in ${check_types}
+do
+ test_command_fn "P7 ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" P7
+ test_command_fn "P7 ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" P7
+done
+
+# PAM format
+for type in ${check_types}
+do
+ for depth in 8 16 32
+ do
+ test_command_fn "PAM ${type} (depth ${depth})" ${MEMCHECK} ${rwfile} -filespec "out_${type}_${depth}_%d" "${SRCDIR}/input_${type}.miff" PAM
+ test_command_fn "PAM ${type} (stdio, depth ${depth})" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_${depth}_stdio_%d" "${SRCDIR}/input_${type}.miff" PAM
+ done
+done
+
+# PBM format
+for type in ${check_types}
+do
+ test_command_fn "PBM ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PBM
+ test_command_fn "PBM ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PBM
+ test_command_fn "PBM ASCII ${type}" ${MEMCHECK} ${rwfile} -compress None -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PBM
+ test_command_fn "PBM ASCII ${type} (stdio)" ${MEMCHECK} ${rwfile} -compress None -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PBM
+done
+
+# PCD format
+for type in ${check_types}
+do
+ test_command_fn "PCD ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PCD
+ test_command_fn "PCD ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PCD
+done
+
+# PCDS format
+for type in ${check_types}
+do
+ test_command_fn "PCDS ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PCDS
+ test_command_fn "PCDS ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PCDS
+done
+
+# PCX format
+for type in ${check_types}
+do
+ test_command_fn "PCX ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PCX
+ test_command_fn "PCX ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PCX
+done
+
+# PDF format
+for type in ${check_types}
+do
+ test_command_fn "PDF ${type}" -F PS ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PDF
+ #test_command_fn "PDF ${type} (stdio)" -F PS ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PDF
+done
+
+# PGM format
+for type in ${check_types}
+do
+ for depth in 8 16 32
+ do
+ test_command_fn "PGM ${type} (depth ${depth})" ${MEMCHECK} ${rwfile} -depth ${depth} -filespec "out_${type}_${depth}_%d" "${SRCDIR}/input_${type}.miff" PGM
+ test_command_fn "PGM ${type} (stdio, depth ${depth})" ${MEMCHECK} ${rwfile} -depth ${depth} -stdio -filespec "out_${type}_${depth}_stdio_%d" "${SRCDIR}/input_${type}.miff" PGM
+ test_command_fn "PGM ASCII ${type} (depth ${depth})" ${MEMCHECK} ${rwfile} -depth ${depth} -quality 0 -filespec "out_${type}_${depth}_%d" "${SRCDIR}/input_${type}.miff" PGM
+ test_command_fn "PGM ASCII ${type} (stdio, depth ${depth})" ${MEMCHECK} ${rwfile} -depth ${depth} -quality 0 -stdio -filespec "out_${type}_${depth}_stdio_%d" "${SRCDIR}/input_${type}.miff" PGM
+ done
+done
+
+# PGX format
+for type in ${check_types}
+do
+ test_command_fn "PGX ${type}" -F JP2 ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PGX
+ test_command_fn "PGX ${type} (stdio)" -F JP2 ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PGX
+done
+
+# PICON format
+for type in ${check_types}
+do
+ test_command_fn "PICON ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PICON
+ test_command_fn "PICON ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PICON
+done
+
+# PICT format
+for type in ${check_types}
+do
+ test_command_fn "PICT ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PICT
+ test_command_fn "PICT ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PICT
+done
+
+# PNG format
+for type in ${check_types}
+do
+ test_command_fn "PNG ${type}" -F PNG ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PNG
+ test_command_fn "PNG ${type} (stdio)" -F PNG ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PNG
+done
+
+# PNM format
+for type in ${check_types}
+do
+ test_command_fn "PNM ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PNM
+ test_command_fn "PNM ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PNM
+done
+
+# PPM format
+for type in ${check_types}
+do
+ for depth in 8 16 32
+ do
+ test_command_fn "PPM ${type} (depth ${depth})" ${MEMCHECK} ${rwfile} -filespec "out_${type}_${depth}_%d" "${SRCDIR}/input_${type}.miff" PPM
+ test_command_fn "PPM ${type} (stdio, depth ${depth})" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_${depth}_stdio_%d" "${SRCDIR}/input_${type}.miff" PPM
+ test_command_fn "PPM ASCII ${type} (depth ${depth})" ${MEMCHECK} ${rwfile} -quality 0 -filespec "out_${type}_${depth}_%d" "${SRCDIR}/input_${type}.miff" PPM
+ test_command_fn "PPM ASCII ${type} (stdio, depth ${depth})" ${MEMCHECK} ${rwfile} -quality 0 -stdio -filespec "out_${type}_${depth}_stdio_%d" "${SRCDIR}/input_${type}.miff" PPM
+ done
+done
+
+# PS format
+for type in ${check_types}
+do
+ test_command_fn "PS ${type}" -F PS ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PS
+ #test_command_fn "PS ${type} (stdio)" -F PS ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PS
+done
+
+# PS2 format
+for type in ${check_types}
+do
+ test_command_fn "PS2 ${type}" -F PS ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PS2
+ #test_command_fn "PS2 ${type} (stdio)" -F PS ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PS2
+done
+
+# PS3 format
+for type in ${check_types}
+do
+ test_command_fn "PS3 ${type}" -F PS ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PS3
+ #test_command_fn "PS3 ${type} (stdio)" -F PS ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PS3
+done
+
+# PSD format
+for type in ${check_types}
+do
+ test_command_fn "PSD ${type}" -F PSD ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PSD
+ #test_command_fn "PSD ${type} (stdio)" -F PSD ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PSD
+done
+
+# PTIF format
+for type in ${check_types}
+do
+ test_command_fn "PTIF ${type}" -F TIFF ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" PTIF
+ test_command_fn "PTIF ${type} (stdio)" -F TIFF ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" PTIF
+done
+
+# RAS format
+for type in ${check_types}
+do
+ test_command_fn "RAS ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" RAS
+ test_command_fn "RAS ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" RAS
+done
+
+# SGI format
+for type in ${check_types}
+do
+ test_command_fn "SGI ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" SGI
+ test_command_fn "SGI ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" SGI
+done
+
+# SUN format
+for type in ${check_types}
+do
+ test_command_fn "SUN ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" SUN
+ test_command_fn "SUN ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" SUN
+done
+
+# TGA format
+for type in ${check_types}
+do
+ test_command_fn "TGA ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" TGA
+ test_command_fn "TGA ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" TGA
+done
+
+# TXT format
+for type in ${check_types}
+do
+ test_command_fn "TXT ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" TXT
+ test_command_fn "TXT ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" TXT
+done
+
+# TIFF format
+for type in ${check_types}
+do
+ test_command_fn "TIFF ${type}" -F TIFF ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" TIFF
+ test_command_fn "TIFF ${type} (stdio)" -F TIFF ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" TIFF
+done
+
+# VDA format
+for type in ${check_types}
+do
+ test_command_fn "VDA ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" VDA
+ test_command_fn "VDA ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" VDA
+done
+
+# VICAR format
+for type in ${check_types}
+do
+ test_command_fn "VICAR ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" VICAR
+ test_command_fn "VICAR ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" VICAR
+done
+
+# VIFF format
+for type in ${check_types}
+do
+ test_command_fn "VIFF ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" VIFF
+ test_command_fn "VIFF ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" VIFF
+done
+
+# VST format
+for type in ${check_types}
+do
+ test_command_fn "VST ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" VST
+ test_command_fn "VST ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" VST
+done
+
+# WBMP format
+for type in ${check_types}
+do
+ test_command_fn "WBMP ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" WBMP
+ test_command_fn "WBMP ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" WBMP
+done
+
+# WEBP format
+for type in ${check_types}
+do
+ test_command_fn "WEBP ${type}" -F WEBP ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" WEBP
+ test_command_fn "WEBP ${type} (stdio)" -F WEBP ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" WEBP
+done
+for type in ${check_types}
+do
+ test_command_fn "WEBP ${type} (lossless)" -F WEBP ${MEMCHECK} ${rwfile} -filespec "out_${type}_lossless_%d" -define webp:lossless=true "${SRCDIR}/input_${type}.miff" WEBP
+done
+
+# XBM format
+for type in ${check_types}
+do
+ test_command_fn "XBM ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" XBM
+ test_command_fn "XBM ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" XBM
+done
+
+# XPM format
+for type in ${check_types}
+do
+ test_command_fn "XPM ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" XPM
+ test_command_fn "XPM ${type} (stdio)" ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" XPM
+done
+
+# XWD format
+for type in ${check_types}
+do
+ test_command_fn "XWD ${type}" -F X ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.miff" XWD
+ test_command_fn "XWD ${type} (stdio)" -F X ${MEMCHECK} ${rwfile} -stdio -filespec "out_${type}_stdio_%d" "${SRCDIR}/input_${type}.miff" XWD
+done
+
+:
diff --git a/tests/rwfile_deep.tap b/tests/rwfile_deep.tap
new file mode 100755
index 0000000..f186e9a
--- /dev/null
+++ b/tests/rwfile_deep.tap
@@ -0,0 +1,100 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+
+# Test program
+rwfile=./rwfile
+
+# Types we will test
+check_types='truecolor10 truecolor12 truecolor16'
+
+# Number of tests we plan to run
+test_plan_fn 42
+
+# CIN format
+for type in ${check_types}
+do
+ test_command_fn "CIN ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" CIN
+done
+
+# DPX format
+for type in ${check_types}
+do
+ test_command_fn "DPX ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" DPX
+done
+
+# FITS format
+for type in ${check_types}
+do
+ test_command_fn "FITS ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" FITS
+done
+
+# JP2 format
+for type in ${check_types}
+do
+ test_command_fn "JP2 ${type}" -F JP2 ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" JP2
+done
+
+# MAT format
+for type in ${check_types}
+do
+ test_command_fn "MAT ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" MAT
+done
+
+# MIFF format
+for type in ${check_types}
+do
+ test_command_fn "MIFF ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" MIFF
+done
+
+# MNG format
+for type in ${check_types}
+do
+ test_command_fn "MNG ${type}" -F PNG ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" MNG
+done
+
+# PNG format
+for type in ${check_types}
+do
+ test_command_fn "PNG ${type}" -F PNG ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" PNG
+done
+
+# PPM format
+for type in ${check_types}
+do
+ test_command_fn "PPM ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" PPM
+done
+
+# PTIF format
+for type in ${check_types}
+do
+ test_command_fn "PTIF ${type}" -F TIFF ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" PTIF
+done
+
+# SGI format
+for type in ${check_types}
+do
+ test_command_fn "SGI ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" SGI
+done
+
+# TIFF format
+for type in ${check_types}
+do
+ test_command_fn "TIFF ${type}" -F TIFF ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" TIFF
+done
+
+# TGA format
+for type in ${check_types}
+do
+ test_command_fn "TGA ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" TGA
+done
+
+# TXT format
+for type in ${check_types}
+do
+ test_command_fn "TXT ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" "${SRCDIR}/input_${type}.dpx" TXT
+done
+
+:
diff --git a/tests/rwfile_miff.tap b/tests/rwfile_miff.tap
new file mode 100755
index 0000000..0e0d4cc
--- /dev/null
+++ b/tests/rwfile_miff.tap
@@ -0,0 +1,33 @@
+#!/bin/sh
+# Copyright (C) 2004-2013 GraphicsMagick Group
+# Test MIFF format with various storage and compression types
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+
+# Test program
+rwfile=./rwfile
+
+# Storage types we will test
+check_types='bilevel gray pallette truecolor'
+
+# Comression types we will test
+compress_types='none bzip zip rle'
+
+# Depths we will test
+depths='8 16 32'
+
+# Number of tests we plan to run
+test_plan_fn 48
+
+for compress in ${compress_types}
+do
+ for type in ${check_types}
+ do
+ for depth in ${depths}
+ do
+ test_command_fn "MIFF ${compress} ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_${compress}_%d" -compress ${compress} -depth ${depth} "${SRCDIR}/input_${type}.miff" MIFF
+ done
+ done
+done
+
+:
diff --git a/tests/rwfile_pdf.tap b/tests/rwfile_pdf.tap
new file mode 100755
index 0000000..37becd8
--- /dev/null
+++ b/tests/rwfile_pdf.tap
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test PDF format with various storage and compression types
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+
+# Test program
+rwfile=./rwfile
+
+# Storage types we will test
+check_types='bilevel gray pallette truecolor'
+
+# Comression types we will test
+compress_types='none fax jpeg lzw rle zip'
+
+# Number of tests we plan to run
+test_plan_fn 24
+
+for compress in ${compress_types}
+do
+ for type in ${check_types}
+ do
+ test_command_fn "PDF ${type} ${compress}" -F PS ${MEMCHECK} ${rwfile} -filespec "out_${type}_${compress}_%d" -compress $compress "${SRCDIR}/input_${type}.miff" PDF
+ done
+done
+
+:
diff --git a/tests/rwfile_sized.tap b/tests/rwfile_sized.tap
new file mode 100755
index 0000000..fe64d40
--- /dev/null
+++ b/tests/rwfile_sized.tap
@@ -0,0 +1,111 @@
+#!/bin/sh
+# Copyright (C) 2004-2012 GraphicsMagick Group
+. ./common.shi
+. ${top_srcdir}/tests/common.shi
+
+# Test program
+rwfile=./rwfile
+
+# Types we will test
+check_types='truecolor_70x46'
+
+# Number of tests we plan to run
+test_plan_fn 16
+
+# CMYK format
+for type in ${check_types}
+do
+ test_command_fn "CMYK ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" CMYK
+done
+
+# GRAY format
+for type in ${check_types}
+do
+ test_command_fn "GRAY ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" GRAY
+done
+
+# GRAYA format
+for type in ${check_types}
+do
+ test_command_fn "GRAYA ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" GRAYA
+done
+
+# R format
+for type in ${check_types}
+do
+ test_command_fn "R (red) ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" R
+done
+
+# G format
+for type in ${check_types}
+do
+ test_command_fn "G (green) ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" G
+done
+
+# B format
+for type in ${check_types}
+do
+ test_command_fn "B (blue) ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" B
+done
+
+# C format
+for type in ${check_types}
+do
+ test_command_fn "C (cyan) ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" C
+done
+
+# M format
+for type in ${check_types}
+do
+ test_command_fn "M (magenta) ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" M
+done
+
+# Y format
+for type in ${check_types}
+do
+ test_command_fn "Y (yellow) ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" Y
+done
+
+# K format
+for type in ${check_types}
+do
+ test_command_fn "K (black) ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" K
+done
+
+# MONO format
+for type in ${check_types}
+do
+ test_command_fn "MONO ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" MONO
+done
+
+# PAL format
+for type in ${check_types}
+do
+ test_command_fn "PAL ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" PAL
+done
+
+# RGB format
+for type in ${check_types}
+do
+ test_command_fn "RGB ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" RGB
+done
+
+# RGBA format
+for type in ${check_types}
+do
+ test_command_fn "RGBA ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" RGBA
+done
+
+# UYVY format
+for type in ${check_types}
+do
+ test_command_fn "UYVY ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" UYVY
+done
+
+# YUV format
+for type in ${check_types}
+do
+ test_command_fn "YUV ${type}" ${MEMCHECK} ${rwfile} -filespec "out_${type}_%d" -size 70x46 "${SRCDIR}/input_${type}.miff" YUV
+done
+
+:
diff --git a/utilities/Makefile.am b/utilities/Makefile.am
new file mode 100644
index 0000000..8b6178c
--- /dev/null
+++ b/utilities/Makefile.am
@@ -0,0 +1,81 @@
+# Copyright (C) 2004-2012 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building GraphicsMagick utilities
+#
+#
+
+UTILITIES_PGMS = \
+ utilities/gm
+
+utilities_gm_LDADD = $(LIBMAGICK)
+utilities_gm_LDFLAGS = $(LDFLAGS)
+utilities_gm_SOURCES = utilities/gm.c
+
+
+UTILITIES_XFAIL_TESTS =
+
+# Tests to run
+UTILITIES_TESTS = \
+ utilities/tests/effects.tap \
+ utilities/tests/pipe.tap \
+ utilities/tests/hald-clut.tap \
+ utilities/tests/help.tap \
+ utilities/tests/icc-transform.tap \
+ utilities/tests/identify.tap \
+ utilities/tests/list.tap \
+ utilities/tests/montage.tap \
+ utilities/tests/msl_composite.tap \
+ utilities/tests/preview.tap
+
+utilities/tests/montage.log : \
+ utilities/tests/effects.tap
+
+UTILITIES_MANS = \
+ utilities/gm.1 \
+ utilities/miff.4 \
+ utilities/quantize.5
+
+UTILITIES_EXTRA_DIST = \
+ $(UTILITIES_MANS) \
+ $(UTILITIES_TESTS) \
+ utilities/tests/BetaRGB.icc \
+ utilities/tests/common.sh \
+ utilities/tests/sunrise.jpg \
+ utilities/tests/sunrise.miff
+
+UTILITIES_CLEANFILES = \
+ utilities/tests/*_out.miff \
+ utilities/tests/*_out.pnm \
+ utilities/tests/*_out.txt \
+ utilities/tests/demo*.miff \
+ utilities/tests/gm.core \
+ utilities/tests/core
+
+# Install/Uninstall ImageMagick compatibility links
+if MAGICK_COMPAT
+MAGICKPROGRAMS=animate compare composite conjure convert display identify import mogrify montage
+UTILITIES_INSTALL_EXEC_LOCAL_TARGETS=install-exec-local-utilities
+install-exec-local-utilities:
+ $(mkdir_p) $(DESTDIR)$(bindir)
+ cd $(DESTDIR)$(bindir) ; \
+ gm=`echo "gm" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ for name in $(MAGICKPROGRAMS) ; \
+ do \
+ target=`echo "$$name" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ rm -f $$target ; \
+ $(LN_S) $$gm $$target ; \
+ done
+
+UTILITIES_UNINSTALL_LOCAL_TARGETS=uninstall-local-utilities
+uninstall-local-utilities:
+ cd $(DESTDIR)$(bindir) ; \
+ for name in $(MAGICKPROGRAMS) ; \
+ do \
+ target=`echo "$$name" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ rm -f $$target ; \
+ done
+endif # MAGICK_COMPAT
diff --git a/utilities/gm.1 b/utilities/gm.1
new file mode 100644
index 0000000..889c3a1
--- /dev/null
+++ b/utilities/gm.1
@@ -0,0 +1,10474 @@
+.TH gm 1 "2017/01/29" "GraphicsMagick"
+.TP
+.in 15
+.in 15
+.in 20
+.SH NAME
+
+gm - command-line utility to create, edit, compare, convert, or display images
+
+.SH SYNOPSIS
+
+\fBgm animate\fP \fB[\fP \fIoptions ...\fP \fB]\fP \fIfile\fP \fB[ [\fP
+\fIoptions ...\fP \fB]\fP \fIfile ...\fP \fB]\fP
+
+\fBgm batch\fP \fB[\fP \fIoptions ...\fP \fB]\fP \fB[\fP \fIscript\fP \fB]\fP
+
+\fBgm benchmark\fP \fB[\fP \fIoptions ...\fP \fB]\fP subcommand
+
+\fBgm compare\fP \fB[\fP \fIoptions\fP \fB... ]\fP \fIreference-image\fP
+\fB[\fP \fIoptions\fP \fB... ]\fP \fIcompare-image\fP
+\fB[\fP \fIoptions\fP \fB... ]\fP
+
+\fBgm composite\fP \fB[\fP \fIoptions ...\fP \fB]\fP \fIchange-image base-image\fP
+\fB[\fP \fImask-image\fP \fB]\fP \fIoutput-image\fP
+
+\fBgm conjure\fP \fB[\fP \fIoptions\fP \fB]\fP \fIscript.msl\fP
+\fB[ [\fP \fIoptions\fP \fB]\fP \fIscript.msl\fP \fB]\fP
+
+\fBgm convert\fP \fB[ [\fP \fIoptions ...\fP \fB] [\fP \fIinput-file ...\fP
+\fB] [\fP \fIoptions ...\fP \fB] ]\fP \fIoutput-file\fP
+
+\fBgm display\fP \fB[\fP \fIoptions ...\fP \fB]\fP \fIfile ...\fP
+\fB[ [\fP\fIoptions ...\fP \fB]\fP\fIfile ...\fP \fB]\fP
+
+\fBgm identify\fP \fIfile\fP \fB[\fP \fIfile ...\fP \fB]\fP
+
+\fBgm import\fP \fB[\fP \fIoptions ...\fP \fB]\fP \fIfile\fP
+
+\fBgm mogrify\fP \fB[\fP \fIoptions ...\fP \fB]\fP \fIfile ...\fP
+
+\fBgm montage\fP \fB[\fP \fIoptions ...\fP \fB]\fP \fIfile\fP \fB[ [\fP
+\fIoptions ...\fP \fB]\fP \fIfile ...\fP \fB]\fP \fIoutput-file\fP
+
+\fBgm time\fP subcommand
+
+\fBgm version\fP
+.SH DESCRIPTION
+ GraphicsMagick's \fBgm\fP provides a suite of utilities for
+creating, comparing, converting, editing, and displaying images. All
+of the utilities are provided as sub-commands of a single \fBgm\fP
+executable:
+
+\fBanimate\fP
+displays an animation (e.g. a GIF file) on any workstation display
+running an \fIX\fP server.
+
+\fBbatch\fP
+executes an arbitary number of the utility commands
+(e.g. \fBconvert\fP) in the form of a simple linear batch script in
+order to improve execution efficiency, and/or to allow use as a
+subordinate co-process under the control of an arbitrary script or
+program.
+
+\fBbenchmark\fP
+executes one of the other utility commands (e.g. \fBconvert\fP) for a
+specified number of iterations, or execution time, and reports
+execution time and other profiling information such as CPU
+utilization. \fBBenchmark\fP provides various operating modes
+including executing the command with a varying number of threads, and
+alternate reporting formats such as comma-separated value (CSV).
+
+\fBcompare\fP
+compares two images and reports difference statistics according to
+specified metrics and/or outputs an image with a visual representation
+of the differences. It may also be used to test if images are similar
+within a particular range and specified metric, returning a truth
+value to the executing environment.
+
+\fBcomposite\fP
+composites images (blends or merges images together) to create new images.
+
+\fBconjure\fP
+interprets and executes scripts in
+the Magick Scripting Language (MSL).
+
+\fBconvert\fP
+converts an input file using one image format to an output file with
+the same or differing image format while applying an arbitrary number
+of image transformations.
+
+\fBdisplay\fP
+is a machine architecture independent image processing and display
+facility. It can display an image on any workstation display running
+an \fIX\fP server.
+
+\fBidentify\fP
+describes the format and characteristics of one or more image
+files. It will also report if an image is incomplete or corrupt.
+
+\fBimport\fP
+reads an image from any visible window on an \fIX\fP server and
+outputs it as an image file. You can capture a single window, the
+entire screen, or any rectangular portion of the screen.
+
+\fBmogrify\fP
+transforms an image or a sequence of images. These transforms include
+\fBimage scaling\fP, \fBimage rotation\fP, \fBcolor reduction\fP,
+and others. The transmogrified image \fBoverwrites\fP the original
+image.
+
+\fBmontage\fP
+creates a composite by combining several separate images. The images
+are tiled on the composite image with the name of the image optionally
+appearing just below the individual tile.
+
+\fBtime\fP
+executes a subcommand and reports the user, system, and total
+execution time consumed.
+
+\fBversion\fP
+reports the GraphicsMagick release version, maximum sample-depth,
+copyright notice, supported features, and the options used while
+building the software.
+
+The \fBGraphicsMagick\fP utilities recognize the following image formats:
+
+
+\fBName\fP \fBMode\fP \fBDescription\fP
+ o 3FR r-- Hasselblad Photo RAW
+ o 8BIM rw- Photoshop resource format
+ o 8BIMTEXT rw- Photoshop resource text format
+ o 8BIMWTEXT rw- Photoshop resource wide text format
+ o APP1 rw- Raw application information
+ o APP1JPEG rw- Raw JPEG binary data
+ o ART r-- PF1: 1st Publisher
+ o ARW r-- Sony Alpha DSLR RAW
+ o AVS rw+ AVS X image
+ o BIE rw- Joint Bi-level Image experts Group
+ interchange format
+ o BMP rw+ Microsoft Windows bitmap image
+ o BMP2 -w- Microsoft Windows bitmap image v2
+ o BMP3 -w- Microsoft Windows bitmap image v3
+ o CACHE --- Magick Persistent Cache image format
+ o CALS rw- Continuous Acquisition and Life-cycle
+ Support Type 1 image
+ o CAPTION r-- Caption (requires separate size info)
+ o CIN rw- Kodak Cineon Format
+ o CMYK rw- Raw cyan, magenta, yellow, and black
+ samples (8 or 16 bits, depending on
+ the image depth)
+ o CMYKA rw- Raw cyan, magenta, yellow, black, and
+ matte samples (8 or 16 bits, depending
+ on the image depth)
+ o CR2 r-- Canon Photo RAW
+ o CRW r-- Canon Photo RAW
+ o CUR r-- Microsoft Cursor Icon
+ o CUT r-- DR Halo
+ o DCM r-- Digital Imaging and Communications in
+ Medicine image
+ o DCR r-- Kodak Photo RAW
+ o DCX rw+ ZSoft IBM PC multi-page Paintbrush
+ o DNG r-- Adobe Digital Negative
+ o DPS r-- Display PostScript Interpreter
+ o DPX rw- Digital Moving Picture Exchange
+ o EPDF rw- Encapsulated Portable Document Format
+ o EPI rw- Adobe Encapsulated PostScript
+ Interchange format
+ o EPS rw- Adobe Encapsulated PostScript
+ o EPS2 -w- Adobe Level II Encapsulated PostScript
+ o EPS3 -w- Adobe Level III Encapsulated PostScript
+ o EPSF rw- Adobe Encapsulated PostScript
+ o EPSI rw- Adobe Encapsulated PostScript
+ Interchange format
+ o EPT rw- Adobe Encapsulated PostScript with MS-DOS
+ TIFF preview
+ o EPT2 rw- Adobe Level II Encapsulated PostScript
+ with MS-DOS TIFF preview
+ o EPT3 rw- Adobe Level III Encapsulated PostScript
+ with MS-DOS TIFF preview
+ o EXIF rw- Exif digital camera binary data
+ o FAX rw+ Group 3 FAX (Not TIFF Group3 FAX!)
+ o FITS rw- Flexible Image Transport System
+ o FRACTAL r-- Plasma fractal image
+ o FPX rw- FlashPix Format
+ o GIF rw+ CompuServe graphics interchange format
+ o GIF87 rw- CompuServe graphics interchange format
+ (version 87a)
+ o GRADIENT r-- Gradual passing from one shade to
+ another
+ o GRAY rw+ Raw gray samples (8/16/32 bits,
+ depending on the image depth)
+ o HISTOGRAM -w- Histogram of the image
+ o HRZ r-- HRZ: Slow scan TV
+ o HTML -w- Hypertext Markup Language and a
+ client-side image map
+ o ICB rw+ Truevision Targa image
+ o ICC rw- ICC Color Profile
+ o ICM rw- ICC Color Profile
+ o ICO r-- Microsoft icon
+ o ICON r-- Microsoft icon
+ o IDENTITY r-- Hald CLUT identity image
+ o IMAGE r-- GraphicsMagick Embedded Image
+ o INFO -w+ Image descriptive information and
+ statistics
+ o IPTC rw- IPTC Newsphoto
+ o IPTCTEXT rw- IPTC Newsphoto text format
+ o IPTCWTEXT rw- IPTC Newsphoto wide text format
+ o JBG rw+ Joint Bi-level Image experts Group
+ interchange format
+ o JBIG rw+ Joint Bi-level Image experts Group
+ interchange format
+ o JNG rw- JPEG Network Graphics
+ o JP2 rw- JPEG-2000 JP2 File Format Syntax
+ o JPC rw- JPEG-2000 Code Stream Syntax
+ o JPEG rw- Joint Photographic Experts Group
+ JFIF format
+ o JPG rw- Joint Photographic Experts Group
+ JFIF format
+ o K25 r-- Kodak Photo RAW
+ o KDC r-- Kodak Photo RAW
+ o LABEL r-- Text image format
+ o M2V rw+ MPEG-2 Video Stream
+ o MAP rw- Colormap intensities and indices
+ o MAT r-- MATLAB image format
+ o MATTE -w+ MATTE format
+ o MIFF rw+ Magick Image File Format
+ o MNG rw+ Multiple-image Network Graphics
+ o MONO rw- Bi-level bitmap in least-significant-
+ -byte-first order
+ o MPC rw+ Magick Persistent Cache image format
+ o MPEG rw+ MPEG-1 Video Stream
+ o MPG rw+ MPEG-1 Video Stream
+ o MRW r-- Minolta Photo Raw
+ o MSL r-- Magick Scripting Language
+ o MTV rw+ MTV Raytracing image format
+ o MVG rw- Magick Vector Graphics
+ o NEF r-- Nikon Electronic Format
+ o NULL r-- Constant image of uniform color
+ o OTB rw- On-the-air bitmap
+ o P7 rw+ Xv thumbnail format
+ o PAL rw- 16bit/pixel interleaved YUV
+ o PALM rw- Palm Pixmap
+ o PBM rw+ Portable bitmap format (black and white)
+ o PCD rw- Photo CD
+ o PCDS rw- Photo CD
+ o PCL -w- Page Control Language
+ o PCT rw- Apple Macintosh QuickDraw/PICT
+ o PCX rw- ZSoft IBM PC Paintbrush
+ o PDB rw+ Palm Database ImageViewer Format
+ o PDF rw+ Portable Document Format
+ o PEF r-- Pentax Electronic File
+ o PFA r-- TrueType font
+ o PFB r-- TrueType font
+ o PGM rw+ Portable graymap format (gray scale)
+ o PGX r-- JPEG-2000 VM Format
+ o PICON rw- Personal Icon
+ o PICT rw- Apple Macintosh QuickDraw/PICT
+ o PIX r-- Alias/Wavefront RLE image format
+ o PLASMA r-- Plasma fractal image
+ o PNG rw- Portable Network Graphics
+ o PNG24 rw- Portable Network Graphics, 24 bit RGB
+ opaque only
+ o PNG32 rw- Portable Network Graphics, 32 bit RGBA
+ semitransparency OK
+ o PNG8 rw- Portable Network Graphics, 8-bit
+ indexed, binary transparency only
+ o PNM rw+ Portable anymap
+ o PPM rw+ Portable pixmap format (color)
+ o PREVIEW -w- Show a preview an image enhancement,
+ effect, or f/x
+ o PS rw+ Adobe PostScript
+ o PS2 -w+ Adobe Level II PostScript
+ o PS3 -w+ Adobe Level III PostScript
+ o PSD rw- Adobe Photoshop bitmap
+ o PTIF rw- Pyramid encoded TIFF
+ o PWP r-- Seattle Film Works
+ o RAF r-- Fuji Photo RAW
+ o RAS rw+ SUN Rasterfile
+ o RGB rw+ Raw red, green, and blue samples
+ o RGBA rw+ Raw red, green, blue, and matte samples
+ o RLA r-- Alias/Wavefront image
+ o RLE r-- Utah Run length encoded image
+ o SCT r-- Scitex HandShake
+ o SFW r-- Seattle Film Works
+ o SGI rw+ Irix RGB image
+ o SHTML -w- Hypertext Markup Language and a
+ client-side image map
+ o STEGANO r-- Steganographic image
+ o SUN rw+ SUN Rasterfile
+ o SVG rw+ Scalable Vector Gaphics
+ o TEXT rw+ Raw text
+ o TGA rw+ Truevision Targa image
+ o TIFF rw+ Tagged Image File Format
+ o TILE r-- Tile image with a texture
+ o TIM r-- PSX TIM
+ o TOPOL r-- TOPOL X Image
+ o TTF r-- TrueType font
+ o TXT rw+ Raw text
+ o UIL -w- X-Motif UIL table
+ o UYVY rw- 16bit/pixel interleaved YUV
+ o VDA rw+ Truevision Targa image
+ o VICAR rw- VICAR rasterfile format
+ o VID rw+ Visual Image Directory
+ o VIFF rw+ Khoros Visualization image
+ o VST rw+ Truevision Targa image
+ o WBMP rw- Wireless Bitmap (level 0) image
+ o WMF r-- Windows Metafile
+ o WPG r-- Word Perfect Graphics
+ o X rw- X Image
+ o X3F r-- Foveon X3 (Sigma/Polaroid) RAW
+ o XBM rw- X Windows system bitmap (black
+ and white)
+ o XC r-- Constant image uniform color
+ o XCF r-- GIMP image
+ o XMP rw- Adobe XML metadata
+ o XPM rw- X Windows system pixmap (color)
+ o XV rw+ Khoros Visualization image
+ o XWD rw- X Windows system window dump (color)
+ o YUV rw- CCIR 601 4:1:1 or 4:2:2 (8-bit only)
+
+ Modes:
+ r Read
+ w Write
+ + Multi-image
+
+
+\fISupport for some of these formats require additional programs or libraries.
+See README
+in the source package for where to find optional additional software\fP.
+
+Note, a format delineated with + means that if more than one
+image is specified, frames are combined into a single multi-image
+file. Use \fB+adjoin\fP if you want a single image produced for each
+frame.
+
+Your installation might not support all of the formats in the list.
+To get an accurate listing of the formats supported by your particular
+configuration, run "gm convert -list format".
+
+Raw images are expected to have one byte per pixel unless \fBgm\fP is
+compiled in 16-bit quantum mode or in 32-bit quantum mode. Here, the
+raw data is expected to be stored two or four bytes per pixel,
+respectively, in most-significant-byte-first order. For example, you
+can tell if \fBgm\fP was compiled in 16-bit mode by typing "gm
+version" without any options, and looking for "Q:16" in the first line
+of output.
+.SH FILES AND FORMATS
+
+By default, the image format is determined by its magic number, i.e., the
+first few bytes of the file. To specify
+a particular image format, precede the filename with an image format name
+and a colon (\fIi.e.\fP\fBps:image\fP) or specify the image type as the
+filename suffix (\fIi.e.\fP\fBimage.ps\fP).
+The magic number takes precedence over the filename suffix
+and the prefix takes precedence over the magic number and the suffix
+in input files.
+When a file is read, its magic number is stored in the "image->magick"
+string.
+In output files, the prefix takes precedence over the filename suffix,
+and the filename suffix takes precedence over the
+"image->magick" string.
+
+To read the "built-in" formats (GRANITE, H, LOGO,
+NETSCAPE, PLASMA, and ROSE) use a prefix (including the colon) without a
+filename or suffix. To read the XC format, follow the colon with a color
+specification. To read the CAPTION format, follow the colon with a text
+string or with a filename prefixed with the at symbol (\fB@\fP).
+
+
+When you specify \fBX\fP as your image type, the filename has special
+meaning. It specifies an X window by \fBid, name\fP, or
+\fBroot\fP. If
+no filename is specified, the window is selected by clicking the mouse
+in the desired window.
+
+Specify \fIinput_file\fP as \fB-\fP for standard input,
+\fIoutput_file\fP as \fB-\fP for standard output.
+If \fIinput_file\fP has the extension \fB.Z\fP or \fB.gz\fP, the
+file is uncompressed with \fBuncompress\fP or \fBgunzip\fP
+respectively.
+If \fIoutput_file\fP has the extension \fB.Z\fP or \fB.gz\fP,
+the file is compressed using with \fIcompress\fP or \fIgzip\fP respectively.
+
+Use an optional index enclosed in brackets after an input file name to
+specify a desired subimage of a multi-resolution image format like
+Photo CD (e.g. "img0001.pcd[4]") or a range for MPEG images
+(e.g. "video.mpg[50-75]"). A subimage specification can be
+disjoint (e.g. "image.tiff[2,7,4]"). For raw images, specify
+a subimage with a geometry (e.g. -size 640x512
+"image.rgb[320x256+50+50]"). Surround the image name with
+quotation marks to prevent your shell from interpreting the square
+brackets. Single images are written with the filename you
+specify. However, multi-part images (e.g., a multi-page PostScript
+document with \fB+adjoin\fP specified) may be written with the scene
+number included as part of the filename. In order to include the scene
+number in the filename, it is necessary to include a printf-style
+%d format specification in the file name and use the +adjoin
+option. For example,
+
+ image%02d.miff
+
+
+writes files \fIimage00.miff, image01.miff,\fP etc. Only a single
+specification is allowed within an output filename. If more than one
+specification is present, it will be ignored. It is best to embed the
+scene number in the base part of the file name, not in the extension,
+because the extension will not be a recognizeable image type.
+
+When running a commandline utility, you can
+prepend an at sign @ to a filename to read a list of image
+filenames from that file. This is convenient in the event you have too
+many image filenames to fit on the command line.
+.SH OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or \fB-noop\fP.
+Some options only affect the decoding of images and others only the encoding.
+The latter can appear after the final group of input images.
+
+This is a combined list of the command-line options used by the
+GraphicsMagick utilities (\fIanimate\fP, \fIcompare\fP,
+\fIcomposite\fP, \fIconvert\fP, \fIdisplay\fP, \fIidentify\fP,
+\fIimport\fP, \fImogrify\fP and \fImontage\fP).
+
+
+In this document, angle brackets ("<>") enclose variables and curly
+brackets ("{}") enclose optional parameters. For example,
+"\fB-fuzz <distance>{%}\fP" means you can use the
+option "-fuzz 10"
+or "-fuzz 2%".
+
+.TP
+.B "-adjoin"
+\fRjoin images into a single multi-image file
+
+By default, all images of an image sequence are stored in the same
+file. However, some formats (e.g. JPEG) do not support storing more
+than one image per file and only the first frame in an image sequence
+will be saved unless the result is saved to separate files. Use
+\fB+adjoin\fP to force saving multiple frames to multiple numbered
+files. If \fB+adjoin\fP is used, then the output filename must
+include a printf style formatting specification for the numeric part
+of the filename. For example,
+
+ image%02d.miff
+
+.TP
+.B "-affine \fI<matrix>"\fP
+\fRdrawing transform matrix
+
+This option provides a transform matrix {sx,rx,ry,sy,tx,ty} for
+use by subsequent \fB-draw\fP or \fB-transform\fP options.
+.TP
+.B "-antialias"
+\fRremove pixel aliasing
+
+By default antialiasing algorithms are used when drawing objects (e.g. lines)
+or rendering vector formats (e.g. WMF and Postscript). Use +antialias to
+disable use of antialiasing algorithms. Reasons to disable antialiasing
+include avoiding increasing colors in the image, or improving rendering speed.
+.TP
+.B "-append"
+\fRappend a set of images
+
+This option creates a single image where the images in the original set
+are stacked top-to-bottom. If they are not of the same width,
+any narrow images will be expanded to fit using the background color.
+Use \fB+append\fP to stack images left-to-right. The set of images
+is terminated by the appearance of any option.
+If the \fB-append\fP
+option appears after all of the input images, all images are appended.
+.TP
+.B " \fI-asc-cdl <spec>"\fP
+\fRapply ASC CDL color transform
+
+Applies ("bakes in") the ASC CDL, which is a format for the exchange
+of basic primary color grading information between equipment and
+software from different manufacturers. The format defines the math for
+three functions: slope, offset and power. Each function uses a number
+for the red, green, and blue color channels for a total of nine
+numbers comprising a single color decision. The tenth number
+(optional) is for chromiance (saturation) as specified by ASC CDL
+1.2.
+
+The argument string is comma delimited and is in the following form
+(but without invervening spaces or line breaks)
+
+ redslope,redoffset,redpower:
+ greenslope,greenoffset,greenpower:
+ blueslope,blueoffset,bluepower:
+ saturation
+
+
+with the unity (no change) specification being:
+
+ "1.0,0.0,1.0:1.0,0.0,1.0:1.0,0.0,1.0:1.0"
+
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+
+Use this option to supply a password for decrypting an image or an
+image sequence, if it is being read from a format such as PDF that supports
+encryption. Encrypting images being written is not supported.
+.TP
+.B "-auto-orient"
+\fRorient (rotate) image so it is upright
+
+Adjusts the image orienation so that it is suitable for viewing. Uses
+the orientation tag obtained from the image file or as supplied by the
+\fB-orient\fP option.
+.TP
+.B "-average"
+\fRaverage a set of images
+
+The set of images
+is terminated by the appearance of any option.
+If the \fB-average\fP
+option appears after all of the input images, all images are averaged.
+.TP
+.B "-backdrop"
+\fRdisplay the image centered on a backdrop.
+
+This backdrop covers the entire workstation screen and is useful for hiding
+other X window activity while viewing the image. The color of the backdrop
+is specified as the foreground color (X11 default is black).
+Refer to
+"X Resources", below,
+for details.
+.TP
+.B "-background \fI<color>"\fP
+\fRthe background color
+
+The color is specified using the format described under the \fB-fill\fP
+option.
+.TP
+.B "-black-threshold \fIred[,green][,blue][,opacity]"\fP
+\fRpixels below the threshold become black
+
+Use \fB-black-threshold\fP to set pixels with values below the specified
+threshold to minimum value (black). If only one value is supplied, or the
+red, green, and blue values are identical, then intensity thresholding is
+used. If the color threshold values are not identical then channel-based
+thresholding is used, and color distortion will occur. Specify a negative
+value (e.g. -1) if you want a channel to be ignored but you do want to
+threshold a channel later in the list. If a percent (%) symbol is
+appended, then the values are treated as a percentage of maximum
+range.
+.TP
+.B "-blue-primary \fI<x>,<y>"\fP
+\fRblue chromaticity primary point
+.TP
+.B "-blur \fI<radius>{x<sigma>}"\fP
+\fRblur the image with a Gaussian operator
+
+Blur with the given radius and
+standard deviation (sigma).
+.TP
+.B "-border \fI<width>x<height>"\fP
+\fRsurround the image with a border of color
+
+See \fB-geometry\fP for details
+about the geometry specification.
+.TP
+.B "-bordercolor \fI<color>"\fP
+\fRthe border color
+
+The color is specified using the format described under the \fB-fill\fP
+option.
+.TP
+.B "-borderwidth \fI<geometry>"\fP
+\fRthe border width
+.TP
+.B "-box \fI<color>"\fP
+\fRset the color of the annotation bounding box
+
+The color is specified using the format described under the \fB-fill\fP
+option.
+
+See \fB-draw\fP for further
+details.
+.TP
+.B "-channel \fI<type>"\fP
+\fRthe type of channel
+
+Choose from: \fBRed\fP, \fBGreen\fP, \fBBlue\fP, \fBOpacity\fP,
+\fBMatte\fP, \fBCyan\fP, \fBMagenta\fP, \fBYellow\fP, \fBBlack\fP,
+or \fBGray\fP.
+
+Use this option to extract a particular \fIchannel\fP from the image.
+\fBOpacity\fP,
+for example, is useful for extracting the opacity values from an image.
+.TP
+.B "-charcoal \fI<factor>"\fP
+\fRsimulate a charcoal drawing
+.TP
+.B "-chop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRremove pixels from the interior of an image
+
+\fIWidth\fP and \fIheight\fP give the number of columns and rows to remove,
+and \fIx\fP and \fIy\fP are offsets that give the location of the
+leftmost column and topmost row to remove.
+
+The \fIx\fP offset normally specifies the leftmost column to remove.
+If the \fB-gravity\fP option is present with \fINorthEast, East,\fP
+or \fISouthEast\fP
+gravity, it gives the distance leftward from the right edge
+of the image to the rightmost column to remove. Similarly, the \fIy\fP offset
+normally specifies the topmost row to remove, but if
+the \fB-gravity\fP option is present with \fISouthWest, South,\fP
+or \fISouthEast\fP
+gravity, it specifies the distance upward from the bottom edge of the
+image to the bottom row to remove.
+
+The \fB-chop\fP option removes entire rows and columns,
+and moves the remaining corner blocks leftward and upward to close the gaps.
+.TP
+.B "-clip"
+\fRapply the clipping path, if one is present
+
+If a clipping path is present, it will be applied to subsequent operations.
+
+For example, if you type the following command:
+
+ gm convert -clip -negate cockatoo.tif negated.tif
+
+
+only the pixels within the clipping path are negated.
+
+The \fB-clip\fP feature requires the XML library. If the XML library
+is not present, the option is ignored.
+.TP
+.B "-coalesce"
+\fRmerge a sequence of images
+
+Each image N in the sequence after Image 0 is replaced with the image
+created by flattening images 0 through N.
+
+The set of images
+is terminated by the appearance of any option.
+If the \fB-coalesce\fP
+option appears after all of the input images, all images are coalesced.
+.TP
+.B "-colorize \fI<value>"\fP
+\fRcolorize the image with the pen color
+
+Specify the amount of colorization as a percentage. You can apply separate
+colorization values to the red, green, and blue channels of the image with
+a colorization value list delimited with slashes (e.g. 0/0/50).
+
+The \fB-colorize\fP option may be used in conjunction with \fB-modulate\fP
+to produce a nice sepia toned image like:
+
+ gm convert input.ppm -modulate 115,0,100 \\
+ -colorize 7,21,50 output.ppm.
+
+.TP
+.B "-colormap \fI<type>"\fP
+\fRdefine the colormap type
+
+Choose between \fBshared\fP or \fBprivate\fP.
+
+This option only applies when the default X server visual is \fIPseudoColor\fP
+or \fIGRAYScale\fP. Refer to \fB-visual\fP for more details. By default,
+a shared colormap is allocated. The image shares colors with other X clients.
+Some image colors could be approximated, therefore your image may look
+very different than intended. Choose \fBPrivate\fP and the image colors
+appear exactly as they are defined. However, other clients may
+go \fItechnicolor\fP when the image colormap is installed.
+.TP
+.B "-colors \fI<value>"\fP
+\fRpreferred number of colors in the image
+
+The actual number of colors in the image may be less than your request,
+but never more. Note, this is a color reduction option. Images with less
+unique colors than specified with this option will have any duplicate or
+unused colors removed. The ordering of an existing color palette may be
+altered. When converting an image from color to grayscale, convert the
+image to the gray colorspace before reducing the number of colors since
+doing so is most efficient. Refer to <a
+href="quantize.html">quantize for more details.
+
+Note, options \fB-dither\fP, \fB-colorspace\fP, and \fB-treedepth\fP
+affect the color reduction algorithm.
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+
+Choices are:
+\fBCineonLog\fP, \fBCMYK\fP, \fBGRAY\fP, \fBHSL\fP, \fBHWB\fP,
+\fBOHTA\fP, \fBRGB\fP, \fBRec601Luma\fP, \fBRec709Luma\fP,
+\fBRec601YCbCr\fP, \fBRec709YCbCr\fP, \fBTransparent\fP, \fBXYZ\fP,
+\fBYCbCr\fP, \fBYIQ\fP, \fBYPbPr\fP, or \fBYUV\fP.
+
+Color reduction, by default, takes place in the RGB color space. Empirical
+evidence suggests that distances in color spaces such as YUV or YIQ correspond
+to perceptual color differences more closely than do distances in RGB space.
+These color spaces may give better results when color reducing an image.
+Refer to quantize for more details.
+Two gray colorspaces are supported. The \fBRec601Luma\fP space is
+based on the recommendations for legacy NTSC television (ITU-R
+BT.601-5). The \fBRec709Luma\fP space is based on the
+recommendations for HDTV (Rec. ITU-R BT.709-5) and is suitable for use
+with computer graphics, and for contemporary CRT displays. The
+\fBGRAY\fP colorspace currently selects the \fBRec601Luma\fP
+colorspace by default for backwards compatibly reasons. This default
+may be re-considered in the future.
+
+Two YCbCr colorspaces are supported. The \fBRec601YCbCr\fP space is
+based on the recommendations for legacy NTSC television (ITU-R BT.601-5). The
+\fBRec709CbCr\fP space is based on the recommendations for HDTV (Rec.
+ITU-R BT.709-5) and is suitable for suitable for use with computer
+graphics, and for contemporary CRT displays. The \fBYCbCr\fP colorspace
+specification is equivalent to\fBRec601YCbCr\fP.
+
+
+The \fBTransparent\fP color space behaves uniquely in that it preserves
+the matte channel of the image if it exists.
+
+The \fB-colors\fP or \fB-monochrome\fP option, or saving to a file
+format which requires color reduction, is required for this option to
+take effect.
+.TP
+.B "-comment \fI<string>"\fP
+\fRannotate an image with a comment
+
+Use this option to assign a specific comment to the image, when writing
+to an image format that supports comments. You can include the
+image filename, type, width, height, or other image attribute by embedding
+special format characters listed under the \fB-format\fP option.
+The comment is not drawn on the image, but is embedded in the image
+datastream via a "Comment" tag or similar mechanism. If you want the
+comment to be visible on the image itself, use the \fB-draw\fP option
+instead.
+
+For example,
+
+ -comment "%m:%f %wx%h"
+
+
+produces an image comment of \fBMIFF:bird.miff 512x480\fP for an image
+titled \fBbird.miff\fP and whose width is 512 and height is 480.
+
+If the first character of \fIstring\fP is \fI@\fP, the image comment
+is read from a file titled by the remaining characters in the string.
+
+If the -comment option appears multiple times, only the last comment is
+stored.
+
+In PNG images, the comment is stored in a \fBtEXt\fP or \fBzTXt\fP chunk
+with the keyword "comment".
+.TP
+.B "-compose \fI<operator>"\fP
+\fRthe type of image composition
+
+The description of composition uses abstract terminology in order to
+allow the the description to be more clear, while avoiding constant
+values which are specific to a particular build configuration. Each image
+pixel is represented by red, green, and blue levels (which are equal for
+a gray pixel). MaxRGB is the maximum integral value which may be stored
+in the red, green, or blue channels of the image. Each image pixel may
+also optionally (if the image matte channel is enabled) have an
+associated level of opacity (ranging from opaque to transparent), which
+may be used to determine the influence of the pixel color when
+compositing the pixel with another image pixel. If the image matte
+channel is disabled, then all pixels in the image are treated as opaque.
+The color of an \fIopaque\fP pixel is fully visible while the color of a
+\fItransparent\fP pixel color is entirely absent (pixel color is ignored).
+
+By definition, raster images have a rectangular shape. All image rows are
+of equal length, and all image columns have the same number of rows. By
+treating the opacity channel as a visual "mask" the rectangular image may
+be given a "shape" by treating the opacity channel as a cookie-cutter for
+the image. Pixels within the shape are opaque, while pixels outside the
+shape are transparent. Pixels on the boundary of the shape may be between
+opaque and transparent in order to provide antialiasing (visually smooth
+edges). The description of the composition operators use this concept of
+image "shape" in order to make the description of the operators easier to
+understand. While it is convenient to describe the operators in terms of
+"shapes" they are by no means limited to mask-style operations since they
+are based on continuous floating-point mathematics rather than simple
+boolean operations.
+
+By default, the \fIOver\fP composite operator is used. The following
+composite operators are available:
+
+ Over
+ In
+ Out
+ Atop
+ Xor
+ Plus
+ Minus
+ Add
+ Subtract
+ Difference
+ Divide
+ Multiply
+ Bumpmap
+ Copy
+ CopyRed
+ CopyGreen
+ CopyBlue
+ CopyOpacity
+ CopyCyan
+ CopyMagenta
+ CopyYellow
+ CopyBlack
+
+
+The behavior of each operator is described below.
+
+.in 15
+
+.in 15
+.B "Over"
+.in 20
+ \fR
+.in 20
+The result will be the union of the two image shapes, with opaque areas
+of \fIchange-image\fP obscuring \fIbase-image\fP in the region of
+overlap.
+
+.in 15
+.in 15
+.B "In"
+.in 20
+ \fR
+.in 20
+The result is simply \fIchange-image\fP cut by the shape of
+\fIbase-image\fP. None of the image data of \fIbase-image\fP will be in
+the result.
+
+.in 15
+.in 15
+.B "Out"
+.in 20
+ \fR
+.in 20
+The resulting image is \fIchange-image\fP with the shape of
+\fIbase-image\fP cut out.
+
+.in 15
+.in 15
+.B "Atop"
+.in 20
+ \fR
+.in 20
+The result is the same shape as \fIbase-image\fP, with
+\fIchange-image\fP obscuring \fIbase-image\fP where the image shapes
+overlap. Note this differs from \fBover\fP because the portion of
+\fIchange-image\fP outside \fIbase-image\fP's shape does not appear in
+the result.
+
+.in 15
+.in 15
+.B "Xor"
+.in 20
+ \fR
+.in 20
+The result is the image data from both \fIchange-image\fP and
+\fIbase-image\fP that is outside the overlap region. The overlap region
+will be blank.
+
+.in 15
+.in 15
+.B "Plus"
+.in 20
+ \fR
+.in 20
+The result is just the sum of the image data. Output values are cropped
+to MaxRGB (no overflow). This operation is independent of the matte
+channels.
+
+.in 15
+.in 15
+.B "Minus"
+.in 20
+ \fR
+.in 20
+The result of \fIchange-image\fP - \fIbase-image\fP, with underflow
+cropped to zero. The matte channel is ignored (set to opaque, full
+coverage).
+
+.in 15
+.in 15
+.B "Add"
+.in 20
+ \fR
+.in 20
+The result of \fIchange-image\fP + \fIbase-image\fP, with overflow
+wrapping around (\fImod\fP MaxRGB+1).
+
+.in 15
+.in 15
+.B "Subtract"
+.in 20
+ \fR
+.in 20
+The result of \fIchange-image\fP - \fIbase-image\fP, with underflow
+wrapping around (\fImod\fP MaxRGB+1). The \fBadd\fP and \fBsubtract\fP
+operators can be used to perform reversible transformations.
+
+.in 15
+.in 15
+.B "Difference"
+.in 20
+ \fR
+.in 20
+The result of abs(\fIchange-image\fP - \fIbase-image\fP). This is
+useful for comparing two very similar images.
+
+.in 15
+.in 15
+.B "Divide"
+.in 20
+ \fR
+.in 20
+The result of \fIchange-image\fP / \fIbase-image\fP. This is useful
+for improving the readability of text on unevenly illuminated photos (by
+using a gaussian blurred copy of change-image as base-image).
+
+.in 15
+.in 15
+.B "Multiply"
+.in 20
+ \fR
+.in 20
+The result of \fIchange-image\fP * \fIbase-image\fP. This is useful for
+the creation of drop-shadows.
+
+.in 15
+.in 15
+.B "Bumpmap"
+.in 20
+ \fR
+.in 20
+The result \fIbase-image\fP shaded by \fIchange-image\fP.
+
+.in 15
+.in 15
+.B "Copy"
+.in 20
+ \fR
+.in 20
+The resulting image is \fIbase-image\fP replaced with
+\fIchange-image\fP. Here the matte information is ignored.
+
+.in 15
+.in 15
+.B "CopyRed"
+.in 20
+ \fR
+.in 20
+The resulting image is the red channel in \fIbase-image\fP replaced with
+the red channel in \fIchange-image\fP. The other channels are copied
+untouched.
+
+.in 15
+.in 15
+.B "CopyGreen"
+.in 20
+ \fR
+.in 20
+The resulting image is the green channel in \fIbase-image\fP replaced
+with the green channel in \fIchange-image\fP. The other channels are
+copied untouched.
+
+.in 15
+.in 15
+.B "CopyBlue"
+.in 20
+ \fR
+.in 20
+The resulting image is the blue channel in \fIbase-image\fP replaced
+with the blue channel in \fIchange-image\fP. The other channels are
+copied untouched.
+
+.in 15
+.in 15
+.B "CopyOpacity"
+.in 20
+ \fR
+.in 20
+The resulting image is the opacity channel in \fIbase-image\fP replaced
+with the opacity channel in \fIchange-image\fP. The other channels are
+copied untouched.
+
+.in 15
+.in 15
+.B "CopyCyan"
+.in 20
+ \fR
+.in 20
+The resulting image is the cyan channel in \fIbase-image\fP replaced
+with the cyan channel in \fIchange-image\fP. The other channels are
+copied untouched. Use of this operator requires that base-image be in
+CMYK(A) colorspace.
+
+.in 15
+.in 15
+.B "CopyMagenta"
+.in 20
+ \fR
+.in 20
+The resulting image is the magenta channel in \fIbase-image\fP
+replaced with the magenta channel in \fIchange-image\fP. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace.
+
+.in 15
+.in 15
+.B "CopyYellow"
+.in 20
+ \fR
+.in 20
+The resulting image is the yellow channel in \fIbase-image\fP
+replaced with the yellow channel in \fIchange-image\fP. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace.
+
+.in 15
+.in 15
+.B "CopyBlack"
+.in 20
+ \fR
+.in 20
+The resulting image is the black channel in \fIbase-image\fP
+replaced with the black channel in \fIchange-image\fP. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace. If change-image is not in CMYK
+space, then the change-image pixel intensities are used.
+
+.in 15
+
+
+.TP
+.B "-compress \fI<type>"\fP
+\fRthe type of image compression
+
+Choices are: \fINone\fP, \fIBZip\fP, \fIFax\fP,
+\fIGroup4\fP,
+\fIJPEG\fP, \fILossless\fP,
+\fILZW\fP, \fIRLE\fP, \fIZip\fP, or \fILZMA\fP.
+
+
+Specify \fB+compress\fP to store the binary image in an uncompressed format.
+The default is the compression type of the specified image file.
+
+\fI"Lossless"\fP refers to lossless JPEG, which is only available if
+the JPEG library has been patched to support it. Use of lossless JPEG is
+generally not recommended.
+
+Use the \fB-quality\fP option to set the compression level to be used by
+JPEG, PNG, MIFF, and MPEG encoders. Use the \fB-sampling-factor\fP
+option to set the sampling factor to be used by the DPX, JPEG, MPEG, and
+YUV encoders for downsampling the chroma channels.
+.TP
+.B "-contrast"
+\fRenhance or reduce the image contrast
+
+This option enhances the intensity differences between the lighter and
+darker elements of the image. Use \fB-contrast\fP to enhance
+the image
+or \fB+contrast\fP to reduce the image contrast.
+
+
+For a more pronounced effect you can repeat the option:
+
+ gm convert rose: -contrast -contrast rose_c2.png
+
+.TP
+.B "-convolve \fI<kernel>"\fP
+\fRconvolve image with the specified convolution kernel
+
+The kernel is specified as a comma-separated list of floating point
+values, ordered left-to right, starting with the top row. The order of
+the kernel is determined by the square root of the number of entries.
+Presently only square kernels are supported.
+.TP
+.B "-create-directories"
+\fRcreate output directory if required
+
+Use this option with \fB-output-directory\fP if the input paths contain
+subdirectories and it is desired to create similar subdirectories in the
+output directory. Without this option, \fBmogrify\fP will fail if the
+required output directory does not exist.
+.TP
+.B "-crop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRpreferred size and location of the cropped image
+
+See \fB-geometry\fP for details
+about the geometry specification.
+
+The width and height give the size of the image that remains after cropping,
+and \fIx\fP and \fIy\fP are offsets that give the location of the top left
+corner of the cropped
+image with respect to the original image. To specify the amount to be
+removed, use \fB-shave\fP instead.
+
+If the \fIx\fP and \fIy\fP offsets are present, a single image is
+generated, consisting of the pixels from the cropping region.
+The offsets specify the location of the upper left corner of
+the cropping region measured downward and rightward with respect to the
+upper left corner of the image.
+If the \fB-gravity\fP option is present with \fINorthEast, East,\fP
+or \fISouthEast\fP
+gravity, it gives the distance leftward from the right edge
+of the image to the right edge of the cropping region. Similarly, if
+the \fB-gravity\fP option is present with \fISouthWest, South,\fP
+or \fISouthEast\fP
+gravity, the distance is measured upward between the bottom
+edges.
+
+If the \fIx\fP and \fIy\fP offsets are omitted, a set of tiles of the
+specified geometry, covering the entire input image, is generated. The
+rightmost tiles and the bottom tiles are smaller if the
+specified geometry extends beyond the dimensions of the input image.
+.TP
+.B "-cycle \fI<amount>"\fP
+\fRdisplace image colormap by amount
+
+\fIAmount\fP defines the number of positions each colormap entry isshifted.
+
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+
+The events parameter specifies which events are to be logged. It
+can be either None, All, or a comma-separated list
+consisting of one or more of the following domains: Annotate,
+Blob, Cache, Coder, Configure,
+Deprecate, Error, Exception, Locale,
+Render,Resource, TemporaryFile,
+Transform, Warning, X11, or User.
+For example, to log cache and blob events, use
+
+ gm convert -debug "Cache,Blob" rose: rose.png
+
+
+The "User" domain is normally empty, but developers can log "User" events
+in their private copy of GraphicsMagick.
+
+Use the \fB-log\fP option to specify the format for debugging output.
+
+Use \fB+debug\fP to turn off all logging.
+
+An alternative to using \fB-debug\fP is to use the \fBMAGICK_DEBUG\fP
+environment variable. The allowed values for the \fBMAGICK_DEBUG\fP
+environment variable are the same as for the \fB-debug\fP option.
+.TP
+.B "-deconstruct"
+\fRbreak down an image sequence into constituent parts
+
+This option compares each image with the next in a sequence and
+returns the maximum bounding region of any pixel differences it discovers.
+This method can undo a coalesced sequence returned by the
+\fB-coalesce\fP option, and is useful for removing redundant information
+from a GIF or MNG animation.
+
+The sequence of images
+is terminated by the appearance of any option.
+If the \fB-deconstruct\fP
+option appears after all of the input images, all images are deconstructed.
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+This option creates one or more definitions for coders and
+decoders to use while reading and writing image data. Definitions
+may be passed to coders and decoders to control options that are
+specific to certain image formats. If \fIvalue\fP is missing for a
+definition, an empty-valued definition of a flag will be created with
+that name. This is used to control on/off options. Use +define
+<key>,... to remove definitions previously created. Use
++define "*" to remove all existing definitions.
+
+The following definitions may be created:
+
+.in 15
+
+.in 15
+.B "cineon:colorspace={rgb|cineonlog}"
+.in 20
+ \fR
+.in 20
+Use the cineon:colorspace option when reading a Cineon file to
+specify the colorspace the Cineon file uses. This overrides the colorspace
+type implied by the DPX header (if any).
+
+.in 15
+.in 15
+.B "dpx:bits-per-sample=<value>"
+.in 20
+ \fR
+.in 20
+If the dpx:bits-per-sample key is defined, GraphicsMagick will write
+DPX images with the specified bits per sample, overriding any existing
+depth value. If this option is not specified, then the value is based on
+the existing image depth value from the original image file. The DPX
+standard supports bits per sample values of 1, 8, 10, 12, and 16. Many
+DPX readers demand a sample size of 10 bits with type A padding (see
+below).
+
+.in 15
+.in 15
+.B "dpx:colorspace={rgb|cineonlog}"
+.in 20
+ \fR
+.in 20
+Use the dpx:colorspace option when reading a DPX file to
+specify the colorspace the DPX file uses. This overrides the colorspace
+type implied by the DPX header (if any).
+
+.in 15
+.in 15
+.B "dpx:packing-method={packed|a|b|lsbpad|msbpad}"
+.in 20
+ \fR
+.in 20
+DPX samples are output within 32-bit words. They may be tightly
+packed end-to-end within the words ("packed"), padded with null bits to
+the right of the sample ("a" or "lsbpad), or padded with null bits to the
+left of the sample ("b" or "msbpad"). This option only has an effect for
+sample sizes of 10 or 12 bits. If samples are not packed, the DPX
+standard recommends type A padding. Many DPX readers demand a sample size
+of 10 bits with type A padding.
+
+.in 15
+.in 15
+.B "dpx:pixel-endian={lsb|msb}"
+.in 20
+ \fR
+.in 20
+Allows the user to specify the endian order of the pixels when
+reading or writing the DPX files. Sometimes this is useful if the file is
+(or must be) written incorrectly so that the file header and the pixels
+use different endianness.
+
+.in 15
+.in 15
+.B "dpx:swap-samples={true|false}"
+.in 20
+ \fR
+.in 20
+GraphicsMagick strives to adhere to the DPX standard but certain
+aspects of the standard can be quite confusing. As a result, some 10-bit
+DPX files have Red and Blue interchanged, or Cb and Cr interchanged due
+to an different interpretation of the standard, or getting the wires
+crossed. The swap-samples option may be supplied when reading or writing
+in order to read or write using the necessary sample order.
+
+.in 15
+.in 15
+.B "jp2:rate=<value>"
+.in 20
+ \fR
+.in 20
+Specify the compression factor to use while writing JPEG-2000
+files. The compression factor is the reciprocal of the compression
+ratio. The valid range is 0.0 to 1.0, with 1.0 indicating lossless
+compression. If defined, this value overrides the -quality
+setting. The default quality setting of 75 results in a rate value of
+0.06641.
+
+.in 15
+.in 15
+.B "jpeg:block-smoothing={true|false}"
+.in 20
+ \fR
+.in 20
+Enables or disables block smoothing when reading a JPEG file
+(default enabled).
+
+.in 15
+.in 15
+.B "jpeg:dct-method=<value>"
+.in 20
+ \fR
+.in 20
+Selects the IJG JPEG library DCT implementation to use. The
+encoding implementations vary in speed and encoding error. The
+available choices for \fBvalue\fP are \fBislow\fP, \fBifast\fP,
+\fBfloat\fP, \fBdefault\fP and \fBfastest\fP. Note that
+\fBfastest\fP might not necessarily be fastest on your CPU, depending
+on the choices made when the JPEG library was built and how your CPU
+behaves.
+
+.in 15
+.in 15
+.B "jpeg:fancy-upsampling={true|false}"
+.in 20
+ \fR
+.in 20
+Enables or disables fancy upsampling when reading a JPEG file
+(default enabled).
+
+.in 15
+.in 15
+.B "jpeg:optimize-coding={true|false}"
+.in 20
+ \fR
+.in 20
+
+Selects if huffman encoding should be used. Huffman encoding is enabled
+by default, but may be disabled for very large images since it encoding
+requires that the entire image be buffered in memory. Huffman encoding
+produces smaller JPEG files at the expense of added compression time and
+memory consumption.
+
+.in 15
+.in 15
+.B "jpeg:preserve-settings"
+.in 20
+ \fR
+.in 20
+If the jpeg:preserve-settings flag is defined, the JPEG encoder will
+use the same "quality" and "sampling-factor" settings that were found
+in the input file, if the input was in JPEG format. These settings are
+also preserved if the input is a JPEG file and the output is a JNG
+file. If the colorspace of the output file differs from that of the
+input file, the quality setting is preserved but the sampling-factors
+are not.
+
+.in 15
+.in 15
+.B "pcl:fit-to-page"
+.in 20
+ \fR
+.in 20
+If the pcl:fit-to-page flag is defined, then the printer is
+requested to scale the image to fit the page size (width and/or
+height).
+.in 15
+.in 15
+.B "pdf:use-cropbox={true|false}"
+.in 20
+ \fR
+.in 20
+If the pdf:use-cropbox flag is set to \fBtrue\fP, then
+Ghostscript is requested to apply the PDF crop box.
+
+.in 15
+.in 15
+.B "pdf:stop-on-error={true|false}"
+.in 20
+ \fR
+.in 20
+If the pdf:stop-on-error flag is set to \fBtrue\fP, then
+Ghostscript is requested to stop processing the PDF when the first
+error is encountered. Otherwise it will attempt to process all
+requested pages.
+
+.in 15
+.in 15
+.B "ps:imagemask"
+.in 20
+ \fR
+.in 20
+If the ps:imagemask flag is defined, the PS3 and EPS3 coders will
+create Postscript files that render bilevel images with the Postscript
+imagemask operator instead of the image operator.
+
+.in 15
+.in 15
+.B "tiff:alpha={unspecified|associated|unassociated}"
+.in 20
+ \fR
+.in 20
+Specify the TIFF alpha channel type when reading or writing TIFF files,
+overriding the normal value. The default alpha channel type for new files
+is unspecified alpha. Existing alpha settings are preserved when
+converting from one TIFF file to another. When a TIFF file uses
+associated alpha, the image pixels are pre-multiplied (i.e. altered) with
+the alpha channel. Files with "associated" alpha appear as if they were
+alpha composited on a black background when the matte channel is
+disabled. If the unassociated alpha type is selected, then the alpha
+channel is saved without altering the pixels. Photoshop recognizes
+associated alpha as transparency information, if the file is saved with
+unassociated alpha, the alpha information is loaded as an independent
+channel. Note that for many years, ImageMagick and GraphicsMagick marked
+TIFF files as using associated alpha, without properly pre-multiplying
+the pixels.
+
+.in 15
+.in 15
+.B "tiff:fill-order={msb2lsb|lsb2msb}"
+.in 20
+ \fR
+.in 20
+If the tiff:fill-order key is defined, GraphicsMagick will use it to
+determine the bit fill order used while writing TIFF files. The normal default
+is "msb2lsb", which matches the native bit order of all modern CPUs. The
+only exception to this is when Group3 or Group4 FAX compression is
+requested since FAX machines send data in bit-reversed order and
+therefore RFC 2301 recommends using reverse order.
+
+.in 15
+.in 15
+.B "tiff:group-three-options=<value>"
+.in 20
+ \fR
+.in 20
+If the tiff:group-three-options key is defined, GraphicsMagick
+will use it to set the group3 options tag when writing
+group3-compressed TIFF. Please see the TIFF specification for the
+usage of this tag. The default value is 4.
+
+.in 15
+.in 15
+.B "tiff:ignore-tags=<tags>"
+.in 20
+ \fR
+.in 20
+If the tiff:ignore-tags key is defined, then it is used as a list
+of comma-delimited integer TIFF tag values to ignore while reading the
+TIFF file. This is useful in order to be able to read files which
+which otherwise fail to read due to problems with TIFF tags. Note
+that some TIFF tags are required in order to be able to read the image
+data at all.
+
+.in 15
+.in 15
+.B "tiff:report-warnings={false|true}"
+.in 20
+ \fR
+.in 20
+If the tiff:report-warnings key is defined and set to \fBtrue\fP,
+then TIFF warnings are reported as a warning exception rather than as
+a coder log message. Such warnings are reported after the image has
+been read or written. Most TIFF warnings are benign but sometimes
+they may help deduce problems with the TIFF file, or help detect that
+the TIFF file requires a special application to read successfully due
+to the use of proprietary or specialized extensions.
+
+.in 15
+.in 15
+.B "tiff:sample-format={unsigned|ieeefp}"
+.in 20
+ \fR
+.in 20
+If the tiff:sample-format key is defined, GraphicsMagick will use it to
+determine the sample format used while writing TIFF files. The default is
+"unsigned". Specify "ieeefp" in order to write floating-point TIFF
+files with float (32-bit) or double (64-bit) values. Use the
+tiff:bits-per-sample define to determine the type of floating-point value
+to use.
+
+.in 15
+.in 15
+.B "tiff:max-sample-value=<value>"
+.in 20
+ \fR
+.in 20
+If the tiff:max-sample-value key is defined, GraphicsMagick will use the
+assigned value as the maximum floating point value while reading or
+writing IEEE floating point TIFFs. Otherwise the maximum value is 1.0 or
+the value obtained from the file's SMaxSampleValue tag (if present). The
+floating point data is currently not scanned in advance to determine a
+best maximum sample value so if the range is not 1.0, or the
+SMaxSampleValue tag is not present, it may be necessary to
+(intelligently) use this parameter to properly read a file.
+
+.in 15
+.in 15
+.B "tiff:min-sample-value=<value>"
+.in 20
+ \fR
+.in 20
+If the tiff:min-sample-value key is defined, GraphicsMagick will use
+the assigned value as the minimum floating point value while reading or
+writing IEEE floating point TIFFs. Otherwise the minimum value is 0.0 or
+the value obtained from the file's SMinSampleValue tag (if present).
+
+.in 15
+.in 15
+.B "tiff:bits-per-sample=<value>"
+.in 20
+ \fR
+.in 20
+If the tiff:bits-per-sample key is defined, GraphicsMagick will write
+images with the specified bits per sample, overriding any existing depth
+value. Value may be any in the range of 1 to 32, or 64 when the default
+\'unsigned' format is written, or 16/32/24/64 if IEEEFP format is written.
+Please note that the baseline TIFF 6.0 specification only requires
+readers to handle certain powers of two, and the values to be handled
+depend on the nature of the image (e.g. colormapped, grayscale, RGB, CMYK).
+
+.in 15
+.in 15
+.B "tiff:samples-per-pixel=<value>"
+.in 20
+ \fR
+.in 20
+If the tiff:samples-per-pixel key is defined to a value, the TIFF coder
+will write TIFF images with the defined samples per pixel, overriding any
+value stored in the image. This option should not normally be used.
+
+.in 15
+.in 15
+.B "tiff:rows-per-strip=<value>"
+.in 20
+ \fR
+.in 20
+Allows the user to specify the number of rows per TIFF strip.
+Rounded up to a multiple of 16 when using JPEG compression. Ignored when
+using tiles.
+
+.in 15
+.in 15
+.B "tiff:strip-per-page=true"
+.in 20
+ \fR
+.in 20
+Requests that the image is written in a single TIFF strip. This is
+normally the default when group3 or group4 compression is requested
+within reasonable limits. Requesting a single strip for large images may
+result in failure due to resource consumption in the writer or reader.
+
+.in 15
+.in 15
+.B "tiff:tile"
+.in 20
+ \fR
+.in 20
+Enable writing tiled TIFF (rather than stripped) using the default tile
+size. Tiled TIFF organizes the image as an array of smaller images
+(tiles) in order to enable random access.
+
+.in 15
+.in 15
+.B "tiff:tile-geometry=<width>x<height>"
+.in 20
+ \fR
+.in 20
+Specify the tile size to use while writing tiled TIFF. Width and
+height should be a multiple of 16. If the value is not a multiple of 16,
+then it will be rounded down. Enables tiled TIFF if it has not already
+been enabled. GraphicsMagick does not use tiled storage internally so
+tiles need to be converted back and forth from the internal
+scanline-oriented storage to tile-oriented storage. Testing with typical
+RGB images shows that useful square tile size values range from 128x128
+to 1024x1024. Large images which require using a disk-based pixel cache
+benefit from large tile sizes while images which fit in memory work well
+with smaller tile sizes.
+
+.in 15
+.in 15
+.B "tiff:tile-width=<width>"
+.in 20
+ \fR
+.in 20
+Specify the tile width to use while writing tiled TIFF. The tile height
+is then defaulted to an appropriate size. Width should be a multiple of
+16. If the value is not a multiple of 16, then it will be rounded down.
+Enables tiled TIFF if it has not already been enabled.
+
+.in 15
+.in 15
+.B "tiff:tile-height=<height>"
+.in 20
+ \fR
+.in 20
+Specify the tile height to use while writing tiled TIFF. The tile width
+is then defaulted to an appropriate size. Height should be a multiple of
+16. If the value is not a multiple of 16, then it will be rounded down.
+Enables tiled TIFF if it has not already been enabled.
+
+.in 15
+.in 15
+.B "webp:lossless={true|false}"
+.in 20
+ \fR
+.in 20
+Enable lossless encoding.
+
+.in 15
+.in 15
+.B "webp:method={0-6}"
+.in 20
+ \fR
+.in 20
+Quality/speed trade-off.
+
+.in 15
+.in 15
+.B "webp:image-hint={default,graph,photo,picture}"
+.in 20
+ \fR
+.in 20
+Hint for image type.
+
+.in 15
+.in 15
+.B "webp:target-size=<integer>"
+.in 20
+ \fR
+.in 20
+Target size in bytes.
+
+.in 15
+.in 15
+.B "webp:target-psnr=<float>"
+.in 20
+ \fR
+.in 20
+Minimal distortion to try to achieve.
+
+.in 15
+.in 15
+.B "webp:segments={1-4}"
+.in 20
+ \fR
+.in 20
+Maximum number of segments to use.
+
+.in 15
+.in 15
+.B "webp:sns-strength={0-100}"
+.in 20
+ \fR
+.in 20
+Spatial Noise Shaping.
+
+.in 15
+.in 15
+.B "webp:filter-strength={0-100}"
+.in 20
+ \fR
+.in 20
+Filter strength.
+
+.in 15
+.in 15
+.B "webp:filter-sharpness={0-7}"
+.in 20
+ \fR
+.in 20
+Filter sharpness.
+
+.in 15
+.in 15
+.B "webp:filter-type={0,1}"
+.in 20
+ \fR
+.in 20
+Filtering type. 0 = simple, 1 = strong (only used if
+filter-strength > 0 or autofilter is enabled).
+
+.in 15
+.in 15
+.B "webp:auto-filter={true|false}"
+.in 20
+ \fR
+.in 20
+Auto adjust filter's strength.
+
+.in 15
+.in 15
+.B "webp:alpha-compression=<integer>"
+.in 20
+ \fR
+.in 20
+Algorithm for encoding the alpha plane (0 = none, 1 = compressed
+with WebP lossless). Default is 1.
+
+.in 15
+.in 15
+.B "webp:alpha-filtering=<integer>"
+.in 20
+ \fR
+.in 20
+Predictive filtering method for alpha plane. 0: none, 1: fast, 2:
+best. Default is 1.
+
+.in 15
+.in 15
+.B "webp:alpha-quality={0-100}"
+.in 20
+ \fR
+.in 20
+Between 0 (smallest size) and 100 (lossless). Default is 100.
+
+.in 15
+.in 15
+.B "webp:pass=[1..10]"
+.in 20
+ \fR
+.in 20
+Number of entropy-analysis passes.
+
+.in 15
+.in 15
+.B "webp:show-compressed={true|false}"
+.in 20
+ \fR
+.in 20
+Export the compressed picture back. In-loop filtering is not
+applied.
+
+.in 15
+.in 15
+.B "webp:preprocessing=[0,1,2]"
+.in 20
+ \fR
+.in 20
+0=none, 1=segment-smooth, 2=pseudo-random dithering
+
+.in 15
+.in 15
+.B "webp:partitions=[0-3]"
+.in 20
+ \fR
+.in 20
+log2(number of token partitions) in [0..3]. Default is 0 for
+easier progressive decoding.
+
+.in 15
+.in 15
+.B "webp:partition-limit={0-100}"
+.in 20
+ \fR
+.in 20
+Quality degradation allowed to fit the 512k limit on prediction
+modes coding (0: no degradation, 100: maximum possible
+degradation).
+
+.in 15
+.in 15
+.B "webp:emulate-jpeg-size={true|false}"
+.in 20
+ \fR
+.in 20
+If true, compression parameters will be remapped to better match
+the expected output size from JPEG compression. Generally, the output
+size will be similar but the degradation will be lower.
+
+.in 15
+.in 15
+.B "webp:thread-level=<integer>"
+.in 20
+ \fR
+.in 20
+If non-zero, try and use multi-threaded encoding.
+
+.in 15
+.in 15
+.B "webp:low-memory={true|false}"
+.in 20
+ \fR
+.in 20
+If set, reduce memory usage (but increase CPU use)
+
+.in 15
+
+
+
+For example, to create a postscript file that will render only the black
+pixels of a bilevel image, use:
+
+ gm convert bilevel.tif -define ps:imagemask eps3:stencil.ps
+
+.TP
+.B "-delay \fI<1/100ths of a second>"\fP
+\fRdisplay the next image after pausing
+
+This option is useful for regulating the animation of image sequences
+\fIDelay/100\fP seconds must expire before the display
+of the next image. The default is no delay between each showing of the
+image sequence. The maximum delay is 65535.
+
+You can specify a delay range (e.g. \fI-delay 10-500\fP) which sets the
+minimum and maximum delay.
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+This option specifies the image resolution to store while encoding a
+raster image or the canvas resolution while rendering (reading) vector
+formats such as Postscript, PDF, WMF, and SVG into a raster image. Image
+resolution provides the unit of measure to apply when rendering to an
+output device or raster image. The default unit of measure is in dots
+per inch (DPI). The \fB-units\fP option may be used to select dots per
+centimeter instead.
+ The default resolution is 72 dots per inch, which is equivalent to
+one point per pixel (Macintosh and Postscript standard). Computer
+screens are normally 72 or 96 dots per inch while printers typically
+support 150, 300, 600, or 1200 dots per inch. To determine the
+resolution of your display, use a ruler to measure the width of your
+screen in inches, and divide by the number of horizontal pixels (1024 on
+a 1024x768 display).
+If the file format supports it, this option may be used to update
+the stored image resolution. Note that Photoshop stores and obtains
+image resolution from a proprietary embedded profile. If this profile is
+not stripped from the image, then Photoshop will continue to treat the
+image using its former resolution, ignoring the image resolution
+specified in the standard file header.
+The density option is an attribute and does not alter the underlying
+raster image. It may be used to adjust the rendered size for desktop
+publishing purposes by adjusting the scale applied to the pixels. To
+resize the image so that it is the same size at a different resolution,
+use the \fB-resample\fP option.
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+
+This is the number of bits of color to preserve in the image. Any value
+between 1 and \fBQuantumDepth\fP (build option) may be specified,
+although 8 or 16 are the most common values. Use this option to specify
+the depth of raw images whose depth is unknown such as GRAY, RGB, or
+CMYK, or to change the depth of any image after it has been read.
+The depth option is applied to the pixels immediately so it may be
+used as a form of simple compression by discarding the least significant
+bits. Reducing the depth in advance may speed up color quantization, and
+help create smaller file sizes when using a compression algorithm like
+LZW or ZIP.
+.TP
+.B "-descend"
+\fRobtain image by descending window hierarchy
+.TP
+.B "-despeckle"
+\fRreduce the speckles within an image
+.TP
+.B "-displace \fI<horizontal scale>x<vertical scale>"\fP
+\fRshift image pixels as defined by a displacement map
+
+With this option, \fIcomposite image\fP is used as a displacement map. Black,
+within the displacement map, is a maximum positive displacement. White is a
+maximum negative displacement and middle gray is neutral. The displacement
+is scaled to determine the pixel shift. By default, the displacement applies
+in both the horizontal and vertical directions. However, if you specify
+\fImask\fP, \fIcomposite image\fP is the horizontal X displacement and
+\fImask\fP the vertical Y displacement.
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+
+This option is used with convert for
+obtaining image or font from this X server. See \fIX(1)\fP.
+.TP
+.B "-dispose \fI<method>"\fP
+\fRGIF disposal method
+
+The Disposal Method indicates the way in which the graphic is to
+be treated after being displayed.
+
+Here are the valid methods:
+
+ Undefined No disposal specified.
+ None Do not dispose between frames.
+ Background Overwrite the image area with
+ the background color.
+ Previous Overwrite the image area with
+ what was there prior to rendering
+ the image.
+
+.TP
+.B "-dissolve \fI<percent>"\fP
+\fRdissolve an image into another by the given percent
+
+The opacity of the composite image is multiplied by the given percent,
+then it is composited over the main image.
+.TP
+.B "-dither"
+\fRapply Floyd/Steinberg error diffusion to the image
+
+The basic strategy of dithering is to trade intensity resolution for spatial
+resolution by averaging the intensities of several neighboring pixels.
+Images which suffer from severe contouring when reducing colors can be
+improved with this option.
+
+The \fB-colors\fP or \fB-monochrome\fP option is required for this option
+to take effect.
+
+Use \fB+dither\fP to turn off dithering and to render PostScript
+without text or graphic aliasing. Disabling dithering often (but not
+always) leads to decreased processing time.
+.TP
+.B "-draw \fI<string>"\fP
+\fRannotate an image with one or more graphic primitives
+
+Use this option to annotate an image with one or more graphic primitives.
+The primitives include shapes, text, transformations,
+and pixel operations. The shape primitives are
+
+ point x,y
+ line x0,y0 x1,y1
+ rectangle x0,y0 x1,y1
+ roundRectangle x0,y0 x1,y1 wc,hc
+ arc x0,y0 x1,y1 a0,a1
+ ellipse x0,y0 rx,ry a0,a1
+ circle x0,y0 x1,y1
+ polyline x0,y0 ... xn,yn
+ polygon x0,y0 ... xn,yn
+ Bezier x0,y0 ... xn,yn
+ path path specification
+ image operator x0,y0 w,h filename
+
+
+The text primitive is
+
+ text x0,y0 string
+
+
+The text gravity primitive is
+
+ gravity NorthWest, North, NorthEast, West, Center,
+ East, SouthWest, South, or SouthEast
+
+
+The text gravity primitive only affects the placement of text and
+does not interact with the other primitives. It is equivalent to
+using the \fB-gravity\fP commandline option, except that it is
+limited in scope to the \fB-draw\fP option in which it appears.
+
+The transformation primitives are
+
+ rotate degrees
+ translate dx,dy
+ scale sx,sy
+ skewX degrees
+ skewY degrees
+
+
+The pixel operation primitives are
+
+ color x0,y0 method
+ matte x0,y0 method
+
+
+The shape primitives are drawn in the color specified in the preceding
+\fB-stroke\fP option. Except for the \fBline\fP and \fBpoint\fP
+primitives, they are filled with the color specified in the preceding
+\fB-fill\fP option. For unfilled shapes, use -fill none.
+
+\fBPoint\fP requires a single coordinate.
+
+\fBLine\fP requires a start and end coordinate.
+
+\fBRectangle\fP
+expects an upper left and lower right coordinate.
+
+\fBRoundRectangle\fP has the upper left and lower right coordinates
+and the width and height of the corners.
+
+\fBCircle\fP has a center coordinate and a coordinate for
+the outer edge.
+
+Use \fBArc\fP to inscribe an elliptical arc within
+a rectangle. Arcs require a start and end point as well as the degree
+of rotation (e.g. 130,30 200,100 45,90).
+
+Use \fBEllipse\fP to draw a partial ellipse
+centered at the given point with the x-axis and y-axis radius
+and start and end of arc in degrees (e.g. 100,100 100,150 0,360).
+
+Finally, \fBpolyline\fP and \fBpolygon\fP require
+three or more coordinates to define its boundaries.
+Coordinates are integers separated by an optional comma. For example,
+to define a circle centered at 100,100
+that extends to 150,150 use:
+
+ -draw 'circle 100,100 150,150'
+
+
+\fBPaths\fP
+(See Paths)
+represent an outline of an object which is defined in terms of
+moveto (set a new current point), lineto (draw a straight line),
+curveto (draw a curve using a cubic Bezier), arc (elliptical or
+circular arc) and closepath (close the current shape by drawing a line
+to the last moveto) elements. Compound paths (i.e., a path with
+subpaths, each consisting of a single moveto followed by one or more
+line or curve operations) are possible to allow effects such as
+"donut holes" in objects.
+
+Use \fBimage\fP to composite an image with another image. Follow the
+image keyword with the composite operator, image location, image size,
+and filename:
+
+ -draw 'image Over 100,100 225,225 image.jpg'
+
+
+You can use 0,0 for the image size, which means to use the actual
+dimensions found in the image header. Otherwise, it will
+be scaled to the given dimensions.
+See \fB-compose\fP for a description of the composite operators.
+
+Use \fBtext\fP to annotate an image with text. Follow the text
+coordinates with a string. If the string has embedded spaces, enclose it
+in single or double quotes. Optionally you can include the image
+filename, type, width, height, or other image attribute by embedding
+special format character. See \fB-comment\fP for details.
+
+For example,
+
+
+ -draw 'text 100,100 "%m:%f %wx%h"'
+
+
+annotates the image with MIFF:bird.miff 512x480 for an image titled
+bird.miff
+and whose width is 512 and height is 480.
+
+If the first character of \fIstring\fP is \fI@\fP, the text is read from
+a file titled by the remaining characters in the string.
+
+\fBRotate\fP rotates subsequent shape primitives and text primitives about
+the origin of the main image. If the \fB-region\fP option precedes the
+\fB-draw\fP option, the origin for transformations is the upper left
+corner of the region.
+
+\fBTranslate\fP translates them.
+
+\fBScale\fP scales them.
+
+\fBSkewX\fP and \fBSkewY\fP skew them with respect to the origin of
+the main image or the region.
+
+The transformations modify the current affine matrix, which is initialized
+from the initial affine matrix defined by the \fB-affine\fP option.
+Transformations are cumulative within the \fB-draw\fP option.
+The initial affine matrix is not affected; that matrix is only changed by the
+appearance of another \fB-affine\fP option. If another \fB-draw\fP
+option appears, the current affine matrix is reinitialized from
+the initial affine matrix.
+
+Use \fBcolor\fP to change the color of a pixel to the fill color (see
+\fB-fill\fP). Follow the pixel coordinate
+with a method:
+
+ point
+ replace
+ floodfill
+ filltoborder
+ reset
+
+
+Consider the target pixel as that specified by your coordinate. The
+\fBpoint\fP
+method recolors the target pixel. The \fBreplace\fP method recolors any
+pixel that matches the color of the target pixel.
+\fBFloodfill\fP recolors
+any pixel that matches the color of the target pixel and is a neighbor,
+whereas \fBfilltoborder\fP recolors any neighbor pixel that is not the
+border color. Finally, \fBreset\fP recolors all pixels.
+
+Use \fBmatte\fP to the change the pixel matte value to transparent. Follow
+the pixel coordinate with a method (see the \fBcolor\fP primitive for
+a description of methods). The \fBpoint\fP method changes the matte value
+of the target pixel. The \fBreplace\fP method changes the matte value
+of any pixel that matches the color of the target pixel. \fBFloodfill\fP
+changes the matte value of any pixel that matches the color of the target
+pixel and is a neighbor, whereas
+\fBfilltoborder\fP changes the matte
+value of any neighbor pixel that is not the border color (\fB-bordercolor\fP).
+Finally \fBreset\fP changes the matte value of all pixels.
+
+You can set the primitive color, font, and font bounding box
+color with
+\fB-fill\fP, \fB-font\fP, and \fB-box\fP respectively. Options
+are processed in command line order so be sure to use these
+options \fIbefore\fP the \fB-draw\fP option.
+.TP
+.B "-edge \fI<radius>"\fP
+\fRdetect edges within an image
+.TP
+.B "-emboss \fI<radius>"\fP
+\fRemboss an image
+.TP
+.B "-encoding \fI<type>"\fP
+\fRspecify the text encoding
+
+Choose from \fIAdobeCustom, AdobeExpert, AdobeStandard, AppleRoman,
+BIG5, GB2312, Latin 2, None, SJIScode, Symbol, Unicode, Wansung.\fP
+.TP
+.B "-endian \fI<type>"\fP
+\fRspecify endianness (MSB, LSB, or Native) of image
+
+\fIMSB\fP indicates big-endian (e.g. SPARC, Motorola 68K) while
+\fILSB\fP indicates little-endian (e.g. Intel 'x86, VAX) byte
+ordering. \fINative\fP indicates to use the normal ordering for the
+current CPU. This option currently only influences the CMYK, DPX,
+GRAY, RGB, and TIFF, formats.
+
+Use \fB+endian\fP to revert to unspecified endianness.
+.TP
+.B "-enhance"
+\fRapply a digital filter to enhance a noisy image
+.TP
+.B "-equalize"
+\fRperform histogram equalization to the image
+.TP
+.B "-extent \fI<width>x<height>{+-}<x>{+-}<y>"\fP
+\fRcomposite image on background color canvas image
+
+This option composites the image on a new background color
+(\fB-background\fP) canvas image of size <width>x<height>. The
+existing image content is composited at the position specified by
+geometry x and y offset and/or desired gravity (\fB-gravity\fP) using
+the current image compose (\fB-compose\fP) method. Image content
+which falls outside the bounds of the new image dimensions is
+discarded.
+
+For example, this command creates a thumbnail of an image, and centers
+it on a red color backdrop image, offsetting the canvas ten pixels to
+the left and five pixels up, with respect to the thumbnail:
+
+ gm convert infile.jpg -thumbnail 120x80 -background red -gravity center \\
+ -extent 140x100-10-5 outfile.jpg
+
+
+This command reduces or expands a JPEG image to fit on an 800x600
+display:
+
+ gm convert -size 800x600 input.jpg \\
+ -resize 800x600 -background black \\
+ -compose Copy -gravity center \\
+ -extent 800x600 \\
+ -quality 92 output.jpg
+
+
+If the aspect ratio of the input image isn't exactly 4:3, then the
+image is centered on an 800x600 black canvas.
+.TP
+.B "-file \fI<filename>"\fP
+\fRwrite annotated difference image to file
+
+If \fB-file\fP is specified, then an annotated difference image is
+generated and written to the specified file. Pixels which differ between
+the \fBreference\fP and \fBcompare\fP images are modified from those in
+the \fBcompare\fP image so that the changed pixels become more obvious.
+Some images may require use of an alternative highlight style (see
+\fB-highlight-style\fP) or highlight color (see \fB-highlight-color\fP)
+before the changes are obvious.
+.TP
+.B "-fill \fI<color>"\fP
+\fRcolor to use when filling a graphic primitive
+
+Colors are represented in GraphicsMagick in the same form used by SVG. Use "gm convert -list color" to list named colors:
+
+ name (named color)
+ #RGB (hex numbers, 4 bits each)
+ #RRGGBB (8 bits each)
+ #RRRGGGBBB (12 bits each)
+ #RRRRGGGGBBBB (16 bits each)
+ #RGBA (4 bits each)
+ #RRGGBBAA (8 bits each)
+ #RRRGGGBBBAAA (12 bits each)
+ #RRRRGGGGBBBBAAAA (16 bits each)
+ rgb(r,g,b) (r,g,b are decimal numbers)
+ rgba(r,g,b,a) (r,g,b,a are decimal numbers)
+
+
+Enclose the color specification in quotation marks to prevent the "#"
+or the parentheses from being interpreted by your shell.
+
+For example,
+
+ gm convert -fill blue ...
+ gm convert -fill "#ddddff" ...
+ gm convert -fill "rgb(65000,65000,65535)" ...
+
+
+The shorter forms are scaled up, if necessary by replication. For example,
+#3af, #33aaff, and #3333aaaaffff are all equivalent.
+
+See \fB-draw\fP for further details.
+.TP
+.B "-filter \fI<type>"\fP
+\fRuse this type of filter when resizing an image
+
+Use this option to affect the resizing operation of an image (see
+\fB-geometry\fP).
+Choose from these filters (ordered by approximate increasing CPU
+time):
+
+ Point
+ Box
+ Triangle
+ Hermite
+ Hanning
+ Hamming
+ Blackman
+ Gaussian
+ Quadratic
+ Cubic
+ Catrom
+ Mitchell
+ Lanczos
+ Bessel
+ Sinc
+
+
+The default filter is automatically selected to provide the best quality
+while consuming a reasonable amount of time. The \fBMitchell\fP filter
+is used if the image supports a palette, supports a matte channel, or is
+being enlarged, otherwise the \fBLanczos\fP filter is used.
+.TP
+.B "-flatten"
+\fRflatten a sequence of images
+
+In some file formats (e.g. Photoshop's PSD) complex images may be
+represented by "layers" (independent images) which must be composited
+in order to obtain the final rendition. The \fB-flatten\fP option
+accomplishes this composition. The sequence of images is replaced by
+a single image created by compositing each image in turn, while
+respecting composition operators and page offsets. While
+\fB-flatten\fP is immediately useful for eliminating layers, it is
+also useful as a general-purpose composition tool.
+
+The sequence of images is terminated by the appearance of any option.
+If the \fB-flatten\fP option appears after all of the input images,
+all images are flattened. Also see \fB-mosaic\fP which is similar to
+\fB-flatten\fP except that it adds a suitably-sized canvas base
+image.
+
+For example, this composites an image on top of a 640x400 transparent
+black canvas image:
+
+ gm convert -size 640x300 xc:transparent \\
+ -compose over -page +0-100 \\
+ frame.png -flatten output.png
+
+
+and this flattens a Photoshop PSD file:
+
+ gm convert input.psd -flatten output.png
+
+.TP
+.B "-flip"
+\fRcreate a "mirror image"
+
+reflect the scanlines in the vertical direction.
+.TP
+.B "-flop"
+\fRcreate a "mirror image"
+
+reflect the scanlines in the horizontal direction.
+.TP
+.B "-font \fI<name>"\fP
+\fRuse this font when annotating the image with text
+
+You can tag a font to specify whether it is a PostScript, TrueType, or X11
+font. For example, Arial.ttf is a TrueType font, ps:helvetica
+is PostScript, and x:fixed is X11.
+.TP
+.B "-foreground \fI<color>"\fP
+\fRdefine the foreground color
+
+The color is specified using the format described under the \fB-fill\fP
+option.
+.TP
+.B "-format \fI<type>"\fP
+\fRthe image format type
+
+When used with the \fBmogrify\fP utility,
+this option will convert any image to the image format you specify.
+See \fIGraphicsMagick(1)\fP for a list of image format types supported by
+\fBGraphicsMagick\fP, or see the output of 'gm -list format'.
+
+By default the file is written to its original name. However, if the
+filename extension matches a supported format, the extension is replaced
+with the image format type specified with \fB-format\fP. For example,
+if you specify \fItiff\fP as the format type and the input image
+filename is \fIimage.gif\fP, the output image filename becomes
+\fIimage.tiff\fP.
+.TP
+.B "-format \fI<string>"\fP
+\fRoutput formatted image characteristics
+
+When used with the \fBidentify\fP utility, or the \fBconvert\fP
+utility with output written to the 'info:-' file specification, use
+this option to print information about the image in a format of your
+choosing. You can include the image filename, type, width, height,
+Exif data, or other image attributes by embedding special format
+characters:
+
+ %b file size
+ %c comment
+ %d directory
+ %e filename extension
+ %f filename
+ %g page dimensions and offsets
+ %h height
+ %i input filename
+ %k number of unique colors
+ %l label
+ %m magick
+ %n number of scenes
+ %o output filename
+ %p page number
+ %q image bit depth
+ %r image type description
+ %s scene number
+ %t top of filename
+ %u unique temporary filename
+ %w width
+ %x horizontal resolution
+ %y vertical resolution
+ %A transparency supported
+ %C compression type
+ %D GIF disposal method
+ %G Original width and height
+ %H page height
+ %M original filename specification
+ %O page offset (x,y)
+ %P page dimensions (width,height)
+ %Q compression quality
+ %T time delay (in centi-seconds)
+ %U resolution units
+ %W page width
+ %X page horizontal offset (x)
+ %Y page vertical offset (y)
+ %@ trim bounding box
+ %# signature
+ \\n newline
+ \\r carriage return
+ %% %
+
+
+For example,
+
+ -format "%m:%f %wx%h"
+
+
+displays \fBMIFF:bird.miff 512x480\fP for an image
+titled \fBbird.miff\fP and whose width is 512 and height is 480.
+
+If the first character of \fIstring\fP is \fB@\fP, the format
+is read from a file titled by the remaining characters in the string.
+
+The values of image type (\fB%p\fP) which may be returned include:
+
+ Bilevel
+ Grayscale
+ GrayscaleMatte
+ Palette
+ PaletteMatte
+ TrueColor
+ TrueColorMatte
+ ColorSeparation
+ ColorSeparationMatte
+ Optimize
+
+
+You can also use the following special formatting syntax to print Exif
+information contained in the file:
+
+ %[EXIF:<tag>]
+
+
+Where "<tag>" may be one of the following:
+
+ * (print all Exif tags, in keyword=data format)
+ ! (print all Exif tags, in tag_number format)
+ #hhhh (print data for Exif tag #hhhh)
+ ImageWidth
+ ImageLength
+ BitsPerSample
+ Compression
+ PhotometricInterpretation
+ FillOrder
+ DocumentName
+ ImageDescription
+ Make
+ Model
+ StripOffsets
+ Orientation
+ SamplesPerPixel
+ RowsPerStrip
+ StripByteCounts
+ XResolution
+ YResolution
+ PlanarConfiguration
+ ResolutionUnit
+ TransferFunction
+ Software
+ DateTime
+ Artist
+ WhitePoint
+ PrimaryChromaticities
+ TransferRange
+ JPEGProc
+ JPEGInterchangeFormat
+ JPEGInterchangeFormatLength
+ YCbCrCoefficients
+ YCbCrSubSampling
+ YCbCrPositioning
+ ReferenceBlackWhite
+ CFARepeatPatternDim
+ CFAPattern
+ BatteryLevel
+ Copyright
+ ExposureTime
+ FNumber
+ IPTC/NAA
+ ExifOffset
+ InterColorProfile
+ ExposureProgram
+ SpectralSensitivity
+ GPSInfo
+ ISOSpeedRatings
+ OECF
+ ExifVersion
+ DateTimeOriginal
+ DateTimeDigitized
+ ComponentsConfiguration
+ CompressedBitsPerPixel
+ ShutterSpeedValue
+ ApertureValue
+ BrightnessValue
+ ExposureBiasValue
+ MaxApertureValue
+ SubjectDistance
+ MeteringMode
+ LightSource
+ Flash
+ FocalLength
+ MakerNote
+ UserComment
+ SubSecTime
+ SubSecTimeOriginal
+ SubSecTimeDigitized
+ FlashPixVersion
+ ColorSpace
+ ExifImageWidth
+ ExifImageLength
+ InteroperabilityOffset
+ FlashEnergy
+ SpatialFrequencyResponse
+ FocalPlaneXResolution
+ FocalPlaneYResolution
+ FocalPlaneResolutionUnit
+ SubjectLocation
+ ExposureIndex
+ SensingMethod
+ FileSource
+ SceneType
+
+
+JPEG specific information (from reading a JPEG file) may be obtained
+like this:
+
+ %[JPEG-<tag>]
+
+
+Where "<tag>" may be one of the following:
+
+ * (all JPEG-related tags, in
+ keyword=data format)
+ Quality IJG JPEG "quality" estimate
+ Colorspace JPEG colorspace numeric ID
+ Colorspace-Name JPEG colorspace name
+ Sampling-factors JPEG sampling factors
+
+
+Please note that JPEG has no notion of "quality" and that the quality
+metric used by, and estimated by the software is based on the quality
+metric established by IJG JPEG 6b. Other encoders (e.g. that used by
+Adobe Photoshop) use different encoding metrics.
+
+Surround the format specification with quotation marks to prevent your shell
+from misinterpreting any spaces and square brackets.
+.TP
+.B "-frame \fI<width>x<height>+<outer bevel width>+<inner bevel width>"\fP
+\fRsurround the image with an ornamental border
+
+See \fB-geometry\fP for details about the geometry
+specification. The \fB-frame\fP option is not affected by the
+\fB-gravity\fP option.
+
+The color of the border is specified with the \fB-mattecolor\fP
+command line option.
+.TP
+.B "-frame"
+\fRinclude the X window frame in the imported image
+.TP
+.B "-fuzz \fI<distance>{%}"\fP
+\fRcolors within this Euclidean distance are considered equal
+
+A number of algorithms search for a target color. By default the color
+must be exact. Use this option to match colors that are close (in
+Euclidean distance) to the target color in RGB 3D space. For example,
+if you want to automatically trim the edges of an image with
+\fB-trim\fP but the image was scanned and the target background color
+may differ by a small amount. This option can account for these
+differences.
+
+The \fIdistance\fP can be in absolute intensity units or, by appending
+\fI"%"\fP, as a percentage of the maximum possible intensity (255,
+65535, or 4294967295).
+.TP
+.B "-gamma \fI<value>"\fP
+\fRlevel of gamma correction
+
+The same color image displayed on two different workstations may look
+different due to differences in the display monitor. Use gamma
+correction to adjust for this color difference. Reasonable values extend
+from \fB0.8\fP to \fB2.3\fP. Gamma less than 1.0 darkens the image and
+gamma greater than 1.0 lightens it. Large adjustments to image gamma may
+result in the loss of some image information if the pixel quantum size
+is only eight bits (quantum range 0 to 255).
+
+You can apply separate gamma values to the red, green, and blue channels
+of the image with a gamma value list delimited with slashes
+(e.g., \fB1.7\fP/\fB2.3\fP/\fB1.2\fP).
+
+Use \fB+gamma\fP \fIvalue\fP
+to set the image gamma level without actually adjusting
+the image pixels. This option is useful if the image is of a known gamma
+but not set as an image attribute (e.g. PNG images).
+.TP
+.B "-gaussian \fI<radius>{x<sigma>}"\fP
+\fRblur the image with a Gaussian operator
+
+Use the given radius and standard deviation (sigma).
+.TP
+.B "-geometry \fI<width>x<height>{+-}<x>{+-}<y>{%}{@}{!}{^}{<}{>}"\fP
+\fRSpecify dimension, offset, and resize options.
+
+The \fB-geometry\fP option is used for a number of different
+purposes, depending on the utility it is used with.
+
+For the X11 commands ('animate', 'display', and 'import'), it
+specifies the preferred size and location of the Image window. By
+default, the window size is the image size and the location is chosen
+by you (or your window manager) when it is mapped.
+ For the 'import', 'convert', 'mogrify' utility commands it may be
+used to specify the desired size when resizing an image. In this
+case, symbols representing resize options may be appended to the
+geometry string to influence how the resize request is treated.
+
+See later notes corresponding to usage by particular commands. The
+following notes apply to when \fB-geometry\fP is used to express a
+resize request, taking into account the current properties of the
+image.
+
+By default, the width and height are maximum values. That is, the
+image is expanded or contracted to fit the width and height value
+while maintaining the aspect ratio of the image.
+
+Append a ^ to the geometry so that the image aspect ratio is
+maintained when the image is resized, but the resulting width or
+height are treated as minimum values rather than maximum values.
+
+Append a ! (exclamation point) to the geometry to force the image size to
+exactly the size you specify. For example, if you specify
+640x480! the image width is set to 640 pixels and height to
+480.
+
+If only the width is specified, without the trailing 'x', then height
+is set to width (e.g., -geometry 100 is the same as
+-geometry 100x100). If only the width is specified but with
+the trailing 'x', then width assumes the value and the height is
+chosen to maintain the aspect ratio of the image. Similarly, if only
+the height is specified prefixed by 'x' (e.g., -geometry
+x256), the width is chosen to maintain the aspect ratio.
+
+To specify a percentage width or height instead, append %. The image size
+is multiplied by the width and height percentages to obtain the final image
+dimensions. To increase the size of an image, use a value greater than
+100 (e.g. 125%). To decrease an image's size, use a percentage less than
+100.
+
+Use @ to specify the maximum area in pixels of an image.
+
+Use > to change the dimensions of the image \fIonly\fP if
+its width or height exceeds the geometry specification. < resizes
+the image \fIonly\fP if both of its dimensions are less than the geometry
+specification. For example,
+if you specify '640x480>' and the image size is 256x256, the image
+size does not change. However, if the image is 512x512 or 1024x1024, it is
+resized to 480x480. Enclose the geometry specification in quotation marks to
+prevent the < or > from being interpreted by your shell
+as a file redirection.
+
+When used with \fIanimate\fP and \fIdisplay\fP, offsets are handled in
+the same manner as in \fIX(1)\fP and the \fB-gravity\fP option is not used.
+If the \fIx\fP is negative, the offset is measured leftward
+from the right edge of the
+screen to the right edge of the image being displayed.
+Similarly, negative \fIy\fP is measured between the bottom edges. The
+offsets are not affected by "%"; they are always measured in pixels.
+
+When used as a \fIcomposite\fP option, \fB-geometry\fP
+gives the dimensions of the image and its location with respect
+to the composite image. If the \fB-gravity\fP option is present
+with \fINorthEast, East,\fP or \fISouthEast\fP gravity, the \fIx\fP
+represents the distance from the right edge of the image to the right edge of
+the composite image. Similarly, if the \fB-gravity\fP option is present
+with \fISouthWest, South,\fP or \fISouthEast\fP gravity, \fIy\fP
+is measured between the bottom edges. Accordingly, a positive offset will
+never point in the direction outside of the image. The
+offsets are not affected by "%"; they are always measured in pixels.
+To specify the dimensions of the composite image, use the \fB-resize\fP
+option.
+
+When used as a \fIconvert\fP, \fIimport\fP or \fImogrify\fP option,
+\fB-geometry\fP is synonymous with \fB-resize\fP and
+specifies the size of the output image. The offsets, if present, are ignored.
+
+When used as a \fImontage\fP option, \fB-geometry\fP specifies the image
+size and border size for each tile; default is 256x256+0+0. Negative
+offsets (border dimensions) are meaningless. The \fB-gravity\fP
+option affects the placement of the image within the tile; the default
+gravity for this purpose is \fICenter\fP. If the "%" sign appears in
+the geometry specification, the tile size is the specified percentage of
+the original dimensions of the first tile.
+To specify the dimensions of the montage, use the \fB-resize\fP
+option.
+.TP
+.B "-gravity \fI<type>"\fP
+\fRdirection primitive gravitates to when annotating the image.
+
+Choices are: NorthWest, North,
+NorthEast, West, Center, East, SouthWest, South, SouthEast.
+
+The direction you choose specifies where to position the text
+when annotating
+the image. For example \fICenter\fP gravity forces the text to be centered
+within the image. By default, the image gravity is \fINorthWest\fP.
+See \fB-draw\fP for more details about graphic primitives. Only the
+text primitive is affected by the \fB-gravity\fP option.
+
+The \fB-gravity\fP option is also used in concert with the \fB-geometry\fP
+option and other options that take \fB<geometry>\fP as a parameter, such
+as the \fB-crop\fP option. See \fB-geometry\fP for details of how the
+\fB-gravity\fP option interacts with the
+\fB<x>\fP and \fB<y>\fP parameters of a geometry
+specification.
+
+When used as an option to \fIcomposite\fP, \fB-gravity\fP
+gives the direction that the image gravitates within the composite.
+
+When used as an option to \fImontage\fP, \fB-gravity\fP gives the direction
+that an image gravitates within a tile. The default gravity is \fICenter\fP
+for this purpose.
+.TP
+.B "-green-primary \fI<x>,<y>"\fP
+\fRgreen chromaticity primary point
+.TP
+.B "-hald-clut \fI<clut>"\fP
+\fRapply a Hald CLUT to the image
+
+A Hald CLUT ("Color Look-Up Table") is a special square color image
+which contains a look-up table for red, green, and blue. The size of
+the Hald CLUT image is determined by its order. The width (and
+height) of a Hald CLUT is the cube of the order. For example, a Hald
+CLUT of order 8 is 512x512 pixels (262,144 colors) and of order 16 is
+4096x4096 (16,777,216 colors). A special CLUT is the identity CLUT
+which which causes no change to the input image. In order to use the
+Hald CLUT, one takes an identity CLUT and adjusts its colors in some
+way. The modified CLUT can then be used to transform any number of
+images in an identical way.
+
+GraphicsMagick contains a built-in identity CLUT generator via the
+\fBIDENTITY\fP coder. For example reading from the file name
+\fPIDENTITY:8\fP returns an identity CLUT of order 8. Typical Hald
+CLUT identity images have an order of between 8 and 16. The default
+order for the \fBIDENTITY\fP CLUT generator is 8. Interpolation is
+used so it is not usually necessary for CLUT images to be very large.
+The PNG file format is ideal for storing Hald CLUT images because it
+compresses them very well.
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-highlight-color \fI<color>"\fP
+\fRpixel annotation color
+
+Specifies the color to use when annotating difference pixels.
+.TP
+.B "-highlight-style \fI<style>"\fP
+\fRpixel annotation style
+
+Specifies the pixel difference annotation style used to draw attention to
+changed pixels. May be one of \fBAssign\fP, \fBThreshold\fP,
+\fBTint\fP, or \fBXOR\fP; where \fBAssign\fP replaces the pixel with
+the highlight color (see \fB-highlight-color\fP), \fBThreshold\fP
+replaces the pixel with black or white based on the difference in
+intensity, \fBTint\fP alpha tints the pixel with the highlight color,
+and \fBXOR\fP does an XOR between the pixel and the highlight color.
+.TP
+.B "-iconGeometry \fI<geometry>"\fP
+\fRspecify the icon geometry
+
+Offsets, if present in the geometry specification, are handled in
+the same manner as the \fB-geometry\fP option, using X11 style to handle
+negative offsets.
+.TP
+.B "-iconic"
+\fRiconic animation
+.TP
+.B "-immutable"
+\fRmake image immutable
+.TP
+.B "-implode \fI<factor>"\fP
+\fRimplode image pixels about the center
+.TP
+.B "-intent \fI<type>"\fP
+\fRuse this type of rendering intent when managing the image color
+
+Use this option to affect the the color management operation of an image (see
+\fB-profile\fP).
+Choose from these intents:
+\fBAbsolute, Perceptual, Relative, Saturation\fP.
+
+The default intent is undefined.
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+
+Choices are: \fBNone, Line, Plane,\fP
+or \fBPartition\fP. The default is \fBNone\fP.
+
+This option is used to specify the type of interlacing scheme for raw image
+formats such as \fBRGB\fP or \fBYUV\fP.
+\fBNone\fP means do not interlace
+(RGBRGBRGBRGBRGBRGB...),
+
+\fBLine\fP uses scanline interlacing
+(RRR...GGG...BBB...RRR...GGG...BBB...),
+and
+\fBPlane\fP uses plane interlacing (RRRRRR...GGGGGG...BBBBBB...).
+
+\fBPartition\fP
+is like plane except the different planes are saved to individual files
+(e.g. image.R, image.G, and image.B).
+
+Use \fBLine\fP to create an \fBinterlaced PNG\fP or \fB GIF\fP or
+\fBprogressive JPEG\fP image.
+.TP
+.B "-label \fI<name>"\fP
+\fRassign a label to an image
+
+Use this option to assign a specific label to the image, when writing
+to an image format that supports labels, such as TIFF, PNG, MIFF, or
+PostScript. You can include the the image filename, type, width, height,
+or other image attribute by embedding special format character. A label
+is not drawn on the image, but is embedded in the image datastream via
+a "Label" tag or similar mechanism. If you want the
+label to be visible on the image itself, use the \fB-draw\fP option.
+See \fB-comment\fP for details.
+
+For example,
+
+ -label "%m:%f %wx%h"
+
+
+produces an image label of \fBMIFF:bird.miff 512x480\fP for an image titled
+\fBbird.miff\fP
+and whose width is 512 and height is 480.
+
+If the first character of \fIstring\fP is \fI@\fP, the image label is
+read from a file titled by the remaining characters in the string.
+
+If the -label option appears multiple times, only the last label is
+stored.
+
+In PNG images, the label is stored in a \fBtEXt\fP or \fBzTXt\fP chunk
+with the keyword "label".
+
+When converting to \fIPostScript\fP, use this option to specify a header
+string to print above the image. Specify the label font with
+\fB-font\fP.
+
+When creating a montage, by default the label associated with an image
+is displayed with the corresponding tile in the montage. Use the
+\fB+label\fP option to suppress this behavior.
+
+
+.TP
+.B "-lat \fI<width>x<height>{+-}<offset>{%}"\fP
+\fRperform local adaptive thresholding
+
+Perform local adaptive thresholding using the specified width, height,
+and offset. The offset is a distance in sample space from the mean,
+as an absolute integer ranging from 0 to the maximum sample value or
+as a percentage. If the percent option is supplied, then the offset
+is computed as a percentage of the quantum range. It is strongly
+recommended to use the percent option so that results are not
+sensitive to pixel quantum depth.
+
+For example,
+
+ -colorspace gray -lat "10x10-5%"
+
+
+will help clarify a scanned grayscale or color document, producing a
+bi-level equivalent.
+.TP
+.B "-level \fI<black_point>{,<gamma>}{,<white_point>}{%}"\fP
+\fRadjust the level of image contrast
+
+Give one, two or three values delimited with commas: black-point, gamma,
+white-point (e.g. 10,1.0,250 or 2%,0.5,98%). The black and white
+points range from 0 to MaxRGB or from 0 to 100%; if the white point is
+omitted it is set to MaxRGB-black_point. If a "%" sign is present
+anywhere in the string, the black and white points are percentages of
+MaxRGB. Gamma is an exponent that ranges from 0.1 to 10.; if it is
+omitted, the default of 1.0 (no gamma correction) is assumed. This
+interface works similar to Photoshop's "Image->Adjustments->Levels..."
+"Input Levels" interface.
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+
+By default, resource limits are estimated based on the available
+resources of the system. The resource limits are \fBDisk\fP, maximum
+total disk space consumed; \fBFile\fP, maximum number of file
+descriptors allowed to be open at once; \fBMap\fP, maximum total
+number of file bytes which may be memory mapped; \fBMemory\fP,
+maximum total number of bytes of heap memory used for image storage;
+\fBPixels\fP, maximum absolute image size (per image); \fBWidth\fP,
+maximum image pixels width; \fBHeight\fP, maximum image pixels
+height; and \fBThreads\fP, the maximum number of worker threads to
+use per OpenMP thread team.
+
+These resource limits are used to decide if (for a given image) the
+decoded image ("pixel cache") should be stored in heap memory (RAM),
+in a memory-mapped disk file, or in a disk file accessed via
+read/write I/O. The number of total pixels in one image, and/or the
+width/height, may also be limited in order to force the reading, or
+creation of images larger than the limit (in pixels) to intentionally
+fail. The disk limit establishes an overall limit since using the disk
+is the means of last resort. When the disk limit has been reached, no
+more images may be read.
+
+The value argument is an absolute value, but may have standard binary
+suffix characters applied ('K', 'M', 'G', 'T', 'P', 'E') to apply a
+scaling to the value (based on a multiplier of 1024). Any additional
+characters are ignored. For example, '-limit Pixels 10MP' limits
+the maximum image size to 10 megapixels and '-limit memory 32MB
+-limit map 64MB' limits memory and memory mapped files to 32
+megabytes and 64 megabytes respectively.
+
+Resource limits may also be set using environment variables. The
+environment variables \fBMAGICK_LIMIT_DISK\fP,
+\fBMAGICK_LIMIT_FILES\fP, \fBMAGICK_LIMIT_MAP\fP,
+\fBMAGICK_LIMIT_MEMORY\fP, \fBMAGICK_LIMIT_PIXELS\fP,
+\fBMAGICK_LIMIT_WIDTH\fP, \fBMAGICK_LIMIT_HEIGHT\fP,and
+\fBOMP_NUM_THREADS\fP may be used to set the limits for disk space,
+open files, memory mapped size, heap memory, per-image pixels, image
+width, image height, and threads respectively.
+
+Use the option -list resource list the current limits.
+.TP
+.B "-linewidth"
+\fRthe line width for subsequent draw operations
+.TP
+.B "-list \fI<type>"\fP
+\fRthe type of list
+
+Choices are: \fBColor\fP, \fBDelegate\fP, \fBFormat\fP, \fBMagic\fP,
+\fBModule\fP, \fBResource\fP, or \fBType\fP. The \fBModule\fP option
+is only available if GraphicsMagick was built to support loadable modules.
+
+This option lists information about the GraphicsMagick configuration.
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+
+This option specifies the format for the log printed when the \fB-debug\fP
+option is active.
+
+You can display the following components by embedding
+special format characters:
+
+ %d domain
+ %e event
+ %f function
+ %l line
+ %m module
+ %p process ID
+ %r real CPU time
+ %t wall clock time
+ %u user CPU time
+ %% percent sign
+ \\n newline
+ \\r carriage return
+
+
+For example:
+
+ gm convert -debug coders -log "%u %m:%l %e" in.gif out.png
+
+
+The default behavior is to print all of the components.
+.TP
+.B "-loop \fI<iterations>"\fP
+\fRadd Netscape loop extension to your GIF animation
+
+A value other than zero forces the animation to repeat itself up to
+\fIiterations\fP
+times.
+.TP
+.B "-magnify"
+\fRmagnify the image
+
+The image size is doubled using linear interpolation.
+.TP
+.B "-magnify \fI<factor>"\fP
+\fRmagnify the image
+
+The displayed image is magnified by \fBfactor\fP.
+.TP
+.B "-map \fI<filename>"\fP
+\fRchoose a particular set of colors from this image
+
+[\fIconvert\fP or \fImogrify\fP]
+
+By default, color reduction chooses an optimal set of colors that best
+represent the original image. Alternatively, you can choose a particular
+set of colors from an image file with this option.
+
+Use
+\fB+map\fP to reduce
+all images in the image sequence that follows to a single optimal set of colors
+that best represent all the images. The sequence of images
+is terminated by the appearance of any option.
+If the \fB+map\fP
+option appears after all of the input images, all images are mapped.
+.TP
+.B "-map \fI<type>"\fP
+\fRdisplay image using this type.
+
+[\fIanimate\fP or \fIdisplay\fP]
+
+Choose from these \fIStandard Colormap\fP types:
+
+ best
+ default
+ gray
+ red
+ green
+ blue
+
+
+The \fIX server\fP must support the \fIStandard Colormap\fP you choose,
+otherwise an error occurs. Use \fBlist\fP as the type and \fBdisplay\fP
+searches the list of colormap types in \fBtop-to-bottom\fP order until
+one is located. See \fIxstdcmap(1)\fP for one way of creating Standard
+Colormaps.
+.TP
+.B "-mask \fI<filename>"\fP
+\fRSpecify a clipping mask
+
+The image read from the file is used as a clipping mask. It must have
+the same dimensions as the image being masked.
+
+If the mask image contains an opacity channel, the opacity of each
+pixel is used to define the mask. Otherwise, the intensity (gray
+level) of each pixel is used. Unmasked (black) pixels are modified
+while masked pixels (not black) are protected from alteration.
+
+Use \fB+mask\fP to remove the clipping mask.
+
+It is not necessary to use \fB-clip\fP to activate the mask; \fB-clip\fP
+is implied by \fB-mask\fP.
+.TP
+.B "-matte"
+\fRstore matte channel if the image has one
+
+If the image does not have a matte channel, create an opaque one.
+
+Use \fB+matte\fP to ignore the matte channel and to avoid writing a
+matte channel in the output file.
+.TP
+.B "-mattecolor \fI<color>"\fP
+\fRspecify the color to be used with the \fB-frame\fP option
+
+The color is specified using the format described under the \fB-fill\fP
+option.
+.TP
+.B "-maximum-error \fI<limit>"\fP
+\fRspecifies the maximum amount of total image error
+
+Specifies the maximum amount of total image error (based on comparison
+using a specified metric) before an error ("image difference exceeds
+limit") is reported. The error is reported via a non-zero command
+execution return status.
+.TP
+.B "-median \fI<radius>"\fP
+\fRapply a median filter to the image
+.TP
+.B "-metric \fI<metric>"\fP
+\fRcomparison metric (MAE, MSE, PAE, PSNR, RMSE)
+.TP
+.B "-minify \fI<factor>"\fP
+\fRminify the image
+
+The image size is halved using linear interpolation.
+.TP
+.B "-mode \fI<value>"\fP
+\fRmode of operation
+
+The available montage modes are \fBframe\fP to place the images in a
+rectangular grid while adding a decorative frame with dropshadow,
+\fBunframe\fP to place undecorated images in a rectangular grid, and
+\fBconcatenate\fP to pack the images closely together without any
+well-defined grid or decoration.
+.TP
+.B "-modulate \fIbrightness[,saturation[,hue]]"\fP
+\fRvary the brightness, saturation, and hue of an image
+
+Specify the percent change in brightness, color saturation, and
+hue separated by commas. Default argument values are 100 percent,
+resulting in no change. For example, to increase the color brightness
+by 20% and decrease the color saturation by 10% and leave the hue
+unchanged, use: \fB-modulate 120,90\fP.
+
+Hue is the percentage of absolute rotation from the current
+position. For example 50 results in a counter-clockwise rotation of 90
+degrees, 150 results in a clockwise rotation of 90 degrees, with 0 and
+200 both resulting in a rotation of 180 degrees.
+.TP
+.B "-monitor"
+\fRshow progress indication
+
+A simple command-line progress indication is shown while the command is
+running. The process indication shows the operation currently being
+performed and the percent completed. Commands using X11 may replace the
+command line progress indication with a graphical one once an image has
+been displayed.
+.TP
+.B "-monochrome"
+\fRtransform the image to black and white
+.TP
+.B "-morph \fI<frames>"\fP
+\fRmorphs an image sequence
+
+Both the image pixels and size are linearly interpolated to give the appearance
+of a meta-morphosis from one image to the next.
+
+The sequence of images
+is terminated by the appearance of any option.
+If the \fB-morph\fP
+option appears after all of the input images, all images are morphed.
+.TP
+.B "-mosaic"
+\fRcreate a mosaic from an image or an image sequence
+
+The \fB-mosaic\fP option provides a flexible way to composite one or
+more images onto a solid-color canvas image. It works similar to
+\fB-flatten\fP except that a base canvas image is automatically
+created with a suitable size given the image size, page dimensions,
+and page offsets of images to be composited. The color of the base
+canvas image may be set via the \fB-background\fP option. The
+default canvas color is 'white', but 'black' or 'transparent' may be
+more suitable depending on the composition algorithm requested.
+
+The \fB-compose\fP option may be used to specify the composition
+algorithm to use when compositing the subsequent image on the base
+canvas.
+
+The \fB-page\fP option can be used to establish the dimensions of the
+mosaic and to position the subsequent image within the mosaic. If the
+\fB-page\fP argument does not specify width and height, then the
+canvas dimensions are evaluated based on the image sizes and
+offsets.
+
+The sequence of images is terminated by the appearance of any option.
+If the \fB-mosaic\fP option appears after all of the input images,
+all images are included in the mosaic.
+
+The following is an example of composing an image based on red, green,
+and blue layers extracted from a sequence of images and pasted on the
+canvas image at specified offsets:
+
+ gm convert -background black \\
+ -compose CopyRed -page +0-100 red.png \\
+ -compose CopyGreen -page +0+40 green.png \\
+ -compose CopyBlue -page +0+180 blue.png \\
+ -mosaic output.png
+
+.TP
+.B "-motion-blur \fI<radius>{x<sigma>}{+angle}"\fP
+\fRSimulate motion blur
+
+Simulate motion blur by convolving the image with a Gaussian operator of
+the given radius and standard deviation (sigma). For reasonable results,
+radius should be larger than sigma. If radius is zero, then a suitable
+radius is automatically selected based on sigma. The angle specifies the
+angle that the object is coming from (side which is blurred).
+.TP
+.B "-name"
+\fRname an image
+.TP
+.B "-negate"
+\fRreplace every pixel with its complementary color
+
+The red, green, and blue intensities of an image are negated.
+White becomes black,
+yellow becomes blue, etc.
+Use \fB+negate\fP
+to only negate the grayscale pixels of the image.
+.TP
+.B "-noise \fI<radius|type>"\fP
+\fRadd or reduce noise in an image
+
+The principal function of noise peak elimination filter is to smooth the
+objects within an image without losing edge information and without creating
+undesired structures. The central idea of the algorithm is to replace a
+pixel with its next neighbor in value within a pixel window, if this pixel
+has been found to be noise. A pixel is defined as noise if and only if
+this pixel is a maximum or minimum within the pixel window.
+
+Use \fBradius\fP to specify the width of the neighborhood.
+
+Use \fB+noise\fP followed by a noise type to add noise to an image.
+The noise added modulates the existing image pixels. Choose from these
+noise types:
+
+ Uniform
+ Gaussian
+ Multiplicative
+ Impulse
+ Laplacian
+ Poisson
+ Random (uniform distribution)
+
+.TP
+.B "-noop"
+\fRNOOP (no option)
+
+The \fB-noop\fP option can be used to terminate a group of images
+and reset all options to their default values, when no other option is
+desired.
+.TP
+.B "-normalize"
+\fRtransform image to span the full range of color values
+
+This is a contrast enhancement technique based on the image histogram.
+
+When computing the contrast enhancement values, the histogram edges
+are truncated so that the majority of the image pixels are considered
+in the constrast enhancement, and outliers (e.g. random noise or
+minute details) are ignored. The default is that 0.1 percent of the
+histogram entries are ignored. The percentage of the histogram to
+ignore may be specified by using the \fB-set\fP option with the
+\fBhistogram-threshold\fP parameter similar to \fB-set
+histogram-threshold 0.01\fP to specify 0.01 percent. Use 0 percent
+to use the entire histogram, with possibly diminished contrast
+enhancement.
+.TP
+.B "-opaque \fI<color>"\fP
+\fRchange this color to the pen color within the image
+
+The color is specified using the format described under the
+\fB-fill\fP option. The color is replaced if it is identical to the
+target color, or close enough to the target color in a 3D space as
+defined by the Euclidean distance specified by \fB-fuzz\fP.
+
+See \fB-fill\fP and \fB-fuzz\fP for more details.
+.TP
+.B "-operator \fIchannel operator rvalue[%]"\fP
+\fRapply a mathematical, bitwise, or value operator to an image channel
+
+Apply a low-level mathematical, bitwise, or value operator to a selected
+image channel or all image channels. Operations which result in negative
+results are reset to zero, and operations which overflow the available
+range are reset to the maximum possible value.
+
+Select a channel from: \fBRed\fP, \fBGreen\fP, \fBBlue\fP,
+\fBOpacity\fP, \fBMatte\fP, \fBCyan\fP, \fBMagenta\fP, \fBYellow\fP,
+\fBBlack\fP, \fBAll\fP, or \fBGray\fP. \fBAll\fP only modifies the
+color channels and does not modify the \fBOpacity\fP channel. Except for
+the threshold operators, \fBAll\fP operates on each channel
+independently so that operations are on a per-channel basis.
+
+\fBGray\fP treats the color channels as a grayscale intensity and
+performs the requested operation on the equivalent pixel intensity so the
+result is a gray image.
+Select an operator from \fBAdd\fP, \fBAnd\fP, \fBAssign\fP,
+\fBDepth\fP, \fBDivide\fP, \fBGamma\fP, \fBNegate\fP,
+\fBLShift\fP, \fBLog\fP, \fBMax\fP, \fBMin\fP, \fBMultiply\fP,
+\fBOr\fP, \fBPow\fP \fBRShift\fP, \fBSubtract\fP,
+\fBThreshold\fP, \fBThreshold-White\fP,
+\fBThreshold-White-Negate\fP, \fBThreshold-Black\fP,
+\fBThreshold-Black-Negate\fP, \fBXor\fP, \fBNoise-Gaussian\fP,
+\fBNoise-Impulse\fP, \fBNoise-Laplacian\fP,
+\fBNoise-Multiplicative\fP, \fBNoise-Poisson\fP,
+\fBNoise-Random\fP, and \fBNoise-Uniform\fP.
+
+Rvalue may be any floating point or integer value. Normally rvalue will
+be in the range of 0 to MaxRGB, where MaxRGB is the largest quantum value
+supported by the GraphicsMagick build (255, 65535, or 4294967295) but
+values outside this range are useful for some arithmetic operations.
+Arguments to logical or bit-wise operations are rounded to a positive
+integral value prior to use. If a percent (\fB%\fP) symbol is appended
+to the argument, then the argument has a range of 0 to 100 percent.
+
+The following is a description of the operators:
+
+.in 15
+
+.in 15
+.B "Add"
+.in 20
+ \fR
+.in 20
+Result is rvalue added to channel value.
+
+.in 15
+.in 15
+.B "And"
+.in 20
+ \fR
+.in 20
+Result is the logical AND of rvalue with channel value.
+
+.in 15
+.in 15
+.B "Assign"
+.in 20
+ \fR
+.in 20
+Result is rvalue.
+
+.in 15
+.in 15
+.B "Depth"
+.in 20
+ \fR
+.in 20
+Result is channel value adjusted so that it may be (approximately)
+stored in the specified number of bits without additional loss.
+
+.in 15
+.in 15
+.B "Divide"
+.in 20
+ \fR
+.in 20
+Result is channel value divided by rvalue.
+
+.in 15
+.in 15
+.B "Gamma"
+.in 20
+ \fR
+.in 20
+Result is channel value gamma adjusted by rvalue.
+
+.in 15
+.in 15
+.B "LShift"
+.in 20
+ \fR
+.in 20
+Result is channel value bitwise left shifted by rvalue bits.
+
+.in 15
+.in 15
+.B "Log"
+.in 20
+ \fR
+.in 20
+Result is computed as log(value*rvalue+1)/log(rvalue+1).
+
+.in 15
+.in 15
+.B "Max"
+.in 20
+ \fR
+.in 20
+Result is assigned to rvalue if rvalue is greater than value.
+
+.in 15
+.in 15
+.B "Min"
+.in 20
+ \fR
+.in 20
+Result is assigned to rvalue if rvalue is less than value.
+
+.in 15
+.in 15
+.B "Multiply"
+.in 20
+ \fR
+.in 20
+Result is channel value multiplied by rvalue.
+
+.in 15
+.in 15
+.B "Negate"
+.in 20
+ \fR
+.in 20
+Result is inverse of channel value (like a film negative). An rvalue
+must be supplied but is currently not used. Inverting the image twice
+results in the original image.
+
+.in 15
+.in 15
+.B "Or"
+.in 20
+ \fR
+.in 20
+Result is the logical OR of rvalue with channel value.
+
+.in 15
+.in 15
+.B "Pow"
+.in 20
+ \fR
+.in 20
+Result is computed as pow(value,rvalue). Similar to Gamma except that
+rvalue is not inverted.
+
+.in 15
+.in 15
+.B "RShift"
+.in 20
+ \fR
+.in 20
+Result is channel value bitwise right shifted by rvalue bits.
+
+.in 15
+.in 15
+.B "Subtract"
+.in 20
+ \fR
+.in 20
+Result is channel value minus rvalue.
+
+.in 15
+.in 15
+.B "Threshold"
+.in 20
+ \fR
+.in 20
+Result is maximum (white) if channel value is greater than rvalue,
+or minimum (black) if it is less than or equal to rvalue. If \fBall\fP
+channels are specified, then thresholding is done based on computed pixel
+intensity.
+
+.in 15
+.in 15
+.B "Threshold-white"
+.in 20
+ \fR
+.in 20
+Result is maximum (white) if channel value is greater than rvalue and
+is unchanged if it is less than or equal to rvalue. This can be used to
+remove apparent noise from the bright parts of an image. If \fBall\fP
+channels are specified, then thresholding is done based on computed pixel
+intensity.
+
+.in 15
+.in 15
+.B "Threshold-White-Negate"
+.in 20
+ \fR
+.in 20
+Result is set to black if channel value is greater than
+rvalue and is unchanged if it is less than or equal to rvalue. If
+\fBall\fP channels are specified, then thresholding is done based on
+computed pixel intensity.
+
+.in 15
+.in 15
+.B "Threshold-black"
+.in 20
+ \fR
+.in 20
+Result is minimum (black) if channel value is less than than rvalue
+and is unchanged if it is greater than or equal to rvalue. This can be
+used to remove apparent noise from the dark parts of an image. If
+\fBall\fP channels are specified, then thresholding is done based on
+computed pixel intensity.
+
+.in 15
+.in 15
+.B "Threshold-Black-Negate"
+.in 20
+ \fR
+.in 20
+Result is set to white if channel value is less than than
+rvalue and is unchanged if it is greater than or equal to rvalue. If
+\fBall\fP channels are specified, then thresholding is done based on
+computed pixel intensity.
+
+.in 15
+.in 15
+.B "Xor"
+.in 20
+ \fR
+.in 20
+Result is the logical XOR of rvalue with channel value. An
+interesting property of XOR is that performing the same operation twice
+results in the original value.
+
+.in 15
+.in 15
+.B "Noise-Gaussian"
+.in 20
+ \fR
+.in 20
+Result is the current channel value modulated with gaussian noise
+according to the intensity specified by rvalue.
+
+.in 15
+.in 15
+.B "Noise-Impulse"
+.in 20
+ \fR
+.in 20
+Result is the current channel value modulated with impulse noise
+according to the intensity specified by rvalue.
+
+.in 15
+.in 15
+.B "Noise-Laplacian"
+.in 20
+ \fR
+.in 20
+Result is the current channel value modulated with laplacian noise
+according to the intensity specified by rvalue.
+
+.in 15
+.in 15
+.B "Noise-Multiplicative"
+.in 20
+ \fR
+.in 20
+Result is the current channel value modulated with multiplicative
+gaussian noise according to the intensity specified by rvalue.
+
+.in 15
+.in 15
+.B "Noise-Poisson"
+.in 20
+ \fR
+.in 20
+Result is the current channel value modulated with poisson noise
+according to the intensity specified by rvalue.
+
+.in 15
+.in 15
+.B "Noise-Random"
+.in 20
+ \fR
+.in 20
+Result is the current channel value modulated with random (uniform
+distribution) noise according to the intensity specified by rvalue.
+The initial noise intensity (rvalue=1.0) is the range of one pixel
+quantum span.
+
+.in 15
+.in 15
+.B "Noise-Uniform"
+.in 20
+ \fR
+.in 20
+Result is the channel value with uniform noise applied according to
+the intensity specified by rvalue.
+
+.in 15
+
+
+
+As an example, the \fBAssign\fP operator assigns a fixed value to a
+channel. For example, this command sets the red channel to the mid-range
+value:
+
+ gm convert in.bmp -operator red assign "50%" out.bmp
+
+
+The following applies 50% thresholding to the image and returns a gray
+image:
+
+ gm convert in.bmp -operator gray threshold "50%" out.bmp
+
+.TP
+.B "-ordered-dither \fI<channeltype> <NxN>"\fP
+\fRordered dither the image
+
+The channel or channels specified in the \fBchanneltype\fP argument are
+reduced to binary, using an ordered dither method. The choices for
+\fBchanneltype\fP are \fBAll\fP, \fBIntensity\fP, \fBRed\fP,
+\fBGreen\fP, \fBBlue\fP, \fBCyan\fP, \fBMagenta\fP, \fBYellow\fP,
+\fBBlack\fP, and \fBOpacity\fP
+
+When \fBchanneltype\fP is "All", the color samples are dithered into
+a gray level and then that gray level is stored in the three color
+channels. Separately, the opacity channel is dithered into a bilevel
+opacity value which is stored in the opacity channel.
+
+When \fBchanneltype\fP is "Intensity", only the color samples are
+dithered. When \fBchanneltype\fP is "opacity" or "matte", only the
+opacity channel is dithered. When a color channel is specified, only that
+channel is dithered.
+
+The choices for N are 2 through 7. The image is divided into
+NxN pixel tiles. In each tile, some or all pixels are turned to
+white depending on their intensity. For each N, (N**2)+1 levels
+of gray can be represented. For N == 2, 3, or 4, the pixels
+are turned to white in an order that maximizes dispersion (i.e.,
+reduces granularity), while
+for N == 5, 6, and 7, they are turned to white in an order that
+creates a roughly circular black blob in the middle of each tile.
+An attractive "half-tone" looking image can be obtained by first
+rotating the image 45 degrees, performing a 5x5 ordered-dither
+operation, then rotating it back to the original orientation and
+cropping to the original image dimensions. If the original image
+is gamma-encoded, it is adviseable to convert it to linear intensity
+first, e.g., with the "-gamma 0.45455" option.
+.TP
+.B "-output-directory \fI<directory>"\fP
+\fRoutput files to directory
+
+Use -output-directory to specify a directory under which to write the
+output files. Normally mogrify overwrites the input files but with this
+option the output files may be written to a different directory so that
+the input files are preserved. The algorithm used preserves all of the
+input path specification in the output path so that the user-specified
+input path (including any directory part) is appended to the output path.
+The user is responsible for creating the output directory.
+.TP
+.B "-orient \fI<orientation>"\fP
+\fRSet the image orientation attribute
+
+Sets the image orientation attribute. The image orientation attribute
+is compatible with the TIFF orientation tag (and the EXIF orientation
+tag). Accepted values are \fBundefined\fP, \fBTopLeft\fP,
+\fBTopRight\fP, \fBBottomRight\fP, \fBBottomLeft\fP,
+\fBLeftTop\fP, \fBRightTop\fP, \fBRightBottom\fP,
+\fBLeftBottom\fP, and hyphenated versions thereof
+(e.g. \fBleft-bottom\fP). Please note that GraphicsMagick does not
+include an EXIF editor so if an EXIF profile is written to the output
+image, the value in the EXIF profile might not match the image. It is
+possible for an image file to indicate its orientation in several
+different ways simultaneously.
+.TP
+.B "-page \fI<width>x<height>{+-}<x>{+-}<y>{%}{!}{<}{>}"\fP
+\fRsize and location of an image canvas
+
+Use this option to specify the dimensions of the
+\fIPostScript\fP page
+in dots per inch or a TEXT page in pixels. The choices for a PostScript
+page are:
+
+ 11x17 792 1224
+ Ledger 1224 792
+ Legal 612 1008
+ Letter 612 792
+ LetterSmall 612 792
+ ArchE 2592 3456
+ ArchD 1728 2592
+ ArchC 1296 1728
+ ArchB 864 1296
+ ArchA 648 864
+ A0 2380 3368
+ A1 1684 2380
+ A2 1190 1684
+ A3 842 1190
+ A4 595 842
+ A4Small 595 842
+ A5 421 595
+ A6 297 421
+ A7 210 297
+ A8 148 210
+ A9 105 148
+ A10 74 105
+ B0 2836 4008
+ B1 2004 2836
+ B2 1418 2004
+ B3 1002 1418
+ B4 709 1002
+ B5 501 709
+ C0 2600 3677
+ C1 1837 2600
+ C2 1298 1837
+ C3 918 1298
+ C4 649 918
+ C5 459 649
+ C6 323 459
+ Flsa 612 936
+ Flse 612 936
+ HalfLetter 396 612
+
+
+For convenience you can specify the page size by media (e.g. A4, Ledger,
+etc.). Otherwise, \fB-page\fP behaves much like
+\fB-geometry\fP (e.g. -page letter+43+43>).
+
+This option is also used to place subimages when writing to a multi-image
+format that supports offsets, such as GIF89 and MNG. When used for this
+purpose the offsets are always measured from the
+top left corner of the canvas and are not affected by the \fB-gravity\fP
+option.
+To position a GIF or MNG image, use \fB-page\fP\fI{+-}<x>{+-}<y>\fP
+(e.g. -page +100+200). When writing to a MNG file, a \fB-page\fP
+option appearing ahead of the first image in the sequence with nonzero
+width and height defines the width and height values that are written in
+the \fBMHDR\fP chunk. Otherwise, the MNG width and height are computed
+from the bounding box that contains all images in the sequence. When
+writing a GIF89 file, only the bounding box method is used to determine its
+dimensions.
+
+For a PostScript page, the image is sized as in \fB-geometry\fP and positioned
+relative to the lower left hand corner of the page by
+{+-}<\fBx\fP\fIoffset\fP>{+-}<\fBy\fP
+\fIoffset>\fP. Use
+-page 612x792>, for example, to center the
+image within the page. If the image size exceeds the PostScript page, it
+is reduced to fit the page.
+The default gravity for the \fB-page\fP
+option is \fINorthWest\fP, i.e., positive \fBx\fP and
+\fBy\fP \fIoffset\fP are measured rightward and downward from the top
+left corner of the page, unless the \fB-gravity\fP option is present with
+a value other than \fINorthWest\fP.
+
+The default page dimensions for a TEXT image is 612x792.
+
+This option is used in concert with \fB-density\fP.
+
+Use \fB+page\fP to remove the page settings for an image.
+.TP
+.B "-paint \fI<radius>"\fP
+\fRsimulate an oil painting
+
+Each pixel is replaced by the most frequent color in a circular neighborhood
+whose width is specified with \fIradius\fP.
+.TP
+.B "-pause \fI<seconds>"\fP
+\fRpause between animation loops [animate]
+
+Pause for the specified number of seconds before repeating the
+animation.
+.TP
+.B "-pause \fI<seconds>"\fP
+\fRpause between snapshots [import]
+
+Pause for the specified number of seconds before taking the next
+snapshot.
+.TP
+.B "-pen \fI<color>"\fP
+\fR(This option has been replaced by the -fill option)
+.TP
+.B "-ping"
+\fRefficiently determine image characteristics
+
+Use this option to disable reading the image pixels so that image
+characteristics such as the image dimensions may be obtained very
+quickly. For identify, use +ping to force reading the image pixels so
+that the pixel read rate may be included in the displayed information.
+.TP
+.B "-pointsize \fI<value>"\fP
+\fRpointsize of the PostScript, X11, or TrueType font
+.TP
+.B "-preview \fI<type>"\fP
+\fRimage preview type
+
+Use this option to affect the preview operation of an image (e.g.
+convert file.png -preview Gamma Preview:gamma.png). Choose
+from these previews:
+
+ Rotate
+ Shear
+ Roll
+ Hue
+ Saturation
+ Brightness
+ Gamma
+ Spiff
+ Dull
+ Grayscale
+ Quantize
+ Despeckle
+ ReduceNoise
+ AddNoise
+ Sharpen
+ Blur
+ Threshold
+ EdgeDetect
+ Spread
+ Shade
+ Raise
+ Segment
+ Solarize
+ Swirl
+ Implode
+ Wave
+ OilPaint
+ CharcoalDrawing
+ JPEG
+
+
+The default preview is \fBJPEG\fP.
+.TP
+.B "-process \fI<command>"\fP
+\fRprocess a sequence of images using a process module
+
+The command argument has the form \fBmodule=arg1,arg2,arg3,...,argN\fP
+where \fBmodule\fP is the name of the module to invoke (e.g. "analyze")
+and arg1,arg2,arg3,...,argN are an arbitrary number of arguments to
+pass to the process module.
+The sequence of images
+is terminated by the appearance of any option.
+
+If the \fB-process\fP
+option appears after all of the input images, all images are processed.
+.TP
+.B "-profile \fI<filename>"\fP
+\fRadd ICM, IPTC, or generic profile to image
+
+-profile filename adds an ICM (ICC color management), IPTC
+(newswire information), or a generic (including Exif) profile to the image
+.
+
+Use +profile icm, +profile iptc, or
++profile profile_name to remove the respective profile.
+Multiple profiles may be listed, separated by commas. Profiles may be
+excluded from subsequent listed matches by preceding their name with
+an exclamation point. For example, +profile '!icm,*' strips
+all profiles except for the ICM profile. Use identify
+-verbose to find out what profiles are in the image file. Use
++profile "*" to remove all profiles.
+Writing the image to a format that does not support profiles will
+of course also cause all profiles to be removed. The JPEG and PNG
+formats will store any profiles that have been read and not removed.
+In JPEG they are stored in APP1 markers, and in PNG they are stored
+as hex-coded binary in compressed zTXt chunks, except for the iCC
+chunk which is stored in the iCCP chunk.
+
+To extract a profile, the \fB-profile\fP option is not used. Instead,
+simply write the file to an image
+format such as \fIAPP1, 8BIM, ICM,\fP or \fIIPTC\fP.
+
+For example, to extract the Exif data (which is stored in JPEG files
+in the \fIAPP1\fP profile), use
+
+
+ gm convert cockatoo.jpg exifdata.app1
+
+Note that GraphicsMagick does not attempt to update any profile to
+reflect changes made to the image, e.g., rotation from portrait to landscape
+orientation, so it is possible that the preserved profile may contain
+invalid data.
+.TP
+.B "-preserve-timestamp"
+\fRpreserve the original timestamps of the file
+
+Use this option to preserve the original modification and access
+timestamps of the file, even if it has been modified.
+.TP
+.B "+progress"
+\fRdisable progress monitor and busy cursor
+
+By default, when an image is displayed, a progress monitor bar is shown
+in the top left corner of an existing image display window, and the
+current cursor is replaced with an hourglass cursor. Use \fB+progress\fP
+to disable the progress monitor and busy cursor during display operations.
+While the progress monitor is disabled for all operations, the busy
+cursor continues to be enabled for non-display operations such as image
+processing. This option is useful for non-interactive display operations,
+or when a "clean" look is desired.
+.TP
+.B "-quality \fI<value>"\fP
+\fRJPEG/MIFF/PNG/TIFF compression level
+ For the JPEG and MPEG image formats, quality is 0 (lowest image
+quality and highest compression) to 100 (best quality but least
+effective compression). The default quality is 75. Use the
+\fB-sampling-factor\fP option to specify the factors for chroma
+downsampling. To use the same quality value as that found by the JPEG
+decoder, use the -define jpeg:preserve-settings flag.
+
+For the MIFF image format, and the TIFF format while using ZIP
+compression, quality/10 is the zlib compression level, which is 0 (worst
+but fastest compression) to 9 (best but slowest). It has no effect on the
+image appearance, since the compression is always lossless.
+
+For the JPEG-2000 image format, quality is mapped using a non-linear
+equation to the compression ratio required by the Jasper library. This
+non-linear equation is intended to loosely approximate the quality
+provided by the JPEG v1 format. The default quality value 75 results in
+a request for 16:1 compression. The quality value 100 results in
+a request for non-lossy compression.
+
+For the MNG and PNG image formats, the quality value sets the zlib compression
+level (quality / 10) and filter-type (quality % 10). Compression levels
+range from 0 (fastest compression) to 100 (best but slowest). For compression
+level 0, the Huffman-only strategy is used, which is fastest but not
+necessarily the worst compression.
+
+If
+filter-type is 4 or less, the specified filter-type is used for all scanlines:
+
+ 0: none
+ 1: sub
+ 2: up
+ 3: average
+ 4: Paeth
+
+
+If filter-type is 5, adaptive filtering is used when quality is greater
+than 50 and the image does not have a color map, otherwise no filtering
+is used.
+
+If filter-type is 6, adaptive filtering
+with \fIminimum-sum-of-absolute-values\fP
+is used.
+
+Only if the output is MNG, if filter-type is 7, the LOCO color transformation
+and adaptive filtering with \fIminimum-sum-of-absolute-values\fP
+are used.
+
+The default is quality is 75, which means nearly the best compression with
+adaptive filtering. The quality setting has no effect on the appearance
+of PNG and MNG images, since the compression is always lossless.
+
+For further information, see the PNG
+specification.
+
+When writing a JNG image with transparency, two quality values are required,
+one for the main image and one for the grayscale image that conveys the
+opacity channel. These are written as a single integer equal to the main
+image quality plus 1000 times the opacity quality. For example, if you
+want to use quality 75 for the main image and quality 90 to compress
+the opacity data, use -quality 90075.
+
+For the PNM family of formats (PNM, PGM, and PPM) specify a quality
+factor of zero in order to obtain the ASCII variant of the format. Note
+that -compress \fInone\fP used to be used to trigger ASCII output but
+provided the opposite result of what was expected as compared with other
+formats.
+.TP
+.B "-raise \fI<width>x<height>"\fP
+\fRlighten or darken image edges
+
+This will create a 3-D effect. See \fB-geometry\fP for details
+details about the geometry specification. Offsets are not used.
+
+Use \fB-raise\fP to create a raised effect, otherwise use \fB+raise\fP.
+.TP
+.B "-random-threshold \fI<channeltype> <LOWxHIGH>"\fP
+\fRrandom threshold the image
+
+The channel or channels specified in the <channeltype> argument are
+reduced to binary, using an random-threshold method. The choices for
+\fBchanneltype\fP are \fBAll\fP, \fBIntensity\fP, \fBRed\fP,
+\fBGreen\fP, \fBBlue\fP, \fBCyan\fP, \fBMagenta\fP, \fBYellow\fP,
+\fBBlack\fP, and \fBOpacity\fP
+
+When \fBchanneltype\fP is "All", the color samples are thresholded into
+a graylevel and then that gray level is stored in the three color
+channels. Separately, the opacity channel is thresholded into a bilevel
+opacity value which is stored in the opacity channel. For each pixel, a
+new random number is used to establish the threshold to be used. The
+threshold never exceeds the specified maximum (HIGH) and is never less
+than the specified minimum (LOW).
+
+When \fBchanneltype\fP is "intensity", only the color samples are
+thresholded. When \fBchanneltype\fP is "opacity" or "matte", only the
+opacity channel is thresholded. The other named channels only threshold
+the associated channel.
+.TP
+.B "-recolor \fI<matrix>"\fP
+\fRapply a color translation matrix to image channels
+
+A user supplied color translation matrix (expressed as a text string)
+is used to translate/blend the image channels based on weightings in a
+supplied matrix which may be of order 3 (color channels only), 4
+(color channels plus opacity), or 5 (color channels plus opacity and
+offset). Values in the columns of the matrix (red, green, blue,
+opacity) are used as multipliers with the existing channel values and
+added together according to the rows of the matrix. Matrix values are
+floating point and may be negative. The offset column (column 5) is
+purely additive and is scaled such that 0.0 to 1.0 represents the
+maximum quantum range (but values are not limited to this range). The
+math for the color translation matrix is similar to that used by Adobe
+Flash except that the offset is scaled to 1.0 (divide Flash offset by
+255 for use with GraphicsMagick) so that the results are independent
+of quantum depth.
+
+An \fBidentity\fP matrix exists for each matrix order which
+results in no change to the image. The translation matrix should be
+based on an alteration of the identity matrix.
+
+Identity matrix of order 3
+
+ 1 0 0
+ 0 1 0
+ 0 0 1
+
+
+which may be formatted into a convenient matrix argument similar to
+(comma is treated as white space):
+
+ -recolor "1 0 0, 0 1 0, 0 0 1"
+
+
+Identity matrix of order 4
+
+ 1 0 0 0
+ 0 1 0 0
+ 0 0 1 0
+ 0 0 0 1
+
+
+Identity matrix of order 5. The last row is required to exist
+for the purpose of parsing, but is otherwise not used.
+
+ 1 0 0 0 0
+ 0 1 0 0 0
+ 0 0 1 0 0
+ 0 0 0 1 0
+ 0 0 0 0 1
+
+
+As an example, an image wrongly in BGR channel order may be converted
+to RGB using this matrix (blue->red, red->blue):
+
+ 0 0 1
+ 0 1 0
+ 1 0 0
+
+
+and an RGB image using standard Rec.709 primaries may be converted
+to grayscale using this matrix of standard weighting factors:
+
+ 0.2126 0.7152 0.0722
+ 0.2126 0.7152 0.0722
+ 0.2126 0.7152 0.0722
+
+
+and contrast may be reduced by scaling down by 80% and adding a 10%
+offset:
+
+ 0.8 0.0 0.0 0.0 0.1
+ 0.0 0.8 0.0 0.0 0.1
+ 0.0 0.0 0.8 0.0 0.1
+ 0.0 0.0 0.0 0.8 0.1
+ 0.0 0.0 0.0 0.0 1.0
+
+.TP
+.B "-red-primary \fI<x>,<y>"\fP
+\fRred chromaticity primary point
+.TP
+.B "-region \fI<width>x<height>{+-}<x>{+-}<y>"\fP
+\fRapply options to a portion of the image
+
+The \fIx\fP and \fIy\fP offsets are treated in the same manner as in \fB-crop\fP.
+.TP
+.B "-remote"
+\fRperform a X11 remote operation
+
+The \fB-remote\fP command sends a command to a "gm display" or "gm
+animate" which is already running. The only command recognized at this
+time is the name of an image file to load. This capability is very
+useful to load new images without needing to restart GraphicsMagick
+(e.g. for a slide-show or to use GraphicsMagick as the display engine
+for a different GUI). Also see the \fB+progress\fP option for a way
+to disable progress indication for a clean look while loading new images.
+.TP
+.B "-render"
+\fRrender vector operations
+
+Use \fB+render\fP to turn off rendering vector operations. This is
+useful when saving the result to vector formats such as MVG or SVG.
+.TP
+.B "-repage \fI <width>x<height>+xoff+yoff[!]"\fP
+\fRAdjust image page offsets
+
+Adjust the current image page canvas and position based on a relative
+page specification. This option may be used to change the location of
+a subframe (e.g. part of an animation) prior to composition. If the
+geometry specification is absolute (includes a '!'), then the offset
+adjustment is absolute and there is no adjustment to page width and
+height, otherwise the page width and height values are also adjusted
+based on the current image dimensions. Use \fB+repage\fP to set the
+image page offsets to default.
+.TP
+.B "-resample \fI<horizontal>x<vertical>"\fP
+\fRResample image to specified horizontal and vertical resolution
+
+Resize the image so that its rendered size remains the same as the
+original at the specified target resolution. Either the current image
+resolution units or the previously set with \fB-units\fP are used to
+interpret the argument. For example, if a 300 DPI image renders at 3
+inches by 2 inches on a 300 DPI device, when the image has been
+resampled to 72 DPI, it will render at 3 inches by 2 inches on a 72
+DPI device. Note that only a small number of image formats
+(e.g. JPEG, PNG, and TIFF) are capable of storing the image
+resolution. For formats which do not support an image resolution, the
+original resolution of the image must be specified via \fB-density\fP
+on the command line prior to specifying the resample resolution.
+
+Note that Photoshop stores and obtains image resolution from a
+proprietary embedded profile. If this profile exists in the image,
+then Photoshop will continue to treat the image using its former
+resolution, ignoring the image resolution specified in the standard
+file header.
+
+Some image formats (e.g. PNG) require use of metric or english units
+so even if the original image used a particular unit system, if it is
+saved to a different format prior to resampling, then it may be
+necessary to specify the desired resolution units using \fB-units\fP
+since the original units may have been lost. In other words, do not
+assume that the resolution units are restored if the image has been
+saved to a file.
+.TP
+.B "-resize \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image
+
+This is an alias for the \fB-geometry\fP option and it behaves in the
+same manner. If the \fB-filter\fP option precedes the \fB-resize\fP
+option, the specified filter is used.
+
+There are some exceptions:
+
+When used as a \fIcomposite\fP option, \fB-resize\fP conveys the
+preferred size of the output image, while \fB-geometry\fP conveys the
+size and placement of the \fIcomposite image\fP within the main
+image.
+
+When used as a \fImontage\fP option, \fB-resize\fP conveys the preferred
+size of the montage, while \fB-geometry\fP conveys
+information about the tiles.
+.TP
+.B "-roll \fI{+-}<x>{+-}<y>"\fP
+\fRroll an image vertically or horizontally
+
+See \fB-geometry\fP for details the geometry specification. The
+\fIx\fP and \fIy\fP offsets are not affected by the \fB-gravity\fP
+option.
+
+A negative \fIx\fP offset rolls the image left-to-right. A negative
+\fIy\fP offset rolls the image top-to-bottom.
+.TP
+.B "-rotate \fI<degrees>{<}{>}"\fP
+\fRrotate the image
+
+Positive angles rotate the image in a clockwise direction while
+negative angles rotate counter-clockwise.
+
+Use > to rotate the image only if its width exceeds the
+height. < rotates the image \fIonly\fP if its width is less
+than the height. For example, if you specify -rotate "-90>"
+and the image size is 480x640, the image is not rotated. However, if
+the image is 640x480, it is rotated by -90 degrees. If you use
+> or <, enclose it in quotation marks to prevent it
+from being misinterpreted as a file redirection.
+
+Empty triangles left over from rotating the image are filled with the
+color defined as \fBbackground\fP (class \fBbackgroundColor\fP).
+The color is specified using the format described under the
+\fB-fill\fP option.
+.TP
+.B "-sample \fI<geometry>"\fP
+\fRscale image using pixel sampling
+
+See \fB-geometry\fP for details about
+the geometry specification.
+\fB-sample\fP ignores the \fB-filter\fP selection if the \fB-filter\fP option
+is present. Offsets, if present in the geometry string, are ignored, and
+the \fB-gravity\fP option has no effect.
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+
+This option specifies the sampling factors to be used by the DPX, JPEG,
+MPEG, or YUV encoders for chroma downsampling. The sampling factor must
+be specified while reading the raw YUV format since it is not preserved
+in the file header.
+Industry-standard video subsampling notation such as "4:2:2" may also
+be used to specify the sampling factors. "4:2:2" is equivalent to a
+specification of "2x1"
+
+The JPEG decoder obtains the original sampling factors (and quality
+settings) when a JPEG file is read. To re-use the original sampling
+factors (and quality setting) when JPEG is output, use the -define
+jpeg:preserve-settings flag.
+.TP
+.B "-scale \fI<geometry>"\fP
+\fRscale the image.
+
+See \fB-geometry\fP for details about
+the geometry specification. \fB-scale\fP uses a simpler, faster algorithm,
+and it ignores the \fB-filter\fP selection if the \fB-filter\fP option
+is present. Offsets, if present in the geometry string, are ignored, and
+the \fB-gravity\fP option has no effect.
+.TP
+.B "-scene \fI<value>"\fP
+\fRset scene number
+
+This option sets the scene number of an image or the first image in
+an image sequence.
+.TP
+.B "-scenes \fI<value-value>"\fP
+\fRrange of image scene numbers to read
+
+Each image in the range is read
+with the filename followed by a period (\fB.\fP) and the decimal scene
+number. You
+can change this behavior by embedding a \fB%d, %0Nd, %o, %0No, %x, or %0Nx
+printf\fP format specification in the file name. For example,
+
+ gm montage -scenes 5-7 image.miff montage.miff
+
+
+makes a montage of files image.miff.5, image.miff.6, and image.miff.7, and
+
+ gm animate -scenes 0-12 image%02d.miff
+
+
+animates files image00.miff, image01.miff, through image12.miff.
+.TP
+.B "-screen"
+\fRspecify the screen to capture
+
+This option indicates that the GetImage request used to obtain the image
+should be done on the root window, rather than directly on the specified
+window. In this way, you can obtain pieces of other windows that overlap
+the specified window, and more importantly, you can capture menus or other
+popups that are independent windows but appear over the specified window.
+.TP
+.B "-set \fI<attribute> <value>"\fP
+\fRset an image attribute
+
+Set a named image attribute. The attribute is set on the current
+(previously specified on command line) image.
+.TP
+.B "+set \fI<attribute>"\fP
+\fRunset an image attribute
+
+Unset a named image attribute. The attribute is removed from the current
+(previously specified on command line) image.
+.TP
+.B "-segment \fI<cluster threshold>x<smoothing threshold>"\fP
+\fRsegment an image
+
+Segment an image by analyzing the histograms of the color components and
+identifying units that are homogeneous with the fuzzy c-means technique.
+
+Segmentation is a very useful fast and and approximate color quantization
+algorithm for scanned printed pages or scanned cartoons. It may also be
+used as a special effect. Specify \fIcluster threshold\fP as the minimum
+percentage of total pixels in a cluster before it is considered valid.
+For huge images containing small detail, this may need to be a tiny
+fraction of a percent (e.g. 0.015) so that important detail is not lost.
+\fISmoothing threshold\fP eliminates noise in the second derivative of
+the histogram. As the value is increased, you can expect a smoother
+second derivative. The default is 1.5. Add the \fI-verbose\fP option to
+see a dump of cluster statistics given the parameters used. The
+statistics may be used as a guide to help fine tune the options.
+.TP
+.B "-shade \fI<azimuth>x<elevation>"\fP
+\fRshade the image using a distant light source
+
+Specify \fIazimuth\fP and \fIelevation\fP as the position of the light
+source. Use \fB+shade\fP to return the shading results as a grayscale
+image.
+.TP
+.B "-shadow \fI<radius>{x<sigma>}"\fP
+\fRshadow the montage
+.TP
+.B "-shared-memory"
+\fRuse shared memory
+
+This option specifies whether the utility should attempt to use shared
+memory for pixmaps. GraphicsMagick must be compiled with shared
+memory support, and the display must support the \fIMIT-SHM\fP
+extension. Otherwise, this option is ignored. The default is
+\fBTrue\fP.
+.TP
+.B "-sharpen \fI<radius>{x<sigma>}"\fP
+\fRsharpen the image
+
+Use a Gaussian operator of the given radius and standard deviation
+(sigma).
+.TP
+.B "-shave \fI<width>x<height>{%}"\fP
+\fRshave pixels from the image edges
+
+Specify the width of the region to be removed from both
+sides of the image and the height of the regions to be removed from
+top and bottom.
+.TP
+.B "-shear \fI<x degrees>x<y degrees>"\fP
+\fRshear the image along the X or Y axis
+
+Use the specified positive or negative shear angle.
+
+Shearing slides one edge of an image along the X or Y axis, creating a
+parallelogram. An X direction shear slides an edge along the X axis,
+while a Y direction shear slides an edge along the Y axis. The amount
+of the shear is controlled by a shear angle. For X direction shears,
+\fIx degrees\fP is measured relative to the Y axis, and similarly,
+for Y direction shears \fIy degrees\fP is measured relative to the X
+axis.
+
+Empty triangles left over from shearing the image are filled with the
+color defined as \fBbackground\fP (class \fBbackgroundColor\fP).
+The color is specified using the format described under the
+\fB-fill\fP option.
+.TP
+.B "-silent"
+\fRoperate silently
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+
+Use this option to specify the width and height of raw images whose
+dimensions are unknown such as \fBGRAY\fP, \fBRGB\fP, or
+\fBCMYK\fP. In addition to width and height, use \fB-size\fP with an
+offset to skip any header information in the image or tell the number
+of colors in a \fBMAP\fP image file, (e.g. -size 640x512+256).
+
+For Photo CD images, choose from these sizes:
+
+ 192x128
+ 384x256
+ 768x512
+ 1536x1024
+ 3072x2048
+
+
+Finally, use this option to choose a particular resolution layer of a JBIG
+or JPEG image (e.g. -size 1024x768).
+.TP
+.B "-snaps \fI<value>"\fP
+\fRnumber of screen snapshots
+
+Use this option
+to grab more than one image from the X server screen, to create
+an animation sequence.
+.TP
+.B "-solarize \fI<factor>"\fP
+\fRnegate all pixels above the threshold level
+
+Specify \fIfactor\fP as the
+percent threshold of the intensity (0 - 99.9%).
+
+This option produces a \fIsolarization\fP effect seen when exposing a
+photographic film to light during the development process.
+.TP
+.B "-spread \fI<amount>"\fP
+\fRdisplace image pixels by a random amount
+
+\fIAmount\fP defines the size of the neighborhood around each pixel to
+choose a candidate pixel to swap.
+.TP
+.B "-stegano \fI<offset>"\fP
+\fRhide watermark within an image
+
+Use an offset to start the image hiding some number of pixels from the
+beginning of the image. Note this offset and the image size. You will
+need this information to recover the steganographic image
+(e.g. display -size 320x256+35 stegano:image.png).
+.TP
+.B "-stereo"
+\fRcomposite two images to create a stereo anaglyph
+
+The left side of the stereo pair is saved as the red channel of the output
+image. The right side is saved as the green channel. Red-green stereo
+glasses are required to properly view the stereo image.
+.TP
+.B "-strip"
+\fRremove all profiles and text attributes from the image
+
+All embedded profiles and text attributes are stripped from the image.
+This is useful for images used for the web, or when output files need
+to be as small as possible
+
+Be careful not to use this option to remove author, copyright, and
+license information that you are required to retain when redistributing
+an image.
+.TP
+.B "-stroke \fI<color>"\fP
+\fRcolor to use when stroking a graphic primitive
+
+The color is specified using the format described under the \fB-fill\fP
+option.
+
+See \fB-draw\fP for further details.
+.TP
+.B "-strokewidth \fI<value>"\fP
+\fRset the stroke width
+
+See \fB-draw\fP for further details.
+.TP
+.B "-swirl \fI<degrees>"\fP
+\fRswirl image pixels about the center
+
+\fIDegrees\fP defines the tightness of the swirl.
+.TP
+.B "-text-font \fI<name>"\fP
+\fRfont for writing fixed-width text
+
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point \fICourier\fP.
+
+You can tag a font to specify whether it is a PostScript, TrueType, or
+X11 font. For example, Courier.ttf is a TrueType font
+and x:fixed is X11.
+.TP
+.B "-texture \fI<filename>"\fP
+\fRname of texture to tile onto the image background
+.TP
+.B "-threshold \fI<value>{%}"\fP
+\fRthreshold the image
+
+Modify the image such that any pixel sample with an intensity value
+greater than the threshold is assigned the maximum intensity (white), or
+otherwise is assigned the minimum intensity (black). If a percent prefix
+is applied, then the threshold is a percentage of the available range.
+
+To efficiently create a black and white image from a color image, use
+
+ gm convert -threshold 50% in.png out.png
+
+
+The optimum threshold value depends on the nature of the image.
+In order to threshold individual channels, use the \fB-operator\fP
+subcommand with it's \fBThreshold\fP, \fBThreshold-White\fP, or
+\fBThreshold-Black\fP options.
+.TP
+.B "-thumbnail \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image (quickly)
+
+The \fB-thumbnail\fP command resizes the image as quickly as
+possible, with more concern for speed than resulting image quality.
+Regardless, resulting image quality should be acceptable for many
+uses. It is primarily intended to be used to generate smaller
+versions of the image, but may also be used to enlarge the image. The
+\fB-thumbnail\fP \fBgeometry\fP argument observes the same syntax
+and rules as it does for \fB-resize\fP.
+.TP
+.B "-tile \fI<filename>"\fP
+\fRtile image when filling a graphic primitive
+.TP
+.B "-tile \fI<geometry>"\fP
+\fRlayout of images [\fImontage\fP]
+.TP
+.B "-title \fI<string>"\fP
+\fRassign title to displayed image [\fIanimate, display, montage\fP]
+
+Use this option to assign a specific title to the image. This is
+assigned to the image window and is typically displayed in the window
+title bar. Optionally you can include the image filename, type,
+width, height, Exif data, or other image attribute by embedding
+special format characters described under the \fB-format\fP
+option.
+
+For example,
+
+ -title "%m:%f %wx%h"
+
+
+produces an image title of MIFF:bird.miff 512x480 for an image
+titled bird.miff and whose width is 512 and height is 480.
+.TP
+.B "-transform"
+\fRtransform the image
+
+This option applies the transformation matrix from a previous
+\fB-affine\fP option.
+
+ gm convert -affine 2,2,-2,2,0,0 -transform bird.ppm bird.jpg
+
+.TP
+.B "-transparent \fI<color>"\fP
+\fRmake this color transparent within the image
+
+The color is specified using the format described under the \fB-fill\fP
+option.
+.TP
+.B "-treedepth \fI<value>"\fP
+\fRtree depth for the color reduction algorithm
+
+Normally, this integer value is zero or one. A value of zero or one
+causes the use of an optimal tree depth for the color reduction
+algorithm
+
+An optimal depth generally allows the best representation of the source
+image with the fastest computational speed and the least amount of memory.
+However, the default depth is inappropriate for some images. To assure
+the best representation, try values between 2 and 8 for this parameter.
+Refer to
+quantize for more details.
+
+The \fB-colors\fP or \fB-monochrome\fP option, or writing to an image
+format which requires color reduction, is required for this option to
+take effect.
+.TP
+.B "-trim"
+\fRtrim an image
+
+This option removes any edges that are exactly the same color as the
+corner pixels. Use \fB-fuzz\fP to make \fB-trim\fP remove edges that
+are nearly the same color as the corner pixels.
+.TP
+.B "-type \fI<type>"\fP
+\fRthe image type
+
+Choose from:
+\fBBilevel\fP, \fBGrayscale\fP, \fBPalette\fP,
+\fBPaletteMatte\fP, \fBTrueColor\fP, \fBTrueColorMatte\fP,
+\fBColorSeparation\fP, \fBColorSeparationMatte\fP, or \fBOptimize\fP.
+
+Normally, when a format supports different subformats such as bilevel,
+grayscale, palette, truecolor, and truecolor+alpha, the encoder will try
+to choose a suitable subformat based on the nature of the image. The
+\fB-type\fP option may be used to tailor the output subformat. By
+default the output subformat is based on readily available image
+information and is usually similar to the input format.
+
+Specify -type Optimize in order to enable inspecting all pixels
+(if necessary) in order to find the most efficient subformat. Inspecting
+all of the pixels may be slow for very large images, particularly if they
+are stored in a disk cache. If an RGB image contains only gray pixels,
+then every pixel in the image must be inspected in order to decide that
+the image is actually grayscale!
+
+Sometimes a specific subformat is desired. For example, to force a JPEG
+image to be written in TrueColor RGB format even though only gray pixels
+are present, use
+
+ gm convert bird.pgm -type TrueColor bird.jpg
+
+
+Similarly, using -type TrueColorMatte will force the encoder to
+write an alpha channel even though the image is opaque, if the output
+format supports transparency.
+
+Some pseudo-formats (e.g. the XC format) will respect the requested
+type if it occurs previously on the command line. For example, to obtain
+a DirectClass solid color canvas image rather than PsuedoClass, use
+
+ gm convert -size 640x480 -type TrueColor xc:red red.miff
+
+
+Likewise, specify \fB-type\fP \fBBilevel\fP, \fBGrayscale\fP,
+\fBTrueColor\fP, or \fBTrueColorMatte\fP prior to reading a Postscript
+(or PDF file) in order to influence the type of image that Ghostcript
+returns. Reading performance will be dramatically improved for
+black/white Postscript if \fBBilevel\fP is specified, and will be
+considerably faster if \fBGrayscale\fP is specified.
+.TP
+.B "-update \fI<seconds>"\fP
+\fR
+detect when image file is modified and redisplay.
+
+Suppose that while you are displaying an image the file that is currently
+displayed is over-written.
+\fBdisplay\fP will automatically detect that
+the input file has been changed and update the displayed image accordingly.
+.TP
+.B "-units \fI<type>"\fP
+\fRthe units of image resolution
+
+Choose from: \fBUndefined\fP, \fBPixelsPerInch\fP, or
+\fBPixelsPerCentimeter\fP. This option is normally used in conjunction
+with the \fB-density\fP option.
+.TP
+.B "-unsharp \fI<radius>{x<sigma>}{+<amount>}{+<threshold>}"\fP
+\fRsharpen the image with an unsharp mask operator
+
+The \fB-unsharp\fP option sharpens an image. The image is convolved
+with a Gaussian operator of the given radius and standard deviation
+(sigma). For reasonable results, radius should be larger than sigma. Use
+a radius of 0 to have the method select a suitable radius.
+
+The parameters are:
+
+.in 15
+
+.in 15
+.B "radius"
+.in 20
+ \fR
+.in 20
+
+The radius of the Gaussian, in pixels, not counting the center pixel (default 0).
+
+.in 15
+.in 15
+.B "sigma"
+.in 20
+ \fR
+.in 20
+
+The standard deviation of the Gaussian, in pixels (default 1.0).
+
+.in 15
+.in 15
+.B "amount"
+.in 20
+ \fR
+.in 20
+
+The percentage of the difference between the original and the blur image that
+is added back into the original (default 1.0).
+
+.in 15
+.in 15
+.B "threshold"
+.in 20
+ \fR
+.in 20
+
+The threshold, as a fraction of MaxRGB, needed to apply the difference
+amount (default 0.05).
+
+.in 15
+
+
+.TP
+.B "-use-pixmap"
+\fRuse the pixmap
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+
+This information is printed: image scene number; image name; image size;
+the image class (\fIDirectClass\fP or \fIPseudoClass\fP); the total
+number of unique colors; and the number of seconds to read and transform
+the image. If the image is \fIDirectClass\fP, the total number of unique
+colors is not displayed unless \fB-verbose\fP is specified twice since
+it may take quite a long time to compute, particularly for deep images.
+If the image is \fIPseudoClass\fP then its pixels are defined by indexes
+into a colormap. If the image is \fIDirectClass\fP then each pixel
+includes a complete and independent color specification.
+
+If \fB-colors\fP is also specified, the total unique colors in the image
+and color reduction error values are printed. Refer to quantize
+for a description of these values.
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+.TP
+.B "-view \fI<string>"\fP
+\fRFlashPix viewing parameters
+.TP
+.B "-virtual-pixel \fI<method>"\fP
+\fRspecify contents of "virtual pixels"
+
+This option
+defines "virtual pixels" for use in operations that can access pixels outside
+the boundaries of an image.
+
+Choose from these methods:
+
+.in 15
+
+.in 15
+.B "Constant"
+.in 20
+ \fR
+.in 20
+
+Use the image background color.
+
+.in 15
+.in 15
+.B "Edge"
+.in 20
+ \fR
+.in 20
+
+Extend the edge pixel toward infinity (default).
+
+.in 15
+.in 15
+.B "Mirror"
+.in 20
+ \fR
+.in 20
+
+Mirror the image.
+
+.in 15
+.in 15
+.B "Tile"
+.in 20
+ \fR
+.in 20
+
+Tile the image.
+
+.in 15
+
+
+
+This option affects operations that use
+virtual pixels such as \fB-blur\fP, \fB-sharpen\fP, \fB-wave\fP, etc.
+.TP
+.B "-visual \fI<type>"\fP
+\fRanimate images using this X visual type
+
+Choose from these visual classes:
+
+ StaticGray
+ GrayScale
+ StaticColor
+ PseudoColor
+ TrueColor
+ DirectColor
+ default
+ visual id
+
+
+The X server must support the visual you choose, otherwise an error occurs.
+If a visual is not specified, the visual class that can display the most
+simultaneous colors on the default screen is chosen.
+.TP
+.B "-watermark \fI<brightness>x<saturation>"\fP
+\fRpercent brightness and saturation of a watermark
+.TP
+.B "-wave \fI<amplitude>x<wavelength>"\fP
+\fRalter an image along a sine wave
+
+Specify \fIamplitude\fP and \fIwavelength\fP
+of the wave.
+.TP
+.B "-white-point \fI<x>,<y>"\fP
+\fRchromaticity white point
+.TP
+.B "-white-threshold \fIred[,green][,blue][,opacity]"\fP
+\fRpixels above the threshold become white
+
+Use \fB-white-threshold\fP to set pixels with values above the specified
+threshold to maximum value (white). If only one value is supplied, or the
+red, green, and blue values are identical, then intensity thresholding is
+used. If the color threshold values are not identical then channel-based
+thresholding is used, and color distortion will occur. Specify a negative
+value (e.g. -1) if you want a channel to be ignored but you do want to
+threshold a channel later in the list. If a percent (%) symbol is
+appended, then the values are treated as a percentage of maximum
+range.
+.TP
+.B "-window \fI<id>"\fP
+\fRmake image the background of a window
+
+\fIid\fP can be a window id or name. Specify \fBroot\fP to
+select X's root window as the target window.
+
+By default the image is tiled onto the background of the target
+window. If \fBbackdrop\fP or \fB-geometry\fP are
+specified, the image is surrounded by the background color. Refer to
+\fBX RESOURCES\fP for details.
+
+The image will not display on the root window if the image has more
+unique colors than the target window colormap allows. Use
+\fB-colors\fP to reduce the number of colors.
+.TP
+.B "-window-group"
+\fRspecify the window group
+.TP
+.B "-write \fI<filename>"\fP
+\fRwrite an intermediate image [\fIconvert, composite\fP]
+
+The current image is written to the specified filename and then
+processing continues using that image. The following is an example of how
+several sizes of an image may be generated in one command (repeat as
+often as needed):
+
+ gm convert input.jpg -resize 50% -write input50.jpg \\
+ -resize 25% input25.jpg
+
+.TP
+.B "-write \fI<filename>"\fP
+\fRwrite the image to a file [\fIdisplay\fP]
+
+If \fIfilename\fP already exists, you will be prompted as to whether it should
+be overwritten.
+
+By default, the image is written in the format that it was read in as.
+To specify a particular image format, prefix \fIfilename\fP with the
+image type and a colon (e.g., ps:image) or specify the image type as
+the filename suffix (e.g., image.ps). Specify file as - for standard
+output. If file has the extension \fB.Z\fP or \fB.gz\fP, the file
+size is \fBcompressed\fP using compress or \fBgzip\fP
+respectively. Precede the image file name with | to pipe to a system
+command.
+
+Use \fB-compress\fP to specify the type of image compression.
+
+The equivalent X resource for this option is
+\fBwriteFilename\fP (class \fBWriteFilename\fP).
+See
+"X Resources", below,
+for details.
+.SH ENVIRONMENT
+.TP
+.B "COLUMNS"
+\fROutput screen width. Used when formatting text for the screen. Many
+Unix systems keep this shell variable up to date, but it may need to be
+explicitly exported in order for GraphicsMagick to see it.
+.TP
+.B "DISPLAY"
+\fRX11 display ID (host, display number, and screen in the form
+hostname:display.screen).
+.TP
+.B "HOME"
+\fRLocation of user's home directory. GraphicsMagick searches for
+configuration files in $HOME/.magick if the directory exists. See
+\fBMAGICK_CODER_MODULE_PATH\fP, \fBMAGICK_CONFIGURE_PATH\fP, and
+\fBMAGICK_FILTER_MODULE_PATH\fP if more flexibility is needed.
+.TP
+.B "MAGICK_ACCESS_MONITOR"
+\fRWhen set to \fBTRUE\fP, command line monitor mode (enabled by
+\fB-monitor\fP) will also show files accessed (including temporary
+files) and any external commands which are executed. This is useful
+for debugging, but also illustrates arguments made available to an
+access handler registered by the
+\fBMagickSetConfirmAccessHandler()\fP C library function.
+.TP
+.B "MAGICK_CODER_STABILITY"
+\fRThe minimum coder stability level before it will be used. The
+available levels are \fBPRIMARY\fP, \fBSTABLE\fP, \fBUNSTABLE\fP,
+and \fBBROKEN\fP. The default minimum level is \fBUNSTABLE\fP,
+which means that all available working coders will be used. The
+purpose of this option is to reduce the security exposure (or apparent
+complexity) due to the huge number of formats supported. Coders at the
+\fBPRIMARY\fP level are commonly used formats with very well
+maintained implementations. Coders at the \fBSTABLE\fP level are
+reasonably well maintained but represent less used formats. Coders at
+the \fBUNSTABLE\fP level either have weak implementations, the file
+format itself is weak, or the probability the coder will be needed is
+vanishingly small. Coders at the \fBBROKEN\fP level are known to
+often not work properly or might not be useful in their current state
+at all.
+.TP
+.B "MAGICK_CODER_MODULE_PATH"
+\fRSearch path to use when searching for image format coder modules.
+This path allows the user to arbitrarily extend the image formats
+supported by GraphicsMagick by adding loadable modules to an arbitrary
+location rather than copying them into the GraphicsMagick installation
+directory. The formatting of the search path is similar to operating
+system search paths (i.e. colon delimited for Unix, and semi-colon
+delimited for Microsoft Windows). This user specified search path is used
+before trying the default search path.
+.TP
+.B "MAGICK_CONFIGURE_PATH"
+\fRSearch path to use when searching for configuration (.mgk) files.
+The formatting of the search path is similar to operating system search
+paths (i.e. colon delimited for Unix, and semi-colon delimited for
+Microsoft Windows). This user specified search path is used before trying
+the default search path.
+.TP
+.B "MAGICK_DEBUG"
+\fRDebug options (see \fB-debug\fP for details). Setting debug
+options via an environment variable is currently necessary to see the
+complete initialization process.
+.TP
+.B "MAGICK_FILTER_MODULE_PATH"
+\fRSearch path to use when searching for filter process modules
+(invoked via \fB-process\fP). This path allows the user to arbitrarily
+extend GraphicsMagick's image processing functionality by adding loadable
+modules to an arbitrary location rather than copying them into the
+GraphicsMagick installation directory. The formatting of the search path
+is similar to operating system search paths (i.e. colon delimited for
+Unix, and semi-colon delimited for Microsoft Windows). This user
+specified search path is used before trying the default search path.
+.TP
+.B "MAGICK_GHOSTSCRIPT_PATH"
+\fRFor Microsoft Windows, specify the path to the Ghostscript
+installation rather than searching for it via the Windows registry.
+This helps in case Ghostscript is not installed via the Ghostscript
+Windows installer or the user wants more control over the Ghostscript
+used.
+.TP
+.B "MAGICK_HOME"
+\fRPath to top of GraphicsMagick installation directory. Only observed
+by "uninstalled" builds of GraphicsMagick which do not have their location
+hard-coded or set by an installer.
+.TP
+.B "MAGICK_MMAP_READ"
+\fRIf \fBMAGICK_MMAP_READ\fP is set to \fBTRUE\fP, GraphicsMagick
+will attempt to memory-map the input file for reading. This usually
+substantially improves repeated read performance since the file is
+already in memory after the first time it has been read. However,
+testing shows that performance may be reduced for files accessed for
+the first time since data is accessed via page-faults (upon first
+access) and many operating systems fail to do sequential read-ahead of
+memory mapped files, and particularly if those files are accessed over
+a network. If many large input files are read, then enabling this
+option may harm performance by overloading the operating system's VM
+system as it then needs to free unmapped pages and map new ones.
+.TP
+.B "MAGICK_IO_FSYNC"
+\fRIf \fBMAGICK_IO_FSYNC\fP is set to \fBTRUE\fP, then GraphicsMagick
+will request that the output file is fully flushed and synchronized to
+disk when it is closed. This incurs a performance penalty, but has the
+benefit that if the power fails or the system crashes, the file should be
+valid on disk. If image files are referenced from a database, then this
+option helps assure that the files referenced by the database are
+valid.
+.TP
+.B "MAGICK_IOBUF_SIZE"
+\fRThe amount of I/O buffering (in bytes) to use when reading and
+writing encoded files. The default is 16384, which is observed to work
+well for many cases. The best value for a local filesystem is usually the
+the native filesystem block size (e.g. 4096, 8192, or even 131,072 for
+ZFS) in order to minimize the number of physical disk I/O operations.
+I/O performance to files accessed over a network may benefit
+significantly by tuning this option. Larger values are not necessarily
+better (they may be slower!), and there is rarely any benefit from using
+values larger than 32768. Use convert's \fB-verbose\fP option in order
+to evaluate read and write rates in pixels per second while keeping in
+mind that the operating system will try to cache files in RAM.
+.TP
+.B "MAGICK_LIMIT_DISK"
+\fRMaximum amount of disk space allowed for use by the pixel cache.
+.TP
+.B "MAGICK_LIMIT_FILES"
+\fRMaximum number of open files.
+.TP
+.B "MAGICK_LIMIT_MAP"
+\fRMaximum size of a memory mapped file allocation. A memory mapped
+file consumes memory when the file is accessed, although the system
+may reclaim such memory when needed.
+.TP
+.B "MAGICK_LIMIT_MEMORY"
+\fRMaximum amount of memory to allocate from the heap.
+.TP
+.B "MAGICK_LIMIT_PIXELS"
+\fRMaximum number of total pixels (image rows times image colums) to
+allow for any image which is requested to be created or read. This is
+useful to place a limit on how large an image may be. If the input
+image file has image dimensions larger than the pixel limit, then the
+image memory allocation is denied and an error is returned
+immediately. This is a per-image limit and does not limit the total
+number of pixels due to multiple image frames/pages (e.g. multi-page
+document or an animation).
+.TP
+.B "MAGICK_LIMIT_WIDTH"
+\fRMaximum pixel width of an image read, or created.
+.TP
+.B "MAGICK_LIMIT_HEIGHT"
+\fRMaximum pixel height of an image read, or created.
+.TP
+.B "MAGICK_TMPDIR"
+\fRPath to directory where GraphicsMagick should write temporary
+files. The default is to use the system default, or the location set by
+\fBTMPDIR\fP.
+.TP
+.B "TMPDIR"
+\fRFor POSIX-compatible systems (Unix-compatible), the path to the
+directory where all applications should write temporary files.
+Overridden by \fBMAGICK_TMPDIR\fP if it is set.
+.TP
+.B "TMP \fIor TEMP"\fP
+\fRFor Microsoft Windows, the path to the directory where applications
+should write temporary files. Overridden by \fBMAGICK_TMPDIR\fP if it
+is set.
+.TP
+.B "OMP_NUM_THREADS"
+\fRAs per the OpenMP standard, this specifies the number of threads to
+use in parallel regions. Some compilers default the number of threads to
+use to the number of processor cores available while others default to
+just one thread. See the OpenMP specification for other standard
+adjustments and your compiler's manual for vendor-specific settings.
+.SH CONFIGURATION FILES
+GraphicsMagick uses a number of XML format configuration files:
+.TP
+.B "colors.mgk"
+\fRcolors configuration file
+
+ <?xml version="1.0"?>
+ <colormap>
+ <color name="AliceBlue" red="240" green="248" blue="255"
+ compliance="SVG, X11, XPM" />
+ </colormap>
+
+.TP
+.B "delegates.mgk"
+\fRdelegates configuration file
+.TP
+.B "log.mgk"
+\fRlogging configuration file
+
+ <?xml version="1.0"?>
+ <magicklog>
+ <log events="None" />
+ <log output="stdout" />
+ <log filename="Magick-%d.log" />
+ <log generations="3" />
+ <log limit="2000" />
+ <log format="%t %r %u %p %m/%f/%l/%d:\\n %e" />
+ </magicklog>
+
+.TP
+.B "modules.mgk"
+\fRloadable modules configuration file
+
+ <?xml version="1.0"?>
+ <modulemap>
+ <module magick="8BIM" name="META" />
+ </modulemap>
+
+.TP
+.B "type.mgk"
+\fRmaster type (fonts) configuration file
+
+ <?xml version="1.0"?>
+ <typemap>
+ <\fB\fPinclude file="type-windows.mgk" />
+ <type
+ name="AvantGarde-Book"
+ fullname="AvantGarde Book"
+ family="AvantGarde"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/local/share/ghostscript/fonts/a010013l.afm"
+ glyphs="/usr/local/share/ghostscript/fonts/a010013l.pfb"
+ />
+ </typemap>
+
+.SH GM ANIMATE
+
+\fBAnimate\fP displays a sequence of images on any workstation display
+running an X server. \fBanimate\fP first determines the hardware capabilities
+of the workstation. If the number of unique colors in an image is less
+than or equal to the number the workstation can support, the image is displayed
+in an X window. Otherwise the number of colors in the image is first reduced
+to match the color resolution of the workstation before it is displayed.
+
+This means that a continuous-tone 24 bits-per-pixel image can display on
+a 8 bit pseudo-color device or monochrome device. In most instances the
+reduced color image closely resembles the original. Alternatively, a monochrome
+or pseudo-color image sequence can display on a continuous-tone 24 bits-per-pixel
+device.
+
+To help prevent color flashing on X server visuals that have colormaps,
+\fBanimate\fP
+creates a single colormap from the image sequence. This can be rather time
+consuming. You can speed this operation up by reducing the colors in the
+image before you "animate" them. Use \fBmogrify\fP to color reduce the
+images to a single colormap. See \fBmogrify(1)\fP for details. Alternatively,
+you can use a Standard Colormap; or a static, direct, or true color visual.
+You can define a Standard Colormap with \fIxstdcmap\fP. See \fBxstdcmap(1)\fP
+for details. This method is recommended for colormapped X server because
+it eliminates the need to compute a global colormap.
+.SH EXAMPLES
+
+To animate a set of images of a cockatoo, use:
+
+ gm animate cockatoo.*
+
+
+To animate a cockatoo image sequence while using the Standard Colormap
+\fIbest\fP, use:
+
+ xstdcmap -best
+ gm animate -map best cockatoo.*
+
+
+To animate an image of a cockatoo without a border centered on a backdrop,
+use:
+
+
+ gm animate +borderwidth -backdrop cockatoo.*
+
+.SH OPTIONS
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+.TP
+.B "-backdrop"
+\fRdisplay the image centered on a backdrop.
+.TP
+.B "-background \fI<color>"\fP
+\fRthe background color
+.TP
+.B "-bordercolor \fI<color>"\fP
+\fRthe border color
+.TP
+.B "-borderwidth \fI<geometry>"\fP
+\fRthe border width
+.TP
+.B "-chop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRremove pixels from the interior of an image
+.TP
+.B "-colormap \fI<type>"\fP
+\fRdefine the colormap type
+.TP
+.B "-colors \fI<value>"\fP
+\fRpreferred number of colors in the image
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+.TP
+.B "-crop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRpreferred size and location of the cropped image
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-delay \fI<1/100ths of a second>"\fP
+\fRdisplay the next image after pausing
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+.TP
+.B "-dispose \fI<method>"\fP
+\fRGIF disposal method
+.TP
+.B "-dither"
+\fRapply Floyd/Steinberg error diffusion to the image
+.TP
+.B "-font \fI<name>"\fP
+\fRuse this font when annotating the image with text
+.TP
+.B "-foreground \fI<color>"\fP
+\fRdefine the foreground color
+.TP
+.B "-gamma \fI<value>"\fP
+\fRlevel of gamma correction
+.TP
+.B "-geometry \fI<width>x<height>{+-}<x>{+-}<y>{%}{@}{!}{^}{<}{>}"\fP
+\fRSpecify dimension, offset, and resize options.
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-iconGeometry \fI<geometry>"\fP
+\fRspecify the icon geometry
+.TP
+.B "-iconic"
+\fRiconic animation
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-map \fI<type>"\fP
+\fRdisplay image using this type.
+.TP
+.B "-matte"
+\fRstore matte channel if the image has one
+.TP
+.B "-mattecolor \fI<color>"\fP
+\fRspecify the color to be used with the \fB-frame\fP option
+.TP
+.B "-monitor"
+\fRshow progress indication
+.TP
+.B "-monochrome"
+\fRtransform the image to black and white
+.TP
+.B "-name"
+\fRname an image
+.TP
+.B "-noop"
+\fRNOOP (no option)
+.TP
+.B "-pause \fI<seconds>"\fP
+\fRpause between animation loops [animate]
+.TP
+.B "-remote"
+\fRperform a X11 remote operation
+.TP
+.B "-rotate \fI<degrees>{<}{>}"\fP
+\fRrotate the image
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-scenes \fI<value-value>"\fP
+\fRrange of image scene numbers to read
+.TP
+.B "-shared-memory"
+\fRuse shared memory
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+.TP
+.B "-text-font \fI<name>"\fP
+\fRfont for writing fixed-width text
+.TP
+.B "-title \fI<string>"\fP
+\fRassign title to displayed image [\fIanimate, display, montage\fP]
+.TP
+.B "-treedepth \fI<value>"\fP
+\fRtree depth for the color reduction algorithm
+.TP
+.B "-trim"
+\fRtrim an image
+.TP
+.B "-type \fI<type>"\fP
+\fRthe image type
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+.TP
+.B "-visual \fI<type>"\fP
+\fRanimate images using this X visual type
+.TP
+.B "-window \fI<id>"\fP
+\fRmake image the background of a window
+
+For a more detailed description of each option, see
+Options, above.
+
+
+Any option you specify on the command line remains in effect for the group
+of images following it, until the group is terminated by the appearance of
+any option or \fB-noop\fP. For example, to animate three images, the first
+with 32 colors, the second with an unlimited number of colors, and the
+third with only 16 colors, use:
+
+
+ gm animate -colors 32 cockatoo.1 -noop cockatoo.2
+ -colors 16 cockatoo.3
+
+
+\fBAnimate\fP options can appear on the command line or in your X resources
+file. See \fIX(1)\fP. Options on the command line supersede values specified
+in your X resources file.
+Image filenames may appear in any order on the command line if the image
+format is \fIMIFF\fP (refer to \fBmiff(5)\fP and the
+\fBscene\fP keyword
+is specified in the image. Otherwise the images will display in the order
+they appear on the command line.
+.SH MOUSE BUTTONS
+
+Press any button to map or unmap the Command widget. See the next section
+for more information about the Command widget.
+.SH COMMAND WIDGET
+
+The Command widget lists a number of sub-menus and commands. They are
+
+ \fBAnimate\fP
+
+ Open
+ Play
+ Step
+ Repeat
+ Auto Reverse
+
+ \fBSpeed\fP
+
+ Faster
+ Slower
+
+ \fBDirection\fP
+
+ Forward
+ Reverse
+
+ \fBImage Info\fP
+ \fBHelp\fP
+ \fBQuit\fP
+
+
+Menu items with a indented triangle have a sub-menu. They are represented
+above as the indented items. To access a sub-menu item, move the pointer
+to the appropriate menu and press a button and drag. When you find the
+desired sub-menu item, release the button and the command is executed.
+Move the pointer away from the sub-menu if you decide not to execute a
+particular command.
+.SH KEYBOARD ACCELERATORS
+.in 15
+
+.in 15
+.B "\fBCtl+O\fP"
+.in 20
+ \fR
+.in 20
+Press to load an image from a file.
+.in 15
+.in 15
+.B "\fBspace\fP"
+.in 20
+ \fR
+.in 20
+Press to display the next image in the sequence.
+.in 15
+.in 15
+.B "\fB<\fP"
+.in 20
+ \fR
+.in 20
+Press to speed-up the display of the images. Refer to
+\fB-delay\fP for more information.
+.in 15
+.in 15
+.B "\fB>\fP"
+.in 20
+ \fR
+.in 20
+Press to slow the display of the images. Refer to
+\fB-delay\fP for more information.
+.in 15
+.in 15
+.B "\fB?\fP"
+.in 20
+ \fR
+.in 20
+Press to display information about the image. Press
+any key or button to erase the information.
+.in 15
+.in 20
+This information is printed: image name; image size;
+and the total number of unique colors in the image.
+.in 15
+.in 15
+.B "\fBF1\fP"
+.in 20
+ \fR
+.in 20
+Press to display helpful information about \fBanimate(1)\fP.
+.in 15
+.in 15
+.B "\fBCtl-q\fP"
+.in 20
+ \fR
+.in 20
+Press to discard all images and exit program.
+.in 15
+
+.SH X RESOURCES
+
+\fBAnimate\fP options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See \fBX(1)\fP for more information on X resources.
+
+All \fBanimate\fP options have a corresponding X resource. In addition,
+the \fBanimate\fP program uses the following X resources:
+.in 15
+
+.in 15
+.B "\fBbackground\fP \fB(\fP\fIclass\fP \fBBackground)\fP"
+.in 20
+ \fR
+.in 20
+
+Specifies the preferred color to use for the Image window background. The
+default is #ccc.
+.in 15
+.in 15
+.B "\fBborderColor\fP \fB(\fP\fIclass\fP \fBBorderColor)\fP"
+.in 20
+ \fR
+.in 20
+
+Specifies the preferred color to use for the Image window border. The default
+is #ccc.
+.in 15
+.in 15
+.B "\fBborderWidth\fP \fB(\fP\fIclass\fP \fBBorderWidth)\fP"
+.in 20
+ \fR
+.in 20
+
+Specifies the width in pixels of the Image window border. The default is
+2.
+.in 15
+.in 15
+.B "\fBfont\fP \fB(\fP\fIclass\fP \fBFont\fP \fBor\fP \fBFontList)\fP"
+.in 20
+ \fR
+.in 20
+
+Specifies the name of the preferred font to use in normal formatted text.
+The default is 14 point \fIHelvetica\fP.
+.in 15
+.in 15
+.B "\fBforeground\fP \fB(\fP\fIclass\fP \fBForeground)\fP"
+.in 20
+ \fR
+.in 20
+
+Specifies the preferred color to use for text within the Image window.
+The default is black.
+.in 15
+.in 15
+.B "\fBgeometry\fP \fB(\fP\fIclass\fP \fBgeometry)\fP"
+.in 20
+ \fR
+.in 20
+
+Specifies the preferred size and position of the image window. It is not
+necessarily obeyed by all window managers.
+Offsets, if present, are handled in \fIX(1)\fP style. A negative x offset is
+measured from the right edge of the screen to the right edge of the icon,
+and a negative y offset is measured from the bottom edge of the screen
+to the bottom edge of the icon.
+.in 15
+.in 15
+.B "\fBiconGeometry\fP \fB(\fP\fIclass\fP \fBIconGeometry)\fP"
+.in 20
+ \fR
+.in 20
+
+Specifies the preferred size and position of the application when iconified.
+It is not necessarily obeyed by all window managers.
+Offsets, if present, are handled in the same manner as in class Geometry.
+.in 15
+.in 15
+.B "\fBiconic\fP \fB(\fP\fIclass\fP \fBIconic)\fP"
+.in 20
+ \fR
+.in 20
+
+This resource indicates that you would prefer that the application's windows
+initially not be visible as if the windows had be immediately iconified
+by you. Window managers may choose not to honor the application's request.
+.in 15
+.in 15
+.B "\fBmatteColor\fP \fB(\fP\fIclass\fP \fBMatteColor)\fP"
+.in 20
+ \fR
+.in 20
+
+Specify the color of windows. It is used for the backgrounds of windows,
+menus, and notices. A 3D effect is achieved by using highlight and shadow
+colors derived from this color. Default value: #ddd.
+.in 15
+.in 15
+.B "\fBname\fP \fB(\fP\fIclass\fP \fBName)\fP"
+.in 20
+ \fR
+.in 20
+
+This resource specifies the name under which resources for the application
+should be found. This resource is useful in shell aliases to distinguish
+between invocations of an application, without resorting to creating links
+to alter the executable file name. The default is the application name.
+.in 15
+.in 15
+.B "\fBsharedMemory\fP \fB(\fP\fIclass\fP \fBSharedMemory)\fP"
+.in 20
+ \fR
+.in 20
+
+This resource specifies whether animate should attempt use shared memory
+for pixmaps. ImageMagick must be compiled with shared memory support, and
+the display must support the MIT-SHM extension. Otherwise, this resource
+is ignored. The default is True.
+.in 15
+.in 15
+.B "\fBtext_font\fP \fB(\fP\fIclass\fP \fBtextFont)\fP"
+.in 20
+ \fR
+.in 20
+
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point \fICourier\fP.
+.in 15
+.in 15
+.B "\fBtitle\fP \fB(\fP\fIclass\fP \fBTitle)\fP"
+.in 20
+ \fR
+.in 20
+
+This resource specifies the title to be used for the Image window. This
+information is sometimes used by a window manager to provide some sort
+of header identifying the window. The default is the image file name.
+.in 15
+
+.SH GM BATCH
+.SH DESCRIPTION
+
+\fBbatch\fP executes an arbitary number of the utility commands
+(e.g. \fBconvert\fP) in the form of a simple linear batch script in
+order to improve execution efficiency, and/or to allow use as a
+subordinate co-process under the control of an arbitrary script or
+program.
+.SH EXAMPLES
+ To drive \fB'gm batch'\fP using a shell script (or a program
+written in any language), have the script/program send commands to 'gm
+batch' via its standard input. Specify that standard input should be
+used by using \fB'-'\fP as the file name. The following example
+converts all files matching '*.jpg' to TIFF format while rotating each
+file by 90 degrees and stripping all embedded profiles. The shell
+script syntax is standard Unix shell:
+
+ for file in *.jpg
+ do
+ outfile=`basename $file .jpg`.tiff
+ echo convert -verbose "'$file'" -rotate 90 \\
+ +profile "'*'" "'$outfile'"
+ done | gm batch -echo on -feedback on -
+
+
+We can accomplish the same as the previous example by putting all the
+commands in a text file and then specifying the name of the text file
+as the script to execute:
+
+ for file in *.jpg
+ do
+ outfile=`basename $file .jpg`.tiff
+ echo convert -verbose "'$file'" -rotate 90 \\
+ +profile "'*'" "'$outfile'"
+ done > script.txt
+ gm batch -echo on -feedback on script.txt
+
+.SH OPTIONS
+
+Options are processed from left to right and must appear before any filename argument.
+.TP
+.B "-echo \fIon|off"\fP
+\fRcommand echo on or off
+
+Specify \fBon\fP to enable echoing commands to standard output as
+they are read or \fBoff\fP to disable. The default is
+\fBoff\fP.
+.TP
+.B "-escape \fIunix|windows"\fP
+\fRParse using unix or windows syntax
+
+Commands must be parsed from the input stream and escaping needs to be
+used to protect spaces or quoting characters in the input. Specify
+\fBunix\fP to use unix-style command line parsing or \fBwindows\fP
+for Microsoft Windows command shell style parsing. The default depends
+on if the software is compiled for Microsoft Windows or for a
+Unix-type system (including Cygwin on Microsoft Windows). It is
+recommended to use unix syntax because it is more powerful and more
+portable.
+.TP
+.B "-fail \fItext"\fP
+\fRtext to print if a command fails
+
+When feedback is enabled, this specifies the text to print when the
+command fails. The default text is \fBFAIL\fP.
+.TP
+.B "-feedback \fIon|off"\fP
+\fRenable error feedback
+
+Print text (see -pass and -fail options) feedback after each
+command to indicate the result, the default is \fBoff\fP.
+.TP
+.B "-help"
+
+Prints batch command help.
+.TP
+.B "-pass \fItext"\fP
+\fRtext to print if a command passes
+
+When feedback is enabled, this specifies the text to print when the
+command passes. The default text is \fBPASS\fP.
+.TP
+.B "-prompt \fItext"\fP
+\fRPrompt text to use for command line
+
+If no filename argument was specified, a simple command prompt appears
+where you may enter GraphicsMagick commands. The default prompt is
+\fBGM>\fP. Use this option to change the prompt to something else.
+.TP
+.B "-stop-on-error \fIon|off"\fP
+\fRSpecify if command processing stops on error
+
+Normally command processing continues if a command encounters an
+error. Specify \fB-stop-on-error on\fP to cause processing to quit
+immediately on error.
+.SH GM BENCHMARK
+.SH DESCRIPTION
+
+\fBbenchmark\fP executes an arbitrary \fBgm\fP utility command
+(e.g. \fBconvert\fP) for one or more loops, and/or a specified
+execution time, and reports many execution metrics. For builds using
+OpenMP, a mode is provided to execute the benchmark with an increasing
+number of threads and provide a report of speedup and multi-thread
+execution efficiency. If \fBbenchmark\fP is used to execute a
+command without any additional benchmark options, then the command is
+run once.
+.SH EXAMPLES
+To obtain benchmark information for a single execution of a
+command:
+
+ gm benchmark convert input.ppm -gaussian 0x1 output.ppm
+
+To obtain benchmark information from 100 iterations of the
+command:
+
+ gm benchmark -iterations 100 convert input.ppm \\
+ -gaussian 0x1 output.ppm
+
+To obtain benchmark information by iterating the command until a
+specified amount of time (in seconds) has been consumed:
+
+ gm benchmark -duration 30 convert input.ppm \\
+ -gaussian 0x1 output.ppm
+
+To obtain a full performance report with an increasing number of
+threads (1-32 threads, stepping the number of threads by four each
+time):
+
+ gm benchmark -duration 3 -stepthreads 4 convert \\
+ input.ppm -gaussian 0x2 output.ppm
+
+Here is the interpretation of the output:
+
+ \fBthreads\fP - number of threads used.
+ \fBiter\fP - number of command iterations executed.
+ \fBuser\fP - total user time consumed.
+ \fBtotal\fP - total elapsed time consumed.
+ \fBiter/s\fP - number of command iterations per second.
+ \fBiter/cpu\fP - amount of CPU time consumed per iteration.
+ \fBspeedup\fP - speedup compared with one thread.
+ \fBkarp-flatt\fP - Karp-Flatt measure of speedup efficiency.
+
+\fIPlease note that the reported "speedup" is based on the
+execution time of just one thread. A preliminary warm-up pass is used
+before timing the first loop in order to ensure that the CPU is
+brought out of power-saving modes and that system caches are warmed
+up. Most modern CPUs provide a "turbo" mode where the CPU clock speed
+is increased (e.g. by a factor of two) when only one or two cores are
+active. If the CPU grows excessively hot (due to insufficient
+cooling), then it may dial back its clock rates as a form of thermal
+management. These factors result in an under-reporting of speedup
+compared to if "turbo" mode was disabled and the CPU does not need to
+worry about thermal management. The \fBpowertop\fP utility available
+under Linux and Solaris provides a way to observe CPU core clock rates
+while a benchmark is running.\fP
+.SH OPTIONS
+ Options are processed from left to right and must appear before
+any argument.
+.TP
+.B "-duration \fIduration"\fP
+\fRduration to run benchmark
+Specify the number of seconds to run the benchmark. The command is
+executed repeatedly until the specified amount of time has
+elapsed.
+.TP
+.B "-help"
+
+Prints benchmark command help.
+.TP
+.B "-iterations \fIloops"\fP
+\fRnumber of command iterations
+Specify the number of iterations to run the benchmark. The command
+is executed repeatedly until the specified number of iterations has
+been reached.
+.TP
+.B "-rawcsv"
+\fRPrint results in CSV format
+Print results in a comma-separated value (CSV) format which is easy
+to parse for plotting or importing into a spreadsheet or database.
+The values reported are \fBthreads\fP, \fBiterations\fP,
+\fBuser_time\fP, and \fBelapsed_time\fP.
+.TP
+.B "-stepthreads \fIstep"\fP
+\fRexecute a per-thread benchmark ramp
+ Execute a per-thread benchmark ramp, incrementing the number of
+threads at each step by the specified value. The maximum number of
+threads is taken from the standard OMP_NUM_THREADS
+environment variable.
+.SH GM COMPARE
+
+\fBcompare\fP compares two similar images using a specified statistical
+method (see \fB-metric\fP) and/or by writing a difference image
+(\fB-file\fP), with the altered pixels annotated using a specified
+method (see \fB-highlight-style\fP) and color (see
+\fB-highlight-color\fP). \fIReference-image\fP is the original
+image and \fIcompare-image\fP is the (possibly) altered version, which
+should have the same dimensions as \fIreference-image\fP.
+.SH EXAMPLES
+
+To compare two images using Mean Square Error (MSE) statistical analysis
+use:
+
+ gm compare -metric mse original.miff compare.miff
+
+
+To create an annotated difference image use:
+
+ gm compare -highlight-style assign -highlight-color purple \\
+ -file diff.miff original.miff compare.miff
+
+.SH OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect only for the image that follows. All
+options are reset to their default values after each image is read.
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+.TP
+.B "-endian \fI<type>"\fP
+\fRspecify endianness (MSB, LSB, or Native) of image
+.TP
+.B "-file \fI<filename>"\fP
+\fRwrite annotated difference image to file
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-highlight-color \fI<color>"\fP
+\fRpixel annotation color
+.TP
+.B "-highlight-style \fI<style>"\fP
+\fRpixel annotation style
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-matte"
+\fRstore matte channel if the image has one
+.TP
+.B "-maximum-error \fI<limit>"\fP
+\fRspecifies the maximum amount of total image error
+.TP
+.B "-metric \fI<metric>"\fP
+\fRcomparison metric (MAE, MSE, PAE, PSNR, RMSE)
+.TP
+.B "-monitor"
+\fRshow progress indication
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+.TP
+.B "-type \fI<type>"\fP
+\fRthe image type
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+
+For a more detailed description of each option, see
+Options, above.
+
+.SH GM COMPOSITE
+
+\fBcomposite\fP composites (combines) images to create new images.
+\fIbase-image\fP is the base image and \fIchange-image\fP contains the changes.
+\fIouput-image\fP is the result, and normally has the same dimensions
+as \fIbase-image\fP.
+
+
+The optional \fImask-image\fP can be used to provide opacity information
+for \fIchange-image\fP when it has none or if you want a different mask.
+A mask image is typically grayscale and the same size as
+\fBbase-image\fP. If \fImask-image\fP is not grayscale, it is converted
+to grayscale and the resulting intensities are used as opacity
+information.
+.SH EXAMPLES
+
+To composite an image of a cockatoo with a perch, use:
+
+ gm composite cockatoo.miff perch.ras composite.miff
+
+
+To compute the difference between images in a series, use:
+
+ gm composite -compose difference series.2 series.1
+ difference.miff
+
+
+To composite an image of a cockatoo with a perch starting at location (100,150),
+use:
+
+ gm composite -geometry +100+150 cockatoo.miff
+ perch.ras composite.miff
+
+
+To tile a logo across your image of a cockatoo, use
+
+ gm convert +shade 30x60 cockatoo.miff mask.miff
+ gm composite -compose bumpmap -tile logo.png
+ cockatoo.miff mask.miff composite.miff
+
+
+To composite a red, green, and blue color plane into a single composite image,
+try
+
+ gm composite -compose CopyGreen green.png red.png
+ red-green.png
+ gm composite -compose CopyBlue blue.png red-green.png
+ gm composite.png
+
+.SH OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect only for the image that follows. All
+options are reset to their default values after each image is read.
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+.TP
+.B "-background \fI<color>"\fP
+\fRthe background color
+.TP
+.B "-blue-primary \fI<x>,<y>"\fP
+\fRblue chromaticity primary point
+.TP
+.B "-colors \fI<value>"\fP
+\fRpreferred number of colors in the image
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+.TP
+.B "-comment \fI<string>"\fP
+\fRannotate an image with a comment
+.TP
+.B "-compose \fI<operator>"\fP
+\fRthe type of image composition
+.TP
+.B "-compress \fI<type>"\fP
+\fRthe type of image compression
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-displace \fI<horizontal scale>x<vertical scale>"\fP
+\fRshift image pixels as defined by a displacement map
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+.TP
+.B "-dispose \fI<method>"\fP
+\fRGIF disposal method
+.TP
+.B "-dissolve \fI<percent>"\fP
+\fRdissolve an image into another by the given percent
+.TP
+.B "-dither"
+\fRapply Floyd/Steinberg error diffusion to the image
+.TP
+.B "-encoding \fI<type>"\fP
+\fRspecify the text encoding
+.TP
+.B "-endian \fI<type>"\fP
+\fRspecify endianness (MSB, LSB, or Native) of image
+.TP
+.B "-filter \fI<type>"\fP
+\fRuse this type of filter when resizing an image
+.TP
+.B "-font \fI<name>"\fP
+\fRuse this font when annotating the image with text
+.TP
+.B "-geometry \fI<width>x<height>{+-}<x>{+-}<y>{%}{@}{!}{^}{<}{>}"\fP
+\fRSpecify dimension, offset, and resize options.
+.TP
+.B "-gravity \fI<type>"\fP
+\fRdirection primitive gravitates to when annotating the image.
+.TP
+.B "-green-primary \fI<x>,<y>"\fP
+\fRgreen chromaticity primary point
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-label \fI<name>"\fP
+\fRassign a label to an image
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-matte"
+\fRstore matte channel if the image has one
+.TP
+.B "-monitor"
+\fRshow progress indication
+.TP
+.B "-monochrome"
+\fRtransform the image to black and white
+.TP
+.B "-negate"
+\fRreplace every pixel with its complementary color
+.TP
+.B "-page \fI<width>x<height>{+-}<x>{+-}<y>{%}{!}{<}{>}"\fP
+\fRsize and location of an image canvas
+.TP
+.B "-profile \fI<filename>"\fP
+\fRadd ICM, IPTC, or generic profile to image
+.TP
+.B "-quality \fI<value>"\fP
+\fRJPEG/MIFF/PNG/TIFF compression level
+.TP
+.B "-recolor \fI<matrix>"\fP
+\fRapply a color translation matrix to image channels
+.TP
+.B "-red-primary \fI<x>,<y>"\fP
+\fRred chromaticity primary point
+.TP
+.B "-render"
+\fRrender vector operations
+.TP
+.B "-repage \fI <width>x<height>+xoff+yoff[!]"\fP
+\fRAdjust image page offsets
+.TP
+.B "-resize \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image
+.TP
+.B "-rotate \fI<degrees>{<}{>}"\fP
+\fRrotate the image
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-scene \fI<value>"\fP
+\fRset scene number
+.TP
+.B "-set \fI<attribute> <value>"\fP
+\fRset an image attribute
+.TP
+.B "+set \fI<attribute>"\fP
+\fRunset an image attribute
+.TP
+.B "-sharpen \fI<radius>{x<sigma>}"\fP
+\fRsharpen the image
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+.TP
+.B "-stegano \fI<offset>"\fP
+\fRhide watermark within an image
+.TP
+.B "-stereo"
+\fRcomposite two images to create a stereo anaglyph
+.TP
+.B "-strip"
+\fRremove all profiles and text attributes from the image
+.TP
+.B "-thumbnail \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image (quickly)
+.TP
+.B "-treedepth \fI<value>"\fP
+\fRtree depth for the color reduction algorithm
+.TP
+.B "-trim"
+\fRtrim an image
+.TP
+.B "-type \fI<type>"\fP
+\fRthe image type
+.TP
+.B "-units \fI<type>"\fP
+\fRthe units of image resolution
+.TP
+.B "-unsharp \fI<radius>{x<sigma>}{+<amount>}{+<threshold>}"\fP
+\fRsharpen the image with an unsharp mask operator
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+.TP
+.B "-watermark \fI<brightness>x<saturation>"\fP
+\fRpercent brightness and saturation of a watermark
+.TP
+.B "-white-point \fI<x>,<y>"\fP
+\fRchromaticity white point
+.TP
+.B "-write \fI<filename>"\fP
+\fRwrite an intermediate image [\fIconvert, composite\fP]
+
+For a more detailed description of each option, see
+Options, above.
+
+.SH GM CONJURE
+
+The Magick scripting language (MSL) will primarily benefit those that
+want to accomplish custom image processing tasks but do not wish to
+program, or those that do not have access to a Perl interpreter or a
+compiler. The interpreter is called conjure and here is an example
+script:
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <image size="400x400" >
+ <read filename="image.gif" />
+ <get width="base-width" height="base-height" />
+ <resize geometry="%[dimensions]" />
+ <get width="width" height="height" />
+ <print output=
+ "Image sized from %[base-width]x%[base-height]
+ to %[width]x%[height].\\n" />
+ <write filename="image.png" />
+ </image>
+
+
+invoked with
+
+ gm conjure -dimensions 400x400 incantation.msl
+
+
+All operations will closely follow the key/value pairs defined in
+PerlMagick, unless otherwise noted.
+.SH OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect, or if it is changed by a statement
+in the scripting language.
+
+You can define your own keyword/value pairs on the command line.
+The script can then use this information when setting values by including
+%[keyword] in the string. For example, if you included
+"-dimensions 400x400" on the command line, as illustrated above,
+then any string
+containing "%[dimensions]" would have 400x400 substituted.
+The "%[string]" can be used either an entire string, such as
+geometry="%[dimensions]" or as a part of a string such as
+filename="%[basename].png".
+
+The keyword can be any string except for the following reserved
+strings (in any upper, lower, or mixed case variant): \fBdebug\fP,
+\fBhelp\fP, and \fBverbose\fP, whose usage is described below.
+
+The value can be any string. If
+either the keyword or the value contains white space or any
+symbols that have special meanings to your shell such as "#",
+"|",
+or
+"%", enclose the string in quotation marks or use "\\" to escape the white
+space and special symbols.
+
+Keywords and values are case dependent. "Key",
+"key",
+and "KEY" would
+be three different keywords.
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+.SH MAGICK SCRIPTING LANGUAGE
+
+The Magick Scripting Language (MSL) presently defines the following
+elements and their attributes:
+.in 15
+
+.in 15
+.B "<image>"
+.in 20
+ \fR
+.in 20
+background, color, id, size
+.in 15
+.in 20
+
+Define a new image object. \fB</image>\fP destroys it. Because of
+this, if you wish to reference multiple "subimages" (aka pages or
+layers), you can embed one \fBimage\fP element inside of another. For
+example:
+
+.in 15
+.in 20
+
+
+ <image>
+ <read filename="input.png" />
+ <get width="base-width" height="base-height" />
+ <image height="base-height" width="base-width">
+ <image />
+ <write filename="output.mng" />
+ </image>
+
+
+.in 15
+.in 20
+
+
+ <image size="400x400" />
+
+
+.in 15
+.in 15
+.B "<group>"
+.in 20
+ \fR
+.in 20
+
+Define a new group of image objects. By default, images are only
+valid for the life of their \fB<image>\fPelement.
+
+.in 15
+.in 20
+
+
+ <image> -- creates the image
+ ..... -- do stuff with it
+ </image> -- dispose of the image
+
+
+.in 15
+.in 20
+
+However, in a group, all images in that group will stay around for the
+life of the group:
+
+.in 15
+.in 20
+
+
+ <group> -- start a group
+ <image> -- create an image
+ .... -- do stuff
+ </image> -- NOOP
+ <image> -- create another image
+ .... -- do more stuff
+ </image> -- NOOP
+ <write filename="image.mng" /> -- output
+ </group> -- dispose of both images
+
+
+.in 15
+.in 15
+.B "<read>"
+.in 20
+ \fR
+.in 20
+ filename
+.in 15
+.in 20
+
+Read a new image from a disk file.
+
+.in 15
+.in 20
+
+
+ <read filename="image.gif" />
+
+
+.in 15
+.in 20
+
+To read two images use
+
+.in 15
+.in 20
+
+
+ <read filename="image.gif" />
+ <read filename="image.png />
+
+
+.in 15
+.in 15
+.B "<write>"
+.in 20
+ \fR
+.in 20
+ filename
+.in 15
+.in 20
+Write the image(s) to disk, either as
+a single multiple-image file or multiple ones if necessary.
+
+.in 15
+.in 20
+
+
+ <write filename=image.tiff" />
+
+.in 15
+.B "<get>"
+.in 20
+ \fR
+.in 20
+Get any attribute recognized by
+PerlMagick's GetAttribute() and stores it as an image attribute for later
+use. Currently only \fIwidth\fP and \fIheight\fP are supported.
+.in 15
+.in 20
+
+
+ <get width="base-width" height="base-height" />
+ <print output="Image size is %[base-width]x%[base-height].\\n" />
+
+
+.in 15
+.in 15
+.B "<set>"
+.in 20
+ \fR
+.in 20
+background, bordercolor, clip-mask, colorspace, density,
+magick, mattecolor, opacity. Set an attribute recognized by
+PerlMagick's GetAttribute().
+.in 15
+.in 15
+.B "<profile>"
+.in 20
+ \fR
+.in 20
+ [profilename]
+.in 15
+.in 20
+
+Read one or more IPTC, ICC or generic profiles from file and assign to image
+
+.in 15
+.in 20
+
+
+ <profile iptc="profile.iptc" generic="generic.dat" />
+
+
+.in 15
+.in 20
+
+To remove a specified profile use "!" as the filename eg
+
+.in 15
+.in 20
+
+
+ <profile icm="!" iptc="profile.iptc" />
+
+
+.in 15
+.in 15
+.B "<border>"
+.in 20
+ \fR
+.in 20
+ fill, geometry, height, width
+.in 15
+.in 15
+.B "<blur>"
+.in 20
+ \fR
+.in 20
+ radius, sigma
+.in 15
+.in 15
+.B "<charcoal>"
+.in 20
+ \fR
+.in 20
+ radius, sigma
+.in 15
+.in 15
+.B "<chop>"
+.in 20
+ \fR
+.in 20
+ geometry, height, width, x, y
+.in 15
+.in 15
+.B "<crop>"
+.in 20
+ \fR
+.in 20
+ geometry, height, width, x, y
+.in 15
+.in 15
+.B "<composite>"
+.in 20
+ \fR
+.in 20
+ compose, geometry, gravity, image, x, y
+.in 15
+.in 20
+
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <group>
+ <image id="image_01">
+ <read filename="cloud3.gif"/>
+ <resize geometry="250x90"/>
+ </image>
+ <image id="image_02">
+ <read filename="cloud4.gif"/>
+ <resize geometry="190x100"/>
+ </image>
+ <image>
+ <read filename="background.jpg"/>
+ <composite image="image_01" geometry="+740+470"/>
+ <composite image="image_02" geometry="+390+415"/>
+ </image>
+ <write filename="result.png"/>
+ </group>
+
+
+.in 15
+.in 15
+.B "<despeckle>"
+.in 20
+ \fR
+.in 15
+.B "<emboss>"
+.in 20
+ \fR
+.in 20
+ radius, sigma
+.in 15
+.in 15
+.B "<enhance>"
+.in 20
+ \fR
+.in 15
+.B "<equalize>"
+.in 20
+ \fR
+.in 15
+.B "<edge>"
+.in 20
+ \fR
+.in 20
+ radius
+.in 15
+.in 15
+.B "<flip>"
+.in 20
+ \fR
+.in 15
+.B "<flop>"
+.in 20
+ \fR
+.in 15
+.B "<frame>"
+.in 20
+ \fR
+.in 20
+ fill, geometry, height, width, x, y, inner, outer
+.in 15
+.in 15
+.B "<flatten>"
+.in 20
+ \fR
+.in 15
+.B "<get>"
+.in 20
+ \fR
+.in 20
+ height, width
+.in 15
+.in 15
+.B "<gamma>"
+.in 20
+ \fR
+.in 20
+ red, green, blue
+.in 15
+.in 15
+.B "<image>"
+.in 20
+ \fR
+.in 20
+ background, color, id, size
+.in 15
+.in 15
+.B "<implode>"
+.in 20
+ \fR
+.in 20
+ amount
+.in 15
+.in 15
+.B "<magnify>"
+.in 20
+ \fR
+.in 15
+.B "<minify>"
+.in 20
+ \fR
+.in 15
+.B "<medianfilter>"
+.in 20
+ \fR
+.in 20
+ radius
+.in 15
+.in 15
+.B "<normalize>"
+.in 20
+ \fR
+.in 15
+.B "<oilpaint>"
+.in 20
+ \fR
+.in 20
+ radius
+.in 15
+.in 15
+.B "<print>"
+.in 20
+ \fR
+.in 20
+ output
+.in 15
+.in 15
+.B "<profile>"
+.in 20
+ \fR
+.in 20
+ [profilename]
+.in 15
+.in 15
+.B "<read>"
+.in 20
+ \fR
+.in 15
+.B "<resize>"
+.in 20
+ \fR
+.in 20
+ blur, filter, geometry, height, width
+.in 15
+.in 15
+.B "<roll>"
+.in 20
+ \fR
+.in 20
+ geometry, x, y
+.in 15
+.in 15
+.B "<rotate>"
+.in 20
+ \fR
+.in 20
+ degrees
+.in 15
+.in 15
+.B "<reducenoise>"
+.in 20
+ \fR
+.in 20
+ radius
+.in 15
+.in 15
+.B "<sample>"
+.in 20
+ \fR
+.in 20
+ geometry, height, width
+.in 15
+.in 15
+.B "<scale>"
+.in 20
+ \fR
+.in 20
+ geometry, height, width
+.in 15
+.in 15
+.B "<sharpen>"
+.in 20
+ \fR
+.in 20
+ radius, sigma
+.in 15
+.in 15
+.B "<shave>"
+.in 20
+ \fR
+.in 20
+ geometry, height, width
+.in 15
+.in 15
+.B "<shear>"
+.in 20
+ \fR
+.in 20
+ x, y
+.in 15
+.in 15
+.B "<solarize>"
+.in 20
+ \fR
+.in 20
+ threshold
+.in 15
+.in 15
+.B "<spread>"
+.in 20
+ \fR
+.in 20
+ radius
+.in 15
+.in 15
+.B "<stegano>"
+.in 20
+ \fR
+.in 20
+ image
+.in 15
+.in 15
+.B "<stereo>"
+.in 20
+ \fR
+.in 20
+ image
+.in 15
+.in 15
+.B "<swirl>"
+.in 20
+ \fR
+.in 20
+ degrees
+.in 15
+.in 15
+.B "<texture>"
+.in 20
+ \fR
+.in 20
+ image
+.in 15
+.in 15
+.B "<threshold>"
+.in 20
+ \fR
+.in 20
+ threshold
+.in 15
+.in 15
+.B "<transparent>"
+.in 20
+ \fR
+.in 20
+ color
+.in 15
+.in 15
+.B "<trim>"
+.in 20
+ \fR
+
+.SH GM CONVERT
+
+\fBConvert\fP converts an input file using one image format to an output
+file with a differing image format. In addition, various types of image
+processing can be performed on the converted image during the conversion
+process. \fBConvert\fP recognizes the image formats listed in
+\fIGraphicsMagick(1)\fP.
+
+.SH EXAMPLES
+
+To make a thumbnail of a JPEG image, use:
+
+ gm convert -size 120x120 cockatoo.jpg -resize 120x120
+ +profile "*" thumbnail.jpg
+
+
+In this example, '-size 120x120' gives a hint to the JPEG decoder
+that the image is going to be downscaled to 120x120, allowing it to run
+faster by avoiding returning full-resolution images to GraphicsMagick for
+the subsequent resizing operation. The
+\'-resize 120x120' specifies the desired dimensions of the
+output image. It will be scaled so its largest dimension is 120 pixels. The
+\'+profile "*"' removes any ICM, EXIF, IPTC, or other profiles
+that might be present in the input and aren't needed in the thumbnail.
+
+To convert a \fIMIFF\fP image of a cockatoo to a SUN raster image, use:
+
+ gm convert cockatoo.miff sun:cockatoo.ras
+
+
+To convert a multi-page \fIPostScript\fP document to individual FAX pages,
+use:
+
+ gm convert -monochrome document.ps fax:page
+
+
+To convert a TIFF image to a \fIPostScript\fP A4 page with the image in
+the lower left-hand corner, use:
+
+ gm convert -page A4+0+0 image.tiff document.ps
+
+
+To convert a raw Gray image with a 128 byte header to a portable graymap,
+use:
+
+ gm convert -depth 8 -size 768x512+128 gray:raw
+ image.pgm
+
+
+In this example, "raw" is the input file. Its format is "gray" and it
+has the dimensions and number of header bytes specified by the -size
+option and the sample depth specified by the
+-depth option. The output file is "image.pgm". The suffix ".pgm"
+specifies its format.
+
+To convert a Photo CD image to a TIFF image, use:
+
+ gm convert -size 1536x1024 img0009.pcd image.tiff
+ gm convert img0009.pcd[4] image.tiff
+
+
+To create a visual image directory of all your JPEG images, use:
+
+ gm convert 'vid:*.jpg' directory.miff
+
+
+To annotate an image with blue text using font 12x24 at position (100,100),
+use:
+
+ gm convert -font helvetica -fill blue
+ -draw "text 100,100 Cockatoo"
+ bird.jpg bird.miff
+
+
+To tile a 640x480 image with a JPEG texture with bumps use:
+
+ gm convert -size 640x480 tile:bumps.jpg tiled.png
+
+
+To surround an icon with an ornamental border to use with Mosaic(1), use:
+
+ gm convert -mattecolor "#697B8F" -frame 6x6 bird.jpg
+ icon.png
+
+
+To create a MNG animation from a DNA molecule sequence, use:
+
+ gm convert -delay 20 dna.* dna.mng
+
+.SH OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or \fB-noop\fP.
+Some options only affect the decoding of images and others only the encoding.
+The latter can appear after the final group of input images.
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-adjoin"
+\fRjoin images into a single multi-image file
+.TP
+.B "-affine \fI<matrix>"\fP
+\fRdrawing transform matrix
+.TP
+.B "-antialias"
+\fRremove pixel aliasing
+.TP
+.B "-append"
+\fRappend a set of images
+.TP
+.B " \fI-asc-cdl <spec>"\fP
+\fRapply ASC CDL color transform
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+.TP
+.B "-auto-orient"
+\fRorient (rotate) image so it is upright
+.TP
+.B "-average"
+\fRaverage a set of images
+.TP
+.B "-background \fI<color>"\fP
+\fRthe background color
+.TP
+.B "-black-threshold \fIred[,green][,blue][,opacity]"\fP
+\fRpixels below the threshold become black
+.TP
+.B "-blue-primary \fI<x>,<y>"\fP
+\fRblue chromaticity primary point
+.TP
+.B "-blur \fI<radius>{x<sigma>}"\fP
+\fRblur the image with a Gaussian operator
+.TP
+.B "-border \fI<width>x<height>"\fP
+\fRsurround the image with a border of color
+.TP
+.B "-bordercolor \fI<color>"\fP
+\fRthe border color
+.TP
+.B "-box \fI<color>"\fP
+\fRset the color of the annotation bounding box
+.TP
+.B "-channel \fI<type>"\fP
+\fRthe type of channel
+.TP
+.B "-charcoal \fI<factor>"\fP
+\fRsimulate a charcoal drawing
+.TP
+.B "-chop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRremove pixels from the interior of an image
+.TP
+.B "-clip"
+\fRapply the clipping path, if one is present
+.TP
+.B "-coalesce"
+\fRmerge a sequence of images
+.TP
+.B "-colorize \fI<value>"\fP
+\fRcolorize the image with the pen color
+.TP
+.B "-colors \fI<value>"\fP
+\fRpreferred number of colors in the image
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+.TP
+.B "-comment \fI<string>"\fP
+\fRannotate an image with a comment
+.TP
+.B "-compose \fI<operator>"\fP
+\fRthe type of image composition
+.TP
+.B "-compress \fI<type>"\fP
+\fRthe type of image compression
+.TP
+.B "-contrast"
+\fRenhance or reduce the image contrast
+.TP
+.B "-convolve \fI<kernel>"\fP
+\fRconvolve image with the specified convolution kernel
+.TP
+.B "-crop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRpreferred size and location of the cropped image
+.TP
+.B "-cycle \fI<amount>"\fP
+\fRdisplace image colormap by amount
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-deconstruct"
+\fRbreak down an image sequence into constituent parts
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-delay \fI<1/100ths of a second>"\fP
+\fRdisplay the next image after pausing
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-despeckle"
+\fRreduce the speckles within an image
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+.TP
+.B "-dispose \fI<method>"\fP
+\fRGIF disposal method
+.TP
+.B "-dither"
+\fRapply Floyd/Steinberg error diffusion to the image
+.TP
+.B "-draw \fI<string>"\fP
+\fRannotate an image with one or more graphic primitives
+.TP
+.B "-edge \fI<radius>"\fP
+\fRdetect edges within an image
+.TP
+.B "-emboss \fI<radius>"\fP
+\fRemboss an image
+.TP
+.B "-encoding \fI<type>"\fP
+\fRspecify the text encoding
+.TP
+.B "-endian \fI<type>"\fP
+\fRspecify endianness (MSB, LSB, or Native) of image
+.TP
+.B "-enhance"
+\fRapply a digital filter to enhance a noisy image
+.TP
+.B "-equalize"
+\fRperform histogram equalization to the image
+.TP
+.B "-extent \fI<width>x<height>{+-}<x>{+-}<y>"\fP
+\fRcomposite image on background color canvas image
+.TP
+.B "-fill \fI<color>"\fP
+\fRcolor to use when filling a graphic primitive
+.TP
+.B "-filter \fI<type>"\fP
+\fRuse this type of filter when resizing an image
+.TP
+.B "-flatten"
+\fRflatten a sequence of images
+.TP
+.B "-flip"
+\fRcreate a "mirror image"
+.TP
+.B "-flop"
+\fRcreate a "mirror image"
+.TP
+.B "-font \fI<name>"\fP
+\fRuse this font when annotating the image with text
+.TP
+.B "-format \fI<string>"\fP
+\fRoutput formatted image characteristics
+.TP
+.B "-frame \fI<width>x<height>+<outer bevel width>+<inner bevel width>"\fP
+\fRsurround the image with an ornamental border
+.TP
+.B "-fuzz \fI<distance>{%}"\fP
+\fRcolors within this Euclidean distance are considered equal
+.TP
+.B "-gamma \fI<value>"\fP
+\fRlevel of gamma correction
+.TP
+.B "-gaussian \fI<radius>{x<sigma>}"\fP
+\fRblur the image with a Gaussian operator
+.TP
+.B "-geometry \fI<width>x<height>{+-}<x>{+-}<y>{%}{@}{!}{^}{<}{>}"\fP
+\fRSpecify dimension, offset, and resize options.
+.TP
+.B "-gravity \fI<type>"\fP
+\fRdirection primitive gravitates to when annotating the image.
+.TP
+.B "-green-primary \fI<x>,<y>"\fP
+\fRgreen chromaticity primary point
+.TP
+.B "-hald-clut \fI<clut>"\fP
+\fRapply a Hald CLUT to the image
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-implode \fI<factor>"\fP
+\fRimplode image pixels about the center
+.TP
+.B "-intent \fI<type>"\fP
+\fRuse this type of rendering intent when managing the image color
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-label \fI<name>"\fP
+\fRassign a label to an image
+.TP
+.B "-lat \fI<width>x<height>{+-}<offset>{%}"\fP
+\fRperform local adaptive thresholding
+.TP
+.B "-level \fI<black_point>{,<gamma>}{,<white_point>}{%}"\fP
+\fRadjust the level of image contrast
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-list \fI<type>"\fP
+\fRthe type of list
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-loop \fI<iterations>"\fP
+\fRadd Netscape loop extension to your GIF animation
+.TP
+.B "-magnify"
+\fRmagnify the image
+.TP
+.B "-map \fI<filename>"\fP
+\fRchoose a particular set of colors from this image
+.TP
+.B "-mask \fI<filename>"\fP
+\fRSpecify a clipping mask
+.TP
+.B "-matte"
+\fRstore matte channel if the image has one
+.TP
+.B "-mattecolor \fI<color>"\fP
+\fRspecify the color to be used with the \fB-frame\fP option
+.TP
+.B "-median \fI<radius>"\fP
+\fRapply a median filter to the image
+.TP
+.B "-minify \fI<factor>"\fP
+\fRminify the image
+.TP
+.B "-modulate \fIbrightness[,saturation[,hue]]"\fP
+\fRvary the brightness, saturation, and hue of an image
+.TP
+.B "-monitor"
+\fRshow progress indication
+.TP
+.B "-monochrome"
+\fRtransform the image to black and white
+.TP
+.B "-morph \fI<frames>"\fP
+\fRmorphs an image sequence
+.TP
+.B "-mosaic"
+\fRcreate a mosaic from an image or an image sequence
+.TP
+.B "-motion-blur \fI<radius>{x<sigma>}{+angle}"\fP
+\fRSimulate motion blur
+.TP
+.B "-negate"
+\fRreplace every pixel with its complementary color
+.TP
+.B "-noise \fI<radius|type>"\fP
+\fRadd or reduce noise in an image
+.TP
+.B "-noop"
+\fRNOOP (no option)
+.TP
+.B "-normalize"
+\fRtransform image to span the full range of color values
+.TP
+.B "-opaque \fI<color>"\fP
+\fRchange this color to the pen color within the image
+.TP
+.B "-operator \fIchannel operator rvalue[%]"\fP
+\fRapply a mathematical, bitwise, or value operator to an image channel
+.TP
+.B "-ordered-dither \fI<channeltype> <NxN>"\fP
+\fRordered dither the image
+.TP
+.B "-orient \fI<orientation>"\fP
+\fRSet the image orientation attribute
+.TP
+.B "-page \fI<width>x<height>{+-}<x>{+-}<y>{%}{!}{<}{>}"\fP
+\fRsize and location of an image canvas
+.TP
+.B "-paint \fI<radius>"\fP
+\fRsimulate an oil painting
+.TP
+.B "-pen \fI<color>"\fP
+\fR(This option has been replaced by the -fill option)
+.TP
+.B "-ping"
+\fRefficiently determine image characteristics
+.TP
+.B "-pointsize \fI<value>"\fP
+\fRpointsize of the PostScript, X11, or TrueType font
+.TP
+.B "-preview \fI<type>"\fP
+\fRimage preview type
+.TP
+.B "-process \fI<command>"\fP
+\fRprocess a sequence of images using a process module
+.TP
+.B "-profile \fI<filename>"\fP
+\fRadd ICM, IPTC, or generic profile to image
+.TP
+.B "-quality \fI<value>"\fP
+\fRJPEG/MIFF/PNG/TIFF compression level
+.TP
+.B "-raise \fI<width>x<height>"\fP
+\fRlighten or darken image edges
+.TP
+.B "-random-threshold \fI<channeltype> <LOWxHIGH>"\fP
+\fRrandom threshold the image
+.TP
+.B "-recolor \fI<matrix>"\fP
+\fRapply a color translation matrix to image channels
+.TP
+.B "-red-primary \fI<x>,<y>"\fP
+\fRred chromaticity primary point
+.TP
+.B "-region \fI<width>x<height>{+-}<x>{+-}<y>"\fP
+\fRapply options to a portion of the image
+.TP
+.B "-render"
+\fRrender vector operations
+.TP
+.B "-repage \fI <width>x<height>+xoff+yoff[!]"\fP
+\fRAdjust image page offsets
+.TP
+.B "-resample \fI<horizontal>x<vertical>"\fP
+\fRResample image to specified horizontal and vertical resolution
+.TP
+.B "-resize \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image
+.TP
+.B "-roll \fI{+-}<x>{+-}<y>"\fP
+\fRroll an image vertically or horizontally
+.TP
+.B "-rotate \fI<degrees>{<}{>}"\fP
+\fRrotate the image
+.TP
+.B "-sample \fI<geometry>"\fP
+\fRscale image using pixel sampling
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-scale \fI<geometry>"\fP
+\fRscale the image.
+.TP
+.B "-scene \fI<value>"\fP
+\fRset scene number
+.TP
+.B "-set \fI<attribute> <value>"\fP
+\fRset an image attribute
+.TP
+.B "+set \fI<attribute>"\fP
+\fRunset an image attribute
+.TP
+.B "-segment \fI<cluster threshold>x<smoothing threshold>"\fP
+\fRsegment an image
+.TP
+.B "-shade \fI<azimuth>x<elevation>"\fP
+\fRshade the image using a distant light source
+.TP
+.B "-sharpen \fI<radius>{x<sigma>}"\fP
+\fRsharpen the image
+.TP
+.B "-shave \fI<width>x<height>{%}"\fP
+\fRshave pixels from the image edges
+.TP
+.B "-shear \fI<x degrees>x<y degrees>"\fP
+\fRshear the image along the X or Y axis
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+.TP
+.B "-solarize \fI<factor>"\fP
+\fRnegate all pixels above the threshold level
+.TP
+.B "-spread \fI<amount>"\fP
+\fRdisplace image pixels by a random amount
+.TP
+.B "-strip"
+\fRremove all profiles and text attributes from the image
+.TP
+.B "-stroke \fI<color>"\fP
+\fRcolor to use when stroking a graphic primitive
+.TP
+.B "-strokewidth \fI<value>"\fP
+\fRset the stroke width
+.TP
+.B "-swirl \fI<degrees>"\fP
+\fRswirl image pixels about the center
+.TP
+.B "-texture \fI<filename>"\fP
+\fRname of texture to tile onto the image background
+.TP
+.B "-threshold \fI<value>{%}"\fP
+\fRthreshold the image
+.TP
+.B "-thumbnail \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image (quickly)
+.TP
+.B "-tile \fI<filename>"\fP
+\fRtile image when filling a graphic primitive
+.TP
+.B "-transform"
+\fRtransform the image
+.TP
+.B "-transparent \fI<color>"\fP
+\fRmake this color transparent within the image
+.TP
+.B "-treedepth \fI<value>"\fP
+\fRtree depth for the color reduction algorithm
+.TP
+.B "-trim"
+\fRtrim an image
+.TP
+.B "-type \fI<type>"\fP
+\fRthe image type
+.TP
+.B "-units \fI<type>"\fP
+\fRthe units of image resolution
+.TP
+.B "-unsharp \fI<radius>{x<sigma>}{+<amount>}{+<threshold>}"\fP
+\fRsharpen the image with an unsharp mask operator
+.TP
+.B "-use-pixmap"
+\fRuse the pixmap
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+.TP
+.B "-view \fI<string>"\fP
+\fRFlashPix viewing parameters
+.TP
+.B "-virtual-pixel \fI<method>"\fP
+\fRspecify contents of "virtual pixels"
+.TP
+.B "-wave \fI<amplitude>x<wavelength>"\fP
+\fRalter an image along a sine wave
+.TP
+.B "-white-point \fI<x>,<y>"\fP
+\fRchromaticity white point
+.TP
+.B "-white-threshold \fIred[,green][,blue][,opacity]"\fP
+\fRpixels above the threshold become white
+.TP
+.B "-write \fI<filename>"\fP
+\fRwrite an intermediate image [\fIconvert, composite\fP]
+
+For a more detailed description of each option, see
+Options, above.
+.SH GM DISPLAY
+
+Display is a machine architecture independent
+image processing and display program. It can display an image on any workstation
+screen running an X server. \fBDisplay\fP can read and write
+\fBmany\fP
+of the more popular image formats (e.g. \fBJPEG\fP,
+\fBTIFF\fP,
+\fBPNM\fP,
+\fBPhoto
+CD\fP, etc.).
+
+With \fBdisplay\fP, you can perform these functions on an image:
+.in 15
+
+ o load an image from a file
+ o display the next image
+ o display the former image
+ o display a sequence of images as a slide show
+ o write the image to a file
+ o print the image to a \fIPostScript\fP printer
+ o delete the image file
+ o create a Visual Image Directory
+ o select the image to display by its thumbnail rather than name
+ o undo last image transformation
+ o copy a region of the image
+ o paste a region to the image
+ o restore the image to its original size
+ o refresh the image
+ o half the image size
+ o double the image size
+ o resize the image
+ o crop the image
+ o cut the image
+ o flop image in the horizontal direction
+ o flip image in the vertical direction
+ o rotate the image 90 degrees clockwise
+ o rotate the image 90 degrees counter-clockwise
+ o rotate the image
+ o shear the image
+ o roll the image
+ o trim the image edges
+ o invert the colors of the image
+ o vary the color brightness
+ o vary the color saturation
+ o vary the image hue
+ o gamma correct the image
+ o sharpen the image contrast
+ o dull the image contrast
+ o perform histogram equalization on the image
+ o perform histogram normalization on the image
+ o negate the image colors
+ o convert the image to grayscale
+ o set the maximum number of unique colors in the image
+ o reduce the speckles within an image
+ o eliminate peak noise from an image
+ o detect edges within the image
+ o emboss an image
+ o segment the image by color
+ o simulate an oil painting
+ o simulate a charcoal drawing
+ o annotate the image with text
+ o draw on the image
+ o edit an image pixel color
+ o edit the image matte information
+ o composite an image with another
+ o add a border to the image
+ o surround image with an ornamental border
+ o apply image processing techniques to a region of interest
+ o display information about the image
+ o zoom a portion of the image
+ o show a histogram of the image
+ o display image to background of a window
+ o set user preferences
+ o display information about this program
+ o discard all images and exit program
+ o change the level of magnification
+ o display images specified by a World Wide Web (WWW) uniform resource locator (URL)
+
+.SH EXAMPLES
+
+To scale an image of a cockatoo to exactly 640 pixels in width and 480
+pixels in height and position the window at location (200,200), use:
+
+ gm display -geometry 640x480+200+200! cockatoo.miff
+
+
+To display an image of a cockatoo without a border centered on a backdrop,
+use:
+
+ gm display +borderwidth -backdrop cockatoo.miff
+
+
+To tile a slate texture onto the root window, use:
+
+ gm display -size 1280x1024 -window root slate.png
+
+
+To display a visual image directory of all your JPEG images, use:
+
+ gm display 'vid:*.jpg'
+
+
+To display a MAP image that is 640 pixels in width and 480 pixels in height
+with 256 colors, use:
+
+ gm display -size 640x480+256 cockatoo.map
+
+
+To display an image of a cockatoo specified with a \fBWorld Wide Web (WWW)\fP
+uniform resource locator \fB(URL)\fP, use:
+
+ gm display ftp://wizards.dupont.com/images/cockatoo.jpg
+
+
+To display histogram of an image, use:
+
+ gm gm convert file.jpg HISTOGRAM:- | gm display -
+
+.SH OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect. For example to display three images,
+the first with 32 colors, the second with an unlimited number of colors,
+and the third with only 16 colors, use:
+
+ gm display -colors 32 cockatoo.miff -noop duck.miff
+ -colors 16 macaw.miff
+
+
+\fBDisplay\fP options can appear on the command line or in your X resources
+file. See \fIX(1)\fP. Options on the command line supersede values specified
+in your X resources file.
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+.TP
+.B "-backdrop"
+\fRdisplay the image centered on a backdrop.
+.TP
+.B "-background \fI<color>"\fP
+\fRthe background color
+.TP
+.B "-border \fI<width>x<height>"\fP
+\fRsurround the image with a border of color
+.TP
+.B "-bordercolor \fI<color>"\fP
+\fRthe border color
+.TP
+.B "-borderwidth \fI<geometry>"\fP
+\fRthe border width
+.TP
+.B "-colormap \fI<type>"\fP
+\fRdefine the colormap type
+.TP
+.B "-colors \fI<value>"\fP
+\fRpreferred number of colors in the image
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+.TP
+.B "-comment \fI<string>"\fP
+\fRannotate an image with a comment
+.TP
+.B "-compress \fI<type>"\fP
+\fRthe type of image compression
+.TP
+.B "-contrast"
+\fRenhance or reduce the image contrast
+.TP
+.B "-crop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRpreferred size and location of the cropped image
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-delay \fI<1/100ths of a second>"\fP
+\fRdisplay the next image after pausing
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-despeckle"
+\fRreduce the speckles within an image
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+.TP
+.B "-dispose \fI<method>"\fP
+\fRGIF disposal method
+.TP
+.B "-dither"
+\fRapply Floyd/Steinberg error diffusion to the image
+.TP
+.B "-edge \fI<radius>"\fP
+\fRdetect edges within an image
+.TP
+.B "-endian \fI<type>"\fP
+\fRspecify endianness (MSB, LSB, or Native) of image
+.TP
+.B "-enhance"
+\fRapply a digital filter to enhance a noisy image
+.TP
+.B "-filter \fI<type>"\fP
+\fRuse this type of filter when resizing an image
+.TP
+.B "-flip"
+\fRcreate a "mirror image"
+.TP
+.B "-flop"
+\fRcreate a "mirror image"
+.TP
+.B "-font \fI<name>"\fP
+\fRuse this font when annotating the image with text
+.TP
+.B "-foreground \fI<color>"\fP
+\fRdefine the foreground color
+.TP
+.B "-frame \fI<width>x<height>+<outer bevel width>+<inner bevel width>"\fP
+\fRsurround the image with an ornamental border
+.TP
+.B "-gamma \fI<value>"\fP
+\fRlevel of gamma correction
+.TP
+.B "-geometry \fI<width>x<height>{+-}<x>{+-}<y>{%}{@}{!}{^}{<}{>}"\fP
+\fRSpecify dimension, offset, and resize options.
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-iconGeometry \fI<geometry>"\fP
+\fRspecify the icon geometry
+.TP
+.B "-iconic"
+\fRiconic animation
+.TP
+.B "-immutable"
+\fRmake image immutable
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-label \fI<name>"\fP
+\fRassign a label to an image
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-magnify \fI<factor>"\fP
+\fRmagnify the image
+.TP
+.B "-map \fI<type>"\fP
+\fRdisplay image using this type.
+.TP
+.B "-matte"
+\fRstore matte channel if the image has one
+.TP
+.B "-mattecolor \fI<color>"\fP
+\fRspecify the color to be used with the \fB-frame\fP option
+.TP
+.B "-monitor"
+\fRshow progress indication
+.TP
+.B "-monochrome"
+\fRtransform the image to black and white
+.TP
+.B "-name"
+\fRname an image
+.TP
+.B "-negate"
+\fRreplace every pixel with its complementary color
+.TP
+.B "-noop"
+\fRNOOP (no option)
+.TP
+.B "-page \fI<width>x<height>{+-}<x>{+-}<y>{%}{!}{<}{>}"\fP
+\fRsize and location of an image canvas
+.TP
+.B "+progress"
+\fRdisable progress monitor and busy cursor
+.TP
+.B "-quality \fI<value>"\fP
+\fRJPEG/MIFF/PNG/TIFF compression level
+.TP
+.B "-raise \fI<width>x<height>"\fP
+\fRlighten or darken image edges
+.TP
+.B "-remote"
+\fRperform a X11 remote operation
+.TP
+.B "-roll \fI{+-}<x>{+-}<y>"\fP
+\fRroll an image vertically or horizontally
+.TP
+.B "-rotate \fI<degrees>{<}{>}"\fP
+\fRrotate the image
+.TP
+.B "-sample \fI<geometry>"\fP
+\fRscale image using pixel sampling
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-scenes \fI<value-value>"\fP
+\fRrange of image scene numbers to read
+.TP
+.B "-set \fI<attribute> <value>"\fP
+\fRset an image attribute
+.TP
+.B "+set \fI<attribute>"\fP
+\fRunset an image attribute
+.TP
+.B "-segment \fI<cluster threshold>x<smoothing threshold>"\fP
+\fRsegment an image
+.TP
+.B "-shared-memory"
+\fRuse shared memory
+.TP
+.B "-sharpen \fI<radius>{x<sigma>}"\fP
+\fRsharpen the image
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+.TP
+.B "-text-font \fI<name>"\fP
+\fRfont for writing fixed-width text
+.TP
+.B "-texture \fI<filename>"\fP
+\fRname of texture to tile onto the image background
+.TP
+.B "-title \fI<string>"\fP
+\fRassign title to displayed image [\fIanimate, display, montage\fP]
+.TP
+.B "-treedepth \fI<value>"\fP
+\fRtree depth for the color reduction algorithm
+.TP
+.B "-trim"
+\fRtrim an image
+.TP
+.B "-type \fI<type>"\fP
+\fRthe image type
+.TP
+.B "-update \fI<seconds>"\fP
+\fR
+detect when image file is modified and redisplay.
+.TP
+.B "-use-pixmap"
+\fRuse the pixmap
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+.TP
+.B "-visual \fI<type>"\fP
+\fRanimate images using this X visual type
+.TP
+.B "-window \fI<id>"\fP
+\fRmake image the background of a window
+.TP
+.B "-window-group"
+\fRspecify the window group
+.TP
+.B "-write \fI<filename>"\fP
+\fRwrite the image to a file [\fIdisplay\fP]
+
+For a more detailed description of each option, see
+Options, above.
+
+.SH MOUSE BUTTONS
+
+The effects of each button press is described below. Three buttons are
+required. If you have a two button mouse, button 1 and 3 are returned.
+Press \fBALT\fP and button 3 to simulate button 2.
+.TP
+.B "1"
+\fR
+Press this button to map or unmap the Command
+widget . See the next section for more information about the Command
+widget.
+.TP
+.B "2"
+\fR
+Press and drag to define a region of the image to magnify.
+.TP
+.B "3"
+\fR
+Press and drag to choose from a select set of \fBdisplay(1)\fP
+commands. This button behaves differently if the image being displayed
+is a visual image directory. Choose a particular tile of the directory
+and press this button and drag to select a command from a pop-up menu.
+Choose from these menu items:
+
+ Open
+ Next
+ Former
+ Delete
+ Update
+
+
+If you choose \fBOpen\fP, the image represented by the tile is displayed.
+To return to the visual image directory, choose \fBNext\fP from the Command
+widget (refer to Command Widget).
+\fBNext\fP and \fBFormer\fP
+moves to the next or former image respectively. Choose \fBDelete\fP to
+delete a particular image tile. Finally, choose \fBUpdate\fP to synchronize
+all the image tiles with their respective images. See
+montage
+and
+miff for more details.
+.SH COMMAND WIDGET
+
+The Command widget lists a number of sub-menus and commands. They are
+
+ \fBFile\fP
+
+ Open...
+ Next
+ Former
+ Select...
+ Save...
+ Print...
+ Delete...
+ Canvas...
+ Visual Directory...
+ Quit
+
+
+
+ \fBEdit\fP
+
+ Undo
+ Redo
+ Cut
+ Copy
+ Paste
+
+
+
+ \fBView\fP
+
+ Half Size
+ Original Size
+ Double Size
+ Resize...
+ Apply
+ Refresh
+ Restore
+
+
+
+ \fBTransform\fP
+
+ Crop
+ Chop
+ Flop
+ Flip
+ Rotate Right
+ Rotate Left
+ Rotate...
+ Shear...
+ Roll...
+ Trim Edges
+
+
+
+ \fBEnhance\fP
+
+ Hue...
+ Saturation...
+ Brightness...
+ Gamma...
+ Spiff...
+ Dull
+ Equalize
+ Normalize
+ Negate
+ GRAYscale
+ Quantize...
+
+
+
+ \fBEffects\fP
+
+ Despeckle
+ Emboss
+ Reduce Noise
+ Add Noise
+ Sharpen...
+ Blur...
+ Threshold...
+ Edge Detect...
+ Spread...
+ Shade...
+ Raise...
+ Segment...
+
+
+
+ \fBF/X\fP
+
+ Solarize...
+ Swirl...
+ Implode...
+ Wave...
+ Oil Paint...
+ Charcoal Draw...
+
+
+
+ \fBImage Edit\fP
+
+ Annotate...
+ Draw...
+ Color...
+ Matte...
+ Composite...
+ Add Border...
+ Add Frame...
+ Comment...
+ Launch...
+ Region of Interest...
+
+
+
+ \fBMiscellany\fP
+
+ Image Info
+ Zoom Image
+ Show Preview...
+ Show Histogram
+ Show Matte
+ Background...
+ Slide Show
+ Preferences...
+
+
+
+ \fBHelp\fP
+
+ Overview
+ Browse Documentation
+ About Display
+
+
+
+Menu items with a indented triangle have a sub-menu. They are represented
+above as the indented items. To access a sub-menu item, move the pointer
+to the appropriate menu and press button 1 and drag. When you find the
+desired sub-menu item, release the button and the command is executed.
+Move the pointer away from the sub-menu if you decide not to execute a
+particular command.
+.SH KEYBOARD ACCELERATORS
+
+Accelerators are one or two key presses that effect a particular command.
+The keyboard accelerators that
+\fBdisplay\fP understands is:
+
+ Ctl+O Press to load an image from a file.
+ space Press to display the next image.
+
+
+If the image is a multi-paged document such as a
+\fIPostScript\fP document,
+you can skip ahead several pages by preceding this command with a number.
+For example to display the fourth page beyond the current page,
+press 4space.
+
+ backspace Press to display the former image.
+
+
+If the image is a multi-paged document such as a
+\fIPostScript\fP document,
+you can skip behind several pages by preceding this command with a number.
+For example to display the fourth page preceding the current page, press
+4n.
+
+ Ctl-S Press to save the image to a file.
+ Ctl-P Press to print the image to a
+ \fIPostScript\fP printer.
+ Ctl-D Press to delete an image file.
+ Ctl-N Press to create a blank canvas.
+ Ctl-Q Press to discard all images and exit program.
+ Ctl+Z Press to undo last image transformation.
+ Ctl+R Press to redo last image transformation.
+ Ctl-X Press to cut a region of
+ the image.
+ Ctl-C Press to copy a region of
+ the image.
+ Ctl-V Press to paste a region to
+ the image.
+ < Press to halve the image size.
+ . Press to return to the original image size.
+ > Press to double the image size.
+ % Press to resize the image to a width and height
+ you specify.
+ Cmd-A Press to make any image transformations
+ permanent.
+ By default, any image size transformations are
+ applied to the original image to create the
+ image displayed on the X server. However, the
+ transformations are not permanent (i.e. the
+ original image does not change size only the
+ X image does). For example, if you press ">"
+ the X image will appear to double in size, but
+ the original image will in fact remain the same
+ size. To force the original image to double in
+ size, press ">" followed by "Cmd-A".
+ @ Press to refresh the image window.
+ C Press to crop the image.
+ [ Press to chop the image.
+ H Press to flop image in the horizontal direction.
+ V Press to flip image in the vertical direction.
+ / Press to rotate the image 90 degrees clockwise.
+ \\ Press to rotate the image 90 degrees
+ counter-clockwise.
+ * Press to rotate the image
+ the number of degrees you specify.
+ S Press to shear the image the number of degrees
+ you specify.
+ R Press to roll the image.
+ T Press to trim the image edges.
+ Shft-H Press to vary the color hue.
+ Shft-S Press to vary the color saturation.
+ Shft-L Press to vary the image brightness.
+ Shft-G Press to gamma correct the image.
+ Shft-C Press to spiff up the image contrast.
+ Shft-Z Press to dull the image contrast.
+ = Press to perform histogram equalization on
+ the image.
+ Shft-N Press to perform histogram normalization on
+ the image.
+ Shft-~ Press to negate the colors of the image.
+ . Press to convert the image colors to gray.
+ Shft-# Press to set the maximum number of unique
+ colors in the image.
+ F2 Press to reduce the speckles in an image.
+ F2 Press to emboss an image.
+ F4 Press to eliminate peak noise from an image.
+ F5 Press to add noise to an image.
+ F6 Press to sharpen an image.
+ F7 Press to blur image an image.
+ F8 Press to threshold the image.
+ F9 Press to detect edges within an image.
+ F10 Press to displace pixels by a random amount.
+ F11 Press to shade the image using a distant light
+ source.
+ F12 Press to lighten or darken image edges to
+ create a 3-D effect.
+ F13 Press to segment the image by color.
+ Meta-S Press to swirl image pixels about the center.
+ Meta-I Press to implode image pixels about the center.
+ Meta-W Press to alter an image along a sine wave.
+ Meta-P Press to simulate an oil painting.
+ Meta-C Press to simulate a charcoal drawing.
+ Alt-X Press to composite the image
+ with another.
+ Alt-A Press to annotate the image with text.
+ Alt-D Press to draw a line on the image.
+ Alt-P Press to edit an image pixel color.
+ Alt-M Press to edit the image matte information.
+ Alt-X Press to composite the image with another.
+ Alt-A Press to add a border to the image.
+ Alt-F Press to add a ornamental frame to the image.
+ Alt-Shft-! Press to add an image comment.
+ Ctl-A Press to apply image processing techniques to a
+ region of interest.
+ Shft-? Press to display information about the image.
+ Shft-+ Press to map the zoom image window.
+ Shft-P Press to preview an image enhancement, effect,
+ or f/x.
+ F1 Press to display helpful information about
+ the "display" utility.
+ Find Press to browse documentation about
+ GraphicsMagick.
+ 1-9 Press to change the level of magnification.
+
+
+Use the arrow keys to move the image one pixel up, down, left, or right
+within the magnify window. Be sure to first map the magnify window by pressing
+button 2.
+
+Press ALT and one of the arrow keys to trim off one pixel from any side
+of the image.
+.SH X RESOURCES
+
+\fBDisplay\fP options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See \fIX(1)\fP for more information on X resources.
+
+Most \fBdisplay\fP options have a corresponding X resource. In addition,
+\fBdisplay\fP
+uses the following X resources:
+.TP
+.B "background \fI(class Background)"\fP
+\fR
+Specifies the preferred color to use for the Image window background. The
+default is #ccc.
+.TP
+.B "borderColor \fI(class BorderColor)"\fP
+\fR
+Specifies the preferred color to use for the Image window border. The default
+is #ccc.
+.TP
+.B "borderWidth \fI(class BorderWidth)"\fP
+\fR
+Specifies the width in pixels of the image window border. The default is
+2.
+.TP
+.B "browseCommand \fI(class browseCommand)"\fP
+\fR
+Specifies the name of the preferred browser when displaying GraphicsMagick
+documentation. The default is netscape %s.
+.TP
+.B "confirmExit \fI(class ConfirmExit)"\fP
+\fR
+\fBDisplay\fP pops up a dialog box to confirm exiting the program when
+exiting the program. Set this resource to False to exit without
+a confirmation.
+.TP
+.B "displayGamma \fI(class DisplayGamma)"\fP
+\fR
+Specifies the gamma of the X server.
+\fR
+You can apply separate gamma values to the red, green, and blue channels
+of the image with a gamma value list delineated with slashes (i.e. 1.7/2.3/1.2).
+\fR
+The default is 2.2.
+.TP
+.B "displayWarnings \fI(class DisplayWarnings)"\fP
+\fR
+\fBDisplay\fP pops up a dialog box whenever a warning message occurs.
+Set this resource to False to ignore warning messages.
+.TP
+.B "font \fI(class FontList)"\fP
+\fR
+Specifies the name of the preferred font to use in normal formatted text.
+The default is 14 point Helvetica.
+.TP
+.B "font[1-9] \fI(class Font[1-9])"\fP
+\fR
+Specifies the name of the preferred font to use when
+annotating
+the image window with text. The default fonts are fixed, variable, 5x8,
+6x10, 7x13bold, 8x13bold, 9x15bold, 10x20, and 12x24.
+.TP
+.B "foreground \fI(class Foreground)"\fP
+\fR
+Specifies the preferred color to use for text within the image window.
+The default is black.
+.TP
+.B "gammaCorrect \fI(class gammaCorrect)"\fP
+\fR
+This resource, if true, will lighten or darken an image of known gamma
+to match the gamma of the display (see resource \fBdisplayGamma\fP). The
+default is True.
+.TP
+.B "geometry \fI(class Geometry)"\fP
+\fR
+Specifies the preferred size and position of the image window. It is not
+necessarily obeyed by all window managers.
+
+Offsets, if present, are handled in \fIX(1)\fP style. A negative x offset is
+measured from the right edge of the screen to the right edge of the icon,
+and a negative y offset is measured from the bottom edge of the screen
+to the bottom edge of the icon.
+.TP
+.B "iconGeometry \fI(class IconGeometry)"\fP
+\fR
+Specifies the preferred size and position of the application when iconified.
+It is not necessarily obeyed by all window managers.
+
+Offsets, if present, are handled in the same manner as in class Geometry.
+.TP
+.B "iconic \fI(class Iconic)"\fP
+\fR
+This resource indicates that you would prefer that the application's windows
+initially not be visible as if the windows had be immediately iconified
+by you. Window managers may choose not to honor the application's request.
+.TP
+.B "magnify \fI(class Magnify)"\fP
+\fR
+specifies an integral factor by which the image should be enlarged. The
+default is 3.
+\fR
+This value only affects the magnification window which is invoked with
+button
+number 3 after the image is displayed.
+.TP
+.B "matteColor \fI(class MatteColor)"\fP
+\fR
+Specify the color of windows. It is used for the backgrounds of windows,
+menus, and notices. A 3D effect is achieved by using highlight and shadow
+colors derived from this color. Default value: #697B8F.
+.TP
+.B "name \fI(class Name)"\fP
+\fR
+This resource specifies the name under which resources for the application
+should be found. This resource is useful in shell aliases to distinguish
+between invocations of an application, without resorting to creating links
+to alter the executable file name. The default is the application name.
+.TP
+.B "pen[1-9] \fI(class Pen[1-9])"\fP
+\fR
+Specifies the color of the preferred font to use when
+annotating
+the image window with text. The default colors are black, blue, green,
+cyan, gray, red, magenta, yellow, and white.
+.TP
+.B "printCommand \fI(class PrintCommand)"\fP
+\fR
+This command is executed whenever Print is issued. In general, it is the
+command to print \fIPostScript\fP to your printer. Default value: lp
+-c -s %i.
+.TP
+.B "sharedMemory \fI(class SharedMemory)"\fP
+\fR
+This resource specifies whether display should attempt use shared memory
+for pixmaps. GraphicsMagick must be compiled with shared memory support,
+and the display must support the MIT-SHM extension. Otherwise, this
+resource is ignored. The default is True.
+.TP
+.B "textFont \fI(class textFont)"\fP
+\fR
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point Courier.
+.TP
+.B "title \fI(class Title)"\fP
+\fR
+This resource specifies the title to be used for the image window. This
+information is sometimes used by a window manager to provide a header identifying
+the window. The default is the image file name.
+.TP
+.B "undoCache \fI(class UndoCache)"\fP
+\fR
+Specifies, in mega-bytes, the amount of memory in the undo edit cache.
+Each time you modify the image it is saved in the undo edit cache as long
+as memory is available. You can subsequently \fIundo\fP one or more of
+these transformations. The default is 16 Megabytes.
+.TP
+.B "usePixmap \fI(class UsePixmap)"\fP
+\fR
+Images are maintained as a XImage by default. Set this resource to True
+to utilize a server Pixmap instead. This option is useful if your image
+exceeds the dimensions of your server screen and you intend to pan the
+image. Panning is much faster with Pixmaps than with a XImage. Pixmaps
+are considered a precious resource, use them with discretion.
+
+To set the geometry of the Magnify or Pan or window, use the geometry resource.
+For example, to set the Pan window geometry to 256x256, use:
+
+ gm display.pan.geometry: 256x256
+
+.SH IMAGE LOADING
+
+To select an image to display, choose \fBOpen\fP of the \fBFile\fP sub-menu
+from the Command widget. A file browser is displayed.
+To choose a particular image file, move the pointer to the filename and
+press any button. The filename is copied to the text window. Next, press
+\fBOpen\fP
+or press the \fBRETURN\fP key. Alternatively, you can type the image file
+name directly into the text window. To descend directories, choose a directory
+name and press the button twice quickly. A scrollbar allows a large list
+of filenames to be moved through the viewing area if it exceeds the size
+of the list area.
+
+You can trim the list of file names by using shell globbing characters.
+For example, type *.jpg to list only files that end
+with .jpg.
+
+To select your image from the X server screen instead of from a file, Choose
+\fBGrab\fP of the \fBOpen\fP widget.
+.SH VISUAL IMAGE DIRECTORY
+
+To create a Visual Image Directory, choose Visual Directory of the \fBFile\fP
+sub-menu from the Command widget . A file browser is
+displayed. To create a Visual Image Directory from all the images in the
+current directory, press \fBDirectory\fP or press the \fBRETURN key\fP.
+Alternatively, you can select a set of image names by using shell globbing
+characters. For example, type *.jpg to include only files that
+end with .jpg. To descend directories, choose a directory name
+and press the button twice quickly. A scrollbar allows a large list of
+filenames to be moved through the viewing area if it exceeds the size of
+the list area.
+
+After you select a set of files, they are turned into thumbnails and tiled
+onto a single image. Now move the pointer to a particular thumbnail and
+press \fBbutton 3\fP and drag. Finally, select Open. The image represented
+by the thumbnail is displayed at its full size. Choose \fBNext\fP from
+the \fBFile\fP sub-menu of the Command widget to return to the Visual
+Image Directory.
+.SH IMAGE CUTTING
+
+Note that cut information for image window is not retained for colormapped
+X server visuals (e.g. \fIStaticColor\fP,
+\fIStaticColor\fP, \fIGRAYScale\fP,
+\fIPseudoColor\fP).
+Correct cutting behavior may require a \fITrueColor\fP or \fIDirectColor\fP
+visual or a \fIStandard Colormap\fP.
+
+To begin, press choose \fBCut\fP of the \fBEdit\fP sub-menu from the
+Command
+widget. Alternatively, press
+\fBF3\fP in the image window.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in cut mode. In cut mode, the Command widget has these
+options:
+
+ \fBHelp\fP
+ \fBDismiss\fP
+
+
+To define a cut region, press button 1 and drag. The cut region is defined
+by a highlighted rectangle that expands or contracts as it follows the
+pointer. Once you are satisfied with the cut region, release the button.
+You are now in rectify mode. In rectify mode, the Command widget has these
+options:
+
+ \fBCut\fP
+ \fBHelp\fP
+ \fBDismiss\fP
+
+
+You can make adjustments by moving the pointer to one of the cut rectangle
+corners, pressing a button, and dragging. Finally, press Cut to commit
+your copy region. To exit without cutting the image, press Dismiss.
+.SH IMAGE COPYING
+
+To begin, press choose \fBCopy\fP of the \fBEdit\fP sub-menu from the
+Command
+widget. Alternatively, press
+\fBF4\fP in the image window.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in copy mode. In copy mode, the Command widget has
+these options:
+
+ Help
+ Dismiss
+
+
+To define a copy region, press button 1 and drag. The copy region is defined
+by a highlighted rectangle that expands or contracts as it follows the
+pointer. Once you are satisfied with the copy region, release the button.
+You are now in rectify mode. In rectify mode, the Command widget has these
+options:
+
+ Copy
+ Help
+ Dismiss
+
+
+You can make adjustments by moving the pointer to one of the copy rectangle
+corners, pressing a button, and dragging. Finally, press Copy to commit
+your copy region. To exit without copying the image, press Dismiss.
+.SH IMAGE PASTING
+
+To begin, press choose \fBPaste\fP of the \fBEdit\fP sub-menu from the
+Command
+widget. Alternatively, press
+\fBF5\fP in the image window.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in Paste mode. To exit immediately, press Dismiss.
+In Paste mode, the Command widget has these options:
+
+ \fBOperators\fP
+
+ over
+ in
+ out
+ atop
+ xor
+ plus
+ minus
+ add
+ subtract
+ difference
+ multiply
+ bumpmap
+ replace
+
+ \fBHelp\fP
+ \fBDismiss\fP
+
+
+Choose a composite operation from the \fBOperators\fP sub-menu of the
+Command
+widget. How each operator behaves is described below. \fIimage window\fP
+is the image currently displayed on your X server and \fIimage\fP is the
+image obtained with the File Browser widget.
+.TP
+.B "over"
+\fR
+The result is the union of the two image shapes, with \fIimage\fP obscuring
+\fIimage
+window\fP in the region of overlap.
+.TP
+.B "in"
+\fR
+The result is simply \fIimage\fP cut by the shape of
+\fIimage window\fP.
+None of the image data of image window is in the result.
+.TP
+.B "out"
+\fR
+The resulting image is \fIimage\fP with the shape of
+\fIimage window\fP
+cut out.
+.TP
+.B "atop"
+\fR
+The result is the same shape as \fIimage window\fP, with
+\fIimage\fP
+obscuring \fIimage window\fP where the image shapes overlap. Note this
+differs from over because the portion of image outside
+\fIimage window\fP's
+shape does not appear in the result.
+.TP
+.B "xor"
+\fR
+The result is the image data from both \fIimage\fP and
+\fIimage window\fP
+that is outside the overlap region. The overlap region is blank.
+.TP
+.B "plus"
+\fR
+The result is just the sum of the image data. Output values are cropped
+to the maximum value (no overflow). This operation is independent of the
+matte channels.
+.TP
+.B "minus"
+\fR
+The result of \fIimage\fP - \fIimage window\fP, with underflow cropped
+to zero. The matte channel is ignored (set to opaque, full coverage).
+.TP
+.B "add"
+\fR
+The result of \fIimage\fP + \fIimage window\fP, with overflow wrapping
+around (mod MaxRGB+1).
+.TP
+.B "subtract"
+\fR
+The result of \fIimage\fP - \fIimage window\fP, with underflow wrapping
+around (mod MaxRGB+1). The add and subtract operators can be used to perform
+reversible transformations.
+.TP
+.B "difference"
+\fR
+The result of abs(\fIimage\fP - \fIimage window\fP). This is useful for
+comparing two very similar images.
+.TP
+.B "multiply"
+\fR
+The result of \fIimage\fP * \fIimage window\fP. This is useful for
+the creation of drop-shadows.
+.TP
+.B "bumpmap"
+\fR
+The result of \fIimage window\fP shaded by \fIwindow\fP.
+.TP
+.B "replace"
+\fRThe resulting image is \fIimage window\fP replaced with
+\fIimage\fP.
+Here the matte information is ignored.
+
+The image compositor requires a matte, or alpha channel in the image for
+some operations. This extra channel usually defines a mask which represents
+a sort of a cookie-cutter for the image. This is the case when matte is
+255 (full coverage) for pixels inside the shape, zero outside, and between
+zero and 255 on the boundary. If image does not have a matte channel, it
+is initialized with 0 for any pixel matching in color to pixel location
+(0,0), otherwise 255. See Matte Editing for a method
+of defining a matte channel.
+
+Note that matte information for image window is not retained for colormapped
+X server visuals (e.g. \fIStaticColor, StaticColor, GrayScale, PseudoColor\fP).
+Correct compositing behavior may require a
+\fITrueColor\fP or \fIDirectColor\fP
+visual or a \fIStandard Colormap\fP.
+
+Choosing a composite operator is optional. The default operator is replace.
+However, you must choose a location to composite your image and press button
+1. Press and hold the button before releasing and an outline of the image
+will appear to help you identify your location.
+
+The actual colors of the pasted image is saved. However, the color that
+appears in image window may be different. For example, on a monochrome
+screen image window will appear black or white even though your pasted
+image may have many colors. If the image is saved to a file it is written
+with the correct colors. To assure the correct colors are saved in the
+final image, any \fIPseudoClass\fP image is promoted to \fIDirectClass\fP.
+To force a
+\fIPseudoClass\fP image to remain \fIPseudoClass\fP,
+use \fB-colors\fP.
+.SH IMAGE CROPPING
+
+To begin, press choose \fBCrop\fP of the \fBTransform\fP submenu from
+the Command widget. Alternatively,
+press C in the image window.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in crop mode. In crop mode, the Command widget has
+these options:
+
+ \fBHelp\fP
+ \fBDismiss\fP
+
+
+To define a cropping region, press button 1 and drag. The cropping region
+is defined by a highlighted rectangle that expands or contracts as it follows
+the pointer. Once you are satisfied with the cropping region, release the
+button. You are now in rectify mode. In rectify mode, the Command widget
+has these options:
+
+ \fBCrop\fP
+ \fBHelp\fP
+ \fBDismiss\fP
+
+
+You can make adjustments by moving the pointer to one of the cropping rectangle
+corners, pressing a button, and dragging. Finally, press Crop to commit
+your cropping region. To exit without cropping the image, press Dismiss.
+.SH IMAGE CHOPPING
+
+An image is chopped interactively. There is no command line argument to
+chop an image. To begin, choose \fBChop\fP of the \fBTransform\fP sub-menu
+from the Command widget. Alternatively,
+press [ in the Image window.
+
+You are now in \fBChop\fP mode. To exit immediately, press
+\fBDismiss\fP.
+In Chop mode, the Command widget has these options:
+
+ \fBDirection\fP
+
+ horizontal
+ vertical
+
+ \fBHelp\fP
+ \fBDismiss\fP
+
+
+If the you choose the horizontal direction (this is the default), the area
+of the image between the two horizontal endpoints of the chop line is removed.
+Otherwise, the area of the image between the two vertical endpoints of
+the chop line is removed.
+
+Select a location within the image window to begin your chop, press and
+hold any button. Next, move the pointer to another location in the image.
+As you move a line will connect the initial location and the pointer. When
+you release the button, the area within the image to chop is determined
+by which direction you choose from the Command widget.
+
+To cancel the image chopping, move the pointer back to the starting point
+of the line and release the button.
+.SH IMAGE ROTATION
+
+Press the / key to rotate the image 90 degrees or \\ to rotate -90 degrees.
+To interactively choose the degree of rotation, choose
+\fBRotate...\fP
+of the \fBTransform\fP submenu from the Command Widget.
+Alternatively, press * in the image window.
+
+A small horizontal line is drawn next to the pointer. You are now in rotate
+mode. To exit immediately, press Dismiss. In rotate mode, the Command widget
+has these options:
+
+ \fBPixel Color\fP
+
+ black
+ blue
+ cyan
+ green
+ gray
+ red
+ magenta
+ yellow
+ white
+ Browser...
+
+ \fBDirection\fP
+
+ horizontal
+ vertical
+
+ \fBHelp\fP
+ \fBDismiss\fP
+
+
+Choose a background color from the Pixel Color sub-menu. Additional background
+colors can be specified with the color browser. You can change the menu
+colors by setting the X resources pen1 through pen9.
+
+If you choose the color browser and press \fBGrab\fP, you can select the
+background color by moving the pointer to the desired color on the screen
+and press any button.
+
+Choose a point in the image window and press this button and hold. Next,
+move the pointer to another location in the image. As you move a line connects
+the initial location and the pointer. When you release the button, the
+degree of image rotation is determined by the slope of the line you just
+drew. The slope is relative to the direction you choose from the Direction
+sub-menu of the Command widget.
+
+To cancel the image rotation, move the pointer back to the starting point
+of the line and release the button.
+.SH IMAGE ANNOTATION
+
+An image is annotated interactively. There is no command line argument
+to annotate an image. To begin, choose
+\fBAnnotate\fP of the \fBImage
+Edit\fP sub-menu from the Command widget. Alternatively,
+press a in the image window.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in annotate mode. To exit immediately, press Dismiss.
+In annotate mode, the Command widget has these options:
+
+
+\fBFont Name\fP
+
+
+fixed
+
+variable
+
+5x8
+
+6x10
+
+7x13bold
+
+8x13bold
+
+9x15bold
+
+10x20
+
+12x24
+
+Browser...
+
+
+\fBFont Color\fP
+
+
+black
+
+blue
+
+cyan
+
+green
+
+gray
+
+red
+
+magenta
+
+yellow
+
+white
+
+transparent
+
+Browser...
+
+
+\fBBox Color\fP
+
+
+black
+
+blue
+
+cyan
+
+green
+
+gray
+
+red
+
+magenta
+
+yellow
+
+white
+
+transparent
+
+Browser...
+
+
+\fBRotate Text\fP
+
+
+-90
+
+-45
+
+-30
+
+0
+
+30
+
+45
+
+90
+
+180
+
+Dialog...
+
+
+\fBHelp\fP
+
+\fBDismiss\fP
+
+
+Choose a font name from the \fBFont Name\fP sub-menu. Additional font
+names can be specified with the font browser. You can change the menu names
+by setting the X resources font1 through font9.
+
+Choose a font color from the \fBFont Color\fP sub-menu. Additional font
+colors can be specified with the color browser. You can change the menu
+colors by setting the X resources pen1 through pen9.
+
+If you select the color browser and press \fBGrab\fP, you can choose the
+font color by moving the pointer to the desired color on the screen and
+press any button.
+
+If you choose to rotate the text, choose \fBRotate Text\fP from the menu
+and select an angle. Typically you will only want to rotate one line of
+text at a time. Depending on the angle you choose, subsequent lines may
+end up overwriting each other.
+
+Choosing a font and its color is optional. The default font is fixed and
+the default color is black. However, you must choose a location to begin
+entering text and press a button. An underscore character will appear at
+the location of the pointer. The cursor changes to a pencil to indicate
+you are in text mode. To exit immediately, press Dismiss.
+
+In text mode, any key presses will display the character at the location
+of the underscore and advance the underscore cursor. Enter your text and
+once completed press Apply to finish your image annotation. To correct
+errors press \fBBACK SPACE\fP. To delete an entire line of text, press
+\fBDELETE\fP.
+Any text that exceeds the boundaries of the image window is automatically
+continued onto the next line.
+
+The actual color you request for the font is saved in the image. However,
+the color that appears in your Image window may be different. For example,
+on a monochrome screen the text will appear black or white even if you
+choose the color red as the font color. However, the image saved to a file
+with \fB-write\fP is written with red lettering. To assure the correct
+color text in the final image, any \fIPseudoClass\fP image is promoted
+to \fIDirectClass\fP (see miff(5)). To force a \fIPseudoClass\fP image
+to remain
+\fIPseudoClass\fP, use \fB-colors\fP.
+.SH IMAGE COMPOSITING
+
+An image composite is created interactively. \fBThere is no command line
+argument to composite an image\fP. To begin, choose \fBComposite\fP of
+the \fBImage Edit\fP from the Command widget. Alternatively,
+press x in the Image window.
+
+First a popup window is displayed requesting you to enter an image name.
+Press \fBComposite\fP, \fBGrab\fP or type a file name. Press \fBCancel\fP
+if you choose not to create a composite image. When you choose \fBGrab\fP,
+move the pointer to the desired window and press any button.
+
+If the \fBComposite\fP image does not have any matte information, you
+are informed and the file browser is displayed again. Enter the name of
+a mask image. The image is typically grayscale and the same size as the
+composite image. If the image is not grayscale, it is converted to grayscale
+and the resulting intensities are used as matte information.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in composite mode. To exit immediately, press Dismiss.
+In composite mode, the Command widget has these options:
+
+
+\fBOperators\fP
+
+
+over
+
+in
+
+out
+
+atop
+
+xor
+
+plus
+
+minus
+
+add
+
+subtract
+
+difference
+
+bumpmap
+
+replace
+
+
+\fBBlend\fP
+
+\fBDisplace\fP
+
+\fBHelp\fP
+
+\fBDismiss\fP
+
+
+Choose a composite operation from the Operators sub-menu of the Command
+widget. How each operator behaves is described below. image window is the
+image currently displayed on your X server and image is the image obtained
+.TP
+.B "over"
+\fR
+The result is the union of the two image shapes, with \fIimage\fP obscuring
+\fIimage
+window\fP in the region of overlap.
+.TP
+.B "in"
+\fR
+The result is simply \fIimage\fP cut by the shape of
+\fIimage window\fP.
+None of the image data of image window is in the result.
+.TP
+.B "out"
+\fR
+The resulting image is \fIimage\fP with the shape of
+\fIimage window\fP
+cut out.
+.TP
+.B "atop"
+\fR
+The result is the same shape as \fIimage window\fP, with
+\fIimage\fP
+obscuring \fIimage window\fP where the image shapes overlap. Note this
+differs from over because the portion of image outside
+\fIimage window\fP's
+shape does not appear in the result.
+.TP
+.B "xor"
+\fR
+The result is the image data from both \fIimage\fP and
+\fIimage window\fP
+that is outside the overlap region. The overlap region is blank.
+.TP
+.B "plus"
+\fR
+The result is just the sum of the image data. Output values are cropped
+to 255 (no overflow). This operation is independent of the matte channels.
+.TP
+.B "minus"
+\fR
+The result of \fIimage\fP - \fIimage window\fP, with underflow cropped
+to zero. The matte channel is ignored (set to 255, full coverage).
+.TP
+.B "add"
+\fR
+The result of \fIimage\fP + \fIimage window\fP, with overflow wrapping
+around (mod 256).
+.TP
+.B "subtract"
+\fR
+The result of \fIimage\fP - \fIimage window\fP, with underflow wrapping
+around (mod 256). The add and subtract operators can be used to perform
+reversible transformations.
+.TP
+.B "difference"
+\fR
+The result of abs(\fIimage\fP - \fIimage window\fP). This is useful for
+comparing two very similar images.
+.TP
+.B "bumpmap"
+\fR
+The result of \fIimage window\fP shaded by \fIwindow\fP.
+.TP
+.B "replace"
+\fR
+The resulting image is \fIimage window\fP replaced with
+\fIimage\fP.
+Here the matte information is ignored.
+
+The image compositor requires a matte, or alpha channel in the image for
+some operations. This extra channel usually defines a mask which represents
+a sort of a cookie-cutter for the image. This is the case when matte is
+255 (full coverage) for pixels inside the shape, zero outside, and between
+zero and 255 on the boundary. If image does not have a matte channel, it
+is initialized with 0 for any pixel matching in color to pixel location
+(0,0), otherwise 255. See Matte Editing for a method
+of defining a matte channel.
+
+If you choose \fBblend\fP, the composite operator becomes \fBover\fP.
+The image matte channel percent transparency is initialized to factor.
+The image window is initialized to (100-factor). Where factor is the value
+you specify in the Dialog widget.
+
+\fBDisplace\fP shifts the image pixels as defined by a displacement map.
+With this option, \fIimage\fP is used as a displacement map. Black, within
+the displacement map, is a maximum positive displacement. White is a maximum
+negative displacement and middle gray is neutral. The displacement is scaled
+to determine the pixel shift. By default, the displacement applies in both
+the horizontal and vertical directions. However, if you specify
+\fImask\fP,
+\fIimage\fP
+is the horizontal X displacement and
+\fImask\fP the vertical Y displacement.
+
+Note that matte information for image window is not retained for colormapped
+X server visuals (e.g.
+\fIStaticColor, StaticColor, GrayScale, PseudoColor\fP).
+Correct compositing behavior may require a \fITrueColor\fP or
+\fIDirectColor\fP
+visual or a \fIStandard Colormap\fP.
+
+Choosing a composite operator is optional. The default operator is replace.
+However, you must choose a location to composite your image and press button
+1. Press and hold the button before releasing and an outline of the image
+will appear to help you identify your location.
+
+The actual colors of the composite image is saved. However, the color that
+appears in image window may be different. For example, on a monochrome
+screen Image window will appear black or white even though your composited
+image may have many colors. If the image is saved to a file it is written
+with the correct colors. To assure the correct colors are saved in the
+final image, any PseudoClass image is promoted to \fIDirectClass\fP (see
+miff).
+To force a \fIPseudoClass\fP image to remain \fIPseudoClass\fP,
+use \fB-colors\fP.
+.SH COLOR EDITING
+
+Changing the the color of a set of pixels is performed interactively. There
+is no command line argument to edit a pixel. To begin, choose \fBColor\fP
+from the \fBImage Edit\fP submenu of the Command widget.
+Alternatively, press c in the image window.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in color edit mode. To exit immediately, press \fBDismiss\fP.
+In color edit mode, the
+\fBCommand widget\fP has these options:
+
+
+\fBMethod\fP
+
+
+point
+
+replace
+
+floodfill
+
+reset
+
+
+\fBPixel Color\fP
+
+
+black
+
+blue
+
+cyan
+
+green
+
+gray
+
+red
+
+magenta
+
+yellow
+
+white
+
+Browser...
+
+
+\fBBorder Color\fP
+
+
+black
+
+blue
+
+cyan
+
+green
+
+gray
+
+red
+
+magenta
+
+yellow
+
+white
+
+Browser...
+
+
+\fBFuzz\fP
+
+
+0
+
+2
+
+4
+
+8
+
+16
+ Dialog...
+
+
+\fBUndo\fP
+
+\fBHelp\fP
+
+\fBDismiss\fP
+
+
+Choose a color editing method from the \fBMethod\fP sub-menu of
+the Command
+widget. The \fBpoint method\fP recolors any pixel selected with the
+pointer unless the button is released. The \fBreplace method\fP recolors
+any pixel that matches the color of the pixel you select with a button
+press. \fBFloodfill\fP recolors any pixel that matches the color of the
+pixel you select with a button press and is a neighbor.
+Whereas \fBfilltoborder\fP
+changes the matte value of any neighbor pixel that is not the border color.
+Finally \fBreset\fP changes the entire image to the designated color.
+
+Next, choose a pixel color from the \fBPixel Color\fP sub-menu. Additional
+pixel colors can be specified with the color browser. You can change the
+menu colors by setting the X resources pen1 through
+pen9.
+
+Now press button 1 to select a pixel within the Image window to change
+its color. Additional pixels may be recolored as prescribed by the method
+you choose. additional pixels by increasing the Delta value.
+
+If the \fBMagnify widget\fP is mapped, it can be helpful in positioning
+your pointer within the image (refer to button 2). Alternatively you can
+select a pixel to recolor from within the \fBMagnify widget\fP. Move the
+pointer to the \fBMagnify widget\fP and position the pixel with the cursor
+control keys. Finally, press a button to recolor the selected pixel (or
+pixels).
+
+The actual color you request for the pixels is saved in the image. However,
+the color that appears in your Image window may be different. For example,
+on a monochrome screen the pixel will appear black or white even if you
+choose the color red as the pixel color. However, the image saved to a
+file with -write is written with red pixels. To assure the correct color
+text in the final image, any \fIPseudoClass\fP image is promoted
+to \fIDirectClass\fP
+To force a \fIPseudoClass\fP image to remain
+\fIPseudoClass\fP, use \fB-colors\fP.
+.SH MATTE EDITING
+
+Matte information within an image is useful for some operations such as
+image compositing. This extra channel usually defines
+a mask which represents a sort of a cookie-cutter for the image. This is
+the case when matte is 255 (full coverage) for pixels inside the shape,
+zero outside, and between zero and 255 on the boundary.
+
+Setting the matte information in an image is done interactively. There
+is no command line argument to edit a pixel. To begin, and choose \fBMatte\fP
+of the \fBImage Edit\fP sub-menu from the Command widget.
+
+Alternatively, press m in the image window.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in matte edit mode. To exit immediately, press Dismiss.
+In matte edit mode, the Command widget has these options:
+
+
+\fBMethod\fP
+
+
+point
+
+replace
+
+floodfill
+
+reset
+
+
+\fBBorder Color\fP
+
+
+black
+
+blue
+
+cyan
+
+green
+
+gray
+
+red
+
+magenta
+
+yellow
+
+white
+
+Browser...
+
+
+\fBFuzz\fP
+
+
+0
+
+2
+
+4
+
+8
+
+16
+ Dialog...
+
+
+\fBMatte\fP
+
+\fBUndo\fP
+
+\fBHelp\fP
+
+\fBDismiss\fP
+
+Choose a matte editing method from the \fBMethod\fP sub-menu of the Command
+widget. The \fBpoint method\fP changes the matte value of the any
+pixel selected with the pointer until the button is released. The \fBreplace
+method\fP changes the matte value of any pixel that matches the color
+of the pixel you select with a button press. \fBFloodfill\fP changes the
+matte value of any pixel that matches the color of the pixel you select
+with a button press and is a neighbor. Whereas
+\fBfilltoborder\fP recolors
+any neighbor pixel that is not the border color. Finally \fBreset\fP changes
+the entire image to the designated matte value.
+Choose \fBMatte Value\fP and a dialog appears requesting a matte value.
+Enter a value between \fB0 and 255\fP. This value is assigned as the matte
+value of the selected pixel or pixels.
+Now, press any button to select a pixel within the Image window to change
+its matte value. You can change the matte value of additional pixels by
+increasing the Delta value. The Delta value is first added then subtracted
+from the red, green, and blue of the target color. Any pixels within the
+range also have their matte value updated.
+If the \fBMagnify widget\fP is mapped, it can be helpful in positioning
+your pointer within the image (refer to button 2). Alternatively you can
+select a pixel to change the matte value from within the
+\fBMagnify widget\fP.
+Move the pointer to the \fBMagnify widget\fP and position the pixel with
+the cursor control keys. Finally, press a button to change the matte value
+of the selected pixel (or pixels).
+Matte information is only valid in a \fIDirectClass image\fP. Therefore,
+any \fIPseudoClass\fP image is promoted to
+\fIDirectClass\fP. Note that
+matte information for \fIPseudoClass\fP is not retained for colormapped
+X server visuals (e.g. \fIStaticColor, StaticColor, GrayScale, PseudoColor\fP)
+unless you immediately save your image to a file (refer to Write). Correct
+matte editing behavior may require a \fITrueColor\fP or \fIDirectColor\fP
+visual or a \fIStandard Colormap\fP.
+.SH IMAGE DRAWING
+
+An image is drawn upon interactively. \fBThere is no command line argument
+to draw on an image\fP. To begin, choose \fBDraw\fP of the Image \fBEdit\fP
+sub-menu from the Command widget.
+Alternatively, press d in the image window.
+
+The cursor changes to a crosshair to indicate you are in draw mode. To
+exit immediately, press Dismiss. In draw mode, the Command widget has these
+options:
+
+
+\fBPrimitive\fP
+
+
+point
+
+line
+
+rectangle
+
+fill rectangle
+
+circle
+
+fill circle
+
+ellipse
+
+fill ellipse
+
+polygon
+
+fill polygon
+
+
+\fBColor\fP
+
+
+black
+
+blue
+
+cyan
+
+green
+
+gray
+
+red
+
+magenta
+
+yellow
+
+white
+
+transparent
+
+Browser...
+
+
+\fBStipple\fP
+
+
+Brick
+
+Diagonal
+
+Scales
+
+Vertical
+
+Wavy
+
+Translucent
+
+Opaque
+
+Open...
+
+
+\fBWidth\fP
+
+
+1
+
+2
+
+4
+
+8
+
+16
+ Dialog...
+
+
+\fBUndo\fP
+
+\fBHelp\fP
+
+\fBDismiss\fP
+
+Choose a drawing primitive from the \fBPrimitive\fP sub-menu.
+
+Next, choose a color from the \fBColor\fP sub-menu. Additional colors
+can be specified with the color browser. You can change the menu colors
+by setting the X resources pen1 through pen9. The transparent
+color updates the image matte channel and is useful for image compositing.
+
+If you choose the color browser and press \fBGrab\fP, you can select the
+primitive color by moving the pointer to the desired color on the screen
+and press any button. The transparent color updates the image matte channel
+and is useful for image compositing.
+
+Choose a stipple, if appropriate, from the \fBStipple\fP sub-menu. Additional
+stipples can be specified with the file browser. Stipples obtained from
+the file browser must be on disk in the X11 bitmap format.
+
+Choose a line width, if appropriate, from the \fBWidth\fP sub-menu. To
+choose a specific width select the \fBDialog\fP widget.
+
+Choose a point in the image window and press button 1 and hold. Next, move
+the pointer to another location in the image. As you move, a line connects
+the initial location and the pointer. When you release the button, the
+image is updated with the primitive you just drew. For polygons, the image
+is updated when you press and release the button without moving the pointer.
+
+To cancel image drawing, move the pointer back to the starting point of
+the line and release the button.
+.SH REGION OF INTEREST
+
+To begin, press choose Region of Interest of the Pixel Transform sub-menu
+from the Command widget.
+Alternatively, press R in the image window.
+
+A small window appears showing the location of the cursor in the image
+window. You are now in region of interest mode. In region of interest mode,
+the Command widget has these options:
+
+
+\fBHelp\fP
+
+\fBDismiss\fP
+
+
+To define a region of interest, press button 1 and drag. The region of
+interest is defined by a highlighted rectangle that expands or contracts
+as it follows the pointer. Once you are satisfied with the region of interest,
+release the button. You are now in apply mode. In apply mode the Command
+widget has these options:
+
+
+\fBFile\fP
+
+
+Save...
+
+Print...
+
+
+\fBEdit\fP
+
+
+Undo
+
+Redo
+
+
+\fBTransform\fP
+
+
+Flip
+
+Flop
+
+Rotate Right
+
+Rotate Left
+
+
+\fBEnhance\fP
+
+
+Hue...
+
+Saturation...
+
+Brightness...
+
+Gamma...
+
+Spiff
+
+Dull
+
+Equalize
+
+Normalize
+
+Negate
+
+GRAYscale
+
+Quantize...
+
+
+\fBEffects\fP
+
+
+Despeckle
+
+Emboss
+
+Reduce Noise
+
+Add Noise
+
+Sharpen...
+
+Blur...
+
+Threshold...
+
+Edge Detect...
+
+Spread...
+
+Shade...
+
+Raise...
+
+Segment...
+
+
+
+
+\fBF/X\fP
+
+
+Solarize...
+
+Swirl...
+
+Implode...
+
+Wave...
+
+Oil Paint
+
+Charcoal Draw...
+
+
+
+
+\fBMiscellany\fP
+
+
+Image Info
+
+Zoom Image
+
+Show Preview...
+
+Show Histogram
+
+Show Matte
+
+
+\fBHelp\fP
+
+\fBDismiss\fP
+
+
+You can make adjustments to the region of interest by moving the pointer
+to one of the rectangle corners, pressing a button, and dragging. Finally,
+choose an image processing technique from the Command widget. You can choose
+more than one image processing technique to apply to an area. Alternatively,
+you can move the region of interest before applying another image processing
+technique. To exit, press Dismiss.
+.SH IMAGE PANNING
+
+When an image exceeds the width or height of the X server screen, display
+maps a small panning icon. The rectangle within the panning icon shows
+the area that is currently displayed in the the image window. To pan about
+the image, press any button and drag the pointer within the panning icon.
+The pan rectangle moves with the pointer and the image window is updated
+to reflect the location of the rectangle within the panning icon. When
+you have selected the area of the image you wish to view, release the button.
+
+Use the arrow keys to pan the image one pixel up, down, left, or right
+within the image window.
+
+The panning icon is withdrawn if the image becomes smaller than the dimensions
+of the X server screen.
+.SH USER PREFERENCES
+
+Preferences affect the default behavior of \fBdisplay(1)\fP. The preferences
+are either true or false and are stored in your home directory
+as .displayrc:
+.in 15
+
+.in 15
+.B "
+\fBdisplay image centered on a backdrop\fP"
+.in 20
+ \fR
+.in 20
+
+This backdrop covers the entire workstation screen and is useful for hiding
+other X window activity while viewing the image. The color of the backdrop
+is specified as the background color. Refer to X Resources
+for details.
+.in 15
+.in 15
+.B "
+\fBconfirm on program exit\fP"
+.in 20
+ \fR
+.in 20
+
+Ask for a confirmation before exiting the \fBdisplay(1)\fP program.
+.in 15
+.in 15
+.B "
+\fBcorrect image for display gamma\fP"
+.in 20
+ \fR
+.in 20
+
+If the image has a known gamma, the gamma is corrected to match that of
+the X server (see the X Resource\fB displayGamma\fP).
+.in 15
+.in 15
+.B "
+\fBdisplay warning messages\fP"
+.in 20
+ \fR
+.in 20
+
+Display any warning messages.
+.in 15
+.in 15
+.B "
+\fBapply Floyd/Steinberg error diffusion to image\fP"
+.in 20
+ \fR
+.in 20
+
+The basic strategy of dithering is to trade intensity resolution for spatial
+resolution by averaging the intensities of several neighboring pixels.
+Images which suffer from severe contouring when reducing colors can be
+improved with this preference.
+.in 15
+.in 15
+.B "
+\fBuse a shared colormap for colormapped X visuals\fP"
+.in 20
+ \fR
+.in 20
+
+This option only applies when the default X server visual is
+\fIPseudoColor\fP
+or \fIGRAYScale\fP. Refer to \fB-visual\fP for more details. By default,
+a shared colormap is allocated. The image shares colors with other X clients.
+Some image colors could be approximated, therefore your image may look
+very different than intended. Otherwise the image colors appear exactly
+as they are defined. However, other clients may go technicolor when the
+image colormap is installed.
+.in 15
+.in 15
+.B "
+\fBdisplay images as an X server pixmap\fP"
+.in 20
+ \fR
+.in 20
+
+Images are maintained as a XImage by default. Set this resource to True
+to utilize a server Pixmap instead. This option is useful if your image
+exceeds the dimensions of your server screen and you intend to pan the
+image. Panning is much faster with Pixmaps than with a XImage. Pixmaps
+are considered a precious resource, use them with discretion.
+.in 15
+
+.TP
+.in 15
+.in 15
+.in 20
+.SH GM IDENTIFY
+
+\fBIdentify\fP describes the format and characteristics of one or
+more image files as internally supported by the software. It will also
+report if an image is incomplete or corrupt. The information
+displayed includes the scene number, the file name, the width and
+height of the image, whether the image is colormapped or not, the
+number of colors in the image, the number of bytes in the image, the
+format of the image (JPEG, PNM, etc.), and finally the number of
+seconds in both user time and elapsed time it took to read and process
+the image. If -verbose or +ping are provided as an option, the pixel
+read rate is also displayed. An example line output from
+\fBidentify\fP follows:
+
+ images/aquarium.miff 640x480 PseudoClass 256c
+ 308135b MIFF 0.000u 0:01
+
+
+If -verbose is set, expect additional output including any image
+comment:
+
+
+ Image: images/aquarium.miff
+ class: PseudoClass
+ colors: 256
+ signature: eb5dca81dd93ae7e6ffae99a527eb5dca8...
+ matte: False
+ geometry: 640x480
+ depth: 8
+ bytes: 308135
+ format: MIFF
+ comments:
+ Imported from MTV raster image: aquarium.mtv
+
+
+For some formats, additional format-specific information about the file
+will be written if the -debug coder or -debug all option
+is used.
+.SH IDENTIFY OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images immediately
+following, until the set is terminated by the appearance of any option
+or \fB-noop\fP.
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-format \fI<string>"\fP
+\fRoutput formatted image characteristics
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-ping"
+\fRefficiently determine image characteristics
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+
+For a more detailed description of each option, see
+Options, above.
+
+.SH GM IMPORT
+
+\fBImport\fP reads an image from any visible window on an X server and
+outputs it as an image file. You can capture a single window, the entire
+screen, or any rectangular portion of the screen.
+Use \fIdisplay\fP
+for redisplay, printing, editing, formatting, archiving, image processing,
+etc. of the captured image.
+
+The target window can be specified by id, name, or may be selected
+by clicking the mouse in the desired window. If you press a button and
+then drag, a rectangle will form which expands and contracts as the mouse
+moves. To save the portion of the screen defined by the rectangle, just
+release the button. The keyboard bell is rung once at the beginning of
+the screen capture and twice when it completes.
+.SH EXAMPLES
+
+To select an X window or an area of the screen with the mouse and save it
+in the MIFF image format to a file entitled window.miff, use:
+
+ gm import window.miff
+
+
+To select an X window or an area of the screen with the mouse and save it
+in the Encapsulated PostScript format to include in another document, use:
+
+ gm import figure.eps
+
+
+To capture the entire X server screen in the JPEG image format in a file
+entitled root.jpeg, without using the mouse, use:
+
+ gm import -window root root.jpeg
+
+
+To capture the 512x256 area at the upper right corner of the X server
+screen in the PNG image format in a well-compressed file entitled corner.png,
+without using the mouse, use:
+
+ gm import -window root -crop 512x256-0+0 -quality 90
+ corner.png
+
+.SH OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect.
+
+\fBImport\fP options can appear on the command line or in your
+X resources file. See \fIX(1)\fP. Options on the command line supersede
+values specified in your X resources file.
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-bordercolor \fI<color>"\fP
+\fRthe border color
+.TP
+.B "-colors \fI<value>"\fP
+\fRpreferred number of colors in the image
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+.TP
+.B "-comment \fI<string>"\fP
+\fRannotate an image with a comment
+.TP
+.B "-crop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRpreferred size and location of the cropped image
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-delay \fI<1/100ths of a second>"\fP
+\fRdisplay the next image after pausing
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-descend"
+\fRobtain image by descending window hierarchy
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+.TP
+.B "-dispose \fI<method>"\fP
+\fRGIF disposal method
+.TP
+.B "-dither"
+\fRapply Floyd/Steinberg error diffusion to the image
+.TP
+.B "-encoding \fI<type>"\fP
+\fRspecify the text encoding
+.TP
+.B "-endian \fI<type>"\fP
+\fRspecify endianness (MSB, LSB, or Native) of image
+.TP
+.B "-frame"
+\fRinclude the X window frame in the imported image
+.TP
+.B "-geometry \fI<width>x<height>{+-}<x>{+-}<y>{%}{@}{!}{^}{<}{>}"\fP
+\fRSpecify dimension, offset, and resize options.
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-label \fI<name>"\fP
+\fRassign a label to an image
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-monitor"
+\fRshow progress indication
+.TP
+.B "-monochrome"
+\fRtransform the image to black and white
+.TP
+.B "-negate"
+\fRreplace every pixel with its complementary color
+.TP
+.B "-page \fI<width>x<height>{+-}<x>{+-}<y>{%}{!}{<}{>}"\fP
+\fRsize and location of an image canvas
+.TP
+.B "-pause \fI<seconds>"\fP
+\fRpause between snapshots [import]
+.TP
+.B "-ping"
+\fRefficiently determine image characteristics
+.TP
+.B "-pointsize \fI<value>"\fP
+\fRpointsize of the PostScript, X11, or TrueType font
+.TP
+.B "-quality \fI<value>"\fP
+\fRJPEG/MIFF/PNG/TIFF compression level
+.TP
+.B "-resize \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image
+.TP
+.B "-rotate \fI<degrees>{<}{>}"\fP
+\fRrotate the image
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-scene \fI<value>"\fP
+\fRset scene number
+.TP
+.B "-screen"
+\fRspecify the screen to capture
+.TP
+.B "-set \fI<attribute> <value>"\fP
+\fRset an image attribute
+.TP
+.B "+set \fI<attribute>"\fP
+\fRunset an image attribute
+.TP
+.B "-silent"
+\fRoperate silently
+.TP
+.B "-snaps \fI<value>"\fP
+\fRnumber of screen snapshots
+.TP
+.B "-thumbnail \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image (quickly)
+.TP
+.B "-transparent \fI<color>"\fP
+\fRmake this color transparent within the image
+.TP
+.B "-trim"
+\fRtrim an image
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+
+For a more detailed description of each option, see
+Options, above.
+
+.SH GM MOGRIFY
+
+\fBMogrify\fP transforms an image or a sequence of images. These transforms
+include image scaling, image rotation, color reduction, and others. Each
+transmogrified image overwrites the corresponding original image, unless an
+option such as
+\fB-format\fP causes the output filename to be different from the input
+filename.
+
+The graphics formats supported by \fBmogrify\fP are listed in
+\fIGraphicsMagick(1)\fP.
+.SH EXAMPLES
+
+To convert all the TIFF files in a particular directory to JPEG, use:
+
+ gm mogrify -format jpeg *.tiff
+
+
+To convert a directory full of JPEG images to thumbnails, use:
+
+ gm mogrify -size 120x120 *.jpg -resize 120x120 +profile "*"
+
+
+In this example, '-size 120x120' gives a hint to the JPEG decoder
+that the images are going to be downscaled to 120x120, allowing it to run
+faster by avoiding returning full-resolution images to GraphicsMagick for
+the subsequent resizing operation. The
+\'-resize 120x120' specifies the desired dimensions of the
+output images. It will be scaled so its largest dimension is 120 pixels. The
+\'+profile "*"' removes any ICM, EXIF, IPTC, or other profiles
+that might be present in the input and aren't needed in the thumbnails.
+
+To scale an image of a cockatoo to exactly 640 pixels in width and 480
+pixels in height, use:
+
+ gm mogrify -resize 640x480! cockatoo.miff
+
+.SH OPTIONS
+
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or \fB-noop\fP.
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-affine \fI<matrix>"\fP
+\fRdrawing transform matrix
+.TP
+.B "-antialias"
+\fRremove pixel aliasing
+.TP
+.B " \fI-asc-cdl <spec>"\fP
+\fRapply ASC CDL color transform
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+.TP
+.B "-auto-orient"
+\fRorient (rotate) image so it is upright
+.TP
+.B "-background \fI<color>"\fP
+\fRthe background color
+.TP
+.B "-black-threshold \fIred[,green][,blue][,opacity]"\fP
+\fRpixels below the threshold become black
+.TP
+.B "-blue-primary \fI<x>,<y>"\fP
+\fRblue chromaticity primary point
+.TP
+.B "-blur \fI<radius>{x<sigma>}"\fP
+\fRblur the image with a Gaussian operator
+.TP
+.B "-border \fI<width>x<height>"\fP
+\fRsurround the image with a border of color
+.TP
+.B "-bordercolor \fI<color>"\fP
+\fRthe border color
+.TP
+.B "-channel \fI<type>"\fP
+\fRthe type of channel
+.TP
+.B "-charcoal \fI<factor>"\fP
+\fRsimulate a charcoal drawing
+.TP
+.B "-colorize \fI<value>"\fP
+\fRcolorize the image with the pen color
+.TP
+.B "-colors \fI<value>"\fP
+\fRpreferred number of colors in the image
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+.TP
+.B "-comment \fI<string>"\fP
+\fRannotate an image with a comment
+.TP
+.B "-compose \fI<operator>"\fP
+\fRthe type of image composition
+.TP
+.B "-compress \fI<type>"\fP
+\fRthe type of image compression
+.TP
+.B "-contrast"
+\fRenhance or reduce the image contrast
+.TP
+.B "-convolve \fI<kernel>"\fP
+\fRconvolve image with the specified convolution kernel
+.TP
+.B "-create-directories"
+\fRcreate output directory if required
+.TP
+.B "-crop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRpreferred size and location of the cropped image
+.TP
+.B "-cycle \fI<amount>"\fP
+\fRdisplace image colormap by amount
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-delay \fI<1/100ths of a second>"\fP
+\fRdisplay the next image after pausing
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-despeckle"
+\fRreduce the speckles within an image
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+.TP
+.B "-dispose \fI<method>"\fP
+\fRGIF disposal method
+.TP
+.B "-dither"
+\fRapply Floyd/Steinberg error diffusion to the image
+.TP
+.B "-draw \fI<string>"\fP
+\fRannotate an image with one or more graphic primitives
+.TP
+.B "-edge \fI<radius>"\fP
+\fRdetect edges within an image
+.TP
+.B "-emboss \fI<radius>"\fP
+\fRemboss an image
+.TP
+.B "-encoding \fI<type>"\fP
+\fRspecify the text encoding
+.TP
+.B "-endian \fI<type>"\fP
+\fRspecify endianness (MSB, LSB, or Native) of image
+.TP
+.B "-enhance"
+\fRapply a digital filter to enhance a noisy image
+.TP
+.B "-equalize"
+\fRperform histogram equalization to the image
+.TP
+.B "-extent \fI<width>x<height>{+-}<x>{+-}<y>"\fP
+\fRcomposite image on background color canvas image
+.TP
+.B "-fill \fI<color>"\fP
+\fRcolor to use when filling a graphic primitive
+.TP
+.B "-filter \fI<type>"\fP
+\fRuse this type of filter when resizing an image
+.TP
+.B "-flip"
+\fRcreate a "mirror image"
+.TP
+.B "-flop"
+\fRcreate a "mirror image"
+.TP
+.B "-font \fI<name>"\fP
+\fRuse this font when annotating the image with text
+.TP
+.B "-format \fI<type>"\fP
+\fRthe image format type
+.TP
+.B "-frame \fI<width>x<height>+<outer bevel width>+<inner bevel width>"\fP
+\fRsurround the image with an ornamental border
+.TP
+.B "-fuzz \fI<distance>{%}"\fP
+\fRcolors within this Euclidean distance are considered equal
+.TP
+.B "-gamma \fI<value>"\fP
+\fRlevel of gamma correction
+.TP
+.B "-gaussian \fI<radius>{x<sigma>}"\fP
+\fRblur the image with a Gaussian operator
+.TP
+.B "-geometry \fI<width>x<height>{+-}<x>{+-}<y>{%}{@}{!}{^}{<}{>}"\fP
+\fRSpecify dimension, offset, and resize options.
+.TP
+.B "-gravity \fI<type>"\fP
+\fRdirection primitive gravitates to when annotating the image.
+.TP
+.B "-green-primary \fI<x>,<y>"\fP
+\fRgreen chromaticity primary point
+.TP
+.B "-hald-clut \fI<clut>"\fP
+\fRapply a Hald CLUT to the image
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-implode \fI<factor>"\fP
+\fRimplode image pixels about the center
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-label \fI<name>"\fP
+\fRassign a label to an image
+.TP
+.B "-lat \fI<width>x<height>{+-}<offset>{%}"\fP
+\fRperform local adaptive thresholding
+.TP
+.B "-level \fI<black_point>{,<gamma>}{,<white_point>}{%}"\fP
+\fRadjust the level of image contrast
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-linewidth"
+\fRthe line width for subsequent draw operations
+.TP
+.B "-list \fI<type>"\fP
+\fRthe type of list
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-loop \fI<iterations>"\fP
+\fRadd Netscape loop extension to your GIF animation
+.TP
+.B "-magnify"
+\fRmagnify the image
+.TP
+.B "-map \fI<filename>"\fP
+\fRchoose a particular set of colors from this image
+.TP
+.B "-mask \fI<filename>"\fP
+\fRSpecify a clipping mask
+.TP
+.B "-matte"
+\fRstore matte channel if the image has one
+.TP
+.B "-mattecolor \fI<color>"\fP
+\fRspecify the color to be used with the \fB-frame\fP option
+.TP
+.B "-median \fI<radius>"\fP
+\fRapply a median filter to the image
+.TP
+.B "-minify \fI<factor>"\fP
+\fRminify the image
+.TP
+.B "-modulate \fIbrightness[,saturation[,hue]]"\fP
+\fRvary the brightness, saturation, and hue of an image
+.TP
+.B "-monitor"
+\fRshow progress indication
+.TP
+.B "-monochrome"
+\fRtransform the image to black and white
+.TP
+.B "-motion-blur \fI<radius>{x<sigma>}{+angle}"\fP
+\fRSimulate motion blur
+.TP
+.B "-negate"
+\fRreplace every pixel with its complementary color
+.TP
+.B "-noise \fI<radius|type>"\fP
+\fRadd or reduce noise in an image
+.TP
+.B "-noop"
+\fRNOOP (no option)
+.TP
+.B "-normalize"
+\fRtransform image to span the full range of color values
+.TP
+.B "-opaque \fI<color>"\fP
+\fRchange this color to the pen color within the image
+.TP
+.B "-operator \fIchannel operator rvalue[%]"\fP
+\fRapply a mathematical, bitwise, or value operator to an image channel
+.TP
+.B "-ordered-dither \fI<channeltype> <NxN>"\fP
+\fRordered dither the image
+.TP
+.B "-output-directory \fI<directory>"\fP
+\fRoutput files to directory
+.TP
+.B "-orient \fI<orientation>"\fP
+\fRSet the image orientation attribute
+.TP
+.B "-page \fI<width>x<height>{+-}<x>{+-}<y>{%}{!}{<}{>}"\fP
+\fRsize and location of an image canvas
+.TP
+.B "-paint \fI<radius>"\fP
+\fRsimulate an oil painting
+.TP
+.B "-pen \fI<color>"\fP
+\fR(This option has been replaced by the -fill option)
+.TP
+.B "-pointsize \fI<value>"\fP
+\fRpointsize of the PostScript, X11, or TrueType font
+.TP
+.B "-profile \fI<filename>"\fP
+\fRadd ICM, IPTC, or generic profile to image
+.TP
+.B "-preserve-timestamp"
+\fRpreserve the original timestamps of the file
+.TP
+.B "-quality \fI<value>"\fP
+\fRJPEG/MIFF/PNG/TIFF compression level
+.TP
+.B "-raise \fI<width>x<height>"\fP
+\fRlighten or darken image edges
+.TP
+.B "-random-threshold \fI<channeltype> <LOWxHIGH>"\fP
+\fRrandom threshold the image
+.TP
+.B "-recolor \fI<matrix>"\fP
+\fRapply a color translation matrix to image channels
+.TP
+.B "-red-primary \fI<x>,<y>"\fP
+\fRred chromaticity primary point
+.TP
+.B "-region \fI<width>x<height>{+-}<x>{+-}<y>"\fP
+\fRapply options to a portion of the image
+.TP
+.B "-render"
+\fRrender vector operations
+.TP
+.B "-repage \fI <width>x<height>+xoff+yoff[!]"\fP
+\fRAdjust image page offsets
+.TP
+.B "-resample \fI<horizontal>x<vertical>"\fP
+\fRResample image to specified horizontal and vertical resolution
+.TP
+.B "-resize \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image
+.TP
+.B "-roll \fI{+-}<x>{+-}<y>"\fP
+\fRroll an image vertically or horizontally
+.TP
+.B "-rotate \fI<degrees>{<}{>}"\fP
+\fRrotate the image
+.TP
+.B "-sample \fI<geometry>"\fP
+\fRscale image using pixel sampling
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-scale \fI<geometry>"\fP
+\fRscale the image.
+.TP
+.B "-scene \fI<value>"\fP
+\fRset scene number
+.TP
+.B "-set \fI<attribute> <value>"\fP
+\fRset an image attribute
+.TP
+.B "+set \fI<attribute>"\fP
+\fRunset an image attribute
+.TP
+.B "-segment \fI<cluster threshold>x<smoothing threshold>"\fP
+\fRsegment an image
+.TP
+.B "-shade \fI<azimuth>x<elevation>"\fP
+\fRshade the image using a distant light source
+.TP
+.B "-sharpen \fI<radius>{x<sigma>}"\fP
+\fRsharpen the image
+.TP
+.B "-shave \fI<width>x<height>{%}"\fP
+\fRshave pixels from the image edges
+.TP
+.B "-shear \fI<x degrees>x<y degrees>"\fP
+\fRshear the image along the X or Y axis
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+.TP
+.B "-solarize \fI<factor>"\fP
+\fRnegate all pixels above the threshold level
+.TP
+.B "-spread \fI<amount>"\fP
+\fRdisplace image pixels by a random amount
+.TP
+.B "-strip"
+\fRremove all profiles and text attributes from the image
+.TP
+.B "-stroke \fI<color>"\fP
+\fRcolor to use when stroking a graphic primitive
+.TP
+.B "-strokewidth \fI<value>"\fP
+\fRset the stroke width
+.TP
+.B "-swirl \fI<degrees>"\fP
+\fRswirl image pixels about the center
+.TP
+.B "-texture \fI<filename>"\fP
+\fRname of texture to tile onto the image background
+.TP
+.B "-threshold \fI<value>{%}"\fP
+\fRthreshold the image
+.TP
+.B "-thumbnail \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image (quickly)
+.TP
+.B "-tile \fI<filename>"\fP
+\fRtile image when filling a graphic primitive
+.TP
+.B "-transform"
+\fRtransform the image
+.TP
+.B "-transparent \fI<color>"\fP
+\fRmake this color transparent within the image
+.TP
+.B "-treedepth \fI<value>"\fP
+\fRtree depth for the color reduction algorithm
+.TP
+.B "-trim"
+\fRtrim an image
+.TP
+.B "-type \fI<type>"\fP
+\fRthe image type
+.TP
+.B "-units \fI<type>"\fP
+\fRthe units of image resolution
+.TP
+.B "-unsharp \fI<radius>{x<sigma>}{+<amount>}{+<threshold>}"\fP
+\fRsharpen the image with an unsharp mask operator
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+.TP
+.B "-view \fI<string>"\fP
+\fRFlashPix viewing parameters
+.TP
+.B "-virtual-pixel \fI<method>"\fP
+\fRspecify contents of "virtual pixels"
+.TP
+.B "-wave \fI<amplitude>x<wavelength>"\fP
+\fRalter an image along a sine wave
+.TP
+.B "-white-point \fI<x>,<y>"\fP
+\fRchromaticity white point
+.TP
+.B "-white-threshold \fIred[,green][,blue][,opacity]"\fP
+\fRpixels above the threshold become white
+
+For a more detailed description of each option, see
+Options, above.
+
+.SH GM MONTAGE
+
+\fBmontage\fP creates a composite image by combining several separate
+images. The images are tiled on the composite image with the name of the
+image optionally appearing just below the individual tile.
+
+The composite image is constructed in the following manner. First, each
+image specified on the command line, except for the last, is scaled to
+fit the maximum tile size. The maximum tile size by default is 120x120.
+It can be modified with the \fB-geometry\fP command line argument or X
+resource. See
+\fBOptions\fP
+for more information on command line arguments. See
+\fBX(1)\fP for more information on X resources.
+Note that the maximum tile size need not be a square.
+
+Next the composite image is initialized with the color specified by the
+\fB-background\fP
+command line argument or X resource. The width and height of the composite
+image is determined by the title specified, the maximum tile size, the
+number of tiles per row, the tile border width and height, the image border
+width, and the label height. The number of tiles per row specifies how
+many images are to appear in each row of the composite image. The default
+is to have 5 tiles in each row and 4 tiles in each column of the composite.
+A specific value is specified with \fB-tile\fP. The tile border width
+and height, and the image border width defaults to the value of the X resource
+\fB-borderwidth\fP. It can be changed with the \fB-borderwidth\fP or
+\fB-geometry\fP command line argument or X resource. The label height
+is determined by the font you specify with the \fB-font\fP command line
+argument or X resource. If you do not specify a font, a font is chosen
+that allows the name of the image to fit the maximum width of a tiled area.
+The label colors is determined by the \fB-background\fP and \fB-fill\fP
+command line argument or X resource. Note, that if the background and pen
+colors are the same, labels will not appear.
+
+Initially, the composite image title is placed at the top if one is specified
+(refer to \fB-fill\fP). Next, each image is set onto the composite image,
+surrounded by its border color, with its name centered just below it. The
+individual images are left-justified within the width of the tiled area.
+The order of the images is the same as they appear on the command line
+unless the images have a scene keyword. If a scene number is specified
+in each image, then the images are tiled onto the composite in the order
+of their scene number. Finally, the last argument on the command line is
+the name assigned to the composite image. By default, the image is written
+in the \fBMIFF\fP format and can be viewed or printed with
+\fIdisplay(1)\fP.
+
+
+Note, that if the number of tiles exceeds the default number of 20 (5 per
+row, 4 per column), more than one composite image is created. To ensure
+a single image is produced, use \fB-tile\fP to increase the number of
+tiles to meet or exceed the number of input images.
+
+Finally, to create one or more empty spaces in the sequence of tiles, use
+the \fB"NULL:"\fP image format.
+
+Note, a composite MIFF image displayed to an X server with
+\fBdisplay\fP
+behaves differently than other images. You can think of the composite as
+a visual image directory. Choose a particular tile of the composite and
+press a button to display it. See \fBdisplay(1)\fP and \fBmiff(5)\fP
+.SH EXAMPLES
+
+To create a montage of a cockatoo, a parrot, and a hummingbird and write
+it to a file called birds, use:
+
+ gm montage cockatoo.miff parrot.miff hummingbird.miff
+ birds.miff
+
+
+To tile several bird images so that they are at most 256 pixels in width
+and 192 pixels in height, surrounded by a red border, and separated by
+10 pixels of background color, use:
+
+ gm montage -geometry 256x192+10+10 -bordercolor red
+ birds.* montage.miff
+
+
+To create an unlabeled parrot image, 640 by 480 pixels, and surrounded
+by a border of black, use:
+
+ gm montage -geometry 640x480 -bordercolor black
+ -label "" parrot.miff bird.miff
+
+
+To create an image of an eagle with a textured background, use:
+
+ gm montage -texture bumps.jpg eagle.jpg eagle.png
+
+
+To join several GIF images together without any extraneous graphics (e.g.
+no label, no shadowing, no surrounding tile frame), use:
+
+ gm montage +frame +shadow +label -tile 5x1
+ -geometry 50x50+0+0 *.png joined.png
+
+.SH OPTIONS
+
+Any option you specify on the command line remains in effect for the group
+of images following it, until the group is terminated by the appearance of
+any option or \fB-noop\fP. For example, to make a montage of three images,
+the first with 32 colors, the second with an unlimited number of colors, and
+the third with only 16 colors, use:
+
+
+ gm montage -colors 32 cockatoo.1 -noop cockatoo.2
+ -colors 16 cockatoo.3 cockatoos.miff
+
+
+For a more detailed description of each option, see
+Options, above.
+
+.TP
+.B "-adjoin"
+\fRjoin images into a single multi-image file
+.TP
+.B "-affine \fI<matrix>"\fP
+\fRdrawing transform matrix
+.TP
+.B "-authenticate \fI<string>"\fP
+\fRdecrypt image with this password
+.TP
+.B "-background \fI<color>"\fP
+\fRthe background color
+.TP
+.B "-blue-primary \fI<x>,<y>"\fP
+\fRblue chromaticity primary point
+.TP
+.B "-blur \fI<radius>{x<sigma>}"\fP
+\fRblur the image with a Gaussian operator
+.TP
+.B "-bordercolor \fI<color>"\fP
+\fRthe border color
+.TP
+.B "-borderwidth \fI<geometry>"\fP
+\fRthe border width
+.TP
+.B "-chop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRremove pixels from the interior of an image
+.TP
+.B "-colors \fI<value>"\fP
+\fRpreferred number of colors in the image
+.TP
+.B "-colorspace \fI<value>"\fP
+\fRthe type of colorspace
+.TP
+.B "-comment \fI<string>"\fP
+\fRannotate an image with a comment
+.TP
+.B "-compose \fI<operator>"\fP
+\fRthe type of image composition
+.TP
+.B "-compress \fI<type>"\fP
+\fRthe type of image compression
+.TP
+.B "-crop \fI<width>x<height>{+-}<x>{+-}<y>{%}"\fP
+\fRpreferred size and location of the cropped image
+.TP
+.B "-debug \fI<events>"\fP
+\fRenable debug printout
+.TP
+.B "-define \fI<key>{=<value>},..."\fP
+\fRadd coder/decoder specific options
+.TP
+.B "-density \fI<width>x<height>"\fP
+\fRhorizontal and vertical resolution in pixels of the image
+.TP
+.B "-depth \fI<value>"\fP
+\fRdepth of the image
+.TP
+.B "-display \fI<host:display[.screen]>"\fP
+\fRspecifies the X server to contact
+.TP
+.B "-dispose \fI<method>"\fP
+\fRGIF disposal method
+.TP
+.B "-dither"
+\fRapply Floyd/Steinberg error diffusion to the image
+.TP
+.B "-draw \fI<string>"\fP
+\fRannotate an image with one or more graphic primitives
+.TP
+.B "-encoding \fI<type>"\fP
+\fRspecify the text encoding
+.TP
+.B "-endian \fI<type>"\fP
+\fRspecify endianness (MSB, LSB, or Native) of image
+.TP
+.B "-fill \fI<color>"\fP
+\fRcolor to use when filling a graphic primitive
+.TP
+.B "-filter \fI<type>"\fP
+\fRuse this type of filter when resizing an image
+.TP
+.B "-font \fI<name>"\fP
+\fRuse this font when annotating the image with text
+.TP
+.B "-frame \fI<width>x<height>+<outer bevel width>+<inner bevel width>"\fP
+\fRsurround the image with an ornamental border
+.TP
+.B "-gamma \fI<value>"\fP
+\fRlevel of gamma correction
+.TP
+.B "-geometry \fI<width>x<height>{+-}<x>{+-}<y>{%}{@}{!}{^}{<}{>}"\fP
+\fRSpecify dimension, offset, and resize options.
+.TP
+.B "-gravity \fI<type>"\fP
+\fRdirection primitive gravitates to when annotating the image.
+.TP
+.B "-green-primary \fI<x>,<y>"\fP
+\fRgreen chromaticity primary point
+.TP
+.B "-help"
+\fRprint usage instructions
+.TP
+.B "-interlace \fI<type>"\fP
+\fRthe type of interlacing scheme
+.TP
+.B "-label \fI<name>"\fP
+\fRassign a label to an image
+.TP
+.B "-limit \fI<type> <value>"\fP
+\fRDisk, File, Map, Memory, Pixels, Width, Height or Threads resource limit
+.TP
+.B "-log \fI<string>"\fP
+\fRSpecify format for debug log
+.TP
+.B "-matte"
+\fRstore matte channel if the image has one
+.TP
+.B "-mattecolor \fI<color>"\fP
+\fRspecify the color to be used with the \fB-frame\fP option
+.TP
+.B "-mode \fI<value>"\fP
+\fRmode of operation
+.TP
+.B "-monitor"
+\fRshow progress indication
+.TP
+.B "-monochrome"
+\fRtransform the image to black and white
+.TP
+.B "-noop"
+\fRNOOP (no option)
+.TP
+.B "-page \fI<width>x<height>{+-}<x>{+-}<y>{%}{!}{<}{>}"\fP
+\fRsize and location of an image canvas
+.TP
+.B "-pen \fI<color>"\fP
+\fR(This option has been replaced by the -fill option)
+.TP
+.B "-pointsize \fI<value>"\fP
+\fRpointsize of the PostScript, X11, or TrueType font
+.TP
+.B "-quality \fI<value>"\fP
+\fRJPEG/MIFF/PNG/TIFF compression level
+.TP
+.B "-red-primary \fI<x>,<y>"\fP
+\fRred chromaticity primary point
+.TP
+.B "-render"
+\fRrender vector operations
+.TP
+.B "-repage \fI <width>x<height>+xoff+yoff[!]"\fP
+\fRAdjust image page offsets
+.TP
+.B "-resize \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image
+.TP
+.B "-rotate \fI<degrees>{<}{>}"\fP
+\fRrotate the image
+.TP
+.B "-sampling-factor \fI<horizontal_factor>x<vertical_factor>"\fP
+\fRchroma subsampling factors
+.TP
+.B "-scenes \fI<value-value>"\fP
+\fRrange of image scene numbers to read
+.TP
+.B "-shadow \fI<radius>{x<sigma>}"\fP
+\fRshadow the montage
+.TP
+.B "-sharpen \fI<radius>{x<sigma>}"\fP
+\fRsharpen the image
+.TP
+.B "-size \fI<width>x<height>{+offset}"\fP
+\fRwidth and height of the image
+.TP
+.B "-strip"
+\fRremove all profiles and text attributes from the image
+.TP
+.B "-stroke \fI<color>"\fP
+\fRcolor to use when stroking a graphic primitive
+.TP
+.B "-strokewidth \fI<value>"\fP
+\fRset the stroke width
+.TP
+.B "-texture \fI<filename>"\fP
+\fRname of texture to tile onto the image background
+.TP
+.B "-thumbnail \fI<width>x<height>{%}{@}{!}{<}{>}"\fP
+\fRresize an image (quickly)
+.TP
+.B "-tile \fI<geometry>"\fP
+\fRlayout of images [\fImontage\fP]
+.TP
+.B "-title \fI<string>"\fP
+\fRassign title to displayed image [\fIanimate, display, montage\fP]
+.TP
+.B "-transform"
+\fRtransform the image
+.TP
+.B "-transparent \fI<color>"\fP
+\fRmake this color transparent within the image
+.TP
+.B "-treedepth \fI<value>"\fP
+\fRtree depth for the color reduction algorithm
+.TP
+.B "-trim"
+\fRtrim an image
+.TP
+.B "-type \fI<type>"\fP
+\fRthe image type
+.TP
+.B "-verbose"
+\fRprint detailed information about the image
+.TP
+.B "-version"
+\fRprint GraphicsMagick version string
+.TP
+.B "-white-point \fI<x>,<y>"\fP
+\fRchromaticity white point
+
+For a more detailed description of each option, see
+Options, above.
+
+.SH X RESOURCES
+
+\fBMontage\fP options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See \fBX(1)\fP for more information on X resources.
+
+All \fBmontage\fP options have a corresponding X resource. In addition,
+\fBmontage\fP
+uses the following X resources:
+.TP
+.B "background \fI(class Background)"\fP
+\fRbackground color
+
+Specifies the preferred color to use for the composite image background.
+The default is #ccc.
+.TP
+.B "borderColor \fI(class BorderColor)"\fP
+\fRborder color
+
+Specifies the preferred color to use for the composite image border. The
+default is #ccc.
+.TP
+.B "borderWidth \fI(class BorderWidth)"\fP
+\fRborder width
+
+Specifies the width in pixels of the composite image border. The default
+is 2.
+.TP
+.B "font \fI(class Font)"\fP
+\fRfont to use
+
+Specifies the name of the preferred font to use when displaying text within
+the composite image. The default is 9x15, fixed, or 5x8 determined by the
+composite image size.
+.TP
+.B "matteColor \fI(class MatteColor)"\fP
+\fRcolor of the frame
+
+Specify the color of an image frame. A 3D effect is achieved by using highlight
+and shadow colors derived from this color. The default value is #697B8F.
+.TP
+.B "pen \fI(class Pen)"\fP
+\fRtext color
+
+Specifies the preferred color to use for text within the composite image.
+The default is black.
+.TP
+.B "title \fI(class Title)"\fP
+\fRcomposite image title
+
+This resource specifies the title to be placed at the top of the composite
+image. The default is not to place a title at the top of the composite
+image.
+.SH GM TIME
+.SH DESCRIPTION
+
+\fBtime\fP executes an arbitrary \fBgm\fP utility command
+(e.g. \fBconvert\fP) and reports the user and elapsed time. This
+provides way to measure command execution times similar to the Unix
+\'time' command but in a portable and consistent way.
+.SH EXAMPLES
+To obtain time information for the execution of a
+command:
+
+% gm time convert input.ppm -gaussian 0x2 output.ppm
+convert input.ppm -gaussian 0x2 output.ppm 22.60s user 0.00s system 2354% cpu 0.960 total
+
+Here is the interpretation of the above output:
+
+ \fBuser\fP - the total user time consumed.
+ \fBsystem\fP - the total system time consumed.
+ \fBtotal\fP - the total elapsed time consumed.
+
+.SH OPTIONS
+The time command reqires no options other than the gm command to
+execute.
+.SH GM VERSION
+.SH DESCRIPTION
+
+\fBversion\fP displays the software release version, build quantum
+(pixel sample) depth, web site URL, copyright notice, enabled features
+support, configuration parameters, and final build options used to
+build the software. The available information depends on how the
+software was configured and the host system.
+.SH EXAMPLES
+To display the version information:
+
+ % gm -version
+ GraphicsMagick 1.3.19 2013-12-31 Q16 http://www.GraphicsMagick.org/
+ Copyright (C) 2002-2013 GraphicsMagick Group.
+ Additional copyrights and licenses apply to this software.
+ See http://www.GraphicsMagick.org/www/Copyright.html for details.
+ Feature Support:
+ Thread Safe yes
+ Large Files (> 32 bit) yes
+ Large Memory (> 32 bit) no
+ BZIP yes
+ DPS no
+ FlashPix no
+ FreeType yes
+ Ghostscript (Library) no
+ JBIG no
+ JPEG-2000 yes
+ JPEG yes
+ Little CMS yes
+ Loadable Modules no
+ OpenMP yes (201107)
+ PNG yes
+ TIFF yes
+ TRIO no
+ UMEM yes
+ WMF no
+ X11 yes
+ XML yes
+ ZLIB yes
+ Host type: i386-pc-solaris2.11
+ Configured using the command:
+ ./configure ...
+ Final Build Parameters:
+ CC = ...
+ CFLAGS = ...
+ CPPFLAGS = ...
+ CXX = ...
+ CXXFLAGS = ...
+ LDFLAGS = ...
+ LIBS = ...
+
+.SH OPTIONS
+The version command does not currently support any options.
diff --git a/utilities/gm.c b/utilities/gm.c
new file mode 100644
index 0000000..31f477d
--- /dev/null
+++ b/utilities/gm.c
@@ -0,0 +1,62 @@
+/*
+% Copyright (C) 2003 GraphicsMagick Group
+% Copyright (C) 2002 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% GGGG M M %
+% G MM MM %
+% G GG M M M %
+% G G M M %
+% GGG M M %
+% %
+% %
+% GraphicsMagick Driver %
+% %
+% %
+% %
+% Software Design %
+% Glenn Randers-Pehrson %
+% December 2002 %
+% Header Centered By %
+% Bob Friesenhahn %
+% May 2003 %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Gm is a common wrapper around a set of commands, which include animate,
+% composite, conjure, convert, display, identify, import, mogrify, and
+% montage. Please see the manual page gm.1 for detailed usage information.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/api.h"
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a i n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+int main(int argc,char **argv)
+{
+ return GMCommand(argc,argv);
+}
diff --git a/utilities/miff.4 b/utilities/miff.4
new file mode 100644
index 0000000..d44405e
--- /dev/null
+++ b/utilities/miff.4
@@ -0,0 +1,271 @@
+.ad l
+.nh
+.TH MIFF 4 "$Date$" "ImageMagick"
+.SH NAME
+MIFF - Magick Image File Format
+.SH SYNOPSIS
+.B #include <image.h>
+.SH DESCRIPTION
+The Magick Image File Format (MIFF) is a platform-independent format for
+storing bitmap images. MIFF is a part of the ImageMagick toolkit of
+image manipulation utilities for the X Window System. ImageMagick is
+capable of converting many different image file formats to and from MIFF
+(e.g. JPEG, XPM, TIFF, etc.).
+
+A MIFF image file consist of two sections. The first section is a
+header composed of keys describing the image in text form. The
+next section is the binary image data. The header is separated from
+the image data by a \fB:\fP character immediately followed by a
+\fBnewline\fP.
+
+The MIFF header is composed entirely of LATIN-1 characters. The fields
+in the header are key and value combination in the
+\fIkey=value\fP format, with each key and value separated by an
+equal sign (=). Each \fIkey=value\fP combination is delimited by
+at least one control or whitespace character. Comments may appear in
+the header section and are always delimited by braces. The MIFF header
+always ends with a colon (:) character, followed by a \fBctrl-Z\fP
+character. It is also common to proceed the colon with a \fBformfeed\fP
+and a \fBnewline\fP character. The \fBformfeed\fP prevents the listing
+of binary data when using \fBmore(1)\fP under Unix where the \fBctrl-Z\fP
+has the same effect with the \fBtype\fP command on the Win32 command line.
+
+The following is a list of \fIkey=value\fP combinations that may be
+found in a MIFF file:
+.TP
+.B "background-color=\fIcolor\fP"
+.B "border-color=\fIcolor\fP"
+.B "matte-color=\fIcolor\fP"
+these optional keys reflects the image background, border, and matte
+colors respectively. A color can be a name (e.g. white) or a
+hex value (e.g. #ccc).
+.TP
+.B "class=\fIDirectClass\fP"
+.B "class=\fBPseudoClass\fP"
+the type of binary image data stored in the MIFF file. If
+this key is not present, \fBDirectClass\fP image data is assumed.
+.TP
+.B "colors=\fIvalue\fP"
+the number of colors in a \fBDirectClass\fP image. For a
+\fBPseudoClass\fP image, this key specifies the size of the
+colormap. If this key is not present in the header, and the image
+is \fBPseudoClass\fP, a linear 256 color grayscale colormap is used
+with the image data. The maximum number of colormap entries is 65535.
+.B "colorspace=\fBCMYK\fP"
+the colorspace of the pixel data. The default is RGB.
+.TP
+.B "columns=\fIvalue\fP"
+the width of the image in pixels. This is a required key and
+has no default.
+.TP
+.B "compression=\fBBZip\fP"
+.B "compression=\fBFax\fP"
+.B "compression=\fBJPEG\fP"
+.B "compression=\fBLZW\fP"
+.B "compression=\fBRLE\fP"
+.B "compression=\fBZip\fP"
+the type of algorithm used to compress the image data. If this
+key is not present, the image data is assumed to be uncompressed.
+.TP
+.B "delay \fI<1/100ths of a second>\fP"
+the interframe delay in an image sequence. The maximum delay is 65535.
+.TP
+.B "depth=\fB8\fP"
+.B "depth=\fB16\fP"
+the depth of a single color value representing values from 0 to 255
+(depth 8) or 65535 (depth 16). If this key is absent, a depth of 8 is
+assumed.
+.TP
+.B "dispose \fIvalue\fP"
+GIF disposal method.
+
+Here are the valid methods:
+
+.nf
+ 0 No disposal specified.
+ 1 Do not dispose between frames.
+ 2 Overwrite frame with background color from header.
+ 3 Overwrite with previous frame.
+.fi
+.TP
+.B "gamma=\fIvalue\fP"
+the gamma of the image. If it is not specified, a gamma of 1.0
+(linear brightness response) is assumed,
+.TP
+.B "id=\fBImageMagick\fP"
+identifies the file as a MIFF-format image file. This key
+is required and has no default. Although this key can appear anywhere
+in the header, it should start as the first key of the header in column
+1. This will allow programs like \fBfile\fP(1) to easily identify the file
+as MIFF.
+.TP
+.B "iterations \fIvalue\fP"
+the number of times an image sequence loops before stopping.
+.TP
+.B "label=\fI{value}\fP"
+defines a short title or caption for the image. If
+any whitespace appears in the label, it must be enclosed within braces.
+.TP
+.B "matte=\fBTrue\fP"
+.B "matte=\fBFalse\fP"
+specifies whether a \fBDirectClass\fP image has matte data. Matte data
+is generally useful for image compositing. This key has no meaning
+for pseudo-color images.
+.TP
+.B "montage=\fI<width>x<height>{\+-}<x offset>{\+-}<y offset>\fP
+size and location of the individual tiles of a composite image. See
+\fBX(1)\fP for details about the geometry specification.
+
+Use this key when the image is a composite of a number of different
+tiles. A tile consists of an image and optionally a border and a
+label. \fI<width>\fP is the size in pixels of each individual tile in
+the horizontal direction and \fI<height>\fP is the size in the vertical
+direction. Each tile must have an equal number of pixels in width and
+equal in height. However, the width can differ from the height. \fI<x
+offset>\fP is the offset in number of pixels from the vertical edge of
+the composite image where the first tile of a row begins and \fI<y
+offset>\fP is the offset from the horizontal edge where the first tile
+of a column begins.
+
+If this key is specified, a directory of tile names must follow the
+image header. The format of the directory is explained below.
+.TP
+.B "page=\fIvalue\fP"
+preferred size and location of an image canvas.
+.TP
+.B "profile-icc=\fIvalue\fP"
+the number of bytes in the International Color Consortium color profile.
+The profile is defined by the ICC profile specification located at
+ftp://sgigate.sgi.com/pub/icc/icc34.ps.
+.TP
+.B "colorspace=\fBRGB\fP"
+.TP
+.B "red-primary=\fIx,y\fP"
+.B "green-primary=\fIx,y\fP"
+.B "blue-primary=\fIx,y\fP"
+.B "white-point=\fIx,y\fP"
+this optional key reflects the chromaticity primaries and white point.
+.TP
+.B "rendering-intent=\fBsaturation\fP"
+.B "rendering-intent=\fBperceptual\fP"
+.B "rendering-intent=\fBabsolute\fP"
+.B "rendering-intent=\fBrelative\fP"
+Rendering intent is the CSS-1 property that has been defined by the
+International Color Consortium (http://www.color.org).
+.TP
+.B "resolution=\fI<x-resolution>x<y-resolution>\fP"
+vertical and horizontal resolution of the image. See \fBunits\fP
+for the specific resolution units (e.g. pixels per inch).
+.TP
+.B "rows=\fIvalue\fP"
+the height of the image in pixels. This is a required key
+and has no default.
+.TP
+.B "scene=\fIvalue\fP"
+the sequence number for this MIFF image file. This optional
+key is used when a MIFF image file is one in a sequence of files
+used in an animation.
+.TP
+.B "signature=\fIvalue\fP"
+this optional key contains a string that uniquely identifies
+the image pixel contents. NIST's SHA-256 message digest algorithm is
+recommended.
+.TP
+.B "units=\fBpixels-per-inch\fP"
+.B "units=\fBpixels-per-centimeter\fP"
+image resolution units.
+
+Other key value pairs are permitted. If a value contains whitespace it
+must be enclosed with braces as illustrated here:
+
+ id=ImageMagick
+ class=PseudoClass colors=256
+ compression=RunlengthEncoded packets=27601
+ columns=1280 rows=1024
+ signature=d79e1c308aa5bbcdeea8ed63df412da9
+ copyright={Copyright (c) 2001 ImageMagick Studio}
+ <FF>
+ :
+
+.PP
+Note that \fIkey=value\fP combinations may be separated by newlines or
+spaces and may occur in any order within the header. Comments (within
+braces) may appear anywhere before the colon.
+
+If you specify the \fBmontage\fP key in the header, follow
+the header with a directory of image tiles. This directory consists of
+a name for each tile of the composite image separated by a
+\fBnewline\fP character. The list is terminated with a NULL character.
+
+If you specify the \fBcolor-profile\fP key in the header, follow
+the header (or montage directory if the \fBmontage\fP key is in the
+header) with the binary color profile.
+
+Next comes the binary image data itself. How the image
+data is formatted depends upon the class of the image as specified (or
+not specified) by the value of the \fBclass\fP key in the header.
+
+DirectClass images (class=DirectClass) are continuous-tone, images
+stored as RGB (red, green, blue), RGBA (red, green, blue, alpha), or
+CMYK (cyan, yellow, magenta, black) intensity values as defined by the
+colorspace key. Each intensity value is one byte in length for
+images of depth 8 (0..255), whereas, images of depth 16 (0..65535)
+require two bytes in most significant byte first order.
+
+PseudoClass images (class=PseudoClass) are colormapped RGB images. The
+colormap is stored as a series of red, green, and blue pixel values,
+each value being a byte in size. If the image depth is 16, each
+colormap entry consumes two bytes with the most significant byte being
+first. The number of colormap entries is defined by the colors key.
+The colormap data occurs immediately following the header (or image
+directory if the montage key is in the header). PseudoClass image
+data is an array of index values into the color map. If there are 256
+or fewer colors in the image, each byte of image data contains an index
+value. If the image contains more than 256 colors or the image depth is
+16, the index value is stored as two contiguous bytes with the most
+significant byte being first. If matte is true, each
+colormap index is followed by a 1 or 2-byte alpha value.
+
+The image data in a MIFF file may be uncompressed, runlength encoded,
+Zip compressed, or BZip compressed. The compression key in the
+header defines how the image data is compressed. Uncompressed pixels
+are just stored one scanline at a time in row order. Runlength encoded
+compression counts runs of identical adjacent pixels and stores the
+pixels followed by a length byte (the number of identical pixels minus
+1). Zip and BZip compression compresses each row of an image and
+preceeds the compressed row with the length of compressed pixel bytes
+as a word in most significant byte first order.
+
+MIFF files may contain more than one image. Simply concatenate each
+individual image (composed of a header and image data) into one file.
+.SH SEE ALSO
+.B
+display(1), animate(1), import(1), montage(1), mogrify(1), convert(1), more(1), compress(1)
+.SH COPYRIGHT
+Copyright (C) 2000 ImageMagick Studio, a non-profit organization dedicated
+to making software imaging solutions freely available.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files ("ImageMagick"),
+to deal in ImageMagick without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of ImageMagick, and to permit persons to whom the
+ImageMagick is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of ImageMagick.
+
+The software is provided "as is", without warranty of any kind, express or
+implied, including but not limited to the warranties of merchantability,
+fitness for a particular purpose and noninfringement. In no event shall
+ImageMagick Studio be liable for any claim, damages or other liability,
+whether in an action of contract, tort or otherwise, arising from, out of
+or in connection with ImageMagick or the use or other dealings in
+ImageMagick.
+
+Except as contained in this notice, the name of the ImageMagick Studio
+shall not be used in advertising or otherwise to promote the sale, use or
+other dealings in ImageMagick without prior written authorization from the
+ImageMagick Studio.
+.SH AUTHORS
+John Cristy, ImageMagick Studio
diff --git a/utilities/quantize.5 b/utilities/quantize.5
new file mode 100644
index 0000000..0717cad
--- /dev/null
+++ b/utilities/quantize.5
@@ -0,0 +1,236 @@
+.ad l
+.nh
+.TH quantize 5 "$Date$" "ImageMagick"
+.SH NAME
+Quantize - ImageMagick's color reduction algorithm.
+.SH SYNOPSIS
+.B #include <magick.h>
+.SH DESCRIPTION
+This document describes how \fBImageMagick\fP performs color reduction on an
+image. To fully understand this document, you should have a knowledge
+of basic imaging techniques and the tree data structure and terminology.
+
+For purposes of color allocation, an image is a set of \fIn\fP pixels,
+where each pixel is a point in RGB space. RGB space is a 3-dimensional
+vector space, and each pixel, \fIp\d\s-3i\s0\u\fP, is defined by an
+ordered triple of red, green, and blue coordinates, (\fIr\d\s-3i\s0\u,
+g\d\s-3i\s0\u, b\d\s-3i\s0\u\fP).
+
+Each primary color component (red, green, or blue) represents an
+intensity which varies linearly from 0 to a maximum value,
+\fIc\d\s-3max\s0\u\fP, which corresponds to full saturation of that
+color. Color allocation is defined over a domain consisting of the
+cube in RGB space with opposite vertices at (0,0,0) and
+(\fIc\d\s-3max\s0\u,c\d\s-3max\s0\u,c\d\s-3max\s0\u\fP). \fBImageMagick\fP
+requires \fIc\d\s-3max\s0\u = 255\fP.
+
+The algorithm maps this domain onto a tree in which each node
+represents a cube within that domain. In the following discussion,
+these cubes are defined by the coordinate of two opposite vertices: The
+vertex nearest the origin in RGB space and the vertex farthest from the
+origin.
+
+The tree's root node represents the the entire domain, (0,0,0) through
+(\fIc\d\s-3max\s0\u,c\d\s-3max\s0\u,c\d\s-3max\s0\u\fP). Each lower level in
+the tree is generated by subdividing one node's cube into eight smaller
+cubes of equal size. This corresponds to bisecting the parent cube
+with planes passing through the midpoints of each edge.
+
+The basic algorithm operates in three phases: \fBClassification,
+Reduction\fP, and \fBAssignment\fP. \fBClassification\fP builds a
+color description tree for the image. \fBReduction\fP collapses the
+tree until the number it represents, at most, is the number of colors
+desired in the output image. \fBAssignment\fP defines the output
+image's color map and sets each pixel's color by reclassification in
+the reduced tree. Our goal is to minimize the numerical discrepancies
+between the original colors and quantized colors. To learn more about
+quantization error, see MEASURING COLOR REDUCTION ERROR later in this
+document.
+
+\fBClassification\fP begins by initializing a color description tree of
+sufficient depth to represent each possible input color in a leaf.
+However, it is impractical to generate a fully-formed color description
+tree in the classification phase for realistic values of
+\fIc\d\s-3max\s0\u\fP. If color components in the input image are
+quantized to \fIk\fP-bit precision, so that \fIc\d\s-3max\s0\u =
+2\u\s-3k\s0\d-1\fP, the tree would need \fIk\fP levels below the root
+node to allow representing each possible input color in a leaf. This
+becomes prohibitive because the tree's total number of nodes is
+
+.nf
+ \s+6\(*S\u\s-9 k\d\di=1\s0 8k\fP\s0\u
+.fi
+.PP
+A complete tree would require 19,173,961 nodes for \fIk = 8,
+c\d\s-3max\s0\u = 255\fP. Therefore, to avoid building a fully
+populated tree, \fBImageMagick\fP: (1) Initializes data structures for
+nodes only as they are needed; (2) Chooses a maximum depth for the tree
+as a function of the desired number of colors in the output image
+(currently \fIlog\d\s-34\s0\u(colormap size)\+2\fP). A tree of this
+depth generally allows the best representation of the source image with
+the fastest computational speed and the least amount of memory.
+However, the default depth is inappropriate for some images.
+Therefore, the caller can request a specific tree depth.
+
+For each pixel in the input image, classification scans downward from
+the root of the color description tree. At each level of the tree, it
+identifies the single node which represents a cube in RGB space
+containing the pixel's color. It updates the following data for each
+such node:
+.TP
+.B n\d\s-31\s0\u:
+Number of pixels whose color is contained in the RGB cube which this
+node represents;
+.TP
+.B n\d\s-32\s0\u:
+Number of pixels whose color is not represented in a node at lower
+depth in the tree; initially, \fIn\d\s-32\s0\u = 0\fP for all nodes
+except leaves of the tree.
+.TP
+.B S\d\s-3r\s0\u, S\d\s-3g\s0\u, S\d\s-3b\s0\u:
+Sums of the red, green, and blue component values for all pixels not
+classified at a lower depth. The combination of these sums and
+\fIn\d\s-32\s0\u\fP will ultimately characterize the mean color of a
+set of pixels represented by this node.
+.TP
+.B E:
+The distance squared in RGB space between each pixel contained within a
+node and the nodes' center. This represents the quantization error for
+a node.
+.PP
+\fBReduction\fP repeatedly prunes the tree until the number of nodes with
+\fIn\d\s-32\s0\u > 0\fP is less than or equal to the maximum number of colors
+allowed in the output image. On any given iteration over the tree, it
+selects those nodes whose \fIE\fP value is minimal for pruning and
+merges their color statistics upward. It uses a pruning threshold,
+\fIE\d\s-3p\s0\u\fP, to govern node selection as follows:
+
+ E\d\s-3p\s0\u = 0
+ while number of nodes with (n\d\s-32\s0\u > 0) > required maximum number of colors
+ prune all nodes such that E <= E\d\s-3p\s0\u
+ Set E\d\s-3p\s0\u to minimum E in remaining nodes
+
+This has the effect of minimizing any quantization error when
+merging two nodes together.
+
+When a node to be pruned has offspring, the pruning procedure invokes
+itself recursively in order to prune the tree from the leaves upward.
+The values of \fIn\d\s-32\s0\u S\d\s-3r\s0\u, S\d\s-3g\s0\u,\fP and
+\fIS\d\s-3b\s0\u\fP in a node being pruned are always added to the
+corresponding data in that node's parent. This retains the pruned
+node's color characteristics for later averaging.
+
+For each node, \fIn\d\s-32\s0\u\fP pixels exist for which that node
+represents the smallest volume in RGB space containing those pixel's
+colors. When \fIn\d\s-32\s0\u > 0\fP the node will uniquely define a
+color in the output image. At the beginning of reduction,
+\fIn\d\s-32\s0\u = 0\fP for all nodes except the leaves of the tree
+which represent colors present in the input image.
+
+The other pixel count, \fIn\d\s-31\s0\u\fP, indicates the total
+number of colors within the cubic volume which the node represents.
+This includes \fIn\d\s-31\s0\u - n\d\s-32\s0\u\fP pixels whose colors
+should be defined by nodes at a lower level in the tree.
+
+\fBAssignment\fP generates the output image from the pruned tree. The
+output image consists of two parts: (1) A color map, which is an
+array of color descriptions (RGB triples) for each color present in the
+output image; (2) A pixel array, which represents each pixel as an
+index into the color map array.
+
+First, the assignment phase makes one pass over the pruned color
+description tree to establish the image's color map. For each node
+with \fIn\d\s-32\s0\u > 0\fP, it divides \fIS\d\s-3r\s0\u,
+S\d\s-3g\s0\u\fP, and \fPS\d\s-3b\s0\u\fP by \fIn\d\s-32\s0\u\fP. This
+produces the mean color of all pixels that classify no lower than this
+node. Each of these colors becomes an entry in the color map.
+
+Finally, the assignment phase reclassifies each pixel in the pruned
+tree to identify the deepest node containing the pixel's color. The
+pixel's value in the pixel array becomes the index of this node's mean
+color in the color map.
+
+Empirical evidence suggests that distances in color spaces such as
+YUV, or YIQ correspond to perceptual color differences more closely
+than do distances in RGB space. These color spaces may give better
+results when color reducing an image. Here the algorithm is as described
+except each pixel is a point in the alternate color space. For convenience,
+the color components are normalized to the range 0 to a maximum value,
+\fIc\d\s-3max\s0\u\fP. The color reduction can then proceed as described.
+.SH "MEASURING COLOR REDUCTION ERROR"
+
+Depending on the image, the color reduction error may be obvious or
+invisible. Images with high spatial frequencies (such as hair or
+grass) will show error much less than pictures with large smoothly
+shaded areas (such as faces). This is because the high-frequency
+contour edges introduced by the color reduction process are masked by
+the high frequencies in the image.
+
+To measure the difference between the original and color reduced images
+(the total color reduction error), \fBImageMagick\fP sums over all pixels
+in an image the distance squared in RGB space between each original
+pixel value and its color reduced value. \fBImageMagick\fP prints several error
+measurements including the mean error per pixel, the normalized mean error,
+and the normalized maximum error.
+
+The normalized error measurement can be used to compare images. In
+general, the closer the mean error is to zero the more the quantized
+image resembles the source image. Ideally, the error should be
+perceptually-based, since the human eye is the final judge of
+quantization quality.
+
+These errors are measured and printed when \fB-verbose\fP and \fB-colors\fI
+are specified on the command line:
+.TP
+.B mean error per pixel:
+is the mean error for any single pixel in the image.
+.TP
+.B normalized mean square error:
+is the normalized mean square quantization error for any single pixel in the
+image.
+
+This distance measure is normalized to a range between 0 and 1. It is
+independent of the range of red, green, and blue values in the image.
+.TP
+.B normalized maximum square error:
+is the largest normalized square quantization error for any single
+pixel in the image.
+
+This distance measure is normalized to a range between 0 and 1. It is
+independent of the range of red, green, and blue values in the image.
+.SH SEE ALSO
+.B
+display(1), animate(1), mogrify(1), import(1), miff(5)
+.SH COPYRIGHT
+Copyright (C) 2002 ImageMagick Studio, a non-profit organization dedicated
+to making software imaging solutions freely available.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files ("ImageMagick"),
+to deal in ImageMagick without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of ImageMagick, and to permit persons to whom the
+ImageMagick is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of ImageMagick.
+
+The software is provided "as is", without warranty of any kind, express or
+implied, including but not limited to the warranties of merchantability,
+fitness for a particular purpose and noninfringement. In no event shall
+ImageMagick Studio be liable for any claim, damages or other liability,
+whether in an action of contract, tort or otherwise, arising from, out of
+or in connection with ImageMagick or the use or other dealings in
+ImageMagick.
+
+Except as contained in this notice, the name of the ImageMagick Studio
+shall not be used in advertising or otherwise to promote the sale, use or
+other dealings in ImageMagick without prior written authorization from the
+ImageMagick Studio.
+.SH ACKNOWLEDGEMENTS
+Paul Raveling, USC Information Sciences Institute, for the original
+idea of using space subdivision for the color reduction algorithm.
+With Paul's permission, this document is an adaptation from a document he
+wrote.
+.SH AUTHORS
+John Cristy, ImageMagick Studio
diff --git a/utilities/tests/BetaRGB.icc b/utilities/tests/BetaRGB.icc
new file mode 100644
index 0000000..c13aa34
--- /dev/null
+++ b/utilities/tests/BetaRGB.icc
Binary files differ
diff --git a/utilities/tests/common.sh b/utilities/tests/common.sh
new file mode 100644
index 0000000..f128d40
--- /dev/null
+++ b/utilities/tests/common.sh
@@ -0,0 +1,16 @@
+# -*- shell-script -*-
+# Common code fragment for utilities tests
+#
+subdir=utilities/tests
+. ${top_srcdir}/scripts/tap-functions.shi
+mkdir -p ${subdir}
+cd ${subdir} || exit 1
+BETARGB_PROFILE="${top_srcdir}/utilities/tests/BetaRGB.icc"
+GENERIC_TTF="${top_srcdir}/PerlMagick/demo/Generic.ttf"
+MODEL_MIFF="${top_srcdir}/Magick++/demo/model.miff"
+SMILE_MIFF="${top_srcdir}/Magick++/demo/smile.miff"
+SUNRISE_JPEG="${top_srcdir}/utilities/tests/sunrise.jpg"
+SUNRISE_MIFF="${top_srcdir}/utilities/tests/sunrise.miff"
+#CONVERT_FLAGS='-monitor'
+#COMPOSITE_FLAGS='-monitor'
+#MONTAGE_FLAGS='-monitor'
diff --git a/utilities/tests/effects.tap b/utilities/tests/effects.tap
new file mode 100755
index 0000000..be8a159
--- /dev/null
+++ b/utilities/tests/effects.tap
@@ -0,0 +1,270 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test image processing
+# This script should be executed prior to Montage
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 59
+
+OUTFILE=TileAddNoise_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'AddNoise' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} +noise Laplacian -label AddNoise ${OUTFILE}
+
+OUTFILE=TileAffine_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Affine' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -affine 1,0,0.785,1,0,0 -transform -label Affine ${OUTFILE}
+
+OUTFILE=TileAnnotate_out.miff
+ANNOTATE_CMD_FILE=annotate_cmds_out.txt
+echo 'gravity North text 0,20 "Magick"' > ${ANNOTATE_CMD_FILE}
+rm -f ${OUTFILE}
+test_command_fn 'Annotate' -F TTF ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -fill gold -pointsize 14 \
+ -font ${GENERIC_TTF} \
+ -draw @${ANNOTATE_CMD_FILE} \
+ -label Annotate ${OUTFILE}
+
+OUTFILE=TileThresholdBlack_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Black-Threshold' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -black-threshold "20%" \
+ -label 'Black-Threshold' ${OUTFILE}
+
+OUTFILE=TileBlur_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Blur' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -blur 0x1 -label Blur ${OUTFILE}
+
+OUTFILE=TileBorder_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Border' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -bordercolor gold -border 6x6 -label Border ${OUTFILE}
+
+OUTFILE=TileChannel_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Channel' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -colorspace cmyk -channel yellow -label Channel ${OUTFILE}
+
+OUTFILE=TileCharcoal_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Charcoal' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -charcoal 0x1 -label Charcoal ${OUTFILE}
+
+OUTFILE=TileComposite_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Composite' ${GM} composite ${COMPOSITE_FLAGS} ${SMILE_MIFF} -geometry +35+65 ${MODEL_MIFF} -label Composite ${OUTFILE}
+
+OUTFILE=TileContrast_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Contrast' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -contrast -label Contrast ${OUTFILE}
+
+OUTFILE=TileConvolve_out.miff
+rm -f ${OUTFILE}
+# 1,1,1,
+# 1,4,1,
+# 1,1,1
+test_command_fn 'Convolve' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -convolve 1,1,1,1,4,1,1,1,1 -label Convolve ${OUTFILE}
+
+OUTFILE=TileCrop_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Crop' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -crop '80x80+25+50' -label Crop ${OUTFILE}
+
+OUTFILE=TileDespeckle_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Despeckle' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -despeckle -label Despeckle ${OUTFILE}
+
+OUTFILE=TileDraw_out.miff
+DRAWFILE=draw_circle_out.txt
+rm -f ${OUTFILE}
+echo 'circle 60,90 60,120' > ${DRAWFILE}
+test_command_fn 'Draw' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -fill none -stroke gold \
+ -draw @${DRAWFILE} -label Draw ${OUTFILE}
+rm -f ${DRAWFILE}
+
+OUTFILE=TileEdge_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Edge' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -edge 0x1 -label Edge ${OUTFILE}
+
+OUTFILE=TileEmboss_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Emboss' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -emboss 0x1 -label Emboss ${OUTFILE}
+
+OUTFILE=TileEqualize_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Equalize' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -equalize -label Equalize ${OUTFILE}
+
+OUTFILE=TileExplode_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Explode' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -implode -1 -label Explode ${OUTFILE}
+
+OUTFILE=TileFlip_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Flip' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -flip -label Flip ${OUTFILE}
+
+OUTFILE=TileFlop_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Flop' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -flop -label Flop ${OUTFILE}
+
+OUTFILE=TileFrame_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Frame' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -frame 15x15+3+3 -label Frame ${OUTFILE}
+
+OUTFILE=TileGamma_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Gamma' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -gamma 1.6 -label Gamma ${OUTFILE}
+
+OUTFILE=TileGaussianBlur_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'GaussianBlur' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -gaussian 0x1.5 -label GaussianBlur ${OUTFILE}
+
+OUTFILE=TileGradient_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Gradient' ${GM} convert ${CONVERT_FLAGS} -size 130x194 gradient:'#20a0ff-#ffff00' -label Gradient ${OUTFILE}
+
+OUTFILE=TileGrayscale_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Grayscale' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -colorspace gray -label Grayscale ${OUTFILE}
+
+OUTFILE=TileImplode_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Implode' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -implode 0.5 -label Implode ${OUTFILE}
+
+OUTFILE=TileLevel_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Level' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -level 10%,1.2,90% -label Level ${OUTFILE}
+
+rm -f mask_out.miff TileMask_out.miff
+${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -threshold "30%" mask_out.miff
+test_command_fn 'Mask' ${GM} convert ${CONVERT_FLAGS} -mask mask_out.miff ${MODEL_MIFF} -negate -label Mask TileMask_out.miff
+
+OUTFILE=TileMedian_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'MedianFilter' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -median 3 -label MedianFilter ${OUTFILE}
+
+OUTFILE=TileModulate_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Modulate' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -modulate 110/110/110 -label Modulate ${OUTFILE}
+
+OUTFILE=TileMonochrome_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Monochrome' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -colorspace gray -colors 2 \
+ +dither -label Monochrome ${OUTFILE}
+
+OUTFILE=TileNegate_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Negate' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -negate -label Negate ${OUTFILE}
+
+OUTFILE=TileNormalize_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Normalize' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -normalize -label Normalize ${OUTFILE}
+
+OUTFILE=TileOilPaint_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Oilpaint' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -paint 0x1 -label Oilpaint ${OUTFILE}
+
+OUTFILE=TileOrderedDither2_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Ordered2x2' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -equalize -ordered-dither intensity 2x2 -label Ordered2x2 ${OUTFILE}
+
+OUTFILE=TileOrderedDither3_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Ordered3x3' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -equalize -ordered-dither intensity 3x3 -label Ordered3x3 ${OUTFILE}
+
+OUTFILE=TileOrderedDither4_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Ordered4x4' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -equalize -ordered-dither intensity 4x4 -label Ordered4x4 ${OUTFILE}
+
+OUTFILE=TilePlasma_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Plasma' ${GM} convert ${CONVERT_FLAGS} -size 130x194 plasma:fractal -label Plasma ${OUTFILE}
+
+OUTFILE=TileQuantize_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Quantize' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -colors 16 -label Quantize ${OUTFILE}
+
+OUTFILE=TileRaise_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Raise' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -raise 10x10 -label Raise ${OUTFILE}
+
+OUTFILE=TileRandomThreshold_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Random 10%' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -equalize -random-threshold intensity '10%' -label 'Random10%%' ${OUTFILE}
+
+OUTFILE=TileRecolor_out.miff
+MATRIXFILE=recolor_matrix_out.txt
+echo '0.9 0 0, 0 0.9 0, 0 0 1.2' > ${MATRIXFILE}
+rm -f ${OUTFILE}
+test_command_fn 'Recolor' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -recolor @${MATRIXFILE} -label Recolor ${OUTFILE}
+rm -f ${MATRIXFILE}
+
+OUTFILE=TileReduceNoise_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'ReduceNoise' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -noise 0x1 -label ReduceNoise ${OUTFILE}
+
+OUTFILE=TileResize_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Resize' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -resize 50% -label Resize ${OUTFILE}
+
+OUTFILE=TileRoll_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Roll' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -roll +20+10 -label Roll ${OUTFILE}
+
+OUTFILE=TileRotate_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Rotate 45' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -fill black -rotate 45 \
+ -transparent black -label Rotate ${OUTFILE}
+
+OUTFILE=TileScale_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Scale' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -scale 60% -label Scale ${OUTFILE}
+
+OUTFILE=TileSegment_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Segment' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -segment 0.5x0.25 -label Segment ${OUTFILE}
+
+OUTFILE=TileShade_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Shade' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -shade 30x30 -label Shade ${OUTFILE}
+
+OUTFILE=TileSharpen_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Sharpen' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -sharpen 0x1 -label Sharpen ${OUTFILE}
+
+OUTFILE=TileShave_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Shave' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -shave 10x10 -label Shave ${OUTFILE}
+
+OUTFILE=TileShear_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Shear' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -fill black -shear 45x45 \
+ -transparent black -label Shear ${OUTFILE}
+
+OUTFILE=TileSolar_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Solarize' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -solarize 50% -label Solarize ${OUTFILE}
+
+OUTFILE=TileSpread_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Spread' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -spread 3 -label Spread ${OUTFILE}
+
+OUTFILE=TileSwirl_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Swirl' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -background '#000000FF' \
+ -swirl 90 -label Swirl ${OUTFILE}
+
+OUTFILE=TileThreshold_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Threshold' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -threshold "35%" \
+ -label Threshold ${OUTFILE}
+
+OUTFILE=TileUnsharpMask_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'UnsharpMask' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -unsharp 0x1+10+10 -label UnsharpMask ${OUTFILE}
+
+OUTFILE=TileWave_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'Wave' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -background '#000000FF' \
+ -wave 25x150 -label Wave ${OUTFILE}
+
+OUTFILE=TileThresholdWhite_out.miff
+rm -f ${OUTFILE}
+test_command_fn 'White-Threshold' ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -white-threshold "80%" \
+ -label 'White-Threshold' ${OUTFILE}
+:
diff --git a/utilities/tests/hald-clut.tap b/utilities/tests/hald-clut.tap
new file mode 100755
index 0000000..ee87722
--- /dev/null
+++ b/utilities/tests/hald-clut.tap
@@ -0,0 +1,33 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test hald CLUT operations
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 12
+
+OUTFILE=HaldClutIdentity_out.miff
+levels='2 7 8 10 12'
+for level in $levels
+do
+ echo "Testing Hald CLUT identity level ${level} ..."
+ identity_image=identity:${level}
+ rm -f ${OUTFILE}
+ test_command_fn 'Hald CLUT identity' ${GM} convert ${CONVERT_FLAGS} ${identity_image} -hald-clut ${identity_image} -label Hald-Clut ${OUTFILE}
+ test_command_fn 'Hald CLUT verify' ${GM} compare -maximum-error 1.5e-11 -metric MAE ${identity_image} ${OUTFILE}
+ echo
+done
+
+XFORM='-negate'
+IDENTITY_CLUT='identity:8'
+CLUT_OUTPUT=HaldClutTransform_out.miff
+REFERENCE_OUTPUT=HaldClutTransformRef_out.miff
+XFORM_CLUT=HaldClutTransformCLUT_out.miff
+
+eval ${GM} convert ${IDENTITY_CLUT} ${XFORM} ${XFORM_CLUT}
+eval ${GM} convert ${MODEL_MIFF} ${XFORM} ${REFERENCE_OUTPUT}
+test_command_fn 'Hald CLUT emulate negate' ${GM} convert ${MODEL_MIFF} -hald-clut ${XFORM_CLUT} ${CLUT_OUTPUT}
+test_command_fn 'Hald CLUT verify' ${GM} compare -maximum-error 4.0e-12 -metric MAE ${REFERENCE_OUTPUT} ${CLUT_OUTPUT}
+:
diff --git a/utilities/tests/help.tap b/utilities/tests/help.tap
new file mode 100755
index 0000000..81c34da
--- /dev/null
+++ b/utilities/tests/help.tap
@@ -0,0 +1,29 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2013 GraphicsMagick Group
+# Test -list option
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 32
+
+nox_commands='batch benchmark compare composite conjure convert help identify mogrify montage time version'
+
+test_command_fn "gm help" ${GM} help
+
+test_command_fn "gm -version" ${GM} -version
+
+for command in ${nox_commands}
+do
+ test_command_fn "gm help ${command}" ${GM} help ${command}
+ test_command_fn "gm ${command} -help" ${GM} ${command} -help
+done
+
+x_commands='animate display import'
+for command in ${x_commands}
+do
+ test_command_fn "gm help ${command}" ${GM} help ${command}
+ test_command_fn "gm ${command} -help" -F X ${GM} ${command} -help
+done
+:
diff --git a/utilities/tests/icc-transform.tap b/utilities/tests/icc-transform.tap
new file mode 100755
index 0000000..934d381
--- /dev/null
+++ b/utilities/tests/icc-transform.tap
@@ -0,0 +1,21 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test ICC Transforms
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 3
+
+ORIGINAL_PROFILE=sunrise.icc
+IMAGE_OUTPUT=ICCTransform_out.miff
+
+rm -f ${ORIGINAL_PROFILE}
+rm -f ${IMAGE_OUTPUT}
+test_command_fn 'Extract ICC profile' ${GM} convert ${SUNRISE_MIFF} ${ORIGINAL_PROFILE}
+test_command_fn 'Apply ICC profile and then reverse it' -F LCMS ${GM} convert ${SUNRISE_MIFF} -profile ${BETARGB_PROFILE} -profile ${ORIGINAL_PROFILE} ${IMAGE_OUTPUT}
+test_command_fn 'Verify results' ${GM} compare -maximum-error 0.004 -metric MAE ${SUNRISE_MIFF} ${IMAGE_OUTPUT}
+rm -f ${ORIGINAL_PROFILE}
+rm -f ${IMAGE_OUTPUT}
+:
diff --git a/utilities/tests/identify.tap b/utilities/tests/identify.tap
new file mode 100755
index 0000000..f0cc821
--- /dev/null
+++ b/utilities/tests/identify.tap
@@ -0,0 +1,11 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test ICC Transforms
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 1
+
+test_command_fn 'identify -verbose' -F JPEG ${GM} identify -verbose "${SUNRISE_JPEG}"
diff --git a/utilities/tests/list.tap b/utilities/tests/list.tap
new file mode 100755
index 0000000..dcffcff
--- /dev/null
+++ b/utilities/tests/list.tap
@@ -0,0 +1,21 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test -list option
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 16
+
+list_opts='color delegate format magic modulemap resource type'
+
+for list_opt in ${list_opts}
+do
+ test_command_fn "gm convert -list ${list_opt}" ${GM} convert -list ${list_opt}
+ test_command_fn "gm mogrify -list ${list_opt}" ${GM} mogrify -list ${list_opt}
+done
+
+test_command_fn 'gm convert -list module' -F MODULES ${GM} convert -list module
+test_command_fn 'gm mogrify -list module' -F MODULES ${GM} mogrify -list module
+:
diff --git a/utilities/tests/montage.tap b/utilities/tests/montage.tap
new file mode 100755
index 0000000..90ec5b4
--- /dev/null
+++ b/utilities/tests/montage.tap
@@ -0,0 +1,18 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test montage
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 3
+
+test_command_fn 'Montage' -F TTF ${GM} montage ${MONTAGE_FLAGS} -geometry '130x194+10+5>' -gravity 'Center' \
+ -bordercolor 'green' -borderwidth 1x1 -tile '7x4' -compose 'over' \
+ -background '#ffffff' -font ${GENERIC_TTF} -pointsize 18 -fill '#600' \
+ -stroke 'none' null: null: null: null: null: null: null: 'Tile*_out.miff' \
+ -compress rle montage_out.miff
+test_command_fn 'Prepare logo' ${GM} convert ${CONVERT_FLAGS} logo: -resize 40% logo_out.miff
+test_command_fn 'Composite logo' ${GM} composite ${COMPOSITE_FLAGS} 'tmp:logo_out.miff' -gravity north 'tmp:montage_out.miff' -depth 8 demo.miff
+:
diff --git a/utilities/tests/msl_composite.tap b/utilities/tests/msl_composite.tap
new file mode 100755
index 0000000..950a18f
--- /dev/null
+++ b/utilities/tests/msl_composite.tap
@@ -0,0 +1,155 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test MSL Composite
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+#Author: Max Hohenegger
+#Last change: 2008-10-01
+#Module: conjure, MSL
+#Description: Test whether compositing images over a background image using
+# gravity delivers the same result using conjure (MSL) and convert
+
+# Number of tests we plan to execute
+test_plan_fn 2
+
+COMPOSITE_CMD="${GM} composite"
+CONJURE_CMD="${GM} conjure -debug exception"
+CONVERT_CMD="${GM} convert"
+COMPARE_CMD="${GM} compare"
+DISPLAY_CMD="${GM} display"
+
+FORMAT="_out.pnm"
+
+BLANK="comp_blank$FORMAT"
+CENTER="comp_Center$FORMAT"
+NORTH="comp_North$FORMAT"
+NORTHEAST="comp_NorthEast$FORMAT"
+EAST="comp_East$FORMAT"
+SOUTHEAST="comp_SouthEast$FORMAT"
+SOUTH="comp_South$FORMAT"
+SOUTHWEST="comp_SouthWest$FORMAT"
+WEST="comp_West$FORMAT"
+NORTHWEST="comp_NorthWest$FORMAT"
+
+RESULT="comp_result_out$FORMAT"
+CONJURE_RESULT="comp_conjure_result_out$FORMAT"
+COMPARED="comp_compared$FORMAT"
+
+draw_text ()
+{
+ TEXT=$1
+ TARGET=$2
+
+ DRAWCMDFILE=msl_composite_draw_out.txt
+# TEMPFILE=draw_text_tmp.svg
+# cat <<EOF >$TEMPFILE
+#<?xml version="1.0" encoding="utf-8" ?>
+#<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+# "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+#<svg width="120" height="100" xmlns="http://www.w3.org/2000/svg">
+# <style type="text/css"><![CDATA[ text {font-size:20px; text-anchor:middle;} ]]></style>
+# <text x="50" y="50">$TEXT</text>
+#</svg>
+#EOF
+
+# $CONVERT_CMD $TEMPFILE $TARGET || exit 1
+
+ echo "font-size 20 font '${GENERIC_TTF}' gravity center text 0,0 '$TEXT'" > ${DRAWCMDFILE}
+ $CONVERT_CMD -size 100x100 xc:white -draw @${DRAWCMDFILE} $TARGET
+ rm -f ${DRAWCMDFILE}
+# rm -f $TEMPFILE
+}
+
+draw_blank ()
+{
+ TARGET=$1
+
+# TEMPFILE=draw_blank_tmp.svg
+# cat <<EOF >$TEMPFILE
+#<?xml version="1.0" encoding="utf-8" ?>
+#<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+# "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+#<svg width="500" height="500"
+# xmlns="http://www.w3.org/2000/svg">
+#</svg>
+#EOF
+
+# $CONVERT_CMD $TEMPFILE $TARGET || exit 2
+ $CONVERT_CMD -size 500x500 xc:white $TARGET
+# rm -f $TEMPFILE
+}
+
+########################## PREPARE TEST OBJECTS ###########################
+draw_blank $BLANK
+draw_text "Center" $CENTER
+draw_text "North" $NORTH
+draw_text "NorthEast" $NORTHEAST
+draw_text "East" $EAST
+draw_text "SouthEast" $SOUTHEAST
+draw_text "South" $SOUTH
+draw_text "SouthWest" $SOUTHWEST
+draw_text "West" $WEST
+draw_text "NorthWest" $NORTHWEST
+
+########################## CREATE TEST BASE ###########################
+cp $BLANK $RESULT
+$COMPOSITE_CMD $CENTER $RESULT -gravity Center $RESULT || exit 3
+$COMPOSITE_CMD $NORTH $RESULT -gravity North $RESULT || exit 3
+$COMPOSITE_CMD $NORTHEAST $RESULT -gravity NorthEast $RESULT || exit 3
+$COMPOSITE_CMD $EAST $RESULT -gravity East $RESULT || exit 3
+$COMPOSITE_CMD $SOUTHEAST $RESULT -gravity SouthEast $RESULT || exit 3
+$COMPOSITE_CMD $SOUTH $RESULT -gravity South $RESULT || exit 3
+$COMPOSITE_CMD $SOUTHWEST $RESULT -gravity SouthWest $RESULT || exit 3
+$COMPOSITE_CMD $WEST $RESULT -gravity West $RESULT || exit 3
+$COMPOSITE_CMD $NORTHWEST $RESULT -gravity NorthWest $RESULT || exit 3
+
+########################## CREATE TEST OBJECT ###########################
+TEMPFILE=composite_tmp.msl
+cat <<EOF >$TEMPFILE
+<?xml version="1.0" encoding="utf-8" ?>
+<group>
+ <image id="1"><read filename="$CENTER"/></image>
+ <image id="2"><read filename="$NORTH"/></image>
+ <image id="3"><read filename="$NORTHEAST"/></image>
+ <image id="4"><read filename="$EAST"/></image>
+ <image id="5"><read filename="$SOUTHEAST"/></image>
+ <image id="6"><read filename="$SOUTH"/></image>
+ <image id="7"><read filename="$SOUTHWEST"/></image>
+ <image id="8"><read filename="$WEST"/></image>
+ <image id="9"><read filename="$NORTHWEST"/></image>
+ <image>
+ <read filename="$BLANK"/>
+ <composite image="1" gravity="Center"/>
+ <composite image="2" gravity="North"/>
+ <composite image="3" gravity="NorthEast"/>
+ <composite image="4" gravity="East"/>
+ <composite image="5" gravity="SouthEast"/>
+ <composite image="6" gravity="South"/>
+ <composite image="7" gravity="SouthWest"/>
+ <composite image="8" gravity="West"/>
+ <composite image="9" gravity="NorthWest"/>
+ </image>
+ <write filename="$CONJURE_RESULT"/>
+</group>
+EOF
+test_command_fn 'Conjure' -F 'XML' $CONJURE_CMD $TEMPFILE
+
+################### COMPARE TEST OBJECT TO TESTBASE #########################
+
+#gm display $RESULT
+#gm display $CONJURE_RESULT
+
+cmp $RESULT $CONJURE_RESULT
+status=$?
+test_command_fn 'Verify Result' test $status
+if test $status -eq 0
+then
+ rm -f $TEMPFILE $BLANK $CENTER $NORTH $NORTHEAST $EAST $SOUTHEAST $SOUTH \
+ $SOUTHWEST $WEST $NORTHWEST $RESULT $CONJURE_RESULT
+fi
+#diff --report-identical-files $RESULT $CONJURE_RESULT
+#$COMPARE_CMD $RESULT $CONJURE_RESULT $COMPARED || exit 5
+#$DISPLAY_CMD $COMPARED || exit 6
+:
diff --git a/utilities/tests/pipe.tap b/utilities/tests/pipe.tap
new file mode 100755
index 0000000..46a4365
--- /dev/null
+++ b/utilities/tests/pipe.tap
@@ -0,0 +1,37 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test I/O using pipes
+# Note that running a test command containing a pipe blows up
+# test_command_fn so we will only check final status.
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 8
+
+${GM} convert ${CONVERT_FLAGS} - - < ${SUNRISE_MIFF} | ${GM} identify -format '%m %wx%h %r %q-bit' -
+test_command_fn 'Convert piped to identify (implicit MIFF)' test $?
+
+${GM} convert ${CONVERT_FLAGS} MIFF:- - < ${SUNRISE_MIFF} | ${GM} identify -format '%m %wx%h %r %q-bit' -
+test_command_fn 'Convert piped to identify (explicit MIFF)' test $?
+
+${GM} convert ${CONVERT_FLAGS} MIFF:- PNM:- < ${SUNRISE_MIFF} | ${GM} identify -format '%m %wx%h %r %q-bit' -
+test_command_fn 'Convert piped to identify (explicit MIFF to explicit PNM)' test $?
+
+${GM} convert ${CONVERT_FLAGS} - PNM:- < ${SUNRISE_MIFF} | ${GM} identify -format '%m %wx%h %r %q-bit' -
+test_command_fn 'Convert piped to identify (explicit PNM)' test $?
+
+${GM} convert ${CONVERT_FLAGS} - 'null:' < ${SUNRISE_MIFF}
+test_command_fn 'Convert implicit MIFF stdin to null:' test $?
+
+${GM} convert ${CONVERT_FLAGS} MIFF:- 'null:' < ${SUNRISE_MIFF}
+test_command_fn 'Convert explicit MIFF stdin to null:' test $?
+
+${GM} convert ${CONVERT_FLAGS} ${SUNRISE_MIFF} - | ${GM} identify -format '%m %wx%h %r %q-bit' -
+test_command_fn 'Convert MIFF piped to identify -format' test $?
+
+${GM} convert ${CONVERT_FLAGS} ${SUNRISE_MIFF} PPM:- | ${GM} identify -format '%m %wx%h %r %q-bit' -
+test_command_fn 'Convert PNM piped to identify -format' test $?
+
+:
diff --git a/utilities/tests/preview.tap b/utilities/tests/preview.tap
new file mode 100755
index 0000000..f6f53f2
--- /dev/null
+++ b/utilities/tests/preview.tap
@@ -0,0 +1,22 @@
+#!/bin/sh
+# -*- shell-script -*-
+# Copyright (C) 2004-2012 GraphicsMagick Group
+# Test preview generation
+. ./common.shi
+. ${top_srcdir}/utilities/tests/common.sh
+
+# Number of tests we plan to execute
+test_plan_fn 28
+
+previews='AddNoise Blur Brightness CharcoalDrawing Despeckle Dull EdgeDetect
+ Gamma Grayscale Hue Implode OilPaint Quantize Raise ReduceNoise Roll
+ Rotate Saturation Segment Shade Sharpen Shear Solarize Spiff Spread
+ Swirl Threshold Wave'
+
+for preview in ${previews}
+do
+ OUTFILE="Preview${preview}_out.miff"
+ rm -f ${OUTFILE}
+ test_command_fn "${preview}" ${GM} convert ${CONVERT_FLAGS} ${MODEL_MIFF} -preview ${preview} "preview:${OUTFILE}"
+done
+:
diff --git a/utilities/tests/sunrise.jpg b/utilities/tests/sunrise.jpg
new file mode 100644
index 0000000..5c54d7b
--- /dev/null
+++ b/utilities/tests/sunrise.jpg
Binary files differ
diff --git a/utilities/tests/sunrise.miff b/utilities/tests/sunrise.miff
new file mode 100644
index 0000000..2b736e7
--- /dev/null
+++ b/utilities/tests/sunrise.miff
Binary files differ
diff --git a/version.sh b/version.sh
new file mode 100755
index 0000000..4ff58a6
--- /dev/null
+++ b/version.sh
@@ -0,0 +1,106 @@
+#
+# Package name and versioning information for GraphicsMagick
+#
+# This file is sourced by a Bourne shell (/bin/sh) script so it must
+# observe Bourne shell syntax.
+#
+
+#
+# Package base name
+#
+PACKAGE_NAME='GraphicsMagick'
+
+#
+# Package bugs/support mailing list
+#
+PACKAGE_BUGREPORT='graphicsmagick-bugs@lists.sourceforge.net'
+
+# Package base version. This is is the numeric version suffix applied to
+# PACKAGE_NAME (e.g. "1.2").
+PACKAGE_VERSION='1.3.26'
+
+#
+# Package name plus version string.
+#
+PACKAGE_STRING="$PACKAGE_NAME $PACKAGE_VERSION"
+
+#
+# Formal Package release date
+# Set to string "unreleased" if package is not a formal release.
+PACKAGE_RELEASE_DATE="2017-07-04"
+#PACKAGE_RELEASE_DATE="unreleased"
+
+#
+# Date of last ChangeLog update
+#
+PACKAGE_CHANGE_DATE=`awk '/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/ { print substr($1,1,4) substr($1,6,2) substr($1,9,2); exit; }' ${srcdir}/ChangeLog`
+
+#
+# Package version addendum. This is a suffix (if any) appended to the
+# package base version. Formal releases do not have a suffix applied.
+#
+if test "$PACKAGE_RELEASE_DATE" = "unreleased"
+then
+ PACKAGE_VERSION_ADDENDUM=".0${PACKAGE_CHANGE_DATE}"
+ PACKAGE_RELEASE_DATE="snapshot-${PACKAGE_CHANGE_DATE}"
+else
+ PACKAGE_VERSION_ADDENDUM=''
+fi
+
+#
+# Mercurial branch that this release is on.
+#
+HG_BRANCH_TAG=default
+
+#
+# Libtool library revision control info
+# See the libtool documentation under the heading "Libtool's versioning
+# system" in order to understand the meaning of these fields
+#
+# current
+# The most recent interface number that this library implements.
+# revision
+# The implementation number of the current interface.
+# age
+# The difference between the newest and oldest interfaces that
+# this library implements. In other words, the library implements
+# all the interface numbers in the range from number current -
+# age to current.
+#
+# Here are a set of rules to help you update your library version
+# information:
+#
+# 1. Start with version information of `0:0:0' for each libtool library.
+# 2. Update the version information only immediately before a public
+# release of your software. More frequent updates are unnecessary, and
+# only guarantee that the current interface number gets larger faster.
+# 3. If the library source code has changed at all since the last update,
+# then increment revision (`c:r:a' becomes `c:r+1:a').
+# 4. If any interfaces have been added, removed, or changed since the last
+# update, increment current, and set revision to 0.
+# 5. If any interfaces have been added since the last public release, then
+# increment age.
+# 6. If any interfaces have been removed since the last public release,
+# then set age to 0.
+
+#
+# Magick library versioning
+#
+MAGICK_LIBRARY_CURRENT=19
+
+MAGICK_LIBRARY_REVISION=0
+MAGICK_LIBRARY_AGE=16
+
+#
+# Magick++ library versioning
+#
+MAGICK_PLUS_PLUS_LIBRARY_CURRENT=14
+MAGICK_PLUS_PLUS_LIBRARY_REVISION=0
+MAGICK_PLUS_PLUS_LIBRARY_AGE=2
+
+#
+# Magick Wand library versioning
+#
+MAGICK_WAND_LIBRARY_CURRENT=10
+MAGICK_WAND_LIBRARY_REVISION=0
+MAGICK_WAND_LIBRARY_AGE=8
diff --git a/wand/GraphicsMagickWand-config.1 b/wand/GraphicsMagickWand-config.1
new file mode 100644
index 0000000..aded420
--- /dev/null
+++ b/wand/GraphicsMagickWand-config.1
@@ -0,0 +1,71 @@
+.ad l
+.nh
+.TH GraphicsMagick-Config 1 "15 June 2003" "GraphicsMagick"
+.SH NAME
+GraphicsMagickWand-config \- get information about the installed version of GraphicsMagick
+.SH SYNOPSIS
+.B GraphicsMagickWand-config
+.B [--cflags]
+.B [--cppflags]
+.B [--exec-prefix]
+.B [--ldflags]
+.B [--libs]
+.B [--prefix]
+.B [--version]
+.SH DESCRIPTION
+.B GraphicsMagickWand-config
+prints the compiler and linker flags required to compile and link programs
+that use the
+.B GraphicsMagick Wand
+Application Programmer Interface.
+.SH EXAMPLES
+To print the version of the installed distribution of
+.BR GraphicsMagick ,
+use:
+
+.nf
+ GraphicsMagickWand-config --version
+.fi
+
+To compile a program that calls the
+.B GraphicsMagick Wand
+Application Programmer Interface, use:
+
+.nf
+ cc `GraphicsMagickWand-config --cflags --cppflags --ldflags --libs` program.c
+.fi
+
+.SH OPTIONS
+.TP
+.B --cflags
+Print the compiler flags that were used to compile
+.BR libGraphicsMagick .
+.TP
+.B --cppflags
+Print the preprocessor flags that are needed to find the
+.B GraphicsMagick
+C include files and defines to ensure that the GraphicsMagick data structures match between
+your program and the installed libraries.
+.TP
+.B --exec-prefix
+Print the directory under which target specific binaries and executables are installed.
+.TP
+.B --ldflags
+Print the linker flags that are needed to link with the
+.B GraphicsMagickWand
+library.
+.TP
+.B --libs
+Print the linker flags that are needed to link a program with
+.BR libMagick .
+.TP
+.B --version
+Print the version of the
+.B GraphicsMagick
+distribution to standard output.
+.SH COPYRIGHT
+Copyright (C) 2003 GraphicsMagick Group
+
+Copyright (C) 2002 ImageMagick Studio
+.SH AUTHORS
+Bob Friesenhahn
diff --git a/wand/GraphicsMagickWand-config.in b/wand/GraphicsMagickWand-config.in
new file mode 100644
index 0000000..462fdf9
--- /dev/null
+++ b/wand/GraphicsMagickWand-config.in
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# Configure options script for re-calling GraphicsMagick compilation
+# options required to use the GraphicsMagick Wand library.
+#
+# Concept derived from gtk-config in the Gtk package except that Autoconf-style
+# configuration information is presented instead so that it may be used more
+# effectively in configure scripts.
+#
+usage='Usage: GraphicsMagickWand-config [--cflags] [--cppflags] [--exec-prefix] [--ldflags] [--libs] [--prefix] [--version]
+
+ For example, "example.c" may be compiled to produce "example" as follows:
+
+ "gcc -o example example.c `GraphicsMagickWand-config --cppflags --cflags --ldflags --libs`"'
+
+if test $# -eq 0; then
+ echo "${usage}" 1>&2
+ exit 1
+fi
+
+while test $# -gt 0; do
+ case $1 in
+ --prefix)
+ echo @PREFIX_DIR@
+ ;;
+ --exec-prefix)
+ echo @EXEC_PREFIX_DIR@
+ ;;
+ --version)
+ echo @PACKAGE_VERSION@
+ ;;
+ --cflags)
+ echo "`GraphicsMagick-config --cflags`"
+ ;;
+ --cppflags)
+ echo "`GraphicsMagick-config --cppflags`"
+ ;;
+ --ldflags)
+ echo "`GraphicsMagick-config --ldflags`"
+ ;;
+ --libs)
+ echo "-lGraphicsMagickWand `GraphicsMagick-config --libs`"
+ ;;
+ *)
+ echo "${usage}" 1>&2
+ exit 1
+ ;;
+ esac
+ shift
+done
+
diff --git a/wand/GraphicsMagickWand.pc.in b/wand/GraphicsMagickWand.pc.in
new file mode 100644
index 0000000..2bc9ddf
--- /dev/null
+++ b/wand/GraphicsMagickWand.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/GraphicsMagick
+
+
+Name: GraphicsMagickWand
+Version: @PACKAGE_VERSION@
+Description: GraphicsMagick Wand image processing library
+Requires: GraphicsMagick
+Libs: -lGraphicsMagickWand
+Cflags:
diff --git a/wand/Makefile.am b/wand/Makefile.am
new file mode 100644
index 0000000..55e4ae0
--- /dev/null
+++ b/wand/Makefile.am
@@ -0,0 +1,82 @@
+# Copyright (C) 2004 - 2014 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building Wand library
+#
+
+wandincdir = $(topincludedir)/wand
+
+WAND_CPPFLAGS = $(AM_CPPFLAGS)
+
+WAND_SOURCES = \
+ wand/drawing_wand.c \
+ wand/drawing_wand.h \
+ wand/magick_compat.c \
+ wand/magick_wand.c \
+ wand/magick_wand.h \
+ wand/pixel_wand.c \
+ wand/pixel_wand.h \
+ wand/wand_api.h \
+ wand/wand_private.h
+
+WAND_INCLUDE_HDRS = \
+ wand/drawing_wand.h \
+ wand/magick_wand.h \
+ wand/pixel_wand.h \
+ wand/wand_api.h \
+ wand/wand_symbols.h
+
+# Headers which are installed
+wandinc_HEADERS = \
+ $(WAND_INCLUDE_HDRS)
+
+WAND_BIN_SCRPTS = \
+ wand/GraphicsMagickWand-config
+
+WAND_PKGCONFIG = \
+ wand/GraphicsMagickWand.pc
+
+WAND_MANS = \
+ wand/GraphicsMagickWand-config.1
+
+LIBWAND=wand/libGraphicsMagickWand.la
+
+wand_libGraphicsMagickWand_la_SOURCES = $(WAND_SOURCES)
+wand_libGraphicsMagickWand_la_CPPFLAGS = $(WAND_CPPFLAGS)
+wand_libGraphicsMagickWand_la_LDFLAGS = -no-undefined -export-symbols-regex ".*" \
+ $(MAGICK_LT_RELEASE_OPTS) \
+ -version-info $(MAGICK_WAND_LIBRARY_CURRENT):$(MAGICK_WAND_LIBRARY_REVISION):$(MAGICK_WAND_LIBRARY_AGE)
+wand_libGraphicsMagickWand_la_LIBADD = $(LIBMAGICK) $(LIB_MATH)
+
+WAND_EXTRA_DIST = \
+ wand/GraphicsMagickWand-config.1 \
+ wand/input_256c.miff \
+ wand/input_bilevel.miff \
+ wand/input_gray.miff \
+ wand/input_truecolor.miff \
+ wand/sequence.miff \
+ wand/common.shi \
+ $(WAND_TESTS)
+
+wand_drawtest_LDADD = $(LIBWAND)
+wand_drawtest_CPPFLAGS = $(WAND_CPPFLAGS)
+wand_drawtest_LDFLAGS = $(LDFLAGS)
+wand_drawtest_SOURCES = wand/drawtest.c
+
+wand_wandtest_LDADD = $(LIBWAND)
+wand_wandtest_CPPFLAGS = $(WAND_CPPFLAGS)
+wand_wandtest_LDFLAGS = $(LDFLAGS)
+wand_wandtest_SOURCES = wand/wandtest.c
+
+WAND_CHECK_PGRMS = \
+ wand/drawtest \
+ wand/wandtest
+
+WAND_TESTS = \
+ wand/wandtests.tap
+
+WAND_CLEANFILES = \
+ wand/*_out.*
diff --git a/wand/common.shi b/wand/common.shi
new file mode 100644
index 0000000..35573b4
--- /dev/null
+++ b/wand/common.shi
@@ -0,0 +1,7 @@
+# Common code fragment for wand tests
+#
+subdir=wand
+SRCDIR=${top_srcdir}/${subdir}
+export SRCDIR
+. ${top_srcdir}/scripts/tap-functions.shi
+cd ${subdir} || exit 1
diff --git a/wand/drawing_wand.c b/wand/drawing_wand.c
new file mode 100644
index 0000000..55a1347
--- /dev/null
+++ b/wand/drawing_wand.c
@@ -0,0 +1,5557 @@
+/* Copyright (C) 2003-2015 GraphicsMagick Group */
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% DDDD RRRR AAA W W IIIII N N GGGG %
+% D D R R A A W W I NN N G %
+% D D RRRR AAAAA W W I N N N G GG %
+% D D R R A A W W W I N NN G G %
+% DDDD R R A A W W IIIII N N GGG %
+% %
+% W W AAA N N DDDD %
+% W W A A NN N D D %
+% W W W AAAAA N N N D D %
+% WW WW A A N NN D D %
+% W W A A N N DDDD %
+% %
+% %
+% ImageMagick Image Vector Drawing Methods %
+% %
+% Software Design %
+% Bob Friesenhahn %
+% March 2002 %
+% %
+% %
+% Copyright (C) 2003 ImageMagick Studio, a non-profit organization dedicated %
+% to making software imaging solutions freely available. %
+% %
+% Permission is hereby granted, free of charge, to any person obtaining a %
+% copy of this software and associated documentation files ("ImageMagick"), %
+% to deal in ImageMagick without restriction, including without limitation %
+% the rights to use, copy, modify, merge, publish, distribute, sublicense, %
+% and/or sell copies of ImageMagick, and to permit persons to whom the %
+% ImageMagick is furnished to do so, subject to the following conditions: %
+% %
+% The above copyright notice and this permission notice shall be included in %
+% all copies or substantial portions of ImageMagick. %
+% %
+% The software is provided "as is", without warranty of any kind, express or %
+% implied, including but not limited to the warranties of merchantability, %
+% fitness for a particular purpose and noninfringement. In no event shall %
+% ImageMagick Studio be liable for any claim, damages or other liability, %
+% whether in an action of contract, tort or otherwise, arising from, out of %
+% or in connection with ImageMagick or the use or other dealings in %
+% ImageMagick. %
+% %
+% Except as contained in this notice, the name of the ImageMagick Studio %
+% shall not be used in advertising or otherwise to promote the sale, use or %
+% other dealings in ImageMagick without prior written authorization from the %
+% ImageMagick Studio. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/enum_strings.h"
+#include "magick/error.h"
+#include "magick/gem.h"
+#include "magick/list.h"
+#include "magick/log.h"
+#include "magick/magick.h"
+#include "magick/monitor.h"
+#include "wand/magick_wand.h"
+#include "wand/wand_private.h"
+
+/*
+ Define declarations.
+*/
+#define CurrentContext (drawing_wand->graphic_context[drawing_wand->index])
+#define WandColorMatch(p,q) (((p)->red == (q)->red) && \
+ ((p)->green == (q)->green) && ((p)->blue == (q)->blue) && \
+ ((p)->opacity == (q)->opacity))
+
+/*
+ Typedef declarations.
+*/
+typedef enum
+{
+ PathDefaultOperation,
+ PathCloseOperation, /* Z|z (none) */
+ PathCurveToOperation, /* C|c (x1 y1 x2 y2 x y)+ */
+ PathCurveToQuadraticBezierOperation, /* Q|q (x1 y1 x y)+ */
+ PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */
+ PathCurveToSmoothOperation, /* S|s (x2 y2 x y)+ */
+ PathEllipticArcOperation, /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
+ PathLineToHorizontalOperation, /* H|h x+ */
+ PathLineToOperation, /* L|l (x y)+ */
+ PathLineToVerticalOperation, /* V|v y+ */
+ PathMoveToOperation /* M|m (x y)+ */
+} PathOperation;
+
+typedef enum
+{
+ DefaultPathMode,
+ AbsolutePathMode,
+ RelativePathMode
+} PathMode;
+
+struct _DrawingWand
+{
+ /* Support structures */
+ ExceptionInfo
+ exception;
+
+ Image
+ *image;
+
+ MagickBool
+ own_image; /* If true, then we own the image. */
+
+ /* MVG output string and housekeeping */
+ char
+ *mvg; /* MVG data */
+
+ size_t
+ mvg_alloc, /* total allocated memory */
+ mvg_length; /* total MVG length */
+
+ unsigned int
+ mvg_width; /* current line length */
+
+ /* Pattern support */
+ char
+ *pattern_id;
+
+ RectangleInfo
+ pattern_bounds;
+
+ size_t
+ pattern_offset;
+
+ /* Graphic drawing_wand */
+ int
+ index; /* array index */
+
+ DrawInfo
+ **graphic_context;
+
+ int
+ filter_off; /* true if not filtering attributes */
+
+ /* Pretty-printing depth */
+ unsigned int
+ indent_depth; /* number of left-hand pad characters */
+
+ /* Path operation support */
+ PathOperation
+ path_operation;
+
+ PathMode
+ path_mode;
+
+ /* Structure unique signature */
+ unsigned long
+ signature;
+};
+
+/*
+ Forward declarations.
+*/
+static int
+ MvgPrintf(DrawingWand *drawing_wand, const char *format, ...)
+#if defined(__GNUC__)
+MAGICK_ATTRIBUTE ((format (printf, 2, 3)))
+#endif
+,
+ MvgAutoWrapPrintf(DrawingWand *drawing_wand, const char *format, ...)
+#if defined(__GNUC__)
+MAGICK_ATTRIBUTE ((format (printf, 2, 3)))
+#endif
+;
+static void
+ MvgAppendColor(DrawingWand *drawing_wand, const PixelPacket *color);
+
+
+/* "Printf" for MVG commands */
+static int MvgPrintf(DrawingWand *drawing_wand,const char *format,...)
+{
+ const size_t
+ alloc_size=20*MaxTextExtent; /* 40K */
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->mvg == (char*) NULL)
+ {
+ drawing_wand->mvg=MagickAllocateMemory(char *,alloc_size);
+ if ( drawing_wand->mvg == (char*) NULL )
+ {
+ ThrowException3(&drawing_wand->exception,
+ ResourceLimitError,MemoryAllocationFailed,UnableToDrawOnImage);
+ return(-1);
+ }
+
+ drawing_wand->mvg_alloc=alloc_size;
+ drawing_wand->mvg_length=0;
+ if (drawing_wand->mvg == 0)
+ {
+ ThrowException3(&drawing_wand->exception,
+ ResourceLimitError,MemoryAllocationFailed,UnableToDrawOnImage);
+ return(-1);
+ }
+ }
+ if (drawing_wand->mvg_alloc < (drawing_wand->mvg_length + MaxTextExtent * 10))
+ {
+ size_t realloc_size=drawing_wand->mvg_alloc + alloc_size;
+
+ MagickReallocMemory(char *,drawing_wand->mvg,realloc_size);
+ if (drawing_wand->mvg == NULL)
+ {
+ ThrowException3(&drawing_wand->exception,
+ ResourceLimitError,MemoryAllocationFailed,UnableToDrawOnImage);
+ return -1;
+ }
+ drawing_wand->mvg_alloc=realloc_size;
+ }
+ {
+ ssize_t
+ formatted_length;
+
+ va_list
+ argp;
+
+ while (drawing_wand->mvg_width < drawing_wand->indent_depth)
+ {
+ drawing_wand->mvg[drawing_wand->mvg_length]=' ';
+ drawing_wand->mvg_length++;
+ drawing_wand->mvg_width++;
+ }
+ drawing_wand->mvg[drawing_wand->mvg_length]=0;
+
+ /*
+ According to C99, vsnprintf() returns the number of formatted
+ bytes which WOULD have been written (not including trailing
+ '\0') if there was sufficient space available. If an output
+ error occurs, then a negative value is returned.
+
+ Under Linux glibc 2.0.6 and earlier, -1 is returned when the
+ output has been truncated.
+ */
+ {
+ size_t
+ space_available;
+
+ space_available=drawing_wand->mvg_alloc-drawing_wand->mvg_length-1;
+ formatted_length = -1;
+ if (space_available > 0)
+ {
+
+ va_start(argp, format);
+#if defined(HAVE_VSNPRINTF)
+ formatted_length=vsnprintf(drawing_wand->mvg+drawing_wand->mvg_length,
+ (size_t) space_available,format,argp);
+#else
+ formatted_length=vsprintf(drawing_wand->mvg+drawing_wand->mvg_length,
+ format,argp);
+#endif
+ va_end(argp);
+ }
+ if ((formatted_length < 0) || ((size_t) formatted_length > space_available))
+ {
+ ThrowException(&drawing_wand->exception,DrawError,
+ UnableToPrint,format);
+ }
+ else
+ {
+ drawing_wand->mvg_length+=formatted_length;
+ drawing_wand->mvg_width+=formatted_length;
+ }
+ }
+ drawing_wand->mvg[drawing_wand->mvg_length]=0;
+ if ((drawing_wand->mvg_length > 1) &&
+ (drawing_wand->mvg[drawing_wand->mvg_length-1] == '\n'))
+ drawing_wand->mvg_width=0;
+ assert((drawing_wand->mvg_length+1) < drawing_wand->mvg_alloc);
+ return formatted_length;
+ }
+}
+
+static int MvgAutoWrapPrintf(DrawingWand *drawing_wand,const char *format,...)
+{
+ char
+ buffer[MaxTextExtent];
+
+ int
+ formatted_length;
+
+ va_list
+ argp;
+
+ va_start(argp,format);
+#if defined(HAVE_VSNPRINTF)
+ formatted_length=vsnprintf(buffer,sizeof(buffer)-1,format,argp);
+#else
+ formatted_length=vsprintf(buffer,format,argp);
+#endif
+ va_end(argp);
+ buffer[sizeof(buffer)-1]=0;
+ if (formatted_length < 0)
+ {
+ ThrowException(&drawing_wand->exception,DrawError,
+ UnableToPrint,format);
+ }
+ else
+ {
+ if (((drawing_wand->mvg_width + formatted_length) > 78) &&
+ (buffer[formatted_length-1] != '\n'))
+ (void) MvgPrintf(drawing_wand, "\n");
+ (void) MvgPrintf(drawing_wand,"%s",buffer);
+ }
+ return(formatted_length);
+}
+
+static void MvgAppendColor(DrawingWand *drawing_wand, const PixelPacket *color)
+{
+ if (color->red == 0U && color->green == 0U && color->blue == 0U &&
+ color->opacity == TransparentOpacity)
+ (void) MvgPrintf(drawing_wand,"none");
+ else
+ {
+ char
+ tuple[MaxTextExtent];
+
+ GetColorTuple(color,QuantumDepth,MagickTrue,MagickTrue,tuple);
+ (void) MvgPrintf(drawing_wand,"%.1024s",tuple);
+ }
+}
+
+static void MvgAppendPointsCommand(DrawingWand *drawing_wand,
+ char *command,const unsigned long number_coordinates,const PointInfo *coordinates)
+{
+ const PointInfo
+ *coordinate;
+
+ size_t
+ i;
+
+ (void) MvgPrintf(drawing_wand, "%s", command);
+ for (i=number_coordinates, coordinate=coordinates; i; i--)
+ {
+ (void) MvgAutoWrapPrintf(drawing_wand," %g,%g",coordinate->x,coordinate->y);
+ coordinate++;
+ }
+ (void) MvgPrintf(drawing_wand, "\n");
+}
+
+static void AdjustAffine(DrawingWand *drawing_wand,const AffineMatrix *affine)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
+ (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
+ {
+ AffineMatrix
+ current;
+
+ current=CurrentContext->affine;
+ CurrentContext->affine.sx=current.sx*affine->sx+current.ry*affine->rx;
+ CurrentContext->affine.rx=current.rx*affine->sx+current.sy*affine->rx;
+ CurrentContext->affine.ry=current.sx*affine->ry+current.ry*affine->sy;
+ CurrentContext->affine.sy=current.rx*affine->ry+current.sy*affine->sy;
+ CurrentContext->affine.tx=current.sx*affine->tx+current.ry*affine->ty+
+ current.tx;
+ CurrentContext->affine.ty=current.rx*affine->tx+current.sy*affine->ty+
+ current.ty;
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e D r a w i n g W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneDrawingWand() returns a new drawing wand which is a full (deep) copy
+% of an existing drawing wand.
+%
+% The format of the CloneDrawingWand method is:
+%
+% DrawingWand *CloneDrawingWand(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand to copy
+%
+*/
+WandExport DrawingWand *CloneDrawingWand(const DrawingWand *drawing_wand)
+{
+ DrawingWand
+ *clone_wand;
+
+ ExceptionInfo
+ exeption_info;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+
+ clone_wand=MagickAllocateMemory(DrawingWand *,sizeof(*clone_wand));
+ if (clone_wand == (DrawingWand *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateDrawingWand);
+
+ GetExceptionInfo(&exeption_info);
+ (void) memcpy(clone_wand,drawing_wand,sizeof(*clone_wand));
+ GetExceptionInfo(&clone_wand->exception);
+ clone_wand->image=(Image *) NULL;
+ clone_wand->mvg=(char *) NULL;
+ clone_wand->pattern_id=(char *) NULL;
+ clone_wand->graphic_context=(DrawInfo **) NULL;
+
+ clone_wand->own_image=MagickTrue;
+ if (drawing_wand->image != (Image *) NULL)
+ {
+ clone_wand->image=CloneImage(drawing_wand->image,0,0,MagickTrue,
+ &exeption_info);
+ if (clone_wand->image == (Image *) NULL)
+ goto clone_drawing_wand_fail;
+ }
+
+ if (drawing_wand->mvg)
+ {
+ clone_wand->mvg=MagickAllocateMemory(char *,drawing_wand->mvg_alloc);
+ if (clone_wand->mvg == (char *) NULL)
+ {
+ ThrowException3(&exeption_info,ResourceLimitError,
+ MemoryAllocationFailed,UnableToCloneDrawingWand);
+ goto clone_drawing_wand_fail;
+ }
+ (void) memcpy(clone_wand->mvg,drawing_wand->mvg,drawing_wand->mvg_length+1);
+ }
+
+ if (drawing_wand->pattern_id != (const char *) NULL)
+ clone_wand->pattern_id=AllocateString(drawing_wand->pattern_id);
+
+ if (drawing_wand->graphic_context != (DrawInfo **) NULL)
+ {
+ clone_wand->graphic_context=MagickAllocateArray(DrawInfo **,
+ drawing_wand->index+1,
+ sizeof(DrawInfo *));
+ if (clone_wand->graphic_context == (DrawInfo **) NULL)
+ {
+ ThrowException3(&exeption_info,ResourceLimitError,
+ MemoryAllocationFailed,UnableToCloneDrawingWand);
+ goto clone_drawing_wand_fail;
+ }
+ (void) memset(clone_wand->graphic_context,0,
+ (drawing_wand->index+1)*sizeof(DrawInfo *));
+
+ for (clone_wand->index=0; clone_wand->index <= drawing_wand->index; clone_wand->index++)
+ {
+ clone_wand->graphic_context[clone_wand->index]=
+ CloneDrawInfo((ImageInfo*)NULL,drawing_wand->graphic_context[clone_wand->index]);
+ if (clone_wand->graphic_context[clone_wand->index] == (DrawInfo*) NULL)
+ {
+ ThrowException3(&exeption_info,ResourceLimitError,
+ MemoryAllocationFailed,UnableToCloneDrawingWand);
+ goto clone_drawing_wand_fail;
+ }
+ }
+ clone_wand->index=drawing_wand->index;
+ }
+
+ return(clone_wand);
+
+clone_drawing_wand_fail:
+
+ if (clone_wand->image != (Image *) NULL)
+ DestroyImage(clone_wand->image);
+ MagickFreeMemory(clone_wand->mvg);
+ MagickFreeMemory(clone_wand->pattern_id);
+ if (clone_wand->graphic_context != (DrawInfo **) NULL)
+ {
+ for ( ; clone_wand->index >= 0; clone_wand->index--)
+ {
+ if (clone_wand->graphic_context[clone_wand->index] != (DrawInfo*) NULL)
+ DestroyDrawInfo(clone_wand->graphic_context[clone_wand->index]);
+ clone_wand->graphic_context[clone_wand->index]=(DrawInfo*) NULL;
+ }
+ MagickFreeMemory(clone_wand->graphic_context);
+ }
+ (void) memset(clone_wand,0,sizeof(*clone_wand));
+ MagickFreeMemory(clone_wand);
+ /* No place to report exception, but it may be logged. */
+ DestroyExceptionInfo(&exeption_info);
+ return(clone_wand);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y D r a w i n g W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyDrawingWand() frees all resources associated with the drawing
+% wand. Once the drawing wand has been freed, it should not be used
+% any further unless it re-allocated.
+%
+% The format of the DestroyDrawingWand method is:
+%
+% void DestroyDrawingWand(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand to destroy.
+%
+*/
+WandExport void DestroyDrawingWand(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+
+ DestroyExceptionInfo(&drawing_wand->exception);
+
+ if ((drawing_wand->image != (Image*) NULL) &&
+ (drawing_wand->own_image == MagickTrue))
+ DestroyImage(drawing_wand->image);
+
+ MagickFreeMemory(drawing_wand->mvg);
+
+ MagickFreeMemory(drawing_wand->pattern_id);
+
+ if (drawing_wand->graphic_context != (DrawInfo **) NULL)
+ {
+ for ( ; drawing_wand->index >= 0; drawing_wand->index--)
+ {
+ if (drawing_wand->graphic_context[drawing_wand->index] != (DrawInfo*) NULL)
+ DestroyDrawInfo(drawing_wand->graphic_context[drawing_wand->index]);
+ drawing_wand->graphic_context[drawing_wand->index]=(DrawInfo*) NULL;
+ }
+ MagickFreeMemory(drawing_wand->graphic_context);
+ }
+
+ (void) memset(drawing_wand,0,sizeof(*drawing_wand));
+ MagickFreeMemory(drawing_wand);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w A n n o t a t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawAnnotation() draws text on the image.
+%
+% The format of the DrawAnnotation method is:
+%
+% void DrawAnnotation(DrawingWand *drawing_wand,const double x,
+% const double y,const unsigned char *text)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: x ordinate to left of text
+%
+% o y: y ordinate to text baseline
+%
+% o text: text to draw
+%
+*/
+WandExport void DrawAnnotation(DrawingWand *drawing_wand,const double x,
+ const double y,const unsigned char *text)
+{
+ char
+ *escaped_text;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(text != (const unsigned char *) NULL);
+ escaped_text=EscapeString((const char*)text,'\'');
+ (void) MvgPrintf(drawing_wand,"text %g,%g '%s'\n",x,y,escaped_text);
+ MagickFreeMemory(escaped_text);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w A f f i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawAffine() adjusts the current affine transformation matrix with
+% the specified affine transformation matrix. Note that the current affine
+% transform is adjusted rather than replaced.
+%
+% The format of the DrawAffine method is:
+%
+% void DrawAffine(DrawingWand *drawing_wand,const AffineMatrix *affine)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: Drawing drawing_wand
+%
+% o affine: Affine matrix parameters
+%
+*/
+WandExport void DrawAffine(DrawingWand *drawing_wand,
+ const AffineMatrix *affine)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(affine != (const AffineMatrix *)NULL);
+ AdjustAffine(drawing_wand,affine );
+ (void) MvgPrintf(drawing_wand,"affine %.6g,%.6g,%.6g,%.6g,%.6g,%.6g\n",affine->sx,
+ affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w A l l o c a t e W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawAllocateWand() allocates an initial drawing wand which is an
+% opaque handle required by the remaining drawing methods.
+%
+% The format of the DrawAllocateWand method is:
+%
+% DrawingWand DrawAllocateWand(const DrawInfo *draw_info,Image *image)
+%
+% A description of each parameter follows:
+%
+% o draw_info: Initial drawing defaults. Set to NULL to use
+% ImageMagick defaults.
+%
+% o image: The image to draw on.
+%
+*/
+WandExport DrawingWand *DrawAllocateWand(const DrawInfo *draw_info,Image *image)
+{
+ DrawingWand
+ *drawing_wand;
+
+ drawing_wand=NewDrawingWand();
+ if (draw_info != (const DrawInfo *) NULL)
+ {
+ DestroyDrawInfo(CurrentContext);
+ CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ }
+ if (image != (Image *) NULL)
+ {
+ DestroyImage(drawing_wand->image);
+ drawing_wand->own_image=MagickFalse;
+ }
+ drawing_wand->image=image;
+ return drawing_wand;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w A r c %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawArc() draws an arc falling within a specified bounding rectangle on the
+% image.
+%
+% The format of the DrawArc method is:
+%
+% void DrawArc(DrawingWand *drawing_wand,const double sx,const double sy,
+% const double ex,const double ey,const double sd,const double ed)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o sx: starting x ordinate of bounding rectangle
+%
+% o sy: starting y ordinate of bounding rectangle
+%
+% o ex: ending x ordinate of bounding rectangle
+%
+% o ey: ending y ordinate of bounding rectangle
+%
+% o sd: starting degrees of rotation
+%
+% o ed: ending degrees of rotation
+%
+*/
+WandExport void DrawArc(DrawingWand *drawing_wand,const double sx,
+ const double sy,const double ex,const double ey,const double sd,
+ const double ed)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"arc %g,%g %g,%g %g,%g\n",sx,sy,ex,ey,
+ sd,ed);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w B e z i e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawBezier() draws a bezier curve through a set of points on the image.
+%
+% The format of the DrawBezier method is:
+%
+% void DrawBezier(DrawingWand *drawing_wand,
+% const unsigned long number_coordinates,const PointInfo *coordinates)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o number_coordinates: number of coordinates
+%
+% o coordinates: coordinates
+%
+*/
+WandExport void DrawBezier(DrawingWand *drawing_wand,
+ const unsigned long number_coordinates,const PointInfo *coordinates)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(coordinates != (const PointInfo *) NULL);
+ MvgAppendPointsCommand(drawing_wand,"bezier",number_coordinates,coordinates);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C i r c l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawCircle() draws a circle on the image.
+%
+% The format of the DrawCircle method is:
+%
+% void DrawCircle(DrawingWand *drawing_wand,const double ox,
+% const double oy,const double px, const double py)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o ox: origin x ordinate
+%
+% o oy: origin y ordinate
+%
+% o px: perimeter x ordinate
+%
+% o py: perimeter y ordinate
+%
+*/
+WandExport void DrawCircle(DrawingWand *drawing_wand,const double ox,
+ const double oy,const double px,const double py)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand, "circle %g,%g %g,%g\n",ox,oy,px,py);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C l e a r E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawClearException() clears any existing exception from the drawing wand.
+%
+% The format of the DrawGetException method is:
+%
+% MagickPassFail DrawClearException(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport MagickBool DrawClearException(DrawingWand *drawing_wand)
+{
+ DestroyExceptionInfo(&drawing_wand->exception);
+ GetExceptionInfo(&drawing_wand->exception);
+ return MagickPass;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetClipPath() obtains the current clipping path ID. The value returned
+% must be deallocated by the user when it is no longer needed.
+%
+% The format of the DrawGetClipPath method is:
+%
+% char *DrawGetClipPath(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport char *DrawGetClipPath(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (CurrentContext->clip_path != (char *) NULL)
+ return((char *) AcquireString(CurrentContext->clip_path));
+ return((char *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetClipPath() associates a named clipping path with the image. Only
+% the areas drawn on by the clipping path will be modified as long as it
+% remains in effect.
+%
+% The format of the DrawSetClipPath method is:
+%
+% void DrawSetClipPath(DrawingWand *drawing_wand,const char *clip_path)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o clip_path: name of clipping path to associate with image
+%
+*/
+WandExport void DrawSetClipPath(DrawingWand *drawing_wand,
+ const char *clip_path)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(clip_path != (const char *) NULL);
+ if ((CurrentContext->clip_path == NULL) || drawing_wand->filter_off ||
+ LocaleCompare(CurrentContext->clip_path,clip_path) != 0)
+ {
+ (void) CloneString(&CurrentContext->clip_path,clip_path);
+ if (CurrentContext->clip_path == (char*)NULL)
+ ThrowException3(&drawing_wand->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ (void) MvgPrintf(drawing_wand,"clip-path url(#%s)\n",clip_path);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t C l i p R u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetClipRule() returns the current polygon fill rule to be used by the
+% clipping path.
+%
+% The format of the DrawGetClipRule method is:
+%
+% FillRule DrawGetClipRule(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport FillRule DrawGetClipRule(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->fill_rule);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t C l i p R u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
+%
+% The format of the DrawSetClipRule method is:
+%
+% void DrawSetClipRule(DrawingWand *drawing_wand,const FillRule fill_rule)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
+%
+*/
+WandExport void DrawSetClipRule(DrawingWand *drawing_wand,
+ const FillRule fill_rule)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->fill_rule != fill_rule))
+ {
+ CurrentContext->fill_rule=fill_rule;
+ switch (fill_rule)
+ {
+ case EvenOddRule:
+ p="evenodd";
+ break;
+ case NonZeroRule:
+ p="nonzero";
+ break;
+ default:
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand, "clip-rule %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t C l i p U n i t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetClipUnits() returns the interpretation of clip path units.
+%
+% The format of the DrawGetClipUnits method is:
+%
+% ClipPathUnits DrawGetClipUnits(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->clip_units);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetException() obtains error information associated with the last
+% exception (if any). If an exception did occur, an allocated text string
+% is returned which contains a detailed description of the exception. This
+% string must be deallocated by the user once it is no longer needed.
+%
+% The format of the DrawGetException method is:
+%
+% char *DrawGetException(const DrawingWand *drawing_wand,
+% ExceptionType *severity)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o severity: Enumeration corresponding to last thrown exception.
+%
+*/
+WandExport char *DrawGetException(const DrawingWand *drawing_wand,
+ ExceptionType *severity)
+{
+ char
+ buffer[MaxTextExtent],
+ *description;
+
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(drawing_wand->exception.signature == MagickSignature);
+
+ description=(char *) NULL;
+ buffer[0]='\0';
+ *severity=drawing_wand->exception.severity;
+ if (drawing_wand->exception.severity != UndefinedException)
+ {
+ if (drawing_wand->exception.description)
+ FormatString(buffer,"%.1024s (%.1024s)",
+ drawing_wand->exception.reason,
+ drawing_wand->exception.description);
+ else
+ FormatString(buffer,"%.1024s",
+ drawing_wand->exception.reason);
+ CloneString(&description,buffer);
+ }
+
+ return(description);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t C l i p U n i t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetClipUnits() sets the interpretation of clip path units.
+%
+% The format of the DrawSetClipUnits method is:
+%
+% void DrawSetClipUnits(DrawingWand *drawing_wand,
+% const ClipPathUnits clip_units)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o clip_units: units to use (UserSpace, UserSpaceOnUse, or ObjectBoundingBox)
+%
+*/
+WandExport void DrawSetClipUnits(DrawingWand *drawing_wand,
+ const ClipPathUnits clip_units)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->clip_units != clip_units))
+ {
+ CurrentContext->clip_units=clip_units;
+ if ( clip_units == ObjectBoundingBox )
+ {
+ AffineMatrix
+ affine;
+
+ IdentityAffine(&affine);
+ affine.sx=CurrentContext->bounds.x2;
+ affine.sy=CurrentContext->bounds.y2;
+ affine.tx=CurrentContext->bounds.x1;
+ affine.ty=CurrentContext->bounds.y1;
+ AdjustAffine( drawing_wand, &affine );
+ }
+
+ switch (clip_units)
+ {
+ case UserSpace:
+ p="userSpace";
+ break;
+ case UserSpaceOnUse:
+ p="userSpaceOnUse";
+ break;
+ case ObjectBoundingBox:
+ p="objectBoundingBox";
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand, "clip-units %s\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawColor() draws color on image using the current fill color, starting at
+% specified position, and using specified paint method. The available paint
+% methods are:
+%
+% PointMethod: Recolors the target pixel
+% ReplaceMethod: Recolor any pixel that matches the target pixel.
+% FloodfillMethod: Recolors target pixels and matching neighbors.
+% FillToBorderMethod: Recolor target pixels and neighbors not matching
+$ border color.
+% ResetMethod: Recolor all pixels.
+%
+% The format of the DrawColor method is:
+%
+% void DrawColor(DrawingWand *drawing_wand,const double x,const double y,
+% const PaintMethod paintMethod)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: x ordinate
+%
+% o y: y ordinate
+%
+% o paintMethod: paint method
+%
+*/
+WandExport void DrawColor(DrawingWand *drawing_wand,const double x,
+ const double y,const PaintMethod paintMethod)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ switch (paintMethod)
+ {
+ case PointMethod:
+ p="point";
+ break;
+ case ReplaceMethod:
+ p="replace";
+ break;
+ case FloodfillMethod:
+ p="floodfill";
+ break;
+ case FillToBorderMethod:
+ p="filltoborder";
+ break;
+ case ResetMethod:
+ p="reset";
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand, "color %g,%g %s\n", x, y, p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C o m m e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawComment() adds a comment to a vector output stream.
+%
+% The format of the DrawComment method is:
+%
+% void DrawComment(DrawingWand *drawing_wand,const char *comment)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o comment: comment text
+%
+*/
+WandExport void DrawComment(DrawingWand *drawing_wand,const char* comment)
+{
+ (void) MvgPrintf(drawing_wand,"#%s\n",comment);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w E l l i p s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawEllipse() draws an ellipse on the image.
+%
+% The format of the DrawEllipse method is:
+%
+% void DrawEllipse(DrawingWand *drawing_wand,const double ox,
+% const double oy,const double rx,const double ry,const double start,
+% const double end)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o ox: origin x ordinate
+%
+% o oy: origin y ordinate
+%
+% o rx: radius in x
+%
+% o ry: radius in y
+%
+% o start: starting rotation in degrees
+%
+% o end: ending rotation in degrees
+%
+*/
+WandExport void DrawEllipse(DrawingWand *drawing_wand,const double ox,
+ const double oy,const double rx,const double ry,const double start,
+ const double end)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"ellipse %g,%g %g,%g %g,%g\n",ox,oy,rx,ry,
+ start,end);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F i l l C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFillColor() returns the fill color used for drawing filled objects.
+%
+% The format of the DrawGetFillColor method is:
+%
+% void DrawGetFillColor(const DrawingWand *drawing_wand,
+% PixelWand *fill_color)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o fill_color: Return the fill color.
+%
+*/
+WandExport void DrawGetFillColor(const DrawingWand *drawing_wand,
+ PixelWand *fill_color)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ PixelSetQuantumColor(fill_color,&CurrentContext->fill);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillColor() sets the fill color to be used for drawing filled objects.
+%
+% The format of the DrawSetFillColor method is:
+%
+% void DrawSetFillColor(DrawingWand *drawing_wand,
+% const PixelWand *fill_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o fill_wand: fill wand.
+%
+*/
+WandExport void DrawSetFillColor(DrawingWand *drawing_wand,
+ const PixelWand *fill_wand)
+{
+ PixelPacket
+ *current_fill,
+ fill_color,
+ new_fill;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(fill_wand != (const PixelWand *) NULL);
+ PixelGetQuantumColor(fill_wand,&fill_color);
+ new_fill=fill_color;
+ if (new_fill.opacity != TransparentOpacity)
+ new_fill.opacity=CurrentContext->opacity;
+ current_fill=&CurrentContext->fill;
+ if (drawing_wand->filter_off || !WandColorMatch(current_fill,&new_fill))
+ {
+ CurrentContext->fill=new_fill;
+ (void) MvgPrintf(drawing_wand,"fill '");
+ MvgAppendColor(drawing_wand,&fill_color);
+ (void) MvgPrintf(drawing_wand,"'\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l P a t t e r n U R L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
+% objects. Only local URLs ("#identifier") are supported at this time. These
+% local URLs are normally created by defining a named fill pattern with
+% DrawPushPattern/DrawPopPattern.
+%
+% The format of the DrawSetFillPatternURL method is:
+%
+% void DrawSetFillPatternURL(DrawingWand *drawing_wand,
+% const char *fill_url)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o fill_url: URL to use to obtain fill pattern.
+%
+*/
+WandExport void DrawSetFillPatternURL(DrawingWand *drawing_wand,
+ const char* fill_url)
+{
+ char
+ pattern[MaxTextExtent];
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(fill_url != NULL);
+ if (fill_url[0] != '#')
+ ThrowException(&drawing_wand->exception,DrawWarning,
+ NotARelativeURL,fill_url);
+ (void) MagickFormatString(pattern,MaxTextExtent,"[%.1024s]",fill_url+1);
+ if (GetImageAttribute(drawing_wand->image,pattern) == (ImageAttribute *) NULL)
+ {
+ ThrowException(&drawing_wand->exception,DrawWarning,
+ URLNotFound,fill_url);
+ }
+ else
+ {
+ char
+ pattern_spec[MaxTextExtent];
+
+ (void) MagickFormatString(pattern_spec,MaxTextExtent,"url(%.1024s)",
+ fill_url);
+ if (CurrentContext->fill.opacity != TransparentOpacity)
+ CurrentContext->fill.opacity=CurrentContext->opacity;
+ (void) MvgPrintf(drawing_wand,"fill %s\n",pattern_spec);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F i l l O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFillOpacity() returns the opacity used when drawing using the fill
+% color or fill texture. Fully opaque is 1.0.
+%
+% The format of the DrawGetFillOpacity method is:
+%
+% double DrawGetFillOpacity(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport double DrawGetFillOpacity(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return((double) CurrentContext->opacity/MaxRGB);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillOpacity() sets the opacity to use when drawing using the fill
+% color or fill texture. Fully opaque is 1.0.
+%
+% The format of the DrawSetFillOpacity method is:
+%
+% void DrawSetFillOpacity(DrawingWand *drawing_wand,
+% const double fill_opacity)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o fill_opacity: fill opacity
+%
+*/
+WandExport void DrawSetFillOpacity(DrawingWand *drawing_wand,
+ const double fill_opacity)
+{
+ Quantum
+ opacity;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ opacity=(Quantum)
+ ((double) MaxRGB*(1.0-(fill_opacity <= 1.0 ? fill_opacity : 1.0 ))+0.5);
+ if (drawing_wand->filter_off || (CurrentContext->opacity != opacity))
+ {
+ CurrentContext->opacity=opacity;
+ (void) MvgPrintf(drawing_wand,"fill-opacity %g\n",fill_opacity);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F i l l R u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFillRule() returns the fill rule used while drawing polygons.
+%
+% The format of the DrawGetFillRule method is:
+%
+% FillRule DrawGetFillRule(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport FillRule DrawGetFillRule(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->fill_rule);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F i l l R u l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFillRule() sets the fill rule to use while drawing polygons.
+%
+% The format of the DrawSetFillRule method is:
+%
+% void DrawSetFillRule(DrawingWand *drawing_wand,const FillRule fill_rule)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
+%
+*/
+WandExport void DrawSetFillRule(DrawingWand *drawing_wand,
+ const FillRule fill_rule)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->fill_rule != fill_rule))
+ {
+ CurrentContext->fill_rule=fill_rule;
+ switch (fill_rule)
+ {
+ case EvenOddRule:
+ p="evenodd";
+ break;
+ case NonZeroRule:
+ p="nonzero";
+ break;
+ default:
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand,"fill-rule %s\n",p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFont() returns a null-terminaged string specifying the font used
+% when annotating with text. The value returned must be freed by the user
+% when no longer needed.
+%
+% The format of the DrawGetFont method is:
+%
+% char *DrawGetFont(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport char *DrawGetFont(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (CurrentContext->font != (char *) NULL)
+ return(AcquireString(CurrentContext->font));
+ return((char *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFont() sets the fully-sepecified font to use when annotating with
+% text.
+%
+% The format of the DrawSetFont method is:
+%
+% void DrawSetFont(DrawingWand *drawing_wand,const char *font_name)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o font_name: font name
+%
+*/
+WandExport void DrawSetFont(DrawingWand *drawing_wand,const char *font_name)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(font_name != (const char *) NULL);
+ if (drawing_wand->filter_off || (CurrentContext->font == NULL) ||
+ LocaleCompare(CurrentContext->font,font_name) != 0)
+ {
+ (void) CloneString(&CurrentContext->font,font_name);
+ if (CurrentContext->font == (char*)NULL)
+ ThrowException3(&drawing_wand->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ (void) MvgPrintf(drawing_wand,"font '%s'\n",font_name);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t F a m i l y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontFamily() returns the font family to use when annotating with text.
+% The value returned must be freed by the user when it is no longer needed.
+%
+% The format of the DrawGetFontFamily method is:
+%
+% char *DrawGetFontFamily(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport char *DrawGetFontFamily(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (CurrentContext->family != NULL)
+ return(AcquireString(CurrentContext->family));
+ return((char *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t F a m i l y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontFamily() sets the font family to use when annotating with text.
+%
+% The format of the DrawSetFontFamily method is:
+%
+% void DrawSetFontFamily(DrawingWand *drawing_wand,const char *font_family)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o font_family: font family
+%
+*/
+WandExport void DrawSetFontFamily(DrawingWand *drawing_wand,
+ const char *font_family)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(font_family != (const char *) NULL);
+ if (drawing_wand->filter_off || (CurrentContext->family == NULL) ||
+ LocaleCompare(CurrentContext->family,font_family) != 0)
+ {
+ (void) CloneString(&CurrentContext->family,font_family);
+ if (CurrentContext->family == (char *) NULL)
+ ThrowException3(&drawing_wand->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ (void) MvgPrintf(drawing_wand,"font-family '%s'\n",font_family);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontSize() returns the font pointsize used when annotating with text.
+%
+% The format of the DrawGetFontSize method is:
+%
+% double DrawGetFontSize(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport double DrawGetFontSize(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->pointsize);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontSize() sets the font pointsize to use when annotating with text.
+%
+% The format of the DrawSetFontSize method is:
+%
+% void DrawSetFontSize(DrawingWand *drawing_wand,const double pointsize)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o pointsize: text pointsize
+%
+*/
+WandExport void DrawSetFontSize(DrawingWand *drawing_wand,
+ const double pointsize)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off ||
+ (AbsoluteValue(CurrentContext->pointsize-pointsize) > MagickEpsilon))
+ {
+ CurrentContext->pointsize=pointsize;
+ (void) MvgPrintf(drawing_wand,"font-size %g\n",pointsize);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t S t r e t c h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontStretch() returns the font stretch used when annotating with text.
+%
+% The format of the DrawGetFontStretch method is:
+%
+% StretchType DrawGetFontStretch(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport StretchType DrawGetFontStretch(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->stretch);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t S t r e t c h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontStretch() sets the font stretch to use when annotating with text.
+% The AnyStretch enumeration acts as a wild-card "don't care" option.
+%
+% The format of the DrawSetFontStretch method is:
+%
+% void DrawSetFontStretch(DrawingWand *drawing_wand,
+% const StretchType font_stretch)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
+% CondensedStretch, SemiCondensedStretch,
+% SemiExpandedStretch, ExpandedStretch,
+% ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
+%
+*/
+WandExport void DrawSetFontStretch(DrawingWand *drawing_wand,
+ const StretchType font_stretch)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->stretch != font_stretch))
+ {
+ CurrentContext->stretch=font_stretch;
+ switch (font_stretch)
+ {
+ case NormalStretch:
+ p="normal";
+ break;
+ case UltraCondensedStretch:
+ p="ultra-condensed";
+ break;
+ case ExtraCondensedStretch:
+ p="extra-condensed";
+ break;
+ case CondensedStretch:
+ p="condensed";
+ break;
+ case SemiCondensedStretch:
+ p="semi-condensed";
+ break;
+ case SemiExpandedStretch:
+ p="semi-expanded";
+ break;
+ case ExpandedStretch:
+ p="expanded";
+ break;
+ case ExtraExpandedStretch:
+ p="extra-expanded";
+ break;
+ case UltraExpandedStretch:
+ p="ultra-expanded";
+ break;
+ case AnyStretch:
+ p="all";
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand,"font-stretch '%s'\n",p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t S t y l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontStyle() returns the font style used when annotating with text.
+%
+% The format of the DrawGetFontStyle method is:
+%
+% StyleType DrawGetFontStyle(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport StyleType DrawGetFontStyle(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->style);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t S t y l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontStyle() sets the font style to use when annotating with text.
+% The AnyStyle enumeration acts as a wild-card "don't care" option.
+%
+% The format of the DrawSetFontStyle method is:
+%
+% void DrawSetFontStyle(DrawingWand *drawing_wand,const StyleType style)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
+%
+*/
+WandExport void DrawSetFontStyle(DrawingWand *drawing_wand,
+ const StyleType style)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->style != style))
+ {
+ CurrentContext->style=style;
+ switch (style)
+ {
+ case NormalStyle:
+ p="normal";
+ break;
+ case ItalicStyle:
+ p="italic";
+ break;
+ case ObliqueStyle:
+ p="oblique";
+ break;
+ case AnyStyle:
+ p="all";
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand, "font-style '%s'\n", p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t F o n t W e i g h t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetFontWeight() returns the font weight used when annotating with text.
+%
+% The format of the DrawGetFontWeight method is:
+%
+% unsigned long DrawGetFontWeight(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport unsigned long DrawGetFontWeight(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->weight);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t F o n t W e i g h t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetFontWeight() sets the font weight to use when annotating with text.
+%
+% The format of the DrawSetFontWeight method is:
+%
+% void DrawSetFontWeight(DrawingWand *drawing_wand,
+% const unsigned long font_weight)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o font_weight: font weight (valid range 100-900)
+%
+*/
+WandExport void DrawSetFontWeight(DrawingWand *drawing_wand,
+ const unsigned long font_weight)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->weight != font_weight))
+ {
+ CurrentContext->weight=font_weight;
+ (void) MvgPrintf(drawing_wand,"font-weight %lu\n",font_weight);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t G r a v i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetGravity() returns the text placement gravity used when annotating
+% with text.
+%
+% The format of the DrawGetGravity method is:
+%
+% GravityType DrawGetGravity(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport GravityType DrawGetGravity(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->gravity);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t G r a v i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetGravity() sets the text placement gravity to use when annotating
+% with text.
+%
+% The format of the DrawSetGravity method is:
+%
+% void DrawSetGravity(DrawingWand *drawing_wand,const GravityType gravity)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o gravity: positioning gravity (NorthWestGravity, NorthGravity,
+% NorthEastGravity, WestGravity, CenterGravity,
+% EastGravity, SouthWestGravity, SouthGravity,
+% SouthEastGravity)
+%
+*/
+WandExport void DrawSetGravity(DrawingWand *drawing_wand,
+ const GravityType gravity)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->gravity != gravity))
+ {
+ CurrentContext->gravity=gravity;
+ switch (gravity)
+ {
+ case NorthWestGravity:
+ p="NorthWest";
+ break;
+ case NorthGravity:
+ p="North";
+ break;
+ case NorthEastGravity:
+ p="NorthEast";
+ break;
+ case WestGravity:
+ p="West";
+ break;
+ case CenterGravity:
+ p="Center";
+ break;
+ case EastGravity:
+ p="East";
+ break;
+ case SouthWestGravity:
+ p="SouthWest";
+ break;
+ case SouthGravity:
+ p="South";
+ break;
+ case SouthEastGravity:
+ p="SouthEast";
+ break;
+ case StaticGravity:
+ case ForgetGravity:
+ {
+ }
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand,"gravity %s\n",p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w C o m p o s i t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawComposite() composites an image onto the current image, using the
+% specified composition operator, specified position, and at the specified
+% size.
+%
+% The format of the DrawComposite method is:
+%
+% void DrawComposite(DrawingWand *drawing_wand,
+% const CompositeOperator composite_operator,const double x,
+% const double y,const double width,const double height,
+% const Image *image)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o composite_operator: composition operator
+%
+% o x: x ordinate of top left corner
+%
+% o y: y ordinate of top left corner
+%
+% o width: Width to resize image to prior to compositing. Specify zero to
+% use existing width.
+%
+% o height: Height to resize image to prior to compositing. Specify zero
+% to use existing height.
+%
+% o image: Image to composite
+%
+*/
+WandExport void DrawComposite(DrawingWand *drawing_wand,
+ const CompositeOperator composite_operator,const double x,const double y,
+ const double width,const double height,const Image *image)
+
+{
+ ImageInfo
+ *image_info;
+
+ Image
+ *clone_image;
+
+ char
+ *media_type=NULL,
+ *base64=NULL;
+
+ const char
+ *mode=NULL;
+
+ unsigned char
+ *blob=(unsigned char *) NULL;
+
+ size_t
+ blob_length=2048,
+ encoded_length=0;
+
+ MonitorHandler
+ handler;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(image != (Image *) NULL);
+ assert(width != 0);
+ assert(height != 0);
+ assert(*image->magick != '\0');
+ clone_image=CloneImage(image,0,0,MagickTrue,&drawing_wand->exception);
+ if (!clone_image)
+ return;
+ image_info=CloneImageInfo((ImageInfo*)NULL);
+ if (!image_info)
+ ThrowException3(&drawing_wand->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ handler=SetMonitorHandler((MonitorHandler) NULL);
+ blob=(unsigned char*) ImageToBlob( image_info,clone_image,&blob_length,
+ &drawing_wand->exception);
+ (void) SetMonitorHandler(handler);
+ DestroyImageInfo(image_info);
+ DestroyImageList(clone_image);
+ if (!blob)
+ return;
+ base64=Base64Encode(blob,blob_length,&encoded_length);
+ MagickFreeMemory(blob);
+ if (!base64)
+ {
+ char
+ buffer[MaxTextExtent];
+
+ (void) MagickFormatString(buffer,MaxTextExtent,"%"
+ MAGICK_SIZE_T_F "d bytes",
+ (4L*blob_length/3L+4L));
+ ThrowException(&drawing_wand->exception,ResourceLimitWarning,
+ MemoryAllocationFailed,buffer);
+ }
+ mode=CompositeOperatorToString(composite_operator);
+ media_type=MagickToMime(image->magick);
+ if (media_type != NULL)
+ {
+ char
+ *str;
+
+ int
+ remaining;
+
+ (void) MvgPrintf(drawing_wand,"image %s %g,%g %g,%g 'data:%s;base64,\n",
+ mode,x,y,width,height,media_type);
+ remaining=(int) encoded_length;
+ str=base64;
+ while ( remaining > 0 )
+ {
+ (void) MvgPrintf(drawing_wand,"%.76s", str);
+ remaining -= 76;
+ str += 76;
+ if (remaining > 0)
+ (void) MvgPrintf(drawing_wand,"\n");
+ }
+ (void) MvgPrintf(drawing_wand,"'\n");
+ }
+ MagickFreeMemory(base64);
+ MagickFreeMemory(media_type);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w L i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawLine() draws a line on the image using the current stroke color,
+% stroke opacity, and stroke width.
+%
+% The format of the DrawLine method is:
+%
+% void DrawLine(DrawingWand *drawing_wand,const double sx,const double sy,
+% const double ex,const double ey)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o sx: starting x ordinate
+%
+% o sy: starting y ordinate
+%
+% o ex: ending x ordinate
+%
+% o ey: ending y ordinate
+%
+*/
+WandExport void DrawLine(DrawingWand *drawing_wand,const double sx,
+ const double sy,const double ex,const double ey)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"line %g,%g %g,%g\n",sx,sy,ex,ey);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w M a t t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawMatte() paints on the image's opacity channel in order to set effected
+% pixels to transparent.
+% to influence the opacity of pixels. The available paint
+% methods are:
+%
+% PointMethod: Select the target pixel
+% ReplaceMethod: Select any pixel that matches the target pixel.
+% FloodfillMethod: Select the target pixel and matching neighbors.
+% FillToBorderMethod: Select the target pixel and neighbors not matching
+% border color.
+% ResetMethod: Select all pixels.
+%
+% The format of the DrawMatte method is:
+%
+% void DrawMatte(DrawingWand *drawing_wand,const double x,const double y,
+% const PaintMethod paint_method)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: x ordinate
+%
+% o y: y ordinate
+%
+% o paint_method:
+%
+*/
+WandExport void DrawMatte(DrawingWand *drawing_wand,const double x,
+ const double y,const PaintMethod paint_method)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ switch (paint_method)
+ {
+ case PointMethod:
+ p="point";
+ break;
+ case ReplaceMethod:
+ p="replace";
+ break;
+ case FloodfillMethod:
+ p="floodfill";
+ break;
+ case FillToBorderMethod:
+ p="filltoborder";
+ break;
+ case ResetMethod:
+ p="reset";
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand,"matte %g,%g %s\n",x,y,p);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C l o s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathClose() adds a path element to the current path which closes the
+% current subpath by drawing a straight line from the current point to the
+% current subpath's most recent starting point (usually, the most recent
+% moveto point).
+%
+% The format of the DrawPathClose method is:
+%
+% void DrawPathClose(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPathClose(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgAutoWrapPrintf(drawing_wand,"%s",
+ drawing_wand->path_mode == AbsolutePathMode ? "Z" : "z");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
+% point to (x,y) using (x1,y1) as the control point at the beginning of
+% the curve and (x2,y2) as the control point at the end of the curve using
+% absolute coordinates. At the end of the command, the new current point
+% becomes the final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToAbsolute method is:
+%
+% void DrawPathCurveToAbsolute(DrawingWand *drawing_wand,const double x1,
+% const double y1,const double x2,const double y2,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x1: x ordinate of control point for curve beginning
+%
+% o y1: y ordinate of control point for curve beginning
+%
+% o x2: x ordinate of control point for curve ending
+%
+% o y2: y ordinate of control point for curve ending
+%
+% o x: x ordinate of the end of the curve
+%
+% o y: y ordinate of the end of the curve
+%
+*/
+
+static void DrawPathCurveTo(DrawingWand *drawing_wand,const PathMode mode,
+ const double x1,const double y1,const double x2,const double y2,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((drawing_wand->path_operation != PathCurveToOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathCurveToOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand, "%c%g,%g %g,%g %g,%g",
+ mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g,%g %g,%g %g,%g",
+ x1,y1,x2,y2,x,y);
+}
+
+WandExport void DrawPathCurveToAbsolute(DrawingWand *drawing_wand,
+ const double x1,const double y1,const double x2,const double y2,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathCurveTo(drawing_wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToRelative() draws a cubic Bezier curve from the current
+% point to (x,y) using (x1,y1) as the control point at the beginning of
+% the curve and (x2,y2) as the control point at the end of the curve using
+% relative coordinates. At the end of the command, the new current point
+% becomes the final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToRelative method is:
+%
+% void DrawPathCurveToRelative(DrawingWand *drawing_wand,const double x1,
+% const double y1,const double x2,const double y2,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x1: x ordinate of control point for curve beginning
+%
+% o y1: y ordinate of control point for curve beginning
+%
+% o x2: x ordinate of control point for curve ending
+%
+% o y2: y ordinate of control point for curve ending
+%
+% o x: x ordinate of the end of the curve
+%
+% o y: y ordinate of the end of the curve
+%
+*/
+WandExport void DrawPathCurveToRelative(DrawingWand *drawing_wand,
+ const double x1,const double y1,const double x2,const double y2,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathCurveTo(drawing_wand,RelativePathMode,x1,y1,x2,y2,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
+% from the current point to (x,y) using (x1,y1) as the control point using
+% absolute coordinates. At the end of the command, the new current point
+% becomes the final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
+%
+% void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *drawing_wand,
+% const double x1,const double y1,onst double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x1: x ordinate of the control point
+%
+% o y1: y ordinate of the control point
+%
+% o x: x ordinate of final point
+%
+% o y: y ordinate of final point
+%
+*/
+
+static void DrawPathCurveToQuadraticBezier(DrawingWand *drawing_wand,
+ const PathMode mode,const double x1,double y1,const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((drawing_wand->path_operation != PathCurveToQuadraticBezierOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathCurveToQuadraticBezierOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand, "%c%g,%g %g,%g",
+ mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g,%g %g,%g",x1,y1,x,y);
+}
+
+WandExport void DrawPathCurveToQuadraticBezierAbsolute(
+ DrawingWand *drawing_wand,const double x1,const double y1,const double x,
+ const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathCurveToQuadraticBezier(drawing_wand,AbsolutePathMode,x1,y1,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
+% from the current point to (x,y) using (x1,y1) as the control point using
+% relative coordinates. At the end of the command, the new current point
+% becomes the final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToQuadraticBezierRelative method is:
+%
+% void DrawPathCurveToQuadraticBezierRelative(DrawingWand *drawing_wand,
+% const double x1,const double y1,const double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x1: x ordinate of the control point
+%
+% o y1: y ordinate of the control point
+%
+% o x: x ordinate of final point
+%
+% o y: y ordinate of final point
+%
+*/
+WandExport void DrawPathCurveToQuadraticBezierRelative(
+ DrawingWand *drawing_wand,const double x1,const double y1,const double x,
+ const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathCurveToQuadraticBezier(drawing_wand,RelativePathMode,x1,y1,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
+% Bezier curve (using absolute coordinates) from the current point to
+% (x,y). The control point is assumed to be the reflection of the
+% control point on the previous command relative to the current
+% point. (If there is no previous command or if the previous command was
+% not a DrawPathCurveToQuadraticBezierAbsolute,
+% DrawPathCurveToQuadraticBezierRelative,
+% DrawPathCurveToQuadraticBezierSmoothAbsolute or
+% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
+% is coincident with the current point.). At the end of the command, the
+% new current point becomes the final (x,y) coordinate pair used in the
+% polybezier.
+%
+% The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
+%
+% void DrawPathCurveToQuadraticBezierSmoothAbsolute(
+% DrawingWand *drawing_wand,const double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: x ordinate of final point
+%
+% o y: y ordinate of final point
+%
+*/
+
+static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *drawing_wand,
+ const PathMode mode,const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((drawing_wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand, "%c%g,%g",
+ mode == AbsolutePathMode ? 'T' : 't',x,y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g,%g",x,y);
+}
+
+WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(
+ DrawingWand *drawing_wand,const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathCurveToQuadraticBezierSmooth(drawing_wand,AbsolutePathMode,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToQuadraticBezierSmoothRelative() draws a quadratic
+% Bezier curve (using relative coordinates) from the current point to
+% (x,y). The control point is assumed to be the reflection of the
+% control point on the previous command relative to the current
+% point. (If there is no previous command or if the previous command was
+% not a DrawPathCurveToQuadraticBezierAbsolute,
+% DrawPathCurveToQuadraticBezierRelative,
+% DrawPathCurveToQuadraticBezierSmoothAbsolute or
+% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
+% is coincident with the current point.). At the end of the command, the
+% new current point becomes the final (x,y) coordinate pair used in the
+% polybezier.
+%
+% The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
+%
+% void DrawPathCurveToQuadraticBezierSmoothRelative(
+% DrawingWand *drawing_wand,const double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: x ordinate of final point
+%
+% o y: y ordinate of final point
+%
+%
+*/
+WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(
+ DrawingWand *drawing_wand,const double x,const double y)
+{
+ DrawPathCurveToQuadraticBezierSmooth(drawing_wand,RelativePathMode,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o S m o o t h A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
+% current point to (x,y) using absolute coordinates. The first control
+% point is assumed to be the reflection of the second control point on
+% the previous command relative to the current point. (If there is no
+% previous command or if the previous command was not an
+% DrawPathCurveToAbsolute, DrawPathCurveToRelative,
+% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
+% the first control point is coincident with the current point.) (x2,y2)
+% is the second control point (i.e., the control point at the end of the
+% curve). At the end of the command, the new current point becomes the
+% final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToSmoothAbsolute method is:
+%
+% void DrawPathCurveToSmoothAbsolute(DrawingWand *drawing_wand,
+% const double x2const double y2,const double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x2: x ordinate of second control point
+%
+% o y2: y ordinate of second control point
+%
+% o x: x ordinate of termination point
+%
+% o y: y ordinate of termination point
+%
+%
+*/
+static void DrawPathCurveToSmooth(DrawingWand *drawing_wand,const PathMode mode,
+ const double x2,const double y2,const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((drawing_wand->path_operation != PathCurveToSmoothOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathCurveToSmoothOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand,"%c%g,%g %g,%g",
+ mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g,%g %g,%g",x2,y2,x,y);
+}
+
+WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *drawing_wand,
+ const double x2,const double y2,const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathCurveToSmooth(drawing_wand,AbsolutePathMode,x2,y2,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h C u r v e T o S m o o t h R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the
+% current point to (x,y) using relative coordinates. The first control
+% point is assumed to be the reflection of the second control point on
+% the previous command relative to the current point. (If there is no
+% previous command or if the previous command was not an
+% DrawPathCurveToAbsolute, DrawPathCurveToRelative,
+% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
+% the first control point is coincident with the current point.) (x2,y2)
+% is the second control point (i.e., the control point at the end of the
+% curve). At the end of the command, the new current point becomes the
+% final (x,y) coordinate pair used in the polybezier.
+%
+% The format of the DrawPathCurveToSmoothRelative method is:
+%
+% void DrawPathCurveToSmoothRelative(DrawingWand *drawing_wand,
+% const double x2,const double y2,const double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x2: x ordinate of second control point
+%
+% o y2: y ordinate of second control point
+%
+% o x: x ordinate of termination point
+%
+% o y: y ordinate of termination point
+%
+%
+*/
+WandExport void DrawPathCurveToSmoothRelative(DrawingWand *drawing_wand,
+ const double x2,const double y2,const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathCurveToSmooth(drawing_wand,RelativePathMode,x2,y2,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h E l l i p t i c A r c A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathEllipticArcAbsolute() draws an elliptical arc from the current
+% point to (x, y) using absolute coordinates. The size and orientation
+% of the ellipse are defined by two radii (rx, ry) and an
+% xAxisRotation, which indicates how the ellipse as a whole is rotated
+% relative to the current coordinate system. The center (cx, cy) of the
+% ellipse is calculated automatically to satisfy the constraints imposed
+% by the other parameters. largeArcFlag and sweepFlag contribute to the
+% automatic calculations and help determine how the arc is drawn. If
+% largeArcFlag is true then draw the larger of the available arcs. If
+% sweepFlag is true, then draw the arc matching a clock-wise rotation.
+%
+% The format of the DrawPathEllipticArcAbsolute method is:
+%
+% void DrawPathEllipticArcAbsolute(DrawingWand *drawing_wand,
+% const double rx,const double ry,const double x_axis_rotation,
+% unsigned int large_arc_flag,unsigned int sweep_flag,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o rx: x radius
+%
+% o ry: y radius
+%
+% o x_axis_rotation: indicates how the ellipse as a whole is rotated
+% relative to the current coordinate system
+%
+% o large_arc_flag: If non-zero (true) then draw the larger of the
+% available arcs
+%
+% o sweep_flag: If non-zero (true) then draw the arc matching a
+% clock-wise rotation
+%
+%
+*/
+
+static void DrawPathEllipticArc(DrawingWand *drawing_wand, const PathMode mode,
+ const double rx,const double ry,const double x_axis_rotation,
+ unsigned int large_arc_flag,unsigned int sweep_flag,const double x,
+ const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((drawing_wand->path_operation != PathEllipticArcOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathEllipticArcOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand, "%c%g,%g %g %u %u %g,%g",
+ mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
+ large_arc_flag,sweep_flag,x,y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g,%g %g %u %u %g,%g",rx,ry,
+ x_axis_rotation,large_arc_flag,sweep_flag,x,y);
+}
+
+WandExport void DrawPathEllipticArcAbsolute(DrawingWand *drawing_wand,
+ const double rx,const double ry,const double x_axis_rotation,
+ unsigned int large_arc_flag,unsigned int sweep_flag,const double x,
+ const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathEllipticArc(drawing_wand,AbsolutePathMode,rx,ry,x_axis_rotation,
+ large_arc_flag,sweep_flag,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h E l l i p t i c A r c R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathEllipticArcRelative() draws an elliptical arc from the current
+% point to (x, y) using relative coordinates. The size and orientation
+% of the ellipse are defined by two radii (rx, ry) and an
+% xAxisRotation, which indicates how the ellipse as a whole is rotated
+% relative to the current coordinate system. The center (cx, cy) of the
+% ellipse is calculated automatically to satisfy the constraints imposed
+% by the other parameters. largeArcFlag and sweepFlag contribute to the
+% automatic calculations and help determine how the arc is drawn. If
+% largeArcFlag is true then draw the larger of the available arcs. If
+% sweepFlag is true, then draw the arc matching a clock-wise rotation.
+%
+% The format of the DrawPathEllipticArcRelative method is:
+%
+% void DrawPathEllipticArcRelative(DrawingWand *drawing_wand,
+% const double rx,const double ry,const double x_axis_rotation,
+% unsigned int large_arc_flag,unsigned int sweep_flag,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o rx: x radius
+%
+% o ry: y radius
+%
+% o x_axis_rotation: indicates how the ellipse as a whole is rotated
+% relative to the current coordinate system
+%
+% o large_arc_flag: If non-zero (true) then draw the larger of the
+% available arcs
+%
+% o sweep_flag: If non-zero (true) then draw the arc matching a
+% clock-wise rotation
+%
+*/
+WandExport void DrawPathEllipticArcRelative(DrawingWand *drawing_wand,
+ const double rx,const double ry,const double x_axis_rotation,
+ unsigned int large_arc_flag,unsigned int sweep_flag,const double x,
+ const double y)
+{
+ DrawPathEllipticArc(drawing_wand,RelativePathMode,rx,ry,x_axis_rotation,
+ large_arc_flag,sweep_flag,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h F i n i s h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathFinish() terminates the current path.
+%
+% The format of the DrawPathFinish method is:
+%
+% void DrawPathFinish(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPathFinish(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"'\n");
+ drawing_wand->path_operation=PathDefaultOperation;
+ drawing_wand->path_mode=DefaultPathMode;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToAbsolute() draws a line path from the current point to the
+% given coordinate using absolute coordinates. The coordinate then becomes
+% the new current point.
+%
+% The format of the DrawPathLineToAbsolute method is:
+%
+% void DrawPathLineToAbsolute(DrawingWand *drawing_wand,const double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: target x ordinate
+%
+% o y: target y ordinate
+%
+*/
+static void DrawPathLineTo(DrawingWand *drawing_wand,const PathMode mode,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+
+ if ((drawing_wand->path_operation != PathLineToOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathLineToOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand,"%c%g,%g",
+ mode == AbsolutePathMode ? 'L' : 'l',x,y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g,%g",x,y);
+}
+
+WandExport void DrawPathLineToAbsolute(DrawingWand *drawing_wand,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathLineTo(drawing_wand,AbsolutePathMode,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToRelative() draws a line path from the current point to the
+% given coordinate using relative coordinates. The coordinate then becomes
+% the new current point.
+%
+% The format of the DrawPathLineToRelative method is:
+%
+% void DrawPathLineToRelative(DrawingWand *drawing_wand,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: target x ordinate
+%
+% o y: target y ordinate
+%
+*/
+WandExport void DrawPathLineToRelative(DrawingWand *drawing_wand,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathLineTo(drawing_wand,RelativePathMode,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o H o r i z o n t a l A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
+% current point to the target point using absolute coordinates. The target
+% point then becomes the new current point.
+%
+% The format of the DrawPathLineToHorizontalAbsolute method is:
+%
+% void DrawPathLineToHorizontalAbsolute(DrawingWand *drawing_wand,
+% const PathMode mode,const double x)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: target x ordinate
+%
+*/
+
+static void DrawPathLineToHorizontal(DrawingWand *drawing_wand,
+ const PathMode mode,const double x)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((drawing_wand->path_operation != PathLineToHorizontalOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathLineToHorizontalOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand,"%c%g",
+ mode == AbsolutePathMode ? 'H' : 'h',x);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g",x);
+}
+
+WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *drawing_wand,
+ const double x)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathLineToHorizontal(drawing_wand,AbsolutePathMode,x);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o H o r i z o n t a l R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToHorizontalRelative() draws a horizontal line path from the
+% current point to the target point using relative coordinates. The target
+% point then becomes the new current point.
+%
+% The format of the DrawPathLineToHorizontalRelative method is:
+%
+% void DrawPathLineToHorizontalRelative(DrawingWand *drawing_wand,
+% const double x)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: target x ordinate
+%
+*/
+WandExport void DrawPathLineToHorizontalRelative(DrawingWand *drawing_wand,
+ const double x)
+{
+ DrawPathLineToHorizontal(drawing_wand,RelativePathMode,x);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o V e r t i c a l A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToVerticalAbsolute() draws a vertical line path from the
+% current point to the target point using absolute coordinates. The target
+% point then becomes the new current point.
+%
+% The format of the DrawPathLineToVerticalAbsolute method is:
+%
+% void DrawPathLineToVerticalAbsolute(DrawingWand *drawing_wand,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o y: target y ordinate
+%
+*/
+
+static void DrawPathLineToVertical(DrawingWand *drawing_wand,
+ const PathMode mode,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((drawing_wand->path_operation != PathLineToVerticalOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathLineToVerticalOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand,"%c%g",
+ mode == AbsolutePathMode ? 'V' : 'v',y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g",y);
+}
+
+WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *drawing_wand,
+ const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathLineToVertical(drawing_wand,AbsolutePathMode,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h L i n e T o V e r t i c a l R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathLineToVerticalRelative() draws a vertical line path from the
+% current point to the target point using relative coordinates. The target
+% point then becomes the new current point.
+%
+% The format of the DrawPathLineToVerticalRelative method is:
+%
+% void DrawPathLineToVerticalRelative(DrawingWand *drawing_wand,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o y: target y ordinate
+%
+*/
+WandExport void DrawPathLineToVerticalRelative(DrawingWand *drawing_wand,
+ const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathLineToVertical(drawing_wand,RelativePathMode,y);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h M o v e T o A b s o l u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
+% using absolute coordinates. The current point then becomes the
+% specified coordinate.
+%
+% The format of the DrawPathMoveToAbsolute method is:
+%
+% void DrawPathMoveToAbsolute(DrawingWand *drawing_wand,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: target x ordinate
+%
+% o y: target y ordinate
+%
+*/
+static void DrawPathMoveTo(DrawingWand *drawing_wand,const PathMode mode,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if ((drawing_wand->path_operation != PathMoveToOperation) ||
+ (drawing_wand->path_mode != mode))
+ {
+ drawing_wand->path_operation=PathMoveToOperation;
+ drawing_wand->path_mode=mode;
+ (void) MvgAutoWrapPrintf(drawing_wand,"%c%g,%g",
+ mode == AbsolutePathMode ? 'M' : 'm',x,y);
+ }
+ else
+ (void) MvgAutoWrapPrintf(drawing_wand," %g,%g",x,y);
+}
+
+WandExport void DrawPathMoveToAbsolute(DrawingWand *drawing_wand,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathMoveTo(drawing_wand,AbsolutePathMode,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h M o v e T o R e l a t i v e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathMoveToRelative() starts a new sub-path at the given coordinate
+% using relative coordinates. The current point then becomes the
+% specified coordinate.
+%
+% The format of the DrawPathMoveToRelative method is:
+%
+% void DrawPathMoveToRelative(DrawingWand *drawing_wand,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: target x ordinate
+%
+% o y: target y ordinate
+%
+*/
+WandExport void DrawPathMoveToRelative(DrawingWand *drawing_wand,
+ const double x,const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ DrawPathMoveTo(drawing_wand,RelativePathMode,x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P a t h S t a r t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPathStart() declares the start of a path drawing list which is terminated
+% by a matching DrawPathFinish() command. All other DrawPath commands must
+% be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
+% is because path drawing commands are subordinate commands and they do not
+% function by themselves.
+%
+% The format of the DrawPathStart method is:
+%
+% void DrawPathStart(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPathStart(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"path '");
+ drawing_wand->path_operation=PathDefaultOperation;
+ drawing_wand->path_mode=DefaultPathMode;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P e e k G r a p h i c C o n t e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPeekGraphicContext() returns the current graphic drawing_wand.
+%
+% The format of the DrawPeekGraphicContext method is:
+%
+% DrawInfo *DrawPeekGraphicContext(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport DrawInfo *DrawPeekGraphicContext(const DrawingWand *drawing_wand)
+{
+ DrawInfo
+ *draw_info;
+
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
+ (void) CloneString(&draw_info->primitive,drawing_wand->mvg);
+ return(draw_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o i n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPoint() draws a point using the current stroke color and stroke
+% thickness at the specified coordinates.
+%
+% The format of the DrawPoint method is:
+%
+% void DrawPoint(DrawingWand *drawing_wand,const double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: target x coordinate
+%
+% o y: target y coordinate
+%
+*/
+WandExport void DrawPoint(DrawingWand *drawing_wand,const double x,
+ const double y)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"point %g,%g\n",x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o l y g o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPolygon() draws a polygon using the current stroke, stroke width, and
+% fill color or texture, using the specified array of coordinates.
+%
+% The format of the DrawPolygon method is:
+%
+% void DrawPolygon(DrawingWand *drawing_wand,
+% const unsigned long number_coordinates,const PointInfo *coordinates)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o number_coordinates: number of coordinates
+%
+% o coordinates: coordinate array
+%
+*/
+WandExport void DrawPolygon(DrawingWand *drawing_wand,
+ const unsigned long number_coordinates,const PointInfo *coordinates)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ MvgAppendPointsCommand(drawing_wand,"polygon",number_coordinates,coordinates);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o l y l i n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPolyline() draws a polyline using the current stroke, stroke width, and
+% fill color or texture, using the specified array of coordinates.
+%
+% The format of the DrawPolyline method is:
+%
+% void DrawPolyline(DrawingWand *drawing_wand,
+% const unsigned long number_coordinates,const PointInfo *coordinates)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o number_coordinates: number of coordinates
+%
+% o coordinates: coordinate array
+%
+*/
+WandExport void DrawPolyline(DrawingWand *drawing_wand,
+ const unsigned long number_coordinates,const PointInfo *coordinates)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ MvgAppendPointsCommand(drawing_wand,"polyline",number_coordinates,
+ coordinates);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o p C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPopClipPath() terminates a clip path definition.
+%
+% The format of the DrawPopClipPath method is:
+%
+% void DrawPopClipPath(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPopClipPath(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->indent_depth > 0)
+ drawing_wand->indent_depth--;
+ (void) MvgPrintf(drawing_wand,"pop clip-path\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o p D e f s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPopDefs() terminates a definition list
+%
+% The format of the DrawPopDefs method is:
+%
+% void DrawPopDefs(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPopDefs(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->indent_depth > 0)
+ drawing_wand->indent_depth--;
+ (void) MvgPrintf(drawing_wand,"pop defs\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o p G r a p h i c C o n t e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPopGraphicContext() destroys the current drawing_wand returning to the
+% previously pushed drawing wand. Multiple drawing wand may exist. It is an
+% error to attempt to pop more drawing_wands than have been pushed, and it is
+% proper form to pop all drawing_wands which have been pushed.
+%
+% The format of the DrawPopGraphicContext method is:
+%
+% void DrawPopGraphicContext(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPopGraphicContext(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->index <= 0)
+ {
+ ThrowException(&drawing_wand->exception,DrawError,
+ UnbalancedGraphicContextPushPop,NULL);
+ }
+ else
+ {
+ /* Destroy clip path if not same in preceding drawing_wand */
+ DestroyDrawInfo(CurrentContext);
+ CurrentContext=(DrawInfo*)NULL;
+ drawing_wand->index--;
+ if (drawing_wand->indent_depth > 0)
+ drawing_wand->indent_depth--;
+ (void) MvgPrintf(drawing_wand,"pop graphic-context\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P o p P a t t e r n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPopPattern() terminates a pattern definition.
+%
+% The format of the DrawPopPattern method is:
+%
+% void DrawPopPattern(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPopPattern(DrawingWand *drawing_wand)
+{
+ char
+ geometry[MaxTextExtent],
+ key[MaxTextExtent];
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->pattern_id == NULL)
+ ThrowException(&drawing_wand->exception,DrawWarning,
+ NotCurrentlyPushingPatternDefinition,NULL);
+ (void) MagickFormatString(key,MaxTextExtent,"[%.1024s]",
+ drawing_wand->pattern_id);
+ (void) SetImageAttribute(drawing_wand->image,key,
+ drawing_wand->mvg+drawing_wand->pattern_offset);
+ (void) MagickFormatString(geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
+ drawing_wand->pattern_bounds.width,drawing_wand->pattern_bounds.height,
+ drawing_wand->pattern_bounds.x,drawing_wand->pattern_bounds.y);
+ (void) SetImageAttribute(drawing_wand->image,key,geometry);
+ MagickFreeMemory(drawing_wand->pattern_id);
+ drawing_wand->pattern_id=NULL;
+ drawing_wand->pattern_offset=0;
+ drawing_wand->pattern_bounds.x=0;
+ drawing_wand->pattern_bounds.y=0;
+ drawing_wand->pattern_bounds.width=0;
+ drawing_wand->pattern_bounds.height=0;
+ drawing_wand->filter_off=MagickFalse;
+ if (drawing_wand->indent_depth > 0)
+ drawing_wand->indent_depth--;
+ (void) MvgPrintf(drawing_wand,"pop pattern\n");
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P u s h C l i p P a t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPushClipPath() starts a clip path definition which is comprized of
+% any number of drawing commands and terminated by a DrawPopClipPath()
+% command.
+%
+% The format of the DrawPushClipPath method is:
+%
+% void DrawPushClipPath(DrawingWand *drawing_wand,const char *clip_path_id)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o clip_path_id: string identifier to associate with the clip path for
+% later use.
+%
+*/
+WandExport void DrawPushClipPath(DrawingWand *drawing_wand,
+ const char *clip_path_id)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(clip_path_id != (const char *) NULL);
+ (void) MvgPrintf(drawing_wand,"push clip-path %s\n",clip_path_id);
+ drawing_wand->indent_depth++;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P u s h D e f s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
+% command create named elements (e.g. clip-paths, textures, etc.) which
+% may safely be processed earlier for the sake of efficiency.
+%
+% The format of the DrawPushDefs method is:
+%
+% void DrawPushDefs(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPushDefs(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"push defs\n");
+ drawing_wand->indent_depth++;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P u s h G r a p h i c C o n t e x t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPushGraphicContext() clones the current drawing wand to create a
+% new drawing wand. The original drawing drawing_wand(s) may be returned to
+% by invoking DrawPopGraphicContext(). The drawing wands are stored on a
+% drawing wand stack. For every Pop there must have already been an
+% equivalent Push.
+%
+% The format of the DrawPushGraphicContext method is:
+%
+% void DrawPushGraphicContext(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport void DrawPushGraphicContext(DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ drawing_wand->index++;
+ MagickReallocMemory(DrawInfo **,drawing_wand->graphic_context,
+ (drawing_wand->index+1)*sizeof(DrawInfo *));
+ if (drawing_wand->graphic_context == (DrawInfo **) NULL)
+ {
+ drawing_wand->index--;
+ ThrowException3(&drawing_wand->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ return;
+ }
+ CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
+ drawing_wand->graphic_context[drawing_wand->index-1]);
+ (void) MvgPrintf(drawing_wand,"push graphic-context\n");
+ drawing_wand->indent_depth++;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w P u s h P a t t e r n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawPushPattern() indicates that subsequent commands up to a
+% DrawPopPattern() command comprise the definition of a named pattern.
+% The pattern space is assigned top left corner coordinates, a width
+% and height, and becomes its own drawing space. Anything which can
+% be drawn may be used in a pattern definition.
+% Named patterns may be used as stroke or brush definitions.
+%
+% The format of the DrawPushPattern method is:
+%
+% void DrawPushPattern(DrawingWand *drawing_wand,const char *pattern_id,
+% const double x,const double y,const double width,const double height)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o pattern_id: pattern identification for later reference
+%
+% o x: x ordinate of top left corner
+%
+% o y: y ordinate of top left corner
+%
+% o width: width of pattern space
+%
+% o height: height of pattern space
+%
+*/
+WandExport void DrawPushPattern(DrawingWand *drawing_wand,
+ const char *pattern_id,const double x,const double y,const double width,
+ const double height)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(pattern_id != (const char *) NULL);
+ if (drawing_wand->pattern_id != NULL)
+ ThrowException(&drawing_wand->exception,DrawError,
+ AlreadyPushingPatternDefinition,drawing_wand->pattern_id);
+ drawing_wand->filter_off=MagickTrue;
+ (void) MvgPrintf(drawing_wand,"push pattern %s %g,%g %g,%g\n",pattern_id,
+ x,y,width,height);
+ drawing_wand->indent_depth++;
+ drawing_wand->pattern_id=AcquireString(pattern_id);
+ drawing_wand->pattern_bounds.x=(long) ceil(x-0.5);
+ drawing_wand->pattern_bounds.y=(long) ceil(y-0.5);
+ drawing_wand->pattern_bounds.width=(unsigned long) (width+0.5);
+ drawing_wand->pattern_bounds.height=(unsigned long) (height+0.5);
+ drawing_wand->pattern_offset=drawing_wand->mvg_length;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w R e c t a n g l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawRectangle() draws a rectangle given two coordinates and using
+% the current stroke, stroke width, and fill settings.
+%
+% The format of the DrawRectangle method is:
+%
+% void DrawRectangle(DrawingWand *drawing_wand,const double x1,
+% const double y1,const double x2,const double y2)
+%
+% A description of each parameter follows:
+%
+% o x1: x ordinate of first coordinate
+%
+% o y1: y ordinate of first coordinate
+%
+% o x2: x ordinate of second coordinate
+%
+% o y2: y ordinate of second coordinate
+%
+*/
+WandExport void DrawRectangle(DrawingWand *drawing_wand,const double x1,
+ const double y1,const double x2,const double y2)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"rectangle %g,%g %g,%g\n",x1,y1,x2,y2);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w R e n d e r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawRender() renders all preceding drawing commands onto the image.
+% This function is deprecated. Use MagickDrawImage() instead.
+%
+% The format of the DrawRender method is:
+%
+% unsigned int DrawRender(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport unsigned int DrawRender(const DrawingWand *drawing_wand)
+{
+ MagickPassFail
+ status;
+
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ CurrentContext->primitive=drawing_wand->mvg;
+ (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",
+ drawing_wand->mvg);
+ status=DrawImage(drawing_wand->image, CurrentContext);
+ CurrentContext->primitive=(char *) NULL;
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w R o t a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawRotate() applies the specified rotation to the current coordinate space.
+%
+% The format of the DrawRotate method is:
+%
+% void DrawRotate(DrawingWand *drawing_wand,const double degrees)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o degrees: degrees of rotation
+%
+*/
+WandExport void DrawRotate(DrawingWand *drawing_wand,const double degrees)
+{
+ AffineMatrix
+ affine;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ IdentityAffine(&affine);
+ affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
+ AdjustAffine(drawing_wand,&affine);
+ (void) MvgPrintf(drawing_wand,"rotate %g\n",degrees);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w R o u n d R e c t a n g l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawRoundRectangle() draws a rounted rectangle given two coordinates,
+% x & y corner radiuses and using the current stroke, stroke width,
+% and fill settings.
+%
+% The format of the DrawRoundRectangle method is:
+%
+% void DrawRoundRectangle(DrawingWand *drawing_wand,double x1,double y1,
+% double x2,double y2,double rx,double ry)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x1: x ordinate of first coordinate
+%
+% o y1: y ordinate of first coordinate
+%
+% o x2: x ordinate of second coordinate
+%
+% o y2: y ordinate of second coordinate
+%
+% o rx: radius of corner in horizontal direction
+%
+% o ry: radius of corner in vertical direction
+%
+*/
+WandExport void DrawRoundRectangle(DrawingWand *drawing_wand,double x1,
+ double y1,double x2,double y2,double rx,double ry)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"roundrectangle %g,%g %g,%g %g,%g\n",
+ x1,y1,x2,y2,rx,ry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S c a l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawScale() adjusts the scaling factor to apply in the horizontal and
+% vertical directions to the current coordinate space.
+%
+% The format of the DrawScale method is:
+%
+% void DrawScale(DrawingWand *drawing_wand,const double x,const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: horizontal scale factor
+%
+% o y: vertical scale factor
+%
+*/
+WandExport void DrawScale(DrawingWand *drawing_wand,const double x,
+ const double y)
+{
+ AffineMatrix
+ affine;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ IdentityAffine(&affine);
+ affine.sx=x;
+ affine.sy=y;
+ AdjustAffine( drawing_wand, &affine );
+ (void) MvgPrintf(drawing_wand,"scale %g,%g\n",x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S k e w X %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSkewX() skews the current coordinate system in the horizontal
+% direction.
+%
+% The format of the DrawSkewX method is:
+%
+% void DrawSkewX(DrawingWand *drawing_wand,const double degrees)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o degrees: number of degrees to skew the coordinates
+%
+*/
+WandExport void DrawSkewX(DrawingWand *drawing_wand,const double degrees)
+{
+ AffineMatrix
+ affine;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ IdentityAffine(&affine);
+ affine.ry=tan(DegreesToRadians(fmod(degrees,360.0)));
+ AdjustAffine(drawing_wand,&affine);
+ (void) MvgPrintf(drawing_wand,"skewX %g\n",degrees);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S k e w Y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSkewY() skews the current coordinate system in the vertical
+% direction.
+%
+% The format of the DrawSkewY method is:
+%
+% void DrawSkewY(DrawingWand *drawing_wand,const double degrees)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o degrees: number of degrees to skew the coordinates
+%
+*/
+WandExport void DrawSkewY(DrawingWand *drawing_wand,const double degrees)
+{
+ AffineMatrix
+ affine;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ IdentityAffine(&affine);
+ affine.rx=tan(DegreesToRadians(fmod(degrees,360.0)));
+ DrawAffine(drawing_wand,&affine);
+ (void) MvgPrintf(drawing_wand,"skewY %g\n",degrees);
+}
+#if 0
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t o p C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStopColor() sets the stop color and offset for gradients
+%
+% The format of the DrawSetStopColor method is:
+%
+% void DrawSetStopColor(DrawingWand *drawing_wand,
+% const PixelPacket *stop_color,const double offset)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o stop_color:
+%
+% o offset:
+%
+*/
+/* This is gradient stuff so it shouldn't be supported yet */
+WandExport void DrawSetStopColor(DrawingWand *drawing_wand,
+ const PixelPacket * stop_color,const double offset)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(stop_color != (const PixelPacket *) NULL);
+ (void) MvgPrintf(drawing_wand,"stop-color ");
+ MvgAppendColor(drawing_wand,stop_color);
+ (void) MvgPrintf(drawing_wand,"\n");
+}
+#endif
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeColor() returns the color used for stroking object outlines.
+%
+% The format of the DrawGetStrokeColor method is:
+%
+% void DrawGetStrokeColor(const DrawingWand *drawing_wand,
+$ PixelWand *stroke_color)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o stroke_color: Return the stroke color.
+%
+*/
+WandExport void DrawGetStrokeColor(const DrawingWand *drawing_wand,
+ PixelWand *stroke_color)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ PixelSetQuantumColor(stroke_color,&CurrentContext->stroke);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeColor() sets the color used for stroking object outlines.
+%
+% The format of the DrawSetStrokeColor method is:
+%
+% void DrawSetStrokeColor(DrawingWand *drawing_wand,
+% const PixelWand *stroke_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o stroke_wand: stroke wand.
+%
+*/
+WandExport void DrawSetStrokeColor(DrawingWand *drawing_wand,
+ const PixelWand *stroke_wand)
+{
+ PixelPacket
+ *current_stroke,
+ new_stroke,
+ stroke_color;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(stroke_wand != (const PixelWand *) NULL);
+ PixelGetQuantumColor(stroke_wand,&stroke_color);
+ new_stroke=stroke_color;
+ if (new_stroke.opacity != TransparentOpacity)
+ new_stroke.opacity=CurrentContext->opacity;
+ current_stroke=&CurrentContext->stroke;
+ if (drawing_wand->filter_off ||
+ !WandColorMatch(current_stroke,&new_stroke))
+ {
+ CurrentContext->stroke=new_stroke;
+ (void) MvgPrintf(drawing_wand,"stroke '");
+ MvgAppendColor(drawing_wand,&stroke_color);
+ (void) MvgPrintf(drawing_wand,"'\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e P a t t e r n U R L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
+%
+% The format of the DrawSetStrokePatternURL method is:
+%
+% void DrawSetStrokePatternURL(DrawingWand *drawing_wand,
+% const char *stroke_url)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
+%
+*/
+WandExport void DrawSetStrokePatternURL(DrawingWand *drawing_wand,
+ const char *stroke_url)
+{
+ char
+ pattern[MaxTextExtent];
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(stroke_url != NULL);
+ if (stroke_url[0] != '#')
+ ThrowException(&drawing_wand->exception,DrawWarning,
+ NotARelativeURL,stroke_url);
+ (void) MagickFormatString(pattern,MaxTextExtent,"[%.1024s]",stroke_url+1);
+ if (GetImageAttribute(drawing_wand->image,pattern) == (ImageAttribute *) NULL)
+ {
+ ThrowException(&drawing_wand->exception,DrawWarning,
+ URLNotFound,stroke_url);
+ }
+ else
+ {
+ char
+ pattern_spec[MaxTextExtent];
+
+ (void) MagickFormatString(pattern_spec,MaxTextExtent,"url(%.1024s)",
+ stroke_url);
+ if (CurrentContext->stroke.opacity != TransparentOpacity)
+ CurrentContext->stroke.opacity=CurrentContext->opacity;
+ (void) MvgPrintf(drawing_wand,"stroke %s\n",pattern_spec);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e A n t i a l i a s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeAntialias() returns the current stroke antialias setting.
+% Stroked outlines are antialiased by default. When antialiasing is disabled
+% stroked pixels are thresholded to determine if the stroke color or
+% underlying canvas color should be used.
+%
+% The format of the DrawGetStrokeAntialias method is:
+%
+% unsigned int DrawGetStrokeAntialias(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport unsigned int DrawGetStrokeAntialias(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->stroke_antialias);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e A n t i a l i a s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
+% Stroked outlines are antialiased by default. When antialiasing is disabled
+% stroked pixels are thresholded to determine if the stroke color or
+% underlying canvas color should be used.
+%
+% The format of the DrawSetStrokeAntialias method is:
+%
+% void DrawSetStrokeAntialias(DrawingWand *drawing_wand,
+% const unsigned int stroke_antialias)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o stroke_antialias: set to false (zero) to disable antialiasing
+%
+*/
+WandExport void DrawSetStrokeAntialias(DrawingWand *drawing_wand,
+ const unsigned int stroke_antialias)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off ||
+ (CurrentContext->stroke_antialias != stroke_antialias))
+ {
+ CurrentContext->stroke_antialias=stroke_antialias;
+ (void) MvgPrintf(drawing_wand,"stroke-antialias %i\n",stroke_antialias ? 1 : 0);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e D a s h A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeDashArray() returns an array representing the pattern of
+% dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
+% array must be freed once it is no longer required by the user.
+%
+% The format of the DrawGetStrokeDashArray method is:
+%
+% double *DrawGetStrokeDashArray(const DrawingWand *drawing_wand,
+% unsigned long *number_elements)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o number_elements: address to place number of elements in dash array
+%
+% */
+WandExport double *DrawGetStrokeDashArray(const DrawingWand *drawing_wand,
+ unsigned long *number_elements)
+{
+ register const double
+ *p;
+
+ register double
+ *q;
+
+ double
+ *dash_array;
+
+ unsigned int
+ i,
+ n=0;
+
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(number_elements != (unsigned long *)NULL);
+ p=CurrentContext->dash_pattern;
+ if ( p != (const double *) NULL )
+ while (*p++ != 0.0)
+ n++;
+ *number_elements=n;
+ dash_array=(double *)NULL;
+ if (n != 0)
+ {
+ dash_array=MagickAllocateArray(double *, n+1, sizeof(double));
+ p=CurrentContext->dash_pattern;
+ q=dash_array;
+ i=n;
+ while (i--)
+ *q++=(*p++);
+ *q=0.0;
+ }
+ return(dash_array);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e D a s h A r r a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
+% stroke paths. The stroke dash array represents an array of numbers that
+% specify the lengths of alternating dashes and gaps in pixels. If an odd
+% number of values is provided, then the list of values is repeated to yield
+% an even number of values. To remove an existing dash array, pass a zero
+% number_elements argument and null dash_array.
+% A typical stroke dash array might contain the members 5 3 2.
+%
+% The format of the DrawSetStrokeDashArray method is:
+%
+% void DrawSetStrokeDashArray(DrawingWand *drawing_wand,
+% const unsigned long number_elements,const double *dash_array)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o number_elements: number of elements in dash array
+%
+% o dash_array: dash array values
+%
+% */
+WandExport void DrawSetStrokeDashArray(DrawingWand *drawing_wand,
+ const unsigned long number_elements,const double *dash_array)
+{
+ register const double
+ *p;
+
+ register double
+ *q;
+
+ unsigned long
+ i,
+ n_new = number_elements,
+ n_old = 0;
+
+ MagickBool
+ updated = MagickFalse;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (dash_array == (const double *) NULL)
+ n_new = 0;
+ q=CurrentContext->dash_pattern;
+ if (q != (const double *) NULL)
+ while (*q++ != 0.0)
+ n_old++;
+
+ if ((n_old == 0) && (n_new == 0))
+ {
+ updated=MagickFalse;
+ }
+ else if ( n_old != n_new )
+ {
+ updated=MagickTrue;
+ }
+ else if ((CurrentContext->dash_pattern != (double *) NULL) &&
+ (dash_array != (double *) NULL))
+ {
+ p=dash_array;
+ q=CurrentContext->dash_pattern;
+ i=n_new;
+ while ( i-- )
+ {
+ if (AbsoluteValue(*p - *q) > MagickEpsilon)
+ {
+ updated=MagickTrue;
+ break;
+ }
+ p++;
+ q++;
+ }
+ }
+ if (drawing_wand->filter_off || updated)
+ {
+ if (CurrentContext->dash_pattern != (double *) NULL)
+ MagickFreeMemory(CurrentContext->dash_pattern);
+ if (n_new != 0)
+ {
+ CurrentContext->dash_pattern=MagickAllocateArray(double *,
+ (n_new+1),
+ sizeof(double));
+ if (!CurrentContext->dash_pattern)
+ {
+ ThrowException3(&drawing_wand->exception,
+ ResourceLimitError,MemoryAllocationFailed,UnableToDrawOnImage);
+ }
+ else
+ {
+ for (i=0; i < n_new; i++)
+ CurrentContext->dash_pattern[i]=dash_array[i];
+ CurrentContext->dash_pattern[n_new]=0.0;
+ }
+ }
+ (void) MvgPrintf(drawing_wand,"stroke-dasharray ");
+ if ( n_new == 0 )
+ (void) MvgPrintf(drawing_wand, "none");
+ else
+ {
+ for (i=0; i < n_new; i++)
+ {
+ if (i != 0)
+ (void) MvgPrintf(drawing_wand, ",");
+ (void) MvgPrintf(drawing_wand, "%g", dash_array[i]);
+ }
+ }
+ (void) MvgPrintf(drawing_wand,"\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e D a s h O f f s e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeDashOffset() returns the offset into the dash pattern to
+% start the dash.
+%
+% The format of the DrawGetStrokeDashOffset method is:
+%
+% double DrawGetStrokeDashOffset(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport double DrawGetStrokeDashOffset(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->dash_offset);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e D a s h O f f s e t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
+% start the dash.
+%
+% The format of the DrawSetStrokeDashOffset method is:
+%
+% void DrawSetStrokeDashOffset(DrawingWand *drawing_wand,
+% const double dash_offset)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o dash_offset: dash offset
+%
+*/
+WandExport void DrawSetStrokeDashOffset(DrawingWand *drawing_wand,
+ const double dash_offset)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+
+ if (drawing_wand->filter_off ||
+ (AbsoluteValue(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
+ {
+ CurrentContext->dash_offset=dash_offset;
+ (void) MvgPrintf(drawing_wand,"stroke-dashoffset %g\n",dash_offset);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e L i n e C a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeLineCap() returns the shape to be used at the end of
+% open subpaths when they are stroked. Values of LineCap are
+% UndefinedCap, ButtCap, RoundCap, and SquareCap.
+%
+% The format of the DrawGetStrokeLineCap method is:
+%
+% LineCap DrawGetStrokeLineCap(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% */
+WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->linecap);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e L i n e C a p %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeLineCap() specifies the shape to be used at the end of
+% open subpaths when they are stroked. Values of LineCap are
+% UndefinedCap, ButtCap, RoundCap, and SquareCap.
+%
+% The format of the DrawSetStrokeLineCap method is:
+%
+% void DrawSetStrokeLineCap(DrawingWand *drawing_wand,
+% const LineCap linecap)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o linecap: linecap style
+%
+% */
+WandExport void DrawSetStrokeLineCap(DrawingWand *drawing_wand,
+ const LineCap linecap)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+
+ if (drawing_wand->filter_off || (CurrentContext->linecap != linecap))
+ {
+ const char
+ *p=NULL;
+
+ CurrentContext->linecap=linecap;
+ switch (linecap)
+ {
+ case ButtCap:
+ p="butt";
+ break;
+ case RoundCap:
+ p="round";
+ break;
+ case SquareCap:
+ p="square";
+ break;
+ default:
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand,"stroke-linecap %s\n",p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e L i n e J o i n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeLineJoin() returns the shape to be used at the
+% corners of paths (or other vector shapes) when they are
+% stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
+% and BevelJoin.
+%
+% The format of the DrawGetStrokeLineJoin method is:
+%
+% LineJoin DrawGetStrokeLineJoin(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% */
+WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->linejoin);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e L i n e J o i n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeLineJoin() specifies the shape to be used at the
+% corners of paths (or other vector shapes) when they are
+% stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
+% and BevelJoin.
+%
+% The format of the DrawSetStrokeLineJoin method is:
+%
+% void DrawSetStrokeLineJoin(DrawingWand *drawing_wand,
+% const LineJoin linejoin)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o linejoin: line join style
+%
+%
+*/
+WandExport void DrawSetStrokeLineJoin(DrawingWand *drawing_wand,
+ const LineJoin linejoin)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->linejoin != linejoin))
+ {
+ const char
+ *p=NULL;
+
+ CurrentContext->linejoin=linejoin;
+
+ switch (linejoin)
+ {
+ case MiterJoin:
+ p="miter";
+ break;
+ case RoundJoin:
+ p="round";
+ break;
+ case BevelJoin:
+ p="bevel";
+ break;
+ default:
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand,"stroke-linejoin %s\n",p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e M i t e r L i m i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeMiterLimit() returns the miter limit. When two line
+% segments meet at a sharp angle and miter joins have been specified for
+% 'lineJoin', it is possible for the miter to extend far beyond the
+% thickness of the line stroking the path. The miterLimit' imposes a
+% limit on the ratio of the miter length to the 'lineWidth'.
+%
+% The format of the DrawGetStrokeMiterLimit method is:
+%
+% unsigned long DrawGetStrokeMiterLimit(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% */
+WandExport unsigned long DrawGetStrokeMiterLimit(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return CurrentContext->miterlimit;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e M i t e r L i m i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeMiterLimit() specifies the miter limit. When two line
+% segments meet at a sharp angle and miter joins have been specified for
+% 'lineJoin', it is possible for the miter to extend far beyond the
+% thickness of the line stroking the path. The miterLimit' imposes a
+% limit on the ratio of the miter length to the 'lineWidth'.
+%
+% The format of the DrawSetStrokeMiterLimit method is:
+%
+% void DrawSetStrokeMiterLimit(DrawingWand *drawing_wand,
+% const unsigned long miterlimit)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o miterlimit: miter limit
+%
+% */
+WandExport void DrawSetStrokeMiterLimit(DrawingWand *drawing_wand,
+ const unsigned long miterlimit)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (CurrentContext->miterlimit != miterlimit)
+ {
+ CurrentContext->miterlimit=miterlimit;
+ (void) MvgPrintf(drawing_wand,"stroke-miterlimit %lu\n",miterlimit);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
+%
+% The format of the DrawGetStrokeOpacity method is:
+%
+% double DrawGetStrokeOpacity(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+*/
+WandExport double DrawGetStrokeOpacity(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(1.0-(((double)CurrentContext->stroke.opacity)/MaxRGB));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
+%
+% The format of the DrawSetStrokeOpacity method is:
+%
+% void DrawSetStrokeOpacity(DrawingWand *drawing_wand,
+% const double stroke_opacity)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o stroke_opacity: stroke opacity. The value 1.0 is opaque.
+%
+*/
+WandExport void DrawSetStrokeOpacity(DrawingWand *drawing_wand,
+ const double stroke_opacity)
+{
+ double
+ opacity;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ opacity=(Quantum) ((double) MaxRGB*
+ (1.0-(stroke_opacity <= 1.0 ? stroke_opacity : 1.0 ))+0.5);
+ if (drawing_wand->filter_off || (CurrentContext->stroke.opacity != opacity))
+ {
+ CurrentContext->stroke.opacity=(Quantum) (opacity+0.5);
+ (void) MvgPrintf(drawing_wand,"stroke-opacity %g\n",stroke_opacity);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t S t r o k e W i d t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetStrokeWidth() returns the width of the stroke used to draw object
+% outlines.
+%
+% The format of the DrawGetStrokeWidth method is:
+%
+% double DrawGetStrokeWidth(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport double DrawGetStrokeWidth(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->stroke_width);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t S t r o k e W i d t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetStrokeWidth() sets the width of the stroke used to draw object
+% outlines.
+%
+% The format of the DrawSetStrokeWidth method is:
+%
+% void DrawSetStrokeWidth(DrawingWand *drawing_wand,
+% const double stroke_width)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o stroke_width: stroke width
+%
+*/
+WandExport void DrawSetStrokeWidth(DrawingWand *drawing_wand,
+ const double stroke_width)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off ||
+ (AbsoluteValue(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
+ {
+ CurrentContext->stroke_width=stroke_width;
+ (void) MvgPrintf(drawing_wand,"stroke-width %g\n",stroke_width);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t T e x t A n t i a l i a s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetTextAntialias() returns the current text antialias setting, which
+% determines whether text is antialiased. Text is antialiased by default.
+%
+% The format of the DrawGetTextAntialias method is:
+%
+% unsigned int DrawGetTextAntialias(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport unsigned int DrawGetTextAntialias(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->text_antialias);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t A n t i a l i a s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextAntialias() controls whether text is antialiased. Text is
+% antialiased by default.
+%
+% The format of the DrawSetTextAntialias method is:
+%
+% void DrawSetTextAntialias(DrawingWand *drawing_wand,
+% const unsigned int text_antialias)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o text_antialias: antialias boolean. Set to false (0) to disable
+% antialiasing.
+%
+*/
+WandExport void DrawSetTextAntialias(DrawingWand *drawing_wand,
+ const unsigned int text_antialias)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off ||
+ (CurrentContext->text_antialias != text_antialias))
+ {
+ CurrentContext->text_antialias=text_antialias;
+ (void) MvgPrintf(drawing_wand,"text-antialias %i\n",text_antialias ? 1 : 0);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t T e x t D e c o r a t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetTextDecoration() returns the decoration applied when annotating with
+% text.
+%
+% The format of the DrawGetTextDecoration method is:
+%
+% DecorationType DrawGetTextDecoration(DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+*/
+WandExport DecorationType DrawGetTextDecoration(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ return(CurrentContext->decorate);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t D e c o r a t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextDecoration() specifies a decoration to be applied when
+% annotating with text.
+%
+% The format of the DrawSetTextDecoration method is:
+%
+% void DrawSetTextDecoration(DrawingWand *drawing_wand,
+% const DecorationType decoration)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
+% OverlineDecoration, or LineThroughDecoration
+%
+*/
+WandExport void DrawSetTextDecoration(DrawingWand *drawing_wand,
+ const DecorationType decoration)
+{
+ const char
+ *p=NULL;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (drawing_wand->filter_off || (CurrentContext->decorate != decoration))
+ {
+ CurrentContext->decorate=decoration;
+ switch (decoration)
+ {
+ case NoDecoration:
+ p="none";
+ break;
+ case UnderlineDecoration:
+ p="underline";
+ break;
+ case OverlineDecoration:
+ p="overline";
+ break;
+ case LineThroughDecoration:
+ p="line-through";
+ break;
+ }
+ if (p != NULL)
+ (void) MvgPrintf(drawing_wand,"decorate %s\n",p);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t T e x t E n c o d i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetTextEncoding() returns a null-terminated string which specifies the
+% code set used for text annotations. The string must be freed by the user
+% once it is no longer required.
+%
+% The format of the DrawGetTextEncoding method is:
+%
+% char *DrawGetTextEncoding(const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% */
+WandExport char *DrawGetTextEncoding(const DrawingWand *drawing_wand)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ if (CurrentContext->encoding != (char *)NULL)
+ return((char *) AcquireString(CurrentContext->encoding));
+ return((char *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t E n c o d i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextEncoding() specifies specifies the code set to use for
+% text annotations. The only character encoding which may be specified
+% at this time is "UTF-8" for representing Unicode as a sequence of
+% bytes. Specify an empty string to set text encoding to the system's
+% default. Successful text annotation using Unicode may require fonts
+% designed to support Unicode.
+%
+% The format of the DrawSetTextEncoding method is:
+%
+% void DrawSetTextEncoding(DrawingWand *drawing_wand,const char *encoding)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o encoding: character string specifying text encoding
+%
+% */
+WandExport void DrawSetTextEncoding(DrawingWand *drawing_wand,
+ const char *encoding)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(encoding != (char *) NULL);
+ if (drawing_wand->filter_off || (CurrentContext->encoding == (char *) NULL) ||
+ (LocaleCompare(CurrentContext->encoding,encoding) != 0))
+ {
+ (void) CloneString(&CurrentContext->encoding,encoding);
+ (void) MvgPrintf(drawing_wand,"encoding '%s'\n",encoding);
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w G e t T e x t U n d e r C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawGetTextUnderColor() returns the color of a background rectangle
+% to place under text annotations.
+%
+% The format of the DrawGetTextUnderColor method is:
+%
+% void DrawGetTextUnderColor(const DrawingWand *drawing_wand,
+% PixelWand *under_color)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o under_color: Return the under color.
+%
+*/
+WandExport void DrawGetTextUnderColor(const DrawingWand *drawing_wand,
+ PixelWand *under_color)
+{
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t T e x t U n d e r C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetTextUnderColor() specifies the color of a background rectangle
+% to place under text annotations.
+%
+% The format of the DrawSetTextUnderColor method is:
+%
+% void DrawSetTextUnderColor(DrawingWand *drawing_wand,
+% const PixelWand *under_wand)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o under_wand.: text under wand.
+%
+*/
+WandExport void DrawSetTextUnderColor(DrawingWand *drawing_wand,
+ const PixelWand *under_wand)
+{
+ PixelPacket
+ under_color;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ assert(under_wand != (const PixelWand *) NULL);
+ PixelGetQuantumColor(under_wand,&under_color);
+ if (drawing_wand->filter_off ||
+ !WandColorMatch(&CurrentContext->undercolor,&under_color))
+ {
+ CurrentContext->undercolor=under_color;
+ (void) MvgPrintf(drawing_wand,"text-undercolor '");
+ MvgAppendColor(drawing_wand,&under_color);
+ (void) MvgPrintf(drawing_wand,"'\n");
+ }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w T r a n s l a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawTranslate() applies a translation to the current coordinate
+% system which moves the coordinate system origin to the specified
+% coordinate.
+%
+% The format of the DrawTranslate method is:
+%
+% void DrawTranslate(DrawingWand *drawing_wand,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x: new x ordinate for coordinate system origin
+%
+% o y: new y ordinate for coordinate system origin
+%
+*/
+WandExport void DrawTranslate(DrawingWand *drawing_wand,const double x,
+ const double y)
+{
+ AffineMatrix
+ affine;
+
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ IdentityAffine(&affine);
+ affine.tx=x;
+ affine.ty=y;
+ AdjustAffine(drawing_wand,&affine );
+ (void) MvgPrintf(drawing_wand,"translate %g,%g\n",x,y);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D r a w S e t V i e w b o x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DrawSetViewbox() sets the overall canvas size to be recorded with the
+% drawing vector data. Usually this will be specified using the same
+% size as the canvas image. When the vector data is saved to SVG or MVG
+% formats, the viewbox is use to specify the size of the canvas image that
+% a viewer will render the vector data on.
+%
+% The format of the DrawSetViewbox method is:
+%
+% void DrawSetViewbox(DrawingWand *drawing_wand,unsigned long x1,
+% unsigned long y1,unsigned long x2,unsigned long y2)
+%
+% A description of each parameter follows:
+%
+% o drawing_wand: The drawing wand.
+%
+% o x1: left x ordinate
+%
+% o y1: top y ordinate
+%
+% o x2: right x ordinate
+%
+% o y2: bottom y ordinate
+%
+*/
+WandExport void DrawSetViewbox(DrawingWand *drawing_wand,unsigned long x1,
+ unsigned long y1,unsigned long x2,unsigned long y2)
+{
+ assert(drawing_wand != (DrawingWand *) NULL);
+ assert(drawing_wand->signature == MagickSignature);
+ (void) MvgPrintf(drawing_wand,"viewbox %lu %lu %lu %lu\n",x1,y1,x2,y2);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N e w D r a w i n g W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NewDrawingWand() returns a drawing wand required for all other methods in
+% the API.
+%
+% The format of the NewDrawingWand method is:
+%
+% DrawingWand *NewDrawingWand(void)
+%
+%
+*/
+WandExport DrawingWand *NewDrawingWand(void)
+{
+ DrawingWand
+ *drawing_wand;
+
+ /*
+ Initialize GraphicsMagick in case it is not already initialized.
+ */
+ InitializeMagick(NULL);
+
+ drawing_wand=MagickAllocateMemory(DrawingWand *,sizeof(struct _DrawingWand));
+ if (drawing_wand == (DrawingWand *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateDrawingWand);
+ GetExceptionInfo(&drawing_wand->exception);
+ drawing_wand->image=AllocateImage((const ImageInfo *) NULL);
+ drawing_wand->own_image=MagickTrue;
+ drawing_wand->mvg=NULL;
+ drawing_wand->mvg_alloc=0;
+ drawing_wand->mvg_length=0;
+ drawing_wand->mvg_width=0;
+ drawing_wand->pattern_id=NULL;
+ drawing_wand->pattern_offset=0;
+ drawing_wand->pattern_bounds.x=0;
+ drawing_wand->pattern_bounds.y=0;
+ drawing_wand->pattern_bounds.width=0;
+ drawing_wand->pattern_bounds.height=0;
+ drawing_wand->index=0;
+ drawing_wand->graphic_context=MagickAllocateMemory(DrawInfo **,
+ sizeof(DrawInfo *));
+ if (drawing_wand->graphic_context == (DrawInfo **) NULL)
+ {
+ ThrowException3(&drawing_wand->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ return (DrawingWand *) NULL;
+ }
+ CurrentContext=CloneDrawInfo((ImageInfo*)NULL,(DrawInfo *) NULL);
+ if (CurrentContext == (DrawInfo*) NULL)
+ {
+ ThrowException3(&drawing_wand->exception,ResourceLimitError,
+ MemoryAllocationFailed,UnableToDrawOnImage);
+ return (DrawingWand *) NULL;
+ }
+ drawing_wand->filter_off=MagickFalse;
+ drawing_wand->indent_depth=0;
+ drawing_wand->path_operation=PathDefaultOperation;
+ drawing_wand->path_mode=DefaultPathMode;
+ drawing_wand->signature=MagickSignature;
+ return(drawing_wand);
+}
diff --git a/wand/drawing_wand.h b/wand/drawing_wand.h
new file mode 100644
index 0000000..9d37135
--- /dev/null
+++ b/wand/drawing_wand.h
@@ -0,0 +1,416 @@
+/* Copyright (C) 2003-2009 GraphicsMagick Group */
+/*
+ ImageMagick Drawing Wand API.
+*/
+#ifndef _MAGICK_DRAWING_WAND_H
+#define _MAGICK_DRAWING_WAND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "wand/wand_symbols.h"
+#include "wand/pixel_wand.h"
+
+#undef CloneDrawingWand
+#define CloneDrawingWand MagickCloneDrawingWand
+#undef DestroyDrawingWand
+#define DestroyDrawingWand MagickDestroyDrawingWand
+#undef DrawAffine
+#define DrawAffine MagickDrawAffine
+#undef DrawAllocateWand
+#define DrawAllocateWand MagickDrawAllocateWand
+#undef DrawAnnotation
+#define DrawAnnotation MagickDrawAnnotation
+#undef DrawArc
+#define DrawArc MagickDrawArc
+#undef DrawBezier
+#define DrawBezier MagickDrawBezier
+#undef DrawClearException
+#define DrawClearException MagickDrawClearException
+#undef DrawCircle
+#define DrawCircle MagickDrawCircle
+#undef DrawColor
+#define DrawColor MagickDrawColor
+#undef DrawComment
+#define DrawComment MagickDrawComment
+#undef DrawComposite
+#define DrawComposite MagickDrawComposite
+#undef DrawEllipse
+#define DrawEllipse MagickDrawEllipse
+#undef DrawGetClipPath
+#define DrawGetClipPath MagickDrawGetClipPath
+#undef DrawGetClipRule
+#define DrawGetClipRule MagickDrawGetClipRule
+#undef DrawGetClipUnits
+#define DrawGetClipUnits MagickDrawGetClipUnits
+#undef DrawGetException
+#define DrawGetException MagickDrawGetException
+#undef DrawGetFillColor
+#define DrawGetFillColor MagickDrawGetFillColor
+#undef DrawGetFillOpacity
+#define DrawGetFillOpacity MagickDrawGetFillOpacity
+#undef DrawGetFillRule
+#define DrawGetFillRule MagickDrawGetFillRule
+#undef DrawGetFont
+#define DrawGetFont MagickDrawGetFont
+#undef DrawGetFontFamily
+#define DrawGetFontFamily MagickDrawGetFontFamily
+#undef DrawGetFontSize
+#define DrawGetFontSize MagickDrawGetFontSize
+#undef DrawGetFontStretch
+#define DrawGetFontStretch MagickDrawGetFontStretch
+#undef DrawGetFontStyle
+#define DrawGetFontStyle MagickDrawGetFontStyle
+#undef DrawGetFontWeight
+#define DrawGetFontWeight MagickDrawGetFontWeight
+#undef DrawGetGravity
+#define DrawGetGravity MagickDrawGetGravity
+#undef DrawGetStrokeAntialias
+#define DrawGetStrokeAntialias MagickDrawGetStrokeAntialias
+#undef DrawGetStrokeColor
+#define DrawGetStrokeColor MagickDrawGetStrokeColor
+#undef DrawGetStrokeDashArray
+#define DrawGetStrokeDashArray MagickDrawGetStrokeDashArray
+#undef DrawGetStrokeDashOffset
+#define DrawGetStrokeDashOffset MagickDrawGetStrokeDashOffset
+#undef DrawGetStrokeLineCap
+#define DrawGetStrokeLineCap MagickDrawGetStrokeLineCap
+#undef DrawGetStrokeLineJoin
+#define DrawGetStrokeLineJoin MagickDrawGetStrokeLineJoin
+#undef DrawGetStrokeMiterLimit
+#define DrawGetStrokeMiterLimit MagickDrawGetStrokeMiterLimit
+#undef DrawGetStrokeOpacity
+#define DrawGetStrokeOpacity MagickDrawGetStrokeOpacity
+#undef DrawGetStrokeWidth
+#define DrawGetStrokeWidth MagickDrawGetStrokeWidth
+#undef DrawGetTextAntialias
+#define DrawGetTextAntialias MagickDrawGetTextAntialias
+#undef DrawGetTextDecoration
+#define DrawGetTextDecoration MagickDrawGetTextDecoration
+#undef DrawGetTextEncoding
+#define DrawGetTextEncoding MagickDrawGetTextEncoding
+#undef DrawGetTextUnderColor
+#define DrawGetTextUnderColor MagickDrawGetTextUnderColor
+#undef DrawLine
+#define DrawLine MagickDrawLine
+#undef DrawMatte
+#define DrawMatte MagickDrawMatte
+#undef DrawPathClose
+#define DrawPathClose MagickDrawPathClose
+#undef DrawPathCurveToAbsolute
+#define DrawPathCurveToAbsolute MagickDrawPathCurveToAbsolute
+#undef DrawPathCurveToQuadraticBezierAbsolute
+#define DrawPathCurveToQuadraticBezierAbsolute MagickDrawPathCurveToQuadraticBezierAbsolute
+#undef DrawPathCurveToQuadraticBezierRelative
+#define DrawPathCurveToQuadraticBezierRelative MagickDrawPathCurveToQuadraticBezierRelative
+#undef DrawPathCurveToQuadraticBezierSmoothAbsolute
+#define DrawPathCurveToQuadraticBezierSmoothAbsolute MagickDrawPathCurveToQuadraticBezierSmoothAbsolute
+#undef DrawPathCurveToQuadraticBezierSmoothRelative
+#define DrawPathCurveToQuadraticBezierSmoothRelative MagickDrawPathCurveToQuadraticBezierSmoothRelative
+#undef DrawPathCurveToRelative
+#define DrawPathCurveToRelative MagickDrawPathCurveToRelative
+#undef DrawPathCurveToSmoothAbsolute
+#define DrawPathCurveToSmoothAbsolute MagickDrawPathCurveToSmoothAbsolute
+#undef DrawPathCurveToSmoothRelative
+#define DrawPathCurveToSmoothRelative MagickDrawPathCurveToSmoothRelative
+#undef DrawPathEllipticArcAbsolute
+#define DrawPathEllipticArcAbsolute MagickDrawPathEllipticArcAbsolute
+#undef DrawPathEllipticArcRelative
+#define DrawPathEllipticArcRelative MagickDrawPathEllipticArcRelative
+#undef DrawPathFinish
+#define DrawPathFinish MagickDrawPathFinish
+#undef DrawPathLineToAbsolute
+#define DrawPathLineToAbsolute MagickDrawPathLineToAbsolute
+#undef DrawPathLineToHorizontalAbsolute
+#define DrawPathLineToHorizontalAbsolute MagickDrawPathLineToHorizontalAbsolute
+#undef DrawPathLineToHorizontalRelative
+#define DrawPathLineToHorizontalRelative MagickDrawPathLineToHorizontalRelative
+#undef DrawPathLineToRelative
+#define DrawPathLineToRelative MagickDrawPathLineToRelative
+#undef DrawPathLineToVerticalAbsolute
+#define DrawPathLineToVerticalAbsolute MagickDrawPathLineToVerticalAbsolute
+#undef DrawPathLineToVerticalRelative
+#define DrawPathLineToVerticalRelative MagickDrawPathLineToVerticalRelative
+#undef DrawPathMoveToAbsolute
+#define DrawPathMoveToAbsolute MagickDrawPathMoveToAbsolute
+#undef DrawPathMoveToRelative
+#define DrawPathMoveToRelative MagickDrawPathMoveToRelative
+#undef DrawPathStart
+#define DrawPathStart MagickDrawPathStart
+#undef DrawPeekGraphicContext
+#define DrawPeekGraphicContext MagickDrawPeekGraphicContext
+#undef DrawPoint
+#define DrawPoint MagickDrawPoint
+#undef DrawPolygon
+#define DrawPolygon MagickDrawPolygon
+#undef DrawPolyline
+#define DrawPolyline MagickDrawPolyline
+#undef DrawPopClipPath
+#define DrawPopClipPath MagickDrawPopClipPath
+#undef DrawPopDefs
+#define DrawPopDefs MagickDrawPopDefs
+#undef DrawPopGraphicContext
+#define DrawPopGraphicContext MagickDrawPopGraphicContext
+#undef DrawPopPattern
+#define DrawPopPattern MagickDrawPopPattern
+#undef DrawPushClipPath
+#define DrawPushClipPath MagickDrawPushClipPath
+#undef DrawPushDefs
+#define DrawPushDefs MagickDrawPushDefs
+#undef DrawPushGraphicContext
+#define DrawPushGraphicContext MagickDrawPushGraphicContext
+#undef DrawPushPattern
+#define DrawPushPattern MagickDrawPushPattern
+#undef DrawRectangle
+#define DrawRectangle MagickDrawRectangle
+#undef DrawRender
+#define DrawRender MagickDrawRender
+#undef DrawRotate
+#define DrawRotate MagickDrawRotate
+#undef DrawRoundRectangle
+#define DrawRoundRectangle MagickDrawRoundRectangle
+#undef DrawScale
+#define DrawScale MagickDrawScale
+#undef DrawSetClipPath
+#define DrawSetClipPath MagickDrawSetClipPath
+#undef DrawSetClipRule
+#define DrawSetClipRule MagickDrawSetClipRule
+#undef DrawSetClipUnits
+#define DrawSetClipUnits MagickDrawSetClipUnits
+#undef DrawSetFillColor
+#define DrawSetFillColor MagickDrawSetFillColor
+#undef DrawSetFillOpacity
+#define DrawSetFillOpacity MagickDrawSetFillOpacity
+#undef DrawSetFillPatternURL
+#define DrawSetFillPatternURL MagickDrawSetFillPatternURL
+#undef DrawSetFillRule
+#define DrawSetFillRule MagickDrawSetFillRule
+#undef DrawSetFont
+#define DrawSetFont MagickDrawSetFont
+#undef DrawSetFontFamily
+#define DrawSetFontFamily MagickDrawSetFontFamily
+#undef DrawSetFontSize
+#define DrawSetFontSize MagickDrawSetFontSize
+#undef DrawSetFontStretch
+#define DrawSetFontStretch MagickDrawSetFontStretch
+#undef DrawSetFontStyle
+#define DrawSetFontStyle MagickDrawSetFontStyle
+#undef DrawSetFontWeight
+#define DrawSetFontWeight MagickDrawSetFontWeight
+#undef DrawSetGravity
+#define DrawSetGravity MagickDrawSetGravity
+#undef DrawSetStrokeAntialias
+#define DrawSetStrokeAntialias MagickDrawSetStrokeAntialias
+#undef DrawSetStrokeColor
+#define DrawSetStrokeColor MagickDrawSetStrokeColor
+#undef DrawSetStrokeDashArray
+#define DrawSetStrokeDashArray MagickDrawSetStrokeDashArray
+#undef DrawSetStrokeDashOffset
+#define DrawSetStrokeDashOffset MagickDrawSetStrokeDashOffset
+#undef DrawSetStrokeLineCap
+#define DrawSetStrokeLineCap MagickDrawSetStrokeLineCap
+#undef DrawSetStrokeLineJoin
+#define DrawSetStrokeLineJoin MagickDrawSetStrokeLineJoin
+#undef DrawSetStrokeMiterLimit
+#define DrawSetStrokeMiterLimit MagickDrawSetStrokeMiterLimit
+#undef DrawSetStrokeOpacity
+#define DrawSetStrokeOpacity MagickDrawSetStrokeOpacity
+#undef DrawSetStrokePatternURL
+#define DrawSetStrokePatternURL MagickDrawSetStrokePatternURL
+#undef DrawSetStrokeWidth
+#define DrawSetStrokeWidth MagickDrawSetStrokeWidth
+#undef DrawSetTextAntialias
+#define DrawSetTextAntialias MagickDrawSetTextAntialias
+#undef DrawSetTextDecoration
+#define DrawSetTextDecoration MagickDrawSetTextDecoration
+#undef DrawSetTextEncoding
+#define DrawSetTextEncoding MagickDrawSetTextEncoding
+#undef DrawSetTextUnderColor
+#define DrawSetTextUnderColor MagickDrawSetTextUnderColor
+#undef DrawSetViewbox
+#define DrawSetViewbox MagickDrawSetViewbox
+#undef DrawSkewX
+#define DrawSkewX MagickDrawSkewX
+#undef DrawSkewY
+#define DrawSkewY MagickDrawSkewY
+#undef DrawTranslate
+#define DrawTranslate MagickDrawTranslate
+#undef NewDrawingWand
+#define NewDrawingWand MagickNewDrawingWand
+
+typedef struct _DrawingWand
+ DrawingWand;
+
+extern WandExport char
+ *DrawGetClipPath(const DrawingWand *),
+ *DrawGetException(const DrawingWand *,ExceptionType *),
+ *DrawGetFont(const DrawingWand *),
+ *DrawGetFontFamily(const DrawingWand *),
+ *DrawGetTextEncoding(const DrawingWand *);
+
+extern WandExport ClipPathUnits
+ DrawGetClipUnits(const DrawingWand *);
+
+extern WandExport DecorationType
+ DrawGetTextDecoration(const DrawingWand *);
+
+extern WandExport double
+ DrawGetFillOpacity(const DrawingWand *),
+ DrawGetFontSize(const DrawingWand *),
+ *DrawGetStrokeDashArray(const DrawingWand *,unsigned long *),
+ DrawGetStrokeDashOffset(const DrawingWand *),
+ DrawGetStrokeOpacity(const DrawingWand *),
+ DrawGetStrokeWidth(const DrawingWand *);
+
+extern WandExport DrawInfo
+ *DrawPeekGraphicContext(const DrawingWand *);
+
+extern WandExport DrawingWand
+ *CloneDrawingWand(const DrawingWand *drawing_wand),
+ *DrawAllocateWand(const DrawInfo *,Image *) MAGICK_ATTRIBUTE ((deprecated)),
+ *NewDrawingWand(void);
+
+extern WandExport FillRule
+ DrawGetClipRule(const DrawingWand *),
+ DrawGetFillRule(const DrawingWand *);
+
+extern WandExport GravityType
+ DrawGetGravity(const DrawingWand *);
+
+extern WandExport LineCap
+ DrawGetStrokeLineCap(const DrawingWand *);
+
+extern WandExport LineJoin
+ DrawGetStrokeLineJoin(const DrawingWand *);
+
+extern WandExport StretchType
+ DrawGetFontStretch(const DrawingWand *);
+
+extern WandExport StyleType
+ DrawGetFontStyle(const DrawingWand *);
+
+extern WandExport unsigned int
+ DrawClearException(DrawingWand *),
+ DrawGetStrokeAntialias(const DrawingWand *),
+ DrawGetTextAntialias(const DrawingWand *),
+ DrawRender(const DrawingWand *) MAGICK_ATTRIBUTE ((deprecated)); /* Use MagickDrawImage() instead */
+
+extern WandExport unsigned long
+ DrawGetFontWeight(const DrawingWand *),
+ DrawGetStrokeMiterLimit(const DrawingWand *);
+
+extern WandExport void
+ DrawAffine(DrawingWand *,const AffineMatrix *),
+ DrawAnnotation(DrawingWand *,const double,const double,const unsigned char *),
+ DrawArc(DrawingWand *,const double,const double,const double,const double,
+ const double,const double),
+ DrawBezier(DrawingWand *,const unsigned long,const PointInfo *),
+ DrawCircle(DrawingWand *,const double,const double,const double,const double),
+ DrawColor(DrawingWand *,const double,const double,const PaintMethod),
+ DrawComment(DrawingWand *,const char *),
+ DestroyDrawingWand(DrawingWand *),
+ DrawEllipse(DrawingWand *,const double,const double,const double,const double,
+ const double,const double),
+ DrawComposite(DrawingWand *,const CompositeOperator,const double,const double,
+ const double,const double,const Image *),
+ DrawGetFillColor(const DrawingWand *,PixelWand *),
+ DrawGetStrokeColor(const DrawingWand *,PixelWand *),
+ DrawGetTextUnderColor(const DrawingWand *,PixelWand *),
+ DrawLine(DrawingWand *,const double, const double,const double,const double),
+ DrawMatte(DrawingWand *,const double,const double,const PaintMethod),
+ DrawPathClose(DrawingWand *),
+ DrawPathCurveToAbsolute(DrawingWand *,const double,const double,const double,
+ const double,const double,const double),
+ DrawPathCurveToRelative(DrawingWand *,const double,const double,const double,
+ const double,const double, const double),
+ DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *,const double,
+ const double,const double,const double),
+ DrawPathCurveToQuadraticBezierRelative(DrawingWand *,const double,
+ const double,const double,const double),
+ DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *,const double,
+ const double),
+ DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *,const double,
+ const double),
+ DrawPathCurveToSmoothAbsolute(DrawingWand *,const double,const double,
+ const double,const double),
+ DrawPathCurveToSmoothRelative(DrawingWand *,const double,const double,
+ const double,const double),
+ DrawPathEllipticArcAbsolute(DrawingWand *,const double,const double,
+ const double,unsigned int,unsigned int,const double,const double),
+ DrawPathEllipticArcRelative(DrawingWand *,const double,const double,
+ const double,unsigned int,unsigned int,const double,const double),
+ DrawPathFinish(DrawingWand *),
+ DrawPathLineToAbsolute(DrawingWand *,const double,const double),
+ DrawPathLineToRelative(DrawingWand *,const double,const double),
+ DrawPathLineToHorizontalAbsolute(DrawingWand *,const double),
+ DrawPathLineToHorizontalRelative(DrawingWand *,const double),
+ DrawPathLineToVerticalAbsolute(DrawingWand *,const double),
+ DrawPathLineToVerticalRelative(DrawingWand *,const double),
+ DrawPathMoveToAbsolute(DrawingWand *,const double,const double),
+ DrawPathMoveToRelative(DrawingWand *,const double,const double),
+ DrawPathStart(DrawingWand *),
+ DrawPoint(DrawingWand *,const double,const double),
+ DrawPolygon(DrawingWand *,const unsigned long,const PointInfo *),
+ DrawPolyline(DrawingWand *,const unsigned long,const PointInfo *),
+ DrawPopClipPath(DrawingWand *),
+ DrawPopDefs(DrawingWand *),
+ DrawPopGraphicContext(DrawingWand *),
+ DrawPopPattern(DrawingWand *),
+ DrawPushClipPath(DrawingWand *,const char *),
+ DrawPushDefs(DrawingWand *),
+ DrawPushGraphicContext(DrawingWand *),
+ DrawPushPattern(DrawingWand *,const char *,const double,const double,
+ const double,const double),
+ DrawRectangle(DrawingWand *,const double,const double,const double,
+ const double),
+ DrawRotate(DrawingWand *,const double),
+ DrawRoundRectangle(DrawingWand *,double,double,double,double,double,double),
+ DrawScale(DrawingWand *,const double,const double),
+ DrawSetClipPath(DrawingWand *,const char *),
+ DrawSetClipRule(DrawingWand *,const FillRule),
+ DrawSetClipUnits(DrawingWand *,const ClipPathUnits),
+ DrawSetFillColor(DrawingWand *,const PixelWand *),
+ DrawSetFillOpacity(DrawingWand *,const double),
+ DrawSetFillRule(DrawingWand *,const FillRule),
+ DrawSetFillPatternURL(DrawingWand *,const char *),
+ DrawSetFont(DrawingWand *,const char *),
+ DrawSetFontFamily(DrawingWand *,const char *),
+ DrawSetFontSize(DrawingWand *,const double),
+ DrawSetFontStretch(DrawingWand *,const StretchType),
+ DrawSetFontStyle(DrawingWand *,const StyleType),
+ DrawSetFontWeight(DrawingWand *,const unsigned long),
+ DrawSetGravity(DrawingWand *,const GravityType),
+ DrawSkewX(DrawingWand *,const double),
+ DrawSkewY(DrawingWand *,const double),
+ DrawSetStrokeAntialias(DrawingWand *,const unsigned int),
+ DrawSetStrokeColor(DrawingWand *,const PixelWand *),
+ DrawSetStrokeDashArray(DrawingWand *,const unsigned long,const double *),
+ DrawSetStrokeDashOffset(DrawingWand *,const double dashoffset),
+ DrawSetStrokeLineCap(DrawingWand *,const LineCap),
+ DrawSetStrokeLineJoin(DrawingWand *,const LineJoin),
+ DrawSetStrokeMiterLimit(DrawingWand *,const unsigned long),
+ DrawSetStrokeOpacity(DrawingWand *, const double),
+ DrawSetStrokePatternURL(DrawingWand *,const char *),
+ DrawSetStrokeWidth(DrawingWand *,const double),
+ DrawSetTextAntialias(DrawingWand *,const unsigned int),
+ DrawSetTextDecoration(DrawingWand *,const DecorationType),
+ DrawSetTextEncoding(DrawingWand *,const char *),
+ DrawSetTextUnderColor(DrawingWand *,const PixelWand *),
+ DrawSetViewbox(DrawingWand *,unsigned long,unsigned long,unsigned long,
+ unsigned long),
+ DrawTranslate(DrawingWand *,const double,const double);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/wand/drawtest.c b/wand/drawtest.c
new file mode 100644
index 0000000..3e824d6
--- /dev/null
+++ b/wand/drawtest.c
@@ -0,0 +1,444 @@
+/* Copyright (C) 2003-2010 GraphicsMagick Group */
+/*
+ *
+ * Test program for C drawing API
+ * Written by Bob Friesenhahn
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+#include <wand/magick_wand.h>
+
+static MagickPassFail
+ScribbleImage (MagickWand *canvas)
+{
+ DrawingWand
+ *draw_wand;
+
+ PixelWand
+ *color;
+
+ MagickPassFail
+ status;
+
+ draw_wand=NewDrawingWand();
+ color=NewPixelWand();
+ DrawPushGraphicContext(draw_wand);
+ {
+ DrawSetViewbox(draw_wand,0,0,MagickGetImageWidth(canvas),
+ MagickGetImageHeight(canvas));
+ DrawScale(draw_wand,1.101,1.08);
+ DrawTranslate(draw_wand,-23.69,-22.97);
+ DrawRotate(draw_wand,0);
+ PixelSetColor(color,"#ffffff");
+ DrawSetFillColor(draw_wand,color);
+ DrawRectangle(draw_wand,23.69,22.97,564.6,802.2);
+ DrawSetFillOpacity(draw_wand,1.0);
+ PixelSetColor(color,"none");
+ DrawSetFillColor(draw_wand,color);
+ DrawSetStrokeColor(draw_wand,color);
+
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+
+ DrawPushDefs(draw_wand);
+ {
+ DrawPushClipPath(draw_wand,"clip_1");
+ {
+ DrawPushGraphicContext(draw_wand);
+ {
+ DrawRectangle(draw_wand,0,0,595.3,841.9);
+ }
+ DrawPopGraphicContext(draw_wand);
+ }
+ DrawPopClipPath(draw_wand);
+ }
+ DrawPopDefs(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ DrawSetClipPath(draw_wand, "url(#clip_1)");
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,4.032);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#ff0000");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#ff00ff");
+ DrawSetFillColor(draw_wand,color);
+ DrawRectangle(draw_wand,72,72,144,144);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,9);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#00ff00");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#0080ff");
+ DrawSetFillColor(draw_wand,color);
+ DrawRoundRectangle(draw_wand,72,216,360,432,9,9);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ const PointInfo points[37] =
+ {
+ { 378.1,81.72 }, { 381.1,79.56 }, { 384.3,78.12 }, { 387.6,77.33 },
+ { 391.1,77.11 }, { 394.6,77.62 }, { 397.8,78.77 }, { 400.9,80.57 },
+ { 403.6,83.02 }, { 523.9,216.8 }, { 526.2,219.7 }, { 527.6,223 },
+ { 528.4,226.4 }, { 528.6,229.8 }, { 528,233.3 }, { 526.9,236.5 },
+ { 525.1,239.5 }, { 522.6,242.2 }, { 495.9,266.3 }, { 493,268.5 },
+ { 489.7,269.9 }, { 486.4,270.8 }, { 482.9,270.9 }, { 479.5,270.4 },
+ { 476.2,269.3 }, { 473.2,267.5 }, { 470.4,265 }, { 350,131.2 },
+ { 347.8,128.3 }, { 346.4,125.1 }, { 345.6,121.7 }, {345.4,118.2 },
+ { 346,114.8 }, { 347.1,111.5 }, { 348.9,108.5 }, { 351.4,105.8 },
+ { 378.1,81.72 }
+ };
+
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,2.016);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#000080");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#c2c280");
+ DrawSetFillColor(draw_wand,color);
+ DrawPolygon(draw_wand,37,points);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,3.024);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#000080");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#000080");
+ DrawSetFillColor(draw_wand,color);
+ DrawEllipse(draw_wand,489.6,424.8,72,129.6,0,360);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ const PointInfo points[48] =
+ {
+ { 213.8,25.13}, { 216.7,24.48 }, {219.8,24.55 }, { 223.1,25.42 },
+ { 226.7,27 }, { 230.3,29.3 }, { 234.1,32.26 }, { 237.9,35.86 },
+ { 241.8,40.03 }, { 249.7,50.11 }, { 257.4,62.14 }, { 264.8,75.89 },
+ { 271.6,91.15 }, { 277.3,106.8 }, { 281.6,121.8 }, { 284.4,135.9 },
+ { 285.7,148.5 }, { 285.6,159.6 }, { 284.9,164.3 }, { 283.8,168.5 },
+ { 282.5,172.1 }, { 280.7,175 }, { 278.5,177.3 }, { 275.9,178.7 },
+ { 273,179.4 }, { 269.9,179.3 }, { 266.6,178.4 }, { 263.1,176.8 },
+ { 259.5,174.5}, { 255.7,171.6 }, { 251.9,168 }, { 248,163.8 },
+ { 244.1,159 }, { 240.1,153.7 }, { 232.3,141.7 }, { 225,127.9 },
+ { 218.2,112.7 }, { 212.5,97.06 }, { 208.2,82.01 }, { 205.4,67.97 },
+ { 204,55.3 }, { 204.3,44.35 }, { 204.9,39.6 }, { 205.9,35.42 },
+ { 207.4,31.82 }, { 209.2,28.87 }, { 211.3,26.64}, { 213.8,25.13 }
+ };
+
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,3.024);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#ff8000");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#00ffff");
+ DrawSetFillColor(draw_wand,color);
+ DrawPolygon(draw_wand,48,points);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,12.02);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#4000c2");
+ DrawSetStrokeColor(draw_wand,color);
+ PixelSetColor(color,"none");
+ DrawSetFillColor(draw_wand,color);
+ DrawArc(draw_wand,360,554.4,187.2,237.6,0,90);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,9);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#4000c2");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#4000c2");
+ DrawSetFillColor(draw_wand,color);
+ DrawEllipse(draw_wand,388.8,626.4,100.8,122.4,0,90);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ const PointInfo points[6] =
+ {
+ { 180,504 }, { 282.7,578.6 }, { 243.5,699.4 }, { 116.5,699.4 },
+ { 77.26,578.6 }, { 180,504 }
+ };
+
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,9);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#4000c2");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#800000");
+ DrawSetFillColor(draw_wand,color);
+ DrawPolygon(draw_wand,6,points);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ const PointInfo points[11] =
+ {
+ { 180,504 }, { 211.8,568.3 }, { 282.7,578.6 }, { 231.3,628.7 },
+ { 243.5,699.4 }, { 180,666 }, { 116.5,699.4 }, { 128.7,628.7 },
+ { 77.26,578.6 }, { 148.2,568.3 }, { 180,504 }
+ };
+
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,9);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#4000c2");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#800000");
+ DrawSetFillColor(draw_wand,color);
+ DrawPolygon(draw_wand,11,points);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ const PointInfo points[15] =
+ {
+ { 540,288 }, { 561.6,216 }, { 547.2,43.2 }, { 280.8,36 },
+ { 302.4,194.4 }, { 331.2,64.8 }, { 504,64.8 }, { 475.2,115.2 },
+ { 525.6,93.6 }, { 496.8,158.4 }, { 532.8,136.8 }, { 518.4,180 },
+ { 540,172.8 }, { 540,223.2 }, { 540,288 }
+ };
+
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,5.976);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#4000c2");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#ffff00");
+ DrawSetFillColor(draw_wand,color);
+ DrawPolygon(draw_wand,15,points);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ const PointInfo points[7] =
+ {
+ { 57.6,640.8 }, { 57.6,784.8 }, { 194.4,799.2 }, { 259.2,777.6 },
+ { 151.2,756 }, { 86.4,748.8 }, { 57.6,640.8 }
+ };
+
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,5.976);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#4000c2");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#ffff00");
+ DrawSetFillColor(draw_wand,color);
+ DrawPolygon(draw_wand,7,points);
+ }
+ DrawPopGraphicContext(draw_wand);
+
+ DrawPushGraphicContext(draw_wand);
+ {
+ const PointInfo points[193] =
+ {
+ { 27.86,565.3 }, { 29.66,550.8 }, { 31.97,538.1 }, { 34.85,527.1 },
+ { 38.09,517.7 }, { 41.83,509.8 }, { 45.86,503.1 }, { 50.33,497.6 },
+ { 55.08,493.2 }, { 60.19,489.8 }, { 65.45,487.3 }, { 70.92,485.4 },
+ { 76.61,484.2 }, { 88.42,483 }, { 100.4,482.9 }, { 108.4,482.2 },
+ { 119.8,480.3 }, { 150.8,474.1 }, { 189.4,466.6 }, { 210.3,463 },
+ { 231.5,459.9 }, { 252.4,457.8 }, { 272.7,456.6 }, { 291.8,456.9 },
+ { 300.7,457.7 }, { 309.1,458.9 }, { 316.9,460.6 }, { 324.1,462.8 },
+ { 330.7,465.6 }, { 336.4,469 }, { 341.3,473 }, { 345.3,477.7 },
+ { 348.4,483.1 }, { 350.4,489.2}, { 352.4,495.4 }, { 355.2,500.9 },
+ { 358.8,505.8 }, { 363,510 }, { 367.8,513.6 }, { 373,516.8 },
+ { 378.6,519.6 }, { 384.3,521.8 }, { 396.4,525.4 }, { 408.2,527.9 },
+ { 428,531.2 }, { 434.6,532.9 }, { 436.7,533.8 }, { 437.8,534.9 },
+ { 437.8,536.2 }, { 436.8,537.8 }, { 434.5,539.6 }, { 430.9,541.8 },
+ { 419.3,547.6 }, { 401.3,555.2 }, { 342.4,577.9 }, {325.2,584.9 },
+ { 311,591.3 }, { 300,597.3 }, { 291.6,602.8 }, { 285.8,607.8 },
+ { 282.3,612.3 }, { 281.4,614.4 }, { 280.9,616.2 }, { 281.2,619.6 },
+ { 282.1,621.2 }, { 283.3,622.6 }, { 286.8,624.9 }, { 291.5,626.6 },
+ { 297.1,627.8 }, { 303.6,628.3 }, { 310.5,628.3 }, { 317.9,627.6 },
+ { 325.2,626.3 }, { 332.6,624.3 }, { 339.5,621.7 }, { 345.9,618.4 },
+ { 351.4,614.4 }, { 353.9,612.2 }, { 356,609.8 }, { 357.9,607.1 },
+ { 359.4,604.3 }, { 360.6,601.3 }, { 361.4,598.2 }, { 361.7,594.9 },
+ { 361.7,591.3 }, { 361.2,587.7 }, { 360.1,583.7 }, { 358.6,579.7 },
+ { 356.4,575.4 }, { 353.7,570.9 }, { 350.4,566.2 }, { 346.4,561.3 },
+ { 341.8,556.2 }, { 336.5,550.9 }, { 330.6,545.5 }, { 323.8,539.8 },
+ { 316.2,533.9 }, { 298.7,521.5 }, { 277.8,508.2 }, { 256.1,495.5 },
+ { 236,484.5 }, { 217.7,475.1 }, { 200.8,467.1 }, { 185.6,460.7 },
+ { 171.9,455.5 }, { 159.6,451.6 }, { 148.6,448.8 }, { 139,447 },
+ { 130.5,446.2 }, { 123.3,446.2 }, { 117.1,446.9 }, { 112,448.3 },
+ { 107.9,450.2 }, { 104.8,452.5 }, { 102.5,455.2 }, { 101,458.1 },
+ { 100.2,461.2 }, { 100.2,464.3 }, { 100.7,467.4 }, { 101.8,470.3 },
+ { 103.4,473 }, { 105.4,475.3 }, { 107.8,477.1 }, { 110.5,478.4 },
+ { 113.4,479.1 }, { 116.5,478.9 }, { 119.7,478 }, { 123,476.2 },
+ { 126.4,473.3 }, { 129.6,469.2 }, { 132.7,463.9 }, { 135.2,458.4 },
+ { 136.6,453.7 }, { 137,449.9 }, { 136.6,446.8 }, { 135.4,444.5 },
+ { 133.3,442.9 }, { 130.8,441.9 }, { 127.5,441.4 }, { 123.9,441.6 },
+ { 119.8,442.3 }, { 110.7,445.1 }, { 101.1,449.5 }, { 91.37,455.2 },
+ { 82.37,461.9 }, { 74.66,469.2 }, { 71.57,473 }, { 68.98,476.8 },
+ { 67.03,480.7 }, { 65.81,484.4 }, { 65.45,488.2 }, { 65.95,491.7 },
+ { 67.46,495.1 }, { 69.98,498.3 }, { 73.66,501.3 }, { 78.55,503.9 },
+ { 84.82,506.3 }, { 92.38,508.2 }, { 107.1,511.6 }, { 118.2,514.8 },
+ { 125.9,517.8 }, { 130.7,520.4 }, { 132.1,521.7 }, { 132.8,522.9 },
+ { 133,524.2 }, { 132.6,525.3 }, { 131.8,526.5 }, { 130.5,527.5 },
+ { 126.6,529.6 }, { 121.5,531.7 }, { 115.3,533.7 }, { 101.4,537.6 },
+ { 87.55,541.8 }, { 81.36,544 }, { 76.25,546.3 }, { 71.64,549.5 },
+ { 66.89,554.1 }, { 62.14,559.8 }, { 57.38,566.1 }, { 48.17,579.6 },
+ { 39.96,591.4 }, { 36.43,595.9 }, { 34.78,597.6 }, { 33.26,598.8 },
+ { 31.9,599.6 }, { 30.67,599.9 }, { 29.59,599.7 }, { 28.66,598.8 },
+ { 27.86,597.4 }, { 27.29,595.2 }, { 26.64,588.7 }, { 26.86,578.8 },
+ { 27.86,565.3 }
+ };
+
+ DrawSetStrokeAntialias(draw_wand,MagickTrue);
+ DrawSetStrokeWidth(draw_wand,5.904);
+ DrawSetStrokeLineCap(draw_wand,RoundCap);
+ DrawSetStrokeLineJoin(draw_wand,RoundJoin);
+ DrawSetStrokeDashArray(draw_wand,0,(const double *)NULL);
+ PixelSetColor(color,"#4000c2");
+ DrawSetStrokeColor(draw_wand,color);
+ DrawSetFillRule(draw_wand,EvenOddRule);
+ PixelSetColor(color,"#ffff00");
+ DrawSetFillColor(draw_wand,color);
+ DrawPolygon(draw_wand,193,points);
+ }
+ DrawPopGraphicContext(draw_wand);
+ }
+ DrawPopGraphicContext(draw_wand);
+ }
+ DrawPopGraphicContext(draw_wand);
+ status=MagickDrawImage(canvas,draw_wand);
+ DestroyPixelWand(color);
+ DestroyDrawingWand(draw_wand);
+ return status;
+}
+
+int main ( int argc, char **argv )
+{
+ MagickWand
+ *canvas = (MagickWand *) NULL;
+
+ char
+ outfile[MaxTextExtent];
+
+ MagickPassFail
+ status=MagickPass;
+
+ if ( argc != 2 )
+ {
+ printf ( "Usage: %s filename\n", argv[0] );
+ exit( 1 );
+ }
+
+ outfile[MaxTextExtent-1]='\0';
+ (void) strncpy( outfile, argv[1], MaxTextExtent-1 );
+
+ if (LocaleNCompare("drawtest",argv[0],7) == 0)
+ InitializeMagick((char *) NULL);
+ else
+ InitializeMagick(*argv);
+
+ /*
+ * Create canvas image
+ */
+ canvas=NewMagickWand();
+ if (MagickFail != status)
+ if ((status = MagickSetSize( canvas, 596, 842 )) == MagickFail)
+ printf ( "Failed to set image size\n" );
+
+ if (MagickPass == status)
+ if ((status = MagickReadImage( canvas, "xc:white" )) == MagickFail)
+ printf ( "Failed to read canvas image %s\n", MagickGetFilename(canvas) );
+
+ /*
+ * Scribble on image
+ */
+ if (MagickPass == status)
+ if ((status = ScribbleImage( canvas )) == MagickFail)
+ printf ( "Failed draw on image\n" );
+
+ /*
+ * Set depth to 8
+ */
+ if (MagickPass == status)
+ status=MagickSetImageDepth( canvas, 8);
+
+ /*
+ * Set RLE compression
+ */
+ if (MagickPass == status)
+ status=MagickSetImageCompression( canvas, RLECompression);
+
+ /*
+ * Save image to file
+ */
+ if (MagickPass == status)
+ if ((status = MagickWriteImage ( canvas, outfile )) == MagickFail)
+ printf ( "Failed to write image file %s\n", outfile );
+
+ DestroyMagickWand( canvas );
+ DestroyMagick();
+
+ return (MagickPass == status ? 0 : 1);
+}
diff --git a/wand/input_256c.miff b/wand/input_256c.miff
new file mode 100644
index 0000000..ea84fd1
--- /dev/null
+++ b/wand/input_256c.miff
Binary files differ
diff --git a/wand/input_bilevel.miff b/wand/input_bilevel.miff
new file mode 100644
index 0000000..8f4ba29
--- /dev/null
+++ b/wand/input_bilevel.miff
Binary files differ
diff --git a/wand/input_gray.miff b/wand/input_gray.miff
new file mode 100644
index 0000000..5ca323f
--- /dev/null
+++ b/wand/input_gray.miff
Binary files differ
diff --git a/wand/input_truecolor.miff b/wand/input_truecolor.miff
new file mode 100644
index 0000000..096baf9
--- /dev/null
+++ b/wand/input_truecolor.miff
@@ -0,0 +1,5 @@
+id=ImageMagick version=1.0
+class=DirectClass matte=False
+columns=70 rows=46 depth=8
+
+:0/-20.62/83.:3-92-80-91.80-80-7/,5-*4,)5-*5-*1-'1.'41*74-96/?:/F?3JB4LA2NB2UA2tD4C3A5E=DGCF=B<@@;?/?-@-A+@+?.=,=+=*?.?3B3D6F9R:/:5372172/61.30,//-0/-3,-6+-P78IGbn|lpPHnRLauw|z|lYVS/.,0/-50-71-81,80,6/,81-81-81.7.,4-*4,*6/+6.+3/*30*41+63-750>8-E=2H?1I>.K@/MD3iE4@.<-G<DGBE<A<@A;?-?+?,@+?+>.=,=*;*>->3@4D8H;D7,95593162/62.11--1.00.5/.2*,E21xA5Y\}clJ>kK@\]^g~lp_YWS,,,,-+0/,1.+2,(2-*0,+2,+2++2,+2,+1,+1,)3-,3-,3/,31,40,52-750:3,>6-@6-C8-H;/EE5UD4m=+9(E4H=E@<>>=A0@*?->-?,>)>,=-<-;.?/B1@8GDWN<?5;4193.53.14/-4.,40/3/12000.3-+I.!lMNkqH==1X54H>FFISIYZO,-/+-/.--/-)/*'-+(,**,**.++.++.++/++/--0,,0-./-*2.,2.+2-,30.82/<4/>4/A5-F91H>7Q<5_70y7-;/A3E9E@HAB/@,>-=/=-=+<+<,<.<2C7G:E@g_yWeWCB875+/1*.1+-0,-0//0.02./2./-24*,gcb~ipY\o`pr|_eQ,/2+/2..0-.--+),*++)+('(**+,*+,*+*))*()-+,.-./,+0,+.*)/++0--811<32;21>0.A2/A73B:6K62h7/=0>5A3D7G<?3?,=+;-<-;,9)9*:.?7G@E>UR{rpSZG<@301(-)'2,+2,+0,*0-+0/+2*10)(eqRʳǰYdJ.0.//-/1.21.30-3/,2-*-*+,+,*)-+(,-',+(),*)--+/-,.+*/+)4,)6/*;3.=40;1-;/.>/.>3,59/93,O,'i:-A1@1;-B2>2</=.?/</9,{;,v:*};0G;KDQOpwy\{ZN^G=:32'(/')-(+0(,2(/1+00*0+'[f@vvɌÓ~vpO[D23-34-53.961961:2.80-3.,300-.0/(/1)./*,1.*10*01./004/+;1+A5,C8/A90=5-;0/<1/E1-R).F*.70)R/(j9.:794?5B6A1>-:+;*v>)v8,s9-{@4G>NEdVzq{v|egdePfP4=0*&#.$&+**)+,'+/''-)$"W\H~j{j~oo}t~{olLVD782782994<:5@=8B:8A95=73<75:549009//61.62.63.641973?72B90H=1J>4H=4B80@61?62<94C54A50<6*E5'c6-=;BAC;>6A5~:/y;/u>.z4)PL[VpJ9kS@s`IzXf`zr~vxooXiM?;)3)"%+!+/&:&*C))TN:hqRhWk\nckhsttthdNXC8939:4>>8A?:D?:FA<EA:E@:G?8E=4D;1C:3C:3<8095/94/<70B<0I=0OA2P@5K<4E:1A:1=<3G70EJGIC:KHF9?3C5E1@2>BCEvC9y:4<HEGUPpYC`jHlSSZ(H)K@VM_Yhfnjr_mWkPbFOR.(>3(G@-e^:w\n\mYsd~{d}_S_G671681==8B@;FA?HC>HC>JD<MB7J=0H<-F=/E;0A91<71:7.>9,E</M?/OA0O>1K;1D:/>=17=0B@K]35;#?5;0>3D7:(>2>88?<<D?7;.'B:dOcJc^;EBCFO.E,H0T4\:h:oArGoZx[fa=3HC/vdӰg{eWgL330551883=<6DC9GG>JI;MI6IE7MHJH@9E;+C9-?80>83=71>94@=9IA6P@-H?-K81C745=0@?/I@4+4!A&:$6'=2A1@2@48)1+++0)6%5!9,UIUQAK?A;.E;AD>HAQ=V>h>qEwJnWxY]nnd҅un10-/.,43/892>?5GD;OK8MK4XWW|x[ToF?O94462&52):9.B=-K@/P@/C;*:4)040B1-6<;/<';%>,=1;19*:+?23*4,8.1+/(5 4!9,?6CAA>>39(=-E@FKDKDXBbJtK}MzTtCc{_T:8163-30+74,<;2IA6VJ9TH:dar䬲쏏nmLIX@?M<99A=(BC.8A9:EQEUaFSRaG<F7=+A-;(6*80:482:3;2?71'-(-(2(7!7"5(C<VM>2:#:)@7HFGHFJO\F`JnRzXzUqSg`pKU᪤D@5A=3;6-52(:5/F=7TG6WF7]Ujޫ|f\RLs7:C:97RJNs]{KP<'9#:*;-<3;361>9<78/D9?4))++2,2%<(:*7-LHC@9$9(>2QIE>NIQSTaVnNoUxWoZiWeOTtnOI;MG:F@5?90=60A=8ME5SD.WLS틍ozaeN_OWL]HR;>>>>5>/?2>49/3+7/8/3)3$9">08;052054537+>/PJEI=38+<-C2=-H=NJ\afvPmZurxbp{ueVPAWN?VM?PI:KB4F<1E@7LG5SG.VNQvAN<?;7@1F;=A9<@:E96(2+41;/7)4!6!7&5)5+8.42-5*01)5$LAHIMK8.:(;';*</@3^Vnmgpgqtrouz|AQ3[PA[OAYM?TJ:TG9NG<RJ9WK4XQTԕ䙢씟؈Їi=P@:>C?F>;GF>A?;=1?0;+:.933/4.8*;+;6<99%9!3&5/7+8&=)>5@BUSG=9):*<-<.:*VGmjagbmnqdlWpuiXnE[N>ZN>[N=XM<ZL<WK?XL<ZL8ULGd_uwx{{fm|Rb;F3?E>CNBG@5C;41B5;)9%:%8(4+13,3-1.8(>(00'8(;2=4D66&5)75./4*5*J>>16*:+7&H>qrs~r{s{VeDa}}g̮Ưʪǚպ[L<[L<\L<YI;ZK;[L>^M<^P<[NAYLI^Sdmeě~q@G>+@9<@BJ<79(B8;8D:7$;(8'4'9.4',$)'%26'6<D1:0:+.85GG64;65*8&8+QG<391:38+8-kkzrMd?\^gQ|\a~QeYyhtyŵ[K:[K:YK:YI9[K:]J<^K<^O;^O;_N:_KHaWw|w‡ew4K@FC@BGC@;.8&@68;MEPA6(4*601/19-<*<-H.WQc\m8O057&C6SNC@9.7$;%8)FB833100914'\W|k|Ha>UYa7eNd~mpopoqÿ\K7\K6\K6]L7]L9]L;^M=]P=]P=aM:cG>g]quqKU?Q=G<=>4;*>/833+9'MAA3:.792>"/ -!+%7;VcpNS:56$-:086IE;08+8+8/J@3..1-02,4%ME{Yt?a@SIY1p[oq|f~fk~en^M:^M:^M:^M:^M:_L7^N9VNAaXYo`mmdppxꙃ͹v|d\MU9A77B2:+G>B96+6'4.D7<.03DNCG/-,(23>C?C783.OJOQIGUUEAB:<72=7?>:1*20.20.4%H<qFh<dAGNb<rZycu`v_zd{d{Zhvlg_O=_O?_O>_O=_O=`P7\L9_[a}|}qv|ƚǺȶpRLAHJ79:27.I?fX@32+1,=17)-)55RXJQQVV[@B9?-7JVozfvRN53A<E<40,:5?634*2/.2/-5)<3bw>cAd\;/L_>u^{coWrXx^y[wVahe|V[M=_P@_RB`RC`R@\OBcYawww|cjzz֯諸ydlgWZ6:63:1OAXI1'><@70%-'3*95SWVbdoag/7(6FS^fT[73648280:5;;655+6*0-/40/9.82wRp<dJ[=<&AJ0h~StXhLmQsZsTlMbENj4Ia4TH8YL<_RBbVD`S?f]b{ytz]flv·ojejdyugeDA=5<1B2<-GFIF70609+:&=6:A[gW^73BI?F79565130:/;36578646-7(1+350/4*DBhu;d@hMGRP<EB-O_9iLeDgKnUhL^EY}CWoB[sDDB6JE<\M>`S>e_Xztsp]_iiߝޢ֠֞Εpg}^VR|SHYQys|^Z6-5#;*:07,9/8/<*@1=473PLKB6$/0(:'?:#8.6:5<57535407)9&6&5-5)4'V\Pk8e@X95#AB378!QZ4dyN_AcDlNhGcIcJfIbD47-::4OD;VL=gelljQQ[]y{Ή݌ш͈ҍȇ~Zj\[LpWDSVfkz;-;#;)6+;+6(:-8(:-:/:0?5:.1'/7+=*>$:&95=:6;454486/7)8&6$9&;%=4Wl7cCjk3=#/%/4^Y2s`]>mKpQkHiMeJfHgG*0&+0+975EC=Z\i\][Zy|օ낂ځʃҋۍ~xsWR`_Hd_CWPZcnjK@7&<'8+1(>+:(G;9+:)7(7(</;06;1?-;36587;6585:8786;848*:):'=!<&KMBg6gCO3648+/DN)y՚q\]=rNoRfEgMeKfGkJ.2&+.(01+:=0LONXVmnlꓐфǍΎwla]^]Gf]Ij\EYCRQ==0+7&7&5+5)=+<+D98):(9(4(2);48</:EJVQA=8284888<7<59;68)=*=*9#5)P`=_I]K@1-3%J3'eԌ|Kc9`=lIdGeCkOiOfEpP@>0>=4<=2AE*LM:UTAecgzwszyon_WlYGh\Kj^N_OK<5.0+4*8$=$9,;)7&=5IB9':)9-<4;7:886HIZXC=:79284688>6=7;?7;+;';(6#IDUhMX]O39"FO)u_ijIT<<H,g~CjFaEkKlPoQmMvVUM>VM?VN?VP=\RC`WBbYKmckwj|pdm]W[WUR]VGfZFn_HjdOZORG:,4+7/7.6*9):,<+5"9-<4H:B9>9<<68;8=29*;-<56:6:86929688;=@8;,;(8$6'YZTVYRcK`x;qvYO];;=.23+;C1fGoJjMmRjGqKxUqWcZKe[Ke[Kd[Le[Mg_Jh_Hg^Mg]Lf\I`ZGQN=LH7SP>[ZF__OaYJL40=):*9+8*7*:+=/5?)7*9/496<6;5<648&9&:)>4986785<3>9>>@;8+:(:(7"~:*RJTI\Sn]sScB'258176/9909C0gKwQpSpOoIxUwY`Jh_Pi`Qi`Qi`Qh_PkbTjbSi`PibLibHhbK`ZFLJ6@E4@H8CJ>UM;XODF:,7%8):):(9);/698*;5@E>;61:59->*A+<'6)<5=7?6D9A9838*8'<)};(w3"A3SGZNYSYMAM+'2%7><KM@=;(7:/8@-hKvPqPpJyV}bbI`Li`Qi`Qi`QjaRjaQk_Zk__kaVkaTkaXlaRkbNZVDDF8<C55C1?C)ZF]YJM;09+<0=1>2@:>3C3HAIEEA=/F2C1yA-:+<,=,8*:.;0?1<.6*7,<,;*{;,s9*v5(H;OBSNVWo_fvIGV4^kQKQ5:;#88/8B/iLwPpNrP}`fNbJbMi`Qi`Qh_PlcTkbSmbWlbUldOldPlbVmbUmcThaQVP@EA18A'K@>@NOimNJC<E?HCIFGKLKIHACBA@==0A2<1:3;2~;1z;/z;+{:+8,8,8(:*<,8+{3(y6,p4)v=1Q@TGQM[SWX@Oe=`vFCW-6@*:<279/8@-_yAxQpQwYjS\GgJaIi`QjaRlbTjaRjaRkbSkbSkbRlcSlcTpbRpaUf_RfaP_YCA@%rM<ECBCONLLCB@9E;DE@ECEDCA>B>A<9/=/<382;/;.:-|:.|:/{91{8/|9.z:.x9/u8.r6+o4*l2'v@6TLQMUMyeOZnJUmDM_:9C(89,;=34;089)Vd>tTx\r\ZC_IeL\GhaQibRjdSibRibRjbSkbSkbSlcTlcTmaTfZPspi}{j7>+3<(<=/?;.^B5HEAE><DADDDDFDF?F=D>=4=,~>/9.:+:+:,~:/~:0{90y8/w9/v90t:.q6-n3+k4)e1%s=2RNYR_R_\HES;2?);E0BJ69A04;.49578,LW3rS{^`IZ~CaIaKX|GhbRibRkcSibRibRjbSkbSlcTlcTkbRe]S|ՠ|CJ25?+:72*0+Z?>XU9:@DBDABC?E;B:B8;,=,<+:+}9-}9/}:0|:1w:3s8/p6,o8-n7+n6/k4,g3*`.$p8/UQz\ONO>5@1/5,330.3+4>1;K80>.-2/54+AM/sYnTTu?Z|E_L_IWwHhcShcShcShcShcSjcSlcTmdUmdUlbQlje̝KO1=6)OHFqq=:@<@@>?B=@<C<;1=/~<,:.{9/|90{<3z<4p;1k8-i7-h8-h8.k70i6-a0'Y+m=4vTNG@3.9)1<.7:2686280-9*6D29H616,,-"@J1zm^MQo<VsB\yGbLQjEgdSgdRgdRgdRfdRicRlcUmdUmdSjaQdddrnWAJ<޲OA80A<B=E@?;<3=3~<1~:.|9/|90z92v80j8/h8/f7,e7-e7,i60i70f6.h;2nLB88314,37-56+37)/9+09*.8*/8,8A2;C201$DM:ojGj=Lk<Li;WuFbNCV;heVheWheWheWheWieVkdZneWhfQnlhٸpsWo{jػj^8+@6H9E6B7?6;2}92x8/u7.s7.o5+j70h70f5/g6/i70l71l</gF4q_nk[)2(17.07-16*05,/3-/3-/4..1,.5.2?43@3@M:IX@BU8Mg@Gb9XrJ]xT4D5heVheVheVheVheVgeUkd[ndXghP}~ҷǣE49.<9:;@=pB<q@6q?5o?4j<2h:1q62m51j7/g91g>4fF9cJ5_M5iQYF*1(07,17-06,/3,-2-.3--2,,0+,3,)4--8-2>-2>*6C.DV;H]=^qRZlS,8.heVheVheVifWifWjeVlc\ngZhiQlupԼkS?.6*8,oA3r=7s?9sA;o?8n=6q94l:3d=2^>2P;+UP9]X=]]?nv\2@+27/28.39/28-/5,.3-.3-,1+*/)+0++3+*4,-5,7@59C43>,>J4\hTQ]O+4-gdUheVifWifWifWjeVnc\lhZflShwoìu]yH1e6"e3)j90l?4i>4h>2cA7_D5YG5e]GEF/9C'EI+ppR\`G29'7=57=37>48>38<57;66;5271.3-,1+(.(*.*,1,/2/=D==J81?(BP<EPD/90ddSgdUhgWieWhfWkeVnd\lhZdkRdwoҶƿѽhS;XD,]K2\L4VO:QN7MO8^gK@L0=E*GJ+igJ`YDFF5:?5:>58>49?59@8;A;:>9:@:9=87;6062,1,+/.)-.)3)6J29L38I1;K8/;.\gO_iRgkWihXlfXlgYkf[hgYelY|ɾmgKRK-UO2SO3PN4LO6HO5EN.LS0]e@aeFVV=WT<UR9MI6CB5<?58A58C59A79A6:B7;C8<E<;E:9@55=66D/G`5Gb<:M8@R:H\A4B1 \ No newline at end of file
diff --git a/wand/magick_compat.c b/wand/magick_compat.c
new file mode 100644
index 0000000..9e6893a
--- /dev/null
+++ b/wand/magick_compat.c
@@ -0,0 +1,714 @@
+/*
+% Copyright (C) 2003-2012 GraphicsMagick Group
+% Copyright (C) 2003 ImageMagick Studio
+%
+% This program is covered by multiple licenses, which are described in
+% Copyright.txt. You should have received a copy of Copyright.txt with this
+% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% IIIII M M CCCC OOO M M PPPP AAA TTTTT %
+% I MM MM C O O MM MM P P A A T %
+% I M M M C O O M M M PPPP AAAAA T %
+% I M M C O O M M P A A T %
+% IIIII M M CCCC OOO M M P A A T %
+% %
+% %
+% ImageMagick Compatability Methods %
+% %
+% %
+% Software Design %
+% John Cristy %
+% January 2003 %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+% THIS MODULE IS SCHEDULED FOR DELETION. IT CONTAINS DEAD CODE WHICH REMAINS
+% ONLY TO SUPPORT THE PREVIOUSLY EXISTING ABI.
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/constitute.h"
+#include "magick/error.h"
+#include "magick/utility.h"
+#include "wand/wand_api.h"
+#include "wand/wand_private.h"
+
+/*
+ Legacy definitions to compile code below with same exported symbols as
+ before.
+*/
+#define AcquireMagickMemory(memory) malloc(memory)
+#define AcquireUniqueFileResource(char_pointer) AcquireTemporaryFileName(char_pointer)
+ /* #define CopyMagickString GMPrivateCopyMagickString */
+ /* #define FormatMagickString GMPrivateFormatMagickString */
+#define GetAffineMatrix(affine_matrix) IdentityAffine(affine_matrix)
+#define InheritException(copy,original) CopyException(copy,original)
+#define RelinquishUniqueFileResource LiberateTemporaryFile
+#define ThrowMagickException ThrowException
+
+#define PsiNegative YNegative
+#define PsiValue XValue
+#define RhoValue WidthValue
+#define SigmaValue HeightValue
+#define XiNegative XNegative
+#define XiValue YValue
+
+#define ConcatenateMagickString GMPrivateConcatenateMagickString
+#define GeometryInfo GMPrivateGeometryInfo
+#define ImportImagePixels GMPrivateImportImagePixels
+#define ParseAbsoluteGeometry GMPrivateParseAbsoluteGeometry
+#define ParseGeometry GMPrivateParseGeometry
+#define RelinquishMagickMemory GMPrivateRelinquishMagickMemory
+#define ResizeMagickMemory GMPrivateResizeMagickMemory
+#define SetGeometryInfo GMPrivateSetGeometryInfo
+#define _GeometryInfo _GMPrivateGeometryInfo
+
+#define ExportImagePixels DispatchImage
+
+typedef struct _GeometryInfo
+{
+ double
+ rho,
+ sigma,
+ xi,
+ psi;
+} GeometryInfo;
+
+typedef struct _MagickPixelPacket
+{
+ ColorspaceType
+ colorspace;
+
+ unsigned int
+ matte;
+
+ Quantum
+ red,
+ green,
+ blue,
+ opacity;
+
+ IndexPacket
+ index;
+} MagickPixelPacket;
+
+
+extern WandExport void
+ *RelinquishMagickMemory(void *),
+ *ResizeMagickMemory(void *memory,const size_t size),
+ SetGeometryInfo(GeometryInfo *geometry_info);
+
+extern WandExport int
+ FormatMagickString(char *,const size_t,const char *,...)
+ MAGICK_ATTRIBUTE((format (printf,3,4))),
+ FormatMagickStringList(char *string,const size_t length,
+ const char *format,va_list operands);
+
+extern WandExport unsigned int
+ ImportImagePixels(Image *image,const long x_offset,
+ const long y_offset,const unsigned long columns,const unsigned long rows,
+ const char *map,const StorageType type,const void *pixels),
+ ParseAbsoluteGeometry(const char *geometry,RectangleInfo *region_info),
+ ParseGeometry(const char *geometry,GeometryInfo *geometry_info),
+ QueryMagickColor(const char *,MagickPixelPacket *,ExceptionInfo *);
+
+extern WandExport size_t
+ ConcatenateMagickString(char *,const char *,const size_t),
+ CopyMagickString(char *,const char *,const size_t);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o p y M a g i c k S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CopyMagickString() copies the source string to the destination string. The
+% destination buffer is always null-terminated even if the string must be
+% truncated.
+%
+% The format of the CopyMagickString method is:
+%
+% size_t CopyMagickString(const char *destination,char *source,
+% const size_t length)
+%
+% A description of each parameter follows:
+%
+% o destination: The destination string.
+%
+% o source: The source string.
+%
+% o length: The length of the destination string.
+%
+%
+*/
+WandExport size_t CopyMagickString(char *destination,const char *source,
+ const size_t length)
+{
+ return(strlcpy(destination,source,length));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% F o r m a t M a g i c k S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% FormatMagickString() prints formatted output of a variable argument list.
+%
+% The format of the FormatMagickString method is:
+%
+% void FormatMagickString(char *string,const size_t length,
+% const char *format,...)
+%
+% A description of each parameter follows.
+%
+% o string: FormatMagickString() returns the formatted string in this
+% character buffer.
+%
+% o length: The maximum length of the string.
+%
+% o format: A string describing the format to use to write the remaining
+% arguments.
+%
+%
+*/
+WandExport int FormatMagickStringList(char *string,const size_t length,
+ const char *format,va_list operands)
+{
+ int
+ count;
+
+#if defined(HAVE_VSNPRINTF)
+ count=vsnprintf(string,length,format,operands);
+#else
+ count=vsprintf(string,format,operands);
+#endif
+
+ return(count);
+}
+WandExport int FormatMagickString(char *string,const size_t length,
+ const char *format,...)
+{
+ int
+ count;
+
+ va_list
+ operands;
+
+ va_start(operands, format);
+ count=FormatMagickStringList(string,length,format,operands);
+ va_end(operands);
+ return (count);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C o n c a t e n a t e M a g i c k S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ConcatenateMagickString() concatenates the source string to the destination
+% string. The destination buffer is always null-terminated even if the
+% string must be truncated.
+%
+% The format of the ConcatenateMagickString method is:
+%
+% size_t ConcatenateMagickString(char *destination,const char *source,
+% const size_t length)
+%
+% A description of each parameter follows:
+%
+% o destination: The destination string.
+%
+% o source: The source string.
+%
+% o length: The length of the destination string.
+%
+%
+*/
+WandExport size_t ConcatenateMagickString(char *destination,
+ const char *source,const size_t length)
+{
+ return(strlcat(destination,source,length));
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% I m p o r t I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ImportImagePixels() accepts pixel data and stores in the image at the
+% location you specify. The method returns True on success otherwise False
+% if an error is encountered. The pixel data can be either char, short int,
+% int, long, float, or double in the order specified by map.
+%
+% Suppose your want want to upload the first scanline of a 640x480 image from
+% character data in red-green-blue order:
+%
+% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
+%
+% The format of the ImportImagePixels method is:
+%
+% unsigned int ImportImagePixels(Image *image,const long x_offset,
+% const long y_offset,const unsigned long columns,
+% const unsigned long rows,const char *map,const StorageType type,
+% const void *pixels)
+%
+% A description of each parameter follows:
+%
+% o image: The image.
+%
+% o x_offset, y_offset: Offset (from top left) on base image on which
+% to composite image data.
+%
+% o map: This string reflects the expected ordering of the pixel array.
+% It can be any combination or order of R = red, G = green, B = blue,
+% A = alpha (same as Transparency), O = Opacity, T = Transparency,
+% C = cyan, Y = yellow, M = magenta, K = black, or I = intensity
+% (for grayscale). Specify "P" = pad, to skip over a quantum which is
+% intentionally ignored. Creation of an alpha channel for CMYK images
+% is currently not supported.
+%
+% o type: Define the data type of the pixels. Float and double types are
+% normalized to [0..1] otherwise [0..MaxRGB]. Choose from these types:
+% CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel, or
+% DoublePixel.
+%
+% o pixels: This array of values contain the pixel components as defined by
+% map and type. You must preallocate this array where the expected
+% length varies depending on the values of width, height, map, and type.
+%
+%
+*/
+WandExport unsigned int ImportImagePixels(Image *image,const long x_offset,
+ const long y_offset,const unsigned long columns,const unsigned long rows,
+ const char *map,const StorageType type,const void *pixels)
+{
+ Image
+ *constitute_image;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ constitute_image=
+ ConstituteImage(columns,rows,map,type,pixels,&image->exception);
+ if (constitute_image)
+ {
+ (void) CompositeImage(image,CopyCompositeOp,constitute_image,x_offset,
+ y_offset);
+ DestroyImage(constitute_image);
+ return (image->exception.severity == UndefinedException);
+ }
+ return (False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P a r s e A b s o l u t e G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ParseAbsoluteGeometry() returns a region as defined by the geometry string.
+%
+% The format of the ParseAbsoluteGeometry method is:
+%
+% unsigned int ParseAbsoluteGeometry(const char *geometry,
+% RectangeInfo *region_info)
+%
+% A description of each parameter follows:
+%
+% o geometry: The geometry (e.g. 100x100+10+10).
+%
+% o region_info: The region as defined by the geometry string.
+%
+%
+*/
+WandExport unsigned int ParseAbsoluteGeometry(const char *geometry,
+ RectangleInfo *region_info)
+{
+ unsigned int
+ flags;
+
+ flags=GetGeometry(geometry,&region_info->x,&region_info->y,
+ &region_info->width,&region_info->height);
+ return(flags);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P a r s e G e o m e t r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ParseGeometry() parses a geometry specification and returns the sigma,
+% rho, xi, and psi values. It also returns flags that indicates which
+% of the four values (sigma, rho, xi, psi) were located in the string, and
+% whether the xi or pi values are negative. In addition, there are flags to
+% report any meta characters (%, !, <, or >).
+%
+% The format of the ParseGeometry method is:
+%
+% unsigned int ParseGeometry(const char *geometry,
+% GeometryInfo *geometry_info)
+%
+% A description of each parameter follows:
+%
+% o geometry: The geometry.
+%
+% o geometry_info: returns the parsed width/height/x/y in this structure.
+%
+%
+*/
+static inline char *MoveStringForward(char *dst,const char *src,size_t dstlen)
+{
+ const size_t srclen = strlen(src);
+ const size_t movelen = Min(dstlen,srclen+1);
+ (void) memmove(dst,src,movelen);
+ dst[movelen-1]='\0';
+ return dst;
+}
+WandExport unsigned int ParseGeometry(const char *geometry,
+ GeometryInfo *geometry_info)
+{
+ char
+ *p,
+ pedantic_geometry[MaxTextExtent],
+ *q;
+
+ unsigned int
+ flags;
+
+ double
+ double_val;
+
+ /*
+ Remove whitespaces meta characters from geometry specification.
+ */
+ assert(geometry_info != (GeometryInfo *) NULL);
+ flags=NoValue;
+ if ((geometry == (char *) NULL) || (*geometry == '\0'))
+ return(flags);
+ if (strlcpy(pedantic_geometry,geometry,sizeof(pedantic_geometry))
+ >= sizeof(pedantic_geometry))
+ return(flags);
+ for (p=pedantic_geometry; *p != '\0'; )
+ {
+ if (isspace((int) (*p)))
+ {
+ (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
+ continue;
+ }
+ switch (*p)
+ {
+ case '%':
+ {
+ flags|=PercentValue;
+ (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
+ break;
+ }
+ case '!':
+ {
+ flags|=AspectValue;
+ (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
+ break;
+ }
+ case '<':
+ {
+ flags|=LessValue;
+ (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
+ break;
+ }
+ case '>':
+ {
+ flags|=GreaterValue;
+ (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
+ break;
+ }
+ case '@':
+ {
+ flags|=AreaValue;
+ (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
+ break;
+ }
+ case '-':
+ case '.':
+ case '+':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'x':
+ case 'X':
+ case ',':
+ case '/':
+ {
+ p++;
+ break;
+ }
+ default:
+ {
+ ExceptionInfo
+ exception;
+
+ Image
+ *image;
+
+ ImageInfo
+ *image_info;
+
+ /*
+ See if we can grab geometry from an image.
+ */
+ GetExceptionInfo(&exception);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ (void) strlcpy(image_info->filename,geometry,sizeof(image_info->filename));
+ image=PingImage(image_info,&exception);
+ if (image != (Image *) NULL)
+ {
+ geometry_info->rho=image->columns;
+ geometry_info->sigma=image->rows;
+ flags|=RhoValue | SigmaValue;
+ DestroyImage(image);
+ }
+ DestroyImageInfo(image_info);
+ DestroyExceptionInfo(&exception);
+ return(flags);
+ }
+ }
+ }
+ /*
+ Parse rho, sigma, xi, and psi.
+ */
+ p=pedantic_geometry;
+ if (*p == '\0')
+ return(flags);
+ q=p;
+ double_val=strtod(p,&q);
+ (void) double_val;
+ if ((*q == 'x') || (*q == 'X') || (*q == '/') || (*q == ',') || (*q =='\0'))
+ {
+ /*
+ Parse rho.
+ */
+ q=p;
+ if (LocaleNCompare(p,"0x",2) == 0)
+ geometry_info->rho=strtol(p,&p,10);
+ else
+ geometry_info->rho=strtod(p,&p);
+ if (p != q)
+ flags|=RhoValue;
+ }
+ if ((*p == 'x') || (*p == 'X') || (*p == '/') || (*p == ','))
+ {
+ /*
+ Parse sigma.
+ */
+ p++;
+ q=p;
+ geometry_info->sigma=strtod(p,&p);
+ if (p != q)
+ flags|=SigmaValue;
+ }
+ if ((*p == '+') || (*p == '-') || (*p == ',') || (*p == '/'))
+ {
+ /*
+ Parse xi value.
+ */
+ if ((*p == ',') || (*p == '/'))
+ p++;
+ q=p;
+ geometry_info->xi=strtod(p,&p);
+ if (p != q)
+ {
+ flags|=XiValue;
+ if (*q == '-')
+ flags|=XiNegative;
+ }
+ if ((*p == '+') || (*p == '-') || (*p == ',') || (*p == '/'))
+ {
+ /*
+ Parse psi value.
+ */
+ if ((*p == ',') || (*p == '/'))
+ p++;
+ q=p;
+ geometry_info->psi=strtod(p,&p);
+ if (p != q)
+ {
+ flags|=PsiValue;
+ if (*q == '-')
+ flags|=PsiNegative;
+ }
+ }
+ }
+ return(flags);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e l i n q u i s h M a g i c k M e m o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% RelinquishMagickMemory() frees memory that has already been allocated with
+% AcquireMagickMemory().
+%
+% The format of the RelinquishMagickMemory method is:
+%
+% void *RelinquishMagickMemory(void *memory)
+%
+% A description of each parameter follows:
+%
+% o memory: A pointer to a block of memory to free for reuse.
+%
+%
+*/
+WandExport void *RelinquishMagickMemory(void *memory)
+{
+ if (memory == (void *) NULL)
+ return((void *) NULL);
+ free(memory);
+ return((void *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% R e s i z e M a g i c k M e m o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ResizeMagickMemory() changes the size of the memory and returns a pointer to
+% the (possibly moved) block. The contents will be unchanged up to the
+% lesser of the new and old sizes.
+%
+% The format of the ResizeMagickMemory method is:
+%
+% void *ResizeMagickMemory(void *memory,const size_t size)
+%
+% A description of each parameter follows:
+%
+% o memory: A pointer to a memory allocation. On return the pointer
+% may change but the contents of the original allocation will not.
+%
+% o size: The new size of the allocated memory.
+%
+%
+*/
+WandExport void *ResizeMagickMemory(void *memory,const size_t size)
+{
+ void
+ *allocation;
+
+ if (memory == (void *) NULL)
+ return(AcquireMagickMemory(size));
+ allocation=realloc(memory,size);
+ if (allocation == (void *) NULL)
+ (void) RelinquishMagickMemory(memory);
+ return(allocation);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% Q u e r y M a g i c k C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% QueryMagickColor() returns the red, green, blue, and opacity intensities
+% for a given color name.
+%
+% The format of the QueryMagickColor method is:
+%
+% unsigned int QueryMagickColor(const char *name,MagickPixelPacket *color,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o name: The color name (e.g. white, blue, yellow).
+%
+% o color: The red, green, blue, and opacity intensities values of the
+% named color in this structure.
+%
+% o exception: Return any errors or warnings in this structure.
+%
+%
+*/
+WandExport unsigned int QueryMagickColor(const char *name,
+ MagickPixelPacket *color,ExceptionInfo *exception)
+{
+ PixelPacket
+ pixel;
+
+ unsigned int
+ status;
+
+ status=QueryColorDatabase(name,&pixel,exception);
+ color->colorspace=RGBColorspace;
+ color->matte=0;
+ color->red=pixel.red;
+ color->green=pixel.green;
+ color->blue=pixel.blue;
+ color->opacity=pixel.opacity;
+ color->index=0;
+ return status;
+}
diff --git a/wand/magick_wand.c b/wand/magick_wand.c
new file mode 100644
index 0000000..e3df549
--- /dev/null
+++ b/wand/magick_wand.c
@@ -0,0 +1,10954 @@
+/* Copyright (C) 2003-2017 GraphicsMagick Group */
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M AAA GGGG IIIII CCCC K K %
+% MM MM A A G I C K K %
+% M M M AAAAA G GGG I C KKK %
+% M M A A G G I C K K %
+% M M A A GGGG IIIII CCCC K K %
+% %
+% W W AAA N N DDDD %
+% W W A A NN N D D %
+% W W W AAAAA N N N D D %
+% WW WW A A N NN D D %
+% W W A A N N DDDD %
+% %
+% %
+% ImageMagick MagickWand Programming Interface %
+% %
+% Software Design %
+% John Cristy %
+% August 2003 %
+% %
+% %
+% Copyright (C) 1999-2004 ImageMagick Studio LLC, a non-profit organization %
+% dedicated to making software imaging solutions freely available. %
+% %
+% This software and documentation is provided "as is," and the copyright %
+% holders and contributing author(s) make no representations or warranties, %
+% express or implied, including but not limited to, warranties of %
+% merchantability or fitness for any particular purpose or that the use of %
+% the software or documentation will not infringe any third party patents, %
+% copyrights, trademarks or other rights. %
+% %
+% The copyright holders and contributing author(s) will not be held liable %
+% for any direct, indirect, special or consequential damages arising out of %
+% any use of the software or documentation, even if advised of the %
+% possibility of such damage. %
+% %
+% Permission is hereby granted to use, copy, modify, and distribute this %
+% source code, or portions hereof, documentation and executables, for any %
+% purpose, without fee, subject to the following restrictions: %
+% %
+% 1. The origin of this source code must not be misrepresented. %
+% 2. Altered versions must be plainly marked as such and must not be %
+% misrepresented as being the original source. %
+% 3. This Copyright notice may not be removed or altered from any source %
+% or altered source distribution. %
+% %
+% The copyright holders and contributing author(s) specifically permit, %
+% without fee, and encourage the use of this source code as a component for %
+% supporting image processing in commercial products. If you use this %
+% source code in a product, acknowledgment is not required but would be %
+% appreciated. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+
+/*
+ * This version has been modified by Bob Friesenhahn for use with
+ * GraphicsMagick.
+ *
+ * The following functions are not implemented at this time and always
+ * return False:
+ *
+ * MagickFxImage
+ * MagickFxImageChannel
+ * MagickGetConfigureInfo
+ * MagickPreviewImages
+ * MagickRadialBlurImage
+ * MagickTintImage
+ *
+ */
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/attribute.h"
+#include "magick/blob.h"
+#include "magick/error.h"
+#include "magick/image.h"
+#include "magick/list.h"
+#include "magick/paint.h"
+#include "magick/quantize.h"
+#include "magick/resize.h"
+#include "magick/resource.h"
+#include "wand/magick_wand.h"
+#include "wand/wand_private.h"
+
+/*
+ Define declarations.
+*/
+#define ThrowWandException(code,reason,description) \
+{ \
+ ThrowException(&wand->exception,code,reason,description); \
+ return(False); \
+}
+
+
+/*
+ Typedef declarations.
+*/
+struct _MagickWand
+{
+ char
+ id[MaxTextExtent];
+
+ ExceptionInfo
+ exception;
+
+ ImageInfo
+ *image_info;
+
+ QuantizeInfo
+ *quantize_info;
+
+ Image
+ *image, /* Current working image */
+ *images; /* Whole image list */
+
+ unsigned int
+ iterator;
+
+ unsigned long
+ signature;
+};
+
+/*
+ Forward declarations.
+*/
+static unsigned long
+ GetMagickWandId(void);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e M a g i c k W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneMagickWand() makes an exact copy of the specified wand.
+%
+% The format of the CloneMagickWand method is:
+%
+% MagickWand *CloneMagickWand(const MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand to clone.
+%
+*/
+WandExport MagickWand *CloneMagickWand(const MagickWand *wand)
+{
+ MagickWand
+ *clone_wand;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ clone_wand=MagickAllocateMemory(MagickWand *,sizeof(MagickWand));
+ if (clone_wand == (MagickWand *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateImage);
+ (void) memset(clone_wand,0,sizeof(MagickWand));
+ (void) MagickFormatString(clone_wand->id,MaxTextExtent,"MagickWand-%lu",
+ GetMagickWandId());
+ GetExceptionInfo(&clone_wand->exception);
+ CopyException(&clone_wand->exception,&wand->exception);
+ clone_wand->image_info=CloneImageInfo(wand->image_info);
+ clone_wand->quantize_info=CloneQuantizeInfo(wand->quantize_info);
+ clone_wand->images=CloneImageList(wand->images,&clone_wand->exception);
+ clone_wand->image=clone_wand->images;
+ clone_wand->signature=MagickSignature;
+ return(clone_wand);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ C l o n e M a g i c k W a n d W i t h I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% CloneMagickWandWithImages() clones the magick wand and inserts a new image
+% list.
+%
+% The format of the CloneMagickWandWithImages method is:
+%
+% MagickWand *CloneMagickWandWithImages(const MagickWand *wand,
+% Image *images)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o images: replace the image list with these image(s).
+%
+*/
+static MagickWand *CloneMagickWandWithImages(const MagickWand *wand,
+ Image *images)
+{
+ MagickWand
+ *clone_wand;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ clone_wand=MagickAllocateMemory(MagickWand *,sizeof(MagickWand));
+ if (clone_wand == (MagickWand *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateWand);
+ (void) memset(clone_wand,0,sizeof(MagickWand));
+ (void) MagickFormatString(clone_wand->id,MaxTextExtent,"MagickWand-%lu",
+ GetMagickWandId());
+ GetExceptionInfo(&clone_wand->exception);
+ CopyException(&clone_wand->exception,&wand->exception);
+ clone_wand->image_info=CloneImageInfo(wand->image_info);
+ clone_wand->quantize_info=CloneQuantizeInfo(wand->quantize_info);
+ clone_wand->images=images;
+ clone_wand->image=clone_wand->images;
+ clone_wand->signature=MagickSignature;
+ return(clone_wand);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y M a g i c k W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyMagickWand() deallocates memory associated with an MagickWand.
+%
+% The format of the DestroyMagickWand method is:
+%
+% void DestroyMagickWand(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+%
+*/
+WandExport unsigned int DestroyMagickWand(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ DestroyQuantizeInfo(wand->quantize_info);
+ DestroyImageInfo(wand->image_info);
+ DestroyExceptionInfo(&wand->exception);
+ DestroyImageList(wand->images);
+ MagickFreeMemory(wand);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A d a p t i v e T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAdaptiveThresholdImage() selects an individual threshold for each pixel
+% based on the range of intensity values in its local neighborhood. This
+% allows for thresholding of an image whose global intensity histogram
+% doesn't contain distinctive peaks.
+%
+% The format of the MagickAdaptiveThresholdImage method is:
+%
+% unsigned int MagickAdaptiveThresholdImage(MagickWand *wand,
+% const unsigned long width,const unsigned long height,
+% const long offset)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o width: The width of the local neighborhood.
+%
+% o height: The height of the local neighborhood.
+%
+% o offset: The mean offset.
+%
+*/
+WandExport unsigned int MagickAdaptiveThresholdImage(MagickWand *wand,
+ const unsigned long width,const unsigned long height,const long offset)
+{
+ Image
+ *threshold_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ threshold_image=AdaptiveThresholdImage(wand->image,width,height,offset,
+ &wand->exception);
+ if (threshold_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,threshold_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A d d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAddImage() adds the specified images at the current image location.
+%
+% The format of the MagickAddImage method is:
+%
+% unsigned int MagickAddImage(MagickWand *wand,
+% const MagickWand *add_wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o insert: The splice wand.
+%
+*/
+WandExport unsigned int MagickAddImage(MagickWand *wand,
+ const MagickWand *add_wand)
+{
+ Image
+ *images;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(add_wand != (MagickWand *) NULL);
+ assert(add_wand->signature == MagickSignature);
+ if (add_wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,add_wand->id);
+ images=CloneImageList(add_wand->images,&wand->exception);
+ if (images == (Image *) NULL)
+ return(False);
+ if ((wand->iterator != False) &&
+ (GetPreviousImageInList(wand->image) == (Image *) NULL))
+ PrependImageToList(&wand->image,images);
+ else
+ if ((wand->iterator != False) &&
+ (GetNextImageInList(wand->image) == (Image *) NULL))
+ AppendImageToList(&wand->image,images);
+ else
+ InsertImageInList(&wand->image,images);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M a g i c k A d d N o i s e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAddNoiseImage() adds random noise to the image.
+%
+% The format of the MagickAddNoiseImage method is:
+%
+% unsigned int MagickAddNoiseImage(MagickWand *wand,
+% const NoiseType noise_type)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o noise_type: The type of noise: Uniform, Gaussian, Multiplicative,
+% Impulse, Laplacian, Poisson, or Random.
+%
+*/
+WandExport unsigned int MagickAddNoiseImage(MagickWand *wand,
+ const NoiseType noise_type)
+{
+ Image
+ *noise_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ noise_image=AddNoiseImage(wand->image,noise_type,&wand->exception);
+ if (noise_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,noise_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A f f i n e T r a n s f o r m I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAffineTransformImage() transforms an image as dictated by the affine
+% matrix of the drawing wand.
+%
+% The format of the MagickAffineTransformImage method is:
+%
+% unsigned int MagickAffineTransformImage(MagickWand *wand,
+% const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o drawing_wand: The draw wand.
+%
+*/
+WandExport unsigned int MagickAffineTransformImage(MagickWand *wand,
+ const DrawingWand *drawing_wand)
+{
+ DrawInfo
+ *draw_info;
+
+ Image
+ *affine_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ draw_info=DrawPeekGraphicContext(drawing_wand);
+ if (draw_info == (DrawInfo *) NULL)
+ return(False);
+ affine_image=AffineTransformImage(wand->image,&draw_info->affine,
+ &wand->exception);
+ DestroyDrawInfo(draw_info);
+ if (affine_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,affine_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A n n o t a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAnnotateImage() annotates an image with text.
+%
+% The format of the MagickAnnotateImage method is:
+%
+% unsigned int MagickAnnotateImage(MagickWand *wand,
+% const DrawingWand *drawing_wand,const double x,const double y,
+% const double angle,const char *text)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o drawing_wand: The draw wand.
+%
+% o x: x ordinate to left of text
+%
+% o y: y ordinate to text baseline
+%
+% o angle: rotate text relative to this angle.
+%
+% o text: text to draw
+%
+*/
+WandExport unsigned int MagickAnnotateImage(MagickWand *wand,
+ const DrawingWand *drawing_wand,const double x,const double y,
+ const double angle,const char *text)
+{
+ char
+ geometry[MaxTextExtent];
+
+ DrawInfo
+ *draw_info;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ draw_info=DrawPeekGraphicContext(drawing_wand);
+ if (draw_info == (DrawInfo *) NULL)
+ return(False);
+ (void) CloneString(&draw_info->text,text);
+ (void) MagickFormatString(geometry,MaxTextExtent,"%+f%+f",x,y);
+ draw_info->affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+ draw_info->affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+ draw_info->affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+ draw_info->affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+ (void) CloneString(&draw_info->geometry,geometry);
+ status=AnnotateImage(wand->image,draw_info);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ DestroyDrawInfo(draw_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A n i m a t e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAnimateImages() animates an image or image sequence.
+%
+% The format of the MagickAnimateImages method is:
+%
+% unsigned int MagickAnimateImages(MagickWand *wand,
+% const char *server_name)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o server_name: The X server name.
+%
+%
+*/
+WandExport unsigned int MagickAnimateImages(MagickWand *wand,
+ const char *server_name)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->image_info->server_name=(char *) AcquireString(server_name);
+ status=AnimateImages(wand->image_info,wand->images);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A p p e n d I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAppendImages() append a set of images.
+%
+% The format of the MagickAppendImages method is:
+%
+% MagickWand *MagickAppendImages(MagickWand *wand,
+% const unsigned int stack)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o stack: By default, images are stacked left-to-right. Set stack to True
+% to stack them top-to-bottom.
+%
+*/
+WandExport MagickWand *MagickAppendImages(MagickWand *wand,
+ const unsigned int stack)
+{
+ Image
+ *append_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ append_image=AppendImages(wand->images,stack,&wand->exception);
+ if (append_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,append_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A u t o O r i e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAutoOrientImage() adjusts the current image so that its orientation
+% is suitable for viewing (i.e. top-left orientation).
+%
+% The format of the MagickAutoOrientImage method is:
+%
+% unsigned int MagickAutoOrientImage(MagickWand *wand,
+% const OrientationType current_orientation,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o current_orientation: Current image orientation. May be one of:
+% TopLeftOrientation Left to right and Top to bottom
+% TopRightOrientation Right to left and Top to bottom
+% BottomRightOrientation Right to left and Bottom to top
+% BottomLeftOrientation Left to right and Bottom to top
+% LeftTopOrientation Top to bottom and Left to right
+% RightTopOrientation Top to bottom and Right to left
+% RightBottomOrientation Bottom to top and Right to left
+% LeftBottomOrientation Bottom to top and Left to right
+% UndefinedOrientation Current orientation is not known.
+% Use orientation defined by the
+% current image if any. Equivalent
+% to MagickGetImageOrientation().
+%
+% Returns True on success, False otherwise.
+%
+% Note that after successful auto-orientation the internal orientation will
+% be set to TopLeftOrientation. However this internal value is only written
+% to TIFF files. For JPEG files, there is currently no support for resetting
+% the EXIF orientation tag to TopLeft so the JPEG should be stripped or EXIF
+% profile removed if present to prevent saved auto-oriented images from being
+% incorrectly rotated a second time by follow-on viewers that understand the
+% EXIF orientation tag.
+%
+*/
+WandExport unsigned int MagickAutoOrientImage(MagickWand *wand,
+ const OrientationType current_orientation)
+{
+ Image
+ *orient_image;
+
+ OrientationType
+ orientation;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ orientation = (current_orientation == UndefinedOrientation)
+ ? wand->image->orientation
+ : current_orientation;
+
+ orient_image=AutoOrientImage(wand->image,orientation,&wand->exception);
+ if (orient_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,orient_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k A v e r a g e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAverageImages() average a set of images.
+%
+% The format of the MagickAverageImages method is:
+%
+% MagickWand *MagickAverageImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport MagickWand *MagickAverageImages(MagickWand *wand)
+{
+ Image
+ *average_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ average_image=AverageImages(wand->images,&wand->exception);
+ if (average_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,average_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k B l a c k T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickBlackThresholdImage() is like MagickThresholdImage() but forces all
+% pixels below the threshold into black while leaving all pixels above the
+% threshold unchanged.
+%
+% The format of the MagickBlackThresholdImage method is:
+%
+% unsigned int MagickBlackThresholdImage(MagickWand *wand,
+% const PixelWand *threshold)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o threshold: The pixel wand.
+%
+*/
+WandExport unsigned int MagickBlackThresholdImage(MagickWand *wand,
+ const PixelWand *threshold)
+{
+ char
+ thresholds[MaxTextExtent];
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) MagickFormatString(thresholds,MaxTextExtent,"%u,%u,%u,%u",
+ PixelGetRedQuantum(threshold),PixelGetGreenQuantum(threshold),
+ PixelGetBlueQuantum(threshold),PixelGetOpacityQuantum(threshold));
+ status=BlackThresholdImage(wand->image,thresholds);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k B l u r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickBlurImage() blurs an image. We convolve the image with a Gaussian
+% operator of the given radius and standard deviation (sigma).
+% For reasonable results, the radius should be larger than sigma. Use a
+% radius of 0 and BlurImage() selects a suitable radius for you.
+%
+% The format of the MagickBlurImage method is:
+%
+% unsigned int MagickBlurImage(MagickWand *wand,const double radius,
+% const double sigma)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+*/
+WandExport unsigned int MagickBlurImage(MagickWand *wand,const double radius,
+ const double sigma)
+{
+ Image
+ *blur_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ blur_image=BlurImage(wand->image,radius,sigma,&wand->exception);
+ if (blur_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,blur_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k B o r d e r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickBorderImage() surrounds the image with a border of the color defined
+% by the bordercolor pixel wand.
+%
+% The format of the MagickBorderImage method is:
+%
+% unsigned int MagickBorderImage(MagickWand *wand,
+% const PixelWand *bordercolor,const unsigned long width,
+% const unsigned long height)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o bordercolor: The border color pixel wand.
+%
+% o width: The border width.
+%
+% o height: The border height.
+%
+*/
+WandExport unsigned int MagickBorderImage(MagickWand *wand,
+ const PixelWand *bordercolor,const unsigned long width,
+ const unsigned long height)
+{
+ Image
+ *border_image;
+
+ RectangleInfo
+ border_info;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ border_info.width=width;
+ border_info.height=height;
+ border_info.x=0;
+ border_info.y=0;
+ PixelGetQuantumColor(bordercolor,&wand->image->border_color);
+ border_image=BorderImage(wand->image,&border_info,&wand->exception);
+ if (border_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,border_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M a g i c k C d l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The MagickCdlImage() method applies ("bakes in") the ASC-CDL which is a
+% format for the exchange of basic primary color grading information between
+% equipment and software from different manufacturers. The format defines
+% the math for three functions: slope, offset and power. Each function uses
+% a number for the red, green, and blue color channels for a total of nine
+% numbers comprising a single color decision. A tenth number for chrominance
+% (saturation) has been proposed but is not yet standardized.
+%
+% The cdl argument string is comma delimited and is in the form (but
+% without invervening spaces or line breaks):
+%
+% redslope, redoffset, redpower :
+% greenslope, greenoffset, greenpower :
+% blueslope, blueoffset, bluepower :
+% saturation
+%
+% with the unity (no change) specification being:
+%
+% "1.0,0.0,1.0:1.0,0.0,1.0:1.0,0.0,1.0:0.0"
+%
+% See http://en.wikipedia.org/wiki/ASC_CDL for more information.
+%
+% The format of the MagickCdlImage method is:
+%
+% MagickPassFail MagickCdlImage(MagickWand *wand,const char *cdl)
+%
+% A description of each parameter follows:
+%
+% o wand: The image wand.
+%
+% o cdl: Define the coefficients for slope offset and power in the
+% red green and blue channels, plus saturation.
+%
+*/
+WandExport MagickPassFail MagickCdlImage(MagickWand *wand,const char *cdl)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(cdl != (const char *) NULL);
+
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ return CdlImage(wand->image,cdl);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C h a r c o a l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCharcoalImage() simulates a charcoal drawing.
+%
+% The format of the MagickCharcoalImage method is:
+%
+% unsigned int MagickCharcoalImage(MagickWand *wand,const double radius,
+% const double sigma)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+*/
+WandExport unsigned int MagickCharcoalImage(MagickWand *wand,
+ const double radius,const double sigma)
+{
+ Image
+ *charcoal_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ charcoal_image=CharcoalImage(wand->image,radius,sigma,&wand->exception);
+ if (charcoal_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,charcoal_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C h o p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickChopImage() removes a region of an image and collapses the image to
+% occupy the removed portion
+%
+% The format of the MagickChopImage method is:
+%
+% unsigned int MagickChopImage(MagickWand *wand,const unsigned long width,
+% const unsigned long height,const long x,const long y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o width: The region width.
+%
+% o height: The region height.
+%
+% o x: The region x offset.
+%
+% o y: The region y offset.
+%
+%
+*/
+WandExport unsigned int MagickChopImage(MagickWand *wand,
+ const unsigned long width,const unsigned long height,const long x,
+ const long y)
+{
+ Image
+ *chop_image;
+
+ RectangleInfo
+ chop;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ chop.width=width;
+ chop.height=height;
+ chop.x=x;
+ chop.y=y;
+ chop_image=ChopImage(wand->image,&chop,&wand->exception);
+ if (chop_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,chop_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C l e a r E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickClearException() clears the last wand exception.
+%
+% The format of the MagickClearException method is:
+%
+% void MagickClearException(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport void MagickClearException(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ GetExceptionInfo(&wand->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C l i p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickClipImage() clips along the first path from the 8BIM profile, if
+% present.
+%
+% The format of the MagickClipImage method is:
+%
+% unsigned int MagickClipImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickClipImage(MagickWand *wand)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=ClipImage(wand->image);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C l i p P a t h I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickClipPathImage() clips along the named paths from the 8BIM profile, if
+% present. Later operations take effect inside the path. Id may be a number
+% if preceded with #, to work on a numbered path, e.g., "#1" to use the first
+% path.
+%
+% The format of the MagickClipPathImage method is:
+%
+% unsigned int MagickClipPathImage(MagickWand *wand,const char *pathname,
+% const unsigned int inside)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o pathname: name of clipping path resource. If name is preceded by #, use
+% clipping path numbered by name.
+%
+% o inside: if non-zero, later operations take effect inside clipping path.
+% Otherwise later operations take effect outside clipping path.
+%
+*/
+WandExport unsigned int MagickClipPathImage(MagickWand *wand,
+ const char *pathname,const unsigned int inside)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=ClipPathImage(wand->image,pathname,inside);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o a l e s c e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCoalesceImages() composites a set of images while respecting any page
+% offsets and disposal methods. GIF, MIFF, and MNG animation sequences
+% typically start with an image background and each subsequent image
+% varies in size and offset. MagickCoalesceImages() returns a new sequence
+% where each image in the sequence is the same size as the first and
+% composited with the next image in the sequence.
+%
+% The format of the MagickCoalesceImages method is:
+%
+% MagickWand *MagickCoalesceImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport MagickWand *MagickCoalesceImages(MagickWand *wand)
+{
+ Image
+ *coalesce_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ coalesce_image=CoalesceImages(wand->images,&wand->exception);
+ if (coalesce_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,coalesce_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o l o r F l o o d f i l l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickColorFloodfillImage() changes the color value of any pixel that matches
+% target and is an immediate neighbor. If the method FillToBorderMethod is
+% specified, the color value is changed for any neighbor pixel that does not
+% match the bordercolor member of image.
+%
+% The format of the MagickColorFloodfillImage method is:
+%
+% unsigned int MagickColorFloodfillImage(MagickWand *wand,
+% const PixelWand *fill,const double fuzz,const PixelWand *bordercolor,
+% const long x,const long y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o fill: The floodfill color pixel wand.
+%
+% o fuzz: By default target must match a particular pixel color
+% exactly. However, in many cases two colors may differ by a small amount.
+% The fuzz member of image defines how much tolerance is acceptable to
+% consider two colors as the same. For example, set fuzz to 10 and the
+% color red at intensities of 100 and 102 respectively are now interpreted
+% as the same color for the purposes of the floodfill.
+%
+% o bordercolor: The border color pixel wand.
+%
+% o x,y: The starting location of the operation.
+%
+*/
+WandExport unsigned int MagickColorFloodfillImage(MagickWand *wand,
+ const PixelWand *fill,const double fuzz,const PixelWand *bordercolor,
+ const long x,const long y)
+{
+ DrawInfo
+ *draw_info;
+
+ PixelPacket
+ target;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ draw_info=CloneDrawInfo(wand->image_info,(DrawInfo *) NULL);
+ PixelGetQuantumColor(fill,&draw_info->fill);
+ (void) AcquireOnePixelByReference(wand->image,&target,x % wand->image->columns,
+ y % wand->image->rows,&wand->exception);
+ if (bordercolor != (PixelWand *) NULL)
+ PixelGetQuantumColor(bordercolor,&target);
+ wand->image->fuzz=fuzz;
+ status=ColorFloodfillImage(wand->image,draw_info,target,x,y,
+ bordercolor != (PixelWand *) NULL ? FillToBorderMethod : FloodfillMethod);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ DestroyDrawInfo(draw_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o l o r i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickColorizeImage() blends the fill color with each pixel in the image.
+%
+% The format of the MagickColorizeImage method is:
+%
+% unsigned int MagickColorizeImage(MagickWand *wand,
+% const PixelWand *colorize,const PixelWand *opacity)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o colorize: The colorize pixel wand.
+%
+% o opacity: The opacity pixel wand.
+%
+*/
+WandExport unsigned int MagickColorizeImage(MagickWand *wand,
+ const PixelWand *colorize,const PixelWand *opacity)
+{
+ char
+ percent_opaque[MaxTextExtent];
+
+ Image
+ *colorize_image;
+
+ PixelPacket
+ target;
+
+ ARG_NOT_USED(opacity);
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) MagickFormatString(percent_opaque,MaxTextExtent,"%g,%g,%g,%g",
+ 100.0*PixelGetRedQuantum(colorize)/MaxRGB,
+ 100.0*PixelGetGreenQuantum(colorize)/MaxRGB,
+ 100.0*PixelGetBlueQuantum(colorize)/MaxRGB,
+ 100.0*PixelGetOpacityQuantum(colorize)/MaxRGB);
+ PixelGetQuantumColor(colorize,&target);
+ colorize_image=ColorizeImage(wand->image,percent_opaque,target,
+ &wand->exception);
+ if (colorize_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,colorize_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o m m e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCommentImage() adds a comment to your image.
+%
+% The format of the MagickCommentImage method is:
+%
+% unsigned int MagickCommentImage(MagickWand *wand,const char *comment)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o comment: The image comment.
+%
+*/
+WandExport unsigned int MagickCommentImage(MagickWand *wand,const char *comment)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) SetImageAttribute(wand->image,"comment",(char *) NULL);
+ status=SetImageAttribute(wand->image,"comment",comment);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o m p a r e I m a g e C h a n n e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCompareImageChannels() compares one or more image channels and
+% returns the specified distortion metric.
+%
+% The format of the MagickCompareImageChannels method is:
+%
+% MagickWand *MagickCompareImageChannels(MagickWand *wand,
+% const MagickWand *reference,const ChannelType channel,
+% const MetricType metric,double *distortion)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o reference: The reference wand.
+%
+% o channel: The channel.
+%
+% o metric: The metric.
+%
+% o distortion: The computed distortion between the images.
+%
+*/
+WandExport MagickWand *
+MagickCompareImageChannels(MagickWand *wand,
+ const MagickWand *reference,
+ const ChannelType channel,
+ const MetricType metric,
+ double *distortion)
+{
+ DifferenceImageOptions
+ difference_options;
+
+ Image
+ *compare_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if ((wand->images == (Image *) NULL) || (reference->images == (Image *) NULL))
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ if (distortion != (double *) NULL)
+ *distortion=0.0;
+ InitializeDifferenceImageOptions(&difference_options,
+ &wand->image->exception);
+ difference_options.channel=channel;
+ compare_image=DifferenceImage(wand->image,reference->image,
+ &difference_options,
+ &wand->image->exception);
+ if (compare_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+
+ /*
+ Perform statistical comparison of images using a metric.
+ */
+ if (distortion != (double *) NULL)
+ {
+ GetImageChannelDistortion(wand->image,reference->image,
+ channel,metric,distortion,
+ &wand->image->exception);
+ }
+
+ return(CloneMagickWandWithImages(wand,compare_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o m p a r e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCompareImage() compares one or more images and returns the specified
+% distortion metric.
+%
+% The format of the MagickCompareImages method is:
+%
+% MagickWand *MagickCompareImages(MagickWand *wand,
+% const MagickWand *reference,const MetricType metric,
+% double *distortion)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o reference: The reference wand.
+%
+% o metric: The metric.
+%
+% o distortion: The computed distortion between the images.
+%
+*/
+WandExport MagickWand *MagickCompareImages(MagickWand *wand,
+ const MagickWand *reference,
+ const MetricType metric,
+ double *distortion)
+{
+ return MagickCompareImageChannels(wand,reference,AllChannels,
+ metric,distortion);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o m p o s i t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCompositeImage() composite one image onto another at the specified
+% offset.
+%
+% The format of the MagickCompositeImage method is:
+%
+% unsigned int MagickCompositeImage(MagickWand *wand,
+% const MagickWand *composite_wand,const CompositeOperator compose,
+% const long x,const long y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o composite_image: The composite image.
+%
+% o compose: This operator affects how the composite is applied to the
+% image. The default is Over. Choose from these operators:
+%
+% OverCompositeOp InCompositeOp OutCompositeOP
+% AtopCompositeOP XorCompositeOP PlusCompositeOP
+% MinusCompositeOP AddCompositeOP SubtractCompositeOP
+% DifferenceCompositeOP BumpmapCompositeOP CopyCompositeOP
+% DisplaceCompositeOP
+%
+% o x_offset: The column offset of the composited image.
+%
+% o y_offset: The row offset of the composited image.
+%
+%
+*/
+WandExport unsigned int MagickCompositeImage(MagickWand *wand,
+ const MagickWand *composite_wand,const CompositeOperator compose,const long x,
+ const long y)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if ((wand->images == (Image *) NULL) ||
+ (composite_wand->images == (Image *) NULL))
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=CompositeImage(wand->image,compose,composite_wand->image,x,y);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o n t r a s t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickContrastImage() enhances the intensity differences between the lighter
+% and darker elements of the image. Set sharpen to a value other than 0 to
+% increase the image contrast otherwise the contrast is reduced.
+%
+% The format of the MagickContrastImage method is:
+%
+% unsigned int MagickContrastImage(MagickWand *wand,
+% const unsigned int sharpen)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o sharpen: Increase or decrease image contrast.
+%
+%
+*/
+WandExport unsigned int MagickContrastImage(MagickWand *wand,
+ const unsigned int sharpen)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=ContrastImage(wand->image,sharpen);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C o n v o l v e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickConvolveImage() applies a custom convolution kernel to the image.
+%
+% The format of the MagickConvolveImage method is:
+%
+% unsigned int MagickConvolveImage(MagickWand *wand,
+% const unsigned long order,const double *kernel)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o order: The number of columns and rows in the filter kernel.
+%
+% o kernel: An array of doubles representing the convolution kernel.
+%
+%
+*/
+WandExport unsigned int MagickConvolveImage(MagickWand *wand,
+ const unsigned long order,const double *kernel)
+{
+ Image
+ *convolve_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (kernel == (const double *) NULL)
+ return(False);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ convolve_image=ConvolveImage(wand->image,order,kernel,&wand->exception);
+ if (convolve_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,convolve_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C r o p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCropImage() extracts a region of the image.
+%
+% The format of the MagickCropImage method is:
+%
+% unsigned int MagickCropImage(MagickWand *wand,const unsigned long width,
+% const unsigned long height,const long x,const long y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o width: The region width.
+%
+% o height: The region height.
+%
+% o x: The region x offset.
+%
+% o y: The region y offset.
+%
+%
+*/
+WandExport unsigned int MagickCropImage(MagickWand *wand,
+ const unsigned long width,const unsigned long height,const long x,
+ const long y)
+{
+ Image
+ *crop_image;
+
+ RectangleInfo
+ crop;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ crop.width=width;
+ crop.height=height;
+ crop.x=x;
+ crop.y=y;
+ crop_image=CropImage(wand->image,&crop,&wand->exception);
+ if (crop_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,crop_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k C y c l e C o l o r m a p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickCycleColormapImage() displaces an image's colormap by a given number
+% of positions. If you cycle the colormap a number of times you can produce
+% a psychodelic effect.
+%
+% The format of the MagickCycleColormapImage method is:
+%
+% unsigned int MagickCycleColormapImage(MagickWand *wand,
+% const long displace)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o pixel_wand: The pixel wand.
+%
+*/
+WandExport unsigned int MagickCycleColormapImage(MagickWand *wand,
+ const long displace)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=CycleColormapImage(wand->image,displace);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k D e c o n s t r u c t I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickDeconstructImages() compares each image with the next in a sequence
+% and returns the maximum bounding region of any pixel differences it
+% discovers.
+%
+% The format of the MagickDeconstructImages method is:
+%
+% MagickWand *MagickDeconstructImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport MagickWand *MagickDeconstructImages(MagickWand *wand)
+{
+ Image
+ *deconstruct_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ deconstruct_image=DeconstructImages(wand->images,&wand->exception);
+ if (deconstruct_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,deconstruct_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k D e s c r i b e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickDescribeImage() describes an image by formatting its attributes
+% to an allocated string which must be freed by the user. Attributes
+% include the image width, height, size, and others. The string is
+% similar to the output of 'identify -verbose'.
+%
+% The format of the MagickDescribeImage method is:
+%
+% const char *MagickDescribeImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport char *MagickDescribeImage(MagickWand *wand)
+{
+ char
+ *description,
+ filename[MaxTextExtent];
+
+ FILE
+ *file;
+
+ size_t
+ length;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ description=(char *) NULL;
+ filename[0]='\0';
+ length=0;
+ if ((file = AcquireTemporaryFileStream(filename, TextFileIOMode)) == (FILE *) NULL)
+ {
+ ThrowException(&wand->exception,FileOpenError,
+ UnableToCreateTemporaryFile,filename);
+ }
+ else
+ {
+ (void) DescribeImage(wand->image,file,MagickTrue);
+ (void) fclose(file);
+ description=(char *) FileToBlob(filename,&length,&wand->exception);
+ (void) LiberateTemporaryFile(filename);
+ }
+ return(description);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M a g i c k D e s p e c k l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickDespeckleImage() reduces the speckle noise in an image while
+% perserving the edges of the original image.
+%
+% The format of the MagickDespeckleImage method is:
+%
+% unsigned int MagickDespeckleImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickDespeckleImage(MagickWand *wand)
+{
+ Image
+ *despeckle_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ despeckle_image=DespeckleImage(wand->image,&wand->exception);
+ if (despeckle_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,despeckle_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k D i s p l a y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickDisplayImage() displays an image.
+%
+% The format of the MagickDisplayImage method is:
+%
+% unsigned int MagickDisplayImage(MagickWand *wand,const char *server_name)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o server_name: The X server name.
+%
+*/
+WandExport unsigned int MagickDisplayImage(MagickWand *wand,
+ const char *server_name)
+{
+ Image
+ *image;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ image=CloneImage(wand->image,0,0,True,&wand->exception);
+ if (image == (Image *) NULL)
+ return(False);
+ wand->image_info->server_name=(char *) AcquireString(server_name);
+ status=DisplayImages(wand->image_info,image);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ DestroyImage(image);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k D i s p l a y I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickDisplayImages() displays an image or image sequence.
+%
+% The format of the MagickDisplayImages method is:
+%
+% unsigned int MagickDisplayImages(MagickWand *wand,
+% const char *server_name)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o server_name: The X server name.
+%
+%
+*/
+WandExport unsigned int MagickDisplayImages(MagickWand *wand,
+ const char *server_name)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) CloneString(&wand->image_info->server_name,server_name);
+ status=DisplayImages(wand->image_info,wand->images);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k D r a w I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickDrawImage() draws vectors on the image as described by DrawingWand.
+%
+% The format of the MagickDrawImage method is:
+%
+% unsigned int MagickDrawImage(MagickWand *wand,
+% const DrawingWand *drawing_wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o drawing_wand: The draw wand.
+%
+*/
+WandExport unsigned int MagickDrawImage(MagickWand *wand,
+ const DrawingWand *drawing_wand)
+{
+ DrawInfo
+ *draw_info;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ draw_info=DrawPeekGraphicContext(drawing_wand);
+ if ((draw_info == (DrawInfo *) NULL) ||
+ (draw_info->primitive == (char *) NULL))
+ {
+ if (draw_info != (DrawInfo *) NULL)
+ DestroyDrawInfo(draw_info);
+ return(False);
+ }
+ status=DrawImage(wand->image,draw_info);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ DestroyDrawInfo(draw_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k E d g e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickEdgeImage() enhance edges within the image with a convolution filter
+% of the given radius. Use a radius of 0 and Edge() selects a suitable
+% radius for you.
+%
+% The format of the MagickEdgeImage method is:
+%
+% unsigned int MagickEdgeImage(MagickWand *wand,const double radius)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: the radius of the pixel neighborhood.
+%
+*/
+WandExport unsigned int MagickEdgeImage(MagickWand *wand,const double radius)
+{
+ Image
+ *edge_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ edge_image=EdgeImage(wand->image,radius,&wand->exception);
+ if (edge_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,edge_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k E m b o s s I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickEmbossImage() returns a grayscale image with a three-dimensional
+% effect. We convolve the image with a Gaussian operator of the given radius
+% and standard deviation (sigma). For reasonable results, radius should be
+% larger than sigma. Use a radius of 0 and Emboss() selects a suitable
+% radius for you.
+%
+% The format of the MagickEmbossImage method is:
+%
+% unsigned int MagickEmbossImage(MagickWand *wand,const double radius,
+% const double sigma)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+*/
+WandExport unsigned int MagickEmbossImage(MagickWand *wand,const double radius,
+ const double sigma)
+{
+ Image
+ *emboss_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ emboss_image=EmbossImage(wand->image,radius,sigma,&wand->exception);
+ if (emboss_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,emboss_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k E n h a n c e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickEnhanceImage() applies a digital filter that improves the quality of a
+% noisy image.
+%
+% The format of the MagickEnhanceImage method is:
+%
+% unsigned int MagickEnhanceImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickEnhanceImage(MagickWand *wand)
+{
+ Image
+ *enhance_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ enhance_image=EnhanceImage(wand->image,&wand->exception);
+ if (enhance_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,enhance_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k E q u a l i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickEqualizeImage() equalizes the image histogram.
+%
+% The format of the MagickEqualizeImage method is:
+%
+% unsigned int MagickEqualizeImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickEqualizeImage(MagickWand *wand)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=EqualizeImage(wand->image);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k E x t e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use MagickExtentImage() to change the image dimensions as specified by
+% geometry width and height. The existing image content is composited at
+% the position specified by geometry x and y using the image compose method.
+% Existing image content which falls outside the bounds of the new image
+% dimensions is discarded.
+%
+% The format of the MagickExtentImage method is:
+%
+% unsigned int MagickExtentImage(MagickWand *wand,const size_t width,
+% const size_t height, const ssize_t x,
+% const ssize_t y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o width: New image width
+%
+% o height: New image height
+%
+% o x, y: Top left composition coordinate to place existing image content
+% on the new image.
+%
+*/
+WandExport unsigned int
+MagickExtentImage(MagickWand *wand,const size_t width,const size_t height,
+ const ssize_t x,const ssize_t y)
+{
+ Image
+ *extent_image;
+
+ RectangleInfo
+ geometry;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ geometry.width=(unsigned long) width;
+ geometry.height=(unsigned long) height;
+ geometry.x=x;
+ geometry.y=y;
+ extent_image=ExtentImage(wand->image,&geometry,&wand->exception);
+ if (extent_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,extent_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F l a t t e n I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFlattenImages() merges a sequence of images. This is useful for
+% combining Photoshop layers into a single image.
+%
+% The format of the MagickFlattenImages method is:
+%
+% MagickWand *MagickFlattenImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport MagickWand *MagickFlattenImages(MagickWand *wand)
+{
+ Image
+ *flatten_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ flatten_image=FlattenImages(wand->images,&wand->exception);
+ if (flatten_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,flatten_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F l i p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFlipImage() creates a vertical mirror image by reflecting the pixels
+% around the central x-axis.
+%
+% The format of the MagickFlipImage method is:
+%
+% unsigned int MagickFlipImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickFlipImage(MagickWand *wand)
+{
+ Image
+ *flip_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ flip_image=FlipImage(wand->image,&wand->exception);
+ if (flip_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,flip_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F l o p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFlopImage() creates a horizontal mirror image by reflecting the pixels
+% around the central y-axis.
+%
+% The format of the MagickFlopImage method is:
+%
+% unsigned int MagickFlopImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickFlopImage(MagickWand *wand)
+{
+ Image
+ *flop_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ flop_image=FlopImage(wand->image,&wand->exception);
+ if (flop_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,flop_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F r a m e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFrameImage() adds a simulated three-dimensional border around the
+% image. The width and height specify the border width of the vertical and
+% horizontal sides of the frame. The inner and outer bevels indicate the
+% width of the inner and outer shadows of the frame.
+%
+% The format of the MagickFrameImage method is:
+%
+% unsigned int MagickFrameImage(MagickWand *wand,
+% const PixelWand *matte_color,const unsigned long width,
+% const unsigned long height,const long inner_bevel,
+% const long outer_bevel)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o matte_color: The frame color pixel wand.
+%
+% o width: The border width.
+%
+% o height: The border height.
+%
+% o inner_bevel: The inner bevel width.
+%
+% o outer_bevel: The outer bevel width.
+%
+*/
+WandExport unsigned int MagickFrameImage(MagickWand *wand,
+ const PixelWand *matte_color,const unsigned long width,
+ const unsigned long height,const long inner_bevel,const long outer_bevel)
+{
+ Image
+ *frame_image;
+
+ FrameInfo
+ frame_info;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) memset(&frame_info,0,sizeof(FrameInfo));
+ frame_info.width=wand->image->columns+2*width;
+ frame_info.height=wand->image->rows+2*height;
+ frame_info.x=(long) width;
+ frame_info.y=(long) height;
+ frame_info.inner_bevel=inner_bevel;
+ frame_info.outer_bevel=outer_bevel;
+ PixelGetQuantumColor(matte_color,&wand->image->matte_color);
+ frame_image=FrameImage(wand->image,&frame_info,&wand->exception);
+ if (frame_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,frame_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F x I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFxImage() evaluate expression for each pixel in the image.
+%
+% The format of the MagickFxImage method is:
+%
+% MagickWand *MagickFxImage(MagickWand *wand,const char *expression)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o expression: The expression.
+%
+*/
+WandExport MagickWand *MagickFxImage(MagickWand *wand,const char *expression)
+{
+#if defined(NOT_IMPLEMENTED)
+ Image
+ *fx_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ fx_image=FxImage(wand->images,expression,&wand->exception);
+ if (fx_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,fx_image));
+#else
+ ARG_NOT_USED(expression);
+ ThrowWandException(WandError,WandAPINotImplemented,"MagickFxImage");
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k F x I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickFxImageChannel() evaluate expression for each pixel in the specified
+% channel.
+%
+% The format of the MagickFxImageChannel method is:
+%
+% MagickWand *MagickFxImageChannel(MagickWand *wand,
+% const ChannelType channel,const char *expression)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: Identify which channel to level: RedChannel, GreenChannel,
+% BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+% BlackChannel.
+%
+% o expression: The expression.
+%
+*/
+WandExport MagickWand * MagickFxImageChannel(MagickWand *wand,
+ const ChannelType channel,const char *expression)
+{
+#if defined(NOT_IMPLEMENTED)
+ Image
+ *fx_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ fx_image=FxImageChannel(wand->images,channel,expression,&wand->exception);
+ if (fx_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,fx_image));
+#else
+ ARG_NOT_USED(channel);
+ ARG_NOT_USED(expression);
+ ThrowWandException(WandError,WandAPINotImplemented,"MagickFxImageChannel");
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G a m m a I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use MagickGammaImage() to gamma-correct an image. The same image viewed on
+% different devices will have perceptual differences in the way the
+% image's intensities are represented on the screen. Specify individual
+% gamma levels for the red, green, and blue channels, or adjust all three
+% with the gamma parameter. Values typically range from 0.8 to 2.3.
+%
+% You can also reduce the influence of a particular channel with a gamma
+% value of 0.
+%
+% The format of the MagickGammaImage method is:
+%
+% unsigned int MagickGammaImage(MagickWand *wand,const double gamma)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o gamme: Define the level of gamma correction.
+%
+*/
+WandExport unsigned int MagickGammaImage(MagickWand *wand,const double gamma)
+{
+ char
+ level[MaxTextExtent];
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ FormatString(level,"%g",gamma);
+ status=GammaImage(wand->image,level);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G a m m a I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use MagickGammaImageChannel() to gamma-correct a particular image channel.
+% The same image viewed on different devices will have perceptual differences
+% in the way the image's intensities are represented on the screen. Specify
+% individual gamma levels for the red, green, and blue channels, or adjust all
+% three with the gamma parameter. Values typically range from 0.8 to 2.3.
+%
+% You can also reduce the influence of a particular channel with a gamma
+% value of 0.
+%
+% The format of the MagickGammaImageChannel method is:
+%
+% unsigned int MagickGammaImageChannel(MagickWand *wand,
+% const ChannelType channel,const double gamma)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: The channel.
+%
+% o level: Define the level of gamma correction.
+%
+*/
+WandExport unsigned int MagickGammaImageChannel(MagickWand *wand,
+ const ChannelType channel,const double gamma)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return QuantumOperatorImage(wand->image,channel,GammaQuantumOp,
+ gamma,&wand->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t C o n f i g u r e I n f o %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetConfigureInfo() returns ImageMagick configure attributes such as
+% NAME, VERSION, LIB_VERSION, COPYRIGHT, etc.
+%
+% The format of the MagickGetConfigureInfo() method is:
+%
+% char *MagickGetConfigureInfo(MagickWand *wand,const char *name)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o name: Return the attribute associated with this name.
+%
+*/
+WandExport char *MagickGetConfigureInfo(MagickWand *wand,const char *name)
+{
+#if NOT_SUPPORTED
+ const ConfigureInfo
+ *configure_info;
+
+ configure_info=GetConfigureInfo(name,&wand->exception);
+ if (configure_info == (const ConfigureInfo *) NULL)
+ return((char *) NULL);
+ return(AcquireString(configure_info->value));
+#else
+ ARG_NOT_USED(name);
+ ARG_NOT_USED(wand);
+ return 0;
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t C o p y r i g h t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetCopyright() returns the ImageMagick API copyright as a string.
+%
+% The format of the MagickGetCopyright method is:
+%
+% const char *MagickGetCopyright(void)
+%
+*/
+WandExport const char *MagickGetCopyright(void)
+{
+ return(GetMagickCopyright());
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetException() returns the severity, reason, and description of any
+% error that occurs when using other methods in this API.
+%
+% The format of the MagickGetException method is:
+%
+% char *MagickGetException(const MagickWand *wand,ExceptionType *severity)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o severity: The severity of the error is returned here.
+%
+*/
+WandExport char *MagickGetException(const MagickWand *wand,
+ ExceptionType *severity)
+{
+ char
+ *description;
+
+ assert(wand != (const MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(severity != (ExceptionType *) NULL);
+ *severity=wand->exception.severity;
+ description=MagickAllocateMemory(char *,2*MaxTextExtent);
+ if (description == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateString);
+ *description='\0';
+ if (wand->exception.reason != (char *) NULL)
+ (void) strlcpy(description,GetLocaleExceptionMessage(
+ wand->exception.severity,wand->exception.reason),MaxTextExtent);
+ if (wand->exception.description != (char *) NULL)
+ {
+ (void) strlcat(description," (",MaxTextExtent);
+ (void) strlcat(description,GetLocaleExceptionMessage(
+ wand->exception.severity,wand->exception.description),MaxTextExtent);
+ (void) strlcat(description,")",MaxTextExtent);
+ }
+ return(description);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t F i l e n a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetFilename() returns the filename associated with an image sequence.
+%
+% The format of the MagickGetFilename method is:
+%
+% const char *MagickGetFilename(const MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+%
+*/
+WandExport char *MagickGetFilename(const MagickWand *wand)
+{
+ assert(wand != (const MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(AcquireString(wand->image_info->filename));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t H o m e U R L %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetHomeURL() returns the ImageMagick home URL.
+%
+% The format of the MagickGetHomeURL method is:
+%
+% const char *MagickGetHomeURL(void)
+%
+*/
+WandExport const char *MagickGetHomeURL(void)
+{
+ return(GetMagickWebSite());
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImage() clones the image at the current image index.
+%
+% The format of the MagickGetImage method is:
+%
+% MagickWand *MagickGetImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport MagickWand *MagickGetImage(MagickWand *wand)
+{
+ Image
+ *image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ image=CloneImage(wand->image,0,0,True,&wand->exception);
+ if (image == (Image *) NULL)
+ return(False);
+ return(CloneMagickWandWithImages(wand,image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e A t t r i b u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageAttribute returns an image attribute as a string
+%
+% The format of the MagickGetImageAttribute method is:
+%
+% char *MagickGetImageAttribute(MagickWand *wand, const char *name)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o name: The name of the attribute
+%
+*/
+WandExport char *MagickGetImageAttribute(MagickWand *wand, const char *name)
+{
+ const ImageAttribute
+ *attribute;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ attribute=GetImageAttribute(wand->image,name);
+ if (attribute != (ImageAttribute *) NULL)
+ return(AcquireString(attribute->value));
+ CopyException(&wand->exception,&wand->image->exception);
+ return((char *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e B a c k g r o u n d C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageBackgroundColor() returns the image background color.
+%
+% The format of the MagickGetImageBackgroundColor method is:
+%
+% unsigned int MagickGetImageBackgroundColor(MagickWand *wand,
+% PixelWand *background_color)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o background_color: Return the background color.
+%
+*/
+WandExport unsigned int MagickGetImageBackgroundColor(MagickWand *wand,
+ PixelWand *background_color)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelSetQuantumColor(background_color,&wand->image->background_color);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e B l u e P r i m a r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageBluePrimary() returns the chromaticy blue primary point for the
+% image.
+%
+% The format of the MagickGetImageBluePrimary method is:
+%
+% unsigned int MagickGetImageBluePrimary(MagickWand *wand,double *x,
+% double *y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The chromaticity blue primary x-point.
+%
+% o y: The chromaticity blue primary y-point.
+%
+*/
+WandExport unsigned int MagickGetImageBluePrimary(MagickWand *wand,double *x,
+ double *y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ *x=wand->image->chromaticity.blue_primary.x;
+ *y=wand->image->chromaticity.blue_primary.y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e B o r d e r C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageBorderColor() returns the image border color.
+%
+% The format of the MagickGetImageBorderColor method is:
+%
+% unsigned int MagickGetImageBorderColor(MagickWand *wand,
+% PixelWand *border_color)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o border_color: Return the border color.
+%
+*/
+WandExport unsigned int MagickGetImageBorderColor(MagickWand *wand,
+ PixelWand *border_color)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelSetQuantumColor(border_color,&wand->image->border_color);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e B o u n d i n g B o x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageBoundingBox() obtains the crop bounding box required to
+% remove a solid-color border from the image. Color quantums which differ
+% less than the fuzz setting are considered to be the same. If a border is
+% not detected, then the the original image dimensions are returned. The
+% crop bounding box estimation uses the same algorithm as MagickTrimImage().
+%
+% The format of the MagickGetImageBoundingBox method is:
+%
+% unsigned int MagickGetImageBoundingBox(MagickWand *wand,
+% const double fuzz,
+% unsigned long *width,unsigned long *height,
+% long *x, long *y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o fuzz: Color comparison fuzz factor. Use 0.0 for exact match.
+%
+% o width: The crop width
+%
+% o height: The crop height
+%
+% o x: The crop x offset
+%
+% o y: The crop y offset
+%
+*/
+WandExport unsigned int
+MagickGetImageBoundingBox(MagickWand *wand,const double fuzz,
+ unsigned long *width, unsigned long *height,
+ long *x, long *y)
+{
+ RectangleInfo
+ rectangle;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(width != (unsigned long *) NULL);
+ assert(height != (unsigned long *) NULL);
+ assert(x != (long *) NULL);
+ assert(y != (long *) NULL);
+
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ wand->image->fuzz=fuzz;
+ rectangle=GetImageBoundingBox(wand->image,&wand->exception);
+ *width=rectangle.width;
+ *height=rectangle.height;
+ *x=rectangle.x;
+ *y=rectangle.y;
+
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e C h a n n e l D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageChannelDepth() gets the depth for a particular image channel.
+%
+% The format of the MagickGetImageChannelDepth method is:
+%
+% unsigned long MagickGetImageChannelDepth(MagickWand *wand,
+% const ChannelType channel)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: Identify which channel to extract: RedChannel, GreenChannel,
+% BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+% BlackChannel.
+%
+*/
+WandExport unsigned long MagickGetImageChannelDepth(MagickWand *wand,
+ const ChannelType channel)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(GetImageChannelDepth(wand->image,channel,&wand->exception));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e C h a n n e l E x t r e m a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageChannelExtrema() gets the extrema for one or more image
+% channels.
+%
+% The format of the MagickGetImageChannelExtrema method is:
+%
+% unsigned int MagickGetImageChannelExtrema(MagickWand *wand,
+% const ChannelType channel,unsigned long *minima,unsigned long *maxima)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: Identify which channel to extract: RedChannel, GreenChannel,
+% BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+% or BlackChannel.
+%
+% o minima: The minimum pixel value for the specified channel(s).
+%
+% o maxima: The maximum pixel value for the specified channel(s).
+%
+*/
+WandExport unsigned int
+MagickGetImageChannelExtrema(MagickWand *wand,
+ const ChannelType channel,
+ unsigned long *minima,
+ unsigned long *maxima)
+{
+ ImageStatistics
+ statistics;
+
+ double
+ minimum,
+ maximum;
+
+ MagickPassFail
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ status = GetImageStatistics(wand->image,&statistics,&wand->exception);
+ minimum = 1.0;
+ if (MagickChannelEnabled(channel,RedChannel) ||
+ MagickChannelEnabled(channel,CyanChannel))
+ minimum = Min(minimum,statistics.red.minimum);
+ if (MagickChannelEnabled(channel,GreenChannel) ||
+ MagickChannelEnabled(channel,MagentaChannel))
+ minimum = Min(minimum,statistics.green.minimum);
+ if (MagickChannelEnabled(channel,BlueChannel) ||
+ MagickChannelEnabled(channel,YellowChannel))
+ minimum = Min(minimum,statistics.blue.minimum);
+ /* CMYK opacity not handled correctly here */
+ if (MagickChannelEnabled(channel,OpacityChannel) ||
+ MagickChannelEnabled(channel,BlackChannel))
+ minimum = Min(minimum,statistics.opacity.minimum);
+ minimum *= MaxRGBDouble;
+ *minima = RoundDoubleToQuantum(minimum);
+
+ maximum = 0.0;
+ if (MagickChannelEnabled(channel,RedChannel) ||
+ MagickChannelEnabled(channel,CyanChannel))
+ maximum = Max(maximum,statistics.red.maximum);
+ if (MagickChannelEnabled(channel,GreenChannel) ||
+ MagickChannelEnabled(channel,MagentaChannel))
+ maximum = Max(maximum,statistics.green.maximum);
+ if (MagickChannelEnabled(channel,BlueChannel) ||
+ MagickChannelEnabled(channel,YellowChannel))
+ maximum = Max(maximum,statistics.blue.maximum);
+ /* CMYK opacity not handled correctly here */
+ if (MagickChannelEnabled(channel,OpacityChannel) ||
+ MagickChannelEnabled(channel,BlackChannel))
+ maximum = Max(maximum,statistics.opacity.maximum);
+ maximum *= MaxRGBDouble;
+ *maxima = RoundDoubleToQuantum(maximum);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e C h a n n e l M e a n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageChannelMean() gets the mean and standard deviation of one or
+% more image channels.
+%
+% The format of the MagickGetImageChannelMean method is:
+%
+% unsigned int MagickGetImageChannelMean(MagickWand *wand,
+% const ChannelType channel,double *mean,double *standard_deviation)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: Identify which channel to extract: RedChannel, GreenChannel,
+% BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+% or BlackChannel.
+%
+% o mean: The mean pixel value for the specified channel(s).
+%
+% o standard_deviation: The standard deviation for the specified channel(s).
+%
+*/
+WandExport unsigned int MagickGetImageChannelMean(MagickWand *wand,
+ const ChannelType channel,double *mean,double *standard_deviation)
+{
+ ImageStatistics
+ statistics;
+
+ unsigned int
+ count;
+
+ double
+ deviation,
+ meanf;
+
+ MagickPassFail
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ status = GetImageStatistics(wand->image,&statistics,&wand->exception);
+ deviation = 0.0;
+ meanf =0.0;
+ count = 0;
+ if (MagickChannelEnabled(channel,RedChannel) ||
+ MagickChannelEnabled(channel,CyanChannel))
+ {
+ deviation += statistics.red.standard_deviation;
+ meanf += statistics.red.mean;
+ count++;
+ }
+ if (MagickChannelEnabled(channel,GreenChannel) ||
+ MagickChannelEnabled(channel,MagentaChannel))
+ {
+ deviation += statistics.green.standard_deviation;
+ meanf += statistics.green.mean;
+ count++;
+ }
+ if (MagickChannelEnabled(channel,BlueChannel) ||
+ MagickChannelEnabled(channel,YellowChannel))
+ {
+ deviation += statistics.blue.standard_deviation;
+ meanf += statistics.blue.mean;
+ count++;
+ }
+ /* CMYK opacity not handled correctly here */
+ if (MagickChannelEnabled(channel,OpacityChannel) ||
+ MagickChannelEnabled(channel,BlackChannel))
+ {
+ deviation += statistics.opacity.standard_deviation;
+ meanf += statistics.opacity.mean;
+ count++;
+ }
+ if (count > 1)
+ {
+ /*
+ If multiple channels are selected then deviation is not
+ technically correct but an average of the deviation is better
+ than nothing.
+ */
+ deviation /= (double) count;
+ meanf /= (double) count;
+ }
+ deviation *= MaxRGBDouble;
+ *standard_deviation = RoundDoubleToQuantum(deviation);
+
+ meanf *= MaxRGBDouble;
+ *mean = RoundDoubleToQuantum(meanf);
+
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e C o l o r m a p C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageColormapColor() returns the color of the specified colormap
+% index.
+%
+% The format of the MagickGetImageColormapColor method is:
+%
+% unsigned int MagickGetImageColormapColor(MagickWand *wand,
+% const unsigned long index,PixelWand *color)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o index: The offset into the image colormap.
+%
+% o color: Return the colormap color in this wand.
+%
+*/
+WandExport unsigned int MagickGetImageColormapColor(MagickWand *wand,
+ const unsigned long index,PixelWand *color)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ if ((wand->image->colormap == (PixelPacket *) NULL) ||
+ (index >= wand->image->colors))
+ ThrowWandException(WandError,InvalidColormapIndex,(char *) NULL);
+ PixelSetQuantumColor(color,wand->image->colormap+index);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e C o l o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageColors() gets the number of unique colors in the image.
+%
+% The format of the MagickGetImageColors method is:
+%
+% unsigned long MagickGetImageColors(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetImageColors(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(GetNumberColors(wand->image,(FILE *) NULL,&wand->exception));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e C o l o r s p a c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageColorspace() gets the image colorspace.
+%
+% The format of the MagickGetImageColorspace method is:
+%
+% ColorspaceType MagickGetImageColorspace(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport ColorspaceType MagickGetImageColorspace(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+ return(UndefinedColorspace);
+ }
+ return(wand->image->colorspace);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e C o m p o s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageCompose() returns the composite operator associated with the
+% image.
+%
+% The format of the MagickGetImageCompose method is:
+%
+% CompositeOperator MagickGetImageCompose(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport CompositeOperator MagickGetImageCompose(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages
+ ,wand->id);
+ return(UndefinedCompositeOp);
+ }
+ return(wand->image->compose);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e C o m p r e s s i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageCompression() gets the image compression.
+%
+% The format of the MagickGetImageCompression method is:
+%
+% CompressionType MagickGetImageCompression(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport CompressionType MagickGetImageCompression(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->compression);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e D e l a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageDelay() gets the image delay.
+%
+% The format of the MagickGetImageDelay method is:
+%
+% unsigned long MagickGetImageDelay(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetImageDelay(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->delay);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageDepth() gets the image depth.
+%
+% The format of the MagickGetImageDepth method is:
+%
+% unsigned long MagickGetImageDepth(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetImageDepth(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(GetImageDepth(wand->image,&wand->exception));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e E x t r e m a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageExtrema() gets the extrema for the image.
+%
+% The format of the MagickGetImageExtrema method is:
+%
+% unsigned int MagickGetImageExtrema(MagickWand *wand,
+% unsigned long *min,unsigned long *max)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o min: The minimum pixel value for the specified channel(s).
+%
+% o max: The maximum pixel value for the specified channel(s).
+%
+*/
+WandExport unsigned int MagickGetImageExtrema(MagickWand *wand,
+ unsigned long *min,unsigned long *max)
+{
+ ImageStatistics
+ statistics;
+
+ double
+ minimum,
+ maximum;
+
+ MagickPassFail
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ status = GetImageStatistics(wand->image,&statistics,&wand->exception);
+ minimum = 1.0;
+ minimum = Min(minimum,statistics.red.minimum);
+ minimum = Min(minimum,statistics.green.minimum);
+ minimum = Min(minimum,statistics.blue.minimum);
+ minimum *= MaxRGBDouble;
+ *min = RoundDoubleToQuantum(minimum);
+
+ maximum = 0.0;
+ maximum = Max(maximum,statistics.red.maximum);
+ maximum = Max(maximum,statistics.green.maximum);
+ maximum = Max(maximum,statistics.blue.maximum);
+ maximum *= MaxRGBDouble;
+ *max = RoundDoubleToQuantum(maximum);
+ return status;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e D i s p o s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageDispose() gets the image disposal method.
+%
+% The format of the MagickGetImageDispose method is:
+%
+% DisposeType MagickGetImageDispose(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport DisposeType MagickGetImageDispose(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+ return(UndefinedDispose);
+ }
+ return((DisposeType) wand->image->dispose);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e F i l e n a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageFilename() returns the filename of a particular image in a
+% sequence.
+%
+% The format of the MagickGetImageFilename method is:
+%
+% const char MagickGetImageFilename(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport char *MagickGetImageFilename(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(AcquireString(wand->image->filename));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e F o r m a t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageFormat() returns the format of a particular image in a
+% sequence.
+%
+% The format of the MagickGetImageFormat method is:
+%
+% const char MagickGetImageFormat(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport char *MagickGetImageFormat(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(AcquireString(wand->image->magick));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e F u z z %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageFuzz() returns the color comparison fuzz factor. Colors
+% closer than the fuzz factor are considered to be the same when comparing
+% colors. Note that some other functions such as MagickColorFloodfillImage()
+% implicitly set this value.
+%
+% The format of the MagickGetImageFuzz method is:
+%
+% double MagickGetImageFuzz(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport double MagickGetImageFuzz(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return wand->image->fuzz;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e G a m m a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageGamma() gets the image gamma.
+%
+% The format of the MagickGetImageGamma method is:
+%
+% double MagickGetImageGamma(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport double MagickGetImageGamma(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->gamma);
+}
+/*
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % %
+ % %
+ % %
+ % M a g i c k G e t I m a g e G e o m e t r y %
+ % %
+ % %
+ % %
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+ % MagickGetImageGeometry() gets the image geometry string. NULL is
+ % returned if the image does not contain a geometry string.
+ %
+ % The format of the MagickGetImageGeometry method is:
+ %
+ % const char *MagickGetImageGeometry(MagickWand *wand)
+ %
+ % A description of each parameter follows:
+ %
+ % o wand: The magick wand.
+ %
+ */
+WandExport const char *MagickGetImageGeometry(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->geometry);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e G r a v i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageGravity() gets the image gravity.
+%
+% The format of the MagickGetImageGravity method is:
+%
+% GravityType MagickGetImageGravity(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport GravityType MagickGetImageGravity(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->gravity);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e G r e e n P r i m a r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageGreenPrimary() returns the chromaticy green primary point.
+%
+% The format of the MagickGetImageGreenPrimary method is:
+%
+% unsigned int MagickGetImageGreenPrimary(MagickWand *wand,double *x,
+% double *y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The chromaticity green primary x-point.
+%
+% o y: The chromaticity green primary y-point.
+%
+*/
+WandExport unsigned int MagickGetImageGreenPrimary(MagickWand *wand,double *x,
+ double *y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ *x=wand->image->chromaticity.green_primary.x;
+ *y=wand->image->chromaticity.green_primary.y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e H e i g h t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageHeight() returns the image height.
+%
+% The format of the MagickGetImageHeight method is:
+%
+% unsigned long MagickGetImageHeight(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetImageHeight(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->rows);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e H i s t o g r a m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageHistogram() returns the image histogram as an array of
+% PixelWand wands.
+%
+% The format of the MagickGetImageHistogram method is:
+%
+% PixelWand *MagickGetImageHistogram(MagickWand *wand,
+% unsigned long *number_colors)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o number_colors: The number of unique colors in the image and the number
+% of pixel wands returned.
+%
+%
+*/
+WandExport PixelWand **MagickGetImageHistogram(MagickWand *wand,
+ unsigned long *number_colors)
+{
+ HistogramColorPacket
+ *histogram;
+
+ PixelWand
+ **pixel_wands;
+
+ register long
+ i;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ histogram=GetColorHistogram(wand->image,number_colors,&wand->exception);
+ if (histogram == (HistogramColorPacket *) NULL)
+ return((PixelWand **) NULL);
+ pixel_wands=NewPixelWands(*number_colors);
+ for (i=0; i < (long) *number_colors; i++)
+ {
+ PixelSetQuantumColor(pixel_wands[i],&histogram[i].pixel);
+ PixelSetColorCount(pixel_wands[i],histogram[i].count);
+ }
+ MagickFreeMemory(histogram);
+ return(pixel_wands);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e I n d e x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageIndex() returns the index of the current image.
+%
+% The format of the MagickGetImageIndex method is:
+%
+% unsigned int MagickGetImageIndex(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport long MagickGetImageIndex(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImageIndexs,wand->id);
+ return(GetImageIndexInList(wand->image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e I n t e r l a c e S c h e m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageInterlaceScheme() gets the image interlace scheme.
+%
+% The format of the MagickGetImageInterlaceScheme method is:
+%
+% InterlaceType MagickGetImageInterlaceScheme(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport InterlaceType MagickGetImageInterlaceScheme(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+ return(UndefinedInterlace);
+ }
+ return(wand->image->interlace);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e I t e r a t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageIterations() gets the image iterations.
+%
+% The format of the MagickGetImageIterations method is:
+%
+% unsigned long MagickGetImageIterations(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetImageIterations(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->iterations);
+}
+/*
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % %
+ % %
+ % %
+ % M a g i c k G e t I m a g e M a t t e %
+ % %
+ % %
+ % %
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+ % MagickGetImageMatte() gets the image matte flag. The flag is MagickTrue
+ % if the image supports an opacity (inverse of transparency) channel.
+ %
+ % The format of the MagickGetImageMatte method is:
+ %
+ % MagickBool MagickGetImageMatte(MagickWand *wand)
+ %
+ % A description of each parameter follows:
+ %
+ % o wand: The magick wand.
+ %
+ */
+WandExport MagickBool MagickGetImageMatte(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->matte);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e M a t t e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageMatteColor() returns the image matte color.
+%
+% The format of the MagickGetImageMatteColor method is:
+%
+% unsigned int MagickGetImageMatteColor(MagickWand *wand,
+% PixelWand *matte_color)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o matte_color: Return the matte color.
+%
+*/
+WandExport unsigned int MagickGetImageMatteColor(MagickWand *wand,
+ PixelWand *matte_color)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelSetQuantumColor(matte_color,&wand->image->matte_color);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e O r i e n t a t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageOrientation() gets the image orientation type. May be one of:
+%
+% UndefinedOrientation Image orientation not specified or error.
+% TopLeftOrientation Left to right and Top to bottom.
+% TopRightOrientation Right to left and Top to bottom.
+% BottomRightOrientation Right to left and Bottom to top.
+% BottomLeftOrientation Left to right and Bottom to top.
+% LeftTopOrientation Top to bottom and Left to right.
+% RightTopOrientation Top to bottom and Right to left.
+% RightBottomOrientation Bottom to top and Right to left.
+% LeftBottomOrientation Bottom to top and Left to right.
+%
+% The format of the MagickGetImageOrientation method is:
+%
+% OrientationType MagickGetImageOrientation(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport OrientationType MagickGetImageOrientation(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+ return(UndefinedOrientation);
+ }
+ return(wand->image->orientation);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e P a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImagePage() retrieves the image page size and offset used when
+% placing (e.g. compositing) the image.
+%
+% The format of the MagickGetImagePage method is:
+%
+% MagickGetImagePage(MagickWand *wand,
+% unsigned long *width,
+% unsigned long *height,
+% long *x,
+% long *y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o width, height: The region size.
+%
+% o x, y: Offset (from top left) on base canvas image on
+% which to composite image data.
+%
+*/
+WandExport unsigned int MagickGetImagePage(MagickWand *wand,
+ unsigned long *width,
+ unsigned long *height,
+ long *x,
+ long *y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ *width=wand->image->page.width;
+ *height=wand->image->page.height;
+ *x=wand->image->page.x;
+ *y=wand->image->page.y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImagePixels() extracts pixel data from an image and returns it to
+% you. The method returns False on success otherwise True if an error is
+% encountered. The data is returned as char, short int, int, long, float,
+% or double in the order specified by map.
+%
+% Suppose you want to extract the first scanline of a 640x480 image as
+% character data in red-green-blue order:
+%
+% MagickGetImagePixels(wand,0,0,640,1,"RGB",CharPixel,pixels);
+%
+% The format of the MagickGetImagePixels method is:
+%
+% unsigned int MagickGetImagePixels(MagickWand *wand,const long x_offset,
+% const long y_offset,const unsigned long columns,
+% const unsigned long rows,const char *map,const StorageType storage,
+% unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x_offset, y_offset, columns, rows: These values define the perimeter
+% of a region of pixels you want to extract.
+%
+% o map: This string reflects the expected ordering of the pixel array.
+% It can be any combination or order of R = red, G = green, B = blue,
+% A = alpha, C = cyan, Y = yellow, M = magenta, K = black, or
+% I = intensity (for grayscale).
+%
+% o storage: Define the data type of the pixels. Float and double types are
+% expected to be normalized [0..1] otherwise [0..MaxRGB]. Choose from
+% these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
+% or DoublePixel.
+%
+% o pixels: This array of values contain the pixel components as defined by
+% map and type. You must preallocate this array where the expected
+% length varies depending on the values of width, height, map, and type.
+%
+%
+*/
+WandExport unsigned int MagickGetImagePixels(MagickWand *wand,
+ const long x_offset,const long y_offset,const unsigned long columns,
+ const unsigned long rows,const char *map,const StorageType storage,
+ unsigned char *pixels)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=DispatchImage(wand->image,x_offset,y_offset,columns,rows,map,
+ storage,pixels,&wand->exception);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e P r o f i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageProfile() returns the named image profile.
+%
+% The format of the MagickGetImageProfile method is:
+%
+% unsigned char *MagickGetImageProfile(MagickWand *wand,const char *name,
+% unsigned long *length)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o name: Name of profile to return: ICC, IPTC, or generic profile.
+%
+% o length: The length of the profile.
+%
+*/
+WandExport unsigned char *MagickGetImageProfile(MagickWand *wand,
+ const char *name,unsigned long *length)
+{
+ size_t
+ profile_length=0;
+
+ const unsigned char
+ *profile=0;
+
+ unsigned char
+ *result=0;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ *length=0;
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ profile=GetImageProfile(wand->image,name,&profile_length);
+ if (profile)
+ {
+ result=MagickAllocateMemory(unsigned char *,profile_length);
+ if (result)
+ (void) memcpy(result,profile,profile_length);
+ }
+ *length=(unsigned long) profile_length;
+ return (result);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e R e d P r i m a r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageRedPrimary() returns the chromaticy red primary point.
+%
+% The format of the MagickGetImageRedPrimary method is:
+%
+% unsigned int MagickGetImageRedPrimary(MagickWand *wand,double *x,
+% double *y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The chromaticity red primary x-point.
+%
+% o y: The chromaticity red primary y-point.
+%
+*/
+WandExport unsigned int MagickGetImageRedPrimary(MagickWand *wand,double *x,
+ double *y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ *x=wand->image->chromaticity.red_primary.x;
+ *y=wand->image->chromaticity.red_primary.y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e R e n d e r i n g I n t e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageRenderingIntent() gets the image rendering intent.
+%
+% The format of the MagickGetImageRenderingIntent method is:
+%
+% RenderingIntent MagickGetImageRenderingIntent(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport RenderingIntent MagickGetImageRenderingIntent(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+ return(UndefinedIntent);
+ }
+ return((RenderingIntent) wand->image->rendering_intent);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e R e s o l u t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageResolution() gets the image X & Y resolution.
+%
+% The format of the MagickGetImageResolution method is:
+%
+% unsigned int MagickGetImageResolution(MagickWand *wand,double *x,
+% double *y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The image x-resolution.
+%
+% o y: The image y-resolution.
+%
+*/
+WandExport unsigned int MagickGetImageResolution(MagickWand *wand,double *x,
+ double *y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ *x=wand->image->x_resolution;
+ *y=wand->image->y_resolution;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e S c e n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageScene() gets the image scene.
+%
+% The format of the MagickGetImageScene method is:
+%
+% unsigned long MagickGetImageScene(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetImageScene(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->scene);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e S i g n a t u r e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageSignature() generates an SHA-256 message digest for the image
+% pixel stream.
+%
+% The format of the MagickGetImageSignature method is:
+%
+% const char MagickGetImageSignature(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport char *MagickGetImageSignature(MagickWand *wand)
+{
+ const ImageAttribute
+ *attribute;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=SignatureImage(wand->image);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ attribute=GetImageAttribute(wand->image,"signature");
+ if (attribute != (ImageAttribute *) NULL)
+ return(AcquireString(attribute->value));
+ CopyException(&wand->exception,&wand->image->exception);
+ return((char *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageSize() returns the image size.
+%
+% The format of the MagickGetImageSize method is:
+%
+% MagickSizeType MagickGetImageSize(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport MagickSizeType MagickGetImageSize(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(GetBlobSize(wand->image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e T y p e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageType() gets the image type.
+%
+% The format of the MagickGetImageType method is:
+%
+% ImageType MagickGetImageType(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport ImageType MagickGetImageType(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+ return(UndefinedType);
+ }
+ return(GetImageType(wand->image,&wand->exception));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e S a v e d T y p e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageSavedType() gets the image type that will be used when the
+% image is saved. This may be different to the current image type, returned
+% by MagickGetImageType().
+%
+% The format of the MagickGetImageSavedType method is:
+%
+% ImageType MagickGetImageSavedType(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport ImageType MagickGetImageSavedType(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->image_info->type);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e U n i t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageUnits() gets the image units of resolution.
+%
+% The format of the MagickGetImageUnits method is:
+%
+% ResolutionType MagickGetImageUnits(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport ResolutionType MagickGetImageUnits(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+ return(UndefinedResolution);
+ }
+ return(wand->image->units);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e V i r t u a l P i x e l M e t h o d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageVirtualPixelMethod() returns the virtual pixel method for the
+% sepcified image.
+%
+% The format of the MagickGetImageVirtualPixelMethod method is:
+%
+% VirtualPixelMethod MagickGetImageVirtualPixelMethod(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport VirtualPixelMethod MagickGetImageVirtualPixelMethod(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ {
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+ return(UndefinedVirtualPixelMethod);
+ }
+ return(GetImageVirtualPixelMethod(wand->image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e W h i t e P o i n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageWhitePoint() returns the chromaticy white point.
+%
+% The format of the MagickGetImageWhitePoint method is:
+%
+% unsigned int MagickGetImageWhitePoint(MagickWand *wand,double *x,
+% double *y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The chromaticity white x-point.
+%
+% o y: The chromaticity white y-point.
+%
+*/
+WandExport unsigned int MagickGetImageWhitePoint(MagickWand *wand,double *x,
+ double *y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ *x=wand->image->chromaticity.white_point.x;
+ *y=wand->image->chromaticity.white_point.y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t I m a g e W i d t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetImageWidth() returns the image width.
+%
+% The format of the MagickGetImageWidth method is:
+%
+% unsigned long MagickGetImageWidth(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetImageWidth(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(wand->image->columns);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t N u m b e r I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetNumberOfImages() returns the number of images associated with a
+% magick wand.
+%
+% The format of the MagickGetNumberImages method is:
+%
+% unsigned long MagickGetNumberImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetNumberImages(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(GetImageListLength(wand->image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t P a c k a g e N a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetPackageName() returns the ImageMagick package name.
+%
+% The format of the MagickGetPackageName method is:
+%
+% const char *MagickGetPackageName(void)
+%
+%
+*/
+WandExport const char *MagickGetPackageName(void)
+{
+ return(MagickPackageName);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t Q u a n t u m D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetQuantumDepth() returns the ImageMagick quantum depth.
+%
+% The format of the MagickGetQuantumDepth method is:
+%
+% const char *MagickGetQuantumDepth(unsigned long *depth)
+%
+% A description of each parameter follows:
+%
+% o depth: The quantum depth is returned as a number.
+%
+%
+*/
+WandExport const char *MagickGetQuantumDepth(unsigned long *depth)
+{
+ *depth = (unsigned long) QuantumDepth;
+ return(MagickQuantumDepth);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t R e l e a s e D a t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetReleaseDate() returns the ImageMagick release date.
+%
+% The format of the MagickGetReleaseDate method is:
+%
+% const char *MagickGetReleaseDate(void)
+%
+*/
+WandExport const char *MagickGetReleaseDate(void)
+{
+ return(MagickReleaseDate);
+}
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t R e s o u r c e L i m i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetResourceLimit() returns the the specified resource in megabytes.
+%
+% The format of the MagickGetResourceLimit method is:
+%
+% unsigned long MagickGetResourceLimit(const ResourceType type)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned long MagickGetResourceLimit(const ResourceType type)
+{
+ return(GetMagickResource(type));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t S a m p l i n g F a c t o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetSamplingFactors() gets the horizontal and vertical sampling factor.
+%
+% The format of the MagickGetSamplingFactors method is:
+%
+% double *MagickGetSamplingFactors(MagickWand *wand,
+% unsigned long *number_factors)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o number_factors: The number of factors in the returned array.
+%
+*/
+WandExport double *MagickGetSamplingFactors(MagickWand *wand,
+ unsigned long *number_factors)
+{
+ double
+ *sampling_factors;
+
+ register const char
+ *p;
+
+ register long
+ i;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ *number_factors=0;
+ sampling_factors=(double *) NULL;
+ if (wand->image_info->sampling_factor == (char *) NULL)
+ return(sampling_factors);
+ i=0;
+ for (p=wand->image_info->sampling_factor; p != (char *) NULL; p=strchr(p,','))
+ {
+ while (((int) *p != 0) && ((isspace((int) ((unsigned char) *p)) != 0) ||
+ (*p == ',')))
+ p++;
+ i++;
+ }
+ sampling_factors=MagickAllocateMemory(double *,(size_t) i*sizeof(double));
+ if (sampling_factors == (double *) NULL)
+ MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
+ wand->image_info->filename);
+ i=0;
+ for (p=wand->image_info->sampling_factor; p != (char *) NULL; p=strchr(p,','))
+ {
+ while (((int) *p != 0) && ((isspace((int) ((unsigned char) *p)) != 0) ||
+ (*p == ',')))
+ p++;
+ sampling_factors[i]=atof(p);
+ i++;
+ }
+ *number_factors=(unsigned long) i;
+ return(sampling_factors);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetSize() returns the size associated with the magick wand.
+%
+% The format of the MagickGetSize method is:
+%
+% unsigned int MagickGetSize(const MagickWand *wand,unsigned long *columns,
+% unsigned long *rows)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o columns: The width in pixels.
+%
+% o height: The height in pixels.
+%
+*/
+WandExport unsigned int MagickGetSize(const MagickWand *wand,
+ unsigned long *columns,
+ unsigned long *rows)
+{
+ RectangleInfo
+ geometry;
+
+ assert(wand != (const MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) memset(&geometry,0,sizeof(RectangleInfo));
+ (void) GetGeometry(wand->image_info->size,&geometry.x,&geometry.y,
+ &geometry.width,&geometry.height);
+ *columns=geometry.width;
+ *rows=geometry.height;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k G e t V e r s i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickGetVersion() returns the ImageMagick API version as a string and
+% as a number.
+%
+% The format of the MagickGetVersion method is:
+%
+% const char *MagickGetVersion(unsigned long *version)
+%
+% A description of each parameter follows:
+%
+% o version: The ImageMagick version is returned as a number.
+%
+*/
+WandExport const char *MagickGetVersion(unsigned long *version)
+{
+ return(GetMagickVersion(version));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k H a l d C l u t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The MagickHaldClutImage() method apply a color lookup table (Hald CLUT) to
+% the image. The fundamental principle of the Hald CLUT algorithm is that
+% application of an identity CLUT causes no change to the input image,
+% but an identity CLUT image which has had its colors transformed in
+% some way (e.g. in Adobe Photoshop) may be used to implement an identical
+% transform on any other image.
+%
+% The minimum CLUT level is 2, and the maximum depends on available memory
+% (largest successfully tested is 24). A CLUT image is required to have equal
+% width and height. A CLUT of level 8 is an image of dimension 512x512, a CLUT
+% of level 16 is an image of dimension 4096x4096. Interpolation is used so
+% extremely large CLUT images are not required.
+%
+% GraphicsMagick provides an 'identity' coder which may be used to generate
+% identity HLUTs. For example, reading from "identity:8" creates an identity
+% CLUT of order 8.
+%
+% The Hald CLUT algorithm has been developed by Eskil Steenberg as described
+% at http://www.quelsolaar.com/technology/clut.html, and was adapted for
+% GraphicsMagick by Clment Follet with support from Cdric Lejeune of
+% Workflowers.
+%
+% The format of the HaldClutImage method is:
+%
+% MagickPassFail MagickHaldClutImage(MagickWand *wand,const MagickWand *clut_wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The image wand.
+%
+% o clut_wand: The color lookup table image wand
+%
+%
+*/
+WandExport MagickPassFail MagickHaldClutImage(MagickWand *wand,const MagickWand *clut_wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(clut_wand != (MagickWand *) NULL);
+ assert(clut_wand->signature == MagickSignature);
+
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ if (clut_wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ return HaldClutImage(wand->image,clut_wand->image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k H a s N e x t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickHasNextImage() returns True if the wand has more images when
+% traversing the list in the forward direction
+%
+% The format of the MagickHasNextImage method is:
+%
+% unsigned int MagickHasNextImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickHasNextImage(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ if (GetNextImageInList(wand->image) == (Image *) NULL)
+ return(False);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k H a s P r e v i o u s I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickHasPreviousImage() returns True if the wand has more images when
+% traversing the list in the reverse direction
+%
+% The format of the MagickHasPreviousImage method is:
+%
+% unsigned int MagickHasPreviousImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickHasPreviousImage(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ if (GetPreviousImageInList(wand->image) == (Image *) NULL)
+ return(False);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k I m p l o d e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickImplodeImage() creates a new image that is a copy of an existing
+% one with the image pixels "implode" by the specified percentage. It
+% allocates the memory necessary for the new Image structure and returns a
+% pointer to the new image.
+%
+% The format of the MagickImplodeImage method is:
+%
+% unsigned int MagickImplodeImage(MagickWand *wand,const double radius)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o amount: Define the extent of the implosion.
+%
+*/
+WandExport unsigned int MagickImplodeImage(MagickWand *wand,const double amount)
+{
+ Image
+ *implode_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ implode_image=ImplodeImage(wand->image,amount,&wand->exception);
+ if (implode_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,implode_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k L a b e l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickLabelImage() adds a label to your image.
+%
+% The format of the MagickLabelImage method is:
+%
+% unsigned int MagickLabelImage(MagickWand *wand,const char *label)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o label: The image label.
+%
+*/
+WandExport unsigned int MagickLabelImage(MagickWand *wand,const char *label)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) SetImageAttribute(wand->image,"label",(char *) NULL);
+ status=SetImageAttribute(wand->image,"label",label);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k L e v e l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickLevelImage() adjusts the levels of an image by scaling the colors
+% falling between specified white and black points to the full available
+% quantum range. The parameters provided represent the black, mid, and white
+% points. The black point specifies the darkest color in the image. Colors
+% darker than the black point are set to zero. Mid point specifies a gamma
+% correction to apply to the image. White point specifies the lightest color
+% in the image. Colors brighter than the white point are set to the maximum
+% quantum value.
+%
+% The format of the MagickLevelImage method is:
+%
+% unsigned int MagickLevelImage(MagickWand *wand,const double black_point,
+% const double gamma,const double white_point)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o black_point: The black point.
+%
+% o gamma: The gamma.
+%
+% o white_point: The white point.
+%
+*/
+WandExport unsigned int MagickLevelImage(MagickWand *wand,
+ const double black_point,const double gamma,const double white_point)
+{
+ char
+ levels[MaxTextExtent];
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) MagickFormatString(levels,MaxTextExtent,"%g,%g,%g",black_point,
+ white_point,gamma);
+ status=LevelImage(wand->image,levels);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k L e v e l I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickLevelImageChannel() adjusts the levels of the specified channel of
+% the reference image by scaling the colors falling between specified white
+% and black points to the full available quantum range. The parameters
+% provided represent the black, mid, and white points. The black point
+% specifies the darkest color in the image. Colors darker than the black
+% point are set to zero. Mid point specifies a gamma correction to apply
+% to the image. White point specifies the lightest color in the image.
+% Colors brighter than the white point are set to the maximum quantum value.
+%
+% The format of the MagickLevelImageChannel method is:
+%
+% unsigned int MagickLevelImageChannel(MagickWand *wand,
+% const ChannelType channel,const double black_point,
+% const double gamma,const double white_point)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: Identify which channel to level: RedChannel, GreenChannel,
+% BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+% BlackChannel.
+%
+% o black_point: The black point.
+%
+% o gamma: The gamma.
+%
+% o white_point: The white point.
+%
+*/
+WandExport unsigned int MagickLevelImageChannel(MagickWand *wand,
+ const ChannelType channel,const double black_point,const double gamma,
+ const double white_point)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=LevelImageChannel(wand->image,channel,black_point,white_point,gamma);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M a g n i f y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMagnifyImage() is a convenience method that scales an image
+% proportionally to twice its original size.
+%
+% The format of the MagickMagnifyImage method is:
+%
+% unsigned int MagickMagnifyImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickMagnifyImage(MagickWand *wand)
+{
+ Image
+ *magnify_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ magnify_image=MagnifyImage(wand->image,&wand->exception);
+ if (magnify_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,magnify_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M a p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMapImage() replaces the colors of an image with the closest color
+% from a reference image.
+%
+% The format of the MagickMapImage method is:
+%
+% unsigned int MagickMapImage(MagickWand *wand,const MagickWand *map_wand,
+% const unsigned int dither)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o map: The map wand.
+%
+% o dither: Set this integer value to something other than zero to dither
+% the mapped image.
+%
+*/
+WandExport unsigned int MagickMapImage(MagickWand *wand,
+ const MagickWand *map_wand,const unsigned int dither)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if ((wand->images == (Image *) NULL) || (map_wand->images == (Image *) NULL))
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=MapImage(wand->image,map_wand->image,dither);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M a t t e F l o o d f i l l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMatteFloodfillImage() changes the transparency value of any pixel that
+% matches target and is an immediate neighbor. If the method
+% FillToBorderMethod is specified, the transparency value is changed for any
+% neighbor pixel that does not match the bordercolor member of image.
+%
+% The format of the MagickMatteFloodfillImage method is:
+%
+% unsigned int MagickMatteFloodfillImage(MagickWand *wand,
+% const Quantum opacity,const double fuzz,const PixelWand *bordercolor,
+% const long x,const long y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o opacity: The opacity.
+%
+% o fuzz: By default target must match a particular pixel color
+% exactly. However, in many cases two colors may differ by a small amount.
+% The fuzz member of image defines how much tolerance is acceptable to
+% consider two colors as the same. For example, set fuzz to 10 and the
+% color red at intensities of 100 and 102 respectively are now interpreted
+% as the same color for the purposes of the floodfill.
+%
+% o bordercolor: The border color pixel wand.
+%
+% o x,y: The starting location of the operation.
+%
+*/
+WandExport unsigned int MagickMatteFloodfillImage(MagickWand *wand,
+ const Quantum opacity,const double fuzz,const PixelWand *bordercolor,
+ const long x,const long y)
+{
+ DrawInfo
+ *draw_info;
+
+ PixelPacket
+ target;
+
+ unsigned int
+ status;
+
+ ARG_NOT_USED(fuzz);
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ draw_info=CloneDrawInfo(wand->image_info,(DrawInfo *) NULL);
+ (void) AcquireOnePixelByReference(wand->image,&target,x % wand->image->columns,
+ y % wand->image->rows,&wand->exception);
+ if (bordercolor != (PixelWand *) NULL)
+ PixelGetQuantumColor(bordercolor,&target);
+ status=MatteFloodfillImage(wand->image,target,opacity,x,y,
+ bordercolor != (PixelWand *) NULL ? FillToBorderMethod : FloodfillMethod);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ DestroyDrawInfo(draw_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M e d i a n F i l t e r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMedianFilterImage() applies a digital filter that improves the quality
+% of a noisy image. Each pixel is replaced by the median in a set of
+% neighboring pixels as defined by radius.
+%
+% The format of the MagickMedianFilterImage method is:
+%
+% unsigned int MagickMedianFilterImage(MagickWand *wand,
+% const double radius)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the pixel neighborhood.
+%
+*/
+WandExport unsigned int MagickMedianFilterImage(MagickWand *wand,
+ const double radius)
+{
+ Image
+ *median_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ median_image=MedianFilterImage(wand->image,radius,&wand->exception);
+ if (median_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,median_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M i n i f y I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMinifyImage() is a convenience method that scales an image
+% proportionally to one-half its original size
+%
+% The format of the MagickMinifyImage method is:
+%
+% unsigned int MagickMinifyImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickMinifyImage(MagickWand *wand)
+{
+ Image
+ *minify_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ minify_image=MinifyImage(wand->image,&wand->exception);
+ if (minify_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,minify_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M o d u l a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickModulateImage() lets you control the brightness, saturation, and hue
+% of an image.
+%
+% The format of the MagickModulateImage method is:
+%
+% unsigned int MagickModulateImage(MagickWand *wand,
+% const double brightness,const double saturation,const double hue)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o brightness: The percent change in brighness (-100 thru +100).
+%
+% o saturation: The percent change in saturation (-100 thru +100)
+%
+% o hue: The percent change in hue (-100 thru +100)
+%
+*/
+WandExport unsigned int MagickModulateImage(MagickWand *wand,
+ const double brightness,const double saturation,const double hue)
+{
+ char
+ modulate[MaxTextExtent];
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) MagickFormatString(modulate,MaxTextExtent,"%g,%g,%g",brightness,
+ saturation,hue);
+ status=ModulateImage(wand->image,modulate);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M o n t a g e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use MagickMontageImage() to create a composite image by combining several
+% separate images. The images are tiled on the composite image with the name
+% of the image optionally appearing just below the individual tile.
+%
+% The format of the MagickMontageImage method is:
+%
+% MagickWand MagickMontageImage(MagickWand *wand,
+% const DrawingWand drawing_wand,const char *tile_geometry,
+% const char *thumbnail_geometry,const MontageMode mode,
+% const char *frame)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o drawing_wand: The drawing wand. The font name, size, and color are
+% obtained from this wand.
+%
+% o tile_geometry: the number of tiles per row and page (e.g. 6x4+0+0).
+%
+% o thumbnail_geometry: Preferred image size and border size of each
+% thumbnail (e.g. 120x120+4+3>).
+%
+% o mode: Thumbnail framing mode: Frame, Unframe, or Concatenate.
+%
+% o frame: Surround the image with an ornamental border (e.g. 15x15+3+3).
+% The frame color is that of the thumbnail's matte color.
+%
+*/
+WandExport MagickWand *MagickMontageImage(MagickWand *wand,
+ const DrawingWand *drawing_wand,const char *tile_geometry,
+ const char *thumbnail_geometry,const MontageMode mode,const char *frame)
+{
+ char
+ *font;
+
+ Image
+ *montage_image;
+
+ MontageInfo
+ *montage_info;
+
+ PixelWand
+ *pixel_wand;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ montage_info=CloneMontageInfo(wand->image_info,(MontageInfo *) NULL);
+ switch (mode)
+ {
+ case FrameMode:
+ {
+ (void) CloneString(&montage_info->frame,"15x15+3+3");
+ montage_info->shadow=True;
+ break;
+ }
+ case UnframeMode:
+ {
+ montage_info->frame=(char *) NULL;
+ montage_info->shadow=False;
+ montage_info->border_width=0;
+ break;
+ }
+ case ConcatenateMode:
+ {
+ montage_info->frame=(char *) NULL;
+ montage_info->shadow=False;
+ (void) CloneString(&montage_info->geometry,"+0+0");
+ montage_info->border_width=0;
+ break;
+ }
+ default:
+ break;
+ }
+ font=DrawGetFont(drawing_wand);
+ if (font != (char *) NULL)
+ {
+ (void) CloneString(&montage_info->font,font);
+ MagickFreeMemory(font);
+ }
+ if (frame != (char *) NULL)
+ (void) CloneString(&montage_info->frame,frame);
+ montage_info->pointsize=DrawGetFontSize(drawing_wand);
+ pixel_wand=NewPixelWand();
+ DrawGetFillColor(drawing_wand,pixel_wand);
+ PixelGetQuantumColor(pixel_wand,&montage_info->fill);
+ DrawGetStrokeColor(drawing_wand,pixel_wand);
+ PixelGetQuantumColor(pixel_wand,&montage_info->stroke);
+ DestroyPixelWand(pixel_wand);
+ if (thumbnail_geometry != (char *) NULL)
+ (void) CloneString(&montage_info->geometry,thumbnail_geometry);
+ if (tile_geometry != (char *) NULL)
+ (void) CloneString(&montage_info->tile,tile_geometry);
+ montage_image=MontageImages(wand->images,montage_info,&wand->exception);
+ DestroyMontageInfo(montage_info);
+ if (montage_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,montage_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M o r p h I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMorphImages() method morphs a set of images. Both the image pixels
+% and size are linearly interpolated to give the appearance of a
+% meta-morphosis from one image to the next.
+%
+% The format of the MagickMorphImages method is:
+%
+% MagickWand *MagickMorphImages(MagickWand *wand,
+% const unsigned long number_frames)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o number_frames: The number of in-between images to generate.
+%
+*/
+WandExport MagickWand *MagickMorphImages(MagickWand *wand,
+ const unsigned long number_frames)
+{
+ Image
+ *morph_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ morph_image=MorphImages(wand->images,number_frames,&wand->exception);
+ if (morph_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,morph_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M o s a i c I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMosaicImages() inlays an image sequence to form a single coherent
+% picture. It returns a wand with each image in the sequence composited at
+% the location defined by the page offset of the image.
+%
+% The format of the MagickMosaicImages method is:
+%
+% MagickWand *MagickMosaicImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport MagickWand *MagickMosaicImages(MagickWand *wand)
+{
+ Image
+ *mosaic_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ mosaic_image=MosaicImages(wand->images,&wand->exception);
+ if (mosaic_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,mosaic_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M o t i o n B l u r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMotionBlurImage() simulates motion blur. We convolve the image with a
+% Gaussian operator of the given radius and standard deviation (sigma).
+% For reasonable results, radius should be larger than sigma. Use a
+% radius of 0 and MotionBlurImage() selects a suitable radius for you.
+% Angle gives the angle of the blurring motion.
+%
+% The format of the MagickMotionBlurImage method is:
+%
+% unsigned int MagickMotionBlurImage(MagickWand *wand,
+% const double radius,const double sigma,const double angle)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting
+% the center pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o angle: Apply the effect along this angle.
+%
+*/
+WandExport unsigned int MagickMotionBlurImage(MagickWand *wand,
+ const double radius,const double sigma,const double angle)
+{
+ Image
+ *blur_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ blur_image=MotionBlurImage(wand->image,radius,sigma,angle,&wand->exception);
+ if (blur_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,blur_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k N e g a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickNegateImage() negates the colors in the reference image. The
+% Grayscale option means that only grayscale values within the image are
+% negated.
+%
+% You can also reduce the influence of a particular channel with a gamma
+% value of 0.
+%
+% The format of the MagickNegateImage method is:
+%
+% unsigned int MagickNegateImage(MagickWand *wand,const unsigned int gray)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o gray: If True, only negate grayscale pixels within the image.
+%
+*/
+WandExport unsigned int MagickNegateImage(MagickWand *wand,
+ const unsigned int gray)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=NegateImage(wand->image,gray);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k N e g a t e I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickNegateImageChannel() negates the colors in the specified channel of the
+% reference image. The Grayscale option means that only grayscale values
+% within the image are negated. Note that the Grayscale option has no
+% effect for GraphicsMagick.
+%
+% You can also reduce the influence of a particular channel with a gamma
+% value of 0.
+%
+% The format of the MagickNegateImageChannel method is:
+%
+% unsigned int MagickNegateImageChannel(MagickWand *wand,
+% const ChannelType channel,const unsigned int gray)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: Identify which channel to extract: RedChannel, GreenChannel,
+% BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+% BlackChannel.
+%
+% o gray: If True, only negate grayscale pixels within the image.
+%
+*/
+WandExport unsigned int MagickNegateImageChannel(MagickWand *wand,
+ const ChannelType channel,const unsigned int gray)
+{
+ ARG_NOT_USED(gray);
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return QuantumOperatorImage(wand->image,channel,NegateQuantumOp,
+ 0,&wand->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k N e x t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickNextImage() associates the next image in the image list with a magick
+% wand. True is returned if the Wand iterated to a next image, or False is
+% returned if the wand did not iterate to a next image.
+%
+% The format of the MagickNextImage method is:
+%
+% unsigned int MagickNextImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickNextImage(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ if (GetNextImageInList(wand->image) == (Image *) NULL)
+ {
+ wand->iterator=True;
+ return(False);
+ }
+ if (wand->iterator != False)
+ {
+ wand->iterator=False;
+ return(True);
+ }
+ wand->image=GetNextImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k N o r m a l i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickNormalizeImage() enhances the contrast of a color image by adjusting
+% the pixels color to span the entire range of colors available
+%
+% You can also reduce the influence of a particular channel with a gamma
+% value of 0.
+%
+% The format of the MagickNormalizeImage method is:
+%
+% unsigned int MagickNormalizeImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickNormalizeImage(MagickWand *wand)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=NormalizeImage(wand->image);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k O i l P a i n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickOilPaintImage() applies a special effect filter that simulates an oil
+% painting. Each pixel is replaced by the most frequent color occurring
+% in a circular region defined by radius.
+%
+% The format of the MagickOilPaintImage method is:
+%
+% unsigned int MagickOilPaintImage(MagickWand *wand,const double radius)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the circular neighborhood.
+%
+*/
+WandExport unsigned int MagickOilPaintImage(MagickWand *wand,
+ const double radius)
+{
+ Image
+ *paint_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ paint_image=OilPaintImage(wand->image,radius,&wand->exception);
+ if (paint_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,paint_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k O p a q u e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickOpaqueImage() changes any pixel that matches color with the color
+% defined by fill.
+%
+% The format of the MagickOpaqueImage method is:
+%
+% unsigned int MagickOpaqueImage(MagickWand *wand,const PixelWand *target,
+% const PixelWand *fill,const double fuzz)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o target: Change this target color to the fill color within the image.
+%
+% o fill: The fill pixel wand.
+%
+% o fuzz: By default target must match a particular pixel color
+% exactly. However, in many cases two colors may differ by a small amount.
+% The fuzz member of image defines how much tolerance is acceptable to
+% consider two colors as the same. For example, set fuzz to 10 and the
+% color red at intensities of 100 and 102 respectively are now interpreted
+% as the same color for the purposes of the floodfill.
+%
+*/
+WandExport unsigned int MagickOpaqueImage(MagickWand *wand,
+ const PixelWand *target,const PixelWand *fill,const double fuzz)
+{
+ PixelPacket
+ fill_pixel,
+ target_pixel;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelGetQuantumColor(target,&target_pixel);
+ PixelGetQuantumColor(fill,&fill_pixel);
+ wand->image->fuzz=fuzz;
+ status=OpaqueImage(wand->image,target_pixel,fill_pixel);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % %
+ % %
+ % %
+ % M a g i c k O p e r a t o r I m a g e C h a n n e l %
+ % %
+ % %
+ % %
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+ % MagickOperatorImageChannel() performs the requested arithmetic,
+ % bitwise-logical, or value operation on the selected channels of
+ % the entire image. The AllChannels channel option operates on all
+ % color channels whereas the GrayChannel channel option treats the
+ % color channels as a grayscale intensity.
+ %
+ % These operations are on the DirectClass pixels of the image and do not
+ % update pixel indexes or colormap.
+ %
+ % The format of the MagickOperatorImageChannel method is:
+ %
+ % MagickPassFail MagickOperatorImageChannel(MagickWand *wand,
+ % const ChannelType channel,const QuantumOperator quantum_operator,
+ % const double rvalue)
+ %
+ % A description of each parameter follows:
+ %
+ % o wand: The magick wand.
+ %
+ % o channel: Channel to operate on (RedChannel, CyanChannel,
+ % GreenChannel, MagentaChannel, BlueChannel, YellowChannel,
+ % OpacityChannel, BlackChannel, MatteChannel, AllChannels,
+ % GrayChannel). The AllChannels type only updates color
+ % channels. The GrayChannel type treats the color channels
+ % as if they represent an intensity.
+ %
+ % o quantum_operator: Operator to use (AddQuantumOp,AndQuantumOp,
+ % AssignQuantumOp, DepthQuantumOp, DivideQuantumOp, GammaQuantumOp,
+ % LShiftQuantumOp, MultiplyQuantumOp, NegateQuantumOp,
+ % NoiseGaussianQuantumOp, NoiseImpulseQuantumOp,
+ % NoiseLaplacianQuantumOp, NoiseMultiplicativeQuantumOp,
+ % NoisePoissonQuantumOp, NoiseRandomQuantumOp, NoiseUniformQuantumOp,
+ % OrQuantumOp, RShiftQuantumOp, SubtractQuantumOp,
+ % ThresholdBlackQuantumOp, ThresholdQuantumOp, ThresholdWhiteQuantumOp,
+ % ThresholdBlackNegateQuantumOp, ThresholdWhiteNegateQuantumOp,
+ % XorQuantumOp).
+ %
+ % o rvalue: Operator argument.
+ %
+ */
+WandExport unsigned int
+MagickOperatorImageChannel(MagickWand *wand,
+ const ChannelType channel,
+ const QuantumOperator quantum_operator,
+ const double rvalue)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return QuantumOperatorImage(wand->image,channel,quantum_operator,
+ rvalue,&wand->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k P i n g I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickPingImage() is like MagickReadImage() except the only valid
+% information returned is the image width, height, size, and format. It
+% is designed to efficiently obtain this information from a file without
+% reading the entire image sequence into memory.
+%
+% The format of the MagickPingImage method is:
+%
+% unsigned int MagickPingImage(MagickWand *wand,const char *filename)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o filename: The image filename.
+%
+%
+*/
+WandExport unsigned int MagickPingImage(MagickWand *wand,const char *filename)
+{
+ Image
+ *images;
+
+ ImageInfo
+ *ping_info;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ ping_info=CloneImageInfo(wand->image_info);
+ (void) strlcpy(ping_info->filename,filename,MaxTextExtent);
+ images=PingImage(ping_info,&wand->exception);
+ DestroyImageInfo(ping_info);
+ if (images == (Image *) NULL)
+ return(False);
+ AppendImageToList(&wand->images,images);
+ wand->image=GetLastImageInList(wand->images);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k P r e v i e w I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickPreviewImages() tiles 9 thumbnails of the specified image with an
+% image processing operation applied at varying strengths. This is helpful
+% to quickly pin-point an appropriate parameter for an image processing
+% operation.
+%
+% The format of the MagickPreviewImages method is:
+%
+% MagickWand *MagickPreviewImages(MagickWand *wand,
+% const PreviewType preview)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o preview: The preview type.
+%
+*/
+WandExport MagickWand *MagickPreviewImages(MagickWand *wand,
+ const PreviewType preview)
+{
+#if defined(NOT_IMPLEMENTED)
+ Image
+ *preview_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ preview_image=PreviewImage(wand->images,preview,&wand->exception);
+ if (preview_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWand(wand,preview_image));
+#else
+ ARG_NOT_USED(preview);
+ ThrowWandException(WandError,WandAPINotImplemented,"MagickPreviewImages");
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k P r e v i o u s I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickPreviousImage() selects the previous image associated with a magick
+% wand.
+%
+% The format of the MagickPreviousImage method is:
+%
+% unsigned int MagickPreviousImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickPreviousImage(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if ((wand->images == (Image *) NULL) ||
+ (wand->image->previous == (Image *) NULL))
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ if (GetPreviousImageInList(wand->image) == (Image *) NULL)
+ {
+ wand->iterator=True;
+ return(False);
+ }
+ if (wand->iterator != False)
+ {
+ wand->iterator=False;
+ return(True);
+ }
+ wand->image=GetPreviousImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k P r o f i l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use MagickProfileImage() to add or remove a ICC, IPTC, or generic profile
+% from an image. If the profile is NULL, it is removed from the image
+% otherwise added. Use a name of '*' and a profile of NULL to remove all
+% profiles from the image.
+%
+% The format of the MagickProfileImage method is:
+%
+% unsigned int MagickProfileImage(MagickWand *wand,const char *name,
+% const unsigned char *profile,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o name: Name of profile to add or remove: ICC, IPTC, or generic profile.
+%
+% o profile: The profile.
+%
+% o length: The length of the profile.
+%
+*/
+WandExport unsigned int MagickProfileImage(MagickWand *wand,const char *name,
+ const unsigned char *profile,const unsigned long length)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=ProfileImage(wand->image,name,(unsigned char *)profile,length,True);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k Q u a n t i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickQuantizeImage() analyzes the colors within a reference image and
+% chooses a fixed number of colors to represent the image. The goal of the
+% algorithm is to minimize the color difference between the input and output
+% image while minimizing the processing time.
+%
+% The format of the MagickQuantizeImage method is:
+%
+% unsigned int MagickQuantizeImage(MagickWand *wand,
+% const unsigned long number_colors,const ColorspaceType colorspace,
+% const unsigned long treedepth,const unsigned int dither,
+% const unsigned int measure_error)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o number_colors: The number of colors.
+%
+% o colorspace: Perform color reduction in this colorspace, typically
+% RGBColorspace.
+%
+% o treedepth: Normally, this integer value is zero or one. A zero or
+% one tells Quantize to choose a optimal tree depth of Log4(number_colors).% A tree of this depth generally allows the best representation of the
+% reference image with the least amount of memory and the fastest
+% computational speed. In some cases, such as an image with low color
+% dispersion (a few number of colors), a value other than
+% Log4(number_colors) is required. To expand the color tree completely,
+% use a value of 8.
+%
+% o dither: A value other than zero distributes the difference between an
+% original image and the corresponding color reduced algorithm to
+% neighboring pixels along a Hilbert curve.
+%
+% o measure_error: A value other than zero measures the difference between
+% the original and quantized images. This difference is the total
+% quantization error. The error is computed by summing over all pixels
+% in an image the distance squared in RGB space between each reference
+% pixel value and its quantized value.
+%
+*/
+WandExport unsigned int MagickQuantizeImage(MagickWand *wand,
+ const unsigned long number_colors,const ColorspaceType colorspace,
+ const unsigned long treedepth,const unsigned int dither,
+ const unsigned int measure_error)
+{
+ QuantizeInfo
+ *quantize_info;
+
+ unsigned int
+ status;
+
+ ARG_NOT_USED(dither);
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
+ quantize_info->number_colors=number_colors;
+ quantize_info->tree_depth=treedepth;
+ quantize_info->colorspace=colorspace;
+ quantize_info->measure_error=measure_error;
+ status=QuantizeImage(quantize_info,wand->image);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ DestroyQuantizeInfo(quantize_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k Q u a n t i z e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickQuantizeImage() analyzes the colors within a sequence of images and
+% chooses a fixed number of colors to represent the image. The goal of the
+% algorithm is to minimize the color difference between the input and output
+% image while minimizing the processing time.
+%
+% The format of the MagickQuantizeImages method is:
+%
+% unsigned int MagickQuantizeImages(MagickWand *wand,
+% const unsigned long number_colors,const ColorspaceType colorspace,
+% const unsigned long treedepth,const unsigned int dither,
+% const unsigned int measure_error)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o number_colors: The number of colors.
+%
+% o colorspace: Perform color reduction in this colorspace, typically
+% RGBColorspace.
+%
+% o treedepth: Normally, this integer value is zero or one. A zero or
+% one tells Quantize to choose a optimal tree depth of Log4(number_colors).% A tree of this depth generally allows the best representation of the
+% reference image with the least amount of memory and the fastest
+% computational speed. In some cases, such as an image with low color
+% dispersion (a few number of colors), a value other than
+% Log4(number_colors) is required. To expand the color tree completely,
+% use a value of 8.
+%
+% o dither: A value other than zero distributes the difference between an
+% original image and the corresponding color reduced algorithm to
+% neighboring pixels along a Hilbert curve.
+%
+% o measure_error: A value other than zero measures the difference between
+% the original and quantized images. This difference is the total
+% quantization error. The error is computed by summing over all pixels
+% in an image the distance squared in RGB space between each reference
+% pixel value and its quantized value.
+%
+*/
+WandExport unsigned int MagickQuantizeImages(MagickWand *wand,
+ const unsigned long number_colors,const ColorspaceType colorspace,
+ const unsigned long treedepth,const unsigned int dither,
+ const unsigned int measure_error)
+{
+ QuantizeInfo
+ *quantize_info;
+
+ unsigned int
+ status;
+
+ ARG_NOT_USED(dither);
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
+ quantize_info->number_colors=number_colors;
+ quantize_info->tree_depth=treedepth;
+ quantize_info->colorspace=colorspace;
+ quantize_info->measure_error=measure_error;
+ status=QuantizeImages(quantize_info,wand->images);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ DestroyQuantizeInfo(quantize_info);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k Q u e r y F o n t M e t r i c s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickQueryFontMetrics() returns a 7 element array representing the
+% following font metrics:
+%
+% Element Description
+% -------------------------------------------------
+% 0 character width
+% 1 character height
+% 2 ascender
+% 3 descender
+% 4 text width
+% 5 text height
+% 6 maximum horizontal advance
+%
+% The format of the MagickQueryFontMetrics method is:
+%
+% double *MagickQueryFontMetrics(MagickWand *wand,
+% const DrawingWand *drawing_wand,const char *text)
+%
+% A description of each parameter follows:
+%
+% o wand: The Magick wand.
+%
+% o drawing_wand: The drawing wand.
+%
+% o text: The text.
+%
+% */
+WandExport double *MagickQueryFontMetrics(MagickWand *wand,
+ const DrawingWand *drawing_wand,const char *text)
+{
+ double
+ *font_metrics;
+
+ DrawInfo
+ *draw_info;
+
+ TypeMetric
+ metrics;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(drawing_wand != (const DrawingWand *) NULL);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ font_metrics=MagickAllocateMemory(double *,7*sizeof(double));
+ if (font_metrics == (double *) NULL)
+ return((double *) NULL);
+ draw_info=DrawPeekGraphicContext(drawing_wand);
+ if (draw_info == (DrawInfo *) NULL)
+ {
+ MagickFreeMemory(font_metrics);
+ return((double *) NULL);
+ }
+ (void) CloneString(&draw_info->text,text);
+ status=GetTypeMetrics(wand->image,draw_info,&metrics);
+ DestroyDrawInfo(draw_info);
+ if (status == False)
+ {
+ CopyException(&wand->exception,&wand->image->exception);
+ MagickFreeMemory(font_metrics);
+ return((double *) NULL);
+ }
+ font_metrics[0]=metrics.pixels_per_em.x;
+ font_metrics[1]=metrics.pixels_per_em.y;
+ font_metrics[2]=metrics.ascent;
+ font_metrics[3]=metrics.descent;
+ font_metrics[4]=metrics.width;
+ font_metrics[5]=metrics.height;
+ font_metrics[6]=metrics.max_advance;
+ return(font_metrics);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k Q u e r y F o n t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickQueryFonts() returns any font that match the specified pattern.
+%
+% The format of the MagickQueryFonts function is:
+%
+% char **MagickQueryFonts(const char *pattern,unsigned long *number_fonts)
+%
+% A description of each parameter follows:
+%
+% o pattern: Specifies a pointer to a text string containing a pattern.
+%
+% o number_fonts: This integer returns the number of fonts in the list.
+%
+%
+*/
+WandExport char **MagickQueryFonts(const char *pattern,
+ unsigned long *number_fonts)
+{
+ return(GetTypeList(pattern,number_fonts));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k Q u e r y F o r m a t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickQueryFormats() returns any image formats that match the specified
+% pattern.
+%
+% The format of the MagickQueryFormats function is:
+%
+% char **MagickQueryFormats(const char *pattern,
+% unsigned long *number_formats)
+%
+% A description of each parameter follows:
+%
+% o pattern: Specifies a pointer to a text string containing a pattern.
+%
+% o number_formats: This integer returns the number of image formats in the
+% list.
+%
+%
+*/
+WandExport char **MagickQueryFormats(const char *pattern,
+ unsigned long *number_formats)
+{
+ ExceptionInfo
+ exception;
+
+ char
+ **format_array;
+
+ int
+ entries,
+ i;
+
+ MagickInfo **
+ magick_info;
+
+ ARG_NOT_USED(pattern);
+ *number_formats=0;
+ GetExceptionInfo(&exception);
+ magick_info=GetMagickInfoArray(&exception);
+ DestroyExceptionInfo(&exception);
+ if (!magick_info)
+ return 0;
+
+ for (entries = 0; magick_info[entries] != 0; entries++);
+ if (!entries)
+ {
+ MagickFreeMemory(magick_info);
+ return 0;
+ }
+
+ format_array=MagickAllocateMemory(char **,(entries+1)*sizeof(char *));
+ if (!format_array)
+ {
+ MagickFreeMemory(magick_info);
+ return 0;
+ }
+
+ for (i=0 ; i < entries ; i++)
+ format_array[i]=AcquireString(magick_info[i]->name);
+ format_array[i]=0;
+
+ MagickFreeMemory(magick_info);
+ *number_formats=entries;
+ return (format_array);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R a d i a l B l u r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRadialBlurImage() radial blurs an image.
+%
+% The format of the MagickRadialBlurImage method is:
+%
+% unsigned int MagickRadialBlurImage(MagickWand *wand,const double angle)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o angle: The angle of the blur in degrees.
+%
+*/
+WandExport unsigned int MagickRadialBlurImage(MagickWand *wand,
+ const double angle)
+{
+#if defined(NOT_IMPLEMENTED)
+ Image
+ *blur_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ blur_image=RadialBlurImage(wand->image,angle,&wand->exception);
+ if (blur_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,blur_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+#else
+ ARG_NOT_USED(angle);
+ ThrowWandException(WandError,WandAPINotImplemented,"MagickRadialBlurImage");
+#endif
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R a i s e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRaiseImage() creates a simulated three-dimensional button-like effect
+% by lightening and darkening the edges of the image. Members width and
+% height of raise_info define the width of the vertical and horizontal
+% edge of the effect.
+%
+% The format of the MagickRaiseImage method is:
+%
+% unsigned int MagickRaiseImage(MagickWand *wand,const unsigned long width,
+% const unsigned long height,const long x,const long y,
+% const unsigned int raise_flag)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o width,height,x,y: Define the dimensions of the area to raise.
+%
+% o raise_flag: A value other than zero creates a 3-D raise effect,
+% otherwise it has a lowered effect.
+%
+*/
+WandExport unsigned int MagickRaiseImage(MagickWand *wand,
+ const unsigned long width,const unsigned long height,const long x,
+ const long y,const unsigned int raise_flag)
+{
+ RectangleInfo
+ raise_info;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ raise_info.width=width;
+ raise_info.height=height;
+ raise_info.x=x;
+ raise_info.y=y;
+ status=RaiseImage(wand->image,&raise_info,raise_flag);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e a d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickReadImage() reads an image or image sequence.
+%
+% The format of the MagickReadImage method is:
+%
+% unsigned int MagickReadImage(MagickWand *wand,const char *filename)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o filename: The image filename.
+%
+*/
+WandExport unsigned int MagickReadImage(MagickWand *wand,const char *filename)
+{
+ Image
+ *images;
+
+ ImageInfo
+ *read_info;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ read_info=CloneImageInfo(wand->image_info);
+ (void) strlcpy(read_info->filename,filename,MaxTextExtent);
+ images=ReadImage(read_info,&wand->exception);
+ DestroyImageInfo(read_info);
+ if (images == (Image *) NULL)
+ return(False);
+ AppendImageToList(&wand->images,images);
+ wand->image=GetLastImageInList(wand->images);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e a d I m a g e B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickReadImageBlob() reads an image or image sequence from a blob.
+%
+% The format of the MagickReadImageBlob method is:
+%
+% unsigned int MagickReadImageBlob(MagickWand *wand,
+% const unsigned char *blob,const size_t length)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o blob: The blob.
+%
+% o length: The blob length.
+%
+*/
+WandExport unsigned int MagickReadImageBlob(MagickWand *wand,
+ const unsigned char *blob,const size_t length)
+{
+ Image
+ *images;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ images=BlobToImage(wand->image_info,blob,length,&wand->exception);
+ if (images == (Image *) NULL)
+ return(False);
+ AppendImageToList(&wand->images,images);
+ wand->image=GetLastImageInList(wand->images);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e a d I m a g e F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickReadImageFile() reads an image or image sequence from an open file
+% descriptor.
+%
+% The format of the MagickReadImageFile method is:
+%
+% unsigned int MagickReadImageFile(MagickWand *wand,FILE *file)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o file: The file descriptor.
+%
+*/
+WandExport unsigned int MagickReadImageFile(MagickWand *wand,FILE *file)
+{
+ Image
+ *images;
+
+ ImageInfo
+ *read_info;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ read_info=CloneImageInfo(wand->image_info);
+ read_info->file=file;
+ images=ReadImage(read_info,&wand->exception);
+ DestroyImageInfo(read_info);
+ if (images == (Image *) NULL)
+ return(False);
+ AppendImageToList(&wand->images,images);
+ wand->image=GetLastImageInList(wand->images);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M a g i c k R e d u c e N o i s e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickReduceNoiseImage() smooths the contours of an image while still
+% preserving edge information. The algorithm works by replacing each pixel
+% with its neighbor closest in value. A neighbor is defined by radius. Use
+% a radius of 0 and ReduceNoise() selects a suitable radius for you.
+%
+% The format of the MagickReduceNoiseImage method is:
+%
+% unsigned int MagickReduceNoiseImage(MagickWand *wand,const double radius)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the pixel neighborhood.
+%
+*/
+WandExport unsigned int MagickReduceNoiseImage(MagickWand *wand,
+ const double radius)
+{
+ Image
+ *noise_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ noise_image=ReduceNoiseImage(wand->image,radius,&wand->exception);
+ if (noise_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,noise_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e l i n q u i s h M e m o r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRelinquishMemory() relinquishes memory resources returned by such
+% methods as MagickDescribeImage(), MagickGetException(), etc.
+%
+% The format of the MagickRelinquishMemory method is:
+%
+% unsigned int MagickRelinquishMemory(void *resource)
+%
+% A description of each parameter follows:
+%
+% o resource: Relinquish the memory associated with this resource.
+%
+%
+*/
+WandExport unsigned int MagickRelinquishMemory(void *memory)
+{
+ assert(memory != (void *) NULL);
+ MagickFreeMemory(memory);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e m o v e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRemoveImage() removes an image from the image list.
+%
+% The format of the MagickRemoveImage method is:
+%
+% unsigned int MagickRemoveImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickRemoveImage(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ DeleteImageFromList(&wand->image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e m o v e I m a g e O p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRemoveImageOption() removes an image format-specific option from the
+% the image (.e.g MagickRemoveImageOption(wand,"jpeg","preserve-settings").
+%
+% The format of the MagickRemoveImageOption method is:
+%
+% unsigned int MagickRemoveImageOption(MagickWand *wand,const char *format,
+% const char *key)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o format: The image format.
+%
+% o key: The key.
+%
+*/
+WandExport unsigned int MagickRemoveImageOption(MagickWand *wand,
+ const char *format,const char *key)
+{
+ char
+ option[MaxTextExtent];
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) MagickFormatString(option,MaxTextExtent,"%.1024s:%.1024s",
+ format,key);
+ return (RemoveDefinitions(wand->image_info,option) ? True : False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e m o v e I m a g e P r o f i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRemoveImageProfile() removes the named image profile and returns it.
+%
+% The format of the MagickRemoveImageProfile method is:
+%
+% unsigned char *MagickRemoveImageProfile(MagickWand *wand,const char *name,
+% unsigned long *length)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o name: Name of profile to return: ICC, IPTC, or generic profile.
+%
+% o length: The length of the profile.
+%
+*/
+WandExport unsigned char *MagickRemoveImageProfile(MagickWand *wand,
+ const char *name,unsigned long *length)
+{
+ const unsigned char
+ *profile;
+
+ unsigned char
+ *cloned_profile;
+
+ size_t
+ profile_length;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ *length=0;
+ /*
+ Obtain pointer to existing image profile
+ */
+ profile=GetImageProfile(wand->image,name,&profile_length);
+ if (!profile || !profile_length)
+ return 0;
+ /*
+ Clone profile
+ */
+ *length=(unsigned long) profile_length;
+ cloned_profile=MagickAllocateMemory(unsigned char *,profile_length);
+ if (!cloned_profile)
+ return 0;
+ (void) memcpy(cloned_profile,profile,profile_length);
+ profile=0;
+ /*
+ Remove image profile
+ */
+ (void) DeleteImageProfile(wand->image,name);
+ return cloned_profile;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e s e t I t e r a t o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickReset() resets the wand iterator. Use it in conjunction
+% with MagickNextImage() to iterate over all the images in a wand
+% container.
+%
+% The format of the MagickReset method is:
+%
+% void MagickResetIterator(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport void MagickResetIterator(MagickWand *wand)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->iterator=True;
+ wand->image=wand->images;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e s a m p l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickResampleImage() resample image to desired resolution.
+%
+% Bessel Blackman Box
+% Catrom Cubic Gaussian
+% Hanning Hermite Lanczos
+% Mitchell Point Quandratic
+% Sinc Triangle
+%
+% Most of the filters are FIR (finite impulse response), however, Bessel,
+% Gaussian, and Sinc are IIR (infinite impulse response). Bessel and Sinc
+% are windowed (brought down to zero) with the Blackman filter.
+%
+% The format of the MagickResampleImage method is:
+%
+% unsigned int MagickResampleImage(MagickWand *wand,
+% const double x_resolution,const double y_resolution,
+% const FilterTypes filter,const double blur)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x_resolution: The new image x resolution.
+%
+% o y_resolution: The new image y resolution.
+%
+% o filter: Image filter to use.
+%
+% o blur: The blur factor where > 1 is blurry, < 1 is sharp.
+%
+%
+*/
+WandExport unsigned int MagickResampleImage(MagickWand *wand,
+ const double x_resolution,const double y_resolution,const FilterTypes filter,
+ const double blur)
+{
+ Image
+ *resample_image;
+
+ unsigned long
+ height,
+ width;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ width=(unsigned long) (x_resolution*wand->image->columns/
+ (wand->image->x_resolution == 0.0 ? 72.0 : wand->image->x_resolution)+0.5);
+ height=(unsigned long) (y_resolution*wand->image->rows/
+ (wand->image->y_resolution == 0.0 ? 72.0 : wand->image->y_resolution)+0.5);
+ resample_image=ResizeImage(wand->image,width,height,filter,blur,
+ &wand->exception);
+ if (resample_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,resample_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R e s i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickResizeImage() scales an image to the desired dimensions with one of
+% these filters:
+%
+% Bessel Blackman Box
+% Catrom Cubic Gaussian
+% Hanning Hermite Lanczos
+% Mitchell Point Quandratic
+% Sinc Triangle
+%
+% Most of the filters are FIR (finite impulse response), however, Bessel,
+% Gaussian, and Sinc are IIR (infinite impulse response). Bessel and Sinc
+% are windowed (brought down to zero) with the Blackman filter.
+%
+% The format of the MagickResizeImage method is:
+%
+% unsigned int MagickResizeImage(MagickWand *wand,
+% const unsigned long columns,const unsigned long rows,
+% const FilterTypes filter,const double blur)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o columns: The number of columns in the scaled image.
+%
+% o rows: The number of rows in the scaled image.
+%
+% o filter: Image filter to use.
+%
+% o blur: The blur factor where > 1 is blurry, < 1 is sharp.
+%
+%
+*/
+WandExport unsigned int MagickResizeImage(MagickWand *wand,
+ const unsigned long columns,const unsigned long rows,const FilterTypes filter,
+ const double blur)
+{
+ Image
+ *resize_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ resize_image=ResizeImage(wand->image,columns,rows,filter,blur,
+ &wand->exception);
+ if (resize_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,resize_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R o l l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRollImage() offsets an image as defined by x_offset and y_offset.
+%
+% The format of the MagickRollImage method is:
+%
+% unsigned int MagickRollImage(MagickWand *wand,const long x_offset,
+% const unsigned long y_offset)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x_offset: The x offset.
+%
+% o y_offset: The y offset.
+%
+%
+*/
+WandExport unsigned int MagickRollImage(MagickWand *wand,const long x_offset,
+ const long y_offset)
+{
+ Image
+ *roll_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ roll_image=RollImage(wand->image,x_offset,y_offset,&wand->exception);
+ if (roll_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,roll_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k R o t a t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickRotateImage() rotates an image the specified number of degrees. Empty
+% triangles left over from rotating the image are filled with the
+% background color.
+%
+% The format of the MagickRotateImage method is:
+%
+% unsigned int MagickRotateImage(MagickWand *wand,
+% const PixelWand *background,const double degrees)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o background: The background pixel wand.
+%
+% o degrees: The number of degrees to rotate the image.
+%
+%
+*/
+WandExport unsigned int MagickRotateImage(MagickWand *wand,
+ const PixelWand *background,const double degrees)
+{
+ Image
+ *rotate_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelGetQuantumColor(background,&wand->image->background_color);
+ rotate_image=RotateImage(wand->image,degrees,&wand->exception);
+ if (rotate_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,rotate_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S a m p l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSampleImage() scales an image to the desired dimensions with pixel
+% sampling. Unlike other scaling methods, this method does not introduce
+% any additional color into the scaled image.
+%
+% The format of the MagickSampleImage method is:
+%
+% unsigned int MagickSampleImage(MagickWand *wand,
+% const unsigned long columns,const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o columns: The number of columns in the scaled image.
+%
+% o rows: The number of rows in the scaled image.
+%
+%
+*/
+WandExport unsigned int MagickSampleImage(MagickWand *wand,
+ const unsigned long columns,const unsigned long rows)
+{
+ Image
+ *sample_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ sample_image=SampleImage(wand->image,columns,rows,&wand->exception);
+ if (sample_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,sample_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S c a l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickScaleImage() scales the size of an image to the given dimensions.
+%
+% The format of the MagickScaleImage method is:
+%
+% unsigned int MagickScaleImage(MagickWand *wand,
+% const unsigned long columns,const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o columns: The number of columns in the scaled image.
+%
+% o rows: The number of rows in the scaled image.
+%
+%
+*/
+WandExport unsigned int MagickScaleImage(MagickWand *wand,
+ const unsigned long columns,const unsigned long rows)
+{
+ Image
+ *scale_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ scale_image=ScaleImage(wand->image,columns,rows,&wand->exception);
+ if (scale_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,scale_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e p a r a t e I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickChannelImage() separates a channel from the image and returns a
+% grayscale image. A channel is a particular color component of each pixel
+% in the image.
+%
+% The format of the MagickChannelImage method is:
+%
+% unsigned int MagickSeparateImageChannel(MagickWand *wand,
+% const ChannelType channel)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: Identify which channel to extract: RedChannel, GreenChannel,
+% BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+% BlackChannel.
+%
+*/
+WandExport unsigned int MagickSeparateImageChannel(MagickWand *wand,
+ const ChannelType channel)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=ChannelImage(wand->image,channel);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t C o m p r e s s i o n Q u a l i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetCompressionQuality() sets the image quality factor, which
+% determines compression options when saving the file.
+%
+% For the JPEG and MPEG image formats, quality is 0 (lowest image
+% quality and highest compression) to 100 (best quality but least
+% effective compression). The default quality is 75. Use the
+% -sampling-factor option to specify the factors for chroma
+% downsampling. To use the same quality value as that found by the
+% JPEG decoder, use the -define jpeg:preserve-settings flag.
+%
+% For the MIFF image format, and the TIFF format while using ZIP
+% compression, quality/10 is the zlib compres- sion level, which is 0
+% (worst but fastest compression) to 9 (best but slowest). It has no
+% effect on the image appearance, since the compression is always
+% lossless.
+%
+% For the JPEG-2000 image format, quality is mapped using a non-linear
+% equation to the compression ratio required by the Jasper library.
+% This non-linear equation is intended to loosely approximate the
+% quality provided by the JPEG v1 format. The default quality value 75
+% results in a request for 16:1 compression. The quality value 100
+% results in a request for non-lossy compres- sion.
+%
+% For the MNG and PNG image formats, the quality value sets the zlib
+% compression level (quality / 10) and filter-type (quality % 10).
+% Compression levels range from 0 (fastest compression) to 100 (best
+% but slowest). For compression level 0, the Huffman-only strategy is
+% used, which is fastest but not necessarily the worst compression. If
+% filter-type is 4 or less, the specified filter-type is used for all
+% scanlines:
+%
+% 0) none
+% 1) sub
+% 2) up
+% 3) average
+% 4) Paeth
+%
+% If filter-type is 5, adaptive filtering is used when quality is
+% greater than 50 and the image does not have a color map, otherwise no
+% filtering is used.
+%
+% If filter-type is 6, adaptive filtering with minimum-
+% sum-of-absolute-values is used.
+%
+% Only if the output is MNG, if filter-type is 7, the LOCO color
+% transformation and adaptive filtering with
+% minimum-sum-of-absolute-values are used.
+%
+% The default is quality is 75, which means nearly the best compression
+% with adaptive filtering. The quality setting has no effect on the
+% appearance of PNG and MNG images, since the compression is always
+% lossless.
+%
+% For further information, see the PNG specification.
+%
+% When writing a JNG image with transparency, two quality values are
+% required, one for the main image and one for the grayscale image that
+% conveys the opacity channel. These are written as a single integer
+% equal to the main image quality plus 1000 times the opacity quality.
+% For example, if you want to use quality 75 for the main image and
+% quality 90 to compress the opacity data, use -quality 90075.
+%
+% For the PNM family of formats (PNM, PGM, and PPM) specify a quality
+% factor of zero in order to obtain the ASCII variant of the
+% format. Note that -compress none used to be used to trigger ASCII
+% output but provided the opposite result of what was expected as
+% compared with other formats.
+%
+% The format of the MagickSetCompressionQuality method is:
+%
+% unsigned int MagickSetCompressionQuality(MagickWand *wand,
+% const unsigned long quality)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o delay: The image quality.
+%
+*/
+WandExport unsigned int MagickSetCompressionQuality(MagickWand *wand,
+ const unsigned long quality)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->image_info->quality=quality;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetDepth() sets the sample depth to be used when reading from a
+% raw image or a format which requires that the depth be specified in
+% advance by the user.
+%
+% The format of the MagickSetDepth method is:
+%
+% unsigned int MagickSetDepth(MagickWand *wand,const size_t depth)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o depth: The sample depth.
+%
+*/
+WandExport unsigned int MagickSetDepth(MagickWand *wand,const size_t depth)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->image_info->depth = (unsigned long) depth;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t F i l e n a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetFilename() sets the filename before you read or write an image file.
+%
+% The format of the MagickSetFilename method is:
+%
+% unsigned int MagickSetFilename(MagickWand *wand,const char *filename)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o filename: The image filename.
+%
+*/
+WandExport unsigned int MagickSetFilename(MagickWand *wand,const char *filename)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) strlcpy(wand->image_info->filename,filename,MaxTextExtent);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t F o r m a t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetFormat() sets the file or blob format (e.g. "BMP") to be used
+% when a file or blob is read. Usually this is not necessary because
+% GraphicsMagick is able to auto-detect the format based on the file
+% header (or the file extension), but some formats do not use a unique
+% header or the selection may be ambigious. Use MagickSetImageFormat()
+% to set the format to be used when a file or blob is to be written.
+%
+% The format of the MagickSetFormat method is:
+%
+% unsigned int MagickSetFormat(MagickWand *wand,const char *format)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o filename: The file or blob format.
+%
+*/
+WandExport unsigned int MagickSetFormat(MagickWand *wand,const char *format)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) strlcpy(wand->image_info->magick,format,MaxTextExtent);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImage() replaces the last image returned by MagickSetImageIndex(),
+% MagickNextImage(), MagickPreviousImage() with the images from the specified
+% wand.
+%
+% The format of the MagickSetImage method is:
+%
+% unsigned int MagickSetImage(MagickWand *wand,const MagickWand *set_wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o set_wand: The set_wand wand.
+%
+*/
+WandExport unsigned int MagickSetImage(MagickWand *wand,
+ const MagickWand *set_wand)
+{
+ Image
+ *images;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(set_wand != (MagickWand *) NULL);
+ assert(set_wand->signature == MagickSignature);
+ if (set_wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ images=CloneImageList(set_wand->images,&wand->exception);
+ if (images == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,images);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e A t t r i b u t e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageAttribute sets an image attribute
+%
+% The format of the MagickSetImageAttribute method is:
+%
+% unsigned int MagickSetImageAttribute(MagickWand *wand, const char *name, const char *value)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o name: The name of the attribute
+%
+% o value: The value of the attribute
+%
+*/
+WandExport unsigned int MagickSetImageAttribute(MagickWand *wand, const char *name,
+ const char *value)
+{
+ unsigned int status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status = SetImageAttribute(wand->image,name,value);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e B a c k g r o u n d C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageBackgroundColor() sets the image background color.
+%
+% The format of the MagickSetImageBackgroundColor method is:
+%
+% unsigned int MagickSetImageBackgroundColor(MagickWand *wand,
+% const PixelWand *background)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o background: The background pixel wand.
+%
+*/
+WandExport unsigned int MagickSetImageBackgroundColor(MagickWand *wand,
+ const PixelWand *background)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelGetQuantumColor(background,&wand->image->background_color);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e B l u e P r i m a r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageBluePrimary() sets the image chromaticity blue primary point.
+%
+% The format of the MagickSetImageBluePrimary method is:
+%
+% unsigned int MagickSetImageBluePrimary(MagickWand *wand,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The blue primary x-point.
+%
+% o y: The blue primary y-point.
+%
+%
+*/
+WandExport unsigned int MagickSetImageBluePrimary(MagickWand *wand,
+ const double x,const double y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->chromaticity.blue_primary.x=x;
+ wand->image->chromaticity.blue_primary.y=y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e B o r d e r C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageBorderColor() sets the image border color.
+%
+% The format of the MagickSetImageBorderColor method is:
+%
+% unsigned int MagickSetImageBorderColor(MagickWand *wand,
+% const PixelWand *border)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o border: The border pixel wand.
+%
+*/
+WandExport unsigned int MagickSetImageBorderColor(MagickWand *wand,
+ const PixelWand *border)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelGetQuantumColor(border,&wand->image->border_color);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e C o l o r m a p C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageColormapColor() sets the color of the specified colormap
+% index.
+%
+% The format of the MagickSetImageColormapColor method is:
+%
+% unsigned int MagickSetImageColormapColor(MagickWand *wand,
+% const unsigned long index,const PixelWand *color)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o index: The offset into the image colormap.
+%
+% o color: Return the colormap color in this wand.
+%
+*/
+WandExport unsigned int MagickSetImageColormapColor(MagickWand *wand,
+ const unsigned long index,const PixelWand *color)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ if ((wand->image->colormap == (PixelPacket *) NULL) ||
+ (index >= wand->image->colors))
+ ThrowWandException(WandError,InvalidColormapIndex,(char *) NULL);
+ PixelGetQuantumColor(color,wand->image->colormap+index);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e C o l o r s p a c e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageColorspace() sets the image colorspace.
+%
+% The format of the MagickSetImageColorspace method is:
+%
+% unsigned int MagickSetImageColorspace(MagickWand *wand,
+% const ColorspaceType colorspace)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o colorspace: The image colorspace: UndefinedColorspace, RGBColorspace,
+% GRAYColorspace, TransparentColorspace, OHTAColorspace, XYZColorspace,
+% YCbCrColorspace, YCCColorspace, YIQColorspace, YPbPrColorspace,
+% YPbPrColorspace, YUVColorspace, CMYKColorspace, sRGBColorspace,
+% HSLColorspace, or HWBColorspace.
+%
+*/
+WandExport unsigned int MagickSetImageColorspace(MagickWand *wand,
+ const ColorspaceType colorspace)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(TransformColorspace(wand->image,colorspace));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e C o m p o s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageCompose() sets the image composite operator, useful for
+% specifying how to composite the image thumbnail when using the
+% MagickMontageImage() method.
+%
+% The format of the MagickSetImageCompose method is:
+%
+% unsigned int MagickSetImageCompose(MagickWand *wand,
+% const CompositeOperator compose)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o compose: The image composite operator.
+%
+*/
+WandExport unsigned int MagickSetImageCompose(MagickWand *wand,
+ const CompositeOperator compose)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->compose=compose;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e C o m p r e s s i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageCompression() sets the image compression.
+%
+% The format of the MagickSetImageCompression method is:
+%
+% unsigned int MagickSetImageCompression(MagickWand *wand,
+% const CompressionType compression)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o compression: The image compression type.
+%
+*/
+WandExport unsigned int MagickSetImageCompression(MagickWand *wand,
+ const CompressionType compression)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->compression=compression;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e D e l a y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageDelay() sets the image delay.
+%
+% The format of the MagickSetImageDelay method is:
+%
+% unsigned int MagickSetImageDelay(MagickWand *wand,
+% const unsigned long delay)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o delay: The image delay in 1/100th of a second.
+%
+*/
+WandExport unsigned int MagickSetImageDelay(MagickWand *wand,
+ const unsigned long delay)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->delay=delay;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e C h a n n e l D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageChannelDepth() sets the depth of a particular image channel.
+%
+% The format of the MagickSetImageChannelDepth method is:
+%
+% unsigned int MagickSetImageChannelDepth(MagickWand *wand,
+% const ChannelType channel,const unsigned long depth)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: Identify which channel to extract: RedChannel, GreenChannel,
+% BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+% BlackChannel.
+%
+% o depth: The image depth in bits.
+%
+*/
+WandExport unsigned int MagickSetImageChannelDepth(MagickWand *wand,
+ const ChannelType channel,const unsigned long depth)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) SetImageChannelDepth(wand->image,channel,depth);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e D e p t h %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageDepth() sets the image depth.
+%
+% The format of the MagickSetImageDepth method is:
+%
+% unsigned int MagickSetImageDepth(MagickWand *wand,
+% const unsigned long depth)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o depth: The image depth in bits: 8, 16, or 32.
+%
+*/
+WandExport unsigned int MagickSetImageDepth(MagickWand *wand,
+ const unsigned long depth)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) SetImageDepth(wand->image,depth);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e D i s p o s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageDispose() sets the image disposal method.
+%
+% The format of the MagickSetImageDispose method is:
+%
+% unsigned int MagickSetImageDispose(MagickWand *wand,
+% const DisposeType dispose)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o dispose: The image disposeal type.
+%
+*/
+WandExport unsigned int MagickSetImageDispose(MagickWand *wand,
+ const DisposeType dispose)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->dispose=dispose;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e F i l e n a m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageFilename() sets the filename of a particular image in a
+% sequence.
+%
+% The format of the MagickSetImageFilename method is:
+%
+% unsigned int MagickSetImageFilename(MagickWand *wand,
+% const char *filename)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o filename: The image filename.
+%
+*/
+WandExport unsigned int MagickSetImageFilename(MagickWand *wand,
+ const char *filename)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) strlcpy(wand->image->filename,filename,MaxTextExtent);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e F o r m a t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageFormat() sets the format of a particular image in a
+% sequence. The format is designated by a magick string (e.g. "GIF").
+%
+% The format of the MagickSetImageFormat method is:
+%
+% unsigned int MagickSetImageFormat(MagickWand *wand,
+% const char *format)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o magick: The image format.
+%
+*/
+WandExport unsigned int MagickSetImageFormat(MagickWand *wand,
+ const char *format)
+{
+ const char
+ *magick = "";
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ if (format != (const char *) NULL)
+ magick=format;
+ (void) strlcpy(wand->image->magick,magick,
+ sizeof(wand->image->magick));
+ return MagickTrue;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e F u z z %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageFuzz() sets the color comparison fuzz factor. Colors
+% closer than the fuzz factor are considered to be the same when comparing
+% colors. Note that some other functions such as MagickColorFloodfillImage()
+% implicitly set this value.
+%
+% The format of the MagickSetImageFuzz method is:
+%
+% unsigned int MagickSetImageFuzz(MagickWand *wand,const double fuzz)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o fuzz: The color comparison fuzz factor
+%
+*/
+WandExport unsigned int
+MagickSetImageFuzz(MagickWand *wand,const double fuzz)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->fuzz=fuzz;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e G a m m a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageGamma() sets the image gamma.
+%
+% The format of the MagickSetImageGamma method is:
+%
+% unsigned int MagickSetImageGamma(MagickWand *wand,const double gamma)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o gamma: The image gamma.
+%
+*/
+WandExport unsigned int MagickSetImageGamma(MagickWand *wand,const double gamma)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->gamma=gamma;
+ return(True);
+}
+
+/*
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % %
+ % %
+ % %
+ % M a g i c k S e t I m a g e G e o m e t r y %
+ % %
+ % %
+ % %
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+ % MagickSetImageGeometry() sets the image geometry string.
+ %
+ % The format of the MagickSetImageGeometry method is:
+ %
+ % unsigned int MagickSetImageGeometry(MagickWand *wand,
+ % const char *geometry)
+ %
+ % A description of each parameter follows:
+ %
+ % o wand: The magick wand.
+ %
+ % o geometry: The image geometry.
+ %
+ */
+WandExport unsigned int MagickSetImageGeometry(MagickWand *wand,
+ const char *geometry)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) CloneString(&wand->image->geometry,geometry);
+
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e G r a v i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageGravity() sets the image gravity. This is used
+% when evaluating regions defined by a geometry and the image
+% dimensions. It may be used in conjunction with operations which
+% use a geometry parameter to adjust the x, y parameters of the
+% final operation. Gravity is used in composition to determine where
+% the image should be placed within the defined geometry region.
+% It may be used with montage to effect placement of the image within
+% the tile.
+%
+% The format of the MagickSetImageGravity method is:
+%
+% unsigned int MagickSetImageGravity(MagickWand *wand,const GravityType)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o gravity: The image gravity. Available values are ForgetGravity,
+% NorthWestGravity, NorthGravity, NorthEastGravity, WestGravity,
+% CenterGravity, EastGravity, SouthWestGravity, SouthGravity,
+% SouthEastGravity, and StaticGravity
+%
+*/
+WandExport unsigned int MagickSetImageGravity(MagickWand *wand,
+ const GravityType gravity)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->gravity=gravity;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e G r e e n P r i m a r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageGreenPrimary() sets the image chromaticity green primary
+% point.
+%
+% The format of the MagickSetImageGreenPrimary method is:
+%
+% unsigned int MagickSetImageGreenPrimary(MagickWand *wand,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The green primary x-point.
+%
+% o y: The green primary y-point.
+%
+%
+*/
+WandExport unsigned int MagickSetImageGreenPrimary(MagickWand *wand,
+ const double x,const double y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->chromaticity.green_primary.x=x;
+ wand->image->chromaticity.green_primary.y=y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e I n d e x %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageIndex() set the current image to the position of the list
+% specified with the index parameter.
+%
+% The format of the MagickSetImageIndex method is:
+%
+% unsigned int MagickSetImageIndex(MagickWand *wand,const long index)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o index: The scene number.
+%
+*/
+WandExport unsigned int MagickSetImageIndex(MagickWand *wand,const long index)
+{
+ Image
+ *image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ image=GetImageFromList(wand->images,index);
+ if (image == (Image *) NULL)
+ return(False);
+ wand->image=image;
+ wand->iterator=False;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e I n t e r l a c e S c h e m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageInterlaceScheme() sets the image interlace scheme. Please
+% use SetInterlaceScheme() instead to change the interlace scheme used when
+% writing the image.
+%
+% The format of the MagickSetImageInterlaceScheme method is:
+%
+% unsigned int MagickSetImageInterlaceScheme(MagickWand *wand,
+% const InterlaceType interlace_scheme)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o interlace_scheme: The image interlace scheme: NoInterlace, LineInterlace,
+% PlaneInterlace, PartitionInterlace.
+%
+*/
+WandExport unsigned int MagickSetImageInterlaceScheme(MagickWand *wand,
+ const InterlaceType interlace_scheme)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->interlace=interlace_scheme;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e I t e r a t i o n s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageIterations() sets the image iterations.
+%
+% The format of the MagickSetImageIterations method is:
+%
+% unsigned int MagickSetImageIterations(MagickWand *wand,
+% const unsigned long iterations)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o delay: The image delay in 1/100th of a second.
+%
+*/
+WandExport unsigned int MagickSetImageIterations(MagickWand *wand,
+ const unsigned long iterations)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->iterations=iterations;
+ return(True);
+}
+
+/*
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ % %
+ % %
+ % %
+ % M a g i c k S e t I m a g e M a t t e %
+ % %
+ % %
+ % %
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ %
+ % MagickSetImageMatte() sets the image matte flag. The image opacity
+ % (inverse of transparency) channel is enabled if the matte flag is
+ % True.
+ %
+ % The format of the MagickSetImageMatte method is:
+ %
+ % unsigned int MagickSetImageMatte(MagickWand *wand,
+ % const unsigned int matte)
+ %
+ % A description of each parameter follows:
+ %
+ % o wand: The magick wand.
+ %
+ % o matte: The image matte.
+ %
+ */
+WandExport unsigned int MagickSetImageMatte(MagickWand *wand,
+ const unsigned int matte)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->images->matte = matte;
+
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e M a t t e C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageMatteColor() sets the image matte color.
+%
+% The format of the MagickSetImageMatteColor method is:
+%
+% unsigned int MagickSetImageMatteColor(MagickWand *wand,
+% const PixelWand *matte)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o matte: The matte pixel wand.
+%
+*/
+WandExport unsigned int MagickSetImageMatteColor(MagickWand *wand,
+ const PixelWand *matte)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelGetQuantumColor(matte,&wand->image->matte_color);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e O p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageOption() associates one or options with a particular image
+% format (.e.g MagickSetImageOption(wand,"jpeg","preserve-settings","true").
+%
+% The format of the MagickSetImageOption method is:
+%
+% unsigned int MagickSetImageOption(MagickWand *wand,const char *format,
+% const char *key,const char *value)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o format: The image format.
+%
+% o key: The key.
+%
+% o value: The value.
+%
+*/
+WandExport unsigned int MagickSetImageOption(MagickWand *wand,
+ const char *format,const char *key,const char *value)
+{
+ char
+ option[MaxTextExtent];
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) MagickFormatString(option,MaxTextExtent,"%.1024s:%.1024s=%.1024s",
+ format,key,value);
+ (void) AddDefinitions(wand->image_info,option,&wand->exception);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e O r i e n t a t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageOrientation() sets the internal image orientation type.
+% The EXIF orientation tag will be updated if present.
+%
+% The format of the MagickSetImageOrientation method is:
+%
+% MagickSetImageOrientation(MagickWand *wand,
+% OrientationType new_orientation)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o new_orientation: The new orientation of the image. One of:
+%
+% UndefinedOrientation Image orientation not specified.
+% TopLeftOrientation Left to right and Top to bottom.
+% TopRightOrientation Right to left and Top to bottom.
+% BottomRightOrientation Right to left and Bottom to top.
+% BottomLeftOrientation Left to right and Bottom to top.
+% LeftTopOrientation Top to bottom and Left to right.
+% RightTopOrientation Top to bottom and Right to left.
+% RightBottomOrientation Bottom to top and Right to left.
+% LeftBottomOrientation Bottom to top and Left to right.
+%
+% Returns True on success, False otherwise.
+%
+*/
+WandExport unsigned int MagickSetImageOrientation(MagickWand *wand,
+ const OrientationType new_orientation)
+{
+ OrientationType orientation;
+ char orientation_attribute[MaxTextExtent];
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ orientation = ((new_orientation > UndefinedOrientation
+ && new_orientation <= LeftBottomOrientation)
+ ? new_orientation
+ : UndefinedOrientation);
+ FormatString(orientation_attribute,"%d",new_orientation);
+
+ if (wand->images == (Image *) NULL)
+ (void) ThrowException(&wand->exception,WandError,WandContainsNoImages,
+ wand->id);
+
+ (void) SetImageAttribute(wand->image, "EXIF:Orientation", orientation_attribute);
+ wand->image->orientation = orientation;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e P a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImagePage() sets the image page size and offset used when
+% placing (e.g. compositing) the image. Pass all zeros for the
+% default placement.
+%
+% The format of the MagickSetImagePage method is:
+%
+% unsigned int MagickSetImagePage(MagickWand *wand,
+% const unsigned long width,
+% const unsigned long height,
+% const long x,
+% const long y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o width, height: The region size.
+%
+% o x, y: Offset (from top left) on base canvas image on
+% which to composite image data.
+%
+*/
+WandExport unsigned int MagickSetImagePage(MagickWand *wand,
+ const unsigned long width,
+ const unsigned long height,
+ const long x,
+ const long y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->page.width=width;
+ wand->image->page.height=height;
+ wand->image->page.x=x;
+ wand->image->page.y=y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e P i x e l s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImagePixels() accepts pixel data and stores it in the image at the
+% location you specify. The method returns False on success otherwise True
+% if an error is encountered. The pixel data can be either char, short int,
+% int, long, float, or double in the order specified by map.
+%
+% Suppose your want want to upload the first scanline of a 640x480 image from
+% character data in red-green-blue order:
+%
+% MagickSetImagePixels(wand,0,0,0,640,1,"RGB",CharPixel,pixels);
+%
+% The format of the MagickSetImagePixels method is:
+%
+% unsigned int MagickSetImagePixels(MagickWand *wand,
+% const long x_offset,const long y_offset,const unsigned long columns,
+% const unsigned long rows,const char *map,const StorageType storage,
+% unsigned char *pixels)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x_offset, y_offset: Offset (from top left) on base canvas image on
+% which to composite image data.
+%
+% o columns, rows: Dimensions of image.
+%
+% o map: This string reflects the expected ordering of the pixel array.
+% It can be any combination or order of R = red, G = green, B = blue,
+% A = alpha (same as Transparency), O = Opacity, T = Transparency,
+% C = cyan, Y = yellow, M = magenta, K = black, or I = intensity
+% (for grayscale). Specify "P" = pad, to skip over a quantum which is
+% intentionally ignored. Creation of an alpha channel for CMYK images
+% is currently not supported.
+%
+% o storage: Define the data type of the pixels. Float and double types are
+% expected to be normalized [0..1] otherwise [0..MaxRGB]. Choose from
+% these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
+% or DoublePixel.
+%
+% o pixels: This array of values contain the pixel components as defined by
+% map and type. You must preallocate this array where the expected
+% length varies depending on the values of width, height, map, and type.
+%
+%
+*/
+WandExport unsigned int MagickSetImagePixels(MagickWand *wand,
+ const long x_offset,const long y_offset,const unsigned long columns,
+ const unsigned long rows,const char *map,const StorageType storage,
+ unsigned char *pixels)
+{
+ Image
+ *constitute_image,
+ *image;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+
+ image=wand->image;
+ constitute_image=
+ ConstituteImage(columns,rows,map,storage,pixels,&image->exception);
+ if (constitute_image)
+ {
+ (void) CompositeImage(image,CopyCompositeOp,constitute_image,x_offset,
+ y_offset);
+ DestroyImage(constitute_image);
+ status = (image->exception.severity == UndefinedException);
+ }
+ else
+ {
+ status = False;
+ }
+
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e P r o f i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageProfile() adds a named profile to the magick wand. If a
+% profile with the same name already exists, it is replaced. This method
+% differs from the MagickProfileImage() method in that it does not apply any
+% CMS color profiles.
+%
+% The format of the MagickSetImageProfile method is:
+%
+% unsigned int MagickSetImageProfile(MagickWand *wand,const char *name,
+% const unsigned char *profile,const unsigned long length)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o name: Name of profile to add or remove: ICC, IPTC, or generic profile.
+%
+% o profile: The profile.
+%
+% o length: The length of the profile.
+%
+*/
+WandExport unsigned int MagickSetImageProfile(MagickWand *wand,const char *name,
+ const unsigned char *profile,const unsigned long length)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=SetImageProfile(wand->image,name,profile, length);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e R e d P r i m a r y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageRedPrimary() sets the image chromaticity red primary point.
+%
+% The format of the MagickSetImageRedPrimary method is:
+%
+% unsigned int MagickSetImageRedPrimary(MagickWand *wand,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The red primary x-point.
+%
+% o y: The red primary y-point.
+%
+*/
+WandExport unsigned int MagickSetImageRedPrimary(MagickWand *wand,
+ const double x,const double y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->chromaticity.red_primary.x=x;
+ wand->image->chromaticity.red_primary.y=y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e R e n d e r i n g I n t e n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageRenderingIntent() sets the image rendering intent.
+%
+% The format of the MagickSetImageRenderingIntent method is:
+%
+% unsigned int MagickSetImageRenderingIntent(MagickWand *wand,
+% const RenderingIntent rendering_intent)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o rendering_intent: The image rendering intent: UndefinedIntent,
+% SaturationIntent, PerceptualIntent, AbsoluteIntent, or RelativeIntent.
+%
+*/
+WandExport unsigned int MagickSetImageRenderingIntent(MagickWand *wand,
+ const RenderingIntent rendering_intent)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->rendering_intent=rendering_intent;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e R e s o l u t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageResolution() sets the image resolution.
+%
+% The format of the MagickSetImageResolution method is:
+%
+% unsigned int MagickSetImageResolution(MagickWand *wand,
+% const double x_resolution,const doubtl y_resolution)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x_resolution: The image x resolution.
+%
+% o y_resolution: The image y resolution.
+%
+*/
+WandExport unsigned int MagickSetImageResolution(MagickWand *wand,
+ const double x_resolution,const double y_resolution)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->x_resolution=x_resolution;
+ wand->image->y_resolution=y_resolution;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e S c e n e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageScene() sets the image scene.
+%
+% The format of the MagickSetImageScene method is:
+%
+% unsigned int MagickSetImageScene(MagickWand *wand,
+% const unsigned long scene)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o delay: The image scene number.
+%
+*/
+WandExport unsigned int MagickSetImageScene(MagickWand *wand,
+ const unsigned long scene)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->scene=scene;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e T y p e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageType() sets the image type.
+%
+% The format of the MagickSetImageType method is:
+%
+% unsigned int MagickSetImageType(MagickWand *wand,
+% const ImageType image_type)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o image_type: The image type: UndefinedType, BilevelType, GrayscaleType,
+% GrayscaleMatteType, PaletteType, PaletteMatteType, TrueColorType,
+% TrueColorMatteType, ColorSeparationType, ColorSeparationMatteType,
+% or OptimizeType.
+%
+*/
+WandExport unsigned int MagickSetImageType(MagickWand *wand,
+ const ImageType image_type)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image_info->type=image_type;
+ return(SetImageType(wand->image,image_type));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e S a v e d T y p e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageSavedType() sets the image type that will be used when the
+% image is saved.
+%
+% The format of the MagickSetImageSavedType method is:
+%
+% unsigned int MagickSetImageSavedType(MagickWand *wand,
+% const ImageType image_type)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o image_type: The image type: UndefinedType, BilevelType, GrayscaleType,
+% GrayscaleMatteType, PaletteType, PaletteMatteType, TrueColorType,
+% TrueColorMatteType, ColorSeparationType, ColorSeparationMatteType,
+% or OptimizeType.
+%
+*/
+WandExport unsigned int MagickSetImageSavedType(MagickWand *wand,
+ const ImageType image_type)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->image_info->type = image_type;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e U n i t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageUnits() sets the image units of resolution.
+%
+% The format of the MagickSetImageUnits method is:
+%
+% unsigned int MagickSetImageUnits(MagickWand *wand,
+% const ResolutionType units)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o units: The image units of resolution : Undefinedresolution,
+% PixelsPerInchResolution, or PixelsPerCentimeterResolution.
+%
+*/
+WandExport unsigned int MagickSetImageUnits(MagickWand *wand,
+ const ResolutionType units)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->units=units;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e V i r t u a l P i x e l M e t h o d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageVirtualPixelMethod() sets the image virtual pixel method.
+%
+% The format of the MagickSetImageVirtualPixelMethod method is:
+%
+% unsigned int MagickSetImageVirtualPixelMethod(MagickWand *wand,
+% const VirtualPixelMethod method)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o method: The image virtual pixel method : UndefinedVirtualPixelMethod,
+% ConstantVirtualPixelMethod, EdgeVirtualPixelMethod,
+% MirrorVirtualPixelMethod, or TileVirtualPixelMethod.
+%
+*/
+WandExport unsigned int MagickSetImageVirtualPixelMethod(MagickWand *wand,
+ const VirtualPixelMethod method)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(SetImageVirtualPixelMethod(wand->image,method));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I n t e r l a c e S c h e m e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetInterlaceScheme() sets the interlace scheme used when writing
+% the image.
+%
+% The format of the MagickSetInterlaceScheme method is:
+%
+% unsigned int MagickSetInterlaceScheme(MagickWand *wand,
+% const InterlaceType interlace_scheme)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o interlace_scheme: The image interlace scheme: NoInterlace, LineInterlace,
+% PlaneInterlace, PartitionInterlace.
+%
+*/
+WandExport unsigned int MagickSetInterlaceScheme(MagickWand *wand,
+ const InterlaceType interlace_scheme)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->image_info->interlace=interlace_scheme;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t R e s o l u t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetResolution() sets the resolution (density) of the magick wand.
+% Set it before you read an EPS, PDF, or Postscript file in order to
+% influence the size of the returned image, or after an image has already
+% been created to influence the rendered image size when used with
+% typesetting software.
+%
+% Also see MagickSetResolutionUnits() which specifies the units to use for
+% the image resolution.
+%
+% The format of the MagickSetResolution method is:
+%
+% unsigned int MagickSetResolution(MagickWand *wand,
+% const double x_resolution,const double y_resolution)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x_resolution: The horizontal resolution
+%
+% o y_resolution: The vertical reesolution
+%
+%
+*/
+WandExport unsigned int
+MagickSetResolution(MagickWand *wand,
+ const double x_resolution,const double y_resolution)
+{
+ char
+ geometry[MaxTextExtent];
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) MagickFormatString(geometry,MaxTextExtent,"%gx%g",x_resolution,y_resolution);
+ (void) CloneString(&wand->image_info->density,geometry);
+ if (wand->image != (Image *) NULL)
+ {
+ wand->image->x_resolution=x_resolution;
+ wand->image->y_resolution=y_resolution;
+ }
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t R e s o l u t i o n U n i t s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetResolutionUnits() sets the resolution units of the magick wand.
+% It should be used in conjunction with MagickSetResolution().
+% This method works both before and after an image has been read.
+%
+% Also see MagickSetImageUnits() which specifies the units which apply to
+% the image resolution setting after an image has been read.
+%
+% The format of the MagickSetResolutionUnits method is:
+%
+% unsigned int MagickSetResolutionUnits(MagickWand *wand,
+% const ResolutionType units)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o units: The image units of resolution : Undefinedresolution,
+% PixelsPerInchResolution, or PixelsPerCentimeterResolution.
+%
+*/
+WandExport unsigned int
+MagickSetResolutionUnits(MagickWand *wand,const ResolutionType units)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->image_info->units=units;
+ if (wand->image != (Image *) NULL)
+ wand->image->units=units;
+ return(MagickPass);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t R e s o u r c e L i m i t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetResourceLimit() sets the limit for a particular resource in
+% megabytes.
+%
+% The format of the MagickSetResourceLimit method is:
+%
+% unsigned int MagickSetResourceLimit(const ResourceType type,
+% const unsigned long *limit)
+%
+% A description of each parameter follows:
+%
+% o type: The type of resource: DiskResource, FileResource, MapResource,
+% MemoryResource, PixelsResource, ThreadsResource, WidthResource,
+% HeightResource.
+%
+% o The maximum limit for the resource.
+%
+*/
+WandExport unsigned int MagickSetResourceLimit(const ResourceType type,
+ const unsigned long limit)
+{
+ return(SetMagickResourceLimit(type,limit));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t S a m p l i n g F a c t o r s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetSamplingFactors() sets the image sampling factors.
+%
+% The format of the MagickSetSamplingFactors method is:
+%
+% unsigned int MagickSetSamplingFactors(MagickWand *wand,
+% const unsigned long number_factors,const double *sampling_factors)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o number_factoes: The number of factors.
+%
+% o sampling_factors: An array of doubles representing the sampling factor
+% for each color component (in RGB order).
+%
+*/
+WandExport unsigned int MagickSetSamplingFactors(MagickWand *wand,
+ const unsigned long number_factors,const double *sampling_factors)
+{
+ char
+ sampling_factor[MaxTextExtent];
+
+ register long
+ i;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ MagickFreeMemory(wand->image_info->sampling_factor);
+ if (number_factors == 0)
+ return(True);
+ for (i=0; i < (long) (number_factors-1); i++)
+ {
+ (void) MagickFormatString(sampling_factor,MaxTextExtent,"%g,",
+ sampling_factors[i]);
+ (void) ConcatenateString(&wand->image_info->sampling_factor,
+ sampling_factor);
+ }
+ (void) MagickFormatString(sampling_factor,MaxTextExtent,"%g",
+ sampling_factors[i]);
+ (void) ConcatenateString(&wand->image_info->sampling_factor,sampling_factor);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t S i z e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetSize() sets the size of the magick wand. Set it before you
+% read a raw image format such as RGB, GRAY, or CMYK.
+%
+% The format of the MagickSetSize method is:
+%
+% unsigned int MagickSetSize(MagickWand *wand,const unsigned long columns,
+% const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o columns: The width in pixels.
+%
+% o height: The height in pixels.
+%
+%
+*/
+WandExport unsigned int MagickSetSize(MagickWand *wand,
+ const unsigned long columns,const unsigned long rows)
+{
+ char
+ geometry[MaxTextExtent];
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) MagickFormatString(geometry,MaxTextExtent,"%lux%lu",columns,rows);
+ (void) CloneString(&wand->image_info->size,geometry);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t I m a g e W h i t e P o i n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetImageWhitePoint() sets the image chromaticity white point.
+%
+% The format of the MagickSetImageWhitePoint method is:
+%
+% unsigned int MagickSetImageWhitePoint(MagickWand *wand,const double x,
+% const double y)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o x: The white x-point.
+%
+% o y: The white y-point.
+%
+%
+*/
+WandExport unsigned int MagickSetImageWhitePoint(MagickWand *wand,
+ const double x,const double y)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->chromaticity.white_point.x=x;
+ wand->image->chromaticity.white_point.y=y;
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S e t P a s s p h r a s e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSetPassphrase() sets the passphrase.
+%
+% The format of the MagickSetPassphrase method is:
+%
+% unsigned int MagickSetPassphrase(MagickWand *wand,const char *passphrase)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o passphrase: The passphrase.
+%
+*/
+WandExport unsigned int MagickSetPassphrase(MagickWand *wand,
+ const char *passphrase)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) CloneString(&wand->image_info->authenticate,passphrase);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S h a r p e n I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSharpenImage() sharpens an image. We convolve the image with a Gaussian
+% operator of the given radius and standard deviation (sigma).
+% For reasonable results, the radius should be larger than sigma. Use a
+% radius of 0 and SharpenImage() selects a suitable radius for you.
+%
+% The format of the MagickSharpenImage method is:
+%
+% unsigned int MagickSharpenImage(MagickWand *wand,const double radius,
+% const double sigma)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+*/
+WandExport unsigned int MagickSharpenImage(MagickWand *wand,const double radius,
+ const double sigma)
+{
+ Image
+ *sharpen_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ sharpen_image=SharpenImage(wand->image,radius,sigma,&wand->exception);
+ if (sharpen_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,sharpen_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S h a v e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickShaveImage() shaves pixels from the image edges. It allocates the
+% memory necessary for the new Image structure and returns a pointer to the
+% new image.
+%
+% The format of the MagickShaveImage method is:
+%
+% unsigned int MagickShaveImage(MagickWand *wand,
+% const unsigned long columns,const unsigned long rows)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o columns: The number of columns in the scaled image.
+%
+% o rows: The number of rows in the scaled image.
+%
+%
+*/
+WandExport unsigned int MagickShaveImage(MagickWand *wand,
+ const unsigned long columns,const unsigned long rows)
+{
+ Image
+ *shave_image;
+
+ RectangleInfo
+ shave_info;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ shave_info.width=columns;
+ shave_info.height=rows;
+ shave_info.x=0;
+ shave_info.y=0;
+ shave_image=ShaveImage(wand->image,&shave_info,&wand->exception);
+ if (shave_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,shave_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S h e a r I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickShearImage() slides one edge of an image along the X or Y axis,
+% creating a parallelogram. An X direction shear slides an edge along the X
+% axis, while a Y direction shear slides an edge along the Y axis. The amount
+% of the shear is controlled by a shear angle. For X direction shears, x_shear
+% is measured relative to the Y axis, and similarly, for Y direction shears
+% y_shear is measured relative to the X axis. Empty triangles left over from
+% shearing the image are filled with the background color.
+%
+% The format of the MagickShearImage method is:
+%
+% unsigned int MagickShearImage(MagickWand *wand,
+% const PixelWand *background,const double x_shear,onst double y_shear)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o background: The background pixel wand.
+%
+% o x_shear: The number of degrees to shear the image.
+%
+% o y_shear: The number of degrees to shear the image.
+%
+%
+*/
+WandExport unsigned int MagickShearImage(MagickWand *wand,
+ const PixelWand *background,const double x_shear,const double y_shear)
+{
+ Image
+ *shear_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelGetQuantumColor(background,&wand->image->background_color);
+ shear_image=ShearImage(wand->image,x_shear,y_shear,&wand->exception);
+ if (shear_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,shear_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% M a g i c k S o l a r i z e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSolarizeImage() applies a special effect to the image, similar to the
+% effect achieved in a photo darkroom by selectively exposing areas of photo
+% sensitive paper to light. Threshold ranges from 0 to MaxRGB and is a
+% measure of the extent of the solarization.
+%
+% The format of the MagickSolarizeImage method is:
+%
+% unsigned int MagickSolarizeImage(MagickWand *wand,const double threshold)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o threshold: Define the extent of the solarization.
+%
+*/
+WandExport unsigned int MagickSolarizeImage(MagickWand *wand,
+ const double threshold)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=SolarizeImage(wand->image,threshold);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S p r e a d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSpreadImage() is a special effects method that randomly displaces each
+% pixel in a block defined by the radius parameter.
+%
+% The format of the MagickSpreadImage method is:
+%
+% unsigned int MagickSpreadImage(MagickWand *wand,const double radius)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: Choose a random pixel in a neighborhood of this extent.
+%
+*/
+WandExport unsigned int MagickSpreadImage(MagickWand *wand,const double radius)
+{
+ Image
+ *spread_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ spread_image=SpreadImage(wand->image,radius,&wand->exception);
+ if (spread_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,spread_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S t e g a n o I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Use MagickSteganoImage() to hide a digital watermark within the image.
+% Recover the hidden watermark later to prove that the authenticity of
+% an image. Offset defines the start position within the image to hide
+% the watermark.
+%
+% The format of the MagickSteganoImage method is:
+%
+% MagickWand *MagickSteganoImage(MagickWand *wand,
+% const MagickWand *watermark_wand,const long offset)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o watermark_wand: The watermark wand.
+%
+% o offset: Start hiding at this offset into the image.
+%
+*/
+WandExport MagickWand *MagickSteganoImage(MagickWand *wand,
+ const MagickWand *watermark_wand,const long offset)
+{
+ Image
+ *stegano_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if ((wand->images == (Image *) NULL) ||
+ (watermark_wand->images == (Image *) NULL))
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wand->image->offset=offset;
+ stegano_image=SteganoImage(wand->image,watermark_wand->image,
+ &wand->exception);
+ if (stegano_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,stegano_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S t e r e o I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickStereoImage() composites two images and produces a single image that
+% is the composite of a left and right image of a stereo pair
+%
+% The format of the MagickStereoImage method is:
+%
+% MagickWand *MagickStereoImage(MagickWand *wand,
+% const MagickWand *offset_wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o offset_wand: Another image wand.
+%
+*/
+WandExport MagickWand *MagickStereoImage(MagickWand *wand,
+ const MagickWand *offset_wand)
+{
+ Image
+ *stereo_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if ((wand->images == (Image *) NULL) || (offset_wand->images == (Image *) NULL))
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ stereo_image=StereoImage(wand->image,offset_wand->image,&wand->exception);
+ if (stereo_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,stereo_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S t r i p I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickStripImage() removes all profiles and text attributes from the image.
+%
+% The format of the MagickStripImage method is:
+%
+% unsigned int MagickStripImage(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+*/
+WandExport unsigned int MagickStripImage(MagickWand *wand)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=StripImage(wand->image);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k S w i r l I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickSwirlImage() swirls the pixels about the center of the image, where
+% degrees indicates the sweep of the arc through which each pixel is moved.
+% You get a more dramatic effect as the degrees move from 1 to 360.
+%
+% The format of the MagickSwirlImage method is:
+%
+% unsigned int MagickSwirlImage(MagickWand *wand,const double degrees)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o degrees: Define the tightness of the swirling effect.
+%
+*/
+WandExport unsigned int MagickSwirlImage(MagickWand *wand,const double degrees)
+{
+ Image
+ *swirl_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ swirl_image=SwirlImage(wand->image,degrees,&wand->exception);
+ if (swirl_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,swirl_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k T e x t u r e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickTextureImage() repeatedly tiles the texture image across and down the
+% image canvas.
+%
+% The format of the MagickTextureImage method is:
+%
+% MagickWand *MagickTextureImage(MagickWand *wand,
+% const MagickWand *texture_wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o texture_wand: The texture wand
+%
+*/
+WandExport MagickWand *MagickTextureImage(MagickWand *wand,
+ const MagickWand *texture_wand)
+{
+ Image
+ *texture_image;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if ((wand->images == (Image *) NULL) ||
+ (texture_wand->images == (Image *) NULL))
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ texture_image=CloneImage(wand->image,0,0,True,&wand->exception);
+ if (texture_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ status=TextureImage(texture_image,texture_wand->image);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(CloneMagickWandWithImages(wand,texture_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickThresholdImage() changes the value of individual pixels based on
+% the intensity of each pixel compared to threshold. The result is a
+% high-contrast, two color image.
+%
+% The format of the MagickThresholdImage method is:
+%
+% unsigned int MagickThresholdImage(MagickWand *wand,
+% const double threshold)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o threshold: Define the threshold value.
+%
+*/
+WandExport unsigned int MagickThresholdImage(MagickWand *wand,
+ const double threshold)
+{
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ status=ThresholdImage(wand->image,threshold);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k T h r e s h o l d I m a g e C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickThresholdImageChannel() changes the value of individual pixel
+% component based on the intensity of each pixel compared to threshold. The
+% result is a high-contrast, two color image.
+%
+% The format of the MagickThresholdImage method is:
+%
+% unsigned int MagickThresholdImageChannel(MagickWand *wand,
+% const ChannelType channel,const double threshold)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o channel: The channel.
+%
+% o threshold: Define the threshold value.
+%
+*/
+WandExport unsigned int MagickThresholdImageChannel(MagickWand *wand,
+ const ChannelType channel,const double threshold)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return QuantumOperatorImage(wand->image,channel,ThresholdQuantumOp,
+ threshold,&wand->exception);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k T i n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickTintImage() applies a color vector to each pixel in the image. The
+% length of the vector is 0 for black and white and at its maximum for the
+% midtones. The vector weighting function is
+% f(x)=(1-(4.0*((x-0.5)*(x-0.5)))).
+%
+% The format of the MagickTintImage method is:
+%
+% unsigned int MagickTintImage(MagickWand *wand,
+% const PixelWand *tint,const PixelWand *opacity)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o tint: The tint pixel wand.
+%
+% o opacity: The opacity pixel wand.
+%
+*/
+WandExport unsigned int MagickTintImage(MagickWand *wand,
+ const PixelWand *tint,const PixelWand *opacity)
+{
+#if defined(NOT_IMPLEMENTED)
+ char
+ percent_opaque[MaxTextExtent];
+
+ Image
+ *tint_image;
+
+ PixelPacket
+ target;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) MagickFormatString(percent_opaque,MaxTextExtent,"%g,%g,%g,%g",
+ 100.0*PixelGetRedQuantum(tint)/MaxRGB,
+ 100.0*PixelGetGreenQuantum(tint)/MaxRGB,
+ 100.0*PixelGetBlueQuantum(tint)/MaxRGB,
+ 100.0*PixelGetOpacityQuantum(tint)/MaxRGB);
+ PixelGetQuantumColor(tint,&target);
+ tint_image=TintImage(wand->image,percent_opaque,target,&wand->exception);
+ if (tint_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,tint_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+#else
+ ARG_NOT_USED(tint);
+ ARG_NOT_USED(opacity);
+ ThrowWandException(WandError,WandAPINotImplemented,"MagickTintImage");
+#endif /* NOT_IMPLEMENTED */
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k T r a n s f o r m I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickTransformImage() is a convenience method that behaves like
+% MagickResizeImage() or MagickCropImage() but accepts scaling and/or cropping
+% information as a region geometry specification. If the operation fails, the
+% original image handle is returned.
+%
+% The format of the MagickTransformImage method is:
+%
+% MagickWand *MagickTransformImage(MagickWand *wand,const char *crop,
+% const char *geometry)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o crop: A crop geometry string. This geometry defines a subregion of the
+% image to crop.
+%
+% o geometry: An image geometry string. This geometry defines the final
+% size of the image.
+%
+*/
+WandExport MagickWand *MagickTransformImage(MagickWand *wand,
+ const char *crop,const char *geometry)
+{
+ Image
+ *transform_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ return(False);
+ transform_image=CloneImage(wand->image,0,0,True,&wand->exception);
+ if (transform_image == (Image *) NULL)
+ return(False);
+ TransformImage(&transform_image,crop,geometry);
+ if (transform_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandWithImages(wand,transform_image));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k T r a n s p a r e n t I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickTransparentImage() changes any pixel that matches color with the color
+% defined by fill.
+%
+% The format of the MagickTransparentImage method is:
+%
+% unsigned int MagickTransparentImage(MagickWand *wand,
+% const PixelWand *target,const unsigned int opacity,const double fuzz)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o target: Change this target color to specified opacity value within
+% the image.
+%
+% o opacity: The replacement opacity value.
+%
+% o fuzz: By default target must match a particular pixel color
+% exactly. However, in many cases two colors may differ by a small amount.
+% The fuzz member of image defines how much tolerance is acceptable to
+% consider two colors as the same. For example, set fuzz to 10 and the
+% color red at intensities of 100 and 102 respectively are now interpreted
+% as the same color for the purposes of the floodfill.
+%
+*/
+WandExport unsigned int MagickTransparentImage(MagickWand *wand,
+ const PixelWand *target,const Quantum opacity,const double fuzz)
+{
+ PixelPacket
+ target_pixel;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ PixelGetQuantumColor(target,&target_pixel);
+ wand->image->fuzz=fuzz;
+ status=TransparentImage(wand->image,target_pixel,opacity);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k T r i m I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickTrimImage() remove edges that are the background color from the image.
+%
+% The format of the MagickTrimImage method is:
+%
+% unsigned int MagickTrimImage(MagickWand *wand,const double fuzz)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o fuzz: By default target must match a particular pixel color
+% exactly. However, in many cases two colors may differ by a small amount.
+% The fuzz member of image defines how much tolerance is acceptable to
+% consider two colors as the same. For example, set fuzz to 10 and the
+% color red at intensities of 100 and 102 respectively are now interpreted
+% as the same color for the purposes of the floodfill.
+%
+*/
+WandExport unsigned int MagickTrimImage(MagickWand *wand,const double fuzz)
+{
+ Image
+ *trim_image;
+
+ RectangleInfo
+ trim;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ trim.width=0;
+ trim.height=0;
+ trim.x=0;
+ trim.y=0;
+ wand->image->fuzz=fuzz;
+ trim_image=CropImage(wand->image,&trim,&wand->exception);
+ if (trim_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,trim_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k U n s h a r p M a s k I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickUnsharpMaskImage() sharpens an image. We convolve the image with a
+% Gaussian operator of the given radius and standard deviation (sigma).
+% For reasonable results, radius should be larger than sigma. Use a radius
+% of 0 and UnsharpMaskImage() selects a suitable radius for you.
+%
+% The format of the MagickUnsharpMaskImage method is:
+%
+% unsigned int MagickUnsharpMaskImage(MagickWand *wand,const double radius,
+% const double sigma,const double amount,const double threshold)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o radius: The radius of the Gaussian, in pixels, not counting the center
+% pixel.
+%
+% o sigma: The standard deviation of the Gaussian, in pixels.
+%
+% o amount: The percentage of the difference between the original and the
+% blur image that is added back into the original.
+%
+% o threshold: The threshold in pixels needed to apply the diffence amount.
+%
+*/
+WandExport unsigned int MagickUnsharpMaskImage(MagickWand *wand,
+ const double radius,const double sigma,const double amount,
+ const double threshold)
+{
+ Image
+ *unsharp_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ unsharp_image=UnsharpMaskImage(wand->image,radius,sigma,amount,threshold,
+ &wand->exception);
+ if (unsharp_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,unsharp_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W a v e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickWaveImage() creates a "ripple" effect in the image by shifting
+% the pixels vertically along a sine wave whose amplitude and wavelength
+% is specified by the given parameters.
+%
+% The format of the MagickWaveImage method is:
+%
+% unsigned int MagickWaveImage(MagickWand *wand,const double amplitude,
+% const double wave_length)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o amplitude, wave_length: Define the amplitude and wave length of the
+% sine wave.
+%
+*/
+WandExport unsigned int MagickWaveImage(MagickWand *wand,const double amplitude,
+ const double wave_length)
+{
+ Image
+ *wave_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ wave_image=WaveImage(wand->image,amplitude,wave_length,&wand->exception);
+ if (wave_image == (Image *) NULL)
+ return(False);
+ ReplaceImageInList(&wand->image,wave_image);
+ wand->images=GetFirstImageInList(wand->image);
+ return(True);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W h i t e T h r e s h o l d I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickWhiteThresholdImage() is like ThresholdImage() but forces all pixels
+% above the threshold into white while leaving all pixels below the threshold
+% unchanged.
+%
+% The format of the MagickWhiteThresholdImage method is:
+%
+% unsigned int MagickWhiteThresholdImage(MagickWand *wand,
+% const PixelWand *threshold)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o threshold: The pixel wand.
+%
+*/
+WandExport unsigned int MagickWhiteThresholdImage(MagickWand *wand,
+ const PixelWand *threshold)
+{
+ char
+ thresholds[MaxTextExtent];
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) MagickFormatString(thresholds,MaxTextExtent,"%u,%u,%u,%u",
+ PixelGetRedQuantum(threshold),PixelGetGreenQuantum(threshold),
+ PixelGetBlueQuantum(threshold),PixelGetOpacityQuantum(threshold));
+ status=WhiteThresholdImage(wand->image,thresholds);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W r i t e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickWriteImage() writes an image.
+%
+% The format of the MagickWriteImage method is:
+%
+% unsigned int MagickWriteImage(MagickWand *wand,const char *filename)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o filename: The image filename.
+%
+%
+*/
+WandExport unsigned int MagickWriteImage(MagickWand *wand,const char *filename)
+{
+ ImageInfo
+ *write_info;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ (void) strlcpy(wand->image->filename,filename,MaxTextExtent);
+ write_info=CloneImageInfo(wand->image_info);
+ write_info->adjoin=False;
+ status=WriteImage(write_info,wand->image);
+ DestroyImageInfo(write_info);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W r i t e I m a g e s F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickWriteImagesFile() writes an image or image sequence to a stdio
+% FILE handle. This may be used to append an encoded image to an already
+% existing appended image sequence if the file seek position is at the end
+% of an existing file.
+%
+% The format of the MagickWriteImages method is:
+%
+% unsigned int MagickWriteImagesFile(MagickWand *wand,
+% FILE * file,const unsigned int adjoin)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o file: The open (and positioned) file handle.
+%
+% o adjoin: join images into a single multi-image file.
+%
+*/
+WandExport unsigned int MagickWriteImagesFile(MagickWand *wand,FILE * file,
+ const unsigned int adjoin)
+{
+ ImageInfo
+ *write_info;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ write_info=CloneImageInfo(wand->image_info);
+ write_info->adjoin=adjoin;
+ write_info->file=file;
+ status=WriteImagesFile(write_info,wand->images,file,&wand->exception);
+ DestroyImageInfo(write_info);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W r i t e I m a g e B l o b %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickWriteImageBlob() implements direct to memory image formats. It
+% returns the image as a blob (a formatted "file" in memory) and its
+% length, starting from the current position in the image sequence.
+% Use MagickSetImageFormat() to set the format to write to the blob
+% (GIF, JPEG, PNG, etc.).
+%
+% Use MagickResetIterator() on the wand if it is desired to write
+% a sequence from the beginning and the iterator is not currently
+% at the beginning.
+%
+% The format of the MagickWriteImageBlob method is:
+%
+% unsigned char *MagickWriteImageBlob(MagickWand *wand,size_t *length)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o length: The length of the blob.
+%
+*/
+WandExport unsigned char *MagickWriteImageBlob(MagickWand *wand,size_t *length)
+{
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ return(ImageToBlob(wand->image_info,wand->image,length,&wand->exception));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W r i t e I m a g e F i l e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickWriteImageFile() writes an image to an open file descriptor.
+%
+% The format of the MagickWandToFile method is:
+%
+% unsigned int MagickWriteImageFile(MagickWand *wand,FILE *file)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o file: The file descriptor.
+%
+%
+*/
+WandExport unsigned int MagickWriteImageFile(MagickWand *wand,FILE *file)
+{
+ ImageInfo
+ *write_info;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (wand->images == (Image *) NULL)
+ ThrowWandException(WandError,WandContainsNoImages,wand->id);
+ write_info=CloneImageInfo(wand->image_info);
+ write_info->file=file;
+ status=WriteImage(write_info,wand->image);
+ DestroyImageInfo(write_info);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k W r i t e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickWriteImages() writes an image or image sequence. If the wand
+% represents an image sequence, then it is written starting at the first
+% frame in the sequence.
+%
+% The format of the MagickWriteImages method is:
+%
+% unsigned int MagickWriteImages(MagickWand *wand,
+% const char *filename,const unsigned int adjoin)
+%
+% A description of each parameter follows:
+%
+% o wand: The magick wand.
+%
+% o filename: The image filename.
+%
+% o adjoin: join images into a single multi-image file.
+%
+*/
+WandExport unsigned int MagickWriteImages(MagickWand *wand,const char *filename,
+ const unsigned int adjoin)
+{
+ ImageInfo
+ *write_info;
+
+ unsigned int
+ status;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ write_info=CloneImageInfo(wand->image_info);
+ write_info->adjoin=adjoin;
+ status=WriteImages(write_info,wand->images,filename,&wand->exception);
+ DestroyImageInfo(write_info);
+ if (status == False)
+ CopyException(&wand->exception,&wand->image->exception);
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N e w M a g i c k W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NewMagickWand() returns a wand required for all other methods in the API.
+%
+% The format of the NewMagickWand method is:
+%
+% MagickWand NewMagickWand(void)
+%
+%
+*/
+static unsigned long GetMagickWandId(void)
+{
+ static SemaphoreInfo
+ *wand_semaphore = (SemaphoreInfo *) NULL;
+
+ static unsigned long
+ id = 0;
+
+ if (wand_semaphore == (SemaphoreInfo *) NULL)
+ wand_semaphore=AllocateSemaphoreInfo();
+ LockSemaphoreInfo(wand_semaphore);
+ id++;
+ UnlockSemaphoreInfo(wand_semaphore);
+ return(id);
+}
+
+WandExport MagickWand *NewMagickWand(void)
+{
+ MagickWand
+ *wand;
+
+ /*
+ Initialize GraphicsMagick in case it is not already initialized.
+ */
+ InitializeMagick(NULL);
+
+ wand=MagickAllocateMemory(MagickWand *,sizeof(MagickWand));
+ if (wand == (MagickWand *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateWand);
+ (void) memset(wand,0,sizeof(MagickWand));
+ (void) MagickFormatString(wand->id,MaxTextExtent,"MagickWand-%lu",
+ GetMagickWandId());
+ GetExceptionInfo(&wand->exception);
+ wand->image_info=CloneImageInfo((ImageInfo *) NULL);
+ wand->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
+ wand->images=NewImageList();
+ wand->signature=MagickSignature;
+ return(wand);
+}
diff --git a/wand/magick_wand.h b/wand/magick_wand.h
new file mode 100644
index 0000000..41877d6
--- /dev/null
+++ b/wand/magick_wand.h
@@ -0,0 +1,383 @@
+/* Copyright (C) 2003-2016 GraphicsMagick Group */
+
+/*
+ ImageMagick MagickWand interface.
+*/
+
+#ifndef _MAGICK_WAND_H
+#define _MAGICK_WAND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if defined(_VISUALC_)
+# if defined(_MT) && defined(_DLL) && !defined(_LIB)
+# pragma warning( disable: 4273 )
+# if !defined(_WANDLIB_)
+# define WandExport __declspec(dllimport)
+# else
+# define WandExport __declspec(dllexport)
+# endif
+# else
+# define WandExport
+# endif
+
+# pragma warning(disable : 4018)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4142)
+#else
+# define WandExport
+#endif
+
+#include "magick/api.h"
+#include "wand/wand_symbols.h"
+#include "wand/drawing_wand.h"
+#include "wand/pixel_wand.h"
+
+ /*
+ ImageMagick compatibility definitions
+ */
+#define MagickSizeType magick_int64_t
+#define ReplaceCompositeOp CopyCompositeOp
+#define IndexChannel BlackChannel
+#define AreaResource UndefinedResource /* not supported */
+
+extern WandExport int
+ FormatMagickString(char *,const size_t,const char *,...)
+ MAGICK_ATTRIBUTE((format (printf,3,4)));
+extern WandExport size_t
+ CopyMagickString(char *,const char *,const size_t);
+
+typedef struct _MagickWand
+ MagickWand;
+
+extern WandExport char
+ *MagickDescribeImage(MagickWand *),
+ *MagickGetConfigureInfo(MagickWand *,const char *),
+ *MagickGetException(const MagickWand *,ExceptionType *),
+ *MagickGetFilename(const MagickWand *),
+ *MagickGetImageAttribute(MagickWand *, const char *),
+ *MagickGetImageFilename(MagickWand *),
+ *MagickGetImageFormat(MagickWand *),
+ *MagickGetImageSignature(MagickWand *),
+ **MagickQueryFonts(const char *,unsigned long *),
+ **MagickQueryFormats(const char *,unsigned long *);
+
+extern WandExport CompositeOperator
+ MagickGetImageCompose(MagickWand *);
+
+extern WandExport ColorspaceType
+ MagickGetImageColorspace(MagickWand *);
+
+extern WandExport CompressionType
+ MagickGetImageCompression(MagickWand *);
+
+extern WandExport const char
+ *MagickGetCopyright(void),
+ *MagickGetHomeURL(void),
+ *MagickGetImageGeometry(MagickWand *),
+ *MagickGetPackageName(void),
+ *MagickGetQuantumDepth(unsigned long *),
+ *MagickGetReleaseDate(void),
+ *MagickGetVersion(unsigned long *);
+
+extern WandExport DisposeType
+ MagickGetImageDispose(MagickWand *);
+
+extern WandExport double
+ MagickGetImageGamma(MagickWand *),
+ MagickGetImageFuzz(MagickWand *),
+ *MagickGetSamplingFactors(MagickWand *,unsigned long *),
+ *MagickQueryFontMetrics(MagickWand *,const DrawingWand *,const char *);
+
+extern WandExport GravityType
+ MagickGetImageGravity(MagickWand *wand);
+
+extern WandExport ImageType
+ MagickGetImageType(MagickWand *);
+
+extern WandExport ImageType
+ MagickGetImageSavedType(MagickWand *);
+
+extern WandExport InterlaceType
+ MagickGetImageInterlaceScheme(MagickWand *);
+
+extern WandExport long
+ MagickGetImageIndex(MagickWand *);
+
+extern WandExport MagickSizeType
+ MagickGetImageSize(MagickWand *);
+
+extern WandExport MagickWand
+ *CloneMagickWand(const MagickWand *),
+ *MagickAppendImages(MagickWand *,const unsigned int),
+ *MagickAverageImages(MagickWand *),
+ *MagickCoalesceImages(MagickWand *),
+ *MagickCompareImageChannels(MagickWand *,const MagickWand *,const ChannelType,
+ const MetricType,double *),
+ *MagickCompareImages(MagickWand *,const MagickWand *,const MetricType,
+ double *),
+ *MagickDeconstructImages(MagickWand *),
+ *MagickFlattenImages(MagickWand *),
+ *MagickFxImage(MagickWand *,const char *),
+ *MagickFxImageChannel(MagickWand *,const ChannelType,const char *),
+ *MagickGetImage(MagickWand *),
+ *MagickMorphImages(MagickWand *,const unsigned long),
+ *MagickMosaicImages(MagickWand *),
+ *MagickMontageImage(MagickWand *,const DrawingWand *,const char *,
+ const char *,const MontageMode,const char *),
+ *MagickPreviewImages(MagickWand *wand,const PreviewType),
+ *MagickSteganoImage(MagickWand *,const MagickWand *,const long),
+ *MagickStereoImage(MagickWand *,const MagickWand *),
+ *MagickTextureImage(MagickWand *,const MagickWand *),
+ *MagickTransformImage(MagickWand *,const char *,const char *),
+ *NewMagickWand(void);
+
+extern WandExport OrientationType
+ MagickGetImageOrientation(MagickWand *);
+
+extern WandExport PixelWand
+ **MagickGetImageHistogram(MagickWand *,unsigned long *);
+
+extern WandExport RenderingIntent
+ MagickGetImageRenderingIntent(MagickWand *);
+
+extern WandExport ResolutionType
+ MagickGetImageUnits(MagickWand *);
+
+extern WandExport unsigned int
+ DestroyMagickWand(MagickWand *),
+ MagickAdaptiveThresholdImage(MagickWand *,const unsigned long,
+ const unsigned long,const long),
+ MagickAddImage(MagickWand *,const MagickWand *),
+ MagickAddNoiseImage(MagickWand *,const NoiseType),
+ MagickAffineTransformImage(MagickWand *,const DrawingWand *),
+ MagickAnnotateImage(MagickWand *,const DrawingWand *,const double,
+ const double,const double,const char *),
+ MagickAnimateImages(MagickWand *,const char *),
+ MagickAutoOrientImage(MagickWand *wand,const OrientationType),
+ MagickBlackThresholdImage(MagickWand *,const PixelWand *),
+ MagickBlurImage(MagickWand *,const double,const double),
+ MagickBorderImage(MagickWand *,const PixelWand *,const unsigned long,
+ const unsigned long),
+ MagickCdlImage(MagickWand *wand,const char *cdl),
+ MagickCharcoalImage(MagickWand *,const double,const double),
+ MagickChopImage(MagickWand *,const unsigned long,const unsigned long,
+ const long,const long),
+ MagickClipImage(MagickWand *),
+ MagickClipPathImage(MagickWand *,const char *,const unsigned int),
+ MagickColorFloodfillImage(MagickWand *,const PixelWand *,const double,
+ const PixelWand *,const long,const long),
+ MagickColorizeImage(MagickWand *,const PixelWand *,const PixelWand *),
+ MagickCommentImage(MagickWand *,const char *),
+ MagickCompositeImage(MagickWand *,const MagickWand *,const CompositeOperator,
+ const long,const long),
+ MagickContrastImage(MagickWand *,const unsigned int),
+ MagickConvolveImage(MagickWand *,const unsigned long,const double *),
+ MagickCropImage(MagickWand *,const unsigned long,const unsigned long,
+ const long,const long),
+ MagickCycleColormapImage(MagickWand *,const long),
+ MagickDespeckleImage(MagickWand *),
+ MagickDisplayImage(MagickWand *,const char *),
+ MagickDisplayImages(MagickWand *,const char *),
+ MagickDrawImage(MagickWand *,const DrawingWand *),
+ MagickEdgeImage(MagickWand *,const double),
+ MagickEmbossImage(MagickWand *,const double,const double),
+ MagickEnhanceImage(MagickWand *),
+ MagickEqualizeImage(MagickWand *),
+ MagickExtentImage(MagickWand *,const size_t,const size_t,const ssize_t, const ssize_t),
+ MagickFlipImage(MagickWand *),
+ MagickFlopImage(MagickWand *),
+ MagickFrameImage(MagickWand *,const PixelWand *,const unsigned long,
+ const unsigned long,const long,const long),
+ MagickGammaImage(MagickWand *,const double),
+ MagickGammaImageChannel(MagickWand *,const ChannelType,const double),
+ MagickGetImageBackgroundColor(MagickWand *,PixelWand *),
+ MagickGetImageBluePrimary(MagickWand *,double *,double *),
+ MagickGetImageBorderColor(MagickWand *,PixelWand *),
+ MagickGetImageBoundingBox(MagickWand *wand,const double fuzz,
+ unsigned long *width,unsigned long *height,long *x, long *y),
+ MagickGetImageChannelExtrema(MagickWand *,const ChannelType,unsigned long *,
+ unsigned long *),
+ MagickGetImageChannelMean(MagickWand *,const ChannelType,double *,double *),
+ MagickGetImageColormapColor(MagickWand *,const unsigned long,PixelWand *),
+ MagickGetImageExtrema(MagickWand *,unsigned long *,unsigned long *),
+ MagickGetImageGreenPrimary(MagickWand *,double *,double *),
+ MagickGetImageMatte(MagickWand *),
+ MagickGetImageMatteColor(MagickWand *,PixelWand *),
+ MagickGetImagePage(MagickWand *wand,
+ unsigned long *width,unsigned long *height,long *x,long *y),
+ MagickGetImagePixels(MagickWand *,const long,const long,const unsigned long,
+ const unsigned long,const char *,const StorageType,unsigned char *),
+ MagickGetImageRedPrimary(MagickWand *,double *,double *),
+ MagickGetImageResolution(MagickWand *,double *,double *),
+ MagickGetImageWhitePoint(MagickWand *,double *,double *),
+ MagickGetSize(const MagickWand *,unsigned long *,unsigned long *),
+ MagickHaldClutImage(MagickWand *wand,const MagickWand *clut_wand),
+ MagickHasNextImage(MagickWand *),
+ MagickHasPreviousImage(MagickWand *),
+ MagickImplodeImage(MagickWand *,const double),
+ MagickLabelImage(MagickWand *,const char *),
+ MagickLevelImage(MagickWand *,const double,const double,const double),
+ MagickLevelImageChannel(MagickWand *,const ChannelType,const double,
+ const double,const double),
+ MagickMagnifyImage(MagickWand *),
+ MagickMapImage(MagickWand *,const MagickWand *,const unsigned int),
+ MagickMatteFloodfillImage(MagickWand *,const Quantum,const double,
+ const PixelWand *,const long,const long),
+ MagickMedianFilterImage(MagickWand *,const double),
+ MagickMinifyImage(MagickWand *),
+ MagickModulateImage(MagickWand *,const double,const double,const double),
+ MagickMotionBlurImage(MagickWand *,const double,const double,const double),
+ MagickNegateImage(MagickWand *,const unsigned int),
+ MagickNegateImageChannel(MagickWand *,const ChannelType,const unsigned int),
+ MagickNextImage(MagickWand *),
+ MagickNormalizeImage(MagickWand *),
+ MagickOilPaintImage(MagickWand *,const double),
+ MagickOpaqueImage(MagickWand *,const PixelWand *,const PixelWand *,
+ const double),
+ MagickOperatorImageChannel(MagickWand *,const ChannelType,const QuantumOperator,
+ const double),
+ MagickPingImage(MagickWand *,const char *),
+ MagickPreviousImage(MagickWand *),
+ MagickProfileImage(MagickWand *,const char *,const unsigned char *,
+ const unsigned long),
+ MagickQuantizeImage(MagickWand *,const unsigned long,const ColorspaceType,
+ const unsigned long,const unsigned int,const unsigned int),
+ MagickQuantizeImages(MagickWand *,const unsigned long,const ColorspaceType,
+ const unsigned long,const unsigned int,const unsigned int),
+ MagickRadialBlurImage(MagickWand *,const double),
+ MagickRaiseImage(MagickWand *,const unsigned long,const unsigned long,
+ const long,const long,const unsigned int),
+ MagickReadImage(MagickWand *,const char *),
+ MagickReadImageBlob(MagickWand *,const unsigned char *,const size_t length),
+ MagickReadImageFile(MagickWand *,FILE *),
+ MagickReduceNoiseImage(MagickWand *,const double),
+ MagickRelinquishMemory(void *),
+ MagickRemoveImage(MagickWand *),
+ MagickRemoveImageOption(MagickWand *wand,const char *,const char *),
+ MagickResampleImage(MagickWand *,const double,const double,const FilterTypes,
+ const double),
+ MagickResizeImage(MagickWand *,const unsigned long,const unsigned long,
+ const FilterTypes,const double),
+ MagickRollImage(MagickWand *,const long,const long),
+ MagickRotateImage(MagickWand *,const PixelWand *,const double),
+ MagickSampleImage(MagickWand *,const unsigned long,const unsigned long),
+ MagickScaleImage(MagickWand *,const unsigned long,const unsigned long),
+ MagickSeparateImageChannel(MagickWand *,const ChannelType),
+ MagickSetCompressionQuality(MagickWand *wand,const unsigned long quality),
+ MagickSetFilename(MagickWand *,const char *),
+ MagickSetFormat(MagickWand *,const char *),
+ MagickSetImage(MagickWand *,const MagickWand *),
+ MagickSetImageAttribute(MagickWand *,const char *, const char *),
+ MagickSetImageBackgroundColor(MagickWand *,const PixelWand *),
+ MagickSetImageBluePrimary(MagickWand *,const double,const double),
+ MagickSetImageBorderColor(MagickWand *,const PixelWand *),
+ MagickSetImageChannelDepth(MagickWand *,const ChannelType,
+ const unsigned long),
+ MagickSetImageColormapColor(MagickWand *,const unsigned long,
+ const PixelWand *),
+ MagickSetImageCompose(MagickWand *,const CompositeOperator),
+ MagickSetImageCompression(MagickWand *,const CompressionType),
+ MagickSetImageDelay(MagickWand *,const unsigned long),
+ MagickSetImageDepth(MagickWand *,const unsigned long),
+ MagickSetImageDispose(MagickWand *,const DisposeType),
+ MagickSetImageColorspace(MagickWand *,const ColorspaceType),
+ MagickSetImageGreenPrimary(MagickWand *,const double,const double),
+ MagickSetImageGamma(MagickWand *,const double),
+ MagickSetImageGeometry(MagickWand *,const char *),
+ MagickSetImageGravity(MagickWand *,const GravityType),
+ MagickSetImageFilename(MagickWand *,const char *),
+ MagickSetImageFormat(MagickWand *wand,const char *format),
+ MagickSetImageFuzz(MagickWand *,const double),
+ MagickSetImageIndex(MagickWand *,const long),
+ MagickSetImageInterlaceScheme(MagickWand *,const InterlaceType),
+ MagickSetImageIterations(MagickWand *,const unsigned long),
+ MagickSetImageMatte(MagickWand *,const unsigned int),
+ MagickSetImageMatteColor(MagickWand *,const PixelWand *),
+ MagickSetImageOption(MagickWand *,const char *,const char *,const char *),
+ MagickSetImageOrientation(MagickWand *,const OrientationType),
+ MagickSetImagePage(MagickWand *wand,
+ const unsigned long width,const unsigned long height,const long x,
+ const long y),
+ MagickSetImagePixels(MagickWand *,const long,const long,const unsigned long,
+ const unsigned long,const char *,const StorageType,unsigned char *),
+ MagickSetImageRedPrimary(MagickWand *,const double,const double),
+ MagickSetImageRenderingIntent(MagickWand *,const RenderingIntent),
+ MagickSetImageResolution(MagickWand *,const double,const double),
+ MagickSetImageScene(MagickWand *,const unsigned long),
+ MagickSetImageType(MagickWand *,const ImageType),
+ MagickSetImageSavedType(MagickWand *,const ImageType),
+ MagickSetImageUnits(MagickWand *,const ResolutionType),
+ MagickSetImageVirtualPixelMethod(MagickWand *,const VirtualPixelMethod),
+ MagickSetPassphrase(MagickWand *,const char *),
+ MagickSetImageProfile(MagickWand *,const char *,const unsigned char *,
+ const unsigned long),
+ MagickSetResolution(MagickWand *wand,
+ const double x_resolution,const double y_resolution),
+ MagickSetResolutionUnits(MagickWand *wand,const ResolutionType units),
+ MagickSetResourceLimit(const ResourceType type,const unsigned long limit),
+ MagickSetSamplingFactors(MagickWand *,const unsigned long,const double *),
+ MagickSetSize(MagickWand *,const unsigned long,const unsigned long),
+ MagickSetImageWhitePoint(MagickWand *,const double,const double),
+ MagickSetInterlaceScheme(MagickWand *,const InterlaceType),
+ MagickSharpenImage(MagickWand *,const double,const double),
+ MagickShaveImage(MagickWand *,const unsigned long,const unsigned long),
+ MagickShearImage(MagickWand *,const PixelWand *,const double,const double),
+ MagickSolarizeImage(MagickWand *,const double),
+ MagickSpreadImage(MagickWand *,const double),
+ MagickStripImage(MagickWand *),
+ MagickSwirlImage(MagickWand *,const double),
+ MagickTintImage(MagickWand *,const PixelWand *,const PixelWand *),
+ MagickThresholdImage(MagickWand *,const double),
+ MagickThresholdImageChannel(MagickWand *,const ChannelType,const double),
+ MagickTransparentImage(MagickWand *,const PixelWand *,const Quantum,
+ const double),
+ MagickTrimImage(MagickWand *,const double),
+ MagickUnsharpMaskImage(MagickWand *,const double,const double,const double,
+ const double),
+ MagickWaveImage(MagickWand *,const double,const double),
+ MagickWhiteThresholdImage(MagickWand *,const PixelWand *),
+ MagickWriteImage(MagickWand *,const char *),
+ MagickWriteImageFile(MagickWand *,FILE *),
+ MagickWriteImagesFile(MagickWand *,FILE *,const unsigned int),
+ MagickWriteImages(MagickWand *,const char *,const unsigned int);
+
+extern WandExport unsigned long
+ MagickGetImageColors(MagickWand *),
+ MagickGetImageDelay(MagickWand *),
+ MagickGetImageChannelDepth(MagickWand *,const ChannelType),
+ MagickGetImageDepth(MagickWand *),
+ MagickGetImageHeight(MagickWand *),
+ MagickGetImageIterations(MagickWand *),
+ MagickGetImageScene(MagickWand *),
+ MagickGetImageWidth(MagickWand *),
+ MagickGetNumberImages(MagickWand *),
+ MagickGetResourceLimit(const ResourceType);
+
+extern WandExport VirtualPixelMethod
+ MagickGetImageVirtualPixelMethod(MagickWand *);
+
+extern WandExport unsigned char
+ *MagickGetImageProfile(MagickWand *,const char *,unsigned long *),
+ *MagickRemoveImageProfile(MagickWand *,const char *,unsigned long *),
+ *MagickWriteImageBlob(MagickWand *,size_t *);
+
+extern WandExport void
+ MagickClearException(MagickWand *),
+ MagickResetIterator(MagickWand *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/wand/pixel_wand.c b/wand/pixel_wand.c
new file mode 100644
index 0000000..20c6ff8
--- /dev/null
+++ b/wand/pixel_wand.c
@@ -0,0 +1,1608 @@
+/* Copyright (C) 2003-2014 GraphicsMagick Group */
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% PPPP IIIII X X EEEEE L %
+% P P I X X E L %
+% PPPP I X EEE L %
+% P I X X E L %
+% P IIIII X X EEEEE LLLLL %
+% %
+% W W AAA N N DDDD %
+% W W A A NN N D D %
+% W W W AAAAA N N N D D %
+% WW WW A A N NN D D %
+% W W A A N N DDDD %
+% %
+% %
+% ImageMagick Image Pixel Wand Methods %
+% %
+% Software Design %
+% John Cristy %
+% March 2003 %
+% %
+% %
+% Copyright (C) 1999-2004 ImageMagick Studio LLC, a non-profit organization %
+% dedicated to making software imaging solutions freely available. %
+% %
+% This software and documentation is provided "as is," and the copyright %
+% holders and contributing author(s) make no representations or warranties, %
+% express or implied, including but not limited to, warranties of %
+% merchantability or fitness for any particular purpose or that the use of %
+% the software or documentation will not infringe any third party patents, %
+% copyrights, trademarks or other rights. %
+% %
+% The copyright holders and contributing author(s) will not be held liable %
+% for any direct, indirect, special or consequential damages arising out of %
+% any use of the software or documentation, even if advised of the %
+% possibility of such damage. %
+% %
+% Permission is hereby granted to use, copy, modify, and distribute this %
+% source code, or portions hereof, documentation and executables, for any %
+% purpose, without fee, subject to the following restrictions: %
+% %
+% 1. The origin of this source code must not be misrepresented. %
+% 2. Altered versions must be plainly marked as such and must not be %
+% misrepresented as being the original source. %
+% 3. This Copyright notice may not be removed or altered from any source %
+% or altered source distribution. %
+% %
+% The copyright holders and contributing author(s) specifically permit, %
+% without fee, and encourage the use of this source code as a component for %
+% supporting image processing in commercial products. If you use this %
+% source code in a product, acknowledgment is not required but would be %
+% appreciated. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% This is the tentative public API for ImageMagick. Use it with caution
+% because it is subject to change until it is finished somewhere around
+% January of 2004.
+%
+*/
+
+/*
+ Include declarations.
+*/
+#include "magick/studio.h"
+#include "magick/error.h"
+#include "wand/magick_wand.h"
+#include "wand/wand_private.h"
+
+/*
+ Typedef declarations.
+*/
+
+typedef struct _SuperDoublePixelPacket
+{
+ double
+ red,
+ green,
+ blue,
+ opacity,
+ index;
+} SuperDoublePixelPacket;
+
+struct _PixelWand
+{
+ ExceptionInfo
+ exception;
+
+ ColorspaceType
+ colorspace;
+
+ unsigned int
+ matte;
+
+ SuperDoublePixelPacket
+ pixel;
+
+ unsigned long
+ count,
+ signature;
+};
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e P i x e l W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ClonePixelWand() creates an exact copy of a PixelWand. PixelWand may not be
+% a null pointer.
+%
+% The format of the ClonePixelWand method is:
+%
+% PixelWand *ClonePixelWand(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand to clone.
+%
+%
+*/
+WandExport PixelWand *
+ClonePixelWand(const PixelWand *wand)
+{
+ PixelWand
+ *clone_wand;
+
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+
+ clone_wand=NewPixelWand();
+ clone_wand->colorspace=wand->colorspace;
+ clone_wand->matte=wand->matte;
+ clone_wand->pixel=wand->pixel;
+ clone_wand->count=wand->count;
+
+ return clone_wand;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% C l o n e P i x e l W a n d s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% ClonePixelWands creates a deep-copy an array of PixelWands.
+%
+% The format of the ClonePixelWands method is:
+%
+% PixelWand **ClonePixelWands(const PixelWand **wands,
+% const unsigned long number_wands)
+%
+% A description of each parameter follows:
+%
+% o wands: The pixel wands to clone.
+%
+% o number_wands: The number of wands in the array
+%
+*/
+WandExport PixelWand **
+ClonePixelWands(const PixelWand **wands,const unsigned long number_wands)
+{
+ PixelWand
+ **clone_wands;
+
+ unsigned long
+ i;
+
+ assert(wands != (const PixelWand **) NULL);
+ assert(number_wands > 0);
+
+ clone_wands=MagickAllocateArray(PixelWand **,
+ sizeof(PixelWand *),number_wands);
+ if (clone_wands == (PixelWand **) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateWand);
+
+ for (i=0; i < number_wands; i++)
+ clone_wands[i]=ClonePixelWand(wands[i]);
+
+ return clone_wands;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% D e s t r o y P i x e l W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DestroyPixelWand() deallocates resources associated with a PixelWand.
+%
+% The format of the DestroyPixelWand method is:
+%
+% unsigned int DestroyPixelWand(PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+%
+*/
+WandExport void DestroyPixelWand(PixelWand *wand)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ MagickFreeMemory(wand);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N e w P i x e l W a n d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NewPixelWand() returns a new pixel wand.
+%
+% The format of the NewPixelWand method is:
+%
+% PixelWand NewPixelWand(void)
+%
+%
+*/
+WandExport PixelWand *NewPixelWand(void)
+{
+ struct _PixelWand
+ *wand;
+
+ /*
+ Initialize GraphicsMagick in case it is not already initialized.
+ */
+ InitializeMagick(NULL);
+
+ wand=MagickAllocateMemory(struct _PixelWand *,sizeof(struct _PixelWand));
+ if (wand == (PixelWand *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateWand);
+ (void) memset(wand,0,sizeof(PixelWand));
+ GetExceptionInfo(&wand->exception);
+ wand->colorspace=RGBColorspace;
+ wand->signature=MagickSignature;
+ return(wand);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% N e w P i x e l W a n d s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% NewPixelWands() returns an array of pixel wands.
+%
+% The format of the NewPixelWand method is:
+%
+% PixelWand NewPixelWands(const unsigned long number_wands)
+%
+% A description of each parameter follows:
+%
+% o number_wands: The number of wands.
+%
+*/
+WandExport PixelWand **NewPixelWands(const unsigned long number_wands)
+{
+ register long
+ i;
+
+ struct _PixelWand
+ **wands;
+
+ wands=MagickAllocateMemory(struct _PixelWand **,
+ (size_t) number_wands*sizeof(struct _PixelWand *));
+ if (wands == (PixelWand **) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateWand);
+ for (i=0; i < (long) number_wands; i++)
+ wands[i]=NewPixelWand();
+ return(wands);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t E x c e p t i o n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetException() returns the severity, reason, and description of any
+% error that occurs when using the pixel wand methods.
+%
+% The format of the PixelGetException method is:
+%
+% unsigned int PixelGetException(PixelWand *wand,char **description)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o description: A description of the error.
+%
+*/
+
+WandExport unsigned int PixelGetException(PixelWand *wand,char **description)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(description != (char **) NULL);
+ *description=(char *) malloc(2*MaxTextExtent);
+ if (*description == (char *) NULL)
+ MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
+ UnableToAllocateString);
+ **description='\0';
+ if (wand->exception.reason != (char *) NULL)
+ (void) strlcpy(*description,GetLocaleExceptionMessage(
+ wand->exception.severity,wand->exception.reason),MaxTextExtent);
+ if (wand->exception.description != (char *) NULL)
+ {
+ (void) strlcat(*description," (",MaxTextExtent);
+ (void) strlcat(*description,GetLocaleExceptionMessage(
+ wand->exception.severity,wand->exception.description),MaxTextExtent);
+ (void) strlcat(*description,")",MaxTextExtent);
+ }
+ return(wand->exception.severity);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t B l a c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetBlack() returns the normalized black color of the pixel wand.
+%
+% The format of the PixelGetBlack method is:
+%
+% double PixelGetBlack(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport double PixelGetBlack(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->pixel.index);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t B l a c k Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetBlackQuantum() returns the black color of the pixel wand. The
+% color is in the range of [0..MaxRGB]
+%
+% The format of the PixelGetBlackQuantum method is:
+%
+% Quantum PixelGetBlackQuantum(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport Quantum PixelGetBlackQuantum(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return((Quantum) (MaxRGB*wand->pixel.index+0.5));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t B l u e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetBlue(const) returns the normalized blue color of the pixel wand.
+%
+% The format of the PixelGetBlue method is:
+%
+% double PixelGetBlue(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport double PixelGetBlue(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->pixel.blue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t B l u e Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetBlueQuantum(const ) returns the blue color of the pixel wand. The
+% color is in the range of [0..MaxRGB]
+%
+% The format of the PixelGetBlueQuantum method is:
+%
+% Quantum PixelGetBlueQuantum(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport Quantum PixelGetBlueQuantum(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return((Quantum) (MaxRGB*wand->pixel.blue+0.5));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t C o l o r A s S t r i n g %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetColorAsString() gets the color of the pixel wand.
+%
+% The format of the PixelGetColorAsString method is:
+%
+% char *PixelGetColorAsString(PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport char *PixelGetColorAsString(const PixelWand *wand)
+{
+ char
+ color[MaxTextExtent];
+
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ (void) FormatString(color,"%u,%u,%u",
+ (Quantum) (MaxRGB*wand->pixel.red+0.5),
+ (Quantum) (MaxRGB*wand->pixel.green+0.5),
+ (Quantum) (MaxRGB*wand->pixel.blue+0.5));
+ if (wand->colorspace == CMYKColorspace)
+ (void) FormatString(color,"%.1024s,%u",color,
+ (Quantum) (MaxRGB*wand->pixel.index+0.5));
+ if (wand->matte != False)
+ (void) FormatString(color,"%.1024s,%u",color,
+ (Quantum) (MaxRGB*wand->pixel.opacity+0.5));
+ return(AcquireString(color));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t C o l o r C o u n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetColorCount() returns the color count associated with this color.
+%
+% The format of the PixelGetColorCount method is:
+%
+% unsigned long PixelGetColorCount(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport unsigned long PixelGetColorCount(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->count);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t C y a n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetCyan() returns the normalized cyan color of the pixel wand.
+%
+% The format of the PixelGetCyan method is:
+%
+% double PixelGetCyan(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport double PixelGetCyan(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->pixel.red);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t C y a n Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetCyanQuantum() returns the cyan color of the pixel wand. The color
+% is in the range of [0..MaxRGB]
+%
+% The format of the PixelGetCyanQuantum method is:
+%
+% Quantum PixelGetCyanQuantum(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport Quantum PixelGetCyanQuantum(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return((Quantum) (MaxRGB*wand->pixel.red+0.5));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t G r e e n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetGreen(const ) returns the normalized green color of the pixel wand.
+%
+% The format of the PixelGetGreen method is:
+%
+% double PixelGetGreen(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport double PixelGetGreen(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->pixel.green);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t G r e e n Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetGreenQuantum(const ) returns the green color of the pixel wand. The
+% color is in the range of [0..MaxRGB]
+%
+% The format of the PixelGetGreenQuantum method is:
+%
+% Quantum PixelGetGreenQuantum(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport Quantum PixelGetGreenQuantum(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return((Quantum) (MaxRGB*wand->pixel.green+0.5));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t M a g e n t a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetMagenta() returns the normalized magenta color of the pixel wand.
+%
+% The format of the PixelGetMagenta method is:
+%
+% double PixelGetMagenta(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport double PixelGetMagenta(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->pixel.green);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t M a g e n t a Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetMagentaQuantum() returns the magenta color of the pixel wand. The
+% color is in the range of [0..MaxRGB]
+%
+% The format of the PixelGetMagentaQuantum method is:
+%
+% Quantum PixelGetMagentaQuantum(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport Quantum PixelGetMagentaQuantum(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return((Quantum) (MaxRGB*wand->pixel.green+0.5));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetOpacity(const ) returns the normalized opacity color of the pixel
+% wand.
+%
+% The format of the PixelGetOpacity method is:
+%
+% double PixelGetOpacity(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport double PixelGetOpacity(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->pixel.opacity);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t O p a c i t y Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetOpacityQuantum(const ) returns the opacity color of the pixel wand.
+% The color is in the range of [0..MaxRGB]
+%
+% The format of the PixelGetOpacityQuantum method is:
+%
+% Quantum PixelGetOpacityQuantum(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport Quantum PixelGetOpacityQuantum(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return((Quantum) (MaxRGB*wand->pixel.opacity+0.5));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
++ P i x e l G e t Q u a n t u m C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetQuantumColor() gets the color of the pixel wand.
+%
+% The format of the PixelGetQuantumColor method is:
+%
+% PixelGetQuantumColor(PixelWand *wand,PixelPacket *color)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o color: Return the pixel wand color here.
+%
+*/
+WandExport void PixelGetQuantumColor(const PixelWand *wand,PixelPacket *color)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(color != (PixelPacket *) NULL);
+ color->red=(Quantum) (MaxRGB*wand->pixel.red+0.5);
+ color->green=(Quantum) (MaxRGB*wand->pixel.green+0.5);
+ color->blue=(Quantum) (MaxRGB*wand->pixel.blue+0.5);
+ color->opacity=(Quantum) (MaxRGB*wand->pixel.opacity+0.5);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t R e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetRed(const ) returns the normalized red color of the pixel wand.
+%
+% The format of the PixelGetRed method is:
+%
+% double PixelGetRed(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport double PixelGetRed(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->pixel.red);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t R e d Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetRedQuantum(const ) returns the red color of the pixel wand. The
+% color is in the range of [0..MaxRGB]
+%
+% The format of the PixelGetRedQuantum method is:
+%
+% Quantum PixelGetRedQuantum(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport Quantum PixelGetRedQuantum(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return((Quantum) (MaxRGB*wand->pixel.red+0.5));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t Y e l l o w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetYellow() returns the normalized yellow color of the pixel wand.
+%
+% The format of the PixelGetYellow method is:
+%
+% double PixelGetYellow(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport double PixelGetYellow(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return(wand->pixel.blue);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l G e t Y e l l o w Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelGetYellowQuantum() returns the yellow color of the pixel wand. The
+% color is in the range of [0..MaxRGB]
+%
+% The format of the PixelGetYellowQuantum method is:
+%
+% Quantum PixelGetYellowQuantum(const PixelWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+*/
+WandExport Quantum PixelGetYellowQuantum(const PixelWand *wand)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ return((Quantum) (MaxRGB*wand->pixel.blue+0.5));
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t B l a c k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetBlack() sets the normalized black color of the pixel wand.
+%
+% The format of the PixelSetBlack method is:
+%
+% unsigned int PixelSetBlack(PixelWand *wand,const double black)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o black: The black color.
+%
+*/
+WandExport void PixelSetBlack(PixelWand *wand,const double black)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (black > 1.0)
+ wand->pixel.index=1.0;
+ else
+ if (black < 0.0)
+ wand->pixel.index=0.0;
+ else
+ wand->pixel.index=black;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t B l a c k Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetBlackQuantum() sets the black color of the pixel wand. The color
+% must be in the range of [0..MaxRGB]
+%
+% The format of the PixelSetBlackQuantum method is:
+%
+% unsigned int PixelSetBlackQuantum(PixelWand *wand,
+% const Quantum black)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o black: The black color.
+%
+*/
+WandExport void PixelSetBlackQuantum(PixelWand *wand,const Quantum black)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->pixel.index=(double) black/MaxRGB;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t B l u e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetBlue() sets the normalized blue color of the pixel wand.
+%
+% The format of the PixelSetBlue method is:
+%
+% unsigned int PixelSetBlue(PixelWand *wand,const double blue)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o blue: The blue color.
+%
+*/
+WandExport void PixelSetBlue(PixelWand *wand,const double blue)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (blue > 1.0)
+ wand->pixel.blue=1.0;
+ else
+ if (blue < 0.0)
+ wand->pixel.blue=0.0;
+ else
+ wand->pixel.blue=blue;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t B l u e Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetBlueQuantum() sets the blue color of the pixel wand. The color must
+% be in the range of [0..MaxRGB]
+%
+% The format of the PixelSetBlueQuantum method is:
+%
+% unsigned int PixelSetBlueQuantum(PixelWand *wand,const Quantum blue)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o blue: The blue color.
+%
+*/
+WandExport void PixelSetBlueQuantum(PixelWand *wand,const Quantum blue)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->pixel.blue=(double) blue/MaxRGB;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetColor() sets the color of the pixel wand with a string (e.g.
+% "blue", "#0000ff", "rgb(0,0,255)", etc.).
+%
+% The format of the PixelSetColor method is:
+%
+% unsigned int PixelSetColor(PixelWand *wand,const char *color)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o color: The pixel wand color.
+%
+%
+*/
+WandExport unsigned int PixelSetColor(PixelWand *wand,const char *color)
+{
+ PixelPacket
+ pixel;
+
+ unsigned int
+ status;
+
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+
+ status=QueryColorDatabase(color,&pixel,&wand->exception);
+ if (status == False)
+ return(status);
+
+ wand->colorspace=RGBColorspace;
+ wand->matte=0;
+ wand->pixel.red=(double) pixel.red/MaxRGB;
+ wand->pixel.green=(double) pixel.green/MaxRGB;
+ wand->pixel.blue=(double) pixel.blue/MaxRGB;
+ wand->pixel.opacity=(double) pixel.opacity/MaxRGB;
+ wand->pixel.index=0;
+ return(status);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t C o l o r C o u n t %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetColorCount() sets the color count of the pixel wand.
+%
+% The format of the PixelSetColorCount method is:
+%
+% unsigned int PixelSetColorCount(PixelWand *wand,
+% const unsigned long count)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o count: The number of this particular color.
+%
+*/
+WandExport void PixelSetColorCount(PixelWand *wand,const unsigned long count)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->count=count;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t C y a n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetCyan() sets the normalized cyan color of the pixel wand.
+%
+% The format of the PixelSetCyan method is:
+%
+% unsigned int PixelSetCyan(PixelWand *wand,const double cyan)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o cyan: The cyan color.
+%
+*/
+WandExport void PixelSetCyan(PixelWand *wand,const double cyan)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (cyan > 1.0)
+ wand->pixel.red=1.0;
+ else
+ if (cyan < 0.0)
+ wand->pixel.red=0.0;
+ else
+ wand->pixel.red=cyan;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t C y a n Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetCyanQuantum() sets the cyan color of the pixel wand. The color must
+% be in the range of [0..MaxRGB]
+%
+% The format of the PixelSetCyanQuantum method is:
+%
+% unsigned int PixelSetCyanQuantum(PixelWand *wand,const Quantum cyan)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o cyan: The cyan color.
+%
+*/
+WandExport void PixelSetCyanQuantum(PixelWand *wand,const Quantum cyan)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->pixel.red=(double) cyan/MaxRGB;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t G r e e n %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetGreen() sets the normalized green color of the pixel wand.
+%
+% The format of the PixelSetGreen method is:
+%
+% unsigned int PixelSetGreen(PixelWand *wand,const double green)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o green: The green color.
+%
+*/
+WandExport void PixelSetGreen(PixelWand *wand,const double green)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (green > 1.0)
+ wand->pixel.green=1.0;
+ else
+ if (green < 0.0)
+ wand->pixel.green=0.0;
+ else
+ wand->pixel.green=green;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t G r e e n Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetGreenQuantum() sets the green color of the pixel wand. The color must
+% be in the range of [0..MaxRGB]
+%
+% The format of the PixelSetGreenQuantum method is:
+%
+% unsigned int PixelSetGreenQuantum(PixelWand *wand,const Quantum green)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o green: The green color.
+%
+*/
+WandExport void PixelSetGreenQuantum(PixelWand *wand,const Quantum green)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->pixel.green=(double) green/MaxRGB;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t M a g e n t a %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetMagenta() sets the normalized magenta color of the pixel wand.
+%
+% The format of the PixelSetMagenta method is:
+%
+% unsigned int PixelSetMagenta(PixelWand *wand,const double magenta)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o magenta: The magenta color.
+%
+*/
+WandExport void PixelSetMagenta(PixelWand *wand,const double magenta)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (magenta > 1.0)
+ wand->pixel.green=1.0;
+ else
+ if (magenta < 0.0)
+ wand->pixel.green=0.0;
+ else
+ wand->pixel.green=magenta;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t M a g e n t a Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetMagentaQuantum() sets the magenta color of the pixel wand. The
+% color must be in the range of [0..MaxRGB]
+%
+% The format of the PixelSetMagentaQuantum method is:
+%
+% unsigned int PixelSetMagentaQuantum(PixelWand *wand,
+% const Quantum magenta)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o magenta: The magenta color.
+%
+*/
+WandExport void PixelSetMagentaQuantum(PixelWand *wand,const Quantum magenta)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->pixel.green=(double) magenta/MaxRGB;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t O p a c i t y %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetOpacity() sets the normalized opacity color of the pixel wand.
+%
+% The format of the PixelSetOpacity method is:
+%
+% unsigned int PixelSetOpacity(PixelWand *wand,const double opacity)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o opacity: The opacity value.
+%
+*/
+WandExport void PixelSetOpacity(PixelWand *wand,const double opacity)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (opacity > 1.0)
+ wand->pixel.opacity=1.0;
+ else
+ if (opacity < 0.0)
+ wand->pixel.opacity=0.0;
+ else
+ wand->pixel.opacity=opacity;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t O p a c i t y Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetOpacityQuantum() sets the opacity color of the pixel wand. The
+% color must be in the range of [0..MaxRGB]
+%
+% The format of the PixelSetOpacityQuantum method is:
+%
+% unsigned int PixelSetOpacityQuantum(PixelWand *wand,
+% const Quantum opacity)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o opacity: The opacity value.
+%
+*/
+WandExport void PixelSetOpacityQuantum(PixelWand *wand,const Quantum opacity)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->pixel.opacity=(double) opacity/MaxRGB;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t Q u a n t u m C o l o r %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetQuantumColor() sets the color of the pixel wand.
+%
+% The format of the PixelSetQuantumColor method is:
+%
+% PixelSetQuantumColor(PixelWand *wand,PixelPacket *color)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o color: The pixel wand color (expressed as a PixelPacket).
+%
+*/
+/* FIXME: color argument should be const! */
+WandExport void PixelSetQuantumColor(PixelWand *wand,PixelPacket *color)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ assert(color != (PixelPacket *) NULL);
+ wand->pixel.red=(double) color->red/MaxRGB;
+ wand->pixel.green=(double) color->green/MaxRGB;
+ wand->pixel.blue=(double) color->blue/MaxRGB;
+ wand->pixel.opacity=(double) color->opacity/MaxRGB;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t R e d %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetRed() sets the normalized red color of the pixel wand.
+%
+% The format of the PixelSetRed method is:
+%
+% unsigned int PixelSetRed(PixelWand *wand,const double red)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o red: The red color.
+%
+*/
+WandExport void PixelSetRed(PixelWand *wand,const double red)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (red > 1.0)
+ wand->pixel.red=1.0;
+ else
+ if (red < 0.0)
+ wand->pixel.red=0.0;
+ else
+ wand->pixel.red=red;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t R e d Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetRedQuantum() sets the red color of the pixel wand. The color must
+% be in the range of [0..MaxRGB]
+%
+% The format of the PixelSetRedQuantum method is:
+%
+% unsigned int PixelSetRedQuantum(PixelWand *wand,const Quantum red)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o red: The red color.
+%
+*/
+WandExport void PixelSetRedQuantum(PixelWand *wand,const Quantum red)
+{
+ assert(wand != (PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->pixel.red=(double) red/MaxRGB;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t Y e l l o w %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetYellow() sets the normalized yellow color of the pixel wand.
+%
+% The format of the PixelSetYellow method is:
+%
+% unsigned int PixelSetYellow(PixelWand *wand,const double yellow)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o yellow: The yellow color.
+%
+*/
+WandExport void PixelSetYellow(PixelWand *wand,const double yellow)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ if (yellow > 1.0)
+ wand->pixel.blue=1.0;
+ else
+ if (yellow < 0.0)
+ wand->pixel.blue=0.0;
+ else
+ wand->pixel.blue=yellow;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% P i x e l S e t Y e l l o w Q u a n t u m %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% PixelSetYellowQuantum() sets the yellow color of the pixel wand. The color
+% must be in the range of [0..MaxRGB]
+%
+% The format of the PixelSetYellowQuantum method is:
+%
+% unsigned int PixelSetYellowQuantum(PixelWand *wand,const Quantum yellow)
+%
+% A description of each parameter follows:
+%
+% o wand: The pixel wand.
+%
+% o yellow: The yellow color.
+%
+*/
+WandExport void PixelSetYellowQuantum(PixelWand *wand,const Quantum yellow)
+{
+ assert(wand != (const PixelWand *) NULL);
+ assert(wand->signature == MagickSignature);
+ wand->pixel.blue=(double) yellow/MaxRGB;
+}
diff --git a/wand/pixel_wand.h b/wand/pixel_wand.h
new file mode 100644
index 0000000..5c4841e
--- /dev/null
+++ b/wand/pixel_wand.h
@@ -0,0 +1,91 @@
+/*
+ Copyright (C) 2003-2009 GraphicsMagick Group
+ Copyright (C) 2003 ImageMagick Studio
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ GraphicsMagick Pixel Wand Methods.
+*/
+#ifndef _MAGICK_PIXEL_WAND_H
+#define _MAGICK_PIXEL_WAND_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "wand/wand_symbols.h"
+
+typedef struct _PixelWand PixelWand;
+
+extern WandExport char
+ *PixelGetColorAsString(const PixelWand *);
+
+extern WandExport double
+ PixelGetBlack(const PixelWand *),
+ PixelGetBlue(const PixelWand *),
+ PixelGetCyan(const PixelWand *),
+ PixelGetGreen(const PixelWand *),
+ PixelGetMagenta(const PixelWand *),
+ PixelGetOpacity(const PixelWand *),
+ PixelGetRed(const PixelWand *),
+ PixelGetYellow(const PixelWand *);
+
+extern WandExport PixelWand
+ *ClonePixelWand(const PixelWand *),
+ **ClonePixelWands(const PixelWand **,const unsigned long),
+ *NewPixelWand(void),
+ **NewPixelWands(const unsigned long);
+
+extern WandExport Quantum
+ PixelGetBlackQuantum(const PixelWand *),
+ PixelGetBlueQuantum(const PixelWand *),
+ PixelGetCyanQuantum(const PixelWand *),
+ PixelGetGreenQuantum(const PixelWand *),
+ PixelGetMagentaQuantum(const PixelWand *),
+ PixelGetOpacityQuantum(const PixelWand *),
+ PixelGetRedQuantum(const PixelWand *),
+ PixelGetYellowQuantum(const PixelWand *);
+
+extern WandExport unsigned int
+ PixelSetColor(PixelWand *,const char *);
+
+extern WandExport unsigned long
+ PixelGetColorCount(const PixelWand *);
+
+extern WandExport void
+ DestroyPixelWand(PixelWand *),
+ PixelGetQuantumColor(const PixelWand *,PixelPacket *),
+ PixelSetBlack(PixelWand *,const double),
+ PixelSetBlackQuantum(PixelWand *,const Quantum),
+ PixelSetBlue(PixelWand *,const double),
+ PixelSetBlueQuantum(PixelWand *,const Quantum),
+ PixelSetColorCount(PixelWand *,const unsigned long),
+ PixelSetCyan(PixelWand *,const double),
+ PixelSetCyanQuantum(PixelWand *,const Quantum),
+ PixelSetGreen(PixelWand *,const double),
+ PixelSetGreenQuantum(PixelWand *,const Quantum),
+ PixelSetMagenta(PixelWand *,const double),
+ PixelSetMagentaQuantum(PixelWand *,const Quantum),
+ PixelSetOpacity(PixelWand *,const double),
+ PixelSetOpacityQuantum(PixelWand *,const Quantum),
+ PixelSetQuantumColor(PixelWand *,PixelPacket *),
+ PixelSetRed(PixelWand *,const double),
+ PixelSetRedQuantum(PixelWand *,const Quantum),
+ PixelSetYellow(PixelWand *,const double),
+ PixelSetYellowQuantum(PixelWand *,const Quantum);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/wand/sequence.miff b/wand/sequence.miff
new file mode 100644
index 0000000..165bdd5
--- /dev/null
+++ b/wand/sequence.miff
Binary files differ
diff --git a/wand/wand_api.h b/wand/wand_api.h
new file mode 100644
index 0000000..954ed10
--- /dev/null
+++ b/wand/wand_api.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2003-2009 GraphicsMagick Group
+
+ GraphicsMagick Wand API Methods
+*/
+#ifndef _MAGICK_WAND_API_H
+#define _MAGICK_WAND_API_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <wand/wand_symbols.h>
+#include <magick/api.h>
+
+#if defined(_VISUALC_)
+
+/**
+ * Under VISUALC we have single threaded static libraries, or
+ * mutli-threaded DLLs using the multithreaded runtime DLLs.
+ **/
+# if defined(_MT) && defined(_DLL) && !defined(_LIB)
+# pragma warning( disable: 4273 ) /* Disable the stupid dll linkage warnings */
+# if !defined(_WANDLIB_)
+# define WandExport __declspec(dllimport)
+# else
+# define WandExport __declspec(dllexport)
+# endif
+# else
+# define WandExport
+# endif
+
+# pragma warning(disable : 4018)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4142)
+#else
+# define WandExport
+#endif
+
+#include <wand/drawing_wand.h>
+#include <wand/magick_wand.h>
+#include <wand/pixel_wand.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* defined(__cplusplus) || defined(c_plusplus) */
+
+#endif /* _MAGICK_WAND_API_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/wand/wand_private.h b/wand/wand_private.h
new file mode 100644
index 0000000..b021b6e
--- /dev/null
+++ b/wand/wand_private.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2003-2014 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Private methods and definitions for Wand implementation.
+*/
+
+#ifndef _MAGICK_COMPAT_H
+#define _MAGICK_COMPAT_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+#if defined(MAGICK_IMPLEMENTATION)
+
+#include "wand/wand_symbols.h"
+
+#include "magick/common.h"
+#include "magick/color.h"
+#include "magick/composite.h"
+#include "magick/constitute.h"
+#include "magick/decorate.h"
+#include "magick/effect.h"
+#include "magick/enhance.h"
+#include "magick/fx.h"
+#include "magick/pixel_cache.h"
+#include "magick/shear.h"
+#include "magick/semaphore.h"
+#include "magick/tempfile.h"
+#include "magick/transform.h"
+
+#endif /* defined(MAGICK_IMPLEMENTATION) */
+
+#endif /* _MAGICK_COMPAT_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 2
+ * fill-column: 78
+ * End:
+ */
diff --git a/wand/wand_symbols.h b/wand/wand_symbols.h
new file mode 100644
index 0000000..387292e
--- /dev/null
+++ b/wand/wand_symbols.h
@@ -0,0 +1,415 @@
+/*
+ Copyright (C) 2012-2014 GraphicsMagick Group
+
+ This program is covered by multiple licenses, which are described in
+ Copyright.txt. You should have received a copy of Copyright.txt with this
+ package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+
+ Library symbol name-scoping support.
+
+ Obtained via:
+
+ nm -p wand/.libs/libGraphicsMagickWand.a | grep ' T ' | egrep -vi '(Gm)|(lt_)' | \
+ awk '{ printf("#define %s Gm%s\n", $3, $3); }' | sort > wand/wand_symbols.h
+
+*/
+
+#if !defined(_MAGICK_WAND_SYMBOLS_H)
+#define _MAGICK_WAND_SYMBOLS_H
+
+#if defined(PREFIX_MAGICK_SYMBOLS)
+
+#define CloneMagickWand GmCloneMagickWand
+#define ClonePixelWand GmClonePixelWand
+#define ClonePixelWands GmClonePixelWands
+#define CopyMagickString GmCopyMagickString
+#define DestroyMagickWand GmDestroyMagickWand
+#define DestroyPixelWand GmDestroyPixelWand
+#define FormatMagickString GmFormatMagickString
+#define FormatMagickStringList GmFormatMagickStringList
+#define MagickAdaptiveThresholdImage GmMagickAdaptiveThresholdImage
+#define MagickAddImage GmMagickAddImage
+#define MagickAddNoiseImage GmMagickAddNoiseImage
+#define MagickAffineTransformImage GmMagickAffineTransformImage
+#define MagickAnimateImages GmMagickAnimateImages
+#define MagickAnnotateImage GmMagickAnnotateImage
+#define MagickAppendImages GmMagickAppendImages
+#define MagickAverageImages GmMagickAverageImages
+#define MagickBlackThresholdImage GmMagickBlackThresholdImage
+#define MagickBlurImage GmMagickBlurImage
+#define MagickBorderImage GmMagickBorderImage
+#define MagickCdlImage GmMagickCdlImage
+#define MagickCharcoalImage GmMagickCharcoalImage
+#define MagickChopImage GmMagickChopImage
+#define MagickClipImage GmMagickClipImage
+#define MagickClipPathImage GmMagickClipPathImage
+#define MagickCloneDrawingWand GmMagickCloneDrawingWand
+#define MagickCoalesceImages GmMagickCoalesceImages
+#define MagickColorFloodfillImage GmMagickColorFloodfillImage
+#define MagickColorizeImage GmMagickColorizeImage
+#define MagickCommentImage GmMagickCommentImage
+#define MagickCompareImageChannels GmMagickCompareImageChannels
+#define MagickCompareImages GmMagickCompareImages
+#define MagickCompositeImage GmMagickCompositeImage
+#define MagickContrastImage GmMagickContrastImage
+#define MagickConvolveImage GmMagickConvolveImage
+#define MagickCropImage GmMagickCropImage
+#define MagickCycleColormapImage GmMagickCycleColormapImage
+#define MagickDeconstructImages GmMagickDeconstructImages
+#define MagickDescribeImage GmMagickDescribeImage
+#define MagickDespeckleImage GmMagickDespeckleImage
+#define MagickDestroyDrawingWand GmMagickDestroyDrawingWand
+#define MagickDisplayImage GmMagickDisplayImage
+#define MagickDisplayImages GmMagickDisplayImages
+#define MagickDrawAffine GmMagickDrawAffine
+#define MagickDrawAllocateWand GmMagickDrawAllocateWand
+#define MagickDrawAnnotation GmMagickDrawAnnotation
+#define MagickDrawArc GmMagickDrawArc
+#define MagickDrawBezier GmMagickDrawBezier
+#define MagickDrawCircle GmMagickDrawCircle
+#define MagickDrawClearException GmMagickDrawClearException
+#define MagickDrawColor GmMagickDrawColor
+#define MagickDrawComment GmMagickDrawComment
+#define MagickDrawComposite GmMagickDrawComposite
+#define MagickDrawEllipse GmMagickDrawEllipse
+#define MagickDrawGetClipPath GmMagickDrawGetClipPath
+#define MagickDrawGetClipRule GmMagickDrawGetClipRule
+#define MagickDrawGetClipUnits GmMagickDrawGetClipUnits
+#define MagickDrawGetException GmMagickDrawGetException
+#define MagickDrawGetFillColor GmMagickDrawGetFillColor
+#define MagickDrawGetFillOpacity GmMagickDrawGetFillOpacity
+#define MagickDrawGetFillRule GmMagickDrawGetFillRule
+#define MagickDrawGetFontFamily GmMagickDrawGetFontFamily
+#define MagickDrawGetFont GmMagickDrawGetFont
+#define MagickDrawGetFontSize GmMagickDrawGetFontSize
+#define MagickDrawGetFontStretch GmMagickDrawGetFontStretch
+#define MagickDrawGetFontStyle GmMagickDrawGetFontStyle
+#define MagickDrawGetFontWeight GmMagickDrawGetFontWeight
+#define MagickDrawGetGravity GmMagickDrawGetGravity
+#define MagickDrawGetStrokeAntialias GmMagickDrawGetStrokeAntialias
+#define MagickDrawGetStrokeColor GmMagickDrawGetStrokeColor
+#define MagickDrawGetStrokeDashArray GmMagickDrawGetStrokeDashArray
+#define MagickDrawGetStrokeDashOffset GmMagickDrawGetStrokeDashOffset
+#define MagickDrawGetStrokeLineCap GmMagickDrawGetStrokeLineCap
+#define MagickDrawGetStrokeLineJoin GmMagickDrawGetStrokeLineJoin
+#define MagickDrawGetStrokeMiterLimit GmMagickDrawGetStrokeMiterLimit
+#define MagickDrawGetStrokeOpacity GmMagickDrawGetStrokeOpacity
+#define MagickDrawGetStrokeWidth GmMagickDrawGetStrokeWidth
+#define MagickDrawGetTextAntialias GmMagickDrawGetTextAntialias
+#define MagickDrawGetTextDecoration GmMagickDrawGetTextDecoration
+#define MagickDrawGetTextEncoding GmMagickDrawGetTextEncoding
+#define MagickDrawGetTextUnderColor GmMagickDrawGetTextUnderColor
+#define MagickDrawImage GmMagickDrawImage
+#define MagickDrawLine GmMagickDrawLine
+#define MagickDrawMatte GmMagickDrawMatte
+#define MagickDrawPathClose GmMagickDrawPathClose
+#define MagickDrawPathCurveToAbsolute GmMagickDrawPathCurveToAbsolute
+#define MagickDrawPathCurveToQuadraticBezierAbsolute GmMagickDrawPathCurveToQuadraticBezierAbsolute
+#define MagickDrawPathCurveToQuadraticBezierRelative GmMagickDrawPathCurveToQuadraticBezierRelative
+#define MagickDrawPathCurveToQuadraticBezierSmoothAbsolute GmMagickDrawPathCurveToQuadraticBezierSmoothAbsolute
+#define MagickDrawPathCurveToQuadraticBezierSmoothRelative GmMagickDrawPathCurveToQuadraticBezierSmoothRelative
+#define MagickDrawPathCurveToRelative GmMagickDrawPathCurveToRelative
+#define MagickDrawPathCurveToSmoothAbsolute GmMagickDrawPathCurveToSmoothAbsolute
+#define MagickDrawPathCurveToSmoothRelative GmMagickDrawPathCurveToSmoothRelative
+#define MagickDrawPathEllipticArcAbsolute GmMagickDrawPathEllipticArcAbsolute
+#define MagickDrawPathEllipticArcRelative GmMagickDrawPathEllipticArcRelative
+#define MagickDrawPathFinish GmMagickDrawPathFinish
+#define MagickDrawPathLineToAbsolute GmMagickDrawPathLineToAbsolute
+#define MagickDrawPathLineToHorizontalAbsolute GmMagickDrawPathLineToHorizontalAbsolute
+#define MagickDrawPathLineToHorizontalRelative GmMagickDrawPathLineToHorizontalRelative
+#define MagickDrawPathLineToRelative GmMagickDrawPathLineToRelative
+#define MagickDrawPathLineToVerticalAbsolute GmMagickDrawPathLineToVerticalAbsolute
+#define MagickDrawPathLineToVerticalRelative GmMagickDrawPathLineToVerticalRelative
+#define MagickDrawPathMoveToAbsolute GmMagickDrawPathMoveToAbsolute
+#define MagickDrawPathMoveToRelative GmMagickDrawPathMoveToRelative
+#define MagickDrawPathStart GmMagickDrawPathStart
+#define MagickDrawPeekGraphicContext GmMagickDrawPeekGraphicContext
+#define MagickDrawPoint GmMagickDrawPoint
+#define MagickDrawPolygon GmMagickDrawPolygon
+#define MagickDrawPolyline GmMagickDrawPolyline
+#define MagickDrawPopClipPath GmMagickDrawPopClipPath
+#define MagickDrawPopDefs GmMagickDrawPopDefs
+#define MagickDrawPopGraphicContext GmMagickDrawPopGraphicContext
+#define MagickDrawPopPattern GmMagickDrawPopPattern
+#define MagickDrawPushClipPath GmMagickDrawPushClipPath
+#define MagickDrawPushDefs GmMagickDrawPushDefs
+#define MagickDrawPushGraphicContext GmMagickDrawPushGraphicContext
+#define MagickDrawPushPattern GmMagickDrawPushPattern
+#define MagickDrawRectangle GmMagickDrawRectangle
+#define MagickDrawRender GmMagickDrawRender
+#define MagickDrawRotate GmMagickDrawRotate
+#define MagickDrawRoundRectangle GmMagickDrawRoundRectangle
+#define MagickDrawScale GmMagickDrawScale
+#define MagickDrawSetClipPath GmMagickDrawSetClipPath
+#define MagickDrawSetClipRule GmMagickDrawSetClipRule
+#define MagickDrawSetClipUnits GmMagickDrawSetClipUnits
+#define MagickDrawSetFillColor GmMagickDrawSetFillColor
+#define MagickDrawSetFillOpacity GmMagickDrawSetFillOpacity
+#define MagickDrawSetFillPatternURL GmMagickDrawSetFillPatternURL
+#define MagickDrawSetFillRule GmMagickDrawSetFillRule
+#define MagickDrawSetFontFamily GmMagickDrawSetFontFamily
+#define MagickDrawSetFont GmMagickDrawSetFont
+#define MagickDrawSetFontSize GmMagickDrawSetFontSize
+#define MagickDrawSetFontStretch GmMagickDrawSetFontStretch
+#define MagickDrawSetFontStyle GmMagickDrawSetFontStyle
+#define MagickDrawSetFontWeight GmMagickDrawSetFontWeight
+#define MagickDrawSetGravity GmMagickDrawSetGravity
+#define MagickDrawSetStrokeAntialias GmMagickDrawSetStrokeAntialias
+#define MagickDrawSetStrokeColor GmMagickDrawSetStrokeColor
+#define MagickDrawSetStrokeDashArray GmMagickDrawSetStrokeDashArray
+#define MagickDrawSetStrokeDashOffset GmMagickDrawSetStrokeDashOffset
+#define MagickDrawSetStrokeLineCap GmMagickDrawSetStrokeLineCap
+#define MagickDrawSetStrokeLineJoin GmMagickDrawSetStrokeLineJoin
+#define MagickDrawSetStrokeMiterLimit GmMagickDrawSetStrokeMiterLimit
+#define MagickDrawSetStrokeOpacity GmMagickDrawSetStrokeOpacity
+#define MagickDrawSetStrokePatternURL GmMagickDrawSetStrokePatternURL
+#define MagickDrawSetStrokeWidth GmMagickDrawSetStrokeWidth
+#define MagickDrawSetTextAntialias GmMagickDrawSetTextAntialias
+#define MagickDrawSetTextDecoration GmMagickDrawSetTextDecoration
+#define MagickDrawSetTextEncoding GmMagickDrawSetTextEncoding
+#define MagickDrawSetTextUnderColor GmMagickDrawSetTextUnderColor
+#define MagickDrawSetViewbox GmMagickDrawSetViewbox
+#define MagickDrawSkewX GmMagickDrawSkewX
+#define MagickDrawSkewY GmMagickDrawSkewY
+#define MagickDrawTranslate GmMagickDrawTranslate
+#define MagickEdgeImage GmMagickEdgeImage
+#define MagickEmbossImage GmMagickEmbossImage
+#define MagickEnhanceImage GmMagickEnhanceImage
+#define MagickEqualizeImage GmMagickEqualizeImage
+#define MagickExtentImage GmMagickExtentImage
+#define MagickFlattenImages GmMagickFlattenImages
+#define MagickFlipImage GmMagickFlipImage
+#define MagickFlopImage GmMagickFlopImage
+#define MagickFrameImage GmMagickFrameImage
+#define MagickFxImageChannel GmMagickFxImageChannel
+#define MagickFxImage GmMagickFxImage
+#define MagickGammaImageChannel GmMagickGammaImageChannel
+#define MagickGammaImage GmMagickGammaImage
+#define MagickGetConfigureInfo GmMagickGetConfigureInfo
+#define MagickGetCopyright GmMagickGetCopyright
+#define MagickGetException GmMagickGetException
+#define MagickGetFilename GmMagickGetFilename
+#define MagickGetHomeURL GmMagickGetHomeURL
+#define MagickGetImageAttribute GmMagickGetImageAttribute
+#define MagickGetImageBackgroundColor GmMagickGetImageBackgroundColor
+#define MagickGetImageBluePrimary GmMagickGetImageBluePrimary
+#define MagickGetImageBorderColor GmMagickGetImageBorderColor
+#define MagickGetImageBoundingBox GmMagickGetImageBoundingBox
+#define MagickGetImageChannelDepth GmMagickGetImageChannelDepth
+#define MagickGetImageChannelExtrema GmMagickGetImageChannelExtrema
+#define MagickGetImageChannelMean GmMagickGetImageChannelMean
+#define MagickGetImageColormapColor GmMagickGetImageColormapColor
+#define MagickGetImageColors GmMagickGetImageColors
+#define MagickGetImageColorspace GmMagickGetImageColorspace
+#define MagickGetImageCompose GmMagickGetImageCompose
+#define MagickGetImageCompression GmMagickGetImageCompression
+#define MagickGetImageDelay GmMagickGetImageDelay
+#define MagickGetImageDepth GmMagickGetImageDepth
+#define MagickGetImageDispose GmMagickGetImageDispose
+#define MagickGetImageExtrema GmMagickGetImageExtrema
+#define MagickGetImageFilename GmMagickGetImageFilename
+#define MagickGetImageFormat GmMagickGetImageFormat
+#define MagickGetImageFuzz GmMagickGetImageFuzz
+#define MagickGetImageGamma GmMagickGetImageGamma
+#define MagickGetImageGeometry GmMagickGetImageGeometry
+#define MagickGetImageGravity GmMagickGetImageGravity
+#define MagickGetImage GmMagickGetImage
+#define MagickGetImageGreenPrimary GmMagickGetImageGreenPrimary
+#define MagickGetImageHeight GmMagickGetImageHeight
+#define MagickGetImageHistogram GmMagickGetImageHistogram
+#define MagickGetImageIndex GmMagickGetImageIndex
+#define MagickGetImageInterlaceScheme GmMagickGetImageInterlaceScheme
+#define MagickGetImageIterations GmMagickGetImageIterations
+#define MagickGetImageMatte GmMagickGetImageMatte
+#define MagickGetImageMatteColor GmMagickGetImageMatteColor
+#define MagickGetImagePage GmMagickGetImagePage
+#define MagickGetImagePixels GmMagickGetImagePixels
+#define MagickGetImageProfile GmMagickGetImageProfile
+#define MagickGetImageRedPrimary GmMagickGetImageRedPrimary
+#define MagickGetImageRenderingIntent GmMagickGetImageRenderingIntent
+#define MagickGetImageResolution GmMagickGetImageResolution
+#define MagickGetImageSavedType GmMagickGetImageSavedType
+#define MagickGetImageScene GmMagickGetImageScene
+#define MagickGetImageSignature GmMagickGetImageSignature
+#define MagickGetImageSize GmMagickGetImageSize
+#define MagickGetImageType GmMagickGetImageType
+#define MagickGetImageUnits GmMagickGetImageUnits
+#define MagickGetImageVirtualPixelMethod GmMagickGetImageVirtualPixelMethod
+#define MagickGetImageWhitePoint GmMagickGetImageWhitePoint
+#define MagickGetImageWidth GmMagickGetImageWidth
+#define MagickGetNumberImages GmMagickGetNumberImages
+#define MagickGetPackageName GmMagickGetPackageName
+#define MagickGetQuantumDepth GmMagickGetQuantumDepth
+#define MagickGetReleaseDate GmMagickGetReleaseDate
+#define MagickGetResourceLimit GmMagickGetResourceLimit
+#define MagickGetSamplingFactors GmMagickGetSamplingFactors
+#define MagickGetSize GmMagickGetSize
+#define MagickGetVersion GmMagickGetVersion
+#define MagickHaldClutImage GmMagickHaldClutImage
+#define MagickHasNextImage GmMagickHasNextImage
+#define MagickHasPreviousImage GmMagickHasPreviousImage
+#define MagickImplodeImage GmMagickImplodeImage
+#define MagickLabelImage GmMagickLabelImage
+#define MagickLevelImageChannel GmMagickLevelImageChannel
+#define MagickLevelImage GmMagickLevelImage
+#define MagickMagnifyImage GmMagickMagnifyImage
+#define MagickMapImage GmMagickMapImage
+#define MagickMatteFloodfillImage GmMagickMatteFloodfillImage
+#define MagickMedianFilterImage GmMagickMedianFilterImage
+#define MagickMinifyImage GmMagickMinifyImage
+#define MagickModulateImage GmMagickModulateImage
+#define MagickMontageImage GmMagickMontageImage
+#define MagickMorphImages GmMagickMorphImages
+#define MagickMosaicImages GmMagickMosaicImages
+#define MagickMotionBlurImage GmMagickMotionBlurImage
+#define MagickNegateImageChannel GmMagickNegateImageChannel
+#define MagickNegateImage GmMagickNegateImage
+#define MagickNewDrawingWand GmMagickNewDrawingWand
+#define MagickNextImage GmMagickNextImage
+#define MagickNormalizeImage GmMagickNormalizeImage
+#define MagickOilPaintImage GmMagickOilPaintImage
+#define MagickOpaqueImage GmMagickOpaqueImage
+#define MagickPingImage GmMagickPingImage
+#define MagickPreviewImages GmMagickPreviewImages
+#define MagickPreviousImage GmMagickPreviousImage
+#define MagickProfileImage GmMagickProfileImage
+#define MagickQuantizeImage GmMagickQuantizeImage
+#define MagickQuantizeImages GmMagickQuantizeImages
+#define MagickQueryFontMetrics GmMagickQueryFontMetrics
+#define MagickQueryFonts GmMagickQueryFonts
+#define MagickQueryFormats GmMagickQueryFormats
+#define MagickRadialBlurImage GmMagickRadialBlurImage
+#define MagickRaiseImage GmMagickRaiseImage
+#define MagickReadImageBlob GmMagickReadImageBlob
+#define MagickReadImageFile GmMagickReadImageFile
+#define MagickReadImage GmMagickReadImage
+#define MagickReduceNoiseImage GmMagickReduceNoiseImage
+#define MagickRelinquishMemory GmMagickRelinquishMemory
+#define MagickRemoveImage GmMagickRemoveImage
+#define MagickRemoveImageProfile GmMagickRemoveImageProfile
+#define MagickResampleImage GmMagickResampleImage
+#define MagickResetIterator GmMagickResetIterator
+#define MagickResizeImage GmMagickResizeImage
+#define MagickRollImage GmMagickRollImage
+#define MagickRotateImage GmMagickRotateImage
+#define MagickSampleImage GmMagickSampleImage
+#define MagickScaleImage GmMagickScaleImage
+#define MagickSeparateImageChannel GmMagickSeparateImageChannel
+#define MagickSetCompressionQuality GmMagickSetCompressionQuality
+#define MagickSetDepth GmMagickSetDepth
+#define MagickSetFilename GmMagickSetFilename
+#define MagickSetFormat GmMagickSetFormat
+#define MagickSetImageAttribute GmMagickSetImageAttribute
+#define MagickSetImageBackgroundColor GmMagickSetImageBackgroundColor
+#define MagickSetImageBluePrimary GmMagickSetImageBluePrimary
+#define MagickSetImageBorderColor GmMagickSetImageBorderColor
+#define MagickSetImageChannelDepth GmMagickSetImageChannelDepth
+#define MagickSetImageColormapColor GmMagickSetImageColormapColor
+#define MagickSetImageColorspace GmMagickSetImageColorspace
+#define MagickSetImageCompose GmMagickSetImageCompose
+#define MagickSetImageCompression GmMagickSetImageCompression
+#define MagickSetImageDelay GmMagickSetImageDelay
+#define MagickSetImageDepth GmMagickSetImageDepth
+#define MagickSetImageDispose GmMagickSetImageDispose
+#define MagickSetImageFilename GmMagickSetImageFilename
+#define MagickSetImageFormat GmMagickSetImageFormat
+#define MagickSetImageFuzz GmMagickSetImageFuzz
+#define MagickSetImageGamma GmMagickSetImageGamma
+#define MagickSetImageGravity GmMagickSetImageGravity
+#define MagickSetImage GmMagickSetImage
+#define MagickSetImageGreenPrimary GmMagickSetImageGreenPrimary
+#define MagickSetImageIndex GmMagickSetImageIndex
+#define MagickSetImageInterlaceScheme GmMagickSetImageInterlaceScheme
+#define MagickSetImageIterations GmMagickSetImageIterations
+#define MagickSetImageMatte GmMagickSetImageMatte
+#define MagickSetImageMatteColor GmMagickSetImageMatteColor
+#define MagickSetImageOption GmMagickSetImageOption
+#define MagickSetImagePage GmMagickSetImagePage
+#define MagickSetImagePixels GmMagickSetImagePixels
+#define MagickSetImageProfile GmMagickSetImageProfile
+#define MagickSetImageRedPrimary GmMagickSetImageRedPrimary
+#define MagickSetImageRenderingIntent GmMagickSetImageRenderingIntent
+#define MagickSetImageResolution GmMagickSetImageResolution
+#define MagickSetImageSavedType GmMagickSetImageSavedType
+#define MagickSetImageScene GmMagickSetImageScene
+#define MagickSetImageType GmMagickSetImageType
+#define MagickSetImageUnits GmMagickSetImageUnits
+#define MagickSetImageVirtualPixelMethod GmMagickSetImageVirtualPixelMethod
+#define MagickSetImageWhitePoint GmMagickSetImageWhitePoint
+#define MagickSetInterlaceScheme GmMagickSetInterlaceScheme
+#define MagickSetPassphrase GmMagickSetPassphrase
+#define MagickSetResolution GmMagickSetResolution
+#define MagickSetResolutionUnits GmMagickSetResolutionUnits
+#define MagickSetResourceLimit GmMagickSetResourceLimit
+#define MagickSetSamplingFactors GmMagickSetSamplingFactors
+#define MagickSetSize GmMagickSetSize
+#define MagickSharpenImage GmMagickSharpenImage
+#define MagickShaveImage GmMagickShaveImage
+#define MagickShearImage GmMagickShearImage
+#define MagickSolarizeImage GmMagickSolarizeImage
+#define MagickSpreadImage GmMagickSpreadImage
+#define MagickSteganoImage GmMagickSteganoImage
+#define MagickStereoImage GmMagickStereoImage
+#define MagickStripImage GmMagickStripImage
+#define MagickSwirlImage GmMagickSwirlImage
+#define MagickTextureImage GmMagickTextureImage
+#define MagickThresholdImageChannel GmMagickThresholdImageChannel
+#define MagickThresholdImage GmMagickThresholdImage
+#define MagickTintImage GmMagickTintImage
+#define MagickTransformImage GmMagickTransformImage
+#define MagickTransparentImage GmMagickTransparentImage
+#define MagickTrimImage GmMagickTrimImage
+#define MagickUnsharpMaskImage GmMagickUnsharpMaskImage
+#define MagickWaveImage GmMagickWaveImage
+#define MagickWhiteThresholdImage GmMagickWhiteThresholdImage
+#define MagickWriteImageBlob GmMagickWriteImageBlob
+#define MagickWriteImageFile GmMagickWriteImageFile
+#define MagickWriteImage GmMagickWriteImage
+#define MagickWriteImagesFile GmMagickWriteImagesFile
+#define MagickWriteImages GmMagickWriteImages
+#define NewMagickWand GmNewMagickWand
+#define NewPixelWand GmNewPixelWand
+#define NewPixelWands GmNewPixelWands
+#define PixelGetBlack GmPixelGetBlack
+#define PixelGetBlackQuantum GmPixelGetBlackQuantum
+#define PixelGetBlue GmPixelGetBlue
+#define PixelGetBlueQuantum GmPixelGetBlueQuantum
+#define PixelGetColorAsString GmPixelGetColorAsString
+#define PixelGetColorCount GmPixelGetColorCount
+#define PixelGetCyan GmPixelGetCyan
+#define PixelGetCyanQuantum GmPixelGetCyanQuantum
+#define PixelGetException GmPixelGetException
+#define PixelGetGreen GmPixelGetGreen
+#define PixelGetGreenQuantum GmPixelGetGreenQuantum
+#define PixelGetMagenta GmPixelGetMagenta
+#define PixelGetMagentaQuantum GmPixelGetMagentaQuantum
+#define PixelGetOpacity GmPixelGetOpacity
+#define PixelGetOpacityQuantum GmPixelGetOpacityQuantum
+#define PixelGetQuantumColor GmPixelGetQuantumColor
+#define PixelGetRed GmPixelGetRed
+#define PixelGetRedQuantum GmPixelGetRedQuantum
+#define PixelGetYellow GmPixelGetYellow
+#define PixelGetYellowQuantum GmPixelGetYellowQuantum
+#define PixelSetBlack GmPixelSetBlack
+#define PixelSetBlackQuantum GmPixelSetBlackQuantum
+#define PixelSetBlue GmPixelSetBlue
+#define PixelSetBlueQuantum GmPixelSetBlueQuantum
+#define PixelSetColorCount GmPixelSetColorCount
+#define PixelSetColor GmPixelSetColor
+#define PixelSetCyan GmPixelSetCyan
+#define PixelSetCyanQuantum GmPixelSetCyanQuantum
+#define PixelSetGreen GmPixelSetGreen
+#define PixelSetGreenQuantum GmPixelSetGreenQuantum
+#define PixelSetMagenta GmPixelSetMagenta
+#define PixelSetMagentaQuantum GmPixelSetMagentaQuantum
+#define PixelSetOpacity GmPixelSetOpacity
+#define PixelSetOpacityQuantum GmPixelSetOpacityQuantum
+#define PixelSetQuantumColor GmPixelSetQuantumColor
+#define PixelSetRed GmPixelSetRed
+#define PixelSetRedQuantum GmPixelSetRedQuantum
+#define PixelSetYellow GmPixelSetYellow
+#define PixelSetYellowQuantum GmPixelSetYellowQuantum
+#define QueryMagickColor GmQueryMagickColor
+
+#endif /* defined(PREFIX_MAGICK_SYMBOLS) */
+#endif /* defined(_MAGICK_WAND_SYMBOLS_H) */
diff --git a/wand/wandtest.c b/wand/wandtest.c
new file mode 100644
index 0000000..105cf18
--- /dev/null
+++ b/wand/wandtest.c
@@ -0,0 +1,267 @@
+/* Copyright (C) 2003-2010 GraphicsMagick Group */
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M M AAA GGGG IIIII CCCC K K %
+% MM MM A A G I C K K %
+% M M M AAAAA G GGG I C KKK %
+% M M A A G G I C K K %
+% M M A A GGGG IIIII CCCC K K %
+% %
+% W W AAA N N DDDD %
+% W W A A NN N D D %
+% W W W AAAAA N N N D D %
+% WW WW A A N NN D D %
+% W W A A N N DDDD %
+% %
+% ImageMagick MagickWand Validation Tests %
+% %
+% %
+% Software Design %
+% John Cristy %
+% March 2003 %
+% %
+% %
+% Copyright (C) 1999-2004 ImageMagick Studio, a non-profit organization %
+% dedicated to making software imaging solutions freely available. %
+% %
+% This software and documentation is provided "as is," and the copyright %
+% holders and contributing author(s) make no representations or warranties, %
+% express or implied, including but not limited to, warranties of %
+% merchantability or fitness for any particular purpose or that the use of %
+% the software or documentation will not infringe any third party patents, %
+% copyrights, trademarks or other rights. %
+% %
+% The copyright holders and contributing author(s) will not be held liable %
+% for any direct, indirect, special or consequential damages arising out of %
+% any use of the software or documentation, even if advised of the %
+% possibility of such damage. %
+% %
+% Permission is hereby granted to use, copy, modify, and distribute this %
+% source code, or portions hereof, documentation and executables, for any %
+% purpose, without fee, subject to the following restrictions: %
+% %
+% 1. The origin of this source code must not be misrepresented. %
+% 2. Altered versions must be plainly marked as such and must not be %
+% misrepresented as being the original source. %
+% 3. This Copyright notice may not be removed or altered from any source %
+% or altered source distribution. %
+% %
+% The copyright holders and contributing author(s) specifically permit, %
+% without fee, and encourage the use of this source code as a component for %
+% supporting image processing in commercial products. If you use this %
+% source code in a product, acknowledgment is not required but would be %
+% appreciated. %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%
+*/
+
+/*
+ * This version is modified by Bob Friesenhahn so that it may be executed
+ * from outside the source directory.
+ *
+ */
+
+
+/*
+ Include declarations.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <wand/magick_wand.h>
+
+#define False 0
+#define True 1
+
+#define ThrowAPIException(wand) \
+{ \
+ description=MagickGetException(wand,&severity); \
+ (void) fprintf(stderr,"%s %s %d %.1024s\n",GetMagickModule(),description); \
+ free(description); \
+ exit(-1); \
+}
+
+int main(int argc,char **argv)
+{
+ char
+ *description;
+
+ DrawingWand
+ *drawing_wand;
+
+ ExceptionType
+ severity;
+
+ MagickWand
+ *clone_wand,
+ *magick_wand;
+
+ PixelWand
+ *background,
+ *fill;
+
+ register long
+ i;
+
+ unsigned int
+ status;
+
+ unsigned long
+ columns,
+ rows;
+
+ (void) argc;
+
+ InitializeMagick(*argv);
+ magick_wand=NewMagickWand();
+ MagickSetSize(magick_wand,640,480);
+ MagickGetSize(magick_wand,&columns,&rows);
+ if ((columns != 640) || (rows != 480))
+ {
+ (void) fprintf(stderr,"Unexpected magick wand size\n");
+ exit(1);
+ }
+ (void) fprintf(stdout,"Reading images...\n");
+ {
+ char
+ *p,
+ path[MaxTextExtent];
+
+ path[0]=0;
+ p=getenv("SRCDIR");
+ if (p)
+ {
+ strcpy(path,p);
+ if (path[strlen(path)-1] != '/')
+ strcat(path,"/");
+ }
+ strcat(path,"sequence.miff");
+
+ status=MagickReadImage(magick_wand,path);
+ }
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ if (MagickGetNumberImages(magick_wand) != 5)
+ (void) fprintf(stderr,"read %lu images; expected 5\n",
+ (unsigned long) MagickGetNumberImages(magick_wand));
+ (void) fprintf(stdout,"Iterate forward...\n");
+ MagickResetIterator(magick_wand);
+ while (MagickNextImage(magick_wand) != False)
+ (void) fprintf(stdout,"index %ld scene %ld\n",
+ MagickGetImageIndex(magick_wand),MagickGetImageScene(magick_wand));
+ (void) fprintf(stdout,"Iterate reverse...\n");
+ while (MagickPreviousImage(magick_wand) != False)
+ (void) fprintf(stdout,"index %ld scene %ld\n",
+ MagickGetImageIndex(magick_wand),MagickGetImageScene(magick_wand));
+ (void) fprintf(stdout,"Remove scene 1...\n");
+ (void) MagickSetImageIndex(magick_wand,1);
+ clone_wand=MagickGetImage(magick_wand);
+ status=MagickRemoveImage(magick_wand);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ MagickResetIterator(magick_wand);
+ while (MagickNextImage(magick_wand) != False)
+ (void) fprintf(stdout,"index %ld scene %ld\n",
+ MagickGetImageIndex(magick_wand),MagickGetImageScene(magick_wand));
+ (void) fprintf(stdout,"Insert scene 1 back in sequence...\n");
+ (void) MagickSetImageIndex(magick_wand,0);
+ status=MagickAddImage(magick_wand,clone_wand);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ MagickResetIterator(magick_wand);
+ while (MagickNextImage(magick_wand) != False)
+ (void) fprintf(stdout,"index %ld scene %ld\n",
+ MagickGetImageIndex(magick_wand),MagickGetImageScene(magick_wand));
+ (void) fprintf(stdout,"Set scene 2 to scene 1...\n");
+ (void) MagickSetImageIndex(magick_wand,2);
+ status=MagickSetImage(magick_wand,clone_wand);
+ DestroyMagickWand(clone_wand);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ MagickResetIterator(magick_wand);
+ while (MagickNextImage(magick_wand) != False)
+ (void) fprintf(stdout,"index %ld scene %ld\n",
+ MagickGetImageIndex(magick_wand),MagickGetImageScene(magick_wand));
+ (void) fprintf(stdout,"Apply image processing options...\n");
+ status=MagickCropImage(magick_wand,60,60,10,10);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ MagickResetIterator(magick_wand);
+ background=NewPixelWand();
+ PixelSetColor(background,"#000000");
+ status=MagickRotateImage(magick_wand,background,90.0);
+ DestroyPixelWand(background);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ drawing_wand=NewDrawingWand();
+ (void) DrawPushGraphicContext(drawing_wand);
+ (void) DrawRotate(drawing_wand,45);
+ (void) DrawSetFontSize(drawing_wand,18);
+ fill=NewPixelWand();
+ PixelSetColor(fill,"green");
+ (void) DrawSetFillColor(drawing_wand,fill);
+ DestroyPixelWand(fill);
+ (void) DrawAnnotation(drawing_wand,15,5,(const unsigned char *) "Magick");
+ (void) DrawPopGraphicContext(drawing_wand);
+ (void) MagickSetImageIndex(magick_wand,1);
+ status=MagickDrawImage(magick_wand,drawing_wand);
+ DestroyDrawingWand(drawing_wand);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ {
+ unsigned char
+ pixels[27],
+ primary_colors[27] =
+ {
+ 0, 0, 0,
+ 0, 0, 255,
+ 0, 255, 0,
+ 0, 255, 255,
+ 255, 255, 255,
+ 255, 0, 0,
+ 255, 0, 255,
+ 255, 255, 0,
+ 128, 128, 128,
+ };
+
+ (void) MagickSetImageIndex(magick_wand,2);
+ status=MagickSetImagePixels(magick_wand,10,10,3,3,"RGB",CharPixel,
+ primary_colors);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ status=MagickGetImagePixels(magick_wand,10,10,3,3,"RGB",CharPixel,pixels);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ for (i=0; i < 9; i++)
+ if (pixels[i] != primary_colors[i])
+ {
+ (void) fprintf(stderr,"Get pixels does not match set pixels\n");
+ exit(1);
+ }
+ }
+ (void) MagickSetImageIndex(magick_wand,3);
+ status=MagickResizeImage(magick_wand,50,50,UndefinedFilter,1.0);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+
+ MagickResetIterator(magick_wand);
+ while (MagickNextImage(magick_wand) != False)
+ {
+ MagickSetImageDepth( magick_wand, 8);
+ MagickSetImageCompression( magick_wand, RLECompression);
+ }
+ MagickResetIterator(magick_wand);
+
+ (void) fprintf(stdout,"Write to wandtest_out.miff...\n");
+ status=MagickWriteImages(magick_wand,"wandtest_out.miff",True);
+ if (status == False)
+ ThrowAPIException(magick_wand);
+ DestroyMagickWand(magick_wand);
+ return(0);
+}
diff --git a/wand/wandtests.tap b/wand/wandtests.tap
new file mode 100755
index 0000000..d522c8c
--- /dev/null
+++ b/wand/wandtests.tap
@@ -0,0 +1,11 @@
+#!/bin/sh
+# Copyright (C) 2004-2013 GraphicsMagick Group
+# Test wand interface
+. ./common.shi
+. ${srcdir}/wand/common.shi
+test_plan_fn 2
+rm -f drawtest_out.miff
+test_command_fn 'wand vector drawing' ${MEMCHECK} ./drawtest drawtest_out.miff
+rm -f wandtest_out.miff
+test_command_fn 'wand api' -F TTF ${MEMCHECK} ./wandtest
+:
diff --git a/winpath.sh b/winpath.sh
new file mode 100755
index 0000000..2d8e353
--- /dev/null
+++ b/winpath.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+# Copyright (C) 2003 GraphicsMagick Group
+#
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Convert the specified POSIX path to a Windows path under MinGW and Cygwin
+# The optional second parameter specifies the level of backslash escaping
+# to apply for each Windows backslash position in order to support varying
+# levels of variable substitutions in scripts.
+#
+# Note that Cygwin includes the 'cygpath' utility, which already provides
+# path translation capability.
+#
+# Written by Bob Friesenhahn <bfriesen@simple.dallas.tx.us> June 2002
+#
+arg="$1"
+escapes=0
+if test -n "$2"
+then
+ escapes="$2"
+fi
+if test $escapes -gt 3
+then
+ echo "$0: escape level must in range 0 - 3"
+ exit 1
+fi
+result=''
+length=0
+max_length=0
+mount | sed -e 's:\\:/:g' | (
+ IFS="\n"
+ while read mount_entry
+ do
+ win_mount_path=`echo "$mount_entry" | sed -e 's: .*::g'`
+ unix_mount_path=`echo "$mount_entry" | sed -e 's:.* on ::;s: type .*::'`
+ temp=`echo "$arg" | sed -e "s!^$unix_mount_path!$win_mount_path!"`
+ if test "$temp" != "$arg"
+ then
+ candidate="$temp"
+ length=${#unix_mount_path}
+ if test $length -gt $max_length
+ then
+ result=$candidate
+ max_length=$length
+ fi
+ fi
+ done
+ if test -z "$result"
+ then
+ echo "$0: path \"$arg\" is not mounted"
+ exit 1
+ fi
+ case $escapes in
+ 0)
+ echo "$result" | sed -e 's:/:\\:g'
+ ;;
+ 1)
+ echo "$result" | sed -e 's:/:\\\\:g'
+ ;;
+ 2)
+ echo "$result" | sed -e 's:/:\\\\\\\\:g'
+ ;;
+ 3)
+ echo "$result" | sed -e 's:/:\\\\\\\\\\\\\\\\:g'
+ ;;
+ esac
+ exit 0;
+ )
diff --git a/www/ChangeLog-2001.html b/www/ChangeLog-2001.html
new file mode 100644
index 0000000..5e55fdc
--- /dev/null
+++ b/www/ChangeLog-2001.html
@@ -0,0 +1,440 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2001-12-28 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Even more features and options were added to conjure</li>
+<li>Added CropBox support to PDF writer</li>
+</ul>
+</blockquote>
+<p>2001-12-26 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Conjure now supports having a list of files for the script to
+process being passed on the command line.</li>
+<li>More features and options were added to conjure</li>
+</ul>
+</blockquote>
+<p>2001-12-25 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Made a huge number of improvements to conjure. It now supports
+over 15 different commands for manipulating your images.</li>
+</ul>
+</blockquote>
+<p>2001-12-24 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Started a new scripting language utility, conjure.</li>
+</ul>
+</blockquote>
+<p>2001-12-20 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Display the search path in the event a utility cannot find a
+particular configuration file (thanks to <a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>)</li>
+</ul>
+</blockquote>
+<p>2001-12-14 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed some bugs in the new composite operators.</li>
+</ul>
+</blockquote>
+<p>2001-12-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added native BLOB support to coders/wmf.c.</li>
+</ul>
+</blockquote>
+<p>2001-12-13 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added new composite operators to support PSD/XCF
+layer compositing: NoCompositeOp, DarkenCompositeOp,
+LightenCompositeOp, HueCompositeOp, SaturateCompositeOp,
+ValueCompositeOp, ColorizeCompositeOp, LuminizeCompositeOp,
+ScreenCompositeOp, OverlayCompositeOp.</li>
+<li>Modified the PSD coder to set the appropriate composite
+operator.</li>
+<li>Modified the XCF coder to set the appropriate composite
+operator.</li>
+</ul>
+</blockquote>
+<p>2001-12-10 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Removed the flatten option from ImageInfo.</li>
+<li>Added new compose member to ImageInfo that defines which of
+the composite operators to use when flattening an image.</li>
+</ul>
+</blockquote>
+<p>2001-12-09 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added new member to ImageInfo, flatten, used by PSD and XCF
+to determine whether to flatten an image when read.</li>
+<li>PSD and XCF now respect image_info-&gt;flatten.</li>
+<li>Fixed bug in XCF loader when loading layered image as layers.</li>
+<li>Modified the convert program to set image_info-&gt;flatten if
+-flatten is specified; we still call FlattenImages for other
+formats that don't respect image_info-&gt;flatten.</li>
+<li>Modified Magick++'s Image class to support image_info-&gt;flatten.</li>
+</ul>
+</blockquote>
+<p>2001-12-08 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Improvements to the Photoshop (PSD) coder: 1) added support
+for Duotone images loaded as grayscale as per PSD docs; and 2)
+added option to composite layers when reading respects layer
+visibility setting.</li>
+</ul>
+</blockquote>
+<p>2001-12-07 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>-dissolve wasn't working for the composite program (thanks to
+Rick Manbry).</li>
+<li>DCM coder failed to read a valid DCM image file.</li>
+</ul>
+</blockquote>
+<p>2001-12-06 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Stream buffer was not being freed in ReadStream().</li>
+</ul>
+</blockquote>
+<p>2001-12-05 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Corrected bias when downsizing an image with ResizeImage().</li>
+</ul>
+</blockquote>
+<p>2001-11-25 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>AcquireImagePixels() can accept (x,y) outside the image area
+(e.g. AcquireImagePixels(image,-3,-3,7,7,exception)).</li>
+</ul>
+</blockquote>
+<p>2001-11-22 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added limited SVG gradient support.</li>
+</ul>
+</blockquote>
+<p>2001-11-21 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added API method, PingBlob().</li>
+</ul>
+</blockquote>
+<p>2001-11-14 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Moved a few pixel related defines (e.g. Downscale()) to
+a corresponding method to enforce strong type checking at
+compile time.</li>
+</ul>
+</blockquote>
+<p>2001-11-12 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Previously ImageMagick did not write 8-bit ASCII PPM/PGM files
+when QuantumDepth == 16.</li>
+<li>Added 'id' as an image attribute in PerlMagick (returns
+ImageMagick registry ID).</li>
+</ul>
+</blockquote>
+<p>2001-11-10 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added SVG pattern support.</li>
+<li>Changed default background color to none.</li>
+</ul>
+</blockquote>
+<p>2001-11-06 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added support of reading and writing 16-bit raw PPM/PGM files.</li>
+</ul>
+</blockquote>
+<p>2001-11-05 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added -level to convert/mogrify (suggested by
+<a class="reference external" href="mailto:mericson&#37;&#52;&#48;phillynews&#46;kom">mericson<span>&#64;</span>phillynews<span>&#46;</span>kom</a>).</li>
+</ul>
+</blockquote>
+<p>2001-11-04 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>-shadow/-shade were not distiguished.</li>
+</ul>
+</blockquote>
+<p>2001-11-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Makefile.PL.in: Install PerlMagick using
+ImageMagick's configure prefix.</li>
+</ul>
+</blockquote>
+<p>2001-11-02 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Typecast offset to unsigned long in coders/pdf.c.</li>
+</ul>
+</blockquote>
+<p>2001-11-01 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Convert's -flatten, -average, etc. failed with an assert error.</li>
+</ul>
+</blockquote>
+<p>2001-10-30 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added support for On-the-air bitmap.</li>
+</ul>
+</blockquote>
+<p>2001-09-29 Glenn &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>When the delay setting for an image is greater than 4cs, duplicate
+frames are inserted to achieve the desired delay while creating MPEG
+files (contributed by Lawrence Livermore National Laboratory (LLNL)).</li>
+</ul>
+</blockquote>
+<p>2001-10-29 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick now has a registry for storing image blobs.</li>
+</ul>
+</blockquote>
+<p>2001-10-26 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added VMS patches (thanks to Jouk Jansen).</li>
+</ul>
+</blockquote>
+<p>2001-10-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed parsing bug for decorate #FFFFFF.</li>
+</ul>
+</blockquote>
+<p>2001-10-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added tests for mpeg2 library to configure.</li>
+</ul>
+</blockquote>
+<p>2001-10-22 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added a MPEG coder module.</li>
+<li>Added ImageType member to the image_info structure (suggested
+by Glenn)</li>
+</ul>
+</blockquote>
+<p>2001-10-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Eliminated libMagick.so dependency on libxml by not listing -lxml
+when doing modules link.</li>
+</ul>
+</blockquote>
+<p>2001-10-18 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Eliminated the libMagick.so dependancy on libtiff by moving
+Huffman2DEncodeImage() from magick/compress.c to coders/pdf.c,
+coders/ps2.c and coders/ps3.c (suggested by Bob Friesenhahn).
+This change has the side-effect of elminating dependency on libpng
+and libjpeg as well (which libtiff may depend on).</li>
+</ul>
+</blockquote>
+<p>2001-10-16 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Convert now supports -channel {Cyan,Magenta,Yellow,Black}.</li>
+</ul>
+</blockquote>
+<p>2001-10-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c updated for libwmf 0.2. Plenty of bugs remain within.</li>
+</ul>
+</blockquote>
+<p>2001-10-11 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>QueryFontMetrics() of PerlMagick now recognizes embedded
+special characters (e.g. %h).</li>
+</ul>
+</blockquote>
+<p>2001-10-10 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed seg-fault for PingImage() on a JP2 image file.</li>
+</ul>
+</blockquote>
+<p>2001-10-07 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>CloneImage() now uses a referenced counted pixel cache.</li>
+</ul>
+</blockquote>
+<p>2001-10-05 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added AcquireImagePixels() method.</li>
+<li>Changed the formal parameter from Image * to const Image *
+for a number of methods (e.g. ZoomImage()).</li>
+<li>Added ExceptionInfo parameter to DispatchImage().</li>
+</ul>
+</blockquote>
+<p>2001-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Find libxml headers under Debian Linux (bug ID 921).</li>
+</ul>
+</blockquote>
+<p>2001-10-02 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed assertion error on drawing stroked text.</li>
+</ul>
+</blockquote>
+<p>2001-10-01 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added blob test to the PerlMagick test suite.</li>
+</ul>
+</blockquote>
+<p>2001-09-30 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>switched strcpy to strncpy to help protect against buffer
+overflow.</li>
+<li>ltdl.c passed int reference but a long was needed; caused a
+fault on Solaris 64-bit compiles.</li>
+</ul>
+</blockquote>
+<p>2001-09-25 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Removed most lint complaints from the source.</li>
+<li>strtod() returns different results on Linux and Solaris for 0x13.</li>
+<li>Added a MATLAB encoder contributed by Jaroslav Fojtik.</li>
+</ul>
+</blockquote>
+<p>2001-09-21 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Replaced TemporaryFilename() with UniqueImageFilename().</li>
+<li>ImageMagick CORE API is now 64-bit clean.</li>
+</ul>
+</blockquote>
+<p>2001-09-20 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed svg.c to accept a viewbox with a negative offset.</li>
+</ul>
+</blockquote>
+<p>2001-09-15 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Surveying the code for 64-bit compatibility.</li>
+<li>The cloned colormap was too small (reported by Glenn).</li>
+<li>A blob was being unmapped more than once for multi-frame images.</li>
+</ul>
+</blockquote>
+<p>2001-09-12 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Text drawing now handles UTF8-encoding.</li>
+<li>Off-by-one GetImagePixels() fix in draw.c</li>
+<li>PingImage() now reports attributes for all images in an image
+sequence.</li>
+</ul>
+</blockquote>
+<p>2001-09-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h: Rename QuantumLeap define to QuantumDepth.
+QuantumDepth is set to the values 8 or 16, depending on user
+configuration option.</li>
+</ul>
+</blockquote>
+<p>2001-09-09 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated PerlMagick signatures to reflect new message digest
+algorithm.</li>
+</ul>
+</blockquote>
+<p>2001-09-08 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick defaults to 16-bit quantum. Set QuantumMagick
+for 8-bit.</li>
+<li>Changed image-&gt;blob from BlobInfo to BlobInfo* so the Image
+structure size is not dependent on the large-file preprocessor
+defines.</li>
+</ul>
+</blockquote>
+<p>2001-09-07 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added -background to convert program usage text.</li>
+<li>DispatchImage() now properly handles grayscale images.</li>
+</ul>
+</blockquote>
+<p>2001-09-01 Glenn &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>The compression quality setting is now recognized when creating
+MPEG images (contributed by Lawrence Livermore National Laboratory
+(LLNL)).</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2001.rst b/www/ChangeLog-2001.rst
new file mode 100644
index 0000000..7993925
--- /dev/null
+++ b/www/ChangeLog-2001.rst
@@ -0,0 +1,290 @@
+2001-12-28 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Even more features and options were added to conjure
+ - Added CropBox support to PDF writer
+
+2001-12-26 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Conjure now supports having a list of files for the script to
+ process being passed on the command line.
+ - More features and options were added to conjure
+
+2001-12-25 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Made a huge number of improvements to conjure. It now supports
+ over 15 different commands for manipulating your images.
+
+2001-12-24 Cristy <cristy@mystic.es.dupont.com>
+
+ - Started a new scripting language utility, conjure.
+
+2001-12-20 Cristy <cristy@mystic.es.dupont.com>
+
+ - Display the search path in the event a utility cannot find a
+ particular configuration file (thanks to billr@corbis.com)
+
+2001-12-14 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Fixed some bugs in the new composite operators.
+
+2001-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added native BLOB support to coders/wmf.c.
+
+2001-12-13 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Added new composite operators to support PSD/XCF
+ layer compositing: NoCompositeOp, DarkenCompositeOp,
+ LightenCompositeOp, HueCompositeOp, SaturateCompositeOp,
+ ValueCompositeOp, ColorizeCompositeOp, LuminizeCompositeOp,
+ ScreenCompositeOp, OverlayCompositeOp.
+ - Modified the PSD coder to set the appropriate composite
+ operator.
+ - Modified the XCF coder to set the appropriate composite
+ operator.
+
+2001-12-10 Cristy <cristy@mystic.es.dupont.com>
+
+ - Removed the flatten option from ImageInfo.
+ - Added new compose member to ImageInfo that defines which of
+ the composite operators to use when flattening an image.
+
+2001-12-09 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Added new member to ImageInfo, flatten, used by PSD and XCF
+ to determine whether to flatten an image when read.
+ - PSD and XCF now respect image\_info->flatten.
+ - Fixed bug in XCF loader when loading layered image as layers.
+ - Modified the convert program to set image\_info->flatten if
+ -flatten is specified; we still call FlattenImages for other
+ formats that don't respect image\_info->flatten.
+ - Modified Magick++'s Image class to support image\_info->flatten.
+
+2001-12-08 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Improvements to the Photoshop (PSD) coder: 1) added support
+ for Duotone images loaded as grayscale as per PSD docs; and 2)
+ added option to composite layers when reading respects layer
+ visibility setting.
+
+2001-12-07 Cristy <cristy@mystic.es.dupont.com>
+
+ - -dissolve wasn't working for the composite program (thanks to
+ Rick Manbry).
+ - DCM coder failed to read a valid DCM image file.
+
+2001-12-06 Cristy <cristy@mystic.es.dupont.com>
+
+ - Stream buffer was not being freed in ReadStream().
+
+2001-12-05 Cristy <cristy@mystic.es.dupont.com>
+
+ - Corrected bias when downsizing an image with ResizeImage().
+
+2001-11-25 Cristy <cristy@mystic.es.dupont.com>
+
+ - AcquireImagePixels() can accept (x,y) outside the image area
+ (e.g. AcquireImagePixels(image,-3,-3,7,7,exception)).
+
+2001-11-22 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added limited SVG gradient support.
+
+2001-11-21 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added API method, PingBlob().
+
+2001-11-14 Cristy <cristy@mystic.es.dupont.com>
+
+ - Moved a few pixel related defines (e.g. Downscale()) to
+ a corresponding method to enforce strong type checking at
+ compile time.
+
+2001-11-12 Cristy <cristy@mystic.es.dupont.com>
+
+ - Previously ImageMagick did not write 8-bit ASCII PPM/PGM files
+ when QuantumDepth == 16.
+ - Added 'id' as an image attribute in PerlMagick (returns
+ ImageMagick registry ID).
+
+2001-11-10 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added SVG pattern support.
+ - Changed default background color to none.
+
+2001-11-06 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added support of reading and writing 16-bit raw PPM/PGM files.
+
+2001-11-05 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added -level to convert/mogrify (suggested by
+ mericson@phillynews.kom).
+
+2001-11-04 Cristy <cristy@mystic.es.dupont.com>
+
+ - -shadow/-shade were not distiguished.
+
+2001-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Makefile.PL.in: Install PerlMagick using
+ ImageMagick's configure prefix.
+
+2001-11-02 Cristy <cristy@mystic.es.dupont.com>
+
+ - Typecast offset to unsigned long in coders/pdf.c.
+
+2001-11-01 Cristy <cristy@mystic.es.dupont.com>
+
+ - Convert's -flatten, -average, etc. failed with an assert error.
+
+2001-10-30 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added support for On-the-air bitmap.
+
+2001-09-29 Glenn <randeg@alum.rpi.edu>
+
+ - When the delay setting for an image is greater than 4cs, duplicate
+ frames are inserted to achieve the desired delay while creating MPEG
+ files (contributed by Lawrence Livermore National Laboratory (LLNL)).
+
+2001-10-29 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick now has a registry for storing image blobs.
+
+2001-10-26 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added VMS patches (thanks to Jouk Jansen).
+
+2001-10-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fixed parsing bug for decorate #FFFFFF.
+
+2001-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added tests for mpeg2 library to configure.
+
+2001-10-22 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added a MPEG coder module.
+ - Added ImageType member to the image\_info structure (suggested
+ by Glenn)
+
+2001-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Eliminated libMagick.so dependency on libxml by not listing -lxml
+ when doing modules link.
+
+2001-10-18 Cristy <cristy@mystic.es.dupont.com>
+
+ - Eliminated the libMagick.so dependancy on libtiff by moving
+ Huffman2DEncodeImage() from magick/compress.c to coders/pdf.c,
+ coders/ps2.c and coders/ps3.c (suggested by Bob Friesenhahn).
+ This change has the side-effect of elminating dependency on libpng
+ and libjpeg as well (which libtiff may depend on).
+
+2001-10-16 Cristy <cristy@mystic.es.dupont.com>
+
+ - Convert now supports -channel {Cyan,Magenta,Yellow,Black}.
+
+2001-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c updated for libwmf 0.2. Plenty of bugs remain within.
+
+2001-10-11 Cristy <cristy@mystic.es.dupont.com>
+
+ - QueryFontMetrics() of PerlMagick now recognizes embedded
+ special characters (e.g. %h).
+
+2001-10-10 Cristy <cristy@mystic.es.dupont.com>
+
+ - Fixed seg-fault for PingImage() on a JP2 image file.
+
+2001-10-07 Cristy <cristy@mystic.es.dupont.com>
+
+ - CloneImage() now uses a referenced counted pixel cache.
+
+2001-10-05 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added AcquireImagePixels() method.
+ - Changed the formal parameter from Image \* to const Image \*
+ for a number of methods (e.g. ZoomImage()).
+ - Added ExceptionInfo parameter to DispatchImage().
+
+2001-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Find libxml headers under Debian Linux (bug ID 921).
+
+2001-10-02 Cristy <cristy@mystic.es.dupont.com>
+
+ - Fixed assertion error on drawing stroked text.
+
+2001-10-01 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added blob test to the PerlMagick test suite.
+
+2001-09-30 Cristy <cristy@mystic.es.dupont.com>
+
+ - switched strcpy to strncpy to help protect against buffer
+ overflow.
+
+ - ltdl.c passed int reference but a long was needed; caused a
+ fault on Solaris 64-bit compiles.
+
+2001-09-25 Cristy <cristy@mystic.es.dupont.com>
+
+ - Removed most lint complaints from the source.
+ - strtod() returns different results on Linux and Solaris for 0x13.
+ - Added a MATLAB encoder contributed by Jaroslav Fojtik.
+
+2001-09-21 Cristy <cristy@mystic.es.dupont.com>
+
+ - Replaced TemporaryFilename() with UniqueImageFilename().
+ - ImageMagick CORE API is now 64-bit clean.
+
+2001-09-20 Cristy <cristy@mystic.es.dupont.com>
+
+ - Fixed svg.c to accept a viewbox with a negative offset.
+
+2001-09-15 Cristy <cristy@mystic.es.dupont.com>
+
+ - Surveying the code for 64-bit compatibility.
+ - The cloned colormap was too small (reported by Glenn).
+ - A blob was being unmapped more than once for multi-frame images.
+
+2001-09-12 Cristy <cristy@mystic.es.dupont.com>
+
+ - Text drawing now handles UTF8-encoding.
+ - Off-by-one GetImagePixels() fix in draw.c
+ - PingImage() now reports attributes for all images in an image
+ sequence.
+
+2001-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h: Rename QuantumLeap define to QuantumDepth.
+ QuantumDepth is set to the values 8 or 16, depending on user
+ configuration option.
+
+2001-09-09 Cristy <cristy@mystic.es.dupont.com>
+
+ - Updated PerlMagick signatures to reflect new message digest
+ algorithm.
+
+2001-09-08 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick defaults to 16-bit quantum. Set QuantumMagick
+ for 8-bit.
+ - Changed image->blob from BlobInfo to BlobInfo\* so the Image
+ structure size is not dependent on the large-file preprocessor
+ defines.
+
+2001-09-07 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added -background to convert program usage text.
+ - DispatchImage() now properly handles grayscale images.
+
+2001-09-01 Glenn <randeg@alum.rpi.edu>
+
+ - The compression quality setting is now recognized when creating
+ MPEG images (contributed by Lawrence Livermore National Laboratory
+ (LLNL)).
diff --git a/www/ChangeLog-2002.html b/www/ChangeLog-2002.html
new file mode 100644
index 0000000..e7cdff5
--- /dev/null
+++ b/www/ChangeLog-2002.html
@@ -0,0 +1,1753 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2002-12-31 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Do not quantize CMYK (bug fix).</li>
+<li>magick/render.c: Ensure that stroke is not drawn wider than
+requested when antialiasing is disabled (bug fix).</li>
+</ul>
+</blockquote>
+<p>2002-12-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: For TransformRGBImage() and RGBTransformImage()
+round values to int when creating tables rather than using scaling
+to avoid rounding.</li>
+</ul>
+</blockquote>
+<p>2002-12-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Fixed compile problems.</li>
+<li>magick/image.c: SyncImage() performance optimizations.</li>
+<li>TransformRGBImage() cleanup/enhancements. Some rounding issues
+remain.</li>
+<li>RGBTransformImage() cleanup/enhancements. Some rounding issues
+remain.</li>
+</ul>
+</blockquote>
+<p>2002-12-24 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BUGFIX: Fixed bug, introduced on 12/18/02, in which a misplaced
+&quot;}&quot; caused an assertion failure after reading any opaque JNG
+image.</li>
+<li>Added CloseBlob before returning a NULL JNG image.</li>
+<li>Merged png.c with IM-5.5.3-1, including a seemingly pointless
+rename of SaveImageText string to SaveImageTag.</li>
+</ul>
+</blockquote>
+<p>2002-12-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: Optimized gray x, y, z, tables creation in
+RGBTransformImage().</li>
+</ul>
+</blockquote>
+<p>2002-12-27 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pcd.c: IsPCDImage() fix offset to test header magic.</li>
+<li>coders/pcd.c: Ensure that blob is closed on error.</li>
+<li>coders (all): Pass image-&gt;colorspace to TransformRGBImage()</li>
+<li>magick (animate.c, command.c, display.c, image.c, nt_feature.c)
+Pass image-&gt;colorspace to TransformRGBImage().</li>
+<li>magick/nt_feature.c: Ensure that image is RGB prior to transfer
+to HBITMAP.</li>
+</ul>
+</blockquote>
+<p>2002-12-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: Re-worked TransformRGBImage() again so that it
+is now smoking fast for Q:8 and Q:16. Changed lookup tables, and
+all per-pixel transforms to use only integer arithmetic. A
+pre-multiplication scheme is used which should actually improve
+the quantization error over using double arithmetic. It is
+actually possible to improve Q:32 performance a bit more but is it
+worth the effort?</li>
+</ul>
+</blockquote>
+<p>2002-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: Implemented logging for TransformRGBImage() and
+RGBTransformImage().</li>
+</ul>
+</blockquote>
+<p>2002-12-24 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>The png codec would close the blob twice (second time raising an
+assertion) if a libpng error was encountered.</li>
+<li>Sometimes the PNG writer would receive an invalid bit depth from
+CompositeImages(); this is now ignored.</li>
+</ul>
+</blockquote>
+<p>2002-12-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: Re-wrote TransformRGBImage() so that it does not
+penalize a Q:8 build. The function should be faster now, but no
+timings have been made to verify that.</li>
+</ul>
+</blockquote>
+<p>2002-12-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Elimimated unused transparent_pixel array in png.c.</li>
+<li>Reverted to incrementing loops in bmp.c where the counter &quot;i&quot; is
+used in the loop.</li>
+</ul>
+</blockquote>
+<p>2002-12-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Update MogrifyImage() so that gm is 9X faster
+when transforming a color image to grayscale.</li>
+</ul>
+</blockquote>
+<p>2002-12-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated coders to use VerifyColormapIndex macro rather than slow
+ConstrainColormapIndex() function.</li>
+<li>magick/constitute.c: Trial use of VerifyColormapIndex in
+PushImagePixels() IndexQuantum case.</li>
+</ul>
+</blockquote>
+<p>2002-12-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/color.c: Added VerifyColormapIndex macro to verify range
+of color index without a function call.</li>
+<li>coders/bmp.c: Updated to use VerifyColormapIndex macro.</li>
+</ul>
+</blockquote>
+<p>2002-12-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c: Sped up RLE expansion and sped up byte-size
+PseudoColor scanline conversion. Results in 50% speed-up when
+running on SPARC.</li>
+</ul>
+</blockquote>
+<p>2002-12-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities: Removed legacy ImageMagick utilities which have been
+rolled up into gm.c/command.c.</li>
+</ul>
+</blockquote>
+<p>2002-12-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Fixed FormatString() format problems
+identified by the compiler.</li>
+</ul>
+</blockquote>
+<p>2002-12-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h: Moved function prototypes for functions
+implemented in code modules other than image.c to seperate header
+files with names based on the implementation files.</li>
+</ul>
+</blockquote>
+<p>2002-12-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enhance.c: Report appropriate message while leveling
+image.</li>
+</ul>
+</blockquote>
+<p>2002-12-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Sync png.c and fx.c with IM-5.5.3. &quot;gm convert -list format&quot;
+now includes zlib version info among the PNG info.</li>
+<li>ConvolveImage() logs kernel info as a &quot;Transform&quot; debug event.</li>
+<li>ReadJNGImage() now skips decoding JPEG subimage when &quot;pinging&quot;</li>
+</ul>
+</blockquote>
+<p>2002-12-17 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>SVG element <cite>stroke-dasharray: 0</cite> no longer causes a
+segmentation fault.</li>
+</ul>
+</blockquote>
+<p>2002-12-17 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>CoaleseceImage() properly handles a dispose method of
+BackgroundDispose.</li>
+</ul>
+</blockquote>
+<p>2002-12-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Updated to substitute for &#64;GMDelegate&#64;.</li>
+<li>magick/effect.c: Changed AdaptiveThresholdImage offset to double
+so that it works with QuantumDepth=32. Thanks to Glenn for
+pointing out this problem.</li>
+<li>magick/image.c: Adapted to AdaptiveThresholdImage API change.</li>
+<li>magick/image.h: Annotated global constants and functions with
+the name of the source file where they are implemented. This is
+in preparation to break up image.h into multiple header files to
+diminish unnecessary header dependencies.</li>
+<li>coders/delegates.mgk.in: Updated to use &#64;GMDelegate&#64; definition
+and <cite>gm</cite> program rather than ImageMagick utility names.</li>
+<li>PerlMagick/t/read.t: Converted gradient test (which was not
+working at all) to compare with a reference image.</li>
+<li>PerlMagick/t/jpeg/read.t: Re-wrote to compare with reference
+image.</li>
+<li>PerlMagick/t/jpeg/write.t: Re-wrote to compare with reference
+image.</li>
+<li>magick/image.c, magick/command.c: Moved MogrifyImage and
+MogrifyImages from image.c to command.c in order to diminish
+unnecessary inter-object coupling. Only functions in command.c
+should use MogrifyImage or MogrifyImages. Some work remains to
+accomplish that.</li>
+</ul>
+</blockquote>
+<p>2002-12-16 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: Add missing break statements to fix colorspace
+handling when image colorspace is CMYKColorspace or
+YCbCrColorspace.</li>
+<li>magick/decorate.c: Cast to double in calculation.</li>
+<li>magick/enhance.c: Tweaks to equalization map calculation to
+(hopefully) provide more consistent results.</li>
+<li>magick/resize.c: Use type double rather than long for minify
+weighting constants.</li>
+</ul>
+</blockquote>
+<p>2002-12-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/image.h: AdaptiveThresholdImage offset must be a signed
+type.</li>
+</ul>
+</blockquote>
+<p>2002-12-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Re-wrote PerlMagick filter.t tests so that they all compare
+results with reference images rather than compare signatures.
+This makes the tests easier to maintain and also makes it easier
+to find errors in ImageMagick.</li>
+</ul>
+</blockquote>
+<p>2002-12-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Warnings reduction</li>
+<li>magick/list.c: Warnings reduction</li>
+</ul>
+</blockquote>
+<p>2002-12-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated PerlMagick tests for Emboss, Equalize, Gamma, Normalize,
+OilPaint, and Gradient so that they pass at Q:8 under Windows.</li>
+<li>Updated PerlMagick tests for Emboss, and reading WMF, so that
+they pass at Q:16 under Windows.</li>
+<li>VisualMagickinstallerImageMagick-16.iss: Ported over from
+ImageMagick-8.iss and verified.</li>
+</ul>
+</blockquote>
+<p>2002-12-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Major smashing of ImageMagick to GraphicsMagick in .txt files
+and .html files.</li>
+<li>ImageMagick.html: Renamed to index.html.</li>
+<li>www/ImageMagick.html: Renamed to www/GraphicsMagick.html</li>
+</ul>
+</blockquote>
+<p>2002-12-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/list.c: Added GetFirstImageInList() function.</li>
+<li>magick/list.c: Added GetLastImageInList() function.</li>
+<li>coders/pcd.c: Re-implemented image tile labeling to avoid use of
+MogrifyImages().</li>
+</ul>
+</blockquote>
+<p>2002-12-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added <cite>commit</cite> shell script to CVS for those who chose to use
+it.</li>
+</ul>
+</blockquote>
+<p>2002-12-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c: Ensure that operating system call error return
+values are never used in resource limit calculation.</li>
+</ul>
+</blockquote>
+<p>2002-12-12 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c: Fixed bugs in InitializeMagick, but I also
+heavily commented the code so show what it seems to be doing. It
+appears broken and needs testing on all platforms. Toward that
+end, I added Log events so that we can see what it is doing.</li>
+</ul>
+</blockquote>
+<p>2002-12-12 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/gm.c: Fixes a crashing bug in gm.c caused by an
+attempt to free a bad pointer. Added comments to the code that
+explain why this happens so that future developers don't fall into
+the same trap. * win2k/IMDisplay/IMDisplay.rc Modified some of
+the string resources that define supported file formats that were
+in error. One example was eps with had a *.eps in the string
+instead of just .eps. This caused the document class to ASSERT
+under the debug build.</li>
+</ul>
+</blockquote>
+<p>2002-12-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Enable the module loading code for shared/DLL builds regardless
+of whether the build is a &quot;modules&quot; build. This allows users to
+add their own modules without requiring the use of a special
+&quot;modules&quot; build.</li>
+</ul>
+</blockquote>
+<p>2002-12-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h: Backed out arbitrary name change from
+ChannelThresholdImage() to ThresholdImageChannel() that snuck in
+from Cristy's image.h changes.</li>
+</ul>
+</blockquote>
+<p>2002-12-11 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c: Reference cloned image Blob (not sure why needed
+but must be important).</li>
+</ul>
+</blockquote>
+<p>2002-12-11 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enhance.c: Fixed LevelImage() to accept percent
+black/white points (.i.e. 90%).</li>
+<li>magick/enhance.c: Added LevelImageChannel().</li>
+<li>magick/enhance.c: Improved Q:8 performance of color
+transformations (e.g. for Gamma) which are based on a mapping
+array.</li>
+<li>coders/pcl.c: Fixed PCL coder to output proper color PCL
+instructions.</li>
+</ul>
+</blockquote>
+<p>2002-12-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: Disabled SetImageInfo() code which uses
+GetImageMagick() to test file magic via Is* methods so that we can
+learn if eliminating use of these tests causes any ill effects.</li>
+</ul>
+</blockquote>
+<p>2002-12-09 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Moved xtrn.c from contrib area into coders area so that it can
+be used from within the COM object. This is windows only code that
+provides a back door way for the COM object to have data read or
+written into VB arrays.</li>
+</ul>
+</blockquote>
+<p>2002-12-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/mac.c: Merged in fixes from ImageMagick version.</li>
+<li>magick/magick.mgk: Merged in fixes from ImageMagick version.</li>
+</ul>
+</blockquote>
+<p>2002-12-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: Fix ChannelImage() so that it does not destroy
+CMYK(A) channels by forcing RGB.</li>
+</ul>
+</blockquote>
+<p>2002-12-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/version.h: Changed to release 1.0.0.</li>
+<li>magick/nt_base.c: Changed &quot;ImageMagick&quot; to &quot;GraphicsMagick&quot; so
+registry lookups work for GraphicsMagick. Probably should be
+configured via a magick_config.h define.</li>
+<li>VisualMagick/installer/ImageMagick-8.iss:
+Changed for GraphicsMagick.</li>
+<li>utilities/conjure.c: Fix unterminated comment.</li>
+</ul>
+</blockquote>
+<p>2002-12-06 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: Modification of JPEG APP1 detection logic to name
+EXIF and XMP profiles as EXIF and XMP instead of APP1. THe current
+algorithm is brute force.</li>
+<li>coders/meta.c: Modification deal with EXIF and XMP requests so
+that you can ask for these blobs specifically if they exist.</li>
+<li>coders/pdf.c,ps.c,ps2.c,ps3.c: Cristy bug fixes to eliminate
+redundant file access checking and fix embedded JPEG support.</li>
+<li>magick/random.c: Upgraded this to match current Cristy code. The
+upgrade is to support more robust temporary filenames in another
+change to this in utility.c however, I have not upgraded this code
+yet because I don't understand it well enough.</li>
+</ul>
+</blockquote>
+<p>2002-12-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added build support for utilities/gm.c</li>
+</ul>
+</blockquote>
+<p>2002-12-06 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Relocated animate, conjure, display, and import functions into
+command.c.</li>
+<li>Added utilities/gm.c; gm is a driver for all of the utility
+functions (animate, composite, conjure, convert, display,
+identify, import, mongrify, and montage), which are now run with
+&quot;gm convert [convert_options]&quot;, &quot;gm identify [identify_options]&quot;,
+etc.</li>
+</ul>
+</blockquote>
+<p>2002-12-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c: Remove bogus code for handling temporary file.</li>
+</ul>
+</blockquote>
+<p>2002-12-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated to Autoconf 2.57.</li>
+<li>Install libraries as -lGraphicsMagick and -lGraphicsMagick++
+under Unix.</li>
+<li>Install headers under ${PREFIX}/include/GraphicsMagick under
+Unix.</li>
+<li>Update *-config scripts to produce correct library and include
+statements.</li>
+<li>Update PerlMagick to use correct library and include statements.</li>
+</ul>
+</blockquote>
+<p>2002-12-04 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp:
+Fixed serious problem with not installing custom error and warning
+handlers in the new version of the COM object.</li>
+</ul>
+</blockquote>
+<p>2002-12-04 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c: Pass exceptions on write up into the
+exception structure passed into the WriteImages function.</li>
+</ul>
+</blockquote>
+<p>2002-12-04 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: Added orphan image functionality changes that
+are purported to fix bugs in PDF and PS coders.</li>
+</ul>
+</blockquote>
+<p>2002-12-04 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/locale.c: Hard coded the locale as per Cristy fix, but
+also added a comment and disabled useless code.</li>
+</ul>
+</blockquote>
+<p>2002-12-04 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/bin/magic.mgk: Added JNG as per the copy in magick
+subdirectory.</li>
+</ul>
+</blockquote>
+<p>2002-12-04 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff/libtiff/tiff.h: Minor changes to make reading older
+Photoshop TIFF files spew fewer warnings.</li>
+</ul>
+</blockquote>
+<p>2002-12-04 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Optimized ConvolveImage() by normalizing the kernel values
+instead of normalizing the pixels.</li>
+</ul>
+</blockquote>
+<p>2002-12-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/formats.html: Add JNG and fix libpng links.</li>
+</ul>
+</blockquote>
+<p>2002-12-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ChangeLog: Updated this ChangeLog to use the format prescribed
+by the GNU coding standards.</li>
+</ul>
+</blockquote>
+<p>2002-12-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Use PNG_SETJMP_NOT_THREAD_SAFE to indicate that
+the C library's setjmp() API is not thread safe.</li>
+<li>Fix use of image_info-&gt;blob.</li>
+</ul>
+</blockquote>
+<p>2002-11-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Set up new CVS repository for GraphicsMagick based on current
+ImageMagick 5.5.2 (pre-release) sources.</li>
+</ul>
+</blockquote>
+<p>2002-11-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Flashpix library now uses C++ standard &lt;new&gt; and iostreams
+rather than legacy new and iostreams.</li>
+</ul>
+</blockquote>
+<p>2002-11-15 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>The blob methods were enhanced to use GZip or BZip API methods
+to compress/uncompress images (previously the external programs
+gunzip or bunzip2 were used).</li>
+</ul>
+</blockquote>
+<p>2002-11-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Update to Autoconf 2.56</li>
+</ul>
+</blockquote>
+<p>2002-11-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Update to Autoconf 2.55</li>
+</ul>
+</blockquote>
+<p>2002-11-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Moved coder Register/Unregister method prototypes to static.h
+since they are only needed by static.c.</li>
+<li>Removed defunct HDF and libmpeg2 support since it was confusing
+to users.</li>
+</ul>
+</blockquote>
+<p>2002-11-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c: Set white background of embedded bitmaps to
+transparent if the image background is a texture image, not-white,
+or non-opaque. This improves the output when the WMF is rendered
+on a non-default background.</li>
+</ul>
+</blockquote>
+<p>2002-11-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated Windows CVS to FreeType 2.1.2.</li>
+</ul>
+</blockquote>
+<p>2002-11-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated Windows CVS to Jasper 1.600.0.</li>
+</ul>
+</blockquote>
+<p>2002-11-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Verify sanity of sysconf(_SC_PAGE_SIZE) and
+sysconf(_SC_PHYS_PAGES) before using their values.</li>
+</ul>
+</blockquote>
+<p>2002-11-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Modified IMdisplay so that larger images may be loaded
+(primarily limited by Windows bitmap size limits).</li>
+<li>Added some more file types (EPS, GIF, MIFF, SVG, &amp; WMF) to
+IMdisplay's file open list.</li>
+<li>The list management methods were given more meaningful names.</li>
+</ul>
+</blockquote>
+<p>2002-11-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Modified IMdisplay so that Magick++ Images are stored by value
+rather than via pointer.</li>
+<li>IMdisplay now uses minify(), magnify(), and zoom() methods where
+appropriate.</li>
+</ul>
+</blockquote>
+<p>2002-11-04 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Quantizing a DirectClass image with less than 256 unique colors
+is no longer lossy.</li>
+<li>Transparent TGA images had incorrect opacity values.</li>
+</ul>
+</blockquote>
+<p>2002-10-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added configure test for compiler __func__ support
+(HAS___func__).</li>
+<li>Added configure test for ftime().</li>
+</ul>
+</blockquote>
+<p>2002-10-31 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>CMYK + alpha layered PSD files now correctly read!</li>
+</ul>
+</blockquote>
+<p>2002-10-30 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ReadPSDImage() is now fully instrumented with logging</li>
+<li>Fixed long standing bug in ReadPSDImage, so it no longer returns
+an extra layer</li>
+</ul>
+</blockquote>
+<p>2002-10-29 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added three output formats: PNG24 (24-bit RGB PNG, opaque only),
+PNG32 32-bit (RGBA PNG, semitransparency OK), and PNG8 (8-bit
+indexed PNG, binary transparency only).</li>
+</ul>
+</blockquote>
+<p>2002-10-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/vid.c: Modified to be 10X faster for large images and to
+take advantage of JPEG size optimizations.</li>
+</ul>
+</blockquote>
+<p>2002-10-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/xwindow.c: Optimize loading of TrueColor images with
+gamma = 1.0.</li>
+</ul>
+</blockquote>
+<p>2002-10-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c: Added logging facilities.</li>
+</ul>
+</blockquote>
+<p>2002-10-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>display.c: removed unnecessary SignatureImage() calls which
+dramatically slowed down loading images and quiting the program.</li>
+<li>xwindow.c: optimized image size reduction for the case where the
+target size is a small fraction of the original size. This makes
+creation of display's panner and thumbnail images tremendously
+faster, with no noticeable degradation of thumbnail quality.</li>
+</ul>
+</blockquote>
+<p>2002-10-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added Windows95 define to VisualMagick magick_config.h to
+disable use of features not available under Windows '95</li>
+</ul>
+</blockquote>
+<p>2002-10-21 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added large file pixel cache support for Windows NT.</li>
+</ul>
+</blockquote>
+<p>2002-10-21 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PDF coder no longer uses ASCII85 encoding with TIFF for MUCH
+smaller files!</li>
+<li>Cleaned up a few other things in PDF coder.</li>
+</ul>
+</blockquote>
+<p>2002-10-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated to Automake 1.7.1.</li>
+</ul>
+</blockquote>
+<p>2002-10-18 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PingBlob() improperly set the length of BlobInfo to zero.</li>
+<li>Fixed Ping() memory leak in PerlMagick.</li>
+<li>Fixed -map problem in convert/mogrify utilities.</li>
+<li>Fixed -remote problem with display utility (returns correct
+error status).</li>
+</ul>
+</blockquote>
+<p>2002-10-16 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>-border with a single value now produces correct results
+(e.g. -border 10).</li>
+<li>Added -lat to convert/mogrify (local adaptive thresholding).</li>
+</ul>
+</blockquote>
+<p>2002-10-15 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Set locale type LC_NUMERIC to &quot;C&quot;.</li>
+<li>Bug fix for PS2 encoder.</li>
+<li>Added PS-Adobe preamble to PS3 encoder.</li>
+</ul>
+</blockquote>
+<p>2002-10-14 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick 5.5.1 released.</li>
+</ul>
+</blockquote>
+<p>2002-10-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Use ImageMagick release number to allow multiple ImageMagick
+releases to co-exist without interference on the same machine.</li>
+</ul>
+</blockquote>
+<p>2002-10-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Decided that DrawGet functions should return by value.</li>
+</ul>
+</blockquote>
+<p>2002-10-06 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added detailed logging to BMP, PNG, and JPEG codecs, including
+JPEG quality estimate.</li>
+</ul>
+</blockquote>
+<p>2002-10-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added draw.h &quot;DrawGet&quot; equivalents to most of the &quot;DrawSet&quot;
+functions.</li>
+<li>Added an array size argument to DrawSetDashPattern and got rid
+of the zero-termination garbage.</li>
+<li>Remove <cite>Set</cite> from the names of draw.h functions which update the
+current affine transformation array (e.g. DrawSetRotate becomes
+DrawRotate).</li>
+</ul>
+</blockquote>
+<p>2002-09-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated to Automake 1.7.</li>
+</ul>
+</blockquote>
+<p>2002-09-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Under Windows, a DllMain function which automatically
+initializes ImageMagick (when ImageMagick is built using DLLs) may
+be added by defining ProvideDllMain in magick_config.h</li>
+</ul>
+</blockquote>
+<p>2002-09-28 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added resource consumption methods, see magick/resource.c.</li>
+</ul>
+</blockquote>
+<p>2002-09-27 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Replaced underscores in commandline options with hyphens. For
+backward compatibility, underscores will continue to be
+recognized.</li>
+<li>Added -blue-primary, -green-primary, -red-primary, -white-point
+options.</li>
+</ul>
+</blockquote>
+<p>2002-09-27 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added BMP2 and BMP3 output formats.</li>
+<li>Changed chromaticity primary.z from 1.0 to
+1.0-(primary.x+primary.y) in the PNG and PCD codecs.</li>
+</ul>
+</blockquote>
+<p>2002-09-21 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added <cite>exception</cite> parameter to the ImageMagick progress monitor
+API.</li>
+<li>Added enumerated types for the dispose member of the Image
+structure.</li>
+<li>Added -version option to commandline utilities.</li>
+</ul>
+</blockquote>
+<p>2002-09-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>The xcf decoder would sometimes create artifacts when reading
+RLE-encoded grayscale images, due to the green and blue samples
+not being defined.</li>
+</ul>
+</blockquote>
+<p>2002-09-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Update to Autoconf 2.54.</li>
+</ul>
+</blockquote>
+<p>2002-08-08 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added logging capabilities to the CORE API. This facility is
+useful for debugging. Added &quot;events&quot; parameter to the -debug
+commandline option.</li>
+<li>AcquireImagePixels() did not always return the same pixel values
+for virtual pixels when the cache was stored on disk (very rare).</li>
+<li>new -virtual-pixel command line option.</li>
+<li>new PerlMagick virtual-pixel image attribute.</li>
+</ul>
+</blockquote>
+<p>2002-08-07 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick 5.4.9 released.</li>
+</ul>
+</blockquote>
+<p>2002-09-06 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed some bugs in the Clipboard coder</li>
+<li>Added new ImageToHBITMAP function to NTFeature.c/.h in core</li>
+<li>Added support for Quantum==32 to IMDisplay</li>
+</ul>
+</blockquote>
+<p>2002-08-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fix formatting in the *.mgk files so that they are XML conformant</li>
+</ul>
+</blockquote>
+<p>2002-08-30 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>QuantizeImage() did not always produce proper bilevel images.</li>
+</ul>
+</blockquote>
+<p>2002-08-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Apply prefix/suffix transformations to ImageMagick program names
+which are substituted into delegates.mgk. This fix was requested
+by Glenn Randers-Pehrson.</li>
+</ul>
+</blockquote>
+<p>2002-08-25 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Arcs are now rendered properly.</li>
+<li>Use -authenticate to specifiy a password when viewing encrypted
+PDF's.</li>
+<li>-page was previouly being ignored.</li>
+<li>Configure files are returned as blobs now (suggested by William
+Radcliffe).</li>
+</ul>
+</blockquote>
+<p>2002-08-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added --disable-installed option to configure to support
+building an ImageMagick which is not installed via hard-coded
+paths. This is intended to be used for the ad-hoc binary
+distributions built by ImageMagick Studio.</li>
+<li>The UseInstalledImageMagick define is to be used by builds
+formally installed under a prefix, or via the Windows registry.</li>
+<li>Replaced GetMagickConfigurePath() with the three functions
+FindConfigurationFile(), FindFontFile(), and FindModuleFile().</li>
+<li>Re-implemented InitializeMagick() to try harder at finding the
+uninstalled ImageMagick without the help of MAGICK_HOME. In the
+future, it can try even harder.</li>
+<li>Unix binaries packages (built with --disable-installed) should
+now work using the same file layout as the distribution file.
+There is no longer a need to put all files in the same directory.</li>
+</ul>
+</blockquote>
+<p>2002-08-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Under Windows, define UseInstalledImageMagick to locate
+components using the registry rather than scanning the filesystem.</li>
+</ul>
+</blockquote>
+<p>2002-08-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added DrawSetTextEncoding() function to specify text encoding
+(e.g. &quot;UTF-8&quot;).</li>
+</ul>
+</blockquote>
+<p>2002-08-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Extend <cite>convert -list type</cite> output so it prints more details.</li>
+<li>Fix draw.c problem when specifying font family names that
+contain spaces.</li>
+</ul>
+</blockquote>
+<p>2002-08-15 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Finished 32-Bit QuantumDepth support.</li>
+<li>Subimage memory leak fixed (bug report by William Radcliffe).</li>
+<li>Fixed subimage specification memory overrun.</li>
+<li>Subimage specification did not work properly under Windows.</li>
+</ul>
+</blockquote>
+<p>2002-08-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fix problem with TEXT encoder. It was prepending the filename
+to the text.</li>
+</ul>
+</blockquote>
+<p>2002-08-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Render Postscript via Ghostscript DLL (gsdll32.dll) under
+Windows if it can be loaded. Only ps.c currently uses this to
+verify there are no problems.</li>
+</ul>
+</blockquote>
+<p>2002-08-14 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added 16-bit raw write support to PPM.</li>
+</ul>
+</blockquote>
+<p>2002-08-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Re-implemented ReadTTFImage() using the draw.h APIs.</li>
+</ul>
+</blockquote>
+<p>2002-08-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed a libtool bug in order to allow passing -m64 to allow
+building 64-bit ImageMagick using gcc 3.1 or later under SPARC
+Solaris.</li>
+</ul>
+</blockquote>
+<p>2002-08-04 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added experimental 32-bit QuantumDepth pixel support.</li>
+<li>Stream support was not thread-safe (bug report by William Radcliffe).</li>
+<li>Push/PopImagePixels() now recognizes the proper buffer length
+(previously it operated on one scanline at a time).</li>
+<li>Deprecated Down/Upscale defines. Replaced them with
+Scale*ToQuantum() and ScaleQuantumTo*() methods.</li>
+</ul>
+</blockquote>
+<p>2002-08-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Changed configure argument --disable-16bit-pixel to
+--with-quantum-depth in order to make its usage more
+straightforward and generic. Build ImageMagick using an eight-bit
+quantum via --with-quantum-depth=8.</li>
+<li>Magick++ library builds as a DLL under Windows now.</li>
+</ul>
+</blockquote>
+<p>2002-07-31 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Delegates/modules are restricted to hard-coded search paths (a
+security feature suggested by Bob Friesenhahn).</li>
+</ul>
+</blockquote>
+<p>2002-07-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added SubstituteString to utility.c for performing substitions
+on strings.</li>
+<li>Added support for performing Ghostscript-related substitutions
+while reading delegates.mgk and type.mgk files.</li>
+</ul>
+</blockquote>
+<p>2002-07-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added the Windows utility functions NTGhostscriptDLL(),
+NTGhostscriptEXE(), and NTGhostscriptFonts(), to find the DLL,
+executable, and font directory corresponding to the newest
+Ghostscript install on the system.</li>
+</ul>
+</blockquote>
+<p>2002-07-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Split nt.c into ntbase.c and ntfeature.c</li>
+<li>Split nt.h into ntbase.h and ntfeature.h</li>
+<li>Invoke NTIsMagickConflict() under Cygwin to ensure that drive
+letters in file specifications are not confused with magick
+strings.</li>
+<li>Invoke NTGetTypeList() under Cygwin to read the list of Windows
+fonts.</li>
+</ul>
+</blockquote>
+<p>2002-07-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Created Windows &quot;setup.exe&quot; style installation package for
+ImageMagick.</li>
+<li>Include PerlMagick Perl extension for ActiveState ActivePerl as
+checkmark install option in Windows installation package.</li>
+<li>Include ImageMagickObject OLE Object for WSH and Visual Basic
+(not IIS!!!) as checkmark install option in Windows installation
+package.</li>
+<li>Windows installation package establishes file extension
+associations for ImageMagick.</li>
+</ul>
+</blockquote>
+<p>2002-07-17 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PPM files were being written in P4 or P5 format if all pixels
+were gray. This is correct behavior for the PNM format but not
+for the PPM format.</li>
+</ul>
+</blockquote>
+<p>2002-07-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Load font information from Windows rather than depending on hand
+edited type-windows.mgk file. Still not incorporated in Cygwin
+build.</li>
+</ul>
+</blockquote>
+<p>2002-07-04 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Typos corrected in perl.html (thanks to Ron Savage);</li>
+<li>A color profile is now correctly referred to as ICM instead of
+IPTC.</li>
+<li>Added XPM color compliance to colors.mgk.</li>
+<li>$image-&gt;Get(<cite>clip-mask</cite>) now returns the clipping image.</li>
+</ul>
+</blockquote>
+<p>2002-07-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added NTRegistryKeyLookup() to nt.c in order to look up
+ImageMagick installation parameters from the Windows Registry.</li>
+<li>Updated GetMagickConfigurePath() in magick.c to use installation
+path data from the Windows Registry (if available).</li>
+<li>Updated VisualMagick/ImageMagick.iss so that Windows Registry is
+updated by install package.</li>
+</ul>
+</blockquote>
+<p>2002-07-03 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Semaphore.c will compile now when pthreads are not present.</li>
+<li>8-Bit Quantum PCD images now read correctly.</li>
+<li>The antialias member of the ImageInfo structure was not being
+cloned.</li>
+</ul>
+</blockquote>
+<p>2002-07-01 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick 5.4.7 released.</li>
+</ul>
+</blockquote>
+<p>2002-06-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt.c (readdir): Make readdir re-entrant for each instance
+of DIR. This should improve thread safety.</li>
+<li>ltdl/ltdl.c : Support building as DLL under Win32.</li>
+</ul>
+</blockquote>
+<p>2002-06-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Update to use Automake 1.6.2</li>
+</ul>
+</blockquote>
+<p>2002-06-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Try harder when searching for Ghostscript fonts under Linux.</li>
+</ul>
+</blockquote>
+<p>2002-06-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Identify PICT files via magic.mgk.</li>
+</ul>
+</blockquote>
+<p>2002-06-18 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added PerlMagick threading support (patch by Doug MacEachern).</li>
+</ul>
+</blockquote>
+<p>2002-06-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>CLIPBOARD and EMF modules compile under MinGW and Cygwin.</li>
+</ul>
+</blockquote>
+<p>2002-06-14 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>The wbmp writer would dump core if it received a DirectClass
+image that contained only black and white pixels, because no
+colormap exists.</li>
+</ul>
+</blockquote>
+<p>2002-06-09 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Label color could not be set (bug report by Ron Savage).</li>
+<li>Added CatchException() method to magick/error.c.</li>
+</ul>
+</blockquote>
+<p>2002-06-06 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick, version 5.4.6-1 released.</li>
+</ul>
+</blockquote>
+<p>2002-06-05 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added -encoding option to command line utilities.</li>
+</ul>
+</blockquote>
+<dl class="docutils">
+<dt>2002-06-02 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</dt>
+<dd><ul class="first last simple">
+<li>ImageMagick, version 5.4.6 released.</li>
+</ul>
+</dd>
+</dl>
+<p>2002-05-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick may now be built (static build only) using the free
+MinGW development package from <a class="reference external" href="http://www.mingw.org">http://www.mingw.org</a>. Leonard's
+&quot;clipboard&quot; coder is included in the build.</li>
+</ul>
+</blockquote>
+<p>2002-05-28 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added new &quot;clipboard&quot; coder for reading/writing the system's
+clipboard. Currently this is only implemented on Windows. For
+example: <cite>convert logo: clipboard:</cite>, <cite>convert clipboard: foo.png</cite>.</li>
+</ul>
+</blockquote>
+<p>2002-05-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Support autotrace via delegates.mgk. For example: <cite>convert
+autotrace:file.png file.mvg</cite>.</li>
+</ul>
+</blockquote>
+<p>2002-05-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added progress monitor support to DrawImage().</li>
+</ul>
+</blockquote>
+<p>2002-05-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added progress monitor support to wmf.c.</li>
+</ul>
+</blockquote>
+<p>2002-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added EscapeText() to utility.c to support escaping text.</li>
+</ul>
+</blockquote>
+<p>2002-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Text escaping for -draw and DrawAnnotation was not working
+properly. Now it does. Backslash should act as a escape for the
+the active quote character (', &quot;, or }) as well as backslash. The
+backslash should be discarded if it was used as an escape
+character. In order to reliably pass a backslash, two successive
+backslashes are required
+(e.g. &quot;\&quot;).</li>
+</ul>
+</blockquote>
+<p>2002-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Modified Base64Encode() of utility.c so that it returns the
+number of characters encoded. This avoids having to invoke
+strlen() on possibly megabytes of data.</li>
+</ul>
+</blockquote>
+<p>2002-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed compilation error with Sun Workshop compiler (wmf.c).</li>
+</ul>
+</blockquote>
+<p>2002-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Implement polypolygon support in WMF renderer. Requires libwmf
+0.2.4 with draw_polypolygon IPA callback.</li>
+</ul>
+</blockquote>
+<p>2002-05-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added --enable-ccmalloc configure option.</li>
+</ul>
+</blockquote>
+<p>2002-05-09 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>DCM patch provided by Shane Blackett.</li>
+</ul>
+</blockquote>
+<p>2002-05-07 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Lock mutex when destroying a SemaphoreInfo structure (patch
+provided by William Radcliffe).</li>
+<li>Added mingw patches provided by Derry Bryson.</li>
+</ul>
+</blockquote>
+<p>2002-05-05 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick, version 5.4.5-1 released.</li>
+</ul>
+</blockquote>
+<p>2002-04-30 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Subimage specification did not work for TIFF (e.g. convert
+<cite>image.tiff[1]</cite> image.png).</li>
+</ul>
+</blockquote>
+<p>2002-04-30 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick, version 5.4.5 released.</li>
+</ul>
+</blockquote>
+<p>2002-04-20 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added magic string detection for the FPX format (patch provided by
+Marc).</li>
+</ul>
+</blockquote>
+<p>2002-04-18 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added ExceptionInfo parameter to C API method,
+QueryColorDatabase().</li>
+</ul>
+</blockquote>
+<p>2002-04-17 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed all known bugs with the IMDisplay utility for Windows.</li>
+</ul>
+</blockquote>
+<p>2002-04-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac (libtool_build_static_libs): Added
+--enable-delegate-build option to suuport building ImageMagick
+using delegate libraries in subdirectories of the ImageMagick
+source directory.</li>
+</ul>
+</blockquote>
+<p>2002-04-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>WMF now supplies bitmaps as inline images rather than via a mpri
+reference.</li>
+</ul>
+</blockquote>
+<p>2002-04-15 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed DrawImage() to properly handle affine image transforms.</li>
+<li>Added AffineTransformImage() to C API.</li>
+<li>Added -transform option to convert/mogrify program.</li>
+</ul>
+</blockquote>
+<p>2002-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (MagickToMime): New method to return the MIME
+media type corresponding to a specified magick tag.</li>
+</ul>
+</blockquote>
+<p>2002-04-12 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed a bug in writing layer names in PSD files.</li>
+</ul>
+</blockquote>
+<p>2002-04-10 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed PingImage() memory leak (thanks to Timo Vogel).</li>
+<li>Added encoding and unicode attributes to PerlMagick (patch
+provided by Youki Kadobayashi).</li>
+</ul>
+</blockquote>
+<p>2002-04-08 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added reference counted blobs.</li>
+<li>Added MagickFatalError() and SetFatalErrorHandler() to the C
+API.</li>
+<li>One color images caused memory corruption in QuantizeImage()
+(thanks to Vincent Broz).</li>
+<li>Memory leak in NormalizeImage() (thanks to Vincent Broz).</li>
+</ul>
+</blockquote>
+<p>2002-04-06 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added CCIS-601 4:2:2 YUV format read-write support.</li>
+<li>Added CCIS-601 4:2:2 MPEG-2 format write support.</li>
+<li>Fixed a bug introduced in 5.4.0 that caused files with &quot;M2V&quot;
+suffix to be written in MPEG-1 instead of MPEG-2 format.</li>
+</ul>
+</blockquote>
+<p>2002-03-28 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageToBlob() only returned the first frame of a multi-frame
+image.</li>
+</ul>
+</blockquote>
+<p>2002-04-05 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed inversion of colors when converting CMYk JPEG to PDF</li>
+</ul>
+</blockquote>
+<p>2002-04-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed TTF preview function.</li>
+</ul>
+</blockquote>
+<p>2002-03-28 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>DCM patches provided by Syam Gadde.</li>
+<li>Multi-frame MPC image files caused a fault under Windows.</li>
+<li>Copy entire comment from SVG (bug report from Bob Friesenhahn).</li>
+<li>Enlarged scanline buffer for JPEG-compressed TIFF's (bug report
+from Bob Friesenhahn).</li>
+</ul>
+</blockquote>
+<p>2002-03-27 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ImageMagick, version 5.4.4, released.</li>
+</ul>
+</blockquote>
+<p>2002-03-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added preliminary version of C API for vector drawing commands
+(draw.h &amp; draw.c). This interface is subject to change, and has
+not even been tested yet so it should not be used to support
+production code. The previous draw.h and draw.c have been renamed
+to render.h and render.c respectively.</li>
+</ul>
+</blockquote>
+<p>2002-03-25 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed bugs related to layered CMYK PSD images.</li>
+</ul>
+</blockquote>
+<p>2002-03-13 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PSD coder now saves layer information (name, offset &amp; opacity)
+in hidden attributes.</li>
+</ul>
+</blockquote>
+<p>2002-03-13 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Enhanced MPC to read/write image sequences.</li>
+</ul>
+</blockquote>
+<p>2002-03-13 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>A number of formats (e.g. JPEG, PS) did not handle DirectClass
+grayscale images properly.</li>
+</ul>
+</blockquote>
+<p>2002-03-12 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Changed Clone*Info() API so structure members are set directly rather
+than by the *clone=*info method (suggested by William Radcliffe).</li>
+</ul>
+</blockquote>
+<p>2002-03-11 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added AcquireString() to allocate read-only strings.</li>
+</ul>
+</blockquote>
+<p>2002-03-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/null.c (WriteNULLImage): Support writing &quot;null:&quot; image
+type for use when profiling or testing ImageMagick.</li>
+</ul>
+</blockquote>
+<p>2002-03-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Update to Autoconf 2.53 (new release)</li>
+<li>Update to Automake 1.6 (new release)</li>
+</ul>
+</blockquote>
+<p>2002-03-07 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Bob Friesenhahn's execution profile results in a number of
+speed-ups with a faster LocaleCompare() algorithm and
+self-adjusting lists.</li>
+<li>Recognize additional DCM metadata (suggested by Barry Branham).</li>
+<li>Fixed CopyOpacity composite operator for CMYKA images.</li>
+</ul>
+</blockquote>
+<p>2002-03-06 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Inlined AlphaComposite() and ValidateColormapIndex().</li>
+<li>Corrected compositing algorithm for the case where both source
+and destination pixels had opacity values that were neither fully
+transparent nor fully opaque.</li>
+</ul>
+</blockquote>
+<p>2002-03-05 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Memory overrun when drawing large circles.</li>
+</ul>
+</blockquote>
+<p>2002-03-04 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Removed bug introduced into Bob's Base64Encode() method.</li>
+</ul>
+</blockquote>
+<p>2002-03-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added Base64Decode() and Base64Encode() to utility.c and updated
+ReadInlineImage() in magick/constitute.c to use Base64Decode().</li>
+</ul>
+</blockquote>
+<p>2002-03-01 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GetTypeInfoByFamily() null pointer fault (reported by Bob
+Friesenhahn).</li>
+<li>Added module version number (patch by Glenn Randers-Pehrson).</li>
+</ul>
+</blockquote>
+<p>2002-03-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>image-&gt;matte was not being set when reading GRAY-ALPHA PNG
+files.</li>
+</ul>
+</blockquote>
+<p>2002-02-26 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Potential infinite loop in SyncBlob() (reported by Vladimir
+Faiden).</li>
+</ul>
+</blockquote>
+<p>2002-02-26 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Gravity not respected when drawing text with the convert
+program.</li>
+</ul>
+</blockquote>
+<p>2002-02-21 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>MPEG multi-part filenames require an embedded %d, not %lu.</li>
+<li>WriteStream() did not write to fifo (thanks to William
+Radcliffe).</li>
+</ul>
+</blockquote>
+<p>2002-02-20 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Annotation did not support SJIS properly (patch provided by
+Katsutoshi Shibuya).</li>
+</ul>
+</blockquote>
+<p>2002-02-18 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed memory overrun with -format option of the mogrify program.</li>
+<li>Labels were not positioned correctly for VID format.</li>
+</ul>
+</blockquote>
+<p>2002-02-16 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Replaced -copy/-replace options with +/-write in the convert
+program.</li>
+<li>Median filtering speed enhancement using skip list contributed
+by Mike Edmonds.</li>
+</ul>
+</blockquote>
+<p>2002-02-14 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Command line options now stay in effect for any image in command
+line order until a another option is encountered or if -noop is
+specified.</li>
+</ul>
+</blockquote>
+<p>2002-02-07 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>SVG coders understands inline images.</li>
+</ul>
+</blockquote>
+<p>2002-02-06 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;, Glenn Randers-Pehrson</p>
+<blockquote>
+<ul class="simple">
+<li>Made -scene consistent across all utilities. -snaps replaces
+previous functionality of -scene for import program.</li>
+</ul>
+</blockquote>
+<p>2002-01-30 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Correctly draw arc when arc end/start are not integer
+(patch contributed by Giuliano Pochini).</li>
+</ul>
+</blockquote>
+<p>2002-01-28 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;, Glenn Randers-Pehrson</p>
+<blockquote>
+<ul class="simple">
+<li>Geometry strings respect -gravity (e.g. -gravity SouthWest -crop
+100x100).</li>
+<li>Postive offsets in geometry strings move within the image canvas
+with respect to the gravity (SouthWest gravity is similar to
+Postscript page offsets).</li>
+</ul>
+</blockquote>
+<p>2002-01-24 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Use -trim to trim the edges of an image.</li>
+<li>Palm pixmap supported contributed by Christopher R. Hawks.</li>
+<li>Added -mask to the convert/mogrify programs to add clips masks
+to an image.</li>
+</ul>
+</blockquote>
+<p>2002-01-21 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed occasional small memory leak associated with exceptions.</li>
+<li>Persistent cache is no longer updated (MPC coder).</li>
+</ul>
+</blockquote>
+<p>2002-01-20 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed some bugs in the uncompressed PGM and PPM reader/writer
+(pnm.c).</li>
+</ul>
+</blockquote>
+<p>2002-01-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Removed test for libwmf/font.h.</li>
+</ul>
+</blockquote>
+<p>2002-01-13 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>More bug fixes and improvements in PSD writer.</li>
+</ul>
+</blockquote>
+<p>2002-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magic.mgk: Added entries for detecting PFA and PFB
+formats. Is this file used for anything anymore?</li>
+<li>coders/modules.mgk: Add support for PFA fonts.</li>
+<li>coders/ttf.c (RegisterTTFImage): Add support for PFA fonts.</li>
+<li>magick/annotate.c (RenderType): Add support for PFA fonts.</li>
+</ul>
+</blockquote>
+<p>2002-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Modified type.mgk so that it may include the additional files
+type-windows.mgk, type-solaris.mgk, and type-ghostscript.mgk
+depending on the operating system used, and the font files
+available.</li>
+</ul>
+</blockquote>
+<p>2002-01-11 Leonard Rosenthol &lt;<a class="reference external" href="mailto:leonardr&#37;&#52;&#48;lazerware&#46;com">leonardr<span>&#64;</span>lazerware<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PSD now supports writing layered images and IPTC data</li>
+<li>Fixed some bugs in XCF</li>
+</ul>
+</blockquote>
+<p>2002-01-11 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added image list methods to the API.</li>
+</ul>
+</blockquote>
+<p>2002-01-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac : Renamed configure option --with-ttf-fontpath to
+--with-fontpath since ImageMagick loads more than TrueType fonts.</li>
+<li>ChangeLog : Renamed Changelog.txt to ChangeLog in order to
+conform to GNU and open-source standards.</li>
+</ul>
+</blockquote>
+<p>2002-01-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am : $(DESTDIR) already contains trailing <cite>/</cite>.</li>
+</ul>
+</blockquote>
+<p>2002-01-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c (wmf_magick_device_begin): Fix non-opaque fills.
+Now properly fills with texture image.</li>
+</ul>
+</blockquote>
+<p>2002-01-05 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed an out-of-bounds memset() and two other memory overruns
+when decoding 1-bit AVI, BMP, and DIB images.</li>
+</ul>
+</blockquote>
+<p>2002-01-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fix lcms header inclusion in transform.c.</li>
+</ul>
+</blockquote>
+<p>2002-01-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c (magick_brush): Fixed bug with setting fill color.</li>
+</ul>
+</blockquote>
+<p>2002-01-03 Cristy &lt;<a class="reference external" href="mailto:cristy&#37;&#52;&#48;mystic&#46;es&#46;dupont&#46;com">cristy<span>&#64;</span>mystic<span>&#46;</span>es<span>&#46;</span>dupont<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Postscript Level II is now DCS compliant.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2002.rst b/www/ChangeLog-2002.rst
new file mode 100644
index 0000000..be017fe
--- /dev/null
+++ b/www/ChangeLog-2002.rst
@@ -0,0 +1,1417 @@
+2002-12-31 Cristy <cristy@mystic.es.dupont.com>
+
+ - magick/command.c: Do not quantize CMYK (bug fix).
+
+ - magick/render.c: Ensure that stroke is not drawn wider than
+ requested when antialiasing is disabled (bug fix).
+
+2002-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: For TransformRGBImage() and RGBTransformImage()
+ round values to int when creating tables rather than using scaling
+ to avoid rounding.
+
+2002-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c: Fixed compile problems.
+
+ - magick/image.c: SyncImage() performance optimizations.
+
+ - TransformRGBImage() cleanup/enhancements. Some rounding issues
+ remain.
+
+ - RGBTransformImage() cleanup/enhancements. Some rounding issues
+ remain.
+
+2002-12-24 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - BUGFIX: Fixed bug, introduced on 12/18/02, in which a misplaced
+ "}" caused an assertion failure after reading any opaque JNG
+ image.
+
+ - Added CloseBlob before returning a NULL JNG image.
+
+ - Merged png.c with IM-5.5.3-1, including a seemingly pointless
+ rename of SaveImageText string to SaveImageTag.
+
+2002-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: Optimized gray x, y, z, tables creation in
+ RGBTransformImage().
+
+2002-12-27 Cristy <cristy@mystic.es.dupont.com>
+
+ - coders/pcd.c: IsPCDImage() fix offset to test header magic.
+
+ - coders/pcd.c: Ensure that blob is closed on error.
+
+ - coders (all): Pass image->colorspace to TransformRGBImage()
+
+ - magick (animate.c, command.c, display.c, image.c, nt\_feature.c)
+ Pass image->colorspace to TransformRGBImage().
+
+ - magick/nt\_feature.c: Ensure that image is RGB prior to transfer
+ to HBITMAP.
+
+2002-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: Re-worked TransformRGBImage() again so that it
+ is now smoking fast for Q:8 and Q:16. Changed lookup tables, and
+ all per-pixel transforms to use only integer arithmetic. A
+ pre-multiplication scheme is used which should actually improve
+ the quantization error over using double arithmetic. It is
+ actually possible to improve Q:32 performance a bit more but is it
+ worth the effort?
+
+2002-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: Implemented logging for TransformRGBImage() and
+ RGBTransformImage().
+
+2002-12-24 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - The png codec would close the blob twice (second time raising an
+ assertion) if a libpng error was encountered.
+
+ - Sometimes the PNG writer would receive an invalid bit depth from
+ CompositeImages(); this is now ignored.
+
+2002-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: Re-wrote TransformRGBImage() so that it does not
+ penalize a Q:8 build. The function should be faster now, but no
+ timings have been made to verify that.
+
+2002-12-21 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Elimimated unused transparent\_pixel array in png.c.
+
+ - Reverted to incrementing loops in bmp.c where the counter "i" is
+ used in the loop.
+
+2002-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Update MogrifyImage() so that gm is 9X faster
+ when transforming a color image to grayscale.
+
+2002-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated coders to use VerifyColormapIndex macro rather than slow
+ ConstrainColormapIndex() function.
+
+ - magick/constitute.c: Trial use of VerifyColormapIndex in
+ PushImagePixels() IndexQuantum case.
+
+2002-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/color.c: Added VerifyColormapIndex macro to verify range
+ of color index without a function call.
+
+ - coders/bmp.c: Updated to use VerifyColormapIndex macro.
+
+2002-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c: Sped up RLE expansion and sped up byte-size
+ PseudoColor scanline conversion. Results in 50% speed-up when
+ running on SPARC.
+
+2002-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities: Removed legacy ImageMagick utilities which have been
+ rolled up into gm.c/command.c.
+
+2002-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: Fixed FormatString() format problems
+ identified by the compiler.
+
+2002-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h: Moved function prototypes for functions
+ implemented in code modules other than image.c to seperate header
+ files with names based on the implementation files.
+
+2002-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/enhance.c: Report appropriate message while leveling
+ image.
+
+2002-12-18 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Sync png.c and fx.c with IM-5.5.3. "gm convert -list format"
+ now includes zlib version info among the PNG info.
+
+ - ConvolveImage() logs kernel info as a "Transform" debug event.
+
+ - ReadJNGImage() now skips decoding JPEG subimage when "pinging"
+
+2002-12-17 Cristy <cristy@mystic.es.dupont.com>
+
+ - SVG element `stroke-dasharray: 0` no longer causes a
+ segmentation fault.
+
+2002-12-17 Cristy <cristy@mystic.es.dupont.com>
+
+ - CoaleseceImage() properly handles a dispose method of
+ BackgroundDispose.
+
+2002-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Updated to substitute for @GMDelegate@.
+
+ - magick/effect.c: Changed AdaptiveThresholdImage offset to double
+ so that it works with QuantumDepth=32. Thanks to Glenn for
+ pointing out this problem.
+
+ - magick/image.c: Adapted to AdaptiveThresholdImage API change.
+
+ - magick/image.h: Annotated global constants and functions with
+ the name of the source file where they are implemented. This is
+ in preparation to break up image.h into multiple header files to
+ diminish unnecessary header dependencies.
+
+ - coders/delegates.mgk.in: Updated to use @GMDelegate@ definition
+ and `gm` program rather than ImageMagick utility names.
+
+ - PerlMagick/t/read.t: Converted gradient test (which was not
+ working at all) to compare with a reference image.
+
+ - PerlMagick/t/jpeg/read.t: Re-wrote to compare with reference
+ image.
+
+ - PerlMagick/t/jpeg/write.t: Re-wrote to compare with reference
+ image.
+
+ - magick/image.c, magick/command.c: Moved MogrifyImage and
+ MogrifyImages from image.c to command.c in order to diminish
+ unnecessary inter-object coupling. Only functions in command.c
+ should use MogrifyImage or MogrifyImages. Some work remains to
+ accomplish that.
+
+2002-12-16 Cristy <cristy@mystic.es.dupont.com>
+
+ - coders/jpeg.c: Add missing break statements to fix colorspace
+ handling when image colorspace is CMYKColorspace or
+ YCbCrColorspace.
+
+ - magick/decorate.c: Cast to double in calculation.
+
+ - magick/enhance.c: Tweaks to equalization map calculation to
+ (hopefully) provide more consistent results.
+
+ - magick/resize.c: Use type double rather than long for minify
+ weighting constants.
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/image.h: AdaptiveThresholdImage offset must be a signed
+ type.
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Re-wrote PerlMagick filter.t tests so that they all compare
+ results with reference images rather than compare signatures.
+ This makes the tests easier to maintain and also makes it easier
+ to find errors in ImageMagick.
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Warnings reduction
+
+ - magick/list.c: Warnings reduction
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated PerlMagick tests for Emboss, Equalize, Gamma, Normalize,
+ OilPaint, and Gradient so that they pass at Q:8 under Windows.
+
+ - Updated PerlMagick tests for Emboss, and reading WMF, so that
+ they pass at Q:16 under Windows.
+
+ - VisualMagick\installer\ImageMagick-16.iss: Ported over from
+ ImageMagick-8.iss and verified.
+
+2002-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Major smashing of ImageMagick to GraphicsMagick in .txt files
+ and .html files.
+
+ - ImageMagick.html: Renamed to index.html.
+
+ - www/ImageMagick.html: Renamed to www/GraphicsMagick.html
+
+2002-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/list.c: Added GetFirstImageInList() function.
+
+ - magick/list.c: Added GetLastImageInList() function.
+
+ - coders/pcd.c: Re-implemented image tile labeling to avoid use of
+ MogrifyImages().
+
+2002-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added `commit` shell script to CVS for those who chose to use
+ it.
+
+2002-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c: Ensure that operating system call error return
+ values are never used in resource limit calculation.
+
+2002-12-12 William Radcliffe <billr@corbis.com>
+
+ - magick/magick.c: Fixed bugs in InitializeMagick, but I also
+ heavily commented the code so show what it seems to be doing. It
+ appears broken and needs testing on all platforms. Toward that
+ end, I added Log events so that we can see what it is doing.
+
+2002-12-12 William Radcliffe <billr@corbis.com>
+
+ - utilities/gm.c: Fixes a crashing bug in gm.c caused by an
+ attempt to free a bad pointer. Added comments to the code that
+ explain why this happens so that future developers don't fall into
+ the same trap. \* win2k/IMDisplay/IMDisplay.rc Modified some of
+ the string resources that define supported file formats that were
+ in error. One example was eps with had a \*.eps in the string
+ instead of just .eps. This caused the document class to ASSERT
+ under the debug build.
+
+2002-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Enable the module loading code for shared/DLL builds regardless
+ of whether the build is a "modules" build. This allows users to
+ add their own modules without requiring the use of a special
+ "modules" build.
+
+2002-12-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h: Backed out arbitrary name change from
+ ChannelThresholdImage() to ThresholdImageChannel() that snuck in
+ from Cristy's image.h changes.
+
+2002-12-11 Cristy <cristy@mystic.es.dupont.com>
+
+ - coders/psd.c: Reference cloned image Blob (not sure why needed
+ but must be important).
+
+2002-12-11 Cristy <cristy@mystic.es.dupont.com>
+
+ - magick/enhance.c: Fixed LevelImage() to accept percent
+ black/white points (.i.e. 90%).
+
+ - magick/enhance.c: Added LevelImageChannel().
+
+ - magick/enhance.c: Improved Q:8 performance of color
+ transformations (e.g. for Gamma) which are based on a mapping
+ array.
+
+ - coders/pcl.c: Fixed PCL coder to output proper color PCL
+ instructions.
+
+2002-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: Disabled SetImageInfo() code which uses
+ GetImageMagick() to test file magic via Is\* methods so that we can
+ learn if eliminating use of these tests causes any ill effects.
+
+2002-12-09 William Radcliffe <billr@corbis.com>
+
+ - Moved xtrn.c from contrib area into coders area so that it can
+ be used from within the COM object. This is windows only code that
+ provides a back door way for the COM object to have data read or
+ written into VB arrays.
+
+2002-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/mac.c: Merged in fixes from ImageMagick version.
+
+ - magick/magick.mgk: Merged in fixes from ImageMagick version.
+
+2002-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: Fix ChannelImage() so that it does not destroy
+ CMYK(A) channels by forcing RGB.
+
+2002-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/version.h: Changed to release 1.0.0.
+
+ - magick/nt\_base.c: Changed "ImageMagick" to "GraphicsMagick" so
+ registry lookups work for GraphicsMagick. Probably should be
+ configured via a magick\_config.h define.
+
+ - VisualMagick/installer/ImageMagick-8.iss:
+ Changed for GraphicsMagick.
+
+ - utilities/conjure.c: Fix unterminated comment.
+
+2002-12-06 William Radcliffe <billr@corbis.com>
+
+ - coders/jpeg.c: Modification of JPEG APP1 detection logic to name
+ EXIF and XMP profiles as EXIF and XMP instead of APP1. THe current
+ algorithm is brute force.
+
+ - coders/meta.c: Modification deal with EXIF and XMP requests so
+ that you can ask for these blobs specifically if they exist.
+
+ - coders/pdf.c,ps.c,ps2.c,ps3.c: Cristy bug fixes to eliminate
+ redundant file access checking and fix embedded JPEG support.
+
+ - magick/random.c: Upgraded this to match current Cristy code. The
+ upgrade is to support more robust temporary filenames in another
+ change to this in utility.c however, I have not upgraded this code
+ yet because I don't understand it well enough.
+
+2002-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added build support for utilities/gm.c
+
+2002-12-06 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Relocated animate, conjure, display, and import functions into
+ command.c.
+
+ - Added utilities/gm.c; gm is a driver for all of the utility
+ functions (animate, composite, conjure, convert, display,
+ identify, import, mongrify, and montage), which are now run with
+ "gm convert [convert\_options]", "gm identify [identify\_options]",
+ etc.
+
+2002-12-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c: Remove bogus code for handling temporary file.
+
+2002-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated to Autoconf 2.57.
+
+ - Install libraries as -lGraphicsMagick and -lGraphicsMagick++
+ under Unix.
+
+ - Install headers under ${PREFIX}/include/GraphicsMagick under
+ Unix.
+
+ - Update \*-config scripts to produce correct library and include
+ statements.
+
+ - Update PerlMagick to use correct library and include statements.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ - contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp:
+ Fixed serious problem with not installing custom error and warning
+ handlers in the new version of the COM object.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ - magick/constitute.c: Pass exceptions on write up into the
+ exception structure passed into the WriteImages function.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ - magick/image.c: Added orphan image functionality changes that
+ are purported to fix bugs in PDF and PS coders.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ - magick/locale.c: Hard coded the locale as per Cristy fix, but
+ also added a comment and disabled useless code.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ - VisualMagick/bin/magic.mgk: Added JNG as per the copy in magick
+ subdirectory.
+
+2002-12-04 William Radcliffe <billr@corbis.com>
+
+ - tiff/libtiff/tiff.h: Minor changes to make reading older
+ Photoshop TIFF files spew fewer warnings.
+
+2002-12-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Optimized ConvolveImage() by normalizing the kernel values
+ instead of normalizing the pixels.
+
+2002-12-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - www/formats.html: Add JNG and fix libpng links.
+
+2002-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ChangeLog: Updated this ChangeLog to use the format prescribed
+ by the GNU coding standards.
+
+2002-12-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/png.c: Use PNG\_SETJMP\_NOT\_THREAD\_SAFE to indicate that
+ the C library's setjmp() API is not thread safe.
+
+ - Fix use of image\_info->blob.
+
+2002-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Set up new CVS repository for GraphicsMagick based on current
+ ImageMagick 5.5.2 (pre-release) sources.
+
+2002-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Flashpix library now uses C++ standard <new> and iostreams
+ rather than legacy new and iostreams.
+
+2002-11-15 Cristy <cristy@mystic.es.dupont.com>
+
+ - The blob methods were enhanced to use GZip or BZip API methods
+ to compress/uncompress images (previously the external programs
+ gunzip or bunzip2 were used).
+
+2002-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Update to Autoconf 2.56
+
+2002-11-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Update to Autoconf 2.55
+
+2002-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Moved coder Register/Unregister method prototypes to static.h
+ since they are only needed by static.c.
+
+ - Removed defunct HDF and libmpeg2 support since it was confusing
+ to users.
+
+2002-11-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c: Set white background of embedded bitmaps to
+ transparent if the image background is a texture image, not-white,
+ or non-opaque. This improves the output when the WMF is rendered
+ on a non-default background.
+
+2002-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated Windows CVS to FreeType 2.1.2.
+
+2002-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated Windows CVS to Jasper 1.600.0.
+
+2002-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Verify sanity of sysconf(\_SC\_PAGE\_SIZE) and
+ sysconf(\_SC\_PHYS\_PAGES) before using their values.
+
+2002-11-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Modified IMdisplay so that larger images may be loaded
+ (primarily limited by Windows bitmap size limits).
+
+ - Added some more file types (EPS, GIF, MIFF, SVG, & WMF) to
+ IMdisplay's file open list.
+
+ - The list management methods were given more meaningful names.
+
+2002-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Modified IMdisplay so that Magick++ Images are stored by value
+ rather than via pointer.
+
+ - IMdisplay now uses minify(), magnify(), and zoom() methods where
+ appropriate.
+
+2002-11-04 Cristy <cristy@mystic.es.dupont.com>
+
+ - Quantizing a DirectClass image with less than 256 unique colors
+ is no longer lossy.
+
+ - Transparent TGA images had incorrect opacity values.
+
+2002-10-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added configure test for compiler \_\_func\_\_ support
+ (HAS\_\_\_func\_\_).
+
+ - Added configure test for ftime().
+
+2002-10-31 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - CMYK + alpha layered PSD files now correctly read!
+
+2002-10-30 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - ReadPSDImage() is now fully instrumented with logging
+
+ - Fixed long standing bug in ReadPSDImage, so it no longer returns
+ an extra layer
+
+2002-10-29 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Added three output formats: PNG24 (24-bit RGB PNG, opaque only),
+ PNG32 32-bit (RGBA PNG, semitransparency OK), and PNG8 (8-bit
+ indexed PNG, binary transparency only).
+
+2002-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/vid.c: Modified to be 10X faster for large images and to
+ take advantage of JPEG size optimizations.
+
+2002-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/xwindow.c: Optimize loading of TrueColor images with
+ gamma = 1.0.
+
+2002-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c: Added logging facilities.
+
+2002-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - display.c: removed unnecessary SignatureImage() calls which
+ dramatically slowed down loading images and quiting the program.
+
+ - xwindow.c: optimized image size reduction for the case where the
+ target size is a small fraction of the original size. This makes
+ creation of display's panner and thumbnail images tremendously
+ faster, with no noticeable degradation of thumbnail quality.
+
+2002-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added Windows95 define to VisualMagick magick\_config.h to
+ disable use of features not available under Windows '95
+
+2002-10-21 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added large file pixel cache support for Windows NT.
+
+2002-10-21 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - PDF coder no longer uses ASCII85 encoding with TIFF for MUCH
+ smaller files!
+
+ - Cleaned up a few other things in PDF coder.
+
+2002-10-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated to Automake 1.7.1.
+
+2002-10-18 Cristy <cristy@mystic.es.dupont.com>
+
+ - PingBlob() improperly set the length of BlobInfo to zero.
+
+ - Fixed Ping() memory leak in PerlMagick.
+
+ - Fixed -map problem in convert/mogrify utilities.
+
+ - Fixed -remote problem with display utility (returns correct
+ error status).
+
+2002-10-16 Cristy <cristy@mystic.es.dupont.com>
+
+ - -border with a single value now produces correct results
+ (e.g. -border 10).
+
+ - Added -lat to convert/mogrify (local adaptive thresholding).
+
+2002-10-15 Cristy <cristy@mystic.es.dupont.com>
+
+ - Set locale type LC\_NUMERIC to "C".
+
+ - Bug fix for PS2 encoder.
+
+ - Added PS-Adobe preamble to PS3 encoder.
+
+2002-10-14 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick 5.5.1 released.
+
+2002-10-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Use ImageMagick release number to allow multiple ImageMagick
+ releases to co-exist without interference on the same machine.
+
+2002-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Decided that DrawGet functions should return by value.
+
+2002-10-06 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Added detailed logging to BMP, PNG, and JPEG codecs, including
+ JPEG quality estimate.
+
+2002-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added draw.h "DrawGet" equivalents to most of the "DrawSet"
+ functions.
+
+ - Added an array size argument to DrawSetDashPattern and got rid
+ of the zero-termination garbage.
+
+ - Remove `Set` from the names of draw.h functions which update the
+ current affine transformation array (e.g. DrawSetRotate becomes
+ DrawRotate).
+
+2002-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated to Automake 1.7.
+
+2002-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Under Windows, a DllMain function which automatically
+ initializes ImageMagick (when ImageMagick is built using DLLs) may
+ be added by defining ProvideDllMain in magick\_config.h
+
+2002-09-28 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added resource consumption methods, see magick/resource.c.
+
+2002-09-27 Cristy <cristy@mystic.es.dupont.com>
+
+ - Replaced underscores in commandline options with hyphens. For
+ backward compatibility, underscores will continue to be
+ recognized.
+
+ - Added -blue-primary, -green-primary, -red-primary, -white-point
+ options.
+
+2002-09-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Added BMP2 and BMP3 output formats.
+
+ - Changed chromaticity primary.z from 1.0 to
+ 1.0-(primary.x+primary.y) in the PNG and PCD codecs.
+
+2002-09-21 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added `exception` parameter to the ImageMagick progress monitor
+ API.
+
+ - Added enumerated types for the dispose member of the Image
+ structure.
+
+ - Added -version option to commandline utilities.
+
+2002-09-21 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - The xcf decoder would sometimes create artifacts when reading
+ RLE-encoded grayscale images, due to the green and blue samples
+ not being defined.
+
+2002-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Update to Autoconf 2.54.
+
+2002-08-08 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added logging capabilities to the CORE API. This facility is
+ useful for debugging. Added "events" parameter to the -debug
+ commandline option.
+
+ - AcquireImagePixels() did not always return the same pixel values
+ for virtual pixels when the cache was stored on disk (very rare).
+
+ - new -virtual-pixel command line option.
+
+ - new PerlMagick virtual-pixel image attribute.
+
+2002-08-07 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick 5.4.9 released.
+
+2002-09-06 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Fixed some bugs in the Clipboard coder
+
+ - Added new ImageToHBITMAP function to NTFeature.c/.h in core
+
+ - Added support for Quantum==32 to IMDisplay
+
+2002-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fix formatting in the \*.mgk files so that they are XML conformant
+
+2002-08-30 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - QuantizeImage() did not always produce proper bilevel images.
+
+2002-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Apply prefix/suffix transformations to ImageMagick program names
+ which are substituted into delegates.mgk. This fix was requested
+ by Glenn Randers-Pehrson.
+
+2002-08-25 Cristy <cristy@mystic.es.dupont.com>
+
+ - Arcs are now rendered properly.
+
+ - Use -authenticate to specifiy a password when viewing encrypted
+ PDF's.
+
+ - -page was previouly being ignored.
+
+ - Configure files are returned as blobs now (suggested by William
+ Radcliffe).
+
+2002-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added --disable-installed option to configure to support
+ building an ImageMagick which is not installed via hard-coded
+ paths. This is intended to be used for the ad-hoc binary
+ distributions built by ImageMagick Studio.
+
+ - The UseInstalledImageMagick define is to be used by builds
+ formally installed under a prefix, or via the Windows registry.
+
+ - Replaced GetMagickConfigurePath() with the three functions
+ FindConfigurationFile(), FindFontFile(), and FindModuleFile().
+
+ - Re-implemented InitializeMagick() to try harder at finding the
+ uninstalled ImageMagick without the help of MAGICK\_HOME. In the
+ future, it can try even harder.
+
+ - Unix binaries packages (built with --disable-installed) should
+ now work using the same file layout as the distribution file.
+ There is no longer a need to put all files in the same directory.
+
+2002-08-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Under Windows, define UseInstalledImageMagick to locate
+ components using the registry rather than scanning the filesystem.
+
+2002-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added DrawSetTextEncoding() function to specify text encoding
+ (e.g. "UTF-8").
+
+2002-08-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Extend `convert -list type` output so it prints more details.
+
+ - Fix draw.c problem when specifying font family names that
+ contain spaces.
+
+2002-08-15 Cristy <cristy@mystic.es.dupont.com>
+
+ - Finished 32-Bit QuantumDepth support.
+
+ - Subimage memory leak fixed (bug report by William Radcliffe).
+
+ - Fixed subimage specification memory overrun.
+
+ - Subimage specification did not work properly under Windows.
+
+2002-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fix problem with TEXT encoder. It was prepending the filename
+ to the text.
+
+2002-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Render Postscript via Ghostscript DLL (gsdll32.dll) under
+ Windows if it can be loaded. Only ps.c currently uses this to
+ verify there are no problems.
+
+2002-08-14 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added 16-bit raw write support to PPM.
+
+2002-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Re-implemented ReadTTFImage() using the draw.h APIs.
+
+2002-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fixed a libtool bug in order to allow passing -m64 to allow
+ building 64-bit ImageMagick using gcc 3.1 or later under SPARC
+ Solaris.
+
+2002-08-04 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added experimental 32-bit QuantumDepth pixel support.
+
+ - Stream support was not thread-safe (bug report by William Radcliffe).
+
+ - Push/PopImagePixels() now recognizes the proper buffer length
+ (previously it operated on one scanline at a time).
+
+ - Deprecated Down/Upscale defines. Replaced them with
+ Scale\*ToQuantum() and ScaleQuantumTo\*() methods.
+
+2002-08-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Changed configure argument --disable-16bit-pixel to
+ --with-quantum-depth in order to make its usage more
+ straightforward and generic. Build ImageMagick using an eight-bit
+ quantum via --with-quantum-depth=8.
+
+ - Magick++ library builds as a DLL under Windows now.
+
+2002-07-31 Cristy <cristy@mystic.es.dupont.com>
+
+ - Delegates/modules are restricted to hard-coded search paths (a
+ security feature suggested by Bob Friesenhahn).
+
+2002-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added SubstituteString to utility.c for performing substitions
+ on strings.
+
+ - Added support for performing Ghostscript-related substitutions
+ while reading delegates.mgk and type.mgk files.
+
+2002-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added the Windows utility functions NTGhostscriptDLL(),
+ NTGhostscriptEXE(), and NTGhostscriptFonts(), to find the DLL,
+ executable, and font directory corresponding to the newest
+ Ghostscript install on the system.
+
+2002-07-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Split nt.c into ntbase.c and ntfeature.c
+
+ - Split nt.h into ntbase.h and ntfeature.h
+
+ - Invoke NTIsMagickConflict() under Cygwin to ensure that drive
+ letters in file specifications are not confused with magick
+ strings.
+
+ - Invoke NTGetTypeList() under Cygwin to read the list of Windows
+ fonts.
+
+2002-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Created Windows "setup.exe" style installation package for
+ ImageMagick.
+
+ - Include PerlMagick Perl extension for ActiveState ActivePerl as
+ checkmark install option in Windows installation package.
+
+ - Include ImageMagickObject OLE Object for WSH and Visual Basic
+ (not IIS!!!) as checkmark install option in Windows installation
+ package.
+
+ - Windows installation package establishes file extension
+ associations for ImageMagick.
+
+2002-07-17 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - PPM files were being written in P4 or P5 format if all pixels
+ were gray. This is correct behavior for the PNM format but not
+ for the PPM format.
+
+2002-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Load font information from Windows rather than depending on hand
+ edited type-windows.mgk file. Still not incorporated in Cygwin
+ build.
+
+2002-07-04 Cristy <cristy@mystic.es.dupont.com>
+
+ - Typos corrected in perl.html (thanks to Ron Savage);
+
+ - A color profile is now correctly referred to as ICM instead of
+ IPTC.
+
+ - Added XPM color compliance to colors.mgk.
+
+ - $image->Get(`clip-mask`) now returns the clipping image.
+
+2002-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added NTRegistryKeyLookup() to nt.c in order to look up
+ ImageMagick installation parameters from the Windows Registry.
+
+ - Updated GetMagickConfigurePath() in magick.c to use installation
+ path data from the Windows Registry (if available).
+
+ - Updated VisualMagick/ImageMagick.iss so that Windows Registry is
+ updated by install package.
+
+2002-07-03 Cristy <cristy@mystic.es.dupont.com>
+
+ - Semaphore.c will compile now when pthreads are not present.
+
+ - 8-Bit Quantum PCD images now read correctly.
+
+ - The antialias member of the ImageInfo structure was not being
+ cloned.
+
+2002-07-01 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick 5.4.7 released.
+
+2002-06-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt.c (readdir): Make readdir re-entrant for each instance
+ of DIR. This should improve thread safety.
+
+ - ltdl/ltdl.c : Support building as DLL under Win32.
+
+2002-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Update to use Automake 1.6.2
+
+2002-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Try harder when searching for Ghostscript fonts under Linux.
+
+2002-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Identify PICT files via magic.mgk.
+
+2002-06-18 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added PerlMagick threading support (patch by Doug MacEachern).
+
+2002-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - CLIPBOARD and EMF modules compile under MinGW and Cygwin.
+
+2002-06-14 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - The wbmp writer would dump core if it received a DirectClass
+ image that contained only black and white pixels, because no
+ colormap exists.
+
+2002-06-09 Cristy <cristy@mystic.es.dupont.com>
+
+ - Label color could not be set (bug report by Ron Savage).
+
+ - Added CatchException() method to magick/error.c.
+
+2002-06-06 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick, version 5.4.6-1 released.
+
+2002-06-05 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added -encoding option to command line utilities.
+
+2002-06-02 Cristy <cristy@mystic.es.dupont.com>
+ - ImageMagick, version 5.4.6 released.
+
+2002-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ImageMagick may now be built (static build only) using the free
+ MinGW development package from http://www.mingw.org. Leonard's
+ "clipboard" coder is included in the build.
+
+2002-05-28 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Added new "clipboard" coder for reading/writing the system's
+ clipboard. Currently this is only implemented on Windows. For
+ example: `convert logo: clipboard:`, `convert clipboard: foo.png`.
+
+2002-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Support autotrace via delegates.mgk. For example: `convert
+ autotrace:file.png file.mvg`.
+
+2002-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added progress monitor support to DrawImage().
+
+2002-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added progress monitor support to wmf.c.
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added EscapeText() to utility.c to support escaping text.
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Text escaping for -draw and DrawAnnotation was not working
+ properly. Now it does. Backslash should act as a escape for the
+ the active quote character (', ", or }) as well as backslash. The
+ backslash should be discarded if it was used as an escape
+ character. In order to reliably pass a backslash, two successive
+ backslashes are required
+ (e.g. "\\").
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Modified Base64Encode() of utility.c so that it returns the
+ number of characters encoded. This avoids having to invoke
+ strlen() on possibly megabytes of data.
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fixed compilation error with Sun Workshop compiler (wmf.c).
+
+2002-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Implement polypolygon support in WMF renderer. Requires libwmf
+ 0.2.4 with draw\_polypolygon IPA callback.
+
+2002-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added --enable-ccmalloc configure option.
+
+2002-05-09 Cristy <cristy@mystic.es.dupont.com>
+
+ - DCM patch provided by Shane Blackett.
+
+2002-05-07 Cristy <cristy@mystic.es.dupont.com>
+
+ - Lock mutex when destroying a SemaphoreInfo structure (patch
+ provided by William Radcliffe).
+
+ - Added mingw patches provided by Derry Bryson.
+
+2002-05-05 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick, version 5.4.5-1 released.
+
+2002-04-30 Cristy <cristy@mystic.es.dupont.com>
+
+ - Subimage specification did not work for TIFF (e.g. convert
+ `image.tiff[1]` image.png).
+
+2002-04-30 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick, version 5.4.5 released.
+
+2002-04-20 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added magic string detection for the FPX format (patch provided by
+ Marc).
+
+2002-04-18 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added ExceptionInfo parameter to C API method,
+ QueryColorDatabase().
+
+2002-04-17 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Fixed all known bugs with the IMDisplay utility for Windows.
+
+2002-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac (libtool\_build\_static\_libs): Added
+ --enable-delegate-build option to suuport building ImageMagick
+ using delegate libraries in subdirectories of the ImageMagick
+ source directory.
+
+2002-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - WMF now supplies bitmaps as inline images rather than via a mpri
+ reference.
+
+2002-04-15 Cristy <cristy@mystic.es.dupont.com>
+
+ - Fixed DrawImage() to properly handle affine image transforms.
+
+ - Added AffineTransformImage() to C API.
+
+ - Added -transform option to convert/mogrify program.
+
+2002-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (MagickToMime): New method to return the MIME
+ media type corresponding to a specified magick tag.
+
+2002-04-12 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Fixed a bug in writing layer names in PSD files.
+
+2002-04-10 Cristy <cristy@mystic.es.dupont.com>
+
+ - Fixed PingImage() memory leak (thanks to Timo Vogel).
+
+ - Added encoding and unicode attributes to PerlMagick (patch
+ provided by Youki Kadobayashi).
+
+2002-04-08 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added reference counted blobs.
+
+ - Added MagickFatalError() and SetFatalErrorHandler() to the C
+ API.
+
+ - One color images caused memory corruption in QuantizeImage()
+ (thanks to Vincent Broz).
+
+ - Memory leak in NormalizeImage() (thanks to Vincent Broz).
+
+2002-04-06 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Added CCIS-601 4:2:2 YUV format read-write support.
+
+ - Added CCIS-601 4:2:2 MPEG-2 format write support.
+
+ - Fixed a bug introduced in 5.4.0 that caused files with "M2V"
+ suffix to be written in MPEG-1 instead of MPEG-2 format.
+
+2002-03-28 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageToBlob() only returned the first frame of a multi-frame
+ image.
+
+2002-04-05 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Fixed inversion of colors when converting CMYk JPEG to PDF
+
+2002-04-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fixed TTF preview function.
+
+2002-03-28 Cristy <cristy@mystic.es.dupont.com>
+
+ - DCM patches provided by Syam Gadde.
+
+ - Multi-frame MPC image files caused a fault under Windows.
+
+ - Copy entire comment from SVG (bug report from Bob Friesenhahn).
+
+ - Enlarged scanline buffer for JPEG-compressed TIFF's (bug report
+ from Bob Friesenhahn).
+
+2002-03-27 Cristy <cristy@mystic.es.dupont.com>
+
+ - ImageMagick, version 5.4.4, released.
+
+2002-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added preliminary version of C API for vector drawing commands
+ (draw.h & draw.c). This interface is subject to change, and has
+ not even been tested yet so it should not be used to support
+ production code. The previous draw.h and draw.c have been renamed
+ to render.h and render.c respectively.
+
+2002-03-25 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - Fixed bugs related to layered CMYK PSD images.
+
+2002-03-13 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - PSD coder now saves layer information (name, offset & opacity)
+ in hidden attributes.
+
+2002-03-13 Cristy <cristy@mystic.es.dupont.com>
+
+ - Enhanced MPC to read/write image sequences.
+
+2002-03-13 Cristy <cristy@mystic.es.dupont.com>
+
+ - A number of formats (e.g. JPEG, PS) did not handle DirectClass
+ grayscale images properly.
+
+2002-03-12 Cristy <cristy@mystic.es.dupont.com>
+
+ - Changed Clone\*Info() API so structure members are set directly rather
+ than by the \*clone=\*info method (suggested by William Radcliffe).
+
+2002-03-11 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added AcquireString() to allocate read-only strings.
+
+2002-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/null.c (WriteNULLImage): Support writing "null:" image
+ type for use when profiling or testing ImageMagick.
+
+2002-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Update to Autoconf 2.53 (new release)
+
+ - Update to Automake 1.6 (new release)
+
+2002-03-07 Cristy <cristy@mystic.es.dupont.com>
+
+ - Bob Friesenhahn's execution profile results in a number of
+ speed-ups with a faster LocaleCompare() algorithm and
+ self-adjusting lists.
+
+ - Recognize additional DCM metadata (suggested by Barry Branham).
+
+ - Fixed CopyOpacity composite operator for CMYKA images.
+
+2002-03-06 Cristy <cristy@mystic.es.dupont.com>
+
+ - Inlined AlphaComposite() and ValidateColormapIndex().
+
+ - Corrected compositing algorithm for the case where both source
+ and destination pixels had opacity values that were neither fully
+ transparent nor fully opaque.
+
+2002-03-05 Cristy <cristy@mystic.es.dupont.com>
+
+ - Memory overrun when drawing large circles.
+
+2002-03-04 Cristy <cristy@mystic.es.dupont.com>
+
+ - Removed bug introduced into Bob's Base64Encode() method.
+
+2002-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Added Base64Decode() and Base64Encode() to utility.c and updated
+ ReadInlineImage() in magick/constitute.c to use Base64Decode().
+
+2002-03-01 Cristy <cristy@mystic.es.dupont.com>
+
+ - GetTypeInfoByFamily() null pointer fault (reported by Bob
+ Friesenhahn).
+
+ - Added module version number (patch by Glenn Randers-Pehrson).
+
+2002-03-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - image->matte was not being set when reading GRAY-ALPHA PNG
+ files.
+
+2002-02-26 Cristy <cristy@mystic.es.dupont.com>
+
+ - Potential infinite loop in SyncBlob() (reported by Vladimir
+ Faiden).
+
+2002-02-26 Cristy <cristy@mystic.es.dupont.com>
+
+ - Gravity not respected when drawing text with the convert
+ program.
+
+2002-02-21 Cristy <cristy@mystic.es.dupont.com>
+
+ - MPEG multi-part filenames require an embedded %d, not %lu.
+
+ - WriteStream() did not write to fifo (thanks to William
+ Radcliffe).
+
+2002-02-20 Cristy <cristy@mystic.es.dupont.com>
+
+ - Annotation did not support SJIS properly (patch provided by
+ Katsutoshi Shibuya).
+
+2002-02-18 Cristy <cristy@mystic.es.dupont.com>
+
+ - Fixed memory overrun with -format option of the mogrify program.
+
+ - Labels were not positioned correctly for VID format.
+
+2002-02-16 Cristy <cristy@mystic.es.dupont.com>
+
+ - Replaced -copy/-replace options with +/-write in the convert
+ program.
+
+ - Median filtering speed enhancement using skip list contributed
+ by Mike Edmonds.
+
+2002-02-14 Cristy <cristy@mystic.es.dupont.com>
+
+ - Command line options now stay in effect for any image in command
+ line order until a another option is encountered or if -noop is
+ specified.
+
+2002-02-07 Cristy <cristy@mystic.es.dupont.com>
+
+ - SVG coders understands inline images.
+
+2002-02-06 Cristy <cristy@mystic.es.dupont.com>, Glenn Randers-Pehrson
+
+ - Made -scene consistent across all utilities. -snaps replaces
+ previous functionality of -scene for import program.
+
+2002-01-30 Cristy <cristy@mystic.es.dupont.com>
+
+ - Correctly draw arc when arc end/start are not integer
+ (patch contributed by Giuliano Pochini).
+
+2002-01-28 Cristy <cristy@mystic.es.dupont.com>, Glenn Randers-Pehrson
+
+ - Geometry strings respect -gravity (e.g. -gravity SouthWest -crop
+ 100x100).
+
+ - Postive offsets in geometry strings move within the image canvas
+ with respect to the gravity (SouthWest gravity is similar to
+ Postscript page offsets).
+
+2002-01-24 Cristy <cristy@mystic.es.dupont.com>
+
+ - Use -trim to trim the edges of an image.
+
+ - Palm pixmap supported contributed by Christopher R. Hawks.
+
+ - Added -mask to the convert/mogrify programs to add clips masks
+ to an image.
+
+2002-01-21 Cristy <cristy@mystic.es.dupont.com>
+
+ - Fixed occasional small memory leak associated with exceptions.
+
+ - Persistent cache is no longer updated (MPC coder).
+
+2002-01-20 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Fixed some bugs in the uncompressed PGM and PPM reader/writer
+ (pnm.c).
+
+2002-01-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Removed test for libwmf/font.h.
+
+2002-01-13 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - More bug fixes and improvements in PSD writer.
+
+2002-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magic.mgk: Added entries for detecting PFA and PFB
+ formats. Is this file used for anything anymore?
+
+ - coders/modules.mgk: Add support for PFA fonts.
+
+ - coders/ttf.c (RegisterTTFImage): Add support for PFA fonts.
+
+ - magick/annotate.c (RenderType): Add support for PFA fonts.
+
+2002-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Modified type.mgk so that it may include the additional files
+ type-windows.mgk, type-solaris.mgk, and type-ghostscript.mgk
+ depending on the operating system used, and the font files
+ available.
+
+2002-01-11 Leonard Rosenthol <leonardr@lazerware.com>
+
+ - PSD now supports writing layered images and IPTC data
+
+ - Fixed some bugs in XCF
+
+2002-01-11 Cristy <cristy@mystic.es.dupont.com>
+
+ - Added image list methods to the API.
+
+2002-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac : Renamed configure option --with-ttf-fontpath to
+ --with-fontpath since ImageMagick loads more than TrueType fonts.
+
+ - ChangeLog : Renamed Changelog.txt to ChangeLog in order to
+ conform to GNU and open-source standards.
+
+2002-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am : $(DESTDIR) already contains trailing `/`.
+
+2002-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c (wmf\_magick\_device\_begin): Fix non-opaque fills.
+ Now properly fills with texture image.
+
+2002-01-05 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Fixed an out-of-bounds memset() and two other memory overruns
+ when decoding 1-bit AVI, BMP, and DIB images.
+
+2002-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fix lcms header inclusion in transform.c.
+
+2002-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c (magick\_brush): Fixed bug with setting fill color.
+
+2002-01-03 Cristy <cristy@mystic.es.dupont.com>
+
+ - Postscript Level II is now DCS compliant.
+
diff --git a/www/ChangeLog-2003.html b/www/ChangeLog-2003.html
new file mode 100644
index 0000000..9b426dd
--- /dev/null
+++ b/www/ChangeLog-2003.html
@@ -0,0 +1,4764 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2003-12-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/annotate.c (RenderFreetype): Ensure that image storage
+class is set to DirectClass. Text rendering was not working
+properly on top of PseudoClass images.</li>
+<li>magick/map.c (MagickMapRemoveEntry): Logic didn't properly
+handle removing entry in list.</li>
+<li>configure.ac: Added --enable-efence option to enable memory
+debugging using Electric Fence.</li>
+</ul>
+</blockquote>
+<p>2003-12-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/maptest.c (main): Extended test to add an entry to the
+list after an entry has already been removed.</li>
+<li>magick/image.c (ColorspaceTypeToString): Add support for LAB
+colorspace.</li>
+<li>magick/map.c: Added signature members to all structures and
+added assertions to ensure that the signature == MagickSignature
+prior to use. MagickMapAllocateObject now initializes the object
+reference count to one, and MagickMapDestroyObject decrements it
+in order to be more correct even though the object reference count
+is not actually used yet.
+(MagickMapCopyString): Preserve a null argument, and use
+AcquireString since it doesn't enlarge the string storage.
+(MagickMapCopyBlob): Preserve null blobs.</li>
+<li>configure.ac: Search for the shmctl() function. Under current
+Cygwin, this is hiding in -lcygipc.</li>
+</ul>
+</blockquote>
+<p>2003-12-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c: Fixed the composite operator list in the
+CompositeImage documentation.</li>
+<li>www/api/types.html: Corrected list of composition
+operators. Sometime prior to the creation of GraphicsMagick, the
+&quot;Replace&quot; composite operators were renamed to be &quot;Copy&quot; composite
+operators. Thanks to David Relson for bringing this problem to
+our attention.</li>
+<li>PerlMagick/Magick.xs: Added &quot;LAB&quot; to colorspace types.</li>
+<li>magick/image.h (enum ColorSpace): Add LABColorspace enumeration.</li>
+<li>wand/magick_wand.h : Add some compatibility definitions to
+translate from ImageMagick enumerations to existing GraphicsMagick
+enumerations.</li>
+</ul>
+</blockquote>
+<p>2003-12-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/annotate.c: Use header synonyms defined by FreeType's
+ftheader.h (included via &lt;ft2build.h&gt;) to include FreeType headers.
+This will presumably be more portable in the future.</li>
+<li>configure.ac: &lt;ft2build.h&gt; is an optional prerequisite for
+&lt;freetype/freetype.h&gt; and &lt;libwmf/ipa.h&gt; so include it when
+testing for these headers.</li>
+<li>magick/annotate.c: Include &lt;ft2build.h&gt; if it is available.</li>
+</ul>
+</blockquote>
+<p>2003-12-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/wandtest.c: Ported from latest ImageMagick version.</li>
+<li>wand/drawing_wand.c: Adapted to be compatible with latest
+ImageMagick version.</li>
+<li>wand/pixel_wand.c: Adapted to be compatible with latest
+ImageMagick version.</li>
+<li>wand/magick_wand.c: Ported from latest ImageMagick version.</li>
+<li>magick/image.h (Image): Members color_profile, iptc_profile,
+generic_profile, and generic_profiles are now deprecated and
+private although they continue to work as before. Please migrate
+existing code to use the GetImageProfile and SetImageProfile
+functions since these members will eventually be removed.</li>
+<li>magick/image.c (GetImageProfile): New function to retrieve an
+image profile. Return value differs from similarly named
+ImageMagick method since the ImageMagick approach assumes a
+particular storage method.
+(SetImageProfile): New function to add (or remove) an image
+profile. Does not execute CMS color profiles.</li>
+<li>magick/cache.c (SetImageVirtualPixelMethod): Return unsigned int to
+make the Wand implementation happy.</li>
+<li>magick/image.c (TransformColorspace): Return unsigned int to
+make the Wand implementation happy.
+(SetImageType): Return unsigned int to make the Wand
+implementation happy.</li>
+<li>magick/draw.h, magick/draw.c: Substitute <cite>unsigned long</cite> in
+place of <cite>size_t</cite> in interfaces so that the draw API is not
+sensitive to the definition of _LP64.</li>
+<li>locale/C.mgk: Added new messages required by Wand library.</li>
+<li>magick/error.c (ExceptionSeverityToTag): Add tag translations
+for the WandWarning, WandError, &amp; WandFatalError enumerations</li>
+<li>magick/error.h (enum ExceptionType): Add WandWarning, WandError,
+&amp; WandFatalError enumerations to ExceptionType for ImageMagick
+API compatibility.</li>
+<li>magick/image.h (enum ChannelType): Add an <cite>AllChannels</cite>
+enumeration to the ChannelType enumeration for ImageMagick
+API compatibility.</li>
+</ul>
+</blockquote>
+<p>2003-12-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick, tests: Adjusted allowed error values for tests based
+on new error computation arithmatic. Some tests were left failing
+since the operation they test provides results which are
+unreasonably inaccurate, or obviously broken.</li>
+</ul>
+</blockquote>
+<p>2003-12-17 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: Changed &quot;JPEG:preserve-settings from a key/value
+pair to a simple flag. Save and restore attributes when
+&quot;-define JPEG:preserve-settings&quot; appears on the commandline. Use
+&quot;+define JPEG:preserve-settings&quot; to unset the flag.</li>
+</ul>
+</blockquote>
+<p>2003-12-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c: Include &lt;ft2build.h&gt; if it is available since some
+libwmf installs don't work unless it is included before the libwmf
+API headers.</li>
+<li>configure.ac: Check for &lt;ft2build.h&gt;.</li>
+</ul>
+</blockquote>
+<p>2003-12-16 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: Changed stored jpeg quality attribute from
+[jpeg-quality] to JPEG-Quality. Added attributes JPEG-Colorspace
+and JPEG-Sampling-factors. Added code to save and restore
+these attributes when &quot;-define JPEG:preserve-settings=yes&quot; is
+present in the comandline. Quality is restored if the input
+was a JPEG and the quality was preserved. Sampling factors
+are restored if the input was a JPEG, sampling factors were
+preserved, and the colorspace for the output file is the same
+as that of the input file.</li>
+</ul>
+</blockquote>
+<p>2003-12-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>TclMagick/source/configure.ac: Add an initial TclMagick
+configure-based build environment based on a template and macros
+from the Tcl project. I recall that while the extension does build,
+it is possible that it is not properly registered as a module to Tcl.</li>
+</ul>
+</blockquote>
+<p>2003-12-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (IsImagesEqual): Properly compute error distance
+vectors. Math was missing the necessary sqrt call. Also,
+pre-normalize the error differences to 1.0 in order to reduce the
+storage size required to store the summation of error values.</li>
+<li>PerlMagick/t/composite.t: Update Minus and Xor reference images.</li>
+<li>magick/composite.c (CompositeImage): Incorporated fixes from
+ImageMagick for XorCompositeOp, PlusCompositeOp, and
+MinusCompositeOp. Thanks to John Cristy for bringing the need for
+these fixes to our attention.</li>
+<li>magick/image.h (RoundToQuantum): Added missing parenthesis.</li>
+</ul>
+</blockquote>
+<p>2003-12-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/environment.imdoc: Document MAGICK_CODER_MODULE_PATH and
+MAGICK_FILTER_MODULE_PATH.</li>
+<li>rungm.sh.in: Pass MAGICK_CODER_MODULE_PATH and
+MAGICK_FILTER_MODULE_PATH in the environment so modules build may
+be tested without first being installed.</li>
+<li>magick/module.c (FindMagickModule): Use the
+MAGICK_CODER_MODULE_PATH environment variable to specify a search
+path for coder modules. Use MAGICK_FILTER_MODULE_PATH to specify
+a search path for filter modules.</li>
+<li>Makefile.am: Updated to Automake 1.8.
+(install-exec-perl): Fixes which achieve a successful
+<cite>make distcheck</cite> for the first time in *Magick history.</li>
+<li>configure.ac: Set scripts to executable.</li>
+</ul>
+</blockquote>
+<p>2003-12-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (uninstall-data-html): Pathnames were computed
+incorrectly so documentation directories were being left behind.</li>
+<li>configure.ac: --without-frozenpaths is now the default. This
+helps <cite>make distcheck</cite> work and makes the package more portable.
+Path to gm was being incorrectly frozen when --without-frozenpaths
+was specified.</li>
+<li>magick/delegate.c (ReadConfigureFile): Validate delegate paths
+prior to substitution.</li>
+<li>rungm.sh.in (top_builddir): Use a more reliable scheme for
+computing location of source and build directories.</li>
+<li>magick/Makefile.am: Improve include directory computation logic.</li>
+<li>configure.ac: Don't override includedir. Pass user-supplied LIBS
+to the linker.</li>
+</ul>
+</blockquote>
+<p>2003-12-08 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: store JPEG quality as &quot;[jpeg_quality]&quot; attribute.</li>
+</ul>
+</blockquote>
+<p>2003-12-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>rungm.sh.in: New script to support executing uninstalled
+executables.</li>
+<li>magick/blob.c (GetConfigureBlob): New MAGICK_CONFIGURE_PATH
+environment variable allows the user to specify the search path
+for configuration (.mgk) files.</li>
+</ul>
+</blockquote>
+<p>2003-12-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>index.html: Added a table showing current stable release and
+development version.</li>
+</ul>
+</blockquote>
+<p>2003-12-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc (use): Describe the syntax of the -process
+argument.</li>
+<li>acinclude.m4 (AC_CHECK_CC_OPT): Add quoting in AC_CHECK_CC_OPT
+definition. Change suggested by Patrick Welche</li>
+</ul>
+</blockquote>
+<p>2003-12-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (GetMagickInfo): Fix preprocessing logic error
+which caused moby shared library build to not register static
+modules.</li>
+</ul>
+</blockquote>
+<p>2003-12-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/module.c (ExecuteModuleProcess): Add some logging.</li>
+<li>magick/static.c (ExecuteStaticModuleProcess): Add some logging.</li>
+</ul>
+</blockquote>
+<p>2003-11-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer: Add optional build support for LZW.</li>
+<li>wand/Makefile.am: Add AUTOMAKE_OPTIONS.</li>
+<li>configure.ac: Update to Autoconf 2.59.</li>
+</ul>
+</blockquote>
+<p>2003-11-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/tasks-install-perlmagick.isx: Update
+to reflect that the next release will use ActivePerl 5.8.1 Build
+807.</li>
+<li>VisualMagick/installer/inc/files-configs.isx: Updated the source
+locations for the .mgk files. Install modules.mgk into the config
+directory rather than the modules directory.</li>
+<li>configure.ac: Fixes to work with latest CVS libtool.</li>
+<li>libtool.m4: Update to latest CVS libtool.</li>
+<li>magick/modules.c, magick/static.c (ExecuteStaticModuleProcess):
+Fix conditional compilation logic so that &quot;moby&quot; shared library
+build works again.</li>
+<li>magick/compress.c, magick/mac.c: Use existing SaveImageText and
+LoadImageText global constants rather than separate defines.</li>
+</ul>
+</blockquote>
+<p>2003-11-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Update to Autoconf 2.58.</li>
+<li>Makefile.am: Update to Automake 1.7.9.</li>
+</ul>
+</blockquote>
+<p>2003-11-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/draw.c (DrawComposite): Base64-encoded image was not
+being deallocated. Bad memory leak.</li>
+</ul>
+</blockquote>
+<p>2003-11-03 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick: Updated installation procedure. Please read
+BCBMagick/readme.txt for details.</li>
+</ul>
+</blockquote>
+<p>2003-11-03 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick: Released DLL Version. Please read BCBMagick/readme.txt
+for details about installation and/or use.</li>
+</ul>
+</blockquote>
+<p>2003-11-03 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetPathComponent): Added x, X, and +
+characters to list of legal characters in subimage
+specifications. Required by raw RGB image reader which accepts the
+syntax &quot;image.rgb[100x100+50+50]&quot;. Thanks to John Cristy for
+catching that one.</li>
+</ul>
+</blockquote>
+<p>2003-11-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/locale.c (GetLocaleMessageFromID): Fix ID range checking
+logic.</li>
+</ul>
+</blockquote>
+<p>2003-10-30 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: changed to not write gray CMYK images as
+grayscales. That would not be a valid optimization.</li>
+<li>magick/color.c (IsGrayImage, IsMonochromeImage): Changed to
+never return true for CMYK images. Separated images get wrong
+colors when optimized to grayscales based on what these two
+functions return. Gray and CMYK are two different color spaces.</li>
+<li>magick/nt_feature.c (NTIsMagickConflict): changed to accept
+colon as part of the magick string, consistent with the way the
+function is used.</li>
+<li>magick/utility.c, magick/utility.h (ExpandFilenames,
+GetPathComponent): Fixed filename glob expansion. Added handling
+of filename prefix-magick and sub-image specification to
+GetPathComponent. Sub-image specification takes precedence over
+any filename patterns.</li>
+</ul>
+</blockquote>
+<p>2003-10-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/static.c (ExecuteModuleProcess): Renamed from
+ExecuteStaticModuleProcess. Only compiled if SupportMagickModules
+is not defined.</li>
+<li>magick/type.c (GetTypeBlob): Eliminated function.
+(ReadTypeConfigureFile): Use GetConfigureBlob() rather than
+GetTypeBlob().</li>
+<li>magick/module.c (GetModuleBlob): Eliminate this function since
+modules.mgk is now installed under
+${prefix}/share/GraphicsMagick-version/config so
+GetConfigureBlob() may be used.
+(lt_dlexit, etc.) Eliminate fake libltdl function wrappers used
+for the static build.
+(DestroyMagickModules): Added a new destroy function (simply
+invokes DestroyModuleInfo()).
+(GetModuleList): Learn where modules live by using
+FindMagickModule() to locate the LOGO module rather than by using
+the location of modules.mgk. This is necessary since now
+modules.mgk may be seperate from the modules.
+(GetModuleBlob): Eliminated function.
+(InitializeMagickModules): New function to safely initialize the
+module loader.
+(OpenModule): Added logging messages.
+(OpenModules): Added logging messages.
+(ReadModuleConfigureFile): Use GetConfigureBlob() rather than
+GetModuleBlob().
+Totally eliminated the rat's-nest of conditional code dependent on
+SupportMagickModules. Now all the code in module.c is dependent
+on #if defined(SupportMagickModules).</li>
+<li>magick/magick.c (DestroyMagick): Invoke DestroyMagickModules().
+(GetMagickInfo): #ifdef chunks of code which exist to support the
+modules-build rather than forcing the module loader to pretend
+that modules are being used when they are not. Pass module loading
+exceptions back to the user rather than discarding them.
+(GetMagickInfoArray): Don't inspect the exception status since may
+short-circuits the operation. Use best-effort instead.
+(ListMagickInfo): Don't inspect the current exception status so
+that all the modules which did load successfully will be
+represented.
+(InitializeMagick): Invoke InitializeMagickModules().</li>
+<li>magick/log.c: (GetLogBlob): Eliminated function.
+GetConfigureBlob() is safe to use now when configuring logging.
+(LogToBlob): Simplified function. Only exists since FileToBlob()
+may throw exceptions (which are logged, causing deadlock).
+(ReadLogConfigureFile): Use GetConfigureBlob().</li>
+<li>magick/blob.c (GetConfigureBlob): Re-written to use the
+MagickMap interface and to support the new <cite>lib</cite> and <cite>share</cite>
+config directories. The directory
+${prefix}/lib/GraphicsMagick-version/config is scanned before
+${prefix}/share/GraphicsMagick-version/config.
+(FileToBlob): Simplified implementation.</li>
+<li>config/Makefile.am: New makefile to install .mgk files.</li>
+<li>magick/magick_config.h.in: Added MagickLibConfigPath and
+MagickShareConfigPath defines.</li>
+<li>configure.ac: Install configuration files (.mgk files) in
+${prefix}/lib/GraphicsMagick-version/config and
+${prefix}/share/GraphicsMagick-version/config. Architecture
+independent files to under &quot;share&quot; while architecture dependnet
+files go under &quot;lib&quot;.</li>
+<li>Makefile.am: Added <cite>config</cite> subdirectory to distribution. All
+.mgk files are moved from <cite>coders</cite> &amp; <cite>magick</cite> into this single
+directory.</li>
+</ul>
+</blockquote>
+<p>2003-10-21 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h: small modifications to achieve DLL
+compilation of library with Borland C++ Builder.</li>
+<li>coders/ps3.c (ZLIBEncode2Image): Fixed bug. Compilation
+fail when HasZLIB is undefined because parameters 5 and 6,
+are undefined.</li>
+</ul>
+</blockquote>
+<p>2003-10-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libtool.m4: Updated libtool again to CVS latest version.
+Libtool required some fixes for building DLLs under MinGW.</li>
+<li>magick/resource.c (InitializeMagickResources): Some code is
+conditional based on HAVE_POPEN.</li>
+<li>magick/utility.c (SystemCommand): Improved conditional
+compilation logic.</li>
+<li>magick/blob.c (OpenBlob): Code depending on popen() is
+conditionally compiled based on HAVE_POPEN. Code depending on
+pclose() is conditionally compiled based on HAVE_PCLOSE.</li>
+<li>configure.ac: Add test for _pclose(), pclose(), _popen(), and
+popen().</li>
+<li>magick/locale.c (GetLocaleMessage): Add missing MagickExport.
+(GetLocaleMessageFromID): Add missing MagickExport.</li>
+<li>VisualMagick/installer/inc/files-development.isx (Source):
+Include all of the headers from the magick directory in the
+development package. Including them individually is too error
+prone.</li>
+</ul>
+</blockquote>
+<p>2003-10-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/magick/magick_config.h.in: Added
+PREFIX_MAGICK_SYMBOLS as a configuration option.</li>
+<li>magick/module.c (_CoderInfo): Added register_function and
+unregister_function members to record the module's register and
+unregister function addresses.
+(OpenModule): Locate the module's register and unregister
+functions and save their address to the module's CoderInfo record.
+(UnloadModule): Invoke the module unregister function using the
+address recorded by OpenModule().
+(TagToFunctionName): If PREFIX_MAGICK_SYMBOLS is defined, then add
+a &quot;Gm&quot; prefix to the register and unregister function names.</li>
+<li>libtool: Updated libtool files to the latest CVS version.</li>
+<li>configure.ac: Changed define name from MAGICK_SYMBOL_PREFIX to
+PREFIX_MAGICK_SYMBOLS since support is not available for
+specifying an arbitrary prefix.</li>
+</ul>
+</blockquote>
+<p>2003-10-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Added --enable-symbol-prefix configure option
+which prepends &quot;Gm&quot; to all GraphicsMagick library symbols using
+the C pre-processor. In the future, this may change to support
+specifying an arbitrary prefix, depending on experience.</li>
+<li>magick/studio.h: Include magick/symbols.h.</li>
+<li>magick/api.h: Include magick/symbols.h.</li>
+<li>magick/symbols.h: New header to support optionally remapping
+library symbols. If MAGICK_SYMBOL_PREFIX is defined, then
+library symbols are remapped.</li>
+</ul>
+</blockquote>
+<p>2003-10-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/api.h: Removed inclusion of &lt;magick/semaphore.h&gt; since it
+is an implementation header.</li>
+</ul>
+</blockquote>
+<p>2003-10-13 Lars Skyum &lt;<a class="reference external" href="mailto:lrs&#37;&#52;&#48;stibo&#46;dk">lrs<span>&#64;</span>stibo<span>&#46;</span>dk</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/GraphicsMagick.html, www/animate.html, www/composite.html,
+www/conjure.html, www/convert.html, www/display.html, www/gm.html,
+www/identify.html, www/import.html, www/mogrify.html,
+www/montage.html: added documentation for &quot;-define&quot; command line
+option.</li>
+<li>doc/brief_options.imdoc, doc/options.imdoc: Added documentation
+for &quot;-define&quot; command line option.</li>
+<li>doc/gmdocselect, doc/imdocselect: Changed &quot;skipform&quot; label in
+sed scripts to just &quot;skipf&quot;. Solaris sed had problems with the
+long(?) &quot;skipform&quot; label.</li>
+</ul>
+</blockquote>
+<p>2003-10-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/composite.imdoc, doc/options.imdoc, doc/GraphicsMagick.imdoc:
+Attempted to clarify the meaning of the compose arguments and how
+composition works, as well as eliminating use of hard-coded values like
+255.</li>
+<li>www/links.html: Added a link to Michael Still's article
+&quot;Graphics from the command line&quot;.</li>
+</ul>
+</blockquote>
+<p>2003-10-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/*.c: Updated module descriptions so that they accurately
+describe the module rather than saying &quot;Read/Write GraphicsMagick
+Image Format&quot;.</li>
+<li>coders/cineon.c: Fix source module description. Contrary to
+opinion, ImageMagick did not invent the Cineon X image format so
+description is now &quot;Read/Write Cineon X Image Format.&quot;</li>
+<li>magick/magic.mgk: Added a CINEON entry for the Cineon X image
+format.</li>
+<li>magick/static.c (RegisterStaticModules): Invoke
+RegisterCINEONImage().</li>
+<li>coders/modules.mgk: Map &quot;CIN&quot; magick to CINEON module.</li>
+</ul>
+</blockquote>
+<p>2003-10-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>locale/C.mgk: Added message for &quot;UnrecognizedCommand&quot;.</li>
+<li>magick/command.c (MagickCommand): No error was reported when a
+subcommand failed to be matched so <cite>gm foo</cite> would silently return.
+Now an error message is properly reported.</li>
+</ul>
+</blockquote>
+<p>2003-10-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Updated to Automake 1.7.8.</li>
+<li>various: Edits to eliminate minor issues detected by SGI C compiler.</li>
+<li>coders/ps3.c (WritePS3Image): Variable <cite>value</cite> was set but never
+used so it is removed.</li>
+<li>magick/image.c (RGBTransformPacket): Removed inline request
+since this function is too big to inline.</li>
+<li>magick/animate.c (XAnimateBackgroundImage): Fixed a GCC 3.X
+&quot;type pinning&quot; warning.</li>
+<li>magick/display.c (XDisplayBackgroundImage): Fixed a GCC 3.X
+&quot;type pinning&quot; warning.</li>
+<li>magick/render.c (GetPixelOpacity): Removed inline directive. No
+one in their right mind could ever imagine this function inlining
+successfully.</li>
+<li>magick/cache.c (IsNexusInCore): Adjusted so function inlines as
+requested.</li>
+<li>coders/tiff.c (ReadTIFFImage): Improved logging information.
+(WriteTIFFImage): Changed the way the bilevel/grayscale logic
+works. Now bilevel images are treated similar to any other
+grayscale image unless CCITT FAX3 or FAX4 compression is requested
+(which selects the MINISWHITE photometric). The default is now to
+write uncompressed bilevel images with MINISBLACK photometric.</li>
+<li>PerlMagick/t/composite.t: Use some reasonable error values.</li>
+<li>magick/image.c (GetImageDepth): Added special cases for
+colormapped images and monochrome images in order to improve
+performance.</li>
+</ul>
+</blockquote>
+<p>2003-10-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: added info about color scaling, sampling-factor, and
+changed a reference to &quot;-coder-options&quot; to &quot;-define&quot;.</li>
+</ul>
+</blockquote>
+<p>2003-10-09 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/bin/modules.mgk: added EPS3 mapping to PS3 module.</li>
+<li>coders/ps3.c, coders/tiff.c, magick/command.c, magick/image.c,
+magick/image.h, magick/utility.c: Changed -coder-options option to
+-define. Also renamed functions {Add,Remove,Access}CoderOption(s)
+to {Add,Remove,Access}Definition(s). Changed ps coder-specific
+option ps:image=imagemask to just ps:imagemask.</li>
+</ul>
+</blockquote>
+<p>2003-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/cineon.c: Imported and adapted Cineon image format coder
+written by Kelly Bergougnoux &lt;<a class="reference external" href="mailto:three3&#37;&#52;&#48;users&#46;sourceforge&#46;net">three3<span>&#64;</span>users<span>&#46;</span>sourceforge<span>&#46;</span>net</a>&gt; with
+assistance from John Cristy.</li>
+</ul>
+</blockquote>
+<p>2003-10-08 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: Extended -sampling-factor option to allow
+user to supply full set of sampling factors. If the full
+set is not supplied, omitted ones are 1x1 by default, similar
+to the behavior of &quot;cjpeg -sample&quot;.</li>
+<li>magick/command.c: Accept multiple pairs of sampling factors.</li>
+</ul>
+</blockquote>
+<p>2003-10-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Re-arranged logging for improved
+output. Cleaned up evaluation of SAMPLESPERPIXEL and
+BITSPERSAMPLE. Provided support for the TIFF coder options
+tiff:samples-per-pixel and tiff:bits-per-sample for power users.
+(ReadTIFFImage): Colormap generation for PHOTOMETRIC_MINISBLACK
+and PHOTOMETRIC_MINISWHITE was inaccurate. Seems to be accurate
+now.</li>
+<li>PerlMagick/t/reference/read/input.miff: Updated due to Glenn's
+change to scale macros.</li>
+<li>PerlMagick/t/tiff/input_gray_12bit.tiff: Replaced 12 bit image
+with a different one which is written by GraphicsMagick.</li>
+<li>coders/ps3.c (WritePS3Image): Use AccessCoderOption().</li>
+<li>magick/image.c (AccessCoderOption): Added a function to use for
+accessing coder-specific options.</li>
+</ul>
+</blockquote>
+<p>2003-10-08 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (TraceSVGClippingPath): optimized for speed
+and precision in clipping mask generation by using lines to
+connect Bezier curve anchor points where applicable.</li>
+</ul>
+</blockquote>
+<p>2003-10-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Revised ScaleColor5to8 and ScaleColor6to8 macros again, to
+fill the low bits correctly.</li>
+</ul>
+</blockquote>
+<p>2003-10-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/tiff/read.t: Added 16-color and 256 color
+colormapped tests with a matte channel.</li>
+<li>PerlMagick/t/tiff/write.t: Added 16-color and 256 color
+colormapped tests with a matte channel.</li>
+<li>coders/tiff.c (WriteTIFFImage): When using LZW compression,
+apply the horizontal differencing predictor to RGB truecolor and
+deep gray images since the TIFF spec says that LZW compression is
+usually improved by using horizontal differencing with continuous
+tone images.
+Re-implemented grayscale and colormapped scanline preparation to
+use the new bit-stream interface. This is a bit slower, but very
+flexible, and the implementation is very compact. Writing of a
+matte (transparency) channel is now believed to be correct for all
+depths.</li>
+<li>magick/command.c (MogrifyImage): Only transform the colorspace
+if it has been set (i.e. is not UndefinedColorspace).</li>
+</ul>
+</blockquote>
+<p>2003-10-06 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): PNG decoder would exit too
+early when reading image.png[0].</li>
+</ul>
+</blockquote>
+<p>2003-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/tiff/write.t: Added TIFF write tests for 4
+bits-per-sample TIFF images, both with and without a transparency
+channel.</li>
+<li>magick/image.c (DescribeImage): Added -verbose support for
+displaying individual channel depths.</li>
+</ul>
+</blockquote>
+<p>2003-10-06 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): cleaned up parsing of subimage
+specification (image.psd[0]). It would fail sometimes due to
+incorrect reuse of variables. It's a bit strange the code accepts
+more range syntax-variations than can be stored in ImageInfo.</li>
+</ul>
+</blockquote>
+<p>2003-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (ChannelImage): The OpacityChannel, MatteChannel,
+and BlackChannel operations set the matte channel to opaque, so
+set image-&gt;matte to False for those operations.
+(RGBTransformImage): Add an assertion to prevent passing the
+colorspace argument <cite>UndefinedColorspace</cite>.
+(TransformRGBImage): Add an assertion to prevent passing an image
+with colorspace set to <cite>UndefinedColorspace</cite>.</li>
+</ul>
+</blockquote>
+<p>2003-10-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c (LogToBlob): Since MagickSeek(file,0,SEEK_END) is
+used to obtain the Blob size, MagickSeek(file,0,SEEK_SET) must be
+used to restore the seek position. Thanks to John Cristy for
+bringing this to our attention.</li>
+</ul>
+</blockquote>
+<p>2003-10-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/bit_stream.h: Added a bit-stream writer function.</li>
+<li>PerlMagick/t/reference/read/input_tim.miff: Reference image
+was defective.</li>
+</ul>
+</blockquote>
+<p>2003-10-03 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c, magick/image.h: Updated AddCoderOptions to
+accept &quot;flag&quot; keys that have no values. They are placed in the
+coder options map with an empty, zero length string value. Option
+argument syntax is now: &quot;key1[=[value1]],key2[=[value2]],...&quot;</li>
+</ul>
+</blockquote>
+<p>2003-10-03 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Updated +coder-options option to not clear the
+entire map of coder options, but accept a list of names to remove
+from the map. Use option argument &quot;*&quot; to clear the entire map of
+coder options.</li>
+<li>magick/image.c, magick/image.h: Added function
+RemoveCoderOptions. Added cast of signed char to unsigned char and
+int in calls to isspace and isprint.</li>
+<li>magick/utility.c: Added cast of signed char to unsigned char and
+int in calls to isspace and isprint. Added special handling of
++coder-options option in ExpandFilenames function.</li>
+</ul>
+</blockquote>
+<p>2003-10-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/reference/read/input_tim.miff: The TIM read results
+changed somewhat due to Glenn's ScaleColor5to8 fix.</li>
+</ul>
+</blockquote>
+<p>2003-10-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Revised ScaleColor5to8 and ScaleColor6to8 macros to fill in the
+low bytes.</li>
+<li>coders/bmp.c (ReadBMPImage): scaling of 8-8-8-8-bit images was
+also slightly incorrect.</li>
+</ul>
+</blockquote>
+<p>2003-09-30 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (ReadBMPImage): scaling of 5-5-5-bit and 5-6-5-bit
+images was slightly incorrect.</li>
+</ul>
+</blockquote>
+<p>2003-09-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): When using the generic bit-stream
+marshaller to read colormapped/gray images, the slight performance
+improvement from creating a special case for matte images did not
+justify almost doubling the amount of code. Therefore, the two
+loops are combined back into one.</li>
+</ul>
+</blockquote>
+<p>2003-09-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Fixed reading grayscale TIFFs
+that have a transparency channel. Now uses a generic bit-stream
+marshaller to allow reading any grayscale or colormapped TIFF with
+any bits per sample in the range of 1 to 16.</li>
+<li>magick/bit_stream.h: Added a generic implementation for
+marshalling from a bit-stream into a quantum. Still needs
+re-writing for best performance.</li>
+<li>PerlMagick/t/tiff/read.t: Added a test case for reading 8-bit
+grayscale TIFF with matte. Corrected grayscale 12-bit read
+signatures. Added 16 color PseudoClass read test. Added 4-bit
+grayscale read test.</li>
+</ul>
+</blockquote>
+<p>2003-09-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Add support for writing
+DirectClass grayscale images at 4 bits per sample, including those
+with an opacity channel. This allows writing smaller files
+(half the size) when the image has 16 (or less) levels of gray.
+Use &quot;gm convert inimage.tiff -depth 4 outimage.tiff&quot; to quickly
+create grayscale TIFF file with 16 (or less) levels of gray.</li>
+</ul>
+</blockquote>
+<p>2003-09-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: Updated NEWS file with changes since last update.</li>
+<li>index.html: Added a link to the www/AUTHORS.html file, as well
+as text stating that GraphicsMagick is originally derived from
+ImageMagick 5.5.2, with a link to the ImageMagick site.</li>
+<li>Makefile.am: Add rules to generate www/AUTHORS.html.</li>
+<li>www/AUTHORS.html: New HTML file based on the AUTHORS file in the
+source package. GraphicsMagick has many authors.</li>
+</ul>
+</blockquote>
+<dl class="docutils">
+<dt>2003-09-25 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</dt>
+<dd><ul class="first last simple">
+<li>magick/image.c: Updated DescribeImage to cleanup EXIF data display
+based on work by Cristy in ImageMagick.</li>
+</ul>
+</dd>
+</dl>
+<p>2003-09-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Add support for writing
+colormapped TIFF images with 1, 2, &amp; 4 bits per colormap index.
+This allows writing smaller files.</li>
+</ul>
+</blockquote>
+<p>2003-09-24 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/ps3.c: Now creates a correct %%BoundingBox for images
+with resolution stored as pixels per centimeter. Renamed serialize
+functions. Added comment headers where they were
+missing. Reformatted code to be in alignment with GraphicsMagick
+standard formatting.</li>
+<li>magick/map.c: Fixed semaphore double locking problem in
+MagickMapCloneMap.</li>
+</ul>
+</blockquote>
+<p>2003-09-23 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick/readme.txt : Updated compilation instructions.</li>
+<li>BCBMagick/magick/libMagick.bpr : Updated project, now include map.c.</li>
+<li>BCBMagick/lcms/Projects/BCB6/lcms.bpr : Updated project, now
+include cmscam02.c and cmsvirt.c. Much thanks to Alex Dvoretsky
+for bringing this problem to my attention.</li>
+</ul>
+</blockquote>
+<p>2003-09-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h (Image): Moved private members to bottom of
+structure.
+(_ImageInfo): Moved private members to bottom of
+structure.</li>
+<li>magick/Makefile.am (pkginclude_HEADERS): Don't install
+semaphore.h.
+(noinst_HEADERS): Distribute map.h and semaphore.h.</li>
+<li>magick/image.h (ImageInfo): Change coder_options member from
+type <cite>MagickMap</cite> to type <cite>void *</cite>.</li>
+<li>coders/png.c: include magick/semaphore.h.</li>
+<li>magick/blob.c: include magick/semaphore.h.</li>
+<li>magick/color.c: include magick/semaphore.h.</li>
+<li>magick/constitute.c: include magick/semaphore.h.</li>
+<li>magick/delegate.c: include magick/semaphore.h.</li>
+<li>magick/log.c: include magick/semaphore.h.</li>
+<li>magick/magic.c: include magick/semaphore.h.</li>
+<li>magick/magick.c: include magick/semaphore.h.</li>
+<li>magick/module.c: include magick/semaphore.h.</li>
+<li>magick/semaphore.c: include magick/semaphore.h.</li>
+<li>magick/stream.c: include magick/semaphore.h.</li>
+<li>magick/tempfile.c: include magick/semaphore.h.</li>
+<li>magick/type.c: include magick/semaphore.h.</li>
+<li>magick/blob.h (_BlobInfo): Changed <cite>Semaphore *</cite> to <cite>void *</cite>.</li>
+<li>magick/cache.h (_CacheInfo): Changed <cite>Semaphore *</cite> to <cite>void *</cite>.</li>
+<li>magick/image.h (_Image): Changed <cite>Semaphore *</cite> to <cite>void *</cite>.</li>
+<li>magick/command.c: Updated each invokation of MagickMapAddEntry()
+to add an exception argument.</li>
+<li>tests/maptest.c: Updated to pass an exception argument to
+MagickMapAddEntry.</li>
+<li>magick/image.c (AddCoderOptions): Added exception argument
+and some more error handling.</li>
+<li>magick/map.c: Added formal documentation for methods.
+(MagickMapCloneMap): Added exception argument.
+(MagickMapAddEntry): Added exception argument and status.</li>
+</ul>
+</blockquote>
+<p>2003-09-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/emf.c: Changed NotAnEMFFile to ImproperImageHeader.</li>
+<li>magick/map.h: Changed all size parmeters from type <cite>unsigned
+long</cite> to <cite>size_t</cite>.</li>
+<li>magick/map.c (MagickMapCopyBlob): Add new function to support
+copying a Blob in a MagickMap.
+(MagickMapDeallocateBlob): Add new function to support
+deallocating a Blob in MagickMap.</li>
+</ul>
+</blockquote>
+<p>2003-09-23 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/ps3.c: Fixed handling the case when no -coder-options are
+provided to the PS3 coder.</li>
+</ul>
+</blockquote>
+<p>2003-09-22 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/ps3.c: Changed %%Creator version to use
+MagickLibVersionText, increased precision in HiResBoundingBox,
+added a coder specific option for rendering bilevel images with
+the PS imagemask operator indstead of the image operator.</li>
+<li>magick/command.c: Added &quot;-coder-options&quot; command line argument
+to all relevant command line utilities. Option argument to
+-coder-options is a list of comma separated key-value pairs that
+are saved in a MagickMap in ImageInfo for (de-)coders to use. See
+PS3 coder for an example that checks for: -coder-options
+&quot;ps:image=imagemask&quot;</li>
+<li>magick/image.c, magick/image.h: Added function AddCoderOptions().</li>
+<li>magick/map.c, magick/map.h: removed MS-DOS line terminators.</li>
+</ul>
+</blockquote>
+<p>2003-09-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/maptest.c (main): Test/demo program for key,value map API.</li>
+<li>magick/map.c, magick/map.h: Implementation of a key,value map
+API for internal use.</li>
+</ul>
+</blockquote>
+<p>2003-09-19 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lcms/include/icc34.h lcms.h: Added back the icc34.h header and
+changes to make lcms compile on Win32&quot; icc34.h lcms.h.</li>
+</ul>
+</blockquote>
+<p>2003-09-19 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/ps3.c: Fixed warnings from Solaris compiler.</li>
+</ul>
+</blockquote>
+<p>2003-09-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>locale/C.mgk: Eliminated the many &quot;NotA&quot; messages since they may
+all be considered forms of &quot;ImproperImageHeader&quot;. It is useful to
+provide the origin of such messages in case the wrong coder has
+been invoked, however, this is expensive to do via the message
+database since it explodes the number of messages. The exception
+logging can help here. Once the exception reports include the
+reporting entity, it will be more clear when the software
+misbehaves.</li>
+<li>magick/error.h (ThrowReaderException2): Remove since no longer
+used.
+(ThrowReaderException): Simplified implementation so that
+ThrowException is not expanded twice.</li>
+<li>magick/error.h (ThrowReaderException3): Remove since never used.</li>
+<li>coders/xtrn.c (ReadXTRNImage): Use ThrowReaderException rather
+than ThrowReaderException2.</li>
+<li>locale/C.mgk (MissingArgument) Updated to include %s so that the
+description field appears earlier in the message.</li>
+<li>magick/error.c (DefaultErrorHandler): Added a hack to allow the
+<cite>reason</cite> member to include a %s so that it may specify the
+formating of the message. Care should be taken to not over-use
+this hack.</li>
+</ul>
+</blockquote>
+<p>2003-09-18 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/ps3.c: Major update of the PS3 coder. Now ascii85 encodes
+all binary data. Many printer spoolers don't like the binary
+data. The coder now creates much smaller files for bilevel, gray,
+and colormapped images. Compression and image type is now
+separated so they may be combined independently. Any alpha channel
+is separated into a separate mask so it's possible to mask
+bilevel, gray, colormapped, rgb, and CKYK images. You may also
+mask a JPEG compressed PS file for instance. Clipping masks
+created from a photoshop clipping path with -clip option is
+converted to a corresponding postscript clipping path. New
+functions need comment headers.</li>
+<li>magick/attribute.c: Added TracePSClippingPath for creating a
+postscript clipping path from a photoshop clipping path.</li>
+<li>magick/compress.c, magick/compress.h: Added write-hook based
+interface to compression functions. Required for ascii encoding
+compressed, binary data. The interface between blob write
+functions, compression functions, and encoding functions could
+benefit from more of this work.</li>
+<li>magick/image.c: ClipPathImage now stores the name of the
+clipping path in the mask image filename so that it is remembered
+and may be used for creating a postscript clipping path for
+postscript output.</li>
+<li>coders/modules.mgk: Added EPS3 mapping to module PS3.</li>
+</ul>
+</blockquote>
+<p>2003-09-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Coalesced various &quot;Missing&quot; error reports into
+one &quot;MissingArgument&quot; error report in order to reduce the number
+of messages to be maintained.</li>
+<li>locale/C.mgk: Removed almost all &quot;Missing&quot; messages.</li>
+<li>magick/gm_messages.mc: Added Microsoft message compiler source
+file to CVS until which time it may be generated automatically
+during the build.</li>
+</ul>
+</blockquote>
+<p>2003-09-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>locale/Makefile: Added ability to generate gm_messages.mc
+(for Windows message compiler) as well as adding <cite>clean</cite> and
+<cite>install</cite> targets.</li>
+<li>magick/delegate.h: Visual Studio .NET 2003 doesn't like
+the chaining of GhostscriptVector members which share a
+common return type. Splitting the definitions solves this
+problem.</li>
+</ul>
+</blockquote>
+<p>2003-09-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/deprecate.h (MagickSignedType): Compatibility definition
+to handle ImageMagick API change.
+(MagickUnsignedType): Compatibility definition to handle
+ImageMagick API change. The new names are just as useless as the
+old names, but at least they are shorter.</li>
+<li>magick/command.c: Linux's sscanf has the terrible bug that it
+improperly handles pulling out the first floating value from the
+string &quot;0x1&quot;. Instead of retrieving the value 0 and returning 1,
+it returns 0, probably because it rejects the string as a hex
+constant. As a result, all options which used sscanf to validate
+this input are now converted to use IsGeometry().</li>
+</ul>
+</blockquote>
+<p>2003-09-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ltdl/ltdl.c: Update to libltdl current as of today.</li>
+<li>ltmain.sh: Update to libtool current as of today.</li>
+<li>configure.ac: For HPUX C++ compiler, add -AA to CXXFLAGS rather
+than CXX.</li>
+</ul>
+</blockquote>
+<p>2003-09-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Decided that the standards conformance
+defines create more problems than they solve so they are
+removed.
+Move the large-file tests to before the libtool configuration
+since the libtool configuration was causing stdlib.h to be
+included prior to the large file defines, and this causes
+header failure with C++ under AIX.</li>
+<li>www/api/types.html: Update description of MonitorHandler.</li>
+</ul>
+</blockquote>
+<p>2003-09-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Set CXX to PTHREAD_CXX if necessary (and warn).</li>
+<li>acinclude.m4 (ACX_PTHREAD): Add check to see if xlC_r should be
+used for AIX.</li>
+</ul>
+</blockquote>
+<p>2003-09-10 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c: Fixed handling of arc primitive (see IM-5.5.8).</li>
+</ul>
+</blockquote>
+<p>2003-09-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.h: It seems that test programs are using
+GetMagickModule so make it visible by default.</li>
+<li>configure.ac: Use GM_FUNC_MMAP_FILEIO macro to test mmap.</li>
+<li>acinclude.m4 (GM_FUNC_MMAP_FILEIO): New macro to test mmap's
+capability to do coherent file I/O. The AC_FUNC_MMAP macro
+was not testing the mmap features that GraphicsMagick uses, and
+was failing on a number of systems.</li>
+<li>magick/blob.c (BlobMapModeToString): Only include this static
+function if HAVE_MMAP is defined.</li>
+<li>coders/locale.c (WriteLOCALEImage): Fix FormatString argument
+type inconsistencies.</li>
+<li>wand/magick_compat.h: Change MagickExport to WandExport.</li>
+<li>coders/jpeg.c, coders/locale.c, coders/meta.c, coders/miff.c,
+coders/palm.c, coders/pict.c, coders/svg.c, coders/tiff.c,
+coders/topol.c, magick/cache.c, magick/display.c, magick/image.c,
+magick/widget.c: Removed unused values, changed storage types, or
+added explicit casts, in order to reduce the number of &quot;REMARK&quot;s
+when using the SGI IRIX compiler.</li>
+<li>magick/render.c (DrawClipPath): Fix memory leak of
+clone_info-&gt;clip_path. Problem reported by Vladimir
+&lt;<a class="reference external" href="mailto:lvm&#37;&#52;&#48;integrum&#46;ru">lvm<span>&#64;</span>integrum<span>&#46;</span>ru</a>&gt;.
+(DestroyDrawInfo): Remove unnecessary checks for non-null prior to
+invoking MagickFreeMemory. MagickFreeMemory already checks for
+non-null.</li>
+<li>magick/log.h (GetCurrentFunction): Apparently Visual C++ 6.0
+does not support __FUNCTION__. Problem reported by Vladimir
+&lt;<a class="reference external" href="mailto:lvm&#37;&#52;&#48;integrum&#46;ru">lvm<span>&#64;</span>integrum<span>&#46;</span>ru</a>&gt;.</li>
+<li>wand/magick_compat.c: All functions in magick_compat.c must use
+WandExport rather than MagickExport. Fix recommended by Vladimir
+&lt;<a class="reference external" href="mailto:lvm&#37;&#52;&#48;integrum&#46;ru">lvm<span>&#64;</span>integrum<span>&#46;</span>ru</a>&gt;.</li>
+<li>magick/constitute.c (PushImagePixels): number_pixels was always
+cast to a long during use, so change to store value in a long
+instead.
+(PopImagePixels): number_pixels was always
+cast to a long during use, so change to store value in a long
+instead.</li>
+</ul>
+</blockquote>
+<p>2003-09-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c: Eliminated warning regarding unused initialized
+variable.</li>
+<li>magick/log.c: Eliminate type warnings regarding enum assignment.</li>
+<li>coders/locale.c (WriteLOCALEImage): Use UndefinedException
+rather than 0 in severity_list terminating entry in order to avoid
+a type conversion warning.</li>
+<li>magick/image.c (SetImageChannelDepth): Depth parameter was being
+returned rather than status. Oops!</li>
+<li>magick/effect.c (BlurScanline): Due to automatic casting
+conventions, computation was being done (at least with SGI
+compiler) as type <cite>unsigned long</cite> rather than <cite>long</cite> as it should
+have been.</li>
+<li>coders/jpeg.c, coders/meta.c, coders/miff.c, coders/msl.c,
+coders/palm.c, coders/pcd.c, coders/psd.c, coders/svg.c,
+coders/tiff.c, coders/xcf.c, magick/render.c, : Quench many SGI
+compiler warnings regarding variables which are initialized but
+never used.</li>
+<li>magick/xwindow.h: Undef gravity defines so that enumerated type
+is used instead.</li>
+</ul>
+</blockquote>
+<p>2003-09-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c (LogMagickEvent): Windows system logging
+functionality is not currently ported to work with Cygwin so
+disable when compiling under Cygwin.</li>
+<li>magick/log.c (Win32EventlogOutput): Remove spurious comma in enum.</li>
+<li>wand/drawing_wand.h: Remove junk comment marker that I forgot to
+remove.</li>
+<li>magick/studio.h: Provide prototypes for strlcpy and vsnprintf if
+the system doesn't provide them in the requested compilation
+environment.</li>
+<li>configure.ac: Add necessary standards compilance definitions to
+magick_config.h.
+Check for strlcpy and vsnprintf prototypes.</li>
+<li>Makefile.am (DOCDIRS): www/api/types does not exist anymore.</li>
+</ul>
+</blockquote>
+<p>2003-09-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Move multithread tests prior to libtool
+configuration in case value of CC is changed. Otherwise libtool
+gets confused and refuses to run.</li>
+<li>acinclude.m4 (ACX_PTHREAD): If using AIX CC <cite>xlc</cite> use <cite>xlc_r</cite>
+for multithread compiler.</li>
+<li>coders/jpeg.c: Undef HAVE_STDLIB_H before including the
+jpeg headers or else we get an already defined error/warning.</li>
+</ul>
+</blockquote>
+<p>2003-09-04 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick : Updated whole directory tree to achieve correct
+compilation with Borland C++ Buider 6.0.</li>
+</ul>
+</blockquote>
+<p>2003-09-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (ClipPathImage): Remove MS-DOS line terminations
+(actually, extra carriage returns) which somehow crept into
+ClipPathImage.</li>
+<li>locale/C.mgk: Added message for &quot;PNG library is too old&quot;.</li>
+</ul>
+</blockquote>
+<p>2003-09-04 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/transform.c (ProfileImage): Bugfix: conditional
+compilation based on LCMS being present or not now works as
+expected. An exception is thrown if LCMS is not present and
+profile conversion is used.</li>
+</ul>
+</blockquote>
+<p>2003-09-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c (ReadTXTImage): Fix strlen() pointer type warning.</li>
+<li>magick/image.c (TextureImage): Fixed return with no value warning.</li>
+<li>magick/color.c (GetColorInfoArray): Decided that the const
+return value was a bad idea. Therefore, the return type has been
+made non-const.</li>
+<li>magick/magick.c (GetMagickInfoArray): Decided that the const
+return value was a bad idea. Therefore, the return type has been
+made non-const.</li>
+<li>tests/constitute.c, tests/rwblob.c, tests/rwfile.c : Define
+MAGICK_IMPLEMENTATION since these test programs using some internal
+extensions.</li>
+<li>configure.ac: Test C++ compiler for __func__ support.</li>
+<li>magick/log.h: Added GetCurrentFunction() macro to handle
+__func__ support determination. Re-wrote GetMagickModule() macro
+to use GetCurrentFunction(). Changes should allow compilation of
+Magick++ when the C compiler supports __func__ but the C++
+compiler does not.</li>
+<li>configure.ac: Changed from using HAS___func__ define to
+HAS_C__func__ since this feature may be language sensitive.</li>
+<li>locale/C.mgk: Added missing JNGCompressionNotSupported message.</li>
+</ul>
+</blockquote>
+<p>2003-09-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (Generate8BIMAttribute): Fix sscanf argument
+type mis-match.</li>
+<li>coders/ps3.c (ZLIBEncodeImage): Fix mis-classified
+ZipLibraryIsNotAvailable error report.</li>
+<li>coders/url.c (RegisterURLImage): Only register URL format
+support if libxml2 is available.</li>
+<li>coders/msl.c (RegisterMSLImage): Only register MSL format
+support if libxml2 is available.</li>
+</ul>
+</blockquote>
+<p>2003-09-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/histogram.c (WriteHISTOGRAMImage): Remove a useless loop.</li>
+<li>coders/wpg.c: Applied patch from Fojtik Jaroslav to support
+reading WPGs which use the EXT token.</li>
+</ul>
+</blockquote>
+<p>2003-08-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/color.c (HistogramToFile): Renamed static method
+<cite>Histogram</cite> to <cite>HistogramToFile</cite> to make it more clear what this
+function does.
+(GetColorHistogram): Added new function to support retrieving a
+color histogram of the image. A color histogram contains a count
+of how many times each color occurs in the image.</li>
+<li>magick/image.c (GetImageChannelDepth): Return an <cite>unsigned int</cite>
+rather than <cite>long</cite>.</li>
+</ul>
+</blockquote>
+<p>2003-08-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Add support for CopyCyan, CopyMagenta,
+CopyYellow, and CopyBlack, composition operators.</li>
+<li>magick/composite.c (CompositeImage): Added support for
+CopyCyanCompositeOp, CopyMagentaCompositeOp,
+CopyYellowCompositeOp, and CopyBlackCompositeOp, composition
+operators.</li>
+</ul>
+</blockquote>
+<p>2003-08-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/*: Updated to current ImageMagick Wand API (minus a few
+unimplemented functions).</li>
+<li>magick/image.c (TextureImage): Add status return because Wand API
+wants it. Inherit is_grayscale status from texture image.</li>
+<li>magick/fx.c (SolarizeImage): Add status return because Wand API
+wants it.</li>
+<li>magick/resource.c (SetMagickResourceLimit): Add status return
+because Wand API wants it.</li>
+<li>magick/draw.c (DrawPeekGraphicContext): Now returns a
+copy of the current DrawInfo context rather than returning
+a pointer into the context stack. The user must destroy
+this copy using DestroyDrawInfo() once it is no longer
+needed.</li>
+</ul>
+</blockquote>
+<p>2003-08-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/filters/LIBRARY.txt: This file is necessary to
+incorporate analyze.c into the static build. Without it the
+build fails.</li>
+</ul>
+</blockquote>
+<p>2003-08-23 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/transform.c: ProfileImage updated to handle alpha
+channels and grayscale images. Also optimized color profiling of
+color mapped images and fixed a few bugs in profiling of CMYK
+images.</li>
+<li>magic/locale_c.h: added MagickExport to prototype declaration of
+GetLocaleMessageFromID in WriteLOCALEImage again. Please update
+your locale coder.</li>
+</ul>
+</blockquote>
+<p>2003-08-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c: Applied patch from Fojtik Jaroslav to use the
+GetMagicInfo() function to obtain the format of embedded images,
+and to provide a default WPG palette if the WPG file does not
+supply a palette.</li>
+</ul>
+</blockquote>
+<p>2003-08-22 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magickgm_messages.bin locale_c.h transform.c: Fixed missing
+message problem and added support for new lcms error handler.</li>
+</ul>
+</blockquote>
+<p>2003-08-21 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c, magick/image.c, magick/command.c: Added
+&quot;clippath&quot; option for clipping named Photoshop clipping paths,
+increased precision in clipping path knots, added comments, and
+fixed a few bugs resulting from moving TraceClippingPath function
+from ImageMagick to GraphicsMagick. Still need to update some of
+the documentation.</li>
+<li>magick/locale_c.h, magick/studio.h: added MagickExport to
+declaration of GetLocaleMessageFromID and moved include of
+magick/locale_c.h after declaration of MagickExport. This fixes a
+link error in dynamic, DLL version.</li>
+<li>coders/locale.h: added MagickExport to prototype declaration of
+GetLocaleMessageFromID in WriteLOCALEImage.</li>
+</ul>
+</blockquote>
+<p>2003-08-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/subroutines.pl (testRead): Ignore useless TIFF
+warning so that 12-bit TIFF test passes.</li>
+<li>magick/constitute.c (ReadImage): Ensure that the reported image
+magic string is that of the user-specified input file rather than
+a temporary file prepared by an external delegate program.</li>
+<li>magick/command.c (ImportImageCommand): Since
+DestroyExceptionInfo() now sets the destroyed exception signature
+to an invalid value, GetExceptionInfo(exception) must be invoked
+when the intention is to simply purge the exception. This fix
+resolves an abort when executing <cite>gm import</cite>.</li>
+</ul>
+</blockquote>
+<p>2003-08-18 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magickgm_messages.bin locale_c.h transform.c: Updates that
+add latest enhancments by Lars to color management code in
+ProfileImage.</li>
+</ul>
+</blockquote>
+<p>2003-08-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c: Incorporated patch from Fojtik Jaroslav to support
+rendering embedded WMFs.</li>
+</ul>
+</blockquote>
+<p>2003-08-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageChannelDepth): New function to transform
+the specified channel so it fits the specified modulus depth.</li>
+<li>magick/blob.c (BlobToImage): Skip calling SetImageInfo() if
+magick is already set.</li>
+</ul>
+</blockquote>
+<p>2003-08-18 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Some fixes to get PerlMagick compiling
+again due to new ID based error macros.</li>
+</ul>
+</blockquote>
+<p>2003-08-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/error.h (enum): Remove spurious comma.</li>
+</ul>
+</blockquote>
+<p>2003-08-17 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coderspng.c: Had to modify a few exception calls to work with
+newest macros.</li>
+</ul>
+</blockquote>
+<p>2003-08-17 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coderslocale.c magick/error.h locale.c locale_c.h studio.h:
+The LOCALEH header file generator now adds an MGK_ prefiix to
+all the ID defines as part of a fix to support the new error
+and exception macros cross platform.</li>
+</ul>
+</blockquote>
+<p>2003-08-16 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wandmagick_wand.c pixel_wand.c: The wand api code was totally
+left out of the large macro conversion below as an oversight.</li>
+</ul>
+</blockquote>
+<p>2003-08-15 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>.coders art.c avi.c avs.c bmp.c caption.c clipboard.c cmyk.c
+cut.c dcm.c dib.c dps.c dpx.c emf.c ept.c fax.c fits.c fpx.c gif.c
+gradient.c gray.c hdf.c histogram.c html.c icon.c jbig.c jp2.c
+jpeg.c label.c locale.c logo.c map.c mat.c matte.c meta.c miff.c
+mono.c mpc.c mpeg.c msl.c mtv.c mvg.c null.c otb.c palm.c pcd.c
+pcl.c pcx.c pdb.c pdf.c pict.c pix.c png.c pnm.c preview.c ps.c
+ps2.c ps3.c psd.c pwp.c rgb.c rla.c rle.c sct.c sfw.c sgi.c
+stegano.c sun.c svg.c tga.c tiff.c tile.c tim.c topol.c ttf.c txt.c
+uil.c url.c uyvy.c vicar.c vid.c viff.c wbmp.c wmf.c wpg.c x.c xbm.c
+xc.c xcf.c xpm.c xtrn.c xwd.c yuv.c .magickanimate.c annotate.c
+blob.c cache.c cache_view.c color.c color.h command.c compress.c
+constitute.c decorate.c delegate.c display.c draw.c effect.c
+enhance.c error.c error.h fx.c gm_messages.bin image.c list.c
+locale.c locale_c.h log.c mac.c magic.c magick.c module.c montage.c
+nt_feature.c paint.c quantize.c registry.c render.c resize.c
+segment.c semaphore.c shear.c signature.c static.c static.h
+stream.c studio.h tempfile.h transform.c type.c utility.c widget.c
+xwindow.c : Changes to support ID based message access and checking
+all message usages. The main thing that was done was to remove all
+the quotes around the &quot;tags&quot; used to lookup messages defined in
+the localeC.XML file. Macros were added to error.h to allow the
+code to be compiled for either string based access or binary ID
+based access. Using binary ID's will cause the code to fail to
+compile if a message does not exist in C.XML, since no ID will be
+created for a missing message. This change then allowed us to
+easily track down all the messages that were &quot;missing&quot; or not
+being accessed properly. The problems were massive and took many
+days to resolve. I have left the code compiling in ID mode to keep
+things in sync going forward and also because it makes message
+lookup instantaneous. An ID is just an index into and array of
+char *'s. There is still a lot of cleanup work remaining, but this
+is a very good start.</li>
+</ul>
+</blockquote>
+<p>2003-08-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/error.c (GetLocaleExceptionMessage): Add check to avoid
+duplicating severity prefix.</li>
+<li>magick/log.c (LogMagickEvent): Incorporated fix from Bill
+Radcliffe to enable logging control flags to work properly again.</li>
+<li>NEWS: Updated news.</li>
+<li>magick/blob.c (OpenBlob): Rewind file descriptor so that first
+read is at zero offset. This fixes reading GIFs via a
+user-provided file handle.</li>
+</ul>
+</blockquote>
+<p>2003-08-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GetImageDepth): Extend so that the actual
+minimum depth required to represent the image is
+returned. Previously only the values 8, 16, and 32 were
+returned. This means that a value of one is returned for a
+monochrome image. Also fixed a bug in that the pixels were
+incremented while the depth was incremented, resulting in the
+first image pixels not being properly evaluated for depth.
+(SetImageDepth): Extend to support converting the image to
+arbitrary modulus depths.
+(GetImageChannelDepth): New function to obtain the modulus depth
+for a specified image channel.</li>
+</ul>
+</blockquote>
+<p>2003-08-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/draw.c (MvgAutoWrapPrintf): StreamError reported when
+DrawError was intended.</li>
+<li>coders/logo.c (ReadLOGOImage): Report FileOpenError rather than
+BlobError if requested image does not exist.</li>
+</ul>
+</blockquote>
+<p>2003-08-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cache.c (PersistCache): If HAVE_SYSCONF and _SC_PAGE_SIZE
+are defined, then assume that sysconf works and don't use legacy
+getpagesize() function.</li>
+<li>magick/studio.h (_XOPEN_SOURCE): Should be defined as 600 in
+order to match _POSIX_C_SOURCE=200112L according to the Single
+UNIX Specification v3. This is necessary for the vsnprintf
+prototype to be visible.</li>
+<li>magick/attribute.c (ReadByte): Fix compilation warnings due to
+casting <cite>unsigned char *</cite> to <cite>char *</cite> by changing function
+definition to accept <cite>unsigned char *</cite> instead.</li>
+<li>magick/error.h (UndefinedException): UndefinedException should
+be ExceptionType, not ExceptionBaseType.</li>
+<li>magick/magick.c (IsValidFilesystemPath): Eliminate warning about
+unused function when UseInstalledMagick is defined.</li>
+<li>magick/error.c (ThrowLoggedException): Fix improper parameters
+passed to LogMagickEvent() when reason is not available.</li>
+</ul>
+</blockquote>
+<p>003-08-07 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c, log.h: Added ability to log by either severity
+or by category of event. Made the defualt on windows to log all
+fatal errors, errors, and warnings to the event log. This will
+include anything generated by exceptions currently, but not any
+normal &quot;informational&quot; logging.</li>
+</ul>
+</blockquote>
+<p>2003-08-07 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c, log.h: Translation of event codes to mask vals
+was not working. Code was left out of last update. It is now in.</li>
+</ul>
+</blockquote>
+<p>2003-08-07 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/error.c: Protect against NULL string passed into the
+message lookup function.</li>
+</ul>
+</blockquote>
+<p>2003-08-07 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/locale.c: Switched use of IsAccessible to nonloggging
+version to prevent recursive problems.</li>
+</ul>
+</blockquote>
+<p>2003-08-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/Makefile.am (noinst_HEADERS): Distribute locale_c.h.</li>
+<li>locale/Makefile: Output locale_c.h.</li>
+<li>utilities/gm.c (main): Fix typo in Unix InitializeMagick
+invocation.</li>
+<li>configure.ac: Use ACX_PTHREAD pthreads test macro.</li>
+<li>magick/(semaphore.c,spinlock.h,studio.h): Change HasPTHREADS
+conditional define to HAVE_PTHREAD.</li>
+<li>magick/Makefile.am (noinst_HEADERS): Include spinlock.h in
+distribution.</li>
+</ul>
+</blockquote>
+<p>2003-08-06 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>contribwin32ATL7ImageMagickObject/ImageMagickObject.cpp,
+ImageMagickObject_.h, ImageMagickObject.def, ImageMagickObject.rc
+gm.rc: Changes to get things compiling again since all windows
+specific logging support has been eliminated. The special build
+script BuildImageMagickObject.cmd now compiles the message file
+for resource based messages. The result is in gm_messages.bin.
+The script also generates a special version of gm.exe that uses
+the COM dll as a regular DLL and links to it. This is the long
+desired Moby DLL build idea.</li>
+<li>magick/error.c, magick/error.h, magick/log.c, magick/log.h:
+Upgrade of logging system to take over previous special logging
+code for windows in nt_base.c. The new logic provides logging of
+events to the debug api and the windows event log and also
+provides a generic text file logging method.</li>
+<li>magick/gm_messages.bin, magick/ImageMagick.rc: New compiled
+message file based on data in localeC.mgk. RC file modified to
+include this as a resource.</li>
+<li>magick/locale.c, magick/locale_c.h: locale_c.h is generated by
+the LOCALEH format of the locale coder. The logic in locale.c uses
+the tables in the header lookup messages. On windows, all the
+messages are stored as resources, while on UNIX they remain in a
+string table.</li>
+<li>locale/C.mgk: Removed duplicate messages and added some new
+default messages that help to create a complete set of severity
+strings.</li>
+<li>magick/command.c, magick/magick.c: Get rid compiler warnings.</li>
+</ul>
+</blockquote>
+<p>2003-08-05 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c, magick/gm.c: Application level changes to
+implement the client name - filename changes. The client name can
+now be anything that the application wants and has nothing to do
+with the saved filename of the application.</li>
+<li>magick/nt_base.c, magick/nt_base.h, magick/magick.c: Ripped out
+old nt specific debugging and logging logic. Moving to the
+standard logging. New and major revisions to InitializeMagick to
+make the code more maintainable, reliable, and reaable. It should
+be functionally identical, but implements the new split client
+name and filename methododology.</li>
+<li>magick/utility.c, magick/utility.h: Added a couple of new
+routines to support splitting the overloaded use of the client
+name and client filename.</li>
+<li>coders/xtrn.c: Minor code cleanup</li>
+</ul>
+</blockquote>
+<p>2003-08-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Copyright.txt: Added missing copyright notice which is required
+due to copying the rlecomp manual page into ImageMagick.</li>
+<li>doc/config_files.imdoc: Started documentation for configuration
+files.</li>
+<li>magick/xwindow.c (XSignalHandler): Ensure that segment_info is
+non-null before attempting to use it. Much thanks to John Cristy
+for bringing this problem to our attention.</li>
+</ul>
+</blockquote>
+<p>2003-08-05 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/locale.c: Added several new formats to this coder to
+generate windows message resource format messages and also to
+generates a new header file format that will support a table based
+version of the other magick/locale.c.</li>
+<li>coders/xtrn.c: Minor code cleanup</li>
+</ul>
+</blockquote>
+<p>2003-08-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Only configure C and C++ libtool tags.</li>
+<li>PerlMagick/t/reference/composite/*.miff: Added some composition
+test reference images. These reference images will serve as
+placeholders until better composition tests can be figured out.
+It is not clear from the documentation what some of the
+composition operators are supposed to do.</li>
+</ul>
+</blockquote>
+<p>2003-08-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>README.txt: Add documentation regarding using TRIO.</li>
+<li>configure.ac: Test for TRIO library if vsnprintf is not
+available.</li>
+<li>magick/studio.h: Remap vsnprintf to trio_vsnprintf if TRIO is
+available.</li>
+<li>coders/topol.c, coders/wmf.c, magick/magick.c, magick/nt_base.c,
+magick/resource.c: Use traditional C comment form in C source
+files.</li>
+</ul>
+</blockquote>
+<p>2003-07-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.h (LogEventType::AllEvents): Increase the value of
+AllEvents so that it spans the complete positive range of a signed
+integer.</li>
+<li>magick/xwindow.c, magick/xwindow.h: Incorporate patch from John
+Cristy's ImageMagick to eliminate conditional dependence of
+magick/xwindow.h on &lt;X11/extensions/XShm.h&gt;.</li>
+<li>magick/magick_config_api.h.in: HasSharedMemory define no longer
+needed.</li>
+</ul>
+</blockquote>
+<p>2003-07-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/programming.html: Update Rmagick URL.</li>
+<li>GraphicsMagick.spec.in : Update according to instructions from
+Troy Edwards.</li>
+</ul>
+</blockquote>
+<p>2003-07-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec.in: Replaced GraphicsMagick.spec with
+GraphicsMagick.spec.in, which is configured to produce
+GraphicsMagick.spec.</li>
+<li>configure.ac: Configure GraphicsMagick.spec.</li>
+</ul>
+</blockquote>
+<p>2003-07-29 Troy Edwards &lt;<a class="reference external" href="mailto:vallimar&#37;&#52;&#48;sexorcisto&#46;net">vallimar<span>&#64;</span>sexorcisto<span>&#46;</span>net</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec: Updated to CVS build. Added the
+GraphicsMagickWand files to the spec. Only try to remove the
+unneeded perl package files if we are using PerlMagick.</li>
+</ul>
+</blockquote>
+<p>2003-07-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec: Added RPM spec file authored by Troy
+Edwards &lt;<a class="reference external" href="mailto:vallimar&#37;&#52;&#48;sexorcisto&#46;net">vallimar<span>&#64;</span>sexorcisto<span>&#46;</span>net</a>&gt;.</li>
+<li>NEWS: Add note regarding EXIF fix.</li>
+<li>magick/attribute.c (GenerateEXIFAttribute): Look for the profile
+name &quot;EXIF&quot; rather than &quot;APP1&quot;.</li>
+</ul>
+</blockquote>
+<p>2003-07-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick_config_api.h.in: XWindowInfo structure in
+xwindow.h needs HasSharedMemory define.</li>
+<li>magick/xwindow.c, magick/xwindow.h: Move inclusion of
+&lt;X11/extensions/shape.h&gt; to xwindow.c.</li>
+<li>coders/dps.c, magick/xwindow.h: Move DPS includes to
+coders/dps.c</li>
+<li>coders/Makefile.am: Substituted values are also set as
+make variables, so use variables rather than substitutions.</li>
+<li>magick/log.c (GetLogBlob): MAGICK_HOME needs to take
+precedence over the client path for the uninstalled build.</li>
+<li>magick/type.c (GetTypeBlob): MAGICK_HOME needs to take
+precedence over the client path for the uninstalled build.</li>
+<li>magick/blob.c (GetConfigureBlob): MAGICK_HOME needs to take
+precedence over the client path for the uninstalled build.</li>
+<li>magick/module.c (FindMagickModule): MAGICK_HOME needs to take
+precedence over the client path for the uninstalled build.</li>
+</ul>
+</blockquote>
+<p>2003-07-24 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (TraceClippingPath): Improvements to clipping
+path parsing.</li>
+</ul>
+</blockquote>
+<p>2003-07-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cache.c: Disable the Windows open() extensions when
+compiling using Borland C++.</li>
+<li>magick/log.c (LogMagickEvent): Unlock semaphore before
+returning.</li>
+<li>ltdl/ltdl.h: Updated to latest CVS version.</li>
+<li>ltdl/ltdl.c: Updated to latest CVS version.</li>
+<li>Libtool: Updated to use latest CVS libtool.</li>
+</ul>
+</blockquote>
+<p>2003-07-17 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick: Contributed initial Borland C++ Builder 6.0 build
+environment.</li>
+</ul>
+</blockquote>
+<p>2003-07-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/color.c (GetColorInfoArray): Added a function to access
+the color definition list as an array.
+(GetColorList): Added access locks to ensure that list is not
+re-ordered while it is being traversed.</li>
+<li>www/Magick++/Image.html: Add some more information regarding raw
+pixel access.</li>
+</ul>
+</blockquote>
+<p>2003-07-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/GraphicsMagickWand.pc.in (Cflags): Remove LFS_CPPFLAGS.</li>
+<li>wand/GraphicsMagickWand-config.in: Remove LFS_CPPFLAGS.</li>
+<li>magick/GraphicsMagick.pc.in (Cflags): Remove LFS_CPPFLAGS.</li>
+<li>magick/GraphicsMagick-config.in: Remove LFS_CPPFLAGS.</li>
+<li>configure.ac: Logic for setting LFS_CPPFLAGS was incomplete.</li>
+<li>coders/topol.c: Updated topol coder contributed by Jaroslav
+Fojtik. Topol is coming to life!</li>
+</ul>
+</blockquote>
+<p>2003-07-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.h: Add a typedef for ssize_t</li>
+<li>magick/deprecate.h: ExtendedSignedIntegralType and
+ExtendedUnsignedIntegralType are now deprecated types so they are
+moved to deprecate.h. Existing code which uses these types should
+continue to work.</li>
+<li>magick/blob.c (MapBlob): Change <cite>offset</cite> parameter from type
+off_t to magick_off_t so that it is not LFS dependent.</li>
+<li>magick/cache.c (GetPixelCacheArea): Return magick_off_t.
+(PersistCache): Change <cite>offset</cite> parameter to type magick_off_t.</li>
+<li>magick/cache.h (NexusInfo): Change <cite>length</cite> type from
+ExtendedSignedIntegralType to magick_off_t.
+(CacheInfo): Change <cite>offset</cite> and <cite>length</cite> types from
+ExtendedSignedIntegralType to magick_off_t.</li>
+<li>magick/blob.c (BlobToFile): Use ssize_t rather than
+ExtendedSignedIntegralType for count.
+(TellBlob): Return magick_off_t rather than
+ExtendedSignedIntegralType.</li>
+<li>configure.ac: Check for a ssize_t type.</li>
+<li>magick/blob.h (_BlobInfo): Change <cite>offset</cite> and <cite>size</cite> members
+from ExtendedSignedIntegralType to magick_off_t.</li>
+<li>magick/blob.c (GetBlobSize): Return magick_off_t rather than
+ExtendedSignedIntegralType.
+(SeekBlob): Accept and return magick_off_t rather than
+ExtendedSignedIntegralType.</li>
+</ul>
+</blockquote>
+<p>2003-07-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/monitor.c (MagickMonitor): Change <cite>quantum</cite> argument from
+type ExtendedSignedIntegralType to magick_int64_t. Change <cite>span</cite>
+argument from ExtendedUnsignedIntegralType to magick_uint64_t.</li>
+<li>magick/xwindow.c (XMagickMonitor): Change <cite>quantum</cite> argument from
+type ExtendedSignedIntegralType to magick_int64_t. Change <cite>span</cite>
+argument from ExtendedUnsignedIntegralType to magick_uint64_t.</li>
+<li>magick/widget.c (XMonitorWidget): Change <cite>quantum</cite> argument from
+type ExtendedSignedIntegralType to magick_int64_t. Change <cite>span</cite>
+argument from ExtendedUnsignedIntegralType to magick_uint64_t.</li>
+<li>magick/studio.h (QuantumTick): Change typecast from
+ExtendedSignedIntegralType to magick_int64_t.</li>
+<li>magick/resource.c (AcquireMagickResource): Change <cite>size</cite>
+argument type from ExtendedSignedIntegralType to magick_int64_t.
+(LiberateMagickResource): Change <cite>size</cite> argument type from
+ExtendedSignedIntegralType to magick_int64_t.</li>
+<li>magick/utility.c (FormatSize): Change <cite>size</cite> argument type from
+ExtendedSignedIntegralType to magick_int64_t.</li>
+<li>magick/nt_base.c: Change MagickOffset to magick_off_t.</li>
+<li>magick/studio.h (magick_off_t): Change MagickOffset to magick_off_t.</li>
+<li>coders/topol.c: Insert dummy member into palettRAS structure
+since Visual C++ doesn`t seem to handle empty structures.</li>
+<li>wand/GraphicsMagickWand.pc.in (prefix): Pass LFS CPPFLAGS.</li>
+<li>wand/GraphicsMagickWand-config.in: Pass LFS CPPFLAGS.</li>
+<li>wand/Makefile.am: Fix include path.</li>
+<li>magick/GraphicsMagick.pc.in (prefix): Pass LFS CPPFLAGS.</li>
+<li>magick/magick_config_api.h.in: Pass LFS configuration options
+until the API is fixed so that it is not LFS sensitive anymore.</li>
+<li>magick/GraphicsMagick-config.in: Pass LFS CPPFLAGS.</li>
+<li>PerlMagick/Makefile.PL.in: Pass LFS CPPFLAGS.</li>
+<li>magick/Makefile.am: Install magick_types.h.</li>
+<li>magick/api.h: Include magick_types.h.</li>
+<li>magick/studio.h: Include magick_types.h rather than integral_types.h.</li>
+<li>VisualMagick/magick/magick_types.h.in: New header file (replacing
+integral_types.h) to contain CPU and system-dependent primitive
+typedefs.</li>
+<li>magick/magick_types.h.in: New header file (replacing
+integral_types.h) to contain CPU and system-dependent primitive
+typedefs.</li>
+<li>configure.ac: Use AC_SYS_LARGEFILE to test for large file
+options. Update to determine integral typedefs for current CPU and
+compiler options. Configure magick_types.h.</li>
+<li>magick/attribute.c (TraceClippingPath): Apply patch from Lars
+Ruben Skyum which fixes clipping path parsing for paths generated
+by Adobe software which pre-dates the Photoshop file format
+specification.</li>
+</ul>
+</blockquote>
+<p>2003-07-08 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/semaphore.c: Modified the way the system handles the
+initialization of Win32 critical sections to use a spin lock
+on WIn32 to bootstrap the initialization of all other crtical
+sections. This is not an issue on UNIX since static init is used.</li>
+<li>magick/magic.c module.c magick.c log.c resource.c constitute.c
+color.c cache.c delegate.c registry.c type.c: Small modifications
+were made to eliminate the side effect of unlocking semaphores
+as part of the releasing procedure. This also eliminated the
+apparent bug of the system double locking certain semaphores.
+The locked flag should now not be needed, but remains in place
+for the time being as an added safegaurd.</li>
+</ul>
+</blockquote>
+<p>2003-07-04 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png.c: added missing #ifdef JNG_SUPPORTED/#endif directives.</li>
+</ul>
+</blockquote>
+<p>2003-07-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: Updated news to include fixes and enhancements since the
+1.0 release.</li>
+</ul>
+</blockquote>
+<p>2003-07-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/semaphore.c (UnlockSemaphoreInfo): Bugfix, modify
+the <cite>locked</cite> flag while still under protection of the lock.
+This fix is necessary for thread-safety.</li>
+</ul>
+</blockquote>
+<p>2003-07-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (ReadJPEGImage): Conditionally copy exception.</li>
+<li>wand/Makefile.am (noinst_HEADERS): Need to distribute
+magick_compat.h.
+(EXTRA_DIST): Need to distribute GraphicsMagickWand-config.1.</li>
+<li>coders/wmf.c (ipa_bmp_draw): Use CopyException.
+(ipa_device_begin): Use CopyException.
+(lite_font_map): Use CopyException.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Use CopyException.</li>
+<li>magick/image.c (GetImageException): Use CopyException.</li>
+<li>magick/constitute.c (WriteImages): Use CopyException.</li>
+<li>Makefile.am (DIST_SUBDIRS): wand needs to be included in
+distribution.</li>
+</ul>
+</blockquote>
+<p>2003-06-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/static.c (RegisterStaticModules): Invoke
+RegisterTOPOLImage.</li>
+<li>magick/magick.h (MagickInfo): Add member usage comments.</li>
+<li>magick/error.c (CatchException): Restore saved errno from
+exception-&gt;error_number.
+(CopyException): Copy error_number.
+(DestroyExceptionInfo): Reset error_number to zero.
+(GetExceptionInfo): Initialize error_number to zero.
+(ThrowException): Save errno to exception-&gt; error_number.
+(ThrowLoggedException): Save errno to exception-&gt; error_number.</li>
+<li>magick/error.h (ExceptionInfo): Borrow John Cristy's idea and
+add a error_number member to ExceptionInfo to save the current
+errno value. Otherwise CatchException may use some random errno.</li>
+<li>coders/Makefile.am: Build topol.c.</li>
+<li>coders/topol.c: Added initial TOPOL X image coder which is under
+development by Jaroslav Fojtik. Not working yet.</li>
+</ul>
+</blockquote>
+<p>2003-06-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pwp.c (ReadPWPImage): Ensure that image is initialized
+before invoking ThrowReaderException.</li>
+<li>magick/image.c (CloneImage): Use CopyException.</li>
+<li>magick/error.c (CopyException): Add function to support copying
+ExceptionInfo structures.</li>
+<li>magick/error.h (ExceptionInfo): Replaced recently-added <cite>whence</cite>
+member with module, function, and line members in order to keep
+the information seperate, and match the parameters used by the
+logging system.
+(ThrowException): Log thrown exceptions.</li>
+<li>magick/error.c (ThrowLoggedException): New function used to
+throw an exception, while recording and logging the location
+where the exception is thrown.</li>
+<li>doc/options.imdoc (operation): Document TemporaryFile and
+Exception events.</li>
+<li>magick/log.c (LogMagickEvent): Support logging ExceptionEvent.</li>
+<li>PerlMagick/Magick.xs: Added &quot;Exception&quot; event type.</li>
+<li>magick/log.h (LogEventType): Added ExceptionEvent.</li>
+</ul>
+</blockquote>
+<p>2003-06-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/error.c (ThrowException): Handle <cite>whence</cite>
+member. MagickFreeMemory already checks for null pointer so don't
+check again.
+(DestroyExceptionInfo): Handle <cite>whence</cite> member. MagickFreeMemory
+already checks for null pointer so don't check again.</li>
+<li>magick/error.h (ExceptionInfo): Add a <cite>whence</cite> member to support
+the ability to record where the exception is was thrown.</li>
+<li>VisualMagick/installer: Install Wand files.</li>
+</ul>
+</blockquote>
+<p>2003-06-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (GetConfigureBlob): GetConfigureBlob should always
+return a value.</li>
+<li>magick/type.c (GetTypeBlob): GetTypeBlob should always return a
+value.</li>
+<li>magick/log.c (GetLogBlob): GetLogBlob should always return
+a value.</li>
+<li>magick/magick.c (GetMagickInfoArray): Fixed array memory
+allocation and clearing bug. Eliminate warnings.</li>
+</ul>
+</blockquote>
+<p>2003-06-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/files-configs.isx: For a static
+build, install the configuration files directly into the
+application directory.</li>
+<li>VisualMagick/installer/inc/uninstallrun-unregister-com.isx
+(Filename): Change ImageMagickObject.dll path.</li>
+<li>VisualMagick/installer/inc/run-register-com.isx (Filename):
+Change ImageMagickObject.dll path.</li>
+<li>VisualMagick/installer/inc/files-com.isx (Source): Install
+ImageMagickObject.dll and MagickCMD.exe in the application
+directory alongside gm.exe and the CORE DLLs.</li>
+<li>INSTALL-unix.txt: Add additional information regarding LZW.</li>
+<li>VisualMagick/magick/magick_config.h.in: Add additional notes
+regarding UNISYS LZW patent.</li>
+<li>PerlMagick/Magick.xs: Applied Dissolve composite operator fix
+obtained from from John Cristy's ImageMagick which ensures that an
+unused matte channel is set to Opaque, and uses this knowledge to
+simplify the math.</li>
+<li>VisualMagick/configure/configure.cpp: The <cite>wand</cite> library has a
+linkage dependency on the <cite>magick</cite> library. Also don't include
+the magick subdirectory so that headers must be included like
+&lt;magick/api.h&gt; for safety.</li>
+<li>coders/xtrn.c: Fix magick header inclusion.</li>
+<li>lcmssrccmserr.c: Fix magick header inclusion.</li>
+</ul>
+</blockquote>
+<p>2003-06-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Fix to formatting. Fix spelling of origin.</li>
+<li>PerlMagick/t/bzlib/read.t: Add test for reading BZipped file.</li>
+<li>PerlMagick/t/subroutines.pl (testRead): Skip testing reads
+of compressed BLOBs because reading compressed BLOBs is not
+supported yet.</li>
+<li>coders/bmp.c (ReadBMPImage): Only validate the file size value
+for compressed BMPs.</li>
+<li>VisualMagick/wand, wand: First stab at building the Wand API
+under Visual C++. Still does not build as a DLL.</li>
+</ul>
+</blockquote>
+<p>2003-06-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/static.h: Add prototypes for RegisterXTRNImage and
+UnregisterXTRNImage.</li>
+<li>Makefile.am (DISTDIRS): Don't distribute the <cite>guide</cite>
+subdirectory. It is available for checkout from CVS.</li>
+<li>www: Utilities documentation is updated from &lt;imdoc&gt; masters.
+Formatting could be improved, but the content seems ok.</li>
+<li>doc/environment.imdoc: New file to describe environment
+variables.</li>
+<li>coders/cut.c (ReadCUTImage): Use MagickAllocateMemory and
+MagickFreeMemory rather than malloc and free.</li>
+<li>doc/gmdoc2html: Add GraphicsMagick styling to utility web pages.</li>
+<li>doc/Makefile: Additional documentation Makefile enhancements.</li>
+<li>AUTHORS: New file to acknowledge significant contributors
+to the software. If an author is not listed here, please let
+us know.</li>
+<li>configure.ac: test -a is not POSIX compliant.</li>
+</ul>
+</blockquote>
+<p>2003-06-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc: Source documentation for <cite>gm</cite> is now available via a <cite>doc</cite>
+CVS module. A Makefile is provided which formats the
+documentation and installs it into the <cite>www</cite> and <cite>utilities</cite>
+subdirectories.</li>
+</ul>
+</blockquote>
+<p>2003-06-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand: Added Magick Wand library available via
+-lGraphicsMagickWand and &lt;wand/wand_api.h&gt;. Use
+GraphicsMagickWand-config or GraphicsMagickWand.pc to obtain the
+compilation options required to use the library. Magick Wand is
+authored by John Cristy. Magick Wand is provided as a separate
+library from -lGraphicsMagick in order to assure the stability of
+the core GraphicsMagick library while allowing Magick Wand to
+to evolve.</li>
+<li>images: Replace existing logo images with cleaner ones.</li>
+<li>www: Update links to point to updated logo images.</li>
+<li>logos: New CVS directory to contain master logos.</li>
+<li>scripts/txt2html: Updated inline logo image link.</li>
+<li>scripts/format_c_api_docs: Updated inline logo image link.</li>
+<li>version.sh: Support versioning all libraries independently.</li>
+<li>coders/meta.c: Prefix include paths for safety.</li>
+<li>magick/image.h: (TransmitType) Removed unused enumeration.
+(ProfileType) Removed unused enumeration.
+(QuantumType) Moved enumeration to constitute.h
+(StorageType) Moved enumeration to constitute.h</li>
+<li>magick/draw.c (DrawPeekGraphicContext): Added function to peek
+at head of drawing context stack (function added for ImageMagick
+compatability).</li>
+<li>magick/image.c (CycleColormapImage): Change return type from
+<cite>void</cite> to <cite>unsigned int</cite> so that error status is returned to user.
+(DescribeImage): Change return type from
+<cite>void</cite> to <cite>unsigned int</cite> so that error status is returned to user.</li>
+<li>magick/list.c (ReplaceImageInList): Incorporated function from
+John Cristy's ImageMagick to replace current image in the list.</li>
+<li>coders/sgi.c (ReadSGIImage): Applied patch from John Cristy's
+ImageMagick to save the compression type for SGI images.</li>
+</ul>
+</blockquote>
+<p>2003-06-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c (WriteTXTImage): Apply patch from John Cristy's
+ImageMagick to observe image depth while writing pixel colors.
+This patch is not applied to the 1.0 branch because it represents
+an output format change which could break a dependent application.
+(IsTXT): Recognize files written by the TXT coder.
+(ReadTXTImage): Reject files written by the TXT coder until support
+for reading these files is implemented.
+(IsTXT): Ensure that sscanf doesn't read outside of provided data
+by using a fixed size buffer.</li>
+</ul>
+</blockquote>
+<p>2003-06-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Don't add -lfpx to LIBS while configuring
+because the C compiler may fail to link with it in later
+tests.</li>
+</ul>
+</blockquote>
+<p>2003-06-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: RotateImage is documented to take
+<cite>degrees</cite> argument, not <cite>degree</cite>. SwirlImage is documented to
+take <cite>degrees</cite> argument, not <cite>degree</cite>. SolarizeImage is
+documented to take a <cite>threshold</cite> argument, not <cite>factor</cite>. Wave is
+documented to take <cite>amplitude</cite> and <cite>wavelength</cite> arguments. Don't
+transform colorspace to RGB when retrieving <cite>pixel</cite> color value.
+Release memory acquired to store <cite>length</cite> pointer. Picked up
+memory leak fix related to <cite>SV **reference_vector</cite> variable from
+John Cristy's ImageMagick.</li>
+<li>configure: Incorporate patch to handle inline better.</li>
+<li>magick/utility.c (GetToken): Adjust code to avoid &quot;end-of-loop
+code not reached&quot; warning.</li>
+<li>magick/log.c (GetLogBlob): Eliminate warning regarding
+unreached code.</li>
+<li>magick/command.c (AnimateImageCommand): Eliminate warning regarding
+unreached code.
+(ConvertImageCommand): Eliminate warning regarding
+unreached code.
+(ImportImageCommand): Eliminate warning regarding
+unreached code.</li>
+<li>magick/type.c (GetTypeBlob): Eliminate warning regarding
+unreached code.</li>
+<li>magick/blob.c (GetConfigureBlob): Eliminate warning regarding
+unreached code.</li>
+<li>coders/meta.c (super_fgets): Eliminated warnings regarding
+comparison and return of incompatible pointer types.
+(super_fgets_w): Eliminated warnings regarding
+comparison and return of incompatible pointer types.</li>
+<li>magick/command.c (ConvertImageCommand): Eliminate warnings
+noticed when using Sun's compiler.</li>
+</ul>
+</blockquote>
+<p>2003-06-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>acinclude.m4: Add <cite>#undef inline</cite> in front of C++ tests.</li>
+<li>coders/x.c (RegisterXImage): Only register the X coder if HasX11
+is defined.</li>
+</ul>
+</blockquote>
+<p>2003-06-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GetImageGeometry) Y was a function of width
+instead of height when processing EastGravity or WestGravity
+(bug report from Cristy).</li>
+</ul>
+</blockquote>
+<p>2003-06-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (LocaleNCompare): Documented that comparison is
+case-insensitive.
+(LocaleCompare): Documented that comparison is case-insensitive.</li>
+<li>magick/log.c (ParseEvents): LocaleNCompare already does
+case-insensitive compare so lower-casing is not necessary.</li>
+<li>Magick++: Updates to cause exceptions to be thrown if a bad
+geometry specification is supplied.</li>
+</ul>
+</blockquote>
+<p>2003-06-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c (ReadConfigureFile): Move event parsing to
+ParseEvents funtion.
+(SetLogEventMask): Move event parsing to
+ParseEvents funtion.</li>
+<li>magick/utility.c (GetGeometry): Validate that the geometry
+string only contains valid characters.</li>
+<li>PerlMagick/t/subroutines.pl (testMontage): It seems that passing
+an empty set of options to the SetImage method corrupts the image
+options (surely a PerlMagick bug), so don't invoke SetImage unless
+there are options to set.</li>
+</ul>
+</blockquote>
+<p>2003-06-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (VersionCommand): Add build information to
+version output.</li>
+<li>configure.ac: Save configure/build parameters for later use in
+version output.</li>
+</ul>
+</blockquote>
+<p>2003-06-04 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c: Added some casts to make things compile better.</li>
+</ul>
+</blockquote>
+<p>2003-06-03 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c: Was broken due to editing mistakes as well
+as inherent incompatability with MagickReallocMemory macro.</li>
+</ul>
+</blockquote>
+<p>2003-06-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xpm.c (RegisterXPMImage): Module registration for PICON
+should have been XPM. Thanks to John Cristy for noticing this
+bug.</li>
+<li>coders/psd.c (ReadPSDImage): Applied John Cristy's patch to fix
+a index calculation bug which is evident when QuantumDepth&gt;8.</li>
+</ul>
+</blockquote>
+<p>2003-06-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c: Eliminated some compiler warnings.</li>
+<li>magick/transform.c (ProfileImage): Eliminated some compiler
+warnings.</li>
+<li>magick/static.c (RegisterStaticModules): Invoke
+RegisterXTRNImage if _VISUALC_ is defined.</li>
+</ul>
+</blockquote>
+<p>2003-06-02 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/gm.c: made -format work again but had to add off flag
+to MagickCommand to maintain backward compatability with previous
+versions of GM.</li>
+<li>magick/command.c: Added flag to tell MagickCommand whether GM is
+expected to process metadata requests. The COM object *always* does.</li>
+<li>magick/transform.c: Added error handling, memory leak avoidance
+and performanc enhancment.</li>
+</ul>
+</blockquote>
+<p>2003-06-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: Added Bug Fixes item with info about the JNG encoder fix.</li>
+</ul>
+</blockquote>
+<p>2003-06-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: Listed significant changes (thus far) in version 1.1.</li>
+<li>version.sh: Updated LIBRARY_CURRENT and LIBRARY_REVISION since
+some command.c interfaces have changed, and a new interface has
+been added. The only user of these interfaces should be <cite>gm</cite> but
+it always pays to be careful.</li>
+<li>utilities/gm.c (main): Use MagickCommand.</li>
+<li>magick/command.c (MagickCommand): New function to provide
+API-level command access to the command functions provided by the
+GM utility with an interface similar to ConvertImageCommand.
+(AnimateImageCommand): Changed function arguments to match
+ConvertImageCommand.
+(ConjureImageCommand): Changed function arguments to match
+ConvertImageCommand.
+(DisplayImageCommand): Changed function arguments to match
+ConvertImageCommand.
+(ImportImageCommand): Changed function arguments to match
+ConvertImageCommand.</li>
+<li>libxml/libxml2.def: Remove LIBRARY line since Visual C++ 6.0
+doesn't like that the build library doesn't match the name
+specified by LIBRARY.</li>
+</ul>
+</blockquote>
+<p>2003-05-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (GetMagickInfoArray): Resolve thread-safety
+issue by accessing magick_list directly under the protection of a
+lock rather than using the pointer returned by GetMagickInfo.
+Added error handling for insufficient memory.</li>
+<li>coders/tile.c (RegisterTILEImage): Added a usage note in formats
+listing.</li>
+<li>coders/viff.c (RegisterVIFFImage): Module definition for &quot;XV&quot;
+was missing.</li>
+<li>coders/ps2.c (RegisterPS2Image): Module definition for &quot;PS2&quot; was
+missing.</li>
+<li>coders/wmf.c (RegisterWMFImage): Added usage note in formats
+listing.</li>
+<li>coders/xpm.c (RegisterXPMImage): Hide PM alias for XPM in the
+formats listing.</li>
+<li>coders/logo.c (RegisterLOGOImage): Hide registrations for
+GRANITE, LOGO, and NETSCAPE in the formats listing.</li>
+<li>coders/jpeg.c (RegisterJPEGImage): Module definition for &quot;JPEG&quot;
+was missing.</li>
+<li>coders/html.c (RegisterHTMLImage): Module definition for &quot;HTML&quot;
+was missing.</li>
+<li>coders/bmp.c (RegisterBMPImage): Module names for &quot;BMP2&quot; and
+&quot;BMP3&quot; should be &quot;BMP&quot;.</li>
+</ul>
+</blockquote>
+<p>2003-05-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (GetMagickInfoArray): New function to return
+MagickInfo array.
+(ListMagickInfo): Updated to use GetMagickInfoArray.
+(ListModuleMap): New function to list module map to a file.</li>
+<li>utilities/gm.c: Centered the file header and made note of this
+stupendously significant accomplishment.</li>
+<li>magick/command.c: Added a <cite>-list modulemap</cite> option. Added plural
+forms of other list options for people who are are not limited to
+the singular. Also <cite>-list font</cite> and <cite>-list fonts</cite> now work for
+people who think in terms of fonts rather than type.</li>
+</ul>
+</blockquote>
+<p>2003-05-30 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>MNG encoder failed to set the JNG bit in the simplicity profile.</li>
+<li>MNG encoder failed to write FRAM chunks when all images were JNG.</li>
+<li>JNG encoder wrote the wrong alpha_sample_depth for opaque images.</li>
+</ul>
+</blockquote>
+<p>2003-05-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magic.c (ReadConfigureFile): Removed bogus embedded magic
+data and ensured that errors with loading magic.mgk propogate to
+the top.</li>
+<li>magick/constitute.c (ReadImage): When building delegate error
+report, handle the case where the filename is empty (such as for
+&quot;LOGO:&quot;).</li>
+<li>coders/png.c (WritePNGImage): Ensure that most severe exception
+is reported via exception argument.
+(ReadMNGImage): Ensure that most severe exception is reported via
+exception argument.</li>
+<li>magick/command.c (ConvertImageCommand): Ensure that most severe
+exception is reported via exception argument.
+(CompositeImageList): Ensure that most severe exception is
+reported via exception argument.
+(CompositeImageCommand): Ensure that most severe exception is
+reported via exception argument.</li>
+<li>magick/constitute.c (WriteImages): Ensure that most severe
+exception is reported via exception argument.</li>
+<li>utilities/gm.c: Centered file header because I didn't like it.</li>
+<li>locale/C.mgk: Removed some defunct messages.</li>
+<li>magick/blob.c (PingBlob): Report useful error message.
+(BlobToImage): Report sensible error message for null blob.</li>
+<li>magick/utility.c (AcquireString): Change UnableToAquireString to
+UnableToAllocateString.</li>
+<li>coders/xwd.c (ReadXWDImage): Report CorruptImage rather than
+CorruptXWDImage.</li>
+<li>coders/xpm.c (ReadXPMImage): Report CorruptImage rather than
+CorruptXPMImage.</li>
+<li>coders/xcf.c (load_level): Report CorruptImage rather than
+CorruptXCFImage.</li>
+<li>coders/wbmp.c (ReadWBMPImage): Report CorruptImage rather than
+CorruptWBMPImage.</li>
+<li>coders/pcd.c: Report CorruptImage rather than CorruptPCDImage.</li>
+<li>coders/otb.c (ReadOTBImage): Report CorruptImage rather than
+CorruptOTBImage.</li>
+<li>magick/constitute.c (ReadInlineImage): Report CorruptImage
+rather than CorruptInlineImage.</li>
+<li>coders/pdb.c (ReadPDBImage): Incorporated undocumented fix from
+ImageMagick which obtains the image depth from the image depth
+attribute, and increases the packet memory allocation. Report
+CorruptImage rather than CorruptPDBImageFile.</li>
+</ul>
+</blockquote>
+<p>2003-05-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/bin/modules.mgk: Add mapping from SVGZ to SVG.</li>
+<li>coders/modules.mgk: Add mapping from SVGZ to SVG.</li>
+<li>coders/svg.c (RegisterSVGImage): Add registration for SVGZ
+format.</li>
+<li>PerlMagick/t/zlib/read.t: Added test to check reading a file
+with .gz extension. The blob portion of the test currently fails.</li>
+<li>coders/wpg.c (ReadWPGImage): Fix reading WPGs with embedded
+Postscript. Ensure that scene numbers are sane. Bugs remain.</li>
+<li>magick/blob.c (OpenBlob): Recognize the .svgz extension as a
+gzipped format. Not required in order to read .svgz files since
+the blob file magic detects gzip files.</li>
+<li>magick/command.c (MontageImageCommand): Wrong exception
+macro was being invoked. Steps have been taken to ensure that
+this doesn't happen again.
+(ImportUsage): Fix spelling of <cite>type</cite>.</li>
+<li>magick/magick.c (DestroyMagick): Decided that initialization
+state should be tracked via an enum so that DestroyMagick will
+take effect even if InitializeMagick has never been called.</li>
+</ul>
+</blockquote>
+<p>2003-05-27 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: png.c would dump core when writing a grayscale
+image in png24 or png32 format.</li>
+</ul>
+</blockquote>
+<p>2003-05-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/ept.c (WriteEPTImage): Fixed writing EPT preview image and
+added logging.</li>
+<li>magick/enhance.c (NegateImage): If image is in CMYK colorspace,
+then negate the <cite>K</cite> channel as well.</li>
+<li>PerlMagick/Magick.xs: Fix spelling of <cite>elevation</cite> argument to
+Shade method.</li>
+<li>magick/image.h (ImageInfo): Added more documenting comments.</li>
+<li>magick/image.c (CloneImage): Don't clone huffman ascii85
+encoding support structure since it is not useful outside of the
+current image context. Cloning a structure via pointer assignment
+causes a memory leak.</li>
+</ul>
+</blockquote>
+<p>2003-05-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c: Incorporate math tweaks obtained from
+ImageMagick which are purported to improve accuracy when rotating
+and shearing using small angles. Also avoid unneccessarily
+transforming CMYK images into RGB images.</li>
+<li>magick/paint.c (ColorFloodfillImage): Fix hang while
+floodfilling using a pattern image with color similar to the
+border color.</li>
+<li>coders/modules.mgk: Add missing mappings for PNG8,
+PNG24, and PNG32.</li>
+<li>VisualMagick/bin/modules.mgk: Add missing mappings for PNG8,
+PNG24, and PNG32.</li>
+</ul>
+</blockquote>
+<p>2003-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c (GetLogBlob): Return an error if log.mgk can not
+be accessed.</li>
+<li>locale/C.mgk: Added UnableToAccessLogFile.</li>
+<li>magick/blob.c (GetConfigureBlob): Only return result of
+NTResourceToBlob if it is non-NULL.</li>
+<li>magick/type.c (GetTypeBlob): Search $MAGICK_HOME for
+type.mgk. Only return result of NTResourceToBlob if it is
+non-NULL.</li>
+<li>magick/magick.c (GetMagickInfo): Return an error if GetModuleInfo
+reports an error.</li>
+<li>magick/module.c (GetModuleInfo): Return an error if modules.txt
+fails to load.</li>
+<li>utility.c (SubstituteString): Fixed a bug which was introduced
+while updating the code to use the memory allocation macros.</li>
+</ul>
+</blockquote>
+<p>2003-05-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/GraphicsMagick-config.in (usage): Added example
+usage to the help output.</li>
+<li>magick/magick.c (InitializeMagick): Added a static flag to
+ensure that the Magick library is initialized only one time.
+(DestroyMagick): Ensure that Magick library resources are only
+destroyed if it has previously been initialized.</li>
+<li>magick/nt_base.c (DllMain): Fix contributed by Achim Domma. For
+a DLL build, update PATH during Magick DLL initialization to
+include the directory where the Magick core DLL resides. This
+allows the loadable modules to find the core DLLs, even if the
+core DLLs are not already in the PATH.</li>
+<li>magick/image.c (TextureImage): Incorporate new implementation
+authored by John Cristy of ImageMagick Studio. This
+implementation is a full 7X (run-time) or 14X (user-time) faster
+than the original ImageMagick implementation, and is about 2X
+faster than the speeded-up version I commited on the 19th.</li>
+</ul>
+</blockquote>
+<p>2003-05-20 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagickconfigure : Fixed bug with add on (plug-ins) not
+building automatically in DLL mode.</li>
+</ul>
+</blockquote>
+<p>2003-05-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (TextureImage): Creation of tiled image textures
+is speeded up by 3.7X.</li>
+<li>coders/tile.c (ReadTILEImage): Use TextureImage.</li>
+<li>VisualMagick/bin/modules.mgk: Map &quot;PATTERN&quot; to &quot;LOGO&quot;.</li>
+<li>coders/modules.mgk: Map &quot;PATTERN&quot; to &quot;LOGO&quot;.</li>
+<li>coders/logo.c (ReadLOGOImage): Add &quot;PATTERN&quot; tiling support in
+order to be compatible with ImageMagick.</li>
+<li>magick/image.c (SetImageInfo): Map &quot;MAGICK&quot; magick to &quot;IMAGE&quot; in
+order to be compatible with ImageMagick.</li>
+</ul>
+</blockquote>
+<p>2003-05-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Copyright.html: Try to fix formatting of XFig entry.</li>
+<li>www/windows.html: Update file names for 1.0.1 release.</li>
+<li>index.html: Mention 1.0.1 release as latest release.</li>
+<li>magick/magick_config_api.h.in: Add define for HasX11
+so that it is possible to use functions in the installed
+xwindow.h</li>
+<li>*/*.c: Updated to use MagickAllocateMemory macro.</li>
+</ul>
+</blockquote>
+<p>2003-05-17 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: stifled compiler warnings about uninitialized
+chunk and blob variables.</li>
+</ul>
+</blockquote>
+<p>2003-05-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.h (MagickAllocateMemory): New macro to allocate
+memory.
+(MagickFreeMemory): New macro to free memory.
+(MagickReallocMemory): New macro to reallocate memory.</li>
+<li>*/*.c,*/*.h: Updated to use MagickFreeMemory and
+MagickReallocMemory. Eliminated warnings when compiling with
+GCC 3.3 using -Wall.</li>
+<li>images: The logo image was determined to have a copyright
+problem so replace with blank image until a replacement is
+available.</li>
+</ul>
+</blockquote>
+<p>2003-05-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/magick/magick_config.h.in (HAVE_SYS_TYPES_H):
+Moved this define back from nt_base.h since removing it was
+causing some problems for Magick++.</li>
+</ul>
+</blockquote>
+<p>2003-05-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: (SetMagickInfo): Don't mask failure to
+read magic.mgk.</li>
+<li>magick/constitute.c (ReadImage): Don't overwrite specific
+exception info.</li>
+<li>magick/nt_base.c (NTResourceToBlob): Add logging similar
+to that used in IsAccessible() in order to make operation
+more clear.</li>
+<li>magick/module.c (FindMagickModule): Removed extraneous
+&quot;Searching for module file&quot; log event.
+(GetModuleBlob): Under Windows, don't clear or overwrite
+an existing exception.</li>
+<li>magick/nt_base.h: Imported some obscure defines from
+magickmagick_config.h.</li>
+<li>VisualMagick/magick/magick_config.h.in: Improved description
+text and formatting. Moved some obscure defines to
+magick/nt_base.h.</li>
+<li>locale/C.mgk: Added a &quot;RegistryKeyLookupFailed&quot; error message.</li>
+<li>magick/type.c (GetTypeBlob): Report registry key lookup
+failures. Also ensure correct return value when an error is
+reported.</li>
+<li>magick/log.c (GetLogBlob): Report registry key lookup failures.</li>
+<li>magick/delegate.c (ReadConfigureFile): Report registry key
+lookup failures.</li>
+<li>magick/blob.c (GetConfigureBlob): Report registry key lookup
+failures. Also ensure correct return value when an error is
+reported.</li>
+<li>magick/module.c (FindMagickModule): Report registry key lookup
+failures. Also ensure correct return value when an error is
+reported.</li>
+<li>magick/nt_base.c (NTRegistryKeyLookup): Simplify base key lookup
+code, and improve coding style.</li>
+<li>coders/logo.c, Copyright.txt, www/Copyright.html: Acknowledge
+and respect the XFig copyright.</li>
+<li>VisualMagick/installer/inc/files-documentation.isx: QuickStart.txt
+is no longer distributed so it is removed.</li>
+</ul>
+</blockquote>
+<p>2003-05-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h (RoundToQuantum): New macro to round positive
+double to Quantum.</li>
+<li>magick/xwindow.c, magick/xwindow.h, magick/studio.h: Use FreeBSD
+portability fixes from FreeBSD ports collection.</li>
+<li>configure.ac: Test for &lt;machine/param.h&gt; as used by some *BSD systems.</li>
+<li>QuickStart.txt, www/QuickStart.html: Don't distribute QuickStart.txt or
+www/QuickStart.html since the content doesn't currently apply to
+GraphicsMagick.</li>
+</ul>
+</blockquote>
+<p>2003-05-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>README.txt: Added text regarding where to obtain dcraw, a simple
+but useful decoder for the proprietary raw file formats produced
+by digital cameras (58 supported cameras!).</li>
+<li>configure.ac: Added support for finding dcraw.</li>
+<li>VisualMagick/bin/delegates.mgk: Added support for dcraw.</li>
+<li>coders/delegates.mgk.in: Added support for dcraw.</li>
+<li>version.sh (PACKAGE_RELEASE_DATE): Extract the most recent
+update date from the ChangeLog file using awk.</li>
+</ul>
+</blockquote>
+<p>2003-05-12 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>modules.mgk, magic.mgk : Sync up both of these for UNIX
+as well as VisualMagick builds. Includes changes for the
+meta.c code.</li>
+</ul>
+</blockquote>
+<p>2003-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/formats.html: Documented embedded gray intensity images.</li>
+<li>coders/logo.c: Added the embedded dithered gray intensity images
+gray0, gray5, ..., through gray100 to support bilevel filling and
+painting with an intensity resolution of 5%.</li>
+<li>www/formats.html: Added description of images available via
+&quot;IMAGE:&quot; format tag, as well as providing a tiled preview.</li>
+<li>coders/logo.c: Renamed &quot;transparent&quot; image to &quot;checkerboard&quot;
+since it is a better description. Added a set of tiny bilevel
+images (accessed via IMAGE:) for use when tiling, filling, or for
+use as a texture image. The complete set of image names available
+via the IMAGE: coder are now BRICKS, CIRCLES, CROSSHATCH,
+CROSSHATCH30, CROSSHATCH45, FISHSCALES, GRANITE, HEXAGONS,
+HORIZONTAL, HORIZONTALSAW, HS_BDIAGONAL, HS_CROSS, HS_DIAGCROSS,
+HS_FDIAGONAL, HS_HORIZONTAL, HS_VERTICAL, LEFT30, LEFT45,
+LEFTSHINGLE, LOGO, NETSCAPE, OCTAGONS, RIGHT30, RIGHT45,
+RIGHTSHINGLE, ROSE, SMALLFISHSCALES, CHECKERBOARD, VERTICAL,
+VERTICALBRICKS, VERTICALLEFTSHINGLE, VERTICALRIGHTSHINGLE, &amp;
+VERTICALSAW. The HS_* variants are similar to the standard
+pattern images provided with the Windows GDI.</li>
+<li>coders/msl.c (MSLStartElement): Don't reset gravity if the user
+provides an x,y coordinate. Passing coodinates was loosing the
+gravity setting.</li>
+</ul>
+</blockquote>
+<p>2003-05-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/modules.mgk: Support the IMAGE: format via the LOGO
+module.</li>
+<li>win2k/IMDisplay/IMDisplayView.cpp (DoDisplayImage):
+Transparent tile is created by reading &quot;tile:image:transparent&quot;.</li>
+<li>coders/logo.c (ReadLOGOImage): Add IMAGE: format to front for
+embedded images so that adding new images doesn't proliferate coder
+registrations. Legacy logo magick names (GRANITE, LOGO, NETSCAPE,
+and ROSE) are still supported, but they are also available in the
+IMAGE file space (e.g. IMAGE:ROSE).</li>
+</ul>
+</blockquote>
+<p>2003-05-09 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagickconfigure : Further refinements that support both
+the new &quot;big&quot; library and the normal dynamic DLL buidling styles.</li>
+</ul>
+</blockquote>
+<p>2003-05-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/logo.c (ReadLOGOImage): Added a &quot;TRANSPARENT&quot; pattern
+image which can be tiled to form the background of transparent
+images.</li>
+<li>win32/IMDisplay/IMDisplayView.cpp: When displaying images which
+include an opacity channel, use a checker-board pattern as the
+image background so non-opaque pixels become evident.</li>
+</ul>
+</blockquote>
+<p>2003-05-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c : Add or fix commenting of DebugString so that
+module does not require Windows.</li>
+<li>lcms: Updated to release 1.10.</li>
+</ul>
+</blockquote>
+<p>2003-05-07 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagickbin : Brought the MGK files back into sync with
+the rest of the package and added types for meta.c.</li>
+<li>VisualMagickbinwin32ATL : removed config files in order to
+prevent very old ATL project from being picked up in the config</li>
+</ul>
+</blockquote>
+<p>2003-05-06 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagicklcmsLIBRARY.txt : a define to prevent popup message
+box behaviour.</li>
+<li>VisualMagickconfigure: New feature - -t consolidates all the
+coders into on library for the static build in order to make the
+build process tolerable.</li>
+<li>codersxtrn.c : new support for BSTR - wdie character data</li>
+<li>coderssvg.c : put back logic that allows the -size parameter to
+control the pixel dimensions of the output image.</li>
+<li>codersmeta.c : added support for wide character parsing of iptc
+and 8BIM formats.</li>
+</ul>
+</blockquote>
+<p>2003-05-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh : Update to reflect development status.</li>
+</ul>
+</blockquote>
+<p>2003-05-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick 1.0 Released.</li>
+<li>version.sh (LIBRARY_REVISION): Updated for the 1.0 release.</li>
+<li>magick/studio.h: Add fix to avoid problems caused by zlib
+under AIX.</li>
+<li>magick/cache.h: Parameterized prototypes to make them easier
+to follow.</li>
+<li>filters/analyze.c: Replace C++ comments with C comments.</li>
+<li>magick/command.c: For the composite, convert, identify, mogrify,
+and montage commands, make sure a usage error is returned if a
+usage message is printed. This is useful for ImageMagickObject
+users who won't see the usage message if stdio is not supported.</li>
+<li>locale/C.mgk: Added &quot;UsageError&quot; error. Added missing closure
+to &lt;Corrupt&gt; tag which caused most/many message lookups to fail.</li>
+<li>magick/nt_base.h: Fixed a compile problem caused by masking
+internals in delegate.h</li>
+<li>magick/ImageMagick.rc: Added missing .mgk files.</li>
+</ul>
+</blockquote>
+<p>2003-05-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (lt_dlerror): Defining lt_dlerror to be
+NTGetLastError was not a correct implementation since the
+interface is defined to return a const pointer to a string, but
+NTGetLastError returns an allocated string, causing a memory leak
+if NTGetLastError is used in the place of lt_dlerror. A new
+lt_dlerror function is added to fix this.
+(lt_dlsetsearchpath): lt_dlsetsearchpath should return an int
+and accept a const char *.
+(lt_dlsym): lt_dlsym is supposed to take a const char *.</li>
+<li>magick/nt_base.h: lt_dlclose should return an <cite>int</cite>.</li>
+<li>magick/nt_base.c (lt_dlclose): Return status from lt_dlclose.</li>
+<li>magick/module.c (lt_dlclose): lt_dlclose is supposed to return
+an <cite>int</cite>, not <cite>void</cite>. A return value of zero indicates success.</li>
+<li>VisualMagick/tests/run_constitute.bat: Add batch script to
+run constitute tests.</li>
+<li>magick/module.c: Added a ltdl_initialized static flag to track
+if libltdl has been initialized by lt_dlinit().
+(TagToFunctionName): Use a stack buffer for the string rather than
+allocating heap data.
+(UnregisterModule): Report errors via exception info as the
+interface suggests.
+(UnloadModule): Report errors via exception info as the interface
+suggests.
+(DestroyModuleInfo): Only invoke lt_dlexit() if lt_dlinit() has
+previously been invoked.</li>
+<li>locale/C.mgk: Added FailedToCloseModule module error.</li>
+<li>magick/module.c (UnloadModule): Report exception via exception
+parameter rather than simply printing out an error message and
+exiting.</li>
+<li>magick/Makefile.am (noinst_HEADERS): integral_types.h had to be
+listed *somewhere* in order to make it into the distribution.</li>
+<li>Magick++/lib/Magick++/Image.h: InitializeMagick must be DLL
+exported.</li>
+</ul>
+</blockquote>
+<p>2003-05-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (magick-version): Perform version.isx substitutions
+via Makefile.am rather than configure.</li>
+<li>magick/magick_config_api.h.in: Added template header for
+the installed magick_config.h.</li>
+<li>magick/magick.c (InitializeMagick): Improved the signal handling
+and registration method. Signal handlers are only registered for a
+signal if the current signal handling disposition for that signal
+is set to the default (SIG_DFL). When a signal is caught,
+DestroyMagick is invoked, the handling for the signal is set back
+to SIG_DFL, and then the signal is re-raised to trigger the
+default handler for that signal. This causes the process to behave
+as closely to the default as possible (e.g. generating a core
+file) while ensuring that DestroyMagick is executed. This also
+ensures that signal handlers registered by API users are not
+overridden by invoking InitializeMagick.</li>
+<li>configure.ac: Added tests for sigemptyset and
+sigaction.
+Add a check for the return type of signal handlers.
+Test for the <cite>raise</cite> function.</li>
+<li>www/formats.html: Add an entry for CUR, Microsoft
+Cursor Icon format.</li>
+</ul>
+</blockquote>
+<p>2003-05-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/semaphore.c (struct SemaphoreInfo): Added
+<cite>locked</cite> and <cite>thread_id</cite> members. These are used to record
+if the semaphore is locked, and to validate the thread
+ID of the unlocker.</li>
+<li>www/links.html: Added link to Nathan Day's MagickDocs
+&quot;ImageMagick and GraphicsMagick documentation project&quot;
+site.
+Added a link to an on-line article regarding the PHP front-end
+to ImageMagick.</li>
+<li>coders/icon.c (ReadIconImage): Add support for Windows
+.CUR format based on advice from Jean Piquemal.</li>
+<li>magick/image.c (SetImageInfo): Added missing CloseBlob
+in error path for failure to allocate temporary file.</li>
+<li>coders/pcx.c (ReadPCXImage): Added support for reading
+uncompressed PCX images based on code from Jean Piquemal.</li>
+</ul>
+</blockquote>
+<p>2003-05-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (AddNoiseImage): For gray images, wrong
+pointer was being used to evaluate intensity, leading to a
+black image with noise.</li>
+<li>magick/image.c (ChannelImage): Return the channel
+image in RGBColorspace. Also properly support extracting
+the opacity channel for images which are not CMYK.</li>
+</ul>
+</blockquote>
+<p>2003-04-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/Makefile.am (install-data-local): Install
+magick_config_api.h rather than magick_config.h.</li>
+<li>magick/api.h: Removed inclusion of integral_types.h from
+magick/api.h. It is included by magick/studio.h.</li>
+<li>magick/delegate.h: Mapped out a block of private implementation
+code.</li>
+<li>configure.ac: Perform substitutions on magick_config_api.h.</li>
+<li>magick/magick_config_api.h.in: New header file template to
+use for installed magick_config.h.</li>
+<li>magick/studio.h (MAGICK_IMPLEMENTATION): Added the define
+MAGICK_IMPLEMENTATION used to enable private types, includes, and
+defines in the headers. This supports hiding implementation stuff
+that API users shouldn't see in the headers.</li>
+<li>utilities/Makefile.am (check): Cleaned up the utilities
+test/demo a bit as well as using the undocumented &quot;tmp:&quot; prefix to
+cause GraphicsMagick to remove temporary input files once they
+have been read. This leaves just the final output file
+&quot;demo.miff&quot; when the test completes.</li>
+<li>coders/jpeg.c (WriteJPEGImage): If the image resolution is
+overwritten with 72DPI, make sure that the resolution units are
+set to PixelsPerInchResolution.</li>
+<li>coders/jpeg.c (WriteJPEGImage): Don't overwrite the image
+resolution if it is valid.</li>
+<li>magick/command.c (MogrifyImageCommand): Added -resample
+option to match documentation.</li>
+<li>VisualMagick/configure: Added rpcrt4.lib to project settings
+for Visual C++ 6.0 so that configure links. The code which
+needs these interfaces is to support Visual C++ 7.0 XML-style
+project files.</li>
+</ul>
+</blockquote>
+<p>2003-04-30 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/Makefile.am (check) Change % to %% in -label parameter.</li>
+<li>www/gm.html, utilities/gm.1, etc. Documented use of %% to convey
+the % sign in -format, -comment, -label strings.</li>
+</ul>
+</blockquote>
+<p>2003-04-30 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Changes from 2003-04-19 to free the arg
+list when it was still pointed to by the option arg and accessed
+on an exception. This caused gm to crash on any erroneous command
+line argument.</li>
+</ul>
+</blockquote>
+<p>2003-04-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/windows.html: Updated to match current installer.</li>
+<li>VisualMagick/installer/inc/tasks-install-devel.isx (Name):
+Added an installation checkbox so the user can select to install
+development headers and libraries for C &amp; C++.</li>
+<li>VisualMagick/installer/inc/files-perlmagick.isx (Source):
+Only install PerlMagick PPD files if the user selects to install
+PerlMagick.</li>
+<li>VisualMagick/installer/inc/files-com.isx (Source): Only
+install ImageMagickObject files if the user selects to install
+ImageMagickObject.</li>
+<li>magick/version.h.in: Added some documentation for the
+functioning of MagickLibVersion and MagickLibVersionNumber.</li>
+<li>configure.ac: Perform substutions to create
+VisualMagick/installer/inc/version.isx from
+VisualMagick/installer/inc/version.isx.in. This allows Windows
+versioning info to be updated from info in version.sh.</li>
+<li>Makefile.am (magick-version): For a VPATH build, update
+VisualMagick/installer/inc/version.isx in the source directory if
+it is out of date.</li>
+</ul>
+</blockquote>
+<p>2003-04-28 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cache.c: CloneImagePixels(): applied Cristy's bugfix
+from IM-5.5.7.</li>
+</ul>
+</blockquote>
+<p>2003-04-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/api.html: The demo program on the ImageMagick API page is
+usually intended to be an exercise for the reader. It rarely
+compiles or works. Sure enough the demo code was not even close
+to compiling, didn't run, and did something totally different than
+described. This is not a good way to treat new users. Now the
+demo program compiles and runs, and its description is correct.</li>
+<li>www/magick.css, www/smile.c: Remove &quot;Pair&quot; advertisement which
+was discovered appended at the end of these files.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Check for failure of
+AllocateImage. Close blob prior to error return.</li>
+<li>configure.ac: Perform substitutions on magick/version.h</li>
+<li>magick/version.h.in: New file to provide base for configured
+magick/version.h</li>
+<li>version.sh (PACKAGE_RELEASE_DATE): Support setting a package
+release date.</li>
+<li>configure.ac: Perform substitutions on PerlMagick/Magick.pm.in to
+create PerlMagick/Magick.pm.in.</li>
+<li>PerlMagick/Magick.pm.in: &#64;PACKAGE_VERSION&#64; is substituted while
+configuring PerlMagick/Magick.pm.</li>
+<li>magick/magic.mgk, VisualMagick/bin/magic.mgk: Removed risky
+entry for PICT which has been demonstrated to lead to a false
+match in the real-world.</li>
+<li>coders/pict.c (ReadPICTImage): Ensure that PICT decoder don't
+loop forever with an EOF condition if none of the PICT op-codes
+encountered result in a condition which terminates the input loop.
+If EOF is dectected while in the input loop a &quot;corrupt image&quot;
+&quot;unexpected end of file&quot; error is reported.</li>
+<li>VisualMagick/installer: Updated installer.</li>
+</ul>
+</blockquote>
+<p>2003-04-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c, magick/blob.c, magick/studio.h: Added
+Compilation fixes recommended by Harold Bien for for Borland C++.</li>
+<li>www/contribute.html: Added text regarding contributing to
+GraphicsMagick.</li>
+<li>www/api/types.html: Documentation for GraphicsMagick API types
+moved from www/api/types/*.html into this one file. Types
+documentation is still very much under development.</li>
+<li>README.txt: Added note regarding the download location for free
+Windows fonts which are kindly made available by Microsoft.</li>
+<li>VisualMagick/installer/gm-dynamic-full-*.iss: Install
+nt_base.h and nt_feature.h.</li>
+</ul>
+</blockquote>
+<p>2003-04-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/windows.html: Updated for GraphicsMagick 1.0 and to
+link to ImageMagickObject.html.</li>
+<li>www/programming.html: Added link to ImageMagickObject.html.</li>
+<li>www/ImageMagickObject.html: New file to provide some
+documentation for ImageMagickObject.</li>
+<li>www: Found and fixed broken URL links.</li>
+</ul>
+</blockquote>
+<p>2003-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>FlashPIX: Applied patches from FreeBSD. Bumped package
+version to version to 1.2.0.8.</li>
+<li>www/api.html: Updated to reflect GraphicsMagick</li>
+<li>www/*.html: Updated with format_c_api_docs script.</li>
+<li>Makefile.am (format_c_api_docs): Add a target to update
+the C API documentation.</li>
+<li>scripts/format_c_api_docs: Add script which extracts and
+formats the C API documentation into HTML files in the www/api
+subdirectory.</li>
+</ul>
+</blockquote>
+<p>2003-04-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh (PACKAGE_VERSION): Update release version ID.</li>
+<li>magick/version.h (MagickReleaseDate): Update release date.</li>
+<li>magick/constitute.c (ConstituteImage): Fixed problems with
+reading intensity (gray) pixel arrays.</li>
+<li>magick/image.c (GrayscalePseudoClassImage): Use
+ScaleQuantumToIndex rather than ScaleQuantumToMap.</li>
+<li>magick/constitute.c (ConstituteImage): Use ScaleQuantumToIndex
+macro to scale integral intensity values to colormap range.</li>
+<li>magick/image.h (ScaleQuantumToIndex): New macro to scale a
+quantum to the maximum range of a colormap index. Useful when
+writing to PsuedoClass grayscale images.</li>
+<li>VisualMagick/tests/run_constitute.bat: Batch script to run
+constitute tests.</li>
+<li>VisualMagick/installer/*.iss: Updated for Beta1 release.</li>
+</ul>
+</blockquote>
+<p>2003-04-22 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/Makefile.am (check) fixed typos (RM -&gt; RMDelegate
+and removed stray &quot;gm&quot;), added -random-threshold, ordered-dither.</li>
+<li>magick/effect.c: Random-threshold was not treating non-gray
+PseudoColor images correctly.</li>
+</ul>
+</blockquote>
+<p>2003-04-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/Makefile.am (check): Added code to put logo on demo
+output.</li>
+<li>magick/command.c (MontageImageCommand): Pass exception rather
+than &amp;image-&gt;exception because image may be null, and it is
+pointless to store the exception where it will not be reported to
+the user anyway.</li>
+<li>utilities/Makefile.am (check): Ported Glenn Randers-Pehrson's
+utilities demo script into the Makefile to serve as a check
+target.
+(check): Add definition to find Generic.ttf.</li>
+<li>locale/C.mgk: Fixed syntax error in &lt;Option&gt;&lt;FatalError&gt;
+section.</li>
+<li>www/development.html: New file to describe development
+process.</li>
+<li>index.html, www/*.html: Added link to development.html
+and improved formatting a bit.</li>
+</ul>
+</blockquote>
+<p>2003-04-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed bug with compiling png.c with libpng versions
+older than libpng-0.95.</li>
+</ul>
+</blockquote>
+<p>2003-04-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/programming.html: Added links to Delphi and Scheme
+programming interfaces.</li>
+<li>configure.ac : Removed outdated test for jp2conf.h.</li>
+</ul>
+</blockquote>
+<p>2003-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Add argument expansion and deallocation code
+to command functions which lacked this functionality.
+Replace calls to Exit with a return to the invoking function.</li>
+<li>utilities/gm.c: Expect each subcommand to expand and deallocate
+its own argument list. Treat subcommands more similarly.</li>
+<li>magick/magick.c (InitializeMagick): Seed the random number
+generator.</li>
+<li>magick/utility.c (ExpandFilenames): Handle tilde expansion
+properly. Handle relative glob specifications. Skip over &quot;*&quot;
+argument to +profile properly. Don't expand VID: specifications
+since the VID: coder will execute ExpandFilenames() later. Apply
+format specifier prefix to globbed file names. Fix double frees
+and rationalize memory management by always copying to a new
+vector.</li>
+</ul>
+</blockquote>
+<p>2003-04-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (InitializeMagick): Decided to
+move clean-up signal-handler registration from gm.c
+to magick.c in order to ensure that resources are
+cleaned up for all library users. This means that
+if a user program wants to do something special for
+signals registered to be caught by InitializeMagick
+(SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGTERM, SIGXCPU,
+&amp; SIGXFSZ) then the user program should register its
+own signal handlers after invoking InitializeMagick.
+The user is then responsible for making sure that
+DestroyMagick is invoked if an unexpected signal is
+caught.</li>
+<li>tests/Makefile.am (check-constitute): Added
+constitute tests.</li>
+<li>magick/constitute.c: New test program to ensure
+that ConstituteImage and DispatchImage are working
+correctly.</li>
+</ul>
+</blockquote>
+<p>2003-04-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/download.html: Added links to directories
+at ftp.graphicsmagick.org.</li>
+<li>index.html: Add notice regarding 1.0 Beta0
+availability.</li>
+<li>www/cvs.html: Updated CVS checkout information to
+include the GraphicsMagick-1_0 branch.</li>
+<li>coders/psd.c (ReadPSDImage): Applied patch
+(SourceForge patch ID 722849) from Derry Bryson to
+fix a memory leak. An image was being leaked.</li>
+<li>magick/constitute.c (DispatchImage): Applied patch
+(SourceForge patch ID 722655) from Derry Bryson to
+correctly use the switch_map array rather than the
+map array. Without this patch, DispatchImage does
+not work at all.</li>
+<li>GraphicsMagick 1.0.0-beta0 release.</li>
+<li>version.sh: Updated for beta0 release.</li>
+<li>*.c magick/*.h: Update header inclusion to include
+&quot;magick/&quot; prefix in order to ensure that there is no
+confusion with headers from another package.</li>
+</ul>
+</blockquote>
+<p>2003-04-16 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c: 4x4 ordered dither threshold was
+incorrect.</li>
+</ul>
+</blockquote>
+<p>2003-04-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (InitializeMagickResources):
+Added the ability to obtain the amount of physical
+memory by executing an external command.</li>
+<li>configure.ac: Check for getpagesize().
+(MAGICK_PHYSICAL_MEMORY_COMMAND): Added a test for
+an external command which (quickly) returns the
+amount of physical memory installed on the machine.
+Currently only activated for FreeBSD.
+(MAGICK_PHYSICAL_MEMORY_COMMAND): Use sysctl to
+determine total physical memory for Darwin.</li>
+<li>magick/delegate.c (ListDelegateInfo): If COLUMNS
+environment variable is set, then use it to obtain
+the screen width. Some shells dynamically update
+COLUMNS, but COLUMNS may need to be explicitly
+exported in order for it to be seen by subordinate
+programs (such as gm).</li>
+<li>magick/effect.c (AddNoiseImage): Use IsGrayImage()
+to check if the image is gray. Add missing columns
+loop for intensity case (oops!).</li>
+<li>magick/command.c (DisplayImageCommand): Fix
+-dispose option processing bug reported by
+Felix Heimbrecht.</li>
+<li>coders/fpx.c: Check status from FPX_InitSystem().</li>
+</ul>
+</blockquote>
+<p>2003-04-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Define PERLMAINCC to be the C compiler
+if there are no C++ dependencies, or the C++ compiler
+if there are C++ dependencies.</li>
+<li>PerlMagick/Makefile.PL.in: Use PERLMAINCC to compile
+and link perlmain.c. This allows using the C++ compiler
+to link, which is useful when the build depends on C++
+libraries like libfpx.</li>
+<li>ltmain.sh: Updated to libtool 1.5 release.</li>
+<li>Makefile.am ($(PERLMAGICK)/$(PERLSTATICNAME)): Add
+rules to make sure that static PerlMagick is linked
+against the current GraphicsMagick library.</li>
+<li>coders/miff.c (ReadMIFFImage): Properly scale
+colormap entries.</li>
+<li>magick/image.c (TransformRGBImage): Eliminate 32-bit
+integer overflow condition for Q:32 build while
+transforming CMYK pixels.</li>
+</ul>
+</blockquote>
+<p>2003-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/ttf/read.t: Updated signatures and
+reference image for FreeType 2.1.4.</li>
+<li>(PerlMagick/t/write.t, PerlMagick/t/montage.t,
+PerlMagick/t/rad/read.t, PerlMagick/t/rad/write.t):
+Fix signatures which were thrown off by previous
+change to how signatures are specified to functions
+in subroutines.pl.</li>
+<li>PerlMagick/t/cgm/read.t: Updated to use reference
+image.</li>
+<li>PerlMagick/Makefile.PL.in: Perform substitutions
+on generated Makefile to ensure that the proper
+-lGraphicsMagick is used for a static build.</li>
+<li>ttf: Updated to FreeType 2.1.4. Now stored in
+CVS as delegates/freetype2 rather than delegates/ttf
+so be sure to re-checkout the ttf directory so that
+the correct files are used.</li>
+<li>wmf/incude/libwmf/api.h: Updating FreeType caused
+a problem since it introduced a copy of zlib and
+api.h included zlib.h. Fixed problem by adding
+a typedef for gzFile and not including zlib.h.</li>
+<li>utilities/gm.c: Fixed minor compilation problem
+under Windows caused by a typo in the signal
+handler registration code.</li>
+</ul>
+</blockquote>
+<p>2003-04-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: When building a static PerlMagick,
+build PerlMagick as part of the <cite>all</cite> target and
+don't do a <cite>make clean</cite> of PerlMagick at install
+time.</li>
+<li>configure.ac (LIB_DPS): Add check to see if -lXt
+is required by -ldps. XFree86 -ldps requires -lXt.</li>
+<li>FlashPIX: FlashPIX library now compiles under
+FreeBSD 5.0.</li>
+<li>magick/deprecate.c (ValidateColormapIndex): Remove
+non-interface deprecated function.</li>
+<li>magick/tempfile.c (AcquireTemporaryFileDescriptor):
+Priortize use of mkstemp() over tempname() since *BSD
+compilers whine about tempname() (although we do use
+tempname() safely).</li>
+<li>magick/color.c (ConstrainColormapIndex): Removed
+function since it is no longer used.</li>
+<li>magick/utility.c (TemporaryFilename): Removed
+TemporaryFilename utility function since it is
+no longer used and it makes *BSD compilers
+complain.</li>
+<li>magick/studio.h: Don't define _ISOC99_SOURCE,
+_POSIX_C_SOURCE, or _XOPEN_SOURCE when compiling
+under FreeBSD since this maps out a <cite>ushort</cite>
+definition required by /usr/include/sys/ipc.h.</li>
+</ul>
+</blockquote>
+<p>2003-04-11 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Some grayscale PNG images and the
+JNG alpha channel were decoded improperly at Q:32.</li>
+<li>magick/constitute.c (PopImagePixels): Changed many
+instances of (Quantum) typecast to (unsigned char).</li>
+</ul>
+</blockquote>
+<p>2003-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/tiff/read.t: Added signature for 12-bit
+TIFF test and a Q:32 build.</li>
+<li>PerlMagick/t/subroutines.pl: Extended routines
+which are signature based to accept signatures for
+Q:32 as well.</li>
+<li>PerlMagick/t/wmf/read.t: Relax error values slightly
+to pass at Q:32.</li>
+<li>coders/miff.c (PushImageRLEPixels): Fix reading
+RLE MIFF at Q:32. A fragment of old code was being
+used to obtain the length.
+(WriteRunlengthPacket): Fix writing RLE MIFF at Q:32.
+In most cases the wrong scaling macro was being used.</li>
+<li>tests/Makefile.am (check-miff): Added MIFF tests
+for supported compression options.</li>
+</ul>
+</blockquote>
+<p>2003-04-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/color.c (QueryColorDatabase): Extended to
+support parsing Q:32 hex color specification strings.
+Also add error reporting for failure to parse the
+color specification. This resolves a bug that drawing
+via the draw.c APIs was not working for Q:32 builds.</li>
+<li>utilities/gm.c (main): Add signal handlers to
+make sure that program cleans-up on exit by invoking
+DestroyMagick.</li>
+<li>magick/draw.c (DrawSetFillColor): Quote color
+specification.
+(DrawSetStrokeColor): Quote color specification.
+(DrawSetTextUnderColor): Quote color specification.</li>
+<li>ltmain.sh: Update to latest CVS libtool.</li>
+</ul>
+</blockquote>
+<p>2003-04-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enhance.c (NormalizeImage): Only normalize the opacity
+channel if image-&gt;matte is true. This results in some (15%)
+speedup. While it can be argued that the <cite>K</cite> in CMYK should be
+normalized, it can also be argued that this is senseless since <cite>K</cite>
+is not a &quot;linear&quot; measure like C, M, &amp; Y are, and there may not be
+any any value to normalizing CMY at all.
+(EqualizeImage): Only equalize the opacity channel if image-&gt;matte
+is true. This results in a 23% speedup.
+(GammaImage): Minor loop optimization.
+(LevelImage): Don't level the opacity channel. Doing so doesn't
+make any sense.
+(LevelImageChannel): Put loops inside switch statement rather than
+around it.</li>
+<li>PerlMagick/t/tiff/read.t: Added grayscale 12-bit and 16-bit TIFF
+read tests.</li>
+</ul>
+</blockquote>
+<p>2003-04-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Add support for reading
+12-bit grayscale TIFFs. Fix reading 16-bit grayscale TIFFs
+when QuantumDepth=8.</li>
+<li>VisualMagick/installer/gm-dynamic-full-8.iss,
+VisualMagick/installer/gm-dynamic-full-16.iss: Many C header
+files were not being included in the distribution. Oops!</li>
+</ul>
+</blockquote>
+<p>2003-04-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>(index.html, www/*.html): Update to new web page style.</li>
+<li>scripts/txt2html: Update to output new web page style.</li>
+<li>ltmain.sh: Updated to latest CVS libtool.</li>
+<li>magick/tempfile.c (DestroyTemporaryFiles): Function was
+crashing if it was executed twice.</li>
+</ul>
+</blockquote>
+<p>2003-04-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/delegates.mgk.in: Ralcgm was appending &quot;.ps&quot; to the
+provided output file name, so change cgm delegate command so that
+the input file is delivered via standard input, output is
+re-directed to a file, and anything printed to stderr (such as
+the Ralcgm program name and version) is sent to /dev/null.</li>
+<li>INSTALL-unix.txt: Added/corrected/improved documentation
+regarding --disable-installed, --enable-shared, and
+--with-modules.</li>
+<li>VisualMagick/magick/magick_config.h.in: Add more documentation
+and explanatory notes in order to lessen confusion.</li>
+<li>Many files: Replaced &quot;UseInstalledImageMagick&quot; with
+&quot;UseInstalledMagick&quot; for obvious reasons.</li>
+</ul>
+</blockquote>
+<p>2003-04-04 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c, utilities/gm.c: Print &quot;help&quot; screen for a
+tool when user types &quot;gm tool&quot; or &quot;gm tool -help&quot;</li>
+<li>magick/command.c, magick/effect.c: add -ordered-dither option.</li>
+</ul>
+</blockquote>
+<p>2003-04-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>locale/C.mgk: Fixed message associated with
+&quot;UnableToCreateTemporaryFile&quot;.</li>
+<li>magick/tempfile.c (AcquireTemporaryFileDescriptor): Decided
+to return a pathname (if possible), even on failure, for use
+in error reports. The function return status should be used
+to determine if the function has succeeded.</li>
+<li>locale/locale.mgk: Updated copyright header.</li>
+<li>(magick/annotate.c, magick/attribute.c, magick/blob.c,
+magick/cache.c, magick/constitute.c, magick/delegate.c,
+magick/display.c, magick/image.c, magick/locale.c
+magick/tempfile.c, magick/tempfile.h, magick/utility.c,
+magick/xwindow.c, coders/dcm.c, coders/ept.c,
+coders/histogram.c, coders/mpeg.c, coders/pdf.c,
+coders/pict.c, coders/preview.c, coders/ps2.c,
+coders/ps3.c, coders/ps.c, coders/pwp.c, coders/sfw.c,
+coders/svg.c, coders/tiff.c, coders/url.c, coders/wpg.c):
+Ensure that failure to allocate/create temporary file is
+properly detected and reported.</li>
+</ul>
+</blockquote>
+<p>2003-04-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/type.c (GetTypeBlob): Prioritize hard-coded path
+over Windows registry values.</li>
+<li>magick/log.c (GetLogBlob): Prioritize hard-coded path
+over Windows registry values.</li>
+<li>magick/blob.c (GetConfigureBlob): Prioritize hard-coded path
+over Windows registry values.</li>
+<li>magick/delegate.c (ReadConfigureFile): Perform substitutions
+for &quot;&#64;GMDelegate&#64;&quot;, &quot;&#64;GMDisplayDelegate&#64;&quot;, &quot;&#64;MPEGDecodeDelegate&#64;&quot;,
+&quot;&#64;MPEGEncodeDelegate&#64;&quot;, and &quot;&#64;HPGLDecodeDelegate&#64;&quot; while reading
+delegates.mgk under windows.
+(ListDelegateInfo): Format delegate command line to multiple
+lines if necessary rather than truncating.</li>
+<li>configure.ac (MagickBinPathDefine): Added support for
+a MagickBinPath definition.</li>
+<li>configure.ac (GSVersion): Added test to obtain version
+of installed Ghostcript.</li>
+<li>magick/tempfile.c (AcquireTemporaryFileDescriptor): Open
+flag should have been O_RDWR, not O_WRONLY!</li>
+</ul>
+</blockquote>
+<p>2003-04-03 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c: Simplified skipping over the &quot;*&quot; in
+the +profile &quot;*&quot; option when expanding filenames.</li>
+</ul>
+</blockquote>
+<p>2003-04-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/bin/delegates.mgk: Update similarly to
+coders/delegates.mgk.in.</li>
+<li>coders/delegates.mgk.in: Replaced <cite>mpeg-decode</cite> delegate
+specification with <cite>mpeg</cite> delegate specification.</li>
+<li>PerlMagick/t/mpeg/read.t: Since -r option is no longer
+supplied to mpeg2decode, the signatures must be updated.</li>
+<li>magick/utility.c (ExpandFilenames): Skip over no-argument
+commands properly.</li>
+<li>coders/mpeg.c: Removed ReadMPEGImage since this is handled
+entirely by delegate now.</li>
+<li>magick/command.c: Add convert -temporary option for use
+when input files are temporary files which should be
+automatically removed.</li>
+<li>magick/delegate.c (InvokeDelegate): Ensure that temporary
+file access is secure.</li>
+<li>coders/ept.c (ReadEPTImage): Ensure that temporary file
+specified by image_info-&gt;filename is liberated before
+allocating a new temporary file name.</li>
+<li>coders/ps.c (ReadPSImage): Ensure that temporary file
+specified by image_info-&gt;filename is liberated before
+allocating a new temporary file name.</li>
+<li>coders/pdf.c (ReadPDFImage): Change TemporaryFilename
+to AcquireTemporaryFileName.</li>
+<li>magick/tempfile.c (LiberateTemporaryFile): Now takes
+a <cite>char *</cite> argument rather than <cite>const char *</cite>, and
+erases the provided filename if it is the name of a valid
+temporary file. This helps avoid errors. The return
+status may be used to determine if a file was removed.
+(AcquireTemporaryFileDescriptor): Decided that adding a
+.tmp extension to temporary file names is unnecessary.</li>
+<li>coders/jp2.c (WriteJP2Image): Destroy pixel matrix
+after encoding image. Cristy says that there is memory
+corruption otherwise.</li>
+</ul>
+</blockquote>
+<p>2003-04-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Use new temporary file manager for JNG components.
+Merge with IM 5.5.7 (mostly cosmetic changes).</li>
+</ul>
+</blockquote>
+<p>2003-03-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cache.c (OpenCache): Add some Windows-specific
+open options.</li>
+<li>magick/resource.c (InitializeMagickResources): Increase
+the number of &quot;lowio&quot; file handles available for use under
+Windows.</li>
+<li>ltdl/ltdl.c: Incorporate more Darwin fixes from CVS libtool.</li>
+<li>coders/pcx.c (ReadPCXImage): Incorporate bugfix from
+ImageMagick -- Not enough memory allocated for reading PCX
+(bug report by Trevor Willis).</li>
+<li>magick/magick.c (InitializeMagick): Only invoke
+SetLogEventMask() to set debug options based on
+getenv(&quot;MAGICK_DEBUG&quot;) if the environment variable is set.</li>
+</ul>
+</blockquote>
+<p>2003-03-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/tempfile.c: Include tempfile.h rather than temporary.h</li>
+<li>magick/magick.c: Include tempfile.h rather than temporary.h</li>
+<li>coders/dcm.c, coders/ept.c, coders/histogram.c, coders/mpeg.c,
+coders/pdf.c, coders/pict.c, coders/preview.c, coders/ps.c,
+coders/ps2.c, coders/ps3.c, coders/pwp.c, coders/sfw.c,
+coders/svg.c, coders/tiff.c, coders/url.c, coders/wpg.c,
+magick/annotate.c, magick/attribute.c, magick/blob.c,
+magick/cache.c, magick/constitute.c, magick/delegate.c,
+magick/display.c, magick/image.c, magick/magick.c,
+magick/utility.c, magick/xwindow.c: Updated to use new temporary
+file allocation APIs.</li>
+<li>magick/tempfile.c: New temporary file allocation subsystem for
+allocating, tracking, and deallocating temporary files. Use of
+this subsystem should reduce the likelyhood that temporary
+files will be left behind once the process exits.
+If the environment variable MAGICK_TMPDIR is set, then its
+value is used as the location to place temporary files.</li>
+<li>magick/utility.c (IsAccessibleAndNotEmpty): New function
+for testing for file exists, is a regular file, and is not empty.
+Used to test if a temporary file has been updated by a delegate.</li>
+<li>magick/log.c (SetLogEventMask): Add support for setting
+TemporaryFileEvent.</li>
+<li>PerlMagick/Magick.xs: Added TemporaryFile log event type.</li>
+<li>magick/log.h (LogEventType): Add TemporaryFileEvent event
+classification.</li>
+</ul>
+</blockquote>
+<p>2003-03-29 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (SampleImage) and magick/render.c (DrawAffineImage():
+Applied Cristy fix for bug that offset images to the top and left.</li>
+<li>magick/resize.c (ScaleImage): Fixed bug that caused intensity
+levels to be one unit too high.</li>
+<li>coders/png.c: make JNG support depend on HasJPEG. Remove temp files.</li>
+</ul>
+</blockquote>
+<p>2003-03-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (ResizeImage): Applied fix authored by John
+Cristy for distortion when using the bessel filter.</li>
+<li>magick/display.c: Applied fix authored by John Cristy which
+eliminates bogging down when using the magnifier window on
+large images.</li>
+<li>Several files: A few files included multiple copies of the
+copyright header text due to either pilot error, or equipment
+failure.</li>
+</ul>
+</blockquote>
+<p>2003-03-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am : Removed some debug code which was
+accidentally committed to CVS.</li>
+<li>Copyright.txt: Add copyright statements to all the files,
+including some apparently missing copyrights.</li>
+</ul>
+</blockquote>
+<dl class="docutils">
+<dt>2003-03-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</dt>
+<dd><ul class="first last simple">
+<li>magick/Makefile.am: Added temporary.c and temporary.h. These
+are not finished yet.</li>
+<li>magick/cache.c: Transferred optimization from ImageMagick
+to read/write all requested pixel cache rows in one system
+call when accessing the cache using file I/O, and the
+requested columns equals the image columns.</li>
+<li>magick/resource.c: (ResourceInfo): Use type <cite>double</cite> rather
+than <cite>long double</cite>. For many systems, the range of <cite>long double</cite>
+is the same as <cite>double</cite>. On others, use of <cite>long double</cite> incurs
+the cost of function calls since there is no hardware support.</li>
+</ul>
+</dd>
+</dl>
+<p>2003-03-22 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.h, effect.c, command.c: Revised -random-dither
+to require parameters: channel LOWxHIGH. Channel can presently
+be &quot;intensity&quot;, &quot;opacity&quot;, or &quot;all&quot;.</li>
+</ul>
+</blockquote>
+<p>2003-03-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ltdl/ltdl.c: Updated to latest CVS version. Claimed to
+support loading modules under MacOS-X.</li>
+<li>magick/resource.c (InitializeMagickResources): Enable code
+under Windows which queries system limits.</li>
+<li>magick/cache.c (S_MODE): Fixed portability problems with
+definition.</li>
+<li>VisualMagick/bin/delegates.mgk: Fix typo in &quot;mpeg-decode&quot;
+decode rule.</li>
+<li>libtool: Update to latest CVS version.</li>
+<li>configure.ac: Test zlib for gzseek and gztell.</li>
+<li>magick/effect.c (ChannelThresholdImage): The is_grayscale flag
+was not be evaluated correctly.</li>
+</ul>
+</blockquote>
+<p>2003-03-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h (RoundSignedToQuantum): Added handy
+RoundSignedToQuantum macro for munging doubles into Quantums.</li>
+<li>magick/effect.c (ThresholdImage): Added optimizations for
+thresholding all pixels to white or black. Threshold using an
+integral value rather than a double so compares are faster.
+(ChannelThresholdImage): Threshold against integral values since
+compares are faster. Invoke ThresholdImage for simple thresholding
+across all channels since it is faster.</li>
+</ul>
+</blockquote>
+<p>2003-03-19 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c: #ifdef'ed out some dead code.</li>
+<li>magick/annotate.c: #ifdef'ed out some code that is only
+used when HasTTF is defined.</li>
+<li>Added RandomThresholdImage() method and -random-threshold
+commandline option.</li>
+</ul>
+</blockquote>
+<p>2003-03-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac (LIB_TIFF): Check for TIFFReadRGBATile and TIFFReadRGBAStrip
+in libtiff before deciding to use it.</li>
+<li>magick/blob.c (WriteBlob): Move pointer increment into
+paranthesis.
+(ReadBlob): Move pointer increment into paranthesis.</li>
+<li>magick/gem.c (HSLTransform): Removed inline statement.
+(TransformHSL): Removed inline statement.</li>
+<li>magick/random.[c|h]: Removed files from CVS.</li>
+<li>magick/command.c: Don't include random.h.</li>
+<li>PerlMagick/t/reference/jng: Update reference files to current output.</li>
+</ul>
+</blockquote>
+<p>2003-03-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Added tests for pread and pwrite functions.</li>
+<li>magick/image.c (GrayscalePseudoClassImage): Properly invoke
+SyncImagePixels.</li>
+<li>magick/cache.c (SyncCacheNexus): Add back in is_monochrome and
+is_grayscale flag resetting which was lost by copying over
+ImageMagick's cache.c.
+(FilePositionRead): Inline wrapper for reading a chunk of data at
+an offset.
+Cleans up some messy code, and makes it easy to use pread().
+(FilePositionWrite): Inline wrapper for writing a chunk of data at
+an offset.
+Cleans up some messy code, and makes it easy to use pwrite().
+Cache now uses pread() and pwrite() to access the cache if these
+calls are available.</li>
+<li>magick/resource.c (InitializeMagickResources): Support setting
+resource limits via the environment variables MAGICK_LIMIT_DISK,
+MAGICK_LIMIT_FILES, MAGICK_LIMIT_MEMORY, and MAGICK_LIMIT_MAP.</li>
+</ul>
+</blockquote>
+<p>2003-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/stream.c (AcquirePixelStream): Store total pixels in
+64-bit type.
+(SetPixelStream): Store total pixels in 64-bit type.</li>
+<li>coders/tiff.c (WriteTIFFImage): CoderError should be
+MissingDelegateError.</li>
+<li>coders/ps3.c (Huffman2DEncodeImage): CoderError should be
+MissingDelegateError.
+(WritePS3Image): CoderError should be MissingDelegateError.</li>
+<li>coders/ps2.c (Huffman2DEncodeImage): CoderError should be
+MissingDelegateError.</li>
+<li>coders/pdf.c (Huffman2DEncodeImage): CoderError should be
+MissingDelegateError.</li>
+<li>coders/fpx.c (ReadFPXImage): CoderError should be
+MissingDelegateError.
+(WriteFPXImage): CoderError should be MissingDelegateError.</li>
+<li>coders/dps.c (ReadDPSImage): CoderError should be
+MissingDelegateError.</li>
+<li>magick/image.c (AnimateImages): DelegateError should be
+MissingDelegateError.</li>
+<li>magick/annotate.c (RenderX11): DelegateError should be
+MissingDelegateError.</li>
+<li>magick/image.c (DisplayImages): DelegateError should be
+MissingDelegateError.</li>
+</ul>
+</blockquote>
+<p>2003-03-17 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c Relocated misplaced break in ChannelImage()
+and sped up SetImageOpacity by avoiding blend operation when
+setting the image fully opaque.</li>
+</ul>
+</blockquote>
+<p>2003-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cache.c: Snarfed cache.c updates from ImageMagick.</li>
+<li>magick/command.c: Added -list resource support.</li>
+</ul>
+</blockquote>
+<p>2003-03-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/Makefile.am (random.c): Removed building, packaging,
+and intialization of random.c functions since it is not actually
+used.</li>
+<li>magick/semaphore.c (InitializeSemaphore): Only initialize
+critical section if active_semaphore is not already true.</li>
+<li>magick/resource.c: Snarf resource.c updates from ImageMagick.</li>
+<li>PerlMagick/Magick.xs: Added missing log event types.</li>
+<li>magick/log.h (enum): Added ResourceEvent enumeration.</li>
+<li>magick/log.c (LogMagickEvent): fflush(stdout) at the end of
+each log. Otherwise output may not be seen for a long time.
+(SetLogEventMask): Add support for &quot;-debug resource&quot;.</li>
+<li>coders/tiff.c (RegisterTIFFImage): Don't register encode and
+decode handlers for TIFF if TIFF library is not available.</li>
+<li>magick/constitute.c (WriteImage): Fix cut-n-paste error
+in log message (&quot;decoder&quot; --&gt; &quot;encoder&quot;).</li>
+</ul>
+</blockquote>
+<p>2003-03-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>index.html: Added a link to the GraphicsMagick mailing lists.</li>
+<li>Magick++/demo/zoom.cpp: Added dashed option support, including
+a -resample option for image resampling.</li>
+</ul>
+</blockquote>
+<p>2003-03-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (DIST_SUBDIRS): Filters subdirectory needs to
+be distributed.</li>
+</ul>
+</blockquote>
+<p>2003-03-14 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c Ported Cristy's bugfix to DrawAffineImage().</li>
+</ul>
+</blockquote>
+<p>2003-03-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (DestroyImage): Comment out new assertions until
+we are certain that there are no ill effects.</li>
+<li>coders/mat.c (ReadMATImage): Set image-&gt;depth to valid values.</li>
+<li><dl class="first docutils">
+<dt>PerlMagick/Magick.xs: Update so that new DestroyImage assertions</dt>
+<dd>aren't asserted.</dd>
+</dl>
+</li>
+<li>magick/list.c (DestroyImageList): Update so that new DestroyImage
+assertions aren't asserted.</li>
+<li>coders/wpg.c (ReadWPGImage): Don't leave dangling pointer when
+trimming list. Don't set image-&gt;depth to invalid values.</li>
+</ul>
+</blockquote>
+<p>2003-03-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (DestroyImage): Add assertions to verify
+that destroyed image is not currently referenced by another
+image. This should help prevent accidental continued use
+of a destroyed image.
+(DestroyImage): Added assertions to enforce that images
+should not continue to reference the destroyed image.</li>
+<li>coders/wpg.c: Incorporated fixes from Jaroslav Fojtik.</li>
+<li>version.sh (PACKAGE_VERSION_ADDENDUM): Construct a package
+snapshot version based on the ChangeLog modification time.
+This requires GNU find to work propery since the -printf
+option is used.</li>
+<li>configure.ac (LIB_GS): Do not test for the Ghostscript
+library by default due to the issue of its embedded libjpeg
+conflicting with libjpeg.</li>
+<li>coders/ept.c (ReadEPTImage): &quot;PostscriptDelegateFailed&quot; should
+be classified as a DelegateError type.</li>
+</ul>
+</blockquote>
+<p>2003-03-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (BlobToFile): Truncate while opening file.
+(ImageToFile): Truncate while opening file.</li>
+<li>magick/annotate.c (RenderFreetype): Missing freetype library
+should result in a MissingDelegateError type rather than a
+DelegateError type.</li>
+<li>INSTALL-windows.txt: Added a note regarding a workaround for
+internal compiler errors while compiling image.c when using
+Visual C++ 7.0.</li>
+<li>coders/jpeg.c (ReadICCProfile): Incorporate ImageMagick fix
+to handle short JPEG ICC profiles.</li>
+<li>magick/integral_types.h: Ignore SIZEOF_LONG_LONG and
+SIZEOF_UNSIGNED_LONG_LONG defines if _VISUALC_ is defined.</li>
+</ul>
+</blockquote>
+<p>2003-03-11 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/gm.html, utilities/gm.1, guide/gm.tex: Expanded description
+of the -affine option.</li>
+</ul>
+</blockquote>
+<p>2003-03-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GetImageDepth): Re-implemented using a single-pass
+algorithm and 1/2 the code. Previous implementation didn't return
+correct results for Q:32 build. Now it does.</li>
+<li>magick/command.c (IdentifyImageCommand): For identify, when
+%q format specifier is present, image must be read rather than
+pinged. If not, either the value 8 is returned, or there is a
+crash due to reading an uninitialized image.</li>
+</ul>
+</blockquote>
+<p>2003-03-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c: Incorporate fixes from Jaroslav Fojtik. Close
+Blob before rotating image.</li>
+<li>PerlMagick/README.txt: Update to reflect that PerlMagick is
+part of GraphicsMagick.</li>
+<li>PerlMagick/t/input.mat: Added test image for Matlab format.</li>
+<li>PerlMagick/t/input.wpg: Added test image for WordPerfect Graphics Format.</li>
+<li>utilities/Makefile.am (ALLMANPAGES): Install gm.1 rather than
+old utility manual pages.</li>
+</ul>
+</blockquote>
+<p>2003-03-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/gm.html, utilities/gm.1, guide/gm.tex: First cut at
+manpage for gm, to replace individual utility manpages.</li>
+</ul>
+</blockquote>
+<p>2003-03-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c: Fix some erroneous log printf specifications.
+Improved blob log messages a bit.</li>
+<li>magick/log.c (IsEventLogging): Use InitializeLogInfo().
+(InitializeLogInfo): New function to intelligently initialize
+logging subsystem. Only locks when initialization may be required,
+and only locks long enough to determine if initialization is required.
+This approach should avoid deadlocking while logging from functions
+used to initialize logging.
+(IsLogAccessible): No longer need this duplicate of IsAccessible().
+(SetLogEventMask): Use InitializeLogInfo().</li>
+<li>coders/fpx.c (ReadFPXImage): FlashPIX library does not support
+BLOB I/O so don't use OpenBlob/CloseBlob. Opening the blob caused
+a conflict when the FlashPIX library attempted to open the file.</li>
+</ul>
+</blockquote>
+<p>2003-03-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Test for libtiff functions (TIFFClientOpen &amp;
+TIFFIsByteSwapped), which are required by GraphicsMagick, but
+not found in older libtiff versions.</li>
+<li>magick/blob.c: Added logging for Blob open/close and memory
+mapping operations.</li>
+</ul>
+</blockquote>
+<p>2003-03-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwblob.c (main): DestroyImage asserts on NULL so only
+call it for non-null image.</li>
+<li>tests/rwfile.c (main): DestroyImage asserts on NULL so only
+call it for non-null image.</li>
+</ul>
+</blockquote>
+<p>2003-03-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwblob.c (main): Add -pause option to require keypress to
+exit program. Clean-up to avoid any appearance of leaks.</li>
+<li>tests/rwfile.c (main): Add -pause option to require keypress to
+exit program. Clean-up to avoid any appearance of leaks.</li>
+<li>magick/static.c (ExecuteStaticModuleProcess): Don't bind in
+process filter functions for Visual C++ since the build environment
+doesn't support it yet.</li>
+<li>magick/log.c (GetLogBlob) Code wasn't actually testing current
+directory for log.mgk, now it does.</li>
+<li>magick/log.c (IsEventLogging): Eliminate accidental recursive, or
+repeated, initialization of the logging system.</li>
+</ul>
+</blockquote>
+<p>2003-03-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (WriteJP2Image): Improved -quality rate estimation
+for very small files.</li>
+</ul>
+</blockquote>
+<p>2003-03-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (WriteJP2Image): Add additional logging support.</li>
+<li>tests/rwblob.c: Added BLOB read/write logging.</li>
+<li>tests/rwfile.c: Added file read/write logging.</li>
+<li>magick/module.c (FindMagickModule): Minor code cleanup and limit
+directory and file name lengths to sensible values.</li>
+<li>magick/utility.c (IsAccessible): Log test failures along with
+test failure reason [strerror(errno)]. Also log test success.</li>
+<li>VisualMagick/bin/delegates.mgk: -DSAFER does not work with
+Ghostscript 8.0.</li>
+<li>magick/module.c: Needed to conditionally include nt_feature.h.</li>
+</ul>
+</blockquote>
+<p>2003-03-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/module.c (ExecuteModuleProcess): Updated to support locating
+filter modules based on search rules.
+(CoderInfo): Declare only in module.c since use is private to this
+module.
+(GetCoderInfo): Made static and commented out since currently unused.
+(FindMagickModule): New function to search for a module.
+(GetModuleBlob): Moved from blob.c, made static, and re-implemented
+based on FindMagickModule.</li>
+<li>magick/blob.c: Moved GetTypeBlob() to type.c and made it static.
+Moved GetModuleBlob() to module.c and made it static.</li>
+</ul>
+</blockquote>
+<p>2003-03-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/Makefile.am: MIFF module does not depend on -ljpeg, but
+PNG module does (for JNG).</li>
+<li>filters/analyze.c (AnalyzeImage): Bugfix, image should be passed
+as Image** rather than Image*.</li>
+<li>magick/utility.c (IsAccessible): Don't log errno if errno==0.</li>
+</ul>
+</blockquote>
+<p>2003-03-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/Makefile.am: Link with libFilters convenience library.</li>
+<li>VisualMagick/magick/magick_config.h.in: Change MagickModulesPath
+to MagickCoderModulesPath and add a MagickFilterModulesPath to
+locate filter modules.</li>
+<li>filters/Makefile.am: New makefile to build filter modules.</li>
+<li>configure.ac: Configure magick/GraphicsMagick.pc and
+Magick++/lib/GraphicsMagick++.pc.
+(MagickModulesSubdir): Add quantum depth to modules path to ensure
+that modules with the correct depth are loaded. The modules path
+is now
+${libdir}/GraphicsMagick-${PACKAGE_VERSION}/modules-Q${QuantumDepth}/coders.
+(MagickCoderModulesPath): Rename MagickModulesPath to
+MagickCoderModulesPath.
+(MagickFilterModulesPath): Define to location of filter modules.</li>
+<li>magick/Makefile.am: Added rules to install GraphicsMagick.pc.</li>
+<li>magick/GraphicsMagick.pc.in: Added pkgconfig file for
+-lGraphicsMagick.</li>
+</ul>
+</blockquote>
+<p>2003-02-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (WriteJP2Image): Quality factor calculation had
+accidentally been removed. The calculation is back, but has been
+biased up slightly so that a quality factor of 75 results in a
+more reasonable 16:1 compression. Past a quality factor of 99.5,
+the compression is set to 1:1 (non-lossy).</li>
+</ul>
+</blockquote>
+<p>2003-02-27 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed bug with reading interlaced PNG images, introduced
+yesterday.</li>
+<li>Fixed bug with skipping MNG subimages, also introduced
+yesterday.</li>
+</ul>
+</blockquote>
+<p>2003-02-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (EXTRA_DIST): Forgot to distribute version.sh</li>
+<li>configure.ac: Use definitions from version.sh to drive
+package versioning and naming. These definitions support
+libtool's recommended approach to library versioning.</li>
+<li>version.sh: New file for managing release versioning.
+Edit this file to change the release number, etc.</li>
+<li>PerlMagick/t/tiff/read.t: Added read tests for stripped,
+planar contiguous, and planar seperated TIFFs.</li>
+<li>coders/tiff.c (ReadTIFFImage): Transferred stripped-TIFF
+reading code from ImageMagick.
+Enumerated reading methods to make the logic more clear.</li>
+</ul>
+</blockquote>
+<p>2003-02-27 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>JNG alpha sample depth was sometimes inconsistent.</li>
+<li>Bring only one line at a time into memory during PNG
+read/write (Merge with Cristy's 5.5.6 update).</li>
+</ul>
+</blockquote>
+<p>2003-02-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Makefile.PL.in (LIBS): Put MAGICKLIB first to
+decrease the probability that the wrong libMagick is used
+when linking static PerlMagick.</li>
+<li>configure.ac (PerlMagick): Fix linker search path for
+-lGraphicsMagick when linking a static PerlMagick. It seems
+that libtool changed the location where it places static
+libraries.</li>
+<li>PerlMagick/t/tiff/read.t: Added test for reading tiled TIFF.</li>
+<li>coders/tiff.c (ReadTIFFImage): Add optimized support for
+reading tiled TIFFs.
+(ReadTIFFImage): Optimize loops for reading tiled TIFFs as well.
+(ReadTIFFImage): Eliminate compiler warning.
+(ReadTIFFImage): Add some missing error handling for tiled TIFF.</li>
+</ul>
+</blockquote>
+<p>2003-02-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Optimize RGBA transfer loop.</li>
+</ul>
+</blockquote>
+<p>2003-02-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawPrimitive): Return DrawPolygonPrimitive
+status (edit transferred from ImageMagick).</li>
+<li>magick/utility.c (GetMagickGeometry): Scaling to an area now
+preserves the image aspect ratio.</li>
+</ul>
+</blockquote>
+<p>2003-02-24 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png.c: Added missing parentheses in typecast (cristy noticed
+the bug that I introduced on 2/18).</li>
+</ul>
+</blockquote>
+<p>2003-02-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Add rules to produce www/README.html,
+www/INSTALL-mac.html, www/INSTALL-unix.html, www/INSTALL-vms.html,
+and www/INSTALL-windows.html</li>
+<li>www/README.html: New file produced from README.txt</li>
+<li>www/INSTALL-mac.html: New file produced from INSTALL-mac.txt.</li>
+<li>www/INSTALL-unix.html: New file produced from INSTALL-unix.txt.</li>
+<li>www/INSTALL-vms.html: New file produced from INSTALL-vms.txt.</li>
+<li>www/INSTALL-windows.html: New file produced from INSTALL-windows.txt.</li>
+<li>NEWS: Added news for GraphicsMagick 1.0.0.</li>
+<li>magick/locale.c: Added error messages to support JP2.</li>
+<li>locale/C.mgk: Added error messages to support JP2.</li>
+<li>locale/locale.mgk: Update to GraphicsMagick copyright.</li>
+<li>coders/jp2.c: Updated to use Jasper 1.700.1 interface
+conventions. Jasper 1.700.1 is required now. Support
+reading arbitrary quantum sizes up to 16-bits. Return
+grayscale images as PseudoClass.</li>
+<li>jp2/: Updated Jasper sources to version 1.700.1.</li>
+</ul>
+</blockquote>
+<p>2003-02-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (ReadJP2Image): Obtain channel indexes by
+ID rather than assuming index value. Validate that channel
+geometry and encoding is supported.</li>
+<li>magick/effect.c (ThresholdImage): Additional performance
+optimization. Work faster if image is already gray.</li>
+</ul>
+</blockquote>
+<p>2003-02-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (WriteJP2Image): Port to Jasper 1.7.
+For Q:32, don't write 32-bit pixels rather than the
+16-bit pixels we told Jasper we would write.
+(WriteJP2Image): Back-port to Jasper 1.6.</li>
+</ul>
+</blockquote>
+<p>2003-02-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/modules.mgk: Added JNG entry.</li>
+</ul>
+</blockquote>
+<p>2003-02-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (RegisterJP2Image): Added registration for
+&quot;PGX&quot; magick tag.</li>
+<li>magick/magic.mgk: Added entry for JPEG V2's PGX format.</li>
+<li>PerlMagick/t/jp2/read.t: Added JPEG Version 2 read tests.</li>
+<li>coders/modules.mgk: Added JPC and PGX magick types to
+support JPEG V2.</li>
+<li>magick/color.c (IsMonochromeImage): Re-arranged test logic
+to short-circuit test using ORs.
+(IsGrayImage): Re-arranged test logic to short-circuit test
+using ORs.</li>
+<li>magick/constitute.c (PopImagePixels): Speed GrayQuantum
+and GrayAlphaQuantum cases if is_grayscale is True.</li>
+<li>magick/quantize.c (AssignImageColors): Sync image to
+update DirectClass pixels to new colormap.</li>
+<li>coders/fpx.c (RegisterFPXImage): FlashPIX does not
+provide direct BLOB I/O support.</li>
+<li>magick/blob.c (BlobToImage): Add logging.
+(BlobToFile): Add logging.</li>
+</ul>
+</blockquote>
+<p>2003-02-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fpx.c (ReadFPXImage): Removing the input file is
+antisocial.</li>
+<li>PerlMagick/t/fpx/*.fpx: Replaced with new copies. Files
+seemed to be corrupt.</li>
+<li>PerlMagick/t/cgm/read.t: Specify file magick so that CGM
+read test passes for BLOB case.</li>
+<li>PerlMagick/t/rad/read.t: Specify file magick so that RAD
+read test passes for BLOB case.</li>
+<li>PerlMagick/t/jng/read.t: Add read tests for JNG.</li>
+<li>PerlMagick/t/jng/write.t: Add read/write tests for JNG.</li>
+<li>configure.ac (DELEGATES): Added <cite>jng</cite> to the DELEGATES list
+so that JNG can be included in the PerlMagick tests.</li>
+</ul>
+</blockquote>
+<p>2003-02-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Write proper JNG image_interlace_method.</li>
+<li>coders/png.c: Read and write proper MNG and JNG sRGB intent.</li>
+<li>PerlMagick/t/jng: Add twelve test files in JNG format.</li>
+<li>coders/png.c: Write proper progressive JNG output when
+transparency is present.</li>
+</ul>
+</blockquote>
+<p>2003-02-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/version.c (GetMagickWebSite): New function.</li>
+</ul>
+</blockquote>
+<p>2003-02-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c (ipa_device_begin): Use MagickWebSite definition.</li>
+<li>www/Copyright.html: Updated to match Copyright.txt</li>
+<li>www/perl: Updated to reflect GraphicsMagick vs ImageMagick.</li>
+<li>magick/xwindow.c (XMakeImageMSBFirst): Minor loop optimizations.</li>
+<li>magick/constitute.c (ConstituteImage): Check for grayscale
+and monochrome image if image is PseudoClass.</li>
+</ul>
+</blockquote>
+<p>2003-02-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enhance.c (ContrastImage): Preserve is_grayscale flag.
+(EqualizeImage): Preserve is_grayscale flag.
+(ModulateImage): Preserve is_grayscale flag.
+(NegateImage): Preserve is_grayscale flag.
+(NormalizeImage): Preserve is_grayscale flag.</li>
+<li>magick/fx.c (ColorizeImage): Evaluate is_grayscale status.
+(ConvolveImage): Preserve is_grayscale flag.
+(ImplodeImage): Preserve is_grayscale flag.
+(SolarizeImage): Preserve is_grayscale flag.
+(OilPaintImage): Preserve is_grayscale flag.
+(SwirlImage): Preserve is_grayscale flag.
+(WaveImage): Preserve is_grayscale flag.</li>
+<li>magick/resize.c (MagnifyImage): Preserve is_grayscale flag.
+(MinifyImage): Preserve is_grayscale flag.
+(ResizeImage): Preserve is_grayscale flag.</li>
+<li>magick/decorate.c (FrameImage): Evaluate is_grayscale status.
+(RaiseImage): Preserve is_grayscale.</li>
+<li>magick/shear.c (IntegralRotateImage): Preserve is_grayscale.
+flag.
+(XShearImage): Evaluate is_grayscale status.
+(YShearImage): Evaluate is_grayscale status.</li>
+<li>magick/transform.c (ChopImage): Preserve is_grayscale flag.
+(CropImage): Preserve is_grayscale flag.
+(FlipImage): Preserve is_grayscale flag.
+(FlopImage): Preserve is_grayscale flag.
+(RollImage): Preserve is_grayscale flag.</li>
+<li>magick/effect.c (AddNoiseImage): If image colorspace is
+GRAYColorspace, then add intensity noise, and transfer
+image is_grayscale flag to output image.
+(BlurImage): Preserve is_grayscale flag.
+(DespeckleImage): Preserve is_grayscale flag.
+(EdgeImage): Preserve is_grayscale flag.
+(EmbossImage): Preserve is_grayscale flag.
+(GaussianBlurImage): Preserve is_grayscale flag.
+(MotionBlurImage): Preserve is_grayscale flag.
+(ShadeImage): Preserve is_grayscale flag.
+(SharpenImage): Preserve is_grayscale flag.
+(UnsharpMaskImage): Preserve is_grayscale flag.</li>
+<li>magick/quantize.c (QuantizeImage): Pre-reduce gray images
+to PseudoClass in order to quickly determine the number of
+colors, and provide the expected PseudoClass output. Also
+skip slow color quantization if there are already fewer
+colors than requested.</li>
+<li>magick/image.c (GrayscalePseudoClassImage): New function
+to quickly reduce an image to PseudoClass grayscale. This
+is a fast way to determine the number of intensities in a
+grayscale image. Either a compact sorted colormap or a faster,
+contiguous linear colormap is created, depending on the
+optimize_colormap flag. If the image is already PseudoClass,
+and the optimize_colormap flag is True, then the existing
+colormap is sorted and reduced.
+(SyncImage): Preserve is_grayscale flag.
+(ChannelImage): Result is grayscale.
+(CycleColormapImage): Preserve is_grayscale and is_monochrome flags.
+(SetImage): Evaluate is_grayscale flag.
+(SetImageDepth): Preserve is_grayscale flag.
+(SetImageOpacity): Preserve is_grayscale flag.
+(SortColormapByIntensity): Preserve is_grayscale flag.
+(TransformRGBImage): Evaluate is_grayscale flag.</li>
+</ul>
+</blockquote>
+<p>2003-02-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (SampleImage): Preserve grayscale and
+monochrome flags.</li>
+<li>magick/quantize.c (AssignImageColors): Set image monochrome
+flag to True when quantizing to two colors in GrayColorspace.</li>
+<li>magick/effect.c (SpreadImage): Preserve grayscale and
+monochrome flags.
+(AdaptiveThresholdImage): Short-circuit algorithm if image
+flags indicate it is already monochrome. Set monochrome and
+grayscale flags once algorithm completes.
+(ThresholdImage): Short-circuit algorithm if image
+flags indicate it is already monochrome. Set monochrome and
+grayscale flags once algorithm completes.
+(ChannelThresholdImage): Short-circuit algorithm if image
+flags indicate it is already monochrome. Set monochrome and
+grayscale flags once algorithm completes.
+(ShadeImage): If grayscale shading is done, then set image
+grayscale flag to True.</li>
+<li>magick/color.c (IsGrayImage): If the image is_grayscale
+flag is True, then short-circuit the test. Update the flag
+if the test is performed.
+(IsMonochromeImage): If the image is_monochrome flag is True
+then short-circuit the test. Update the flag if the test is
+performed.</li>
+<li>magick/image.c (CloneImage): Copy image is_grayscale and
+is_monochrome members.</li>
+<li>magick/cache.c (SyncCacheNexus): If image pixels are updated
+then set image is_grayscale and is_monochrome members to False.
+Algorithms which want to preserve the values of these members
+should save their original values before processing the image
+and restore them when processing is complete, or transfer them
+from the input image to the output image.</li>
+<li>magick/constitute.c (ReadImage): If the returned image is
+PseudoClass then invoke IsGrayImage() and IsMonochromeImage()
+and cache the result in image is_grayscale and is_monochrome
+members for later use.</li>
+<li>magick/image.h (Image): Added is_grayscale and is_monochrome
+members to remember if image is grayscale or monochrome.</li>
+</ul>
+</blockquote>
+<p>2003-02-14 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/archives.html: commented out sites not mirroring GM yet.
+Changed &quot;ftp.simplesystems.org&quot; to &quot;ftp.graphicsmagick.org&quot;.
+Added link to graphicsmagick.sf.net.</li>
+</ul>
+</blockquote>
+<p>2003-02-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (FormatString): Check for the availability of
+vsprintf.</li>
+<li>magick/log.c (LogMagickEvent): Check for the availability of
+vsprintf.</li>
+<li>configure.ac: Test for vsprintf.</li>
+</ul>
+</blockquote>
+<p>2003-02-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/annotate.c (RenderFreetype): Used smarter code to prepare
+the beta argument for AlphaComposite.</li>
+</ul>
+</blockquote>
+<p>2003-02-12 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/logo.c: updated logo.c to produce the GraphicsMagick logo.</li>
+</ul>
+</blockquote>
+<p>2003-02-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>INSTALL-unix.txt: Document that default quantum depth is now 8.</li>
+<li>VisualMagick/magick/magick_config.h.in: Default quantum depth is now 8.</li>
+<li>configure.ac: Default quantum depth is now 8.</li>
+<li>tests/Makefile.am: Test format types that require a size
+seperately since always specifying the size caused some formats
+(e.g. PCD) to improperly fail.</li>
+</ul>
+</blockquote>
+<p>2003-02-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/NEWS.html: New HTML file for project news.</li>
+<li>scripts/txt2html: New script for formatting text into HTML.</li>
+<li>Makefile.am: Automated the generation of www/Changelog.html and
+www/NEWS.html.</li>
+<li>coders/xpm.c (WritePICONImage): Close blob using correct image.</li>
+<li>tests/Makefile.am (CHECK_SIZED_FILES): Added files to tests
+subdirectory so that tests don't need to use files from
+PerlMagick.</li>
+<li>magick/image.c (TransformColorspace): New function to
+simplify/centralize colorspace transform requests. Replaced calls
+to RGBTransformImage and TransformRGBImage throughout the code
+with calls to TransformColorspace.</li>
+<li>IMDisplay: Disable save function since it is not implemented yet.</li>
+</ul>
+</blockquote>
+<p>2003-02-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs (SetAttribute): Support changing back to
+RGB or Transparent colorspace.</li>
+</ul>
+</blockquote>
+<p>2003-02-10 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Brought MNG handling of final delay into compliance with MNG spec.</li>
+</ul>
+</blockquote>
+<p>2003-02-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (WriteBMPImage): Added support for
+bits_per_pixel==4.
+(WriteBMPImage): Convert PseudoClass images with more than 256
+colors to DirectClass.
+(WriteBMPImage): Do not require 2-color images to pass the
+IsMonochromeImage() test before writing them as one-bit-per-pixel
+BMPs. Decided to allow this after four readers (including Windows
+XP) displayed the image using the proper colormap.
+(WriteBMPImage): BMP2 encoder was writing colormap using wrong format.</li>
+<li>images: Updated logo images to GraphicsMagick</li>
+<li>Added PDF Sages to web page as a sponsor.</li>
+</ul>
+</blockquote>
+<p>2003-02-08 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/GraphicsMagick.html: add &quot;gm &quot; prefix to examples.</li>
+</ul>
+</blockquote>
+<p>2003-02-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>index.html: Update to distinguish between ImageMagick and
+GraphicsMagick, and to explain &quot;gm&quot; prefix of commandline utilities.</li>
+</ul>
+</blockquote>
+<p>2003-02-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_feature.c (CropImageToHBITMAP): Remove useless
+autocrop support which was transferred from CropImage when
+creating CropImageToHBITMAP.</li>
+</ul>
+</blockquote>
+<p>2003-02-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): RLE packet size was not
+calculated correctly, causing RLE-compressed MIFF images with
+depth&gt;8 to not be read.</li>
+</ul>
+</blockquote>
+<p>2003-02-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/paint.c (ColorFloodfillImage): Transfered fix from
+ImageMagick for the problem that floodfill using a tiled image
+failed if the target color happened to match the current fill
+color.</li>
+</ul>
+</blockquote>
+<p>2003-02-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Fixed preview error message.</li>
+<li>coders/preview.c: Previous update had broken noiseimage demo.
+Also some cleanups.</li>
+<li>magick/display.c (XMagickCommand): No longer uses
+MogrifyImage.</li>
+<li>coders/preview.c (WritePreviewImage): Re-wrote so that
+MogrifyImage is no longer used. Resize image outside of the loop
+to improve performance.</li>
+</ul>
+</blockquote>
+<p>2003-02-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ShadeImage): Use PixelIntensityToDouble macro.</li>
+<li>magick/image.h (PixelIntensityToDouble): Added
+PixelIntensityToDouble macro to handle the case where pixel
+intensity is used for floating arithmetic.</li>
+</ul>
+</blockquote>
+<p>2003-01-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Distribute files ChangeLog, INSTALL-mac.txt,
+INSTALL-unix.txt, INSTALL-vms.txt INSTALL-windows.txt, and NEWS.</li>
+</ul>
+</blockquote>
+<p>2003-01-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/svg.c (SVGStartElement): Applied fix from ImageMagick to
+compute SVG +&gt; MVG viewbox correctly.</li>
+<li>magick/image.c (CloneImage): Applied fix from ImageMagick which
+is purported to solve the problem that &quot;negative (x,y) page offsets
+did not clone properly&quot;.</li>
+<li>magick/gem.c (TransformHWB): Replace implementation with
+ImageMagick's new version which is supposed to fix a rounding
+error problem. Hard to say since implementation is totally
+different.</li>
+<li>coders/msl.c (MSLStartElement): Applied fix for missing break
+from ImageMagick.</li>
+<li>magick/integral_types.h: New header to include the integral
+types typedefs. Needed new header in order to include in both
+studio.h and api.h at the right point.</li>
+<li>magick/studio.h: Move nt_feature.h inclusion to the few modules
+which actually use functions from it.</li>
+<li>magick/api.h: Added typedefs gm_int16_t, gm_uint16_t,
+gm_int32_t, gm_uint32_t, gm_int64_t, gm_uint64_t to support
+specifically sized types.</li>
+<li>configure.ac: Test for size of <cite>short</cite>, <cite>unsigned short</cite>, <cite>int</cite>,
+<cite>unsigned int</cite>, <cite>long</cite>, <cite>unsigned long</cite>, <cite>long long</cite>, <cite>unsigned
+long long</cite> assigning the result to the defines SIZEOF_SHORT,
+SIZEOF_UNSIGNED_SHORT, SIZEOF_INT, SIZEOF_UNSIGNED_INT,
+SIZEOF_LONG, SIZEOF_UNSIGNED_LONG, SIZEOF_LONG_LONG, and
+SIZEOF_UNSIGNED_LONG_LONG respectively.</li>
+</ul>
+</blockquote>
+<p>2003-01-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/fx.c (OilPaintImage): Compute histogram using 8-bit quantums
+for more sensible performance with Q:16 and Q:32 builds.</li>
+<li>magick/image.h (PixelIntensityToQuantum): Compute using integral
+arithmetic for Q:8 and Q:16. Much faster than floating point!
+(PixelIntensity): Compute using integral arithmetic for Q:8 and
+Q:16. Much faster than floating point!</li>
+</ul>
+</blockquote>
+<p>2003-01-28 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed bug in png.c, introduced in IM-5.5.1. A pair of
+{ } brackets were omitted when logging was added, which lets
+old versions of libpng write a zero-length iCCP chunk.</li>
+</ul>
+</blockquote>
+<p>2003-01-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (DespeckleImage): Put loops inside of case
+statement rather than outside.
+(SpreadImage): Improved algorithm so that -spread is 12X faster.</li>
+<li>magick/nt_feature.c (CropImageToHBITMAP): New function to return
+a region of the image as a HBITMAP.</li>
+</ul>
+</blockquote>
+<p>2003-01-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed Copyright statement on all source files.</li>
+<li>magick/effect.c (ThresholdImage): Optimized loop.</li>
+<li>coders/tiff.c (ReadTIFFImage): Read bits more efficiently for
+bits_per_sample=1.</li>
+<li>magick/command.c (MogrifyImage): Set image-&gt;dither to
+image_info-&gt;dither prior to invoking SetImageType.</li>
+<li>magick/constitute.c (WriteImage): Set image-&gt;dither to
+image_info-&gt;dither.</li>
+<li>magick/image.c (SetImageType): For case BilevelType, normalize
+image, and threshold 50% if dithering is disabled. This is at
+least 10X faster than quantizing with dither.
+(AllocateImage): Initialize image-&gt;dither.
+(CloneImage): Copy image-&gt;dither.</li>
+<li>magick/image.h: Added dither member to Image.</li>
+</ul>
+</blockquote>
+<p>2003-01-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/tiff/read.t: Added a test for reading 16-bit TIFF
+images.</li>
+<li>coders/tiff.c (ReadTIFFImage): Support reading 16-bit TIFF images
+with a Q:8 build.</li>
+<li>magick/color.c (ConstrainColormapIndex): Use VerifyColormapIndex.</li>
+<li>coders/pnm.c (ReadPNMImage): Use VerifyColormapIndex.</li>
+<li>coders/gif.c (DecodeImage): Use VerifyColormapIndex.</li>
+<li>magick/image.c (SyncImage): Use VerifyColormapIndex.</li>
+</ul>
+</blockquote>
+<p>2003-01-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (ReadBlobByte): Use getc when reading from FILE stream.</li>
+<li>configure.ac: Added tests for getc_unlocked and putc_unlocked.</li>
+<li>magick/blob.c (ReadBlobByte): Optimized reading from BlobStream.
+(ReadBlobLSBLong): Optimized reading from BlobStream.
+(ReadBlobLSBShort): Optimized reading from BlobStream.
+(ReadBlobMSBLong): Optimized reading from BlobStream.
+(ReadBlobMSBShort): Optimized reading from BlobStream.
+(ReadBlobStream): New static inline function to read from BlobStream.
+(WriteBlob): &quot;Manually&quot; copy data rather than using memcpy() for
+very small copy sizes.
+(WriteBlobByte): Use putc() when writing to a FILE stream.</li>
+</ul>
+</blockquote>
+<p>2003-01-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/gem.c (Hull): Count down loops. Might help.
+(InterpolateColor): Pre-compute common sub-expressions to improve
+performance.</li>
+<li>magick/segment.c (Classify): Implemented idea from Glenn
+Randers-Pehrson to avoid use of pow() when WeightingExponent is
+2.0 (which it is). This makes image segmentation much faster
+(e.g. 8X).</li>
+<li>magick/annotate.c (RenderFreetype): For images with
+matte==False, simply set the opacity of the pixel to be updated to
+OpaqueOpacity before alpha-compositing the pixel rather than using
+SetImageType(TrueColorMatteType) to initialize the opacity of the
+entire image. This is much faster and scales to large images.</li>
+<li>magick/image.c (SetImageType): Eliminated unnecessary conditionals.</li>
+</ul>
+</blockquote>
+<p>2003-01-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (InsertMedianList): Assign computed quantum
+indexes to variables to avoid extra computations for
+QuantumDepth&gt;8.</li>
+<li>magick/composite.c (AlphaComposite): Pre-compute common
+expressions in order to improve performance.</li>
+<li>magick/fx.c (ConvolveImage): Optimized loops.</li>
+<li>magick/paint.c (TransparentImage): Optimize for case fuzz == 0.</li>
+<li>magick/color.c (FuzzyColorMatch): Minor cleanup and optimization.</li>
+<li>magick/locale.c: Added error messages for convolve option.</li>
+<li>coders/locale.c: Picked up recent changes from ImageMagick version.</li>
+<li>locale/C.mgk: Added error messages for convolve option.</li>
+<li>magick/command.c (MogrifyImage): Added support for convolve option.</li>
+<li>coders/xcf.c (ReadXCFImage): Recognize latest GIMP XCF header.</li>
+<li>coders/dcm.c: Transferred the apparent salient fixes from
+ImageMagick for a bug described as &quot;Some DCM grayscale images did
+not display correctly.&quot;.</li>
+<li>coders/miff.c (ReadMIFFImage): Reading RLE-compressed MIFFs is
+now about 4X faster.</li>
+<li>magick/blob.c (OpenBlob): Use setvbuf() to increase stdio buffer
+size to 16K. Solaris default is 1K. This should minimize system
+call overhead for accessing large files.
+(ReadBlob): &quot;Manually&quot; copy data rather than using memcpy() for
+very small copy sizes.
+(ReadBlobZC): New method, similar to ReadBlob, but provides the
+opportunity for zero copy on read.</li>
+<li>magick/constitute.c (PushImagePixels): CMYKA case for
+image-&gt;depth=16 was comparing with 8 instead.</li>
+</ul>
+</blockquote>
+<p>2003-01-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetMagickGeometry): Removed support for <cite>~</cite>
+and disabled centering code until we learn where it should go (if
+anywhere).</li>
+<li>magick/command.c : Add HWB colorspace transform support.</li>
+<li>PerlMagick/Magick.xs: Add HWB colorspace transform support.</li>
+<li>magick/image.c (RGBTransformImage): Add HWB colorspace transform
+support.
+(TransformRGBImage): Add HWB colorspace transform support.</li>
+</ul>
+</blockquote>
+<p>2003-01-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetMagickGeometry): Add support for new new
+<cite>~</cite> geometry string flag. This also fixes a montage bug in which
+thumbnails were mis-sized if the geometry specification incuded x
+or y offsets.</li>
+<li>magick/image.h (GeometryFlags): Added CenterValue enumeration to
+correspond with new <cite>~</cite> geometry string flag. Taking
+ImageMagick's lead on this.</li>
+<li>magick/render.c: Transferred fixes from ImageMagick for an
+artifact which occured at the 360 degree point when rendering
+circles, ellipses, and arcs. Bug reported by <a class="reference external" href="mailto:io219&#37;&#52;&#48;attbi&#46;com">io219<span>&#64;</span>attbi<span>&#46;</span>com</a>.</li>
+<li>PerlMagick/Magick.xs: Add HSL colorspace transform support.</li>
+<li>magick/command.c: Add HSL colorspace transform support.</li>
+<li>magick/image.c (RGBTransformImage): Add HSL colorspace transform
+support.
+(TransformRGBImage): Add HSL colorspace transform support.</li>
+</ul>
+</blockquote>
+<p>2003-01-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated copyright statement on source files to reflect
+the GraphicsMagick Group rather than ImageMagick Studio.</li>
+<li>magick/constitute.c (ConstituteImage): Simplified the switch
+statement for inner loops by creating a simplified map in advance.
+(DispatchImage): Simplified the switch statement for inner loops
+by creating a simplified map in advance.</li>
+<li>magick/compress.c (HuffmanEncodeImage): Test and cache the
+return value of LocaleCompare(image_info-&gt;magick,&quot;FAX&quot;) so that
+LocaleCompare is not executed repeatedly in the output loop.</li>
+<li>magick/color.c (IsGrayImage): Optimized loops.
+(IsMonochromeImage): Optimized loops.
+(IsOpaqueImage): Optimized loop.</li>
+<li>magick/delegate.c (InvokePostscriptDelegate): When using the
+Ghostscript library, identify the library as &quot;[ghostscript library]&quot;
+rather then &quot;gsdll32&quot; so that -verbose prints something useful for
+both Windows and Unix.</li>
+</ul>
+</blockquote>
+<p>2003-01-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: New file.</li>
+<li>magick/montage.c (MontageImages): Use ThumbnailImage() rather
+than ZoomImage() to resize montage thumbnails provided that the
+user has not specified an image filter, and the montage thumbnail
+is smaller than the image. This should provide faster montages
+for large images.</li>
+<li>magick/resize.c (ResizeImage): Added logging support.
+(MagnifyImage): Added logging support.
+(MinifyImage): Added logging support.
+(SampleImage): Added logging support.
+(ScaleImage): Added logging support.</li>
+</ul>
+</blockquote>
+<p>2003-01-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/transform.c (ProfileImage): Duplicate ImageMagick changes
+to image colorspace handling. Avoids using
+SetImageType(image,ColorSeparationMatteType).</li>
+<li>magick/fx.c (OilPaintImage): Replaced with ImageMagick version
+since ImageMagick version has been updated to not penalize Q:8.
+Optimized loops.</li>
+<li>magick/display.c (XDisplayImage): Display to 100% of
+the screen size rather than 90% of the screen size.</li>
+<li>magick/enhance.c (ModulateImage): Ensure that arguments
+are always positive values. Optimized loops.
+(ContrastImage): Optimized loops.</li>
+<li>magick/gem.c (HSLTransform): Optimized performance by
+eliminating redundant intermediate calculations. This
+makes <cite>gm convert -contrast</cite> 21% faster.
+(HSLTransform): Set to inline within the gem.c module.
+(TransformHSL): Set to inline within the gem.c module.
+(Contrast): Moved to bottom of gem.c module so HSLTransform
+and TransformHSL can be inlined. Simplified conditionals.
+(Modulate): Moved to bottom of gem.c module so HSLTransform
+and TransformHSL can be inlined. No longer check/correct
+negative values.</li>
+</ul>
+</blockquote>
+<p>2003-01-14 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c</li>
+<li>magick/blob.h
+Added new stream type flag and support to match with the one
+added to ImageMagick.</li>
+</ul>
+</blockquote>
+<p>2003-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (RGBTransformImage): Fixed bug (thanks to
+Bill for finding it) and finished optimizing XYZ table
+creation.
+(AverageImages): Optimized loops.
+(ChannelImage): Optimized loops. 3X speed-up for SPARC.</li>
+<li>magick/enhance.c: Optimized NegateImage().</li>
+</ul>
+</blockquote>
+<p>2003-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Set some common API structures to 0xbf prior to deallocation
+to make accidental continued use more obvious.</li>
+</ul>
+</blockquote>
+<p>2003-01-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c: Minor optimizations to PopImagePixels()</li>
+<li>coders/dpx.c: Reading the DPX header was off by 4 bytes.</li>
+<li>coders/(art.c,avs.c,bmp.c,cmyk.c,dcm.c,dib.c,dpx.c,fax.c,
+fits.c,gray.c,icon.c,map.c,miff.c,mono.c,mpc.c,mtv.c,otb.c,
+pcx.c,pdb.c,pict.c,pix.c,pnm.c,pwp.c,rgb.c,rla.c,rle.c,sct.c,
+sgi.c,sun.c,tga.c,tim.c,uyvy.c,vicar.c,viff.c,wbmp.c,xwd.c,
+yuv.c): Ensure that blob is closed on unexpected EOF.</li>
+<li>magick/image.c: Optimized SetImageOpacity().
+Optimized SetImage() for intializing non-opaque images. The
+opacity channel was being intialized twice.</li>
+</ul>
+</blockquote>
+<p>2003-01-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c: Log entry and exit from coders so that
+coders don't need to.</li>
+<li>Finished re-writing PushImagePixels() using coding practices
+which may result in faster code.</li>
+<li>PerlMagick is changed from Image::Magick to Graphics::Magick
+in order to avoid conflicts with the ImageMagick version. This
+means that any Perl scripts based on the ImageMagick version need
+to do a global replace of Image::Magick to Graphics::Magick.</li>
+<li>PerlMagick/reference/filter/Raise.miff: Replaced with new version.</li>
+</ul>
+</blockquote>
+<p>2003-01-08 William Radcliffe &lt;<a class="reference external" href="mailto:billr&#37;&#52;&#48;corbis&#46;com">billr<span>&#64;</span>corbis<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_feature.c
+Make ImageToHBITMAP function in nt_feature.c compile under Visual
+C++ again.</li>
+</ul>
+</blockquote>
+<p>2003-01-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/delegates.mgk.in: Fix cgm entry. How did it become so
+terribly broken?</li>
+<li>coders/dps.c: Adding logging support.</li>
+<li>PerlMagick/t/read.t: Changed file read tests to use image
+compares with a reference image rather than comparing with a
+signature.</li>
+<li>PerlMagick/t/wmf/read.t: Ditto.
+magick/shear.c: Fixed documentation for RotateImage.</li>
+</ul>
+</blockquote>
+<p>2003-01-08 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c, magick/magick.h: Add &quot;note&quot; member of magick_info.</li>
+<li>coders/art.c, coders/fax.c, coders/dcm.c, coders/png.c: add notes
+to format registrations.</li>
+<li>fx.c: changed default &quot;colorize&quot; behaviour to preserve image opacity.</li>
+</ul>
+</blockquote>
+<p>2003-01-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/svg.c: Allow the user to specify the initial background
+color via the -background option. This is only useful if the SVG
+doesn't draw its own background rectangle.</li>
+</ul>
+</blockquote>
+<p>2003-01-06 Albert Chin-A-Young &lt;<a class="reference external" href="mailto:china&#37;&#52;&#48;thewrittenword&#46;com">china<span>&#64;</span>thewrittenword<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ltdl/Makefile.am, ltdl/ltdl.c: Fix compilation problem
+under Tru64 UNIX 5.1. The GraphicsMagick random.h was being
+included when the system random.h was needed.</li>
+<li>configure.ac: Improve robustness of POSIX thread API tests
+by including pthread.h when building the test program.</li>
+</ul>
+</blockquote>
+<p>2003-01-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c: In IsImagesEqual() only use type <cite>long double</cite>
+for error summation if QuantumDepth &gt; 16 and <cite>long double</cite> has
+more range than <cite>double</cite>.</li>
+<li>magick/quantize.c: In QuantizeImage() only use type <cite>long
+double</cite> for error summation if QuantumDepth &gt; 16 and <cite>long
+double</cite> has more range than <cite>double</cite>.</li>
+<li>Replaced redundant code with macros.</li>
+<li>Optimize mapping to monochrome.</li>
+<li>utilities/conjure.c: Had missed removing this file earlier.</li>
+</ul>
+</blockquote>
+<p>2003-01-04 Derry Bryson &lt;<a class="reference external" href="mailto:dbryson&#37;&#52;&#48;techass&#46;com">dbryson<span>&#64;</span>techass<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/decorate.c: Use the ShadowFactor rather than ShadowModule
+define in RaiseImage() (bug-fix).</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2003.rst b/www/ChangeLog-2003.rst
new file mode 100644
index 0000000..363251a
--- /dev/null
+++ b/www/ChangeLog-2003.rst
@@ -0,0 +1,4901 @@
+2003-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/annotate.c (RenderFreetype): Ensure that image storage
+ class is set to DirectClass. Text rendering was not working
+ properly on top of PseudoClass images.
+
+ - magick/map.c (MagickMapRemoveEntry): Logic didn't properly
+ handle removing entry in list.
+
+ - configure.ac: Added --enable-efence option to enable memory
+ debugging using Electric Fence.
+
+2003-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/maptest.c (main): Extended test to add an entry to the
+ list after an entry has already been removed.
+
+ - magick/image.c (ColorspaceTypeToString): Add support for LAB
+ colorspace.
+
+ - magick/map.c: Added signature members to all structures and
+ added assertions to ensure that the signature == MagickSignature
+ prior to use. MagickMapAllocateObject now initializes the object
+ reference count to one, and MagickMapDestroyObject decrements it
+ in order to be more correct even though the object reference count
+ is not actually used yet.
+ (MagickMapCopyString): Preserve a null argument, and use
+ AcquireString since it doesn't enlarge the string storage.
+ (MagickMapCopyBlob): Preserve null blobs.
+
+ - configure.ac: Search for the shmctl() function. Under current
+ Cygwin, this is hiding in -lcygipc.
+
+2003-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c: Fixed the composite operator list in the
+ CompositeImage documentation.
+
+ - www/api/types.html: Corrected list of composition
+ operators. Sometime prior to the creation of GraphicsMagick, the
+ "Replace" composite operators were renamed to be "Copy" composite
+ operators. Thanks to David Relson for bringing this problem to
+ our attention.
+
+ - PerlMagick/Magick.xs: Added "LAB" to colorspace types.
+
+ - magick/image.h (enum ColorSpace): Add LABColorspace enumeration.
+
+ - wand/magick\_wand.h : Add some compatibility definitions to
+ translate from ImageMagick enumerations to existing GraphicsMagick
+ enumerations.
+
+2003-12-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/annotate.c: Use header synonyms defined by FreeType's
+ ftheader.h (included via <ft2build.h>) to include FreeType headers.
+ This will presumably be more portable in the future.
+
+ - configure.ac: <ft2build.h> is an optional prerequisite for
+ <freetype/freetype.h> and <libwmf/ipa.h> so include it when
+ testing for these headers.
+
+ - magick/annotate.c: Include <ft2build.h> if it is available.
+
+2003-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/wandtest.c: Ported from latest ImageMagick version.
+
+ - wand/drawing\_wand.c: Adapted to be compatible with latest
+ ImageMagick version.
+
+ - wand/pixel\_wand.c: Adapted to be compatible with latest
+ ImageMagick version.
+
+ - wand/magick\_wand.c: Ported from latest ImageMagick version.
+
+ - magick/image.h (Image): Members color\_profile, iptc\_profile,
+ generic\_profile, and generic\_profiles are now deprecated and
+ private although they continue to work as before. Please migrate
+ existing code to use the GetImageProfile and SetImageProfile
+ functions since these members will eventually be removed.
+
+ - magick/image.c (GetImageProfile): New function to retrieve an
+ image profile. Return value differs from similarly named
+ ImageMagick method since the ImageMagick approach assumes a
+ particular storage method.
+ (SetImageProfile): New function to add (or remove) an image
+ profile. Does not execute CMS color profiles.
+
+ - magick/cache.c (SetImageVirtualPixelMethod): Return unsigned int to
+ make the Wand implementation happy.
+
+ - magick/image.c (TransformColorspace): Return unsigned int to
+ make the Wand implementation happy.
+ (SetImageType): Return unsigned int to make the Wand
+ implementation happy.
+
+ - magick/draw.h, magick/draw.c: Substitute `unsigned long` in
+ place of `size\_t` in interfaces so that the draw API is not
+ sensitive to the definition of \_LP64.
+
+ - locale/C.mgk: Added new messages required by Wand library.
+
+ - magick/error.c (ExceptionSeverityToTag): Add tag translations
+ for the WandWarning, WandError, & WandFatalError enumerations
+
+ - magick/error.h (enum ExceptionType): Add WandWarning, WandError,
+ & WandFatalError enumerations to ExceptionType for ImageMagick
+ API compatibility.
+
+ - magick/image.h (enum ChannelType): Add an `AllChannels`
+ enumeration to the ChannelType enumeration for ImageMagick
+ API compatibility.
+
+2003-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick, tests: Adjusted allowed error values for tests based
+ on new error computation arithmatic. Some tests were left failing
+ since the operation they test provides results which are
+ unreasonably inaccurate, or obviously broken.
+
+2003-12-17 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/jpeg.c: Changed "JPEG:preserve-settings from a key/value
+ pair to a simple flag. Save and restore attributes when
+ "-define JPEG:preserve-settings" appears on the commandline. Use
+ "+define JPEG:preserve-settings" to unset the flag.
+
+2003-12-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c: Include <ft2build.h> if it is available since some
+ libwmf installs don't work unless it is included before the libwmf
+ API headers.
+
+ - configure.ac: Check for <ft2build.h>.
+
+2003-12-16 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/jpeg.c: Changed stored jpeg quality attribute from
+ [jpeg-quality] to JPEG-Quality. Added attributes JPEG-Colorspace
+ and JPEG-Sampling-factors. Added code to save and restore
+ these attributes when "-define JPEG:preserve-settings=yes" is
+ present in the comandline. Quality is restored if the input
+ was a JPEG and the quality was preserved. Sampling factors
+ are restored if the input was a JPEG, sampling factors were
+ preserved, and the colorspace for the output file is the same
+ as that of the input file.
+
+2003-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - TclMagick/source/configure.ac: Add an initial TclMagick
+ configure-based build environment based on a template and macros
+ from the Tcl project. I recall that while the extension does build,
+ it is possible that it is not properly registered as a module to Tcl.
+
+2003-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (IsImagesEqual): Properly compute error distance
+ vectors. Math was missing the necessary sqrt call. Also,
+ pre-normalize the error differences to 1.0 in order to reduce the
+ storage size required to store the summation of error values.
+
+ - PerlMagick/t/composite.t: Update Minus and Xor reference images.
+
+ - magick/composite.c (CompositeImage): Incorporated fixes from
+ ImageMagick for XorCompositeOp, PlusCompositeOp, and
+ MinusCompositeOp. Thanks to John Cristy for bringing the need for
+ these fixes to our attention.
+
+ - magick/image.h (RoundToQuantum): Added missing parenthesis.
+
+2003-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/environment.imdoc: Document MAGICK\_CODER\_MODULE\_PATH and
+ MAGICK\_FILTER\_MODULE\_PATH.
+
+ - rungm.sh.in: Pass MAGICK\_CODER\_MODULE\_PATH and
+ MAGICK\_FILTER\_MODULE\_PATH in the environment so modules build may
+ be tested without first being installed.
+
+ - magick/module.c (FindMagickModule): Use the
+ MAGICK\_CODER\_MODULE\_PATH environment variable to specify a search
+ path for coder modules. Use MAGICK\_FILTER\_MODULE\_PATH to specify
+ a search path for filter modules.
+
+ - Makefile.am: Updated to Automake 1.8.
+ (install-exec-perl): Fixes which achieve a successful
+ `make distcheck` for the first time in \*Magick history.
+
+ - configure.ac: Set scripts to executable.
+
+2003-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (uninstall-data-html): Pathnames were computed
+ incorrectly so documentation directories were being left behind.
+
+ - configure.ac: --without-frozenpaths is now the default. This
+ helps `make distcheck` work and makes the package more portable.
+ Path to gm was being incorrectly frozen when --without-frozenpaths
+ was specified.
+
+ - magick/delegate.c (ReadConfigureFile): Validate delegate paths
+ prior to substitution.
+
+ - rungm.sh.in (top\_builddir): Use a more reliable scheme for
+ computing location of source and build directories.
+
+ - magick/Makefile.am: Improve include directory computation logic.
+
+ - configure.ac: Don't override includedir. Pass user-supplied LIBS
+ to the linker.
+
+2003-12-08 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/jpeg.c: store JPEG quality as "[jpeg\_quality]" attribute.
+
+2003-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - rungm.sh.in: New script to support executing uninstalled
+ executables.
+
+ - magick/blob.c (GetConfigureBlob): New MAGICK\_CONFIGURE\_PATH
+ environment variable allows the user to specify the search path
+ for configuration (.mgk) files.
+
+2003-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - index.html: Added a table showing current stable release and
+ development version.
+
+2003-12-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc (use): Describe the syntax of the -process
+ argument.
+
+ - acinclude.m4 (AC\_CHECK\_CC\_OPT): Add quoting in AC\_CHECK\_CC\_OPT
+ definition. Change suggested by Patrick Welche
+
+2003-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (GetMagickInfo): Fix preprocessing logic error
+ which caused moby shared library build to not register static
+ modules.
+
+2003-12-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/module.c (ExecuteModuleProcess): Add some logging.
+
+ - magick/static.c (ExecuteStaticModuleProcess): Add some logging.
+
+2003-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer: Add optional build support for LZW.
+
+ - wand/Makefile.am: Add AUTOMAKE\_OPTIONS.
+
+ - configure.ac: Update to Autoconf 2.59.
+
+2003-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/tasks-install-perlmagick.isx: Update
+ to reflect that the next release will use ActivePerl 5.8.1 Build
+ 807.
+
+ - VisualMagick/installer/inc/files-configs.isx: Updated the source
+ locations for the .mgk files. Install modules.mgk into the config
+ directory rather than the modules directory.
+
+ - configure.ac: Fixes to work with latest CVS libtool.
+
+ - libtool.m4: Update to latest CVS libtool.
+
+ - magick/modules.c, magick/static.c (ExecuteStaticModuleProcess):
+ Fix conditional compilation logic so that "moby" shared library
+ build works again.
+
+ - magick/compress.c, magick/mac.c: Use existing SaveImageText and
+ LoadImageText global constants rather than separate defines.
+
+2003-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Update to Autoconf 2.58.
+
+ - Makefile.am: Update to Automake 1.7.9.
+
+2003-11-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/draw.c (DrawComposite): Base64-encoded image was not
+ being deallocated. Bad memory leak.
+
+2003-11-03 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick: Updated installation procedure. Please read
+ BCBMagick/readme.txt for details.
+
+2003-11-03 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick: Released DLL Version. Please read BCBMagick/readme.txt
+ for details about installation and/or use.
+
+2003-11-03 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/utility.c (GetPathComponent): Added x, X, and +
+ characters to list of legal characters in subimage
+ specifications. Required by raw RGB image reader which accepts the
+ syntax "image.rgb[100x100+50+50]". Thanks to John Cristy for
+ catching that one.
+
+2003-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/locale.c (GetLocaleMessageFromID): Fix ID range checking
+ logic.
+
+2003-10-30 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - coders/jpeg.c: changed to not write gray CMYK images as
+ grayscales. That would not be a valid optimization.
+
+ - magick/color.c (IsGrayImage, IsMonochromeImage): Changed to
+ never return true for CMYK images. Separated images get wrong
+ colors when optimized to grayscales based on what these two
+ functions return. Gray and CMYK are two different color spaces.
+
+ - magick/nt\_feature.c (NTIsMagickConflict): changed to accept
+ colon as part of the magick string, consistent with the way the
+ function is used.
+
+ - magick/utility.c, magick/utility.h (ExpandFilenames,
+ GetPathComponent): Fixed filename glob expansion. Added handling
+ of filename prefix-magick and sub-image specification to
+ GetPathComponent. Sub-image specification takes precedence over
+ any filename patterns.
+
+2003-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/static.c (ExecuteModuleProcess): Renamed from
+ ExecuteStaticModuleProcess. Only compiled if SupportMagickModules
+ is not defined.
+
+ - magick/type.c (GetTypeBlob): Eliminated function.
+ (ReadTypeConfigureFile): Use GetConfigureBlob() rather than
+ GetTypeBlob().
+
+ - magick/module.c (GetModuleBlob): Eliminate this function since
+ modules.mgk is now installed under
+ ${prefix}/share/GraphicsMagick-version/config so
+ GetConfigureBlob() may be used.
+ (lt\_dlexit, etc.) Eliminate fake libltdl function wrappers used
+ for the static build.
+ (DestroyMagickModules): Added a new destroy function (simply
+ invokes DestroyModuleInfo()).
+ (GetModuleList): Learn where modules live by using
+ FindMagickModule() to locate the LOGO module rather than by using
+ the location of modules.mgk. This is necessary since now
+ modules.mgk may be seperate from the modules.
+ (GetModuleBlob): Eliminated function.
+ (InitializeMagickModules): New function to safely initialize the
+ module loader.
+ (OpenModule): Added logging messages.
+ (OpenModules): Added logging messages.
+ (ReadModuleConfigureFile): Use GetConfigureBlob() rather than
+ GetModuleBlob().
+ Totally eliminated the rat's-nest of conditional code dependent on
+ SupportMagickModules. Now all the code in module.c is dependent
+ on #if defined(SupportMagickModules).
+
+ - magick/magick.c (DestroyMagick): Invoke DestroyMagickModules().
+ (GetMagickInfo): #ifdef chunks of code which exist to support the
+ modules-build rather than forcing the module loader to pretend
+ that modules are being used when they are not. Pass module loading
+ exceptions back to the user rather than discarding them.
+ (GetMagickInfoArray): Don't inspect the exception status since may
+ short-circuits the operation. Use best-effort instead.
+ (ListMagickInfo): Don't inspect the current exception status so
+ that all the modules which did load successfully will be
+ represented.
+ (InitializeMagick): Invoke InitializeMagickModules().
+
+ - magick/log.c: (GetLogBlob): Eliminated function.
+ GetConfigureBlob() is safe to use now when configuring logging.
+ (LogToBlob): Simplified function. Only exists since FileToBlob()
+ may throw exceptions (which are logged, causing deadlock).
+ (ReadLogConfigureFile): Use GetConfigureBlob().
+
+ - magick/blob.c (GetConfigureBlob): Re-written to use the
+ MagickMap interface and to support the new `lib` and `share`
+ config directories. The directory
+ ${prefix}/lib/GraphicsMagick-version/config is scanned before
+ ${prefix}/share/GraphicsMagick-version/config.
+ (FileToBlob): Simplified implementation.
+
+ - config/Makefile.am: New makefile to install .mgk files.
+
+ - magick/magick\_config.h.in: Added MagickLibConfigPath and
+ MagickShareConfigPath defines.
+
+ - configure.ac: Install configuration files (.mgk files) in
+ ${prefix}/lib/GraphicsMagick-version/config and
+ ${prefix}/share/GraphicsMagick-version/config. Architecture
+ independent files to under "share" while architecture dependnet
+ files go under "lib".
+
+ - Makefile.am: Added `config` subdirectory to distribution. All
+ .mgk files are moved from `coders` & `magick` into this single
+ directory.
+
+2003-10-21 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - magick/studio.h: small modifications to achieve DLL
+ compilation of library with Borland C++ Builder.
+
+ - coders/ps3.c (ZLIBEncode2Image): Fixed bug. Compilation
+ fail when HasZLIB is undefined because parameters 5 and 6,
+ are undefined.
+
+2003-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libtool.m4: Updated libtool again to CVS latest version.
+ Libtool required some fixes for building DLLs under MinGW.
+
+ - magick/resource.c (InitializeMagickResources): Some code is
+ conditional based on HAVE\_POPEN.
+
+ - magick/utility.c (SystemCommand): Improved conditional
+ compilation logic.
+
+ - magick/blob.c (OpenBlob): Code depending on popen() is
+ conditionally compiled based on HAVE\_POPEN. Code depending on
+ pclose() is conditionally compiled based on HAVE\_PCLOSE.
+
+ - configure.ac: Add test for \_pclose(), pclose(), \_popen(), and
+ popen().
+
+ - magick/locale.c (GetLocaleMessage): Add missing MagickExport.
+ (GetLocaleMessageFromID): Add missing MagickExport.
+
+ - VisualMagick/installer/inc/files-development.isx (Source):
+ Include all of the headers from the magick directory in the
+ development package. Including them individually is too error
+ prone.
+
+2003-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/magick/magick\_config.h.in: Added
+ PREFIX\_MAGICK\_SYMBOLS as a configuration option.
+
+ - magick/module.c (\_CoderInfo): Added register\_function and
+ unregister\_function members to record the module's register and
+ unregister function addresses.
+ (OpenModule): Locate the module's register and unregister
+ functions and save their address to the module's CoderInfo record.
+ (UnloadModule): Invoke the module unregister function using the
+ address recorded by OpenModule().
+ (TagToFunctionName): If PREFIX\_MAGICK\_SYMBOLS is defined, then add
+ a "Gm" prefix to the register and unregister function names.
+
+ - libtool: Updated libtool files to the latest CVS version.
+
+ - configure.ac: Changed define name from MAGICK\_SYMBOL\_PREFIX to
+ PREFIX\_MAGICK\_SYMBOLS since support is not available for
+ specifying an arbitrary prefix.
+
+2003-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Added --enable-symbol-prefix configure option
+ which prepends "Gm" to all GraphicsMagick library symbols using
+ the C pre-processor. In the future, this may change to support
+ specifying an arbitrary prefix, depending on experience.
+
+ - magick/studio.h: Include magick/symbols.h.
+
+ - magick/api.h: Include magick/symbols.h.
+
+ - magick/symbols.h: New header to support optionally remapping
+ library symbols. If MAGICK\_SYMBOL\_PREFIX is defined, then
+ library symbols are remapped.
+
+2003-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/api.h: Removed inclusion of <magick/semaphore.h> since it
+ is an implementation header.
+
+2003-10-13 Lars Skyum <lrs@stibo.dk>
+
+ - www/GraphicsMagick.html, www/animate.html, www/composite.html,
+ www/conjure.html, www/convert.html, www/display.html, www/gm.html,
+ www/identify.html, www/import.html, www/mogrify.html,
+ www/montage.html: added documentation for "-define" command line
+ option.
+
+ - doc/brief\_options.imdoc, doc/options.imdoc: Added documentation
+ for "-define" command line option.
+
+ - doc/gmdocselect, doc/imdocselect: Changed "skipform" label in
+ sed scripts to just "skipf". Solaris sed had problems with the
+ long(?) "skipform" label.
+
+2003-10-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/composite.imdoc, doc/options.imdoc, doc/GraphicsMagick.imdoc:
+ Attempted to clarify the meaning of the compose arguments and how
+ composition works, as well as eliminating use of hard-coded values like
+ 255.
+
+ - www/links.html: Added a link to Michael Still's article
+ "Graphics from the command line".
+
+2003-10-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/\*.c: Updated module descriptions so that they accurately
+ describe the module rather than saying "Read/Write GraphicsMagick
+ Image Format".
+
+ - coders/cineon.c: Fix source module description. Contrary to
+ opinion, ImageMagick did not invent the Cineon X image format so
+ description is now "Read/Write Cineon X Image Format."
+
+ - magick/magic.mgk: Added a CINEON entry for the Cineon X image
+ format.
+
+ - magick/static.c (RegisterStaticModules): Invoke
+ RegisterCINEONImage().
+
+ - coders/modules.mgk: Map "CIN" magick to CINEON module.
+
+2003-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - locale/C.mgk: Added message for "UnrecognizedCommand".
+
+ - magick/command.c (MagickCommand): No error was reported when a
+ subcommand failed to be matched so `gm foo` would silently return.
+ Now an error message is properly reported.
+
+2003-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Updated to Automake 1.7.8.
+
+ - various: Edits to eliminate minor issues detected by SGI C compiler.
+
+ - coders/ps3.c (WritePS3Image): Variable `value` was set but never
+ used so it is removed.
+
+ - magick/image.c (RGBTransformPacket): Removed inline request
+ since this function is too big to inline.
+
+ - magick/animate.c (XAnimateBackgroundImage): Fixed a GCC 3.X
+ "type pinning" warning.
+
+ - magick/display.c (XDisplayBackgroundImage): Fixed a GCC 3.X
+ "type pinning" warning.
+
+ - magick/render.c (GetPixelOpacity): Removed inline directive. No
+ one in their right mind could ever imagine this function inlining
+ successfully.
+
+ - magick/cache.c (IsNexusInCore): Adjusted so function inlines as
+ requested.
+
+ - coders/tiff.c (ReadTIFFImage): Improved logging information.
+ (WriteTIFFImage): Changed the way the bilevel/grayscale logic
+ works. Now bilevel images are treated similar to any other
+ grayscale image unless CCITT FAX3 or FAX4 compression is requested
+ (which selects the MINISWHITE photometric). The default is now to
+ write uncompressed bilevel images with MINISBLACK photometric.
+
+ - PerlMagick/t/composite.t: Use some reasonable error values.
+
+ - magick/image.c (GetImageDepth): Added special cases for
+ colormapped images and monochrome images in order to improve
+ performance.
+
+2003-10-09 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - NEWS: added info about color scaling, sampling-factor, and
+ changed a reference to "-coder-options" to "-define".
+
+2003-10-09 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - VisualMagick/bin/modules.mgk: added EPS3 mapping to PS3 module.
+
+ - coders/ps3.c, coders/tiff.c, magick/command.c, magick/image.c,
+ magick/image.h, magick/utility.c: Changed -coder-options option to
+ -define. Also renamed functions {Add,Remove,Access}CoderOption(s)
+ to {Add,Remove,Access}Definition(s). Changed ps coder-specific
+ option ps:image=imagemask to just ps:imagemask.
+
+2003-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/cineon.c: Imported and adapted Cineon image format coder
+ written by Kelly Bergougnoux <three3@users.sourceforge.net> with
+ assistance from John Cristy.
+
+2003-10-08 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/jpeg.c: Extended -sampling-factor option to allow
+ user to supply full set of sampling factors. If the full
+ set is not supplied, omitted ones are 1x1 by default, similar
+ to the behavior of "cjpeg -sample".
+
+ - magick/command.c: Accept multiple pairs of sampling factors.
+
+2003-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Re-arranged logging for improved
+ output. Cleaned up evaluation of SAMPLESPERPIXEL and
+ BITSPERSAMPLE. Provided support for the TIFF coder options
+ tiff:samples-per-pixel and tiff:bits-per-sample for power users.
+ (ReadTIFFImage): Colormap generation for PHOTOMETRIC\_MINISBLACK
+ and PHOTOMETRIC\_MINISWHITE was inaccurate. Seems to be accurate
+ now.
+
+ - PerlMagick/t/reference/read/input.miff: Updated due to Glenn's
+ change to scale macros.
+
+ - PerlMagick/t/tiff/input\_gray\_12bit.tiff: Replaced 12 bit image
+ with a different one which is written by GraphicsMagick.
+
+ - coders/ps3.c (WritePS3Image): Use AccessCoderOption().
+
+ - magick/image.c (AccessCoderOption): Added a function to use for
+ accessing coder-specific options.
+
+2003-10-08 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/attribute.c (TraceSVGClippingPath): optimized for speed
+ and precision in clipping mask generation by using lines to
+ connect Bezier curve anchor points where applicable.
+
+2003-10-07 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Revised ScaleColor5to8 and ScaleColor6to8 macros again, to
+ fill the low bits correctly.
+
+2003-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/tiff/read.t: Added 16-color and 256 color
+ colormapped tests with a matte channel.
+
+ - PerlMagick/t/tiff/write.t: Added 16-color and 256 color
+ colormapped tests with a matte channel.
+
+ - coders/tiff.c (WriteTIFFImage): When using LZW compression,
+ apply the horizontal differencing predictor to RGB truecolor and
+ deep gray images since the TIFF spec says that LZW compression is
+ usually improved by using horizontal differencing with continuous
+ tone images.
+ Re-implemented grayscale and colormapped scanline preparation to
+ use the new bit-stream interface. This is a bit slower, but very
+ flexible, and the implementation is very compact. Writing of a
+ matte (transparency) channel is now believed to be correct for all
+ depths.
+
+ - magick/command.c (MogrifyImage): Only transform the colorspace
+ if it has been set (i.e. is not UndefinedColorspace).
+
+2003-10-06 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/png.c (ReadOnePNGImage): PNG decoder would exit too
+ early when reading image.png[0].
+
+2003-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/tiff/write.t: Added TIFF write tests for 4
+ bits-per-sample TIFF images, both with and without a transparency
+ channel.
+
+ - magick/image.c (DescribeImage): Added -verbose support for
+ displaying individual channel depths.
+
+2003-10-06 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/image.c (SetImageInfo): cleaned up parsing of subimage
+ specification (image.psd[0]). It would fail sometimes due to
+ incorrect reuse of variables. It's a bit strange the code accepts
+ more range syntax-variations than can be stored in ImageInfo.
+
+2003-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (ChannelImage): The OpacityChannel, MatteChannel,
+ and BlackChannel operations set the matte channel to opaque, so
+ set image->matte to False for those operations.
+ (RGBTransformImage): Add an assertion to prevent passing the
+ colorspace argument `UndefinedColorspace`.
+ (TransformRGBImage): Add an assertion to prevent passing an image
+ with colorspace set to `UndefinedColorspace`.
+
+2003-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.c (LogToBlob): Since MagickSeek(file,0,SEEK\_END) is
+ used to obtain the Blob size, MagickSeek(file,0,SEEK\_SET) must be
+ used to restore the seek position. Thanks to John Cristy for
+ bringing this to our attention.
+
+2003-10-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/bit\_stream.h: Added a bit-stream writer function.
+
+ - PerlMagick/t/reference/read/input\_tim.miff: Reference image
+ was defective.
+
+2003-10-03 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/image.c, magick/image.h: Updated AddCoderOptions to
+ accept "flag" keys that have no values. They are placed in the
+ coder options map with an empty, zero length string value. Option
+ argument syntax is now: "key1[=[value1]],key2[=[value2]],..."
+
+2003-10-03 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/command.c: Updated +coder-options option to not clear the
+ entire map of coder options, but accept a list of names to remove
+ from the map. Use option argument "\*" to clear the entire map of
+ coder options.
+
+ - magick/image.c, magick/image.h: Added function
+ RemoveCoderOptions. Added cast of signed char to unsigned char and
+ int in calls to isspace and isprint.
+
+ - magick/utility.c: Added cast of signed char to unsigned char and
+ int in calls to isspace and isprint. Added special handling of
+ +coder-options option in ExpandFilenames function.
+
+2003-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/reference/read/input\_tim.miff: The TIM read results
+ changed somewhat due to Glenn's ScaleColor5to8 fix.
+
+2003-10-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Revised ScaleColor5to8 and ScaleColor6to8 macros to fill in the
+ low bytes.
+
+ - coders/bmp.c (ReadBMPImage): scaling of 8-8-8-8-bit images was
+ also slightly incorrect.
+
+2003-09-30 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/bmp.c (ReadBMPImage): scaling of 5-5-5-bit and 5-6-5-bit
+ images was slightly incorrect.
+
+2003-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): When using the generic bit-stream
+ marshaller to read colormapped/gray images, the slight performance
+ improvement from creating a special case for matte images did not
+ justify almost doubling the amount of code. Therefore, the two
+ loops are combined back into one.
+
+2003-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Fixed reading grayscale TIFFs
+ that have a transparency channel. Now uses a generic bit-stream
+ marshaller to allow reading any grayscale or colormapped TIFF with
+ any bits per sample in the range of 1 to 16.
+
+ - magick/bit\_stream.h: Added a generic implementation for
+ marshalling from a bit-stream into a quantum. Still needs
+ re-writing for best performance.
+
+ - PerlMagick/t/tiff/read.t: Added a test case for reading 8-bit
+ grayscale TIFF with matte. Corrected grayscale 12-bit read
+ signatures. Added 16 color PseudoClass read test. Added 4-bit
+ grayscale read test.
+
+2003-09-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Add support for writing
+ DirectClass grayscale images at 4 bits per sample, including those
+ with an opacity channel. This allows writing smaller files
+ (half the size) when the image has 16 (or less) levels of gray.
+ Use "gm convert inimage.tiff -depth 4 outimage.tiff" to quickly
+ create grayscale TIFF file with 16 (or less) levels of gray.
+
+2003-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS: Updated NEWS file with changes since last update.
+
+ - index.html: Added a link to the www/AUTHORS.html file, as well
+ as text stating that GraphicsMagick is originally derived from
+ ImageMagick 5.5.2, with a link to the ImageMagick site.
+
+ - Makefile.am: Add rules to generate www/AUTHORS.html.
+
+ - www/AUTHORS.html: New HTML file based on the AUTHORS file in the
+ source package. GraphicsMagick has many authors.
+
+2003-09-25 William Radcliffe <billr@corbis.com>
+ - magick/image.c: Updated DescribeImage to cleanup EXIF data display
+ based on work by Cristy in ImageMagick.
+
+2003-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Add support for writing
+ colormapped TIFF images with 1, 2, & 4 bits per colormap index.
+ This allows writing smaller files.
+
+2003-09-24 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - coders/ps3.c: Now creates a correct %%BoundingBox for images
+ with resolution stored as pixels per centimeter. Renamed serialize
+ functions. Added comment headers where they were
+ missing. Reformatted code to be in alignment with GraphicsMagick
+ standard formatting.
+
+ - magick/map.c: Fixed semaphore double locking problem in
+ MagickMapCloneMap.
+
+2003-09-23 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick/readme.txt : Updated compilation instructions.
+
+ - BCBMagick/magick/libMagick.bpr : Updated project, now include map.c.
+
+ - BCBMagick/lcms/Projects/BCB6/lcms.bpr : Updated project, now
+ include cmscam02.c and cmsvirt.c. Much thanks to Alex Dvoretsky
+ for bringing this problem to my attention.
+
+2003-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h (Image): Moved private members to bottom of
+ structure.
+ (\_ImageInfo): Moved private members to bottom of
+ structure.
+
+ - magick/Makefile.am (pkginclude\_HEADERS): Don't install
+ semaphore.h.
+ (noinst\_HEADERS): Distribute map.h and semaphore.h.
+
+ - magick/image.h (ImageInfo): Change coder\_options member from
+ type `MagickMap` to type `void \*`.
+
+ - coders/png.c: include magick/semaphore.h.
+
+ - magick/blob.c: include magick/semaphore.h.
+
+ - magick/color.c: include magick/semaphore.h.
+
+ - magick/constitute.c: include magick/semaphore.h.
+
+ - magick/delegate.c: include magick/semaphore.h.
+
+ - magick/log.c: include magick/semaphore.h.
+
+ - magick/magic.c: include magick/semaphore.h.
+
+ - magick/magick.c: include magick/semaphore.h.
+
+ - magick/module.c: include magick/semaphore.h.
+
+ - magick/semaphore.c: include magick/semaphore.h.
+
+ - magick/stream.c: include magick/semaphore.h.
+
+ - magick/tempfile.c: include magick/semaphore.h.
+
+ - magick/type.c: include magick/semaphore.h.
+
+ - magick/blob.h (\_BlobInfo): Changed `Semaphore \*` to `void \*`.
+
+ - magick/cache.h (\_CacheInfo): Changed `Semaphore \*` to `void \*`.
+
+ - magick/image.h (\_Image): Changed `Semaphore \*` to `void \*`.
+
+ - magick/command.c: Updated each invokation of MagickMapAddEntry()
+ to add an exception argument.
+
+ - tests/maptest.c: Updated to pass an exception argument to
+ MagickMapAddEntry.
+
+ - magick/image.c (AddCoderOptions): Added exception argument
+ and some more error handling.
+
+ - magick/map.c: Added formal documentation for methods.
+ (MagickMapCloneMap): Added exception argument.
+ (MagickMapAddEntry): Added exception argument and status.
+
+2003-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/emf.c: Changed NotAnEMFFile to ImproperImageHeader.
+
+ - magick/map.h: Changed all size parmeters from type `unsigned
+ long` to `size\_t`.
+
+ - magick/map.c (MagickMapCopyBlob): Add new function to support
+ copying a Blob in a MagickMap.
+ (MagickMapDeallocateBlob): Add new function to support
+ deallocating a Blob in MagickMap.
+
+2003-09-23 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - coders/ps3.c: Fixed handling the case when no -coder-options are
+ provided to the PS3 coder.
+
+2003-09-22 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - coders/ps3.c: Changed %%Creator version to use
+ MagickLibVersionText, increased precision in HiResBoundingBox,
+ added a coder specific option for rendering bilevel images with
+ the PS imagemask operator indstead of the image operator.
+
+ - magick/command.c: Added "-coder-options" command line argument
+ to all relevant command line utilities. Option argument to
+ -coder-options is a list of comma separated key-value pairs that
+ are saved in a MagickMap in ImageInfo for (de-)coders to use. See
+ PS3 coder for an example that checks for: -coder-options
+ "ps:image=imagemask"
+
+ - magick/image.c, magick/image.h: Added function AddCoderOptions().
+
+ - magick/map.c, magick/map.h: removed MS-DOS line terminators.
+
+2003-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/maptest.c (main): Test/demo program for key,value map API.
+
+ - magick/map.c, magick/map.h: Implementation of a key,value map
+ API for internal use.
+
+2003-09-19 William Radcliffe <billr@corbis.com>
+
+ - lcms/include/icc34.h lcms.h: Added back the icc34.h header and
+ changes to make lcms compile on Win32" icc34.h lcms.h.
+
+2003-09-19 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - coders/ps3.c: Fixed warnings from Solaris compiler.
+
+2003-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - locale/C.mgk: Eliminated the many "NotA" messages since they may
+ all be considered forms of "ImproperImageHeader". It is useful to
+ provide the origin of such messages in case the wrong coder has
+ been invoked, however, this is expensive to do via the message
+ database since it explodes the number of messages. The exception
+ logging can help here. Once the exception reports include the
+ reporting entity, it will be more clear when the software
+ misbehaves.
+
+ - magick/error.h (ThrowReaderException2): Remove since no longer
+ used.
+ (ThrowReaderException): Simplified implementation so that
+ ThrowException is not expanded twice.
+
+ - magick/error.h (ThrowReaderException3): Remove since never used.
+
+ - coders/xtrn.c (ReadXTRNImage): Use ThrowReaderException rather
+ than ThrowReaderException2.
+
+ - locale/C.mgk (MissingArgument) Updated to include %s so that the
+ description field appears earlier in the message.
+
+ - magick/error.c (DefaultErrorHandler): Added a hack to allow the
+ `reason` member to include a %s so that it may specify the
+ formating of the message. Care should be taken to not over-use
+ this hack.
+
+2003-09-18 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - coders/ps3.c: Major update of the PS3 coder. Now ascii85 encodes
+ all binary data. Many printer spoolers don't like the binary
+ data. The coder now creates much smaller files for bilevel, gray,
+ and colormapped images. Compression and image type is now
+ separated so they may be combined independently. Any alpha channel
+ is separated into a separate mask so it's possible to mask
+ bilevel, gray, colormapped, rgb, and CKYK images. You may also
+ mask a JPEG compressed PS file for instance. Clipping masks
+ created from a photoshop clipping path with -clip option is
+ converted to a corresponding postscript clipping path. New
+ functions need comment headers.
+
+ - magick/attribute.c: Added TracePSClippingPath for creating a
+ postscript clipping path from a photoshop clipping path.
+
+ - magick/compress.c, magick/compress.h: Added write-hook based
+ interface to compression functions. Required for ascii encoding
+ compressed, binary data. The interface between blob write
+ functions, compression functions, and encoding functions could
+ benefit from more of this work.
+
+ - magick/image.c: ClipPathImage now stores the name of the
+ clipping path in the mask image filename so that it is remembered
+ and may be used for creating a postscript clipping path for
+ postscript output.
+
+ - coders/modules.mgk: Added EPS3 mapping to module PS3.
+
+2003-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Coalesced various "Missing" error reports into
+ one "MissingArgument" error report in order to reduce the number
+ of messages to be maintained.
+
+ - locale/C.mgk: Removed almost all "Missing" messages.
+
+ - magick/gm\_messages.mc: Added Microsoft message compiler source
+ file to CVS until which time it may be generated automatically
+ during the build.
+
+2003-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - locale/Makefile: Added ability to generate gm\_messages.mc
+ (for Windows message compiler) as well as adding `clean` and
+ `install` targets.
+
+ - magick/delegate.h: Visual Studio .NET 2003 doesn't like
+ the chaining of GhostscriptVector members which share a
+ common return type. Splitting the definitions solves this
+ problem.
+
+2003-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/deprecate.h (MagickSignedType): Compatibility definition
+ to handle ImageMagick API change.
+ (MagickUnsignedType): Compatibility definition to handle
+ ImageMagick API change. The new names are just as useless as the
+ old names, but at least they are shorter.
+
+ - magick/command.c: Linux's sscanf has the terrible bug that it
+ improperly handles pulling out the first floating value from the
+ string "0x1". Instead of retrieving the value 0 and returning 1,
+ it returns 0, probably because it rejects the string as a hex
+ constant. As a result, all options which used sscanf to validate
+ this input are now converted to use IsGeometry().
+
+2003-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ltdl/ltdl.c: Update to libltdl current as of today.
+
+ - ltmain.sh: Update to libtool current as of today.
+
+ - configure.ac: For HPUX C++ compiler, add -AA to CXXFLAGS rather
+ than CXX.
+
+2003-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Decided that the standards conformance
+ defines create more problems than they solve so they are
+ removed.
+ Move the large-file tests to before the libtool configuration
+ since the libtool configuration was causing stdlib.h to be
+ included prior to the large file defines, and this causes
+ header failure with C++ under AIX.
+
+ - www/api/types.html: Update description of MonitorHandler.
+
+2003-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Set CXX to PTHREAD\_CXX if necessary (and warn).
+
+ - acinclude.m4 (ACX\_PTHREAD): Add check to see if xlC\_r should be
+ used for AIX.
+
+2003-09-10 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/render.c: Fixed handling of arc primitive (see IM-5.5.8).
+
+2003-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.h: It seems that test programs are using
+ GetMagickModule so make it visible by default.
+
+ - configure.ac: Use GM\_FUNC\_MMAP\_FILEIO macro to test mmap.
+
+ - acinclude.m4 (GM\_FUNC\_MMAP\_FILEIO): New macro to test mmap's
+ capability to do coherent file I/O. The AC\_FUNC\_MMAP macro
+ was not testing the mmap features that GraphicsMagick uses, and
+ was failing on a number of systems.
+
+ - magick/blob.c (BlobMapModeToString): Only include this static
+ function if HAVE\_MMAP is defined.
+
+ - coders/locale.c (WriteLOCALEImage): Fix FormatString argument
+ type inconsistencies.
+
+ - wand/magick\_compat.h: Change MagickExport to WandExport.
+
+ - coders/jpeg.c, coders/locale.c, coders/meta.c, coders/miff.c,
+ coders/palm.c, coders/pict.c, coders/svg.c, coders/tiff.c,
+ coders/topol.c, magick/cache.c, magick/display.c, magick/image.c,
+ magick/widget.c: Removed unused values, changed storage types, or
+ added explicit casts, in order to reduce the number of "REMARK"s
+ when using the SGI IRIX compiler.
+
+ - magick/render.c (DrawClipPath): Fix memory leak of
+ clone\_info->clip\_path. Problem reported by Vladimir
+ <lvm@integrum.ru>.
+ (DestroyDrawInfo): Remove unnecessary checks for non-null prior to
+ invoking MagickFreeMemory. MagickFreeMemory already checks for
+ non-null.
+
+ - magick/log.h (GetCurrentFunction): Apparently Visual C++ 6.0
+ does not support \_\_FUNCTION\_\_. Problem reported by Vladimir
+ <lvm@integrum.ru>.
+
+ - wand/magick\_compat.c: All functions in magick\_compat.c must use
+ WandExport rather than MagickExport. Fix recommended by Vladimir
+ <lvm@integrum.ru>.
+
+ - magick/constitute.c (PushImagePixels): number\_pixels was always
+ cast to a long during use, so change to store value in a long
+ instead.
+ (PopImagePixels): number\_pixels was always
+ cast to a long during use, so change to store value in a long
+ instead.
+
+2003-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/psd.c: Eliminated warning regarding unused initialized
+ variable.
+
+ - magick/log.c: Eliminate type warnings regarding enum assignment.
+
+ - coders/locale.c (WriteLOCALEImage): Use UndefinedException
+ rather than 0 in severity\_list terminating entry in order to avoid
+ a type conversion warning.
+
+ - magick/image.c (SetImageChannelDepth): Depth parameter was being
+ returned rather than status. Oops!
+
+ - magick/effect.c (BlurScanline): Due to automatic casting
+ conventions, computation was being done (at least with SGI
+ compiler) as type `unsigned long` rather than `long` as it should
+ have been.
+
+ - coders/jpeg.c, coders/meta.c, coders/miff.c, coders/msl.c,
+ coders/palm.c, coders/pcd.c, coders/psd.c, coders/svg.c,
+ coders/tiff.c, coders/xcf.c, magick/render.c, : Quench many SGI
+ compiler warnings regarding variables which are initialized but
+ never used.
+
+ - magick/xwindow.h: Undef gravity defines so that enumerated type
+ is used instead.
+
+2003-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.c (LogMagickEvent): Windows system logging
+ functionality is not currently ported to work with Cygwin so
+ disable when compiling under Cygwin.
+
+ - magick/log.c (Win32EventlogOutput): Remove spurious comma in enum.
+
+ - wand/drawing\_wand.h: Remove junk comment marker that I forgot to
+ remove.
+
+ - magick/studio.h: Provide prototypes for strlcpy and vsnprintf if
+ the system doesn't provide them in the requested compilation
+ environment.
+
+ - configure.ac: Add necessary standards compilance definitions to
+ magick\_config.h.
+ Check for strlcpy and vsnprintf prototypes.
+
+ - Makefile.am (DOCDIRS): www/api/types does not exist anymore.
+
+2003-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Move multithread tests prior to libtool
+ configuration in case value of CC is changed. Otherwise libtool
+ gets confused and refuses to run.
+
+ - acinclude.m4 (ACX\_PTHREAD): If using AIX CC `xlc` use `xlc\_r`
+ for multithread compiler.
+
+ - coders/jpeg.c: Undef HAVE\_STDLIB\_H before including the
+ jpeg headers or else we get an already defined error/warning.
+
+2003-09-04 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick : Updated whole directory tree to achieve correct
+ compilation with Borland C++ Buider 6.0.
+
+2003-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (ClipPathImage): Remove MS-DOS line terminations
+ (actually, extra carriage returns) which somehow crept into
+ ClipPathImage.
+
+ - locale/C.mgk: Added message for "PNG library is too old".
+
+2003-09-04 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/transform.c (ProfileImage): Bugfix: conditional
+ compilation based on LCMS being present or not now works as
+ expected. An exception is thrown if LCMS is not present and
+ profile conversion is used.
+
+2003-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/txt.c (ReadTXTImage): Fix strlen() pointer type warning.
+
+ - magick/image.c (TextureImage): Fixed return with no value warning.
+
+ - magick/color.c (GetColorInfoArray): Decided that the const
+ return value was a bad idea. Therefore, the return type has been
+ made non-const.
+
+ - magick/magick.c (GetMagickInfoArray): Decided that the const
+ return value was a bad idea. Therefore, the return type has been
+ made non-const.
+
+ - tests/constitute.c, tests/rwblob.c, tests/rwfile.c : Define
+ MAGICK\_IMPLEMENTATION since these test programs using some internal
+ extensions.
+
+ - configure.ac: Test C++ compiler for \_\_func\_\_ support.
+
+ - magick/log.h: Added GetCurrentFunction() macro to handle
+ \_\_func\_\_ support determination. Re-wrote GetMagickModule() macro
+ to use GetCurrentFunction(). Changes should allow compilation of
+ Magick++ when the C compiler supports \_\_func\_\_ but the C++
+ compiler does not.
+
+ - configure.ac: Changed from using HAS\_\_\_func\_\_ define to
+ HAS\_C\_\_func\_\_ since this feature may be language sensitive.
+
+ - locale/C.mgk: Added missing JNGCompressionNotSupported message.
+
+2003-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (Generate8BIMAttribute): Fix sscanf argument
+ type mis-match.
+
+ - coders/ps3.c (ZLIBEncodeImage): Fix mis-classified
+ ZipLibraryIsNotAvailable error report.
+
+ - coders/url.c (RegisterURLImage): Only register URL format
+ support if libxml2 is available.
+
+ - coders/msl.c (RegisterMSLImage): Only register MSL format
+ support if libxml2 is available.
+
+2003-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/histogram.c (WriteHISTOGRAMImage): Remove a useless loop.
+
+ - coders/wpg.c: Applied patch from Fojtik Jaroslav to support
+ reading WPGs which use the EXT token.
+
+2003-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/color.c (HistogramToFile): Renamed static method
+ `Histogram` to `HistogramToFile` to make it more clear what this
+ function does.
+ (GetColorHistogram): Added new function to support retrieving a
+ color histogram of the image. A color histogram contains a count
+ of how many times each color occurs in the image.
+
+ - magick/image.c (GetImageChannelDepth): Return an `unsigned int`
+ rather than `long`.
+
+2003-08-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: Add support for CopyCyan, CopyMagenta,
+ CopyYellow, and CopyBlack, composition operators.
+
+ - magick/composite.c (CompositeImage): Added support for
+ CopyCyanCompositeOp, CopyMagentaCompositeOp,
+ CopyYellowCompositeOp, and CopyBlackCompositeOp, composition
+ operators.
+
+2003-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/\*: Updated to current ImageMagick Wand API (minus a few
+ unimplemented functions).
+
+ - magick/image.c (TextureImage): Add status return because Wand API
+ wants it. Inherit is\_grayscale status from texture image.
+
+ - magick/fx.c (SolarizeImage): Add status return because Wand API
+ wants it.
+
+ - magick/resource.c (SetMagickResourceLimit): Add status return
+ because Wand API wants it.
+
+ - magick/draw.c (DrawPeekGraphicContext): Now returns a
+ copy of the current DrawInfo context rather than returning
+ a pointer into the context stack. The user must destroy
+ this copy using DestroyDrawInfo() once it is no longer
+ needed.
+
+2003-08-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/filters/LIBRARY.txt: This file is necessary to
+ incorporate analyze.c into the static build. Without it the
+ build fails.
+
+2003-08-23 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/transform.c: ProfileImage updated to handle alpha
+ channels and grayscale images. Also optimized color profiling of
+ color mapped images and fixed a few bugs in profiling of CMYK
+ images.
+
+ - magic/locale\_c.h: added MagickExport to prototype declaration of
+ GetLocaleMessageFromID in WriteLOCALEImage again. Please update
+ your locale coder.
+
+2003-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wpg.c: Applied patch from Fojtik Jaroslav to use the
+ GetMagicInfo() function to obtain the format of embedded images,
+ and to provide a default WPG palette if the WPG file does not
+ supply a palette.
+
+2003-08-22 William Radcliffe <billr@corbis.com>
+
+ - magick\gm\_messages.bin locale\_c.h transform.c: Fixed missing
+ message problem and added support for new lcms error handler.
+
+2003-08-21 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/attribute.c, magick/image.c, magick/command.c: Added
+ "clippath" option for clipping named Photoshop clipping paths,
+ increased precision in clipping path knots, added comments, and
+ fixed a few bugs resulting from moving TraceClippingPath function
+ from ImageMagick to GraphicsMagick. Still need to update some of
+ the documentation.
+
+ - magick/locale\_c.h, magick/studio.h: added MagickExport to
+ declaration of GetLocaleMessageFromID and moved include of
+ magick/locale\_c.h after declaration of MagickExport. This fixes a
+ link error in dynamic, DLL version.
+
+ - coders/locale.h: added MagickExport to prototype declaration of
+ GetLocaleMessageFromID in WriteLOCALEImage.
+
+2003-08-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/subroutines.pl (testRead): Ignore useless TIFF
+ warning so that 12-bit TIFF test passes.
+
+ - magick/constitute.c (ReadImage): Ensure that the reported image
+ magic string is that of the user-specified input file rather than
+ a temporary file prepared by an external delegate program.
+
+ - magick/command.c (ImportImageCommand): Since
+ DestroyExceptionInfo() now sets the destroyed exception signature
+ to an invalid value, GetExceptionInfo(exception) must be invoked
+ when the intention is to simply purge the exception. This fix
+ resolves an abort when executing `gm import`.
+
+2003-08-18 William Radcliffe <billr@corbis.com>
+
+ - magick\gm\_messages.bin locale\_c.h transform.c: Updates that
+ add latest enhancments by Lars to color management code in
+ ProfileImage.
+
+2003-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wpg.c: Incorporated patch from Fojtik Jaroslav to support
+ rendering embedded WMFs.
+
+2003-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageChannelDepth): New function to transform
+ the specified channel so it fits the specified modulus depth.
+
+ - magick/blob.c (BlobToImage): Skip calling SetImageInfo() if
+ magick is already set.
+
+2003-08-18 William Radcliffe <billr@corbis.com>
+
+ - PerlMagick/Magick.xs: Some fixes to get PerlMagick compiling
+ again due to new ID based error macros.
+
+2003-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/error.h (enum): Remove spurious comma.
+
+2003-08-17 William Radcliffe <billr@corbis.com>
+
+ - coders\png.c: Had to modify a few exception calls to work with
+ newest macros.
+
+2003-08-17 William Radcliffe <billr@corbis.com>
+
+ - coders\locale.c magick/error.h locale.c locale\_c.h studio.h:
+ The LOCALEH header file generator now adds an MGK\_ prefiix to
+ all the ID defines as part of a fix to support the new error
+ and exception macros cross platform.
+
+2003-08-16 William Radcliffe <billr@corbis.com>
+
+ - wand\magick\_wand.c pixel\_wand.c: The wand api code was totally
+ left out of the large macro conversion below as an oversight.
+
+2003-08-15 William Radcliffe <billr@corbis.com>
+
+ - .\coders art.c avi.c avs.c bmp.c caption.c clipboard.c cmyk.c
+ cut.c dcm.c dib.c dps.c dpx.c emf.c ept.c fax.c fits.c fpx.c gif.c
+ gradient.c gray.c hdf.c histogram.c html.c icon.c jbig.c jp2.c
+ jpeg.c label.c locale.c logo.c map.c mat.c matte.c meta.c miff.c
+ mono.c mpc.c mpeg.c msl.c mtv.c mvg.c null.c otb.c palm.c pcd.c
+ pcl.c pcx.c pdb.c pdf.c pict.c pix.c png.c pnm.c preview.c ps.c
+ ps2.c ps3.c psd.c pwp.c rgb.c rla.c rle.c sct.c sfw.c sgi.c
+ stegano.c sun.c svg.c tga.c tiff.c tile.c tim.c topol.c ttf.c txt.c
+ uil.c url.c uyvy.c vicar.c vid.c viff.c wbmp.c wmf.c wpg.c x.c xbm.c
+ xc.c xcf.c xpm.c xtrn.c xwd.c yuv.c .\magick\animate.c annotate.c
+ blob.c cache.c cache\_view.c color.c color.h command.c compress.c
+ constitute.c decorate.c delegate.c display.c draw.c effect.c
+ enhance.c error.c error.h fx.c gm\_messages.bin image.c list.c
+ locale.c locale\_c.h log.c mac.c magic.c magick.c module.c montage.c
+ nt\_feature.c paint.c quantize.c registry.c render.c resize.c
+ segment.c semaphore.c shear.c signature.c static.c static.h
+ stream.c studio.h tempfile.h transform.c type.c utility.c widget.c
+ xwindow.c : Changes to support ID based message access and checking
+ all message usages. The main thing that was done was to remove all
+ the quotes around the "tags" used to lookup messages defined in
+ the locale\C.XML file. Macros were added to error.h to allow the
+ code to be compiled for either string based access or binary ID
+ based access. Using binary ID's will cause the code to fail to
+ compile if a message does not exist in C.XML, since no ID will be
+ created for a missing message. This change then allowed us to
+ easily track down all the messages that were "missing" or not
+ being accessed properly. The problems were massive and took many
+ days to resolve. I have left the code compiling in ID mode to keep
+ things in sync going forward and also because it makes message
+ lookup instantaneous. An ID is just an index into and array of
+ char \*'s. There is still a lot of cleanup work remaining, but this
+ is a very good start.
+
+2003-08-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/error.c (GetLocaleExceptionMessage): Add check to avoid
+ duplicating severity prefix.
+
+ - magick/log.c (LogMagickEvent): Incorporated fix from Bill
+ Radcliffe to enable logging control flags to work properly again.
+
+ - NEWS: Updated news.
+
+ - magick/blob.c (OpenBlob): Rewind file descriptor so that first
+ read is at zero offset. This fixes reading GIFs via a
+ user-provided file handle.
+
+2003-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (GetImageDepth): Extend so that the actual
+ minimum depth required to represent the image is
+ returned. Previously only the values 8, 16, and 32 were
+ returned. This means that a value of one is returned for a
+ monochrome image. Also fixed a bug in that the pixels were
+ incremented while the depth was incremented, resulting in the
+ first image pixels not being properly evaluated for depth.
+ (SetImageDepth): Extend to support converting the image to
+ arbitrary modulus depths.
+ (GetImageChannelDepth): New function to obtain the modulus depth
+ for a specified image channel.
+
+2003-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/draw.c (MvgAutoWrapPrintf): StreamError reported when
+ DrawError was intended.
+
+ - coders/logo.c (ReadLOGOImage): Report FileOpenError rather than
+ BlobError if requested image does not exist.
+
+2003-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/cache.c (PersistCache): If HAVE\_SYSCONF and \_SC\_PAGE\_SIZE
+ are defined, then assume that sysconf works and don't use legacy
+ getpagesize() function.
+
+ - magick/studio.h (\_XOPEN\_SOURCE): Should be defined as 600 in
+ order to match \_POSIX\_C\_SOURCE=200112L according to the Single
+ UNIX Specification v3. This is necessary for the vsnprintf
+ prototype to be visible.
+
+ - magick/attribute.c (ReadByte): Fix compilation warnings due to
+ casting `unsigned char \*` to `char \*` by changing function
+ definition to accept `unsigned char \*` instead.
+
+ - magick/error.h (UndefinedException): UndefinedException should
+ be ExceptionType, not ExceptionBaseType.
+
+ - magick/magick.c (IsValidFilesystemPath): Eliminate warning about
+ unused function when UseInstalledMagick is defined.
+
+ - magick/error.c (ThrowLoggedException): Fix improper parameters
+ passed to LogMagickEvent() when reason is not available.
+
+003-08-07 William Radcliffe <billr@corbis.com>
+
+ - magick/log.c, log.h: Added ability to log by either severity
+ or by category of event. Made the defualt on windows to log all
+ fatal errors, errors, and warnings to the event log. This will
+ include anything generated by exceptions currently, but not any
+ normal "informational" logging.
+
+2003-08-07 William Radcliffe <billr@corbis.com>
+
+ - magick/log.c, log.h: Translation of event codes to mask vals
+ was not working. Code was left out of last update. It is now in.
+
+2003-08-07 William Radcliffe <billr@corbis.com>
+
+ - magick/error.c: Protect against NULL string passed into the
+ message lookup function.
+
+2003-08-07 William Radcliffe <billr@corbis.com>
+
+ - magick/locale.c: Switched use of IsAccessible to nonloggging
+ version to prevent recursive problems.
+
+2003-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/Makefile.am (noinst\_HEADERS): Distribute locale\_c.h.
+
+ - locale/Makefile: Output locale\_c.h.
+
+ - utilities/gm.c (main): Fix typo in Unix InitializeMagick
+ invocation.
+
+ - configure.ac: Use ACX\_PTHREAD pthreads test macro.
+
+ - magick/(semaphore.c,spinlock.h,studio.h): Change HasPTHREADS
+ conditional define to HAVE\_PTHREAD.
+
+ - magick/Makefile.am (noinst\_HEADERS): Include spinlock.h in
+ distribution.
+
+2003-08-06 William Radcliffe <billr@corbis.com>
+
+ - contrib\win32\ATL7\ImageMagickObject/ImageMagickObject.cpp,
+ ImageMagickObject\_.h, ImageMagickObject.def, ImageMagickObject.rc
+ gm.rc: Changes to get things compiling again since all windows
+ specific logging support has been eliminated. The special build
+ script BuildImageMagickObject.cmd now compiles the message file
+ for resource based messages. The result is in gm\_messages.bin.
+ The script also generates a special version of gm.exe that uses
+ the COM dll as a regular DLL and links to it. This is the long
+ desired Moby DLL build idea.
+
+ - magick/error.c, magick/error.h, magick/log.c, magick/log.h:
+ Upgrade of logging system to take over previous special logging
+ code for windows in nt\_base.c. The new logic provides logging of
+ events to the debug api and the windows event log and also
+ provides a generic text file logging method.
+
+ - magick/gm\_messages.bin, magick/ImageMagick.rc: New compiled
+ message file based on data in locale\C.mgk. RC file modified to
+ include this as a resource.
+
+ - magick/locale.c, magick/locale\_c.h: locale\_c.h is generated by
+ the LOCALEH format of the locale coder. The logic in locale.c uses
+ the tables in the header lookup messages. On windows, all the
+ messages are stored as resources, while on UNIX they remain in a
+ string table.
+
+ - locale/C.mgk: Removed duplicate messages and added some new
+ default messages that help to create a complete set of severity
+ strings.
+
+ - magick/command.c, magick/magick.c: Get rid compiler warnings.
+
+2003-08-05 William Radcliffe <billr@corbis.com>
+
+ - magick/command.c, magick/gm.c: Application level changes to
+ implement the client name - filename changes. The client name can
+ now be anything that the application wants and has nothing to do
+ with the saved filename of the application.
+
+ - magick/nt\_base.c, magick/nt\_base.h, magick/magick.c: Ripped out
+ old nt specific debugging and logging logic. Moving to the
+ standard logging. New and major revisions to InitializeMagick to
+ make the code more maintainable, reliable, and reaable. It should
+ be functionally identical, but implements the new split client
+ name and filename methododology.
+
+ - magick/utility.c, magick/utility.h: Added a couple of new
+ routines to support splitting the overloaded use of the client
+ name and client filename.
+
+ - coders/xtrn.c: Minor code cleanup
+
+2003-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Copyright.txt: Added missing copyright notice which is required
+ due to copying the rlecomp manual page into ImageMagick.
+
+ - doc/config\_files.imdoc: Started documentation for configuration
+ files.
+
+ - magick/xwindow.c (XSignalHandler): Ensure that segment\_info is
+ non-null before attempting to use it. Much thanks to John Cristy
+ for bringing this problem to our attention.
+
+2003-08-05 William Radcliffe <billr@corbis.com>
+
+ - coders/locale.c: Added several new formats to this coder to
+ generate windows message resource format messages and also to
+ generates a new header file format that will support a table based
+ version of the other magick/locale.c.
+
+ - coders/xtrn.c: Minor code cleanup
+
+2003-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Only configure C and C++ libtool tags.
+
+ - PerlMagick/t/reference/composite/\*.miff: Added some composition
+ test reference images. These reference images will serve as
+ placeholders until better composition tests can be figured out.
+ It is not clear from the documentation what some of the
+ composition operators are supposed to do.
+
+2003-08-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - README.txt: Add documentation regarding using TRIO.
+
+ - configure.ac: Test for TRIO library if vsnprintf is not
+ available.
+
+ - magick/studio.h: Remap vsnprintf to trio\_vsnprintf if TRIO is
+ available.
+
+ - coders/topol.c, coders/wmf.c, magick/magick.c, magick/nt\_base.c,
+ magick/resource.c: Use traditional C comment form in C source
+ files.
+
+2003-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.h (LogEventType::AllEvents): Increase the value of
+ AllEvents so that it spans the complete positive range of a signed
+ integer.
+
+ - magick/xwindow.c, magick/xwindow.h: Incorporate patch from John
+ Cristy's ImageMagick to eliminate conditional dependence of
+ magick/xwindow.h on <X11/extensions/XShm.h>.
+
+ - magick/magick\_config\_api.h.in: HasSharedMemory define no longer
+ needed.
+
+2003-07-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/programming.html: Update Rmagick URL.
+
+ - GraphicsMagick.spec.in : Update according to instructions from
+ Troy Edwards.
+
+2003-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - GraphicsMagick.spec.in: Replaced GraphicsMagick.spec with
+ GraphicsMagick.spec.in, which is configured to produce
+ GraphicsMagick.spec.
+
+ - configure.ac: Configure GraphicsMagick.spec.
+
+2003-07-29 Troy Edwards <vallimar@sexorcisto.net>
+
+ - GraphicsMagick.spec: Updated to CVS build. Added the
+ GraphicsMagickWand files to the spec. Only try to remove the
+ unneeded perl package files if we are using PerlMagick.
+
+2003-07-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - GraphicsMagick.spec: Added RPM spec file authored by Troy
+ Edwards <vallimar@sexorcisto.net>.
+
+ - NEWS: Add note regarding EXIF fix.
+
+ - magick/attribute.c (GenerateEXIFAttribute): Look for the profile
+ name "EXIF" rather than "APP1".
+
+2003-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick\_config\_api.h.in: XWindowInfo structure in
+ xwindow.h needs HasSharedMemory define.
+
+ - magick/xwindow.c, magick/xwindow.h: Move inclusion of
+ <X11/extensions/shape.h> to xwindow.c.
+
+ - coders/dps.c, magick/xwindow.h: Move DPS includes to
+ coders/dps.c
+
+ - coders/Makefile.am: Substituted values are also set as
+ make variables, so use variables rather than substitutions.
+
+ - magick/log.c (GetLogBlob): MAGICK\_HOME needs to take
+ precedence over the client path for the uninstalled build.
+
+ - magick/type.c (GetTypeBlob): MAGICK\_HOME needs to take
+ precedence over the client path for the uninstalled build.
+
+ - magick/blob.c (GetConfigureBlob): MAGICK\_HOME needs to take
+ precedence over the client path for the uninstalled build.
+
+ - magick/module.c (FindMagickModule): MAGICK\_HOME needs to take
+ precedence over the client path for the uninstalled build.
+
+2003-07-24 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/attribute.c (TraceClippingPath): Improvements to clipping
+ path parsing.
+
+2003-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/cache.c: Disable the Windows open() extensions when
+ compiling using Borland C++.
+
+ - magick/log.c (LogMagickEvent): Unlock semaphore before
+ returning.
+
+ - ltdl/ltdl.h: Updated to latest CVS version.
+
+ - ltdl/ltdl.c: Updated to latest CVS version.
+
+ - Libtool: Updated to use latest CVS libtool.
+
+2003-07-17 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick: Contributed initial Borland C++ Builder 6.0 build
+ environment.
+
+2003-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/color.c (GetColorInfoArray): Added a function to access
+ the color definition list as an array.
+ (GetColorList): Added access locks to ensure that list is not
+ re-ordered while it is being traversed.
+
+ - www/Magick++/Image.html: Add some more information regarding raw
+ pixel access.
+
+2003-07-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/GraphicsMagickWand.pc.in (Cflags): Remove LFS\_CPPFLAGS.
+
+ - wand/GraphicsMagickWand-config.in: Remove LFS\_CPPFLAGS.
+
+ - magick/GraphicsMagick.pc.in (Cflags): Remove LFS\_CPPFLAGS.
+
+ - magick/GraphicsMagick-config.in: Remove LFS\_CPPFLAGS.
+
+ - configure.ac: Logic for setting LFS\_CPPFLAGS was incomplete.
+
+ - coders/topol.c: Updated topol coder contributed by Jaroslav
+ Fojtik. Topol is coming to life!
+
+2003-07-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.h: Add a typedef for ssize\_t
+
+ - magick/deprecate.h: ExtendedSignedIntegralType and
+ ExtendedUnsignedIntegralType are now deprecated types so they are
+ moved to deprecate.h. Existing code which uses these types should
+ continue to work.
+
+ - magick/blob.c (MapBlob): Change `offset` parameter from type
+ off\_t to magick\_off\_t so that it is not LFS dependent.
+
+ - magick/cache.c (GetPixelCacheArea): Return magick\_off\_t.
+ (PersistCache): Change `offset` parameter to type magick\_off\_t.
+
+ - magick/cache.h (NexusInfo): Change `length` type from
+ ExtendedSignedIntegralType to magick\_off\_t.
+ (CacheInfo): Change `offset` and `length` types from
+ ExtendedSignedIntegralType to magick\_off\_t.
+
+ - magick/blob.c (BlobToFile): Use ssize\_t rather than
+ ExtendedSignedIntegralType for count.
+ (TellBlob): Return magick\_off\_t rather than
+ ExtendedSignedIntegralType.
+
+ - configure.ac: Check for a ssize\_t type.
+
+ - magick/blob.h (\_BlobInfo): Change `offset` and `size` members
+ from ExtendedSignedIntegralType to magick\_off\_t.
+
+ - magick/blob.c (GetBlobSize): Return magick\_off\_t rather than
+ ExtendedSignedIntegralType.
+ (SeekBlob): Accept and return magick\_off\_t rather than
+ ExtendedSignedIntegralType.
+
+2003-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/monitor.c (MagickMonitor): Change `quantum` argument from
+ type ExtendedSignedIntegralType to magick\_int64\_t. Change `span`
+ argument from ExtendedUnsignedIntegralType to magick\_uint64\_t.
+
+ - magick/xwindow.c (XMagickMonitor): Change `quantum` argument from
+ type ExtendedSignedIntegralType to magick\_int64\_t. Change `span`
+ argument from ExtendedUnsignedIntegralType to magick\_uint64\_t.
+
+ - magick/widget.c (XMonitorWidget): Change `quantum` argument from
+ type ExtendedSignedIntegralType to magick\_int64\_t. Change `span`
+ argument from ExtendedUnsignedIntegralType to magick\_uint64\_t.
+
+ - magick/studio.h (QuantumTick): Change typecast from
+ ExtendedSignedIntegralType to magick\_int64\_t.
+
+ - magick/resource.c (AcquireMagickResource): Change `size`
+ argument type from ExtendedSignedIntegralType to magick\_int64\_t.
+ (LiberateMagickResource): Change `size` argument type from
+ ExtendedSignedIntegralType to magick\_int64\_t.
+
+ - magick/utility.c (FormatSize): Change `size` argument type from
+ ExtendedSignedIntegralType to magick\_int64\_t.
+
+ - magick/nt\_base.c: Change MagickOffset to magick\_off\_t.
+
+ - magick/studio.h (magick\_off\_t): Change MagickOffset to magick\_off\_t.
+
+ - coders/topol.c: Insert dummy member into palettRAS structure
+ since Visual C++ doesn`t seem to handle empty structures.
+
+ - wand/GraphicsMagickWand.pc.in (prefix): Pass LFS CPPFLAGS.
+
+ - wand/GraphicsMagickWand-config.in: Pass LFS CPPFLAGS.
+
+ - wand/Makefile.am: Fix include path.
+
+ - magick/GraphicsMagick.pc.in (prefix): Pass LFS CPPFLAGS.
+
+ - magick/magick\_config\_api.h.in: Pass LFS configuration options
+ until the API is fixed so that it is not LFS sensitive anymore.
+
+ - magick/GraphicsMagick-config.in: Pass LFS CPPFLAGS.
+
+ - PerlMagick/Makefile.PL.in: Pass LFS CPPFLAGS.
+
+ - magick/Makefile.am: Install magick\_types.h.
+
+ - magick/api.h: Include magick\_types.h.
+
+ - magick/studio.h: Include magick\_types.h rather than integral\_types.h.
+ - VisualMagick/magick/magick\_types.h.in: New header file (replacing
+ integral\_types.h) to contain CPU and system-dependent primitive
+ typedefs.
+
+ - magick/magick\_types.h.in: New header file (replacing
+ integral\_types.h) to contain CPU and system-dependent primitive
+ typedefs.
+
+ - configure.ac: Use AC\_SYS\_LARGEFILE to test for large file
+ options. Update to determine integral typedefs for current CPU and
+ compiler options. Configure magick\_types.h.
+
+ - magick/attribute.c (TraceClippingPath): Apply patch from Lars
+ Ruben Skyum which fixes clipping path parsing for paths generated
+ by Adobe software which pre-dates the Photoshop file format
+ specification.
+
+2003-07-08 William Radcliffe <billr@corbis.com>
+
+ - magick/semaphore.c: Modified the way the system handles the
+ initialization of Win32 critical sections to use a spin lock
+ on WIn32 to bootstrap the initialization of all other crtical
+ sections. This is not an issue on UNIX since static init is used.
+
+ - magick/magic.c module.c magick.c log.c resource.c constitute.c
+ color.c cache.c delegate.c registry.c type.c: Small modifications
+ were made to eliminate the side effect of unlocking semaphores
+ as part of the releasing procedure. This also eliminated the
+ apparent bug of the system double locking certain semaphores.
+ The locked flag should now not be needed, but remains in place
+ for the time being as an added safegaurd.
+
+2003-07-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - png.c: added missing #ifdef JNG\_SUPPORTED/#endif directives.
+
+2003-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS: Updated news to include fixes and enhancements since the
+ 1.0 release.
+
+2003-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/semaphore.c (UnlockSemaphoreInfo): Bugfix, modify
+ the `locked` flag while still under protection of the lock.
+ This fix is necessary for thread-safety.
+
+2003-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (ReadJPEGImage): Conditionally copy exception.
+
+ - wand/Makefile.am (noinst\_HEADERS): Need to distribute
+ magick\_compat.h.
+ (EXTRA\_DIST): Need to distribute GraphicsMagickWand-config.1.
+
+ - coders/wmf.c (ipa\_bmp\_draw): Use CopyException.
+ (ipa\_device\_begin): Use CopyException.
+ (lite\_font\_map): Use CopyException.
+ - coders/jpeg.c (ReadJPEGImage): Use CopyException.
+ - magick/image.c (GetImageException): Use CopyException.
+ - magick/constitute.c (WriteImages): Use CopyException.
+ - Makefile.am (DIST\_SUBDIRS): wand needs to be included in
+ distribution.
+
+2003-06-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/static.c (RegisterStaticModules): Invoke
+ RegisterTOPOLImage.
+
+ - magick/magick.h (MagickInfo): Add member usage comments.
+
+ - magick/error.c (CatchException): Restore saved errno from
+ exception->error\_number.
+ (CopyException): Copy error\_number.
+ (DestroyExceptionInfo): Reset error\_number to zero.
+ (GetExceptionInfo): Initialize error\_number to zero.
+ (ThrowException): Save errno to exception-> error\_number.
+ (ThrowLoggedException): Save errno to exception-> error\_number.
+
+ - magick/error.h (ExceptionInfo): Borrow John Cristy's idea and
+ add a error\_number member to ExceptionInfo to save the current
+ errno value. Otherwise CatchException may use some random errno.
+
+ - coders/Makefile.am: Build topol.c.
+
+ - coders/topol.c: Added initial TOPOL X image coder which is under
+ development by Jaroslav Fojtik. Not working yet.
+
+2003-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pwp.c (ReadPWPImage): Ensure that image is initialized
+ before invoking ThrowReaderException.
+
+ - magick/image.c (CloneImage): Use CopyException.
+
+ - magick/error.c (CopyException): Add function to support copying
+ ExceptionInfo structures.
+
+ - magick/error.h (ExceptionInfo): Replaced recently-added `whence`
+ member with module, function, and line members in order to keep
+ the information seperate, and match the parameters used by the
+ logging system.
+ (ThrowException): Log thrown exceptions.
+
+ - magick/error.c (ThrowLoggedException): New function used to
+ throw an exception, while recording and logging the location
+ where the exception is thrown.
+
+ - doc/options.imdoc (operation): Document TemporaryFile and
+ Exception events.
+
+ - magick/log.c (LogMagickEvent): Support logging ExceptionEvent.
+
+ - PerlMagick/Magick.xs: Added "Exception" event type.
+
+ - magick/log.h (LogEventType): Added ExceptionEvent.
+
+2003-06-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/error.c (ThrowException): Handle `whence`
+ member. MagickFreeMemory already checks for null pointer so don't
+ check again.
+ (DestroyExceptionInfo): Handle `whence` member. MagickFreeMemory
+ already checks for null pointer so don't check again.
+
+ - magick/error.h (ExceptionInfo): Add a `whence` member to support
+ the ability to record where the exception is was thrown.
+
+ - VisualMagick/installer: Install Wand files.
+
+2003-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (GetConfigureBlob): GetConfigureBlob should always
+ return a value.
+
+ - magick/type.c (GetTypeBlob): GetTypeBlob should always return a
+ value.
+
+ - magick/log.c (GetLogBlob): GetLogBlob should always return
+ a value.
+
+ - magick/magick.c (GetMagickInfoArray): Fixed array memory
+ allocation and clearing bug. Eliminate warnings.
+
+2003-06-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/files-configs.isx: For a static
+ build, install the configuration files directly into the
+ application directory.
+
+ - VisualMagick/installer/inc/uninstallrun-unregister-com.isx
+ (Filename): Change ImageMagickObject.dll path.
+
+ - VisualMagick/installer/inc/run-register-com.isx (Filename):
+ Change ImageMagickObject.dll path.
+
+ - VisualMagick/installer/inc/files-com.isx (Source): Install
+ ImageMagickObject.dll and MagickCMD.exe in the application
+ directory alongside gm.exe and the CORE DLLs.
+
+ - INSTALL-unix.txt: Add additional information regarding LZW.
+
+ - VisualMagick/magick/magick\_config.h.in: Add additional notes
+ regarding UNISYS LZW patent.
+
+ - PerlMagick/Magick.xs: Applied Dissolve composite operator fix
+ obtained from from John Cristy's ImageMagick which ensures that an
+ unused matte channel is set to Opaque, and uses this knowledge to
+ simplify the math.
+
+ - VisualMagick/configure/configure.cpp: The `wand` library has a
+ linkage dependency on the `magick` library. Also don't include
+ the magick subdirectory so that headers must be included like
+ <magick/api.h> for safety.
+
+ - coders/xtrn.c: Fix magick header inclusion.
+
+ - lcms\src\cmserr.c: Fix magick header inclusion.
+
+2003-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Fix to formatting. Fix spelling of origin.
+
+ - PerlMagick/t/bzlib/read.t: Add test for reading BZipped file.
+
+ - PerlMagick/t/subroutines.pl (testRead): Skip testing reads
+ of compressed BLOBs because reading compressed BLOBs is not
+ supported yet.
+
+ - coders/bmp.c (ReadBMPImage): Only validate the file size value
+ for compressed BMPs.
+
+ - VisualMagick/wand, wand: First stab at building the Wand API
+ under Visual C++. Still does not build as a DLL.
+
+2003-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/static.h: Add prototypes for RegisterXTRNImage and
+ UnregisterXTRNImage.
+
+ - Makefile.am (DISTDIRS): Don't distribute the `guide`
+ subdirectory. It is available for checkout from CVS.
+
+ - www: Utilities documentation is updated from <imdoc> masters.
+ Formatting could be improved, but the content seems ok.
+
+ - doc/environment.imdoc: New file to describe environment
+ variables.
+
+ - coders/cut.c (ReadCUTImage): Use MagickAllocateMemory and
+ MagickFreeMemory rather than malloc and free.
+
+ - doc/gmdoc2html: Add GraphicsMagick styling to utility web pages.
+
+ - doc/Makefile: Additional documentation Makefile enhancements.
+
+ - AUTHORS: New file to acknowledge significant contributors
+ to the software. If an author is not listed here, please let
+ us know.
+
+ - configure.ac: test -a is not POSIX compliant.
+
+2003-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc: Source documentation for `gm` is now available via a `doc`
+ CVS module. A Makefile is provided which formats the
+ documentation and installs it into the `www` and `utilities`
+ subdirectories.
+
+2003-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand: Added Magick Wand library available via
+ -lGraphicsMagickWand and <wand/wand\_api.h>. Use
+ GraphicsMagickWand-config or GraphicsMagickWand.pc to obtain the
+ compilation options required to use the library. Magick Wand is
+ authored by John Cristy. Magick Wand is provided as a separate
+ library from -lGraphicsMagick in order to assure the stability of
+ the core GraphicsMagick library while allowing Magick Wand to
+ to evolve.
+
+ - images: Replace existing logo images with cleaner ones.
+
+ - www: Update links to point to updated logo images.
+
+ - logos: New CVS directory to contain master logos.
+
+ - scripts/txt2html: Updated inline logo image link.
+
+ - scripts/format\_c\_api\_docs: Updated inline logo image link.
+
+ - version.sh: Support versioning all libraries independently.
+
+ - coders/meta.c: Prefix include paths for safety.
+
+ - magick/image.h: (TransmitType) Removed unused enumeration.
+ (ProfileType) Removed unused enumeration.
+ (QuantumType) Moved enumeration to constitute.h
+ (StorageType) Moved enumeration to constitute.h
+
+ - magick/draw.c (DrawPeekGraphicContext): Added function to peek
+ at head of drawing context stack (function added for ImageMagick
+ compatability).
+
+ - magick/image.c (CycleColormapImage): Change return type from
+ `void` to `unsigned int` so that error status is returned to user.
+ (DescribeImage): Change return type from
+ `void` to `unsigned int` so that error status is returned to user.
+
+ - magick/list.c (ReplaceImageInList): Incorporated function from
+ John Cristy's ImageMagick to replace current image in the list.
+
+ - coders/sgi.c (ReadSGIImage): Applied patch from John Cristy's
+ ImageMagick to save the compression type for SGI images.
+
+2003-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/txt.c (WriteTXTImage): Apply patch from John Cristy's
+ ImageMagick to observe image depth while writing pixel colors.
+ This patch is not applied to the 1.0 branch because it represents
+ an output format change which could break a dependent application.
+ (IsTXT): Recognize files written by the TXT coder.
+ (ReadTXTImage): Reject files written by the TXT coder until support
+ for reading these files is implemented.
+ (IsTXT): Ensure that sscanf doesn't read outside of provided data
+ by using a fixed size buffer.
+
+2003-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Don't add -lfpx to LIBS while configuring
+ because the C compiler may fail to link with it in later
+ tests.
+
+2003-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: RotateImage is documented to take
+ `degrees` argument, not `degree`. SwirlImage is documented to
+ take `degrees` argument, not `degree`. SolarizeImage is
+ documented to take a `threshold` argument, not `factor`. Wave is
+ documented to take `amplitude` and `wavelength` arguments. Don't
+ transform colorspace to RGB when retrieving `pixel` color value.
+ Release memory acquired to store `length` pointer. Picked up
+ memory leak fix related to `SV \*\*reference\_vector` variable from
+ John Cristy's ImageMagick.
+
+ - configure: Incorporate patch to handle inline better.
+
+ - magick/utility.c (GetToken): Adjust code to avoid "end-of-loop
+ code not reached" warning.
+
+ - magick/log.c (GetLogBlob): Eliminate warning regarding
+ unreached code.
+
+ - magick/command.c (AnimateImageCommand): Eliminate warning regarding
+ unreached code.
+ (ConvertImageCommand): Eliminate warning regarding
+ unreached code.
+ (ImportImageCommand): Eliminate warning regarding
+ unreached code.
+
+ - magick/type.c (GetTypeBlob): Eliminate warning regarding
+ unreached code.
+
+ - magick/blob.c (GetConfigureBlob): Eliminate warning regarding
+ unreached code.
+
+ - coders/meta.c (super\_fgets): Eliminated warnings regarding
+ comparison and return of incompatible pointer types.
+ (super\_fgets\_w): Eliminated warnings regarding
+ comparison and return of incompatible pointer types.
+
+ - magick/command.c (ConvertImageCommand): Eliminate warnings
+ noticed when using Sun's compiler.
+
+2003-06-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - acinclude.m4: Add `#undef inline` in front of C++ tests.
+
+ - coders/x.c (RegisterXImage): Only register the X coder if HasX11
+ is defined.
+
+2003-06-07 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/image.c (GetImageGeometry) Y was a function of width
+ instead of height when processing EastGravity or WestGravity
+ (bug report from Cristy).
+
+2003-06-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (LocaleNCompare): Documented that comparison is
+ case-insensitive.
+ (LocaleCompare): Documented that comparison is case-insensitive.
+
+ - magick/log.c (ParseEvents): LocaleNCompare already does
+ case-insensitive compare so lower-casing is not necessary.
+
+ - Magick++: Updates to cause exceptions to be thrown if a bad
+ geometry specification is supplied.
+
+2003-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.c (ReadConfigureFile): Move event parsing to
+ ParseEvents funtion.
+ (SetLogEventMask): Move event parsing to
+ ParseEvents funtion.
+
+ - magick/utility.c (GetGeometry): Validate that the geometry
+ string only contains valid characters.
+
+ - PerlMagick/t/subroutines.pl (testMontage): It seems that passing
+ an empty set of options to the SetImage method corrupts the image
+ options (surely a PerlMagick bug), so don't invoke SetImage unless
+ there are options to set.
+
+2003-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (VersionCommand): Add build information to
+ version output.
+
+ - configure.ac: Save configure/build parameters for later use in
+ version output.
+
+2003-06-04 William Radcliffe <billr@corbis.com>
+
+ - coders/meta.c: Added some casts to make things compile better.
+
+2003-06-03 William Radcliffe <billr@corbis.com>
+
+ - coders/meta.c: Was broken due to editing mistakes as well
+ as inherent incompatability with MagickReallocMemory macro.
+
+2003-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xpm.c (RegisterXPMImage): Module registration for PICON
+ should have been XPM. Thanks to John Cristy for noticing this
+ bug.
+
+ - coders/psd.c (ReadPSDImage): Applied John Cristy's patch to fix
+ a index calculation bug which is evident when QuantumDepth>8.
+
+2003-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c: Eliminated some compiler warnings.
+
+ - magick/transform.c (ProfileImage): Eliminated some compiler
+ warnings.
+
+ - magick/static.c (RegisterStaticModules): Invoke
+ RegisterXTRNImage if \_VISUALC\_ is defined.
+
+2003-06-02 William Radcliffe <billr@corbis.com>
+
+ - utilities/gm.c: made -format work again but had to add off flag
+ to MagickCommand to maintain backward compatability with previous
+ versions of GM.
+
+ - magick/command.c: Added flag to tell MagickCommand whether GM is
+ expected to process metadata requests. The COM object \*always\* does.
+
+ - magick/transform.c: Added error handling, memory leak avoidance
+ and performanc enhancment.
+
+2003-06-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - NEWS: Added Bug Fixes item with info about the JNG encoder fix.
+
+2003-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS: Listed significant changes (thus far) in version 1.1.
+
+ - version.sh: Updated LIBRARY\_CURRENT and LIBRARY\_REVISION since
+ some command.c interfaces have changed, and a new interface has
+ been added. The only user of these interfaces should be `gm` but
+ it always pays to be careful.
+
+ - utilities/gm.c (main): Use MagickCommand.
+
+ - magick/command.c (MagickCommand): New function to provide
+ API-level command access to the command functions provided by the
+ GM utility with an interface similar to ConvertImageCommand.
+ (AnimateImageCommand): Changed function arguments to match
+ ConvertImageCommand.
+ (ConjureImageCommand): Changed function arguments to match
+ ConvertImageCommand.
+ (DisplayImageCommand): Changed function arguments to match
+ ConvertImageCommand.
+ (ImportImageCommand): Changed function arguments to match
+ ConvertImageCommand.
+
+ - libxml/libxml2.def: Remove LIBRARY line since Visual C++ 6.0
+ doesn't like that the build library doesn't match the name
+ specified by LIBRARY.
+
+2003-05-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (GetMagickInfoArray): Resolve thread-safety
+ issue by accessing magick\_list directly under the protection of a
+ lock rather than using the pointer returned by GetMagickInfo.
+ Added error handling for insufficient memory.
+
+ - coders/tile.c (RegisterTILEImage): Added a usage note in formats
+ listing.
+
+ - coders/viff.c (RegisterVIFFImage): Module definition for "XV"
+ was missing.
+
+ - coders/ps2.c (RegisterPS2Image): Module definition for "PS2" was
+ missing.
+
+ - coders/wmf.c (RegisterWMFImage): Added usage note in formats
+ listing.
+
+ - coders/xpm.c (RegisterXPMImage): Hide PM alias for XPM in the
+ formats listing.
+
+ - coders/logo.c (RegisterLOGOImage): Hide registrations for
+ GRANITE, LOGO, and NETSCAPE in the formats listing.
+
+ - coders/jpeg.c (RegisterJPEGImage): Module definition for "JPEG"
+ was missing.
+
+ - coders/html.c (RegisterHTMLImage): Module definition for "HTML"
+ was missing.
+
+ - coders/bmp.c (RegisterBMPImage): Module names for "BMP2" and
+ "BMP3" should be "BMP".
+
+2003-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (GetMagickInfoArray): New function to return
+ MagickInfo array.
+ (ListMagickInfo): Updated to use GetMagickInfoArray.
+ (ListModuleMap): New function to list module map to a file.
+
+ - utilities/gm.c: Centered the file header and made note of this
+ stupendously significant accomplishment.
+
+ - magick/command.c: Added a `-list modulemap` option. Added plural
+ forms of other list options for people who are are not limited to
+ the singular. Also `-list font` and `-list fonts` now work for
+ people who think in terms of fonts rather than type.
+
+2003-05-30 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - MNG encoder failed to set the JNG bit in the simplicity profile.
+
+ - MNG encoder failed to write FRAM chunks when all images were JNG.
+
+ - JNG encoder wrote the wrong alpha\_sample\_depth for opaque images.
+
+2003-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magic.c (ReadConfigureFile): Removed bogus embedded magic
+ data and ensured that errors with loading magic.mgk propogate to
+ the top.
+
+ - magick/constitute.c (ReadImage): When building delegate error
+ report, handle the case where the filename is empty (such as for
+ "LOGO:").
+
+ - coders/png.c (WritePNGImage): Ensure that most severe exception
+ is reported via exception argument.
+ (ReadMNGImage): Ensure that most severe exception is reported via
+ exception argument.
+
+ - magick/command.c (ConvertImageCommand): Ensure that most severe
+ exception is reported via exception argument.
+ (CompositeImageList): Ensure that most severe exception is
+ reported via exception argument.
+ (CompositeImageCommand): Ensure that most severe exception is
+ reported via exception argument.
+
+ - magick/constitute.c (WriteImages): Ensure that most severe
+ exception is reported via exception argument.
+
+ - utilities/gm.c: Centered file header because I didn't like it.
+
+ - locale/C.mgk: Removed some defunct messages.
+
+ - magick/blob.c (PingBlob): Report useful error message.
+ (BlobToImage): Report sensible error message for null blob.
+
+ - magick/utility.c (AcquireString): Change UnableToAquireString to
+ UnableToAllocateString.
+
+ - coders/xwd.c (ReadXWDImage): Report CorruptImage rather than
+ CorruptXWDImage.
+
+ - coders/xpm.c (ReadXPMImage): Report CorruptImage rather than
+ CorruptXPMImage.
+
+ - coders/xcf.c (load\_level): Report CorruptImage rather than
+ CorruptXCFImage.
+
+ - coders/wbmp.c (ReadWBMPImage): Report CorruptImage rather than
+ CorruptWBMPImage.
+
+ - coders/pcd.c: Report CorruptImage rather than CorruptPCDImage.
+
+ - coders/otb.c (ReadOTBImage): Report CorruptImage rather than
+ CorruptOTBImage.
+
+ - magick/constitute.c (ReadInlineImage): Report CorruptImage
+ rather than CorruptInlineImage.
+
+ - coders/pdb.c (ReadPDBImage): Incorporated undocumented fix from
+ ImageMagick which obtains the image depth from the image depth
+ attribute, and increases the packet memory allocation. Report
+ CorruptImage rather than CorruptPDBImageFile.
+
+2003-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/bin/modules.mgk: Add mapping from SVGZ to SVG.
+
+ - coders/modules.mgk: Add mapping from SVGZ to SVG.
+
+ - coders/svg.c (RegisterSVGImage): Add registration for SVGZ
+ format.
+
+ - PerlMagick/t/zlib/read.t: Added test to check reading a file
+ with .gz extension. The blob portion of the test currently fails.
+
+ - coders/wpg.c (ReadWPGImage): Fix reading WPGs with embedded
+ Postscript. Ensure that scene numbers are sane. Bugs remain.
+
+ - magick/blob.c (OpenBlob): Recognize the .svgz extension as a
+ gzipped format. Not required in order to read .svgz files since
+ the blob file magic detects gzip files.
+
+ - magick/command.c (MontageImageCommand): Wrong exception
+ macro was being invoked. Steps have been taken to ensure that
+ this doesn't happen again.
+ (ImportUsage): Fix spelling of `type`.
+
+ - magick/magick.c (DestroyMagick): Decided that initialization
+ state should be tracked via an enum so that DestroyMagick will
+ take effect even if InitializeMagick has never been called.
+
+2003-05-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/png.c: png.c would dump core when writing a grayscale
+ image in png24 or png32 format.
+
+2003-05-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/ept.c (WriteEPTImage): Fixed writing EPT preview image and
+ added logging.
+
+ - magick/enhance.c (NegateImage): If image is in CMYK colorspace,
+ then negate the `K` channel as well.
+
+ - PerlMagick/Magick.xs: Fix spelling of `elevation` argument to
+ Shade method.
+
+ - magick/image.h (ImageInfo): Added more documenting comments.
+
+ - magick/image.c (CloneImage): Don't clone huffman ascii85
+ encoding support structure since it is not useful outside of the
+ current image context. Cloning a structure via pointer assignment
+ causes a memory leak.
+
+2003-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c: Incorporate math tweaks obtained from
+ ImageMagick which are purported to improve accuracy when rotating
+ and shearing using small angles. Also avoid unneccessarily
+ transforming CMYK images into RGB images.
+
+ - magick/paint.c (ColorFloodfillImage): Fix hang while
+ floodfilling using a pattern image with color similar to the
+ border color.
+
+ - coders/modules.mgk: Add missing mappings for PNG8,
+ PNG24, and PNG32.
+
+ - VisualMagick/bin/modules.mgk: Add missing mappings for PNG8,
+ PNG24, and PNG32.
+
+2003-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.c (GetLogBlob): Return an error if log.mgk can not
+ be accessed.
+
+ - locale/C.mgk: Added UnableToAccessLogFile.
+
+ - magick/blob.c (GetConfigureBlob): Only return result of
+ NTResourceToBlob if it is non-NULL.
+
+ - magick/type.c (GetTypeBlob): Search $MAGICK\_HOME for
+ type.mgk. Only return result of NTResourceToBlob if it is
+ non-NULL.
+
+ - magick/magick.c (GetMagickInfo): Return an error if GetModuleInfo
+ reports an error.
+
+ - magick/module.c (GetModuleInfo): Return an error if modules.txt
+ fails to load.
+
+ - utility.c (SubstituteString): Fixed a bug which was introduced
+ while updating the code to use the memory allocation macros.
+
+2003-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/GraphicsMagick-config.in (usage): Added example
+ usage to the help output.
+
+ - magick/magick.c (InitializeMagick): Added a static flag to
+ ensure that the Magick library is initialized only one time.
+ (DestroyMagick): Ensure that Magick library resources are only
+ destroyed if it has previously been initialized.
+
+ - magick/nt\_base.c (DllMain): Fix contributed by Achim Domma. For
+ a DLL build, update PATH during Magick DLL initialization to
+ include the directory where the Magick core DLL resides. This
+ allows the loadable modules to find the core DLLs, even if the
+ core DLLs are not already in the PATH.
+
+ - magick/image.c (TextureImage): Incorporate new implementation
+ authored by John Cristy of ImageMagick Studio. This
+ implementation is a full 7X (run-time) or 14X (user-time) faster
+ than the original ImageMagick implementation, and is about 2X
+ faster than the speeded-up version I commited on the 19th.
+
+2003-05-20 William Radcliffe <billr@corbis.com>
+
+ - VisualMagick\configure : Fixed bug with add on (plug-ins) not
+ building automatically in DLL mode.
+
+2003-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (TextureImage): Creation of tiled image textures
+ is speeded up by 3.7X.
+
+ - coders/tile.c (ReadTILEImage): Use TextureImage.
+
+ - VisualMagick/bin/modules.mgk: Map "PATTERN" to "LOGO".
+
+ - coders/modules.mgk: Map "PATTERN" to "LOGO".
+
+ - coders/logo.c (ReadLOGOImage): Add "PATTERN" tiling support in
+ order to be compatible with ImageMagick.
+
+ - magick/image.c (SetImageInfo): Map "MAGICK" magick to "IMAGE" in
+ order to be compatible with ImageMagick.
+
+2003-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Copyright.html: Try to fix formatting of XFig entry.
+
+ - www/windows.html: Update file names for 1.0.1 release.
+
+ - index.html: Mention 1.0.1 release as latest release.
+
+ - magick/magick\_config\_api.h.in: Add define for HasX11
+ so that it is possible to use functions in the installed
+ xwindow.h
+
+ - \*/\*.c: Updated to use MagickAllocateMemory macro.
+
+2003-05-17 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/png.c: stifled compiler warnings about uninitialized
+ chunk and blob variables.
+
+2003-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.h (MagickAllocateMemory): New macro to allocate
+ memory.
+ (MagickFreeMemory): New macro to free memory.
+ (MagickReallocMemory): New macro to reallocate memory.
+
+ - \*/\*.c,\*/\*.h: Updated to use MagickFreeMemory and
+ MagickReallocMemory. Eliminated warnings when compiling with
+ GCC 3.3 using -Wall.
+
+ - images: The logo image was determined to have a copyright
+ problem so replace with blank image until a replacement is
+ available.
+
+2003-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/magick/magick\_config.h.in (HAVE\_SYS\_TYPES\_H):
+ Moved this define back from nt\_base.h since removing it was
+ causing some problems for Magick++.
+
+2003-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: (SetMagickInfo): Don't mask failure to
+ read magic.mgk.
+
+ - magick/constitute.c (ReadImage): Don't overwrite specific
+ exception info.
+
+ - magick/nt\_base.c (NTResourceToBlob): Add logging similar
+ to that used in IsAccessible() in order to make operation
+ more clear.
+
+ - magick/module.c (FindMagickModule): Removed extraneous
+ "Searching for module file" log event.
+ (GetModuleBlob): Under Windows, don't clear or overwrite
+ an existing exception.
+
+ - magick/nt\_base.h: Imported some obscure defines from
+ magick\magick\_config.h.
+
+ - VisualMagick/magick/magick\_config.h.in: Improved description
+ text and formatting. Moved some obscure defines to
+ magick/nt\_base.h.
+
+ - locale/C.mgk: Added a "RegistryKeyLookupFailed" error message.
+
+ - magick/type.c (GetTypeBlob): Report registry key lookup
+ failures. Also ensure correct return value when an error is
+ reported.
+
+ - magick/log.c (GetLogBlob): Report registry key lookup failures.
+
+ - magick/delegate.c (ReadConfigureFile): Report registry key
+ lookup failures.
+
+ - magick/blob.c (GetConfigureBlob): Report registry key lookup
+ failures. Also ensure correct return value when an error is
+ reported.
+
+ - magick/module.c (FindMagickModule): Report registry key lookup
+ failures. Also ensure correct return value when an error is
+ reported.
+
+ - magick/nt\_base.c (NTRegistryKeyLookup): Simplify base key lookup
+ code, and improve coding style.
+
+ - coders/logo.c, Copyright.txt, www/Copyright.html: Acknowledge
+ and respect the XFig copyright.
+
+ - VisualMagick/installer/inc/files-documentation.isx: QuickStart.txt
+ is no longer distributed so it is removed.
+
+2003-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h (RoundToQuantum): New macro to round positive
+ double to Quantum.
+
+ - magick/xwindow.c, magick/xwindow.h, magick/studio.h: Use FreeBSD
+ portability fixes from FreeBSD ports collection.
+
+ - configure.ac: Test for <machine/param.h> as used by some \*BSD systems.
+
+ - QuickStart.txt, www/QuickStart.html: Don't distribute QuickStart.txt or
+ www/QuickStart.html since the content doesn't currently apply to
+ GraphicsMagick.
+
+2003-05-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - README.txt: Added text regarding where to obtain dcraw, a simple
+ but useful decoder for the proprietary raw file formats produced
+ by digital cameras (58 supported cameras!).
+
+ - configure.ac: Added support for finding dcraw.
+
+ - VisualMagick/bin/delegates.mgk: Added support for dcraw.
+
+ - coders/delegates.mgk.in: Added support for dcraw.
+
+ - version.sh (PACKAGE\_RELEASE\_DATE): Extract the most recent
+ update date from the ChangeLog file using awk.
+
+2003-05-12 William Radcliffe <billr@corbis.com>
+
+ - modules.mgk, magic.mgk : Sync up both of these for UNIX
+ as well as VisualMagick builds. Includes changes for the
+ meta.c code.
+
+2003-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/formats.html: Documented embedded gray intensity images.
+
+ - coders/logo.c: Added the embedded dithered gray intensity images
+ gray0, gray5, ..., through gray100 to support bilevel filling and
+ painting with an intensity resolution of 5%.
+
+ - www/formats.html: Added description of images available via
+ "IMAGE:" format tag, as well as providing a tiled preview.
+
+ - coders/logo.c: Renamed "transparent" image to "checkerboard"
+ since it is a better description. Added a set of tiny bilevel
+ images (accessed via IMAGE:) for use when tiling, filling, or for
+ use as a texture image. The complete set of image names available
+ via the IMAGE: coder are now BRICKS, CIRCLES, CROSSHATCH,
+ CROSSHATCH30, CROSSHATCH45, FISHSCALES, GRANITE, HEXAGONS,
+ HORIZONTAL, HORIZONTALSAW, HS\_BDIAGONAL, HS\_CROSS, HS\_DIAGCROSS,
+ HS\_FDIAGONAL, HS\_HORIZONTAL, HS\_VERTICAL, LEFT30, LEFT45,
+ LEFTSHINGLE, LOGO, NETSCAPE, OCTAGONS, RIGHT30, RIGHT45,
+ RIGHTSHINGLE, ROSE, SMALLFISHSCALES, CHECKERBOARD, VERTICAL,
+ VERTICALBRICKS, VERTICALLEFTSHINGLE, VERTICALRIGHTSHINGLE, &
+ VERTICALSAW. The HS\_\* variants are similar to the standard
+ pattern images provided with the Windows GDI.
+
+ - coders/msl.c (MSLStartElement): Don't reset gravity if the user
+ provides an x,y coordinate. Passing coodinates was loosing the
+ gravity setting.
+
+2003-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/modules.mgk: Support the IMAGE: format via the LOGO
+ module.
+ - win2k/IMDisplay/IMDisplayView.cpp (DoDisplayImage):
+ Transparent tile is created by reading "tile:image:transparent".
+ - coders/logo.c (ReadLOGOImage): Add IMAGE: format to front for
+ embedded images so that adding new images doesn't proliferate coder
+ registrations. Legacy logo magick names (GRANITE, LOGO, NETSCAPE,
+ and ROSE) are still supported, but they are also available in the
+ IMAGE file space (e.g. IMAGE:ROSE).
+
+2003-05-09 William Radcliffe <billr@corbis.com>
+
+ - VisualMagick\configure : Further refinements that support both
+ the new "big" library and the normal dynamic DLL buidling styles.
+
+2003-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/logo.c (ReadLOGOImage): Added a "TRANSPARENT" pattern
+ image which can be tiled to form the background of transparent
+ images.
+
+ - win32/IMDisplay/IMDisplayView.cpp: When displaying images which
+ include an opacity channel, use a checker-board pattern as the
+ image background so non-opaque pixels become evident.
+
+2003-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c : Add or fix commenting of DebugString so that
+ module does not require Windows.
+
+ - lcms: Updated to release 1.10.
+
+2003-05-07 William Radcliffe <billr@corbis.com>
+
+ - VisualMagick\bin : Brought the MGK files back into sync with
+ the rest of the package and added types for meta.c.
+
+ - VisualMagick\bin\win32\ATL : removed config files in order to
+ prevent very old ATL project from being picked up in the config
+
+2003-05-06 William Radcliffe <billr@corbis.com>
+
+ - VisualMagick\lcms\LIBRARY.txt : a define to prevent popup message
+ box behaviour.
+
+ - VisualMagick\configure\ : New feature - -t consolidates all the
+ coders into on library for the static build in order to make the
+ build process tolerable.
+
+ - coders\xtrn.c : new support for BSTR - wdie character data
+
+ - coders\svg.c : put back logic that allows the -size parameter to
+ control the pixel dimensions of the output image.
+
+ - coders\meta.c : added support for wide character parsing of iptc
+ and 8BIM formats.
+
+2003-05-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh : Update to reflect development status.
+
+2003-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - GraphicsMagick 1.0 Released.
+
+ - version.sh (LIBRARY\_REVISION): Updated for the 1.0 release.
+
+ - magick/studio.h: Add fix to avoid problems caused by zlib
+ under AIX.
+
+ - magick/cache.h: Parameterized prototypes to make them easier
+ to follow.
+
+ - filters/analyze.c: Replace C++ comments with C comments.
+
+ - magick/command.c: For the composite, convert, identify, mogrify,
+ and montage commands, make sure a usage error is returned if a
+ usage message is printed. This is useful for ImageMagickObject
+ users who won't see the usage message if stdio is not supported.
+
+ - locale/C.mgk: Added "UsageError" error. Added missing closure
+ to <Corrupt> tag which caused most/many message lookups to fail.
+
+ - magick/nt\_base.h: Fixed a compile problem caused by masking
+ internals in delegate.h
+
+ - magick/ImageMagick.rc: Added missing .mgk files.
+
+2003-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (lt\_dlerror): Defining lt\_dlerror to be
+ NTGetLastError was not a correct implementation since the
+ interface is defined to return a const pointer to a string, but
+ NTGetLastError returns an allocated string, causing a memory leak
+ if NTGetLastError is used in the place of lt\_dlerror. A new
+ lt\_dlerror function is added to fix this.
+ (lt\_dlsetsearchpath): lt\_dlsetsearchpath should return an int
+ and accept a const char \*.
+ (lt\_dlsym): lt\_dlsym is supposed to take a const char \*.
+
+ - magick/nt\_base.h: lt\_dlclose should return an `int`.
+
+ - magick/nt\_base.c (lt\_dlclose): Return status from lt\_dlclose.
+
+ - magick/module.c (lt\_dlclose): lt\_dlclose is supposed to return
+ an `int`, not `void`. A return value of zero indicates success.
+
+ - VisualMagick/tests/run\_constitute.bat: Add batch script to
+ run constitute tests.
+
+ - magick/module.c: Added a ltdl\_initialized static flag to track
+ if libltdl has been initialized by lt\_dlinit().
+ (TagToFunctionName): Use a stack buffer for the string rather than
+ allocating heap data.
+ (UnregisterModule): Report errors via exception info as the
+ interface suggests.
+ (UnloadModule): Report errors via exception info as the interface
+ suggests.
+ (DestroyModuleInfo): Only invoke lt\_dlexit() if lt\_dlinit() has
+ previously been invoked.
+
+ - locale/C.mgk: Added FailedToCloseModule module error.
+
+ - magick/module.c (UnloadModule): Report exception via exception
+ parameter rather than simply printing out an error message and
+ exiting.
+
+ - magick/Makefile.am (noinst\_HEADERS): integral\_types.h had to be
+ listed \*somewhere\* in order to make it into the distribution.
+
+ - Magick++/lib/Magick++/Image.h: InitializeMagick must be DLL
+ exported.
+
+2003-05-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (magick-version): Perform version.isx substitutions
+ via Makefile.am rather than configure.
+
+ - magick/magick\_config\_api.h.in: Added template header for
+ the installed magick\_config.h.
+
+ - magick/magick.c (InitializeMagick): Improved the signal handling
+ and registration method. Signal handlers are only registered for a
+ signal if the current signal handling disposition for that signal
+ is set to the default (SIG\_DFL). When a signal is caught,
+ DestroyMagick is invoked, the handling for the signal is set back
+ to SIG\_DFL, and then the signal is re-raised to trigger the
+ default handler for that signal. This causes the process to behave
+ as closely to the default as possible (e.g. generating a core
+ file) while ensuring that DestroyMagick is executed. This also
+ ensures that signal handlers registered by API users are not
+ overridden by invoking InitializeMagick.
+
+ - configure.ac: Added tests for sigemptyset and
+ sigaction.
+ Add a check for the return type of signal handlers.
+ Test for the `raise` function.
+
+ - www/formats.html: Add an entry for CUR, Microsoft
+ Cursor Icon format.
+
+2003-05-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/semaphore.c (struct SemaphoreInfo): Added
+ `locked` and `thread\_id` members. These are used to record
+ if the semaphore is locked, and to validate the thread
+ ID of the unlocker.
+
+ - www/links.html: Added link to Nathan Day's MagickDocs
+ "ImageMagick and GraphicsMagick documentation project"
+ site.
+ Added a link to an on-line article regarding the PHP front-end
+ to ImageMagick.
+
+ - coders/icon.c (ReadIconImage): Add support for Windows
+ .CUR format based on advice from Jean Piquemal.
+
+ - magick/image.c (SetImageInfo): Added missing CloseBlob
+ in error path for failure to allocate temporary file.
+
+ - coders/pcx.c (ReadPCXImage): Added support for reading
+ uncompressed PCX images based on code from Jean Piquemal.
+
+2003-05-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (AddNoiseImage): For gray images, wrong
+ pointer was being used to evaluate intensity, leading to a
+ black image with noise.
+ - magick/image.c (ChannelImage): Return the channel
+ image in RGBColorspace. Also properly support extracting
+ the opacity channel for images which are not CMYK.
+
+2003-04-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/Makefile.am (install-data-local): Install
+ magick\_config\_api.h rather than magick\_config.h.
+
+ - magick/api.h: Removed inclusion of integral\_types.h from
+ magick/api.h. It is included by magick/studio.h.
+
+ - magick/delegate.h: Mapped out a block of private implementation
+ code.
+
+ - configure.ac: Perform substitutions on magick\_config\_api.h.
+
+ - magick/magick\_config\_api.h.in: New header file template to
+ use for installed magick\_config.h.
+
+ - magick/studio.h (MAGICK\_IMPLEMENTATION): Added the define
+ MAGICK\_IMPLEMENTATION used to enable private types, includes, and
+ defines in the headers. This supports hiding implementation stuff
+ that API users shouldn't see in the headers.
+
+ - utilities/Makefile.am (check): Cleaned up the utilities
+ test/demo a bit as well as using the undocumented "tmp:" prefix to
+ cause GraphicsMagick to remove temporary input files once they
+ have been read. This leaves just the final output file
+ "demo.miff" when the test completes.
+
+ - coders/jpeg.c (WriteJPEGImage): If the image resolution is
+ overwritten with 72DPI, make sure that the resolution units are
+ set to PixelsPerInchResolution.
+
+ - coders/jpeg.c (WriteJPEGImage): Don't overwrite the image
+ resolution if it is valid.
+
+ - magick/command.c (MogrifyImageCommand): Added -resample
+ option to match documentation.
+
+ - VisualMagick/configure: Added rpcrt4.lib to project settings
+ for Visual C++ 6.0 so that configure links. The code which
+ needs these interfaces is to support Visual C++ 7.0 XML-style
+ project files.
+
+2003-04-30 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - utilities/Makefile.am (check) Change % to %% in -label parameter.
+
+ - www/gm.html, utilities/gm.1, etc. Documented use of %% to convey
+ the % sign in -format, -comment, -label strings.
+
+2003-04-30 William Radcliffe <billr@corbis.com>
+
+ - magick/command.c: Changes from 2003-04-19 to free the arg
+ list when it was still pointed to by the option arg and accessed
+ on an exception. This caused gm to crash on any erroneous command
+ line argument.
+
+2003-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/windows.html: Updated to match current installer.
+
+ - VisualMagick/installer/inc/tasks-install-devel.isx (Name):
+ Added an installation checkbox so the user can select to install
+ development headers and libraries for C & C++.
+
+ - VisualMagick/installer/inc/files-perlmagick.isx (Source):
+ Only install PerlMagick PPD files if the user selects to install
+ PerlMagick.
+
+ - VisualMagick/installer/inc/files-com.isx (Source): Only
+ install ImageMagickObject files if the user selects to install
+ ImageMagickObject.
+
+ - magick/version.h.in: Added some documentation for the
+ functioning of MagickLibVersion and MagickLibVersionNumber.
+
+ - configure.ac: Perform substutions to create
+ VisualMagick/installer/inc/version.isx from
+ VisualMagick/installer/inc/version.isx.in. This allows Windows
+ versioning info to be updated from info in version.sh.
+
+ - Makefile.am (magick-version): For a VPATH build, update
+ VisualMagick/installer/inc/version.isx in the source directory if
+ it is out of date.
+
+2003-04-28 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/cache.c: CloneImagePixels(): applied Cristy's bugfix
+ from IM-5.5.7.
+
+2003-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/api.html: The demo program on the ImageMagick API page is
+ usually intended to be an exercise for the reader. It rarely
+ compiles or works. Sure enough the demo code was not even close
+ to compiling, didn't run, and did something totally different than
+ described. This is not a good way to treat new users. Now the
+ demo program compiles and runs, and its description is correct.
+
+ - www/magick.css, www/smile.c: Remove "Pair" advertisement which
+ was discovered appended at the end of these files.
+
+ - coders/jpeg.c (ReadJPEGImage): Check for failure of
+ AllocateImage. Close blob prior to error return.
+
+ - configure.ac: Perform substitutions on magick/version.h
+
+ - magick/version.h.in: New file to provide base for configured
+ magick/version.h
+
+ - version.sh (PACKAGE\_RELEASE\_DATE): Support setting a package
+ release date.
+
+ - configure.ac: Perform substitutions on PerlMagick/Magick.pm.in to
+ create PerlMagick/Magick.pm.in.
+
+ - PerlMagick/Magick.pm.in: @PACKAGE\_VERSION@ is substituted while
+ configuring PerlMagick/Magick.pm.
+
+ - magick/magic.mgk, VisualMagick/bin/magic.mgk: Removed risky
+ entry for PICT which has been demonstrated to lead to a false
+ match in the real-world.
+
+ - coders/pict.c (ReadPICTImage): Ensure that PICT decoder don't
+ loop forever with an EOF condition if none of the PICT op-codes
+ encountered result in a condition which terminates the input loop.
+ If EOF is dectected while in the input loop a "corrupt image"
+ "unexpected end of file" error is reported.
+
+ - VisualMagick/installer: Updated installer.
+
+2003-04-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c, magick/blob.c, magick/studio.h: Added
+ Compilation fixes recommended by Harold Bien for for Borland C++.
+
+ - www/contribute.html: Added text regarding contributing to
+ GraphicsMagick.
+
+ - www/api/types.html: Documentation for GraphicsMagick API types
+ moved from www/api/types/\*.html into this one file. Types
+ documentation is still very much under development.
+
+ - README.txt: Added note regarding the download location for free
+ Windows fonts which are kindly made available by Microsoft.
+
+ - VisualMagick/installer/gm-dynamic-full-\*.iss: Install
+ nt\_base.h and nt\_feature.h.
+
+2003-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/windows.html: Updated for GraphicsMagick 1.0 and to
+ link to ImageMagickObject.html.
+
+ - www/programming.html: Added link to ImageMagickObject.html.
+
+ - www/ImageMagickObject.html: New file to provide some
+ documentation for ImageMagickObject.
+
+ - www: Found and fixed broken URL links.
+
+2003-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - FlashPIX: Applied patches from FreeBSD. Bumped package
+ version to version to 1.2.0.8.
+
+ - www/api.html: Updated to reflect GraphicsMagick
+
+ - www/\*.html: Updated with format\_c\_api\_docs script.
+
+ - Makefile.am (format\_c\_api\_docs): Add a target to update
+ the C API documentation.
+
+ - scripts/format\_c\_api\_docs: Add script which extracts and
+ formats the C API documentation into HTML files in the www/api
+ subdirectory.
+
+2003-04-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh (PACKAGE\_VERSION): Update release version ID.
+
+ - magick/version.h (MagickReleaseDate): Update release date.
+
+ - magick/constitute.c (ConstituteImage): Fixed problems with
+ reading intensity (gray) pixel arrays.
+
+ - magick/image.c (GrayscalePseudoClassImage): Use
+ ScaleQuantumToIndex rather than ScaleQuantumToMap.
+
+ - magick/constitute.c (ConstituteImage): Use ScaleQuantumToIndex
+ macro to scale integral intensity values to colormap range.
+
+ - magick/image.h (ScaleQuantumToIndex): New macro to scale a
+ quantum to the maximum range of a colormap index. Useful when
+ writing to PsuedoClass grayscale images.
+
+ - VisualMagick/tests/run\_constitute.bat: Batch script to run
+ constitute tests.
+
+ - VisualMagick/installer/\*.iss: Updated for Beta1 release.
+
+2003-04-22 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - utilities/Makefile.am (check) fixed typos (RM -> RMDelegate
+ and removed stray "gm"), added -random-threshold, ordered-dither.
+
+ - magick/effect.c: Random-threshold was not treating non-gray
+ PseudoColor images correctly.
+
+2003-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/Makefile.am (check): Added code to put logo on demo
+ output.
+
+ - magick/command.c (MontageImageCommand): Pass exception rather
+ than &image->exception because image may be null, and it is
+ pointless to store the exception where it will not be reported to
+ the user anyway.
+
+ - utilities/Makefile.am (check): Ported Glenn Randers-Pehrson's
+ utilities demo script into the Makefile to serve as a check
+ target.
+ (check): Add definition to find Generic.ttf.
+
+ - locale/C.mgk: Fixed syntax error in <Option><FatalError>
+ section.
+
+ - www/development.html: New file to describe development
+ process.
+
+ - index.html, www/\*.html: Added link to development.html
+ and improved formatting a bit.
+
+2003-04-21 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Fixed bug with compiling png.c with libpng versions
+ older than libpng-0.95.
+
+2003-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/programming.html: Added links to Delphi and Scheme
+ programming interfaces.
+
+ - configure.ac : Removed outdated test for jp2conf.h.
+
+2003-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Add argument expansion and deallocation code
+ to command functions which lacked this functionality.
+ Replace calls to Exit with a return to the invoking function.
+
+ - utilities/gm.c: Expect each subcommand to expand and deallocate
+ its own argument list. Treat subcommands more similarly.
+
+ - magick/magick.c (InitializeMagick): Seed the random number
+ generator.
+
+ - magick/utility.c (ExpandFilenames): Handle tilde expansion
+ properly. Handle relative glob specifications. Skip over "\*"
+ argument to +profile properly. Don't expand VID: specifications
+ since the VID: coder will execute ExpandFilenames() later. Apply
+ format specifier prefix to globbed file names. Fix double frees
+ and rationalize memory management by always copying to a new
+ vector.
+
+2003-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (InitializeMagick): Decided to
+ move clean-up signal-handler registration from gm.c
+ to magick.c in order to ensure that resources are
+ cleaned up for all library users. This means that
+ if a user program wants to do something special for
+ signals registered to be caught by InitializeMagick
+ (SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGTERM, SIGXCPU,
+ & SIGXFSZ) then the user program should register its
+ own signal handlers after invoking InitializeMagick.
+ The user is then responsible for making sure that
+ DestroyMagick is invoked if an unexpected signal is
+ caught.
+
+ - tests/Makefile.am (check-constitute): Added
+ constitute tests.
+
+ - magick/constitute.c: New test program to ensure
+ that ConstituteImage and DispatchImage are working
+ correctly.
+
+2003-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/download.html: Added links to directories
+ at ftp.graphicsmagick.org.
+
+ - index.html: Add notice regarding 1.0 Beta0
+ availability.
+
+ - www/cvs.html: Updated CVS checkout information to
+ include the GraphicsMagick-1\_0 branch.
+
+ - coders/psd.c (ReadPSDImage): Applied patch
+ (SourceForge patch ID 722849) from Derry Bryson to
+ fix a memory leak. An image was being leaked.
+
+ - magick/constitute.c (DispatchImage): Applied patch
+ (SourceForge patch ID 722655) from Derry Bryson to
+ correctly use the switch\_map array rather than the
+ map array. Without this patch, DispatchImage does
+ not work at all.
+
+ - GraphicsMagick 1.0.0-beta0 release.
+
+ - version.sh: Updated for beta0 release.
+
+ - \*.c magick/\*.h: Update header inclusion to include
+ "magick/" prefix in order to ensure that there is no
+ confusion with headers from another package.
+
+2003-04-16 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/effect.c: 4x4 ordered dither threshold was
+ incorrect.
+
+2003-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (InitializeMagickResources):
+ Added the ability to obtain the amount of physical
+ memory by executing an external command.
+
+ - configure.ac: Check for getpagesize().
+ (MAGICK\_PHYSICAL\_MEMORY\_COMMAND): Added a test for
+ an external command which (quickly) returns the
+ amount of physical memory installed on the machine.
+ Currently only activated for FreeBSD.
+ (MAGICK\_PHYSICAL\_MEMORY\_COMMAND): Use sysctl to
+ determine total physical memory for Darwin.
+
+ - magick/delegate.c (ListDelegateInfo): If COLUMNS
+ environment variable is set, then use it to obtain
+ the screen width. Some shells dynamically update
+ COLUMNS, but COLUMNS may need to be explicitly
+ exported in order for it to be seen by subordinate
+ programs (such as gm).
+
+ - magick/effect.c (AddNoiseImage): Use IsGrayImage()
+ to check if the image is gray. Add missing columns
+ loop for intensity case (oops!).
+
+ - magick/command.c (DisplayImageCommand): Fix
+ -dispose option processing bug reported by
+ Felix Heimbrecht.
+
+ - coders/fpx.c: Check status from FPX\_InitSystem().
+
+2003-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Define PERLMAINCC to be the C compiler
+ if there are no C++ dependencies, or the C++ compiler
+ if there are C++ dependencies.
+
+ - PerlMagick/Makefile.PL.in: Use PERLMAINCC to compile
+ and link perlmain.c. This allows using the C++ compiler
+ to link, which is useful when the build depends on C++
+ libraries like libfpx.
+
+ - ltmain.sh: Updated to libtool 1.5 release.
+
+ - Makefile.am ($(PERLMAGICK)/$(PERLSTATICNAME)): Add
+ rules to make sure that static PerlMagick is linked
+ against the current GraphicsMagick library.
+
+ - coders/miff.c (ReadMIFFImage): Properly scale
+ colormap entries.
+
+ - magick/image.c (TransformRGBImage): Eliminate 32-bit
+ integer overflow condition for Q:32 build while
+ transforming CMYK pixels.
+
+2003-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/ttf/read.t: Updated signatures and
+ reference image for FreeType 2.1.4.
+
+ - (PerlMagick/t/write.t, PerlMagick/t/montage.t,
+ PerlMagick/t/rad/read.t, PerlMagick/t/rad/write.t):
+ Fix signatures which were thrown off by previous
+ change to how signatures are specified to functions
+ in subroutines.pl.
+
+ - PerlMagick/t/cgm/read.t: Updated to use reference
+ image.
+
+ - PerlMagick/Makefile.PL.in: Perform substitutions
+ on generated Makefile to ensure that the proper
+ -lGraphicsMagick is used for a static build.
+
+ - ttf: Updated to FreeType 2.1.4. Now stored in
+ CVS as delegates/freetype2 rather than delegates/ttf
+ so be sure to re-checkout the ttf directory so that
+ the correct files are used.
+
+ - wmf/incude/libwmf/api.h: Updating FreeType caused
+ a problem since it introduced a copy of zlib and
+ api.h included zlib.h. Fixed problem by adding
+ a typedef for gzFile and not including zlib.h.
+
+ - utilities/gm.c: Fixed minor compilation problem
+ under Windows caused by a typo in the signal
+ handler registration code.
+
+2003-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: When building a static PerlMagick,
+ build PerlMagick as part of the `all` target and
+ don't do a `make clean` of PerlMagick at install
+ time.
+
+ - configure.ac (LIB\_DPS): Add check to see if -lXt
+ is required by -ldps. XFree86 -ldps requires -lXt.
+
+ - FlashPIX: FlashPIX library now compiles under
+ FreeBSD 5.0.
+
+ - magick/deprecate.c (ValidateColormapIndex): Remove
+ non-interface deprecated function.
+
+ - magick/tempfile.c (AcquireTemporaryFileDescriptor):
+ Priortize use of mkstemp() over tempname() since \*BSD
+ compilers whine about tempname() (although we do use
+ tempname() safely).
+
+ - magick/color.c (ConstrainColormapIndex): Removed
+ function since it is no longer used.
+
+ - magick/utility.c (TemporaryFilename): Removed
+ TemporaryFilename utility function since it is
+ no longer used and it makes \*BSD compilers
+ complain.
+
+ - magick/studio.h: Don't define \_ISOC99\_SOURCE,
+ \_POSIX\_C\_SOURCE, or \_XOPEN\_SOURCE when compiling
+ under FreeBSD since this maps out a `ushort`
+ definition required by /usr/include/sys/ipc.h.
+
+2003-04-11 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/png.c: Some grayscale PNG images and the
+ JNG alpha channel were decoded improperly at Q:32.
+
+ - magick/constitute.c (PopImagePixels): Changed many
+ instances of (Quantum) typecast to (unsigned char).
+
+2003-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/tiff/read.t: Added signature for 12-bit
+ TIFF test and a Q:32 build.
+
+ - PerlMagick/t/subroutines.pl: Extended routines
+ which are signature based to accept signatures for
+ Q:32 as well.
+
+ - PerlMagick/t/wmf/read.t: Relax error values slightly
+ to pass at Q:32.
+
+ - coders/miff.c (PushImageRLEPixels): Fix reading
+ RLE MIFF at Q:32. A fragment of old code was being
+ used to obtain the length.
+ (WriteRunlengthPacket): Fix writing RLE MIFF at Q:32.
+ In most cases the wrong scaling macro was being used.
+
+ - tests/Makefile.am (check-miff): Added MIFF tests
+ for supported compression options.
+
+2003-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/color.c (QueryColorDatabase): Extended to
+ support parsing Q:32 hex color specification strings.
+ Also add error reporting for failure to parse the
+ color specification. This resolves a bug that drawing
+ via the draw.c APIs was not working for Q:32 builds.
+
+ - utilities/gm.c (main): Add signal handlers to
+ make sure that program cleans-up on exit by invoking
+ DestroyMagick.
+
+ - magick/draw.c (DrawSetFillColor): Quote color
+ specification.
+ (DrawSetStrokeColor): Quote color specification.
+ (DrawSetTextUnderColor): Quote color specification.
+
+ - ltmain.sh: Update to latest CVS libtool.
+
+2003-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/enhance.c (NormalizeImage): Only normalize the opacity
+ channel if image->matte is true. This results in some (15%)
+ speedup. While it can be argued that the `K` in CMYK should be
+ normalized, it can also be argued that this is senseless since `K`
+ is not a "linear" measure like C, M, & Y are, and there may not be
+ any any value to normalizing CMY at all.
+ (EqualizeImage): Only equalize the opacity channel if image->matte
+ is true. This results in a 23% speedup.
+ (GammaImage): Minor loop optimization.
+ (LevelImage): Don't level the opacity channel. Doing so doesn't
+ make any sense.
+ (LevelImageChannel): Put loops inside switch statement rather than
+ around it.
+
+ - PerlMagick/t/tiff/read.t: Added grayscale 12-bit and 16-bit TIFF
+ read tests.
+
+2003-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Add support for reading
+ 12-bit grayscale TIFFs. Fix reading 16-bit grayscale TIFFs
+ when QuantumDepth=8.
+
+ - VisualMagick/installer/gm-dynamic-full-8.iss,
+ VisualMagick/installer/gm-dynamic-full-16.iss: Many C header
+ files were not being included in the distribution. Oops!
+
+2003-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - (index.html, www/\*.html): Update to new web page style.
+
+ - scripts/txt2html: Update to output new web page style.
+
+ - ltmain.sh: Updated to latest CVS libtool.
+
+ - magick/tempfile.c (DestroyTemporaryFiles): Function was
+ crashing if it was executed twice.
+
+2003-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/delegates.mgk.in: Ralcgm was appending ".ps" to the
+ provided output file name, so change cgm delegate command so that
+ the input file is delivered via standard input, output is
+ re-directed to a file, and anything printed to stderr (such as
+ the Ralcgm program name and version) is sent to /dev/null.
+
+ - INSTALL-unix.txt: Added/corrected/improved documentation
+ regarding --disable-installed, --enable-shared, and
+ --with-modules.
+
+ - VisualMagick/magick/magick\_config.h.in: Add more documentation
+ and explanatory notes in order to lessen confusion.
+
+ - Many files: Replaced "UseInstalledImageMagick" with
+ "UseInstalledMagick" for obvious reasons.
+
+2003-04-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/command.c, utilities/gm.c: Print "help" screen for a
+ tool when user types "gm tool" or "gm tool -help"
+
+ - magick/command.c, magick/effect.c: add -ordered-dither option.
+
+2003-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - locale/C.mgk: Fixed message associated with
+ "UnableToCreateTemporaryFile".
+
+ - magick/tempfile.c (AcquireTemporaryFileDescriptor): Decided
+ to return a pathname (if possible), even on failure, for use
+ in error reports. The function return status should be used
+ to determine if the function has succeeded.
+
+ - locale/locale.mgk: Updated copyright header.
+
+ - (magick/annotate.c, magick/attribute.c, magick/blob.c,
+ magick/cache.c, magick/constitute.c, magick/delegate.c,
+ magick/display.c, magick/image.c, magick/locale.c
+ magick/tempfile.c, magick/tempfile.h, magick/utility.c,
+ magick/xwindow.c, coders/dcm.c, coders/ept.c,
+ coders/histogram.c, coders/mpeg.c, coders/pdf.c,
+ coders/pict.c, coders/preview.c, coders/ps2.c,
+ coders/ps3.c, coders/ps.c, coders/pwp.c, coders/sfw.c,
+ coders/svg.c, coders/tiff.c, coders/url.c, coders/wpg.c):
+ Ensure that failure to allocate/create temporary file is
+ properly detected and reported.
+
+2003-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/type.c (GetTypeBlob): Prioritize hard-coded path
+ over Windows registry values.
+
+ - magick/log.c (GetLogBlob): Prioritize hard-coded path
+ over Windows registry values.
+
+ - magick/blob.c (GetConfigureBlob): Prioritize hard-coded path
+ over Windows registry values.
+
+ - magick/delegate.c (ReadConfigureFile): Perform substitutions
+ for "@GMDelegate@", "@GMDisplayDelegate@", "@MPEGDecodeDelegate@",
+ "@MPEGEncodeDelegate@", and "@HPGLDecodeDelegate@" while reading
+ delegates.mgk under windows.
+ (ListDelegateInfo): Format delegate command line to multiple
+ lines if necessary rather than truncating.
+
+ - configure.ac (MagickBinPathDefine): Added support for
+ a MagickBinPath definition.
+
+ - configure.ac (GSVersion): Added test to obtain version
+ of installed Ghostcript.
+
+ - magick/tempfile.c (AcquireTemporaryFileDescriptor): Open
+ flag should have been O\_RDWR, not O\_WRONLY!
+
+2003-04-03 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/utility.c: Simplified skipping over the "\*" in
+ the +profile "\*" option when expanding filenames.
+
+2003-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/bin/delegates.mgk: Update similarly to
+ coders/delegates.mgk.in.
+
+ - coders/delegates.mgk.in: Replaced `mpeg-decode` delegate
+ specification with `mpeg` delegate specification.
+
+ - PerlMagick/t/mpeg/read.t: Since -r option is no longer
+ supplied to mpeg2decode, the signatures must be updated.
+
+ - magick/utility.c (ExpandFilenames): Skip over no-argument
+ commands properly.
+
+ - coders/mpeg.c: Removed ReadMPEGImage since this is handled
+ entirely by delegate now.
+
+ - magick/command.c: Add convert -temporary option for use
+ when input files are temporary files which should be
+ automatically removed.
+
+ - magick/delegate.c (InvokeDelegate): Ensure that temporary
+ file access is secure.
+
+ - coders/ept.c (ReadEPTImage): Ensure that temporary file
+ specified by image\_info->filename is liberated before
+ allocating a new temporary file name.
+
+ - coders/ps.c (ReadPSImage): Ensure that temporary file
+ specified by image\_info->filename is liberated before
+ allocating a new temporary file name.
+
+ - coders/pdf.c (ReadPDFImage): Change TemporaryFilename
+ to AcquireTemporaryFileName.
+
+ - magick/tempfile.c (LiberateTemporaryFile): Now takes
+ a `char \*` argument rather than `const char \*`, and
+ erases the provided filename if it is the name of a valid
+ temporary file. This helps avoid errors. The return
+ status may be used to determine if a file was removed.
+ (AcquireTemporaryFileDescriptor): Decided that adding a
+ .tmp extension to temporary file names is unnecessary.
+
+ - coders/jp2.c (WriteJP2Image): Destroy pixel matrix
+ after encoding image. Cristy says that there is memory
+ corruption otherwise.
+
+2003-04-01 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/png.c: Use new temporary file manager for JNG components.
+ Merge with IM 5.5.7 (mostly cosmetic changes).
+
+2003-03-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/cache.c (OpenCache): Add some Windows-specific
+ open options.
+
+ - magick/resource.c (InitializeMagickResources): Increase
+ the number of "lowio" file handles available for use under
+ Windows.
+
+ - ltdl/ltdl.c: Incorporate more Darwin fixes from CVS libtool.
+
+ - coders/pcx.c (ReadPCXImage): Incorporate bugfix from
+ ImageMagick -- Not enough memory allocated for reading PCX
+ (bug report by Trevor Willis).
+
+ - magick/magick.c (InitializeMagick): Only invoke
+ SetLogEventMask() to set debug options based on
+ getenv("MAGICK\_DEBUG") if the environment variable is set.
+
+2003-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/tempfile.c: Include tempfile.h rather than temporary.h
+
+ - magick/magick.c: Include tempfile.h rather than temporary.h
+
+ - coders/dcm.c, coders/ept.c, coders/histogram.c, coders/mpeg.c,
+ coders/pdf.c, coders/pict.c, coders/preview.c, coders/ps.c,
+ coders/ps2.c, coders/ps3.c, coders/pwp.c, coders/sfw.c,
+ coders/svg.c, coders/tiff.c, coders/url.c, coders/wpg.c,
+ magick/annotate.c, magick/attribute.c, magick/blob.c,
+ magick/cache.c, magick/constitute.c, magick/delegate.c,
+ magick/display.c, magick/image.c, magick/magick.c,
+ magick/utility.c, magick/xwindow.c: Updated to use new temporary
+ file allocation APIs.
+
+ - magick/tempfile.c: New temporary file allocation subsystem for
+ allocating, tracking, and deallocating temporary files. Use of
+ this subsystem should reduce the likelyhood that temporary
+ files will be left behind once the process exits.
+ If the environment variable MAGICK\_TMPDIR is set, then its
+ value is used as the location to place temporary files.
+
+ - magick/utility.c (IsAccessibleAndNotEmpty): New function
+ for testing for file exists, is a regular file, and is not empty.
+ Used to test if a temporary file has been updated by a delegate.
+
+ - magick/log.c (SetLogEventMask): Add support for setting
+ TemporaryFileEvent.
+
+ - PerlMagick/Magick.xs: Added TemporaryFile log event type.
+
+ - magick/log.h (LogEventType): Add TemporaryFileEvent event
+ classification.
+
+2003-03-29 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/resize.c (SampleImage) and magick/render.c (DrawAffineImage():
+ Applied Cristy fix for bug that offset images to the top and left.
+
+ - magick/resize.c (ScaleImage): Fixed bug that caused intensity
+ levels to be one unit too high.
+
+ - coders/png.c: make JNG support depend on HasJPEG. Remove temp files.
+
+2003-03-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resize.c (ResizeImage): Applied fix authored by John
+ Cristy for distortion when using the bessel filter.
+
+ - magick/display.c: Applied fix authored by John Cristy which
+ eliminates bogging down when using the magnifier window on
+ large images.
+
+ - Several files: A few files included multiple copies of the
+ copyright header text due to either pilot error, or equipment
+ failure.
+
+2003-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am : Removed some debug code which was
+ accidentally committed to CVS.
+
+ - Copyright.txt: Add copyright statements to all the files,
+ including some apparently missing copyrights.
+
+2003-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+ - magick/Makefile.am: Added temporary.c and temporary.h. These
+ are not finished yet.
+
+ - magick/cache.c: Transferred optimization from ImageMagick
+ to read/write all requested pixel cache rows in one system
+ call when accessing the cache using file I/O, and the
+ requested columns equals the image columns.
+
+ - magick/resource.c: (ResourceInfo): Use type `double` rather
+ than `long double`. For many systems, the range of `long double`
+ is the same as `double`. On others, use of `long double` incurs
+ the cost of function calls since there is no hardware support.
+
+2003-03-22 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/effect.h, effect.c, command.c: Revised -random-dither
+ to require parameters: channel LOWxHIGH. Channel can presently
+ be "intensity", "opacity", or "all".
+
+2003-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ltdl/ltdl.c: Updated to latest CVS version. Claimed to
+ support loading modules under MacOS-X.
+
+ - magick/resource.c (InitializeMagickResources): Enable code
+ under Windows which queries system limits.
+
+ - magick/cache.c (S\_MODE): Fixed portability problems with
+ definition.
+
+ - VisualMagick/bin/delegates.mgk: Fix typo in "mpeg-decode"
+ decode rule.
+
+ - libtool: Update to latest CVS version.
+
+ - configure.ac: Test zlib for gzseek and gztell.
+
+ - magick/effect.c (ChannelThresholdImage): The is\_grayscale flag
+ was not be evaluated correctly.
+
+2003-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h (RoundSignedToQuantum): Added handy
+ RoundSignedToQuantum macro for munging doubles into Quantums.
+
+ - magick/effect.c (ThresholdImage): Added optimizations for
+ thresholding all pixels to white or black. Threshold using an
+ integral value rather than a double so compares are faster.
+ (ChannelThresholdImage): Threshold against integral values since
+ compares are faster. Invoke ThresholdImage for simple thresholding
+ across all channels since it is faster.
+
+2003-03-19 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/meta.c: #ifdef'ed out some dead code.
+
+ - magick/annotate.c: #ifdef'ed out some code that is only
+ used when HasTTF is defined.
+
+ - Added RandomThresholdImage() method and -random-threshold
+ commandline option.
+
+2003-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac (LIB\_TIFF): Check for TIFFReadRGBATile and TIFFReadRGBAStrip
+ in libtiff before deciding to use it.
+
+ - magick/blob.c (WriteBlob): Move pointer increment into
+ paranthesis.
+ (ReadBlob): Move pointer increment into paranthesis.
+
+ - magick/gem.c (HSLTransform): Removed inline statement.
+ (TransformHSL): Removed inline statement.
+
+ - magick/random.[c|h]: Removed files from CVS.
+
+ - magick/command.c: Don't include random.h.
+
+ - PerlMagick/t/reference/jng: Update reference files to current output.
+
+2003-03-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Added tests for pread and pwrite functions.
+
+ - magick/image.c (GrayscalePseudoClassImage): Properly invoke
+ SyncImagePixels.
+
+ - magick/cache.c (SyncCacheNexus): Add back in is\_monochrome and
+ is\_grayscale flag resetting which was lost by copying over
+ ImageMagick's cache.c.
+ (FilePositionRead): Inline wrapper for reading a chunk of data at
+ an offset.
+ Cleans up some messy code, and makes it easy to use pread().
+ (FilePositionWrite): Inline wrapper for writing a chunk of data at
+ an offset.
+ Cleans up some messy code, and makes it easy to use pwrite().
+ Cache now uses pread() and pwrite() to access the cache if these
+ calls are available.
+
+ - magick/resource.c (InitializeMagickResources): Support setting
+ resource limits via the environment variables MAGICK\_LIMIT\_DISK,
+ MAGICK\_LIMIT\_FILES, MAGICK\_LIMIT\_MEMORY, and MAGICK\_LIMIT\_MAP.
+
+2003-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/stream.c (AcquirePixelStream): Store total pixels in
+ 64-bit type.
+ (SetPixelStream): Store total pixels in 64-bit type.
+
+ - coders/tiff.c (WriteTIFFImage): CoderError should be
+ MissingDelegateError.
+
+ - coders/ps3.c (Huffman2DEncodeImage): CoderError should be
+ MissingDelegateError.
+ (WritePS3Image): CoderError should be MissingDelegateError.
+
+ - coders/ps2.c (Huffman2DEncodeImage): CoderError should be
+ MissingDelegateError.
+
+ - coders/pdf.c (Huffman2DEncodeImage): CoderError should be
+ MissingDelegateError.
+
+ - coders/fpx.c (ReadFPXImage): CoderError should be
+ MissingDelegateError.
+ (WriteFPXImage): CoderError should be MissingDelegateError.
+
+ - coders/dps.c (ReadDPSImage): CoderError should be
+ MissingDelegateError.
+
+ - magick/image.c (AnimateImages): DelegateError should be
+ MissingDelegateError.
+
+ - magick/annotate.c (RenderX11): DelegateError should be
+ MissingDelegateError.
+
+ - magick/image.c (DisplayImages): DelegateError should be
+ MissingDelegateError.
+
+2003-03-17 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/image.c Relocated misplaced break in ChannelImage()
+ and sped up SetImageOpacity by avoiding blend operation when
+ setting the image fully opaque.
+
+2003-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/cache.c: Snarfed cache.c updates from ImageMagick.
+
+ - magick/command.c: Added -list resource support.
+
+2003-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/Makefile.am (random.c): Removed building, packaging,
+ and intialization of random.c functions since it is not actually
+ used.
+
+ - magick/semaphore.c (InitializeSemaphore): Only initialize
+ critical section if active\_semaphore is not already true.
+
+ - magick/resource.c: Snarf resource.c updates from ImageMagick.
+
+ - PerlMagick/Magick.xs: Added missing log event types.
+
+ - magick/log.h (enum): Added ResourceEvent enumeration.
+
+ - magick/log.c (LogMagickEvent): fflush(stdout) at the end of
+ each log. Otherwise output may not be seen for a long time.
+ (SetLogEventMask): Add support for "-debug resource".
+
+ - coders/tiff.c (RegisterTIFFImage): Don't register encode and
+ decode handlers for TIFF if TIFF library is not available.
+
+ - magick/constitute.c (WriteImage): Fix cut-n-paste error
+ in log message ("decoder" --> "encoder").
+
+2003-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - index.html: Added a link to the GraphicsMagick mailing lists.
+
+ - Magick++/demo/zoom.cpp: Added dashed option support, including
+ a -resample option for image resampling.
+
+2003-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (DIST\_SUBDIRS): Filters subdirectory needs to
+ be distributed.
+
+2003-03-14 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/render.c Ported Cristy's bugfix to DrawAffineImage().
+
+2003-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (DestroyImage): Comment out new assertions until
+ we are certain that there are no ill effects.
+
+ - coders/mat.c (ReadMATImage): Set image->depth to valid values.
+
+ - PerlMagick/Magick.xs: Update so that new DestroyImage assertions
+ aren't asserted.
+
+ - magick/list.c (DestroyImageList): Update so that new DestroyImage
+ assertions aren't asserted.
+
+ - coders/wpg.c (ReadWPGImage): Don't leave dangling pointer when
+ trimming list. Don't set image->depth to invalid values.
+
+2003-03-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (DestroyImage): Add assertions to verify
+ that destroyed image is not currently referenced by another
+ image. This should help prevent accidental continued use
+ of a destroyed image.
+ (DestroyImage): Added assertions to enforce that images
+ should not continue to reference the destroyed image.
+
+ - coders/wpg.c: Incorporated fixes from Jaroslav Fojtik.
+
+ - version.sh (PACKAGE\_VERSION\_ADDENDUM): Construct a package
+ snapshot version based on the ChangeLog modification time.
+ This requires GNU find to work propery since the -printf
+ option is used.
+
+ - configure.ac (LIB\_GS): Do not test for the Ghostscript
+ library by default due to the issue of its embedded libjpeg
+ conflicting with libjpeg.
+
+ - coders/ept.c (ReadEPTImage): "PostscriptDelegateFailed" should
+ be classified as a DelegateError type.
+
+2003-03-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (BlobToFile): Truncate while opening file.
+ (ImageToFile): Truncate while opening file.
+
+ - magick/annotate.c (RenderFreetype): Missing freetype library
+ should result in a MissingDelegateError type rather than a
+ DelegateError type.
+
+ - INSTALL-windows.txt: Added a note regarding a workaround for
+ internal compiler errors while compiling image.c when using
+ Visual C++ 7.0.
+
+ - coders/jpeg.c (ReadICCProfile): Incorporate ImageMagick fix
+ to handle short JPEG ICC profiles.
+
+ - magick/integral\_types.h: Ignore SIZEOF\_LONG\_LONG and
+ SIZEOF\_UNSIGNED\_LONG\_LONG defines if \_VISUALC\_ is defined.
+
+2003-03-11 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - www/gm.html, utilities/gm.1, guide/gm.tex: Expanded description
+ of the -affine option.
+
+2003-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (GetImageDepth): Re-implemented using a single-pass
+ algorithm and 1/2 the code. Previous implementation didn't return
+ correct results for Q:32 build. Now it does.
+
+ - magick/command.c (IdentifyImageCommand): For identify, when
+ %q format specifier is present, image must be read rather than
+ pinged. If not, either the value 8 is returned, or there is a
+ crash due to reading an uninitialized image.
+
+2003-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/mat.c: Incorporate fixes from Jaroslav Fojtik. Close
+ Blob before rotating image.
+
+ - PerlMagick/README.txt: Update to reflect that PerlMagick is
+ part of GraphicsMagick.
+
+ - PerlMagick/t/input.mat: Added test image for Matlab format.
+
+ - PerlMagick/t/input.wpg: Added test image for WordPerfect Graphics Format.
+
+ - utilities/Makefile.am (ALLMANPAGES): Install gm.1 rather than
+ old utility manual pages.
+
+2003-03-09 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - www/gm.html, utilities/gm.1, guide/gm.tex: First cut at
+ manpage for gm, to replace individual utility manpages.
+
+2003-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c: Fix some erroneous log printf specifications.
+ Improved blob log messages a bit.
+
+ - magick/log.c (IsEventLogging): Use InitializeLogInfo().
+ (InitializeLogInfo): New function to intelligently initialize
+ logging subsystem. Only locks when initialization may be required,
+ and only locks long enough to determine if initialization is required.
+ This approach should avoid deadlocking while logging from functions
+ used to initialize logging.
+ (IsLogAccessible): No longer need this duplicate of IsAccessible().
+ (SetLogEventMask): Use InitializeLogInfo().
+
+ - coders/fpx.c (ReadFPXImage): FlashPIX library does not support
+ BLOB I/O so don't use OpenBlob/CloseBlob. Opening the blob caused
+ a conflict when the FlashPIX library attempted to open the file.
+
+2003-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Test for libtiff functions (TIFFClientOpen &
+ TIFFIsByteSwapped), which are required by GraphicsMagick, but
+ not found in older libtiff versions.
+
+ - magick/blob.c: Added logging for Blob open/close and memory
+ mapping operations.
+
+2003-03-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwblob.c (main): DestroyImage asserts on NULL so only
+ call it for non-null image.
+
+ - tests/rwfile.c (main): DestroyImage asserts on NULL so only
+ call it for non-null image.
+
+2003-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwblob.c (main): Add -pause option to require keypress to
+ exit program. Clean-up to avoid any appearance of leaks.
+
+ - tests/rwfile.c (main): Add -pause option to require keypress to
+ exit program. Clean-up to avoid any appearance of leaks.
+
+ - magick/static.c (ExecuteStaticModuleProcess): Don't bind in
+ process filter functions for Visual C++ since the build environment
+ doesn't support it yet.
+
+ - magick/log.c (GetLogBlob) Code wasn't actually testing current
+ directory for log.mgk, now it does.
+
+ - magick/log.c (IsEventLogging): Eliminate accidental recursive, or
+ repeated, initialization of the logging system.
+
+2003-03-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (WriteJP2Image): Improved -quality rate estimation
+ for very small files.
+
+2003-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (WriteJP2Image): Add additional logging support.
+
+ - tests/rwblob.c: Added BLOB read/write logging.
+
+ - tests/rwfile.c: Added file read/write logging.
+
+ - magick/module.c (FindMagickModule): Minor code cleanup and limit
+ directory and file name lengths to sensible values.
+
+ - magick/utility.c (IsAccessible): Log test failures along with
+ test failure reason [strerror(errno)]. Also log test success.
+
+ - VisualMagick/bin/delegates.mgk: -DSAFER does not work with
+ Ghostscript 8.0.
+
+ - magick/module.c: Needed to conditionally include nt\_feature.h.
+
+2003-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/module.c (ExecuteModuleProcess): Updated to support locating
+ filter modules based on search rules.
+ (CoderInfo): Declare only in module.c since use is private to this
+ module.
+ (GetCoderInfo): Made static and commented out since currently unused.
+ (FindMagickModule): New function to search for a module.
+ (GetModuleBlob): Moved from blob.c, made static, and re-implemented
+ based on FindMagickModule.
+
+ - magick/blob.c: Moved GetTypeBlob() to type.c and made it static.
+ Moved GetModuleBlob() to module.c and made it static.
+
+2003-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/Makefile.am: MIFF module does not depend on -ljpeg, but
+ PNG module does (for JNG).
+
+ - filters/analyze.c (AnalyzeImage): Bugfix, image should be passed
+ as Image\*\* rather than Image\*.
+
+ - magick/utility.c (IsAccessible): Don't log errno if errno==0.
+
+2003-03-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/Makefile.am: Link with libFilters convenience library.
+
+ - VisualMagick/magick/magick\_config.h.in: Change MagickModulesPath
+ to MagickCoderModulesPath and add a MagickFilterModulesPath to
+ locate filter modules.
+
+ - filters/Makefile.am: New makefile to build filter modules.
+
+ - configure.ac: Configure magick/GraphicsMagick.pc and
+ Magick++/lib/GraphicsMagick++.pc.
+ (MagickModulesSubdir): Add quantum depth to modules path to ensure
+ that modules with the correct depth are loaded. The modules path
+ is now
+ ${libdir}/GraphicsMagick-${PACKAGE\_VERSION}/modules-Q${QuantumDepth}/coders.
+ (MagickCoderModulesPath): Rename MagickModulesPath to
+ MagickCoderModulesPath.
+ (MagickFilterModulesPath): Define to location of filter modules.
+
+ - magick/Makefile.am: Added rules to install GraphicsMagick.pc.
+
+ - magick/GraphicsMagick.pc.in: Added pkgconfig file for
+ -lGraphicsMagick.
+
+2003-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (WriteJP2Image): Quality factor calculation had
+ accidentally been removed. The calculation is back, but has been
+ biased up slightly so that a quality factor of 75 results in a
+ more reasonable 16:1 compression. Past a quality factor of 99.5,
+ the compression is set to 1:1 (non-lossy).
+
+2003-02-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Fixed bug with reading interlaced PNG images, introduced
+ yesterday.
+
+ - Fixed bug with skipping MNG subimages, also introduced
+ yesterday.
+
+2003-02-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (EXTRA\_DIST): Forgot to distribute version.sh
+
+ - configure.ac: Use definitions from version.sh to drive
+ package versioning and naming. These definitions support
+ libtool's recommended approach to library versioning.
+
+ - version.sh: New file for managing release versioning.
+ Edit this file to change the release number, etc.
+
+ - PerlMagick/t/tiff/read.t: Added read tests for stripped,
+ planar contiguous, and planar seperated TIFFs.
+
+ - coders/tiff.c (ReadTIFFImage): Transferred stripped-TIFF
+ reading code from ImageMagick.
+ Enumerated reading methods to make the logic more clear.
+
+2003-02-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - JNG alpha sample depth was sometimes inconsistent.
+
+ - Bring only one line at a time into memory during PNG
+ read/write (Merge with Cristy's 5.5.6 update).
+
+2003-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Makefile.PL.in (LIBS): Put MAGICKLIB first to
+ decrease the probability that the wrong libMagick is used
+ when linking static PerlMagick.
+
+ - configure.ac (PerlMagick): Fix linker search path for
+ -lGraphicsMagick when linking a static PerlMagick. It seems
+ that libtool changed the location where it places static
+ libraries.
+
+ - PerlMagick/t/tiff/read.t: Added test for reading tiled TIFF.
+
+ - coders/tiff.c (ReadTIFFImage): Add optimized support for
+ reading tiled TIFFs.
+ (ReadTIFFImage): Optimize loops for reading tiled TIFFs as well.
+ (ReadTIFFImage): Eliminate compiler warning.
+ (ReadTIFFImage): Add some missing error handling for tiled TIFF.
+
+2003-02-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Optimize RGBA transfer loop.
+
+2003-02-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawPrimitive): Return DrawPolygonPrimitive
+ status (edit transferred from ImageMagick).
+
+ - magick/utility.c (GetMagickGeometry): Scaling to an area now
+ preserves the image aspect ratio.
+
+2003-02-24 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - png.c: Added missing parentheses in typecast (cristy noticed
+ the bug that I introduced on 2/18).
+
+2003-02-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Add rules to produce www/README.html,
+ www/INSTALL-mac.html, www/INSTALL-unix.html, www/INSTALL-vms.html,
+ and www/INSTALL-windows.html
+
+ - www/README.html: New file produced from README.txt
+
+ - www/INSTALL-mac.html: New file produced from INSTALL-mac.txt.
+
+ - www/INSTALL-unix.html: New file produced from INSTALL-unix.txt.
+
+ - www/INSTALL-vms.html: New file produced from INSTALL-vms.txt.
+
+ - www/INSTALL-windows.html: New file produced from INSTALL-windows.txt.
+
+ - NEWS: Added news for GraphicsMagick 1.0.0.
+
+ - magick/locale.c: Added error messages to support JP2.
+
+ - locale/C.mgk: Added error messages to support JP2.
+
+ - locale/locale.mgk: Update to GraphicsMagick copyright.
+
+ - coders/jp2.c: Updated to use Jasper 1.700.1 interface
+ conventions. Jasper 1.700.1 is required now. Support
+ reading arbitrary quantum sizes up to 16-bits. Return
+ grayscale images as PseudoClass.
+
+ - jp2/: Updated Jasper sources to version 1.700.1.
+
+2003-02-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (ReadJP2Image): Obtain channel indexes by
+ ID rather than assuming index value. Validate that channel
+ geometry and encoding is supported.
+
+ - magick/effect.c (ThresholdImage): Additional performance
+ optimization. Work faster if image is already gray.
+
+2003-02-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (WriteJP2Image): Port to Jasper 1.7.
+ For Q:32, don't write 32-bit pixels rather than the
+ 16-bit pixels we told Jasper we would write.
+ (WriteJP2Image): Back-port to Jasper 1.6.
+
+2003-02-18 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/modules.mgk: Added JNG entry.
+
+2003-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (RegisterJP2Image): Added registration for
+ "PGX" magick tag.
+
+ - magick/magic.mgk: Added entry for JPEG V2's PGX format.
+
+ - PerlMagick/t/jp2/read.t: Added JPEG Version 2 read tests.
+
+ - coders/modules.mgk: Added JPC and PGX magick types to
+ support JPEG V2.
+
+ - magick/color.c (IsMonochromeImage): Re-arranged test logic
+ to short-circuit test using ORs.
+ (IsGrayImage): Re-arranged test logic to short-circuit test
+ using ORs.
+
+ - magick/constitute.c (PopImagePixels): Speed GrayQuantum
+ and GrayAlphaQuantum cases if is\_grayscale is True.
+
+ - magick/quantize.c (AssignImageColors): Sync image to
+ update DirectClass pixels to new colormap.
+
+ - coders/fpx.c (RegisterFPXImage): FlashPIX does not
+ provide direct BLOB I/O support.
+
+ - magick/blob.c (BlobToImage): Add logging.
+ (BlobToFile): Add logging.
+
+2003-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/fpx.c (ReadFPXImage): Removing the input file is
+ antisocial.
+
+ - PerlMagick/t/fpx/\*.fpx: Replaced with new copies. Files
+ seemed to be corrupt.
+
+ - PerlMagick/t/cgm/read.t: Specify file magick so that CGM
+ read test passes for BLOB case.
+
+ - PerlMagick/t/rad/read.t: Specify file magick so that RAD
+ read test passes for BLOB case.
+
+ - PerlMagick/t/jng/read.t: Add read tests for JNG.
+
+ - PerlMagick/t/jng/write.t: Add read/write tests for JNG.
+
+ - configure.ac (DELEGATES): Added `jng` to the DELEGATES list
+ so that JNG can be included in the PerlMagick tests.
+
+2003-02-18 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/png.c: Write proper JNG image\_interlace\_method.
+
+ - coders/png.c: Read and write proper MNG and JNG sRGB intent.
+
+ - PerlMagick/t/jng: Add twelve test files in JNG format.
+
+ - coders/png.c: Write proper progressive JNG output when
+ transparency is present.
+
+2003-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/version.c (GetMagickWebSite): New function.
+
+2003-02-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c (ipa\_device\_begin): Use MagickWebSite definition.
+
+ - www/Copyright.html: Updated to match Copyright.txt
+
+ - www/perl: Updated to reflect GraphicsMagick vs ImageMagick.
+
+ - magick/xwindow.c (XMakeImageMSBFirst): Minor loop optimizations.
+
+ - magick/constitute.c (ConstituteImage): Check for grayscale
+ and monochrome image if image is PseudoClass.
+
+2003-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/enhance.c (ContrastImage): Preserve is\_grayscale flag.
+ (EqualizeImage): Preserve is\_grayscale flag.
+ (ModulateImage): Preserve is\_grayscale flag.
+ (NegateImage): Preserve is\_grayscale flag.
+ (NormalizeImage): Preserve is\_grayscale flag.
+
+ - magick/fx.c (ColorizeImage): Evaluate is\_grayscale status.
+ (ConvolveImage): Preserve is\_grayscale flag.
+ (ImplodeImage): Preserve is\_grayscale flag.
+ (SolarizeImage): Preserve is\_grayscale flag.
+ (OilPaintImage): Preserve is\_grayscale flag.
+ (SwirlImage): Preserve is\_grayscale flag.
+ (WaveImage): Preserve is\_grayscale flag.
+
+ - magick/resize.c (MagnifyImage): Preserve is\_grayscale flag.
+ (MinifyImage): Preserve is\_grayscale flag.
+ (ResizeImage): Preserve is\_grayscale flag.
+
+ - magick/decorate.c (FrameImage): Evaluate is\_grayscale status.
+ (RaiseImage): Preserve is\_grayscale.
+
+ - magick/shear.c (IntegralRotateImage): Preserve is\_grayscale.
+ flag.
+ (XShearImage): Evaluate is\_grayscale status.
+ (YShearImage): Evaluate is\_grayscale status.
+
+ - magick/transform.c (ChopImage): Preserve is\_grayscale flag.
+ (CropImage): Preserve is\_grayscale flag.
+ (FlipImage): Preserve is\_grayscale flag.
+ (FlopImage): Preserve is\_grayscale flag.
+ (RollImage): Preserve is\_grayscale flag.
+
+ - magick/effect.c (AddNoiseImage): If image colorspace is
+ GRAYColorspace, then add intensity noise, and transfer
+ image is\_grayscale flag to output image.
+ (BlurImage): Preserve is\_grayscale flag.
+ (DespeckleImage): Preserve is\_grayscale flag.
+ (EdgeImage): Preserve is\_grayscale flag.
+ (EmbossImage): Preserve is\_grayscale flag.
+ (GaussianBlurImage): Preserve is\_grayscale flag.
+ (MotionBlurImage): Preserve is\_grayscale flag.
+ (ShadeImage): Preserve is\_grayscale flag.
+ (SharpenImage): Preserve is\_grayscale flag.
+ (UnsharpMaskImage): Preserve is\_grayscale flag.
+
+ - magick/quantize.c (QuantizeImage): Pre-reduce gray images
+ to PseudoClass in order to quickly determine the number of
+ colors, and provide the expected PseudoClass output. Also
+ skip slow color quantization if there are already fewer
+ colors than requested.
+
+ - magick/image.c (GrayscalePseudoClassImage): New function
+ to quickly reduce an image to PseudoClass grayscale. This
+ is a fast way to determine the number of intensities in a
+ grayscale image. Either a compact sorted colormap or a faster,
+ contiguous linear colormap is created, depending on the
+ optimize\_colormap flag. If the image is already PseudoClass,
+ and the optimize\_colormap flag is True, then the existing
+ colormap is sorted and reduced.
+ (SyncImage): Preserve is\_grayscale flag.
+ (ChannelImage): Result is grayscale.
+ (CycleColormapImage): Preserve is\_grayscale and is\_monochrome flags.
+ (SetImage): Evaluate is\_grayscale flag.
+ (SetImageDepth): Preserve is\_grayscale flag.
+ (SetImageOpacity): Preserve is\_grayscale flag.
+ (SortColormapByIntensity): Preserve is\_grayscale flag.
+ (TransformRGBImage): Evaluate is\_grayscale flag.
+
+2003-02-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resize.c (SampleImage): Preserve grayscale and
+ monochrome flags.
+
+ - magick/quantize.c (AssignImageColors): Set image monochrome
+ flag to True when quantizing to two colors in GrayColorspace.
+
+ - magick/effect.c (SpreadImage): Preserve grayscale and
+ monochrome flags.
+ (AdaptiveThresholdImage): Short-circuit algorithm if image
+ flags indicate it is already monochrome. Set monochrome and
+ grayscale flags once algorithm completes.
+ (ThresholdImage): Short-circuit algorithm if image
+ flags indicate it is already monochrome. Set monochrome and
+ grayscale flags once algorithm completes.
+ (ChannelThresholdImage): Short-circuit algorithm if image
+ flags indicate it is already monochrome. Set monochrome and
+ grayscale flags once algorithm completes.
+ (ShadeImage): If grayscale shading is done, then set image
+ grayscale flag to True.
+
+ - magick/color.c (IsGrayImage): If the image is\_grayscale
+ flag is True, then short-circuit the test. Update the flag
+ if the test is performed.
+ (IsMonochromeImage): If the image is\_monochrome flag is True
+ then short-circuit the test. Update the flag if the test is
+ performed.
+
+ - magick/image.c (CloneImage): Copy image is\_grayscale and
+ is\_monochrome members.
+
+ - magick/cache.c (SyncCacheNexus): If image pixels are updated
+ then set image is\_grayscale and is\_monochrome members to False.
+ Algorithms which want to preserve the values of these members
+ should save their original values before processing the image
+ and restore them when processing is complete, or transfer them
+ from the input image to the output image.
+
+ - magick/constitute.c (ReadImage): If the returned image is
+ PseudoClass then invoke IsGrayImage() and IsMonochromeImage()
+ and cache the result in image is\_grayscale and is\_monochrome
+ members for later use.
+
+ - magick/image.h (Image): Added is\_grayscale and is\_monochrome
+ members to remember if image is grayscale or monochrome.
+
+2003-02-14 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - www/archives.html: commented out sites not mirroring GM yet.
+ Changed "ftp.simplesystems.org" to "ftp.graphicsmagick.org".
+ Added link to graphicsmagick.sf.net.
+
+2003-02-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (FormatString): Check for the availability of
+ vsprintf.
+
+ - magick/log.c (LogMagickEvent): Check for the availability of
+ vsprintf.
+
+ - configure.ac: Test for vsprintf.
+
+2003-02-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/annotate.c (RenderFreetype): Used smarter code to prepare
+ the beta argument for AlphaComposite.
+
+2003-02-12 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/logo.c: updated logo.c to produce the GraphicsMagick logo.
+
+2003-02-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - INSTALL-unix.txt: Document that default quantum depth is now 8.
+
+ - VisualMagick/magick/magick\_config.h.in: Default quantum depth is now 8.
+
+ - configure.ac: Default quantum depth is now 8.
+
+ - tests/Makefile.am: Test format types that require a size
+ seperately since always specifying the size caused some formats
+ (e.g. PCD) to improperly fail.
+
+2003-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/NEWS.html: New HTML file for project news.
+
+ - scripts/txt2html: New script for formatting text into HTML.
+
+ - Makefile.am: Automated the generation of www/Changelog.html and
+ www/NEWS.html.
+
+ - coders/xpm.c (WritePICONImage): Close blob using correct image.
+
+ - tests/Makefile.am (CHECK\_SIZED\_FILES): Added files to tests
+ subdirectory so that tests don't need to use files from
+ PerlMagick.
+
+ - magick/image.c (TransformColorspace): New function to
+ simplify/centralize colorspace transform requests. Replaced calls
+ to RGBTransformImage and TransformRGBImage throughout the code
+ with calls to TransformColorspace.
+
+ - IMDisplay: Disable save function since it is not implemented yet.
+
+2003-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs (SetAttribute): Support changing back to
+ RGB or Transparent colorspace.
+
+2003-02-10 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Brought MNG handling of final delay into compliance with MNG spec.
+
+2003-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c (WriteBMPImage): Added support for
+ bits\_per\_pixel==4.
+ (WriteBMPImage): Convert PseudoClass images with more than 256
+ colors to DirectClass.
+ (WriteBMPImage): Do not require 2-color images to pass the
+ IsMonochromeImage() test before writing them as one-bit-per-pixel
+ BMPs. Decided to allow this after four readers (including Windows
+ XP) displayed the image using the proper colormap.
+ (WriteBMPImage): BMP2 encoder was writing colormap using wrong format.
+
+ - images: Updated logo images to GraphicsMagick
+
+ - Added PDF Sages to web page as a sponsor.
+
+2003-02-08 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - www/GraphicsMagick.html: add "gm " prefix to examples.
+
+2003-02-07 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - index.html: Update to distinguish between ImageMagick and
+ GraphicsMagick, and to explain "gm" prefix of commandline utilities.
+
+2003-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_feature.c (CropImageToHBITMAP): Remove useless
+ autocrop support which was transferred from CropImage when
+ creating CropImageToHBITMAP.
+
+2003-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): RLE packet size was not
+ calculated correctly, causing RLE-compressed MIFF images with
+ depth>8 to not be read.
+
+2003-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/paint.c (ColorFloodfillImage): Transfered fix from
+ ImageMagick for the problem that floodfill using a tiled image
+ failed if the target color happened to match the current fill
+ color.
+
+2003-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Fixed preview error message.
+
+ - coders/preview.c: Previous update had broken noiseimage demo.
+ Also some cleanups.
+
+ - magick/display.c (XMagickCommand): No longer uses
+ MogrifyImage.
+
+ - coders/preview.c (WritePreviewImage): Re-wrote so that
+ MogrifyImage is no longer used. Resize image outside of the loop
+ to improve performance.
+
+2003-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ShadeImage): Use PixelIntensityToDouble macro.
+
+ - magick/image.h (PixelIntensityToDouble): Added
+ PixelIntensityToDouble macro to handle the case where pixel
+ intensity is used for floating arithmetic.
+
+2003-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Distribute files ChangeLog, INSTALL-mac.txt,
+ INSTALL-unix.txt, INSTALL-vms.txt INSTALL-windows.txt, and NEWS.
+
+2003-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/svg.c (SVGStartElement): Applied fix from ImageMagick to
+ compute SVG +> MVG viewbox correctly.
+
+ - magick/image.c (CloneImage): Applied fix from ImageMagick which
+ is purported to solve the problem that "negative (x,y) page offsets
+ did not clone properly".
+
+ - magick/gem.c (TransformHWB): Replace implementation with
+ ImageMagick's new version which is supposed to fix a rounding
+ error problem. Hard to say since implementation is totally
+ different.
+
+ - coders/msl.c (MSLStartElement): Applied fix for missing break
+ from ImageMagick.
+
+ - magick/integral\_types.h: New header to include the integral
+ types typedefs. Needed new header in order to include in both
+ studio.h and api.h at the right point.
+
+ - magick/studio.h: Move nt\_feature.h inclusion to the few modules
+ which actually use functions from it.
+
+ - magick/api.h: Added typedefs gm\_int16\_t, gm\_uint16\_t,
+ gm\_int32\_t, gm\_uint32\_t, gm\_int64\_t, gm\_uint64\_t to support
+ specifically sized types.
+
+ - configure.ac: Test for size of `short`, `unsigned short`, `int`,
+ `unsigned int`, `long`, `unsigned long`, `long long`, `unsigned
+ long long` assigning the result to the defines SIZEOF\_SHORT,
+ SIZEOF\_UNSIGNED\_SHORT, SIZEOF\_INT, SIZEOF\_UNSIGNED\_INT,
+ SIZEOF\_LONG, SIZEOF\_UNSIGNED\_LONG, SIZEOF\_LONG\_LONG, and
+ SIZEOF\_UNSIGNED\_LONG\_LONG respectively.
+
+2003-01-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/fx.c (OilPaintImage): Compute histogram using 8-bit quantums
+ for more sensible performance with Q:16 and Q:32 builds.
+
+ - magick/image.h (PixelIntensityToQuantum): Compute using integral
+ arithmetic for Q:8 and Q:16. Much faster than floating point!
+ (PixelIntensity): Compute using integral arithmetic for Q:8 and
+ Q:16. Much faster than floating point!
+
+2003-01-28 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - Fixed bug in png.c, introduced in IM-5.5.1. A pair of
+ { } brackets were omitted when logging was added, which lets
+ old versions of libpng write a zero-length iCCP chunk.
+
+2003-01-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (DespeckleImage): Put loops inside of case
+ statement rather than outside.
+ (SpreadImage): Improved algorithm so that -spread is 12X faster.
+
+ - magick/nt\_feature.c (CropImageToHBITMAP): New function to return
+ a region of the image as a HBITMAP.
+
+2003-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fixed Copyright statement on all source files.
+
+ - magick/effect.c (ThresholdImage): Optimized loop.
+
+ - coders/tiff.c (ReadTIFFImage): Read bits more efficiently for
+ bits\_per\_sample=1.
+
+ - magick/command.c (MogrifyImage): Set image->dither to
+ image\_info->dither prior to invoking SetImageType.
+
+ - magick/constitute.c (WriteImage): Set image->dither to
+ image\_info->dither.
+
+ - magick/image.c (SetImageType): For case BilevelType, normalize
+ image, and threshold 50% if dithering is disabled. This is at
+ least 10X faster than quantizing with dither.
+ (AllocateImage): Initialize image->dither.
+ (CloneImage): Copy image->dither.
+
+ - magick/image.h: Added dither member to Image.
+
+2003-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/tiff/read.t: Added a test for reading 16-bit TIFF
+ images.
+
+ - coders/tiff.c (ReadTIFFImage): Support reading 16-bit TIFF images
+ with a Q:8 build.
+
+ - magick/color.c (ConstrainColormapIndex): Use VerifyColormapIndex.
+
+ - coders/pnm.c (ReadPNMImage): Use VerifyColormapIndex.
+
+ - coders/gif.c (DecodeImage): Use VerifyColormapIndex.
+
+ - magick/image.c (SyncImage): Use VerifyColormapIndex.
+
+2003-01-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (ReadBlobByte): Use getc when reading from FILE stream.
+
+ - configure.ac: Added tests for getc\_unlocked and putc\_unlocked.
+
+ - magick/blob.c (ReadBlobByte): Optimized reading from BlobStream.
+ (ReadBlobLSBLong): Optimized reading from BlobStream.
+ (ReadBlobLSBShort): Optimized reading from BlobStream.
+ (ReadBlobMSBLong): Optimized reading from BlobStream.
+ (ReadBlobMSBShort): Optimized reading from BlobStream.
+ (ReadBlobStream): New static inline function to read from BlobStream.
+ (WriteBlob): "Manually" copy data rather than using memcpy() for
+ very small copy sizes.
+ (WriteBlobByte): Use putc() when writing to a FILE stream.
+
+2003-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/gem.c (Hull): Count down loops. Might help.
+ (InterpolateColor): Pre-compute common sub-expressions to improve
+ performance.
+
+ - magick/segment.c (Classify): Implemented idea from Glenn
+ Randers-Pehrson to avoid use of pow() when WeightingExponent is
+ 2.0 (which it is). This makes image segmentation much faster
+ (e.g. 8X).
+
+ - magick/annotate.c (RenderFreetype): For images with
+ matte==False, simply set the opacity of the pixel to be updated to
+ OpaqueOpacity before alpha-compositing the pixel rather than using
+ SetImageType(TrueColorMatteType) to initialize the opacity of the
+ entire image. This is much faster and scales to large images.
+
+ - magick/image.c (SetImageType): Eliminated unnecessary conditionals.
+
+2003-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (InsertMedianList): Assign computed quantum
+ indexes to variables to avoid extra computations for
+ QuantumDepth>8.
+
+ - magick/composite.c (AlphaComposite): Pre-compute common
+ expressions in order to improve performance.
+
+ - magick/fx.c (ConvolveImage): Optimized loops.
+
+ - magick/paint.c (TransparentImage): Optimize for case fuzz == 0.
+
+ - magick/color.c (FuzzyColorMatch): Minor cleanup and optimization.
+
+ - magick/locale.c: Added error messages for convolve option.
+
+ - coders/locale.c: Picked up recent changes from ImageMagick version.
+
+ - locale/C.mgk: Added error messages for convolve option.
+
+ - magick/command.c (MogrifyImage): Added support for convolve option.
+
+ - coders/xcf.c (ReadXCFImage): Recognize latest GIMP XCF header.
+
+ - coders/dcm.c: Transferred the apparent salient fixes from
+ ImageMagick for a bug described as "Some DCM grayscale images did
+ not display correctly.".
+
+ - coders/miff.c (ReadMIFFImage): Reading RLE-compressed MIFFs is
+ now about 4X faster.
+
+ - magick/blob.c (OpenBlob): Use setvbuf() to increase stdio buffer
+ size to 16K. Solaris default is 1K. This should minimize system
+ call overhead for accessing large files.
+ (ReadBlob): "Manually" copy data rather than using memcpy() for
+ very small copy sizes.
+ (ReadBlobZC): New method, similar to ReadBlob, but provides the
+ opportunity for zero copy on read.
+
+ - magick/constitute.c (PushImagePixels): CMYKA case for
+ image->depth=16 was comparing with 8 instead.
+
+2003-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetMagickGeometry): Removed support for `~`
+ and disabled centering code until we learn where it should go (if
+ anywhere).
+
+ - magick/command.c : Add HWB colorspace transform support.
+
+ - PerlMagick/Magick.xs: Add HWB colorspace transform support.
+
+ - magick/image.c (RGBTransformImage): Add HWB colorspace transform
+ support.
+ (TransformRGBImage): Add HWB colorspace transform support.
+
+2003-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetMagickGeometry): Add support for new new
+ `~` geometry string flag. This also fixes a montage bug in which
+ thumbnails were mis-sized if the geometry specification incuded x
+ or y offsets.
+
+ - magick/image.h (GeometryFlags): Added CenterValue enumeration to
+ correspond with new `~` geometry string flag. Taking
+ ImageMagick's lead on this.
+
+ - magick/render.c: Transferred fixes from ImageMagick for an
+ artifact which occured at the 360 degree point when rendering
+ circles, ellipses, and arcs. Bug reported by io219@attbi.com.
+
+ - PerlMagick/Magick.xs: Add HSL colorspace transform support.
+
+ - magick/command.c: Add HSL colorspace transform support.
+
+ - magick/image.c (RGBTransformImage): Add HSL colorspace transform
+ support.
+ (TransformRGBImage): Add HSL colorspace transform support.
+
+2003-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated copyright statement on source files to reflect
+ the GraphicsMagick Group rather than ImageMagick Studio.
+
+ - magick/constitute.c (ConstituteImage): Simplified the switch
+ statement for inner loops by creating a simplified map in advance.
+ (DispatchImage): Simplified the switch statement for inner loops
+ by creating a simplified map in advance.
+
+ - magick/compress.c (HuffmanEncodeImage): Test and cache the
+ return value of LocaleCompare(image\_info->magick,"FAX") so that
+ LocaleCompare is not executed repeatedly in the output loop.
+
+ - magick/color.c (IsGrayImage): Optimized loops.
+ (IsMonochromeImage): Optimized loops.
+ (IsOpaqueImage): Optimized loop.
+
+ - magick/delegate.c (InvokePostscriptDelegate): When using the
+ Ghostscript library, identify the library as "[ghostscript library]"
+ rather then "gsdll32" so that -verbose prints something useful for
+ both Windows and Unix.
+
+2003-01-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS: New file.
+
+ - magick/montage.c (MontageImages): Use ThumbnailImage() rather
+ than ZoomImage() to resize montage thumbnails provided that the
+ user has not specified an image filter, and the montage thumbnail
+ is smaller than the image. This should provide faster montages
+ for large images.
+
+ - magick/resize.c (ResizeImage): Added logging support.
+ (MagnifyImage): Added logging support.
+ (MinifyImage): Added logging support.
+ (SampleImage): Added logging support.
+ (ScaleImage): Added logging support.
+
+2003-01-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/transform.c (ProfileImage): Duplicate ImageMagick changes
+ to image colorspace handling. Avoids using
+ SetImageType(image,ColorSeparationMatteType).
+
+ - magick/fx.c (OilPaintImage): Replaced with ImageMagick version
+ since ImageMagick version has been updated to not penalize Q:8.
+ Optimized loops.
+
+ - magick/display.c (XDisplayImage): Display to 100% of
+ the screen size rather than 90% of the screen size.
+
+ - magick/enhance.c (ModulateImage): Ensure that arguments
+ are always positive values. Optimized loops.
+ (ContrastImage): Optimized loops.
+
+ - magick/gem.c (HSLTransform): Optimized performance by
+ eliminating redundant intermediate calculations. This
+ makes `gm convert -contrast` 21% faster.
+ (HSLTransform): Set to inline within the gem.c module.
+ (TransformHSL): Set to inline within the gem.c module.
+ (Contrast): Moved to bottom of gem.c module so HSLTransform
+ and TransformHSL can be inlined. Simplified conditionals.
+ (Modulate): Moved to bottom of gem.c module so HSLTransform
+ and TransformHSL can be inlined. No longer check/correct
+ negative values.
+
+2003-01-14 William Radcliffe <billr@corbis.com>
+
+ - magick/blob.c
+
+ - magick/blob.h
+ Added new stream type flag and support to match with the one
+ added to ImageMagick.
+
+2003-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (RGBTransformImage): Fixed bug (thanks to
+ Bill for finding it) and finished optimizing XYZ table
+ creation.
+ (AverageImages): Optimized loops.
+ (ChannelImage): Optimized loops. 3X speed-up for SPARC.
+
+ - magick/enhance.c: Optimized NegateImage().
+
+2003-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Set some common API structures to 0xbf prior to deallocation
+ to make accidental continued use more obvious.
+
+2003-01-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c: Minor optimizations to PopImagePixels()
+
+ - coders/dpx.c: Reading the DPX header was off by 4 bytes.
+
+ - coders/(art.c,avs.c,bmp.c,cmyk.c,dcm.c,dib.c,dpx.c,fax.c,
+ fits.c,gray.c,icon.c,map.c,miff.c,mono.c,mpc.c,mtv.c,otb.c,
+ pcx.c,pdb.c,pict.c,pix.c,pnm.c,pwp.c,rgb.c,rla.c,rle.c,sct.c,
+ sgi.c,sun.c,tga.c,tim.c,uyvy.c,vicar.c,viff.c,wbmp.c,xwd.c,
+ yuv.c): Ensure that blob is closed on unexpected EOF.
+
+ - magick/image.c: Optimized SetImageOpacity().
+ Optimized SetImage() for intializing non-opaque images. The
+ opacity channel was being intialized twice.
+
+2003-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c: Log entry and exit from coders so that
+ coders don't need to.
+
+ - Finished re-writing PushImagePixels() using coding practices
+ which may result in faster code.
+
+ - PerlMagick is changed from Image::Magick to Graphics::Magick
+ in order to avoid conflicts with the ImageMagick version. This
+ means that any Perl scripts based on the ImageMagick version need
+ to do a global replace of Image::Magick to Graphics::Magick.
+
+ - PerlMagick/reference/filter/Raise.miff: Replaced with new version.
+
+2003-01-08 William Radcliffe <billr@corbis.com>
+
+ - magick/nt\_feature.c
+ Make ImageToHBITMAP function in nt\_feature.c compile under Visual
+ C++ again.
+
+2003-01-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/delegates.mgk.in: Fix cgm entry. How did it become so
+ terribly broken?
+
+ - coders/dps.c: Adding logging support.
+
+ - PerlMagick/t/read.t: Changed file read tests to use image
+ compares with a reference image rather than comparing with a
+ signature.
+
+ - PerlMagick/t/wmf/read.t: Ditto.
+ magick/shear.c: Fixed documentation for RotateImage.
+
+2003-01-08 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/magick.c, magick/magick.h: Add "note" member of magick\_info.
+
+ - coders/art.c, coders/fax.c, coders/dcm.c, coders/png.c: add notes
+ to format registrations.
+
+ - fx.c: changed default "colorize" behaviour to preserve image opacity.
+
+2003-01-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/svg.c: Allow the user to specify the initial background
+ color via the -background option. This is only useful if the SVG
+ doesn't draw its own background rectangle.
+
+2003-01-06 Albert Chin-A-Young <china@thewrittenword.com>
+
+ - ltdl/Makefile.am, ltdl/ltdl.c: Fix compilation problem
+ under Tru64 UNIX 5.1. The GraphicsMagick random.h was being
+ included when the system random.h was needed.
+
+ - configure.ac: Improve robustness of POSIX thread API tests
+ by including pthread.h when building the test program.
+
+2003-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c: In IsImagesEqual() only use type `long double`
+ for error summation if QuantumDepth > 16 and `long double` has
+ more range than `double`.
+
+ - magick/quantize.c: In QuantizeImage() only use type `long
+ double` for error summation if QuantumDepth > 16 and `long
+ double` has more range than `double`.
+
+ - Replaced redundant code with macros.
+
+ - Optimize mapping to monochrome.
+
+ - utilities/conjure.c: Had missed removing this file earlier.
+
+2003-01-04 Derry Bryson <dbryson@techass.com>
+
+ - magick/decorate.c: Use the ShadowFactor rather than ShadowModule
+ define in RaiseImage() (bug-fix).
+
diff --git a/www/ChangeLog-2004.html b/www/ChangeLog-2004.html
new file mode 100644
index 0000000..b56083b
--- /dev/null
+++ b/www/ChangeLog-2004.html
@@ -0,0 +1,1608 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2004-12-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (DescribeImage): Add normalized channel
+statistics to output.</li>
+<li>NEWS: Updated with changes since July.</li>
+<li>magick/constitute.c (ImportImagePixelArea): For GrayQuantum,
+GrayInvertedQuantum, GrayAlphaQuantum, and
+GrayInvertedAlphaQuantum, observe image storage_class so that a
+gray DirectClass image may be created.</li>
+<li>coders/tiff.c (ReadTIFFImage): Fix overflow when computing
+colormap size for bits-per-sample of 32.
+(WriteTIFFImage): Support writing 32-bit RGB(A) for
+QuantumDepth=32 build.
+(ReadTIFFImage): Support reading 32-bit RGB(A) for QuantumDepth=32
+build. Support reading 32-bit grayscale without any quality loss
+for QuantumDepth=32 build.</li>
+</ul>
+</blockquote>
+<p>2004-12-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): TrueColor 16-bits/sample RGB
+images were being written incorrectly on little-endian CPUs.
+Added byte swapping to fix this problem.</li>
+</ul>
+</blockquote>
+<p>2004-12-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/operator.c: New file for quantum operator implementation.
+(QuantumOperatorImage): Moved from image.c.
+(QuantumOperatorRegionImage): Moved from from image.c.</li>
+</ul>
+</blockquote>
+<p>2004-12-22 Ralf Wildenhues &lt;<a class="reference external" href="mailto:Ralf&#46;Wildenhues&#37;&#52;&#48;gmx&#46;de">Ralf<span>&#46;</span>Wildenhues<span>&#64;</span>gmx<span>&#46;</span>de</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/Makefile.am (MAGICK_BASE_SRCS): Remove mention of
+non-existent mmath.h.</li>
+<li>configure.ac: AC_LIBTOOL_SETUP is an internal macro and must not
+be used externally (will be pulled in automatically).</li>
+<li>PerlMagick/Makefile.am: Missing file needed to be committed to CVS.</li>
+<li>tests/Makefile.am (TESTS_TIFF_XFAIL_TESTS): EPT and PTIF tests
+are expected to fail if libtiff is missing.</li>
+</ul>
+</blockquote>
+<p>2004-12-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>TODO.txt: Organized todo list for 1.2 release.</li>
+</ul>
+</blockquote>
+<p>2004-12-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (WriteBMPImage): Handle the case where the image
+has an over-sized colormap. Was writing on unallocated heap memory.</li>
+<li>coders/dib.c (WriteDIBImage): Handle the case where the image
+has an over-sized colormap. Was writing on unallocated heap memory.</li>
+</ul>
+</blockquote>
+<p>2004-12-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/gem.c (Modulate): Hue argument now represents a rotation
+from -180 degrees to +180 degrees expressed as an argument of 0 to
+2.0 (1.0 for no change). Note that this change also effects the
+-modulate argument and the Magick++ modulate method(). This change
+is made because the previous hue adjustment strategy only
+succeeded in corrupting the image.</li>
+</ul>
+</blockquote>
+<p>2004-12-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (opendir): Ensure that data may not overwrite
+the stack.
+(readdir): Ensure that data may not overwrite the stack.</li>
+<li>magick/blob.c (ImageToBlob): Ensure that image-&gt;logging is
+set prior to encoding image.</li>
+<li>magick/constitute.c (WriteImage): Ensure that image-&gt;logging is
+set prior to encoding image.</li>
+</ul>
+</blockquote>
+<p>2004-11-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>rungm.sh.in: Compute final variable definitions from within
+configure in order to improve MinGW test execution times.</li>
+</ul>
+</blockquote>
+<p>2004-11-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gif.c: Fix two error-path memory leaks which were noticed
+by Glenn Randers-Pehrson.</li>
+</ul>
+</blockquote>
+<p>2004-11-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (UnregisterPNGImage): Eliminate Warning: module
+registration for &quot;JNG&quot; from module &quot;PNG&quot; still present!</li>
+</ul>
+</blockquote>
+<p>2004-11-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (DispatchImage): Fix documentation error
+regarding return status.</li>
+</ul>
+</blockquote>
+<p>2004-11-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.h: Only define HAVE_GLOBALMEMORYSTATUSEX for MSVC
+7.0 and later.</li>
+</ul>
+</blockquote>
+<p>2004-11-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Ensure that words in the
+scanline are converted to little-endian format on little-endian
+CPUs.</li>
+</ul>
+</blockquote>
+<p>2004-11-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (MagickStrlCat): New function which is
+equivalent to to OpenBSD's strlcat() function. Concatenates one
+string onto another within a fixed size buffer while ensuring null
+termination.
+(MagickStrlCpy): New function which is equivalent to OpenBSD's
+strlcpy() function. Copies a string into a fixed size buffer
+while ensuring null termination.</li>
+<li>coders/gif.c (DecodeImage): Improve handling of corrupt GIF
+files. Resolves SourceForge bug #1042904. Also, eliminate a
+potential memory leak.</li>
+<li>magick/constitute.c (WriteImages): ImageInfo argument is now a
+const pointer.</li>
+</ul>
+</blockquote>
+<p>2004-10-26 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (TracePath): Applied bugfix from Cristy.</li>
+</ul>
+</blockquote>
+<p>2004-10-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (InitializeMagickResources): Use
+GlobalMemoryStatusEx if it is available.</li>
+<li>magick/nt_base.c (lt_dlopen): Handle errors while loading
+modules rather than allow Windows to display a GUI dialog box.
+(NTKernelAPISupported): New function to support testing to see if
+a Windows kernel API is supported.</li>
+<li>magick/constitute.c (ExportImagePixelArea): Add special-case for
+bilevel gray image in order to restore performance.
+(ImportImagePixelArea): Add special-case for bilevel gray image in
+order to restore performance.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Fix GCC warning about variable
+being clobbered by longjmp.</li>
+<li>Re-port build to MinGW. Modules build passes all tests.</li>
+<li>Skip build and install of modules if a key library is not available.</li>
+<li>Partial recode of metadata handling to use Get/Set profile
+functions. Big job!</li>
+<li>GCC warnings reduction.</li>
+<li>Remove MVG detection from magic.mgk due to security risk.</li>
+</ul>
+</blockquote>
+<p>2004-09-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Properly detect and handle
+errors reported by libtiff so that failure is reported rather than
+writing a corrupted output file.
+(WriteNewsProfile): Re-write so implementation is easier to
+understand.</li>
+</ul>
+</blockquote>
+<p>2004-09-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c: Don't use deprecated tiff.h _SUPPORT defines.
+Support retrieving and saving XMP profile. Use profile set/get
+methods in implementation.</li>
+<li>coders/mat.c,coders/topol.c (ReadBlobWordLSB,ReadBlobDoublesLSB):
+Use better variable name than <cite>I</cite> for image.</li>
+</ul>
+</blockquote>
+<p>2004-09-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (WriteMIFFImage): Ensure that MIFF files are never
+written with bogus compression values.</li>
+<li>magick/image.h: Protected/hid constants which only exist to
+support the library implementation.</li>
+<li>tests/Makefile.am (TESTS_X11_XFAIL_TESTS): Fixed syntax error.</li>
+<li>Makefile.am: Use one Makefile to rule them all as described in
+Peter Miller's excellent paper, Recursive Make Considered Harmful,
+&quot;<a class="reference external" href="http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html">http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html</a>&quot;.
+Some glitches may remain.</li>
+<li>coders/tiff.c (TIFFErrors): Prevent possible stack overflow on
+error.
+(TIFFWarnings): Prevent possible stack overflow on error.</li>
+<li>magick/constitute.c (ImportImagePixelArea): For RGBQuantum
+initialize the opacity channel since it is easier than altering
+all code to properly access it.</li>
+</ul>
+</blockquote>
+<p>2004-09-02 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/transform.c: Bugfix from Cristy in CoalesceImages().</li>
+</ul>
+</blockquote>
+<p>2004-08-26 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Avoid error introduced in libpng-1.2.6 that causes the encoder
+to write out-of-spec zlib header bytes.</li>
+</ul>
+</blockquote>
+<p>2004-08-24 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c is said to have a potential buffer overrun.
+Patch from Cristy applied (also to avi.c and dib.c).</li>
+</ul>
+</blockquote>
+<p>2004-08-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Use ExportImagePixelArea to
+write grayscale and colormapped output.</li>
+<li>magick/constitute.c (ImportImagePixelArea): Implemented support
+for GrayInvertedQuantum &amp; GrayInvertedAlphaQuantum.
+(ExportImagePixelArea): Implemented support for
+GrayInvertedQuantum &amp; GrayInvertedAlphaQuantum.</li>
+<li>magick/constitute.h (enum QuantumType): Added
+GrayInvertedQuantum &amp; GrayInvertedAlphaQuantum to support
+min-is-white gray images.</li>
+</ul>
+</blockquote>
+<p>2004-08-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/tiff/write.t: Adjusted file naming.</li>
+<li>PerlMagick/t/tiff/read.t: Added more tests.</li>
+<li>coders/tiff.c (ReadTIFFImage): Use ImportImagePixelArea to read
+PseudoClass tiff.
+(WriteTIFFImage): Allow user to set the bits-per-sample define to
+any value in the range of 1 to 32.
+(ReadTIFFImage): Fix endian-reordering for DirectClass read and
+bits-per-sample values ranging 9-15.</li>
+<li>coders/rgb.c: Support reading &amp; writing 32-bit depths for raw
+RGB images.</li>
+<li>coders/cmyk.c: Support reading &amp; writing 32-bit depths for raw CMYK
+images.</li>
+<li>coders/gray.c: Support reading &amp; writing 32-bit depths for raw gray
+images.</li>
+<li>magick/deprecate.c (PopImagePixels): Deprecated function.
+(PushImagePixels): Deprecated function.</li>
+<li>magick/constitute.c (ExportImagePixelArea): New function to
+export pixel region using specified QuantumType and
+bits-per-sample.
+(ImportImagePixelArea): New function to import pixel region using
+specified QuantumType and bits-per-sample.</li>
+</ul>
+</blockquote>
+<p>2004-08-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cache.c (ClonePixelCache): It appeared that cloning a
+disk-based pixel cache was limited to the maximum value of
+size_t. This would result in a truncated cache. The offset type
+is changed from size_t to magick_off_t in order to avoid this.</li>
+<li>configure.ac: Check to see if the <cite>char</cite> type is unsigned,
+mostly out of curiosity since the code does not currently make use
+of the result.</li>
+<li>Fixed many compilation warnings when the compiler warning level
+is set as high as possible.</li>
+<li>configure.ac: Check /usr/share/ghostscript/fonts for Ghostscript Type1
+fonts.</li>
+</ul>
+</blockquote>
+<p>2004-08-13 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tEXt and zTXt were inadvertently included in list of unused chunks.</li>
+</ul>
+</blockquote>
+<p>2004-08-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>fix incorrect argument to png_set_keep_unknown_chunks().</li>
+</ul>
+</blockquote>
+<p>2004-08-07 David R. Linn &lt;<a class="reference external" href="mailto:drl&#37;&#52;&#48;vuse&#46;vanderbilt&#46;edu">drl<span>&#64;</span>vuse<span>&#46;</span>vanderbilt<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/formats.html: Titles for JNG and MNG were reversed.</li>
+</ul>
+</blockquote>
+<p>2004-08-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/widget.c (XCommandWidget): Replace ImageMagick logo in
+display command menu with GraphicsMagick logo.</li>
+</ul>
+</blockquote>
+<p>2004-08-05 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Fixes for CERT security alert TA04-217A described
+at &quot;<a class="reference external" href="http://www.us-cert.gov/cas/techalerts/TA04-217A.html">http://www.us-cert.gov/cas/techalerts/TA04-217A.html</a>&quot;.</li>
+</ul>
+</blockquote>
+<p>2004-08-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h (Image): Changed type of <cite>colors</cite> and <cite>depth</cite>
+members from type <cite>unsigned long</cite> to <cite>unsigned int</cite>. This change
+is made because on 64-bit CPUs, <cite>unsigned long</cite> is a 64-bit
+type. The depth member is often used in switch statements. It is
+not recommended to use 64-bit types in switch statements. The
+maximum number of colors in the colormap is limited to 64K so a
+64-bit type is not required.</li>
+</ul>
+</blockquote>
+<p>2004-08-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Restore previous 8/16
+bits-per-sample support code in order to regain lost performance.</li>
+</ul>
+</blockquote>
+<p>2004-07-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Support reading RGB/CMYK scanline
+oriented TIFF images with arbitrary depth.</li>
+</ul>
+</blockquote>
+<p>2004-07-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Update to Automake 1.9.</li>
+</ul>
+</blockquote>
+<p>2004-07-20 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagickmagickGM_magick.bpr: Updated to reflect changes since last update.</li>
+<li>BCBMagickmagicklibMagick.bpr: Updated to reflect changes since last update.</li>
+<li>BCBMagickbzlibGM_bzlib.bpr: Updated version number.</li>
+<li>BCBMagicklcmsBCB6GM_lcms.bpr: Updated version number.</li>
+<li>BCBMagickMagickpplibGM_magickpp.bpr: Updated version number.</li>
+<li>BCBMagickttfGM_ttf.bpr: Updated version number.</li>
+<li>BCBMagickzlibGM_zlib.bpr: Updated version number.</li>
+<li>BCBMagick now support full LZW encoding (read/write).</li>
+</ul>
+</blockquote>
+<p>2004-07-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff/libtiff/tif_lzw.c: Replace with version which supports LZW encoding.</li>
+<li>magick/channel.c: New source file.
+(ExportImageChannel): New function to export an image channel.
+(ImportImageChannel): New function to import an image channel.</li>
+</ul>
+</blockquote>
+<p>2004-07-20 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lcms/src/cmsio1.c: Test [testcms.c] related to lcms 1.13 fail
+with error #12288 when perform &quot;Checking saved linearization
+devicelink&quot;. Fixed function __cmsSaveProfile(). &quot;...malloc(0) is
+implementation dependent and may return non NULL pointer on some
+compilers, like VC++ and gcc. This is not the case of Borland C++
+Builder&quot; - Thanks to Marti Maria that have supplied me this
+patched file: this will be part of the next lcms 1.14 which
+probabily will be released on summer's end.</li>
+</ul>
+</blockquote>
+<p>2004-07-20 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lcms/include/lcms.h: Modified to achieve BCBMagick DLL compilation.
+Included modifications was introduced in GM in 2004-01-16 and
+probabily lost with latest update of library.</li>
+</ul>
+</blockquote>
+<p>2004-07-20 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>BCBMagick: Updated lcms to version 1.13.</dt>
+<dd><ul class="first last">
+<li>Modified files: BCBMagickAllbcbMagick.mak; BCBMagicklcmsBCB6GM_lcms.bpr;
+BCBMagicklcmsBCB6lcms.bpg; BCBMagicklcmsBCB6lcms.bpr;
+BCBMagicklcmsBCB6testcms.bpr</li>
+<li>Deleted files: BCBMagicklcmsBCB6lcms.cpp; BCBMagicklcmsBCB6testcms.cpp</li>
+<li>Added file: BCBMagicklcmsBCB6lcms.bpf</li>
+</ul>
+</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2004-07-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Fix typo regarding -define tiff:samples-per-pixel.</li>
+<li>doc/GNUmakefile (utility-install): Utility HTML targets were not being installed.</li>
+</ul>
+</blockquote>
+<p>2004-07-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lcms: Updated to version 1.13.</li>
+</ul>
+</blockquote>
+<p>2004-07-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh (CVS_BRANCH_TAG): Record the CVS branch tag that
+source package is obtained from.</li>
+</ul>
+</blockquote>
+<p>2004-07-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Pass essential flags on down to subordinate
+configures when performing <cite>make distcheck</cite>. Support DESTDIR
+installs for PERL 5.8.1 and later, which support DESTDIR
+internally.</li>
+</ul>
+</blockquote>
+<p>2004-07-16 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>BCBMagickcoderslibCoders.bpr; BCBMagickmagickGM_magick.bpr: include</dt>
+<dd>file jbig.h could not be found during compilation. Solved.</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2004-07-15 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagickmagickmagick_config.h.: enabled LZW compression by default.</li>
+<li><dl class="first docutils">
+<dt>BCBMagick: included jbig delegate library.</dt>
+<dd><ul class="first last">
+<li>Modified these files into directory BCBMagick: AllbcbMagick.mak;
+AllGMlib.bpg; AllGMdll.bpg; coderslibCoders.bpr; magickGM_magick.bpr;
+utilitiesgm_lib.bpr; utilitiesgm_dll.bpr</li>
+<li>Added these files into new directory BCBMagickjbig: jbig.bpr;
+jbig.bpf; GM_jbig.bpr; GM_jbig.c; tstcodec.bpr</li>
+<li>Modified file jbigjbiglibjbig.h;</li>
+</ul>
+</dd>
+</dl>
+</li>
+<li>BCBMagickreadme.txt: updated documentation.</li>
+</ul>
+</blockquote>
+<p>2004-07-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyUsage): -ordered-dither help was
+formatted incorrectly.</li>
+<li>doc/options.imdoc: Improve formatting a bit for manual pages and
+fix some syntax errors.</li>
+</ul>
+</blockquote>
+<p>2004-07-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: Updated to reflect changes since last update.</li>
+</ul>
+</blockquote>
+<p>2004-07-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (ReadBMPImage): Removed if-test on reading
+red_mask, green_mask, and blue_mask. These are only *valid*
+under certain conditions, but they are always present in the
+file.</li>
+</ul>
+</blockquote>
+<p>2004-07-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Enable LZW compression by default.</li>
+</ul>
+</blockquote>
+<p>2004-07-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (WriteJPEGImage): Don't enable Huffman compression
+for large images (&gt; 16 Mpixels for the moment) in order to
+conserve memory. When Huffman compression is enabled the entire
+image is buffered in memory prior to encoding and writing
+anything. Huffman compression is a method of eliminating
+redundant data so when the Huffman compression is disabled, files
+sizes will be larger, but otherwise the image is the same.</li>
+<li>wand/magick_wand.c (MagickSetPassphrase): String was being
+copied to a null pointer. Now memory is allocated as required
+prior to a copy.
+Ensure that all unimplemented functions return a proper error
+report.</li>
+</ul>
+</blockquote>
+<p>2004-07-01 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick: updated to GraphicsMagick v.1.2</li>
+<li>BCBMagickAll: project GMlib-1.1.bpr has been replaced with
+GMlib.bpr</li>
+<li>BCBMagickAll: project GMdll-1.1.bpr has been replaced with
+GMdll.bpr</li>
+<li>BCBMagickreadme.txt: updated documentation.</li>
+</ul>
+</blockquote>
+<p>2004-06-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): For -units, don't reset
+resolution if units are undefined. Report an error if the -units
+argument is not supported.</li>
+</ul>
+</blockquote>
+<p>2004-06-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): When setting image units, also
+adjust existing image x_resolution and y_resolution so that
+existing image resolution is not trashed.
+(MogrifyImage): When re-sampling an image, report an error if the
+image does not contain a valid resolution.</li>
+</ul>
+</blockquote>
+<p>2004-06-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pcx.c (WritePCXImage): Support writing large PCX files.
+(WritePCXImage): Ensure that UndefinedResolution is handled
+properly. Avoid round-off error for centimeter based resolution.</li>
+</ul>
+</blockquote>
+<p>2004-06-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Look for mozilla by default rather than netscape.</li>
+</ul>
+</blockquote>
+<p>2004-06-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/type.c (ReadTypeConfigureFile): Determine location of
+Ghostscript fonts only once in order to improve performance.</li>
+<li>magick/nt_base.c (NTGhostscriptFonts): Properly determine
+Ghostscript font location for Ghostscript 8.0 and later.</li>
+<li>GraphicsMagick.spec.in: Install *-config scripts with mode 755
+rather than default 644.</li>
+</ul>
+</blockquote>
+<p>2004-05-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/module.c (InitializeModuleSearchPath): Evaluate and cache
+module search path.
+(FindMagickModule): Use cached module search path.
+(OpenModules): Load all modules rather than just the modules in
+the directory where the LOGO module is found. Besides allowing
+user-provided modules in non-GraphicsMagick directories to be
+loaded, this allows the &quot;moby&quot; shared build to load additional
+modules via OpenModules.</li>
+</ul>
+</blockquote>
+<p>2004-05-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/Makefile.am (check): Add convert -list tests.</li>
+</ul>
+</blockquote>
+<p>2004-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Magick++ needs to be built as a static library
+under Cygwin and MinGW since C++ exceptions don't work otherwise.
+Be more assertive about that.</li>
+<li>magick/nt_base.h: Avoid conflict with ssize_t definition under
+MinGW.</li>
+</ul>
+</blockquote>
+<p>2004-05-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (DispatchImage): Support 8-bit output to
+common formats BGR, BGRO, BGRP, RGB, RGBO, and I as special cases
+in order to improve performance.
+(ConstituteImage): Support 8-bit input from common formats BGR,
+BGRO, BGRP, RGB, RGBO, and I as special cases in order to improve
+performance.</li>
+</ul>
+</blockquote>
+<p>2004-05-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ltmain.sh: Fix to allow exe wrapper to work under MinGW.</li>
+<li>wand/magick_compat.c (QueryMagickColor): Fixed DLL export.</li>
+<li>wand/magick_wand.c: Fixed some DLL exports (MagickExport-&gt;WandExport).</li>
+</ul>
+</blockquote>
+<p>2004-05-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageClipMask): Consistently report any
+exceptions to image-&gt;exception.</li>
+</ul>
+</blockquote>
+<p>2004-05-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Update to Automake 1.8.5.</li>
+<li>magick/image.h (ImageInfo): New <cite>progress</cite> monitor to indicate
+if progress monitor and busy cursor are enabled while displaying
+an image. Defaults to True.</li>
+<li>magick/display.c, magick/xwindow.c: Use +progress to disable
+progress monitor and busy cursor.</li>
+<li>magick/command.c (MogrifyUsage): Usage didn't list -operator.
+(ConvertUsage): Usage didn't list -operator.</li>
+</ul>
+</blockquote>
+<p>2004-05-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/compress.c (HuffmanDecodeImage): Properly return error status.
+(HuffmanEncode2Image): Properly return error status.</li>
+<li>magick/composite.c (CompositeImage): Properly return error status.</li>
+<li>magick/quantize.c (ClassifyImageColors): Properly return error status.
+(GetImageQuantizeError): Properly return error status.
+(OrderedDitherImage): Properly return error status.</li>
+<li>magick/profile.c (ProfileImage): Properly return error status.</li>
+<li>magick/paint.c (ColorFloodfillImage): Properly return error status.
+(MatteFloodfillImage): Properly return error status.
+(OpaqueImage): Properly return error status.
+(TransparentImage): Properly return error status.</li>
+<li>magick/enhance.c (ContrastImage): Properly return error status.
+(EqualizeImage): Properly return error status.
+(GammaImage): Properly return error status.
+(LevelImage): Properly return error status.
+(LevelImageChannel): Properly return error status.
+(ModulateImage): Properly return error status.
+(NegateImage): Properly return error status.
+(NormalizeImage): Properly return error status.</li>
+<li>magick/image.c (GetImageClipMask): New function to retrieve an
+associated clip-mask image.
+(SetImageClipMask): Clip-mask image parameter may be const since
+it is cloned prior to storage.
+(ChannelImage): Properly return error status.
+(GradientImage): Properly return error status.
+(RGBTransformImage): Properly return error status.
+(TransformRGBImage): Properly return error status.
+(SyncImage): Return an error status.</li>
+<li>magick/enhance.c (NegateImage): If image has a clip mask,
+then force image to DirectClass so clip mask takes effect.</li>
+</ul>
+</blockquote>
+<p>2004-05-15 Vladimir Lukianov &lt;<a class="reference external" href="mailto:lvm&#37;&#52;&#48;integrum&#46;ru">lvm<span>&#64;</span>integrum<span>&#46;</span>ru</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageOpacity): Ensure that image is
+DirectClass. If specified opacity is TransparentOpacity, then
+replace existing opacity with TransparentOpacity.</li>
+</ul>
+</blockquote>
+<p>2004-04-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Avoid duplicated test status messages for __func__
+tests. Avoid duplicated test status message for jpeg 6b test.</li>
+</ul>
+</blockquote>
+<p>2004-04-19 Patrick Welche &lt;<a class="reference external" href="mailto:prlw1&#37;&#52;&#48;newn&#46;cam&#46;ac&#46;uk">prlw1<span>&#64;</span>newn<span>&#46;</span>cam<span>&#46;</span>ac<span>&#46;</span>uk</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/header.html: HTML syntax fixes.</li>
+</ul>
+</blockquote>
+<p>2004-04-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>: Change web pages to a frames-based design.</li>
+</ul>
+</blockquote>
+<p>2004-04-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/Makefile.am (check): Change geometry arguments which
+were expressed as 0.0xVAL to avoid the problematic Linux scanf
+feature back to 0xVAL.</li>
+</ul>
+</blockquote>
+<p>2004-04-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/symbols.h (GetMagickDimension): Added GetMagickDimension.</li>
+</ul>
+</blockquote>
+<p>2004-04-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetMagickDimension): New function to replace
+occurances of scanf(geometry,&quot;%lfx%lf&quot;,&amp;w,&amp;h) since Linux scanf()
+and strtod() misbehave for strings that start with &quot;0x&quot;. The Linux
+versions always treat 0x as the start of a value expressed in hex
+and can't be forced to read the leading value as a double. This
+function has been applied globally to replace the problem scanf's.</li>
+<li>magick/version.h.in: Make it clear in the -version output that a
+mutitude of copyrights and licenses apply to this software.</li>
+<li>magick/utility.c (GetPathComponent): Avoid strncpy() of
+overlapping regions.</li>
+<li>magick/command.c (DisplayImageCommand): Eliminate double-free
+of resource_info-&gt;image_geometry.
+(DisplayImageCommand): <cite>display</cite> was improperly requiring at least
+one argument (bug was added yesterday).</li>
+</ul>
+</blockquote>
+<p>2004-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/gm.c (main): Default usage message wasn't right for
+aliased utility.</li>
+<li>configure.ac: Added the --enable-magick-compat option to install
+compatibility links to emulate ImageMagick commands.</li>
+<li>magick/command.c: Ensure that each sub-command responds to -help
+and -version appropriately.</li>
+<li>utilities/gm.c (main): Invoke appropriate sub-command if gm is
+executed under a traditional alternate name such as &quot;convert&quot;. The
+user may create hard or symbolic links from <cite>gm</cite> to a traditional
+ImageMagick utility name (or just copy <cite>gm</cite> to the desired
+sub-command name) in order to be 100% command-line compatible with
+ImageMagick 5.5.2. This is necessary in order to work with
+existing software designed to execute ImageMagick utilities.</li>
+</ul>
+</blockquote>
+<p>2004-04-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/compress.c (Ascii85Tuple): Encoding bug is indeed fixed
+on DEC Alpha. Also warnings reduction with Digital Unix compiler.</li>
+</ul>
+</blockquote>
+<p>2004-04-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/compress.c (Ascii85Tuple): Add casts to reduce compiler
+warnings, and maybe even fix a bug.</li>
+<li>coders/pdf.c (ReadPDFImage): Double-check that Ghostscript
+produced an output file since sometimes it reports success after
+it has spewed an error message and has produced no output.</li>
+</ul>
+</blockquote>
+<p>2004-04-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/compress.c (HuffmanEncode2Image): Avoid out of bounds
+array access.</li>
+<li>magick/studio.h (_FILE_OFFSET_BITS): Fix _FILE_OFFSET_BITS
+#ifdef to avoid warnings when it is not defined.</li>
+</ul>
+</blockquote>
+<p>2004-04-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Fix minor shell syntax error (used ==).</li>
+</ul>
+</blockquote>
+<p>2004-04-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Merged in updates from 1.1 release branch.</li>
+<li>version.sh (PACKAGE_VERSION): Release version 1.1.
+(PACKAGE_VERSION): Next major release will be 1.1. Bump library
+versions since we anticipate adding interfaces.</li>
+<li>magick/studio.h: Disabled use of Windows message lookups
+entirely since this doesn't seem to work for programs. It
+probably only works for DLLs like ImageMagickObject.</li>
+<li>magick/delegate.c (ListDelegateInfo): Don't get stuck in a loop
+if fprintf() returns zero.</li>
+</ul>
+</blockquote>
+<p>2004-04-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/*/*.bat: Add .exe to exe file names in order to
+ensure that the executable is executed rather than something else
+(such as a batch script).</li>
+<li>magick/locale.c: Only use Windows resource message lookup for
+the DLL build since it doesn't seem to work for static
+executables.</li>
+<li>magick/utility.c (SetClientPath): Ensure that client path is
+null terminated.
+(SetClientFilename): Initialize default client filename to &quot;&quot;
+rather than &quot;gm.exe&quot; and ensure that filename is null terminated.
+(SetClientName): Ensure that client path is null terminated.</li>
+<li>magick/blob.c (GetConfigureBlob): Enable logging the load of
+log.mgk</li>
+<li>magick/log.c: Re-designed logging initialization in order to
+avoid the &quot;chicken and the egg&quot; snafu. This allows logging the
+initialization of the logging subsystem.</li>
+</ul>
+</blockquote>
+<p>2004-04-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/bin/log.mgk: Add comments to help document usage.</li>
+<li>config/log.mgk: Add comments to help document usage.</li>
+<li>magick/utility.c (IsAccessible): Use access() rather than stat().
+(IsAccessibleNoLogging): Use access() rather than stat().
+(IsDirectory): Implemented return status according to existing API
+documentation.
+(GetExecutionPathUsingName): Complete re-write in order to minimize
+path computation logic and fix failure with partial paths.</li>
+</ul>
+</blockquote>
+<p>2004-03-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Add &quot;Color&quot; to the arguments available for -list.</li>
+</ul>
+</blockquote>
+<p>2004-03-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh (PACKAGE_CHANGE_DATE): Updated version to 1.1Beta3</li>
+<li>magick/nt_base.c (NTSystemComman): Have not been successful with using
+MsgWaitForMultipleObjects() reliably, so back out usage of it for
+now.</li>
+<li>magick/fx.c (ConvolveImage): Support convolution in CMYK
+colorspace.</li>
+</ul>
+</blockquote>
+<p>2004-03-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh (PACKAGE_CHANGE_DATE): Update release to 1.1Beta2.</li>
+<li>magick/constitute.c (ReadImage): Ignore errors of type
+ConfigureError when loading modules so that error report can still
+report the familiar &quot;No delegate for this image format&quot; message
+while still being able to report problems with loading a module if
+it was found. This is a compromise which reports useless messages
+when the modules are not found at all, but I can't think of a way
+around it.</li>
+<li>magick/nt_base.c (NTSystemComman): Adjust
+MsgWaitForMultipleObjects() arguments to wait for object to be
+signaled only (FALSE) rather wait for object to be signaled as
+well as an input event received(TRUE). It seems that process
+status changes do not result in an input event, so the call was
+deadlocking.</li>
+<li>magick/constitute.c (ReadImage): If module loading reported an
+error, ReadImage immediately returned an error rather than trying
+to use a delegate defined by delegates.mgk.</li>
+</ul>
+</blockquote>
+<p>2004-03-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Updated version to 1.1Beta1</li>
+</ul>
+</blockquote>
+<p>2004-03-24 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick/magick/libMagick.bpr: updated to latest source modifications.</li>
+<li>BCBMagick/magick/GM_Magick.bpr: updated to latest source modifications.</li>
+</ul>
+</blockquote>
+<p>2004-03-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/plasma.c (ReadPlasmaImage): srand() is already invoked by
+InitializeMagick() so don't call it here.</li>
+<li>configure.ac: Check for rand_r().</li>
+<li>magick/tempfile.c (ComposeTemporaryFileName): The full range of
+safe characters was not being used, thereby limiting the number of
+unique temporary file names available.</li>
+</ul>
+</blockquote>
+<p>2004-03-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GetImageStatistics): New function to obtain
+image statistics (minimum, maximum, mean, variance, and standard
+deviation).
+(DescribeImage): Include image channel statistics in verbose
+output.</li>
+</ul>
+</blockquote>
+<p>2004-03-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (DispatchImage): Removed some unreachable
+code that was accidentially left in the switch statement.</li>
+<li>magick/pixel_iterator.c (PixelIterateDualRead): Extended so that
+the region in each image may use a different origin.
+(PixelIterateDualModify): Extended so that
+the region in each image may use a different origin.</li>
+<li>magick/composite.c (CompositeImage): Fix XorCompositeOp overflow
+condition which occured on non-Intel architectures.</li>
+</ul>
+</blockquote>
+<p>2004-03-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: Updated with changes up to today's date.</li>
+<li>tests/constitute.c (main): Float type seems to require allowing
+a bit of error for Q:32.</li>
+<li>magick/constitute.c (DispatchImage): Be more careful when
+rounding pixel intensity.
+(ConstituteImage): Be more careful when converting float and
+double to Quantum.</li>
+<li>magick/composite.c (CompositeImage): Fix Multiply composite
+operator for Q:32 build (was all black image).
+(CompositeImage): Tidied up the documented composite operators so
+the implementation is easier to understand.</li>
+<li>PerlMagick/t/ttf/read.t: Set a desired label size so output
+image should be the same size as the reference image even if the
+FreeType type hinter is disabled.</li>
+<li>magick/annotate.c (RenderFreetype): Improve outline bounding box
+computation accuracy.</li>
+</ul>
+</blockquote>
+<p>2004-03-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/x/write.t: Don't test X11 if DISPLAY is not set.</li>
+<li>PerlMagick/t/x/read.t: Don't test X11 if DISPLAY is not set.</li>
+</ul>
+</blockquote>
+<p>2004-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/Makefile.am: Removed some apparently unnecessary library
+dependencies.</li>
+<li>Makefile.am (windows-src): Added a way to generate a Windows
+source zip file.</li>
+</ul>
+</blockquote>
+<p>2004-03-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: The -operator command now supports
+floating-point and percent of range arguments.</li>
+</ul>
+</blockquote>
+<p>2004-03-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Added support for -operator command with
+syntax &quot;-operator channel operator rvalue&quot; which applies a
+arithmetic or bitwise operator to a specified image channel
+or all channels.</li>
+</ul>
+</blockquote>
+<p>2004-03-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/filter.t: Fix Solarize test case.</li>
+<li>PerlMagick/t/wmf/read.t: Added another WMF test case.</li>
+<li>coders/wmf.c: Resolve WMF rendering bug with black color.</li>
+<li>magick/utility.c (StringToArgv): Free argv data prior to error
+return.</li>
+</ul>
+</blockquote>
+<p>2004-03-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (WriteJPEGImage): If image_info-&gt;colorspace is set
+to GRAYColorspace then make sure that image is in a gray
+colorspace.</li>
+<li>magick/image.c (TransformRGBImage): If colorspace is already an
+RGB type (RGBColorspace, GRAYColorspace, or TransparentColorspace),
+then simply return. Do *not* set image-&gt;colorspace to RGBColorspace
+since this potentially loses a valuable setting.</li>
+</ul>
+</blockquote>
+<p>2004-03-10 Peter Boos &lt;<a class="reference external" href="mailto:pedib&#37;&#52;&#48;colorfullife&#46;com">pedib<span>&#64;</span>colorfullife<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/annotate.c (RenderFreetype): If DrawAnnotation is called
+with a string containing only one character and this character is
+not recognized by the TrueType engine, a crash occured due to the
+failure of FT_Load_Glyph. The failure caused an uninitialized
+glyph.image pointer to be used by FT_Done_Glyph() later in the
+code. The solution is to initialize the glyph.image pointer to
+null.</li>
+</ul>
+</blockquote>
+<p>2004-03-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (QuantumOperatorRegionImage): Properly handle
+over and underflow of arithmetic operators.</li>
+<li>magick/draw.c (DrawGetFillOpacity): Use fill opacity, and invert
+opacity range so it is 0.0 to 1.0 (was acting like transparency).
+(DrawSetStrokeOpacity): Validate range of stroke_opacity.
+(DrawSetFillOpacity): Save value to context-&gt;fill.opacity and
+validate the range of fill_opacity.</li>
+<li>magick/image.c (QuantumOperatorImage): New function to apply an
+arithmetic or bitwise operator to the pixel quantums in an image.
+(QuantumOperatorRegionImage): New function to apply an arithmetic
+or bitwise operator to the pixel quantums in an image region.</li>
+<li>magick/image.c (IsImagesEqual): Re-implemented using the new
+pixel iteration functions as a proof of concept.</li>
+<li>magick/pixel_iterator.h: Added some pixel iteration functions in
+order to make it easier to implement algorithms which only need to
+iteratively access pixels in a region. These functions are not
+part of the API yet so their interface should be considered
+unstable.</li>
+<li>doc/GNUmakefile: Rename Makefile to GNUmakefile since it relies
+on GNU make extensions.</li>
+</ul>
+</blockquote>
+<p>2004-03-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ConstituteImage): Add support for <cite>T</cite>
+(transparency) and <cite>O</cite> (opacity) map types. Simplify
+implementation.
+(DispatchImage): Add support for <cite>T</cite> (transparency) and <cite>O</cite>
+(opacity) map types. Simplify implementation.</li>
+<li>config/delegates.mgk.in: Quote delegate command names so
+that they can contain embedded spaces.</li>
+<li>VisualMagick/bin/delegates.mgk: Quote delegate command names so
+that they can contain embedded spaces.</li>
+<li>coders/tiff.c (WriteTIFFImage): Use the libtiff default endian
+mode when writing TIFF rather than forcing MSB2LSB bit order.
+(ReadTIFFImage): Enable reading in MSB2LSB bit order (better for
+our byte-level parsing), enable memory mapping, and enable strip
+chopping. Memory mapping and strip chopping are probably enabled
+by default.</li>
+<li>magick/nt_base.c (NTSystemComman): Use
+MsgWaitForMultipleObjects() rather than WaitForSingleObject() in
+order to avoid possible deadlock when application code directly or
+indirectly creates windows.</li>
+</ul>
+</blockquote>
+<p>2004-02-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/animate.c (XMagickCommand): URL should point to
+<a class="reference external" href="http://graphicsmagick.org/">http://graphicsmagick.org/</a>.</li>
+<li>magick/display.c (XMagickCommand): URL should point to
+<a class="reference external" href="http://graphicsmagick.org/">http://graphicsmagick.org/</a>.</li>
+<li>magick/image.c (DisplayImages): Changes to fix memory leaks in
+X11 commands had bugs which seriously broke DisplayImages. Now
+DisplayImages works properly again.</li>
+<li>magick/xwindow.c (XDestroyResourceInfo): New function to destroy
+XResourceInfo.</li>
+<li>coders/x.c (WriteXImage): Implement based on DisplayImages().
+(RegisterXImage): Always register X coder, but with read/write
+support disabled if X11 not available.</li>
+</ul>
+</blockquote>
+<p>2004-02-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ImportImageCommand): Eliminate memory leaks.</li>
+<li>magick/memory.c (LiberateMemory): Use MagickFreeMemory macro for
+implementation.
+(ReacquireMemory): Use MagickReallocMemory macro for
+implementation.
+(AcquireMemory): Use MagickAllocateMemory for implementation.</li>
+</ul>
+</blockquote>
+<p>2004-02-26 Vladimir &lt;<a class="reference external" href="mailto:lvm&#37;&#52;&#48;integrum&#46;ru">lvm<span>&#64;</span>integrum<span>&#46;</span>ru</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/memory.c (CloneMemory): Fixes to compile under Microsoft
+Visual C++ 6.0.</li>
+</ul>
+</blockquote>
+<p>2004-02-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/animate.c (XAnimateImages): Memory leak reduction and
+better integration with gm command.</li>
+<li>magick/display.c (XDisplayImage): Display was leaking memory
+like a sieve. Now it doesn't.</li>
+<li>magick/memory.c (CloneMemory): Computation for when it is safe
+to use memcpy() was incorrect. Use memmove() rather than
+backwards-copy loop.</li>
+<li>Makefile.am ($(DIST_ARCHIVE_SRPM)): Added rules to build a
+source RPM.</li>
+<li>configure.ac: Search for <cite>buildrpm</cite> or <cite>rpm</cite> programs in order to
+support creating RPM packages on a system which has RPM installed.</li>
+<li>version.sh (PACKAGE_VERSION): Changed snapshot release naming so
+that there is only one dash in the name and the snapshot date is
+prefixed with <cite>0</cite> to assure proper directory sorting. This allows
+snapshot naming to be acceptable to RPM. The snapshot package
+name is now similar to GraphicsMagick-1.1.020040218.tar.bz2</li>
+</ul>
+</blockquote>
+<p>2004-02-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xwd.c (RegisterXWDImage): Always register XWD, but only
+register read/write methods if it is supported.</li>
+<li>wand/magick_wand.c: Synchronized with latest ImageMagick API
+changes.</li>
+</ul>
+</blockquote>
+<p>2004-02-16 Lars Ruben Skyum &lt;<a class="reference external" href="mailto:lars&#46;skyum&#37;&#52;&#48;stibo&#46;com">lars<span>&#46;</span>skyum<span>&#64;</span>stibo<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (HorizontalFilter): Fixed: do process K channel
+for CMYK images.
+(VerticalFilter): do process K channel for CMYK images.</li>
+</ul>
+</blockquote>
+<p>2004-02-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tga.c (ReadTGAImage): Fix matte channel handling. For
+16-bit packets, use integer rather than floating point. Return
+gray images as PseudoClass and set is_grayscale flag. Add
+logging.</li>
+<li>magick/fx.c (WaveImage): Ensure that image is
+DirectClass. Ensure that matte channel is initialized if
+necessary. Include background color in is_grayscale evaluation.</li>
+<li>magick/gem.c (GenerateNoise): Scale noise to range of quantum.</li>
+</ul>
+</blockquote>
+<p>2004-02-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (WriteJP2Image): Support passing all documented
+Jasper options using -define.</li>
+</ul>
+</blockquote>
+<p>2004-02-13 Peter Boos &lt;<a class="reference external" href="mailto:pedib&#37;&#52;&#48;colorfullife&#46;com">pedib<span>&#64;</span>colorfullife<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c (util_draw_arc): Fixes to improve handling for pie,
+arc, and chord. These fixes produce correct output for
+wmf/examples/fjftest.wmf, but it is not known if they are correct
+for all cases.</li>
+</ul>
+</blockquote>
+<p>2004-02-12 Tim Hunter &lt;<a class="reference external" href="mailto:cyclists&#37;&#52;&#48;nc&#46;rr&#46;com">cyclists<span>&#64;</span>nc<span>&#46;</span>rr<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c (SetImageProfile): Bug fixes.</li>
+</ul>
+</blockquote>
+<p>2004-02-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xpm.c (UnregisterXPMImage): Unregister PICON registration.</li>
+</ul>
+</blockquote>
+<p>2004-02-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/Makefile.am (label_la_LDFLAGS): Add a dependency on the
+math library since floor() is used.</li>
+<li>wand/magick_wand.c (MagickRemoveImageProfile): Use C comments in
+C files.</li>
+<li>magick/constitute.c (MapQuantumType): Fix spurious comma in
+enum definition.</li>
+<li>magick/blob.c (GetBlobStreamHandler): Apparently return type can
+not be const.</li>
+</ul>
+</blockquote>
+<p>2004-02-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Check for Windows fonts under
+/usr/X11R6/lib/X11/fonts/truetype (XFree86 standard location?).</li>
+<li>coders/jp2.c (WriteJP2Image): Support providing a compression
+rate value (range 0.0 to 1.0) using command line syntax similar to
+<cite>-define jp2:rate=0.5</cite>. In Magick++ this option may be accessed
+similar to image.defineValue(&quot;jp2&quot;,&quot;rate&quot;,&quot;0.5&quot;);</li>
+<li>magick/command.c (DisplayImageCommand): Exit status was inverted
+so <cite>gm display</cite> was returning 1 for successful commands, and 0 for
+failures.
+(AnimateImageCommand): Exit status was inverted so <cite>gm animate</cite>
+was returning 1 for successful commands, and 0 for failures.</li>
+</ul>
+</blockquote>
+<p>2004-02-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.h (MagickReallocMemory): Solaris compiler
+complains about cast so remove it.</li>
+<li>coders/xwd.c (WriteXWDImage): Right-size the pixels buffer and
+tune writer loops a bit.</li>
+<li>magick/color.h (VerifyColormapIndex): Improve diagnostics.</li>
+<li>coders/pict.c (WritePICTImage): Eliminate use of uninitialized
+data when writing RGB PICT. Fix OpenBlob assertion when writing
+JPEG PICT.
+(ReadPICTImage): Validate <cite>tile_image</cite> colormap indexes rather
+than <cite>image</cite> colormap indexes. Preserve compression attribute from
+tile image.</li>
+<li>magick/constitute.c (DispatchImage): Don't access image opacity
+channel unless image-&gt;matte is True.</li>
+</ul>
+</blockquote>
+<p>2004-02-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (UnregisterPNGImage): Destroy PNG semaphore.</li>
+<li>magick/image.c (SetImageInfo): Since we don't know what the
+&quot;IMPLICIT&quot; specifier is supposed to do, support for it is
+removed. Perhaps by removing support for it, we will be reminded
+why it exists.</li>
+<li>magick/magick.c (DestroyMagickInfo): Invoke
+UnregisterStaticModules().
+(GetMagickInfo): Remove registration for &quot;IMPLICIT&quot; format since
+its purpose is presumed bogus.</li>
+<li>magick/static.c (UnregisterStaticModules): New function so we
+can unregister static modules.</li>
+<li>coders/plasma.c (UnregisterPLASMAImage): Unregister FRACTAL.</li>
+<li>coders/icon.c (UnregisterICONImage): Unregister CUR.</li>
+<li>coders/bmp.c (UnregisterBMPImage): Unregister BMP2 and BMP3.</li>
+<li>coders/meta.c (UnregisterMETAImage): Unregister APP1JPEG, IPTC,
+IPTCTEXT, IPTCWTEXT, and PICON.</li>
+<li>coders/miff.c: Check for run-length termination before testing
+memory and only check opacity channel if matte is valid.</li>
+<li>magick/compress.c: Check for run-length termination before
+testing memory (bad read error).</li>
+</ul>
+</blockquote>
+<p>2004-02-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c: Fix off-by-one error while initializing padding bytes.</li>
+<li>coders/dib.c: Fix off-by-one error while initializing padding bytes.</li>
+<li>magick/enhance.c: MaxMap vs MaxRGB error fixed. Reported by Cristy.</li>
+</ul>
+</blockquote>
+<p>2004-02-04 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/compress.c: avoid a reference to uninitialized data.</li>
+</ul>
+</blockquote>
+<p>2004-02-04 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dib.c: initialize padding bytes.</li>
+</ul>
+</blockquote>
+<p>2004-02-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/montage.c (MontageImages): Fix leak of texture image (big
+leak).</li>
+</ul>
+</blockquote>
+<p>2004-02-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Fix detection of when to use a
+temporary file when writing TIFF. Writing to TIFF BLOBs was
+broken by the recent changes to make BlobInfo a private type.</li>
+<li>magick/render.c (DestroyEdge): Use memmove for overlapping copy.</li>
+</ul>
+</blockquote>
+<p>2004-02-03 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c: initialize padding bytes.</li>
+</ul>
+</blockquote>
+<p>2004-02-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ConstituteImage): Added map support for <cite>P</cite>,
+in order to skip over a pad quantum.
+(DispatchImage): Added map support for <cite>P</cite>, in order to write a pad
+quantum.</li>
+<li>magick/resize.c (HorizontalFilter): Don't process opacity
+channel unless matte is enabled.
+(VerticalFilter): Don't process opacity channel unless matte is
+enabled.</li>
+<li>magick/compress.c (Ascii85Initialize): Don't overwrite an
+existing ascii85 allocation.</li>
+<li>magick/utility.c (Strip): Use <cite>memmove</cite> rather than <cite>memcpy</cite> to
+copy overlapping data.</li>
+<li>tests/rwfile.c (main): Fix memory leak in test. Only apply size
+if format requires it.</li>
+<li>tests/rwblob.c (main): Fix memory leak in test. Only apply size
+if format requires it.</li>
+<li>coders/mono.c (RegisterMONOImage): Mono is a raw format.</li>
+<li>magick/magic.c (GetMagicInfo): Ensure that magic tests are
+within the range of header data which was read.</li>
+</ul>
+</blockquote>
+<p>2004-02-02 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c: fix potential use of uninitialized data.</li>
+<li>coders/png.c: fix potential use of uninitialized data.</li>
+</ul>
+</blockquote>
+<p>2004-01-31 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h: Fixed problem related to DLL version of BCBMagick.
+Sometimes was incorrectly checked the presence of VC++ DLL. Thanks
+very much to Oliver Bertini for bringing this problem to our attention.</li>
+<li>BCBMagick: added libpng delegate library in both static and DLL
+modes.</li>
+<li>BCBMagick: removed all unuseful files from CVS.</li>
+</ul>
+</blockquote>
+<p>2004-01-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (CloneDrawInfo): Fixed nasty memory leak which
+becomes painfully evident when using Magick++.</li>
+<li>magick/type.c (ReadTypeConfigureFile): Fix problem with parsing
+&lt;include&gt; directive.</li>
+<li>configure.ac: The type.mgk generated had a syntax error.</li>
+<li>magick/effect.c (SpreadImage): Eliminate read from uninitialized
+memory.</li>
+<li>magick/quantize.c (NodeInfo): Store nodes in a list similar to
+ImageMagick.
+(DestroyCubeInfo): Eliminate a small memory leak.</li>
+</ul>
+</blockquote>
+<p>2004-01-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/montage.c (MontageImages): Free thumbnails once they are
+no longer needed (big leak).</li>
+<li>magick/blob.c (OpenBlob): Ensure that magick array is
+fully initialized, even if the fread() is short.</li>
+<li>magick/list.c (ImageListToArray): Add a null pointer to the end
+of the image list to serve as a handy list terminator.</li>
+<li>magick/tempfile.c (DestroyTemporaryFiles): Fix memory leak of
+semaphore.</li>
+<li>magick/map.c (MagickMapDeallocateMap): Fix memory leak of
+semaphore.</li>
+<li>coders/png.c (WriteOneJNGImage): Use DestroyBlob.</li>
+<li>magick/list.c (SyncNextImageInList): Use DestroyBlob.</li>
+<li>magick/image.c (AllocateNextImage): Use DestroyBlob.
+(DestroyImage): DestroyBlob.</li>
+<li>coders/wpg.c (ExtractPostscript): Use DestroyBlob.</li>
+<li>magick/blob.c (DestroyBlob): New function. Similar to
+DestroyBlobInfo except that it requires an Image * argument and
+zeros the blob pointer. This one is preferred for use over
+DestroyBlobInfo.</li>
+</ul>
+</blockquote>
+<p>2004-01-27 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Add DestroyBlobInfo() calls to stop memory leak when
+processing JNG datastreams.</li>
+</ul>
+</blockquote>
+<p>2004-01-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.h (MagickReallocMemory): Added a cast required to
+make C++ Happy.</li>
+<li>coders/tiff.c: Adjust for bitstream API function renaming.</li>
+<li>magick/bit_stream.h: Rename BitStreamRead() to
+BitStreamMSBRead() to indicate that it reads most significant bytes
+first (&quot;big endian&quot; order). Rename BitStreamWrite() to
+BitStreamMSBWrite() to indicate that it writes most significant
+bytes first (&quot;big endian&quot; order).</li>
+<li>wand/magick_wand.c: Updated to lastest ImageMagick API.</li>
+</ul>
+</blockquote>
+<p>2004-01-26 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/stream.c: (SetPixelStream) removed &quot;const&quot; from definition of
+local variable [StreamHandler stream]. Borland C++Builder compiler signal
+error &quot;Cannot modify a const object&quot;.</li>
+</ul>
+</blockquote>
+<p>2004-01-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (TIFFMapBlob): Allow libtiff to access memory
+mapped file (or BLOB in memory) directly. This provides a small
+performance increase.</li>
+<li>magick/constitute.c (ReadImage): If a .mpc file is a temporary
+file, then be sure to remove the associated .cache file when
+removing the .mpc file.</li>
+<li>magick/log.h (LogEventType): ExceptionEventMask now maps to
+WarningEventMask|ErrorEventMask|FatalErrorEventMask so that
+<cite>-debug exception</cite> works again.</li>
+<li>magick/blob.c (CloseBlob): Allow CloseBlob to be invoked on a
+blob which is not open (in UndefinedStream state).
+(BlobInfo): The definition of BlobInfo is now private to blob.c.
+(StreamType): The StreamType enumeration is now private to blob.c.
+(GetBlobFileHandle): New function to access the blob file handle.
+(GetBlobStreamHandler): New function to access the blob stream
+handler.
+(GetBlobStreamType): This function is removed entirely.
+(BlobIsSeekable): New function to test if SeekBlob will work
+properly for this blob type.
+(GetBlobClosable): New function to test if the blob is allowed to
+be closed by the library (may be an externally provided file
+descriptor).
+(GetBlobTemporary): New function to test if input file is a
+temporary file which is to be removed.
+(SetBlobClosable): New function to support setting the flag which
+keeps the input file from being closed.
+(SetBlobTemporary): New function to support setting the flag which
+indicates that the input file is a temporary file.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Invoke CloseBlob even if
+blob is in UndefinedStream state.</li>
+<li>magick/error.h (ThrowReaderException): Ditto.
+(ThrowWriterException): Ditto.
+(ThrowWriterException2): Ditto.
+(ThrowWriterException3): Ditto.</li>
+<li>magick/tempfile.h (ThrowReaderTemporaryFileException): Ditto.
+(ThrowWriterTemporaryFileException): Ditto.</li>
+<li>coders/dps.c,coders/jpeg.c, coders/meta.c, coders/mvg.c,
+coders/png.c, coders/tiff.c, magick/constitute.c, magick/stream.c:
+Use new blob accessor functions.</li>
+<li>magick/cache.c (OpenCache): For Windows, set the sequential
+access flag in all cases. Maybe it will make a difference.</li>
+</ul>
+</blockquote>
+<p>2004-01-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (GetConfigureBlob): Don't check Windows registry
+if MagickLibConfigPath or MagickShareConfigPath is defined.</li>
+<li>magick/locale.c: Use a Unix-style message database for MinGW.</li>
+<li>rungm.sh.in: Translate environment paths to Windows format when
+running under MinGW.</li>
+<li>magick/nt_base.c (mmap): Re-wrote mmap emulation to support
+64-bit file offsets and to support anonymous mapping.
+(msync): A crude emulation of Unix msync().</li>
+<li>acinclude.m4 (GM_FUNC_MMAP_FILEIO): Change result define from
+HAVE_MMAP to HAVE_MMAP_FILEIO so that it doesn't conflict with
+Autoconf standard definition.</li>
+</ul>
+</blockquote>
+<p>2004-01-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cache.c (OpenCache): While allocating the pixel cache
+from the heap, reserve enough memory to contain a full PseudoClass
+image in order to reduce the chance that there will be a memory
+allocation failure while processing the image. This also avoids
+the possibility that the image pixels will be block-copied to a
+new location due to heap memory fragmentation. If there is
+insufficient heap memory (malloc() fails), then a disk-based pixel
+cache will be used.</li>
+<li>coders/wpg.c: Backed out Jaroslav Fojtik's patch from 2004-01-13
+because WPG was failing PerlMagick's existing WPG read test.</li>
+</ul>
+</blockquote>
+<p>2004-01-16 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick: updated to recent Windows delegate libraries.</li>
+<li>BCBMagick: modified build procedure. Removed all unused directories
+and include files.</li>
+<li>lcms/include/lcms.h: Modified to achieve BCBMagick compilation.</li>
+<li>tiff/libtiff/tiffio.h: Modified to achieve BCBMagick compilation</li>
+<li>ttf/include/freetype/config/ftoption.h: Modified to achieve
+BCBMagick compilation</li>
+<li>Magick++/lib/Magick++/Include.h: Modified to achieve BCBMagick compilation.</li>
+</ul>
+</blockquote>
+<p>2004-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c: Applied patch from Jaroslav Fojtik to support
+reading the CTM (current transform matrix). The CTM is not
+applied yet (expect later patch).</li>
+</ul>
+</blockquote>
+<p>2004-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sfw.c (ReadSFWImage): Added size_t cast.</li>
+<li>coders/msl.c (MSLStartElement): Added size_t cast.</li>
+<li>coders/meta.c (convertHTMLcodes): Added size_t cast.</li>
+<li>coders/locale.c: Add size_t casts and update to use memory
+allocation macros.</li>
+<li>coders/html.c (WriteHTMLImage): Added size_t cast.</li>
+<li>magick/utility.h (MagickAllocateMemory): Added size_t cast.
+(MagickReallocMemory): Added size_t cast.</li>
+<li>coders/bmp.c (WriteBMPImage): Added size_t cast.</li>
+<li>coders/art.c (ReadARTImage): Use memory allocation macros.</li>
+<li>VisualMagick/configure/configure.cpp: Update to support library
+.def exports files with Visual C++ 7.0.</li>
+<li>Updated Windows delegate libraries: LCMS 1.12, FreeType 2.1.5,
+BIG-KIT 1.5, libpng 1.2.5, libwmf 0.2.8.2, and zlib 1.2.1.</li>
+<li>Verified Windows static and DLL compilation with Visual C++ 6.0.</li>
+<li>Makefile.am: Update to automake 1.8.2.</li>
+<li>coders/gif.c (WriteGIFImage): Use ColorMatch rather than
+FuzzyColorMatch when comparing colormap entries.</li>
+</ul>
+</blockquote>
+<p>2004-01-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c: Needed to include &quot;magick/profile.h&quot; in order
+to obtain prototypes.</li>
+</ul>
+</blockquote>
+<p>2004-01-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/wandtest.c: Change MagickCloneWand to MagickGetImage since
+the API name changed.</li>
+<li>wand/pixel_wand.c: Synchronized with
+latest daily ImageMagick updates.</li>
+<li>wand/magick_wand.c (MagickRemoveImageProfile): Synchronized with
+latest daily ImageMagick updates.</li>
+<li>magick/profile.c (DeleteImageProfile): New method to make
+it easier to destroy an image profile.</li>
+<li>magick/profile.h: New source file to contain functions for
+dealing with embedded image profiles.</li>
+<li>magick/profile.c: New source file to contain functions for
+dealing with embedded image profiles.</li>
+<li>Makefile.am (DISTDIRS): Distribute TclMagick subdirectory.</li>
+</ul>
+</blockquote>
+<p>2004-01-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c: Ported over the latest ImageMagick Wand API
+updates. Note that a comment now says that the Wand API will not
+be finished until around 4th quarter of 2004. This represents a
+1-1/2 year slip from the original estimate!</li>
+</ul>
+</blockquote>
+<p>2004-01-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (IsImagesEqual): Simplified implementation.</li>
+<li>magick/magick.c: Removed some unused code.</li>
+<li>contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp
+(IDispatch): Comment out InitializeSemaphore() so code compiles.</li>
+<li>libtool.m4: Updated to 2004-01-03 version of CVS libtool. This
+should fix configure problems under AIX and IRIX.</li>
+</ul>
+</blockquote>
+<p>2004-01-03 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:randeg&#37;&#52;&#48;alum&#46;rpi&#46;edu">randeg<span>&#64;</span>alum<span>&#46;</span>rpi<span>&#46;</span>edu</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sgi.c: opacity channel was lost when writing grayscale
+SGI images. See bug report in magick-users list.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2004.rst b/www/ChangeLog-2004.rst
new file mode 100644
index 0000000..4c139d5
--- /dev/null
+++ b/www/ChangeLog-2004.rst
@@ -0,0 +1,1491 @@
+2004-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (DescribeImage): Add normalized channel
+ statistics to output.
+
+ - NEWS: Updated with changes since July.
+
+ - magick/constitute.c (ImportImagePixelArea): For GrayQuantum,
+ GrayInvertedQuantum, GrayAlphaQuantum, and
+ GrayInvertedAlphaQuantum, observe image storage\_class so that a
+ gray DirectClass image may be created.
+
+ - coders/tiff.c (ReadTIFFImage): Fix overflow when computing
+ colormap size for bits-per-sample of 32.
+ (WriteTIFFImage): Support writing 32-bit RGB(A) for
+ QuantumDepth=32 build.
+ (ReadTIFFImage): Support reading 32-bit RGB(A) for QuantumDepth=32
+ build. Support reading 32-bit grayscale without any quality loss
+ for QuantumDepth=32 build.
+
+2004-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): TrueColor 16-bits/sample RGB
+ images were being written incorrectly on little-endian CPUs.
+ Added byte swapping to fix this problem.
+
+2004-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/operator.c: New file for quantum operator implementation.
+ (QuantumOperatorImage): Moved from image.c.
+ (QuantumOperatorRegionImage): Moved from from image.c.
+
+2004-12-22 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ - magick/Makefile.am (MAGICK\_BASE\_SRCS): Remove mention of
+ non-existent mmath.h.
+
+ - configure.ac: AC\_LIBTOOL\_SETUP is an internal macro and must not
+ be used externally (will be pulled in automatically).
+
+ - PerlMagick/Makefile.am: Missing file needed to be committed to CVS.
+
+ - tests/Makefile.am (TESTS\_TIFF\_XFAIL\_TESTS): EPT and PTIF tests
+ are expected to fail if libtiff is missing.
+
+2004-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - TODO.txt: Organized todo list for 1.2 release.
+
+2004-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c (WriteBMPImage): Handle the case where the image
+ has an over-sized colormap. Was writing on unallocated heap memory.
+
+ - coders/dib.c (WriteDIBImage): Handle the case where the image
+ has an over-sized colormap. Was writing on unallocated heap memory.
+
+2004-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/gem.c (Modulate): Hue argument now represents a rotation
+ from -180 degrees to +180 degrees expressed as an argument of 0 to
+ 2.0 (1.0 for no change). Note that this change also effects the
+ -modulate argument and the Magick++ modulate method(). This change
+ is made because the previous hue adjustment strategy only
+ succeeded in corrupting the image.
+
+2004-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (opendir): Ensure that data may not overwrite
+ the stack.
+ (readdir): Ensure that data may not overwrite the stack.
+
+ - magick/blob.c (ImageToBlob): Ensure that image->logging is
+ set prior to encoding image.
+
+ - magick/constitute.c (WriteImage): Ensure that image->logging is
+ set prior to encoding image.
+
+2004-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - rungm.sh.in: Compute final variable definitions from within
+ configure in order to improve MinGW test execution times.
+
+2004-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/gif.c: Fix two error-path memory leaks which were noticed
+ by Glenn Randers-Pehrson.
+
+2004-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c (UnregisterPNGImage): Eliminate Warning: module
+ registration for "JNG" from module "PNG" still present!
+
+2004-11-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (DispatchImage): Fix documentation error
+ regarding return status.
+
+2004-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.h: Only define HAVE\_GLOBALMEMORYSTATUSEX for MSVC
+ 7.0 and later.
+
+2004-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Ensure that words in the
+ scanline are converted to little-endian format on little-endian
+ CPUs.
+
+2004-11-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (MagickStrlCat): New function which is
+ equivalent to to OpenBSD's strlcat() function. Concatenates one
+ string onto another within a fixed size buffer while ensuring null
+ termination.
+ (MagickStrlCpy): New function which is equivalent to OpenBSD's
+ strlcpy() function. Copies a string into a fixed size buffer
+ while ensuring null termination.
+
+ - coders/gif.c (DecodeImage): Improve handling of corrupt GIF
+ files. Resolves SourceForge bug #1042904. Also, eliminate a
+ potential memory leak.
+
+ - magick/constitute.c (WriteImages): ImageInfo argument is now a
+ const pointer.
+
+2004-10-26 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - magick/render.c (TracePath): Applied bugfix from Cristy.
+
+2004-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (InitializeMagickResources): Use
+ GlobalMemoryStatusEx if it is available.
+
+ - magick/nt\_base.c (lt\_dlopen): Handle errors while loading
+ modules rather than allow Windows to display a GUI dialog box.
+ (NTKernelAPISupported): New function to support testing to see if
+ a Windows kernel API is supported.
+
+ - magick/constitute.c (ExportImagePixelArea): Add special-case for
+ bilevel gray image in order to restore performance.
+ (ImportImagePixelArea): Add special-case for bilevel gray image in
+ order to restore performance.
+
+ - coders/jpeg.c (ReadJPEGImage): Fix GCC warning about variable
+ being clobbered by longjmp.
+
+ - Re-port build to MinGW. Modules build passes all tests.
+
+ - Skip build and install of modules if a key library is not available.
+
+ - Partial recode of metadata handling to use Get/Set profile
+ functions. Big job!
+
+ - GCC warnings reduction.
+
+ - Remove MVG detection from magic.mgk due to security risk.
+
+2004-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Properly detect and handle
+ errors reported by libtiff so that failure is reported rather than
+ writing a corrupted output file.
+ (WriteNewsProfile): Re-write so implementation is easier to
+ understand.
+
+2004-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c: Don't use deprecated tiff.h \_SUPPORT defines.
+ Support retrieving and saving XMP profile. Use profile set/get
+ methods in implementation.
+
+ - coders/mat.c,coders/topol.c (ReadBlobWordLSB,ReadBlobDoublesLSB):
+ Use better variable name than `I` for image.
+
+2004-09-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (WriteMIFFImage): Ensure that MIFF files are never
+ written with bogus compression values.
+
+ - magick/image.h: Protected/hid constants which only exist to
+ support the library implementation.
+
+ - tests/Makefile.am (TESTS\_X11\_XFAIL\_TESTS): Fixed syntax error.
+
+ - Makefile.am: Use one Makefile to rule them all as described in
+ Peter Miller's excellent paper, Recursive Make Considered Harmful,
+ "http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html".
+ Some glitches may remain.
+
+ - coders/tiff.c (TIFFErrors): Prevent possible stack overflow on
+ error.
+ (TIFFWarnings): Prevent possible stack overflow on error.
+
+ - magick/constitute.c (ImportImagePixelArea): For RGBQuantum
+ initialize the opacity channel since it is easier than altering
+ all code to properly access it.
+
+2004-09-02 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - magick/transform.c: Bugfix from Cristy in CoalesceImages().
+
+2004-08-26 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - Avoid error introduced in libpng-1.2.6 that causes the encoder
+ to write out-of-spec zlib header bytes.
+
+2004-08-24 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/bmp.c is said to have a potential buffer overrun.
+ Patch from Cristy applied (also to avi.c and dib.c).
+
+2004-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Use ExportImagePixelArea to
+ write grayscale and colormapped output.
+
+ - magick/constitute.c (ImportImagePixelArea): Implemented support
+ for GrayInvertedQuantum & GrayInvertedAlphaQuantum.
+ (ExportImagePixelArea): Implemented support for
+ GrayInvertedQuantum & GrayInvertedAlphaQuantum.
+
+ - magick/constitute.h (enum QuantumType): Added
+ GrayInvertedQuantum & GrayInvertedAlphaQuantum to support
+ min-is-white gray images.
+
+2004-08-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/tiff/write.t: Adjusted file naming.
+
+ - PerlMagick/t/tiff/read.t: Added more tests.
+
+ - coders/tiff.c (ReadTIFFImage): Use ImportImagePixelArea to read
+ PseudoClass tiff.
+ (WriteTIFFImage): Allow user to set the bits-per-sample define to
+ any value in the range of 1 to 32.
+ (ReadTIFFImage): Fix endian-reordering for DirectClass read and
+ bits-per-sample values ranging 9-15.
+
+ - coders/rgb.c: Support reading & writing 32-bit depths for raw
+ RGB images.
+
+ - coders/cmyk.c: Support reading & writing 32-bit depths for raw CMYK
+ images.
+
+ - coders/gray.c: Support reading & writing 32-bit depths for raw gray
+ images.
+
+ - magick/deprecate.c (PopImagePixels): Deprecated function.
+ (PushImagePixels): Deprecated function.
+
+ - magick/constitute.c (ExportImagePixelArea): New function to
+ export pixel region using specified QuantumType and
+ bits-per-sample.
+ (ImportImagePixelArea): New function to import pixel region using
+ specified QuantumType and bits-per-sample.
+
+2004-08-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/cache.c (ClonePixelCache): It appeared that cloning a
+ disk-based pixel cache was limited to the maximum value of
+ size\_t. This would result in a truncated cache. The offset type
+ is changed from size\_t to magick\_off\_t in order to avoid this.
+
+ - configure.ac: Check to see if the `char` type is unsigned,
+ mostly out of curiosity since the code does not currently make use
+ of the result.
+
+ - Fixed many compilation warnings when the compiler warning level
+ is set as high as possible.
+
+ - configure.ac: Check /usr/share/ghostscript/fonts for Ghostscript Type1
+ fonts.
+
+2004-08-13 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - tEXt and zTXt were inadvertently included in list of unused chunks.
+
+2004-08-09 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - fix incorrect argument to png\_set\_keep\_unknown\_chunks().
+
+2004-08-07 David R. Linn <drl@vuse.vanderbilt.edu>
+
+ - www/formats.html: Titles for JNG and MNG were reversed.
+
+2004-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/widget.c (XCommandWidget): Replace ImageMagick logo in
+ display command menu with GraphicsMagick logo.
+
+2004-08-05 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/png.c: Fixes for CERT security alert TA04-217A described
+ at "http://www.us-cert.gov/cas/techalerts/TA04-217A.html".
+
+2004-08-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h (Image): Changed type of `colors` and `depth`
+ members from type `unsigned long` to `unsigned int`. This change
+ is made because on 64-bit CPUs, `unsigned long` is a 64-bit
+ type. The depth member is often used in switch statements. It is
+ not recommended to use 64-bit types in switch statements. The
+ maximum number of colors in the colormap is limited to 64K so a
+ 64-bit type is not required.
+
+2004-08-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Restore previous 8/16
+ bits-per-sample support code in order to regain lost performance.
+
+2004-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Support reading RGB/CMYK scanline
+ oriented TIFF images with arbitrary depth.
+
+2004-07-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Update to Automake 1.9.
+
+2004-07-20 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick\magick\GM\_magick.bpr: Updated to reflect changes since last update.
+
+ - BCBMagick\magick\libMagick.bpr: Updated to reflect changes since last update.
+
+ - BCBMagick\bzlib\GM\_bzlib.bpr: Updated version number.
+
+ - BCBMagick\lcms\BCB6\GM\_lcms.bpr: Updated version number.
+
+ - BCBMagick\Magickpp\lib\GM\_magickpp.bpr: Updated version number.
+
+ - BCBMagick\ttf\GM\_ttf.bpr: Updated version number.
+
+ - BCBMagick\zlib\GM\_zlib.bpr: Updated version number.
+
+ - BCBMagick now support full LZW encoding (read/write).
+
+2004-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff/libtiff/tif\_lzw.c: Replace with version which supports LZW encoding.
+
+ - magick/channel.c: New source file.
+ (ExportImageChannel): New function to export an image channel.
+ (ImportImageChannel): New function to import an image channel.
+
+2004-07-20 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - lcms/src/cmsio1.c: Test [testcms.c] related to lcms 1.13 fail
+ with error #12288 when perform "Checking saved linearization
+ devicelink". Fixed function \_\_cmsSaveProfile(). "...malloc(0) is
+ implementation dependent and may return non NULL pointer on some
+ compilers, like VC++ and gcc. This is not the case of Borland C++
+ Builder" - Thanks to Marti Maria that have supplied me this
+ patched file: this will be part of the next lcms 1.14 which
+ probabily will be released on summer's end.
+
+2004-07-20 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - lcms/include/lcms.h: Modified to achieve BCBMagick DLL compilation.
+ Included modifications was introduced in GM in 2004-01-16 and
+ probabily lost with latest update of library.
+
+2004-07-20 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick: Updated lcms to version 1.13.
+ + Modified files: BCBMagick\All\bcbMagick.mak; BCBMagick\lcms\BCB6\GM\_lcms.bpr;
+ BCBMagick\lcms\BCB6\lcms.bpg; BCBMagick\lcms\BCB6\lcms.bpr;
+ BCBMagick\lcms\BCB6\testcms.bpr
+ + Deleted files: BCBMagick\lcms\BCB6\lcms.cpp; BCBMagick\lcms\BCB6\testcms.cpp
+ + Added file: BCBMagick\lcms\BCB6\lcms.bpf
+
+2004-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Fix typo regarding -define tiff:samples-per-pixel.
+
+ - doc/GNUmakefile (utility-install): Utility HTML targets were not being installed.
+
+2004-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lcms: Updated to version 1.13.
+
+2004-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh (CVS\_BRANCH\_TAG): Record the CVS branch tag that
+ source package is obtained from.
+
+2004-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Pass essential flags on down to subordinate
+ configures when performing `make distcheck`. Support DESTDIR
+ installs for PERL 5.8.1 and later, which support DESTDIR
+ internally.
+
+2004-07-16 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick\coders\libCoders.bpr; BCBMagick\magick\GM\_magick.bpr: include
+ file jbig.h could not be found during compilation. Solved.
+
+2004-07-15 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick\magick\magick\_config.h.: enabled LZW compression by default.
+
+ - BCBMagick: included jbig delegate library.
+ + Modified these files into directory BCBMagick: All\bcbMagick.mak;
+ All\GMlib.bpg; All\GMdll.bpg; coders\libCoders.bpr; magick\GM\_magick.bpr;
+ utilities\gm\_lib.bpr; utilities\gm\_dll.bpr
+ + Added these files into new directory BCBMagick\jbig: jbig.bpr;
+ jbig.bpf; GM\_jbig.bpr; GM\_jbig.c; tstcodec.bpr
+ + Modified file jbig\jbiglib\jbig.h;
+
+ - BCBMagick\readme.txt: updated documentation.
+
+2004-07-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyUsage): -ordered-dither help was
+ formatted incorrectly.
+
+ - doc/options.imdoc: Improve formatting a bit for manual pages and
+ fix some syntax errors.
+
+2004-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS: Updated to reflect changes since last update.
+
+2004-07-09 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/bmp.c (ReadBMPImage): Removed if-test on reading
+ red\_mask, green\_mask, and blue\_mask. These are only \*valid\*
+ under certain conditions, but they are always present in the
+ file.
+
+2004-07-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Enable LZW compression by default.
+
+2004-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (WriteJPEGImage): Don't enable Huffman compression
+ for large images (> 16 Mpixels for the moment) in order to
+ conserve memory. When Huffman compression is enabled the entire
+ image is buffered in memory prior to encoding and writing
+ anything. Huffman compression is a method of eliminating
+ redundant data so when the Huffman compression is disabled, files
+ sizes will be larger, but otherwise the image is the same.
+
+ - wand/magick\_wand.c (MagickSetPassphrase): String was being
+ copied to a null pointer. Now memory is allocated as required
+ prior to a copy.
+ Ensure that all unimplemented functions return a proper error
+ report.
+
+2004-07-01 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick: updated to GraphicsMagick v.1.2
+
+ - BCBMagick\All: project GMlib-1.1.bpr has been replaced with
+ GMlib.bpr
+
+ - BCBMagick\All: project GMdll-1.1.bpr has been replaced with
+ GMdll.bpr
+
+ - BCBMagick\readme.txt: updated documentation.
+
+2004-06-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): For -units, don't reset
+ resolution if units are undefined. Report an error if the -units
+ argument is not supported.
+
+2004-06-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): When setting image units, also
+ adjust existing image x\_resolution and y\_resolution so that
+ existing image resolution is not trashed.
+ (MogrifyImage): When re-sampling an image, report an error if the
+ image does not contain a valid resolution.
+
+2004-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pcx.c (WritePCXImage): Support writing large PCX files.
+ (WritePCXImage): Ensure that UndefinedResolution is handled
+ properly. Avoid round-off error for centimeter based resolution.
+
+2004-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Look for mozilla by default rather than netscape.
+
+2004-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/type.c (ReadTypeConfigureFile): Determine location of
+ Ghostscript fonts only once in order to improve performance.
+
+ - magick/nt\_base.c (NTGhostscriptFonts): Properly determine
+ Ghostscript font location for Ghostscript 8.0 and later.
+
+ - GraphicsMagick.spec.in: Install \*-config scripts with mode 755
+ rather than default 644.
+
+2004-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/module.c (InitializeModuleSearchPath): Evaluate and cache
+ module search path.
+ (FindMagickModule): Use cached module search path.
+ (OpenModules): Load all modules rather than just the modules in
+ the directory where the LOGO module is found. Besides allowing
+ user-provided modules in non-GraphicsMagick directories to be
+ loaded, this allows the "moby" shared build to load additional
+ modules via OpenModules.
+
+2004-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/Makefile.am (check): Add convert -list tests.
+
+2004-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Magick++ needs to be built as a static library
+ under Cygwin and MinGW since C++ exceptions don't work otherwise.
+ Be more assertive about that.
+
+ - magick/nt\_base.h: Avoid conflict with ssize\_t definition under
+ MinGW.
+
+2004-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (DispatchImage): Support 8-bit output to
+ common formats BGR, BGRO, BGRP, RGB, RGBO, and I as special cases
+ in order to improve performance.
+ (ConstituteImage): Support 8-bit input from common formats BGR,
+ BGRO, BGRP, RGB, RGBO, and I as special cases in order to improve
+ performance.
+
+2004-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ltmain.sh: Fix to allow exe wrapper to work under MinGW.
+
+ - wand/magick\_compat.c (QueryMagickColor): Fixed DLL export.
+
+ - wand/magick\_wand.c: Fixed some DLL exports (MagickExport->WandExport).
+
+2004-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageClipMask): Consistently report any
+ exceptions to image->exception.
+
+2004-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Update to Automake 1.8.5.
+
+ - magick/image.h (ImageInfo): New `progress` monitor to indicate
+ if progress monitor and busy cursor are enabled while displaying
+ an image. Defaults to True.
+
+ - magick/display.c, magick/xwindow.c: Use +progress to disable
+ progress monitor and busy cursor.
+
+ - magick/command.c (MogrifyUsage): Usage didn't list -operator.
+ (ConvertUsage): Usage didn't list -operator.
+
+2004-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/compress.c (HuffmanDecodeImage): Properly return error status.
+ (HuffmanEncode2Image): Properly return error status.
+
+ - magick/composite.c (CompositeImage): Properly return error status.
+
+ - magick/quantize.c (ClassifyImageColors): Properly return error status.
+ (GetImageQuantizeError): Properly return error status.
+ (OrderedDitherImage): Properly return error status.
+
+ - magick/profile.c (ProfileImage): Properly return error status.
+
+ - magick/paint.c (ColorFloodfillImage): Properly return error status.
+ (MatteFloodfillImage): Properly return error status.
+ (OpaqueImage): Properly return error status.
+ (TransparentImage): Properly return error status.
+
+ - magick/enhance.c (ContrastImage): Properly return error status.
+ (EqualizeImage): Properly return error status.
+ (GammaImage): Properly return error status.
+ (LevelImage): Properly return error status.
+ (LevelImageChannel): Properly return error status.
+ (ModulateImage): Properly return error status.
+ (NegateImage): Properly return error status.
+ (NormalizeImage): Properly return error status.
+
+ - magick/image.c (GetImageClipMask): New function to retrieve an
+ associated clip-mask image.
+ (SetImageClipMask): Clip-mask image parameter may be const since
+ it is cloned prior to storage.
+ (ChannelImage): Properly return error status.
+ (GradientImage): Properly return error status.
+ (RGBTransformImage): Properly return error status.
+ (TransformRGBImage): Properly return error status.
+ (SyncImage): Return an error status.
+
+ - magick/enhance.c (NegateImage): If image has a clip mask,
+ then force image to DirectClass so clip mask takes effect.
+
+2004-05-15 Vladimir Lukianov <lvm@integrum.ru>
+
+ - magick/image.c (SetImageOpacity): Ensure that image is
+ DirectClass. If specified opacity is TransparentOpacity, then
+ replace existing opacity with TransparentOpacity.
+
+2004-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Avoid duplicated test status messages for \_\_func\_\_
+ tests. Avoid duplicated test status message for jpeg 6b test.
+
+2004-04-19 Patrick Welche <prlw1@newn.cam.ac.uk>
+
+ - www/header.html: HTML syntax fixes.
+
+2004-04-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - : Change web pages to a frames-based design.
+
+2004-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/Makefile.am (check): Change geometry arguments which
+ were expressed as 0.0xVAL to avoid the problematic Linux scanf
+ feature back to 0xVAL.
+
+2004-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/symbols.h (GetMagickDimension): Added GetMagickDimension.
+
+2004-04-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetMagickDimension): New function to replace
+ occurances of scanf(geometry,"%lfx%lf",&w,&h) since Linux scanf()
+ and strtod() misbehave for strings that start with "0x". The Linux
+ versions always treat 0x as the start of a value expressed in hex
+ and can't be forced to read the leading value as a double. This
+ function has been applied globally to replace the problem scanf's.
+
+ - magick/version.h.in: Make it clear in the -version output that a
+ mutitude of copyrights and licenses apply to this software.
+
+ - magick/utility.c (GetPathComponent): Avoid strncpy() of
+ overlapping regions.
+
+ - magick/command.c (DisplayImageCommand): Eliminate double-free
+ of resource\_info->image\_geometry.
+ (DisplayImageCommand): `display` was improperly requiring at least
+ one argument (bug was added yesterday).
+
+2004-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/gm.c (main): Default usage message wasn't right for
+ aliased utility.
+
+ - configure.ac: Added the --enable-magick-compat option to install
+ compatibility links to emulate ImageMagick commands.
+
+ - magick/command.c: Ensure that each sub-command responds to -help
+ and -version appropriately.
+
+ - utilities/gm.c (main): Invoke appropriate sub-command if gm is
+ executed under a traditional alternate name such as "convert". The
+ user may create hard or symbolic links from `gm` to a traditional
+ ImageMagick utility name (or just copy `gm` to the desired
+ sub-command name) in order to be 100% command-line compatible with
+ ImageMagick 5.5.2. This is necessary in order to work with
+ existing software designed to execute ImageMagick utilities.
+
+2004-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/compress.c (Ascii85Tuple): Encoding bug is indeed fixed
+ on DEC Alpha. Also warnings reduction with Digital Unix compiler.
+
+2004-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/compress.c (Ascii85Tuple): Add casts to reduce compiler
+ warnings, and maybe even fix a bug.
+
+ - coders/pdf.c (ReadPDFImage): Double-check that Ghostscript
+ produced an output file since sometimes it reports success after
+ it has spewed an error message and has produced no output.
+
+2004-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/compress.c (HuffmanEncode2Image): Avoid out of bounds
+ array access.
+
+ - magick/studio.h (\_FILE\_OFFSET\_BITS): Fix \_FILE\_OFFSET\_BITS
+ #ifdef to avoid warnings when it is not defined.
+
+2004-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Fix minor shell syntax error (used ==).
+
+2004-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Merged in updates from 1.1 release branch.
+
+ - version.sh (PACKAGE\_VERSION): Release version 1.1.
+ (PACKAGE\_VERSION): Next major release will be 1.1. Bump library
+ versions since we anticipate adding interfaces.
+
+ - magick/studio.h: Disabled use of Windows message lookups
+ entirely since this doesn't seem to work for programs. It
+ probably only works for DLLs like ImageMagickObject.
+
+ - magick/delegate.c (ListDelegateInfo): Don't get stuck in a loop
+ if fprintf() returns zero.
+
+2004-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/\*/\*.bat: Add .exe to exe file names in order to
+ ensure that the executable is executed rather than something else
+ (such as a batch script).
+
+ - magick/locale.c: Only use Windows resource message lookup for
+ the DLL build since it doesn't seem to work for static
+ executables.
+
+ - magick/utility.c (SetClientPath): Ensure that client path is
+ null terminated.
+ (SetClientFilename): Initialize default client filename to ""
+ rather than "gm.exe" and ensure that filename is null terminated.
+ (SetClientName): Ensure that client path is null terminated.
+
+ - magick/blob.c (GetConfigureBlob): Enable logging the load of
+ log.mgk
+
+ - magick/log.c: Re-designed logging initialization in order to
+ avoid the "chicken and the egg" snafu. This allows logging the
+ initialization of the logging subsystem.
+
+2004-04-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/bin/log.mgk: Add comments to help document usage.
+
+ - config/log.mgk: Add comments to help document usage.
+
+ - magick/utility.c (IsAccessible): Use access() rather than stat().
+ (IsAccessibleNoLogging): Use access() rather than stat().
+ (IsDirectory): Implemented return status according to existing API
+ documentation.
+ (GetExecutionPathUsingName): Complete re-write in order to minimize
+ path computation logic and fix failure with partial paths.
+
+2004-03-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Add "Color" to the arguments available for -list.
+
+2004-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh (PACKAGE\_CHANGE\_DATE): Updated version to 1.1Beta3
+
+ - magick/nt\_base.c (NTSystemComman): Have not been successful with using
+ MsgWaitForMultipleObjects() reliably, so back out usage of it for
+ now.
+
+ - magick/fx.c (ConvolveImage): Support convolution in CMYK
+ colorspace.
+
+2004-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh (PACKAGE\_CHANGE\_DATE): Update release to 1.1Beta2.
+
+ - magick/constitute.c (ReadImage): Ignore errors of type
+ ConfigureError when loading modules so that error report can still
+ report the familiar "No delegate for this image format" message
+ while still being able to report problems with loading a module if
+ it was found. This is a compromise which reports useless messages
+ when the modules are not found at all, but I can't think of a way
+ around it.
+
+ - magick/nt\_base.c (NTSystemComman): Adjust
+ MsgWaitForMultipleObjects() arguments to wait for object to be
+ signaled only (FALSE) rather wait for object to be signaled as
+ well as an input event received(TRUE). It seems that process
+ status changes do not result in an input event, so the call was
+ deadlocking.
+
+ - magick/constitute.c (ReadImage): If module loading reported an
+ error, ReadImage immediately returned an error rather than trying
+ to use a delegate defined by delegates.mgk.
+
+2004-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Updated version to 1.1Beta1
+
+2004-03-24 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick/magick/libMagick.bpr: updated to latest source modifications.
+
+ - BCBMagick/magick/GM\_Magick.bpr: updated to latest source modifications.
+
+2004-03-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/plasma.c (ReadPlasmaImage): srand() is already invoked by
+ InitializeMagick() so don't call it here.
+
+ - configure.ac: Check for rand\_r().
+
+ - magick/tempfile.c (ComposeTemporaryFileName): The full range of
+ safe characters was not being used, thereby limiting the number of
+ unique temporary file names available.
+
+2004-03-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (GetImageStatistics): New function to obtain
+ image statistics (minimum, maximum, mean, variance, and standard
+ deviation).
+ (DescribeImage): Include image channel statistics in verbose
+ output.
+
+2004-03-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (DispatchImage): Removed some unreachable
+ code that was accidentially left in the switch statement.
+
+ - magick/pixel\_iterator.c (PixelIterateDualRead): Extended so that
+ the region in each image may use a different origin.
+ (PixelIterateDualModify): Extended so that
+ the region in each image may use a different origin.
+
+ - magick/composite.c (CompositeImage): Fix XorCompositeOp overflow
+ condition which occured on non-Intel architectures.
+
+2004-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS: Updated with changes up to today's date.
+
+ - tests/constitute.c (main): Float type seems to require allowing
+ a bit of error for Q:32.
+
+ - magick/constitute.c (DispatchImage): Be more careful when
+ rounding pixel intensity.
+ (ConstituteImage): Be more careful when converting float and
+ double to Quantum.
+
+ - magick/composite.c (CompositeImage): Fix Multiply composite
+ operator for Q:32 build (was all black image).
+ (CompositeImage): Tidied up the documented composite operators so
+ the implementation is easier to understand.
+
+ - PerlMagick/t/ttf/read.t: Set a desired label size so output
+ image should be the same size as the reference image even if the
+ FreeType type hinter is disabled.
+
+ - magick/annotate.c (RenderFreetype): Improve outline bounding box
+ computation accuracy.
+
+2004-03-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/x/write.t: Don't test X11 if DISPLAY is not set.
+
+ - PerlMagick/t/x/read.t: Don't test X11 if DISPLAY is not set.
+
+2004-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/Makefile.am: Removed some apparently unnecessary library
+ dependencies.
+
+ - Makefile.am (windows-src): Added a way to generate a Windows
+ source zip file.
+
+2004-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: The -operator command now supports
+ floating-point and percent of range arguments.
+
+2004-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Added support for -operator command with
+ syntax "-operator channel operator rvalue" which applies a
+ arithmetic or bitwise operator to a specified image channel
+ or all channels.
+
+2004-03-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/filter.t: Fix Solarize test case.
+
+ - PerlMagick/t/wmf/read.t: Added another WMF test case.
+
+ - coders/wmf.c: Resolve WMF rendering bug with black color.
+
+ - magick/utility.c (StringToArgv): Free argv data prior to error
+ return.
+
+2004-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (WriteJPEGImage): If image\_info->colorspace is set
+ to GRAYColorspace then make sure that image is in a gray
+ colorspace.
+
+ - magick/image.c (TransformRGBImage): If colorspace is already an
+ RGB type (RGBColorspace, GRAYColorspace, or TransparentColorspace),
+ then simply return. Do \*not\* set image->colorspace to RGBColorspace
+ since this potentially loses a valuable setting.
+
+2004-03-10 Peter Boos <pedib@colorfullife.com>
+
+ - magick/annotate.c (RenderFreetype): If DrawAnnotation is called
+ with a string containing only one character and this character is
+ not recognized by the TrueType engine, a crash occured due to the
+ failure of FT\_Load\_Glyph. The failure caused an uninitialized
+ glyph.image pointer to be used by FT\_Done\_Glyph() later in the
+ code. The solution is to initialize the glyph.image pointer to
+ null.
+
+2004-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (QuantumOperatorRegionImage): Properly handle
+ over and underflow of arithmetic operators.
+
+ - magick/draw.c (DrawGetFillOpacity): Use fill opacity, and invert
+ opacity range so it is 0.0 to 1.0 (was acting like transparency).
+ (DrawSetStrokeOpacity): Validate range of stroke\_opacity.
+ (DrawSetFillOpacity): Save value to context->fill.opacity and
+ validate the range of fill\_opacity.
+
+ - magick/image.c (QuantumOperatorImage): New function to apply an
+ arithmetic or bitwise operator to the pixel quantums in an image.
+ (QuantumOperatorRegionImage): New function to apply an arithmetic
+ or bitwise operator to the pixel quantums in an image region.
+
+ - magick/image.c (IsImagesEqual): Re-implemented using the new
+ pixel iteration functions as a proof of concept.
+
+ - magick/pixel\_iterator.h: Added some pixel iteration functions in
+ order to make it easier to implement algorithms which only need to
+ iteratively access pixels in a region. These functions are not
+ part of the API yet so their interface should be considered
+ unstable.
+
+ - doc/GNUmakefile: Rename Makefile to GNUmakefile since it relies
+ on GNU make extensions.
+
+2004-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ConstituteImage): Add support for `T`
+ (transparency) and `O` (opacity) map types. Simplify
+ implementation.
+ (DispatchImage): Add support for `T` (transparency) and `O`
+ (opacity) map types. Simplify implementation.
+
+ - config/delegates.mgk.in: Quote delegate command names so
+ that they can contain embedded spaces.
+
+ - VisualMagick/bin/delegates.mgk: Quote delegate command names so
+ that they can contain embedded spaces.
+
+ - coders/tiff.c (WriteTIFFImage): Use the libtiff default endian
+ mode when writing TIFF rather than forcing MSB2LSB bit order.
+ (ReadTIFFImage): Enable reading in MSB2LSB bit order (better for
+ our byte-level parsing), enable memory mapping, and enable strip
+ chopping. Memory mapping and strip chopping are probably enabled
+ by default.
+
+ - magick/nt\_base.c (NTSystemComman): Use
+ MsgWaitForMultipleObjects() rather than WaitForSingleObject() in
+ order to avoid possible deadlock when application code directly or
+ indirectly creates windows.
+
+2004-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/animate.c (XMagickCommand): URL should point to
+ http://graphicsmagick.org/.
+
+ - magick/display.c (XMagickCommand): URL should point to
+ http://graphicsmagick.org/.
+
+ - magick/image.c (DisplayImages): Changes to fix memory leaks in
+ X11 commands had bugs which seriously broke DisplayImages. Now
+ DisplayImages works properly again.
+
+ - magick/xwindow.c (XDestroyResourceInfo): New function to destroy
+ XResourceInfo.
+
+ - coders/x.c (WriteXImage): Implement based on DisplayImages().
+ (RegisterXImage): Always register X coder, but with read/write
+ support disabled if X11 not available.
+
+2004-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ImportImageCommand): Eliminate memory leaks.
+
+ - magick/memory.c (LiberateMemory): Use MagickFreeMemory macro for
+ implementation.
+ (ReacquireMemory): Use MagickReallocMemory macro for
+ implementation.
+ (AcquireMemory): Use MagickAllocateMemory for implementation.
+
+2004-02-26 Vladimir <lvm@integrum.ru>
+
+ - magick/memory.c (CloneMemory): Fixes to compile under Microsoft
+ Visual C++ 6.0.
+
+2004-02-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/animate.c (XAnimateImages): Memory leak reduction and
+ better integration with gm command.
+
+ - magick/display.c (XDisplayImage): Display was leaking memory
+ like a sieve. Now it doesn't.
+
+ - magick/memory.c (CloneMemory): Computation for when it is safe
+ to use memcpy() was incorrect. Use memmove() rather than
+ backwards-copy loop.
+
+ - Makefile.am ($(DIST\_ARCHIVE\_SRPM)): Added rules to build a
+ source RPM.
+
+ - configure.ac: Search for `buildrpm` or `rpm` programs in order to
+ support creating RPM packages on a system which has RPM installed.
+
+ - version.sh (PACKAGE\_VERSION): Changed snapshot release naming so
+ that there is only one dash in the name and the snapshot date is
+ prefixed with `0` to assure proper directory sorting. This allows
+ snapshot naming to be acceptable to RPM. The snapshot package
+ name is now similar to GraphicsMagick-1.1.020040218.tar.bz2
+
+2004-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xwd.c (RegisterXWDImage): Always register XWD, but only
+ register read/write methods if it is supported.
+
+ - wand/magick\_wand.c: Synchronized with latest ImageMagick API
+ changes.
+
+2004-02-16 Lars Ruben Skyum <lars.skyum@stibo.com>
+
+ - magick/resize.c (HorizontalFilter): Fixed: do process K channel
+ for CMYK images.
+ (VerticalFilter): do process K channel for CMYK images.
+
+2004-02-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tga.c (ReadTGAImage): Fix matte channel handling. For
+ 16-bit packets, use integer rather than floating point. Return
+ gray images as PseudoClass and set is\_grayscale flag. Add
+ logging.
+
+ - magick/fx.c (WaveImage): Ensure that image is
+ DirectClass. Ensure that matte channel is initialized if
+ necessary. Include background color in is\_grayscale evaluation.
+
+ - magick/gem.c (GenerateNoise): Scale noise to range of quantum.
+
+2004-02-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (WriteJP2Image): Support passing all documented
+ Jasper options using -define.
+
+2004-02-13 Peter Boos <pedib@colorfullife.com>
+
+ - coders/wmf.c (util\_draw\_arc): Fixes to improve handling for pie,
+ arc, and chord. These fixes produce correct output for
+ wmf/examples/fjftest.wmf, but it is not known if they are correct
+ for all cases.
+
+2004-02-12 Tim Hunter <cyclists@nc.rr.com>
+
+ - magick/profile.c (SetImageProfile): Bug fixes.
+
+2004-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xpm.c (UnregisterXPMImage): Unregister PICON registration.
+
+2004-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/Makefile.am (label\_la\_LDFLAGS): Add a dependency on the
+ math library since floor() is used.
+
+ - wand/magick\_wand.c (MagickRemoveImageProfile): Use C comments in
+ C files.
+
+ - magick/constitute.c (MapQuantumType): Fix spurious comma in
+ enum definition.
+
+ - magick/blob.c (GetBlobStreamHandler): Apparently return type can
+ not be const.
+
+2004-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Check for Windows fonts under
+ /usr/X11R6/lib/X11/fonts/truetype (XFree86 standard location?).
+
+ - coders/jp2.c (WriteJP2Image): Support providing a compression
+ rate value (range 0.0 to 1.0) using command line syntax similar to
+ `-define jp2:rate=0.5`. In Magick++ this option may be accessed
+ similar to image.defineValue("jp2","rate","0.5");
+
+ - magick/command.c (DisplayImageCommand): Exit status was inverted
+ so `gm display` was returning 1 for successful commands, and 0 for
+ failures.
+ (AnimateImageCommand): Exit status was inverted so `gm animate`
+ was returning 1 for successful commands, and 0 for failures.
+
+2004-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.h (MagickReallocMemory): Solaris compiler
+ complains about cast so remove it.
+
+ - coders/xwd.c (WriteXWDImage): Right-size the pixels buffer and
+ tune writer loops a bit.
+
+ - magick/color.h (VerifyColormapIndex): Improve diagnostics.
+
+ - coders/pict.c (WritePICTImage): Eliminate use of uninitialized
+ data when writing RGB PICT. Fix OpenBlob assertion when writing
+ JPEG PICT.
+ (ReadPICTImage): Validate `tile\_image` colormap indexes rather
+ than `image` colormap indexes. Preserve compression attribute from
+ tile image.
+
+ - magick/constitute.c (DispatchImage): Don't access image opacity
+ channel unless image->matte is True.
+
+2004-02-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c (UnregisterPNGImage): Destroy PNG semaphore.
+
+ - magick/image.c (SetImageInfo): Since we don't know what the
+ "IMPLICIT" specifier is supposed to do, support for it is
+ removed. Perhaps by removing support for it, we will be reminded
+ why it exists.
+
+ - magick/magick.c (DestroyMagickInfo): Invoke
+ UnregisterStaticModules().
+ (GetMagickInfo): Remove registration for "IMPLICIT" format since
+ its purpose is presumed bogus.
+
+ - magick/static.c (UnregisterStaticModules): New function so we
+ can unregister static modules.
+
+ - coders/plasma.c (UnregisterPLASMAImage): Unregister FRACTAL.
+
+ - coders/icon.c (UnregisterICONImage): Unregister CUR.
+
+ - coders/bmp.c (UnregisterBMPImage): Unregister BMP2 and BMP3.
+
+ - coders/meta.c (UnregisterMETAImage): Unregister APP1JPEG, IPTC,
+ IPTCTEXT, IPTCWTEXT, and PICON.
+
+ - coders/miff.c: Check for run-length termination before testing
+ memory and only check opacity channel if matte is valid.
+
+ - magick/compress.c: Check for run-length termination before
+ testing memory (bad read error).
+
+2004-02-07 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/bmp.c: Fix off-by-one error while initializing padding bytes.
+
+ - coders/dib.c: Fix off-by-one error while initializing padding bytes.
+
+ - magick/enhance.c: MaxMap vs MaxRGB error fixed. Reported by Cristy.
+
+2004-02-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - magick/compress.c: avoid a reference to uninitialized data.
+
+2004-02-04 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/dib.c: initialize padding bytes.
+
+2004-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/montage.c (MontageImages): Fix leak of texture image (big
+ leak).
+
+2004-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Fix detection of when to use a
+ temporary file when writing TIFF. Writing to TIFF BLOBs was
+ broken by the recent changes to make BlobInfo a private type.
+
+ - magick/render.c (DestroyEdge): Use memmove for overlapping copy.
+
+2004-02-03 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/bmp.c: initialize padding bytes.
+
+2004-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ConstituteImage): Added map support for `P`,
+ in order to skip over a pad quantum.
+ (DispatchImage): Added map support for `P`, in order to write a pad
+ quantum.
+
+ - magick/resize.c (HorizontalFilter): Don't process opacity
+ channel unless matte is enabled.
+ (VerticalFilter): Don't process opacity channel unless matte is
+ enabled.
+
+ - magick/compress.c (Ascii85Initialize): Don't overwrite an
+ existing ascii85 allocation.
+
+ - magick/utility.c (Strip): Use `memmove` rather than `memcpy` to
+ copy overlapping data.
+
+ - tests/rwfile.c (main): Fix memory leak in test. Only apply size
+ if format requires it.
+
+ - tests/rwblob.c (main): Fix memory leak in test. Only apply size
+ if format requires it.
+
+ - coders/mono.c (RegisterMONOImage): Mono is a raw format.
+
+ - magick/magic.c (GetMagicInfo): Ensure that magic tests are
+ within the range of header data which was read.
+
+2004-02-02 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/bmp.c: fix potential use of uninitialized data.
+
+ - coders/png.c: fix potential use of uninitialized data.
+
+2004-01-31 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - magick/studio.h: Fixed problem related to DLL version of BCBMagick.
+ Sometimes was incorrectly checked the presence of VC++ DLL. Thanks
+ very much to Oliver Bertini for bringing this problem to our attention.
+
+ - BCBMagick: added libpng delegate library in both static and DLL
+ modes.
+
+ - BCBMagick: removed all unuseful files from CVS.
+
+2004-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (CloneDrawInfo): Fixed nasty memory leak which
+ becomes painfully evident when using Magick++.
+
+ - magick/type.c (ReadTypeConfigureFile): Fix problem with parsing
+ <include> directive.
+
+ - configure.ac: The type.mgk generated had a syntax error.
+
+ - magick/effect.c (SpreadImage): Eliminate read from uninitialized
+ memory.
+
+ - magick/quantize.c (NodeInfo): Store nodes in a list similar to
+ ImageMagick.
+ (DestroyCubeInfo): Eliminate a small memory leak.
+
+2004-01-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/montage.c (MontageImages): Free thumbnails once they are
+ no longer needed (big leak).
+
+ - magick/blob.c (OpenBlob): Ensure that magick array is
+ fully initialized, even if the fread() is short.
+
+ - magick/list.c (ImageListToArray): Add a null pointer to the end
+ of the image list to serve as a handy list terminator.
+
+ - magick/tempfile.c (DestroyTemporaryFiles): Fix memory leak of
+ semaphore.
+
+ - magick/map.c (MagickMapDeallocateMap): Fix memory leak of
+ semaphore.
+
+ - coders/png.c (WriteOneJNGImage): Use DestroyBlob.
+
+ - magick/list.c (SyncNextImageInList): Use DestroyBlob.
+
+ - magick/image.c (AllocateNextImage): Use DestroyBlob.
+ (DestroyImage): DestroyBlob.
+
+ - coders/wpg.c (ExtractPostscript): Use DestroyBlob.
+
+ - magick/blob.c (DestroyBlob): New function. Similar to
+ DestroyBlobInfo except that it requires an Image \* argument and
+ zeros the blob pointer. This one is preferred for use over
+ DestroyBlobInfo.
+
+2004-01-27 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/png.c: Add DestroyBlobInfo() calls to stop memory leak when
+ processing JNG datastreams.
+
+2004-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.h (MagickReallocMemory): Added a cast required to
+ make C++ Happy.
+
+ - coders/tiff.c: Adjust for bitstream API function renaming.
+
+ - magick/bit\_stream.h: Rename BitStreamRead() to
+ BitStreamMSBRead() to indicate that it reads most significant bytes
+ first ("big endian" order). Rename BitStreamWrite() to
+ BitStreamMSBWrite() to indicate that it writes most significant
+ bytes first ("big endian" order).
+
+ - wand/magick\_wand.c: Updated to lastest ImageMagick API.
+
+2004-01-26 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - magick/stream.c: (SetPixelStream) removed "const" from definition of
+ local variable [StreamHandler stream]. Borland C++Builder compiler signal
+ error "Cannot modify a const object".
+
+2004-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (TIFFMapBlob): Allow libtiff to access memory
+ mapped file (or BLOB in memory) directly. This provides a small
+ performance increase.
+
+ - magick/constitute.c (ReadImage): If a .mpc file is a temporary
+ file, then be sure to remove the associated .cache file when
+ removing the .mpc file.
+
+ - magick/log.h (LogEventType): ExceptionEventMask now maps to
+ WarningEventMask|ErrorEventMask|FatalErrorEventMask so that
+ `-debug exception` works again.
+
+ - magick/blob.c (CloseBlob): Allow CloseBlob to be invoked on a
+ blob which is not open (in UndefinedStream state).
+ (BlobInfo): The definition of BlobInfo is now private to blob.c.
+ (StreamType): The StreamType enumeration is now private to blob.c.
+ (GetBlobFileHandle): New function to access the blob file handle.
+ (GetBlobStreamHandler): New function to access the blob stream
+ handler.
+ (GetBlobStreamType): This function is removed entirely.
+ (BlobIsSeekable): New function to test if SeekBlob will work
+ properly for this blob type.
+ (GetBlobClosable): New function to test if the blob is allowed to
+ be closed by the library (may be an externally provided file
+ descriptor).
+ (GetBlobTemporary): New function to test if input file is a
+ temporary file which is to be removed.
+ (SetBlobClosable): New function to support setting the flag which
+ keeps the input file from being closed.
+ (SetBlobTemporary): New function to support setting the flag which
+ indicates that the input file is a temporary file.
+
+ - coders/jpeg.c (ReadJPEGImage): Invoke CloseBlob even if
+ blob is in UndefinedStream state.
+
+ - magick/error.h (ThrowReaderException): Ditto.
+ (ThrowWriterException): Ditto.
+ (ThrowWriterException2): Ditto.
+ (ThrowWriterException3): Ditto.
+
+ - magick/tempfile.h (ThrowReaderTemporaryFileException): Ditto.
+ (ThrowWriterTemporaryFileException): Ditto.
+
+ - coders/dps.c,coders/jpeg.c, coders/meta.c, coders/mvg.c,
+ coders/png.c, coders/tiff.c, magick/constitute.c, magick/stream.c:
+ Use new blob accessor functions.
+
+ - magick/cache.c (OpenCache): For Windows, set the sequential
+ access flag in all cases. Maybe it will make a difference.
+
+2004-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (GetConfigureBlob): Don't check Windows registry
+ if MagickLibConfigPath or MagickShareConfigPath is defined.
+
+ - magick/locale.c: Use a Unix-style message database for MinGW.
+
+ - rungm.sh.in: Translate environment paths to Windows format when
+ running under MinGW.
+
+ - magick/nt\_base.c (mmap): Re-wrote mmap emulation to support
+ 64-bit file offsets and to support anonymous mapping.
+ (msync): A crude emulation of Unix msync().
+
+ - acinclude.m4 (GM\_FUNC\_MMAP\_FILEIO): Change result define from
+ HAVE\_MMAP to HAVE\_MMAP\_FILEIO so that it doesn't conflict with
+ Autoconf standard definition.
+
+2004-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/cache.c (OpenCache): While allocating the pixel cache
+ from the heap, reserve enough memory to contain a full PseudoClass
+ image in order to reduce the chance that there will be a memory
+ allocation failure while processing the image. This also avoids
+ the possibility that the image pixels will be block-copied to a
+ new location due to heap memory fragmentation. If there is
+ insufficient heap memory (malloc() fails), then a disk-based pixel
+ cache will be used.
+
+ - coders/wpg.c: Backed out Jaroslav Fojtik's patch from 2004-01-13
+ because WPG was failing PerlMagick's existing WPG read test.
+
+2004-01-16 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick: updated to recent Windows delegate libraries.
+
+ - BCBMagick: modified build procedure. Removed all unused directories
+ and include files.
+
+ - lcms/include/lcms.h: Modified to achieve BCBMagick compilation.
+
+ - tiff/libtiff/tiffio.h: Modified to achieve BCBMagick compilation
+
+ - ttf/include/freetype/config/ftoption.h: Modified to achieve
+ BCBMagick compilation
+
+ - Magick++/lib/Magick++/Include.h: Modified to achieve BCBMagick compilation.
+
+2004-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wpg.c: Applied patch from Jaroslav Fojtik to support
+ reading the CTM (current transform matrix). The CTM is not
+ applied yet (expect later patch).
+
+2004-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sfw.c (ReadSFWImage): Added size\_t cast.
+
+ - coders/msl.c (MSLStartElement): Added size\_t cast.
+
+ - coders/meta.c (convertHTMLcodes): Added size\_t cast.
+
+ - coders/locale.c: Add size\_t casts and update to use memory
+ allocation macros.
+
+ - coders/html.c (WriteHTMLImage): Added size\_t cast.
+
+ - magick/utility.h (MagickAllocateMemory): Added size\_t cast.
+ (MagickReallocMemory): Added size\_t cast.
+
+ - coders/bmp.c (WriteBMPImage): Added size\_t cast.
+
+ - coders/art.c (ReadARTImage): Use memory allocation macros.
+
+ - VisualMagick/configure/configure.cpp: Update to support library
+ .def exports files with Visual C++ 7.0.
+
+ - Updated Windows delegate libraries: LCMS 1.12, FreeType 2.1.5,
+ BIG-KIT 1.5, libpng 1.2.5, libwmf 0.2.8.2, and zlib 1.2.1.
+
+ - Verified Windows static and DLL compilation with Visual C++ 6.0.
+
+ - Makefile.am: Update to automake 1.8.2.
+
+ - coders/gif.c (WriteGIFImage): Use ColorMatch rather than
+ FuzzyColorMatch when comparing colormap entries.
+
+2004-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/profile.c: Needed to include "magick/profile.h" in order
+ to obtain prototypes.
+
+2004-01-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/wandtest.c: Change MagickCloneWand to MagickGetImage since
+ the API name changed.
+
+ - wand/pixel\_wand.c: Synchronized with
+ latest daily ImageMagick updates.
+
+ - wand/magick\_wand.c (MagickRemoveImageProfile): Synchronized with
+ latest daily ImageMagick updates.
+
+ - magick/profile.c (DeleteImageProfile): New method to make
+ it easier to destroy an image profile.
+
+ - magick/profile.h: New source file to contain functions for
+ dealing with embedded image profiles.
+
+ - magick/profile.c: New source file to contain functions for
+ dealing with embedded image profiles.
+
+ - Makefile.am (DISTDIRS): Distribute TclMagick subdirectory.
+
+2004-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c: Ported over the latest ImageMagick Wand API
+ updates. Note that a comment now says that the Wand API will not
+ be finished until around 4th quarter of 2004. This represents a
+ 1-1/2 year slip from the original estimate!
+
+2004-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (IsImagesEqual): Simplified implementation.
+
+ - magick/magick.c: Removed some unused code.
+
+ - contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp
+ (IDispatch): Comment out InitializeSemaphore() so code compiles.
+
+ - libtool.m4: Updated to 2004-01-03 version of CVS libtool. This
+ should fix configure problems under AIX and IRIX.
+
+2004-01-03 Glenn Randers-Pehrson <randeg@alum.rpi.edu>
+
+ - coders/sgi.c: opacity channel was lost when writing grayscale
+ SGI images. See bug report in magick-users list.
+
diff --git a/www/ChangeLog-2005.html b/www/ChangeLog-2005.html
new file mode 100644
index 0000000..0cd093c
--- /dev/null
+++ b/www/ChangeLog-2005.html
@@ -0,0 +1,1064 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2005-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff: Update to libtiff 3.8.0.</li>
+</ul>
+</blockquote>
+<p>2005-12-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: Updated with latest changes.</li>
+<li>tiff: Update to libtiff 3.7.4.</li>
+</ul>
+</blockquote>
+<p>2005-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lcms: Update to lcms 1.15.</li>
+</ul>
+</blockquote>
+<p>2005-12-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enhance.c (LevelImage): Fix -level command parsing when a
+percent symbol is supplied within the argument rather than at the
+end.</li>
+<li>magick/utility.c (GetGeometry): Bounds-check geometry string
+length.</li>
+</ul>
+</blockquote>
+<p>2005-12-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Decided to swap 10-bit subsampled 4:2:2 YCbCr by
+default since this is what practically all sample files I have
+been provided actually do. Ignore the fact that there is nothing
+in the standard which supports this.</li>
+</ul>
+</blockquote>
+<p>2005-12-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (NormalizeSamplingFactor): Generalized
+subsampling notation parsing support.</li>
+</ul>
+</blockquote>
+<p>2005-12-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (NormalizeSamplingFactor): Add some support for
+normalizing industry-standard subsampling notation (e.g. 4:2:2)
+into GraphicsMagick's unusual notation.</li>
+</ul>
+</blockquote>
+<p>2005-12-06 Ralf Wildenhues &lt;<a class="reference external" href="mailto:Ralf&#46;Wildenhues&#37;&#52;&#48;gmx&#46;de">Ralf<span>&#46;</span>Wildenhues<span>&#64;</span>gmx<span>&#46;</span>de</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updates to use latest development autotools, including
+development libtool 2.0.</li>
+</ul>
+</blockquote>
+<p>2005-12-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h: Added some useful macros for accessing
+PixelPacket members in a generic way.</li>
+<li>coders/dpx.c (ReadDPXImage): For YCbCr with <cite>A</cite> sample, <cite>A</cite>
+sample levels are like Luma.
+(WriteDPXImage): For YCbCr with <cite>A</cite> sample, <cite>A</cite> sample levels are
+like Luma.</li>
+</ul>
+</blockquote>
+<p>2005-12-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (RegisterTIFFImage): Report libtiff release
+version rather than ABI version.</li>
+</ul>
+</blockquote>
+<p>2005-11-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c: Revert yesterday's benign-appearing edits since
+they caused a bizzare bug.</li>
+</ul>
+</blockquote>
+<p>2005-11-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): Improve performance when reading
+YCbCr files. Handle files which use Printing Density on top of
+YCbCr. Default YCbCr to Rec.709 if the transfer characteristic is
+User Defined.</li>
+<li>coders/pcd.c (Upsample): Moved Upsample from gem.c to here since
+PCD is the only user and it is not a general purpose function.</li>
+</ul>
+</blockquote>
+<p>2005-11-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/magick/magick_config.h.in: Remove unnecessary test
+for WIN32.</li>
+</ul>
+</blockquote>
+<p>2005-11-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_compat.c (FormatMagickStringList): MagickExport since this
+function is used by Ch extension.</li>
+<li>magick/log.c (LogMagickEventList): MagickExport since this
+function is used by Ch extension.</li>
+<li>magick/utility.c (FormatStringList): MagickExport since this
+function is used by Ch extension.</li>
+<li>coders/dpx.c (ReadDPXImage): Added support for dpx:swap-samples
+define in order to handle files with Cb and Cr swapped. Fixed a
+bug in the header reading which caused some valid files to fail to
+read at all.
+(WriteDPXImage): Added support for dpx:swap-samples define in
+order to write files with Cb and Cr swapped.</li>
+<li>magick/profile.c (ProfileImage): Add support for ICC CMS
+profiles in YCbCr space.</li>
+</ul>
+</blockquote>
+<p>2005-10-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/svg.c (ReadSVGImage): Eliminate memory leak.</li>
+</ul>
+</blockquote>
+<p>2005-10-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.h (Image): Added an orientation member to the Image
+structure to record image orientation for the DPX, and TIFF
+formats. Eventually formats which support IPTC and EXIF embedded
+profiles should be supported by the orientation member as well.</li>
+</ul>
+</blockquote>
+<p>2005-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/magick/magick_types.h.in: Add patch for Ch.</li>
+<li>magick/command.c (TransmogrifyImage): Complete re-write of
+mogrify file handling. Former version wrote to a temporary file
+and then moved temporary file to replace original if necessary.
+New version moves an existing writable file to a backup file with
+tilde (<cite>~</cite>) added to end of file name, writes to the final output
+file name, and removes the backup file on success. The new
+approach satisfies formats which embed the output name in the file
+(e.g. the DPX format) and still works when the output file exists
+and is writeable, but is in non-writeable directory. The previous
+approach would fail if the output file exists and is writable, but
+the directory is not writeable.</li>
+</ul>
+</blockquote>
+<p>2005-10-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (AttributeToString): Use strncpy rather than
+strlcpy to copy string. This is important since DPX header
+strings are not null terminated and may need to fill all available
+space. Certain short header fields like mp.film.manufacturer.id,
+mp.film.type, and mp.perfs.offset were being truncated!</li>
+</ul>
+</blockquote>
+<p>2005-09-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GetImageAttribute): Add more general support
+for retrieving wildcarded attributes so that an identify -format
+specification like <cite>%[dpx:*]</cite> works as expected.</li>
+<li>coders/tiff.c (WriteTIFFImage): Transform quality value into zip
+compression quality level similar to what is done for MIFF/MNG/PNG.
+Since default quality value is 75, this means that the default zip
+quality level is 7.</li>
+</ul>
+</blockquote>
+<p>2005-09-24 Peter Wu &lt;<a class="reference external" href="mailto:peterw&#37;&#52;&#48;softintegration&#46;com">peterw<span>&#64;</span>softintegration<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Incorporate changes necessary so that GraphicsMagick can work
+with the Ch C/C++ interpreter from SoftIntegration at
+<a class="reference external" href="http://www.softintegration.com/">http://www.softintegration.com/</a>.</li>
+</ul>
+</blockquote>
+<p>2005-09-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c: Incorporate all functionality from
+cache.c, cache_view.c, and stream.c so that all private interfaces
+can be fully hidden. As a result cache.c, cache_view.c, and
+stream.c are now removed.</li>
+</ul>
+</blockquote>
+<p>2005-09-18 Michal Kowalczuk &lt;<a class="reference external" href="mailto:sammael&#37;&#52;&#48;brzydal&#46;eu&#46;org">sammael<span>&#64;</span>brzydal<span>&#46;</span>eu<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gif.c: Free global_colormap before returning with error.</li>
+</ul>
+</blockquote>
+<p>2005-09-18 Stepan Kasal &lt;<a class="reference external" href="mailto:kasal&#37;&#52;&#48;ucw&#46;cz">kasal<span>&#64;</span>ucw<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (BUILT_SOURCES): Removed.</li>
+<li>magick/Makefile.am (MAGICK_BUILT_SRCS): Removed, too.</li>
+</ul>
+</blockquote>
+<p>2005-09-12 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c (ProfileImage): Free color_profile-&gt;name
+and iptc_profile-&gt;name when destroying the profile.</li>
+</ul>
+</blockquote>
+<p>2005-08-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/api.h: Eliminate requirement to include certain system
+headers prior to including &lt;magick/api.h&gt;.</li>
+<li>utilities/gm.c: Move utility implementation to GMCommand() in
+command.c</li>
+</ul>
+</blockquote>
+<p>2005-08-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Added support for reading and writing DPX Luma
+files using proper video levels.</li>
+<li>magick/colorspace.h (enum ColorspaceType): Decided that
+GRAYColorspace should be reserved for full-range grayscale data
+while Rec601LumaColorspace and Rec709LumaColorspace should be for
+video colorspaces. Therefore, GRAYColorspace is no longer a
+synonym for Rec601LumaColorspace.</li>
+<li>magick/colorspace.c: Added support for influencing Cineon Log
+colorspace transformations via image attributes.
+Perform colorspace transformations in floating point rather than
+integer in order to reduce the amount of noise added by
+transform table quantization.</li>
+<li>coders/psd.c (WritePSDImage): Ensure that output image is 8 or
+16-bits regardless of specific image depth.</li>
+<li>coders/dpx.c: Added support for planar YCbCr 4:2:2.</li>
+</ul>
+</blockquote>
+<p>2005-08-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): 10 and 12-bit packed data was not
+according to DPX specification. Added dpx:pixel-endian={lsb|msb}
+to allow the user to specify the endian order of the pixel data in
+case it does (or should not) not match the headers. Library Of
+Congress format is 10-bit packed data in big-endian format, but is
+marked as little-endian.</li>
+</ul>
+</blockquote>
+<p>2005-08-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Sample order for filled 10 bit samples matches DPX
+specification (was intentionally reversed). RGB sample order is
+changed to match DPX specifiation (i.e. BGR rather than RGB).
+Disabled special support for Library Of Congress little-endian
+10-bit packed format.</li>
+</ul>
+</blockquote>
+<p>2005-08-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Extend all image rows to a 32-bit integer
+boundary.</li>
+</ul>
+</blockquote>
+<p>2005-07-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Support the little-endian 10-bit packed format as
+used by the Library Of Congress.</li>
+</ul>
+</blockquote>
+<p>2005-07-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c: Change how Jasper is intialized. Hopefully
+eliminate memory leak when reading ICC color profile.</li>
+<li>Overall: Compilation warning elimination with GCC 4.0.1.</li>
+<li>magick/utility.c (SystemCommand): Always report error status if
+a command fails.</li>
+</ul>
+</blockquote>
+<p>2005-07-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>zlib: Updated to version 1.2.3.</li>
+<li>coders/dpx.c: Use TriangleFilter for scaling chroma.</li>
+</ul>
+</blockquote>
+<p>2005-07-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Support proper encode and decode of YCbCr video
+levels.</li>
+<li>magick/colorspace.c: Support Rec709YCbCrColorspace colorspace.</li>
+</ul>
+</blockquote>
+<p>2005-07-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/{animate.c, display.c, import.c, xwindow.c}: Rename all
+symbols starting with <cite>X</cite> so that they are prefixed with <cite>Magick</cite>.
+This eases maintenance since it is almost impossible to understand
+code which pretends to be the X11 libraries. The few programs
+which use the GraphicsMagick <cite>X</cite> functions will need to alter the
+symbol names they use. Sorry.</li>
+<li>magick/command.c (DisplayImageCommand): Don't invoke
+XrmDestroyDatabase() to destroy the resource database associated
+with the display since it seems that XCloseDisplay() does this for
+us.</li>
+<li>magick/image.c (DisplayImages): Don't invoke
+XrmDestroyDatabase() to destroy the resource database associated
+with the display since it seems that XCloseDisplay() does this for
+us.</li>
+<li>coders/uyvy.c: Enforce image width restrictions.</li>
+<li>coders/dpx.c: Enforce image width restrictions when subsampling.</li>
+</ul>
+</blockquote>
+<p>2005-07-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Support reading and writing subsampled CbYCr
+images. Colorimetery is not right yet.</li>
+<li>magick/colorspace.h (enum Rec709YCbCrColorspace): New
+enumeration for Rec. 709 YcBCr colorspace.</li>
+</ul>
+</blockquote>
+<p>2005-06-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Fixed a problem with reading 16-bit PNG images
+using the Q8 quantum depth.</li>
+</ul>
+</blockquote>
+<p>2005-06-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): Add read support for CbYCr at 4:4:4.
+(WriteDPXImage): Add write support for CbYCr at 4:4:4.</li>
+</ul>
+</blockquote>
+<p>2005-06-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): Only preserve source image
+dimension and offset information if image size has not changed.
+If image size has changed, the existing information may become
+invalid.
+(WriteDPXImage): Allow user to assign DPX header attribute values
+using syntax like &quot;-define dpx:mp.frame.position=1000&quot;.</li>
+</ul>
+</blockquote>
+<p>2005-06-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fpx.c: Fix compilation problem due to additional
+ExportImagePixelArea parameter.</li>
+</ul>
+</blockquote>
+<p>2005-06-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteMNGImage): Use -define mng:need-cacheoff to
+write a libmng-specific nEED request to disable frame buffering.
+This allows the MNG data to stream without increasing memory
+consumption in the libmng client.</li>
+</ul>
+</blockquote>
+<p>2005-06-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (SMPTEStringToBits): Time code and user bits were
+being displayed in wrong order on little endian CPUs. Thanks very
+much for bug report from Jason Howard.
+(SMPTEStringToBits): Similar fix for time code and user bits
+string to binary.</li>
+</ul>
+</blockquote>
+<p>2005-06-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): Use StringToColorspaceType() to
+parse colorspaces.</li>
+<li>coders/dpx.c (ReadDPXImage): Change existing
+dpx:source-colorspace define to dpx:colorspace so it is easier to
+remember.</li>
+<li>coders/cineon.c (ReadCINEONImage): Extract Cineon header
+attributes in DPX compatible form so that it is possible to
+convert Cineon to DPX while losing as little header information as
+possible. Allow the user to set the existing image colorspace
+using the cineon:colorspace define.</li>
+</ul>
+</blockquote>
+<p>2005-06-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (ReadJPEGImage): Report actual depth of JPEG file
+(8 or 12 bits).</li>
+<li>coders/cineon.c (ReadCINEONImage): Report depth as 10 bits.</li>
+</ul>
+</blockquote>
+<p>2005-05-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Retrieve and restore the DPX user defined data
+area. Make available as a &quot;DPXUSERDATA&quot; attached profile.</li>
+</ul>
+</blockquote>
+<p>2005-05-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c (ReadMETAImage): Fixed reading ICM color profile
+files. Due to a typo ICM color profiles were being stored as IPTC
+profiles. This restores proper operation of the -profile option.
+(ReadMETAImage): Fix double free bug. Hopefully does not result
+in a memory leak in other cases.</li>
+</ul>
+</blockquote>
+<p>2005-05-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (DescribeImage): If the image is DirectClass,
+then don't compute the number of unique colors unless verbose is
+greater than one. This change is made since computing the number
+of unique colors may take hours for some images. The handling of
+the -verbose argument is changed so that it is cumulative.
+Specifying -verbose multiple times increases the level of
+verbosity.</li>
+</ul>
+</blockquote>
+<p>2005-05-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (NTreaddir): Fix write beyond buffer length
+reported in SourceForge issue #1182003. Only impacts Windows.</li>
+</ul>
+</blockquote>
+<p>2005-05-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadRowSamples): Added necessary masking necessary
+in order to cleanly retrieve DPX 10 bit samples. Happened to work
+properly without the masking with QuantumDepth=16.</li>
+</ul>
+</blockquote>
+<p>2005-05-16 Tavis Ormandy &lt;<a class="reference external" href="mailto:taviso&#37;&#52;&#48;gentoo&#46;org">taviso<span>&#64;</span>gentoo<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xwd.c (ReadXWDImage): Fix for infinite loop in the xwd
+decoder when calculating the shift r/g/b values and the mask is
+set to zero.</li>
+</ul>
+</blockquote>
+<p>2005-05-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (ReadJP2Image): Return JP2 images as DirectClass
+grayscale rather than PseudoClass.</li>
+<li>coders/gray.c (ReadGRAYImage): Return GRAY images as DirectClass
+grayscale rather than PseudoClass.</li>
+<li>coders/dpx.c: Rewrote the DPX pixel reading/writing code yet
+again to obtain up to 2X better performance. In the process,
+support little-endian pixel storage.</li>
+</ul>
+</blockquote>
+<p>2005-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Added some performance optimizations for reading
+and writing. Write the motion picture and television headers.</li>
+<li>magick/colorspace.c (TransformRGBImage): Update image colorspace
+to RGB when transforming from Cineon log space to RGB.</li>
+<li>coders/dpx.c (WriteDPXImage): Set image date &amp; time field.
+(ReadDPXImage): Retrieve television header SMTPE time code and
+user bits and return them as a formatted string.
+(WriteDPXImage): Fix colorspace mapping logic. Was converting
+Cineon log to RGB when it shouldn't be.</li>
+</ul>
+</blockquote>
+<p>2005-05-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): Default to big-endian output.</li>
+<li>magick/delegate.c (InvokePostscriptDelegate): Improved
+Ghostscript API-based error reporting and logging.</li>
+<li>magick/attribute.c (GenerateEXIFAttribute): Extend EXIF
+knowledge a bit. Pass more characters from EXIF_FMT_BYTE in case
+the byte stream contains nulls.</li>
+<li>coders/dpx.c: Re-wrote the DPX read/write support in order to
+hopefully surmount problems noticed when testing with files sent
+to me.</li>
+<li>wand/pixel_wand.c (PixelSetYellowQuantum): Wrong PixelPacket
+member was being set. Thanks to Cristy for the heads-up.</li>
+<li>magick/image.c (SetImageType): Revert change from 2005-03-12.
+Some coders require that when the image is set to Bilevel type,
+that it be PseudoClass.</li>
+</ul>
+</blockquote>
+<p>2005-04-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/tests/convolve.sh: Add a convolution parameter.</li>
+</ul>
+</blockquote>
+<p>2005-04-28 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: &quot;IsGeometry() test was rejecting valid
+-convolve parameters. Also, the image returned by ConvolveImage()
+was ignored.</li>
+</ul>
+</blockquote>
+<p>2005-04-25 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Initialize several variables to avoid new
+GCC 4.0.0 warnings.</li>
+<li>coders/pnm.c: Defend against malicious &quot;P7&quot; files that try
+to set the colormap less than 256 bytes (bug fix from ImageMagick)</li>
+</ul>
+</blockquote>
+<p>2005-04-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): Fill out source information
+header.</li>
+<li>Magick++: Added image leveling methods for Magick++.</li>
+</ul>
+</blockquote>
+<p>2005-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS: Update with latest news.</li>
+<li>magick/blob.c (WriteBlob): Move BlobStream write support to a
+subroutine for easier maintenance.</li>
+<li>coders/dpx.c (ReadDPXImage): Support retrieving all DPX
+attributes as image attributes.
+(WriteDPXImage): Buffer writes for better performance on some
+platforms.</li>
+</ul>
+</blockquote>
+<p>2005-04-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): Re-write sample marshalling to be
+based on a series of tighter loops. Results in a small
+performance increase.
+(ReadDPXImage): Re-write sample marshalling to be
+based on a series of tighter loops. Results in a small
+performance increase.</li>
+</ul>
+</blockquote>
+<p>2005-04-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/Xwindow.c (XDelay): Prefer use of select() over poll()
+since it is more portable. MacOS-X has a poll() but it doesn't
+work right.</li>
+</ul>
+</blockquote>
+<p>2005-04-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick_endian.h: Renamed from endian.h in order to avoid
+conflict with system headers.</li>
+</ul>
+</blockquote>
+<p>2005-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (WriteMIFFImage): Normalize image depth to 8/16/32.</li>
+<li>coders/gray.c (WriteGRAYImage): Normalize image depth to 8/16/32.</li>
+<li>coders/fits.c (WriteFITSImage): Normalize image depth to 8/16.</li>
+<li>tests/Makefile.am: Extended read/write tests to include 10, 12,
+and 16-bit original test images.</li>
+<li>coders/dpx.c (ReadDPXImage): If samples are log encoded, then
+set the image to CineonLogRGBColorspace.
+(WriteDPXImage): If image samples are log encoded, then mark DPX
+file as being log encoded.</li>
+<li>magick/colorspace.c (TransformRGBImage): Support translation
+from log RGB to linear RGB based on Cineon guidelines.
+(RGBTransformImage): Support translation from linear RGB to log RGB.</li>
+<li>magick/colorspace.h (enum CineonLogRGBColorspace): New
+enumeration to record that the RGB values are log encoded in a
+2.048 density range as defined for the Cineon Digital Film System.</li>
+</ul>
+</blockquote>
+<p>2005-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Take advantage of ColorspaceTypeToString() and
+StringToColorspaceType() functions in implementation.</li>
+<li>magick/colorspace.c (RGBTransformImage): Added support for
+converting to Rec 709 grayscale colorspace.
+(ColorspaceTypeToString): New function to translate from
+ColorspaceType enumeration value to a string.
+(StringToColorspaceType): New function to translate from a string
+to a ColorspaceType enumeration value. * magick/colorspace.h
+(enum Rec601LumaColorspace): New enumeration to support the Rec
+601 grayscale colorspace. This is the colorspace previously
+represented by GRAYColorspace. If GRAYColorspace is specified,
+then Rec601LumaColorspace is selected.
+(enum Rec709LumaColorspace): New enumeration to support the Rec
+707 grayscale colorspace.</li>
+</ul>
+</blockquote>
+<p>2005-04-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (IdentifyImageCommand): Use +ping to force
+identify to read the image pixels.</li>
+<li>magick/constitute.c (PingImage): Intentionally clear
+user/elapsed timer when ping is used on an image since the results
+are misleading.</li>
+<li>magick/image.c (DescribeImage): Only display pixel read rate if
+the time accumulated is at least the timer's resolution.</li>
+<li>magick/cache.c (OpenCache): Fix a memory resource leak noticed
+by Stefan v. Wachter &lt;<a class="reference external" href="mailto:svwa-dev&#37;&#52;&#48;mnet-online&#46;de">svwa-dev<span>&#64;</span>mnet-online<span>&#46;</span>de</a>&gt;. This error with
+keeping track of resources may eventually cause GraphicsMagick to
+run slower and slower due to using disk-based images rather than
+memory-based images.</li>
+</ul>
+</blockquote>
+<p>2005-04-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: encoder now accepts image-&gt;depth other than 8 and 16.</li>
+</ul>
+</blockquote>
+<p>2005-04-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): First pass at a new SMPTE268M-2003
+DPX writer.</li>
+</ul>
+</blockquote>
+<p>2005-04-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (AllocateString): Performance enhancement.
+(CloneString): Performance enhancement.
+(ConcatenateString): Performance enhancement.</li>
+</ul>
+</blockquote>
+<p>2005-03-31 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: revised EOF test. It was rejecting good image
+files. Needs more work.</li>
+</ul>
+</blockquote>
+<p>2005-03-30 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (ReadPNMImage): Throw a &quot;Corrupt Image&quot; exception
+if EOF is encountered while reading scanlines in P1, P2, P3, or P4
+formatted images (P5 and P6 were OK).</li>
+</ul>
+</blockquote>
+<p>2005-03-29 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sgi.c (ReadSGIImage): Throw a &quot;Corrupt Image&quot; exception
+if EOF is encountered while reading scanlines.</li>
+</ul>
+</blockquote>
+<p>2005-03-28 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (ReadJPEGImage): Throw a &quot;Corrupt Image&quot; exception
+if EOF is encountered while reading scanlines.</li>
+<li>coders/pcx.c (ReadPCXImage): Throw a &quot;Corrupt Image&quot; exception
+if EOF is encountered while reading pixels.</li>
+</ul>
+</blockquote>
+<p>2005-03-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): First pass at a new SMPTE268M-2003
+DPX reader.</li>
+<li>magick/bit_stream.h (WordStreamLSBRead): New function to parse
+values from a stream which is defined by 32-bit words. Values are
+read starting with the least significant bits.</li>
+</ul>
+</blockquote>
+<p>2005-03-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ExtensionTagsInitialize): Fix conditional use of
+TIFFSetTagExtender().</li>
+</ul>
+</blockquote>
+<p>2005-03-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/endian.c: Imported libtiff's swab.c since its functions
+are so useful and well-tested.</li>
+<li>magick/utility.c (FormatSize): Extend to support incredibly
+large sizes.</li>
+<li>magick/image.c (DescribeImage): Use GetTimerResolution() when
+computing pixels-per-second rate in order to avoid computing
+astronomical rates when the time consumed is too small to measure.</li>
+<li>magick/timer.c (GetTimerResolution): New function to return the
+timer's resolution.</li>
+</ul>
+</blockquote>
+<p>2005-03-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c (WritePDFImage): Eliminate cause of annoying
+warning when PDFs are read by Ghostscript 8.5.</li>
+</ul>
+</blockquote>
+<p>2005-03-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.h (lt_dlerror): Needed to provide a mapping to
+NTdlerror().</li>
+<li>coders/tiff.c (TIFFErrors): Update to make thread safe via
+thread specific data.
+(TIFFWarnings): Update to make thread safe via thread specific
+data.</li>
+<li>magick/tsd.c (MagickTsdKeyCreate): New function to support
+thread specific data.
+(MagickTsdKeyDelete): ditto
+(MagickTsdSetSpecific): ditto
+(MagickTsdGetSpecific): ditto.</li>
+</ul>
+</blockquote>
+<p>2005-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (ReplaceImageColormap): New function to replace
+the image colormap with a user-provided one. Colormap indexes are
+adjusted to point to identical colors in the new colormap.</li>
+<li>magick/nt_base.h: Reorganized a bit to cluster code supporting
+similar features in the same area of the header.</li>
+<li>magick/nt_base.c: Renamed wrappers for standard functions so
+that they have the prefix <cite>NT</cite>. Macros are used to apply the new
+names. This assures that there will not be conflicts if the library
+is linked with a different package's wrapper functions.</li>
+</ul>
+</blockquote>
+<p>2005-03-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/quantize.c (GrayscalePseudoClassImage): Moved to here
+from image.c. Added support for is_monochrome.</li>
+</ul>
+</blockquote>
+<p>2005-03-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>jp2: Updated Jasper library to version 1.701.0.</li>
+<li>magick/nt_base.c (NTGhostscriptFonts): Fixed a coding error
+which was added when strcpy/strcat code was replaced with
+strlcpy/strlcat. Ghostscript fonts were not being found.</li>
+<li>magick/constitute.c (ReadImage): Don't attempt to access image
+members if image pointer is null. Oops!</li>
+</ul>
+</blockquote>
+<p>2005-03-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageType): Bilevel image is not required to
+be PseudoClass type.</li>
+<li>coders/mpc.c (WriteMPCImage): Persist is_monochrome and
+is_grayscale flags.
+(ReadMPCImage): Restore is_monochrome and is_grayscale flags.</li>
+<li>magick/constitute.c (WriteImage): Extended logging to include
+monochrome and grayscale flags.
+(ReadImage): Extended logging to include monochrome and grayscale
+flags.</li>
+<li>magick/image.c (DescribeImage): Include the effective pixel I/O
+rate alongside the image read/write time. This provides an easier
+way to evaluate image read/write performance when looking at
+<cite>identify</cite> or <cite>convert -verbose</cite> output.</li>
+<li>coders/sun.c (ReadSUNImage): Ensure that pixel length value does
+not overflow for large images.</li>
+</ul>
+</blockquote>
+<p>2005-03-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cache.c (SetImagePixels): Improved documentation.
+(GetImagePixels): Improved documentation.</li>
+</ul>
+</blockquote>
+<p>2005-03-10 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;glennrp&#46;com">glennrp<span>&#64;</span>glennrp<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Avoid attempting to write indexed PNG when
+a color entry has more than one opacity level. The PNG format
+supports this but GM's colormap does not, so erroneous files
+were being written.</li>
+</ul>
+</blockquote>
+<p>2005-03-09 Arne Rusek &lt;<a class="reference external" href="mailto:zonk&#37;&#52;&#48;matfyz&#46;cz">zonk<span>&#64;</span>matfyz<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GenerateEXIFAttribute): Offset type
+correction to fix loop termination if size_t type is not <cite>long</cite>.</li>
+</ul>
+</blockquote>
+<p>2005-03-09 Alexander Yaworsky &lt;<a class="reference external" href="mailto:yaworsky&#37;&#52;&#48;users&#46;sourceforge&#46;net">yaworsky<span>&#64;</span>users<span>&#46;</span>sourceforge<span>&#46;</span>net</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jbig.c (WriteJBIGImage): JBIG was writing an empty output
+file. Apparently libjbig parameters have changed. Setting l0
+parameter of jbg_enc_options to zero instead of -1 (like in
+jbigkit's pbmtools) solved the problem.</li>
+</ul>
+</blockquote>
+<p>2005-03-07 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagickmagickGM_magick.bpr: Updated to reflect changes since
+last update.</li>
+<li>BCBMagickmagicklibMagick.bpr: Updated to reflect changes since
+last update.</li>
+</ul>
+</blockquote>
+<p>2005-03-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/alpha_composite.h (AlphaComposite): Moved AlphaComposite
+to new alpha_composite.h header since it was causing porting
+problems.</li>
+<li>magick/constitute.h (enum QuantumType): Added CIEYQuantum and
+CIEXYZQuantum quantum import options.</li>
+<li>coders/tiff.c (ReadTIFFImage): Import LogLuv image data within
+GraphicsMagick (rather than libtiff) so that color resolution is
+not lost. Results in a small speedup as well.</li>
+<li>magick/constitute.c (ImportImagePixelArea): Add a speed-up for
+importing bi-level images. Add support for importing pixels in
+CIE XYZ and CIE Y colorspaces.</li>
+<li>coders/tiff.c (ReadTIFFImage): Support reading TIFF images which
+fail to properly scale the samples to the sample size (e.g. 12
+bits in a 16-bit sample).
+(WriteTIFFImage): Adjustments to strip-size (rows-per-strip)
+estimation.</li>
+<li>magick/constitute.c (ExportImagePixelArea): Support exporting
+unsigned samples with values which span only part of the range.
+For example, 12 bit data may be exported within 16 bit samples,
+with a value range of 0 to 4095.
+(ImportImagePixelArea): Support importing unsigned samples with
+values which span only part of the range.</li>
+</ul>
+</blockquote>
+<p>2005-02-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Support reading TIFF files in
+IEEEFP format.
+(WriteTIFFImage): Support writing TIFF files in IEEEFP format.</li>
+<li>magick/constitute.c (ExportImagePixelArea): Support exporting
+floating point data.
+(ImportImagePixelArea): Support importing floating point data.</li>
+</ul>
+</blockquote>
+<p>2005-02-26 Albert Chin-A-Young &lt;<a class="reference external" href="mailto:china&#37;&#52;&#48;thewrittenword&#46;com">china<span>&#64;</span>thewrittenword<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>acinclude.m4 (AC_CXX_IOS_BINARY): Added macro to detect if the
+C++ compiler lacks support for ios::binary.</li>
+<li>configure.ac: Use AC_CXX_IOS_BINARY.</li>
+</ul>
+</blockquote>
+<p>2005-02-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Read grayscale TIFFs as
+DirectClass rather than promoting to PseudoClass. Fix improper
+multiple repeated &quot;disassociate&quot; operations when reading planar
+images which contain an alpha channel.
+(WriteTIFFImage): Fix improper multiple repeated &quot;associate&quot;
+operations when writing planar images with an alpha channel.</li>
+</ul>
+</blockquote>
+<p>2005-02-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>win2k/IMDisplay/IMDisplayView.cpp (DoDisplayImage): Use
+TextureImage to apply background pattern.</li>
+<li>magick/image.c (TextureImage): Alpha blend the texture onto the
+background if the image has a matte channel.</li>
+<li>magick/constitute.h (enum QuantumType): Eliminated
+GrayInvertedQuantum and GrayInvertedAlphaQuantum which were added
+since GraphicsMagick 1.1. Replaced this &quot;inverted&quot; gray
+functionality with the grayscale_inverted flag in
+ExportPixelAreaOptions and ImportPixelAreaOptions.</li>
+<li>magick/constitute.c (ExportImagePixelArea): Added an extra
+parameter for passing seldom used options via an
+ExportPixelAreaOptions structure.
+(ImportImagePixelArea): Added an extra parameter for passing
+seldom used options via an ImportPixelAreaOptions structure.
+(ExportPixelAreaOptionsInit): New function to initialize the
+ExportPixelAreaOptions structure with defaults.
+(ImportPixelAreaOptionsInit): New function to intialize the
+ImportPixelAreaOptions structure with defaults.</li>
+<li>coders/jpeg.c (WriteJPEGImage): Don't use jpeglib private
+BITS_IN_JSAMPLE definition to select JPEG bit depth.</li>
+<li>coders/tiff.c (ReadTIFFImage): Support using -define
+tiff:alpha={unspecified|associated|unassociated} to specify the
+alpha channel type in case the alpha channel is marked
+incorrectly.
+Properly read associated alpha images.
+(WriteTIFFImage): Support using -define
+tiff:alpha={unspecified|associated|unassociated} to override the
+alpha channel type.
+Properly write associated alpha images by default.</li>
+</ul>
+</blockquote>
+<p>2005-02-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WritePTIFImage): Ensure that pyramid image frames
+are the same type as the original image.
+(WriteTIFFImage): Added support for writing tiled TIFF.</li>
+</ul>
+</blockquote>
+<p>2005-01-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (TraceBezier): Avoid probable bug under Visual
+C++ 7.0 or later due to the argument to pow not being promoted to
+double.</li>
+</ul>
+</blockquote>
+<p>2005-01-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Re-wrote TIFF writing code.</li>
+<li>magick/image.h (MaxValueGivenBits): Renamed MaxRGBGivenBits
+macro to MaxValueGivenBits.</li>
+<li>magick/constitute.h (enum QuantumType): Added UndefinedQuantum.</li>
+<li>magick/static.c (RegisterStaticModules): Support compiling
+without PNG.</li>
+</ul>
+</blockquote>
+<p>2005-01-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/color.c (IsPaletteImage): Fix memory leak reported by
+Stefan v. Wachter &lt;<a class="reference external" href="mailto:svwa-dev&#37;&#52;&#48;mnet-online&#46;de">svwa-dev<span>&#64;</span>mnet-online<span>&#46;</span>de</a>&gt;.</li>
+<li>magick/Makefile.am (MAGICK_INCLUDE_HDRS): Needed to install
+magick/operator.h.</li>
+<li>coders/tiff.c (ReadTIFFImage): Re-wrote TIFF reading code again
+for more flexibility and performance.</li>
+</ul>
+</blockquote>
+<p>2005-01-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Remove --disable-lzw option and HasLZW define.
+LZW support is always enabled now.</li>
+</ul>
+</blockquote>
+<p>2005-01-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tga.c (WriteTGAImage): Incorporated patch from Stefan
+v. Wachter to enable writing grayscale images as well as adding
+more image type option smarts.</li>
+<li>coders/psd.c (ReadPSDImage): Fix stack overflow vulnerability
+reported by Andrei Nigmatulin. See <a class="reference external" href="http://lwn.net/Articles/119713/">http://lwn.net/Articles/119713/</a>
+for details.</li>
+</ul>
+</blockquote>
+<p>2005-01-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>win2k/IMDisplay/IMDisplayDoc.cpp (DoReadImage): Ensure that image
+is in RGB color space after being read since this is what Windows
+expects.</li>
+</ul>
+</blockquote>
+<p>2005-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Handle extra samples in scanline
+TIFFs.</li>
+</ul>
+</blockquote>
+<p>2005-01-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (DescribeImage): Report statistics for a virtual
+gray channel for grayscale images rather than discrete red, green,
+and blue.</li>
+<li>PerlMagick/Makefile.nt: JNG and JP2 to test list.</li>
+<li>configure.ac: Changed --without-fpx to --with-fpx due to
+decision to default FlashPIX to <cite>no</cite>. FlashPIX library is not
+very portable and is only known to work properly under SPARC
+Solaris and Windows.</li>
+<li>NEWS: Updated with latest news.</li>
+<li>lcms: Updated to LCMS 1.14.</li>
+</ul>
+</blockquote>
+<p>2005-01-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (ReadJP2Image): Handle images in YCBCR colorspace.
+(ReadJP2Image): Retrieve and store an ICC ICM color profile if
+present.</li>
+<li>PerlMagick/t/tiff/read.t: Added test for reading truecolor
+planar TIFF image.
+Added test for reading 32-bit TrueColor TIFF image.
+Added test for reading 32-bit grayscale TIFF image.</li>
+<li>coders/tiff.c (ReadTIFFImage): Fixed stripped TIFF reader.</li>
+</ul>
+</blockquote>
+<p>2005-01-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Only set TIFFTAG_PREDICTOR to 2
+for bits-per-sample values that libtiff supports.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2005.rst b/www/ChangeLog-2005.rst
new file mode 100644
index 0000000..83fc7d3
--- /dev/null
+++ b/www/ChangeLog-2005.rst
@@ -0,0 +1,914 @@
+2005-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff: Update to libtiff 3.8.0.
+
+2005-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS: Updated with latest changes.
+
+ - tiff: Update to libtiff 3.7.4.
+
+2005-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lcms: Update to lcms 1.15.
+
+2005-12-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/enhance.c (LevelImage): Fix -level command parsing when a
+ percent symbol is supplied within the argument rather than at the
+ end.
+
+ - magick/utility.c (GetGeometry): Bounds-check geometry string
+ length.
+
+2005-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Decided to swap 10-bit subsampled 4:2:2 YCbCr by
+ default since this is what practically all sample files I have
+ been provided actually do. Ignore the fact that there is nothing
+ in the standard which supports this.
+
+2005-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (NormalizeSamplingFactor): Generalized
+ subsampling notation parsing support.
+
+2005-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (NormalizeSamplingFactor): Add some support for
+ normalizing industry-standard subsampling notation (e.g. 4:2:2)
+ into GraphicsMagick's unusual notation.
+
+2005-12-06 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ - Updates to use latest development autotools, including
+ development libtool 2.0.
+
+2005-12-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h: Added some useful macros for accessing
+ PixelPacket members in a generic way.
+
+ - coders/dpx.c (ReadDPXImage): For YCbCr with `A` sample, `A`
+ sample levels are like Luma.
+ (WriteDPXImage): For YCbCr with `A` sample, `A` sample levels are
+ like Luma.
+
+2005-12-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (RegisterTIFFImage): Report libtiff release
+ version rather than ABI version.
+
+2005-11-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resize.c: Revert yesterday's benign-appearing edits since
+ they caused a bizzare bug.
+
+2005-11-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): Improve performance when reading
+ YCbCr files. Handle files which use Printing Density on top of
+ YCbCr. Default YCbCr to Rec.709 if the transfer characteristic is
+ User Defined.
+
+ - coders/pcd.c (Upsample): Moved Upsample from gem.c to here since
+ PCD is the only user and it is not a general purpose function.
+
+2005-11-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/magick/magick\_config.h.in: Remove unnecessary test
+ for WIN32.
+
+2005-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_compat.c (FormatMagickStringList): MagickExport since this
+ function is used by Ch extension.
+
+ - magick/log.c (LogMagickEventList): MagickExport since this
+ function is used by Ch extension.
+
+ - magick/utility.c (FormatStringList): MagickExport since this
+ function is used by Ch extension.
+
+ - coders/dpx.c (ReadDPXImage): Added support for dpx:swap-samples
+ define in order to handle files with Cb and Cr swapped. Fixed a
+ bug in the header reading which caused some valid files to fail to
+ read at all.
+ (WriteDPXImage): Added support for dpx:swap-samples define in
+ order to write files with Cb and Cr swapped.
+
+ - magick/profile.c (ProfileImage): Add support for ICC CMS
+ profiles in YCbCr space.
+
+2005-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/svg.c (ReadSVGImage): Eliminate memory leak.
+
+2005-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.h (Image): Added an orientation member to the Image
+ structure to record image orientation for the DPX, and TIFF
+ formats. Eventually formats which support IPTC and EXIF embedded
+ profiles should be supported by the orientation member as well.
+
+2005-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/magick/magick\_types.h.in: Add patch for Ch.
+
+ - magick/command.c (TransmogrifyImage): Complete re-write of
+ mogrify file handling. Former version wrote to a temporary file
+ and then moved temporary file to replace original if necessary.
+ New version moves an existing writable file to a backup file with
+ tilde (`~`) added to end of file name, writes to the final output
+ file name, and removes the backup file on success. The new
+ approach satisfies formats which embed the output name in the file
+ (e.g. the DPX format) and still works when the output file exists
+ and is writeable, but is in non-writeable directory. The previous
+ approach would fail if the output file exists and is writable, but
+ the directory is not writeable.
+
+2005-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (AttributeToString): Use strncpy rather than
+ strlcpy to copy string. This is important since DPX header
+ strings are not null terminated and may need to fill all available
+ space. Certain short header fields like mp.film.manufacturer.id,
+ mp.film.type, and mp.perfs.offset were being truncated!
+
+2005-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (GetImageAttribute): Add more general support
+ for retrieving wildcarded attributes so that an identify -format
+ specification like `%[dpx:\*]` works as expected.
+
+ - coders/tiff.c (WriteTIFFImage): Transform quality value into zip
+ compression quality level similar to what is done for MIFF/MNG/PNG.
+ Since default quality value is 75, this means that the default zip
+ quality level is 7.
+
+2005-09-24 Peter Wu <peterw@softintegration.com>
+
+ - Incorporate changes necessary so that GraphicsMagick can work
+ with the Ch C/C++ interpreter from SoftIntegration at
+ http://www.softintegration.com/.
+
+2005-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c: Incorporate all functionality from
+ cache.c, cache\_view.c, and stream.c so that all private interfaces
+ can be fully hidden. As a result cache.c, cache\_view.c, and
+ stream.c are now removed.
+
+2005-09-18 Michal Kowalczuk <sammael@brzydal.eu.org>
+
+ - coders/gif.c: Free global\_colormap before returning with error.
+
+2005-09-18 Stepan Kasal <kasal@ucw.cz>
+
+ - Makefile.am (BUILT\_SOURCES): Removed.
+
+ - magick/Makefile.am (MAGICK\_BUILT\_SRCS): Removed, too.
+
+2005-09-12 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - magick/profile.c (ProfileImage): Free color\_profile->name
+ and iptc\_profile->name when destroying the profile.
+
+2005-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/api.h: Eliminate requirement to include certain system
+ headers prior to including <magick/api.h>.
+
+ - utilities/gm.c: Move utility implementation to GMCommand() in
+ command.c
+
+2005-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Added support for reading and writing DPX Luma
+ files using proper video levels.
+
+ - magick/colorspace.h (enum ColorspaceType): Decided that
+ GRAYColorspace should be reserved for full-range grayscale data
+ while Rec601LumaColorspace and Rec709LumaColorspace should be for
+ video colorspaces. Therefore, GRAYColorspace is no longer a
+ synonym for Rec601LumaColorspace.
+
+ - magick/colorspace.c: Added support for influencing Cineon Log
+ colorspace transformations via image attributes.
+ Perform colorspace transformations in floating point rather than
+ integer in order to reduce the amount of noise added by
+ transform table quantization.
+
+ - coders/psd.c (WritePSDImage): Ensure that output image is 8 or
+ 16-bits regardless of specific image depth.
+
+ - coders/dpx.c: Added support for planar YCbCr 4:2:2.
+
+2005-08-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): 10 and 12-bit packed data was not
+ according to DPX specification. Added dpx:pixel-endian={lsb|msb}
+ to allow the user to specify the endian order of the pixel data in
+ case it does (or should not) not match the headers. Library Of
+ Congress format is 10-bit packed data in big-endian format, but is
+ marked as little-endian.
+
+2005-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Sample order for filled 10 bit samples matches DPX
+ specification (was intentionally reversed). RGB sample order is
+ changed to match DPX specifiation (i.e. BGR rather than RGB).
+ Disabled special support for Library Of Congress little-endian
+ 10-bit packed format.
+
+2005-08-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Extend all image rows to a 32-bit integer
+ boundary.
+
+2005-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Support the little-endian 10-bit packed format as
+ used by the Library Of Congress.
+
+2005-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c: Change how Jasper is intialized. Hopefully
+ eliminate memory leak when reading ICC color profile.
+
+ - Overall: Compilation warning elimination with GCC 4.0.1.
+
+ - magick/utility.c (SystemCommand): Always report error status if
+ a command fails.
+
+2005-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - zlib: Updated to version 1.2.3.
+
+ - coders/dpx.c: Use TriangleFilter for scaling chroma.
+
+2005-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Support proper encode and decode of YCbCr video
+ levels.
+
+ - magick/colorspace.c: Support Rec709YCbCrColorspace colorspace.
+
+2005-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/{animate.c, display.c, import.c, xwindow.c}: Rename all
+ symbols starting with `X` so that they are prefixed with `Magick`.
+ This eases maintenance since it is almost impossible to understand
+ code which pretends to be the X11 libraries. The few programs
+ which use the GraphicsMagick `X` functions will need to alter the
+ symbol names they use. Sorry.
+
+ - magick/command.c (DisplayImageCommand): Don't invoke
+ XrmDestroyDatabase() to destroy the resource database associated
+ with the display since it seems that XCloseDisplay() does this for
+ us.
+
+ - magick/image.c (DisplayImages): Don't invoke
+ XrmDestroyDatabase() to destroy the resource database associated
+ with the display since it seems that XCloseDisplay() does this for
+ us.
+
+ - coders/uyvy.c: Enforce image width restrictions.
+
+ - coders/dpx.c: Enforce image width restrictions when subsampling.
+
+2005-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Support reading and writing subsampled CbYCr
+ images. Colorimetery is not right yet.
+
+ - magick/colorspace.h (enum Rec709YCbCrColorspace): New
+ enumeration for Rec. 709 YcBCr colorspace.
+
+2005-06-21 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/png.c: Fixed a problem with reading 16-bit PNG images
+ using the Q8 quantum depth.
+
+2005-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): Add read support for CbYCr at 4:4:4.
+ (WriteDPXImage): Add write support for CbYCr at 4:4:4.
+
+2005-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): Only preserve source image
+ dimension and offset information if image size has not changed.
+ If image size has changed, the existing information may become
+ invalid.
+ (WriteDPXImage): Allow user to assign DPX header attribute values
+ using syntax like "-define dpx:mp.frame.position=1000".
+
+2005-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/fpx.c: Fix compilation problem due to additional
+ ExportImagePixelArea parameter.
+
+2005-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c (WriteMNGImage): Use -define mng:need-cacheoff to
+ write a libmng-specific nEED request to disable frame buffering.
+ This allows the MNG data to stream without increasing memory
+ consumption in the libmng client.
+
+2005-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (SMPTEStringToBits): Time code and user bits were
+ being displayed in wrong order on little endian CPUs. Thanks very
+ much for bug report from Jason Howard.
+ (SMPTEStringToBits): Similar fix for time code and user bits
+ string to binary.
+
+2005-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): Use StringToColorspaceType() to
+ parse colorspaces.
+ - coders/dpx.c (ReadDPXImage): Change existing
+ dpx:source-colorspace define to dpx:colorspace so it is easier to
+ remember.
+
+ - coders/cineon.c (ReadCINEONImage): Extract Cineon header
+ attributes in DPX compatible form so that it is possible to
+ convert Cineon to DPX while losing as little header information as
+ possible. Allow the user to set the existing image colorspace
+ using the cineon:colorspace define.
+
+2005-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (ReadJPEGImage): Report actual depth of JPEG file
+ (8 or 12 bits).
+
+ - coders/cineon.c (ReadCINEONImage): Report depth as 10 bits.
+
+2005-05-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Retrieve and restore the DPX user defined data
+ area. Make available as a "DPXUSERDATA" attached profile.
+
+2005-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c (ReadMETAImage): Fixed reading ICM color profile
+ files. Due to a typo ICM color profiles were being stored as IPTC
+ profiles. This restores proper operation of the -profile option.
+ (ReadMETAImage): Fix double free bug. Hopefully does not result
+ in a memory leak in other cases.
+
+2005-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (DescribeImage): If the image is DirectClass,
+ then don't compute the number of unique colors unless verbose is
+ greater than one. This change is made since computing the number
+ of unique colors may take hours for some images. The handling of
+ the -verbose argument is changed so that it is cumulative.
+ Specifying -verbose multiple times increases the level of
+ verbosity.
+
+2005-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (NTreaddir): Fix write beyond buffer length
+ reported in SourceForge issue #1182003. Only impacts Windows.
+
+2005-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadRowSamples): Added necessary masking necessary
+ in order to cleanly retrieve DPX 10 bit samples. Happened to work
+ properly without the masking with QuantumDepth=16.
+
+2005-05-16 Tavis Ormandy <taviso@gentoo.org>
+
+ - coders/xwd.c (ReadXWDImage): Fix for infinite loop in the xwd
+ decoder when calculating the shift r/g/b values and the mask is
+ set to zero.
+
+2005-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (ReadJP2Image): Return JP2 images as DirectClass
+ grayscale rather than PseudoClass.
+
+ - coders/gray.c (ReadGRAYImage): Return GRAY images as DirectClass
+ grayscale rather than PseudoClass.
+
+ - coders/dpx.c: Rewrote the DPX pixel reading/writing code yet
+ again to obtain up to 2X better performance. In the process,
+ support little-endian pixel storage.
+
+2005-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Added some performance optimizations for reading
+ and writing. Write the motion picture and television headers.
+
+ - magick/colorspace.c (TransformRGBImage): Update image colorspace
+ to RGB when transforming from Cineon log space to RGB.
+
+ - coders/dpx.c (WriteDPXImage): Set image date & time field.
+ (ReadDPXImage): Retrieve television header SMTPE time code and
+ user bits and return them as a formatted string.
+ (WriteDPXImage): Fix colorspace mapping logic. Was converting
+ Cineon log to RGB when it shouldn't be.
+
+2005-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): Default to big-endian output.
+
+ - magick/delegate.c (InvokePostscriptDelegate): Improved
+ Ghostscript API-based error reporting and logging.
+
+ - magick/attribute.c (GenerateEXIFAttribute): Extend EXIF
+ knowledge a bit. Pass more characters from EXIF\_FMT\_BYTE in case
+ the byte stream contains nulls.
+
+ - coders/dpx.c: Re-wrote the DPX read/write support in order to
+ hopefully surmount problems noticed when testing with files sent
+ to me.
+
+ - wand/pixel\_wand.c (PixelSetYellowQuantum): Wrong PixelPacket
+ member was being set. Thanks to Cristy for the heads-up.
+
+ - magick/image.c (SetImageType): Revert change from 2005-03-12.
+ Some coders require that when the image is set to Bilevel type,
+ that it be PseudoClass.
+
+2005-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/tests/convolve.sh: Add a convolution parameter.
+
+2005-04-28 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - magick/command.c: "IsGeometry() test was rejecting valid
+ -convolve parameters. Also, the image returned by ConvolveImage()
+ was ignored.
+
+2005-04-25 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/png.c: Initialize several variables to avoid new
+ GCC 4.0.0 warnings.
+
+ - coders/pnm.c: Defend against malicious "P7" files that try
+ to set the colormap less than 256 bytes (bug fix from ImageMagick)
+
+2005-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): Fill out source information
+ header.
+
+ - Magick++: Added image leveling methods for Magick++.
+
+2005-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS: Update with latest news.
+
+ - magick/blob.c (WriteBlob): Move BlobStream write support to a
+ subroutine for easier maintenance.
+
+ - coders/dpx.c (ReadDPXImage): Support retrieving all DPX
+ attributes as image attributes.
+ (WriteDPXImage): Buffer writes for better performance on some
+ platforms.
+
+2005-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): Re-write sample marshalling to be
+ based on a series of tighter loops. Results in a small
+ performance increase.
+ (ReadDPXImage): Re-write sample marshalling to be
+ based on a series of tighter loops. Results in a small
+ performance increase.
+
+2005-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/Xwindow.c (XDelay): Prefer use of select() over poll()
+ since it is more portable. MacOS-X has a poll() but it doesn't
+ work right.
+
+2005-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick\_endian.h: Renamed from endian.h in order to avoid
+ conflict with system headers.
+
+2005-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (WriteMIFFImage): Normalize image depth to 8/16/32.
+
+ - coders/gray.c (WriteGRAYImage): Normalize image depth to 8/16/32.
+
+ - coders/fits.c (WriteFITSImage): Normalize image depth to 8/16.
+
+ - tests/Makefile.am: Extended read/write tests to include 10, 12,
+ and 16-bit original test images.
+
+ - coders/dpx.c (ReadDPXImage): If samples are log encoded, then
+ set the image to CineonLogRGBColorspace.
+ (WriteDPXImage): If image samples are log encoded, then mark DPX
+ file as being log encoded.
+
+ - magick/colorspace.c (TransformRGBImage): Support translation
+ from log RGB to linear RGB based on Cineon guidelines.
+ (RGBTransformImage): Support translation from linear RGB to log RGB.
+
+ - magick/colorspace.h (enum CineonLogRGBColorspace): New
+ enumeration to record that the RGB values are log encoded in a
+ 2.048 density range as defined for the Cineon Digital Film System.
+
+2005-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Take advantage of ColorspaceTypeToString() and
+ StringToColorspaceType() functions in implementation.
+
+ - magick/colorspace.c (RGBTransformImage): Added support for
+ converting to Rec 709 grayscale colorspace.
+ (ColorspaceTypeToString): New function to translate from
+ ColorspaceType enumeration value to a string.
+ (StringToColorspaceType): New function to translate from a string
+ to a ColorspaceType enumeration value. \* magick/colorspace.h
+ (enum Rec601LumaColorspace): New enumeration to support the Rec
+ 601 grayscale colorspace. This is the colorspace previously
+ represented by GRAYColorspace. If GRAYColorspace is specified,
+ then Rec601LumaColorspace is selected.
+ (enum Rec709LumaColorspace): New enumeration to support the Rec
+ 707 grayscale colorspace.
+
+2005-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (IdentifyImageCommand): Use +ping to force
+ identify to read the image pixels.
+
+ - magick/constitute.c (PingImage): Intentionally clear
+ user/elapsed timer when ping is used on an image since the results
+ are misleading.
+
+ - magick/image.c (DescribeImage): Only display pixel read rate if
+ the time accumulated is at least the timer's resolution.
+
+ - magick/cache.c (OpenCache): Fix a memory resource leak noticed
+ by Stefan v. Wachter <svwa-dev@mnet-online.de>. This error with
+ keeping track of resources may eventually cause GraphicsMagick to
+ run slower and slower due to using disk-based images rather than
+ memory-based images.
+
+2005-04-07 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/png.c: encoder now accepts image->depth other than 8 and 16.
+
+2005-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): First pass at a new SMPTE268M-2003
+ DPX writer.
+
+2005-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (AllocateString): Performance enhancement.
+ (CloneString): Performance enhancement.
+ (ConcatenateString): Performance enhancement.
+
+2005-03-31 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/jpeg.c: revised EOF test. It was rejecting good image
+ files. Needs more work.
+
+2005-03-30 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/pnm.c (ReadPNMImage): Throw a "Corrupt Image" exception
+ if EOF is encountered while reading scanlines in P1, P2, P3, or P4
+ formatted images (P5 and P6 were OK).
+
+2005-03-29 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/sgi.c (ReadSGIImage): Throw a "Corrupt Image" exception
+ if EOF is encountered while reading scanlines.
+
+2005-03-28 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/jpeg.c (ReadJPEGImage): Throw a "Corrupt Image" exception
+ if EOF is encountered while reading scanlines.
+
+ - coders/pcx.c (ReadPCXImage): Throw a "Corrupt Image" exception
+ if EOF is encountered while reading pixels.
+
+2005-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): First pass at a new SMPTE268M-2003
+ DPX reader.
+
+ - magick/bit\_stream.h (WordStreamLSBRead): New function to parse
+ values from a stream which is defined by 32-bit words. Values are
+ read starting with the least significant bits.
+
+2005-03-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ExtensionTagsInitialize): Fix conditional use of
+ TIFFSetTagExtender().
+
+2005-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/endian.c: Imported libtiff's swab.c since its functions
+ are so useful and well-tested.
+
+ - magick/utility.c (FormatSize): Extend to support incredibly
+ large sizes.
+
+ - magick/image.c (DescribeImage): Use GetTimerResolution() when
+ computing pixels-per-second rate in order to avoid computing
+ astronomical rates when the time consumed is too small to measure.
+
+ - magick/timer.c (GetTimerResolution): New function to return the
+ timer's resolution.
+
+2005-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c (WritePDFImage): Eliminate cause of annoying
+ warning when PDFs are read by Ghostscript 8.5.
+
+2005-03-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.h (lt\_dlerror): Needed to provide a mapping to
+ NTdlerror().
+
+ - coders/tiff.c (TIFFErrors): Update to make thread safe via
+ thread specific data.
+ (TIFFWarnings): Update to make thread safe via thread specific
+ data.
+
+ - magick/tsd.c (MagickTsdKeyCreate): New function to support
+ thread specific data.
+ (MagickTsdKeyDelete): ditto
+ (MagickTsdSetSpecific): ditto
+ (MagickTsdGetSpecific): ditto.
+
+2005-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (ReplaceImageColormap): New function to replace
+ the image colormap with a user-provided one. Colormap indexes are
+ adjusted to point to identical colors in the new colormap.
+
+ - magick/nt\_base.h: Reorganized a bit to cluster code supporting
+ similar features in the same area of the header.
+
+ - magick/nt\_base.c: Renamed wrappers for standard functions so
+ that they have the prefix `NT`. Macros are used to apply the new
+ names. This assures that there will not be conflicts if the library
+ is linked with a different package's wrapper functions.
+
+2005-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/quantize.c (GrayscalePseudoClassImage): Moved to here
+ from image.c. Added support for is\_monochrome.
+
+2005-03-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - jp2: Updated Jasper library to version 1.701.0.
+
+ - magick/nt\_base.c (NTGhostscriptFonts): Fixed a coding error
+ which was added when strcpy/strcat code was replaced with
+ strlcpy/strlcat. Ghostscript fonts were not being found.
+
+ - magick/constitute.c (ReadImage): Don't attempt to access image
+ members if image pointer is null. Oops!
+
+2005-03-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageType): Bilevel image is not required to
+ be PseudoClass type.
+
+ - coders/mpc.c (WriteMPCImage): Persist is\_monochrome and
+ is\_grayscale flags.
+ (ReadMPCImage): Restore is\_monochrome and is\_grayscale flags.
+
+ - magick/constitute.c (WriteImage): Extended logging to include
+ monochrome and grayscale flags.
+ (ReadImage): Extended logging to include monochrome and grayscale
+ flags.
+
+ - magick/image.c (DescribeImage): Include the effective pixel I/O
+ rate alongside the image read/write time. This provides an easier
+ way to evaluate image read/write performance when looking at
+ `identify` or `convert -verbose` output.
+
+ - coders/sun.c (ReadSUNImage): Ensure that pixel length value does
+ not overflow for large images.
+
+2005-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/cache.c (SetImagePixels): Improved documentation.
+ (GetImagePixels): Improved documentation.
+
+2005-03-10 Glenn Randers-Pehrson <glennrp@glennrp.com>
+
+ - coders/png.c: Avoid attempting to write indexed PNG when
+ a color entry has more than one opacity level. The PNG format
+ supports this but GM's colormap does not, so erroneous files
+ were being written.
+
+2005-03-09 Arne Rusek <zonk@matfyz.cz>
+
+ - magick/attribute.c (GenerateEXIFAttribute): Offset type
+ correction to fix loop termination if size\_t type is not `long`.
+
+2005-03-09 Alexander Yaworsky <yaworsky@users.sourceforge.net>
+
+ - coders/jbig.c (WriteJBIGImage): JBIG was writing an empty output
+ file. Apparently libjbig parameters have changed. Setting l0
+ parameter of jbg\_enc\_options to zero instead of -1 (like in
+ jbigkit's pbmtools) solved the problem.
+
+2005-03-07 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick\magick\GM\_magick.bpr: Updated to reflect changes since
+ last update.
+
+ - BCBMagick\magick\libMagick.bpr: Updated to reflect changes since
+ last update.
+
+2005-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/alpha\_composite.h (AlphaComposite): Moved AlphaComposite
+ to new alpha\_composite.h header since it was causing porting
+ problems.
+
+ - magick/constitute.h (enum QuantumType): Added CIEYQuantum and
+ CIEXYZQuantum quantum import options.
+
+ - coders/tiff.c (ReadTIFFImage): Import LogLuv image data within
+ GraphicsMagick (rather than libtiff) so that color resolution is
+ not lost. Results in a small speedup as well.
+
+ - magick/constitute.c (ImportImagePixelArea): Add a speed-up for
+ importing bi-level images. Add support for importing pixels in
+ CIE XYZ and CIE Y colorspaces.
+
+ - coders/tiff.c (ReadTIFFImage): Support reading TIFF images which
+ fail to properly scale the samples to the sample size (e.g. 12
+ bits in a 16-bit sample).
+ (WriteTIFFImage): Adjustments to strip-size (rows-per-strip)
+ estimation.
+
+ - magick/constitute.c (ExportImagePixelArea): Support exporting
+ unsigned samples with values which span only part of the range.
+ For example, 12 bit data may be exported within 16 bit samples,
+ with a value range of 0 to 4095.
+ (ImportImagePixelArea): Support importing unsigned samples with
+ values which span only part of the range.
+
+2005-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Support reading TIFF files in
+ IEEEFP format.
+ (WriteTIFFImage): Support writing TIFF files in IEEEFP format.
+
+ - magick/constitute.c (ExportImagePixelArea): Support exporting
+ floating point data.
+ (ImportImagePixelArea): Support importing floating point data.
+
+2005-02-26 Albert Chin-A-Young <china@thewrittenword.com>
+
+ - acinclude.m4 (AC\_CXX\_IOS\_BINARY): Added macro to detect if the
+ C++ compiler lacks support for ios::binary.
+
+ - configure.ac: Use AC\_CXX\_IOS\_BINARY.
+
+2005-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Read grayscale TIFFs as
+ DirectClass rather than promoting to PseudoClass. Fix improper
+ multiple repeated "disassociate" operations when reading planar
+ images which contain an alpha channel.
+ (WriteTIFFImage): Fix improper multiple repeated "associate"
+ operations when writing planar images with an alpha channel.
+
+2005-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - win2k/IMDisplay/IMDisplayView.cpp (DoDisplayImage): Use
+ TextureImage to apply background pattern.
+
+ - magick/image.c (TextureImage): Alpha blend the texture onto the
+ background if the image has a matte channel.
+
+ - magick/constitute.h (enum QuantumType): Eliminated
+ GrayInvertedQuantum and GrayInvertedAlphaQuantum which were added
+ since GraphicsMagick 1.1. Replaced this "inverted" gray
+ functionality with the grayscale\_inverted flag in
+ ExportPixelAreaOptions and ImportPixelAreaOptions.
+
+ - magick/constitute.c (ExportImagePixelArea): Added an extra
+ parameter for passing seldom used options via an
+ ExportPixelAreaOptions structure.
+ (ImportImagePixelArea): Added an extra parameter for passing
+ seldom used options via an ImportPixelAreaOptions structure.
+ (ExportPixelAreaOptionsInit): New function to initialize the
+ ExportPixelAreaOptions structure with defaults.
+ (ImportPixelAreaOptionsInit): New function to intialize the
+ ImportPixelAreaOptions structure with defaults.
+
+ - coders/jpeg.c (WriteJPEGImage): Don't use jpeglib private
+ BITS\_IN\_JSAMPLE definition to select JPEG bit depth.
+
+ - coders/tiff.c (ReadTIFFImage): Support using -define
+ tiff:alpha={unspecified|associated|unassociated} to specify the
+ alpha channel type in case the alpha channel is marked
+ incorrectly.
+ Properly read associated alpha images.
+ (WriteTIFFImage): Support using -define
+ tiff:alpha={unspecified|associated|unassociated} to override the
+ alpha channel type.
+ Properly write associated alpha images by default.
+
+2005-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WritePTIFImage): Ensure that pyramid image frames
+ are the same type as the original image.
+ (WriteTIFFImage): Added support for writing tiled TIFF.
+
+2005-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (TraceBezier): Avoid probable bug under Visual
+ C++ 7.0 or later due to the argument to pow not being promoted to
+ double.
+
+2005-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Re-wrote TIFF writing code.
+
+ - magick/image.h (MaxValueGivenBits): Renamed MaxRGBGivenBits
+ macro to MaxValueGivenBits.
+
+ - magick/constitute.h (enum QuantumType): Added UndefinedQuantum.
+
+ - magick/static.c (RegisterStaticModules): Support compiling
+ without PNG.
+
+2005-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/color.c (IsPaletteImage): Fix memory leak reported by
+ Stefan v. Wachter <svwa-dev@mnet-online.de>.
+
+ - magick/Makefile.am (MAGICK\_INCLUDE\_HDRS): Needed to install
+ magick/operator.h.
+
+ - coders/tiff.c (ReadTIFFImage): Re-wrote TIFF reading code again
+ for more flexibility and performance.
+
+2005-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Remove --disable-lzw option and HasLZW define.
+ LZW support is always enabled now.
+
+2005-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tga.c (WriteTGAImage): Incorporated patch from Stefan
+ v. Wachter to enable writing grayscale images as well as adding
+ more image type option smarts.
+
+ - coders/psd.c (ReadPSDImage): Fix stack overflow vulnerability
+ reported by Andrei Nigmatulin. See http://lwn.net/Articles/119713/
+ for details.
+
+2005-01-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - win2k/IMDisplay/IMDisplayDoc.cpp (DoReadImage): Ensure that image
+ is in RGB color space after being read since this is what Windows
+ expects.
+
+2005-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Handle extra samples in scanline
+ TIFFs.
+
+2005-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (DescribeImage): Report statistics for a virtual
+ gray channel for grayscale images rather than discrete red, green,
+ and blue.
+
+ - PerlMagick/Makefile.nt: JNG and JP2 to test list.
+
+ - configure.ac: Changed --without-fpx to --with-fpx due to
+ decision to default FlashPIX to `no`. FlashPIX library is not
+ very portable and is only known to work properly under SPARC
+ Solaris and Windows.
+
+ - NEWS: Updated with latest news.
+
+ - lcms: Updated to LCMS 1.14.
+
+2005-01-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (ReadJP2Image): Handle images in YCBCR colorspace.
+ (ReadJP2Image): Retrieve and store an ICC ICM color profile if
+ present.
+
+ - PerlMagick/t/tiff/read.t: Added test for reading truecolor
+ planar TIFF image.
+ Added test for reading 32-bit TrueColor TIFF image.
+ Added test for reading 32-bit grayscale TIFF image.
+
+ - coders/tiff.c (ReadTIFFImage): Fixed stripped TIFF reader.
+
+2005-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Only set TIFFTAG\_PREDICTOR to 2
+ for bits-per-sample values that libtiff supports.
+
diff --git a/www/ChangeLog-2006.html b/www/ChangeLog-2006.html
new file mode 100644
index 0000000..012172f
--- /dev/null
+++ b/www/ChangeLog-2006.html
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2006-11-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Magick++/Image.html: Fix documentation regarding retrieving
+EXIF attribute.</li>
+<li>magick/command.c: Fix typo in usage messages.</li>
+</ul>
+</blockquote>
+<p>2006-11-02 Daniel Kobras &lt;<a class="reference external" href="mailto:kobras&#37;&#52;&#48;debian&#46;org">kobras<span>&#64;</span>debian<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcm.c: (ReadDCMImage) Prevent buffer overflow of
+<cite>photometric</cite> array in DCM coder. Original patch thanks to
+M Joonas Pihlaja. (CVE-2006-5456)</li>
+<li>coders/palm.c: (ReadPALMImage) Fix heap overflows of <cite>one_row</cite>
+array in PALM coder. Original patch thanks to M Joonas Pihlaja.
+(CVE-2006-5456)</li>
+</ul>
+</blockquote>
+<p>2006-10-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated libtool to latest CVS head version (1.2352 2006/10/24)
+in order to fix a bootstrap nit.</li>
+</ul>
+</blockquote>
+<p>2006-10-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated autoconf to version 2.60, automake to version 1.10, and
+libtool to latest CVS head version (1.2348 2006/10/22).</li>
+</ul>
+</blockquote>
+<p>2006-09-11 Daniel Kobras &lt;<a class="reference external" href="mailto:kobras&#37;&#52;&#48;debian&#46;org">kobras<span>&#64;</span>debian<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xcf.c (ReadBlobStringWithLongSize): Add new parameter <cite>max</cite>
+to prevent overflowing the <cite>string</cite> array. (CVE-2006-3743)
+(ReadOneLayer): Adjust callers of ReadBlobStringWithLongSize(), and
+guard against infinite loops on premature end-of-file.
+(ReadXCFImage): Adjust callers of ReadBlobStringWithLongSize(), and
+guard against infinite loops on premature end-of-file.</li>
+</ul>
+</blockquote>
+<p>2006-09-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sgi.c (ReadSGIImage): Mostly applied Debian patch for
+CVE-2006-4144 security issue related to RLE decoding. Also added
+complete verification of file header.</li>
+<li>magick/image.c (ComputePixelError): Add progress monitor.
+(GetImageStatisticsMean): Call progress monitor less often.
+(GetImageStatisticsVariance): Call progress monitor less often.</li>
+</ul>
+</blockquote>
+<p>2006-08-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): ImageInfo <cite>endian</cite> option now
+controls TIFF byte-order rather than bit-order when writing.</li>
+<li>coders/png.c (ReadOnePNGImage): Fix compilation problem. Patch
+submitted by Aron Stansvik.</li>
+</ul>
+</blockquote>
+<p>2006-07-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (WriteJPEGImage): Clear the JPEG library
+structures in order to ensure a completely clean slate.</li>
+</ul>
+</blockquote>
+<p>2006-06-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ConvertImageCommand): Fix memory leaks which
+occured when an image was not returned.</li>
+<li>magick/command.c (IdentifyImageCommand): Ditto.</li>
+<li>magick/command.c (MogrifyImageCommand): Ditto.</li>
+</ul>
+</blockquote>
+<p>2006-06-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Add mention of -resample to convert and
+mogrify usage messages.</li>
+</ul>
+</blockquote>
+<p>2006-05-31 Ralf Wildenhues &lt;<a class="reference external" href="mailto:Ralf&#46;Wildenhues&#37;&#52;&#48;gmx&#46;de">Ralf<span>&#46;</span>Wildenhues<span>&#64;</span>gmx<span>&#46;</span>de</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Fix arguments to AC_CHECK_HEADER.</li>
+</ul>
+</blockquote>
+<p>2006-05-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): -define tiff:alpha= override was
+only working if the TIFFTAG_EXTRASAMPLES tag was present. Now it
+is always available when an alpha channel is present.</li>
+</ul>
+</blockquote>
+<p>2006-05-11 JH &lt;<a class="reference external" href="mailto:jh&#37;&#52;&#48;ops&#46;everybox&#46;com">jh<span>&#64;</span>ops<span>&#46;</span>everybox<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec.in (files devel): Include
+%{_libdir}/lib%{name}Wand.so.</li>
+</ul>
+</blockquote>
+<p>2006-05-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (NTGhostscriptEnumerateVersions): Recent GNU
+Ghostscript identifies itself as &quot;GPL Ghostscript&quot;.</li>
+</ul>
+</blockquote>
+<p>2006-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff: Updated bundled libtiff to version 3.8.2.</li>
+</ul>
+</blockquote>
+<p>2006-04-05 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c: Sets image is_grayscale flag as well as added more
+symbolic constants.</li>
+</ul>
+</blockquote>
+<p>2006-04-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (IMAGE_DATA_ROUNDING): Thanks to Steve Sloan for
+noticing that 8K is 8192 rather than 8092. Added a define to
+allow tailoring the pixel data alignment boundary in case 8K is
+not the right answer for some reason.</li>
+</ul>
+</blockquote>
+<p>2006-03-20 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c: Ensure that unusued opacity channel is set to opaque.</li>
+<li>PerlMagick/t/input.art: New ART test image.</li>
+<li>PerlMagick/t/input8.mat: New MATLAB test image (8-bit indexed).</li>
+<li>PerlMagick/t/input_dbl.mat: New MATLAB test image (double grey)</li>
+<li>PerlMagick/t/input_rgb.mat: New MATLAB test image (8-bit RGB)</li>
+</ul>
+</blockquote>
+<p>2006-03-19 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c: Use symbolic constants rather than plain numbers
+so the module is more maintainable. Correct the format for the
+day of the week.</li>
+</ul>
+</blockquote>
+<p>2006-03-13 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c (WriteMATLABImage): Add RGB writer support for
+MATLAB format.</li>
+</ul>
+</blockquote>
+<p>2006-03-11 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c (ReadMATImage): RGB support for MAT reader.</li>
+</ul>
+</blockquote>
+<p>2006-03-02 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c: Fixes for observed crash. Byte and word formats
+are working.</li>
+</ul>
+</blockquote>
+<p>2006-02-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/environment.imdoc: MAGICK_FONT_PATH has not been supported
+since 1.1. Remove mention of it!</li>
+</ul>
+</blockquote>
+<p>2006-02-23 Mike Chiarappa &lt;<a class="reference external" href="mailto:mikechiarappa&#37;&#52;&#48;libero&#46;it">mikechiarappa<span>&#64;</span>libero<span>&#46;</span>it</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BCBMagick: Updated to latest changes</li>
+</ul>
+</blockquote>
+<p>2006-02-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sgi.c (ReadSGIImage): Properly compute image depth for
+16-bit SGI image files.</li>
+</ul>
+</blockquote>
+<p>2006-01-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetExecutionPathUsingName): Search executable
+search path for binary.</li>
+</ul>
+</blockquote>
+<p>2006-01-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage, WriteDPXImage): Alpha channel in DPX
+uses zero, or reference black, to represent an opaque pixel.</li>
+</ul>
+</blockquote>
+<p>2006-01-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/semaphore.c (AllocateSemaphoreInfo): Allow semaphores to
+recurse on POSIX systems which support recursive semaphores but
+also warn if the semaphore recurses.</li>
+<li><dl class="first docutils">
+<dt>magick/log.c (SetLogEventMask): Avoid deadlock if invoked before</dt>
+<dd>log.mgk has been loaded.</dd>
+</dl>
+</li>
+<li>magick/attribute.c (GenerateEXIFAttribute): Fix memory leak on
+error which was reported by Micha³ Kowalczuk.</li>
+</ul>
+</blockquote>
+<p>2006-01-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ReadImage): Avoid crash if delegate fails
+to return image.</li>
+</ul>
+</blockquote>
+<p>2006-01-03 Daniel Kobras &lt;<a class="reference external" href="mailto:kobras&#37;&#52;&#48;debian&#46;org">kobras<span>&#64;</span>debian<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GenerateEXIFAttribute): Fix EXIF IFD stack
+overflow vulnerability.</li>
+<li>configure.ac: Fix typo in HTMLDecodeDelegate.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2006.rst b/www/ChangeLog-2006.rst
new file mode 100644
index 0000000..03610e6
--- /dev/null
+++ b/www/ChangeLog-2006.rst
@@ -0,0 +1,189 @@
+2006-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Magick++/Image.html: Fix documentation regarding retrieving
+ EXIF attribute.
+
+ - magick/command.c: Fix typo in usage messages.
+
+2006-11-02 Daniel Kobras <kobras@debian.org>
+
+ - coders/dcm.c: (ReadDCMImage) Prevent buffer overflow of
+ `photometric` array in DCM coder. Original patch thanks to
+ M Joonas Pihlaja. (CVE-2006-5456)
+
+ - coders/palm.c: (ReadPALMImage) Fix heap overflows of `one\_row`
+ array in PALM coder. Original patch thanks to M Joonas Pihlaja.
+ (CVE-2006-5456)
+
+2006-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated libtool to latest CVS head version (1.2352 2006/10/24)
+ in order to fix a bootstrap nit.
+
+2006-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated autoconf to version 2.60, automake to version 1.10, and
+ libtool to latest CVS head version (1.2348 2006/10/22).
+
+2006-09-11 Daniel Kobras <kobras@debian.org>
+
+ - coders/xcf.c (ReadBlobStringWithLongSize): Add new parameter `max`
+ to prevent overflowing the `string` array. (CVE-2006-3743)
+ (ReadOneLayer): Adjust callers of ReadBlobStringWithLongSize(), and
+ guard against infinite loops on premature end-of-file.
+ (ReadXCFImage): Adjust callers of ReadBlobStringWithLongSize(), and
+ guard against infinite loops on premature end-of-file.
+
+2006-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sgi.c (ReadSGIImage): Mostly applied Debian patch for
+ CVE-2006-4144 security issue related to RLE decoding. Also added
+ complete verification of file header.
+
+ - magick/image.c (ComputePixelError): Add progress monitor.
+ (GetImageStatisticsMean): Call progress monitor less often.
+ (GetImageStatisticsVariance): Call progress monitor less often.
+
+2006-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): ImageInfo `endian` option now
+ controls TIFF byte-order rather than bit-order when writing.
+
+ - coders/png.c (ReadOnePNGImage): Fix compilation problem. Patch
+ submitted by Aron Stansvik.
+
+2006-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (WriteJPEGImage): Clear the JPEG library
+ structures in order to ensure a completely clean slate.
+
+2006-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ConvertImageCommand): Fix memory leaks which
+ occured when an image was not returned.
+
+ - magick/command.c (IdentifyImageCommand): Ditto.
+
+ - magick/command.c (MogrifyImageCommand): Ditto.
+
+2006-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Add mention of -resample to convert and
+ mogrify usage messages.
+
+2006-05-31 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ - configure.ac: Fix arguments to AC\_CHECK\_HEADER.
+
+2006-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): -define tiff:alpha= override was
+ only working if the TIFFTAG\_EXTRASAMPLES tag was present. Now it
+ is always available when an alpha channel is present.
+
+2006-05-11 JH <jh@ops.everybox.com>
+
+ - GraphicsMagick.spec.in (files devel): Include
+ %{\_libdir}/lib%{name}Wand.so.
+
+2006-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (NTGhostscriptEnumerateVersions): Recent GNU
+ Ghostscript identifies itself as "GPL Ghostscript".
+
+2006-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff: Updated bundled libtiff to version 3.8.2.
+
+2006-04-05 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c: Sets image is\_grayscale flag as well as added more
+ symbolic constants.
+
+2006-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (IMAGE\_DATA\_ROUNDING): Thanks to Steve Sloan for
+ noticing that 8K is 8192 rather than 8092. Added a define to
+ allow tailoring the pixel data alignment boundary in case 8K is
+ not the right answer for some reason.
+
+2006-03-20 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c: Ensure that unusued opacity channel is set to opaque.
+
+ - PerlMagick/t/input.art: New ART test image.
+
+ - PerlMagick/t/input8.mat: New MATLAB test image (8-bit indexed).
+
+ - PerlMagick/t/input\_dbl.mat: New MATLAB test image (double grey)
+
+ - PerlMagick/t/input\_rgb.mat: New MATLAB test image (8-bit RGB)
+
+2006-03-19 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c: Use symbolic constants rather than plain numbers
+ so the module is more maintainable. Correct the format for the
+ day of the week.
+
+2006-03-13 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c (WriteMATLABImage): Add RGB writer support for
+ MATLAB format.
+
+2006-03-11 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c (ReadMATImage): RGB support for MAT reader.
+
+2006-03-02 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c: Fixes for observed crash. Byte and word formats
+ are working.
+
+2006-02-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/environment.imdoc: MAGICK\_FONT\_PATH has not been supported
+ since 1.1. Remove mention of it!
+
+2006-02-23 Mike Chiarappa <mikechiarappa@libero.it>
+
+ - BCBMagick: Updated to latest changes
+
+2006-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sgi.c (ReadSGIImage): Properly compute image depth for
+ 16-bit SGI image files.
+
+2006-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetExecutionPathUsingName): Search executable
+ search path for binary.
+
+2006-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage, WriteDPXImage): Alpha channel in DPX
+ uses zero, or reference black, to represent an opaque pixel.
+
+2006-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/semaphore.c (AllocateSemaphoreInfo): Allow semaphores to
+ recurse on POSIX systems which support recursive semaphores but
+ also warn if the semaphore recurses.
+
+ - magick/log.c (SetLogEventMask): Avoid deadlock if invoked before
+ log.mgk has been loaded.
+
+ - magick/attribute.c (GenerateEXIFAttribute): Fix memory leak on
+ error which was reported by Micha Kowalczuk.
+
+2006-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ReadImage): Avoid crash if delegate fails
+ to return image.
+
+2006-01-03 Daniel Kobras <kobras@debian.org>
+
+ - magick/attribute.c (GenerateEXIFAttribute): Fix EXIF IFD stack
+ overflow vulnerability.
+
+ - configure.ac: Fix typo in HTMLDecodeDelegate.
+
diff --git a/www/ChangeLog-2007.html b/www/ChangeLog-2007.html
new file mode 100644
index 0000000..3ce19ba
--- /dev/null
+++ b/www/ChangeLog-2007.html
@@ -0,0 +1,1079 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2007-12-23 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/configure/configure.rc: Better positioning of frog,
+changed original ImageMagick messages.</li>
+<li>VisualMagick/configure/configure.exe: New build.</li>
+</ul>
+</blockquote>
+<p>2007-12-22 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Fix compilability issue for Microsoft Visual
+Studio 6.</li>
+</ul>
+</blockquote>
+<p>2007-12-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Use some improved tests for POSIX standard types
+available in Autoconf 2.61.
+Add support for configuring a magick_uintmax_t type.
+Added support for configuring a magick_uintptr_t type.</li>
+</ul>
+</blockquote>
+<p>2007-12-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.h (MagickSafeMultiplySize_t): New function to
+perform a safe multiply. A multiplication overflow results in
+zero.
+(MagickAllocateMemory): Check for size_t value truncation/overflow
+and zero size before deciding to allocate memory. Any detected
+failure results in a NULL pointer being returned.
+(MagickReallocMemory): Add a type parameter to use in cast in
+order to avoid C++ portability problem.</li>
+<li>PerlMagick/Magick.xs: Eliminate use of deprecated methods.</li>
+<li>magick/memory.c (MagickAcquireMemory): New function to allocate
+memory.
+(MagickAcquireMemoryArray): New function to allocate memory for an
+array of objects.
+(MagickCloneMemory): New function to intelligently copy memory.
+(MagickReallocateMemory): New function to re-allocate memory.
+(MagickReleaseMemory): New function to deallocate memory.</li>
+<li>magick/deprecate.c (AcquireMemory): Deprecated in favor of new
+function MagickAcquireMemory().
+(CloneMemory): Deprecated in favor of new function
+MagickCloneMemory().
+(LiberateMemory): Deprecated in favor of new function
+MagickReleaseMemory().
+(ReacquireMemory): Deprecated in favor of new function
+MagickReallocateMemory().</li>
+</ul>
+</blockquote>
+<p>2007-11-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ReadImage): Log colorspace of returned image.
+(WriteImage): Log colorspace of image to be written.</li>
+<li>coders/{miff.c,mpc.c,tga.c,tiff.c}: Use MagickBoolToString().</li>
+<li>magick/{constitute.c,xwindow.c}: Use MagickBoolToString().</li>
+<li>magick/image.h (MagickBoolToString): New macro to convert truth
+value to a constant &quot;True&quot; or &quot;False&quot; string.</li>
+</ul>
+</blockquote>
+<p>2007-11-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (IsImagesEqual): Allow comparing images if the
+colorspace enumeration is different but the images are both an RGB
+type.</li>
+</ul>
+</blockquote>
+<p>2007-11-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Add support for -monitor option to <cite>animate</cite>,
+<cite>display</cite>, and <cite>import</cite>.</li>
+<li>coders/fpx.c (WriteFPXImage): Fix compilation problem.</li>
+<li>coders/dpx.c (TentUpsampleChroma): Fix access beyond array. Use
+integer calculations where possible.</li>
+</ul>
+</blockquote>
+<p>2007-11-07 Andy Armstrong &lt;<a class="reference external" href="mailto:andy&#37;&#52;&#48;hexten&#46;net">andy<span>&#64;</span>hexten<span>&#46;</span>net</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/setattribute.t: Fix for typo which breaks
+Test::Harness 3.00.</li>
+</ul>
+</blockquote>
+<p>2007-10-20 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>mat.c: Attempt to read <cite>logic</cite> type modification</dt>
+<dd>as monochrome image.</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2007-10-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (ReadBlob?SBFoo): Return 0 on EOF conditions
+rather than a magic value concocted using ~0. The magic value was
+very sensitive to the size/range of the type used to pass and
+store it, leading to increased possibility of error. There was
+also concern that sometimes a successfully read value may match
+the magic value. Added documentation that EOFBlob() may be used
+to determine that the blob is in EOF state.</li>
+<li>coders/pix.c (ReadPIXImage): Avoid reliance on a particular
+magic value being returned from ReadBlobMSBShort on EOF.</li>
+<li>coders/avs.c (ReadAVSImage): Avoid reliance on a particular
+magic value being returned from ReadBlobMSBLong() on EOF.</li>
+</ul>
+</blockquote>
+<p>2007-10-07 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wpg.c: Monochrome images are not using palette -
+palette is discarded in this case.</li>
+</ul>
+</blockquote>
+<p>2007-10-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.h: Blob I/O APIs now use sized types so that passed
+and returned data values are a specific size rather than
+architecture dependent.</li>
+<li>PerlMagick/t/read.t: Added read test for unsigned 32-bit LSB MAT
+format.</li>
+</ul>
+</blockquote>
+<p>2007-10-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dib.c (ReadDIBImage): Use appropriate sized cast for DIB
+width and height values. Validate width and height values.</li>
+<li>coders/bmp.c (ReadBMPImage): Use appropriate sized cast for BMP
+width and height values.</li>
+<li>magick/colorspace.c (RGBTransformImage): Use a better rounding
+algorithm when converting to HSL/HWB colorspaces.</li>
+<li>magick/gem.c (TransformHSL): Avoid GCC opimization bug on
+Opteron which caused wrong results. Ensure that returned values
+fall within bounds 0.0 to 1.0.
+(TransformHWB): Avoid GCC opimization bug on
+Opteron which caused wrong results. Ensure that returned values
+fall within bounds 0.0 to 1.0.</li>
+<li>PerlMagick/t/ttf/read.t: Relax strictness quite a bit for TTF
+read tests in order to allow somewhat different FreeType output.</li>
+</ul>
+</blockquote>
+<p>2007-09-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colorspace.c (RGBTransformImage): Add missing break
+statement. HWB colorspace was used rather than HSL.
+(TransformRGBImage): Add missing break
+statement. HWB colorspace was used rather than HSL.</li>
+</ul>
+</blockquote>
+<p>2007-09-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sun.c (ReadSUNImage): Properly report SUN image depth.</li>
+</ul>
+</blockquote>
+<p>2007-09-28 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Ability to write multiple images to one MAT file.
+Fixed bug - incorrect matrix size for gray image.</li>
+</ul>
+</blockquote>
+<p>2007-09-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c (IntegralRotateImage): Rotation by 270 degrees
+was wrong. It was flipped from what it should be.</li>
+</ul>
+</blockquote>
+<p>2007-09-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (CommandProgressMonitor): Remove any preceding
+whitespace in the task descriptions so that we don't need to
+update all of the task descriptions right away.</li>
+<li>magick/colorspace.c (RGBTransformImage): Improve progress monitor message.
+(TransformRGBImage): Improve progress monitor message.</li>
+<li>coders/miff.c (ReadMIFFImage): Add read progress monitor support.</li>
+</ul>
+</blockquote>
+<p>2007-09-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c (WritePDFImage): Fix writing PDF with CCITT
+compression. Addresses SourceForge bug 1209177 &quot;TIFF to PDF CCITT
+compression fails&quot;.</li>
+</ul>
+</blockquote>
+<p>2007-09-14 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Ability to read multiple images from one MAT file.
+changed ExtendedSignedIntegralType to magick_off_t that better
+corresponds to file positioning.</li>
+</ul>
+</blockquote>
+<p>2007-09-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c (WritePDFImage): Use ThumbnailImage() to create
+thumbnail.</li>
+<li>coders/preview.c (WritePreviewImage): Use ThumbnailImage() to
+create thumbnail.</li>
+<li>coders/xpm.c (WritePICONImage): Use ThumbnailImage() to create
+thumbnail.</li>
+</ul>
+</blockquote>
+<p>2007-09-14 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Several warnings has been suppressed.</li>
+</ul>
+</blockquote>
+<p>2007-09-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Fix writing to pipes and other
+non-seekable output destinations.</li>
+<li>magick/blob.c (WriteBlobFile): New function to copy a disk file
+to a blob stream.</li>
+<li>magick/profile.c (ProfileImage): Fix removing profiles.</li>
+</ul>
+</blockquote>
+<p>2007-09-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (png_flush_data): Don't invoke SyncBlob() since it
+does far more than force data to the output file.
+(ReadPNGImage): Make sure that PNG read errors are reported to the
+user.</li>
+<li>coders/jpeg.c (TerminateDestination): Don't invoke SyncBlob()
+since it does far more than force data to the output file.</li>
+<li>magick/blob.c (SyncBlob): Remove from public interface.</li>
+</ul>
+</blockquote>
+<p>2007-09-12 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Allowed to read signed integer matrices.
+Fixed loop break.</li>
+</ul>
+</blockquote>
+<p>2007-09-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Ensure that selected photometric
+most closely matches the user's expectation. Remove compression
+if requested compression type is not compatible with the selected
+photometric.</li>
+</ul>
+</blockquote>
+<p>2007-09-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c (IntegralRotateImage): Use tiles to speed up
+rotation by 90 or 270 degrees.</li>
+</ul>
+</blockquote>
+<p>2007-09-07 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c The flop image has been eliminated in a reader.
+Code has been shrinked a little bit.</li>
+</ul>
+</blockquote>
+<p>2007-09-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GetImageCharacteristics): Add progress monitor support.</li>
+<li>magick/color.c (IsMonochromeImage): Add progress monitor support.
+(IsGrayImage): Add progress monitor support.
+(IsOpaqueImage): Add progress monitor support.</li>
+<li>coders/dpx.c (ReadDPXImage): Added progress indication.</li>
+<li>coders/cineon.c (WriteCINEONImage): Added progress indication.</li>
+<li>magick/command.c : Added a -monitor command option for
+<cite>composite</cite>, <cite>convert</cite>, <cite>identify</cite>, <cite>mogrify</cite>, and <cite>montage</cite> in
+order to enable a simple progress indicator.</li>
+</ul>
+</blockquote>
+<p>2007-09-06 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Write native gray MAT data when gray image is detected.</li>
+</ul>
+</blockquote>
+<p>2007-09-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetExecutionPath): Add support for Apple OS-X,
+Linux, and FreeBSD.</li>
+</ul>
+</blockquote>
+<p>2007-09-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: For Windows MinGW-based build, find Ghostscript
+fonts installed under C:/Program Files/.</li>
+<li>VisualMagick/bin/delegates.mgk: Adjust quoting to Ghostscript arguments
+so that Ghostscript DLL is passed correct commands.</li>
+<li>config/delegates.mgk.in: Adjust quoting to Ghostscript arguments
+so that Ghostscript DLL is passed correct commands.</li>
+<li>configure.ac: Provide defaults for GSColorAlphaDevice and GSGrayDevice.</li>
+<li>magick/nt_base.c (NTGhostscriptGetString): Support &quot;GPL Ghostscript&quot;.</li>
+</ul>
+</blockquote>
+<p>2007-09-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/ps.c (WritePSImage): Improved Postscript writer
+performance.</li>
+</ul>
+</blockquote>
+<p>2007-09-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c (AllocateImageProfileIterator): New function to
+allocate an image profile iterator.
+(DeallocateImageProfileIterator): New function to deallocate an
+image profile iterator.
+(NextImageProfile): New function to advance the image profile
+iterator to the next profile.</li>
+<li>magick/image.h (Image): Profiles are now stored in a generic
+container. As planned years ago, the color_profile, iptc_profile,
+generic_profile, and generic_profiles members are now removed.</li>
+</ul>
+</blockquote>
+<p>2007-09-01 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c Ability to read true color bitmap with invalid palette size
+like other readers do.</li>
+</ul>
+</blockquote>
+<p>2007-08-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (ClonePixelCacheMethods): Remove DLL export.
+(DestroyCacheInfo): Remove DLL export.
+(GetCacheInfo): Remove DLL export.
+(ReferenceCache): Remove DLL export.</li>
+</ul>
+</blockquote>
+<p>2007-08-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageType): More tweaks to obtain the desired
+behavior when converting to a bilevel image.</li>
+<li>coders/tiff.c (WriteTIFFImage): Logic which decided the output
+subformat to write was too convoluted to understand, and in fact
+palette images were not be written sometimes when they should be
+(bug added on 2007-08-19). Deleted the convoluted code and
+replaced with a different design which should be more correct and
+flexible.
+(ReadTIFFImage): Decided to read bilevel TIFF using a colormap
+since there are significant internal advantages to doing so.
+However, the writer is carefully designed to output normal bilevel
+TIFF so this should not annoy TIFF users.</li>
+<li>magick/constitute.c (ImportImagePixelArea): Re-wrote grayscale
+pseudoclass import to be more efficient and more tidy.</li>
+</ul>
+</blockquote>
+<p>2007-08-30 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/art.c Added ART writer</li>
+</ul>
+</blockquote>
+<p>2007-08-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (ReadBlobLSBFloat): Promoted to be a public
+interface (was in mat.c).
+(ReadBlobMSBFloat):Promoted to be a public interface (was in
+mat.c).</li>
+</ul>
+</blockquote>
+<p>2007-08-29 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/art.c InsertRow has been replaced by ImportImagePixelArea</li>
+</ul>
+</blockquote>
+<p>2007-08-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (ReadPNMImage): PNM &quot;raw&quot; formats are now read
+using ImportImagePixelArea()</li>
+<li>magick/constitute.c (ExportImagePixelArea): Added an optional
+export_info parameter for returning information back to the user.
+(ImportImagePixelArea): Added an optional import_info parameter
+for returning information back to the user.</li>
+<li>coders/jbig.c (ReadJBIGImage): Use ImportImagePixelArea().
+(WriteJBIGImage): Use ExportImagePixelArea();</li>
+<li>coders/tiff.c (WriteTIFFImage): Make compression logic a bit
+more tidy.</li>
+<li>coders/pcx.c (WritePCXImage): Use GetImageCharacteristics().</li>
+<li>coders/pcl.c (WritePCLImage): Use GetImageCharacteristics().</li>
+<li>coders/dib.c (WriteDIBImage): Use GetImageCharacteristics().</li>
+<li>coders/xpm.c (WritePICONImage): Use GetImageCharacteristics().</li>
+<li>coders/viff.c (WriteVIFFImage): Use GetImageCharacteristics().</li>
+<li>coders/tga.c (WriteTGAImage): Use GetImageCharacteristics().</li>
+<li>coders/sgi.c (WriteSGIImage): Use GetImageCharacteristics().</li>
+<li>coders/ps2.c (WritePS2Image): Use GetImageCharacteristics().</li>
+<li>coders/pdf.c (WritePDFImage): Use GetImageCharacteristics().</li>
+<li>coders/palm.c (WritePALMImage): Use GetImageCharacteristics().</li>
+<li>coders/ps.c (WritePSImage): Use GetImageCharacteristics().</li>
+<li>coders/jp2.c (WriteJP2Image): Use GetImageCharacteristics().</li>
+<li>coders/jpeg.c (WriteJPEGImage): Use GetImageCharacteristics().</li>
+<li>PerlMagick/t/read.t: Added read test for LSB <cite>float</cite> MAT.</li>
+</ul>
+</blockquote>
+<p>2007-08-26 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c: MAT reader now extensively uses ImportImagePixelArea.</li>
+</ul>
+</blockquote>
+<p>2007-08-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am: Add rwblob and rwfile tests for MAT format.</li>
+<li>magick/constitute.c: Re-wrote Export/Import Float/Double macros
+because they did not actually work right, and to eliminate the
+performance penalty for native order.</li>
+</ul>
+</blockquote>
+<p>2007-08-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Add support for &quot;native&quot; endian parameter
+in PerlMagick.</li>
+<li>magick/command.c: Utilities now understand &quot;native&quot; as an
+argument to -endian.</li>
+<li>magick/image.h (enum EndianType): Added NativeEndian enum value.</li>
+<li>configure.ac: Test libtiff for TIFFSwabArrayOfTriples().</li>
+<li>magick/constitute.c (ExportImagePixelArea): Support export in
+little, big, and native endian.
+(ImportImagePixelArea): Support import in little, big, and native
+endian.</li>
+</ul>
+</blockquote>
+<p>2007-08-23 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c (WriteMATLABImage): MAT writer uses
+ExportImagePixelArea() now. Fix issues noticed by valgrind.</li>
+</ul>
+</blockquote>
+<p>2007-08-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (WritePNMImage): Use <cite>-quality 0</cite> rather than
+<cite>-compress none</cite> to select the PNM ASCII subformats. This change
+is made based on the principle of least surprise.</li>
+<li>magick/constitute.c (ExportImagePixelArea): Add a GrayQuantum
+implementation for exporting from two color PsuedoClass.</li>
+<li>coders/pnm.c (WritePNMImage): Use GetImageCharacteristics() and
+ExportImagePixelArea() in implementation.</li>
+</ul>
+</blockquote>
+<p>2007-08-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ExportImagePixelArea): Performance
+improvements.
+(ImportImagePixelArea): Performance improvements.</li>
+</ul>
+</blockquote>
+<p>2007-08-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (IdentifyImageCommand): If &quot;%r&quot; is present in
+-format specifier, then read whole image.</li>
+<li>magick/utility.c (TranslateTextEx): Undocumented &quot;%r&quot;
+substitution now returns a string based on GetImageType() rather
+than a concatentation of image class and &quot;Matte&quot;.</li>
+<li>coders/tiff.c (WriteTIFFImage): Use GetImageCharacteristics().</li>
+<li>magick/image.c (GetImageCharacteristics): New function to
+evaluate the basic characteristics of the image.
+(GetImageType): Use GetImageCharacteristics().</li>
+</ul>
+</blockquote>
+<p>2007-08-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (RegisterDPXImage): Remove extra newline in usage
+note.</li>
+<li>coders/fax.c (RegisterFAXImage): Fix note to reflect that the
+output from this coder is *not* a TIFF subformat as was previously
+claimed.</li>
+<li>coders/tiff.c (WriteTIFFImage): Output G3 TIFF FAX images as per
+the TIFF Class F specification.</li>
+</ul>
+</blockquote>
+<p>2007-08-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/{api.h, studio.h}: Strip out legacy MacOS 9 and VMS &quot;support&quot;.</li>
+<li>magick/{nt_base.c, unix_port.c} (MagickGetMMUPageSize): New function to obtain
+the VM page size.</li>
+<li>magick/pixel_cache.c (PersistCache): Fix a terrible memory leak
+when reading MPC files. Added Cache reference-count logging.</li>
+</ul>
+</blockquote>
+<p>2007-08-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (BenchMarkSubCommand): Added a new <cite>benchmark</cite>
+GraphicsMagick command which can be used to perform benchmarking
+on any other GraphicsMagick command.</li>
+</ul>
+</blockquote>
+<p>2007-08-11 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c (ReadMATImage): Support image is_grayscale flag.
+Add some coder logging.</li>
+</ul>
+</blockquote>
+<p>2007-08-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/{paint.c, render.c, annotate.c}: Use AlphaComposite()
+from alpha_composite.h.</li>
+<li>magick/alpha_composite.h (BlendComposite): Move inline
+BlendComposite() to a header file since it is used in multiple
+places.</li>
+<li>magick/{shear.c, image.c}: Use BlendComposite() from
+alpha_composite.h.</li>
+<li>magick/image.c (SetImageDepth): Don't bother to test current
+depth in advance. Preserve is_monochrome flag. Encapsulate
+bit-reduction algorithm in a macro. Be a bit smarter with
+PseudoClass images.
+(SyncImage): Preserve is_monochrome flag. Improve performance
+when image does not have an opacity channel.</li>
+<li>PerlMagick/t/read.t: Allow some error when reading double MAT.</li>
+</ul>
+</blockquote>
+<p>2007-08-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/read.t: Update MAT read tests according to
+instructions from Fojtik Jaroslav.</li>
+</ul>
+</blockquote>
+<p>2007-08-06 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c (ReadWPGImage): Support WPG files which use XOR
+operator.</li>
+</ul>
+</blockquote>
+<p>2007-08-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (ReadBlobLSBdouble): Migrate from mat.c.
+(ReadBlobMSBdouble): Migrate from mat.c.</li>
+</ul>
+</blockquote>
+<p>2007-08-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ExportImagePixelArea): Add optimized
+support for 2 and 16 color PseudoClass.
+(ImportImagePixelArea): Add optimized support for 2 and 16 color
+PseudoClass.</li>
+<li>magick/constitute.c (ImportImagePixelArea): Add option to output
+pad bytes at end of pixel data. Added optimized implementation of
+IndexQuantum for bilevel images.</li>
+<li>coders/tiff.c (WriteTIFFImage): Be smarter when writing gray
+Palette and grayscale TIFF images in order to not waste time.</li>
+<li>coders/bmp.c (ReadBMPImage): Use ImportImagePixelArea() when
+reading and writing bilevel and colormapped images.
+(WriteBMPImage): Use ExportImagePixelArea() when writing bilevel
+images.</li>
+<li>magick/version.h.in: Added wrapping for copyright line to a
+reasonable width.</li>
+<li>AUTHORS: Added Daniel Kobras.</li>
+<li>magick/command.c (VersionCommand): Added feature support list to
+-version output.</li>
+</ul>
+</blockquote>
+<p>2007-08-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (AnimateImageCommand): Add support for -type to
+<cite>animate</cite>.
+(DisplayImageCommand): Add support for -type to <cite>convert</cite></li>
+<li>config/delegates.mgk.in, VisualMagick/bin/delegates.mgk: Added
+gs-gray and gs-color+alpha delegate definitions.</li>
+<li>coders/{ept.c, pdf.c, ps.c}: Respect a -type Bilevel, Grayscale,
+TrueColor, or TrueColorMatte request by passing appropriate
+options to Ghostscript for rendering..</li>
+</ul>
+</blockquote>
+<p>2007-07-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ImportImagePixelArea): Improved read speed
+for bilevel gray image. Many thanks to Mark Mitchell for
+inspiration and ideas.</li>
+<li>coders/caption.c (ReadCAPTIONImage): Eliminate use of strcpy().</li>
+<li>coders/pnm.c (ReadPNMImage): Add logging as well as support for
+is_monochrome and is_grayscale flags.</li>
+<li>magick/color.h (IsMonochrome): Add parenthesis so macro is more
+robust.</li>
+</ul>
+</blockquote>
+<p>2007-07-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/html.c (WriteHTMLImage): Eliminate use of strncat().</li>
+<li>coders/locale.c (ReadConfigureFile): Eliminate use of strncat().</li>
+<li>coders/png.c (ReadOnePNGImage): Eliminate use of strncat().</li>
+<li>magick/fx.c (ConvolveImage): Eliminate use of strncat().</li>
+<li>coders/tiff.c (WriteTIFFImage): Eliminate use of strncat().</li>
+<li>magick/delegate.c (InvokePostscriptDelegate): Eliminate
+doubled-output when running in verbose mode.</li>
+</ul>
+</blockquote>
+<p>2007-07-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/delegate.c (InvokePostscriptDelegate): MagickSpawnVP()
+requires three parameters.</li>
+</ul>
+</blockquote>
+<p>2007-07-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>bzlib: Updated bzip2 to 1.0.4.</li>
+<li>jbig: Updated jbigkit to 1.6</li>
+<li>jp2: Updated JasPer to 1.900.1.</li>
+<li>lcms: Updated lcms to 1.16</li>
+<li>png: Updated libpng to 1.2.18.</li>
+</ul>
+</blockquote>
+<p>2007-07-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xc.c (ReadXCImage): If ImageInfo type field is set to
+TrueColorType or TrueColorMatteType type, then return a
+DirectClass image, otherwise a PseudoClass image is returned as
+before. From the command line this can be used like:
+<cite>gm convert -size 640x480 -type TrueColor xc:red red.miff</cite>.
+Programs may also use this in order to obtain a DirectClass
+canvas image to draw on.</li>
+<li>magick/enhance.c (LevelImage): Fix potential buffer overflow
+which was added since the 1.1 branch.</li>
+</ul>
+</blockquote>
+<p>2007-07-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/delegate.c (UnixShellTextEscape): Don't escape newline
+character since it performs the opposite of what is desired.</li>
+</ul>
+</blockquote>
+<p>2007-07-23 Daniel Kobras &lt;<a class="reference external" href="mailto:kobras&#37;&#52;&#48;debian&#46;org">kobras<span>&#64;</span>debian<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>magick/delegate.c (UnixShellTextEscape): Fix fencepost error</dt>
+<dd>when checking whether escaping is safe.</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2007-07-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Retire VMS and MacOS 9 support from package.</li>
+</ul>
+</blockquote>
+<p>2007-07-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/{cmyk.c, gray.c, mono.c, rgb.c, uyvy.c, wbmp.c, yuv.c}
+(ReadFOOImage): Check for EOF while searching for start of image
+data.</li>
+<li>tests/Makefile.am: Don't test PTIF format with blob I/O since it
+is not possible to pass the rwblob test and it is really an output
+driver rather than a format.</li>
+<li>libtool: Update to latest CVS libtool.</li>
+<li>magick/constitute.c (ExportModulo8Quantum): Move Import and
+Export macros from header file since they are not used anywhere
+else.</li>
+<li>coders/dpx.c: Add underscore suffix to macro local variable
+names in order to avoid conflict with names in code using the
+macros.</li>
+</ul>
+</blockquote>
+<p>2007-07-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c: Reduce the number of warnings when compiling
+the Wand library.</li>
+<li>coders/xwd.c (XWD_OVERFLOW): Eliminate comparison between signed
+and unsigned.</li>
+<li>coders/pnm.c (ValidateScalingIndex): Eliminate check to see if
+unsigned type is less than zero.</li>
+<li>magick/log.c (LogMagickEvent): Even though log file name comes
+from a controlled source (log.mgk), perform safe numeric
+substitution on it.</li>
+<li>coders/xwd.c (ReadXWDImage): Eliminate conflict between locally
+defined OVERFLOW macro and similarly named macro under Windows.</li>
+</ul>
+</blockquote>
+<p>2007-07-18 Daniel Kobras &lt;<a class="reference external" href="mailto:kobras&#37;&#52;&#48;debian&#46;org">kobras<span>&#64;</span>debian<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xwd.c (ReadXWDImage): Integer overflow fix
+(CVE-2007-1797). From Debian patch
+xwd_integer_overflow_fixes_CVE-2007-1797.
+(ReadXWDImage): Fix for integer under/overflow. From Debian patch
+xwd_overflow_fix.</li>
+<li>coders/wpg.c (ReadWPGImage): WPG segfault fix. From Debian
+patch wpg_segfault_fix.</li>
+<li>coders/viff.c (ReadVIFFImage): Verify number of bands prior to
+using image. From Debian patch viff_heap_corruption_fix.</li>
+<li>coders/sun.c (ReadSUNImage): Sun segfault fix. From Debian
+patch sun_segfault_fix.</li>
+<li>magick/blob.c (ReadBlobStream): Never try to read data beyond
+EOF in blob streams. Some (but not all) ReadBlob*() methods
+already implemented similiar checks. Moving it to the central
+ReadBlobStream() increases robustness and prevents out-of-bounds
+reads. From Debian readblob_offset_robustness patch.</li>
+<li>coders/pnm.c (ReadPNMImage): Validate pixel scaling. From
+Debian pnm_scale_fix patch.</li>
+<li>coders/pict.c (ReadPixmap): PICT segfault fix. From Debian
+pict_segfault_fix patch.</li>
+<li>coders/pcx.c (ReadPCXImage): PCX heap overflow fix. From Debian
+pcx_heap_overflow_fix patch.
+(ReadPCXImage): PCX segfault fix. From Debian pcx_segfault_fix.</li>
+<li>magick/montage.c, PerlMagick/t/montage.t: Do not pass bogus
+negative values to modulate shadow in montage. Instead, drop a
+constant grey shadow like current ImageMagick. From Debian
+montage_shadow_fix patch.</li>
+<li>coders/png.c (ReadMNGImage): MNG segfault fix. From Debian
+mng_segfault_fix patch.</li>
+<li>utilities/miff.4: MIFF man page apropos fix. From
+Debian miff_apropos_fix patch.</li>
+<li>coders/icon.c (ReadIconImage): Icon segfault fix. From Debian
+icon_segfault_fix patch.</li>
+<li>tests/drawtest.c: Make sure filename strings do not run out of
+bounds in drawtest. From Debian drawtest_segfault_fix patch.</li>
+<li>config/delegates.mgk.in: Remove obsolete option -2 when calling
+dcraw as a delegate. From Debian dcraw_options_fix patch.</li>
+<li>coders/dcm.c (ReadDCMImage): Fix integer overflow in DCM
+coder. (CVE-2007-1797). From Debian dcm_overflow_fix patch.</li>
+<li>coders/bmp.c (ReadBMPImage): Verify file seek success. From
+Debian bmp_overflow_fix patch.</li>
+</ul>
+</blockquote>
+<p>2007-07-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.h (MagickReallocMemory): It seems that realloc()
+frees the provided memory pointer if the requested size is zero.
+This was causing MagickReallocMemory() to perform a double-free
+under error conditions. Inspired by Debian
+realloc_double_free_fix patch by Daniel Kobras.</li>
+</ul>
+</blockquote>
+<p>2007-07-18 Daniel Kobras &lt;<a class="reference external" href="mailto:kobras&#37;&#52;&#48;debian&#46;org">kobras<span>&#64;</span>debian<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/quantize.c (GrayscalePseudoClassImage): Fix computation
+of memory required for colormap index
+(colormap_heap_overflow_fix).</li>
+</ul>
+</blockquote>
+<p>2007-07-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (WriteRunlengthPacket): Converted excessively long
+macro to a function and hopefully eliminate warnings when using
+Visual Studio 2005.</li>
+<li>magick/pixel_cache.c (ClonePixelCache): Eliminate bug when
+size_t is an unsigned type.</li>
+</ul>
+</blockquote>
+<p>2007-07-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Address security issue noted by
+CVE-2006-0082
+<a class="reference external" href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-0082">http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-0082</a> in
+which output filenames matching arbitrary printf specifications
+may cause GraphicsMagick to crash.</li>
+<li>magick/utility.c (TranslateTextEx): New version of TranslateText
+which allows copying each attribute via a user-provided callback
+function.</li>
+<li>magick/delegate.c (InvokeDelegate): Implement secure delegate
+execution in POSIX environments in order to avoid injection of
+arbitrary shell commands via carefully crafted filenames. Fixes
+Debian Bug 345238 &quot;[CVE-2005-4601] Shell command injection in
+delegate code (via file names)&quot;
+<a class="reference external" href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=345238">http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=345238</a></li>
+</ul>
+</blockquote>
+<p>2007-07-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/forward.h: New header file to support forward type
+declarations.</li>
+<li><dl class="first docutils">
+<dt>coders/pnm.c (ReadPNMImage): Fix pixel scaling problem caused by</dt>
+<dd>floating point rounding error.</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2007-07-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h: Provide pread() and pwrite() prototypes if they
+are missing.</li>
+<li>configure.ac: Check for missing pread() and pwrite() prototypes.</li>
+<li>m4/ac_func_fseeko.m4: Use fixed version of AC_FUNC_FSEEKO.</li>
+<li>magick/utility.c (SystemCommand): Avoid use of snprintf.</li>
+</ul>
+</blockquote>
+<p>2007-07-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c: Only replace getc_unlocked() and putc__unlocked()
+for a thread-safe build.</li>
+<li>magick/studio.h: Always use fseeko() and ftello() if they are
+available.</li>
+</ul>
+</blockquote>
+<p>2007-07-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): Avoid using seek() if possible, and
+don't use at all if the input is not seekable.</li>
+<li>coders/psd.c (ReadPSDImage): Eliminate memory leak when reading
+PSD files. Fixes Sourceforge issue 1625477 &quot;Memory leak reading
+layered PSD Image&quot;.</li>
+</ul>
+</blockquote>
+<p>2007-06-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Fixed -affine command argument
+validation. Fixes SourceForge issue 1743141 &quot;Affine matrix option
+parsing&quot;.</li>
+<li>config/magic.mgk: Added detection for BigTIFF.</li>
+<li>coders/tiff.c: Preliminary work to support BigTIFF.</li>
+</ul>
+</blockquote>
+<p>2007-06-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Fix problems encountered when reading and writing
+from/to pipes or compressed files.</li>
+</ul>
+</blockquote>
+<p>2007-06-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): Improved the pixel data marshalling
+in order to obtain better read performance for 10-bit DPX.</li>
+<li>magick/blob.c (OpenBlob): Added support for MAGICK_MMAP_READ and
+MAGICK_MMAP_WRITE environment variable options to enable input and
+output file access using mmap().</li>
+</ul>
+</blockquote>
+<p>2007-06-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (OpenBlob): Use MAGICK_IOBUF_SIZE to tune the size
+of the I/O buffer. Sometimes performance is improved by using
+something other than the current default of 16KB.</li>
+</ul>
+</blockquote>
+<p>2007-06-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): Handle case where compression
+keyword is present but has value of <cite>None</cite>.</li>
+</ul>
+</blockquote>
+<p>2007-06-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (OpenBlob): Disable reading input files using
+memory mapping since it has been learned that some operating
+systems fail to do read-ahead on network files. Without
+read-ahead, performance is poor.</li>
+<li>magick/resource.c (AcquireMagickResource): Map resource limit
+was not being properly checked due to a typo. The memory limit
+was being tested instead.</li>
+<li>coders/tiff.c (ReadTIFFImage): Use libtiff to decode OJPEG
+compressed files into RGB. Probably requires new OJPEG
+implementation from Joris Van Damme which is new in libtiff and
+not yet released. I am not completely sure that this approach is
+correct yet.</li>
+</ul>
+</blockquote>
+<p>2007-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/xwindow.c (MagickXGetWindowImage): Set image-&gt;depth
+appropriately.</li>
+<li>many files: Compiler warnings reduction.</li>
+</ul>
+</blockquote>
+<p>2007-05-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/cineon.c (ReadCINEONImage): Alter sample scaling
+algorithm a bit.</li>
+<li>tests/rwblob.c, tests/rwfile.c: Allow some slop when testing
+Cineon format with QuantumDepth=8 since we are currently only
+supporting 10 bit samples.</li>
+</ul>
+</blockquote>
+<p>2007-05-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (ReadJPEGImage): Fix reading 12-bit grayscale
+JPEG.</li>
+</ul>
+</blockquote>
+<p>2007-05-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/cineon.c (WriteCINEONImage): Re-wrote Cineon writer from
+scratch. There is no code originating from ImageMagick in this
+source module any more.</li>
+</ul>
+</blockquote>
+<p>2007-04-30 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/art.c, coders.cut.c, coders/mat.c, coders/wpg.c: Add
+support for PingImage() so that image identification is fast by
+default. Also eliminates error message produced by mat.c due to
+rotating an image which has no pixel cache.</li>
+</ul>
+</blockquote>
+<p>2007-04-09 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c (ReadWPGImage): Fix for SourceForge bug id 1431805
+&quot;clip art wpg files cause access violation in graphics magick&quot;.</li>
+</ul>
+</blockquote>
+<p>2007-04-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (ModifyCache): Ensure that the cache nexus
+is open. Fix for SourceForge bug id 1173713 &quot;segfault in
+ModifyCache&quot;</li>
+<li>m4/acx_pthread.m4 (ACX_PTHREAD): Apply fixes necessary to
+support C++ compiler properly.</li>
+</ul>
+</blockquote>
+<p>2007-04-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/GraphicsMagick.pc.in: Fix for SourceForge bug id 1576616
+&quot;Fix includedir variable in pkg-config files&quot;.</li>
+<li>magick/pixel_cache.c (GetOnePixel): Fix for SourceForge bug id
+1572357 &quot;GetOnePixel definition appears incorrect&quot;. It is true
+that this function is intended for read-only purposes and that the
+PixelPacket value is returned directly.</li>
+<li>coders/pdf.c (WritePDFImage): Fix for SourceForge bug id 1510075
+&quot;Failed to write PDF with JPEG compression&quot;.</li>
+<li>magick/command.c (MogrifyImageCommand): Properly bubble up
+errors and terminate further mogrify processing immediately. This
+in response to SourceForge bug id 1391421 &quot;problem doing resize on
+273x1 JPEG&quot;.</li>
+<li>magick/magick.c (InitializeMagickClientPathAndName): Fix for
+SourceForge bug id 1315109 &quot;segfault in InitializeMagick(NULL)&quot;.</li>
+<li>wand/magick_wand.c (MagickGetQuantumDepth): Fix for SourceForge
+bug id 1353744 &quot;MagickGetQuantumDepth doesn't work&quot;.</li>
+<li>PerlMagick/t/read.t: Added a test for WPG v1.</li>
+</ul>
+</blockquote>
+<p>2007-04-07 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c: Read Matlab files in both big and little endian
+format.</li>
+</ul>
+</blockquote>
+<p>2007-03-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): Set DPX reference high quantity to
+2.047 rather than 2.048 since zero is assumed to occupy one count
+and 2.047 seems to be the convention even though the DPX
+specification says the default is 2.048. Technicolor uses 2.047.</li>
+<li>m4/acx_pthread.m4: Update version of ACX_PTHREAD macro used.</li>
+</ul>
+</blockquote>
+<p>2007-03-28 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:fojtik&#37;&#52;&#48;humusoft&#46;cz">fojtik<span>&#64;</span>humusoft<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c: Support CTM translation in WPG reader.</li>
+</ul>
+</blockquote>
+<p>2007-03-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Store 10-bit Luma samples in the filled 32-bit
+storage word starting with the datum in the least significant
+position.</li>
+</ul>
+</blockquote>
+<p>2007-02-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Updated autoconf to version 2.61.</li>
+</ul>
+</blockquote>
+<p>2007-02-10 Daniel Kobras &lt;<a class="reference external" href="mailto:kobras&#37;&#52;&#48;debian&#46;org">kobras<span>&#64;</span>debian<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/palm.c: (ReadPALMImage) Do not implicitly call
+ReadBlobByte() twice in Min() macro. Patch thanks to Vladimir
+Nadvornik. This was a regression introduced in patch for
+CVE-2006-5456. (CVE-2007-0770)</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2007.rst b/www/ChangeLog-2007.rst
new file mode 100644
index 0000000..e56e0f9
--- /dev/null
+++ b/www/ChangeLog-2007.rst
@@ -0,0 +1,973 @@
+2007-12-23 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - VisualMagick/configure/configure.rc: Better positioning of frog,
+ changed original ImageMagick messages.
+
+ - VisualMagick/configure/configure.exe: New build.
+
+2007-12-22 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - magick/command.c: Fix compilability issue for Microsoft Visual
+ Studio 6.
+
+2007-12-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Use some improved tests for POSIX standard types
+ available in Autoconf 2.61.
+ Add support for configuring a magick\_uintmax\_t type.
+ Added support for configuring a magick\_uintptr\_t type.
+
+2007-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.h (MagickSafeMultiplySize\_t): New function to
+ perform a safe multiply. A multiplication overflow results in
+ zero.
+ (MagickAllocateMemory): Check for size\_t value truncation/overflow
+ and zero size before deciding to allocate memory. Any detected
+ failure results in a NULL pointer being returned.
+ (MagickReallocMemory): Add a type parameter to use in cast in
+ order to avoid C++ portability problem.
+
+ - PerlMagick/Magick.xs: Eliminate use of deprecated methods.
+
+ - magick/memory.c (MagickAcquireMemory): New function to allocate
+ memory.
+ (MagickAcquireMemoryArray): New function to allocate memory for an
+ array of objects.
+ (MagickCloneMemory): New function to intelligently copy memory.
+ (MagickReallocateMemory): New function to re-allocate memory.
+ (MagickReleaseMemory): New function to deallocate memory.
+
+ - magick/deprecate.c (AcquireMemory): Deprecated in favor of new
+ function MagickAcquireMemory().
+ (CloneMemory): Deprecated in favor of new function
+ MagickCloneMemory().
+ (LiberateMemory): Deprecated in favor of new function
+ MagickReleaseMemory().
+ (ReacquireMemory): Deprecated in favor of new function
+ MagickReallocateMemory().
+
+2007-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ReadImage): Log colorspace of returned image.
+ (WriteImage): Log colorspace of image to be written.
+
+ - coders/{miff.c,mpc.c,tga.c,tiff.c}: Use MagickBoolToString().
+
+ - magick/{constitute.c,xwindow.c}: Use MagickBoolToString().
+
+ - magick/image.h (MagickBoolToString): New macro to convert truth
+ value to a constant "True" or "False" string.
+
+2007-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (IsImagesEqual): Allow comparing images if the
+ colorspace enumeration is different but the images are both an RGB
+ type.
+
+2007-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Add support for -monitor option to `animate`,
+ `display`, and `import`.
+
+ - coders/fpx.c (WriteFPXImage): Fix compilation problem.
+
+ - coders/dpx.c (TentUpsampleChroma): Fix access beyond array. Use
+ integer calculations where possible.
+
+2007-11-07 Andy Armstrong <andy@hexten.net>
+
+ - PerlMagick/t/setattribute.t: Fix for typo which breaks
+ Test::Harness 3.00.
+
+2007-10-20 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - mat.c: Attempt to read `logic` type modification
+ as monochrome image.
+
+2007-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (ReadBlob?SBFoo): Return 0 on EOF conditions
+ rather than a magic value concocted using ~0. The magic value was
+ very sensitive to the size/range of the type used to pass and
+ store it, leading to increased possibility of error. There was
+ also concern that sometimes a successfully read value may match
+ the magic value. Added documentation that EOFBlob() may be used
+ to determine that the blob is in EOF state.
+
+ - coders/pix.c (ReadPIXImage): Avoid reliance on a particular
+ magic value being returned from ReadBlobMSBShort on EOF.
+
+ - coders/avs.c (ReadAVSImage): Avoid reliance on a particular
+ magic value being returned from ReadBlobMSBLong() on EOF.
+
+2007-10-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - wpg.c: Monochrome images are not using palette -
+ palette is discarded in this case.
+
+2007-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.h: Blob I/O APIs now use sized types so that passed
+ and returned data values are a specific size rather than
+ architecture dependent.
+
+ - PerlMagick/t/read.t: Added read test for unsigned 32-bit LSB MAT
+ format.
+
+2007-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dib.c (ReadDIBImage): Use appropriate sized cast for DIB
+ width and height values. Validate width and height values.
+
+ - coders/bmp.c (ReadBMPImage): Use appropriate sized cast for BMP
+ width and height values.
+
+ - magick/colorspace.c (RGBTransformImage): Use a better rounding
+ algorithm when converting to HSL/HWB colorspaces.
+
+ - magick/gem.c (TransformHSL): Avoid GCC opimization bug on
+ Opteron which caused wrong results. Ensure that returned values
+ fall within bounds 0.0 to 1.0.
+ (TransformHWB): Avoid GCC opimization bug on
+ Opteron which caused wrong results. Ensure that returned values
+ fall within bounds 0.0 to 1.0.
+
+ - PerlMagick/t/ttf/read.t: Relax strictness quite a bit for TTF
+ read tests in order to allow somewhat different FreeType output.
+
+2007-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colorspace.c (RGBTransformImage): Add missing break
+ statement. HWB colorspace was used rather than HSL.
+ (TransformRGBImage): Add missing break
+ statement. HWB colorspace was used rather than HSL.
+
+2007-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sun.c (ReadSUNImage): Properly report SUN image depth.
+
+2007-09-28 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Ability to write multiple images to one MAT file.
+ Fixed bug - incorrect matrix size for gray image.
+
+2007-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c (IntegralRotateImage): Rotation by 270 degrees
+ was wrong. It was flipped from what it should be.
+
+2007-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (CommandProgressMonitor): Remove any preceding
+ whitespace in the task descriptions so that we don't need to
+ update all of the task descriptions right away.
+
+ - magick/colorspace.c (RGBTransformImage): Improve progress monitor message.
+ (TransformRGBImage): Improve progress monitor message.
+
+ - coders/miff.c (ReadMIFFImage): Add read progress monitor support.
+
+2007-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c (WritePDFImage): Fix writing PDF with CCITT
+ compression. Addresses SourceForge bug 1209177 "TIFF to PDF CCITT
+ compression fails".
+
+2007-09-14 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Ability to read multiple images from one MAT file.
+ changed ExtendedSignedIntegralType to magick\_off\_t that better
+ corresponds to file positioning.
+
+2007-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c (WritePDFImage): Use ThumbnailImage() to create
+ thumbnail.
+
+ - coders/preview.c (WritePreviewImage): Use ThumbnailImage() to
+ create thumbnail.
+
+ - coders/xpm.c (WritePICONImage): Use ThumbnailImage() to create
+ thumbnail.
+
+2007-09-14 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Several warnings has been suppressed.
+
+2007-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Fix writing to pipes and other
+ non-seekable output destinations.
+
+ - magick/blob.c (WriteBlobFile): New function to copy a disk file
+ to a blob stream.
+
+ - magick/profile.c (ProfileImage): Fix removing profiles.
+
+2007-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c (png\_flush\_data): Don't invoke SyncBlob() since it
+ does far more than force data to the output file.
+ (ReadPNGImage): Make sure that PNG read errors are reported to the
+ user.
+
+ - coders/jpeg.c (TerminateDestination): Don't invoke SyncBlob()
+ since it does far more than force data to the output file.
+
+ - magick/blob.c (SyncBlob): Remove from public interface.
+
+2007-09-12 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Allowed to read signed integer matrices.
+ Fixed loop break.
+
+2007-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Ensure that selected photometric
+ most closely matches the user's expectation. Remove compression
+ if requested compression type is not compatible with the selected
+ photometric.
+
+2007-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c (IntegralRotateImage): Use tiles to speed up
+ rotation by 90 or 270 degrees.
+
+2007-09-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c The flop image has been eliminated in a reader.
+ Code has been shrinked a little bit.
+
+2007-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (GetImageCharacteristics): Add progress monitor support.
+
+ - magick/color.c (IsMonochromeImage): Add progress monitor support.
+ (IsGrayImage): Add progress monitor support.
+ (IsOpaqueImage): Add progress monitor support.
+
+ - coders/dpx.c (ReadDPXImage): Added progress indication.
+
+ - coders/cineon.c (WriteCINEONImage): Added progress indication.
+
+ - magick/command.c : Added a -monitor command option for
+ `composite`, `convert`, `identify`, `mogrify`, and `montage` in
+ order to enable a simple progress indicator.
+
+2007-09-06 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Write native gray MAT data when gray image is detected.
+
+2007-09-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetExecutionPath): Add support for Apple OS-X,
+ Linux, and FreeBSD.
+
+2007-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: For Windows MinGW-based build, find Ghostscript
+ fonts installed under C:/Program Files/.
+
+ - VisualMagick/bin/delegates.mgk: Adjust quoting to Ghostscript arguments
+ so that Ghostscript DLL is passed correct commands.
+
+ - config/delegates.mgk.in: Adjust quoting to Ghostscript arguments
+ so that Ghostscript DLL is passed correct commands.
+
+ - configure.ac: Provide defaults for GSColorAlphaDevice and GSGrayDevice.
+
+ - magick/nt\_base.c (NTGhostscriptGetString): Support "GPL Ghostscript".
+
+2007-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/ps.c (WritePSImage): Improved Postscript writer
+ performance.
+
+2007-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/profile.c (AllocateImageProfileIterator): New function to
+ allocate an image profile iterator.
+ (DeallocateImageProfileIterator): New function to deallocate an
+ image profile iterator.
+ (NextImageProfile): New function to advance the image profile
+ iterator to the next profile.
+
+ - magick/image.h (Image): Profiles are now stored in a generic
+ container. As planned years ago, the color\_profile, iptc\_profile,
+ generic\_profile, and generic\_profiles members are now removed.
+
+2007-09-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/bmp.c Ability to read true color bitmap with invalid palette size
+ like other readers do.
+
+2007-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (ClonePixelCacheMethods): Remove DLL export.
+ (DestroyCacheInfo): Remove DLL export.
+ (GetCacheInfo): Remove DLL export.
+ (ReferenceCache): Remove DLL export.
+
+2007-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageType): More tweaks to obtain the desired
+ behavior when converting to a bilevel image.
+
+ - coders/tiff.c (WriteTIFFImage): Logic which decided the output
+ subformat to write was too convoluted to understand, and in fact
+ palette images were not be written sometimes when they should be
+ (bug added on 2007-08-19). Deleted the convoluted code and
+ replaced with a different design which should be more correct and
+ flexible.
+ (ReadTIFFImage): Decided to read bilevel TIFF using a colormap
+ since there are significant internal advantages to doing so.
+ However, the writer is carefully designed to output normal bilevel
+ TIFF so this should not annoy TIFF users.
+
+ - magick/constitute.c (ImportImagePixelArea): Re-wrote grayscale
+ pseudoclass import to be more efficient and more tidy.
+
+2007-08-30 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/art.c Added ART writer
+
+2007-08-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (ReadBlobLSBFloat): Promoted to be a public
+ interface (was in mat.c).
+ (ReadBlobMSBFloat):Promoted to be a public interface (was in
+ mat.c).
+
+2007-08-29 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/art.c InsertRow has been replaced by ImportImagePixelArea
+
+2007-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (ReadPNMImage): PNM "raw" formats are now read
+ using ImportImagePixelArea()
+
+ - magick/constitute.c (ExportImagePixelArea): Added an optional
+ export\_info parameter for returning information back to the user.
+ (ImportImagePixelArea): Added an optional import\_info parameter
+ for returning information back to the user.
+
+ - coders/jbig.c (ReadJBIGImage): Use ImportImagePixelArea().
+ (WriteJBIGImage): Use ExportImagePixelArea();
+
+ - coders/tiff.c (WriteTIFFImage): Make compression logic a bit
+ more tidy.
+
+ - coders/pcx.c (WritePCXImage): Use GetImageCharacteristics().
+
+ - coders/pcl.c (WritePCLImage): Use GetImageCharacteristics().
+
+ - coders/dib.c (WriteDIBImage): Use GetImageCharacteristics().
+
+ - coders/xpm.c (WritePICONImage): Use GetImageCharacteristics().
+
+ - coders/viff.c (WriteVIFFImage): Use GetImageCharacteristics().
+
+ - coders/tga.c (WriteTGAImage): Use GetImageCharacteristics().
+
+ - coders/sgi.c (WriteSGIImage): Use GetImageCharacteristics().
+
+ - coders/ps2.c (WritePS2Image): Use GetImageCharacteristics().
+
+ - coders/pdf.c (WritePDFImage): Use GetImageCharacteristics().
+
+ - coders/palm.c (WritePALMImage): Use GetImageCharacteristics().
+
+ - coders/ps.c (WritePSImage): Use GetImageCharacteristics().
+
+ - coders/jp2.c (WriteJP2Image): Use GetImageCharacteristics().
+
+ - coders/jpeg.c (WriteJPEGImage): Use GetImageCharacteristics().
+
+ - PerlMagick/t/read.t: Added read test for LSB `float` MAT.
+
+2007-08-26 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c: MAT reader now extensively uses ImportImagePixelArea.
+
+2007-08-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am: Add rwblob and rwfile tests for MAT format.
+
+ - magick/constitute.c: Re-wrote Export/Import Float/Double macros
+ because they did not actually work right, and to eliminate the
+ performance penalty for native order.
+
+2007-08-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: Add support for "native" endian parameter
+ in PerlMagick.
+
+ - magick/command.c: Utilities now understand "native" as an
+ argument to -endian.
+
+ - magick/image.h (enum EndianType): Added NativeEndian enum value.
+
+ - configure.ac: Test libtiff for TIFFSwabArrayOfTriples().
+
+ - magick/constitute.c (ExportImagePixelArea): Support export in
+ little, big, and native endian.
+ (ImportImagePixelArea): Support import in little, big, and native
+ endian.
+
+2007-08-23 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c (WriteMATLABImage): MAT writer uses
+ ExportImagePixelArea() now. Fix issues noticed by valgrind.
+
+2007-08-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (WritePNMImage): Use `-quality 0` rather than
+ `-compress none` to select the PNM ASCII subformats. This change
+ is made based on the principle of least surprise.
+
+ - magick/constitute.c (ExportImagePixelArea): Add a GrayQuantum
+ implementation for exporting from two color PsuedoClass.
+
+ - coders/pnm.c (WritePNMImage): Use GetImageCharacteristics() and
+ ExportImagePixelArea() in implementation.
+
+2007-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ExportImagePixelArea): Performance
+ improvements.
+ (ImportImagePixelArea): Performance improvements.
+
+2007-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (IdentifyImageCommand): If "%r" is present in
+ -format specifier, then read whole image.
+
+ - magick/utility.c (TranslateTextEx): Undocumented "%r"
+ substitution now returns a string based on GetImageType() rather
+ than a concatentation of image class and "Matte".
+
+ - coders/tiff.c (WriteTIFFImage): Use GetImageCharacteristics().
+
+ - magick/image.c (GetImageCharacteristics): New function to
+ evaluate the basic characteristics of the image.
+ (GetImageType): Use GetImageCharacteristics().
+
+2007-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (RegisterDPXImage): Remove extra newline in usage
+ note.
+
+ - coders/fax.c (RegisterFAXImage): Fix note to reflect that the
+ output from this coder is \*not\* a TIFF subformat as was previously
+ claimed.
+
+ - coders/tiff.c (WriteTIFFImage): Output G3 TIFF FAX images as per
+ the TIFF Class F specification.
+
+2007-08-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/{api.h, studio.h}: Strip out legacy MacOS 9 and VMS "support".
+
+ - magick/{nt\_base.c, unix\_port.c} (MagickGetMMUPageSize): New function to obtain
+ the VM page size.
+
+ - magick/pixel\_cache.c (PersistCache): Fix a terrible memory leak
+ when reading MPC files. Added Cache reference-count logging.
+
+2007-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (BenchMarkSubCommand): Added a new `benchmark`
+ GraphicsMagick command which can be used to perform benchmarking
+ on any other GraphicsMagick command.
+
+2007-08-11 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c (ReadMATImage): Support image is\_grayscale flag.
+ Add some coder logging.
+
+2007-08-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/{paint.c, render.c, annotate.c}: Use AlphaComposite()
+ from alpha\_composite.h.
+
+ - magick/alpha\_composite.h (BlendComposite): Move inline
+ BlendComposite() to a header file since it is used in multiple
+ places.
+
+ - magick/{shear.c, image.c}: Use BlendComposite() from
+ alpha\_composite.h.
+
+ - magick/image.c (SetImageDepth): Don't bother to test current
+ depth in advance. Preserve is\_monochrome flag. Encapsulate
+ bit-reduction algorithm in a macro. Be a bit smarter with
+ PseudoClass images.
+ (SyncImage): Preserve is\_monochrome flag. Improve performance
+ when image does not have an opacity channel.
+
+ - PerlMagick/t/read.t: Allow some error when reading double MAT.
+
+2007-08-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/read.t: Update MAT read tests according to
+ instructions from Fojtik Jaroslav.
+
+2007-08-06 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/wpg.c (ReadWPGImage): Support WPG files which use XOR
+ operator.
+
+2007-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (ReadBlobLSBdouble): Migrate from mat.c.
+ (ReadBlobMSBdouble): Migrate from mat.c.
+
+2007-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ExportImagePixelArea): Add optimized
+ support for 2 and 16 color PseudoClass.
+ (ImportImagePixelArea): Add optimized support for 2 and 16 color
+ PseudoClass.
+
+ - magick/constitute.c (ImportImagePixelArea): Add option to output
+ pad bytes at end of pixel data. Added optimized implementation of
+ IndexQuantum for bilevel images.
+
+ - coders/tiff.c (WriteTIFFImage): Be smarter when writing gray
+ Palette and grayscale TIFF images in order to not waste time.
+
+ - coders/bmp.c (ReadBMPImage): Use ImportImagePixelArea() when
+ reading and writing bilevel and colormapped images.
+ (WriteBMPImage): Use ExportImagePixelArea() when writing bilevel
+ images.
+
+ - magick/version.h.in: Added wrapping for copyright line to a
+ reasonable width.
+
+ - AUTHORS: Added Daniel Kobras.
+
+ - magick/command.c (VersionCommand): Added feature support list to
+ -version output.
+
+2007-08-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (AnimateImageCommand): Add support for -type to
+ `animate`.
+ (DisplayImageCommand): Add support for -type to `convert`
+
+ - config/delegates.mgk.in, VisualMagick/bin/delegates.mgk: Added
+ gs-gray and gs-color+alpha delegate definitions.
+
+ - coders/{ept.c, pdf.c, ps.c}: Respect a -type Bilevel, Grayscale,
+ TrueColor, or TrueColorMatte request by passing appropriate
+ options to Ghostscript for rendering..
+
+2007-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ImportImagePixelArea): Improved read speed
+ for bilevel gray image. Many thanks to Mark Mitchell for
+ inspiration and ideas.
+
+ - coders/caption.c (ReadCAPTIONImage): Eliminate use of strcpy().
+
+ - coders/pnm.c (ReadPNMImage): Add logging as well as support for
+ is\_monochrome and is\_grayscale flags.
+
+ - magick/color.h (IsMonochrome): Add parenthesis so macro is more
+ robust.
+
+2007-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/html.c (WriteHTMLImage): Eliminate use of strncat().
+
+ - coders/locale.c (ReadConfigureFile): Eliminate use of strncat().
+
+ - coders/png.c (ReadOnePNGImage): Eliminate use of strncat().
+
+ - magick/fx.c (ConvolveImage): Eliminate use of strncat().
+
+ - coders/tiff.c (WriteTIFFImage): Eliminate use of strncat().
+
+ - magick/delegate.c (InvokePostscriptDelegate): Eliminate
+ doubled-output when running in verbose mode.
+
+2007-07-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/delegate.c (InvokePostscriptDelegate): MagickSpawnVP()
+ requires three parameters.
+
+2007-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - bzlib: Updated bzip2 to 1.0.4.
+
+ - jbig: Updated jbigkit to 1.6
+
+ - jp2: Updated JasPer to 1.900.1.
+
+ - lcms: Updated lcms to 1.16
+
+ - png: Updated libpng to 1.2.18.
+
+2007-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xc.c (ReadXCImage): If ImageInfo type field is set to
+ TrueColorType or TrueColorMatteType type, then return a
+ DirectClass image, otherwise a PseudoClass image is returned as
+ before. From the command line this can be used like:
+ `gm convert -size 640x480 -type TrueColor xc:red red.miff`.
+ Programs may also use this in order to obtain a DirectClass
+ canvas image to draw on.
+
+ - magick/enhance.c (LevelImage): Fix potential buffer overflow
+ which was added since the 1.1 branch.
+
+2007-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/delegate.c (UnixShellTextEscape): Don't escape newline
+ character since it performs the opposite of what is desired.
+
+2007-07-23 Daniel Kobras <kobras@debian.org>
+
+ - magick/delegate.c (UnixShellTextEscape): Fix fencepost error
+ when checking whether escaping is safe.
+
+2007-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Retire VMS and MacOS 9 support from package.
+
+2007-07-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/{cmyk.c, gray.c, mono.c, rgb.c, uyvy.c, wbmp.c, yuv.c}
+ (ReadFOOImage): Check for EOF while searching for start of image
+ data.
+
+ - tests/Makefile.am: Don't test PTIF format with blob I/O since it
+ is not possible to pass the rwblob test and it is really an output
+ driver rather than a format.
+
+ - libtool: Update to latest CVS libtool.
+
+ - magick/constitute.c (ExportModulo8Quantum): Move Import and
+ Export macros from header file since they are not used anywhere
+ else.
+
+ - coders/dpx.c: Add underscore suffix to macro local variable
+ names in order to avoid conflict with names in code using the
+ macros.
+
+2007-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c: Reduce the number of warnings when compiling
+ the Wand library.
+
+ - coders/xwd.c (XWD\_OVERFLOW): Eliminate comparison between signed
+ and unsigned.
+
+ - coders/pnm.c (ValidateScalingIndex): Eliminate check to see if
+ unsigned type is less than zero.
+
+ - magick/log.c (LogMagickEvent): Even though log file name comes
+ from a controlled source (log.mgk), perform safe numeric
+ substitution on it.
+
+ - coders/xwd.c (ReadXWDImage): Eliminate conflict between locally
+ defined OVERFLOW macro and similarly named macro under Windows.
+
+2007-07-18 Daniel Kobras <kobras@debian.org>
+
+ - coders/xwd.c (ReadXWDImage): Integer overflow fix
+ (CVE-2007-1797). From Debian patch
+ xwd\_integer\_overflow\_fixes\_CVE-2007-1797.
+ (ReadXWDImage): Fix for integer under/overflow. From Debian patch
+ xwd\_overflow\_fix.
+
+ - coders/wpg.c (ReadWPGImage): WPG segfault fix. From Debian
+ patch wpg\_segfault\_fix.
+
+ - coders/viff.c (ReadVIFFImage): Verify number of bands prior to
+ using image. From Debian patch viff\_heap\_corruption\_fix.
+
+ - coders/sun.c (ReadSUNImage): Sun segfault fix. From Debian
+ patch sun\_segfault\_fix.
+
+ - magick/blob.c (ReadBlobStream): Never try to read data beyond
+ EOF in blob streams. Some (but not all) ReadBlob\*() methods
+ already implemented similiar checks. Moving it to the central
+ ReadBlobStream() increases robustness and prevents out-of-bounds
+ reads. From Debian readblob\_offset\_robustness patch.
+
+ - coders/pnm.c (ReadPNMImage): Validate pixel scaling. From
+ Debian pnm\_scale\_fix patch.
+
+ - coders/pict.c (ReadPixmap): PICT segfault fix. From Debian
+ pict\_segfault\_fix patch.
+
+ - coders/pcx.c (ReadPCXImage): PCX heap overflow fix. From Debian
+ pcx\_heap\_overflow\_fix patch.
+ (ReadPCXImage): PCX segfault fix. From Debian pcx\_segfault\_fix.
+
+ - magick/montage.c, PerlMagick/t/montage.t: Do not pass bogus
+ negative values to modulate shadow in montage. Instead, drop a
+ constant grey shadow like current ImageMagick. From Debian
+ montage\_shadow\_fix patch.
+
+ - coders/png.c (ReadMNGImage): MNG segfault fix. From Debian
+ mng\_segfault\_fix patch.
+
+ - utilities/miff.4: MIFF man page apropos fix. From
+ Debian miff\_apropos\_fix patch.
+
+ - coders/icon.c (ReadIconImage): Icon segfault fix. From Debian
+ icon\_segfault\_fix patch.
+
+ - tests/drawtest.c: Make sure filename strings do not run out of
+ bounds in drawtest. From Debian drawtest\_segfault\_fix patch.
+
+ - config/delegates.mgk.in: Remove obsolete option -2 when calling
+ dcraw as a delegate. From Debian dcraw\_options\_fix patch.
+
+ - coders/dcm.c (ReadDCMImage): Fix integer overflow in DCM
+ coder. (CVE-2007-1797). From Debian dcm\_overflow\_fix patch.
+
+ - coders/bmp.c (ReadBMPImage): Verify file seek success. From
+ Debian bmp\_overflow\_fix patch.
+
+2007-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.h (MagickReallocMemory): It seems that realloc()
+ frees the provided memory pointer if the requested size is zero.
+ This was causing MagickReallocMemory() to perform a double-free
+ under error conditions. Inspired by Debian
+ realloc\_double\_free\_fix patch by Daniel Kobras.
+
+2007-07-18 Daniel Kobras <kobras@debian.org>
+
+ - magick/quantize.c (GrayscalePseudoClassImage): Fix computation
+ of memory required for colormap index
+ (colormap\_heap\_overflow\_fix).
+
+2007-07-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (WriteRunlengthPacket): Converted excessively long
+ macro to a function and hopefully eliminate warnings when using
+ Visual Studio 2005.
+ - magick/pixel\_cache.c (ClonePixelCache): Eliminate bug when
+ size\_t is an unsigned type.
+
+2007-07-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Address security issue noted by
+ CVE-2006-0082
+ http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-0082 in
+ which output filenames matching arbitrary printf specifications
+ may cause GraphicsMagick to crash.
+
+ - magick/utility.c (TranslateTextEx): New version of TranslateText
+ which allows copying each attribute via a user-provided callback
+ function.
+
+ - magick/delegate.c (InvokeDelegate): Implement secure delegate
+ execution in POSIX environments in order to avoid injection of
+ arbitrary shell commands via carefully crafted filenames. Fixes
+ Debian Bug 345238 "[CVE-2005-4601] Shell command injection in
+ delegate code (via file names)"
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=345238
+
+2007-07-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/forward.h: New header file to support forward type
+ declarations.
+
+ - coders/pnm.c (ReadPNMImage): Fix pixel scaling problem caused by
+ floating point rounding error.
+
+2007-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h: Provide pread() and pwrite() prototypes if they
+ are missing.
+
+ - configure.ac: Check for missing pread() and pwrite() prototypes.
+
+ - m4/ac\_func\_fseeko.m4: Use fixed version of AC\_FUNC\_FSEEKO.
+
+ - magick/utility.c (SystemCommand): Avoid use of snprintf.
+
+2007-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c: Only replace getc\_unlocked() and putc\_\_unlocked()
+ for a thread-safe build.
+
+ - magick/studio.h: Always use fseeko() and ftello() if they are
+ available.
+
+2007-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): Avoid using seek() if possible, and
+ don't use at all if the input is not seekable.
+
+ - coders/psd.c (ReadPSDImage): Eliminate memory leak when reading
+ PSD files. Fixes Sourceforge issue 1625477 "Memory leak reading
+ layered PSD Image".
+
+2007-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Fixed -affine command argument
+ validation. Fixes SourceForge issue 1743141 "Affine matrix option
+ parsing".
+
+ - config/magic.mgk: Added detection for BigTIFF.
+
+ - coders/tiff.c: Preliminary work to support BigTIFF.
+
+2007-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Fix problems encountered when reading and writing
+ from/to pipes or compressed files.
+
+2007-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): Improved the pixel data marshalling
+ in order to obtain better read performance for 10-bit DPX.
+
+ - magick/blob.c (OpenBlob): Added support for MAGICK\_MMAP\_READ and
+ MAGICK\_MMAP\_WRITE environment variable options to enable input and
+ output file access using mmap().
+
+2007-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (OpenBlob): Use MAGICK\_IOBUF\_SIZE to tune the size
+ of the I/O buffer. Sometimes performance is improved by using
+ something other than the current default of 16KB.
+
+2007-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): Handle case where compression
+ keyword is present but has value of `None`.
+
+2007-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (OpenBlob): Disable reading input files using
+ memory mapping since it has been learned that some operating
+ systems fail to do read-ahead on network files. Without
+ read-ahead, performance is poor.
+
+ - magick/resource.c (AcquireMagickResource): Map resource limit
+ was not being properly checked due to a typo. The memory limit
+ was being tested instead.
+
+ - coders/tiff.c (ReadTIFFImage): Use libtiff to decode OJPEG
+ compressed files into RGB. Probably requires new OJPEG
+ implementation from Joris Van Damme which is new in libtiff and
+ not yet released. I am not completely sure that this approach is
+ correct yet.
+
+2007-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/xwindow.c (MagickXGetWindowImage): Set image->depth
+ appropriately.
+
+ - many files: Compiler warnings reduction.
+
+2007-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/cineon.c (ReadCINEONImage): Alter sample scaling
+ algorithm a bit.
+
+ - tests/rwblob.c, tests/rwfile.c: Allow some slop when testing
+ Cineon format with QuantumDepth=8 since we are currently only
+ supporting 10 bit samples.
+
+2007-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (ReadJPEGImage): Fix reading 12-bit grayscale
+ JPEG.
+
+2007-05-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/cineon.c (WriteCINEONImage): Re-wrote Cineon writer from
+ scratch. There is no code originating from ImageMagick in this
+ source module any more.
+
+2007-04-30 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/art.c, coders.cut.c, coders/mat.c, coders/wpg.c: Add
+ support for PingImage() so that image identification is fast by
+ default. Also eliminates error message produced by mat.c due to
+ rotating an image which has no pixel cache.
+
+2007-04-09 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/wpg.c (ReadWPGImage): Fix for SourceForge bug id 1431805
+ "clip art wpg files cause access violation in graphics magick".
+
+2007-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (ModifyCache): Ensure that the cache nexus
+ is open. Fix for SourceForge bug id 1173713 "segfault in
+ ModifyCache"
+
+ - m4/acx\_pthread.m4 (ACX\_PTHREAD): Apply fixes necessary to
+ support C++ compiler properly.
+
+2007-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/GraphicsMagick.pc.in: Fix for SourceForge bug id 1576616
+ "Fix includedir variable in pkg-config files".
+
+ - magick/pixel\_cache.c (GetOnePixel): Fix for SourceForge bug id
+ 1572357 "GetOnePixel definition appears incorrect". It is true
+ that this function is intended for read-only purposes and that the
+ PixelPacket value is returned directly.
+
+ - coders/pdf.c (WritePDFImage): Fix for SourceForge bug id 1510075
+ "Failed to write PDF with JPEG compression".
+
+ - magick/command.c (MogrifyImageCommand): Properly bubble up
+ errors and terminate further mogrify processing immediately. This
+ in response to SourceForge bug id 1391421 "problem doing resize on
+ 273x1 JPEG".
+
+ - magick/magick.c (InitializeMagickClientPathAndName): Fix for
+ SourceForge bug id 1315109 "segfault in InitializeMagick(NULL)".
+
+ - wand/magick\_wand.c (MagickGetQuantumDepth): Fix for SourceForge
+ bug id 1353744 "MagickGetQuantumDepth doesn't work".
+
+ - PerlMagick/t/read.t: Added a test for WPG v1.
+
+2007-04-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c: Read Matlab files in both big and little endian
+ format.
+
+2007-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): Set DPX reference high quantity to
+ 2.047 rather than 2.048 since zero is assumed to occupy one count
+ and 2.047 seems to be the convention even though the DPX
+ specification says the default is 2.048. Technicolor uses 2.047.
+
+ - m4/acx\_pthread.m4: Update version of ACX\_PTHREAD macro used.
+
+2007-03-28 Fojtik Jaroslav <fojtik@humusoft.cz>
+
+ - coders/wpg.c: Support CTM translation in WPG reader.
+
+2007-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: Store 10-bit Luma samples in the filled 32-bit
+ storage word starting with the datum in the least significant
+ position.
+
+2007-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Updated autoconf to version 2.61.
+
+2007-02-10 Daniel Kobras <kobras@debian.org>
+
+ - coders/palm.c: (ReadPALMImage) Do not implicitly call
+ ReadBlobByte() twice in Min() macro. Patch thanks to Vladimir
+ Nadvornik. This was a regression introduced in patch for
+ CVE-2006-5456. (CVE-2007-0770)
+
diff --git a/www/ChangeLog-2008.html b/www/ChangeLog-2008.html
new file mode 100644
index 0000000..653fa7b
--- /dev/null
+++ b/www/ChangeLog-2008.html
@@ -0,0 +1,2329 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2008-12-28 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c: Ability to read extension blocks.</li>
+<li>coders/fits.c: Fixed MaxTextExtent limitation of blocks.</li>
+</ul>
+</blockquote>
+<p>2008-12-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/OpenMP.rst: Add results for Window Vista 64-bit / AMD Phenom
+X4 9550.</li>
+<li>VisualMagick/installer/inc/body.isx: Revert yesterday's change
+regarding the placement of config files. Place the config files
+in a <cite>config</cite> subdirectory just as before.</li>
+</ul>
+</blockquote>
+<p>2008-12-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/body.isx: They say that when in Rome
+you should do as the Roman's do. Based on this philosophy, all of
+the coder and filter DLLs are now installed to the same directory
+as the executables and DLLs which depend on them. This eases
+operation under Windows Vista.</li>
+</ul>
+</blockquote>
+<p>2008-12-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c: First pass at supporting large file access under
+Windows.</li>
+</ul>
+</blockquote>
+<p>2008-12-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (InitializeMagickResources): Improve resource
+estimation for Microsoft Windows systems with large memory.</li>
+<li>magick/segment.c: Added some code to dump histograms with
+<cite>-verbose -verbose</cite>.</li>
+<li>coders/tiff.c: Support reading/writing 16 and 24 bit float TIFF
+files.</li>
+<li>magick/constitute.c (ExportViewPixelArea): Support exporting 16
+and 24 bit short floats. Relies on code developed for
+GraphicsMagick by Richard Nolde.
+(ImportViewPixelArea): Support importing 16 and 24 bit short
+floats. Relies on code developed for GraphicsMagick by Richard
+Nolde.</li>
+</ul>
+</blockquote>
+<p>2008-12-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/operator.h (enum QuantumOperator): Added LogQuantumOp,
+MaxQuantumOp, MinQuantumOp, and PowQuantumOp enumerations as well
+as &quot;Log&quot;, &quot;Max&quot;, &quot;Min&quot;, and &quot;Pow&quot; options to -operator.</li>
+</ul>
+</blockquote>
+<p>2008-12-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): The -write option was not
+implemented in a useful fashion and the +write option never worked
+at all. Re-implement -write and eliminate +write from the
+documentation since +write is not needed.</li>
+</ul>
+</blockquote>
+<p>2008-12-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage, WriteTIFFImage) Support reading
+and writing 64-bit integer TIFF.</li>
+<li>magick/constitute.c (ImportViewPixelArea): Add support for
+importing 64-bit integer values.
+(ImportViewPixelArea): Add support for exporting 64-bit integer
+values.</li>
+</ul>
+</blockquote>
+<p>2008-12-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Fix bug with reading one bit per
+sample RGB images.</li>
+</ul>
+</blockquote>
+<p>2008-12-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (OpenCache): Fix a code ordering problem
+which results in <cite>identify</cite> throwing an assertion for PseudoClass
+image files. This bug was added in the 1.3.2 release.</li>
+<li>coders/tiff.c (ReadTIFFImage): Fix bug with <cite>ping</cite> mode.</li>
+</ul>
+</blockquote>
+<p>2008-12-07 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c: Proper signed to unsigned conversion for 64 bit LSB images.</li>
+</ul>
+</blockquote>
+<p>2008-12-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/Makefile.am: When X11 is disabled, don't compile the
+X11-specific source modules. Don't ever install any X11-related
+header files.</li>
+</ul>
+</blockquote>
+<p>2008-12-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/segment.c (SegmentImage): Use <cite>double</cite> rather than 64-bit
+integer to accumulate totalized values. Make the cluster summary
+report more concise.</li>
+</ul>
+</blockquote>
+<p>2008-12-06 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c: Fix for 64 bit images.</li>
+</ul>
+</blockquote>
+<p>2008-12-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/segment.c (SegmentImage): Cluster threshold is expressed
+as a percentage of total cluster pixels. Optimize for larger
+images.</li>
+</ul>
+</blockquote>
+<p>2008-12-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/segment.c (SegmentImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-11-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (ExpandFilenames): Remove some arbitrary
+argument length limits. Pass -convolve argument without any
+additional checking. Verify that strings are not truncated during
+copy.
+(ListFiles): Be more memory efficient.</li>
+<li>magick/fx.c (ConvolveImage): Fix formatting problem when logging
+the convolution kernel used.</li>
+<li>magick/utility.c (TranslateTextEx): Support formatting huge
+comment text.</li>
+</ul>
+</blockquote>
+<p>2008-11-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/fx.c (ConvolveImage): Don`t process opacity channel
+unless image has one.</li>
+<li>magick/effect.c (MotionBlurImage): Use
+AcquireOnePixelByReference() rather than AcquireImagePixels() to
+retrieve one pixel. This is much more efficient.
+(AdaptiveThresholdImage): Don`t process opacity channel unless
+image has one.
+(BlurImage): Don`t process opacity channel unless image has one.</li>
+</ul>
+</blockquote>
+<p>2008-11-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c (ProfileImage): +profile now supports a simple
+exclusion syntax. For example, to strip all of the profiles
+except for the ICM profile use +profile '!icm,*'. The new syntax
+also allows multiple profile names to be listed at once. The
+primary requirement is that all excluded profiles must be listed
+prior to those to be stripped.</li>
+</ul>
+</blockquote>
+<p>2008-11-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/transform.c (RollImage): Remove image storage class
+alteration.
+(CompositeImageRegion): Ensure that the canvas image storage class
+is correct.</li>
+</ul>
+</blockquote>
+<p>2008-11-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>config/delegates.mgk.in: Since we removed support for <cite>spawn</cite> a
+long time ago, and no longer execute using the Unix shell by
+default, we need to add an ampersand to the end of the two entries
+previously using <cite>spawn</cite> so that the display program does not hang
+when it invokes the external program.</li>
+<li>utilities/Makefile.am (UTILITIES_TESTS): Add preview-based
+tests.</li>
+<li>coders/preview.c (WritePreviewImage): Solarize requires a
+threshold argument.</li>
+<li>coders/vid.c (WriteVIDImage): Eliminate memory leak.</li>
+<li>magick/montage.c (MontageImages): Fix continued use of freed
+memory.</li>
+</ul>
+</blockquote>
+<p>2008-11-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/omp_data_view.c (AccessThreadViewDataById): New function
+to allow retrieving data via the index it was registered with.</li>
+<li>magick/enhance.c (BuildChannelHistograms): EnhanceImage() and
+NormalizeImage() now share one common function for generating the
+histogram.</li>
+<li>magick/enhance.c (ModulateImage): Improve performance a bit.
+(ContrastImage): Improve performance a bit.
+(GammaImage): Improve performance a bit.</li>
+</ul>
+</blockquote>
+<p>2008-11-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/authors.rst: List Mark Mitchell as an author.</li>
+<li>utilities/tests/msl_composite.sh: Fix <cite>rm -f</cite> without a valid
+argument which annoyed NetBSD.</li>
+<li>coders/fits.c: Impose a limit on the length of the row PDU.
+Make sure that GraphicsMagick version information does not
+overflow the length allowed by a row PDU.</li>
+</ul>
+</blockquote>
+<p>2008-11-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (WriteJPEGImage): Use DCT algorithm default from
+the library rather than the header file.</li>
+<li>magick: Adjust OpenMP scheduling options based on observed
+behavior.</li>
+</ul>
+</blockquote>
+<p>2008-11-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c (IntegralRotateImage): Added OpenMP acceleration
+for rotate by 90 and 270 degrees.</li>
+<li>configure.ac: New --disable-openmp-slow configure for disabling
+use of OpenMP for algorithms which may run slower on operating
+systems with crummy thread libraries. This still allows gaining
+the benefits from OpenMP for CPU hogs. Verified to help with
+FreeBSD 7.0 and Apple OS-X Leopard.</li>
+<li>magick/semaphore.c: Trimmed out the debug code in order to
+obtain a bit more performance.</li>
+</ul>
+</blockquote>
+<p>2008-11-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: Allow the user to specify the DCT method
+(jpeg:dct-method), or if huffman encoding should be enabled
+(jpeg:optimize-coding=true). Default the DCT method to the
+libjpeg default rather than forcing it to JDCT_FLOAT since float
+is slower on some systems.</li>
+</ul>
+</blockquote>
+<p>2008-11-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (BlobClose): Leak a little bit less memory when
+reading a JP2 file.</li>
+</ul>
+</blockquote>
+<p>2008-11-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/wandtest.c: Eliminate memory leak.</li>
+<li>wand/drawing_wand.c (DestroyDrawingWand): Eliminate memory
+leaks.</li>
+<li>coders/xwd.c (WriteXWDImage): Force colormapped images with more
+than 256 colors to DirectClass.</li>
+<li>magick/enhance.c (ModulateImage): Improve progress message.</li>
+<li>coders/msl.c: Eliminate memory leaks.</li>
+<li>GraphicsMagick.spec.in: Apply RPM spec file fixes from Giacomo
+Tenaglia for Red Hat Linux 4.</li>
+</ul>
+</blockquote>
+<p>2008-11-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/msl.c: Fix bug with attributes becoming appended to
+themselves. Resolves SF issue 2255754. Reflowed code.</li>
+</ul>
+</blockquote>
+<p>2008-11-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: GraphicsMagick 1.3 released.
+Next release on head will be 1.4.</li>
+<li>www/OpenMP.rst: Updated with latest measurement data.</li>
+<li>www/benchmarks.rst: Updated with latest benchmark data.</li>
+<li>coders/url.c (RegisterURLImage): Register HTTP and FTP URL
+support in the &quot;unstable&quot; category since these are capable of
+accessing the network and therefore represent a potential security
+issue. Register the FILE URL support in the &quot;stable&quot; category
+since it is capable of incorporating local disk files, which may
+still represent a security security issue for server applications.
+Note that disabling these functions might cause some existing MSL,
+MVG and SVG scripts to stop working if they use external URLs.</li>
+</ul>
+</blockquote>
+<p>2008-11-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (ReadPNMImage): Sequential multi-thread the PNM raw
+format readers. Can improve read performance quite substantially
+for large PBM and PGM files, and less so for PPM. There is most
+benefit for systems with more I/O than one CPU core will support.
+Systems with slow I/O and a relatively fast CPU may see somewhat
+diminished read performance with more CPU consumption. As such,
+this is effectively a verification that multi-threading the reader
+is possible, and may be of benefit to power-users.</li>
+<li>magick/omp_data_view.c (AllocateThreadViewDataArray): New
+function to allocate a thread view data array. Updated modules
+using similar code to use this function in order eliminate
+useless redundancy.</li>
+</ul>
+</blockquote>
+<p>2008-11-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c: Incorporate OMP thread views into the
+pixel cache so usage is less invasive. Update OMP-enhanced source
+modules to suit.
+(GetImagePixelsEx): New function similar to GetImagePixels()
+except that it reports exceptions to a user-provided structure.
+(SetImagePixelsEx): New function similar to SetImagePixels()
+except that it reports exceptions to a user-provided structure.
+(SyncImagePixelsEx): New function similar to SyncImagePixels()
+except that it reports exceptions to a user-provided structure.
+(AccessImmutableIndexes): New function to access read-only
+colormap indexes.
+(AccessMutableIndexes): New function to access writeable colormap
+indexes.
+(AccessMutablePixels): New function to access writeable pixels.
+(AccessDefaultCacheView): New function to access the default cache
+view.</li>
+</ul>
+</blockquote>
+<p>2008-11-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (BenchmarkImageCommand): With no other
+arguments, the benchmark command now defaults to one iteration.</li>
+<li>magick/effect.c (SpreadImage): Offsets array size is a prime
+number to help avoid beating.
+(SpreadImage): Ensure that spread loops are always terminal.</li>
+<li>magick/utility.c (MagickRandReentrant): Fix bug where rand() was
+being continually re-seeded if rand_r() was not available.</li>
+</ul>
+</blockquote>
+<p>2008-11-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/tests/msl_composite.sh: Replace SVG image generation
+with simpler approach which properly centers the text. Use our
+own font so that tests will pass if the user does not have fonts
+installed.</li>
+<li>magick/utility.c (GetMagickDimension): Extend to support parsing
+optional x and y offset values and use to fix parsing for
+-oil-paint and -unsharp when sscanf() is C'99 compliant.</li>
+</ul>
+</blockquote>
+<p>2008-11-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.h (AcquireOneCacheViewPixel): Pass pixel to
+update by reference.
+(AcquireOnePixelByReference): New private inline method which
+passes pixel to update by reference.</li>
+<li>magick/omp_thread_view.h (AcquireOneThreadViewPixel): Pass pixel
+to update by reference.</li>
+<li>magick/alpha_composite.h (BlendCompositePixel): Replace
+BlendComposite with BlendCompositePixel, which passes the
+composite pixel by reference.
+(AlphaCompositePixel): Replace AlphaComposite with
+AlphaCompositePixel, which passes the composite pixel by
+reference.
+(AtopCompositePixel): Replace AtopComposite with
+AtopCompositePixel, which passes the composite pixel by reference.</li>
+<li>configure.ac: With excessive maintenance releases, the library
+age portion of MAGICK_LIB_VERSION was overflowing its allotted
+space. This resulted in 1.1.X releases reporting the wrong
+MagickLibVersion as of 1.1.10. Fix this by supporting up to 99
+values for each field.</li>
+</ul>
+</blockquote>
+<p>2008-11-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Fix passing the --with-windows-font-dir option via
+DISTCHECK_CONFIG_FLAGS.</li>
+<li>utilities/tests/msl_composite.sh: Integrated MSL composition
+test script contributed by Max Hohenegger, Max at hohenegger.eu.</li>
+<li>magick/command.c (ConjureImageCommand): Return status was
+inverted so one was returned for command success rather than zero.</li>
+</ul>
+</blockquote>
+<p>2008-11-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Updated libpng to 1.2.33 release.</li>
+<li>magick/color.c (FuzzyColorMatch): If fuzz is zero then
+completely use the result of ColorMatch() rather than entering
+unnecessary expensive code.</li>
+</ul>
+</blockquote>
+<p>2008-10-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h: Make sure we don't conflict with OpenMP
+implementation if it is active but we are not using it.</li>
+</ul>
+</blockquote>
+<p>2008-10-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h (HAVE_OPENMP): Add logic to make sure that
+OpenMP is only engaged for OpenMP 2.0 or later.</li>
+<li>magick/command.c (VersionCommand): Report OpenMP version.</li>
+<li>Makefile.am: The Magick++ build was supposed to be optional. Now
+it is.</li>
+<li>Makefile.am: Eliminated .tar.bz2 and .zip packages from the
+distribution. The .tar.bz2 package was hardly smaller than the
+.tar.gz package so it wasted 5.9MB with little benefit. The
+compression ratio on the .zip archives is absolutely terrible so
+eliminating zip eliminates huge 9.6MB and 25MB files from the
+distribution equation. Windows users can easily learn how to use
+the vastly more efficient 7-Zip format.</li>
+</ul>
+</blockquote>
+<p>2008-10-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Rationalize OpenMP tests to make sure that OpenMP
+can not be enabled without thread support.</li>
+</ul>
+</blockquote>
+<p>2008-10-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c (CompositeImageRegion): Add some minimal
+region limit checking. Not completed yet.</li>
+<li>magick/transform.c (RollImage): Accellerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-10-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h (omp_get_thread_num): Remove spurious trailing
+<cite>;</cite>.</li>
+<li>magick/render.c (DrawPrimitive): Make method private since
+nothing else is using it.</li>
+<li>magick/omp_thread_view.h (AccessThreadView): Inline function for
+a bit more performance.
+(AcquireOneThreadViewPixel) Inline function for a bit more
+performance.</li>
+</ul>
+</blockquote>
+<p>2008-10-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>pragma omp parallel for: Use consistent static scheduling
+throughout and ensure that 64 threads can be usefully engaged on a
+1024 row image.</li>
+<li>magick/pixel_iterator.c (SetRegionThreads): Implement logic so
+that pixel iterators execute single-threaded when invoked on tiny
+regions.</li>
+<li>magick/pixel_cache.c (SetNexus): Make staging buffer memset()
+conditional in order to dramatically diminish impact to small
+accesses. This memset() only exists to make valgrind happy.</li>
+</ul>
+</blockquote>
+<p>2008-10-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Fix progress monitor for the case
+of reading planar stripped images.</li>
+</ul>
+</blockquote>
+<p>2008-10-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (DespeckleImage): Accelerate using OpenMP.</li>
+<li>magick/paint.c (OpaqueImage): Update to use pixel iterators.
+(TransparentImage): Update to use pixel iterators.</li>
+<li>magick/decorate.c (FrameImage): Accelerate using OpenMP.
+(RaiseImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-10-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c (CompositeImageRegion): Start of new function
+to act as a lighter-weight yet more flexible image composition
+interface.</li>
+<li>magick/transform.c (ChopImage): Accelerate using OpenMP.
+(CropImage): Accelerate using OpenMP.
+(FlipImage): Accelerate using OpenMP.
+(FlopImage): Accelerate using OpenMP.</li>
+<li>magick/effect.c (ThresholdImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-10-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (AcquireOneCacheViewPixel): Optimize
+implementation.</li>
+<li>magick/effect.c (MedianFilterImage): Accelerate using OpenMP.
+(ReduceNoiseImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-10-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/fx.c (WaveImage): Accelerate using OpenMP.
+(SwirlImage): Accelerate using OpenMP.
+(ImplodeImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-10-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (GetCacheViewRegion): New function to
+return the region bounded by a pixel cache view.</li>
+<li>magick/constitute.c (ExportViewPixelArea): New function to
+support exporting the pixels from a pixel cache view.
+(ImportViewPixelArea): New function to support importing pixels
+to a pixel cache view.</li>
+<li>magick/pixel_cache.c (ReadStream): Eliminated function.
+(WriteStream): Eliminated function.
+(ClonePixelCacheMethods): Eliminated function.</li>
+<li>magick/image.h: Eliminated StreamHandler call-back type.
+Eliminated ImageInfo stream member.</li>
+<li>magick/pixel_cache.c (GetCacheViewArea): New function to return
+the area of a cache view.
+(AccessCacheViewPixels): New function to access already selected
+cache view pixels.</li>
+</ul>
+</blockquote>
+<p>2008-10-19 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c: Remove unused exponential data.</li>
+</ul>
+</blockquote>
+<p>2008-10-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/omp_thread_view.c: Move OMP Thread View functions out of
+pixel cache module and put them in this new module.</li>
+<li>coders/xtrn.c (ReadXTRNImage): XTRNSTREAM mode was never
+implemented so remove unfinished stub code.</li>
+</ul>
+</blockquote>
+<p>2008-10-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageDepth): Needed to assign image depth
+attribute to user-specified depth rather than only altering the
+pixels.
+(SetImageOpacity): Reimplement using pixel iterators.
+(AverageImages): Accelerate using OpenMP.
+(GetImageBoundingBox): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-10-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ConstituteTextureImage): Accelerate using
+OpenMP.</li>
+<li>magick/image.c (TextureImage): Accelerate using OpenMP.</li>
+<li>magick/render.c (DrawAffineImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-10-13 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c Fixed palette problem for &gt;8 bit images.</li>
+</ul>
+</blockquote>
+<p>2008-10-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): Using +page now resets image
+page offsets as documented for convert and mogrify.</li>
+</ul>
+</blockquote>
+<p>2008-10-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GradientImage): Re-do OpenMP accelleration based
+on new pixel cache interface for better performance.</li>
+<li>coders/dpx.c (ReadDPXImage): Progress monitor needs to tick when
+row count is updated.</li>
+<li>coders/fits.c (ReadFITSImage): Update to use
+MagickFindRawImageMinMax().
+(WriteFITSImage): Expand buffer size to MaxTextExtent. Include
+GraphicsMagick version in FITS header.</li>
+<li>coders/mat.c (ReadMATImage): Update to use
+MagickFindRawImageMinMax().</li>
+<li>magick/constitute.c (MagickFindRawImageMinMax): New internal
+function to assist with finding the minimum and maximum data of
+raw image files.</li>
+</ul>
+</blockquote>
+<p>2008-10-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (AcquireThreadViewPixels): Convert thread
+set view convenience methods into library methods because the
+inline methods were causing the Sun Studio compiler to produce
+thread unsafe code. Due to likely beneficial inlining in the
+library, this is not expected to cause any performance impact.</li>
+</ul>
+</blockquote>
+<p>2008-10-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/filter.t: Add a test for UnsharpMask.</li>
+<li>magick/effect.c (UnsharpMaskImage): Use Blur rather than
+GaussianBlur to create blur image since it is faster.</li>
+<li>magick/pixel_cache.c (AllocateThreadViewDataSet): Add a
+destructor function in case data should not be destroyed, or needs
+something other than MagickFree().
+(AllocateThreadViewDataSet): Use user-provided destructor to free
+user data.</li>
+<li>scripts/format_c_api_doc.py: Improvements from Mark Mitchell to
+perform keyword/target substitions and wrap function prototypes.</li>
+<li>coders/dpx.c (ReadDPXImage): Accellerate reader using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/api/types.rst: Convert types.html to reStructured text
+format.</li>
+</ul>
+</blockquote>
+<p>2008-10-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/monitor.c (MagickMonitorFormatted): New method to support
+issuing a formatted progress monitor message. Use it throughout
+so that file name is included in progress indication.</li>
+</ul>
+</blockquote>
+<p>2008-10-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Bootstrap with autoconf 2.63. Require autoconf
+2.62 to bootstrap.</li>
+</ul>
+</blockquote>
+<p>2008-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www: Adopted improved web page design by Mark Mitchell.</li>
+</ul>
+</blockquote>
+<p>2008-10-04 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c coders/mat.c Used a same piece of code to calculate
+min and max data value.</li>
+</ul>
+</blockquote>
+<p>2008-09-30 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c Fixed 16 bit fits writer that wrote wrongly
+shaped unsigned ints.</li>
+</ul>
+</blockquote>
+<p>2008-09-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/conjure.imdoc: Applied patches from Max at hohenegger.eu to
+mention previously undocumented elements and to provide a
+composition example.</li>
+</ul>
+</blockquote>
+<p>2008-09-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c (IntegralRotateImage): Accelerate rotation by 0
+and 180 degrees using OpenMP.
+(XShearImage): Accellerate using OpenMP (accellerates -rotate and
+-shear).
+(YShearImage): Accellerate using OpenMP (accellerates -rotate and
+-shear).</li>
+</ul>
+</blockquote>
+<p>2008-09-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (MotionBlurImage): Enable OpenMP now that pixel
+cache is re-entrant.</li>
+<li>magick/pixel_iterator.c: Updated to use thread view convenience
+inline methods as proof of principle.</li>
+<li>magick/pixel_cache.h: Added convenience inline methods to make
+use of thread views a bit more pleasant.</li>
+</ul>
+</blockquote>
+<p>2008-09-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ShadeImage): Fix valgrind gripe.
+(MedianFilterImage): Fix valgrind gripe.</li>
+</ul>
+</blockquote>
+<p>2008-09-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c: Pixel cache is believed to be thread safe
+now.</li>
+<li>magick/deprecate.c (AcquireCacheView): Deprecate this function.
+(GetCacheView): Deprecate this function.
+(SetCacheView): Deprecate this function.
+(SyncCacheView): Deprecate this function.</li>
+<li>magick/pixel_cache.c (AcquireCacheViewPixels): New function to
+replace AcquireCacheView().
+(GetCacheViewPixels): New function to replace GetCacheView().
+(SetCacheViewPixels): New function to replace SetCacheView().
+(SyncCacheViewPixels): New function to replace SyncCacheView().</li>
+<li>coders/msl.c: Applied patches from Max at hohenegger.eu which
+fix a MSL parsing error related to gamma, and erroneous text
+comments which claim that elements can't have attributes.</li>
+</ul>
+</blockquote>
+<p>2008-09-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (ResizeImage): Move OpenMP instrumentation to
+outer loop so that eventually there can be more performance.</li>
+</ul>
+</blockquote>
+<p>2008-09-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (MinifyImage): Accelerate using OpenMP.</li>
+<li>magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+Accept -gaussian-blur as a synonym for -gaussian.
+(ConvertImageCommand, MogrifyImageCommand): Provide access to
+MinifyImage() via -minify.
+(ConvertImageCommand, MogrifyImageCommand): Provide access to
+Magnifyimage() via -magnify.</li>
+</ul>
+</blockquote>
+<p>2008-09-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/channel.c (ImportImageChannelsMasked): New function to
+import all the channels from an image except for the channels
+specified.</li>
+<li>magick/effect.c (AddNoiseImageChannel): New function to add
+noise to an image channel.
+(BlurImageChannel): New function to blur one image channel.
+(GaussianBlurImageChannel): New function to gaussian blur an image
+channel.
+(UnsharpMaskImageChannel): New function to unsharpmask an image
+channel.
+(SharpenImageChannel): New function to sharpen an image channel.</li>
+</ul>
+</blockquote>
+<p>2008-09-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (MotionBlurImage): Use GetOptimalKernelWidth1D()
+to estimate a reasonable convolution kernel size. Prepare code
+for OpenMP but don't enable OpenMP until it runs faster.
+(AddNoiseImageChannel): New function to apply noise to a specified
+image channel.</li>
+</ul>
+</blockquote>
+<p>2008-09-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ConvertImageCommand): Provide <cite>convert</cite> access
+to MotionBlurImage() via -motion-blur option.
+(MogrifyImageCommand): Provide <cite>mogrify</cite> access to
+MotionBlurImage() via -motion-blur option.</li>
+</ul>
+</blockquote>
+<p>2008-09-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (SpreadImage): Accelerate using OpenMP.</li>
+<li>coders/msl.c: Applied MSL patch from graphicsmagick-bugs list to
+correct handling of geometry x,y values by setting gravity
+attribute to ForgetGravity.</li>
+</ul>
+</blockquote>
+<p>2008-09-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ShadeImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-09-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (RandomChannelThresholdImage): Accelerate using
+OpenMP. Support individual thresholding of the color channels.
+(BlurImage): Blur was failing for PseudoClass images. This bug
+was added on 2008-09-08.</li>
+<li>magick/pixel_cache.c (AcquireOneCacheViewPixel): New function to
+return just one pixel from a cache view.</li>
+</ul>
+</blockquote>
+<p>2008-09-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (EnhanceImage): Accelerate using OpenMP.
+(BlurImageScanlines): Added optimizations.</li>
+<li>magick/shear.c (IntegralRotateImage): Add missing progress
+indication for 90 and 270 degrees rotation.</li>
+<li>www/perl.html: Fix formatting of examples. Should address
+SourceForge issue [ 2100339 ] &quot;Wrong format in example script on
+web page&quot;.</li>
+</ul>
+</blockquote>
+<p>2008-09-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (BlurImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-09-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/fx.c (ColorizeImage): Re-implement using pixel iterators.
+(MorphImages): Re-implement using pixel iterators.
+(OilPaintImage): Accelerate using OpenMP.
+(SolarizeImage): Re-implement using pixel iterators.</li>
+</ul>
+</blockquote>
+<p>2008-09-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/fx.c (ConvolveImage): Accelerate using OpenMP.</li>
+<li>magick/effect.c (AdaptiveThresholdImage): Accelerate using OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-09-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c: Exhuastive study of the pixel cache code
+reveals that it is inscrutable and not implemented in a fashion
+which enables useful multi-threading. Therefore, the cache view
+interfaces are now made OpenMP-safe via a global critical section.</li>
+</ul>
+</blockquote>
+<p>2008-09-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_iterator.c: Reduce use of critical sections around
+pixel cache to the bare minimum based on analysis and testing.
+Unfortunately, testing shows that the pixel cache views are still
+not 100% thread safe so the extra locking is still required.</li>
+<li>magick/pixel_cache.c (ModifyCache): Make implementation thread
+safe. This required removing a thread-unsafe optimization from
+Bill Radcliffe.</li>
+<li>magick/command.c (BenchmarkImageCommand): Restore original
+client name for each loop so that it is not extended further for
+each iteration.</li>
+<li>magick/semaphore.c (UnlockSemaphoreInfo): Decrement lock depth
+under protection of the lock.</li>
+</ul>
+</blockquote>
+<p>2008-09-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (AddNoiseImagePixels): Update to pass per-thread
+<cite>seed</cite> value for more performance.</li>
+</ul>
+</blockquote>
+<p>2008-08-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/gem.c (GenerateDifferentialNoise): Use
+MagickRandReentrant(). Added a <cite>seed</cite> argument so that we can pass
+a per-thread <cite>seed</cite> value.</li>
+<li>magick/utility.c (MagickRandNewSeed): New function to produce a
+semi-random <cite>seed</cite> value.
+(MagickRandReentrant): New function which works like rand() but
+attempts to be re-entrant if possible by allowing a seed value to
+be passed.</li>
+</ul>
+</blockquote>
+<p>2008-08-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/channel.c (SetImageChannelDepth): Re-implement using
+QuantumOperatorImage().</li>
+<li>magick/image.c (SetImageDepth): Re-implement using
+QuantumOperatorImage().</li>
+<li>magick/operator.h (QuantumOperator): Added DepthQuantumOp for
+setting the channel depth.</li>
+<li>magick/command.c (BenchmarkImageCommand): Add CPU-based
+iteration rate metric to benchmark output.</li>
+<li>magick/resource.c (ListMagickResourceInfo): Include quantum
+depth, bits per pixel, and process address size in resource
+output so that output is more complete.</li>
+</ul>
+</blockquote>
+<p>2008-08-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SyncImage): Re-implement using pixel iterators.
+(SortColormapByIntensity): Re-implement using pixel iterators.
+(ClipPathImage): Re-implement using pixel iterators.
+(CycleColormapImage): Re-implement using pixel iterators.
+(GetImageDepth): Re-implement using pixel iterators.
+(GradientImage): Parallize inner loop for speedup with larger
+images.
+(ReplaceImageColormap): Re-implement using pixel iterators.
+(SetImage): Re-implement using pixel iterators.</li>
+</ul>
+</blockquote>
+<p>2008-08-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/operator.c (QuantumGamma): Removed unnecessary OpenMP
+request on inner loops.</li>
+<li>magick/enhance.c (EqualizeImage,NormalizeImage): Execute
+histogram generation pixel iterator with just one thread to
+decrease contention for the histogram array.</li>
+<li>magick/pixel_iterator.c (InitializePixelIteratorOptions): New
+function to initialize PixelIteratorOptions with defaults.</li>
+<li>magick/pixel_iterator.h (PixelIteratorOptions): New structure to
+support passing pixel iterator execution options.</li>
+</ul>
+</blockquote>
+<p>2008-08-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated for changes to date in 1.3 development code.</li>
+<li>magick/pixel_iterator.c: Execute pixel iterators in parallel via
+OpenMP.</li>
+<li>magick/pixel_cache.c (OpenCacheView): Ensure that pixel cache is
+open.
+(GetCacheInfo): Allocate semaphore immediately.</li>
+</ul>
+</blockquote>
+<p>2008-08-16 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c Writer now creates valid images according to
+<a class="reference external" href="http://fits.gsfc.nasa.gov/fits_verify.html">http://fits.gsfc.nasa.gov/fits_verify.html</a>
+Fixed problems: 1) zeros in HDU, 2) wrong padding. 3) possible
+strlen() overflow.</li>
+</ul>
+</blockquote>
+<p>2008-08-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/{compare.c, channel.c, enhance.c, image.c, operator.c}:
+Update existing pixel iterator callback functions so that they are
+OpenMP safe.</li>
+</ul>
+</blockquote>
+<p>2008-08-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/compare.c (InitializeDifferenceImageOptions): Renamed
+from DifferenceImageOptionsDefaults().
+(InitializeDifferenceStatistics): New function to initialize
+DifferenceStatistics.
+(ComputeAbsoluteError, ComputePeakAbsoluteError,
+ComputeSquaredError): Use local totalizing structure on stack and
+update cumulative statistics when the loop terminates.</li>
+</ul>
+</blockquote>
+<p>2008-08-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www: Convert HTML pages to use a vibrant green theme rather than
+colors stolen from old GIMP web site.</li>
+</ul>
+</blockquote>
+<p>2008-08-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/{compare.imdoc, options.imdoc}: Added documentation for
+<cite>compare</cite>.</li>
+<li>magick/compare.h (enum HighlightStyle): Added
+AssignHighlightStyle for simple color assignment. <cite>Annotate</cite> is
+now <cite>Tint</cite>.</li>
+<li>magick/command.c (CompareImageCommand): Useful options are now
+-metric, -highlight-color, and -hightlight-style.</li>
+</ul>
+</blockquote>
+<p>2008-08-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/compare.c (DifferenceImagePixels): Fixed <cite>Annotate</cite>
+difference annotation algorithm. Added <cite>Threshold</cite> and <cite>Xor</cite>
+difference annotation algorithms.
+(GetImageChannelDifference): New function for computing
+statistical image error using various metrics. Inspired by
+<cite>imgcmp</cite> from Jasper.
+(GetImageChannelDistortion): New function for obtaining
+statistical image error using various metrics for a specified
+image channel. Signature is compatible with similar ImageMagick
+function.
+(GetImageDistortion): New function for obtaining statistical image
+error using various metrics for all the active channels in the
+image. Signature is compatible with similar ImageMagick function.</li>
+<li>magick/command.c (CompareImageCommand): Added a <cite>compare</cite>
+subcommand which compares two images using various metrics, and/or
+generates a difference image using various difference annotation
+algorithms. Documentation not yet updated.</li>
+</ul>
+</blockquote>
+<p>2008-08-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_iterator.c: Split user context in all pixel
+iterator APIs into a mutable data part, and an immutable data
+part. This required modification to all modules using the pixel
+iterator methods.</li>
+</ul>
+</blockquote>
+<p>2008-07-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickCompareImageChannels): Use
+DifferenceImage().
+(MagickCompareImages): Implement by calling
+MagickCompareImageChannels().</li>
+<li>magick/compare.c (DifferenceImage): The ImageMagick-compatible
+CompareImages() function signature was clearly an example of bad
+design so rename CompareImages() to DifferenceImage() with a
+signature which does not unnecessarily mix functionality and
+allows for ease of future expansion.</li>
+</ul>
+</blockquote>
+<p>2008-07-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/Makefile.am (WAND_TESTS): Added Wand drawtest and wandtest
+to automated test suite.</li>
+</ul>
+</blockquote>
+<p>2008-07-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ThresholdImage): Don't read uninitialized pixel
+indexes (valgrind gripe).</li>
+<li>coders/tiff.c (CompressionSupported): Use
+TIFFIsCODECConfigured() to test if a codec is supported.</li>
+<li>tests/{rwblob.c, rwfile.c}: use DestroyImageList() rather than
+DestroyImage().</li>
+<li>coders/psd.c (RegisterPSDImage): Fix module registration memory leak.</li>
+<li>coders/jpeg.c (RegisterJPEGImage): Fix module registration memory leak.</li>
+</ul>
+</blockquote>
+<p>2008-07-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (DestroyBlob, DestroyBlobInfo): Implementation is
+a bit more robust.</li>
+</ul>
+</blockquote>
+<p>2008-07-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (ReadJPEGImage): Remove over-write of
+image-&gt;client_data. Resolves SourceForge issue [ 2018974 ]
+client_data is not passed to streamhandler.</li>
+<li>coders/png.c (WriteOnePNGImage): Fix crash when writing PNG
+images with transparency and either type Optimize is requested, or
+the image is colormapped.</li>
+</ul>
+</blockquote>
+<p>2008-07-12 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Fixed problem: &quot;In this case, the referenced
+images had previously been deallocated but are still being used.
+Since they are overwritten, their signatures are invalid.</li>
+</ul>
+</blockquote>
+<p>2008-07-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcm.c (ReadDCMImage): Report actual image depth.</li>
+<li>magick/resource.c (InitializeMagickResources): Set default
+maximum memory limit to physical memory rather than 2X physical
+memory. This decision is made since the system paging device is
+often slower than files in the filesystem, and so memory mapping
+is likely faster.</li>
+<li>magick/blob.c (OpenBlob): The MAGICK_IO_FSYNC environment
+variable causes output files to be synchronized to disk when set
+to TRUE.</li>
+</ul>
+</blockquote>
+<p>2008-07-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/GraphicsMagick.html: Improved formatting of documentation.</li>
+</ul>
+</blockquote>
+<p>2008-07-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Make use of the new
+<cite>extension_treatment</cite> field.</li>
+<li>coders/dcraw.c (ReadDCRAWImage): Added a coder module to proxy
+from various common RAW camera format extensions to the <cite>dcraw</cite>
+delegate.</li>
+<li>magick/magick.h (MagickInfo): Add an extension_treatment member
+to indicate how file extensions should be treated for this coder.</li>
+</ul>
+</blockquote>
+<p>2008-06-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/{animate.c,quantize.c}: Replace !ColorMatch() with
+NotColorMatch().</li>
+<li>utilities/Makefile.am (install-exec-local-utilities): Add back
+in support for --enable-magick-compat which was accidentally
+dropped in the new makefiles for GraphicsMagick 1.2. Resolves
+SourceForge bug 2005883.</li>
+<li>magick/color.h (NotColorMatch): New macro for testing that two
+colors are not the same. Opposite from existing ColorMatch().</li>
+<li>magick/command.c: Replaced the many duplicate enum conversion
+code fragments with calls to functions in enum_strings.c.</li>
+<li>magick/enum_strings.c: Absorbed the many &quot;ToString&quot; and
+&quot;StringTo&quot; functions from other source modules.</li>
+<li>magick/effect.c (ThresholdImage): Optimize for larger images.</li>
+<li>magick/constitute.c (ConstituteTextureImage): New function to
+return a texture canvas image based on a tile image. Similar to
+existing TextureImage() except better optimized for creating new
+images and inherits tile image properties.</li>
+<li>magick/color.h (IsBlackPixel): New macro to test if a pixel is
+black.
+(IsWhitePixel): New macro to test if a pixel is white.</li>
+<li>coders/tile.c (ReadTILEImage): Use new ConstituteTextureImage()
+function rather than TextureImage(). Also allow the user to
+request a particular image type.</li>
+<li>coders/pdf.c (Huffman2DEncodeImage): Explicitly request a strip
+per page when writing Group4 TIFF.</li>
+<li>coders/tiff.c (WriteTIFFImage): Place a generous default limit
+on rows-per-strip when using Group3 or Group4 FAX compression.
+The default limit is added since it is observed that the Group4
+compressor fails with extremely huge strips. Added a define
+&quot;tiff:rows-per-strip&quot; to allow the user to explicitly set the rows
+per strip. Added a define &quot;tiff:strip-per-page=true&quot; to allow the
+user to force one strip per page no matter what. Added progress
+monitor support to tile writer.</li>
+</ul>
+</blockquote>
+<p>2008-06-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/configure/configure.cpp: The MAT coder now depends
+on zlib so add explicit dependencies for it.</li>
+<li>wand/magick_wand.c (MagickNegateImage): Implemented previously
+unimplemented Wand method.
+(MagickGammaImageChannel): Implemented previously unimplemented
+Wand method.</li>
+<li>magick/operator.h (enum QuantumOperator): Added GammaQuantumOp
+and &quot;gamma&quot; operator. Renamed InvertQuantumOp to NegateQuantumOp.</li>
+</ul>
+</blockquote>
+<p>2008-06-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/operator.h (enum QuantumOperator): Added InvertQuantumOp
+and &quot;invert&quot; operator.</li>
+<li>coders/xcf.c (GIMPBlendModeToCompositeOperator): For XCF format,
+we do support GIMP_DIVIDE_MODE composition now. Disable progress
+monitor during tile composition.</li>
+<li>magick/composite.c (DivideCompositePixels): New Divide composite
+operator contributed by Michael Burian &lt;<a class="reference external" href="mailto:michael&#46;burian&#37;&#52;&#48;sbg&#46;at">michael<span>&#46;</span>burian<span>&#64;</span>sbg<span>&#46;</span>at</a>&gt;.</li>
+<li>magick/image.h (enum CompositeOperator): Added DivideCompositeOp.</li>
+<li>magick/enum_strings.c (CompositeOperatorToString): New function
+to convert a composite operator to a string.
+(StringToCompositeOperator): New function to convert a string to a
+composite operator.</li>
+</ul>
+</blockquote>
+<p>2008-06-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickThresholdImageChannel): Implement
+previously unimplemented Wand function.
+(MagickGetImageExtrema): Implement previously unimplemented Wand
+function.
+(MagickGetImageChannelExtrema): Implement previously unimplemented
+Wand function.
+(MagickQueryFonts): Implement previously unimplemented Wand
+function.</li>
+</ul>
+</blockquote>
+<p>2008-06-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>scripts/format_c_api_docs: Scan compare.c for API definitions.</li>
+<li>wand/magick_wand.c (MagickCompareImageChannels): Enable use of
+this function.
+(MagickCompareImages): Enable use of this function.</li>
+<li>magick/compare.c: New source file.
+(IsImagesEqual): Move here from magick/image.c.
+(CompareImageChannels): Initial implementation of function roughly
+similar to the one in ImageMagick.
+(CompareImages): Initial implementation of function roughly
+similar to the one in ImageMagick.</li>
+<li>magick/pixel_iterator.c (PixelIterateTripleModify): New pixel
+iterator function to access two images as read-only and one as
+read-write for updating existing pixels.
+(PixelIterateTripleNew): New pixel iterator function to access two
+images as read-only and one as read-write for creating new pixels.</li>
+</ul>
+</blockquote>
+<p>2008-06-22 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>mat.c Added CloseBlob().</li>
+</ul>
+</blockquote>
+<p>2008-06-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickSetImageFormat): Add method to support
+setting the image format.</li>
+</ul>
+</blockquote>
+<p>2008-06-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c (ProfileImage): Convert to use pixel iterators.</li>
+</ul>
+</blockquote>
+<p>2008-06-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/channel.c (ImportImageChannel): Convert to use pixel
+iterators.
+(SetImageChannelDepth): Convert to use pixel
+iterators.</li>
+<li>Magick++/lib/Image.cpp (quantize): Error measurement support was
+being performed incorrectly. SyncImage() is not needed here.</li>
+</ul>
+</blockquote>
+<p>2008-06-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/channel.c (GetImageChannelDepth): Convert to use pixel
+iterators.</li>
+</ul>
+</blockquote>
+<p>2008-06-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c (RegisterMATImage): Set blob support to false for
+MAT coder until bug related to blobs is fixed.</li>
+</ul>
+</blockquote>
+<p>2008-06-16 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>mat.c Ability to read a new compressed MATLAB image format.</li>
+</ul>
+</blockquote>
+<p>2008-06-15 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>mat.c, wpg.c: For empty images a message ImageFileDoesNotContainAnyImageData
+is returned.</li>
+</ul>
+</blockquote>
+<p>2008-06-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/channel.c (ChannelImage): Convert to use pixel iterators.
+(ExportImageChannel): Convert to use pixel iterators.</li>
+<li>coders/dpx.c (WriteDPXImage): As an experimental feature, when
+the environment variable MAGICK_RESERVE_STORAGE is set to &quot;TRUE&quot;,
+then the DPX format writer will request the required storage from
+the filesystem in advance (if supported by the OS) or the full
+amount of memory required (when writing to an in-memory BLOB).</li>
+</ul>
+</blockquote>
+<p>2008-06-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magic.c (InitializeMagicInfo): New function to initialize
+file format detection.
+(GetMagickFileFormat): New internal implementation function to
+detect file format based on file header.
+(GetMagicInfo): This internal implementation function is eliminated.
+(MagicInfo): MagickInfo structure is now private to the
+implementation.</li>
+</ul>
+</blockquote>
+<p>2008-06-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (ListMagickInfo): Replace &quot;blob support&quot;
+indication with the coder stability classification.
+(RegisterMagickInfo): Pay attention to coder classification.</li>
+<li>magick/magick.h (MagickInfo): Added a coder stability
+classification field as well as the MAGICK_CODER_STABILITY
+environment variable to choose which coders are enabled.</li>
+</ul>
+</blockquote>
+<p>2008-06-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GetImageCharacteristics): Don't access image
+pixels if they are not defined yet.</li>
+<li>coders/{avi.c,avs.c,dcm.c,ept.c,fits.c,mtv.c,palm.c,rla.c,tga.c}:
+Readers are now much more robust when faced with reading random files.</li>
+</ul>
+</blockquote>
+<p>2008-06-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Exclude all virtual delegates and
+coders for pseudo-formats.</li>
+</ul>
+</blockquote>
+<p>2008-06-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcm.c (ReadDCMImage): Make DCM reader quit immediately on
+EOF condition.</li>
+<li>coders/avi.c (ReadAVIImage): Make AVI reader more robust at
+rejecting bad files.</li>
+<li>configure.ac: Eliminated --enable-delegate-build option that I
+have not used or tested for almost ten years so it probably did
+not work anyway. Use --with-ttf=/prefix to specify the the
+installation prefix for freetype. Use
+--with-ttf=/prefix/bin/freetype-config to specify the whole path
+to freetype-config.</li>
+</ul>
+</blockquote>
+<p>2008-06-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): Add support for
+-black-threshold and -white-threshold.</li>
+<li>magick/image.h (enum ChannelType): Added GrayChannel
+enumeration.</li>
+<li>magick/operator.c (QuantumOperatorImageMultivalue): New
+implementation function to make creating legacy functions like
+black/white thresholding easier.</li>
+<li>wand/magick_wand.c (MagickBlackThresholdImage): Implemented.
+(MagickWhiteThresholdImage): Implemented.</li>
+<li>magick/effect.c (BlackThresholdImage): Implemented a
+BlackThresholdImage() which is similar to (but not identical to)
+the one in ImageMagick.
+(WhiteThresholdImage): Implemented a WhiteThresholdImage() which
+is similar to (but not identical to) the one in ImageMagick.</li>
+</ul>
+</blockquote>
+<p>2008-06-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/operator.c: Added support for additional channel
+operators (-operator) for applying noise to one or more channels.
+The additional operators are Noise-Gaussian, Noise-Impulse,
+Noise-Laplacian, Noise-Multiplicative, Noise-Poisson, and
+Noise-Uniform. The amount of noise applied is controlled via the
+numeric argument, which can specify the percentage of noise to
+apply.</li>
+<li>magick/enum_strings.c: New source module to contain the various
+EnumToString() and StringToEnum() functions which seem to multiply
+like bunny-rabbits.</li>
+<li>magick/gem.c (GenerateNoise): Poisson noise generation was
+taking excessively long and producing wrong results. Noise
+generation was only producing the correct amount of noise in the
+Q8 build.
+(GenerateDifferentialNoise): New function to return noise in a
+floating-point differential format.</li>
+</ul>
+</blockquote>
+<p>2008-06-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_iterator.h: Removed x,y coordinate information from
+all of the callback definitions since a use for this information
+has yet to be found.</li>
+<li>magick/composite.c (CompositeImage): Use individual callback
+functions for the composition operations.</li>
+<li>coders/xcf.c (ReadXCFImage): Deal with grayscale images the
+GraphicsMagick-way.</li>
+</ul>
+</blockquote>
+<p>2008-06-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xcf.c (ReadXCFImage): Validate XCF file data so that
+corrupted files don't crash GraphicsMagick.</li>
+</ul>
+</blockquote>
+<p>2008-05-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): Incrementally read user data
+part and check for EOF so that bogus files are rejected quickly.</li>
+<li>coders/cineon.c (ReadCINEONImage): Incrementally read user data
+part and check for EOF so that bogus files are rejected quickly.</li>
+</ul>
+</blockquote>
+<p>2008-05-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pict.c (ReadPICTImage): Ensure that row_bytes calculation
+does not overflow. Verify that RLE decode does not overflow
+buffer. Validate image frame dimensions.</li>
+<li>coders/palm.c (ReadPALMImage): Validate PALM bits per pixel and
+colormap indexes.</li>
+<li>magick/resource.c (ListMagickResourceInfo): List controlling
+environment variable in <cite>-list resource</cite> output as a configuration
+usage reminder.</li>
+<li>coders/pdf.c (ReadPDFImage): Properly deal with reading rotated
+PDFs.</li>
+</ul>
+</blockquote>
+<p>2008-05-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>FAQ.txt: Added a FAQ for how to extract and combine CMYK image
+channels to individual files.</li>
+</ul>
+</blockquote>
+<p>2008-05-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/fx.c (ConvolveImage): Eliminate unnecessary &quot;range check&quot;
+feature since range checking is not where the CPU time is going.</li>
+<li>magick/effect.c (UnsharpMaskImage): Re-write implementation to
+use pixel iterators.</li>
+<li>magick/pixel_iterator.c: Decided that the old per-pixel
+iterations were not useful enough to keep since the region-based
+ones are working fine. Moved pixel_row_iterator.c to
+pixel_iterator.c and renamed functions to remove the <cite>Row</cite>
+designation.</li>
+<li>magick/composite.c (CompositeImage): Automatically adjust
+colorspace of composite image so that it is compatible with canvas
+image.</li>
+<li>magick/alpha_composite.h (AlphaComposite): Fix alpha composite
+when both pixels contain transparency.</li>
+<li>PerlMagick/demo/demo.pl: Use segmentation parameters which
+are more suitable for our image.</li>
+</ul>
+</blockquote>
+<p>2008-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c (CompositeImage): CMYK copy composition
+operators automatically set the image colorspace to CMYK.</li>
+<li>coders/tiff.c (WriteTIFFImage): CMYK must take precedence over
+JPEG compression. We don't support JPEG compression in TIFF with
+CMYK.</li>
+</ul>
+</blockquote>
+<p>2008-05-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ChannelThresholdImage): Re-implement using
+pixel iterators. Support thresholding only the red channel by
+eliminating the switch to intensity thresholding if only one
+channel parameter is supplied.</li>
+<li>coders/tiff.c (WriteTIFFImage): Don't accidentially convert CMYK
+images to RGB.</li>
+<li>magick/composite.c (CompositePixels): Handle CopyBlack properly
+for CMYK images.</li>
+<li>magick/command.c (CompositeImageCommand): Support CopyCyan,
+CopyMagenta, CopyYellow, and CopyBlack.</li>
+<li>magick/composite.c (CompositeImage): Preserve the canvas image
+colorspace.</li>
+<li>doc/options.imdoc: Remove mention of thresholding at the channel
+level since this never worked in a useful fashion and now only
+simple intensity thresholding is available via -threshold.</li>
+<li>magick/command.c (MogrifyImage): Revert to using ThresholdImage() rather
+than ChannelThresholdImage().</li>
+<li>PerlMagick/Magick.xs: Revert to using ThresholdImage() rather
+than ChannelThresholdImage().</li>
+</ul>
+</blockquote>
+<p>2008-05-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (AddNoiseImage): Implemented using pixel
+iterators.</li>
+<li>magick/pixel_row_iterator.c (PixelRowIterateDualNew): New pixel
+iterator. Similar to existing PixelRowIterateDualModify except
+that this one is for when initializing a new image.</li>
+</ul>
+</blockquote>
+<p>2008-05-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c (CompositeImage): Update image composition to
+use pixel iterator methods.</li>
+</ul>
+</blockquote>
+<p>2008-05-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enhance.c: Re-wrote all enhancement functions in this
+module to be based on the pixel iterator methods.</li>
+<li>magick/command.c (ConvertImageCommand, MogrifyImageCommand,
+DisplayImageCommand): Gamma multiple channel syntax was broken.
+Now it is fixed.</li>
+</ul>
+</blockquote>
+<p>2008-05-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colorspace.c (RGBTransformImage): Optimized lookup table
+generation performance to the maximum extent possible.
+(TransformRGBImage): Optimized lookup table
+generation performance to the maximum extent possible.</li>
+<li>magick/image.h (RoundDoubleToQuantum): New macro to explicitly
+safely round a <cite>double</cite> to a Quantum.
+(RoundFloatToQuantum): New macro to explicitly safely round a
+<cite>float</cite> to a Quantum.</li>
+<li>configure.ac: Add OpenMP support library to LIBS so that
+dependent applications will pick up this dependency without
+themselves needing to enable OpenMP.</li>
+<li>magick/command.c (CompositeImageList): Don't overwrite matte
+flag for CopyOpacity composition.</li>
+<li>magick/composite.c (CompositeImage): CopyOpacity composition
+needs the opacity channel to be enabled.</li>
+<li>PerlMagick/Magick.xs: Dissolve composition with Opacity was not
+working right. Now it does.</li>
+</ul>
+</blockquote>
+<p>2008-05-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/gem.c (HWBTransform): Hue value range was scaled wrong,
+leading to clipping.
+(TransformHWB): Hue value range was scaled wrong, leading to
+clipping.</li>
+</ul>
+</blockquote>
+<p>2008-05-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colorspace.c (RGBTransformImage): Re-implement transform
+loops using PixelRowIterateMonoModify() in order to simplify the
+code.</li>
+</ul>
+</blockquote>
+<p>2008-05-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colorspace.c (TransformRGBImage): Re-implement transform
+loops using PixelRowIterateMonoModify() in order to simplify the
+code.</li>
+<li>magick/{pixel_iterator.h, pixel_row_iterator.h}: Pass pixel
+colormap index/indexes to callback functions. Dependent code is
+adjusted to match.</li>
+</ul>
+</blockquote>
+<p>2008-05-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ConvertImageCommand, MogrifyImageCommand,
+MogrifyImage): Add command access to the new channel operators.</li>
+<li>magick/operator.c (QuantumOperatorRegionImage): Support the new
+channel operators. Update to use PixelRowIterateMonoModify() for
+a bit more performance.</li>
+<li>magick/operator.h (enum QuantumOperator): Added new operators
+AssignQuantumOp, ThresholdQuantumOp, ThresholdBlackQuantumOp, and
+ThresholdWhiteQuantumOp.</li>
+</ul>
+</blockquote>
+<p>2008-05-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (VersionCommand): Report if OpenMP is supported
+by the build.</li>
+<li>configure.ac, Makefile.am: Install documentation according to
+the conventions established by the configure script. This
+installs the documentation under
+/usr/local/share/doc/GraphicsMagick by default.</li>
+</ul>
+</blockquote>
+<p>2008-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>scripts/format_c_api_docs: Add pixel_iterator.c and
+pixel_row_iterator.c to API documentation formatter.</li>
+<li>magick/api.h: Include pixel_iterator.h and pixel_row_iterator.h.</li>
+<li>magick/Makefile.am (MAGICK_INCLUDE_HDRS): Formally install
+pixel_iterator.h and pixel_row_iterator.h.</li>
+<li>magick/image.c (IsImagesEqual): Update to use
+PixelRowIterateDualRead().
+(GetImageStatistics): Update to use PixelRowIterateMonoRead().</li>
+<li>magick/pixel_row_iterator.h: New interfaces which are similar to
+the already existing interfaces in pixel_iterator.h except that
+they pass a row to the callback rather than one pixel.</li>
+<li>magick/operator.c (QuantumOperatorRegionImage): Add progress
+monitor support.</li>
+<li>magick/pixel_iterator.c (PixelIterateMonoRead): Add a
+<cite>description</cite> argument and progress monitor support.
+(PixelIterateMonoModify): Add a
+<cite>description</cite> argument and progress monitor support.
+(PixelIterateDualRead): Add a
+<cite>description</cite> argument and progress monitor support.
+(PixelIterateDualModify): Add a
+<cite>description</cite> argument and progress monitor support.</li>
+<li>magick/resize.c (HorizontalFilter, VerticalFilter): Switch back
+to RoundSignedToQuantum() since some pixels were experiencing
+underflow. Localize some variables so that we don't have to
+declare them as private for OpenMP.</li>
+</ul>
+</blockquote>
+<p>2008-05-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac, magick/resize.c, PerlMagick/Makefile.PL.in: Added
+OpenMP support for parallelizing a task across multiple cores.</li>
+</ul>
+</blockquote>
+<p>2008-05-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac, magick/nt_base.h: Fix using libbz2 under MinGW.</li>
+<li>coders/{msl.c, svg.c, url.c}: Fix compilation with modern
+libxml2 under MinGW.</li>
+</ul>
+</blockquote>
+<p>2008-05-08 Josue Andrade Gomes &lt;<a class="reference external" href="mailto:josuegomes&#37;&#52;&#48;gmail&#46;com">josuegomes<span>&#64;</span>gmail<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.h, libxml/include/win32config.h (vsnprintf):
+Fixed compilation issue noticed with Visual C++ 2008.</li>
+</ul>
+</blockquote>
+<p>2008-05-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (GetMagickInfo): Simplify implementation.
+(RegisterMagickInfo): Remove any existing entry since module
+loading may result in duplicate entries.</li>
+</ul>
+</blockquote>
+<p>2008-05-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libtool: Update to libtool 1.2.4.</li>
+<li>magick/magick.h (MagickInfo): Store string attributes as <cite>const
+char *</cite> to statically allocated data rather than as heap allocated
+strings. THIS IS AN INTERFACE CHANGE. Using a coder written to
+the old interface is non-fatal but may resemble a small memory
+leak. The reason for the change is to avoid at least 880 needless
+malloc()/strlen()/strlcpy() operations at initialization time, and
+at least 880 free() calls at destruction time. While these
+operations did not take long, they are still an unnecessary
+overhead, which is increased in thread-safe applications.</li>
+<li><dl class="first docutils">
+<dt>magick/module.c (OpenModule): Ignore requests to open modules</dt>
+<dd>which have already been opened.</dd>
+</dl>
+</li>
+<li>GraphicsMagick.spec.in: Add --with-included-ltdl to the default
+options since this seems safest until the libltdl validation logic
+is fully robust. This should be made user-configurable in the
+future.</li>
+<li>magick/Makefile.am (magick_libGraphicsMagick_la_LIBADD): Apply
+libltdl dependency argument as required for building.</li>
+<li>configure.ac: Intuit if the GraphicsMagick library will depend
+on -lltdl.</li>
+<li>Magick++/bin/GraphicsMagick++-config.in: Use substitutions
+rather than invoking GraphicsMagick-config in order to determine
+GraphicsMagick library usage requirements. This avoids problems
+when GraphicsMagick-config is not in the executable search path.</li>
+</ul>
+</blockquote>
+<p>2008-05-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec.in: NEWS was renamed to NEWS.txt. Enable
+libtool verbose output so it is possible to diagnose build
+failures.</li>
+</ul>
+</blockquote>
+<p>2008-05-01 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>mat.c: gm convert -limit Pixels 1 input_gray_lsb_16bit.mat crap.miff
+don't rotate partial image.</li>
+</ul>
+</blockquote>
+<p>2008-04-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (DestroyMagickInfoList): Use DestroyMagickInfo().
+(UnregisterMagickInfo): Use DestroyMagickInfo().
+(RegisterMagickInfo): Simplify dramatically by adding to the front
+of the list rather than maintaining alpha order.</li>
+<li>magick/image.c (DestroyImageInfo): Tidy up and simplify code.</li>
+<li>magick/constitute.c (WriteImage): Comment out the &quot;bi-modal
+delegate&quot; execution code until we determine what value it offers.
+The test suite passes without it.</li>
+<li>magick/magick.h (struct MagickInfo): There is no need for <cite>name</cite>
+to be allocated data so make it const.
+(DestroyMagickInfo): Add a static function to destroy a MagickInfo
+structure. Renamed previous DestroyMagickInfo to
+DestroyMagickInfoList and made it static.</li>
+</ul>
+</blockquote>
+<p>2008-04-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: GraphicsMagick 1.2 released.
+CVS head is now 1.3 development.</li>
+<li>png: Updated libpng to 1.2.27.</li>
+</ul>
+</blockquote>
+<p>2008-04-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Ignore file extensions which
+match defined virtual delegate entries (including stealth
+entries).</li>
+</ul>
+</blockquote>
+<p>2008-04-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BENCHMARKS.txt: Added timings for -blur.</li>
+</ul>
+</blockquote>
+<p>2008-04-27 Darko Kojic &lt;<a class="reference external" href="mailto:dkc&#37;&#52;&#48;sf&#46;net">dkc<span>&#64;</span>sf<span>&#46;</span>net</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (MedianFilterImage): Fixes to compile on ARM
+CPU.</li>
+</ul>
+</blockquote>
+<p>2008-04-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.h (MagickInfo): Remove image_info member since I
+can not find any purpose for it.</li>
+<li>coders/tiff.c (WriteTIFFImage): Remove assertion check on
+scanline size since it has not caught anything.</li>
+<li>magick/image.c (SetImageInfo): Ensure that the file extension
+does not trigger unwanted activity such as access to an X11
+server, printer, or the launch delegate.</li>
+<li>config/Makefile.am (configshare_DATA): Install colors.mgk in
+share path.</li>
+<li>magick/blob.c (GetConfigureBlob): Search <cite>share</cite> config path
+prior to <cite>lib</cite> config path.</li>
+</ul>
+</blockquote>
+<p>2008-04-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): TrueColor RGB was usually
+written rather than the desired more compact format. This is a
+first pass at fixing that.</li>
+</ul>
+</blockquote>
+<p>2008-04-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>BENCHMARKS.txt: Added a benchmark summary.</li>
+</ul>
+</blockquote>
+<p>2008-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Prepare 1.2beta1 release.</li>
+<li>NEWS.txt: Updated with latest news.</li>
+</ul>
+</blockquote>
+<p>2008-04-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libtool: Update to 1.2965 2008-04-22</li>
+<li>coders/png.c (ReadOneJNGImage): Deal with ReadImage() returning
+a NULL pointer when reading JPEG sub-image.</li>
+</ul>
+</blockquote>
+<p>2008-04-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/channel.c (ExportImageChannel): Added progress monitor
+support.
+(SetImageChannelDepth): Added progress monitor support.
+(ChannelImage): Don't preserve matte channel when extracting
+channel.</li>
+<li>magick/image.c (SetImageOpacity): Avoid integer overflow in Q32
+build. Added progress monitor support.
+(SyncImage): Added progress monitor support.
+(SetImage): Added progress monitor support.
+(CycleColormapImage): Added progress monitor support.
+(GetImageBoundingBox): Added progress monitor support.
+(SortColormapByIntensity): Added progress monitor support.</li>
+</ul>
+</blockquote>
+<p>2008-04-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac, magick/Makefile.am: Don't use libtdl unless we are
+supposed to be using it!</li>
+<li>libtool: Updated to GNU libtool 1.2960 2008-04-19.</li>
+<li>configure.ac, magick/delegate.h: It seems that the modern
+convention is to store ghostscript headers in a subdirectory
+called <cite>ghostscript</cite> rather than <cite>ps</cite>.
+We don't actually need Ghostscript errors.h and that is a good
+thing since it seems that some newer Ghostscript calls it ierrors.h</li>
+</ul>
+</blockquote>
+<p>2008-04-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/files-dlls.isx: Comment out inclusion
+of X11 support DLLs.</li>
+<li>VisualMagick/magick/magick_config.h.in: X11 is no longer in the
+default Windows build.</li>
+</ul>
+</blockquote>
+<p>2008-04-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c: Eliminate various annoying warnings noticed
+under MinGW.</li>
+<li>magick/spinlock.h (_spinlock_release): Use <cite>long</cite> rather than
+<cite>int</cite> in order to eliminate warning under MinGW.</li>
+<li>magick/semaphore.c (spinlock_wait): Use <cite>long</cite> rather than <cite>int</cite>
+in order to eliminate warning under MinGW.</li>
+<li>magick/log.c (LogMagickEventList): Eliminate warning under MinGW.</li>
+<li>magick/compress.h: Clean up interface definitions to use
+magick_uint8_t for unsigned character data.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Don't use GetPixelCachePresent()
+since it is not DLL-exported.</li>
+</ul>
+</blockquote>
+<p>2008-04-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/yuv.c (ReadYUVImage): Report exception info correctly.</li>
+<li>coders/xpm.c (ReadXPMImage): Report exception info correctly.</li>
+<li>coders/xc.c (ReadXCImage): Report exception info correctly.</li>
+<li>coders/tiff.c (ReadTIFFImage): Report exception info correctly.</li>
+<li>coders/null.c (ReadNULLImage): Report exception info correctly.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Report exception info correctly.
+Use of Huffman optimization is now based on available memory
+rather than a hard-coded image size.</li>
+<li>coders/gif.c (ReadGIFImage): Report exception info correctly.</li>
+<li>magick/utility.c (MagickSizeStrToInt64): New function to convert
+a size string with optional units suffix to a 64-bit integer.
+(MagickStrToInt64): New function to convert a string to a 64-bit
+integer, with error checking.</li>
+<li>magick/image.c (SetImage): SetImage now returns error status.</li>
+<li>magick/command.c: Eliminated the long-deprecated -cache resource
+limit option.</li>
+<li>magick/resource.c: Complete re-write of the resource limit
+system. Resource specifications are now absolute except that they
+support a binary metric suffix such as <cite>K</cite> to scale the value.
+Added the <cite>Pixels</cite> limit type to limit the maximum number of
+pixels allowed for each image.</li>
+</ul>
+</blockquote>
+<p>2008-04-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (WriteJPEGImage): Output grayscale images more
+efficiently.</li>
+</ul>
+</blockquote>
+<p>2008-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lcms: Updated lcms to 1.17.</li>
+<li>png: Updated libpng to 1.2.26.</li>
+</ul>
+</blockquote>
+<p>2008-04-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage) Use the low bits of the PNG
+tRNS values instead of scaling them when reducing from 16-bits.</li>
+</ul>
+</blockquote>
+<p>2008-04-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Updated to Autoconf 2.62.</li>
+</ul>
+</blockquote>
+<p>2008-04-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImageCommand): New -create-directories
+option automatically creates subdirectories as needed when
+-output-directory option is used. This is useful when one
+directory tree of files is being mogrified to a new tree.</li>
+</ul>
+</blockquote>
+<p>2008-04-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (MagickCreateDirectoryPath): New function to
+create a directory path. Will be used later.</li>
+<li>configure.ac: Tweaks to produce a successful MinGW cross-compile.</li>
+</ul>
+</blockquote>
+<p>2008-04-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Added a simple sentinel
+assertion to hopefully flush out any remaining cases where
+ExportImagePixelArea() writes past the end of its buffer.</li>
+<li>magick/constitute.c (ExportImagePixelArea): GrayQuantum case for
+DirectClass pixels was sometimes writing a zero byte one past the
+end of the allocated buffer. Thanks to Josue Gomes for reporting
+this bug.</li>
+</ul>
+</blockquote>
+<p>2008-04-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/{pcd.c,pcx.c,pdb.c,pict.c,stegano.c,wpg.c,xcf.c}:
+Warnings reduction.</li>
+<li>magick/{channel.c,image.c,unix_port.c,render.c}: Warnings
+reduction.</li>
+<li>coders/mat.c: Convert C99 comments to C89 comments so code can
+compile with a C89 compiler.</li>
+<li>coders/tiff.c (WriteTIFFImage): Add an assertion to enforce that
+the bytes output to the scanline is no more than the bytes
+allocated for the scanline.</li>
+<li>NEWS.txt: Updated with latest NEWS.</li>
+</ul>
+</blockquote>
+<p>2008-04-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c (WritePDFImage): Default to ZIP compression if
+available. Ignore Image compression setting since the useful
+value (set by the user) usually comes from ImageInfo.</li>
+<li>coders/png.c (WriteOnePNGImage): Fix progress monitor when
+writing PNG.</li>
+<li>magick/channel.c (GetImageChannelDepth): Added progress monitor
+support.</li>
+<li>magick/signature.c (SignatureImage): Added progress monitor support.</li>
+<li>magick/image.c (GetImageDepth): Added progress monitor support.</li>
+</ul>
+</blockquote>
+<p>2008-04-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libtool: Update to libtool 2.2.2.</li>
+<li>coders/jpeg.c: Convert more code to use size_t for sized values
+rather than long.</li>
+<li>coders/wpg.c (InsertRow): Fix log format string specification.</li>
+<li>coders/dpx.c (WriteDPXImage): Fix typo in casts.</li>
+<li>coders/fpx.c (ReadFPXImage): Apply FreeBSD patch from Mikhail
+Teterin to allow FlashPIX to work better for 64-bit builds.
+Addresses SourceForge issue 1824658 &quot;FPX should work again now&quot;.</li>
+<li>magick/blob.c (ImageToBlob): Fix typo in cast.</li>
+</ul>
+</blockquote>
+<p>2008-03-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>CONTRIBUTE.txt: Convert contribute.html to reStucturedText
+format and generate HTML version from it.</li>
+<li>PROCESS.txt: Convert description of development process to
+reStucturedText format and generate HTML version from it.</li>
+<li>INSTALL-windows.txt: Add instructions for how to install from
+setup.exe style installer. Also add instructions for how the
+distribution package is built.</li>
+<li>Copyright.txt: Reformat in reStucturedText format and generate
+HTML version from it.</li>
+<li>VisualMagick/installer/inc/body.isx: No longer include
+development headers and libraries in the Windows DLL install
+package since they are large and they may only work with the
+version of Visual C++ used to perform the build. It is much safer
+for the developer to build the package from source with his own
+compiler.</li>
+</ul>
+</blockquote>
+<p>2008-03-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fix compilation issues with Microsoft Visual Studio.</li>
+</ul>
+</blockquote>
+<p>2008-03-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage, WriteDPXImage): Use lookup tables to
+speed up value conversion.</li>
+<li>magick/memory.h (MagickAllocateArray): Renamed from
+MagickAllocateMemoryElements.</li>
+</ul>
+</blockquote>
+<p>2008-03-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Use memory allocation macros like the rest
+of the code.</li>
+<li>magick/memory.c (MagickMalloc): New function which behaves
+similar to malloc().
+(MagickMallocArray): New function for allocating an array.
+(MagickRealloc): New function which behaves similar to realloc().
+(MagickFree): New function which behaves similar to free().
+(MagickAllocFunctions): New function to allow the user to specify
+the memory allocation functions.</li>
+<li>magick/memory.h: New header file to define memory allocation
+functions.</li>
+<li>magick/deprecate.c (DeleteImageList, DestroyImages,
+GetImageList, GetImageListIndex, GetImageListSize, GetNextImage,
+GetNumberScenes, GetPreviousImage, ParseImageGeometry,
+PopImageList, PostscriptGeometry, PushImageList,
+SetCacheThreshold, SetImageList, ShiftImageList, SizeBlob,
+SpliceImageList, UnshiftImageList): Remove functions which were
+already deprecated in ImageMagick 5.5.2 or earlier.</li>
+</ul>
+</blockquote>
+<p>2008-03-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): Support writing image which is
+already in a YCbCr colorspace.
+(ReadDPXImage): Return YCbCr images in YCbCr colorspace unless
+they are also Cineon log encoded.</li>
+<li>magick/image.c (CloneImage): Use CloneImageAttributes().</li>
+<li>magick/attribute.c (CloneImageAttributes): New function for
+copying image attributes from one image to another.</li>
+<li>magick/utility.c (TranslateTextEx): Check if the pixel cache is
+initialized before using a function which requires using it.
+Thanks to Micha³ Kowalczuk for bringing this issue to my
+attention.</li>
+<li>magick/attribute.c (SetImageAttribute): Only apply
+transformations to &quot;comment&quot; and &quot;label&quot; attributes.</li>
+<li>magick/pixel_cache.c (GetPixelCachePresent): New function to
+test if the image pixel cache is present and initialized.</li>
+</ul>
+</blockquote>
+<p>2008-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colorspace.c (RGBTransformPacket): Rationalize casts for
+improved performance.</li>
+<li>magick/image.c (GetImageDepth): Use table lookups to improve
+performance.</li>
+</ul>
+</blockquote>
+<p>2008-03-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (AllocateImage): Transfer any attributes from
+ImageInfo to allocated image.
+(SetImageDepth): Use table lookups to improve performance.</li>
+</ul>
+</blockquote>
+<p>2008-03-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImageCommand): Added an
+-output-directory option to <cite>mogrify</cite> to send output files to the
+specified directory.</li>
+</ul>
+</blockquote>
+<p>2008-03-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/read.t: Add input_logical_lsb_08bit.mat to
+PerlMagick tests.</li>
+<li>magick/nt_feature.c (CropImageToHBITMAP, ImageToHBITMAP): Use
+GlobalFree() to free bitmap handle.</li>
+</ul>
+</blockquote>
+<p>2008-03-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/read.t: Added/adjusted WPG test files from Jaroslav
+Fojtik.</li>
+</ul>
+</blockquote>
+<p>2008-03-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>AUTHORS.txt, BUGS.txt, FAQ.txt, NEWS.txt, PLATFORMS.txt,
+TODO.txt, INSTALL-unix.txt, INSTALL-windows.txt: Use
+reStructuredText format.</li>
+<li>Makefile.am: Use reStructuredText for more files.</li>
+</ul>
+</blockquote>
+<p>2008-02-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ReadImage): Disable colorspace override
+code since it was being wrongly-triggered in X11 display commands.</li>
+</ul>
+</blockquote>
+<p>2008-02-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/body.html: Update to mention 1.1.11 release.</li>
+</ul>
+</blockquote>
+<p>2008-02-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colorspace.c (RndToInt): Cast result to <cite>unsigned int</cite>
+rather than <cite>int</cite> in order to avoid possible value truncation with
+Q32 build. Problem was reported by Kai-Uwe Behrmann.
+(TransformRGBImage): Fix loop iterator which was looping one past
+the end of the array. Reported by Kai-Uwe Behrmann.</li>
+<li>magick/command.c: Added a -set option to the composite, convert,
+display, mogrify, import commands in order to allow setting an
+image attribute.</li>
+</ul>
+</blockquote>
+<p>2008-02-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Use MagickAcquireMemory() rather than
+AquireMemory().</li>
+<li>coders/xwd.c (ReadXWDImage): Eliminate integer overflow
+vulnerability (IDefense 09.19.07).</li>
+<li>coders/xbm.c (ReadXBMImage): ditto</li>
+<li>coders/xcf.c (ReadXCFImage): ditto</li>
+<li>coders/dib.c (ReadDIBImage): ditto</li>
+<li>coders/dcm.c (ReadDCMImage): ditto</li>
+</ul>
+</blockquote>
+<p>2008-02-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): The <a class="reference external" href="http://tools.ietf.org/html/rfc3949.html">RFC 3949</a> specification for
+Internet FAX recommends LSB2MSB fill order so document that.</li>
+</ul>
+</blockquote>
+<p>2008-02-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Use <cite>-define
+tiff:fill-order={msb2lsb|lsb2msb}</cite> to control TIFF bit fill order.</li>
+</ul>
+</blockquote>
+<p>2008-02-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Updated to latest CVS libtool.</li>
+<li>coders/tiff.c (CompressionSupported): Use
+TIFFGetConfiguredCODECs() to test if a requested compression type
+is supported by libtiff. Based on advice from Frank Warmerdam.</li>
+<li>configure.ac: Add test for TIFFGetConfiguredCODECs() in libtiff.</li>
+</ul>
+</blockquote>
+<p>2008-02-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c: With libtiff 3.6.1, including tiff.h and tiffio.h
+is not sufficient to obtain the definitions from tiffconf.h so
+libtiff is assumed to not support any features, such as
+compression. Avoid this problem by explicitly including
+tiffconf.h if it is found. This resolves SourceForge issue
+[1883527] compression of tiff-file has no effect.</li>
+</ul>
+</blockquote>
+<p>2008-02-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/setup.isx: Set Inno Setup installer
+compression to &quot;lzma/max&quot;.</li>
+<li>PerlMagick/Magick.xs: Eliminate use of memory allocation macros
+since these failed miserably under Windows where it seems that
+malloc, free, and realloc are redefined via macros by the Perl
+build environment. This reverts changes made on 2007-12-01.</li>
+<li>magick/memory.c (MagickAcquireMemoryArray): Use implementation
+from the 1.1 branch.</li>
+<li>magick/utility.h: Remove MagickSafeMultiplySize_t since it seems
+that use of inline functions in Windows is a disaster area.</li>
+</ul>
+</blockquote>
+<p>2008-02-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (windows-dist): Create a 7z compressed Windows
+comprehensive source package. See <a class="reference external" href="http://www.7-zip.org/">http://www.7-zip.org/</a> for
+information on Windows 7-Zip and <a class="reference external" href="http://p7zip.sourceforge.net/">http://p7zip.sourceforge.net/</a> for
+information on portable 7-Zip (P7ZIP).</li>
+</ul>
+</blockquote>
+<p>2008-02-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Add logging for image resolution
+and resolution units.</li>
+<li>magick/version.h.in: Update copyright year to 2008.</li>
+</ul>
+</blockquote>
+<p>2008-02-01 Gary V. Vaughan &lt;<a class="reference external" href="mailto:gary&#37;&#52;&#48;gnu&#46;org">gary<span>&#64;</span>gnu<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Updated for libtool-2.1b.</li>
+<li>bootstrap (libtoolize): Libtoolize can figure out the mode and
+directory for libltdl from configure.ac.</li>
+</ul>
+</blockquote>
+<p>2008-01-28 Ralf Wildenhues &lt;<a class="reference external" href="mailto:Ralf&#46;Wildenhues&#37;&#52;&#48;gmx&#46;de">Ralf<span>&#46;</span>Wildenhues<span>&#64;</span>gmx<span>&#46;</span>de</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/Makefile.am: Update
+magick_libGraphicsMagick_la_DEPENDENCIES to use LTDLDEPS.</li>
+</ul>
+</blockquote>
+<p>2008-01-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Successfully read existing file
+names in the form file[123] which were failing to read since they
+appear to be a valid sub-image specification.</li>
+</ul>
+</blockquote>
+<p>2008-01-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (ExpandFilenames): If a filename appears to
+contain a wildcard specification, first check to see if there is
+file matching the unexpanded wildcard prior to engaging in the
+slow task of wildcard expansion. Without this fix, expanding the
+command line takes a very long time if there are a huge number of
+files in the directory, and some file names appear to contain
+wildcard specifications. Inspired by SourceForge bug reports [
+1878992 ] &quot;literal square brackets in file name cause large delay&quot;
+and [ 1783209 ] &quot;converting runs slowly when subimage is
+specified&quot;, but this might not be the complete fix for the
+problem.</li>
+</ul>
+</blockquote>
+<p>2008-01-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Update to Automake 1.10.1 and enable generation of
+an lzma compressed source package.</li>
+</ul>
+</blockquote>
+<p>2008-01-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Added configure option --with-umem to enable use
+of the umem memory allocation library available in Solaris 9,
+Update 3 and later, or from
+<a class="reference external" href="https://labs.omniti.com/trac/portableumem/">https://labs.omniti.com/trac/portableumem/</a>. This library supports
+concurrency in multi-threaded programs and supports debugging
+memory issues. See
+<a class="reference external" href="http://developers.sun.com/solaris/articles/libumem_library.html">http://developers.sun.com/solaris/articles/libumem_library.html</a>
+for a description of how to use the library for debugging memory
+issues.</li>
+</ul>
+</blockquote>
+<p>2008-01-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (VersionCommand): Include a &quot;Large Memory&quot; item
+in the Feature Support list.</li>
+<li>coders/png.c (RegisterPNGImage): Remove reference to dead PNG
+ftp site.</li>
+<li>VisualMagick/configure/configure.cpp (InitInstance): Remove
+project dependency on dxguid.lib (Direct-X).</li>
+</ul>
+</blockquote>
+<p>2008-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Update libtool to latest CVS version.</li>
+</ul>
+</blockquote>
+<p>2008-01-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (DisplayImageCommand): No longer default to
+reading standard input if stdin fails isatty() test. This
+behavior was causing failure to launch from Gnome and it is
+difficult to work around the issue from within a .desktop file.
+(AnimateImageCommand): No longer default to
+reading standard input if stdin fails isatty() test.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2008.rst b/www/ChangeLog-2008.rst
new file mode 100644
index 0000000..6d6b0b1
--- /dev/null
+++ b/www/ChangeLog-2008.rst
@@ -0,0 +1,2127 @@
+2008-12-28 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c: Ability to read extension blocks.
+
+ - coders/fits.c: Fixed MaxTextExtent limitation of blocks.
+
+2008-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/OpenMP.rst: Add results for Window Vista 64-bit / AMD Phenom
+ X4 9550.
+
+ - VisualMagick/installer/inc/body.isx: Revert yesterday's change
+ regarding the placement of config files. Place the config files
+ in a `config` subdirectory just as before.
+
+2008-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/body.isx: They say that when in Rome
+ you should do as the Roman's do. Based on this philosophy, all of
+ the coder and filter DLLs are now installed to the same directory
+ as the executables and DLLs which depend on them. This eases
+ operation under Windows Vista.
+
+2008-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c: First pass at supporting large file access under
+ Windows.
+
+2008-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (InitializeMagickResources): Improve resource
+ estimation for Microsoft Windows systems with large memory.
+
+ - magick/segment.c: Added some code to dump histograms with
+ `-verbose -verbose`.
+
+ - coders/tiff.c: Support reading/writing 16 and 24 bit float TIFF
+ files.
+
+ - magick/constitute.c (ExportViewPixelArea): Support exporting 16
+ and 24 bit short floats. Relies on code developed for
+ GraphicsMagick by Richard Nolde.
+ (ImportViewPixelArea): Support importing 16 and 24 bit short
+ floats. Relies on code developed for GraphicsMagick by Richard
+ Nolde.
+
+2008-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/operator.h (enum QuantumOperator): Added LogQuantumOp,
+ MaxQuantumOp, MinQuantumOp, and PowQuantumOp enumerations as well
+ as "Log", "Max", "Min", and "Pow" options to -operator.
+
+2008-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): The -write option was not
+ implemented in a useful fashion and the +write option never worked
+ at all. Re-implement -write and eliminate +write from the
+ documentation since +write is not needed.
+
+2008-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage, WriteTIFFImage) Support reading
+ and writing 64-bit integer TIFF.
+
+ - magick/constitute.c (ImportViewPixelArea): Add support for
+ importing 64-bit integer values.
+ (ImportViewPixelArea): Add support for exporting 64-bit integer
+ values.
+
+2008-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Fix bug with reading one bit per
+ sample RGB images.
+
+2008-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (OpenCache): Fix a code ordering problem
+ which results in `identify` throwing an assertion for PseudoClass
+ image files. This bug was added in the 1.3.2 release.
+
+ - coders/tiff.c (ReadTIFFImage): Fix bug with `ping` mode.
+
+2008-12-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c: Proper signed to unsigned conversion for 64 bit LSB images.
+
+2008-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/Makefile.am: When X11 is disabled, don't compile the
+ X11-specific source modules. Don't ever install any X11-related
+ header files.
+
+2008-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/segment.c (SegmentImage): Use `double` rather than 64-bit
+ integer to accumulate totalized values. Make the cluster summary
+ report more concise.
+
+2008-12-06 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c: Fix for 64 bit images.
+
+2008-12-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/segment.c (SegmentImage): Cluster threshold is expressed
+ as a percentage of total cluster pixels. Optimize for larger
+ images.
+
+2008-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/segment.c (SegmentImage): Accelerate using OpenMP.
+
+2008-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (ExpandFilenames): Remove some arbitrary
+ argument length limits. Pass -convolve argument without any
+ additional checking. Verify that strings are not truncated during
+ copy.
+ (ListFiles): Be more memory efficient.
+
+ - magick/fx.c (ConvolveImage): Fix formatting problem when logging
+ the convolution kernel used.
+
+ - magick/utility.c (TranslateTextEx): Support formatting huge
+ comment text.
+
+2008-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/fx.c (ConvolveImage): Don`t process opacity channel
+ unless image has one.
+
+ - magick/effect.c (MotionBlurImage): Use
+ AcquireOnePixelByReference() rather than AcquireImagePixels() to
+ retrieve one pixel. This is much more efficient.
+ (AdaptiveThresholdImage): Don`t process opacity channel unless
+ image has one.
+ (BlurImage): Don`t process opacity channel unless image has one.
+
+2008-11-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/profile.c (ProfileImage): +profile now supports a simple
+ exclusion syntax. For example, to strip all of the profiles
+ except for the ICM profile use +profile '!icm,\*'. The new syntax
+ also allows multiple profile names to be listed at once. The
+ primary requirement is that all excluded profiles must be listed
+ prior to those to be stripped.
+
+2008-11-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/transform.c (RollImage): Remove image storage class
+ alteration.
+ (CompositeImageRegion): Ensure that the canvas image storage class
+ is correct.
+
+2008-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - config/delegates.mgk.in: Since we removed support for `spawn` a
+ long time ago, and no longer execute using the Unix shell by
+ default, we need to add an ampersand to the end of the two entries
+ previously using `spawn` so that the display program does not hang
+ when it invokes the external program.
+
+ - utilities/Makefile.am (UTILITIES\_TESTS): Add preview-based
+ tests.
+
+ - coders/preview.c (WritePreviewImage): Solarize requires a
+ threshold argument.
+
+ - coders/vid.c (WriteVIDImage): Eliminate memory leak.
+
+ - magick/montage.c (MontageImages): Fix continued use of freed
+ memory.
+
+2008-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/omp\_data\_view.c (AccessThreadViewDataById): New function
+ to allow retrieving data via the index it was registered with.
+
+ - magick/enhance.c (BuildChannelHistograms): EnhanceImage() and
+ NormalizeImage() now share one common function for generating the
+ histogram.
+
+ - magick/enhance.c (ModulateImage): Improve performance a bit.
+ (ContrastImage): Improve performance a bit.
+ (GammaImage): Improve performance a bit.
+
+2008-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/authors.rst: List Mark Mitchell as an author.
+
+ - utilities/tests/msl\_composite.sh: Fix `rm -f` without a valid
+ argument which annoyed NetBSD.
+
+ - coders/fits.c: Impose a limit on the length of the row PDU.
+ Make sure that GraphicsMagick version information does not
+ overflow the length allowed by a row PDU.
+
+2008-11-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (WriteJPEGImage): Use DCT algorithm default from
+ the library rather than the header file.
+
+ - magick: Adjust OpenMP scheduling options based on observed
+ behavior.
+
+2008-11-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c (IntegralRotateImage): Added OpenMP acceleration
+ for rotate by 90 and 270 degrees.
+
+ - configure.ac: New --disable-openmp-slow configure for disabling
+ use of OpenMP for algorithms which may run slower on operating
+ systems with crummy thread libraries. This still allows gaining
+ the benefits from OpenMP for CPU hogs. Verified to help with
+ FreeBSD 7.0 and Apple OS-X Leopard.
+
+ - magick/semaphore.c: Trimmed out the debug code in order to
+ obtain a bit more performance.
+
+2008-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c: Allow the user to specify the DCT method
+ (jpeg:dct-method), or if huffman encoding should be enabled
+ (jpeg:optimize-coding=true). Default the DCT method to the
+ libjpeg default rather than forcing it to JDCT\_FLOAT since float
+ is slower on some systems.
+
+2008-11-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (BlobClose): Leak a little bit less memory when
+ reading a JP2 file.
+
+2008-11-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/wandtest.c: Eliminate memory leak.
+
+ - wand/drawing\_wand.c (DestroyDrawingWand): Eliminate memory
+ leaks.
+
+ - coders/xwd.c (WriteXWDImage): Force colormapped images with more
+ than 256 colors to DirectClass.
+
+ - magick/enhance.c (ModulateImage): Improve progress message.
+
+ - coders/msl.c: Eliminate memory leaks.
+
+ - GraphicsMagick.spec.in: Apply RPM spec file fixes from Giacomo
+ Tenaglia for Red Hat Linux 4.
+
+2008-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/msl.c: Fix bug with attributes becoming appended to
+ themselves. Resolves SF issue 2255754. Reflowed code.
+
+2008-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: GraphicsMagick 1.3 released.
+ Next release on head will be 1.4.
+
+ - www/OpenMP.rst: Updated with latest measurement data.
+
+ - www/benchmarks.rst: Updated with latest benchmark data.
+
+ - coders/url.c (RegisterURLImage): Register HTTP and FTP URL
+ support in the "unstable" category since these are capable of
+ accessing the network and therefore represent a potential security
+ issue. Register the FILE URL support in the "stable" category
+ since it is capable of incorporating local disk files, which may
+ still represent a security security issue for server applications.
+ Note that disabling these functions might cause some existing MSL,
+ MVG and SVG scripts to stop working if they use external URLs.
+
+2008-11-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (ReadPNMImage): Sequential multi-thread the PNM raw
+ format readers. Can improve read performance quite substantially
+ for large PBM and PGM files, and less so for PPM. There is most
+ benefit for systems with more I/O than one CPU core will support.
+ Systems with slow I/O and a relatively fast CPU may see somewhat
+ diminished read performance with more CPU consumption. As such,
+ this is effectively a verification that multi-threading the reader
+ is possible, and may be of benefit to power-users.
+
+ - magick/omp\_data\_view.c (AllocateThreadViewDataArray): New
+ function to allocate a thread view data array. Updated modules
+ using similar code to use this function in order eliminate
+ useless redundancy.
+
+2008-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c: Incorporate OMP thread views into the
+ pixel cache so usage is less invasive. Update OMP-enhanced source
+ modules to suit.
+ (GetImagePixelsEx): New function similar to GetImagePixels()
+ except that it reports exceptions to a user-provided structure.
+ (SetImagePixelsEx): New function similar to SetImagePixels()
+ except that it reports exceptions to a user-provided structure.
+ (SyncImagePixelsEx): New function similar to SyncImagePixels()
+ except that it reports exceptions to a user-provided structure.
+ (AccessImmutableIndexes): New function to access read-only
+ colormap indexes.
+ (AccessMutableIndexes): New function to access writeable colormap
+ indexes.
+ (AccessMutablePixels): New function to access writeable pixels.
+ (AccessDefaultCacheView): New function to access the default cache
+ view.
+
+2008-11-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (BenchmarkImageCommand): With no other
+ arguments, the benchmark command now defaults to one iteration.
+
+ - magick/effect.c (SpreadImage): Offsets array size is a prime
+ number to help avoid beating.
+ (SpreadImage): Ensure that spread loops are always terminal.
+
+ - magick/utility.c (MagickRandReentrant): Fix bug where rand() was
+ being continually re-seeded if rand\_r() was not available.
+
+2008-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/tests/msl\_composite.sh: Replace SVG image generation
+ with simpler approach which properly centers the text. Use our
+ own font so that tests will pass if the user does not have fonts
+ installed.
+
+ - magick/utility.c (GetMagickDimension): Extend to support parsing
+ optional x and y offset values and use to fix parsing for
+ -oil-paint and -unsharp when sscanf() is C'99 compliant.
+
+2008-11-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.h (AcquireOneCacheViewPixel): Pass pixel to
+ update by reference.
+ (AcquireOnePixelByReference): New private inline method which
+ passes pixel to update by reference.
+
+ - magick/omp\_thread\_view.h (AcquireOneThreadViewPixel): Pass pixel
+ to update by reference.
+
+ - magick/alpha\_composite.h (BlendCompositePixel): Replace
+ BlendComposite with BlendCompositePixel, which passes the
+ composite pixel by reference.
+ (AlphaCompositePixel): Replace AlphaComposite with
+ AlphaCompositePixel, which passes the composite pixel by
+ reference.
+ (AtopCompositePixel): Replace AtopComposite with
+ AtopCompositePixel, which passes the composite pixel by reference.
+
+ - configure.ac: With excessive maintenance releases, the library
+ age portion of MAGICK\_LIB\_VERSION was overflowing its allotted
+ space. This resulted in 1.1.X releases reporting the wrong
+ MagickLibVersion as of 1.1.10. Fix this by supporting up to 99
+ values for each field.
+
+2008-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Fix passing the --with-windows-font-dir option via
+ DISTCHECK\_CONFIG\_FLAGS.
+
+ - utilities/tests/msl\_composite.sh: Integrated MSL composition
+ test script contributed by Max Hohenegger, Max at hohenegger.eu.
+
+ - magick/command.c (ConjureImageCommand): Return status was
+ inverted so one was returned for command success rather than zero.
+
+2008-11-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Updated libpng to 1.2.33 release.
+
+ - magick/color.c (FuzzyColorMatch): If fuzz is zero then
+ completely use the result of ColorMatch() rather than entering
+ unnecessary expensive code.
+
+2008-10-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h: Make sure we don't conflict with OpenMP
+ implementation if it is active but we are not using it.
+
+2008-10-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h (HAVE\_OPENMP): Add logic to make sure that
+ OpenMP is only engaged for OpenMP 2.0 or later.
+
+ - magick/command.c (VersionCommand): Report OpenMP version.
+
+ - Makefile.am: The Magick++ build was supposed to be optional. Now
+ it is.
+
+ - Makefile.am: Eliminated .tar.bz2 and .zip packages from the
+ distribution. The .tar.bz2 package was hardly smaller than the
+ .tar.gz package so it wasted 5.9MB with little benefit. The
+ compression ratio on the .zip archives is absolutely terrible so
+ eliminating zip eliminates huge 9.6MB and 25MB files from the
+ distribution equation. Windows users can easily learn how to use
+ the vastly more efficient 7-Zip format.
+
+2008-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Rationalize OpenMP tests to make sure that OpenMP
+ can not be enabled without thread support.
+
+2008-10-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c (CompositeImageRegion): Add some minimal
+ region limit checking. Not completed yet.
+
+ - magick/transform.c (RollImage): Accellerate using OpenMP.
+
+2008-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h (omp\_get\_thread\_num): Remove spurious trailing
+ `;`.
+
+ - magick/render.c (DrawPrimitive): Make method private since
+ nothing else is using it.
+
+ - magick/omp\_thread\_view.h (AccessThreadView): Inline function for
+ a bit more performance.
+ (AcquireOneThreadViewPixel) Inline function for a bit more
+ performance.
+
+2008-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - pragma omp parallel for: Use consistent static scheduling
+ throughout and ensure that 64 threads can be usefully engaged on a
+ 1024 row image.
+
+ - magick/pixel\_iterator.c (SetRegionThreads): Implement logic so
+ that pixel iterators execute single-threaded when invoked on tiny
+ regions.
+
+ - magick/pixel\_cache.c (SetNexus): Make staging buffer memset()
+ conditional in order to dramatically diminish impact to small
+ accesses. This memset() only exists to make valgrind happy.
+
+2008-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Fix progress monitor for the case
+ of reading planar stripped images.
+
+2008-10-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (DespeckleImage): Accelerate using OpenMP.
+
+ - magick/paint.c (OpaqueImage): Update to use pixel iterators.
+ (TransparentImage): Update to use pixel iterators.
+
+ - magick/decorate.c (FrameImage): Accelerate using OpenMP.
+ (RaiseImage): Accelerate using OpenMP.
+
+2008-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c (CompositeImageRegion): Start of new function
+ to act as a lighter-weight yet more flexible image composition
+ interface.
+
+ - magick/transform.c (ChopImage): Accelerate using OpenMP.
+ (CropImage): Accelerate using OpenMP.
+ (FlipImage): Accelerate using OpenMP.
+ (FlopImage): Accelerate using OpenMP.
+
+ - magick/effect.c (ThresholdImage): Accelerate using OpenMP.
+
+2008-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (AcquireOneCacheViewPixel): Optimize
+ implementation.
+
+ - magick/effect.c (MedianFilterImage): Accelerate using OpenMP.
+ (ReduceNoiseImage): Accelerate using OpenMP.
+
+2008-10-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/fx.c (WaveImage): Accelerate using OpenMP.
+ (SwirlImage): Accelerate using OpenMP.
+ (ImplodeImage): Accelerate using OpenMP.
+
+2008-10-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (GetCacheViewRegion): New function to
+ return the region bounded by a pixel cache view.
+
+ - magick/constitute.c (ExportViewPixelArea): New function to
+ support exporting the pixels from a pixel cache view.
+ (ImportViewPixelArea): New function to support importing pixels
+ to a pixel cache view.
+
+ - magick/pixel\_cache.c (ReadStream): Eliminated function.
+ (WriteStream): Eliminated function.
+ (ClonePixelCacheMethods): Eliminated function.
+
+ - magick/image.h: Eliminated StreamHandler call-back type.
+ Eliminated ImageInfo stream member.
+
+ - magick/pixel\_cache.c (GetCacheViewArea): New function to return
+ the area of a cache view.
+ (AccessCacheViewPixels): New function to access already selected
+ cache view pixels.
+
+2008-10-19 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c: Remove unused exponential data.
+
+2008-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/omp\_thread\_view.c: Move OMP Thread View functions out of
+ pixel cache module and put them in this new module.
+
+ - coders/xtrn.c (ReadXTRNImage): XTRNSTREAM mode was never
+ implemented so remove unfinished stub code.
+
+2008-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageDepth): Needed to assign image depth
+ attribute to user-specified depth rather than only altering the
+ pixels.
+ (SetImageOpacity): Reimplement using pixel iterators.
+ (AverageImages): Accelerate using OpenMP.
+ (GetImageBoundingBox): Accelerate using OpenMP.
+
+2008-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ConstituteTextureImage): Accelerate using
+ OpenMP.
+
+ - magick/image.c (TextureImage): Accelerate using OpenMP.
+
+ - magick/render.c (DrawAffineImage): Accelerate using OpenMP.
+
+2008-10-13 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c Fixed palette problem for >8 bit images.
+
+2008-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): Using +page now resets image
+ page offsets as documented for convert and mogrify.
+
+2008-10-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (GradientImage): Re-do OpenMP accelleration based
+ on new pixel cache interface for better performance.
+
+ - coders/dpx.c (ReadDPXImage): Progress monitor needs to tick when
+ row count is updated.
+
+ - coders/fits.c (ReadFITSImage): Update to use
+ MagickFindRawImageMinMax().
+ (WriteFITSImage): Expand buffer size to MaxTextExtent. Include
+ GraphicsMagick version in FITS header.
+
+ - coders/mat.c (ReadMATImage): Update to use
+ MagickFindRawImageMinMax().
+
+ - magick/constitute.c (MagickFindRawImageMinMax): New internal
+ function to assist with finding the minimum and maximum data of
+ raw image files.
+
+2008-10-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (AcquireThreadViewPixels): Convert thread
+ set view convenience methods into library methods because the
+ inline methods were causing the Sun Studio compiler to produce
+ thread unsafe code. Due to likely beneficial inlining in the
+ library, this is not expected to cause any performance impact.
+
+2008-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/filter.t: Add a test for UnsharpMask.
+
+ - magick/effect.c (UnsharpMaskImage): Use Blur rather than
+ GaussianBlur to create blur image since it is faster.
+
+ - magick/pixel\_cache.c (AllocateThreadViewDataSet): Add a
+ destructor function in case data should not be destroyed, or needs
+ something other than MagickFree().
+ (AllocateThreadViewDataSet): Use user-provided destructor to free
+ user data.
+
+ - scripts/format\_c\_api\_doc.py: Improvements from Mark Mitchell to
+ perform keyword/target substitions and wrap function prototypes.
+
+ - coders/dpx.c (ReadDPXImage): Accellerate reader using OpenMP.
+
+2008-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/api/types.rst: Convert types.html to reStructured text
+ format.
+
+2008-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/monitor.c (MagickMonitorFormatted): New method to support
+ issuing a formatted progress monitor message. Use it throughout
+ so that file name is included in progress indication.
+
+2008-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Bootstrap with autoconf 2.63. Require autoconf
+ 2.62 to bootstrap.
+
+2008-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www: Adopted improved web page design by Mark Mitchell.
+
+2008-10-04 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c coders/mat.c Used a same piece of code to calculate
+ min and max data value.
+
+2008-09-30 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c Fixed 16 bit fits writer that wrote wrongly
+ shaped unsigned ints.
+
+2008-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/conjure.imdoc: Applied patches from Max at hohenegger.eu to
+ mention previously undocumented elements and to provide a
+ composition example.
+
+2008-09-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c (IntegralRotateImage): Accelerate rotation by 0
+ and 180 degrees using OpenMP.
+ (XShearImage): Accellerate using OpenMP (accellerates -rotate and
+ -shear).
+ (YShearImage): Accellerate using OpenMP (accellerates -rotate and
+ -shear).
+
+2008-09-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (MotionBlurImage): Enable OpenMP now that pixel
+ cache is re-entrant.
+
+ - magick/pixel\_iterator.c: Updated to use thread view convenience
+ inline methods as proof of principle.
+
+ - magick/pixel\_cache.h: Added convenience inline methods to make
+ use of thread views a bit more pleasant.
+
+2008-09-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ShadeImage): Fix valgrind gripe.
+ (MedianFilterImage): Fix valgrind gripe.
+
+2008-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c: Pixel cache is believed to be thread safe
+ now.
+
+ - magick/deprecate.c (AcquireCacheView): Deprecate this function.
+ (GetCacheView): Deprecate this function.
+ (SetCacheView): Deprecate this function.
+ (SyncCacheView): Deprecate this function.
+
+ - magick/pixel\_cache.c (AcquireCacheViewPixels): New function to
+ replace AcquireCacheView().
+ (GetCacheViewPixels): New function to replace GetCacheView().
+ (SetCacheViewPixels): New function to replace SetCacheView().
+ (SyncCacheViewPixels): New function to replace SyncCacheView().
+
+ - coders/msl.c: Applied patches from Max at hohenegger.eu which
+ fix a MSL parsing error related to gamma, and erroneous text
+ comments which claim that elements can't have attributes.
+
+2008-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resize.c (ResizeImage): Move OpenMP instrumentation to
+ outer loop so that eventually there can be more performance.
+
+2008-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resize.c (MinifyImage): Accelerate using OpenMP.
+
+ - magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+ Accept -gaussian-blur as a synonym for -gaussian.
+ (ConvertImageCommand, MogrifyImageCommand): Provide access to
+ MinifyImage() via -minify.
+ (ConvertImageCommand, MogrifyImageCommand): Provide access to
+ Magnifyimage() via -magnify.
+
+2008-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/channel.c (ImportImageChannelsMasked): New function to
+ import all the channels from an image except for the channels
+ specified.
+
+ - magick/effect.c (AddNoiseImageChannel): New function to add
+ noise to an image channel.
+ (BlurImageChannel): New function to blur one image channel.
+ (GaussianBlurImageChannel): New function to gaussian blur an image
+ channel.
+ (UnsharpMaskImageChannel): New function to unsharpmask an image
+ channel.
+ (SharpenImageChannel): New function to sharpen an image channel.
+
+2008-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (MotionBlurImage): Use GetOptimalKernelWidth1D()
+ to estimate a reasonable convolution kernel size. Prepare code
+ for OpenMP but don't enable OpenMP until it runs faster.
+ (AddNoiseImageChannel): New function to apply noise to a specified
+ image channel.
+
+2008-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ConvertImageCommand): Provide `convert` access
+ to MotionBlurImage() via -motion-blur option.
+ (MogrifyImageCommand): Provide `mogrify` access to
+ MotionBlurImage() via -motion-blur option.
+
+2008-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (SpreadImage): Accelerate using OpenMP.
+
+ - coders/msl.c: Applied MSL patch from graphicsmagick-bugs list to
+ correct handling of geometry x,y values by setting gravity
+ attribute to ForgetGravity.
+
+2008-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ShadeImage): Accelerate using OpenMP.
+
+2008-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (RandomChannelThresholdImage): Accelerate using
+ OpenMP. Support individual thresholding of the color channels.
+ (BlurImage): Blur was failing for PseudoClass images. This bug
+ was added on 2008-09-08.
+
+ - magick/pixel\_cache.c (AcquireOneCacheViewPixel): New function to
+ return just one pixel from a cache view.
+
+2008-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (EnhanceImage): Accelerate using OpenMP.
+ (BlurImageScanlines): Added optimizations.
+
+ - magick/shear.c (IntegralRotateImage): Add missing progress
+ indication for 90 and 270 degrees rotation.
+
+ - www/perl.html: Fix formatting of examples. Should address
+ SourceForge issue [ 2100339 ] "Wrong format in example script on
+ web page".
+
+2008-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (BlurImage): Accelerate using OpenMP.
+
+2008-09-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/fx.c (ColorizeImage): Re-implement using pixel iterators.
+ (MorphImages): Re-implement using pixel iterators.
+ (OilPaintImage): Accelerate using OpenMP.
+ (SolarizeImage): Re-implement using pixel iterators.
+
+2008-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/fx.c (ConvolveImage): Accelerate using OpenMP.
+
+ - magick/effect.c (AdaptiveThresholdImage): Accelerate using OpenMP.
+
+2008-09-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c: Exhuastive study of the pixel cache code
+ reveals that it is inscrutable and not implemented in a fashion
+ which enables useful multi-threading. Therefore, the cache view
+ interfaces are now made OpenMP-safe via a global critical section.
+
+2008-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_iterator.c: Reduce use of critical sections around
+ pixel cache to the bare minimum based on analysis and testing.
+ Unfortunately, testing shows that the pixel cache views are still
+ not 100% thread safe so the extra locking is still required.
+
+ - magick/pixel\_cache.c (ModifyCache): Make implementation thread
+ safe. This required removing a thread-unsafe optimization from
+ Bill Radcliffe.
+
+ - magick/command.c (BenchmarkImageCommand): Restore original
+ client name for each loop so that it is not extended further for
+ each iteration.
+
+ - magick/semaphore.c (UnlockSemaphoreInfo): Decrement lock depth
+ under protection of the lock.
+
+2008-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (AddNoiseImagePixels): Update to pass per-thread
+ `seed` value for more performance.
+
+2008-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/gem.c (GenerateDifferentialNoise): Use
+ MagickRandReentrant(). Added a `seed` argument so that we can pass
+ a per-thread `seed` value.
+
+ - magick/utility.c (MagickRandNewSeed): New function to produce a
+ semi-random `seed` value.
+ (MagickRandReentrant): New function which works like rand() but
+ attempts to be re-entrant if possible by allowing a seed value to
+ be passed.
+
+2008-08-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/channel.c (SetImageChannelDepth): Re-implement using
+ QuantumOperatorImage().
+
+ - magick/image.c (SetImageDepth): Re-implement using
+ QuantumOperatorImage().
+
+ - magick/operator.h (QuantumOperator): Added DepthQuantumOp for
+ setting the channel depth.
+
+ - magick/command.c (BenchmarkImageCommand): Add CPU-based
+ iteration rate metric to benchmark output.
+
+ - magick/resource.c (ListMagickResourceInfo): Include quantum
+ depth, bits per pixel, and process address size in resource
+ output so that output is more complete.
+
+2008-08-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SyncImage): Re-implement using pixel iterators.
+ (SortColormapByIntensity): Re-implement using pixel iterators.
+ (ClipPathImage): Re-implement using pixel iterators.
+ (CycleColormapImage): Re-implement using pixel iterators.
+ (GetImageDepth): Re-implement using pixel iterators.
+ (GradientImage): Parallize inner loop for speedup with larger
+ images.
+ (ReplaceImageColormap): Re-implement using pixel iterators.
+ (SetImage): Re-implement using pixel iterators.
+
+2008-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/operator.c (QuantumGamma): Removed unnecessary OpenMP
+ request on inner loops.
+
+ - magick/enhance.c (EqualizeImage,NormalizeImage): Execute
+ histogram generation pixel iterator with just one thread to
+ decrease contention for the histogram array.
+
+ - magick/pixel\_iterator.c (InitializePixelIteratorOptions): New
+ function to initialize PixelIteratorOptions with defaults.
+
+ - magick/pixel\_iterator.h (PixelIteratorOptions): New structure to
+ support passing pixel iterator execution options.
+
+2008-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated for changes to date in 1.3 development code.
+
+ - magick/pixel\_iterator.c: Execute pixel iterators in parallel via
+ OpenMP.
+
+ - magick/pixel\_cache.c (OpenCacheView): Ensure that pixel cache is
+ open.
+ (GetCacheInfo): Allocate semaphore immediately.
+
+2008-08-16 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c Writer now creates valid images according to
+ http://fits.gsfc.nasa.gov/fits\_verify.html
+ Fixed problems: 1) zeros in HDU, 2) wrong padding. 3) possible
+ strlen() overflow.
+
+2008-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/{compare.c, channel.c, enhance.c, image.c, operator.c}:
+ Update existing pixel iterator callback functions so that they are
+ OpenMP safe.
+
+2008-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/compare.c (InitializeDifferenceImageOptions): Renamed
+ from DifferenceImageOptionsDefaults().
+ (InitializeDifferenceStatistics): New function to initialize
+ DifferenceStatistics.
+ (ComputeAbsoluteError, ComputePeakAbsoluteError,
+ ComputeSquaredError): Use local totalizing structure on stack and
+ update cumulative statistics when the loop terminates.
+
+2008-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www: Convert HTML pages to use a vibrant green theme rather than
+ colors stolen from old GIMP web site.
+
+2008-08-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/{compare.imdoc, options.imdoc}: Added documentation for
+ `compare`.
+
+ - magick/compare.h (enum HighlightStyle): Added
+ AssignHighlightStyle for simple color assignment. `Annotate` is
+ now `Tint`.
+
+ - magick/command.c (CompareImageCommand): Useful options are now
+ -metric, -highlight-color, and -hightlight-style.
+
+2008-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/compare.c (DifferenceImagePixels): Fixed `Annotate`
+ difference annotation algorithm. Added `Threshold` and `Xor`
+ difference annotation algorithms.
+ (GetImageChannelDifference): New function for computing
+ statistical image error using various metrics. Inspired by
+ `imgcmp` from Jasper.
+ (GetImageChannelDistortion): New function for obtaining
+ statistical image error using various metrics for a specified
+ image channel. Signature is compatible with similar ImageMagick
+ function.
+ (GetImageDistortion): New function for obtaining statistical image
+ error using various metrics for all the active channels in the
+ image. Signature is compatible with similar ImageMagick function.
+
+ - magick/command.c (CompareImageCommand): Added a `compare`
+ subcommand which compares two images using various metrics, and/or
+ generates a difference image using various difference annotation
+ algorithms. Documentation not yet updated.
+
+2008-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_iterator.c: Split user context in all pixel
+ iterator APIs into a mutable data part, and an immutable data
+ part. This required modification to all modules using the pixel
+ iterator methods.
+
+2008-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickCompareImageChannels): Use
+ DifferenceImage().
+ (MagickCompareImages): Implement by calling
+ MagickCompareImageChannels().
+
+ - magick/compare.c (DifferenceImage): The ImageMagick-compatible
+ CompareImages() function signature was clearly an example of bad
+ design so rename CompareImages() to DifferenceImage() with a
+ signature which does not unnecessarily mix functionality and
+ allows for ease of future expansion.
+
+2008-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/Makefile.am (WAND\_TESTS): Added Wand drawtest and wandtest
+ to automated test suite.
+
+2008-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ThresholdImage): Don't read uninitialized pixel
+ indexes (valgrind gripe).
+
+ - coders/tiff.c (CompressionSupported): Use
+ TIFFIsCODECConfigured() to test if a codec is supported.
+
+ - tests/{rwblob.c, rwfile.c}: use DestroyImageList() rather than
+ DestroyImage().
+
+ - coders/psd.c (RegisterPSDImage): Fix module registration memory leak.
+
+ - coders/jpeg.c (RegisterJPEGImage): Fix module registration memory leak.
+
+2008-07-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (DestroyBlob, DestroyBlobInfo): Implementation is
+ a bit more robust.
+
+2008-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (ReadJPEGImage): Remove over-write of
+ image->client\_data. Resolves SourceForge issue [ 2018974 ]
+ client\_data is not passed to streamhandler.
+
+ - coders/png.c (WriteOnePNGImage): Fix crash when writing PNG
+ images with transparency and either type Optimize is requested, or
+ the image is colormapped.
+
+2008-07-12 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Fixed problem: "In this case, the referenced
+ images had previously been deallocated but are still being used.
+ Since they are overwritten, their signatures are invalid.
+
+2008-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcm.c (ReadDCMImage): Report actual image depth.
+
+ - magick/resource.c (InitializeMagickResources): Set default
+ maximum memory limit to physical memory rather than 2X physical
+ memory. This decision is made since the system paging device is
+ often slower than files in the filesystem, and so memory mapping
+ is likely faster.
+
+ - magick/blob.c (OpenBlob): The MAGICK\_IO\_FSYNC environment
+ variable causes output files to be synchronized to disk when set
+ to TRUE.
+
+2008-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/GraphicsMagick.html: Improved formatting of documentation.
+
+2008-07-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Make use of the new
+ `extension\_treatment` field.
+
+ - coders/dcraw.c (ReadDCRAWImage): Added a coder module to proxy
+ from various common RAW camera format extensions to the `dcraw`
+ delegate.
+
+ - magick/magick.h (MagickInfo): Add an extension\_treatment member
+ to indicate how file extensions should be treated for this coder.
+
+2008-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/{animate.c,quantize.c}: Replace !ColorMatch() with
+ NotColorMatch().
+
+ - utilities/Makefile.am (install-exec-local-utilities): Add back
+ in support for --enable-magick-compat which was accidentally
+ dropped in the new makefiles for GraphicsMagick 1.2. Resolves
+ SourceForge bug 2005883.
+
+ - magick/color.h (NotColorMatch): New macro for testing that two
+ colors are not the same. Opposite from existing ColorMatch().
+
+ - magick/command.c: Replaced the many duplicate enum conversion
+ code fragments with calls to functions in enum\_strings.c.
+
+ - magick/enum\_strings.c: Absorbed the many "ToString" and
+ "StringTo" functions from other source modules.
+
+ - magick/effect.c (ThresholdImage): Optimize for larger images.
+
+ - magick/constitute.c (ConstituteTextureImage): New function to
+ return a texture canvas image based on a tile image. Similar to
+ existing TextureImage() except better optimized for creating new
+ images and inherits tile image properties.
+
+ - magick/color.h (IsBlackPixel): New macro to test if a pixel is
+ black.
+ (IsWhitePixel): New macro to test if a pixel is white.
+
+ - coders/tile.c (ReadTILEImage): Use new ConstituteTextureImage()
+ function rather than TextureImage(). Also allow the user to
+ request a particular image type.
+
+ - coders/pdf.c (Huffman2DEncodeImage): Explicitly request a strip
+ per page when writing Group4 TIFF.
+
+ - coders/tiff.c (WriteTIFFImage): Place a generous default limit
+ on rows-per-strip when using Group3 or Group4 FAX compression.
+ The default limit is added since it is observed that the Group4
+ compressor fails with extremely huge strips. Added a define
+ "tiff:rows-per-strip" to allow the user to explicitly set the rows
+ per strip. Added a define "tiff:strip-per-page=true" to allow the
+ user to force one strip per page no matter what. Added progress
+ monitor support to tile writer.
+
+2008-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/configure/configure.cpp: The MAT coder now depends
+ on zlib so add explicit dependencies for it.
+
+ - wand/magick\_wand.c (MagickNegateImage): Implemented previously
+ unimplemented Wand method.
+ (MagickGammaImageChannel): Implemented previously unimplemented
+ Wand method.
+
+ - magick/operator.h (enum QuantumOperator): Added GammaQuantumOp
+ and "gamma" operator. Renamed InvertQuantumOp to NegateQuantumOp.
+
+2008-06-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/operator.h (enum QuantumOperator): Added InvertQuantumOp
+ and "invert" operator.
+
+ - coders/xcf.c (GIMPBlendModeToCompositeOperator): For XCF format,
+ we do support GIMP\_DIVIDE\_MODE composition now. Disable progress
+ monitor during tile composition.
+
+ - magick/composite.c (DivideCompositePixels): New Divide composite
+ operator contributed by Michael Burian <michael.burian@sbg.at>.
+
+ - magick/image.h (enum CompositeOperator): Added DivideCompositeOp.
+
+ - magick/enum\_strings.c (CompositeOperatorToString): New function
+ to convert a composite operator to a string.
+ (StringToCompositeOperator): New function to convert a string to a
+ composite operator.
+
+2008-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickThresholdImageChannel): Implement
+ previously unimplemented Wand function.
+ (MagickGetImageExtrema): Implement previously unimplemented Wand
+ function.
+ (MagickGetImageChannelExtrema): Implement previously unimplemented
+ Wand function.
+ (MagickQueryFonts): Implement previously unimplemented Wand
+ function.
+
+2008-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - scripts/format\_c\_api\_docs: Scan compare.c for API definitions.
+
+ - wand/magick\_wand.c (MagickCompareImageChannels): Enable use of
+ this function.
+ (MagickCompareImages): Enable use of this function.
+
+ - magick/compare.c: New source file.
+ (IsImagesEqual): Move here from magick/image.c.
+ (CompareImageChannels): Initial implementation of function roughly
+ similar to the one in ImageMagick.
+ (CompareImages): Initial implementation of function roughly
+ similar to the one in ImageMagick.
+
+ - magick/pixel\_iterator.c (PixelIterateTripleModify): New pixel
+ iterator function to access two images as read-only and one as
+ read-write for updating existing pixels.
+ (PixelIterateTripleNew): New pixel iterator function to access two
+ images as read-only and one as read-write for creating new pixels.
+
+2008-06-22 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - mat.c Added CloseBlob().
+
+2008-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickSetImageFormat): Add method to support
+ setting the image format.
+
+2008-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/profile.c (ProfileImage): Convert to use pixel iterators.
+
+2008-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/channel.c (ImportImageChannel): Convert to use pixel
+ iterators.
+ (SetImageChannelDepth): Convert to use pixel
+ iterators.
+
+ - Magick++/lib/Image.cpp (quantize): Error measurement support was
+ being performed incorrectly. SyncImage() is not needed here.
+
+2008-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/channel.c (GetImageChannelDepth): Convert to use pixel
+ iterators.
+
+2008-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/mat.c (RegisterMATImage): Set blob support to false for
+ MAT coder until bug related to blobs is fixed.
+
+2008-06-16 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - mat.c Ability to read a new compressed MATLAB image format.
+
+2008-06-15 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - mat.c, wpg.c: For empty images a message ImageFileDoesNotContainAnyImageData
+ is returned.
+
+2008-06-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/channel.c (ChannelImage): Convert to use pixel iterators.
+ (ExportImageChannel): Convert to use pixel iterators.
+
+ - coders/dpx.c (WriteDPXImage): As an experimental feature, when
+ the environment variable MAGICK\_RESERVE\_STORAGE is set to "TRUE",
+ then the DPX format writer will request the required storage from
+ the filesystem in advance (if supported by the OS) or the full
+ amount of memory required (when writing to an in-memory BLOB).
+
+2008-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magic.c (InitializeMagicInfo): New function to initialize
+ file format detection.
+ (GetMagickFileFormat): New internal implementation function to
+ detect file format based on file header.
+ (GetMagicInfo): This internal implementation function is eliminated.
+ (MagicInfo): MagickInfo structure is now private to the
+ implementation.
+
+2008-06-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (ListMagickInfo): Replace "blob support"
+ indication with the coder stability classification.
+ (RegisterMagickInfo): Pay attention to coder classification.
+
+ - magick/magick.h (MagickInfo): Added a coder stability
+ classification field as well as the MAGICK\_CODER\_STABILITY
+ environment variable to choose which coders are enabled.
+
+2008-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (GetImageCharacteristics): Don't access image
+ pixels if they are not defined yet.
+
+ - coders/{avi.c,avs.c,dcm.c,ept.c,fits.c,mtv.c,palm.c,rla.c,tga.c}:
+ Readers are now much more robust when faced with reading random files.
+
+2008-06-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Exclude all virtual delegates and
+ coders for pseudo-formats.
+
+2008-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcm.c (ReadDCMImage): Make DCM reader quit immediately on
+ EOF condition.
+
+ - coders/avi.c (ReadAVIImage): Make AVI reader more robust at
+ rejecting bad files.
+
+ - configure.ac: Eliminated --enable-delegate-build option that I
+ have not used or tested for almost ten years so it probably did
+ not work anyway. Use --with-ttf=/prefix to specify the the
+ installation prefix for freetype. Use
+ --with-ttf=/prefix/bin/freetype-config to specify the whole path
+ to freetype-config.
+
+2008-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): Add support for
+ -black-threshold and -white-threshold.
+
+ - magick/image.h (enum ChannelType): Added GrayChannel
+ enumeration.
+
+ - magick/operator.c (QuantumOperatorImageMultivalue): New
+ implementation function to make creating legacy functions like
+ black/white thresholding easier.
+
+ - wand/magick\_wand.c (MagickBlackThresholdImage): Implemented.
+ (MagickWhiteThresholdImage): Implemented.
+
+ - magick/effect.c (BlackThresholdImage): Implemented a
+ BlackThresholdImage() which is similar to (but not identical to)
+ the one in ImageMagick.
+ (WhiteThresholdImage): Implemented a WhiteThresholdImage() which
+ is similar to (but not identical to) the one in ImageMagick.
+
+2008-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/operator.c: Added support for additional channel
+ operators (-operator) for applying noise to one or more channels.
+ The additional operators are Noise-Gaussian, Noise-Impulse,
+ Noise-Laplacian, Noise-Multiplicative, Noise-Poisson, and
+ Noise-Uniform. The amount of noise applied is controlled via the
+ numeric argument, which can specify the percentage of noise to
+ apply.
+
+ - magick/enum\_strings.c: New source module to contain the various
+ EnumToString() and StringToEnum() functions which seem to multiply
+ like bunny-rabbits.
+
+ - magick/gem.c (GenerateNoise): Poisson noise generation was
+ taking excessively long and producing wrong results. Noise
+ generation was only producing the correct amount of noise in the
+ Q8 build.
+ (GenerateDifferentialNoise): New function to return noise in a
+ floating-point differential format.
+
+2008-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_iterator.h: Removed x,y coordinate information from
+ all of the callback definitions since a use for this information
+ has yet to be found.
+
+ - magick/composite.c (CompositeImage): Use individual callback
+ functions for the composition operations.
+
+ - coders/xcf.c (ReadXCFImage): Deal with grayscale images the
+ GraphicsMagick-way.
+
+2008-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xcf.c (ReadXCFImage): Validate XCF file data so that
+ corrupted files don't crash GraphicsMagick.
+
+2008-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): Incrementally read user data
+ part and check for EOF so that bogus files are rejected quickly.
+
+ - coders/cineon.c (ReadCINEONImage): Incrementally read user data
+ part and check for EOF so that bogus files are rejected quickly.
+
+2008-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pict.c (ReadPICTImage): Ensure that row\_bytes calculation
+ does not overflow. Verify that RLE decode does not overflow
+ buffer. Validate image frame dimensions.
+
+ - coders/palm.c (ReadPALMImage): Validate PALM bits per pixel and
+ colormap indexes.
+
+ - magick/resource.c (ListMagickResourceInfo): List controlling
+ environment variable in `-list resource` output as a configuration
+ usage reminder.
+
+ - coders/pdf.c (ReadPDFImage): Properly deal with reading rotated
+ PDFs.
+
+2008-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - FAQ.txt: Added a FAQ for how to extract and combine CMYK image
+ channels to individual files.
+
+2008-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/fx.c (ConvolveImage): Eliminate unnecessary "range check"
+ feature since range checking is not where the CPU time is going.
+
+ - magick/effect.c (UnsharpMaskImage): Re-write implementation to
+ use pixel iterators.
+
+ - magick/pixel\_iterator.c: Decided that the old per-pixel
+ iterations were not useful enough to keep since the region-based
+ ones are working fine. Moved pixel\_row\_iterator.c to
+ pixel\_iterator.c and renamed functions to remove the `Row`
+ designation.
+
+ - magick/composite.c (CompositeImage): Automatically adjust
+ colorspace of composite image so that it is compatible with canvas
+ image.
+
+ - magick/alpha\_composite.h (AlphaComposite): Fix alpha composite
+ when both pixels contain transparency.
+
+ - PerlMagick/demo/demo.pl: Use segmentation parameters which
+ are more suitable for our image.
+
+2008-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c (CompositeImage): CMYK copy composition
+ operators automatically set the image colorspace to CMYK.
+
+ - coders/tiff.c (WriteTIFFImage): CMYK must take precedence over
+ JPEG compression. We don't support JPEG compression in TIFF with
+ CMYK.
+
+2008-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ChannelThresholdImage): Re-implement using
+ pixel iterators. Support thresholding only the red channel by
+ eliminating the switch to intensity thresholding if only one
+ channel parameter is supplied.
+
+ - coders/tiff.c (WriteTIFFImage): Don't accidentially convert CMYK
+ images to RGB.
+
+ - magick/composite.c (CompositePixels): Handle CopyBlack properly
+ for CMYK images.
+
+ - magick/command.c (CompositeImageCommand): Support CopyCyan,
+ CopyMagenta, CopyYellow, and CopyBlack.
+
+ - magick/composite.c (CompositeImage): Preserve the canvas image
+ colorspace.
+
+ - doc/options.imdoc: Remove mention of thresholding at the channel
+ level since this never worked in a useful fashion and now only
+ simple intensity thresholding is available via -threshold.
+
+ - magick/command.c (MogrifyImage): Revert to using ThresholdImage() rather
+ than ChannelThresholdImage().
+
+ - PerlMagick/Magick.xs: Revert to using ThresholdImage() rather
+ than ChannelThresholdImage().
+
+2008-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (AddNoiseImage): Implemented using pixel
+ iterators.
+
+ - magick/pixel\_row\_iterator.c (PixelRowIterateDualNew): New pixel
+ iterator. Similar to existing PixelRowIterateDualModify except
+ that this one is for when initializing a new image.
+
+2008-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c (CompositeImage): Update image composition to
+ use pixel iterator methods.
+
+2008-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/enhance.c: Re-wrote all enhancement functions in this
+ module to be based on the pixel iterator methods.
+
+ - magick/command.c (ConvertImageCommand, MogrifyImageCommand,
+ DisplayImageCommand): Gamma multiple channel syntax was broken.
+ Now it is fixed.
+
+2008-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colorspace.c (RGBTransformImage): Optimized lookup table
+ generation performance to the maximum extent possible.
+ (TransformRGBImage): Optimized lookup table
+ generation performance to the maximum extent possible.
+
+ - magick/image.h (RoundDoubleToQuantum): New macro to explicitly
+ safely round a `double` to a Quantum.
+ (RoundFloatToQuantum): New macro to explicitly safely round a
+ `float` to a Quantum.
+
+ - configure.ac: Add OpenMP support library to LIBS so that
+ dependent applications will pick up this dependency without
+ themselves needing to enable OpenMP.
+
+ - magick/command.c (CompositeImageList): Don't overwrite matte
+ flag for CopyOpacity composition.
+
+ - magick/composite.c (CompositeImage): CopyOpacity composition
+ needs the opacity channel to be enabled.
+
+ - PerlMagick/Magick.xs: Dissolve composition with Opacity was not
+ working right. Now it does.
+
+2008-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/gem.c (HWBTransform): Hue value range was scaled wrong,
+ leading to clipping.
+ (TransformHWB): Hue value range was scaled wrong, leading to
+ clipping.
+
+2008-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colorspace.c (RGBTransformImage): Re-implement transform
+ loops using PixelRowIterateMonoModify() in order to simplify the
+ code.
+
+2008-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colorspace.c (TransformRGBImage): Re-implement transform
+ loops using PixelRowIterateMonoModify() in order to simplify the
+ code.
+
+ - magick/{pixel\_iterator.h, pixel\_row\_iterator.h}: Pass pixel
+ colormap index/indexes to callback functions. Dependent code is
+ adjusted to match.
+
+2008-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ConvertImageCommand, MogrifyImageCommand,
+ MogrifyImage): Add command access to the new channel operators.
+
+ - magick/operator.c (QuantumOperatorRegionImage): Support the new
+ channel operators. Update to use PixelRowIterateMonoModify() for
+ a bit more performance.
+
+ - magick/operator.h (enum QuantumOperator): Added new operators
+ AssignQuantumOp, ThresholdQuantumOp, ThresholdBlackQuantumOp, and
+ ThresholdWhiteQuantumOp.
+
+2008-05-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (VersionCommand): Report if OpenMP is supported
+ by the build.
+
+ - configure.ac, Makefile.am: Install documentation according to
+ the conventions established by the configure script. This
+ installs the documentation under
+ /usr/local/share/doc/GraphicsMagick by default.
+
+2008-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - scripts/format\_c\_api\_docs: Add pixel\_iterator.c and
+ pixel\_row\_iterator.c to API documentation formatter.
+
+ - magick/api.h: Include pixel\_iterator.h and pixel\_row\_iterator.h.
+
+ - magick/Makefile.am (MAGICK\_INCLUDE\_HDRS): Formally install
+ pixel\_iterator.h and pixel\_row\_iterator.h.
+
+ - magick/image.c (IsImagesEqual): Update to use
+ PixelRowIterateDualRead().
+ (GetImageStatistics): Update to use PixelRowIterateMonoRead().
+
+ - magick/pixel\_row\_iterator.h: New interfaces which are similar to
+ the already existing interfaces in pixel\_iterator.h except that
+ they pass a row to the callback rather than one pixel.
+
+ - magick/operator.c (QuantumOperatorRegionImage): Add progress
+ monitor support.
+
+ - magick/pixel\_iterator.c (PixelIterateMonoRead): Add a
+ `description` argument and progress monitor support.
+ (PixelIterateMonoModify): Add a
+ `description` argument and progress monitor support.
+ (PixelIterateDualRead): Add a
+ `description` argument and progress monitor support.
+ (PixelIterateDualModify): Add a
+ `description` argument and progress monitor support.
+
+ - magick/resize.c (HorizontalFilter, VerticalFilter): Switch back
+ to RoundSignedToQuantum() since some pixels were experiencing
+ underflow. Localize some variables so that we don't have to
+ declare them as private for OpenMP.
+
+2008-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac, magick/resize.c, PerlMagick/Makefile.PL.in: Added
+ OpenMP support for parallelizing a task across multiple cores.
+
+2008-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac, magick/nt\_base.h: Fix using libbz2 under MinGW.
+
+ - coders/{msl.c, svg.c, url.c}: Fix compilation with modern
+ libxml2 under MinGW.
+
+2008-05-08 Josue Andrade Gomes <josuegomes@gmail.com>
+
+ - magick/nt\_base.h, libxml/include/win32config.h (vsnprintf):
+ Fixed compilation issue noticed with Visual C++ 2008.
+
+2008-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (GetMagickInfo): Simplify implementation.
+ (RegisterMagickInfo): Remove any existing entry since module
+ loading may result in duplicate entries.
+
+2008-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libtool: Update to libtool 1.2.4.
+
+ - magick/magick.h (MagickInfo): Store string attributes as `const
+ char \*` to statically allocated data rather than as heap allocated
+ strings. THIS IS AN INTERFACE CHANGE. Using a coder written to
+ the old interface is non-fatal but may resemble a small memory
+ leak. The reason for the change is to avoid at least 880 needless
+ malloc()/strlen()/strlcpy() operations at initialization time, and
+ at least 880 free() calls at destruction time. While these
+ operations did not take long, they are still an unnecessary
+ overhead, which is increased in thread-safe applications.
+
+ - magick/module.c (OpenModule): Ignore requests to open modules
+ which have already been opened.
+
+ - GraphicsMagick.spec.in: Add --with-included-ltdl to the default
+ options since this seems safest until the libltdl validation logic
+ is fully robust. This should be made user-configurable in the
+ future.
+
+ - magick/Makefile.am (magick\_libGraphicsMagick\_la\_LIBADD): Apply
+ libltdl dependency argument as required for building.
+
+ - configure.ac: Intuit if the GraphicsMagick library will depend
+ on -lltdl.
+
+ - Magick++/bin/GraphicsMagick++-config.in: Use substitutions
+ rather than invoking GraphicsMagick-config in order to determine
+ GraphicsMagick library usage requirements. This avoids problems
+ when GraphicsMagick-config is not in the executable search path.
+
+2008-05-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - GraphicsMagick.spec.in: NEWS was renamed to NEWS.txt. Enable
+ libtool verbose output so it is possible to diagnose build
+ failures.
+
+2008-05-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - mat.c: gm convert -limit Pixels 1 input\_gray\_lsb\_16bit.mat crap.miff
+ don't rotate partial image.
+
+2008-04-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (DestroyMagickInfoList): Use DestroyMagickInfo().
+ (UnregisterMagickInfo): Use DestroyMagickInfo().
+ (RegisterMagickInfo): Simplify dramatically by adding to the front
+ of the list rather than maintaining alpha order.
+
+ - magick/image.c (DestroyImageInfo): Tidy up and simplify code.
+
+ - magick/constitute.c (WriteImage): Comment out the "bi-modal
+ delegate" execution code until we determine what value it offers.
+ The test suite passes without it.
+
+ - magick/magick.h (struct MagickInfo): There is no need for `name`
+ to be allocated data so make it const.
+ (DestroyMagickInfo): Add a static function to destroy a MagickInfo
+ structure. Renamed previous DestroyMagickInfo to
+ DestroyMagickInfoList and made it static.
+
+2008-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: GraphicsMagick 1.2 released.
+ CVS head is now 1.3 development.
+
+ - png: Updated libpng to 1.2.27.
+
+2008-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Ignore file extensions which
+ match defined virtual delegate entries (including stealth
+ entries).
+
+2008-04-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - BENCHMARKS.txt: Added timings for -blur.
+
+2008-04-27 Darko Kojic <dkc@sf.net>
+
+ - magick/effect.c (MedianFilterImage): Fixes to compile on ARM
+ CPU.
+
+2008-04-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.h (MagickInfo): Remove image\_info member since I
+ can not find any purpose for it.
+
+ - coders/tiff.c (WriteTIFFImage): Remove assertion check on
+ scanline size since it has not caught anything.
+
+ - magick/image.c (SetImageInfo): Ensure that the file extension
+ does not trigger unwanted activity such as access to an X11
+ server, printer, or the launch delegate.
+
+ - config/Makefile.am (configshare\_DATA): Install colors.mgk in
+ share path.
+
+ - magick/blob.c (GetConfigureBlob): Search `share` config path
+ prior to `lib` config path.
+
+2008-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOnePNGImage): TrueColor RGB was usually
+ written rather than the desired more compact format. This is a
+ first pass at fixing that.
+
+2008-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - BENCHMARKS.txt: Added a benchmark summary.
+
+2008-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Prepare 1.2beta1 release.
+
+ - NEWS.txt: Updated with latest news.
+
+2008-04-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libtool: Update to 1.2965 2008-04-22
+
+ - coders/png.c (ReadOneJNGImage): Deal with ReadImage() returning
+ a NULL pointer when reading JPEG sub-image.
+
+2008-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/channel.c (ExportImageChannel): Added progress monitor
+ support.
+ (SetImageChannelDepth): Added progress monitor support.
+ (ChannelImage): Don't preserve matte channel when extracting
+ channel.
+
+ - magick/image.c (SetImageOpacity): Avoid integer overflow in Q32
+ build. Added progress monitor support.
+ (SyncImage): Added progress monitor support.
+ (SetImage): Added progress monitor support.
+ (CycleColormapImage): Added progress monitor support.
+ (GetImageBoundingBox): Added progress monitor support.
+ (SortColormapByIntensity): Added progress monitor support.
+
+2008-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac, magick/Makefile.am: Don't use libtdl unless we are
+ supposed to be using it!
+
+ - libtool: Updated to GNU libtool 1.2960 2008-04-19.
+
+ - configure.ac, magick/delegate.h: It seems that the modern
+ convention is to store ghostscript headers in a subdirectory
+ called `ghostscript` rather than `ps`.
+ We don't actually need Ghostscript errors.h and that is a good
+ thing since it seems that some newer Ghostscript calls it ierrors.h
+
+2008-04-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/files-dlls.isx: Comment out inclusion
+ of X11 support DLLs.
+
+ - VisualMagick/magick/magick\_config.h.in: X11 is no longer in the
+ default Windows build.
+
+2008-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c: Eliminate various annoying warnings noticed
+ under MinGW.
+
+ - magick/spinlock.h (\_spinlock\_release): Use `long` rather than
+ `int` in order to eliminate warning under MinGW.
+
+ - magick/semaphore.c (spinlock\_wait): Use `long` rather than `int`
+ in order to eliminate warning under MinGW.
+
+ - magick/log.c (LogMagickEventList): Eliminate warning under MinGW.
+
+ - magick/compress.h: Clean up interface definitions to use
+ magick\_uint8\_t for unsigned character data.
+
+ - coders/jpeg.c (ReadJPEGImage): Don't use GetPixelCachePresent()
+ since it is not DLL-exported.
+
+2008-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/yuv.c (ReadYUVImage): Report exception info correctly.
+
+ - coders/xpm.c (ReadXPMImage): Report exception info correctly.
+
+ - coders/xc.c (ReadXCImage): Report exception info correctly.
+
+ - coders/tiff.c (ReadTIFFImage): Report exception info correctly.
+
+ - coders/null.c (ReadNULLImage): Report exception info correctly.
+
+ - coders/jpeg.c (ReadJPEGImage): Report exception info correctly.
+ Use of Huffman optimization is now based on available memory
+ rather than a hard-coded image size.
+
+ - coders/gif.c (ReadGIFImage): Report exception info correctly.
+
+ - magick/utility.c (MagickSizeStrToInt64): New function to convert
+ a size string with optional units suffix to a 64-bit integer.
+ (MagickStrToInt64): New function to convert a string to a 64-bit
+ integer, with error checking.
+
+ - magick/image.c (SetImage): SetImage now returns error status.
+
+ - magick/command.c: Eliminated the long-deprecated -cache resource
+ limit option.
+
+ - magick/resource.c: Complete re-write of the resource limit
+ system. Resource specifications are now absolute except that they
+ support a binary metric suffix such as `K` to scale the value.
+ Added the `Pixels` limit type to limit the maximum number of
+ pixels allowed for each image.
+
+2008-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (WriteJPEGImage): Output grayscale images more
+ efficiently.
+
+2008-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lcms: Updated lcms to 1.17.
+
+ - png: Updated libpng to 1.2.26.
+
+2008-04-09 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c (ReadOnePNGImage) Use the low bits of the PNG
+ tRNS values instead of scaling them when reducing from 16-bits.
+
+2008-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Updated to Autoconf 2.62.
+
+2008-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImageCommand): New -create-directories
+ option automatically creates subdirectories as needed when
+ -output-directory option is used. This is useful when one
+ directory tree of files is being mogrified to a new tree.
+
+2008-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (MagickCreateDirectoryPath): New function to
+ create a directory path. Will be used later.
+ - configure.ac: Tweaks to produce a successful MinGW cross-compile.
+
+2008-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Added a simple sentinel
+ assertion to hopefully flush out any remaining cases where
+ ExportImagePixelArea() writes past the end of its buffer.
+
+ - magick/constitute.c (ExportImagePixelArea): GrayQuantum case for
+ DirectClass pixels was sometimes writing a zero byte one past the
+ end of the allocated buffer. Thanks to Josue Gomes for reporting
+ this bug.
+
+2008-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/{pcd.c,pcx.c,pdb.c,pict.c,stegano.c,wpg.c,xcf.c}:
+ Warnings reduction.
+
+ - magick/{channel.c,image.c,unix\_port.c,render.c}: Warnings
+ reduction.
+
+ - coders/mat.c: Convert C99 comments to C89 comments so code can
+ compile with a C89 compiler.
+
+ - coders/tiff.c (WriteTIFFImage): Add an assertion to enforce that
+ the bytes output to the scanline is no more than the bytes
+ allocated for the scanline.
+
+ - NEWS.txt: Updated with latest NEWS.
+
+2008-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c (WritePDFImage): Default to ZIP compression if
+ available. Ignore Image compression setting since the useful
+ value (set by the user) usually comes from ImageInfo.
+
+ - coders/png.c (WriteOnePNGImage): Fix progress monitor when
+ writing PNG.
+
+ - magick/channel.c (GetImageChannelDepth): Added progress monitor
+ support.
+
+ - magick/signature.c (SignatureImage): Added progress monitor support.
+
+ - magick/image.c (GetImageDepth): Added progress monitor support.
+
+2008-04-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libtool: Update to libtool 2.2.2.
+
+ - coders/jpeg.c: Convert more code to use size\_t for sized values
+ rather than long.
+
+ - coders/wpg.c (InsertRow): Fix log format string specification.
+
+ - coders/dpx.c (WriteDPXImage): Fix typo in casts.
+
+ - coders/fpx.c (ReadFPXImage): Apply FreeBSD patch from Mikhail
+ Teterin to allow FlashPIX to work better for 64-bit builds.
+ Addresses SourceForge issue 1824658 "FPX should work again now".
+
+ - magick/blob.c (ImageToBlob): Fix typo in cast.
+
+2008-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - CONTRIBUTE.txt: Convert contribute.html to reStucturedText
+ format and generate HTML version from it.
+
+ - PROCESS.txt: Convert description of development process to
+ reStucturedText format and generate HTML version from it.
+
+ - INSTALL-windows.txt: Add instructions for how to install from
+ setup.exe style installer. Also add instructions for how the
+ distribution package is built.
+
+ - Copyright.txt: Reformat in reStucturedText format and generate
+ HTML version from it.
+
+ - VisualMagick/installer/inc/body.isx: No longer include
+ development headers and libraries in the Windows DLL install
+ package since they are large and they may only work with the
+ version of Visual C++ used to perform the build. It is much safer
+ for the developer to build the package from source with his own
+ compiler.
+
+2008-03-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fix compilation issues with Microsoft Visual Studio.
+
+2008-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage, WriteDPXImage): Use lookup tables to
+ speed up value conversion.
+
+ - magick/memory.h (MagickAllocateArray): Renamed from
+ MagickAllocateMemoryElements.
+
+2008-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: Use memory allocation macros like the rest
+ of the code.
+
+ - magick/memory.c (MagickMalloc): New function which behaves
+ similar to malloc().
+ (MagickMallocArray): New function for allocating an array.
+ (MagickRealloc): New function which behaves similar to realloc().
+ (MagickFree): New function which behaves similar to free().
+ (MagickAllocFunctions): New function to allow the user to specify
+ the memory allocation functions.
+
+ - magick/memory.h: New header file to define memory allocation
+ functions.
+
+ - magick/deprecate.c (DeleteImageList, DestroyImages,
+ GetImageList, GetImageListIndex, GetImageListSize, GetNextImage,
+ GetNumberScenes, GetPreviousImage, ParseImageGeometry,
+ PopImageList, PostscriptGeometry, PushImageList,
+ SetCacheThreshold, SetImageList, ShiftImageList, SizeBlob,
+ SpliceImageList, UnshiftImageList): Remove functions which were
+ already deprecated in ImageMagick 5.5.2 or earlier.
+
+2008-03-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): Support writing image which is
+ already in a YCbCr colorspace.
+ (ReadDPXImage): Return YCbCr images in YCbCr colorspace unless
+ they are also Cineon log encoded.
+
+ - magick/image.c (CloneImage): Use CloneImageAttributes().
+
+ - magick/attribute.c (CloneImageAttributes): New function for
+ copying image attributes from one image to another.
+
+ - magick/utility.c (TranslateTextEx): Check if the pixel cache is
+ initialized before using a function which requires using it.
+ Thanks to Micha Kowalczuk for bringing this issue to my
+ attention.
+
+ - magick/attribute.c (SetImageAttribute): Only apply
+ transformations to "comment" and "label" attributes.
+
+ - magick/pixel\_cache.c (GetPixelCachePresent): New function to
+ test if the image pixel cache is present and initialized.
+
+2008-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colorspace.c (RGBTransformPacket): Rationalize casts for
+ improved performance.
+
+ - magick/image.c (GetImageDepth): Use table lookups to improve
+ performance.
+
+2008-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (AllocateImage): Transfer any attributes from
+ ImageInfo to allocated image.
+ (SetImageDepth): Use table lookups to improve performance.
+
+2008-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImageCommand): Added an
+ -output-directory option to `mogrify` to send output files to the
+ specified directory.
+
+2008-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/read.t: Add input\_logical\_lsb\_08bit.mat to
+ PerlMagick tests.
+
+ - magick/nt\_feature.c (CropImageToHBITMAP, ImageToHBITMAP): Use
+ GlobalFree() to free bitmap handle.
+
+2008-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/read.t: Added/adjusted WPG test files from Jaroslav
+ Fojtik.
+
+2008-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - AUTHORS.txt, BUGS.txt, FAQ.txt, NEWS.txt, PLATFORMS.txt,
+ TODO.txt, INSTALL-unix.txt, INSTALL-windows.txt: Use
+ reStructuredText format.
+
+ - Makefile.am: Use reStructuredText for more files.
+
+2008-02-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ReadImage): Disable colorspace override
+ code since it was being wrongly-triggered in X11 display commands.
+
+2008-02-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/body.html: Update to mention 1.1.11 release.
+
+2008-02-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colorspace.c (RndToInt): Cast result to `unsigned int`
+ rather than `int` in order to avoid possible value truncation with
+ Q32 build. Problem was reported by Kai-Uwe Behrmann.
+ (TransformRGBImage): Fix loop iterator which was looping one past
+ the end of the array. Reported by Kai-Uwe Behrmann.
+
+ - magick/command.c: Added a -set option to the composite, convert,
+ display, mogrify, import commands in order to allow setting an
+ image attribute.
+
+2008-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: Use MagickAcquireMemory() rather than
+ AquireMemory().
+
+ - coders/xwd.c (ReadXWDImage): Eliminate integer overflow
+ vulnerability (IDefense 09.19.07).
+
+ - coders/xbm.c (ReadXBMImage): ditto
+
+ - coders/xcf.c (ReadXCFImage): ditto
+
+ - coders/dib.c (ReadDIBImage): ditto
+
+ - coders/dcm.c (ReadDCMImage): ditto
+
+2008-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): The RFC 3949 specification for
+ Internet FAX recommends LSB2MSB fill order so document that.
+
+2008-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Use `-define
+ tiff:fill-order={msb2lsb|lsb2msb}` to control TIFF bit fill order.
+
+2008-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Updated to latest CVS libtool.
+
+ - coders/tiff.c (CompressionSupported): Use
+ TIFFGetConfiguredCODECs() to test if a requested compression type
+ is supported by libtiff. Based on advice from Frank Warmerdam.
+
+ - configure.ac: Add test for TIFFGetConfiguredCODECs() in libtiff.
+
+2008-02-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c: With libtiff 3.6.1, including tiff.h and tiffio.h
+ is not sufficient to obtain the definitions from tiffconf.h so
+ libtiff is assumed to not support any features, such as
+ compression. Avoid this problem by explicitly including
+ tiffconf.h if it is found. This resolves SourceForge issue
+ [1883527] compression of tiff-file has no effect.
+
+2008-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/setup.isx: Set Inno Setup installer
+ compression to "lzma/max".
+
+ - PerlMagick/Magick.xs: Eliminate use of memory allocation macros
+ since these failed miserably under Windows where it seems that
+ malloc, free, and realloc are redefined via macros by the Perl
+ build environment. This reverts changes made on 2007-12-01.
+
+ - magick/memory.c (MagickAcquireMemoryArray): Use implementation
+ from the 1.1 branch.
+
+ - magick/utility.h: Remove MagickSafeMultiplySize\_t since it seems
+ that use of inline functions in Windows is a disaster area.
+
+2008-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (windows-dist): Create a 7z compressed Windows
+ comprehensive source package. See http://www.7-zip.org/ for
+ information on Windows 7-Zip and http://p7zip.sourceforge.net/ for
+ information on portable 7-Zip (P7ZIP).
+
+2008-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Add logging for image resolution
+ and resolution units.
+
+ - magick/version.h.in: Update copyright year to 2008.
+
+2008-02-01 Gary V. Vaughan <gary@gnu.org>
+
+ - configure.ac: Updated for libtool-2.1b.
+
+ - bootstrap (libtoolize): Libtoolize can figure out the mode and
+ directory for libltdl from configure.ac.
+
+2008-01-28 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ - magick/Makefile.am: Update
+ magick\_libGraphicsMagick\_la\_DEPENDENCIES to use LTDLDEPS.
+
+2008-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Successfully read existing file
+ names in the form file[123] which were failing to read since they
+ appear to be a valid sub-image specification.
+
+2008-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (ExpandFilenames): If a filename appears to
+ contain a wildcard specification, first check to see if there is
+ file matching the unexpanded wildcard prior to engaging in the
+ slow task of wildcard expansion. Without this fix, expanding the
+ command line takes a very long time if there are a huge number of
+ files in the directory, and some file names appear to contain
+ wildcard specifications. Inspired by SourceForge bug reports [
+ 1878992 ] "literal square brackets in file name cause large delay"
+ and [ 1783209 ] "converting runs slowly when subimage is
+ specified", but this might not be the complete fix for the
+ problem.
+
+2008-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Update to Automake 1.10.1 and enable generation of
+ an lzma compressed source package.
+
+2008-01-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Added configure option --with-umem to enable use
+ of the umem memory allocation library available in Solaris 9,
+ Update 3 and later, or from
+ https://labs.omniti.com/trac/portableumem/. This library supports
+ concurrency in multi-threaded programs and supports debugging
+ memory issues. See
+ http://developers.sun.com/solaris/articles/libumem\_library.html
+ for a description of how to use the library for debugging memory
+ issues.
+
+2008-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (VersionCommand): Include a "Large Memory" item
+ in the Feature Support list.
+
+ - coders/png.c (RegisterPNGImage): Remove reference to dead PNG
+ ftp site.
+
+ - VisualMagick/configure/configure.cpp (InitInstance): Remove
+ project dependency on dxguid.lib (Direct-X).
+
+2008-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Update libtool to latest CVS version.
+
+2008-01-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (DisplayImageCommand): No longer default to
+ reading standard input if stdin fails isatty() test. This
+ behavior was causing failure to launch from Gnome and it is
+ difficult to work around the issue from within a .desktop file.
+ (AnimateImageCommand): No longer default to
+ reading standard input if stdin fails isatty() test.
+
diff --git a/www/ChangeLog-2009.html b/www/ChangeLog-2009.html
new file mode 100644
index 0000000..8780a44
--- /dev/null
+++ b/www/ChangeLog-2009.html
@@ -0,0 +1,1929 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2009-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/unix_port.c (MagickSpawnVP): Remove unneeded new line
+character in error message format.</li>
+<li>Magick++/Makefile.am: Allow Magick++ to be built as a shared
+library under MinGW and Cygwin. This requires a modern GCC in
+order for C++ exceptions to work.</li>
+<li>utilities/tests/annotate.sh: MSYS is garbeling up draw command
+so use a command file rather than using command line.</li>
+<li>coders/{fits.c,meta.c,locale.c}: Fix benign warnings noticed
+under Cygwin 1.7.</li>
+<li>magick/{constitute.c,resource.c,utility.c}: Fix benign warnings
+noticed under Cygwin 1.7.</li>
+</ul>
+</blockquote>
+<p>2009-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/module.c (DestroyModuleInfo): If the Jasper library is
+used, then we can't invoke lt_dlexit() because this unloads the
+Jasper library and Jasper sometimes registers an atexit() cleanup
+handler. Unfortunately, this may annoy memory leak checkers.</li>
+<li>coders/jp2.c: Defer Jasper initialization to point of use.</li>
+</ul>
+</blockquote>
+<p>2009-12-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickCdlImage): New method to apply the ASC
+CDL to an image.
+(MagickHaldClutImage): New method to apply a Hald CLUT to an image.</li>
+</ul>
+</blockquote>
+<p>2009-12-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h atof(), atoi(), and atol() are legacy functions
+which might not be thread safe, might not enforce reasonable
+limits, and should not be used for new code. So we implement them
+via strtod() and strtol().</li>
+</ul>
+</blockquote>
+<p>2009-12-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickGetImageBoundingBox): New method to
+return the crop bounding box required to remove any solid-color
+border from the image.
+(MagickGetImageFuzz/MagickSetImageFuzz): New methods to get and
+set the color comparison fuzz factor</li>
+<li>wand/pixel_wand.c (ClonePixelWand): New method to deep-copy an
+existing pixel wand.
+(ClonePixelWands): New method to deep-copy an array of existing
+pixel wands.</li>
+<li>wand/magick_wand.c (MagickSetResolution): New method to set the
+wand resolution. This one also works before the image has been
+read (unlike MagickSetImageResolution()).
+(MagickSetResolutionUnits): New method to set the wand resolution
+units. Use in conjunction with MagickSetResolution(). This one
+also works before the image has been read (unlike
+MagickSetImageUnits()).</li>
+</ul>
+</blockquote>
+<p>2009-12-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/demo/demo.cpp (main): Stop using deprecated functions.</li>
+<li>wand/drawtest.c: Stop using deprecated functions.</li>
+</ul>
+</blockquote>
+<p>2009-12-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/module.c (ModuleAliases): J2C is supported by the JP2
+coder.</li>
+<li>coders/jp2.c: JP2 is now an alias for JPC since many files use
+that extension. Problem reported by Stefano Acerbetti.</li>
+</ul>
+</blockquote>
+<p>2009-12-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: The png8 encoder would fail when trying to write
+a 1-color image. Problem reported by Bob Clark.</li>
+</ul>
+</blockquote>
+<p>2009-12-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Define _GNU_SOURCE and _NETBSD_SOURCE so that
+pwrite() and pread() prototypes are available under GNU Linux and
+NetBSD.</li>
+<li>coders/tiff.c: Warnings reduction.</li>
+<li>magick/widget.c: Warnings reduction.</li>
+<li>magick/segment.c (Classify): Warnings reduction.</li>
+<li>magick/magic.c (struct StaticMagic): Length and offset can never
+be negative so use an unsigned type rather than size_t.</li>
+<li>magick/render.c (TracePath): Fix access one beyond the end of
+the points array.</li>
+</ul>
+</blockquote>
+<p>2009-11-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/gem.c (GetOptimalKernelWidth1D, GetOptimalKernelWidth2D):
+In the Q32 build, convolution kernel size was estimated
+incorrectly for large sigmas on 32-bit systems due to arithmetic
+overflow.</li>
+</ul>
+</blockquote>
+<p>2009-11-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ConvolveImage): Moved here from fx.c since this
+is a more suitable place for it to be.</li>
+<li>magick/enhance.c (GammaImage): Improve performance a bit.
+Preserve full precision in Q32 build.</li>
+</ul>
+</blockquote>
+<p>2009-11-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/{channel.c,constitute.c,nt_base.h}: Start using the C'99
+<cite>restrict</cite> keyword.</li>
+</ul>
+</blockquote>
+<p>2009-11-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickGetImageAttribute): New method to get
+an image attribute. Patch contributed by Mikko Koppanen.
+(MagickSetImageAttribute): New method to set an image attribute.
+Patch contributed by Mikko Koppanen.</li>
+<li>magick/constitute.c (ReadImage): Log subimage and subrange.</li>
+<li>configure: Update to Autoconf 2.65.</li>
+<li>magick/attribute.c (GenerateIPTCAttribute): Returned IPTC string
+values were one character too short.</li>
+</ul>
+</blockquote>
+<p>2009-11-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (AllocateImage): The documented shorthand for
+specifying image size via filename[WIDTHxHEIGHT] was not working
+for raw formats which use the image tile_info data.</li>
+</ul>
+</blockquote>
+<p>2009-11-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (ParseSubImageSpecification): Try to match
+behavior of previous sub-image specification parser. Some
+incantations did not produce the same results.</li>
+<li>win2k/IMDisplay/res/{IMDisplay.ico, IMDisplayDoc.ico}: Replaced
+with GraphicsMagick icon prepared by Jaroslav Fojtik.</li>
+<li>coders/svg.c (ReadSVGImage): Use runtime initialization of
+SAXModules rather than static initialization.</li>
+<li>magick/command.c: Commands now support reading an image from
+stdin in conjunction with a subrange specification (e.g. &quot;-[1]&quot;).
+Problem was reported by Mario Becroft.</li>
+<li>magick/common.h: New header file to incorporate the common bits
+shared by studio.h and api.h.</li>
+<li>ltdl/ltdl.c: Update libltdl to 2.2.6b in order to fix security
+issue. Resolves CVE-2009-3736 as it pertains to GraphicsMagick.</li>
+</ul>
+</blockquote>
+<p>2009-11-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ConstituteImage, DispatchImage): <cite>A</cite> and
+<cite>T</cite> should indicate transparency and <cite>O</cite> should indicate opacity.
+Behavior was inconsistent. In some cases <cite>O</cite> meant transparency
+while in other cases it meant opacity. Also, in a few cases, matte
+was not getting enabled in the image as it should. Problems were
+reported by Scott Kuhl.</li>
+</ul>
+</blockquote>
+<p>2009-11-10 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Also suppress new pedantic warnings from most
+older libpng-1.4.0 betas.</li>
+<li>coders/png.c: Added a warning when attempting to use libpng-1.4beta
+older than 1.4.0beta67.</li>
+</ul>
+</blockquote>
+<p>2009-11-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): Only invoke ProfileImage() if
+an ICC CMS transform is to be performed. Otherwise invoke
+SetImageProfile() to add the new profile.</li>
+<li>magick/profile.c (ProfileImage): Improve logging messages.</li>
+<li>coders/tiff.c (ReadTIFFImage): Allow CIELAB TIFF to be read.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Detect and apply colorspaces
+appropriately for ITU FAX JPEG.</li>
+</ul>
+</blockquote>
+<p>2009-11-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff: Updated to libtiff 3.9.2.</li>
+</ul>
+</blockquote>
+<p>2009-11-08 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Suppress new pedantic warnings from libpng
+version 1.2.41 and 1.4.0 and later.</li>
+</ul>
+</blockquote>
+<p>2009-11-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Document difference between -recolor and
+Adobe Flash color matrix.</li>
+</ul>
+</blockquote>
+<p>2009-11-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImageCommand): Convolve does not accept
+an argument which looks like a geometry. Resolves SourceForge
+issue #2890923 &quot;Different handling of -convolve between convert
+and mogrify&quot;.
+(MogrifyImage): Validate that user-provided matrix is square when
+parsing -convolve and -recolor commands in order to avoid a core
+dump.</li>
+<li>coders/tiff.c (ReadTIFFImage): Improved/added more coder logging
+statements.</li>
+<li>magick/xwindow.c: Reflowed some code and comments.</li>
+<li>magick/utility.c (SetClientName): Default client name does need
+to be &quot;Magick&quot;, so original value is restored.</li>
+<li>coders/mpc.c (ReadMPCImage): is_monochrome and is_grayscale
+flags were not managed properly for the MPC coder.</li>
+</ul>
+</blockquote>
+<p>2009-10-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (ReadJPEGImage): Added jpeg:block-smoothing and
+jpeg:fancy-upsampling defines to control these JPEG library
+options.</li>
+<li>magick/image.c (SetImageInfo): Fix lockup due to hanging in loop
+while parsing malformed sub-image specification (SourceForge issue
+2886560). Also fixes the ability to pass the image size via the
+filename specification like &quot;myfile.jpg[640x480]&quot; rather than
+needing to use -size.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Fix image scaling when used with
+IJG JPEG library version 7.</li>
+</ul>
+</blockquote>
+<p>2009-10-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c: Added support for a &quot;Threads&quot; limit, which
+specifies how many threads may be used. Note that if
+omp_set_nested(true) is used, GCC's GOMP seems to replicate this
+number of threads for each level of threading rather than sharing
+the specified number of threads across all teams. For example,
+specifying four threads leads to sixteen active threads with
+omp_set_nested(true) and nested threading. This GOMP behavior
+does not seem to cause any harm.
+(GetMagickResourceLimit): New accessor function to retrieve the
+maximum limit for a resource.</li>
+<li>magick/module.c (ReadModuleConfigureFile): Default set of module
+aliases is now statically initialized. The modules.mgk file is
+now optional and can be used to support adding more modules, or
+diverting existing format support to a user-provided module.</li>
+<li>magick/magick.c (DestroyMagick): Document that this function
+should be invoked from the program's primary thread after any
+threads using GraphicsMagick have terminated.
+(GetMagickInfo): Was thread safe for access but not properly
+thread safe during initialization. Is now fully thread safe.
+(InitializeMagick): Fully initialize everything needed to
+read/write files. Document that this function MUST be invoked
+from the program's primary thread prior to using any other
+GraphicsMagick functions.</li>
+<li>magick/color_lookup.c (ReadColorConfigureFile): The colors.mgk
+is now optional so don't throw an exception if it is not found.</li>
+<li>magick/semaphore.c (AcquireSemaphoreInfo): Deprecated this
+internal function. Use AllocateSemaphoreInfo() and
+LockSemaphoreInfo() instead.
+(LiberateSemaphoreInfo): Deprecated this internal function. Use
+UnlockSemaphoreInfo() instead.</li>
+</ul>
+</blockquote>
+<p>2009-10-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>config/colors.mgk: Colors.mkg is now empty since it is used to
+modify or extend the built-in color lookup table.</li>
+<li>magick/{constitute.c,delegate.c,log.c,magic.c,magick.c,tempfile.c}:
+Explicitly initialize semaphores via InitializeMagick().</li>
+<li>magick/type.h: New header file to contain types and function
+prototypes for functions in type.c.</li>
+<li>magick/color_lookup.c (ReadColorConfigureFile): Store RGB color
+table in a static struct. Entries in the colors.mgk file are now
+used to modify statically-defined entries, or add new definitions
+to the color table.</li>
+</ul>
+</blockquote>
+<p>2009-10-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: --enable-libtool-verbose configure option is no
+longer needed now that we have silent build capability.</li>
+</ul>
+</blockquote>
+<p>2009-10-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GenerateEXIFAttribute): Add support for
+retrieving GPS EXIF attributes. Based on work contributed by
+Jukka Manner.</li>
+<li>Magick++/lib/STL.cpp, Magick++/lib/Magick++/STL.h (shadeImage):
+ShadeImage was the result of a botched cut-and-paste. Corrected
+now. Thanks to Jukka Manner for making me aware of this.</li>
+</ul>
+</blockquote>
+<p>2009-10-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/analyze.c: New source file to contain image analysis
+functions. Moved functions from image.c and color.c to this file.</li>
+<li>magick/color_lookup.c: New source file to contain color lookup
+functions. Moved associated functions from color.c to this file.</li>
+<li>magick/ImageMagick.rc: Remove inclusion of magic.mgk.</li>
+<li>magick/utility.c (MagickRoundUpStringLength): Use a bit less
+memory.</li>
+<li>magick/color.c: Use most efficient string allocation function.</li>
+<li>config/Makefile.am: Eliminate use of magic.mgk.</li>
+<li>magick/magic.c: Store file header magic data in a static struct.</li>
+</ul>
+</blockquote>
+<p>2009-10-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/describe.c (DescribeImage): Include composition operator
+in verbose output. Also use CompressionTypeToString() to convert
+a compression enum to a string.</li>
+</ul>
+</blockquote>
+<p>2009-10-11 Toby Thain &lt;<a class="reference external" href="mailto:qu1j0t3&#37;&#52;&#48;users&#46;sourceforge&#46;net">qu1j0t3<span>&#64;</span>users<span>&#46;</span>sourceforge<span>&#46;</span>net</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c: Further fix for 2783535 reported by Daniel Kirsch.
+Omit 0x0 layers from the image list, or they break compositing.</li>
+</ul>
+</blockquote>
+<p>2009-10-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/xwindow.c: Check for overflow on all array allocations.</li>
+<li>magick/command.c (MogrifyImages): If there is only one image in
+the list, then -flatten does nothing at all.</li>
+<li>magick/transform.c (FlattenImages): If the user provides only
+one image then return a clone of that image rather than reporting
+an error.</li>
+<li>magick/texture.c (TextureImage): If an under-texture is applied,
+then remove the matte channel.</li>
+<li>magick/xwindow.c (MagickXMakeImage): Apply a checkerboard
+pattern when displaying non-opaque TrueColor images. Fix a second
+integer overflow issue related to CVE-2009-1882.</li>
+</ul>
+</blockquote>
+<p>2009-10-10 Toby Thain &lt;<a class="reference external" href="mailto:qu1j0t3&#37;&#52;&#48;users&#46;sourceforge&#46;net">qu1j0t3<span>&#64;</span>users<span>&#46;</span>sourceforge<span>&#46;</span>net</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c: Fix for 2783535 reported by Daniel Kirsch. PSD
+parser was confused by 0x0 pixel layers, resulting in image data
+corruption of all following layers.</li>
+</ul>
+</blockquote>
+<p>2009-10-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/xwindow.c (MagickXMakeImage): Fix for CVE-2009-1882
+&quot;Integer overflow in the XMakeImage function&quot;. The problem is
+that the shared memory segment allocated may be smaller than the
+image size requires due to integer overflow. On some systems it
+may be possible to crash GraphicsMagick (while displaying an image
+file) but not likely to overwrite the heap since shared memory
+segments are outside of the heap allocation.</li>
+<li>magick/memory.c (MagickMallocArray): Use MagickArraySize().</li>
+<li>magick/memory.c (MagickArraySize): New private function to
+compute the size of an array and return zero if it overflows the
+size_t type.</li>
+</ul>
+</blockquote>
+<p>2009-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcm.c (ReadDCMImage): Handle (UN)known type VRs correctly
+and interpret the transfer syntax correctly. Added define
+&quot;dcm:avoid-scaling&quot; to request that the coder should not scale
+image samples unless necessary (i.e. when bits used &gt; quantum
+depth or maximum colormap depth, depending on image type). Work
+is contributed by John Sergeant.</li>
+</ul>
+</blockquote>
+<p>2009-10-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am (CHECK_PDF_FILE_COMPRESS): Add PDF tests with
+the various compression options.</li>
+<li>coders/pdf.c (WritePDFImage): If the input file used JPEG
+compression and has not been converted to a bilevel or palette
+image, then use JPEG compression with original settings. Problem
+was reported by Marco Atzeri.</li>
+</ul>
+</blockquote>
+<p>2009-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>config/modules.mgk: DCRAW module entries were missing.</li>
+<li>coders/tiff.c (WriteGROUP4RAWImage): Was not working properly on
+big-endian CPUs with libtiff 1.4.</li>
+<li>coders/ps2.c (WritePS2Image): Use ImageToJPEGBlob().</li>
+<li>coders/ps3.c (WritePS3Image): Use ImageToJPEGBlob().</li>
+<li>coders/pdf.c (WritePDFImage): Decouple from libtiff. Use ImageToJPEGBlob().</li>
+<li>coders/dcraw.c (RegisterDCRAWImage): Needed to register module
+name.</li>
+<li>coders/cals.c (ReadCALSImage): Fix bug in CALS reader which
+caused reading images taller than the image width to fail with an
+error.</li>
+<li>magick/utility.c (AcquireString): Minor optimizations.
+(AllocateString): Minor optimizations.
+(CloneString): Minor optimizations.
+(LocaleCompare): Minor optimizations.
+(SubstituteString): Re-implemented in a more compact way which
+might avoid some reallocations.</li>
+<li>magick/magick.c (ListModuleMap): Don't crash if <cite>module</cite> was not
+set.</li>
+<li>magick/delegate.c (ListDelegateInfo): Fix insignificant memory
+leak.</li>
+<li>magick/compress.c (ImageToJPEGBlob): Preserve JPEG settings if
+feasable.</li>
+</ul>
+</blockquote>
+<p>2009-09-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c (WritePDFImage): Use ImageToHuffman2DBlob() and
+ImageToJPEGBlob().</li>
+<li>coders/cals.c (WriteCALSImage): Use ImageToHuffman2DBlob().</li>
+<li>magick/compress.c (ImageToHuffman2DBlob): New private
+convenience function to produce a CCIT Group4 blob.
+(ImageToJPEGBlob): New private convenience function to produce a
+JPEG blob.</li>
+</ul>
+</blockquote>
+<p>2009-09-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (ReadJP2Image): Fix scaling problem noticed when
+reading 12-bit JP2 format. Problem was reported by Steve Shaw.
+(WriteJP2Image): Support writing JP2 files with arbitrary depth
+ranging from 2 to 16 rather than just 8 or 16.</li>
+</ul>
+</blockquote>
+<p>2009-09-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/unix_port.c (MagickGetMMUPageSize): Cache returned page
+size to eliminated repeated system calls.</li>
+<li>magick/operator.c (QuantumOperatorRegionImage): Fix missing
+percent in progress monitor message.</li>
+</ul>
+</blockquote>
+<p>2009-09-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c (GetIPTCStream): Should return IPTC block length
+rather than remaining blob length. Patch submitted by John
+Sergeant.</li>
+</ul>
+</blockquote>
+<p>2009-09-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c (GetIPTCStream): IPTC blobs should be padded to an
+even size. Patch submitted by John Sergeant.</li>
+</ul>
+</blockquote>
+<p>2009-09-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteGROUP4RAWImage): Added a GROUP4RAW encoder.</li>
+<li>coders/cals.c (Huffman2DEncodeImage): Fix test failures when
+doing I/O to an in-memory blob.</li>
+<li>coders/pcl.c (WritePCLImage): Use a different control code to
+(hopefully) eject the page. Patch submitted by John Sergeant.</li>
+</ul>
+</blockquote>
+<p>2009-09-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am: Add CALS tests. Skip testing deep images for
+most formats which don't support deep images.</li>
+<li>coders/cals.c: CALS module was not being built under Windows
+with MSVC. Now it is.</li>
+<li>VisualMagick/configure/configure.cpp (process_library): CALS
+module is dependent on TIFF library.</li>
+<li>coders/cals.c (WriteCALSImage): Allow CALS writing at any time,
+but only enable CALS reader if libtiff is present at build time.</li>
+<li>coders/{cals.c,pdf.c,ps2.c,ps3.c} (Huffman2DEncodeImage): Force
+TIFF image type to bilevel type.</li>
+<li>config/modules.mgk, VisualMagick/bin/modules.mkg: CAL--&gt;CALS
+rather than CALS--&gt;CAL.</li>
+</ul>
+</blockquote>
+<p>2009-09-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/benchmarks.rst: Updated GraphicsMagick vs ImageMagick
+benchmark results.</li>
+</ul>
+</blockquote>
+<p>2009-09-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/cals.c (WriteCALSImage): Initial CALS Type 1 writer
+implementation. Contributed by John Sergeant.</li>
+<li>coders/png.c (ReadOnePNGImage): Fresh pixels should be set using
+SetImagePixels().</li>
+</ul>
+</blockquote>
+<p>2009-09-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Released GraphicsMagick 1.3.7.</li>
+</ul>
+</blockquote>
+<p>2009-09-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/msl.c, doc/conjure.imdoc: Add support for a new <cite>profile</cite>
+command in MSL/conjure which applies, adds, or removes one or more
+IPTC, ICC or generic profiles from a file. Work contributed by
+John Sergeant.</li>
+</ul>
+</blockquote>
+<p>2009-09-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (NTGhostscriptFind): Make sure we close the
+registry key. Log any Windows error messages.</li>
+<li>magick/profile.c (AppendImageProfile): New function to add or
+append a profile. If the profile already exists, then the data
+provided is appended to it.</li>
+<li>coders/jpeg.c (ReadGenericProfile,ReadICCProfile,ReadIPTCProfile):
+Profile chunks need to be concatenated. Otherwise &quot;chunked&quot;
+profiles become corrupted.</li>
+</ul>
+</blockquote>
+<p>2009-09-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/average.c (AverageImages): Moved from image.c to new
+average.c file.</li>
+<li>magick/colormap.h (VerifyColormapIndex): Moved here from color.h</li>
+<li>magick/colormap.c (AllocateImageColormap): Moved from image.c to
+new colormap.c source file.
+(CycleColormapImage): Moved from image.c.
+(ReplaceImageColormap): Moved from image.c.
+(SortColormapByIntensity): Moved from image.c.
+(MagickConstrainColormapIndex): Moved here from color.c.</li>
+<li>magick/describe.c (DescribeImage): Moved from image.c to new
+describe.c source file.</li>
+<li>magick/plasma.c (PlasmaImage): Moved from image.c to new
+plasma.c source file.</li>
+<li>magick/statistics.c (GetImageStatistics): Moved from image.c to
+new statistics.c source file.</li>
+<li>magick/gradient.c (GradientImage): Moved from image.c to new
+gradient.c source file.</li>
+<li>magick/texture.c (ConstituteTextureImage,TextureImage): Moved to
+new texture.c source file.</li>
+<li>coders/svg.c (ENABLE_SVG_WRITER): Disable SVG writer by default
+since it usually does not work correctly and is unlikely to work
+correctly any time soon.</li>
+</ul>
+</blockquote>
+<p>2009-09-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c (ProfileImage): GlobExpression is case
+sensitive so assure that its glob strings are always upper-cased.
+Without this fix, lower-cased arguments like &quot;icm&quot; would fail to
+be removed. This would not be much of a problem except that the
+documentation claims that lower-case works.
+(SetImageProfile): Assure that profile names are upper-cased.</li>
+<li>magick/fx.c (ColorMatrixImage): Add opaque opacity channel if
+image currently lacks an opacity channel but the matrix updates
+the opacity channel. Requested by Kerry Panchoo.</li>
+</ul>
+</blockquote>
+<p>2009-09-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c (GetIPTCStream): Updates from John.Sergeant to fix
+issues with IPTC record 2 blocks and to deal better with IPTC
+embedded in an 8BIM profile.</li>
+<li>PerlMagick/t/read.t: Added tests for Topol format.</li>
+</ul>
+</blockquote>
+<dl class="docutils">
+<dt>2009-09-12 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</dt>
+<dd><ul class="first last simple">
+<li>coders/topol.c: Pallette overflow fixed for subtype 3.</li>
+</ul>
+</dd>
+</dl>
+<p>2009-09-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/tests/msl_composite.sh: Use a draw command file for
+this test script too.</li>
+<li>utilities/tests/{black-threshold.sh,draw.sh,recolor.sh,
+white-threshold.sh}: MSYS is sometimes wreaking havoc on arguments
+with spaces in them so use work-arounds.</li>
+</ul>
+</blockquote>
+<p>2009-09-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (NTGhostscriptFind): Improve logging messages
+when searching for Ghostscript.</li>
+</ul>
+</blockquote>
+<p>2009-09-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (CacheInfo): Add read_only member to
+indicate if cache is allowed to be modified.
+(ModifyCache): Clone cache if origin cache is read only.
+(PersistCache): Persistent caches which are attached are treated
+as read-only. This avoids crash with MPC images which are read
+and subsequently modified.
+Reverted pixel cache locking changes which were made yesterday
+since I decided that they were too risky until file handle
+management is addressed.</li>
+</ul>
+</blockquote>
+<p>2009-09-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (InitializeMagickResources): Increase
+operating system file handle limits if necessary.</li>
+<li>magick/pixel_cache.c: Pixel cache file locking is now done at
+point of access.</li>
+<li>magick/nt_base.c (NTGhostscriptFind): New function to find
+Ghostscript under Windows, replacing previous Ghostgum
+implementation.</li>
+<li>Copyright.txt: License is now based on MIT license exactly,
+without extra edits. Ghostgum code has been eliminated so it is
+no longer necessary to include its license.</li>
+</ul>
+</blockquote>
+<p>2009-09-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/delegate.c (GetPostscriptDelegateInfo): Add a gs-palette
+delegate entry in order to force Ghostscript to output a
+colormapped image if <cite>-type palette</cite> is specified prior to the
+input filename. Ghostscript's dithering is much courser than
+GraphicsMagick's -colors default (more similar to
+-ordered-dither), but it is fast and produces smaller intermediate
+files.</li>
+<li>coders/ps.c (ReadPSImage): Eliminate use of NULL pointer when
+progress monitor is enabled. Was referring to image-&gt;filename
+rather than image_info-&gt;filename as it should have.</li>
+<li>magick/delegate.c (InvokePostscriptDelegate): Added an
+<cite>exception</cite> argument so that failure details can be returned.
+Tried to reorganize the code so that it is more tolerant of errors
+such as a dynamically-loadable DLL failing to load. On POSIX
+systems, Ghostscript was not being invoked as securely as
+expected.</li>
+<li>coders/Makefile.am: Only build the DPS module if the Display
+Postscript library is available.</li>
+<li>coders/ept.c (ReadEPTImage): If we don`t have the Display
+Postscript library, then don't try to use it as a fallback.</li>
+<li>coders/ps.c (ReadPSImage): If we don't have the Display
+Postscript library, then don't try to use it as a fallback.</li>
+<li>magick/blob.c (CloseBlob): If blob was never allocated, then
+don't try to close it.</li>
+</ul>
+</blockquote>
+<p>2009-09-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/index.rst: Mention 1.2.8 release.</li>
+</ul>
+</blockquote>
+<p>2009-09-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++: New Image methods cdl(), colorMatrix(), and haldClut()
+added.</li>
+</ul>
+</blockquote>
+<p>2009-09-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c (IntegralRotateImage): Select tile sizes in a
+more intelligent fashion.</li>
+<li>magick/pixel_cache.c (GetPixelCacheInCore): New private pixel
+cache method to see if image pixels are in core.</li>
+</ul>
+</blockquote>
+<p>2009-09-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ReadImage): No longer clear the exception
+at the start of ReadImage() and other similar functions. If the
+user of the function cares, she can clear the exception in
+advance. It is not right to overwrite exceptions which might not
+have been reported/handled yet.</li>
+<li>magick/shear.c (IntegralRotateImage): Rotate by zero degrees
+does not need to do any work.</li>
+<li>coders/*.c, magick/*.c: Include image dimensions in progress
+monitor output when loading or saving a file. Eliminate redundant
+text from progress messages.</li>
+</ul>
+</blockquote>
+<p>2009-08-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c: Eliminate memory leaks.</li>
+<li>magick/render.c (DrawDashPolygon): Avoid access beyond end of
+array. Resolves SourceForge issue 2832125 &quot;Crash on SVG
+conversion&quot;.</li>
+<li>coders/png.c (ReadOnePNGImage): Ensure that opacity channel is
+properly initialized. Resolves SourceForge issue 2831240
+&quot;Possible alpha channel issue with PNG w/palette and tRNS&quot;.</li>
+</ul>
+</blockquote>
+<p>2009-08-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.h (HAVE_TIFFSWABARRAYOFTRIPLES): Need to define
+this since libtiff includes this function now.</li>
+<li>VisualMagick/tiff/libtiff/tiffconf.h.in: Enable all the options
+by default.</li>
+<li>tiff: Updated to libtiff 3.9.1. 3.9.0 was broken.</li>
+</ul>
+</blockquote>
+<p>2009-08-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c (MagickFreeCMSTransform): Add a CMS transform
+destructor since otherwise Visual Studio does not like it.</li>
+<li>tiff: Updated to libtiff 3.9.0.</li>
+</ul>
+</blockquote>
+<p>2009-08-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (TimeImageCommand): Add a simple <cite>time</cite>
+sub-command to time the execution of any other GraphicsMagick
+sub-command. Similar in concept to the <cite>benchmark</cite> sub-command
+but produces output similar to the <cite>time</cite> command offered by the
+zsh command shell. Handy for when <cite>time</cite> is not available, or
+consistent output is desired.</li>
+<li>magick/magick.c (MagickGetFileSystemBlockSize): New private
+function to allow getting desired filesystem block size.
+(MagickSetFileSystemBlockSize): New private function to allow
+setting desired filesystem block size.</li>
+<li>magick/pixel_cache.c (WriteCacheIndexes, WriteCachePixels):
+Temporarily disable pixel cache row coalescing when writing to
+disk until we come up with a good way to optimize write sizes.</li>
+<li>coders/meta.c (ReadMETAImage): Fix memory leak of profile blob.</li>
+</ul>
+</blockquote>
+<p>2009-08-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/tests/icc-transform.sh: Add a sanity-test for applying
+ICC profiles.</li>
+<li>magick/profile.c (ProfileImage): Improve OpenMP performance.</li>
+</ul>
+</blockquote>
+<p>2009-08-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawPolygonPrimitive): Drawing of points,
+lines, and polygons is now accelerated using OpenMP with good
+speed-up.</li>
+</ul>
+</blockquote>
+<p>2009-08-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/drawing_wand.c (DrawClearException): New function to clear
+drawing wand exception.
+(DrawGetException): New function to retrieve information regarding
+the last drawing wand exception (if any).
+(DrawRender): DrawRender() is now deprecated since it requires an
+Image pointer to be embedded in the drawing wand. The image
+passed is subsequently lost by CloneDrawingWand() since it must
+clone the image using copy-on-write. Subsequent use of
+DrawRender() on a cloned wand scribbles on an image the user does
+not have access to. Use existing Wand function MagickDrawImage()
+instead.
+(DrawAllocateWand): DrawAllocateWand() is now deprecated since it
+requires passing an Image pointer into the drawing wand. Use
+existing DrawingWand function NewDrawingWand() instead.</li>
+</ul>
+</blockquote>
+<p>2009-08-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/drawing_wand.c (CloneDrawingWand): New function to
+deep-copy a drawing wand.
+(NewDrawingWand): Use a boolean flag to track if image is
+allocated by the wand, or by the user. Most of the previous
+DrawAllocateWand() code is moved into NewDrawingWand() so that the
+boolean flag is easy to manage.</li>
+</ul>
+</blockquote>
+<p>2009-08-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Support writing grayscale
+JPEG-compressed TIFF.</li>
+</ul>
+</blockquote>
+<p>2009-08-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Don't override the photometric
+for grayscale JPEG-compressed TIFF.</li>
+</ul>
+</blockquote>
+<p>2009-08-08 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>coders/png.c: Made compatible with libpng-1.4.0beta74 and later</dt>
+<dd>(won't work with libpng-1.4.0beta35 through beta73) due to change
+in names of png_struct members &quot;trans&quot; and &quot;trans_values&quot;).</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<dl class="docutils">
+<dt>2009-08-08 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</dt>
+<dd><ul class="first last simple">
+<li>coders/topol.c: Pallette is ignored for subtype 5 (RGB).</li>
+</ul>
+</dd>
+</dl>
+<p>2009-08-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/{cineon.c, dpx.c, locale.c, svg.c}, magick/{attribute.c,
+effect.c, utility.c}: Eliminate warnings reported by GCC 4.4.0.</li>
+</ul>
+</blockquote>
+<p>2009-07-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Try to be more insistent about compilation failure
+if libjpeg version is less than 6b. IRIX compiler only warns
+about #error preprocessor statement.</li>
+</ul>
+</blockquote>
+<p>2009-07-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickSetCompressionQuality): New Wand
+method to allow setting the compression quality.</li>
+</ul>
+</blockquote>
+<p>2009-07-29 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/topol.c: Fixed missing break. Added response to ping.</li>
+</ul>
+</blockquote>
+<p>2009-07-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pcx.c (ReadPCXImage): Detect improper rows, columns, or
+depth. Fixes CVE-2008-1097 &quot;Memory corruption in ImageMagick's
+PCX coder&quot;.</li>
+<li>configure.ac: Update to Autoconf 2.64.</li>
+</ul>
+</blockquote>
+<p>2009-07-25 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/topol.c: Fixed several issues. Added possibility to read
+TopoL level 2 images.</li>
+</ul>
+</blockquote>
+<p>2009-07-25 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagickconfigureconfigure.cpp: Fixed library absolute path issue.</li>
+</ul>
+</blockquote>
+<p>2009-07-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/random.c (DestroyMagickRandomGenerator): Trick to free
+thread specific random kernel contexts simply locks up with MSVC's
+OpenMP, so remove this functionality.</li>
+</ul>
+</blockquote>
+<p>2009-07-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/random.c (DestroyMagickRandomGenerator): Cleanup thread
+specific random kernel data.</li>
+<li>magick/tsd.c (MagickTsdKeyCreate): Fix glitch when built without
+any threads support.</li>
+</ul>
+</blockquote>
+<p>2009-07-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/benchmarks.rst: Update GraphicsMagick vs ImageMagick image
+processing benchmark results.</li>
+</ul>
+</blockquote>
+<p>2009-07-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/OpenMP.rst: Update performance measurements for readily
+available systems.</li>
+<li>NEWS.txt: Updated to reflect latest changes.</li>
+</ul>
+</blockquote>
+<p>2009-07-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Updated libpng to 1.2.38.</li>
+</ul>
+</blockquote>
+<p>2009-07-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GetImageInfo): Default interlace for ImageInfo
+is now UndefinedInterlace so that it is possible to preserve the
+original interlace setting for the image file. Code depending on
+the previous default setting of NoInterlace is adjusted to suit.
+This is a potentially risky change given the brittle nature of
+some of the legacy code.</li>
+<li>coders/tiff.c (ReadTIFFImage): Stripped reader needs to read
+planar TIFF plane-wise in order to work with libtiff's internal
+buffering.
+(ReadTIFFImage): Tiled reader needs to read planar TIFF plane-wise
+in order to work with libtiff's internal buffering.
+(WriteTIFFImage): Tiled writer needs to output planar TIFF
+plane-wise in order to work with libtiff's internal buffering.</li>
+</ul>
+</blockquote>
+<p>2009-07-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MontageUsage): Reconcile montage help output
+with actual montage options.</li>
+</ul>
+</blockquote>
+<p>2009-07-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Allow the user to be able to
+specify rows_per_strip when using JPEG compression. The
+rows_per_strip value rounded up to the nearest multiple of 16.</li>
+</ul>
+</blockquote>
+<p>2009-07-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Add the ability for the user to
+manually specify the predictor using syntax like <cite>-define
+tiff:predictor=2</cite>.</li>
+</ul>
+</blockquote>
+<p>2009-07-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/quantize.c (QuantizeImages): Avoid crash when using
+-monitor +map on an image list.</li>
+<li>magick/command.c (BenchmarkImageCommand): Send benchmark report
+to stderr so that it does not interfer with pipes.</li>
+<li>magick/cdl.c (CdlQuantum): Add range limiting of value before
+applying power function.</li>
+<li>coders/dpx.c (ReadDPXImage, WriteDPXImage): Using floating point
+calculations when building sample value lookup tables in order to
+decrease error. In particular input values were being scaled too
+low, resulting in improperly rounding down during processing of
+the image.</li>
+</ul>
+</blockquote>
+<p>2009-07-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c (WritePDFImage): Incorporated updates from John
+Sergeant to remove the font and thumbnail objects from PDF output.</li>
+</ul>
+</blockquote>
+<p>2009-07-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/cdl.c (CdlImage): New function to apply an ASC CDL
+transform to the image. Original implementation by Clément Follet
+from Workflowers but considerably re-worked by Bob Friesenhahn.
+Available as -asc-cdl via the <cite>convert</cite> and <cite>mogrify</cite> subcommands.</li>
+</ul>
+</blockquote>
+<p>2009-07-04 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/formats.rst: MAT module can read compressed files.
+Remove warning about unsupported compression.</li>
+</ul>
+</blockquote>
+<p>2009-07-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcm.c: Eliminate compiler warnings.</li>
+</ul>
+</blockquote>
+<p>2009-07-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcm.c: Significant re-write of the DICOM reader. Work
+contributed by John Sergeant.</li>
+</ul>
+</blockquote>
+<p>2009-07-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (OpenBlob): Subsequent research shows that Direct
+I/O will not be useful to ordinary file I/O due to specific
+requirements for buffer alignments and I/O sizes. Support for
+requesting it is removed.</li>
+</ul>
+</blockquote>
+<p>2009-07-01 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/formats.rst: ART module has writer for more than year.
+So mark this here.</li>
+</ul>
+</blockquote>
+<p>2009-06-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac, magick/blob.c: Add experimental Solaris direct I/O
+support which is enabled by setting the environment variable
+MAGICK_DIRECTIO to TRUE. Direct I/O bypasses the filesystem
+cache. Only works for NFS and UFS, and not for ZFS.</li>
+</ul>
+</blockquote>
+<p>2009-06-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>rungm.sh.in: Fix environment variable issues noticed while
+running the test suite under MinGW.</li>
+<li>Makefile.am (TESTS_ENVIRONMENT): Fix environment variable issues
+noticed while running the test suite under MinGW.</li>
+<li>magick/hclut.c (HaldClutImage): Don't convert Cineon Log to RGB.</li>
+</ul>
+</blockquote>
+<p>2009-06-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImageCommand): Cache mogrify argument
+images so that they are only loaded once when mogrify is used to
+process multiple image files.</li>
+<li>coders/dpx.c (WriteDPXImage): Fix leak of chroma image when
+subsampling to 4:2:2.</li>
+</ul>
+</blockquote>
+<p>2009-06-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (ExpandFilenames): Expand &#64;filename to a list
+of arguments.</li>
+</ul>
+</blockquote>
+<p>2009-06-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImageCommand): Fix memory leak of
+output_directory string buffer, if it was used.</li>
+<li>magick/utility.c (ExpandFilenames): Input wildcard file
+specifications with a subdirectory component such as
+&quot;subdir/*.dpx&quot; were not working.</li>
+</ul>
+</blockquote>
+<p>2009-06-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (InitializeMagick): Invoke InitializeMagickRegistry().</li>
+<li>magick/registry.c (RegistryInfo): There is no reason to expose
+the RegistryInfo structure in the public interface so it is moved
+to registry.c.
+(InitializeMagickRegistry): Add a function for initializing the
+magick registry.</li>
+</ul>
+</blockquote>
+<p>2009-06-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (CompareImageCommand): Report full error rather
+than rounded error in error reports since sometimes the value
+reported was rounded down to zero.</li>
+<li>utilities/tests/hald-clut-transform.sh: New test to verify that
+Hald CLUT interpolation is working perfectly.</li>
+<li>utilities/tests/hald-clut-identity.sh: Renamed from
+hald-clut.sh.</li>
+</ul>
+</blockquote>
+<p>2009-06-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (RegisterJPEGImage): Fix typo which caused IJG
+library version to be shown for &quot;JPG&quot; format but not for &quot;JPEG&quot;.
+Also use a more descriptive name for JPEG library.</li>
+<li>magick/image.c (DescribeImage): Filter out spurious EXIF
+attributes which already exist because we previously accessed
+them. We do a full EXIF dump later.</li>
+</ul>
+</blockquote>
+<p>2009-06-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/FAQ.rst: Add a FAQ about how to process many files at once.</li>
+</ul>
+</blockquote>
+<p>2009-06-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Reduce usage of deprecated Autoconf macros.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Set image orientation from EXIF
+Orientation tag if it is present.</li>
+<li>www/formats.rst: Add TopoL format as per Jaroslav Fojtik.</li>
+</ul>
+</blockquote>
+<p>2009-06-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: User provided LDFLAGS was being overwritten under
+Solaris.</li>
+<li>Many files: Additional reduction of shadowing warnings.</li>
+</ul>
+</blockquote>
+<p>2009-06-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): Fix leak of the entire mask
+image supplied via -mask.</li>
+<li>utilities/tests/mask.sh: Add a test for applying a mask image
+with -mask.</li>
+</ul>
+</blockquote>
+<p>2009-06-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GenerateEXIFAttribute): Identify unknown
+tags via their four-character hex value.</li>
+<li>magick/colorspace.c (CMYKToRGBTransform): Use symbolic notation
+to access pixel quantum values.</li>
+<li>utilities/tests/identify.sh: Added a test for <cite>identify
+-verbose</cite> on a well-populated JPEG file.</li>
+<li>PerlMagick/t/{jpeg/write.t, jng/read.t, jng/write.t}: Relax
+allowed error for JPEG-related tests.</li>
+<li>magick/attribute.c (GenerateEXIFAttribute): Attribute allocation
+size was too small causing overrun of memory buffer. Problem was
+added on 2009-06-08.</li>
+<li>magick/image.c (AllocateDepthMap): Allocation size was one
+element too small.
+(GetImageDepth): Forgot to free depth map. Memory leak of 64K
+bytes per iteration.</li>
+</ul>
+</blockquote>
+<p>2009-06-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/{mat.c, miff.c, pdf.c, ps3.c}: Have Zlib use our memory
+allocators.</li>
+<li>magick/memory.c (MagickMallocCleared): New memory allocation
+interface which is similar to MagickMalloc() except that returned
+memory has been cleared first.</li>
+<li>magick/hclut.c (HaldClutImagePixels): Fix wrong accesses
+detected by valgrind. Also improve execution performance.</li>
+<li>coders/xwd.c (WriteXWDImage): Fixed valgrind memcheck complaint
+about access to uninitialized data.</li>
+</ul>
+</blockquote>
+<p>2009-06-09 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c Handle alpha channel for ImageMagick's alternative .txt</li>
+</ul>
+</blockquote>
+<p>2009-06-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteDPXImage): Fixed valgrind memcheck complaint
+about access to uninitialized data.</li>
+<li>magick/attribute.c (GenerateEXIFAttribute): For EXIF STRING,
+output unprintable characters using three-digit octal notation.</li>
+<li>coders/dpx.c (WriteDPXImage): Assure that offset count is
+correct according to reported bytes written.</li>
+<li>utilities/tests/hald-clut.sh: Add a simple identity test for the
+Hald CLUT support.</li>
+</ul>
+</blockquote>
+<p>2009-06-07 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c Handle alpha channel for ImageMagick's .txt</li>
+</ul>
+</blockquote>
+<p>2009-06-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/hclut.c (HaldClutImage): Add a Hald CLUT capability as
+described at <a class="reference external" href="http://www.quelsolaar.com/technology/clut.html">http://www.quelsolaar.com/technology/clut.html</a>. This
+allows a color transformation to be easily created and replicated
+on any number of images. The algorithm is accessed by the
+-hald-clut option of <cite>convert</cite> and <cite>mogrify</cite>. The original
+algorithm is by Eskil Steenberg and was adapted for GraphicsMagick
+by Clément Follet from Workflowers with support from Cédric
+Lejeune of Workflowers.</li>
+</ul>
+</blockquote>
+<p>2009-06-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetMagickGeometry): Support <cite>^</cite> modifier to
+geometry specification which indicates that specified size is a
+minimum bounding box rather than a maximum bounding box while
+preserving the image aspect ratio.</li>
+</ul>
+</blockquote>
+<p>2009-06-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (ListMagickResourceInfo): If supporting
+OpenMP, then include a &quot;Threads&quot; limit in the output of <cite>-list
+resource</cite>.</li>
+<li>coders/pnm.c (ReadPNMImage): Fix multi-thread issue detected by
+valgrind's helgrind tool. Diminish compilation warnings.</li>
+<li>coders/dpx.c (ReadDPXImage): Diminish compilation warnings.</li>
+<li>magick/random.c (AcquireMagickRandomKernel): Fix potential
+multi-thread issue detected by valgrind's helgrind tool.</li>
+<li>magick/magick.c (InitializeMagick): Semaphore subsystem needs to be
+initialized before anything which uses it.</li>
+<li>magick/semaphore.c (InitializeSemaphore): Since we are using
+PTHREAD_MUTEX_INITIALIZER to initialize primary POSIX mutex in the
+semaphore subsystem, we should not explicitly initialize the
+semaphore a second time.</li>
+<li>magick/segment.c (Classify): Fix multi-thread issue detected by
+valgrind's helgrind tool.</li>
+<li>magick/render.c (DrawAffineImage): Use InterpolateViewColor() to
+evalute a bi-linear interpolated point rather than obtaining a
+pixel value from a close pixel. This provides better results.</li>
+</ul>
+</blockquote>
+<p>2009-06-02 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c Attempt to handle alpha channel.</li>
+</ul>
+</blockquote>
+<p>2009-06-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (InterpolateViewColor, InterpolateColor):
+Moved from gem.c. Gem functions should not be accessing the pixel
+cache.</li>
+</ul>
+</blockquote>
+<p>2009-06-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (CompareImageCommand): Add a -maximum-error
+option to <cite>compare</cite> so that it can easily be used in boolean logic
+when comparing images.</li>
+</ul>
+</blockquote>
+<p>2009-05-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am (TESTS_XFAIL_TESTS): If Ghostscript is not
+available then XFAIL the tests which depend on it.</li>
+<li>magick/pixel_cache.c (GetCacheInfo): Assure that allocated
+stuctures do not occupy the same cache lines.</li>
+</ul>
+</blockquote>
+<p>2009-05-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h (MAGICK_CACHE_LINE_SIZE): Allow cache line size
+to be set in one place in case we want to configure for it later.</li>
+<li>magick/effect.c (AllocateMedianList): Assure that allocated
+stuctures do not occupy the same cache lines.</li>
+<li>magick/random.c (AcquireMagickRandomKernel): Assure that
+allocated random kernels do not occupy the same cache lines.</li>
+<li>magick/gem.c (GenerateDifferentialNoise): User is required to
+supply random kernel.</li>
+<li>doc/options.imdoc: Document -format &quot;%p&quot;. Problem was reported
+by Stijn Sanders.</li>
+</ul>
+</blockquote>
+<p>2009-05-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/Makefile.am (coders_tiff_la_LIBADD): Libtiff may now also
+depend on libjbig and the math library.</li>
+<li>doc/gmdoc2html: Fix link to ball.png. Problem was reported by
+Wes Fox.</li>
+<li>VisualMagick/installer/inc/files-documentation.isx: Include Wand
+API documentation.</li>
+<li>VisualMagick/installer/inc/icons-associate.isx: Fix Windows
+Start menu link to web pages.</li>
+<li>configure.ac: --with-perl is changed to --without-perl since
+building PerlMagick is no longer the default. Building PerlMagick
+automatically has caused too many problems.</li>
+<li>PerlMagick/Makefile.am: GraphicsMagick no longer automatically
+installs PerlMagick. Use the procedure described by
+PerlMagick/README.txt to build and install PerlMagick.</li>
+</ul>
+</blockquote>
+<p>2009-05-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Debian stores Ghostscript fonts under
+/usr/share/fonts/type1/gsfonts so check there for fonts. Issue
+reported by Ralf Wildenhues.</li>
+</ul>
+</blockquote>
+<p>2009-05-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Fix Ping of blob.</li>
+<li>PerlMagick/t/ping.t: Added tests for pinging files and blobs.</li>
+<li>www/perl.rst: Ping blob syntax is like $image-&gt;Ping(blob=&gt;&#64;blob).</li>
+<li>PerlMagick/Makefile.PL.in: Increase the probability of
+PerlMagick build success by using the user-specified C compiler as
+the linker if the C compiler was already used as the linker. This
+helps if the C compiler used to build GraphicsMagick is a more
+recent vintage than the one used to build Perl.</li>
+<li>PerlMagick/t/wmf/read.t: Test needs to be more lenient for
+Linux.</li>
+<li>Makefile.am (TESTS_ENVIRONMENT): Pass a complete text
+environment so that we don't need to execute rungm.sh in order to
+run the test suite.</li>
+</ul>
+</blockquote>
+<p>2009-05-25 Ralf Wildenhues &lt;<a class="reference external" href="mailto:Ralf&#46;Wildenhues&#37;&#52;&#48;gmx&#46;de">Ralf<span>&#46;</span>Wildenhues<span>&#64;</span>gmx<span>&#46;</span>de</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Define PACKAGE_STRING.</li>
+</ul>
+</blockquote>
+<p>2009-05-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/tempfile.c (ComposeTemporaryFileName): Use new random
+number generator.</li>
+<li>magick/random.c: Implement a random number generation system
+based on George Marsaglia's multiply-with-carry generator.
+Somewhat slower than rand() but produces better random numbers
+with a period &gt;2^60. Suggested by Mark Mitchell.</li>
+</ul>
+</blockquote>
+<p>2009-05-24 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul>
+<li><p class="first">coders/txt.c Small optimization:</p>
+<p>Before: 2000 iter 34.08s user 34.24s total 58.420 iter/s</p>
+<p>After: 2000 iter 21.55s user 21.76s total 91.891 iter/s</p>
+</li>
+</ul>
+</blockquote>
+<p>2009-05-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (XFAIL_TESTS): Handle the case where FreeType is not
+available by marking tests dependent on FreeType as XFAIL.
+(TESTS): Reorder TESTS so that there will be no trailing spaces
+since this confuses certain older versions of GNU make.</li>
+</ul>
+</blockquote>
+<p>2009-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/tempfile.c (ComposeTemporaryFileName): Use simpler code
+(suggested by Mark Mitchell) to compute the substitution index.
+(AcquireTemporaryFileDescriptor): Try harder to generate a
+successful temporary file and fall through to alternative
+implementations if the first does not succeed.</li>
+<li>magick/magick.c (InitializeMagick): Use MagickRandNewSeed() to
+seed the default random number generator.</li>
+<li>magick/utility.c (MagickRandNewSeed): Include PID in random
+number seed generation.</li>
+</ul>
+</blockquote>
+<p>2009-05-22 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>coders/txt.c Fixed char vs int parameter problem.</dt>
+<dd>Better detection of too dark 16bit or 32bit images.</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2009-05-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (AUTOMAKE_OPTIONS): Enable parallel-tests and
+color-tests options. Parallel test execution does not pass tests
+yet.</li>
+<li>PerlMagick/PerlMagickCheck.sh.in: Run PerlMagick tests via a
+normal check script rather than a check hook.</li>
+<li>coders/identity.c (ReadIdentityImage): Fix compilation with Sun
+compiler.</li>
+</ul>
+</blockquote>
+<p>2009-05-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwfile.c: Allow the user to specify the basename for
+temporary files.</li>
+<li>tests/Makefile.am: Add a set of TXT read/write tests. Pass the
+file name specification to use for the rwfile-based tests.</li>
+</ul>
+</blockquote>
+<p>2009-05-21 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c Fixed endian set to native endian.</li>
+</ul>
+</blockquote>
+<p>2009-05-20 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c Faster read ImageMagick files.
+Removed BImgBuff=NULL;</li>
+</ul>
+</blockquote>
+<p>2009-05-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c (WriteTXTImage): Ensure that image depth is 8, 16,
+or 32.</li>
+<li>www/formats.rst: Add CALS to formats list.</li>
+<li>coders/cals.c (RegisterCALSImage): Consolidate duplicate text
+strings.</li>
+</ul>
+</blockquote>
+<p>2009-05-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/cals.c: Add support for reading CALS type 1 format.
+Contributed by John Sergeant.</li>
+<li>coders/identity.c: New coder to return a Hald identity CLUT
+image.</li>
+</ul>
+</blockquote>
+<p>2009-05-19 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c Ability to read back Q32 txt files.</li>
+</ul>
+</blockquote>
+<p>2009-05-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Support Linux style silent build rules.</li>
+</ul>
+</blockquote>
+<p>2009-05-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Updated to Automake 1.11.</li>
+</ul>
+</blockquote>
+<p>2009-05-17 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c First attempt to read back txt file.
+It is amazingly ineffective, but it seems to work.</li>
+</ul>
+</blockquote>
+<p>2009-05-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (HorizontalFilter, VerticalFilter): When
+resizing a non-opaque image, attenuate the influence of
+surrounding colors based on their degree of transparency in order
+to avoid &quot;halos&quot; around objects caused by colors which are
+transparent and therefore not part of the visible image. Patch
+contributed by Pavel Merdin via SourceForge Tracker #2792322.
+(VerticalFilter, VerticalFilter): Additional clean-up and
+optimizations.</li>
+</ul>
+</blockquote>
+<p>2009-05-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): Added a -recolor command option
+to provide access to ColorMatrixImage().</li>
+<li>magick/fx.c (ColorMatrixImage): New function to apply a color
+matrix similar to Adobe Flash Flash.filters.colorMatrixFilter(),
+and Windows GDI+ ColorMatrix class, (order up to 5x5) to the image
+pixels.</li>
+</ul>
+</blockquote>
+<p>2009-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/perl.rst: Add missing PerlMagick debug event types.</li>
+<li>coders/pcl.c: Major improvements from John Sergeant. These
+include: 1) Fixed 2 bit output where Max=BLACK - this always
+produced negative images even when -negate was passed as a
+parameter. The code now uses a two element palette to handle this
+situation. 2) Added support for 8 bit pseudoclass images. 3)
+Changed the coder to allow adjoin, placing each sub-image on a new
+page. 4) Added support for compression. Any compression other
+than &quot;None&quot; will cause the coder to to try to calculate and pick
+the best out of the PCL set of RLE, Tiff RLE or delta compression
+on a per row basis, as well as handling repeated rows and zero
+rows intelligently.</li>
+</ul>
+</blockquote>
+<p>2009-05-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>utilities/Makefile.am (MAGICKPROGRAMS): Add a <cite>compare</cite>
+ImageMagick compatibility link.</li>
+<li>INSTALL-unix.txt: Apply patch regarding GnuWin32 from John Wye,
+SourceForge #2779009.</li>
+</ul>
+</blockquote>
+<p>2009-05-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Add the LDFLAGS option -Wl,-zlazyload when using
+the Solaris linker.</li>
+</ul>
+</blockquote>
+<p>2009-05-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/url.c (ReadURLImage): Fix typos.</li>
+</ul>
+</blockquote>
+<p>2009-05-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (SystemCommand): Added access confirmation
+checks for external commands.</li>
+<li>magick/unix_port.c (MagickSpawnVP): Added access confirmation
+checks for external commands.</li>
+<li>coders/url.c (ReadURLImage): Added access confirmation checks
+for URLs.</li>
+<li>magick/blob.c: Added access confirmation checks for files.</li>
+<li>magick/confirm_access.c (MagickConfirmAccess): Added an access
+confirmation facility to allow the API user to monitor and/or
+block access to files and URLs. This allows the API user to
+implement a security policy based on actual accesses.</li>
+</ul>
+</blockquote>
+<p>2009-05-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Updated libpng to 1.2.35.</li>
+<li>lcms: Updated lcms to 1.18a.</li>
+</ul>
+</blockquote>
+<p>2009-05-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage and WriteOneJNGImage): Changed
+internal attribute png_bit_depth to png:bit-depth-written to avoid
+confusion with planned new public png:bit-depth attribute.</li>
+</ul>
+</blockquote>
+<p>2009-04-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImages): Deal slightly better with the
+case when MogrifyImage() expands one image into several. Still
+don't know of a sane way to deal with -crop WIDTHxHEIGHT.</li>
+<li>magick/transform.c (TransformImage): Image which is updated may
+be a list so account for that.</li>
+<li>configure.ac: Add a test for the <cite>restrict</cite> keyword so that
+eventually we can use it.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Tidy JPEG reader by moving JPEG
+properties analysis code into subroutines.</li>
+</ul>
+</blockquote>
+<p>2009-04-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/display.imdoc: Fix documentation for crop and chop keyboard
+accelerators. Fixes SourceForge bug #2593388 &quot;error in the
+documentation/Keyboard accelarators&quot;.</li>
+</ul>
+</blockquote>
+<p>2009-04-20 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Cosmetic-only, change <cite>True</cite> to <cite>MagickTrue</cite> or
+<cite>MagickPass</cite> and <cite>False</cite> to <cite>MagickFalse</cite> or <cite>MagickFail</cite>.</li>
+</ul>
+</blockquote>
+<p>2009-04-20 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Check error return from CompressColormapTransFirst()</li>
+</ul>
+</blockquote>
+<p>2009-04-20 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Refrain from modifying image struct members
+(matte, colors, depth) while writing a PNG.</li>
+</ul>
+</blockquote>
+<p>2009-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Document the direction of rotation.</li>
+</ul>
+</blockquote>
+<p>2009-04-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c (LogMagickEventList): Use MagickPackageName from
+version.h rather than hard-coding <cite>GraphicsMagick</cite>.</li>
+</ul>
+</blockquote>
+<p>2009-04-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: Fixed a warning about <cite>shadowed</cite> variables.</li>
+</ul>
+</blockquote>
+<p>2009-04-17 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Fixed some warnings about <cite>shadowed</cite> variables.</li>
+</ul>
+</blockquote>
+<p>2009-04-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Add tests for some reentrant versions of functions
+where we are still using the non-rentrant versions.</li>
+<li>magick/composite.c (CompositeImage): Fix problem with
+compositing images where the change image overlaps off the left
+side of the canvas. Should fix SourceForge issue #2766200 <cite>memory
+allocation error when compositing small images</cite>.</li>
+</ul>
+</blockquote>
+<p>2009-04-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/semaphore.c: Re-arrange ifdefs so that it is possible to
+use pthreads under the WIN32 API.</li>
+</ul>
+</blockquote>
+<p>2009-04-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/bit_stream.c: Bitstream functions were often not inlining
+and inline functions which don't inline are not much use.
+Bitstream functions are now normal library functions.</li>
+</ul>
+</blockquote>
+<p>2009-03-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/bin/delegates.mgk: Remove bounding box option (-g) from
+Postscript delegate specifications.</li>
+<li>config/delegates.mgk.in: Remove bounding box option (-g) from
+Postscript delegate specifications.</li>
+<li>coders/{ept.c, pdf.c, ps.c} : PDF bounding box is sometimes
+incorrect or not globally applicable so don't specify bounding box
+when reading PDF files. Postscript files do need the bounding box
+so make sure that it is still supplied. Resolves SF tracker issue
+2487651 <cite>convert from pdf chops off rhs</cite>.</li>
+</ul>
+</blockquote>
+<p>2009-03-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Magick++/Image.rst: Translate Image.html to reStructuredText
+format for easier maintenance.</li>
+</ul>
+</blockquote>
+<p>2009-03-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/rgb.c: Compute the quantum type rather than using a
+recurring conditional statement. It turns out that the -endian
+option is working as it should.</li>
+</ul>
+</blockquote>
+<p>2009-03-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/{gray.c, rgb.c, cymk.c}: Work toward supporting the
+-endian option. Not working properly yet.</li>
+<li>magick/enum_strings.c (EndianTypeToString): New function.
+(InterlaceTypeToString): New function.</li>
+</ul>
+</blockquote>
+<p>2009-03-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/drawing_wand.c: Stripped out unused code.</li>
+<li>www/wand: Added formatted Wand API documentation.</li>
+<li>scripts/format_c_api_doc.py: Now supports --include-rst option.</li>
+</ul>
+</blockquote>
+<p>2009-03-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (GetImageBoundingBox): If we fail to find a
+smaller bounding box, then the returned bounding box is the entire
+image.</li>
+</ul>
+</blockquote>
+<p>2009-02-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/magick/magick_config.h.in: Provide configuration
+access to the DisableSlowOpenMP define.</li>
+<li>PerlMagick/t/read.t: Add a test for HRZ Slow scan TV.</li>
+<li>magick/pixel_cache.c (ModifyCache): Set image <cite>taint</cite> flag and
+clear monochrome and grayscale flags when pixels are accessed
+read/write rather than at sync.</li>
+<li>coders/Makefile.am (MAGICK_CODER_SRCS): Add coders/hrz.c to
+build.</li>
+</ul>
+</blockquote>
+<p>2009-01-27 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/hrz.c: New HRZ reader for slow scan TV.</li>
+</ul>
+</blockquote>
+<p>2009-02-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (ResizeImage): Make error handling more robust.</li>
+<li>magick/pixel_cache.c (SetNexus): Return a run-time error to
+invoking code rather than exiting the program if the pixel staging
+buffer fails to be allocated.</li>
+</ul>
+</blockquote>
+<p>2009-02-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Allow the user to force the
+returned image to be TrueColor type for min-is-white and
+min-is-black TIFF files. Previous to this, bilevel TIFF files
+were always returned as PseudoClass.</li>
+</ul>
+</blockquote>
+<p>2009-01-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c, coders/pnm.c: Fix several race conditions
+reported by Julian Seward.
+(OpenCache): Restore conservative pre-allocation of pixel indexes
+since a glitch was encountered that needs to be resolved.</li>
+<li>magick/{channel.c,compare.c,constitute.c,decorate.c,effect.c,fx.c,
+image.c,operator.c,pixel_iterator.c,render.c,resize.c,segment.c,
+shear.c,transform.c}: Use explicit OpenMP critical sections to
+avoid possible cross-contention.</li>
+<li>coders/{dpx.c, pnm.c} Use explicit OpenMP critical sections to
+avoid possible cross-contention.</li>
+</ul>
+</blockquote>
+<p>2009-01-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (OpenCache): Remove conservative
+pre-allocation of pixel indexes.</li>
+</ul>
+</blockquote>
+<p>2009-01-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/index.rst: Reduce the amount of text on the front page.</li>
+</ul>
+</blockquote>
+<p>2009-01-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec.in: The module .la files need to be
+installed as part of the base install or else the modules will
+fail to load.</li>
+</ul>
+</blockquote>
+<p>2009-01-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dib.c (ReadDIBImage): Fix assertion thrown for DIB files
+with negative image height values.</li>
+</ul>
+</blockquote>
+<p>2009-01-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (ReadBMPImage): Fix assertion thrown for BMP files
+with negative image height values. Resolves SF issue 2523536 <cite>bug
+in bmp coder</cite>.</li>
+<li>Makefile.am: Don't install Magick++ headers if Magick++ is
+disabled.</li>
+<li>GraphicsMagick.spec.in: --enable-lzw option is no longer used.</li>
+</ul>
+</blockquote>
+<p>2009-01-17 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c: More robust fits parsing.</li>
+</ul>
+</blockquote>
+<p>2009-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated news.</li>
+</ul>
+</blockquote>
+<p>2009-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colorspace.c (XYZTransformPackets): Fix arithmetic
+overflow problem noticed for Q32 build when using GCC on
+big-endian systems.</li>
+<li>magick/constitute.c: Update Richard Nolde's float 16 and 24
+functions.</li>
+<li>magick/command.c (VersionCommand): Print some build information
+for MSVC builds.</li>
+</ul>
+</blockquote>
+<p>2009-01-10 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c: Ability to skip unsupported multidimensional object.</li>
+</ul>
+</blockquote>
+<p>2009-01-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (GetBlobSize): It seems that under Windows, the
+zip stream is not usable as a file handle. Switch back to using
+stat instead, but use _stati64 if available.</li>
+</ul>
+</blockquote>
+<p>2009-01-04 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/fits.c: Fixed bug in scene count in extension block.</li>
+<li>coders/fits.c: Supported logging.</li>
+</ul>
+</blockquote>
+<p>2009-01-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Produce sprintf scaling strings for
+platform-specific types.</li>
+<li>magick/magick_types.h.in: Include sprintf scaling strings for
+platform-specific types.</li>
+<li>magick/constitute.c (WriteImage): If output stream is not
+seekable and coder needs to use seek, then divert output to
+temporary file, and then send file to stream.</li>
+<li>magick/blob.c (GetBlobSize): Simplify implementation.
+(OpenBlob): Don't attempt to test header magic on file we are
+writing. Silly benign bug in obtuse code.</li>
+<li>coders/tiff.c (ReadTIFFImage,WriteTIFFImage): Strip out use of
+temporary file. Use TIFFClientOpen() for writing.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2009.rst b/www/ChangeLog-2009.rst
new file mode 100644
index 0000000..71045ca
--- /dev/null
+++ b/www/ChangeLog-2009.rst
@@ -0,0 +1,1711 @@
+
+2009-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/unix\_port.c (MagickSpawnVP): Remove unneeded new line
+ character in error message format.
+
+ - Magick++/Makefile.am: Allow Magick++ to be built as a shared
+ library under MinGW and Cygwin. This requires a modern GCC in
+ order for C++ exceptions to work.
+
+ - utilities/tests/annotate.sh: MSYS is garbeling up draw command
+ so use a command file rather than using command line.
+
+ - coders/{fits.c,meta.c,locale.c}: Fix benign warnings noticed
+ under Cygwin 1.7.
+
+ - magick/{constitute.c,resource.c,utility.c}: Fix benign warnings
+ noticed under Cygwin 1.7.
+
+2009-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/module.c (DestroyModuleInfo): If the Jasper library is
+ used, then we can't invoke lt\_dlexit() because this unloads the
+ Jasper library and Jasper sometimes registers an atexit() cleanup
+ handler. Unfortunately, this may annoy memory leak checkers.
+
+ - coders/jp2.c: Defer Jasper initialization to point of use.
+
+2009-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickCdlImage): New method to apply the ASC
+ CDL to an image.
+ (MagickHaldClutImage): New method to apply a Hald CLUT to an image.
+
+2009-12-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h atof(), atoi(), and atol() are legacy functions
+ which might not be thread safe, might not enforce reasonable
+ limits, and should not be used for new code. So we implement them
+ via strtod() and strtol().
+
+2009-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickGetImageBoundingBox): New method to
+ return the crop bounding box required to remove any solid-color
+ border from the image.
+ (MagickGetImageFuzz/MagickSetImageFuzz): New methods to get and
+ set the color comparison fuzz factor
+
+ - wand/pixel\_wand.c (ClonePixelWand): New method to deep-copy an
+ existing pixel wand.
+ (ClonePixelWands): New method to deep-copy an array of existing
+ pixel wands.
+
+ - wand/magick\_wand.c (MagickSetResolution): New method to set the
+ wand resolution. This one also works before the image has been
+ read (unlike MagickSetImageResolution()).
+ (MagickSetResolutionUnits): New method to set the wand resolution
+ units. Use in conjunction with MagickSetResolution(). This one
+ also works before the image has been read (unlike
+ MagickSetImageUnits()).
+
+2009-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/demo/demo.cpp (main): Stop using deprecated functions.
+
+ - wand/drawtest.c: Stop using deprecated functions.
+
+2009-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/module.c (ModuleAliases): J2C is supported by the JP2
+ coder.
+
+ - coders/jp2.c: JP2 is now an alias for JPC since many files use
+ that extension. Problem reported by Stefano Acerbetti.
+
+2009-12-09 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c: The png8 encoder would fail when trying to write
+ a 1-color image. Problem reported by Bob Clark.
+
+2009-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Define \_GNU\_SOURCE and \_NETBSD\_SOURCE so that
+ pwrite() and pread() prototypes are available under GNU Linux and
+ NetBSD.
+
+ - coders/tiff.c: Warnings reduction.
+
+ - magick/widget.c: Warnings reduction.
+
+ - magick/segment.c (Classify): Warnings reduction.
+
+ - magick/magic.c (struct StaticMagic): Length and offset can never
+ be negative so use an unsigned type rather than size\_t.
+
+ - magick/render.c (TracePath): Fix access one beyond the end of
+ the points array.
+
+2009-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/gem.c (GetOptimalKernelWidth1D, GetOptimalKernelWidth2D):
+ In the Q32 build, convolution kernel size was estimated
+ incorrectly for large sigmas on 32-bit systems due to arithmetic
+ overflow.
+
+2009-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ConvolveImage): Moved here from fx.c since this
+ is a more suitable place for it to be.
+
+ - magick/enhance.c (GammaImage): Improve performance a bit.
+ Preserve full precision in Q32 build.
+
+2009-11-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/{channel.c,constitute.c,nt\_base.h}: Start using the C'99
+ `restrict` keyword.
+
+2009-11-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickGetImageAttribute): New method to get
+ an image attribute. Patch contributed by Mikko Koppanen.
+ (MagickSetImageAttribute): New method to set an image attribute.
+ Patch contributed by Mikko Koppanen.
+
+ - magick/constitute.c (ReadImage): Log subimage and subrange.
+
+ - configure: Update to Autoconf 2.65.
+
+ - magick/attribute.c (GenerateIPTCAttribute): Returned IPTC string
+ values were one character too short.
+
+2009-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (AllocateImage): The documented shorthand for
+ specifying image size via filename[WIDTHxHEIGHT] was not working
+ for raw formats which use the image tile\_info data.
+
+2009-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (ParseSubImageSpecification): Try to match
+ behavior of previous sub-image specification parser. Some
+ incantations did not produce the same results.
+
+ - win2k/IMDisplay/res/{IMDisplay.ico, IMDisplayDoc.ico}: Replaced
+ with GraphicsMagick icon prepared by Jaroslav Fojtik.
+
+ - coders/svg.c (ReadSVGImage): Use runtime initialization of
+ SAXModules rather than static initialization.
+
+ - magick/command.c: Commands now support reading an image from
+ stdin in conjunction with a subrange specification (e.g. "-[1]").
+ Problem was reported by Mario Becroft.
+
+ - magick/common.h: New header file to incorporate the common bits
+ shared by studio.h and api.h.
+
+ - ltdl/ltdl.c: Update libltdl to 2.2.6b in order to fix security
+ issue. Resolves CVE-2009-3736 as it pertains to GraphicsMagick.
+
+2009-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ConstituteImage, DispatchImage): `A` and
+ `T` should indicate transparency and `O` should indicate opacity.
+ Behavior was inconsistent. In some cases `O` meant transparency
+ while in other cases it meant opacity. Also, in a few cases, matte
+ was not getting enabled in the image as it should. Problems were
+ reported by Scott Kuhl.
+
+2009-11-10 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c: Also suppress new pedantic warnings from most
+ older libpng-1.4.0 betas.
+
+ - coders/png.c: Added a warning when attempting to use libpng-1.4beta
+ older than 1.4.0beta67.
+
+2009-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): Only invoke ProfileImage() if
+ an ICC CMS transform is to be performed. Otherwise invoke
+ SetImageProfile() to add the new profile.
+
+ - magick/profile.c (ProfileImage): Improve logging messages.
+
+ - coders/tiff.c (ReadTIFFImage): Allow CIELAB TIFF to be read.
+
+ - coders/jpeg.c (ReadJPEGImage): Detect and apply colorspaces
+ appropriately for ITU FAX JPEG.
+
+2009-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff: Updated to libtiff 3.9.2.
+
+2009-11-08 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c: Suppress new pedantic warnings from libpng
+ version 1.2.41 and 1.4.0 and later.
+
+2009-11-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Document difference between -recolor and
+ Adobe Flash color matrix.
+
+2009-11-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImageCommand): Convolve does not accept
+ an argument which looks like a geometry. Resolves SourceForge
+ issue #2890923 "Different handling of -convolve between convert
+ and mogrify".
+ (MogrifyImage): Validate that user-provided matrix is square when
+ parsing -convolve and -recolor commands in order to avoid a core
+ dump.
+
+ - coders/tiff.c (ReadTIFFImage): Improved/added more coder logging
+ statements.
+
+ - magick/xwindow.c: Reflowed some code and comments.
+
+ - magick/utility.c (SetClientName): Default client name does need
+ to be "Magick", so original value is restored.
+
+ - coders/mpc.c (ReadMPCImage): is\_monochrome and is\_grayscale
+ flags were not managed properly for the MPC coder.
+
+2009-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (ReadJPEGImage): Added jpeg:block-smoothing and
+ jpeg:fancy-upsampling defines to control these JPEG library
+ options.
+
+ - magick/image.c (SetImageInfo): Fix lockup due to hanging in loop
+ while parsing malformed sub-image specification (SourceForge issue
+ 2886560). Also fixes the ability to pass the image size via the
+ filename specification like "myfile.jpg[640x480]" rather than
+ needing to use -size.
+
+ - coders/jpeg.c (ReadJPEGImage): Fix image scaling when used with
+ IJG JPEG library version 7.
+
+2009-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c: Added support for a "Threads" limit, which
+ specifies how many threads may be used. Note that if
+ omp\_set\_nested(true) is used, GCC's GOMP seems to replicate this
+ number of threads for each level of threading rather than sharing
+ the specified number of threads across all teams. For example,
+ specifying four threads leads to sixteen active threads with
+ omp\_set\_nested(true) and nested threading. This GOMP behavior
+ does not seem to cause any harm.
+ (GetMagickResourceLimit): New accessor function to retrieve the
+ maximum limit for a resource.
+
+ - magick/module.c (ReadModuleConfigureFile): Default set of module
+ aliases is now statically initialized. The modules.mgk file is
+ now optional and can be used to support adding more modules, or
+ diverting existing format support to a user-provided module.
+
+ - magick/magick.c (DestroyMagick): Document that this function
+ should be invoked from the program's primary thread after any
+ threads using GraphicsMagick have terminated.
+ (GetMagickInfo): Was thread safe for access but not properly
+ thread safe during initialization. Is now fully thread safe.
+ (InitializeMagick): Fully initialize everything needed to
+ read/write files. Document that this function MUST be invoked
+ from the program's primary thread prior to using any other
+ GraphicsMagick functions.
+
+ - magick/color\_lookup.c (ReadColorConfigureFile): The colors.mgk
+ is now optional so don't throw an exception if it is not found.
+
+ - magick/semaphore.c (AcquireSemaphoreInfo): Deprecated this
+ internal function. Use AllocateSemaphoreInfo() and
+ LockSemaphoreInfo() instead.
+ (LiberateSemaphoreInfo): Deprecated this internal function. Use
+ UnlockSemaphoreInfo() instead.
+
+2009-10-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - config/colors.mgk: Colors.mkg is now empty since it is used to
+ modify or extend the built-in color lookup table.
+
+ - magick/{constitute.c,delegate.c,log.c,magic.c,magick.c,tempfile.c}:
+ Explicitly initialize semaphores via InitializeMagick().
+
+ - magick/type.h: New header file to contain types and function
+ prototypes for functions in type.c.
+
+ - magick/color\_lookup.c (ReadColorConfigureFile): Store RGB color
+ table in a static struct. Entries in the colors.mgk file are now
+ used to modify statically-defined entries, or add new definitions
+ to the color table.
+
+2009-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: --enable-libtool-verbose configure option is no
+ longer needed now that we have silent build capability.
+
+2009-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (GenerateEXIFAttribute): Add support for
+ retrieving GPS EXIF attributes. Based on work contributed by
+ Jukka Manner.
+
+ - Magick++/lib/STL.cpp, Magick++/lib/Magick++/STL.h (shadeImage):
+ ShadeImage was the result of a botched cut-and-paste. Corrected
+ now. Thanks to Jukka Manner for making me aware of this.
+
+2009-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/analyze.c: New source file to contain image analysis
+ functions. Moved functions from image.c and color.c to this file.
+
+ - magick/color\_lookup.c: New source file to contain color lookup
+ functions. Moved associated functions from color.c to this file.
+
+ - magick/ImageMagick.rc: Remove inclusion of magic.mgk.
+
+ - magick/utility.c (MagickRoundUpStringLength): Use a bit less
+ memory.
+
+ - magick/color.c: Use most efficient string allocation function.
+
+ - config/Makefile.am: Eliminate use of magic.mgk.
+
+ - magick/magic.c: Store file header magic data in a static struct.
+
+2009-10-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/describe.c (DescribeImage): Include composition operator
+ in verbose output. Also use CompressionTypeToString() to convert
+ a compression enum to a string.
+
+2009-10-11 Toby Thain <qu1j0t3@users.sourceforge.net>
+
+ - coders/psd.c: Further fix for 2783535 reported by Daniel Kirsch.
+ Omit 0x0 layers from the image list, or they break compositing.
+
+2009-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/xwindow.c: Check for overflow on all array allocations.
+
+ - magick/command.c (MogrifyImages): If there is only one image in
+ the list, then -flatten does nothing at all.
+
+ - magick/transform.c (FlattenImages): If the user provides only
+ one image then return a clone of that image rather than reporting
+ an error.
+
+ - magick/texture.c (TextureImage): If an under-texture is applied,
+ then remove the matte channel.
+
+ - magick/xwindow.c (MagickXMakeImage): Apply a checkerboard
+ pattern when displaying non-opaque TrueColor images. Fix a second
+ integer overflow issue related to CVE-2009-1882.
+
+2009-10-10 Toby Thain <qu1j0t3@users.sourceforge.net>
+
+ - coders/psd.c: Fix for 2783535 reported by Daniel Kirsch. PSD
+ parser was confused by 0x0 pixel layers, resulting in image data
+ corruption of all following layers.
+
+2009-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/xwindow.c (MagickXMakeImage): Fix for CVE-2009-1882
+ "Integer overflow in the XMakeImage function". The problem is
+ that the shared memory segment allocated may be smaller than the
+ image size requires due to integer overflow. On some systems it
+ may be possible to crash GraphicsMagick (while displaying an image
+ file) but not likely to overwrite the heap since shared memory
+ segments are outside of the heap allocation.
+
+ - magick/memory.c (MagickMallocArray): Use MagickArraySize().
+
+ - magick/memory.c (MagickArraySize): New private function to
+ compute the size of an array and return zero if it overflows the
+ size\_t type.
+
+2009-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcm.c (ReadDCMImage): Handle (UN)known type VRs correctly
+ and interpret the transfer syntax correctly. Added define
+ "dcm:avoid-scaling" to request that the coder should not scale
+ image samples unless necessary (i.e. when bits used > quantum
+ depth or maximum colormap depth, depending on image type). Work
+ is contributed by John Sergeant.
+
+2009-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am (CHECK\_PDF\_FILE\_COMPRESS): Add PDF tests with
+ the various compression options.
+
+ - coders/pdf.c (WritePDFImage): If the input file used JPEG
+ compression and has not been converted to a bilevel or palette
+ image, then use JPEG compression with original settings. Problem
+ was reported by Marco Atzeri.
+
+2009-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - config/modules.mgk: DCRAW module entries were missing.
+
+ - coders/tiff.c (WriteGROUP4RAWImage): Was not working properly on
+ big-endian CPUs with libtiff 1.4.
+
+ - coders/ps2.c (WritePS2Image): Use ImageToJPEGBlob().
+
+ - coders/ps3.c (WritePS3Image): Use ImageToJPEGBlob().
+
+ - coders/pdf.c (WritePDFImage): Decouple from libtiff. Use ImageToJPEGBlob().
+
+ - coders/dcraw.c (RegisterDCRAWImage): Needed to register module
+ name.
+
+ - coders/cals.c (ReadCALSImage): Fix bug in CALS reader which
+ caused reading images taller than the image width to fail with an
+ error.
+
+ - magick/utility.c (AcquireString): Minor optimizations.
+ (AllocateString): Minor optimizations.
+ (CloneString): Minor optimizations.
+ (LocaleCompare): Minor optimizations.
+ (SubstituteString): Re-implemented in a more compact way which
+ might avoid some reallocations.
+
+ - magick/magick.c (ListModuleMap): Don't crash if `module` was not
+ set.
+
+ - magick/delegate.c (ListDelegateInfo): Fix insignificant memory
+ leak.
+
+ - magick/compress.c (ImageToJPEGBlob): Preserve JPEG settings if
+ feasable.
+
+2009-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c (WritePDFImage): Use ImageToHuffman2DBlob() and
+ ImageToJPEGBlob().
+
+ - coders/cals.c (WriteCALSImage): Use ImageToHuffman2DBlob().
+
+ - magick/compress.c (ImageToHuffman2DBlob): New private
+ convenience function to produce a CCIT Group4 blob.
+ (ImageToJPEGBlob): New private convenience function to produce a
+ JPEG blob.
+
+2009-09-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (ReadJP2Image): Fix scaling problem noticed when
+ reading 12-bit JP2 format. Problem was reported by Steve Shaw.
+ (WriteJP2Image): Support writing JP2 files with arbitrary depth
+ ranging from 2 to 16 rather than just 8 or 16.
+
+2009-09-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/unix\_port.c (MagickGetMMUPageSize): Cache returned page
+ size to eliminated repeated system calls.
+
+ - magick/operator.c (QuantumOperatorRegionImage): Fix missing
+ percent in progress monitor message.
+
+2009-09-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c (GetIPTCStream): Should return IPTC block length
+ rather than remaining blob length. Patch submitted by John
+ Sergeant.
+
+2009-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c (GetIPTCStream): IPTC blobs should be padded to an
+ even size. Patch submitted by John Sergeant.
+
+2009-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteGROUP4RAWImage): Added a GROUP4RAW encoder.
+
+ - coders/cals.c (Huffman2DEncodeImage): Fix test failures when
+ doing I/O to an in-memory blob.
+
+ - coders/pcl.c (WritePCLImage): Use a different control code to
+ (hopefully) eject the page. Patch submitted by John Sergeant.
+
+2009-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am: Add CALS tests. Skip testing deep images for
+ most formats which don't support deep images.
+
+ - coders/cals.c: CALS module was not being built under Windows
+ with MSVC. Now it is.
+
+ - VisualMagick/configure/configure.cpp (process\_library): CALS
+ module is dependent on TIFF library.
+
+ - coders/cals.c (WriteCALSImage): Allow CALS writing at any time,
+ but only enable CALS reader if libtiff is present at build time.
+
+ - coders/{cals.c,pdf.c,ps2.c,ps3.c} (Huffman2DEncodeImage): Force
+ TIFF image type to bilevel type.
+
+ - config/modules.mgk, VisualMagick/bin/modules.mkg: CAL-->CALS
+ rather than CALS-->CAL.
+
+2009-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/benchmarks.rst: Updated GraphicsMagick vs ImageMagick
+ benchmark results.
+
+2009-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/cals.c (WriteCALSImage): Initial CALS Type 1 writer
+ implementation. Contributed by John Sergeant.
+
+ - coders/png.c (ReadOnePNGImage): Fresh pixels should be set using
+ SetImagePixels().
+
+2009-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Released GraphicsMagick 1.3.7.
+
+2009-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/msl.c, doc/conjure.imdoc: Add support for a new `profile`
+ command in MSL/conjure which applies, adds, or removes one or more
+ IPTC, ICC or generic profiles from a file. Work contributed by
+ John Sergeant.
+
+2009-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (NTGhostscriptFind): Make sure we close the
+ registry key. Log any Windows error messages.
+
+ - magick/profile.c (AppendImageProfile): New function to add or
+ append a profile. If the profile already exists, then the data
+ provided is appended to it.
+
+ - coders/jpeg.c (ReadGenericProfile,ReadICCProfile,ReadIPTCProfile):
+ Profile chunks need to be concatenated. Otherwise "chunked"
+ profiles become corrupted.
+
+2009-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/average.c (AverageImages): Moved from image.c to new
+ average.c file.
+
+ - magick/colormap.h (VerifyColormapIndex): Moved here from color.h
+
+ - magick/colormap.c (AllocateImageColormap): Moved from image.c to
+ new colormap.c source file.
+ (CycleColormapImage): Moved from image.c.
+ (ReplaceImageColormap): Moved from image.c.
+ (SortColormapByIntensity): Moved from image.c.
+ (MagickConstrainColormapIndex): Moved here from color.c.
+
+ - magick/describe.c (DescribeImage): Moved from image.c to new
+ describe.c source file.
+
+ - magick/plasma.c (PlasmaImage): Moved from image.c to new
+ plasma.c source file.
+
+ - magick/statistics.c (GetImageStatistics): Moved from image.c to
+ new statistics.c source file.
+
+ - magick/gradient.c (GradientImage): Moved from image.c to new
+ gradient.c source file.
+
+ - magick/texture.c (ConstituteTextureImage,TextureImage): Moved to
+ new texture.c source file.
+
+ - coders/svg.c (ENABLE\_SVG\_WRITER): Disable SVG writer by default
+ since it usually does not work correctly and is unlikely to work
+ correctly any time soon.
+
+2009-09-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/profile.c (ProfileImage): GlobExpression is case
+ sensitive so assure that its glob strings are always upper-cased.
+ Without this fix, lower-cased arguments like "icm" would fail to
+ be removed. This would not be much of a problem except that the
+ documentation claims that lower-case works.
+ (SetImageProfile): Assure that profile names are upper-cased.
+
+ - magick/fx.c (ColorMatrixImage): Add opaque opacity channel if
+ image currently lacks an opacity channel but the matrix updates
+ the opacity channel. Requested by Kerry Panchoo.
+
+2009-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c (GetIPTCStream): Updates from John.Sergeant to fix
+ issues with IPTC record 2 blocks and to deal better with IPTC
+ embedded in an 8BIM profile.
+
+ - PerlMagick/t/read.t: Added tests for Topol format.
+
+2009-09-12 Fojtik Jaroslav <JaFojtik@seznam.cz>
+ - coders/topol.c: Pallette overflow fixed for subtype 3.
+
+2009-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/tests/msl\_composite.sh: Use a draw command file for
+ this test script too.
+
+ - utilities/tests/{black-threshold.sh,draw.sh,recolor.sh,
+ white-threshold.sh}: MSYS is sometimes wreaking havoc on arguments
+ with spaces in them so use work-arounds.
+
+2009-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (NTGhostscriptFind): Improve logging messages
+ when searching for Ghostscript.
+
+2009-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (CacheInfo): Add read\_only member to
+ indicate if cache is allowed to be modified.
+ (ModifyCache): Clone cache if origin cache is read only.
+ (PersistCache): Persistent caches which are attached are treated
+ as read-only. This avoids crash with MPC images which are read
+ and subsequently modified.
+ Reverted pixel cache locking changes which were made yesterday
+ since I decided that they were too risky until file handle
+ management is addressed.
+
+2009-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (InitializeMagickResources): Increase
+ operating system file handle limits if necessary.
+
+ - magick/pixel\_cache.c: Pixel cache file locking is now done at
+ point of access.
+
+ - magick/nt\_base.c (NTGhostscriptFind): New function to find
+ Ghostscript under Windows, replacing previous Ghostgum
+ implementation.
+
+ - Copyright.txt: License is now based on MIT license exactly,
+ without extra edits. Ghostgum code has been eliminated so it is
+ no longer necessary to include its license.
+
+2009-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/delegate.c (GetPostscriptDelegateInfo): Add a gs-palette
+ delegate entry in order to force Ghostscript to output a
+ colormapped image if `-type palette` is specified prior to the
+ input filename. Ghostscript's dithering is much courser than
+ GraphicsMagick's -colors default (more similar to
+ -ordered-dither), but it is fast and produces smaller intermediate
+ files.
+
+ - coders/ps.c (ReadPSImage): Eliminate use of NULL pointer when
+ progress monitor is enabled. Was referring to image->filename
+ rather than image\_info->filename as it should have.
+
+ - magick/delegate.c (InvokePostscriptDelegate): Added an
+ `exception` argument so that failure details can be returned.
+ Tried to reorganize the code so that it is more tolerant of errors
+ such as a dynamically-loadable DLL failing to load. On POSIX
+ systems, Ghostscript was not being invoked as securely as
+ expected.
+
+ - coders/Makefile.am: Only build the DPS module if the Display
+ Postscript library is available.
+
+ - coders/ept.c (ReadEPTImage): If we don`t have the Display
+ Postscript library, then don't try to use it as a fallback.
+
+ - coders/ps.c (ReadPSImage): If we don't have the Display
+ Postscript library, then don't try to use it as a fallback.
+
+ - magick/blob.c (CloseBlob): If blob was never allocated, then
+ don't try to close it.
+
+2009-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/index.rst: Mention 1.2.8 release.
+
+2009-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++: New Image methods cdl(), colorMatrix(), and haldClut()
+ added.
+
+2009-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c (IntegralRotateImage): Select tile sizes in a
+ more intelligent fashion.
+
+ - magick/pixel\_cache.c (GetPixelCacheInCore): New private pixel
+ cache method to see if image pixels are in core.
+
+2009-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ReadImage): No longer clear the exception
+ at the start of ReadImage() and other similar functions. If the
+ user of the function cares, she can clear the exception in
+ advance. It is not right to overwrite exceptions which might not
+ have been reported/handled yet.
+
+ - magick/shear.c (IntegralRotateImage): Rotate by zero degrees
+ does not need to do any work.
+
+ - coders/\*.c, magick/\*.c: Include image dimensions in progress
+ monitor output when loading or saving a file. Eliminate redundant
+ text from progress messages.
+
+2009-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c: Eliminate memory leaks.
+
+ - magick/render.c (DrawDashPolygon): Avoid access beyond end of
+ array. Resolves SourceForge issue 2832125 "Crash on SVG
+ conversion".
+
+ - coders/png.c (ReadOnePNGImage): Ensure that opacity channel is
+ properly initialized. Resolves SourceForge issue 2831240
+ "Possible alpha channel issue with PNG w/palette and tRNS".
+
+2009-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.h (HAVE\_TIFFSWABARRAYOFTRIPLES): Need to define
+ this since libtiff includes this function now.
+
+ - VisualMagick/tiff/libtiff/tiffconf.h.in: Enable all the options
+ by default.
+
+ - tiff: Updated to libtiff 3.9.1. 3.9.0 was broken.
+
+2009-08-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/profile.c (MagickFreeCMSTransform): Add a CMS transform
+ destructor since otherwise Visual Studio does not like it.
+
+ - tiff: Updated to libtiff 3.9.0.
+
+2009-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (TimeImageCommand): Add a simple `time`
+ sub-command to time the execution of any other GraphicsMagick
+ sub-command. Similar in concept to the `benchmark` sub-command
+ but produces output similar to the `time` command offered by the
+ zsh command shell. Handy for when `time` is not available, or
+ consistent output is desired.
+
+ - magick/magick.c (MagickGetFileSystemBlockSize): New private
+ function to allow getting desired filesystem block size.
+ (MagickSetFileSystemBlockSize): New private function to allow
+ setting desired filesystem block size.
+
+ - magick/pixel\_cache.c (WriteCacheIndexes, WriteCachePixels):
+ Temporarily disable pixel cache row coalescing when writing to
+ disk until we come up with a good way to optimize write sizes.
+
+ - coders/meta.c (ReadMETAImage): Fix memory leak of profile blob.
+
+2009-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/tests/icc-transform.sh: Add a sanity-test for applying
+ ICC profiles.
+
+ - magick/profile.c (ProfileImage): Improve OpenMP performance.
+
+2009-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawPolygonPrimitive): Drawing of points,
+ lines, and polygons is now accelerated using OpenMP with good
+ speed-up.
+
+2009-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/drawing\_wand.c (DrawClearException): New function to clear
+ drawing wand exception.
+ (DrawGetException): New function to retrieve information regarding
+ the last drawing wand exception (if any).
+ (DrawRender): DrawRender() is now deprecated since it requires an
+ Image pointer to be embedded in the drawing wand. The image
+ passed is subsequently lost by CloneDrawingWand() since it must
+ clone the image using copy-on-write. Subsequent use of
+ DrawRender() on a cloned wand scribbles on an image the user does
+ not have access to. Use existing Wand function MagickDrawImage()
+ instead.
+ (DrawAllocateWand): DrawAllocateWand() is now deprecated since it
+ requires passing an Image pointer into the drawing wand. Use
+ existing DrawingWand function NewDrawingWand() instead.
+
+2009-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/drawing\_wand.c (CloneDrawingWand): New function to
+ deep-copy a drawing wand.
+ (NewDrawingWand): Use a boolean flag to track if image is
+ allocated by the wand, or by the user. Most of the previous
+ DrawAllocateWand() code is moved into NewDrawingWand() so that the
+ boolean flag is easy to manage.
+
+2009-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Support writing grayscale
+ JPEG-compressed TIFF.
+
+2009-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Don't override the photometric
+ for grayscale JPEG-compressed TIFF.
+
+2009-08-08 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c: Made compatible with libpng-1.4.0beta74 and later
+ (won't work with libpng-1.4.0beta35 through beta73) due to change
+ in names of png\_struct members "trans" and "trans\_values").
+
+2009-08-08 Fojtik Jaroslav <JaFojtik@seznam.cz>
+ - coders/topol.c: Pallette is ignored for subtype 5 (RGB).
+
+2009-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/{cineon.c, dpx.c, locale.c, svg.c}, magick/{attribute.c,
+ effect.c, utility.c}: Eliminate warnings reported by GCC 4.4.0.
+
+2009-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Try to be more insistent about compilation failure
+ if libjpeg version is less than 6b. IRIX compiler only warns
+ about #error preprocessor statement.
+
+2009-07-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickSetCompressionQuality): New Wand
+ method to allow setting the compression quality.
+
+2009-07-29 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/topol.c: Fixed missing break. Added response to ping.
+
+2009-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pcx.c (ReadPCXImage): Detect improper rows, columns, or
+ depth. Fixes CVE-2008-1097 "Memory corruption in ImageMagick's
+ PCX coder".
+
+ - configure.ac: Update to Autoconf 2.64.
+
+2009-07-25 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/topol.c: Fixed several issues. Added possibility to read
+ TopoL level 2 images.
+
+2009-07-25 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - VisualMagick\configure\configure.cpp: Fixed library absolute path issue.
+
+2009-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/random.c (DestroyMagickRandomGenerator): Trick to free
+ thread specific random kernel contexts simply locks up with MSVC's
+ OpenMP, so remove this functionality.
+
+2009-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/random.c (DestroyMagickRandomGenerator): Cleanup thread
+ specific random kernel data.
+
+ - magick/tsd.c (MagickTsdKeyCreate): Fix glitch when built without
+ any threads support.
+
+2009-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/benchmarks.rst: Update GraphicsMagick vs ImageMagick image
+ processing benchmark results.
+
+2009-07-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/OpenMP.rst: Update performance measurements for readily
+ available systems.
+
+ - NEWS.txt: Updated to reflect latest changes.
+
+2009-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Updated libpng to 1.2.38.
+
+2009-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (GetImageInfo): Default interlace for ImageInfo
+ is now UndefinedInterlace so that it is possible to preserve the
+ original interlace setting for the image file. Code depending on
+ the previous default setting of NoInterlace is adjusted to suit.
+ This is a potentially risky change given the brittle nature of
+ some of the legacy code.
+
+ - coders/tiff.c (ReadTIFFImage): Stripped reader needs to read
+ planar TIFF plane-wise in order to work with libtiff's internal
+ buffering.
+ (ReadTIFFImage): Tiled reader needs to read planar TIFF plane-wise
+ in order to work with libtiff's internal buffering.
+ (WriteTIFFImage): Tiled writer needs to output planar TIFF
+ plane-wise in order to work with libtiff's internal buffering.
+
+2009-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MontageUsage): Reconcile montage help output
+ with actual montage options.
+
+2009-07-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Allow the user to be able to
+ specify rows\_per\_strip when using JPEG compression. The
+ rows\_per\_strip value rounded up to the nearest multiple of 16.
+
+2009-07-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Add the ability for the user to
+ manually specify the predictor using syntax like `-define
+ tiff:predictor=2`.
+
+2009-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/quantize.c (QuantizeImages): Avoid crash when using
+ -monitor +map on an image list.
+
+ - magick/command.c (BenchmarkImageCommand): Send benchmark report
+ to stderr so that it does not interfer with pipes.
+
+ - magick/cdl.c (CdlQuantum): Add range limiting of value before
+ applying power function.
+
+ - coders/dpx.c (ReadDPXImage, WriteDPXImage): Using floating point
+ calculations when building sample value lookup tables in order to
+ decrease error. In particular input values were being scaled too
+ low, resulting in improperly rounding down during processing of
+ the image.
+
+2009-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c (WritePDFImage): Incorporated updates from John
+ Sergeant to remove the font and thumbnail objects from PDF output.
+
+2009-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/cdl.c (CdlImage): New function to apply an ASC CDL
+ transform to the image. Original implementation by Clment Follet
+ from Workflowers but considerably re-worked by Bob Friesenhahn.
+ Available as -asc-cdl via the `convert` and `mogrify` subcommands.
+
+2009-07-04 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - www/formats.rst: MAT module can read compressed files.
+ Remove warning about unsupported compression.
+
+2009-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcm.c: Eliminate compiler warnings.
+
+2009-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcm.c: Significant re-write of the DICOM reader. Work
+ contributed by John Sergeant.
+
+2009-07-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (OpenBlob): Subsequent research shows that Direct
+ I/O will not be useful to ordinary file I/O due to specific
+ requirements for buffer alignments and I/O sizes. Support for
+ requesting it is removed.
+
+2009-07-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - www/formats.rst: ART module has writer for more than year.
+ So mark this here.
+
+2009-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac, magick/blob.c: Add experimental Solaris direct I/O
+ support which is enabled by setting the environment variable
+ MAGICK\_DIRECTIO to TRUE. Direct I/O bypasses the filesystem
+ cache. Only works for NFS and UFS, and not for ZFS.
+
+2009-06-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - rungm.sh.in: Fix environment variable issues noticed while
+ running the test suite under MinGW.
+
+ - Makefile.am (TESTS\_ENVIRONMENT): Fix environment variable issues
+ noticed while running the test suite under MinGW.
+
+ - magick/hclut.c (HaldClutImage): Don't convert Cineon Log to RGB.
+
+2009-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImageCommand): Cache mogrify argument
+ images so that they are only loaded once when mogrify is used to
+ process multiple image files.
+
+ - coders/dpx.c (WriteDPXImage): Fix leak of chroma image when
+ subsampling to 4:2:2.
+
+2009-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (ExpandFilenames): Expand @filename to a list
+ of arguments.
+
+2009-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImageCommand): Fix memory leak of
+ output\_directory string buffer, if it was used.
+
+ - magick/utility.c (ExpandFilenames): Input wildcard file
+ specifications with a subdirectory component such as
+ "subdir/\*.dpx" were not working.
+
+2009-06-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (InitializeMagick): Invoke InitializeMagickRegistry().
+
+ - magick/registry.c (RegistryInfo): There is no reason to expose
+ the RegistryInfo structure in the public interface so it is moved
+ to registry.c.
+ (InitializeMagickRegistry): Add a function for initializing the
+ magick registry.
+
+2009-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (CompareImageCommand): Report full error rather
+ than rounded error in error reports since sometimes the value
+ reported was rounded down to zero.
+
+ - utilities/tests/hald-clut-transform.sh: New test to verify that
+ Hald CLUT interpolation is working perfectly.
+
+ - utilities/tests/hald-clut-identity.sh: Renamed from
+ hald-clut.sh.
+
+2009-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (RegisterJPEGImage): Fix typo which caused IJG
+ library version to be shown for "JPG" format but not for "JPEG".
+ Also use a more descriptive name for JPEG library.
+
+ - magick/image.c (DescribeImage): Filter out spurious EXIF
+ attributes which already exist because we previously accessed
+ them. We do a full EXIF dump later.
+
+2009-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/FAQ.rst: Add a FAQ about how to process many files at once.
+
+2009-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Reduce usage of deprecated Autoconf macros.
+
+ - coders/jpeg.c (ReadJPEGImage): Set image orientation from EXIF
+ Orientation tag if it is present.
+
+ - www/formats.rst: Add TopoL format as per Jaroslav Fojtik.
+
+2009-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: User provided LDFLAGS was being overwritten under
+ Solaris.
+ - Many files: Additional reduction of shadowing warnings.
+
+2009-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): Fix leak of the entire mask
+ image supplied via -mask.
+
+ - utilities/tests/mask.sh: Add a test for applying a mask image
+ with -mask.
+
+2009-06-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (GenerateEXIFAttribute): Identify unknown
+ tags via their four-character hex value.
+
+ - magick/colorspace.c (CMYKToRGBTransform): Use symbolic notation
+ to access pixel quantum values.
+
+ - utilities/tests/identify.sh: Added a test for `identify
+ -verbose` on a well-populated JPEG file.
+
+ - PerlMagick/t/{jpeg/write.t, jng/read.t, jng/write.t}: Relax
+ allowed error for JPEG-related tests.
+
+ - magick/attribute.c (GenerateEXIFAttribute): Attribute allocation
+ size was too small causing overrun of memory buffer. Problem was
+ added on 2009-06-08.
+
+ - magick/image.c (AllocateDepthMap): Allocation size was one
+ element too small.
+ (GetImageDepth): Forgot to free depth map. Memory leak of 64K
+ bytes per iteration.
+
+2009-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/{mat.c, miff.c, pdf.c, ps3.c}: Have Zlib use our memory
+ allocators.
+
+ - magick/memory.c (MagickMallocCleared): New memory allocation
+ interface which is similar to MagickMalloc() except that returned
+ memory has been cleared first.
+
+ - magick/hclut.c (HaldClutImagePixels): Fix wrong accesses
+ detected by valgrind. Also improve execution performance.
+
+ - coders/xwd.c (WriteXWDImage): Fixed valgrind memcheck complaint
+ about access to uninitialized data.
+
+2009-06-09 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c Handle alpha channel for ImageMagick's alternative .txt
+
+2009-06-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteDPXImage): Fixed valgrind memcheck complaint
+ about access to uninitialized data.
+
+ - magick/attribute.c (GenerateEXIFAttribute): For EXIF STRING,
+ output unprintable characters using three-digit octal notation.
+
+ - coders/dpx.c (WriteDPXImage): Assure that offset count is
+ correct according to reported bytes written.
+
+ - utilities/tests/hald-clut.sh: Add a simple identity test for the
+ Hald CLUT support.
+
+2009-06-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c Handle alpha channel for ImageMagick's .txt
+
+2009-06-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/hclut.c (HaldClutImage): Add a Hald CLUT capability as
+ described at http://www.quelsolaar.com/technology/clut.html. This
+ allows a color transformation to be easily created and replicated
+ on any number of images. The algorithm is accessed by the
+ -hald-clut option of `convert` and `mogrify`. The original
+ algorithm is by Eskil Steenberg and was adapted for GraphicsMagick
+ by Clment Follet from Workflowers with support from Cdric
+ Lejeune of Workflowers.
+
+2009-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetMagickGeometry): Support `^` modifier to
+ geometry specification which indicates that specified size is a
+ minimum bounding box rather than a maximum bounding box while
+ preserving the image aspect ratio.
+
+2009-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (ListMagickResourceInfo): If supporting
+ OpenMP, then include a "Threads" limit in the output of `-list
+ resource`.
+
+ - coders/pnm.c (ReadPNMImage): Fix multi-thread issue detected by
+ valgrind's helgrind tool. Diminish compilation warnings.
+
+ - coders/dpx.c (ReadDPXImage): Diminish compilation warnings.
+
+ - magick/random.c (AcquireMagickRandomKernel): Fix potential
+ multi-thread issue detected by valgrind's helgrind tool.
+
+ - magick/magick.c (InitializeMagick): Semaphore subsystem needs to be
+ initialized before anything which uses it.
+
+ - magick/semaphore.c (InitializeSemaphore): Since we are using
+ PTHREAD\_MUTEX\_INITIALIZER to initialize primary POSIX mutex in the
+ semaphore subsystem, we should not explicitly initialize the
+ semaphore a second time.
+
+ - magick/segment.c (Classify): Fix multi-thread issue detected by
+ valgrind's helgrind tool.
+
+ - magick/render.c (DrawAffineImage): Use InterpolateViewColor() to
+ evalute a bi-linear interpolated point rather than obtaining a
+ pixel value from a close pixel. This provides better results.
+
+2009-06-02 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c Attempt to handle alpha channel.
+
+2009-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (InterpolateViewColor, InterpolateColor):
+ Moved from gem.c. Gem functions should not be accessing the pixel
+ cache.
+
+2009-06-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (CompareImageCommand): Add a -maximum-error
+ option to `compare` so that it can easily be used in boolean logic
+ when comparing images.
+
+2009-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am (TESTS\_XFAIL\_TESTS): If Ghostscript is not
+ available then XFAIL the tests which depend on it.
+
+ - magick/pixel\_cache.c (GetCacheInfo): Assure that allocated
+ stuctures do not occupy the same cache lines.
+
+2009-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h (MAGICK\_CACHE\_LINE\_SIZE): Allow cache line size
+ to be set in one place in case we want to configure for it later.
+
+ - magick/effect.c (AllocateMedianList): Assure that allocated
+ stuctures do not occupy the same cache lines.
+
+ - magick/random.c (AcquireMagickRandomKernel): Assure that
+ allocated random kernels do not occupy the same cache lines.
+
+ - magick/gem.c (GenerateDifferentialNoise): User is required to
+ supply random kernel.
+
+ - doc/options.imdoc: Document -format "%p". Problem was reported
+ by Stijn Sanders.
+
+2009-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/Makefile.am (coders\_tiff\_la\_LIBADD): Libtiff may now also
+ depend on libjbig and the math library.
+
+ - doc/gmdoc2html: Fix link to ball.png. Problem was reported by
+ Wes Fox.
+
+ - VisualMagick/installer/inc/files-documentation.isx: Include Wand
+ API documentation.
+
+ - VisualMagick/installer/inc/icons-associate.isx: Fix Windows
+ Start menu link to web pages.
+
+ - configure.ac: --with-perl is changed to --without-perl since
+ building PerlMagick is no longer the default. Building PerlMagick
+ automatically has caused too many problems.
+
+ - PerlMagick/Makefile.am: GraphicsMagick no longer automatically
+ installs PerlMagick. Use the procedure described by
+ PerlMagick/README.txt to build and install PerlMagick.
+
+2009-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Debian stores Ghostscript fonts under
+ /usr/share/fonts/type1/gsfonts so check there for fonts. Issue
+ reported by Ralf Wildenhues.
+
+2009-05-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: Fix Ping of blob.
+
+ - PerlMagick/t/ping.t: Added tests for pinging files and blobs.
+
+ - www/perl.rst: Ping blob syntax is like $image->Ping(blob=>@blob).
+
+ - PerlMagick/Makefile.PL.in: Increase the probability of
+ PerlMagick build success by using the user-specified C compiler as
+ the linker if the C compiler was already used as the linker. This
+ helps if the C compiler used to build GraphicsMagick is a more
+ recent vintage than the one used to build Perl.
+
+ - PerlMagick/t/wmf/read.t: Test needs to be more lenient for
+ Linux.
+
+ - Makefile.am (TESTS\_ENVIRONMENT): Pass a complete text
+ environment so that we don't need to execute rungm.sh in order to
+ run the test suite.
+
+2009-05-25 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ - version.sh: Define PACKAGE\_STRING.
+
+2009-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/tempfile.c (ComposeTemporaryFileName): Use new random
+ number generator.
+
+ - magick/random.c: Implement a random number generation system
+ based on George Marsaglia's multiply-with-carry generator.
+ Somewhat slower than rand() but produces better random numbers
+ with a period >2^60. Suggested by Mark Mitchell.
+
+2009-05-24 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c Small optimization:
+
+ Before: 2000 iter 34.08s user 34.24s total 58.420 iter/s
+
+ After: 2000 iter 21.55s user 21.76s total 91.891 iter/s
+
+2009-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (XFAIL\_TESTS): Handle the case where FreeType is not
+ available by marking tests dependent on FreeType as XFAIL.
+ (TESTS): Reorder TESTS so that there will be no trailing spaces
+ since this confuses certain older versions of GNU make.
+
+2009-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/tempfile.c (ComposeTemporaryFileName): Use simpler code
+ (suggested by Mark Mitchell) to compute the substitution index.
+ (AcquireTemporaryFileDescriptor): Try harder to generate a
+ successful temporary file and fall through to alternative
+ implementations if the first does not succeed.
+
+ - magick/magick.c (InitializeMagick): Use MagickRandNewSeed() to
+ seed the default random number generator.
+
+ - magick/utility.c (MagickRandNewSeed): Include PID in random
+ number seed generation.
+
+2009-05-22 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c Fixed char vs int parameter problem.
+ Better detection of too dark 16bit or 32bit images.
+
+2009-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (AUTOMAKE\_OPTIONS): Enable parallel-tests and
+ color-tests options. Parallel test execution does not pass tests
+ yet.
+
+ - PerlMagick/PerlMagickCheck.sh.in: Run PerlMagick tests via a
+ normal check script rather than a check hook.
+
+ - coders/identity.c (ReadIdentityImage): Fix compilation with Sun
+ compiler.
+
+2009-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwfile.c: Allow the user to specify the basename for
+ temporary files.
+
+ - tests/Makefile.am: Add a set of TXT read/write tests. Pass the
+ file name specification to use for the rwfile-based tests.
+
+2009-05-21 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c Fixed endian set to native endian.
+
+2009-05-20 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c Faster read ImageMagick files.
+ Removed BImgBuff=NULL;
+
+2009-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/txt.c (WriteTXTImage): Ensure that image depth is 8, 16,
+ or 32.
+
+ - www/formats.rst: Add CALS to formats list.
+
+ - coders/cals.c (RegisterCALSImage): Consolidate duplicate text
+ strings.
+
+2009-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/cals.c: Add support for reading CALS type 1 format.
+ Contributed by John Sergeant.
+
+ - coders/identity.c: New coder to return a Hald identity CLUT
+ image.
+
+2009-05-19 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c Ability to read back Q32 txt files.
+
+2009-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Support Linux style silent build rules.
+
+2009-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Updated to Automake 1.11.
+
+2009-05-17 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c First attempt to read back txt file.
+ It is amazingly ineffective, but it seems to work.
+
+2009-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resize.c (HorizontalFilter, VerticalFilter): When
+ resizing a non-opaque image, attenuate the influence of
+ surrounding colors based on their degree of transparency in order
+ to avoid "halos" around objects caused by colors which are
+ transparent and therefore not part of the visible image. Patch
+ contributed by Pavel Merdin via SourceForge Tracker #2792322.
+ (VerticalFilter, VerticalFilter): Additional clean-up and
+ optimizations.
+
+2009-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): Added a -recolor command option
+ to provide access to ColorMatrixImage().
+
+ - magick/fx.c (ColorMatrixImage): New function to apply a color
+ matrix similar to Adobe Flash Flash.filters.colorMatrixFilter(),
+ and Windows GDI+ ColorMatrix class, (order up to 5x5) to the image
+ pixels.
+
+2009-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/perl.rst: Add missing PerlMagick debug event types.
+
+ - coders/pcl.c: Major improvements from John Sergeant. These
+ include: 1) Fixed 2 bit output where Max=BLACK - this always
+ produced negative images even when -negate was passed as a
+ parameter. The code now uses a two element palette to handle this
+ situation. 2) Added support for 8 bit pseudoclass images. 3)
+ Changed the coder to allow adjoin, placing each sub-image on a new
+ page. 4) Added support for compression. Any compression other
+ than "None" will cause the coder to to try to calculate and pick
+ the best out of the PCL set of RLE, Tiff RLE or delta compression
+ on a per row basis, as well as handling repeated rows and zero
+ rows intelligently.
+
+2009-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - utilities/Makefile.am (MAGICKPROGRAMS): Add a `compare`
+ ImageMagick compatibility link.
+
+ - INSTALL-unix.txt: Apply patch regarding GnuWin32 from John Wye,
+ SourceForge #2779009.
+
+2009-05-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Add the LDFLAGS option -Wl,-zlazyload when using
+ the Solaris linker.
+
+2009-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/url.c (ReadURLImage): Fix typos.
+
+2009-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (SystemCommand): Added access confirmation
+ checks for external commands.
+
+ - magick/unix\_port.c (MagickSpawnVP): Added access confirmation
+ checks for external commands.
+
+ - coders/url.c (ReadURLImage): Added access confirmation checks
+ for URLs.
+
+ - magick/blob.c: Added access confirmation checks for files.
+
+ - magick/confirm\_access.c (MagickConfirmAccess): Added an access
+ confirmation facility to allow the API user to monitor and/or
+ block access to files and URLs. This allows the API user to
+ implement a security policy based on actual accesses.
+
+2009-05-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Updated libpng to 1.2.35.
+
+ - lcms: Updated lcms to 1.18a.
+
+2009-05-01 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c (WriteOnePNGImage and WriteOneJNGImage): Changed
+ internal attribute png\_bit\_depth to png:bit-depth-written to avoid
+ confusion with planned new public png:bit-depth attribute.
+
+2009-04-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImages): Deal slightly better with the
+ case when MogrifyImage() expands one image into several. Still
+ don't know of a sane way to deal with -crop WIDTHxHEIGHT.
+
+ - magick/transform.c (TransformImage): Image which is updated may
+ be a list so account for that.
+
+ - configure.ac: Add a test for the `restrict` keyword so that
+ eventually we can use it.
+
+ - coders/jpeg.c (ReadJPEGImage): Tidy JPEG reader by moving JPEG
+ properties analysis code into subroutines.
+
+2009-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/display.imdoc: Fix documentation for crop and chop keyboard
+ accelerators. Fixes SourceForge bug #2593388 "error in the
+ documentation/Keyboard accelarators".
+
+2009-04-20 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c: Cosmetic-only, change `True` to `MagickTrue` or
+ `MagickPass` and `False` to `MagickFalse` or `MagickFail`.
+
+2009-04-20 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c: Check error return from CompressColormapTransFirst()
+
+2009-04-20 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c: Refrain from modifying image struct members
+ (matte, colors, depth) while writing a PNG.
+
+2009-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Document the direction of rotation.
+
+2009-04-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.c (LogMagickEventList): Use MagickPackageName from
+ version.h rather than hard-coding `GraphicsMagick`.
+
+2009-04-18 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/jpeg.c: Fixed a warning about `shadowed` variables.
+
+2009-04-17 Glenn Randers-Pehrson <glennrp@simple....>
+
+ - coders/png.c: Fixed some warnings about `shadowed` variables.
+
+2009-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Add tests for some reentrant versions of functions
+ where we are still using the non-rentrant versions.
+
+ - magick/composite.c (CompositeImage): Fix problem with
+ compositing images where the change image overlaps off the left
+ side of the canvas. Should fix SourceForge issue #2766200 `memory
+ allocation error when compositing small images`.
+
+2009-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/semaphore.c: Re-arrange ifdefs so that it is possible to
+ use pthreads under the WIN32 API.
+
+2009-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/bit\_stream.c: Bitstream functions were often not inlining
+ and inline functions which don't inline are not much use.
+ Bitstream functions are now normal library functions.
+
+2009-03-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/bin/delegates.mgk: Remove bounding box option (-g) from
+ Postscript delegate specifications.
+
+ - config/delegates.mgk.in: Remove bounding box option (-g) from
+ Postscript delegate specifications.
+
+ - coders/{ept.c, pdf.c, ps.c} : PDF bounding box is sometimes
+ incorrect or not globally applicable so don't specify bounding box
+ when reading PDF files. Postscript files do need the bounding box
+ so make sure that it is still supplied. Resolves SF tracker issue
+ 2487651 `convert from pdf chops off rhs`.
+
+2009-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Magick++/Image.rst: Translate Image.html to reStructuredText
+ format for easier maintenance.
+
+2009-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/rgb.c: Compute the quantum type rather than using a
+ recurring conditional statement. It turns out that the -endian
+ option is working as it should.
+
+2009-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/{gray.c, rgb.c, cymk.c}: Work toward supporting the
+ -endian option. Not working properly yet.
+
+ - magick/enum\_strings.c (EndianTypeToString): New function.
+ (InterlaceTypeToString): New function.
+
+2009-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/drawing\_wand.c: Stripped out unused code.
+
+ - www/wand: Added formatted Wand API documentation.
+
+ - scripts/format\_c\_api\_doc.py: Now supports --include-rst option.
+
+2009-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (GetImageBoundingBox): If we fail to find a
+ smaller bounding box, then the returned bounding box is the entire
+ image.
+
+2009-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/magick/magick\_config.h.in: Provide configuration
+ access to the DisableSlowOpenMP define.
+
+ - PerlMagick/t/read.t: Add a test for HRZ Slow scan TV.
+
+ - magick/pixel\_cache.c (ModifyCache): Set image `taint` flag and
+ clear monochrome and grayscale flags when pixels are accessed
+ read/write rather than at sync.
+
+ - coders/Makefile.am (MAGICK\_CODER\_SRCS): Add coders/hrz.c to
+ build.
+
+2009-01-27 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/hrz.c: New HRZ reader for slow scan TV.
+
+2009-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resize.c (ResizeImage): Make error handling more robust.
+
+ - magick/pixel\_cache.c (SetNexus): Return a run-time error to
+ invoking code rather than exiting the program if the pixel staging
+ buffer fails to be allocated.
+
+2009-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Allow the user to force the
+ returned image to be TrueColor type for min-is-white and
+ min-is-black TIFF files. Previous to this, bilevel TIFF files
+ were always returned as PseudoClass.
+
+2009-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c, coders/pnm.c: Fix several race conditions
+ reported by Julian Seward.
+ (OpenCache): Restore conservative pre-allocation of pixel indexes
+ since a glitch was encountered that needs to be resolved.
+
+ - magick/{channel.c,compare.c,constitute.c,decorate.c,effect.c,fx.c,
+ image.c,operator.c,pixel\_iterator.c,render.c,resize.c,segment.c,
+ shear.c,transform.c}: Use explicit OpenMP critical sections to
+ avoid possible cross-contention.
+
+ - coders/{dpx.c, pnm.c} Use explicit OpenMP critical sections to
+ avoid possible cross-contention.
+
+2009-01-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (OpenCache): Remove conservative
+ pre-allocation of pixel indexes.
+
+2009-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/index.rst: Reduce the amount of text on the front page.
+
+2009-01-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - GraphicsMagick.spec.in: The module .la files need to be
+ installed as part of the base install or else the modules will
+ fail to load.
+
+2009-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dib.c (ReadDIBImage): Fix assertion thrown for DIB files
+ with negative image height values.
+
+2009-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c (ReadBMPImage): Fix assertion thrown for BMP files
+ with negative image height values. Resolves SF issue 2523536 `bug
+ in bmp coder`.
+
+ - Makefile.am: Don't install Magick++ headers if Magick++ is
+ disabled.
+
+ - GraphicsMagick.spec.in: --enable-lzw option is no longer used.
+
+2009-01-17 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c: More robust fits parsing.
+
+2009-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated news.
+
+2009-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colorspace.c (XYZTransformPackets): Fix arithmetic
+ overflow problem noticed for Q32 build when using GCC on
+ big-endian systems.
+
+ - magick/constitute.c: Update Richard Nolde's float 16 and 24
+ functions.
+
+ - magick/command.c (VersionCommand): Print some build information
+ for MSVC builds.
+
+2009-01-10 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c: Ability to skip unsupported multidimensional object.
+
+2009-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (GetBlobSize): It seems that under Windows, the
+ zip stream is not usable as a file handle. Switch back to using
+ stat instead, but use \_stati64 if available.
+
+2009-01-04 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/fits.c: Fixed bug in scene count in extension block.
+ - coders/fits.c: Supported logging.
+
+2009-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Produce sprintf scaling strings for
+ platform-specific types.
+
+ - magick/magick\_types.h.in: Include sprintf scaling strings for
+ platform-specific types.
+
+ - magick/constitute.c (WriteImage): If output stream is not
+ seekable and coder needs to use seek, then divert output to
+ temporary file, and then send file to stream.
+
+ - magick/blob.c (GetBlobSize): Simplify implementation.
+ (OpenBlob): Don't attempt to test header magic on file we are
+ writing. Silly benign bug in obtuse code.
+
+ - coders/tiff.c (ReadTIFFImage,WriteTIFFImage): Strip out use of
+ temporary file. Use TIFFClientOpen() for writing.
+
diff --git a/www/ChangeLog-2010.html b/www/ChangeLog-2010.html
new file mode 100644
index 0000000..8ca9182
--- /dev/null
+++ b/www/ChangeLog-2010.html
@@ -0,0 +1,808 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2011-01-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickDescribeImage): Was sending
+descriptive output to stdout rather than returning it in an
+allocated string as intended.</li>
+</ul>
+</blockquote>
+<p>2011-01-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/draw.c, wand/drawing_wand.c (MvgPrintf): Update to handle
+C99 vsnprintf() return values.</li>
+<li>magick/draw.c, wand/drawing_wand.c (DrawAnnotation): Linux
+glibc does not pass extended text characters if &quot;%.1024s&quot;
+formatting convention is used. Apparently it assumes that such
+characters may be UTF8 and returns -1 rather than outputting the
+string, even if it is assured to fit.</li>
+</ul>
+</blockquote>
+<p>2010-12-30 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Matlab file level clarification.</li>
+</ul>
+</blockquote>
+<p>2010-12-27 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mac.c New MacPaint image format reader added.</li>
+</ul>
+</blockquote>
+<p>2010-12-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Default to using a LZMAPRESET
+value of 1 based on testing which observed minimal benefit, and
+substantially more cost, from larger values. Value may be
+specified by the user using command line syntax like <cite>-define
+tiff:lzmapreset=7</cite> for purposes of further experimentation. Also
+adjusted default strip memory values for each preset level.</li>
+</ul>
+</blockquote>
+<p>2010-12-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Add LZMA support to PerlMagick.</li>
+<li>coders/tiff.c (WriteTIFFImage): Add TIFF LZMA compressor support.</li>
+</ul>
+</blockquote>
+<p>2010-12-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImages): Should send -verbose output to
+stderr rather than stdout since otherwise usage in pipelines may
+be broken. Resolves SourceForge issue 3131790 &quot;AVS -verbose
+prints to stdout&quot;.</li>
+</ul>
+</blockquote>
+<p>2010-11-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libtool: Upgrade to libtool 2.4.</li>
+<li>coders/pnm.c (ReadPNMImage): Start work on reading NetPBM PAM
+format. Parses PAM header but pixels are not returned yet.</li>
+<li>magick/magic.c (StaticMagic): Be more specific when identifying
+PNM subformats. Return the specific subformat name PBM, PGM, or
+PPM rather than PNM. XV P7 format is now identified as &quot;P7 332&quot;.
+Add detection of NetPBM PAM format.</li>
+</ul>
+</blockquote>
+<p>2010-11-04 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c: Added 5x5, 6x6, and 7x7 circular ordered dither
+patterns to create a halftone effect.</li>
+</ul>
+</blockquote>
+<p>2010-09-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Document pcl:fit-to-page define.</li>
+<li>coders/pcl.c: Fix issue with printing a bi-level image on
+Konica-Minolta printers. Define pcl:fit-to-page in order for the
+printer to scale the image to fit the page. Patch by John
+Sergeant.</li>
+</ul>
+</blockquote>
+<p>2010-09-19 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: removed an apparently harmless extra invocation
+of ScaleShortToQuantum() due to cut-and-paste error in the
+update of 2010-06-02. Also added a line to explicitly set
+the opacity of the background_color to OpaqueOpacity.</li>
+</ul>
+</blockquote>
+<p>2010-09-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c (ReadPDFImage): Enable use of PDF crop box via
+-define pdf:use-cropbox=true. Patch contributed by Chris Gilling.
+SourceForge patch ID 3063794, &quot;Add support for using crop box for
+pdf import&quot;.</li>
+</ul>
+</blockquote>
+<p>2010-09-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Image.cpp (backgroundColor, borderColor, matteColor):
+Opacity part of user-specified color needs to be preserved.
+Problem was reported by Alexander Zheltov.</li>
+</ul>
+</blockquote>
+<p>2010-09-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Applied Automake 1.11.1 patch by Ralf Wildenhues
+which is necessary for the test suite to pass under Windows/MinGW
+due to command line length limits.</li>
+</ul>
+</blockquote>
+<p>2010-09-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/draw.c, wand/drawing_wand.c: Pass full user-provided
+double precision resolution to renderer. Truncating the
+resolution causes problems in some cases. Resolves SourceForge
+bug 3058387 &quot;Incorrect Copy Compositing through C interface&quot;.</li>
+</ul>
+</blockquote>
+<p>2010-09-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (StringToList): Fix performance problem caused
+by using strlcpy.</li>
+<li>coders/pnm.c (ReadPNMImage): Q8 build should be able to read
+16-bit PGM images.</li>
+</ul>
+</blockquote>
+<p>2010-09-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MontageImageCommand): Fix memory leak of
+MontageInfo structure allocation in error handling path.</li>
+<li>magick/montage.c (MontageImages): Fix crash observed with
+&quot;-geometry x+0+0&quot;. Problem reported by Simon Rainer.</li>
+</ul>
+</blockquote>
+<p>2010-08-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Update to Automake 1.11.1.</li>
+</ul>
+</blockquote>
+<p>2010-08-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Use AC_USE_SYSTEM_EXTENSIONS to enable system API
+extensions.</li>
+</ul>
+</blockquote>
+<p>2010-08-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (ModifyCache): Fix deadlock in
+ClonePixelCache() which was caused by using the same semaphore
+pointer in the source and destination images. Problem was
+reported by Stefan Schramowski.</li>
+</ul>
+</blockquote>
+<p>2010-08-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/info.c (WriteINFOImage): Added an <cite>INFO</cite> coder which
+produces textual image description output similar to <cite>identify</cite>
+but may be used with convert like &quot;gm convert myfile info:-&quot;.
+Feature suggested by Stefan Schramowski.</li>
+</ul>
+</blockquote>
+<p>2010-08-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am (TESTS_PS_XFAIL_TESTS): Expect EPT tests to
+fail if Ghostscript is missing.</li>
+<li>configure.ac: Updated to Autoconf 2.67.</li>
+<li>magick/render.c (DrawImage): Use StringToGravityType() to parse
+gravity values.</li>
+</ul>
+</blockquote>
+<p>2010-07-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Document histogram-threshold setting.</li>
+<li>magick/enhance.c (NormalizeImage): Add support for
+histogram-threshold setting to specify the percentage of the
+histogram to discard when computing image normalization parameters
+(default is 0.1%). For example <cite>-set histogram-threshold 0.01
+-normalize</cite>.</li>
+<li>www/api/types.rst: Update Image structure member documentation.</li>
+</ul>
+</blockquote>
+<p>2010-07-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Add a test for posix_spawnp(). Results may be
+used in later development.</li>
+</ul>
+</blockquote>
+<p>2010-07-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am (TESTS_PS_XFAIL_TESTS): PDF tests are expected
+to fail if Ghostscript is not available.</li>
+<li>magick/utility.c (MagickStrlCat, MagickStrlCpy): Add handling
+for the case where size is zero in order to be conformant with the
+strlcat() and strlcpy() formal descriptions. GraphicsMagick does
+its best to never pass a size of zero so an assertion that size is
+not zero remains in order to help catch bugs in GraphicsMagick.
+Issue was reported by Albert Cahalan.</li>
+</ul>
+</blockquote>
+<p>2010-07-10 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Always scale tRNS color to 16-bit short. Otherwise,
+transparency was sometimes lost while reading PNG files whose depth
+is different from the Quantum depth.</li>
+</ul>
+</blockquote>
+<p>2010-07-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (LOG_TIFF_BLOB_IO): Define LOG_TIFF_BLOB_IO=1 when
+building GraphicsMagick in order to enable verbose logging from
+the TIFFClientOpen() registered callbacks when <cite>coder</cite> logging is
+enabled.</li>
+</ul>
+</blockquote>
+<p>2010-06-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwfile.c: Deal with formats which don't have an extension
+by prepending the magic specifier to the file name specification.</li>
+<li>coders/mpr.c (RegisterMPRImage): MPR and MPRI are not useful
+file extensions.</li>
+<li>magick/command.c (CommandAccessMonitor): If the environment
+variable MAGICK_ACCESS_MONITOR is set to TRUE then also log
+invocations of the access monitor callback when -monitor is
+specified. This feature is intended to assist with understanding
+when the access monitor is invoked, and the arguments which are
+passed.</li>
+<li>magick/blob.c (OpenBlob): Throw an exception on error rather
+than depending on the invoking code to do so. Resolves
+SourceForge bug #3023437 &quot;Magick::Image::ping() does not throw
+exception in all cases&quot;.</li>
+</ul>
+</blockquote>
+<p>2010-06-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): The -colors, -map, and
+-monochrome options now take effect immediately rather than at the
+end of all other processing. This is is more intuitive and
+reasonable but may impact the output of scripts which place these
+options prior to additional image processing operations.</li>
+</ul>
+</blockquote>
+<p>2010-06-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (BlobToImage): If a temporary file must be used
+and the user has specified magic, then preserve the magic
+specifier when reading the temporary file.</li>
+<li>coders/mat.c (RegisterMATImage): More accurately describe MATLAB
+format support as &quot;MATLAB Level 5&quot;.</li>
+<li>magick/magic.c (StaticMagic): Automatically detect MATLAB Level
+5 format based on file header.</li>
+<li>PerlMagick/PerlMagickCheck.sh.in: Run PerlMagick tests in
+verbose mode so that all test output appears in &quot;test-suite.log&quot;
+if there is a failure.</li>
+<li>coders/Makefile.am (coders_mat_la_LIBADD): MAT coder is
+optionally dependent on zlib so zlib should be listed as a
+dependency.</li>
+<li>magick/blob.c (BlobToFile): MAGICK_IO_FSYNC=TRUE in the
+environment should cause file data to be explicitly synchronized
+prior to close.</li>
+</ul>
+</blockquote>
+<p>2010-06-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/files-documentation.isx: There are
+not currently any JPEG files in the www/images directory to
+distribute.</li>
+</ul>
+</blockquote>
+<p>2010-06-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ltdl/config/ltmain.sh: Update libtool to 2.2.10.</li>
+<li>magick/profile.c: Support lcms 2.0.</li>
+<li>configure.ac: Add support for configuring for lcms 2.0,
+controlled via a new --without-lcms2 option. By default lcms v2
+is used if it is available, otherwise v1.1X is used if it is
+available.</li>
+</ul>
+</blockquote>
+<p>2010-06-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ltdl/config/ltmain.sh: Update libtool to 2.2.8.</li>
+</ul>
+</blockquote>
+<p>2010-06-02 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c correctly scale bKGD chunk data in Q16 build</li>
+</ul>
+</blockquote>
+<p>2010-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Magick++/Image.rst: Fix documentation error which wrongly
+recommended multiplication by size of PixelPacket. Correction by
+Roel Baardman.</li>
+</ul>
+</blockquote>
+<p>2010-05-23 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c (ReadTXTImage): Ability to read multiple images.</li>
+</ul>
+</blockquote>
+<p>2010-05-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (DispatchImage): <cite>K</cite> channel was always
+output as black for &quot;CMYK&quot; specification unless image matte flag
+was True. Bug report and proposed solution by Lance Brown.</li>
+</ul>
+</blockquote>
+<p>2010-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c (ShearImage): When one of the shear angles was
+specified as zero, the shear request was ignored entirely. An
+simple optimization was using || rather than &amp;&amp; to test the
+angles. Resolves SourceForge issue #2991685 &quot;Shear command does
+not handle zero angles correctly&quot;.</li>
+</ul>
+</blockquote>
+<p>2010-05-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (InitializeMagick, DestroyMagick):
+InitializeMagick and DestroyMagick should be fully thread safe.</li>
+</ul>
+</blockquote>
+<p>2010-05-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gif.c (ReadGIFImage): Set the opacity value of the opaque
+color to transparent. Patch by Tim Baker.</li>
+<li>magick/image.c (SetImageColor): New function which is similar to
+SetImage() but which accepts the pixel color as a parameter rather
+than using the image background color. Patch by Tim Baker.</li>
+<li>magick/transform.c (CoalesceImages): When applying background
+disposal, fill the image with the transparent color, if one
+exists. Patch by Tim Baker. Resolves SourceForge patch ID
+2989472.</li>
+</ul>
+</blockquote>
+<p>2010-05-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c (ReadTXTImage): Matte channel was not being enabled
+for non-opaque images.
+(ReadTXTImage): Opacity values need to be inverted prior to
+ingestion.</li>
+</ul>
+</blockquote>
+<p>2010-04-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Documentation for -flatten and -mosaic has
+been improved.</li>
+<li>magick/transform.c (MosaicImages): The -mosaic command now
+respects the composition option specified by -compose as well as
+the image background color specified by -background.</li>
+</ul>
+</blockquote>
+<p>2010-04-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/*.c, magick/*.c: Eliminate many benign data race
+conditions.</li>
+</ul>
+</blockquote>
+<p>2010-04-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec.in: Avoid duplicate copies of documentation
+files. Put documentation into a versioned directory as used by
+Red Hat and CentOS. Include archive libraries in developer
+package.</li>
+<li>PerlMagick/Makefile.PL.in: Include support for DESTDIR so that
+RPM builds find the installed GraphicsMagick library.</li>
+</ul>
+</blockquote>
+<p>2010-04-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Under Solaris, make sure that OpenWindows Type1
+fonts do exist before deciding to use them. OpenSolaris does not
+provide these fonts.</li>
+</ul>
+</blockquote>
+<p>2010-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec.in: Fix RPM build. PerlMagick was not being
+built due to Makefile changes. Resolves SourceForge issue
+#2952696 &quot;RPM build broken: (Perl) file not found by glob&quot;.</li>
+<li>magick/quantize.c (ReduceImageColors): Progress message should
+include the image file name.</li>
+</ul>
+</blockquote>
+<p>2010-03-24 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Revised coders/jpeg.c to preserve the Exif profile.</li>
+</ul>
+</blockquote>
+<p>2010-03-24 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): Eliminated some of the deprecated
+direct access to ping_info-&gt;members.
+Eliminated support of very old libpng versions (1.0.11 and earlier).</li>
+</ul>
+</blockquote>
+<p>2010-03-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/delegate.c (GetPostscriptDelegateInfo): Add support for
+invoking &quot;gs-cmyk&quot; and &quot;gs-cmyka&quot; entries in delegates.mgk when
+ColorSeparationType or ColorSeparationMatteType is requested.
+Requisite entries in delegates.mgk are left for the user to add.</li>
+</ul>
+</blockquote>
+<p>2010-03-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (InitializeMagick): Don't initialize locale
+settings in InitializeMagick(). Resolves SourceForge bug #2967282
+&quot;setlocale called by GraphicsMagick&quot;.</li>
+</ul>
+</blockquote>
+<p>2010-03-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/{command.c, display.c}: Make sure that <cite>animate</cite>,
+<cite>display</cite>, and <cite>identify</cite> report any error only once, and then
+proceed to the next file name rather than quitting. Problem was
+reported by Patrick Welche.</li>
+</ul>
+</blockquote>
+<p>2010-03-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Released GraphicsMagick 1.3.12.</li>
+</ul>
+</blockquote>
+<p>2010-03-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Makefile.am: Update PerlMagick/Magick.pm in the
+source tree (as required) since it is distributed source and
+contains the current version number.</li>
+</ul>
+</blockquote>
+<p>2010-03-03 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>coders/png.c: restored missing &quot;US&quot; in PNG_USER_CHUNK_CACHE_MAX</dt>
+<dd>at line 102. Added some (unsigned long) typecasts on print statements
+to stifle warnings.</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2010-03-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Updated libpng to 1.2.43. Resolves CVE-2010-0205 as
+pertains to GraphicsMagick Windows build.</li>
+</ul>
+</blockquote>
+<p>2010-03-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwfile_DCX_*.sh: Add tests for reading and writing DCX.</li>
+<li>coders/pcx.c (WritePCXImage): DCX is not the same as PCX so only
+write DCX when requested to (and vice-versa).</li>
+<li>utilities/tests/convert-pipe-out.sh: New test to verify that
+<cite>convert</cite> can write to stdout.</li>
+<li>utilities/tests/convert-pipe-in.sh: New test to verify that
+<cite>convert</cite> can read from stdin.</li>
+<li>utilities/tests/convert-pipe-filter.sh: New test to verify that
+<cite>convert</cite> works properly as a filter.</li>
+<li>magick/image.c (SetImageInfo): The <cite>rectify</cite> parameter was found
+to not be sufficient to meet requirements since it was
+overloaded. The utilities would malfunction (hang or throw an
+exception) if requested to write to stdout. As a result, this
+parameter has been changed to a binary flag type parameter.
+Existing True/False values are mapped to equivalents using the new
+binary flag. This is intended to resolve Debian bug 571719
+&quot;graphicsmagick: &quot;convert&quot; command is broken&quot;, reported by
+Vladimir Stavrinov.</li>
+</ul>
+</blockquote>
+<p>2010-02-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Released GraphicsMagick 1.3.11.</li>
+</ul>
+</blockquote>
+<p>2010-02-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c (GetCompositionPixelIteratorCallback):
+OverCompositeOp and AtopCompositeOp may be replaced with
+CopyCompositeOp in the case where neither image has a matte
+channel.</li>
+<li>magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+Added -extent option to apply a background color canvas behind the
+image. Added -compose option to allow specifying the composition
+operator to use.</li>
+<li>magick/transform.c (ExtentImage): New function apply a
+background color canvas behind the image.</li>
+</ul>
+</blockquote>
+<p>2010-02-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Added a -thumbnail command to all of the GM
+sub-commands which currently support -resize. This is a resize
+method optimized for speed when reducing the size of the image
+(such as when creating thumbnails).</li>
+</ul>
+</blockquote>
+<p>2010-02-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (LocaleCompare, LocaleNCompare): Fix array
+index underflow which occurs if the char type is signed and the
+character value is in the extended range. Problem reported by
+Arseny Solokha. Resolves SourceForge patch #2953314.</li>
+</ul>
+</blockquote>
+<p>2010-02-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Released GraphicsMagick 1.3.10.</li>
+</ul>
+</blockquote>
+<p>2010-02-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/demo/demo.cpp (main): Split demo output frames into
+individual files to enable easier viewing.</li>
+</ul>
+</blockquote>
+<p>2010-02-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/GraphicsMagick.imdoc: Improve usage synopsis for
+<cite>convert</cite>. SourceForge feature request 2845965 &quot;confusing
+documentation&quot;.</li>
+<li>magick/display.c (MagickXDisplayImage): Image number was
+incorrect in window title.</li>
+<li>magick/render.c (DrawImage): Path points data allocation was
+much larger than it needed to be. Patch by Vladimir Lukianov.
+Resolves SourceForge issue 2947851 &quot;Memory allocation error on
+vector graphics (or mem bomb)&quot;.</li>
+<li>magick/constitute.c (WriteImages): +adjoin was not working
+correctly for the case when only one image frame is present. With
++adjoin and writing one frame to &quot;foo%d.jpg&quot; it was outputting
+&quot;foo%d.jpg&quot; rather than &quot;foo0.jpg&quot;. Problem reported by Frans
+Coetzee.</li>
+</ul>
+</blockquote>
+<p>2010-02-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Released GraphicsMagick 1.3.9.</li>
+</ul>
+</blockquote>
+<p>2010-02-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/imdoc2man: Bare single quotes at the beginning of a line
+need to be escaped in order to make roff happy. Problem reported
+by Daniel Kobras.</li>
+<li>magick/command.c (ImportImageCommand): Don't assign a pointer to
+static constant data into an array which uses heap allocated data.
+Avoids a &quot;double free&quot; error when using gm import -frame. Patch
+by Daniel Kobras.</li>
+<li>magick/color_lookup.c (QueryColorname): XPM does not support
+RGBA color syntax, but it does support RGB. Patch by Daniel
+Kobras.</li>
+<li>magick/blob.c (OpenBlob): Only form multi-part filename when
+required.</li>
+<li>magick/display.c (MagickXDisplayImage): The display <cite>-update</cite>
+option was only working in conjunction with the <cite>-delay</cite> option
+with a delay setting of 2 or greater. Problem reported by Sami
+Liedes. Patch by Vincent MAUGE. Resolves Debian bug ID 414779.</li>
+</ul>
+</blockquote>
+<p>2010-02-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (OpenBlob): Only apply scene substitution to
+the filename if adjoin is false.</li>
+<li>magick/constitute.c (WriteImage): If adjoin is true, then
+restore original filename specification since opening the blob
+modifies it. Resolves Debian bug ID 552998.</li>
+<li>magick/image.c (SetImageInfo): Don't check filename for scene
+substitution if adjoin is intentionally false. This allows saving
+to file names which look like they contain a scene substitution
+pattern.</li>
+<li>magick/command.c (MogrifyImage): Convolution failure results in
+a crash rather than an error report. Resolves Debian bug ID
+539251.</li>
+<li>magick/deprecate.c: The string constants LoadImageText,
+SaveImageText, LoadImagesText, and SaveImagesText should have been
+deprecated, rather than being entirely removed.</li>
+</ul>
+</blockquote>
+<p>2010-01-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Makefile.am (install-data-html): Make sure that only the
+necessary documentation files are installed.</li>
+</ul>
+</blockquote>
+<p>2010-01-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/body.isx: Strip out executable
+components which depend on proprietary MFC and ATL libraries.
+This means that &quot;gmdisplay.exe&quot; and &quot;ImageMagickObject&quot; are no
+longer distributed or installed via the Windows setup installer.
+When a new display application is developed based on open source
+libraries, then the display functionality and associations can be
+restored.</li>
+</ul>
+</blockquote>
+<p>2010-01-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/transform.c (FlattenImages): Apply the image background
+color under the initial canvas image if it is non-opaque.</li>
+<li>magick/composite.c (MagickCompositeImageUnderColor): New private
+function to apply a color underneath a non-opaque image.</li>
+</ul>
+</blockquote>
+<p>2010-01-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/prefetch.h: New header to provide wrapper macros for
+compiler-specific explicit prefetch APIs.</li>
+<li>magick/effect.c (BlurImageScanlines): Solid color images which
+only differed in the matte channel were not being blurred.</li>
+<li>magick/color.h (NotPixelMatch,PixelMatch): New macros to
+fully-compare a pixel, including matte.</li>
+<li>magick/resource.c (SetMagickResourceLimit): Invoke
+omp_set_num_threads() to set thread limit if ThreadsResource is
+requested.</li>
+<li>magick/pixel_cache.c (AllocateThreadViewSet): The number of
+cache views to allocate needs to be obtained from
+omp_get_max_threads(). Otherwise there is a crash if the number
+of threads is reduced from the original value.</li>
+</ul>
+</blockquote>
+<p>2010-01-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Released GraphicsMagick 1.3.8.</li>
+<li>NEWS.txt: Update for the 1.3.8 release.</li>
+</ul>
+</blockquote>
+<p>2010-01-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/benchmarks.rst: Update benchmark report to compare
+performance with ImageMagick 6.5.8-10.</li>
+</ul>
+</blockquote>
+<p>2010-01-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c (RotateImage, ShearImage): Ensure that errors
+propagate up to the API user. Don't overwrite a detailed
+exception message with a generic one. Don't return a bogus image
+if there is an error.</li>
+</ul>
+</blockquote>
+<p>2010-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/files-base.isx: Third party
+executables not included in the Visual Studio build are no longer
+bundled in the GraphicsMagick installer. This means that
+hp2xx.exe, mpeg2dec.exe, and mpeg2enc.exe are no longer
+distributed.</li>
+<li>www/Magick++/Image.rst: Emphasize that InitializeMagick() MUST
+be invoked, and make sure that all of the examples show use of it.</li>
+</ul>
+</blockquote>
+<p>2010-01-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/delegate.c (InvokeDelegate): Use MagickSpawnVP() under
+Windows as well.
+(InvokePostscriptDelegate): Use MagickSpawnVP() under Windows as
+well.</li>
+<li>magick/utility.c (MagickSpawnVP): Moved from unix_port.c.
+Updated implementation to use spawnvp() rather than fork()/exec()
+under Windows.</li>
+<li>configure.ac: Add check for Windows spawnvp function.
+Add check for process.h.</li>
+<li>magick/semaphore.c (DestroySemaphore): POSIX mutex statically
+initialized via PTHREAD_MUTEX_INITIALIZER should not be destroyed.</li>
+<li>configure.ac: DisableSlowOpenMP is now the default. Use
+--enable-openmp-slow to enable OpenMP for algorithms which
+sometimes run slower rather than faster.</li>
+</ul>
+</blockquote>
+<p>2010-01-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/version.h.in: Added MagickLibInterfaceNewest and
+MagickLibInterfaceOldest preprocessor defines so that applications
+may easily test for library versions while compiling.</li>
+</ul>
+</blockquote>
+<p>2010-01-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawPolygonPrimitive): Use restrict keyword.</li>
+<li>magick/pixel_iterator.c: Use restrict keyword.</li>
+<li>utilities/Makefile.am: Modules are supported in the shared
+library built so list-module.sh test should be expected to pass.</li>
+<li>configure.ac: Add WITH_SHARED_LIBS conditional.</li>
+</ul>
+</blockquote>
+<p>2010-01-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/version.h.in: Update copyright years.</li>
+<li>magick/semaphore.c: The return code from all pthread mutex APIs
+are now checked (not just initialize and destroy), and any error
+results in an immediate fatal exit.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2010.rst b/www/ChangeLog-2010.rst
new file mode 100644
index 0000000..ad54105
--- /dev/null
+++ b/www/ChangeLog-2010.rst
@@ -0,0 +1,668 @@
+2011-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickDescribeImage): Was sending
+ descriptive output to stdout rather than returning it in an
+ allocated string as intended.
+
+2011-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/draw.c, wand/drawing\_wand.c (MvgPrintf): Update to handle
+ C99 vsnprintf() return values.
+
+ - magick/draw.c, wand/drawing\_wand.c (DrawAnnotation): Linux
+ glibc does not pass extended text characters if "%.1024s"
+ formatting convention is used. Apparently it assumes that such
+ characters may be UTF8 and returns -1 rather than outputting the
+ string, even if it is assured to fit.
+
+2010-12-30 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Matlab file level clarification.
+
+2010-12-27 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mac.c New MacPaint image format reader added.
+
+2010-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Default to using a LZMAPRESET
+ value of 1 based on testing which observed minimal benefit, and
+ substantially more cost, from larger values. Value may be
+ specified by the user using command line syntax like `-define
+ tiff:lzmapreset=7` for purposes of further experimentation. Also
+ adjusted default strip memory values for each preset level.
+
+2010-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: Add LZMA support to PerlMagick.
+
+ - coders/tiff.c (WriteTIFFImage): Add TIFF LZMA compressor support.
+
+2010-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImages): Should send -verbose output to
+ stderr rather than stdout since otherwise usage in pipelines may
+ be broken. Resolves SourceForge issue 3131790 "AVS -verbose
+ prints to stdout".
+
+2010-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libtool: Upgrade to libtool 2.4.
+
+ - coders/pnm.c (ReadPNMImage): Start work on reading NetPBM PAM
+ format. Parses PAM header but pixels are not returned yet.
+
+ - magick/magic.c (StaticMagic): Be more specific when identifying
+ PNM subformats. Return the specific subformat name PBM, PGM, or
+ PPM rather than PNM. XV P7 format is now identified as "P7 332".
+ Add detection of NetPBM PAM format.
+
+2010-11-04 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - magick/effect.c: Added 5x5, 6x6, and 7x7 circular ordered dither
+ patterns to create a halftone effect.
+
+2010-09-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Document pcl:fit-to-page define.
+
+ - coders/pcl.c: Fix issue with printing a bi-level image on
+ Konica-Minolta printers. Define pcl:fit-to-page in order for the
+ printer to scale the image to fit the page. Patch by John
+ Sergeant.
+
+2010-09-19 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/png.c: removed an apparently harmless extra invocation
+ of ScaleShortToQuantum() due to cut-and-paste error in the
+ update of 2010-06-02. Also added a line to explicitly set
+ the opacity of the background\_color to OpaqueOpacity.
+
+2010-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c (ReadPDFImage): Enable use of PDF crop box via
+ -define pdf:use-cropbox=true. Patch contributed by Chris Gilling.
+ SourceForge patch ID 3063794, "Add support for using crop box for
+ pdf import".
+
+2010-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Image.cpp (backgroundColor, borderColor, matteColor):
+ Opacity part of user-specified color needs to be preserved.
+ Problem was reported by Alexander Zheltov.
+
+2010-09-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Applied Automake 1.11.1 patch by Ralf Wildenhues
+ which is necessary for the test suite to pass under Windows/MinGW
+ due to command line length limits.
+
+2010-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/draw.c, wand/drawing\_wand.c: Pass full user-provided
+ double precision resolution to renderer. Truncating the
+ resolution causes problems in some cases. Resolves SourceForge
+ bug 3058387 "Incorrect Copy Compositing through C interface".
+
+2010-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (StringToList): Fix performance problem caused
+ by using strlcpy.
+
+ - coders/pnm.c (ReadPNMImage): Q8 build should be able to read
+ 16-bit PGM images.
+
+2010-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MontageImageCommand): Fix memory leak of
+ MontageInfo structure allocation in error handling path.
+
+ - magick/montage.c (MontageImages): Fix crash observed with
+ "-geometry x+0+0". Problem reported by Simon Rainer.
+
+2010-08-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Update to Automake 1.11.1.
+
+2010-08-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Use AC\_USE\_SYSTEM\_EXTENSIONS to enable system API
+ extensions.
+
+2010-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (ModifyCache): Fix deadlock in
+ ClonePixelCache() which was caused by using the same semaphore
+ pointer in the source and destination images. Problem was
+ reported by Stefan Schramowski.
+
+2010-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/info.c (WriteINFOImage): Added an `INFO` coder which
+ produces textual image description output similar to `identify`
+ but may be used with convert like "gm convert myfile info:-".
+ Feature suggested by Stefan Schramowski.
+
+2010-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am (TESTS\_PS\_XFAIL\_TESTS): Expect EPT tests to
+ fail if Ghostscript is missing.
+
+ - configure.ac: Updated to Autoconf 2.67.
+
+ - magick/render.c (DrawImage): Use StringToGravityType() to parse
+ gravity values.
+
+2010-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Document histogram-threshold setting.
+
+ - magick/enhance.c (NormalizeImage): Add support for
+ histogram-threshold setting to specify the percentage of the
+ histogram to discard when computing image normalization parameters
+ (default is 0.1%). For example `-set histogram-threshold 0.01
+ -normalize`.
+
+ - www/api/types.rst: Update Image structure member documentation.
+
+2010-07-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Add a test for posix\_spawnp(). Results may be
+ used in later development.
+
+2010-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am (TESTS\_PS\_XFAIL\_TESTS): PDF tests are expected
+ to fail if Ghostscript is not available.
+
+ - magick/utility.c (MagickStrlCat, MagickStrlCpy): Add handling
+ for the case where size is zero in order to be conformant with the
+ strlcat() and strlcpy() formal descriptions. GraphicsMagick does
+ its best to never pass a size of zero so an assertion that size is
+ not zero remains in order to help catch bugs in GraphicsMagick.
+ Issue was reported by Albert Cahalan.
+
+2010-07-10 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/png.c: Always scale tRNS color to 16-bit short. Otherwise,
+ transparency was sometimes lost while reading PNG files whose depth
+ is different from the Quantum depth.
+
+2010-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (LOG\_TIFF\_BLOB\_IO): Define LOG\_TIFF\_BLOB\_IO=1 when
+ building GraphicsMagick in order to enable verbose logging from
+ the TIFFClientOpen() registered callbacks when `coder` logging is
+ enabled.
+
+2010-06-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwfile.c: Deal with formats which don't have an extension
+ by prepending the magic specifier to the file name specification.
+
+ - coders/mpr.c (RegisterMPRImage): MPR and MPRI are not useful
+ file extensions.
+
+ - magick/command.c (CommandAccessMonitor): If the environment
+ variable MAGICK\_ACCESS\_MONITOR is set to TRUE then also log
+ invocations of the access monitor callback when -monitor is
+ specified. This feature is intended to assist with understanding
+ when the access monitor is invoked, and the arguments which are
+ passed.
+
+ - magick/blob.c (OpenBlob): Throw an exception on error rather
+ than depending on the invoking code to do so. Resolves
+ SourceForge bug #3023437 "Magick::Image::ping() does not throw
+ exception in all cases".
+
+2010-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): The -colors, -map, and
+ -monochrome options now take effect immediately rather than at the
+ end of all other processing. This is is more intuitive and
+ reasonable but may impact the output of scripts which place these
+ options prior to additional image processing operations.
+
+2010-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (BlobToImage): If a temporary file must be used
+ and the user has specified magic, then preserve the magic
+ specifier when reading the temporary file.
+
+ - coders/mat.c (RegisterMATImage): More accurately describe MATLAB
+ format support as "MATLAB Level 5".
+
+ - magick/magic.c (StaticMagic): Automatically detect MATLAB Level
+ 5 format based on file header.
+
+ - PerlMagick/PerlMagickCheck.sh.in: Run PerlMagick tests in
+ verbose mode so that all test output appears in "test-suite.log"
+ if there is a failure.
+
+ - coders/Makefile.am (coders\_mat\_la\_LIBADD): MAT coder is
+ optionally dependent on zlib so zlib should be listed as a
+ dependency.
+
+ - magick/blob.c (BlobToFile): MAGICK\_IO\_FSYNC=TRUE in the
+ environment should cause file data to be explicitly synchronized
+ prior to close.
+
+2010-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/files-documentation.isx: There are
+ not currently any JPEG files in the www/images directory to
+ distribute.
+
+2010-06-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ltdl/config/ltmain.sh: Update libtool to 2.2.10.
+
+ - magick/profile.c: Support lcms 2.0.
+
+ - configure.ac: Add support for configuring for lcms 2.0,
+ controlled via a new --without-lcms2 option. By default lcms v2
+ is used if it is available, otherwise v1.1X is used if it is
+ available.
+
+2010-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ltdl/config/ltmain.sh: Update libtool to 2.2.8.
+
+2010-06-02 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/png.c correctly scale bKGD chunk data in Q16 build
+
+2010-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Magick++/Image.rst: Fix documentation error which wrongly
+ recommended multiplication by size of PixelPacket. Correction by
+ Roel Baardman.
+
+2010-05-23 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/txt.c (ReadTXTImage): Ability to read multiple images.
+
+2010-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (DispatchImage): `K` channel was always
+ output as black for "CMYK" specification unless image matte flag
+ was True. Bug report and proposed solution by Lance Brown.
+
+2010-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c (ShearImage): When one of the shear angles was
+ specified as zero, the shear request was ignored entirely. An
+ simple optimization was using || rather than && to test the
+ angles. Resolves SourceForge issue #2991685 "Shear command does
+ not handle zero angles correctly".
+
+2010-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (InitializeMagick, DestroyMagick):
+ InitializeMagick and DestroyMagick should be fully thread safe.
+
+2010-05-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/gif.c (ReadGIFImage): Set the opacity value of the opaque
+ color to transparent. Patch by Tim Baker.
+
+ - magick/image.c (SetImageColor): New function which is similar to
+ SetImage() but which accepts the pixel color as a parameter rather
+ than using the image background color. Patch by Tim Baker.
+
+ - magick/transform.c (CoalesceImages): When applying background
+ disposal, fill the image with the transparent color, if one
+ exists. Patch by Tim Baker. Resolves SourceForge patch ID
+ 2989472.
+
+2010-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/txt.c (ReadTXTImage): Matte channel was not being enabled
+ for non-opaque images.
+ (ReadTXTImage): Opacity values need to be inverted prior to
+ ingestion.
+
+2010-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Documentation for -flatten and -mosaic has
+ been improved.
+
+ - magick/transform.c (MosaicImages): The -mosaic command now
+ respects the composition option specified by -compose as well as
+ the image background color specified by -background.
+
+2010-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/\*.c, magick/\*.c: Eliminate many benign data race
+ conditions.
+
+2010-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - GraphicsMagick.spec.in: Avoid duplicate copies of documentation
+ files. Put documentation into a versioned directory as used by
+ Red Hat and CentOS. Include archive libraries in developer
+ package.
+
+ - PerlMagick/Makefile.PL.in: Include support for DESTDIR so that
+ RPM builds find the installed GraphicsMagick library.
+
+2010-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Under Solaris, make sure that OpenWindows Type1
+ fonts do exist before deciding to use them. OpenSolaris does not
+ provide these fonts.
+
+2010-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - GraphicsMagick.spec.in: Fix RPM build. PerlMagick was not being
+ built due to Makefile changes. Resolves SourceForge issue
+ #2952696 "RPM build broken: (Perl) file not found by glob".
+
+ - magick/quantize.c (ReduceImageColors): Progress message should
+ include the image file name.
+
+2010-03-24 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - Revised coders/jpeg.c to preserve the Exif profile.
+
+2010-03-24 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/png.c (ReadOnePNGImage): Eliminated some of the deprecated
+ direct access to ping\_info->members.
+ Eliminated support of very old libpng versions (1.0.11 and earlier).
+
+2010-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/delegate.c (GetPostscriptDelegateInfo): Add support for
+ invoking "gs-cmyk" and "gs-cmyka" entries in delegates.mgk when
+ ColorSeparationType or ColorSeparationMatteType is requested.
+ Requisite entries in delegates.mgk are left for the user to add.
+
+2010-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (InitializeMagick): Don't initialize locale
+ settings in InitializeMagick(). Resolves SourceForge bug #2967282
+ "setlocale called by GraphicsMagick".
+
+2010-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/{command.c, display.c}: Make sure that `animate`,
+ `display`, and `identify` report any error only once, and then
+ proceed to the next file name rather than quitting. Problem was
+ reported by Patrick Welche.
+
+2010-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Released GraphicsMagick 1.3.12.
+
+2010-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Makefile.am: Update PerlMagick/Magick.pm in the
+ source tree (as required) since it is distributed source and
+ contains the current version number.
+
+2010-03-03 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/png.c: restored missing "US" in PNG\_USER\_CHUNK\_CACHE\_MAX
+ at line 102. Added some (unsigned long) typecasts on print statements
+ to stifle warnings.
+
+2010-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Updated libpng to 1.2.43. Resolves CVE-2010-0205 as
+ pertains to GraphicsMagick Windows build.
+
+2010-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwfile\_DCX\_\*.sh: Add tests for reading and writing DCX.
+
+ - coders/pcx.c (WritePCXImage): DCX is not the same as PCX so only
+ write DCX when requested to (and vice-versa).
+
+ - utilities/tests/convert-pipe-out.sh: New test to verify that
+ `convert` can write to stdout.
+
+ - utilities/tests/convert-pipe-in.sh: New test to verify that
+ `convert` can read from stdin.
+
+ - utilities/tests/convert-pipe-filter.sh: New test to verify that
+ `convert` works properly as a filter.
+
+ - magick/image.c (SetImageInfo): The `rectify` parameter was found
+ to not be sufficient to meet requirements since it was
+ overloaded. The utilities would malfunction (hang or throw an
+ exception) if requested to write to stdout. As a result, this
+ parameter has been changed to a binary flag type parameter.
+ Existing True/False values are mapped to equivalents using the new
+ binary flag. This is intended to resolve Debian bug 571719
+ "graphicsmagick: "convert" command is broken", reported by
+ Vladimir Stavrinov.
+
+2010-02-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Released GraphicsMagick 1.3.11.
+
+2010-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c (GetCompositionPixelIteratorCallback):
+ OverCompositeOp and AtopCompositeOp may be replaced with
+ CopyCompositeOp in the case where neither image has a matte
+ channel.
+
+ - magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+ Added -extent option to apply a background color canvas behind the
+ image. Added -compose option to allow specifying the composition
+ operator to use.
+
+ - magick/transform.c (ExtentImage): New function apply a
+ background color canvas behind the image.
+
+2010-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Added a -thumbnail command to all of the GM
+ sub-commands which currently support -resize. This is a resize
+ method optimized for speed when reducing the size of the image
+ (such as when creating thumbnails).
+
+2010-02-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (LocaleCompare, LocaleNCompare): Fix array
+ index underflow which occurs if the char type is signed and the
+ character value is in the extended range. Problem reported by
+ Arseny Solokha. Resolves SourceForge patch #2953314.
+
+2010-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Released GraphicsMagick 1.3.10.
+
+2010-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/demo/demo.cpp (main): Split demo output frames into
+ individual files to enable easier viewing.
+
+2010-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/GraphicsMagick.imdoc: Improve usage synopsis for
+ `convert`. SourceForge feature request 2845965 "confusing
+ documentation".
+
+ - magick/display.c (MagickXDisplayImage): Image number was
+ incorrect in window title.
+
+ - magick/render.c (DrawImage): Path points data allocation was
+ much larger than it needed to be. Patch by Vladimir Lukianov.
+ Resolves SourceForge issue 2947851 "Memory allocation error on
+ vector graphics (or mem bomb)".
+
+ - magick/constitute.c (WriteImages): +adjoin was not working
+ correctly for the case when only one image frame is present. With
+ +adjoin and writing one frame to "foo%d.jpg" it was outputting
+ "foo%d.jpg" rather than "foo0.jpg". Problem reported by Frans
+ Coetzee.
+
+2010-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Released GraphicsMagick 1.3.9.
+
+2010-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/imdoc2man: Bare single quotes at the beginning of a line
+ need to be escaped in order to make roff happy. Problem reported
+ by Daniel Kobras.
+
+ - magick/command.c (ImportImageCommand): Don't assign a pointer to
+ static constant data into an array which uses heap allocated data.
+ Avoids a "double free" error when using gm import -frame. Patch
+ by Daniel Kobras.
+
+ - magick/color\_lookup.c (QueryColorname): XPM does not support
+ RGBA color syntax, but it does support RGB. Patch by Daniel
+ Kobras.
+
+ - magick/blob.c (OpenBlob): Only form multi-part filename when
+ required.
+
+ - magick/display.c (MagickXDisplayImage): The display `-update`
+ option was only working in conjunction with the `-delay` option
+ with a delay setting of 2 or greater. Problem reported by Sami
+ Liedes. Patch by Vincent MAUGE. Resolves Debian bug ID 414779.
+
+2010-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (OpenBlob): Only apply scene substitution to
+ the filename if adjoin is false.
+
+ - magick/constitute.c (WriteImage): If adjoin is true, then
+ restore original filename specification since opening the blob
+ modifies it. Resolves Debian bug ID 552998.
+
+ - magick/image.c (SetImageInfo): Don't check filename for scene
+ substitution if adjoin is intentionally false. This allows saving
+ to file names which look like they contain a scene substitution
+ pattern.
+
+ - magick/command.c (MogrifyImage): Convolution failure results in
+ a crash rather than an error report. Resolves Debian bug ID
+ 539251.
+
+ - magick/deprecate.c: The string constants LoadImageText,
+ SaveImageText, LoadImagesText, and SaveImagesText should have been
+ deprecated, rather than being entirely removed.
+
+2010-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Makefile.am (install-data-html): Make sure that only the
+ necessary documentation files are installed.
+
+2010-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/body.isx: Strip out executable
+ components which depend on proprietary MFC and ATL libraries.
+ This means that "gmdisplay.exe" and "ImageMagickObject" are no
+ longer distributed or installed via the Windows setup installer.
+ When a new display application is developed based on open source
+ libraries, then the display functionality and associations can be
+ restored.
+
+2010-01-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/transform.c (FlattenImages): Apply the image background
+ color under the initial canvas image if it is non-opaque.
+
+ - magick/composite.c (MagickCompositeImageUnderColor): New private
+ function to apply a color underneath a non-opaque image.
+
+2010-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/prefetch.h: New header to provide wrapper macros for
+ compiler-specific explicit prefetch APIs.
+
+ - magick/effect.c (BlurImageScanlines): Solid color images which
+ only differed in the matte channel were not being blurred.
+
+ - magick/color.h (NotPixelMatch,PixelMatch): New macros to
+ fully-compare a pixel, including matte.
+
+ - magick/resource.c (SetMagickResourceLimit): Invoke
+ omp\_set\_num\_threads() to set thread limit if ThreadsResource is
+ requested.
+
+ - magick/pixel\_cache.c (AllocateThreadViewSet): The number of
+ cache views to allocate needs to be obtained from
+ omp\_get\_max\_threads(). Otherwise there is a crash if the number
+ of threads is reduced from the original value.
+
+2010-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Released GraphicsMagick 1.3.8.
+
+ - NEWS.txt: Update for the 1.3.8 release.
+
+2010-01-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/benchmarks.rst: Update benchmark report to compare
+ performance with ImageMagick 6.5.8-10.
+
+2010-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c (RotateImage, ShearImage): Ensure that errors
+ propagate up to the API user. Don't overwrite a detailed
+ exception message with a generic one. Don't return a bogus image
+ if there is an error.
+
+2010-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/files-base.isx: Third party
+ executables not included in the Visual Studio build are no longer
+ bundled in the GraphicsMagick installer. This means that
+ hp2xx.exe, mpeg2dec.exe, and mpeg2enc.exe are no longer
+ distributed.
+
+ - www/Magick++/Image.rst: Emphasize that InitializeMagick() MUST
+ be invoked, and make sure that all of the examples show use of it.
+
+2010-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/delegate.c (InvokeDelegate): Use MagickSpawnVP() under
+ Windows as well.
+ (InvokePostscriptDelegate): Use MagickSpawnVP() under Windows as
+ well.
+
+ - magick/utility.c (MagickSpawnVP): Moved from unix\_port.c.
+ Updated implementation to use spawnvp() rather than fork()/exec()
+ under Windows.
+
+ - configure.ac: Add check for Windows spawnvp function.
+ Add check for process.h.
+
+ - magick/semaphore.c (DestroySemaphore): POSIX mutex statically
+ initialized via PTHREAD\_MUTEX\_INITIALIZER should not be destroyed.
+
+ - configure.ac: DisableSlowOpenMP is now the default. Use
+ --enable-openmp-slow to enable OpenMP for algorithms which
+ sometimes run slower rather than faster.
+
+2010-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/version.h.in: Added MagickLibInterfaceNewest and
+ MagickLibInterfaceOldest preprocessor defines so that applications
+ may easily test for library versions while compiling.
+
+2010-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawPolygonPrimitive): Use restrict keyword.
+
+ - magick/pixel\_iterator.c: Use restrict keyword.
+
+ - utilities/Makefile.am: Modules are supported in the shared
+ library built so list-module.sh test should be expected to pass.
+
+ - configure.ac: Add WITH\_SHARED\_LIBS conditional.
+
+2010-01-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/version.h.in: Update copyright years.
+
+ - magick/semaphore.c: The return code from all pthread mutex APIs
+ are now checked (not just initialize and destroy), and any error
+ results in an immediate fatal exit.
diff --git a/www/ChangeLog-2011.html b/www/ChangeLog-2011.html
new file mode 100644
index 0000000..33139b2
--- /dev/null
+++ b/www/ChangeLog-2011.html
@@ -0,0 +1,731 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2011-12-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (AcquireCacheNexus):
+MirrorVirtualPixelMethod was broken.</li>
+</ul>
+</blockquote>
+<p>2011-12-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Improve configuration support for Open64 Compiler
+Suite: Version 4.2.5.2 compiler with OpenMP.</li>
+<li>coders/tga.c (ReadTGAImage): Assume that 32-bit TGA files have
+an alpha channel, even if they are not marked as such. Fixes
+SourceForge issue 3466908 &quot;TGA with alpha&quot;.</li>
+<li>configure.ac: Revert changeset eaa27346d8e9 which tried to avoid
+the OpenMP library being included multiple times because in some
+cases it is not included at all.</li>
+</ul>
+</blockquote>
+<p>2011-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (VersionCommand): For MSVC builds, report if
+SSE or SSE2 was used in the build.</li>
+<li>Release GraphicsMagick 1.3.13.</li>
+<li>Update libtiff to release 4.0.0</li>
+</ul>
+</blockquote>
+<p>2011-12-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Update libpng to release 1.5.7</li>
+</ul>
+</blockquote>
+<p>2011-12-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Update lcms2 to release 2.3</li>
+</ul>
+</blockquote>
+<p>2011-12-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Update Automake used to 1.11.2.</li>
+</ul>
+</blockquote>
+<p>2011-12-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/OpenMP.rst: Updated with new results, including 12-core
+Intel Xeon E5649 and 16-core AMD Opteron 6220 &quot;Bulldozer&quot; CPUs.</li>
+<li>magick/studio.h: Enable building and running correctly with
+Open64 Compiler Suite: Version 4.2.5.2 compiler with OpenMP.</li>
+<li>magick/command.c (BenchmarkImageCommand): Add -rawcsv option to
+benchmark to output only original data in a CSV format.</li>
+</ul>
+</blockquote>
+<p>2011-12-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Fix various issues noticed when cross-compiling for the
+i686-w64-mingw32 target.</li>
+</ul>
+</blockquote>
+<p>2011-12-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ConvolveImage): For Q8 and Q16 builds use
+'float' rather than 'double' for computations in order to improve
+performance with some compilers.</li>
+</ul>
+</blockquote>
+<p>2011-12-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ConvolveImage): Special-case grayscale images
+for better convolution performance.</li>
+</ul>
+</blockquote>
+<p>2011-12-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (BenchmarkUsage): -stepthreads now requires an
+argument which is the increment (starting at zero) to the number
+of threads for each step. This hastens benchmarking with a large
+number of cores.</li>
+</ul>
+</blockquote>
+<p>2011-12-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Eliminate use of FARDATA. It's no longer needed
+and will no longer be supplied by png.h in libpng-1.6.0.</li>
+</ul>
+</blockquote>
+<p>2011-12-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (BenchmarkImageCommand): Added Karp-Flatt
+metric to benchmark output.</li>
+</ul>
+</blockquote>
+<p>2011-12-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick.spec.in: Eliminate use of deprecated BuildPrereq
+in RPM spec file.</li>
+</ul>
+</blockquote>
+<p>2011-11-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (WriteImagesFile): Should set file in
+ImageInfo based on provided parameter rather than relying on it
+already being set. File argument was not being used.</li>
+</ul>
+</blockquote>
+<p>2011-11-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: For packed 10 bits, datums are now represented in
+the same (reversed) order for all RGB and YCbCr formats.
+Previously YCbCr 4:4:4 formats were not swapping the word datums
+because the only real-world files encountered did not swap the
+word datums. Resolves SourceForge bug 2057277 &quot;DPX 10bit CbYCr
+Image seems to be wrong&quot;.</li>
+<li>wand/magick_wand.c (MagickWriteImagesFile): New function to
+append images to a provided file handle. Resolves SourceForge
+issue 3046868 &quot;added MagickWriteImagesFile&quot;.</li>
+<li>magick/constitute.c (WriteImagesFile): New function to append
+images to a provided file handle.</li>
+<li>magick/blob.c (OpenBlob): Don't rewind already open file handle
+passed to OpenBlob() since we don't know the intended state of
+this file handle, and because it prevents appending to an existing
+file. This change is part of the fix for SourceForge issue
+3046868 &quot;added MagickWriteImagesFile&quot;.</li>
+<li>wand/magick_wand.c (MagickSetImageSavedType): New function to
+allow specifying the storage type used when saving the file
+(rather than changing the current image characteristics).
+Resolves SourceForge patch 3110185
+&quot;MagickGetImageSavedType()/MagickSetImageSavedType() API&quot;.
+(MagickGetImageSavedType): Return the storage type which will be
+used when the image is saved.</li>
+<li>magick/annotate.c (RenderFreetype): Add support for drawing text
+using a bitmap font. Resolves SourceForge patch 3230719 &quot;add
+support for drawing text with bitmap font to annotate.c&quot;.</li>
+<li>magick/profile.c (AppendImageProfile): Don't leak profile buffer
+while appending a chunk to an existing profile. Resolves
+SourceForge patch 3294496 &quot;Fix a memory leak in
+profile.c(AppendImageProfile)&quot;.</li>
+</ul>
+</blockquote>
+<p>2011-11-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (BenchmarkImageCommand): Include the number of
+threads used in the benchmark results output.
+(BenchmarkImageCommand): New benchmark option -stepthreads to
+execute the specified command with an increasing number of threads
+to measure how an algorithm benefits from threading.
+(BenchmarkImageCommand): Fix benchmark argument parsing so it is
+not order dependent.
+(BenchmarkImageCommand): Add a speedup indication to -stepthreads
+output.</li>
+<li>config/delegates.mgk.in: File names in gnuplot files need to be
+surrounded by double quotes or gnuplot parser will reject them.</li>
+</ul>
+</blockquote>
+<p>2011-11-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (GetMedianList): Return PixelPacket via pointer
+rather than by value.</li>
+<li>version.sh: For snapshots packages, PACKAGE_CHANGE_DATE now uses
+a form like &quot;snapshot-20111121&quot; rather than &quot;unreleased&quot; so it is
+possible to determine the vintage of an installed snapshot.</li>
+</ul>
+</blockquote>
+<p>2011-11-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tga.c (ReadTGAImage): Fix for poor TGA reading
+performance due to excessive use of GetBlobByte(). Performance is
+fixed by adding local buffering. Fixes SourceForge bug 3439531
+&quot;Slow TGA reading&quot;.</li>
+</ul>
+</blockquote>
+<p>2011-11-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (AdaptiveThresholdImage): More performance
+improvements.</li>
+</ul>
+</blockquote>
+<p>2011-11-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/analyze.c (GetImageBoundingBox): Add a special case to
+handle absolute color comparison.</li>
+</ul>
+</blockquote>
+<p>2011-11-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Update libpng to 1.5.6 release.</li>
+</ul>
+</blockquote>
+<p>2011-10-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Avoid linker warnings when building GraphicsMagick
+regarding OpenMP library being included multiple times.</li>
+</ul>
+</blockquote>
+<p>2011-10-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c (GetIPTCStream): Eliminate possible use of
+uninitialized data when parsing long format tag length.</li>
+</ul>
+</blockquote>
+<p>2011-10-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/import.c: Move low-level pixel import functions from
+constitute.c to new file import.c.</li>
+<li>magick/export.c: Move low-level pixel export functions from
+constitute.c to new file export.c.</li>
+<li>magick/floats.c: Move Richard Nolde's floating point conversion
+functions from constitute.c to new file floats.c.</li>
+</ul>
+</blockquote>
+<p>2011-10-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libtool: Updated to libtool 2.4.2.</li>
+<li>configure.ac: Automake conditional for HasPNG can not itself be
+conditional. Indent PNG script code appropriately.</li>
+</ul>
+</blockquote>
+<p>2011-10-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (AUTOMAKE_OPTIONS): Distribute lzma-compressed
+tarball in 'xz' format rather than deprecated 'lzma' format.</li>
+</ul>
+</blockquote>
+<p>2011-10-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Fix syntax error with GSCMYKDevice ('==' rather
+than '='). Thanks to Glenn Randers-Pehrson for noticing and
+reporting the issue.</li>
+</ul>
+</blockquote>
+<p>2011-10-12 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Use a &quot;for&quot; loop in configure.ac to find libpngNN.</li>
+</ul>
+</blockquote>
+<p>2011-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/pixel_wand.c (NewPixelWand): Invoke InitializeMagick()
+automatically in case user forgets to do so.</li>
+<li>wand/drawing_wand.c (NewDrawingWand): Invoke InitializeMagick()
+automatically in case user forgets to do so.</li>
+<li>wand/magick_wand.c (NewMagickWand): Invoke InitializeMagick()
+automatically in case user forgets to do so.</li>
+<li>png: libpng sources were updated to release 1.5.4.</li>
+</ul>
+</blockquote>
+<p>2011-10-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): TIFFGetField() on
+TIFFTAG_OPIIMAGEID was causing a crash due to an argument
+mis-match between GraphicsMagick and libtiff. Also fixed a few
+GCC 4.6 warnings. Problem was reported by Dylan Millikin.</li>
+</ul>
+</blockquote>
+<p>2011-10-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickSetDepth): New function to set the
+depth used when reading from an image format which requires that
+the depth be specified in advance.
+(MagickReadImageBlob): Use BlobToImage() to read the blob.</li>
+<li>magick/effect.c (AdaptiveThresholdImage): Reduce or eliminate
+expensive floating point calculations when possible.</li>
+<li>wand/magick_wand.c (MagickSetFormat): New Wand function to allow
+setting the file or blob format before it has been read.</li>
+</ul>
+</blockquote>
+<p>2011-09-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/inc/tasks-install-perlmagick.isx: Windows
+setup installer now installs PerlMagick built against ActiveState
+Perl v5.12.4 build 1205.</li>
+<li>magick/annotate.c (RenderFreetype): Eliminate spurious &quot;out of
+memory&quot; exceptions due to empty text string.</li>
+</ul>
+</blockquote>
+<p>2011-09-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/module.c (ModuleAliases): PAM format is handled by PNM
+coder.</li>
+<li>jpeg: Record that jpeg sources were updated to release v8c.</li>
+<li>lcms: Record that lcms sources were updated to release 2.2.</li>
+<li>png: Record that png sources were updated to release 1.5.4.</li>
+<li>tiff: Record that tiff sources were updated to release 4.0.0beta7.</li>
+<li>xml: Record that libxml2 sources were updated to release 2.7.8.</li>
+<li>zlib: Record that zlib sources were updated to release 1.2.5.</li>
+<li>VisualMagick/installer/inc/body.isx: Set MagickConfigDirectory
+for DLL build so that .mgk files are put in application top
+directory. This makes installation layout between static and DLL
+builds more similar.</li>
+</ul>
+</blockquote>
+<p>2011-08-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/list.c (AppendImageToList): Documentation for
+AppendImageToList() was wrong. Problem was reported by Brad
+Harder.</li>
+</ul>
+</blockquote>
+<p>2011-08-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/display.c (MagickXMagickCommand): Display 'save' and
+'print' should display useful error details. Problem was reported
+by Brad Harder.</li>
+</ul>
+</blockquote>
+<p>2011-08-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/semaphore.c (AllocateSemaphoreInfo): Enable pthread mutex
+error checking if MAGICK_DEBUG is defined when the code is
+compiled. This mode helps validate that mutexes are used
+correctly. No longer enable recursive mutexes since the
+GraphicsMagick logic should be able to operate without this
+assistance.</li>
+</ul>
+</blockquote>
+<p>2011-08-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcm.c (DCM_ReadOffsetTable): Fix wrong cast noticed when
+compiling with LLVM.</li>
+</ul>
+</blockquote>
+<p>2011-08-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enhance.c (LevelImageChannel): Fix documented prototype.
+Problem was reported by Brad Harder.</li>
+</ul>
+</blockquote>
+<p>2011-07-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (AcquireOneCacheViewPixelInlined): Only use
+image colormap if the image storage class is PseudoClass.
+Eliminates a core dump when the image is in CMYK space.</li>
+</ul>
+</blockquote>
+<p>2011-07-20 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: account for changed typecast of png_get_iCCP
+argument in libpng15</li>
+</ul>
+</blockquote>
+<p>2011-07-20 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: look for libpng15, libpng14, libpng12, and libpng
+in that order.</li>
+</ul>
+</blockquote>
+<p>2011-07-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Update to libpng 1.5.4.</li>
+</ul>
+</blockquote>
+<p>2011-06-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/docutils-articles.css: Style sheet syntax fixes. Patch by
+Mark Mitchell.</li>
+<li>scripts/html_fragments.py: Use proper quoting in banner search
+HTML. Patch by Mark Mitchell.</li>
+</ul>
+</blockquote>
+<p>2011-06-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageType): Fix documentation for enumeration
+names. The types need &quot;Type&quot; as part of the name. Problem was
+reported by Brad Harder.</li>
+</ul>
+</blockquote>
+<p>2011-06-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>scripts/html_fragments.py (banner_template): HTML banner
+improvements to go along with style-sheet changes.</li>
+<li>www/docutils-articles.css: Style-sheet improvements by Mark
+Mitchell to work better on small screens.</li>
+</ul>
+</blockquote>
+<p>2011-06-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/project.rst: Add a page for links to pages about the
+project. The intention is to use this page to reduce the clutter
+in the banner.</li>
+</ul>
+</blockquote>
+<p>2011-05-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Document tiff:group-three-options define.</li>
+<li>coders/tiff.c (WriteTIFFImage): Add support for a
+tiff:group-three-options define to allow power-users to set the
+value of the GROUP3OPTIONS tag.</li>
+</ul>
+</blockquote>
+<p>2011-05-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Makefile.am: Include Hg.*, remove CVS.*.</li>
+<li>scripts/html_fragments.py (nav_template): CVS tab changed to
+Source, which links to Hg.html.</li>
+<li>www/Hg.rst: Document Hg repository access.</li>
+</ul>
+</blockquote>
+<p>2011-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>scripts/rst2htmldeco.py (docutils_opts): Do not include a
+datestamp of any kind since it unnecessarily churns the
+repository, particularly if the output file did not otherwise
+change.</li>
+<li>INSTALL-unix.txt: Fix typo in description of --without-lzma.</li>
+</ul>
+</blockquote>
+<p>2011-05-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (ReadJPEGImage): Treat exceptions thrown by
+jpeg_finish_decompress() as warnings rather than errors.
+(JPEGErrorHandler): Handle JPEG errors directly rather than
+passing them to a message formatting routine for handling. Also
+added useful logging.
+(JPEGMessageHandler): Only handle JPEG traces and warnings. Also
+added useful logging.</li>
+</ul>
+</blockquote>
+<p>2011-05-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (EmitMessage): Treat an unhandled EXP marker as a
+warning rather than a hard error. Resolves SourceForge issue
+3297995 &quot;Unsupported marker type 0xdf&quot;.</li>
+</ul>
+</blockquote>
+<p>2011-05-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (AppendImages): If the input list only contains
+one image, then return a new handle to the one image in the list
+rather than reporting an exception. Problem was reported by Ravil
+Rakhimgulov (&quot;Hunter1972&quot;).</li>
+</ul>
+</blockquote>
+<p>2011-04-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageColorRegion): New function to set the
+constant pixel color for a specified region of the image.
+(AppendImages): Only color background pixels when needed.</li>
+</ul>
+</blockquote>
+<p>2011-04-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Added TIFF writer support for
+JBIG1 compression. Not proven to work yet.</li>
+<li>magick/image.h (CompressionType): Added Group3Compression as an
+alias for already existing FaxCompression. Added
+JPEG2000Compression, JBIG1Compression, and JBIG2Compression for
+future use.</li>
+</ul>
+</blockquote>
+<p>2011-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: For MinGW32 use 64-bit value formatting
+conventions which will work with any version of the WIN32 CRT.</li>
+</ul>
+</blockquote>
+<p>2011-04-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (WriteJPEGImage): Properly handle errors reported
+by the JPEG library when writing. Up to now, JPEG library simply
+invoked exit(), which crashed or hung if driven by Magick++ API.
+Fixes SourceForge bug 3106947 &quot;Assertion failure when saving an
+&quot;invalid&quot; image as JPEG&quot;.</li>
+<li>magick/module.c (ModuleAliases): Delete &quot;XTRNBSTR&quot;-entry. Fix by
+Stefan Graff.</li>
+<li>contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp
+(Perform): Member &quot;Perform&quot; - out-commented SafeArrayAccessData
+and following SafeArrayUnaccessData. Fix by Stefan Graff.</li>
+<li>contrib/win32/ATL/ImageMagickObject/MagickImage.cpp: Delete
+&quot;XTRNSTREAM&quot;-branch because &quot;XTRNSTREAM&quot; doesn't exist
+anymore. Fix by Stefan Graff.</li>
+<li>coders/xtrn.c: In function &quot;WriteXTRNImage&quot; there is no branch
+for XTRNARRAY. Fix by Stefan Graff.</li>
+<li>PerlMagick/Magick.xs: AdaptiveThreshold offset argument was
+being parsed into an 'unsigned long' rather than 'double' as it
+should have been. This resulted in inability to handle negative
+offsets. Fixes SourceForge bug 3288735 &quot;PerlMagick issue with
+AdaptiveThreshold&quot;.</li>
+<li>coders/jpeg.c (ReadIPTCProfile): JPEG may deliver IPTC profile
+in chunks but code was only allowing one chunk, even though it was
+otherwise prepared to concatenate chunks. Fixes SourceForge bug
+2978422 &quot;Clipping paths in JPG images are truncated&quot;.</li>
+<li>magick/utility.c (GetToken): Fix case where parser may run off
+end of string. Also add asserts to check for passing null
+pointer.</li>
+</ul>
+</blockquote>
+<p>2011-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/channel.c (ChannelImage): Report an error if the
+requested channel is not compatible with the image colorspace.
+Only deals with CMYK/RGB conflicts. Resolves SourceForge issue
+3283046 &quot;Bug in CMYK&quot;.</li>
+</ul>
+</blockquote>
+<p>2011-03-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c (ReadTXTImage): Throw error if attempt to read
+empty file.</li>
+<li>coders/{fits.c,mac.c,miff.c,pcd.c,pict.c,ps3.c,rla.c,txt.c}:
+Format requires seekable stream.</li>
+<li>coders/pnm.c (WritePNMImage): Implement writer for PAM format.</li>
+<li>coders/ept.c (WriteEPTImage): Fix error handling for case when
+TIFF writer fails.</li>
+<li>magick/constitute.c (ReadImage): Use of GetBlobStatus() to
+evaluate image reader success is bogus.
+(MagickGetQuantumSamplesPerPixel): New private method to return
+the number of samples returned per pixel for a given quantum type.</li>
+</ul>
+</blockquote>
+<p>2011-03-14 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage(): Fixed a rounding error in
+writing the pHYs chunk (it was truncating instead of rounding).</li>
+</ul>
+</blockquote>
+<p>2011-02-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (MagickPanicSignalHandler,MagickSignalHandler):
+Don't invoke DestroyMagick() since there may be OpenMP worker
+threads still running which are using data which would be
+deallocated. Instead we invoke PurgeTemporaryFiles() to remove
+any existing temporary files. Valgrind will report leaks if the
+program is terminated by a signal but this causes no actual harm.
+Resolves SourceForge issue 3165456 &quot;^C causes semaphore failure in
+MacOSX&quot;.
+(MagickPanicSignalHandler): Invoke abort() in panic signal handler
+so that we will reliably get a core dump.</li>
+<li>magick/tempfile.c (PurgeTemporaryFiles): New private function to
+remove any existing temporary files but without destroying
+temporary file semaphore.</li>
+</ul>
+</blockquote>
+<p>2011-02-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (ReadPNMImage): Fix mis-placed break in PAM header
+parser.</li>
+<li>wand/magick_wand.c (MagickWriteImageBlob): Improve the
+documentation to mention the related use of MagickSetImageFormat()
+and MagickResetIterator().</li>
+</ul>
+</blockquote>
+<p>2011-02-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/xwindow.c (MagickXBestFont): Check for a few more common
+font names, and ensure to always check for &quot;fixed&quot; as a final
+fallback.</li>
+</ul>
+</blockquote>
+<p>2011-02-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>config/delegates.mgk.in: Added gs-cmyk entry. Used if '-type
+ColorSeparation' is specified on the command-line prior to the PDF
+or Postscript file name. This entry specifies use of the
+Ghostscript PAM driver which is capable of supporting CMYK output.
+This may be useful if it is desired to apply CMYK color profiles
+to the image returned from the PDF. As fair warning, it seems
+that Ghostscript 8.62 outputs CMYK even if the PDF was in RGB
+space if the PAM driver is used.</li>
+<li>coders/pnm.c (ReadPNMImage): Add support for reading netpbm's
+PAM format.</li>
+</ul>
+</blockquote>
+<p>2011-02-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwblob.c, tests/rwfile.c: Fixes to help tests work when
+testing with multiple frames.</li>
+<li>coders/sgi.c: SGI format is not documented to support multiple
+frames. Remove the half-baked extension for it.</li>
+</ul>
+</blockquote>
+<p>2011-02-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;&#46;&#46;">glennrp<span>&#64;</span>simple<span>&#46;</span><span>&#46;</span><span>&#46;</span></a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (ReadBMPImage): Changed file_size greater than
+expected from a corrupt-image error to a debug log entry.
+File_size too small is still an error, and made that so also for
+BI_RGB images which were previously exempted from the test.</li>
+</ul>
+</blockquote>
+<p>2011-01-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwblob.c, tests/rwfile.c: Validate the data in each image
+frame, validate that each read returns the same number of frames,
+and validate that the correct number of frames was ultimately
+returned.</li>
+<li>magick/blob.c (SyncBlob): Disable bogus code which attempted to
+replicate the blob I/O object across all images in the list when
+the blob is synced. Leave a less bogus bit of code in place (but
+commented out) in case such functionality is deemed to actually be
+needed in the future. The previous code was copying structs on
+top of each other, including a pointer member to a semaphore.</li>
+</ul>
+</blockquote>
+<p>2011-01-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Changes.rst: Add a new Changes page to wrap up the yearly
+change logs to lessen download size.</li>
+<li>scripts/changelog2rst.sh: Simple utility to format ChangeLog
+format into something resembling reStructuredText.</li>
+<li>www/Makefile.am: Use reStructuredText to format the ChangeLog
+files to HTML so that we can inherit the improved formatting and
+page style.</li>
+<li>coders/pnm.c (ReadPNMImage): Support for multi-frame PNM was
+botched due to on-going edits to support PAM format.</li>
+</ul>
+</blockquote>
+<p>2011-01-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickDescribeImage): Was sending
+descriptive output to stdout rather than returning it in an
+allocated string as intended.</li>
+</ul>
+</blockquote>
+<p>2011-01-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/draw.c, wand/drawing_wand.c (MvgPrintf): Update to handle
+C99 vsnprintf() return values.</li>
+<li>magick/draw.c, wand/drawing_wand.c (DrawAnnotation): Linux
+glibc does not pass extended text characters if &quot;%.1024s&quot;
+formatting convention is used. Apparently it assumes that such
+characters may be UTF8 and returns -1 rather than outputting the
+string, even if it is assured to fit.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2011.rst b/www/ChangeLog-2011.rst
new file mode 100644
index 0000000..3da9cca
--- /dev/null
+++ b/www/ChangeLog-2011.rst
@@ -0,0 +1,607 @@
+2011-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (AcquireCacheNexus):
+ MirrorVirtualPixelMethod was broken.
+
+2011-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Improve configuration support for Open64 Compiler
+ Suite: Version 4.2.5.2 compiler with OpenMP.
+
+ - coders/tga.c (ReadTGAImage): Assume that 32-bit TGA files have
+ an alpha channel, even if they are not marked as such. Fixes
+ SourceForge issue 3466908 "TGA with alpha".
+
+ - configure.ac: Revert changeset eaa27346d8e9 which tried to avoid
+ the OpenMP library being included multiple times because in some
+ cases it is not included at all.
+
+2011-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (VersionCommand): For MSVC builds, report if
+ SSE or SSE2 was used in the build.
+
+ - Release GraphicsMagick 1.3.13.
+
+ - Update libtiff to release 4.0.0
+
+2011-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Update libpng to release 1.5.7
+
+2011-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Update lcms2 to release 2.3
+
+2011-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Update Automake used to 1.11.2.
+
+2011-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/OpenMP.rst: Updated with new results, including 12-core
+ Intel Xeon E5649 and 16-core AMD Opteron 6220 "Bulldozer" CPUs.
+
+ - magick/studio.h: Enable building and running correctly with
+ Open64 Compiler Suite: Version 4.2.5.2 compiler with OpenMP.
+
+ - magick/command.c (BenchmarkImageCommand): Add -rawcsv option to
+ benchmark to output only original data in a CSV format.
+
+2011-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Fix various issues noticed when cross-compiling for the
+ i686-w64-mingw32 target.
+
+2011-12-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ConvolveImage): For Q8 and Q16 builds use
+ 'float' rather than 'double' for computations in order to improve
+ performance with some compilers.
+
+2011-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ConvolveImage): Special-case grayscale images
+ for better convolution performance.
+
+2011-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (BenchmarkUsage): -stepthreads now requires an
+ argument which is the increment (starting at zero) to the number
+ of threads for each step. This hastens benchmarking with a large
+ number of cores.
+
+2011-12-07 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/png.c: Eliminate use of FARDATA. It's no longer needed
+ and will no longer be supplied by png.h in libpng-1.6.0.
+
+2011-12-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (BenchmarkImageCommand): Added Karp-Flatt
+ metric to benchmark output.
+
+2011-12-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - GraphicsMagick.spec.in: Eliminate use of deprecated BuildPrereq
+ in RPM spec file.
+
+2011-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (WriteImagesFile): Should set file in
+ ImageInfo based on provided parameter rather than relying on it
+ already being set. File argument was not being used.
+
+2011-11-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c: For packed 10 bits, datums are now represented in
+ the same (reversed) order for all RGB and YCbCr formats.
+ Previously YCbCr 4:4:4 formats were not swapping the word datums
+ because the only real-world files encountered did not swap the
+ word datums. Resolves SourceForge bug 2057277 "DPX 10bit CbYCr
+ Image seems to be wrong".
+
+ - wand/magick\_wand.c (MagickWriteImagesFile): New function to
+ append images to a provided file handle. Resolves SourceForge
+ issue 3046868 "added MagickWriteImagesFile".
+
+ - magick/constitute.c (WriteImagesFile): New function to append
+ images to a provided file handle.
+
+ - magick/blob.c (OpenBlob): Don't rewind already open file handle
+ passed to OpenBlob() since we don't know the intended state of
+ this file handle, and because it prevents appending to an existing
+ file. This change is part of the fix for SourceForge issue
+ 3046868 "added MagickWriteImagesFile".
+
+ - wand/magick\_wand.c (MagickSetImageSavedType): New function to
+ allow specifying the storage type used when saving the file
+ (rather than changing the current image characteristics).
+ Resolves SourceForge patch 3110185
+ "MagickGetImageSavedType()/MagickSetImageSavedType() API".
+ (MagickGetImageSavedType): Return the storage type which will be
+ used when the image is saved.
+
+ - magick/annotate.c (RenderFreetype): Add support for drawing text
+ using a bitmap font. Resolves SourceForge patch 3230719 "add
+ support for drawing text with bitmap font to annotate.c".
+
+ - magick/profile.c (AppendImageProfile): Don't leak profile buffer
+ while appending a chunk to an existing profile. Resolves
+ SourceForge patch 3294496 "Fix a memory leak in
+ profile.c(AppendImageProfile)".
+
+2011-11-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (BenchmarkImageCommand): Include the number of
+ threads used in the benchmark results output.
+ (BenchmarkImageCommand): New benchmark option -stepthreads to
+ execute the specified command with an increasing number of threads
+ to measure how an algorithm benefits from threading.
+ (BenchmarkImageCommand): Fix benchmark argument parsing so it is
+ not order dependent.
+ (BenchmarkImageCommand): Add a speedup indication to -stepthreads
+ output.
+
+ - config/delegates.mgk.in: File names in gnuplot files need to be
+ surrounded by double quotes or gnuplot parser will reject them.
+
+2011-11-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (GetMedianList): Return PixelPacket via pointer
+ rather than by value.
+
+ - version.sh: For snapshots packages, PACKAGE\_CHANGE\_DATE now uses
+ a form like "snapshot-20111121" rather than "unreleased" so it is
+ possible to determine the vintage of an installed snapshot.
+
+2011-11-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tga.c (ReadTGAImage): Fix for poor TGA reading
+ performance due to excessive use of GetBlobByte(). Performance is
+ fixed by adding local buffering. Fixes SourceForge bug 3439531
+ "Slow TGA reading".
+
+2011-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (AdaptiveThresholdImage): More performance
+ improvements.
+
+2011-11-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/analyze.c (GetImageBoundingBox): Add a special case to
+ handle absolute color comparison.
+
+2011-11-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Update libpng to 1.5.6 release.
+
+2011-10-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Avoid linker warnings when building GraphicsMagick
+ regarding OpenMP library being included multiple times.
+
+2011-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c (GetIPTCStream): Eliminate possible use of
+ uninitialized data when parsing long format tag length.
+
+2011-10-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/import.c: Move low-level pixel import functions from
+ constitute.c to new file import.c.
+
+ - magick/export.c: Move low-level pixel export functions from
+ constitute.c to new file export.c.
+
+ - magick/floats.c: Move Richard Nolde's floating point conversion
+ functions from constitute.c to new file floats.c.
+
+2011-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libtool: Updated to libtool 2.4.2.
+
+ - configure.ac: Automake conditional for HasPNG can not itself be
+ conditional. Indent PNG script code appropriately.
+
+2011-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (AUTOMAKE\_OPTIONS): Distribute lzma-compressed
+ tarball in 'xz' format rather than deprecated 'lzma' format.
+
+2011-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Fix syntax error with GSCMYKDevice ('==' rather
+ than '='). Thanks to Glenn Randers-Pehrson for noticing and
+ reporting the issue.
+
+2011-10-12 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - Use a "for" loop in configure.ac to find libpngNN.
+
+2011-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/pixel\_wand.c (NewPixelWand): Invoke InitializeMagick()
+ automatically in case user forgets to do so.
+
+ - wand/drawing\_wand.c (NewDrawingWand): Invoke InitializeMagick()
+ automatically in case user forgets to do so.
+
+ - wand/magick\_wand.c (NewMagickWand): Invoke InitializeMagick()
+ automatically in case user forgets to do so.
+
+ - png: libpng sources were updated to release 1.5.4.
+
+2011-10-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): TIFFGetField() on
+ TIFFTAG\_OPIIMAGEID was causing a crash due to an argument
+ mis-match between GraphicsMagick and libtiff. Also fixed a few
+ GCC 4.6 warnings. Problem was reported by Dylan Millikin.
+
+2011-10-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickSetDepth): New function to set the
+ depth used when reading from an image format which requires that
+ the depth be specified in advance.
+ (MagickReadImageBlob): Use BlobToImage() to read the blob.
+
+ - magick/effect.c (AdaptiveThresholdImage): Reduce or eliminate
+ expensive floating point calculations when possible.
+
+ - wand/magick\_wand.c (MagickSetFormat): New Wand function to allow
+ setting the file or blob format before it has been read.
+
+2011-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/inc/tasks-install-perlmagick.isx: Windows
+ setup installer now installs PerlMagick built against ActiveState
+ Perl v5.12.4 build 1205.
+
+ - magick/annotate.c (RenderFreetype): Eliminate spurious "out of
+ memory" exceptions due to empty text string.
+
+2011-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/module.c (ModuleAliases): PAM format is handled by PNM
+ coder.
+
+ - jpeg: Record that jpeg sources were updated to release v8c.
+
+ - lcms: Record that lcms sources were updated to release 2.2.
+
+ - png: Record that png sources were updated to release 1.5.4.
+
+ - tiff: Record that tiff sources were updated to release 4.0.0beta7.
+
+ - xml: Record that libxml2 sources were updated to release 2.7.8.
+
+ - zlib: Record that zlib sources were updated to release 1.2.5.
+
+ - VisualMagick/installer/inc/body.isx: Set MagickConfigDirectory
+ for DLL build so that .mgk files are put in application top
+ directory. This makes installation layout between static and DLL
+ builds more similar.
+
+2011-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/list.c (AppendImageToList): Documentation for
+ AppendImageToList() was wrong. Problem was reported by Brad
+ Harder.
+
+2011-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/display.c (MagickXMagickCommand): Display 'save' and
+ 'print' should display useful error details. Problem was reported
+ by Brad Harder.
+
+2011-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/semaphore.c (AllocateSemaphoreInfo): Enable pthread mutex
+ error checking if MAGICK\_DEBUG is defined when the code is
+ compiled. This mode helps validate that mutexes are used
+ correctly. No longer enable recursive mutexes since the
+ GraphicsMagick logic should be able to operate without this
+ assistance.
+
+2011-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcm.c (DCM\_ReadOffsetTable): Fix wrong cast noticed when
+ compiling with LLVM.
+
+2011-08-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/enhance.c (LevelImageChannel): Fix documented prototype.
+ Problem was reported by Brad Harder.
+
+2011-07-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (AcquireOneCacheViewPixelInlined): Only use
+ image colormap if the image storage class is PseudoClass.
+ Eliminates a core dump when the image is in CMYK space.
+
+2011-07-20 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/png.c: account for changed typecast of png\_get\_iCCP
+ argument in libpng15
+
+2011-07-20 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - configure.ac: look for libpng15, libpng14, libpng12, and libpng
+ in that order.
+
+2011-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Update to libpng 1.5.4.
+
+2011-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/docutils-articles.css: Style sheet syntax fixes. Patch by
+ Mark Mitchell.
+
+ - scripts/html\_fragments.py: Use proper quoting in banner search
+ HTML. Patch by Mark Mitchell.
+
+2011-06-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageType): Fix documentation for enumeration
+ names. The types need "Type" as part of the name. Problem was
+ reported by Brad Harder.
+
+2011-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - scripts/html\_fragments.py (banner\_template): HTML banner
+ improvements to go along with style-sheet changes.
+
+ - www/docutils-articles.css: Style-sheet improvements by Mark
+ Mitchell to work better on small screens.
+
+2011-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/project.rst: Add a page for links to pages about the
+ project. The intention is to use this page to reduce the clutter
+ in the banner.
+
+2011-05-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Document tiff:group-three-options define.
+ - coders/tiff.c (WriteTIFFImage): Add support for a
+ tiff:group-three-options define to allow power-users to set the
+ value of the GROUP3OPTIONS tag.
+
+2011-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Makefile.am: Include Hg.\*, remove CVS.\*.
+
+ - scripts/html\_fragments.py (nav\_template): CVS tab changed to
+ Source, which links to Hg.html.
+
+ - www/Hg.rst: Document Hg repository access.
+
+2011-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - scripts/rst2htmldeco.py (docutils\_opts): Do not include a
+ datestamp of any kind since it unnecessarily churns the
+ repository, particularly if the output file did not otherwise
+ change.
+
+ - INSTALL-unix.txt: Fix typo in description of --without-lzma.
+
+2011-05-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (ReadJPEGImage): Treat exceptions thrown by
+ jpeg\_finish\_decompress() as warnings rather than errors.
+ (JPEGErrorHandler): Handle JPEG errors directly rather than
+ passing them to a message formatting routine for handling. Also
+ added useful logging.
+ (JPEGMessageHandler): Only handle JPEG traces and warnings. Also
+ added useful logging.
+
+2011-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (EmitMessage): Treat an unhandled EXP marker as a
+ warning rather than a hard error. Resolves SourceForge issue
+ 3297995 "Unsupported marker type 0xdf".
+
+2011-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (AppendImages): If the input list only contains
+ one image, then return a new handle to the one image in the list
+ rather than reporting an exception. Problem was reported by Ravil
+ Rakhimgulov ("Hunter1972").
+
+2011-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageColorRegion): New function to set the
+ constant pixel color for a specified region of the image.
+ (AppendImages): Only color background pixels when needed.
+
+2011-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Added TIFF writer support for
+ JBIG1 compression. Not proven to work yet.
+
+ - magick/image.h (CompressionType): Added Group3Compression as an
+ alias for already existing FaxCompression. Added
+ JPEG2000Compression, JBIG1Compression, and JBIG2Compression for
+ future use.
+
+2011-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: For MinGW32 use 64-bit value formatting
+ conventions which will work with any version of the WIN32 CRT.
+
+2011-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (WriteJPEGImage): Properly handle errors reported
+ by the JPEG library when writing. Up to now, JPEG library simply
+ invoked exit(), which crashed or hung if driven by Magick++ API.
+ Fixes SourceForge bug 3106947 "Assertion failure when saving an
+ "invalid" image as JPEG".
+
+ - magick/module.c (ModuleAliases): Delete "XTRNBSTR"-entry. Fix by
+ Stefan Graff.
+
+ - contrib/win32/ATL7/ImageMagickObject/ImageMagickObject.cpp
+ (Perform): Member "Perform" - out-commented SafeArrayAccessData
+ and following SafeArrayUnaccessData. Fix by Stefan Graff.
+
+ - contrib/win32/ATL/ImageMagickObject/MagickImage.cpp: Delete
+ "XTRNSTREAM"-branch because "XTRNSTREAM" doesn't exist
+ anymore. Fix by Stefan Graff.
+
+ - coders/xtrn.c: In function "WriteXTRNImage" there is no branch
+ for XTRNARRAY. Fix by Stefan Graff.
+
+ - PerlMagick/Magick.xs: AdaptiveThreshold offset argument was
+ being parsed into an 'unsigned long' rather than 'double' as it
+ should have been. This resulted in inability to handle negative
+ offsets. Fixes SourceForge bug 3288735 "PerlMagick issue with
+ AdaptiveThreshold".
+
+ - coders/jpeg.c (ReadIPTCProfile): JPEG may deliver IPTC profile
+ in chunks but code was only allowing one chunk, even though it was
+ otherwise prepared to concatenate chunks. Fixes SourceForge bug
+ 2978422 "Clipping paths in JPG images are truncated".
+
+ - magick/utility.c (GetToken): Fix case where parser may run off
+ end of string. Also add asserts to check for passing null
+ pointer.
+
+2011-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/channel.c (ChannelImage): Report an error if the
+ requested channel is not compatible with the image colorspace.
+ Only deals with CMYK/RGB conflicts. Resolves SourceForge issue
+ 3283046 "Bug in CMYK".
+
+2011-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/txt.c (ReadTXTImage): Throw error if attempt to read
+ empty file.
+
+ - coders/{fits.c,mac.c,miff.c,pcd.c,pict.c,ps3.c,rla.c,txt.c}:
+ Format requires seekable stream.
+
+ - coders/pnm.c (WritePNMImage): Implement writer for PAM format.
+
+ - coders/ept.c (WriteEPTImage): Fix error handling for case when
+ TIFF writer fails.
+
+ - magick/constitute.c (ReadImage): Use of GetBlobStatus() to
+ evaluate image reader success is bogus.
+ (MagickGetQuantumSamplesPerPixel): New private method to return
+ the number of samples returned per pixel for a given quantum type.
+
+2011-03-14 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/png.c (WriteOnePNGImage(): Fixed a rounding error in
+ writing the pHYs chunk (it was truncating instead of rounding).
+
+2011-02-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (MagickPanicSignalHandler,MagickSignalHandler):
+ Don't invoke DestroyMagick() since there may be OpenMP worker
+ threads still running which are using data which would be
+ deallocated. Instead we invoke PurgeTemporaryFiles() to remove
+ any existing temporary files. Valgrind will report leaks if the
+ program is terminated by a signal but this causes no actual harm.
+ Resolves SourceForge issue 3165456 "^C causes semaphore failure in
+ MacOSX".
+ (MagickPanicSignalHandler): Invoke abort() in panic signal handler
+ so that we will reliably get a core dump.
+
+ - magick/tempfile.c (PurgeTemporaryFiles): New private function to
+ remove any existing temporary files but without destroying
+ temporary file semaphore.
+
+2011-02-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (ReadPNMImage): Fix mis-placed break in PAM header
+ parser.
+
+ - wand/magick\_wand.c (MagickWriteImageBlob): Improve the
+ documentation to mention the related use of MagickSetImageFormat()
+ and MagickResetIterator().
+
+2011-02-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/xwindow.c (MagickXBestFont): Check for a few more common
+ font names, and ensure to always check for "fixed" as a final
+ fallback.
+
+2011-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - config/delegates.mgk.in: Added gs-cmyk entry. Used if '-type
+ ColorSeparation' is specified on the command-line prior to the PDF
+ or Postscript file name. This entry specifies use of the
+ Ghostscript PAM driver which is capable of supporting CMYK output.
+ This may be useful if it is desired to apply CMYK color profiles
+ to the image returned from the PDF. As fair warning, it seems
+ that Ghostscript 8.62 outputs CMYK even if the PDF was in RGB
+ space if the PAM driver is used.
+
+ - coders/pnm.c (ReadPNMImage): Add support for reading netpbm's
+ PAM format.
+
+2011-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwblob.c, tests/rwfile.c: Fixes to help tests work when
+ testing with multiple frames.
+
+ - coders/sgi.c: SGI format is not documented to support multiple
+ frames. Remove the half-baked extension for it.
+
+2011-02-01 Glenn Randers-Pehrson <glennrp@simple...>
+
+ - coders/bmp.c (ReadBMPImage): Changed file\_size greater than
+ expected from a corrupt-image error to a debug log entry.
+ File\_size too small is still an error, and made that so also for
+ BI\_RGB images which were previously exempted from the test.
+
+2011-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwblob.c, tests/rwfile.c: Validate the data in each image
+ frame, validate that each read returns the same number of frames,
+ and validate that the correct number of frames was ultimately
+ returned.
+
+ - magick/blob.c (SyncBlob): Disable bogus code which attempted to
+ replicate the blob I/O object across all images in the list when
+ the blob is synced. Leave a less bogus bit of code in place (but
+ commented out) in case such functionality is deemed to actually be
+ needed in the future. The previous code was copying structs on
+ top of each other, including a pointer member to a semaphore.
+
+2011-01-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Changes.rst: Add a new Changes page to wrap up the yearly
+ change logs to lessen download size.
+
+ - scripts/changelog2rst.sh: Simple utility to format ChangeLog
+ format into something resembling reStructuredText.
+
+ - www/Makefile.am: Use reStructuredText to format the ChangeLog
+ files to HTML so that we can inherit the improved formatting and
+ page style.
+
+ - coders/pnm.c (ReadPNMImage): Support for multi-frame PNM was
+ botched due to on-going edits to support PAM format.
+
+2011-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickDescribeImage): Was sending
+ descriptive output to stdout rather than returning it in an
+ allocated string as intended.
+
+2011-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/draw.c, wand/drawing\_wand.c (MvgPrintf): Update to handle
+ C99 vsnprintf() return values.
+
+ - magick/draw.c, wand/drawing\_wand.c (DrawAnnotation): Linux
+ glibc does not pass extended text characters if "%.1024s"
+ formatting convention is used. Apparently it assumes that such
+ characters may be UTF8 and returns -1 rather than outputting the
+ string, even if it is assured to fit.
+
diff --git a/www/ChangeLog-2012.html b/www/ChangeLog-2012.html
new file mode 100644
index 0000000..5f8d74f
--- /dev/null
+++ b/www/ChangeLog-2012.html
@@ -0,0 +1,1058 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2012-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Added -auto-orient to 'convert' and 'mogrify'
+to automatically rotate the image upright for viewing based on its
+current orientation setting.
+Added -orient to support setting the image orientation.</li>
+<li>magick/shear.c (AutoOrientImage): New function to automatically
+orient the image so that it is upright for normal viewing.</li>
+</ul>
+</blockquote>
+<p>2012-12-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>scripts/tap-functions.shi: Tidy TAP tests so that they may be
+run alone, or via Perl's 'prove'.</li>
+</ul>
+</blockquote>
+<p>2012-12-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwfile.c (main): Test file name generation was not
+correct.</li>
+</ul>
+</blockquote>
+<p>2012-12-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwfile.tap: Added -stdio tests for most file formats.
+This tests I/O using an already-opened file handle passed via the
+ImageInfo file member. Formats using the Ghostscript delegate are
+not working right yet.</li>
+</ul>
+</blockquote>
+<p>2012-12-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwfile.c (main): Added a '-stdio' option to test
+reading/writing files using file handles opened by the API user.</li>
+<li>magick/blob.c (CloseBlob): It should be possible to invoke
+CloseBlob() multiple times, including blobs set to &quot;exempt&quot;.
+There were some issues when passing in file descriptors.</li>
+</ul>
+</blockquote>
+<p>2012-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/api/api.rst: Add another example Core C API example program.</li>
+<li>magick/blob.c (OpenBlob): Restore file position, rather than
+rewind, after reading header bytes.</li>
+<li>magick/image.c (SetImageInfo): Restore file position after
+reading header bytes. Resolves SourceForge issue 3597486
+&quot;ReadImage not working with file descriptors&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-12-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick: WIN64 (64-bit Windows) installer improvements to
+bring up to par with 32-bit installer.</li>
+</ul>
+</blockquote>
+<p>2012-12-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick: WIN64 (64-bit Windows) is supported now.</li>
+</ul>
+</blockquote>
+<p>2012-12-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c: Eliminate support for experimental
+MAGICK_MMAP_WRITE, which never quite worked correctly and did not
+provide performance benefits.</li>
+</ul>
+</blockquote>
+<p>2012-12-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (FileToBlob): Rewrite to be based on stdio.</li>
+</ul>
+</blockquote>
+<p>2012-12-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick_types.h.in: Changes to try to work better with the
+Windows WIN64 API.</li>
+</ul>
+</blockquote>
+<p>2012-12-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageColorRegion): The provided color should
+be in the same colorspace as the image. The image is no longer
+converted to RGB with the expectation that the provided color is
+always some particular RGB.
+(AppendImages): No longer transform the canvas image to RGB. Now
+append uses the first listed image to determine the colorspace
+which should be used when appending the additional images and of
+the output image. The additional images are converted to the
+canvas image colorspace. Likewise, the background color is
+assumed to be in the same colorspace as the first listed image so
+that it is compatible and can be used to fill the background color
+without translation.</li>
+</ul>
+</blockquote>
+<p>2012-11-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>rungm.sh.in: Remove extraneous space in first line which
+prevents execution with T-shell (tsch). Reported by William
+Langdon.</li>
+</ul>
+</blockquote>
+<p>2012-11-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/wand/wand.rst: Add a simple example of using the Wand API.</li>
+</ul>
+</blockquote>
+<p>2012-11-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (ReadBMPImage): Fixed an old bug with decoding
+chromaticity primaries.</li>
+</ul>
+</blockquote>
+<p>2012-11-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.h (&quot;C&quot;): Need to include wand/wand_symbols.h
+after magick/api.h in order for options from magick_config.h to
+take effect.</li>
+<li>magick/symbols.h (PSPageGeometry): Fix typo. Should map to
+GmPSPageGeometry.</li>
+</ul>
+</blockquote>
+<p>2012-11-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/wand_symbols.h, magick/symbol.h: MagickWand API is now
+prefixed with 'Gm' when the --enable-symbol-prefix configure
+option is supplied. These changes are contributed by Ben Wu.
+Details of changes are as follows:<ol class="arabic">
+<li>A new header file wand/wand_symbols.h which prefixes all
+MagickWand API symbols with Gm.</li>
+<li>Modification to all the header files in wand/ to include
+wand_symbols.h.</li>
+<li>Modification to magick/symbols.h to include additional
+symbols which were colliding with names in ImageMagick.</li>
+<li>Modification to magick/error.c to exclude function
+definitions for MagickError, MagickFatalError,
+MagickWarning, and ThrowException when building with
+--enable-symbol-prefix option. There four names were also
+defined as macros so it appears that putting them in a
+symbol-remapping file wont work.</li>
+</ol>
+</li>
+<li>Makefile.am: Update Automake to 1.12.5.</li>
+</ul>
+</blockquote>
+<p>2012-11-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/COPYING: Change Magick++ usage license to be exactly
+the MIT license without the additional sentence about retention of
+copyright (which was already legally implicit).</li>
+</ul>
+</blockquote>
+<p>2012-11-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/symbols.h: Re-generate list of symbols to prefix.</li>
+<li>magick/utility.c (IsGlob): IsGlob can be more efficient.</li>
+<li>magick/floats.c: Use compile-time selection of endian-specific
+code rather than run-time. Fix cast warning with 64-bit builds.</li>
+</ul>
+</blockquote>
+<p>2012-11-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): The wrong QuantumType was
+sometimes passed to ExportImagePixelArea() by the PNG encoder.</li>
+<li>coders/png.c (ReadOnePNGImage): Let libpng unpack all sub-8-bit
+pixels (see change of 2012-08-31 which lets libpng unpack sub-8-bit
+palette images; this also lets libpng unpack the grayscale images).</li>
+<li>coders/png.c (ReadOnePNGImage): Corrected the reading of interlaced
+images (see SourceForge bug 3420695, in which all passes are
+displayed in a garbled manner instead of only the completed image).</li>
+</ul>
+</blockquote>
+<p>2012-10-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickGetImagePage): Need to use 'image'
+rather than 'images' in order to work with iterator.
+(MagickSetImagePage): Need to use 'image'
+rather than 'images' in order to work with iterator.</li>
+</ul>
+</blockquote>
+<p>2012-10-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (TranslateTextEx): Fix bug with input string
+read overrun if the input string ends with a single '%'. This
+sometimes caused random heap data to be added to the output string
+until another null character is reached. A simple work-around
+without this fix is to use &quot;%%&quot; rather than &quot;%&quot;. Fixes
+SourceForge bug 3580219 &quot;strange results with '%' in Annotate()&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-10-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickSetImagePage): New method to support
+setting the image page size and offsets.
+(MagickGetImagePage): New method to support getting image page
+size and offsets.</li>
+</ul>
+</blockquote>
+<p>2012-10-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Report fatal error if doing modules build and
+libltdl is not found.</li>
+</ul>
+</blockquote>
+<p>2012-10-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ltdl: Libltdl is no longer bundled. Libltdl must be previously
+installed on the system in order to build the modules
+configuration.</li>
+</ul>
+</blockquote>
+<p>2012-10-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/index.rst: Update top index page for 1.3.17 release.</li>
+<li>NEWS.txt: Update NEWS for 1.3.17 release.</li>
+<li>version.sh: Update shared library versioning for 1.3.17 release.</li>
+<li>coders/jnx.c: Fix format string compilation warnings. Remove
+MS-DOS line terminations.</li>
+<li>configure.ac: Module loading is now only supported by the
+modules build and not just because shared libraries are enabled.
+This means that libltdl is only depended upon by the modules
+build. Sometime in the future, libltdl will no longer be bundled
+in the GraphicsMagick source tree.</li>
+</ul>
+</blockquote>
+<p>2012-10-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac (LTDL_INIT): Request installable libltdl rather
+than convenience.</li>
+</ul>
+</blockquote>
+<p>2012-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c: Support alpha channel in uncompressed 32-bit BMP.
+Resolves SourceForge issue 3566239 &quot;Can't open BMP with alpha
+created by photoshop&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-10-07 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>dcraw/dcraw.c: Fixed situation when M_PI is not defined.</li>
+</ul>
+</blockquote>
+<p>2012-10-07 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c: Add image attribute with geolocation.</li>
+</ul>
+</blockquote>
+<p>2012-10-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>dcraw: VisualMagick configure fixes to support linking with JPEG
+and JPEG2000.</li>
+</ul>
+</blockquote>
+<p>2012-09-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>dcraw: Add dcraw to VisualMagick build.</li>
+<li>libxml: Update libxml2 to 2.9.0 release.</li>
+</ul>
+</blockquote>
+<p>2012-09-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff: Update libtiff to 4.0.3 release.</li>
+<li>lcms: Update liblcms2 to 2.4 release.</li>
+<li>png: Update libpng to 1.5.13 release.</li>
+</ul>
+</blockquote>
+<p>2012-09-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am: Update to Automake 1.12.4.</li>
+</ul>
+</blockquote>
+<p>2012-09-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Fix Debian bug 687738 &quot;graphicsmagick:
+repeated words suitable for suitable for in gm manpage&quot; reported
+by Jonas Smedegaard.</li>
+</ul>
+</blockquote>
+<p>2012-09-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Update with news since last release.</li>
+<li>configure.ac: Added the configure option
+--enable-quantum-library-names to enable that shared library name
+includes quantum depth to allow shared libraries with different
+quantum depths to co-exist in same directory (only one can be used
+for development).</li>
+</ul>
+</blockquote>
+<p>2012-09-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (AdaptiveThresholdImage): New implementation
+contributed by Roberto de Deus Barbosa Murta. Executes in linear
+time as threhold area is increased rather than being quadratic.</li>
+</ul>
+</blockquote>
+<p>2012-09-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/svg.c: Fix improper injection of XML headers as rendered
+text.</li>
+<li>magick/render.c (DrawImage): Fix SourceForge issue 3499164
+&quot;Drawing of text fails if text starts with &quot;,&quot; character&quot;. Fix
+SourceForge issue 3411492 &quot;Certain SVGs hang GraphicsMagick&quot;. Fix
+SourceForge issue 1961000 &quot;Could not print ',' via convert draw
+text&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-09-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c (lite_font_stringwidth): Simply return zero.
+Returning a computed string width was causing text placement
+problems when testing with libwmf's fulltest.wmf.</li>
+</ul>
+</blockquote>
+<p>2012-08-31 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: ReadOnePNGImage: sub-8-bit palette images were
+getting unpacked twice; once by libpng via png_set_packing()
+and again by coders/png.c in a switch() statement around line 2500,
+resulting in horizontally stretched pixels.</li>
+</ul>
+</blockquote>
+<p>2012-08-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (AUTOMAKE_OPTIONS): Include lzip as a distribution
+format again.</li>
+</ul>
+</blockquote>
+<p>2012-08-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: BrowseDelegate now defaults to 'xdg-open', but if
+it is not found, then configure will search for firefox,
+google-chrome, mozilla (in that order).</li>
+</ul>
+</blockquote>
+<p>2012-08-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: For testing on MinGW, assume that Postscript is
+available since we don't have a good way to check for that.</li>
+<li>scripts/tap-functions.shi (test_count): Always execute the test
+program rather than skipping execution since we want to make sure
+the test program fails correctly as well.</li>
+<li>coders/gif.c (DecodeImage): Add a log message for attempted LZW
+string data table overflow.</li>
+</ul>
+</blockquote>
+<p>2012-08-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (ConvolveImage): Allocate normalized convolution
+kernel using cache-line aligned memory allocator.</li>
+<li>configure.ac: Remove support for legacy LZWDecodeDelegate and
+LZWEncodeDelegate since these are not used any more.</li>
+</ul>
+</blockquote>
+<p>2012-08-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>scripts/tap-functions.shi: If a test declares that it needs
+certain features, skip the test if required features are not
+available.</li>
+<li>configure.ac: Build a supported features list and save to
+common.shi script for use by test scripts.</li>
+<li>Makefile.am (LOG_COMPILER): Run Bourne-shell based TAP scripts
+with the same shell $(SHELL) that configure selected for the
+Makefile to use.</li>
+</ul>
+</blockquote>
+<p>2012-08-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (AUTOMAKE_OPTIONS): Update to Automake 1.12.3.
+Update test suite to use Automake TAP driver rather than legacy
+tests.</li>
+</ul>
+</blockquote>
+<p>2012-08-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c (ExtractTileJPG): Add a trace of tile offset and size.</li>
+</ul>
+</blockquote>
+<p>2012-08-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c (ExtractTileJPG): Use a memory buffer for the JPEG
+tile rather than a temporary file.</li>
+</ul>
+</blockquote>
+<p>2012-08-12 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+* PerlMagick/t/input_jnx.jnx: Small JNX test file.</blockquote>
+<p>2012-08-11 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c: speedup.</li>
+</ul>
+</blockquote>
+<p>2012-08-10 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c: changed malloc/free to MagickMalloc/MagickFree.</li>
+</ul>
+</blockquote>
+<p>2012-08-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c (ReadJNXImage): Add progress monitor support for
+JNX.</li>
+</ul>
+</blockquote>
+<p>2012-08-06 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c: Image cache is turned off to work-around memory
+overflow.</li>
+</ul>
+</blockquote>
+<p>2012-08-05 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c: Fixed.</li>
+</ul>
+</blockquote>
+<p>2012-08-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jnx.c: Add JNX coder for &quot;Garmin proprietary Image
+Format&quot; (implementation by Jaroslav Fojtik) to the build. Code is
+not yet working properly at this time.</li>
+</ul>
+</blockquote>
+<p>2012-08-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Remove use of -Wl,-zlazyload under Solaris since
+it seems to decrease the stability of C++ exceptions in x86-64
+build and does not measurably improve runtimes. Don't force use
+of liblzma because libtiff is used. User should always have
+control.</li>
+</ul>
+</blockquote>
+<p>2012-07-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/memory.c (MagickMallocAligned): Use RoundUpToAlignment()
+macro to compute aligned pointer.</li>
+<li>magick/effect.c (EnhanceImage): Eliminate use of ugly Enhance
+macro. Only filter based on color channels (ignore opacity).</li>
+</ul>
+</blockquote>
+<p>2012-07-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h (MAGICK_CACHE_LINE_SIZE): Assume a cache line
+size of 64 bytes except for on PowerPC which uses 128.</li>
+<li>magick/pixel_cache.c: Use aligned memory allocator to allocate
+structures and buffers which might suffer from false cache line
+sharing</li>
+<li>magick/memory.c (MagickMallocAligned): Also round up allocation
+size to alignment.</li>
+</ul>
+</blockquote>
+<p>2012-07-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c, magick/random.c, magick/semaphore.c: Use
+aligned memory allocator to align allocations which should be
+aligned to cache line boundary.</li>
+</ul>
+</blockquote>
+<p>2012-07-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/memory.h (MagickAllocateAlignedMemory): New macro to
+allocate aligned memory.
+(MagickFreeAlignedMemory): New macro to free aligned memory.</li>
+<li>magick/memory.c (MagickMallocAligned): New internal function to
+allocate aligned memory.
+(MagickFreeAligned): New internal function to free aligned memory.</li>
+</ul>
+</blockquote>
+<p>2012-07-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/common.h (MAGICK_ASSUME_ALIGNED): Add some GCC attribute
+wrappers for useful features added by GCC 4.7.</li>
+</ul>
+</blockquote>
+<p>2012-07-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gif.c (ReadGIFImage): Try to be better about reporting
+failure when ReadBlob() fails to return the requested number of
+bytes.</li>
+</ul>
+</blockquote>
+<p>2012-06-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/benchmarks.rst: Strip the outdated benchmark results from
+the benchmarks page.</li>
+<li>magick/command.c (ImportImageCommand): Status returned from the
+command was inverted.</li>
+</ul>
+</blockquote>
+<p>2012-06-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Release GraphicsMagick 1.3.16</li>
+</ul>
+</blockquote>
+<p>2012-06-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): -units was adjusting existing
+resolution the wrong way around.</li>
+</ul>
+</blockquote>
+<p>2012-06-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>jpeg: Updated to IJG 8d release.</li>
+<li>libxml: Updated libxml to 2.8.0 release.</li>
+<li>zlib: Updated zlib to 1.2.7 release.</li>
+<li>magick/blob.c (MagickFileHandle): Refer to stdio, bzip2, and
+gzip file handles using their own type. Eliminates warnings
+observed when compiling with zlib 1.2.7.</li>
+<li>tiff: Updated libtiff to 4.0.2 release.</li>
+<li>png: Updated libpng to 1.5.11 release.</li>
+</ul>
+</blockquote>
+<p>2012-06-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Fix typo which caused the --without-lzma option to
+be handled incorrectly. Resolves SourceForge issue 3535309
+&quot;graphicsmagick from 1.3.13 to 1.3.15 has broken lzma support&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-06-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwfile.c (main): Verify that we can 'ping' the file using
+PingImage(). Tests for some formats may take longer to complete.</li>
+<li>tests/rwblob.c (main): Verify that we can 'ping' the blob using
+PingBlob(). Tests for some formats may take longer to complete.</li>
+<li>coders/xbm.c (ReadXBMImage): Fix memory leak of temporary X
+bitmap image allocation encountered when reading in 'ping' mode.</li>
+<li>magick/blob.c (PingBlob): Re-write to be based on BlobToImage()
+so that it works reliably.
+(BlobToImage): Restore original input file name to image if
+temporary file was used so that image 'filename' and
+'magick_filename' do not contain unexpected content due to using a
+temporary file.</li>
+</ul>
+</blockquote>
+<p>2012-06-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Disable new libpng-1.5.10 test for invalid palette
+index when reading a PNG or MNG (for speed), or when writing a MNG
+(because a zero-length PLTE is valid in a MNG).</li>
+</ul>
+</blockquote>
+<p>2012-06-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (SetImageAttribute): Don't translate
+'comment' and 'label' attributes if the request is made while a
+file is being read. This is a temporary workaround until there is
+opportunity to modify the architecture so that there is a clear
+split between user-provided settings and values obtained from the
+input image.</li>
+<li>magick/blob.c (GetBlobIsOpen): New function to return if blob is
+currently open.</li>
+</ul>
+</blockquote>
+<p>2012-06-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/typemap: Add typemap file needed by Perl 5.16.
+Resolves SourceForge issue 3531512 &quot;PerlMagick does not build with
+perl 5.16&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-05-29 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Ignore APNG chunks even if we are using a libpng
+that was built with the &quot;APNG patch&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ConvertImageCommand): +repage does not require
+an argument. Resolves SourceForge issue 3529158 &quot;+repage option
+not respected with convert command&quot;.</li>
+<li>configure: Update to Autoconf 2.69.</li>
+<li>magick/effect.c (MotionBlurImage): Motion blur does scale so
+remove DisableSlowOpenMP for it.</li>
+<li>magick/command.c (BenchmarkImageCommand): Remove parenthesis
+from output, and change &quot;iter/sec cpu&quot; to &quot;iter/cpu&quot; to ease
+parsing.</li>
+<li>magick/pixel_cache.c (GetPixelCacheInCore): Consider read-only
+memory-mapped cache as being &quot;in-core&quot;. Otherwise MPC input files
+are penalized.</li>
+</ul>
+</blockquote>
+<p>2012-05-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/api.h: Include &lt;sys/types.h&gt; on POSIX systems in order to
+help assure that 'size_t' and 'ssize_t' are declared.</li>
+</ul>
+</blockquote>
+<p>2012-05-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick_config_api.h.in: Need to provide definitions for
+'size_t' and 'ssize_t' in case the system headers lack these types
+because the definition of MagickExtentImage() requires them. This
+should resolve PHP bug #62034 &quot;gmagick does not compile&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-05-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_iterator.c (GetRegionThreads): Don't thread region
+if it is not memory-based.</li>
+</ul>
+</blockquote>
+<p>2012-05-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): make transparent_color elements
+unsigned long instead of unsigned short, so 65537 is actually out of
+range as expected, and won't match any pixel if no tRNS chunk is
+present.</li>
+</ul>
+</blockquote>
+<p>2012-05-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sfw.c (ReadSFWImage): Reader needs to be more robust
+against corrupt or maligned headers. Resolves SourceForge issue
+&quot;sfw file crash&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-05-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdf.c (WritePDFImage): Add file basename as the PDF
+document title. Resolves SourceForge bug ID 2835140
+&quot;GraphicsMagick fails to add title attribute to PDF output&quot;.</li>
+<li>coders/sfw.c (ReadSFWImage): Restore original filename and
+format.</li>
+<li>PerlMagick/t/jpeg/read.t: Add a test for reading Seattle
+FilmWorks format based on the sample image from
+<a class="reference external" href="http://www.algonet.se/~cyren/sfw/">http://www.algonet.se/~cyren/sfw/</a>. Image was approved for
+distribution in GraphicsMagick by Bengt Cyrén.</li>
+<li>magick/analyze.c (GetImageBoundingBox): Only apply opacity-based
+bounding box detection if all three test points are non-opaque and
+the same value. Resolves SourceForge bug ID 3522804 &quot;convert
+-trim fails on 8-bit PNG that ImageMagick can trim&quot;.</li>
+<li>coders/sfw.c (ReadSFWImage): Fix variety of bugs related to
+closing Image and blob at wrong points. SFW reader is working
+again. Resolves SourceForge bug ID 523430 &quot;sfw file open failed&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-05-01 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Animated movies inside 4D matrices are loaded now.</li>
+</ul>
+</blockquote>
+<p>2012-04-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_iterator.c: Limit the number of threads to use in
+the loop rather than the total number of threads available.</li>
+</ul>
+</blockquote>
+<p>2012-04-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Release GraphicsMagick 1.3.15</li>
+</ul>
+</blockquote>
+<p>2012-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Remove automatic adjoin mode
+support logic.
+(AddDefinition): Fix use of uninitialized variable.</li>
+</ul>
+</blockquote>
+<p>2012-04-23 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/*.imdoc: some example commandlines in the documentation
+were missing the leading &quot;gm &quot;.</li>
+</ul>
+</blockquote>
+<p>2012-04-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (FormMultiPartFilename): No longer add a
+printf-style scene formatting specification to filenames which do
+not have one and no longer automatically operate in 'adjoin' mode
+in such cases. This is a BIG CHANGE for users who may have become
+used to this automatic functionality. The simple solution to
+update existing scripts depending on this behavior is to change
+any bare filenames to include a format specification similar to
+&quot;image-%d.jpg&quot; and add +adjoin to the command line. The reason
+why this change is made is that the output files produced by any
+given operation were unpredictable, and it was causing temporary
+files to be leaked due to the renaming.</li>
+</ul>
+</blockquote>
+<p>2012-04-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (WriteBMPImage): Enforce that image width and
+height do not exceed BMP dimensions. BMP dimensions are
+represented by a signed type. BMPv2 supports maximum dimensions
+of 32k by 32k.</li>
+</ul>
+</blockquote>
+<p>2012-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/info.c (WriteINFOImage): When driven by the 'convert'
+utility, -format produces user-controlled formatted output similar
+to -format in 'identify'. This is accomplished via a
+'<a class="reference external" href="info:format=value">info:format=value</a>' define.</li>
+<li>magick/image.c (AddDefinition): New function for adding just one
+define to definitions list.</li>
+</ul>
+</blockquote>
+<p>2012-04-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (ReadPNMImage): Completely disable OpenMP in reader
+because there is too much contention.</li>
+<li>magick/pixel_iterator.c: Dereference image to be modified in
+non-threaded context in order to lessen contention.</li>
+<li>magick/semaphore.c (AllocateSemaphoreInfo): Make sure that
+SemaphoreInfo does not share cache lines with another semaphore.</li>
+</ul>
+</blockquote>
+<p>2012-04-11 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: fixed problem with bit depth when the encoder
+decides to write RGBA instead of indexed PNG, by delaying the
+call to png_set_tRNS() until after calling png_set_IHDR().</li>
+</ul>
+</blockquote>
+<p>2012-03-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Update bundled libpng to 1.5.10 release. Provides security
+fix for CVE-2011-3048.</li>
+<li>wand/magick_compat.c (ParseGeometry): Use strlcpy() rather than
+strncpy().
+(CopyMagickString): Depend on strlcpy() because we provide it if
+it is missing.
+(ConcatenateMagickString): Depend on strlcat().</li>
+<li>coders/xcf.c (ReadXCFImage): Now respects image subimage and
+subrange members so that returned image layers may be selected.
+Based on patch from SourceForge issue 3513025 &quot;XCF reads all
+layers all the time&quot;.</li>
+<li>magick/resize.c (ThumbnailImage): Thumbnail default filter is
+intended to be the box filter, but allow the user to override the
+filter used. Resolves SourceForge issue 3513239 &quot;-filter command
+line argument ignored&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+Added support for '+noise random' and '-operator noise-random' to
+'convert' and 'mogrify'.</li>
+<li>magick/effect.c (AddNoiseImage): Added support for RandomNoise.
+(AddNoiseImageChannel): Added support for RandomNoise.</li>
+<li>magick/enum_strings.c (StringToNoiseType): New function to
+convert a string to a NoiseType enumeration value.
+(NoiseTypeToString): New function to convert a NoiseType
+enumeration value into a string.</li>
+<li>PerlMagick/Magick.xs: Added support for RandomNoise.</li>
+<li>magick/operator.c (QuantumOperatorRegionImage): Added support for
+RandomNoise.</li>
+<li>magick/effect.c (AddNoiseImageChannel): Added support for
+RandomNoise.</li>
+<li>magick/gem.c (GenerateDifferentialNoise): Added support for
+RandomNoise.</li>
+<li>magick/random.h (MagickRandomRealInlined): The span of
+MagickRandomRealInlined() is now slightly more accurate.</li>
+<li>magick/image.h (enum NoiseType): New enumeration value RandomNoise.</li>
+</ul>
+</blockquote>
+<p>2012-03-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): Add support for -repage option
+to composite, convert, mogrify, and montage subcommands. Resets
+or adjusts the current image page offsets based on a provided
+geometry specification.</li>
+<li>magick/image.c (ResetImagePage): Add a function to adjust the
+current image page canvas and position based on a relative page
+specification.</li>
+</ul>
+</blockquote>
+<p>2012-03-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImage): Add support for -strip option
+to composite, convert, mogrify, and montage subcommands. Removes
+all profiles and text attributes from the image.</li>
+<li>magick/image.c (StripImage): New function to remove all profiles
+and text attributes from the image.</li>
+</ul>
+</blockquote>
+<p>2012-02-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Release GraphicsMagick 1.3.14.</li>
+<li>NEWS.txt: Updated to describe updates since last release.</li>
+</ul>
+</blockquote>
+<p>2012-02-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Downgrade to Automake 1.11.2 so that test suite can run on
+systems with limited command line length. This means that lzip
+support is temporarily removed.</li>
+<li>magick/resize.c (ResizeImage): Resize filter argument was being
+ignored. Filter from image 'filter' member was used instead.
+Problem was reported by Steven Bakhtiari.</li>
+</ul>
+</blockquote>
+<p>2012-02-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff: Update bundled libtiff to 4.0.1 release.</li>
+<li>png: Update bundled libpng to 1.5.9 release.</li>
+<li>magick/memory.h: Decorate memory allocation functions with GCC
+attribute 'alloc_size'.</li>
+<li>magick/common.h: Add support for GCC 4.3+ attributes
+'alloc_size', 'hot', 'cold'.</li>
+<li>magick/{log.h,monitor.h,utility.h}: Use double-underscore syntax
+in GCC format attribute specifications to defend against
+accidental macro expansion.</li>
+</ul>
+</blockquote>
+<p>2012-02-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xcf.c (ReadXCFImage): Fix reading XCF which is comprised
+of different sized layers.</li>
+</ul>
+</blockquote>
+<p>2012-02-08 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simplesystems&#46;org">glennrp<span>&#64;</span>simplesystems<span>&#46;</span>org</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/txt.c: Added &quot;-define txt:with-im-header&quot; option.</li>
+</ul>
+</blockquote>
+<p>2012-02-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Updated to libpng 1.5.8 release</li>
+<li>zlib: Updated to zlib 1.2.6 release</li>
+</ul>
+</blockquote>
+<p>2012-02-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (AUTOMAKE_OPTIONS): Update to Automake 1.11.3. Add
+lzip compressed archive to options.</li>
+</ul>
+</blockquote>
+<p>2012-01-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcraw.c (RegisterDCRAWImage): Add support for Mamiya
+Photo RAW &quot;MEF&quot; format. Resolves SourceForge issue #3481508
+&quot;*.MEF file open incorrect&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-01-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c (WriteJPEGImage): Convert RGB-compatible
+colorspaces (e.g. CineonLog) to RGB by default since that was the
+case prior to release 1.3.13. User can still override it
+(avoiding removal of log encoding) by explicitly specifying the
+desired colorspace. Problem was reported by Gary Margiotta.</li>
+</ul>
+</blockquote>
+<p>2012-01-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): When reading, save input file
+endianness so that the endianness of the original file is
+preserved by default. The user is able to override this default
+via -endian. Problem was reported by JongAm Park.</li>
+</ul>
+</blockquote>
+<p>2012-01-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/OpenMP.rst: Updated OpenMP results based on latest OpenMP
+tunings and the Intel Xeon E5649 CPU.</li>
+</ul>
+</blockquote>
+<p>2012-01-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcraw.c (ReadDCRAWImage): Fix memory leak of ImageInfo.
+Resolves SourceForge bug #3475148 &quot;memery leaks&quot;.</li>
+<li>magick/module.c (ModuleAliases): EMF format is supported by EMF
+module and so mapping EMF to the WMF module caused EMF not to
+work. Resolves SourceForge bug #3475147 &quot;emf files can not be
+opened&quot;. Note that the EMF module only works for Microsoft
+Windows.</li>
+</ul>
+</blockquote>
+<p>2012-01-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/gem.c (Hull): Improve performance.</li>
+<li>magick/effect.c (DespeckleImage): Improve performance.</li>
+</ul>
+</blockquote>
+<p>2012-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/effect.c (DespeckleImage): Using schedule(static,4)
+blocks any opportunity for speedup. This was a performance
+regression. Oops!</li>
+</ul>
+</blockquote>
+<p>2012-01-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickExtentImage): Added
+MagickExtentImage() to Wand API. Resolves SourceForge issue
+#3471915 &quot;MagickExtentImage in the Wand C API&quot;.</li>
+</ul>
+</blockquote>
+<p>2012-01-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/export.c (ExportViewPixelArea): Break up implementation
+into subroutines to ease compilation.</li>
+</ul>
+</blockquote>
+<p>2012-01-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/import.c (ImportViewPixelArea): Break up implementation
+into subroutines to ease compilation.</li>
+</ul>
+</blockquote>
+<p>2012-01-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h: Use Magick prefixed macro names for ftruncate,
+mmap, and munmap in order to assure that introducing our macros
+does not cause trouble with system headers.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2012.rst b/www/ChangeLog-2012.rst
new file mode 100644
index 0000000..18bd955
--- /dev/null
+++ b/www/ChangeLog-2012.rst
@@ -0,0 +1,868 @@
+2012-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Added -auto-orient to 'convert' and 'mogrify'
+ to automatically rotate the image upright for viewing based on its
+ current orientation setting.
+ Added -orient to support setting the image orientation.
+
+ - magick/shear.c (AutoOrientImage): New function to automatically
+ orient the image so that it is upright for normal viewing.
+
+2012-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - scripts/tap-functions.shi: Tidy TAP tests so that they may be
+ run alone, or via Perl's 'prove'.
+
+2012-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwfile.c (main): Test file name generation was not
+ correct.
+
+2012-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwfile.tap: Added -stdio tests for most file formats.
+ This tests I/O using an already-opened file handle passed via the
+ ImageInfo file member. Formats using the Ghostscript delegate are
+ not working right yet.
+
+2012-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwfile.c (main): Added a '-stdio' option to test
+ reading/writing files using file handles opened by the API user.
+
+ - magick/blob.c (CloseBlob): It should be possible to invoke
+ CloseBlob() multiple times, including blobs set to "exempt".
+ There were some issues when passing in file descriptors.
+
+2012-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/api/api.rst: Add another example Core C API example program.
+
+ - magick/blob.c (OpenBlob): Restore file position, rather than
+ rewind, after reading header bytes.
+
+ - magick/image.c (SetImageInfo): Restore file position after
+ reading header bytes. Resolves SourceForge issue 3597486
+ "ReadImage not working with file descriptors".
+
+2012-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick: WIN64 (64-bit Windows) installer improvements to
+ bring up to par with 32-bit installer.
+
+2012-12-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick: WIN64 (64-bit Windows) is supported now.
+
+2012-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c: Eliminate support for experimental
+ MAGICK\_MMAP\_WRITE, which never quite worked correctly and did not
+ provide performance benefits.
+
+2012-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (FileToBlob): Rewrite to be based on stdio.
+
+2012-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick\_types.h.in: Changes to try to work better with the
+ Windows WIN64 API.
+
+2012-12-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageColorRegion): The provided color should
+ be in the same colorspace as the image. The image is no longer
+ converted to RGB with the expectation that the provided color is
+ always some particular RGB.
+ (AppendImages): No longer transform the canvas image to RGB. Now
+ append uses the first listed image to determine the colorspace
+ which should be used when appending the additional images and of
+ the output image. The additional images are converted to the
+ canvas image colorspace. Likewise, the background color is
+ assumed to be in the same colorspace as the first listed image so
+ that it is compatible and can be used to fill the background color
+ without translation.
+
+2012-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - rungm.sh.in: Remove extraneous space in first line which
+ prevents execution with T-shell (tsch). Reported by William
+ Langdon.
+
+2012-11-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/wand/wand.rst: Add a simple example of using the Wand API.
+
+2012-11-21 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - coders/bmp.c (ReadBMPImage): Fixed an old bug with decoding
+ chromaticity primaries.
+
+2012-11-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.h ("C"): Need to include wand/wand\_symbols.h
+ after magick/api.h in order for options from magick\_config.h to
+ take effect.
+
+ - magick/symbols.h (PSPageGeometry): Fix typo. Should map to
+ GmPSPageGeometry.
+
+2012-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/wand\_symbols.h, magick/symbol.h: MagickWand API is now
+ prefixed with 'Gm' when the --enable-symbol-prefix configure
+ option is supplied. These changes are contributed by Ben Wu.
+ Details of changes are as follows:
+
+ 1. A new header file wand/wand\_symbols.h which prefixes all
+ MagickWand API symbols with Gm.
+ 2. Modification to all the header files in wand/ to include
+ wand\_symbols.h.
+ 3. Modification to magick/symbols.h to include additional
+ symbols which were colliding with names in ImageMagick.
+ 4. Modification to magick/error.c to exclude function
+ definitions for MagickError, MagickFatalError,
+ MagickWarning, and ThrowException when building with
+ --enable-symbol-prefix option. There four names were also
+ defined as macros so it appears that putting them in a
+ symbol-remapping file wont work.
+
+ - Makefile.am: Update Automake to 1.12.5.
+
+2012-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/COPYING: Change Magick++ usage license to be exactly
+ the MIT license without the additional sentence about retention of
+ copyright (which was already legally implicit).
+
+2012-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/symbols.h: Re-generate list of symbols to prefix.
+
+ - magick/utility.c (IsGlob): IsGlob can be more efficient.
+
+ - magick/floats.c: Use compile-time selection of endian-specific
+ code rather than run-time. Fix cast warning with 64-bit builds.
+
+2012-11-07 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - coders/png.c (WriteOnePNGImage): The wrong QuantumType was
+ sometimes passed to ExportImagePixelArea() by the PNG encoder.
+
+ - coders/png.c (ReadOnePNGImage): Let libpng unpack all sub-8-bit
+ pixels (see change of 2012-08-31 which lets libpng unpack sub-8-bit
+ palette images; this also lets libpng unpack the grayscale images).
+
+ - coders/png.c (ReadOnePNGImage): Corrected the reading of interlaced
+ images (see SourceForge bug 3420695, in which all passes are
+ displayed in a garbled manner instead of only the completed image).
+
+2012-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickGetImagePage): Need to use 'image'
+ rather than 'images' in order to work with iterator.
+ (MagickSetImagePage): Need to use 'image'
+ rather than 'images' in order to work with iterator.
+
+2012-10-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (TranslateTextEx): Fix bug with input string
+ read overrun if the input string ends with a single '%'. This
+ sometimes caused random heap data to be added to the output string
+ until another null character is reached. A simple work-around
+ without this fix is to use "%%" rather than "%". Fixes
+ SourceForge bug 3580219 "strange results with '%' in Annotate()".
+
+2012-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickSetImagePage): New method to support
+ setting the image page size and offsets.
+ (MagickGetImagePage): New method to support getting image page
+ size and offsets.
+
+2012-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Report fatal error if doing modules build and
+ libltdl is not found.
+
+2012-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ltdl: Libltdl is no longer bundled. Libltdl must be previously
+ installed on the system in order to build the modules
+ configuration.
+
+2012-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/index.rst: Update top index page for 1.3.17 release.
+
+ - NEWS.txt: Update NEWS for 1.3.17 release.
+
+ - version.sh: Update shared library versioning for 1.3.17 release.
+
+ - coders/jnx.c: Fix format string compilation warnings. Remove
+ MS-DOS line terminations.
+
+ - configure.ac: Module loading is now only supported by the
+ modules build and not just because shared libraries are enabled.
+ This means that libltdl is only depended upon by the modules
+ build. Sometime in the future, libltdl will no longer be bundled
+ in the GraphicsMagick source tree.
+
+2012-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac (LTDL\_INIT): Request installable libltdl rather
+ than convenience.
+
+2012-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c: Support alpha channel in uncompressed 32-bit BMP.
+ Resolves SourceForge issue 3566239 "Can't open BMP with alpha
+ created by photoshop".
+
+2012-10-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - dcraw/dcraw.c: Fixed situation when M\_PI is not defined.
+
+2012-10-07 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/jnx.c: Add image attribute with geolocation.
+
+2012-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - dcraw: VisualMagick configure fixes to support linking with JPEG
+ and JPEG2000.
+
+2012-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - dcraw: Add dcraw to VisualMagick build.
+
+ - libxml: Update libxml2 to 2.9.0 release.
+
+2012-09-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff: Update libtiff to 4.0.3 release.
+
+ - lcms: Update liblcms2 to 2.4 release.
+
+ - png: Update libpng to 1.5.13 release.
+
+2012-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am: Update to Automake 1.12.4.
+
+2012-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Fix Debian bug 687738 "graphicsmagick:
+ repeated words suitable for suitable for in gm manpage" reported
+ by Jonas Smedegaard.
+
+2012-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Update with news since last release.
+
+ - configure.ac: Added the configure option
+ --enable-quantum-library-names to enable that shared library name
+ includes quantum depth to allow shared libraries with different
+ quantum depths to co-exist in same directory (only one can be used
+ for development).
+
+2012-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (AdaptiveThresholdImage): New implementation
+ contributed by Roberto de Deus Barbosa Murta. Executes in linear
+ time as threhold area is increased rather than being quadratic.
+
+2012-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/svg.c: Fix improper injection of XML headers as rendered
+ text.
+
+ - magick/render.c (DrawImage): Fix SourceForge issue 3499164
+ "Drawing of text fails if text starts with "," character". Fix
+ SourceForge issue 3411492 "Certain SVGs hang GraphicsMagick". Fix
+ SourceForge issue 1961000 "Could not print ',' via convert draw
+ text".
+
+2012-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c (lite\_font\_stringwidth): Simply return zero.
+ Returning a computed string width was causing text placement
+ problems when testing with libwmf's fulltest.wmf.
+
+2012-08-31 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - coders/png.c: ReadOnePNGImage: sub-8-bit palette images were
+ getting unpacked twice; once by libpng via png\_set\_packing()
+ and again by coders/png.c in a switch() statement around line 2500,
+ resulting in horizontally stretched pixels.
+
+2012-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (AUTOMAKE\_OPTIONS): Include lzip as a distribution
+ format again.
+
+2012-08-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: BrowseDelegate now defaults to 'xdg-open', but if
+ it is not found, then configure will search for firefox,
+ google-chrome, mozilla (in that order).
+
+2012-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: For testing on MinGW, assume that Postscript is
+ available since we don't have a good way to check for that.
+
+ - scripts/tap-functions.shi (test\_count): Always execute the test
+ program rather than skipping execution since we want to make sure
+ the test program fails correctly as well.
+
+ - coders/gif.c (DecodeImage): Add a log message for attempted LZW
+ string data table overflow.
+
+2012-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (ConvolveImage): Allocate normalized convolution
+ kernel using cache-line aligned memory allocator.
+
+ - configure.ac: Remove support for legacy LZWDecodeDelegate and
+ LZWEncodeDelegate since these are not used any more.
+
+2012-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - scripts/tap-functions.shi: If a test declares that it needs
+ certain features, skip the test if required features are not
+ available.
+
+ - configure.ac: Build a supported features list and save to
+ common.shi script for use by test scripts.
+
+ - Makefile.am (LOG\_COMPILER): Run Bourne-shell based TAP scripts
+ with the same shell $(SHELL) that configure selected for the
+ Makefile to use.
+
+2012-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (AUTOMAKE\_OPTIONS): Update to Automake 1.12.3.
+ Update test suite to use Automake TAP driver rather than legacy
+ tests.
+
+2012-08-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jnx.c (ExtractTileJPG): Add a trace of tile offset and size.
+
+2012-08-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jnx.c (ExtractTileJPG): Use a memory buffer for the JPEG
+ tile rather than a temporary file.
+
+2012-08-12 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ \* PerlMagick/t/input\_jnx.jnx: Small JNX test file.
+
+2012-08-11 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/jnx.c: speedup.
+
+2012-08-10 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/jnx.c: changed malloc/free to MagickMalloc/MagickFree.
+
+2012-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jnx.c (ReadJNXImage): Add progress monitor support for
+ JNX.
+
+2012-08-06 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/jnx.c: Image cache is turned off to work-around memory
+ overflow.
+
+2012-08-05 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/jnx.c: Fixed.
+
+2012-08-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jnx.c: Add JNX coder for "Garmin proprietary Image
+ Format" (implementation by Jaroslav Fojtik) to the build. Code is
+ not yet working properly at this time.
+
+2012-08-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Remove use of -Wl,-zlazyload under Solaris since
+ it seems to decrease the stability of C++ exceptions in x86-64
+ build and does not measurably improve runtimes. Don't force use
+ of liblzma because libtiff is used. User should always have
+ control.
+
+2012-07-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/memory.c (MagickMallocAligned): Use RoundUpToAlignment()
+ macro to compute aligned pointer.
+
+ - magick/effect.c (EnhanceImage): Eliminate use of ugly Enhance
+ macro. Only filter based on color channels (ignore opacity).
+
+2012-07-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h (MAGICK\_CACHE\_LINE\_SIZE): Assume a cache line
+ size of 64 bytes except for on PowerPC which uses 128.
+
+ - magick/pixel\_cache.c: Use aligned memory allocator to allocate
+ structures and buffers which might suffer from false cache line
+ sharing
+
+ - magick/memory.c (MagickMallocAligned): Also round up allocation
+ size to alignment.
+
+2012-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c, magick/random.c, magick/semaphore.c: Use
+ aligned memory allocator to align allocations which should be
+ aligned to cache line boundary.
+
+2012-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/memory.h (MagickAllocateAlignedMemory): New macro to
+ allocate aligned memory.
+ (MagickFreeAlignedMemory): New macro to free aligned memory.
+
+ - magick/memory.c (MagickMallocAligned): New internal function to
+ allocate aligned memory.
+ (MagickFreeAligned): New internal function to free aligned memory.
+
+2012-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/common.h (MAGICK\_ASSUME\_ALIGNED): Add some GCC attribute
+ wrappers for useful features added by GCC 4.7.
+
+2012-07-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/gif.c (ReadGIFImage): Try to be better about reporting
+ failure when ReadBlob() fails to return the requested number of
+ bytes.
+
+2012-06-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/benchmarks.rst: Strip the outdated benchmark results from
+ the benchmarks page.
+
+ - magick/command.c (ImportImageCommand): Status returned from the
+ command was inverted.
+
+2012-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Release GraphicsMagick 1.3.16
+
+2012-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): -units was adjusting existing
+ resolution the wrong way around.
+
+2012-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - jpeg: Updated to IJG 8d release.
+
+ - libxml: Updated libxml to 2.8.0 release.
+
+ - zlib: Updated zlib to 1.2.7 release.
+
+ - magick/blob.c (MagickFileHandle): Refer to stdio, bzip2, and
+ gzip file handles using their own type. Eliminates warnings
+ observed when compiling with zlib 1.2.7.
+
+ - tiff: Updated libtiff to 4.0.2 release.
+
+ - png: Updated libpng to 1.5.11 release.
+
+2012-06-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Fix typo which caused the --without-lzma option to
+ be handled incorrectly. Resolves SourceForge issue 3535309
+ "graphicsmagick from 1.3.13 to 1.3.15 has broken lzma support".
+
+2012-06-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwfile.c (main): Verify that we can 'ping' the file using
+ PingImage(). Tests for some formats may take longer to complete.
+
+ - tests/rwblob.c (main): Verify that we can 'ping' the blob using
+ PingBlob(). Tests for some formats may take longer to complete.
+
+ - coders/xbm.c (ReadXBMImage): Fix memory leak of temporary X
+ bitmap image allocation encountered when reading in 'ping' mode.
+
+ - magick/blob.c (PingBlob): Re-write to be based on BlobToImage()
+ so that it works reliably.
+ (BlobToImage): Restore original input file name to image if
+ temporary file was used so that image 'filename' and
+ 'magick\_filename' do not contain unexpected content due to using a
+ temporary file.
+
+2012-06-07 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - coders/png.c: Disable new libpng-1.5.10 test for invalid palette
+ index when reading a PNG or MNG (for speed), or when writing a MNG
+ (because a zero-length PLTE is valid in a MNG).
+
+2012-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (SetImageAttribute): Don't translate
+ 'comment' and 'label' attributes if the request is made while a
+ file is being read. This is a temporary workaround until there is
+ opportunity to modify the architecture so that there is a clear
+ split between user-provided settings and values obtained from the
+ input image.
+
+ - magick/blob.c (GetBlobIsOpen): New function to return if blob is
+ currently open.
+
+2012-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/typemap: Add typemap file needed by Perl 5.16.
+ Resolves SourceForge issue 3531512 "PerlMagick does not build with
+ perl 5.16".
+
+2012-05-29 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - coders/png.c: Ignore APNG chunks even if we are using a libpng
+ that was built with the "APNG patch".
+
+2012-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ConvertImageCommand): +repage does not require
+ an argument. Resolves SourceForge issue 3529158 "+repage option
+ not respected with convert command".
+
+ - configure: Update to Autoconf 2.69.
+
+ - magick/effect.c (MotionBlurImage): Motion blur does scale so
+ remove DisableSlowOpenMP for it.
+
+ - magick/command.c (BenchmarkImageCommand): Remove parenthesis
+ from output, and change "iter/sec cpu" to "iter/cpu" to ease
+ parsing.
+
+ - magick/pixel\_cache.c (GetPixelCacheInCore): Consider read-only
+ memory-mapped cache as being "in-core". Otherwise MPC input files
+ are penalized.
+
+2012-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/api.h: Include <sys/types.h> on POSIX systems in order to
+ help assure that 'size\_t' and 'ssize\_t' are declared.
+
+2012-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick\_config\_api.h.in: Need to provide definitions for
+ 'size\_t' and 'ssize\_t' in case the system headers lack these types
+ because the definition of MagickExtentImage() requires them. This
+ should resolve PHP bug #62034 "gmagick does not compile".
+
+2012-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_iterator.c (GetRegionThreads): Don't thread region
+ if it is not memory-based.
+
+2012-05-09 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - coders/png.c (ReadOnePNGImage): make transparent\_color elements
+ unsigned long instead of unsigned short, so 65537 is actually out of
+ range as expected, and won't match any pixel if no tRNS chunk is
+ present.
+
+2012-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sfw.c (ReadSFWImage): Reader needs to be more robust
+ against corrupt or maligned headers. Resolves SourceForge issue
+ "sfw file crash".
+
+2012-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdf.c (WritePDFImage): Add file basename as the PDF
+ document title. Resolves SourceForge bug ID 2835140
+ "GraphicsMagick fails to add title attribute to PDF output".
+
+ - coders/sfw.c (ReadSFWImage): Restore original filename and
+ format.
+
+ - PerlMagick/t/jpeg/read.t: Add a test for reading Seattle
+ FilmWorks format based on the sample image from
+ http://www.algonet.se/~cyren/sfw/. Image was approved for
+ distribution in GraphicsMagick by Bengt Cyrn.
+
+ - magick/analyze.c (GetImageBoundingBox): Only apply opacity-based
+ bounding box detection if all three test points are non-opaque and
+ the same value. Resolves SourceForge bug ID 3522804 "convert
+ -trim fails on 8-bit PNG that ImageMagick can trim".
+
+ - coders/sfw.c (ReadSFWImage): Fix variety of bugs related to
+ closing Image and blob at wrong points. SFW reader is working
+ again. Resolves SourceForge bug ID 523430 "sfw file open failed".
+
+2012-05-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Animated movies inside 4D matrices are loaded now.
+
+2012-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_iterator.c: Limit the number of threads to use in
+ the loop rather than the total number of threads available.
+
+2012-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Release GraphicsMagick 1.3.15
+
+2012-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Remove automatic adjoin mode
+ support logic.
+ (AddDefinition): Fix use of uninitialized variable.
+
+2012-04-23 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - doc/\*.imdoc: some example commandlines in the documentation
+ were missing the leading "gm ".
+
+2012-04-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (FormMultiPartFilename): No longer add a
+ printf-style scene formatting specification to filenames which do
+ not have one and no longer automatically operate in 'adjoin' mode
+ in such cases. This is a BIG CHANGE for users who may have become
+ used to this automatic functionality. The simple solution to
+ update existing scripts depending on this behavior is to change
+ any bare filenames to include a format specification similar to
+ "image-%d.jpg" and add +adjoin to the command line. The reason
+ why this change is made is that the output files produced by any
+ given operation were unpredictable, and it was causing temporary
+ files to be leaked due to the renaming.
+
+2012-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c (WriteBMPImage): Enforce that image width and
+ height do not exceed BMP dimensions. BMP dimensions are
+ represented by a signed type. BMPv2 supports maximum dimensions
+ of 32k by 32k.
+
+2012-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/info.c (WriteINFOImage): When driven by the 'convert'
+ utility, -format produces user-controlled formatted output similar
+ to -format in 'identify'. This is accomplished via a
+ 'info:format=value' define.
+
+ - magick/image.c (AddDefinition): New function for adding just one
+ define to definitions list.
+
+2012-04-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (ReadPNMImage): Completely disable OpenMP in reader
+ because there is too much contention.
+
+ - magick/pixel\_iterator.c: Dereference image to be modified in
+ non-threaded context in order to lessen contention.
+
+ - magick/semaphore.c (AllocateSemaphoreInfo): Make sure that
+ SemaphoreInfo does not share cache lines with another semaphore.
+
+2012-04-11 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - coders/png.c: fixed problem with bit depth when the encoder
+ decides to write RGBA instead of indexed PNG, by delaying the
+ call to png\_set\_tRNS() until after calling png\_set\_IHDR().
+
+2012-03-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Update bundled libpng to 1.5.10 release. Provides security
+ fix for CVE-2011-3048.
+
+ - wand/magick\_compat.c (ParseGeometry): Use strlcpy() rather than
+ strncpy().
+ (CopyMagickString): Depend on strlcpy() because we provide it if
+ it is missing.
+ (ConcatenateMagickString): Depend on strlcat().
+
+ - coders/xcf.c (ReadXCFImage): Now respects image subimage and
+ subrange members so that returned image layers may be selected.
+ Based on patch from SourceForge issue 3513025 "XCF reads all
+ layers all the time".
+
+ - magick/resize.c (ThumbnailImage): Thumbnail default filter is
+ intended to be the box filter, but allow the user to override the
+ filter used. Resolves SourceForge issue 3513239 "-filter command
+ line argument ignored".
+
+2012-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ConvertImageCommand, MogrifyImageCommand):
+ Added support for '+noise random' and '-operator noise-random' to
+ 'convert' and 'mogrify'.
+
+ - magick/effect.c (AddNoiseImage): Added support for RandomNoise.
+ (AddNoiseImageChannel): Added support for RandomNoise.
+
+ - magick/enum\_strings.c (StringToNoiseType): New function to
+ convert a string to a NoiseType enumeration value.
+ (NoiseTypeToString): New function to convert a NoiseType
+ enumeration value into a string.
+
+ - PerlMagick/Magick.xs: Added support for RandomNoise.
+
+ - magick/operator.c (QuantumOperatorRegionImage): Added support for
+ RandomNoise.
+
+ - magick/effect.c (AddNoiseImageChannel): Added support for
+ RandomNoise.
+
+ - magick/gem.c (GenerateDifferentialNoise): Added support for
+ RandomNoise.
+
+ - magick/random.h (MagickRandomRealInlined): The span of
+ MagickRandomRealInlined() is now slightly more accurate.
+
+ - magick/image.h (enum NoiseType): New enumeration value RandomNoise.
+
+2012-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): Add support for -repage option
+ to composite, convert, mogrify, and montage subcommands. Resets
+ or adjusts the current image page offsets based on a provided
+ geometry specification.
+
+ - magick/image.c (ResetImagePage): Add a function to adjust the
+ current image page canvas and position based on a relative page
+ specification.
+
+2012-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImage): Add support for -strip option
+ to composite, convert, mogrify, and montage subcommands. Removes
+ all profiles and text attributes from the image.
+
+ - magick/image.c (StripImage): New function to remove all profiles
+ and text attributes from the image.
+
+2012-02-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Release GraphicsMagick 1.3.14.
+
+ - NEWS.txt: Updated to describe updates since last release.
+
+2012-02-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Downgrade to Automake 1.11.2 so that test suite can run on
+ systems with limited command line length. This means that lzip
+ support is temporarily removed.
+
+ - magick/resize.c (ResizeImage): Resize filter argument was being
+ ignored. Filter from image 'filter' member was used instead.
+ Problem was reported by Steven Bakhtiari.
+
+2012-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff: Update bundled libtiff to 4.0.1 release.
+
+ - png: Update bundled libpng to 1.5.9 release.
+
+ - magick/memory.h: Decorate memory allocation functions with GCC
+ attribute 'alloc\_size'.
+
+ - magick/common.h: Add support for GCC 4.3+ attributes
+ 'alloc\_size', 'hot', 'cold'.
+
+ - magick/{log.h,monitor.h,utility.h}: Use double-underscore syntax
+ in GCC format attribute specifications to defend against
+ accidental macro expansion.
+
+2012-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xcf.c (ReadXCFImage): Fix reading XCF which is comprised
+ of different sized layers.
+
+2012-02-08 Glenn Randers-Pehrson <glennrp@simplesystems.org>
+
+ - coders/txt.c: Added "-define txt:with-im-header" option.
+
+2012-02-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Updated to libpng 1.5.8 release
+
+ - zlib: Updated to zlib 1.2.6 release
+
+2012-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (AUTOMAKE\_OPTIONS): Update to Automake 1.11.3. Add
+ lzip compressed archive to options.
+
+2012-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcraw.c (RegisterDCRAWImage): Add support for Mamiya
+ Photo RAW "MEF" format. Resolves SourceForge issue #3481508
+ "\*.MEF file open incorrect".
+
+2012-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c (WriteJPEGImage): Convert RGB-compatible
+ colorspaces (e.g. CineonLog) to RGB by default since that was the
+ case prior to release 1.3.13. User can still override it
+ (avoiding removal of log encoding) by explicitly specifying the
+ desired colorspace. Problem was reported by Gary Margiotta.
+
+2012-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): When reading, save input file
+ endianness so that the endianness of the original file is
+ preserved by default. The user is able to override this default
+ via -endian. Problem was reported by JongAm Park.
+
+2012-01-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/OpenMP.rst: Updated OpenMP results based on latest OpenMP
+ tunings and the Intel Xeon E5649 CPU.
+
+2012-01-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcraw.c (ReadDCRAWImage): Fix memory leak of ImageInfo.
+ Resolves SourceForge bug #3475148 "memery leaks".
+
+ - magick/module.c (ModuleAliases): EMF format is supported by EMF
+ module and so mapping EMF to the WMF module caused EMF not to
+ work. Resolves SourceForge bug #3475147 "emf files can not be
+ opened". Note that the EMF module only works for Microsoft
+ Windows.
+
+2012-01-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/gem.c (Hull): Improve performance.
+
+ - magick/effect.c (DespeckleImage): Improve performance.
+
+2012-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/effect.c (DespeckleImage): Using schedule(static,4)
+ blocks any opportunity for speedup. This was a performance
+ regression. Oops!
+
+2012-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickExtentImage): Added
+ MagickExtentImage() to Wand API. Resolves SourceForge issue
+ #3471915 "MagickExtentImage in the Wand C API".
+
+2012-01-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/export.c (ExportViewPixelArea): Break up implementation
+ into subroutines to ease compilation.
+
+2012-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/import.c (ImportViewPixelArea): Break up implementation
+ into subroutines to ease compilation.
+
+2012-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h: Use Magick prefixed macro names for ftruncate,
+ mmap, and munmap in order to assure that introducing our macros
+ does not cause trouble with system headers.
diff --git a/www/ChangeLog-2013.html b/www/ChangeLog-2013.html
new file mode 100644
index 0000000..157868d
--- /dev/null
+++ b/www/ChangeLog-2013.html
@@ -0,0 +1,641 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2013-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh: Update for 1.3.19 release.</li>
+<li>www/index.rst: Update for 1.3.19 release.</li>
+<li>NEWS.txt: Update for 1.3.19 release.</li>
+<li>magick/blob.c (GetBlobTemporary): Add assertions to assure that
+image and blob are valid structures.</li>
+<li>coders/png.c (ReadOnePNGImage): Fix problem peculiar to Q8 build
+with reading 1-bit PNG files.</li>
+<li>PerlMagick/t/png/(write-16.t, read.t, write-16.t, write.t):
+Update expected signatures</li>
+<li>coders/xpm.c (WriteXPMImage): Limit XPM color resolution to what
+XPM can traditionally handle.</li>
+<li>magick/enhance.c (GammaImage): Eliminate a compiler warning.</li>
+<li>coders/png.c (ReadOnePNGImage): Eliminate a compiler warning.</li>
+<li>coders/pcl.c (WritePCLImage): Eliminate a compiler warning.</li>
+</ul>
+</blockquote>
+<p>2013-12-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/delegate.c (InvokePostscriptDelegate): Log return status.</li>
+<li>magick/nt_base.c (NTGhostscriptFonts): For Microsoft Windows,
+also search c:gsfonts for Ghostscript font files.</li>
+<li>coders/ept.c (ReadEPTImage): Fix crash observed when Ghostscript
+fails to produce output.</li>
+</ul>
+</blockquote>
+<p>2013-12-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/annotate.c: Simplify FreeType2 header inclusion.</li>
+<li>configure.ac: Only test for freetype/freetype.h if ft2build.h
+was not found.</li>
+</ul>
+</blockquote>
+<p>2013-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ttf: Update FreeType to release 2.5.2.</li>
+<li>Updated build to use Automake 1.14.1.</li>
+</ul>
+</blockquote>
+<p>2013-12-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libxml: Update libxml2 to release 2.9.1.</li>
+</ul>
+</blockquote>
+<p>2013-12-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lcms/include/lcms2.h: Update lcms to release 2.5.</li>
+<li>png/README: Update PNG library to release 1.6.8.</li>
+<li>jpeg: Update Windows IJG JPEG library to release 9.</li>
+</ul>
+</blockquote>
+<p>2013-12-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/alpha_composite.h (BlendCompositePixel): Fix from Troy
+Patteson to eliminate induced color problems when compositing two
+images which include fully transparent pixels. Now fully
+transparent pixels do not contribute any color to the composed
+result. Opacity used when blending is now based on the average
+opacity of both pixels. Resolves SourceForge issue #148 &quot;Pixel
+interpolation problem with rotated transparent images &quot;.</li>
+</ul>
+</blockquote>
+<p>2013-12-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): Properly scale 16-bit input
+PNG down to 8-bit when using a Q8 build.</li>
+</ul>
+</blockquote>
+<p>2013-12-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/demo/piddle.cpp (main): Use DrawableDashArray to make
+sure that it works.</li>
+<li>wand/drawing_wand.c (DrawSetStrokeDashArray): Fix defective
+stroke-dasharray MVG generation. Resolves SourceForge issue &quot;#255
+DrawSetStrokeDashArray still fails&quot;.</li>
+<li>magick/draw.c (DrawSetStrokeDashArray): Fix defective
+stroke-dasharray MVG generation.</li>
+</ul>
+</blockquote>
+<p>2013-12-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jpeg.c: Add value scaling changes which will be necessary
+to support all the build depths supported by IJG JPEG 9a.</li>
+<li>coders/webp.c (ReadWEBPImage): Support 'ping'. Improve quality
+of error reporting.</li>
+<li>GraphicsMagick.spec.in: Update RPM spec file to add
+libwebp-devel as a build dependency, and libwebp as a run-time
+depdendency.</li>
+</ul>
+</blockquote>
+<p>2013-12-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/webp.c: Incorporated simple WebP support as contributed
+by &quot;TIMEBUG&quot; at users.sf.net plus a few security changes. Does not
+yet support Windows Visual Studio build, input from a pipe,
+attached profiles, animation, or incremental pixel I/O.
+(RegisterWEBPImage): Register WebP as requiring seekable stream so
+input from pipe works.</li>
+</ul>
+</blockquote>
+<p>2013-11-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/drawing_wand.c (DrawSetStrokeDashArray): Use array size
+specified by user and don't expect user-provided array to be
+terminated by 0.0. Resolves SourceForge bug &quot;#250 Unexpected
+results from DrawSetStrokeDashArray&quot;.</li>
+<li>magick/draw.c (DrawSetStrokeDashArray): Use array size specified
+by user and don't expect user-provided array to be terminated by
+0.0.</li>
+<li>wand/drawing_wand.c (DrawGetStrokeDashArray): terminating 0.0 to
+array returned to user.</li>
+<li>magick/draw.c (DrawGetStrokeDashArray): Add terminating 0.0 to
+array returned to user.</li>
+</ul>
+</blockquote>
+<p>2013-11-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/annotate.c (RenderFreetype): Support rendering UTF-8
+21-bit code points. Was limited to 16-bit code points due to an
+oversight/bug. Resolves SourceForge bug &quot;#149 Rendering UTF-8
+encoded file displays wrong glyphs&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-11-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/constitute.c (ReadImage): Consistently initialize Image
+page width and height to image width and height. Resolves
+SourceForge bug #253 convert pdf output page is the wrong size
+with -geometry &quot;100%&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-11-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): TIFFDefaultStripSize() sometimes
+returns zero so make sure that rows-per-strip is at least one to
+avoid divide by zero error. This bug was added in the current
+development cycle.</li>
+</ul>
+</blockquote>
+<p>2013-10-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Update news since last release.</li>
+<li>magick/annotate.c (RenderFreetype): Support Johab, Latin-1, and
+Latin-2 encodings.</li>
+</ul>
+</blockquote>
+<p>2013-10-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/drawing_wand.c (DrawSetStrokeLineJoin): BevelJoin should
+produce MVG text &quot;bevel&quot;.</li>
+<li>magick/draw.c (DrawSetStrokeLineJoin): BevelJoin should produce
+MVG text &quot;bevel&quot;. Fixes SourceForge bug &quot;#245 error occured to
+DrawableStrokeLineJoin(LineJoin.BevelJoin)&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-10-16 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Added calls to png_set_benign_errors() to allow benign errors
+to be handled as warnings. In particular, GM builds with libpng-1.6.x
+will not crash while copying a PNG with a &quot;known incorrect ICC
+profile&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (NTGhostscriptEXE): Use gswin64c.exe as
+Ghostscript executable name in a 64-bit application.</li>
+</ul>
+</blockquote>
+<p>2013-10-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (NTGhostscriptFind): 64-bit application should
+not search for Ghostscript in 32-bit registry. SourceForge bug
+#243 &quot;GM on Windows will find Ghostscript only if both are 32 bit&quot;</li>
+</ul>
+</blockquote>
+<p>2013-09-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c: As an extension to the standard PNM and PAM
+formats, support writing 32-bit sample depth in the Q32 build, and
+supporting reading 32-bit sample depth in all builds.</li>
+</ul>
+</blockquote>
+<p>2013-09-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c: Allow reading signed integer TIFF files even
+though internal storage uses signed integers. Negative values
+will be handled incorrectly and positive values will be scaled to
+only 1/2 of the available unsigned range. Perhaps the situation
+will improve in the future.</li>
+<li>tests/rwfile_miff.tap: Test MIFF with specific depths.</li>
+<li>tests/rwblob.c: Add support for -quality option.</li>
+<li>tests/rwfile.c: Add support for -quality option.</li>
+<li>tests/rwfile.tap: Add tests for PGM and PPM ASCII subformats.</li>
+<li>coders/pnm.c (WritePNMImage): PGM &quot;P2&quot; format writer was broken
+at 8-bit depth due to lack of white-space between the output
+values. Fixed now.</li>
+</ul>
+</blockquote>
+<p>2013-09-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): Fixes to be able to read MIFF
+written by ImageMagick 6.X, including DirectClass grayscale
+images. Interoperabilty is not completely assured since
+ImageMagick is not consistent with itself and may only be able to
+read the file it just wrote. Reading DirectClass grayscale RLE
+compressed images is not supported yet.</li>
+</ul>
+</blockquote>
+<p>2013-09-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/profile.c (MagickFreeCMSTransform): Only delete the CMS
+transform if it is non-null. If lcms returned a null transform,
+an assertion was thrown in lcms when the pointer was freed.
+Problem was reported by James Bardin.</li>
+</ul>
+</blockquote>
+<p>2013-09-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c: PseudoClass format was written incorrectly in
+that sample storage size is supposed to be selected based on the
+size of the colormap, but it was being selected based on the depth
+parameter instead, leading to excessively sized files and failure
+to read what was written. RLE compressed formats had the sense of
+the alpha channel inverted from the other compression methods, and
+contrary to the specification. PseudoClass with Alpha was not
+supported at all, and reading a file claiming to be such caused an
+assertion to be thrown. Note that these fixes may cause some
+existing files to no longer be read correctly.</li>
+<li>coders/xpm.c (ReadXPMImage): XPM is rarely used to produce
+16-bit output. Set image depth based on the colormap.</li>
+<li>coders/tim.c (ReadTIMImage): PSX TIM is not able to produce more
+than 8-bit output, set image depth appropriately.</li>
+</ul>
+</blockquote>
+<p>2013-09-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Increase rows-per-strip as
+required to try to avoid more than 32K strips per image since some
+programs seem to use a 16-bit strip counter and fail with more
+than 32K strips. Problem was reported by Kevin Myers.</li>
+<li>magick/transform.c (MosaicImages): Fix unsigned underflow
+problem with -mosaic when page offset is negative and exceeds
+image width or height. This problem caused assertions, out of
+memory errors, or pixel cache limit errors due to requesting an
+image of outrageous size.</li>
+</ul>
+</blockquote>
+<dl class="docutils">
+<dt>2013-08-26 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</dt>
+<dd>* dcrawdcraw.c Updated from autor
+* dcrawdcraw.c.patch</dd>
+</dl>
+<p>2013-08-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (ReadPNMImage): Fix SourceForge issue #237
+&quot;Incorrect MAXVAL scaling when reading PAM images&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-08-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawImage): Improve error handling so that
+rendering bails on image access/update errors. Resolves
+SourceForge issues #233 &quot;Another SVG that hangs GraphicsMagick&quot;
+and #232 &quot;Another SVG that hangs GraphicsMagick&quot;. The resolution
+of the bug is to return from image access/update error right away
+rather than adjusting the rendering density to produce a smaller
+image.</li>
+<li>magick/error.h: Hide exception throwing convenience macros under
+MAGICK_IMPLEMENTATION definition.</li>
+<li>Magick++/demo/demos.tap: Fix file naming for 'zoom' demos.</li>
+<li>magick/annotate.c (RenderFreetype): Improve error handling so
+that rendering bails on image access/update errors.</li>
+</ul>
+</blockquote>
+<p>2013-08-02 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): ping a png faster by
+returning the image without reading the pixel data.</li>
+</ul>
+</blockquote>
+<p>2013-07-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/xwindow.c (MagickXMakeImage): Only use ThumbnailImage()
+for DirectClass images in order to avoid a crash while creating
+the panner image.</li>
+</ul>
+</blockquote>
+<p>2013-04-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>design/pixel-cache-struct.dot: Update structure relationships
+diagram.</li>
+<li>design/pixel-cache.dot: Update call flow diagram.</li>
+<li>magick/pixel_cache.c: Eliminate use of internal functions
+GetNexusIndexes(), GetNexusPixels(). Reduce usage of internal
+function IsNexusInCore().</li>
+</ul>
+</blockquote>
+<p>2013-04-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: MAGICK_SSIZE_T should always be a signed type.</li>
+<li>coders/jpeg.c (WriteXMPProfile): Add support for writing 'XMP'
+profile in JPEG.
+(WriteJPEGImage): Restructure/tidy JPEG profile writing code.</li>
+</ul>
+</blockquote>
+<p>2013-04-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Return DirectClass images by
+default for MINISWHITE and MINISBLACK TIFF formats.</li>
+</ul>
+</blockquote>
+<p>2013-04-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c, magick/attribute.c, magick/map.c, magick/render.c,
+magick/widget.c, magick/xwindow.c: Fixes to reduce warnings with
+GCC 4.8.0 at -O3 optimimization level, and for clang 3.2.</li>
+</ul>
+</blockquote>
+<p>2013-04-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/xwindow.c (MagickXMakeImage): Use ThumbnailImage() rather
+than SampleImage() when creating the panner image to improve the
+quality of the image.</li>
+</ul>
+</blockquote>
+<p>2013-03-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (tag_table): Add support for SubjectArea EXIF
+tag. Resolves SourceForge issue #229 &quot;Cannot Parse the
+SubjectArea EXIF Info&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-03-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Hg.rst, www/index.rst: Update SourceForge Mercurial
+repository location (see
+<a class="reference external" href="http://hg.code.sf.net/p/graphicsmagick/code">http://hg.code.sf.net/p/graphicsmagick/code</a>) due to project
+&quot;upgrade&quot;. For the moment there are old and new
+repositories. Changes will be pushed to the new repository.</li>
+</ul>
+</blockquote>
+<p>2013-03-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (InitializeMagickResources): Revert use of
+omp_set_dynamic() since it caused a severe performance regression
+when doing a -stepthreads benchmark or when the number of OpenMP
+threads is set via OMP_NUM_THREADS.</li>
+</ul>
+</blockquote>
+<p>2013-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>INSTALL-unix.txt: Add a section about building Windows binaries
+by cross-compiling from a Unix/Linux system.</li>
+</ul>
+</blockquote>
+<p>2013-03-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac, magick/magick_types.h.in: Fix issues noticed when
+cross-compiling with MinGW64.</li>
+</ul>
+</blockquote>
+<p>2013-03-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>version.sh, www/index.rst: Prepare for 1.3.18 release.</li>
+</ul>
+</blockquote>
+<p>2013-03-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (DisplayImageCommand): display is supposed to
+respond to +/-usePixmap, but was not. It was responding to
++/-use_pixmap. Now it responds to both.</li>
+</ul>
+</blockquote>
+<p>2013-03-03 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/GraphicsMagick.imdoc: Relocated some &lt;im&gt; .. &lt;/im&gt; tags, to
+include several paragraphs that were omitted from the
+GraphicsMagick man page (Environment, Configuration Files, and
+Copyright).</li>
+<li>doc/imdoc2man: the &lt;/pre&gt; tag was being deleted instead of
+replaced with nothing, which caused the first line of the
+subsequent material to be joined to the last line of the &lt;pre&gt;
+block.</li>
+</ul>
+</blockquote>
+<p>2013-03-02 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): Avoid a libpng16 warning about
+storing unknown chunks.</li>
+</ul>
+</blockquote>
+<p>2013-02-25 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): Call png_set_bKGD(), etc.,
+after png_set_IHDR() because they depend on members of info_ptr
+which are set by png_set_IHDR().</li>
+</ul>
+</blockquote>
+<p>2013-02-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (InitializeMagickResources): Enable the
+dynamic adjustment of OpenMP threads if there is more than one
+thread available.</li>
+</ul>
+</blockquote>
+<p>2013-02-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac and configure: Check for libpng17 and libpng16.</li>
+</ul>
+</blockquote>
+<p>2013-02-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/programming.rst: Add mention of Clement Farabet's Lua
+scripting language wrapper for GraphicsMagick.</li>
+</ul>
+</blockquote>
+<p>2013-02-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (GetCacheNexus): Re-write function so it
+has a single point of return.
+(AcquireCacheNexus): Reduce the number of return points.
+(SetCacheNexus): Re-write function so it has a single point of
+return.</li>
+</ul>
+</blockquote>
+<p>2013-02-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Update with latest news.</li>
+<li>magick/export.c (ExportAlphaQuantumType): Fix export of alpha
+for RGBA image and depth 8. Due to typo, was exporting 16-bits
+rather than 8, causing output corruption or crashes. Resolves
+issue reported in SourceForge GraphicsMagick forum under title
+&quot;CMYK per-channel byte order TIFF crashes gm&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-02-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h (MagickIsBlank): Add macro to substitute for ISO
+C99 isblank() which is not globally available. Update 'gm batch'
+code which had substituted isspace() for isblank() to use it.</li>
+</ul>
+</blockquote>
+<p>2013-01-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (BatchCommand): Flush stdout at key points in
+order to ensure that user sees text when it is produced.</li>
+</ul>
+</blockquote>
+<p>2013-01-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/random.c (InitializeMagickRandomGenerator): Use
+MagickTsdKeyCreate2() in order to avoid a small memory leak.</li>
+<li>magick/tsd.c (MagickTsdKeyCreate2): New private function to
+support allocating a thread-specific data key with a specified
+destructor function. For single-threaded build, MagickTsdKey_t is
+now type void* and there is provision to support the destructor
+function.</li>
+</ul>
+</blockquote>
+<p>2013-01-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (BatchCommand): New 'gm batch' command to
+accept one or more GraphicsMagick commands from a specified text
+file, standard input, or CLI. Feature is implemented by Kenneth
+Xu. Submitted via SourceForge Patch #3602331 &quot;Add interactive or
+batch mode support to 1.3.17&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-01-27 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): Added PNG48 and PNG64 support.
+Added PNG00 support (png encoder that inherits its color-type and
+bit-depth from the input, if the input was a PNG datastream).</li>
+</ul>
+</blockquote>
+<p>2013-01-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): PNG8 support was using
+image-&gt;colors to decide if the input image is PseudoClass. This
+is totally bogus. Use image-&gt;storage_class to determine if image
+is PseudoClass and quantize image colors if it is not.</li>
+<li>magick/delegate.c (InvokePostscriptDelegate): Only invoke
+MagickSpawnVP() if Ghostscript filename argument is non-empty.
+This argument may be empty if Ghostscript is not found on a
+Windows system. Report a &quot;Failed to find Ghostscript&quot; error if
+the Ghostscript command name is empty. Resolves SourceForge issue
+#3601816 &quot;Win64 build crashes trying to convert PDF to any other
+format&quot;.</li>
+<li>magick/utility.c (MagickSpawnVP): Verify that file argument is
+non-NULL and not empty.</li>
+</ul>
+</blockquote>
+<p>2013-01-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/tiff/LIBRARY.txt: Fix pre-processor definitions for
+libtiff so that they use multiple statements rather than one long
+statement. Resolves SourceForge issue 3601001 &quot;libtiff won't
+compile with ICL&quot;.</li>
+</ul>
+</blockquote>
+<p>2013-01-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/memory.h (MagickAllocateAlignedArray): New macro to wrap
+use of MagickMallocAlignedArray().</li>
+<li>magick/memory.c (MagickMallocAlignedArray): New private function
+to support safe allocation of an array in memory with a specified
+alignment. Allocation may only be freed using MagickFreeAligned()
+and the allocation may not be reallocated.</li>
+</ul>
+</blockquote>
+<p>2013-01-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/{animate.c,display.c,utility.c}: Only invoke chdir() if
+path is not an empty string. Previously sometimes chdir() was
+passed an empty string (because chdir() was not needed) and this
+was ok because we ignored the error status. Now that we check the
+chdir() error status, some X11 GUI functions (e.g. save file to
+current directory) encounter annoying issues.</li>
+<li>magick/shear.c (IntegralRotateImage): Limit integral rotate to
+two threads.</li>
+<li>coders/pnm.c (ReadPNMImage): Limit PNM reader to two threads.</li>
+</ul>
+</blockquote>
+<p>2013-01-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac (MAGICK_FEATURES): MinGW static build does not
+build modules so MODULES feature should not be listed as
+supported. Resolves MinGW test failures.</li>
+<li>coders/dpx.c (OrientationTypeToDPXOrientation): Return U16 type
+as stored in DPX format.</li>
+<li>coders/cineon.c: Add support for reading/writing 'orientation'
+setting.</li>
+<li>coders/mpc.c: Add support for reading/writing 'orientation'
+setting.</li>
+<li>coders/miff.c: Add support for reading/writing 'orientation'
+setting.</li>
+<li>Rotate ChangeLog for 2012 and update web page copyright years.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2013.rst b/www/ChangeLog-2013.rst
new file mode 100644
index 0000000..bee660d
--- /dev/null
+++ b/www/ChangeLog-2013.rst
@@ -0,0 +1,530 @@
+2013-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh: Update for 1.3.19 release.
+
+ - www/index.rst: Update for 1.3.19 release.
+
+ - NEWS.txt: Update for 1.3.19 release.
+
+ - magick/blob.c (GetBlobTemporary): Add assertions to assure that
+ image and blob are valid structures.
+
+ - coders/png.c (ReadOnePNGImage): Fix problem peculiar to Q8 build
+ with reading 1-bit PNG files.
+
+ - PerlMagick/t/png/(write-16.t, read.t, write-16.t, write.t):
+ Update expected signatures
+
+ - coders/xpm.c (WriteXPMImage): Limit XPM color resolution to what
+ XPM can traditionally handle.
+
+ - magick/enhance.c (GammaImage): Eliminate a compiler warning.
+
+ - coders/png.c (ReadOnePNGImage): Eliminate a compiler warning.
+
+ - coders/pcl.c (WritePCLImage): Eliminate a compiler warning.
+
+2013-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/delegate.c (InvokePostscriptDelegate): Log return status.
+
+ - magick/nt\_base.c (NTGhostscriptFonts): For Microsoft Windows,
+ also search c:\gs\fonts for Ghostscript font files.
+
+ - coders/ept.c (ReadEPTImage): Fix crash observed when Ghostscript
+ fails to produce output.
+
+2013-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/annotate.c: Simplify FreeType2 header inclusion.
+
+ - configure.ac: Only test for freetype/freetype.h if ft2build.h
+ was not found.
+
+2013-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ttf: Update FreeType to release 2.5.2.
+
+ - Updated build to use Automake 1.14.1.
+
+2013-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libxml: Update libxml2 to release 2.9.1.
+
+2013-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lcms/include/lcms2.h: Update lcms to release 2.5.
+
+ - png/README: Update PNG library to release 1.6.8.
+
+ - jpeg: Update Windows IJG JPEG library to release 9.
+
+2013-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/alpha\_composite.h (BlendCompositePixel): Fix from Troy
+ Patteson to eliminate induced color problems when compositing two
+ images which include fully transparent pixels. Now fully
+ transparent pixels do not contribute any color to the composed
+ result. Opacity used when blending is now based on the average
+ opacity of both pixels. Resolves SourceForge issue #148 "Pixel
+ interpolation problem with rotated transparent images ".
+
+2013-12-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOnePNGImage): Properly scale 16-bit input
+ PNG down to 8-bit when using a Q8 build.
+
+2013-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/demo/piddle.cpp (main): Use DrawableDashArray to make
+ sure that it works.
+
+ - wand/drawing\_wand.c (DrawSetStrokeDashArray): Fix defective
+ stroke-dasharray MVG generation. Resolves SourceForge issue "#255
+ DrawSetStrokeDashArray still fails".
+
+ - magick/draw.c (DrawSetStrokeDashArray): Fix defective
+ stroke-dasharray MVG generation.
+
+2013-12-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jpeg.c: Add value scaling changes which will be necessary
+ to support all the build depths supported by IJG JPEG 9a.
+
+ - coders/webp.c (ReadWEBPImage): Support 'ping'. Improve quality
+ of error reporting.
+
+ - GraphicsMagick.spec.in: Update RPM spec file to add
+ libwebp-devel as a build dependency, and libwebp as a run-time
+ depdendency.
+
+2013-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/webp.c: Incorporated simple WebP support as contributed
+ by "TIMEBUG" at users.sf.net plus a few security changes. Does not
+ yet support Windows Visual Studio build, input from a pipe,
+ attached profiles, animation, or incremental pixel I/O.
+ (RegisterWEBPImage): Register WebP as requiring seekable stream so
+ input from pipe works.
+
+2013-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/drawing\_wand.c (DrawSetStrokeDashArray): Use array size
+ specified by user and don't expect user-provided array to be
+ terminated by 0.0. Resolves SourceForge bug "#250 Unexpected
+ results from DrawSetStrokeDashArray".
+
+ - magick/draw.c (DrawSetStrokeDashArray): Use array size specified
+ by user and don't expect user-provided array to be terminated by
+ 0.0.
+
+ - wand/drawing\_wand.c (DrawGetStrokeDashArray): terminating 0.0 to
+ array returned to user.
+
+ - magick/draw.c (DrawGetStrokeDashArray): Add terminating 0.0 to
+ array returned to user.
+
+2013-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/annotate.c (RenderFreetype): Support rendering UTF-8
+ 21-bit code points. Was limited to 16-bit code points due to an
+ oversight/bug. Resolves SourceForge bug "#149 Rendering UTF-8
+ encoded file displays wrong glyphs".
+
+2013-11-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/constitute.c (ReadImage): Consistently initialize Image
+ page width and height to image width and height. Resolves
+ SourceForge bug #253 convert pdf output page is the wrong size
+ with -geometry "100%".
+
+2013-11-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): TIFFDefaultStripSize() sometimes
+ returns zero so make sure that rows-per-strip is at least one to
+ avoid divide by zero error. This bug was added in the current
+ development cycle.
+
+2013-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Update news since last release.
+
+ - magick/annotate.c (RenderFreetype): Support Johab, Latin-1, and
+ Latin-2 encodings.
+
+2013-10-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/drawing\_wand.c (DrawSetStrokeLineJoin): BevelJoin should
+ produce MVG text "bevel".
+
+ - magick/draw.c (DrawSetStrokeLineJoin): BevelJoin should produce
+ MVG text "bevel". Fixes SourceForge bug "#245 error occured to
+ DrawableStrokeLineJoin(LineJoin.BevelJoin)".
+
+2013-10-16 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - Added calls to png\_set\_benign\_errors() to allow benign errors
+ to be handled as warnings. In particular, GM builds with libpng-1.6.x
+ will not crash while copying a PNG with a "known incorrect ICC
+ profile".
+
+2013-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (NTGhostscriptEXE): Use gswin64c.exe as
+ Ghostscript executable name in a 64-bit application.
+
+2013-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (NTGhostscriptFind): 64-bit application should
+ not search for Ghostscript in 32-bit registry. SourceForge bug
+ #243 "GM on Windows will find Ghostscript only if both are 32 bit"
+
+2013-09-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c: As an extension to the standard PNM and PAM
+ formats, support writing 32-bit sample depth in the Q32 build, and
+ supporting reading 32-bit sample depth in all builds.
+
+2013-09-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c: Allow reading signed integer TIFF files even
+ though internal storage uses signed integers. Negative values
+ will be handled incorrectly and positive values will be scaled to
+ only 1/2 of the available unsigned range. Perhaps the situation
+ will improve in the future.
+
+ - tests/rwfile\_miff.tap: Test MIFF with specific depths.
+
+ - tests/rwblob.c: Add support for -quality option.
+
+ - tests/rwfile.c: Add support for -quality option.
+
+ - tests/rwfile.tap: Add tests for PGM and PPM ASCII subformats.
+
+ - coders/pnm.c (WritePNMImage): PGM "P2" format writer was broken
+ at 8-bit depth due to lack of white-space between the output
+ values. Fixed now.
+
+2013-09-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): Fixes to be able to read MIFF
+ written by ImageMagick 6.X, including DirectClass grayscale
+ images. Interoperabilty is not completely assured since
+ ImageMagick is not consistent with itself and may only be able to
+ read the file it just wrote. Reading DirectClass grayscale RLE
+ compressed images is not supported yet.
+
+2013-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/profile.c (MagickFreeCMSTransform): Only delete the CMS
+ transform if it is non-null. If lcms returned a null transform,
+ an assertion was thrown in lcms when the pointer was freed.
+ Problem was reported by James Bardin.
+
+2013-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c: PseudoClass format was written incorrectly in
+ that sample storage size is supposed to be selected based on the
+ size of the colormap, but it was being selected based on the depth
+ parameter instead, leading to excessively sized files and failure
+ to read what was written. RLE compressed formats had the sense of
+ the alpha channel inverted from the other compression methods, and
+ contrary to the specification. PseudoClass with Alpha was not
+ supported at all, and reading a file claiming to be such caused an
+ assertion to be thrown. Note that these fixes may cause some
+ existing files to no longer be read correctly.
+
+ - coders/xpm.c (ReadXPMImage): XPM is rarely used to produce
+ 16-bit output. Set image depth based on the colormap.
+
+ - coders/tim.c (ReadTIMImage): PSX TIM is not able to produce more
+ than 8-bit output, set image depth appropriately.
+
+2013-09-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Increase rows-per-strip as
+ required to try to avoid more than 32K strips per image since some
+ programs seem to use a 16-bit strip counter and fail with more
+ than 32K strips. Problem was reported by Kevin Myers.
+
+ - magick/transform.c (MosaicImages): Fix unsigned underflow
+ problem with -mosaic when page offset is negative and exceeds
+ image width or height. This problem caused assertions, out of
+ memory errors, or pixel cache limit errors due to requesting an
+ image of outrageous size.
+
+2013-08-26 Jaroslav Fojtik <JaFojtik@seznam.cz>
+ \* dcraw\dcraw.c Updated from autor
+ \* dcraw\dcraw.c.patch
+
+2013-08-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (ReadPNMImage): Fix SourceForge issue #237
+ "Incorrect MAXVAL scaling when reading PAM images".
+
+2013-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawImage): Improve error handling so that
+ rendering bails on image access/update errors. Resolves
+ SourceForge issues #233 "Another SVG that hangs GraphicsMagick"
+ and #232 "Another SVG that hangs GraphicsMagick". The resolution
+ of the bug is to return from image access/update error right away
+ rather than adjusting the rendering density to produce a smaller
+ image.
+
+ - magick/error.h: Hide exception throwing convenience macros under
+ MAGICK\_IMPLEMENTATION definition.
+
+ - Magick++/demo/demos.tap: Fix file naming for 'zoom' demos.
+
+ - magick/annotate.c (RenderFreetype): Improve error handling so
+ that rendering bails on image access/update errors.
+
+2013-08-02 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOnePNGImage): ping a png faster by
+ returning the image without reading the pixel data.
+
+2013-07-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/xwindow.c (MagickXMakeImage): Only use ThumbnailImage()
+ for DirectClass images in order to avoid a crash while creating
+ the panner image.
+
+2013-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - design/pixel-cache-struct.dot: Update structure relationships
+ diagram.
+
+ - design/pixel-cache.dot: Update call flow diagram.
+
+ - magick/pixel\_cache.c: Eliminate use of internal functions
+ GetNexusIndexes(), GetNexusPixels(). Reduce usage of internal
+ function IsNexusInCore().
+
+2013-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: MAGICK\_SSIZE\_T should always be a signed type.
+
+ - coders/jpeg.c (WriteXMPProfile): Add support for writing 'XMP'
+ profile in JPEG.
+ (WriteJPEGImage): Restructure/tidy JPEG profile writing code.
+
+2013-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Return DirectClass images by
+ default for MINISWHITE and MINISBLACK TIFF formats.
+
+2013-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wpg.c, magick/attribute.c, magick/map.c, magick/render.c,
+ magick/widget.c, magick/xwindow.c: Fixes to reduce warnings with
+ GCC 4.8.0 at -O3 optimimization level, and for clang 3.2.
+
+2013-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/xwindow.c (MagickXMakeImage): Use ThumbnailImage() rather
+ than SampleImage() when creating the panner image to improve the
+ quality of the image.
+
+2013-03-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (tag\_table): Add support for SubjectArea EXIF
+ tag. Resolves SourceForge issue #229 "Cannot Parse the
+ SubjectArea EXIF Info".
+
+2013-03-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Hg.rst, www/index.rst: Update SourceForge Mercurial
+ repository location (see
+ http://hg.code.sf.net/p/graphicsmagick/code) due to project
+ "upgrade". For the moment there are old and new
+ repositories. Changes will be pushed to the new repository.
+
+2013-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (InitializeMagickResources): Revert use of
+ omp\_set\_dynamic() since it caused a severe performance regression
+ when doing a -stepthreads benchmark or when the number of OpenMP
+ threads is set via OMP\_NUM\_THREADS.
+
+2013-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - INSTALL-unix.txt: Add a section about building Windows binaries
+ by cross-compiling from a Unix/Linux system.
+
+2013-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac, magick/magick\_types.h.in: Fix issues noticed when
+ cross-compiling with MinGW64.
+
+2013-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - version.sh, www/index.rst: Prepare for 1.3.18 release.
+
+2013-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (DisplayImageCommand): display is supposed to
+ respond to +/-usePixmap, but was not. It was responding to
+ +/-use\_pixmap. Now it responds to both.
+
+2013-03-03 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - doc/GraphicsMagick.imdoc: Relocated some <im> .. </im> tags, to
+ include several paragraphs that were omitted from the
+ GraphicsMagick man page (Environment, Configuration Files, and
+ Copyright).
+
+ - doc/imdoc2man: the </pre> tag was being deleted instead of
+ replaced with nothing, which caused the first line of the
+ subsequent material to be joined to the last line of the <pre>
+ block.
+
+2013-03-02 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOnePNGImage): Avoid a libpng16 warning about
+ storing unknown chunks.
+
+2013-02-25 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOnePNGImage): Call png\_set\_bKGD(), etc.,
+ after png\_set\_IHDR() because they depend on members of info\_ptr
+ which are set by png\_set\_IHDR().
+
+2013-02-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (InitializeMagickResources): Enable the
+ dynamic adjustment of OpenMP threads if there is more than one
+ thread available.
+
+2013-02-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - configure.ac and configure: Check for libpng17 and libpng16.
+
+2013-02-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/programming.rst: Add mention of Clement Farabet's Lua
+ scripting language wrapper for GraphicsMagick.
+
+2013-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (GetCacheNexus): Re-write function so it
+ has a single point of return.
+ (AcquireCacheNexus): Reduce the number of return points.
+ (SetCacheNexus): Re-write function so it has a single point of
+ return.
+
+2013-02-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Update with latest news.
+
+ - magick/export.c (ExportAlphaQuantumType): Fix export of alpha
+ for RGBA image and depth 8. Due to typo, was exporting 16-bits
+ rather than 8, causing output corruption or crashes. Resolves
+ issue reported in SourceForge GraphicsMagick forum under title
+ "CMYK per-channel byte order TIFF crashes gm".
+
+2013-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h (MagickIsBlank): Add macro to substitute for ISO
+ C99 isblank() which is not globally available. Update 'gm batch'
+ code which had substituted isspace() for isblank() to use it.
+
+2013-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (BatchCommand): Flush stdout at key points in
+ order to ensure that user sees text when it is produced.
+
+2013-01-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/random.c (InitializeMagickRandomGenerator): Use
+ MagickTsdKeyCreate2() in order to avoid a small memory leak.
+
+ - magick/tsd.c (MagickTsdKeyCreate2): New private function to
+ support allocating a thread-specific data key with a specified
+ destructor function. For single-threaded build, MagickTsdKey\_t is
+ now type void\* and there is provision to support the destructor
+ function.
+
+2013-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (BatchCommand): New 'gm batch' command to
+ accept one or more GraphicsMagick commands from a specified text
+ file, standard input, or CLI. Feature is implemented by Kenneth
+ Xu. Submitted via SourceForge Patch #3602331 "Add interactive or
+ batch mode support to 1.3.17".
+
+2013-01-27 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOnePNGImage): Added PNG48 and PNG64 support.
+ Added PNG00 support (png encoder that inherits its color-type and
+ bit-depth from the input, if the input was a PNG datastream).
+
+2013-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOnePNGImage): PNG8 support was using
+ image->colors to decide if the input image is PseudoClass. This
+ is totally bogus. Use image->storage\_class to determine if image
+ is PseudoClass and quantize image colors if it is not.
+
+ - magick/delegate.c (InvokePostscriptDelegate): Only invoke
+ MagickSpawnVP() if Ghostscript filename argument is non-empty.
+ This argument may be empty if Ghostscript is not found on a
+ Windows system. Report a "Failed to find Ghostscript" error if
+ the Ghostscript command name is empty. Resolves SourceForge issue
+ #3601816 "Win64 build crashes trying to convert PDF to any other
+ format".
+
+ - magick/utility.c (MagickSpawnVP): Verify that file argument is
+ non-NULL and not empty.
+
+2013-01-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/tiff/LIBRARY.txt: Fix pre-processor definitions for
+ libtiff so that they use multiple statements rather than one long
+ statement. Resolves SourceForge issue 3601001 "libtiff won't
+ compile with ICL".
+
+2013-01-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/memory.h (MagickAllocateAlignedArray): New macro to wrap
+ use of MagickMallocAlignedArray().
+
+ - magick/memory.c (MagickMallocAlignedArray): New private function
+ to support safe allocation of an array in memory with a specified
+ alignment. Allocation may only be freed using MagickFreeAligned()
+ and the allocation may not be reallocated.
+
+2013-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/{animate.c,display.c,utility.c}: Only invoke chdir() if
+ path is not an empty string. Previously sometimes chdir() was
+ passed an empty string (because chdir() was not needed) and this
+ was ok because we ignored the error status. Now that we check the
+ chdir() error status, some X11 GUI functions (e.g. save file to
+ current directory) encounter annoying issues.
+
+ - magick/shear.c (IntegralRotateImage): Limit integral rotate to
+ two threads.
+
+ - coders/pnm.c (ReadPNMImage): Limit PNM reader to two threads.
+
+2013-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac (MAGICK\_FEATURES): MinGW static build does not
+ build modules so MODULES feature should not be listed as
+ supported. Resolves MinGW test failures.
+
+ - coders/dpx.c (OrientationTypeToDPXOrientation): Return U16 type
+ as stored in DPX format.
+
+ - coders/cineon.c: Add support for reading/writing 'orientation'
+ setting.
+
+ - coders/mpc.c: Add support for reading/writing 'orientation'
+ setting.
+
+ - coders/miff.c: Add support for reading/writing 'orientation'
+ setting.
+
+ - Rotate ChangeLog for 2012 and update web page copyright years.
diff --git a/www/ChangeLog-2014.html b/www/ChangeLog-2014.html
new file mode 100644
index 0000000..73ad310
--- /dev/null
+++ b/www/ChangeLog-2014.html
@@ -0,0 +1,1031 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2014-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c (UnpackWPGRaster): Fix some compilation and
+valgrind warnings.</li>
+<li>NEWS.txt: Updated news again.</li>
+</ul>
+</blockquote>
+<p>2014-12-31 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c Fixed 2bpp issue.</li>
+</ul>
+</blockquote>
+<p>2014-12-31 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Validate MHDR chunk length.</li>
+<li>coders/png.c: Use ReadBlob() once instead of ReadBlobByte()
+in a loop.</li>
+<li>coders/png.c: Avoid reading beyond the end of a tEXt keyword.</li>
+</ul>
+</blockquote>
+<p>2014-12-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xpm.c (ReadXPMImage): Detect short XPM rows and report
+error to user rather than overrunning a buffer.</li>
+<li>coders/pcx.c (ReadPCXImage): Validate that header bytes per line
+is sufficient to contain the indicated data.</li>
+<li>coders/pdb.c (ReadPDBImage): Fix indexes array overrun for 2 and
+4-bit PDB image files.</li>
+<li>coders/xpm.c (ReadXPMImage): Avoid strncpy() of overlapping
+memory. Fix memory leaks in error paths.</li>
+<li>coders/viff.c (ReadVIFFImage): Validate index before using it to
+access colormap.</li>
+<li>coders/{cineon.c, dpx.c} (StringToAttribute): Can't use
+strlcpy() to copy string which might not be NULL-terminated since
+strlcpy() continues searching for end of string after size bytes
+have been copied.</li>
+<li>coders/meta.c (convertHTMLcodes): Avoid strcpy() of overlapping
+memory.</li>
+</ul>
+</blockquote>
+<p>2014-12-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/process.rst: Update description of development process to be
+more aligned with the process actually used.</li>
+<li>coders/wpg.c (ReadWPGImage): Avoid use of NULL pointer returned
+from FlipImage(), FlopImage(), and RotateImage().</li>
+<li>coders/rle.c (ReadRLEImage): URT RLE reader is now more robust
+with errant files.</li>
+</ul>
+</blockquote>
+<p>2014-12-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libtool: Update bundled libtool to version 2.4.4.</li>
+<li>magick/constitute.c (WriteImage): Remove bogus use of
+GetBlobStatus() as a catch-all for write errors. Coders should be
+detecting write errors all by themselves.</li>
+</ul>
+</blockquote>
+<p>2014-12-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated with more improvements since previous release.</li>
+<li>coders/palm.c (WritePALMImage): Log header details.</li>
+<li>coders/pdb.c: PDB reader and writer need to be more robust when
+calculating packets and buffer allocation. Also log header
+details. Problem was reported by Hanno Böck.</li>
+</ul>
+</blockquote>
+<p>2014-12-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated with more improvements since previous release.</li>
+<li>ttf: Update bundled Freetype to 2.5.4.</li>
+<li>png: Update bundled libpng to 1.6.16.</li>
+</ul>
+</blockquote>
+<p>2014-12-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): The libtiff JBIG coder only
+supports strip images, and fails when scanlines are requested.
+Force use of stripped read method when the file uses JBIG
+compression. It is still not possible to write JBIG compressed
+TIFF files since there is not yet a strip writer. Problem
+reported by Yuriy Kaminskiyon via the GM-bugs mailing list on
+2014-12-22.</li>
+</ul>
+</blockquote>
+<p>2014-12-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (QuantumTransferMode): Fix quantum transfer
+handling for photometrics which might deliver one or three samples
+per pixel. These were assuming that three samples were always
+provided.</li>
+</ul>
+</blockquote>
+<p>2014-12-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Impose a 10-million limit on dimensions
+when reading a PNG file.</li>
+</ul>
+</blockquote>
+<p>2014-12-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated with improvements since previous release.</li>
+</ul>
+</blockquote>
+<p>2014-12-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/statistics.c (GetImageStatistics): Failed to compute
+statistics for the Black channel of CMYK image files. Problem
+reported by Michael Below via Debian bug 773552:
+&quot;graphicsmagick-imagemagick-compat: convert to cmyk leaves k
+channel empty&quot;.</li>
+</ul>
+</blockquote>
+<p>2014-12-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/delegate.c (InvokeDelegate): Windows spawnvp() splits
+arguments into more arguments. Add escaping to avoid the
+splitting. Resolves SourceForge bug #276 &quot;dcraw 9.19 included
+with gm 1.3.20 doesn't support paths with spaces.&quot;</li>
+<li>magick/utility.c (TranslateTextEx): Fix regression added on
+2014-12-13 (yesterday) which caused output file name passed to
+delegate programs to be wrong.</li>
+<li>magick/annotate.c (RenderFreetype): Fix regression added in
+1.3.19 which caused spurious drawing errors to be produced while
+rendering with text when all of the text is off the left-hand side
+of the image.</li>
+</ul>
+</blockquote>
+<p>2014-12-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (CompareUsage): Options should be listed in
+alphabetical order.</li>
+<li>magick/annotate.c (RenderFreetype): Immediately quit processing
+and return an error if SyncImagePixels() reports a problem.</li>
+<li>coders/psd.c (ReadPSDImage): Return with an error right away if
+SetImageEx() (to create solid-color background canvas) reports a
+failure.</li>
+<li>magick/annotate.c (AnnotateImage): Document all of the
+attributes which are supported.</li>
+<li>magick/utility.c (TranslateTextEx): Assure that attributes
+requiring ImageInfo pointer are skipped. AnnotateImage() does not
+pass ImageInfo. Also document all of the attributes which are
+supported.</li>
+<li>doc/compare.imdoc: Compare documentation examples referred to
+non-existing option -algorithm rather than the existing option
+-highlight-style. Fixes SourceForge bug #286 &quot;docs are wrong
+about <cite>-algorithm</cite> option of <cite>gm compare</cite>?&quot;.</li>
+<li>Magick++/lib/Magick++/Geometry.h (Magick): Re-implemented
+Magick++ Geometry to use bit-fields for booleans and used a union
+to reserve space for the future as well as to achieve the same
+size as in the previous release. Eliminated inline methods
+because they make it impossible to change the class internal
+design. ABI was broken already when limitPixels() and fillArea()
+methods were added on 2014-11-28. Inline method instantiations in
+already compiled applications will malfunction unless the
+dependent applications are re-compiled.</li>
+<li>magick/image.c (SetImageEx): Add a new version of SetImage()
+called SetImageEx() which reports exceptions to a provided
+exception parameter rather than into the image.</li>
+</ul>
+</blockquote>
+<p>2014-12-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colormap.c (AllocateImageColormap): Refuse to allocate a
+colormap larger than MaxColormapSize.</li>
+<li>coders/psd.c (ReadPSDImage): Avoid extremely long execution time
+if the PSD colormap size is astonishingly large. Problem was
+reported by Hanno Böck.</li>
+</ul>
+</blockquote>
+<p>2014-11-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dcm.c: Verify that DCM data is available before
+attempting to use it. Avoids a crash due to improper DCM header.
+Problem was reported by Hanno Böck.
+(DCM_ReadNonNativeImages): Fix array over-run (off by one error)
+while looking for end of multi-fragment frames.</li>
+</ul>
+</blockquote>
+<p>2014-11-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sun.c: Thoroughly validate Sun Rasterfile headers and
+verify that there are no arithmetic overflows in buffer-size
+calculations. Problem was reported by Hanno Böck.</li>
+</ul>
+</blockquote>
+<p>2014-11-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Magick++/Geometry.h (Magick::Geometry): Add and
+document limitPixels() and fillArea() methods to support '&#64;' and
+'^' geometry qualifiers. Fill area contributed by Long Ho and
+limitPixels() by Bob Friesenhahn.</li>
+<li>www/Magick++/Image.rst: Document extent and resize methods.</li>
+<li>Magick++/lib/STL.cpp (extentImage): New function object to
+invoke image extent method. Original implementation contributed by
+Long Ho. Subsequently modified by Bob Friesenhahn.
+(resizeImage): New function object to invoke image resize
+method. Contributed by Long Ho.</li>
+<li>Magick++/lib/Image.cpp (extent): New method to place image on
+sized canvas of constant color using gravity. Contributed by Long
+Ho.
+(resize): New method to resize image specifying geometry, filter,
+and blur. Original implementation contributed by Long Ho.
+Subsequently modified by Bob Friesenhahn.</li>
+</ul>
+</blockquote>
+<p>2014-11-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/avi.c: AVI support in GraphicsMagick is completely
+unusable and it could never compete with dedicated software like
+'ffmpeg'. Removing AVI support until such time it can be
+supported properly.</li>
+<li>coders/viff.c: Add protections against buffer overflow by
+verifying that buffer size allocation calculations do not
+overflow. Also added header logging for read and write. Work
+performed due to complaint by Hanno Böck.</li>
+</ul>
+</blockquote>
+<p>2014-11-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/common.h (MAGICK_NO_SANITIZE_ADDRESS): Add
+MAGICK_NO_SANITIZE_ADDRESS macro definition for disabling
+clang/GCC address sanitizer on a function if the need arises.</li>
+</ul>
+</blockquote>
+<p>2014-11-24 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadPNGImage): Do not attempt to clean up
+a &quot;previous&quot; NULL PNG image.</li>
+</ul>
+</blockquote>
+<p>2014-11-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xwd.c (ReadXWDImage): Add logging of XWD header values.
+Fix memory leaks in error reporting paths. Ping mode skips
+allocating memory for data and colormap. Added a few more header
+validation checks (not complete). XWD is put in
+UnstableCoderClass until such time as header validation checks are
+complete.</li>
+</ul>
+</blockquote>
+<p>2014-11-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdb.c (WritePDBImage): Use MagickAllocateArray() when
+allocating packets.</li>
+<li>coders/dpx.c (ReadDPXImage): Validate DPX header orientation and
+number of elements. Problem was reported by Hanno Böck.</li>
+</ul>
+</blockquote>
+<p>2014-11-20 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadJNGImage): Do not attempt to clean up
+a &quot;previous&quot; NULL JNG image.</li>
+</ul>
+</blockquote>
+<p>2014-11-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/FAQ.rst: Add a FAQ entry regarding what 'identify' reports.
+Resolves SF issue #280 &quot;Better documentation for spurious gm
+identify in Q8 compilation.&quot;</li>
+</ul>
+</blockquote>
+<p>2014-11-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enhance.c (ModulateImage): ModulateImage() should produce
+a progress indication even if only the colormap is modified.</li>
+</ul>
+</blockquote>
+<p>2014-11-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c (ReadPSDImage): Patch by Cédric Demière to fix
+&quot;Memory allocation failed&quot; error when reading PSDs files which
+have no layers. Delivered via SF patch #41 &quot;PSD : files without
+layers&quot;. Resolves SF bug #242 &quot;Can not convert PSD to JPG or PNG
+(gm convert: Memory allocation failed)&quot;.</li>
+</ul>
+</blockquote>
+<p>2014-11-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/webp.c (WriteWEBPImage): WebP fix by Roman Hiestand to
+make WebP lossless format truely lossless.</li>
+<li>tests/rwblob.tap (check_types): Added a test for WebP lossless.</li>
+<li>tests/rwfile.tap: Added a test for WebP lossless.</li>
+<li>tests/rwblob.c: Added support for -define.</li>
+<li>tests/rwfile.c: Added support for -define.</li>
+</ul>
+</blockquote>
+<p>2014-11-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>webp, VisualMagick/webp: Updated bundled WebP to 0.4.2 release.</li>
+</ul>
+</blockquote>
+<p>2014-11-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/tests/attributes.cpp: Add a simple test for
+Image::formatExpression().</li>
+<li>Magick++/lib/Image.cpp (formatExpression): Handle case where
+TranslateText() returns NULL. Problem was reported by Dirk
+Lemstra..</li>
+</ul>
+</blockquote>
+<p>2014-10-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Image.cpp (formatExpression): New method to format
+a string based on a format similar to command-line -format.
+Feature was requested by Dirk Lemstra.</li>
+<li>magick/blob.c (BlobReserveSize): Don't throw an exception if
+posix_fallocate() fails since it seems that it is not supported
+for all filesystem types, and is only intended for optimization.</li>
+<li>Magick++/lib/Image.cpp (resolutionUnits): Return resolution
+units from Image if available, else return the value from
+ImageInfo. Issue was reported by Dirk Lemstra.</li>
+</ul>
+</blockquote>
+<p>2014-10-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (ReadPNMImage): Validate PGM, PPM, and PAM header
+MaxValue parameter. Issue was reported by Hanno Böck.</li>
+<li>coders/pcx.c (ReadPCXImage): Fix for CVE-2014-8355, eliminate
+memory leaks in error paths, and add PCX header logging. Issue
+was reported by Hanno Böck.</li>
+</ul>
+</blockquote>
+<p>2014-10-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/wand_symbols.h (MagickSetImageGamma): Fix typo in
+wand/wand_symbols.h. Resolves SF bug #277.</li>
+</ul>
+</blockquote>
+<p>2014-10-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (TIFFIgnoreTags): Avoid warning about unused
+strtol() return value on Linux.</li>
+<li>magick/random-private.h (&quot;C&quot;): Move random inlined
+implementation bits to random-private.h, which is not installed,
+or used outside of the core C library.</li>
+</ul>
+</blockquote>
+<p>2014-09-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/annotate.c (AnnotateImage): An empty text string should
+not be treated as an error. Resolves Debian bug 759956.</li>
+</ul>
+</blockquote>
+<p>2014-08-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c: Added a new define called tiff:ignore-tags that
+can be used to ignore tags in 'corrupted' files with unknown and
+invalid tags. Without this patch the file cannot be read and
+raises an error. Patch by Dirk Lemstra via SF patches #40.</li>
+<li>magick/type.c (ReadTypeConfigureFile): Support reading type
+configuration file from Windows resource. Patch by Dirk Lemstra
+via SF patches #32.</li>
+<li>Magick++/lib/Magick++/STL.h: Fixed code analysis warning in
+STL.h. Patch by Dirk Lemstra via SF patches #32.</li>
+<li>Magick++/lib/Magick++/Include.h: Autolink WebP in Visual
+Studio. Patch by Dirk Lemstra via SF patches #32.</li>
+</ul>
+</blockquote>
+<p>2014-08-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c (WritePSDImage): Fix small stack over-write if more
+than 99 layers are written to PSD format. Similar to
+CVE-2014-1947 for ImageMagick. Changed layer naming to use at
+least 4 digits. Issue was brought to our attention by Rex Dieter
+and change is mostly based on his patch.</li>
+</ul>
+</blockquote>
+<p>2014-08-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/enum_strings.c (StringToCompositeOperator): Support
+composite operator names similar to the major brand, without
+losing any compatibility with previous naming.</li>
+</ul>
+</blockquote>
+<dl class="docutils">
+<dt>2014-08-23 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</dt>
+<dd><ul class="first last simple">
+<li>coders/png.c: Fixed handling of transparency when writing
+indexed PNG. Reference: SourceForge Bug tracker [bugs:#267]
+Transparency lost when converting from GIF to PNG.</li>
+</ul>
+</dd>
+</dl>
+<p>2014-08-17 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagickconfigureconfigure.cpp Remove webp when attempting
+to compile with Visual Studio 6.</li>
+</ul>
+</blockquote>
+<p>2014-08-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Update for 1.3.20 release.</li>
+<li>www/index.rst: Update for 1.3.20 release.</li>
+<li>version.sh: Update library versioning for next release.</li>
+</ul>
+</blockquote>
+<p>2014-08-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>png: Updated libpng to 1.6.12 release.</li>
+<li>zlib: Updated zlib to 1.2.8 release.</li>
+</ul>
+</blockquote>
+<p>2014-08-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated NEWS file to document changes since previous
+release.</li>
+</ul>
+</blockquote>
+<p>2014-08-09 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+* coders/webp.c webp cannot be compiled when HasWEBP is not set.</blockquote>
+<p>2014-08-08 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Eliminated palette and depth optimization (see
+<a class="reference external" href="https://sourceforge.net/p/graphicsmagick/feature-requests/35/">https://sourceforge.net/p/graphicsmagick/feature-requests/35/</a>).</li>
+</ul>
+</blockquote>
+<p>2014-08-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>dcraw/dcraw.c: Fix dcraw build for x64 target when only WIN64 is
+defined (by also defining WIN32).</li>
+<li>VisualMagick/configure/configure.cpp (write_file): Fix problem
+with x64 project naming which caused object file disambiguation
+not to work for x64 target. Make line terminations consistent.</li>
+</ul>
+</blockquote>
+<p>2014-08-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick: VisualMagick fixes by Dirk Lemstra to improve
+configure program so that it is possible to select QuantumDepth,
+OpenMP, and 64-bit build via configure dialog boxes as well as
+options on the command line. Also automatically detects and deals
+with similarly named files in subdirectories so that WebP support
+can now build successfully. Resolves SF patches 31, 33, 35, 37,
+and 38.</li>
+</ul>
+</blockquote>
+<p>2014-07-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (NTResourceToBlob): Support loading mgk files
+as Windows resource from library if MagickLibName is defined.
+Patch contributed by Dirk Lemstra via SF patch #32.
+(NTGhostscriptDLL): For Microsoft Windows, add support for a
+MAGICK_GHOSTSCRIPT_PATH environment variable which specifies the
+path to Ghostscript. If this environment variable is defined,
+then the Windows registry is not used to find Ghostscript. Patch
+contributed by Dirk Lemstra via SF patch #39.</li>
+<li>magick/log.c: Added SetLogMethod() to allow an
+application/library to specify a function to be called for
+logging. Patch contributed by Dirk Lemstra.</li>
+</ul>
+</blockquote>
+<p>2014-07-20 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c: &quot;opacity&quot; read from a BMP3 is actually &quot;alpha&quot;,
+so store q-&gt;opacity=MaxRGB-opacity instead of q-&gt;opacity=opacity.
+Reference: Bug tracker [bugs:#271] Blank result for BMP resize.</li>
+</ul>
+</blockquote>
+<p>2014-07-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>webp, VisualMagick/webp: Integrate webp 0.4.0 into windows
+build. May require manual renaming of output object files in
+project files to build webp until VisualMagick configure is
+improved!</li>
+</ul>
+</blockquote>
+<p>2014-07-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c: fmin() and fmax() are defined by C'99 and
+not available everywhere, so add and use MagickFmin() and
+MagickFmax() to improve portability.</li>
+</ul>
+</blockquote>
+<p>2014-07-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Magick++/Image.h (Magick): Fix complilation errors
+caused by continued raw use of __attribute__.</li>
+</ul>
+</blockquote>
+<p>2014-06-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c: Fixes by Brendan Lane for color channel
+overflows in modified/new quantum operators. Fixes test suite
+results for Q32 build and makes LinearBurn and LinearDodge work
+correctly at all.</li>
+<li>wand/pixel_wand.c (PixelSetMagenta): Fix documentation.
+Resolves SourceForge bug #273 'Green Magenta' typo in docs.</li>
+</ul>
+</blockquote>
+<p>2014-06-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c: Composition improvements and additions
+contributed by Brendan Lane via SourceForge patch #34 &quot;Most of the
+missing Photoshop separable compositing operations&quot;
+(<a class="reference external" href="https://sourceforge.net/p/graphicsmagick/patches/34/">https://sourceforge.net/p/graphicsmagick/patches/34/</a>). These
+composition operators were modified to include alpha in their
+computations: Difference, Darken, Lighten, HardLight, and these
+operators were added Overlay, Exclusion, ColorBurn, ColorDodge,
+SoftLight, LinearBurn, LinearDodge, LinearLight, VividLight,
+PinLight, HardMix.</li>
+</ul>
+</blockquote>
+<p>2014-06-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c (ScreenCompositePixels): Implementation of
+Screen composite contributed by Brendan Lane. SourceForge patch
+#30 &quot;Missing Screen composite operation&quot;.</li>
+<li>wand/magick_compat.c: Re-worked Wand library implementation to
+depend directly on GraphicsMagick library functionality rather
+than using ImageMagick shim code from magick_compat.c and
+magick_compat.h. The magick_compat.c source module becomes &quot;dead
+code&quot;, which remains only to support the existing ABI, and will be
+deleted at the next major ABI break point.</li>
+<li>magick/utility.c (MagickFormatString): New private function to
+format a string into a buffer with a specified size. Same as
+previously existing FormatString() except requires a length
+argument.</li>
+</ul>
+</blockquote>
+<p>2014-06-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_compat.h: Use MAGICK_ATTRIBUTE definition from
+magick/common.h.</li>
+<li>magick/common.h (MAGICK_ATTRIBUTE): Don't undefine __attribute__
+since this may be used by system or compiler headers. Define
+private macro instead. Resolves SourceForge bug #270 &quot;Compile
+error with g++ -std=c++11&quot;.</li>
+</ul>
+</blockquote>
+<p>2014-06-06 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): Free png_pixels and
+quantum_scanline before error return. Use &quot;png_error()&quot;
+instead of &quot;ThrowException2()&quot; for errors occuring while
+decoding a PNG so proper cleanup will happen.</li>
+</ul>
+</blockquote>
+<p>2014-06-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Make sure that libtiff warnings
+are promoted to errors for critical tags.</li>
+</ul>
+</blockquote>
+<p>2014-06-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Be quite a lot more draconian
+when retrieving the baseline standard TIFF tags we need in order
+to avoid consuming uninitalized data later. An error with these
+tags will result in failure to read the image file.</li>
+</ul>
+</blockquote>
+<p>2014-05-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/operator.c: Decided that ThresholdBlackNegateQuantumOp
+and ThresholdWhiteNegateQuantumOp should set the result to white
+or black respectively rather than being based on subtraction.</li>
+</ul>
+</blockquote>
+<p>2014-05-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (AUTOMAKE_OPTIONS): Be ultra-pedantic with CPPFLAGS
+and include paths in order to assure that only required
+directories are supplied, and to avoid accidential collision with
+system header files.</li>
+</ul>
+</blockquote>
+<p>2014-05-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/operator.h (&quot;C&quot;): New quantum operators
+ThresholdBlackNegateQuantumOp and ThresholdWhiteNegateQuantumOp.
+These correspond to -operator &quot;Threshold-Black-Negate&quot; and
+&quot;Threshold-White-Negate&quot;.</li>
+</ul>
+</blockquote>
+<p>2014-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/composite.c (MultiplyCompositePixels): Multiply
+composition now uses SVG interpretation of how alpha should be
+handled. No longer does a simple multiply of alpha channel.
+Behavior change. Patch contributed by Sara Shafaei.</li>
+<li>coders/msl.c (ProcessMSLScript): Deal with case where
+image_info-&gt;attributes is NULL.</li>
+</ul>
+</blockquote>
+<p>2014-04-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (TranslateTextEx): Support additional format
+specifiers 'g', 'A', 'C', 'D', 'G', 'H', 'M', 'O', 'P', 'Q', 'T',
+'U', 'W', 'X', and '&#64;'.
+(GetMagickGeometry): Support '&gt;' and '&lt;' qualifiers with '&#64;'
+qualifier to specify if image should be resized if larger or
+lesser than given area specification. Resolves SourceForge bug
+#216 &quot;&gt;&quot; wont take effect when use &#64; to specify the maximum area.</li>
+<li>magick/transform.c (GetImageMosaicDimensions): Move mosaic
+dimensions code to a static function for possible future re-use.</li>
+</ul>
+</blockquote>
+<p>2014-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/gradient.c (GradientImage): Update image is_grayscale and
+is_monochrome flags based on gradient color properties.</li>
+</ul>
+</blockquote>
+<p>2014-04-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetMagickGeometry): Deal with resize geometry
+missing width or height (e.g. '640x' or 'x480') by substituting
+the missing value with one which preserves the image aspect ratio.
+This has been documented to be supported since almost the dawn of
+GraphicsMagick but was not actually supported until now.</li>
+</ul>
+</blockquote>
+<p>2014-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Document WebP encoder options.</li>
+<li>coders/webp.c (WriteWEBPImage): Support all of the WebP encoder
+options via -define arguments. Most of this work is contributed
+by Roman Hiestand.</li>
+<li>configure.ac: User-provided LIBS should be prepended to LIBS
+that configure script produces so that user option takes
+precedence.</li>
+</ul>
+</blockquote>
+<p>2014-04-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/Magick.xs: Added support for HardLight composition
+operator.</li>
+<li>www/perl.rst: Update PerlMagick documentation, including the
+composition operators.</li>
+<li>coders/xcf.c (GIMPBlendModeToCompositeOperator): Use new
+HardLight composition operator to support XCF GIMP_HARDLIGHT_MODE
+blend mode. Contributed by Sara Shafaei.</li>
+<li>coders/psd.c (CompositeOperatorToPSDBlendMode): Use new
+HardLight composition operator to support PSD &quot;hLit&quot; blend mode.
+Contributed by Sara Shafaei.</li>
+<li>wand/magick_wand.c (MagickOperatorImageChannel): New function to
+apply an operator to an image channel. Contributed by Sara
+Shafaei.</li>
+<li>magick/composite.c (HardLightCompositePixels): New HardLight
+composition operator. Contributed by Sara Shafaei.</li>
+</ul>
+</blockquote>
+<p>2014-04-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (BenchmarkImageCommand): Add a CSV title line
+and quoting to benchmark -rawcsv output.</li>
+</ul>
+</blockquote>
+<p>2014-04-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/webp.c: Add progress indication support to WebP writer.</li>
+<li>magick/command.c (VersionCommand): WebP support is included in
+-version output.</li>
+<li>coders/webp.c: WebP coder identifies library version and header
+ABI versions. Improve WebP error reporting.</li>
+</ul>
+</blockquote>
+<p>2014-04-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Allow specifying the TIFF image
+software tag. In the special case that the string length is zero
+(e.g. -set software '') then the tag is skipped entirely. This is
+to support SourceForge feature request #37 &quot;Option to prevent
+addition of Exif Software tag&quot; opened by Jean-Louis Grall. Please
+note that this tag is not an EXIF tag.</li>
+<li>magick/command.c: composite, convert, display, mogrify, and
+import now support +set to remove an existing image attribute.</li>
+</ul>
+</blockquote>
+<p>2014-03-16 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Don't block threads when PNG_SETJMP_SUPPORTED is
+not enabled.</li>
+<li>coders/png.c: Changed prefix of macros defined in coders/png.c
+from PNG_ to GMPNG_. PNG_ is reserved for macros defined by
+libpng.</li>
+</ul>
+</blockquote>
+<p>2014-03-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c: Don't use setvbuf() to set stdio block size if
+filesystem block size is zero (e.g. MAGICK_IOBUF_SIZE=0)</li>
+</ul>
+</blockquote>
+<p>2014-03-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/{rwblob.tap, rwfile.tap}: Added tests for WEBP.</li>
+<li>tests/{rwblob.c, rwfile.c}: Add lossy hint for WEBP.</li>
+<li>coders/webp.c (WriteWEBPImage): Fix inverted return status.
+Added a tiny bit of logging.</li>
+</ul>
+</blockquote>
+<p>2014-03-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ttf: Updated FreeType to release 2.5.3 of March 6, 2014.
+Provides security fixes for CVE-2014-2240.</li>
+<li>jpeg: Update to libjpeg 9a of 19-Jan-2014.</li>
+<li>png: Update to Libpng 1.6.10 - March 6, 2014.</li>
+</ul>
+</blockquote>
+<p>2014-03-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (NTResourceToBlob): According to Microsoft
+Report article 193678 (<a class="reference external" href="http://support.microsoft.com/kb/193678">http://support.microsoft.com/kb/193678</a>),
+FreeResource() is not needed in WIN32 and performs no useful
+function. Remove use of it. Also remove use of UnlockResource()
+which is similarly unuseful for WIN32.</li>
+<li>configure.ac (MAGICK_LIBRARY_REVISION): Test for Windows
+_aligned_malloc() is not reliable. Use Windows CRT version to
+decide if it is available.</li>
+</ul>
+</blockquote>
+<p>2014-03-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h: Make sure that Windows _aligned_malloc() is not
+used under MinGW unless the CRT version allows it.</li>
+</ul>
+</blockquote>
+<p>2014-02-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (InterpolateViewColor): Applied patch by
+Troy Patteson plus fixes to ignore opacity channel if image matte
+is false. Replaces most of the code rewritten on 2014-02-16 and
+which produced a faint darkened border. The results look stellar
+now.</li>
+</ul>
+</blockquote>
+<p>2014-02-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/shear.c: Applied patch by Troy Patteson to improve
+non-integral rotation by around 40% by minimizing added image
+borders. This may cause small differences in results for some
+images.</li>
+<li>reference/filter/Rotate10.miff: Update rotate 10 degrees
+reference image so that PerlMagick test passes.</li>
+<li>magick/shear.c: Applied patch by Troy Patteson to fix
+SourceForge issue #260 &quot;Rotation exhibits clipping/shearing errors
+for short wide images at some angles&quot;.</li>
+</ul>
+</blockquote>
+<p>2014-02-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc: Fix documentation to note that 'unspecified
+alpha' is the GraphicsMagick default when writing TIFF rather than
+'associated alpha'. Much thanks to Mats Peterson for alerting us
+of this error.</li>
+</ul>
+</blockquote>
+<p>2014-02-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (InterpolateViewColor): Added a hack so that
+affine transformations and displace composite do not have
+background colored fringing on the transferred image edges when
+the background is completely transparent. Fringing problem was
+caused by one or more of the line ends being a transparent pixel
+outside of the bounds of the original image content. May not be
+the final solution.</li>
+</ul>
+</blockquote>
+<p>2014-02-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/semaphore.c (AcquireSemaphoreInfo): Document that this
+function was deprecated.
+(LiberateSemaphoreInfo): Document that this function was
+deprecated.</li>
+</ul>
+</blockquote>
+<p>2014-02-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c (RegisterPSDImage): Set PSD to UnstableCoderClass
+since its implementation is currently rather marginal. It may
+even be that this coder deserves to be marked with the new
+BrokenCoderClass. We are still looking for a volunteer to iron
+out the wrinkles in the PSD reader.</li>
+<li>magick/magick.h (CoderClass): Added BrokenCoderClass to mark
+coders which often malfunction or are not very useful in their
+current condition. Sometimes there is still hope that problems
+will be resolved and so the source file is not outright deleted.
+This setting allows us to mark and use coders which might
+malfunction by defining MAGICK_CODER_STABILITY=BROKEN in the
+environment while not causing danger for normal use.</li>
+</ul>
+</blockquote>
+<p>2014-02-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c: Documentation improvements for
+MagickSetInterlaceScheme() and MagickSetImageInterlaceScheme().
+Resolves SourceForge bug #262 &quot;setImageInterlaceScheme doesn't
+make image progressive&quot;.</li>
+</ul>
+</blockquote>
+<p>2014-02-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/{ps.c, ps2.c, ps3.c, pdf.c}: Only use resolution from
+image or -density if units was properly specified. Without units,
+resolution is worthless.</li>
+<li>coders/ps3.c (WritePS3Image): Use image resolution similar to PDF
+changes.</li>
+<li>coders/ps2.c (WritePS2Image): Use image resolution similar to PDF
+changes.</li>
+<li>coders/ps.c (WritePSImage): Use image resolution similar to PDF
+changes.</li>
+<li>coders/pdf.c (WritePDFImage): Use resolution from image if it
+appears to be valid. Resolves SourceForge issue #261 &quot;PNG Pixel
+Density Not Preserved Converting to PDF&quot;.</li>
+<li>magick/enum_strings.c (StringToResolutionType): New function to
+convert ResolutionType to C string.
+(ResolutionTypeToString): New function to convert from C string to
+ResolutionType.</li>
+</ul>
+</blockquote>
+<p>2014-02-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickGetImageGeometry): New function to get
+the image geometry string. This function and the three others in
+this change set are contributed by Sara Shafaei.
+(MagickGetImageMatte): New function to read the image matte
+(opacity) channel enable flag.
+(MagickSetImageGeometry): New function to set the image geometry
+string.
+(MagickSetImageMatte): New function to set the image matte
+(opacity) channel enable flag.</li>
+</ul>
+</blockquote>
+<p>2014-01-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.c (MagickDrawImage): Remove development debug
+fprintf which causes each drawing primitive to be printed to
+stderr.</li>
+</ul>
+</blockquote>
+<p>2014-01-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (ReadPNMImage): Fix scaling of alpha in sub-ranged
+pixels. Addresses SourceForge issue #237 &quot;Incorrect MAXVAL
+scaling when reading PAM images&quot;, which was not fully fixed in by
+the previous attempt.</li>
+</ul>
+</blockquote>
+<p>2014-01-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/tsd.c: Implement TSD for &quot;pure&quot; OpenMP mode without
+relying on POSIX or WIN32 TSD APIs.</li>
+<li>magick/semaphore.c: Implement OpenMP-based locking so that code
+can compile in a &quot;pure&quot; OpenMP mode without relying on POSIX or
+WIN32 locking APIs.</li>
+<li>configure.ac: --without-threads no longer disables use of
+OpenMP. Use the already existing option --disable-openmp to
+disable OpenMP.</li>
+</ul>
+</blockquote>
+<p>2014-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/common.h: Support use of clang/llvm __attribute__ and
+__builtin extensions similar to the existing support for GCC.</li>
+</ul>
+</blockquote>
+<p>2014-01-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Image.cpp (thumbnail): New method for fast image
+resizing, particularly to make thumbnails.</li>
+<li>coders/gif.c: Log when Netscape loop exension is read and
+written.</li>
+<li>coders/png.c (WriteOnePNGImage): In optimize mode, disable matte
+channel immediately if there are no non-opaque pixels. Also added
+some useful logging. Resolves SourceForge issue #252 &quot;convert an
+8bit PNG result in a corrupted image &quot;.</li>
+<li>wand/magick_wand.c (MagickSetImageGravity): New Wand method to
+set image gravity.
+(MagickGetImageGravity): New wand method to get image gravity.</li>
+</ul>
+</blockquote>
+<p>2014-01-02 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): Use libpng function
+png_set_strip_16_to_8() when scaling 16-bit input PNG down to
+8-bit in a Q8 build. The png_set_scale_16_to_8() function is
+more accurate, but the slight difference causes reference tests
+to fail and causes unexpected difference between the behavior
+of PNG and other formats. If png_set_strip_16_to_8() is not
+supported in libpng, then we use png_set_scale_16_to_8() if
+that is available.</li>
+</ul>
+</blockquote>
+<p>2014-01-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>INSTALL-windows.txt: Update for 2014.</li>
+<li>INSTALL-unix.txt: Update for 2014.</li>
+<li>Copyright.txt: Update for 2014.</li>
+<li>NEWS.txt: Update for 2014.</li>
+<li>README.txt: Update for 2014.</li>
+<li>doc: Update for 2014.</li>
+<li>www: Update for 2014.</li>
+<li>VisualMagick/installer: Update for 2014.</li>
+<li>ChangeLog: Rotate Changelog to ChangeLog.2013 for 2014.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2014.rst b/www/ChangeLog-2014.rst
new file mode 100644
index 0000000..eb78a33
--- /dev/null
+++ b/www/ChangeLog-2014.rst
@@ -0,0 +1,895 @@
+2014-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wpg.c (UnpackWPGRaster): Fix some compilation and
+ valgrind warnings.
+
+ - NEWS.txt: Updated news again.
+
+2014-12-31 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/wpg.c Fixed 2bpp issue.
+
+2014-12-31 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Validate MHDR chunk length.
+
+ - coders/png.c: Use ReadBlob() once instead of ReadBlobByte()
+ in a loop.
+
+ - coders/png.c: Avoid reading beyond the end of a tEXt keyword.
+
+2014-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xpm.c (ReadXPMImage): Detect short XPM rows and report
+ error to user rather than overrunning a buffer.
+
+ - coders/pcx.c (ReadPCXImage): Validate that header bytes per line
+ is sufficient to contain the indicated data.
+
+ - coders/pdb.c (ReadPDBImage): Fix indexes array overrun for 2 and
+ 4-bit PDB image files.
+
+ - coders/xpm.c (ReadXPMImage): Avoid strncpy() of overlapping
+ memory. Fix memory leaks in error paths.
+
+ - coders/viff.c (ReadVIFFImage): Validate index before using it to
+ access colormap.
+
+ - coders/{cineon.c, dpx.c} (StringToAttribute): Can't use
+ strlcpy() to copy string which might not be NULL-terminated since
+ strlcpy() continues searching for end of string after size bytes
+ have been copied.
+
+ - coders/meta.c (convertHTMLcodes): Avoid strcpy() of overlapping
+ memory.
+
+2014-12-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/process.rst: Update description of development process to be
+ more aligned with the process actually used.
+
+ - coders/wpg.c (ReadWPGImage): Avoid use of NULL pointer returned
+ from FlipImage(), FlopImage(), and RotateImage().
+
+ - coders/rle.c (ReadRLEImage): URT RLE reader is now more robust
+ with errant files.
+
+2014-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libtool: Update bundled libtool to version 2.4.4.
+
+ - magick/constitute.c (WriteImage): Remove bogus use of
+ GetBlobStatus() as a catch-all for write errors. Coders should be
+ detecting write errors all by themselves.
+
+2014-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated with more improvements since previous release.
+
+ - coders/palm.c (WritePALMImage): Log header details.
+
+ - coders/pdb.c: PDB reader and writer need to be more robust when
+ calculating packets and buffer allocation. Also log header
+ details. Problem was reported by Hanno Böck.
+
+2014-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated with more improvements since previous release.
+
+ - ttf: Update bundled Freetype to 2.5.4.
+
+ - png: Update bundled libpng to 1.6.16.
+
+2014-12-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): The libtiff JBIG coder only
+ supports strip images, and fails when scanlines are requested.
+ Force use of stripped read method when the file uses JBIG
+ compression. It is still not possible to write JBIG compressed
+ TIFF files since there is not yet a strip writer. Problem
+ reported by Yuriy Kaminskiyon via the GM-bugs mailing list on
+ 2014-12-22.
+
+2014-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (QuantumTransferMode): Fix quantum transfer
+ handling for photometrics which might deliver one or three samples
+ per pixel. These were assuming that three samples were always
+ provided.
+
+2014-12-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Impose a 10-million limit on dimensions
+ when reading a PNG file.
+
+2014-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated with improvements since previous release.
+
+2014-12-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/statistics.c (GetImageStatistics): Failed to compute
+ statistics for the Black channel of CMYK image files. Problem
+ reported by Michael Below via Debian bug 773552:
+ "graphicsmagick-imagemagick-compat: convert to cmyk leaves k
+ channel empty".
+
+2014-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/delegate.c (InvokeDelegate): Windows spawnvp() splits
+ arguments into more arguments. Add escaping to avoid the
+ splitting. Resolves SourceForge bug #276 "dcraw 9.19 included
+ with gm 1.3.20 doesn't support paths with spaces."
+
+ - magick/utility.c (TranslateTextEx): Fix regression added on
+ 2014-12-13 (yesterday) which caused output file name passed to
+ delegate programs to be wrong.
+
+ - magick/annotate.c (RenderFreetype): Fix regression added in
+ 1.3.19 which caused spurious drawing errors to be produced while
+ rendering with text when all of the text is off the left-hand side
+ of the image.
+
+2014-12-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (CompareUsage): Options should be listed in
+ alphabetical order.
+
+ - magick/annotate.c (RenderFreetype): Immediately quit processing
+ and return an error if SyncImagePixels() reports a problem.
+
+ - coders/psd.c (ReadPSDImage): Return with an error right away if
+ SetImageEx() (to create solid-color background canvas) reports a
+ failure.
+
+ - magick/annotate.c (AnnotateImage): Document all of the
+ attributes which are supported.
+
+ - magick/utility.c (TranslateTextEx): Assure that attributes
+ requiring ImageInfo pointer are skipped. AnnotateImage() does not
+ pass ImageInfo. Also document all of the attributes which are
+ supported.
+
+ - doc/compare.imdoc: Compare documentation examples referred to
+ non-existing option -algorithm rather than the existing option
+ -highlight-style. Fixes SourceForge bug #286 "docs are wrong
+ about `-algorithm` option of `gm compare`?".
+
+ - Magick++/lib/Magick++/Geometry.h (Magick): Re-implemented
+ Magick++ Geometry to use bit-fields for booleans and used a union
+ to reserve space for the future as well as to achieve the same
+ size as in the previous release. Eliminated inline methods
+ because they make it impossible to change the class internal
+ design. ABI was broken already when limitPixels() and fillArea()
+ methods were added on 2014-11-28. Inline method instantiations in
+ already compiled applications will malfunction unless the
+ dependent applications are re-compiled.
+
+ - magick/image.c (SetImageEx): Add a new version of SetImage()
+ called SetImageEx() which reports exceptions to a provided
+ exception parameter rather than into the image.
+
+2014-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colormap.c (AllocateImageColormap): Refuse to allocate a
+ colormap larger than MaxColormapSize.
+
+ - coders/psd.c (ReadPSDImage): Avoid extremely long execution time
+ if the PSD colormap size is astonishingly large. Problem was
+ reported by Hanno Böck.
+
+2014-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dcm.c: Verify that DCM data is available before
+ attempting to use it. Avoids a crash due to improper DCM header.
+ Problem was reported by Hanno Böck.
+ (DCM\_ReadNonNativeImages): Fix array over-run (off by one error)
+ while looking for end of multi-fragment frames.
+
+2014-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sun.c: Thoroughly validate Sun Rasterfile headers and
+ verify that there are no arithmetic overflows in buffer-size
+ calculations. Problem was reported by Hanno Böck.
+
+2014-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Magick++/Geometry.h (Magick::Geometry): Add and
+ document limitPixels() and fillArea() methods to support '@' and
+ '^' geometry qualifiers. Fill area contributed by Long Ho and
+ limitPixels() by Bob Friesenhahn.
+
+ - www/Magick++/Image.rst: Document extent and resize methods.
+
+ - Magick++/lib/STL.cpp (extentImage): New function object to
+ invoke image extent method. Original implementation contributed by
+ Long Ho. Subsequently modified by Bob Friesenhahn.
+ (resizeImage): New function object to invoke image resize
+ method. Contributed by Long Ho.
+
+ - Magick++/lib/Image.cpp (extent): New method to place image on
+ sized canvas of constant color using gravity. Contributed by Long
+ Ho.
+ (resize): New method to resize image specifying geometry, filter,
+ and blur. Original implementation contributed by Long Ho.
+ Subsequently modified by Bob Friesenhahn.
+
+2014-11-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/avi.c: AVI support in GraphicsMagick is completely
+ unusable and it could never compete with dedicated software like
+ 'ffmpeg'. Removing AVI support until such time it can be
+ supported properly.
+
+ - coders/viff.c: Add protections against buffer overflow by
+ verifying that buffer size allocation calculations do not
+ overflow. Also added header logging for read and write. Work
+ performed due to complaint by Hanno Böck.
+
+2014-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/common.h (MAGICK\_NO\_SANITIZE\_ADDRESS): Add
+ MAGICK\_NO\_SANITIZE\_ADDRESS macro definition for disabling
+ clang/GCC address sanitizer on a function if the need arises.
+
+2014-11-24 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadPNGImage): Do not attempt to clean up
+ a "previous" NULL PNG image.
+
+2014-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xwd.c (ReadXWDImage): Add logging of XWD header values.
+ Fix memory leaks in error reporting paths. Ping mode skips
+ allocating memory for data and colormap. Added a few more header
+ validation checks (not complete). XWD is put in
+ UnstableCoderClass until such time as header validation checks are
+ complete.
+
+2014-11-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdb.c (WritePDBImage): Use MagickAllocateArray() when
+ allocating packets.
+
+ - coders/dpx.c (ReadDPXImage): Validate DPX header orientation and
+ number of elements. Problem was reported by Hanno Böck.
+
+2014-11-20 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadJNGImage): Do not attempt to clean up
+ a "previous" NULL JNG image.
+
+2014-11-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/FAQ.rst: Add a FAQ entry regarding what 'identify' reports.
+ Resolves SF issue #280 "Better documentation for spurious gm
+ identify in Q8 compilation."
+
+2014-11-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/enhance.c (ModulateImage): ModulateImage() should produce
+ a progress indication even if only the colormap is modified.
+
+2014-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/psd.c (ReadPSDImage): Patch by Cédric Demière to fix
+ "Memory allocation failed" error when reading PSDs files which
+ have no layers. Delivered via SF patch #41 "PSD : files without
+ layers". Resolves SF bug #242 "Can not convert PSD to JPG or PNG
+ (gm convert: Memory allocation failed)".
+
+2014-11-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/webp.c (WriteWEBPImage): WebP fix by Roman Hiestand to
+ make WebP lossless format truely lossless.
+
+ - tests/rwblob.tap (check\_types): Added a test for WebP lossless.
+
+ - tests/rwfile.tap: Added a test for WebP lossless.
+
+ - tests/rwblob.c: Added support for -define.
+
+ - tests/rwfile.c: Added support for -define.
+
+2014-11-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - webp, VisualMagick/webp: Updated bundled WebP to 0.4.2 release.
+
+2014-11-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/tests/attributes.cpp: Add a simple test for
+ Image::formatExpression().
+
+ - Magick++/lib/Image.cpp (formatExpression): Handle case where
+ TranslateText() returns NULL. Problem was reported by Dirk
+ Lemstra..
+
+2014-10-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Image.cpp (formatExpression): New method to format
+ a string based on a format similar to command-line -format.
+ Feature was requested by Dirk Lemstra.
+
+ - magick/blob.c (BlobReserveSize): Don't throw an exception if
+ posix\_fallocate() fails since it seems that it is not supported
+ for all filesystem types, and is only intended for optimization.
+
+ - Magick++/lib/Image.cpp (resolutionUnits): Return resolution
+ units from Image if available, else return the value from
+ ImageInfo. Issue was reported by Dirk Lemstra.
+
+2014-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (ReadPNMImage): Validate PGM, PPM, and PAM header
+ MaxValue parameter. Issue was reported by Hanno Böck.
+
+ - coders/pcx.c (ReadPCXImage): Fix for CVE-2014-8355, eliminate
+ memory leaks in error paths, and add PCX header logging. Issue
+ was reported by Hanno Böck.
+
+2014-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/wand\_symbols.h (MagickSetImageGamma): Fix typo in
+ wand/wand\_symbols.h. Resolves SF bug #277.
+
+2014-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (TIFFIgnoreTags): Avoid warning about unused
+ strtol() return value on Linux.
+
+ - magick/random-private.h ("C"): Move random inlined
+ implementation bits to random-private.h, which is not installed,
+ or used outside of the core C library.
+
+2014-09-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/annotate.c (AnnotateImage): An empty text string should
+ not be treated as an error. Resolves Debian bug 759956.
+
+2014-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c: Added a new define called tiff:ignore-tags that
+ can be used to ignore tags in 'corrupted' files with unknown and
+ invalid tags. Without this patch the file cannot be read and
+ raises an error. Patch by Dirk Lemstra via SF patches #40.
+
+ - magick/type.c (ReadTypeConfigureFile): Support reading type
+ configuration file from Windows resource. Patch by Dirk Lemstra
+ via SF patches #32.
+
+ - Magick++/lib/Magick++/STL.h: Fixed code analysis warning in
+ STL.h. Patch by Dirk Lemstra via SF patches #32.
+
+ - Magick++/lib/Magick++/Include.h: Autolink WebP in Visual
+ Studio. Patch by Dirk Lemstra via SF patches #32.
+
+2014-08-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/psd.c (WritePSDImage): Fix small stack over-write if more
+ than 99 layers are written to PSD format. Similar to
+ CVE-2014-1947 for ImageMagick. Changed layer naming to use at
+ least 4 digits. Issue was brought to our attention by Rex Dieter
+ and change is mostly based on his patch.
+
+2014-08-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/enum\_strings.c (StringToCompositeOperator): Support
+ composite operator names similar to the major brand, without
+ losing any compatibility with previous naming.
+
+2014-08-23 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+ - coders/png.c: Fixed handling of transparency when writing
+ indexed PNG. Reference: SourceForge Bug tracker [bugs:#267]
+ Transparency lost when converting from GIF to PNG.
+
+2014-08-17 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ - VisualMagick\configure\configure.cpp Remove webp when attempting
+ to compile with Visual Studio 6.
+
+2014-08-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Update for 1.3.20 release.
+
+ - www/index.rst: Update for 1.3.20 release.
+
+ - version.sh: Update library versioning for next release.
+
+2014-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - png: Updated libpng to 1.6.12 release.
+
+ - zlib: Updated zlib to 1.2.8 release.
+
+2014-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated NEWS file to document changes since previous
+ release.
+
+2014-08-09 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ \* coders/webp.c webp cannot be compiled when HasWEBP is not set.
+
+2014-08-08 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Eliminated palette and depth optimization (see
+ https://sourceforge.net/p/graphicsmagick/feature-requests/35/).
+
+2014-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - dcraw/dcraw.c: Fix dcraw build for x64 target when only WIN64 is
+ defined (by also defining WIN32).
+
+ - VisualMagick/configure/configure.cpp (write\_file): Fix problem
+ with x64 project naming which caused object file disambiguation
+ not to work for x64 target. Make line terminations consistent.
+
+2014-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick: VisualMagick fixes by Dirk Lemstra to improve
+ configure program so that it is possible to select QuantumDepth,
+ OpenMP, and 64-bit build via configure dialog boxes as well as
+ options on the command line. Also automatically detects and deals
+ with similarly named files in subdirectories so that WebP support
+ can now build successfully. Resolves SF patches 31, 33, 35, 37,
+ and 38.
+
+2014-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (NTResourceToBlob): Support loading mgk files
+ as Windows resource from library if MagickLibName is defined.
+ Patch contributed by Dirk Lemstra via SF patch #32.
+ (NTGhostscriptDLL): For Microsoft Windows, add support for a
+ MAGICK\_GHOSTSCRIPT\_PATH environment variable which specifies the
+ path to Ghostscript. If this environment variable is defined,
+ then the Windows registry is not used to find Ghostscript. Patch
+ contributed by Dirk Lemstra via SF patch #39.
+
+ - magick/log.c: Added SetLogMethod() to allow an
+ application/library to specify a function to be called for
+ logging. Patch contributed by Dirk Lemstra.
+
+2014-07-20 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/bmp.c: "opacity" read from a BMP3 is actually "alpha",
+ so store q->opacity=MaxRGB-opacity instead of q->opacity=opacity.
+ Reference: Bug tracker [bugs:#271] Blank result for BMP resize.
+
+2014-07-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - webp, VisualMagick/webp: Integrate webp 0.4.0 into windows
+ build. May require manual renaming of output object files in
+ project files to build webp until VisualMagick configure is
+ improved!
+
+2014-07-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c: fmin() and fmax() are defined by C'99 and
+ not available everywhere, so add and use MagickFmin() and
+ MagickFmax() to improve portability.
+
+2014-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Magick++/Image.h (Magick): Fix complilation errors
+ caused by continued raw use of \_\_attribute\_\_.
+
+2014-06-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c: Fixes by Brendan Lane for color channel
+ overflows in modified/new quantum operators. Fixes test suite
+ results for Q32 build and makes LinearBurn and LinearDodge work
+ correctly at all.
+
+ - wand/pixel\_wand.c (PixelSetMagenta): Fix documentation.
+ Resolves SourceForge bug #273 'Green Magenta' typo in docs.
+
+2014-06-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c: Composition improvements and additions
+ contributed by Brendan Lane via SourceForge patch #34 "Most of the
+ missing Photoshop separable compositing operations"
+ (https://sourceforge.net/p/graphicsmagick/patches/34/). These
+ composition operators were modified to include alpha in their
+ computations: Difference, Darken, Lighten, HardLight, and these
+ operators were added Overlay, Exclusion, ColorBurn, ColorDodge,
+ SoftLight, LinearBurn, LinearDodge, LinearLight, VividLight,
+ PinLight, HardMix.
+
+2014-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c (ScreenCompositePixels): Implementation of
+ Screen composite contributed by Brendan Lane. SourceForge patch
+ #30 "Missing Screen composite operation".
+
+ - wand/magick\_compat.c: Re-worked Wand library implementation to
+ depend directly on GraphicsMagick library functionality rather
+ than using ImageMagick shim code from magick\_compat.c and
+ magick\_compat.h. The magick\_compat.c source module becomes "dead
+ code", which remains only to support the existing ABI, and will be
+ deleted at the next major ABI break point.
+
+ - magick/utility.c (MagickFormatString): New private function to
+ format a string into a buffer with a specified size. Same as
+ previously existing FormatString() except requires a length
+ argument.
+
+2014-06-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_compat.h: Use MAGICK\_ATTRIBUTE definition from
+ magick/common.h.
+
+ - magick/common.h (MAGICK\_ATTRIBUTE): Don't undefine \_\_attribute\_\_
+ since this may be used by system or compiler headers. Define
+ private macro instead. Resolves SourceForge bug #270 "Compile
+ error with g++ -std=c++11".
+
+2014-06-06 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOnePNGImage): Free png\_pixels and
+ quantum\_scanline before error return. Use "png\_error()"
+ instead of "ThrowException2()" for errors occuring while
+ decoding a PNG so proper cleanup will happen.
+
+2014-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Make sure that libtiff warnings
+ are promoted to errors for critical tags.
+
+2014-06-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Be quite a lot more draconian
+ when retrieving the baseline standard TIFF tags we need in order
+ to avoid consuming uninitalized data later. An error with these
+ tags will result in failure to read the image file.
+
+2014-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/operator.c: Decided that ThresholdBlackNegateQuantumOp
+ and ThresholdWhiteNegateQuantumOp should set the result to white
+ or black respectively rather than being based on subtraction.
+
+2014-05-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (AUTOMAKE\_OPTIONS): Be ultra-pedantic with CPPFLAGS
+ and include paths in order to assure that only required
+ directories are supplied, and to avoid accidential collision with
+ system header files.
+
+2014-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/operator.h ("C"): New quantum operators
+ ThresholdBlackNegateQuantumOp and ThresholdWhiteNegateQuantumOp.
+ These correspond to -operator "Threshold-Black-Negate" and
+ "Threshold-White-Negate".
+
+2014-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/composite.c (MultiplyCompositePixels): Multiply
+ composition now uses SVG interpretation of how alpha should be
+ handled. No longer does a simple multiply of alpha channel.
+ Behavior change. Patch contributed by Sara Shafaei.
+
+ - coders/msl.c (ProcessMSLScript): Deal with case where
+ image\_info->attributes is NULL.
+
+2014-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (TranslateTextEx): Support additional format
+ specifiers 'g', 'A', 'C', 'D', 'G', 'H', 'M', 'O', 'P', 'Q', 'T',
+ 'U', 'W', 'X', and '@'.
+ (GetMagickGeometry): Support '>' and '<' qualifiers with '@'
+ qualifier to specify if image should be resized if larger or
+ lesser than given area specification. Resolves SourceForge bug
+ #216 ">" wont take effect when use @ to specify the maximum area.
+
+ - magick/transform.c (GetImageMosaicDimensions): Move mosaic
+ dimensions code to a static function for possible future re-use.
+
+2014-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/gradient.c (GradientImage): Update image is\_grayscale and
+ is\_monochrome flags based on gradient color properties.
+
+2014-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetMagickGeometry): Deal with resize geometry
+ missing width or height (e.g. '640x' or 'x480') by substituting
+ the missing value with one which preserves the image aspect ratio.
+ This has been documented to be supported since almost the dawn of
+ GraphicsMagick but was not actually supported until now.
+
+2014-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Document WebP encoder options.
+
+ - coders/webp.c (WriteWEBPImage): Support all of the WebP encoder
+ options via -define arguments. Most of this work is contributed
+ by Roman Hiestand.
+
+ - configure.ac: User-provided LIBS should be prepended to LIBS
+ that configure script produces so that user option takes
+ precedence.
+
+2014-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/Magick.xs: Added support for HardLight composition
+ operator.
+
+ - www/perl.rst: Update PerlMagick documentation, including the
+ composition operators.
+
+ - coders/xcf.c (GIMPBlendModeToCompositeOperator): Use new
+ HardLight composition operator to support XCF GIMP\_HARDLIGHT\_MODE
+ blend mode. Contributed by Sara Shafaei.
+
+ - coders/psd.c (CompositeOperatorToPSDBlendMode): Use new
+ HardLight composition operator to support PSD "hLit" blend mode.
+ Contributed by Sara Shafaei.
+
+ - wand/magick\_wand.c (MagickOperatorImageChannel): New function to
+ apply an operator to an image channel. Contributed by Sara
+ Shafaei.
+
+ - magick/composite.c (HardLightCompositePixels): New HardLight
+ composition operator. Contributed by Sara Shafaei.
+
+2014-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (BenchmarkImageCommand): Add a CSV title line
+ and quoting to benchmark -rawcsv output.
+
+2014-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/webp.c: Add progress indication support to WebP writer.
+
+ - magick/command.c (VersionCommand): WebP support is included in
+ -version output.
+
+ - coders/webp.c: WebP coder identifies library version and header
+ ABI versions. Improve WebP error reporting.
+
+2014-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Allow specifying the TIFF image
+ software tag. In the special case that the string length is zero
+ (e.g. -set software '') then the tag is skipped entirely. This is
+ to support SourceForge feature request #37 "Option to prevent
+ addition of Exif Software tag" opened by Jean-Louis Grall. Please
+ note that this tag is not an EXIF tag.
+
+ - magick/command.c: composite, convert, display, mogrify, and
+ import now support +set to remove an existing image attribute.
+
+2014-03-16 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Don't block threads when PNG\_SETJMP\_SUPPORTED is
+ not enabled.
+
+ - coders/png.c: Changed prefix of macros defined in coders/png.c
+ from PNG\_ to GMPNG\_. PNG\_ is reserved for macros defined by
+ libpng.
+
+2014-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c: Don't use setvbuf() to set stdio block size if
+ filesystem block size is zero (e.g. MAGICK\_IOBUF\_SIZE=0)
+
+2014-03-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/{rwblob.tap, rwfile.tap}: Added tests for WEBP.
+
+ - tests/{rwblob.c, rwfile.c}: Add lossy hint for WEBP.
+
+ - coders/webp.c (WriteWEBPImage): Fix inverted return status.
+ Added a tiny bit of logging.
+
+2014-03-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ttf: Updated FreeType to release 2.5.3 of March 6, 2014.
+ Provides security fixes for CVE-2014-2240.
+
+ - jpeg: Update to libjpeg 9a of 19-Jan-2014.
+
+ - png: Update to Libpng 1.6.10 - March 6, 2014.
+
+2014-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (NTResourceToBlob): According to Microsoft
+ Report article 193678 (http://support.microsoft.com/kb/193678),
+ FreeResource() is not needed in WIN32 and performs no useful
+ function. Remove use of it. Also remove use of UnlockResource()
+ which is similarly unuseful for WIN32.
+
+ - configure.ac (MAGICK\_LIBRARY\_REVISION): Test for Windows
+ \_aligned\_malloc() is not reliable. Use Windows CRT version to
+ decide if it is available.
+
+2014-03-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h: Make sure that Windows \_aligned\_malloc() is not
+ used under MinGW unless the CRT version allows it.
+
+2014-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (InterpolateViewColor): Applied patch by
+ Troy Patteson plus fixes to ignore opacity channel if image matte
+ is false. Replaces most of the code rewritten on 2014-02-16 and
+ which produced a faint darkened border. The results look stellar
+ now.
+
+2014-02-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/shear.c: Applied patch by Troy Patteson to improve
+ non-integral rotation by around 40% by minimizing added image
+ borders. This may cause small differences in results for some
+ images.
+
+ - reference/filter/Rotate10.miff: Update rotate 10 degrees
+ reference image so that PerlMagick test passes.
+
+ - magick/shear.c: Applied patch by Troy Patteson to fix
+ SourceForge issue #260 "Rotation exhibits clipping/shearing errors
+ for short wide images at some angles".
+
+2014-02-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc: Fix documentation to note that 'unspecified
+ alpha' is the GraphicsMagick default when writing TIFF rather than
+ 'associated alpha'. Much thanks to Mats Peterson for alerting us
+ of this error.
+
+2014-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (InterpolateViewColor): Added a hack so that
+ affine transformations and displace composite do not have
+ background colored fringing on the transferred image edges when
+ the background is completely transparent. Fringing problem was
+ caused by one or more of the line ends being a transparent pixel
+ outside of the bounds of the original image content. May not be
+ the final solution.
+
+2014-02-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/semaphore.c (AcquireSemaphoreInfo): Document that this
+ function was deprecated.
+ (LiberateSemaphoreInfo): Document that this function was
+ deprecated.
+
+2014-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/psd.c (RegisterPSDImage): Set PSD to UnstableCoderClass
+ since its implementation is currently rather marginal. It may
+ even be that this coder deserves to be marked with the new
+ BrokenCoderClass. We are still looking for a volunteer to iron
+ out the wrinkles in the PSD reader.
+
+ - magick/magick.h (CoderClass): Added BrokenCoderClass to mark
+ coders which often malfunction or are not very useful in their
+ current condition. Sometimes there is still hope that problems
+ will be resolved and so the source file is not outright deleted.
+ This setting allows us to mark and use coders which might
+ malfunction by defining MAGICK\_CODER\_STABILITY=BROKEN in the
+ environment while not causing danger for normal use.
+
+2014-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c: Documentation improvements for
+ MagickSetInterlaceScheme() and MagickSetImageInterlaceScheme().
+ Resolves SourceForge bug #262 "setImageInterlaceScheme doesn't
+ make image progressive".
+
+2014-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/{ps.c, ps2.c, ps3.c, pdf.c}: Only use resolution from
+ image or -density if units was properly specified. Without units,
+ resolution is worthless.
+
+ - coders/ps3.c (WritePS3Image): Use image resolution similar to PDF
+ changes.
+
+ - coders/ps2.c (WritePS2Image): Use image resolution similar to PDF
+ changes.
+
+ - coders/ps.c (WritePSImage): Use image resolution similar to PDF
+ changes.
+
+ - coders/pdf.c (WritePDFImage): Use resolution from image if it
+ appears to be valid. Resolves SourceForge issue #261 "PNG Pixel
+ Density Not Preserved Converting to PDF".
+
+ - magick/enum\_strings.c (StringToResolutionType): New function to
+ convert ResolutionType to C string.
+ (ResolutionTypeToString): New function to convert from C string to
+ ResolutionType.
+
+2014-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickGetImageGeometry): New function to get
+ the image geometry string. This function and the three others in
+ this change set are contributed by Sara Shafaei.
+ (MagickGetImageMatte): New function to read the image matte
+ (opacity) channel enable flag.
+ (MagickSetImageGeometry): New function to set the image geometry
+ string.
+ (MagickSetImageMatte): New function to set the image matte
+ (opacity) channel enable flag.
+
+2014-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.c (MagickDrawImage): Remove development debug
+ fprintf which causes each drawing primitive to be printed to
+ stderr.
+
+2014-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (ReadPNMImage): Fix scaling of alpha in sub-ranged
+ pixels. Addresses SourceForge issue #237 "Incorrect MAXVAL
+ scaling when reading PAM images", which was not fully fixed in by
+ the previous attempt.
+
+2014-01-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/tsd.c: Implement TSD for "pure" OpenMP mode without
+ relying on POSIX or WIN32 TSD APIs.
+
+ - magick/semaphore.c: Implement OpenMP-based locking so that code
+ can compile in a "pure" OpenMP mode without relying on POSIX or
+ WIN32 locking APIs.
+
+ - configure.ac: --without-threads no longer disables use of
+ OpenMP. Use the already existing option --disable-openmp to
+ disable OpenMP.
+
+2014-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/common.h: Support use of clang/llvm \_\_attribute\_\_ and
+ \_\_builtin extensions similar to the existing support for GCC.
+
+2014-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Image.cpp (thumbnail): New method for fast image
+ resizing, particularly to make thumbnails.
+
+ - coders/gif.c: Log when Netscape loop exension is read and
+ written.
+
+ - coders/png.c (WriteOnePNGImage): In optimize mode, disable matte
+ channel immediately if there are no non-opaque pixels. Also added
+ some useful logging. Resolves SourceForge issue #252 "convert an
+ 8bit PNG result in a corrupted image ".
+
+ - wand/magick\_wand.c (MagickSetImageGravity): New Wand method to
+ set image gravity.
+ (MagickGetImageGravity): New wand method to get image gravity.
+
+2014-01-02 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOnePNGImage): Use libpng function
+ png\_set\_strip\_16\_to\_8() when scaling 16-bit input PNG down to
+ 8-bit in a Q8 build. The png\_set\_scale\_16\_to\_8() function is
+ more accurate, but the slight difference causes reference tests
+ to fail and causes unexpected difference between the behavior
+ of PNG and other formats. If png\_set\_strip\_16\_to\_8() is not
+ supported in libpng, then we use png\_set\_scale\_16\_to\_8() if
+ that is available.
+
+2014-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - INSTALL-windows.txt: Update for 2014.
+
+ - INSTALL-unix.txt: Update for 2014.
+
+ - Copyright.txt: Update for 2014.
+
+ - NEWS.txt: Update for 2014.
+
+ - README.txt: Update for 2014.
+
+ - doc: Update for 2014.
+
+ - www: Update for 2014.
+
+ - VisualMagick/installer: Update for 2014.
+
+ - ChangeLog: Rotate Changelog to ChangeLog.2013 for 2014.
+
diff --git a/www/ChangeLog-2015.html b/www/ChangeLog-2015.html
new file mode 100644
index 0000000..09346d7
--- /dev/null
+++ b/www/ChangeLog-2015.html
@@ -0,0 +1,2043 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2015-12-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>ttf: Update bundled freetype to release 2.6.2.</li>
+<li>libxml: Update bundled libxml2 to release 2.9.3.</li>
+</ul>
+</blockquote>
+<p>2015-11-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>webp: Updated bundled libwebp to release 0.4.4.</li>
+<li>png: Updated bundled libpng to release 1.6.19.</li>
+</ul>
+</blockquote>
+<p>2015-11-05 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): Added &quot;volatile&quot; to
+several declarations to stop &quot;might be clobbered&quot; warnings.</li>
+</ul>
+</blockquote>
+<p>2015-11-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Update NEWS for 1.3.23 release.</li>
+</ul>
+</blockquote>
+<p>2015-11-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (IdentifyImageCommand): Fix problem that
+identify with -format &quot;%A&quot; does not always report correct answer
+due to insufficient analysis of image. Fixes SourceForge bug #326
+&quot;gm identify: transparency detection bug &quot;.</li>
+</ul>
+</blockquote>
+<p>2015-11-05 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): Restored a &quot;volatile&quot;
+declaration that was accidentally deleted on 2015-11-03.</li>
+</ul>
+</blockquote>
+<p>2015-11-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Add checks for 'ps2write' and 'eps2write' as
+Ghostscript Postscript and Encapsulated Postscript
+writers. Resolves issue reported to graphicsmagick-bugs mailing
+list on 2015-11-01 entitled &quot;Failure to detect pswrite and
+epswrite Ghostscript devices&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-11-03 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadRawProfile): Issue a warning instead of
+an error when attempting to read a zero-length profile.</li>
+</ul>
+</blockquote>
+<p>2015-11-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h (MagickSleep): Provide the macro 'MagickSleep'
+to call a function which delays for one second. No longer provide
+a macro 'sleep' in WIN32 compiles. Resolves issue reported to
+graphicsmagick-bugs mailing list on 2005-11-01 entitled &quot;MinGW
+build error when sleep re#defined as Sleep&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-10-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/demo/demos.tap: Add zoom test cases to test resize to
+original dimensions, change height, and change width.</li>
+<li>magick/resize.c (ScaleImage): Fix regression introduced in
+1.3.22 release which results in pixel cache not open if the scale
+width and height match the original. Patch by Troy Patteson.
+Fixes part of SourceForge bug #323 &quot;ScaleImage() issues in
+v1.3.22&quot;.
+(ScaleImage): Fix double free problem when scaled rows equals
+original rows. This regression was added in the 1.3.22 release
+via changset 080b99bba574. Based on patch by Troy Patteson.
+Fixes remaining part SourceForge bug #323 &quot;ScaleImage() issues in
+v1.3.22&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-10-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Magick++/Image.rst (thumbnail): Paragraph heading fix.
+Resolves SourceForge issue #321 &quot;find tiny error in
+Magick++/Image.html document&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-10-06 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>docs/*.imdoc: Changed synopses in manpages to add &quot;gm &quot;
+prefix to commands. Updated synopsis for &quot;convert&quot; to agree
+with what's in the &quot;gm&quot; manpage.</li>
+</ul>
+</blockquote>
+<p>2015-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Remove CFLAGS and LDFLAGS deduplication code.
+Resolves SourceForge bug #320 OS X &quot;universal build failure&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-10-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/index.rst: Updated for 1.3.22 release.</li>
+<li>NEWS.txt: Updated for 1.3.22 release.</li>
+</ul>
+</blockquote>
+<p>2015-09-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Brought up to date with changes thus far since last
+release.</li>
+<li>magick/blob.c (OpenBlob): Disable fflush() of read-only handle
+under Microsoft Windows, which produced a spurious error status,
+blocking file reads for Visual Studio 2015 on Windows 2012 server.
+Problem was reported and diagnosed by Dirk Lemstra.</li>
+</ul>
+</blockquote>
+<p>2015-09-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff: Update bundled libtiff sources to 4.0.6 release.</li>
+<li>magick/module.c (InitializeModuleSearchPath): Fix compilation
+problem when UseInstalledMagick is not defined.</li>
+</ul>
+</blockquote>
+<p>2015-09-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xpm.c: Static string/array allocations are now more
+const.</li>
+<li>coders/{ps.c, ps2.c, ps3.c}: Static string/array allocations are
+now more const.</li>
+<li>coders/palm.c: Palm static arrays should be 'const'.</li>
+<li>coders/meta.c (jpeg_embed): Stop sharing writeable static string
+'psheader'.
+(tag_spec): The 'tags' static array should be all 'const'.</li>
+<li>coders/jp2.c: Try to reduce the amount of non-const static data.</li>
+<li>coders/dcm.c (dicom_info): Try to make dicom_info array more
+'const'.</li>
+<li>coders/dpx.c: Eliminate use of static buffer strings.</li>
+<li>coders/png.c: Make MNG chunk id strings constant rather than
+initialized data.</li>
+<li>magick/render.c (DrawAffineImage): Fix problem that sometimes
+output rows are skipped when using OpenMP. Problem identification
+and patch by Kevin Matzen. Resolves SourceForge issue #316
+&quot;-affine sometimes produces output with missing rows&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-08-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/rwblob.tap: Add specific tests for BMP2 BMP3 subformats.</li>
+<li>tests/rwfile.tap: Add specific tests for BMP2 BMP3 PS2 PS3
+subformats.</li>
+</ul>
+</blockquote>
+<p>2015-08-30 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<p>* magick/ImageMagick.rc Replace Imagemagick.ico by GraphicsMagick.ico</p>
+<p>* magick/Imagemagick.ico is no longer needed and not referenced anywhere.</p>
+</blockquote>
+<p>2015-08-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>README.txt: Fix SourceForge bug 314 &quot;README: bad hg clone URL&quot;.</li>
+<li>magick/module.c (GetModuleListForDirectory): Fix Coverity 107017
+&quot;Copy into fixed size buffer&quot; and 107013 &quot;Overlapping buffer in
+memory copy&quot;.
+(UnloadModule): Fix SourceForge bug 312 &quot;uninitialized variable
+&quot;name&quot; in UnloadModule&quot;.</li>
+<li>coders/bmp.c (WriteBMPImage): Fix typo in fix on 2015-08-17.
+Fixes Coverity 107014 &quot;Test should be assignment&quot;.</li>
+<li>magick/module.c (OpenModules): Fix Coverity 107016 &quot;Resource
+leak&quot;.
+(GetModuleListForDirectory): Fix Coverity 107015 &quot;Resource leak&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-08-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (WriteBMPImage): Fix inverted alpha channel when
+writing BGRA8888 format. Problem was reported by 张铎 via the
+graphicsmagick-help discussion list on 2015-08-17.</li>
+</ul>
+</blockquote>
+<p>2015-08-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GenerateEXIFAttribute): Verify that entry
+pointer is within the metadata buffer in order to avoid buffer
+overflow. Resolution and patch by Federico Larumbe.</li>
+<li>magick/profile.c (SetImageProfile): Avoid crash given NULL
+profile pointer. Resolution and patch by Federico Larumbe.</li>
+</ul>
+</blockquote>
+<p>2015-08-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GenerateEXIFAttribute): Fix logic problem
+while validating EXIF GPS_OFFSET. Problem reported by Federico
+Larumbe.</li>
+</ul>
+</blockquote>
+<p>2015-07-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): Applied fix
+(<a class="reference external" href="http://hg.code.sf.net/u/zacmorris/graphicsmagick/rev/edcc4c184b42">http://hg.code.sf.net/u/zacmorris/graphicsmagick/rev/edcc4c184b42</a>)
+by Zac Morris to detect buffer overrun while reading zip
+compressed data.
+(ReadMIFFImage): Fixed some memory leaks which were occuring when
+an exception was thrown from zip-compressed data reader.</li>
+</ul>
+</blockquote>
+<p>2015-07-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WritePTIFImage): Fix SourceForge issue #269
+&quot;Convert creates SubfileType 0x2 instead of 0x1&quot;. From looking at
+the code, this is a regression since the time support for the page
+subfile type was added (probably via changeset 11831
+(037eef0f67f2) on 2007-08-17).</li>
+</ul>
+</blockquote>
+<p>2015-07-19 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>dcraw/dcraw.c: Fixed bad define WIN32.</li>
+</ul>
+</blockquote>
+<p>2015-07-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt, www/Hg.rst, www/index.rst: Applied English bugs patch
+by Amadu Jalloh.</li>
+<li>dcraw/dcraw.c: Add a port replacement for strnlen().</li>
+</ul>
+</blockquote>
+<p>2015-07-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>wand/magick_wand.h: The declaration for MagickGetImageGravity()
+was missing. Resolves SourceForge bug #308 magick_wand.h misses
+declaration of MagickGetImageGravity.</li>
+</ul>
+</blockquote>
+<p>2015-07-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>dcraw: Update bundled dcraw to release 9.26.0.</li>
+<li>png: Updated bundled libpng to release 1.6.17.</li>
+<li>lcms: Update bundled lcms2 to release 2.7.</li>
+</ul>
+</blockquote>
+<p>2015-07-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Brought up to date with changes thus far since last
+release.</li>
+<li>magick/version.h.in (MagickCopyright): Update most recent
+copyright year.</li>
+<li>magick/render.c (DrawAffineImage): Fix problem with negative x
+offset. Resolves SourceForge issue #306 &quot;gm fails to convert svg
+to jpeg if svg has images with negative coordinates&quot;.</li>
+<li>magick/pixel_cache.c (ReadCachePixels): Add checks for integer
+overflows.</li>
+</ul>
+</blockquote>
+<p>2015-07-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/module.c (ModuleAliases): Add a module alias for GRAYA.</li>
+</ul>
+</blockquote>
+<p>2015-07-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/montage.c (MontageImages): Fix Coverity 101317 &quot;Resource
+leak&quot;.</li>
+<li>magick/blob.c: Limit the data size passed to the read/write
+calls to the filesystem blocksize and make multiple calls if
+required.</li>
+<li>magick/pixel_cache.c: Limit the data size passed to the
+read/write, pread/prwite calls and make multiple calls if
+required.</li>
+</ul>
+</blockquote>
+<p>2015-07-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (WriteBlobFile): Properly handle short read. Read
+data in units of filesystem block size.
+(BlobToFile): Write data in units of filesystem block size.</li>
+<li>patches: Added directory of patches which may be useful when
+integrating new versions of 3rd-party programs or libraries into
+the VisualMagick build.</li>
+<li>libxml: Re-applied libxml changes which were used in prior
+release.</li>
+</ul>
+</blockquote>
+<p>2015-07-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>webp: Updated bundled libwebp to release 0.4.3.</li>
+<li>ttf: Update bundled freetype to release 2.6.</li>
+<li>libxml: Update bundled libxml2 to release 2.9.2.</li>
+<li>tiff/VERSION: Update bundled libtiff to release 4.0.4.</li>
+<li>magick/nt_base.h (HAVE_TIFFISCODECCONFIGURED): Enable use of
+TIFFIsCODECConfigured in MSVC build.</li>
+<li>coders/tiff.c: I am too lazy to modify VisualMagick configure so
+it is possible to include jpeglib.h in tiff.c, so block out this
+low-value code just for MSVC builds.</li>
+</ul>
+</blockquote>
+<p>2015-06-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac, magick/profile.c: Removed support for lcms 1.X.
+No one should be using a lesser version than lcms 2.0.</li>
+</ul>
+</blockquote>
+<p>2015-06-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (DisassociateBlob): Applied patch by Dirk Lemstra
+to assure that the image blob is no longer shared with other
+images when the image is written. This helps with thread safety.</li>
+</ul>
+</blockquote>
+<p>2015-06-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Add/fix utility usage messages for -box,
+-convolve, -gravity, -linewidth, -list, -mattecolor, -render and
+-shave. Resolves SourceForge issue #302 &quot;MogrifyUsage prints
+incomplete information &quot;.</li>
+</ul>
+</blockquote>
+<p>2015-06-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Include JPEG headers to obtain
+its BITS_IN_JSAMPLE definition. This is needed so we can know
+what JPEG depth libtiff supports.</li>
+<li>www/index.rst: Add mention of GraphicsMagick having zero defects
+reported by Coverity.</li>
+</ul>
+</blockquote>
+<p>2015-06-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/STL.cpp (adaptiveThresholdImage): Add a new
+constructor which accepts a 'double' offset value. The previous
+version of this constructor is deprecated and subject to removal
+in the future. The size of the class is enlarged to store a
+'double' and so this is a break in the ABI when this class was
+used. Code using this class should be re-compiled.</li>
+<li>Magick++/lib/Image.cpp (adaptiveThreshold): Add a new version of
+this method which accepts a 'double' offset value. The previous
+version of the method is deprecated and subject to removal in the
+future. Problem was reported by Dirk Lemstra.</li>
+</ul>
+</blockquote>
+<p>2015-05-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gray.c (ReadGRAYImage): Based on feedback from Glenn,
+return a gray image from the reader, even if a channelized format
+specifier is given.</li>
+</ul>
+</blockquote>
+<p>2015-05-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gray.c (ReadGRAYImage): Fix read glitch caused by
+incorrect memset(). Added missing break statement to switch.
+Added more logging.
+(RegisterGRAYImage): Register &quot;gray&quot; formats R, G, B, C, M, Y, K,
+O such that they are not triggered by file extension. It is
+necessary to apply a magick prefix to the file name (or set image
+magick in the API) in order to force using these formats. This
+avoids accidents in case the file extension was used for some
+other purpose.</li>
+</ul>
+</blockquote>
+<p>2015-05-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gray.c: Added support for &quot;GRAYA&quot; format. Format
+specifiers &quot;R&quot;, &quot;G&quot;, &quot;B&quot;, &quot;A&quot;, &quot;C&quot;, &quot;M&quot;, and &quot;Y&quot; may now be used
+to save and restore the associated channel using the same raw
+format as &quot;GRAY&quot;. These format specifiers were already supported
+but did not appear to serve any useful function.</li>
+</ul>
+</blockquote>
+<p>2015-05-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Improve handling of libxml2 dependencies. Only
+test for and use libwmflite. Full-up libwmf is no longer used.</li>
+<li>configure.ac: Deduplicate CFLAGS and LDFLAGS.</li>
+</ul>
+</blockquote>
+<p>2015-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): Eliminate a &quot;clobber&quot;
+compilation warning.</li>
+<li>coders/jpeg.c (WriteJPEGImage): Eliminate a &quot;clobber&quot;
+compilation warning.</li>
+<li>configure.ac: Don't compute libwmf2 and libxml2 linkage path
+based on claimed installation prefix. This is hoped to improve
+configure reliability on multi-arch type systems.</li>
+</ul>
+</blockquote>
+<p>2015-05-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Use the first -I, -L, and -l arguments produced by
+freetype-config and don't produce arguments based on installation
+prefix. This is hoped to improve configure reliability on
+multi-arch type systems.</li>
+</ul>
+</blockquote>
+<p>2015-05-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/tempfile.c (AcquireTemporaryFileDescriptor): P_tmpdir is
+not an environment variable. Need to consider Windows environment
+variables for Cygwin.</li>
+<li>magick/random.c (InitializeMagickRandomKernel): For Microsoft
+Windows, use CryptGenRandom() to salt the built-in random number
+generator.</li>
+</ul>
+</blockquote>
+<p>2015-05-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (MagickRandReentrant): Quiet Coverity 10092
+&quot;Calling risky function&quot;.
+(MagickRandNewSeed): Quiet Coverity 10093 &quot;Calling risky
+function&quot;.</li>
+<li>coders/tga.c (ReadTGAImage): Quiet Coverity 10201 &quot;Identical
+code for different branches&quot;.</li>
+<li>coders/pcx.c (ReadPCXImage): Quiet Coverity 10218 &quot;Identical
+code for different branches&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-05-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetGeometry): Fix handling of area geometries
+in the form &quot;5000000&#64;&quot;. Resolves SourceForge issue #299 &quot;-resize
+with &#64; and &gt; in geometry specification&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-05-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Disable matte channel for
+compression types which don't support it. Resolves SourceForge
+bug #297 &quot;GM distorts image using -transform&quot;.
+(WriteTIFFImage): When type is Optimize, disable matte channel if
+image is opaque.</li>
+</ul>
+</blockquote>
+<p>2015-05-09 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>webp/src/utils/endian_inl.h: Fixed defect in intrinsic function
+byteswap_ulong for Visual Studio less than 2005.</li>
+</ul>
+</blockquote>
+<p>2015-05-08 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/configure/system_page.cpp,
+VisualMagick/configure/system_page.h: Suppress reloading .vcproj
+when configuration type does not change.</li>
+</ul>
+</blockquote>
+<p>2015-05-08 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/configure/system_page.cpp,
+VisualMagick/configure/system_page.h,
+VisualMagick/configure/target_page.h: Ability to re-use already
+given paths. It is highly frustrating to enter path for different
+configurations again and again.</li>
+</ul>
+</blockquote>
+<p>2015-05-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/vid.c (ReadVIDImage): Fix use of uninitialized variable
+reported by MSVC 2003 (but not GCC, Clang, or Coverity).</li>
+</ul>
+</blockquote>
+<p>2015-05-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): Fix possible leak of profiles in
+error path.</li>
+<li>coders/mpc.c (ReadMPCImage): Fix memory leak of values
+allocation.
+(ReadMPCImage): Fix possible leak of profiles in error path. Fixes
+Coverity 80697 &quot;Resource leak&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-05-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): Fix memory leak of values
+allocation.</li>
+</ul>
+</blockquote>
+<p>2015-05-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): Hopefully quiet Coverity 10305
+&quot;Untrusted loop bound&quot;.</li>
+<li>coders/tga.c (ReadTGAImage): Hopefully quiet Coverity 53418
+&quot;Untrusted loop bound&quot;.</li>
+<li>magick/tempfile.c (AcquireTemporaryFileDescriptor): Eliminate
+all use of operating system provided temporary file allocation
+functions (all apparently flawed in one way or another) and rely
+exclusively on our own implementation.</li>
+<li>magick/constitute.c (ConstituteImage): Quiet Coverity 53399
+&quot;Logically dead code&quot;.</li>
+<li>coders/webp.c (ReadWEBPImage): Quiet Coverity 53400 &quot;Logically dead
+code&quot;.</li>
+<li>coders/miff.c (WriteRunlengthPacket): More work to quiet
+Coverity 10186 and 10214 &quot;Missing break in switch&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-05-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/tempfile.c (AcquireTemporaryFileDescriptor): Thoroughly
+vet temporary file path. Might quiet Coverity 64613 &quot;Use of
+untrusted string value&quot;.</li>
+<li>wand/magick_compat.c (ParseGeometry): Another try at quieting
+Coverity 10248 &quot;Copy into fixed size buffer&quot; and 10078
+&quot;Overlapping buffer in memory copy&quot; in this dead code.</li>
+<li>magick/tempfile.c (AcquireTemporaryFileDescriptor): Remove
+unneeded, almost certainly never used, and potentially insecure
+use of mkstemp(). Will quiet Coverity 10315 &quot;Insecure temporary
+file&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Keep Ghostscript gibberish from appearing in
+Configure output.</li>
+<li>coders/miff.c (WriteRunlengthPacket): Quiet Coverity 10186 and
+10214 &quot;Missing break in switch&quot;.</li>
+<li>magick/pixel_cache.c (GetCacheInfo): Quiet Coverity 10208 &quot;Data
+race condition&quot;.</li>
+<li>magick/blob.c (CloneBlobInfo): Quiet Coverity 10188 &quot;Data race
+condition&quot;.
+(GetBlobInfo): Quiet Coverity 10191 &quot;Data race condition&quot;.</li>
+<li>magick/image.c (AllocateImage): Quiet Coverity 10196 &quot;Data race
+condition&quot;.
+(CloneImage): Quiet Coverity 10206 &quot;Data race condition&quot;.</li>
+<li>magick/map.c (MagickMapAllocateMap): Quiet Coverity 10192, 10193
+and 10228 &quot;Data race condition&quot;.</li>
+<li>configure.ac: Use an algorithm to try to discover the best value
+for GSCMYKDevice.</li>
+<li>VisualMagick/bin/delegates.mgk: Recipe for 'gs-cmyk' contained a
+typo which breaks using '-type ColorSeparation'.</li>
+<li>coders/pwp.c (ReadPWPImage): Fix Coverity CID 64491 &quot;Integer
+handling issues&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xcf.c (load_tile_rle): Quiet Coverity 10259 &quot;Untrusted
+loop bound&quot;.</li>
+<li>coders/sct.c (ReadSCTImage): Quiet Coverity 10285 &quot;Untrusted
+loop bound&quot;.</li>
+<li>coders/pwp.c (ReadPWPImage): Quiet Coverity 10299 &quot;Untrusted
+loop bound&quot;.</li>
+<li>coders/pcd.c (ReadPCDImage): Quiet Coverity 10301 &quot;Untrusted
+loop bound&quot;.</li>
+<li>coders/tga.c (ReadTGAImage): Quiet Coverity 53418 &quot;Untrusted
+loop bound&quot;.</li>
+<li>wand/magick_compat.c (ParseGeometry): Fix overlap strcpy() in
+dead code. Quiets Coverity 10078 &quot;Overlapping buffer in memory
+copy&quot; and 10248 &quot;Copy into fixed size buffer&quot;.</li>
+<li>magick/segment.c (Classify): Fix Coverity 64317 &quot;Resource leak&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xcf.c (ReadXCFImage): Fix Coverity 64064 &quot;Resource leak&quot;.</li>
+<li>coders/txt.c (ReadTXTImage): Fix Coverity 64061 &quot;Resource leak&quot;.</li>
+<li>coders/rla.c (ReadRLAImage): Fix Coverity 64063 &quot;Resource leak&quot;.</li>
+<li>coders/dib.c (ReadDIBImage): Fix Coverity 64057 Resource leak&quot;.</li>
+<li>magick/segment.c (Classify): Fix Coverity 64056 &quot;Resource leak&quot;.</li>
+<li>magick/resize.c (SampleImage): Fix Coverity 64053, 64054, and
+64062 &quot;Resource leak&quot;.</li>
+<li>magick/render.c (TraceStrokePolygon): Fix Coverity 64055, 64059,
+and 64060 &quot;Resource leak&quot;.</li>
+<li>magick/magick.c (ListModuleMap): Quiet Coverity 64058 &quot;Resource
+leak&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-28 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c: Fix Coverity 10305 &quot;Untrusted loop bound&quot;.</li>
+<li>coders/cineon.c: Fix Coverity 10310 &quot;Untrusted loop bound&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/memory.c: All use of user-provided allocation functions
+is done via MagickFree(), MagickMalloc(), and MagickRealloc().</li>
+</ul>
+</blockquote>
+<p>2015-04-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/colormap.c (MagickConstrainColormapIndex): For out of
+range condition, specifically return 0 rather than setting index
+to zero, and then returning index.</li>
+<li>coders/pcx.c (ReadPCXImage): Fix Coverity 10197 &quot;Negative loop
+bound&quot;.</li>
+<li>coders/map.c (ReadMAPImage): Allocate pixels after return case
+for 'ping' mode.
+(ReadMAPImage): Fix problem added in last commit due to multiple
+uses of 'packet_size'.</li>
+<li>magick/floats.c (_Gm_convert_fp16_to_fp32)
+(_Gm_convert_fp24_to_fp32): Fix Coverity 10094 &quot;Logically dead
+code&quot;.</li>
+<li>coders/pcx.c (ReadPCXImage): Fix Coverity 10197 &quot;Negative loop
+bound&quot;.</li>
+<li>coders/wpg.c (UnpackWPG2Raster): Always test for EOF from
+ReadBlobByte(). Should fix Coverity 10205 &quot;Negative loop bound&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pcx.c (ReadPCXImage): Add some more integer-overflow
+safety to computations. Add some casts.</li>
+<li>coders/meta.c (formatIPTC): Fix Coverity 10221 &quot;Infinite loop&quot;.</li>
+<li>magick/attribute.c (GenerateEXIFAttribute): Fix Coverity 10320
+&quot;Untrusted array index read&quot; and &quot;Untrusted loop bound&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-24 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gif.c (ReadGIFImage): Attempt to fix Coverity issue
+10284 by using &quot;opacity = (header[3] &amp; 0xff)&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-23 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (ReadBlobMSBLong, ReadBlobLSBLong): Attempt
+to fix various &quot;tainted&quot; or &quot;untrusted&quot; variables
+by masking off all but the lower 32 bits returned.</li>
+</ul>
+</blockquote>
+<p>2015-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xcf.c (ReadXCFImage): Fix Coverity 10216 &quot;Integer
+overflowed argument&quot;.</li>
+<li>magick/transform.c (FlipImage): Fix Coverity 61461 &quot;Division or
+modulo by zero&quot;.</li>
+<li>coders/gif.c: Protect against integer overflow in array size
+calculations. Used unsigned type for colormap index.</li>
+</ul>
+</blockquote>
+<p>2015-04-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/map.c (ReadMAPImage): Maybe quiet Coverity 10326
+&quot;Untrusted pointer read&quot;.</li>
+<li>magick/utility.c (GlobExpression): See if testing for null
+terminating character quiets Coverity 10246 &quot;Untrusted value as
+argument&quot;.</li>
+<li>magick/transform.c (FlipImage): Possibly quiet case #4 of
+Coverity 10311 &quot;Untrusted value as argument&quot;.</li>
+<li>magick/utility.c (Base64Encode): Quiet Coverity 10296 and 10272
+&quot;Use of untrusted scalar value&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-22 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c (ReadBlobMSBShort, ReadBlobLSBShort): Attempt
+to fix various &quot;tainted&quot; or &quot;untrusted&quot; variables, e.g., in
+coders/gif.c and coders/sgi.c by masking off all but the lower
+16 bits returned.</li>
+</ul>
+</blockquote>
+<p>2015-04-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tim.c (ReadTIMImage): Make TIM reader more robust against
+EOF.</li>
+<li>coders/sct.c (ReadSCTImage): Make SCT reader more robust against
+EOF.</li>
+<li>coders/pwp.c (ReadPWPImage): Test loop for EOF.</li>
+<li>coders/otb.c (ReadOTBImage): Make error reporting a bit more
+robust.</li>
+<li>coders/jnx.c (ExtractTileJPG): Add some EOF checks.</li>
+<li>coders/cut.c (ReadCUTImage): Limit width/height to range of
+signed integer.</li>
+<li>tests/rwfile.tap: Add a R/W file test for ART.</li>
+<li>tests/rwblob.tap: Add a R/W blob test for ART.</li>
+<li>coders/art.c (ReadARTImage): Improve error checking.</li>
+</ul>
+</blockquote>
+<p>2015-04-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sun.c (ReadSUNImage): Try to quench Coverity 10280
+&quot;Untrusted loop bound&quot;.</li>
+<li>coders/mpc.c (ReadMPCImage): Port MIFF header reading fixes.</li>
+</ul>
+</blockquote>
+<p>2015-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): MIFF reader failed to read some
+MIFF headers properly. Fixes SourceForge issue #298 &quot;invalid next
+size (normal)/memory corruption&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadMNGImage): Fix Coverity 55862 &quot;Resource leak&quot;
+and quiet Coverity 55825, 55826, and 55827 &quot;Data race condition&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GetToken): Fix an overlapping strlcpy() which
+caused a crash in pedantic strlcpy() implementations while parsing
+a SVG-style URL from text. Several other issues remain.</li>
+</ul>
+</blockquote>
+<p>2015-04-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ParseUnixCommandLine): Fix Coverity 59256
+&quot;Unused value&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/display.c (MagickXROIImage): Fix Coverity 10179 &quot;Missing
+break in switch&quot;.
+(MagickXCropImage): Fix Coverity 10211 &quot;Missing break in switch&quot;.</li>
+<li>magick/utility.c (Base64Decode): Fix Coverity 10203 &quot;Missing
+break in switch&quot;.
+(Tokenizer): Quench Coverity 10182 &quot;Missing break in switch&quot;. Not
+believed to be an actual problem.</li>
+<li>magick/command.c (ParseUnixCommandLine): Fix Coverity 10174 and
+10178 &quot;Missing break in switch&quot;.
+(ProcessBatchOptions): Fix Coverity 10180 &quot;Missing break in
+switch&quot;.
+(ParseWindowsCommandLine): Fix Coverity 10220 &quot;Missing break in
+switch&quot;.</li>
+<li>coders/xwd.c (ReadXWDImage): Fix Coverity 10095 &quot;Division or
+modulo by zero&quot;. 3rd try.</li>
+</ul>
+</blockquote>
+<p>2015-04-14 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOneJNGImage): Fix Coverity 55829 and 55846
+&quot;Resource leak&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+55831 &quot;Resource leak&quot;. 2nd try.</li>
+<li>coders/vid.c (ReadVIDImage): Fix Coverity 55868 and 55874
+&quot;Resource leak&quot;. 2nd try.</li>
+</ul>
+</blockquote>
+<p>2015-04-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c (ReadPSDImage): Fix Coverity 55855 &quot;Resource
+leak&quot;. 2nd try.</li>
+<li>coders/pict.c (PictPixmapOp): Fix Coverity 55875 and 55883
+&quot;Resource leak&quot;. 2nd try.</li>
+<li>coders/pcx.c (WritePCXImage): Fix Coverity 55877 &quot;Resource
+leak&quot;. 2nd try.</li>
+<li>coders/meta.c (format8BIM): Fix Coverity 55842 &quot;Resource
+leak&quot;. 2nd try.</li>
+<li>coders/mat.c (WriteMATLABImage): Fix Coverity 55850 &quot;Resource
+leak&quot;. 2nd try.</li>
+<li>coders/dpx.c (ReadDPXImage): Fix Coverity 55878 &quot;Resource leak&quot;.
+2nd try.</li>
+<li>coders/preview.c (WritePreviewImage): Fix Coverity 55988
+&quot;Resource leak&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-12 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOneJNGImage): Avoid some memory leaks
+newly reported by Coverity (work in progress)</li>
+</ul>
+</blockquote>
+<p>2015-04-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resize.c (ScaleImage): Fix Coverity 55824 &quot;Division or
+modulo by float zero&quot;.</li>
+<li>magick/annotate.c (AnnotateImage): Fix Coverity 55863
+&quot;Uninitialized scalar variable&quot;.</li>
+<li>wand/magick_wand.c (MagickDrawImage): Fix Coverity 55828
+&quot;Resource leak&quot;.
+(MagickMontageImage): Fix Coverity 55835 &quot;Resource leak&quot;.</li>
+<li>wand/drawing_wand.c (DrawComposite): Fix Coverity 55849
+&quot;Resource leak&quot;.</li>
+<li>magick/widget.c (MagickXColorBrowserWidget): Fix Coverity 55854
+&quot;Resource leak&quot;.</li>
+<li>magick/resize.c (ScaleImage): Fix Coverity 55841, 55853, 55858,
+and 55860 &quot;Resource leak&quot;.</li>
+<li>magick/render.c (ConvertPathToPolygon): Fix Coverity 55836
+&quot;Resource leak&quot;.
+(DrawDashPolygon): Fix Coverity 55837 &quot;Resource leak&quot;.</li>
+<li>magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+55831 &quot;Resource leak&quot;.</li>
+<li>magick/paint.c (ColorFloodfillImage): Fix Coverity 55886
+&quot;Resource leak&quot;.</li>
+<li>magick/map.c (MagickMapAddEntry): Possibly silence 55844
+&quot;Resource leak&quot;.</li>
+<li>magick/image.c (CloneImage): Fix Coverity 55833 &quot;Resource leak&quot;.</li>
+<li>magick/effect.c (BlurImage): Fix Coverity 55851 &quot;Resource leak&quot;.</li>
+<li>magick/display.c (MagickXAnnotateEditImage): Fix Coverity 55830
+&quot;Resource leak&quot;.
+(MagickXVisualDirectoryImage): Fix Coverity 55894 &quot;Resource leak&quot;.</li>
+<li>magick/constitute.c (ReadImages): Fix Coverity 55834 &quot;Resource
+leak&quot;.
+(ReadInlineImage): Fix Coverity 55843 &quot;Resource leak&quot;.</li>
+<li>magick/compress.c (HuffmanEncode2Image): Fix Coverity 55839
+&quot;Resource leak&quot;.
+(HuffmanDecodeImage): Fix Coverity 55859 &quot;Resource leak&quot;.</li>
+<li>magick/color.c (GetColorHistogram): Fix Coverity 55845 &quot;Resource
+leak&quot;.
+(ComputeCubeInfo): Fix Coverity 55857 &quot;Resource leak&quot;.</li>
+<li>coders/yuv.c (ReadYUVImage): Fix Coverity 55890 &quot;Resource leak&quot;.</li>
+<li>coders/wpg.c (UnpackWPG2Raster): Fix Coverity 55832 and 55848
+&quot;Resource leak&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/vid.c (ReadVIDImage): Fix Coverity 55868 &quot;Resource leak&quot;
+(ReadVIDImage): Fix Coverity 55874 &quot;Resource leak&quot;.</li>
+<li>coders/txt.c (ReadTXTImage): Fix Coverity 55866 &quot;Resource leak&quot;.</li>
+<li>coders/topol.c (ReadTOPOLImage): Fix Coverity 55865 &quot;Resource
+leak&quot;.</li>
+<li>coders/sgi.c (WriteSGIImage): Fix Coverity 55891 &quot;Resource leak&quot;.</li>
+<li>coders/psd.c (ReadPSDImage): Fix Coverity 55855 &quot;Resource leak&quot;.</li>
+<li>coders/pict.c (WritePICTImage): Fix Coverity 55867, 55875, 55883
+&quot;Resource leak&quot;. Fix Coverity 55892 &quot;Resource leak&quot;.</li>
+<li>coders/pdb.c (ReadPDBImage): Fix Coverity 55840, 55856, and
+55885 &quot;Resource leak&quot;.</li>
+<li>coders/pcx.c (WritePCXImage): Fix Coverity 55877 &quot;Resource
+leak&quot;.</li>
+<li>coders/mvg.c (ReadMVGImage): Fix Coverity 55873 &quot;Resource leak&quot;.</li>
+<li>coders/mpeg.c (WriteMPEGImage): Fix Coverity 55880 &quot;Resource
+leak&quot;.</li>
+<li>coders/miff.c (WriteMIFFImage): Fix Coverity 55864 &quot;Resource
+leak&quot;.
+(WriteMIFFImage): Fix Coverity 55872 &quot;Resource leak&quot;.</li>
+<li>coders/meta.c (formatIPTCfromBuffer): Fix Coverity 55838
+&quot;Resource leak&quot;.
+(format8BIM): Fix Coverity 55842 and 55852 &quot;Resource leak&quot;.
+(formatIPTC): Fix Coverity 5882 &quot;Resource leak&quot;.</li>
+<li>coders/mat.c (ReadMATImage): Fix Coverity 55850 &quot;Resource leak&quot;.</li>
+<li>coders/map.c (ReadMAPImage): Fix Coverity 55876 &quot;Resource leak&quot;.</li>
+<li>coders/logo.c (ReadLOGOImage): Fix Coverity 55870 &quot;Resource
+leak&quot;.</li>
+<li>coders/label.c (ReadLABELImage): Fix Coverity 55869 &quot;Resource
+leak&quot;.</li>
+<li>coders/icon.c (ReadIconImage): Fix Coverity 55887 &quot;Resource
+leak&quot;.</li>
+<li>coders/fits.c (WriteFITSImage): Fix Coverity 55884 &quot;Resource
+leak&quot;.</li>
+<li>coders/dpx.c (WriteDPXImage): Fix Coverity 55861 &quot;Resource
+leak&quot;.
+(ReadDPXImage): Fix Coverity 55878 &quot;Resource leak&quot;.
+(ReadDPXImage): Fix Coverity 55879 &quot;Resource leak&quot;.</li>
+<li>coders/dib.c (WriteDIBImage): Fix Coverity 55881 &quot;Resource
+leak&quot;.
+(WriteDIBImage): Fix Coverity 55895 &quot;Resource leak&quot;.</li>
+<li>coders/cut.c (ReadCUTImage): Fix Coverity 55893 &quot;Resource leak&quot;.</li>
+<li>coders/caption.c (ReadCAPTIONImage): Fix Coverity 55888
+&quot;Resource leak&quot;.
+(ReadCAPTIONImage): Fix Coverity 55889 &quot;Resource leak&quot;.
+(ReadCAPTIONImage): Fix Coverity 55896 &quot;Resource leak&quot;.</li>
+<li>magick/annotate.c (RenderX11): Silence Coverity 10106 &quot;Logically
+dead code&quot;.</li>
+<li>coders/xcf.c: Silence Coverity 10224, 10233, and 10236 &quot;Improper
+use of negative value&quot;.</li>
+<li>coders/mat.c (ReadMATImage): Silence Coverity 10175 &quot;Improper
+use of negative value&quot;</li>
+<li>coders/tga.c (ReadTGAImage): Silence Coverity 10088 &quot;Operands
+don't affect result&quot;.</li>
+<li>magick/annotate.c (RenderFreetype): Silence Coverity 14396 and
+44755 &quot;Unused value&quot;.</li>
+<li>coders/wpg.c (LoadWPG2Flags): Silence Coverity 10273 and 10253
+&quot;Unused value&quot;.</li>
+<li>magick/montage.c (MontageImages): Silence Coverity 10255 &quot;Unused
+value&quot;.
+(MontageImages): Silence Coverity 10264 &quot;Unused value&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOneJNGImage): Avoid using a NULL alpha_image
+or color_image. (ReadJNGImage): Removed an extraneous CloseBlob().</li>
+</ul>
+</blockquote>
+<p>2015-04-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (MagickCreateDirectoryPath): Silence Coverity
+10098 &quot;Logically dead code&quot;.</li>
+<li>magick/resource.c (InitializeMagickResources): Silence Coverity
+10101 &quot;Logically dead code&quot;.</li>
+<li>magick/magick.c (MagickSignalHandlerMessage): Fix Coverity 44725
+&quot;Logically dead code&quot;.</li>
+<li>magick/log.c (DestroyLogInfo): Silence Coverity 53659 and 53661
+&quot;Data race condition&quot;.
+(ReadLogConfigureFile): Silence Coverity 53660 &quot;Data race
+condition&quot;.</li>
+<li>magick/effect.c (DespeckleImage): Fix error handling issue
+caused by shadowed variable. Fixes Coverity 10099 &quot;Logically dead
+code&quot;.</li>
+<li>magick/command.c (TimeImageCommand): Fix Coverity 10097
+&quot;Logically dead code&quot;.</li>
+<li>magick/attribute.c (ReadMSBLong): Hopefully silence Coverity
+10276 &quot;Unintended sign extension&quot;.</li>
+<li>coders/sgi.c (ReadSGIImage, WriteSGIImage): Fix Coverity 10243,
+10244, 10247, 10254, and 10294 &quot;Unintended sign extension&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/xwindow.c (MagickXMakeImage): Quiet Coverity 10282
+&quot;Unused value&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Another change targeting
+Coverity 44742 and 44746 &quot;Unintended sign extension&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (TracePath): Fix Coverity 10258 &quot;Uninitialized
+scalar variable&quot;.</li>
+<li>magick/widget.c (MagickXFontBrowserWidget): Fix Coverity 10323
+&quot;Sizeof not portable&quot;. 2nd try.</li>
+<li>coders/xwd.c (ReadXWDImage): Fix Coverity 10095, 10100, 10104
+&quot;Division or modulo by zero&quot;. 2nd try.</li>
+<li>magick/analyze.c (GetImageCharacteristics): Fix Coverity 10096
+&quot;Logically dead code&quot;.</li>
+<li>coders/yuv.c (ReadYUVImage): Fix Coverity 10260 &quot;Structurally
+dead code&quot;.</li>
+<li>coders/xcf.c (ReadXCFImage): Fix Coverity 10226 &quot;Missing break
+in switch&quot;.</li>
+<li>coders/tim.c (ReadTIMImage): Fix Coverity 10249 &quot;Unused value&quot;.</li>
+<li>coders/tiff.c (CompressionSupported): Fix Coverity 44723
+&quot;Logically dead code&quot;.
+(WriteTIFFImage): Fix Coverity 44742 and 44746 &quot;Unintended sign
+extension&quot;.</li>
+<li>coders/ps3.c (WritePS3Image): Validate results from TellBlob()
+and SeekBlob(). Should quiet Coverity 10198 &quot;Improper use of
+negative value&quot;.</li>
+<li>coders/ps2.c (WritePS2Image): Validate results from TellBlob()
+and SeekBlob(). Should quiet Coverity 10230 &quot;Improper use of
+negative value&quot;.</li>
+<li>coders/mpeg.c (WriteMPEGImage): Quiet Coverity 10176 &quot;Missing
+break in switch&quot;.</li>
+<li>coders/map.c (WriteMAPImage): Make MAP reader/writer more
+robust. May quiet 10326 &quot;Untrusted pointer read&quot;.</li>
+<li>coders/locale.c (ReadLOCALEImage): Quiet Coverity 10108
+&quot;Logically dead code&quot;.</li>
+<li>coders/rle.c: Make URT RLE reader more robust. Should quiet
+Coverity CID 10070 &quot;Bad bit shift operation&quot;, as well as 10235
+&quot;Improper use of negative value&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-04-04 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOneJNGImage): Quiet Coverity CID issue 14370,
+&quot;Unused value&quot; (status was ignored).</li>
+<li>coders/png.c (ReadOneJNGImage): Quiet Coverity CID issue 44724,
+&quot;Logically dead code&quot; (skip_to_iend can't be true).</li>
+<li>coders/png.c (ReadOnePNGImage): Attempt to quiet Coverity
+CID 10232 &quot;Missing unlock&quot;, by using png_error() instead of
+throwing an exception.</li>
+</ul>
+</blockquote>
+<p>2015-04-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xwd.c (ReadXWDImage): Fix Coverity 10104 &quot;Division or
+modulo by zero&quot;.</li>
+<li>magick/resize.c (ResizeImage): Fix Coverity 53404 &quot;Division or
+modulo by zero&quot;.</li>
+<li>coders/ps3.c (WritePS3MaskImage): Fix Coverity 53415 &quot;Improper
+use of negative value&quot;.</li>
+<li>coders/meta.c (parse8BIM): Fix Coverity 53413 &quot;Improper use of
+negative value&quot;.
+(parse8BIMW): Fix Coverity 53414 &quot;Improper use of negative value&quot;.</li>
+<li>magick/utility.c (GetMagickGeometry): Fix Coverity 53403 and
+53405 &quot;Division or modulo by float zero&quot;.
+(GetPathComponent): Fix Coverity 53417 &quot;Wrong sizeof argument.</li>
+<li>magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+10256 &quot;Wrong sizeof argument&quot;.</li>
+<li>magick/image.c (ResetImagePage): Fix Coverity 53401 &quot;Division or
+modulo by float zero&quot; and 53402 &quot;Division or modulo by float
+zero&quot;.</li>
+<li>coders/histogram.c (WriteHISTOGRAMImage): Silence Coverity 10107
+&quot;Division or modulo by float zero&quot;. 2nd try.</li>
+<li>magick/xwindow.c (MagickXImportImage): Silence Coverity 10207
+&quot;Array compared against 0&quot;.</li>
+<li>magick/widget.c (MagickXColorBrowserWidget): Silence Coverity
+53406 &quot;Identical code for different branches&quot;.
+(MagickXListBrowserWidget): Silence Coverity 53407 &quot;Identical code
+for different branches&quot;.</li>
+<li>magick/animate.c (MagickXMagickCommand): Silence Coverity 53410
+&quot;Identical code for different branches&quot;.</li>
+<li>coders/rgb.c (WriteRGBImage): Silence Coverity 53409 &quot;Identical
+code for different branches&quot;.</li>
+<li>coders/cmyk.c (WriteCMYKImage): Silence Coverity 53408
+&quot;Identical code for different branches&quot;.</li>
+<li>magick/xwindow.c (MagickXMakeImage): Silence Coverity 44727
+&quot;Dereference after null check&quot;. 2nd try.</li>
+<li>magick/utility.c (EscapeString): Silence Coverity 53416
+&quot;Dereference before null check&quot;.</li>
+<li>coders/gif.c (WriteGIFImage): Fix Coverity 10219 &quot;Dereference
+null return value&quot;.</li>
+<li>magick/log.c (InitializeLogInfo): Hopefully silence Coverity
+53411 and 53412 &quot;Data race condition&quot;.</li>
+<li>coders/cineon.c (AttributeToString): Silence Coverity 10079
+&quot;Buffer not null terminated&quot;. 2nd try. The buffer is not
+required to be null terminated!</li>
+<li>coders/pict.c (ReadPICTImage): 10171 &quot;Resource leak&quot;. 2nd try.</li>
+<li>coders/wmf.c (util_set_brush): Silence Coverity 44739
+&quot;Out-of-bounds access&quot;. 2nd try.</li>
+</ul>
+</blockquote>
+<p>2015-03-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c (SetLogEventMask): Silence Coverity 10069 &quot;Value
+not atomically updated&quot;. Logging initialization is done
+single-threaded entirely in InitializeLogInfo() now.</li>
+</ul>
+</blockquote>
+<p>2015-03-28 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): Attempt to quiet Coverity
+44734 &quot;Data race condition&quot; by freeing mng_info-&gt;png_pixels
+and mng_info-&gt;quantum_scanline separately from MngInfoFreeStruct.</li>
+</ul>
+</blockquote>
+<p>2015-03-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/widget.c (XEditText): Silence Coverity 10072 &quot;Overlapping
+buffer in memory copy&quot;</li>
+<li>coders/locale.c (ReadConfigureFile): Silence Coverity 10075
+&quot;Overlapping buffer in memory copy&quot;.</li>
+<li>magick/xwindow.c (MagickXMakeWindow): Silence Coverity 10076
+&quot;Overlapping buffer in memory copy&quot;.</li>
+<li>coders/dcm.c (funcDCM_TransferSyntax): Silence Coverity 10083
+&quot;Unchecked return value&quot;.</li>
+<li>magick/static.c (ExecuteStaticModuleProcess): Silence Coverity
+10082 &quot;Unchecked return value&quot;.</li>
+<li>coders/cals.c (ReadCALSImage): Silence Coverity 10086 &quot;Unchecked
+return value from library&quot;.
+(ReadCALSImage): Silence Coverity 10085 &quot;Unchecked return value&quot;.
+(ReadCALSImage): Silence Coverity 10084 &quot;Unchecked return value
+from library&quot;.</li>
+<li>magick/enhance.c (ModulateImage): Silence Coverity 10087
+&quot;Unchecked return value&quot;.</li>
+</ul>
+</blockquote>
+<p>2014-03-24 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+* coders/wpg.c More paranoa in checking ReadBlobByte() negative return.</blockquote>
+<p>2015-03-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (Generate8BIMAttribute): Silence Coverity
+10195 &quot;Argument cannot be negative&quot;.</li>
+<li>Magick++/lib/Image.cpp (syncPixels): Silence Coverity 44722
+&quot;Unchecked return value&quot;.
+(fontTypeMetrics): Silence Coverity 44721 &quot;Unchecked return
+value&quot;.</li>
+<li>magick/render.c (ConvertPathToPolygon): Silence Coverity 10120
+&quot;Dereference after null check&quot;.</li>
+<li>magick/effect.c (EmbossImage): Silence Coverity 10114
+&quot;Dereference after null check&quot;.
+(AdaptiveThresholdImage): Silence Coverity 10118 &quot;Explicit null
+dereferenced&quot;.</li>
+<li>coders/msl.c (MSLPushImage): Silence Coverity 10128 &quot;Dereference
+after null check&quot;.</li>
+<li>magick/render.c (DrawPolygonPrimitive): Silence Coverity 10136
+&quot;Dereference after null check&quot;.</li>
+<li>wand/drawing_wand.c (DrawSetStrokeDashArray): Silence Coverity
+10117 &quot;Dereference after null check&quot;.</li>
+<li>magick/draw.c (DrawSetStrokeDashArray): Silence Coverity 10150
+&quot;Dereference after null check&quot;.</li>
+<li>wand/drawing_wand.c (DrawPushGraphicContext): Silence Coverity
+10151 &quot;Dereference after null check&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-03-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c (parse8BIM): Silence Coverity 10159 &quot;Explicit null
+dereferenced&quot;.
+(parse8BIMW): Silence Coverity 10144 &quot;Explicit null dereferenced&quot;.</li>
+<li>coders/uil.c (WriteUILImage): Silence Coverity 10202
+&quot;Dereference after null check&quot;. In fact, UIL output was not
+working at all due to this bug.</li>
+<li>magick/xwindow.c (MagickXMakeImage): Silence Coverity 44727
+&quot;Dereference after null check&quot;.</li>
+<li>Magick++/lib/Image.cpp (colorMapSize): Silence Coverity 44728
+&quot;Dereference after null check&quot;.</li>
+<li>coders/vid.c (ReadVIDImage): Silence Coverity 44730 &quot;Explicit
+null dereferenced&quot;.</li>
+<li>coders/mpc.c (ReadMPCImage): Silence Coverity 44732 &quot;Dereference
+after null check&quot;.</li>
+<li>Magick++/lib/Image.cpp (signature): Silence Coverity 44735
+&quot;Dereference null return value&quot;.</li>
+<li>coders/ps.c (ReadPSImage): Ghostscript options concatenation
+should be more secure against buffer overflow.</li>
+<li>coders/pdf.c (ReadPDFImage): Applied patch by Chris Gilling such
+that '-define pdf:stop-on-error=true' will stop PDF processing
+immediately upon an error.
+(ReadPDFImage): Ghostscript options concatenation should be more
+secure against buffer overflow.</li>
+</ul>
+</blockquote>
+<p>2015-03-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/animate.c (MagickXAnimateImages): Silence Coverity 44736
+&quot;Dereference null return value&quot;. Also fixed apparent memory leak
+that Coverity did not notice.</li>
+<li>coders/fits.c (ReadFITSImage): Silence Coverity 10209
+&quot;Dereference before null check&quot;.</li>
+<li>magick/color_lookup.c (ReadColorConfigureFile): Silence Coverity
+44743 &quot;Dereference before null check&quot;.</li>
+<li>magick/xwindow.c (MagickXMakeImage): Silence Coverity 44745
+&quot;Dereference before null check&quot;.</li>
+<li>coders/pict.c (ReadPICTImage): Hopefully address consequences of
+Coverity 10292 &quot;Untrusted loop bound&quot; although it will likely
+still complain.</li>
+<li>magick/utility.c (LocaleCompare, LocaleNCompare): Try to create
+an implementation that Coverity won't label an &quot;tainted sink&quot;, and
+therefore result in a Coverity &quot;Use of untrusted scalar value&quot;
+report whenever a string from an external source is compared. The
+original implementations are not believed to be faulty.</li>
+</ul>
+</blockquote>
+<p>2015-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ProcessBatchOptions): Silence Coverity 10080
+&quot;Buffer not null terminated&quot;.</li>
+<li>magick/widget.c (MagickXConfirmWidget): Silence Coverity 10089
+&quot;Copy-paste error&quot;. This is an amazing find by Coverity.</li>
+<li>magick/xwindow.c (MagickXImportImage): Silence Coverity 10207
+&quot;Array compared against 0&quot;.</li>
+<li>magick/quantize.c (GrayscalePseudoClassImage): Silence Coverity
+10256 &quot;Wrong sizeof argument&quot;.</li>
+<li>coders/tiff.c (ReadTIFFImage): Fix Coverity 44747 and 44748
+&quot;Extra sizeof expression&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-03-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Magick++/Include.h (Magick): Fix compilation with
+'clang' under Linux. Build was broken yesterday.</li>
+<li>coders/tiff.c (QuantumTransferMode): Fix reading Old JPEG and
+YCbCr sample images from libtiff pics-3.8.0.tar.gz image file
+collection. There was a regression for YCbCr added in last
+release.</li>
+</ul>
+</blockquote>
+<p>2015-03-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (ReadBMPImage): Fix Coverity 44726 &quot;Division or
+modulo by float zero&quot;. I don't think that this can actually
+happen due to prior checks.</li>
+<li>magick/xwindow.c (MagickXMakeWindow): Silence Coverity 10281
+&quot;Copy into fixed size buffer&quot;.</li>
+<li>coders/pdf.c (ReadPDFImage): Silence Coverity 10241 &quot;Copy into
+fixed size buffer&quot;.</li>
+<li>magick/type.c (ReadTypeConfigureFile): Silence Coverity 10242
+&quot;Copy into fixed size buffer&quot;.</li>
+<li>magick/utility.c (GetPathComponent): Silence Coverity 10263
+&quot;Copy into fixed size buffer&quot;.</li>
+<li>coders/txt.c (ReadTXTImage): Silence Coverity 10287 &quot;Copy into
+fixed size buffer&quot;.</li>
+<li>coders/ps.c (WritePSImage): Silence Coverity 10289 &quot;Copy into
+fixed size buffer&quot;.</li>
+<li>magick/delegate.c (ReadConfigureFile): Silence Coverity 10297
+&quot;Copy into fixed size buffer&quot;.</li>
+<li>magick/log.c (ReadLogConfigureFile): Silence Coverity 10300
+&quot;Copy into fixed size buffer&quot;.</li>
+<li>coders/ps3.c (WritePS3Image): Silence Coverity 10303 &quot;Copy into
+fixed size buffer&quot;.</li>
+<li>coders/pdf.c (WritePDFImage): Silence Coverity 10304 &quot;Copy into
+fixed size buffer&quot;.</li>
+<li>coders/ps.c (ReadPSImage): Silence Coverity 10306 &quot;Copy into
+fixed size buffer&quot;.</li>
+<li>coders/msl.c (MSLStartElement): Silence Coverity 10308 &quot;Copy
+into fixed size buffer&quot;.</li>
+<li>coders/ps2.c (WritePS2Image): Silence Coverity 10309 &quot;Copy into
+fixed size buffer&quot;.</li>
+<li>Magick++/lib/Geometry.cpp (operator): Silence Coverity 44749
+&quot;Copy into fixed size buffer&quot;.</li>
+<li>Magick++/lib/Image.cpp (annotate): Silence Coverity 44750 &quot;Copy
+into fixed size buffer&quot;.</li>
+<li>coders/ept.c (ReadEPTImage): Silence Coverity 44751 &quot;Copy into
+fixed size buffer&quot;.</li>
+<li>coders/wmf.c (ipa_device_begin): Silence Coverity 44753 &quot;Copy
+into fixed size buffer&quot;.
+(lite_font_map): Silence Coverity 44752 &quot;Copy into fixed size
+buffer&quot;.</li>
+<li>magick/random.c (InitializeMagickRandomKernel): Silence Coverity
+10091 &quot;Don't Call&quot; in the case where /dev/random is available.</li>
+<li>coders/mpeg.c (WriteMPEGParameterFiles): Fix Coverity 10190
+&quot;Resource leak&quot;. File descriptor was leaked under certain error
+conditions.</li>
+<li>coders/wpg.c (UnpackWPG2Raster): Fix Coverity 10312
+&quot;Uninitialized scalar variable&quot; gripe.</li>
+<li>magick/utility.c (ListFiles): Possibly address
+Coverity 10245 &quot;Sizeof not portable&quot; gripe.</li>
+<li>magick/widget.c (MagickXFontBrowserWidget): Possibly address
+Coverity 10323 &quot;Sizeof not portable&quot; gripe.</li>
+<li>coders/mat.c (WriteMATLABImage): FormatString() requires a
+buffer of MaxTextExtent bytes. Use sprintf instead. Fix for
+Coverity issue 10170.</li>
+<li>Magick++/lib/Geometry.cpp (string): FormatString() requires a
+buffer of MaxTextExtent bytes. Fix for Coverity issue 44737.</li>
+<li>coders/wmf.c (draw_pattern_push): FormatString() requires a
+buffer of MaxTextExtent bytes. Fix for Coverity issue 44741.
+(ipa_device_begin): FormatString() requires a buffer of
+MaxTextExtent bytes. Fix for Coverity issue 44740.
+(util_set_brush): FormatString() requires a buffer of
+MaxTextExtent bytes. Fix for Coverity issue 44739.
+(ipa_region_clip): FormatString() requires a buffer of
+MaxTextExtent bytes. Fix for Coverity issue 44738.</li>
+</ul>
+</blockquote>
+<p>2015-03-15 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WritePNGImage) Avoid a Coverity gripe about
+potential NULL dereference (actually it is impossible because
+png_error() does not return. Fix for Coverity gripe 44731.</li>
+<li>coders/png.c (WritePNGImage) Avoid a null pointer dereference
+while logging inherited color_type. Fix for Coverity issue 10185.</li>
+<li>coders/png.c (WriteOneJNGImage) Avoid possible unintended sign
+extension. Fix for Coverity issue 44744.</li>
+<li>coders/png.c (WriteOnePNGImage) Quiet a false Coverity warning
+about dereference after NULL check. Fix for Coverity issue 44729.</li>
+<li>coders/png.c (ReadOnePNGImage): Redid the &quot;Respect the
+PixelsResource limit&quot; patch of March 7, using unsigned arithmetic
+to determine the width limit. Sometimes the calculated
+width limit was incorrectly zero.</li>
+</ul>
+</blockquote>
+<p>2015-03-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Fix problems with reading
+filenames that include a colon. Resolves SourceForge bug #294
+&quot;display and convert (probably other things too) choke on
+filenames with colons in&quot;.</li>
+<li>magick/utility.c (GetPathComponent): Fix SubImagePath
+extraction. Fixes SourceForge bug #66 &quot;converting runs slowly when
+subimage is specified&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-03-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc (-geometry): Document the significance of 'x'
+as used in a geometry specification. In particular, document that
+if width is specified without a trailing 'x' that height is set to
+width. This is in response to SourceForge bug #296 &quot;Strange
+-resize WIDTH results with version 1.3.21&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-03-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (GlobExpression): Remove use of IsSubimage().</li>
+<li>magick/image.c (IsSubimage): Re-implement with a more robust
+solution. Combined with fixes to ps.c and pdf.c, allows selecting
+specific pages, as well as re-ordering.</li>
+<li>coders/ps.c (ReadPSImage): Set image frame scene ids
+appropriately.</li>
+<li>coders/pdf.c (ReadPDFImage): Set image frame scene ids
+appropriately.</li>
+<li>magick/utility.c (TranslateTextEx): -format %Q should report
+JPEG quality estimate if it is available. Resolves SourceForge
+bug #293 &quot;gm identify bug?&quot;.</li>
+<li>doc/options.imdoc: Documented JPEG-specific -format tags.</li>
+</ul>
+</blockquote>
+<p>2015-03-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Image.cpp (repage): New method to reset page
+settings. Contributed by Dirk Lemstra.</li>
+</ul>
+</blockquote>
+<p>2015-03-07 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): Respect the PixelsResource
+limit.</li>
+<li>coders/png.c (ReadOnePNGImage): Moved quantum_scanline
+and png_pixels into the MngInfo struct. This prevents
+memory leaks when reading malformed PNG images, but unfortunately
+triggers a new complaint about a possible race condition.</li>
+<li>coders/png.c (ReadOnePNGImage): Removed two superflous calls to
+CloseBlob().</li>
+<li>coders/png.c (ReadOnePNGImage): Do the allocation and free of
+quantum_scanline outside the &quot;pass&quot; loop, i.e., do it once per
+image rather than once per pass while decoding interlaced PNG
+images. Log these when -debug coders is enabled.</li>
+<li>coders/png.c: Fixed typo recently introduced in the JNG reader
+(status != MagickFalse should be status == MagickFalse).</li>
+</ul>
+</blockquote>
+<p>2015-03-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xwd.c (ReadXWDImage): Fix memory leaks in error paths.</li>
+<li>coders/xpm.c (ReadXPMImage): Fix memory leaks in error paths.</li>
+<li>coders/miff.c (ReadMIFFImage): Fix memory leak of Image in error
+case.
+(ReadMIFFImage): Fix memory leaks of zlib and bzlib2 context in
+error path which reports decompression failure.</li>
+<li>coders/bmp.c (ReadBMPImage): BMP reader was wrongly rejecting
+RLE-compressed files as being too small. Fixes SourceForge bug
+#295 &quot;1.3.21 identify regression&quot;. Also fixed 'ping' support code
+which was still reading the pixels in 'ping' mode.
+(ReadBMPImage): Fix memory leak when BMP is handled as a sequence.</li>
+</ul>
+</blockquote>
+<p>2015-03-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/palm.c (ReadPALMImage): PALM reader now applies PALM's
+special non-linear colormap if the file does not provide a custom
+colormap. Custom colormap size is verified to not exceed image
+colors. Added logging statements regarding colormap.</li>
+</ul>
+</blockquote>
+<p>2015-02-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/index.rst: Update for 1.3.21 release.</li>
+<li>www/Changes.rst: Update for 1.3.21 release.</li>
+<li>NEWS.txt: Update NEWS for 1.3.21 release.</li>
+<li>version.sh: Bump/adjust library versioning.</li>
+</ul>
+</blockquote>
+<p>2015-02-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/delegate.c: Fix compilation under Cygwin. Thanks to Marco
+Atzeri for advising us of this problem.</li>
+</ul>
+</blockquote>
+<p>2015-02-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/error.h (ThrowReaderException): More significant
+exceptions (e.g. errors) should overwrite less significant
+exceptions (e.g. warnings) thrown earlier.</li>
+<li>coders/bmp.c (ReadBMPImage): Detect 32-bit integer overflows and
+other annoyances caused by intentionally broken files. Also, only
+warn if the file header claims the file is larger than it is since
+this is a benign issue.</li>
+<li>magick/blob.c (OpenBlob): Fix &quot;magic header bytes&quot; log message
+count value.</li>
+</ul>
+</blockquote>
+<p>2015-02-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated NEWS with more changes.</li>
+<li>Magick++/lib/Magick++/Include.h (Magick): Add GetImageGeometry
+to MagickLib namespace in order to avoid a compilation problem
+noticed with Visual C++ 6.0.</li>
+</ul>
+</blockquote>
+<p>2014-02-22 Jaroslav Fojtik &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>VisualMagickconfigureconfigure.cpp Fixed crash.</dt>
+<dd>Renamed debug to configure_d.exe to prevent mess.</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2015-02-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (InitializeMagick): Invoke
+NTInitializeExceptionHandlers() under Windows.</li>
+<li>magick/nt_base.c (NTInitializeExceptionHandlers): Add a new
+private function which disables pop-up Windows on exceptions and
+registers a handler for Windows exceptions to clean up temporary
+files prior to program exit.</li>
+<li>magick/magick.c (PanicDestroyMagick): Use
+PurgeTemporaryFilesAsyncSafe() rather than PurgeTemporaryFiles().
+(InitializeMagickSignalHandlers): Always register for SIGINT, even
+under Microsoft Windows.</li>
+<li>magick/tempfile.c (PurgeTemporaryFilesAsyncSafe): New private
+function to clean up temporary files prior to program exit.
+Async-safe so it can be safely called from a signal handler.
+Intentionally leaks memory.</li>
+</ul>
+</blockquote>
+<p>2015-02-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GenerateEXIFAttribute): Fix crash while
+parsing corrupt EXIF which was reported by Stijn Sanders on
+2015-02-17.</li>
+<li>Magick++/lib/{Blob.cpp, Image.cpp}: Incorrect lock scope
+resulted in Magick++ locking not actually working to protect
+critical sections in spite of no detected problems with locking
+these past 16 years. Problem was detected using the
+misc-unused-raii check from clang-tidy and was reported by Hyrum
+Wright.</li>
+<li>coders/palm.c (ReadPALMImage): Add header logging to writer.
+Writer still seeks and overwrites its own header so logging is not
+entirely accurate yet.</li>
+</ul>
+</blockquote>
+<p>2015-02-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>libtool: Update GNU libtool to 2.4.6.</li>
+<li>coders/palm.c (ReadPALMImage): Fix support for transparency in
+PALM reader.</li>
+</ul>
+</blockquote>
+<p>2015-02-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/palm.c (ReadPALMImage): Major re-work of PALM reader.
+More log message improvements. More header validation.</li>
+</ul>
+</blockquote>
+<p>2015-02-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/palm.c (ReadPALMImage): Improve log messages. Add more
+header validation. Check image pixel limits. Support 'ping'
+mode.</li>
+</ul>
+</blockquote>
+<p>2015-02-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/palm.c (ReadPALMImage): PALM reader now supports 1, 2, 4,
+8, and 16-bit test files we were able to generate using
+'pnmtopalm'. A progress monitor was added. Memory leaks in error
+paths were fixed.</li>
+</ul>
+</blockquote>
+<p>2015-02-12 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Insert &quot;if (QuantumTick(...))&quot; ahead of
+each &quot;if (!MagickMonitorFormatted(...)&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-02-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/rla.c (ReadRLAImage): Assure that header ASCII strings
+are properly terminated. Resolves Coverity CID 10322.</li>
+</ul>
+</blockquote>
+<p>2015-02-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.h (STDERR_FILENO): Provide definitions for
+standard POSIX file numbers so that Visual Studio should compile.
+Fixes SourceForge bug #291 &quot;STDERR_FILENO (used in magick.c) is
+not defined under Windows&quot;</li>
+</ul>
+</blockquote>
+<p>2015-02-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Image.cpp (Image::quiet()): Patch by Dirk Lemstra
+to support silencing warnings in Magick++. Adds a quiet() method
+which blocks (ignores) warning exceptions when passed a true
+argument. Warning exceptions are still generated by default.</li>
+<li>coders/tiff.c: Support '-define tiff:report-warnings=true' to
+enable that warnings reported by libtiff are thrown as warning
+exceptions so that they may be caught or will be reported at the
+gm command-line.</li>
+</ul>
+</blockquote>
+<p>2015-02-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (WriteTIFFImage): Use YCbCr encoding when JPEG
+compression is requested for an RGB image.</li>
+</ul>
+</blockquote>
+<p>2015-02-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (QuantumTransferMode): Fix reading or writing
+planar min-is-white or min-is-black images with an associated
+alpha channel.</li>
+</ul>
+</blockquote>
+<p>2015-02-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xpm.c (ReadXPMImage): Reading empty XPM file should not
+cause bad memory access.</li>
+<li>coders/gif.c (DecodeImage): Assure that GIF decoder does not use
+unitialized data.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Verify that we support the number
+of output components before proceeding to decode the image.</li>
+</ul>
+</blockquote>
+<p>2015-01-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): MIFF needs to stop spinning if
+zlib or bzlib report an error while decompressing. Solves problem
+with file provided by Jodie Cunningham on 2015-01-25.</li>
+<li>coders/vicar.c (ReadVICARImage): Fix Vicar reader's dogged
+determination to continue reading when there is nothing left to
+read. Solves problem with file provided by Jodie Cunningham on
+2015-01-25.</li>
+<li>magick/magick.c (PanicDestroyMagick): Replace memory allocation
+functions with dummy functions rather than NULL pointers.
+(InitializeMagickSignalHandlers): Register
+MagickPanicSignalHandler() for SIGSEGV.
+(MagickPanicSignalHandler): Produce an informative message for the
+user.
+(MagickSignalHandlerMessage): Include more detailed information
+from the signal handler via a common routine used by default
+signal handlers.</li>
+</ul>
+</blockquote>
+<p>2015-01-25 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (ReadBMPImage): An attempt to address CID 10291.</li>
+</ul>
+</blockquote>
+<p>2015-01-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/nt_base.c (Exit): Changed to return 'void'. Function can
+not return a value if it does not return.</li>
+<li>magick/error.c (DefaultFatalErrorHandler): Invoke
+PanicDestroyMagick() rather than DestroyMagick(). If we are
+really that short on memory, DestroyMagick() might not work.</li>
+<li>magick/magick.c (MagickPanicSignalHandler): Only use async-safe
+functions in signal handler.
+(PanicDestroyMagick): New function for emergency release of
+persistent resources just prior to program exit. Async-safe and
+does not acquire or release any heap memory.</li>
+<li>magick/export.c: Eliminate two 'clang' warnings.</li>
+</ul>
+</blockquote>
+<p>2015-01-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pdb.c (ReadPDBImage): Fix typo.</li>
+<li>coders/cineon.c (ReadCINEONImage): Enforce that Cineon image
+info channels is valid. Solves problem with file provided by
+Jodie Cunningham on 2015-01-24</li>
+<li>coders/fits.c (ReadFITSImage): Enforce valid bits-per-pixel
+values. Add detailed header logging. Solves problem with file
+provided by Jodie Cunningham on 2015-01-24</li>
+</ul>
+</blockquote>
+<p>2015-01-22 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadPNGImage): Check length of various MNG
+chunks before using the chunk data.</li>
+<li>coders/png.c (WriteOnePNGImage): Use png_error() instead of
+throwing an exception so cleanup in the setjmp block can happen,
+including unlocking the semaphore. Addresses Coverity CID 10184.</li>
+</ul>
+</blockquote>
+<p>2015-01-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gif.c (WriteGIFImage): Don't use an unchecked value from
+GetImageAttribute(), even if the access succeeded before.
+Resolves Coverity CID 10219.</li>
+<li>coders/dpx.c (StringToAttribute): Make sure that string is not
+accidentally shortened by one character if it occupies the full
+field size.
+(ReadDPXImage): Validate that the bits per sample claimed by the
+file header is a supported depth before using it further in the
+code. This might resolve Coverity CID 10071 &quot;Bad shift
+operation&quot;.
+(ReadDPXImage): Check for EOF while reading forward to element
+data. Might solve Coverity CID 10305.</li>
+<li>coders/dib.c (ReadDIBImage): Resolve Coverity CID 10228 &quot;Integer
+overflowed argument&quot;.
+(ReadDIBImage): Hopefully resolve Coverity CID 10268 &quot;Various&quot;,
+which is primarily about placing too much trust in the claimed
+number of colors.</li>
+<li>coders/pnm.c (WritePNMImage): Fix overwrite of status by
+progress monitor. Remaining issues may lurk within. May resolve
+Coverity CID 10288.</li>
+<li>coders/pdb.c: Resolve Coverity CID 11173 &quot;Buffer not null
+terminated&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-01-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (GetMagickInfoArray): Resolve Coverity CID 10212
+&quot;Missing unlock&quot;.</li>
+<li>magick/colormap.c (ReplaceImageColormap): Allocate new image
+colormap up front in order to avoid the possibility that we are
+left with an image with no colormap due to memory allocation
+failure. If there is a memory allocation failure, then the
+original colormap is preserved. Resolves Coverity CID 10194
+&quot;Dereference after null check&quot;.</li>
+<li>magick/utility.c (MagickStripSpacesFromString): New private
+utility function to strip spaces from a string.</li>
+<li>magick/color_lookup.c (GetColorInfoArray): Resolves Coverity CID
+10231 &quot;Missing unlock&quot;
+(ReadColorConfigureFile): Resolves Coverity CID 10261 &quot;Use of
+untrusted scalar value&quot;
+(GetColorInfo): Resolves Coverity CID 10077 &quot;Overlapping buffer in
+memory copy&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-01-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadOnePNGImage): Use png_error() instead of
+throwing an exception so cleanup in the setjmp block can happen,
+including unlocking the semaphore. Resolves Coverity CID 10232.</li>
+<li>coders/png.c (ReadOnePNGImage): Moved a logging statement into a
+block where &quot;attribute&quot; has been checked for NULL. Resolves
+Coverity CIDs 10185 and 10187.</li>
+<li>coders/png.c (ReadMNGImage): Fixed a cut-and-paste typo
+(change_delay should be change_timeout) reported by Coverity
+CID 10090.</li>
+</ul>
+</blockquote>
+<p>2015-01-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (CloneImage): The definition is poor as to what a
+non-orphan clone should do. However, the definition surely does
+not include crashing the software or supplanting the original
+image in an image list. Clone image blob and previous/next
+pointers but do not supplant original image in list. Resolves
+Coverity CID 10155.</li>
+</ul>
+</blockquote>
+<p>2015-01-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (WriteRowSamples): Ensure that callback function is
+always defined. Resolves Coverity CID 10122.
+(ReadRowSamples): Ensure that callback function is always
+defined. Resolves Coverity CID 10125.</li>
+<li>magick/random.c (InitializeMagickRandomKernel): Avoid possible
+double-close of file. Resolves Coverity CID 10257.</li>
+<li>coders/histogram.c (WriteHISTOGRAMImage): Avoid possible divide
+by zero exception. Resolves Coverity CID 10107.</li>
+<li>magick/error.c (MagickFatalError): Document that
+MagickFatalError() is not supposed to return (program must quit)
+and add GCC/Clang hints to that effect.</li>
+<li>magick/bit_stream.c (BitAndMasks): Avoid possible access
+one-beyond end of BitAndMasks array. It is not clear if there is
+a possible bug with 32-bit quantums. If there is a bug, it has
+not been noticed via testing. Resolves Coverity CID 10213.</li>
+<li>magick/tempfile.c (AcquireTemporaryFileDescriptor): Avoid buffer
+overrun in the case of an astonishingly long environment variable
+string. Resolves Coverity CID 10267.
+(AddTemporaryFileToList): Use strlcpy() rather than strlcpy(). In
+practice, should not make a difference. Will quiet Coverity CID
+10321.</li>
+<li>magick/command.c (GMCommandSingle): Don't use the address of a
+stack allocation to update argv[0]. Removed updating argv[0] until
+a better design can be found. Resolves Coverity CID 10223.
+(GMCommandSingle): Plan B: Use static allocation from
+SetClientName() to both store the new command name and provide
+storage for argv[0].</li>
+<li>magick/utility.c (SystemCommand): Fix possible overwrite of
+memory location due to uninitialized 'end' pointer. Resolves
+Coverity CID 10251.</li>
+<li>magick/blob.c (WriteBlobFile): Was not closing file in certain
+error conditions. Resolves Coverity CID 10237.</li>
+<li>coders/cineon.c (ReadCINEONImage): Don't trust file header so
+much. Resolves Coverity CIDs 10079, 10310, 10325.</li>
+<li>coders/art.c (ReadARTImage): Fix signed vs unsigned comparison
+caused by earlier changes.</li>
+</ul>
+</blockquote>
+<p>2014-01-17 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c Do not execute wpg raster read in ping mode.</li>
+</ul>
+</blockquote>
+<p>2014-01-15 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Properly deallocating zip structures.</li>
+</ul>
+</blockquote>
+<p>2015-01-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sfw.c (ReadSFWImage): Fix pixel cache access errors in
+'ping' mode.</li>
+</ul>
+</blockquote>
+<p>2015-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wmf.c (ReadWMFImage): Fix memory leak in 'ping' mode and
+some error paths.</li>
+</ul>
+</blockquote>
+<p>2015-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jbig.c (ReadJBIGImage): Fix memory leak in 'ping' mode.</li>
+<li>magick/delegate.c (InvokeDelegate): Fix memory leak of argument
+list when invoking external program via MagickSpawnVP().</li>
+</ul>
+</blockquote>
+<p>2015-01-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (InitializeMagickResources): Base image width
+and height default limits on the range of a 32-bit signed integer,
+even for 64-bit builds. These limits are still beyond what most
+computers in the world can handle. Limits can be increased by the
+user.</li>
+<li>coders/xwd.c (ReadXWDImage): Check image size limits
+immediately.</li>
+<li>coders/xc.c (ReadXCImage): Check image size limits immediately.</li>
+<li>coders/webp.c (ReadWEBPImage): Check image size limits
+immediately.</li>
+<li>coders/viff.c (ReadVIFFImage): Check image size limits
+immediately.</li>
+<li>coders/vicar.c (ReadVICARImage): Check image size limits
+immediately.</li>
+<li>coders/txt.c (ReadTXTImage): Check image size limits
+immediately.</li>
+<li>coders/ttf.c (ReadTTFImage): Check image size limits
+immediately.</li>
+<li>coders/tim.c (ReadTIMImage): Check image size limits
+immediately.</li>
+<li>coders/tiff.c (ReadTIFFImage): Check image size limits
+immediately.</li>
+<li>coders/tga.c (ReadTGAImage): Check image size limits
+immediately.</li>
+<li>coders/sgi.c (ReadSGIImage): Check image size limits
+immediately.</li>
+<li>coders/sct.c (ReadSCTImage): Check image size limits
+immediately.</li>
+<li>coders/rle.c (ReadRLEImage): Check image size limits
+immediately.</li>
+<li>coders/rla.c (ReadRLAImage): Check image size limits
+immediately.</li>
+<li>coders/psd.c (ReadPSDImage): Check image size limits
+immediately.</li>
+<li>coders/pnm.c (ReadPNMImage): Check image size limits
+immediately.</li>
+<li>coders/pix.c (ReadPIXImage): Check image size limits
+immediately.</li>
+<li>coders/pict.c (ReadPICTImage): Check image size limits
+immediately.</li>
+<li>coders/pdb.c (ReadPDBImage): Check image size limits
+immediately.</li>
+<li>coders/pcx.c (ReadPCXImage): Check image size limits
+immediately.</li>
+<li>coders/pcd.c (ReadPCDImage): Check image size limits
+immediately.</li>
+<li>coders/otb.c (ReadOTBImage): Check image size limits
+immediately.</li>
+<li>coders/null.c (ReadNULLImage): Check image size limits
+immediately.</li>
+<li>coders/mvg.c (ReadMVGImage): Check image size limits
+immediately.</li>
+<li>coders/mtv.c (ReadMTVImage): Check image size limits
+immediately.</li>
+<li>coders/mpc.c (ReadMPCImage): Check image size limits
+immediately.</li>
+<li>coders/miff.c (ReadMIFFImage): Check image size limits
+immediately.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Check image size limits
+immediately.</li>
+<li>coders/jp2.c (ReadJP2Image): Check image size limits
+immediately.</li>
+<li>coders/jbig.c (ReadJBIGImage): Check image size limits
+immediately.</li>
+<li>coders/hdf.c (ReadHDFImage): Check image size limits
+immediately.</li>
+<li>coders/gif.c (ReadGIFImage): Check image size limits
+immediately.</li>
+<li>coders/fpx.c (ReadFPXImage): Check image size limits
+immediately.</li>
+<li>coders/fax.c (ReadFAXImage): Check image size limits
+immediately.</li>
+<li>coders/dpx.c (ReadDPXImage): Check image size limits
+immediately.</li>
+<li>coders/dps.c (ReadDPSImage): Check image size limits
+immediately.</li>
+<li>coders/dib.c (ReadDIBImage): Check image size limits
+immediately.</li>
+<li>coders/dcm.c (ReadDCMImage): Check image size limits
+immediately.</li>
+<li>coders/cut.c (ReadCUTImage): Check image size limits
+immediately.</li>
+<li>coders/cineon.c (ReadCINEONImage): Check image size limits
+immediately.</li>
+<li>coders/avs.c (ReadAVSImage): Check image size limits
+immediately.</li>
+<li>coders/art.c (ReadARTImage): Check image size limits
+immediately.</li>
+<li>coders/sun.c (ReadSUNImage): Check image size limits in advance
+of allocating memory for pixels.</li>
+<li>coders/bmp.c (ReadBMPImage): Check image size limits in advance
+of allocating memory for pixels.</li>
+<li>coders/sun.c (ReadSUNImage): There is no definition for Sun map
+type RMT_RAW so it can not be supported. Update DirectClass
+pixels directly rather using SyncImage(). Problem was reported by
+Jodie Cunningham.</li>
+</ul>
+</blockquote>
+<p>2015-01-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pict.c (ReadPICTImage): Fix PICT reader crash when
+reading corrupted file.</li>
+<li>coders/sun.c (ReadSUNImage): Sun reader was still not as robust
+as it should be. Now it is.</li>
+</ul>
+</blockquote>
+<p>2014-01-10 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c Fixed reading behind EOF issue.</li>
+</ul>
+</blockquote>
+<p>2015-01-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (LSBPackedU32WordToOctets): Fix typo which adds
+severe corruption to encoded little-endian 32-bit packed output.
+The good news is that since the corruption is severe, it is easily
+visually detected. The problem has corrupted all such
+(little-endian 10-bit) output since it was originally implemented
+on 2007-06-17 (changeset 11686, first released in GraphicsMagick
+1.1.8). GraphicsMagick preserves the endianness of input DPX
+files by default, defaults to big-endian, and DPX files are
+commonly big-endian, so this problem may not have occured for many
+usages. Problem was reported by Steve Dabner on the
+GraphicsMagick discussion mailing list.</li>
+</ul>
+</blockquote>
+<p>2015-01-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (MagickPanicSignalHandler): Print a message in
+the case of signals SIGXCPU and SIGXFSZ.</li>
+<li>coders/bmp.c (ReadBMPImage): Don't hang in endless loop if EOF
+is encountered while checking for &quot;BA&quot; header.</li>
+<li>coders/icon.c (ReadIconImage): Limit icon image allocation size.</li>
+</ul>
+</blockquote>
+<p>2015-01-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/icon.c (ReadIconImage): Removed all of the
+previously-existing DIB reading code from icon.c and use new
+&quot;ICODIB&quot; reader to read DIB icons, or the PNG reader to read PNG
+icons.</li>
+<li>coders/dib.c (ReadDIBImage): Added an &quot;ICODIB&quot; coder for
+internal use which reads a Windows BMP 3 DIB followed by a Windows
+ICO alpha mask. This allows existing DIB code to be used to read
+ICO directory entries.</li>
+</ul>
+</blockquote>
+<p>2015-01-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/icon.c: The Windows ICO reader is now more robust. Still
+a work in progress since some files still can not be read or read
+incorrectly.</li>
+</ul>
+</blockquote>
+<p>2015-01-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/resource.c (ListMagickResourceInfo): &quot;kilo&quot; for binary
+prefixes is supposed to be &quot;Ki&quot;.</li>
+<li>magick/utility.c (FormatSize): &quot;kilo&quot; for binary prefixes is
+supposed to be &quot;Ki&quot;.</li>
+</ul>
+</blockquote>
+<p>2015-01-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Use WidthResource and HeightResource instead
+of fixed 1-million limit for rows and columns.</li>
+</ul>
+</blockquote>
+<p>2015-01-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/utility.c (FormatSize): Add 'i' to value range
+identifiers since these are all in units of 2^10 rather than 1000.</li>
+<li>magick/pixel_cache.c (CheckImagePixelLimits): Fix typo and
+produce an informative error message.</li>
+<li>magick/resource.c: Added support for Image width and height
+pixels resource limits.</li>
+<li>magick/resource.h (ResourceType): New resource enumerations
+WidthResource and HeightResource.</li>
+<li>magick/enum_strings.c (StringToResourceType): Added support for
+parsing '-limit Width' and '-limit Height'.</li>
+<li>magick/pixel_cache.c (CheckImagePixelLimits): New function to
+test image to see if it exceeds pixels limits.</li>
+<li>coders/viff.c (ReadVIFFImage): Make the VIFF reader robust with
+detecting and reporting problems.</li>
+</ul>
+</blockquote>
+<p>2014-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Rotate Changelog for new year. Update documentation copyrights
+for new year.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2015.rst b/www/ChangeLog-2015.rst
new file mode 100644
index 0000000..df06148
--- /dev/null
+++ b/www/ChangeLog-2015.rst
@@ -0,0 +1,2066 @@
+2015-12-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - ttf: Update bundled freetype to release 2.6.2.
+
+ - libxml: Update bundled libxml2 to release 2.9.3.
+
+2015-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - webp: Updated bundled libwebp to release 0.4.4.
+
+ - png: Updated bundled libpng to release 1.6.19.
+
+2015-11-05 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOnePNGImage): Added "volatile" to
+ several declarations to stop "might be clobbered" warnings.
+
+2015-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Update NEWS for 1.3.23 release.
+
+2015-11-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (IdentifyImageCommand): Fix problem that
+ identify with -format "%A" does not always report correct answer
+ due to insufficient analysis of image. Fixes SourceForge bug #326
+ "gm identify: transparency detection bug ".
+
+2015-11-05 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOnePNGImage): Restored a "volatile"
+ declaration that was accidentally deleted on 2015-11-03.
+
+2015-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Add checks for 'ps2write' and 'eps2write' as
+ Ghostscript Postscript and Encapsulated Postscript
+ writers. Resolves issue reported to graphicsmagick-bugs mailing
+ list on 2015-11-01 entitled "Failure to detect pswrite and
+ epswrite Ghostscript devices".
+
+2015-11-03 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadRawProfile): Issue a warning instead of
+ an error when attempting to read a zero-length profile.
+
+2015-11-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h (MagickSleep): Provide the macro 'MagickSleep'
+ to call a function which delays for one second. No longer provide
+ a macro 'sleep' in WIN32 compiles. Resolves issue reported to
+ graphicsmagick-bugs mailing list on 2005-11-01 entitled "MinGW
+ build error when sleep re#defined as Sleep".
+
+2015-10-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/demo/demos.tap: Add zoom test cases to test resize to
+ original dimensions, change height, and change width.
+
+ - magick/resize.c (ScaleImage): Fix regression introduced in
+ 1.3.22 release which results in pixel cache not open if the scale
+ width and height match the original. Patch by Troy Patteson.
+ Fixes part of SourceForge bug #323 "ScaleImage() issues in
+ v1.3.22".
+ (ScaleImage): Fix double free problem when scaled rows equals
+ original rows. This regression was added in the 1.3.22 release
+ via changset 080b99bba574. Based on patch by Troy Patteson.
+ Fixes remaining part SourceForge bug #323 "ScaleImage() issues in
+ v1.3.22".
+
+2015-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Magick++/Image.rst (thumbnail): Paragraph heading fix.
+ Resolves SourceForge issue #321 "find tiny error in
+ Magick++/Image.html document".
+
+2015-10-06 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - docs/\*.imdoc: Changed synopses in manpages to add "gm "
+ prefix to commands. Updated synopsis for "convert" to agree
+ with what's in the "gm" manpage.
+
+2015-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Remove CFLAGS and LDFLAGS deduplication code.
+ Resolves SourceForge bug #320 OS X "universal build failure".
+
+2015-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/index.rst: Updated for 1.3.22 release.
+
+ - NEWS.txt: Updated for 1.3.22 release.
+
+2015-09-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Brought up to date with changes thus far since last
+ release.
+
+ - magick/blob.c (OpenBlob): Disable fflush() of read-only handle
+ under Microsoft Windows, which produced a spurious error status,
+ blocking file reads for Visual Studio 2015 on Windows 2012 server.
+ Problem was reported and diagnosed by Dirk Lemstra.
+
+2015-09-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff: Update bundled libtiff sources to 4.0.6 release.
+
+ - magick/module.c (InitializeModuleSearchPath): Fix compilation
+ problem when UseInstalledMagick is not defined.
+
+2015-09-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xpm.c: Static string/array allocations are now more
+ const.
+
+ - coders/{ps.c, ps2.c, ps3.c}: Static string/array allocations are
+ now more const.
+
+ - coders/palm.c: Palm static arrays should be 'const'.
+
+ - coders/meta.c (jpeg\_embed): Stop sharing writeable static string
+ 'psheader'.
+ (tag\_spec): The 'tags' static array should be all 'const'.
+
+ - coders/jp2.c: Try to reduce the amount of non-const static data.
+
+ - coders/dcm.c (dicom\_info): Try to make dicom\_info array more
+ 'const'.
+
+ - coders/dpx.c: Eliminate use of static buffer strings.
+
+ - coders/png.c: Make MNG chunk id strings constant rather than
+ initialized data.
+
+ - magick/render.c (DrawAffineImage): Fix problem that sometimes
+ output rows are skipped when using OpenMP. Problem identification
+ and patch by Kevin Matzen. Resolves SourceForge issue #316
+ "-affine sometimes produces output with missing rows".
+
+2015-08-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/rwblob.tap: Add specific tests for BMP2 BMP3 subformats.
+
+ - tests/rwfile.tap: Add specific tests for BMP2 BMP3 PS2 PS3
+ subformats.
+
+2015-08-30 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ \* magick/ImageMagick.rc Replace Imagemagick.ico by GraphicsMagick.ico
+
+ \* magick/Imagemagick.ico is no longer needed and not referenced anywhere.
+
+2015-08-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - README.txt: Fix SourceForge bug 314 "README: bad hg clone URL".
+
+ - magick/module.c (GetModuleListForDirectory): Fix Coverity 107017
+ "Copy into fixed size buffer" and 107013 "Overlapping buffer in
+ memory copy".
+ (UnloadModule): Fix SourceForge bug 312 "uninitialized variable
+ "name" in UnloadModule".
+
+ - coders/bmp.c (WriteBMPImage): Fix typo in fix on 2015-08-17.
+ Fixes Coverity 107014 "Test should be assignment".
+
+ - magick/module.c (OpenModules): Fix Coverity 107016 "Resource
+ leak".
+ (GetModuleListForDirectory): Fix Coverity 107015 "Resource leak".
+
+2015-08-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c (WriteBMPImage): Fix inverted alpha channel when
+ writing BGRA8888 format. Problem was reported by 张铎 via the
+ graphicsmagick-help discussion list on 2015-08-17.
+
+2015-08-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (GenerateEXIFAttribute): Verify that entry
+ pointer is within the metadata buffer in order to avoid buffer
+ overflow. Resolution and patch by Federico Larumbe.
+
+ - magick/profile.c (SetImageProfile): Avoid crash given NULL
+ profile pointer. Resolution and patch by Federico Larumbe.
+
+2015-08-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (GenerateEXIFAttribute): Fix logic problem
+ while validating EXIF GPS\_OFFSET. Problem reported by Federico
+ Larumbe.
+
+2015-07-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): Applied fix
+ (http://hg.code.sf.net/u/zacmorris/graphicsmagick/rev/edcc4c184b42)
+ by Zac Morris to detect buffer overrun while reading zip
+ compressed data.
+ (ReadMIFFImage): Fixed some memory leaks which were occuring when
+ an exception was thrown from zip-compressed data reader.
+
+2015-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WritePTIFImage): Fix SourceForge issue #269
+ "Convert creates SubfileType 0x2 instead of 0x1". From looking at
+ the code, this is a regression since the time support for the page
+ subfile type was added (probably via changeset 11831
+ (037eef0f67f2) on 2007-08-17).
+
+2015-07-19 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ - dcraw/dcraw.c: Fixed bad define WIN32.
+
+2015-07-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt, www/Hg.rst, www/index.rst: Applied English bugs patch
+ by Amadu Jalloh.
+
+ - dcraw/dcraw.c: Add a port replacement for strnlen().
+
+2015-07-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - wand/magick\_wand.h: The declaration for MagickGetImageGravity()
+ was missing. Resolves SourceForge bug #308 magick\_wand.h misses
+ declaration of MagickGetImageGravity.
+
+2015-07-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - dcraw: Update bundled dcraw to release 9.26.0.
+
+ - png: Updated bundled libpng to release 1.6.17.
+
+ - lcms: Update bundled lcms2 to release 2.7.
+
+2015-07-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Brought up to date with changes thus far since last
+ release.
+
+ - magick/version.h.in (MagickCopyright): Update most recent
+ copyright year.
+
+ - magick/render.c (DrawAffineImage): Fix problem with negative x
+ offset. Resolves SourceForge issue #306 "gm fails to convert svg
+ to jpeg if svg has images with negative coordinates".
+
+ - magick/pixel\_cache.c (ReadCachePixels): Add checks for integer
+ overflows.
+
+2015-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/module.c (ModuleAliases): Add a module alias for GRAYA.
+
+2015-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/montage.c (MontageImages): Fix Coverity 101317 "Resource
+ leak".
+
+ - magick/blob.c: Limit the data size passed to the read/write
+ calls to the filesystem blocksize and make multiple calls if
+ required.
+
+ - magick/pixel\_cache.c: Limit the data size passed to the
+ read/write, pread/prwite calls and make multiple calls if
+ required.
+
+2015-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (WriteBlobFile): Properly handle short read. Read
+ data in units of filesystem block size.
+ (BlobToFile): Write data in units of filesystem block size.
+
+ - patches: Added directory of patches which may be useful when
+ integrating new versions of 3rd-party programs or libraries into
+ the VisualMagick build.
+
+ - libxml: Re-applied libxml changes which were used in prior
+ release.
+
+2015-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - webp: Updated bundled libwebp to release 0.4.3.
+
+ - ttf: Update bundled freetype to release 2.6.
+
+ - libxml: Update bundled libxml2 to release 2.9.2.
+
+ - tiff/VERSION: Update bundled libtiff to release 4.0.4.
+
+ - magick/nt\_base.h (HAVE\_TIFFISCODECCONFIGURED): Enable use of
+ TIFFIsCODECConfigured in MSVC build.
+
+ - coders/tiff.c: I am too lazy to modify VisualMagick configure so
+ it is possible to include jpeglib.h in tiff.c, so block out this
+ low-value code just for MSVC builds.
+
+2015-06-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac, magick/profile.c: Removed support for lcms 1.X.
+ No one should be using a lesser version than lcms 2.0.
+
+2015-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c (DisassociateBlob): Applied patch by Dirk Lemstra
+ to assure that the image blob is no longer shared with other
+ images when the image is written. This helps with thread safety.
+
+2015-06-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Add/fix utility usage messages for -box,
+ -convolve, -gravity, -linewidth, -list, -mattecolor, -render and
+ -shave. Resolves SourceForge issue #302 "MogrifyUsage prints
+ incomplete information ".
+
+2015-06-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Include JPEG headers to obtain
+ its BITS\_IN\_JSAMPLE definition. This is needed so we can know
+ what JPEG depth libtiff supports.
+
+ - www/index.rst: Add mention of GraphicsMagick having zero defects
+ reported by Coverity.
+
+2015-06-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/STL.cpp (adaptiveThresholdImage): Add a new
+ constructor which accepts a 'double' offset value. The previous
+ version of this constructor is deprecated and subject to removal
+ in the future. The size of the class is enlarged to store a
+ 'double' and so this is a break in the ABI when this class was
+ used. Code using this class should be re-compiled.
+
+ - Magick++/lib/Image.cpp (adaptiveThreshold): Add a new version of
+ this method which accepts a 'double' offset value. The previous
+ version of the method is deprecated and subject to removal in the
+ future. Problem was reported by Dirk Lemstra.
+
+2015-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/gray.c (ReadGRAYImage): Based on feedback from Glenn,
+ return a gray image from the reader, even if a channelized format
+ specifier is given.
+
+2015-05-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/gray.c (ReadGRAYImage): Fix read glitch caused by
+ incorrect memset(). Added missing break statement to switch.
+ Added more logging.
+ (RegisterGRAYImage): Register "gray" formats R, G, B, C, M, Y, K,
+ O such that they are not triggered by file extension. It is
+ necessary to apply a magick prefix to the file name (or set image
+ magick in the API) in order to force using these formats. This
+ avoids accidents in case the file extension was used for some
+ other purpose.
+
+2015-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/gray.c: Added support for "GRAYA" format. Format
+ specifiers "R", "G", "B", "A", "C", "M", and "Y" may now be used
+ to save and restore the associated channel using the same raw
+ format as "GRAY". These format specifiers were already supported
+ but did not appear to serve any useful function.
+
+2015-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Improve handling of libxml2 dependencies. Only
+ test for and use libwmflite. Full-up libwmf is no longer used.
+ - configure.ac: Deduplicate CFLAGS and LDFLAGS.
+
+2015-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOnePNGImage): Eliminate a "clobber"
+ compilation warning.
+
+ - coders/jpeg.c (WriteJPEGImage): Eliminate a "clobber"
+ compilation warning.
+
+ - configure.ac: Don't compute libwmf2 and libxml2 linkage path
+ based on claimed installation prefix. This is hoped to improve
+ configure reliability on multi-arch type systems.
+
+2015-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Use the first -I, -L, and -l arguments produced by
+ freetype-config and don't produce arguments based on installation
+ prefix. This is hoped to improve configure reliability on
+ multi-arch type systems.
+
+2015-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/tempfile.c (AcquireTemporaryFileDescriptor): P\_tmpdir is
+ not an environment variable. Need to consider Windows environment
+ variables for Cygwin.
+
+ - magick/random.c (InitializeMagickRandomKernel): For Microsoft
+ Windows, use CryptGenRandom() to salt the built-in random number
+ generator.
+
+2015-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (MagickRandReentrant): Quiet Coverity 10092
+ "Calling risky function".
+ (MagickRandNewSeed): Quiet Coverity 10093 "Calling risky
+ function".
+
+ - coders/tga.c (ReadTGAImage): Quiet Coverity 10201 "Identical
+ code for different branches".
+
+ - coders/pcx.c (ReadPCXImage): Quiet Coverity 10218 "Identical
+ code for different branches".
+
+2015-05-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetGeometry): Fix handling of area geometries
+ in the form "5000000@". Resolves SourceForge issue #299 "-resize
+ with @ and > in geometry specification".
+
+2015-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Disable matte channel for
+ compression types which don't support it. Resolves SourceForge
+ bug #297 "GM distorts image using -transform".
+ (WriteTIFFImage): When type is Optimize, disable matte channel if
+ image is opaque.
+
+2015-05-09 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ - webp/src/utils/endian\_inl.h: Fixed defect in intrinsic function
+ byteswap\_ulong for Visual Studio less than 2005.
+
+2015-05-08 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ - VisualMagick/configure/system\_page.cpp,
+ VisualMagick/configure/system\_page.h: Suppress reloading .vcproj
+ when configuration type does not change.
+
+2015-05-08 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ - VisualMagick/configure/system\_page.cpp,
+ VisualMagick/configure/system\_page.h,
+ VisualMagick/configure/target\_page.h: Ability to re-use already
+ given paths. It is highly frustrating to enter path for different
+ configurations again and again.
+
+2015-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/vid.c (ReadVIDImage): Fix use of uninitialized variable
+ reported by MSVC 2003 (but not GCC, Clang, or Coverity).
+
+2015-05-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): Fix possible leak of profiles in
+ error path.
+
+ - coders/mpc.c (ReadMPCImage): Fix memory leak of values
+ allocation.
+ (ReadMPCImage): Fix possible leak of profiles in error path. Fixes
+ Coverity 80697 "Resource leak".
+
+2015-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): Fix memory leak of values
+ allocation.
+
+2015-05-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): Hopefully quiet Coverity 10305
+ "Untrusted loop bound".
+
+ - coders/tga.c (ReadTGAImage): Hopefully quiet Coverity 53418
+ "Untrusted loop bound".
+
+ - magick/tempfile.c (AcquireTemporaryFileDescriptor): Eliminate
+ all use of operating system provided temporary file allocation
+ functions (all apparently flawed in one way or another) and rely
+ exclusively on our own implementation.
+
+ - magick/constitute.c (ConstituteImage): Quiet Coverity 53399
+ "Logically dead code".
+
+ - coders/webp.c (ReadWEBPImage): Quiet Coverity 53400 "Logically dead
+ code".
+
+ - coders/miff.c (WriteRunlengthPacket): More work to quiet
+ Coverity 10186 and 10214 "Missing break in switch".
+
+2015-05-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/tempfile.c (AcquireTemporaryFileDescriptor): Thoroughly
+ vet temporary file path. Might quiet Coverity 64613 "Use of
+ untrusted string value".
+
+ - wand/magick\_compat.c (ParseGeometry): Another try at quieting
+ Coverity 10248 "Copy into fixed size buffer" and 10078
+ "Overlapping buffer in memory copy" in this dead code.
+
+ - magick/tempfile.c (AcquireTemporaryFileDescriptor): Remove
+ unneeded, almost certainly never used, and potentially insecure
+ use of mkstemp(). Will quiet Coverity 10315 "Insecure temporary
+ file".
+
+2015-04-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Keep Ghostscript gibberish from appearing in
+ Configure output.
+
+ - coders/miff.c (WriteRunlengthPacket): Quiet Coverity 10186 and
+ 10214 "Missing break in switch".
+
+ - magick/pixel\_cache.c (GetCacheInfo): Quiet Coverity 10208 "Data
+ race condition".
+
+ - magick/blob.c (CloneBlobInfo): Quiet Coverity 10188 "Data race
+ condition".
+ (GetBlobInfo): Quiet Coverity 10191 "Data race condition".
+
+ - magick/image.c (AllocateImage): Quiet Coverity 10196 "Data race
+ condition".
+ (CloneImage): Quiet Coverity 10206 "Data race condition".
+
+ - magick/map.c (MagickMapAllocateMap): Quiet Coverity 10192, 10193
+ and 10228 "Data race condition".
+
+ - configure.ac: Use an algorithm to try to discover the best value
+ for GSCMYKDevice.
+
+ - VisualMagick/bin/delegates.mgk: Recipe for 'gs-cmyk' contained a
+ typo which breaks using '-type ColorSeparation'.
+
+ - coders/pwp.c (ReadPWPImage): Fix Coverity CID 64491 "Integer
+ handling issues".
+
+2015-04-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xcf.c (load\_tile\_rle): Quiet Coverity 10259 "Untrusted
+ loop bound".
+
+ - coders/sct.c (ReadSCTImage): Quiet Coverity 10285 "Untrusted
+ loop bound".
+
+ - coders/pwp.c (ReadPWPImage): Quiet Coverity 10299 "Untrusted
+ loop bound".
+
+ - coders/pcd.c (ReadPCDImage): Quiet Coverity 10301 "Untrusted
+ loop bound".
+
+ - coders/tga.c (ReadTGAImage): Quiet Coverity 53418 "Untrusted
+ loop bound".
+
+ - wand/magick\_compat.c (ParseGeometry): Fix overlap strcpy() in
+ dead code. Quiets Coverity 10078 "Overlapping buffer in memory
+ copy" and 10248 "Copy into fixed size buffer".
+
+ - magick/segment.c (Classify): Fix Coverity 64317 "Resource leak".
+
+2015-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xcf.c (ReadXCFImage): Fix Coverity 64064 "Resource leak".
+
+ - coders/txt.c (ReadTXTImage): Fix Coverity 64061 "Resource leak".
+
+ - coders/rla.c (ReadRLAImage): Fix Coverity 64063 "Resource leak".
+
+ - coders/dib.c (ReadDIBImage): Fix Coverity 64057 Resource leak".
+
+ - magick/segment.c (Classify): Fix Coverity 64056 "Resource leak".
+
+ - magick/resize.c (SampleImage): Fix Coverity 64053, 64054, and
+ 64062 "Resource leak".
+
+ - magick/render.c (TraceStrokePolygon): Fix Coverity 64055, 64059,
+ and 64060 "Resource leak".
+
+ - magick/magick.c (ListModuleMap): Quiet Coverity 64058 "Resource
+ leak".
+
+2015-04-28 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/dpx.c: Fix Coverity 10305 "Untrusted loop bound".
+
+ - coders/cineon.c: Fix Coverity 10310 "Untrusted loop bound".
+
+2015-04-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/memory.c: All use of user-provided allocation functions
+ is done via MagickFree(), MagickMalloc(), and MagickRealloc().
+
+2015-04-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/colormap.c (MagickConstrainColormapIndex): For out of
+ range condition, specifically return 0 rather than setting index
+ to zero, and then returning index.
+
+ - coders/pcx.c (ReadPCXImage): Fix Coverity 10197 "Negative loop
+ bound".
+
+ - coders/map.c (ReadMAPImage): Allocate pixels after return case
+ for 'ping' mode.
+ (ReadMAPImage): Fix problem added in last commit due to multiple
+ uses of 'packet\_size'.
+
+ - magick/floats.c (\_Gm\_convert\_fp16\_to\_fp32)
+ (\_Gm\_convert\_fp24\_to\_fp32): Fix Coverity 10094 "Logically dead
+ code".
+
+ - coders/pcx.c (ReadPCXImage): Fix Coverity 10197 "Negative loop
+ bound".
+
+ - coders/wpg.c (UnpackWPG2Raster): Always test for EOF from
+ ReadBlobByte(). Should fix Coverity 10205 "Negative loop bound".
+
+2015-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pcx.c (ReadPCXImage): Add some more integer-overflow
+ safety to computations. Add some casts.
+
+ - coders/meta.c (formatIPTC): Fix Coverity 10221 "Infinite loop".
+
+ - magick/attribute.c (GenerateEXIFAttribute): Fix Coverity 10320
+ "Untrusted array index read" and "Untrusted loop bound".
+
+2015-04-24 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/gif.c (ReadGIFImage): Attempt to fix Coverity issue
+ 10284 by using "opacity = (header[3] & 0xff)".
+
+2015-04-23 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - magick/blob.c (ReadBlobMSBLong, ReadBlobLSBLong): Attempt
+ to fix various "tainted" or "untrusted" variables
+ by masking off all but the lower 32 bits returned.
+
+2015-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xcf.c (ReadXCFImage): Fix Coverity 10216 "Integer
+ overflowed argument".
+
+ - magick/transform.c (FlipImage): Fix Coverity 61461 "Division or
+ modulo by zero".
+
+ - coders/gif.c: Protect against integer overflow in array size
+ calculations. Used unsigned type for colormap index.
+
+2015-04-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/map.c (ReadMAPImage): Maybe quiet Coverity 10326
+ "Untrusted pointer read".
+
+ - magick/utility.c (GlobExpression): See if testing for null
+ terminating character quiets Coverity 10246 "Untrusted value as
+ argument".
+
+ - magick/transform.c (FlipImage): Possibly quiet case #4 of
+ Coverity 10311 "Untrusted value as argument".
+
+ - magick/utility.c (Base64Encode): Quiet Coverity 10296 and 10272
+ "Use of untrusted scalar value".
+
+2015-04-22 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - magick/blob.c (ReadBlobMSBShort, ReadBlobLSBShort): Attempt
+ to fix various "tainted" or "untrusted" variables, e.g., in
+ coders/gif.c and coders/sgi.c by masking off all but the lower
+ 16 bits returned.
+
+2015-04-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tim.c (ReadTIMImage): Make TIM reader more robust against
+ EOF.
+
+ - coders/sct.c (ReadSCTImage): Make SCT reader more robust against
+ EOF.
+
+ - coders/pwp.c (ReadPWPImage): Test loop for EOF.
+
+ - coders/otb.c (ReadOTBImage): Make error reporting a bit more
+ robust.
+
+ - coders/jnx.c (ExtractTileJPG): Add some EOF checks.
+
+ - coders/cut.c (ReadCUTImage): Limit width/height to range of
+ signed integer.
+
+ - tests/rwfile.tap: Add a R/W file test for ART.
+
+ - tests/rwblob.tap: Add a R/W blob test for ART.
+
+ - coders/art.c (ReadARTImage): Improve error checking.
+
+2015-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sun.c (ReadSUNImage): Try to quench Coverity 10280
+ "Untrusted loop bound".
+
+ - coders/mpc.c (ReadMPCImage): Port MIFF header reading fixes.
+
+2015-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): MIFF reader failed to read some
+ MIFF headers properly. Fixes SourceForge issue #298 "invalid next
+ size (normal)/memory corruption".
+
+2015-04-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadMNGImage): Fix Coverity 55862 "Resource leak"
+ and quiet Coverity 55825, 55826, and 55827 "Data race condition".
+
+2015-04-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GetToken): Fix an overlapping strlcpy() which
+ caused a crash in pedantic strlcpy() implementations while parsing
+ a SVG-style URL from text. Several other issues remain.
+
+2015-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ParseUnixCommandLine): Fix Coverity 59256
+ "Unused value".
+
+2015-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/display.c (MagickXROIImage): Fix Coverity 10179 "Missing
+ break in switch".
+ (MagickXCropImage): Fix Coverity 10211 "Missing break in switch".
+
+ - magick/utility.c (Base64Decode): Fix Coverity 10203 "Missing
+ break in switch".
+ (Tokenizer): Quench Coverity 10182 "Missing break in switch". Not
+ believed to be an actual problem.
+
+ - magick/command.c (ParseUnixCommandLine): Fix Coverity 10174 and
+ 10178 "Missing break in switch".
+ (ProcessBatchOptions): Fix Coverity 10180 "Missing break in
+ switch".
+ (ParseWindowsCommandLine): Fix Coverity 10220 "Missing break in
+ switch".
+
+ - coders/xwd.c (ReadXWDImage): Fix Coverity 10095 "Division or
+ modulo by zero". 3rd try.
+
+2015-04-14 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOneJNGImage): Fix Coverity 55829 and 55846
+ "Resource leak".
+
+2015-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+ 55831 "Resource leak". 2nd try.
+
+ - coders/vid.c (ReadVIDImage): Fix Coverity 55868 and 55874
+ "Resource leak". 2nd try.
+
+2015-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/psd.c (ReadPSDImage): Fix Coverity 55855 "Resource
+ leak". 2nd try.
+
+ - coders/pict.c (PictPixmapOp): Fix Coverity 55875 and 55883
+ "Resource leak". 2nd try.
+
+ - coders/pcx.c (WritePCXImage): Fix Coverity 55877 "Resource
+ leak". 2nd try.
+
+ - coders/meta.c (format8BIM): Fix Coverity 55842 "Resource
+ leak". 2nd try.
+
+ - coders/mat.c (WriteMATLABImage): Fix Coverity 55850 "Resource
+ leak". 2nd try.
+
+ - coders/dpx.c (ReadDPXImage): Fix Coverity 55878 "Resource leak".
+ 2nd try.
+
+ - coders/preview.c (WritePreviewImage): Fix Coverity 55988
+ "Resource leak".
+
+2015-04-12 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOneJNGImage): Avoid some memory leaks
+ newly reported by Coverity (work in progress)
+
+2015-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resize.c (ScaleImage): Fix Coverity 55824 "Division or
+ modulo by float zero".
+
+ - magick/annotate.c (AnnotateImage): Fix Coverity 55863
+ "Uninitialized scalar variable".
+
+ - wand/magick\_wand.c (MagickDrawImage): Fix Coverity 55828
+ "Resource leak".
+ (MagickMontageImage): Fix Coverity 55835 "Resource leak".
+
+ - wand/drawing\_wand.c (DrawComposite): Fix Coverity 55849
+ "Resource leak".
+
+ - magick/widget.c (MagickXColorBrowserWidget): Fix Coverity 55854
+ "Resource leak".
+
+ - magick/resize.c (ScaleImage): Fix Coverity 55841, 55853, 55858,
+ and 55860 "Resource leak".
+
+ - magick/render.c (ConvertPathToPolygon): Fix Coverity 55836
+ "Resource leak".
+ (DrawDashPolygon): Fix Coverity 55837 "Resource leak".
+
+ - magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+ 55831 "Resource leak".
+
+ - magick/paint.c (ColorFloodfillImage): Fix Coverity 55886
+ "Resource leak".
+
+ - magick/map.c (MagickMapAddEntry): Possibly silence 55844
+ "Resource leak".
+
+ - magick/image.c (CloneImage): Fix Coverity 55833 "Resource leak".
+
+ - magick/effect.c (BlurImage): Fix Coverity 55851 "Resource leak".
+
+ - magick/display.c (MagickXAnnotateEditImage): Fix Coverity 55830
+ "Resource leak".
+ (MagickXVisualDirectoryImage): Fix Coverity 55894 "Resource leak".
+
+ - magick/constitute.c (ReadImages): Fix Coverity 55834 "Resource
+ leak".
+ (ReadInlineImage): Fix Coverity 55843 "Resource leak".
+
+ - magick/compress.c (HuffmanEncode2Image): Fix Coverity 55839
+ "Resource leak".
+ (HuffmanDecodeImage): Fix Coverity 55859 "Resource leak".
+
+ - magick/color.c (GetColorHistogram): Fix Coverity 55845 "Resource
+ leak".
+ (ComputeCubeInfo): Fix Coverity 55857 "Resource leak".
+
+ - coders/yuv.c (ReadYUVImage): Fix Coverity 55890 "Resource leak".
+
+ - coders/wpg.c (UnpackWPG2Raster): Fix Coverity 55832 and 55848
+ "Resource leak".
+
+2015-04-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/vid.c (ReadVIDImage): Fix Coverity 55868 "Resource leak"
+ (ReadVIDImage): Fix Coverity 55874 "Resource leak".
+
+ - coders/txt.c (ReadTXTImage): Fix Coverity 55866 "Resource leak".
+
+ - coders/topol.c (ReadTOPOLImage): Fix Coverity 55865 "Resource
+ leak".
+
+ - coders/sgi.c (WriteSGIImage): Fix Coverity 55891 "Resource leak".
+
+ - coders/psd.c (ReadPSDImage): Fix Coverity 55855 "Resource leak".
+
+ - coders/pict.c (WritePICTImage): Fix Coverity 55867, 55875, 55883
+ "Resource leak". Fix Coverity 55892 "Resource leak".
+
+ - coders/pdb.c (ReadPDBImage): Fix Coverity 55840, 55856, and
+ 55885 "Resource leak".
+
+ - coders/pcx.c (WritePCXImage): Fix Coverity 55877 "Resource
+ leak".
+
+ - coders/mvg.c (ReadMVGImage): Fix Coverity 55873 "Resource leak".
+
+ - coders/mpeg.c (WriteMPEGImage): Fix Coverity 55880 "Resource
+ leak".
+
+ - coders/miff.c (WriteMIFFImage): Fix Coverity 55864 "Resource
+ leak".
+ (WriteMIFFImage): Fix Coverity 55872 "Resource leak".
+
+ - coders/meta.c (formatIPTCfromBuffer): Fix Coverity 55838
+ "Resource leak".
+ (format8BIM): Fix Coverity 55842 and 55852 "Resource leak".
+ (formatIPTC): Fix Coverity 5882 "Resource leak".
+
+ - coders/mat.c (ReadMATImage): Fix Coverity 55850 "Resource leak".
+
+ - coders/map.c (ReadMAPImage): Fix Coverity 55876 "Resource leak".
+
+ - coders/logo.c (ReadLOGOImage): Fix Coverity 55870 "Resource
+ leak".
+
+ - coders/label.c (ReadLABELImage): Fix Coverity 55869 "Resource
+ leak".
+
+ - coders/icon.c (ReadIconImage): Fix Coverity 55887 "Resource
+ leak".
+
+ - coders/fits.c (WriteFITSImage): Fix Coverity 55884 "Resource
+ leak".
+
+ - coders/dpx.c (WriteDPXImage): Fix Coverity 55861 "Resource
+ leak".
+ (ReadDPXImage): Fix Coverity 55878 "Resource leak".
+ (ReadDPXImage): Fix Coverity 55879 "Resource leak".
+
+ - coders/dib.c (WriteDIBImage): Fix Coverity 55881 "Resource
+ leak".
+ (WriteDIBImage): Fix Coverity 55895 "Resource leak".
+
+ - coders/cut.c (ReadCUTImage): Fix Coverity 55893 "Resource leak".
+
+ - coders/caption.c (ReadCAPTIONImage): Fix Coverity 55888
+ "Resource leak".
+ (ReadCAPTIONImage): Fix Coverity 55889 "Resource leak".
+ (ReadCAPTIONImage): Fix Coverity 55896 "Resource leak".
+
+ - magick/annotate.c (RenderX11): Silence Coverity 10106 "Logically
+ dead code".
+
+ - coders/xcf.c: Silence Coverity 10224, 10233, and 10236 "Improper
+ use of negative value".
+
+ - coders/mat.c (ReadMATImage): Silence Coverity 10175 "Improper
+ use of negative value"
+
+ - coders/tga.c (ReadTGAImage): Silence Coverity 10088 "Operands
+ don't affect result".
+
+ - magick/annotate.c (RenderFreetype): Silence Coverity 14396 and
+ 44755 "Unused value".
+
+ - coders/wpg.c (LoadWPG2Flags): Silence Coverity 10273 and 10253
+ "Unused value".
+
+ - magick/montage.c (MontageImages): Silence Coverity 10255 "Unused
+ value".
+ (MontageImages): Silence Coverity 10264 "Unused value".
+
+2015-04-09 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOneJNGImage): Avoid using a NULL alpha\_image
+ or color\_image. (ReadJNGImage): Removed an extraneous CloseBlob().
+
+2015-04-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (MagickCreateDirectoryPath): Silence Coverity
+ 10098 "Logically dead code".
+
+ - magick/resource.c (InitializeMagickResources): Silence Coverity
+ 10101 "Logically dead code".
+
+ - magick/magick.c (MagickSignalHandlerMessage): Fix Coverity 44725
+ "Logically dead code".
+
+ - magick/log.c (DestroyLogInfo): Silence Coverity 53659 and 53661
+ "Data race condition".
+ (ReadLogConfigureFile): Silence Coverity 53660 "Data race
+ condition".
+
+ - magick/effect.c (DespeckleImage): Fix error handling issue
+ caused by shadowed variable. Fixes Coverity 10099 "Logically dead
+ code".
+
+ - magick/command.c (TimeImageCommand): Fix Coverity 10097
+ "Logically dead code".
+
+ - magick/attribute.c (ReadMSBLong): Hopefully silence Coverity
+ 10276 "Unintended sign extension".
+
+ - coders/sgi.c (ReadSGIImage, WriteSGIImage): Fix Coverity 10243,
+ 10244, 10247, 10254, and 10294 "Unintended sign extension".
+
+2015-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/xwindow.c (MagickXMakeImage): Quiet Coverity 10282
+ "Unused value".
+
+2015-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Another change targeting
+ Coverity 44742 and 44746 "Unintended sign extension".
+
+2015-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (TracePath): Fix Coverity 10258 "Uninitialized
+ scalar variable".
+
+ - magick/widget.c (MagickXFontBrowserWidget): Fix Coverity 10323
+ "Sizeof not portable". 2nd try.
+
+ - coders/xwd.c (ReadXWDImage): Fix Coverity 10095, 10100, 10104
+ "Division or modulo by zero". 2nd try.
+
+ - magick/analyze.c (GetImageCharacteristics): Fix Coverity 10096
+ "Logically dead code".
+
+ - coders/yuv.c (ReadYUVImage): Fix Coverity 10260 "Structurally
+ dead code".
+
+ - coders/xcf.c (ReadXCFImage): Fix Coverity 10226 "Missing break
+ in switch".
+
+ - coders/tim.c (ReadTIMImage): Fix Coverity 10249 "Unused value".
+
+ - coders/tiff.c (CompressionSupported): Fix Coverity 44723
+ "Logically dead code".
+ (WriteTIFFImage): Fix Coverity 44742 and 44746 "Unintended sign
+ extension".
+
+ - coders/ps3.c (WritePS3Image): Validate results from TellBlob()
+ and SeekBlob(). Should quiet Coverity 10198 "Improper use of
+ negative value".
+
+ - coders/ps2.c (WritePS2Image): Validate results from TellBlob()
+ and SeekBlob(). Should quiet Coverity 10230 "Improper use of
+ negative value".
+
+ - coders/mpeg.c (WriteMPEGImage): Quiet Coverity 10176 "Missing
+ break in switch".
+
+ - coders/map.c (WriteMAPImage): Make MAP reader/writer more
+ robust. May quiet 10326 "Untrusted pointer read".
+
+ - coders/locale.c (ReadLOCALEImage): Quiet Coverity 10108
+ "Logically dead code".
+
+ - coders/rle.c: Make URT RLE reader more robust. Should quiet
+ Coverity CID 10070 "Bad bit shift operation", as well as 10235
+ "Improper use of negative value".
+
+2015-04-04 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOneJNGImage): Quiet Coverity CID issue 14370,
+ "Unused value" (status was ignored).
+
+ - coders/png.c (ReadOneJNGImage): Quiet Coverity CID issue 44724,
+ "Logically dead code" (skip\_to\_iend can't be true).
+
+ - coders/png.c (ReadOnePNGImage): Attempt to quiet Coverity
+ CID 10232 "Missing unlock", by using png\_error() instead of
+ throwing an exception.
+
+2015-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xwd.c (ReadXWDImage): Fix Coverity 10104 "Division or
+ modulo by zero".
+
+ - magick/resize.c (ResizeImage): Fix Coverity 53404 "Division or
+ modulo by zero".
+
+ - coders/ps3.c (WritePS3MaskImage): Fix Coverity 53415 "Improper
+ use of negative value".
+
+ - coders/meta.c (parse8BIM): Fix Coverity 53413 "Improper use of
+ negative value".
+ (parse8BIMW): Fix Coverity 53414 "Improper use of negative value".
+
+ - magick/utility.c (GetMagickGeometry): Fix Coverity 53403 and
+ 53405 "Division or modulo by float zero".
+ (GetPathComponent): Fix Coverity 53417 "Wrong sizeof argument.
+
+ - magick/quantize.c (GrayscalePseudoClassImage): Fix Coverity
+ 10256 "Wrong sizeof argument".
+
+ - magick/image.c (ResetImagePage): Fix Coverity 53401 "Division or
+ modulo by float zero" and 53402 "Division or modulo by float
+ zero".
+
+ - coders/histogram.c (WriteHISTOGRAMImage): Silence Coverity 10107
+ "Division or modulo by float zero". 2nd try.
+
+ - magick/xwindow.c (MagickXImportImage): Silence Coverity 10207
+ "Array compared against 0".
+
+ - magick/widget.c (MagickXColorBrowserWidget): Silence Coverity
+ 53406 "Identical code for different branches".
+ (MagickXListBrowserWidget): Silence Coverity 53407 "Identical code
+ for different branches".
+
+ - magick/animate.c (MagickXMagickCommand): Silence Coverity 53410
+ "Identical code for different branches".
+
+ - coders/rgb.c (WriteRGBImage): Silence Coverity 53409 "Identical
+ code for different branches".
+
+ - coders/cmyk.c (WriteCMYKImage): Silence Coverity 53408
+ "Identical code for different branches".
+
+ - magick/xwindow.c (MagickXMakeImage): Silence Coverity 44727
+ "Dereference after null check". 2nd try.
+
+ - magick/utility.c (EscapeString): Silence Coverity 53416
+ "Dereference before null check".
+
+ - coders/gif.c (WriteGIFImage): Fix Coverity 10219 "Dereference
+ null return value".
+
+ - magick/log.c (InitializeLogInfo): Hopefully silence Coverity
+ 53411 and 53412 "Data race condition".
+
+ - coders/cineon.c (AttributeToString): Silence Coverity 10079
+ "Buffer not null terminated". 2nd try. The buffer is not
+ required to be null terminated!
+
+ - coders/pict.c (ReadPICTImage): 10171 "Resource leak". 2nd try.
+
+ - coders/wmf.c (util\_set\_brush): Silence Coverity 44739
+ "Out-of-bounds access". 2nd try.
+
+2015-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.c (SetLogEventMask): Silence Coverity 10069 "Value
+ not atomically updated". Logging initialization is done
+ single-threaded entirely in InitializeLogInfo() now.
+
+2015-03-28 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOnePNGImage): Attempt to quiet Coverity
+ 44734 "Data race condition" by freeing mng\_info->png\_pixels
+ and mng\_info->quantum\_scanline separately from MngInfoFreeStruct.
+
+2015-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/widget.c (XEditText): Silence Coverity 10072 "Overlapping
+ buffer in memory copy"
+
+ - coders/locale.c (ReadConfigureFile): Silence Coverity 10075
+ "Overlapping buffer in memory copy".
+
+ - magick/xwindow.c (MagickXMakeWindow): Silence Coverity 10076
+ "Overlapping buffer in memory copy".
+
+ - coders/dcm.c (funcDCM\_TransferSyntax): Silence Coverity 10083
+ "Unchecked return value".
+
+ - magick/static.c (ExecuteStaticModuleProcess): Silence Coverity
+ 10082 "Unchecked return value".
+
+ - coders/cals.c (ReadCALSImage): Silence Coverity 10086 "Unchecked
+ return value from library".
+ (ReadCALSImage): Silence Coverity 10085 "Unchecked return value".
+ (ReadCALSImage): Silence Coverity 10084 "Unchecked return value
+ from library".
+
+ - magick/enhance.c (ModulateImage): Silence Coverity 10087
+ "Unchecked return value".
+
+2014-03-24 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ \* coders/wpg.c More paranoa in checking ReadBlobByte() negative return.
+
+2015-03-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (Generate8BIMAttribute): Silence Coverity
+ 10195 "Argument cannot be negative".
+
+ - Magick++/lib/Image.cpp (syncPixels): Silence Coverity 44722
+ "Unchecked return value".
+ (fontTypeMetrics): Silence Coverity 44721 "Unchecked return
+ value".
+
+ - magick/render.c (ConvertPathToPolygon): Silence Coverity 10120
+ "Dereference after null check".
+
+ - magick/effect.c (EmbossImage): Silence Coverity 10114
+ "Dereference after null check".
+ (AdaptiveThresholdImage): Silence Coverity 10118 "Explicit null
+ dereferenced".
+
+ - coders/msl.c (MSLPushImage): Silence Coverity 10128 "Dereference
+ after null check".
+
+ - magick/render.c (DrawPolygonPrimitive): Silence Coverity 10136
+ "Dereference after null check".
+
+ - wand/drawing\_wand.c (DrawSetStrokeDashArray): Silence Coverity
+ 10117 "Dereference after null check".
+
+ - magick/draw.c (DrawSetStrokeDashArray): Silence Coverity 10150
+ "Dereference after null check".
+
+ - wand/drawing\_wand.c (DrawPushGraphicContext): Silence Coverity
+ 10151 "Dereference after null check".
+
+2015-03-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c (parse8BIM): Silence Coverity 10159 "Explicit null
+ dereferenced".
+ (parse8BIMW): Silence Coverity 10144 "Explicit null dereferenced".
+
+ - coders/uil.c (WriteUILImage): Silence Coverity 10202
+ "Dereference after null check". In fact, UIL output was not
+ working at all due to this bug.
+
+ - magick/xwindow.c (MagickXMakeImage): Silence Coverity 44727
+ "Dereference after null check".
+
+ - Magick++/lib/Image.cpp (colorMapSize): Silence Coverity 44728
+ "Dereference after null check".
+
+ - coders/vid.c (ReadVIDImage): Silence Coverity 44730 "Explicit
+ null dereferenced".
+
+ - coders/mpc.c (ReadMPCImage): Silence Coverity 44732 "Dereference
+ after null check".
+
+ - Magick++/lib/Image.cpp (signature): Silence Coverity 44735
+ "Dereference null return value".
+
+ - coders/ps.c (ReadPSImage): Ghostscript options concatenation
+ should be more secure against buffer overflow.
+
+ - coders/pdf.c (ReadPDFImage): Applied patch by Chris Gilling such
+ that '-define pdf:stop-on-error=true' will stop PDF processing
+ immediately upon an error.
+ (ReadPDFImage): Ghostscript options concatenation should be more
+ secure against buffer overflow.
+
+2015-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/animate.c (MagickXAnimateImages): Silence Coverity 44736
+ "Dereference null return value". Also fixed apparent memory leak
+ that Coverity did not notice.
+
+ - coders/fits.c (ReadFITSImage): Silence Coverity 10209
+ "Dereference before null check".
+
+ - magick/color\_lookup.c (ReadColorConfigureFile): Silence Coverity
+ 44743 "Dereference before null check".
+
+ - magick/xwindow.c (MagickXMakeImage): Silence Coverity 44745
+ "Dereference before null check".
+
+ - coders/pict.c (ReadPICTImage): Hopefully address consequences of
+ Coverity 10292 "Untrusted loop bound" although it will likely
+ still complain.
+
+ - magick/utility.c (LocaleCompare, LocaleNCompare): Try to create
+ an implementation that Coverity won't label an "tainted sink", and
+ therefore result in a Coverity "Use of untrusted scalar value"
+ report whenever a string from an external source is compared. The
+ original implementations are not believed to be faulty.
+
+2015-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ProcessBatchOptions): Silence Coverity 10080
+ "Buffer not null terminated".
+
+ - magick/widget.c (MagickXConfirmWidget): Silence Coverity 10089
+ "Copy-paste error". This is an amazing find by Coverity.
+
+ - magick/xwindow.c (MagickXImportImage): Silence Coverity 10207
+ "Array compared against 0".
+
+ - magick/quantize.c (GrayscalePseudoClassImage): Silence Coverity
+ 10256 "Wrong sizeof argument".
+
+ - coders/tiff.c (ReadTIFFImage): Fix Coverity 44747 and 44748
+ "Extra sizeof expression".
+
+2015-03-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Magick++/Include.h (Magick): Fix compilation with
+ 'clang' under Linux. Build was broken yesterday.
+
+ - coders/tiff.c (QuantumTransferMode): Fix reading Old JPEG and
+ YCbCr sample images from libtiff pics-3.8.0.tar.gz image file
+ collection. There was a regression for YCbCr added in last
+ release.
+
+2015-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c (ReadBMPImage): Fix Coverity 44726 "Division or
+ modulo by float zero". I don't think that this can actually
+ happen due to prior checks.
+
+ - magick/xwindow.c (MagickXMakeWindow): Silence Coverity 10281
+ "Copy into fixed size buffer".
+
+ - coders/pdf.c (ReadPDFImage): Silence Coverity 10241 "Copy into
+ fixed size buffer".
+
+ - magick/type.c (ReadTypeConfigureFile): Silence Coverity 10242
+ "Copy into fixed size buffer".
+
+ - magick/utility.c (GetPathComponent): Silence Coverity 10263
+ "Copy into fixed size buffer".
+
+ - coders/txt.c (ReadTXTImage): Silence Coverity 10287 "Copy into
+ fixed size buffer".
+
+ - coders/ps.c (WritePSImage): Silence Coverity 10289 "Copy into
+ fixed size buffer".
+
+ - magick/delegate.c (ReadConfigureFile): Silence Coverity 10297
+ "Copy into fixed size buffer".
+
+ - magick/log.c (ReadLogConfigureFile): Silence Coverity 10300
+ "Copy into fixed size buffer".
+
+ - coders/ps3.c (WritePS3Image): Silence Coverity 10303 "Copy into
+ fixed size buffer".
+
+ - coders/pdf.c (WritePDFImage): Silence Coverity 10304 "Copy into
+ fixed size buffer".
+
+ - coders/ps.c (ReadPSImage): Silence Coverity 10306 "Copy into
+ fixed size buffer".
+
+ - coders/msl.c (MSLStartElement): Silence Coverity 10308 "Copy
+ into fixed size buffer".
+
+ - coders/ps2.c (WritePS2Image): Silence Coverity 10309 "Copy into
+ fixed size buffer".
+
+ - Magick++/lib/Geometry.cpp (operator): Silence Coverity 44749
+ "Copy into fixed size buffer".
+
+ - Magick++/lib/Image.cpp (annotate): Silence Coverity 44750 "Copy
+ into fixed size buffer".
+
+ - coders/ept.c (ReadEPTImage): Silence Coverity 44751 "Copy into
+ fixed size buffer".
+
+ - coders/wmf.c (ipa\_device\_begin): Silence Coverity 44753 "Copy
+ into fixed size buffer".
+ (lite\_font\_map): Silence Coverity 44752 "Copy into fixed size
+ buffer".
+
+ - magick/random.c (InitializeMagickRandomKernel): Silence Coverity
+ 10091 "Don't Call" in the case where /dev/random is available.
+
+ - coders/mpeg.c (WriteMPEGParameterFiles): Fix Coverity 10190
+ "Resource leak". File descriptor was leaked under certain error
+ conditions.
+
+ - coders/wpg.c (UnpackWPG2Raster): Fix Coverity 10312
+ "Uninitialized scalar variable" gripe.
+
+ - magick/utility.c (ListFiles): Possibly address
+ Coverity 10245 "Sizeof not portable" gripe.
+
+ - magick/widget.c (MagickXFontBrowserWidget): Possibly address
+ Coverity 10323 "Sizeof not portable" gripe.
+
+ - coders/mat.c (WriteMATLABImage): FormatString() requires a
+ buffer of MaxTextExtent bytes. Use sprintf instead. Fix for
+ Coverity issue 10170.
+
+ - Magick++/lib/Geometry.cpp (string): FormatString() requires a
+ buffer of MaxTextExtent bytes. Fix for Coverity issue 44737.
+
+ - coders/wmf.c (draw\_pattern\_push): FormatString() requires a
+ buffer of MaxTextExtent bytes. Fix for Coverity issue 44741.
+ (ipa\_device\_begin): FormatString() requires a buffer of
+ MaxTextExtent bytes. Fix for Coverity issue 44740.
+ (util\_set\_brush): FormatString() requires a buffer of
+ MaxTextExtent bytes. Fix for Coverity issue 44739.
+ (ipa\_region\_clip): FormatString() requires a buffer of
+ MaxTextExtent bytes. Fix for Coverity issue 44738.
+
+2015-03-15 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (WritePNGImage) Avoid a Coverity gripe about
+ potential NULL dereference (actually it is impossible because
+ png\_error() does not return. Fix for Coverity gripe 44731.
+
+ - coders/png.c (WritePNGImage) Avoid a null pointer dereference
+ while logging inherited color\_type. Fix for Coverity issue 10185.
+
+ - coders/png.c (WriteOneJNGImage) Avoid possible unintended sign
+ extension. Fix for Coverity issue 44744.
+
+ - coders/png.c (WriteOnePNGImage) Quiet a false Coverity warning
+ about dereference after NULL check. Fix for Coverity issue 44729.
+
+ - coders/png.c (ReadOnePNGImage): Redid the "Respect the
+ PixelsResource limit" patch of March 7, using unsigned arithmetic
+ to determine the width limit. Sometimes the calculated
+ width limit was incorrectly zero.
+
+2015-03-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Fix problems with reading
+ filenames that include a colon. Resolves SourceForge bug #294
+ "display and convert (probably other things too) choke on
+ filenames with colons in".
+
+ - magick/utility.c (GetPathComponent): Fix SubImagePath
+ extraction. Fixes SourceForge bug #66 "converting runs slowly when
+ subimage is specified".
+
+2015-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc (-geometry): Document the significance of 'x'
+ as used in a geometry specification. In particular, document that
+ if width is specified without a trailing 'x' that height is set to
+ width. This is in response to SourceForge bug #296 "Strange
+ -resize WIDTH results with version 1.3.21".
+
+2015-03-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (GlobExpression): Remove use of IsSubimage().
+
+ - magick/image.c (IsSubimage): Re-implement with a more robust
+ solution. Combined with fixes to ps.c and pdf.c, allows selecting
+ specific pages, as well as re-ordering.
+
+ - coders/ps.c (ReadPSImage): Set image frame scene ids
+ appropriately.
+
+ - coders/pdf.c (ReadPDFImage): Set image frame scene ids
+ appropriately.
+
+ - magick/utility.c (TranslateTextEx): -format %Q should report
+ JPEG quality estimate if it is available. Resolves SourceForge
+ bug #293 "gm identify bug?".
+
+ - doc/options.imdoc: Documented JPEG-specific -format tags.
+
+2015-03-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Image.cpp (repage): New method to reset page
+ settings. Contributed by Dirk Lemstra.
+
+2015-03-07 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOnePNGImage): Respect the PixelsResource
+ limit.
+
+ - coders/png.c (ReadOnePNGImage): Moved quantum\_scanline
+ and png\_pixels into the MngInfo struct. This prevents
+ memory leaks when reading malformed PNG images, but unfortunately
+ triggers a new complaint about a possible race condition.
+
+ - coders/png.c (ReadOnePNGImage): Removed two superflous calls to
+ CloseBlob().
+
+ - coders/png.c (ReadOnePNGImage): Do the allocation and free of
+ quantum\_scanline outside the "pass" loop, i.e., do it once per
+ image rather than once per pass while decoding interlaced PNG
+ images. Log these when -debug coders is enabled.
+
+ - coders/png.c: Fixed typo recently introduced in the JNG reader
+ (status != MagickFalse should be status == MagickFalse).
+
+2015-03-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xwd.c (ReadXWDImage): Fix memory leaks in error paths.
+
+ - coders/xpm.c (ReadXPMImage): Fix memory leaks in error paths.
+
+ - coders/miff.c (ReadMIFFImage): Fix memory leak of Image in error
+ case.
+ (ReadMIFFImage): Fix memory leaks of zlib and bzlib2 context in
+ error path which reports decompression failure.
+
+ - coders/bmp.c (ReadBMPImage): BMP reader was wrongly rejecting
+ RLE-compressed files as being too small. Fixes SourceForge bug
+ #295 "1.3.21 identify regression". Also fixed 'ping' support code
+ which was still reading the pixels in 'ping' mode.
+ (ReadBMPImage): Fix memory leak when BMP is handled as a sequence.
+
+2015-03-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/palm.c (ReadPALMImage): PALM reader now applies PALM's
+ special non-linear colormap if the file does not provide a custom
+ colormap. Custom colormap size is verified to not exceed image
+ colors. Added logging statements regarding colormap.
+
+2015-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/index.rst: Update for 1.3.21 release.
+
+ - www/Changes.rst: Update for 1.3.21 release.
+
+ - NEWS.txt: Update NEWS for 1.3.21 release.
+
+ - version.sh: Bump/adjust library versioning.
+
+2015-02-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/delegate.c: Fix compilation under Cygwin. Thanks to Marco
+ Atzeri for advising us of this problem.
+
+2015-02-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/error.h (ThrowReaderException): More significant
+ exceptions (e.g. errors) should overwrite less significant
+ exceptions (e.g. warnings) thrown earlier.
+
+ - coders/bmp.c (ReadBMPImage): Detect 32-bit integer overflows and
+ other annoyances caused by intentionally broken files. Also, only
+ warn if the file header claims the file is larger than it is since
+ this is a benign issue.
+
+ - magick/blob.c (OpenBlob): Fix "magic header bytes" log message
+ count value.
+
+2015-02-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated NEWS with more changes.
+
+ - Magick++/lib/Magick++/Include.h (Magick): Add GetImageGeometry
+ to MagickLib namespace in order to avoid a compilation problem
+ noticed with Visual C++ 6.0.
+
+2014-02-22 Jaroslav Fojtik <JaFojtik@seznam.cz>
+
+ - VisualMagick\configure\configure.cpp Fixed crash.
+ Renamed debug to configure\_d.exe to prevent mess.
+
+2015-02-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (InitializeMagick): Invoke
+ NTInitializeExceptionHandlers() under Windows.
+
+ - magick/nt\_base.c (NTInitializeExceptionHandlers): Add a new
+ private function which disables pop-up Windows on exceptions and
+ registers a handler for Windows exceptions to clean up temporary
+ files prior to program exit.
+
+ - magick/magick.c (PanicDestroyMagick): Use
+ PurgeTemporaryFilesAsyncSafe() rather than PurgeTemporaryFiles().
+ (InitializeMagickSignalHandlers): Always register for SIGINT, even
+ under Microsoft Windows.
+
+ - magick/tempfile.c (PurgeTemporaryFilesAsyncSafe): New private
+ function to clean up temporary files prior to program exit.
+ Async-safe so it can be safely called from a signal handler.
+ Intentionally leaks memory.
+
+2015-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (GenerateEXIFAttribute): Fix crash while
+ parsing corrupt EXIF which was reported by Stijn Sanders on
+ 2015-02-17.
+
+ - Magick++/lib/{Blob.cpp, Image.cpp}: Incorrect lock scope
+ resulted in Magick++ locking not actually working to protect
+ critical sections in spite of no detected problems with locking
+ these past 16 years. Problem was detected using the
+ misc-unused-raii check from clang-tidy and was reported by Hyrum
+ Wright.
+
+ - coders/palm.c (ReadPALMImage): Add header logging to writer.
+ Writer still seeks and overwrites its own header so logging is not
+ entirely accurate yet.
+
+2015-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - libtool: Update GNU libtool to 2.4.6.
+
+ - coders/palm.c (ReadPALMImage): Fix support for transparency in
+ PALM reader.
+
+2015-02-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/palm.c (ReadPALMImage): Major re-work of PALM reader.
+ More log message improvements. More header validation.
+
+2015-02-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/palm.c (ReadPALMImage): Improve log messages. Add more
+ header validation. Check image pixel limits. Support 'ping'
+ mode.
+
+2015-02-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/palm.c (ReadPALMImage): PALM reader now supports 1, 2, 4,
+ 8, and 16-bit test files we were able to generate using
+ 'pnmtopalm'. A progress monitor was added. Memory leaks in error
+ paths were fixed.
+
+2015-02-12 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Insert "if (QuantumTick(...))" ahead of
+ each "if (!MagickMonitorFormatted(...)".
+
+2015-02-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/rla.c (ReadRLAImage): Assure that header ASCII strings
+ are properly terminated. Resolves Coverity CID 10322.
+
+2015-02-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.h (STDERR\_FILENO): Provide definitions for
+ standard POSIX file numbers so that Visual Studio should compile.
+ Fixes SourceForge bug #291 "STDERR\_FILENO (used in magick.c) is
+ not defined under Windows"
+
+2015-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Image.cpp (Image::quiet()): Patch by Dirk Lemstra
+ to support silencing warnings in Magick++. Adds a quiet() method
+ which blocks (ignores) warning exceptions when passed a true
+ argument. Warning exceptions are still generated by default.
+
+ - coders/tiff.c: Support '-define tiff:report-warnings=true' to
+ enable that warnings reported by libtiff are thrown as warning
+ exceptions so that they may be caught or will be reported at the
+ gm command-line.
+
+2015-02-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (WriteTIFFImage): Use YCbCr encoding when JPEG
+ compression is requested for an RGB image.
+
+2015-02-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (QuantumTransferMode): Fix reading or writing
+ planar min-is-white or min-is-black images with an associated
+ alpha channel.
+
+2015-02-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xpm.c (ReadXPMImage): Reading empty XPM file should not
+ cause bad memory access.
+
+ - coders/gif.c (DecodeImage): Assure that GIF decoder does not use
+ unitialized data.
+
+ - coders/jpeg.c (ReadJPEGImage): Verify that we support the number
+ of output components before proceeding to decode the image.
+
+2015-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): MIFF needs to stop spinning if
+ zlib or bzlib report an error while decompressing. Solves problem
+ with file provided by Jodie Cunningham on 2015-01-25.
+
+ - coders/vicar.c (ReadVICARImage): Fix Vicar reader's dogged
+ determination to continue reading when there is nothing left to
+ read. Solves problem with file provided by Jodie Cunningham on
+ 2015-01-25.
+
+ - magick/magick.c (PanicDestroyMagick): Replace memory allocation
+ functions with dummy functions rather than NULL pointers.
+ (InitializeMagickSignalHandlers): Register
+ MagickPanicSignalHandler() for SIGSEGV.
+ (MagickPanicSignalHandler): Produce an informative message for the
+ user.
+ (MagickSignalHandlerMessage): Include more detailed information
+ from the signal handler via a common routine used by default
+ signal handlers.
+
+2015-01-25 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/bmp.c (ReadBMPImage): An attempt to address CID 10291.
+
+2015-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/nt\_base.c (Exit): Changed to return 'void'. Function can
+ not return a value if it does not return.
+
+ - magick/error.c (DefaultFatalErrorHandler): Invoke
+ PanicDestroyMagick() rather than DestroyMagick(). If we are
+ really that short on memory, DestroyMagick() might not work.
+
+ - magick/magick.c (MagickPanicSignalHandler): Only use async-safe
+ functions in signal handler.
+ (PanicDestroyMagick): New function for emergency release of
+ persistent resources just prior to program exit. Async-safe and
+ does not acquire or release any heap memory.
+
+ - magick/export.c: Eliminate two 'clang' warnings.
+
+2015-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pdb.c (ReadPDBImage): Fix typo.
+
+ - coders/cineon.c (ReadCINEONImage): Enforce that Cineon image
+ info channels is valid. Solves problem with file provided by
+ Jodie Cunningham on 2015-01-24
+
+ - coders/fits.c (ReadFITSImage): Enforce valid bits-per-pixel
+ values. Add detailed header logging. Solves problem with file
+ provided by Jodie Cunningham on 2015-01-24
+
+2015-01-22 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadPNGImage): Check length of various MNG
+ chunks before using the chunk data.
+
+ - coders/png.c (WriteOnePNGImage): Use png\_error() instead of
+ throwing an exception so cleanup in the setjmp block can happen,
+ including unlocking the semaphore. Addresses Coverity CID 10184.
+
+2015-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/gif.c (WriteGIFImage): Don't use an unchecked value from
+ GetImageAttribute(), even if the access succeeded before.
+ Resolves Coverity CID 10219.
+
+ - coders/dpx.c (StringToAttribute): Make sure that string is not
+ accidentally shortened by one character if it occupies the full
+ field size.
+ (ReadDPXImage): Validate that the bits per sample claimed by the
+ file header is a supported depth before using it further in the
+ code. This might resolve Coverity CID 10071 "Bad shift
+ operation".
+ (ReadDPXImage): Check for EOF while reading forward to element
+ data. Might solve Coverity CID 10305.
+
+ - coders/dib.c (ReadDIBImage): Resolve Coverity CID 10228 "Integer
+ overflowed argument".
+ (ReadDIBImage): Hopefully resolve Coverity CID 10268 "Various",
+ which is primarily about placing too much trust in the claimed
+ number of colors.
+
+ - coders/pnm.c (WritePNMImage): Fix overwrite of status by
+ progress monitor. Remaining issues may lurk within. May resolve
+ Coverity CID 10288.
+
+ - coders/pdb.c: Resolve Coverity CID 11173 "Buffer not null
+ terminated".
+
+2015-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (GetMagickInfoArray): Resolve Coverity CID 10212
+ "Missing unlock".
+
+ - magick/colormap.c (ReplaceImageColormap): Allocate new image
+ colormap up front in order to avoid the possibility that we are
+ left with an image with no colormap due to memory allocation
+ failure. If there is a memory allocation failure, then the
+ original colormap is preserved. Resolves Coverity CID 10194
+ "Dereference after null check".
+
+ - magick/utility.c (MagickStripSpacesFromString): New private
+ utility function to strip spaces from a string.
+
+ - magick/color\_lookup.c (GetColorInfoArray): Resolves Coverity CID
+ 10231 "Missing unlock"
+ (ReadColorConfigureFile): Resolves Coverity CID 10261 "Use of
+ untrusted scalar value"
+ (GetColorInfo): Resolves Coverity CID 10077 "Overlapping buffer in
+ memory copy".
+
+2015-01-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadOnePNGImage): Use png\_error() instead of
+ throwing an exception so cleanup in the setjmp block can happen,
+ including unlocking the semaphore. Resolves Coverity CID 10232.
+
+ - coders/png.c (ReadOnePNGImage): Moved a logging statement into a
+ block where "attribute" has been checked for NULL. Resolves
+ Coverity CIDs 10185 and 10187.
+
+ - coders/png.c (ReadMNGImage): Fixed a cut-and-paste typo
+ (change\_delay should be change\_timeout) reported by Coverity
+ CID 10090.
+
+2015-01-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (CloneImage): The definition is poor as to what a
+ non-orphan clone should do. However, the definition surely does
+ not include crashing the software or supplanting the original
+ image in an image list. Clone image blob and previous/next
+ pointers but do not supplant original image in list. Resolves
+ Coverity CID 10155.
+
+2015-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (WriteRowSamples): Ensure that callback function is
+ always defined. Resolves Coverity CID 10122.
+ (ReadRowSamples): Ensure that callback function is always
+ defined. Resolves Coverity CID 10125.
+
+ - magick/random.c (InitializeMagickRandomKernel): Avoid possible
+ double-close of file. Resolves Coverity CID 10257.
+
+ - coders/histogram.c (WriteHISTOGRAMImage): Avoid possible divide
+ by zero exception. Resolves Coverity CID 10107.
+
+ - magick/error.c (MagickFatalError): Document that
+ MagickFatalError() is not supposed to return (program must quit)
+ and add GCC/Clang hints to that effect.
+
+ - magick/bit\_stream.c (BitAndMasks): Avoid possible access
+ one-beyond end of BitAndMasks array. It is not clear if there is
+ a possible bug with 32-bit quantums. If there is a bug, it has
+ not been noticed via testing. Resolves Coverity CID 10213.
+
+ - magick/tempfile.c (AcquireTemporaryFileDescriptor): Avoid buffer
+ overrun in the case of an astonishingly long environment variable
+ string. Resolves Coverity CID 10267.
+ (AddTemporaryFileToList): Use strlcpy() rather than strlcpy(). In
+ practice, should not make a difference. Will quiet Coverity CID
+ 10321.
+
+ - magick/command.c (GMCommandSingle): Don't use the address of a
+ stack allocation to update argv[0]. Removed updating argv[0] until
+ a better design can be found. Resolves Coverity CID 10223.
+ (GMCommandSingle): Plan B: Use static allocation from
+ SetClientName() to both store the new command name and provide
+ storage for argv[0].
+
+ - magick/utility.c (SystemCommand): Fix possible overwrite of
+ memory location due to uninitialized 'end' pointer. Resolves
+ Coverity CID 10251.
+
+ - magick/blob.c (WriteBlobFile): Was not closing file in certain
+ error conditions. Resolves Coverity CID 10237.
+
+ - coders/cineon.c (ReadCINEONImage): Don't trust file header so
+ much. Resolves Coverity CIDs 10079, 10310, 10325.
+
+ - coders/art.c (ReadARTImage): Fix signed vs unsigned comparison
+ caused by earlier changes.
+
+2014-01-17 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/wpg.c Do not execute wpg raster read in ping mode.
+
+2014-01-15 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Properly deallocating zip structures.
+
+2015-01-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sfw.c (ReadSFWImage): Fix pixel cache access errors in
+ 'ping' mode.
+
+2015-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/wmf.c (ReadWMFImage): Fix memory leak in 'ping' mode and
+ some error paths.
+
+2015-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jbig.c (ReadJBIGImage): Fix memory leak in 'ping' mode.
+
+ - magick/delegate.c (InvokeDelegate): Fix memory leak of argument
+ list when invoking external program via MagickSpawnVP().
+
+2015-01-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (InitializeMagickResources): Base image width
+ and height default limits on the range of a 32-bit signed integer,
+ even for 64-bit builds. These limits are still beyond what most
+ computers in the world can handle. Limits can be increased by the
+ user.
+
+ - coders/xwd.c (ReadXWDImage): Check image size limits
+ immediately.
+
+ - coders/xc.c (ReadXCImage): Check image size limits immediately.
+
+ - coders/webp.c (ReadWEBPImage): Check image size limits
+ immediately.
+
+ - coders/viff.c (ReadVIFFImage): Check image size limits
+ immediately.
+
+ - coders/vicar.c (ReadVICARImage): Check image size limits
+ immediately.
+
+ - coders/txt.c (ReadTXTImage): Check image size limits
+ immediately.
+
+ - coders/ttf.c (ReadTTFImage): Check image size limits
+ immediately.
+
+ - coders/tim.c (ReadTIMImage): Check image size limits
+ immediately.
+
+ - coders/tiff.c (ReadTIFFImage): Check image size limits
+ immediately.
+
+ - coders/tga.c (ReadTGAImage): Check image size limits
+ immediately.
+
+ - coders/sgi.c (ReadSGIImage): Check image size limits
+ immediately.
+
+ - coders/sct.c (ReadSCTImage): Check image size limits
+ immediately.
+
+ - coders/rle.c (ReadRLEImage): Check image size limits
+ immediately.
+
+ - coders/rla.c (ReadRLAImage): Check image size limits
+ immediately.
+
+ - coders/psd.c (ReadPSDImage): Check image size limits
+ immediately.
+
+ - coders/pnm.c (ReadPNMImage): Check image size limits
+ immediately.
+
+ - coders/pix.c (ReadPIXImage): Check image size limits
+ immediately.
+
+ - coders/pict.c (ReadPICTImage): Check image size limits
+ immediately.
+
+ - coders/pdb.c (ReadPDBImage): Check image size limits
+ immediately.
+
+ - coders/pcx.c (ReadPCXImage): Check image size limits
+ immediately.
+
+ - coders/pcd.c (ReadPCDImage): Check image size limits
+ immediately.
+
+ - coders/otb.c (ReadOTBImage): Check image size limits
+ immediately.
+
+ - coders/null.c (ReadNULLImage): Check image size limits
+ immediately.
+
+ - coders/mvg.c (ReadMVGImage): Check image size limits
+ immediately.
+
+ - coders/mtv.c (ReadMTVImage): Check image size limits
+ immediately.
+
+ - coders/mpc.c (ReadMPCImage): Check image size limits
+ immediately.
+
+ - coders/miff.c (ReadMIFFImage): Check image size limits
+ immediately.
+
+ - coders/jpeg.c (ReadJPEGImage): Check image size limits
+ immediately.
+
+ - coders/jp2.c (ReadJP2Image): Check image size limits
+ immediately.
+
+ - coders/jbig.c (ReadJBIGImage): Check image size limits
+ immediately.
+
+ - coders/hdf.c (ReadHDFImage): Check image size limits
+ immediately.
+
+ - coders/gif.c (ReadGIFImage): Check image size limits
+ immediately.
+
+ - coders/fpx.c (ReadFPXImage): Check image size limits
+ immediately.
+
+ - coders/fax.c (ReadFAXImage): Check image size limits
+ immediately.
+
+ - coders/dpx.c (ReadDPXImage): Check image size limits
+ immediately.
+
+ - coders/dps.c (ReadDPSImage): Check image size limits
+ immediately.
+
+ - coders/dib.c (ReadDIBImage): Check image size limits
+ immediately.
+
+ - coders/dcm.c (ReadDCMImage): Check image size limits
+ immediately.
+
+ - coders/cut.c (ReadCUTImage): Check image size limits
+ immediately.
+
+ - coders/cineon.c (ReadCINEONImage): Check image size limits
+ immediately.
+
+ - coders/avs.c (ReadAVSImage): Check image size limits
+ immediately.
+
+ - coders/art.c (ReadARTImage): Check image size limits
+ immediately.
+
+ - coders/sun.c (ReadSUNImage): Check image size limits in advance
+ of allocating memory for pixels.
+
+ - coders/bmp.c (ReadBMPImage): Check image size limits in advance
+ of allocating memory for pixels.
+
+ - coders/sun.c (ReadSUNImage): There is no definition for Sun map
+ type RMT\_RAW so it can not be supported. Update DirectClass
+ pixels directly rather using SyncImage(). Problem was reported by
+ Jodie Cunningham.
+
+2015-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pict.c (ReadPICTImage): Fix PICT reader crash when
+ reading corrupted file.
+
+ - coders/sun.c (ReadSUNImage): Sun reader was still not as robust
+ as it should be. Now it is.
+
+2014-01-10 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/wpg.c Fixed reading behind EOF issue.
+
+2015-01-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (LSBPackedU32WordToOctets): Fix typo which adds
+ severe corruption to encoded little-endian 32-bit packed output.
+ The good news is that since the corruption is severe, it is easily
+ visually detected. The problem has corrupted all such
+ (little-endian 10-bit) output since it was originally implemented
+ on 2007-06-17 (changeset 11686, first released in GraphicsMagick
+ 1.1.8). GraphicsMagick preserves the endianness of input DPX
+ files by default, defaults to big-endian, and DPX files are
+ commonly big-endian, so this problem may not have occured for many
+ usages. Problem was reported by Steve Dabner on the
+ GraphicsMagick discussion mailing list.
+
+2015-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (MagickPanicSignalHandler): Print a message in
+ the case of signals SIGXCPU and SIGXFSZ.
+
+ - coders/bmp.c (ReadBMPImage): Don't hang in endless loop if EOF
+ is encountered while checking for "BA" header.
+
+ - coders/icon.c (ReadIconImage): Limit icon image allocation size.
+
+2015-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/icon.c (ReadIconImage): Removed all of the
+ previously-existing DIB reading code from icon.c and use new
+ "ICODIB" reader to read DIB icons, or the PNG reader to read PNG
+ icons.
+
+ - coders/dib.c (ReadDIBImage): Added an "ICODIB" coder for
+ internal use which reads a Windows BMP 3 DIB followed by a Windows
+ ICO alpha mask. This allows existing DIB code to be used to read
+ ICO directory entries.
+
+2015-01-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/icon.c: The Windows ICO reader is now more robust. Still
+ a work in progress since some files still can not be read or read
+ incorrectly.
+
+2015-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/resource.c (ListMagickResourceInfo): "kilo" for binary
+ prefixes is supposed to be "Ki".
+
+ - magick/utility.c (FormatSize): "kilo" for binary prefixes is
+ supposed to be "Ki".
+
+2015-01-01 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Use WidthResource and HeightResource instead
+ of fixed 1-million limit for rows and columns.
+
+2015-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/utility.c (FormatSize): Add 'i' to value range
+ identifiers since these are all in units of 2^10 rather than 1000.
+
+ - magick/pixel\_cache.c (CheckImagePixelLimits): Fix typo and
+ produce an informative error message.
+
+ - magick/resource.c: Added support for Image width and height
+ pixels resource limits.
+
+ - magick/resource.h (ResourceType): New resource enumerations
+ WidthResource and HeightResource.
+
+ - magick/enum\_strings.c (StringToResourceType): Added support for
+ parsing '-limit Width' and '-limit Height'.
+
+ - magick/pixel\_cache.c (CheckImagePixelLimits): New function to
+ test image to see if it exceeds pixels limits.
+
+ - coders/viff.c (ReadVIFFImage): Make the VIFF reader robust with
+ detecting and reporting problems.
+
+2014-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Rotate Changelog for new year. Update documentation copyrights
+ for new year.
+
+
diff --git a/www/ChangeLog-2016.html b/www/ChangeLog-2016.html
new file mode 100644
index 0000000..8200052
--- /dev/null
+++ b/www/ChangeLog-2016.html
@@ -0,0 +1,1061 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2016-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (WritePNMImage): Support writing GRAYSCALE PAM
+format. Before this fix, grayscale output was marked as type
+BLACKANDWHITE. Problem was reported by Aaron Boxer via email on
+December 31, 2016.</li>
+<li>TclMagick/generic/Makefile.am: Applied patch by Massimo Manghi
+(plus some fixes by me) to add a 'libttkcommon' shared library to
+contain codde common to the TclMagick/TkMagick loadable modules,
+and particularly to allow TkMagick to access TclMagick functions
+without depending on dlopen() with RTLD_GLOBAL behavior.</li>
+</ul>
+</blockquote>
+<p>2016-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/compare.c (DifferenceImage): Fix all-black difference
+image if an input file is colormapped. Resolves SourceForge issue
+#404 &quot;Difference file does not work if PNG &quot;.</li>
+</ul>
+</blockquote>
+<p>2016-12-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul>
+<li><p class="first">coders/txt.c (ReadTXTImage): Fix Coverity issue 55866 &quot;Resource
+leak&quot;.</p>
+</li>
+<li><p class="first">magick/enum_strings.c (StringToCompositeOperator): Fix Coverity
+issue 139296 &quot;Constant expression result&quot;.</p>
+</li>
+<li><p class="first">magick/channel.c (ImportImageChannelsMasked): Fix Coverity issue
+139297 &quot;Constant expression result&quot;. This was a bug but only in
+terms of reduced performance, not results.</p>
+</li>
+<li><p class="first">Magick++/lib/Drawable.cpp
+(PathSmoothCurvetoRel::operator): Fix Coverity issue 139301 &quot;Using
+invalid iterator&quot;.
+(PathSmoothCurvetoRel::operator): Fix Coverity issue 139302 &quot;Using
+invalid iterator&quot;</p>
+</li>
+<li><p class="first">magick/attribute.c: From SourceForge patches #47
+&quot;GraphicsMagick-1.3.25-get-exif-attribute-gps-fix.patch&quot; and
+&quot;GraphicsMagick-1.3.25-set-exif-orientation-fix.patch&quot; by Troy
+Patteson with description (related to provided Coverity reports in
+coverity.txt): Those coverity errors indicate a problem with the
+earlier patch I sent you to fix getting the EXIF orientation when
+the GPS IFD occurs before the EXIF IFD. Although the patch fixed
+that issue it introduced a new issue in that GPS tags could no
+longer be retrieved. This occurs because the gpsfound flag is set
+when the GPS IFD is pushed onto the stack but then cleared
+immediately when breaking out of the loop processing the directory
+entries for the current IFD. The solution is to push the gpsfound
+flag onto the stack as well as it needs to be set when the GPS IFD
+is popped off the stack rather than being set straight away.</p>
+<p>The second coverity error relates to gpsoffset not being set in
+FindEXIFAttribute(). The code that sets gpsoffset in
+GenerateEXIFAttribute() was embedded in the code that gets tags
+values which was removed in FindEXIFAttribute() as only the DE
+offset is required. I have removed the need for gpsoffset and just
+computed the GPS IFD offset when pushing it onto the stack in the
+same way the EXIF IFD offset is computed.</p>
+</li>
+</ul>
+</blockquote>
+<p>2016-12-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul>
+<li><p class="first">magick/attribute.c: From SourceForge patches #47
+&quot;GraphicsMagick-1.3.25-5-set-exif-orientation.patch&quot; by Troy
+Patteson with description: Rotating an image without resetting the
+EXIF orientation tag is problematic as follow-on viewers that
+support the EXIF orientation tag may incorrectly rotate the image
+a second time. For JPEG images, the current solution is to either
+strip the image, remove the EXIF profile or modify the EXIF data
+of the written image with other software. This patch adds the
+ability to set the orientation tag in the EXIF profile via the
+SetImageAttribute on attribute EXIF:Orientation provided the EXIF
+orientation already exists. AutoOrientImage() has been modified to
+set the EXIF orientation tag on successful rotation of the image.</p>
+<p>The implementation is less than ideal. The EXIF profile must be
+duplicated because it is returned read-only from the profiles
+map. Large amounts of the GenerateEXIFAttribute() function has
+been duplicated in a function called FindEXIFAttribute() which
+returns the offset in the EXIF profile of a given tag ID. Once
+found, the orientation tag value is updated accordingly and the
+new EXIF profile set. Despite the patches shortcomings, I believe
+it is preferable to leaving the EXIF orientation tag unchanged
+after auto-orienting the image.</p>
+</li>
+<li><p class="first">wand/magick_wand.c (MagickClearException): From SourceForge
+patches #47 &quot;GraphicsMagick-1.3.25-1-wand-clear-exception.patch&quot;
+by Troy Patteson with description: This patch adds the ability to
+clear the last Wand exception. This is particularly useful to
+clear any exception on the Wand before calling MagickReadImage()
+which can return success with a warning exception such as &quot;JPEG
+data: premature end of data segment&quot;.
+(MagickRemoveImageOption): From SourceForge patches #47
+&quot;GraphicsMagick-1.3.25-2-wand-remove-image-option.patch&quot; by Troy
+Patteson with description: There is MagickSetImageOption() to set
+options like JPEG preserve-settings but no way to remove the
+option once set. Since the mechanism to remove image options
+already exists in lower-level API there seems no reason not to
+expose it in the Wand API.
+(MagickGetImageOrientation, MagickSetImageOrientation): From
+SourceForge patches #47
+&quot;GraphicsMagick-1.3.25-3-wand-get-set-orientation.patch&quot; by Troy
+Patteson with description: MagickGetImageOrientation returns the
+internal orientation setting which is useful to know to determine
+whether an image needs rotation. The function to set the
+orientation is less useful as it only sets the internal
+orientation setting which is only used when writing out TIFF
+files. A future patch addresses this issue.
+(MagickAutoOrientImage): From SourceForge patches #47
+&quot;GraphicsMagick-1.3.25-4-wand-auto-orient.patch&quot; by Troy Patteson
+with description: This patch adds auto-orient image to the Wand
+API.</p>
+</li>
+</ul>
+</blockquote>
+<p>2016-12-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>TclMagick/{configure.ac, Makefile.am}: Applied patches by
+Massimo Manghi to use TEA tcl.m4 version 3.9.</li>
+</ul>
+</blockquote>
+<p>2016-11-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/gif.c (DecodeImage): Applied fixes by Tianyu Lang for
+&quot;Excessive LZW string data&quot; problem leading to &quot;Corrupt image&quot;
+report while reading some GIF files.</li>
+</ul>
+</blockquote>
+<p>2016-11-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc, doc/config_files.imdoc, doc/benchmark.imdoc:
+Fixed some indentation in the documentation.</li>
+</ul>
+</blockquote>
+<p>2016-10-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>acinclude.m4 (LIBS): Fix memory leaks in GM_FUNC_MMAP_FILEIO
+macro test-case so that it can be used successfully with ASAN
+compilation options.</li>
+<li>magick/blob.c: Eliminate unused variable compiler warnings when
+HAVE_MMAP_FILEIO is not defined.</li>
+</ul>
+</blockquote>
+<p>2016-10-24 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Ability to read multiple images from Matlab V4 format.</li>
+</ul>
+</blockquote>
+<p>2016-10-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<p>*coders/png.c (ReadOneJNGImage): Enforce spec requirement that the
+dimensions of the JPEG embedded in a JDAT chunk must match the
+JHDR dimensions. This issue was assigned CVE-2016-9830 on
+2016-12-04. Please note that GraphicsMagick's pixel, width, and
+height default limits are often greater than the dimension limits
+of JNG and JPEG so the user should add explicit limits (if needed)
+to prevent unexpected memory consumption from properly-constructed
+JNG files with large dimensions.</p>
+<p>*doc/options.imdoc (-strip): Added a caution to not use the -strip
+option to remove author, copyright, and license information
+when redistributing an image that requires them to be retained.</p>
+<p>*doc/options.imdoc (-comment and -label): Document the fact that
+only one comment or label is stored, and how they are stored in
+PNG files.</p>
+</blockquote>
+<p>2016-10-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sgi.c (ReadSGIImage): Adjusts some variable types and
+lessen the amount of casting.</li>
+</ul>
+</blockquote>
+<p>2016-10-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (ReadJNGImage): Quiet COVERITY issue about
+a potential memory leak.</li>
+</ul>
+</blockquote>
+<p>2016-10-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xcf.c (ReadXCFImage): Fix memory leak of layer_info for
+some recently added error-return paths.</li>
+</ul>
+</blockquote>
+<p>2016-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sgi.c (ReadSGIImage): For RLE SGI image, defer memory
+allocations for as long as possible and allow the file to prove
+itself worthy before making the largest allocations. This helps
+with rejecting bogus RLE files while avoiding rejecting valid
+files.</li>
+</ul>
+</blockquote>
+<p>2016-10-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): If TIFF uses Old JPEG
+compression, then read using full tiles or strips. Solves
+&quot;Improper call to JPEG library in state 0. (LibJpeg).&quot; error.
+Problem was reported via email on October 6, 2016 by John Brown.</li>
+</ul>
+</blockquote>
+<p>2016-10-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/attribute.c (GenerateEXIFAttribute): Fixed SourceForge
+bug 400 &quot;Exif orientation unknown for some JPEG files&quot;. Patch
+submitted by Troy Patteson.</li>
+</ul>
+</blockquote>
+<p>2016-10-02 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/wpg.c Add sanity check for palette. Merge
+RemoveLastImageFromList+AppendImageToList to ReplaceImageInList.
+Possible heap overflow of colormap in Q8 build was assigned
+CVE-2016-7996. Assertion crash due to blob != NULL was assigned
+CVE-2016-7997.</li>
+</ul>
+</blockquote>
+<p>2016-10-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/meta.c (parse8BIM): Fix unsigned underflow leading to
+heap overflow when parsing 8BIM chunk. Problem was reported by
+Marco Grassi via email on October 1, 2016. Problem was already
+known (but not fixed) based on comments in the code. This issue
+has been assigned CVE-2016-7800.</li>
+</ul>
+</blockquote>
+<p>2016-09-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xcf.c: Improve the robustness of the XCF reader by adding
+more error checking.</li>
+</ul>
+</blockquote>
+<p>2016-09-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/rle.c (RLEConstrainColormapIndex): Was not constraining
+colormap index like it should be. This problem was added on
+2016-09-23.</li>
+<li>www/thanks.rst: Added Moshe Kaplan to Thanks.</li>
+<li>www/Hg.rst: Mercurial URL fixes. Patch from Mark Mitchell.</li>
+<li>www/programming.rst: Updated programming APIs page.</li>
+</ul>
+</blockquote>
+<p>2016-09-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/pixel_cache.c (OpenCache): Trace ExtendCache() failures.</li>
+</ul>
+</blockquote>
+<p>2016-09-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sgi.c (ReadSGIImage): Fix unexpectedly large memory
+allocation with corrupt SGI file provided via email by Agostino
+Sarubbo on September 15, 2016.</li>
+<li>coders/rle.c (ReadRLEImage): Only report an invalid colormap
+index once. Fixes slowness problem with corrupt file provided via
+email by Agostino Sarubbo on September 15, 2016.</li>
+</ul>
+</blockquote>
+<p>2016-09-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/thanks.rst: Added a 'thanks' page.</li>
+</ul>
+</blockquote>
+<p>2016-09-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/MANIFEST: Fix content of PerlMagick MANIFEST.</li>
+</ul>
+</blockquote>
+<p>2016-09-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pcx.c (ReadPCXImage): Check that filesize is reasonable
+given header. Fixes excessive memory allocation followed by
+eventual file truncation error for corrupt file. Problem was
+reported via email by Agostino Sarubbo on 2016-09-10.</li>
+<li>coders/sgi.c (ReadSGIImage): Check that filesize is reasonable
+given header. Fixes excessive memory allocation followed by
+eventual file truncation error for corrupt file. Problem was
+reported via email by Agostino Sarubbo on 2016-09-09.</li>
+<li>coders/sct.c (ReadSCTImage): Fix stack-buffer read overflow
+while reading SCT header. Problem was reported via email by
+Agostino Sarubbo on 2016-09-09.</li>
+<li>coders/svg.c: Fix Coverity issue 135772 &quot;RESOURCE_LEAK&quot; and
+issue 135829 &quot;Null pointer dereferences&quot;. None of these issues
+were new, but Coverity noticed them now. Reflowed source to GNU C
+style for consistent indentation and so it does not fight with my
+editor.</li>
+</ul>
+</blockquote>
+<p>2016-09-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/common.h (MAGICK_HAS_ATTRIBUTE): Coverity is allergic to
+__has_attribute() so don't use it for Coverity builds.</li>
+</ul>
+</blockquote>
+<p>2016-09-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/index.rst: Update for 1.3.25 release.</li>
+<li>version.sh: Update library versioning for 1.3.25 release.</li>
+<li>NEWS.txt: Make sure is up to date.</li>
+<li>Various fixes for minor issues noticed when compiling under
+Visual Studio.</li>
+</ul>
+</blockquote>
+<p>2016-08-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/studio.h (MAGICK_CACHE_LINE_SIZE): Apply patch from
+Gentoo Linux to increase MAGICK_CACHE_LINE_SIZE to 128 when
+__powerpc__ is defined.</li>
+</ul>
+</blockquote>
+<p>2016-08-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated with latest changes.</li>
+</ul>
+</blockquote>
+<p>2016-08-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/rle.c (ReadRLEImage): Reject truncated/absurd Utah RLE
+files. Problem was reported by Agostino Sarubbo on August 19,
+2016. This problem was assigned CVE-2016-7448 after the 1.3.25
+release.</li>
+</ul>
+</blockquote>
+<p>2016-08-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (ReadTIFFImage): Fix heap-based buffer read
+overflow. TIFF sized attibutes were not being properly copied to
+a null-terminated string if the value was not null terminated.
+Problem was reported by Agostino Sarubbo on August 18, 2016. This
+problem was assigned CVE-2016-7449 after the 1.3.25 release.</li>
+</ul>
+</blockquote>
+<p>2016-08-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lcms/src/cmstypes.c (Type_MLU_Read): &quot;Added an extra check to
+MLU bounds&quot;, change based on github mm2/Little-CMS commit
+5ca71a7bc18b6897ab21d815d15e218e204581e2 and announced to the
+oss-security list by Ibrahim M. El-Sayed on Mon, 15 Aug 2016.</li>
+</ul>
+</blockquote>
+<p>2016-08-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>webp: Updated bundled libwebp to release 0.5.1.</li>
+<li>libxml: Updated bundled libxml2 to release 2.9.4.</li>
+<li>lcms: Updated bundled lcms2 to release 2.8.</li>
+<li>png: Update bundled libpng to release 1.6.24.</li>
+<li>coders/jpeg.c (ReadJPEGImage): Log setting resolution and
+resolution units due to JFIF marker.</li>
+<li>coders/sgi.c (SGIDecode): Fix integer overflow of size type in
+Win64 build where sizeof(long) &lt; sizeof(size_t).</li>
+</ul>
+</blockquote>
+<p>2016-08-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders, magick: Compile clean using GCC with -std=c90.</li>
+<li>magick/describe.c (DescribeImage): The 'identify' and 'info'
+functionality only shows the pixel read rate if image was not read
+in 'ping' mode. Provide seconds timing with 6 digits of precision
+since that is what is needed.</li>
+</ul>
+</blockquote>
+<p>2016-08-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/describe.c (DescribeImage): Include milliseconds
+resolution in elapsed time output.</li>
+<li>magick/timer.c (ElapsedTime): Use clock_gettime() (when
+available with default linkage) to obtain elapsed time.</li>
+</ul>
+</blockquote>
+<p>2016-08-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/yuv.c (WriteYUVImage): Fix benign clang compiler warning
+regarding &quot;variable 'x' is incremented both in the loop header and
+in the loop body&quot;.</li>
+<li>configure.ac: Fixes to use clang's OpenMP runtime library
+(-lomp) for clang 3.8 and later. Specifically tested with clang
+3.8 on Ubuntu 16.04 'xenial'. Problem was reported by Holger
+Hoffstätte via private email.</li>
+<li>NEWS.txt: Bring up to date with latest changes.</li>
+</ul>
+</blockquote>
+<p>2016-07-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawImage): Reject abnormally absurd gradient
+size requests (many absurd requests are still allowed). Provide
+detailed error reports when a gradient is rejected.</li>
+<li>coders/svg.c: Support units for 'stroke-dashoffset'.</li>
+</ul>
+</blockquote>
+<p>2016-07-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/annotate.c (EscapeParenthesis): In private email on
+2016-07-07, Gustavo Grieco notified us of a heap overflow in
+EscapeParenthesis(). I was not able to reproduce the issue but
+changed the implementation with the suspicion that the
+implementation has a bug, and due to noticing arbitary limits and
+inefficiency. This issue was assigned CVE-2016-7447 after the
+1.3.25 release.</li>
+</ul>
+</blockquote>
+<p>2016-07-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawImage): Fix absolute and arbitrary gradient
+dimension sanity checks which caused gradient requests to fail.
+Resolves SourceForge issue #392 &quot;SVG 'push defs' fails (Debian
+bugs 829063 and 828120)&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-06-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/security.rst: Add discussion of SVG format and SSRF
+vulnerability.</li>
+</ul>
+</blockquote>
+<p>2016-06-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/svg.c (ReadSVGImage): Assure that SVGInfo data is freed
+when XMP parsing is aborted due to an error.</li>
+</ul>
+</blockquote>
+<p>2016-06-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated NEWS with changes since last release.</li>
+<li>www/security.rst: Add a page about GraphicsMagick security.</li>
+</ul>
+</blockquote>
+<p>2016-06-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawPrimitive): Over-aggressive error reporting
+was causing failures when elements were &quot;drawn&quot; off-image.
+Resolves SourceForge issue #389 &quot;Non-conforming drawing primitive
+definition (line)&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-05-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawImage): Fix problem while reading file
+&quot;tnamkejarz.svg.2532308010849170049&quot; provided via private email
+from Gustavo Grieco on May 31, 2016.</li>
+<li>magick/utility.c (MagickGetToken): Fix problem while reading
+file &quot;vqxwatmqmi.svg.-3669039972557308254&quot; provided via private
+email from Gustavo Grieco on May 31, 2016.</li>
+</ul>
+</blockquote>
+<p>2016-05-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Update for 1.3.24 release.</li>
+<li>www/Changes.rst: Mention 1.3.24 release.</li>
+<li>www/index.rst: Update for 1.3.24 release.</li>
+<li>version.sh: Update library ABI information in preparation for
+1.3.24 release.</li>
+<li>NEWS.txt: Updated NEWS to reflect fixes and issues.</li>
+</ul>
+</blockquote>
+<p>2016-05-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated with latest news.</li>
+<li>magick/blob.c (OpenBlob): Remove support for reading input from
+a shell command, or writing output to a shell command, by
+prefixing the specified filename (containing the command) with a
+'|'. This feature provided a remote shell execution opportunity
+(CVE-2016-5118).</li>
+<li>coders/mat.c (ReadMATImage): Validate that MAT frames is not
+zero.</li>
+</ul>
+</blockquote>
+<p>2016-05-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawImage): Be less optimistic when estimating
+the number of points required to represent a path. This should
+help address CVE-2016-2317 &quot;Heap buffer overflow&quot;. This resolves
+SourceForge issue #275 &quot;Applying Clipping Path to high resolution
+JPG&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-05-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawImage): Fix problem while reading file
+&quot;pxypjhfdxf.svg.7406476585885697806&quot; provided via via private
+email from Gustavo Grieco on May 24, 2016.</li>
+<li>coders/svg.c: Fix problem while reading file
+&quot;pxypjhfdxf.svg.308008972284643989&quot; provided via private email
+from Gustavo Grieco on May 24, 2016.</li>
+</ul>
+</blockquote>
+<p>2016-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/svg.c (&quot;C&quot;): Support font-size &quot;medium&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-05-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated NEWS.txt to reflect latest changes.</li>
+<li>magick/render.c (DrawImage): Added DrawImage() recursion
+detection/prevention.</li>
+<li>coders/svg.c (ReadSVGImage): Add basic primitive argument
+validation.</li>
+<li>magick/render.c (DrawImage): Add basic primitive argument
+validation.</li>
+</ul>
+</blockquote>
+<p>2016-05-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/url.c (ReadURLImage): Reading &quot;<a class="reference external" href="file://">file://</a>&quot; URLs was not
+working. Now file URLs are working.</li>
+</ul>
+</blockquote>
+<p>2016-05-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Respect JPEG limits (65535x65535) and user width
+and height limits from &quot;-limit&quot; while reading or writing JNG files.</li>
+</ul>
+</blockquote>
+<p>2016-05-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/url.c: Don't hide HTTP, FTP, and FILE URL support from
+'-list format' output. Ignore HTTP, FTP, and FILE as a useful
+file extension for determing the file format.</li>
+</ul>
+</blockquote>
+<p>2016-05-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (ConvertPathToPolygon): Make sure that first
+edge is initialized. Make sure that points is not null.</li>
+</ul>
+</blockquote>
+<p>2016-05-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawImage): Fixed segmentation violation while
+reading file &quot;275077586554139424.lqxdgqxtfs.svg&quot; provided via
+private email from Gustavo Grieco on May 15, 2016. This is due to
+another CVE-2016-2317 related issue.</li>
+</ul>
+</blockquote>
+<p>2016-05-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/svg.c (&quot;C&quot;): Fixed problems while reading files
+&quot;aaphrbkwwe.svg.-1899680443073025602&quot;,
+&quot;aaphrbkwwe.svg.-5751004588641220738&quot;,
+&quot;aaphrbkwwe.svg.-8875730334406147537&quot;, and
+&quot;aaphrbkwwe.svg.4495884156523242589&quot; provided via private email
+from Gustavo Grieco on February 8, 2016.</li>
+</ul>
+</blockquote>
+<p>2016-05-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dib.c (ReadDIBImage): Verify that DIB file data is
+sufficient to meet claims made by file header. Validate image
+planes. Fixes Fixes problem reported by Hanno Böck on May 8th,
+2016 via private email entitled &quot;malloc issue in ReadDIBImage&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-05-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/msl.c (RegisterMSLImage): Ignore the file extension on
+MSL files. The only way to read an image from a MSL file (as
+opposed to explicitly running a MSL script with 'conjure') is by
+reading using a filename specification like &quot;msl:filename&quot;. This
+is done for security reasons.</li>
+<li>magick/render.c (DrawPrimitive): Fix Coverity issue 126378
+&quot;Resource leak&quot;.</li>
+<li>coders/mat.c (DecompressBlock): Fix Coverity issue 126379
+&quot;Resource leak&quot;.</li>
+<li>magick/render.c (DrawImage): Fix Coverity issue 126380 &quot;Resource
+leak&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-05-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawPrimitive): Sanity check the image file
+path or URL before passing it to ReadImage().</li>
+<li>config/delegates.mgk.in: Pare down delegates.mgk to reduce
+security exposure due to external programs not under our control.</li>
+</ul>
+</blockquote>
+<p>2016-05-08 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Typo fix - matrix has nothing to do with PostScript.</li>
+</ul>
+</blockquote>
+<p>2016-05-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c (DecompressBlock): Don't hang on a corrupt deflate
+stream when reading matlab v6 file. Fixes problem reported by
+Hanno Böck on May 8, 2016 via private email entitled &quot;hang of
+matlab input file&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-05-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Undocumented &quot;TMP&quot; magick prefix
+no longer removes the argument file after it has been read. This
+functionality is only used to support the &quot;show&quot; delegate which is
+used by options in the 'display' program which need to display a
+generated image in a new instance of 'display'. The &quot;show&quot;
+delegate is used by writing a temporary file to be viewed, and
+which should be removed before the program quits. Since the &quot;TMP&quot;
+feature was originally implemented, GraphicsMagick added a
+temporary file management subsystem which assures that temporary
+files are removed so this feature is not needed.</li>
+<li>coders/tiff.c (ReadTIFFImage): Fix heap overflow with file
+&quot;gkkxrilssm.tiff.-4678010562506843336&quot; provided by Gustavo Grieco
+on February 8, 2006 via private email.</li>
+<li>coders/viff.c (ReadVIFFImage): Fix problem with a very large
+malloc in sample file provided by Hanno Böck on May 7, 2016 with
+subject &quot;large malloc in ReadVIFFImage&quot;.</li>
+<li>coders/mvg.c (RegisterMVGImage): Do not auto-detect MVG format
+based on file extension. MVG files can then only be read by
+adding a &quot;MVG:&quot; prefix to the file name. There is already no
+auto-detection of MVG based on content.</li>
+</ul>
+</blockquote>
+<p>2016-05-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xpm.c (ReadXPMImage): Limit the number of XPM colors and
+assure array initialization. Fixes bad behavior with a sample
+file provided by Hanno Böck on May 6, 2016 with subject &quot;Invalid
+free in ReadXPMImage&quot;.</li>
+<li>coders/pcx.c (ReadPCXImage): Limit the number of PCX image
+planes allowed. Fixes an unreasonable memory allocation in a
+sample file provided by Hanno Böck on May 5, 2016.</li>
+</ul>
+</blockquote>
+<p>2016-05-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>config/delegates.mgk.in: Gnuplot files are inherently insecure.
+Remove delegates support for reading them. Reported by John
+Lightsey via private email.
+Added -dSAFER to Ghostscript invokations in delegates.mgk for more
+secure execution. Reported by David Chan via SourceForge bug
+&quot;#386 ghostscript delegates should explicitly use -dSAFER.&quot;.</li>
+<li>magick/constitute.c (ReadImages): Avoid possible infinite
+ReadImage() recursion.</li>
+</ul>
+</blockquote>
+<p>2016-05-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawPolygonPrimitive): Fix divide by zero
+exception encountered while reading file &quot;sigfpe.svg&quot; posted by
+Gustavo Grieco on May 1, 2016 to the oss-security mailing list
+with subject &quot;CVE request: DoS in multiple versions of
+GraphicsMagick&quot;.
+(DrawDashPolygon): Fix endless loop problem caused by negative
+stroke-dasharray arguments. Resolves problem observed while
+reading file &quot;circular.svg&quot; posted by Gustavo Grieco on May 1,
+2016 to the oss-security mailing list with subject &quot;CVE request:
+DoS in multiple versions of GraphicsMagick&quot;.</li>
+<li>magick/import.c (ImportViewPixelArea): Fix assertion while
+reading TIFF file gkkxrilssm.tiff.105123337066 provided by Gustavo
+Grieco.</li>
+</ul>
+</blockquote>
+<p>2016-04-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/locale.c (ReadLOCALEImage): Make sure to close blob
+before returning.</li>
+<li>coders/svg.c (&quot;C&quot;): Provide a hack work-around for double-quoted
+font-family argument.</li>
+<li>magick/render.c (DrawImage): Make SVG path and other primitive
+parsing more robust. Fixes SEGV when reading files provided by
+CVE-2016-2318 test cases. Fixes CVE-2016-2318 completely.</li>
+</ul>
+</blockquote>
+<p>2016-04-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/render.c (DrawImage): Fix heap buffer overflow when
+reading aaphrbkwwe.svg.-1114777018469422437 from CVE-2016-2317
+test cases. This resolves CVE-2016-2317 completely.</li>
+</ul>
+</blockquote>
+<p>2016-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (MogrifyImageCommand): Added mogrify
+-preserve-timestamp option to preserve file access and
+modification timestamps. Contributed by Niko Rosvall via
+SourceForge patch #45 &quot;preserve-timestamp option for mogrify
+command.&quot;</li>
+</ul>
+</blockquote>
+<p>2016-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/blob.c: Added ReadBlobLSBSignedShort(),
+ReadBlobMSBSignedShort(),
+ReadBlobLSBSignedLong(),ReadBlobMSBSignedLong(),
+WriteBlobLSBSignedShort(), WriteBlobLSBSignedLong(),
+WriteBlobMSBSignedLong(), WriteBlobMSBSignedShort() for doing I/O
+on signed integer types without the need for dangerous casts or
+unexpected values due to signed/unsigned conversion.</li>
+</ul>
+</blockquote>
+<p>2016-04-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Updated with latest changes.</li>
+<li>magick/constitute.c (ReadImage): Added asserts to check that the
+I/O blob is not still open in the returned image since this causes
+problems.</li>
+<li>magick/blob.c (CloneBlobInfo): Use a cloning approach which does
+not require manually keeping structure members in sync.</li>
+<li>coders/msl.c (ProcessMSLScript): Need to close I/O blob before
+returning.</li>
+<li>coders/psd.c (ReadPSDImage): Assure that allocated image is not
+dereferenced before checking if it is NULL. Check some memory
+calculations for overflow.
+(ReadPSDImage): Need to close I/O blob before returning.</li>
+<li>coders/dib.c (ReadDIBImage): Use DestroyBlob() rather than
+DestroyBlobInfo().</li>
+<li>coders/bmp.c (ReadBMPImage): Use DestroyBlob() rather than
+DestroyBlobInfo().</li>
+<li>magick/blob.c: Improve blob tracing.</li>
+</ul>
+</blockquote>
+<p>2016-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/bmp.c (ReadBMPImage): Fix reading 24-bit Microsoft BMP
+which claims to have a colormap.</li>
+</ul>
+</blockquote>
+<p>2016-04-13 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/input_complex_lsb_double_V4.mat Demo Matlab V4
+complex file.</li>
+<li>coders/mat.c Missing break added.</li>
+</ul>
+</blockquote>
+<p>2016-04-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xpm.c (ReadXPMImage): Fix SourceForge issue #361
+&quot;out-of-bounds read in coders/xpm.c:150:24&quot;</li>
+<li>coders/psd.c (ReadPSDImage): Add some defensive code to assure
+that image layers are not freed twice.</li>
+</ul>
+</blockquote>
+<p>2016-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/log.c (InitializeLogInfo): Simplify LogInfo structure and
+its allocation in order to lessen the amount of fixed overhead.</li>
+</ul>
+</blockquote>
+<p>2016-04-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c (WriteJP2Image): Fix SourceForge issue #378 &quot;jp2:
+impossible to create lossless jpeg-2000&quot;. With this fix,
+specifying 'define jp2:rate=1.0' or '-quality 100' results in a
+lossless JP2 file.</li>
+</ul>
+</blockquote>
+<p>2016-04-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/common.h: Update for GCC 5.</li>
+<li>PerlMagick/MANIFEST: Update PerlMagick manifest.</li>
+<li>PerlMagick/t/{read.t, write.t}: Add tests for MAT v4.</li>
+</ul>
+</blockquote>
+<p>2016-04-03 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Matlab V4 attempt to read complex part of data.</li>
+</ul>
+</blockquote>
+<p>2016-04-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick/t/features.pl.in: Provide a way that PerlMagick
+feature tests can test if a feature is supported. Use it to make
+the PSD test optional.</li>
+<li>coders/Makefile.am: Only build PSD module if
+ENABLE_BROKEN_CODERS is enabled.</li>
+<li>magick/module.c (UnloadModule): Only invoke the module
+unregister function if it is defined. The module register
+function is not defined if either the register or unregister
+functions were not found in the module which was loaded.</li>
+</ul>
+</blockquote>
+<p>2016-04-02 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><dl class="first docutils">
+<dt>coders/mat.c Matlab V4 files are also rotated.</dt>
+<dd>* PerlMagick/t/input_gray_lsb_double_V4.mat Demo Matlab V4 file.</dd>
+</dl>
+</li>
+</ul>
+</blockquote>
+<p>2016-04-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/magick.c (GetMagickInfo): Only declare that ExceptionInfo
+argument is not used if modules are not supported.</li>
+</ul>
+</blockquote>
+<p>2016-03-28 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Attempt to read Matlab V4 files.</li>
+</ul>
+</blockquote>
+<p>2016-03-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (DestroyImage): Simply return if image is NULL
+since it is more user-friendly.</li>
+<li>magick/shear.c (RotateImage): Fix Coverity issue 124519
+&quot;Logically dead code&quot;.</li>
+<li>magick/effect.c (BlurImage): Fix Coverity issue 124520
+&quot;Dereference after null check&quot;.</li>
+<li>coders/pdb.c (WritePDBImage): Fix SourceForge bug #360
+&quot;out-of-bounds read in utilities/gm+0x80fcc71) (PDB reader)&quot;.</li>
+<li>coders/meta.c (convertHTMLcodes): Fix SourceForge bug #373
+&quot;out-of-bounds read in coders/meta.c:444:50&quot;
+(ReadMETAImage): Fix SourceForge bug #364 &quot;out-of-bounds write in
+coders/meta.c:1331:7&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-03-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sgi.c (ReadSGIImage): Fix SourceForge bug #366
+&quot;out-of-bounds write in coders/sgi.c:528:4&quot; and bug #369
+&quot;out-of-bounds write in coders/sgi.c:535:4&quot;.</li>
+<li>coders/rle.c (ReadRLEImage): Fix SourceForge bug #371
+&quot;out-of-bounds read in coders/rle.c:633:39&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-03-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dib.c (ReadDIBImage): Fix SourceForge bug #367
+&quot;out-of-bounds read in coders/dib.c:706:13&quot; and bug #370
+&quot;out-of-bounds read in coders/dib.c:716:15&quot;.</li>
+<li>coders/pict.c (ReadPICTImage): Fix SourceForge bug #365
+&quot;out-of-bounds read in magick/image.c:1305:3&quot;</li>
+<li>magick/utility.c (GetPageGeometry): Fix SourceForge bug #374
+&quot;out-of-bounds write in magick/utility.c:4355:7&quot;</li>
+</ul>
+</blockquote>
+<p>2016-03-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/miff.c (ReadMIFFImage): Fix SourceForge bug #376 &quot;SIGABRT
+in magick/colorspace.c:1052&quot;.</li>
+<li>magick/shear.c (RotateImage): Fix SourceForge bug #375 &quot;SIGABRT
+in magick/image.c:1230&quot;.</li>
+<li>coders/sun.c (DecodeImage): Fix SourceForge bug #368
+&quot;out-of-bounds read in coders/sun.c:223:17&quot; and bug #363
+&quot;out-of-bounds read in coders/sun.c:221:16&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-03-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/svg.c (GetUserSpaceCoordinateValue): Fix stack buffer
+overflow when reading file 'aaphrbkwwe.svg.-632425326915265752'
+from CVE-2016-2317 problem files. Partial fix for SourceForge bug
+#358 &quot;CVE-2016-2317 - SVG heap/stack buffer overflows&quot;.</li>
+<li>magick/utility.c (MagickGetToken): New private function to
+replace GetToken(). The new function accepts a token buffer
+length argument. GetToken() is modified to assume a token buffer
+length 'MaxTextExtent'. All code using GetToken() is updated to
+use MagickGetToken().</li>
+<li>coders/svg.c: Fix heap buffer overflow when reading file
+&quot;aaphrbkwwe.svg.4495884156523242589&quot; from CVE-2016-2317 problem
+files. Partial fix for SourceForge bug #358 &quot;CVE-2016-2317 - SVG
+heap/stack buffer overflows&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-03-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/psd.c (ReadPSDImage): Fix SourceForge bug #341
+&quot;out-of-bounds read in coders/psd.c:1435&quot;.
+(WriteWhiteBackground): Fix SourceForge bug #350 &quot;SEGV in
+coders/psd.c:1685&quot;.
+(DecodeImage): Fix SourceForge bug #351 &quot;heap-buffer-overflow in
+coders/psd.c:142&quot;.
+(ReadPSDImage): Fix SourceForge bug #342 &quot;out-of-bounds write in
+coders/psd.c:892&quot;</li>
+<li>coders/xcf.c (load_tile): Fix SourceForge bug #337
+&quot;heap-buffer-overflow in coders/xcf.c:373&quot;.</li>
+<li>coders/pict.c (WritePICTImage): Fix SourceForge bug #340
+&quot;out-of-bounds write in coders/pict.c:1929&quot;.</li>
+<li>coders/pdb.c (WritePDBImage): Fix SourceForge bug #348
+&quot;heap-buffer-overflow in coders/pdb.c:949:26&quot;.</li>
+<li>coders/xpm.c (ReadXPMImage): Fix SourceForge bug #334
+&quot;heap-buffer-overflow in coders/xpm.c:150&quot;.</li>
+</ul>
+</blockquote>
+<p>2016-03-09 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Fixed huge image limitation.</li>
+</ul>
+</blockquote>
+<p>2016-03-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/sun.c (WriteSUNImage): Fix SourceForge bug #343
+&quot;out-of-bounds write in coders/sun.c:962&quot;.</li>
+<li>coders/rle.c (ReadRLEImage): Fix SourceForge bug #344
+&quot;out-of-bounds write in coders/rle.c:524&quot;.</li>
+<li>coders/xpm.c (ReadXPMImage): Fix SourceForge bug #335
+&quot;out-of-bounds read in coders/xpm.c:154 &quot;.</li>
+</ul>
+</blockquote>
+<p>2016-03-06 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc (-extent): Revised the example to
+clarify the interaction of -gravity with the &quot;geometry&quot; offsets.</li>
+</ul>
+</blockquote>
+<p>2016-03-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>configure.ac: Add support for --enable-broken-coders which
+determines if broken or hazardous file format support should be
+enabled in the build. Currently Adobe Photoshop (PSD) format is
+included in this category.</li>
+<li>Rotate Changelog for new year. Update documentation copyrights
+for new year.</li>
+</ul>
+</blockquote>
+<p>2016-03-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff/libtiff/tif_config.h (HAVE_SNPRINTF): Define HAVE_SNPRINTF
+when using Microsoft Visual C++ 14 (Visual Studio 2015) or later.
+This is based on advice by Pablo Elpuro.</li>
+</ul>
+</blockquote>
+<p>2016-02-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++/lib/Image.cpp (xResolution): New method to support
+setting the horizontal resolution with double precision.
+(yResolution): New method to support setting the vertical
+resolution with double precision.</li>
+<li>www/Hg.rst: Document the ssh public keys for the server hosting
+the development Mercurial repository.</li>
+</ul>
+</blockquote>
+<p>2016-02-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xpm.c (ReadXPMImage): Fix SourceForge bug #333
+heap-buffer-overflow in coders/xpm.c:409.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/ChangeLog-2016.rst b/www/ChangeLog-2016.rst
new file mode 100644
index 0000000..96636ea
--- /dev/null
+++ b/www/ChangeLog-2016.rst
@@ -0,0 +1,911 @@
+2016-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pnm.c (WritePNMImage): Support writing GRAYSCALE PAM
+ format. Before this fix, grayscale output was marked as type
+ BLACKANDWHITE. Problem was reported by Aaron Boxer via email on
+ December 31, 2016.
+
+ - TclMagick/generic/Makefile.am: Applied patch by Massimo Manghi
+ (plus some fixes by me) to add a 'libttkcommon' shared library to
+ contain codde common to the TclMagick/TkMagick loadable modules,
+ and particularly to allow TkMagick to access TclMagick functions
+ without depending on dlopen() with RTLD\_GLOBAL behavior.
+
+2016-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/compare.c (DifferenceImage): Fix all-black difference
+ image if an input file is colormapped. Resolves SourceForge issue
+ #404 "Difference file does not work if PNG ".
+
+2016-12-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/txt.c (ReadTXTImage): Fix Coverity issue 55866 "Resource
+ leak".
+
+ - magick/enum\_strings.c (StringToCompositeOperator): Fix Coverity
+ issue 139296 "Constant expression result".
+
+ - magick/channel.c (ImportImageChannelsMasked): Fix Coverity issue
+ 139297 "Constant expression result". This was a bug but only in
+ terms of reduced performance, not results.
+
+ - Magick++/lib/Drawable.cpp
+ (PathSmoothCurvetoRel::operator): Fix Coverity issue 139301 "Using
+ invalid iterator".
+ (PathSmoothCurvetoRel::operator): Fix Coverity issue 139302 "Using
+ invalid iterator"
+
+ - magick/attribute.c: From SourceForge patches #47
+ "GraphicsMagick-1.3.25-get-exif-attribute-gps-fix.patch" and
+ "GraphicsMagick-1.3.25-set-exif-orientation-fix.patch" by Troy
+ Patteson with description (related to provided Coverity reports in
+ coverity.txt): Those coverity errors indicate a problem with the
+ earlier patch I sent you to fix getting the EXIF orientation when
+ the GPS IFD occurs before the EXIF IFD. Although the patch fixed
+ that issue it introduced a new issue in that GPS tags could no
+ longer be retrieved. This occurs because the gpsfound flag is set
+ when the GPS IFD is pushed onto the stack but then cleared
+ immediately when breaking out of the loop processing the directory
+ entries for the current IFD. The solution is to push the gpsfound
+ flag onto the stack as well as it needs to be set when the GPS IFD
+ is popped off the stack rather than being set straight away.
+
+ The second coverity error relates to gpsoffset not being set in
+ FindEXIFAttribute(). The code that sets gpsoffset in
+ GenerateEXIFAttribute() was embedded in the code that gets tags
+ values which was removed in FindEXIFAttribute() as only the DE
+ offset is required. I have removed the need for gpsoffset and just
+ computed the GPS IFD offset when pushing it onto the stack in the
+ same way the EXIF IFD offset is computed.
+
+2016-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c: From SourceForge patches #47
+ "GraphicsMagick-1.3.25-5-set-exif-orientation.patch" by Troy
+ Patteson with description: Rotating an image without resetting the
+ EXIF orientation tag is problematic as follow-on viewers that
+ support the EXIF orientation tag may incorrectly rotate the image
+ a second time. For JPEG images, the current solution is to either
+ strip the image, remove the EXIF profile or modify the EXIF data
+ of the written image with other software. This patch adds the
+ ability to set the orientation tag in the EXIF profile via the
+ SetImageAttribute on attribute EXIF:Orientation provided the EXIF
+ orientation already exists. AutoOrientImage() has been modified to
+ set the EXIF orientation tag on successful rotation of the image.
+
+ The implementation is less than ideal. The EXIF profile must be
+ duplicated because it is returned read-only from the profiles
+ map. Large amounts of the GenerateEXIFAttribute() function has
+ been duplicated in a function called FindEXIFAttribute() which
+ returns the offset in the EXIF profile of a given tag ID. Once
+ found, the orientation tag value is updated accordingly and the
+ new EXIF profile set. Despite the patches shortcomings, I believe
+ it is preferable to leaving the EXIF orientation tag unchanged
+ after auto-orienting the image.
+
+ - wand/magick\_wand.c (MagickClearException): From SourceForge
+ patches #47 "GraphicsMagick-1.3.25-1-wand-clear-exception.patch"
+ by Troy Patteson with description: This patch adds the ability to
+ clear the last Wand exception. This is particularly useful to
+ clear any exception on the Wand before calling MagickReadImage()
+ which can return success with a warning exception such as "JPEG
+ data: premature end of data segment".
+ (MagickRemoveImageOption): From SourceForge patches #47
+ "GraphicsMagick-1.3.25-2-wand-remove-image-option.patch" by Troy
+ Patteson with description: There is MagickSetImageOption() to set
+ options like JPEG preserve-settings but no way to remove the
+ option once set. Since the mechanism to remove image options
+ already exists in lower-level API there seems no reason not to
+ expose it in the Wand API.
+ (MagickGetImageOrientation, MagickSetImageOrientation): From
+ SourceForge patches #47
+ "GraphicsMagick-1.3.25-3-wand-get-set-orientation.patch" by Troy
+ Patteson with description: MagickGetImageOrientation returns the
+ internal orientation setting which is useful to know to determine
+ whether an image needs rotation. The function to set the
+ orientation is less useful as it only sets the internal
+ orientation setting which is only used when writing out TIFF
+ files. A future patch addresses this issue.
+ (MagickAutoOrientImage): From SourceForge patches #47
+ "GraphicsMagick-1.3.25-4-wand-auto-orient.patch" by Troy Patteson
+ with description: This patch adds auto-orient image to the Wand
+ API.
+
+2016-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - TclMagick/{configure.ac, Makefile.am}: Applied patches by
+ Massimo Manghi to use TEA tcl.m4 version 3.9.
+
+2016-11-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/gif.c (DecodeImage): Applied fixes by Tianyu Lang for
+ "Excessive LZW string data" problem leading to "Corrupt image"
+ report while reading some GIF files.
+
+2016-11-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - doc/options.imdoc, doc/config\_files.imdoc, doc/benchmark.imdoc:
+ Fixed some indentation in the documentation.
+
+2016-10-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - acinclude.m4 (LIBS): Fix memory leaks in GM\_FUNC\_MMAP\_FILEIO
+ macro test-case so that it can be used successfully with ASAN
+ compilation options.
+
+ - magick/blob.c: Eliminate unused variable compiler warnings when
+ HAVE\_MMAP\_FILEIO is not defined.
+
+2016-10-24 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Ability to read multiple images from Matlab V4 format.
+
+2016-10-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ \*coders/png.c (ReadOneJNGImage): Enforce spec requirement that the
+ dimensions of the JPEG embedded in a JDAT chunk must match the
+ JHDR dimensions. This issue was assigned CVE-2016-9830 on
+ 2016-12-04. Please note that GraphicsMagick's pixel, width, and
+ height default limits are often greater than the dimension limits
+ of JNG and JPEG so the user should add explicit limits (if needed)
+ to prevent unexpected memory consumption from properly-constructed
+ JNG files with large dimensions.
+
+ \*doc/options.imdoc (-strip): Added a caution to not use the -strip
+ option to remove author, copyright, and license information
+ when redistributing an image that requires them to be retained.
+
+ \*doc/options.imdoc (-comment and -label): Document the fact that
+ only one comment or label is stored, and how they are stored in
+ PNG files.
+
+2016-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sgi.c (ReadSGIImage): Adjusts some variable types and
+ lessen the amount of casting.
+
+2016-10-09 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (ReadJNGImage): Quiet COVERITY issue about
+ a potential memory leak.
+
+2016-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xcf.c (ReadXCFImage): Fix memory leak of layer\_info for
+ some recently added error-return paths.
+
+2016-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sgi.c (ReadSGIImage): For RLE SGI image, defer memory
+ allocations for as long as possible and allow the file to prove
+ itself worthy before making the largest allocations. This helps
+ with rejecting bogus RLE files while avoiding rejecting valid
+ files.
+
+2016-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): If TIFF uses Old JPEG
+ compression, then read using full tiles or strips. Solves
+ "Improper call to JPEG library in state 0. (LibJpeg)." error.
+ Problem was reported via email on October 6, 2016 by John Brown.
+
+2016-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/attribute.c (GenerateEXIFAttribute): Fixed SourceForge
+ bug 400 "Exif orientation unknown for some JPEG files". Patch
+ submitted by Troy Patteson.
+
+2016-10-02 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/wpg.c Add sanity check for palette. Merge
+ RemoveLastImageFromList+AppendImageToList to ReplaceImageInList.
+ Possible heap overflow of colormap in Q8 build was assigned
+ CVE-2016-7996. Assertion crash due to blob != NULL was assigned
+ CVE-2016-7997.
+
+2016-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/meta.c (parse8BIM): Fix unsigned underflow leading to
+ heap overflow when parsing 8BIM chunk. Problem was reported by
+ Marco Grassi via email on October 1, 2016. Problem was already
+ known (but not fixed) based on comments in the code. This issue
+ has been assigned CVE-2016-7800.
+
+2016-09-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xcf.c: Improve the robustness of the XCF reader by adding
+ more error checking.
+
+2016-09-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/rle.c (RLEConstrainColormapIndex): Was not constraining
+ colormap index like it should be. This problem was added on
+ 2016-09-23.
+
+ - www/thanks.rst: Added Moshe Kaplan to Thanks.
+
+ - www/Hg.rst: Mercurial URL fixes. Patch from Mark Mitchell.
+
+ - www/programming.rst: Updated programming APIs page.
+
+2016-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/pixel\_cache.c (OpenCache): Trace ExtendCache() failures.
+
+2016-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sgi.c (ReadSGIImage): Fix unexpectedly large memory
+ allocation with corrupt SGI file provided via email by Agostino
+ Sarubbo on September 15, 2016.
+
+ - coders/rle.c (ReadRLEImage): Only report an invalid colormap
+ index once. Fixes slowness problem with corrupt file provided via
+ email by Agostino Sarubbo on September 15, 2016.
+
+2016-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/thanks.rst: Added a 'thanks' page.
+
+2016-09-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/MANIFEST: Fix content of PerlMagick MANIFEST.
+
+2016-09-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/pcx.c (ReadPCXImage): Check that filesize is reasonable
+ given header. Fixes excessive memory allocation followed by
+ eventual file truncation error for corrupt file. Problem was
+ reported via email by Agostino Sarubbo on 2016-09-10.
+
+ - coders/sgi.c (ReadSGIImage): Check that filesize is reasonable
+ given header. Fixes excessive memory allocation followed by
+ eventual file truncation error for corrupt file. Problem was
+ reported via email by Agostino Sarubbo on 2016-09-09.
+
+ - coders/sct.c (ReadSCTImage): Fix stack-buffer read overflow
+ while reading SCT header. Problem was reported via email by
+ Agostino Sarubbo on 2016-09-09.
+
+ - coders/svg.c: Fix Coverity issue 135772 "RESOURCE\_LEAK" and
+ issue 135829 "Null pointer dereferences". None of these issues
+ were new, but Coverity noticed them now. Reflowed source to GNU C
+ style for consistent indentation and so it does not fight with my
+ editor.
+
+2016-09-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/common.h (MAGICK\_HAS\_ATTRIBUTE): Coverity is allergic to
+ \_\_has\_attribute() so don't use it for Coverity builds.
+
+2016-09-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/index.rst: Update for 1.3.25 release.
+
+ - version.sh: Update library versioning for 1.3.25 release.
+
+ - NEWS.txt: Make sure is up to date.
+
+ - Various fixes for minor issues noticed when compiling under
+ Visual Studio.
+
+2016-08-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/studio.h (MAGICK\_CACHE\_LINE\_SIZE): Apply patch from
+ Gentoo Linux to increase MAGICK\_CACHE\_LINE\_SIZE to 128 when
+ \_\_powerpc\_\_ is defined.
+
+2016-08-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated with latest changes.
+
+2016-08-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/rle.c (ReadRLEImage): Reject truncated/absurd Utah RLE
+ files. Problem was reported by Agostino Sarubbo on August 19,
+ 2016. This problem was assigned CVE-2016-7448 after the 1.3.25
+ release.
+
+2016-08-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (ReadTIFFImage): Fix heap-based buffer read
+ overflow. TIFF sized attibutes were not being properly copied to
+ a null-terminated string if the value was not null terminated.
+ Problem was reported by Agostino Sarubbo on August 18, 2016. This
+ problem was assigned CVE-2016-7449 after the 1.3.25 release.
+
+2016-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lcms/src/cmstypes.c (Type\_MLU\_Read): "Added an extra check to
+ MLU bounds", change based on github mm2/Little-CMS commit
+ 5ca71a7bc18b6897ab21d815d15e218e204581e2 and announced to the
+ oss-security list by Ibrahim M. El-Sayed on Mon, 15 Aug 2016.
+
+2016-08-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - webp: Updated bundled libwebp to release 0.5.1.
+
+ - libxml: Updated bundled libxml2 to release 2.9.4.
+
+ - lcms: Updated bundled lcms2 to release 2.8.
+
+ - png: Update bundled libpng to release 1.6.24.
+
+ - coders/jpeg.c (ReadJPEGImage): Log setting resolution and
+ resolution units due to JFIF marker.
+
+ - coders/sgi.c (SGIDecode): Fix integer overflow of size type in
+ Win64 build where sizeof(long) < sizeof(size\_t).
+
+2016-08-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders, magick: Compile clean using GCC with -std=c90.
+
+ - magick/describe.c (DescribeImage): The 'identify' and 'info'
+ functionality only shows the pixel read rate if image was not read
+ in 'ping' mode. Provide seconds timing with 6 digits of precision
+ since that is what is needed.
+
+2016-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/describe.c (DescribeImage): Include milliseconds
+ resolution in elapsed time output.
+
+ - magick/timer.c (ElapsedTime): Use clock\_gettime() (when
+ available with default linkage) to obtain elapsed time.
+
+2016-08-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/yuv.c (WriteYUVImage): Fix benign clang compiler warning
+ regarding "variable 'x' is incremented both in the loop header and
+ in the loop body".
+
+ - configure.ac: Fixes to use clang's OpenMP runtime library
+ (-lomp) for clang 3.8 and later. Specifically tested with clang
+ 3.8 on Ubuntu 16.04 'xenial'. Problem was reported by Holger
+ Hoffstätte via private email.
+
+ - NEWS.txt: Bring up to date with latest changes.
+
+2016-07-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawImage): Reject abnormally absurd gradient
+ size requests (many absurd requests are still allowed). Provide
+ detailed error reports when a gradient is rejected.
+
+ - coders/svg.c: Support units for 'stroke-dashoffset'.
+
+2016-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/annotate.c (EscapeParenthesis): In private email on
+ 2016-07-07, Gustavo Grieco notified us of a heap overflow in
+ EscapeParenthesis(). I was not able to reproduce the issue but
+ changed the implementation with the suspicion that the
+ implementation has a bug, and due to noticing arbitary limits and
+ inefficiency. This issue was assigned CVE-2016-7447 after the
+ 1.3.25 release.
+
+2016-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawImage): Fix absolute and arbitrary gradient
+ dimension sanity checks which caused gradient requests to fail.
+ Resolves SourceForge issue #392 "SVG 'push defs' fails (Debian
+ bugs 829063 and 828120)".
+
+2016-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/security.rst: Add discussion of SVG format and SSRF
+ vulnerability.
+
+2016-06-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/svg.c (ReadSVGImage): Assure that SVGInfo data is freed
+ when XMP parsing is aborted due to an error.
+
+2016-06-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated NEWS with changes since last release.
+
+ - www/security.rst: Add a page about GraphicsMagick security.
+
+2016-06-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawPrimitive): Over-aggressive error reporting
+ was causing failures when elements were "drawn" off-image.
+ Resolves SourceForge issue #389 "Non-conforming drawing primitive
+ definition (line)".
+
+2016-05-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawImage): Fix problem while reading file
+ "tnamkejarz.svg.2532308010849170049" provided via private email
+ from Gustavo Grieco on May 31, 2016.
+
+ - magick/utility.c (MagickGetToken): Fix problem while reading
+ file "vqxwatmqmi.svg.-3669039972557308254" provided via private
+ email from Gustavo Grieco on May 31, 2016.
+
+2016-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Update for 1.3.24 release.
+
+ - www/Changes.rst: Mention 1.3.24 release.
+
+ - www/index.rst: Update for 1.3.24 release.
+
+ - version.sh: Update library ABI information in preparation for
+ 1.3.24 release.
+
+ - NEWS.txt: Updated NEWS to reflect fixes and issues.
+
+2016-05-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated with latest news.
+
+ - magick/blob.c (OpenBlob): Remove support for reading input from
+ a shell command, or writing output to a shell command, by
+ prefixing the specified filename (containing the command) with a
+ '|'. This feature provided a remote shell execution opportunity
+ (CVE-2016-5118).
+
+ - coders/mat.c (ReadMATImage): Validate that MAT frames is not
+ zero.
+
+2016-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawImage): Be less optimistic when estimating
+ the number of points required to represent a path. This should
+ help address CVE-2016-2317 "Heap buffer overflow". This resolves
+ SourceForge issue #275 "Applying Clipping Path to high resolution
+ JPG".
+
+2016-05-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawImage): Fix problem while reading file
+ "pxypjhfdxf.svg.7406476585885697806" provided via via private
+ email from Gustavo Grieco on May 24, 2016.
+
+ - coders/svg.c: Fix problem while reading file
+ "pxypjhfdxf.svg.308008972284643989" provided via private email
+ from Gustavo Grieco on May 24, 2016.
+
+2016-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/svg.c ("C"): Support font-size "medium".
+
+2016-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated NEWS.txt to reflect latest changes.
+
+ - magick/render.c (DrawImage): Added DrawImage() recursion
+ detection/prevention.
+
+ - coders/svg.c (ReadSVGImage): Add basic primitive argument
+ validation.
+
+ - magick/render.c (DrawImage): Add basic primitive argument
+ validation.
+
+2016-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/url.c (ReadURLImage): Reading "file://" URLs was not
+ working. Now file URLs are working.
+
+2016-05-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Respect JPEG limits (65535x65535) and user width
+ and height limits from "-limit" while reading or writing JNG files.
+
+2016-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/url.c: Don't hide HTTP, FTP, and FILE URL support from
+ '-list format' output. Ignore HTTP, FTP, and FILE as a useful
+ file extension for determing the file format.
+
+2016-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (ConvertPathToPolygon): Make sure that first
+ edge is initialized. Make sure that points is not null.
+
+2016-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawImage): Fixed segmentation violation while
+ reading file "275077586554139424.lqxdgqxtfs.svg" provided via
+ private email from Gustavo Grieco on May 15, 2016. This is due to
+ another CVE-2016-2317 related issue.
+
+2016-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/svg.c ("C"): Fixed problems while reading files
+ "aaphrbkwwe.svg.-1899680443073025602",
+ "aaphrbkwwe.svg.-5751004588641220738",
+ "aaphrbkwwe.svg.-8875730334406147537", and
+ "aaphrbkwwe.svg.4495884156523242589" provided via private email
+ from Gustavo Grieco on February 8, 2016.
+
+2016-05-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dib.c (ReadDIBImage): Verify that DIB file data is
+ sufficient to meet claims made by file header. Validate image
+ planes. Fixes Fixes problem reported by Hanno Böck on May 8th,
+ 2016 via private email entitled "malloc issue in ReadDIBImage".
+
+2016-05-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/msl.c (RegisterMSLImage): Ignore the file extension on
+ MSL files. The only way to read an image from a MSL file (as
+ opposed to explicitly running a MSL script with 'conjure') is by
+ reading using a filename specification like "msl:filename". This
+ is done for security reasons.
+
+ - magick/render.c (DrawPrimitive): Fix Coverity issue 126378
+ "Resource leak".
+
+ - coders/mat.c (DecompressBlock): Fix Coverity issue 126379
+ "Resource leak".
+
+ - magick/render.c (DrawImage): Fix Coverity issue 126380 "Resource
+ leak".
+
+2016-05-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawPrimitive): Sanity check the image file
+ path or URL before passing it to ReadImage().
+
+ - config/delegates.mgk.in: Pare down delegates.mgk to reduce
+ security exposure due to external programs not under our control.
+
+2016-05-08 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Typo fix - matrix has nothing to do with PostScript.
+
+2016-05-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/mat.c (DecompressBlock): Don't hang on a corrupt deflate
+ stream when reading matlab v6 file. Fixes problem reported by
+ Hanno Böck on May 8, 2016 via private email entitled "hang of
+ matlab input file".
+
+2016-05-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Undocumented "TMP" magick prefix
+ no longer removes the argument file after it has been read. This
+ functionality is only used to support the "show" delegate which is
+ used by options in the 'display' program which need to display a
+ generated image in a new instance of 'display'. The "show"
+ delegate is used by writing a temporary file to be viewed, and
+ which should be removed before the program quits. Since the "TMP"
+ feature was originally implemented, GraphicsMagick added a
+ temporary file management subsystem which assures that temporary
+ files are removed so this feature is not needed.
+
+ - coders/tiff.c (ReadTIFFImage): Fix heap overflow with file
+ "gkkxrilssm.tiff.-4678010562506843336" provided by Gustavo Grieco
+ on February 8, 2006 via private email.
+
+ - coders/viff.c (ReadVIFFImage): Fix problem with a very large
+ malloc in sample file provided by Hanno Böck on May 7, 2016 with
+ subject "large malloc in ReadVIFFImage".
+
+ - coders/mvg.c (RegisterMVGImage): Do not auto-detect MVG format
+ based on file extension. MVG files can then only be read by
+ adding a "MVG:" prefix to the file name. There is already no
+ auto-detection of MVG based on content.
+
+2016-05-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xpm.c (ReadXPMImage): Limit the number of XPM colors and
+ assure array initialization. Fixes bad behavior with a sample
+ file provided by Hanno Böck on May 6, 2016 with subject "Invalid
+ free in ReadXPMImage".
+
+ - coders/pcx.c (ReadPCXImage): Limit the number of PCX image
+ planes allowed. Fixes an unreasonable memory allocation in a
+ sample file provided by Hanno Böck on May 5, 2016.
+
+2016-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - config/delegates.mgk.in: Gnuplot files are inherently insecure.
+ Remove delegates support for reading them. Reported by John
+ Lightsey via private email.
+ Added -dSAFER to Ghostscript invokations in delegates.mgk for more
+ secure execution. Reported by David Chan via SourceForge bug
+ "#386 ghostscript delegates should explicitly use -dSAFER.".
+
+ - magick/constitute.c (ReadImages): Avoid possible infinite
+ ReadImage() recursion.
+
+2016-05-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawPolygonPrimitive): Fix divide by zero
+ exception encountered while reading file "sigfpe.svg" posted by
+ Gustavo Grieco on May 1, 2016 to the oss-security mailing list
+ with subject "CVE request: DoS in multiple versions of
+ GraphicsMagick".
+ (DrawDashPolygon): Fix endless loop problem caused by negative
+ stroke-dasharray arguments. Resolves problem observed while
+ reading file "circular.svg" posted by Gustavo Grieco on May 1,
+ 2016 to the oss-security mailing list with subject "CVE request:
+ DoS in multiple versions of GraphicsMagick".
+
+ - magick/import.c (ImportViewPixelArea): Fix assertion while
+ reading TIFF file gkkxrilssm.tiff.105123337066 provided by Gustavo
+ Grieco.
+
+2016-04-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/locale.c (ReadLOCALEImage): Make sure to close blob
+ before returning.
+
+ - coders/svg.c ("C"): Provide a hack work-around for double-quoted
+ font-family argument.
+
+ - magick/render.c (DrawImage): Make SVG path and other primitive
+ parsing more robust. Fixes SEGV when reading files provided by
+ CVE-2016-2318 test cases. Fixes CVE-2016-2318 completely.
+
+2016-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/render.c (DrawImage): Fix heap buffer overflow when
+ reading aaphrbkwwe.svg.-1114777018469422437 from CVE-2016-2317
+ test cases. This resolves CVE-2016-2317 completely.
+
+2016-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (MogrifyImageCommand): Added mogrify
+ -preserve-timestamp option to preserve file access and
+ modification timestamps. Contributed by Niko Rosvall via
+ SourceForge patch #45 "preserve-timestamp option for mogrify
+ command."
+
+2016-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/blob.c: Added ReadBlobLSBSignedShort(),
+ ReadBlobMSBSignedShort(),
+ ReadBlobLSBSignedLong(),ReadBlobMSBSignedLong(),
+ WriteBlobLSBSignedShort(), WriteBlobLSBSignedLong(),
+ WriteBlobMSBSignedLong(), WriteBlobMSBSignedShort() for doing I/O
+ on signed integer types without the need for dangerous casts or
+ unexpected values due to signed/unsigned conversion.
+
+2016-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Updated with latest changes.
+
+ - magick/constitute.c (ReadImage): Added asserts to check that the
+ I/O blob is not still open in the returned image since this causes
+ problems.
+
+ - magick/blob.c (CloneBlobInfo): Use a cloning approach which does
+ not require manually keeping structure members in sync.
+
+ - coders/msl.c (ProcessMSLScript): Need to close I/O blob before
+ returning.
+
+ - coders/psd.c (ReadPSDImage): Assure that allocated image is not
+ dereferenced before checking if it is NULL. Check some memory
+ calculations for overflow.
+ (ReadPSDImage): Need to close I/O blob before returning.
+
+ - coders/dib.c (ReadDIBImage): Use DestroyBlob() rather than
+ DestroyBlobInfo().
+
+ - coders/bmp.c (ReadBMPImage): Use DestroyBlob() rather than
+ DestroyBlobInfo().
+
+ - magick/blob.c: Improve blob tracing.
+
+2016-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/bmp.c (ReadBMPImage): Fix reading 24-bit Microsoft BMP
+ which claims to have a colormap.
+
+2016-04-13 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - PerlMagick/t/input\_complex\_lsb\_double\_V4.mat Demo Matlab V4
+ complex file.
+ - coders/mat.c Missing break added.
+
+2016-04-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xpm.c (ReadXPMImage): Fix SourceForge issue #361
+ "out-of-bounds read in coders/xpm.c:150:24"
+
+ - coders/psd.c (ReadPSDImage): Add some defensive code to assure
+ that image layers are not freed twice.
+
+2016-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/log.c (InitializeLogInfo): Simplify LogInfo structure and
+ its allocation in order to lessen the amount of fixed overhead.
+
+2016-04-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c (WriteJP2Image): Fix SourceForge issue #378 "jp2:
+ impossible to create lossless jpeg-2000". With this fix,
+ specifying 'define jp2:rate=1.0' or '-quality 100' results in a
+ lossless JP2 file.
+
+2016-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/common.h: Update for GCC 5.
+
+ - PerlMagick/MANIFEST: Update PerlMagick manifest.
+
+ - PerlMagick/t/{read.t, write.t}: Add tests for MAT v4.
+
+2016-04-03 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Matlab V4 attempt to read complex part of data.
+
+2016-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - PerlMagick/t/features.pl.in: Provide a way that PerlMagick
+ feature tests can test if a feature is supported. Use it to make
+ the PSD test optional.
+
+ - coders/Makefile.am: Only build PSD module if
+ ENABLE\_BROKEN\_CODERS is enabled.
+
+ - magick/module.c (UnloadModule): Only invoke the module
+ unregister function if it is defined. The module register
+ function is not defined if either the register or unregister
+ functions were not found in the module which was loaded.
+
+2016-04-02 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Matlab V4 files are also rotated.
+ \* PerlMagick/t/input\_gray\_lsb\_double\_V4.mat Demo Matlab V4 file.
+
+2016-04-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/magick.c (GetMagickInfo): Only declare that ExceptionInfo
+ argument is not used if modules are not supported.
+
+2016-03-28 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Attempt to read Matlab V4 files.
+
+2016-03-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (DestroyImage): Simply return if image is NULL
+ since it is more user-friendly.
+
+ - magick/shear.c (RotateImage): Fix Coverity issue 124519
+ "Logically dead code".
+
+ - magick/effect.c (BlurImage): Fix Coverity issue 124520
+ "Dereference after null check".
+
+ - coders/pdb.c (WritePDBImage): Fix SourceForge bug #360
+ "out-of-bounds read in utilities/gm+0x80fcc71) (PDB reader)".
+
+ - coders/meta.c (convertHTMLcodes): Fix SourceForge bug #373
+ "out-of-bounds read in coders/meta.c:444:50"
+ (ReadMETAImage): Fix SourceForge bug #364 "out-of-bounds write in
+ coders/meta.c:1331:7".
+
+2016-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sgi.c (ReadSGIImage): Fix SourceForge bug #366
+ "out-of-bounds write in coders/sgi.c:528:4" and bug #369
+ "out-of-bounds write in coders/sgi.c:535:4".
+
+ - coders/rle.c (ReadRLEImage): Fix SourceForge bug #371
+ "out-of-bounds read in coders/rle.c:633:39".
+
+2016-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dib.c (ReadDIBImage): Fix SourceForge bug #367
+ "out-of-bounds read in coders/dib.c:706:13" and bug #370
+ "out-of-bounds read in coders/dib.c:716:15".
+
+ - coders/pict.c (ReadPICTImage): Fix SourceForge bug #365
+ "out-of-bounds read in magick/image.c:1305:3"
+
+ - magick/utility.c (GetPageGeometry): Fix SourceForge bug #374
+ "out-of-bounds write in magick/utility.c:4355:7"
+
+2016-03-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/miff.c (ReadMIFFImage): Fix SourceForge bug #376 "SIGABRT
+ in magick/colorspace.c:1052".
+
+ - magick/shear.c (RotateImage): Fix SourceForge bug #375 "SIGABRT
+ in magick/image.c:1230".
+
+ - coders/sun.c (DecodeImage): Fix SourceForge bug #368
+ "out-of-bounds read in coders/sun.c:223:17" and bug #363
+ "out-of-bounds read in coders/sun.c:221:16".
+
+2016-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/svg.c (GetUserSpaceCoordinateValue): Fix stack buffer
+ overflow when reading file 'aaphrbkwwe.svg.-632425326915265752'
+ from CVE-2016-2317 problem files. Partial fix for SourceForge bug
+ #358 "CVE-2016-2317 - SVG heap/stack buffer overflows".
+
+ - magick/utility.c (MagickGetToken): New private function to
+ replace GetToken(). The new function accepts a token buffer
+ length argument. GetToken() is modified to assume a token buffer
+ length 'MaxTextExtent'. All code using GetToken() is updated to
+ use MagickGetToken().
+
+ - coders/svg.c: Fix heap buffer overflow when reading file
+ "aaphrbkwwe.svg.4495884156523242589" from CVE-2016-2317 problem
+ files. Partial fix for SourceForge bug #358 "CVE-2016-2317 - SVG
+ heap/stack buffer overflows".
+
+2016-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/psd.c (ReadPSDImage): Fix SourceForge bug #341
+ "out-of-bounds read in coders/psd.c:1435".
+ (WriteWhiteBackground): Fix SourceForge bug #350 "SEGV in
+ coders/psd.c:1685".
+ (DecodeImage): Fix SourceForge bug #351 "heap-buffer-overflow in
+ coders/psd.c:142".
+ (ReadPSDImage): Fix SourceForge bug #342 "out-of-bounds write in
+ coders/psd.c:892"
+
+ - coders/xcf.c (load\_tile): Fix SourceForge bug #337
+ "heap-buffer-overflow in coders/xcf.c:373".
+
+ - coders/pict.c (WritePICTImage): Fix SourceForge bug #340
+ "out-of-bounds write in coders/pict.c:1929".
+
+ - coders/pdb.c (WritePDBImage): Fix SourceForge bug #348
+ "heap-buffer-overflow in coders/pdb.c:949:26".
+
+ - coders/xpm.c (ReadXPMImage): Fix SourceForge bug #334
+ "heap-buffer-overflow in coders/xpm.c:150".
+
+2016-03-09 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Fixed huge image limitation.
+
+2016-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/sun.c (WriteSUNImage): Fix SourceForge bug #343
+ "out-of-bounds write in coders/sun.c:962".
+
+ - coders/rle.c (ReadRLEImage): Fix SourceForge bug #344
+ "out-of-bounds write in coders/rle.c:524".
+
+ - coders/xpm.c (ReadXPMImage): Fix SourceForge bug #335
+ "out-of-bounds read in coders/xpm.c:154 ".
+
+2016-03-06 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - doc/options.imdoc (-extent): Revised the example to
+ clarify the interaction of -gravity with the "geometry" offsets.
+
+2016-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - configure.ac: Add support for --enable-broken-coders which
+ determines if broken or hazardous file format support should be
+ enabled in the build. Currently Adobe Photoshop (PSD) format is
+ included in this category.
+
+ - Rotate Changelog for new year. Update documentation copyrights
+ for new year.
+
+2016-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff/libtiff/tif\_config.h (HAVE\_SNPRINTF): Define HAVE\_SNPRINTF
+ when using Microsoft Visual C++ 14 (Visual Studio 2015) or later.
+ This is based on advice by Pablo Elpuro.
+
+2016-02-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++/lib/Image.cpp (xResolution): New method to support
+ setting the horizontal resolution with double precision.
+ (yResolution): New method to support setting the vertical
+ resolution with double precision.
+
+ - www/Hg.rst: Document the ssh public keys for the server hosting
+ the development Mercurial repository.
+
+2016-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/xpm.c (ReadXPMImage): Fix SourceForge bug #333
+ heap-buffer-overflow in coders/xpm.c:409.
+
diff --git a/www/Changelog.html b/www/Changelog.html
new file mode 100644
index 0000000..f98b69b
--- /dev/null
+++ b/www/Changelog.html
@@ -0,0 +1,341 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2017-07-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Make sure is up to date.</li>
+<li>www/index.rst: Update for 1.3.26 release.</li>
+<li>version.sh: Update library versioning for 1.3.26 release.</li>
+<li>magick/command.c (BatchCommand): Add ferror() checks around
+batch input loop.</li>
+</ul>
+</blockquote>
+<p>2017-07-03 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Reject a PNG file if the file size is too small
+(less than 61 bytes). Reject a JNG file if it is too small (less
+than 147 bytes).</li>
+<li>coders/jpeg.c: Reject a JPEG file if the file size is too small
+(less than 107 bytes).</li>
+</ul>
+</blockquote>
+<p>2017-07-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/dpx.c (ReadDPXImage): Compute required file size and
+verify that sufficient data exists in file before allocating
+memory to decode the image data. Resolves problem with DPX file
+with valid header (but a huge claimed image width) provided
+provided via email on Thu, 29 Jun 2017 by LCatro. This issue has
+been assigned CVE-2017-10799.</li>
+</ul>
+</blockquote>
+<p>2016-07-02 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Check whether reported object size overflows file size.</li>
+</ul>
+</blockquote>
+<p>2016-07-01 Fojtik Jaroslav &lt;<a class="reference external" href="mailto:JaFojtik&#37;&#52;&#48;seznam&#46;cz">JaFojtik<span>&#64;</span>seznam<span>&#46;</span>cz</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/mat.c Safety check for forged and or corrupted data.
+This issue has been assigned CVE-2017-10800.</li>
+</ul>
+</blockquote>
+<p>2017-07-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (&quot;QuantumTransferMode&quot;): Use a generalized method
+to enforce that buffer overflow can not happen while importing
+pixels. Resolves problem with RGB TIFF claiming only one sample
+per pixel provided via email on Thu, 29 Jun 2017 by LCatro. This
+issue has been assigned CVE-2017-10794.</li>
+</ul>
+</blockquote>
+<p>2017-06-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c: Convert bare 'unsigned int' to MagickPassFail
+where suitable to make intentions clear. Convert True/False to
+MagickTrue/MagickFalse or MagickPass/MagickFail according to
+purpose. This is a continuation of a gradual migration and does
+not represent an API change.</li>
+</ul>
+</blockquote>
+<p>2017-06-25 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Avoid NULL dereference when MAGN chunk processing
+fails (<a class="reference external" href="https://sourceforge.net/p/graphicsmagick/bugs/426/">https://sourceforge.net/p/graphicsmagick/bugs/426/</a>). Expand
+TABs.</li>
+</ul>
+</blockquote>
+<p>2017-06-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>NEWS.txt: Update NEWS with changes since the previous release.</li>
+<li>www/programming.rst: Switch the Lua link to
+<a class="reference external" href="https://github.com/arcapos/luagraphicsmagick">https://github.com/arcapos/luagraphicsmagick</a>, which is a more
+complete and direct interface from Lua to GraphicsMagick's Wand
+API.</li>
+</ul>
+</blockquote>
+<p>2017-06-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>VisualMagick/installer/gm-foo-dll.iss: Remove PerlMagick from
+the slim Inno Setup installer builder and remove mention of
+PerlMagick from the installer documentation.</li>
+<li>TclMagick/generic/TclMagick.c (magickCmd): Resolve SourceForge
+patch #51 &quot;TclMagick: memory access error; possible segfault&quot;.
+(newMagickObj): Fix formatting of pointer value so it is 64-bit
+safe. Resolves SourceForge patch #50 &quot;TclMagick: 64-bit
+portability issue&quot;.</li>
+<li>coders/pict.c (ReadPICTImage): Avoid possible use of negative
+value when indexing array, which would cause buffer overflow.
+Resolves SourceForge issue #427 &quot;One possible buffer overflow
+vulnerability in
+GraphicsMagick-1.3.25/coders/pict.c:ReadPICTImage()&quot;.</li>
+</ul>
+</blockquote>
+<p>2017-06-22 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Stop memory leak when reading invalid JNG image.
+Fixes CVE-2017-8350.</li>
+</ul>
+</blockquote>
+<p>2017-06-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Fix lcms2.h inclusion logic.</li>
+<li>wand/magick_wand.c (MagickSetImageOrientation): Eliminate use of
+snprintf, which is not supported by older Visual Studio.</li>
+</ul>
+</blockquote>
+<p>2017-06-09 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Accept exIf chunks whose data segment
+erroneously begins with &quot;Exif00&quot;.</li>
+</ul>
+</blockquote>
+<p>2017-06-01 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Removed experimental zxIF chunk support. That
+proposal is dead.</li>
+</ul>
+</blockquote>
+<p>2017-05-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>config/log.mgk: Added documentation suggested by SourceForge
+issue #419 &quot;Consider a small patch to log.mgk&quot;.</li>
+<li>www/Changes.rst: Add missing link to most recent changes.</li>
+</ul>
+</blockquote>
+<p>2017-05-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>www/Magick++/Image.rst: Improve documentation for Magick++
+Image::iccColorProfile() and Image::renderingIntent().</li>
+</ul>
+</blockquote>
+<p>2017-05-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tiff: Update to libtiff 4.0.8.</li>
+</ul>
+</blockquote>
+<p>2017-03-19 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Quieted a new Coverity complaint about a potential
+text buffer overrun.</li>
+</ul>
+</blockquote>
+<p>2017-03-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/image.c (SetImageInfo): Ignore empty magic prefix
+specification and do not remove colon character from start of
+filename. Resolves SourceForge bug #415 &quot;Inconsistent Behavior w/
+input_file Parameter&quot;.</li>
+</ul>
+</blockquote>
+<p>2017-03-18 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Added new private orNT PNG chunk, to
+preserve image-&gt;orientation when it is defined and not
+the default TopLeft.</li>
+<li>coders/jpeg.c: Mention image-&gt;orientation in the log when
+writing a JPEG.</li>
+</ul>
+</blockquote>
+<p>2017-03-15 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c (WriteOnePNGImage): Add version info about
+gm, libpng, zlib, and lcms to the PNG debug log.</li>
+</ul>
+</blockquote>
+<p>2017-03-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>magick/command.c (ImportImageCommand): Fix handling of -frame
+options. Option handling was incorrect due to option checking the
+frame option after it had been freed. Checking the frame dash
+option before freeing the argument solves the problem. From patch
+provided by Victor Ananjevsky as SourceForge patch #49 &quot;-frame
+doesn't work in gm import&quot;.</li>
+<li>Magick++/lib/Image.cpp (attribute): Added Image attribute method
+which accepts a 'char *' argument, and will remove the attribute
+if the value argument is NULL. From patch provided by &quot;Gints&quot; as
+SourceForge patch #46 &quot;C++ api - method to clear/remove
+attribute&quot;.</li>
+<li>VisualMagick/configure/configure.cpp (InitInstance): Applied
+patch by Paul McConkey to allow the quantum command line argument
+to set the default value in the wizard drop list. This allows
+setting the quantum depth when the /nowizard argument was
+supplied. Resolves SourceForge patch #48 &quot;When running from the
+command line configure.exe does not use the quantum argument&quot;.
+The provided configure.exe still needs to be rebuilt to
+incorporate this change.</li>
+<li>magick/command.c (MogrifyImage): The -orient command now also
+updates the orientation in the EXIF profile, if it exists.</li>
+<li>Magick++/lib/Image.cpp (orientation): Update orientation in EXIF
+profile, if it exists.</li>
+</ul>
+</blockquote>
+<p>2017-03-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/jp2.c: Support PGX JPEG 2000 format for reading and
+writing (within the bounds of what JasPer supports).</li>
+</ul>
+</blockquote>
+<p>2017-02-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/tiff.c (QuantumTransferMode): Fix out of bounds read when
+reading CMYKA TIFF which claims to have only 2 samples per pixel.
+Problem was reported via email on February 15, 2017 by Valon
+Chu. This issue was assigned CVE-2017-6335.</li>
+</ul>
+</blockquote>
+<p>2017-01-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>doc/options.imdoc (-geometry): Geometry documentation changes
+suggested by Jon Wong.</li>
+</ul>
+</blockquote>
+<p>2017-01-26 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Added support for a proposed new PNG chunk
+(zxIf, read-only) that is currently being discussed on the
+png-mng-misc at lists.sourceforge.net mailing list. Enable
+exIf and zxIf with CPPFLAGS=&quot;-DexIf_SUPPORTED -DxzIf_SUPPORTED&quot;.
+If exIf is enabled, only the uncompressed exIF chunk will be
+written and the hex-encoded zTXt chunk containing the raw Exif
+profile won't be written.</li>
+</ul>
+</blockquote>
+<p>2017-01-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/msl.c (MSLStartElement): Change test for NULL image
+pointer to before it is used rather than after it is used.
+Problem reported by Petr Gajdos on 2017-01-25.</li>
+</ul>
+</blockquote>
+<p>2017-01-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>TclMagick/unix/m4/tcl.m4: Update tcl.m4 to TEA 3.10. File
+supplied by Massimo Manghi.</li>
+</ul>
+</blockquote>
+<p>2017-01-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Added support for a proposed new PNG
+chunk (exIf read-write, eXIf read-only) that is currently
+being discussed on the png-mng-misc at lists.sourceforge.net
+mailing list.</li>
+</ul>
+</blockquote>
+<p>2017-01-21 Glenn Randers-Pehrson &lt;<a class="reference external" href="mailto:glennrp&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">glennrp<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/png.c: Added read_user_chunk_callback() function
+and used it to implement a private PNG caNv (canvas) chunk
+for remembering the original dimensions and offsets when an
+image is cropped. Previously we used the oFFs chunk for this
+purpose, but this had potential conflicts with other applications
+that also use the oFFs chunk.</li>
+</ul>
+</blockquote>
+<p>2017-01-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>TclMagick/Makefile.am (AM_DISTCHECK_CONFIGURE_FLAGS): Applied
+patch by Massimo Manghi to set AM_DISTCHECK_CONFIGURE_FLAGS so
+that 'make distcheck' remembers configuration options, and also to
+uninstall pkgIndex.tcl.</li>
+<li>magick/image.c (SetImageEx): Use PixelIterateMonoSet() for
+possibly improved efficiency.</li>
+<li>magick/pixel_iterator.c (PixelIterateMonoSet): New pixel
+iterator intended for use when initializing image pixels, without
+regard to existing values.</li>
+</ul>
+</blockquote>
+<p>2017-01-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Copyright.txt: Bump copyright years and rotate ChangeLog.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/Changelog.rst b/www/Changelog.rst
new file mode 100644
index 0000000..50e2029
--- /dev/null
+++ b/www/Changelog.rst
@@ -0,0 +1,252 @@
+2017-07-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Make sure is up to date.
+
+ - www/index.rst: Update for 1.3.26 release.
+
+ - version.sh: Update library versioning for 1.3.26 release.
+
+ - magick/command.c (BatchCommand): Add ferror() checks around
+ batch input loop.
+
+2017-07-03 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Reject a PNG file if the file size is too small
+ (less than 61 bytes). Reject a JNG file if it is too small (less
+ than 147 bytes).
+ - coders/jpeg.c: Reject a JPEG file if the file size is too small
+ (less than 107 bytes).
+
+2017-07-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/dpx.c (ReadDPXImage): Compute required file size and
+ verify that sufficient data exists in file before allocating
+ memory to decode the image data. Resolves problem with DPX file
+ with valid header (but a huge claimed image width) provided
+ provided via email on Thu, 29 Jun 2017 by LCatro. This issue has
+ been assigned CVE-2017-10799.
+
+2016-07-02 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Check whether reported object size overflows file size.
+
+2016-07-01 Fojtik Jaroslav <JaFojtik@seznam.cz>
+
+ - coders/mat.c Safety check for forged and or corrupted data.
+ This issue has been assigned CVE-2017-10800.
+
+2017-07-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c ("QuantumTransferMode"): Use a generalized method
+ to enforce that buffer overflow can not happen while importing
+ pixels. Resolves problem with RGB TIFF claiming only one sample
+ per pixel provided via email on Thu, 29 Jun 2017 by LCatro. This
+ issue has been assigned CVE-2017-10794.
+
+2017-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c: Convert bare 'unsigned int' to MagickPassFail
+ where suitable to make intentions clear. Convert True/False to
+ MagickTrue/MagickFalse or MagickPass/MagickFail according to
+ purpose. This is a continuation of a gradual migration and does
+ not represent an API change.
+
+2017-06-25 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Avoid NULL dereference when MAGN chunk processing
+ fails (https://sourceforge.net/p/graphicsmagick/bugs/426/). Expand
+ TABs.
+
+2017-06-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - NEWS.txt: Update NEWS with changes since the previous release.
+
+ - www/programming.rst: Switch the Lua link to
+ https://github.com/arcapos/luagraphicsmagick, which is a more
+ complete and direct interface from Lua to GraphicsMagick's Wand
+ API.
+
+2017-06-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - VisualMagick/installer/gm-foo-dll.iss: Remove PerlMagick from
+ the slim Inno Setup installer builder and remove mention of
+ PerlMagick from the installer documentation.
+
+ - TclMagick/generic/TclMagick.c (magickCmd): Resolve SourceForge
+ patch #51 "TclMagick: memory access error; possible segfault".
+ (newMagickObj): Fix formatting of pointer value so it is 64-bit
+ safe. Resolves SourceForge patch #50 "TclMagick: 64-bit
+ portability issue".
+
+ - coders/pict.c (ReadPICTImage): Avoid possible use of negative
+ value when indexing array, which would cause buffer overflow.
+ Resolves SourceForge issue #427 "One possible buffer overflow
+ vulnerability in
+ GraphicsMagick-1.3.25/coders/pict.c:ReadPICTImage()".
+
+2017-06-22 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Stop memory leak when reading invalid JNG image.
+ Fixes CVE-2017-8350.
+
+2017-06-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/png.c: Fix lcms2.h inclusion logic.
+
+ - wand/magick\_wand.c (MagickSetImageOrientation): Eliminate use of
+ snprintf, which is not supported by older Visual Studio.
+
+2017-06-09 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Accept exIf chunks whose data segment
+ erroneously begins with "Exif\0\0".
+
+2017-06-01 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Removed experimental zxIF chunk support. That
+ proposal is dead.
+
+2017-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - config/log.mgk: Added documentation suggested by SourceForge
+ issue #419 "Consider a small patch to log.mgk".
+
+ - www/Changes.rst: Add missing link to most recent changes.
+
+2017-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - www/Magick++/Image.rst: Improve documentation for Magick++
+ Image::iccColorProfile() and Image::renderingIntent().
+
+2017-05-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tiff: Update to libtiff 4.0.8.
+
+2017-03-19 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Quieted a new Coverity complaint about a potential
+ text buffer overrun.
+
+2017-03-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/image.c (SetImageInfo): Ignore empty magic prefix
+ specification and do not remove colon character from start of
+ filename. Resolves SourceForge bug #415 "Inconsistent Behavior w/
+ input\_file Parameter".
+
+2017-03-18 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Added new private orNT PNG chunk, to
+ preserve image->orientation when it is defined and not
+ the default TopLeft.
+ - coders/jpeg.c: Mention image->orientation in the log when
+ writing a JPEG.
+
+2017-03-15 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c (WriteOnePNGImage): Add version info about
+ gm, libpng, zlib, and lcms to the PNG debug log.
+
+2017-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - magick/command.c (ImportImageCommand): Fix handling of -frame
+ options. Option handling was incorrect due to option checking the
+ frame option after it had been freed. Checking the frame dash
+ option before freeing the argument solves the problem. From patch
+ provided by Victor Ananjevsky as SourceForge patch #49 "-frame
+ doesn't work in gm import".
+
+ - Magick++/lib/Image.cpp (attribute): Added Image attribute method
+ which accepts a 'char \*' argument, and will remove the attribute
+ if the value argument is NULL. From patch provided by "Gints" as
+ SourceForge patch #46 "C++ api - method to clear/remove
+ attribute".
+
+ - VisualMagick/configure/configure.cpp (InitInstance): Applied
+ patch by Paul McConkey to allow the quantum command line argument
+ to set the default value in the wizard drop list. This allows
+ setting the quantum depth when the /nowizard argument was
+ supplied. Resolves SourceForge patch #48 "When running from the
+ command line configure.exe does not use the quantum argument".
+ The provided configure.exe still needs to be rebuilt to
+ incorporate this change.
+
+ - magick/command.c (MogrifyImage): The -orient command now also
+ updates the orientation in the EXIF profile, if it exists.
+
+ - Magick++/lib/Image.cpp (orientation): Update orientation in EXIF
+ profile, if it exists.
+
+2017-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/jp2.c: Support PGX JPEG 2000 format for reading and
+ writing (within the bounds of what JasPer supports).
+
+2017-02-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/tiff.c (QuantumTransferMode): Fix out of bounds read when
+ reading CMYKA TIFF which claims to have only 2 samples per pixel.
+ Problem was reported via email on February 15, 2017 by Valon
+ Chu. This issue was assigned CVE-2017-6335.
+
+2017-01-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - doc/options.imdoc (-geometry): Geometry documentation changes
+ suggested by Jon Wong.
+
+2017-01-26 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Added support for a proposed new PNG chunk
+ (zxIf, read-only) that is currently being discussed on the
+ png-mng-misc at lists.sourceforge.net mailing list. Enable
+ exIf and zxIf with CPPFLAGS="-DexIf\_SUPPORTED -DxzIf\_SUPPORTED".
+ If exIf is enabled, only the uncompressed exIF chunk will be
+ written and the hex-encoded zTXt chunk containing the raw Exif
+ profile won't be written.
+
+2017-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - coders/msl.c (MSLStartElement): Change test for NULL image
+ pointer to before it is used rather than after it is used.
+ Problem reported by Petr Gajdos on 2017-01-25.
+
+2017-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - TclMagick/unix/m4/tcl.m4: Update tcl.m4 to TEA 3.10. File
+ supplied by Massimo Manghi.
+
+2017-01-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Added support for a proposed new PNG
+ chunk (exIf read-write, eXIf read-only) that is currently
+ being discussed on the png-mng-misc at lists.sourceforge.net
+ mailing list.
+
+2017-01-21 Glenn Randers-Pehrson <glennrp@simple.dallas.tx.us>
+
+ - coders/png.c: Added read\_user\_chunk\_callback() function
+ and used it to implement a private PNG caNv (canvas) chunk
+ for remembering the original dimensions and offsets when an
+ image is cropped. Previously we used the oFFs chunk for this
+ purpose, but this had potential conflicts with other applications
+ that also use the oFFs chunk.
+
+2017-01-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - TclMagick/Makefile.am (AM\_DISTCHECK\_CONFIGURE\_FLAGS): Applied
+ patch by Massimo Manghi to set AM\_DISTCHECK\_CONFIGURE\_FLAGS so
+ that 'make distcheck' remembers configuration options, and also to
+ uninstall pkgIndex.tcl.
+
+ - magick/image.c (SetImageEx): Use PixelIterateMonoSet() for
+ possibly improved efficiency.
+
+ - magick/pixel\_iterator.c (PixelIterateMonoSet): New pixel
+ iterator intended for use when initializing image pixels, without
+ regard to existing values.
+
+2017-01-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Copyright.txt: Bump copyright years and rotate ChangeLog.
+
+
diff --git a/www/Changes.html b/www/Changes.html
new file mode 100644
index 0000000..36c4a6d
--- /dev/null
+++ b/www/Changes.html
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Change Logs</title>
+<meta content="GraphicsMagick is a robust collection of tools and libraries to read, write, and manipulate an image in any of the more popular image formats including GIF, JPEG, PNG, PDF, and Photo CD. With GraphicsMagick you can create GIFs dynamically making it suitable for Web applications. You can also resize, rotate, sharpen, color reduce, or add special effects to an image and save your completed work in the same or differing image format. " name="description" />
+<meta content="GraphicsMagick, Image Magick, Image Magic, PerlMagick, Perl Magick, Perl Magic, CineMagick, PixelMagick, Pixel Magic, WebMagick, Web Magic, visualization, image processing, software development, simulation, image, software, AniMagick, Animagic, Magick++" name="keywords" />
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-change-logs">
+<h1 class="title">GraphicsMagick Change Logs</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The following are the <tt class="docutils literal">GraphicsMagick</tt> change logs since 2001:</p>
+<blockquote>
+<ul class="simple">
+<li><a class="reference external" href="Changelog.html">2017</a> (1.3.26 released)</li>
+<li><a class="reference external" href="ChangeLog-2016.html">2016</a> (1.3.24, 1.3.25 released)</li>
+<li><a class="reference external" href="ChangeLog-2015.html">2015</a> (1.3.21 - 1.3.23 released)</li>
+<li><a class="reference external" href="ChangeLog-2014.html">2014</a> (1.3.20 released)</li>
+<li><a class="reference external" href="ChangeLog-2013.html">2013</a> (1.3.18 - 1.3.19 released)</li>
+<li><a class="reference external" href="ChangeLog-2012.html">2012</a> (1.3.14 - 1.3.17 released)</li>
+<li><a class="reference external" href="ChangeLog-2011.html">2011</a> (1.3.13 released)</li>
+<li><a class="reference external" href="ChangeLog-2010.html">2010</a> (1.2.10, 1.3.8 - 1.3.12 released)</li>
+<li><a class="reference external" href="ChangeLog-2009.html">2009</a> (1.3.4 - 1.3.7 released)</li>
+<li><a class="reference external" href="ChangeLog-2008.html">2008</a> (1.1.11 - 1.1.14, 1.2 - 1.2.9, 1.3 - 1.3.3 released)</li>
+<li><a class="reference external" href="ChangeLog-2007.html">2007</a> (1.1.8 - 1.1.10 released)</li>
+<li><a class="reference external" href="ChangeLog-2006.html">2006</a></li>
+<li><a class="reference external" href="ChangeLog-2005.html">2005</a> (1.1.5 - 1.1.7 released)</li>
+<li><a class="reference external" href="ChangeLog-2004.html">2004</a> (1.0.5 - 1.0.6, 1.1 - 1.1.4 released)</li>
+<li><a class="reference external" href="ChangeLog-2003.html">2003</a> (1.0 - 1.0.4 released)</li>
+<li><a class="reference external" href="ChangeLog-2002.html">2002</a></li>
+<li><a class="reference external" href="ChangeLog-2001.html">2001</a></li>
+</ul>
+</blockquote>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Changes.rst b/www/Changes.rst
new file mode 100644
index 0000000..1114877
--- /dev/null
+++ b/www/Changes.rst
@@ -0,0 +1,86 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+==========================
+GraphicsMagick Change Logs
+==========================
+
+.. meta::
+ :description: GraphicsMagick is a robust collection of tools and
+ libraries to read, write, and manipulate an image in any
+ of the more popular image formats including GIF, JPEG,
+ PNG, PDF, and Photo CD. With GraphicsMagick you can
+ create GIFs dynamically making it suitable for Web
+ applications. You can also resize, rotate, sharpen,
+ color reduce, or add special effects to an image and
+ save your completed work in the same or differing image
+ format.
+
+ :keywords: GraphicsMagick, Image Magick, Image Magic, PerlMagick,
+ Perl Magick, Perl Magic, CineMagick, PixelMagick, Pixel
+ Magic, WebMagick, Web Magic, visualization, image
+ processing, software development, simulation, image,
+ software, AniMagick, Animagic, Magick++
+
+.. _GraphicsMagick : index.html
+.. _2017 : Changelog.html
+.. _2016 : ChangeLog-2016.html
+.. _2015 : ChangeLog-2015.html
+.. _2014 : ChangeLog-2014.html
+.. _2013 : ChangeLog-2013.html
+.. _2012 : ChangeLog-2012.html
+.. _2011 : ChangeLog-2011.html
+.. _2010 : ChangeLog-2010.html
+.. _2009 : ChangeLog-2009.html
+.. _2008 : ChangeLog-2008.html
+.. _2007 : ChangeLog-2007.html
+.. _2006 : ChangeLog-2006.html
+.. _2005 : ChangeLog-2005.html
+.. _2004 : ChangeLog-2004.html
+.. _2003 : ChangeLog-2003.html
+.. _2002 : ChangeLog-2002.html
+.. _2001 : ChangeLog-2001.html
+
+The following are the ``GraphicsMagick`` change logs since 2001:
+
+ * 2017_ (1.3.26 released)
+
+ * 2016_ (1.3.24, 1.3.25 released)
+
+ * 2015_ (1.3.21 - 1.3.23 released)
+
+ * 2014_ (1.3.20 released)
+
+ * 2013_ (1.3.18 - 1.3.19 released)
+
+ * 2012_ (1.3.14 - 1.3.17 released)
+
+ * 2011_ (1.3.13 released)
+
+ * 2010_ (1.2.10, 1.3.8 - 1.3.12 released)
+
+ * 2009_ (1.3.4 - 1.3.7 released)
+
+ * 2008_ (1.1.11 - 1.1.14, 1.2 - 1.2.9, 1.3 - 1.3.3 released)
+
+ * 2007_ (1.1.8 - 1.1.10 released)
+
+ * 2006_
+
+ * 2005_ (1.1.5 - 1.1.7 released)
+
+ * 2004_ (1.0.5 - 1.0.6, 1.1 - 1.1.4 released)
+
+ * 2003_ (1.0 - 1.0.4 released)
+
+ * 2002_
+
+ * 2001_
+
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/Copyright.html b/www/Copyright.html
new file mode 100644
index 0000000..ac7ace8
--- /dev/null
+++ b/www/Copyright.html
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Copyrights and Licenses</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-copyrights-and-licenses">
+<h1 class="title">GraphicsMagick Copyrights and Licenses</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>This file is part of the GraphicsMagick software distributed by the
+GraphicsMagick Group.</p>
+<blockquote>
+[<em>Please note that the legal community considers 15 or more
+total lines of code or text (not necessarily contiguous) to
+be significant for the purposes of copyright. Repeated
+changes such as renaming a symbol has similar significance
+to changing one line of code.</em>]</blockquote>
+<p>The licenses which components of this software fall under are as follows.</p>
+<ol class="arabic">
+<li><p class="first">In November 2002, the GraphicsMagick Group created GraphicsMagick
+from ImageMagick Studio's ImageMagick and applied the &quot;MIT&quot; style
+license:</p>
+<p>Copyright (C) 2002 - 2017 GraphicsMagick Group</p>
+<p>Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the &quot;Software&quot;), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:</p>
+<p>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.</p>
+<p>THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.</p>
+</li>
+<li><p class="first">In October 1999, ImageMagick Studio assumed the responsibility for
+the development of ImageMagick (forking from the distribution by
+E. I. du Pont de Nemours and Company) and applied a new license:</p>
+<p>Copyright (C) 2002 ImageMagick Studio, a non-profit organization dedicated
+to making software imaging solutions freely available.</p>
+<p>Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (&quot;ImageMagick&quot;),
+to deal in ImageMagick without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of ImageMagick, and to permit persons to whom the
+ImageMagick is furnished to do so, subject to the following conditions:</p>
+<p>The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of ImageMagick.</p>
+<p>The software is provided &quot;as is&quot;, without warranty of any kind, express or
+implied, including but not limited to the warranties of merchantability,
+fitness for a particular purpose and noninfringement. In no event shall
+ImageMagick Studio be liable for any claim, damages or other liability,
+whether in an action of contract, tort or otherwise, arising from, out of
+or in connection with ImageMagick or the use or other dealings in
+ImageMagick.</p>
+<p>Except as contained in this notice, the name of the ImageMagick Studio
+shall not be used in advertising or otherwise to promote the sale, use or
+other dealings in ImageMagick without prior written authorization from the
+ImageMagick Studio.</p>
+</li>
+<li><p class="first">From 1991 to October 1999 (through ImageMagick 4.2.9), ImageMagick
+was developed and distributed by E. I. du Pont de Nemours and
+Company:</p>
+<p>Copyright 1999 E. I. du Pont de Nemours and Company</p>
+<p>Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files
+(&quot;ImageMagick&quot;), to deal in ImageMagick without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of ImageMagick, and to
+permit persons to whom the ImageMagick is furnished to do so, subject
+to the following conditions:</p>
+<p>The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of ImageMagick.</p>
+<p>The software is provided &quot;as is&quot;, without warranty of any kind, express
+or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and noninfringement.
+In no event shall E. I. du Pont de Nemours and Company be liable for
+any claim, damages or other liability, whether in an action of
+contract, tort or otherwise, arising from, out of or in connection with
+ImageMagick or the use or other dealings in ImageMagick.</p>
+<p>Except as contained in this notice, the name of the E. I. du Pont de
+Nemours and Company shall not be used in advertising or otherwise to
+promote the sale, use or other dealings in ImageMagick without prior
+written authorization from the E. I. du Pont de Nemours and Company.</p>
+</li>
+<li><p class="first">The GraphicsMagick Base64Decode() and Base64Encode() functions are
+based on source code obtained from OpenSSH. This source code is
+distributed under the following license:</p>
+<p>Copyright (c) 2000 Markus Friedl. All rights reserved.</p>
+<p>Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:</p>
+<ol class="arabic simple">
+<li>Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.</li>
+<li>Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.</li>
+</ol>
+<p>THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
+</li>
+<li><p class="first">Many of the pattern images in coders/logo.c are derived from XFig,
+which is distributed under the following license:</p>
+<div class="line-block">
+<div class="line">FIG : Facility for Interactive Generation of figures</div>
+<div class="line">Copyright (c) 1985-1988 by Supoj Sutanthavibul</div>
+<div class="line">Parts Copyright (c) 1989-2000 by Brian V. Smith</div>
+<div class="line">Parts Copyright (c) 1991 by Paul King</div>
+</div>
+<p>Any party obtaining a copy of these files is granted, free of charge, a
+full and unrestricted irrevocable, world-wide, paid up, royalty-free,
+nonexclusive right and license to deal in this software and
+documentation files (the &quot;Software&quot;), including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons who receive
+copies from any such party to do so, with the only requirement being
+that this copyright notice remain intact.</p>
+</li>
+<li><p class="first">The documentation for the composition operators is copied from the
+rlecomp manual page, which is authored by Rod Bogart and John W.
+Peterson. Rlecomp is part of the Utah Raster Toolkit distributed by the
+University of Michigan and the University of Utah. The copyright for
+this manual page is as follows:</p>
+<p>Copyright (c) 1986, University of Utah</p>
+<p>This software is copyrighted as noted below. It may be freely copied,
+modified, and redistributed, provided that the copyright notice is
+preserved on all copies.</p>
+<p>There is no warranty or other guarantee of fitness for this software,
+it is provided solely &quot;as is&quot;. Bug reports or fixes may be sent
+to the author, who may or may not act on them as he desires.</p>
+<p>You may not include this software in a program or other software product
+without supplying the source, or without informing the end-user that the
+source is available for no extra charge.</p>
+<p>If you modify this software, you should include a notice giving the
+name of the person performing the modification, the date of modification,
+and the reason for such modification.</p>
+</li>
+<li><p class="first">The source code comprising magick_endian.c is originally derived
+from libtiff which has the following license:</p>
+<div class="line-block">
+<div class="line">Copyright (c) 1988-1997 Sam Leffler</div>
+<div class="line">Copyright (c) 1991-1997 Silicon Graphics, Inc.</div>
+</div>
+<p>Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee, provided
+that (i) the above copyright notices and this permission notice appear in
+all copies of the software and related documentation, and (ii) the names of
+Sam Leffler and Silicon Graphics may not be used in any advertising or
+publicity relating to the software without the specific, prior written
+permission of Sam Leffler and Silicon Graphics.</p>
+<p>THE SOFTWARE IS PROVIDED &quot;AS-IS&quot; AND WITHOUT WARRANTY OF ANY KIND,
+EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p>
+<p>IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.</p>
+</li>
+<li><p class="first">The C++ API known as &quot;Magick++&quot;, and which resides in the Magick++
+directory, is distributed under the following license:</p>
+<p>Copyright 1999 - 2012 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<p>Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(&quot;Magick++&quot;), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject
+to the following conditions:</p>
+<p>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.</p>
+<p>THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.</p>
+</li>
+<li><p class="first">The GraphicsMagick HaldClutImagePixels() function in magick/hclut.c
+is based on source code from the HaldCLUT package by Eskil Steenberg
+(<a class="reference external" href="http://www.quelsolaar.com/technology/clut.html">http://www.quelsolaar.com/technology/clut.html</a>) which is
+distributed under the following license:</p>
+<p>Copyright (c) 2005 Eskil Steenberg. All rights reserved.</p>
+<p>Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:</p>
+<ol class="arabic simple">
+<li>Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.</li>
+<li>Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.</li>
+</ol>
+<p>THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
+</li>
+<li><p class="first">GraphicsMagick makes use of third-party &quot;delegate&quot; libraries to
+support certain optional features. These libraries bear their own
+copyrights and licenses, which may be more or less restrictive than the
+GraphicsMagick license. For convenience, when GraphicsMagick is
+bundled with (or compiled with) &quot;delegate&quot; libraries, a copy of the
+licenses for these libraries is provided in a &quot;licenses&quot; directory.</p>
+</li>
+</ol>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/FAQ.html b/www/FAQ.html
new file mode 100644
index 0000000..dbe92a9
--- /dev/null
+++ b/www/FAQ.html
@@ -0,0 +1,799 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick FAQ</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-faq">
+<h1 class="title">GraphicsMagick FAQ</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<!-- URL links -->
+<div class="contents topic" id="faq-contents">
+<p class="topic-title first">FAQ Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#how-does-graphicsmagick-differ-from-imagemagick" id="id1">How does GraphicsMagick differ from ImageMagick?</a></li>
+<li><a class="reference internal" href="#how-often-does-graphicsmagick-pick-up-new-code-from-imagemagick" id="id2">How often does GraphicsMagick pick up new code from ImageMagick?</a></li>
+<li><a class="reference internal" href="#are-there-any-plans-to-use-opencl-or-cuda-to-use-a-gpu" id="id3">Are there any plans to use OpenCL or CUDA to use a GPU?</a></li>
+<li><a class="reference internal" href="#what-is-the-meaning-of-magick" id="id4">What is the meaning of &quot;magick&quot;?</a></li>
+<li><a class="reference internal" href="#how-can-i-process-many-files-at-once" id="id5">How can I process many files at once?</a></li>
+<li><a class="reference internal" href="#i-received-the-following-message-delegation-failed-what-does-it-mean" id="id6">I received the following message, &quot;?????? delegation failed ...&quot;. What does it mean?</a></li>
+<li><a class="reference internal" href="#how-do-i-set-the-transparency-index-in-a-gif-image-so-it-displays-properly-within-mozilla" id="id7">How do I set the transparency index in a GIF image so it displays properly within Mozilla?</a></li>
+<li><a class="reference internal" href="#how-can-i-stop-the-filenames-from-changing-in-the-title-bar-of-the-animate-1-image-window" id="id8">How can I stop the filenames from changing in the title bar of the animate(1) image window?</a></li>
+<li><a class="reference internal" href="#the-image-grabbed-by-import-1-does-not-look-like-the-image-on-my-x-server-what-s-wrong" id="id9">The image grabbed by import(1) does not look like the image on my X server. What's wrong?</a></li>
+<li><a class="reference internal" href="#how-do-i-animate-a-digital-yuv-image-sequence" id="id10">How do I animate a digital YUV image sequence?</a></li>
+<li><a class="reference internal" href="#how-do-i-change-the-default-postscript-page-size" id="id11">How do I change the default <em>PostScript</em> page size?</a></li>
+<li><a class="reference internal" href="#i-get-a-memory-allocation-error-what-can-i-do" id="id12">I get a memory allocation error. What can I do?</a></li>
+<li><a class="reference internal" href="#how-do-i-concatenate-three-images-left-to-right-with-no-borders-frames-or-text" id="id13">How do I concatenate three images left-to-right with no borders, frames, or text?</a></li>
+<li><a class="reference internal" href="#how-do-i-create-a-gif-animation-sequence-to-display-within-firefox" id="id14">How do I create a GIF animation sequence to display within Firefox?</a></li>
+<li><a class="reference internal" href="#when-i-display-a-postscript-image-white-borders-are-trimmed" id="id15">When I display a <em>PostScript</em> image, white borders are trimmed.</a></li>
+<li><a class="reference internal" href="#what-are-visual-image-directories-how-do-i-use-them" id="id16">What are visual image directories? How do I use them?</a></li>
+<li><a class="reference internal" href="#how-can-i-include-the-window-frame-when-importing-a-window" id="id17">How can I include the window frame when importing a window?</a></li>
+<li><a class="reference internal" href="#i-displayed-an-image-and-it-appears-as-one-solid-color-what-did-i-do-wrong" id="id18">I displayed an image and it appears as one solid color. What did I do wrong?</a></li>
+<li><a class="reference internal" href="#i-received-the-following-message-library-is-not-available" id="id19">I received the following message, &quot;???? library is not available...&quot;.</a></li>
+<li><a class="reference internal" href="#i-want-to-inspect-the-values-of-the-matte-channel-within-my-image" id="id20">I want to inspect the values of the matte channel within my image.</a></li>
+<li><a class="reference internal" href="#how-can-i-add-one-of-those-cool-bevels-to-my-image-that-i-see-used-on-the-web" id="id21">How can I add one of those cool bevels to my image that I see used on the Web?</a></li>
+<li><a class="reference internal" href="#i-try-to-launch-display-from-my-window-manager-and-it-fails-what-s-up" id="id22">I try to launch display from my window manager and it fails. What's up?</a></li>
+<li><a class="reference internal" href="#how-can-i-make-postscript-text-look-good" id="id23">How can I make Postscript text look good?</a></li>
+<li><a class="reference internal" href="#how-can-i-annotate-an-image-with-text-that-is-2-to-3-inches-tall" id="id24">How can I annotate an image with text that is 2 to 3 inches tall?</a></li>
+<li><a class="reference internal" href="#how-can-i-convert-my-gif-animation-sequence-to-individual-image-files" id="id25">How can I convert my GIF animation sequence to individual image files?</a></li>
+<li><a class="reference internal" href="#how-can-i-remove-the-background-that-prints-around-my-image-when-i-display-it-with-firefox" id="id26">How can I remove the background that prints around my image when I display it with Firefox?</a></li>
+<li><a class="reference internal" href="#how-do-i-create-a-gif-or-png-image-with-web-safe-colors" id="id27">How do I create a GIF or PNG image with Web safe colors?</a></li>
+<li><a class="reference internal" href="#how-can-i-add-a-matte-layer-to-my-image" id="id28">How can I add a matte layer to my image?</a></li>
+<li><a class="reference internal" href="#how-can-i-draw-with-text-using-convert-under-windows-nt" id="id29">How can I draw with text using 'convert' under Windows NT?</a></li>
+<li><a class="reference internal" href="#why-are-my-jpeg-files-larger-than-expected" id="id30">Why are my JPEG files larger than expected?</a></li>
+<li><a class="reference internal" href="#how-do-i-extract-a-single-image-from-a-multi-image-file" id="id31">How do I extract a single image from a multi-image file?</a></li>
+<li><a class="reference internal" href="#how-can-i-extract-and-combine-cmyk-channels-in-a-cmyk-image" id="id32">How can I extract and combine CMYK channels in a CMYK image?</a></li>
+<li><a class="reference internal" href="#how-can-i-create-a-solid-or-patterned-canvas-image" id="id33">How can I create a solid or patterned canvas image?</a></li>
+<li><a class="reference internal" href="#what-does-identify-report" id="id34">What does <cite>identify</cite> report?</a></li>
+</ul>
+</div>
+<div class="section" id="how-does-graphicsmagick-differ-from-imagemagick">
+<h1><a class="toc-backref" href="#id1">How does GraphicsMagick differ from ImageMagick?</a></h1>
+<p><em>GraphicsMagick</em> is originally based on (forked from) ImageMagick
+5.5.2 in November 2002, from the version distributed by ImageMagick
+Studio LLC, which is itself forked in August 1999 from ImageMagick
+developed by E. I. du Pont de Nemours and Company starting in
+1992. Other than utilities being executed as sub-commands of the 'gm'
+command, the command-line syntax and programming APIs remain entirely
+upward compatible with ImageMagick 5.5.2. A better question might be
+&quot;<em>How does ImageMagick differ from ImageMagick?</em>&quot; since ImageMagick
+continues to alter and evolve its interfaces so they are no longer
+completely compatible with earlier versions. While GraphicsMagick also
+adds new features, it does so in a way which assures that existing
+features work as they did before. ImageMagick focuses on adding new
+functionality and features and has dramatically mutated several times
+since the fork.</p>
+<p>GraphicsMagick maintains a stable release branch, maintains a detailed
+ChangeLog, and maintains a stable source repository with complete version
+history so that changes are controlled, and changes between releases are
+accurately described. GraphicsMagick provides continued support for a
+release branch. ImageMagick does not offer any of these things.</p>
+<p>Since GraphicsMagick is more stable, more time has been spent optimizing
+and debugging its code.</p>
+<p>GraphicsMagick is much smaller than ImageMagick and has dramatically
+fewer dependencies on external libraries. For example, on the FreeBSD
+operating system, a fully-featured install of GraphicsMagick depends
+on 36 libraries whereas ImageMagick requires 64. GraphicsMagick's
+installation footprint is 3-5X smaller than ImageMagick.</p>
+<p>GraphicsMagick is usually faster than ImageMagick. The baseline execution
+overhead for simple commands is much lower, and GraphicsMagick is also
+more efficient at dealing with large images.</p>
+</div>
+<div class="section" id="how-often-does-graphicsmagick-pick-up-new-code-from-imagemagick">
+<h1><a class="toc-backref" href="#id2">How often does GraphicsMagick pick up new code from ImageMagick?</a></h1>
+<p>GraphicsMagick never picks up new code from ImageMagick as distributed
+by ImageMagick Studio LLC. Not long after the GraphicsMagick project
+was started in November 2002, ImageMagick from ImageMagick Studio LLC
+abandoned the MIT X11 style license it had been using since 1992, and
+switched between several different licenses until it ended up with one
+based on the Apache license, which is intended to penalize projects
+which borrow some of its source code, or fork from it. Since that
+time, GraphicsMagick has not incorporated any ImageMagick source code.</p>
+<p>On November 27, 2003 ImageMagick Studio LLC applied to register
+&quot;ImageMagick&quot; as its trademark, and it was awarded this registered
+trademark (serial number 78333969) on August 30, 2005. Those who
+re-distribute modified versions of &quot;ImageMagick&quot; (e.g. patched or
+improved) under license as &quot;ImageMagick&quot; now face the risk of
+arbitrary trademark infringement claims by ImageMagick Studio LLC.</p>
+<p>Authors of new features are encouraged to independently contribute
+their work to the GraphicsMagick project so that it can be released
+under GraphicsMagick's MIT X11 style license without additional
+encumberment. In order for a work to be accepted, it must have been
+developed entirely outside the ImageMagick source base to avoid any
+possibility of copyright taint.</p>
+</div>
+<div class="section" id="are-there-any-plans-to-use-opencl-or-cuda-to-use-a-gpu">
+<h1><a class="toc-backref" href="#id3">Are there any plans to use OpenCL or CUDA to use a GPU?</a></h1>
+<p>It is well known that some math-intensive algorithms run very quickly
+on video-card (and stand-alone) GPUs. Video card vendors encourage
+you to buy an expensive video card with quite a lot of installed RAM
+and modify applications to use the GPU via their proprietary or
+limited-purpose APIs. GPUs are quite effective at producing images
+for real-time display, such as for video games and virtual reality.
+GraphicsMagick has been significantly updated to use multiple CPU
+cores to speed up the image processing, and work continues to thread
+the few remaining algorithms, or remove inefficiencies in algorithms
+which don't see as much speed-up as they should. Linear speedup as
+cores are added is typical for CPU-bound algorithms on well-designed
+CPUs. Regardless, <a class="reference external" href="http://en.wikipedia.org/wiki/Amdal%27s_law">Amdahl's law</a> is a significant factor
+in GraphicsMagick, with non-parallelizable code paths often dominating
+the time.</p>
+<p>It is my belief that stand-alone GPUs are a poor design (expensive,
+inefficient, failure-prone, bandwidth bottlenecked, lack
+functionality, are insecure, and are not supported in servers) and
+that multi-core CPUs will ultimately prevail. Functionality which
+currently works best in a GPU will simply be integrated into
+tomorrow's multi-core CPUs and C compilers will naturally support that
+functionality. Once GPU capabilities are integrated into CPUs, there
+will be no more need to develop specialized code for a GPU. Today 16
+core CPUs are readily available for purchase in systems at reasonable
+prices, and this trend is certain to continue.</p>
+<p>Intel's <a class="reference external" href="http://en.wikipedia.org/wiki/Xeon_Phi">Xeon Phi</a> offers a
+61 core 'x86 CPU in a GPU-like plugin form-factor which provides over
+a TeraFLOP of performance. Being based on power-hungry plug-in cards,
+this solution suffers from many of the issues associated with GPUs.
+However, since it supports OpenMP, it may be a suitable target for
+executing some GraphicsMagick algorithms. Effective use of Xeon Phi
+currently requires use of Intel's development tools so from that
+standpoint it is not much more open than GPUs.</p>
+<p>Future multi-core CPUs will use a similar amount of power to today's
+CPUs, will idle at very low power consumption levels, and will fit
+into a very small chassis. Due to this trend, there is no value
+obtained by expending energy toward developing specialized code for
+today's GPUs.</p>
+</div>
+<div class="section" id="what-is-the-meaning-of-magick">
+<h1><a class="toc-backref" href="#id4">What is the meaning of &quot;magick&quot;?</a></h1>
+<p>According to the infamous British accultist <a class="reference external" href="http://en.wikipedia.org/wiki/Aleister_Crowley">Aleister Crowley</a>, the definition of
+<a class="reference external" href="http://en.wikipedia.org/wiki/Magick_(Aleister_Crowley)">magick</a> is
+&quot;the science and art of causing change to occur in conformity with the
+will&quot;.</p>
+</div>
+<div class="section" id="how-can-i-process-many-files-at-once">
+<h1><a class="toc-backref" href="#id5">How can I process many files at once?</a></h1>
+<p>Use 'gm mogrify'. The 'mogrify' subcommand is designed to operate on
+any number of files in one command. Normally 'mogrify' overwrites the
+input files but the <cite>-output-directory</cite> option (which must appear
+before any input file names!) allows sending the modified files to a
+different directory (which could be in a subdirectory). For example:</p>
+<pre class="literal-block">
+gm mogrify -output-directory .thumbs -resize 320x200 *.jpg
+</pre>
+<p>If you encounter command line length limitations then you can have
+GraphicsMagick expand the file list by quoting the wildcard argument
+to prevent it from being expanded by your command shell:</p>
+<pre class="literal-block">
+gm mogrify -output-directory .thumbs -resize 320x200 &quot;*.jpg&quot;
+</pre>
+<p>and you can also retrieve a list of files to process from a text file
+(e.g. named 'files.txt') like:</p>
+<pre class="literal-block">
+gm mogrify -output-directory .thumbs -resize 320x200 &#64;files.txt
+</pre>
+<p>where files.txt has one line per file name. If the input file paths
+contain relative sub-directory paths (e.g. &quot;foo/file1&quot;, &quot;bar/file2&quot;),
+you can instruct GraphicsMagick to create a similar subdirectory
+structure under the output directory by adding the
+<cite>-create-directories</cite> option:</p>
+<pre class="literal-block">
+gm mogrify -output-directory .thumbs -create-directories -resize 320x200 &#64;files.txt
+</pre>
+<p>Note that the algorithm used to generate output file names is quite
+simple. If -output-directory is &quot;/foo&quot; and the file path is
+&quot;bar/none.jpg&quot; then the final path will be &quot;foo/bar/none.jpg&quot;. Based
+on this it should be clear that when <cite>-output-directory</cite> is used, file
+paths should be relative paths rather than absolute paths or else the
+concatenation won't work.</p>
+</div>
+<div class="section" id="i-received-the-following-message-delegation-failed-what-does-it-mean">
+<h1><a class="toc-backref" href="#id6">I received the following message, &quot;?????? delegation failed ...&quot;. What does it mean?</a></h1>
+<p><em>GraphicsMagick</em> uses several freely available packages to perform the
+translation of certain image formats (<em>PostScript</em>, <em>MPEG</em>, etc.). Make
+sure these packages are available as described in the <a class="reference external" href="README.html">README</a> file. Also
+verify that you have plenty of temporary disk space. If not, set the
+MAGICK_TMPDIR (or TMPDIR) environment variable to an area where
+sufficient space is available. Finally, for <em>PostScript</em>, verify that
+Ghostscript supports the <em>pnmraw</em> or <em>ppmraw</em> device (<tt class="docutils literal">gs <span class="pre">-h</span></tt>) and that
+the document contains valid <em>PostScript</em> statements (<tt class="docutils literal">gs image.ps</tt>).</p>
+</div>
+<div class="section" id="how-do-i-set-the-transparency-index-in-a-gif-image-so-it-displays-properly-within-mozilla">
+<h1><a class="toc-backref" href="#id7">How do I set the transparency index in a GIF image so it displays properly within Mozilla?</a></h1>
+<p>Display your GIF image with <a class="reference external" href="display.html">display</a>. Choose <em>Matte</em> from the <em>Image
+Edit</em> command menu and identify a pixel that has the <em>transparency</em>
+color. Press <em>Method</em> and select a matte edit method from a pop-up menu.
+Choose from these methods:</p>
+<ul class="simple">
+<li>point</li>
+<li>replace</li>
+<li>floodfill</li>
+</ul>
+<p>The <em>point</em> method changes the matte value of any pixel selected with the
+pointer until the button is is released. The <em>replace</em> method changes the
+matte value of any pixel that matches the color of the pixel you select
+with a button press. <em>Floodfill</em> changes the matte value of any pixel
+that matches the color of the pixel you select with a button press and is
+a neighbor.</p>
+<p>Select your transparent pixel with the pointer and press a button. The
+image is redisplayed with any transparent pixels recolored to the
+background color. You can select other pixels or areas to force to
+transparent. When you are satisfied, press Return.</p>
+<p>Finally, choose <em>Save</em> from the command menu and write your GIF image to
+a file. <strong>Note that setting transparency works best on a TrueColor or
+DirectColor visual</strong>. If your server only exports colormapped visuals you
+will need to use a <em>Standard Colormap</em> to set transparency.</p>
+<pre class="literal-block">
+xstdcmap -best
+gm display -map list image.gif
+[ choose Matte Edit ]
+[ select your transparent pixel then press Return ]
+[ choose Save '
+</pre>
+<p>If you do not have the <em>xstdcmap(1)</em> program, try</p>
+<pre class="literal-block">
+gm display -visual TrueColor image.gif
+</pre>
+</div>
+<div class="section" id="how-can-i-stop-the-filenames-from-changing-in-the-title-bar-of-the-animate-1-image-window">
+<h1><a class="toc-backref" href="#id8">How can I stop the filenames from changing in the title bar of the animate(1) image window?</a></h1>
+<p><a class="reference external" href="animate.html">Animate</a> updates the image file name in the title bar of the image window
+as each image is displayed from the image sequence. To display just a
+single name that will not change, use <em>-title</em>:</p>
+<pre class="literal-block">
+gm animate -title &quot;My Image Sequence&quot; images.
+</pre>
+</div>
+<div class="section" id="the-image-grabbed-by-import-1-does-not-look-like-the-image-on-my-x-server-what-s-wrong">
+<h1><a class="toc-backref" href="#id9">The image grabbed by import(1) does not look like the image on my X server. What's wrong?</a></h1>
+<p>Use the <em>-descend</em> option:</p>
+<pre class="literal-block">
+gm import -descend image.miff
+</pre>
+<p>or set this X resource:</p>
+<pre class="literal-block">
+gm import.descend: True
+</pre>
+<p>By default, <a class="reference external" href="import.html">import</a> quickly grabs the image from the X server. However,
+it may not always have the correct colors in some areas. This can happen
+when a subwindow has a different colormap than its parent. With
+<em>-descend</em>, <a class="reference external" href="import.html">import</a> descends the window hierarchy. Descending involves
+grabbing the image and colormap of each window or subwindow associated
+with the window you select and compositing it on a blank canvas. This can
+be significantly slower than just grabbing the top-level window but
+ensures the correct image.</p>
+</div>
+<div class="section" id="how-do-i-animate-a-digital-yuv-image-sequence">
+<h1><a class="toc-backref" href="#id10">How do I animate a digital YUV image sequence?</a></h1>
+<p>Suppose your sequence is 72 352x240 frames titled frame0.Y, frame0.U,
+frame0.V, frame1.Y, frame1.U, etc. Use this command:</p>
+<pre class="literal-block">
+gm animate -geometry 352x240 -scene 0-71 yuv3:frame%d
+</pre>
+</div>
+<div class="section" id="how-do-i-change-the-default-postscript-page-size">
+<h1><a class="toc-backref" href="#id11">How do I change the default <em>PostScript</em> page size?</a></h1>
+<p>The default dimensions of a <em>PostScript</em> page is 612x792. If you prefer
+another default, change the page geometries (PSPageGeometry) in
+<cite>magick/image.h</cite> and recompile.</p>
+</div>
+<div class="section" id="i-get-a-memory-allocation-error-what-can-i-do">
+<h1><a class="toc-backref" href="#id12">I get a memory allocation error. What can I do?</a></h1>
+<p>Memory allocation is a complex topic in GraphicsMagick and image
+processing requires a lot of memory. GraphicsMagick tries to take best
+advantage of the resources available by optimizing its use of <em>virtual</em>
+memory. Virtual memory is normally the amount of RAM (Random Access
+Memory) available to the process plus the amount of free space in the
+system paging area (known as &quot;swap&quot; under Unix, or a &quot;page file&quot; under
+Windows). In addition to the RAM and the paging area, GraphicsMagick is
+able to expand the amount of virtual memory available by using
+memory-mapped files which cause the file to be treated as extra memory. A
+piece of hardware known as the Memory Management Unit (MMU) performs the
+magic which allows the system paging area and memory-mapped files to be
+treated as more memory by your system's CPU.</p>
+<p>Usually when a memory allocation error occurs, it is because the system's
+paging area is full, or the programs memory (heap) is fragmented badly
+enough that there is no large-enough block of memory available to satisfy
+the request. In some cases the operating system may artificially limit
+the memory available to the program. Failures of small memory allocations
+are generally considered fatal by GraphicsMagick. If it is impossible to
+allocate even a little bit of memory, then there is no point in
+continuing. When large memory allocations associated with allocating
+memory for image pixels fail, GraphicsMagick uses that as a key to know
+that it should start using memory-mapped temporary files to increase
+virtual memory. Under Unix and other POSIX-compliant systems, these
+memory-mapped temporary files are created in either the system default
+location (e.g. <cite>/var/tmp</cite>) or the directory set by the TMPDIR environment
+variable. Under Windows, temporary files are created in the directory set
+by the TEMP or TMP environment variable. Use the MAGICK_TMPDIR
+environment variable to specify a directory for GraphicsMagick to write
+its temporary files.</p>
+<p>If the temporary file directory is too small, or is itself mapped to the
+system's paging area (no win!), then GraphicsMagick will fail to allocate
+more virtual memory via the temporary file and will return an error.</p>
+<p>The single biggest factor in how much memory is required by
+GraphicsMagick is the QuantumDepth setting when it was compiled. The
+amount of memory (in bytes) required to store a single image in memory is
+may be calculated via the equation (QuantumDepth*Rows*Columns*5)/8. As a
+means of example, the following table shows the amount of memory consumed
+by a single 1024x768 image using the supported QuantumDepth settings:</p>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="46%" />
+<col width="54%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">QuantumDepth</th>
+<th class="head">Virtual Memory</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>8</td>
+<td>3MB</td>
+</tr>
+<tr><td>16</td>
+<td>8MB</td>
+</tr>
+<tr><td>32</td>
+<td>15MB</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<p>Performing an image processing operation may require that several images
+be in memory at one time. In the case of animations, hundreds of images
+may be in memory at one time.</p>
+<p><em>GraphicsMagick</em> is designed to be general purpose. It can display many
+image storage formats (<em>Monochrome</em>, <em>PseudoColor</em>, or <em>TrueColor</em>) on
+many different types of X visuals (<em>StaticGray, StaticColor, PseudoColor,
+GrayScale, DirectColor,</em> or <em>TrueColor</em>). To support all these
+combinations of image storage formats and X visuals, extra memory is
+required. Additionally, <a class="reference external" href="animate.html">animate</a> and <a class="reference external" href="montage.html">montage</a> store an entire image
+sequence in memory.</p>
+<p>It is recommended that systems used to run <em>GraphicsMagick</em> have at least
+96MB of RAM and 140MB free in their paging area. Systems used to process
+large images (do the math!) may require considerably more memory to
+operate efficiently. GraphicsMagick is proven to be far more efficient at
+processing huge images when it is compiled as a 64-bit application on a
+64-bit capable CPU. RAM is typically 1000 times faster than disk, so it
+is important to keep as much data in RAM as possible (buy lots of RAM).
+The temporary file area should have plenty of free space. The size of the
+temporary file area is usually the deciding factor as to whether
+GraphicsMagick is able to complete an operation. With sufficient free
+disk space, GraphicsMagick is primarily limited by your CPU, your
+operating system's ability to address memory, and your degree of
+patience. GraphicsMagick has been used to process RGB images 64K by 64K
+pixels in size!</p>
+</div>
+<div class="section" id="how-do-i-concatenate-three-images-left-to-right-with-no-borders-frames-or-text">
+<h1><a class="toc-backref" href="#id13">How do I concatenate three images left-to-right with no borders, frames, or text?</a></h1>
+<p>Assume your three images are called image1.ppm, image2.ppm, and
+image3.ppm. Type</p>
+<pre class="literal-block">
+gm montage -mode concatenate -tile 3x1 image1.ppm image2.ppm \
+ image3.ppm concatenated.miff
+</pre>
+<p>To concatenate the images top-to-bottom, use -tile 1x3.</p>
+<p>For more control over the placement of an image, use <a class="reference external" href="composite.html">composite</a>. First
+create a matte image and position your images onto the matte. For
+example,</p>
+<pre class="literal-block">
+gm convert -size 350x500 xc:black composite.miff
+gm composite -geometry +0+0 composite.miff image1.gif composite.miff
+gm composite -geometry &quot;+1&quot;00+0 composite.miff image2.gif composite.miff
+gm composite -geometry +0+300 composite.miff image3.gif composite.miff
+gm composite -geometry +0+375 composite.miff image4.gif composite.miff
+</pre>
+</div>
+<div class="section" id="how-do-i-create-a-gif-animation-sequence-to-display-within-firefox">
+<h1><a class="toc-backref" href="#id14">How do I create a GIF animation sequence to display within Firefox?</a></h1>
+<p>Use <a class="reference external" href="convert.html">convert</a> with the <em>-delay</em> and <em>-page</em> options. The <em>-delay</em> option
+is used to specify the delay in <em>1/100ths of a second</em> between the
+display of each frame of the animation. For example,</p>
+<pre class="literal-block">
+gm convert -delay 20 frame*.gif animation.gif
+</pre>
+<p>You can also declare specific delays for each frame of the image
+sequence. For example, if the delay was 20, 10, and 5, use</p>
+<pre class="literal-block">
+gm convert -delay 20 frame1.gif -delay 10 frame2.gif \
+ -delay 5 frame3.gif animation.gif
+</pre>
+<p>Use <em>-page</em> to specify the <em>left</em> and <em>top</em> locations of the image frame</p>
+<pre class="literal-block">
+gm convert frame1.gif -page +50&quot;+1&quot;00 frame2.gif -page +0&quot;+1&quot;00 \
+ frame3.gif animation.gif
+</pre>
+<p>Finally, if you want the image to loop within <em>FireFox</em>, use <em>-loop</em></p>
+<pre class="literal-block">
+gm convert -loop 50 frame*.gif animation.gif
+</pre>
+<p>Note, that all the images are composited into a single multi-image GIF
+animation. If you want a single image produced for each frame, use
+<em>+adjoin</em></p>
+<pre class="literal-block">
+gm convert +adjoin images.* frames%d.gif
+</pre>
+</div>
+<div class="section" id="when-i-display-a-postscript-image-white-borders-are-trimmed">
+<h1><a class="toc-backref" href="#id15">When I display a <em>PostScript</em> image, white borders are trimmed.</a></h1>
+<p><em>GraphicsMagick</em> automatically trims any <em>PostScript</em> image as defined by
+the bounding box. To preempt this behavior, remove the bounding box
+statement from the <em>Postscript</em> or explicitly set the page size. For
+example,</p>
+<pre class="literal-block">
+gm display -page letter image.ps
+</pre>
+</div>
+<div class="section" id="what-are-visual-image-directories-how-do-i-use-them">
+<h1><a class="toc-backref" href="#id16">What are visual image directories? How do I use them?</a></h1>
+<p>A visual image directory (VID) is an image that contains thumbnails of
+one or more images in a file directory. Rather than displaying each
+individual image at its full resolution, you can browse the visual image
+directory and choose an image to display. You can create a VID with
+either of these commands:</p>
+<pre class="literal-block">
+gm montage *.jpg directory.vid
+gm convert 'vid:*.jpg' directory.vid
+</pre>
+<p>Of course you can substitute any filenames you desire. <a class="reference external" href="montage.html">Montage</a> has many
+relevant command line options. You can exercise more control over the
+appearance of the VID than with <a class="reference external" href="convert.html">convert</a>.</p>
+<p>Next display the directory:</p>
+<pre class="literal-block">
+gm display directory.vid
+</pre>
+<p>Finally browse and select an image to display. Move the pointer to the
+image and press button 3.</p>
+<p>You can create the VID directory with this command:</p>
+<pre class="literal-block">
+gm display 'vid:*.jpg'
+</pre>
+<p>You can also select <em>Visual Image...</em> from the <em>File</em> menu of the command
+widget.</p>
+<p><em>Note, that creating a VID is time consuming</em>. Creating them on-the-fly
+within <a class="reference external" href="display.html">display</a> may be less convenient than using <a class="reference external" href="montage.html">montage</a> or <a class="reference external" href="convert.html">convert</a> .
+Also, if you create them with <a class="reference external" href="montage.html">montage</a>. or <a class="reference external" href="convert.html">convert</a>, you can reuse them
+as often as necessary.</p>
+<p>Note that a visual image directory is useful for looking at individual
+frames of an image sequence:</p>
+<pre class="literal-block">
+gm display vid:movie.mpg
+</pre>
+</div>
+<div class="section" id="how-can-i-include-the-window-frame-when-importing-a-window">
+<h1><a class="toc-backref" href="#id17">How can I include the window frame when importing a window?</a></h1>
+<p>I use the window ID reported by <em>xwininfo(1)</em> with import and it does not
+include the window manager frame as expected. How can I save the window
+with its frame?</p>
+<p>By default, <em>xwininfo(1)</em> returns the ID of the window you click on. Use
+the <em>-frame</em> option to get the reparented window ID:</p>
+<pre class="literal-block">
+xwininfo -frame
+</pre>
+<p>You can then use the returned window ID with <a class="reference external" href="import.html">import</a>:</p>
+<pre class="literal-block">
+gm import -frame -window ID window.miff
+</pre>
+</div>
+<div class="section" id="i-displayed-an-image-and-it-appears-as-one-solid-color-what-did-i-do-wrong">
+<h1><a class="toc-backref" href="#id18">I displayed an image and it appears as one solid color. What did I do wrong?</a></h1>
+<p>A blank image generally means that the image is either corrupt or it has
+a matte channel and the matte values are all zero. <em>GraphicsMagick</em>
+treats a matte value of zero as completely transparent. To determine if
+this is the problem, try</p>
+<pre class="literal-block">
+gm display +matte image.miff
+</pre>
+</div>
+<div class="section" id="i-received-the-following-message-library-is-not-available">
+<h1><a class="toc-backref" href="#id19">I received the following message, &quot;???? library is not available...&quot;.</a></h1>
+<p><em>GraphicsMagick</em> requires source libraries not included with the
+distribution to view or convert certain image formats such as JPEG or
+TIFF. The above message means you did not compile the required library
+and link with the <em>GraphicsMagick</em> utilities. See <a class="reference external" href="README.html">README</a> for the
+location of these libraries and compiling instructions.</p>
+</div>
+<div class="section" id="i-want-to-inspect-the-values-of-the-matte-channel-within-my-image">
+<h1><a class="toc-backref" href="#id20">I want to inspect the values of the matte channel within my image.</a></h1>
+<p>View the matte image as a gray scale image. Suppose you have a TIFF image
+that has a matte channel and is 640 pixels in width and 480 in height.
+Type:</p>
+<pre class="literal-block">
+gm convert image.tiff image.matte
+gm display -size 640x480 gray:image.matte
+</pre>
+</div>
+<div class="section" id="how-can-i-add-one-of-those-cool-bevels-to-my-image-that-i-see-used-on-the-web">
+<h1><a class="toc-backref" href="#id21">How can I add one of those cool bevels to my image that I see used on the Web?</a></h1>
+<p>There are four types of ornamental borders you can add to your image
+with GraphicsMagick. Each is listed below with the procedure to use
+them with your image.</p>
+<ul>
+<li><p class="first">Surround the image with a border of color</p>
+<p>Use -border followed by the width and height of the border. Set the
+color of the border with -bordercolor. For example, to surround your
+image with a red border that is 25 pixels wide on each side, use</p>
+<pre class="literal-block">
+gm convert -bordercolor red -border 25x25 image.jpg image.gif
+</pre>
+</li>
+<li><p class="first">Lighten or darken image edges to create a 3-D effect</p>
+<p>Use -raise followed by the width of the image edge. For example, to
+create a raised edge effect of 25 pixels, use</p>
+<pre class="literal-block">
+gm convert -raise 25 image.jpg image.gif
+</pre>
+</li>
+<li><p class="first">Surround the image with an ornamental frame</p>
+<p>Use -frame followed by the width and height of the frame. Set the
+color of the border with -mattecolor. For example, to surround your
+image with a gray frame that is 25 pixels wide on each side, use</p>
+<pre class="literal-block">
+gm convert -mattecolor gray -frame 25x25 image.jpg image.gif
+</pre>
+</li>
+<li><p class="first">Surround the image with a raised or sunken bevel</p>
+<p>Use -frame followed by the width and height of the bevel. Set the
+color of the border with -mattecolor. This is just like the
+description above except you specify a bevel width that matches the
+frame width. For example, to surround your image with a gray bevel
+that is 25 pixels wide on each side, use</p>
+<pre class="literal-block">
+gm convert -mattecolor gray -frame 25x25+0+25 image.jpg image.gif
+gm convert -mattecolor gray -frame 25x25+25+0 image.jpg image.gif
+</pre>
+</li>
+</ul>
+</div>
+<div class="section" id="i-try-to-launch-display-from-my-window-manager-and-it-fails-what-s-up">
+<h1><a class="toc-backref" href="#id22">I try to launch display from my window manager and it fails. What's up?</a></h1>
+<p><a class="reference external" href="display.html">Display</a> determines if it is executing interactively and behaves
+differently depending on the result. To convince display &lt;display.html&gt;
+you are running in an interactive environment when launching from a
+window manager, use either of</p>
+<pre class="literal-block">
+display logo:Untitled
+display &lt; /dev/console
+</pre>
+<p>Note that this issue no longer exists as of GraphicsMagick 1.2.</p>
+</div>
+<div class="section" id="how-can-i-make-postscript-text-look-good">
+<h1><a class="toc-backref" href="#id23">How can I make Postscript text look good?</a></h1>
+<p>Simple. Increase the dots-per-inch when converting and sub-sample:</p>
+<pre class="literal-block">
+gm convert -density 288 -geometry 25% image.ps image.gif
+</pre>
+<p>Change the density to 144 and geometry to 50% if the above command fails
+due to insufficient memory. Alternatively, see the Ghostscript
+documentation about using high-quality fonts.</p>
+<p>The -density option increases the number of pixels (or dots) generated by
+Ghostscript when processing the input postscript file. However as all
+other images formats are generally displayed on screens which are
+typically about 72 to 100 dots per inch, the output image will be larger.</p>
+<p>The <em>-geometry</em> option reduces the large image output of ghostscript
+image back to a normal 72 dpi resolution (25% of 288 dpi gives 72 dpi)
+but in the process anti-aliases (or smooths) the fonts and lines of the
+image so as to remove the jaggies you would otherwise get from a normal
+postscript to image conversion.</p>
+</div>
+<div class="section" id="how-can-i-annotate-an-image-with-text-that-is-2-to-3-inches-tall">
+<h1><a class="toc-backref" href="#id24">How can I annotate an image with text that is 2 to 3 inches tall?</a></h1>
+<p>If you do not access to a particular named font that is large, try
+scalable fonts. First see if you have any scalable fonts. Type</p>
+<pre class="literal-block">
+xlsfonts -fn '*-0-0-0-0-*'
+</pre>
+<p>Or if you are using <a class="reference external" href="display.html">display</a>, use the font pattern above within the Font
+Browser (see Image Edit-&gt;Annotate). Next substitute the appropriate
+resolution. Keep in mind that a scalable font must be fully qualified to
+work. That is, all 14 fields must be specified. Here is one example where
+we annotate an image with large <em>Helvetica</em> text:</p>
+<pre class="literal-block">
+gm convert -font '-*-helvetica-*-*-*--300-300-*-*-*-*-iso8859-1' \
+ -fill green -draw 'text 50,300 Magick' image.gif annotated.gif
+</pre>
+<p>If you have the FreeType support built into GraphicsMagick, just
+increase your pointsize and/or density:</p>
+<pre class="literal-block">
+gm convert -font Helvetica -pointsize 100 -density 300 ...
+</pre>
+</div>
+<div class="section" id="how-can-i-convert-my-gif-animation-sequence-to-individual-image-files">
+<h1><a class="toc-backref" href="#id25">How can I convert my GIF animation sequence to individual image files?</a></h1>
+<p>Use the scene embedded file format with <a class="reference external" href="convert.html">convert</a>:</p>
+<pre class="literal-block">
+gm convert animation.gif +adjoin frame%02d.gif
+</pre>
+<p>The resulting image files are titled frame01.gif, frame02.gif,
+frame03.gif, etc.</p>
+</div>
+<div class="section" id="how-can-i-remove-the-background-that-prints-around-my-image-when-i-display-it-with-firefox">
+<h1><a class="toc-backref" href="#id26">How can I remove the background that prints around my image when I display it with Firefox?</a></h1>
+<p>Use the +page option of the <a class="reference external" href="convert.html">convert</a> command:</p>
+<pre class="literal-block">
+gm convert +page alpha.gif beta.gif
+</pre>
+<p>GIF allows for a page offset relative to some background. The page
+offset information may have been in your GIF image already or it
+could have been introduced by GraphicsMagick. Either way, +page
+removes the unwanted page offset and FireFox should behave as
+expected.</p>
+</div>
+<div class="section" id="how-do-i-create-a-gif-or-png-image-with-web-safe-colors">
+<h1><a class="toc-backref" href="#id27">How do I create a GIF or PNG image with Web safe colors?</a></h1>
+<p>Web safe colors are not normally needed any more since almost all
+computers now have true color displays. However, this FAQ may still be
+useful since it demonstrates how a colormap from an image may be
+applied to another image..</p>
+<p>Use the -map option of the <a class="reference external" href="convert.html">convert</a> command:</p>
+<pre class="literal-block">
+gm convert -map netscape: alpha.gif beta.gif
+</pre>
+<p>Netscape predefines 216 colors for colormapped displays. Use the above
+command to ensure only these predefined colors are used. Otherwise
+Netscape dithers your image with varying degrees of image fidelity.</p>
+</div>
+<div class="section" id="how-can-i-add-a-matte-layer-to-my-image">
+<h1><a class="toc-backref" href="#id28">How can I add a matte layer to my image?</a></h1>
+<p>One way is to use a bitmap as your transparency mask First, use the
+-matte option to add an all-opaque opacity channel, then use the
+composite utility to copy the graylevel samples from the mask file
+into your new opacity channel:</p>
+<pre class="literal-block">
+gm convert image.gif -matte temp.miff
+gm composite -compose CopyOpacity mask.xbm temp.miff transparent.gif
+</pre>
+<p>Note, GIF is limited to one transparent color. If your mask has
+variable opacity, use a format like MIFF, TIFF, or PNG as your output
+image format.</p>
+</div>
+<div class="section" id="how-can-i-draw-with-text-using-convert-under-windows-nt">
+<h1><a class="toc-backref" href="#id29">How can I draw with text using 'convert' under Windows NT?</a></h1>
+<p>The problem is that NT interprets the command line differently than
+Unix does, causing the documented command to fail. The following
+command has been reported to work correctly (all on one line):</p>
+<pre class="literal-block">
+gm convert -font Arial -fill blue -draw &quot;text 10,10 'your text here'&quot; \
+ d:\test.tif png:d:\test.png
+</pre>
+<p>and here is another example which is reported to work (which relies
+on Ghostscript's 'gs' program to installed):</p>
+<pre class="literal-block">
+gm convert.exe -pointsize 18 -draw &quot;text 0,0 &quot;This is my text!&quot;&quot; \
+ C:\blank.gif c:\text.gif
+</pre>
+</div>
+<div class="section" id="why-are-my-jpeg-files-larger-than-expected">
+<h1><a class="toc-backref" href="#id30">Why are my JPEG files larger than expected?</a></h1>
+<p>Your JPEG files may contain embedded &quot;profiles&quot; such as Exif or IPTC,
+or they may contain uncompressed thumbnails. You can use the <cite>+profile
+&quot;*&quot;</cite> commandline option or an equivalent API method to remove them.</p>
+</div>
+<div class="section" id="how-do-i-extract-a-single-image-from-a-multi-image-file">
+<h1><a class="toc-backref" href="#id31">How do I extract a single image from a multi-image file?</a></h1>
+<p>Use a square-bracket syntax to indicate which frame or frames you
+want. For example,</p>
+<pre class="literal-block">
+gm convert &quot;Image.gif[0]&quot; first.gif
+</pre>
+<p>Will extract the first image (scene 0) from a GIF animation. Be sure
+to surround the file specification with quotation marks, to prevent
+the shell from interpreting the square brackets.</p>
+</div>
+<div class="section" id="how-can-i-extract-and-combine-cmyk-channels-in-a-cmyk-image">
+<h1><a class="toc-backref" href="#id32">How can I extract and combine CMYK channels in a CMYK image?</a></h1>
+<p>GraphicsMagick 1.2.2 and later support combining multiple channels in of
+any image file format in order to create a CMYK image file. For example,
+starting with a CMYK JPEG file, we can create a set of separate files
+with one file per channel:</p>
+<pre class="literal-block">
+gm convert cmyk.jpg -channel cyan cyan.tiff
+gm convert cmyk.jpg -channel magenta magenta.tiff
+gm convert cmyk.jpg -channel yellow yellow.tiff
+gm convert cmyk.jpg -channel black black.tiff
+</pre>
+<p>and then we can join them back together:</p>
+<pre class="literal-block">
+gm composite -compose CopyMagenta magenta.tiff cyan.tiff result.tiff
+gm composite -compose CopyYellow yellow.tiff result.tiff result.tiff
+gm composite -compose CopyBlack black.tiff result.tiff result.tiff
+</pre>
+<p>Perhaps it is possible to accomplish this in one composite command. We
+will leave that as an exercise for later. Note that it is possible to
+extract just one channel, manipulate it, and then insert it back into the
+original image file.</p>
+<p>There is also built-in support for a <em>Partition</em> interlace format which
+can split to a set of files, and join a set of files, but the only
+supported format is a raw format which is not easy to deal with.</p>
+</div>
+<div class="section" id="how-can-i-create-a-solid-or-patterned-canvas-image">
+<h1><a class="toc-backref" href="#id33">How can I create a solid or patterned canvas image?</a></h1>
+<p>Canvas images may be created using the 'XC:' or 'TILE:' pseudo-image
+formats. XC produces solid color images based on an color you specify
+while TILE produces a tiled image based on an an image you specify. Both
+of these require that the desired size be specified, and the desired
+image type may be specified as well.</p>
+<p>To create a solid red canvas image:</p>
+<pre class="literal-block">
+gm convert -size 640x480 xc:red canvas.tiff
+</pre>
+<p>or using hex syntax to specify the color:</p>
+<pre class="literal-block">
+gm convert -size 640x480 &quot;xc:#f00&quot; canvas.tiff
+</pre>
+<p>To create a solid red canvas image using truecolor pixels:</p>
+<pre class="literal-block">
+gm convert -size 640x480 -type TrueColor xc:red canvas.tiff
+</pre>
+<p>To create a patterned canvas image using a built-in crosshatch pattern:</p>
+<pre class="literal-block">
+gm convert -size 640x480 tile:image:CROSSHATCH45 canvas.tiff
+</pre>
+<p>To create a patterned canvas image using a user-supplied image:</p>
+<pre class="literal-block">
+gm convert -size 640x480 tile:myimage.tiff canvas.tiff
+</pre>
+</div>
+<div class="section" id="what-does-identify-report">
+<h1><a class="toc-backref" href="#id34">What does <cite>identify</cite> report?</a></h1>
+<p>GraphicsMagick is sophisticated image handling software supporting
+perhaps a hundred formats, and hundreds of subformats, yet it needs to
+be able to apply image processing algorithms in a consistent way, and
+save to many output formats. Some image types are radically different
+from others. Due to this, GraphicsMagick normalizes images it reads
+into only nine internal in-memory formats (see the description of
+-type) which are a specialization of just two internal formats. The
+<cite>identify</cite> command reports the characteristics of one of those
+internal formats rather than the genuine properties of the input image
+file. In fact, if the properties of all the input files were to be
+reported, it would require a book to describe all of the properties.
+For example, the WMF vector-drawing format is much different from the
+PNG image file format, yet GraphicsMagick can read both.</p>
+<p>Only limited original properties are preserved, and it depends on how
+GraphicsMagick was built. For example, a &quot;Q8&quot; build can only report
+up to a depth of 8 bits, but a &quot;Q32&quot; build can report a depth of up to
+32 bits. The original image depth is reported if it is at least 8
+bits, and equal to or less than the build depth.</p>
+<p>By default <cite>identify</cite> reports only the most basic properties:</p>
+<pre class="literal-block">
+% gm identify seaworld.jpg
+seaworld.jpg JPEG 1530x1020+0+0 DirectClass 8-bit 204.0K 0.000u 0:01
+</pre>
+<p>but with -verbose it can report on a large number of properties.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/FAQ.rst b/www/FAQ.rst
new file mode 100644
index 0000000..1c4a274
--- /dev/null
+++ b/www/FAQ.rst
@@ -0,0 +1,776 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+==================
+GraphicsMagick FAQ
+==================
+
+.. URL links
+.. _animate: animate.html
+.. _composite: composite.html
+.. _convert: convert.html
+.. _display: display.html
+.. _import: import.html
+.. _install: install.html
+.. _montage: montage.html
+.. _README: README.html
+
+.. contents:: FAQ Contents
+
+How does GraphicsMagick differ from ImageMagick?
+------------------------------------------------
+
+*GraphicsMagick* is originally based on (forked from) ImageMagick
+5.5.2 in November 2002, from the version distributed by ImageMagick
+Studio LLC, which is itself forked in August 1999 from ImageMagick
+developed by E. I. du Pont de Nemours and Company starting in
+1992. Other than utilities being executed as sub-commands of the 'gm'
+command, the command-line syntax and programming APIs remain entirely
+upward compatible with ImageMagick 5.5.2. A better question might be
+"*How does ImageMagick differ from ImageMagick?*" since ImageMagick
+continues to alter and evolve its interfaces so they are no longer
+completely compatible with earlier versions. While GraphicsMagick also
+adds new features, it does so in a way which assures that existing
+features work as they did before. ImageMagick focuses on adding new
+functionality and features and has dramatically mutated several times
+since the fork.
+
+GraphicsMagick maintains a stable release branch, maintains a detailed
+ChangeLog, and maintains a stable source repository with complete version
+history so that changes are controlled, and changes between releases are
+accurately described. GraphicsMagick provides continued support for a
+release branch. ImageMagick does not offer any of these things.
+
+Since GraphicsMagick is more stable, more time has been spent optimizing
+and debugging its code.
+
+GraphicsMagick is much smaller than ImageMagick and has dramatically
+fewer dependencies on external libraries. For example, on the FreeBSD
+operating system, a fully-featured install of GraphicsMagick depends
+on 36 libraries whereas ImageMagick requires 64. GraphicsMagick's
+installation footprint is 3-5X smaller than ImageMagick.
+
+GraphicsMagick is usually faster than ImageMagick. The baseline execution
+overhead for simple commands is much lower, and GraphicsMagick is also
+more efficient at dealing with large images.
+
+How often does GraphicsMagick pick up new code from ImageMagick?
+----------------------------------------------------------------
+
+GraphicsMagick never picks up new code from ImageMagick as distributed
+by ImageMagick Studio LLC. Not long after the GraphicsMagick project
+was started in November 2002, ImageMagick from ImageMagick Studio LLC
+abandoned the MIT X11 style license it had been using since 1992, and
+switched between several different licenses until it ended up with one
+based on the Apache license, which is intended to penalize projects
+which borrow some of its source code, or fork from it. Since that
+time, GraphicsMagick has not incorporated any ImageMagick source code.
+
+On November 27, 2003 ImageMagick Studio LLC applied to register
+"ImageMagick" as its trademark, and it was awarded this registered
+trademark (serial number 78333969) on August 30, 2005. Those who
+re-distribute modified versions of "ImageMagick" (e.g. patched or
+improved) under license as "ImageMagick" now face the risk of
+arbitrary trademark infringement claims by ImageMagick Studio LLC.
+
+Authors of new features are encouraged to independently contribute
+their work to the GraphicsMagick project so that it can be released
+under GraphicsMagick's MIT X11 style license without additional
+encumberment. In order for a work to be accepted, it must have been
+developed entirely outside the ImageMagick source base to avoid any
+possibility of copyright taint.
+
+Are there any plans to use OpenCL or CUDA to use a GPU?
+-------------------------------------------------------
+
+It is well known that some math-intensive algorithms run very quickly
+on video-card (and stand-alone) GPUs. Video card vendors encourage
+you to buy an expensive video card with quite a lot of installed RAM
+and modify applications to use the GPU via their proprietary or
+limited-purpose APIs. GPUs are quite effective at producing images
+for real-time display, such as for video games and virtual reality.
+GraphicsMagick has been significantly updated to use multiple CPU
+cores to speed up the image processing, and work continues to thread
+the few remaining algorithms, or remove inefficiencies in algorithms
+which don't see as much speed-up as they should. Linear speedup as
+cores are added is typical for CPU-bound algorithms on well-designed
+CPUs. Regardless, `Amdahl's law
+<http://en.wikipedia.org/wiki/Amdal%27s_law>`_ is a significant factor
+in GraphicsMagick, with non-parallelizable code paths often dominating
+the time.
+
+It is my belief that stand-alone GPUs are a poor design (expensive,
+inefficient, failure-prone, bandwidth bottlenecked, lack
+functionality, are insecure, and are not supported in servers) and
+that multi-core CPUs will ultimately prevail. Functionality which
+currently works best in a GPU will simply be integrated into
+tomorrow's multi-core CPUs and C compilers will naturally support that
+functionality. Once GPU capabilities are integrated into CPUs, there
+will be no more need to develop specialized code for a GPU. Today 16
+core CPUs are readily available for purchase in systems at reasonable
+prices, and this trend is certain to continue.
+
+Intel's `Xeon Phi <http://en.wikipedia.org/wiki/Xeon_Phi>`_ offers a
+61 core 'x86 CPU in a GPU-like plugin form-factor which provides over
+a TeraFLOP of performance. Being based on power-hungry plug-in cards,
+this solution suffers from many of the issues associated with GPUs.
+However, since it supports OpenMP, it may be a suitable target for
+executing some GraphicsMagick algorithms. Effective use of Xeon Phi
+currently requires use of Intel's development tools so from that
+standpoint it is not much more open than GPUs.
+
+Future multi-core CPUs will use a similar amount of power to today's
+CPUs, will idle at very low power consumption levels, and will fit
+into a very small chassis. Due to this trend, there is no value
+obtained by expending energy toward developing specialized code for
+today's GPUs.
+
+What is the meaning of "magick"?
+--------------------------------
+
+According to the infamous British accultist `Aleister Crowley
+<http://en.wikipedia.org/wiki/Aleister_Crowley>`_, the definition of
+`magick <http://en.wikipedia.org/wiki/Magick_(Aleister_Crowley)>`_ is
+"the science and art of causing change to occur in conformity with the
+will".
+
+How can I process many files at once?
+-------------------------------------
+
+Use 'gm mogrify'. The 'mogrify' subcommand is designed to operate on
+any number of files in one command. Normally 'mogrify' overwrites the
+input files but the `-output-directory` option (which must appear
+before any input file names!) allows sending the modified files to a
+different directory (which could be in a subdirectory). For example::
+
+ gm mogrify -output-directory .thumbs -resize 320x200 *.jpg
+
+If you encounter command line length limitations then you can have
+GraphicsMagick expand the file list by quoting the wildcard argument
+to prevent it from being expanded by your command shell::
+
+ gm mogrify -output-directory .thumbs -resize 320x200 "*.jpg"
+
+and you can also retrieve a list of files to process from a text file
+(e.g. named 'files.txt') like::
+
+ gm mogrify -output-directory .thumbs -resize 320x200 @files.txt
+
+where files.txt has one line per file name. If the input file paths
+contain relative sub-directory paths (e.g. "foo/file1", "bar/file2"),
+you can instruct GraphicsMagick to create a similar subdirectory
+structure under the output directory by adding the
+`-create-directories` option::
+
+ gm mogrify -output-directory .thumbs -create-directories -resize 320x200 @files.txt
+
+Note that the algorithm used to generate output file names is quite
+simple. If -output-directory is "/foo" and the file path is
+"bar/none.jpg" then the final path will be "foo/bar/none.jpg". Based
+on this it should be clear that when `-output-directory` is used, file
+paths should be relative paths rather than absolute paths or else the
+concatenation won't work.
+
+
+I received the following message, "?????? delegation failed ...". What does it mean?
+------------------------------------------------------------------------------------
+
+*GraphicsMagick* uses several freely available packages to perform the
+translation of certain image formats (*PostScript*, *MPEG*, etc.). Make
+sure these packages are available as described in the README_ file. Also
+verify that you have plenty of temporary disk space. If not, set the
+MAGICK_TMPDIR (or TMPDIR) environment variable to an area where
+sufficient space is available. Finally, for *PostScript*, verify that
+Ghostscript supports the *pnmraw* or *ppmraw* device (``gs -h``) and that
+the document contains valid *PostScript* statements (``gs image.ps``).
+
+How do I set the transparency index in a GIF image so it displays properly within Mozilla?
+------------------------------------------------------------------------------------------
+
+Display your GIF image with display_. Choose *Matte* from the *Image
+Edit* command menu and identify a pixel that has the *transparency*
+color. Press *Method* and select a matte edit method from a pop-up menu.
+Choose from these methods:
+
+* point
+* replace
+* floodfill
+
+The *point* method changes the matte value of any pixel selected with the
+pointer until the button is is released. The *replace* method changes the
+matte value of any pixel that matches the color of the pixel you select
+with a button press. *Floodfill* changes the matte value of any pixel
+that matches the color of the pixel you select with a button press and is
+a neighbor.
+
+Select your transparent pixel with the pointer and press a button. The
+image is redisplayed with any transparent pixels recolored to the
+background color. You can select other pixels or areas to force to
+transparent. When you are satisfied, press Return.
+
+Finally, choose *Save* from the command menu and write your GIF image to
+a file. **Note that setting transparency works best on a TrueColor or
+DirectColor visual**. If your server only exports colormapped visuals you
+will need to use a *Standard Colormap* to set transparency. ::
+
+ xstdcmap -best
+ gm display -map list image.gif
+ [ choose Matte Edit ]
+ [ select your transparent pixel then press Return ]
+ [ choose Save '
+
+If you do not have the *xstdcmap(1)* program, try ::
+
+ gm display -visual TrueColor image.gif
+
+How can I stop the filenames from changing in the title bar of the animate(1) image window?
+-------------------------------------------------------------------------------------------
+
+Animate_ updates the image file name in the title bar of the image window
+as each image is displayed from the image sequence. To display just a
+single name that will not change, use *-title*::
+
+ gm animate -title "My Image Sequence" images.
+
+The image grabbed by import(1) does not look like the image on my X server. What's wrong?
+-----------------------------------------------------------------------------------------
+
+Use the *-descend* option::
+
+ gm import -descend image.miff
+
+or set this X resource::
+
+ gm import.descend: True
+
+By default, import_ quickly grabs the image from the X server. However,
+it may not always have the correct colors in some areas. This can happen
+when a subwindow has a different colormap than its parent. With
+*-descend*, import_ descends the window hierarchy. Descending involves
+grabbing the image and colormap of each window or subwindow associated
+with the window you select and compositing it on a blank canvas. This can
+be significantly slower than just grabbing the top-level window but
+ensures the correct image.
+
+How do I animate a digital YUV image sequence?
+----------------------------------------------
+
+Suppose your sequence is 72 352x240 frames titled frame0.Y, frame0.U,
+frame0.V, frame1.Y, frame1.U, etc. Use this command::
+
+ gm animate -geometry 352x240 -scene 0-71 yuv3:frame%d
+
+How do I change the default *PostScript* page size?
+---------------------------------------------------
+
+The default dimensions of a *PostScript* page is 612x792. If you prefer
+another default, change the page geometries (PSPageGeometry) in
+`magick/image.h` and recompile.
+
+I get a memory allocation error. What can I do?
+-----------------------------------------------
+
+Memory allocation is a complex topic in GraphicsMagick and image
+processing requires a lot of memory. GraphicsMagick tries to take best
+advantage of the resources available by optimizing its use of *virtual*
+memory. Virtual memory is normally the amount of RAM (Random Access
+Memory) available to the process plus the amount of free space in the
+system paging area (known as "swap" under Unix, or a "page file" under
+Windows). In addition to the RAM and the paging area, GraphicsMagick is
+able to expand the amount of virtual memory available by using
+memory-mapped files which cause the file to be treated as extra memory. A
+piece of hardware known as the Memory Management Unit (MMU) performs the
+magic which allows the system paging area and memory-mapped files to be
+treated as more memory by your system's CPU.
+
+Usually when a memory allocation error occurs, it is because the system's
+paging area is full, or the programs memory (heap) is fragmented badly
+enough that there is no large-enough block of memory available to satisfy
+the request. In some cases the operating system may artificially limit
+the memory available to the program. Failures of small memory allocations
+are generally considered fatal by GraphicsMagick. If it is impossible to
+allocate even a little bit of memory, then there is no point in
+continuing. When large memory allocations associated with allocating
+memory for image pixels fail, GraphicsMagick uses that as a key to know
+that it should start using memory-mapped temporary files to increase
+virtual memory. Under Unix and other POSIX-compliant systems, these
+memory-mapped temporary files are created in either the system default
+location (e.g. `/var/tmp`) or the directory set by the TMPDIR environment
+variable. Under Windows, temporary files are created in the directory set
+by the TEMP or TMP environment variable. Use the MAGICK_TMPDIR
+environment variable to specify a directory for GraphicsMagick to write
+its temporary files.
+
+If the temporary file directory is too small, or is itself mapped to the
+system's paging area (no win!), then GraphicsMagick will fail to allocate
+more virtual memory via the temporary file and will return an error.
+
+The single biggest factor in how much memory is required by
+GraphicsMagick is the QuantumDepth setting when it was compiled. The
+amount of memory (in bytes) required to store a single image in memory is
+may be calculated via the equation (QuantumDepth*Rows*Columns*5)/8. As a
+means of example, the following table shows the amount of memory consumed
+by a single 1024x768 image using the supported QuantumDepth settings:
+
+ ============ ==============
+ QuantumDepth Virtual Memory
+ ============ ==============
+ 8 3MB
+ 16 8MB
+ 32 15MB
+ ============ ==============
+
+Performing an image processing operation may require that several images
+be in memory at one time. In the case of animations, hundreds of images
+may be in memory at one time.
+
+*GraphicsMagick* is designed to be general purpose. It can display many
+image storage formats (*Monochrome*, *PseudoColor*, or *TrueColor*) on
+many different types of X visuals (*StaticGray, StaticColor, PseudoColor,
+GrayScale, DirectColor,* or *TrueColor*). To support all these
+combinations of image storage formats and X visuals, extra memory is
+required. Additionally, animate_ and montage_ store an entire image
+sequence in memory.
+
+It is recommended that systems used to run *GraphicsMagick* have at least
+96MB of RAM and 140MB free in their paging area. Systems used to process
+large images (do the math!) may require considerably more memory to
+operate efficiently. GraphicsMagick is proven to be far more efficient at
+processing huge images when it is compiled as a 64-bit application on a
+64-bit capable CPU. RAM is typically 1000 times faster than disk, so it
+is important to keep as much data in RAM as possible (buy lots of RAM).
+The temporary file area should have plenty of free space. The size of the
+temporary file area is usually the deciding factor as to whether
+GraphicsMagick is able to complete an operation. With sufficient free
+disk space, GraphicsMagick is primarily limited by your CPU, your
+operating system's ability to address memory, and your degree of
+patience. GraphicsMagick has been used to process RGB images 64K by 64K
+pixels in size!
+
+How do I concatenate three images left-to-right with no borders, frames, or text?
+---------------------------------------------------------------------------------
+
+Assume your three images are called image1.ppm, image2.ppm, and
+image3.ppm. Type ::
+
+ gm montage -mode concatenate -tile 3x1 image1.ppm image2.ppm \
+ image3.ppm concatenated.miff
+
+To concatenate the images top-to-bottom, use -tile 1x3.
+
+For more control over the placement of an image, use composite_. First
+create a matte image and position your images onto the matte. For
+example, ::
+
+ gm convert -size 350x500 xc:black composite.miff
+ gm composite -geometry +0+0 composite.miff image1.gif composite.miff
+ gm composite -geometry "+1"00+0 composite.miff image2.gif composite.miff
+ gm composite -geometry +0+300 composite.miff image3.gif composite.miff
+ gm composite -geometry +0+375 composite.miff image4.gif composite.miff
+
+
+How do I create a GIF animation sequence to display within Firefox?
+-------------------------------------------------------------------
+
+Use convert_ with the *-delay* and *-page* options. The *-delay* option
+is used to specify the delay in *1/100ths of a second* between the
+display of each frame of the animation. For example, ::
+
+ gm convert -delay 20 frame*.gif animation.gif
+
+You can also declare specific delays for each frame of the image
+sequence. For example, if the delay was 20, 10, and 5, use ::
+
+ gm convert -delay 20 frame1.gif -delay 10 frame2.gif \
+ -delay 5 frame3.gif animation.gif
+
+Use *-page* to specify the *left* and *top* locations of the image frame ::
+
+ gm convert frame1.gif -page +50"+1"00 frame2.gif -page +0"+1"00 \
+ frame3.gif animation.gif
+
+Finally, if you want the image to loop within *FireFox*, use *-loop* ::
+
+ gm convert -loop 50 frame*.gif animation.gif
+
+Note, that all the images are composited into a single multi-image GIF
+animation. If you want a single image produced for each frame, use
+*+adjoin* ::
+
+ gm convert +adjoin images.* frames%d.gif
+
+When I display a *PostScript* image, white borders are trimmed.
+---------------------------------------------------------------
+
+*GraphicsMagick* automatically trims any *PostScript* image as defined by
+the bounding box. To preempt this behavior, remove the bounding box
+statement from the *Postscript* or explicitly set the page size. For
+example, ::
+
+ gm display -page letter image.ps
+
+What are visual image directories? How do I use them?
+-----------------------------------------------------
+
+A visual image directory (VID) is an image that contains thumbnails of
+one or more images in a file directory. Rather than displaying each
+individual image at its full resolution, you can browse the visual image
+directory and choose an image to display. You can create a VID with
+either of these commands::
+
+ gm montage *.jpg directory.vid
+ gm convert 'vid:*.jpg' directory.vid
+
+Of course you can substitute any filenames you desire. Montage_ has many
+relevant command line options. You can exercise more control over the
+appearance of the VID than with convert_.
+
+Next display the directory::
+
+ gm display directory.vid
+
+Finally browse and select an image to display. Move the pointer to the
+image and press button 3.
+
+You can create the VID directory with this command::
+
+ gm display 'vid:*.jpg'
+
+You can also select *Visual Image...* from the *File* menu of the command
+widget.
+
+*Note, that creating a VID is time consuming*. Creating them on-the-fly
+within display_ may be less convenient than using montage_ or convert_ .
+Also, if you create them with montage_. or convert_, you can reuse them
+as often as necessary.
+
+Note that a visual image directory is useful for looking at individual
+frames of an image sequence::
+
+ gm display vid:movie.mpg
+
+How can I include the window frame when importing a window?
+-----------------------------------------------------------
+
+I use the window ID reported by *xwininfo(1)* with import and it does not
+include the window manager frame as expected. How can I save the window
+with its frame?
+
+By default, *xwininfo(1)* returns the ID of the window you click on. Use
+the *-frame* option to get the reparented window ID::
+
+ xwininfo -frame
+
+You can then use the returned window ID with import_::
+
+ gm import -frame -window ID window.miff
+
+I displayed an image and it appears as one solid color. What did I do wrong?
+----------------------------------------------------------------------------
+
+A blank image generally means that the image is either corrupt or it has
+a matte channel and the matte values are all zero. *GraphicsMagick*
+treats a matte value of zero as completely transparent. To determine if
+this is the problem, try ::
+
+ gm display +matte image.miff
+
+I received the following message, "???? library is not available...".
+---------------------------------------------------------------------
+
+*GraphicsMagick* requires source libraries not included with the
+distribution to view or convert certain image formats such as JPEG or
+TIFF. The above message means you did not compile the required library
+and link with the *GraphicsMagick* utilities. See README_ for the
+location of these libraries and compiling instructions.
+
+I want to inspect the values of the matte channel within my image.
+------------------------------------------------------------------
+
+View the matte image as a gray scale image. Suppose you have a TIFF image
+that has a matte channel and is 640 pixels in width and 480 in height.
+Type::
+
+ gm convert image.tiff image.matte
+ gm display -size 640x480 gray:image.matte
+
+How can I add one of those cool bevels to my image that I see used on the Web?
+------------------------------------------------------------------------------
+
+There are four types of ornamental borders you can add to your image
+with GraphicsMagick. Each is listed below with the procedure to use
+them with your image.
+
+* Surround the image with a border of color
+
+ Use -border followed by the width and height of the border. Set the
+ color of the border with -bordercolor. For example, to surround your
+ image with a red border that is 25 pixels wide on each side, use ::
+
+ gm convert -bordercolor red -border 25x25 image.jpg image.gif
+
+* Lighten or darken image edges to create a 3-D effect
+
+ Use -raise followed by the width of the image edge. For example, to
+ create a raised edge effect of 25 pixels, use ::
+
+ gm convert -raise 25 image.jpg image.gif
+
+* Surround the image with an ornamental frame
+
+ Use -frame followed by the width and height of the frame. Set the
+ color of the border with -mattecolor. For example, to surround your
+ image with a gray frame that is 25 pixels wide on each side, use ::
+
+ gm convert -mattecolor gray -frame 25x25 image.jpg image.gif
+
+* Surround the image with a raised or sunken bevel
+
+ Use -frame followed by the width and height of the bevel. Set the
+ color of the border with -mattecolor. This is just like the
+ description above except you specify a bevel width that matches the
+ frame width. For example, to surround your image with a gray bevel
+ that is 25 pixels wide on each side, use ::
+
+ gm convert -mattecolor gray -frame 25x25+0+25 image.jpg image.gif
+ gm convert -mattecolor gray -frame 25x25+25+0 image.jpg image.gif
+
+I try to launch display from my window manager and it fails. What's up?
+-----------------------------------------------------------------------
+
+Display_ determines if it is executing interactively and behaves
+differently depending on the result. To convince display <display.html>
+you are running in an interactive environment when launching from a
+window manager, use either of ::
+
+ display logo:Untitled
+ display < /dev/console
+
+Note that this issue no longer exists as of GraphicsMagick 1.2.
+
+How can I make Postscript text look good?
+-----------------------------------------
+
+Simple. Increase the dots-per-inch when converting and sub-sample::
+
+ gm convert -density 288 -geometry 25% image.ps image.gif
+
+Change the density to 144 and geometry to 50% if the above command fails
+due to insufficient memory. Alternatively, see the Ghostscript
+documentation about using high-quality fonts.
+
+The -density option increases the number of pixels (or dots) generated by
+Ghostscript when processing the input postscript file. However as all
+other images formats are generally displayed on screens which are
+typically about 72 to 100 dots per inch, the output image will be larger.
+
+The *-geometry* option reduces the large image output of ghostscript
+image back to a normal 72 dpi resolution (25% of 288 dpi gives 72 dpi)
+but in the process anti-aliases (or smooths) the fonts and lines of the
+image so as to remove the jaggies you would otherwise get from a normal
+postscript to image conversion.
+
+How can I annotate an image with text that is 2 to 3 inches tall?
+-----------------------------------------------------------------
+
+If you do not access to a particular named font that is large, try
+scalable fonts. First see if you have any scalable fonts. Type ::
+
+ xlsfonts -fn '*-0-0-0-0-*'
+
+Or if you are using display_, use the font pattern above within the Font
+Browser (see Image Edit->Annotate). Next substitute the appropriate
+resolution. Keep in mind that a scalable font must be fully qualified to
+work. That is, all 14 fields must be specified. Here is one example where
+we annotate an image with large *Helvetica* text::
+
+ gm convert -font '-*-helvetica-*-*-*--300-300-*-*-*-*-iso8859-1' \
+ -fill green -draw 'text 50,300 Magick' image.gif annotated.gif
+
+If you have the FreeType support built into GraphicsMagick, just
+increase your pointsize and/or density::
+
+ gm convert -font Helvetica -pointsize 100 -density 300 ...
+
+How can I convert my GIF animation sequence to individual image files?
+----------------------------------------------------------------------
+
+Use the scene embedded file format with convert_::
+
+ gm convert animation.gif +adjoin frame%02d.gif
+
+The resulting image files are titled frame01.gif, frame02.gif,
+frame03.gif, etc.
+
+How can I remove the background that prints around my image when I display it with Firefox?
+-------------------------------------------------------------------------------------------
+
+Use the +page option of the convert_ command::
+
+ gm convert +page alpha.gif beta.gif
+
+GIF allows for a page offset relative to some background. The page
+offset information may have been in your GIF image already or it
+could have been introduced by GraphicsMagick. Either way, +page
+removes the unwanted page offset and FireFox should behave as
+expected.
+
+How do I create a GIF or PNG image with Web safe colors?
+--------------------------------------------------------
+
+Web safe colors are not normally needed any more since almost all
+computers now have true color displays. However, this FAQ may still be
+useful since it demonstrates how a colormap from an image may be
+applied to another image..
+
+Use the -map option of the convert_ command::
+
+ gm convert -map netscape: alpha.gif beta.gif
+
+Netscape predefines 216 colors for colormapped displays. Use the above
+command to ensure only these predefined colors are used. Otherwise
+Netscape dithers your image with varying degrees of image fidelity.
+
+How can I add a matte layer to my image?
+----------------------------------------
+
+One way is to use a bitmap as your transparency mask First, use the
+-matte option to add an all-opaque opacity channel, then use the
+composite utility to copy the graylevel samples from the mask file
+into your new opacity channel::
+
+ gm convert image.gif -matte temp.miff
+ gm composite -compose CopyOpacity mask.xbm temp.miff transparent.gif
+
+Note, GIF is limited to one transparent color. If your mask has
+variable opacity, use a format like MIFF, TIFF, or PNG as your output
+image format.
+
+How can I draw with text using 'convert' under Windows NT?
+----------------------------------------------------------
+
+The problem is that NT interprets the command line differently than
+Unix does, causing the documented command to fail. The following
+command has been reported to work correctly (all on one line)::
+
+ gm convert -font Arial -fill blue -draw "text 10,10 'your text here'" \
+ d:\test.tif png:d:\test.png
+
+and here is another example which is reported to work (which relies
+on Ghostscript's 'gs' program to installed)::
+
+ gm convert.exe -pointsize 18 -draw "text 0,0 "This is my text!"" \
+ C:\blank.gif c:\text.gif
+
+Why are my JPEG files larger than expected?
+-------------------------------------------
+
+Your JPEG files may contain embedded "profiles" such as Exif or IPTC,
+or they may contain uncompressed thumbnails. You can use the `+profile
+"*"` commandline option or an equivalent API method to remove them.
+
+How do I extract a single image from a multi-image file?
+--------------------------------------------------------
+
+Use a square-bracket syntax to indicate which frame or frames you
+want. For example, ::
+
+ gm convert "Image.gif[0]" first.gif
+
+Will extract the first image (scene 0) from a GIF animation. Be sure
+to surround the file specification with quotation marks, to prevent
+the shell from interpreting the square brackets.
+
+How can I extract and combine CMYK channels in a CMYK image?
+------------------------------------------------------------
+
+GraphicsMagick 1.2.2 and later support combining multiple channels in of
+any image file format in order to create a CMYK image file. For example,
+starting with a CMYK JPEG file, we can create a set of separate files
+with one file per channel::
+
+ gm convert cmyk.jpg -channel cyan cyan.tiff
+ gm convert cmyk.jpg -channel magenta magenta.tiff
+ gm convert cmyk.jpg -channel yellow yellow.tiff
+ gm convert cmyk.jpg -channel black black.tiff
+
+and then we can join them back together::
+
+ gm composite -compose CopyMagenta magenta.tiff cyan.tiff result.tiff
+ gm composite -compose CopyYellow yellow.tiff result.tiff result.tiff
+ gm composite -compose CopyBlack black.tiff result.tiff result.tiff
+
+Perhaps it is possible to accomplish this in one composite command. We
+will leave that as an exercise for later. Note that it is possible to
+extract just one channel, manipulate it, and then insert it back into the
+original image file.
+
+There is also built-in support for a *Partition* interlace format which
+can split to a set of files, and join a set of files, but the only
+supported format is a raw format which is not easy to deal with.
+
+How can I create a solid or patterned canvas image?
+---------------------------------------------------
+
+Canvas images may be created using the 'XC:' or 'TILE:' pseudo-image
+formats. XC produces solid color images based on an color you specify
+while TILE produces a tiled image based on an an image you specify. Both
+of these require that the desired size be specified, and the desired
+image type may be specified as well.
+
+To create a solid red canvas image::
+
+ gm convert -size 640x480 xc:red canvas.tiff
+
+or using hex syntax to specify the color::
+
+ gm convert -size 640x480 "xc:#f00" canvas.tiff
+
+To create a solid red canvas image using truecolor pixels::
+
+ gm convert -size 640x480 -type TrueColor xc:red canvas.tiff
+
+To create a patterned canvas image using a built-in crosshatch pattern::
+
+ gm convert -size 640x480 tile:image:CROSSHATCH45 canvas.tiff
+
+To create a patterned canvas image using a user-supplied image::
+
+ gm convert -size 640x480 tile:myimage.tiff canvas.tiff
+
+What does `identify` report?
+----------------------------
+
+GraphicsMagick is sophisticated image handling software supporting
+perhaps a hundred formats, and hundreds of subformats, yet it needs to
+be able to apply image processing algorithms in a consistent way, and
+save to many output formats. Some image types are radically different
+from others. Due to this, GraphicsMagick normalizes images it reads
+into only nine internal in-memory formats (see the description of
+-type) which are a specialization of just two internal formats. The
+`identify` command reports the characteristics of one of those
+internal formats rather than the genuine properties of the input image
+file. In fact, if the properties of all the input files were to be
+reported, it would require a book to describe all of the properties.
+For example, the WMF vector-drawing format is much different from the
+PNG image file format, yet GraphicsMagick can read both.
+
+Only limited original properties are preserved, and it depends on how
+GraphicsMagick was built. For example, a "Q8" build can only report
+up to a depth of 8 bits, but a "Q32" build can report a depth of up to
+32 bits. The original image depth is reported if it is at least 8
+bits, and equal to or less than the build depth.
+
+By default `identify` reports only the most basic properties::
+
+ % gm identify seaworld.jpg
+ seaworld.jpg JPEG 1530x1020+0+0 DirectClass 8-bit 204.0K 0.000u 0:01
+
+but with -verbose it can report on a large number of properties.
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/GraphicsMagick.html b/www/GraphicsMagick.html
new file mode 100644
index 0000000..bb9aaab
--- /dev/null
+++ b/www/GraphicsMagick.html
@@ -0,0 +1,6371 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+gm - command-line utility to create, edit, compare, convert, or display images
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#desc">Description</a>
+</dt>
+<dt>
+<a href="#files">Files and Formats</a>
+</dt>
+<dt>
+<a href="#opti">Options</a>
+</dt>
+<dt>
+<a href="#envi">Environment</a>
+</dt>
+<dt>
+<a href="#file">Configuration Files</a>
+</dt>
+<dt>
+<a href="#auth">Authors</a>
+</dt>
+<dt>
+<a href="#copy">Copyright</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm animate</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file</em> <strong>[ [</strong>
+<em>options ...</em> <strong>]</strong> <em>file ...</em> <strong>]</strong>
+<p>
+<strong>gm batch</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <strong>[</strong> <em>script</em> <strong>]</strong>
+<p>
+<strong>gm benchmark</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> subcommand
+<p>
+<strong>gm compare</strong> <strong>[</strong> <em>options</em> <strong>... ]</strong> <em>reference-image</em>
+<strong>[</strong> <em>options</em> <strong>... ]</strong> <em>compare-image</em>
+<strong>[</strong> <em>options</em> <strong>... ]</strong>
+<p>
+<strong>gm composite</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>change-image base-image</em>
+<strong>[</strong> <em>mask-image</em> <strong>]</strong> <em>output-image</em>
+<p>
+<strong>gm conjure</strong> <strong>[</strong> <em>options</em> <strong>]</strong> <em>script.msl</em>
+<strong>[ [</strong> <em>options</em> <strong>]</strong> <em>script.msl</em> <strong>]</strong>
+<p>
+<strong>gm convert</strong> <strong>[ [</strong> <em>options ...</em> <strong>] [</strong> <em>input-file ...</em>
+<strong>] [</strong> <em>options ...</em> <strong>] ]</strong> <em>output-file</em>
+<p>
+<strong>gm display</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file ...</em>
+<strong>[ [</strong><em>options ...</em> <strong>]</strong><em>file ...</em> <strong>]</strong>
+<p>
+<strong>gm identify</strong> <em>file</em> <strong>[</strong> <em>file ...</em> <strong>]</strong>
+<p>
+<strong>gm import</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file</em>
+<p>
+<strong>gm mogrify</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file ...</em>
+<p>
+<strong>gm montage</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file</em> <strong>[ [</strong>
+<em>options ...</em> <strong>]</strong> <em>file ...</em> <strong>]</strong> <em>output-file</em>
+<p>
+<strong>gm time</strong> subcommand
+<p>
+<strong>gm version</strong>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p> GraphicsMagick's <strong>gm</strong> provides a suite of utilities for
+creating, comparing, converting, editing, and displaying images. All
+of the utilities are provided as sub-commands of a single <strong>gm</strong>
+executable:
+<p>
+<a href="animate.html"><strong>animate</strong></a>
+displays an animation (e.g. a GIF file) on any workstation display
+running an <em>X</em> server.
+<p>
+<a href="batch.html"><strong>batch</strong></a>
+executes an arbitary number of the utility commands
+(e.g. <strong>convert</strong>) in the form of a simple linear batch script in
+order to improve execution efficiency, and/or to allow use as a
+subordinate co-process under the control of an arbitrary script or
+program.
+<p>
+<a href="benchmark.html"><strong>benchmark</strong></a>
+executes one of the other utility commands (e.g. <strong>convert</strong>) for a
+specified number of iterations, or execution time, and reports
+execution time and other profiling information such as CPU
+utilization. <strong>Benchmark</strong> provides various operating modes
+including executing the command with a varying number of threads, and
+alternate reporting formats such as comma-separated value (CSV).
+<p>
+<a href="compare.html"><strong>compare</strong></a>
+compares two images and reports difference statistics according to
+specified metrics and/or outputs an image with a visual representation
+of the differences. It may also be used to test if images are similar
+within a particular range and specified metric, returning a truth
+value to the executing environment.
+<p>
+<a href="composite.html"><strong>composite</strong></a>
+composites images (blends or merges images together) to create new images.
+<p>
+<a href="conjure.html"><strong>conjure</strong></a>
+interprets and executes scripts in
+the Magick Scripting Language (MSL).
+<p>
+<a href="convert.html"><strong>convert</strong></a>
+converts an input file using one image format to an output file with
+the same or differing image format while applying an arbitrary number
+of image transformations.
+<p>
+<a href="display.html"><strong>display</strong></a>
+is a machine architecture independent image processing and display
+facility. It can display an image on any workstation display running
+an <em>X</em> server.
+<p>
+<a href="identify.html"><strong>identify</strong></a>
+describes the format and characteristics of one or more image
+files. It will also report if an image is incomplete or corrupt.
+<p>
+<a href="import.html"><strong>import</strong></a>
+reads an image from any visible window on an <em>X</em> server and
+outputs it as an image file. You can capture a single window, the
+entire screen, or any rectangular portion of the screen.
+<p>
+<a href="mogrify.html"><strong>mogrify</strong></a>
+transforms an image or a sequence of images. These transforms include
+<strong>image scaling</strong>, <strong>image rotation</strong>, <strong>color reduction</strong>,
+and others. The transmogrified image <strong>overwrites</strong> the original
+image.
+<p>
+<a href="montage.html"><strong>montage</strong></a>
+creates a composite by combining several separate images. The images
+are tiled on the composite image with the name of the image optionally
+appearing just below the individual tile.
+<p>
+<a href="time.html"><strong>time</strong></a>
+executes a subcommand and reports the user, system, and total
+execution time consumed.
+<p>
+<a href="version.html"><strong>version</strong></a>
+reports the GraphicsMagick release version, maximum sample-depth,
+copyright notice, supported features, and the options used while
+building the software.
+<p>
+The <strong>GraphicsMagick</strong> utilities recognize the following image formats:
+<br>&nbsp;<br>
+<table border="0" cellspacing="0" cellpadding="2">
+<p>
+<tr><td><strong>Name</strong> </td><td><strong>Mode</strong></td><td><strong>Description</strong></td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">3FR </td><td>r--</td><td>Hasselblad Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">8BIM </td><td>rw-</td><td>Photoshop resource format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">8BIMTEXT </td><td>rw-</td><td>Photoshop resource text format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">8BIMWTEXT</td><td>rw-</td><td>Photoshop resource wide text format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">APP1 </td><td>rw-</td><td>Raw application information</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">APP1JPEG </td><td>rw-</td><td>Raw JPEG binary data</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ART </td><td>r--</td><td>PF1: 1st Publisher</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ARW </td><td>r--</td><td>Sony Alpha DSLR RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">AVS </td><td>rw+</td><td>AVS X image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">BIE </td><td>rw-</td><td>Joint Bi-level Image experts Group</td></tr>
+<tr><td> </td><td> </td><td>interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">BMP </td><td>rw+</td><td>Microsoft Windows bitmap image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">BMP2 </td><td>-w-</td><td>Microsoft Windows bitmap image v2</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">BMP3 </td><td>-w-</td><td>Microsoft Windows bitmap image v3</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CACHE </td><td>---</td><td>Magick Persistent Cache image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CALS </td><td>rw-</td><td>Continuous Acquisition and Life-cycle</td></tr>
+<tr><td> </td><td> </td><td>Support Type 1 image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CAPTION </td><td>r--</td><td>Caption (requires separate size info)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CIN </td><td>rw-</td><td>Kodak Cineon Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CMYK </td><td>rw-</td><td>Raw cyan, magenta, yellow, and black</td></tr>
+<tr><td> </td><td> </td><td>samples (8 or 16 bits, depending on</td></tr>
+<tr><td> </td><td> </td><td>the image depth)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CMYKA </td><td>rw-</td><td>Raw cyan, magenta, yellow, black, and</td></tr>
+<tr><td> </td><td> </td><td>matte samples (8 or 16 bits, depending</td></tr>
+<tr><td> </td><td> </td><td>on the image depth)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CR2 </td><td>r--</td><td>Canon Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CRW </td><td>r--</td><td>Canon Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CUR </td><td>r--</td><td>Microsoft Cursor Icon</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CUT </td><td>r--</td><td>DR Halo</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DCM </td><td>r--</td><td>Digital Imaging and Communications in</td></tr>
+<tr><td> </td><td> </td><td>Medicine image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DCR </td><td>r--</td><td>Kodak Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DCX </td><td>rw+</td><td>ZSoft IBM PC multi-page Paintbrush</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DNG </td><td>r--</td><td>Adobe Digital Negative</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DPS </td><td>r--</td><td>Display PostScript Interpreter</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DPX </td><td>rw-</td><td>Digital Moving Picture Exchange</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPDF </td><td>rw-</td><td>Encapsulated Portable Document Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPI </td><td>rw-</td><td>Adobe Encapsulated PostScript</td></tr>
+<tr><td> </td><td> </td><td>Interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPS </td><td>rw-</td><td>Adobe Encapsulated PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPS2 </td><td>-w-</td><td>Adobe Level II Encapsulated PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPS3 </td><td>-w-</td><td>Adobe Level III Encapsulated PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPSF </td><td>rw-</td><td>Adobe Encapsulated PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPSI </td><td>rw-</td><td>Adobe Encapsulated PostScript</td></tr>
+<tr><td> </td><td> </td><td>Interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPT </td><td>rw-</td><td>Adobe Encapsulated PostScript with MS-DOS</td></tr>
+<tr><td> </td><td> </td><td>TIFF preview</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPT2 </td><td>rw-</td><td>Adobe Level II Encapsulated PostScript</td></tr>
+<tr><td> </td><td> </td><td>with MS-DOS TIFF preview</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPT3 </td><td>rw-</td><td>Adobe Level III Encapsulated PostScript</td></tr>
+<tr><td> </td><td> </td><td>with MS-DOS TIFF preview</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EXIF </td><td>rw-</td><td>Exif digital camera binary data</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">FAX </td><td>rw+</td><td>Group 3 FAX (Not TIFF Group3 FAX!)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">FITS </td><td>rw-</td><td>Flexible Image Transport System</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">FRACTAL </td><td>r--</td><td>Plasma fractal image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">FPX </td><td>rw-</td><td>FlashPix Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">GIF </td><td>rw+</td><td>CompuServe graphics interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">GIF87 </td><td>rw-</td><td>CompuServe graphics interchange format</td></tr>
+<tr><td> </td><td> </td><td>(version 87a)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">GRADIENT </td><td>r--</td><td>Gradual passing from one shade to</td></tr>
+<tr><td> </td><td> </td><td>another</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">GRAY </td><td>rw+</td><td>Raw gray samples (8/16/32 bits,</td></tr>
+<tr><td> </td><td> </td><td>depending on the image depth)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">HISTOGRAM</td><td>-w-</td><td>Histogram of the image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">HRZ </td><td>r--</td><td>HRZ: Slow scan TV</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">HTML </td><td>-w-</td><td>Hypertext Markup Language and a</td></tr>
+<tr><td> </td><td> </td><td>client-side image map</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICB </td><td>rw+</td><td>Truevision Targa image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICC </td><td>rw-</td><td>ICC Color Profile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICM </td><td>rw-</td><td>ICC Color Profile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICO </td><td>r--</td><td>Microsoft icon</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICON </td><td>r--</td><td>Microsoft icon</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IDENTITY </td><td>r--</td><td>Hald CLUT identity image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IMAGE </td><td>r--</td><td>GraphicsMagick Embedded Image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">INFO </td><td>-w+</td><td>Image descriptive information and</td></tr>
+<tr><td> </td><td> </td><td> statistics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IPTC </td><td>rw-</td><td>IPTC Newsphoto</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IPTCTEXT </td><td>rw-</td><td>IPTC Newsphoto text format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IPTCWTEXT</td><td>rw-</td><td>IPTC Newsphoto wide text format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JBG </td><td>rw+</td><td>Joint Bi-level Image experts Group</td></tr>
+<tr><td> </td><td> </td><td>interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JBIG </td><td>rw+</td><td>Joint Bi-level Image experts Group</td></tr>
+<tr><td> </td><td> </td><td>interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JNG </td><td>rw-</td><td>JPEG Network Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JP2 </td><td>rw-</td><td>JPEG-2000 JP2 File Format Syntax</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JPC </td><td>rw-</td><td>JPEG-2000 Code Stream Syntax</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JPEG </td><td>rw-</td><td>Joint Photographic Experts Group</td></tr>
+<tr><td> </td><td> </td><td>JFIF format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JPG </td><td>rw-</td><td>Joint Photographic Experts Group</td></tr>
+<tr><td> </td><td> </td><td>JFIF format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">K25 </td><td>r--</td><td>Kodak Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">KDC </td><td>r--</td><td>Kodak Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">LABEL </td><td>r--</td><td>Text image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">M2V </td><td>rw+</td><td>MPEG-2 Video Stream</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MAP </td><td>rw-</td><td>Colormap intensities and indices</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MAT </td><td>r--</td><td>MATLAB image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MATTE </td><td>-w+</td><td>MATTE format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MIFF </td><td>rw+</td><td>Magick Image File Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MNG </td><td>rw+</td><td>Multiple-image Network Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MONO </td><td>rw-</td><td>Bi-level bitmap in least-significant-</td></tr>
+<tr><td> </td><td> </td><td>-byte-first order</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MPC </td><td>rw+</td><td>Magick Persistent Cache image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MPEG </td><td>rw+</td><td>MPEG-1 Video Stream</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MPG </td><td>rw+</td><td>MPEG-1 Video Stream</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MRW </td><td>r--</td><td>Minolta Photo Raw</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MSL </td><td>r--</td><td>Magick Scripting Language</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MTV </td><td>rw+</td><td>MTV Raytracing image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MVG </td><td>rw-</td><td>Magick Vector Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">NEF </td><td>r--</td><td>Nikon Electronic Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">NULL </td><td>r--</td><td>Constant image of uniform color</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">OTB </td><td>rw-</td><td>On-the-air bitmap</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">P7 </td><td>rw+</td><td>Xv thumbnail format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PAL </td><td>rw-</td><td>16bit/pixel interleaved YUV</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PALM </td><td>rw-</td><td>Palm Pixmap</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PBM </td><td>rw+</td><td>Portable bitmap format (black and white)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCD </td><td>rw-</td><td>Photo CD</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCDS </td><td>rw-</td><td>Photo CD</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCL </td><td>-w-</td><td>Page Control Language</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCT </td><td>rw-</td><td>Apple Macintosh QuickDraw/PICT</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCX </td><td>rw-</td><td>ZSoft IBM PC Paintbrush</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PDB </td><td>rw+</td><td>Palm Database ImageViewer Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PDF </td><td>rw+</td><td>Portable Document Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PEF </td><td>r--</td><td>Pentax Electronic File</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PFA </td><td>r--</td><td>TrueType font</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PFB </td><td>r--</td><td>TrueType font</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PGM </td><td>rw+</td><td>Portable graymap format (gray scale)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PGX </td><td>r--</td><td>JPEG-2000 VM Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PICON </td><td>rw-</td><td>Personal Icon</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PICT </td><td>rw-</td><td>Apple Macintosh QuickDraw/PICT</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PIX </td><td>r--</td><td>Alias/Wavefront RLE image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PLASMA </td><td>r--</td><td>Plasma fractal image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNG </td><td>rw-</td><td>Portable Network Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNG24 </td><td>rw-</td><td>Portable Network Graphics, 24 bit RGB</td></tr>
+<tr><td> </td><td> </td><td>opaque only</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNG32 </td><td>rw-</td><td>Portable Network Graphics, 32 bit RGBA</td></tr>
+<tr><td> </td><td> </td><td>semitransparency OK</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNG8 </td><td>rw-</td><td>Portable Network Graphics, 8-bit</td></tr>
+<tr><td> </td><td> </td><td>indexed, binary transparency only</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNM </td><td>rw+</td><td>Portable anymap</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PPM </td><td>rw+</td><td>Portable pixmap format (color)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PREVIEW </td><td>-w-</td><td>Show a preview an image enhancement,</td></tr>
+<tr><td> </td><td> </td><td>effect, or f/x</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PS </td><td>rw+</td><td>Adobe PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PS2 </td><td>-w+</td><td>Adobe Level II PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PS3 </td><td>-w+</td><td>Adobe Level III PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PSD </td><td>rw-</td><td>Adobe Photoshop bitmap</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PTIF </td><td>rw-</td><td>Pyramid encoded TIFF</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PWP </td><td>r--</td><td>Seattle Film Works</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RAF </td><td>r--</td><td>Fuji Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RAS </td><td>rw+</td><td>SUN Rasterfile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RGB </td><td>rw+</td><td>Raw red, green, and blue samples</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RGBA </td><td>rw+</td><td>Raw red, green, blue, and matte samples</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RLA </td><td>r--</td><td>Alias/Wavefront image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RLE </td><td>r--</td><td>Utah Run length encoded image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SCT </td><td>r--</td><td>Scitex HandShake</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SFW </td><td>r--</td><td>Seattle Film Works</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SGI </td><td>rw+</td><td>Irix RGB image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SHTML </td><td>-w-</td><td>Hypertext Markup Language and a</td></tr>
+<tr><td> </td><td> </td><td>client-side image map</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">STEGANO </td><td>r--</td><td>Steganographic image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SUN </td><td>rw+</td><td>SUN Rasterfile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SVG </td><td>rw+</td><td>Scalable Vector Gaphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TEXT </td><td>rw+</td><td>Raw text</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TGA </td><td>rw+</td><td>Truevision Targa image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TIFF </td><td>rw+</td><td>Tagged Image File Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TILE </td><td>r--</td><td>Tile image with a texture</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TIM </td><td>r--</td><td>PSX TIM</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TOPOL </td><td>r--</td><td>TOPOL X Image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TTF </td><td>r--</td><td>TrueType font</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TXT </td><td>rw+</td><td>Raw text</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">UIL </td><td>-w-</td><td>X-Motif UIL table</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">UYVY </td><td>rw-</td><td>16bit/pixel interleaved YUV</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VDA </td><td>rw+</td><td>Truevision Targa image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VICAR </td><td>rw-</td><td>VICAR rasterfile format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VID </td><td>rw+</td><td>Visual Image Directory</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VIFF </td><td>rw+</td><td>Khoros Visualization image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VST </td><td>rw+</td><td>Truevision Targa image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">WBMP </td><td>rw-</td><td>Wireless Bitmap (level 0) image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">WMF </td><td>r--</td><td>Windows Metafile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">WPG </td><td>r--</td><td>Word Perfect Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">X </td><td>rw-</td><td>X Image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">X3F </td><td>r--</td><td>Foveon X3 (Sigma/Polaroid) RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XBM </td><td>rw-</td><td>X Windows system bitmap (black</td></tr>
+<tr><td> </td><td> </td><td>and white)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XC </td><td>r--</td><td>Constant image uniform color</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XCF </td><td>r--</td><td>GIMP image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XMP </td><td>rw-</td><td>Adobe XML metadata</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XPM </td><td>rw-</td><td>X Windows system pixmap (color)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XV </td><td>rw+</td><td>Khoros Visualization image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XWD </td><td>rw-</td><td>X Windows system window dump (color)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">YUV </td><td>rw-</td><td>CCIR 601 4:1:1 or 4:2:2 (8-bit only)</td></tr>
+<tr><td> </td><td> </td><td></td></tr>
+<tr><td> Modes: </td><td> </td><td></td></tr>
+<tr><td> </td><td>r </td><td>Read</td></tr>
+<tr><td> </td><td>w </td><td>Write</td></tr>
+<tr><td> </td><td>+ </td><td>Multi-image</td></tr>
+<br>&nbsp;<br>
+</table>
+<p>
+<em>Support for some of these formats require additional programs or libraries.
+See <a href="README.html">README</a>
+in the source package for where to find optional additional software</em>.
+<p>
+Note, a format delineated with <tt>+</tt> means that if more than one
+image is specified, frames are combined into a single multi-image
+file. Use <strong>+adjoin</strong> if you want a single image produced for each
+frame.
+<p>
+Your installation might not support all of the formats in the list.
+To get an accurate listing of the formats supported by your particular
+configuration, run <tt>"gm convert -list format"</tt>.
+<p>
+Raw images are expected to have one byte per pixel unless <strong>gm</strong> is
+compiled in 16-bit quantum mode or in 32-bit quantum mode. Here, the
+raw data is expected to be stored two or four bytes per pixel,
+respectively, in most-significant-byte-first order. For example, you
+can tell if <strong>gm</strong> was compiled in 16-bit mode by typing "gm
+version" without any options, and looking for "Q:16" in the first line
+of output.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="files"></a>Files and Formats
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+By default, the image format is determined by its magic number, i.e., the
+first few bytes of the file. To specify
+a particular image format, precede the filename with an image format name
+and a colon (<em>i.e.</em><strong>ps:image</strong>) or specify the image type as the
+filename suffix (<em>i.e.</em><strong>image.ps</strong>).
+The magic number takes precedence over the filename suffix
+and the prefix takes precedence over the magic number and the suffix
+in input files.
+When a file is read, its magic number is stored in the "image-&gt;magick"
+string.
+In output files, the prefix takes precedence over the filename suffix,
+and the filename suffix takes precedence over the
+"image-&gt;magick" string.
+<br>&nbsp;<br>
+<p>To read the "built-in" formats (GRANITE, H, LOGO,
+NETSCAPE, PLASMA, and ROSE) use a prefix (including the colon) without a
+filename or suffix. To read the XC format, follow the colon with a color
+specification. To read the CAPTION format, follow the colon with a text
+string or with a filename prefixed with the at symbol (<strong>@</strong>).
+<br>&nbsp;<br>
+<p>
+When you specify <strong>X</strong> as your image type, the filename has special
+meaning. It specifies an X window by <strong>id, name</strong>, or
+<strong>root</strong>. If
+no filename is specified, the window is selected by clicking the mouse
+in the desired window.
+<p>
+Specify <em>input_file</em> as <strong>-</strong> for standard input,
+<em>output_file</em> as <strong>-</strong> for standard output.
+If <em>input_file</em> has the extension <strong>.Z</strong> or <strong>.gz</strong>, the
+file is uncompressed with <strong>uncompress</strong> or <strong>gunzip</strong>
+respectively.
+If <em>output_file</em> has the extension <strong>.Z</strong> or <strong>.gz</strong>,
+the file is compressed using with <em>compress</em> or <em>gzip</em> respectively.
+<p>
+Use an optional index enclosed in brackets after an input file name to
+specify a desired subimage of a multi-resolution image format like
+Photo CD (e.g. <tt>"img0001.pcd[4]"</tt>) or a range for MPEG images
+(e.g. <tt>"video.mpg[50-75]"</tt>). A subimage specification can be
+disjoint (e.g. <tt>"image.tiff[2,7,4]"</tt>). For raw images, specify
+a subimage with a geometry (e.g. <tt>-size 640x512</tt>
+<tt>"image.rgb[320x256+50+50]"</tt>). Surround the image name with
+quotation marks to prevent your shell from interpreting the square
+brackets. <p>Single images are written with the filename you
+specify. However, multi-part images (e.g., a multi-page PostScript
+document with <strong>+adjoin</strong> specified) may be written with the scene
+number included as part of the filename. In order to include the scene
+number in the filename, it is necessary to include a printf-style
+<tt>%d</tt> format specification in the file name and use the +adjoin
+option. For example,
+<pre>
+ image%02d.miff
+</pre>
+<p>
+writes files <em>image00.miff, image01.miff,</em> etc. Only a single
+specification is allowed within an output filename. If more than one
+specification is present, it will be ignored. It is best to embed the
+scene number in the base part of the file name, not in the extension,
+because the extension will not be a recognizeable image type.
+<p>
+When running a commandline utility, you can
+prepend an at sign <tt>@</tt> to a filename to read a list of image
+filenames from that file. This is convenient in the event you have too
+many image filenames to fit on the command line.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or <strong>-noop</strong>.
+Some options only affect the decoding of images and others only the encoding.
+The latter can appear after the final group of input images.
+<p>
+This is a combined list of the command-line options used by the
+GraphicsMagick utilities (<em>animate</em>, <em>compare</em>,
+<em>composite</em>, <em>convert</em>, <em>display</em>, <em>identify</em>,
+<em>import</em>, <em>mogrify</em> and <em>montage</em>).
+<br>&nbsp;<br>
+<p>
+In this document, angle brackets ("&lt;&gt;") enclose variables and curly
+brackets ("{}") enclose optional parameters. For example,
+"<strong>-fuzz &lt;distance&gt;{%}</strong>" means you can use the
+option <tt>"-fuzz 10"</tt>
+or <tt>"-fuzz 2%"</tt>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-adjoin"></a>-adjoin
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>join images into a single multi-image file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, all images of an image sequence are stored in the same
+file. However, some formats (e.g. JPEG) do not support storing more
+than one image per file and only the first frame in an image sequence
+will be saved unless the result is saved to separate files. Use
+<strong>+adjoin</strong> to force saving multiple frames to multiple numbered
+files. If <strong>+adjoin</strong> is used, then the output filename must
+include a printf style formatting specification for the numeric part
+of the filename. For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ image%02d.miff
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-affine"></a>-affine <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>drawing transform matrix</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option provides a transform matrix <tt>{sx,rx,ry,sy,tx,ty}</tt> for
+use by subsequent <strong>-draw</strong> or <strong>-transform</strong> options.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-antialias"></a>-antialias
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixel aliasing</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default antialiasing algorithms are used when drawing objects (e.g. lines)
+or rendering vector formats (e.g. WMF and Postscript). Use +antialias to
+disable use of antialiasing algorithms. Reasons to disable antialiasing
+include avoiding increasing colors in the image, or improving rendering speed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-append"></a>-append
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>append a set of images</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option creates a single image where the images in the original set
+are stacked top-to-bottom. If they are not of the same width,
+any narrow images will be expanded to fit using the background color.
+Use <strong>+append</strong> to stack images left-to-right. The set of images
+is terminated by the appearance of any option.
+If the <strong>-append</strong>
+option appears after all of the input images, all images are appended.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details"></a> <i>-asc-cdl &lt;spec&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply ASC CDL color transform</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Applies ("bakes in") the ASC CDL, which is a format for the exchange
+of basic primary color grading information between equipment and
+software from different manufacturers. The format defines the math for
+three functions: slope, offset and power. Each function uses a number
+for the red, green, and blue color channels for a total of nine
+numbers comprising a single color decision. The tenth number
+(optional) is for chromiance (saturation) as specified by ASC CDL
+1.2.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The argument string is comma delimited and is in the following form
+(but without invervening spaces or line breaks)</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ redslope,redoffset,redpower:
+ greenslope,greenoffset,greenpower:
+ blueslope,blueoffset,bluepower:
+ saturation
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+with the unity (no change) specification being:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ "1.0,0.0,1.0:1.0,0.0,1.0:1.0,0.0,1.0:1.0"
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-authenticate"></a>-authenticate <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to supply a password for decrypting an image or an
+image sequence, if it is being read from a format such as PDF that supports
+encryption. Encrypting images being written is not supported.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-auto-orient"></a>-auto-orient
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>orient (rotate) image so it is upright</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Adjusts the image orienation so that it is suitable for viewing. Uses
+the orientation tag obtained from the image file or as supplied by the
+<strong>-orient</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-average"></a>-average
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>average a set of images</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The set of images
+is terminated by the appearance of any option.
+If the <strong>-average</strong>
+option appears after all of the input images, all images are averaged.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-backdrop"></a>-backdrop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the image centered on a backdrop.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This backdrop covers the entire workstation screen and is useful for hiding
+other X window activity while viewing the image. The color of the backdrop
+is specified as the foreground color (X11 default is black).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Refer to
+<a href="#xres">X Resources</a>
+for details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-background"></a>-background <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-black-threshold"></a>-black-threshold <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels below the threshold become black</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>-black-threshold</strong> to set pixels with values below the specified
+threshold to minimum value (black). If only one value is supplied, or the
+red, green, and blue values are identical, then intensity thresholding is
+used. If the color threshold values are not identical then channel-based
+thresholding is used, and color distortion will occur. Specify a negative
+value (e.g. -1) if you want a channel to be ignored but you do want to
+threshold a channel later in the list. If a percent (%) symbol is
+appended, then the values are treated as a percentage of maximum
+range.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-blue-primary"></a>-blue-primary <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-blur"></a>-blur <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Blur with the given radius and
+standard deviation (sigma).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-border"></a>-border <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with a border of color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details
+about the geometry specification.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-bordercolor"></a>-bordercolor <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -borderwidth <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-box"></a>-box <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the color of the annotation bounding box</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-draw</strong> for further
+details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-channel"></a>-channel <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of channel</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from: <strong>Red</strong>, <strong>Green</strong>, <strong>Blue</strong>, <strong>Opacity</strong>,
+<strong>Matte</strong>, <strong>Cyan</strong>, <strong>Magenta</strong>, <strong>Yellow</strong>, <strong>Black</strong>,
+or <strong>Gray</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to extract a particular <em>channel</em> from the image.
+<strong>Opacity</strong>,
+for example, is useful for extracting the opacity values from an image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -charcoal <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate a charcoal drawing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-chop"></a>-chop <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixels from the interior of an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>Width</em> and <em>height</em> give the number of columns and rows to remove,
+and <em>x</em> and <em>y</em> are offsets that give the location of the
+leftmost column and topmost row to remove.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <em>x</em> offset normally specifies the leftmost column to remove.
+If the <strong>-gravity</strong> option is present with <em>NorthEast, East,</em>
+or <em>SouthEast</em>
+gravity, it gives the distance leftward from the right edge
+of the image to the rightmost column to remove. Similarly, the <em>y</em> offset
+normally specifies the topmost row to remove, but if
+the <strong>-gravity</strong> option is present with <em>SouthWest, South,</em>
+or <em>SouthEast</em>
+gravity, it specifies the distance upward from the bottom edge of the
+image to the bottom row to remove.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-chop</strong> option removes entire rows and columns,
+and moves the remaining corner blocks leftward and upward to close the gaps.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-clip"></a>-clip
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply the clipping path, if one is present</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If a clipping path is present, it will be applied to subsequent operations.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, if you type the following command:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -clip -negate cockatoo.tif negated.tif
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+only the pixels within the clipping path are negated.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-clip</strong> feature requires the XML library. If the XML library
+is not present, the option is ignored.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-coalesce"></a>-coalesce
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>merge a sequence of images</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Each image N in the sequence after Image 0 is replaced with the image
+created by flattening images 0 through N.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The set of images
+is terminated by the appearance of any option.
+If the <strong>-coalesce</strong>
+option appears after all of the input images, all images are coalesced.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-colorize"></a>-colorize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colorize the image with the pen color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify the amount of colorization as a percentage. You can apply separate
+colorization values to the red, green, and blue channels of the image with
+a colorization value list delimited with slashes (e.g. 0/0/50).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-colorize</strong> option may be used in conjunction with <strong>-modulate</strong>
+to produce a nice sepia toned image like:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert input.ppm -modulate 115,0,100 \
+ -colorize 7,21,50 output.ppm.
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-colormap"></a>-colormap <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the colormap type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose between <strong>shared</strong> or <strong>private</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option only applies when the default X server visual is <em>PseudoColor</em>
+or <em>GRAYScale</em>. Refer to <strong>-visual</strong> for more details. By default,
+a shared colormap is allocated. The image shares colors with other X clients.
+Some image colors could be approximated, therefore your image may look
+very different than intended. Choose <strong>Private</strong> and the image colors
+appear exactly as they are defined. However, other clients may
+go <em>technicolor</em> when the image colormap is installed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-colors"></a>-colors <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The actual number of colors in the image may be less than your request,
+but never more. Note, this is a color reduction option. Images with less
+unique colors than specified with this option will have any duplicate or
+unused colors removed. The ordering of an existing color palette may be
+altered. When converting an image from color to grayscale, convert the
+image to the gray colorspace before reducing the number of colors since
+doing so is most efficient. Refer to &lt;a
+href="quantize.html"&gt;quantize</a> for more details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Note, options <strong>-dither</strong>, <strong>-colorspace</strong>, and <strong>-treedepth</strong>
+affect the color reduction algorithm.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-colorspace"></a>-colorspace <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are:
+<strong>CineonLog</strong>, <strong>CMYK</strong>, <strong>GRAY</strong>, <strong>HSL</strong>, <strong>HWB</strong>,
+<strong>OHTA</strong>, <strong>RGB</strong>, <strong>Rec601Luma</strong>, <strong>Rec709Luma</strong>,
+<strong>Rec601YCbCr</strong>, <strong>Rec709YCbCr</strong>, <strong>Transparent</strong>, <strong>XYZ</strong>,
+<strong>YCbCr</strong>, <strong>YIQ</strong>, <strong>YPbPr</strong>, or <strong>YUV</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Color reduction, by default, takes place in the RGB color space. Empirical
+evidence suggests that distances in color spaces such as YUV or YIQ correspond
+to perceptual color differences more closely than do distances in RGB space.
+These color spaces may give better results when color reducing an image.
+Refer to <a href="quantize.html">quantize</a> for more details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Two gray colorspaces are supported. The <strong>Rec601Luma</strong> space is
+based on the recommendations for legacy NTSC television (ITU-R
+BT.601-5). The <strong>Rec709Luma</strong> space is based on the
+recommendations for HDTV (Rec. ITU-R BT.709-5) and is suitable for use
+with computer graphics, and for contemporary CRT displays. The
+<strong>GRAY</strong> colorspace currently selects the <strong>Rec601Luma</strong>
+colorspace by default for backwards compatibly reasons. This default
+may be re-considered in the future.
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Two YCbCr colorspaces are supported. The <strong>Rec601YCbCr</strong> space is
+based on the recommendations for legacy NTSC television (ITU-R BT.601-5). The
+<strong>Rec709CbCr</strong> space is based on the recommendations for HDTV (Rec.
+ITU-R BT.709-5) and is suitable for suitable for use with computer
+graphics, and for contemporary CRT displays. The <strong>YCbCr</strong> colorspace
+specification is equivalent to<strong>Rec601YCbCr</strong>.
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>Transparent</strong> color space behaves uniquely in that it preserves
+the matte channel of the image if it exists.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-colors</strong> or <strong>-monochrome</strong> option, or saving to a file
+format which requires color reduction, is required for this option to
+take effect.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-comment"></a>-comment <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to assign a specific comment to the image, when writing
+to an image format that supports comments. You can include the
+image filename, type, width, height, or other image attribute by embedding
+special format characters listed under the <strong>-format</strong> option.
+The comment is not drawn on the image, but is embedded in the image
+datastream via a "Comment" tag or similar mechanism. If you want the
+comment to be visible on the image itself, use the <strong>-draw</strong> option
+instead.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -comment "%m:%f %wx%h"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+produces an image comment of <strong>MIFF:bird.miff 512x480</strong> for an image
+titled <strong>bird.miff</strong> and whose width is 512 and height is 480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the first character of <em>string</em> is <em>@</em>, the image comment
+is read from a file titled by the remaining characters in the string.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the -comment option appears multiple times, only the last comment is
+stored.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In PNG images, the comment is stored in a <strong>tEXt</strong> or <strong>zTXt</strong> chunk
+with the keyword "comment".</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-compose"></a>-compose <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The description of composition uses abstract terminology in order to
+allow the the description to be more clear, while avoiding constant
+values which are specific to a particular build configuration. Each image
+pixel is represented by red, green, and blue levels (which are equal for
+a gray pixel). MaxRGB is the maximum integral value which may be stored
+in the red, green, or blue channels of the image. Each image pixel may
+also optionally (if the image matte channel is enabled) have an
+associated level of opacity (ranging from opaque to transparent), which
+may be used to determine the influence of the pixel color when
+compositing the pixel with another image pixel. If the image matte
+channel is disabled, then all pixels in the image are treated as opaque.
+The color of an <em>opaque</em> pixel is fully visible while the color of a
+<em>transparent</em> pixel color is entirely absent (pixel color is ignored).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By definition, raster images have a rectangular shape. All image rows are
+of equal length, and all image columns have the same number of rows. By
+treating the opacity channel as a visual "mask" the rectangular image may
+be given a "shape" by treating the opacity channel as a cookie-cutter for
+the image. Pixels within the shape are opaque, while pixels outside the
+shape are transparent. Pixels on the boundary of the shape may be between
+opaque and transparent in order to provide antialiasing (visually smooth
+edges). The description of the composition operators use this concept of
+image "shape" in order to make the description of the operators easier to
+understand. While it is convenient to describe the operators in terms of
+"shapes" they are by no means limited to mask-style operations since they
+are based on continuous floating-point mathematics rather than simple
+boolean operations.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, the <em>Over</em> composite operator is used. The following
+composite operators are available:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Over
+ In
+ Out
+ Atop
+ Xor
+ Plus
+ Minus
+ Add
+ Subtract
+ Difference
+ Divide
+ Multiply
+ Bumpmap
+ Copy
+ CopyRed
+ CopyGreen
+ CopyBlue
+ CopyOpacity
+ CopyCyan
+ CopyMagenta
+ CopyYellow
+ CopyBlack
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The behavior of each operator is described below.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>Over</dt>
+<dd>The result will be the union of the two image shapes, with opaque areas
+of <em>change-image</em> obscuring <em>base-image</em> in the region of
+overlap.
+</dd>
+<dt>In</dt>
+<dd>The result is simply <em>change-image</em> cut by the shape of
+<em>base-image</em>. None of the image data of <em>base-image</em> will be in
+the result.
+</dd>
+<dt>Out</dt>
+<dd>The resulting image is <em>change-image</em> with the shape of
+<em>base-image</em> cut out.
+</dd>
+<dt>Atop</dt>
+<dd>The result is the same shape as <em>base-image</em>, with
+<em>change-image</em> obscuring <em>base-image</em> where the image shapes
+overlap. Note this differs from <strong>over</strong> because the portion of
+<em>change-image</em> outside <em>base-image</em>'s shape does not appear in
+the result.
+</dd>
+<dt>Xor</dt>
+<dd>The result is the image data from both <em>change-image</em> and
+<em>base-image</em> that is outside the overlap region. The overlap region
+will be blank.
+</dd>
+<dt>Plus</dt>
+<dd>The result is just the sum of the image data. Output values are cropped
+to MaxRGB (no overflow). This operation is independent of the matte
+channels.
+</dd>
+<dt>Minus</dt>
+<dd>The result of <em>change-image</em> - <em>base-image</em>, with underflow
+cropped to zero. The matte channel is ignored (set to opaque, full
+coverage).
+</dd>
+<dt>Add</dt>
+<dd>The result of <em>change-image</em> + <em>base-image</em>, with overflow
+wrapping around (<em>mod</em> MaxRGB+1).
+</dd>
+<dt>Subtract</dt>
+<dd>The result of <em>change-image</em> - <em>base-image</em>, with underflow
+wrapping around (<em>mod</em> MaxRGB+1). The <strong>add</strong> and <strong>subtract</strong>
+operators can be used to perform reversible transformations.
+</dd>
+<dt>Difference</dt>
+<dd>The result of abs(<em>change-image</em> - <em>base-image</em>). This is
+useful for comparing two very similar images.
+</dd>
+<dt>Divide</dt>
+<dd>The result of <em>change-image</em> / <em>base-image</em>. This is useful
+for improving the readability of text on unevenly illuminated photos (by
+using a gaussian blurred copy of change-image as base-image).
+</dd>
+<dt>Multiply</dt>
+<dd>The result of <em>change-image</em> * <em>base-image</em>. This is useful for
+the creation of drop-shadows.
+</dd>
+<dt>Bumpmap</dt>
+<dd>The result <em>base-image</em> shaded by <em>change-image</em>.
+</dd>
+<dt>Copy</dt>
+<dd>The resulting image is <em>base-image</em> replaced with
+<em>change-image</em>. Here the matte information is ignored.
+</dd>
+<dt>CopyRed</dt>
+<dd>The resulting image is the red channel in <em>base-image</em> replaced with
+the red channel in <em>change-image</em>. The other channels are copied
+untouched.
+</dd>
+<dt>CopyGreen</dt>
+<dd>The resulting image is the green channel in <em>base-image</em> replaced
+with the green channel in <em>change-image</em>. The other channels are
+copied untouched.
+</dd>
+<dt>CopyBlue</dt>
+<dd>The resulting image is the blue channel in <em>base-image</em> replaced
+with the blue channel in <em>change-image</em>. The other channels are
+copied untouched.
+</dd>
+<dt>CopyOpacity</dt>
+<dd>The resulting image is the opacity channel in <em>base-image</em> replaced
+with the opacity channel in <em>change-image</em>. The other channels are
+copied untouched.
+</dd>
+<dt>CopyCyan</dt>
+<dd>The resulting image is the cyan channel in <em>base-image</em> replaced
+with the cyan channel in <em>change-image</em>. The other channels are
+copied untouched. Use of this operator requires that base-image be in
+CMYK(A) colorspace.
+</dd>
+<dt>CopyMagenta</dt>
+<dd>The resulting image is the magenta channel in <em>base-image</em>
+replaced with the magenta channel in <em>change-image</em>. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace.
+</dd>
+<dt>CopyYellow</dt>
+<dd>The resulting image is the yellow channel in <em>base-image</em>
+replaced with the yellow channel in <em>change-image</em>. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace.
+</dd>
+<dt>CopyBlack</dt>
+<dd>The resulting image is the black channel in <em>base-image</em>
+replaced with the black channel in <em>change-image</em>. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace. If change-image is not in CMYK
+space, then the change-image pixel intensities are used.
+</dd>
+</dl>
+</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-compress"></a>-compress <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are: <em>None</em>, <em>BZip</em>, <em>Fax</em>,
+<em>Group4</em>,
+<em>JPEG</em>, <em>Lossless</em>,
+<em>LZW</em>, <em>RLE</em>, <em>Zip</em>, or <em>LZMA</em>.
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <strong>+compress</strong> to store the binary image in an uncompressed format.
+The default is the compression type of the specified image file.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>"Lossless"</em> refers to lossless JPEG, which is only available if
+the JPEG library has been patched to support it. Use of lossless JPEG is
+generally not recommended.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the <strong>-quality</strong> option to set the compression level to be used by
+JPEG, PNG, MIFF, and MPEG encoders. Use the <strong>-sampling-factor</strong>
+option to set the sampling factor to be used by the DPX, JPEG, MPEG, and
+YUV encoders for downsampling the chroma channels.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-contrast"></a>-contrast
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enhance or reduce the image contrast</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option enhances the intensity differences between the lighter and
+darker elements of the image. Use <strong>-contrast</strong> to enhance
+the image
+or <strong>+contrast</strong> to reduce the image contrast.
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For a more pronounced effect you can repeat the option:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert rose: -contrast -contrast rose_c2.png
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-convolve"></a>-convolve <i>&lt;kernel&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>convolve image with the specified convolution kernel</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The kernel is specified as a comma-separated list of floating point
+values, ordered left-to right, starting with the top row. The order of
+the kernel is determined by the square root of the number of entries.
+Presently only square kernels are supported.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-create-directories"></a>-create-directories
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create output directory if required</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option with <strong>-output-directory</strong> if the input paths contain
+subdirectories and it is desired to create similar subdirectories in the
+output directory. Without this option, <strong>mogrify</strong> will fail if the
+required output directory does not exist.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-crop"></a>-crop <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details
+about the geometry specification.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The width and height give the size of the image that remains after cropping,
+and <em>x</em> and <em>y</em> are offsets that give the location of the top left
+corner of the cropped
+image with respect to the original image. To specify the amount to be
+removed, use <strong>-shave</strong> instead.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the <em>x</em> and <em>y</em> offsets are present, a single image is
+generated, consisting of the pixels from the cropping region.
+The offsets specify the location of the upper left corner of
+the cropping region measured downward and rightward with respect to the
+upper left corner of the image.
+If the <strong>-gravity</strong> option is present with <em>NorthEast, East,</em>
+or <em>SouthEast</em>
+gravity, it gives the distance leftward from the right edge
+of the image to the right edge of the cropping region. Similarly, if
+the <strong>-gravity</strong> option is present with <em>SouthWest, South,</em>
+or <em>SouthEast</em>
+gravity, the distance is measured upward between the bottom
+edges.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the <em>x</em> and <em>y</em> offsets are omitted, a set of tiles of the
+specified geometry, covering the entire input image, is generated. The
+rightmost tiles and the bottom tiles are smaller if the
+specified geometry extends beyond the dimensions of the input image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-cycle"></a>-cycle <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image colormap by amount</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>Amount</em> defines the number of positions each colormap entry isshifted.
+</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <tt>events</tt> parameter specifies which events are to be logged. It
+can be either <tt>None</tt>, <tt>All</tt>, or a comma-separated list
+consisting of one or more of the following domains: <tt>Annotate</tt>,
+<tt>Blob</tt>, <tt>Cache</tt>, <tt>Coder</tt>, <tt>Configure</tt>,
+<tt>Deprecate</tt>, <tt>Error</tt>, <tt>Exception</tt>, <tt>Locale</tt>,
+<tt>Render</tt>,<tt>Resource</tt>, <tt>TemporaryFile</tt>,
+<tt>Transform</tt>, <tt>Warning</tt>, <tt>X11</tt>, or <tt>User</tt>.
+For example, to log cache and blob events, use</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -debug "Cache,Blob" rose: rose.png
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The "User" domain is normally empty, but developers can log "User" events
+in their private copy of GraphicsMagick.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the <strong>-log</strong> option to specify the format for debugging output.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+debug</strong> to turn off all logging.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+An alternative to using <strong>-debug</strong> is to use the <strong>MAGICK_DEBUG</strong>
+environment variable. The allowed values for the <strong>MAGICK_DEBUG</strong>
+environment variable are the same as for the <strong>-debug</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-deconstruct"></a>-deconstruct
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>break down an image sequence into constituent parts</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option compares each image with the next in a sequence and
+returns the maximum bounding region of any pixel differences it discovers.
+This method can undo a coalesced sequence returned by the
+<strong>-coalesce</strong> option, and is useful for removing redundant information
+from a GIF or MNG animation.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images
+is terminated by the appearance of any option.
+If the <strong>-deconstruct</strong>
+option appears after all of the input images, all images are deconstructed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-define"></a>-define <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">This option creates one or more definitions for coders and
+decoders to use while reading and writing image data. Definitions
+may be passed to coders and decoders to control options that are
+specific to certain image formats. If <em>value</em> is missing for a
+definition, an empty-valued definition of a flag will be created with
+that name. This is used to control on/off options. Use <tt>+define
+&lt;key&gt;,...</tt> to remove definitions previously created. Use
+<tt>+define "*"</tt> to remove all existing definitions.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The following definitions may be created:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>cineon:colorspace={rgb|cineonlog}</dt>
+<dd>Use the cineon:colorspace option when reading a Cineon file to
+specify the colorspace the Cineon file uses. This overrides the colorspace
+type implied by the DPX header (if any).
+</dd>
+<dt>dpx:bits-per-sample=&lt;value&gt;</dt>
+<dd>If the dpx:bits-per-sample key is defined, GraphicsMagick will write
+DPX images with the specified bits per sample, overriding any existing
+depth value. If this option is not specified, then the value is based on
+the existing image depth value from the original image file. The DPX
+standard supports bits per sample values of 1, 8, 10, 12, and 16. Many
+DPX readers demand a sample size of 10 bits with type A padding (see
+below).
+</dd>
+<dt>dpx:colorspace={rgb|cineonlog}</dt>
+<dd>Use the dpx:colorspace option when reading a DPX file to
+specify the colorspace the DPX file uses. This overrides the colorspace
+type implied by the DPX header (if any).
+</dd>
+<dt>dpx:packing-method={packed|a|b|lsbpad|msbpad}</dt>
+<dd>DPX samples are output within 32-bit words. They may be tightly
+packed end-to-end within the words ("packed"), padded with null bits to
+the right of the sample ("a" or "lsbpad), or padded with null bits to the
+left of the sample ("b" or "msbpad"). This option only has an effect for
+sample sizes of 10 or 12 bits. If samples are not packed, the DPX
+standard recommends type A padding. Many DPX readers demand a sample size
+of 10 bits with type A padding.
+</dd>
+<dt>dpx:pixel-endian={lsb|msb}</dt>
+<dd>Allows the user to specify the endian order of the pixels when
+reading or writing the DPX files. Sometimes this is useful if the file is
+(or must be) written incorrectly so that the file header and the pixels
+use different endianness.
+</dd>
+<dt>dpx:swap-samples={true|false}</dt>
+<dd>GraphicsMagick strives to adhere to the DPX standard but certain
+aspects of the standard can be quite confusing. As a result, some 10-bit
+DPX files have Red and Blue interchanged, or Cb and Cr interchanged due
+to an different interpretation of the standard, or getting the wires
+crossed. The swap-samples option may be supplied when reading or writing
+in order to read or write using the necessary sample order.
+</dd>
+<dt>jp2:rate=&lt;value&gt;</dt>
+<dd>Specify the compression factor to use while writing JPEG-2000
+files. The compression factor is the reciprocal of the compression
+ratio. The valid range is 0.0 to 1.0, with 1.0 indicating lossless
+compression. If defined, this value overrides the -quality
+setting. The default quality setting of 75 results in a rate value of
+0.06641.
+</dd>
+<dt>jpeg:block-smoothing={true|false}</dt>
+<dd>Enables or disables block smoothing when reading a JPEG file
+(default enabled).
+</dd>
+<dt>jpeg:dct-method=&lt;value&gt;</dt>
+<dd>Selects the IJG JPEG library DCT implementation to use. The
+encoding implementations vary in speed and encoding error. The
+available choices for <strong>value</strong> are <strong>islow</strong>, <strong>ifast</strong>,
+<strong>float</strong>, <strong>default</strong> and <strong>fastest</strong>. Note that
+<strong>fastest</strong> might not necessarily be fastest on your CPU, depending
+on the choices made when the JPEG library was built and how your CPU
+behaves.
+</dd>
+<dt>jpeg:fancy-upsampling={true|false}</dt>
+<dd>Enables or disables fancy upsampling when reading a JPEG file
+(default enabled).
+</dd>
+<dt>jpeg:optimize-coding={true|false}</dt>
+<dd>
+Selects if huffman encoding should be used. Huffman encoding is enabled
+by default, but may be disabled for very large images since it encoding
+requires that the entire image be buffered in memory. Huffman encoding
+produces smaller JPEG files at the expense of added compression time and
+memory consumption.
+</dd>
+<dt>jpeg:preserve-settings</dt>
+<dd>If the jpeg:preserve-settings flag is defined, the JPEG encoder will
+use the same "quality" and "sampling-factor" settings that were found
+in the input file, if the input was in JPEG format. These settings are
+also preserved if the input is a JPEG file and the output is a JNG
+file. If the colorspace of the output file differs from that of the
+input file, the quality setting is preserved but the sampling-factors
+are not.
+</dd>
+<dt>pcl:fit-to-page</dt>
+<dd>If the pcl:fit-to-page flag is defined, then the printer is
+requested to scale the image to fit the page size (width and/or
+height).</dd>
+<dt>pdf:use-cropbox={true|false}</dt>
+<dd>If the pdf:use-cropbox flag is set to <strong>true</strong>, then
+Ghostscript is requested to apply the PDF crop box.
+</dd>
+<dt>pdf:stop-on-error={true|false}</dt>
+<dd>If the pdf:stop-on-error flag is set to <strong>true</strong>, then
+Ghostscript is requested to stop processing the PDF when the first
+error is encountered. Otherwise it will attempt to process all
+requested pages.
+</dd>
+<dt>ps:imagemask</dt>
+<dd>If the ps:imagemask flag is defined, the PS3 and EPS3 coders will
+create Postscript files that render bilevel images with the Postscript
+imagemask operator instead of the image operator.
+</dd>
+<dt>tiff:alpha={unspecified|associated|unassociated}</dt>
+<dd>Specify the TIFF alpha channel type when reading or writing TIFF files,
+overriding the normal value. The default alpha channel type for new files
+is unspecified alpha. Existing alpha settings are preserved when
+converting from one TIFF file to another. When a TIFF file uses
+associated alpha, the image pixels are pre-multiplied (i.e. altered) with
+the alpha channel. Files with "associated" alpha appear as if they were
+alpha composited on a black background when the matte channel is
+disabled. If the unassociated alpha type is selected, then the alpha
+channel is saved without altering the pixels. Photoshop recognizes
+associated alpha as transparency information, if the file is saved with
+unassociated alpha, the alpha information is loaded as an independent
+channel. Note that for many years, ImageMagick and GraphicsMagick marked
+TIFF files as using associated alpha, without properly pre-multiplying
+the pixels.
+</dd>
+<dt>tiff:fill-order={msb2lsb|lsb2msb}</dt>
+<dd>If the tiff:fill-order key is defined, GraphicsMagick will use it to
+determine the bit fill order used while writing TIFF files. The normal default
+is "msb2lsb", which matches the native bit order of all modern CPUs. The
+only exception to this is when Group3 or Group4 FAX compression is
+requested since FAX machines send data in bit-reversed order and
+therefore RFC 2301 recommends using reverse order.
+</dd>
+<dt>tiff:group-three-options=&lt;value&gt;</dt>
+<dd>If the tiff:group-three-options key is defined, GraphicsMagick
+will use it to set the group3 options tag when writing
+group3-compressed TIFF. Please see the TIFF specification for the
+usage of this tag. The default value is 4.
+</dd>
+<dt>tiff:ignore-tags=&lt;tags&gt;</dt>
+<dd>If the tiff:ignore-tags key is defined, then it is used as a list
+of comma-delimited integer TIFF tag values to ignore while reading the
+TIFF file. This is useful in order to be able to read files which
+which otherwise fail to read due to problems with TIFF tags. Note
+that some TIFF tags are required in order to be able to read the image
+data at all.
+</dd>
+<dt>tiff:report-warnings={false|true}</dt>
+<dd>If the tiff:report-warnings key is defined and set to <strong>true</strong>,
+then TIFF warnings are reported as a warning exception rather than as
+a coder log message. Such warnings are reported after the image has
+been read or written. Most TIFF warnings are benign but sometimes
+they may help deduce problems with the TIFF file, or help detect that
+the TIFF file requires a special application to read successfully due
+to the use of proprietary or specialized extensions.
+</dd>
+<dt>tiff:sample-format={unsigned|ieeefp}</dt>
+<dd>If the tiff:sample-format key is defined, GraphicsMagick will use it to
+determine the sample format used while writing TIFF files. The default is
+"unsigned". Specify "ieeefp" in order to write floating-point TIFF
+files with float (32-bit) or double (64-bit) values. Use the
+tiff:bits-per-sample define to determine the type of floating-point value
+to use.
+</dd>
+<dt>tiff:max-sample-value=&lt;value&gt;</dt>
+<dd>If the tiff:max-sample-value key is defined, GraphicsMagick will use the
+assigned value as the maximum floating point value while reading or
+writing IEEE floating point TIFFs. Otherwise the maximum value is 1.0 or
+the value obtained from the file's SMaxSampleValue tag (if present). The
+floating point data is currently not scanned in advance to determine a
+best maximum sample value so if the range is not 1.0, or the
+SMaxSampleValue tag is not present, it may be necessary to
+(intelligently) use this parameter to properly read a file.
+</dd>
+<dt>tiff:min-sample-value=&lt;value&gt;</dt>
+<dd>If the tiff:min-sample-value key is defined, GraphicsMagick will use
+the assigned value as the minimum floating point value while reading or
+writing IEEE floating point TIFFs. Otherwise the minimum value is 0.0 or
+the value obtained from the file's SMinSampleValue tag (if present).
+</dd>
+<dt>tiff:bits-per-sample=&lt;value&gt;</dt>
+<dd>If the tiff:bits-per-sample key is defined, GraphicsMagick will write
+images with the specified bits per sample, overriding any existing depth
+value. Value may be any in the range of 1 to 32, or 64 when the default
+'unsigned' format is written, or 16/32/24/64 if IEEEFP format is written.
+Please note that the baseline TIFF 6.0 specification only requires
+readers to handle certain powers of two, and the values to be handled
+depend on the nature of the image (e.g. colormapped, grayscale, RGB, CMYK).
+</dd>
+<dt>tiff:samples-per-pixel=&lt;value&gt;</dt>
+<dd>If the tiff:samples-per-pixel key is defined to a value, the TIFF coder
+will write TIFF images with the defined samples per pixel, overriding any
+value stored in the image. This option should not normally be used.
+</dd>
+<dt>tiff:rows-per-strip=&lt;value&gt;</dt>
+<dd>Allows the user to specify the number of rows per TIFF strip.
+Rounded up to a multiple of 16 when using JPEG compression. Ignored when
+using tiles.
+</dd>
+<dt>tiff:strip-per-page=true</dt>
+<dd>Requests that the image is written in a single TIFF strip. This is
+normally the default when group3 or group4 compression is requested
+within reasonable limits. Requesting a single strip for large images may
+result in failure due to resource consumption in the writer or reader.
+</dd>
+<dt>tiff:tile</dt>
+<dd>Enable writing tiled TIFF (rather than stripped) using the default tile
+size. Tiled TIFF organizes the image as an array of smaller images
+(tiles) in order to enable random access.
+</dd>
+<dt>tiff:tile-geometry=&lt;width&gt;x&lt;height&gt;</dt>
+<dd>Specify the tile size to use while writing tiled TIFF. Width and
+height should be a multiple of 16. If the value is not a multiple of 16,
+then it will be rounded down. Enables tiled TIFF if it has not already
+been enabled. GraphicsMagick does not use tiled storage internally so
+tiles need to be converted back and forth from the internal
+scanline-oriented storage to tile-oriented storage. Testing with typical
+RGB images shows that useful square tile size values range from 128x128
+to 1024x1024. Large images which require using a disk-based pixel cache
+benefit from large tile sizes while images which fit in memory work well
+with smaller tile sizes.
+</dd>
+<dt>tiff:tile-width=&lt;width&gt;</dt>
+<dd>Specify the tile width to use while writing tiled TIFF. The tile height
+is then defaulted to an appropriate size. Width should be a multiple of
+16. If the value is not a multiple of 16, then it will be rounded down.
+Enables tiled TIFF if it has not already been enabled.
+</dd>
+<dt>tiff:tile-height=&lt;height&gt;</dt>
+<dd>Specify the tile height to use while writing tiled TIFF. The tile width
+is then defaulted to an appropriate size. Height should be a multiple of
+16. If the value is not a multiple of 16, then it will be rounded down.
+Enables tiled TIFF if it has not already been enabled.
+</dd>
+<dt>webp:lossless={true|false}</dt>
+<dd>Enable lossless encoding.
+</dd>
+<dt>webp:method={0-6}</dt>
+<dd>Quality/speed trade-off.
+</dd>
+<dt>webp:image-hint={default,graph,photo,picture}</dt>
+<dd>Hint for image type.
+</dd>
+<dt>webp:target-size=&lt;integer&gt;</dt>
+<dd>Target size in bytes.
+</dd>
+<dt>webp:target-psnr=&lt;float&gt;</dt>
+<dd>Minimal distortion to try to achieve.
+</dd>
+<dt>webp:segments={1-4}</dt>
+<dd>Maximum number of segments to use.
+</dd>
+<dt>webp:sns-strength={0-100}</dt>
+<dd>Spatial Noise Shaping.
+</dd>
+<dt>webp:filter-strength={0-100}</dt>
+<dd>Filter strength.
+</dd>
+<dt>webp:filter-sharpness={0-7}</dt>
+<dd>Filter sharpness.
+</dd>
+<dt>webp:filter-type={0,1}</dt>
+<dd>Filtering type. 0 = simple, 1 = strong (only used if
+filter-strength &gt; 0 or autofilter is enabled).
+</dd>
+<dt>webp:auto-filter={true|false}</dt>
+<dd>Auto adjust filter's strength.
+</dd>
+<dt>webp:alpha-compression=&lt;integer&gt;</dt>
+<dd>Algorithm for encoding the alpha plane (0 = none, 1 = compressed
+with WebP lossless). Default is 1.
+</dd>
+<dt>webp:alpha-filtering=&lt;integer&gt;</dt>
+<dd>Predictive filtering method for alpha plane. 0: none, 1: fast, 2:
+best. Default is 1.
+</dd>
+<dt>webp:alpha-quality={0-100}</dt>
+<dd>Between 0 (smallest size) and 100 (lossless). Default is 100.
+</dd>
+<dt>webp:pass=[1..10]</dt>
+<dd>Number of entropy-analysis passes.
+</dd>
+<dt>webp:show-compressed={true|false}</dt>
+<dd>Export the compressed picture back. In-loop filtering is not
+applied.
+</dd>
+<dt>webp:preprocessing=[0,1,2]</dt>
+<dd>0=none, 1=segment-smooth, 2=pseudo-random dithering
+</dd>
+<dt>webp:partitions=[0-3]</dt>
+<dd>log2(number of token partitions) in [0..3]. Default is 0 for
+easier progressive decoding.
+</dd>
+<dt>webp:partition-limit={0-100}</dt>
+<dd>Quality degradation allowed to fit the 512k limit on prediction
+modes coding (0: no degradation, 100: maximum possible
+degradation).
+</dd>
+<dt>webp:emulate-jpeg-size={true|false}</dt>
+<dd>If true, compression parameters will be remapped to better match
+the expected output size from JPEG compression. Generally, the output
+size will be similar but the degradation will be lower.
+</dd>
+<dt>webp:thread-level=&lt;integer&gt;</dt>
+<dd>If non-zero, try and use multi-threaded encoding.
+</dd>
+<dt>webp:low-memory={true|false}</dt>
+<dd>If set, reduce memory usage (but increase CPU use)
+</dd>
+</dl>
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, to create a postscript file that will render only the black
+pixels of a bilevel image, use:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert bilevel.tif -define ps:imagemask eps3:stencil.ps
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-delay"></a>-delay <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is useful for regulating the animation of image sequences
+<em>Delay/100</em> seconds must expire before the display
+of the next image. The default is no delay between each showing of the
+image sequence. The maximum delay is 65535.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can specify a delay range (e.g. <em>-delay 10-500</em>) which sets the
+minimum and maximum delay.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-density"></a>-density <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">This option specifies the image resolution to store while encoding a
+raster image or the canvas resolution while rendering (reading) vector
+formats such as Postscript, PDF, WMF, and SVG into a raster image. Image
+resolution provides the unit of measure to apply when rendering to an
+output device or raster image. The default unit of measure is in dots
+per inch (DPI). The <strong>-units</strong> option may be used to select dots per
+centimeter instead.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"> The default resolution is 72 dots per inch, which is equivalent to
+one point per pixel (Macintosh and Postscript standard). Computer
+screens are normally 72 or 96 dots per inch while printers typically
+support 150, 300, 600, or 1200 dots per inch. To determine the
+resolution of your display, use a ruler to measure the width of your
+screen in inches, and divide by the number of horizontal pixels (1024 on
+a 1024x768 display).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">If the file format supports it, this option may be used to update
+the stored image resolution. Note that Photoshop stores and obtains
+image resolution from a proprietary embedded profile. If this profile is
+not stripped from the image, then Photoshop will continue to treat the
+image using its former resolution, ignoring the image resolution
+specified in the standard file header.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">The density option is an attribute and does not alter the underlying
+raster image. It may be used to adjust the rendered size for desktop
+publishing purposes by adjusting the scale applied to the pixels. To
+resize the image so that it is the same size at a different resolution,
+use the <strong>-resample</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-depth"></a>-depth <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This is the number of bits of color to preserve in the image. Any value
+between 1 and <strong>QuantumDepth</strong> (build option) may be specified,
+although 8 or 16 are the most common values. Use this option to specify
+the depth of raw images whose depth is unknown such as GRAY, RGB, or
+CMYK, or to change the depth of any image after it has been read.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">The depth option is applied to the pixels immediately so it may be
+used as a form of simple compression by discarding the least significant
+bits. Reducing the depth in advance may speed up color quantization, and
+help create smaller file sizes when using a compression algorithm like
+LZW or ZIP.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -descend
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>obtain image by descending window hierarchy</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -despeckle
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>reduce the speckles within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-displace"></a>-displace <i>&lt;horizontal scale&gt;x&lt;vertical scale&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shift image pixels as defined by a displacement map</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+With this option, <em>composite image</em> is used as a displacement map. Black,
+within the displacement map, is a maximum positive displacement. White is a
+maximum negative displacement and middle gray is neutral. The displacement
+is scaled to determine the pixel shift. By default, the displacement applies
+in both the horizontal and vertical directions. However, if you specify
+<em>mask</em>, <em>composite image</em> is the horizontal X displacement and
+<em>mask</em> the vertical Y displacement.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-display"></a>-display <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is used with convert for
+obtaining image or font from this X server. See <em>X(1)</em>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-dispose"></a>-dispose <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The Disposal Method indicates the way in which the graphic is to
+be treated after being displayed.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Here are the valid methods:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Undefined No disposal specified.
+ None Do not dispose between frames.
+ Background Overwrite the image area with
+ the background color.
+ Previous Overwrite the image area with
+ what was there prior to rendering
+ the image.
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-dissolve"></a>-dissolve <i>&lt;percent&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>dissolve an image into another by the given percent</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The opacity of the composite image is multiplied by the given percent,
+then it is composited over the main image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-dither"></a>-dither
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The basic strategy of dithering is to trade intensity resolution for spatial
+resolution by averaging the intensities of several neighboring pixels.
+Images which suffer from severe contouring when reducing colors can be
+improved with this option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-colors</strong> or <strong>-monochrome</strong> option is required for this option
+to take effect.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+dither</strong> to turn off dithering and to render PostScript
+without text or graphic aliasing. Disabling dithering often (but not
+always) leads to decreased processing time.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-draw"></a>-draw <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with one or more graphic primitives</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to annotate an image with one or more graphic primitives.
+The primitives include shapes, text, transformations,
+and pixel operations. The shape primitives are</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ point x,y
+ line x0,y0 x1,y1
+ rectangle x0,y0 x1,y1
+ roundRectangle x0,y0 x1,y1 wc,hc
+ arc x0,y0 x1,y1 a0,a1
+ ellipse x0,y0 rx,ry a0,a1
+ circle x0,y0 x1,y1
+ polyline x0,y0 ... xn,yn
+ polygon x0,y0 ... xn,yn
+ Bezier x0,y0 ... xn,yn
+ path path specification
+ image operator x0,y0 w,h filename
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The text primitive is</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ text x0,y0 string
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The text gravity primitive is</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gravity NorthWest, North, NorthEast, West, Center,
+ East, SouthWest, South, or SouthEast
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The text gravity primitive only affects the placement of text and
+does not interact with the other primitives. It is equivalent to
+using the <strong>-gravity</strong> commandline option, except that it is
+limited in scope to the <strong>-draw</strong> option in which it appears.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The transformation primitives are</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ rotate degrees
+ translate dx,dy
+ scale sx,sy
+ skewX degrees
+ skewY degrees
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The pixel operation primitives are</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ color x0,y0 method
+ matte x0,y0 method
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The shape primitives are drawn in the color specified in the preceding
+<strong>-stroke</strong> option. Except for the <strong>line</strong> and <strong>point</strong>
+primitives, they are filled with the color specified in the preceding
+<strong>-fill</strong> option. For unfilled shapes, use <tt>-fill none</tt></font></td></tr></table>.
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Point</strong> requires a single coordinate.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Line</strong> requires a start and end coordinate.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Rectangle</strong>
+expects an upper left and lower right coordinate.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>RoundRectangle</strong> has the upper left and lower right coordinates
+and the width and height of the corners.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Circle</strong> has a center coordinate and a coordinate for
+the outer edge.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>Arc</strong> to inscribe an elliptical arc within
+a rectangle. Arcs require a start and end point as well as the degree
+of rotation (e.g. 130,30 200,100 45,90).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>Ellipse</strong> to draw a partial ellipse
+centered at the given point with the x-axis and y-axis radius
+and start and end of arc in degrees (e.g. 100,100 100,150 0,360).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Finally, <strong>polyline</strong> and <strong>polygon</strong> require
+three or more coordinates to define its boundaries.
+Coordinates are integers separated by an optional comma. For example,
+to define a circle centered at 100,100
+that extends to 150,150 use:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -draw 'circle 100,100 150,150'
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Paths</strong>
+(See <a href="http://www.w3.org/TR/SVG/paths.html">Paths</a>)
+represent an outline of an object which is defined in terms of
+moveto (set a new current point), lineto (draw a straight line),
+curveto (draw a curve using a cubic Bezier), arc (elliptical or
+circular arc) and closepath (close the current shape by drawing a line
+to the last moveto) elements. Compound paths (i.e., a path with
+subpaths, each consisting of a single moveto followed by one or more
+line or curve operations) are possible to allow effects such as
+"donut holes" in objects.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>image</strong> to composite an image with another image. Follow the
+image keyword with the composite operator, image location, image size,
+and filename:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -draw 'image Over 100,100 225,225 image.jpg'
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can use 0,0 for the image size, which means to use the actual
+dimensions found in the image header. Otherwise, it will
+be scaled to the given dimensions.
+See <strong>-compose</strong> for a description of the composite operators.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>text</strong> to annotate an image with text. Follow the text
+coordinates with a string. If the string has embedded spaces, enclose it
+in single or double quotes. Optionally you can include the image
+filename, type, width, height, or other image attribute by embedding
+special format character. See <strong>-comment</strong> for details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -draw 'text 100,100 "%m:%f %wx%h"'
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+annotates the image with <tt>MIFF:bird.miff 512x480</tt> for an image titled
+<tt>bird.miff</tt>
+and whose width is 512 and height is 480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the first character of <em>string</em> is <em>@</em>, the text is read from
+a file titled by the remaining characters in the string.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Rotate</strong> rotates subsequent shape primitives and text primitives about
+the origin of the main image. If the <strong>-region</strong> option precedes the
+<strong>-draw</strong> option, the origin for transformations is the upper left
+corner of the region.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Translate</strong> translates them.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Scale</strong> scales them.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>SkewX</strong> and <strong>SkewY</strong> skew them with respect to the origin of
+the main image or the region.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The transformations modify the current affine matrix, which is initialized
+from the initial affine matrix defined by the <strong>-affine</strong> option.
+Transformations are cumulative within the <strong>-draw</strong> option.
+The initial affine matrix is not affected; that matrix is only changed by the
+appearance of another <strong>-affine</strong> option. If another <strong>-draw</strong>
+option appears, the current affine matrix is reinitialized from
+the initial affine matrix.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>color</strong> to change the color of a pixel to the fill color (see
+<strong>-fill</strong>). Follow the pixel coordinate
+with a method:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ point
+ replace
+ floodfill
+ filltoborder
+ reset
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Consider the target pixel as that specified by your coordinate. The
+<strong>point</strong>
+method recolors the target pixel. The <strong>replace</strong> method recolors any
+pixel that matches the color of the target pixel.
+<strong>Floodfill</strong> recolors
+any pixel that matches the color of the target pixel and is a neighbor,
+whereas <strong>filltoborder</strong> recolors any neighbor pixel that is not the
+border color. Finally, <strong>reset</strong> recolors all pixels.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>matte</strong> to the change the pixel matte value to transparent. Follow
+the pixel coordinate with a method (see the <strong>color</strong> primitive for
+a description of methods). The <strong>point</strong> method changes the matte value
+of the target pixel. The <strong>replace</strong> method changes the matte value
+of any pixel that matches the color of the target pixel. <strong>Floodfill</strong>
+changes the matte value of any pixel that matches the color of the target
+pixel and is a neighbor, whereas
+<strong>filltoborder</strong> changes the matte
+value of any neighbor pixel that is not the border color (<strong>-bordercolor</strong>).
+Finally <strong>reset</strong> changes the matte value of all pixels.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can set the primitive color, font, and font bounding box
+color with
+<strong>-fill</strong>, <strong>-font</strong>, and <strong>-box</strong> respectively. Options
+are processed in command line order so be sure to use these
+options <em>before</em> the <strong>-draw</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -edge <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>detect edges within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -emboss <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>emboss an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-encoding"></a>-encoding <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from <em>AdobeCustom, AdobeExpert, AdobeStandard, AppleRoman,
+BIG5, GB2312, Latin 2, None, SJIScode, Symbol, Unicode, Wansung.</em></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-endian"></a>-endian <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>MSB</em> indicates big-endian (e.g. SPARC, Motorola 68K) while
+<em>LSB</em> indicates little-endian (e.g. Intel 'x86, VAX) byte
+ordering. <em>Native</em> indicates to use the normal ordering for the
+current CPU. This option currently only influences the CMYK, DPX,
+GRAY, RGB, and TIFF, formats.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+endian</strong> to revert to unspecified endianness.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -enhance
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a digital filter to enhance a noisy image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -equalize
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform histogram equalization to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-extent"></a>-extent <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite image on background color canvas image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option composites the image on a new background color
+(<strong>-background</strong>) canvas image of size &lt;width&gt;x&lt;height&gt;. The
+existing image content is composited at the position specified by
+geometry x and y offset and/or desired gravity (<strong>-gravity</strong>) using
+the current image compose (<strong>-compose</strong>) method. Image content
+which falls outside the bounds of the new image dimensions is
+discarded.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, this command creates a thumbnail of an image, and centers
+it on a red color backdrop image, offsetting the canvas ten pixels to
+the left and five pixels up, with respect to the thumbnail:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert infile.jpg -thumbnail 120x80 -background red -gravity center \
+ -extent 140x100-10-5 outfile.jpg
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This command reduces or expands a JPEG image to fit on an 800x600
+display: </font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -size 800x600 input.jpg \
+ -resize 800x600 -background black \
+ -compose Copy -gravity center \
+ -extent 800x600 \
+ -quality 92 output.jpg
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the aspect ratio of the input image isn't exactly 4:3, then the
+image is centered on an 800x600 black canvas. </font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-file"></a>-file <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write annotated difference image to file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If <strong>-file</strong> is specified, then an annotated difference image is
+generated and written to the specified file. Pixels which differ between
+the <strong>reference</strong> and <strong>compare</strong> images are modified from those in
+the <strong>compare</strong> image so that the changed pixels become more obvious.
+Some images may require use of an alternative highlight style (see
+<strong>-highlight-style</strong>) or highlight color (see <strong>-highlight-color</strong>)
+before the changes are obvious.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-fill"></a>-fill <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when filling a graphic primitive</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Colors are represented in GraphicsMagick in the same form used by SVG. Use "gm convert -list color" to list named colors:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ name (named color)
+ #RGB (hex numbers, 4 bits each)
+ #RRGGBB (8 bits each)
+ #RRRGGGBBB (12 bits each)
+ #RRRRGGGGBBBB (16 bits each)
+ #RGBA (4 bits each)
+ #RRGGBBAA (8 bits each)
+ #RRRGGGBBBAAA (12 bits each)
+ #RRRRGGGGBBBBAAAA (16 bits each)
+ rgb(r,g,b) (r,g,b are decimal numbers)
+ rgba(r,g,b,a) (r,g,b,a are decimal numbers)
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Enclose the color specification in quotation marks to prevent the "#"
+or the parentheses from being interpreted by your shell.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -fill blue ...
+ gm convert -fill "#ddddff" ...
+ gm convert -fill "rgb(65000,65000,65535)" ...
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The shorter forms are scaled up, if necessary by replication. For example,
+#3af, #33aaff, and #3333aaaaffff are all equivalent.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-draw</strong> for further details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-filter"></a>-filter <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to affect the resizing operation of an image (see
+<strong>-geometry</strong>).
+Choose from these filters (ordered by approximate increasing CPU
+time):</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Point
+ Box
+ Triangle
+ Hermite
+ Hanning
+ Hamming
+ Blackman
+ Gaussian
+ Quadratic
+ Cubic
+ Catrom
+ Mitchell
+ Lanczos
+ Bessel
+ Sinc
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default filter is automatically selected to provide the best quality
+while consuming a reasonable amount of time. The <strong>Mitchell</strong> filter
+is used if the image supports a palette, supports a matte channel, or is
+being enlarged, otherwise the <strong>Lanczos</strong> filter is used.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-flatten"></a>-flatten
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>flatten a sequence of images</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In some file formats (e.g. Photoshop's PSD) complex images may be
+represented by "layers" (independent images) which must be composited
+in order to obtain the final rendition. The <strong>-flatten</strong> option
+accomplishes this composition. The sequence of images is replaced by
+a single image created by compositing each image in turn, while
+respecting composition operators and page offsets. While
+<strong>-flatten</strong> is immediately useful for eliminating layers, it is
+also useful as a general-purpose composition tool.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images is terminated by the appearance of any option.
+If the <strong>-flatten</strong> option appears after all of the input images,
+all images are flattened. Also see <strong>-mosaic</strong> which is similar to
+<strong>-flatten</strong> except that it adds a suitably-sized canvas base
+image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, this composites an image on top of a 640x400 transparent
+black canvas image:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -size 640x300 xc:transparent \
+ -compose over -page +0-100 \
+ frame.png -flatten output.png
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+and this flattens a Photoshop PSD file:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert input.psd -flatten output.png
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-flip"></a>-flip
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+reflect the scanlines in the vertical direction.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-flop"></a>-flop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+reflect the scanlines in the horizontal direction.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-font"></a>-font <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can tag a font to specify whether it is a PostScript, TrueType, or X11
+font. For example, <tt>Arial.ttf</tt> is a TrueType font, <tt>ps:helvetica</tt>
+is PostScript, and <tt>x:fixed</tt> is X11.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-foreground"></a>-foreground <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the foreground color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-format"></a>-format <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image format type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used with the <strong>mogrify</strong> utility,
+this option will convert any image to the image format you specify.
+See <em>GraphicsMagick(1)</em> for a list of image format types supported by
+<strong>GraphicsMagick</strong>, or see the output of 'gm -list format'.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default the file is written to its original name. However, if the
+filename extension matches a supported format, the extension is replaced
+with the image format type specified with <strong>-format</strong>. For example,
+if you specify <em>tiff</em> as the format type and the input image
+filename is <em>image.gif</em>, the output image filename becomes
+<em>image.tiff</em>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-format"></a>-format <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output formatted image characteristics</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used with the <strong>identify</strong> utility, or the <strong>convert</strong>
+utility with output written to the 'info:-' file specification, use
+this option to print information about the image in a format of your
+choosing. You can include the image filename, type, width, height,
+Exif data, or other image attributes by embedding special format
+characters:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ %b file size
+ %c comment
+ %d directory
+ %e filename extension
+ %f filename
+ %g page dimensions and offsets
+ %h height
+ %i input filename
+ %k number of unique colors
+ %l label
+ %m magick
+ %n number of scenes
+ %o output filename
+ %p page number
+ %q image bit depth
+ %r image type description
+ %s scene number
+ %t top of filename
+ %u unique temporary filename
+ %w width
+ %x horizontal resolution
+ %y vertical resolution
+ %A transparency supported
+ %C compression type
+ %D GIF disposal method
+ %G Original width and height
+ %H page height
+ %M original filename specification
+ %O page offset (x,y)
+ %P page dimensions (width,height)
+ %Q compression quality
+ %T time delay (in centi-seconds)
+ %U resolution units
+ %W page width
+ %X page horizontal offset (x)
+ %Y page vertical offset (y)
+ %@ trim bounding box
+ %# signature
+ \n newline
+ \r carriage return
+ %% %
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -format "%m:%f %wx%h"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+displays <strong>MIFF:bird.miff 512x480</strong> for an image
+titled <strong>bird.miff</strong> and whose width is 512 and height is 480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the first character of <em>string</em> is <strong>@</strong>, the format
+is read from a file titled by the remaining characters in the string.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The values of image type (<strong>%p</strong>) which may be returned include:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Bilevel
+ Grayscale
+ GrayscaleMatte
+ Palette
+ PaletteMatte
+ TrueColor
+ TrueColorMatte
+ ColorSeparation
+ ColorSeparationMatte
+ Optimize
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can also use the following special formatting syntax to print Exif
+information contained in the file:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ %[EXIF:&lt;tag&gt;]
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Where "&lt;tag&gt;" may be one of the following:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ * (print all Exif tags, in keyword=data format)
+ ! (print all Exif tags, in tag_number format)
+ #hhhh (print data for Exif tag #hhhh)
+ ImageWidth
+ ImageLength
+ BitsPerSample
+ Compression
+ PhotometricInterpretation
+ FillOrder
+ DocumentName
+ ImageDescription
+ Make
+ Model
+ StripOffsets
+ Orientation
+ SamplesPerPixel
+ RowsPerStrip
+ StripByteCounts
+ XResolution
+ YResolution
+ PlanarConfiguration
+ ResolutionUnit
+ TransferFunction
+ Software
+ DateTime
+ Artist
+ WhitePoint
+ PrimaryChromaticities
+ TransferRange
+ JPEGProc
+ JPEGInterchangeFormat
+ JPEGInterchangeFormatLength
+ YCbCrCoefficients
+ YCbCrSubSampling
+ YCbCrPositioning
+ ReferenceBlackWhite
+ CFARepeatPatternDim
+ CFAPattern
+ BatteryLevel
+ Copyright
+ ExposureTime
+ FNumber
+ IPTC/NAA
+ ExifOffset
+ InterColorProfile
+ ExposureProgram
+ SpectralSensitivity
+ GPSInfo
+ ISOSpeedRatings
+ OECF
+ ExifVersion
+ DateTimeOriginal
+ DateTimeDigitized
+ ComponentsConfiguration
+ CompressedBitsPerPixel
+ ShutterSpeedValue
+ ApertureValue
+ BrightnessValue
+ ExposureBiasValue
+ MaxApertureValue
+ SubjectDistance
+ MeteringMode
+ LightSource
+ Flash
+ FocalLength
+ MakerNote
+ UserComment
+ SubSecTime
+ SubSecTimeOriginal
+ SubSecTimeDigitized
+ FlashPixVersion
+ ColorSpace
+ ExifImageWidth
+ ExifImageLength
+ InteroperabilityOffset
+ FlashEnergy
+ SpatialFrequencyResponse
+ FocalPlaneXResolution
+ FocalPlaneYResolution
+ FocalPlaneResolutionUnit
+ SubjectLocation
+ ExposureIndex
+ SensingMethod
+ FileSource
+ SceneType
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+JPEG specific information (from reading a JPEG file) may be obtained
+like this:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ %[JPEG-&lt;tag&gt;]
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Where "&lt;tag&gt;" may be one of the following:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ * (all JPEG-related tags, in
+ keyword=data format)
+ Quality IJG JPEG "quality" estimate
+ Colorspace JPEG colorspace numeric ID
+ Colorspace-Name JPEG colorspace name
+ Sampling-factors JPEG sampling factors
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Please note that JPEG has no notion of "quality" and that the quality
+metric used by, and estimated by the software is based on the quality
+metric established by IJG JPEG 6b. Other encoders (e.g. that used by
+Adobe Photoshop) use different encoding metrics.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Surround the format specification with quotation marks to prevent your shell
+from misinterpreting any spaces and square brackets.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-frame"></a>-frame <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details about the geometry
+specification. The <strong>-frame</strong> option is not affected by the
+<strong>-gravity</strong> option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color of the border is specified with the <strong>-mattecolor</strong>
+command line option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -frame
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>include the X window frame in the imported image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-fuzz"></a>-fuzz <i>&lt;distance&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colors within this Euclidean distance are considered equal</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A number of algorithms search for a target color. By default the color
+must be exact. Use this option to match colors that are close (in
+Euclidean distance) to the target color in RGB 3D space. For example,
+if you want to automatically trim the edges of an image with
+<strong>-trim</strong> but the image was scanned and the target background color
+may differ by a small amount. This option can account for these
+differences.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <em>distance</em> can be in absolute intensity units or, by appending
+<em>"%"</em>, as a percentage of the maximum possible intensity (255,
+65535, or 4294967295).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-gamma"></a>-gamma <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The same color image displayed on two different workstations may look
+different due to differences in the display monitor. Use gamma
+correction to adjust for this color difference. Reasonable values extend
+from <strong>0.8</strong> to <strong>2.3</strong>. Gamma less than 1.0 darkens the image and
+gamma greater than 1.0 lightens it. Large adjustments to image gamma may
+result in the loss of some image information if the pixel quantum size
+is only eight bits (quantum range 0 to 255).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can apply separate gamma values to the red, green, and blue channels
+of the image with a gamma value list delimited with slashes
+(e.g., <strong>1.7</strong>/<strong>2.3</strong>/<strong>1.2</strong>).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+gamma</strong> <em>value</em>
+to set the image gamma level without actually adjusting
+the image pixels. This option is useful if the image is of a known gamma
+but not set as an image attribute (e.g. PNG images).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-gaussian"></a>-gaussian <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the given radius and standard deviation (sigma).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-geometry"></a>-geometry <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-geometry</strong> option is used for a number of different
+purposes, depending on the utility it is used with.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the X11 commands ('animate', 'display', and 'import'), it
+specifies the preferred size and location of the Image window. By
+default, the window size is the image size and the location is chosen
+by you (or your window manager) when it is mapped.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"> For the 'import', 'convert', 'mogrify' utility commands it may be
+used to specify the desired size when resizing an image. In this
+case, symbols representing resize options may be appended to the
+geometry string to influence how the resize request is treated.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See later notes corresponding to usage by particular commands. The
+following notes apply to when <strong>-geometry</strong> is used to express a
+resize request, taking into account the current properties of the
+image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, the width and height are maximum values. That is, the
+image is expanded or contracted to fit the width and height value
+while maintaining the aspect ratio of the image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Append a ^ to the geometry so that the image aspect ratio is
+maintained when the image is resized, but the resulting width or
+height are treated as minimum values rather than maximum values.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Append a ! (exclamation point) to the geometry to force the image size to
+exactly the size you specify. For example, if you specify
+<tt>640x480!</tt> the image width is set to 640 pixels and height to
+480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If only the width is specified, without the trailing 'x', then height
+is set to width (e.g., <tt>-geometry 100</tt> is the same as
+<tt>-geometry 100x100</tt>). If only the width is specified but with
+the trailing 'x', then width assumes the value and the height is
+chosen to maintain the aspect ratio of the image. Similarly, if only
+the height is specified prefixed by 'x' (e.g., <tt>-geometry
+x256</tt>), the width is chosen to maintain the aspect ratio.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+To specify a percentage width or height instead, append %. The image size
+is multiplied by the width and height percentages to obtain the final image
+dimensions. To increase the size of an image, use a value greater than
+100 (e.g. 125%). To decrease an image's size, use a percentage less than
+100.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <tt>@</tt> to specify the maximum area in pixels of an image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <tt>&gt;</tt> to change the dimensions of the image <em>only</em> if
+its width or height exceeds the geometry specification. <tt>&lt;</tt> resizes
+the image <em>only</em> if both of its dimensions are less than the geometry
+specification. For example,
+if you specify <tt>'640x480&gt;'</tt> and the image size is 256x256, the image
+size does not change. However, if the image is 512x512 or 1024x1024, it is
+resized to 480x480. Enclose the geometry specification in quotation marks to
+prevent the <tt>&lt;</tt> or <tt>&gt;</tt> from being interpreted by your shell
+as a file redirection.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used with <em>animate</em> and <em>display</em>, offsets are handled in
+the same manner as in <em>X(1)</em> and the <strong>-gravity</strong> option is not used.
+If the <em>x</em> is negative, the offset is measured leftward
+from the right edge of the
+screen to the right edge of the image being displayed.
+Similarly, negative <em>y</em> is measured between the bottom edges. The
+offsets are not affected by "%"; they are always measured in pixels.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>composite</em> option, <strong>-geometry</strong>
+gives the dimensions of the image and its location with respect
+to the composite image. If the <strong>-gravity</strong> option is present
+with <em>NorthEast, East,</em> or <em>SouthEast</em> gravity, the <em>x</em>
+represents the distance from the right edge of the image to the right edge of
+the composite image. Similarly, if the <strong>-gravity</strong> option is present
+with <em>SouthWest, South,</em> or <em>SouthEast</em> gravity, <em>y</em>
+is measured between the bottom edges. Accordingly, a positive offset will
+never point in the direction outside of the image. The
+offsets are not affected by "%"; they are always measured in pixels.
+To specify the dimensions of the composite image, use the <strong>-resize</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>convert</em>, <em>import</em> or <em>mogrify</em> option,
+<strong>-geometry</strong> is synonymous with <strong>-resize</strong> and
+specifies the size of the output image. The offsets, if present, are ignored.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>montage</em> option, <strong>-geometry</strong> specifies the image
+size and border size for each tile; default is 256x256+0+0. Negative
+offsets (border dimensions) are meaningless. The <strong>-gravity</strong>
+option affects the placement of the image within the tile; the default
+gravity for this purpose is <em>Center</em>. If the "%" sign appears in
+the geometry specification, the tile size is the specified percentage of
+the original dimensions of the first tile.
+To specify the dimensions of the montage, use the <strong>-resize</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-gravity"></a>-gravity <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are: NorthWest, North,
+NorthEast, West, Center, East, SouthWest, South, SouthEast.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The direction you choose specifies where to position the text
+when annotating
+the image. For example <em>Center</em> gravity forces the text to be centered
+within the image. By default, the image gravity is <em>NorthWest</em>.
+See <strong>-draw</strong> for more details about graphic primitives. Only the
+text primitive is affected by the <strong>-gravity</strong> option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-gravity</strong> option is also used in concert with the <strong>-geometry</strong>
+option and other options that take <strong>&lt;geometry&gt;</strong> as a parameter, such
+as the <strong>-crop</strong> option. See <strong>-geometry</strong> for details of how the
+<strong>-gravity</strong> option interacts with the
+<strong>&lt;x&gt;</strong> and <strong>&lt;y&gt;</strong> parameters of a geometry
+specification.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as an option to <em>composite</em>, <strong>-gravity</strong>
+gives the direction that the image gravitates within the composite.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as an option to <em>montage</em>, <strong>-gravity</strong> gives the direction
+that an image gravitates within a tile. The default gravity is <em>Center</em>
+for this purpose.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-green-primary"></a>-green-primary <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -hald-clut <i>&lt;clut&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a Hald CLUT to the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A Hald CLUT ("Color Look-Up Table") is a special square color image
+which contains a look-up table for red, green, and blue. The size of
+the Hald CLUT image is determined by its order. The width (and
+height) of a Hald CLUT is the cube of the order. For example, a Hald
+CLUT of order 8 is 512x512 pixels (262,144 colors) and of order 16 is
+4096x4096 (16,777,216 colors). A special CLUT is the identity CLUT
+which which causes no change to the input image. In order to use the
+Hald CLUT, one takes an identity CLUT and adjusts its colors in some
+way. The modified CLUT can then be used to transform any number of
+images in an identical way.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+GraphicsMagick contains a built-in identity CLUT generator via the
+<strong>IDENTITY</strong> coder. For example reading from the file name
+</strong>IDENTITY:8</strong> returns an identity CLUT of order 8. Typical Hald
+CLUT identity images have an order of between 8 and 16. The default
+order for the <strong>IDENTITY</strong> CLUT generator is 8. Interpolation is
+used so it is not usually necessary for CLUT images to be very large.
+The PNG file format is ideal for storing Hald CLUT images because it
+compresses them very well.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-highlight-color"></a>-highlight-color <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixel annotation color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specifies the color to use when annotating difference pixels.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-highlight-style"></a>-highlight-style <i>&lt;style&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixel annotation style</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specifies the pixel difference annotation style used to draw attention to
+changed pixels. May be one of <strong>Assign</strong>, <strong>Threshold</strong>,
+<strong>Tint</strong>, or <strong>XOR</strong>; where <strong>Assign</strong> replaces the pixel with
+the highlight color (see <strong>-highlight-color</strong>), <strong>Threshold</strong>
+replaces the pixel with black or white based on the difference in
+intensity, <strong>Tint</strong> alpha tints the pixel with the highlight color,
+and <strong>XOR</strong> does an XOR between the pixel and the highlight color.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-iconGeometry"></a>-iconGeometry <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the icon geometry</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Offsets, if present in the geometry specification, are handled in
+the same manner as the <strong>-geometry</strong> option, using X11 style to handle
+negative offsets.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -iconic
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>iconic animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -immutable
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image immutable</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -implode <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>implode image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-intent"></a>-intent <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of rendering intent when managing the image color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to affect the the color management operation of an image (see
+<strong>-profile</strong>).
+Choose from these intents:
+<strong>Absolute, Perceptual, Relative, Saturation</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default intent is undefined.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-interlace"></a>-interlace <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are: <strong>None, Line, Plane,</strong>
+or <strong>Partition</strong>. The default is <strong>None</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is used to specify the type of interlacing scheme for raw image
+formats such as <strong>RGB</strong> or <strong>YUV</strong>.</font></td></tr></table><table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>None</strong> means do not interlace
+(RGBRGBRGBRGBRGBRGB...),</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Line</strong> uses scanline interlacing
+(RRR...GGG...BBB...RRR...GGG...BBB...),
+and</font></td></tr></table><table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Plane</strong> uses plane interlacing (RRRRRR...GGGGGG...BBBBBB...).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Partition</strong>
+is like plane except the different planes are saved to individual files
+(e.g. image.R, image.G, and image.B).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>Line</strong> to create an <strong>interlaced PNG</strong> or <strong> GIF</strong> or
+<strong>progressive JPEG</strong> image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-label"></a>-label <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to assign a specific label to the image, when writing
+to an image format that supports labels, such as TIFF, PNG, MIFF, or
+PostScript. You can include the the image filename, type, width, height,
+or other image attribute by embedding special format character. A label
+is not drawn on the image, but is embedded in the image datastream via
+a "Label" tag or similar mechanism. If you want the
+label to be visible on the image itself, use the <strong>-draw</strong> option.
+See <strong>-comment</strong> for details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -label "%m:%f %wx%h"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+produces an image label of <strong>MIFF:bird.miff 512x480</strong> for an image titled
+<strong>bird.miff</strong>
+and whose width is 512 and height is 480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the first character of <em>string</em> is <em>@</em>, the image label is
+read from a file titled by the remaining characters in the string.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the -label option appears multiple times, only the last label is
+stored.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In PNG images, the label is stored in a <strong>tEXt</strong> or <strong>zTXt</strong> chunk
+with the keyword "label".</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When converting to <em>PostScript</em>, use this option to specify a header
+string to print above the image. Specify the label font with
+<strong>-font</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When creating a montage, by default the label associated with an image
+is displayed with the corresponding tile in the montage. Use the
+<strong>+label</strong> option to suppress this behavior.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-lat"></a>-lat <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;offset&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform local adaptive thresholding</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Perform local adaptive thresholding using the specified width, height,
+and offset. The offset is a distance in sample space from the mean,
+as an absolute integer ranging from 0 to the maximum sample value or
+as a percentage. If the percent option is supplied, then the offset
+is computed as a percentage of the quantum range. It is strongly
+recommended to use the percent option so that results are not
+sensitive to pixel quantum depth.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -colorspace gray -lat "10x10-5%"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+will help clarify a scanned grayscale or color document, producing a
+bi-level equivalent.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-level"></a>-level <i>&lt;black_point&gt;</i>{<i>,&lt;gamma&gt;</i>}<i></i>{<i>,&lt;white_point&gt;</i>}<i></i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>adjust the level of image contrast</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Give one, two or three values delimited with commas: black-point, gamma,
+white-point (e.g. 10,1.0,250 or 2%,0.5,98%). The black and white
+points range from 0 to MaxRGB or from 0 to 100%; if the white point is
+omitted it is set to MaxRGB-black_point. If a "%" sign is present
+anywhere in the string, the black and white points are percentages of
+MaxRGB. Gamma is an exponent that ranges from 0.1 to 10.; if it is
+omitted, the default of 1.0 (no gamma correction) is assumed. This
+interface works similar to Photoshop's "Image-&gt;Adjustments-&gt;Levels..."
+"Input Levels" interface.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-limit"></a>-limit <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, resource limits are estimated based on the available
+resources of the system. The resource limits are <strong>Disk</strong>, maximum
+total disk space consumed; <strong>File</strong>, maximum number of file
+descriptors allowed to be open at once; <strong>Map</strong>, maximum total
+number of file bytes which may be memory mapped; <strong>Memory</strong>,
+maximum total number of bytes of heap memory used for image storage;
+<strong>Pixels</strong>, maximum absolute image size (per image); <strong>Width</strong>,
+maximum image pixels width; <strong>Height</strong>, maximum image pixels
+height; and <strong>Threads</strong>, the maximum number of worker threads to
+use per OpenMP thread team.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+These resource limits are used to decide if (for a given image) the
+decoded image ("pixel cache") should be stored in heap memory (RAM),
+in a memory-mapped disk file, or in a disk file accessed via
+read/write I/O. The number of total pixels in one image, and/or the
+width/height, may also be limited in order to force the reading, or
+creation of images larger than the limit (in pixels) to intentionally
+fail. The disk limit establishes an overall limit since using the disk
+is the means of last resort. When the disk limit has been reached, no
+more images may be read.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The value argument is an absolute value, but may have standard binary
+suffix characters applied ('K', 'M', 'G', 'T', 'P', 'E') to apply a
+scaling to the value (based on a multiplier of 1024). Any additional
+characters are ignored. For example, <tt>'-limit Pixels 10MP'</tt> limits
+the maximum image size to 10 megapixels and <tt>'-limit memory 32MB
+-limit map 64MB'</tt> limits memory and memory mapped files to 32
+megabytes and 64 megabytes respectively.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Resource limits may also be set using environment variables. The
+environment variables <strong>MAGICK_LIMIT_DISK</strong>,
+<strong>MAGICK_LIMIT_FILES</strong>, <strong>MAGICK_LIMIT_MAP</strong>,
+<strong>MAGICK_LIMIT_MEMORY</strong>, <strong>MAGICK_LIMIT_PIXELS</strong>,
+<strong>MAGICK_LIMIT_WIDTH</strong>, <strong>MAGICK_LIMIT_HEIGHT</strong>,and
+<strong>OMP_NUM_THREADS</strong> may be used to set the limits for disk space,
+open files, memory mapped size, heap memory, per-image pixels, image
+width, image height, and threads respectively.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the option <tt>-list resource</tt> list the current limits.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -linewidth
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the line width for subsequent draw operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-list"></a>-list <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of list</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are: <strong>Color</strong>, <strong>Delegate</strong>, <strong>Format</strong>, <strong>Magic</strong>,
+<strong>Module</strong>, <strong>Resource</strong>, or <strong>Type</strong>. The <strong>Module</strong> option
+is only available if GraphicsMagick was built to support loadable modules.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option lists information about the GraphicsMagick configuration.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-log"></a>-log <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option specifies the format for the log printed when the <strong>-debug</strong>
+option is active.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can display the following components by embedding
+special format characters:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ %d domain
+ %e event
+ %f function
+ %l line
+ %m module
+ %p process ID
+ %r real CPU time
+ %t wall clock time
+ %u user CPU time
+ %% percent sign
+ \n newline
+ \r carriage return
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -debug coders -log "%u %m:%l %e" in.gif out.png
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default behavior is to print all of the components.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-loop"></a>-loop <i>&lt;iterations&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add Netscape loop extension to your GIF animation</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A value other than zero forces the animation to repeat itself up to
+<em>iterations</em>
+times.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The image size is doubled using linear interpolation.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The displayed image is magnified by <strong>factor</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-map"></a>-map <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>choose a particular set of colors from this image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+[<em>convert</em> or <em>mogrify</em>]</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, color reduction chooses an optimal set of colors that best
+represent the original image. Alternatively, you can choose a particular
+set of colors from an image file with this option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use
+<strong>+map</strong> to reduce
+all images in the image sequence that follows to a single optimal set of colors
+that best represent all the images. The sequence of images
+is terminated by the appearance of any option.
+If the <strong>+map</strong>
+option appears after all of the input images, all images are mapped.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-map"></a>-map <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display image using this type.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+[<em>animate</em> or <em>display</em>]</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from these <em>Standard Colormap</em> types:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ best
+ default
+ gray
+ red
+ green
+ blue
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <em>X server</em> must support the <em>Standard Colormap</em> you choose,
+otherwise an error occurs. Use <strong>list</strong> as the type and <strong>display</strong>
+searches the list of colormap types in <strong>top-to-bottom</strong> order until
+one is located. See <em>xstdcmap(1)</em> for one way of creating Standard
+Colormaps.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-mask"></a>-mask <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify a clipping mask</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The image read from the file is used as a clipping mask. It must have
+the same dimensions as the image being masked.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the mask image contains an opacity channel, the opacity of each
+pixel is used to define the mask. Otherwise, the intensity (gray
+level) of each pixel is used. Unmasked (black) pixels are modified
+while masked pixels (not black) are protected from alteration.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+mask</strong> to remove the clipping mask.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+It is not necessary to use <strong>-clip</strong> to activate the mask; <strong>-clip</strong>
+is implied by <strong>-mask</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-matte"></a>-matte
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the image does not have a matte channel, create an opaque one.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+matte</strong> to ignore the matte channel and to avoid writing a
+matte channel in the output file.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-mattecolor"></a>-mattecolor <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-maximum-error"></a>-maximum-error <i>&lt;limit&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the maximum amount of total image error</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specifies the maximum amount of total image error (based on comparison
+using a specified metric) before an error ("image difference exceeds
+limit") is reported. The error is reported via a non-zero command
+execution return status.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -median <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a median filter to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -metric <i>&lt;metric&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>comparison metric (MAE, MSE, PAE, PSNR, RMSE)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -minify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>minify the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The image size is halved using linear interpolation.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -mode <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>mode of operation</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The available montage modes are <strong>frame</strong> to place the images in a
+rectangular grid while adding a decorative frame with dropshadow,
+<strong>unframe</strong> to place undecorated images in a rectangular grid, and
+<strong>concatenate</strong> to pack the images closely together without any
+well-defined grid or decoration. </font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-modulate"></a>-modulate <i>brightness[,saturation[,hue]]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>vary the brightness, saturation, and hue of an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify the percent change in brightness, color saturation, and
+hue separated by commas. Default argument values are 100 percent,
+resulting in no change. For example, to increase the color brightness
+by 20% and decrease the color saturation by 10% and leave the hue
+unchanged, use: <strong>-modulate 120,90</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Hue is the percentage of absolute rotation from the current
+position. For example 50 results in a counter-clockwise rotation of 90
+degrees, 150 results in a clockwise rotation of 90 degrees, with 0 and
+200 both resulting in a rotation of 180 degrees.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A simple command-line progress indication is shown while the command is
+running. The process indication shows the operation currently being
+performed and the percent completed. Commands using X11 may replace the
+command line progress indication with a graphical one once an image has
+been displayed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-morph"></a>-morph <i>&lt;frames&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>morphs an image sequence</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Both the image pixels and size are linearly interpolated to give the appearance
+of a meta-morphosis from one image to the next.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images
+is terminated by the appearance of any option.
+If the <strong>-morph</strong>
+option appears after all of the input images, all images are morphed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-mosaic"></a>-mosaic
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a mosaic from an image or an image sequence</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-mosaic</strong> option provides a flexible way to composite one or
+more images onto a solid-color canvas image. It works similar to
+<strong>-flatten</strong> except that a base canvas image is automatically
+created with a suitable size given the image size, page dimensions,
+and page offsets of images to be composited. The color of the base
+canvas image may be set via the <strong>-background</strong> option. The
+default canvas color is 'white', but 'black' or 'transparent' may be
+more suitable depending on the composition algorithm requested.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-compose</strong> option may be used to specify the composition
+algorithm to use when compositing the subsequent image on the base
+canvas.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-page</strong> option can be used to establish the dimensions of the
+mosaic and to position the subsequent image within the mosaic. If the
+<strong>-page</strong> argument does not specify width and height, then the
+canvas dimensions are evaluated based on the image sizes and
+offsets.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images is terminated by the appearance of any option.
+If the <strong>-mosaic</strong> option appears after all of the input images,
+all images are included in the mosaic.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The following is an example of composing an image based on red, green,
+and blue layers extracted from a sequence of images and pasted on the
+canvas image at specified offsets:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -background black \
+ -compose CopyRed -page +0-100 red.png \
+ -compose CopyGreen -page +0+40 green.png \
+ -compose CopyBlue -page +0+180 blue.png \
+ -mosaic output.png
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-motion-blur"></a>-motion-blur <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+angle</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Simulate motion blur</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Simulate motion blur by convolving the image with a Gaussian operator of
+the given radius and standard deviation (sigma). For reasonable results,
+radius should be larger than sigma. If radius is zero, then a suitable
+radius is automatically selected based on sigma. The angle specifies the
+angle that the object is coming from (side which is blurred).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -name
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-negate"></a>-negate
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The red, green, and blue intensities of an image are negated.
+White becomes black,
+yellow becomes blue, etc.
+Use <strong>+negate</strong>
+to only negate the grayscale pixels of the image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-noise"></a>-noise <i>&lt;radius|type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add or reduce noise in an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The principal function of noise peak elimination filter is to smooth the
+objects within an image without losing edge information and without creating
+undesired structures. The central idea of the algorithm is to replace a
+pixel with its next neighbor in value within a pixel window, if this pixel
+has been found to be noise. A pixel is defined as noise if and only if
+this pixel is a maximum or minimum within the pixel window.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>radius</strong> to specify the width of the neighborhood.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+noise</strong> followed by a noise type to add noise to an image.
+The noise added modulates the existing image pixels. Choose from these
+noise types:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Uniform
+ Gaussian
+ Multiplicative
+ Impulse
+ Laplacian
+ Poisson
+ Random (uniform distribution)
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-noop"></a>-noop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-noop</strong> option can be used to terminate a group of images
+and reset all options to their default values, when no other option is
+desired.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-normalize"></a>-normalize
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform image to span the full range of color values</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This is a contrast enhancement technique based on the image histogram.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When computing the contrast enhancement values, the histogram edges
+are truncated so that the majority of the image pixels are considered
+in the constrast enhancement, and outliers (e.g. random noise or
+minute details) are ignored. The default is that 0.1 percent of the
+histogram entries are ignored. The percentage of the histogram to
+ignore may be specified by using the <strong>-set</strong> option with the
+<strong>histogram-threshold</strong> parameter similar to <strong>-set
+histogram-threshold 0.01</strong> to specify 0.01 percent. Use 0 percent
+to use the entire histogram, with possibly diminished contrast
+enhancement.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-opaque"></a>-opaque <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>change this color to the pen color within the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the
+<strong>-fill</strong> option. The color is replaced if it is identical to the
+target color, or close enough to the target color in a 3D space as
+defined by the Euclidean distance specified by <strong>-fuzz</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-fill</strong> and <strong>-fuzz</strong> for more details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-operator"></a>-operator <i>channel operator rvalue[%]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a mathematical, bitwise, or value operator to an image channel</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Apply a low-level mathematical, bitwise, or value operator to a selected
+image channel or all image channels. Operations which result in negative
+results are reset to zero, and operations which overflow the available
+range are reset to the maximum possible value.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Select a channel from: <strong>Red</strong>, <strong>Green</strong>, <strong>Blue</strong>,
+<strong>Opacity</strong>, <strong>Matte</strong>, <strong>Cyan</strong>, <strong>Magenta</strong>, <strong>Yellow</strong>,
+<strong>Black</strong>, <strong>All</strong>, or <strong>Gray</strong>. <strong>All</strong> only modifies the
+color channels and does not modify the <strong>Opacity</strong> channel. Except for
+the threshold operators, <strong>All</strong> operates on each channel
+independently so that operations are on a per-channel basis.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Gray</strong> treats the color channels as a grayscale intensity and
+performs the requested operation on the equivalent pixel intensity so the
+result is a gray image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Select an operator from <strong>Add</strong>, <strong>And</strong>, <strong>Assign</strong>,
+<strong>Depth</strong>, <strong>Divide</strong>, <strong>Gamma</strong>, <strong>Negate</strong>,
+<strong>LShift</strong>, <strong>Log</strong>, <strong>Max</strong>, <strong>Min</strong>, <strong>Multiply</strong>,
+<strong>Or</strong>, <strong>Pow</strong> <strong>RShift</strong>, <strong>Subtract</strong>,
+<strong>Threshold</strong>, <strong>Threshold-White</strong>,
+<strong>Threshold-White-Negate</strong>, <strong>Threshold-Black</strong>,
+<strong>Threshold-Black-Negate</strong>, <strong>Xor</strong>, <strong>Noise-Gaussian</strong>,
+<strong>Noise-Impulse</strong>, <strong>Noise-Laplacian</strong>,
+<strong>Noise-Multiplicative</strong>, <strong>Noise-Poisson</strong>,
+<strong>Noise-Random</strong>, and <strong>Noise-Uniform</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Rvalue may be any floating point or integer value. Normally rvalue will
+be in the range of 0 to MaxRGB, where MaxRGB is the largest quantum value
+supported by the GraphicsMagick build (255, 65535, or 4294967295) but
+values outside this range are useful for some arithmetic operations.
+Arguments to logical or bit-wise operations are rounded to a positive
+integral value prior to use. If a percent (<strong>%</strong>) symbol is appended
+to the argument, then the argument has a range of 0 to 100 percent.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The following is a description of the operators:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>Add</dt>
+<dd>Result is rvalue added to channel value.
+</dd>
+<dt>And</dt>
+<dd>Result is the logical AND of rvalue with channel value.
+</dd>
+<dt>Assign</dt>
+<dd>Result is rvalue.
+</dd>
+<dt>Depth</dt>
+<dd>Result is channel value adjusted so that it may be (approximately)
+stored in the specified number of bits without additional loss.
+</dd>
+<dt>Divide</dt>
+<dd>Result is channel value divided by rvalue.
+</dd>
+<dt>Gamma</dt>
+<dd>Result is channel value gamma adjusted by rvalue.
+</dd>
+<dt>LShift</dt>
+<dd>Result is channel value bitwise left shifted by rvalue bits.
+</dd>
+<dt>Log</dt>
+<dd>Result is computed as log(value*rvalue+1)/log(rvalue+1).
+</dd>
+<dt>Max</dt>
+<dd>Result is assigned to rvalue if rvalue is greater than value.
+</dd>
+<dt>Min</dt>
+<dd>Result is assigned to rvalue if rvalue is less than value.
+</dd>
+<dt>Multiply</dt>
+<dd>Result is channel value multiplied by rvalue.
+</dd>
+<dt>Negate</dt>
+<dd>Result is inverse of channel value (like a film negative). An rvalue
+must be supplied but is currently not used. Inverting the image twice
+results in the original image.
+</dd>
+<dt>Or</dt>
+<dd>Result is the logical OR of rvalue with channel value.
+</dd>
+<dt>Pow</dt>
+<dd>Result is computed as pow(value,rvalue). Similar to Gamma except that
+rvalue is not inverted.
+</dd>
+<dt>RShift</dt>
+<dd>Result is channel value bitwise right shifted by rvalue bits.
+</dd>
+<dt>Subtract</dt>
+<dd>Result is channel value minus rvalue.
+</dd>
+<dt>Threshold</dt>
+<dd>Result is maximum (white) if channel value is greater than rvalue,
+or minimum (black) if it is less than or equal to rvalue. If <strong>all</strong>
+channels are specified, then thresholding is done based on computed pixel
+intensity.
+</dd>
+<dt>Threshold-white</dt>
+<dd>Result is maximum (white) if channel value is greater than rvalue and
+is unchanged if it is less than or equal to rvalue. This can be used to
+remove apparent noise from the bright parts of an image. If <strong>all</strong>
+channels are specified, then thresholding is done based on computed pixel
+intensity.
+</dd>
+<dt>Threshold-White-Negate</dt>
+<dd>Result is set to black if channel value is greater than
+rvalue and is unchanged if it is less than or equal to rvalue. If
+<strong>all</strong> channels are specified, then thresholding is done based on
+computed pixel intensity.
+</dd>
+<dt>Threshold-black</dt>
+<dd>Result is minimum (black) if channel value is less than than rvalue
+and is unchanged if it is greater than or equal to rvalue. This can be
+used to remove apparent noise from the dark parts of an image. If
+<strong>all</strong> channels are specified, then thresholding is done based on
+computed pixel intensity.
+</dd>
+<dt>Threshold-Black-Negate</dt>
+<dd>Result is set to white if channel value is less than than
+rvalue and is unchanged if it is greater than or equal to rvalue. If
+<strong>all</strong> channels are specified, then thresholding is done based on
+computed pixel intensity.
+</dd>
+<dt>Xor</dt>
+<dd>Result is the logical XOR of rvalue with channel value. An
+interesting property of XOR is that performing the same operation twice
+results in the original value.
+</dd>
+<dt>Noise-Gaussian</dt>
+<dd>Result is the current channel value modulated with gaussian noise
+according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Impulse</dt>
+<dd>Result is the current channel value modulated with impulse noise
+according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Laplacian</dt>
+<dd>Result is the current channel value modulated with laplacian noise
+according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Multiplicative</dt>
+<dd>Result is the current channel value modulated with multiplicative
+gaussian noise according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Poisson</dt>
+<dd>Result is the current channel value modulated with poisson noise
+according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Random</dt>
+<dd>Result is the current channel value modulated with random (uniform
+distribution) noise according to the intensity specified by rvalue.
+The initial noise intensity (rvalue=1.0) is the range of one pixel
+quantum span.
+</dd>
+<dt>Noise-Uniform</dt>
+<dd>Result is the channel value with uniform noise applied according to
+the intensity specified by rvalue.
+</dd>
+</dl>
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+As an example, the <strong>Assign</strong> operator assigns a fixed value to a
+channel. For example, this command sets the red channel to the mid-range
+value:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert in.bmp -operator red assign "50%" out.bmp
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The following applies 50% thresholding to the image and returns a gray
+image:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert in.bmp -operator gray threshold "50%" out.bmp
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-ordered-dither"></a>-ordered-dither <i>&lt;channeltype&gt; &lt;NxN&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>ordered dither the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The channel or channels specified in the <strong>channeltype</strong> argument are
+reduced to binary, using an ordered dither method. The choices for
+<strong>channeltype</strong> are <strong>All</strong>, <strong>Intensity</strong>, <strong>Red</strong>,
+<strong>Green</strong>, <strong>Blue</strong>, <strong>Cyan</strong>, <strong>Magenta</strong>, <strong>Yellow</strong>,
+<strong>Black</strong>, and <strong>Opacity</strong></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When <strong>channeltype</strong> is "All", the color samples are dithered into
+a gray level and then that gray level is stored in the three color
+channels. Separately, the opacity channel is dithered into a bilevel
+opacity value which is stored in the opacity channel.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When <strong>channeltype</strong> is "Intensity", only the color samples are
+dithered. When <strong>channeltype</strong> is "opacity" or "matte", only the
+opacity channel is dithered. When a color channel is specified, only that
+channel is dithered.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The choices for N are 2 through 7. The image is divided into
+NxN pixel tiles. In each tile, some or all pixels are turned to
+white depending on their intensity. For each N, (N**2)+1 levels
+of gray can be represented. For N == 2, 3, or 4, the pixels
+are turned to white in an order that maximizes dispersion (i.e.,
+reduces granularity), while
+for N == 5, 6, and 7, they are turned to white in an order that
+creates a roughly circular black blob in the middle of each tile.
+An attractive "half-tone" looking image can be obtained by first
+rotating the image 45 degrees, performing a 5x5 ordered-dither
+operation, then rotating it back to the original orientation and
+cropping to the original image dimensions. If the original image
+is gamma-encoded, it is adviseable to convert it to linear intensity
+first, e.g., with the "-gamma 0.45455" option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-output-directory"></a>-output-directory <i>&lt;directory&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output files to directory</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use -output-directory to specify a directory under which to write the
+output files. Normally mogrify overwrites the input files but with this
+option the output files may be written to a different directory so that
+the input files are preserved. The algorithm used preserves all of the
+input path specification in the output path so that the user-specified
+input path (including any directory part) is appended to the output path.
+The user is responsible for creating the output directory.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-orient"></a>-orient <i>&lt;orientation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Set the image orientation attribute</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Sets the image orientation attribute. The image orientation attribute
+is compatible with the TIFF orientation tag (and the EXIF orientation
+tag). Accepted values are <strong>undefined</strong>, <strong>TopLeft</strong>,
+<strong>TopRight</strong>, <strong>BottomRight</strong>, <strong>BottomLeft</strong>,
+<strong>LeftTop</strong>, <strong>RightTop</strong>, <strong>RightBottom</strong>,
+<strong>LeftBottom</strong>, and hyphenated versions thereof
+(e.g. <strong>left-bottom</strong>). Please note that GraphicsMagick does not
+include an EXIF editor so if an EXIF profile is written to the output
+image, the value in the EXIF profile might not match the image. It is
+possible for an image file to indicate its orientation in several
+different ways simultaneously.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-page"></a>-page <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to specify the dimensions of the
+<em>PostScript</em> page
+in dots per inch or a TEXT page in pixels. The choices for a PostScript
+page are:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 11x17 792 1224
+ Ledger 1224 792
+ Legal 612 1008
+ Letter 612 792
+ LetterSmall 612 792
+ ArchE 2592 3456
+ ArchD 1728 2592
+ ArchC 1296 1728
+ ArchB 864 1296
+ ArchA 648 864
+ A0 2380 3368
+ A1 1684 2380
+ A2 1190 1684
+ A3 842 1190
+ A4 595 842
+ A4Small 595 842
+ A5 421 595
+ A6 297 421
+ A7 210 297
+ A8 148 210
+ A9 105 148
+ A10 74 105
+ B0 2836 4008
+ B1 2004 2836
+ B2 1418 2004
+ B3 1002 1418
+ B4 709 1002
+ B5 501 709
+ C0 2600 3677
+ C1 1837 2600
+ C2 1298 1837
+ C3 918 1298
+ C4 649 918
+ C5 459 649
+ C6 323 459
+ Flsa 612 936
+ Flse 612 936
+ HalfLetter 396 612
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For convenience you can specify the page size by media (e.g. A4, Ledger,
+etc.). Otherwise, <strong>-page</strong> behaves much like
+<strong>-geometry</strong> (e.g. <tt>-page letter+43+43&gt;</tt>).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is also used to place subimages when writing to a multi-image
+format that supports offsets, such as GIF89 and MNG. When used for this
+purpose the offsets are always measured from the
+top left corner of the canvas and are not affected by the <strong>-gravity</strong>
+option.
+To position a GIF or MNG image, use <strong>-page</strong><em>{+-}&lt;x&gt;{+-}&lt;y&gt;</em>
+(e.g. -page +100+200). When writing to a MNG file, a <strong>-page</strong>
+option appearing ahead of the first image in the sequence with nonzero
+width and height defines the width and height values that are written in
+the <strong>MHDR</strong> chunk. Otherwise, the MNG width and height are computed
+from the bounding box that contains all images in the sequence. When
+writing a GIF89 file, only the bounding box method is used to determine its
+dimensions.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For a PostScript page, the image is sized as in <strong>-geometry</strong> and positioned
+relative to the lower left hand corner of the page by
+{+-}&lt;<strong>x</strong><em>offset</em>&gt;{+-}&lt;<strong>y</strong>
+<em>offset&gt;</em>. Use
+<tt>-page 612x792&gt;</tt>, for example, to center the
+image within the page. If the image size exceeds the PostScript page, it
+is reduced to fit the page.
+The default gravity for the <strong>-page</strong>
+option is <em>NorthWest</em>, i.e., positive <strong>x</strong> and
+<strong>y</strong> <em>offset</em> are measured rightward and downward from the top
+left corner of the page, unless the <strong>-gravity</strong> option is present with
+a value other than <em>NorthWest</em>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default page dimensions for a TEXT image is 612x792.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is used in concert with <strong>-density</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+page</strong> to remove the page settings for an image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-paint"></a>-paint <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate an oil painting</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Each pixel is replaced by the most frequent color in a circular neighborhood
+whose width is specified with <em>radius</em>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-pause"></a>-pause <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pause between animation loops [animate]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Pause for the specified number of seconds before repeating the
+animation.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-pause"></a>-pause <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pause between snapshots [import]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Pause for the specified number of seconds before taking the next
+snapshot.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-pen"></a>-pen <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>(This option has been replaced by the -fill option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -ping
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>efficiently determine image characteristics</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to disable reading the image pixels so that image
+characteristics such as the image dimensions may be obtained very
+quickly. For identify, use +ping to force reading the image pixels so
+that the pixel read rate may be included in the displayed information.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-preview"></a>-preview <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>image preview type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to affect the preview operation of an image (e.g.
+<tt>convert file.png -preview Gamma Preview:gamma.png</tt>). Choose
+from these previews:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Rotate
+ Shear
+ Roll
+ Hue
+ Saturation
+ Brightness
+ Gamma
+ Spiff
+ Dull
+ Grayscale
+ Quantize
+ Despeckle
+ ReduceNoise
+ AddNoise
+ Sharpen
+ Blur
+ Threshold
+ EdgeDetect
+ Spread
+ Shade
+ Raise
+ Segment
+ Solarize
+ Swirl
+ Implode
+ Wave
+ OilPaint
+ CharcoalDrawing
+ JPEG
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default preview is <strong>JPEG</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-process"></a>-process <i>&lt;command&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>process a sequence of images using a process module</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The command argument has the form <strong>module=arg1,arg2,arg3,...,argN</strong>
+where <strong>module</strong> is the name of the module to invoke (e.g. "analyze")
+and arg1,arg2,arg3,...,argN are an arbitrary number of arguments to
+pass to the process module.</font></td></tr></table><table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images
+is terminated by the appearance of any option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the <strong>-process</strong>
+option appears after all of the input images, all images are processed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-profile"></a>-profile <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add ICM, IPTC, or generic profile to image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<tt>-profile filename</tt> adds an ICM (ICC color management), IPTC
+(newswire information), or a generic (including Exif) profile to the image
+</font></td></tr></table>.
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <tt>+profile icm</tt>, <tt>+profile iptc</tt>, or
+<tt>+profile profile_name</tt> to remove the respective profile.
+Multiple profiles may be listed, separated by commas. Profiles may be
+excluded from subsequent listed matches by preceding their name with
+an exclamation point. For example, <tt>+profile '!icm,*'</tt> strips
+all profiles except for the ICM profile. Use <tt>identify
+-verbose</tt> to find out what profiles are in the image file. Use
+<tt>+profile "*"</tt> to remove all profiles.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Writing the image to a format that does not support profiles will
+of course also cause all profiles to be removed. The JPEG and PNG
+formats will store any profiles that have been read and not removed.
+In JPEG they are stored in APP1 markers, and in PNG they are stored
+as hex-coded binary in compressed zTXt chunks, except for the iCC
+chunk which is stored in the iCCP chunk.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+To extract a profile, the <strong>-profile</strong> option is not used. Instead,
+simply write the file to an image
+format such as <em>APP1, 8BIM, ICM,</em> or <em>IPTC</em>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, to extract the Exif data (which is stored in JPEG files
+in the <em>APP1</em> profile), use
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert cockatoo.jpg exifdata.app1
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Note that GraphicsMagick does not attempt to update any profile to
+reflect changes made to the image, e.g., rotation from portrait to landscape
+orientation, so it is possible that the preserved profile may contain
+invalid data.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-preserve-timestamp"></a>-preserve-timestamp
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preserve the original timestamps of the file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to preserve the original modification and access
+timestamps of the file, even if it has been modified.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details+progress"></a>+progress
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>disable progress monitor and busy cursor</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, when an image is displayed, a progress monitor bar is shown
+in the top left corner of an existing image display window, and the
+current cursor is replaced with an hourglass cursor. Use <strong>+progress</strong>
+to disable the progress monitor and busy cursor during display operations.
+While the progress monitor is disabled for all operations, the busy
+cursor continues to be enabled for non-display operations such as image
+processing. This option is useful for non-interactive display operations,
+or when a "clean" look is desired.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-quality"></a>-quality <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"> For the JPEG and MPEG image formats, quality is 0 (lowest image
+quality and highest compression) to 100 (best quality but least
+effective compression). The default quality is 75. Use the
+<strong>-sampling-factor</strong> option to specify the factors for chroma
+downsampling. To use the same quality value as that found by the JPEG
+decoder, use the <tt>-define jpeg:preserve-settings</tt> flag.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the MIFF image format, and the TIFF format while using ZIP
+compression, quality/10 is the zlib compression level, which is 0 (worst
+but fastest compression) to 9 (best but slowest). It has no effect on the
+image appearance, since the compression is always lossless.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the JPEG-2000 image format, quality is mapped using a non-linear
+equation to the compression ratio required by the Jasper library. This
+non-linear equation is intended to loosely approximate the quality
+provided by the JPEG v1 format. The default quality value 75 results in
+a request for 16:1 compression. The quality value 100 results in
+a request for non-lossy compression.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the MNG and PNG image formats, the quality value sets the zlib compression
+level (quality / 10) and filter-type (quality % 10). Compression levels
+range from 0 (fastest compression) to 100 (best but slowest). For compression
+level 0, the Huffman-only strategy is used, which is fastest but not
+necessarily the worst compression.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If
+filter-type is 4 or less, the specified filter-type is used for all scanlines:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 0: none
+ 1: sub
+ 2: up
+ 3: average
+ 4: Paeth
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If filter-type is 5, adaptive filtering is used when quality is greater
+than 50 and the image does not have a color map, otherwise no filtering
+is used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If filter-type is 6, adaptive filtering
+with <em>minimum-sum-of-absolute-values</em>
+is used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Only if the output is MNG, if filter-type is 7, the LOCO color transformation
+and adaptive filtering with <em>minimum-sum-of-absolute-values</em>
+are used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default is quality is 75, which means nearly the best compression with
+adaptive filtering. The quality setting has no effect on the appearance
+of PNG and MNG images, since the compression is always lossless.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For further information, see the <a href="http://www.w3.org/TR/">PNG</a>
+specification.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When writing a JNG image with transparency, two quality values are required,
+one for the main image and one for the grayscale image that conveys the
+opacity channel. These are written as a single integer equal to the main
+image quality plus 1000 times the opacity quality. For example, if you
+want to use quality 75 for the main image and quality 90 to compress
+the opacity data, use <tt>-quality 90075</tt>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the PNM family of formats (PNM, PGM, and PPM) specify a quality
+factor of zero in order to obtain the ASCII variant of the format. Note
+that -compress <em>none</em> used to be used to trigger ASCII output but
+provided the opposite result of what was expected as compared with other
+formats.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-raise"></a>-raise <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>lighten or darken image edges</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This will create a 3-D effect. See <strong>-geometry</strong> for details
+details about the geometry specification. Offsets are not used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>-raise</strong> to create a raised effect, otherwise use <strong>+raise</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-random-threshold"></a>-random-threshold <i>&lt;channeltype&gt; &lt;LOWxHIGH&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>random threshold the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The channel or channels specified in the &lt;channeltype&gt; argument are
+reduced to binary, using an random-threshold method. The choices for
+<strong>channeltype</strong> are <strong>All</strong>, <strong>Intensity</strong>, <strong>Red</strong>,
+<strong>Green</strong>, <strong>Blue</strong>, <strong>Cyan</strong>, <strong>Magenta</strong>, <strong>Yellow</strong>,
+<strong>Black</strong>, and <strong>Opacity</strong></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When <strong>channeltype</strong> is "All", the color samples are thresholded into
+a graylevel and then that gray level is stored in the three color
+channels. Separately, the opacity channel is thresholded into a bilevel
+opacity value which is stored in the opacity channel. For each pixel, a
+new random number is used to establish the threshold to be used. The
+threshold never exceeds the specified maximum (HIGH) and is never less
+than the specified minimum (LOW).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When <strong>channeltype</strong> is "intensity", only the color samples are
+thresholded. When <strong>channeltype</strong> is "opacity" or "matte", only the
+opacity channel is thresholded. The other named channels only threshold
+the associated channel.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-recolor"></a>-recolor <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a color translation matrix to image channels</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A user supplied color translation matrix (expressed as a text string)
+is used to translate/blend the image channels based on weightings in a
+supplied matrix which may be of order 3 (color channels only), 4
+(color channels plus opacity), or 5 (color channels plus opacity and
+offset). Values in the columns of the matrix (red, green, blue,
+opacity) are used as multipliers with the existing channel values and
+added together according to the rows of the matrix. Matrix values are
+floating point and may be negative. The offset column (column 5) is
+purely additive and is scaled such that 0.0 to 1.0 represents the
+maximum quantum range (but values are not limited to this range). The
+math for the color translation matrix is similar to that used by Adobe
+Flash except that the offset is scaled to 1.0 (divide Flash offset by
+255 for use with GraphicsMagick) so that the results are independent
+of quantum depth.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+An <strong>identity</strong> matrix exists for each matrix order which
+results in no change to the image. The translation matrix should be
+based on an alteration of the identity matrix.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Identity matrix of order 3</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 1 0 0
+ 0 1 0
+ 0 0 1
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+which may be formatted into a convenient matrix argument similar to
+(comma is treated as white space):</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -recolor "1 0 0, 0 1 0, 0 0 1"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Identity matrix of order 4</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 1 0 0 0
+ 0 1 0 0
+ 0 0 1 0
+ 0 0 0 1
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Identity matrix of order 5. The last row is required to exist
+for the purpose of parsing, but is otherwise not used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 1 0 0 0 0
+ 0 1 0 0 0
+ 0 0 1 0 0
+ 0 0 0 1 0
+ 0 0 0 0 1
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+As an example, an image wrongly in BGR channel order may be converted
+to RGB using this matrix (blue-&gt;red, red-&gt;blue):</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 0 0 1
+ 0 1 0
+ 1 0 0
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+and an RGB image using standard Rec.709 primaries may be converted
+to grayscale using this matrix of standard weighting factors:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 0.2126 0.7152 0.0722
+ 0.2126 0.7152 0.0722
+ 0.2126 0.7152 0.0722
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+and contrast may be reduced by scaling down by 80% and adding a 10%
+offset:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 0.8 0.0 0.0 0.0 0.1
+ 0.0 0.8 0.0 0.0 0.1
+ 0.0 0.0 0.8 0.0 0.1
+ 0.0 0.0 0.0 0.8 0.1
+ 0.0 0.0 0.0 0.0 1.0
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-red-primary"></a>-red-primary <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-region"></a>-region <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply options to a portion of the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <em>x</em> and <em>y</em> offsets are treated in the same manner as in <strong>-crop</strong></font></td></tr></table>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-remote"></a>-remote
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform a X11 remote operation</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-remote</strong> command sends a command to a "gm display" or "gm
+animate" which is already running. The only command recognized at this
+time is the name of an image file to load. This capability is very
+useful to load new images without needing to restart GraphicsMagick
+(e.g. for a slide-show or to use GraphicsMagick as the display engine
+for a different GUI). Also see the <strong>+progress</strong> option for a way
+to disable progress indication for a clean look while loading new images.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-render"></a>-render
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+render</strong> to turn off rendering vector operations. This is
+useful when saving the result to vector formats such as MVG or SVG.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-repage"></a>-repage <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Adjust the current image page canvas and position based on a relative
+page specification. This option may be used to change the location of
+a subframe (e.g. part of an animation) prior to composition. If the
+geometry specification is absolute (includes a '!'), then the offset
+adjustment is absolute and there is no adjustment to page width and
+height, otherwise the page width and height values are also adjusted
+based on the current image dimensions. Use <strong>+repage</strong> to set the
+image page offsets to default.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-resample"></a>-resample <i>&lt;horizontal&gt;x&lt;vertical&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Resample image to specified horizontal and vertical resolution</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Resize the image so that its rendered size remains the same as the
+original at the specified target resolution. Either the current image
+resolution units or the previously set with <strong>-units</strong> are used to
+interpret the argument. For example, if a 300 DPI image renders at 3
+inches by 2 inches on a 300 DPI device, when the image has been
+resampled to 72 DPI, it will render at 3 inches by 2 inches on a 72
+DPI device. Note that only a small number of image formats
+(e.g. JPEG, PNG, and TIFF) are capable of storing the image
+resolution. For formats which do not support an image resolution, the
+original resolution of the image must be specified via <strong>-density</strong>
+on the command line prior to specifying the resample resolution.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Note that Photoshop stores and obtains image resolution from a
+proprietary embedded profile. If this profile exists in the image,
+then Photoshop will continue to treat the image using its former
+resolution, ignoring the image resolution specified in the standard
+file header.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Some image formats (e.g. PNG) require use of metric or english units
+so even if the original image used a particular unit system, if it is
+saved to a different format prior to resampling, then it may be
+necessary to specify the desired resolution units using <strong>-units</strong>
+since the original units may have been lost. In other words, do not
+assume that the resolution units are restored if the image has been
+saved to a file.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-resize"></a>-resize <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This is an alias for the <strong>-geometry</strong> option and it behaves in the
+same manner. If the <strong>-filter</strong> option precedes the <strong>-resize</strong>
+option, the specified filter is used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+There are some exceptions:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>composite</em> option, <strong>-resize</strong> conveys the
+preferred size of the output image, while <strong>-geometry</strong> conveys the
+size and placement of the <em>composite image</em> within the main
+image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>montage</em> option, <strong>-resize</strong> conveys the preferred
+size of the montage, while <strong>-geometry</strong> conveys
+information about the tiles.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-roll"></a>-roll <i></i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>roll an image vertically or horizontally</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details the geometry specification. The
+<em>x</em> and <em>y</em> offsets are not affected by the <strong>-gravity</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A negative <em>x</em> offset rolls the image left-to-right. A negative
+<em>y</em> offset rolls the image top-to-bottom.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-rotate"></a>-rotate <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Positive angles rotate the image in a clockwise direction while
+negative angles rotate counter-clockwise.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <tt>&gt;</tt> to rotate the image only if its width exceeds the
+height. <tt>&lt;</tt> rotates the image <em>only</em> if its width is less
+than the height. For example, if you specify <tt>-rotate "-90&gt;"</tt>
+and the image size is 480x640, the image is not rotated. However, if
+the image is 640x480, it is rotated by -90 degrees. If you use
+<tt>&gt;</tt> or <tt>&lt;</tt>, enclose it in quotation marks to prevent it
+from being misinterpreted as a file redirection.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Empty triangles left over from rotating the image are filled with the
+color defined as <strong>background</strong> (class <strong>backgroundColor</strong>).
+The color is specified using the format described under the
+<strong>-fill</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-sample"></a>-sample <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale image using pixel sampling</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details about
+the geometry specification.
+<strong>-sample</strong> ignores the <strong>-filter</strong> selection if the <strong>-filter</strong> option
+is present. Offsets, if present in the geometry string, are ignored, and
+the <strong>-gravity</strong> option has no effect.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-sampling-factor"></a>-sampling-factor <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option specifies the sampling factors to be used by the DPX, JPEG,
+MPEG, or YUV encoders for chroma downsampling. The sampling factor must
+be specified while reading the raw YUV format since it is not preserved
+in the file header.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Industry-standard video subsampling notation such as "4:2:2" may also
+be used to specify the sampling factors. "4:2:2" is equivalent to a
+specification of "2x1"</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The JPEG decoder obtains the original sampling factors (and quality
+settings) when a JPEG file is read. To re-use the original sampling
+factors (and quality setting) when JPEG is output, use the <tt>-define
+jpeg:preserve-settings</tt> flag.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-scale"></a>-scale <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale the image.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details about
+the geometry specification. <strong>-scale</strong> uses a simpler, faster algorithm,
+and it ignores the <strong>-filter</strong> selection if the <strong>-filter</strong> option
+is present. Offsets, if present in the geometry string, are ignored, and
+the <strong>-gravity</strong> option has no effect.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-scene"></a>-scene <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option sets the scene number of an image or the first image in
+an image sequence.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-scenes"></a>-scenes <i>&lt;value-value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>range of image scene numbers to read</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Each image in the range is read
+with the filename followed by a period (<strong>.</strong>) and the decimal scene
+number. You
+can change this behavior by embedding a <strong>%d, %0Nd, %o, %0No, %x, or %0Nx
+printf</strong> format specification in the file name. For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm montage -scenes 5-7 image.miff montage.miff
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+makes a montage of files image.miff.5, image.miff.6, and image.miff.7, and</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm animate -scenes 0-12 image%02d.miff
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+animates files image00.miff, image01.miff, through image12.miff.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-screen"></a>-screen
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the screen to capture</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option indicates that the GetImage request used to obtain the image
+should be done on the root window, rather than directly on the specified
+window. In this way, you can obtain pieces of other windows that overlap
+the specified window, and more importantly, you can capture menus or other
+popups that are independent windows but appear over the specified window.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-set"></a>-set <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Set a named image attribute. The attribute is set on the current
+(previously specified on command line) image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details+set"></a>+set <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Unset a named image attribute. The attribute is removed from the current
+(previously specified on command line) image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-segment"></a>-segment <i>&lt;cluster threshold&gt;x&lt;smoothing threshold&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>segment an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Segment an image by analyzing the histograms of the color components and
+identifying units that are homogeneous with the fuzzy c-means technique.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Segmentation is a very useful fast and and approximate color quantization
+algorithm for scanned printed pages or scanned cartoons. It may also be
+used as a special effect. Specify <em>cluster threshold</em> as the minimum
+percentage of total pixels in a cluster before it is considered valid.
+For huge images containing small detail, this may need to be a tiny
+fraction of a percent (e.g. 0.015) so that important detail is not lost.
+<em>Smoothing threshold</em> eliminates noise in the second derivative of
+the histogram. As the value is increased, you can expect a smoother
+second derivative. The default is 1.5. Add the <em>-verbose</em> option to
+see a dump of cluster statistics given the parameters used. The
+statistics may be used as a guide to help fine tune the options.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-shade"></a>-shade <i>&lt;azimuth&gt;x&lt;elevation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shade the image using a distant light source</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <em>azimuth</em> and <em>elevation</em> as the position of the light
+source. Use <strong>+shade</strong> to return the shading results as a grayscale
+image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -shadow <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shadow the montage</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-shared-memory"></a>-shared-memory
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use shared memory</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option specifies whether the utility should attempt to use shared
+memory for pixmaps. GraphicsMagick must be compiled with shared
+memory support, and the display must support the <em>MIT-SHM</em>
+extension. Otherwise, this option is ignored. The default is
+<strong>True</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-sharpen"></a>-sharpen <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use a Gaussian operator of the given radius and standard deviation
+(sigma).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-shave"></a>-shave <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shave pixels from the image edges</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify the width of the region to be removed from both
+sides of the image and the height of the regions to be removed from
+top and bottom.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-shear"></a>-shear <i>&lt;x degrees&gt;x&lt;y degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shear the image along the X or Y axis</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the specified positive or negative shear angle.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Shearing slides one edge of an image along the X or Y axis, creating a
+parallelogram. An X direction shear slides an edge along the X axis,
+while a Y direction shear slides an edge along the Y axis. The amount
+of the shear is controlled by a shear angle. For X direction shears,
+<em>x degrees</em> is measured relative to the Y axis, and similarly,
+for Y direction shears <em>y degrees</em> is measured relative to the X
+axis.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Empty triangles left over from shearing the image are filled with the
+color defined as <strong>background</strong> (class <strong>backgroundColor</strong>).
+The color is specified using the format described under the
+<strong>-fill</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -silent
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>operate silently</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-size"></a>-size <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to specify the width and height of raw images whose
+dimensions are unknown such as <strong>GRAY</strong>, <strong>RGB</strong>, or
+<strong>CMYK</strong>. In addition to width and height, use <strong>-size</strong> with an
+offset to skip any header information in the image or tell the number
+of colors in a <strong>MAP</strong> image file, (e.g. -size 640x512+256).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For Photo CD images, choose from these sizes:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 192x128
+ 384x256
+ 768x512
+ 1536x1024
+ 3072x2048
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Finally, use this option to choose a particular resolution layer of a JBIG
+or JPEG image (e.g. -size 1024x768).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-snaps"></a>-snaps <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>number of screen snapshots</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option
+to grab more than one image from the X server screen, to create
+an animation sequence.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-solarize"></a>-solarize <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>negate all pixels above the threshold level</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <em>factor</em> as the
+percent threshold of the intensity (0 - 99.9%).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option produces a <em>solarization</em> effect seen when exposing a
+photographic film to light during the development process.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-spread"></a>-spread <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image pixels by a random amount</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>Amount</em> defines the size of the neighborhood around each pixel to
+choose a candidate pixel to swap.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-stegano"></a>-stegano <i>&lt;offset&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>hide watermark within an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use an offset to start the image hiding some number of pixels from the
+beginning of the image. Note this offset and the image size. You will
+need this information to recover the steganographic image
+(e.g. display -size 320x256+35 stegano:image.png).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-stereo"></a>-stereo
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite two images to create a stereo anaglyph</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The left side of the stereo pair is saved as the red channel of the output
+image. The right side is saved as the green channel. Red-green stereo
+glasses are required to properly view the stereo image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-strip"></a>-strip
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+All embedded profiles and text attributes are stripped from the image.
+This is useful for images used for the web, or when output files need
+to be as small as possible</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Be careful not to use this option to remove author, copyright, and
+license information that you are required to retain when redistributing
+an image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-stroke"></a>-stroke <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when stroking a graphic primitive</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-draw</strong> for further details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-strokewidth"></a>-strokewidth <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the stroke width</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-draw</strong> for further details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-swirl"></a>-swirl <i>&lt;degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>swirl image pixels about the center</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>Degrees</em> defines the tightness of the swirl.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-text-font"></a>-text-font <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>font for writing fixed-width text</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point <em>Courier</em>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can tag a font to specify whether it is a PostScript, TrueType, or
+X11 font. For example, <tt>Courier.ttf</tt> is a TrueType font
+and <tt>x:fixed</tt> is X11.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-threshold"></a>-threshold <i>&lt;value&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>threshold the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Modify the image such that any pixel sample with an intensity value
+greater than the threshold is assigned the maximum intensity (white), or
+otherwise is assigned the minimum intensity (black). If a percent prefix
+is applied, then the threshold is a percentage of the available range.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+To efficiently create a black and white image from a color image, use</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -threshold 50% in.png out.png
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The optimum threshold value depends on the nature of the image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">In order to threshold individual channels, use the <strong>-operator</strong>
+subcommand with it's <strong>Threshold</strong>, <strong>Threshold-White</strong>, or
+<strong>Threshold-Black</strong> options.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-thumbnail"></a>-thumbnail <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-thumbnail</strong> command resizes the image as quickly as
+possible, with more concern for speed than resulting image quality.
+Regardless, resulting image quality should be acceptable for many
+uses. It is primarily intended to be used to generate smaller
+versions of the image, but may also be used to enlarge the image. The
+<strong>-thumbnail</strong> <strong>geometry</strong> argument observes the same syntax
+and rules as it does for <strong>-resize</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tile image when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>layout of images [<em>montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-title"></a>-title <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign title to displayed image [<em>animate, display, montage</em>]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to assign a specific title to the image. This is
+assigned to the image window and is typically displayed in the window
+title bar. Optionally you can include the image filename, type,
+width, height, Exif data, or other image attribute by embedding
+special format characters described under the <strong>-format</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -title "%m:%f %wx%h"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+produces an image title of <tt>MIFF:bird.miff 512x480</tt> for an image
+titled <tt>bird.miff</tt> and whose width is 512 and height is 480.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-transform"></a>-transform
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option applies the transformation matrix from a previous
+<strong>-affine</strong> option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -affine 2,2,-2,2,0,0 -transform bird.ppm bird.jpg
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-transparent"></a>-transparent <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-treedepth"></a>-treedepth <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Normally, this integer value is zero or one. A value of zero or one
+causes the use of an optimal tree depth for the color reduction
+algorithm</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+An optimal depth generally allows the best representation of the source
+image with the fastest computational speed and the least amount of memory.
+However, the default depth is inappropriate for some images. To assure
+the best representation, try values between 2 and 8 for this parameter.
+Refer to
+<a href="quantize.html">quantize</a> for more details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-colors</strong> or <strong>-monochrome</strong> option, or writing to an image
+format which requires color reduction, is required for this option to
+take effect.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-trim"></a>-trim
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option removes any edges that are exactly the same color as the
+corner pixels. Use <strong>-fuzz</strong> to make <strong>-trim</strong> remove edges that
+are nearly the same color as the corner pixels.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-type"></a>-type <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from:
+<strong>Bilevel</strong>, <strong>Grayscale</strong>, <strong>Palette</strong>,
+<strong>PaletteMatte</strong>, <strong>TrueColor</strong>, <strong>TrueColorMatte</strong>,
+<strong>ColorSeparation</strong>, <strong>ColorSeparationMatte</strong>, or <strong>Optimize</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Normally, when a format supports different subformats such as bilevel,
+grayscale, palette, truecolor, and truecolor+alpha, the encoder will try
+to choose a suitable subformat based on the nature of the image. The
+<strong>-type</strong> option may be used to tailor the output subformat. By
+default the output subformat is based on readily available image
+information and is usually similar to the input format.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <tt>-type Optimize</tt> in order to enable inspecting all pixels
+(if necessary) in order to find the most efficient subformat. Inspecting
+all of the pixels may be slow for very large images, particularly if they
+are stored in a disk cache. If an RGB image contains only gray pixels,
+then every pixel in the image must be inspected in order to decide that
+the image is actually grayscale!</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Sometimes a specific subformat is desired. For example, to force a JPEG
+image to be written in TrueColor RGB format even though only gray pixels
+are present, use</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert bird.pgm -type TrueColor bird.jpg
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Similarly, using <tt>-type TrueColorMatte</tt> will force the encoder to
+write an alpha channel even though the image is opaque, if the output
+format supports transparency.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Some pseudo-formats (e.g. the XC format) will respect the requested
+type if it occurs previously on the command line. For example, to obtain
+a DirectClass solid color canvas image rather than PsuedoClass, use</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -size 640x480 -type TrueColor xc:red red.miff
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Likewise, specify <strong>-type</strong> <strong>Bilevel</strong>, <strong>Grayscale</strong>,
+<strong>TrueColor</strong>, or <strong>TrueColorMatte</strong> prior to reading a Postscript
+(or PDF file) in order to influence the type of image that Ghostcript
+returns. Reading performance will be dramatically improved for
+black/white Postscript if <strong>Bilevel</strong> is specified, and will be
+considerably faster if <strong>Grayscale</strong> is specified.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-update"></a>-update <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+detect when image file is modified and redisplay.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Suppose that while you are displaying an image the file that is currently
+displayed is over-written.
+<strong>display</strong> will automatically detect that
+the input file has been changed and update the displayed image accordingly.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-units"></a>-units <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the units of image resolution</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from: <strong>Undefined</strong>, <strong>PixelsPerInch</strong>, or
+<strong>PixelsPerCentimeter</strong>. This option is normally used in conjunction
+with the <strong>-density</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-unsharp"></a>-unsharp <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+&lt;amount&gt;</i>}<i></i>{<i>+&lt;threshold&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image with an unsharp mask operator</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-unsharp</strong> option sharpens an image. The image is convolved
+with a Gaussian operator of the given radius and standard deviation
+(sigma). For reasonable results, radius should be larger than sigma. Use
+a radius of 0 to have the method select a suitable radius.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The parameters are:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>radius</dt>
+<dd>
+The radius of the Gaussian, in pixels, not counting the center pixel (default 0).
+</dd>
+<dt>sigma</dt>
+<dd>
+The standard deviation of the Gaussian, in pixels (default 1.0).
+</dd>
+<dt>amount</dt>
+<dd>
+The percentage of the difference between the original and the blur image that
+is added back into the original (default 1.0).
+</dd>
+<dt>threshold</dt>
+<dd>
+The threshold, as a fraction of MaxRGB, needed to apply the difference
+amount (default 0.05).
+</dd>
+</dl>
+</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -use-pixmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use the pixmap</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-verbose"></a>-verbose
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This information is printed: image scene number; image name; image size;
+the image class (<em>DirectClass</em> or <em>PseudoClass</em>); the total
+number of unique colors; and the number of seconds to read and transform
+the image. If the image is <em>DirectClass</em>, the total number of unique
+colors is not displayed unless <strong>-verbose</strong> is specified twice since
+it may take quite a long time to compute, particularly for deep images.
+If the image is <em>PseudoClass</em> then its pixels are defined by indexes
+into a colormap. If the image is <em>DirectClass</em> then each pixel
+includes a complete and independent color specification.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If <strong>-colors</strong> is also specified, the total unique colors in the image
+and color reduction error values are printed. Refer to <a href="quantize.html">quantize</a>
+for a description of these values.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-version"></a>-version
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -view <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>FlashPix viewing parameters</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-virtual-pixel"></a>-virtual-pixel <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify contents of "virtual pixels"</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option
+defines "virtual pixels" for use in operations that can access pixels outside
+the boundaries of an image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from these methods:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>Constant</dt>
+<dd>
+Use the image background color.
+</dd>
+<dt>Edge</dt>
+<dd>
+Extend the edge pixel toward infinity (default).
+</dd>
+<dt>Mirror</dt>
+<dd>
+Mirror the image.
+</dd>
+<dt>Tile</dt>
+<dd>
+Tile the image.
+</dd>
+</dl>
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option affects operations that use
+virtual pixels such as <strong>-blur</strong>, <strong>-sharpen</strong>, <strong>-wave</strong>, etc.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-visual"></a>-visual <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>animate images using this X visual type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from these visual classes:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ StaticGray
+ GrayScale
+ StaticColor
+ PseudoColor
+ TrueColor
+ DirectColor
+ default
+ visual id
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The X server must support the visual you choose, otherwise an error occurs.
+If a visual is not specified, the visual class that can display the most
+simultaneous colors on the default screen is chosen.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -watermark <i>&lt;brightness&gt;x&lt;saturation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>percent brightness and saturation of a watermark</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-wave"></a>-wave <i>&lt;amplitude&gt;x&lt;wavelength&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>alter an image along a sine wave</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <em>amplitude</em> and <em>wavelength</em>
+of the wave.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-white-point"></a>-white-point <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-white-threshold"></a>-white-threshold <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels above the threshold become white</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>-white-threshold</strong> to set pixels with values above the specified
+threshold to maximum value (white). If only one value is supplied, or the
+red, green, and blue values are identical, then intensity thresholding is
+used. If the color threshold values are not identical then channel-based
+thresholding is used, and color distortion will occur. Specify a negative
+value (e.g. -1) if you want a channel to be ignored but you do want to
+threshold a channel later in the list. If a percent (%) symbol is
+appended, then the values are treated as a percentage of maximum
+range.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-window"></a>-window <i>&lt;id&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image the background of a window</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>id</em> can be a window id or name. Specify <strong>root</strong> to
+select X's root window as the target window.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default the image is tiled onto the background of the target
+window. If <strong>backdrop</strong> or <strong>-geometry</strong> are
+specified, the image is surrounded by the background color. Refer to
+<strong>X RESOURCES</strong> for details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The image will not display on the root window if the image has more
+unique colors than the target window colormap allows. Use
+<strong>-colors</strong> to reduce the number of colors.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -window-group
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the window group</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-write"></a>-write <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write an intermediate image [<em>convert, composite</em>]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The current image is written to the specified filename and then
+processing continues using that image. The following is an example of how
+several sizes of an image may be generated in one command (repeat as
+often as needed):</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert input.jpg -resize 50% -write input50.jpg \
+ -resize 25% input25.jpg
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-write"></a>-write <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write the image to a file [<em>display</em>]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If <em>filename</em> already exists, you will be prompted as to whether it should
+be overwritten.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, the image is written in the format that it was read in as.
+To specify a particular image format, prefix <em>filename</em> with the
+image type and a colon (e.g., ps:image) or specify the image type as
+the filename suffix (e.g., image.ps). Specify file as - for standard
+output. If file has the extension <strong>.Z</strong> or <strong>.gz</strong>, the file
+size is <strong>compressed</strong> using compress or <strong>gzip</strong>
+respectively. Precede the image file name with | to pipe to a system
+command.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>-compress</strong> to specify the type of image compression.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The equivalent X resource for this option is
+<strong>writeFilename</strong> (class <strong>WriteFilename</strong>).
+See
+<a href="#xres">X Resources</a>
+for details.</font></td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="envi"></a>Environment
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ COLUMNS
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Output screen width. Used when formatting text for the screen. Many
+Unix systems keep this shell variable up to date, but it may need to be
+explicitly exported in order for GraphicsMagick to see it.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ DISPLAY
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>X11 display ID (host, display number, and screen in the form
+hostname:display.screen).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ HOME
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Location of user's home directory. GraphicsMagick searches for
+configuration files in $HOME/.magick if the directory exists. See
+<strong>MAGICK_CODER_MODULE_PATH</strong>, <strong>MAGICK_CONFIGURE_PATH</strong>, and
+<strong>MAGICK_FILTER_MODULE_PATH</strong> if more flexibility is needed.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_ACCESS_MONITOR
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>When set to <strong>TRUE</strong>, command line monitor mode (enabled by
+<strong>-monitor</strong>) will also show files accessed (including temporary
+files) and any external commands which are executed. This is useful
+for debugging, but also illustrates arguments made available to an
+access handler registered by the
+<strong>MagickSetConfirmAccessHandler()</strong> C library function.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_CODER_STABILITY
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>The minimum coder stability level before it will be used. The
+available levels are <strong>PRIMARY</strong>, <strong>STABLE</strong>, <strong>UNSTABLE</strong>,
+and <strong>BROKEN</strong>. The default minimum level is <strong>UNSTABLE</strong>,
+which means that all available working coders will be used. The
+purpose of this option is to reduce the security exposure (or apparent
+complexity) due to the huge number of formats supported. Coders at the
+<strong>PRIMARY</strong> level are commonly used formats with very well
+maintained implementations. Coders at the <strong>STABLE</strong> level are
+reasonably well maintained but represent less used formats. Coders at
+the <strong>UNSTABLE</strong> level either have weak implementations, the file
+format itself is weak, or the probability the coder will be needed is
+vanishingly small. Coders at the <strong>BROKEN</strong> level are known to
+often not work properly or might not be useful in their current state
+at all.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_CODER_MODULE_PATH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Search path to use when searching for image format coder modules.
+This path allows the user to arbitrarily extend the image formats
+supported by GraphicsMagick by adding loadable modules to an arbitrary
+location rather than copying them into the GraphicsMagick installation
+directory. The formatting of the search path is similar to operating
+system search paths (i.e. colon delimited for Unix, and semi-colon
+delimited for Microsoft Windows). This user specified search path is used
+before trying the default search path.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_CONFIGURE_PATH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Search path to use when searching for configuration (.mgk) files.
+The formatting of the search path is similar to operating system search
+paths (i.e. colon delimited for Unix, and semi-colon delimited for
+Microsoft Windows). This user specified search path is used before trying
+the default search path.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_DEBUG
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Debug options (see <strong>-debug</strong> for details). Setting debug
+options via an environment variable is currently necessary to see the
+complete initialization process.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_FILTER_MODULE_PATH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Search path to use when searching for filter process modules
+(invoked via <strong>-process</strong>). This path allows the user to arbitrarily
+extend GraphicsMagick's image processing functionality by adding loadable
+modules to an arbitrary location rather than copying them into the
+GraphicsMagick installation directory. The formatting of the search path
+is similar to operating system search paths (i.e. colon delimited for
+Unix, and semi-colon delimited for Microsoft Windows). This user
+specified search path is used before trying the default search path.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_GHOSTSCRIPT_PATH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>For Microsoft Windows, specify the path to the Ghostscript
+installation rather than searching for it via the Windows registry.
+This helps in case Ghostscript is not installed via the Ghostscript
+Windows installer or the user wants more control over the Ghostscript
+used.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_HOME
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Path to top of GraphicsMagick installation directory. Only observed
+by "uninstalled" builds of GraphicsMagick which do not have their location
+hard-coded or set by an installer.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_MMAP_READ
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>If <strong>MAGICK_MMAP_READ</strong> is set to <strong>TRUE</strong>, GraphicsMagick
+will attempt to memory-map the input file for reading. This usually
+substantially improves repeated read performance since the file is
+already in memory after the first time it has been read. However,
+testing shows that performance may be reduced for files accessed for
+the first time since data is accessed via page-faults (upon first
+access) and many operating systems fail to do sequential read-ahead of
+memory mapped files, and particularly if those files are accessed over
+a network. If many large input files are read, then enabling this
+option may harm performance by overloading the operating system's VM
+system as it then needs to free unmapped pages and map new ones.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_IO_FSYNC
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>If <strong>MAGICK_IO_FSYNC</strong> is set to <strong>TRUE</strong>, then GraphicsMagick
+will request that the output file is fully flushed and synchronized to
+disk when it is closed. This incurs a performance penalty, but has the
+benefit that if the power fails or the system crashes, the file should be
+valid on disk. If image files are referenced from a database, then this
+option helps assure that the files referenced by the database are
+valid.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_IOBUF_SIZE
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>The amount of I/O buffering (in bytes) to use when reading and
+writing encoded files. The default is 16384, which is observed to work
+well for many cases. The best value for a local filesystem is usually the
+the native filesystem block size (e.g. 4096, 8192, or even 131,072 for
+ZFS) in order to minimize the number of physical disk I/O operations.
+I/O performance to files accessed over a network may benefit
+significantly by tuning this option. Larger values are not necessarily
+better (they may be slower!), and there is rarely any benefit from using
+values larger than 32768. Use convert's <strong>-verbose</strong> option in order
+to evaluate read and write rates in pixels per second while keeping in
+mind that the operating system will try to cache files in RAM.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_DISK
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum amount of disk space allowed for use by the pixel cache.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_FILES
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum number of open files.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_MAP
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum size of a memory mapped file allocation. A memory mapped
+file consumes memory when the file is accessed, although the system
+may reclaim such memory when needed.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_MEMORY
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum amount of memory to allocate from the heap.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_PIXELS
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum number of total pixels (image rows times image colums) to
+allow for any image which is requested to be created or read. This is
+useful to place a limit on how large an image may be. If the input
+image file has image dimensions larger than the pixel limit, then the
+image memory allocation is denied and an error is returned
+immediately. This is a per-image limit and does not limit the total
+number of pixels due to multiple image frames/pages (e.g. multi-page
+document or an animation).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_WIDTH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum pixel width of an image read, or created.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_HEIGHT
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum pixel height of an image read, or created.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_TMPDIR
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Path to directory where GraphicsMagick should write temporary
+files. The default is to use the system default, or the location set by
+<strong>TMPDIR</strong>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ TMPDIR
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>For POSIX-compatible systems (Unix-compatible), the path to the
+directory where all applications should write temporary files.
+Overridden by <strong>MAGICK_TMPDIR</strong> if it is set.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ TMP <i>or TEMP</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>For Microsoft Windows, the path to the directory where applications
+should write temporary files. Overridden by <strong>MAGICK_TMPDIR</strong> if it
+is set.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ OMP_NUM_THREADS
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>As per the OpenMP standard, this specifies the number of threads to
+use in parallel regions. Some compilers default the number of threads to
+use to the number of processor cores available while others default to
+just one thread. See the OpenMP specification for other standard
+adjustments and your compiler's manual for vendor-specific settings.</td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="file"></a>Configuration Files
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>GraphicsMagick uses a number of XML format configuration files:
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ colors.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colors configuration file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ &lt;?xml version="1.0"?&gt;
+ &lt;colormap&gt;
+ &lt;color name="AliceBlue" red="240" green="248" blue="255"
+ compliance="SVG, X11, XPM" /&gt;
+ &lt;/colormap&gt;
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ delegates.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>delegates configuration file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ log.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>logging configuration file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ &lt;?xml version="1.0"?&gt;
+ &lt;magicklog&gt;
+ &lt;log events="None" /&gt;
+ &lt;log output="stdout" /&gt;
+ &lt;log filename="Magick-%d.log" /&gt;
+ &lt;log generations="3" /&gt;
+ &lt;log limit="2000" /&gt;
+ &lt;log format="%t %r %u %p %m/%f/%l/%d:\n %e" /&gt;
+ &lt;/magicklog&gt;
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ modules.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>loadable modules configuration file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ &lt;?xml version="1.0"?&gt;
+ &lt;modulemap&gt;
+ &lt;module magick="8BIM" name="META" /&gt;
+ &lt;/modulemap&gt;
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ type.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>master type (fonts) configuration file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ &lt;?xml version="1.0"?&gt;
+ &lt;typemap&gt;
+ &lt;<strong></strong>include file="type-windows.mgk" /&gt;
+ &lt;type
+ name="AvantGarde-Book"
+ fullname="AvantGarde Book"
+ family="AvantGarde"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/local/share/ghostscript/fonts/a010013l.afm"
+ glyphs="/usr/local/share/ghostscript/fonts/a010013l.pfb"
+ /&gt;
+ &lt;/typemap&gt;
+</pre></font></td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="auth"></a>Authors
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<em>
+John Cristy,<br>
+Bob Friesenhahn,<br>
+Glenn Randers-Pehrson,<br>
+William Radcliff,<br>
+Leonard Rosenthol,<br>
+Lars Ruben Skyum,<br>
+Jaroslav Fojtik,<br>
+and many more.
+</em>
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="copy"></a>Copyright
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Copyright (C) 2002 - 2017 GraphicsMagick Group.</strong> Additional
+copyrights apply. Please see see
+http://www.GraphicsMagick.org/Copyright.html for details.
+<p>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<HR>
+
+[<a href="index.html">Home</a>] [<a href="utilities.html">Utilities Index</a>]
+<BR>
+<p align=center <a href="Copyright.html">Copyright &#169; GraphicsMagick Group 2002 - 2017</a></p></td>
+</tr></table>
+</body></html>
diff --git a/www/Hg.html b/www/Hg.html
new file mode 100644
index 0000000..4138a80
--- /dev/null
+++ b/www/Hg.html
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Mercurial</title>
+<meta content="GraphicsMagick is a robust collection of tools and libraries to read, write, and manipulate an image in any of the more popular image formats including GIF, JPEG, PNG, PDF, and Photo CD. With GraphicsMagick you can create GIFs dynamically making it suitable for Web applications. You can also resize, rotate, sharpen, color reduce, or add special effects to an image and save your completed work in the same or differing image format. " name="description" />
+<meta content="GraphicsMagick, PerlMagick, visualization, image processing, software development, simulation, image, software, Magick++" name="keywords" />
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-mercurial">
+<h1 class="title">GraphicsMagick Mercurial</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#what-is-mercurial" id="id1">What is Mercurial?</a></li>
+<li><a class="reference internal" href="#web-access" id="id2">Web Access</a></li>
+<li><a class="reference internal" href="#cloning-the-mercurial-repository" id="id3">Cloning the Mercurial Repository</a></li>
+<li><a class="reference internal" href="#selecting-a-version-of-the-code" id="id4">Selecting a version of the code</a></li>
+<li><a class="reference internal" href="#updating-from-the-mercurial-repository" id="id5">Updating from the Mercurial Repository</a></li>
+<li><a class="reference internal" href="#mercurial-software" id="id6">Mercurial Software</a></li>
+<li><a class="reference internal" href="#mercurial-for-graphicsmagick-developers" id="id7">Mercurial for GraphicsMagick Developers</a></li>
+<li><a class="reference internal" href="#ssh-public-keys-for-hg-graphicsmagick-org" id="id8">SSH Public Keys For hg.GraphicsMagick.org</a></li>
+<li><a class="reference internal" href="#email-notifications" id="id9">Email Notifications</a></li>
+<li><a class="reference internal" href="#rsync-the-repository" id="id10">Rsync The Repository</a></li>
+<li><a class="reference internal" href="#mercurial-topics" id="id11">Mercurial Topics</a></li>
+</ul>
+</div>
+<p>The GraphicsMagick source code is now available via <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a>.
+Previously GraphicsMagick source control was via CVS, but now the
+repository has been migrated to <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a>. <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a> is a
+convenient way for developers from around the country or world to
+download the GraphicsMagick source, fix bugs, or add new features.
+Due to the way <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a> works, it may also be used to manage local
+changes to GraphicsMagick.</p>
+<div class="section" id="what-is-mercurial">
+<h1><a class="toc-backref" href="#id1">What is Mercurial?</a></h1>
+<p><a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a> (also known as <cite>Hg</cite> due to the abbreviation for Mercury in
+the periodic table of the elements) is a modern source control system
+which provides anyone who clones a repository with a stand-alone local
+repository containing the full development history and the ability to
+select any version of the code. Since the local repository is
+fully-functional, you may use the same repository to manage your local
+changes to GraphicsMagick code and you may use the repository to share
+your changes with others.</p>
+</div>
+<div class="section" id="web-access">
+<h1><a class="toc-backref" href="#id2">Web Access</a></h1>
+<p>The <a class="reference external" href="http://hg.code.sf.net/p/graphicsmagick/code/">GraphicsMagick repository at SourceForge</a> web interface is
+available which may be used to interactively view the latest versions
+of files, or the changes to files, using your web browser.</p>
+</div>
+<div class="section" id="cloning-the-mercurial-repository">
+<h1><a class="toc-backref" href="#id3">Cloning the Mercurial Repository</a></h1>
+<p>To get the tree and place it in a sub-directory of your current working
+directory, issue the command:</p>
+<pre class="literal-block">
+hg clone http://hg.code.sf.net/p/graphicsmagick/code GM
+</pre>
+</div>
+<div class="section" id="selecting-a-version-of-the-code">
+<h1><a class="toc-backref" href="#id4">Selecting a version of the code</a></h1>
+<p>By default the cloned directory is populated with files from the
+<cite>default</cite> (i.e. head) branch of the code.</p>
+<p>If you require a specific release of GraphicsMagick (e.g. 1.3.23), you may select it like:</p>
+<pre class="literal-block">
+hg update -r GraphicsMagick-1_3_23
+</pre>
+<p>or if you require a specific branch of GraphicsMagick (e.g. 1.3), you may use:</p>
+<pre class="literal-block">
+hg update -r GraphicsMagick-1_3
+</pre>
+<p>or you may request the files which were current on a specific date:</p>
+<pre class="literal-block">
+hg update -d 2009-01-14
+</pre>
+<p>Use:</p>
+<pre class="literal-block">
+hg branches
+</pre>
+<p>to see the available branches, and:</p>
+<pre class="literal-block">
+hg tags
+</pre>
+<p>to see the available release tags.</p>
+</div>
+<div class="section" id="updating-from-the-mercurial-repository">
+<h1><a class="toc-backref" href="#id5">Updating from the Mercurial Repository</a></h1>
+<p>To pull more changes from the repository, execute:</p>
+<pre class="literal-block">
+hg pull
+</pre>
+<p>and to make them visible in your files (via a merge), execute:</p>
+<pre class="literal-block">
+hg update
+</pre>
+<p>or just:</p>
+<pre class="literal-block">
+hg pull -u
+</pre>
+<p>The latter pulls down any updates into your local repository and
+automatically does a merge.</p>
+</div>
+<div class="section" id="mercurial-software">
+<h1><a class="toc-backref" href="#id6">Mercurial Software</a></h1>
+<p>The best place to look for the latest version of Mercurial (<cite>Hg</cite>) is
+at the <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a> web site. Most free operating systems (e.g. Linux,
+OpenSolaris, and *BSD) will offer a version of Mercurial as an
+installable package and it may already be installed on your system.
+We recommend use of <a class="reference external" href="https://tortoisehg.bitbucket.io/">TortoiseHg</a> on Microsoft Windows systems since it
+provides a very nice graphical interface. <a class="reference external" href="https://tortoisehg.bitbucket.io/">TortoiseHg</a> is also
+available on Linux and other systems.</p>
+</div>
+<div class="section" id="mercurial-for-graphicsmagick-developers">
+<h1><a class="toc-backref" href="#id7">Mercurial for GraphicsMagick Developers</a></h1>
+<p>Since <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a> is a distributed revision control system, you may
+clone the GraphicsMagick repository and work for days or weeks (making
+your own local commits) before you decide to push some or all of your
+changes to the GraphicsMagick development repository. GraphicsMagick
+developers first commit changes to their own local respository, then
+they push their changes to the GraphicsMagick development repository
+at hg.graphicsmagick.org, later on (after testing and possible fixes)
+I will push the changes to the stable repository at SourceForge.
+Pushes to the stable repository at SourceForge should occur at least
+as often as source code snapshots are produced.</p>
+<p>The repository hierarchy is as follows:</p>
+<ol class="arabic simple">
+<li>Local</li>
+</ol>
+<blockquote>
+The developer makes any local changes and commits what he likes in his
+own repository. It is best to commit often and whenever all the
+files have been updated to implement a coherent change or feature
+(including the ChangeLog file!) since <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a> stores related
+changes as a changeset along with the change message you enter.
+When you push your repository, these changesets and messages are
+preserved.</blockquote>
+<ol class="arabic simple" start="2">
+<li>Unstable</li>
+</ol>
+<blockquote>
+<p>The unstable development repository is available via ssh at
+&quot;<a class="reference external" href="ssh://yourid&#64;hg.GraphicsMagick.org//hg/GraphicsMagick">ssh://yourid&#64;hg.GraphicsMagick.org//hg/GraphicsMagick</a>&quot;.</p>
+<p>Where <cite>yourid</cite> is the Unix user ID on the GraphicsMagick server.
+The <cite>yourid&#64;</cite> part may left out if your client system uses the same
+user ID as on the GraphicsMagick server.</p>
+</blockquote>
+<ol class="arabic simple" start="3">
+<li>Stable</li>
+</ol>
+<blockquote>
+The stable repository is available via http at
+&quot;<a class="reference external" href="http://hg.code.sf.net/p/graphicsmagick/code">http://hg.code.sf.net/p/graphicsmagick/code</a>&quot;. Any changes in the
+unstable development repository are pushed to the stable repository
+(by the developer responsible for this role) once any necessary
+adjustments have been made, documentation files have been generated,
+and the software test suite has passed on at least one machine.</blockquote>
+<p>To build your local development repository (as quickly as possible),
+you may use these steps:</p>
+<ol class="arabic">
+<li><p class="first">Clone the stable respository at SourceForge:</p>
+<pre class="literal-block">
+hg clone http://hg.code.sf.net/p/graphicsmagick/code GM
+</pre>
+</li>
+<li><p class="first">Adjust your local repository path default to use the unstable repository.</p>
+<p>Edit .hg/hgrc in your local repository so that it contains:</p>
+<pre class="literal-block">
+[paths]
+default = ssh://yourid&#64;hg.GraphicsMagick.org//hg/GraphicsMagick
+</pre>
+<p>where <cite>yourid</cite> is the Unix user ID on the GraphicsMagick server.</p>
+</li>
+<li><p class="first">Pull any additional pending updates from the unstable repository:</p>
+<pre class="literal-block">
+hg pull -u
+</pre>
+</li>
+</ol>
+<p>Please note that when ssh access is used, Mercurial uncompresses any
+data and sends it in uncompressed form. Mercurial expects that
+compression will be enabled in ssh when needed. One way to enable ssh
+compression is to put this in your local .hgrc:</p>
+<pre class="literal-block">
+[ui]
+ssh = ssh -C
+</pre>
+<p>but ssh also provides its own way to enable compression on a
+site-by-site basis (e.g. via .ssh/config). For example an entry in
+.ssh/config will enable use of compression:</p>
+<pre class="literal-block">
+Host hg.code.sf.net
+ Compression yes
+</pre>
+</div>
+<div class="section" id="ssh-public-keys-for-hg-graphicsmagick-org">
+<h1><a class="toc-backref" href="#id8">SSH Public Keys For hg.GraphicsMagick.org</a></h1>
+<p>In December, 2015, the services provided by hg.GraphicsMagick.org
+(more formally known as src.GraphicsMagick.org) where moved to a new
+server (using OpenSSH 7.1.2 at the time), with new server keys.
+Developers accessing this server via ssh may be notified about a ssh
+key change. For reference, these are the server's ssh public keys:</p>
+<p>DSS (DSA):</p>
+<pre class="literal-block">
+ssh-dss AAAAB3NzaC1kc3MAAACBANZAsDZ9fUWQNwUoRw8HoNl8aLLs97KmyiaA6mSPeM1NeQKrxk0PAFEXMR05CNcZHSyopUx6B8PuTWE4+4rDhFCw7J0JkfFS4uIG3bu3YCRqQrg2k4VsDw60zK9sNum5BcLEWd+qs8X7DrEff5fGmXkc8IdMXPgHTzaJWCT9YJU1AAAAFQCJaFq4/7FqHcHm5abhW5qJyH0RgQAAAIEAgv6s3gfB8p/Elf0ZcIZ5eITCpI9aZFaSLSeKHMmhYps1uMuZ9LtWjZ11cotcuOh0tlwGUixlu/5soZqX6VbnJAuyvfI+7WSUFuJmRjsbXJVCBuSPZ7YgMNuLYlLst7sZLCs5hU61jxnaR2zmkUjDWP4GWROC6AYZXlbJX1qRJ7YAAACBAMsIbVVgz/aP95yCPk1Pw0FjoL5t6C3BpxdA9aiIFBMg14ElaHh+gaXQoZfjAuafZ8pc5woYtQLLkzinCQnmvH/EqqYCe+Fu7jcsYU7oWUXG1O9ZBKI7QZkeCTaYMXIWBplgVD+tkRpH/gxn5iweNMM9e43qPB0b2JYObliqD1E9 root&#64;src
+</pre>
+<p>RSA:</p>
+<pre class="literal-block">
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1IuJDYT85qz/w6+vn5hkpzM5Ju5dsMeJD9GnATj3op5dhBWyfbaJpS7yyK2Vhhz26GBUvUtO3LGm0dQvdj83P3DX3aUuzfnC3Bc9dWeARomQPtDy9MfDikD6kqjD9/Lemgvv8I4Na9vUEmYvXUpTrtawJ4S7A7IctPnvKLPGA5+qY5XzMSE0wcOSBdbeV1PAIDOXYH2hKakZwtxXlvfTv6CZphz/jG5nmf+/Zlkr4yopNvPFbtd3vbaaqSuCoGHXKfmpRko2gXf6EGF92wXzbsE1tW3AkSJ2xdhFHRNmQEu2y9F1l9zb8IETBtKMWRJWAsPPpUSkht0DRsTXt/f+Zw== root&#64;src
+</pre>
+<p>ECDSA:</p>
+<pre class="literal-block">
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOrGQ6tjmZvm8w+GP7yLFJ1/vkImKkpXv7kPNxA0+Sfx6WCqAjV0pWP5MVCraP8SNbphL8jiS/x3WADXlf+R2KQ= root&#64;src
+</pre>
+<p>ED25519:</p>
+<pre class="literal-block">
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAtwIcJEBiSUWsB2sydInR76gE84Jp1rxmc8lTGPg5cB root&#64;src
+</pre>
+</div>
+<div class="section" id="email-notifications">
+<h1><a class="toc-backref" href="#id9">Email Notifications</a></h1>
+<p>An email notification is sent to the <a class="reference external" href="https://lists.sourceforge.net/lists/listinfo/graphicsmagick-commit">graphicsmagick-commit</a> mailing
+list at SourceForge whenever a change is submitted to the development
+(unstable) repository. Subscribe to this list if you would like to be
+notified by email of changes when they occur.</p>
+</div>
+<div class="section" id="rsync-the-repository">
+<h1><a class="toc-backref" href="#id10">Rsync The Repository</a></h1>
+<p>It is possible to use the <a class="reference external" href="http://rsync.samba.org/">rsync</a> program to make a copy of the
+GraphicsMagick Mercurial repository. Using <a class="reference external" href="http://rsync.samba.org/">rsync</a> might be faster for
+the initial repository checkout, but the copied repository might not
+be coherent if it was updated while the <a class="reference external" href="http://rsync.samba.org/">rsync</a> was in progress. If
+there is any problem, just execute the same <a class="reference external" href="http://rsync.samba.org/">rsync</a> command again
+without deleting any files and the remaining changes (updated files)
+will be transferred. To use <a class="reference external" href="http://rsync.samba.org/">rsync</a> to copy the repository do:</p>
+<pre class="literal-block">
+mkdir -p GM
+rsync -avPSz hg.code.sf.net::p/graphicsmagick/code/ GM/
+</pre>
+<p>Rsync will not checkout a working set of files. To accomplish that
+do:</p>
+<pre class="literal-block">
+cd GM
+hg update
+</pre>
+</div>
+<div class="section" id="mercurial-topics">
+<h1><a class="toc-backref" href="#id11">Mercurial Topics</a></h1>
+<ul class="simple">
+<li><a class="reference external" href="https://www.mercurial-scm.org/wiki/MergeToolConfiguration">Merge Tool Configuration</a></li>
+<li><a class="reference external" href="https://www.mercurial-scm.org/wiki/TipsAndTricks#Keep_.22My.22_or_.22Their.22_files_when_doing_a_merge">Keep &quot;My&quot; or &quot;Their&quot; files when doing a merge</a></li>
+</ul>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2012 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/Hg.rst b/www/Hg.rst
new file mode 100644
index 0000000..dca73b8
--- /dev/null
+++ b/www/Hg.rst
@@ -0,0 +1,268 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=======================================
+GraphicsMagick Mercurial
+=======================================
+
+.. meta::
+ :description: GraphicsMagick is a robust collection of tools and libraries to read,
+ write, and manipulate an image in any of the more popular
+ image formats including GIF, JPEG, PNG, PDF, and Photo CD.
+ With GraphicsMagick you can create GIFs dynamically making it
+ suitable for Web applications. You can also resize, rotate,
+ sharpen, color reduce, or add special effects to an image and
+ save your completed work in the same or differing image format.
+
+ :keywords: GraphicsMagick, PerlMagick, visualization, image
+ processing, software development, simulation, image,
+ software, Magick++
+
+.. _Mercurial : https://www.mercurial-scm.org/
+.. _TortoiseHg : https://tortoisehg.bitbucket.io/
+.. _`GraphicsMagick repository at SourceForge` : http://hg.code.sf.net/p/graphicsmagick/code/
+
+.. contents::
+
+The GraphicsMagick source code is now available via Mercurial_.
+Previously GraphicsMagick source control was via CVS, but now the
+repository has been migrated to Mercurial_. Mercurial_ is a
+convenient way for developers from around the country or world to
+download the GraphicsMagick source, fix bugs, or add new features.
+Due to the way Mercurial_ works, it may also be used to manage local
+changes to GraphicsMagick.
+
+What is Mercurial?
+==================
+
+Mercurial_ (also known as `Hg` due to the abbreviation for Mercury in
+the periodic table of the elements) is a modern source control system
+which provides anyone who clones a repository with a stand-alone local
+repository containing the full development history and the ability to
+select any version of the code. Since the local repository is
+fully-functional, you may use the same repository to manage your local
+changes to GraphicsMagick code and you may use the repository to share
+your changes with others.
+
+Web Access
+=============
+
+The `GraphicsMagick repository at SourceForge`_ web interface is
+available which may be used to interactively view the latest versions
+of files, or the changes to files, using your web browser.
+
+Cloning the Mercurial Repository
+==================================
+
+To get the tree and place it in a sub-directory of your current working
+directory, issue the command::
+
+ hg clone http://hg.code.sf.net/p/graphicsmagick/code GM
+
+Selecting a version of the code
+========================================
+
+By default the cloned directory is populated with files from the
+`default` (i.e. head) branch of the code.
+
+If you require a specific release of GraphicsMagick (e.g. 1.3.23), you may select it like::
+
+ hg update -r GraphicsMagick-1_3_23
+
+or if you require a specific branch of GraphicsMagick (e.g. 1.3), you may use::
+
+ hg update -r GraphicsMagick-1_3
+
+or you may request the files which were current on a specific date::
+
+ hg update -d 2009-01-14
+
+Use::
+
+ hg branches
+
+to see the available branches, and::
+
+ hg tags
+
+to see the available release tags.
+
+Updating from the Mercurial Repository
+========================================
+
+To pull more changes from the repository, execute::
+
+ hg pull
+
+and to make them visible in your files (via a merge), execute::
+
+ hg update
+
+or just::
+
+ hg pull -u
+
+The latter pulls down any updates into your local repository and
+automatically does a merge.
+
+Mercurial Software
+==================
+
+The best place to look for the latest version of Mercurial (`Hg`) is
+at the Mercurial_ web site. Most free operating systems (e.g. Linux,
+OpenSolaris, and \*BSD) will offer a version of Mercurial as an
+installable package and it may already be installed on your system.
+We recommend use of TortoiseHg_ on Microsoft Windows systems since it
+provides a very nice graphical interface. TortoiseHg_ is also
+available on Linux and other systems.
+
+Mercurial for GraphicsMagick Developers
+========================================
+
+Since Mercurial_ is a distributed revision control system, you may
+clone the GraphicsMagick repository and work for days or weeks (making
+your own local commits) before you decide to push some or all of your
+changes to the GraphicsMagick development repository. GraphicsMagick
+developers first commit changes to their own local respository, then
+they push their changes to the GraphicsMagick development repository
+at hg.graphicsmagick.org, later on (after testing and possible fixes)
+I will push the changes to the stable repository at SourceForge.
+Pushes to the stable repository at SourceForge should occur at least
+as often as source code snapshots are produced.
+
+The repository hierarchy is as follows:
+
+1. Local
+
+ The developer makes any local changes and commits what he likes in his
+ own repository. It is best to commit often and whenever all the
+ files have been updated to implement a coherent change or feature
+ (including the ChangeLog file!) since Mercurial_ stores related
+ changes as a changeset along with the change message you enter.
+ When you push your repository, these changesets and messages are
+ preserved.
+
+2. Unstable
+
+ The unstable development repository is available via ssh at
+ "ssh://yourid@hg.GraphicsMagick.org//hg/GraphicsMagick".
+
+ Where `yourid` is the Unix user ID on the GraphicsMagick server.
+ The `yourid@` part may left out if your client system uses the same
+ user ID as on the GraphicsMagick server.
+
+3. Stable
+
+ The stable repository is available via http at
+ "http://hg.code.sf.net/p/graphicsmagick/code". Any changes in the
+ unstable development repository are pushed to the stable repository
+ (by the developer responsible for this role) once any necessary
+ adjustments have been made, documentation files have been generated,
+ and the software test suite has passed on at least one machine.
+
+To build your local development repository (as quickly as possible),
+you may use these steps:
+
+1. Clone the stable respository at SourceForge::
+
+ hg clone http://hg.code.sf.net/p/graphicsmagick/code GM
+
+2. Adjust your local repository path default to use the unstable repository.
+
+ Edit .hg/hgrc in your local repository so that it contains::
+
+ [paths]
+ default = ssh://yourid@hg.GraphicsMagick.org//hg/GraphicsMagick
+
+ where `yourid` is the Unix user ID on the GraphicsMagick server.
+
+3. Pull any additional pending updates from the unstable repository::
+
+ hg pull -u
+
+Please note that when ssh access is used, Mercurial uncompresses any
+data and sends it in uncompressed form. Mercurial expects that
+compression will be enabled in ssh when needed. One way to enable ssh
+compression is to put this in your local .hgrc::
+
+ [ui]
+ ssh = ssh -C
+
+but ssh also provides its own way to enable compression on a
+site-by-site basis (e.g. via .ssh/config). For example an entry in
+.ssh/config will enable use of compression::
+
+ Host hg.code.sf.net
+ Compression yes
+
+SSH Public Keys For hg.GraphicsMagick.org
+=========================================
+
+In December, 2015, the services provided by hg.GraphicsMagick.org
+(more formally known as src.GraphicsMagick.org) where moved to a new
+server (using OpenSSH 7.1.2 at the time), with new server keys.
+Developers accessing this server via ssh may be notified about a ssh
+key change. For reference, these are the server's ssh public keys:
+
+DSS (DSA)::
+
+ ssh-dss AAAAB3NzaC1kc3MAAACBANZAsDZ9fUWQNwUoRw8HoNl8aLLs97KmyiaA6mSPeM1NeQKrxk0PAFEXMR05CNcZHSyopUx6B8PuTWE4+4rDhFCw7J0JkfFS4uIG3bu3YCRqQrg2k4VsDw60zK9sNum5BcLEWd+qs8X7DrEff5fGmXkc8IdMXPgHTzaJWCT9YJU1AAAAFQCJaFq4/7FqHcHm5abhW5qJyH0RgQAAAIEAgv6s3gfB8p/Elf0ZcIZ5eITCpI9aZFaSLSeKHMmhYps1uMuZ9LtWjZ11cotcuOh0tlwGUixlu/5soZqX6VbnJAuyvfI+7WSUFuJmRjsbXJVCBuSPZ7YgMNuLYlLst7sZLCs5hU61jxnaR2zmkUjDWP4GWROC6AYZXlbJX1qRJ7YAAACBAMsIbVVgz/aP95yCPk1Pw0FjoL5t6C3BpxdA9aiIFBMg14ElaHh+gaXQoZfjAuafZ8pc5woYtQLLkzinCQnmvH/EqqYCe+Fu7jcsYU7oWUXG1O9ZBKI7QZkeCTaYMXIWBplgVD+tkRpH/gxn5iweNMM9e43qPB0b2JYObliqD1E9 root@src
+
+RSA::
+
+ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1IuJDYT85qz/w6+vn5hkpzM5Ju5dsMeJD9GnATj3op5dhBWyfbaJpS7yyK2Vhhz26GBUvUtO3LGm0dQvdj83P3DX3aUuzfnC3Bc9dWeARomQPtDy9MfDikD6kqjD9/Lemgvv8I4Na9vUEmYvXUpTrtawJ4S7A7IctPnvKLPGA5+qY5XzMSE0wcOSBdbeV1PAIDOXYH2hKakZwtxXlvfTv6CZphz/jG5nmf+/Zlkr4yopNvPFbtd3vbaaqSuCoGHXKfmpRko2gXf6EGF92wXzbsE1tW3AkSJ2xdhFHRNmQEu2y9F1l9zb8IETBtKMWRJWAsPPpUSkht0DRsTXt/f+Zw== root@src
+
+ECDSA::
+
+ ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOrGQ6tjmZvm8w+GP7yLFJ1/vkImKkpXv7kPNxA0+Sfx6WCqAjV0pWP5MVCraP8SNbphL8jiS/x3WADXlf+R2KQ= root@src
+
+ED25519::
+
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAtwIcJEBiSUWsB2sydInR76gE84Jp1rxmc8lTGPg5cB root@src
+
+
+Email Notifications
+===================
+
+.. _`graphicsmagick-commit` : https://lists.sourceforge.net/lists/listinfo/graphicsmagick-commit
+
+An email notification is sent to the `graphicsmagick-commit`_ mailing
+list at SourceForge whenever a change is submitted to the development
+(unstable) repository. Subscribe to this list if you would like to be
+notified by email of changes when they occur.
+
+Rsync The Repository
+====================
+
+.. _rsync : http://rsync.samba.org/
+
+It is possible to use the rsync_ program to make a copy of the
+GraphicsMagick Mercurial repository. Using rsync_ might be faster for
+the initial repository checkout, but the copied repository might not
+be coherent if it was updated while the rsync_ was in progress. If
+there is any problem, just execute the same rsync_ command again
+without deleting any files and the remaining changes (updated files)
+will be transferred. To use rsync_ to copy the repository do::
+
+ mkdir -p GM
+ rsync -avPSz hg.code.sf.net::p/graphicsmagick/code/ GM/
+
+Rsync will not checkout a working set of files. To accomplish that
+do::
+
+ cd GM
+ hg update
+
+Mercurial Topics
+====================
+
+* `Merge Tool Configuration <https://www.mercurial-scm.org/wiki/MergeToolConfiguration>`_
+* `Keep "My" or "Their" files when doing a merge <https://www.mercurial-scm.org/wiki/TipsAndTricks#Keep_.22My.22_or_.22Their.22_files_when_doing_a_merge>`_
+
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2012 - 2017
diff --git a/www/INSTALL-unix.html b/www/INSTALL-unix.html
new file mode 100644
index 0000000..2f79c01
--- /dev/null
+++ b/www/INSTALL-unix.html
@@ -0,0 +1,1009 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>UNIX/Cygwin/MinGW Compilation</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="unix-cygwin-mingw-compilation">
+<h1 class="title">UNIX/Cygwin/MinGW Compilation</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#archive-formats" id="id1">Archive Formats</a></li>
+<li><a class="reference internal" href="#build-configuration" id="id2">Build Configuration</a><ul>
+<li><a class="reference internal" href="#optional-features" id="id3">Optional Features</a></li>
+<li><a class="reference internal" href="#optional-packages-options" id="id4">Optional Packages/Options</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#building-under-cygwin" id="id5">Building under Cygwin</a></li>
+<li><a class="reference internal" href="#building-under-mingw-msys" id="id6">Building under MinGW &amp; MSYS</a><ul>
+<li><a class="reference internal" href="#cross-compilation-on-unix-linux-host" id="id7">Cross-compilation On Unix/Linux Host</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#dealing-with-configuration-failures" id="id8">Dealing with configuration failures</a></li>
+<li><a class="reference internal" href="#makefile-build-targets" id="id9">Makefile Build Targets</a></li>
+<li><a class="reference internal" href="#build-install" id="id10">Build &amp; Install</a></li>
+<li><a class="reference internal" href="#verifying-the-build" id="id11">Verifying The Build</a></li>
+</ul>
+</div>
+<div class="section" id="archive-formats">
+<h1><a class="toc-backref" href="#id1">Archive Formats</a></h1>
+<p>GraphicsMagick is distributed in a number of different archive formats.
+The source code must be extracted prior to compilation as follows:</p>
+<p>7z</p>
+<blockquote>
+<p>7-Zip archive format. The Z-Zip format may be extracted under Unix
+using '7za' from the P7ZIP package (<a class="reference external" href="http://p7zip.sourceforge.net/">http://p7zip.sourceforge.net/</a>).
+Extract similar to:</p>
+<pre class="literal-block">
+7za x GraphicsMagick-1.3.7z
+</pre>
+</blockquote>
+<p>.tar.bz2</p>
+<blockquote>
+<p>BZip2 compressed tar archive format. Requires that both the bzip2
+(<a class="reference external" href="http://www.bzip.org/">http://www.bzip.org/</a>) and tar programs to be available. Extract
+similar to:</p>
+<pre class="literal-block">
+bzip2 -d GraphicsMagick-1.3.tar.bz | tar -xvf -
+</pre>
+</blockquote>
+<p>.tar.gz</p>
+<blockquote>
+<p>Gzip compressed tar archive format. Requires that both the gzip
+(<a class="reference external" href="http://www.gzip.org/">http://www.gzip.org/</a>) and tar programs to be available. Extract
+similar to:</p>
+<pre class="literal-block">
+gzip -d GraphicsMagick-1.3.tar.gz | tar -xvf -
+</pre>
+</blockquote>
+<p>.tar.lz</p>
+<blockquote>
+<p>Lzip compressed tar archive format. Requires that both the lzip
+(<a class="reference external" href="http://lzip.nongnu.org/lzip.html">http://lzip.nongnu.org/lzip.html</a>) and tar programs to be
+available. Extract similar to:</p>
+<pre class="literal-block">
+lzip -d -c GraphicsMagick-1.3.tar.gz | tar -xvf -
+</pre>
+</blockquote>
+<p>.tar.xz</p>
+<blockquote>
+<p>LZMA compressed tar archive format. Requires that LZMA utils
+(<a class="reference external" href="http://tukaani.org/lzma/">http://tukaani.org/lzma/</a>) and tar programs to be available. Extract
+similar to:</p>
+<pre class="literal-block">
+xz -d GraphicsMagick-1.3.tar.xz | tar -xvf -
+</pre>
+</blockquote>
+<p>zip</p>
+<blockquote>
+<p>PK-ZIP archive format. Requires that the unzip program from Info-Zip
+(<a class="reference external" href="http://www.info-zip.org/UnZip.html">http://www.info-zip.org/UnZip.html</a>) be available. Extract similar to:</p>
+<pre class="literal-block">
+unzip GraphicsMagick-1.3.zip
+</pre>
+</blockquote>
+<p>The GraphicsMagick source code is extracted into a subdirectory
+similar to 'GraphicsMagick-1.3'. After the source code extracted,
+change to the new directory (using the actual directory name) using
+a command similar to:</p>
+<pre class="literal-block">
+cd GraphicsMagick-1.3
+</pre>
+</div>
+<div class="section" id="build-configuration">
+<h1><a class="toc-backref" href="#id2">Build Configuration</a></h1>
+<p>Use 'configure' to automatically configure, build, and install
+GraphicsMagick. The configure script may be executed from the
+GraphicsMagick source directory (e.g ./configure) or from a separate
+build directory by specifying the full path to configure (e.g.
+/src/GraphicsMagick-1.3/configure). The advantage of using a separate
+build directory is that multiple GraphicsMagick builds may share the
+same GraphicsMagick source directory while allowing each build to use a
+unique set of options. Using a separate directory also makes it easier
+to keep track of any files you may have edited.</p>
+<p>If you are willing to accept configure's default options (static
+build, 8 bits/sample), and build from within the source directory,
+type:</p>
+<pre class="literal-block">
+./configure
+</pre>
+<p>and watch the configure script output to verify that it finds everything
+that you think it should. If it does not, then adjust your environment
+so that it does.</p>
+<p>By default, 'make install' will install the package's files
+in '/usr/local/bin', '/usr/local/man', etc. You can specify an
+installation prefix other than '/usr/local' by giving 'configure'
+the option '--prefix=PATH'. This is valuable in case you don't have
+privileges to install under the default paths or if you want to install
+in the system directories instead.</p>
+<p>If you are not happy with configure's choice of compiler, compilation
+flags, or libraries, you can give 'configure' initial values for
+variables by specifying them on the configure command line, e.g.:</p>
+<pre class="literal-block">
+./configure CC=c99 CFLAGS=-O2 LIBS=-lposix
+</pre>
+<p>Options which should be common to packages installed under the same
+directory heirarchy may be supplied via a 'config.site' file located
+under the installation prefix via the path ${prefix}/share/config.site
+where ${prefix} is the installation prefix. This file is used for all
+packages installed under that prefix. As an alternative, the CONFIG_SITE
+environment variable may be used to specify the path of a site
+configuration file to load. This is an example config.site file:</p>
+<pre class="literal-block">
+# Configuration values for all packages installed under this prefix
+CC=gcc
+CXX=c++
+CPPFLAGS='-I/usr/local/include'
+LDFLAGS='-L/usr/local/lib -R/usr/local/lib'
+</pre>
+<p>When the 'config.site' file is being used to supply configuration
+options, configure will issue a message similar to:</p>
+<pre class="literal-block">
+configure: loading site script /usr/local/share/config.site
+</pre>
+<p>The configure variables you should be aware of are:</p>
+<p>CC</p>
+<blockquote>
+Name of C compiler (e.g. 'cc -Xa') to use</blockquote>
+<p>CXX</p>
+<blockquote>
+Name of C++ compiler to use (e.g. 'CC')</blockquote>
+<p>CFLAGS</p>
+<blockquote>
+Compiler flags (e.g. '-g -O2') to compile C code</blockquote>
+<p>CXXFLAGS</p>
+<blockquote>
+Compiler flags (e.g. '-g -O2') to compile C++ code</blockquote>
+<p>CPPFLAGS</p>
+<blockquote>
+Include paths (-I/somedir) to look for header files</blockquote>
+<p>LDFLAGS</p>
+<blockquote>
+Library paths (-L/somedir) to look for libraries Systems that
+support the notion of a library run-path may require an additional
+argument in order to find shared libraries at run time. For
+example, the Solaris linker requires an argument of the form
+'-R/somedir', some Linux systems will work with '-rpath /somedir',
+while some other Linux systems who's gcc does not pass -rpath to
+the linker require an argument of the form '-Wl,-rpath,/somedir'.</blockquote>
+<p>LIBS</p>
+<blockquote>
+Extra libraries (-lsomelib) required to link</blockquote>
+<p>Any variable (e.g. CPPFLAGS or LDFLAGS) which requires a directory
+path must specify an absolute path rather than a relative path.</p>
+<p>The build now supports a Linux-style &quot;silent&quot; build (default
+disabled). To enable this, add the configure option
+--enable-silent-rules or invoke make like 'make V=0'. If the build
+has been configured for silent mode and it is necessary to see a
+verbose build, then invoke make like 'make V=1'.</p>
+<p>Configure can usually find the X include and library files
+automatically, but if it doesn't, you can use the 'configure' options
+'--x-includes=DIR' and '--x-libraries=DIR' to specify their locations.</p>
+<p>The configure script provides a number of GraphicsMagick specific
+options. When disabling an option --disable-something is equivalent
+to specifying --enable-something=no and --without-something is
+equivalent to --with-something=no. The configure options are as
+follows (execute 'configure --help' to see all options).</p>
+<div class="section" id="optional-features">
+<h2><a class="toc-backref" href="#id3">Optional Features</a></h2>
+<table class="docutils option-list" frame="void" rules="none">
+<col class="option" />
+<col class="description" />
+<tbody valign="top">
+<tr><td class="option-group">
+<kbd><span class="option">--enable-prof</span></kbd></td>
+<td>enable 'prof' profiling support (default disabled)</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--enable-gprof</span></kbd></td>
+<td>enable 'gprof' profiling support (default disabled)</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--enable-gcov</span></kbd></td>
+<td>enable 'gcov' profiling support (default disabled)</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--disable-installed</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>disable building an installed GraphicsMagick (default enabled)</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-broken-coders</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>enable broken/dangerous file formats support</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--disable-largefile</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>disable support for large (64 bit) file offsets</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--disable-openmp</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>disable use of OpenMP (automatic multi-threaded loops) at all</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-openmp-slow</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>enable OpenMP for algorithms which sometimes run slower</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-symbol-prefix</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>enable prefixing library symbols with &quot;Gm&quot;</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-magick-compat</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>install ImageMagick utility shortcuts (default disabled)</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-maintainer-mode</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>enable additional Makefile rules which update generated files
+included in the distribution. Requires GNU make as well as a
+number of utilities and tools.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-quantum-library-names</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>shared library name includes quantum depth to allow shared
+libraries with different quantum depths to co-exist in same
+directory (only one can be used for development)</td></tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="optional-packages-options">
+<h2><a class="toc-backref" href="#id4">Optional Packages/Options</a></h2>
+<table class="docutils option-list" frame="void" rules="none">
+<col class="option" />
+<col class="description" />
+<tbody valign="top">
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-quantum-depth</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>number of bits in a pixel quantum (default 8). Also see
+'--enable-quantum-library-names.'</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--with-modules</span></kbd></td>
+<td>enable building dynamically loadable modules</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--without-threads</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>disable POSIX threads API support</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-frozenpaths</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>enable frozen delegate paths</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--without-magick-plus-plus</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>disable build/install of Magick++</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--with-perl</span></kbd></td>
+<td>enable build/install of PerlMagick</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-perl=<var>PERL</var></span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>use specified Perl binary to configure PerlMagick</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-perl-options=<var>OPTIONS</var></span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>options to pass on command-line when generating PerlMagick's Makefile from Makefile.PL</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--without-bzlib</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>disable BZLIB support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-dps</span></kbd></td>
+<td>disable Display Postscript support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--with-fpx</span></kbd></td>
+<td>enable FlashPIX support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--with-gslib</span></kbd></td>
+<td>enable Ghostscript library support (not recommended)</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-jbig</span></kbd></td>
+<td>disable JBIG support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-jp2</span></kbd></td>
+<td>disable JPEG v2 support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-jpeg</span></kbd></td>
+<td>disable JPEG support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-jp2</span></kbd></td>
+<td>disable JPEG v2 support</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--without-lcms2</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>disable lcms (v2.X) support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-lzma</span></kbd></td>
+<td>disable LZMA support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-png</span></kbd></td>
+<td>disable PNG support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-tiff</span></kbd></td>
+<td>disable TIFF support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-trio</span></kbd></td>
+<td>disable TRIO library support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-ttf</span></kbd></td>
+<td>disable TrueType support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--with-umem</span></kbd></td>
+<td>enable libumem memory allocation library support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-wmf</span></kbd></td>
+<td>disable WMF support</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-fontpath</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>prepend to default font search path</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-gs-font-dir</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>directory containing Ghostscript fonts</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-windows-font-dir</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>directory containing MS-Windows fonts</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-xml</span></kbd></td>
+<td>disable XML support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-zlib</span></kbd></td>
+<td>disable ZLIB support</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--with-x</span></kbd></td>
+<td>use the X Window System</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-share-path=<var>DIR</var></span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>Alternate path to share directory (default share/GraphicsMagick)</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-libstdc=<var>DIR</var></span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>use libstdc++ in DIR (for GNU C++)</td></tr>
+</tbody>
+</table>
+<p>GraphicsMagick options represent either features to be enabled, disabled,
+or packages to be included in the build. When a feature is enabled (via
+--enable-something), it enables code already present in GraphicsMagick.
+When a package is enabled (via --with-something), the configure script
+will search for it, and if is is properly installed and ready to use
+(headers and built libraries are found by compiler) it will be included
+in the build. The configure script is delivered with all features
+disabled and all packages enabled. In general, the only reason to
+disable a package is if a package exists but it is unsuitable for
+the build (perhaps an old version or not compiled with the right
+compilation flags).</p>
+<p>Several configure options require special note:</p>
+<table class="docutils option-list" frame="void" rules="none">
+<col class="option" />
+<col class="description" />
+<tbody valign="top">
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-shared</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td><p class="first">The shared libraries are built and support for loading coder and
+process modules is enabled. Shared libraries are preferred because
+they allow programs to share common code, making the individual
+programs much smaller. In addition shared libraries are required in
+order for PerlMagick to be dynamically loaded by an installed PERL
+(otherwise an additional PERL (PerlMagick) must be installed. This
+option is not the default because all libraries used by
+GraphicsMagick must also be dynamic libraries if GraphicsMagick
+itself is to be dynamically loaded (such as for PerlMagick).</p>
+<p>GraphicsMagick built with delegates (see MAGICK PLUG-INS below)
+can pose additional challenges. If GraphicsMagick is built using
+static libraries (the default without --enable-shared) then
+delegate libraries may be built as either static libraries or
+shared libraries. However, if GraphicsMagick is built using shared
+libraries, then all delegate libraries must also be built as
+shared libraries. Static libraries usually have the extension .a,
+while shared libraries typically have extensions like .so, .sa,
+or .dll. Code in shared libraries normally must compiled using
+a special compiler option to produce Position Independent Code
+(PIC). The only time this is not necessary is if the platform
+compiles code as PIC by default.</p>
+<p>PIC compilation flags differ from vendor to vendor (gcc's is
+-fPIC). However, you must compile all shared library source with
+the same flag (for gcc use -fPIC rather than -fpic). While static
+libraries are normally created using an archive tool like 'ar',
+shared libraries are built using special linker or compiler options
+(e.g. -shared for gcc).</p>
+<p>Building shared libraries often requires subtantial hand-editing
+of Makefiles and is only recommended for those who know what they
+are doing.</p>
+<p class="last">If --enable-shared is not specified, a new PERL interpreter
+(PerlMagick) is built which is statically linked against the
+PerlMagick extension. This new interpreter is installed into the
+same directory as the GraphicsMagick utilities. If --enable-shared
+is specified, the PerlMagick extension is built as a dynamically
+loadable object which is loaded into your current PERL interpreter
+at run-time. Use of dynamically-loaded extensions is preferable over
+statically linked extensions so --enable-shared should be specified
+if possible (note that all libraries used with GraphicsMagick must
+be shared libraries!).</p>
+</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--disable-static</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>static archive libraries (with extension .a) are not built. If you
+are building shared libraries, there is little value to building
+static libraries. Reasons to build static libraries include: 1) they
+can be easier to debug; 2) the clients do not have external
+dependencies (i.e. libMagick.so); 3) building PIC versions of the
+delegate libraries may take additional expertise and effort; 4) you
+are unable to build shared libraries.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--disable-installed</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>By default the GraphicsMagick build is configured to formally install
+into a directory tree. This is the most secure and reliable way to
+install GraphicsMagick. Specifying --disable-installed configures
+GraphicsMagick so that it doesn't use hard-coded paths and locates
+support files by computing an offset path from the executable (or
+from the location specified by the MAGICK_HOME environment variable.
+The uninstalled configuration is ideal for binary distributions which
+are expected to extract and run in any location.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-broken-coders</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>The implementation of file format support for some formats is
+incomplete or imperfectly implemented such that file corruption or a
+security exploit might occur. These formats are not included in the
+build by default but may be enabled using
+<tt class="docutils literal"><span class="pre">--enable-broken-coders</span></tt>. The existing implementation may still
+have value in controlled circumstances so it remains but needs to be
+enabled. One of the formats currently controlled by this is Adobe
+Photoshop bitmap format (PSD).</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--with-modules</span></kbd></td>
+<td>Image coders and process modules are built as loadable modules which
+are installed under the directory
+[prefix]/lib/GraphicsMagick-X.X.X/modules-QN (where 'N' equals 8, 16,
+or 32 depending on the quantum depth) in the subdirectories 'coders'
+and 'filters' respectively. The modules build option is only
+available in conjunction with --enable-shared. If --enable-shared is
+not also specified, then support for building modules is disabled.
+Note that if --enable-shared is specified, the module loader is
+active (allowing extending an installed GraphicsMagick by simply
+copying a module into place) but GraphicsMagick itself is not built
+using modules.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-symbol-prefix</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>The GraphicsMagick libraries may contain symbols which conflict with
+other libraries. Specifify this option to prefix &quot;Gm&quot; to all library
+symbols, and use the C pre-processor to allow dependent code to still
+compile as before.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-magick-compat</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>Normally GraphicsMagick installs only the 'gm' utility from which all
+commands may be accessed. Existing packages may be designed to invoke
+ImageMagick utilities (e.g. &quot;convert&quot;). Specify this option to
+install ImageMagick utility compatibility links to allow
+GraphicsMagick to substitute directly for ImageMagick. Take care when
+selecting this option since if there is an existing ImageMagick
+installation installed in the same directory, its utilities will be
+replaced when GraphicsMagick is installed.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-quantum-depth</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td><p class="first">This option allows the user to specify the number of bits to use per
+pixel quantum (the size of the red, green, blue, and alpha pixel
+components. When an image file with less depth is read, smaller
+values are scaled up to this size for processing, and are scaled
+down from this size when a file with lower depth is written. For
+example, &quot;--with-quantum-depth=8&quot; builds GraphicsMagick using 8-bit
+quantums. Most computer display adaptors use 8-bit
+quantums. Currently supported arguments are 8, 16, or 32. The
+default is 8. This option is the most important option in
+determining the overall run-time performance of GraphicsMagick.</p>
+<p>The number of bits in a quantum determines how many values it may
+contain. Each quantum level supports 256 times as many values as
+the previous level. The following table shows the range available
+for various quantum sizes.</p>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="24%" />
+<col width="42%" />
+<col width="34%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">QuantumDepth</th>
+<th class="head">Valid Range (Decimal)</th>
+<th class="head">Valid Range (Hex)</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>8</td>
+<td>0-255</td>
+<td>00-FF</td>
+</tr>
+<tr><td>16</td>
+<td>0-65535</td>
+<td>0000-FFFF</td>
+</tr>
+<tr><td>32</td>
+<td>0-4294967295</td>
+<td>00000000-FFFFFFFF</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<p>Larger pixel quantums cause GraphicsMagick to run more slowly and to
+require more memory. For example, using sixteen-bit pixel quantums
+causes GraphicsMagick to run 15% to 50% slower (and take twice as
+much memory) than when it is built to support eight-bit pixel
+quantums. Regardless, the GraphicsMagick authors prefer to use
+sixteen-bit pixel quantums since they support all common image
+formats and assure that there is no loss of color precision.</p>
+<p>The amount of virtual memory consumed by an image can be computed
+by the equation (QuantumDepth*Rows*Columns*5)/8. This is an
+important consideration when resources are limited, particularly
+since processing an image may require several images to be in
+memory at one time. The following table shows memory consumption
+values for a 1024x768 image:</p>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="46%" />
+<col width="54%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">QuantumDepth</th>
+<th class="head">Virtual Memory</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>8</td>
+<td>3MB</td>
+</tr>
+<tr><td>16</td>
+<td>8MB</td>
+</tr>
+<tr><td>32</td>
+<td>15MB</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<p>GraphicsMagick performs all image processing computations using
+floating point or non-lossy integer arithmetic, so results are very
+accurate. Increasing the quantum storage size decreases the amount
+of quantization noise (usually not visible at 8 bits) and helps
+prevent countouring and posterization in the image.</p>
+<p class="last">Consider also using the --enable-quantum-library-names configure
+option so that installed shared libraries include the quantum depth
+as part of their names so that shared libraries using different
+quantum depth options may co-exist in the same directory.</p>
+</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--without-magick-plus-plus</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>Disable building Magick++, the C++ application programming interface
+to GraphicsMagick. A suitable C++ compiler is required in order to
+build Magick++. Specify the CXX configure variable to select the C++
+compiler to use (default &quot;g++&quot;), and CXXFLAGS to select the desired
+compiler opimization and debug flags (default &quot;-g -O2&quot;). Antique C++
+compilers will normally be rejected by configure tests so specifying
+this option should only be necessary if Magick++ fails to compile.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-frozenpaths</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>Normally external program names are substituted into the
+delegates.mgk file without full paths. Specify this option to enable
+saving full paths to programs using locations determined by
+configure. This is useful for environments where programs are stored
+under multiple paths, and users may use different PATH settings than
+the person who builds GraphicsMagick.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--without-threads</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>By default, the GraphicsMagick library is compiled to be fully
+thread safe by using thread APIs to implement required locking.
+This is intended to allow the GraphicsMagick library to be used by
+multi-threaded programs using native POSIX threads. If the locking
+or dependence on thread APIs is undesireable, then specify
+--without-threads. Testing shows that the overhead from thread
+safety is virtually unmeasurable so usually there is no reason to
+disable multi-thread support. While previous versions disabled
+OpenMP support when this option was supplied, that is no longer the
+case.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--disable-largefile</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>By default, GraphicsMagick is compiled with support for large (&gt; 2GB
+on a 32-bit CPU) files if the operating system supports large files.
+Applications which use the GraphicsMagick library might then also
+need to be compiled to support for large files (operating system
+dependent). Normally support for large files is a good thing. Only
+disable this option if there is a need to do so.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--disable-openmp</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td><p class="first">By default, GraphicsMagick is compiled with support for OpenMP
+(<a class="reference external" href="http://www.openmp.org/">http://www.openmp.org/</a>) if the compilation environment supports it.
+OpenMP automatically parallizes loops across concurrent threads
+based on instructions in pragmas. OpenMP was introduced in GCC
+4.2. OpenMP is a well-established standard and was implemented in
+some other compilers in the late '90s, long before its appearance in
+GCC. OpenMP adds additional build and linkage requirements.</p>
+<p class="last">By default, GraphicsMagick enables as many threads as there are CPU
+cores (or CPU threads). According to the OpenMP standard, the
+OMP_NUM_THREADS environment variable specifies how many threads
+should be used and GraphicsMagick also honors this request. In order
+to obtain the best single-user performance, set OMP_NUM_THREADS
+equal to the number of available CPU cores. On a server with many
+cores and many programs running at once, there may be benefit to
+setting OMP_NUM_THREADS to a much smaller value than the number of
+cores, and sometimes values as low as two (or even one, to disable
+threading) will offer the best overall system performance. Tuning a
+large system with OpenMP programs running in parallel (competing for
+resources) is a complex topic and some research and experimentation
+may be required in order to find the best parameters.</p>
+</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--enable-openmp-slow</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>On some systems, memory-bound algorithms run slower (rather than
+faster) as threads are added via OpenMP. This may be due to CPU
+cache and memory architecture implementation, or OS thread API
+implementation. Since it is not known how a system will behave
+without testing and pre-built binaries need to work well on all
+systems, these algorithms are now disabled for OpenMP by default.
+If you are using a well-threaded OS on a CPU with a good
+high-performance memory architecture, you might consider enabling
+this option based on experimentation.</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--with-perl</span></kbd></td>
+<td><p class="first">Use this option to include PerlMagick in the GraphicsMagick build
+and test suite. While PerlMagick is always configured by default
+(PerlMagick/Makefile.PL is generated by the configure script),
+PerlMagick is no longer installed by GraphicsMagick's ''make
+install''. The procedure to configure, build, install, and check
+PerlMagick is described in PerlMagick/README.txt. When using a
+shared library build of GraphicsMagick, it is necessary to formally
+install GraphicsMagick prior to building PerlMagick in order to
+achieve a working PerlMagick since otherwise the wrong
+GraphicsMagick libraries may be used.</p>
+<p class="last">If the argument ''--with-perl=/path/to/perl'' is supplied, then
+/path/to/perl will be taken as the PERL interpreter to use. This is
+important in case the 'perl' executable in your PATH is not PERL5,
+or is not the PERL you want to use. Experience suggests that static
+PerlMagick builds may not be fully successful for Perl versions
+newer than 5.8.8.</p>
+</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-perl-options</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>The PerlMagick module is normally installed using the Perl
+interpreter's installation PREFIX, rather than GraphicsMagick's. If
+GraphicsMagick's installation prefix is not the same as PERL's
+PREFIX, then you may find that PerlMagick's 'make install' step tries
+to install into a directory tree that you don't have write
+permissions to. This is common when PERL is delivered with the
+operating system or on Internet Service Provider (ISP) web servers.
+If you want PerlMagick to install elsewhere, then provide a PREFIX
+option to PERL's configuration step via
+&quot;--with-perl-options=PREFIX=/some/place&quot;. Other options accepted by
+MakeMaker are 'LIB', 'LIBPERL_A', 'LINKTYPE', and 'OPTIMIZE'. See the
+ExtUtils::MakeMaker(3) manual page for more information on
+configuring PERL extensions.</td></tr>
+<tr><td class="option-group">
+<kbd><span class="option">--without-x</span></kbd></td>
+<td>By default, GraphicsMagick will use X11 libraries if they are
+available. When --without-x is specified, use of X11 is disabled. The
+display, animate, and import sub-commands are not included. The
+remaining sub-commands have reduced functionality such as no access
+to X11 fonts (consider using Postscript or TrueType fonts instead).</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-gs-font-dir</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>Specify the directory containing the Ghostscript Postscript Type 1
+font files (e.g. &quot;n022003l.pfb&quot;) so that they can be rendered using
+the FreeType library. If the font files are installed using the
+default Ghostscript installation paths
+(${prefix}/share/ghostscript/fonts), they should be discovered
+automatically by configure and specifying this option is not
+necessary. Specify this option if the Ghostscript fonts fail to be
+located automatically, or the location needs to be overridden.</td></tr>
+<tr><td class="option-group" colspan="2">
+<kbd><span class="option">--with-windows-font-dir</span></kbd></td>
+</tr>
+<tr><td>&nbsp;</td><td>Specify the directory containing MS-Windows-compatible fonts. This is
+not necessary when GraphicsMagick is running under MS-Windows.</td></tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="section" id="building-under-cygwin">
+<h1><a class="toc-backref" href="#id5">Building under Cygwin</a></h1>
+<p>GraphicsMagick may be built under the Windows '95-XP Cygwin
+Unix-emulation environment available for free from</p>
+<blockquote>
+<a class="reference external" href="http://www.cygwin.com/">http://www.cygwin.com/</a></blockquote>
+<p>It is suggested that the X11R6 package be installed since this enables
+GraphicsMagick's X11 support (animate, display, and import
+sub-commands will work) and it includes the Freetype v2 DLL required
+to support TrueType and Postscript Type 1 fonts. Make sure that
+/usr/X11R6/bin is in your PATH prior to running configure.</p>
+<p>If you are using Cygwin version 1.3.9 or later, you may specify the
+configure option '--enable-shared' to build Cygwin DLLs. Specifying
+'--enable-shared' is required if you want to build PerlMagick under
+Cygwin because Cygwin does not provide the libperl.a static library
+required to create a static PerlMagick. Note that older Cygwin
+compilers may not generate code which supports reliably catching C++
+exceptions thrown by DLL code. The Magick++ library requires that it
+be possible to catch C++ exceptions thrown from DLLs. The test suite
+<tt class="docutils literal">make check</tt> includes several tests to verify that C++ exceptions
+are working properly.</p>
+</div>
+<div class="section" id="building-under-mingw-msys">
+<h1><a class="toc-backref" href="#id6">Building under MinGW &amp; MSYS</a></h1>
+<p>GraphicsMagick may be built using the free MinGW (&quot;Minimalistic GNU for
+Windows&quot;) package, available from</p>
+<blockquote>
+<a class="reference external" href="http://www.mingw.org/">http://www.mingw.org/</a></blockquote>
+<p>or from</p>
+<blockquote>
+<a class="reference external" href="http://mingw-w64.sourceforge.net/">http://mingw-w64.sourceforge.net/</a></blockquote>
+<p>which consist of GNU-based (GCC) compilation toolsets plus headers and
+libraries required to build programs which are entirely based on
+standard Microsoft Windows DLLs so that they may be used for
+proprietary applications. MSYS provides a Unix-style console shell
+window with sufficient functionality to run the GraphicsMagick
+configure script and execute 'make', 'make check', and 'make install'.
+GraphicsMagick may be executed from the MSYS shell, but since it is a
+normal Windows application, it will work just as well from the Windows
+command line.</p>
+<p>Unlike the Cygwin build which creates programs based on a
+Unix-emulation DLL, and which uses Unix-style paths to access Windows
+files, the MinGW build creates native Windows console applications
+similar to the Visual C++ build. Run-time performance is similar to the
+Microsoft compilers.</p>
+<p>The base MinGW (or MinGW-w64) package and the MSYS package should be
+installed. Other MinGW packages are entirely optional. Once MSYS is
+installed a MSYS icon (blue capital 'M') is added to the
+desktop. Double clicking on this icon starts an instance of the MSYS
+shell.</p>
+<p>Start the MSYS console and follow the Unix configure and build
+instructions. The configure and build for MinGW is the same as for
+Unix. Any additional delegate libraries (e.g. libpng) will need to be
+built under MinGW in order to be used. These libraries should be built
+and installed prior to configuring GraphicsMagick. While some delegate
+libraries are easy to configure and build under MinGW, others may be
+quite a challenge.</p>
+<p>Lucky for us, the most common delegate libraries are available
+pre-built, as part of the GnuWin32 project, from</p>
+<blockquote>
+<a class="reference external" href="http://gnuwin32.sourceforge.net/packages.html">http://gnuwin32.sourceforge.net/packages.html</a></blockquote>
+<p>The relevant packages are bzip2, freetype, jbigkit, libintl, jpeg,
+libpng, libtiff, libwmf and zlib. However, note that for freetype
+to be detected by configure, you must move the <tt class="docutils literal">freetype</tt> directory
+out of <tt class="docutils literal">GnuWin32\include\freetype2</tt> and into <tt class="docutils literal">GnuWin32\include</tt>.</p>
+<p>Note that older MinGW compilers may not generate code which supports
+reliably catching C++ exceptions thrown by DLL code. The Magick++
+library requires that it be possible to catch C++ exceptions thrown
+from DLLs. The test suite (<tt class="docutils literal">make check</tt>) includes several tests to
+verify that C++ exceptions are working properly. If the MinGW you are
+using fails the C++ exception tests, then the solution is to either
+find a MinGW with working C++ exceptions, configure a static build
+with --disable-shared, or disable building Magick++ with
+--without-magick-plus-plus.</p>
+<p>Note that the default installation prefix is MSYS's notion of
+<tt class="docutils literal">/usr/local</tt> which installs the package into a MSYS directory. To
+install outside of the MSYS directory tree, you may specify an
+installation prefix like <tt class="docutils literal">/c/GraphicsMagick</tt> which causes the package
+to be installed under the Windows directory <tt class="docutils literal"><span class="pre">C:\GraphicsMagick</span></tt>. The
+installation directory structure will look very much like the Unix
+installation layout (e.g. <tt class="docutils literal"><span class="pre">C:\GraphicsMagick\bin</span></tt>,
+<tt class="docutils literal"><span class="pre">C:\GraphicsMagick\lib</span></tt>, <tt class="docutils literal"><span class="pre">C:\GraphicsMagick\share</span></tt>, etc.). Paths
+which may be embedded in libraries and configuration files are
+transformed into Windows paths so they don't depend on MSYS.</p>
+<div class="section" id="cross-compilation-on-unix-linux-host">
+<h2><a class="toc-backref" href="#id7">Cross-compilation On Unix/Linux Host</a></h2>
+<p>Given a modern and working MinGW32 or mingw-w64 installation, it is
+easy to cross-compile GraphicsMagick from a Unix-type host to produce
+Microsoft Windows executables.</p>
+<p>This incantation produces a static WIN32 <cite>gm.exe</cite> executable on an
+Ubuntu Linux host with the i686-w64 cross-compiler installed:</p>
+<pre class="literal-block">
+./configure '--host=i686-w64-mingw32' '--disable-shared'
+</pre>
+<p>and this incantation produces a static WIN64 <cite>gm.exe</cite> executable on an
+Ubuntu Linux host with the x86_64-w64 cross-compiler installed:</p>
+<pre class="literal-block">
+./configure '--host=x86_64-w64-mingw32' '--disable-shared'
+</pre>
+<p>For a full-fledged GraphicsMagick program, normally one will want to
+pre-install or cross-compile the optional libraries that
+GraphicsMagick may depend on and install them where the cross-compiler
+will find them, or add extra <cite>CPPFLAGS</cite> and <cite>LDFLAGS</cite> options so that
+the compiler searches for header files and libraries in the correct
+place.</p>
+<p>Configuring for building with shared libraries (libGraphicsMagick,
+libGraphicsMagickWand, and libGraphicsMagick++ DLLs) and modules
+(coders as DLLs) is also supported by the cross-builds. A cross-built
+libtool libltdl needs to be built in advance in order to use the
+<cite>--with-modules</cite> modules option.</p>
+<p>After configuring the software for cross-compilation, the software is
+built using <cite>make</cite> as usual and everything should be as with native
+compilation except that <cite>make check</cite> is likely not available (testing
+might be possible on build system via WINE, not currently
+tested/supported by GraphicsMagick authors).</p>
+<p>Use of the <cite>DESTDIR</cite> approach as described in the <a class="reference internal" href="#build-install">Build &amp; Install</a>
+section is recommended in order to install the build products into a
+formal directory tree before preparing to copy onto the Windows target
+system (e.g. by packaging via an installer).</p>
+</div>
+</div>
+<div class="section" id="dealing-with-configuration-failures">
+<h1><a class="toc-backref" href="#id8">Dealing with configuration failures</a></h1>
+<p>While configure is designed to ease installation of GraphicsMagick, it
+often discovers problems that would otherwise be encountered later
+when compiling GraphicsMagick. The configure script tests for headers
+and libraries by executing the compiler (CC) with the specified
+compilation flags (CFLAGS), pre-processor flags (CPPFLAGS), and linker
+flags (LDFLAGS). Any errors are logged to the file 'config.log'. If
+configure fails to discover a header or library please review this
+log file to determine why, however, please be aware that <em>errors
+in the config.log are normal</em> because configure works by trying
+something and seeing if it fails. An error in config.log is only a
+problem if the test should have passed on your system. After taking
+corrective action, be sure to remove the 'config.cache' file before
+running configure so that configure will re-inspect the environment
+rather than using cached values.</p>
+<p>Common causes of configure failures are:</p>
+<ol class="arabic simple">
+<li>A delegate header is not in the header include path (CPPFLAGS -I
+option).</li>
+<li>A delegate library is not in the linker search/run path (LDFLAGS
+-L/-R option).</li>
+<li>A delegate library is missing a function (old version?).OB</li>
+<li>The compilation environment is faulty.</li>
+</ol>
+<p>If all reasonable corrective actions have been tried and the problem
+appears to be due to a flaw in the configure script, please send a
+bug report to the configure script maintainer (currently
+<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;graphicsmagick&#46;org">bfriesen<span>&#64;</span>graphicsmagick<span>&#46;</span>org</a>). All bug reports should contain the
+operating system type (as reported by 'uname -a') and the
+compiler/compiler-version. A copy of the configure script output
+and/or the config.log file may be valuable in order to find the
+problem. If you send a config.log, please also send a script of the
+configure output and a description of what you expected to see (and
+why) so the failure you are observing can be identified and resolved.</p>
+</div>
+<div class="section" id="makefile-build-targets">
+<h1><a class="toc-backref" href="#id9">Makefile Build Targets</a></h1>
+<p>Once GraphicsMagick is configured, these standard build targets are
+available from the generated Makefiles:</p>
+<blockquote>
+<p>'make'</p>
+<blockquote>
+Build the package</blockquote>
+<p>'make install'</p>
+<blockquote>
+Install the package</blockquote>
+<p>'make check'</p>
+<blockquote>
+Run tests using the uninstalled software. On some systems, 'make
+install' must be done before the test suite will work but usually
+the software can be tested prior to installation.</blockquote>
+<p>'make clean'</p>
+<blockquote>
+Remove everything in the build directory created by 'make'</blockquote>
+<p>'make distclean'</p>
+<blockquote>
+Remove everything in the build directory created by 'configure'
+and 'make'. This is useful if you want to start over from scratch.</blockquote>
+<p>'make uninstall'</p>
+<blockquote>
+Remove all files from the system which are (or would be) installed
+by 'make install' using the current configuration. Note that this
+target does not work for PerlMagick since Perl no longer supports
+an 'uninstall' target.</blockquote>
+</blockquote>
+</div>
+<div class="section" id="build-install">
+<h1><a class="toc-backref" href="#id10">Build &amp; Install</a></h1>
+<p>Now that GraphicsMagick is configured, type</p>
+<pre class="literal-block">
+make
+</pre>
+<p>to build the package and</p>
+<pre class="literal-block">
+make install
+</pre>
+<p>to install it.</p>
+<p>To install under a specified directory using the install directory
+tree layout (e.g. as part of the process for packaging the built
+software), specify DESTDIR like</p>
+<pre class="literal-block">
+make DESTDIR=/my/dest/dir install
+</pre>
+</div>
+<div class="section" id="verifying-the-build">
+<h1><a class="toc-backref" href="#id11">Verifying The Build</a></h1>
+<p>To confirm your installation of the GraphicsMagick distribution was
+successful, ensure that the installation directory is in your executable
+search path and type</p>
+<pre class="literal-block">
+gm display
+</pre>
+<p>The GraphicsMagick logo should be displayed on your X11 display.</p>
+<p>Verify that the expected image formats are supported by executing</p>
+<pre class="literal-block">
+gm convert -list formats
+</pre>
+<p>Verify that the expected fonts are available by executing</p>
+<pre class="literal-block">
+gm convert -list fonts
+</pre>
+<p>Verify that delegates (external programs) are configured as expected
+by executing</p>
+<pre class="literal-block">
+gm convert -list delegates
+</pre>
+<p>Verify that color definitions may be loaded by executing</p>
+<pre class="literal-block">
+gm convert -list colors
+</pre>
+<p>If GraphicsMagick is built to use loadable coder modules, then verify
+that the modules load via</p>
+<pre class="literal-block">
+gm convert -list modules
+</pre>
+<p>Verify that GraphicsMagick is properly identifying the resources of
+your machine via</p>
+<pre class="literal-block">
+gm convert -list resources
+</pre>
+<p>For a thorough test, you should run the GraphicsMagick test suite by
+typing</p>
+<pre class="literal-block">
+make check
+</pre>
+<p>Note that due to differences between the developer's environment and
+your own, it is possible that some tests may be indicated as failed
+even though the results are ok. Such failures should be rare, and if
+they do occur, they should be reported as a bug. Differences between
+the developer's environment environment and your own may include the
+compiler, the CPU type, and the library versions used. The
+GraphicsMagick developers use the current release of all dependent
+libraries.</p>
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/INSTALL-unix.rst b/www/INSTALL-unix.rst
new file mode 100644
index 0000000..d24add7
--- /dev/null
+++ b/www/INSTALL-unix.rst
@@ -0,0 +1,984 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=============================
+UNIX/Cygwin/MinGW Compilation
+=============================
+
+.. contents::
+ :local:
+
+Archive Formats
+---------------
+
+GraphicsMagick is distributed in a number of different archive formats.
+The source code must be extracted prior to compilation as follows:
+
+7z
+
+ 7-Zip archive format. The Z-Zip format may be extracted under Unix
+ using '7za' from the P7ZIP package (http://p7zip.sourceforge.net/).
+ Extract similar to::
+
+ 7za x GraphicsMagick-1.3.7z
+
+.tar.bz2
+
+ BZip2 compressed tar archive format. Requires that both the bzip2
+ (http://www.bzip.org/) and tar programs to be available. Extract
+ similar to::
+
+ bzip2 -d GraphicsMagick-1.3.tar.bz | tar -xvf -
+
+.tar.gz
+
+ Gzip compressed tar archive format. Requires that both the gzip
+ (http://www.gzip.org/) and tar programs to be available. Extract
+ similar to::
+
+ gzip -d GraphicsMagick-1.3.tar.gz | tar -xvf -
+
+.tar.lz
+
+ Lzip compressed tar archive format. Requires that both the lzip
+ (http://lzip.nongnu.org/lzip.html) and tar programs to be
+ available. Extract similar to::
+
+ lzip -d -c GraphicsMagick-1.3.tar.gz | tar -xvf -
+
+.tar.xz
+
+ LZMA compressed tar archive format. Requires that LZMA utils
+ (http://tukaani.org/lzma/) and tar programs to be available. Extract
+ similar to::
+
+ xz -d GraphicsMagick-1.3.tar.xz | tar -xvf -
+
+zip
+
+ PK-ZIP archive format. Requires that the unzip program from Info-Zip
+ (http://www.info-zip.org/UnZip.html) be available. Extract similar to::
+
+ unzip GraphicsMagick-1.3.zip
+
+The GraphicsMagick source code is extracted into a subdirectory
+similar to 'GraphicsMagick-1.3'. After the source code extracted,
+change to the new directory (using the actual directory name) using
+a command similar to::
+
+ cd GraphicsMagick-1.3
+
+
+Build Configuration
+-------------------
+
+Use 'configure' to automatically configure, build, and install
+GraphicsMagick. The configure script may be executed from the
+GraphicsMagick source directory (e.g ./configure) or from a separate
+build directory by specifying the full path to configure (e.g.
+/src/GraphicsMagick-1.3/configure). The advantage of using a separate
+build directory is that multiple GraphicsMagick builds may share the
+same GraphicsMagick source directory while allowing each build to use a
+unique set of options. Using a separate directory also makes it easier
+to keep track of any files you may have edited.
+
+If you are willing to accept configure's default options (static
+build, 8 bits/sample), and build from within the source directory,
+type::
+
+ ./configure
+
+and watch the configure script output to verify that it finds everything
+that you think it should. If it does not, then adjust your environment
+so that it does.
+
+By default, 'make install' will install the package's files
+in '/usr/local/bin', '/usr/local/man', etc. You can specify an
+installation prefix other than '/usr/local' by giving 'configure'
+the option '--prefix=PATH'. This is valuable in case you don't have
+privileges to install under the default paths or if you want to install
+in the system directories instead.
+
+If you are not happy with configure's choice of compiler, compilation
+flags, or libraries, you can give 'configure' initial values for
+variables by specifying them on the configure command line, e.g.::
+
+ ./configure CC=c99 CFLAGS=-O2 LIBS=-lposix
+
+Options which should be common to packages installed under the same
+directory heirarchy may be supplied via a 'config.site' file located
+under the installation prefix via the path ${prefix}/share/config.site
+where ${prefix} is the installation prefix. This file is used for all
+packages installed under that prefix. As an alternative, the CONFIG_SITE
+environment variable may be used to specify the path of a site
+configuration file to load. This is an example config.site file::
+
+ # Configuration values for all packages installed under this prefix
+ CC=gcc
+ CXX=c++
+ CPPFLAGS='-I/usr/local/include'
+ LDFLAGS='-L/usr/local/lib -R/usr/local/lib'
+
+When the 'config.site' file is being used to supply configuration
+options, configure will issue a message similar to::
+
+ configure: loading site script /usr/local/share/config.site
+
+The configure variables you should be aware of are:
+
+CC
+
+ Name of C compiler (e.g. 'cc -Xa') to use
+
+CXX
+
+ Name of C++ compiler to use (e.g. 'CC')
+
+CFLAGS
+
+ Compiler flags (e.g. '-g -O2') to compile C code
+
+CXXFLAGS
+
+ Compiler flags (e.g. '-g -O2') to compile C++ code
+
+CPPFLAGS
+
+ Include paths (-I/somedir) to look for header files
+
+LDFLAGS
+
+ Library paths (-L/somedir) to look for libraries Systems that
+ support the notion of a library run-path may require an additional
+ argument in order to find shared libraries at run time. For
+ example, the Solaris linker requires an argument of the form
+ '-R/somedir', some Linux systems will work with '-rpath /somedir',
+ while some other Linux systems who's gcc does not pass -rpath to
+ the linker require an argument of the form '-Wl,-rpath,/somedir'.
+
+LIBS
+
+ Extra libraries (-lsomelib) required to link
+
+Any variable (e.g. CPPFLAGS or LDFLAGS) which requires a directory
+path must specify an absolute path rather than a relative path.
+
+The build now supports a Linux-style "silent" build (default
+disabled). To enable this, add the configure option
+--enable-silent-rules or invoke make like 'make V=0'. If the build
+has been configured for silent mode and it is necessary to see a
+verbose build, then invoke make like 'make V=1'.
+
+Configure can usually find the X include and library files
+automatically, but if it doesn't, you can use the 'configure' options
+'--x-includes=DIR' and '--x-libraries=DIR' to specify their locations.
+
+The configure script provides a number of GraphicsMagick specific
+options. When disabling an option --disable-something is equivalent
+to specifying --enable-something=no and --without-something is
+equivalent to --with-something=no. The configure options are as
+follows (execute 'configure --help' to see all options).
+
+
+Optional Features
+~~~~~~~~~~~~~~~~~
+
+--enable-prof
+
+ enable 'prof' profiling support (default disabled)
+
+--enable-gprof
+
+ enable 'gprof' profiling support (default disabled)
+
+--enable-gcov
+
+ enable 'gcov' profiling support (default disabled)
+
+--disable-installed
+
+ disable building an installed GraphicsMagick (default enabled)
+
+--enable-broken-coders
+
+ enable broken/dangerous file formats support
+
+--disable-largefile
+
+ disable support for large (64 bit) file offsets
+
+--disable-openmp
+
+ disable use of OpenMP (automatic multi-threaded loops) at all
+
+--enable-openmp-slow
+
+ enable OpenMP for algorithms which sometimes run slower
+
+--enable-symbol-prefix
+
+ enable prefixing library symbols with "Gm"
+
+--enable-magick-compat
+
+ install ImageMagick utility shortcuts (default disabled)
+
+--enable-maintainer-mode
+
+ enable additional Makefile rules which update generated files
+ included in the distribution. Requires GNU make as well as a
+ number of utilities and tools.
+
+--enable-quantum-library-names
+
+ shared library name includes quantum depth to allow shared
+ libraries with different quantum depths to co-exist in same
+ directory (only one can be used for development)
+
+
+Optional Packages/Options
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+--with-quantum-depth
+
+ number of bits in a pixel quantum (default 8). Also see
+ '--enable-quantum-library-names.'
+
+--with-modules
+
+ enable building dynamically loadable modules
+
+--without-threads
+
+ disable POSIX threads API support
+
+--with-frozenpaths
+
+ enable frozen delegate paths
+
+--without-magick-plus-plus
+
+ disable build/install of Magick++
+
+--with-perl
+
+ enable build/install of PerlMagick
+
+--with-perl=PERL
+
+ use specified Perl binary to configure PerlMagick
+
+--with-perl-options=OPTIONS
+
+ options to pass on command-line when generating PerlMagick's Makefile from Makefile.PL
+
+--without-bzlib
+
+ disable BZLIB support
+
+--without-dps
+
+ disable Display Postscript support
+
+--with-fpx
+
+ enable FlashPIX support
+
+--with-gslib
+
+ enable Ghostscript library support (not recommended)
+
+--without-jbig
+
+ disable JBIG support
+
+--without-jp2
+
+ disable JPEG v2 support
+
+--without-jpeg
+
+ disable JPEG support
+
+--without-jp2
+
+ disable JPEG v2 support
+
+--without-lcms2
+
+ disable lcms (v2.X) support
+
+--without-lzma
+
+ disable LZMA support
+
+--without-png
+
+ disable PNG support
+
+--without-tiff
+
+ disable TIFF support
+
+--without-trio
+
+ disable TRIO library support
+
+--without-ttf
+
+ disable TrueType support
+
+--with-umem
+
+ enable libumem memory allocation library support
+
+--without-wmf
+
+ disable WMF support
+
+--with-fontpath
+
+ prepend to default font search path
+
+--with-gs-font-dir
+
+ directory containing Ghostscript fonts
+
+--with-windows-font-dir
+
+ directory containing MS-Windows fonts
+
+--without-xml
+
+ disable XML support
+
+--without-zlib
+
+ disable ZLIB support
+
+--with-x
+
+ use the X Window System
+
+--with-share-path=DIR
+
+ Alternate path to share directory (default share/GraphicsMagick)
+
+--with-libstdc=DIR
+
+ use libstdc++ in DIR (for GNU C++)
+
+GraphicsMagick options represent either features to be enabled, disabled,
+or packages to be included in the build. When a feature is enabled (via
+--enable-something), it enables code already present in GraphicsMagick.
+When a package is enabled (via --with-something), the configure script
+will search for it, and if is is properly installed and ready to use
+(headers and built libraries are found by compiler) it will be included
+in the build. The configure script is delivered with all features
+disabled and all packages enabled. In general, the only reason to
+disable a package is if a package exists but it is unsuitable for
+the build (perhaps an old version or not compiled with the right
+compilation flags).
+
+Several configure options require special note:
+
+--enable-shared
+
+ The shared libraries are built and support for loading coder and
+ process modules is enabled. Shared libraries are preferred because
+ they allow programs to share common code, making the individual
+ programs much smaller. In addition shared libraries are required in
+ order for PerlMagick to be dynamically loaded by an installed PERL
+ (otherwise an additional PERL (PerlMagick) must be installed. This
+ option is not the default because all libraries used by
+ GraphicsMagick must also be dynamic libraries if GraphicsMagick
+ itself is to be dynamically loaded (such as for PerlMagick).
+
+ GraphicsMagick built with delegates (see MAGICK PLUG-INS below)
+ can pose additional challenges. If GraphicsMagick is built using
+ static libraries (the default without --enable-shared) then
+ delegate libraries may be built as either static libraries or
+ shared libraries. However, if GraphicsMagick is built using shared
+ libraries, then all delegate libraries must also be built as
+ shared libraries. Static libraries usually have the extension .a,
+ while shared libraries typically have extensions like .so, .sa,
+ or .dll. Code in shared libraries normally must compiled using
+ a special compiler option to produce Position Independent Code
+ (PIC). The only time this is not necessary is if the platform
+ compiles code as PIC by default.
+
+ PIC compilation flags differ from vendor to vendor (gcc's is
+ -fPIC). However, you must compile all shared library source with
+ the same flag (for gcc use -fPIC rather than -fpic). While static
+ libraries are normally created using an archive tool like 'ar',
+ shared libraries are built using special linker or compiler options
+ (e.g. -shared for gcc).
+
+ Building shared libraries often requires subtantial hand-editing
+ of Makefiles and is only recommended for those who know what they
+ are doing.
+
+ If --enable-shared is not specified, a new PERL interpreter
+ (PerlMagick) is built which is statically linked against the
+ PerlMagick extension. This new interpreter is installed into the
+ same directory as the GraphicsMagick utilities. If --enable-shared
+ is specified, the PerlMagick extension is built as a dynamically
+ loadable object which is loaded into your current PERL interpreter
+ at run-time. Use of dynamically-loaded extensions is preferable over
+ statically linked extensions so --enable-shared should be specified
+ if possible (note that all libraries used with GraphicsMagick must
+ be shared libraries!).
+
+--disable-static
+
+ static archive libraries (with extension .a) are not built. If you
+ are building shared libraries, there is little value to building
+ static libraries. Reasons to build static libraries include: 1) they
+ can be easier to debug; 2) the clients do not have external
+ dependencies (i.e. libMagick.so); 3) building PIC versions of the
+ delegate libraries may take additional expertise and effort; 4) you
+ are unable to build shared libraries.
+
+--disable-installed
+
+ By default the GraphicsMagick build is configured to formally install
+ into a directory tree. This is the most secure and reliable way to
+ install GraphicsMagick. Specifying --disable-installed configures
+ GraphicsMagick so that it doesn't use hard-coded paths and locates
+ support files by computing an offset path from the executable (or
+ from the location specified by the MAGICK_HOME environment variable.
+ The uninstalled configuration is ideal for binary distributions which
+ are expected to extract and run in any location.
+
+--enable-broken-coders
+
+ The implementation of file format support for some formats is
+ incomplete or imperfectly implemented such that file corruption or a
+ security exploit might occur. These formats are not included in the
+ build by default but may be enabled using
+ ``--enable-broken-coders``. The existing implementation may still
+ have value in controlled circumstances so it remains but needs to be
+ enabled. One of the formats currently controlled by this is Adobe
+ Photoshop bitmap format (PSD).
+
+--with-modules
+
+ Image coders and process modules are built as loadable modules which
+ are installed under the directory
+ [prefix]/lib/GraphicsMagick-X.X.X/modules-QN (where 'N' equals 8, 16,
+ or 32 depending on the quantum depth) in the subdirectories 'coders'
+ and 'filters' respectively. The modules build option is only
+ available in conjunction with --enable-shared. If --enable-shared is
+ not also specified, then support for building modules is disabled.
+ Note that if --enable-shared is specified, the module loader is
+ active (allowing extending an installed GraphicsMagick by simply
+ copying a module into place) but GraphicsMagick itself is not built
+ using modules.
+
+--enable-symbol-prefix
+
+ The GraphicsMagick libraries may contain symbols which conflict with
+ other libraries. Specifify this option to prefix "Gm" to all library
+ symbols, and use the C pre-processor to allow dependent code to still
+ compile as before.
+
+--enable-magick-compat
+
+ Normally GraphicsMagick installs only the 'gm' utility from which all
+ commands may be accessed. Existing packages may be designed to invoke
+ ImageMagick utilities (e.g. "convert"). Specify this option to
+ install ImageMagick utility compatibility links to allow
+ GraphicsMagick to substitute directly for ImageMagick. Take care when
+ selecting this option since if there is an existing ImageMagick
+ installation installed in the same directory, its utilities will be
+ replaced when GraphicsMagick is installed.
+
+--with-quantum-depth
+
+ This option allows the user to specify the number of bits to use per
+ pixel quantum (the size of the red, green, blue, and alpha pixel
+ components. When an image file with less depth is read, smaller
+ values are scaled up to this size for processing, and are scaled
+ down from this size when a file with lower depth is written. For
+ example, "--with-quantum-depth=8" builds GraphicsMagick using 8-bit
+ quantums. Most computer display adaptors use 8-bit
+ quantums. Currently supported arguments are 8, 16, or 32. The
+ default is 8. This option is the most important option in
+ determining the overall run-time performance of GraphicsMagick.
+
+ The number of bits in a quantum determines how many values it may
+ contain. Each quantum level supports 256 times as many values as
+ the previous level. The following table shows the range available
+ for various quantum sizes.
+
+ ============ ===================== =================
+ QuantumDepth Valid Range (Decimal) Valid Range (Hex)
+ ============ ===================== =================
+ 8 0-255 00-FF
+ 16 0-65535 0000-FFFF
+ 32 0-4294967295 00000000-FFFFFFFF
+ ============ ===================== =================
+
+ Larger pixel quantums cause GraphicsMagick to run more slowly and to
+ require more memory. For example, using sixteen-bit pixel quantums
+ causes GraphicsMagick to run 15% to 50% slower (and take twice as
+ much memory) than when it is built to support eight-bit pixel
+ quantums. Regardless, the GraphicsMagick authors prefer to use
+ sixteen-bit pixel quantums since they support all common image
+ formats and assure that there is no loss of color precision.
+
+ The amount of virtual memory consumed by an image can be computed
+ by the equation (QuantumDepth*Rows*Columns*5)/8. This is an
+ important consideration when resources are limited, particularly
+ since processing an image may require several images to be in
+ memory at one time. The following table shows memory consumption
+ values for a 1024x768 image:
+
+ ============ ==============
+ QuantumDepth Virtual Memory
+ ============ ==============
+ 8 3MB
+ 16 8MB
+ 32 15MB
+ ============ ==============
+
+ GraphicsMagick performs all image processing computations using
+ floating point or non-lossy integer arithmetic, so results are very
+ accurate. Increasing the quantum storage size decreases the amount
+ of quantization noise (usually not visible at 8 bits) and helps
+ prevent countouring and posterization in the image.
+
+ Consider also using the --enable-quantum-library-names configure
+ option so that installed shared libraries include the quantum depth
+ as part of their names so that shared libraries using different
+ quantum depth options may co-exist in the same directory.
+
+--without-magick-plus-plus
+
+ Disable building Magick++, the C++ application programming interface
+ to GraphicsMagick. A suitable C++ compiler is required in order to
+ build Magick++. Specify the CXX configure variable to select the C++
+ compiler to use (default "g++"), and CXXFLAGS to select the desired
+ compiler opimization and debug flags (default "-g -O2"). Antique C++
+ compilers will normally be rejected by configure tests so specifying
+ this option should only be necessary if Magick++ fails to compile.
+
+--with-frozenpaths
+
+ Normally external program names are substituted into the
+ delegates.mgk file without full paths. Specify this option to enable
+ saving full paths to programs using locations determined by
+ configure. This is useful for environments where programs are stored
+ under multiple paths, and users may use different PATH settings than
+ the person who builds GraphicsMagick.
+
+--without-threads
+
+ By default, the GraphicsMagick library is compiled to be fully
+ thread safe by using thread APIs to implement required locking.
+ This is intended to allow the GraphicsMagick library to be used by
+ multi-threaded programs using native POSIX threads. If the locking
+ or dependence on thread APIs is undesireable, then specify
+ --without-threads. Testing shows that the overhead from thread
+ safety is virtually unmeasurable so usually there is no reason to
+ disable multi-thread support. While previous versions disabled
+ OpenMP support when this option was supplied, that is no longer the
+ case.
+
+--disable-largefile
+
+ By default, GraphicsMagick is compiled with support for large (> 2GB
+ on a 32-bit CPU) files if the operating system supports large files.
+ Applications which use the GraphicsMagick library might then also
+ need to be compiled to support for large files (operating system
+ dependent). Normally support for large files is a good thing. Only
+ disable this option if there is a need to do so.
+
+--disable-openmp
+
+ By default, GraphicsMagick is compiled with support for OpenMP
+ (http://www.openmp.org/) if the compilation environment supports it.
+ OpenMP automatically parallizes loops across concurrent threads
+ based on instructions in pragmas. OpenMP was introduced in GCC
+ 4.2. OpenMP is a well-established standard and was implemented in
+ some other compilers in the late '90s, long before its appearance in
+ GCC. OpenMP adds additional build and linkage requirements.
+
+ By default, GraphicsMagick enables as many threads as there are CPU
+ cores (or CPU threads). According to the OpenMP standard, the
+ OMP_NUM_THREADS environment variable specifies how many threads
+ should be used and GraphicsMagick also honors this request. In order
+ to obtain the best single-user performance, set OMP_NUM_THREADS
+ equal to the number of available CPU cores. On a server with many
+ cores and many programs running at once, there may be benefit to
+ setting OMP_NUM_THREADS to a much smaller value than the number of
+ cores, and sometimes values as low as two (or even one, to disable
+ threading) will offer the best overall system performance. Tuning a
+ large system with OpenMP programs running in parallel (competing for
+ resources) is a complex topic and some research and experimentation
+ may be required in order to find the best parameters.
+
+--enable-openmp-slow
+
+ On some systems, memory-bound algorithms run slower (rather than
+ faster) as threads are added via OpenMP. This may be due to CPU
+ cache and memory architecture implementation, or OS thread API
+ implementation. Since it is not known how a system will behave
+ without testing and pre-built binaries need to work well on all
+ systems, these algorithms are now disabled for OpenMP by default.
+ If you are using a well-threaded OS on a CPU with a good
+ high-performance memory architecture, you might consider enabling
+ this option based on experimentation.
+
+--with-perl
+
+ Use this option to include PerlMagick in the GraphicsMagick build
+ and test suite. While PerlMagick is always configured by default
+ (PerlMagick/Makefile.PL is generated by the configure script),
+ PerlMagick is no longer installed by GraphicsMagick's ''make
+ install''. The procedure to configure, build, install, and check
+ PerlMagick is described in PerlMagick/README.txt. When using a
+ shared library build of GraphicsMagick, it is necessary to formally
+ install GraphicsMagick prior to building PerlMagick in order to
+ achieve a working PerlMagick since otherwise the wrong
+ GraphicsMagick libraries may be used.
+
+ If the argument ''--with-perl=/path/to/perl'' is supplied, then
+ /path/to/perl will be taken as the PERL interpreter to use. This is
+ important in case the 'perl' executable in your PATH is not PERL5,
+ or is not the PERL you want to use. Experience suggests that static
+ PerlMagick builds may not be fully successful for Perl versions
+ newer than 5.8.8.
+
+--with-perl-options
+
+ The PerlMagick module is normally installed using the Perl
+ interpreter's installation PREFIX, rather than GraphicsMagick's. If
+ GraphicsMagick's installation prefix is not the same as PERL's
+ PREFIX, then you may find that PerlMagick's 'make install' step tries
+ to install into a directory tree that you don't have write
+ permissions to. This is common when PERL is delivered with the
+ operating system or on Internet Service Provider (ISP) web servers.
+ If you want PerlMagick to install elsewhere, then provide a PREFIX
+ option to PERL's configuration step via
+ "--with-perl-options=PREFIX=/some/place". Other options accepted by
+ MakeMaker are 'LIB', 'LIBPERL_A', 'LINKTYPE', and 'OPTIMIZE'. See the
+ ExtUtils::MakeMaker(3) manual page for more information on
+ configuring PERL extensions.
+
+--without-x
+
+ By default, GraphicsMagick will use X11 libraries if they are
+ available. When --without-x is specified, use of X11 is disabled. The
+ display, animate, and import sub-commands are not included. The
+ remaining sub-commands have reduced functionality such as no access
+ to X11 fonts (consider using Postscript or TrueType fonts instead).
+
+--with-gs-font-dir
+
+ Specify the directory containing the Ghostscript Postscript Type 1
+ font files (e.g. "n022003l.pfb") so that they can be rendered using
+ the FreeType library. If the font files are installed using the
+ default Ghostscript installation paths
+ (${prefix}/share/ghostscript/fonts), they should be discovered
+ automatically by configure and specifying this option is not
+ necessary. Specify this option if the Ghostscript fonts fail to be
+ located automatically, or the location needs to be overridden.
+
+--with-windows-font-dir
+
+ Specify the directory containing MS-Windows-compatible fonts. This is
+ not necessary when GraphicsMagick is running under MS-Windows.
+
+Building under Cygwin
+---------------------
+
+GraphicsMagick may be built under the Windows '95-XP Cygwin
+Unix-emulation environment available for free from
+
+ http://www.cygwin.com/
+
+It is suggested that the X11R6 package be installed since this enables
+GraphicsMagick's X11 support (animate, display, and import
+sub-commands will work) and it includes the Freetype v2 DLL required
+to support TrueType and Postscript Type 1 fonts. Make sure that
+/usr/X11R6/bin is in your PATH prior to running configure.
+
+If you are using Cygwin version 1.3.9 or later, you may specify the
+configure option '--enable-shared' to build Cygwin DLLs. Specifying
+'--enable-shared' is required if you want to build PerlMagick under
+Cygwin because Cygwin does not provide the libperl.a static library
+required to create a static PerlMagick. Note that older Cygwin
+compilers may not generate code which supports reliably catching C++
+exceptions thrown by DLL code. The Magick++ library requires that it
+be possible to catch C++ exceptions thrown from DLLs. The test suite
+``make check`` includes several tests to verify that C++ exceptions
+are working properly.
+
+Building under MinGW & MSYS
+---------------------------
+
+GraphicsMagick may be built using the free MinGW ("Minimalistic GNU for
+Windows") package, available from
+
+ http://www.mingw.org/
+
+or from
+
+ http://mingw-w64.sourceforge.net/
+
+which consist of GNU-based (GCC) compilation toolsets plus headers and
+libraries required to build programs which are entirely based on
+standard Microsoft Windows DLLs so that they may be used for
+proprietary applications. MSYS provides a Unix-style console shell
+window with sufficient functionality to run the GraphicsMagick
+configure script and execute 'make', 'make check', and 'make install'.
+GraphicsMagick may be executed from the MSYS shell, but since it is a
+normal Windows application, it will work just as well from the Windows
+command line.
+
+Unlike the Cygwin build which creates programs based on a
+Unix-emulation DLL, and which uses Unix-style paths to access Windows
+files, the MinGW build creates native Windows console applications
+similar to the Visual C++ build. Run-time performance is similar to the
+Microsoft compilers.
+
+The base MinGW (or MinGW-w64) package and the MSYS package should be
+installed. Other MinGW packages are entirely optional. Once MSYS is
+installed a MSYS icon (blue capital 'M') is added to the
+desktop. Double clicking on this icon starts an instance of the MSYS
+shell.
+
+Start the MSYS console and follow the Unix configure and build
+instructions. The configure and build for MinGW is the same as for
+Unix. Any additional delegate libraries (e.g. libpng) will need to be
+built under MinGW in order to be used. These libraries should be built
+and installed prior to configuring GraphicsMagick. While some delegate
+libraries are easy to configure and build under MinGW, others may be
+quite a challenge.
+
+Lucky for us, the most common delegate libraries are available
+pre-built, as part of the GnuWin32 project, from
+
+ http://gnuwin32.sourceforge.net/packages.html
+
+The relevant packages are bzip2, freetype, jbigkit, libintl, jpeg,
+libpng, libtiff, libwmf and zlib. However, note that for freetype
+to be detected by configure, you must move the ``freetype`` directory
+out of ``GnuWin32\include\freetype2`` and into ``GnuWin32\include``.
+
+Note that older MinGW compilers may not generate code which supports
+reliably catching C++ exceptions thrown by DLL code. The Magick++
+library requires that it be possible to catch C++ exceptions thrown
+from DLLs. The test suite (``make check``) includes several tests to
+verify that C++ exceptions are working properly. If the MinGW you are
+using fails the C++ exception tests, then the solution is to either
+find a MinGW with working C++ exceptions, configure a static build
+with --disable-shared, or disable building Magick++ with
+--without-magick-plus-plus.
+
+Note that the default installation prefix is MSYS's notion of
+``/usr/local`` which installs the package into a MSYS directory. To
+install outside of the MSYS directory tree, you may specify an
+installation prefix like ``/c/GraphicsMagick`` which causes the package
+to be installed under the Windows directory ``C:\GraphicsMagick``. The
+installation directory structure will look very much like the Unix
+installation layout (e.g. ``C:\GraphicsMagick\bin``,
+``C:\GraphicsMagick\lib``, ``C:\GraphicsMagick\share``, etc.). Paths
+which may be embedded in libraries and configuration files are
+transformed into Windows paths so they don't depend on MSYS.
+
+Cross-compilation On Unix/Linux Host
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Given a modern and working MinGW32 or mingw-w64 installation, it is
+easy to cross-compile GraphicsMagick from a Unix-type host to produce
+Microsoft Windows executables.
+
+This incantation produces a static WIN32 `gm.exe` executable on an
+Ubuntu Linux host with the i686-w64 cross-compiler installed::
+
+ ./configure '--host=i686-w64-mingw32' '--disable-shared'
+
+and this incantation produces a static WIN64 `gm.exe` executable on an
+Ubuntu Linux host with the x86_64-w64 cross-compiler installed::
+
+ ./configure '--host=x86_64-w64-mingw32' '--disable-shared'
+
+For a full-fledged GraphicsMagick program, normally one will want to
+pre-install or cross-compile the optional libraries that
+GraphicsMagick may depend on and install them where the cross-compiler
+will find them, or add extra `CPPFLAGS` and `LDFLAGS` options so that
+the compiler searches for header files and libraries in the correct
+place.
+
+Configuring for building with shared libraries (libGraphicsMagick,
+libGraphicsMagickWand, and libGraphicsMagick++ DLLs) and modules
+(coders as DLLs) is also supported by the cross-builds. A cross-built
+libtool libltdl needs to be built in advance in order to use the
+`--with-modules` modules option.
+
+After configuring the software for cross-compilation, the software is
+built using `make` as usual and everything should be as with native
+compilation except that `make check` is likely not available (testing
+might be possible on build system via WINE, not currently
+tested/supported by GraphicsMagick authors).
+
+Use of the `DESTDIR` approach as described in the `Build & Install`_
+section is recommended in order to install the build products into a
+formal directory tree before preparing to copy onto the Windows target
+system (e.g. by packaging via an installer).
+
+Dealing with configuration failures
+-----------------------------------
+
+While configure is designed to ease installation of GraphicsMagick, it
+often discovers problems that would otherwise be encountered later
+when compiling GraphicsMagick. The configure script tests for headers
+and libraries by executing the compiler (CC) with the specified
+compilation flags (CFLAGS), pre-processor flags (CPPFLAGS), and linker
+flags (LDFLAGS). Any errors are logged to the file 'config.log'. If
+configure fails to discover a header or library please review this
+log file to determine why, however, please be aware that *errors
+in the config.log are normal* because configure works by trying
+something and seeing if it fails. An error in config.log is only a
+problem if the test should have passed on your system. After taking
+corrective action, be sure to remove the 'config.cache' file before
+running configure so that configure will re-inspect the environment
+rather than using cached values.
+
+Common causes of configure failures are:
+
+1) A delegate header is not in the header include path (CPPFLAGS -I
+ option).
+
+2) A delegate library is not in the linker search/run path (LDFLAGS
+ -L/-R option).
+
+3) A delegate library is missing a function (old version?).OB
+
+4) The compilation environment is faulty.
+
+If all reasonable corrective actions have been tried and the problem
+appears to be due to a flaw in the configure script, please send a
+bug report to the configure script maintainer (currently
+bfriesen@graphicsmagick.org). All bug reports should contain the
+operating system type (as reported by 'uname -a') and the
+compiler/compiler-version. A copy of the configure script output
+and/or the config.log file may be valuable in order to find the
+problem. If you send a config.log, please also send a script of the
+configure output and a description of what you expected to see (and
+why) so the failure you are observing can be identified and resolved.
+
+Makefile Build Targets
+----------------------
+
+Once GraphicsMagick is configured, these standard build targets are
+available from the generated Makefiles:
+
+ 'make'
+
+ Build the package
+
+ 'make install'
+
+ Install the package
+
+ 'make check'
+
+ Run tests using the uninstalled software. On some systems, 'make
+ install' must be done before the test suite will work but usually
+ the software can be tested prior to installation.
+
+ 'make clean'
+
+ Remove everything in the build directory created by 'make'
+
+ 'make distclean'
+
+ Remove everything in the build directory created by 'configure'
+ and 'make'. This is useful if you want to start over from scratch.
+
+ 'make uninstall'
+
+ Remove all files from the system which are (or would be) installed
+ by 'make install' using the current configuration. Note that this
+ target does not work for PerlMagick since Perl no longer supports
+ an 'uninstall' target.
+
+Build & Install
+---------------
+
+Now that GraphicsMagick is configured, type ::
+
+ make
+
+to build the package and ::
+
+ make install
+
+to install it.
+
+To install under a specified directory using the install directory
+tree layout (e.g. as part of the process for packaging the built
+software), specify DESTDIR like ::
+
+ make DESTDIR=/my/dest/dir install
+
+Verifying The Build
+-------------------
+
+To confirm your installation of the GraphicsMagick distribution was
+successful, ensure that the installation directory is in your executable
+search path and type ::
+
+ gm display
+
+The GraphicsMagick logo should be displayed on your X11 display.
+
+Verify that the expected image formats are supported by executing ::
+
+ gm convert -list formats
+
+Verify that the expected fonts are available by executing ::
+
+ gm convert -list fonts
+
+Verify that delegates (external programs) are configured as expected
+by executing ::
+
+ gm convert -list delegates
+
+Verify that color definitions may be loaded by executing ::
+
+ gm convert -list colors
+
+If GraphicsMagick is built to use loadable coder modules, then verify
+that the modules load via ::
+
+ gm convert -list modules
+
+Verify that GraphicsMagick is properly identifying the resources of
+your machine via ::
+
+ gm convert -list resources
+
+For a thorough test, you should run the GraphicsMagick test suite by
+typing ::
+
+ make check
+
+Note that due to differences between the developer's environment and
+your own, it is possible that some tests may be indicated as failed
+even though the results are ok. Such failures should be rare, and if
+they do occur, they should be reported as a bug. Differences between
+the developer's environment environment and your own may include the
+compiler, the CPU type, and the library versions used. The
+GraphicsMagick developers use the current release of all dependent
+libraries.
+
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/INSTALL-windows.html b/www/INSTALL-windows.html
new file mode 100644
index 0000000..e9acccf
--- /dev/null
+++ b/www/INSTALL-windows.html
@@ -0,0 +1,786 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Windows Installation</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-windows-installation">
+<h1 class="title">GraphicsMagick Windows Installation</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#installing-using-installer-package" id="id1">Installing Using Installer Package</a><ul>
+<li><a class="reference internal" href="#prerequisites" id="id2">Prerequisites</a></li>
+<li><a class="reference internal" href="#retrieve-install-package" id="id3">Retrieve Install Package</a></li>
+<li><a class="reference internal" href="#start-installation-wizard" id="id4">Start Installation Wizard</a></li>
+<li><a class="reference internal" href="#read-installation-information" id="id5">Read Installation Information</a></li>
+<li><a class="reference internal" href="#select-destination-directory" id="id6">Select Destination Directory</a></li>
+<li><a class="reference internal" href="#select-start-menu-folder" id="id7">Select Start Menu Folder</a></li>
+<li><a class="reference internal" href="#select-additional-tasks" id="id8">Select Additional Tasks</a></li>
+<li><a class="reference internal" href="#ready-to-install" id="id9">Ready to Install</a></li>
+<li><a class="reference internal" href="#installation-progress" id="id10">Installation Progress</a></li>
+<li><a class="reference internal" href="#final-information" id="id11">Final Information</a></li>
+<li><a class="reference internal" href="#finishing-up" id="id12">Finishing Up</a></li>
+<li><a class="reference internal" href="#testing-the-installation" id="id13">Testing The Installation</a></li>
+<li><a class="reference internal" href="#uninstall" id="id14">Uninstall</a></li>
+<li><a class="reference internal" href="#use-from-another-package-or-program" id="id15">Use From Another Package or Program</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#installing-from-source-code" id="id16">Installing From Source Code</a><ul>
+<li><a class="reference internal" href="#applicability" id="id17">Applicability</a></li>
+<li><a class="reference internal" href="#important-notes" id="id18">Important Notes</a></li>
+<li><a class="reference internal" href="#windows-xp-vista-7-visual-c-6-0-through-14-0-compilation" id="id19">Windows XP, Vista, 7 Visual C++ 6.0 through 14.0 Compilation</a></li>
+<li><a class="reference internal" href="#environment-variables" id="id20">Environment Variables</a></li>
+<li><a class="reference internal" href="#windows-distribution-build-procedure" id="id21">Windows Distribution Build Procedure</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="installing-using-installer-package">
+<h1><a class="toc-backref" href="#id1">Installing Using Installer Package</a></h1>
+<blockquote>
+This section provides information specific to GraphicsMagick installed
+via a &quot;setup.exe&quot; style installation wizard under Microsoft Windows. It
+applies only to the pre-built &quot;binaries&quot; package, and not to versions
+compiled from source code. If you would like to install GraphicsMagick
+from source code, then please refer to the Installing From Source Code
+section.</blockquote>
+<div class="section" id="prerequisites">
+<h2><a class="toc-backref" href="#id2">Prerequisites</a></h2>
+<blockquote>
+<p>While multiple versions of GraphicsMagick may be installed at one
+time, if your intention is to replace a prior installation of
+GraphicsMagick with a newer version, then it is wise to uninstall
+the existing GraphicsMagick (see uninstall procedure) prior to
+installing the newer version.</p>
+<p>While it is not a requirement, it is strongly recommended that the
+<a class="reference external" href="http://sourceforge.net/projects/ghostscript/">Ghostscript</a>
+package (GraphicsMagick is tested with version 9.10) be
+installed. GraphicsMagick uses Ghostscript to render Postscript and
+PDF files, as well as formats where a translator to Postscript is
+available. GraphicsMagick will use the <a class="reference external" href="http://sourceforge.net/projects/gs-fonts/">Ghostscript Fonts</a> to support the
+standard set of Adobe Postscript fonts like &quot;Helvetica&quot; and &quot;Times
+Roman&quot; if these fonts are not available as TrueType fonts. The
+Ghostscript fonts need to manually installed with administrator
+privileges in the Ghostscript installation directory.</p>
+<p>Make sure to install a Ghostscript which is compatible with the
+GraphicsMagick you are installing. For example, if you are
+installing a 64-bit GraphicsMagick, you should install a 64-bit
+Ghostscript. The installation order of the two packages is not
+important. Both 32 and 64-bit versions of GraphicsMagick and
+Ghostscript may be installed at the same time.</p>
+</blockquote>
+</div>
+<div class="section" id="retrieve-install-package">
+<h2><a class="toc-backref" href="#id3">Retrieve Install Package</a></h2>
+<blockquote>
+<p>Retrieve the GraphicsMagick Windows binary install package from a one
+of the ftp sites listed at the <a class="reference external" href="download.html">GraphicsMagick Download Sites</a> page. The available install packages are as follows</p>
+<p>Windows Dynamic-Multithread (DLL-based) install package with utilities,
+ImageMagickObject COM object, and web pages:</p>
+<blockquote>
+<pre class="literal-block">
+GraphicsMagick-1.3-Q8-win32-dll.exe
+GraphicsMagick-1.3-Q16-win32-dll.exe
+GraphicsMagick-1.3-Q8-win64-dll.exe
+GraphicsMagick-1.3-Q16-win64-dll.exe
+</pre>
+</blockquote>
+<p>Note that the QuantumDepth=8 version (Q8) which provides industry
+standard 24/32 bit pixels consumes half the memory and about 30% less
+CPU than the QuantumDepth=16 version (Q16) which provides 48/64 bit
+pixels for high-resolution color. A Q8 version is fine for processing
+typical photos intended for viewing on a computer screen. If you are
+dealing with film, scientific, or medical images, use ICC color
+profiles, or deal with images that have limited contrast, then the Q16
+version is recommended.</p>
+<p>The <cite>win32' packages are for 32-bit or 64-bit Windows, whereas the
+`win64</cite> packages are only for 64-bit Windows. The 64-bit version
+allows processing larger images in memory (rather than disk files),
+provided that the system has more than 2GB of RAM installed. Memory
+access is 1000 times faster than disk access.</p>
+</blockquote>
+</div>
+<div class="section" id="start-installation-wizard">
+<h2><a class="toc-backref" href="#id4">Start Installation Wizard</a></h2>
+<blockquote>
+Execute the downloaded file from your browser or by double-clicking on
+the filename from within Windows Explorer. The GraphicsMagick Setup
+Wizard will appear. Click on &quot;<em>Next&gt;</em>&quot; to continue.</blockquote>
+</div>
+<div class="section" id="read-installation-information">
+<h2><a class="toc-backref" href="#id5">Read Installation Information</a></h2>
+<blockquote>
+An informational screen is presented which provides a summary of things
+you should know before you proceed. Please take care to read this
+information. Once you have finished, Click on &quot;<em>Next&gt;</em>&quot; to continue.</blockquote>
+</div>
+<div class="section" id="select-destination-directory">
+<h2><a class="toc-backref" href="#id6">Select Destination Directory</a></h2>
+<blockquote>
+Specify what drive and directory to install GraphicsMagick into.
+Approximately 15MB of free disk space is required to install all of
+GraphicsMagick (you may choose to install a subset to save space). A
+message at the bottom of the screen will tell you exactly how much
+space is required to install the complete package. The default
+installation directory is similar to <tt class="docutils literal"><span class="pre">C:\Program</span>
+<span class="pre">Files\GraphicsMagick-1.3-Q8</span></tt>. Once you have entered the desired
+installation directory, then select &quot;<em>Next&gt;</em>&quot; to continue.</blockquote>
+</div>
+<div class="section" id="select-start-menu-folder">
+<h2><a class="toc-backref" href="#id7">Select Start Menu Folder</a></h2>
+<blockquote>
+Select the folder where you would like the program's shortcuts to
+appear. The default should normally be satisfactory. Click on &quot;<em>Next&gt;</em>&quot;
+to continue.</blockquote>
+</div>
+<div class="section" id="select-additional-tasks">
+<h2><a class="toc-backref" href="#id8">Select Additional Tasks</a></h2>
+<blockquote>
+<p>A screen is displayed which presents most (or all) of the following
+options:</p>
+<ul class="simple">
+<li>Create a desktop icon</li>
+<li>Update executable search path</li>
+<li>Associate supported file extensions with GraphicsMagick</li>
+<li>Install ImageMagickObject OLE Control for VBscript, Visual Basic,
+and WSH.</li>
+</ul>
+<p>&quot;Creating a desktop icon&quot; and &quot;Update the executable search path&quot;
+are selected by default. The remaining options default to
+un-selected. Select the options you prefer.</p>
+<p>Think twice before selecting &quot;<em>Associate supported file extensions with
+GraphicsMagick</em>&quot; since this will set up approximately fifty file
+associations, including common formats like JPEG, GIF, PNG, TIFF, and
+PDF. These file associations will be to the 'gmdisplay' program which
+is suitable for displaying images, but currently offers little more
+than that. Windows XP seems to handle the file associations pretty
+well, allowing you to choose from a list of programs, but older systems
+like Windows NT 4.0 and Windows '98 only support a single association
+per format, which can be quite annoying. Associations for
+GraphicsMagick's native formats (such as <a class="reference external" href="miff.html">MIFF</a>) will
+always be made.</p>
+<p>Once you have made your selections, click on &quot;<em>Next&gt;</em>&quot; to continue.</p>
+</blockquote>
+</div>
+<div class="section" id="ready-to-install">
+<h2><a class="toc-backref" href="#id9">Ready to Install</a></h2>
+<blockquote>
+A screen is displayed which displays the selected options. If you are
+not satisfied with a selected option, then click on &quot;<em>&lt;Back</em>&quot; to go back
+to a previous screen so that the option may be adjusted. If you are
+satisfied with the options and are ready to install, then select
+&quot;<em>Install</em>&quot;. To abort the installation entirely, select &quot;<em>Cancel</em>&quot;.</blockquote>
+</div>
+<div class="section" id="installation-progress">
+<h2><a class="toc-backref" href="#id10">Installation Progress</a></h2>
+<blockquote>
+While the install program is performing the installation, it will
+display what it is doing in an installation progress window.</blockquote>
+</div>
+<div class="section" id="final-information">
+<h2><a class="toc-backref" href="#id11">Final Information</a></h2>
+<blockquote>
+A summary of post-install steps is provided. These steps include some
+commands you can execute to make sure that GraphicsMagick is working,
+as well as some notes about what has been installed on your system, and
+where to find additional information. Once you have read this
+information, click on &quot;<em>Next&gt;</em>&quot; to continue.</blockquote>
+</div>
+<div class="section" id="finishing-up">
+<h2><a class="toc-backref" href="#id12">Finishing Up</a></h2>
+<blockquote>
+By default &quot;<em>View GraphicsMagick.html</em>&quot; is check-marked. This causes the
+GraphicsMagick web pages to be displayed in your web browser when
+&quot;<em>Finish</em>&quot; is selected. If you do not want to view the web pages, then
+de-select &quot;<em>View GraphicsMagick.html</em>&quot;. Select &quot;<em>Finish</em>&quot; to exit the
+installation program.</blockquote>
+</div>
+<div class="section" id="testing-the-installation">
+<h2><a class="toc-backref" href="#id13">Testing The Installation</a></h2>
+<blockquote>
+<p>Select &quot;<em>Command Prompt</em>&quot; from the Windows Start menu. Within the window
+type</p>
+<blockquote>
+<pre class="literal-block">
+gm convert logo: logo.miff
+gmdisplay logo.miff
+</pre>
+</blockquote>
+<p>and the GraphicsMagick logo should be displayed in a window.</p>
+</blockquote>
+</div>
+<div class="section" id="uninstall">
+<h2><a class="toc-backref" href="#id14">Uninstall</a></h2>
+<blockquote>
+<p>The GraphicsMagick package incorporates its own uninstall
+functionality. Always remove an installed GraphicsMagick via its
+uninstall function since manually removing it (such as by removing its
+installation directory) will leave behind the registry entries and path
+settings established at install time.</p>
+<p>Under Windows '95 and Windows '98, use the &quot;<em>Uninstall</em>&quot; entry in the
+GraphicsMagick portion of the Windows start menu to initiate the
+uninstall.</p>
+<p>On NT 4.0 and 5.X -based systems, GraphicsMagick should be removed via
+the &quot;<em>Add or Remove Programs</em>&quot; area of the Windows Control Panel. Select
+the GraphicsMagick package from the list, and click on &quot;<em>Change/Remove</em>&quot;
+to uninstall it.</p>
+</blockquote>
+</div>
+<div class="section" id="use-from-another-package-or-program">
+<h2><a class="toc-backref" href="#id15">Use From Another Package or Program</a></h2>
+<blockquote>
+<p>The GraphicsMagick gm utility may be executed as a sub-process by other
+programs. If gm utility is not in the systems executable search path
+(it should be since the GraphicsMagick install extends the path), then
+the utility should be executed via the complete path to the executable.</p>
+<p>The <a class="reference external" href="ImageMagickObject.html">ImageMagickObject</a> COM object may be
+used to execute the gm sub-functions (e.g. &quot;convert&quot;) without spawning
+a new process or causing Windows to pop up a window. The COM object
+supports multi-threaded concurrent use.</p>
+<p>When GraphicsMagick is installed, entries are added to the Windows
+Registry so that other programs may obtain information regarding the
+most recently installed GraphicsMagick. These entries are available
+under the registry path <tt class="docutils literal">HKEY_LOCAL_MACHINE\SOFTWARE\GraphicsMagick\Current</tt>.</p>
+<p>These registry keys are currently available:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="25%" />
+<col width="12%" />
+<col width="64%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Key Name</th>
+<th class="head">Key Type</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>BinPath</td>
+<td>REG_SZ</td>
+<td>Directory where GraphicsMagick executables
+are installed</td>
+</tr>
+<tr><td>ConfigurePath</td>
+<td>REG_SZ</td>
+<td>Directory where configuration files are
+installed</td>
+</tr>
+<tr><td>LibPath</td>
+<td>REG_SZ</td>
+<td>Directory where GraphicsMagick core DLLs
+are installed</td>
+</tr>
+<tr><td>CoderModulesPath</td>
+<td>REG_SZ</td>
+<td>Directory where GraphicsMagick loadable
+coder modules are installed</td>
+</tr>
+<tr><td>FilterModulesPath</td>
+<td>REG_SZ</td>
+<td>Directory where GraphicsMagick loadable
+filter modules are installed</td>
+</tr>
+<tr><td>SharePath</td>
+<td>REG_SZ</td>
+<td>Directory where configuration files are
+installed</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+</div>
+</div>
+<div class="section" id="installing-from-source-code">
+<h1><a class="toc-backref" href="#id16">Installing From Source Code</a></h1>
+<div class="section" id="applicability">
+<h2><a class="toc-backref" href="#id17">Applicability</a></h2>
+<blockquote>
+This section provides instructions for building GraphicsMagick
+Microsoft Windows using the Visual C++ (Visual Studio, etc.) IDE. For
+building using the free Cygwin or MinGW compilers, follow the
+instructions in INSTALL-unix.txt.</blockquote>
+</div>
+<div class="section" id="important-notes">
+<h2><a class="toc-backref" href="#id18">Important Notes</a></h2>
+<blockquote>
+On some platforms Visual C++ may fail with an internal compiler
+error. If this happens to you, then make sure that your compiler is
+updated with the latest fixes from the Microsoft web site and the
+problem will hopefully go away. If the problem does not go away,
+then adjust the settings for the module which failed and disable
+optimization, and the problem is likely to go away (but with less
+performance).</blockquote>
+</div>
+<div class="section" id="windows-xp-vista-7-visual-c-6-0-through-14-0-compilation">
+<h2><a class="toc-backref" href="#id19">Windows XP, Vista, 7 Visual C++ 6.0 through 14.0 Compilation</a></h2>
+<blockquote>
+<p>The Visual C++ distribution targeted at Windows 2000 through Windows
+8 does not provide any stock workspace (DSW) or project files (DSP)
+except for those included with third party libraries. Instead, there
+is a &quot;configure&quot; program that must run to create build
+environments to satisfy various requirements.</p>
+<p>The configure program resides in VisualMagickconfigure in the
+GraphicsMagick source tree. A pre-compiled configure.exe is
+provided, as well as Visual Studio project files to recompile it
+from source code if needed.</p>
+<p>Once started, the configure program provides this configuration
+dialog after proceeding past the initial notifications screen:</p>
+<img alt="Configure program screen shot" class="align-center" src="configure-target-setup.png" style="width: 512.0px; height: 485.0px;" />
+<p>In addition to (or as a replacement to) the above dialog, the
+configure.exe program supports these command-line options:</p>
+<dl class="docutils">
+<dt><cite>/Q8 /Q16 /Q32</cite></dt>
+<dd>Set quantum depth</dd>
+<dt><cite>/x64</cite></dt>
+<dd>Add x64 configuration</dd>
+<dt><cite>/mtd /sts /mts /mtsd</cite></dt>
+<dd>Set project type</dd>
+<dt><cite>/noWizard</cite></dt>
+<dd>Do not show the wizard</dd>
+<dt><cite>/openMP</cite></dt>
+<dd>Enable openMP</dd>
+</dl>
+<p>The Visual C++ system provides three different types of &quot;runtimes&quot;
+that must match across all application, library, and DLL code that is
+built. The &quot;configure&quot; program creates a set of build files that are
+consistent for a specific runtime selection.</p>
+<p>The three options for runtime support are:</p>
+<ol class="arabic simple">
+<li>Dynamic Multi-threaded DLL runtimes (VisualDynamicMT), <cite>/mtd</cite> option</li>
+<li>Static Single-threaded runtimes (<cite>VisualStaticST</cite>), <cite>/sts</cite> option</li>
+<li>Static Multi-threaded runtimes (VisualStaticMT), <cite>/mts</cite> option</li>
+<li>Static Multi-threaded DLL runtimes (VisualStaticMTDLL), <cite>/mtsd</cite> option</li>
+</ol>
+<p>In addition to these runtimes, the VisualMagick build environment allows
+you to select whether to include the X11 libraries in the build or not.
+X11 DLLs and headers are provided with the VisualMagick build
+environment. Most Windows users do not use X11 so they will prefer to
+build without X11 support. When X11 is not supported, gm subcommands
+'animate', 'display', and 'import' will not work.</p>
+<p>This leads to five different possible build options, which should
+cover almost any particular situation. The default binary
+distribution is built using #1 from above with the X11 libraries
+excluded. This results build using all DLL's for everything and
+multi-threaded support (the only option for DLL's).</p>
+<p>To do a build for your requirements, simply go to the configure sub-
+directory under VisualMagick and open the configure.dsw workspace (for
+Visual C++ 6.0) or configure.sln (for Visual C++ 7.X or 8.X). Set the
+build configuration to &quot;Release&quot; under the</p>
+<blockquote>
+&quot;Build..., Set Active Configuration...&quot; menu.</blockquote>
+<p>Build and execute the configure program and follow the on-screen
+instructions. You should not change any of the defaults unless you have a
+specific reason to do so.</p>
+<p>The configure program provides a button entitled</p>
+<blockquote>
+Edit &quot;magick_config.h&quot;</blockquote>
+<p>Clicking this button brings up magick_config.h in Windows notepad
+for optionally changing any preprocessor defines in GraphicsMagick's
+magick_config.h file. This file is copied to
+<tt class="docutils literal">magick\magick_config.h</tt>. You may safely open
+<tt class="docutils literal">magick\magick_config.h</tt>, modify it, and recompile without
+re-running the configure program. In fact, using Visual Studio to
+edit the copied file may be preferable since it preserves the
+original magick_config.h file.</p>
+<p>Key user tunables in magick_config.h include:</p>
+<blockquote>
+<p>QuantumDepth (default 8)</p>
+<blockquote>
+Specify size of PixelPacket color Quantums (8, 16, or 32) A value of
+8 uses half the memory than 16 and may run 30% faster, but provides
+256 times less color resolution than a value of 16.</blockquote>
+<p>UseInstalledMagick (default undefined)</p>
+<blockquote>
+Define to build a GraphicsMagick which uses registry settings or
+embedded paths to locate installed components (coder modules and
+configuration files). The default is to look for all files in the
+same directory as the executable.</blockquote>
+<p>ProvideDllMain (default undefined)</p>
+<blockquote>
+Define to include a DllMain() function ensures that the GraphicsMagick
+DLL is properly initialized without participation from dependent
+applications. This avoids the requirement to invoke IntializeMagick()
+from dependent applications but only works for DLL builds.</blockquote>
+<p>EnableBrokenCoders (default undefined)</p>
+<blockquote>
+Define to enable broken/dangerous file format support. Only
+enable this if you have complete control over the input files
+and not for arbitrary files such as uploaded from untrusted
+sources via the Internet. Currently this must be enabled to
+enable Adobe Photoshop Format (PSD).</blockquote>
+</blockquote>
+<p>After creating your build environment you can proceed to open the DSW (or
+SLN) file that was generated in the VisualMagick directory and build
+everything from there.</p>
+<p>In the final DSW file you will find a project call &quot;All&quot;. In order to
+build everything in the distribution, select this project and make it
+the &quot;active&quot; project. Set the build configuration to the desired one
+(Debug, or Release) and do a &quot;clean&quot; followed by a &quot;build&quot;. You should
+do the build in a specific way:</p>
+<blockquote>
+<ol class="arabic simple">
+<li>Make the &quot;All&quot; project the active project (Bold)
+Right click on the All project and select &quot;Set As Active Project&quot;</li>
+<li>Select &quot;Build..., Clean&quot;</li>
+<li>Select &quot;Build..., Build&quot;</li>
+<li>Go get some coffee unless you have a very fast machine!.</li>
+</ol>
+</blockquote>
+<p>The &quot;Clean&quot; step is needed in order to make sure that all of the target
+support libraries are updated with any patches needed to get them to
+compile properly under Visual C++.</p>
+<p>All of the required files that are needed to run any of the command
+line tools will be found in the &quot;bin&quot; subdirectory of the VisualMagick
+subdirectory. This includes EXE, and DLL files. You should be able
+to test the build directly from this directory without having to move
+anything to any of the global SYSTEM or SYSTEM32 areas in the operating
+system installation.</p>
+<p>Note #1:</p>
+<p>The Visual C++ distribution of GraphicsMagick comes with the Magick++
+C++ wrapper by default. This add-on layer has a large number of demo
+and test files that can be found in <tt class="docutils literal"><span class="pre">GraphicsMagick\Magick++\demo</span></tt>, and
+<tt class="docutils literal"><span class="pre">GraphicsMagick\Magick++\tests</span></tt>. There are also a variety of tests that
+use the straight C API as well in <tt class="docutils literal">GraphicsMagick\tests</tt>.</p>
+<p>All of these programs are NOT configured to be built in the default
+workspace created by the configure program. You can cause all of these
+demos and test programs to be built by checking the box in configure
+that says:</p>
+<blockquote>
+&quot;Include all demo and test programs&quot;</blockquote>
+<p>In addition, there is another related checkbox (checked by default)
+that causes all generated project files to be created standalone so
+that they can be copied to other areas of you system.</p>
+<p>This is the checkbox:</p>
+<blockquote>
+&quot;Generate all utility projects with full paths rather then relative
+paths&quot;</blockquote>
+<p>WOW - that a mouthfull - eh?</p>
+<p>Visual C++ uses a concept of &quot;dependencies&quot; that tell it what other
+components need to be build when a particular project is being build. This
+mechanism is also used to ensure that components link properly. In my normal
+development environment, I want to be able to make changes and debug the
+system as a whole, so I like and NEED to use dependencies. However, most
+end users don't want to work this way.</p>
+<p>Instead they really just want to build the package and then get down
+to business working on their application. The solution is to make all
+the utility projects (UTIL_xxxx_yy_exe.dsp) use full absolute paths
+to all the things they need. This way the projects stand on their own
+and can actually be copied and used as templates to get a particular
+custom application compiling with little effort.</p>
+<p>With this feature enabled, you should be able to nab a copy of...</p>
+<blockquote>
+<p><tt class="docutils literal">VisualMagick\utilities\UTIL_gm_xxx_exe.dsp</tt> (for C)</p>
+<blockquote>
+-or-</blockquote>
+<p><tt class="docutils literal"><span class="pre">VisualMagick\Magick++\demo\UTIL_demo_xxx_exe.dsp</span></tt> (for C++)</p>
+</blockquote>
+<p>... and pop it into notepad, modify it (carefully) to your needs and
+be on your way to happy compiling and linking.</p>
+<p>You can feel free to pick any of the standard utilities, tests, or
+demo programs as the basis for a new program by copying the project
+and the source and hacking away.</p>
+<p>The choice of what to use as a starting point is very easy...</p>
+<p>For straight C API command line applications use something from</p>
+<blockquote>
+<p><tt class="docutils literal">GraphicsMagick\tests</tt> or <tt class="docutils literal">GraphicsMagick\utilities</tt> (source code)</p>
+<p><tt class="docutils literal">GraphicsMagick\VisualMagick\tests</tt> or <tt class="docutils literal">GraphicsMagick\Visualmagick\utilities</tt>
+(project - DSP)</p>
+</blockquote>
+<p>For C++ and Magick++ command line applications use something from</p>
+<blockquote>
+<p><tt class="docutils literal"><span class="pre">GraphicsMagick\Magick++\tests</span></tt> or <tt class="docutils literal"><span class="pre">GraphicsMagick\Magick++\demo</span></tt> (source code)</p>
+<p><tt class="docutils literal"><span class="pre">GraphicsMagick\VisualMagick\Magick++\tests</span></tt> or
+<tt class="docutils literal"><span class="pre">GraphicsMagick\VisualMagick\Magick++\demo</span></tt> (project - DSP)</p>
+</blockquote>
+<p>For C++ and Magick++ and MFC windows applications use</p>
+<blockquote>
+<p><tt class="docutils literal">GraphicsMagick\win2k\IMDisplay</tt> (source code)</p>
+<p><tt class="docutils literal">GraphicsMagick\VisualMagick\win32\NtMagick</tt> (project - DSP)</p>
+</blockquote>
+<p>Note #2:</p>
+<p>The GraphicsMagick distribution is very modular. The default
+configuration is there to get you rolling, but you need to make some
+serious choices when you wish to change things around.</p>
+<p>The default options are all targeted at having all the components in one
+place (e.g. the &quot;bin&quot; directory of the VisualMagick build tree). These
+components may be copied to another folder (such as to another computer).</p>
+<p>The folder containing the executables and DLLs should contain the
+following files:</p>
+<blockquote>
+<ol class="arabic simple">
+<li>colors.mgk</li>
+<li>delegates.mgk</li>
+<li>log.mgk</li>
+<li>magic.mgk</li>
+<li>modules.mgk</li>
+<li>type.mgk</li>
+<li>type-ghostscript.mgk (if Ghostscript is used)</li>
+</ol>
+</blockquote>
+<p>The &quot;bin&quot; folder should contains all EXE's and DLL's as well as the
+very important &quot;modules.mgk&quot; file.</p>
+<p>With this default setup, you can use any of the command line tools
+and run scripts as normal. You can actually get by quite nicely this
+way by doing something like <tt class="docutils literal">pushd <span class="pre">e:\xxx\yyy\bin</span></tt> in any scripts you
+write to execute &quot;out of&quot; this directory.</p>
+<p>By default the core of GraphicsMagick on Win32 always looks in the place
+were the exe program is run from in order to find all of the files as
+well as the DLL's it needs.</p>
+</blockquote>
+</div>
+<div class="section" id="environment-variables">
+<h2><a class="toc-backref" href="#id20">Environment Variables</a></h2>
+<blockquote>
+<p>You can use the &quot;System&quot; control panel to allow you to add and delete
+what is in any of the environment variables. You can even have user
+specific environment variables if you wish.</p>
+<p>PATH</p>
+<blockquote>
+<p>This sets the default list of places were Windows looks for EXE's and
+DLL's. Windows CMD shell seems to look in the &quot;current&quot; directory first
+- no matter what, which may make it unnecessary to update the PATH. If
+you wish to run any of utilities from another location then you must
+add the path to your &quot;bin&quot; directory in. For instance, you might add:</p>
+<blockquote>
+<tt class="docutils literal"><span class="pre">D:\Devel\GraphicsMagick\VisualMagick\bin</span></tt></blockquote>
+<p>to do this for the default build environment like I do.</p>
+</blockquote>
+<p>MAGICK_HOME</p>
+<blockquote>
+<p>If all you do is modify the PATH variable, the first problem you
+will run into is that GraphicsMagick may not be able to find any of
+its &quot;modules. Modules are all the IM_MOD*.DLL files you see in the
+distribution. There is one of these for each and every file format
+that GraphicsMagick supports. This environment variable tells the system
+were to look for these DLL's. The compiled in &quot;default&quot; is &quot;execution
+path&quot; - which says - look in the same place that the application is
+running &quot;in&quot;. If you are running from somewhere other then &quot;bin&quot; -
+this will no longer work and you must use this variable. If you elect
+to leave the modules in the same place as the EXE's (a good idea)
+then you can simply set this to the same place
+as you did the PATH variable. In my case:</p>
+<blockquote>
+<tt class="docutils literal"><span class="pre">D:\\GraphicsMagick\coders</span></tt></blockquote>
+<p>This is also the place were GraphicsMagick expects to find the
+&quot;colors.mgk&quot;, &quot;delegates.mgk&quot;, &quot;magic.mgk&quot;, &quot;modules.mgk&quot;, and
+&quot;type.mgk&quot; files.</p>
+<p>One cool thing about the modules build of GraphicsMagick is that you can
+now leave out file formats and lighten you load. If all you ever need
+is GIF and JPEG, then simply drop all the other DLL's into the local
+trash can and get on with your life.</p>
+<p>WARNING: Always keep the &quot;xc&quot; format, since GM uses it for internal
+purposes.</p>
+</blockquote>
+<p>ALSO. You can elect to changes these things the good old &quot;hard-coded&quot;
+way. Two #defines are applicable.</p>
+<p>defines.h has</p>
+<blockquote>
+<tt class="docutils literal">#define MagickConfigurePath&nbsp; <span class="pre">&quot;c:\\GraphicsMagick\\&quot;</span></tt></blockquote>
+<p>To view any image in a Microsoft window, type</p>
+<blockquote>
+<tt class="docutils literal">gm convert image.ext win:</tt></blockquote>
+<p>Make sure Ghostscript is installed, otherwise, you will be unable to
+convert or view a Postscript document, and Postscript standard fonts will
+not be available.</p>
+<p>You may use any standard web browser (e.g. Internet Explorer) to browse
+the GraphicsMagick documentation.</p>
+<p>The Win2K executables will work under Windows '98 and later.</p>
+</blockquote>
+</div>
+<div class="section" id="windows-distribution-build-procedure">
+<h2><a class="toc-backref" href="#id21">Windows Distribution Build Procedure</a></h2>
+<blockquote>
+<p>The following are the instructions for how to build a Q:8 (or Q:16)
+DLL-based distribution installer package using Visual Studio 2008
+Professional. This is the same procedure used to produce the
+release packages. The PerlMagick steps are skipped as of
+GraphicsMagick 1.3.26):</p>
+<ol class="arabic simple">
+<li>Install prerequisite software:</li>
+</ol>
+<blockquote>
+<ol class="loweralpha simple">
+<li>Install Microsoft Visual Studio.</li>
+<li>Download and install Inno Setup 5
+&lt;&quot;<a class="reference external" href="http://www.jrsoftware.org/isinfo.php">http://www.jrsoftware.org/isinfo.php</a>&quot;&gt;.</li>
+<li>Download and install ActiveState ActivePerl (optional)
+&lt;&quot;<a class="reference external" href="http://www.activestate.com/activeperl/downloads/">http://www.activestate.com/activeperl/downloads/</a>&quot;&gt;.</li>
+</ol>
+</blockquote>
+<ol class="arabic" start="2">
+<li><p class="first">Disable automatic indexing and virus scanning for the
+GraphicsMagick source tree. In particular, &quot;Windows Defender&quot; in
+Windows 10 (and similar software in earlier Windows releases) has
+been observed to cause Visual Studio builds to fail since the
+virus scanner opens built libraries and executables to inspect
+whem while Visual Studio is still using them. Indexing and
+scanning also cause significant slowdowns since there are many
+megabytes of files to index.</p>
+</li>
+<li><p class="first">Build <cite>GMVisualMagickconfigureconfigure.exe</cite> (if
+missing/outdated)</p>
+<ol class="loweralpha simple">
+<li>Open workspace <cite>GMVisualMagickconfigureconfigure.dsp</cite> by
+double-clicking from Windows Explorer.</li>
+<li>Upgrade Visual Studio project (as required)</li>
+<li>Select <cite>Rebuild All</cite> to build configure.exe</li>
+<li>Close the project.</li>
+</ol>
+</li>
+<li><p class="first">Configure Initial GraphicsMagick Visual Studio Workspace</p>
+<ol class="loweralpha simple">
+<li>Use Windows Explorer to navigate to <cite>GMVisualMagickconfigure</cite>.</li>
+<li>Double-click on <cite>configure.exe</cite> to run configure program.</li>
+<li>Select desired build options: DLL build, Quantum Depth, 64-bit, OpenMP)</li>
+<li>Check <cite>Build demo and test programs</cite>.</li>
+<li>Finish remaining configure wizard screens to complete.</li>
+<li><cite>File</cite> -&gt; <cite>Close Workspace</cite>.</li>
+</ol>
+</li>
+<li><p class="first">Open Workspace, set build configuration, build GraphicsMagick software.</p>
+<ol class="loweralpha simple">
+<li>Open workspace <cite>GMVisualMagickconfigureconfigure.sln</cite> by
+double-clicking from Windows Explorer.</li>
+<li>Build -&gt; &quot;Set Active Configuration&quot; -&gt; &quot;All - Win32 Release&quot; -&gt; OK</li>
+<li>Optionally enable 64-bit (WIN64) compilation. &quot;<cite>Build</cite> /
+<cite>Configuration Manager...</cite> / <cite>Active Solution Platform</cite> /
+<cite>New</cite> / <cite>x64</cite>&quot;.</li>
+<li>Open <cite>CORE_magickmagickmagick_config.h</cite> and edit any
+configuration settings you would like to change. For example,
+you might change QuantumDepth to 16 for a&quot;Q:16&quot; build.</li>
+<li>If using Visual Studio Professional Edition, and OpenMP
+support is desired, then select <cite>CORE_magick</cite> in the Solution
+Explorer pane and use the right mouse button menu to select
+<cite>Properties</cite>. In <cite>Configuration Properties</cite> / <cite>C/C++</cite> /
+<cite>Language</cite> set OpenMP support to 'yes'.</li>
+<li>Select &quot;Rebuild All&quot;</li>
+<li>Click on '!' icon to run configure program</li>
+<li>Select DLL build</li>
+<li>Check <cite>Build demo and test programs</cite>.</li>
+<li>Click on Edit <cite>magick_config.h</cite> and verify desired settings
+such as QuantumDepth. You can also defer this step to later
+by opening the header file
+<tt class="docutils literal">CORE_magick\include\magick_config.h</tt> in the Visual Studio
+project.</li>
+<li>Finish remaining configure wizard screens to complete.</li>
+<li>File -&gt; <cite>Close Workspace</cite></li>
+</ol>
+</li>
+<li><p class="first">Build ImageMagickObject</p>
+<ol class="loweralpha simple">
+<li>Open Visual Studio Command Shell Window for WIN32 or WIN64</li>
+<li>Change to GraphicsMagick project directory <tt class="docutils literal">GM</tt></li>
+<li><tt class="docutils literal">cd GM\contrib\win32\ATL7\ImageMagickObject</tt></li>
+<li><tt class="docutils literal">BuildImageMagickObject clean</tt></li>
+<li><tt class="docutils literal">BuildImageMagickObject release</tt></li>
+<li><tt class="docutils literal">cd <span class="pre">..\..\..\..</span></tt></li>
+</ol>
+</li>
+<li><p class="first">Build PerlMagick extension (optional)</p>
+<ol class="loweralpha">
+<li><p class="first">Open Visual Studio Command Shell Window for WIN32 or WIN64</p>
+</li>
+<li><p class="first">Change to GraphicsMagick project directory <tt class="docutils literal">GM</tt></p>
+</li>
+<li><p class="first"><tt class="docutils literal">cd GM\PerlMagick</tt></p>
+</li>
+<li><p class="first"><tt class="docutils literal">nmake clean</tt> (only if this is a rebuild)</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">C:\Perl32\bin\perl.exe</span> Makefile.nt</tt> (or Perl64)</p>
+<p>Note that if multiple Perl's are installed, then it may be
+necessary to specify the full path to perl.exe in order to use
+the correct Perl.</p>
+</li>
+<li><p class="first"><tt class="docutils literal">nmake release</tt></p>
+</li>
+</ol>
+</li>
+</ol>
+<p>NOTE: access to <em>nmake</em> requires that there be a path to it. Depending on
+how the install of Visual Studio was done, this may not be the case.
+Visual Studio provides a batch script in VC98Bin called VCVARS32.BAT
+that can be used to do this manually after you open up a command prompt.</p>
+<ol class="arabic simple" start="8">
+<li>Open <cite>GMVisualMagickinstallergm-win32-Q8-dll-full.iss</cite> (or
+<cite>gm-win32-Q16-dll-full.iss</cite> if QuantumDepth=16) by
+double-clicking from Windows Explorer.<ol class="loweralpha">
+<li><cite>File</cite> -&gt; <cite>Compile</cite></li>
+<li>Test install by clicking on green triangle</li>
+</ol>
+</li>
+<li>Test PerlMagick (optional).<ol class="loweralpha">
+<li><tt class="docutils literal">cd PerlMagick</tt></li>
+<li><tt class="docutils literal">nmake test</tt> (All tests must pass!)</li>
+</ol>
+</li>
+<li>Test file format read and write.</li>
+</ol>
+<blockquote>
+<ol class="loweralpha simple">
+<li><tt class="docutils literal">cd VisualMagick\tests</tt></li>
+<li><tt class="docutils literal">run_rwfile.bat</tt> (All tests must pass!)</li>
+<li><tt class="docutils literal">run_rwblob.bat</tt> (All tests must pass!)</li>
+</ol>
+</blockquote>
+<ol class="arabic simple" start="11">
+<li>Run Magick++ test programs.</li>
+</ol>
+<blockquote>
+<ol class="loweralpha simple">
+<li><tt class="docutils literal">cd <span class="pre">Magick++/tests</span></tt></li>
+<li><tt class="docutils literal">run_tests.bat</tt> (All tests must pass!)</li>
+</ol>
+</blockquote>
+<ol class="arabic simple" start="12">
+<li>Run Magick++ demo programs.</li>
+</ol>
+<blockquote>
+<ol class="loweralpha simple">
+<li><tt class="docutils literal">cd <span class="pre">Magick++/demo</span></tt></li>
+<li><tt class="docutils literal">run_demos.bat</tt></li>
+<li>Use <em>gmdisplay</em> to visually inspect all output files.</li>
+</ol>
+</blockquote>
+<ol class="arabic simple" start="13">
+<li>Distribution package is available named similar to
+<tt class="docutils literal"><span class="pre">GM\VisualMagick\bin\GraphicsMagick-1.3-Q8-dll.exe</span></tt></li>
+</ol>
+</blockquote>
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/INSTALL-windows.rst b/www/INSTALL-windows.rst
new file mode 100644
index 0000000..89f2949
--- /dev/null
+++ b/www/INSTALL-windows.rst
@@ -0,0 +1,771 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+===================================
+GraphicsMagick Windows Installation
+===================================
+
+.. contents::
+ :local:
+
+Installing Using Installer Package
+==================================
+
+ This section provides information specific to GraphicsMagick installed
+ via a "setup.exe" style installation wizard under Microsoft Windows. It
+ applies only to the pre-built "binaries" package, and not to versions
+ compiled from source code. If you would like to install GraphicsMagick
+ from source code, then please refer to the Installing From Source Code
+ section.
+
+Prerequisites
+-------------
+
+ While multiple versions of GraphicsMagick may be installed at one
+ time, if your intention is to replace a prior installation of
+ GraphicsMagick with a newer version, then it is wise to uninstall
+ the existing GraphicsMagick (see uninstall procedure) prior to
+ installing the newer version.
+
+ While it is not a requirement, it is strongly recommended that the
+ `Ghostscript <http://sourceforge.net/projects/ghostscript/>`_
+ package (GraphicsMagick is tested with version 9.10) be
+ installed. GraphicsMagick uses Ghostscript to render Postscript and
+ PDF files, as well as formats where a translator to Postscript is
+ available. GraphicsMagick will use the `Ghostscript Fonts
+ <http://sourceforge.net/projects/gs-fonts/>`_ to support the
+ standard set of Adobe Postscript fonts like "Helvetica" and "Times
+ Roman" if these fonts are not available as TrueType fonts. The
+ Ghostscript fonts need to manually installed with administrator
+ privileges in the Ghostscript installation directory.
+
+ Make sure to install a Ghostscript which is compatible with the
+ GraphicsMagick you are installing. For example, if you are
+ installing a 64-bit GraphicsMagick, you should install a 64-bit
+ Ghostscript. The installation order of the two packages is not
+ important. Both 32 and 64-bit versions of GraphicsMagick and
+ Ghostscript may be installed at the same time.
+
+Retrieve Install Package
+------------------------
+
+ Retrieve the GraphicsMagick Windows binary install package from a one
+ of the ftp sites listed at the `GraphicsMagick Download Sites
+ <download.html>`_ page. The available install packages are as follows
+
+ Windows Dynamic-Multithread (DLL-based) install package with utilities,
+ ImageMagickObject COM object, and web pages:
+
+ ::
+
+ GraphicsMagick-1.3-Q8-win32-dll.exe
+ GraphicsMagick-1.3-Q16-win32-dll.exe
+ GraphicsMagick-1.3-Q8-win64-dll.exe
+ GraphicsMagick-1.3-Q16-win64-dll.exe
+
+ Note that the QuantumDepth=8 version (Q8) which provides industry
+ standard 24/32 bit pixels consumes half the memory and about 30% less
+ CPU than the QuantumDepth=16 version (Q16) which provides 48/64 bit
+ pixels for high-resolution color. A Q8 version is fine for processing
+ typical photos intended for viewing on a computer screen. If you are
+ dealing with film, scientific, or medical images, use ICC color
+ profiles, or deal with images that have limited contrast, then the Q16
+ version is recommended.
+
+ The `win32' packages are for 32-bit or 64-bit Windows, whereas the
+ `win64` packages are only for 64-bit Windows. The 64-bit version
+ allows processing larger images in memory (rather than disk files),
+ provided that the system has more than 2GB of RAM installed. Memory
+ access is 1000 times faster than disk access.
+
+Start Installation Wizard
+-------------------------
+
+ Execute the downloaded file from your browser or by double-clicking on
+ the filename from within Windows Explorer. The GraphicsMagick Setup
+ Wizard will appear. Click on "*Next>*" to continue.
+
+Read Installation Information
+-----------------------------
+
+ An informational screen is presented which provides a summary of things
+ you should know before you proceed. Please take care to read this
+ information. Once you have finished, Click on "*Next>*" to continue.
+
+Select Destination Directory
+----------------------------
+
+ Specify what drive and directory to install GraphicsMagick into.
+ Approximately 15MB of free disk space is required to install all of
+ GraphicsMagick (you may choose to install a subset to save space). A
+ message at the bottom of the screen will tell you exactly how much
+ space is required to install the complete package. The default
+ installation directory is similar to ``C:\Program
+ Files\GraphicsMagick-1.3-Q8``. Once you have entered the desired
+ installation directory, then select "*Next>*" to continue.
+
+Select Start Menu Folder
+------------------------
+
+ Select the folder where you would like the program's shortcuts to
+ appear. The default should normally be satisfactory. Click on "*Next>*"
+ to continue.
+
+Select Additional Tasks
+-----------------------
+
+ A screen is displayed which presents most (or all) of the following
+ options:
+
+ * Create a desktop icon
+
+ * Update executable search path
+
+ * Associate supported file extensions with GraphicsMagick
+
+ * Install ImageMagickObject OLE Control for VBscript, Visual Basic,
+ and WSH.
+
+ "Creating a desktop icon" and "Update the executable search path"
+ are selected by default. The remaining options default to
+ un-selected. Select the options you prefer.
+
+ Think twice before selecting "*Associate supported file extensions with
+ GraphicsMagick*" since this will set up approximately fifty file
+ associations, including common formats like JPEG, GIF, PNG, TIFF, and
+ PDF. These file associations will be to the 'gmdisplay' program which
+ is suitable for displaying images, but currently offers little more
+ than that. Windows XP seems to handle the file associations pretty
+ well, allowing you to choose from a list of programs, but older systems
+ like Windows NT 4.0 and Windows '98 only support a single association
+ per format, which can be quite annoying. Associations for
+ GraphicsMagick's native formats (such as `MIFF <miff.html>`_) will
+ always be made.
+
+ Once you have made your selections, click on "*Next>*" to continue.
+
+Ready to Install
+----------------
+
+ A screen is displayed which displays the selected options. If you are
+ not satisfied with a selected option, then click on "*<Back*" to go back
+ to a previous screen so that the option may be adjusted. If you are
+ satisfied with the options and are ready to install, then select
+ "*Install*". To abort the installation entirely, select "*Cancel*".
+
+Installation Progress
+---------------------
+
+ While the install program is performing the installation, it will
+ display what it is doing in an installation progress window.
+
+
+Final Information
+-----------------
+
+ A summary of post-install steps is provided. These steps include some
+ commands you can execute to make sure that GraphicsMagick is working,
+ as well as some notes about what has been installed on your system, and
+ where to find additional information. Once you have read this
+ information, click on "*Next>*" to continue.
+
+Finishing Up
+------------
+
+ By default "*View GraphicsMagick.html*" is check-marked. This causes the
+ GraphicsMagick web pages to be displayed in your web browser when
+ "*Finish*" is selected. If you do not want to view the web pages, then
+ de-select "*View GraphicsMagick.html*". Select "*Finish*" to exit the
+ installation program.
+
+Testing The Installation
+------------------------
+
+ Select "*Command Prompt*" from the Windows Start menu. Within the window
+ type
+
+ ::
+
+ gm convert logo: logo.miff
+ gmdisplay logo.miff
+
+ and the GraphicsMagick logo should be displayed in a window.
+
+Uninstall
+---------
+
+ The GraphicsMagick package incorporates its own uninstall
+ functionality. Always remove an installed GraphicsMagick via its
+ uninstall function since manually removing it (such as by removing its
+ installation directory) will leave behind the registry entries and path
+ settings established at install time.
+
+ Under Windows '95 and Windows '98, use the "*Uninstall*" entry in the
+ GraphicsMagick portion of the Windows start menu to initiate the
+ uninstall.
+
+ On NT 4.0 and 5.X -based systems, GraphicsMagick should be removed via
+ the "*Add or Remove Programs*" area of the Windows Control Panel. Select
+ the GraphicsMagick package from the list, and click on "*Change/Remove*"
+ to uninstall it.
+
+Use From Another Package or Program
+-----------------------------------
+
+ The GraphicsMagick gm utility may be executed as a sub-process by other
+ programs. If gm utility is not in the systems executable search path
+ (it should be since the GraphicsMagick install extends the path), then
+ the utility should be executed via the complete path to the executable.
+
+ The `ImageMagickObject <ImageMagickObject.html>`_ COM object may be
+ used to execute the gm sub-functions (e.g. "convert") without spawning
+ a new process or causing Windows to pop up a window. The COM object
+ supports multi-threaded concurrent use.
+
+ When GraphicsMagick is installed, entries are added to the Windows
+ Registry so that other programs may obtain information regarding the
+ most recently installed GraphicsMagick. These entries are available
+ under the registry path ``HKEY_LOCAL_MACHINE\SOFTWARE\GraphicsMagick\Current``.
+
+ These registry keys are currently available:
+
+ ================= ======== ============================================
+ Key Name Key Type Description
+ ================= ======== ============================================
+ BinPath REG_SZ Directory where GraphicsMagick executables
+ are installed
+ ConfigurePath REG_SZ Directory where configuration files are
+ installed
+ LibPath REG_SZ Directory where GraphicsMagick core DLLs
+ are installed
+ CoderModulesPath REG_SZ Directory where GraphicsMagick loadable
+ coder modules are installed
+ FilterModulesPath REG_SZ Directory where GraphicsMagick loadable
+ filter modules are installed
+ SharePath REG_SZ Directory where configuration files are
+ installed
+ ================= ======== ============================================
+
+
+Installing From Source Code
+===========================
+
+Applicability
+-------------
+
+ This section provides instructions for building GraphicsMagick
+ Microsoft Windows using the Visual C++ (Visual Studio, etc.) IDE. For
+ building using the free Cygwin or MinGW compilers, follow the
+ instructions in INSTALL-unix.txt.
+
+Important Notes
+---------------
+
+ On some platforms Visual C++ may fail with an internal compiler
+ error. If this happens to you, then make sure that your compiler is
+ updated with the latest fixes from the Microsoft web site and the
+ problem will hopefully go away. If the problem does not go away,
+ then adjust the settings for the module which failed and disable
+ optimization, and the problem is likely to go away (but with less
+ performance).
+
+Windows XP, Vista, 7 Visual C++ 6.0 through 14.0 Compilation
+------------------------------------------------------------
+
+ The Visual C++ distribution targeted at Windows 2000 through Windows
+ 8 does not provide any stock workspace (DSW) or project files (DSP)
+ except for those included with third party libraries. Instead, there
+ is a "configure" program that must run to create build
+ environments to satisfy various requirements.
+
+ The configure program resides in VisualMagick\configure in the
+ GraphicsMagick source tree. A pre-compiled configure.exe is
+ provided, as well as Visual Studio project files to recompile it
+ from source code if needed.
+
+ Once started, the configure program provides this configuration
+ dialog after proceeding past the initial notifications screen:
+
+ .. image:: configure-target-setup.png
+ :height: 485px
+ :width: 512px
+ :scale: 100%
+ :alt: Configure program screen shot
+ :align: center
+
+ In addition to (or as a replacement to) the above dialog, the
+ configure.exe program supports these command-line options:
+
+ `/Q8 /Q16 /Q32`
+ Set quantum depth
+
+ `/x64`
+ Add x64 configuration
+
+ `/mtd /sts /mts /mtsd`
+ Set project type
+
+ `/noWizard`
+ Do not show the wizard
+
+ `/openMP`
+ Enable openMP
+
+ The Visual C++ system provides three different types of "runtimes"
+ that must match across all application, library, and DLL code that is
+ built. The "configure" program creates a set of build files that are
+ consistent for a specific runtime selection.
+
+ The three options for runtime support are:
+
+ 1) Dynamic Multi-threaded DLL runtimes (VisualDynamicMT), `/mtd` option
+ 2) Static Single-threaded runtimes (`VisualStaticST`), `/sts` option
+ 3) Static Multi-threaded runtimes (VisualStaticMT), `/mts` option
+ 4) Static Multi-threaded DLL runtimes (VisualStaticMTDLL), `/mtsd` option
+
+ In addition to these runtimes, the VisualMagick build environment allows
+ you to select whether to include the X11 libraries in the build or not.
+ X11 DLLs and headers are provided with the VisualMagick build
+ environment. Most Windows users do not use X11 so they will prefer to
+ build without X11 support. When X11 is not supported, gm subcommands
+ 'animate', 'display', and 'import' will not work.
+
+ This leads to five different possible build options, which should
+ cover almost any particular situation. The default binary
+ distribution is built using #1 from above with the X11 libraries
+ excluded. This results build using all DLL's for everything and
+ multi-threaded support (the only option for DLL's).
+
+ To do a build for your requirements, simply go to the configure sub-
+ directory under VisualMagick and open the configure.dsw workspace (for
+ Visual C++ 6.0) or configure.sln (for Visual C++ 7.X or 8.X). Set the
+ build configuration to "Release" under the
+
+ "Build..., Set Active Configuration..." menu.
+
+ Build and execute the configure program and follow the on-screen
+ instructions. You should not change any of the defaults unless you have a
+ specific reason to do so.
+
+ The configure program provides a button entitled
+
+ Edit "magick_config.h"
+
+ Clicking this button brings up magick_config.h in Windows notepad
+ for optionally changing any preprocessor defines in GraphicsMagick's
+ magick_config.h file. This file is copied to
+ ``magick\magick_config.h``. You may safely open
+ ``magick\magick_config.h``, modify it, and recompile without
+ re-running the configure program. In fact, using Visual Studio to
+ edit the copied file may be preferable since it preserves the
+ original magick_config.h file.
+
+ Key user tunables in magick_config.h include:
+
+ QuantumDepth (default 8)
+
+ Specify size of PixelPacket color Quantums (8, 16, or 32) A value of
+ 8 uses half the memory than 16 and may run 30% faster, but provides
+ 256 times less color resolution than a value of 16.
+
+ UseInstalledMagick (default undefined)
+
+ Define to build a GraphicsMagick which uses registry settings or
+ embedded paths to locate installed components (coder modules and
+ configuration files). The default is to look for all files in the
+ same directory as the executable.
+
+ ProvideDllMain (default undefined)
+
+ Define to include a DllMain() function ensures that the GraphicsMagick
+ DLL is properly initialized without participation from dependent
+ applications. This avoids the requirement to invoke IntializeMagick()
+ from dependent applications but only works for DLL builds.
+
+ EnableBrokenCoders (default undefined)
+
+ Define to enable broken/dangerous file format support. Only
+ enable this if you have complete control over the input files
+ and not for arbitrary files such as uploaded from untrusted
+ sources via the Internet. Currently this must be enabled to
+ enable Adobe Photoshop Format (PSD).
+
+ After creating your build environment you can proceed to open the DSW (or
+ SLN) file that was generated in the VisualMagick directory and build
+ everything from there.
+
+ In the final DSW file you will find a project call "All". In order to
+ build everything in the distribution, select this project and make it
+ the "active" project. Set the build configuration to the desired one
+ (Debug, or Release) and do a "clean" followed by a "build". You should
+ do the build in a specific way:
+
+ 1) Make the "All" project the active project (Bold)
+ Right click on the All project and select "Set As Active Project"
+ 2) Select "Build..., Clean"
+ 3) Select "Build..., Build"
+ 4) Go get some coffee unless you have a very fast machine!.
+
+ The "Clean" step is needed in order to make sure that all of the target
+ support libraries are updated with any patches needed to get them to
+ compile properly under Visual C++.
+
+ All of the required files that are needed to run any of the command
+ line tools will be found in the "bin" subdirectory of the VisualMagick
+ subdirectory. This includes EXE, and DLL files. You should be able
+ to test the build directly from this directory without having to move
+ anything to any of the global SYSTEM or SYSTEM32 areas in the operating
+ system installation.
+
+ Note #1:
+
+ The Visual C++ distribution of GraphicsMagick comes with the Magick++
+ C++ wrapper by default. This add-on layer has a large number of demo
+ and test files that can be found in ``GraphicsMagick\Magick++\demo``, and
+ ``GraphicsMagick\Magick++\tests``. There are also a variety of tests that
+ use the straight C API as well in ``GraphicsMagick\tests``.
+
+ All of these programs are NOT configured to be built in the default
+ workspace created by the configure program. You can cause all of these
+ demos and test programs to be built by checking the box in configure
+ that says:
+
+ "Include all demo and test programs"
+
+ In addition, there is another related checkbox (checked by default)
+ that causes all generated project files to be created standalone so
+ that they can be copied to other areas of you system.
+
+ This is the checkbox:
+
+ "Generate all utility projects with full paths rather then relative
+ paths"
+
+ WOW - that a mouthfull - eh?
+
+ Visual C++ uses a concept of "dependencies" that tell it what other
+ components need to be build when a particular project is being build. This
+ mechanism is also used to ensure that components link properly. In my normal
+ development environment, I want to be able to make changes and debug the
+ system as a whole, so I like and NEED to use dependencies. However, most
+ end users don't want to work this way.
+
+ Instead they really just want to build the package and then get down
+ to business working on their application. The solution is to make all
+ the utility projects (UTIL_xxxx_yy_exe.dsp) use full absolute paths
+ to all the things they need. This way the projects stand on their own
+ and can actually be copied and used as templates to get a particular
+ custom application compiling with little effort.
+
+ With this feature enabled, you should be able to nab a copy of...
+
+ ``VisualMagick\utilities\UTIL_gm_xxx_exe.dsp`` (for C)
+
+ -or-
+
+ ``VisualMagick\Magick++\demo\UTIL_demo_xxx_exe.dsp`` (for C++)
+
+ ... and pop it into notepad, modify it (carefully) to your needs and
+ be on your way to happy compiling and linking.
+
+ You can feel free to pick any of the standard utilities, tests, or
+ demo programs as the basis for a new program by copying the project
+ and the source and hacking away.
+
+ The choice of what to use as a starting point is very easy...
+
+ For straight C API command line applications use something from
+
+ ``GraphicsMagick\tests`` or ``GraphicsMagick\utilities`` (source code)
+
+ ``GraphicsMagick\VisualMagick\tests`` or ``GraphicsMagick\Visualmagick\utilities``
+ (project - DSP)
+
+ For C++ and Magick++ command line applications use something from
+
+ ``GraphicsMagick\Magick++\tests`` or ``GraphicsMagick\Magick++\demo`` (source code)
+
+ ``GraphicsMagick\VisualMagick\Magick++\tests`` or
+ ``GraphicsMagick\VisualMagick\Magick++\demo`` (project - DSP)
+
+ For C++ and Magick++ and MFC windows applications use
+
+ ``GraphicsMagick\win2k\IMDisplay`` (source code)
+
+ ``GraphicsMagick\VisualMagick\win32\NtMagick`` (project - DSP)
+
+ Note #2:
+
+ The GraphicsMagick distribution is very modular. The default
+ configuration is there to get you rolling, but you need to make some
+ serious choices when you wish to change things around.
+
+ The default options are all targeted at having all the components in one
+ place (e.g. the "bin" directory of the VisualMagick build tree). These
+ components may be copied to another folder (such as to another computer).
+
+ The folder containing the executables and DLLs should contain the
+ following files:
+
+ 1) colors.mgk
+ 2) delegates.mgk
+ 3) log.mgk
+ 4) magic.mgk
+ 5) modules.mgk
+ 6) type.mgk
+ 7) type-ghostscript.mgk (if Ghostscript is used)
+
+ The "bin" folder should contains all EXE's and DLL's as well as the
+ very important "modules.mgk" file.
+
+ With this default setup, you can use any of the command line tools
+ and run scripts as normal. You can actually get by quite nicely this
+ way by doing something like ``pushd e:\xxx\yyy\bin`` in any scripts you
+ write to execute "out of" this directory.
+
+ By default the core of GraphicsMagick on Win32 always looks in the place
+ were the exe program is run from in order to find all of the files as
+ well as the DLL's it needs.
+
+Environment Variables
+---------------------
+
+ You can use the "System" control panel to allow you to add and delete
+ what is in any of the environment variables. You can even have user
+ specific environment variables if you wish.
+
+ PATH
+
+ This sets the default list of places were Windows looks for EXE's and
+ DLL's. Windows CMD shell seems to look in the "current" directory first
+ - no matter what, which may make it unnecessary to update the PATH. If
+ you wish to run any of utilities from another location then you must
+ add the path to your "bin" directory in. For instance, you might add:
+
+ ``D:\Devel\GraphicsMagick\VisualMagick\bin``
+
+ to do this for the default build environment like I do.
+
+ MAGICK_HOME
+
+ If all you do is modify the PATH variable, the first problem you
+ will run into is that GraphicsMagick may not be able to find any of
+ its "modules. Modules are all the IM_MOD*.DLL files you see in the
+ distribution. There is one of these for each and every file format
+ that GraphicsMagick supports. This environment variable tells the system
+ were to look for these DLL's. The compiled in "default" is "execution
+ path" - which says - look in the same place that the application is
+ running "in". If you are running from somewhere other then "bin" -
+ this will no longer work and you must use this variable. If you elect
+ to leave the modules in the same place as the EXE's (a good idea)
+ then you can simply set this to the same place
+ as you did the PATH variable. In my case:
+
+ ``D:\\GraphicsMagick\coders``
+
+ This is also the place were GraphicsMagick expects to find the
+ "colors.mgk", "delegates.mgk", "magic.mgk", "modules.mgk", and
+ "type.mgk" files.
+
+ One cool thing about the modules build of GraphicsMagick is that you can
+ now leave out file formats and lighten you load. If all you ever need
+ is GIF and JPEG, then simply drop all the other DLL's into the local
+ trash can and get on with your life.
+
+ WARNING: Always keep the "xc" format, since GM uses it for internal
+ purposes.
+
+ ALSO. You can elect to changes these things the good old "hard-coded"
+ way. Two #defines are applicable.
+
+ defines.h has
+
+ ``#define MagickConfigurePath "c:\\GraphicsMagick\\"``
+
+ To view any image in a Microsoft window, type
+
+ ``gm convert image.ext win:``
+
+ Make sure Ghostscript is installed, otherwise, you will be unable to
+ convert or view a Postscript document, and Postscript standard fonts will
+ not be available.
+
+ You may use any standard web browser (e.g. Internet Explorer) to browse
+ the GraphicsMagick documentation.
+
+ The Win2K executables will work under Windows '98 and later.
+
+Windows Distribution Build Procedure
+------------------------------------
+
+ The following are the instructions for how to build a Q:8 (or Q:16)
+ DLL-based distribution installer package using Visual Studio 2008
+ Professional. This is the same procedure used to produce the
+ release packages. The PerlMagick steps are skipped as of
+ GraphicsMagick 1.3.26):
+
+ 1. Install prerequisite software:
+
+ a. Install Microsoft Visual Studio.
+
+ b. Download and install Inno Setup 5
+ <"http://www.jrsoftware.org/isinfo.php">.
+
+ c. Download and install ActiveState ActivePerl (optional)
+ <"http://www.activestate.com/activeperl/downloads/">.
+
+ 2. Disable automatic indexing and virus scanning for the
+ GraphicsMagick source tree. In particular, "Windows Defender" in
+ Windows 10 (and similar software in earlier Windows releases) has
+ been observed to cause Visual Studio builds to fail since the
+ virus scanner opens built libraries and executables to inspect
+ whem while Visual Studio is still using them. Indexing and
+ scanning also cause significant slowdowns since there are many
+ megabytes of files to index.
+
+ 3. Build `GM\VisualMagick\configure\configure.exe` (if
+ missing/outdated)
+
+ a. Open workspace `GM\VisualMagick\configure\configure.dsp` by
+ double-clicking from Windows Explorer.
+
+ b. Upgrade Visual Studio project (as required)
+
+ c. Select `Rebuild All` to build configure.exe
+
+ d. Close the project.
+
+ 4. Configure Initial GraphicsMagick Visual Studio Workspace
+
+ a. Use Windows Explorer to navigate to `GM\VisualMagick\configure`.
+
+ b. Double-click on `configure.exe` to run configure program.
+
+ c. Select desired build options: DLL build, Quantum Depth, 64-bit, OpenMP)
+
+ d. Check `Build demo and test programs`.
+
+ e. Finish remaining configure wizard screens to complete.
+
+ f. `File` -> `Close Workspace`.
+
+ 5. Open Workspace, set build configuration, build GraphicsMagick software.
+
+ a. Open workspace `GM\VisualMagick\configure\configure.sln` by
+ double-clicking from Windows Explorer.
+
+ b. Build -> "Set Active Configuration" -> "All - Win32 Release" -> OK
+
+ c. Optionally enable 64-bit (WIN64) compilation. "`Build` /
+ `Configuration Manager...` / `Active Solution Platform` /
+ `New` / `x64`".
+
+ d. Open `CORE_magick\magick\magick_config.h` and edit any
+ configuration settings you would like to change. For example,
+ you might change QuantumDepth to 16 for a"Q:16" build.
+
+ e. If using Visual Studio Professional Edition, and OpenMP
+ support is desired, then select `CORE_magick` in the Solution
+ Explorer pane and use the right mouse button menu to select
+ `Properties`. In `Configuration Properties` / `C/C++` /
+ `Language` set OpenMP support to 'yes'.
+
+ f. Select "Rebuild All"
+
+ g. Click on '!' icon to run configure program
+
+ h. Select DLL build
+
+ i. Check `Build demo and test programs`.
+
+ j. Click on Edit `magick_config.h` and verify desired settings
+ such as QuantumDepth. You can also defer this step to later
+ by opening the header file
+ ``CORE_magick\include\magick_config.h`` in the Visual Studio
+ project.
+
+ k. Finish remaining configure wizard screens to complete.
+
+ l. File -> `Close Workspace`
+
+ 6. Build ImageMagickObject
+
+ a. Open Visual Studio Command Shell Window for WIN32 or WIN64
+
+ b. Change to GraphicsMagick project directory ``GM``
+
+ c. ``cd GM\contrib\win32\ATL7\ImageMagickObject``
+
+ d. ``BuildImageMagickObject clean``
+
+ e. ``BuildImageMagickObject release``
+
+ f. ``cd ..\..\..\..``
+
+ 7. Build PerlMagick extension (optional)
+
+ a. Open Visual Studio Command Shell Window for WIN32 or WIN64
+
+ b. Change to GraphicsMagick project directory ``GM``
+
+ c. ``cd GM\PerlMagick``
+
+ d. ``nmake clean`` (only if this is a rebuild)
+
+ e. ``C:\Perl32\bin\perl.exe Makefile.nt`` (or Perl64)
+
+ Note that if multiple Perl's are installed, then it may be
+ necessary to specify the full path to perl.exe in order to use
+ the correct Perl.
+
+ f. ``nmake release``
+
+ NOTE: access to *nmake* requires that there be a path to it. Depending on
+ how the install of Visual Studio was done, this may not be the case.
+ Visual Studio provides a batch script in VC98\Bin called VCVARS32.BAT
+ that can be used to do this manually after you open up a command prompt.
+
+ 8. Open `GM\VisualMagick\installer\gm-win32-Q8-dll-full.iss` (or
+ `gm-win32-Q16-dll-full.iss` if QuantumDepth=16) by
+ double-clicking from Windows Explorer.
+
+ a. `File` -> `Compile`
+
+ b. Test install by clicking on green triangle
+
+ 9. Test PerlMagick (optional).
+
+ a. ``cd PerlMagick``
+
+ b. ``nmake test`` (All tests must pass!)
+
+ 10. Test file format read and write.
+
+ a. ``cd VisualMagick\tests``
+
+ b. ``run_rwfile.bat`` (All tests must pass!)
+
+ c. ``run_rwblob.bat`` (All tests must pass!)
+
+ 11. Run Magick++ test programs.
+
+ a. ``cd Magick++/tests``
+
+ b. ``run_tests.bat`` (All tests must pass!)
+
+ 12. Run Magick++ demo programs.
+
+ a. ``cd Magick++/demo``
+
+ b. ``run_demos.bat``
+
+ c. Use *gmdisplay* to visually inspect all output files.
+
+ 13. Distribution package is available named similar to
+ ``GM\VisualMagick\bin\GraphicsMagick-1.3-Q8-dll.exe``
+
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/ImageMagickObject.html b/www/ImageMagickObject.html
new file mode 100644
index 0000000..9433c02
--- /dev/null
+++ b/www/ImageMagickObject.html
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>ImageMagickObject</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="imagemagickobject">
+<h1 class="title">ImageMagickObject</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="section" id="overview">
+<h1>Overview</h1>
+<p>The <em>ImageMagickObject</em> is a COM+ compatible component that may be
+invoked from any language capable of using COM objects. The intended use
+is for Windows Scripting Host VBS scripts and Visual Basic, but it can
+also be used from C++, ASP, and other languages like Delphi, Perl and PHP.</p>
+<p>The strategy with the <em>ImageMagickObject</em> COM+ component is not to the
+same as with PerlMagick interface provided with ImageMagick. PerlMagick
+is a low level API based system that defines a whole new way of scripting
+IM operations. The IM COM+ component simply provides access to the
+<a class="reference external" href="convert.html">convert</a>, composite, <a class="reference external" href="mogrify.html">mogrify</a>, <a class="reference external" href="identify.html">identify</a>, and <a class="reference external" href="montage.html">montage</a> tools,
+efficiently executing them as part of your process, rather than as
+external programs. The way you use it is exactly the same. You pass it a
+list of strings including filenames and various options and it does the
+job. In fact, you can take any existing batch scripts that use the
+command line tools and translate them into the equivalent calls to the
+COM+ object in a matter of minutes. Beyond that, there is also a way to
+pass in and retrieve images in memory in the form of standard smart
+arrays (byte arrays). Samples are provided, to show both the simple and
+more elaborate forms of access.</p>
+<p><em>GraphicsMagick</em> provides a statically-built ImageMagick object as part of
+its &quot;utils&quot; <a class="reference external" href="INSTALL-windows.html">Windows installation package</a>. When this package is
+installed, <em>ImageMagickObject</em> and its sample programs are installed to</p>
+<pre class="literal-block">
+c:\Program Files\GraphicsMagick-1.3-Q16\ImageMagickObject
+</pre>
+<p>by default (path shown is for the Q:16 build). <em>ImageMagickObject</em> is
+registered if the checkbox for &quot;Register ImageMagickObject&quot; is checked at
+install time.</p>
+<p>You may execute the sample program from the Windows Command Shell like:</p>
+<pre class="literal-block">
+cscript SimpleTest.vbs
+</pre>
+<p>Since the <em>GraphicsMagick</em> utility command line parsers are incorporated
+within <em>ImageMagickObject</em>, please refer to the command line <a class="reference external" href="utilities.html">utility
+documentation</a> to learn how to use it. The sample VBS scripts show how
+the object should be called and used and have lots of comments.</p>
+<p>For C++ programmers - have a look at the MagickCMD.cpp command line
+utility for an example of how to call the object from C++. This is a bit
+complex because the object requires a variable size list of BSTR's to
+emulate the command line argc, argv style calling conventions of the COM
+component which is more complex in C++ then in VBS or VB.</p>
+</div>
+<div class="section" id="other-goodies">
+<h1>Other goodies...</h1>
+<p>MagickCMD is a C++ sample, but it can also server as a replacement for
+all the other command line utilities in most applications. Instead of
+using &quot;<tt class="docutils literal">convert xxxx yyyy</tt>&quot; you can use &quot;<tt class="docutils literal">MagickCMD convert xxxx
+yyyy</tt>&quot; instead. MagickCMD calls the COM object to get the job done. This
+small tight combination replaces the entire usual binary distribution in
+just a few megabytes.</p>
+</div>
+<div class="section" id="building-imagemagickobject-from-source">
+<h1>Building ImageMagickObject From Source</h1>
+<p>The source code for <em>ImageMagickObject</em> is available from <em>GraphicsMagick</em>
+CVS, or as part of the <em>GraphicsMagick</em> Windows source package. Once the
+source code has been retrieved and extracted, the source for
+<em>ImageMagickObject</em> may be found hidden in the directory
+&quot;<tt class="docutils literal">GraphicsMagick\contrib\win32\ATL7ImageMagickObject</tt>&quot;, however,
+<em>GraphicsMagick</em> itself must be built using the &quot;static-multithread&quot;
+(VisualStaticMT) build configuration. Building <em>ImageMagickObject</em>
+requires Microsoft Visual C++ 7.0 as delivered with Microsoft's Visual
+Studio .net package. See the Windows compilation instructions in order to
+get <em>GraphicsMagick</em> itself built before building <em>ImageMagickObject</em>.</p>
+<p>Once the VisualStaticMT project has been built, <em>ImageMagickObject</em> may
+be built by following the procedure:</p>
+<pre class="literal-block">
+cd GraphicsMagick\contrib\win32\ATL7ImageMagickObject
+BuildImageMagickObject release
+</pre>
+<p>This procedure assumes that the VisualStaticMT project has been built
+using the &quot;release&quot; setting for an optimized build. If the &quot;debug&quot;
+setting was used for a debug build, then specify the argument &quot;debug&quot;
+instead.</p>
+<p>To register the DLL as a COM+ server use</p>
+<pre class="literal-block">
+regsvr32 /c /s ImageMagickObject.dll
+</pre>
+<p>To unregister the DLL use</p>
+<pre class="literal-block">
+regsvr32 /u /s ImageMagickObject.dll
+</pre>
+<p>The MagickCMD sample program operates similarly to the gm.exe program,
+and is a great way to exercise <em>ImageMagickObject</em> to verify that it is
+working.</p>
+<p>Sometime in the future, MagickCMD may assume the place of gm.exe in the
+&quot;utils&quot; distribution in order to decrease the overall package size.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/ImageMagickObject.rst b/www/ImageMagickObject.rst
new file mode 100644
index 0000000..c10ed03
--- /dev/null
+++ b/www/ImageMagickObject.rst
@@ -0,0 +1,130 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=================
+ImageMagickObject
+=================
+
+.. _animate : animate.html
+.. _composite : composite.html
+.. _compare : compare.html
+.. _conjure : conjure.html
+.. _convert : convert.html
+.. _display : display.html
+.. _identify : identify.html
+.. _import : import.html
+.. _mogrify : mogrify.html
+.. _montage : montage.html
+.. _`utility documentation` : utilities.html
+.. _`Windows installation package` : INSTALL-windows.html
+
+Overview
+========
+
+The *ImageMagickObject* is a COM+ compatible component that may be
+invoked from any language capable of using COM objects. The intended use
+is for Windows Scripting Host VBS scripts and Visual Basic, but it can
+also be used from C++, ASP, and other languages like Delphi, Perl and PHP.
+
+The strategy with the *ImageMagickObject* COM+ component is not to the
+same as with PerlMagick interface provided with ImageMagick. PerlMagick
+is a low level API based system that defines a whole new way of scripting
+IM operations. The IM COM+ component simply provides access to the
+`convert`_, composite, `mogrify`_, `identify`_, and `montage`_ tools,
+efficiently executing them as part of your process, rather than as
+external programs. The way you use it is exactly the same. You pass it a
+list of strings including filenames and various options and it does the
+job. In fact, you can take any existing batch scripts that use the
+command line tools and translate them into the equivalent calls to the
+COM+ object in a matter of minutes. Beyond that, there is also a way to
+pass in and retrieve images in memory in the form of standard smart
+arrays (byte arrays). Samples are provided, to show both the simple and
+more elaborate forms of access.
+
+*GraphicsMagick* provides a statically-built ImageMagick object as part of
+its "utils" `Windows installation package`_. When this package is
+installed, *ImageMagickObject* and its sample programs are installed to
+
+::
+
+ c:\Program Files\GraphicsMagick-1.3-Q16\ImageMagickObject
+
+by default (path shown is for the Q:16 build). *ImageMagickObject* is
+registered if the checkbox for "Register ImageMagickObject" is checked at
+install time.
+
+You may execute the sample program from the Windows Command Shell like::
+
+ cscript SimpleTest.vbs
+
+Since the *GraphicsMagick* utility command line parsers are incorporated
+within *ImageMagickObject*, please refer to the command line `utility
+documentation`_ to learn how to use it. The sample VBS scripts show how
+the object should be called and used and have lots of comments.
+
+For C++ programmers - have a look at the MagickCMD.cpp command line
+utility for an example of how to call the object from C++. This is a bit
+complex because the object requires a variable size list of BSTR's to
+emulate the command line argc, argv style calling conventions of the COM
+component which is more complex in C++ then in VBS or VB.
+
+Other goodies...
+================
+
+MagickCMD is a C++ sample, but it can also server as a replacement for
+all the other command line utilities in most applications. Instead of
+using "``convert xxxx yyyy``" you can use "``MagickCMD convert xxxx
+yyyy``" instead. MagickCMD calls the COM object to get the job done. This
+small tight combination replaces the entire usual binary distribution in
+just a few megabytes.
+
+Building ImageMagickObject From Source
+======================================
+
+The source code for *ImageMagickObject* is available from *GraphicsMagick*
+CVS, or as part of the *GraphicsMagick* Windows source package. Once the
+source code has been retrieved and extracted, the source for
+*ImageMagickObject* may be found hidden in the directory
+"``GraphicsMagick\contrib\win32\ATL7ImageMagickObject``", however,
+*GraphicsMagick* itself must be built using the "static-multithread"
+(VisualStaticMT) build configuration. Building *ImageMagickObject*
+requires Microsoft Visual C++ 7.0 as delivered with Microsoft's Visual
+Studio .net package. See the Windows compilation instructions in order to
+get *GraphicsMagick* itself built before building *ImageMagickObject*.
+
+Once the VisualStaticMT project has been built, *ImageMagickObject* may
+be built by following the procedure::
+
+ cd GraphicsMagick\contrib\win32\ATL7ImageMagickObject
+ BuildImageMagickObject release
+
+This procedure assumes that the VisualStaticMT project has been built
+using the "release" setting for an optimized build. If the "debug"
+setting was used for a debug build, then specify the argument "debug"
+instead.
+
+To register the DLL as a COM+ server use
+
+::
+
+ regsvr32 /c /s ImageMagickObject.dll
+
+To unregister the DLL use
+
+::
+
+ regsvr32 /u /s ImageMagickObject.dll
+
+The MagickCMD sample program operates similarly to the gm.exe program,
+and is a great way to exercise *ImageMagickObject* to verify that it is
+working.
+
+Sometime in the future, MagickCMD may assume the place of gm.exe in the
+"utils" distribution in order to decrease the overall package size.
+
+-------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/Magick++/Blob.html b/www/Magick++/Blob.html
new file mode 100644
index 0000000..1446f0b
--- /dev/null
+++ b/www/Magick++/Blob.html
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Blob</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-blob">
+<h1 class="title">Magick::Blob</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>Blob provides the means to contain any opaque data. It is named after
+the term <a class="reference external" href="http://en.wikipedia.org/wiki/Binary_large_object">Binary Large OBject</a> commonly used to
+describe unstructured data (such as encoded images) which are stored
+in a database. While the function of Blob is very simple (store a
+pointer and and size associated with allocated data), the Blob class
+provides some very useful capabilities. In particular, it is fully
+reference counted just like the Image class.</p>
+<p>The Blob class supports value assignment while preserving any
+outstanding earlier versions of the object. Since assignment is via a
+pointer internally, Blob is efficient enough to be stored directly in
+an STL container or any other data structure which requires
+assignment. In particular, by storing a Blob in an <a class="reference external" href="http://www.sgi.com/tech/stl/AssociativeContainer.html">associative
+container</a>
+(such as STL's <a class="reference external" href="http://www.sgi.com/tech/stl/Map.html">map</a>) it is
+possible to create simple indexed in-memory &quot;database&quot; of Blobs.</p>
+<p>Magick++ currently uses Blob to contain encoded images (e.g. JPEG) as
+well as ICC and IPTC profiles. Since Blob is a general-purpose class,
+it may be used for other purposes as well.</p>
+<p>The following is the definition of the Magick::Blob class:</p>
+<pre class="literal-block">
+class Blob
+{
+
+public:
+
+ enum Allocator
+ {
+ MallocAllocator,
+ NewAllocator
+ };
+
+ // Default constructor
+ Blob ( void );
+
+ // Construct object with data, making a copy of the supplied data.
+ Blob ( const void* data_, size_t length_ );
+
+ // Copy constructor (reference counted)
+ Blob ( const Blob&amp; blob_ );
+
+ // Destructor (reference counted)
+ virtual ~Blob ();
+
+ // Assignment operator (reference counted)
+ Blob&amp; operator= ( const Blob&amp; blob_ );
+
+ // Update object contents from Base64-encoded string representation.
+ void base64 ( const std::string base64_ );
+ // Return Base64-encoded string representation.
+ std::string base64 ( void );
+
+ // Update object contents, making a copy of the supplied data.
+ // Any existing data in the object is deallocated.
+ void update ( const void* data_, size_t length_ );
+
+ // Update object contents, using supplied pointer directly (no
+ // copy). Any existing data in the object is deallocated. The user
+ // must ensure that the pointer supplied is not deleted or
+ // otherwise modified after it has been supplied to this method.
+ // Specify allocator_ as &quot;MallocAllocator&quot; if memory is allocated
+ // via the C language malloc() function, or &quot;NewAllocator&quot; if
+ // memory is allocated via C++ 'new'.
+ void updateNoCopy ( void* data_, size_t length_,
+ Allocator allocator_ = NewAllocator );
+
+ // Obtain pointer to data. The user should never try to modify or
+ // free this data since the Blob class manages its own data. The
+ // user must be finished with the data before allowing the Blob to
+ // be destroyed since the pointer is invalid once the Blob is
+ // destroyed.
+ const void* data ( void ) const;
+
+ // Obtain data length
+ size_t length ( void ) const;
+
+};
+</pre>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Blob.rst b/www/Magick++/Blob.rst
new file mode 100644
index 0000000..a55635a
--- /dev/null
+++ b/www/Magick++/Blob.rst
@@ -0,0 +1,93 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+============
+Magick::Blob
+============
+
+Blob provides the means to contain any opaque data. It is named after
+the term `Binary Large OBject
+<http://en.wikipedia.org/wiki/Binary_large_object>`_ commonly used to
+describe unstructured data (such as encoded images) which are stored
+in a database. While the function of Blob is very simple (store a
+pointer and and size associated with allocated data), the Blob class
+provides some very useful capabilities. In particular, it is fully
+reference counted just like the Image class.
+
+The Blob class supports value assignment while preserving any
+outstanding earlier versions of the object. Since assignment is via a
+pointer internally, Blob is efficient enough to be stored directly in
+an STL container or any other data structure which requires
+assignment. In particular, by storing a Blob in an `associative
+container <http://www.sgi.com/tech/stl/AssociativeContainer.html>`_
+(such as STL's `map <http://www.sgi.com/tech/stl/Map.html>`_) it is
+possible to create simple indexed in-memory "database" of Blobs.
+
+Magick++ currently uses Blob to contain encoded images (e.g. JPEG) as
+well as ICC and IPTC profiles. Since Blob is a general-purpose class,
+it may be used for other purposes as well.
+
+The following is the definition of the Magick::Blob class::
+
+ class Blob
+ {
+
+ public:
+
+ enum Allocator
+ {
+ MallocAllocator,
+ NewAllocator
+ };
+
+ // Default constructor
+ Blob ( void );
+
+ // Construct object with data, making a copy of the supplied data.
+ Blob ( const void* data_, size_t length_ );
+
+ // Copy constructor (reference counted)
+ Blob ( const Blob& blob_ );
+
+ // Destructor (reference counted)
+ virtual ~Blob ();
+
+ // Assignment operator (reference counted)
+ Blob& operator= ( const Blob& blob_ );
+
+ // Update object contents from Base64-encoded string representation.
+ void base64 ( const std::string base64_ );
+ // Return Base64-encoded string representation.
+ std::string base64 ( void );
+
+ // Update object contents, making a copy of the supplied data.
+ // Any existing data in the object is deallocated.
+ void update ( const void* data_, size_t length_ );
+
+ // Update object contents, using supplied pointer directly (no
+ // copy). Any existing data in the object is deallocated. The user
+ // must ensure that the pointer supplied is not deleted or
+ // otherwise modified after it has been supplied to this method.
+ // Specify allocator_ as "MallocAllocator" if memory is allocated
+ // via the C language malloc() function, or "NewAllocator" if
+ // memory is allocated via C++ 'new'.
+ void updateNoCopy ( void* data_, size_t length_,
+ Allocator allocator_ = NewAllocator );
+
+ // Obtain pointer to data. The user should never try to modify or
+ // free this data since the Blob class manages its own data. The
+ // user must be finished with the data before allowing the Blob to
+ // be destroyed since the pointer is invalid once the Blob is
+ // destroyed.
+ const void* data ( void ) const;
+
+ // Obtain data length
+ size_t length ( void ) const;
+
+ };
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/COPYING b/www/Magick++/COPYING
new file mode 100644
index 0000000..c0d2da5
--- /dev/null
+++ b/www/Magick++/COPYING
@@ -0,0 +1,22 @@
+
+Copyright 1999 - 2015 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files ("Magick++"), to deal in Magick++ without restriction,
+including without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell copies of
+Magick++, and to permit persons to whom the Magick++ is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of Magick++.
+
+The software is provided "as is", without warranty of any kind,
+express or implied, including but not limited to the warranties of
+merchantability, fitness for a particular purpose and
+noninfringement. In no event shall Bob Friesenhahn be liable for
+any claim, damages or other liability, whether in an action of
+contract, tort or otherwise, arising from, out of or in connection
+with Magick++ or the use or other dealings in Magick++.
+
diff --git a/www/Magick++/Cache.fig b/www/Magick++/Cache.fig
new file mode 100644
index 0000000..5b880a7
--- /dev/null
+++ b/www/Magick++/Cache.fig
@@ -0,0 +1,35 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+0
+1200 2
+1 3 0 3 4 4 0 0 20 0.000 1 0.0000 2715 3030 31 31 2715 3030 2745 3037
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1200 3300 1200 2100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2925 1875 1500 1875
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3825 1875 4800 1875
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1200 3600 1200 4800
+2 2 0 1 0 6 9 0 30 0.000 0 0 -1 0 0 5
+ 2325 2700 4125 2700 4125 3825 2325 3825 2325 2700
+2 2 0 1 0 2 10 0 30 0.000 0 0 7 0 0 5
+ 1500 2100 4800 2100 4800 4800 1500 4800 1500 2100
+2 2 0 1 7 7 11 0 20 0.000 0 0 -1 0 0 5
+ 900 1500 5100 1500 5100 5100 900 5100 900 1500
+4 1 0 0 0 16 12 0.0000 4 180 810 3375 1950 columns()\001
+4 2 0 0 0 16 12 0.0000 4 180 510 1500 3525 rows()\001
+4 0 0 0 0 16 12 0.0000 4 165 255 1575 2325 0,0\001
+4 1 0 0 0 16 12 0.0000 4 180 795 3375 2625 columns_\001
+4 1 0 0 0 16 12 0.0000 4 135 225 2325 2625 x,y\001
+4 2 0 0 0 16 12 0.0000 4 135 495 2250 3300 rows_\001
+4 0 0 0 0 16 12 0.0000 4 135 405 2730 3232 Pixel\001
diff --git a/www/Magick++/Cache.png b/www/Magick++/Cache.png
new file mode 100644
index 0000000..91d0efb
--- /dev/null
+++ b/www/Magick++/Cache.png
Binary files differ
diff --git a/www/Magick++/ChangeLog.html b/www/Magick++/ChangeLog.html
new file mode 100644
index 0000000..2d4b623
--- /dev/null
+++ b/www/Magick++/ChangeLog.html
@@ -0,0 +1,2336 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title></title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document">
+
+
+<p>2017-03-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (orientation): Update orientation in EXIF profile,
+if it exists.
+(attribute): Added Image attribute method which accepts a 'char *'
+argument, and will remove the attribute if the value argument is
+NULL.</li>
+</ul>
+</blockquote>
+<p>2014-11-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Geometry.h (Magick::Geometry): Add and document
+limitPixels() and fillArea() methods to support '&#64;' and '^'
+geometry qualifiers. Fill area contributed by Long Ho and
+limitPixels() by Bob Friesenhahn.</li>
+<li>../www/Magick++/Image.rst: Document extent and resize methods.</li>
+<li>lib/STL.cpp (extentImage): New function object to invoke image
+extent method. Original implementation contributed by Long Ho.
+Subsequently modified by Bob Friesenhahn.
+(resizeImage): New function object to invoke image resize
+method. Contributed by Long Ho.</li>
+<li>lib/Image.cpp (extent): New method to place image on sized
+canvas of constant color using gravity. Contributed by Long Ho.
+(resize): New method to resize image specifying geometry, filter,
+and blur. Original implementation contributed by Long Ho.
+Subsequently modified by Bob Friesenhahn.</li>
+</ul>
+</blockquote>
+<p>2014-01-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (thumbnail): New method for fast image resizing,
+particularly to make thumbnails.</li>
+</ul>
+</blockquote>
+<p>2013-12-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableDashArray): DrawableDashArray now uses
+C++ memory allocation rather than from GraphicsMagick library.
+Also, implement direct copy constructor and assignment operator
+rather than using dasyarray() method.</li>
+</ul>
+</blockquote>
+<p>2012-11-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>COPYING: Change Magick++ usage license to be exactly the MIT
+license without the additional sentence about retention of
+copyright (which was already legally implicit).</li>
+</ul>
+</blockquote>
+<p>2012-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (defineValue): Use AddDefinition() rather than
+AddDefinitions().</li>
+</ul>
+</blockquote>
+<p>2012-03-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h (Magick): Added support for RandomNoise.</li>
+</ul>
+</blockquote>
+<p>2012-03-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/STL.cpp (stripImage): New unary function to to remove all
+profiles and text attributes from the image.</li>
+<li>lib/Image.cpp (strip): New method to remove all profiles and
+text attributes from the image.</li>
+</ul>
+</blockquote>
+<p>2011-12-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: Explicitly DLL import/export Magick++
+symbols when building under MinGW GCC.</li>
+</ul>
+</blockquote>
+<p>2010-12-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h (Magick): Add LZMACompression</li>
+</ul>
+</blockquote>
+<p>2010-12-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (InitializeMagick): Don't use atexit(). C++
+destructures are sufficient.</li>
+</ul>
+</blockquote>
+<p>2010-09-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (backgroundColor, borderColor, matteColor):
+Opacity part of user-specified color needs to be preserved.
+Problem was reported by Alexander Zheltov.</li>
+</ul>
+</blockquote>
+<p>2010-04-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/CoderInfo.h: Add default constructor, copy
+constructor, and assignment operator.</li>
+</ul>
+</blockquote>
+<p>2010-01-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (Magick): Fix potential memory leak.</li>
+</ul>
+</blockquote>
+<p>2010-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>demo/shapes.cpp (main): Floodfill shape more agressively and
+scale fuzz factor so that it provides the same results across
+quantum depths.</li>
+</ul>
+</blockquote>
+<p>2009-10-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/STL.cpp, lib/Magick++/STL.h (shadeImage): ShadeImage was the
+result of a botched cut-and-paste. Corrected now. Thanks to
+Jukka Manner for making me aware of this.</li>
+</ul>
+</blockquote>
+<p>2009-09-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (cdl): New method to apply the ASC CDL.
+(colorMatrix): New method to apply a color matrix to the image
+channels.
+(haldClut): New method to apply a color lookup table (Hald CLUT)
+to the image.</li>
+</ul>
+</blockquote>
+<p>2009-07-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (attribute): Invoke modifyImage() to assure
+exclusive access to image when updating attributes.</li>
+</ul>
+</blockquote>
+<p>2009-03-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (quantumOperator): New variant of method which
+takes a 'double' argument, as it originally should. Previous
+method taking a Quantum argument is still supported but marked
+deprecated.</li>
+</ul>
+</blockquote>
+<p>2009-01-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: If the user defines STATIC_MAGICK in his
+project, then the Windows DLL decorations are ignored. Without
+this, Windows DLL-based code can't use a static GraphicsMagick.
+This is recommended by SourceForge bug 2537627.</li>
+<li>lib/Magick++/Drawable.h: Apparently the only STL container which
+may be DLL-exported is &lt;vector&gt; but we are using &lt;list&gt; so disable
+DLL-export of list-based template objects.</li>
+</ul>
+</blockquote>
+<p>2008-10-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Color.cpp: Added an _isValid boolean to represent an invalid
+color. Transparent black is no longer special and can be used in
+drawing.</li>
+<li>lib/Pixels.cpp: Update to use new cache view interfaces provided
+by GraphicsMagick 1.3.</li>
+</ul>
+</blockquote>
+<p>2008-09-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (addNoiseChannel): New method to add noise to a
+specified channel.
+(blurChannel): New method to blur a specified channel.
+(gaussianBlurChannel): New method to gaussian blur a specified
+channel.
+(motionBlur): New method to motion blur the image.
+(randomThresholdChannel): New method to apply random thresholding
+or ordered dithering to the image.
+(randomThresholdChannel): New method to apply random thresholding
+or ordered dithering to the specified image channels.
+(sharpenChannel): New method to sharpen a specified image channel.
+(unsharpmaskChannel): New method to unsharpmask a specified image
+channel.</li>
+</ul>
+</blockquote>
+<p>2008-06-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (quantize): Error measurement support was being
+performed incorrectly. SyncImage() is not needed here.</li>
+</ul>
+</blockquote>
+<p>2008-05-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>demo/demo.cpp (main): Fix segmentation parameters so they are
+more suitable for our image.</li>
+</ul>
+</blockquote>
+<p>2008-04-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (depth): Remove 8/16/32 restriction on depth
+value.</li>
+</ul>
+</blockquote>
+<p>2008-03-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Geometry.cpp, lib/Image.cpp: Include &lt;strings.h&gt; since it is
+needed in order to use strcpy().</li>
+</ul>
+</blockquote>
+<p>2007-12-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/{Drawable.cpp, Geometry.cpp, BlobRef.cpp, Blob.cpp,
+Montage.cpp, Options.cpp, Image.cpp}: Eliminate use of deprecated
+GraphicsMagick functions.</li>
+<li>lib/Magick++/{STL.h, Include.h}: Eliminate use of deprecated
+GraphicsMagick functions.</li>
+</ul>
+</blockquote>
+<p>2007-07-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp: Include &lt;cstdlib&gt;</li>
+</ul>
+</blockquote>
+<p>2006-10-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (pixelColor): Don't enforce color &quot;validity&quot; when
+setting the pixel color.</li>
+</ul>
+</blockquote>
+<p>2005-10-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (orientation): New accessor method to support
+image orientation.</li>
+</ul>
+</blockquote>
+<p>2005-04-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/STL.cpp (levelImage): New function object for leveling the
+image channels.
+(levelChannelImage): New function object for leveling a specific
+image channel.</li>
+<li>lib/Image.cpp (level): New method for leveling the image
+channels.
+(levelChannel): New method for leveling a specific image channel.</li>
+</ul>
+</blockquote>
+<p>2005-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h (Magick): Import CineonLogRGBColorspace
+into Magick namespace.</li>
+</ul>
+</blockquote>
+<p>2005-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: Import Rec601LumaColorspace (was called
+GRAYColorspace) and Rec709LumaColorspace into Magick
+namespace. Use of GRAYColorspace is mapped via a macro into
+Rec601LumaColorspace in order to avoid a user-visible API change.</li>
+</ul>
+</blockquote>
+<p>2004-08-17 Volker Lukas &lt;<a class="reference external" href="mailto:vlukas&#37;&#52;&#48;gmx&#46;de">vlukas<span>&#64;</span>gmx<span>&#46;</span>de</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp: Fixes to ensure that drawable objects remain
+coherent even if an exception is thrown within the assignment
+operator.</li>
+</ul>
+</blockquote>
+<p>2004-07-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt; &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>demo/Makefile.am (AUTOMAKE_OPTIONS): Added nostdinc in order to
+avoid accidentally using magick/list.h when including &lt;list&gt;.</li>
+<li>tests/Makefile.am (AUTOMAKE_OPTIONS): Added nostdinc in order to
+avoid accidentally using magick/list.h when including &lt;list&gt;.</li>
+<li>tests/readWriteBlob.cpp: If MISSING_STD_IOS_BINARY is defined,
+then ios::binary is not used. Use simple ifstream rather than
+std::ifstream since we are already using the std namespace.</li>
+</ul>
+</blockquote>
+<p>2004-06-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: Disable unavoidable warnings under
+Visual C++ when instantiating STL templates within DLL
+code. Consensus from postings on the net is that as long as the
+same C++ compiler is used throughout, these warnings are of no
+concern.</li>
+</ul>
+</blockquote>
+<p>2004-05-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (coderInfoList): Make error reporting a bit
+more lenient so that if an error occurs while loading a module it
+is not reported as an exception unless no coders were found at
+all.</li>
+</ul>
+</blockquote>
+<p>2004-05-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (clipMask): Use GetImageClipMask.</li>
+</ul>
+</blockquote>
+<p>2004-04-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/CoderInfo.cpp (CoderInfo): Sense of isReadable() and
+isWritable() was inverted.</li>
+</ul>
+</blockquote>
+<p>2004-04-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: &lt;inttypes.h&gt; is not used. Inclusion
+removed.</li>
+</ul>
+</blockquote>
+<p>2004-03-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Thread.cpp (lock): Have not been successful with using
+MsgWaitForMultipleObjects() reliably, so back out usage of it for
+now.</li>
+</ul>
+</blockquote>
+<p>2004-03-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Thread.cpp (lock): For MsgWaitForMultipleObjects, monitor
+state change only. Otherwise lock may deadlock.</li>
+</ul>
+</blockquote>
+<p>2004-03-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (statistics): New method to obtain image
+statistics (minimum, maximum, mean, variance, and standard
+deviation).</li>
+</ul>
+</blockquote>
+<p>2004-03-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (quantumOperator): New image method to apply an
+arithmetic or bitwise operator to the pixel quantums in an image.
+Still needs documentation.
+(quantumOperator): New image method to apply an arithmetic or
+bitwise operator to the pixel quantums in an image region.</li>
+</ul>
+</blockquote>
+<p>2004-03-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Makefile.am (../www/Magick++/ChangeLog.html): Fix execution of
+txt2html.</li>
+<li>lib/STL.cpp (composeImage): Added a function object to set/get
+the Image composition option.</li>
+<li>lib/Image.cpp (compose): Added a method to set/get the Image
+composition option.</li>
+</ul>
+</blockquote>
+<p>2004-03-06 Vladimir Lukianov &lt;<a class="reference external" href="mailto:lvm&#37;&#52;&#48;integrum&#46;ru">lvm<span>&#64;</span>integrum<span>&#46;</span>ru</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Thread.cpp (lock): Use MsgWaitForMultipleObjects() rather
+than WaitForSingleObject() in order to avoid possible deadlock
+when application code directly or indirectly creates windows.</li>
+</ul>
+</blockquote>
+<p>2004-02-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (interlaceType): Retrieve interlace setting from
+Image rather than ImageInfo.</li>
+</ul>
+</blockquote>
+<p>2004-02-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (Image): Delete the allocated image reference
+object if a Magick::Error is thrown by the Image constructor.
+Otherwise the image reference object becomes a memory leak.</li>
+</ul>
+</blockquote>
+<p>2004-01-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (WriteImages): Pass Blob::MallocAllocator to
+updateNoCopy() in order to ensure that correct deallocator is
+used.</li>
+<li>tests/readWriteBlob.cpp (main): Needed to delete character array
+using array [] reference.</li>
+</ul>
+</blockquote>
+<p>2004-01-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>demo/analyze.cpp (main): Fix a GNU C++ library portability
+problem noticed under MinGW. The 'left' iostream manipulator seems
+to be missing.</li>
+</ul>
+</blockquote>
+<p>2004-01-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am: coderInfo test is expected to fail for moby
+builds when the package is not yet installed since a .la file
+exists in the coders directory, but there is no associated .so
+file. Therefore failures of the coderInfo test are now ignored.</li>
+</ul>
+</blockquote>
+<p>2003-12-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (defineValue): New method to support setting
+format-specific defines.
+(defineSet): New method to support setting or testing for
+format-specific flags.</li>
+</ul>
+</blockquote>
+<p>2003-12-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (iccColorProfile): Implementation now uses the
+profile method with profile name &quot;ICM&quot;. Note that this now
+invokes the color profile if the image already has one.
+(iccColorProfile): Reimplement using new GetImageProfile function.
+(iptcProfile): Reimplement using the new GetImageProfile and
+SetImageProfile functions.
+(profile): Reimplement using new GetImageProfile function.</li>
+</ul>
+</blockquote>
+<p>2003-12-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Makefile.am (pkglibdir): Improve header file
+install location logic.</li>
+</ul>
+</blockquote>
+<p>2003-12-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>demo/analyze.cpp (main): New program to demonstrate using the
+'analyze' process module.</li>
+<li>demo/Makefile.am: Add rules to build analyze program.</li>
+<li>lib/Image.cpp (process): New method to execute process modules.</li>
+<li>lib/Image.cpp (attribute): New method to get and set named image
+attributes.</li>
+</ul>
+</blockquote>
+<p>2003-10-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Color.cpp: Ensure that all non-default constructors set
+opacity to opaque.</li>
+</ul>
+</blockquote>
+<p>2003-09-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (colorHistogram): If map key is not const,
+then implicit type conversion occurs. Sun's C++ compiler doesn't
+seem to handle that. The map key is now defined as const in the
+insert arguments.</li>
+</ul>
+</blockquote>
+<p>2003-09-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/Makefile.am: Add build support for colorHistogram.cpp.</li>
+<li>tests/colorHistogram.cpp: New test program to test retrieving
+color histograms from the image using colorHistogram().</li>
+<li>lib/Magick++/STL.h (colorHistogram): Added new template function
+to retrieve a color histogram into a user-provided container.
+Verified to work when using STL &lt;vector&gt; and &lt;map&gt; as the target
+container types. When &lt;map&gt; is used, a user-specified color may
+be used to perform lookups in the map to obtain the usage count
+for that color.</li>
+<li>lib/Color.cpp (operator &gt;=): Insufficient resolution was being
+provided in order to reliably sort color objects in STL
+containers. The updated algorithm should be fail-safe.</li>
+</ul>
+</blockquote>
+<p>2003-08-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (channelDepth): New method to set or get the
+modulus depth for a specified channel.</li>
+</ul>
+</blockquote>
+<p>2003-08-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h (Magick): Added support for
+CopyCyanCompositeOp, CopyMagentaCompositeOp,
+CopyYellowCompositeOp, and CopyBlackCompositeOp, composition
+operators.</li>
+</ul>
+</blockquote>
+<p>2003-08-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (depth): Method now only updates the
+Image/ImageInfo depth member and retrieves the value of the Image
+depth member.
+(modulusDepth): New method to inspect the pixels for actual
+modulus depth, or update/reduce the pixels to a specified modulus
+depth. The depth method was performing this function so any code
+which depended on the depth method to compute or set the modulus
+depth should be updated to use modulusDepth() instead.</li>
+</ul>
+</blockquote>
+<p>2003-08-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (matte): If a new matte channel is created,
+initialize it to opaque. Likewise, if the matte channel is
+eliminated, initialize the unused channel to opaque.</li>
+</ul>
+</blockquote>
+<p>2003-07-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>demo/demo.cpp (main): Don't crop logo image.</li>
+<li>*.h, *.cpp: Include &quot;Magick++/Include.h&quot; before including any
+compiler or system header in order to ensure that LFS defines are
+properly applied. Inspired by patch from Albert Chin-A-Young.</li>
+</ul>
+</blockquote>
+<p>2003-06-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: Needed to import ThrowLoggedException.</li>
+<li>lib/Exception.cpp (throwException): Add originating source
+module, source line, and function name (if available) to exception
+report. This is useful in order to determine the exact conditions
+that lead to the exception being thrown.</li>
+<li>lib/Magick++/Exception.h: Added ErrorCoder, WarningCoder,
+ErrorConfigure, WarningConfigure, ErrorDraw, WarningDraw,
+ErrorImage, WarningImage, ErrorMonitor, WarningMonitor,
+ErrorRegistry, WarningRegistry, ErrorStream, WarningStream,
+ErrorType, and WarningType, exception classes to support the full
+set of exceptions that GraphicsMagick can throw.</li>
+</ul>
+</blockquote>
+<p>2003-06-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/CoderInfo.cpp (CoderInfo): Applied compilation fix from Mike
+Chiarappa to compile using Borland C++.</li>
+</ul>
+</blockquote>
+<p>2003-06-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Geometry.cpp (string): Throw an exception if a string is
+requested from an invalid geometry object.</li>
+</ul>
+</blockquote>
+<p>2003-06-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Geometry.cpp (operator =): If GetGeometry returns NoValue,
+then assign an invalid geometry object to cause an exception if
+the geometry is then used.</li>
+</ul>
+</blockquote>
+<p>2003-06-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Exception.h (ErrorModule): Added class to handle
+module errors.</li>
+<li>lib/Magick++/Exception.h (WarningModule) Added class to handle
+module warnings.</li>
+</ul>
+</blockquote>
+<p>2003-05-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (coderInfoList): Use GetMagickInfoArray to
+access coder list.</li>
+</ul>
+</blockquote>
+<p>2003-05-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (affineTransformImage): Add function object
+contributed by Vladimir Lukianov to apply an affine transform to
+the image.</li>
+<li>lib/Image.cpp (affineTransform): Added method contributed by
+Vladimir Lukianov to apply an affine transform to the image.</li>
+</ul>
+</blockquote>
+<p>2003-05-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: Decided to back out change which used
+the _VISUALC_ define to trigger inclusion of &lt;sys/types.h&gt;.</li>
+</ul>
+</blockquote>
+<p>2003-05-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: If _VISUALC_ is defined, include
+&lt;sys/types.h&gt;. This ensures that this necessary header is included
+even if HAVE_SYS_TYPES_H is not defined in magick_config.h.</li>
+</ul>
+</blockquote>
+<p>2003-05-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (InitializeMagick): InitializeMagick is now a C++
+function rather than a namespace inclusion. An atexit() handler
+is registered to invoke DestroyMagick when the program
+exits. Relying on static deconstruction to invoke DestroyMagick
+proved to be unreliable due to translation unit destruction
+uncertainty.</li>
+</ul>
+</blockquote>
+<p>2003-04-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (Image::Image (MagickLib::Image* image_)):
+Incorporated recommended fix from Jukka Manner to avoid
+a scenario which leaks an Options object.</li>
+<li>tests/coalesceImages.cpp: Updated to use modified
+coalesceImages() interface.</li>
+<li>lib/Magick++/STL.h (coalesceImages): Replaced implementation
+with one from Felix Heimbrecht. The template signature has changed
+to return a new image sequence. This template API silently ceased
+to funtion due to an ImageMagick CoalesceImages API change.</li>
+</ul>
+</blockquote>
+<p>2003-03-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/readWriteBlob.cpp (main): Added check for stream read
+failure when reading blob data.
+(class myBlob): Use get rather than read.</li>
+</ul>
+</blockquote>
+<p>2003-03-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/attributes.cpp : Change in the way that Magick++ retrieves
+density caused tests to fail. Density now defaults to 72x72
+(GraphicsMagick default) rather than invalid.</li>
+</ul>
+</blockquote>
+<p>2003-03-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>demo/Makefile.am (CLEANFILES): Fix clean target to
+remove *_out.mvg output files as well.</li>
+<li>demo/zoom.cpp: Added a command-line parser for dash arguments as
+well as an image &quot;resample&quot; capability.</li>
+<li>lib/Image.cpp (density): Obtain density from Image rather than
+ImageInfo if the Image is valid.</li>
+</ul>
+</blockquote>
+<p>2003-03-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Makefile.am : Added rules to install GraphicsMagick++.pc.</li>
+<li>lib/GraphicsMagick++.pc.in : Added pkgconfig file for
+-lGraphicsMagick++.</li>
+</ul>
+</blockquote>
+<p>2003-02-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (colorSpace): Pass image-&gt;colorspace to
+TransformRGBColorspace.</li>
+</ul>
+</blockquote>
+<p>2003-01-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (writeImages): Should have been invoking
+WriteImages rather than WriteImage!</li>
+</ul>
+</blockquote>
+<p>2003-01-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h: Add HSL and HWB colorspace
+transformation support.</li>
+</ul>
+</blockquote>
+<p>2003-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (colorSpace): Support colorspace transforms other
+than to and from RGB by translating to RGB as an intermediate
+step.</li>
+</ul>
+</blockquote>
+<p>2002-11-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp: Added DrawablePushClipPath,
+DrawablePopClipPath, and DrawableClipPath. Implementation
+contributed by Vladimir &lt;<a class="reference external" href="mailto:lvm&#37;&#52;&#48;integrum&#46;ru">lvm<span>&#64;</span>integrum<span>&#46;</span>ru</a>&gt;.</li>
+</ul>
+</blockquote>
+<p>2002-11-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (colorMapSize): New method to set, or return the
+colormap size.</li>
+</ul>
+</blockquote>
+<p>2002-11-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (adaptiveThreshold): New method.</li>
+</ul>
+</blockquote>
+<p>2002-10-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (coderInfoList): Intentionally ignore missing
+delegate exceptions.</li>
+</ul>
+</blockquote>
+<p>2002-09-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Options.cpp (textEncoding): Had forgotten to implement
+textEncoding!</li>
+</ul>
+</blockquote>
+<p>2002-09-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Color.cpp (Color): Use of 'new' and 'delete' in inlines was
+causing memory allocation/deallocation problems for users of the
+DLL build. Problem was identified by Marc Iwan.</li>
+</ul>
+</blockquote>
+<p>2002-09-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (compare): New method to compare current image
+with a reference image.</li>
+</ul>
+</blockquote>
+<p>2002-08-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (textEncoding): New method to allow setting the
+default text encoding (e.g. &quot;UTF-8&quot;).</li>
+<li>lib/Drawable.cpp (DrawableText): Added an alternate constructor
+to allow specifying the text encoding (e.g. &quot;UTF-8&quot;).</li>
+</ul>
+</blockquote>
+<p>2002-08-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Overall: Now compiles as a DLL using Visual C++.</li>
+</ul>
+</blockquote>
+<p>2002-07-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (profile): Added method to store, delete, or
+retrieve named application profiles.</li>
+</ul>
+</blockquote>
+<p>2002-07-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (type): Set the ImageInfo type attribute when
+setting the image type. If the type attribute is set to something
+other than UndefinedType (implying that the user has set a desired
+output image type), then return that as the image type, otherwise
+use GetImageType() to evaluate the image type.</li>
+</ul>
+</blockquote>
+<p>2002-05-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableTextUnderColor): New class to set the
+text undercolor. When text undercolor is set, a rectangle of the
+specified color is rendered under text annotations.</li>
+</ul>
+</blockquote>
+<p>2002-05-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Magick++ library no longer depends on iostreams at all.</li>
+</ul>
+</blockquote>
+<p>2002-04-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (throwImageException): ExceptionInfo was not being
+properly initialized. This could cause some errors to cause an
+abort in error.c rather than throwing an exception.</li>
+</ul>
+</blockquote>
+<p>2002-04-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (draw): Use draw.h drawing APIs to draw on image.
+This means that MVG output no longer comes from code in
+Drawable.cpp.</li>
+</ul>
+</blockquote>
+<p>2002-04-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/STL.cpp: Moved function object implementations from STL.h to
+STL.cpp.</li>
+</ul>
+</blockquote>
+<p>2002-04-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (getConstPixels): Changed offset parameter type
+from 'unsigned int' to 'int'.
+(getPixels): Changed offset parameter type from 'unsigned int' to
+'int'.
+(setPixels): Changed offset parameter type from 'unsigned int' to
+'int'.
+(cacheThreshold): Changed argument type from 'const long' to
+'const int'.
+(matteFloodfill): Changed offset parameter type from 'const long'
+to 'const int'.</li>
+<li>lib/Pixels.cpp (getConst): New method to return read-only
+pixels.
+(get): Offset parameter types changed from 'unsigned int' to
+'int'.</li>
+</ul>
+</blockquote>
+<p>2002-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Drawable.h (DrawableDashOffset): Change dashoffset
+type to 'double' rather than 'unsigned int' in order to match
+ImageMagick.</li>
+<li>lib/Drawable.cpp (DrawableDashArray): Change dasharray type to
+'double' rather than 'unsigned int' in order to match
+ImageMagick. Previous 'unsigned int' methods remain for
+compatability reasons.</li>
+</ul>
+</blockquote>
+<p>2002-04-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableCompositeImage): Always output
+composite images as inlined Base64.</li>
+</ul>
+</blockquote>
+<p>2002-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableCompositeImage): If magick attribute
+string is specified, then composite image is supplied to
+ImageMagick as inlined Base64 rather than by MPRI reference.</li>
+<li>lib/Blob.cpp (base64): Added methods to update Blob with data
+from Base64-encoded string, or to return a Base64-encoded string
+from Blob. Still needs documentation.</li>
+</ul>
+</blockquote>
+<p>2002-04-09 Dom Lachowicz &lt;<a class="reference external" href="mailto:cinamod&#37;&#52;&#48;hotmail&#46;com">cinamod<span>&#64;</span>hotmail<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (Image::ping): Added PingBlob function</li>
+</ul>
+</blockquote>
+<p>2002-04-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableDashArray::operator=): Added missing
+assignment operator (fixes a bug).
+(DrawableDashArray::DrawableDashArray): Added missing copy
+constructor (fixes a bug).</li>
+<li>lib/Image.cpp (oilPaint): Changed argument type from unsigned
+int to double.
+(chromaBluePrimary): Changed argument type from float to double.
+(chromaGreenPrimary): Changed argument type from float to double.
+(chromaRedPrimary): Changed argument type from float to double.
+(chromaWhitePoint): Changed argument type from float to double.
+(getConstPixels): Changed argument type of x_ &amp; _y from 'int' to
+'unsigned int'.
+(getPixels): Changed argument type of x_ &amp; _y from 'int' to
+'unsigned int'.</li>
+</ul>
+</blockquote>
+<p>2002-04-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (debug): Added method to set ImageMagick debug
+flag so that it prints debugging information while it runs.</li>
+</ul>
+</blockquote>
+<p>2002-04-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp: Fixed a bunch of bugs related to
+DrawableCompositeImage, DrawableFont, and inconsistencies
+discovered by Gimpel lint.</li>
+</ul>
+</blockquote>
+<p>2002-04-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (draw): Properly delimit individual drawing
+commands so that MVG output is correct.</li>
+</ul>
+</blockquote>
+<p>2002-03-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableViewbox): MVG syntax wasn't correct.</li>
+<li>lib/Image.cpp (draw): Fix algorithm used to append newlines to
+MVG commands so that draw() may be invoked multiple times while
+still producing valid MVG.</li>
+</ul>
+</blockquote>
+<p>2002-03-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableViewbox): New class to allow setting
+the MVG output size.</li>
+</ul>
+</blockquote>
+<p>2002-03-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (print): Changed &quot;mpr:&quot; to &quot;mpri:&quot; in order to
+finally get DrawableCompositeImage to work as intended.</li>
+<li>lib/Image.cpp (registerId): Bugfix. Register using
+sizeof(MagickLib::Image) rather than sizeof(Image).</li>
+</ul>
+</blockquote>
+<p>2002-03-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableCompositeImage): Had failed to
+initialize width and height in object to image width and height.</li>
+</ul>
+</blockquote>
+<p>2002-02-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (endianImage): New class to specify the
+endian option for formats which support this notion (e.g. TIFF).</li>
+<li>lib/Image.cpp (endian): New method to specify the endian option
+for formats which support this notion (e.g. TIFF).</li>
+</ul>
+</blockquote>
+<p>2002-02-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableFont): Support specifying a font via
+font-family, font-style, font-weight, and font-stretch. Wildcard
+matches are supported.</li>
+</ul>
+</blockquote>
+<p>2002-02-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (charcoal): Replace Magick++'s charcoal effect
+with the output of ImageMagick's CharcoalImage function in order
+to ensure consistency.</li>
+<li>lib/Magick++/CoderInfo.h (MatchType): Scope the MatchType
+enumeration to the CoderInfo class so these enumeration names can
+be re-used elsewhere without conflict. This results in a minor
+API change to the coderInfoList() templated function since
+enumerations must be specified like &quot;CoderInfo::TrueMatch&quot; rather
+than just &quot;TrueMatch&quot;. Hopefully not a problem since this
+function and class were not documented outside of the headers
+until this release.</li>
+</ul>
+</blockquote>
+<p>2002-02-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (coderInfoList): Finally wrote some
+documentation.</li>
+</ul>
+</blockquote>
+<p>2002-01-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Options.cpp : Use DestroyImageList() rather than
+DestroyImage().</li>
+<li>lib/Geometry.cpp (operator =): Use GetPageGeometry() rather than
+PostscriptGeometry() to parse geometry specifications containing a
+page size.</li>
+</ul>
+</blockquote>
+<p>2002-01-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>Remove bogus cast of blob data in readImages().</li>
+</ul>
+</blockquote>
+<p>2002-01-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (throwImageException): Throwing exceptions was
+leaking memory.</li>
+<li>lib/Exception.cpp (throwException): Throwing exceptions was
+leaking memory.</li>
+<li>lib/Image.cpp (replaceImage): Updated to properly handle
+registration ids.
+(modifyImage): Updated to properly handle registration ids.</li>
+</ul>
+</blockquote>
+<p>2002-01-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (Magick::DrawableGravity::print):
+Bugfix. Remove &quot;Gravity&quot; from the end of each gravity
+specification string. Reported as PR#1084 by stefan&#64;dotify.com.</li>
+</ul>
+</blockquote>
+<p>2002-01-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp, Magick++/Include.h: Use DestroyImageList() rather
+than DestroyImages().</li>
+</ul>
+</blockquote>
+<p>2002-01-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Options.h (antiAlias): Bugfix, set
+drawInfo-&gt;text_antialias to control text antialiasing.</li>
+</ul>
+</blockquote>
+<p>2002-01-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h : Imported new composition operators to
+namespace: NoCompositeOp, DarkenCompositeOp, LightenCompositeOp,
+HueCompositeOp, SaturateCompositeOp, ValueCompositeOp,
+ColorizeCompositeOp, LuminizeCompositeOp, ScreenCompositeOp,
+OverlayCompositeOp.</li>
+</ul>
+</blockquote>
+<p>2001-12-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (strokePattern): New method to specify image to
+use as pattern while drawing stroked-outlines of drawn objects.
+(fillPattern): New method to specify image to use as pattern while
+filling drawn objects.
+(penTexture): Method is officially deprecated. Don't use anymore.
+(penColor): Method is officially deprecated. Don't use anymore.</li>
+<li>lib/Drawable.cpp (DrawablePushPattern): Support pushing
+(starting) pattern definition.
+(DrawablePopPattern): Support popping (terminating) pattern
+definition.</li>
+</ul>
+</blockquote>
+<p>2001-12-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableCompositeImage): Read image
+immediately if provided by filename, register with peristent
+registry, and pass as perisistant image type.
+(DrawableCompositeImage): Support specifying Image in memory.
+Passed as perisistant image type.</li>
+</ul>
+</blockquote>
+<p>2001-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Color.cpp (operator std::string): Color string buffer was
+one character too short!</li>
+</ul>
+</blockquote>
+<p>2001-12-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;sun1107&#46;ssd&#46;usa&#46;alcatel&#46;com">bfriesen<span>&#64;</span>sun1107<span>&#46;</span>ssd<span>&#46;</span>usa<span>&#46;</span>alcatel<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/TypeMetric.cpp (characterWidth): Eliminate method.
+(characterHeight): Eliminate method.
+(all remaining methods): Change return type to 'double'. Fix
+documentation in source files to reflect that units are in pixels
+rather than points.
+(descent): Renamed method from 'decent' to 'descent'.</li>
+</ul>
+</blockquote>
+<p>2001-11-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (Magick): Invoke DestroyMagick() to clean up
+ImageMagick allocations.</li>
+<li>lib/Magick++/Include.h (ImageType): Added some missing enums to
+Magick namespace.</li>
+</ul>
+</blockquote>
+<p>2001-11-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/CoderInfo.h (CoderInfo): Syntax fix.
+ImageMagick bug #975.</li>
+<li>lib/Image.cpp (draw): Delete ostrstream data when it is no
+longer needed. ImageMagick bug #988.</li>
+</ul>
+</blockquote>
+<p>2001-11-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (pixelColor): Implementation didn't handle pixels
+indexes correctly. Now it does.</li>
+</ul>
+</blockquote>
+<p>2001-11-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (matteFloodfill): Coordinates are long values.
+(floodFillOpacity): New method to floodfill opacity across pixels
+matching color (within fuzz-factor) at point. Similar to
+matteFloodfill except that color is selected from starting point.</li>
+</ul>
+</blockquote>
+<p>2001-10-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;sun1107&#46;ssd&#46;usa&#46;alcatel&#46;com">bfriesen<span>&#64;</span>sun1107<span>&#46;</span>ssd<span>&#46;</span>usa<span>&#46;</span>alcatel<span>&#46;</span>com</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (strokeDashArray): Change to type double.
+(strokeDashOffset): Change to type double.</li>
+</ul>
+</blockquote>
+<p>2001-10-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Geometry.cpp (Geometry): Add constructor from
+MagickLib::RectangleInfo.</li>
+<li>lib/Image.cpp (boundingBox): Method to return smallest bounding
+box enclosing non-border pixels.</li>
+</ul>
+</blockquote>
+<p>2001-10-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (getConstIndexes): Add method to obtain read-only
+pixel indexes.
+(getIndexes): Add method to obtain read-write pixel indexes.
+(Image::Image): Send warnings from Image constructor to cerr
+rather than throwing.</li>
+<li>lib/Color.cpp (Color(PixelPacket&amp;)): Change argument to const
+PixelPacket&amp; as it should have been from the beginning.</li>
+<li>lib/Image.cpp (pixelColor): Reimplemented to be a const method.</li>
+</ul>
+</blockquote>
+<p>2001-10-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (getConstPixels): New method for returning a
+read-only pixel view. Still requires documentation.</li>
+<li>lib/Magick++/STL.h (coderInfoList): Fixed compilation problem
+when compiling with Visual C++.</li>
+</ul>
+</blockquote>
+<p>2001-10-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Color.h (scaleQuantumToDouble): Add polymorphic
+version that accepts double to avoid downconversion error.</li>
+</ul>
+</blockquote>
+<p>2001-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Color.h (scaleQuantumToDouble): Cast Quantum to
+double prior to division. Hopefully fix bug.</li>
+</ul>
+</blockquote>
+<p>2001-10-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Color.h (Color(const std::string)): Pass argument by reference.</li>
+<li>(operator=): Pass argument by const reference.</li>
+</ul>
+</blockquote>
+<p>2001-09-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (coderInfoList): New function to support
+obtaining format coder information (as a list of type CoderInfo).</li>
+<li>lib/CoderInfo.cpp (CoderInfo): New class to support obtaining
+format coder information.</li>
+</ul>
+</blockquote>
+<p>2001-09-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (depth): Use GetImageDepth and SetImageDepth
+rather than just getting/setting depth attributes.</li>
+<li>lib/Magick++/STL.h (opacityImage): New unary function object to
+set, or attenuate, image pixel opacity throughout the image.</li>
+<li>lib/Image.cpp (opacity): New method to set, or attenuate, image
+pixel opacity throughout the image.</li>
+<li>lib/Magick++/STL.h (typeImage): New unary function object to set
+image type.</li>
+<li>lib/Image.cpp (type): Added ability to set image type.</li>
+</ul>
+</blockquote>
+<p>2001-09-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (write(Blob)): Tell blob to use malloc allocator.</li>
+<li>lib/Blob.cpp (updateNoCopy): Added parameter so that user can
+specify the allocation system (malloc or new) the memory came
+from. Defaults to C++ memory allocator.</li>
+</ul>
+</blockquote>
+<p>2001-09-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (fileSize): Decided to change return type to off_t
+for increased range and portability.</li>
+</ul>
+</blockquote>
+<p>2001-09-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (fileSize): Changed return value to double.</li>
+</ul>
+</blockquote>
+<p>2001-09-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (colorMap): Allocate a colormap if it does not
+already exist.</li>
+<li>lib/Pixels.cpp (indexes): Don't attempt to validate image type.</li>
+<li>lib/Image.cpp (colorMap): Optimized more for performance.</li>
+</ul>
+</blockquote>
+<p>2001-09-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (fontTypeMetrics): New method to support
+retrieving font metrics.</li>
+<li>lib/TypeMetric.cpp : New class to support font metrics
+information.</li>
+</ul>
+</blockquote>
+<p>2001-09-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Color.h (scaleDoubleToQuantum): Inline static
+method made from previous ScaleDoubleToQuantum #define.
+(scaleQuantumToDouble): Inline static method made from previous
+ScaleQuantumToDouble #define. Helps avoid possibility of clash
+with user code.</li>
+</ul>
+</blockquote>
+<p>2001-08-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (colorMap): Automatically extend colormap if
+specified index is past end of current colormap. Colormap is
+limited to a maximum depth of MaxRGB entries.</li>
+</ul>
+</blockquote>
+<p>2001-08-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (clipMask): New method to add a clip mask to the
+image. Adds clipping to any image operation wherever the clip
+mask image is tranparent.</li>
+</ul>
+</blockquote>
+<p>2001-08-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (print): Add single quotes around file names
+and font specifications.</li>
+</ul>
+</blockquote>
+<p>2001-07-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (read): Ensure that only a single image frame is
+read.</li>
+</ul>
+</blockquote>
+<p>2001-07-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (flattenImages): New function to flatten a
+layered image.</li>
+<li>lib/Montage.cpp (Montage): Montage initial defaults are no
+longer drawn from ImageInfo. MontageInfo structure is entirely
+filled out by updateMontageInfo();</li>
+</ul>
+</blockquote>
+<p>2001-07-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Montage.cpp (updateMontageInfo): Bugfix; colors which were
+intentionally specified as invalid (unset) were being ignored.
+This produced unattractive label text when doing a montage.</li>
+</ul>
+</blockquote>
+<p>2001-07-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (medianFilterImage): Changed argument from
+unsigned int to const double.
+(fillColorImage): New method.
+(strokeColorImage): New method.
+(isValidImage): New method.</li>
+<li>lib/Magick++/Image.h (edge): Change argument from unsigned int
+to double.
+(medianFilter): Changed argument from unsigned int to const
+double.</li>
+<li>lib/Magick++/STL.h (edgeImage): Change argument from unsigned
+int to double.</li>
+<li>demo/demo.cpp (main): Updated to match PerlMagick demo.</li>
+</ul>
+</blockquote>
+<p>2001-06-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (shaveImage): New function to shave edges
+from image.</li>
+<li>lib/Image.cpp (shave): New method to shave edges from image.</li>
+</ul>
+</blockquote>
+<p>2001-06-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (quantize): Remove conditions on whether
+quantization should be done. Now quantization is always done.</li>
+</ul>
+</blockquote>
+<p>2001-06-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Image.h (blur,charcoal,emboss,sharpen): Changed
+radius and sigma parameters to match current ImageMagick defaults.</li>
+</ul>
+</blockquote>
+<p>2001-02-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Options.cpp (updateDrawInfo): The updateDrawInfo() method
+was no longer needed. Due to ImageMagick changes, calling it was
+causing some options to be lost.</li>
+</ul>
+</blockquote>
+<p>2001-01-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (fillRule): New method to specify the rule to use
+when filling drawn objects.</li>
+</ul>
+</blockquote>
+<p>2001-01-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (erase): New method to reset image to background
+color.
+(strokeAntiAlias): New method to control antialiasing of stroked
+objects.</li>
+</ul>
+</blockquote>
+<p>2001-01-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (channel): Renamed method from 'layer' to match
+equivalent change in ImageMagick (ChannelImage). Enumeration
+names *Layer renamed to *Channel.</li>
+</ul>
+</blockquote>
+<p>2001-01-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Montage.h (strokeColor): New method.
+(fillColor): New method.</li>
+<li>lib/Image.cpp (replaceImage): Revised logic so that an inValid
+image should be returned if a NULL pointer is passed. Before this
+change the existing image was preserved.
+(label): Work-around ImageMagick SetImageAttribute bug.</li>
+</ul>
+</blockquote>
+<p>2001-01-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp : Adjusted to ImageMagick animation parameter API
+change.</li>
+</ul>
+</blockquote>
+<p>2000-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableCompositeImage): Support specifying
+composition rule.</li>
+</ul>
+</blockquote>
+<p>2000-12-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (draw): Bugfix - the primitive string was not
+properly null terminated. It is a wonder that the code usually
+worked at all. Thanks to <a class="reference external" href="mailto:afatela&#37;&#52;&#48;marktest&#46;pt">afatela<span>&#64;</span>marktest<span>&#46;</span>pt</a> for reporting it.</li>
+</ul>
+</blockquote>
+<p>2000-12-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (deconstructImages): New STL function for
+deconstructing an image list to assist with creating an animation.
+(mosaicImages): New STL function for inlaying an image list to
+form a single coherent picture.</li>
+</ul>
+</blockquote>
+<p>2000-12-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (convolve): New method to convolve image using
+user-supplied convolution matrix.
+(unsharpmask): New method to replace image with a sharpened
+version of the original image using the unsharp mask algorithm.</li>
+</ul>
+</blockquote>
+<p>2000-12-14 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>: Adapted to ImageMagick API change which eliminates
+AnnotateInfo.</li>
+</ul>
+</blockquote>
+<p>2000-12-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (annotateImage): Brought into sync with
+annotate methods in Image.</li>
+</ul>
+</blockquote>
+<p>2000-12-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (annotate): Usage of Geometry parameter was
+incorrect. Geometry parameter is used to specify bounding
+area. This changes the interpretation for two of the annotate
+methods (which probably weren't usable before).</li>
+</ul>
+</blockquote>
+<p>2000-11-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Color.h (alphaQuantum): Bugfix. Due to change in
+treatment of opacity member, alphaQuantum() was not allowing value
+to be set.</li>
+</ul>
+</blockquote>
+<p>2000-11-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableFillRule): New class to specify fill
+rule (see SVG's fill-rule).
+(DrawableDashOffset): New class to specify initial offset in dash
+array.
+(DrawableDashArray): New class to specify a stroke dash pattern.
+(DrawableStrokeLineCap): New class to specify the shape to be used
+at the end of open subpaths when they are stroked.
+(DrawableStrokeLineJoin): New class to specify the shape to be
+used at the corners of paths (or other vector shapes) when they
+are stroked.
+(DrawableMiterLimit): New class to specify extension limit for
+miter joins.</li>
+</ul>
+</blockquote>
+<p>2000-11-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (annotate): Reimplement text rotation using affine
+member of AnnotateInfo.
+(strokeDashOffset): New method for specifying the dash offset to
+use for drawing vector objects. Similar to SVG stroke-dashoffset.
+(strokeDashArray): New method for specifying the dash pattern to
+use for drawing vector objects. Similar to SVG stroke-dasharray
+(strokeLineCap): New method to specify the shape to be used at the
+end of open subpaths when they are stroked. Similar to SVG
+stroke-linecap.
+(strokLineJoin): New method to specify the shape to be used at the
+corners of paths (or other vector shapes) when they are
+stroked. Similar to SVG stroke-linejoin.
+(strokeMiterLimit): New method to specify the miter limit when
+joining lines using MiterJoin. Similar to SVG stroke-miterlimit.
+(strokeWidth): Renamed lineWidth method to strokeWidth.</li>
+</ul>
+</blockquote>
+<p>2000-10-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Drawable.h (DrawableCompositeImage): Add a
+short-form constructor to support specifying image location and
+name, but without specifying rendered size (use existing image
+size).</li>
+</ul>
+</blockquote>
+<p>2000-10-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Drawable.h (DrawablePopGraphicContext): New class
+to pop graphic context.
+(DrawablePushGraphicContext): New class to push graphic context.</li>
+<li>lib/Drawable.cpp (DrawableStrokeAntialias): New class to set
+stroke antialiasing.
+(DrawableTextAntialias): New class to set text antialiasing.</li>
+</ul>
+</blockquote>
+<p>2000-10-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (transformOrigin): New method to set origin of
+coordinate system for use when annotating with text or drawing
+(transformRotation): New method to set rotation for use when
+annotating with text or drawing
+(transformScale): New method to set scale for use when annotating
+with text or drawing.
+(transformSkewX): New method to set skew for use in X axis when
+annotating with text or drawing.
+(transformSkewY): New method to set skew for use in Y axis when
+annotating with text or drawing.
+(transformReset): New method to reset transformation to default.</li>
+<li>lib/Drawable.cpp (DrawablePath): New class for drawing SVG-style
+vector paths.
+(PathArcArgs): New class. Argument for PathArcArgs &amp; PathArcAbs.
+(PathArcAbs): New class. Draw arc using absolute coordinates.
+(PathArcRel): New class. Draw arc using relative coordinates.
+(PathClosePath): New class. Close drawing path.
+(PathCurvetoArgs): New class. Argument class for PathCurvetoAbs &amp;
+PathCurvetoRel.
+(PathCurvetoAbs): New class. Cubic bezier, absolute coordinates
+(PathCurvetoRel): New class. Cubic bezier, relative coordinates
+(PathSmoothCurvetoAbs): New class. Cubic bezier, absolute
+coordinates
+(PathSmoothCurvetoRel): New class. Cubic bezier, relative
+coordinates
+(PathQuadraticCurvetoArgs): New class. Argument class for
+PathQuadraticCurvetoAbs and PathQuadraticCurvetoRel.
+(PathQuadraticCurvetoAbs): New class. Quadratic bezier, absolute
+coordinates
+(PathQuadraticCurvetoRel): New class. Quadratic bezier, relative
+coordinates
+(PathSmoothQuadraticCurvetoAbs): New class. Quadratic bezier,
+absolute coordinates
+(PathSmoothQuadraticCurvetoRel): New class. Quadratic bezier,
+relative coordinates
+(PathLinetoAbs): New class. Line to, absolute coordinates
+(PathLinetoRel): New class. Line to, relative coordinates
+(PathLinetoHorizontalAbs): New class. Horizontal lineto, absolute
+coordinates
+(PathLinetoHorizontalRel): New class. Horizontal lineto, relative
+coordinates
+(PathLinetoVerticalAbs): New class. Veritical lineto, absolute
+coordinates.
+(PathLinetoVerticalRel): New class. Vertical lineto, relative
+coordinates.
+(PathMovetoAbs): New class. Moveto, absolute coordinates
+(PathMovetoRel): New class. Moveto, relative coordinates</li>
+</ul>
+</blockquote>
+<p>2000-10-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableSkewX): New object to apply skew in X
+direction.
+(DrawableSkewY): New object to apply skew in Y direction.</li>
+</ul>
+</blockquote>
+<p>2000-10-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (edge): Change argument from 'unsigned int' to
+'double' in order to match ImageMagick API.</li>
+</ul>
+</blockquote>
+<p>2000-10-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableCompositeImage): Renamed from
+DrawableImage.
+(DrawableTextDecoration): Renamed form DrawableDecoration.
+(all-classes): Complete re-write to write the drawing command to a
+stream when draw() is invoked rather than at object construction
+time. This may be somewhat slower for individual draw operations
+but but should be at least as fast for lists of drawing commands,
+and is more flexible going into the future. Drawable classes now
+inherit from DrawableBase but are passed into STL lists and Image
+draw() methods via the surrogate class Drawable. The upshot of
+all this is that the existing published API has not been altered
+but things work much differently under the covers.</li>
+</ul>
+</blockquote>
+<p>2000-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableStrokeColor): Renamed from
+DrawableStroke
+(DrawableFillColor): Renamed from DrawableFill
+(DrawableRotation): New class to influence object rotation.
+(DrawableScaling): New class to influence object scaling.
+(DrawableTranslation): New class to influence object translation.</li>
+</ul>
+</blockquote>
+<p>2000-10-04 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableAffine): New class to influence object
+scaling, rotation, and translation (as defined by SVG XML).
+(DrawableAngle): New class to influence drawing angle.
+(DrawableDecoration): New class to influence text decoration such
+as underline.
+(DrawableFill): New class to set object filling color.
+(DrawableFillOpacity): New class to set opacity to use when
+filling object.
+(DrawableFont::): New class to set font.
+(DrawableGravity): New class to set text placement gravity.
+(DrawablePointSize): New class to set font point size.
+(DrawableStroke): New class to set drawing stroke color.
+(DrawableStrokeOpacity): New class to set drawing stroke opacity.
+(DrawableStrokeWidth): New class to set drawing stroke width.</li>
+</ul>
+</blockquote>
+<p>2000-10-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableImage): Added width and height
+parameters to specify size to scale rendered image to. This is
+actually a bug-fix since it seems that the correct drawing command
+was no longer being generated.</li>
+</ul>
+</blockquote>
+<p>2000-09-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (read): New overloaded method to read an image
+based on an array of raw pixels, of specified type and mapping, in
+memory.
+(write): New overloaded method to write image to an array of
+pixels, of specified type and mapping.
+(Image): New overloaded constructor to construct an image based on
+an array of raw pixels, of specified type and mapping, in memory.</li>
+</ul>
+</blockquote>
+<p>2000-09-27 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (colorize): API change to match change in
+ImageMagick. Now accepts percentage of red, green, and blue to
+colorize with using specified pen color.</li>
+</ul>
+</blockquote>
+<p>2000-09-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Drawable.h: Reverted Coordinate implemenation back
+from and STL pair based implementation to a simple class. Maybe
+this will improve portability. It is more understandable anyway.</li>
+</ul>
+</blockquote>
+<p>2000-09-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Options.cpp : Bugfix. Some DrawInfo attributes were not
+being updated. This lead to options like fontPointsize not
+changing the font.</li>
+</ul>
+</blockquote>
+<p>2000-08-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (blurImage, charcoalImage, embossImage,
+sharpenImage): Expand order_ argument to radius_ &amp; sigma_
+arguments for more control (matches ImageMagick API change).</li>
+<li>lib/Image.cpp (blur, charcoal, emboss, sharpen): Expand order_
+argument to radius_ &amp; sigma_ arguments for more control (matches
+ImageMagick API change).</li>
+</ul>
+</blockquote>
+<p>2000-08-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (read): Check returned Image for embedded
+exception, as well as the existing parameter check. This fixes
+the bug that warnings are not reported.</li>
+</ul>
+</blockquote>
+<p>2000-07-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>test/*.cpp demo/*.cpp: Added call to MagickIncarnate() to set
+ImageMagick install location for Windows. Hopefully this hack can
+be removed someday.</li>
+</ul>
+</blockquote>
+<p>2000-07-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (colorFuzz): Changed type to 'double' from
+'unsigned int' to match change in ImageMagick.</li>
+<li>lib/Color.cpp (Color*): Added copy constructor from base class.
+(operator =): Added assignment operator from base class.</li>
+</ul>
+</blockquote>
+<p>2000-06-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h : Changed enumeration FilterType to
+FilterTypes, and QuantumTypes to QuantumType in order to match
+last-minute API change in ImageMagick.</li>
+</ul>
+</blockquote>
+<p>2000-06-22 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Pixels.cpp (indexes): Bugfix, use
+GetCacheViewIndexes() rather than GetIndexes().</li>
+</ul>
+</blockquote>
+<p>2000-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Montage.h (gravity): Type of gravity_ argument, and
+return value changed from 'unsigned int' to GravityType.</li>
+</ul>
+</blockquote>
+<p>2000-04-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (DrawableArc, DrawableBezier, DrawablePolyline,
+RoundRectangle): Added support for new drawing objects.</li>
+</ul>
+</blockquote>
+<p>2000-04-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp: Removed all public methods which accept
+Coordinate arguments except those that accept lists of
+Coordinates. Converted remaining drawable object methods into
+individual classes which inherit from Drawable (e.g. &quot;circle&quot;
+becomes &quot;DrawableCircle&quot;). The constructor for each class is
+compatible with the original method. This results in annoying
+changes to user code but provides more implementation flexibility.</li>
+</ul>
+</blockquote>
+<p>2000-04-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp
+(fillEllipse,fillRectangle,fillCircle,fillPolygon): Removed
+methods. Object filling is now based on whether fillColor or
+penTexture are valid or not. This reflects ImageMagick internal
+changes.</li>
+<li>lib/Image.cpp (fillColor): New method to specify fill color when
+drawing objects.
+(strokeColor): New method to specify outline color when drawing
+objects.
+(penColor): Setting penColor now sets fillColor and
+strokeColor. Getting penColor retrieves the value of
+strokeColor. This supports backwards compatability.</li>
+</ul>
+</blockquote>
+<p>2000-03-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (lineWidth): Type changed from unsigned int to
+double.</li>
+</ul>
+</blockquote>
+<p>2000-03-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (Magick):</li>
+</ul>
+</blockquote>
+<p>2000-03-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h
+(blurImage,charcoalImage,edgeImage,embossImage,
+reduceNoiseImage,sharpenImage): Modified to support order of the
+pixel neighborhood. Backward compatable function objects
+constructors are provided for embossImage, and reduceNoiseImage.</li>
+<li>lib/Image.cpp (blur,charcoal,edge,emboss,reduceNoise,sharpen):
+Now accept unsigned int argument which represents the order of the
+pixel neighborhood (e.g. 3). This is not a backwards compatable
+change, however, backward compatable methods are provided for
+emboss, and reduceNoise.</li>
+</ul>
+</blockquote>
+<p>2000-03-02 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Pixels.h (Pixels): Moved Image pixel methods to
+Pixels class.</li>
+</ul>
+</blockquote>
+<p>2000-02-29 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (annotate): Re-wrote to improve performance.
+(draw): Re-wrote to improve performance.</li>
+</ul>
+</blockquote>
+<p>2000-02-26 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Drawable.cpp (text): Bugfix: support spaces in annotation
+text.</li>
+</ul>
+</blockquote>
+<p>2000-02-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (gaussianBlurImage): New function object to
+Gaussian blur image.</li>
+<li>lib/Image.cpp (gaussianBlur): New method to Gaussian blur image.</li>
+</ul>
+</blockquote>
+<p>2000-02-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp : Call-back based LastError class is eliminated in
+favor of ImageMagick 5.2's re-entrant ExceptionInfo reporting.
+This should make Magick++ thread safe under Win32.</li>
+</ul>
+</blockquote>
+<p>2000-02-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (floodFillTexture): Fixed bug due to pixel pointer
+becoming invalid in ImageMagick function.</li>
+</ul>
+</blockquote>
+<p>2000-01-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp : Added locking to reference counting to ensure
+thread (pthread) safety.</li>
+<li>lib/Blob.cpp : Added locking to reference counting to ensure
+thread (pthread) safety.</li>
+<li>lib/LastError.cpp: Added support for thread specific data
+(pthreads) so that error reporting is thread safe.</li>
+<li>lib/Magick++/Thread.h: Added thread wrapper class to provide
+thread-safe locking (pthreads) to Magick++.</li>
+</ul>
+</blockquote>
+<p>2000-01-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp: Added methods getPixels, setPixels, syncPixels,
+readPixels, and writePixels, in order to provide low-level access
+to Image pixels. This approach (direct wrapper around ImageMagick
+functions) does not mean that the planned object-oriented wrapper
+has been forgotten, only that this wrapper is not ready yet, and
+users need to manipulate pixels *now*.</li>
+</ul>
+</blockquote>
+<p>2000-01-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/LastError.cpp: Complete re-implementation of LastError so
+that it hides its implementation. Also assures that all memory is
+explicitly deallocated at program exit to avoid the appearance of
+a leak.</li>
+</ul>
+</blockquote>
+<p>2000-01-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (size): Bug-fix. Set image columns and rows as
+well as image options columns and rows.</li>
+<li>lib/Image.cpp :Depth parameters are now all unsigned in for
+consistency.</li>
+<li>lib/Image.cpp (write): Parameters for writing Blobs re-arranged
+again to hopefully be more sensible.</li>
+<li>lib/Magick++/STL.h: Bug-fix. Re-number scenes from zero when
+linking image range in container into a list. This provides
+expected results.</li>
+</ul>
+</blockquote>
+<p>1999-12-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp
+(write): Additional overloaded methods for BLOBs.
+(read): Additional overloaded methods for BLOBs. Re-ordered
+parameters for one existing method.
+(Image): Additional overloaded methods for BLOBs. Re-ordered
+parameters for one existing method.</li>
+</ul>
+</blockquote>
+<p>1999-12-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (floodFillTexture): Changed coordinates to
+unsigned.</li>
+</ul>
+</blockquote>
+<p>1999-12-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (medianFilter): New method.</li>
+</ul>
+</blockquote>
+<p>1999-12-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (density): Bug fix. Was not setting image x &amp; y
+density.</li>
+</ul>
+</blockquote>
+<p>1999-11-30 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (page): psPageSize() is renamed to page() and now
+properly returns the attribute from the image.</li>
+</ul>
+</blockquote>
+<p>1999-11-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp: Rename transformColorSpace() to colorSpace().
+Added colorSpace() accessor method.</li>
+</ul>
+</blockquote>
+<p>1999-11-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Color.cpp: Re-implemented PixelPacket pointer so that it is
+never NULL and added a 'valid' field for tracking object validity.</li>
+</ul>
+</blockquote>
+<p>1999-11-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (quantizeError): Eliminated method.</li>
+</ul>
+</blockquote>
+<p>1999-11-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (annotate &amp; draw): Changed implementation to
+reflect change to the way AnnotateInfo is managed by ImageMagick.</li>
+</ul>
+</blockquote>
+<p>1999-11-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (cacheThreshold): New method to set the pixel
+cache threshold.</li>
+<li>lib/Magick++/Include.h (Magick): Added new enumerations from
+classify.h.</li>
+</ul>
+</blockquote>
+<p>1999-10-28 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Options.h (fontPointsize): Argument is now a double
+to match change in ImageMagick.</li>
+<li>lib/Image.cpp (fontPointsize): Argument is now a double to match
+change in ImageMagick.</li>
+</ul>
+</blockquote>
+<p>1999-10-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Blob.cpp (BlobRef): Bugfix -- start blob reference count at
+one rather than zero.</li>
+</ul>
+</blockquote>
+<p>1999-10-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (Image): Fixed Image constructors from Blob. The
+image reference was not being instantiated as it should have been,
+causing a crash.</li>
+</ul>
+</blockquote>
+<p>1999-10-05 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Blob.cpp: All blob length parameters are now of type size_t.</li>
+<li>lib/Image.cpp (write): Length estimate is now of type size_t.</li>
+</ul>
+</blockquote>
+<p>1999-09-20 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (rotate): No longer accepts a crop option since
+ImageMagick no longer supports this.
+(shear): No longer accepts a crop option since ImageMagick no
+longer supports this.</li>
+</ul>
+</blockquote>
+<p>1999-09-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp:
+(rotate): No longer accepts sharpen argument. User must sharpen
+seperately if desired. This change is due to a similar change in
+ImageMagick 5.0.
+(condense): Removed method.
+(uncondense): Removed method.
+(condensed): Removed method.
+(pixelColor): Adapted to 5.0.</li>
+<li>lib/Magick++/Color.h : Rewrote to efficiently use ImageMagick
+5.0's PixelPacket color representation.</li>
+<li>lib/Color.cpp : Rewrote to efficiently use ImageMagick 5.0's
+PixelPacket color representation.</li>
+</ul>
+</blockquote>
+<p>1999-09-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (condensed): Bug fix. The condensed() method was
+returning the opposite bool value than it should. Oops!</li>
+</ul>
+</blockquote>
+<p>1999-09-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Include.h (MagickLib): Eliminated requirement for
+including &lt;magick/define.h&gt;.</li>
+</ul>
+</blockquote>
+<p>1999-08-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp: Added accessor methods for other key ImageMagick
+structs.</li>
+<li>lib/Options.cpp (penTexture): Fixed bug with removing texture
+caused by change in Image constructor.</li>
+<li>lib/Image.cpp: Changed strategy such that an Image containing a
+null MagickLib::Image pointer is never constructed except for
+under error conditions. Removed existing checks for null image
+pointer on attribute methods.
+Use image() and constImage() accessor methods as part of Image
+implementation in order to clean-up code and ensure
+const-correctness.</li>
+</ul>
+</blockquote>
+<p>1999-08-03 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/STL.h (Magick): Added STL function readImages().
+Not tested yet.
+(Magick): Added STL function writeImages(). Not tested yet.</li>
+<li>lib/Image.cpp: Removed support for 'text' attribute as this is
+no longer present in ImageMagick as of 4.2.8.</li>
+</ul>
+</blockquote>
+<p>1999-07-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Image.cpp (condense): Skip condensing image if already
+condensed.
+(uncondense): Skip uncondensing image if not condensed.
+(condensed): New method to test if image is condensed.
+(classType): New method which supports conversion of the image
+storage class. May result in loss of color information
+(quantization is used) if a DirectClass image is converted to
+PseudoClass.</li>
+</ul>
+</blockquote>
+<p>1999-07-18 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Magick++/Color.h (Magick::Color): Color parameters are now
+stored in a MagickLib::RunlengthPacket structure which is
+referenced via a pointer. This structure is either allocated by a
+Magick::Color constructor or passed as an argument to a
+Magick::Color constructor so that it may refer to to a
+MagickLib::Image pixel. The owner of the structure is managed so
+that the structure is only deleted if it was allocated by
+Magick::Color.</li>
+</ul>
+</blockquote>
+<p>1999-07-09 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>overall : Removed 'Magick' prefix from all source file
+names. Moved class headers to Magick++ subdirectory. This should
+not break any code using the documented interface (via
+Magick++.h).</li>
+</ul>
+</blockquote>
+<p>1999-07-08 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickImage.cpp (composite): Support composition placement
+by gravity like PerlMagick does.</li>
+</ul>
+</blockquote>
+<p>1999-07-07 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickImage.cpp (Image): Added constructors to construct an
+Image from a BLOB.</li>
+</ul>
+</blockquote>
+<p>1999-07-06 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/manipulate.cpp (main): Wrote a basic sanity test for
+reading and writing BLOBS.</li>
+</ul>
+</blockquote>
+<p>1999-06-21 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickImage.cpp (read): Added support for reading an encoded
+image stored in a BLOB. Uses new ImageMagick APIs introduced on
+July 21, 1999.
+(write): Added support for writing an encoded image to a BLOB.</li>
+</ul>
+</blockquote>
+<p>1999-06-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickInclude.h : Use new &lt;magick/api.h&gt; interface to
+ImageMagick to avoid namespace-induced problems.</li>
+<li>configure.in : CPPFLAGS and LDFLAGS specified via the
+environment take precidence over flags from Magick-config.</li>
+</ul>
+</blockquote>
+<p>1999-05-31 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickSTL.h (mapImages): New algorithm to map the sequence
+of images to the color map of a provided image.
+(quantizeImages): New algorithm to quantize a sequence of images
+to a common color map.</li>
+</ul>
+</blockquote>
+<p>1999-05-24 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickBlob.cpp (updateNoCopy): New method to allow derived
+classes to insert data into the base class without making a copy
+of the data. This represents a transfer of ownership of the data
+from the derived class to the base class.</li>
+</ul>
+</blockquote>
+<p>1999-05-23 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickColor.cpp (operator =): Adapted to new ImageMagick
+4.2.6 as of 5/23/99 which removes X11 compatability functions.</li>
+<li>lib/MagickGeometry.cpp (operator =): Adapted to new ImageMagick
+4.2.6 as of 5/23/99 which removes X11 compatability functions.</li>
+</ul>
+</blockquote>
+<p>1999-05-17 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickBlob.cpp (Blob): Support default constructor for Blob.</li>
+</ul>
+</blockquote>
+<p>1999-05-16 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickSTL.h (transformColorSpaceImage): New unary function
+object to invoke transformColorSpace on STL container object.</li>
+<li>lib/MagickImage.cpp (transformColorSpace): New method to
+transform the image data to a new colorspace.</li>
+</ul>
+</blockquote>
+<p>1999-05-15 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickImage.cpp (ping): Re-implemented to match (requested)
+API change in ImageMagick 4.2.5. Method signature has changed to
+be like 'read'.
+(annotate): Added two new overloaded methods for text annotation
+in order to support the new rotated text capability in ImageMagick
+4.2.5. To accomplish this, the default for gravity had to be
+removed from several methods. This may impact existing code.
+Still not sure if this is the best set of method signatures.</li>
+</ul>
+</blockquote>
+<p>1999-05-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickImage.cpp (ping): New method to obtain image size in
+bytes and geometry without the overhead of reading the complete
+image.
+(uncondense): New method to uncompress run-length encoded pixels
+into a simple array to make them easy to operate on.</li>
+</ul>
+</blockquote>
+<p>1999-05-12 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickImage.cpp (comment): Passing an empty string as the
+comment results in no comment at all rather than a comment with no
+data.</li>
+</ul>
+</blockquote>
+<p>1999-05-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickImage.cpp (iccColorProfile): Implemented method to set
+ICC color profile from opaque object in memory (must be formatted
+outside of Magick++).
+(iptcProfile): Implemented method to set IPTC profile from opaque
+object in memory (must be formatted outside of Magick++).</li>
+<li>lib/MagickBlob.cpp: New class to support managing user-supplied
+opaque Binary Large OBjects (BLOBS) in the API. Reference counted
+to improve semantics and to possibly reduce memory consumption.</li>
+</ul>
+</blockquote>
+<p>1999-05-01 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/Makefile.am (libMagick): Updated to use libtool 1.3 so that
+shared library can be built.</li>
+</ul>
+</blockquote>
+<p>1999-04-25 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickImage.cpp (montageGeometry): Return Magick::Geometry
+rather than std::string.</li>
+</ul>
+</blockquote>
+<p>1999-04-19 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickColor.cpp (alpha): Added support for setting alpha via
+scaled-double to the Color class. The new method name is 'alpha'.</li>
+</ul>
+</blockquote>
+<p>1999-04-13 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>lib/MagickColor.cpp: Added support for setting an alpha value
+(unscaled Quantum only) for use on DirectColor images that have
+matte enabled. This requires ImageMagick 4.2.2 dated April 13,
+1999 or later to compile since Cristy added a special flag to
+allow testing to see if the user has specified an opacity value:
+&quot;I added XColorFlags to magick/classify.h. If DoMatte is set in
+color-&gt;flags then the opacity value is valid in color-&gt;pixel.&quot;</li>
+</ul>
+</blockquote>
+<p>1999-04-11 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>demo/flip.cpp (main): New file. Demonstrates use of flipImage
+function object as well as morphImages algorithm.</li>
+</ul>
+</blockquote>
+<p>1999-04-10 Bob Friesenhahn &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>tests/color.cpp : New file to support testing the Magick::Color
+classes.</li>
+<li>lib/MagickOptions.cpp: The ImageInfo filter member is now
+ignored by ImageMagick (as of ImageMagick 4.2.2 April 10, 1998) so
+support for setting it is removed. The Image filter member is
+still updated. According to Cristy, this ImageMagick version
+removes automatic sharpening of resized images. The blur member
+is added to the Image structure. A blur value &lt; 1 causes the image
+to be sharpened when resizing while a value &gt; 1 leaves the image
+blurry. Magick++ does not yet support the blur member.</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/ChangeLog.rst b/www/Magick++/ChangeLog.rst
new file mode 100644
index 0000000..c794f8e
--- /dev/null
+++ b/www/Magick++/ChangeLog.rst
@@ -0,0 +1,1886 @@
+2017-03-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (orientation): Update orientation in EXIF profile,
+ if it exists.
+ (attribute): Added Image attribute method which accepts a 'char \*'
+ argument, and will remove the attribute if the value argument is
+ NULL.
+
+2014-11-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Geometry.h (Magick::Geometry): Add and document
+ limitPixels() and fillArea() methods to support '@' and '^'
+ geometry qualifiers. Fill area contributed by Long Ho and
+ limitPixels() by Bob Friesenhahn.
+
+ - ../www/Magick++/Image.rst: Document extent and resize methods.
+
+ - lib/STL.cpp (extentImage): New function object to invoke image
+ extent method. Original implementation contributed by Long Ho.
+ Subsequently modified by Bob Friesenhahn.
+ (resizeImage): New function object to invoke image resize
+ method. Contributed by Long Ho.
+
+ - lib/Image.cpp (extent): New method to place image on sized
+ canvas of constant color using gravity. Contributed by Long Ho.
+ (resize): New method to resize image specifying geometry, filter,
+ and blur. Original implementation contributed by Long Ho.
+ Subsequently modified by Bob Friesenhahn.
+
+2014-01-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (thumbnail): New method for fast image resizing,
+ particularly to make thumbnails.
+
+2013-12-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableDashArray): DrawableDashArray now uses
+ C++ memory allocation rather than from GraphicsMagick library.
+ Also, implement direct copy constructor and assignment operator
+ rather than using dasyarray() method.
+
+2012-11-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - COPYING: Change Magick++ usage license to be exactly the MIT
+ license without the additional sentence about retention of
+ copyright (which was already legally implicit).
+
+2012-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (defineValue): Use AddDefinition() rather than
+ AddDefinitions().
+
+2012-03-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h (Magick): Added support for RandomNoise.
+
+2012-03-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/STL.cpp (stripImage): New unary function to to remove all
+ profiles and text attributes from the image.
+
+ - lib/Image.cpp (strip): New method to remove all profiles and
+ text attributes from the image.
+
+2011-12-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: Explicitly DLL import/export Magick++
+ symbols when building under MinGW GCC.
+
+2010-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h (Magick): Add LZMACompression
+
+2010-12-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (InitializeMagick): Don't use atexit(). C++
+ destructures are sufficient.
+
+2010-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (backgroundColor, borderColor, matteColor):
+ Opacity part of user-specified color needs to be preserved.
+ Problem was reported by Alexander Zheltov.
+
+2010-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/CoderInfo.h: Add default constructor, copy
+ constructor, and assignment operator.
+
+2010-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (Magick): Fix potential memory leak.
+
+2010-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - demo/shapes.cpp (main): Floodfill shape more agressively and
+ scale fuzz factor so that it provides the same results across
+ quantum depths.
+
+2009-10-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/STL.cpp, lib/Magick++/STL.h (shadeImage): ShadeImage was the
+ result of a botched cut-and-paste. Corrected now. Thanks to
+ Jukka Manner for making me aware of this.
+
+2009-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (cdl): New method to apply the ASC CDL.
+ (colorMatrix): New method to apply a color matrix to the image
+ channels.
+ (haldClut): New method to apply a color lookup table (Hald CLUT)
+ to the image.
+
+2009-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (attribute): Invoke modifyImage() to assure
+ exclusive access to image when updating attributes.
+
+2009-03-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (quantumOperator): New variant of method which
+ takes a 'double' argument, as it originally should. Previous
+ method taking a Quantum argument is still supported but marked
+ deprecated.
+
+2009-01-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: If the user defines STATIC\_MAGICK in his
+ project, then the Windows DLL decorations are ignored. Without
+ this, Windows DLL-based code can't use a static GraphicsMagick.
+ This is recommended by SourceForge bug 2537627.
+
+ - lib/Magick++/Drawable.h: Apparently the only STL container which
+ may be DLL-exported is <vector> but we are using <list> so disable
+ DLL-export of list-based template objects.
+
+2008-10-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Color.cpp: Added an \_isValid boolean to represent an invalid
+ color. Transparent black is no longer special and can be used in
+ drawing.
+ - lib/Pixels.cpp: Update to use new cache view interfaces provided
+ by GraphicsMagick 1.3.
+
+2008-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (addNoiseChannel): New method to add noise to a
+ specified channel.
+ (blurChannel): New method to blur a specified channel.
+ (gaussianBlurChannel): New method to gaussian blur a specified
+ channel.
+ (motionBlur): New method to motion blur the image.
+ (randomThresholdChannel): New method to apply random thresholding
+ or ordered dithering to the image.
+ (randomThresholdChannel): New method to apply random thresholding
+ or ordered dithering to the specified image channels.
+ (sharpenChannel): New method to sharpen a specified image channel.
+ (unsharpmaskChannel): New method to unsharpmask a specified image
+ channel.
+
+2008-06-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (quantize): Error measurement support was being
+ performed incorrectly. SyncImage() is not needed here.
+
+2008-05-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - demo/demo.cpp (main): Fix segmentation parameters so they are
+ more suitable for our image.
+
+2008-04-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (depth): Remove 8/16/32 restriction on depth
+ value.
+
+2008-03-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Geometry.cpp, lib/Image.cpp: Include <strings.h> since it is
+ needed in order to use strcpy().
+
+2007-12-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/{Drawable.cpp, Geometry.cpp, BlobRef.cpp, Blob.cpp,
+ Montage.cpp, Options.cpp, Image.cpp}: Eliminate use of deprecated
+ GraphicsMagick functions.
+
+ - lib/Magick++/{STL.h, Include.h}: Eliminate use of deprecated
+ GraphicsMagick functions.
+
+2007-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp: Include <cstdlib>
+
+2006-10-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (pixelColor): Don't enforce color "validity" when
+ setting the pixel color.
+
+2005-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (orientation): New accessor method to support
+ image orientation.
+
+2005-04-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/STL.cpp (levelImage): New function object for leveling the
+ image channels.
+ (levelChannelImage): New function object for leveling a specific
+ image channel.
+
+ - lib/Image.cpp (level): New method for leveling the image
+ channels.
+ (levelChannel): New method for leveling a specific image channel.
+
+2005-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h (Magick): Import CineonLogRGBColorspace
+ into Magick namespace.
+
+2005-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: Import Rec601LumaColorspace (was called
+ GRAYColorspace) and Rec709LumaColorspace into Magick
+ namespace. Use of GRAYColorspace is mapped via a macro into
+ Rec601LumaColorspace in order to avoid a user-visible API change.
+
+2004-08-17 Volker Lukas <vlukas@gmx.de>
+
+ - lib/Drawable.cpp: Fixes to ensure that drawable objects remain
+ coherent even if an exception is thrown within the assignment
+ operator.
+
+2004-07-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us> <bfriesen@simple.dallas.tx.us>
+
+ - demo/Makefile.am (AUTOMAKE\_OPTIONS): Added nostdinc in order to
+ avoid accidentally using magick/list.h when including <list>.
+
+ - tests/Makefile.am (AUTOMAKE\_OPTIONS): Added nostdinc in order to
+ avoid accidentally using magick/list.h when including <list>.
+
+ - tests/readWriteBlob.cpp: If MISSING\_STD\_IOS\_BINARY is defined,
+ then ios::binary is not used. Use simple ifstream rather than
+ std::ifstream since we are already using the std namespace.
+
+2004-06-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: Disable unavoidable warnings under
+ Visual C++ when instantiating STL templates within DLL
+ code. Consensus from postings on the net is that as long as the
+ same C++ compiler is used throughout, these warnings are of no
+ concern.
+
+2004-05-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (coderInfoList): Make error reporting a bit
+ more lenient so that if an error occurs while loading a module it
+ is not reported as an exception unless no coders were found at
+ all.
+
+2004-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (clipMask): Use GetImageClipMask.
+
+2004-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/CoderInfo.cpp (CoderInfo): Sense of isReadable() and
+ isWritable() was inverted.
+
+2004-04-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: <inttypes.h> is not used. Inclusion
+ removed.
+
+2004-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Thread.cpp (lock): Have not been successful with using
+ MsgWaitForMultipleObjects() reliably, so back out usage of it for
+ now.
+
+2004-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Thread.cpp (lock): For MsgWaitForMultipleObjects, monitor
+ state change only. Otherwise lock may deadlock.
+
+2004-03-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (statistics): New method to obtain image
+ statistics (minimum, maximum, mean, variance, and standard
+ deviation).
+
+2004-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (quantumOperator): New image method to apply an
+ arithmetic or bitwise operator to the pixel quantums in an image.
+ Still needs documentation.
+ (quantumOperator): New image method to apply an arithmetic or
+ bitwise operator to the pixel quantums in an image region.
+
+2004-03-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Makefile.am (../www/Magick++/ChangeLog.html): Fix execution of
+ txt2html.
+
+ - lib/STL.cpp (composeImage): Added a function object to set/get
+ the Image composition option.
+
+ - lib/Image.cpp (compose): Added a method to set/get the Image
+ composition option.
+
+2004-03-06 Vladimir Lukianov <lvm@integrum.ru>
+
+ - lib/Thread.cpp (lock): Use MsgWaitForMultipleObjects() rather
+ than WaitForSingleObject() in order to avoid possible deadlock
+ when application code directly or indirectly creates windows.
+
+2004-02-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (interlaceType): Retrieve interlace setting from
+ Image rather than ImageInfo.
+
+2004-02-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (Image): Delete the allocated image reference
+ object if a Magick::Error is thrown by the Image constructor.
+ Otherwise the image reference object becomes a memory leak.
+
+2004-01-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (WriteImages): Pass Blob::MallocAllocator to
+ updateNoCopy() in order to ensure that correct deallocator is
+ used.
+
+ - tests/readWriteBlob.cpp (main): Needed to delete character array
+ using array [] reference.
+
+2004-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - demo/analyze.cpp (main): Fix a GNU C++ library portability
+ problem noticed under MinGW. The 'left' iostream manipulator seems
+ to be missing.
+
+2004-01-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am: coderInfo test is expected to fail for moby
+ builds when the package is not yet installed since a .la file
+ exists in the coders directory, but there is no associated .so
+ file. Therefore failures of the coderInfo test are now ignored.
+
+2003-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (defineValue): New method to support setting
+ format-specific defines.
+ (defineSet): New method to support setting or testing for
+ format-specific flags.
+
+2003-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (iccColorProfile): Implementation now uses the
+ profile method with profile name "ICM". Note that this now
+ invokes the color profile if the image already has one.
+ (iccColorProfile): Reimplement using new GetImageProfile function.
+ (iptcProfile): Reimplement using the new GetImageProfile and
+ SetImageProfile functions.
+ (profile): Reimplement using new GetImageProfile function.
+
+2003-12-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Makefile.am (pkglibdir): Improve header file
+ install location logic.
+
+2003-12-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - demo/analyze.cpp (main): New program to demonstrate using the
+ 'analyze' process module.
+
+ - demo/Makefile.am: Add rules to build analyze program.
+
+ - lib/Image.cpp (process): New method to execute process modules.
+
+ - lib/Image.cpp (attribute): New method to get and set named image
+ attributes.
+
+2003-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Color.cpp: Ensure that all non-default constructors set
+ opacity to opaque.
+
+2003-09-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (colorHistogram): If map key is not const,
+ then implicit type conversion occurs. Sun's C++ compiler doesn't
+ seem to handle that. The map key is now defined as const in the
+ insert arguments.
+
+2003-09-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/Makefile.am: Add build support for colorHistogram.cpp.
+
+ - tests/colorHistogram.cpp: New test program to test retrieving
+ color histograms from the image using colorHistogram().
+
+ - lib/Magick++/STL.h (colorHistogram): Added new template function
+ to retrieve a color histogram into a user-provided container.
+ Verified to work when using STL <vector> and <map> as the target
+ container types. When <map> is used, a user-specified color may
+ be used to perform lookups in the map to obtain the usage count
+ for that color.
+
+ - lib/Color.cpp (operator >=): Insufficient resolution was being
+ provided in order to reliably sort color objects in STL
+ containers. The updated algorithm should be fail-safe.
+
+2003-08-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (channelDepth): New method to set or get the
+ modulus depth for a specified channel.
+
+2003-08-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h (Magick): Added support for
+ CopyCyanCompositeOp, CopyMagentaCompositeOp,
+ CopyYellowCompositeOp, and CopyBlackCompositeOp, composition
+ operators.
+
+2003-08-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (depth): Method now only updates the
+ Image/ImageInfo depth member and retrieves the value of the Image
+ depth member.
+ (modulusDepth): New method to inspect the pixels for actual
+ modulus depth, or update/reduce the pixels to a specified modulus
+ depth. The depth method was performing this function so any code
+ which depended on the depth method to compute or set the modulus
+ depth should be updated to use modulusDepth() instead.
+
+2003-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (matte): If a new matte channel is created,
+ initialize it to opaque. Likewise, if the matte channel is
+ eliminated, initialize the unused channel to opaque.
+
+2003-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - demo/demo.cpp (main): Don't crop logo image.
+
+ - \*.h, \*.cpp: Include "Magick++/Include.h" before including any
+ compiler or system header in order to ensure that LFS defines are
+ properly applied. Inspired by patch from Albert Chin-A-Young.
+
+2003-06-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: Needed to import ThrowLoggedException.
+
+ - lib/Exception.cpp (throwException): Add originating source
+ module, source line, and function name (if available) to exception
+ report. This is useful in order to determine the exact conditions
+ that lead to the exception being thrown.
+
+ - lib/Magick++/Exception.h: Added ErrorCoder, WarningCoder,
+ ErrorConfigure, WarningConfigure, ErrorDraw, WarningDraw,
+ ErrorImage, WarningImage, ErrorMonitor, WarningMonitor,
+ ErrorRegistry, WarningRegistry, ErrorStream, WarningStream,
+ ErrorType, and WarningType, exception classes to support the full
+ set of exceptions that GraphicsMagick can throw.
+
+2003-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/CoderInfo.cpp (CoderInfo): Applied compilation fix from Mike
+ Chiarappa to compile using Borland C++.
+
+2003-06-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Geometry.cpp (string): Throw an exception if a string is
+ requested from an invalid geometry object.
+
+2003-06-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Geometry.cpp (operator =): If GetGeometry returns NoValue,
+ then assign an invalid geometry object to cause an exception if
+ the geometry is then used.
+
+2003-06-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Exception.h (ErrorModule): Added class to handle
+ module errors.
+
+ - lib/Magick++/Exception.h (WarningModule) Added class to handle
+ module warnings.
+
+2003-05-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (coderInfoList): Use GetMagickInfoArray to
+ access coder list.
+
+2003-05-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (affineTransformImage): Add function object
+ contributed by Vladimir Lukianov to apply an affine transform to
+ the image.
+
+ - lib/Image.cpp (affineTransform): Added method contributed by
+ Vladimir Lukianov to apply an affine transform to the image.
+
+2003-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: Decided to back out change which used
+ the \_VISUALC\_ define to trigger inclusion of <sys/types.h>.
+
+2003-05-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: If \_VISUALC\_ is defined, include
+ <sys/types.h>. This ensures that this necessary header is included
+ even if HAVE\_SYS\_TYPES\_H is not defined in magick\_config.h.
+
+2003-05-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (InitializeMagick): InitializeMagick is now a C++
+ function rather than a namespace inclusion. An atexit() handler
+ is registered to invoke DestroyMagick when the program
+ exits. Relying on static deconstruction to invoke DestroyMagick
+ proved to be unreliable due to translation unit destruction
+ uncertainty.
+
+2003-04-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (Image::Image (MagickLib::Image\* image\_)):
+ Incorporated recommended fix from Jukka Manner to avoid
+ a scenario which leaks an Options object.
+
+ - tests/coalesceImages.cpp: Updated to use modified
+ coalesceImages() interface.
+
+ - lib/Magick++/STL.h (coalesceImages): Replaced implementation
+ with one from Felix Heimbrecht. The template signature has changed
+ to return a new image sequence. This template API silently ceased
+ to funtion due to an ImageMagick CoalesceImages API change.
+
+2003-03-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/readWriteBlob.cpp (main): Added check for stream read
+ failure when reading blob data.
+ (class myBlob): Use get rather than read.
+
+2003-03-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/attributes.cpp : Change in the way that Magick++ retrieves
+ density caused tests to fail. Density now defaults to 72x72
+ (GraphicsMagick default) rather than invalid.
+
+2003-03-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - demo/Makefile.am (CLEANFILES): Fix clean target to
+ remove \*\_out.mvg output files as well.
+
+ - demo/zoom.cpp: Added a command-line parser for dash arguments as
+ well as an image "resample" capability.
+
+ - lib/Image.cpp (density): Obtain density from Image rather than
+ ImageInfo if the Image is valid.
+
+2003-03-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Makefile.am : Added rules to install GraphicsMagick++.pc.
+
+ - lib/GraphicsMagick++.pc.in : Added pkgconfig file for
+ -lGraphicsMagick++.
+
+2003-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (colorSpace): Pass image->colorspace to
+ TransformRGBColorspace.
+
+2003-01-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (writeImages): Should have been invoking
+ WriteImages rather than WriteImage!
+
+2003-01-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h: Add HSL and HWB colorspace
+ transformation support.
+
+2003-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (colorSpace): Support colorspace transforms other
+ than to and from RGB by translating to RGB as an intermediate
+ step.
+
+2002-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp: Added DrawablePushClipPath,
+ DrawablePopClipPath, and DrawableClipPath. Implementation
+ contributed by Vladimir <lvm@integrum.ru>.
+
+2002-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (colorMapSize): New method to set, or return the
+ colormap size.
+
+2002-11-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (adaptiveThreshold): New method.
+
+2002-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (coderInfoList): Intentionally ignore missing
+ delegate exceptions.
+
+2002-09-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Options.cpp (textEncoding): Had forgotten to implement
+ textEncoding!
+
+2002-09-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Color.cpp (Color): Use of 'new' and 'delete' in inlines was
+ causing memory allocation/deallocation problems for users of the
+ DLL build. Problem was identified by Marc Iwan.
+
+2002-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (compare): New method to compare current image
+ with a reference image.
+
+2002-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (textEncoding): New method to allow setting the
+ default text encoding (e.g. "UTF-8").
+
+ - lib/Drawable.cpp (DrawableText): Added an alternate constructor
+ to allow specifying the text encoding (e.g. "UTF-8").
+
+2002-08-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Overall: Now compiles as a DLL using Visual C++.
+
+2002-07-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (profile): Added method to store, delete, or
+ retrieve named application profiles.
+
+2002-07-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (type): Set the ImageInfo type attribute when
+ setting the image type. If the type attribute is set to something
+ other than UndefinedType (implying that the user has set a desired
+ output image type), then return that as the image type, otherwise
+ use GetImageType() to evaluate the image type.
+
+2002-05-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableTextUnderColor): New class to set the
+ text undercolor. When text undercolor is set, a rectangle of the
+ specified color is rendered under text annotations.
+
+2002-05-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Magick++ library no longer depends on iostreams at all.
+
+2002-04-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (throwImageException): ExceptionInfo was not being
+ properly initialized. This could cause some errors to cause an
+ abort in error.c rather than throwing an exception.
+
+2002-04-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (draw): Use draw.h drawing APIs to draw on image.
+ This means that MVG output no longer comes from code in
+ Drawable.cpp.
+
+2002-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/STL.cpp: Moved function object implementations from STL.h to
+ STL.cpp.
+
+2002-04-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (getConstPixels): Changed offset parameter type
+ from 'unsigned int' to 'int'.
+ (getPixels): Changed offset parameter type from 'unsigned int' to
+ 'int'.
+ (setPixels): Changed offset parameter type from 'unsigned int' to
+ 'int'.
+ (cacheThreshold): Changed argument type from 'const long' to
+ 'const int'.
+ (matteFloodfill): Changed offset parameter type from 'const long'
+ to 'const int'.
+
+ - lib/Pixels.cpp (getConst): New method to return read-only
+ pixels.
+ (get): Offset parameter types changed from 'unsigned int' to
+ 'int'.
+
+2002-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Drawable.h (DrawableDashOffset): Change dashoffset
+ type to 'double' rather than 'unsigned int' in order to match
+ ImageMagick.
+
+ - lib/Drawable.cpp (DrawableDashArray): Change dasharray type to
+ 'double' rather than 'unsigned int' in order to match
+ ImageMagick. Previous 'unsigned int' methods remain for
+ compatability reasons.
+
+2002-04-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableCompositeImage): Always output
+ composite images as inlined Base64.
+
+2002-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableCompositeImage): If magick attribute
+ string is specified, then composite image is supplied to
+ ImageMagick as inlined Base64 rather than by MPRI reference.
+
+ - lib/Blob.cpp (base64): Added methods to update Blob with data
+ from Base64-encoded string, or to return a Base64-encoded string
+ from Blob. Still needs documentation.
+
+2002-04-09 Dom Lachowicz <cinamod@hotmail.com>
+
+ - lib/Image.cpp (Image::ping): Added PingBlob function
+
+2002-04-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableDashArray::operator=): Added missing
+ assignment operator (fixes a bug).
+ (DrawableDashArray::DrawableDashArray): Added missing copy
+ constructor (fixes a bug).
+
+ - lib/Image.cpp (oilPaint): Changed argument type from unsigned
+ int to double.
+ (chromaBluePrimary): Changed argument type from float to double.
+ (chromaGreenPrimary): Changed argument type from float to double.
+ (chromaRedPrimary): Changed argument type from float to double.
+ (chromaWhitePoint): Changed argument type from float to double.
+ (getConstPixels): Changed argument type of x\_ & \_y from 'int' to
+ 'unsigned int'.
+ (getPixels): Changed argument type of x\_ & \_y from 'int' to
+ 'unsigned int'.
+
+2002-04-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (debug): Added method to set ImageMagick debug
+ flag so that it prints debugging information while it runs.
+
+2002-04-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp: Fixed a bunch of bugs related to
+ DrawableCompositeImage, DrawableFont, and inconsistencies
+ discovered by Gimpel lint.
+
+2002-04-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (draw): Properly delimit individual drawing
+ commands so that MVG output is correct.
+
+2002-03-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableViewbox): MVG syntax wasn't correct.
+
+ - lib/Image.cpp (draw): Fix algorithm used to append newlines to
+ MVG commands so that draw() may be invoked multiple times while
+ still producing valid MVG.
+
+2002-03-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableViewbox): New class to allow setting
+ the MVG output size.
+
+2002-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (print): Changed "mpr:" to "mpri:" in order to
+ finally get DrawableCompositeImage to work as intended.
+
+ - lib/Image.cpp (registerId): Bugfix. Register using
+ sizeof(MagickLib::Image) rather than sizeof(Image).
+
+2002-03-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableCompositeImage): Had failed to
+ initialize width and height in object to image width and height.
+
+2002-02-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (endianImage): New class to specify the
+ endian option for formats which support this notion (e.g. TIFF).
+
+ - lib/Image.cpp (endian): New method to specify the endian option
+ for formats which support this notion (e.g. TIFF).
+
+2002-02-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableFont): Support specifying a font via
+ font-family, font-style, font-weight, and font-stretch. Wildcard
+ matches are supported.
+
+2002-02-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (charcoal): Replace Magick++'s charcoal effect
+ with the output of ImageMagick's CharcoalImage function in order
+ to ensure consistency.
+
+ - lib/Magick++/CoderInfo.h (MatchType): Scope the MatchType
+ enumeration to the CoderInfo class so these enumeration names can
+ be re-used elsewhere without conflict. This results in a minor
+ API change to the coderInfoList() templated function since
+ enumerations must be specified like "CoderInfo::TrueMatch" rather
+ than just "TrueMatch". Hopefully not a problem since this
+ function and class were not documented outside of the headers
+ until this release.
+
+2002-02-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (coderInfoList): Finally wrote some
+ documentation.
+
+2002-01-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Options.cpp : Use DestroyImageList() rather than
+ DestroyImage().
+
+ - lib/Geometry.cpp (operator =): Use GetPageGeometry() rather than
+ PostscriptGeometry() to parse geometry specifications containing a
+ page size.
+
+2002-01-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - Remove bogus cast of blob data in readImages().
+
+2002-01-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (throwImageException): Throwing exceptions was
+ leaking memory.
+
+ - lib/Exception.cpp (throwException): Throwing exceptions was
+ leaking memory.
+
+ - lib/Image.cpp (replaceImage): Updated to properly handle
+ registration ids.
+ (modifyImage): Updated to properly handle registration ids.
+
+2002-01-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (Magick::DrawableGravity::print):
+ Bugfix. Remove "Gravity" from the end of each gravity
+ specification string. Reported as PR#1084 by stefan@dotify.com.
+
+2002-01-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp, Magick++/Include.h: Use DestroyImageList() rather
+ than DestroyImages().
+
+2002-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Options.h (antiAlias): Bugfix, set
+ drawInfo->text\_antialias to control text antialiasing.
+
+2002-01-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h : Imported new composition operators to
+ namespace: NoCompositeOp, DarkenCompositeOp, LightenCompositeOp,
+ HueCompositeOp, SaturateCompositeOp, ValueCompositeOp,
+ ColorizeCompositeOp, LuminizeCompositeOp, ScreenCompositeOp,
+ OverlayCompositeOp.
+
+2001-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (strokePattern): New method to specify image to
+ use as pattern while drawing stroked-outlines of drawn objects.
+ (fillPattern): New method to specify image to use as pattern while
+ filling drawn objects.
+ (penTexture): Method is officially deprecated. Don't use anymore.
+ (penColor): Method is officially deprecated. Don't use anymore.
+
+ - lib/Drawable.cpp (DrawablePushPattern): Support pushing
+ (starting) pattern definition.
+ (DrawablePopPattern): Support popping (terminating) pattern
+ definition.
+
+2001-12-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableCompositeImage): Read image
+ immediately if provided by filename, register with peristent
+ registry, and pass as perisistant image type.
+ (DrawableCompositeImage): Support specifying Image in memory.
+ Passed as perisistant image type.
+
+2001-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Color.cpp (operator std::string): Color string buffer was
+ one character too short!
+
+2001-12-20 Bob Friesenhahn <bfriesen@sun1107.ssd.usa.alcatel.com>
+
+ - lib/TypeMetric.cpp (characterWidth): Eliminate method.
+ (characterHeight): Eliminate method.
+ (all remaining methods): Change return type to 'double'. Fix
+ documentation in source files to reflect that units are in pixels
+ rather than points.
+ (descent): Renamed method from 'decent' to 'descent'.
+
+2001-11-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (Magick): Invoke DestroyMagick() to clean up
+ ImageMagick allocations.
+
+ - lib/Magick++/Include.h (ImageType): Added some missing enums to
+ Magick namespace.
+
+2001-11-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/CoderInfo.h (CoderInfo): Syntax fix.
+ ImageMagick bug #975.
+
+ - lib/Image.cpp (draw): Delete ostrstream data when it is no
+ longer needed. ImageMagick bug #988.
+
+2001-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (pixelColor): Implementation didn't handle pixels
+ indexes correctly. Now it does.
+
+2001-11-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (matteFloodfill): Coordinates are long values.
+ (floodFillOpacity): New method to floodfill opacity across pixels
+ matching color (within fuzz-factor) at point. Similar to
+ matteFloodfill except that color is selected from starting point.
+
+2001-10-29 Bob Friesenhahn <bfriesen@sun1107.ssd.usa.alcatel.com>
+
+ - lib/Image.cpp (strokeDashArray): Change to type double.
+ (strokeDashOffset): Change to type double.
+
+2001-10-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Geometry.cpp (Geometry): Add constructor from
+ MagickLib::RectangleInfo.
+
+ - lib/Image.cpp (boundingBox): Method to return smallest bounding
+ box enclosing non-border pixels.
+
+2001-10-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (getConstIndexes): Add method to obtain read-only
+ pixel indexes.
+ (getIndexes): Add method to obtain read-write pixel indexes.
+ (Image::Image): Send warnings from Image constructor to cerr
+ rather than throwing.
+
+ - lib/Color.cpp (Color(PixelPacket&)): Change argument to const
+ PixelPacket& as it should have been from the beginning.
+
+ - lib/Image.cpp (pixelColor): Reimplemented to be a const method.
+
+2001-10-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (getConstPixels): New method for returning a
+ read-only pixel view. Still requires documentation.
+
+ - lib/Magick++/STL.h (coderInfoList): Fixed compilation problem
+ when compiling with Visual C++.
+
+2001-10-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Color.h (scaleQuantumToDouble): Add polymorphic
+ version that accepts double to avoid downconversion error.
+
+2001-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Color.h (scaleQuantumToDouble): Cast Quantum to
+ double prior to division. Hopefully fix bug.
+
+2001-10-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Color.h (Color(const std::string)): Pass argument by reference.
+
+ - (operator=): Pass argument by const reference.
+
+2001-09-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (coderInfoList): New function to support
+ obtaining format coder information (as a list of type CoderInfo).
+
+ - lib/CoderInfo.cpp (CoderInfo): New class to support obtaining
+ format coder information.
+
+2001-09-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (depth): Use GetImageDepth and SetImageDepth
+ rather than just getting/setting depth attributes.
+
+ - lib/Magick++/STL.h (opacityImage): New unary function object to
+ set, or attenuate, image pixel opacity throughout the image.
+
+ - lib/Image.cpp (opacity): New method to set, or attenuate, image
+ pixel opacity throughout the image.
+
+ - lib/Magick++/STL.h (typeImage): New unary function object to set
+ image type.
+
+ - lib/Image.cpp (type): Added ability to set image type.
+
+2001-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (write(Blob)): Tell blob to use malloc allocator.
+
+ - lib/Blob.cpp (updateNoCopy): Added parameter so that user can
+ specify the allocation system (malloc or new) the memory came
+ from. Defaults to C++ memory allocator.
+
+2001-09-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (fileSize): Decided to change return type to off\_t
+ for increased range and portability.
+
+2001-09-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (fileSize): Changed return value to double.
+
+2001-09-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (colorMap): Allocate a colormap if it does not
+ already exist.
+
+ - lib/Pixels.cpp (indexes): Don't attempt to validate image type.
+
+ - lib/Image.cpp (colorMap): Optimized more for performance.
+
+2001-09-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (fontTypeMetrics): New method to support
+ retrieving font metrics.
+
+ - lib/TypeMetric.cpp : New class to support font metrics
+ information.
+
+2001-09-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Color.h (scaleDoubleToQuantum): Inline static
+ method made from previous ScaleDoubleToQuantum #define.
+ (scaleQuantumToDouble): Inline static method made from previous
+ ScaleQuantumToDouble #define. Helps avoid possibility of clash
+ with user code.
+
+2001-08-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (colorMap): Automatically extend colormap if
+ specified index is past end of current colormap. Colormap is
+ limited to a maximum depth of MaxRGB entries.
+
+2001-08-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (clipMask): New method to add a clip mask to the
+ image. Adds clipping to any image operation wherever the clip
+ mask image is tranparent.
+
+2001-08-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (print): Add single quotes around file names
+ and font specifications.
+
+2001-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (read): Ensure that only a single image frame is
+ read.
+
+2001-07-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (flattenImages): New function to flatten a
+ layered image.
+
+ - lib/Montage.cpp (Montage): Montage initial defaults are no
+ longer drawn from ImageInfo. MontageInfo structure is entirely
+ filled out by updateMontageInfo();
+
+2001-07-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Montage.cpp (updateMontageInfo): Bugfix; colors which were
+ intentionally specified as invalid (unset) were being ignored.
+ This produced unattractive label text when doing a montage.
+
+2001-07-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (medianFilterImage): Changed argument from
+ unsigned int to const double.
+ (fillColorImage): New method.
+ (strokeColorImage): New method.
+ (isValidImage): New method.
+
+ - lib/Magick++/Image.h (edge): Change argument from unsigned int
+ to double.
+ (medianFilter): Changed argument from unsigned int to const
+ double.
+
+ - lib/Magick++/STL.h (edgeImage): Change argument from unsigned
+ int to double.
+
+ - demo/demo.cpp (main): Updated to match PerlMagick demo.
+
+2001-06-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (shaveImage): New function to shave edges
+ from image.
+
+ - lib/Image.cpp (shave): New method to shave edges from image.
+
+2001-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (quantize): Remove conditions on whether
+ quantization should be done. Now quantization is always done.
+
+2001-06-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Image.h (blur,charcoal,emboss,sharpen): Changed
+ radius and sigma parameters to match current ImageMagick defaults.
+
+2001-02-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Options.cpp (updateDrawInfo): The updateDrawInfo() method
+ was no longer needed. Due to ImageMagick changes, calling it was
+ causing some options to be lost.
+
+2001-01-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (fillRule): New method to specify the rule to use
+ when filling drawn objects.
+
+2001-01-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (erase): New method to reset image to background
+ color.
+ (strokeAntiAlias): New method to control antialiasing of stroked
+ objects.
+
+2001-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (channel): Renamed method from 'layer' to match
+ equivalent change in ImageMagick (ChannelImage). Enumeration
+ names \*Layer renamed to \*Channel.
+
+2001-01-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Montage.h (strokeColor): New method.
+ (fillColor): New method.
+
+ - lib/Image.cpp (replaceImage): Revised logic so that an inValid
+ image should be returned if a NULL pointer is passed. Before this
+ change the existing image was preserved.
+ (label): Work-around ImageMagick SetImageAttribute bug.
+
+2001-01-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp : Adjusted to ImageMagick animation parameter API
+ change.
+
+2000-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableCompositeImage): Support specifying
+ composition rule.
+
+2000-12-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (draw): Bugfix - the primitive string was not
+ properly null terminated. It is a wonder that the code usually
+ worked at all. Thanks to afatela@marktest.pt for reporting it.
+
+2000-12-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (deconstructImages): New STL function for
+ deconstructing an image list to assist with creating an animation.
+ (mosaicImages): New STL function for inlaying an image list to
+ form a single coherent picture.
+
+2000-12-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (convolve): New method to convolve image using
+ user-supplied convolution matrix.
+ (unsharpmask): New method to replace image with a sharpened
+ version of the original image using the unsharp mask algorithm.
+
+2000-12-14 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - : Adapted to ImageMagick API change which eliminates
+ AnnotateInfo.
+
+2000-12-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (annotateImage): Brought into sync with
+ annotate methods in Image.
+
+2000-12-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (annotate): Usage of Geometry parameter was
+ incorrect. Geometry parameter is used to specify bounding
+ area. This changes the interpretation for two of the annotate
+ methods (which probably weren't usable before).
+
+2000-11-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Color.h (alphaQuantum): Bugfix. Due to change in
+ treatment of opacity member, alphaQuantum() was not allowing value
+ to be set.
+
+2000-11-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableFillRule): New class to specify fill
+ rule (see SVG's fill-rule).
+ (DrawableDashOffset): New class to specify initial offset in dash
+ array.
+ (DrawableDashArray): New class to specify a stroke dash pattern.
+ (DrawableStrokeLineCap): New class to specify the shape to be used
+ at the end of open subpaths when they are stroked.
+ (DrawableStrokeLineJoin): New class to specify the shape to be
+ used at the corners of paths (or other vector shapes) when they
+ are stroked.
+ (DrawableMiterLimit): New class to specify extension limit for
+ miter joins.
+
+2000-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (annotate): Reimplement text rotation using affine
+ member of AnnotateInfo.
+ (strokeDashOffset): New method for specifying the dash offset to
+ use for drawing vector objects. Similar to SVG stroke-dashoffset.
+ (strokeDashArray): New method for specifying the dash pattern to
+ use for drawing vector objects. Similar to SVG stroke-dasharray
+ (strokeLineCap): New method to specify the shape to be used at the
+ end of open subpaths when they are stroked. Similar to SVG
+ stroke-linecap.
+ (strokLineJoin): New method to specify the shape to be used at the
+ corners of paths (or other vector shapes) when they are
+ stroked. Similar to SVG stroke-linejoin.
+ (strokeMiterLimit): New method to specify the miter limit when
+ joining lines using MiterJoin. Similar to SVG stroke-miterlimit.
+ (strokeWidth): Renamed lineWidth method to strokeWidth.
+
+2000-10-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Drawable.h (DrawableCompositeImage): Add a
+ short-form constructor to support specifying image location and
+ name, but without specifying rendered size (use existing image
+ size).
+
+2000-10-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Drawable.h (DrawablePopGraphicContext): New class
+ to pop graphic context.
+ (DrawablePushGraphicContext): New class to push graphic context.
+
+ - lib/Drawable.cpp (DrawableStrokeAntialias): New class to set
+ stroke antialiasing.
+ (DrawableTextAntialias): New class to set text antialiasing.
+
+2000-10-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (transformOrigin): New method to set origin of
+ coordinate system for use when annotating with text or drawing
+ (transformRotation): New method to set rotation for use when
+ annotating with text or drawing
+ (transformScale): New method to set scale for use when annotating
+ with text or drawing.
+ (transformSkewX): New method to set skew for use in X axis when
+ annotating with text or drawing.
+ (transformSkewY): New method to set skew for use in Y axis when
+ annotating with text or drawing.
+ (transformReset): New method to reset transformation to default.
+
+ - lib/Drawable.cpp (DrawablePath): New class for drawing SVG-style
+ vector paths.
+ (PathArcArgs): New class. Argument for PathArcArgs & PathArcAbs.
+ (PathArcAbs): New class. Draw arc using absolute coordinates.
+ (PathArcRel): New class. Draw arc using relative coordinates.
+ (PathClosePath): New class. Close drawing path.
+ (PathCurvetoArgs): New class. Argument class for PathCurvetoAbs &
+ PathCurvetoRel.
+ (PathCurvetoAbs): New class. Cubic bezier, absolute coordinates
+ (PathCurvetoRel): New class. Cubic bezier, relative coordinates
+ (PathSmoothCurvetoAbs): New class. Cubic bezier, absolute
+ coordinates
+ (PathSmoothCurvetoRel): New class. Cubic bezier, relative
+ coordinates
+ (PathQuadraticCurvetoArgs): New class. Argument class for
+ PathQuadraticCurvetoAbs and PathQuadraticCurvetoRel.
+ (PathQuadraticCurvetoAbs): New class. Quadratic bezier, absolute
+ coordinates
+ (PathQuadraticCurvetoRel): New class. Quadratic bezier, relative
+ coordinates
+ (PathSmoothQuadraticCurvetoAbs): New class. Quadratic bezier,
+ absolute coordinates
+ (PathSmoothQuadraticCurvetoRel): New class. Quadratic bezier,
+ relative coordinates
+ (PathLinetoAbs): New class. Line to, absolute coordinates
+ (PathLinetoRel): New class. Line to, relative coordinates
+ (PathLinetoHorizontalAbs): New class. Horizontal lineto, absolute
+ coordinates
+ (PathLinetoHorizontalRel): New class. Horizontal lineto, relative
+ coordinates
+ (PathLinetoVerticalAbs): New class. Veritical lineto, absolute
+ coordinates.
+ (PathLinetoVerticalRel): New class. Vertical lineto, relative
+ coordinates.
+ (PathMovetoAbs): New class. Moveto, absolute coordinates
+ (PathMovetoRel): New class. Moveto, relative coordinates
+
+2000-10-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableSkewX): New object to apply skew in X
+ direction.
+ (DrawableSkewY): New object to apply skew in Y direction.
+
+2000-10-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (edge): Change argument from 'unsigned int' to
+ 'double' in order to match ImageMagick API.
+
+2000-10-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableCompositeImage): Renamed from
+ DrawableImage.
+ (DrawableTextDecoration): Renamed form DrawableDecoration.
+ (all-classes): Complete re-write to write the drawing command to a
+ stream when draw() is invoked rather than at object construction
+ time. This may be somewhat slower for individual draw operations
+ but but should be at least as fast for lists of drawing commands,
+ and is more flexible going into the future. Drawable classes now
+ inherit from DrawableBase but are passed into STL lists and Image
+ draw() methods via the surrogate class Drawable. The upshot of
+ all this is that the existing published API has not been altered
+ but things work much differently under the covers.
+
+2000-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableStrokeColor): Renamed from
+ DrawableStroke
+ (DrawableFillColor): Renamed from DrawableFill
+ (DrawableRotation): New class to influence object rotation.
+ (DrawableScaling): New class to influence object scaling.
+ (DrawableTranslation): New class to influence object translation.
+
+2000-10-04 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableAffine): New class to influence object
+ scaling, rotation, and translation (as defined by SVG XML).
+ (DrawableAngle): New class to influence drawing angle.
+ (DrawableDecoration): New class to influence text decoration such
+ as underline.
+ (DrawableFill): New class to set object filling color.
+ (DrawableFillOpacity): New class to set opacity to use when
+ filling object.
+ (DrawableFont::): New class to set font.
+ (DrawableGravity): New class to set text placement gravity.
+ (DrawablePointSize): New class to set font point size.
+ (DrawableStroke): New class to set drawing stroke color.
+ (DrawableStrokeOpacity): New class to set drawing stroke opacity.
+ (DrawableStrokeWidth): New class to set drawing stroke width.
+
+2000-10-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableImage): Added width and height
+ parameters to specify size to scale rendered image to. This is
+ actually a bug-fix since it seems that the correct drawing command
+ was no longer being generated.
+
+2000-09-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (read): New overloaded method to read an image
+ based on an array of raw pixels, of specified type and mapping, in
+ memory.
+ (write): New overloaded method to write image to an array of
+ pixels, of specified type and mapping.
+ (Image): New overloaded constructor to construct an image based on
+ an array of raw pixels, of specified type and mapping, in memory.
+
+2000-09-27 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (colorize): API change to match change in
+ ImageMagick. Now accepts percentage of red, green, and blue to
+ colorize with using specified pen color.
+
+2000-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Drawable.h: Reverted Coordinate implemenation back
+ from and STL pair based implementation to a simple class. Maybe
+ this will improve portability. It is more understandable anyway.
+
+2000-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Options.cpp : Bugfix. Some DrawInfo attributes were not
+ being updated. This lead to options like fontPointsize not
+ changing the font.
+
+2000-08-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (blurImage, charcoalImage, embossImage,
+ sharpenImage): Expand order\_ argument to radius\_ & sigma\_
+ arguments for more control (matches ImageMagick API change).
+
+ - lib/Image.cpp (blur, charcoal, emboss, sharpen): Expand order\_
+ argument to radius\_ & sigma\_ arguments for more control (matches
+ ImageMagick API change).
+
+2000-08-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (read): Check returned Image for embedded
+ exception, as well as the existing parameter check. This fixes
+ the bug that warnings are not reported.
+
+2000-07-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - test/\*.cpp demo/\*.cpp: Added call to MagickIncarnate() to set
+ ImageMagick install location for Windows. Hopefully this hack can
+ be removed someday.
+
+2000-07-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (colorFuzz): Changed type to 'double' from
+ 'unsigned int' to match change in ImageMagick.
+
+ - lib/Color.cpp (Color\*): Added copy constructor from base class.
+ (operator =): Added assignment operator from base class.
+
+2000-06-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h : Changed enumeration FilterType to
+ FilterTypes, and QuantumTypes to QuantumType in order to match
+ last-minute API change in ImageMagick.
+
+2000-06-22 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Pixels.cpp (indexes): Bugfix, use
+ GetCacheViewIndexes() rather than GetIndexes().
+
+2000-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Montage.h (gravity): Type of gravity\_ argument, and
+ return value changed from 'unsigned int' to GravityType.
+
+2000-04-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (DrawableArc, DrawableBezier, DrawablePolyline,
+ RoundRectangle): Added support for new drawing objects.
+
+2000-04-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp: Removed all public methods which accept
+ Coordinate arguments except those that accept lists of
+ Coordinates. Converted remaining drawable object methods into
+ individual classes which inherit from Drawable (e.g. "circle"
+ becomes "DrawableCircle"). The constructor for each class is
+ compatible with the original method. This results in annoying
+ changes to user code but provides more implementation flexibility.
+
+2000-04-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp
+ (fillEllipse,fillRectangle,fillCircle,fillPolygon): Removed
+ methods. Object filling is now based on whether fillColor or
+ penTexture are valid or not. This reflects ImageMagick internal
+ changes.
+
+ - lib/Image.cpp (fillColor): New method to specify fill color when
+ drawing objects.
+ (strokeColor): New method to specify outline color when drawing
+ objects.
+ (penColor): Setting penColor now sets fillColor and
+ strokeColor. Getting penColor retrieves the value of
+ strokeColor. This supports backwards compatability.
+
+2000-03-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (lineWidth): Type changed from unsigned int to
+ double.
+
+2000-03-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (Magick):
+
+2000-03-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h
+ (blurImage,charcoalImage,edgeImage,embossImage,
+ reduceNoiseImage,sharpenImage): Modified to support order of the
+ pixel neighborhood. Backward compatable function objects
+ constructors are provided for embossImage, and reduceNoiseImage.
+
+ - lib/Image.cpp (blur,charcoal,edge,emboss,reduceNoise,sharpen):
+ Now accept unsigned int argument which represents the order of the
+ pixel neighborhood (e.g. 3). This is not a backwards compatable
+ change, however, backward compatable methods are provided for
+ emboss, and reduceNoise.
+
+2000-03-02 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Pixels.h (Pixels): Moved Image pixel methods to
+ Pixels class.
+
+2000-02-29 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (annotate): Re-wrote to improve performance.
+ (draw): Re-wrote to improve performance.
+
+2000-02-26 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Drawable.cpp (text): Bugfix: support spaces in annotation
+ text.
+
+2000-02-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (gaussianBlurImage): New function object to
+ Gaussian blur image.
+
+ - lib/Image.cpp (gaussianBlur): New method to Gaussian blur image.
+
+2000-02-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp : Call-back based LastError class is eliminated in
+ favor of ImageMagick 5.2's re-entrant ExceptionInfo reporting.
+ This should make Magick++ thread safe under Win32.
+
+2000-02-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (floodFillTexture): Fixed bug due to pixel pointer
+ becoming invalid in ImageMagick function.
+
+2000-01-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp : Added locking to reference counting to ensure
+ thread (pthread) safety.
+
+ - lib/Blob.cpp : Added locking to reference counting to ensure
+ thread (pthread) safety.
+
+ - lib/LastError.cpp: Added support for thread specific data
+ (pthreads) so that error reporting is thread safe.
+
+ - lib/Magick++/Thread.h: Added thread wrapper class to provide
+ thread-safe locking (pthreads) to Magick++.
+
+2000-01-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp: Added methods getPixels, setPixels, syncPixels,
+ readPixels, and writePixels, in order to provide low-level access
+ to Image pixels. This approach (direct wrapper around ImageMagick
+ functions) does not mean that the planned object-oriented wrapper
+ has been forgotten, only that this wrapper is not ready yet, and
+ users need to manipulate pixels \*now\*.
+
+2000-01-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/LastError.cpp: Complete re-implementation of LastError so
+ that it hides its implementation. Also assures that all memory is
+ explicitly deallocated at program exit to avoid the appearance of
+ a leak.
+
+2000-01-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (size): Bug-fix. Set image columns and rows as
+ well as image options columns and rows.
+
+ - lib/Image.cpp :Depth parameters are now all unsigned in for
+ consistency.
+
+ - lib/Image.cpp (write): Parameters for writing Blobs re-arranged
+ again to hopefully be more sensible.
+
+ - lib/Magick++/STL.h: Bug-fix. Re-number scenes from zero when
+ linking image range in container into a list. This provides
+ expected results.
+
+1999-12-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp
+ (write): Additional overloaded methods for BLOBs.
+ (read): Additional overloaded methods for BLOBs. Re-ordered
+ parameters for one existing method.
+ (Image): Additional overloaded methods for BLOBs. Re-ordered
+ parameters for one existing method.
+
+1999-12-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (floodFillTexture): Changed coordinates to
+ unsigned.
+
+1999-12-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (medianFilter): New method.
+
+1999-12-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (density): Bug fix. Was not setting image x & y
+ density.
+
+1999-11-30 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (page): psPageSize() is renamed to page() and now
+ properly returns the attribute from the image.
+
+1999-11-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp: Rename transformColorSpace() to colorSpace().
+ Added colorSpace() accessor method.
+
+1999-11-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Color.cpp: Re-implemented PixelPacket pointer so that it is
+ never NULL and added a 'valid' field for tracking object validity.
+
+1999-11-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (quantizeError): Eliminated method.
+
+1999-11-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (annotate & draw): Changed implementation to
+ reflect change to the way AnnotateInfo is managed by ImageMagick.
+
+1999-11-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (cacheThreshold): New method to set the pixel
+ cache threshold.
+
+ - lib/Magick++/Include.h (Magick): Added new enumerations from
+ classify.h.
+
+1999-10-28 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Options.h (fontPointsize): Argument is now a double
+ to match change in ImageMagick.
+
+ - lib/Image.cpp (fontPointsize): Argument is now a double to match
+ change in ImageMagick.
+
+1999-10-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Blob.cpp (BlobRef): Bugfix -- start blob reference count at
+ one rather than zero.
+
+1999-10-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (Image): Fixed Image constructors from Blob. The
+ image reference was not being instantiated as it should have been,
+ causing a crash.
+
+1999-10-05 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Blob.cpp: All blob length parameters are now of type size\_t.
+
+ - lib/Image.cpp (write): Length estimate is now of type size\_t.
+
+1999-09-20 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (rotate): No longer accepts a crop option since
+ ImageMagick no longer supports this.
+ (shear): No longer accepts a crop option since ImageMagick no
+ longer supports this.
+
+1999-09-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp:
+ (rotate): No longer accepts sharpen argument. User must sharpen
+ seperately if desired. This change is due to a similar change in
+ ImageMagick 5.0.
+ (condense): Removed method.
+ (uncondense): Removed method.
+ (condensed): Removed method.
+ (pixelColor): Adapted to 5.0.
+
+ - lib/Magick++/Color.h : Rewrote to efficiently use ImageMagick
+ 5.0's PixelPacket color representation.
+
+ - lib/Color.cpp : Rewrote to efficiently use ImageMagick 5.0's
+ PixelPacket color representation.
+
+1999-09-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (condensed): Bug fix. The condensed() method was
+ returning the opposite bool value than it should. Oops!
+
+1999-09-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Include.h (MagickLib): Eliminated requirement for
+ including <magick/define.h>.
+
+1999-08-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp: Added accessor methods for other key ImageMagick
+ structs.
+
+ - lib/Options.cpp (penTexture): Fixed bug with removing texture
+ caused by change in Image constructor.
+
+ - lib/Image.cpp: Changed strategy such that an Image containing a
+ null MagickLib::Image pointer is never constructed except for
+ under error conditions. Removed existing checks for null image
+ pointer on attribute methods.
+ Use image() and constImage() accessor methods as part of Image
+ implementation in order to clean-up code and ensure
+ const-correctness.
+
+1999-08-03 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/STL.h (Magick): Added STL function readImages().
+ Not tested yet.
+ (Magick): Added STL function writeImages(). Not tested yet.
+
+ - lib/Image.cpp: Removed support for 'text' attribute as this is
+ no longer present in ImageMagick as of 4.2.8.
+
+1999-07-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Image.cpp (condense): Skip condensing image if already
+ condensed.
+ (uncondense): Skip uncondensing image if not condensed.
+ (condensed): New method to test if image is condensed.
+ (classType): New method which supports conversion of the image
+ storage class. May result in loss of color information
+ (quantization is used) if a DirectClass image is converted to
+ PseudoClass.
+
+1999-07-18 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Magick++/Color.h (Magick::Color): Color parameters are now
+ stored in a MagickLib::RunlengthPacket structure which is
+ referenced via a pointer. This structure is either allocated by a
+ Magick::Color constructor or passed as an argument to a
+ Magick::Color constructor so that it may refer to to a
+ MagickLib::Image pixel. The owner of the structure is managed so
+ that the structure is only deleted if it was allocated by
+ Magick::Color.
+
+1999-07-09 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - overall : Removed 'Magick' prefix from all source file
+ names. Moved class headers to Magick++ subdirectory. This should
+ not break any code using the documented interface (via
+ Magick++.h).
+
+1999-07-08 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickImage.cpp (composite): Support composition placement
+ by gravity like PerlMagick does.
+
+1999-07-07 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickImage.cpp (Image): Added constructors to construct an
+ Image from a BLOB.
+
+1999-07-06 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/manipulate.cpp (main): Wrote a basic sanity test for
+ reading and writing BLOBS.
+
+1999-06-21 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickImage.cpp (read): Added support for reading an encoded
+ image stored in a BLOB. Uses new ImageMagick APIs introduced on
+ July 21, 1999.
+ (write): Added support for writing an encoded image to a BLOB.
+
+1999-06-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickInclude.h : Use new <magick/api.h> interface to
+ ImageMagick to avoid namespace-induced problems.
+
+ - configure.in : CPPFLAGS and LDFLAGS specified via the
+ environment take precidence over flags from Magick-config.
+
+1999-05-31 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickSTL.h (mapImages): New algorithm to map the sequence
+ of images to the color map of a provided image.
+ (quantizeImages): New algorithm to quantize a sequence of images
+ to a common color map.
+
+1999-05-24 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickBlob.cpp (updateNoCopy): New method to allow derived
+ classes to insert data into the base class without making a copy
+ of the data. This represents a transfer of ownership of the data
+ from the derived class to the base class.
+
+1999-05-23 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickColor.cpp (operator =): Adapted to new ImageMagick
+ 4.2.6 as of 5/23/99 which removes X11 compatability functions.
+
+ - lib/MagickGeometry.cpp (operator =): Adapted to new ImageMagick
+ 4.2.6 as of 5/23/99 which removes X11 compatability functions.
+
+1999-05-17 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickBlob.cpp (Blob): Support default constructor for Blob.
+
+1999-05-16 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickSTL.h (transformColorSpaceImage): New unary function
+ object to invoke transformColorSpace on STL container object.
+
+ - lib/MagickImage.cpp (transformColorSpace): New method to
+ transform the image data to a new colorspace.
+
+1999-05-15 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickImage.cpp (ping): Re-implemented to match (requested)
+ API change in ImageMagick 4.2.5. Method signature has changed to
+ be like 'read'.
+ (annotate): Added two new overloaded methods for text annotation
+ in order to support the new rotated text capability in ImageMagick
+ 4.2.5. To accomplish this, the default for gravity had to be
+ removed from several methods. This may impact existing code.
+ Still not sure if this is the best set of method signatures.
+
+1999-05-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickImage.cpp (ping): New method to obtain image size in
+ bytes and geometry without the overhead of reading the complete
+ image.
+ (uncondense): New method to uncompress run-length encoded pixels
+ into a simple array to make them easy to operate on.
+
+1999-05-12 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickImage.cpp (comment): Passing an empty string as the
+ comment results in no comment at all rather than a comment with no
+ data.
+
+1999-05-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickImage.cpp (iccColorProfile): Implemented method to set
+ ICC color profile from opaque object in memory (must be formatted
+ outside of Magick++).
+ (iptcProfile): Implemented method to set IPTC profile from opaque
+ object in memory (must be formatted outside of Magick++).
+
+ - lib/MagickBlob.cpp: New class to support managing user-supplied
+ opaque Binary Large OBjects (BLOBS) in the API. Reference counted
+ to improve semantics and to possibly reduce memory consumption.
+
+1999-05-01 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/Makefile.am (libMagick): Updated to use libtool 1.3 so that
+ shared library can be built.
+
+1999-04-25 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickImage.cpp (montageGeometry): Return Magick::Geometry
+ rather than std::string.
+
+1999-04-19 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickColor.cpp (alpha): Added support for setting alpha via
+ scaled-double to the Color class. The new method name is 'alpha'.
+
+1999-04-13 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - lib/MagickColor.cpp: Added support for setting an alpha value
+ (unscaled Quantum only) for use on DirectColor images that have
+ matte enabled. This requires ImageMagick 4.2.2 dated April 13,
+ 1999 or later to compile since Cristy added a special flag to
+ allow testing to see if the user has specified an opacity value:
+ "I added XColorFlags to magick/classify.h. If DoMatte is set in
+ color->flags then the opacity value is valid in color->pixel."
+
+1999-04-11 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - demo/flip.cpp (main): New file. Demonstrates use of flipImage
+ function object as well as morphImages algorithm.
+
+1999-04-10 Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
+
+ - tests/color.cpp : New file to support testing the Magick::Color
+ classes.
+
+ - lib/MagickOptions.cpp: The ImageInfo filter member is now
+ ignored by ImageMagick (as of ImageMagick 4.2.2 April 10, 1998) so
+ support for setting it is removed. The Image filter member is
+ still updated. According to Cristy, this ImageMagick version
+ removes automatic sharpening of resized images. The blur member
+ is added to the Image structure. A blur value < 1 causes the image
+ to be sharpened when resizing while a value > 1 leaves the image
+ blurry. Magick++ does not yet support the blur member.
+
+
diff --git a/www/Magick++/CoderInfo.html b/www/Magick++/CoderInfo.html
new file mode 100644
index 0000000..8c4e34b
--- /dev/null
+++ b/www/Magick++/CoderInfo.html
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::CoderInfo Class</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-coderinfo-class">
+<h1 class="title">Magick::CoderInfo Class</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The CoderInfo class supports obtaining information about
+GraphicsMagick support for an image format (designated by a magick
+string). It may be used to provide support for a specific named format
+(provided as an argument to the constructor), or as an element of a
+container when format support is queried using the coderInfoList()
+templated function.</p>
+<p>The following code fragment illustrates how CoderInfo may be used:</p>
+<pre class="literal-block">
+CoderInfo info(&quot;GIF&quot;);
+cout &lt;&lt; info-&gt;name() &lt;&lt; &quot;: (&quot; &lt;&lt; info-&gt;description() &lt;&lt; &quot;) : &quot;;
+cout &lt;&lt; &quot;Readable = &quot;;
+if ( info-&gt;isReadable() )
+ cout &lt;&lt; &quot;true&quot;;
+else
+ cout &lt;&lt; &quot;false&quot;;
+cout &lt;&lt; &quot;, &quot;;
+cout &lt;&lt; &quot;Writable = &quot;;
+if ( info-&gt;isWritable() )
+ cout &lt;&lt; &quot;true&quot;;
+else
+ cout &lt;&lt; &quot;false&quot;;
+cout &lt;&lt; &quot;, &quot;;
+cout &lt;&lt; &quot;Multiframe = &quot;;
+if ( info-&gt;isMultiframe() )
+ cout &lt;&lt; &quot;true&quot;;
+else
+ cout &lt;&lt; &quot;false&quot;;
+cout &lt;&lt; endl;
+</pre>
+<p>The definition of class 'Magick::CoderInfo' is:</p>
+<pre class="literal-block">
+namespace Magick
+{
+ class MagickDLLDecl CoderInfo
+ {
+ public:
+
+ enum MatchType {
+ AnyMatch, // match any coder
+ TrueMatch, // match coder if true
+ FalseMatch // match coder if false
+ };
+
+ // Default constructor
+ CoderInfo ( void );
+
+ // Copy constructor
+ CoderInfo ( const CoderInfo &amp;coder_ );
+
+ // Construct with coder name
+ CoderInfo ( const std::string &amp;name_ );
+
+ // Destructor
+ ~CoderInfo ( void );
+
+ // Format name
+ std::string name( void ) const;
+
+ // Format description
+ std::string description( void ) const;
+
+ // Format is readable
+ bool isReadable( void ) const;
+
+ // Format is writeable
+ bool isWritable( void ) const;
+
+ // Format supports multiple frames
+ bool isMultiFrame( void ) const;
+
+ // Assignment operator
+ CoderInfo&amp; operator= (const CoderInfo &amp;coder_ );
+
+ };
+}
+</pre>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/CoderInfo.rst b/www/Magick++/CoderInfo.rst
new file mode 100644
index 0000000..7e10ce8
--- /dev/null
+++ b/www/Magick++/CoderInfo.rst
@@ -0,0 +1,89 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=======================
+Magick::CoderInfo Class
+=======================
+
+The CoderInfo class supports obtaining information about
+GraphicsMagick support for an image format (designated by a magick
+string). It may be used to provide support for a specific named format
+(provided as an argument to the constructor), or as an element of a
+container when format support is queried using the coderInfoList()
+templated function.
+
+The following code fragment illustrates how CoderInfo may be used::
+
+ CoderInfo info("GIF");
+ cout << info->name() << ": (" << info->description() << ") : ";
+ cout << "Readable = ";
+ if ( info->isReadable() )
+ cout << "true";
+ else
+ cout << "false";
+ cout << ", ";
+ cout << "Writable = ";
+ if ( info->isWritable() )
+ cout << "true";
+ else
+ cout << "false";
+ cout << ", ";
+ cout << "Multiframe = ";
+ if ( info->isMultiframe() )
+ cout << "true";
+ else
+ cout << "false";
+ cout << endl;
+
+The definition of class 'Magick::CoderInfo' is::
+
+ namespace Magick
+ {
+ class MagickDLLDecl CoderInfo
+ {
+ public:
+
+ enum MatchType {
+ AnyMatch, // match any coder
+ TrueMatch, // match coder if true
+ FalseMatch // match coder if false
+ };
+
+ // Default constructor
+ CoderInfo ( void );
+
+ // Copy constructor
+ CoderInfo ( const CoderInfo &coder_ );
+
+ // Construct with coder name
+ CoderInfo ( const std::string &name_ );
+
+ // Destructor
+ ~CoderInfo ( void );
+
+ // Format name
+ std::string name( void ) const;
+
+ // Format description
+ std::string description( void ) const;
+
+ // Format is readable
+ bool isReadable( void ) const;
+
+ // Format is writeable
+ bool isWritable( void ) const;
+
+ // Format supports multiple frames
+ bool isMultiFrame( void ) const;
+
+ // Assignment operator
+ CoderInfo& operator= (const CoderInfo &coder_ );
+
+ };
+ }
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/Color.html b/www/Magick++/Color.html
new file mode 100644
index 0000000..16c308a
--- /dev/null
+++ b/www/Magick++/Color.html
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Color Class</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-color-class">
+<h1 class="title">Magick::Color Class</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>Color is the base color class in Magick++. It is a simple container
+class for the pixel red, green, blue, and alpha values scaled to fit
+GraphicsMagick's Quantum (number of bits in a color component value)
+size. Normally users will instantiate a class derived from Color which
+supports the color model that fits the needs of the application. The
+Color class may be constructed directly from an X11-style color
+string. As a perhaps odd design decision, the value transparent black
+is considered to represent an unset value (invalid color) in many
+cases. This choice was made since it avoided using more memory. The
+default Color constructor constructs an invalid color
+(i.e. transparent black) and may be used as a parameter in order to
+remove a color setting.</p>
+<div class="section" id="quantum">
+<h1>Quantum</h1>
+<p>The base type used to represent color samples in GraphicsMagick is the
+Quantum type. Pixels are represented by a structure of Quantum
+values. For example, an RGB pixel contains red, green, and blue
+quantums, while an RGBA pixel contains red, green, blue, and opacity
+quantums. The maximum value that a Quantum can attain is specified by
+a constant value represented by the MaxRGB define, which is itself
+determined by the number of bits in a Quantum. The QuantumDepth build
+option determines the number of bits in a Quantum.</p>
+</div>
+<div class="section" id="pixelpacket">
+<h1>PixelPacket</h1>
+<p>PixelPacket is the internal representation of a pixel in
+GraphicsMagick. GraphicsMagick may be compiled to support 32, 64, or
+128 bit pixels of type PixelPacket. This is controlled by the value of
+the QuantumDepth define. The default is 32 bit pixels
+(QuantumDepth=8), which provides the best performance and the least
+resource consumption. If additional color precision or range is
+desired, then GraphicsMagick may be compiled with QuantumDepth=16 or
+QuantumDepth=32. The following table shows the relationship between
+QuantumDepth, the type of Quantum, and the overall PixelPacket size:</p>
+<table border="1" class="docutils">
+<caption>Effect Of QuantumDepth Values</caption>
+<colgroup>
+<col width="28%" />
+<col width="35%" />
+<col width="37%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">QuantumDepth</th>
+<th class="head">Quantum Typedef</th>
+<th class="head">PixelPacket Size</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>8</td>
+<td>unsigned char</td>
+<td>32 bits</td>
+</tr>
+<tr><td>16</td>
+<td>unsigned short</td>
+<td>64 bits</td>
+</tr>
+<tr><td>32</td>
+<td>unsigned int</td>
+<td>128 bits</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="color-class">
+<h1>Color Class</h1>
+<p>The Color base class is not intended to be used directly. Normally a
+user will construct a derived class or inherit from this class. Color
+arguments are must be scaled to fit the Quantum size according to the
+range of MaxRGB. The Color class contains a pointer to a PixelPacket,
+which may be allocated by the Color class, or may refer to an existing
+pixel in an image.</p>
+<p>An alternate way to construct the class is via an X11-compatible color
+specification string (e.g. Color(“red”) or Color (“#FF0000”)). Since
+the class may be constructed from a string, convenient strings may be
+passed in place of an explicit Color object in methods which accept a
+reference to Color. Color may also be converted to a std::string for
+convenience in user interfaces, and for saving settings to a text
+file.</p>
+<p>The following is the definition of the Color class:</p>
+<pre class="literal-block">
+// Compare two Color objects regardless of LHS/RHS
+int MagickDLLDecl operator == ( const Magick::Color&amp; left_, const Magick::Color&amp; right_ );
+int MagickDLLDecl operator != ( const Magick::Color&amp; left_, const Magick::Color&amp; right_ );
+int MagickDLLDecl operator &gt; ( const Magick::Color&amp; left_, const Magick::Color&amp; right_ );
+int MagickDLLDecl operator &lt; ( const Magick::Color&amp; left_, const Magick::Color&amp; right_ );
+int MagickDLLDecl operator &gt;= ( const Magick::Color&amp; left_, const Magick::Color&amp; right_ );
+int MagickDLLDecl operator &lt;= ( const Magick::Color&amp; left_, const Magick::Color&amp; right_ );
+
+// Base color class stores RGB components scaled to fit Quantum
+class MagickDLLDecl Color
+{
+public:
+ Color ( Quantum red_,
+ Quantum green_,
+ Quantum blue_ );
+ Color ( Quantum red_,
+ Quantum green_,
+ Quantum blue_,
+ Quantum alpha_ );
+ Color ( const std::string &amp;x11color_ );
+ Color ( const char * x11color_ );
+ Color ( void );
+ virtual ~Color ( void );
+ Color ( const Color &amp; color_ );
+
+ // Red color (range 0 to MaxRGB)
+ void redQuantum ( Quantum red_ );
+ Quantum redQuantum ( void ) const;
+
+ // Green color (range 0 to MaxRGB)
+ void greenQuantum ( Quantum green_ );
+ Quantum greenQuantum ( void ) const;
+
+ // Blue color (range 0 to MaxRGB)
+ void blueQuantum ( Quantum blue_ );
+ Quantum blueQuantum ( void ) const;
+
+ // Alpha level (range OpaqueOpacity=0 to TransparentOpacity=MaxRGB)
+ void alphaQuantum ( Quantum alpha_ );
+ Quantum alphaQuantum ( void ) const;
+
+ // Scaled (to 1.0) version of alpha for use in sub-classes
+ // (range opaque=0 to transparent=1.0)
+ void alpha ( double alpha_ );
+ double alpha ( void ) const;
+
+ // Does object contain valid color?
+ void isValid ( bool valid_ );
+ bool isValid ( void ) const;
+
+ // Set color via X11 color specification string
+ const Color&amp; operator= ( const std::string &amp;x11color_ );
+ const Color&amp; operator= ( const char * x11color_ );
+
+ // Assignment operator
+ Color&amp; operator= ( const Color&amp; color_ );
+
+ // Return X11 color specification string
+ /* virtual */ operator std::string() const;
+
+ // Return ImageMagick PixelPacket
+ operator PixelPacket() const;
+
+ // Construct color via ImageMagick PixelPacket
+ Color ( const PixelPacket &amp;color_ );
+
+ // Set color via ImageMagick PixelPacket
+ const Color&amp; operator= ( const PixelPacket &amp;color_ );
+
+};
+</pre>
+</div>
+<div class="section" id="color-derived-classes">
+<h1>Color Derived Classes</h1>
+<p>Available derived color specification classes are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>Color Derived Classes</caption>
+<colgroup>
+<col width="14%" />
+<col width="86%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Class</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td><a class="reference internal" href="#colorrgb">ColorRGB</a></td>
+<td>Representation of RGB color with red, green, and blue specified
+as ratios (0 to 1)</td>
+</tr>
+<tr><td><a class="reference internal" href="#colorgray">ColorGray</a></td>
+<td>Representation of grayscale RGB color (equal parts red, green,
+and blue) specified as a ratio (0 to 1)</td>
+</tr>
+<tr><td><a class="reference internal" href="#colormono">ColorMono</a></td>
+<td>Representation of a black/white color (true/false)</td>
+</tr>
+<tr><td><a class="reference internal" href="#colorhsl">ColorHSL</a></td>
+<td>Representation of a color in Hue/Saturation/Luminosity (HSL)
+colorspace</td>
+</tr>
+<tr><td><a class="reference internal" href="#coloryuv">ColorYUV</a></td>
+<td>Representation of a color in the YUV colorspace</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="colorrgb">
+<h1>ColorRGB</h1>
+<p>Representation of an RGB color in floating point. All color arguments
+have a valid range of 0.0 - 1.0. Note that floating point alpha may be
+set via the alpha() method in the Color base class:</p>
+<pre class="literal-block">
+class ColorRGB : public Color
+{
+public:
+ ColorRGB ( double red_, double green_, double blue_ );
+ ColorRGB ( void );
+ ColorRGB ( const Color &amp; color_ );
+ /* virtual */ ~ColorRGB ( void );
+
+ void red ( double red_ );
+ double red ( void ) const;
+
+ void green ( double green_ );
+ double green ( void ) const;
+
+ void blue ( double blue_ );
+ double blue ( void ) const;
+
+ // Assignment operator from base class
+ ColorRGB&amp; operator= ( const Color&amp; color_ );
+
+protected:
+ // Constructor to construct with PixelPacket*
+ ColorRGB ( PixelPacket* rep_, PixelType pixelType_ );
+};
+</pre>
+</div>
+<div class="section" id="colorgray">
+<h1>ColorGray</h1>
+<p>Representation of a floating point grayscale color (in RGB
+colorspace). Grayscale is simply RGB with equal parts of red, green,
+and blue. All double arguments have a valid range of 0.0 - 1.0:</p>
+<pre class="literal-block">
+class ColorGray : public Color
+{
+public:
+ ColorGray ( double shade_ );
+ ColorGray ( void );
+ ColorGray ( const Color &amp; color_ );
+ /* virtual */ ~ColorGray ();
+
+ void shade ( double shade_ );
+ double shade ( void ) const;
+
+ // Assignment operator from base class
+ ColorGray&amp; operator= ( const Color&amp; color_ );
+
+};
+</pre>
+</div>
+<div class="section" id="colormono">
+<h1>ColorMono</h1>
+<p>Representation of a black/white pixel (in RGB colorspace). Color
+arguments are constrained to 'false' (black pixel) and 'true' (white
+pixel):</p>
+<pre class="literal-block">
+class ColorMono : public Color
+{
+public:
+ ColorMono ( bool mono_ );
+ ColorMono ( void );
+ ColorMono ( const Color &amp; color_ );
+ /* virtual */ ~ColorMono ();
+
+ void mono ( bool mono_ );
+ bool mono ( void ) const;
+
+ // Assignment operator from base class
+ ColorMono&amp; operator= ( const Color&amp; color_ );
+
+};
+</pre>
+</div>
+<div class="section" id="colorhsl">
+<h1>ColorHSL</h1>
+<p>Representation of a color in Hue/Saturation/Luminosity (HSL) colorspace:</p>
+<pre class="literal-block">
+class MagickDLLDecl ColorHSL : public Color
+{
+public:
+ ColorHSL ( double hue_, double saturation_, double luminosity_ );
+ ColorHSL ( void );
+ ColorHSL ( const Color &amp; color_ );
+ /* virtual */ ~ColorHSL ( );
+
+ void hue ( double hue_ );
+ double hue ( void ) const;
+
+ void saturation ( double saturation_ );
+ double saturation ( void ) const;
+
+ void luminosity ( double luminosity_ );
+ double luminosity ( void ) const;
+
+ // Assignment operator from base class
+ ColorHSL&amp; operator= ( const Color&amp; color_ );
+
+};
+</pre>
+</div>
+<div class="section" id="coloryuv">
+<h1>ColorYUV</h1>
+<p>Representation of a color in YUV colorspace (used to encode color for
+television transmission). Argument ranges are</p>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="11%" />
+<col width="89%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Y</td>
+<td>0.0 through 1.0</td>
+</tr>
+<tr><td>U</td>
+<td>-0.5 through 0.5</td>
+</tr>
+<tr><td>V</td>
+<td>-0.5 through 0.5</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<pre class="literal-block">
+class ColorYUV : public Color
+{
+public:
+ ColorYUV ( double y_, double u_, double v_ );
+ ColorYUV ( void );
+ ColorYUV ( const Color &amp; color_ );
+ /* virtual */ ~ColorYUV ( void );
+
+ void u ( double u_ );
+ double u ( void ) const;
+
+ void v ( double v_ );
+ double v ( void ) const;
+
+ void y ( double y_ );
+ double y ( void ) const;
+
+ // Assignment operator from base class
+ ColorYUV&amp; operator= ( const Color&amp; color_ );
+
+};
+</pre>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Color.rst b/www/Magick++/Color.rst
new file mode 100644
index 0000000..b4bb445
--- /dev/null
+++ b/www/Magick++/Color.rst
@@ -0,0 +1,317 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+===================
+Magick::Color Class
+===================
+
+Color is the base color class in Magick++. It is a simple container
+class for the pixel red, green, blue, and alpha values scaled to fit
+GraphicsMagick's Quantum (number of bits in a color component value)
+size. Normally users will instantiate a class derived from Color which
+supports the color model that fits the needs of the application. The
+Color class may be constructed directly from an X11-style color
+string. As a perhaps odd design decision, the value transparent black
+is considered to represent an unset value (invalid color) in many
+cases. This choice was made since it avoided using more memory. The
+default Color constructor constructs an invalid color
+(i.e. transparent black) and may be used as a parameter in order to
+remove a color setting.
+
+Quantum
+-------
+
+The base type used to represent color samples in GraphicsMagick is the
+Quantum type. Pixels are represented by a structure of Quantum
+values. For example, an RGB pixel contains red, green, and blue
+quantums, while an RGBA pixel contains red, green, blue, and opacity
+quantums. The maximum value that a Quantum can attain is specified by
+a constant value represented by the MaxRGB define, which is itself
+determined by the number of bits in a Quantum. The QuantumDepth build
+option determines the number of bits in a Quantum.
+
+PixelPacket
+-----------
+
+PixelPacket is the internal representation of a pixel in
+GraphicsMagick. GraphicsMagick may be compiled to support 32, 64, or
+128 bit pixels of type PixelPacket. This is controlled by the value of
+the QuantumDepth define. The default is 32 bit pixels
+(QuantumDepth=8), which provides the best performance and the least
+resource consumption. If additional color precision or range is
+desired, then GraphicsMagick may be compiled with QuantumDepth=16 or
+QuantumDepth=32. The following table shows the relationship between
+QuantumDepth, the type of Quantum, and the overall PixelPacket size:
+
+.. table:: Effect Of QuantumDepth Values
+
+ ============ =============== ================
+ QuantumDepth Quantum Typedef PixelPacket Size
+ ============ =============== ================
+ 8 unsigned char 32 bits
+ 16 unsigned short 64 bits
+ 32 unsigned int 128 bits
+ ============ =============== ================
+
+Color Class
+-----------
+
+The Color base class is not intended to be used directly. Normally a
+user will construct a derived class or inherit from this class. Color
+arguments are must be scaled to fit the Quantum size according to the
+range of MaxRGB. The Color class contains a pointer to a PixelPacket,
+which may be allocated by the Color class, or may refer to an existing
+pixel in an image.
+
+An alternate way to construct the class is via an X11-compatible color
+specification string (e.g. Color(“red”) or Color (“#FF0000”)). Since
+the class may be constructed from a string, convenient strings may be
+passed in place of an explicit Color object in methods which accept a
+reference to Color. Color may also be converted to a std::string for
+convenience in user interfaces, and for saving settings to a text
+file.
+
+The following is the definition of the Color class::
+
+ // Compare two Color objects regardless of LHS/RHS
+ int MagickDLLDecl operator == ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator != ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator > ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator < ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator >= ( const Magick::Color& left_, const Magick::Color& right_ );
+ int MagickDLLDecl operator <= ( const Magick::Color& left_, const Magick::Color& right_ );
+
+ // Base color class stores RGB components scaled to fit Quantum
+ class MagickDLLDecl Color
+ {
+ public:
+ Color ( Quantum red_,
+ Quantum green_,
+ Quantum blue_ );
+ Color ( Quantum red_,
+ Quantum green_,
+ Quantum blue_,
+ Quantum alpha_ );
+ Color ( const std::string &x11color_ );
+ Color ( const char * x11color_ );
+ Color ( void );
+ virtual ~Color ( void );
+ Color ( const Color & color_ );
+
+ // Red color (range 0 to MaxRGB)
+ void redQuantum ( Quantum red_ );
+ Quantum redQuantum ( void ) const;
+
+ // Green color (range 0 to MaxRGB)
+ void greenQuantum ( Quantum green_ );
+ Quantum greenQuantum ( void ) const;
+
+ // Blue color (range 0 to MaxRGB)
+ void blueQuantum ( Quantum blue_ );
+ Quantum blueQuantum ( void ) const;
+
+ // Alpha level (range OpaqueOpacity=0 to TransparentOpacity=MaxRGB)
+ void alphaQuantum ( Quantum alpha_ );
+ Quantum alphaQuantum ( void ) const;
+
+ // Scaled (to 1.0) version of alpha for use in sub-classes
+ // (range opaque=0 to transparent=1.0)
+ void alpha ( double alpha_ );
+ double alpha ( void ) const;
+
+ // Does object contain valid color?
+ void isValid ( bool valid_ );
+ bool isValid ( void ) const;
+
+ // Set color via X11 color specification string
+ const Color& operator= ( const std::string &x11color_ );
+ const Color& operator= ( const char * x11color_ );
+
+ // Assignment operator
+ Color& operator= ( const Color& color_ );
+
+ // Return X11 color specification string
+ /* virtual */ operator std::string() const;
+
+ // Return ImageMagick PixelPacket
+ operator PixelPacket() const;
+
+ // Construct color via ImageMagick PixelPacket
+ Color ( const PixelPacket &color_ );
+
+ // Set color via ImageMagick PixelPacket
+ const Color& operator= ( const PixelPacket &color_ );
+
+ };
+
+
+Color Derived Classes
+---------------------
+
+Available derived color specification classes are shown in the following table:
+
+.. table:: Color Derived Classes
+
+ ========== ================================================================
+ Class Description
+ ========== ================================================================
+ ColorRGB_ Representation of RGB color with red, green, and blue specified
+ as ratios (0 to 1)
+ ColorGray_ Representation of grayscale RGB color (equal parts red, green,
+ and blue) specified as a ratio (0 to 1)
+ ColorMono_ Representation of a black/white color (true/false)
+ ColorHSL_ Representation of a color in Hue/Saturation/Luminosity (HSL)
+ colorspace
+ ColorYUV_ Representation of a color in the YUV colorspace
+ ========== ================================================================
+
+ColorRGB
+---------
+
+Representation of an RGB color in floating point. All color arguments
+have a valid range of 0.0 - 1.0. Note that floating point alpha may be
+set via the alpha() method in the Color base class::
+
+ class ColorRGB : public Color
+ {
+ public:
+ ColorRGB ( double red_, double green_, double blue_ );
+ ColorRGB ( void );
+ ColorRGB ( const Color & color_ );
+ /* virtual */ ~ColorRGB ( void );
+
+ void red ( double red_ );
+ double red ( void ) const;
+
+ void green ( double green_ );
+ double green ( void ) const;
+
+ void blue ( double blue_ );
+ double blue ( void ) const;
+
+ // Assignment operator from base class
+ ColorRGB& operator= ( const Color& color_ );
+
+ protected:
+ // Constructor to construct with PixelPacket*
+ ColorRGB ( PixelPacket* rep_, PixelType pixelType_ );
+ };
+
+
+ColorGray
+---------
+
+Representation of a floating point grayscale color (in RGB
+colorspace). Grayscale is simply RGB with equal parts of red, green,
+and blue. All double arguments have a valid range of 0.0 - 1.0::
+
+ class ColorGray : public Color
+ {
+ public:
+ ColorGray ( double shade_ );
+ ColorGray ( void );
+ ColorGray ( const Color & color_ );
+ /* virtual */ ~ColorGray ();
+
+ void shade ( double shade_ );
+ double shade ( void ) const;
+
+ // Assignment operator from base class
+ ColorGray& operator= ( const Color& color_ );
+
+ };
+
+
+ColorMono
+---------
+
+Representation of a black/white pixel (in RGB colorspace). Color
+arguments are constrained to 'false' (black pixel) and 'true' (white
+pixel)::
+
+ class ColorMono : public Color
+ {
+ public:
+ ColorMono ( bool mono_ );
+ ColorMono ( void );
+ ColorMono ( const Color & color_ );
+ /* virtual */ ~ColorMono ();
+
+ void mono ( bool mono_ );
+ bool mono ( void ) const;
+
+ // Assignment operator from base class
+ ColorMono& operator= ( const Color& color_ );
+
+ };
+
+
+ColorHSL
+--------
+
+Representation of a color in Hue/Saturation/Luminosity (HSL) colorspace::
+
+ class MagickDLLDecl ColorHSL : public Color
+ {
+ public:
+ ColorHSL ( double hue_, double saturation_, double luminosity_ );
+ ColorHSL ( void );
+ ColorHSL ( const Color & color_ );
+ /* virtual */ ~ColorHSL ( );
+
+ void hue ( double hue_ );
+ double hue ( void ) const;
+
+ void saturation ( double saturation_ );
+ double saturation ( void ) const;
+
+ void luminosity ( double luminosity_ );
+ double luminosity ( void ) const;
+
+ // Assignment operator from base class
+ ColorHSL& operator= ( const Color& color_ );
+
+ };
+
+
+ColorYUV
+--------
+
+Representation of a color in YUV colorspace (used to encode color for
+television transmission). Argument ranges are
+
+ == =================
+ Y 0.0 through 1.0
+ U -0.5 through 0.5
+ V -0.5 through 0.5
+ == =================
+
+::
+
+ class ColorYUV : public Color
+ {
+ public:
+ ColorYUV ( double y_, double u_, double v_ );
+ ColorYUV ( void );
+ ColorYUV ( const Color & color_ );
+ /* virtual */ ~ColorYUV ( void );
+
+ void u ( double u_ );
+ double u ( void ) const;
+
+ void v ( double v_ );
+ double v ( void ) const;
+
+ void y ( double y_ );
+ double y ( void ) const;
+
+ // Assignment operator from base class
+ ColorYUV& operator= ( const Color& color_ );
+
+ };
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/Drawable.html b/www/Magick++/Drawable.html
new file mode 100644
index 0000000..0a03eed
--- /dev/null
+++ b/www/Magick++/Drawable.html
@@ -0,0 +1,1127 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Drawable</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-drawable">
+<h1 class="title">Magick::Drawable</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#coordinate-structure" id="id8">Coordinate structure</a></li>
+<li><a class="reference internal" href="#drawable-classes" id="id9">Drawable classes</a></li>
+<li><a class="reference internal" href="#vector-path-classes" id="id10">Vector Path Classes</a></li>
+</ul>
+</div>
+<p>Drawable provides a convenient interface for preparing vector, image,
+or text arguments for the Image::draw() method. Each instance of a
+Drawable sub-class represents a single drawable object. Drawable
+objects may be drawn &quot;one-by-one&quot; via multiple invocations of the
+Image <a class="reference external" href="Image.html#draw">draw()</a> method, or may be drawn
+&quot;all-at-once&quot; by passing a list of Drawable objects to the Image
+<a class="reference external" href="Image.html#draw">draw()</a> method. The one-by-one approach is
+convenient for simple drawings, while the list-based approach is
+appropriate for drawings which require more sophistication.</p>
+<p>The following is an example using the Drawable subclasses with a
+one-by-one approach to draw the following figure:</p>
+<img alt="Figure showing drawing example" src="Drawable_example_1.png" style="width: 300px; height: 200px;" />
+<pre class="literal-block">
+#include &lt;string&gt;
+#include &lt;iostream&gt;
+#include &lt;Magick++.h&gt;
+
+using namespace std;
+using namespace Magick;
+
+int main(int /*argc*/,char **argv)
+{
+ try {
+ InitializeMagick(*argv);
+
+ // Create base image (white image of 300 by 200 pixels)
+ Image image( Geometry(300,200), Color(&quot;white&quot;) );
+
+ // Set draw options
+ image.strokeColor(&quot;red&quot;); // Outline color
+ image.fillColor(&quot;green&quot;); // Fill color
+ image.strokeWidth(5);
+
+ // Draw a circle
+ image.draw( DrawableCircle(100,100, 50,100) );
+
+ // Draw a rectangle
+ image.draw( DrawableRectangle(200,200, 270,170) );
+
+ // Display the result
+ image.display( );
+ }
+ catch( exception &amp;error_ )
+ {
+ cout &lt;&lt; &quot;Caught exception: &quot; &lt;&lt; error_.what() &lt;&lt; endl;
+ return 1;
+ }
+
+ return 0;
+}
+</pre>
+<p>Since Drawable is an object it may be saved in an array or a list for
+later (perhaps repeated) use. The following example shows how to draw
+the same figure using the list-based approach:</p>
+<pre class="literal-block">
+#include &lt;string&gt;
+#include &lt;iostream&gt;
+#include &lt;list&gt;
+#include &lt;Magick++.h&gt;
+
+using namespace std;
+using namespace Magick;
+
+int main(int /*argc*/,char **/*argv*/)
+{
+ try {
+
+ InitializeMagick(*argv);
+
+ // Create base image (white image of 300 by 200 pixels)
+ Image image( Geometry(300,200), Color(&quot;white&quot;) );
+
+ // Construct drawing list
+ std::list&lt;Magick::Drawable&gt; drawList;
+
+ // Add some drawing options to drawing list
+ drawList.push_back(DrawableStrokeColor(&quot;red&quot;)); // Outline color
+ drawList.push_back(DrawableStrokeWidth(5)); // Stroke width
+ drawList.push_back(DrawableFillColor(&quot;green&quot;)); // Fill color
+
+ // Add a Circle to drawing list
+ drawList.push_back(DrawableCircle(100,100, 50,100));
+
+ // Add a Rectangle to drawing list
+ drawList.push_back(DrawableRectangle(200,100, 270,170));
+
+ // Draw everything using completed drawing list
+ image.draw(drawList);
+
+ // Display the result
+ image.display( );
+ }
+ catch( exception &amp;error_ )
+ {
+ cout &lt;&lt; &quot;Caught exception: &quot; &lt;&lt; error_.what() &lt;&lt; endl;
+ return 1;
+ }
+
+ return 0;
+}
+</pre>
+<div class="section" id="coordinate-structure">
+<h1><a class="toc-backref" href="#id8">Coordinate structure</a></h1>
+<p>Drawable depends on the simple Coordinate structure which represents a
+pair of x,y coodinates. The Coordinate structure is defined as
+follows:</p>
+<pre class="literal-block">
+class Coordinate
+{
+public:
+
+ // Default Constructor
+ Coordinate ( void );
+
+ // Constructor, setting first &amp; second
+ Coordinate ( double x_, double y_ );
+
+ // Destructor
+ virtual ~Coordinate ();
+
+ // x coordinate member
+ void x ( double x_ );
+ double x ( void ) const;
+
+ // y coordinate member
+ void y ( double y_ );
+ double y ( void ) const;
+};
+</pre>
+</div>
+<div class="section" id="drawable-classes">
+<h1><a class="toc-backref" href="#id9">Drawable classes</a></h1>
+<p>Drawable classes represent objects to be drawn on the image.</p>
+<div class="contents local topic" id="id2">
+<p class="topic-title first">Drawable classes</p>
+<ul class="simple">
+<li><a class="reference internal" href="#drawableaffine" id="id11">DrawableAffine</a></li>
+<li><a class="reference internal" href="#drawablearc" id="id12">DrawableArc</a></li>
+<li><a class="reference internal" href="#drawablebezier" id="id13">DrawableBezier</a></li>
+<li><a class="reference internal" href="#drawableclippath" id="id14">DrawableClipPath</a></li>
+<li><a class="reference internal" href="#drawablecircle" id="id15">DrawableCircle</a></li>
+<li><a class="reference internal" href="#drawablecolor" id="id16">DrawableColor</a></li>
+<li><a class="reference internal" href="#drawablecompositeimage" id="id17">DrawableCompositeImage</a></li>
+<li><a class="reference internal" href="#drawabledasharray" id="id18">DrawableDashArray</a></li>
+<li><a class="reference internal" href="#drawabledashoffset" id="id19">DrawableDashOffset</a></li>
+<li><a class="reference internal" href="#drawableellipse" id="id20">DrawableEllipse</a></li>
+<li><a class="reference internal" href="#drawablefillcolor" id="id21">DrawableFillColor</a></li>
+<li><a class="reference internal" href="#drawablefillrule" id="id22">DrawableFillRule</a></li>
+<li><a class="reference internal" href="#drawablefillopacity" id="id23">DrawableFillOpacity</a></li>
+<li><a class="reference internal" href="#drawablefont" id="id24">DrawableFont</a></li>
+<li><a class="reference internal" href="#drawablegravity" id="id25">DrawableGravity</a></li>
+<li><a class="reference internal" href="#drawableline" id="id26">DrawableLine</a></li>
+<li><a class="reference internal" href="#drawablematte" id="id27">DrawableMatte</a></li>
+<li><a class="reference internal" href="#drawablemiterlimit" id="id28">DrawableMiterLimit</a></li>
+<li><a class="reference internal" href="#drawablepath" id="id29">DrawablePath</a></li>
+<li><a class="reference internal" href="#drawablepoint" id="id30">DrawablePoint</a></li>
+<li><a class="reference internal" href="#drawablepointsize" id="id31">DrawablePointSize</a></li>
+<li><a class="reference internal" href="#drawablepolygon" id="id32">DrawablePolygon</a></li>
+<li><a class="reference internal" href="#drawablepolyline" id="id33">DrawablePolyline</a></li>
+<li><a class="reference internal" href="#drawablepopclippath" id="id34">DrawablePopClipPath</a></li>
+<li><a class="reference internal" href="#drawablepopgraphiccontext" id="id35">DrawablePopGraphicContext</a></li>
+<li><a class="reference internal" href="#drawablepushclippath" id="id36">DrawablePushClipPath</a></li>
+<li><a class="reference internal" href="#drawablepushgraphiccontext" id="id37">DrawablePushGraphicContext</a></li>
+<li><a class="reference internal" href="#drawablepushpattern" id="id38">DrawablePushPattern</a></li>
+<li><a class="reference internal" href="#drawablepoppattern" id="id39">DrawablePopPattern</a></li>
+<li><a class="reference internal" href="#drawablerectangle" id="id40">DrawableRectangle</a></li>
+<li><a class="reference internal" href="#drawablerotation" id="id41">DrawableRotation</a></li>
+<li><a class="reference internal" href="#drawableroundrectangle" id="id42">DrawableRoundRectangle</a></li>
+<li><a class="reference internal" href="#drawablescaling" id="id43">DrawableScaling</a></li>
+<li><a class="reference internal" href="#drawableskewx" id="id44">DrawableSkewX</a></li>
+<li><a class="reference internal" href="#drawableskewy" id="id45">DrawableSkewY</a></li>
+<li><a class="reference internal" href="#drawablestrokeantialias" id="id46">DrawableStrokeAntialias</a></li>
+<li><a class="reference internal" href="#drawablestrokecolor" id="id47">DrawableStrokeColor</a></li>
+<li><a class="reference internal" href="#drawablestrokelinecap" id="id48">DrawableStrokeLineCap</a></li>
+<li><a class="reference internal" href="#drawablestrokelinejoin" id="id49">DrawableStrokeLineJoin</a></li>
+<li><a class="reference internal" href="#drawablestrokeopacity" id="id50">DrawableStrokeOpacity</a></li>
+<li><a class="reference internal" href="#drawablestrokewidth" id="id51">DrawableStrokeWidth</a></li>
+<li><a class="reference internal" href="#drawabletext" id="id52">DrawableText</a></li>
+<li><a class="reference internal" href="#drawabletextantialias" id="id53">DrawableTextAntialias</a></li>
+<li><a class="reference internal" href="#drawabletextdecoration" id="id54">DrawableTextDecoration</a></li>
+<li><a class="reference internal" href="#drawabletextundercolor" id="id55">DrawableTextUnderColor</a></li>
+<li><a class="reference internal" href="#drawabletranslation" id="id56">DrawableTranslation</a></li>
+<li><a class="reference internal" href="#drawableviewbox" id="id57">DrawableViewbox</a></li>
+</ul>
+</div>
+<div class="section" id="drawableaffine">
+<h2><a class="toc-backref" href="#id11">DrawableAffine</a></h2>
+<p>Specify a transformation matrix to adjust scaling, rotation, and
+translation (coordinate transformation) for subsequently drawn objects
+in the same or decendent drawing context. The <cite>sx_</cite> &amp; <cite>sy_</cite> parameters
+represent the x &amp; y scale factors, the <cite>rx_</cite> &amp; <cite>ry_</cite> parameters represent
+the x &amp; y rotation, and the <cite>tx_</cite> &amp; <cite>ty_</cite> parameters represent the x &amp; y
+translation:</p>
+<pre class="literal-block">
+DrawableAffine ( double sx_, double sy_,
+ double rx_, double ry_,
+ double tx_, double ty_ );
+</pre>
+<p>Specify a transformation matrix to adjust scaling, rotation, and
+translation (coordinate transformation) for subsequently drawn objects
+in the same or decendent drawing context. Initialized to unity (no
+effect) affine values. Use class methods (not currently documented but
+defined in the Drawable.h header file) to adjust individual parameters
+from their unity values:</p>
+<pre class="literal-block">
+DrawableAffine ( void );
+</pre>
+</div>
+<div class="section" id="drawablearc">
+<h2><a class="toc-backref" href="#id12">DrawableArc</a></h2>
+<p>Draw an arc using the stroke color and based on the circle starting at
+coordinates <cite>startX_</cite>,`startY_`, and ending with coordinates
+<cite>endX_</cite>,`endY_`, and bounded by the rotational arc
+<cite>startDegrees_</cite>,`endDegrees_`:</p>
+<pre class="literal-block">
+DrawableArc ( double startX_, double startY_,
+ double endX_, double endY_,
+ double startDegrees_, double endDegrees_ );
+</pre>
+</div>
+<div class="section" id="drawablebezier">
+<h2><a class="toc-backref" href="#id13">DrawableBezier</a></h2>
+<p>Draw a bezier curve using the stroke color and based on the
+coordinates specified by the <cite>coordinates_</cite> list:</p>
+<pre class="literal-block">
+DrawableBezier ( const CoordinateList &amp;coordinates_ );
+</pre>
+</div>
+<div class="section" id="drawableclippath">
+<h2><a class="toc-backref" href="#id14">DrawableClipPath</a></h2>
+<p>Select a drawing clip path matching <cite>id_</cite>:</p>
+<pre class="literal-block">
+DrawableClipPath ( const std::string &amp;id_ );
+</pre>
+</div>
+<div class="section" id="drawablecircle">
+<h2><a class="toc-backref" href="#id15">DrawableCircle</a></h2>
+<p>Draw a circle using the stroke color and thickness using specified
+origin and perimeter coordinates. If a fill color is specified, then
+the object is filled:</p>
+<pre class="literal-block">
+DrawableCircle ( double originX_, double originY_,
+ double perimX_, double perimY_ )
+</pre>
+</div>
+<div class="section" id="drawablecolor">
+<h2><a class="toc-backref" href="#id16">DrawableColor</a></h2>
+<p>Color image according to paintMethod. The point method recolors the
+target pixel. The replace method recolors any pixel that matches the
+color of the target pixel. Floodfill recolors any pixel that matches
+the color of the target pixel and is a neighbor, whereas filltoborder
+recolors any neighbor pixel that is not the border color. Finally,
+reset recolors all pixels:</p>
+<pre class="literal-block">
+DrawableColor ( double x_, double y_,
+ PaintMethod paintMethod_ )
+</pre>
+</div>
+<div class="section" id="drawablecompositeimage">
+<h2><a class="toc-backref" href="#id17">DrawableCompositeImage</a></h2>
+<p>Composite current image with contents of specified image, at specified
+coordinates. If the matte attribute is set to true, then the image
+composition will consider an alpha channel, or transparency, present
+in the image file so that non-opaque portions allow part (or all) of
+the composite image to show through:</p>
+<pre class="literal-block">
+DrawableCompositeImage ( double x_, double y_,
+ const std::string &amp;filename_ );
+DrawableCompositeImage ( double x_, double y_,
+ const Image &amp;image_ );
+</pre>
+<p>Composite current image with contents of specified image, rendered
+with specified width and height, at specified coordinates. If the
+matte attribute is set to true, then the image composition will
+consider an alpha channel, or transparency, present in the image file
+so that non-opaque portions allow part (or all) of the composite image
+to show through. If the specified width or height is zero, then the
+image is composited at its natural size, without enlargement or
+reduction:</p>
+<pre class="literal-block">
+DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const std::string &amp;filename_ );
+
+DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const Image &amp;image_ );
+</pre>
+<p>Composite current image with contents of specified image, rendered
+with specified width and height, using specified composition
+algorithm, at specified coordinates. If the matte attribute is set to
+true, then the image composition will consider an alpha channel, or
+transparency, present in the image file so that non-opaque portions
+allow part (or all) of the composite image to show through. If the
+specified width or height is zero, then the image is composited at its
+natural size, without enlargement or reduction:</p>
+<pre class="literal-block">
+DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const std::string &amp;filename_,
+ CompositeOperator composition_ );
+
+DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const Image &amp;image_,
+ CompositeOperator composition_ );
+</pre>
+</div>
+<div class="section" id="drawabledasharray">
+<h2><a class="toc-backref" href="#id18">DrawableDashArray</a></h2>
+<p>Specify the pattern of dashes and gaps used to stroke paths. The
+strokeDashArray represents a zero-terminated array of numbers that
+specify the lengths of alternating dashes and gaps in pixels. If an
+odd number of values is provided, then the list of values is repeated
+to yield an even number of values. A typical <cite>strokeDashArray_</cite> array
+might contain the members 5 3 2 0, where the zero value indicates the
+end of the pattern array:</p>
+<pre class="literal-block">
+DrawableDashArray( const double* dasharray_ );
+</pre>
+</div>
+<div class="section" id="drawabledashoffset">
+<h2><a class="toc-backref" href="#id19">DrawableDashOffset</a></h2>
+<p>Specify the distance into the dash pattern to start the dash. See
+documentation on SVG's <a class="reference external" href="http://www.w3.org/TR/SVG/painting.html#StrokeDashoffsetProperty">stroke-dashoffset</a>
+property for usage details:</p>
+<pre class="literal-block">
+DrawableDashOffset ( const double offset_ )
+</pre>
+</div>
+<div class="section" id="drawableellipse">
+<h2><a class="toc-backref" href="#id20">DrawableEllipse</a></h2>
+<p>Draw an ellipse using the stroke color and thickness, specified
+origin, x &amp; y radius, as well as specified start and end of arc in
+degrees. If a fill color is specified, then the object is filled:</p>
+<pre class="literal-block">
+DrawableEllipse ( double originX_, double originY_,
+ double radiusX_, double radiusY_,
+ double arcStart_, double arcEnd_ )
+</pre>
+</div>
+<div class="section" id="drawablefillcolor">
+<h2><a class="toc-backref" href="#id21">DrawableFillColor</a></h2>
+<p>Specify drawing object fill color:</p>
+<blockquote>
+DrawableFillColor ( const Color &amp;color_ );</blockquote>
+</div>
+<div class="section" id="drawablefillrule">
+<h2><a class="toc-backref" href="#id22">DrawableFillRule</a></h2>
+<p>Specify the algorithm which is to be used to determine what parts of
+the canvas are included inside the shape. See documentation on SVG's
+<a class="reference external" href="http://www.w3.org/TR/SVG/painting.html#FillRuleProperty">fill-rule</a>
+property for usage details:</p>
+<pre class="literal-block">
+DrawableFillRule ( const FillRule fillRule_ )
+</pre>
+</div>
+<div class="section" id="drawablefillopacity">
+<h2><a class="toc-backref" href="#id23">DrawableFillOpacity</a></h2>
+<p>Specify opacity to use when drawing using fill color:</p>
+<pre class="literal-block">
+DrawableFillOpacity ( double opacity_ )
+</pre>
+</div>
+<div class="section" id="drawablefont">
+<h2><a class="toc-backref" href="#id24">DrawableFont</a></h2>
+<p>Specify font family, style, weight (one of the set { 100 | 200 | 300 |
+400 | 500 | 600 | 700 | 800 | 900 } with 400 being the normal size),
+and stretch to be used to select the font used when drawing
+text. Wildcard matches may be applied to style via the AnyStyle
+enumeration, applied to weight if weight is zero, and applied to
+stretch via the AnyStretch enumeration:</p>
+<pre class="literal-block">
+DrawableFont ( const std::string &amp;font_ );
+
+DrawableFont ( const std::string &amp;family_,
+ StyleType style_,
+ const unsigned long weight_,
+ StretchType stretch_ );
+</pre>
+</div>
+<div class="section" id="drawablegravity">
+<h2><a class="toc-backref" href="#id25">DrawableGravity</a></h2>
+<p>Specify text positioning gravity:</p>
+<pre class="literal-block">
+DrawableGravity ( GravityType gravity_ )
+</pre>
+</div>
+<div class="section" id="drawableline">
+<h2><a class="toc-backref" href="#id26">DrawableLine</a></h2>
+<p>Draw a line using stroke color and thickness using starting and ending
+coordinates:</p>
+<pre class="literal-block">
+DrawableLine ( double startX_, double startY_,
+ double endX_, double endY_ )
+</pre>
+</div>
+<div class="section" id="drawablematte">
+<h2><a class="toc-backref" href="#id27">DrawableMatte</a></h2>
+<p>Change the pixel matte value to transparent. The point method changes
+the matte value of the target pixel. The replace method changes the
+matte value of any pixel that matches the color of the target
+pixel. Floodfill changes the matte value of any pixel that matches the
+color of the target pixel and is a neighbor, whereas filltoborder
+changes the matte value of any neighbor pixel that is not the border
+color, Finally reset changes the matte value of all pixels:</p>
+<pre class="literal-block">
+DrawableMatte ( double x_, double y_,
+ PaintMethod paintMethod_ )
+</pre>
+</div>
+<div class="section" id="drawablemiterlimit">
+<h2><a class="toc-backref" href="#id28">DrawableMiterLimit</a></h2>
+<p>Specify miter limit. When two line segments meet at a sharp angle and
+miter joins have been specified for 'lineJoin', it is possible for the
+miter to extend far beyond the thickness of the line stroking the
+path. The miterLimit' imposes a limit on the ratio of the miter length
+to the 'lineWidth'. The default value of this parameter is 4:</p>
+<pre class="literal-block">
+DrawableMiterLimit ( unsigned int miterlimit_ )
+</pre>
+</div>
+<div class="section" id="drawablepath">
+<h2><a class="toc-backref" href="#id29">DrawablePath</a></h2>
+<p>Draw on image using vector path:</p>
+<pre class="literal-block">
+DrawablePath ( const VPathList &amp;path_ );
+</pre>
+</div>
+<div class="section" id="drawablepoint">
+<h2><a class="toc-backref" href="#id30">DrawablePoint</a></h2>
+<p>Draw a point using stroke color and thickness at coordinate:</p>
+<pre class="literal-block">
+DrawablePoint ( double x_, double y_ )
+</pre>
+</div>
+<div class="section" id="drawablepointsize">
+<h2><a class="toc-backref" href="#id31">DrawablePointSize</a></h2>
+<p>Set font point size:</p>
+<pre class="literal-block">
+DrawablePointSize ( double pointSize_ )
+</pre>
+</div>
+<div class="section" id="drawablepolygon">
+<h2><a class="toc-backref" href="#id32">DrawablePolygon</a></h2>
+<p>Draw an arbitrary polygon using stroke color and thickness consisting
+of three or more coordinates contained in an STL list. If a fill color
+is specified, then the object is filled:</p>
+<pre class="literal-block">
+DrawablePolygon ( const CoordinateList &amp;coordinates_ )
+</pre>
+</div>
+<div class="section" id="drawablepolyline">
+<h2><a class="toc-backref" href="#id33">DrawablePolyline</a></h2>
+<p>Draw an arbitrary polyline using stroke color and thickness consisting
+of three or more coordinates contained in an STL list. If a fill color
+is specified, then the object is filled:</p>
+<pre class="literal-block">
+DrawablePolyline ( const CoordinateList &amp;coordinates_ )
+</pre>
+</div>
+<div class="section" id="drawablepopclippath">
+<h2><a class="toc-backref" href="#id34">DrawablePopClipPath</a></h2>
+<p>Pop (terminate) clip path definition started by DrawablePushClipPath:</p>
+<pre class="literal-block">
+DrawablePopClipPath ( void )
+</pre>
+</div>
+<div class="section" id="drawablepopgraphiccontext">
+<h2><a class="toc-backref" href="#id35">DrawablePopGraphicContext</a></h2>
+<p>Pop Graphic Context. Removing the current graphic context from the
+graphic context stack restores the options to the values they had
+prior to the preceding <a class="reference internal" href="#drawablepushgraphiccontext">DrawablePushGraphicContext</a> operation:</p>
+<pre class="literal-block">
+DrawablePopGraphicContext ( void )
+</pre>
+</div>
+<div class="section" id="drawablepushclippath">
+<h2><a class="toc-backref" href="#id36">DrawablePushClipPath</a></h2>
+<p>Push (create) clip path definition with <cite>id_</cite>. Clip patch definition
+consists of subsequent drawing commands, terminated by
+<a class="reference internal" href="#drawablepopclippath">DrawablePopClipPath</a>:</p>
+<pre class="literal-block">
+DrawablePushClipPath ( const std::string &amp;id_)
+</pre>
+</div>
+<div class="section" id="drawablepushgraphiccontext">
+<h2><a class="toc-backref" href="#id37">DrawablePushGraphicContext</a></h2>
+<p>Push Graphic Context. When a graphic context is pushed, options set
+after the context is pushed (such as coordinate transformations, color
+settings, etc.) are saved to a new graphic context. This allows
+related options to be saved on a graphic context &quot;stack&quot; in order to
+support heirarchical nesting of options. When
+<a class="reference internal" href="#drawablepopgraphiccontext">DrawablePopGraphicContext</a> is used to pop the current graphic context,
+the options in effect during the last <a class="reference internal" href="#drawablepushgraphiccontext">DrawablePushGraphicContext</a>
+operation are restored:</p>
+<pre class="literal-block">
+DrawablePushGraphicContext ( void )
+</pre>
+</div>
+<div class="section" id="drawablepushpattern">
+<h2><a class="toc-backref" href="#id38">DrawablePushPattern</a></h2>
+<p>Start a pattern definition with arbitrary pattern name specified by
+<cite>id_</cite>, pattern offset specified by <cite>x_</cite> and <cite>y_</cite>, and pattern size
+specified by <cite>width_</cite> and <cite>height_</cite>. The pattern is defined within the
+coordinate system defined by the specified offset and size. Arbitrary
+drawing objects (including <a class="reference internal" href="#drawablecompositeimage">DrawableCompositeImage</a>) may be specified
+between <a class="reference internal" href="#drawablepushpattern">DrawablePushPattern</a> and <a class="reference internal" href="#drawablepoppattern">DrawablePopPattern</a> in order to draw
+the pattern. Normally the pair <a class="reference internal" href="#drawablepushgraphiccontext">DrawablePushGraphicContext</a> &amp;
+<a class="reference internal" href="#drawablepopgraphiccontext">DrawablePopGraphicContext</a> are used to enclose a pattern
+definition. Pattern definitions are terminated by a
+<a class="reference internal" href="#drawablepoppattern">DrawablePopPattern</a> object:</p>
+<pre class="literal-block">
+DrawablePushPattern ( const std::string &amp;id_, long x_, long y_,
+ long width_, long height_ )
+</pre>
+</div>
+<div class="section" id="drawablepoppattern">
+<h2><a class="toc-backref" href="#id39">DrawablePopPattern</a></h2>
+<p>Terminate a pattern definition started via <a class="reference internal" href="#drawablepushpattern">DrawablePushPattern</a>:</p>
+<pre class="literal-block">
+DrawablePopPattern ( void )
+</pre>
+</div>
+<div class="section" id="drawablerectangle">
+<h2><a class="toc-backref" href="#id40">DrawableRectangle</a></h2>
+<p>Draw a rectangle using stroke color and thickness from upper-left
+coordinates to lower-right coordinates. If a fill color is specified,
+then the object is filled:</p>
+<pre class="literal-block">
+DrawableRectangle ( double upperLeftX_, double upperLeftY_,
+ double lowerRightX_, double lowerRightY_ )
+</pre>
+</div>
+<div class="section" id="drawablerotation">
+<h2><a class="toc-backref" href="#id41">DrawableRotation</a></h2>
+<p>Set rotation to use when drawing (coordinate transformation):</p>
+<pre class="literal-block">
+DrawableRotation ( double angle_ )
+</pre>
+</div>
+<div class="section" id="drawableroundrectangle">
+<h2><a class="toc-backref" href="#id42">DrawableRoundRectangle</a></h2>
+<p>Draw a rounded rectangle using stroke color and thickness, with
+specified center coordinate, specified width and height, and specified
+corner width and height. If a fill color is specified, then the
+object is filled:</p>
+<pre class="literal-block">
+DrawableRoundRectangle ( double centerX_, double centerY_,
+ double width_, double hight_,
+ double cornerWidth_, double cornerHeight_ )
+</pre>
+</div>
+<div class="section" id="drawablescaling">
+<h2><a class="toc-backref" href="#id43">DrawableScaling</a></h2>
+<p>Apply scaling in x and y direction while drawing objects (coordinate
+transformation):</p>
+<pre class="literal-block">
+DrawableScaling ( double x_, double y_ )
+</pre>
+</div>
+<div class="section" id="drawableskewx">
+<h2><a class="toc-backref" href="#id44">DrawableSkewX</a></h2>
+<p>Apply Skew in X direction (coordinate transformation):</p>
+<pre class="literal-block">
+DrawableSkewX ( double angle_ )
+</pre>
+</div>
+<div class="section" id="drawableskewy">
+<h2><a class="toc-backref" href="#id45">DrawableSkewY</a></h2>
+<p>Apply Skew in Y direction:</p>
+<pre class="literal-block">
+DrawableSkewY ( double angle_ )
+</pre>
+</div>
+<div class="section" id="drawablestrokeantialias">
+<h2><a class="toc-backref" href="#id46">DrawableStrokeAntialias</a></h2>
+<p>Antialias while drawing lines or object outlines:</p>
+<pre class="literal-block">
+DrawableStrokeAntialias ( bool flag_ )
+</pre>
+</div>
+<div class="section" id="drawablestrokecolor">
+<h2><a class="toc-backref" href="#id47">DrawableStrokeColor</a></h2>
+<p>Set color to use when drawing lines or object outlines:</p>
+<pre class="literal-block">
+DrawableStrokeColor ( const Color &amp;color_ )
+</pre>
+</div>
+<div class="section" id="drawablestrokelinecap">
+<h2><a class="toc-backref" href="#id48">DrawableStrokeLineCap</a></h2>
+<p>Specify the shape to be used at the end of open subpaths when they are
+stroked. Values of LineCap are UndefinedCap, ButtCap, RoundCap, and
+SquareCap:</p>
+<pre class="literal-block">
+DrawableStrokeLineCap ( LineCap linecap_ )
+</pre>
+</div>
+<div class="section" id="drawablestrokelinejoin">
+<h2><a class="toc-backref" href="#id49">DrawableStrokeLineJoin</a></h2>
+<p>Specify the shape to be used at the corners of paths (or other vector
+shapes) when they are stroked. Values of LineJoin are UndefinedJoin,
+MiterJoin, RoundJoin, and BevelJoin:</p>
+<pre class="literal-block">
+DrawableStrokeLineJoin ( LineJoin linejoin_ )
+</pre>
+</div>
+<div class="section" id="drawablestrokeopacity">
+<h2><a class="toc-backref" href="#id50">DrawableStrokeOpacity</a></h2>
+<p>Opacity to use when drawing lines or object outlines:</p>
+<pre class="literal-block">
+DrawableStrokeOpacity ( double opacity_ )
+</pre>
+</div>
+<div class="section" id="drawablestrokewidth">
+<h2><a class="toc-backref" href="#id51">DrawableStrokeWidth</a></h2>
+<p>Set width to use when drawing lines or object outlines:</p>
+<pre class="literal-block">
+DrawableStrokeWidth ( double width_ )
+</pre>
+</div>
+<div class="section" id="drawabletext">
+<h2><a class="toc-backref" href="#id52">DrawableText</a></h2>
+<p>Annotate image with text using stroke color, font, font pointsize, and
+box color (text background color), at specified coordinates. If text
+contains <a class="reference external" href="FormatCharacters.html">special format characters</a> the
+image filename, type, width, height, or other image attributes may be
+incorporated in the text (see label()):</p>
+<pre class="literal-block">
+DrawableText ( const double x_, const double y_,
+ const std::string &amp;text_ )
+</pre>
+<p>Annotate image with text represented with text encoding, using current
+stroke color, font, font pointsize, and box color (text background
+color), at specified coordinates. If text contains <a class="reference external" href="FormatCharacters.html">special format
+characters</a> the image filename, type, width,
+height, or other image attributes may be incorporated in the text (see
+label()).</p>
+<p>The text encoding specifies the code set to use for text
+annotations. The only character encoding which may be specified at
+this time is &quot;UTF-8&quot; for representing <a class="reference external" href="http://www.unicode.org/">Unicode</a> as a sequence of bytes. Specify an empty
+string to set text encoding to the system's default. Successful text
+annotation using Unicode may require fonts designed to support
+Unicode:</p>
+<pre class="literal-block">
+DrawableText ( const double x_, const double y_,
+ const std::string &amp;text_, const std::string &amp;encoding_)
+</pre>
+</div>
+<div class="section" id="drawabletextantialias">
+<h2><a class="toc-backref" href="#id53">DrawableTextAntialias</a></h2>
+<p>Antialias while drawing text (default true). The main reason to
+disable text antialiasing is to avoid adding new colors to the image:</p>
+<pre class="literal-block">
+DrawableTextAntialias ( bool flag_ )
+</pre>
+</div>
+<div class="section" id="drawabletextdecoration">
+<h2><a class="toc-backref" href="#id54">DrawableTextDecoration</a></h2>
+<p>Specify decoration (e.g. UnderlineDecoration) to apply to text:</p>
+<pre class="literal-block">
+DrawableTextDecoration ( DecorationType decoration_ )
+</pre>
+</div>
+<div class="section" id="drawabletextundercolor">
+<h2><a class="toc-backref" href="#id55">DrawableTextUnderColor</a></h2>
+<p>Draw a box under rendered text using the specified color:</p>
+<pre class="literal-block">
+DrawableTextUnderColor ( const Color &amp;color_ )
+</pre>
+</div>
+<div class="section" id="drawabletranslation">
+<h2><a class="toc-backref" href="#id56">DrawableTranslation</a></h2>
+<p>Apply coordinate translation (set new coordinate origin):</p>
+<pre class="literal-block">
+DrawableTranslation ( double x_, double y_ )
+</pre>
+</div>
+<div class="section" id="drawableviewbox">
+<h2><a class="toc-backref" href="#id57">DrawableViewbox</a></h2>
+<p>Dimensions of the output viewbox. If the image is to be written to a
+vector format (e.g. MVG or SVG), then a <a class="reference internal" href="#drawablepushgraphiccontext">DrawablePushGraphicContext</a>
+object should be pushed to the head of the list, followed by a
+<a class="reference internal" href="#drawableviewbox">DrawableViewbox</a> object to establish the output canvas size. A
+matching <a class="reference internal" href="#drawablepopgraphiccontext">DrawablePopGraphicContext</a> object should be pushed to the
+tail of the list:</p>
+<pre class="literal-block">
+DrawableViewbox(unsigned long x1_, unsigned long y1_,
+ unsigned long x2_, unsigned long y2_)
+</pre>
+</div>
+</div>
+<div class="section" id="vector-path-classes">
+<h1><a class="toc-backref" href="#id10">Vector Path Classes</a></h1>
+<p>The vector paths supported by Magick++ are based on those supported by
+the <a class="reference external" href="http://www.w3.org/TR/SVG/paths.html">SVG XML specification</a>. Vector paths are not directly
+drawable, they must first be supplied as a constructor argument to the
+<a class="reference internal" href="#drawablepath">DrawablePath</a> class in order to create a drawable object. The
+<a class="reference internal" href="#drawablepath">DrawablePath</a> class effectively creates a drawable compound component
+which may be replayed as desired. If the drawable compound component
+consists only of vector path objects using relative coordinates then
+the object may be positioned on the image by preceding it with a
+<a class="reference internal" href="#drawablepath">DrawablePath</a> which sets the current drawing coordinate. Alternatively
+coordinate transforms may be used to <a class="reference external" href="#DrawableTranslation">translate the origin</a> in order to position the object, rotate it,
+skew it, or scale it.</p>
+<div class="contents local topic" id="vector-path-commands">
+<p class="topic-title first">Vector path commands</p>
+<ul class="simple">
+<li><a class="reference internal" href="#the-moveto-commands" id="id58">The &quot;moveto&quot; commands</a></li>
+<li><a class="reference internal" href="#the-closepath-command" id="id59">The &quot;closepath&quot; command</a></li>
+<li><a class="reference internal" href="#the-lineto-commands" id="id60">The &quot;lineto&quot; commands</a></li>
+<li><a class="reference internal" href="#curve-commands" id="id61">Curve commands</a></li>
+</ul>
+</div>
+<div class="section" id="the-moveto-commands">
+<h2><a class="toc-backref" href="#id58">The &quot;moveto&quot; commands</a></h2>
+<p>The &quot;moveto&quot; commands establish a new current point. The effect is as
+if the &quot;pen&quot; were lifted and moved to a new location. A path data
+segment must begin with either one of the &quot;moveto&quot; commands or one of
+the &quot;arc&quot; commands. Subsequent &quot;moveto&quot; commands (i.e., when the
+&quot;moveto&quot; is not the first command) represent the start of a new
+subpath.</p>
+<p>Start a new sub-path at the given coordinate. PathMovetoAbs indicates
+that absolute coordinates will follow; PathMovetoRel indicates that
+relative coordinates will follow. If a relative moveto appears as the
+first element of the path, then it is treated as a pair of absolute
+coordinates. If a moveto is followed by multiple pairs of coordinates,
+the subsequent pairs are treated as implicit lineto commands.</p>
+<div class="section" id="pathmovetoabs">
+<h3>PathMovetoAbs</h3>
+<p>Simple moveto:</p>
+<pre class="literal-block">
+PathMovetoAbs ( const Magick::Coordinate &amp;coordinate_ )
+</pre>
+<p>Moveto followed by implicit linetos:</p>
+<pre class="literal-block">
+PathMovetoAbs ( const CoordinateList &amp;coordinates_ )
+</pre>
+</div>
+<div class="section" id="pathmovetorel">
+<h3>PathMovetoRel</h3>
+<p>Simple moveto:</p>
+<pre class="literal-block">
+PathMovetoRel ( const Magick::Coordinate &amp;coordinate_ );
+</pre>
+<p>Moveto followed by implicit linetos:</p>
+<pre class="literal-block">
+PathMovetoRel ( const CoordinateList &amp;coordinates_ );
+</pre>
+</div>
+</div>
+<div class="section" id="the-closepath-command">
+<h2><a class="toc-backref" href="#id59">The &quot;closepath&quot; command</a></h2>
+<p>The &quot;closepath&quot; command causes an automatic straight line to be drawn from the current point to the initial point of the current subpath.</p>
+<div class="section" id="pathclosepath">
+<h3>PathClosePath</h3>
+<p>Close the current subpath by drawing a straight line from the current
+point to current subpath's most recent starting point (usually, the
+most recent moveto point):</p>
+<pre class="literal-block">
+PathClosePath ( void )
+</pre>
+</div>
+</div>
+<div class="section" id="the-lineto-commands">
+<h2><a class="toc-backref" href="#id60">The &quot;lineto&quot; commands</a></h2>
+<p>The various &quot;lineto&quot; commands draw straight lines from the current
+point to a new point.</p>
+<div class="section" id="pathlinetoabs">
+<h3>PathLinetoAbs</h3>
+<p>Draw a line from the current point to the given coordinate which
+becomes the new current point. <em>PathLinetoAbs</em> indicates that absolute
+coordinates are used. A number of coordinates pairs may be specified
+in a list to draw a polyline. At the end of the command, the new
+current point is set to the final set of coordinates provided.</p>
+<p>Draw to a single point:</p>
+<pre class="literal-block">
+PathLinetoAbs ( const Magick::Coordinate&amp; coordinate_ );
+</pre>
+<p>Draw to multiple points:</p>
+<pre class="literal-block">
+PathLinetoAbs ( const CoordinateList &amp;coordinates_ );
+</pre>
+</div>
+<div class="section" id="pathlinetorel">
+<h3>PathLinetoRel</h3>
+<p>Draw a line from the current point to the given coordinate which
+becomes the new current point. <em>PathLinetoRel</em> indicates that relative
+coordinates are used. A number of coordinates pairs may be specified
+in a list to draw a polyline. At the end of the command, the new
+current point is set to the final set of coordinates provided.</p>
+<p>Draw to a single point:</p>
+<pre class="literal-block">
+PathLinetoRel ( const Magick::Coordinate&amp; coordinate_ );
+</pre>
+<p>Draw to multiple points:</p>
+<pre class="literal-block">
+PathLinetoRel ( const CoordinateList &amp;coordinates_ );
+</pre>
+</div>
+<div class="section" id="pathlinetohorizontalabs">
+<h3>PathLinetoHorizontalAbs</h3>
+<p>Draws a horizontal line from the current point (cpx, cpy) to (x,
+cpy). <em>PathLinetoHorizontalAbs</em> indicates that absolute coordinates
+are supplied. At the end of the command, the new current point
+becomes (x, cpy) for the final value of x:</p>
+<pre class="literal-block">
+PathLinetoHorizontalAbs ( double x_ )
+</pre>
+</div>
+<div class="section" id="pathlinetohorizontalrel">
+<h3>PathLinetoHorizontalRel</h3>
+<p>Draws a horizontal line from the current point (cpx, cpy) to (x,
+cpy). <em>PathLinetoHorizontalRel</em> indicates that relative coordinates
+are supplied. At the end of the command, the new current point becomes
+(x, cpy) for the final value of x:</p>
+<pre class="literal-block">
+PathLinetoHorizontalRel ( double x_ )
+</pre>
+</div>
+<div class="section" id="pathlinetoverticalabs">
+<h3>PathLinetoVerticalAbs</h3>
+<p>Draws a vertical line from the current point (cpx, cpy) to (cpx,
+y). <em>PathLinetoVerticalAbs</em> indicates that absolute coordinates are
+supplied. At the end of the command, the new current point becomes
+(cpx, y) for the final value of y:</p>
+<pre class="literal-block">
+PathLinetoVerticalAbs ( double y_ )
+</pre>
+</div>
+<div class="section" id="pathlinetoverticalrel">
+<h3>PathLinetoVerticalRel</h3>
+<p>Draws a vertical line from the current point (cpx, cpy) to (cpx, y).
+<em>PathLinetoVerticalRel</em> indicates that relative coordinates are
+supplied. At the end of the command, the new current point becomes
+(cpx, y) for the final value of y:</p>
+<pre class="literal-block">
+PathLinetoVerticalRel ( double y_ )
+</pre>
+</div>
+</div>
+<div class="section" id="curve-commands">
+<h2><a class="toc-backref" href="#id61">Curve commands</a></h2>
+<p>These three groups of commands draw curves:</p>
+<ul>
+<li><p class="first">Cubic Bézier commands.</p>
+<p>A cubic Bézier segment is defined by a start point, an end point,
+and two control points.</p>
+</li>
+<li><p class="first">Quadratic Bézier commands.</p>
+<p>A quadratic Bézier segment is defined by a start point, an end
+point, and one control point.</p>
+</li>
+<li><p class="first">Elliptical arc commands.</p>
+<p>An elliptical arc segment draws a segment of an ellipse.</p>
+</li>
+</ul>
+<div class="contents local topic" id="id4">
+<p class="topic-title first">Curve Commands</p>
+<ul class="simple">
+<li><a class="reference internal" href="#cubic-bezier-curve-commands" id="id62">Cubic Bézier curve commands</a></li>
+<li><a class="reference internal" href="#quadratic-bezier-curve-commands" id="id63">Quadratic Bézier curve commands</a></li>
+<li><a class="reference internal" href="#elliptical-arc-curve-commands" id="id64">Elliptical arc curve commands</a></li>
+</ul>
+</div>
+<div class="section" id="cubic-bezier-curve-commands">
+<h3><a class="toc-backref" href="#id62">Cubic Bézier curve commands</a></h3>
+<div class="contents local topic" id="id5">
+<p class="topic-title first">Cubic Bézier curve commands</p>
+<ul class="simple">
+<li><a class="reference internal" href="#pathcurvetoargs" id="id65">PathCurvetoArgs</a></li>
+<li><a class="reference internal" href="#pathcurvetoabs" id="id66">PathCurvetoAbs</a></li>
+<li><a class="reference internal" href="#pathcurvetorel" id="id67">PathCurvetoRel</a></li>
+<li><a class="reference internal" href="#pathsmoothcurvetoabs" id="id68">PathSmoothCurvetoAbs</a></li>
+<li><a class="reference internal" href="#pathsmoothcurvetorel" id="id69">PathSmoothCurvetoRel</a></li>
+</ul>
+</div>
+<div class="section" id="pathcurvetoargs">
+<h4><a class="toc-backref" href="#id65">PathCurvetoArgs</a></h4>
+<p>The cubic Bézier commands depend on the <a class="reference internal" href="#pathcurvetoargs">PathCurvetoArgs</a> argument
+class, which has the constructor signature:</p>
+<pre class="literal-block">
+PathCurvetoArgs( double x1_, double y1_,
+ double x2_, double y2_,
+ double x_, double y_ );
+</pre>
+<p>PathCurveto:</p>
+<p>Draws a cubic Bézier curve from the current point to (<em>x</em>,*y*) using
+(<em>x1</em>,*y1*) as the control point at the beginning of the curve and
+(<em>x2</em>,*y2*) as the control point at the end of the
+curve. <a class="reference internal" href="#pathcurvetoabs">PathCurvetoAbs</a> indicates that absolutecoordinates will follow;
+<a class="reference internal" href="#pathcurvetorel">PathCurvetoRel</a> indicates that relative coordinates will
+follow. Multiple sets of coordinates may be specified to draw a
+polybezier. At the end of the command, the new current point becomes
+the final (<em>x</em>,*y*) coordinate pair used in the polybezier.</p>
+</div>
+<div class="section" id="pathcurvetoabs">
+<h4><a class="toc-backref" href="#id66">PathCurvetoAbs</a></h4>
+<p>Draw a single curve:</p>
+<pre class="literal-block">
+PathCurvetoAbs ( const PathCurvetoArgs &amp;args_ );
+</pre>
+<p>Draw multiple curves:</p>
+<pre class="literal-block">
+PathCurvetoAbs ( const PathCurveToArgsList &amp;args_ );
+</pre>
+</div>
+<div class="section" id="pathcurvetorel">
+<h4><a class="toc-backref" href="#id67">PathCurvetoRel</a></h4>
+<p>Draw a single curve:</p>
+<pre class="literal-block">
+PathCurvetoRel ( const PathCurvetoArgs &amp;args_ );
+</pre>
+<p>Draw multiple curves:</p>
+<pre class="literal-block">
+PathCurvetoRel ( const PathCurveToArgsList &amp;args_ );
+</pre>
+<p>PathSmoothCurveto:</p>
+<p>Draws a cubic Bézier curve from the current point to (x,y). The first
+control point is assumed to be the reflection of the second control
+point on the previous command relative to the current point. (If there
+is no previous command or if the previous command was not an
+PathCurvetoAbs, PathCurvetoRel, PathSmoothCurvetoAbs or
+PathSmoothCurvetoRel, assume the first control point is coincident
+with the current point.) (x2,y2) is the second control point (i.e.,
+the control point at the end of the curve). PathSmoothCurvetoAbs
+indicates that absolute coordinates will follow; PathSmoothCurvetoRel
+indicates that relative coordinates will follow. Multiple sets of
+coordinates may be specified to draw a polybezier. At the end of the
+command, the new current point becomes the final (x,y) coordinate pair
+used in the polybezier.</p>
+</div>
+<div class="section" id="pathsmoothcurvetoabs">
+<h4><a class="toc-backref" href="#id68">PathSmoothCurvetoAbs</a></h4>
+<p>Draw a single curve:</p>
+<pre class="literal-block">
+PathSmoothCurvetoAbs ( const Magick::Coordinate &amp;coordinates_ );
+</pre>
+<p>Draw multiple curves</p>
+<blockquote>
+PathSmoothCurvetoAbs ( const CoordinateList &amp;coordinates_ );</blockquote>
+</div>
+<div class="section" id="pathsmoothcurvetorel">
+<h4><a class="toc-backref" href="#id69">PathSmoothCurvetoRel</a></h4>
+<p>Draw a single curve:</p>
+<pre class="literal-block">
+PathSmoothCurvetoRel ( const Coordinate &amp;coordinates_ );
+</pre>
+<p>Draw multiple curves:</p>
+<pre class="literal-block">
+PathSmoothCurvetoRel ( const CoordinateList &amp;coordinates_ );
+</pre>
+</div>
+</div>
+<div class="section" id="quadratic-bezier-curve-commands">
+<h3><a class="toc-backref" href="#id63">Quadratic Bézier curve commands</a></h3>
+<div class="contents local topic" id="id6">
+<p class="topic-title first">Quadratic Bézier curve commands</p>
+<ul class="simple">
+<li><a class="reference internal" href="#pathquadraticcurvetoargs" id="id70">PathQuadraticCurvetoArgs</a></li>
+<li><a class="reference internal" href="#pathquadraticcurvetoabs" id="id71">PathQuadraticCurvetoAbs</a></li>
+<li><a class="reference internal" href="#pathquadraticcurvetorel" id="id72">PathQuadraticCurvetoRel</a></li>
+<li><a class="reference internal" href="#pathsmoothquadraticcurvetoabs" id="id73">PathSmoothQuadraticCurvetoAbs</a></li>
+<li><a class="reference internal" href="#pathsmoothquadraticcurvetorel" id="id74">PathSmoothQuadraticCurvetoRel</a></li>
+</ul>
+</div>
+<div class="section" id="pathquadraticcurvetoargs">
+<h4><a class="toc-backref" href="#id70">PathQuadraticCurvetoArgs</a></h4>
+<p>The quadratic Bézier commands depend on the <a class="reference internal" href="#pathquadraticcurvetoargs">PathQuadraticCurvetoArgs</a>
+argument class, which has the constructor signature:</p>
+<pre class="literal-block">
+PathQuadraticCurvetoArgs( double x1_, double y1_,
+ double x_, double y_ );
+</pre>
+</div>
+<div class="section" id="pathquadraticcurvetoabs">
+<h4><a class="toc-backref" href="#id71">PathQuadraticCurvetoAbs</a></h4>
+<p>Draw a single curve:</p>
+<pre class="literal-block">
+PathQuadraticCurvetoAbs ( const Magick::PathQuadraticCurvetoArgs &amp;args_ );
+</pre>
+<p>Draw multiple curves:</p>
+<pre class="literal-block">
+PathQuadraticCurvetoAbs ( const PathQuadraticCurvetoArgsList &amp;args_ );
+</pre>
+</div>
+<div class="section" id="pathquadraticcurvetorel">
+<h4><a class="toc-backref" href="#id72">PathQuadraticCurvetoRel</a></h4>
+<p>Draw a single curve:</p>
+<pre class="literal-block">
+PathQuadraticCurvetoRel ( const Magick::PathQuadraticCurvetoArgs &amp;args_ );
+</pre>
+<p>Draw multiple curves:</p>
+<pre class="literal-block">
+PathQuadraticCurvetoRel ( const PathQuadraticCurvetoArgsList &amp;args_ );
+</pre>
+</div>
+<div class="section" id="pathsmoothquadraticcurvetoabs">
+<h4><a class="toc-backref" href="#id73">PathSmoothQuadraticCurvetoAbs</a></h4>
+<p>Draw a single curve:</p>
+<pre class="literal-block">
+PathSmoothQuadraticCurvetoAbs ( const Magick::Coordinate &amp;coordinate_ );
+</pre>
+<p>Draw multiple curves:</p>
+<pre class="literal-block">
+PathSmoothQuadraticCurvetoAbs ( const CoordinateList &amp;coordinates_ );
+</pre>
+</div>
+<div class="section" id="pathsmoothquadraticcurvetorel">
+<h4><a class="toc-backref" href="#id74">PathSmoothQuadraticCurvetoRel</a></h4>
+<p>Draw a single curve:</p>
+<pre class="literal-block">
+PathSmoothQuadraticCurvetoRel ( const Magick::Coordinate &amp;coordinate_ );
+</pre>
+<p>Draw multiple curves:</p>
+<pre class="literal-block">
+PathSmoothQuadraticCurvetoRel ( const CoordinateList &amp;coordinates_ );
+</pre>
+</div>
+</div>
+<div class="section" id="elliptical-arc-curve-commands">
+<h3><a class="toc-backref" href="#id64">Elliptical arc curve commands</a></h3>
+<div class="contents local topic" id="id7">
+<p class="topic-title first">Elliptical arc curve commands</p>
+<ul class="simple">
+<li><a class="reference internal" href="#patharcargs" id="id75">PathArcArgs</a></li>
+<li><a class="reference internal" href="#patharcabs" id="id76">PathArcAbs</a></li>
+<li><a class="reference internal" href="#patharcrel" id="id77">PathArcRel</a></li>
+</ul>
+</div>
+<div class="section" id="patharcargs">
+<h4><a class="toc-backref" href="#id75">PathArcArgs</a></h4>
+<p>The elliptical arc curve commands depend on the PathArcArgs argument
+class, which has the constructor signature:</p>
+<pre class="literal-block">
+PathArcArgs( double radiusX_, double radiusY_,
+ double xAxisRotation_, bool largeArcFlag_,
+ bool sweepFlag_, double x_, double y_ );
+</pre>
+<p>Draws an elliptical arc from the current point to (<em>x</em>, <em>y</em>). The size and
+orientation of the ellipse are defined by two radii (<em>radiusX</em>, <em>radiusY</em>)
+and an <em>xAxisRotation</em>, which indicates how the ellipse as a whole is
+rotated relative to the current coordinate system. The center (cx, cy)
+of the ellipse is calculated automatically to satisfy the constraints
+imposed by the other parameters. <em>largeArcFlag</em> and <em>sweepFlag</em> contribute
+to the automatic calculations and help determine how the arc is
+drawn. If <em>largeArcFlag</em> is true then draw the larger of the available
+arcs. If <em>sweepFlag</em> is true, then draw the arc matching a clock-wise
+rotation.</p>
+</div>
+<div class="section" id="patharcabs">
+<h4><a class="toc-backref" href="#id76">PathArcAbs</a></h4>
+<p>Draw a single arc segment:</p>
+<pre class="literal-block">
+PathArcAbs ( const PathArcArgs &amp;coordinates_ );
+</pre>
+<p>Draw multiple arc segments:</p>
+<pre class="literal-block">
+PathArcAbs ( const PathArcArgsList &amp;coordinates_ );
+</pre>
+</div>
+<div class="section" id="patharcrel">
+<h4><a class="toc-backref" href="#id77">PathArcRel</a></h4>
+<p>Draw a single arc segment:</p>
+<pre class="literal-block">
+PathArcRel ( const PathArcArgs &amp;coordinates_ );
+</pre>
+<p>Draw multiple arc segments:</p>
+<pre class="literal-block">
+PathArcRel ( const PathArcArgsList &amp;coordinates_ );
+</pre>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</div>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Drawable.rst b/www/Magick++/Drawable.rst
new file mode 100644
index 0000000..d5508d6
--- /dev/null
+++ b/www/Magick++/Drawable.rst
@@ -0,0 +1,1055 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+================
+Magick::Drawable
+================
+
+.. contents::
+ :depth: 1
+
+Drawable provides a convenient interface for preparing vector, image,
+or text arguments for the Image::draw() method. Each instance of a
+Drawable sub-class represents a single drawable object. Drawable
+objects may be drawn "one-by-one" via multiple invocations of the
+Image `draw() <Image.html#draw>`_ method, or may be drawn
+"all-at-once" by passing a list of Drawable objects to the Image
+`draw() <Image.html#draw>`_ method. The one-by-one approach is
+convenient for simple drawings, while the list-based approach is
+appropriate for drawings which require more sophistication.
+
+The following is an example using the Drawable subclasses with a
+one-by-one approach to draw the following figure:
+
+.. image:: Drawable_example_1.png
+ :width: 300
+ :height: 200
+ :alt: Figure showing drawing example
+
+::
+
+ #include <string>
+ #include <iostream>
+ #include <Magick++.h>
+
+ using namespace std;
+ using namespace Magick;
+
+ int main(int /*argc*/,char **argv)
+ {
+ try {
+ InitializeMagick(*argv);
+
+ // Create base image (white image of 300 by 200 pixels)
+ Image image( Geometry(300,200), Color("white") );
+
+ // Set draw options
+ image.strokeColor("red"); // Outline color
+ image.fillColor("green"); // Fill color
+ image.strokeWidth(5);
+
+ // Draw a circle
+ image.draw( DrawableCircle(100,100, 50,100) );
+
+ // Draw a rectangle
+ image.draw( DrawableRectangle(200,200, 270,170) );
+
+ // Display the result
+ image.display( );
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ return 0;
+ }
+
+Since Drawable is an object it may be saved in an array or a list for
+later (perhaps repeated) use. The following example shows how to draw
+the same figure using the list-based approach::
+
+ #include <string>
+ #include <iostream>
+ #include <list>
+ #include <Magick++.h>
+
+ using namespace std;
+ using namespace Magick;
+
+ int main(int /*argc*/,char **/*argv*/)
+ {
+ try {
+
+ InitializeMagick(*argv);
+
+ // Create base image (white image of 300 by 200 pixels)
+ Image image( Geometry(300,200), Color("white") );
+
+ // Construct drawing list
+ std::list<Magick::Drawable> drawList;
+
+ // Add some drawing options to drawing list
+ drawList.push_back(DrawableStrokeColor("red")); // Outline color
+ drawList.push_back(DrawableStrokeWidth(5)); // Stroke width
+ drawList.push_back(DrawableFillColor("green")); // Fill color
+
+ // Add a Circle to drawing list
+ drawList.push_back(DrawableCircle(100,100, 50,100));
+
+ // Add a Rectangle to drawing list
+ drawList.push_back(DrawableRectangle(200,100, 270,170));
+
+ // Draw everything using completed drawing list
+ image.draw(drawList);
+
+ // Display the result
+ image.display( );
+ }
+ catch( exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+
+ return 0;
+ }
+
+
+Coordinate structure
+--------------------
+
+Drawable depends on the simple Coordinate structure which represents a
+pair of x,y coodinates. The Coordinate structure is defined as
+follows::
+
+ class Coordinate
+ {
+ public:
+
+ // Default Constructor
+ Coordinate ( void );
+
+ // Constructor, setting first & second
+ Coordinate ( double x_, double y_ );
+
+ // Destructor
+ virtual ~Coordinate ();
+
+ // x coordinate member
+ void x ( double x_ );
+ double x ( void ) const;
+
+ // y coordinate member
+ void y ( double y_ );
+ double y ( void ) const;
+ };
+
+Drawable classes
+----------------
+
+Drawable classes represent objects to be drawn on the image.
+
+.. contents:: Drawable classes
+ :local:
+ :depth: 1
+
+DrawableAffine
+++++++++++++++
+
+Specify a transformation matrix to adjust scaling, rotation, and
+translation (coordinate transformation) for subsequently drawn objects
+in the same or decendent drawing context. The `sx_` & `sy_` parameters
+represent the x & y scale factors, the `rx_` & `ry_` parameters represent
+the x & y rotation, and the `tx_` & `ty_` parameters represent the x & y
+translation::
+
+ DrawableAffine ( double sx_, double sy_,
+ double rx_, double ry_,
+ double tx_, double ty_ );
+
+Specify a transformation matrix to adjust scaling, rotation, and
+translation (coordinate transformation) for subsequently drawn objects
+in the same or decendent drawing context. Initialized to unity (no
+effect) affine values. Use class methods (not currently documented but
+defined in the Drawable.h header file) to adjust individual parameters
+from their unity values::
+
+ DrawableAffine ( void );
+
+
+DrawableArc
++++++++++++
+
+Draw an arc using the stroke color and based on the circle starting at
+coordinates `startX_`,`startY_`, and ending with coordinates
+`endX_`,`endY_`, and bounded by the rotational arc
+`startDegrees_`,`endDegrees_`::
+
+ DrawableArc ( double startX_, double startY_,
+ double endX_, double endY_,
+ double startDegrees_, double endDegrees_ );
+
+DrawableBezier
+++++++++++++++
+
+Draw a bezier curve using the stroke color and based on the
+coordinates specified by the `coordinates_` list::
+
+ DrawableBezier ( const CoordinateList &coordinates_ );
+
+DrawableClipPath
+++++++++++++++++
+
+Select a drawing clip path matching `id_`::
+
+ DrawableClipPath ( const std::string &id_ );
+
+DrawableCircle
+++++++++++++++
+
+Draw a circle using the stroke color and thickness using specified
+origin and perimeter coordinates. If a fill color is specified, then
+the object is filled::
+
+ DrawableCircle ( double originX_, double originY_,
+ double perimX_, double perimY_ )
+
+
+DrawableColor
++++++++++++++
+
+Color image according to paintMethod. The point method recolors the
+target pixel. The replace method recolors any pixel that matches the
+color of the target pixel. Floodfill recolors any pixel that matches
+the color of the target pixel and is a neighbor, whereas filltoborder
+recolors any neighbor pixel that is not the border color. Finally,
+reset recolors all pixels::
+
+ DrawableColor ( double x_, double y_,
+ PaintMethod paintMethod_ )
+
+
+DrawableCompositeImage
+++++++++++++++++++++++
+
+Composite current image with contents of specified image, at specified
+coordinates. If the matte attribute is set to true, then the image
+composition will consider an alpha channel, or transparency, present
+in the image file so that non-opaque portions allow part (or all) of
+the composite image to show through::
+
+ DrawableCompositeImage ( double x_, double y_,
+ const std::string &filename_ );
+ DrawableCompositeImage ( double x_, double y_,
+ const Image &image_ );
+
+Composite current image with contents of specified image, rendered
+with specified width and height, at specified coordinates. If the
+matte attribute is set to true, then the image composition will
+consider an alpha channel, or transparency, present in the image file
+so that non-opaque portions allow part (or all) of the composite image
+to show through. If the specified width or height is zero, then the
+image is composited at its natural size, without enlargement or
+reduction::
+
+ DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const std::string &filename_ );
+
+ DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const Image &image_ );
+
+Composite current image with contents of specified image, rendered
+with specified width and height, using specified composition
+algorithm, at specified coordinates. If the matte attribute is set to
+true, then the image composition will consider an alpha channel, or
+transparency, present in the image file so that non-opaque portions
+allow part (or all) of the composite image to show through. If the
+specified width or height is zero, then the image is composited at its
+natural size, without enlargement or reduction::
+
+ DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const std::string &filename_,
+ CompositeOperator composition_ );
+
+ DrawableCompositeImage ( double x_, double y_,
+ double width_, double height_,
+ const Image &image_,
+ CompositeOperator composition_ );
+
+
+DrawableDashArray
++++++++++++++++++
+
+Specify the pattern of dashes and gaps used to stroke paths. The
+strokeDashArray represents a zero-terminated array of numbers that
+specify the lengths of alternating dashes and gaps in pixels. If an
+odd number of values is provided, then the list of values is repeated
+to yield an even number of values. A typical `strokeDashArray_` array
+might contain the members 5 3 2 0, where the zero value indicates the
+end of the pattern array::
+
+ DrawableDashArray( const double* dasharray_ );
+
+DrawableDashOffset
+++++++++++++++++++
+
+Specify the distance into the dash pattern to start the dash. See
+documentation on SVG's `stroke-dashoffset
+<http://www.w3.org/TR/SVG/painting.html#StrokeDashoffsetProperty>`_
+property for usage details::
+
+ DrawableDashOffset ( const double offset_ )
+
+DrawableEllipse
++++++++++++++++
+
+Draw an ellipse using the stroke color and thickness, specified
+origin, x & y radius, as well as specified start and end of arc in
+degrees. If a fill color is specified, then the object is filled::
+
+ DrawableEllipse ( double originX_, double originY_,
+ double radiusX_, double radiusY_,
+ double arcStart_, double arcEnd_ )
+
+DrawableFillColor
++++++++++++++++++
+
+Specify drawing object fill color:
+
+ DrawableFillColor ( const Color &color_ );
+
+DrawableFillRule
+++++++++++++++++
+
+Specify the algorithm which is to be used to determine what parts of
+the canvas are included inside the shape. See documentation on SVG's
+`fill-rule <http://www.w3.org/TR/SVG/painting.html#FillRuleProperty>`_
+property for usage details::
+
+ DrawableFillRule ( const FillRule fillRule_ )
+
+DrawableFillOpacity
++++++++++++++++++++
+
+Specify opacity to use when drawing using fill color::
+
+ DrawableFillOpacity ( double opacity_ )
+
+DrawableFont
+++++++++++++
+
+Specify font family, style, weight (one of the set { 100 | 200 | 300 |
+400 | 500 | 600 | 700 | 800 | 900 } with 400 being the normal size),
+and stretch to be used to select the font used when drawing
+text. Wildcard matches may be applied to style via the AnyStyle
+enumeration, applied to weight if weight is zero, and applied to
+stretch via the AnyStretch enumeration::
+
+ DrawableFont ( const std::string &font_ );
+
+ DrawableFont ( const std::string &family_,
+ StyleType style_,
+ const unsigned long weight_,
+ StretchType stretch_ );
+
+DrawableGravity
++++++++++++++++
+
+Specify text positioning gravity::
+
+ DrawableGravity ( GravityType gravity_ )
+
+DrawableLine
+++++++++++++
+
+Draw a line using stroke color and thickness using starting and ending
+coordinates::
+
+ DrawableLine ( double startX_, double startY_,
+ double endX_, double endY_ )
+
+DrawableMatte
++++++++++++++
+
+Change the pixel matte value to transparent. The point method changes
+the matte value of the target pixel. The replace method changes the
+matte value of any pixel that matches the color of the target
+pixel. Floodfill changes the matte value of any pixel that matches the
+color of the target pixel and is a neighbor, whereas filltoborder
+changes the matte value of any neighbor pixel that is not the border
+color, Finally reset changes the matte value of all pixels::
+
+ DrawableMatte ( double x_, double y_,
+ PaintMethod paintMethod_ )
+
+DrawableMiterLimit
+++++++++++++++++++
+
+Specify miter limit. When two line segments meet at a sharp angle and
+miter joins have been specified for 'lineJoin', it is possible for the
+miter to extend far beyond the thickness of the line stroking the
+path. The miterLimit' imposes a limit on the ratio of the miter length
+to the 'lineWidth'. The default value of this parameter is 4::
+
+ DrawableMiterLimit ( unsigned int miterlimit_ )
+
+DrawablePath
+++++++++++++
+
+Draw on image using vector path::
+
+ DrawablePath ( const VPathList &path_ );
+
+DrawablePoint
++++++++++++++
+
+Draw a point using stroke color and thickness at coordinate::
+
+ DrawablePoint ( double x_, double y_ )
+
+DrawablePointSize
++++++++++++++++++
+
+Set font point size::
+
+ DrawablePointSize ( double pointSize_ )
+
+DrawablePolygon
++++++++++++++++
+
+Draw an arbitrary polygon using stroke color and thickness consisting
+of three or more coordinates contained in an STL list. If a fill color
+is specified, then the object is filled::
+
+ DrawablePolygon ( const CoordinateList &coordinates_ )
+
+DrawablePolyline
+++++++++++++++++
+
+Draw an arbitrary polyline using stroke color and thickness consisting
+of three or more coordinates contained in an STL list. If a fill color
+is specified, then the object is filled::
+
+ DrawablePolyline ( const CoordinateList &coordinates_ )
+
+DrawablePopClipPath
++++++++++++++++++++
+
+Pop (terminate) clip path definition started by DrawablePushClipPath::
+
+ DrawablePopClipPath ( void )
+
+DrawablePopGraphicContext
++++++++++++++++++++++++++
+
+Pop Graphic Context. Removing the current graphic context from the
+graphic context stack restores the options to the values they had
+prior to the preceding DrawablePushGraphicContext_ operation::
+
+ DrawablePopGraphicContext ( void )
+
+DrawablePushClipPath
+++++++++++++++++++++
+
+Push (create) clip path definition with `id_`. Clip patch definition
+consists of subsequent drawing commands, terminated by
+DrawablePopClipPath_::
+
+ DrawablePushClipPath ( const std::string &id_)
+
+DrawablePushGraphicContext
+++++++++++++++++++++++++++
+
+Push Graphic Context. When a graphic context is pushed, options set
+after the context is pushed (such as coordinate transformations, color
+settings, etc.) are saved to a new graphic context. This allows
+related options to be saved on a graphic context "stack" in order to
+support heirarchical nesting of options. When
+DrawablePopGraphicContext_ is used to pop the current graphic context,
+the options in effect during the last DrawablePushGraphicContext_
+operation are restored::
+
+ DrawablePushGraphicContext ( void )
+
+DrawablePushPattern
++++++++++++++++++++
+
+Start a pattern definition with arbitrary pattern name specified by
+`id_`, pattern offset specified by `x_` and `y_`, and pattern size
+specified by `width_` and `height_`. The pattern is defined within the
+coordinate system defined by the specified offset and size. Arbitrary
+drawing objects (including DrawableCompositeImage_) may be specified
+between DrawablePushPattern_ and DrawablePopPattern_ in order to draw
+the pattern. Normally the pair DrawablePushGraphicContext_ &
+DrawablePopGraphicContext_ are used to enclose a pattern
+definition. Pattern definitions are terminated by a
+DrawablePopPattern_ object::
+
+ DrawablePushPattern ( const std::string &id_, long x_, long y_,
+ long width_, long height_ )
+
+
+DrawablePopPattern
+++++++++++++++++++
+
+Terminate a pattern definition started via DrawablePushPattern_::
+
+ DrawablePopPattern ( void )
+
+DrawableRectangle
++++++++++++++++++
+
+Draw a rectangle using stroke color and thickness from upper-left
+coordinates to lower-right coordinates. If a fill color is specified,
+then the object is filled::
+
+ DrawableRectangle ( double upperLeftX_, double upperLeftY_,
+ double lowerRightX_, double lowerRightY_ )
+
+DrawableRotation
+++++++++++++++++
+
+Set rotation to use when drawing (coordinate transformation)::
+
+ DrawableRotation ( double angle_ )
+
+DrawableRoundRectangle
+++++++++++++++++++++++
+
+Draw a rounded rectangle using stroke color and thickness, with
+specified center coordinate, specified width and height, and specified
+corner width and height. If a fill color is specified, then the
+object is filled::
+
+ DrawableRoundRectangle ( double centerX_, double centerY_,
+ double width_, double hight_,
+ double cornerWidth_, double cornerHeight_ )
+
+DrawableScaling
++++++++++++++++
+
+Apply scaling in x and y direction while drawing objects (coordinate
+transformation)::
+
+ DrawableScaling ( double x_, double y_ )
+
+DrawableSkewX
++++++++++++++
+
+Apply Skew in X direction (coordinate transformation)::
+
+ DrawableSkewX ( double angle_ )
+
+DrawableSkewY
++++++++++++++
+
+Apply Skew in Y direction::
+
+ DrawableSkewY ( double angle_ )
+
+DrawableStrokeAntialias
++++++++++++++++++++++++
+
+Antialias while drawing lines or object outlines::
+
+ DrawableStrokeAntialias ( bool flag_ )
+
+DrawableStrokeColor
++++++++++++++++++++
+
+Set color to use when drawing lines or object outlines::
+
+ DrawableStrokeColor ( const Color &color_ )
+
+DrawableStrokeLineCap
++++++++++++++++++++++
+
+Specify the shape to be used at the end of open subpaths when they are
+stroked. Values of LineCap are UndefinedCap, ButtCap, RoundCap, and
+SquareCap::
+
+ DrawableStrokeLineCap ( LineCap linecap_ )
+
+DrawableStrokeLineJoin
+++++++++++++++++++++++
+
+Specify the shape to be used at the corners of paths (or other vector
+shapes) when they are stroked. Values of LineJoin are UndefinedJoin,
+MiterJoin, RoundJoin, and BevelJoin::
+
+ DrawableStrokeLineJoin ( LineJoin linejoin_ )
+
+DrawableStrokeOpacity
++++++++++++++++++++++
+
+Opacity to use when drawing lines or object outlines::
+
+ DrawableStrokeOpacity ( double opacity_ )
+
+DrawableStrokeWidth
++++++++++++++++++++
+
+Set width to use when drawing lines or object outlines::
+
+ DrawableStrokeWidth ( double width_ )
+
+DrawableText
+++++++++++++
+
+Annotate image with text using stroke color, font, font pointsize, and
+box color (text background color), at specified coordinates. If text
+contains `special format characters <FormatCharacters.html>`_ the
+image filename, type, width, height, or other image attributes may be
+incorporated in the text (see label())::
+
+ DrawableText ( const double x_, const double y_,
+ const std::string &text_ )
+
+Annotate image with text represented with text encoding, using current
+stroke color, font, font pointsize, and box color (text background
+color), at specified coordinates. If text contains `special format
+characters <FormatCharacters.html>`_ the image filename, type, width,
+height, or other image attributes may be incorporated in the text (see
+label()).
+
+The text encoding specifies the code set to use for text
+annotations. The only character encoding which may be specified at
+this time is "UTF-8" for representing `Unicode
+<http://www.unicode.org/>`_ as a sequence of bytes. Specify an empty
+string to set text encoding to the system's default. Successful text
+annotation using Unicode may require fonts designed to support
+Unicode::
+
+ DrawableText ( const double x_, const double y_,
+ const std::string &text_, const std::string &encoding_)
+
+DrawableTextAntialias
++++++++++++++++++++++
+
+Antialias while drawing text (default true). The main reason to
+disable text antialiasing is to avoid adding new colors to the image::
+
+ DrawableTextAntialias ( bool flag_ )
+
+DrawableTextDecoration
+++++++++++++++++++++++
+
+Specify decoration (e.g. UnderlineDecoration) to apply to text::
+
+ DrawableTextDecoration ( DecorationType decoration_ )
+
+DrawableTextUnderColor
+++++++++++++++++++++++
+
+Draw a box under rendered text using the specified color::
+
+ DrawableTextUnderColor ( const Color &color_ )
+
+DrawableTranslation
++++++++++++++++++++
+
+Apply coordinate translation (set new coordinate origin)::
+
+ DrawableTranslation ( double x_, double y_ )
+
+DrawableViewbox
++++++++++++++++
+
+Dimensions of the output viewbox. If the image is to be written to a
+vector format (e.g. MVG or SVG), then a DrawablePushGraphicContext_
+object should be pushed to the head of the list, followed by a
+DrawableViewbox_ object to establish the output canvas size. A
+matching DrawablePopGraphicContext_ object should be pushed to the
+tail of the list::
+
+ DrawableViewbox(unsigned long x1_, unsigned long y1_,
+ unsigned long x2_, unsigned long y2_)
+
+Vector Path Classes
+-------------------
+
+The vector paths supported by Magick++ are based on those supported by
+the `SVG XML specification
+<http://www.w3.org/TR/SVG/paths.html>`_. Vector paths are not directly
+drawable, they must first be supplied as a constructor argument to the
+DrawablePath_ class in order to create a drawable object. The
+DrawablePath_ class effectively creates a drawable compound component
+which may be replayed as desired. If the drawable compound component
+consists only of vector path objects using relative coordinates then
+the object may be positioned on the image by preceding it with a
+DrawablePath_ which sets the current drawing coordinate. Alternatively
+coordinate transforms may be used to `translate the origin
+<#DrawableTranslation>`_ in order to position the object, rotate it,
+skew it, or scale it.
+
+.. contents:: Vector path commands
+ :local:
+ :depth: 1
+
+The "moveto" commands
++++++++++++++++++++++
+
+The "moveto" commands establish a new current point. The effect is as
+if the "pen" were lifted and moved to a new location. A path data
+segment must begin with either one of the "moveto" commands or one of
+the "arc" commands. Subsequent "moveto" commands (i.e., when the
+"moveto" is not the first command) represent the start of a new
+subpath.
+
+Start a new sub-path at the given coordinate. PathMovetoAbs indicates
+that absolute coordinates will follow; PathMovetoRel indicates that
+relative coordinates will follow. If a relative moveto appears as the
+first element of the path, then it is treated as a pair of absolute
+coordinates. If a moveto is followed by multiple pairs of coordinates,
+the subsequent pairs are treated as implicit lineto commands.
+
+PathMovetoAbs
+~~~~~~~~~~~~~
+
+Simple moveto::
+
+ PathMovetoAbs ( const Magick::Coordinate &coordinate_ )
+
+Moveto followed by implicit linetos::
+
+ PathMovetoAbs ( const CoordinateList &coordinates_ )
+
+PathMovetoRel
+~~~~~~~~~~~~~
+
+Simple moveto::
+
+ PathMovetoRel ( const Magick::Coordinate &coordinate_ );
+
+Moveto followed by implicit linetos::
+
+ PathMovetoRel ( const CoordinateList &coordinates_ );
+
+The "closepath" command
++++++++++++++++++++++++
+
+The "closepath" command causes an automatic straight line to be drawn from the current point to the initial point of the current subpath.
+
+PathClosePath
+~~~~~~~~~~~~~
+
+Close the current subpath by drawing a straight line from the current
+point to current subpath's most recent starting point (usually, the
+most recent moveto point)::
+
+ PathClosePath ( void )
+
+The "lineto" commands
++++++++++++++++++++++
+
+The various "lineto" commands draw straight lines from the current
+point to a new point.
+
+PathLinetoAbs
+~~~~~~~~~~~~~
+
+Draw a line from the current point to the given coordinate which
+becomes the new current point. *PathLinetoAbs* indicates that absolute
+coordinates are used. A number of coordinates pairs may be specified
+in a list to draw a polyline. At the end of the command, the new
+current point is set to the final set of coordinates provided.
+
+Draw to a single point::
+
+ PathLinetoAbs ( const Magick::Coordinate& coordinate_ );
+
+Draw to multiple points::
+
+ PathLinetoAbs ( const CoordinateList &coordinates_ );
+
+PathLinetoRel
+~~~~~~~~~~~~~
+
+Draw a line from the current point to the given coordinate which
+becomes the new current point. *PathLinetoRel* indicates that relative
+coordinates are used. A number of coordinates pairs may be specified
+in a list to draw a polyline. At the end of the command, the new
+current point is set to the final set of coordinates provided.
+
+Draw to a single point::
+
+ PathLinetoRel ( const Magick::Coordinate& coordinate_ );
+
+Draw to multiple points::
+
+ PathLinetoRel ( const CoordinateList &coordinates_ );
+
+PathLinetoHorizontalAbs
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Draws a horizontal line from the current point (cpx, cpy) to (x,
+cpy). *PathLinetoHorizontalAbs* indicates that absolute coordinates
+are supplied. At the end of the command, the new current point
+becomes (x, cpy) for the final value of x::
+
+ PathLinetoHorizontalAbs ( double x_ )
+
+PathLinetoHorizontalRel
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Draws a horizontal line from the current point (cpx, cpy) to (x,
+cpy). *PathLinetoHorizontalRel* indicates that relative coordinates
+are supplied. At the end of the command, the new current point becomes
+(x, cpy) for the final value of x::
+
+ PathLinetoHorizontalRel ( double x_ )
+
+PathLinetoVerticalAbs
+~~~~~~~~~~~~~~~~~~~~~
+
+Draws a vertical line from the current point (cpx, cpy) to (cpx,
+y). *PathLinetoVerticalAbs* indicates that absolute coordinates are
+supplied. At the end of the command, the new current point becomes
+(cpx, y) for the final value of y::
+
+ PathLinetoVerticalAbs ( double y_ )
+
+PathLinetoVerticalRel
+~~~~~~~~~~~~~~~~~~~~~
+
+Draws a vertical line from the current point (cpx, cpy) to (cpx, y).
+*PathLinetoVerticalRel* indicates that relative coordinates are
+supplied. At the end of the command, the new current point becomes
+(cpx, y) for the final value of y::
+
+ PathLinetoVerticalRel ( double y_ )
+
+Curve commands
+++++++++++++++
+
+These three groups of commands draw curves:
+
+* Cubic Bézier commands.
+
+ A cubic Bézier segment is defined by a start point, an end point,
+ and two control points.
+
+* Quadratic Bézier commands.
+
+ A quadratic Bézier segment is defined by a start point, an end
+ point, and one control point.
+
+* Elliptical arc commands.
+
+ An elliptical arc segment draws a segment of an ellipse.
+
+.. contents:: Curve Commands
+ :local:
+ :depth: 1
+
+
+Cubic Bézier curve commands
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. contents:: Cubic Bézier curve commands
+ :local:
+ :depth: 1
+
+PathCurvetoArgs
+```````````````
+
+The cubic Bézier commands depend on the PathCurvetoArgs_ argument
+class, which has the constructor signature::
+
+ PathCurvetoArgs( double x1_, double y1_,
+ double x2_, double y2_,
+ double x_, double y_ );
+
+PathCurveto:
+
+Draws a cubic Bézier curve from the current point to (*x*,*y*) using
+(*x1*,*y1*) as the control point at the beginning of the curve and
+(*x2*,*y2*) as the control point at the end of the
+curve. PathCurvetoAbs_ indicates that absolutecoordinates will follow;
+PathCurvetoRel_ indicates that relative coordinates will
+follow. Multiple sets of coordinates may be specified to draw a
+polybezier. At the end of the command, the new current point becomes
+the final (*x*,*y*) coordinate pair used in the polybezier.
+
+PathCurvetoAbs
+``````````````
+
+Draw a single curve::
+
+ PathCurvetoAbs ( const PathCurvetoArgs &args_ );
+
+Draw multiple curves::
+
+ PathCurvetoAbs ( const PathCurveToArgsList &args_ );
+
+PathCurvetoRel
+``````````````
+
+Draw a single curve::
+
+ PathCurvetoRel ( const PathCurvetoArgs &args_ );
+
+Draw multiple curves::
+
+ PathCurvetoRel ( const PathCurveToArgsList &args_ );
+
+PathSmoothCurveto:
+
+Draws a cubic Bézier curve from the current point to (x,y). The first
+control point is assumed to be the reflection of the second control
+point on the previous command relative to the current point. (If there
+is no previous command or if the previous command was not an
+PathCurvetoAbs, PathCurvetoRel, PathSmoothCurvetoAbs or
+PathSmoothCurvetoRel, assume the first control point is coincident
+with the current point.) (x2,y2) is the second control point (i.e.,
+the control point at the end of the curve). PathSmoothCurvetoAbs
+indicates that absolute coordinates will follow; PathSmoothCurvetoRel
+indicates that relative coordinates will follow. Multiple sets of
+coordinates may be specified to draw a polybezier. At the end of the
+command, the new current point becomes the final (x,y) coordinate pair
+used in the polybezier.
+
+PathSmoothCurvetoAbs
+````````````````````
+
+Draw a single curve::
+
+ PathSmoothCurvetoAbs ( const Magick::Coordinate &coordinates_ );
+
+Draw multiple curves
+
+ PathSmoothCurvetoAbs ( const CoordinateList &coordinates_ );
+
+PathSmoothCurvetoRel
+````````````````````
+
+Draw a single curve::
+
+ PathSmoothCurvetoRel ( const Coordinate &coordinates_ );
+
+Draw multiple curves::
+
+ PathSmoothCurvetoRel ( const CoordinateList &coordinates_ );
+
+Quadratic Bézier curve commands
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. contents:: Quadratic Bézier curve commands
+ :local:
+ :depth: 1
+
+PathQuadraticCurvetoArgs
+````````````````````````
+
+The quadratic Bézier commands depend on the PathQuadraticCurvetoArgs_
+argument class, which has the constructor signature::
+
+ PathQuadraticCurvetoArgs( double x1_, double y1_,
+ double x_, double y_ );
+
+
+PathQuadraticCurvetoAbs
+```````````````````````
+
+Draw a single curve::
+
+ PathQuadraticCurvetoAbs ( const Magick::PathQuadraticCurvetoArgs &args_ );
+
+Draw multiple curves::
+
+ PathQuadraticCurvetoAbs ( const PathQuadraticCurvetoArgsList &args_ );
+
+PathQuadraticCurvetoRel
+```````````````````````
+
+Draw a single curve::
+
+ PathQuadraticCurvetoRel ( const Magick::PathQuadraticCurvetoArgs &args_ );
+
+Draw multiple curves::
+
+ PathQuadraticCurvetoRel ( const PathQuadraticCurvetoArgsList &args_ );
+
+PathSmoothQuadraticCurvetoAbs
+`````````````````````````````
+
+Draw a single curve::
+
+ PathSmoothQuadraticCurvetoAbs ( const Magick::Coordinate &coordinate_ );
+
+Draw multiple curves::
+
+ PathSmoothQuadraticCurvetoAbs ( const CoordinateList &coordinates_ );
+
+PathSmoothQuadraticCurvetoRel
+`````````````````````````````
+
+Draw a single curve::
+
+ PathSmoothQuadraticCurvetoRel ( const Magick::Coordinate &coordinate_ );
+
+
+Draw multiple curves::
+
+ PathSmoothQuadraticCurvetoRel ( const CoordinateList &coordinates_ );
+
+Elliptical arc curve commands
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. contents:: Elliptical arc curve commands
+ :local:
+ :depth: 1
+
+PathArcArgs
+```````````
+
+The elliptical arc curve commands depend on the PathArcArgs argument
+class, which has the constructor signature::
+
+ PathArcArgs( double radiusX_, double radiusY_,
+ double xAxisRotation_, bool largeArcFlag_,
+ bool sweepFlag_, double x_, double y_ );
+
+Draws an elliptical arc from the current point to (*x*, *y*). The size and
+orientation of the ellipse are defined by two radii (*radiusX*, *radiusY*)
+and an *xAxisRotation*, which indicates how the ellipse as a whole is
+rotated relative to the current coordinate system. The center (cx, cy)
+of the ellipse is calculated automatically to satisfy the constraints
+imposed by the other parameters. *largeArcFlag* and *sweepFlag* contribute
+to the automatic calculations and help determine how the arc is
+drawn. If *largeArcFlag* is true then draw the larger of the available
+arcs. If *sweepFlag* is true, then draw the arc matching a clock-wise
+rotation.
+
+PathArcAbs
+``````````
+
+Draw a single arc segment::
+
+ PathArcAbs ( const PathArcArgs &coordinates_ );
+
+Draw multiple arc segments::
+
+ PathArcAbs ( const PathArcArgsList &coordinates_ );
+
+PathArcRel
+``````````
+
+Draw a single arc segment::
+
+ PathArcRel ( const PathArcArgs &coordinates_ );
+
+Draw multiple arc segments::
+
+ PathArcRel ( const PathArcArgsList &coordinates_ );
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/Drawable_example_1.png b/www/Magick++/Drawable_example_1.png
new file mode 100644
index 0000000..50e2045
--- /dev/null
+++ b/www/Magick++/Drawable_example_1.png
Binary files differ
diff --git a/www/Magick++/Enumerations.html b/www/Magick++/Enumerations.html
new file mode 100644
index 0000000..662f514
--- /dev/null
+++ b/www/Magick++/Enumerations.html
@@ -0,0 +1,1321 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Enumerations</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="enumerations">
+<h1 class="title">Enumerations</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents topic" id="magick-enumerations">
+<p class="topic-title first">Magick++ Enumerations</p>
+<ul class="simple">
+<li><a class="reference internal" href="#channeltype" id="id2">ChannelType</a></li>
+<li><a class="reference internal" href="#classtype" id="id3">ClassType</a></li>
+<li><a class="reference internal" href="#colorspacetype" id="id4">ColorspaceType</a></li>
+<li><a class="reference internal" href="#compositeoperator" id="id5">CompositeOperator</a></li>
+<li><a class="reference internal" href="#compressiontype" id="id6">CompressionType</a></li>
+<li><a class="reference internal" href="#decorationtype" id="id7">DecorationType</a></li>
+<li><a class="reference internal" href="#endiantype" id="id8">EndianType</a></li>
+<li><a class="reference internal" href="#fillrule" id="id9">FillRule</a></li>
+<li><a class="reference internal" href="#filtertypes" id="id10">FilterTypes</a></li>
+<li><a class="reference internal" href="#gravitytype" id="id11">GravityType</a></li>
+<li><a class="reference internal" href="#imagetype" id="id12">ImageType</a></li>
+<li><a class="reference internal" href="#interlacetype" id="id13">InterlaceType</a></li>
+<li><a class="reference internal" href="#id1" id="id14">ChannelType</a></li>
+<li><a class="reference internal" href="#linecap" id="id15">LineCap</a></li>
+<li><a class="reference internal" href="#linejoin" id="id16">LineJoin</a></li>
+<li><a class="reference internal" href="#noisetype" id="id17">NoiseType</a></li>
+<li><a class="reference internal" href="#orientationtype" id="id18">OrientationType</a></li>
+<li><a class="reference internal" href="#paintmethod" id="id19">PaintMethod</a></li>
+<li><a class="reference internal" href="#quantumtypes" id="id20">QuantumTypes</a></li>
+<li><a class="reference internal" href="#renderingintent" id="id21">RenderingIntent</a></li>
+<li><a class="reference internal" href="#resolutiontype" id="id22">ResolutionType</a></li>
+<li><a class="reference internal" href="#storagetype" id="id23">StorageType</a></li>
+<li><a class="reference internal" href="#stretchtype" id="id24">StretchType</a></li>
+<li><a class="reference internal" href="#styletype" id="id25">StyleType</a></li>
+</ul>
+</div>
+<div class="section" id="channeltype">
+<h1><a class="toc-backref" href="#id2">ChannelType</a></h1>
+<p><em>ChannelType</em> is used as an argument when doing color separations. Use
+<em>ChannelType</em> when extracting a layer from an image. <em>MatteChannel</em> is
+useful for extracting the opacity values from an image. Note that an
+image may be represented in RGB, RGBA, CMYK, or CMYKA, pixel formats
+and a channel may only be extracted if it is valid for the current
+pixel format.</p>
+<table border="1" class="docutils">
+<caption>ChannelType</caption>
+<colgroup>
+<col width="30%" />
+<col width="70%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedChannel</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>RedChannel</td>
+<td>RGB Red channel</td>
+</tr>
+<tr><td>CyanChannel</td>
+<td>CMYK Cyan channel</td>
+</tr>
+<tr><td>GreenChannel</td>
+<td>RGB Green channel</td>
+</tr>
+<tr><td>MagentaChannel</td>
+<td>CMYK Magenta channel</td>
+</tr>
+<tr><td>BlueChannel</td>
+<td>RGB Blue channel</td>
+</tr>
+<tr><td>YellowChannel</td>
+<td>CMYK Yellow channel</td>
+</tr>
+<tr><td>OpacityChannel</td>
+<td>Opacity channel (inverse of transparency)</td>
+</tr>
+<tr><td>BlackChannel</td>
+<td>CMYK Black (K) channel</td>
+</tr>
+<tr><td>MatteChannel</td>
+<td>Same as Opacity channel (deprecated)</td>
+</tr>
+<tr><td>AllChannels</td>
+<td>All color channels</td>
+</tr>
+<tr><td>GrayChannel</td>
+<td>Color channels represent an intensity</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="classtype">
+<h1><a class="toc-backref" href="#id3">ClassType</a></h1>
+<p><em>ClassType</em> specifies the image storage class.</p>
+<table border="1" class="docutils">
+<caption>ClassType</caption>
+<colgroup>
+<col width="30%" />
+<col width="70%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedClass</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>DirectClass</td>
+<td>Image is composed of pixels which represent
+literal color values.</td>
+</tr>
+<tr><td>PseudoClass</td>
+<td>Image is composed of pixels which specify an index
+in a color palette.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="colorspacetype">
+<h1><a class="toc-backref" href="#id4">ColorspaceType</a></h1>
+<p>The <em>ColorspaceType</em> enumeration is used to specify the colorspace that
+quantization (color reduction and mapping) is done under or to specify
+the colorspace when encoding an output image. Colorspaces are ways of
+describing colors to fit the requirements of a particular application
+(e.g. Television, offset printing, color monitors). Color reduction,
+by default, takes place in the <em>RGBColorspace</em>. Empirical evidence
+suggests that distances in color spaces such as <em>YUVColorspace</em> or
+<em>YIQColorspace</em> correspond to perceptual color differences more closely
+han do distances in RGB space. These color spaces may give better
+results when color reducing an image. Refer to quantize for more
+details.</p>
+<p>When encoding an output image, the colorspaces <em>RGBColorspace</em>,
+<em>CMYKColorspace</em>, <em>GRAYColorspace</em>, or <em>YCbCrColorspace</em> may be
+specified. The CMYKColorspace option is only applicable when writing
+TIFF, JPEG, and Adobe Photoshop bitmap (PSD) files.</p>
+<table border="1" class="docutils">
+<caption>ColorspaceType</caption>
+<colgroup>
+<col width="29%" />
+<col width="71%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedColorspace</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>RGBColorspace</td>
+<td>Red-Green-Blue colorspace.</td>
+</tr>
+<tr><td>GRAYColorspace</td>
+<td>Grayscale colorspace</td>
+</tr>
+<tr><td>TransparentColorspace</td>
+<td>The Transparent color space behaves uniquely in
+that it preserves the matte channel of the image
+if it exists.</td>
+</tr>
+<tr><td>OHTAColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>XYZColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>YCbCrColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>YCCColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>YIQColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>YPbPrColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>YUVColorspace</td>
+<td>Y-signal, U-signal, and V-signal colorspace. YUV is
+most widely used to encode color for use in
+television transmission.</td>
+</tr>
+<tr><td>CMYKColorspace</td>
+<td>Cyan-Magenta-Yellow-Black colorspace. CYMK is a
+subtractive color system used by printers and
+photographers for the rendering of colors with ink
+or emulsion,
+normally on a white surface.</td>
+</tr>
+<tr><td>sRGBColorspace</td>
+<td>Kodak PhotoCD sRGB</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="compositeoperator">
+<h1><a class="toc-backref" href="#id5">CompositeOperator</a></h1>
+<p><em>CompositeOperator</em> is used to select the image composition algorithm
+used to compose a composite image with an image. By default, each of
+the composite image pixels are replaced by the corresponding image
+tile pixel. Specify <em>CompositeOperator</em> to select a different
+algorithm.</p>
+<table border="1" class="docutils">
+<caption>CompositeOperator</caption>
+<colgroup>
+<col width="31%" />
+<col width="69%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedCompositeOp</td>
+<td>Not defined.</td>
+</tr>
+<tr><td>OverCompositeOp</td>
+<td>Union of the two image shapes, with
+opaque areas of change-image obscuring base-image
+in the region of overlap.</td>
+</tr>
+<tr><td>InCompositeOp</td>
+<td>Change-image cut by the shape of base-image.
+None of the image data of base-image will be
+in the result.</td>
+</tr>
+<tr><td>OutCompositeOp</td>
+<td>Change-image with the shape of base-image cut out.</td>
+</tr>
+<tr><td>AtopCompositeOp</td>
+<td>Same shape as base-image, with change-image
+obscuring base-image where the image shapes
+overlap. Note this differs from over because the
+portion of change-image outside base-image's shape
+does not appear in the result.</td>
+</tr>
+<tr><td>XorCompositeOp</td>
+<td>Image data from both change-image and base-image
+that is outside the overlap region. The overlap
+region will be blank</td>
+</tr>
+<tr><td>PlusCompositeOp</td>
+<td>Sum of the image data. Output values are
+cropped to MaxRGB (no overflow). This operation is
+independent of the matte channels.</td>
+</tr>
+<tr><td>MinusCompositeOp</td>
+<td>Change-image - base-image, with underflow cropped
+to zero. The matte channel is ignored (set to
+opaque, full coverage)</td>
+</tr>
+<tr><td>AddCompositeOp</td>
+<td>Change-image + base-image, with overflow wrapping
+around (mod MaxRGB+1)</td>
+</tr>
+<tr><td>SubtractCompositeOp</td>
+<td>Change-image - base-image, with underflow wrapping
+around (mod MaxRGB+1). The add and subtract
+operators can be used to perform reversible
+transformations</td>
+</tr>
+<tr><td>DifferenceCompositeOp</td>
+<td>Absolute value of change-image minus base-image.</td>
+</tr>
+<tr><td>MultiplyCompositeOp</td>
+<td>Change-image * base-image. This is useful for the
+creation of drop-shadows.</td>
+</tr>
+<tr><td>BumpmapCompositeOp</td>
+<td>Base-image shaded by change-image</td>
+</tr>
+<tr><td>CopyCompositeOp</td>
+<td>Base-image replaced with change-image. Here
+the matte information is ignored</td>
+</tr>
+<tr><td>CopyRedCompositeOp</td>
+<td>Red channel in base-image replaced with
+the red channel in change-image. The other channels
+are copied untouched</td>
+</tr>
+<tr><td>CopyGreenCompositeOp</td>
+<td>Green channel in base-image replaced with the green
+channel in change-image. The other channels are
+copied untouched.</td>
+</tr>
+<tr><td>CopyBlueCompositeOp</td>
+<td>Blue channel in base-image replaced with the blue
+channel in change-image. The other channels are
+copied untouched.</td>
+</tr>
+<tr><td>CopyOpacityCompositeOp</td>
+<td>Opacity channel in base-image replaced with the
+opacity channel in change-image. The other
+channels are copied untouched.</td>
+</tr>
+<tr><td>ClearCompositeOp</td>
+<td>Pixels are set to transparent.</td>
+</tr>
+<tr><td>DissolveCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>DisplaceCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>ModulateCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>ThresholdCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>NoCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>DarkenCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>LightenCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>HueCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>SaturateCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>ColorizeCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>LuminizeCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>ScreenCompositeOp</td>
+<td>Not yet implemented (Photoshop &amp; PDF)</td>
+</tr>
+<tr><td>OverlayCompositeOp</td>
+<td>Not yet implemented (Photoshop &amp; PDF)</td>
+</tr>
+<tr><td>CopyCyanCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>CopyMagentaCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>CopyYellowCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>CopyBlackCompositeOp</td>
+<td>Copy CMYK Black (K) channel.</td>
+</tr>
+<tr><td>DivideCompositeOp</td>
+<td>Change-image / base-image. This is useful for
+improving the readability of text on unevenly
+illuminated photos. (by using a gaussian blurred
+copy of change-image as base-image)</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="compressiontype">
+<h1><a class="toc-backref" href="#id6">CompressionType</a></h1>
+<p><em>CompressionType</em> is used to express the desired compression type when
+encoding an image. Be aware that most image types only support a
+sub-set of the available compression types. If the compression type
+specified is incompatable with the image, GraphicsMagick selects a
+compression type compatable with the image type.</p>
+<table border="1" class="docutils">
+<caption>CompressionType</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedCompression</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>NoCompression</td>
+<td>No compression</td>
+</tr>
+<tr><td>BZipCompression</td>
+<td>BZip as used by bzip2 utilities</td>
+</tr>
+<tr><td>FaxCompression</td>
+<td>CCITT Group 3 FAX compression</td>
+</tr>
+<tr><td>Group4Compression</td>
+<td>CCITT Group 4 FAX compression (used only for TIFF)</td>
+</tr>
+<tr><td>JPEGCompression</td>
+<td>JPEG compression</td>
+</tr>
+<tr><td>LZWCompression</td>
+<td>Lempel-Ziv-Welch (LZW) compression</td>
+</tr>
+<tr><td>RLECompression</td>
+<td>Run-Length encoded (RLE) compression</td>
+</tr>
+<tr><td>ZipCompression</td>
+<td>Lempel-Ziv compression (LZ77) as used in GNU gzip.</td>
+</tr>
+<tr><td>LZMACompression</td>
+<td>Lempel-Ziv-Markov chain algorithm</td>
+</tr>
+<tr><td>JPEG2000Compression</td>
+<td>ISO/IEC std 15444-1</td>
+</tr>
+<tr><td>JBIG1Compression</td>
+<td>ISO/IEC std 11544 / ITU-T rec T.82</td>
+</tr>
+<tr><td>JBIG2Compression</td>
+<td>ISO/IEC std 14492 / ITU-T rec T.88</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="decorationtype">
+<h1><a class="toc-backref" href="#id7">DecorationType</a></h1>
+<p>The <em>DecorationType</em> enumerations are used to specify line decorations
+of rendered text.</p>
+<table border="1" class="docutils">
+<caption>DecorationType</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>NoDecoration</td>
+<td>No decoration</td>
+</tr>
+<tr><td>UnderlineDecoration</td>
+<td>Underlined text</td>
+</tr>
+<tr><td>OverlineDecoration</td>
+<td>Overlined text</td>
+</tr>
+<tr><td>LineThroughDecoration</td>
+<td>Strike-through text</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="endiantype">
+<h1><a class="toc-backref" href="#id8">EndianType</a></h1>
+<p>The <em>EndianType</em> enumerations are used to specify the endian option
+for formats which support it (e.g. TIFF).</p>
+<table border="1" class="docutils">
+<caption>EndianType</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedEndian</td>
+<td>Not defined (default)</td>
+</tr>
+<tr><td>LSBEndian</td>
+<td>Little endian (like Intel X86 and DEC Alpha)</td>
+</tr>
+<tr><td>MSBEndian</td>
+<td>Big endian (like Motorola 68K, Mac PowerPC, &amp;
+SPARC)</td>
+</tr>
+<tr><td>NativeEndian</td>
+<td>Use native endian of this CPU</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="fillrule">
+<h1><a class="toc-backref" href="#id9">FillRule</a></h1>
+<p><em>FillRule</em> specifies the algorithm which is to be used to determine
+what parts of the canvas are included inside the shape. See the
+documentation on SVG's <a class="reference external" href="http://www.w3.org/TR/SVG/painting.html#FillRuleProperty">fill-rule</a> property
+for usage details.</p>
+<table border="1" class="docutils">
+<caption>FillRule</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedRule</td>
+<td>Fill rule not specified</td>
+</tr>
+<tr><td>EvenOddRule</td>
+<td>See SVG fill-rule evenodd rule.</td>
+</tr>
+<tr><td>NonZeroRule</td>
+<td>See SVG fill-rule nonzero rule.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="filtertypes">
+<h1><a class="toc-backref" href="#id10">FilterTypes</a></h1>
+<p><em>FilterTypes</em> is used to adjust the filter algorithm used when
+resizing images. Different filters experience varying degrees of
+success with various images and can take sipngicantly different
+amounts of processing time. GraphicsMagick uses the <em>LanczosFilter</em> by
+default since this filter has been shown to provide the best results
+for most images in a reasonable amount of time. Other filter types
+(e.g. <em>TriangleFilter</em>) may execute much faster but may show artifacts
+when the image is re-sized or around diagonal lines. The only way to
+be sure is to test the filter with sample images.</p>
+<table border="1" class="docutils">
+<caption>FilterTypes</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedFilter</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>PointFilter</td>
+<td>Point Filter</td>
+</tr>
+<tr><td>BoxFilter</td>
+<td>Box Filter</td>
+</tr>
+<tr><td>TriangleFilter</td>
+<td>Triangle Filter</td>
+</tr>
+<tr><td>HermiteFilter</td>
+<td>Hermite Filter</td>
+</tr>
+<tr><td>HanningFilter</td>
+<td>Hanning Filter</td>
+</tr>
+<tr><td>HammingFilter</td>
+<td>Hamming Filter</td>
+</tr>
+<tr><td>BlackmanFilter</td>
+<td>Blackman Filter</td>
+</tr>
+<tr><td>GaussianFilter</td>
+<td>Gaussian Filter</td>
+</tr>
+<tr><td>QuadraticFilter</td>
+<td>Quadratic Filter</td>
+</tr>
+<tr><td>CubicFilter</td>
+<td>Cubic Filter</td>
+</tr>
+<tr><td>CatromFilter</td>
+<td>Catrom Filter</td>
+</tr>
+<tr><td>MitchellFilter</td>
+<td>Mitchell Filter</td>
+</tr>
+<tr><td>LanczosFilter</td>
+<td>Lanczos Filter</td>
+</tr>
+<tr><td>BesselFilter</td>
+<td>Bessel Filter</td>
+</tr>
+<tr><td>SincFilter</td>
+<td>Sinc Filter</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="gravitytype">
+<h1><a class="toc-backref" href="#id11">GravityType</a></h1>
+<p><em>GravityType</em> specifies positioning of an object (e.g. text, image)
+within a bounding region (e.g. an image). Gravity provides a
+convenient way to locate objects irrespective of the size of the
+bounding region, in other words, you don't need to provide absolute
+coordinates in order to position an object. A common default for
+gravity is <em>NorthWestGravity</em>.</p>
+<table border="1" class="docutils">
+<caption>GravityType</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>ForgetGravity</td>
+<td>Don't use gravity.</td>
+</tr>
+<tr><td>NorthWestGravity</td>
+<td>Position object at top-left of region.</td>
+</tr>
+<tr><td>NorthGravity</td>
+<td>Postiion object at top-center of region</td>
+</tr>
+<tr><td>NorthEastGravity</td>
+<td>Position object at top-right of region</td>
+</tr>
+<tr><td>WestGravity</td>
+<td>Position object at left-center of region</td>
+</tr>
+<tr><td>CenterGravity</td>
+<td>Position object at center of region</td>
+</tr>
+<tr><td>EastGravity</td>
+<td>Position object at right-center of region</td>
+</tr>
+<tr><td>SouthWestGravity</td>
+<td>Position object at left-bottom of region</td>
+</tr>
+<tr><td>SouthGravity</td>
+<td>Position object at bottom-center of region</td>
+</tr>
+<tr><td>SouthEastGravity</td>
+<td>Position object at bottom-right of region</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="imagetype">
+<h1><a class="toc-backref" href="#id12">ImageType</a></h1>
+<p><em>ImageType</em> indicates the type classification of the image.</p>
+<table border="1" class="docutils">
+<caption>ImageType</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedType</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>BilevelType</td>
+<td>Monochrome bi-level image</td>
+</tr>
+<tr><td>GrayscaleType</td>
+<td>Grayscale image</td>
+</tr>
+<tr><td>GrayscaleMatteType</td>
+<td>Grayscale image with opacity</td>
+</tr>
+<tr><td>PaletteType</td>
+<td>Indexed color (palette) image</td>
+</tr>
+<tr><td>PaletteMatteType</td>
+<td>Indexed color (palette) image with opacity</td>
+</tr>
+<tr><td>TrueColorType</td>
+<td>Truecolor image</td>
+</tr>
+<tr><td>TrueColorMatteType</td>
+<td>Truecolor image with opacity</td>
+</tr>
+<tr><td>ColorSeparationType</td>
+<td>Cyan/Yellow/Magenta/Black (CYMK) image</td>
+</tr>
+<tr><td>OptimizeType</td>
+<td>Optimize type based on image characteristics</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="interlacetype">
+<h1><a class="toc-backref" href="#id13">InterlaceType</a></h1>
+<p><em>InterlaceType</em> specifies the ordering of the red, green, and blue
+pixel information in the image. Interlacing is often used to make
+image information available to the user faster by taking advantage of
+the space vs time tradeoff. For example, interlacing allows images on
+the Web to be recognizable sooner and satellite images to
+accumulate/render with image resolution increasing over time.</p>
+<p>Use <em>LineInterlace</em> or <em>PlaneInterlace</em> to create an interlaced GIF or
+progressive JPEG image.</p>
+<table border="1" class="docutils">
+<caption>InterlaceType</caption>
+<colgroup>
+<col width="31%" />
+<col width="69%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedInterlace</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>NoInterlace</td>
+<td>Don't interlace image (RGBRGBRGBRGBRGBRGB...)</td>
+</tr>
+<tr><td>LineInterlace</td>
+<td>Use scanline interlacing
+(RRR...GGG...BBB...RRR...GGG...BBB...)</td>
+</tr>
+<tr><td>PlaneInterlace</td>
+<td>Use plane interlacing (RRRRRR...GGGGGG...BBBBBB...)</td>
+</tr>
+<tr><td>PartitionInterlace</td>
+<td>Similar to plane interlaing except that the
+different planes are saved to individual files
+(e.g. image.R, image.G, and image.B)</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="id1">
+<h1><a class="toc-backref" href="#id14">ChannelType</a></h1>
+<p><em>ChannelType</em> is used as an argument when doing color separations. Use
+<em>ChannelType</em> when extracting a layer from an image. <em>MatteLayer</em> is
+useful for extracting the opacity values from an image.</p>
+<table border="1" class="docutils">
+<caption>ChannelType</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedLayer</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>RedLayer</td>
+<td>Select red layer</td>
+</tr>
+<tr><td>GreenLayer</td>
+<td>Select green layer</td>
+</tr>
+<tr><td>BlueLayer</td>
+<td>Select blue layer</td>
+</tr>
+<tr><td>MatteLayer</td>
+<td>Select matte (opacity values) layer</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="linecap">
+<h1><a class="toc-backref" href="#id15">LineCap</a></h1>
+<p>The <em>LineCap</em> enumerations specify shape to be used at the end of open
+subpaths when they are stroked. See SVG's <a class="reference external" href="http://www.w3.org/TR/SVG/painting.html#StrokeLinecapProperty">stroke-linecap</a> for
+examples.</p>
+<table border="1" class="docutils">
+<caption>LineCap</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedCap</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>ButtCap</td>
+<td>Square ending.</td>
+</tr>
+<tr><td>RoundCap</td>
+<td>Rounded ending (half-circle end with radius of 1/2
+stroke width).</td>
+</tr>
+<tr><td>SquareCap</td>
+<td>Square ending, extended by 1/2 the stroke width at
+end.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="linejoin">
+<h1><a class="toc-backref" href="#id16">LineJoin</a></h1>
+<p>The <em>LineJoin</em> enumerations specify the shape to be used at the
+corners of paths or basic shapes when they are stroked. See SVG's
+<a class="reference external" href="http://www.w3.org/TR/SVG/painting.html#StrokeLinejoinProperty">stroke-linejoin</a> for
+examples.</p>
+<table border="1" class="docutils">
+<caption>LineJoin</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedJoin</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>MiterJoin</td>
+<td>Sharp-edged join</td>
+</tr>
+<tr><td>RoundJoin</td>
+<td>Rounded-edged join</td>
+</tr>
+<tr><td>BevelJoin</td>
+<td>Beveled-edged join</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="noisetype">
+<h1><a class="toc-backref" href="#id17">NoiseType</a></h1>
+<p><em>NoiseType</em> is used as an argument to select the type of noise to be
+added to the image.</p>
+<table border="1" class="docutils">
+<caption>NoiseType</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedNoise</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>UniformNoise</td>
+<td>Uniform noise</td>
+</tr>
+<tr><td>GaussianNoise</td>
+<td>Gaussian noise</td>
+</tr>
+<tr><td>MultiplicativeGaussianNoise</td>
+<td>Multiplicative Gaussian noise</td>
+</tr>
+<tr><td>ImpulseNoise</td>
+<td>Impulse noise</td>
+</tr>
+<tr><td>LaplacianNoise</td>
+<td>Laplacian noise</td>
+</tr>
+<tr><td>PoissonNoise</td>
+<td>Poisson noise</td>
+</tr>
+<tr><td>RandomNoise</td>
+<td>Random noise</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="orientationtype">
+<h1><a class="toc-backref" href="#id18">OrientationType</a></h1>
+<p><em>OrientationType</em> specifies the orientation of the image. Useful for
+when the image is produced via a different ordinate system, the camera
+was turned on its side, or the page was scanned sideways.</p>
+<table border="1" class="docutils">
+<caption>OrientationType</caption>
+<colgroup>
+<col width="38%" />
+<col width="28%" />
+<col width="34%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Scanline Direction</th>
+<th class="head">Frame Direction</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedOrientation</td>
+<td>Unknown</td>
+<td>Unknown</td>
+</tr>
+<tr><td>TopLeftOrientation</td>
+<td>Left to right</td>
+<td>Top to bottom</td>
+</tr>
+<tr><td>TopRightOrientation</td>
+<td>Right to left</td>
+<td>Top to bottom</td>
+</tr>
+<tr><td>BottomRightOrientation</td>
+<td>Right to left</td>
+<td>Bottom to top</td>
+</tr>
+<tr><td>BottomLeftOrientation</td>
+<td>Left to right</td>
+<td>Bottom to top</td>
+</tr>
+<tr><td>LeftTopOrientation</td>
+<td>Top to bottom</td>
+<td>Left to right</td>
+</tr>
+<tr><td>RightTopOrientation</td>
+<td>Top to bottom</td>
+<td>Right to left</td>
+</tr>
+<tr><td>RightBottomOrientation</td>
+<td>Bottom to top</td>
+<td>Right to left</td>
+</tr>
+<tr><td>LeftBottomOrientation</td>
+<td>Bottom to top</td>
+<td>Left to right</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="paintmethod">
+<h1><a class="toc-backref" href="#id19">PaintMethod</a></h1>
+<p><em>PaintMethod</em> specifies how pixel colors are to be replaced in the
+image. It is used to select the pixel-filling algorithm employed.</p>
+<table border="1" class="docutils">
+<caption>PaintMethod</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>PointMethod</td>
+<td>Replace pixel color at point.</td>
+</tr>
+<tr><td>ReplaceMethod</td>
+<td>Replace color for all image pixels matching
+color at point.</td>
+</tr>
+<tr><td>FloodfillMethod</td>
+<td>Replace color for pixels surrounding point
+until encountering pixel that fails to match
+color at point.</td>
+</tr>
+<tr><td>FillToBorderMethod</td>
+<td>Replace color for pixels surrounding point
+until encountering pixels matching border
+color.</td>
+</tr>
+<tr><td>ResetMethod</td>
+<td>Replace colors for all pixels in image with
+pen color.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="quantumtypes">
+<h1><a class="toc-backref" href="#id20">QuantumTypes</a></h1>
+<p><em>QuantumTypes</em> is used to indicate the source or destination format of
+entire pixels, or components of pixels (&quot;Quantums&quot;) while they are
+being read, or written to, a pixel cache. The validity of these format
+specifications depends on whether the Image pixels are in RGB format,
+RGBA format, or CMYK format. The pixel Quantum size is determined by
+the Image depth (typically 8, 16, or 32 bits, but any value from 1-64
+bits integer or float is supported).</p>
+<table border="1" class="docutils">
+<caption>RGB(A) Image Quantums</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>IndexQuantum</td>
+<td>PseudoColor colormap indices</td>
+</tr>
+<tr><td>RedQuantum</td>
+<td>Red pixel Quantum</td>
+</tr>
+<tr><td>GreenQuantum</td>
+<td>Green pixel Quantum</td>
+</tr>
+<tr><td>BlueQuantum</td>
+<td>Blue pixel Quantum</td>
+</tr>
+<tr><td>OpacityQuantum</td>
+<td>Opacity (Alpha) Quantum</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<caption>CMY(K) Image Quantum</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>CyanQuantum</td>
+<td>Cyan pixel Quantum</td>
+</tr>
+<tr><td>MagentaQuantum</td>
+<td>Magenta pixel Quantum</td>
+</tr>
+<tr><td>YellowQuantum</td>
+<td>Yellow pixel Quantum</td>
+</tr>
+<tr><td>BlackQuantum</td>
+<td>Black pixel Quantum</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<caption>Grayscale Image Quantums</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>GrayQuantum</td>
+<td>Gray pixel</td>
+</tr>
+<tr><td>GrayOpacityQuantum</td>
+<td>Pixel opacity</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<caption>Entire Pixels (Expressed in Byte Order)</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>RGBQuantum</td>
+<td>RGB pixel (1 to 64 bits)</td>
+</tr>
+<tr><td>RGBAQuantum</td>
+<td>RGBA pixel (1 to 64 bits)</td>
+</tr>
+<tr><td>CMYKQuantum</td>
+<td>CMYK pixel (1 to 64 bits)</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="renderingintent">
+<h1><a class="toc-backref" href="#id21">RenderingIntent</a></h1>
+<p>Rendering intent is a concept defined by <a class="reference external" href="http://www.color.org/">ICC</a> Spec ICC.1:1998-09, &quot;File Format for Color
+Profiles&quot;. GraphicsMagick uses RenderingIntent in order to support ICC
+Color Profiles.</p>
+<p>From the specification: &quot;Rendering intent specifies the style of
+reproduction to be used during the evaluation of this profile in a
+sequence of profiles. It applies specifically to that profile in the
+sequence and not to the entire sequence. Typically, the user or
+application will set the rendering intent dynamically at runtime or
+embedding time.&quot;</p>
+<table border="1" class="docutils">
+<caption>RenderingIntent</caption>
+<colgroup>
+<col width="36%" />
+<col width="64%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedIntent</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>SaturationIntent</td>
+<td>A rendering intent that specifies the saturation
+of the pixels in the image is preserved perhaps
+at the expense of accuracy in hue and lightness.</td>
+</tr>
+<tr><td>PerceptualIntent</td>
+<td>A rendering intent that specifies the full gamut
+of the image is compressed or expanded to fill
+the gamut of the destination device. Gray
+balance is preserved but colorimetric accuracy
+might not be preserved.</td>
+</tr>
+<tr><td>AbsoluteIntent</td>
+<td>Absolute colorimetric</td>
+</tr>
+<tr><td>RelativeIntent</td>
+<td>Relative colorimetric</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="resolutiontype">
+<h1><a class="toc-backref" href="#id22">ResolutionType</a></h1>
+<p>By default, GraphicsMagick defines resolutions in pixels per
+inch. <em>ResolutionType</em> provides a means to adjust this.</p>
+<table border="1" class="docutils">
+<caption>ResolutionType</caption>
+<colgroup>
+<col width="39%" />
+<col width="61%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedResolution</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>PixelsPerInchResolution</td>
+<td>Density specifications are specified in units
+of pixels per inch (english units).</td>
+</tr>
+<tr><td>PixelsPerCentimeterResolution</td>
+<td>Density specifications are specified in units
+of pixels per centimeter (metric units).</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="storagetype">
+<h1><a class="toc-backref" href="#id23">StorageType</a></h1>
+<p>The <em>StorageType</em> enumerations are used to specify the storage format
+of pixels in the source or destination pixel array.</p>
+<table border="1" class="docutils">
+<caption>StorageType</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>CharPixel</td>
+<td>Character type</td>
+</tr>
+<tr><td>ShortPixel</td>
+<td>Short type</td>
+</tr>
+<tr><td>IntegerPixel</td>
+<td>Integer type</td>
+</tr>
+<tr><td>FloatPixel</td>
+<td>Float type</td>
+</tr>
+<tr><td>DoublePixel</td>
+<td>Double type</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="stretchtype">
+<h1><a class="toc-backref" href="#id24">StretchType</a></h1>
+<p>The <em>StretchType</em> enumerations are used to specify the relative width
+of a font to the regular width for the font family. If the width is
+not important, the <em>AnyStretch</em> enumeration may be specified for a
+wildcard match.</p>
+<table border="1" class="docutils">
+<caption>StretchType</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>AnyStretch</td>
+<td>Wildcard match for font stretch</td>
+</tr>
+<tr><td>NormalStretch</td>
+<td>Normal width font</td>
+</tr>
+<tr><td>UltraCondensedStretch</td>
+<td>Ultra-condensed (narrowest) font</td>
+</tr>
+<tr><td>ExtraCondensedStretch</td>
+<td>Extra-condensed font</td>
+</tr>
+<tr><td>CondensedStretch</td>
+<td>Condensed font</td>
+</tr>
+<tr><td>SemiCondensedStretch</td>
+<td>Semi-Condensed font</td>
+</tr>
+<tr><td>SemiExpandedStretch</td>
+<td>Semi-Expanded font</td>
+</tr>
+<tr><td>ExpandedStretch</td>
+<td>Expanded font</td>
+</tr>
+<tr><td>ExtraExpandedStretch</td>
+<td>Extra-Expanded font</td>
+</tr>
+<tr><td>UltraExpandedStretch</td>
+<td>Ultra-expanded (widest) font</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="styletype">
+<h1><a class="toc-backref" href="#id25">StyleType</a></h1>
+<p>The <em>StyleType</em> enumerations are used to specify the style
+(e.g. Italic) of a font. If the style is not important, the <em>AnyStyle</em>
+enumeration may be specified for a wildcard match.</p>
+<table border="1" class="docutils">
+<caption>StyleType</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>AnyStyle</td>
+<td>Wildcard match for font style</td>
+</tr>
+<tr><td>NormalStyle</td>
+<td>Normal font style</td>
+</tr>
+<tr><td>ItalicStyle</td>
+<td>Italic font style</td>
+</tr>
+<tr><td>ObliqueStyle</td>
+<td>Oblique font style</td>
+</tr>
+</tbody>
+</table>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Enumerations.rst b/www/Magick++/Enumerations.rst
new file mode 100644
index 0000000..17fd27d
--- /dev/null
+++ b/www/Magick++/Enumerations.rst
@@ -0,0 +1,683 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+============
+Enumerations
+============
+
+.. contents:: Magick++ Enumerations
+ :depth: 1
+
+ChannelType
+-----------
+
+*ChannelType* is used as an argument when doing color separations. Use
+*ChannelType* when extracting a layer from an image. *MatteChannel* is
+useful for extracting the opacity values from an image. Note that an
+image may be represented in RGB, RGBA, CMYK, or CMYKA, pixel formats
+and a channel may only be extracted if it is valid for the current
+pixel format.
+
+.. table:: ChannelType
+
+ ===================== ==================================================
+ Enumeration Description
+ ===================== ==================================================
+ UndefinedChannel Unset value.
+ RedChannel RGB Red channel
+ CyanChannel CMYK Cyan channel
+ GreenChannel RGB Green channel
+ MagentaChannel CMYK Magenta channel
+ BlueChannel RGB Blue channel
+ YellowChannel CMYK Yellow channel
+ OpacityChannel Opacity channel (inverse of transparency)
+ BlackChannel CMYK Black (K) channel
+ MatteChannel Same as Opacity channel (deprecated)
+ AllChannels All color channels
+ GrayChannel Color channels represent an intensity
+ ===================== ==================================================
+
+ClassType
+---------
+
+*ClassType* specifies the image storage class.
+
+.. table:: ClassType
+
+ ===================== ==================================================
+ Enumeration Description
+ ===================== ==================================================
+ UndefinedClass Unset value.
+ DirectClass Image is composed of pixels which represent
+ literal color values.
+ PseudoClass Image is composed of pixels which specify an index
+ in a color palette.
+ ===================== ==================================================
+
+ColorspaceType
+--------------
+
+The *ColorspaceType* enumeration is used to specify the colorspace that
+quantization (color reduction and mapping) is done under or to specify
+the colorspace when encoding an output image. Colorspaces are ways of
+describing colors to fit the requirements of a particular application
+(e.g. Television, offset printing, color monitors). Color reduction,
+by default, takes place in the *RGBColorspace*. Empirical evidence
+suggests that distances in color spaces such as *YUVColorspace* or
+*YIQColorspace* correspond to perceptual color differences more closely
+han do distances in RGB space. These color spaces may give better
+results when color reducing an image. Refer to quantize for more
+details.
+
+When encoding an output image, the colorspaces *RGBColorspace*,
+*CMYKColorspace*, *GRAYColorspace*, or *YCbCrColorspace* may be
+specified. The CMYKColorspace option is only applicable when writing
+TIFF, JPEG, and Adobe Photoshop bitmap (PSD) files.
+
+.. table:: ColorspaceType
+
+ ===================== ==================================================
+ Enumeration Description
+ ===================== ==================================================
+ UndefinedColorspace Unset value.
+ RGBColorspace Red-Green-Blue colorspace.
+ GRAYColorspace Grayscale colorspace
+ TransparentColorspace The Transparent color space behaves uniquely in
+ that it preserves the matte channel of the image
+ if it exists.
+ OHTAColorspace
+ XYZColorspace
+ YCbCrColorspace
+ YCCColorspace
+ YIQColorspace
+ YPbPrColorspace
+ YUVColorspace Y-signal, U-signal, and V-signal colorspace. YUV is
+ most widely used to encode color for use in
+ television transmission.
+ CMYKColorspace Cyan-Magenta-Yellow-Black colorspace. CYMK is a
+ subtractive color system used by printers and
+ photographers for the rendering of colors with ink
+ or emulsion,
+ normally on a white surface.
+ sRGBColorspace Kodak PhotoCD sRGB
+ ===================== ==================================================
+
+CompositeOperator
+-----------------
+
+*CompositeOperator* is used to select the image composition algorithm
+used to compose a composite image with an image. By default, each of
+the composite image pixels are replaced by the corresponding image
+tile pixel. Specify *CompositeOperator* to select a different
+algorithm.
+
+.. table:: CompositeOperator
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedCompositeOp Not defined.
+ OverCompositeOp Union of the two image shapes, with
+ opaque areas of change-image obscuring base-image
+ in the region of overlap.
+ InCompositeOp Change-image cut by the shape of base-image.
+ None of the image data of base-image will be
+ in the result.
+ OutCompositeOp Change-image with the shape of base-image cut out.
+ AtopCompositeOp Same shape as base-image, with change-image
+ obscuring base-image where the image shapes
+ overlap. Note this differs from over because the
+ portion of change-image outside base-image's shape
+ does not appear in the result.
+ XorCompositeOp Image data from both change-image and base-image
+ that is outside the overlap region. The overlap
+ region will be blank
+ PlusCompositeOp Sum of the image data. Output values are
+ cropped to MaxRGB (no overflow). This operation is
+ independent of the matte channels.
+ MinusCompositeOp Change-image - base-image, with underflow cropped
+ to zero. The matte channel is ignored (set to
+ opaque, full coverage)
+ AddCompositeOp Change-image + base-image, with overflow wrapping
+ around (mod MaxRGB+1)
+ SubtractCompositeOp Change-image - base-image, with underflow wrapping
+ around (mod MaxRGB+1). The add and subtract
+ operators can be used to perform reversible
+ transformations
+ DifferenceCompositeOp Absolute value of change-image minus base-image.
+ MultiplyCompositeOp Change-image * base-image. This is useful for the
+ creation of drop-shadows.
+ BumpmapCompositeOp Base-image shaded by change-image
+ CopyCompositeOp Base-image replaced with change-image. Here
+ the matte information is ignored
+ CopyRedCompositeOp Red channel in base-image replaced with
+ the red channel in change-image. The other channels
+ are copied untouched
+ CopyGreenCompositeOp Green channel in base-image replaced with the green
+ channel in change-image. The other channels are
+ copied untouched.
+ CopyBlueCompositeOp Blue channel in base-image replaced with the blue
+ channel in change-image. The other channels are
+ copied untouched.
+ CopyOpacityCompositeOp Opacity channel in base-image replaced with the
+ opacity channel in change-image. The other
+ channels are copied untouched.
+ ClearCompositeOp Pixels are set to transparent.
+ DissolveCompositeOp
+ DisplaceCompositeOp
+ ModulateCompositeOp
+ ThresholdCompositeOp
+ NoCompositeOp
+ DarkenCompositeOp
+ LightenCompositeOp
+ HueCompositeOp
+ SaturateCompositeOp
+ ColorizeCompositeOp
+ LuminizeCompositeOp
+ ScreenCompositeOp Not yet implemented (Photoshop & PDF)
+ OverlayCompositeOp Not yet implemented (Photoshop & PDF)
+ CopyCyanCompositeOp
+ CopyMagentaCompositeOp
+ CopyYellowCompositeOp
+ CopyBlackCompositeOp Copy CMYK Black (K) channel.
+ DivideCompositeOp Change-image / base-image. This is useful for
+ improving the readability of text on unevenly
+ illuminated photos. (by using a gaussian blurred
+ copy of change-image as base-image)
+ ======================= ==================================================
+
+CompressionType
+---------------
+
+*CompressionType* is used to express the desired compression type when
+encoding an image. Be aware that most image types only support a
+sub-set of the available compression types. If the compression type
+specified is incompatable with the image, GraphicsMagick selects a
+compression type compatable with the image type.
+
+.. table:: CompressionType
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedCompression Unset value.
+ NoCompression No compression
+ BZipCompression BZip as used by bzip2 utilities
+ FaxCompression CCITT Group 3 FAX compression
+ Group4Compression CCITT Group 4 FAX compression (used only for TIFF)
+ JPEGCompression JPEG compression
+ LZWCompression Lempel-Ziv-Welch (LZW) compression
+ RLECompression Run-Length encoded (RLE) compression
+ ZipCompression Lempel-Ziv compression (LZ77) as used in GNU gzip.
+ LZMACompression Lempel-Ziv-Markov chain algorithm
+ JPEG2000Compression ISO/IEC std 15444-1
+ JBIG1Compression ISO/IEC std 11544 / ITU-T rec T.82
+ JBIG2Compression ISO/IEC std 14492 / ITU-T rec T.88
+ ======================= ==================================================
+
+DecorationType
+--------------
+
+The *DecorationType* enumerations are used to specify line decorations
+of rendered text.
+
+.. table:: DecorationType
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ NoDecoration No decoration
+ UnderlineDecoration Underlined text
+ OverlineDecoration Overlined text
+ LineThroughDecoration Strike-through text
+ ======================= ==================================================
+
+EndianType
+----------
+
+The *EndianType* enumerations are used to specify the endian option
+for formats which support it (e.g. TIFF).
+
+.. table:: EndianType
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedEndian Not defined (default)
+ LSBEndian Little endian (like Intel X86 and DEC Alpha)
+ MSBEndian Big endian (like Motorola 68K, Mac PowerPC, &
+ SPARC)
+ NativeEndian Use native endian of this CPU
+ ======================= ==================================================
+
+FillRule
+--------
+
+*FillRule* specifies the algorithm which is to be used to determine
+what parts of the canvas are included inside the shape. See the
+documentation on SVG's `fill-rule
+<http://www.w3.org/TR/SVG/painting.html#FillRuleProperty>`_ property
+for usage details.
+
+.. table:: FillRule
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedRule Fill rule not specified
+ EvenOddRule See SVG fill-rule evenodd rule.
+ NonZeroRule See SVG fill-rule nonzero rule.
+ ======================= ==================================================
+
+FilterTypes
+-----------
+
+*FilterTypes* is used to adjust the filter algorithm used when
+resizing images. Different filters experience varying degrees of
+success with various images and can take sipngicantly different
+amounts of processing time. GraphicsMagick uses the *LanczosFilter* by
+default since this filter has been shown to provide the best results
+for most images in a reasonable amount of time. Other filter types
+(e.g. *TriangleFilter*) may execute much faster but may show artifacts
+when the image is re-sized or around diagonal lines. The only way to
+be sure is to test the filter with sample images.
+
+.. table:: FilterTypes
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedFilter Unset value.
+ PointFilter Point Filter
+ BoxFilter Box Filter
+ TriangleFilter Triangle Filter
+ HermiteFilter Hermite Filter
+ HanningFilter Hanning Filter
+ HammingFilter Hamming Filter
+ BlackmanFilter Blackman Filter
+ GaussianFilter Gaussian Filter
+ QuadraticFilter Quadratic Filter
+ CubicFilter Cubic Filter
+ CatromFilter Catrom Filter
+ MitchellFilter Mitchell Filter
+ LanczosFilter Lanczos Filter
+ BesselFilter Bessel Filter
+ SincFilter Sinc Filter
+ ======================= ==================================================
+
+GravityType
+-----------
+
+*GravityType* specifies positioning of an object (e.g. text, image)
+within a bounding region (e.g. an image). Gravity provides a
+convenient way to locate objects irrespective of the size of the
+bounding region, in other words, you don't need to provide absolute
+coordinates in order to position an object. A common default for
+gravity is *NorthWestGravity*.
+
+.. table:: GravityType
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ ForgetGravity Don't use gravity.
+ NorthWestGravity Position object at top-left of region.
+ NorthGravity Postiion object at top-center of region
+ NorthEastGravity Position object at top-right of region
+ WestGravity Position object at left-center of region
+ CenterGravity Position object at center of region
+ EastGravity Position object at right-center of region
+ SouthWestGravity Position object at left-bottom of region
+ SouthGravity Position object at bottom-center of region
+ SouthEastGravity Position object at bottom-right of region
+ ======================= ==================================================
+
+ImageType
+---------
+
+*ImageType* indicates the type classification of the image.
+
+.. table:: ImageType
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedType Unset value.
+ BilevelType Monochrome bi-level image
+ GrayscaleType Grayscale image
+ GrayscaleMatteType Grayscale image with opacity
+ PaletteType Indexed color (palette) image
+ PaletteMatteType Indexed color (palette) image with opacity
+ TrueColorType Truecolor image
+ TrueColorMatteType Truecolor image with opacity
+ ColorSeparationType Cyan/Yellow/Magenta/Black (CYMK) image
+ OptimizeType Optimize type based on image characteristics
+ ======================= ==================================================
+
+InterlaceType
+-------------
+
+*InterlaceType* specifies the ordering of the red, green, and blue
+pixel information in the image. Interlacing is often used to make
+image information available to the user faster by taking advantage of
+the space vs time tradeoff. For example, interlacing allows images on
+the Web to be recognizable sooner and satellite images to
+accumulate/render with image resolution increasing over time.
+
+Use *LineInterlace* or *PlaneInterlace* to create an interlaced GIF or
+progressive JPEG image.
+
+.. table:: InterlaceType
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedInterlace Unset value.
+ NoInterlace Don't interlace image (RGBRGBRGBRGBRGBRGB...)
+ LineInterlace Use scanline interlacing
+ (RRR...GGG...BBB...RRR...GGG...BBB...)
+ PlaneInterlace Use plane interlacing (RRRRRR...GGGGGG...BBBBBB...)
+ PartitionInterlace Similar to plane interlaing except that the
+ different planes are saved to individual files
+ (e.g. image.R, image.G, and image.B)
+ ======================= ==================================================
+
+ChannelType
+-----------
+
+*ChannelType* is used as an argument when doing color separations. Use
+*ChannelType* when extracting a layer from an image. *MatteLayer* is
+useful for extracting the opacity values from an image.
+
+.. table:: ChannelType
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedLayer Unset value.
+ RedLayer Select red layer
+ GreenLayer Select green layer
+ BlueLayer Select blue layer
+ MatteLayer Select matte (opacity values) layer
+ ======================= ==================================================
+
+LineCap
+-------
+
+The *LineCap* enumerations specify shape to be used at the end of open
+subpaths when they are stroked. See SVG's `stroke-linecap
+<http://www.w3.org/TR/SVG/painting.html#StrokeLinecapProperty>`_ for
+examples.
+
+.. table:: LineCap
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedCap Unset value.
+ ButtCap Square ending.
+ RoundCap Rounded ending (half-circle end with radius of 1/2
+ stroke width).
+ SquareCap Square ending, extended by 1/2 the stroke width at
+ end.
+ ======================= ==================================================
+
+LineJoin
+--------
+
+The *LineJoin* enumerations specify the shape to be used at the
+corners of paths or basic shapes when they are stroked. See SVG's
+`stroke-linejoin
+<http://www.w3.org/TR/SVG/painting.html#StrokeLinejoinProperty>`_ for
+examples.
+
+.. table:: LineJoin
+
+ ======================= ==================================================
+ Enumeration Description
+ ======================= ==================================================
+ UndefinedJoin Unset value.
+ MiterJoin Sharp-edged join
+ RoundJoin Rounded-edged join
+ BevelJoin Beveled-edged join
+ ======================= ==================================================
+
+NoiseType
+---------
+
+*NoiseType* is used as an argument to select the type of noise to be
+added to the image.
+
+.. table:: NoiseType
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ UndefinedNoise Unset value.
+ UniformNoise Uniform noise
+ GaussianNoise Gaussian noise
+ MultiplicativeGaussianNoise Multiplicative Gaussian noise
+ ImpulseNoise Impulse noise
+ LaplacianNoise Laplacian noise
+ PoissonNoise Poisson noise
+ RandomNoise Random noise
+ =========================== ==============================================
+
+OrientationType
+---------------
+
+*OrientationType* specifies the orientation of the image. Useful for
+when the image is produced via a different ordinate system, the camera
+was turned on its side, or the page was scanned sideways.
+
+.. table:: OrientationType
+
+ =========================== ==================== ========================
+ Enumeration Scanline Direction Frame Direction
+ =========================== ==================== ========================
+ UndefinedOrientation Unknown Unknown
+ TopLeftOrientation Left to right Top to bottom
+ TopRightOrientation Right to left Top to bottom
+ BottomRightOrientation Right to left Bottom to top
+ BottomLeftOrientation Left to right Bottom to top
+ LeftTopOrientation Top to bottom Left to right
+ RightTopOrientation Top to bottom Right to left
+ RightBottomOrientation Bottom to top Right to left
+ LeftBottomOrientation Bottom to top Left to right
+ =========================== ==================== ========================
+
+PaintMethod
+-----------
+
+*PaintMethod* specifies how pixel colors are to be replaced in the
+image. It is used to select the pixel-filling algorithm employed.
+
+.. table:: PaintMethod
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ PointMethod Replace pixel color at point.
+ ReplaceMethod Replace color for all image pixels matching
+ color at point.
+ FloodfillMethod Replace color for pixels surrounding point
+ until encountering pixel that fails to match
+ color at point.
+ FillToBorderMethod Replace color for pixels surrounding point
+ until encountering pixels matching border
+ color.
+ ResetMethod Replace colors for all pixels in image with
+ pen color.
+ =========================== ==============================================
+
+QuantumTypes
+------------
+
+*QuantumTypes* is used to indicate the source or destination format of
+entire pixels, or components of pixels ("Quantums") while they are
+being read, or written to, a pixel cache. The validity of these format
+specifications depends on whether the Image pixels are in RGB format,
+RGBA format, or CMYK format. The pixel Quantum size is determined by
+the Image depth (typically 8, 16, or 32 bits, but any value from 1-64
+bits integer or float is supported).
+
+
+.. table:: RGB(A) Image Quantums
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ IndexQuantum PseudoColor colormap indices
+ RedQuantum Red pixel Quantum
+ GreenQuantum Green pixel Quantum
+ BlueQuantum Blue pixel Quantum
+ OpacityQuantum Opacity (Alpha) Quantum
+ =========================== ==============================================
+
+.. table:: CMY(K) Image Quantum
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ CyanQuantum Cyan pixel Quantum
+ MagentaQuantum Magenta pixel Quantum
+ YellowQuantum Yellow pixel Quantum
+ BlackQuantum Black pixel Quantum
+ =========================== ==============================================
+
+.. table:: Grayscale Image Quantums
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ GrayQuantum Gray pixel
+ GrayOpacityQuantum Pixel opacity
+ =========================== ==============================================
+
+.. table:: Entire Pixels (Expressed in Byte Order)
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ RGBQuantum RGB pixel (1 to 64 bits)
+ RGBAQuantum RGBA pixel (1 to 64 bits)
+ CMYKQuantum CMYK pixel (1 to 64 bits)
+ =========================== ==============================================
+
+RenderingIntent
+---------------
+
+Rendering intent is a concept defined by `ICC
+<http://www.color.org/>`_ Spec ICC.1:1998-09, "File Format for Color
+Profiles". GraphicsMagick uses RenderingIntent in order to support ICC
+Color Profiles.
+
+From the specification: "Rendering intent specifies the style of
+reproduction to be used during the evaluation of this profile in a
+sequence of profiles. It applies specifically to that profile in the
+sequence and not to the entire sequence. Typically, the user or
+application will set the rendering intent dynamically at runtime or
+embedding time."
+
+.. table:: RenderingIntent
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ UndefinedIntent Unset value.
+ SaturationIntent A rendering intent that specifies the saturation
+ of the pixels in the image is preserved perhaps
+ at the expense of accuracy in hue and lightness.
+ PerceptualIntent A rendering intent that specifies the full gamut
+ of the image is compressed or expanded to fill
+ the gamut of the destination device. Gray
+ balance is preserved but colorimetric accuracy
+ might not be preserved.
+ AbsoluteIntent Absolute colorimetric
+ RelativeIntent Relative colorimetric
+ =========================== ==============================================
+
+ResolutionType
+--------------
+
+By default, GraphicsMagick defines resolutions in pixels per
+inch. *ResolutionType* provides a means to adjust this.
+
+.. table:: ResolutionType
+
+ ============================= ============================================
+ Enumeration Description
+ ============================= ============================================
+ UndefinedResolution Unset value.
+ PixelsPerInchResolution Density specifications are specified in units
+ of pixels per inch (english units).
+ PixelsPerCentimeterResolution Density specifications are specified in units
+ of pixels per centimeter (metric units).
+ ============================= ============================================
+
+StorageType
+-----------
+
+The *StorageType* enumerations are used to specify the storage format
+of pixels in the source or destination pixel array.
+
+.. table:: StorageType
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ CharPixel Character type
+ ShortPixel Short type
+ IntegerPixel Integer type
+ FloatPixel Float type
+ DoublePixel Double type
+ =========================== ==============================================
+
+StretchType
+-----------
+
+The *StretchType* enumerations are used to specify the relative width
+of a font to the regular width for the font family. If the width is
+not important, the *AnyStretch* enumeration may be specified for a
+wildcard match.
+
+.. table:: StretchType
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ AnyStretch Wildcard match for font stretch
+ NormalStretch Normal width font
+ UltraCondensedStretch Ultra-condensed (narrowest) font
+ ExtraCondensedStretch Extra-condensed font
+ CondensedStretch Condensed font
+ SemiCondensedStretch Semi-Condensed font
+ SemiExpandedStretch Semi-Expanded font
+ ExpandedStretch Expanded font
+ ExtraExpandedStretch Extra-Expanded font
+ UltraExpandedStretch Ultra-expanded (widest) font
+ =========================== ==============================================
+
+StyleType
+---------
+
+The *StyleType* enumerations are used to specify the style
+(e.g. Italic) of a font. If the style is not important, the *AnyStyle*
+enumeration may be specified for a wildcard match.
+
+.. table:: StyleType
+
+ =========================== ==============================================
+ Enumeration Description
+ =========================== ==============================================
+ AnyStyle Wildcard match for font style
+ NormalStyle Normal font style
+ ItalicStyle Italic font style
+ ObliqueStyle Oblique font style
+ =========================== ==============================================
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/Exception.html b/www/Magick++/Exception.html
new file mode 100644
index 0000000..1b7d606
--- /dev/null
+++ b/www/Magick++/Exception.html
@@ -0,0 +1,300 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Exception</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-exception">
+<h1 class="title">Magick::Exception</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p><em>Exception</em> represents the base class of objects thrown when
+Magick++ reports an error. Magick++ throws C++ exceptions synchronous
+with the operation where the error occurred. This allows errors to be
+trapped within the enclosing code (perhaps the code to process a
+single image) while allowing the code to be written with a simple
+coding style.</p>
+<p>A try/catch block should be placed around any sequence of operations
+which can be considered an important body of work. For example, if
+your program processes lists of images and some of these images may be
+defective, by placing the try/catch block around the entire sequence
+of code that processes one image (including instantiating the image
+object), you can minimize the overhead of error checking while
+ensuring that all objects created to deal with that object are safely
+destroyed (C++ exceptions unroll the stack until the enclosing try
+block, destroying any objects on the stack).</p>
+<p>Note that any objects allocated via 'new' with a pointer on the stack
+are not automatically destroyed by unrolling the stack via a C++
+exception so that it may be necessary to catch the exception at each
+level, destroy any objects allocated via 'new' (or malloc()) and then
+re-throw the exception. This includes constructors which might
+encounter an exception while the object is being constructed and
+should destroy any already-allocated data. Magick++ classes are
+designed to be <strong>very</strong> tiny so it is recommended to automatically
+allocate them on the stack when possible rather than via 'new'.</p>
+<p>The pseudo code for the main loop of your program may look like:</p>
+<pre class="literal-block">
+ using namespace std;
+ for infile in list
+ {
+ try {
+ // Construct an image instance first so that we don't have to worry
+ // about object construction failure due to a minor warning exception
+ // being thrown.
+ Magick::Image image;
+
+ // Determine if Warning exceptions are thrown.
+ // Use is optional. Set to true to block Warning exceptions.
+ image.quiet( false );
+
+ try {
+ // Try reading image file
+ image.read(infile);
+ }
+ catch( Magick::WarningCoder &amp;warning )
+ {
+ // Process coder warning while loading file (e.g. TIFF warning)
+ // Maybe the user will be interested in these warnings (or not).
+ // If a warning is produced while loading an image, the image
+ // can normally still be used (but not if the warning was about
+ // something important!)
+ cerr &lt;&lt; “Coder Warning: “ &lt;&lt; warning.what() &lt;&lt; endl;
+ }
+ catch( Magick::Warning &amp;warning )
+ {
+ // Handle any other Magick++ warning.
+ cerr &lt;&lt; “Warning: “ &lt;&lt; warning.what() &lt;&lt; endl;
+ }
+ catch( Magick::ErrorFileOpen &amp;error )
+ {
+ // Process Magick++ file open error
+ cerr &lt;&lt; “Error: “ &lt;&lt; error.what() &lt;&lt; endl;
+ continue; // Try next image.
+ }
+ try {
+ image.rotate(90);
+ image.write(“outfile”);
+ }
+ catch ( MagickExeption &amp; error)
+ {
+ // Handle problem while rotating or writing outfile.
+ cerr &lt;&lt; “Caught Magick++ exception: “ &lt;&lt; error.what() &lt;&lt; endl;
+ }
+ }
+ catch( std::exception &amp;error )
+ {
+ // Process any other exceptions derived from standard C++ exception
+ cerr &lt;&lt; “Caught C++ STD exception: “ &lt;&lt; error.what() &lt;&lt; endl;
+ }
+ catch( ... )
+ {
+ // Process *any* exception (last-ditch effort). There is not a lot
+ // you can do here other to retry the operation that failed, or exit
+ // the program.
+ }
+ }
+
+The desired location and number of try/catch blocks in your program
+depends how sophisticated its error handling must be. Very simple
+programs may use just one try/catch block.
+</pre>
+<p>The <em>Exception</em> class is derived from the C++ standard
+<em>std::exception</em> class. This means that it contains a C++ string
+containing additional information about the error (e.g to display to
+the user). Obtain access to this string via the what() method. For
+example:</p>
+<pre class="literal-block">
+catch( Exception &amp;error_ )
+{
+ cout &lt;&lt; &quot;Caught exception: &quot; &lt;&lt; error_.what() &lt;&lt; endl;
+}
+</pre>
+<p>The classes <em>Warning</em> and <em>Error</em> derive from the <em>Exception</em>
+class. Exceptions derived from <em>Warning</em> are thrown to represent
+non-fatal errors which may effect the completeness or quality of the
+result (e.g. one image provided as an argument to montage is
+defective). In most cases, a <em>Warning</em> exception may be ignored by
+catching it immediately, processing it (e.g. printing a diagnostic)
+and continuing on. Exceptions derived from <em>Error</em> are thrown to
+represent fatal errors that can not produce a valid result
+(e.g. attempting to read a file which does not exist).</p>
+<p>The specific derived exception classes are shown in the following tables:</p>
+<table border="1" class="docutils">
+<caption>Warning (Suspect but completed) Sub-Classes</caption>
+<colgroup>
+<col width="35%" />
+<col width="65%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Warning</th>
+<th class="head">Warning Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>WarningUndefined</td>
+<td>Unspecified type.</td>
+</tr>
+<tr><td>WarningBlob</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningCache</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningCoder</td>
+<td>Issued by some coders.</td>
+</tr>
+<tr><td>WarningConfigure</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningCorruptImage</td>
+<td>Issued when an image may be corrupt.</td>
+</tr>
+<tr><td>WarningDelegate</td>
+<td>Reported by a subordinate program.</td>
+</tr>
+<tr><td>WarningDraw</td>
+<td>Reported by the rendering subsystem.</td>
+</tr>
+<tr><td>WarningFileOpen</td>
+<td>Reported when file could not be opened.</td>
+</tr>
+<tr><td>WarningImage</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningMissingDelegate</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningModule</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningMonitor</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningOption</td>
+<td>Reported when an option is incorrect.</td>
+</tr>
+<tr><td>WarningRegistry</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningResourceLimit</td>
+<td>Reported when a resource is exhausted.</td>
+</tr>
+<tr><td>WarningStream</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningType</td>
+<td>NOT CURRENTLY USED</td>
+</tr>
+<tr><td>WarningXServer</td>
+<td>Warnings reported by the X11 subsystem.</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<caption>Error (Failed) Sub-Classes</caption>
+<colgroup>
+<col width="33%" />
+<col width="67%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Error</th>
+<th class="head">Error Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>ErrorUndefined</td>
+<td>Unspecified error type.</td>
+</tr>
+<tr><td>ErrorBlob</td>
+<td>Reported by BLOB I/O subsystem.</td>
+</tr>
+<tr><td>ErrorCache</td>
+<td>Reported by the pixel cache subsystem.</td>
+</tr>
+<tr><td>ErrorCoder</td>
+<td>Reported by coders (image format support).</td>
+</tr>
+<tr><td>ErrorConfigure</td>
+<td>Reported while loading configuration files.</td>
+</tr>
+<tr><td>ErrorCorruptImage</td>
+<td>Reported when the image file is corrupt.</td>
+</tr>
+<tr><td>ErrorDelegate</td>
+<td>Reported by a subordinate program</td>
+</tr>
+<tr><td>ErrorDraw</td>
+<td>Reported while drawing on image.</td>
+</tr>
+<tr><td>ErrorFileOpen</td>
+<td>Reported when the image file can not be opened.</td>
+</tr>
+<tr><td>ErrorImage</td>
+<td>Reported while drawing.</td>
+</tr>
+<tr><td>ErrorMissingDelegate</td>
+<td>Reported when optional add-on library or
+subordinate program is missing (but is needed).</td>
+</tr>
+<tr><td>ErrorModule</td>
+<td>Reported by the module loader subsystem.</td>
+</tr>
+<tr><td>ErrorMonitor</td>
+<td>Reported by the progress monitor.</td>
+</tr>
+<tr><td>ErrorOption</td>
+<td>Reported when option is malformed or out of range.</td>
+</tr>
+<tr><td>ErrorRegistry</td>
+<td>Reported by the image/BLOB registry subsystem.</td>
+</tr>
+<tr><td>ErrorResourceLimit</td>
+<td>Reported when a program resource is exhausted.</td>
+</tr>
+<tr><td>ErrorStream</td>
+<td>Reported by the pixel stream subsystem.</td>
+</tr>
+<tr><td>ErrorType</td>
+<td>Reported by the type (font) rendering subsystem.</td>
+</tr>
+<tr><td>ErrorXServer</td>
+<td>Reported by the X11 subsystem.</td>
+</tr>
+</tbody>
+</table>
+<p>Note that <em>ErrorMissingDelegate</em> is a &quot;catch-all&quot; error reported when
+GraphicsMagick is unable to figure out how to open the file.</p>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Exception.rst b/www/Magick++/Exception.rst
new file mode 100644
index 0000000..6e37c60
--- /dev/null
+++ b/www/Magick++/Exception.rst
@@ -0,0 +1,184 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=================
+Magick::Exception
+=================
+
+*Exception* represents the base class of objects thrown when
+Magick++ reports an error. Magick++ throws C++ exceptions synchronous
+with the operation where the error occurred. This allows errors to be
+trapped within the enclosing code (perhaps the code to process a
+single image) while allowing the code to be written with a simple
+coding style.
+
+A try/catch block should be placed around any sequence of operations
+which can be considered an important body of work. For example, if
+your program processes lists of images and some of these images may be
+defective, by placing the try/catch block around the entire sequence
+of code that processes one image (including instantiating the image
+object), you can minimize the overhead of error checking while
+ensuring that all objects created to deal with that object are safely
+destroyed (C++ exceptions unroll the stack until the enclosing try
+block, destroying any objects on the stack).
+
+Note that any objects allocated via 'new' with a pointer on the stack
+are not automatically destroyed by unrolling the stack via a C++
+exception so that it may be necessary to catch the exception at each
+level, destroy any objects allocated via 'new' (or malloc()) and then
+re-throw the exception. This includes constructors which might
+encounter an exception while the object is being constructed and
+should destroy any already-allocated data. Magick++ classes are
+designed to be **very** tiny so it is recommended to automatically
+allocate them on the stack when possible rather than via 'new'.
+
+The pseudo code for the main loop of your program may look like::
+
+ using namespace std;
+ for infile in list
+ {
+ try {
+ // Construct an image instance first so that we don't have to worry
+ // about object construction failure due to a minor warning exception
+ // being thrown.
+ Magick::Image image;
+
+ // Determine if Warning exceptions are thrown.
+ // Use is optional. Set to true to block Warning exceptions.
+ image.quiet( false );
+
+ try {
+ // Try reading image file
+ image.read(infile);
+ }
+ catch( Magick::WarningCoder &warning )
+ {
+ // Process coder warning while loading file (e.g. TIFF warning)
+ // Maybe the user will be interested in these warnings (or not).
+ // If a warning is produced while loading an image, the image
+ // can normally still be used (but not if the warning was about
+ // something important!)
+ cerr << “Coder Warning: “ << warning.what() << endl;
+ }
+ catch( Magick::Warning &warning )
+ {
+ // Handle any other Magick++ warning.
+ cerr << “Warning: “ << warning.what() << endl;
+ }
+ catch( Magick::ErrorFileOpen &error )
+ {
+ // Process Magick++ file open error
+ cerr << “Error: “ << error.what() << endl;
+ continue; // Try next image.
+ }
+ try {
+ image.rotate(90);
+ image.write(“outfile”);
+ }
+ catch ( MagickExeption & error)
+ {
+ // Handle problem while rotating or writing outfile.
+ cerr << “Caught Magick++ exception: “ << error.what() << endl;
+ }
+ }
+ catch( std::exception &error )
+ {
+ // Process any other exceptions derived from standard C++ exception
+ cerr << “Caught C++ STD exception: “ << error.what() << endl;
+ }
+ catch( ... )
+ {
+ // Process *any* exception (last-ditch effort). There is not a lot
+ // you can do here other to retry the operation that failed, or exit
+ // the program.
+ }
+ }
+
+ The desired location and number of try/catch blocks in your program
+ depends how sophisticated its error handling must be. Very simple
+ programs may use just one try/catch block.
+
+The *Exception* class is derived from the C++ standard
+*std::exception* class. This means that it contains a C++ string
+containing additional information about the error (e.g to display to
+the user). Obtain access to this string via the what() method. For
+example::
+
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ }
+
+The classes *Warning* and *Error* derive from the *Exception*
+class. Exceptions derived from *Warning* are thrown to represent
+non-fatal errors which may effect the completeness or quality of the
+result (e.g. one image provided as an argument to montage is
+defective). In most cases, a *Warning* exception may be ignored by
+catching it immediately, processing it (e.g. printing a diagnostic)
+and continuing on. Exceptions derived from *Error* are thrown to
+represent fatal errors that can not produce a valid result
+(e.g. attempting to read a file which does not exist).
+
+The specific derived exception classes are shown in the following tables:
+
+.. table:: Warning (Suspect but completed) Sub-Classes
+
+ ========================= ==============================================
+ Warning Warning Description
+ ========================= ==============================================
+ WarningUndefined Unspecified type.
+ WarningBlob NOT CURRENTLY USED
+ WarningCache NOT CURRENTLY USED
+ WarningCoder Issued by some coders.
+ WarningConfigure NOT CURRENTLY USED
+ WarningCorruptImage Issued when an image may be corrupt.
+ WarningDelegate Reported by a subordinate program.
+ WarningDraw Reported by the rendering subsystem.
+ WarningFileOpen Reported when file could not be opened.
+ WarningImage NOT CURRENTLY USED
+ WarningMissingDelegate NOT CURRENTLY USED
+ WarningModule NOT CURRENTLY USED
+ WarningMonitor NOT CURRENTLY USED
+ WarningOption Reported when an option is incorrect.
+ WarningRegistry NOT CURRENTLY USED
+ WarningResourceLimit Reported when a resource is exhausted.
+ WarningStream NOT CURRENTLY USED
+ WarningType NOT CURRENTLY USED
+ WarningXServer Warnings reported by the X11 subsystem.
+ ========================= ==============================================
+
+.. table:: Error (Failed) Sub-Classes
+
+ ========================= ==============================================
+ Error Error Description
+ ========================= ==============================================
+ ErrorUndefined Unspecified error type.
+ ErrorBlob Reported by BLOB I/O subsystem.
+ ErrorCache Reported by the pixel cache subsystem.
+ ErrorCoder Reported by coders (image format support).
+ ErrorConfigure Reported while loading configuration files.
+ ErrorCorruptImage Reported when the image file is corrupt.
+ ErrorDelegate Reported by a subordinate program
+ ErrorDraw Reported while drawing on image.
+ ErrorFileOpen Reported when the image file can not be opened.
+ ErrorImage Reported while drawing.
+ ErrorMissingDelegate Reported when optional add-on library or
+ subordinate program is missing (but is needed).
+ ErrorModule Reported by the module loader subsystem.
+ ErrorMonitor Reported by the progress monitor.
+ ErrorOption Reported when option is malformed or out of range.
+ ErrorRegistry Reported by the image/BLOB registry subsystem.
+ ErrorResourceLimit Reported when a program resource is exhausted.
+ ErrorStream Reported by the pixel stream subsystem.
+ ErrorType Reported by the type (font) rendering subsystem.
+ ErrorXServer Reported by the X11 subsystem.
+ ========================= ==============================================
+
+Note that *ErrorMissingDelegate* is a "catch-all" error reported when
+GraphicsMagick is unable to figure out how to open the file.
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/FormatCharacters.html b/www/Magick++/FormatCharacters.html
new file mode 100644
index 0000000..7753215
--- /dev/null
+++ b/www/Magick++/FormatCharacters.html
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Special Format Characters</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="special-format-characters">
+<h1 class="title">Special Format Characters</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The Magick::Image methods <a class="reference external" href="Image.html#annotate">annotate</a>, <a class="reference external" href="Image.html#draw">draw</a>, <a class="reference external" href="Image.html#label">label</a>, and the template
+function <a class="reference external" href="STL.html#montageImages">montageImages</a> support special
+format characters contained in the argument text. These format
+characters work similar to C's printf. Whenever a format character
+appears in the text, it is replaced with the equivalent attribute
+text. The available format characters are shown in the following
+table:</p>
+<table border="1" class="docutils">
+<caption>Format Characters</caption>
+<colgroup>
+<col width="37%" />
+<col width="63%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Format Character</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>%b</td>
+<td>file size</td>
+</tr>
+<tr><td>%d</td>
+<td>directory</td>
+</tr>
+<tr><td>%e</td>
+<td>filename extension</td>
+</tr>
+<tr><td>%f</td>
+<td>filename</td>
+</tr>
+<tr><td>%h</td>
+<td>height</td>
+</tr>
+<tr><td>%m</td>
+<td>magick (e.g GIF)</td>
+</tr>
+<tr><td>%p</td>
+<td>page number</td>
+</tr>
+<tr><td>%s</td>
+<td>scene number</td>
+</tr>
+<tr><td>%t</td>
+<td>top of filename</td>
+</tr>
+<tr><td>%w</td>
+<td>width</td>
+</tr>
+<tr><td>%x</td>
+<td>x resolution</td>
+</tr>
+<tr><td>%y</td>
+<td>y resolution</td>
+</tr>
+<tr><td>n</td>
+<td>newline</td>
+</tr>
+<tr><td>r</td>
+<td>carriage return</td>
+</tr>
+</tbody>
+</table>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/FormatCharacters.rst b/www/Magick++/FormatCharacters.rst
new file mode 100644
index 0000000..8078498
--- /dev/null
+++ b/www/Magick++/FormatCharacters.rst
@@ -0,0 +1,42 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=========================
+Special Format Characters
+=========================
+
+The Magick::Image methods `annotate <Image.html#annotate>`_, `draw
+<Image.html#draw>`_, `label <Image.html#label>`_, and the template
+function `montageImages <STL.html#montageImages>`_ support special
+format characters contained in the argument text. These format
+characters work similar to C's printf. Whenever a format character
+appears in the text, it is replaced with the equivalent attribute
+text. The available format characters are shown in the following
+table:
+
+.. table:: Format Characters
+
+ ================ ===========================
+ Format Character Description
+ ================ ===========================
+ %b file size
+ %d directory
+ %e filename extension
+ %f filename
+ %h height
+ %m magick (e.g GIF)
+ %p page number
+ %s scene number
+ %t top of filename
+ %w width
+ %x x resolution
+ %y y resolution
+ \n newline
+ \r carriage return
+ ================ ===========================
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/Geometry.html b/www/Magick++/Geometry.html
new file mode 100644
index 0000000..0847607
--- /dev/null
+++ b/www/Magick++/Geometry.html
@@ -0,0 +1,427 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Geometry</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-geometry">
+<h1 class="title">Magick::Geometry</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>Geometry provides a convenient means to specify a geometry
+argument. The object may be initialized from a C string or C++ string
+containing a geometry specification. It may also be initialized by
+more efficient parameterized constructors.</p>
+<div class="section" id="x11-geometry-specifications">
+<h1>X11 Geometry Specifications</h1>
+<p>X11 geometry specifications are in the form
+&quot;&lt;width&gt;x&lt;height&gt;{+-}&lt;xoffset&gt;{+-}&lt;yoffset&gt;&quot; (where width, height,
+xoffset, and yoffset are numbers) for specifying the size and
+placement location for an object.</p>
+<p>The width and height parts of the geometry specification are measured
+in pixels. The xoffset and yoffset parts are also measured in pixels
+and are used to specify the distance of the placement coordinate from
+the left and top and edges of the image, respectively. Both types of
+offsets are measured from the indicated edge of the object to the
+corresponding edge of the image. The X offset may be specified in the
+following ways:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="13%" />
+<col width="87%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>+xoffset</td>
+<td>The left edge of the object is to be placed xoffset
+pixels in from the left edge of the image.</td>
+</tr>
+<tr><td>-xoffset</td>
+<td>The left edge of the object is to be placed outside the
+image, xoffset pixels out from the left edge of the image.</td>
+</tr>
+</tbody>
+</table>
+<p>The Y offset has similar meanings:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="14%" />
+<col width="86%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>+yoffset</td>
+<td>The top edge of the object is to be yoffset pixels below
+the top edge of the image.</td>
+</tr>
+<tr><td>-yoffset</td>
+<td>The top edge of the object is to be yoffset pixels above
+the top edge of the image.</td>
+</tr>
+</tbody>
+</table>
+<p>Offsets must be given as pairs; in other words, in order to specify
+either xoffset or yoffset both must be present.</p>
+</div>
+<div class="section" id="graphicsmagick-extensions-to-x11-geometry-specifications">
+<h1>GraphicsMagick Extensions To X11 Geometry Specifications</h1>
+<p>GraphicsMagick has added a number of qualifiers to the standard
+geometry string for use when resizing images. The form of an extended
+geometry string is
+&quot;&lt;width&gt;x&lt;height&gt;{+-}&lt;xoffset&gt;{+-}&lt;yoffset&gt;{%}{&#64;}{!}{^}{&lt;}{&gt;}&quot;. Extended
+geometry strings should only be used when resizing an image. Using an
+extended geometry string for other applications may cause the API call
+to fail. The available qualifiers are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>GraphicsMagick Geometry Qualifiers</caption>
+<colgroup>
+<col width="12%" />
+<col width="88%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Qualifier</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>%</td>
+<td>Interpret width and height as a percentage of the current size.</td>
+</tr>
+<tr><td>!</td>
+<td>Resize to width and height exactly, loosing original aspect ratio.</td>
+</tr>
+<tr><td>&lt;</td>
+<td>Resize only if the image is smaller than the geometry specification.</td>
+</tr>
+<tr><td>&gt;</td>
+<td>Resize only if the image is greater than the geometry specification.</td>
+</tr>
+<tr><td>&#64;</td>
+<td>Resize such that width and height are a maximum area in total pixels.</td>
+</tr>
+<tr><td>^</td>
+<td>Dimensions are treated as minimum rather than maximum values.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="postscript-page-size-extension-to-geometry-specifications">
+<h1>Postscript Page Size Extension To Geometry Specifications</h1>
+<p>Any geometry string specification supplied to the Geometry constructor
+is considered to be a Postscript page size nickname if the first
+character is not numeric. The page size nickname is not case
+sensitive. The Geometry constructor converts these page size
+specifications into the equivalent numeric geometry string
+specification (preserving any offset component) prior to conversion to
+the internal object format. Postscript page size specifications are
+short-hand for the pixel geometry required to fill a page of that
+size. Since the 11x17 inch page size used in the US starts with a
+digit, it is not supported as a Postscript page size
+nickname. Instead, substitute the geometry specification &quot;792x1224&gt;&quot;
+when 11x17 output is desired.</p>
+<table border="1" class="docutils">
+<caption>Postscript Page Size Nicknames</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Postscript Nickname</th>
+<th class="head">Equivalent Extended Geometry Specification</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>A0</td>
+<td>2384x3370&gt;</td>
+</tr>
+<tr><td>A1</td>
+<td>1684x2384&gt;</td>
+</tr>
+<tr><td>A10</td>
+<td>73x105&gt;</td>
+</tr>
+<tr><td>A2</td>
+<td>1191x1684&gt;</td>
+</tr>
+<tr><td>A3</td>
+<td>842x1191&gt;</td>
+</tr>
+<tr><td>A4</td>
+<td>595x842&gt;</td>
+</tr>
+<tr><td>A4SMALL</td>
+<td>595x842&gt;</td>
+</tr>
+<tr><td>A5</td>
+<td>420x595&gt;</td>
+</tr>
+<tr><td>A6</td>
+<td>297x420&gt;</td>
+</tr>
+<tr><td>A7</td>
+<td>210x297&gt;</td>
+</tr>
+<tr><td>A8</td>
+<td>148x210&gt;</td>
+</tr>
+<tr><td>A9</td>
+<td>105x148&gt;</td>
+</tr>
+<tr><td>ARCHA</td>
+<td>648x864&gt;</td>
+</tr>
+<tr><td>ARCHB</td>
+<td>864x1296&gt;</td>
+</tr>
+<tr><td>ARCHC</td>
+<td>1296x1728&gt;</td>
+</tr>
+<tr><td>ARCHD</td>
+<td>1728x2592&gt;</td>
+</tr>
+<tr><td>ARCHE</td>
+<td>2592x3456&gt;</td>
+</tr>
+<tr><td>B0</td>
+<td>2920x4127&gt;</td>
+</tr>
+<tr><td>B1</td>
+<td>2064x2920&gt;</td>
+</tr>
+<tr><td>B10</td>
+<td>91x127&gt;</td>
+</tr>
+<tr><td>B2</td>
+<td>1460x2064&gt;</td>
+</tr>
+<tr><td>B3</td>
+<td>1032x1460&gt;</td>
+</tr>
+<tr><td>B4</td>
+<td>729x1032&gt;</td>
+</tr>
+<tr><td>B5</td>
+<td>516x729&gt;</td>
+</tr>
+<tr><td>B6</td>
+<td>363x516&gt;</td>
+</tr>
+<tr><td>B7</td>
+<td>258x363&gt;</td>
+</tr>
+<tr><td>B8</td>
+<td>181x258&gt;</td>
+</tr>
+<tr><td>B9</td>
+<td>127x181&gt;</td>
+</tr>
+<tr><td>C0</td>
+<td>2599x3676&gt;</td>
+</tr>
+<tr><td>C1</td>
+<td>1837x2599&gt;</td>
+</tr>
+<tr><td>C2</td>
+<td>1298x1837&gt;</td>
+</tr>
+<tr><td>C3</td>
+<td>918x1296&gt;</td>
+</tr>
+<tr><td>C4</td>
+<td>649x918&gt;</td>
+</tr>
+<tr><td>C5</td>
+<td>459x649&gt;</td>
+</tr>
+<tr><td>C6</td>
+<td>323x459&gt;</td>
+</tr>
+<tr><td>C7</td>
+<td>230x323&gt;</td>
+</tr>
+<tr><td>EXECUTIVE</td>
+<td>540x720&gt;</td>
+</tr>
+<tr><td>FLSA</td>
+<td>612x936&gt;</td>
+</tr>
+<tr><td>FLSE</td>
+<td>612x936&gt;</td>
+</tr>
+<tr><td>FOLIO</td>
+<td>612x936&gt;</td>
+</tr>
+<tr><td>HALFLETTER</td>
+<td>396x612&gt;</td>
+</tr>
+<tr><td>ISOB0</td>
+<td>2835x4008&gt;</td>
+</tr>
+<tr><td>ISOB1</td>
+<td>2004x2835&gt;</td>
+</tr>
+<tr><td>ISOB10</td>
+<td>88x125&gt;</td>
+</tr>
+<tr><td>ISOB2</td>
+<td>1417x2004&gt;</td>
+</tr>
+<tr><td>ISOB3</td>
+<td>1001x1417&gt;</td>
+</tr>
+<tr><td>ISOB4</td>
+<td>709x1001&gt;</td>
+</tr>
+<tr><td>ISOB5</td>
+<td>499x709&gt;</td>
+</tr>
+<tr><td>ISOB6</td>
+<td>354x499&gt;</td>
+</tr>
+<tr><td>ISOB7</td>
+<td>249x354&gt;</td>
+</tr>
+<tr><td>ISOB8</td>
+<td>176x249&gt;</td>
+</tr>
+<tr><td>ISOB9</td>
+<td>125x176&gt;</td>
+</tr>
+<tr><td>LEDGER</td>
+<td>1224x792&gt;</td>
+</tr>
+<tr><td>LEGAL</td>
+<td>612x1008&gt;</td>
+</tr>
+<tr><td>LETTER</td>
+<td>612x792&gt;</td>
+</tr>
+<tr><td>LETTERSMALL</td>
+<td>612x792&gt;</td>
+</tr>
+<tr><td>QUARTO</td>
+<td>610x780&gt;</td>
+</tr>
+<tr><td>STATEMENT</td>
+<td>396x612&gt;</td>
+</tr>
+<tr><td>TABLOID</td>
+<td>792x1224&gt;</td>
+</tr>
+</tbody>
+</table>
+<p>The following is the definition of the Magick::Geometry class:</p>
+<pre class="literal-block">
+class Geometry
+{
+public:
+
+ Geometry ( unsigned int width_,
+ unsigned int height_,
+ unsigned int xOff_ = 0,
+ unsigned int yOff_ = 0,
+ bool xNegative_ = false,
+ bool yNegative_ = false );
+ Geometry ( const std::string &amp;geometry_ );
+ Geometry ( const char * geometry_ );
+ Geometry ( const Geometry &amp;geometry_ );
+ Geometry ( );
+ ~Geometry ( void );
+
+ // Width
+ void width ( unsigned int width_ );
+ unsigned int width ( void ) const;
+
+ // Height
+ void height ( unsigned int height_ );
+ unsigned int height ( void ) const;
+
+ // X offset from origin
+ void xOff ( unsigned int xOff_ );
+ unsigned int xOff ( void ) const;
+
+ // Y offset from origin
+ void yOff ( unsigned int yOff_ );
+ unsigned int yOff ( void ) const;
+
+ // Sign of X offset negative? (X origin at right)
+ void xNegative ( bool xNegative_ );
+ bool xNegative ( void ) const;
+
+ // Sign of Y offset negative? (Y origin at bottom)
+ void yNegative ( bool yNegative_ );
+ bool yNegative ( void ) const;
+
+ // Width and height are expressed as percentages
+ void percent ( bool percent_ );
+ bool percent ( void ) const;
+
+ // Resize without preserving aspect ratio (!)
+ void aspect ( bool aspect_ );
+ bool aspect ( void ) const;
+
+ // Resize if image is greater than size (&gt;)
+ void greater ( bool greater_ );
+ bool greater ( void ) const;
+
+ // Resize if image is less than size (&lt;)
+ void less ( bool less_ );
+ bool less ( void ) const;
+
+ // Resize image to fit total pixel area specified by dimensions (&#64;).
+ void limitPixels ( bool limitPixels_ );
+ bool limitPixels ( void ) const;
+
+ // Dimensions are treated as minimum rather than maximum values (^)
+ void fillArea ( bool fillArea_ );
+ bool fillArea ( void ) const;
+
+ // Does object contain valid geometry?
+ void isValid ( bool isValid_ );
+ bool isValid ( void ) const;
+
+ // Set via geometry string
+ const Geometry&amp; operator = ( const std::string &amp;geometry_ );
+ const Geometry&amp; operator = ( const char * geometry_ );
+
+ // Assignment operator
+ Geometry&amp; operator= ( const Geometry&amp; Geometry_ );
+
+ // Return geometry string
+ operator std::string() const;
+
+};
+</pre>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Geometry.rst b/www/Magick++/Geometry.rst
new file mode 100644
index 0000000..7d1691d
--- /dev/null
+++ b/www/Magick++/Geometry.rst
@@ -0,0 +1,240 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+================
+Magick::Geometry
+================
+
+Geometry provides a convenient means to specify a geometry
+argument. The object may be initialized from a C string or C++ string
+containing a geometry specification. It may also be initialized by
+more efficient parameterized constructors.
+
+X11 Geometry Specifications
+---------------------------
+
+X11 geometry specifications are in the form
+"<width>x<height>{+-}<xoffset>{+-}<yoffset>" (where width, height,
+xoffset, and yoffset are numbers) for specifying the size and
+placement location for an object.
+
+The width and height parts of the geometry specification are measured
+in pixels. The xoffset and yoffset parts are also measured in pixels
+and are used to specify the distance of the placement coordinate from
+the left and top and edges of the image, respectively. Both types of
+offsets are measured from the indicated edge of the object to the
+corresponding edge of the image. The X offset may be specified in the
+following ways:
+
+========= =========================================================
++xoffset The left edge of the object is to be placed xoffset
+ pixels in from the left edge of the image.
+-xoffset The left edge of the object is to be placed outside the
+ image, xoffset pixels out from the left edge of the image.
+========= =========================================================
+
+The Y offset has similar meanings:
+
+========= =========================================================
++yoffset The top edge of the object is to be yoffset pixels below
+ the top edge of the image.
+-yoffset The top edge of the object is to be yoffset pixels above
+ the top edge of the image.
+========= =========================================================
+
+Offsets must be given as pairs; in other words, in order to specify
+either xoffset or yoffset both must be present.
+
+GraphicsMagick Extensions To X11 Geometry Specifications
+--------------------------------------------------------
+
+GraphicsMagick has added a number of qualifiers to the standard
+geometry string for use when resizing images. The form of an extended
+geometry string is
+"<width>x<height>{+-}<xoffset>{+-}<yoffset>{%}{@}{!}{^}{<}{>}". Extended
+geometry strings should only be used when resizing an image. Using an
+extended geometry string for other applications may cause the API call
+to fail. The available qualifiers are shown in the following table:
+
+.. table:: GraphicsMagick Geometry Qualifiers
+
+ ========= ======================================================
+ Qualifier Description
+ ========= ======================================================
+ % Interpret width and height as a percentage of the current size.
+ ! Resize to width and height exactly, loosing original aspect ratio.
+ < Resize only if the image is smaller than the geometry specification.
+ > Resize only if the image is greater than the geometry specification.
+ @ Resize such that width and height are a maximum area in total pixels.
+ ^ Dimensions are treated as minimum rather than maximum values.
+ ========= ======================================================
+
+Postscript Page Size Extension To Geometry Specifications
+---------------------------------------------------------
+
+Any geometry string specification supplied to the Geometry constructor
+is considered to be a Postscript page size nickname if the first
+character is not numeric. The page size nickname is not case
+sensitive. The Geometry constructor converts these page size
+specifications into the equivalent numeric geometry string
+specification (preserving any offset component) prior to conversion to
+the internal object format. Postscript page size specifications are
+short-hand for the pixel geometry required to fill a page of that
+size. Since the 11x17 inch page size used in the US starts with a
+digit, it is not supported as a Postscript page size
+nickname. Instead, substitute the geometry specification "792x1224>"
+when 11x17 output is desired.
+
+.. table:: Postscript Page Size Nicknames
+
+ ==================== ==========================================
+ Postscript Nickname Equivalent Extended Geometry Specification
+ ==================== ==========================================
+ A0 2384x3370>
+ A1 1684x2384>
+ A10 73x105>
+ A2 1191x1684>
+ A3 842x1191>
+ A4 595x842>
+ A4SMALL 595x842>
+ A5 420x595>
+ A6 297x420>
+ A7 210x297>
+ A8 148x210>
+ A9 105x148>
+ ARCHA 648x864>
+ ARCHB 864x1296>
+ ARCHC 1296x1728>
+ ARCHD 1728x2592>
+ ARCHE 2592x3456>
+ B0 2920x4127>
+ B1 2064x2920>
+ B10 91x127>
+ B2 1460x2064>
+ B3 1032x1460>
+ B4 729x1032>
+ B5 516x729>
+ B6 363x516>
+ B7 258x363>
+ B8 181x258>
+ B9 127x181>
+ C0 2599x3676>
+ C1 1837x2599>
+ C2 1298x1837>
+ C3 918x1296>
+ C4 649x918>
+ C5 459x649>
+ C6 323x459>
+ C7 230x323>
+ EXECUTIVE 540x720>
+ FLSA 612x936>
+ FLSE 612x936>
+ FOLIO 612x936>
+ HALFLETTER 396x612>
+ ISOB0 2835x4008>
+ ISOB1 2004x2835>
+ ISOB10 88x125>
+ ISOB2 1417x2004>
+ ISOB3 1001x1417>
+ ISOB4 709x1001>
+ ISOB5 499x709>
+ ISOB6 354x499>
+ ISOB7 249x354>
+ ISOB8 176x249>
+ ISOB9 125x176>
+ LEDGER 1224x792>
+ LEGAL 612x1008>
+ LETTER 612x792>
+ LETTERSMALL 612x792>
+ QUARTO 610x780>
+ STATEMENT 396x612>
+ TABLOID 792x1224>
+ ==================== ==========================================
+
+The following is the definition of the Magick::Geometry class::
+
+ class Geometry
+ {
+ public:
+
+ Geometry ( unsigned int width_,
+ unsigned int height_,
+ unsigned int xOff_ = 0,
+ unsigned int yOff_ = 0,
+ bool xNegative_ = false,
+ bool yNegative_ = false );
+ Geometry ( const std::string &geometry_ );
+ Geometry ( const char * geometry_ );
+ Geometry ( const Geometry &geometry_ );
+ Geometry ( );
+ ~Geometry ( void );
+
+ // Width
+ void width ( unsigned int width_ );
+ unsigned int width ( void ) const;
+
+ // Height
+ void height ( unsigned int height_ );
+ unsigned int height ( void ) const;
+
+ // X offset from origin
+ void xOff ( unsigned int xOff_ );
+ unsigned int xOff ( void ) const;
+
+ // Y offset from origin
+ void yOff ( unsigned int yOff_ );
+ unsigned int yOff ( void ) const;
+
+ // Sign of X offset negative? (X origin at right)
+ void xNegative ( bool xNegative_ );
+ bool xNegative ( void ) const;
+
+ // Sign of Y offset negative? (Y origin at bottom)
+ void yNegative ( bool yNegative_ );
+ bool yNegative ( void ) const;
+
+ // Width and height are expressed as percentages
+ void percent ( bool percent_ );
+ bool percent ( void ) const;
+
+ // Resize without preserving aspect ratio (!)
+ void aspect ( bool aspect_ );
+ bool aspect ( void ) const;
+
+ // Resize if image is greater than size (>)
+ void greater ( bool greater_ );
+ bool greater ( void ) const;
+
+ // Resize if image is less than size (<)
+ void less ( bool less_ );
+ bool less ( void ) const;
+
+ // Resize image to fit total pixel area specified by dimensions (@).
+ void limitPixels ( bool limitPixels_ );
+ bool limitPixels ( void ) const;
+
+ // Dimensions are treated as minimum rather than maximum values (^)
+ void fillArea ( bool fillArea_ );
+ bool fillArea ( void ) const;
+
+ // Does object contain valid geometry?
+ void isValid ( bool isValid_ );
+ bool isValid ( void ) const;
+
+ // Set via geometry string
+ const Geometry& operator = ( const std::string &geometry_ );
+ const Geometry& operator = ( const char * geometry_ );
+
+ // Assignment operator
+ Geometry& operator= ( const Geometry& Geometry_ );
+
+ // Return geometry string
+ operator std::string() const;
+
+ };
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/Image.fig b/www/Magick++/Image.fig
new file mode 100644
index 0000000..10d0e2c
--- /dev/null
+++ b/www/Magick++/Image.fig
@@ -0,0 +1,98 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+0
+1200 2
+6 5250 4125 7425 5175
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 5325 4350 7425 4350 7425 5175 5325 5175 5325 4350
+4 1 0 0 0 0 10 0.0000 4 135 810 6450 4275 class Options\001
+4 2 0 0 0 0 8 0.0000 4 135 1785 7350 4575 MagickLib::ImageInfo* _imageInfo\001
+4 2 0 0 0 0 8 0.0000 4 135 2040 7350 4800 MagickLib::QuantizeInfo* _quantizeInfo\001
+4 2 0 0 0 0 8 0.0000 4 135 1875 7350 5025 MagickLib::QuantizeInfo* _drawInfo\001
+-6
+6 600 4800 2400 5625
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 600 5025 2400 5025 2400 5625 600 5625 600 5025
+4 1 0 0 0 0 10 0.0000 4 135 690 1500 4950 class Image\001
+4 2 0 0 0 0 8 0.0000 4 135 1395 2325 5400 class ImageRef* _imageRef\001
+-6
+6 1425 3600 1575 4650
+1 3 0 1 0 0 0 0 20 0.000 1 0.0000 1500 3675 75 75 1500 3675 1500 3750
+1 3 0 1 0 0 0 0 20 0.000 1 0.0000 1500 4125 75 75 1500 4125 1500 4200
+1 3 0 1 0 0 0 0 20 0.000 1 0.0000 1500 4575 75 75 1500 4575 1500 4650
+-6
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4800 2400 5325 2400
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4800 2775 5550 4350
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2400 5325 3075 3600
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2400 3000 3075 3000
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2400 1800 3075 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7425 4500 8100 3900
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7425 2250 8100 2250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 60.00 120.00
+ 7425 2550 7800 2550 7800 2850 8100 2850
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 600 2700 2400 2700 2400 3300 600 3300 600 2700
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 600 1500 2400 1500 2400 2100 600 2100 600 1500
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 8100 2100 9300 2100 9300 2400 8100 2400 8100 2100
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 8100 2700 9300 2700 9300 3000 8100 3000 8100 2700
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 8100 3600 9300 3600 9300 4200 8100 4200 8100 3600
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 8100 4500 9300 4500 9300 5100 8100 5100 8100 4500
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 8100 5400 9300 5400 9300 6000 8100 6000 8100 5400
+2 2 0 1 11 11 100 0 25 0.000 0 0 7 0 0 5
+ 75 300 9825 300 9825 6150 75 6150 75 300
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7425 4800 8100 4800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7425 5025 8100 5700
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 3075 2100 4800 2100 4800 3900 3075 3900 3075 2100
+2 2 0 1 0 6 5 0 32 0.000 0 0 7 0 0 5
+ 5325 2100 7425 2100 7425 2700 5325 2700 5325 2100
+4 1 0 0 0 18 14 0.0000 4 210 3300 5250 900 Magick++ Image Data Structures\001
+4 1 0 0 0 0 10 0.0000 4 135 690 1575 1425 class Image\001
+4 1 0 0 0 0 10 0.0000 4 135 690 1500 2625 class Image\001
+4 1 0 0 0 0 10 0.0000 4 135 1725 8700 3525 struct MagickLib::ImageInfo\001
+4 1 0 0 0 0 10 0.0000 4 135 1890 8700 4425 struct MagickLib::QuantizeInfo\001
+4 2 0 0 0 0 8 0.0000 4 135 1395 2325 1875 class ImageRef* _imageRef\001
+4 2 0 0 0 0 8 0.0000 4 135 1395 2325 3075 class ImageRef* _imageRef\001
+4 2 0 0 0 0 8 0.0000 4 135 1665 4725 2475 struct MagickLib::Image* _image\001
+4 1 0 0 0 0 10 0.0000 4 135 1680 8700 5325 struct MagickLib::DrawInfo\001
+4 2 0 0 0 0 8 0.0000 4 135 1485 4725 3750 class MutexLock _mutexLock\001
+4 2 0 0 0 0 8 0.0000 4 135 1140 4725 2850 class Options* _options\001
+4 2 0 0 0 0 8 0.0000 4 135 390 4725 3150 long _id\001
+4 2 0 0 0 0 8 0.0000 4 135 645 4725 3450 int _refCount\001
+4 1 0 0 0 0 10 0.0000 4 135 675 8708 2295 Image Data\001
+4 1 0 0 0 0 10 0.0000 4 135 1005 8700 2902 Image Attributes\001
+4 1 0 0 0 0 10 0.0000 4 135 1485 6450 2025 struct MagickLib::Image\001
+4 1 0 0 0 0 10 0.0000 4 135 900 3975 1950 class ImageRef\001
+4 1 0 0 0 0 10 0.0000 4 105 150 2625 2925 ref\001
+4 1 0 0 0 0 10 0.0000 4 105 150 2625 1875 ref\001
+4 1 0 0 0 0 10 0.0000 4 105 150 2625 4425 ref\001
diff --git a/www/Magick++/Image.html b/www/Magick++/Image.html
new file mode 100644
index 0000000..99da532
--- /dev/null
+++ b/www/Magick++/Image.html
@@ -0,0 +1,3003 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Image Class</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-image-class">
+<h1 class="title">Magick::Image Class</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#introduction" id="id9">Introduction</a></li>
+<li><a class="reference internal" href="#blobs" id="id10">BLOBs</a></li>
+<li><a class="reference internal" href="#construct-an-image" id="id11">Construct An Image</a></li>
+<li><a class="reference internal" href="#read-or-write-an-image" id="id12">Read Or Write An Image</a></li>
+<li><a class="reference internal" href="#manipulate-an-image" id="id13">Manipulate An Image</a></li>
+<li><a class="reference internal" href="#set-get-image-attributes" id="id14">Set/Get Image Attributes</a></li>
+<li><a class="reference internal" href="#low-level-image-pixel-access" id="id15">Low-Level Image Pixel Access</a></li>
+</ul>
+</div>
+<div class="section" id="introduction">
+<h1><a class="toc-backref" href="#id9">Introduction</a></h1>
+<p>Image is the primary object in Magick++ and represents a single image
+frame (see <a class="reference external" href="ImageDesign.html">image design</a>). The <a class="reference external" href="STL.html">STL</a> interface must be used to
+operate on image sequences or images (e.g. of format GIF, TIFF, MIFF,
+Postscript, &amp; MNG) which are comprized of multiple image
+frames. Individual frames of a multi-frame image may be requested by
+adding array-style notation to the end of the file name
+(e.g. &quot;animation.gif[3]&quot; retrieves the fourth frame of a GIF
+animation. Various image manipulation operations may be applied to
+the image. Attributes may be set on the image to influence the
+operation of the manipulation operations. The <a class="reference external" href="Pixels.html">Pixels</a> class provides
+low-level access to image pixels. As a convenience, including
+&lt;Magick++.h&gt; is sufficient in order to use the complete Magick++
+API. The Magick++ API is enclosed within the Magick namespace so you
+must either add the prefix &quot; Magick:: &quot; to each class/enumeration name
+or add the statement &quot; using namespace Magick;&quot; after including the
+Magick++.h header.</p>
+<p>The InitializeMagick() function <em>MUST</em> be invoked before constructing
+any Magick++ objects. This used to be optional, but now it is
+absolutely required. This function initalizes semaphores and
+configuration information necessary for the software to work
+correctly. Failing to invoke InitializeMagick() is likely to lead to
+a program crash or thrown assertion. If the program resides in the
+same directory as the GraphicsMagick files, then argv[0] may be passed
+as an argument so that GraphicsMagick knows where its files reside,
+otherwise NULL may be passed and GraphicsMagick will try to use other
+means (if necessary).</p>
+<p>The preferred way to allocate Image objects is via automatic
+allocation (on the stack). There is no concern that allocating Image
+objects on the stack will excessively enlarge the stack since Magick++
+allocates all large data objects (such as the actual image data) from
+the heap. Use of automatic allocation is preferred over explicit
+allocation (via new) since it is much less error prone and allows use
+of C++ scoping rules to avoid memory leaks. Use of automatic
+allocation allows Magick++ objects to be assigned and copied just like
+the C++ intrinsic data types (e.g. 'int '), leading to clear and easy
+to read code. Use of automatic allocation leads to naturally
+exception-safe code since if an exception is thrown, the object is
+automatically deallocated once the stack unwinds past the scope of the
+allocation (not the case for objects allocated via new ).</p>
+<p>Image is very easy to use. For example, here is a the source to a
+program which reads an image, crops it, and writes it to a new file
+(the exception handling is optional but strongly recommended):</p>
+<pre class="literal-block">
+#include &lt;Magick++.h&gt;
+#include &lt;iostream&gt;
+using namespace std;
+using namespace Magick;
+int main(int argc,char **argv)
+{
+ // Initialize the API. Can pass NULL if argv is not available.
+ InitializeMagick(*argv);
+
+ // Construct the image object. Seperating image construction from the
+ // the read operation ensures that a failure to read the image file
+ // doesn't render the image object useless.
+ Image image;
+
+ try {
+ // Determine if Warning exceptions are thrown.
+ // Use is optional. Set to true to block Warning exceptions.
+ image.quiet( false );
+
+ // Read a file into image object
+ image.read( &quot;girl.gif&quot; );
+
+ // Crop the image to specified size (width, height, xOffset, yOffset)
+ image.crop( Geometry(100,100, 100, 100) );
+
+ // Write the image to a file
+ image.write( &quot;x.gif&quot; );
+ }
+ catch( Exception &amp;error_ )
+ {
+ cout &lt;&lt; &quot;Caught exception: &quot; &lt;&lt; error_.what() &lt;&lt; endl;
+ return 1;
+ }
+ return 0;
+}
+</pre>
+<p>The following is the source to a program which illustrates the use of
+Magick++'s efficient reference-counted assignment and copy-constructor
+operations which minimize use of memory and eliminate unncessary copy
+operations (allowing Image objects to be efficiently assigned, and
+copied into containers). The program accomplishes the following:</p>
+<ol class="arabic simple">
+<li>Read master image.</li>
+<li>Assign master image to second image.</li>
+<li>Zoom second image to the size 640x480.</li>
+<li>Assign master image to a third image.</li>
+<li>Zoom third image to the size 800x600.</li>
+<li>Write the second image to a file.</li>
+<li>Write the third image to a file.</li>
+</ol>
+<pre class="literal-block">
+#include &lt;Magick++.h&gt;
+#include &lt;iostream&gt;
+using namespace std;
+using namespace Magick;
+int main(int argc,char **argv)
+{
+ InitializeMagick(*argv);
+ Image master(&quot;horse.jpg&quot;);
+ Image second = master;
+ second.zoom(&quot;640x480&quot;);
+ Image third = master;
+ third.zoom(&quot;800x600&quot;);
+ second.write(&quot;horse640x480.jpg&quot;);
+ third.write(&quot;horse800x600.jpg&quot;);
+ return 0;
+}
+</pre>
+<p>During the entire operation, a maximum of three images exist in memory
+and the image data is never copied.</p>
+<p>The following is the source for another simple program which creates a
+100 by 100 pixel white image with a red pixel in the center and writes
+it to a file:</p>
+<pre class="literal-block">
+#include &lt;Magick++.h&gt;
+using namespace std;
+using namespace Magick;
+int main(int argc,char **argv)
+{
+ InitializeMagick(*argv);
+ Image image( &quot;100x100&quot;, &quot;white&quot; );
+ image.pixelColor( 49, 49, &quot;red&quot; );
+ image.write( &quot;red_pixel.png&quot; );
+ return 0;
+}
+</pre>
+<p>If you wanted to change the color image to grayscale, you could add
+the lines:</p>
+<pre class="literal-block">
+image.quantizeColorSpace( GRAYColorspace );
+image.quantizeColors( 256 );
+image.quantize( );
+</pre>
+<p>or, more simply:</p>
+<pre class="literal-block">
+image.type( GrayscaleType );
+</pre>
+<p>prior to writing the image.</p>
+</div>
+<div class="section" id="blobs">
+<h1><a class="toc-backref" href="#id10">BLOBs</a></h1>
+<p>While encoded images (e.g. JPEG) are most often written-to and
+read-from a disk file, encoded images may also reside in
+memory. Encoded images in memory are known as BLOBs (Binary Large
+OBjects) and may be represented using the <a class="reference external" href="Blob.html">Blob</a> class. The encoded
+image may be initially placed in memory by reading it directly from a
+file, reading the image from a database, memory-mapped from a disk
+file, or could be written to memory by Magick++. Once the encoded
+image has been placed within a <a class="reference external" href="Blob.html">Blob</a>, it may be read into a Magick++
+Image via a constructor or read() . Likewise, a Magick++ image may be
+written to a <a class="reference external" href="Blob.html">Blob</a> via write().</p>
+<p>An example of using Image to write to a <a class="reference external" href="Blob.html">Blob</a> follows:</p>
+<pre class="literal-block">
+#include &lt;Magick++.h&gt;
+using namespace std;
+using namespace Magick;
+int main(int argc,char **argv)
+{
+ // Read GIF file from disk
+ Image image( &quot;giraffe.gif&quot; );
+
+ // Write to BLOB in JPEG format
+ Blob blob;
+ image.magick( &quot;JPEG&quot; ) // Set JPEG output format
+ image.write( &amp;blob );
+
+ [ Use BLOB data (in JPEG format) here ]
+
+ return 0;
+}
+</pre>
+<p>likewise, to read an image from a <a class="reference external" href="Blob.html">Blob</a>, you could use one of the
+following examples:</p>
+<p>[ Entry condition for the following examples is that data is pointer
+to encoded image data and length represents the size of the data ]</p>
+<pre class="literal-block">
+Blob blob( data, length );
+Image image( blob );
+</pre>
+<p>or</p>
+<pre class="literal-block">
+Blob blob( data, length );
+Image image;
+image.read( blob);
+</pre>
+<p>Some images do not contain their size or format so the size and format
+must be specified in advance:</p>
+<pre class="literal-block">
+Blob blob( data, length );
+Image image;
+image.size( &quot;640x480&quot;)
+image.magick( &quot;RGBA&quot; );
+image.read( blob);
+</pre>
+</div>
+<div class="section" id="construct-an-image">
+<h1><a class="toc-backref" href="#id11">Construct An Image</a></h1>
+<p>An Image may be constructed in a number of ways. It may be constructed
+from a file, a URL, or an encoded image (e.g. JPEG) contained in an
+in-memory <a class="reference external" href="Blob.html">Blob</a> . The following Image constructors and assignment
+operators are available:</p>
+<p>Construct from image file or image specification:</p>
+<pre class="literal-block">
+Image( const std::string &amp;imageSpec_ )
+</pre>
+<p>Construct a blank image canvas of specified size and <a class="reference external" href="Color.html">color</a>:</p>
+<pre class="literal-block">
+Image( const Geometry &amp;size_, const Color &amp;color_ )
+</pre>
+<p>Construct Image from in-memory <a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+Image ( const Blob &amp;blob_ )
+</pre>
+<p>Construct Image of specified size from in-memory <a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+Image ( const Blob &amp;blob_, const Geometry &amp;size_ )
+</pre>
+<p>Construct Image of specified size and depth from in-memory <a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+Image ( const Blob &amp;blob_, const Geometry &amp;size,
+ const unsigned int depth )
+</pre>
+<p>Construct Image of specified size, depth, and format from in-memory <a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+Image ( const Blob &amp;blob_, const Geometry &amp;size,
+ const unsigned int depth_,
+ const std::string &amp;magick_ )
+</pre>
+<p>Construct Image of specified size, and format from in-memory <a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+Image ( const Blob &amp;blob_, const Geometry &amp;size,
+ const std::string &amp;magick_ )
+</pre>
+<p>Construct an image based on an array of raw pixels, of specified type
+and mapping, in memory:</p>
+<pre class="literal-block">
+Image ( const unsigned int width_,
+ const unsigned int height_,
+ const std::string &amp;map_,
+ const StorageType type_,
+ const void *pixels_ )
+</pre>
+<p>Default constructor:</p>
+<pre class="literal-block">
+Image( void )
+</pre>
+<p>Copy constructor:</p>
+<pre class="literal-block">
+Image ( const Image &amp; image_ )
+</pre>
+<p>Assignment operator:</p>
+<pre class="literal-block">
+Image&amp; operator= ( const Image &amp;image_ )
+</pre>
+</div>
+<div class="section" id="read-or-write-an-image">
+<h1><a class="toc-backref" href="#id12">Read Or Write An Image</a></h1>
+<div class="contents local topic" id="id1">
+<ul class="simple">
+<li><a class="reference internal" href="#ping" id="id16">ping</a></li>
+<li><a class="reference internal" href="#read" id="id17">read</a></li>
+<li><a class="reference internal" href="#write" id="id18">write</a></li>
+</ul>
+</div>
+<div class="section" id="ping">
+<h2><a class="toc-backref" href="#id16">ping</a></h2>
+<p>Ping is similar to <a class="reference internal" href="#read">read</a> except only enough of the image is read to
+determine the image columns, rows, and filesize. Access the
+columns(), rows(), and fileSize() attributes after invoking ping.
+Other attributes may also be available. The image pixels are not
+valid after calling ping:</p>
+<pre class="literal-block">
+void ping ( const std::string &amp;imageSpec_ )
+</pre>
+<p>Ping is similar to read except only enough of the image is read
+to determine the image columns, rows, and filesize. Access the
+columns(), rows(), and fileSize() attributes after invoking
+ping. The image pixels are not valid after calling ping:</p>
+<pre class="literal-block">
+void ping ( const Blob &amp;blob_ )
+</pre>
+</div>
+<div class="section" id="read">
+<h2><a class="toc-backref" href="#id17">read</a></h2>
+<p>Read single image frame into current object. Use <a class="reference internal" href="#ping">ping</a> instead if you
+want to obtain the basic attributes of the image without reading the
+whole file/blob:</p>
+<pre class="literal-block">
+void read ( const std::string &amp;imageSpec_ )
+</pre>
+<p>Read single image frame of specified size into current object:</p>
+<pre class="literal-block">
+void read ( const Geometry &amp;size_,
+ const std::string &amp;imageSpec_ )
+</pre>
+<p>Read single image frame from in-memory <a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+void read ( const Blob &amp;blob_ )
+</pre>
+<p>Read single image frame of specified size from in-memory <a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+void read ( const Blob &amp;blob_,
+ const Geometry &amp;size_ )
+</pre>
+<p>Read single image frame of specified size and depth from in-memory
+<a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+void read ( const Blob &amp;blob_,
+ const Geometry &amp;size_,
+ const unsigned int depth_ )
+</pre>
+<p>Read single image frame of specified size, depth, and format from
+in-memory <a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+void read ( const Blob &amp;blob_,
+ const Geometry &amp;size_,
+ const unsigned int depth_,
+ const std::string &amp;magick_ )
+</pre>
+<p>Read single image frame of specified size, and format from in-memory
+<a class="reference external" href="Blob.html">Blob</a>:</p>
+<pre class="literal-block">
+void read ( const Blob &amp;blob_,
+ const Geometry &amp;size_,
+ const std::string &amp;magick_ )
+</pre>
+<p>Read single image frame from an array of raw pixels, with
+specified storage type (ConstituteImage), e.g.
+<tt class="docutils literal">image.read( 640, 480, &quot;RGB&quot;, 0, pixels )</tt>:</p>
+<pre class="literal-block">
+void read ( const unsigned int width_,
+ const unsigned int height_,
+ const std::string &amp;map_,
+ const StorageType type_,
+ const void *pixels_ )
+</pre>
+</div>
+<div class="section" id="write">
+<h2><a class="toc-backref" href="#id18">write</a></h2>
+<p>Write single image frame to a file:</p>
+<pre class="literal-block">
+void write ( const std::string &amp;imageSpec_ )
+</pre>
+<p>Write single image frame to in-memory <a class="reference external" href="Blob.html">Blob</a>, with optional format and
+adjoin parameters:</p>
+<pre class="literal-block">
+void write ( Blob *blob_ )
+
+void write ( Blob *blob_,
+ const std::string &amp;magick_ )
+
+void write ( Blob *blob_,
+ const std::string &amp;magick_,
+ const unsigned int depth_ )
+</pre>
+<p>Write single image frame to an array of pixels with storage type
+specified by user (DispatchImage), e.g. <tt class="docutils literal">image.write( 0, 0, 640, 1,
+&quot;RGB&quot;, 0, pixels )</tt>:</p>
+<pre class="literal-block">
+void write ( const int x_,
+ const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const std::string&amp; map_,
+ const StorageType type_,
+ void *pixels_ )
+</pre>
+</div>
+</div>
+<div class="section" id="manipulate-an-image">
+<h1><a class="toc-backref" href="#id13">Manipulate An Image</a></h1>
+<p>Image supports access to all the single-image (versus image-list)
+manipulation operations provided by the GraphicsMagick library. If you
+must process a multi-image file (such as an animation), the <a class="reference external" href="STL.html">STL</a>
+interface , which provides a multi-image abstraction on top of Image,
+must be used.</p>
+<p>Image manipulation methods are very easy to use. For example:</p>
+<pre class="literal-block">
+Image image;
+image.read(&quot;myImage.tiff&quot;);
+image.addNoise(GaussianNoise);
+image.write(&quot;myImage.tiff&quot;);
+</pre>
+<p>adds gaussian noise to the image file &quot;myImage.tiff&quot;.</p>
+<p>The following image manipulation methods are available:</p>
+<div class="contents local topic" id="id2">
+<ul class="simple">
+<li><a class="reference internal" href="#adaptivethreshold" id="id19">adaptiveThreshold</a></li>
+<li><a class="reference internal" href="#addnoise" id="id20">addNoise</a></li>
+<li><a class="reference internal" href="#addnoisechannel" id="id21">addNoiseChannel</a></li>
+<li><a class="reference internal" href="#affinetransform" id="id22">affineTransform</a></li>
+<li><a class="reference internal" href="#annotate" id="id23">annotate</a></li>
+<li><a class="reference internal" href="#blur" id="id24">blur</a></li>
+<li><a class="reference internal" href="#blurchannel" id="id25">blurChannel</a></li>
+<li><a class="reference internal" href="#border" id="id26">border</a></li>
+<li><a class="reference internal" href="#cdl" id="id27">cdl</a></li>
+<li><a class="reference internal" href="#channel" id="id28">channel</a></li>
+<li><a class="reference internal" href="#channeldepth" id="id29">channelDepth</a></li>
+<li><a class="reference internal" href="#charcoal" id="id30">charcoal</a></li>
+<li><a class="reference internal" href="#chop" id="id31">chop</a></li>
+<li><a class="reference internal" href="#colorize" id="id32">colorize</a></li>
+<li><a class="reference internal" href="#colormatrix" id="id33">colorMatrix</a></li>
+<li><a class="reference internal" href="#comment" id="id34">comment</a></li>
+<li><a class="reference internal" href="#compare" id="id35">compare</a></li>
+<li><a class="reference internal" href="#composite" id="id36">composite</a></li>
+<li><a class="reference internal" href="#contrast" id="id37">contrast</a></li>
+<li><a class="reference internal" href="#convolve" id="id38">convolve</a></li>
+<li><a class="reference internal" href="#crop" id="id39">crop</a></li>
+<li><a class="reference internal" href="#cyclecolormap" id="id40">cycleColormap</a></li>
+<li><a class="reference internal" href="#despeckle" id="id41">despeckle</a></li>
+<li><a class="reference internal" href="#display" id="id42">display</a></li>
+<li><a class="reference internal" href="#draw" id="id43">draw</a></li>
+<li><a class="reference internal" href="#edge" id="id44">edge</a></li>
+<li><a class="reference internal" href="#emboss" id="id45">emboss</a></li>
+<li><a class="reference internal" href="#enhance" id="id46">enhance</a></li>
+<li><a class="reference internal" href="#equalize" id="id47">equalize</a></li>
+<li><a class="reference internal" href="#erase" id="id48">erase</a></li>
+<li><a class="reference internal" href="#extent" id="id49">extent</a></li>
+<li><a class="reference internal" href="#flip" id="id50">flip</a></li>
+<li><a class="reference internal" href="#floodfillcolor" id="id51">floodFillColor</a></li>
+<li><a class="reference internal" href="#floodfillopacity" id="id52">floodFillOpacity</a></li>
+<li><a class="reference internal" href="#floodfilltexture" id="id53">floodFillTexture</a></li>
+<li><a class="reference internal" href="#flop" id="id54">flop</a></li>
+<li><a class="reference internal" href="#frame" id="id55">frame</a></li>
+<li><a class="reference internal" href="#gamma" id="id56">gamma</a></li>
+<li><a class="reference internal" href="#gaussianblur" id="id57">gaussianBlur</a></li>
+<li><a class="reference internal" href="#gaussianblurchannel" id="id58">gaussianBlurChannel</a></li>
+<li><a class="reference internal" href="#implode" id="id59">implode</a></li>
+<li><a class="reference internal" href="#haldclut" id="id60">haldClut</a></li>
+<li><a class="reference internal" href="#label" id="id61">label</a></li>
+<li><a class="reference internal" href="#level" id="id62">level</a></li>
+<li><a class="reference internal" href="#levelchannel" id="id63">levelChannel</a></li>
+<li><a class="reference internal" href="#magnify" id="id64">magnify</a></li>
+<li><a class="reference internal" href="#map" id="id65">map</a></li>
+<li><a class="reference internal" href="#mattefloodfill" id="id66">matteFloodfill</a></li>
+<li><a class="reference internal" href="#medianfilter" id="id67">medianFilter</a></li>
+<li><a class="reference internal" href="#minify" id="id68">minify</a></li>
+<li><a class="reference internal" href="#modifyimage" id="id69">modifyImage</a></li>
+<li><a class="reference internal" href="#modulate" id="id70">modulate</a></li>
+<li><a class="reference internal" href="#motionblur" id="id71">motionBlur</a></li>
+<li><a class="reference internal" href="#negate" id="id72">negate</a></li>
+<li><a class="reference internal" href="#normalize" id="id73">normalize</a></li>
+<li><a class="reference internal" href="#oilpaint" id="id74">oilPaint</a></li>
+<li><a class="reference internal" href="#opacity" id="id75">opacity</a></li>
+<li><a class="reference internal" href="#opaque" id="id76">opaque</a></li>
+<li><a class="reference internal" href="#quantize" id="id77">quantize</a></li>
+<li><a class="reference internal" href="#quantumoperator" id="id78">quantumOperator</a></li>
+<li><a class="reference internal" href="#process" id="id79">process</a></li>
+<li><a class="reference internal" href="#raise" id="id80">raise</a></li>
+<li><a class="reference internal" href="#randomthreshold" id="id81">randomThreshold</a></li>
+<li><a class="reference internal" href="#randomthresholdchannel" id="id82">randomThresholdChannel</a></li>
+<li><a class="reference internal" href="#reducenoise" id="id83">reduceNoise</a></li>
+<li><a class="reference internal" href="#resize" id="id84">resize</a></li>
+<li><a class="reference internal" href="#roll" id="id85">roll</a></li>
+<li><a class="reference internal" href="#rotate" id="id86">rotate</a></li>
+<li><a class="reference internal" href="#sample" id="id87">sample</a></li>
+<li><a class="reference internal" href="#scale" id="id88">scale</a></li>
+<li><a class="reference internal" href="#thumbnail" id="id89">thumbnail</a></li>
+<li><a class="reference internal" href="#segment" id="id90">segment</a></li>
+<li><a class="reference internal" href="#shade" id="id91">shade</a></li>
+<li><a class="reference internal" href="#sharpen" id="id92">sharpen</a></li>
+<li><a class="reference internal" href="#sharpenchannel" id="id93">sharpenChannel</a></li>
+<li><a class="reference internal" href="#shave" id="id94">shave</a></li>
+<li><a class="reference internal" href="#shear" id="id95">shear</a></li>
+<li><a class="reference internal" href="#solarize" id="id96">solarize</a></li>
+<li><a class="reference internal" href="#spread" id="id97">spread</a></li>
+<li><a class="reference internal" href="#stegano" id="id98">stegano</a></li>
+<li><a class="reference internal" href="#stereo" id="id99">stereo</a></li>
+<li><a class="reference internal" href="#strip" id="id100">strip</a></li>
+<li><a class="reference internal" href="#swirl" id="id101">swirl</a></li>
+<li><a class="reference internal" href="#texture" id="id102">texture</a></li>
+<li><a class="reference internal" href="#threshold" id="id103">threshold</a></li>
+<li><a class="reference internal" href="#transform" id="id104">transform</a></li>
+<li><a class="reference internal" href="#transparent" id="id105">transparent</a></li>
+<li><a class="reference internal" href="#trim" id="id106">trim</a></li>
+<li><a class="reference internal" href="#type" id="id107">type</a></li>
+<li><a class="reference internal" href="#unsharpmask" id="id108">unsharpmask</a></li>
+<li><a class="reference internal" href="#unsharpmaskchannel" id="id109">unsharpmaskChannel</a></li>
+<li><a class="reference internal" href="#wave" id="id110">wave</a></li>
+<li><a class="reference internal" href="#zoom" id="id111">zoom</a></li>
+</ul>
+</div>
+<div class="section" id="adaptivethreshold">
+<h2><a class="toc-backref" href="#id19">adaptiveThreshold</a></h2>
+<p>Apply adaptive thresholding to the image (see
+<a class="reference external" href="http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm">http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm</a>). Adaptive
+thresholding is useful if the ideal threshold level is not known in
+advance, or if the illumination gradient is not constant across the
+image. Adaptive thresholding works by evaulating the mean (average) of
+a pixel region (size specified by width and height) and using the mean
+as the thresholding value. In order to remove residual noise from the
+background, the threshold may be adjusted by subtracting a constant
+offset (default zero) from the mean to compute the threshold:</p>
+<pre class="literal-block">
+void adaptiveThreshold ( const unsigned int width,
+ const unsigned int height,
+ const double offset = 0.0 )
+</pre>
+</div>
+<div class="section" id="addnoise">
+<h2><a class="toc-backref" href="#id20">addNoise</a></h2>
+<p>Add noise to image with the specified noise type:</p>
+<pre class="literal-block">
+void addNoise ( const NoiseType noiseType_ )
+</pre>
+</div>
+<div class="section" id="addnoisechannel">
+<h2><a class="toc-backref" href="#id21">addNoiseChannel</a></h2>
+<p>Add noise to an image channel with the specified noise type. The
+<cite>channel</cite> parameter specifies the channel to add noise to. The
+<cite>noiseType</cite> parameter specifies the type of noise:</p>
+<pre class="literal-block">
+void addNoiseChannel ( const ChannelType channel_,
+ const NoiseType noiseType_)
+</pre>
+</div>
+<div class="section" id="affinetransform">
+<h2><a class="toc-backref" href="#id22">affineTransform</a></h2>
+<p>Transform image by specified affine (or free transform) matrix:</p>
+<pre class="literal-block">
+void affineTransform ( const DrawableAffine &amp;affine )
+</pre>
+</div>
+<div class="section" id="annotate">
+<h2><a class="toc-backref" href="#id23">annotate</a></h2>
+<p>Annotate image (draw text on image)</p>
+<p>Gravity effects text placement in bounding area according to these
+rules:</p>
+<dl class="docutils">
+<dt>NorthWestGravity</dt>
+<dd>text bottom-left corner placed at top-left</dd>
+<dt>NorthGravity</dt>
+<dd>text bottom-center placed at top-center</dd>
+<dt>NorthEastGravity</dt>
+<dd>text bottom-right corner placed at top-right</dd>
+<dt>WestGravity</dt>
+<dd>text left-center placed at left-center</dd>
+<dt>CenterGravity</dt>
+<dd>text center placed at center</dd>
+<dt>EastGravity</dt>
+<dd>text right-center placed at right-center</dd>
+<dt>SouthWestGravity</dt>
+<dd>text top-left placed at bottom-left</dd>
+<dt>SouthGravity</dt>
+<dd>text top-center placed at bottom-center</dd>
+<dt>SouthEastGravity</dt>
+<dd>text top-right placed at bottom-right</dd>
+</dl>
+<p>Annotate using specified text, and placement location:</p>
+<pre class="literal-block">
+void annotate ( const std::string &amp;text_,
+ const Geometry &amp;location_ )
+</pre>
+<p>Annotate using specified text, bounding area, and placement gravity:</p>
+<pre class="literal-block">
+void annotate ( const std::string &amp;text_,
+ const Geometry &amp;boundingArea_,
+ const GravityType gravity_ )
+</pre>
+<p>Annotate with text using specified text, bounding area, placement
+gravity, and rotation:</p>
+<pre class="literal-block">
+void annotate ( const std::string &amp;text_,
+ const Geometry &amp;boundingArea_,
+ const GravityType gravity_,
+ const double degrees_ )
+</pre>
+<p>Annotate with text (bounding area is entire image) and placement
+gravity:</p>
+<pre class="literal-block">
+void annotate ( const std::string &amp;text_,
+ const GravityType gravity_ )
+</pre>
+</div>
+<div class="section" id="blur">
+<h2><a class="toc-backref" href="#id24">blur</a></h2>
+<p>Blur an image with the specified blur factor.</p>
+<p>The <cite>radius</cite> parameter specifies the radius of the Gaussian, in
+pixels, not counting the center pixel. The <cite>sigma</cite> parameter
+specifies the standard deviation of the Laplacian, in pixels:</p>
+<pre class="literal-block">
+void blur ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+</pre>
+</div>
+<div class="section" id="blurchannel">
+<h2><a class="toc-backref" href="#id25">blurChannel</a></h2>
+<p>Blur an image channel with the specified blur factor.</p>
+<p>The <cite>channel</cite> parameter specifies the channel to modify. The <cite>radius</cite>
+parameter specifies the radius of the Gaussian, in pixels, not
+counting the center pixel. The <cite>sigma</cite> parameter specifies the
+standard deviation of the Laplacian, in pixels:</p>
+<pre class="literal-block">
+void blurChannel ( const ChannelType channel_,
+ const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+</pre>
+</div>
+<div class="section" id="border">
+<h2><a class="toc-backref" href="#id26">border</a></h2>
+<p>Border image (add border to image). The <a class="reference external" href="Color.html">color</a> of the border is
+specified by the borderColor attribute:</p>
+<pre class="literal-block">
+void border ( const Geometry &amp;geometry_
+ = borderGeometryDefault )
+</pre>
+</div>
+<div class="section" id="cdl">
+<h2><a class="toc-backref" href="#id27">cdl</a></h2>
+<p>Bake in the ASC-CDL, which is a convention for the for the exchange of
+basic primary color grading information between for the exchange of
+basic primary color grading information between equipment and software
+from different manufacturers. It is a useful transform for other
+purposes as well:</p>
+<blockquote>
+void cdl ( const std::string &amp;cdl_ )</blockquote>
+<p>See <a class="reference external" href="../api/cdl.html#cdlimage">CdlImage</a> for more details on the ASC-CDL.</p>
+</div>
+<div class="section" id="channel">
+<h2><a class="toc-backref" href="#id28">channel</a></h2>
+<p>Extract channel from image. Use this option to extract a particular
+channel from the image. MatteChannel for example, is useful for
+extracting the opacity values from an image:</p>
+<pre class="literal-block">
+void channel ( const ChannelType channel_ )
+</pre>
+</div>
+<div class="section" id="channeldepth">
+<h2><a class="toc-backref" href="#id29">channelDepth</a></h2>
+<p>Set or obtain modulus channel depth:</p>
+<pre class="literal-block">
+void channelDepth ( const ChannelType channel_,
+ const unsigned int depth_ )
+
+unsigned int channelDepth ( const ChannelType channel_ )
+</pre>
+</div>
+<div class="section" id="charcoal">
+<h2><a class="toc-backref" href="#id30">charcoal</a></h2>
+<p>Charcoal effect image (looks like charcoal sketch).</p>
+<p>The <cite>radius</cite> parameter specifies the radius of the Gaussian, in
+pixels, not counting the center pixel. The <cite>sigma</cite> parameter
+specifies the standard deviation of the Laplacian, in pixels:</p>
+<pre class="literal-block">
+void charcoal ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+</pre>
+</div>
+<div class="section" id="chop">
+<h2><a class="toc-backref" href="#id31">chop</a></h2>
+<p>Chop image (remove vertical or horizontal subregion of image):</p>
+<pre class="literal-block">
+void chop ( const Geometry &amp;geometry_ )
+</pre>
+</div>
+<div class="section" id="colorize">
+<h2><a class="toc-backref" href="#id32">colorize</a></h2>
+<p>Colorize image with pen <a class="reference external" href="Color.html">color</a>, using specified percent opacity for
+red, green, and blue quantums:</p>
+<pre class="literal-block">
+void colorize ( const unsigned int opacityRed_,
+ const unsigned int opacityGreen_,
+ const unsigned int opacityBlue_,
+ const Color &amp;penColor_ )
+</pre>
+<p>Colorize image with pen <a class="reference external" href="Color.html">color</a>, using specified percent opacity:</p>
+<pre class="literal-block">
+void colorize ( const unsigned int opacity_,
+ const Color &amp;penColor_ )
+</pre>
+</div>
+<div class="section" id="colormatrix">
+<h2><a class="toc-backref" href="#id33">colorMatrix</a></h2>
+<p>Apply a color matrix to the image channels. The user supplied matrix
+may be of order 1 to 5 (1x1 through 5x5):</p>
+<pre class="literal-block">
+void colorMatrix (const unsigned int order_,
+ const double *color_matrix_)
+</pre>
+<p>See <a class="reference external" href="../api/fx.html#colormatriximage">ColorMatrixImage</a> for more details.</p>
+</div>
+<div class="section" id="comment">
+<h2><a class="toc-backref" href="#id34">comment</a></h2>
+<p>Comment image (add comment string to image). By default, each image is
+commented with its file name. Use this method to assign a specific
+comment to the image. Optionally you can include the image filename,
+type, width, height, or other image attributes by embedding <a class="reference external" href="FormatCharacters.html">special
+format characters</a>:</p>
+<pre class="literal-block">
+void comment ( const std::string &amp;comment_ )
+</pre>
+</div>
+<div class="section" id="compare">
+<h2><a class="toc-backref" href="#id35">compare</a></h2>
+<p>Compare current image with another image. Sets meanErrorPerPixel,
+normalizedMaxError, and normalizedMeanError in the current
+image. False is returned if the images are identical. An ErrorOption
+exception is thrown if the reference image columns, rows, colorspace,
+or matte differ from the current image:</p>
+<pre class="literal-block">
+bool compare ( const Image &amp;reference_ )
+</pre>
+</div>
+<div class="section" id="composite">
+<h2><a class="toc-backref" href="#id36">composite</a></h2>
+<p>Compose an image onto another at specified x and y offset and using a
+specified algorithm:</p>
+<pre class="literal-block">
+void composite ( const Image &amp;compositeImage_,
+ const int xOffset_,
+ const int yOffset_,
+ const CompositeOperator compose_
+ = InCompositeOp )
+
+void composite ( const Image &amp;compositeImage_,
+ const Geometry &amp;offset_,
+ const CompositeOperator compose_
+ = InCompositeOp )
+
+void composite ( const Image &amp;compositeImage_,
+ const GravityType gravity_,
+ const CompositeOperator compose_
+ = InCompositeOp )
+</pre>
+</div>
+<div class="section" id="contrast">
+<h2><a class="toc-backref" href="#id37">contrast</a></h2>
+<p>Contrast image (enhance intensity differences in image):</p>
+<pre class="literal-block">
+void contrast ( const unsigned int sharpen_ )
+</pre>
+</div>
+<div class="section" id="convolve">
+<h2><a class="toc-backref" href="#id38">convolve</a></h2>
+<p>Convolve image. Applies a user-specified convolution to the image.
+The <cite>order</cite> parameter represents the number of columns and rows in the
+filter kernel while <cite>kernel</cite> is a two-dimensional array of doubles
+representing the convolution kernel to apply:</p>
+<pre class="literal-block">
+void convolve ( const unsigned int order_,
+ const double *kernel_ )
+</pre>
+</div>
+<div class="section" id="crop">
+<h2><a class="toc-backref" href="#id39">crop</a></h2>
+<p>Crop image (return subregion of original image):</p>
+<pre class="literal-block">
+void crop ( const Geometry &amp;geometry_ )
+</pre>
+</div>
+<div class="section" id="cyclecolormap">
+<h2><a class="toc-backref" href="#id40">cycleColormap</a></h2>
+<p>Cycle (rotate) image colormap:</p>
+<pre class="literal-block">
+void cycleColormap ( const int amount_ )
+</pre>
+</div>
+<div class="section" id="despeckle">
+<h2><a class="toc-backref" href="#id41">despeckle</a></h2>
+<p>Despeckle image (reduce speckle noise):</p>
+<pre class="literal-block">
+void despeckle ( void )
+</pre>
+</div>
+<div class="section" id="display">
+<h2><a class="toc-backref" href="#id42">display</a></h2>
+<p>Display image on screen. Caution: if an image format is is not
+compatible with the display visual (e.g. JPEG on a colormapped
+display) then the original image will be altered. Use a copy of the
+original if this is a problem:</p>
+<blockquote>
+void display ( void )</blockquote>
+</div>
+<div class="section" id="draw">
+<h2><a class="toc-backref" href="#id43">draw</a></h2>
+<p>Draw shape or text on image using a single <a class="reference external" href="Drawable.html">drawable</a> object:</p>
+<pre class="literal-block">
+void draw ( const Drawable &amp;drawable_ );
+</pre>
+<p>Draw shapes or text on image using a set of <a class="reference external" href="Drawable.html">Drawable</a> objects
+contained in an <a class="reference external" href="STL.html">STL</a> list. Use of this method improves drawing
+performance and allows batching draw objects together in a list for
+repeated use:</p>
+<pre class="literal-block">
+void draw ( const std::list&lt;Magick::Drawable&gt; &amp;drawable_ );
+</pre>
+</div>
+<div class="section" id="edge">
+<h2><a class="toc-backref" href="#id44">edge</a></h2>
+<p>Edge image (hilight edges in image). The radius is the radius of the
+pixel neighborhood.. Specify a radius of zero for automatic radius
+selection:</p>
+<pre class="literal-block">
+void edge ( const double radius_ = 0.0 )
+</pre>
+</div>
+<div class="section" id="emboss">
+<h2><a class="toc-backref" href="#id45">emboss</a></h2>
+<p>Emboss image (hilight edges with 3D effect). The <cite>radius</cite> parameter
+specifies the radius of the Gaussian, in pixels, not counting the
+center pixel. The <cite>sigma</cite> parameter specifies the standard deviation
+of the Laplacian, in pixels:</p>
+<pre class="literal-block">
+void emboss ( const double radius_ = 0.0,
+ const double sigma_ = 1.0)
+</pre>
+</div>
+<div class="section" id="enhance">
+<h2><a class="toc-backref" href="#id46">enhance</a></h2>
+<p>Enhance image (minimize noise):</p>
+<pre class="literal-block">
+void enhance ( void );
+</pre>
+</div>
+<div class="section" id="equalize">
+<h2><a class="toc-backref" href="#id47">equalize</a></h2>
+<p>Equalize image (histogram equalization):</p>
+<pre class="literal-block">
+void equalize ( void )
+</pre>
+</div>
+<div class="section" id="erase">
+<h2><a class="toc-backref" href="#id48">erase</a></h2>
+<p>Set all image pixels to the current background color:</p>
+<pre class="literal-block">
+void erase ( void )
+</pre>
+</div>
+<div class="section" id="extent">
+<h2><a class="toc-backref" href="#id49">extent</a></h2>
+<p>Create an image canvas using background color sized according to
+geometry and composite existing image on it, with image placement
+controlled by gravity. Parameters are obtained from existing image
+properties if they are not specified via a method
+parameter. Parameters which are supported by image properties (gravity
+and backgroundColor) update those image properties as a side-effect:</p>
+<pre class="literal-block">
+void extent ( const Geometry &amp;geometry_ )
+
+void extent ( const Geometry &amp;geometry_,
+ const GravityType &amp;gravity_ )
+
+void extent ( const Geometry &amp;geometry_,
+ const Color &amp;backgroundColor_ )
+
+void extent ( const Geometry &amp;geometry_,
+ const Color &amp;backgroundColor_,
+ const GravityType &amp;gravity_ );
+</pre>
+</div>
+<div class="section" id="flip">
+<h2><a class="toc-backref" href="#id50">flip</a></h2>
+<p>Flip image (reflect each scanline in the vertical direction):</p>
+<pre class="literal-block">
+void flip ( void )
+</pre>
+</div>
+<div class="section" id="floodfillcolor">
+<h2><a class="toc-backref" href="#id51">floodFillColor</a></h2>
+<p>Flood-fill <a class="reference external" href="Color.html">color</a> across pixels that match the <a class="reference external" href="Color.html">color</a> of the target
+pixel and are neighbors of the target pixel. Uses current fuzz
+setting when determining <a class="reference external" href="Color.html">color</a> match:</p>
+<pre class="literal-block">
+void floodFillColor( const unsigned int x_,
+ const unsigned int y_,
+ const Color &amp;fillColor_ )
+
+void floodFillColor( const Geometry &amp;point_,
+ const Color &amp;fillColor_ )
+</pre>
+<p>Flood-fill <a class="reference external" href="Color.html">color</a> across pixels starting at target-pixel and stopping
+at pixels matching specified border <a class="reference external" href="Color.html">color</a>. Uses current fuzz setting
+when determining <a class="reference external" href="Color.html">color</a> match:</p>
+<pre class="literal-block">
+void floodFillColor( const unsigned int x_,
+ const unsigned int y_,
+ const Color &amp;fillColor_,
+ const Color &amp;borderColor_ )
+
+void floodFillColor( const Geometry &amp;point_,
+ const Color &amp;fillColor_,
+ const Color &amp;borderColor_ )
+</pre>
+</div>
+<div class="section" id="floodfillopacity">
+<h2><a class="toc-backref" href="#id52">floodFillOpacity</a></h2>
+<p>Flood-fill pixels matching <a class="reference external" href="Color.html">color</a> (within fuzz factor) of target
+pixel(x,y) with replacement opacity value using method:</p>
+<pre class="literal-block">
+void floodFillOpacity ( const unsigned int x_,
+ const unsigned int y_,
+ const unsigned int opacity_,
+ const PaintMethod method_ )
+</pre>
+</div>
+<div class="section" id="floodfilltexture">
+<h2><a class="toc-backref" href="#id53">floodFillTexture</a></h2>
+<p>Flood-fill texture across pixels that match the <a class="reference external" href="Color.html">color</a> of the
+target pixel and are neighbors of the target pixel.
+Uses current fuzz setting when determining <a class="reference external" href="Color.html">color</a> match:</p>
+<pre class="literal-block">
+void floodFillTexture( const unsigned int x_,
+ const unsigned int y_,
+ const Image &amp;texture_ )
+
+void floodFillTexture( const Geometry &amp;point_,
+ const Image &amp;texture_ )
+</pre>
+<p>Flood-fill texture across pixels starting at target-pixel and
+stopping at pixels matching specified border <a class="reference external" href="Color.html">color</a>.
+Uses current fuzz setting when determining <a class="reference external" href="Color.html">color</a> match:</p>
+<pre class="literal-block">
+void floodFillTexture( const unsigned int x_,
+ const unsigned int y_,
+ const Image &amp;texture_,
+ const Color &amp;borderColor_ )
+
+void floodFillTexture( const Geometry &amp;point_,
+ const Image &amp;texture_,
+ const Color &amp;borderColor_ )
+</pre>
+</div>
+<div class="section" id="flop">
+<h2><a class="toc-backref" href="#id54">flop</a></h2>
+<p>Flop image (reflect each scanline in the horizontal direction):</p>
+<pre class="literal-block">
+void flop ( void );
+</pre>
+</div>
+<div class="section" id="frame">
+<h2><a class="toc-backref" href="#id55">frame</a></h2>
+<p>Draw a decorative frame around the image:</p>
+<pre class="literal-block">
+void frame ( const Geometry &amp;geometry_ = frameGeometryDefault )
+
+void frame ( const unsigned int width_,
+ const unsigned int height_,
+ const int innerBevel_ = 6,
+ const int outerBevel_ = 6 )
+</pre>
+</div>
+<div class="section" id="gamma">
+<h2><a class="toc-backref" href="#id56">gamma</a></h2>
+<p>Gamma correct the image or individual image channels:</p>
+<pre class="literal-block">
+void gamma ( const double gamma_ )
+
+void gamma ( const double gammaRed_,
+ const double gammaGreen_,
+ const double gammaBlue_ )
+</pre>
+</div>
+<div class="section" id="gaussianblur">
+<h2><a class="toc-backref" href="#id57">gaussianBlur</a></h2>
+<p>Gaussian blur image. The number of neighbor pixels to be included in
+the convolution mask is specified by <cite>width</cite>. The standard deviation
+of the gaussian bell curve is specified by <cite>sigma</cite>:</p>
+<pre class="literal-block">
+void gaussianBlur ( const double width_, const double sigma_ )
+</pre>
+</div>
+<div class="section" id="gaussianblurchannel">
+<h2><a class="toc-backref" href="#id58">gaussianBlurChannel</a></h2>
+<p>Gaussian blur image channel. The number of neighbor pixels to be
+included in the convolution mask is specified by <cite>width</cite>. The
+standard deviation of the gaussian bell curve is specified by
+<cite>sigma</cite>:</p>
+<pre class="literal-block">
+void gaussianBlurChannel ( const ChannelType channel_,
+ const double width_,
+ const double sigma_ )
+</pre>
+</div>
+<div class="section" id="implode">
+<h2><a class="toc-backref" href="#id59">implode</a></h2>
+<p>Implode image (special effect):</p>
+<pre class="literal-block">
+void implode ( const double factor_ )
+</pre>
+</div>
+<div class="section" id="haldclut">
+<h2><a class="toc-backref" href="#id60">haldClut</a></h2>
+<p>Apply a color lookup table (Hald CLUT) to the image:</p>
+<pre class="literal-block">
+void haldClut ( const Image &amp;clutImage_ )
+</pre>
+<p>See <a class="reference external" href="../api/hclut.html#haldclutimage">HaldClutImage</a> for more details.</p>
+</div>
+<div class="section" id="label">
+<h2><a class="toc-backref" href="#id61">label</a></h2>
+<p>Assign a label to an image. Use this option to assign a specific label
+to the image. Optionally you can include the image filename, type,
+width, height, or scene number in the label by embedding <a class="reference external" href="FormatCharacters.html">special
+format characters</a>. If the first character of string is &#64;, the image
+label is read from a file titled by the remaining characters in the
+string. When converting to Postscript, use this option to specify a
+header string to print above the image:</p>
+<pre class="literal-block">
+void label ( const std::string &amp;label_ )
+</pre>
+</div>
+<div class="section" id="level">
+<h2><a class="toc-backref" href="#id62">level</a></h2>
+<p>Level image to increase image contrast, and/or adjust image
+gamma. Adjust the levels of the image by scaling the colors falling
+between specified white and black points to the full available quantum
+range. The parameters provided represent the black, mid (gamma), and
+white points. The black point specifies the darkest color in the
+image. Colors darker than the black point are set to zero. Mid point
+(gamma) specifies a gamma correction to apply to the image. White
+point specifies the lightest color in the image. Colors brighter than
+the white point are set to the maximum quantum value. The black and
+white point have the valid range 0 to MaxRGB while mid (gamma) has a
+useful range of 0 to ten:</p>
+<pre class="literal-block">
+void level ( const double black_point,
+ const double white_point,
+ const double mid_point=1.0 )
+</pre>
+</div>
+<div class="section" id="levelchannel">
+<h2><a class="toc-backref" href="#id63">levelChannel</a></h2>
+<p>Level image channel to increase image contrast, and/or adjust image
+gamma. Adjust the levels of the image channel by scaling the colors
+falling between specified white and black points to the full available
+quantum range. The parameters provided represent the black, mid
+(gamma), and white points. The black point specifies the darkest
+color in the image. Colors darker than the black point are set to
+zero. Mid point (gamma) specifies a gamma correction to apply to the
+image. White point specifies the lightest color in the image. Colors
+brighter than the white point are set to the maximum quantum
+value. The black and white point have the valid range 0 to MaxRGB
+while mid (gamma) has a useful range of 0 to ten:</p>
+<pre class="literal-block">
+void levelChannel ( const ChannelType channel,
+ const double black_point,
+ const double white_point,
+ const double mid_point=1.0 )
+</pre>
+</div>
+<div class="section" id="magnify">
+<h2><a class="toc-backref" href="#id64">magnify</a></h2>
+<p>Magnify image by integral size (double the dimensions):</p>
+<pre class="literal-block">
+void magnify ( void )
+</pre>
+</div>
+<div class="section" id="map">
+<h2><a class="toc-backref" href="#id65">map</a></h2>
+<p>Remap image colors with closest color from a reference image. Set
+<cite>dither</cite> to true in to apply Floyd/Steinberg error diffusion to the
+image. By default, color reduction chooses an optimal set of colors
+that best represent the original image. Alternatively, you can choose
+a particular set of colors from an image file with this option:</p>
+<pre class="literal-block">
+void map ( const Image &amp;mapImage_ ,
+ const bool dither_ = false )
+</pre>
+</div>
+<div class="section" id="mattefloodfill">
+<h2><a class="toc-backref" href="#id66">matteFloodfill</a></h2>
+<p>Floodfill designated area with a replacement opacity value:</p>
+<pre class="literal-block">
+void matteFloodfill ( const Color &amp;target_ ,
+ const unsigned int opacity_,
+ const int x_, const int y_,
+ const PaintMethod method_ )
+</pre>
+</div>
+<div class="section" id="medianfilter">
+<h2><a class="toc-backref" href="#id67">medianFilter</a></h2>
+<p>Filter image by replacing each pixel component with the median color
+in a circular neighborhood:</p>
+<pre class="literal-block">
+void medianFilter ( const double radius_ = 0.0 )
+</pre>
+</div>
+<div class="section" id="minify">
+<h2><a class="toc-backref" href="#id68">minify</a></h2>
+<p>Reduce image by integral (half) size:</p>
+<pre class="literal-block">
+void minify ( void )
+</pre>
+</div>
+<div class="section" id="modifyimage">
+<h2><a class="toc-backref" href="#id69">modifyImage</a></h2>
+<p>Prepare to update image (copy if reference &gt; 1). Normally Magick++'s
+implicit reference counting takes care of all instance management. In
+the rare case that the automatic instance management does not work,
+use this method to assure that there is only one reference to the
+image to be modified. It should be used in the cases where a
+GraphicsMagick C function is used directly on an image which may have
+multiple references:</p>
+<pre class="literal-block">
+void modifyImage ( void )
+</pre>
+</div>
+<div class="section" id="modulate">
+<h2><a class="toc-backref" href="#id70">modulate</a></h2>
+<p>Modulate percent hue, saturation, and brightness of an image.
+Modulation of saturation and brightness is as a ratio of the current
+value (1.0 for no change). Modulation of hue is an absolute rotation
+of -180 degrees to +180 degrees from the current position
+corresponding to an argument range of 0 to 2.0 (1.0 for no change):</p>
+<pre class="literal-block">
+void modulate ( const double brightness_,
+ const double saturation_,
+ const double hue_ )
+</pre>
+</div>
+<div class="section" id="motionblur">
+<h2><a class="toc-backref" href="#id71">motionBlur</a></h2>
+<p>Motion blur image with specified blur factor. The <cite>radius</cite> parameter
+specifies the radius of the Gaussian, in pixels, not counting the
+center pixel. The <cite>sigma</cite> parameter specifies the standard
+deviation of the Laplacian, in pixels. The <cite>angle</cite> parameter
+specifies the angle the object appears to be comming from (zero
+degrees is from the right):</p>
+<pre class="literal-block">
+void motionBlur ( const double radius_,
+ const double sigma_,
+ const double angle_ )
+</pre>
+</div>
+<div class="section" id="negate">
+<h2><a class="toc-backref" href="#id72">negate</a></h2>
+<p>Negate colors in image. Set <cite>grayscale</cite> to only negate grayscale
+values in image:</p>
+<pre class="literal-block">
+void negate ( const bool grayscale_ = false )
+</pre>
+</div>
+<div class="section" id="normalize">
+<h2><a class="toc-backref" href="#id73">normalize</a></h2>
+<p>Normalize image (increase contrast by normalizing the pixel values to
+span the full range of color values):</p>
+<pre class="literal-block">
+void normalize ( void )
+</pre>
+</div>
+<div class="section" id="oilpaint">
+<h2><a class="toc-backref" href="#id74">oilPaint</a></h2>
+<p>Oilpaint image (image looks like an oil painting):</p>
+<pre class="literal-block">
+void oilPaint ( const double radius_ = 3.0 )
+</pre>
+</div>
+<div class="section" id="opacity">
+<h2><a class="toc-backref" href="#id75">opacity</a></h2>
+<p>Set or attenuate the opacity channel in the image. If the image pixels
+are opaque then they are set to the specified opacity value, otherwise
+they are blended with the supplied opacity value. The value of
+<cite>opacity</cite> ranges from 0 (completely opaque) to MaxRGB. The defines
+<cite>OpaqueOpacity</cite> and <cite>TransparentOpacity</cite> are available to specify
+completely opaque or completely transparent, respectively:</p>
+<pre class="literal-block">
+void opacity ( const unsigned int opacity_ )
+</pre>
+</div>
+<div class="section" id="opaque">
+<h2><a class="toc-backref" href="#id76">opaque</a></h2>
+<p>Change <a class="reference external" href="Color.html">color</a> of specified opaque pixel to specified pen <a class="reference external" href="Color.html">color</a>:</p>
+<pre class="literal-block">
+void opaque ( const Color &amp;opaqueColor_,
+ const Color &amp;penColor_ )
+</pre>
+</div>
+<div class="section" id="quantize">
+<h2><a class="toc-backref" href="#id77">quantize</a></h2>
+<p>Quantize image (reduce number of colors). Set <cite>measureError</cite> to true
+in order to calculate error attributes:</p>
+<pre class="literal-block">
+void quantize ( const bool measureError_ = false )
+</pre>
+</div>
+<div class="section" id="quantumoperator">
+<h2><a class="toc-backref" href="#id78">quantumOperator</a></h2>
+<p>Apply an arithmetic or bitwise operator to the image pixel quantums:</p>
+<pre class="literal-block">
+void quantumOperator ( const ChannelType channel_,
+ const QuantumOperator operator_,
+ double rvalue_)
+
+void quantumOperator ( const int x_,const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const ChannelType channel_,
+ const QuantumOperator operator_,
+ const double rvalue_)
+</pre>
+</div>
+<div class="section" id="process">
+<h2><a class="toc-backref" href="#id79">process</a></h2>
+<p>Execute a named process module using an argc/argv syntax similar to
+that accepted by a C 'main' routine. An exception is thrown if the
+requested process module doesn't exist, fails to load, or fails during
+execution:</p>
+<pre class="literal-block">
+void process ( std::string name_,
+ const int argc_,
+ char **argv_ )
+</pre>
+</div>
+<div class="section" id="raise">
+<h2><a class="toc-backref" href="#id80">raise</a></h2>
+<p>Raise image (lighten or darken the edges of an image to give a 3-D
+raised or lowered effect):</p>
+<pre class="literal-block">
+void raise ( const Geometry &amp;geometry_ = &quot;6x6+0+0&quot;,
+ const bool raisedFlag_ = false )
+</pre>
+</div>
+<div class="section" id="randomthreshold">
+<h2><a class="toc-backref" href="#id81">randomThreshold</a></h2>
+<p>Random threshold image.</p>
+<p>Changes the value of individual pixels based on the intensity
+of each pixel compared to a random threshold. The result is a
+low-contrast, two color image. The <cite>thresholds</cite> argument is a
+geometry containing LOWxHIGH thresholds. If the string
+contains 2x2, 3x3, or 4x4, then an ordered dither of order 2,
+3, or 4 will be performed instead. If a <cite>channel</cite> argument is
+specified then only the specified channel is altered. This is
+a very fast alternative to 'quantize' based dithering:</p>
+<pre class="literal-block">
+void randomThreshold( const Geometry &amp;thresholds_ )
+</pre>
+</div>
+<div class="section" id="randomthresholdchannel">
+<h2><a class="toc-backref" href="#id82">randomThresholdChannel</a></h2>
+<p>Random threshold image channel.</p>
+<p>Changes the value of individual pixels based on the intensity of each
+pixel compared to a random threshold. The result is a low-contrast,
+two color image. The <cite>thresholds</cite> argument is a geometry containing
+LOWxHIGH thresholds. If the string contains 2x2, 3x3, or 4x4, then an
+ordered dither of order 2, 3, or 4 will be performed instead. If a
+<cite>channel</cite> argument is specified then only the specified channel is
+altered. This is a very fast alternative to 'quantize' based
+dithering:</p>
+<pre class="literal-block">
+void randomThresholdChannel( const Geometry &amp;thresholds_,
+ const ChannelType channel_ )
+</pre>
+</div>
+<div class="section" id="reducenoise">
+<h2><a class="toc-backref" href="#id83">reduceNoise</a></h2>
+<p>Reduce noise in image using a noise peak elimination filter:</p>
+<pre class="literal-block">
+void reduceNoise ( void )
+
+void reduceNoise ( const double order_ )
+</pre>
+</div>
+<div class="section" id="resize">
+<h2><a class="toc-backref" href="#id84">resize</a></h2>
+<p>Resize image, specifying geometry, filter, and blur (blur &gt; 1.0 is
+more blurry and &lt; 1.0 is sharper):</p>
+<pre class="literal-block">
+void resize ( const Geometry &amp;geometry_,
+ const FilterTypes filterType_,
+ const double blur_ )
+</pre>
+<p>Resize image, specifying geometry and filter, with blur using Image
+default:</p>
+<pre class="literal-block">
+void resize ( const Geometry &amp;geometry_,
+ const FilterTypes filterType_ )
+</pre>
+<p>Resize image, specifying only geometry, with filter and blur obtained
+from Image default. Provides the same result as the <cite>zoom</cite> method:</p>
+<pre class="literal-block">
+void resize ( const Geometry &amp;geometry_ );
+</pre>
+</div>
+<div class="section" id="roll">
+<h2><a class="toc-backref" href="#id85">roll</a></h2>
+<p>Roll image (rolls image vertically and horizontally) by specified
+number of columnms and rows):</p>
+<pre class="literal-block">
+void roll ( const Geometry &amp;roll_ )
+
+void roll ( const unsigned int columns_,
+ const unsigned int rows_ )
+</pre>
+</div>
+<div class="section" id="rotate">
+<h2><a class="toc-backref" href="#id86">rotate</a></h2>
+<p>Rotate image counter-clockwise by specified number of degrees:</p>
+<pre class="literal-block">
+void rotate ( const double degrees_ )
+</pre>
+</div>
+<div class="section" id="sample">
+<h2><a class="toc-backref" href="#id87">sample</a></h2>
+<p>Resize image by using pixel sampling algorithm:</p>
+<pre class="literal-block">
+void sample ( const Geometry &amp;geometry_ )
+</pre>
+</div>
+<div class="section" id="scale">
+<h2><a class="toc-backref" href="#id88">scale</a></h2>
+<p>Resize image by using simple ratio algorithm which provides good
+quality:</p>
+<pre class="literal-block">
+void scale ( const Geometry &amp;geometry_ )
+</pre>
+</div>
+<div class="section" id="thumbnail">
+<h2><a class="toc-backref" href="#id89">thumbnail</a></h2>
+<p>Resize image using several algorithms to make smaller images very
+quickly. This is very useful to create thumbnails from large images
+but usually works well for any image resizing purpose:</p>
+<pre class="literal-block">
+void thumbnail ( const Geometry &amp;geometry_ );
+</pre>
+</div>
+<div class="section" id="segment">
+<h2><a class="toc-backref" href="#id90">segment</a></h2>
+<p>Segment (coalesce similar image components) by analyzing the
+histograms of the color components and identifying units that are
+homogeneous with the fuzzy c-means technique. A histogram is built
+for the image. This histogram is filtered to reduce noise and a
+second derivative of the histogram plot is built and used to identify
+potential cluster colors (peaks in the histogram). The cluster colors
+are then validated by scanning through all of the pixels to see how
+many pixels fall within each cluster. Some candidate cluster colors
+may not match any of the image pixels at all and should be discarded.
+Specify <cite>clusterThreshold</cite>, as the number of pixels matching a cluster
+color in order for the cluster to be considered
+valid. <cite>SmoothingThreshold</cite> eliminates noise in the second derivative
+of the histogram. As the value is increased, you can expect a smoother
+second derivative. The default is 1.5:</p>
+<pre class="literal-block">
+void segment ( const double clusterThreshold_ = 1.0,
+ const double smoothingThreshold_ = 1.5 )
+</pre>
+</div>
+<div class="section" id="shade">
+<h2><a class="toc-backref" href="#id91">shade</a></h2>
+<p>Shade image using distant light source. Specify <cite>azimuth</cite> and
+<cite>elevation</cite> as the position of the light source. By default, the
+shading results as a grayscale image.. Set <cite>colorShading</cite> to true to
+shade the red, green, and blue components of the image:</p>
+<pre class="literal-block">
+void shade ( const double azimuth_ = 30,
+ const double elevation_ = 30,
+ const bool colorShading_ = false )
+</pre>
+</div>
+<div class="section" id="sharpen">
+<h2><a class="toc-backref" href="#id92">sharpen</a></h2>
+<p>Sharpen pixels in image. The <cite>radius</cite> parameter specifies the radius
+of the Gaussian, in pixels, not counting the center pixel. The
+<cite>sigma</cite> parameter specifies the standard deviation of the Laplacian,
+in pixels:</p>
+<pre class="literal-block">
+void sharpen ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+</pre>
+</div>
+<div class="section" id="sharpenchannel">
+<h2><a class="toc-backref" href="#id93">sharpenChannel</a></h2>
+<p>Sharpen pixels in image channel. The <cite>radius</cite> parameter specifies the
+radius of the Gaussian, in pixels, not counting the center pixel. The
+<cite>sigma</cite> parameter specifies the standard deviation of the Laplacian,
+in pixels:</p>
+<pre class="literal-block">
+void sharpenChannel ( const ChannelType channel_,
+ const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+</pre>
+</div>
+<div class="section" id="shave">
+<h2><a class="toc-backref" href="#id94">shave</a></h2>
+<p>Shave pixels from image edges:</p>
+<pre class="literal-block">
+void shave ( const Geometry &amp;geometry_ )
+</pre>
+</div>
+<div class="section" id="shear">
+<h2><a class="toc-backref" href="#id95">shear</a></h2>
+<p>Shear image (create parallelogram by sliding image by X or Y
+axis). Shearing slides one edge of an image along the X or Y axis,
+creating a parallelogram. An X direction shear slides an edge along
+the X axis, while a Y direction shear slides an edge along the Y axis.
+The amount of the shear is controlled by a shear angle. For X
+direction shears, x degrees is measured relative to the Y axis, and
+similarly, for Y direction shears y degrees is measured relative to
+the X axis. Empty triangles left over from shearing the image are
+filled with the <a class="reference external" href="Color.html">color</a> defined as borderColor:</p>
+<pre class="literal-block">
+void shear ( const double xShearAngle_,
+ const double yShearAngle_ )
+</pre>
+</div>
+<div class="section" id="solarize">
+<h2><a class="toc-backref" href="#id96">solarize</a></h2>
+<p>Solarize image (similar to effect seen when exposing a photographic
+film to light during the development process):</p>
+<pre class="literal-block">
+void solarize ( const double factor_ = 50.0 )
+</pre>
+</div>
+<div class="section" id="spread">
+<h2><a class="toc-backref" href="#id97">spread</a></h2>
+<p>Spread pixels randomly within image by specified ammount:</p>
+<pre class="literal-block">
+void spread ( const unsigned int amount_ = 3 )
+</pre>
+</div>
+<div class="section" id="stegano">
+<h2><a class="toc-backref" href="#id98">stegano</a></h2>
+<p>Add a digital watermark to the image (based on second image):</p>
+<pre class="literal-block">
+void stegano ( const Image &amp;watermark_ )
+</pre>
+</div>
+<div class="section" id="stereo">
+<h2><a class="toc-backref" href="#id99">stereo</a></h2>
+<p>Create an image which appears in stereo when viewed with red-blue
+glasses (Red image on left, blue on right):</p>
+<pre class="literal-block">
+void stereo ( const Image &amp;rightImage_ )
+</pre>
+</div>
+<div class="section" id="strip">
+<h2><a class="toc-backref" href="#id100">strip</a></h2>
+<p>Remove all profiles and text attributes from the image.</p>
+<blockquote>
+void strip ( void );</blockquote>
+</div>
+<div class="section" id="swirl">
+<h2><a class="toc-backref" href="#id101">swirl</a></h2>
+<p>Swirl image (image pixels are rotated by degrees):</p>
+<pre class="literal-block">
+void swirl ( const double degrees_ )
+</pre>
+</div>
+<div class="section" id="texture">
+<h2><a class="toc-backref" href="#id102">texture</a></h2>
+<p>Channel a texture on pixels matching image background <a class="reference external" href="Color.html">color</a>:</p>
+<pre class="literal-block">
+void texture ( const Image &amp;texture_ )
+</pre>
+</div>
+<div class="section" id="threshold">
+<h2><a class="toc-backref" href="#id103">threshold</a></h2>
+<p>Threshold image channels (below threshold becomes black, above
+threshold becomes white). The range of the threshold parameter is 0
+to MaxRGB:</p>
+<pre class="literal-block">
+void threshold ( const double threshold_ )
+</pre>
+</div>
+<div class="section" id="transform">
+<h2><a class="toc-backref" href="#id104">transform</a></h2>
+<p>Transform image based on image and crop geometries. Crop geometry is
+optional:</p>
+<pre class="literal-block">
+void transform ( const Geometry &amp;imageGeometry_ )
+
+void transform ( const Geometry &amp;imageGeometry_,
+ const Geometry &amp;cropGeometry_ )
+</pre>
+</div>
+<div class="section" id="transparent">
+<h2><a class="toc-backref" href="#id105">transparent</a></h2>
+<p>Add matte channel to image, setting pixels matching <a class="reference external" href="Color.html">color</a> to
+transparent:</p>
+<pre class="literal-block">
+void transparent ( const Color &amp;color_ )
+</pre>
+</div>
+<div class="section" id="trim">
+<h2><a class="toc-backref" href="#id106">trim</a></h2>
+<p>Trim edges that are the background <a class="reference external" href="Color.html">color</a> from the image:</p>
+<pre class="literal-block">
+void trim ( void )
+</pre>
+</div>
+<div class="section" id="type">
+<h2><a class="toc-backref" href="#id107">type</a></h2>
+<p>Convert the image representation to the specified type or retrieve the
+current image type. If the image is reduced to an inferior type, then
+image information may be lost (e.g. color changed to grayscale).</p>
+<p>Available enumerations for the <cite>type</cite> parameter:</p>
+<blockquote>
+<dl class="docutils">
+<dt>BilevelType</dt>
+<dd>black/white</dd>
+<dt>GrayscaleType</dt>
+<dd>grayscale</dd>
+<dt>GrayscaleMatteType</dt>
+<dd>grayscale with alpha (opacity) channel</dd>
+<dt>PaletteType</dt>
+<dd>colormapped</dd>
+<dt>PaletteMatteType</dt>
+<dd>colormapped with transparency</dd>
+<dt>TrueColorType</dt>
+<dd>true (full) color</dd>
+<dt>TrueColorMatteType</dt>
+<dd>true (full) color with alpha (opacity) channel</dd>
+<dt>ColorSeparationType</dt>
+<dd>Cyan, magenta, yellow, and black</dd>
+<dt>ColorSeparationMatteType</dt>
+<dd>Cyan, magenta, yellow, and black with alpha (opacity) channel</dd>
+<dt>OptimizeType</dt>
+<dd>Optimize the image type to best represent the existing pixels</dd>
+</dl>
+</blockquote>
+<pre class="literal-block">
+void type ( const ImageType type_ )
+
+ImageType type ( void ) const
+</pre>
+</div>
+<div class="section" id="unsharpmask">
+<h2><a class="toc-backref" href="#id108">unsharpmask</a></h2>
+<p>Replace image with a sharpened version of the original image using the
+unsharp mask algorithm.</p>
+<blockquote>
+<dl class="docutils">
+<dt><cite>radius</cite></dt>
+<dd>the radius of the Gaussian, in pixels, not counting the
+center pixel.</dd>
+<dt><cite>sigma</cite></dt>
+<dd>the standard deviation of the Gaussian, in pixels.</dd>
+<dt><cite>amount</cite></dt>
+<dd>the percentage of the difference between the original and
+the blur image that is added back into the original.</dd>
+<dt><cite>threshold</cite></dt>
+<dd>the threshold in pixels needed to apply the diffence amount.</dd>
+</dl>
+</blockquote>
+<pre class="literal-block">
+void unsharpmask ( const double radius_,
+ const double sigma_,
+ const double amount_,
+ const double threshold_ )
+</pre>
+</div>
+<div class="section" id="unsharpmaskchannel">
+<h2><a class="toc-backref" href="#id109">unsharpmaskChannel</a></h2>
+<p>Replace image channel with a sharpened version of the original image
+using the unsharp mask algorithm.</p>
+<blockquote>
+<dl class="docutils">
+<dt><cite>channel</cite></dt>
+<dd>image channel to modify.</dd>
+<dt><cite>radius</cite></dt>
+<dd>the radius of the Gaussian, in pixels, not counting the
+center pixel.</dd>
+<dt><cite>sigma</cite></dt>
+<dd>the standard deviation of the Gaussian, in pixels.</dd>
+<dt><cite>amount</cite></dt>
+<dd>the percentage of the difference between the original and
+the blur image that is added back into the original.</dd>
+<dt><cite>threshold</cite></dt>
+<dd>the threshold in pixels needed to apply the diffence amount.</dd>
+</dl>
+</blockquote>
+<pre class="literal-block">
+void unsharpmaskChannel ( const ChannelType channel_,
+ const double radius_,
+ const double sigma_,
+ const double amount_,
+ const double threshold_ );
+</pre>
+</div>
+<div class="section" id="wave">
+<h2><a class="toc-backref" href="#id110">wave</a></h2>
+<p>Map image pixels to a sine wave:</p>
+<pre class="literal-block">
+void wave ( const double amplitude_ = 25.0,
+ const double wavelength_ = 150.0 )
+</pre>
+</div>
+<div class="section" id="zoom">
+<h2><a class="toc-backref" href="#id111">zoom</a></h2>
+<p>Zoom (resize) image to specified size:</p>
+<pre class="literal-block">
+void zoom ( const Geometry &amp;geometry_ )
+</pre>
+</div>
+</div>
+<div class="section" id="set-get-image-attributes">
+<h1><a class="toc-backref" href="#id14">Set/Get Image Attributes</a></h1>
+<p>Image attributes are set and obtained via methods in Image. Except for
+methods which accept pointer arguments (e.g. chromaBluePrimary) all
+methods return attributes by value.</p>
+<p>Image attributes are easily used. For example, to set the resolution
+of the TIFF file &quot;file.tiff&quot; to 150 dots-per-inch (DPI) in both the
+horizontal and vertical directions, you can use the following example
+code:</p>
+<pre class="literal-block">
+string filename(&quot;file.tiff&quot;);
+Image image;
+image.read(filename);
+image.resolutionUnits(PixelsPerInchResolution);
+image.density(Geometry(150,150)); // could also use image.density(&quot;150x150&quot;)
+image.write(filename)
+</pre>
+<p>The following image attribute methods are available:</p>
+<div class="contents local topic" id="id3">
+<ul class="simple">
+<li><a class="reference internal" href="#adjoin" id="id112">adjoin</a></li>
+<li><a class="reference internal" href="#antialias" id="id113">antiAlias</a></li>
+<li><a class="reference internal" href="#animationdelay" id="id114">animationDelay</a></li>
+<li><a class="reference internal" href="#animationiterations" id="id115">animationIterations</a></li>
+<li><a class="reference internal" href="#attribute" id="id116">attribute</a></li>
+<li><a class="reference internal" href="#backgroundcolor" id="id117">backgroundColor</a></li>
+<li><a class="reference internal" href="#backgroundtexture" id="id118">backgroundTexture</a></li>
+<li><a class="reference internal" href="#basecolumns" id="id119">baseColumns</a></li>
+<li><a class="reference internal" href="#basefilename" id="id120">baseFilename</a></li>
+<li><a class="reference internal" href="#baserows" id="id121">baseRows</a></li>
+<li><a class="reference internal" href="#bordercolor" id="id122">borderColor</a></li>
+<li><a class="reference internal" href="#boundingbox" id="id123">boundingBox</a></li>
+<li><a class="reference internal" href="#boxcolor" id="id124">boxColor</a></li>
+<li><a class="reference internal" href="#cachethreshold" id="id125">cacheThreshold</a></li>
+<li><a class="reference internal" href="#chromablueprimary" id="id126">chromaBluePrimary</a></li>
+<li><a class="reference internal" href="#chromagreenprimary" id="id127">chromaGreenPrimary</a></li>
+<li><a class="reference internal" href="#chromaredprimary" id="id128">chromaRedPrimary</a></li>
+<li><a class="reference internal" href="#chromawhitepoint" id="id129">chromaWhitePoint</a></li>
+<li><a class="reference internal" href="#classtype" id="id130">classType</a></li>
+<li><a class="reference internal" href="#clipmask" id="id131">clipMask</a></li>
+<li><a class="reference internal" href="#colorfuzz" id="id132">colorFuzz</a></li>
+<li><a class="reference internal" href="#colormap" id="id133">colorMap</a></li>
+<li><a class="reference internal" href="#colormapsize" id="id134">colorMapSize</a></li>
+<li><a class="reference internal" href="#colorspace" id="id135">colorSpace</a></li>
+<li><a class="reference internal" href="#columns" id="id136">columns</a></li>
+<li><a class="reference internal" href="#id4" id="id137">comment</a></li>
+<li><a class="reference internal" href="#compose" id="id138">compose</a></li>
+<li><a class="reference internal" href="#compresstype" id="id139">compressType</a></li>
+<li><a class="reference internal" href="#debug" id="id140">debug</a></li>
+<li><a class="reference internal" href="#definevalue" id="id141">defineValue</a></li>
+<li><a class="reference internal" href="#defineset" id="id142">defineSet</a></li>
+<li><a class="reference internal" href="#density" id="id143">density</a></li>
+<li><a class="reference internal" href="#depth" id="id144">depth</a></li>
+<li><a class="reference internal" href="#directory" id="id145">directory</a></li>
+<li><a class="reference internal" href="#endian" id="id146">endian</a></li>
+<li><a class="reference internal" href="#filename" id="id147">fileName</a></li>
+<li><a class="reference internal" href="#filesize" id="id148">fileSize</a></li>
+<li><a class="reference internal" href="#fillcolor" id="id149">fillColor</a></li>
+<li><a class="reference internal" href="#fillpattern" id="id150">fillPattern</a></li>
+<li><a class="reference internal" href="#fillrule" id="id151">fillRule</a></li>
+<li><a class="reference internal" href="#filtertype" id="id152">filterType</a></li>
+<li><a class="reference internal" href="#font" id="id153">font</a></li>
+<li><a class="reference internal" href="#fontpointsize" id="id154">fontPointsize</a></li>
+<li><a class="reference internal" href="#fonttypemetrics" id="id155">fontTypeMetrics</a></li>
+<li><a class="reference internal" href="#format" id="id156">format</a></li>
+<li><a class="reference internal" href="#formatexpression" id="id157">formatExpression</a></li>
+<li><a class="reference internal" href="#id5" id="id158">gamma</a></li>
+<li><a class="reference internal" href="#id6" id="id159">geometry</a></li>
+<li><a class="reference internal" href="#gifdisposemethod" id="id160">gifDisposeMethod</a></li>
+<li><a class="reference internal" href="#icccolorprofile" id="id161">iccColorProfile</a></li>
+<li><a class="reference internal" href="#interlacetype" id="id162">interlaceType</a></li>
+<li><a class="reference internal" href="#iptcprofile" id="id163">iptcProfile</a></li>
+<li><a class="reference internal" href="#isvalid" id="id164">isValid</a></li>
+<li><a class="reference internal" href="#id7" id="id165">label</a></li>
+<li><a class="reference internal" href="#linewidth" id="id166">lineWidth</a></li>
+<li><a class="reference internal" href="#magick" id="id167">magick</a></li>
+<li><a class="reference internal" href="#matte" id="id168">matte</a></li>
+<li><a class="reference internal" href="#mattecolor" id="id169">matteColor</a></li>
+<li><a class="reference internal" href="#meanerrorperpixel" id="id170">meanErrorPerPixel</a></li>
+<li><a class="reference internal" href="#modulusdepth" id="id171">modulusDepth</a></li>
+<li><a class="reference internal" href="#monochrome" id="id172">monochrome</a></li>
+<li><a class="reference internal" href="#montagegeometry" id="id173">montageGeometry</a></li>
+<li><a class="reference internal" href="#normalizedmaxerror" id="id174">normalizedMaxError</a></li>
+<li><a class="reference internal" href="#normalizedmeanerror" id="id175">normalizedMeanError</a></li>
+<li><a class="reference internal" href="#orientation" id="id176">orientation</a></li>
+<li><a class="reference internal" href="#page" id="id177">page</a></li>
+<li><a class="reference internal" href="#pixelcolor" id="id178">pixelColor</a></li>
+<li><a class="reference internal" href="#profile" id="id179">profile</a></li>
+<li><a class="reference internal" href="#quality" id="id180">quality</a></li>
+<li><a class="reference internal" href="#quantizecolors" id="id181">quantizeColors</a></li>
+<li><a class="reference internal" href="#quantizecolorspace" id="id182">quantizeColorSpace</a></li>
+<li><a class="reference internal" href="#quantizedither" id="id183">quantizeDither</a></li>
+<li><a class="reference internal" href="#quantizetreedepth" id="id184">quantizeTreeDepth</a></li>
+<li><a class="reference internal" href="#quiet" id="id185">quiet</a></li>
+<li><a class="reference internal" href="#renderingintent" id="id186">renderingIntent</a></li>
+<li><a class="reference internal" href="#repage" id="id187">repage</a></li>
+<li><a class="reference internal" href="#resolutionunits" id="id188">resolutionUnits</a></li>
+<li><a class="reference internal" href="#rows" id="id189">rows</a></li>
+<li><a class="reference internal" href="#scene" id="id190">scene</a></li>
+<li><a class="reference internal" href="#signature" id="id191">signature</a></li>
+<li><a class="reference internal" href="#size" id="id192">size</a></li>
+<li><a class="reference internal" href="#statistics" id="id193">statistics</a></li>
+<li><a class="reference internal" href="#strokeantialias" id="id194">strokeAntiAlias</a></li>
+<li><a class="reference internal" href="#strokecolor" id="id195">strokeColor</a></li>
+<li><a class="reference internal" href="#strokedasharray" id="id196">strokeDashArray</a></li>
+<li><a class="reference internal" href="#strokedashoffset" id="id197">strokeDashOffset</a></li>
+<li><a class="reference internal" href="#strokelinecap" id="id198">strokeLineCap</a></li>
+<li><a class="reference internal" href="#strokelinejoin" id="id199">strokeLineJoin</a></li>
+<li><a class="reference internal" href="#strokemiterlimit" id="id200">strokeMiterLimit</a></li>
+<li><a class="reference internal" href="#strokepattern" id="id201">strokePattern</a></li>
+<li><a class="reference internal" href="#strokewidth" id="id202">strokeWidth</a></li>
+<li><a class="reference internal" href="#subimage" id="id203">subImage</a></li>
+<li><a class="reference internal" href="#subrange" id="id204">subRange</a></li>
+<li><a class="reference internal" href="#textencoding" id="id205">textEncoding</a></li>
+<li><a class="reference internal" href="#tilename" id="id206">tileName</a></li>
+<li><a class="reference internal" href="#totalcolors" id="id207">totalColors</a></li>
+<li><a class="reference internal" href="#transformorigin" id="id208">transformOrigin</a></li>
+<li><a class="reference internal" href="#transformrotation" id="id209">transformRotation</a></li>
+<li><a class="reference internal" href="#transformreset" id="id210">transformReset</a></li>
+<li><a class="reference internal" href="#transformscale" id="id211">transformScale</a></li>
+<li><a class="reference internal" href="#transformskewx" id="id212">transformSkewX</a></li>
+<li><a class="reference internal" href="#transformskewy" id="id213">transformSkewY</a></li>
+<li><a class="reference internal" href="#verbose" id="id214">verbose</a></li>
+<li><a class="reference internal" href="#view" id="id215">view</a></li>
+<li><a class="reference internal" href="#x11display" id="id216">x11Display</a></li>
+<li><a class="reference internal" href="#xresolution" id="id217">xResolution</a></li>
+<li><a class="reference internal" href="#yresolution" id="id218">yResolution</a></li>
+</ul>
+</div>
+<div class="section" id="adjoin">
+<h2><a class="toc-backref" href="#id112">adjoin</a></h2>
+<p>Join images into a single multi-image file:</p>
+<pre class="literal-block">
+void adjoin ( const bool flag_ )
+
+bool adjoin ( void ) const
+</pre>
+</div>
+<div class="section" id="antialias">
+<h2><a class="toc-backref" href="#id113">antiAlias</a></h2>
+<p>Control antialiasing of rendered Postscript and Postscript or TrueType
+fonts. Enabled by default:</p>
+<pre class="literal-block">
+void antiAlias( const bool flag_ )
+
+bool antiAlias( void )
+</pre>
+</div>
+<div class="section" id="animationdelay">
+<h2><a class="toc-backref" href="#id114">animationDelay</a></h2>
+<p>Time in 1/100ths of a second (0 to 65535) which must expire before
+displaying the next image in an animated sequence. This option is
+useful for regulating the animation of a sequence of GIF images within
+Netscape:</p>
+<pre class="literal-block">
+void animationDelay ( const unsigned int delay_ )
+
+unsigned int animationDelay ( void ) const
+</pre>
+</div>
+<div class="section" id="animationiterations">
+<h2><a class="toc-backref" href="#id115">animationIterations</a></h2>
+<p>Number of iterations to loop an animation (e.g. Netscape loop
+extension) for:</p>
+<pre class="literal-block">
+void animationIterations ( const unsigned int iterations_ )
+
+unsigned int animationIterations ( void ) const
+</pre>
+</div>
+<div class="section" id="attribute">
+<h2><a class="toc-backref" href="#id116">attribute</a></h2>
+<p>Access or update an arbitrary named image attribute. Any number of
+named attributes may be attached to the image. For example, the image
+comment is a named image attribute with the name &quot;comment&quot;. If the
+named attribute already exists, the provided text is appended to the
+existing attribute text. Pass NULL to remove an existing text
+attribute, or to restart the text attribute from scratch.</p>
+<p>EXIF tags are attached to the image as named attributes. Use the
+syntax &quot;EXIF:&lt;tag&gt;&quot; to request an EXIF tag similar to
+&quot;EXIF:DateTime&quot;:</p>
+<pre class="literal-block">
+void attribute ( const std::string name_,
+ const char * value_ );
+
+void attribute ( const std::string name_,
+ const std::string value_ )
+
+std::string attribute ( const std::string name_ )
+</pre>
+</div>
+<div class="section" id="backgroundcolor">
+<h2><a class="toc-backref" href="#id117">backgroundColor</a></h2>
+<p>Image background <a class="reference external" href="Color.html">color</a>:</p>
+<pre class="literal-block">
+void backgroundColor ( const Color &amp;color_ )
+
+Color backgroundColor ( void ) const
+</pre>
+</div>
+<div class="section" id="backgroundtexture">
+<h2><a class="toc-backref" href="#id118">backgroundTexture</a></h2>
+<p>Image file name to use as the background texture. Does not modify
+image pixels:</p>
+<pre class="literal-block">
+void backgroundTexture (const std::string &amp;backgroundTexture_ )
+
+std::string backgroundTexture ( void ) const
+</pre>
+</div>
+<div class="section" id="basecolumns">
+<h2><a class="toc-backref" href="#id119">baseColumns</a></h2>
+<p>Base image width (before transformations):</p>
+<pre class="literal-block">
+unsigned int baseColumns ( void ) const
+</pre>
+</div>
+<div class="section" id="basefilename">
+<h2><a class="toc-backref" href="#id120">baseFilename</a></h2>
+<p>Base image filename (before transformations):</p>
+<pre class="literal-block">
+std::string baseFilename ( void ) const
+</pre>
+</div>
+<div class="section" id="baserows">
+<h2><a class="toc-backref" href="#id121">baseRows</a></h2>
+<p>Base image height (before transformations):</p>
+<pre class="literal-block">
+unsigned int baseRows ( void ) const
+</pre>
+</div>
+<div class="section" id="bordercolor">
+<h2><a class="toc-backref" href="#id122">borderColor</a></h2>
+<p>Image border <a class="reference external" href="Color.html">color</a>:</p>
+<pre class="literal-block">
+void borderColor ( const Color &amp;color_ )
+
+Color borderColor ( void ) const
+</pre>
+</div>
+<div class="section" id="boundingbox">
+<h2><a class="toc-backref" href="#id123">boundingBox</a></h2>
+<p>Return smallest bounding box enclosing non-border pixels. The
+current fuzz value is used when discriminating between pixels.
+This is the crop bounding box used by <tt class="docutils literal">crop(Geometry(0,0))</tt>:</p>
+<pre class="literal-block">
+Geometry boundingBox ( void ) const
+</pre>
+</div>
+<div class="section" id="boxcolor">
+<h2><a class="toc-backref" href="#id124">boxColor</a></h2>
+<p>Base <a class="reference external" href="Color.html">color</a> that annotation text is rendered on (default none):</p>
+<pre class="literal-block">
+void boxColor ( const Color &amp;boxColor_ )
+
+Color boxColor ( void ) const
+</pre>
+</div>
+<div class="section" id="cachethreshold">
+<h2><a class="toc-backref" href="#id125">cacheThreshold</a></h2>
+<p>Pixel cache threshold in megabytes. Once this memory threshold is
+exceeded, all subsequent pixels cache operations are to/from disk.
+This setting is shared by all Image objects:</p>
+<pre class="literal-block">
+static void cacheThreshold ( const unsigned int threshold_ )
+</pre>
+</div>
+<div class="section" id="chromablueprimary">
+<h2><a class="toc-backref" href="#id126">chromaBluePrimary</a></h2>
+<p>Chromaticity blue primary point (e.g. x=0.15, y=0.06):</p>
+<pre class="literal-block">
+void chromaBluePrimary ( const double x_, const double y_ )
+
+void chromaBluePrimary ( double *x_, double *y_ ) const
+</pre>
+</div>
+<div class="section" id="chromagreenprimary">
+<h2><a class="toc-backref" href="#id127">chromaGreenPrimary</a></h2>
+<p>Chromaticity green primary point (e.g. x=0.3, y=0.6):</p>
+<pre class="literal-block">
+void chromaGreenPrimary ( const double x_, const double y_ )
+
+void chromaGreenPrimary ( double *x_, double *y_ ) const
+</pre>
+</div>
+<div class="section" id="chromaredprimary">
+<h2><a class="toc-backref" href="#id128">chromaRedPrimary</a></h2>
+<p>Chromaticity red primary point (e.g. x=0.64, y=0.33):</p>
+<pre class="literal-block">
+void chromaRedPrimary ( const double x_, const double y_ )
+
+void chromaRedPrimary ( double *x_, double *y_ ) const
+</pre>
+</div>
+<div class="section" id="chromawhitepoint">
+<h2><a class="toc-backref" href="#id129">chromaWhitePoint</a></h2>
+<p>Chromaticity white point (e.g. x=0.3127, y=0.329):</p>
+<pre class="literal-block">
+void chromaWhitePoint ( const double x_, const double y_ )
+void chromaWhitePoint ( double *x_, double *y_ ) const
+</pre>
+</div>
+<div class="section" id="classtype">
+<h2><a class="toc-backref" href="#id130">classType</a></h2>
+<p>Image class (DirectClass or PseudoClass). NOTE: setting a DirectClass
+image to PseudoClass will result in the loss of color information if
+the number of colors in the image is greater than the maximum palette
+size (either 256 or 65536 entries depending on the value of
+QuantumDepth when ImageMagick was built):</p>
+<pre class="literal-block">
+void classType ( const ClassType class_ )
+
+ClassType classType ( void ) const
+</pre>
+</div>
+<div class="section" id="clipmask">
+<h2><a class="toc-backref" href="#id131">clipMask</a></h2>
+<p>Associate a clip mask image with the current image. The clip mask
+image must have the same dimensions as the current image or an
+exception is thrown. Clipping occurs wherever pixels are transparent
+in the clip mask image. Clipping Pass an invalid image to unset an
+existing clip mask:</p>
+<pre class="literal-block">
+void clipMask ( const Image &amp; clipMask_ )
+
+Image clipMask ( void ) const
+</pre>
+</div>
+<div class="section" id="colorfuzz">
+<h2><a class="toc-backref" href="#id132">colorFuzz</a></h2>
+<p>Colors within this distance are considered equal. A number of
+algorithms search for a target color. By default the color must be
+exact. Use this option to match colors that are close to the target
+color in RGB space:</p>
+<pre class="literal-block">
+void colorFuzz ( const double fuzz_ )
+
+double colorFuzz ( void ) const
+</pre>
+</div>
+<div class="section" id="colormap">
+<h2><a class="toc-backref" href="#id133">colorMap</a></h2>
+<p><a class="reference external" href="Color.html">Color</a> at colormap position <cite>index</cite>:</p>
+<pre class="literal-block">
+void colorMap ( const unsigned int index_,
+ const Color &amp;color_ )
+
+Color colorMap ( const unsigned int index_ ) const
+</pre>
+</div>
+<div class="section" id="colormapsize">
+<h2><a class="toc-backref" href="#id134">colorMapSize</a></h2>
+<p>Number of entries in the colormap. Setting the colormap size may
+extend or truncate the colormap. The maximum number of supported
+entries is specified by the MaxColormapSize constant, and is dependent
+on the value of QuantumDepth when GraphicsMagick is compiled. An
+exception is thrown if more entries are requested than may be
+supported. Care should be taken when truncating the colormap to ensure
+that the image colormap indexes reference valid colormap entries:</p>
+<pre class="literal-block">
+void colorMapSize ( const unsigned int entries_ )
+
+unsigned int colorMapSize ( void )
+</pre>
+</div>
+<div class="section" id="colorspace">
+<h2><a class="toc-backref" href="#id135">colorSpace</a></h2>
+<p>The colorspace (e.g. CMYK) used to represent the image pixel colors:</p>
+<pre class="literal-block">
+void colorSpace( const ColorspaceType colorSpace_ )
+
+ColorspaceType colorSpace ( void ) const
+</pre>
+</div>
+<div class="section" id="columns">
+<h2><a class="toc-backref" href="#id136">columns</a></h2>
+<p>Image width:</p>
+<pre class="literal-block">
+unsigned int columns ( void ) const
+</pre>
+</div>
+<div class="section" id="id4">
+<h2><a class="toc-backref" href="#id137">comment</a></h2>
+<p>Image comment:</p>
+<pre class="literal-block">
+std::string comment ( void ) const
+</pre>
+</div>
+<div class="section" id="compose">
+<h2><a class="toc-backref" href="#id138">compose</a></h2>
+<p>Composition operator to be used when composition is implicitly
+used (such as for image flattening):</p>
+<pre class="literal-block">
+void compose (const CompositeOperator compose_)
+
+CompositeOperator compose ( void ) const
+</pre>
+</div>
+<div class="section" id="compresstype">
+<h2><a class="toc-backref" href="#id139">compressType</a></h2>
+<p>Image compresion type. The default is the compression type of the
+input image file:</p>
+<pre class="literal-block">
+void compressType ( const CompressionType compressType_ )
+
+CompressionType compressType ( void ) const
+</pre>
+</div>
+<div class="section" id="debug">
+<h2><a class="toc-backref" href="#id140">debug</a></h2>
+<p>Enable printing of debug messages from GraphicsMagick as it executes:</p>
+<pre class="literal-block">
+void debug ( const bool flag_ )
+
+bool debug ( void ) const
+</pre>
+</div>
+<div class="section" id="definevalue">
+<h2><a class="toc-backref" href="#id141">defineValue</a></h2>
+<p>Set or obtain a definition string to applied when encoding or decoding
+the specified format. The meanings of the definitions are format
+specific. The format is designated by the <cite>magick</cite> argument, the
+format-specific key is designated by <cite>key</cite>, and the associated value
+is specified by <cite>value</cite>. See the defineSet() method if the key must be
+removed entirely:</p>
+<pre class="literal-block">
+void defineValue ( const std::string &amp;magick_,
+ const std::string &amp;key_,
+ const std::string &amp;value_ )
+
+std::string defineValue ( const std::string &amp;magick_,
+ const std::string &amp;key_ ) const
+</pre>
+</div>
+<div class="section" id="defineset">
+<h2><a class="toc-backref" href="#id142">defineSet</a></h2>
+<p>Set or obtain a definition flag to applied when encoding or decoding
+the specified format. Similar to the defineValue() method except that
+passing the <cite>flag</cite> value 'true' creates a value-less define with that
+format and key. Passing the <cite>flag</cite> value 'false' removes any existing
+matching definition. The method returns 'true' if a matching key
+exists, and 'false' if no matching key exists:</p>
+<pre class="literal-block">
+void defineSet ( const std::string &amp;magick_,
+ const std::string &amp;key_,
+ bool flag_ )
+
+bool defineSet ( const std::string &amp;magick_,
+ const std::string &amp;key_ ) const
+</pre>
+</div>
+<div class="section" id="density">
+<h2><a class="toc-backref" href="#id143">density</a></h2>
+<p>Vertical and horizontal resolution in pixels of the image. This option
+specifies an image density when decoding a Postscript or Portable
+Document page. Often used with <cite>psPageSize</cite>:</p>
+<pre class="literal-block">
+void density ( const Geometry &amp;geomery_ )
+
+Geometry density ( void ) const
+</pre>
+<p>Please note that the 'density' method suffers from a design problem in
+that the Geometry object only supports integer dimensions, but the
+underlying image resolution is a floating point value. This results
+in rounding off the value. Please see the xResolution() and
+yResolution() methods for a way to set and get the resolution in
+floating point.</p>
+<p>The resolution units may be obtained via the resolutionUnits() method.</p>
+</div>
+<div class="section" id="depth">
+<h2><a class="toc-backref" href="#id144">depth</a></h2>
+<p>Image depth (bits allocated to red/green/blue components). Used to
+specify the bit depth when reading or writing raw images or when the
+output format supports multiple depths. Defaults to the quantum depth
+that GraphicsMagick is compiled with:</p>
+<pre class="literal-block">
+void depth ( const unsigned int depth_ )
+
+unsigned int depth ( void ) const
+</pre>
+</div>
+<div class="section" id="directory">
+<h2><a class="toc-backref" href="#id145">directory</a></h2>
+<p>Tile names from within an image montage:</p>
+<pre class="literal-block">
+std::string directory ( void ) const
+</pre>
+</div>
+<div class="section" id="endian">
+<h2><a class="toc-backref" href="#id146">endian</a></h2>
+<p>Endianness (<cite>LSBEndian</cite> like Intel, <cite>MSBEndian</cite> like SPARC, or
+<cite>NativeEndian</cite> for what this computer uses) for image formats which
+support endian-specific options:</p>
+<pre class="literal-block">
+void endian ( const EndianType endian_ )
+
+EndianType endian ( void ) const
+</pre>
+</div>
+<div class="section" id="filename">
+<h2><a class="toc-backref" href="#id147">fileName</a></h2>
+<p>Image file name:</p>
+<pre class="literal-block">
+void fileName ( const std::string &amp;fileName_ )
+
+std::string fileName ( void ) const
+</pre>
+</div>
+<div class="section" id="filesize">
+<h2><a class="toc-backref" href="#id148">fileSize</a></h2>
+<p>Number of bytes of the image on disk:</p>
+<pre class="literal-block">
+off_t fileSize ( void ) const
+</pre>
+</div>
+<div class="section" id="fillcolor">
+<h2><a class="toc-backref" href="#id149">fillColor</a></h2>
+<p><a class="reference external" href="Color.html">Color</a> to use when filling drawn objects:</p>
+<pre class="literal-block">
+void fillColor ( const Color &amp;fillColor_ )
+
+Color fillColor ( void ) const
+</pre>
+</div>
+<div class="section" id="fillpattern">
+<h2><a class="toc-backref" href="#id150">fillPattern</a></h2>
+<p>Pattern to use while filling drawn objects:</p>
+<pre class="literal-block">
+void fillPattern ( const Image &amp;fillPattern_ )
+
+Image fillPattern ( void ) const
+</pre>
+</div>
+<div class="section" id="fillrule">
+<h2><a class="toc-backref" href="#id151">fillRule</a></h2>
+<p>Rule to use when filling drawn objects:</p>
+<pre class="literal-block">
+void fillRule ( const FillRule &amp;fillRule_ )
+
+FillRule fillRule ( void ) const
+</pre>
+</div>
+<div class="section" id="filtertype">
+<h2><a class="toc-backref" href="#id152">filterType</a></h2>
+<p>Filter to use when resizing image. The reduction filter employed has a
+sigificant effect on the time required to resize an image and the
+resulting quality. The default filter is Lanczos which has been shown
+to produce high quality results when reducing most images:</p>
+<pre class="literal-block">
+void filterType ( const FilterTypes filterType_ )
+
+FilterTypes filterType ( void ) const
+</pre>
+</div>
+<div class="section" id="font">
+<h2><a class="toc-backref" href="#id153">font</a></h2>
+<p>Text rendering font. If the font is a fully qualified X server font
+name, the font is obtained from an X server. To use a TrueType font,
+precede the TrueType filename with an &#64;. Otherwise, specify a
+Postscript font name (e.g. &quot;helvetica&quot;).:</p>
+<pre class="literal-block">
+void font ( const std::string &amp;font_ )
+
+std::string font ( void ) const
+</pre>
+</div>
+<div class="section" id="fontpointsize">
+<h2><a class="toc-backref" href="#id154">fontPointsize</a></h2>
+<p>Text rendering font point size:</p>
+<pre class="literal-block">
+void fontPointsize ( const double pointSize_ )
+
+double fontPointsize ( void ) const
+</pre>
+</div>
+<div class="section" id="fonttypemetrics">
+<h2><a class="toc-backref" href="#id155">fontTypeMetrics</a></h2>
+<p>Obtain font metrics (see <a class="reference external" href="TypeMetric.html">TypeMetric</a>) for text string given current
+font, pointsize, and density settings. This information is necessary
+in order to do fancy layout of text:</p>
+<pre class="literal-block">
+void fontTypeMetrics( const std::string &amp;text_,
+ TypeMetric *metrics )
+</pre>
+</div>
+<div class="section" id="format">
+<h2><a class="toc-backref" href="#id156">format</a></h2>
+<p>Long image format description:</p>
+<pre class="literal-block">
+std::string format ( void ) const
+</pre>
+</div>
+<div class="section" id="formatexpression">
+<h2><a class="toc-backref" href="#id157">formatExpression</a></h2>
+<p>Format a string based on image properties similar to <cite>identify</cite>
+<cite>-format</cite>. For example, the format expression &quot;%wx%h&quot; is converted to
+a string containing image WIDTHxHEIGHT like &quot;640x480&quot;:</p>
+<pre class="literal-block">
+std::string formatExpression( const std::string expression )
+</pre>
+<p>Please note that this method is not a const method (may modify the
+Image object and will assure a reference count of one) and it <em>may</em>
+throw an exception if there is an internal error.</p>
+</div>
+<div class="section" id="id5">
+<h2><a class="toc-backref" href="#id158">gamma</a></h2>
+<p>Gamma level of the image. Gamma is a pow() function which converts
+between the linear light representation and the representation for the
+computer display. Most computer images are gamma corrected to 2.2
+(1/0.4545) so that each step results in a visually linear step on a
+computer or video display:</p>
+<pre class="literal-block">
+double gamma ( void ) const
+</pre>
+</div>
+<div class="section" id="id6">
+<h2><a class="toc-backref" href="#id159">geometry</a></h2>
+<p>Preferred size of the image when encoding:</p>
+<pre class="literal-block">
+Geometry geometry ( void ) const
+</pre>
+</div>
+<div class="section" id="gifdisposemethod">
+<h2><a class="toc-backref" href="#id160">gifDisposeMethod</a></h2>
+<p>GIF disposal method. This option (specific to the GIF file format) is
+used to control how successive frames are rendered (how the preceding
+frame is disposed of) when creating a GIF animation:</p>
+<pre class="literal-block">
+void gifDisposeMethod ( const unsigned int disposeMethod_ )
+
+unsigned int gifDisposeMethod ( void ) const
+</pre>
+</div>
+<div class="section" id="icccolorprofile">
+<h2><a class="toc-backref" href="#id161">iccColorProfile</a></h2>
+<p>ICC color profile. Supplied via a <a class="reference external" href="Blob.html">Blob</a> since Magick++/ and
+GraphicsMagick do not currently support formating this data structure
+directly.</p>
+<p>If there is not already an ICC color profile, the profile is merely
+attached to the image without transforming the pixels. If there is
+already an ICC color profile (the source profile), the pixels are
+translated according to the source and target profiles, and the
+existing profile is replaced with the target profile.</p>
+<p>Also see <a class="reference internal" href="#renderingintent">renderingIntent</a>, which allows specifying the rendering
+intent if the profile is executed.</p>
+<p>Specifications for ICC color profiles and their usage are available
+from the International Color Consortium for the format of ICC color
+profiles:</p>
+<pre class="literal-block">
+void iccColorProfile( const Blob &amp;colorProfile_ )
+
+Blob iccColorProfile( void ) const
+</pre>
+</div>
+<div class="section" id="interlacetype">
+<h2><a class="toc-backref" href="#id162">interlaceType</a></h2>
+<p>The type of interlacing scheme (default <cite>NoInterlace</cite> ). This option
+is used to specify the type of interlacing scheme for raw image
+formats such as RGB or YUV. <cite>NoInterlace</cite> means do not interlace,
+<cite>LineInterlace</cite> uses scanline interlacing, and <cite>PlaneInterlace</cite> uses
+plane interlacing. <cite>PartitionInterlace</cite> is like <cite>PlaneInterlace</cite>
+except the different planes are saved to individual files (e.g.
+image.R, image.G, and image.B). Use <cite>LineInterlace</cite> or
+<cite>PlaneInterlace</cite> to create an interlaced GIF or progressive JPEG
+image:</p>
+<pre class="literal-block">
+void interlaceType ( const InterlaceType interlace_ )
+
+InterlaceType interlaceType ( void ) const
+</pre>
+</div>
+<div class="section" id="iptcprofile">
+<h2><a class="toc-backref" href="#id163">iptcProfile</a></h2>
+<p>IPTC profile. Supplied via a <a class="reference external" href="Blob.html">Blob</a> since Magick++ and GraphicsMagick do
+not currently support formating this data structure
+directly. Specifications are available from the International Press
+Telecommunications Council for IPTC profiles:</p>
+<pre class="literal-block">
+void iptcProfile( const Blob&amp; iptcProfile_ )
+
+Blob iptcProfile( void ) const
+</pre>
+</div>
+<div class="section" id="isvalid">
+<h2><a class="toc-backref" href="#id164">isValid</a></h2>
+<p>Does object contain valid image? Set to <cite>false</cite> in order to invalidate
+the image. Images constructed via the default constructor are invalid
+images and isValid() will return false:</p>
+<pre class="literal-block">
+void isValid ( const bool isValid_ )
+
+bool isValid ( void ) const
+</pre>
+</div>
+<div class="section" id="id7">
+<h2><a class="toc-backref" href="#id165">label</a></h2>
+<p>Image label:</p>
+<pre class="literal-block">
+std::string label ( void ) const
+</pre>
+</div>
+<div class="section" id="linewidth">
+<h2><a class="toc-backref" href="#id166">lineWidth</a></h2>
+<p>Stroke width for drawing vector objects (default one)
+This method is now deprecated. Please use strokeWidth instead:</p>
+<pre class="literal-block">
+void lineWidth ( const double lineWidth_ )
+
+double lineWidth ( void ) const
+</pre>
+</div>
+<div class="section" id="magick">
+<h2><a class="toc-backref" href="#id167">magick</a></h2>
+<p>File type magick identifier (.e.g &quot;GIF&quot;):</p>
+<pre class="literal-block">
+void magick ( const std::string &amp;magick_ )
+
+std::string magick ( void ) const
+</pre>
+</div>
+<div class="section" id="matte">
+<h2><a class="toc-backref" href="#id168">matte</a></h2>
+<p>Image supports transparency (matte channel):</p>
+<pre class="literal-block">
+void matte ( const bool matteFlag_ )
+
+bool matte ( void ) const
+</pre>
+</div>
+<div class="section" id="mattecolor">
+<h2><a class="toc-backref" href="#id169">matteColor</a></h2>
+<p>Image matte (frame) <a class="reference external" href="Color.html">color</a>:</p>
+<pre class="literal-block">
+void matteColor ( const Color &amp;matteColor_ )
+
+Color matteColor ( void ) const
+</pre>
+</div>
+<div class="section" id="meanerrorperpixel">
+<h2><a class="toc-backref" href="#id170">meanErrorPerPixel</a></h2>
+<p>The mean error per pixel computed when an image is color reduced. This
+parameter is only valid if verbose is set to true and the image has
+just been quantized:</p>
+<pre class="literal-block">
+double meanErrorPerPixel ( void ) const
+</pre>
+</div>
+<div class="section" id="modulusdepth">
+<h2><a class="toc-backref" href="#id171">modulusDepth</a></h2>
+<p>Image modulus depth (minimum number of bits required to support
+red/green/blue components without loss of accuracy). The pixel modulus
+depth may be decreased by supplying a value which is less than the
+current value, updating the pixels (reducing accuracy) to the new
+depth. The pixel modulus depth can not be increased over the current
+value using this method:</p>
+<pre class="literal-block">
+void modulusDepth ( const unsigned int modulusDepth_ )
+
+unsigned int modulusDepth ( void ) const
+</pre>
+</div>
+<div class="section" id="monochrome">
+<h2><a class="toc-backref" href="#id172">monochrome</a></h2>
+<p>Transform image to black and white while color reducing (quantizing):</p>
+<pre class="literal-block">
+void monochrome ( const bool monochromeFlag_ )
+
+bool monochrome ( void ) const
+</pre>
+</div>
+<div class="section" id="montagegeometry">
+<h2><a class="toc-backref" href="#id173">montageGeometry</a></h2>
+<p>Tile size and offset within an image montage. Only valid for montage
+images:</p>
+<pre class="literal-block">
+Geometry montageGeometry ( void ) const
+</pre>
+</div>
+<div class="section" id="normalizedmaxerror">
+<h2><a class="toc-backref" href="#id174">normalizedMaxError</a></h2>
+<p>The normalized max error per pixel computed when an image is color
+reduced. This parameter is only valid if verbose is set to true and
+the image has just been quantized:</p>
+<pre class="literal-block">
+double normalizedMaxError ( void ) const
+</pre>
+</div>
+<div class="section" id="normalizedmeanerror">
+<h2><a class="toc-backref" href="#id175">normalizedMeanError</a></h2>
+<p>The normalized mean error per pixel computed when an image is color
+reduced. This parameter is only valid if verbose is set to true and
+the image has just been quantized:</p>
+<pre class="literal-block">
+double normalizedMeanError ( void ) const
+</pre>
+</div>
+<div class="section" id="orientation">
+<h2><a class="toc-backref" href="#id176">orientation</a></h2>
+<p>Image orientation. Supported by some file formats such as DPX and
+TIFF. Useful for turning the right way up:</p>
+<pre class="literal-block">
+void orientation ( const OrientationType orientation_ )
+
+OrientationType orientation ( void ) const
+</pre>
+</div>
+<div class="section" id="page">
+<h2><a class="toc-backref" href="#id177">page</a></h2>
+<p>Preferred size and location of an image canvas.</p>
+<p>Use this option to specify the dimensions and position of the
+Postscript page in dots per inch or a TEXT page in pixels. This option
+is typically used in concert with density .</p>
+<p>Page may also be used to position a GIF image (such as for a scene in
+an animation):</p>
+<pre class="literal-block">
+void page ( const Geometry &amp;pageSize_ )
+
+Geometry page ( void ) const
+</pre>
+</div>
+<div class="section" id="pixelcolor">
+<h2><a class="toc-backref" href="#id178">pixelColor</a></h2>
+<p>Get/set pixel <a class="reference external" href="Color.html">color</a> at location x &amp; y:</p>
+<pre class="literal-block">
+void pixelColor ( const unsigned int x_,
+ const unsigned int y_,
+ const Color &amp;color_ )
+
+Color pixelColor ( const unsigned int x_,
+ const unsigned int y_ ) const
+</pre>
+</div>
+<div class="section" id="profile">
+<h2><a class="toc-backref" href="#id179">profile</a></h2>
+<p>Add or remove a named profile to/from the image. Remove the
+profile by passing an empty <a class="reference external" href="Blob.html">Blob</a> (e.g. Blob()). Valid names are
+&quot;*&quot;, &quot;8BIM&quot;, &quot;ICM&quot;, &quot;IPTC&quot;, or a user/format-defined profile name:</p>
+<pre class="literal-block">
+void profile( const std::string name_,
+ const Blob &amp;colorProfile_ )
+</pre>
+<p>Retrieve a named profile from the image. Valid names are:
+&quot;8BIM&quot;, &quot;8BIMTEXT&quot;, &quot;APP1&quot;, &quot;APP1JPEG&quot;, &quot;ICC&quot;, &quot;ICM&quot;, &amp; &quot;IPTC&quot;
+or an existing user/format-defined profile name:</p>
+<pre class="literal-block">
+Blob profile( const std::string name_ ) const
+</pre>
+</div>
+<div class="section" id="quality">
+<h2><a class="toc-backref" href="#id180">quality</a></h2>
+<p>JPEG/MIFF/PNG compression level (default 75):</p>
+<pre class="literal-block">
+void quality ( const unsigned int quality_ )
+
+unsigned int quality ( void ) const
+</pre>
+</div>
+<div class="section" id="quantizecolors">
+<h2><a class="toc-backref" href="#id181">quantizeColors</a></h2>
+<p>Maximum number of colors to quantize to:</p>
+<pre class="literal-block">
+void quantizeColors ( const unsigned int colors_ )
+
+unsigned int quantizeColors ( void ) const
+</pre>
+</div>
+<div class="section" id="quantizecolorspace">
+<h2><a class="toc-backref" href="#id182">quantizeColorSpace</a></h2>
+<p>Colorspace to quantize in (default RGB). Empirical evidence suggests
+that distances in color spaces such as YUV or YIQ correspond to
+perceptual color differences more closely than do distances in RGB
+space. These color spaces may give better results when color reducing
+an image:</p>
+<pre class="literal-block">
+void quantizeColorSpace ( const ColorspaceType colorSpace_ )
+
+ColorspaceType quantizeColorSpace ( void ) const
+</pre>
+</div>
+<div class="section" id="quantizedither">
+<h2><a class="toc-backref" href="#id183">quantizeDither</a></h2>
+<p>Apply Floyd/Steinberg error diffusion to the image. The basic strategy
+of dithering is to trade intensity resolution for spatial resolution
+by averaging the intensities of several neighboring pixels. Images
+which suffer from severe contouring when reducing colors can be
+improved with this option. The quantizeColors or monochrome option
+must be set for this option to take effect:</p>
+<pre class="literal-block">
+void quantizeDither ( const bool ditherFlag_ )
+
+bool quantizeDither ( void ) const
+</pre>
+</div>
+<div class="section" id="quantizetreedepth">
+<h2><a class="toc-backref" href="#id184">quantizeTreeDepth</a></h2>
+<p>Depth of the quantization color classification tree. Values of 0 or 1
+allow selection of the optimal tree depth for the color reduction
+algorithm. Values between 2 and 8 may be used to manually adjust the
+tree depth:</p>
+<pre class="literal-block">
+void quantizeTreeDepth ( const unsigned int treeDepth_ )
+
+unsigned int quantizeTreeDepth ( void ) const
+</pre>
+</div>
+<div class="section" id="quiet">
+<h2><a class="toc-backref" href="#id185">quiet</a></h2>
+<p>Determines if Warning exceptions will be thrown, or suppressed.
+The default is that warnings will be thrown (i.e. false):</p>
+<pre class="literal-block">
+void quiet ( const bool quiet_ );
+bool quiet ( void ) const;
+</pre>
+</div>
+<div class="section" id="renderingintent">
+<h2><a class="toc-backref" href="#id186">renderingIntent</a></h2>
+<p>The type of rendering intent (used when applying an ICC color
+profile using <a class="reference internal" href="#icccolorprofile">iccColorProfile</a>):</p>
+<pre class="literal-block">
+void renderingIntent ( const RenderingIntent renderingIntent_ )
+
+RenderingIntent renderingIntent ( void ) const
+</pre>
+</div>
+<div class="section" id="repage">
+<h2><a class="toc-backref" href="#id187">repage</a></h2>
+<p>Reset the image page canvas and position:</p>
+<pre class="literal-block">
+void repage();
+</pre>
+</div>
+<div class="section" id="resolutionunits">
+<h2><a class="toc-backref" href="#id188">resolutionUnits</a></h2>
+<p>Units of image resolution:</p>
+<pre class="literal-block">
+void resolutionUnits ( const ResolutionType resolutionUnits_ )
+
+ResolutionType resolutionUnits ( void ) const
+</pre>
+</div>
+<div class="section" id="rows">
+<h2><a class="toc-backref" href="#id189">rows</a></h2>
+<p>The number of pixel rows in the image:</p>
+<pre class="literal-block">
+unsigned int rows ( void ) const
+</pre>
+</div>
+<div class="section" id="scene">
+<h2><a class="toc-backref" href="#id190">scene</a></h2>
+<p>Image scene number:</p>
+<pre class="literal-block">
+void scene ( const unsigned int scene_ )
+
+unsigned int scene ( void ) const
+</pre>
+</div>
+<div class="section" id="signature">
+<h2><a class="toc-backref" href="#id191">signature</a></h2>
+<p>Image textual signature. Set <cite>force</cite> to true in order to re-calculate
+the signature regardless of whether the image data has been modified:</p>
+<pre class="literal-block">
+std::string signature ( const bool force_ = false ) const
+</pre>
+</div>
+<div class="section" id="size">
+<h2><a class="toc-backref" href="#id192">size</a></h2>
+<p>Width and height of a raw image (an image which does not support width
+and height information). Size may also be used to affect the image
+size read from a multi-resolution format (e.g. Photo CD, JBIG, or
+JPEG:</p>
+<pre class="literal-block">
+void size ( const Geometry &amp;geometry_ )
+
+Geometry size ( void ) const
+</pre>
+</div>
+<div class="section" id="statistics">
+<h2><a class="toc-backref" href="#id193">statistics</a></h2>
+<p>Obtain image statistics. Statistics are normalized to the range
+of 0.0 to 1.0 and are output to the specified ImageStatistics
+structure:</p>
+<pre class="literal-block">
+void statistics ( ImageStatistics *statistics ) const
+</pre>
+</div>
+<div class="section" id="strokeantialias">
+<h2><a class="toc-backref" href="#id194">strokeAntiAlias</a></h2>
+<p>Enable/disable stroke anti-aliasing:</p>
+<pre class="literal-block">
+void strokeAntiAlias( const bool flag_ )
+
+bool strokeAntiAlias( void ) const
+</pre>
+</div>
+<div class="section" id="strokecolor">
+<h2><a class="toc-backref" href="#id195">strokeColor</a></h2>
+<p><a class="reference external" href="Color.html">Color</a> to use when drawing object outlines:</p>
+<pre class="literal-block">
+void strokeColor ( const Color &amp;strokeColor_ )
+
+Color strokeColor ( void ) const
+</pre>
+</div>
+<div class="section" id="strokedasharray">
+<h2><a class="toc-backref" href="#id196">strokeDashArray</a></h2>
+<p>Specify the pattern of dashes and gaps used to stroke paths. The
+strokeDashArray represents a zero-terminated array of numbers that
+specify the lengths of alternating dashes and gaps in pixels. If an
+odd number of values is provided, then the list of values is repeated
+to yield an even number of values. A typical <cite>strokeDashArray</cite> array
+might contain the members 5 3 2 0, where the zero value indicates the
+end of the pattern array:</p>
+<pre class="literal-block">
+void strokeDashArray ( const double* strokeDashArray_ )
+
+const double* strokeDashArray ( void ) const
+</pre>
+</div>
+<div class="section" id="strokedashoffset">
+<h2><a class="toc-backref" href="#id197">strokeDashOffset</a></h2>
+<p>While drawing using a dash pattern, specify distance into the
+dash pattern to start the dash (default 0):</p>
+<pre class="literal-block">
+void strokeDashOffset ( const double strokeDashOffset_ )
+
+double strokeDashOffset ( void ) const
+</pre>
+</div>
+<div class="section" id="strokelinecap">
+<h2><a class="toc-backref" href="#id198">strokeLineCap</a></h2>
+<p>Specify the shape to be used at the end of open subpaths when
+they are stroked. Values of LineCap are UndefinedCap, ButtCap,
+RoundCap, and SquareCap:</p>
+<pre class="literal-block">
+void strokeLineCap ( const LineCap lineCap_ )
+
+LineCap strokeLineCap ( void ) const
+</pre>
+</div>
+<div class="section" id="strokelinejoin">
+<h2><a class="toc-backref" href="#id199">strokeLineJoin</a></h2>
+<p>Specify the shape to be used at the corners of paths (or other
+vector shapes) when they are stroked. Values of LineJoin are
+UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin:</p>
+<pre class="literal-block">
+void strokeLineJoin ( const LineJoin lineJoin_ )
+
+LineJoin strokeLineJoin ( void ) const
+</pre>
+</div>
+<div class="section" id="strokemiterlimit">
+<h2><a class="toc-backref" href="#id200">strokeMiterLimit</a></h2>
+<p>Specify miter limit. When two line segments meet at a sharp
+angle and miter joins have been specified for 'lineJoin', it is
+possible for the miter to extend far beyond the thickness of
+the line stroking the path. The miterLimit' imposes a limit on
+the ratio of the miter length to the 'lineWidth'. The default
+value of this parameter is 4:</p>
+<pre class="literal-block">
+void strokeMiterLimit ( const unsigned int miterLimit_ )
+
+unsigned int strokeMiterLimit ( void ) const
+</pre>
+</div>
+<div class="section" id="strokepattern">
+<h2><a class="toc-backref" href="#id201">strokePattern</a></h2>
+<p>Pattern image to use while stroking object outlines:</p>
+<pre class="literal-block">
+void strokePattern ( const Image &amp;strokePattern_ )
+
+Image strokePattern ( void ) const
+</pre>
+</div>
+<div class="section" id="strokewidth">
+<h2><a class="toc-backref" href="#id202">strokeWidth</a></h2>
+<p>Stroke width for drawing vector objects (default one):</p>
+<pre class="literal-block">
+void strokeWidth ( const double strokeWidth_ )
+
+double strokeWidth ( void ) const
+</pre>
+</div>
+<div class="section" id="subimage">
+<h2><a class="toc-backref" href="#id203">subImage</a></h2>
+<p>Subimage of an image sequence:</p>
+<pre class="literal-block">
+void subImage ( const unsigned int subImage_ )
+
+unsigned int subImage ( void ) const
+</pre>
+</div>
+<div class="section" id="subrange">
+<h2><a class="toc-backref" href="#id204">subRange</a></h2>
+<p>Number of images relative to the base image:</p>
+<pre class="literal-block">
+void subRange ( const unsigned int subRange_ )
+
+unsigned int subRange ( void ) const
+</pre>
+</div>
+<div class="section" id="textencoding">
+<h2><a class="toc-backref" href="#id205">textEncoding</a></h2>
+<p>Annotation text encoding (e.g. &quot;UTF-16&quot;):</p>
+<pre class="literal-block">
+void textEncoding ( const std::string &amp;encoding_ )
+
+std::string textEncoding ( void ) const
+</pre>
+</div>
+<div class="section" id="tilename">
+<h2><a class="toc-backref" href="#id206">tileName</a></h2>
+<p>Tile name:</p>
+<pre class="literal-block">
+void tileName ( const std::string &amp;tileName_ )
+
+std::string tileName ( void ) const
+</pre>
+</div>
+<div class="section" id="totalcolors">
+<h2><a class="toc-backref" href="#id207">totalColors</a></h2>
+<p>Number of colors in the image:</p>
+<pre class="literal-block">
+unsigned long totalColors ( void )
+</pre>
+</div>
+<div class="section" id="transformorigin">
+<h2><a class="toc-backref" href="#id208">transformOrigin</a></h2>
+<p>Origin of coordinate system to use when annotating with text or drawing:</p>
+<pre class="literal-block">
+void transformOrigin ( const double x_,const double y_ )
+</pre>
+</div>
+<div class="section" id="transformrotation">
+<h2><a class="toc-backref" href="#id209">transformRotation</a></h2>
+<p>Rotation to use when annotating with text or drawing:</p>
+<pre class="literal-block">
+void transformRotation ( const double angle_ )
+</pre>
+</div>
+<div class="section" id="transformreset">
+<h2><a class="toc-backref" href="#id210">transformReset</a></h2>
+<p>Reset transformation parameters to default:</p>
+<pre class="literal-block">
+void transformReset ( void )
+</pre>
+</div>
+<div class="section" id="transformscale">
+<h2><a class="toc-backref" href="#id211">transformScale</a></h2>
+<p>Scale to use when annotating with text or drawing:</p>
+<pre class="literal-block">
+void transformScale ( const double sx_, const double sy_ )
+</pre>
+</div>
+<div class="section" id="transformskewx">
+<h2><a class="toc-backref" href="#id212">transformSkewX</a></h2>
+<p>Skew to use in X axis when annotating with text or drawing:</p>
+<pre class="literal-block">
+void transformSkewX ( const double skewx_ )
+</pre>
+</div>
+<div class="section" id="transformskewy">
+<h2><a class="toc-backref" href="#id213">transformSkewY</a></h2>
+<p>Skew to use in Y axis when annotating with text or drawing:</p>
+<pre class="literal-block">
+void transformSkewY ( const double skewy_ )
+</pre>
+</div>
+<div class="section" id="verbose">
+<h2><a class="toc-backref" href="#id214">verbose</a></h2>
+<p>Print detailed information about the image:</p>
+<pre class="literal-block">
+void verbose ( const bool verboseFlag_ )
+
+bool verbose ( void ) const
+</pre>
+</div>
+<div class="section" id="view">
+<h2><a class="toc-backref" href="#id215">view</a></h2>
+<p>FlashPix viewing parameters:</p>
+<pre class="literal-block">
+void view ( const std::string &amp;view_ )
+
+std::string view ( void ) const
+</pre>
+</div>
+<div class="section" id="x11display">
+<h2><a class="toc-backref" href="#id216">x11Display</a></h2>
+<p>X11 display to display to, obtain fonts from, or to capture
+image from:</p>
+<pre class="literal-block">
+void x11Display ( const std::string &amp;display_ )
+
+std::string x11Display ( void ) const
+</pre>
+</div>
+<div class="section" id="xresolution">
+<h2><a class="toc-backref" href="#id217">xResolution</a></h2>
+<p>x resolution of the image:</p>
+<pre class="literal-block">
+void xResolution ( const double x_resolution )
+double xResolution ( void ) const
+</pre>
+</div>
+<div class="section" id="yresolution">
+<h2><a class="toc-backref" href="#id218">yResolution</a></h2>
+<p>y resolution of the image:</p>
+<pre class="literal-block">
+void yResolution ( const double y_resolution )
+double yResolution ( void ) const
+</pre>
+</div>
+</div>
+<div class="section" id="low-level-image-pixel-access">
+<h1><a class="toc-backref" href="#id15">Low-Level Image Pixel Access</a></h1>
+<p>Image pixels (of type <a class="reference external" href="PixelPacket.html">PixelPacket</a> ) may be accessed directly via
+the Image Pixel Cache . The image pixel cache is a rectangular window
+into the actual image pixels (which may be in memory, memory-mapped
+from a disk file, or entirely on disk). Two interfaces exist to access
+the Image Pixel Cache. The interface described here (part of the Image
+class) supports only one view at a time. See the <a class="reference external" href="Pixels.html">Pixels</a> class for a
+more abstract interface which supports simultaneous pixel views (up to
+the number of rows). As an analogy, the interface described here
+relates to the <a class="reference external" href="Pixels.html">Pixels</a> class as stdio's gets() relates to
+fgets(). The <a class="reference external" href="Pixels.html">Pixels</a> class provides the more general form of the
+interface.</p>
+<p>Obtain existing image pixels via getPixels(). Create a new pixel
+region using setPixels().</p>
+<p>In order to ensure that only the current generation of the image is
+modified, the Image's modifyImage() method should be invoked to reduce
+the reference count on the underlying image to one. If this is not
+done, then it is possible for a previous generation of the image to be
+modified due to the use of reference counting when copying or
+constructing an Image.</p>
+<p>Depending on the capabilities of the operating system, and the
+relationship of the window to the image, the pixel cache may be a copy
+of the pixels in the selected window, or it may be the actual image
+pixels. In any case calling syncPixels() insures that the base image
+is updated with the contents of the modified pixel cache. The method
+readPixels() supports copying foreign pixel data formats into the
+pixel cache according to the QuantumTypes. The method writePixels()
+supports copying the pixels in the cache to a foreign pixel
+representation according to the format specified by QuantumTypes.</p>
+<p>The pixel region is effectively a small image in which the pixels may
+be accessed, addressed, and updated, as shown in the following
+example:</p>
+<p><img alt="pixel_cache" src="Cache.png" /></p>
+<pre class="literal-block">
+// Construct image based on an existing file
+Image image(&quot;cow.png&quot;);
+
+// Ensure that there are no other references to this image.
+image.modifyImage();
+
+// Set the image type to TrueColor DirectClass representation.
+image.type(TrueColorType);
+
+// Request pixel region with size 60x40, and top origin at 20x30
+int columns = 60;
+PixelPacket *pixel_cache = image.getPixels(20,30,columns,40);
+
+// Set pixel at column 5, and row 10 in the pixel cache to red.
+int column = 5;
+int row = 10;
+PixelPacket *pixel = pixel_cache+row*columns+column;
+*pixel = Color(&quot;red&quot;);
+
+// Save changes to underlying image .
+image.syncPixels();
+
+ // Save updated image to file.
+image.write(&quot;horse.png&quot;);
+</pre>
+<p>The image cache supports the following methods:</p>
+<div class="contents local topic" id="id8">
+<ul class="simple">
+<li><a class="reference internal" href="#getconstpixels" id="id219">getConstPixels</a></li>
+<li><a class="reference internal" href="#getindexes" id="id220">getIndexes</a></li>
+<li><a class="reference internal" href="#getconstindexes" id="id221">getConstIndexes</a></li>
+<li><a class="reference internal" href="#getpixels" id="id222">getPixels</a></li>
+<li><a class="reference internal" href="#setpixels" id="id223">setPixels</a></li>
+<li><a class="reference internal" href="#syncpixels" id="id224">syncPixels</a></li>
+<li><a class="reference internal" href="#readpixels" id="id225">readPixels</a></li>
+<li><a class="reference internal" href="#writepixels" id="id226">writePixels</a></li>
+</ul>
+</div>
+<div class="section" id="getconstpixels">
+<h2><a class="toc-backref" href="#id219">getConstPixels</a></h2>
+<p>Transfers read-only pixels from the image to the pixel cache as
+defined by the specified region:</p>
+<pre class="literal-block">
+const PixelPacket* getConstPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ ) const
+</pre>
+</div>
+<div class="section" id="getindexes">
+<h2><a class="toc-backref" href="#id220">getIndexes</a></h2>
+<p>Obtain mutable image pixel indexes (valid for PseudoClass images):</p>
+<pre class="literal-block">
+IndexPacket* getIndexes ( void )
+</pre>
+</div>
+<div class="section" id="getconstindexes">
+<h2><a class="toc-backref" href="#id221">getConstIndexes</a></h2>
+<p>Obtain immutable image pixel indexes (valid for PseudoClass images):</p>
+<pre class="literal-block">
+const IndexPacket* getConstIndexes ( void ) const
+</pre>
+</div>
+<div class="section" id="getpixels">
+<h2><a class="toc-backref" href="#id222">getPixels</a></h2>
+<p>Transfers pixels from the image to the pixel cache as defined by the
+specified region. Modified pixels may be subsequently transferred back
+to the image via syncPixels. This method is valid for DirectClass
+images:</p>
+<pre class="literal-block">
+PixelPacket* getPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+</pre>
+</div>
+<div class="section" id="setpixels">
+<h2><a class="toc-backref" href="#id223">setPixels</a></h2>
+<p>Allocates a pixel cache region to store image pixels as defined by the
+region rectangle. This area is subsequently transferred from the
+pixel cache to the image via syncPixels:</p>
+<pre class="literal-block">
+PixelPacket* setPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+</pre>
+</div>
+<div class="section" id="syncpixels">
+<h2><a class="toc-backref" href="#id224">syncPixels</a></h2>
+<p>Transfers the image cache pixels to the image:</p>
+<pre class="literal-block">
+void syncPixels ( void )
+</pre>
+</div>
+<div class="section" id="readpixels">
+<h2><a class="toc-backref" href="#id225">readPixels</a></h2>
+<p>Transfers one or more pixel components from a buffer or file into the
+image pixel cache of an image. Used to support image decoders:</p>
+<pre class="literal-block">
+void readPixels ( const QuantumType quantum_,
+ const unsigned char *source_ )
+</pre>
+</div>
+<div class="section" id="writepixels">
+<h2><a class="toc-backref" href="#id226">writePixels</a></h2>
+<p>Transfers one or more pixel components from the image pixel cache to a
+buffer or file. Used to support image encoders:</p>
+<pre class="literal-block">
+void writePixels ( const QuantumType quantum_,
+ unsigned char *destination_ )
+</pre>
+<p>Copyright © <a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">Bob Friesenhahn</a> 1999 - 2017</p>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Image.png b/www/Magick++/Image.png
new file mode 100644
index 0000000..35a85ee
--- /dev/null
+++ b/www/Magick++/Image.png
Binary files differ
diff --git a/www/Magick++/Image.rst b/www/Magick++/Image.rst
new file mode 100644
index 0000000..aca5e4b
--- /dev/null
+++ b/www/Magick++/Image.rst
@@ -0,0 +1,2817 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+====================
+ Magick::Image Class
+====================
+
+.. _`Blob` : Blob.html
+.. _`Bob Friesenhahn` : mailto:bfriesen@simple.dallas.tx.us
+.. _`CoderInfo` : CoderInfo.html
+.. _`Color` : Color.html
+.. _`Drawable` : Drawable.html
+.. _`Enumerations` : Enumerations.html
+.. _`Exception` : Exception.html
+.. _`Geometry` : Geometry.html
+.. _`GraphicsMagick` : ../index.html
+.. _`PixelPacket` : PixelPacket.html
+.. _`Pixels` : Pixels.html
+.. _`STL` : STL.html
+.. _`TypeMetric` : TypeMetric.html
+.. _`image design` : ImageDesign.html
+.. _`special format characters` : FormatCharacters.html
+
+.. contents::
+ :depth: 1
+
+Introduction
+------------
+
+Image is the primary object in Magick++ and represents a single image
+frame (see `image design`_). The `STL`_ interface must be used to
+operate on image sequences or images (e.g. of format GIF, TIFF, MIFF,
+Postscript, & MNG) which are comprized of multiple image
+frames. Individual frames of a multi-frame image may be requested by
+adding array-style notation to the end of the file name
+(e.g. "animation.gif[3]" retrieves the fourth frame of a GIF
+animation. Various image manipulation operations may be applied to
+the image. Attributes may be set on the image to influence the
+operation of the manipulation operations. The `Pixels`_ class provides
+low-level access to image pixels. As a convenience, including
+<Magick++.h> is sufficient in order to use the complete Magick++
+API. The Magick++ API is enclosed within the Magick namespace so you
+must either add the prefix " Magick:: " to each class/enumeration name
+or add the statement " using namespace Magick;" after including the
+Magick++.h header.
+
+The InitializeMagick() function *MUST* be invoked before constructing
+any Magick++ objects. This used to be optional, but now it is
+absolutely required. This function initalizes semaphores and
+configuration information necessary for the software to work
+correctly. Failing to invoke InitializeMagick() is likely to lead to
+a program crash or thrown assertion. If the program resides in the
+same directory as the GraphicsMagick files, then argv[0] may be passed
+as an argument so that GraphicsMagick knows where its files reside,
+otherwise NULL may be passed and GraphicsMagick will try to use other
+means (if necessary).
+
+The preferred way to allocate Image objects is via automatic
+allocation (on the stack). There is no concern that allocating Image
+objects on the stack will excessively enlarge the stack since Magick++
+allocates all large data objects (such as the actual image data) from
+the heap. Use of automatic allocation is preferred over explicit
+allocation (via new) since it is much less error prone and allows use
+of C++ scoping rules to avoid memory leaks. Use of automatic
+allocation allows Magick++ objects to be assigned and copied just like
+the C++ intrinsic data types (e.g. 'int '), leading to clear and easy
+to read code. Use of automatic allocation leads to naturally
+exception-safe code since if an exception is thrown, the object is
+automatically deallocated once the stack unwinds past the scope of the
+allocation (not the case for objects allocated via new ).
+
+Image is very easy to use. For example, here is a the source to a
+program which reads an image, crops it, and writes it to a new file
+(the exception handling is optional but strongly recommended)::
+
+ #include <Magick++.h>
+ #include <iostream>
+ using namespace std;
+ using namespace Magick;
+ int main(int argc,char **argv)
+ {
+ // Initialize the API. Can pass NULL if argv is not available.
+ InitializeMagick(*argv);
+
+ // Construct the image object. Seperating image construction from the
+ // the read operation ensures that a failure to read the image file
+ // doesn't render the image object useless.
+ Image image;
+
+ try {
+ // Determine if Warning exceptions are thrown.
+ // Use is optional. Set to true to block Warning exceptions.
+ image.quiet( false );
+
+ // Read a file into image object
+ image.read( "girl.gif" );
+
+ // Crop the image to specified size (width, height, xOffset, yOffset)
+ image.crop( Geometry(100,100, 100, 100) );
+
+ // Write the image to a file
+ image.write( "x.gif" );
+ }
+ catch( Exception &error_ )
+ {
+ cout << "Caught exception: " << error_.what() << endl;
+ return 1;
+ }
+ return 0;
+ }
+
+The following is the source to a program which illustrates the use of
+Magick++'s efficient reference-counted assignment and copy-constructor
+operations which minimize use of memory and eliminate unncessary copy
+operations (allowing Image objects to be efficiently assigned, and
+copied into containers). The program accomplishes the following:
+
+1. Read master image.
+2. Assign master image to second image.
+3. Zoom second image to the size 640x480.
+4. Assign master image to a third image.
+5. Zoom third image to the size 800x600.
+6. Write the second image to a file.
+7. Write the third image to a file.
+
+::
+
+ #include <Magick++.h>
+ #include <iostream>
+ using namespace std;
+ using namespace Magick;
+ int main(int argc,char **argv)
+ {
+ InitializeMagick(*argv);
+ Image master("horse.jpg");
+ Image second = master;
+ second.zoom("640x480");
+ Image third = master;
+ third.zoom("800x600");
+ second.write("horse640x480.jpg");
+ third.write("horse800x600.jpg");
+ return 0;
+ }
+
+During the entire operation, a maximum of three images exist in memory
+and the image data is never copied.
+
+The following is the source for another simple program which creates a
+100 by 100 pixel white image with a red pixel in the center and writes
+it to a file::
+
+ #include <Magick++.h>
+ using namespace std;
+ using namespace Magick;
+ int main(int argc,char **argv)
+ {
+ InitializeMagick(*argv);
+ Image image( "100x100", "white" );
+ image.pixelColor( 49, 49, "red" );
+ image.write( "red_pixel.png" );
+ return 0;
+ }
+
+If you wanted to change the color image to grayscale, you could add
+the lines::
+
+ image.quantizeColorSpace( GRAYColorspace );
+ image.quantizeColors( 256 );
+ image.quantize( );
+
+or, more simply::
+
+ image.type( GrayscaleType );
+
+prior to writing the image.
+
+BLOBs
+-----
+
+While encoded images (e.g. JPEG) are most often written-to and
+read-from a disk file, encoded images may also reside in
+memory. Encoded images in memory are known as BLOBs (Binary Large
+OBjects) and may be represented using the `Blob`_ class. The encoded
+image may be initially placed in memory by reading it directly from a
+file, reading the image from a database, memory-mapped from a disk
+file, or could be written to memory by Magick++. Once the encoded
+image has been placed within a `Blob`_, it may be read into a Magick++
+Image via a constructor or read() . Likewise, a Magick++ image may be
+written to a `Blob`_ via write().
+
+An example of using Image to write to a `Blob`_ follows::
+
+ #include <Magick++.h>
+ using namespace std;
+ using namespace Magick;
+ int main(int argc,char **argv)
+ {
+ // Read GIF file from disk
+ Image image( "giraffe.gif" );
+
+ // Write to BLOB in JPEG format
+ Blob blob;
+ image.magick( "JPEG" ) // Set JPEG output format
+ image.write( &blob );
+
+ [ Use BLOB data (in JPEG format) here ]
+
+ return 0;
+ }
+
+likewise, to read an image from a `Blob`_, you could use one of the
+following examples:
+
+[ Entry condition for the following examples is that data is pointer
+to encoded image data and length represents the size of the data ]
+
+::
+
+ Blob blob( data, length );
+ Image image( blob );
+
+or
+
+::
+
+ Blob blob( data, length );
+ Image image;
+ image.read( blob);
+
+Some images do not contain their size or format so the size and format
+must be specified in advance::
+
+ Blob blob( data, length );
+ Image image;
+ image.size( "640x480")
+ image.magick( "RGBA" );
+ image.read( blob);
+
+Construct An Image
+------------------
+
+An Image may be constructed in a number of ways. It may be constructed
+from a file, a URL, or an encoded image (e.g. JPEG) contained in an
+in-memory `Blob`_ . The following Image constructors and assignment
+operators are available:
+
+Construct from image file or image specification::
+
+ Image( const std::string &imageSpec_ )
+
+Construct a blank image canvas of specified size and `color`_::
+
+ Image( const Geometry &size_, const Color &color_ )
+
+Construct Image from in-memory `Blob`_::
+
+ Image ( const Blob &blob_ )
+
+Construct Image of specified size from in-memory `Blob`_::
+
+ Image ( const Blob &blob_, const Geometry &size_ )
+
+Construct Image of specified size and depth from in-memory `Blob`_::
+
+ Image ( const Blob &blob_, const Geometry &size,
+ const unsigned int depth )
+
+Construct Image of specified size, depth, and format from in-memory `Blob`_::
+
+ Image ( const Blob &blob_, const Geometry &size,
+ const unsigned int depth_,
+ const std::string &magick_ )
+
+Construct Image of specified size, and format from in-memory `Blob`_::
+
+ Image ( const Blob &blob_, const Geometry &size,
+ const std::string &magick_ )
+
+Construct an image based on an array of raw pixels, of specified type
+and mapping, in memory::
+
+ Image ( const unsigned int width_,
+ const unsigned int height_,
+ const std::string &map_,
+ const StorageType type_,
+ const void *pixels_ )
+
+Default constructor::
+
+ Image( void )
+
+Copy constructor::
+
+ Image ( const Image & image_ )
+
+Assignment operator::
+
+ Image& operator= ( const Image &image_ )
+
+Read Or Write An Image
+----------------------
+
+.. contents::
+ :local:
+
+ping
+++++
+
+Ping is similar to read_ except only enough of the image is read to
+determine the image columns, rows, and filesize. Access the
+columns(), rows(), and fileSize() attributes after invoking ping.
+Other attributes may also be available. The image pixels are not
+valid after calling ping::
+
+ void ping ( const std::string &imageSpec_ )
+
+Ping is similar to read except only enough of the image is read
+to determine the image columns, rows, and filesize. Access the
+columns(), rows(), and fileSize() attributes after invoking
+ping. The image pixels are not valid after calling ping::
+
+ void ping ( const Blob &blob_ )
+
+read
+++++
+
+Read single image frame into current object. Use ping_ instead if you
+want to obtain the basic attributes of the image without reading the
+whole file/blob::
+
+ void read ( const std::string &imageSpec_ )
+
+Read single image frame of specified size into current object::
+
+ void read ( const Geometry &size_,
+ const std::string &imageSpec_ )
+
+Read single image frame from in-memory `Blob`_::
+
+ void read ( const Blob &blob_ )
+
+Read single image frame of specified size from in-memory `Blob`_::
+
+ void read ( const Blob &blob_,
+ const Geometry &size_ )
+
+Read single image frame of specified size and depth from in-memory
+`Blob`_::
+
+ void read ( const Blob &blob_,
+ const Geometry &size_,
+ const unsigned int depth_ )
+
+Read single image frame of specified size, depth, and format from
+in-memory `Blob`_::
+
+ void read ( const Blob &blob_,
+ const Geometry &size_,
+ const unsigned int depth_,
+ const std::string &magick_ )
+
+Read single image frame of specified size, and format from in-memory
+`Blob`_::
+
+ void read ( const Blob &blob_,
+ const Geometry &size_,
+ const std::string &magick_ )
+
+Read single image frame from an array of raw pixels, with
+specified storage type (ConstituteImage), e.g.
+``image.read( 640, 480, "RGB", 0, pixels )``::
+
+ void read ( const unsigned int width_,
+ const unsigned int height_,
+ const std::string &map_,
+ const StorageType type_,
+ const void *pixels_ )
+
+write
++++++
+
+Write single image frame to a file::
+
+ void write ( const std::string &imageSpec_ )
+
+Write single image frame to in-memory `Blob`_, with optional format and
+adjoin parameters::
+
+ void write ( Blob *blob_ )
+
+ void write ( Blob *blob_,
+ const std::string &magick_ )
+
+ void write ( Blob *blob_,
+ const std::string &magick_,
+ const unsigned int depth_ )
+
+Write single image frame to an array of pixels with storage type
+specified by user (DispatchImage), e.g. ``image.write( 0, 0, 640, 1,
+"RGB", 0, pixels )``::
+
+ void write ( const int x_,
+ const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const std::string& map_,
+ const StorageType type_,
+ void *pixels_ )
+
+
+Manipulate An Image
+-------------------
+
+Image supports access to all the single-image (versus image-list)
+manipulation operations provided by the GraphicsMagick library. If you
+must process a multi-image file (such as an animation), the `STL`_
+interface , which provides a multi-image abstraction on top of Image,
+must be used.
+
+Image manipulation methods are very easy to use. For example::
+
+ Image image;
+ image.read("myImage.tiff");
+ image.addNoise(GaussianNoise);
+ image.write("myImage.tiff");
+
+adds gaussian noise to the image file "myImage.tiff".
+
+The following image manipulation methods are available:
+
+.. contents::
+ :local:
+
+adaptiveThreshold
++++++++++++++++++
+
+Apply adaptive thresholding to the image (see
+http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm). Adaptive
+thresholding is useful if the ideal threshold level is not known in
+advance, or if the illumination gradient is not constant across the
+image. Adaptive thresholding works by evaulating the mean (average) of
+a pixel region (size specified by width and height) and using the mean
+as the thresholding value. In order to remove residual noise from the
+background, the threshold may be adjusted by subtracting a constant
+offset (default zero) from the mean to compute the threshold::
+
+ void adaptiveThreshold ( const unsigned int width,
+ const unsigned int height,
+ const double offset = 0.0 )
+
+addNoise
+++++++++
+
+Add noise to image with the specified noise type::
+
+ void addNoise ( const NoiseType noiseType_ )
+
+addNoiseChannel
++++++++++++++++
+
+Add noise to an image channel with the specified noise type. The
+`channel` parameter specifies the channel to add noise to. The
+`noiseType` parameter specifies the type of noise::
+
+ void addNoiseChannel ( const ChannelType channel_,
+ const NoiseType noiseType_)
+
+affineTransform
++++++++++++++++
+
+Transform image by specified affine (or free transform) matrix::
+
+ void affineTransform ( const DrawableAffine &affine )
+
+annotate
+++++++++
+
+Annotate image (draw text on image)
+
+Gravity effects text placement in bounding area according to these
+rules:
+
+NorthWestGravity
+ text bottom-left corner placed at top-left
+NorthGravity
+ text bottom-center placed at top-center
+NorthEastGravity
+ text bottom-right corner placed at top-right
+WestGravity
+ text left-center placed at left-center
+CenterGravity
+ text center placed at center
+EastGravity
+ text right-center placed at right-center
+SouthWestGravity
+ text top-left placed at bottom-left
+SouthGravity
+ text top-center placed at bottom-center
+SouthEastGravity
+ text top-right placed at bottom-right
+
+Annotate using specified text, and placement location::
+
+ void annotate ( const std::string &text_,
+ const Geometry &location_ )
+
+Annotate using specified text, bounding area, and placement gravity::
+
+ void annotate ( const std::string &text_,
+ const Geometry &boundingArea_,
+ const GravityType gravity_ )
+
+Annotate with text using specified text, bounding area, placement
+gravity, and rotation::
+
+ void annotate ( const std::string &text_,
+ const Geometry &boundingArea_,
+ const GravityType gravity_,
+ const double degrees_ )
+
+Annotate with text (bounding area is entire image) and placement
+gravity::
+
+ void annotate ( const std::string &text_,
+ const GravityType gravity_ )
+
+blur
+++++
+
+Blur an image with the specified blur factor.
+
+The `radius` parameter specifies the radius of the Gaussian, in
+pixels, not counting the center pixel. The `sigma` parameter
+specifies the standard deviation of the Laplacian, in pixels::
+
+ void blur ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+
+blurChannel
++++++++++++
+
+Blur an image channel with the specified blur factor.
+
+The `channel` parameter specifies the channel to modify. The `radius`
+parameter specifies the radius of the Gaussian, in pixels, not
+counting the center pixel. The `sigma` parameter specifies the
+standard deviation of the Laplacian, in pixels::
+
+ void blurChannel ( const ChannelType channel_,
+ const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+
+border
+++++++
+
+Border image (add border to image). The `color`_ of the border is
+specified by the borderColor attribute::
+
+ void border ( const Geometry &geometry_
+ = borderGeometryDefault )
+
+cdl
++++
+
+Bake in the ASC-CDL, which is a convention for the for the exchange of
+basic primary color grading information between for the exchange of
+basic primary color grading information between equipment and software
+from different manufacturers. It is a useful transform for other
+purposes as well:
+
+ void cdl ( const std::string &cdl_ )
+
+See `CdlImage <../api/cdl.html#cdlimage>`_ for more details on the ASC-CDL.
+
+channel
++++++++
+
+Extract channel from image. Use this option to extract a particular
+channel from the image. MatteChannel for example, is useful for
+extracting the opacity values from an image::
+
+ void channel ( const ChannelType channel_ )
+
+channelDepth
+++++++++++++
+
+Set or obtain modulus channel depth::
+
+ void channelDepth ( const ChannelType channel_,
+ const unsigned int depth_ )
+
+ unsigned int channelDepth ( const ChannelType channel_ )
+
+charcoal
+++++++++
+
+Charcoal effect image (looks like charcoal sketch).
+
+The `radius` parameter specifies the radius of the Gaussian, in
+pixels, not counting the center pixel. The `sigma` parameter
+specifies the standard deviation of the Laplacian, in pixels::
+
+ void charcoal ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+
+chop
+++++
+
+Chop image (remove vertical or horizontal subregion of image)::
+
+ void chop ( const Geometry &geometry_ )
+
+colorize
+++++++++
+
+Colorize image with pen `color`_, using specified percent opacity for
+red, green, and blue quantums::
+
+ void colorize ( const unsigned int opacityRed_,
+ const unsigned int opacityGreen_,
+ const unsigned int opacityBlue_,
+ const Color &penColor_ )
+
+Colorize image with pen `color`_, using specified percent opacity::
+
+ void colorize ( const unsigned int opacity_,
+ const Color &penColor_ )
+
+colorMatrix
++++++++++++
+
+Apply a color matrix to the image channels. The user supplied matrix
+may be of order 1 to 5 (1x1 through 5x5)::
+
+ void colorMatrix (const unsigned int order_,
+ const double *color_matrix_)
+
+See `ColorMatrixImage <../api/fx.html#colormatriximage>`_ for more details.
+
+comment
++++++++
+
+Comment image (add comment string to image). By default, each image is
+commented with its file name. Use this method to assign a specific
+comment to the image. Optionally you can include the image filename,
+type, width, height, or other image attributes by embedding `special
+format characters`_::
+
+ void comment ( const std::string &comment_ )
+
+compare
++++++++
+
+Compare current image with another image. Sets meanErrorPerPixel,
+normalizedMaxError, and normalizedMeanError in the current
+image. False is returned if the images are identical. An ErrorOption
+exception is thrown if the reference image columns, rows, colorspace,
+or matte differ from the current image::
+
+ bool compare ( const Image &reference_ )
+
+composite
++++++++++
+
+Compose an image onto another at specified x and y offset and using a
+specified algorithm::
+
+ void composite ( const Image &compositeImage_,
+ const int xOffset_,
+ const int yOffset_,
+ const CompositeOperator compose_
+ = InCompositeOp )
+
+ void composite ( const Image &compositeImage_,
+ const Geometry &offset_,
+ const CompositeOperator compose_
+ = InCompositeOp )
+
+ void composite ( const Image &compositeImage_,
+ const GravityType gravity_,
+ const CompositeOperator compose_
+ = InCompositeOp )
+
+contrast
+++++++++
+
+Contrast image (enhance intensity differences in image)::
+
+ void contrast ( const unsigned int sharpen_ )
+
+convolve
+++++++++
+
+Convolve image. Applies a user-specified convolution to the image.
+The `order` parameter represents the number of columns and rows in the
+filter kernel while `kernel` is a two-dimensional array of doubles
+representing the convolution kernel to apply::
+
+ void convolve ( const unsigned int order_,
+ const double *kernel_ )
+
+crop
+++++
+
+Crop image (return subregion of original image)::
+
+ void crop ( const Geometry &geometry_ )
+
+cycleColormap
++++++++++++++
+
+Cycle (rotate) image colormap::
+
+ void cycleColormap ( const int amount_ )
+
+despeckle
++++++++++
+
+Despeckle image (reduce speckle noise)::
+
+ void despeckle ( void )
+
+display
++++++++
+
+Display image on screen. Caution: if an image format is is not
+compatible with the display visual (e.g. JPEG on a colormapped
+display) then the original image will be altered. Use a copy of the
+original if this is a problem:
+
+ void display ( void )
+
+draw
+++++
+
+Draw shape or text on image using a single `drawable`_ object::
+
+ void draw ( const Drawable &drawable_ );
+
+Draw shapes or text on image using a set of `Drawable`_ objects
+contained in an `STL`_ list. Use of this method improves drawing
+performance and allows batching draw objects together in a list for
+repeated use::
+
+ void draw ( const std::list<Magick::Drawable> &drawable_ );
+
+edge
+++++
+
+Edge image (hilight edges in image). The radius is the radius of the
+pixel neighborhood.. Specify a radius of zero for automatic radius
+selection::
+
+ void edge ( const double radius_ = 0.0 )
+
+emboss
+++++++
+
+Emboss image (hilight edges with 3D effect). The `radius` parameter
+specifies the radius of the Gaussian, in pixels, not counting the
+center pixel. The `sigma` parameter specifies the standard deviation
+of the Laplacian, in pixels::
+
+ void emboss ( const double radius_ = 0.0,
+ const double sigma_ = 1.0)
+
+enhance
++++++++
+
+Enhance image (minimize noise)::
+
+ void enhance ( void );
+
+equalize
+++++++++
+
+Equalize image (histogram equalization)::
+
+ void equalize ( void )
+
+erase
++++++
+
+Set all image pixels to the current background color::
+
+ void erase ( void )
+
+extent
+++++++
+
+Create an image canvas using background color sized according to
+geometry and composite existing image on it, with image placement
+controlled by gravity. Parameters are obtained from existing image
+properties if they are not specified via a method
+parameter. Parameters which are supported by image properties (gravity
+and backgroundColor) update those image properties as a side-effect::
+
+ void extent ( const Geometry &geometry_ )
+
+ void extent ( const Geometry &geometry_,
+ const GravityType &gravity_ )
+
+ void extent ( const Geometry &geometry_,
+ const Color &backgroundColor_ )
+
+ void extent ( const Geometry &geometry_,
+ const Color &backgroundColor_,
+ const GravityType &gravity_ );
+
+
+flip
+++++
+
+Flip image (reflect each scanline in the vertical direction)::
+
+ void flip ( void )
+
+floodFillColor
+++++++++++++++
+
+Flood-fill `color`_ across pixels that match the `color`_ of the target
+pixel and are neighbors of the target pixel. Uses current fuzz
+setting when determining `color`_ match::
+
+ void floodFillColor( const unsigned int x_,
+ const unsigned int y_,
+ const Color &fillColor_ )
+
+ void floodFillColor( const Geometry &point_,
+ const Color &fillColor_ )
+
+Flood-fill `color`_ across pixels starting at target-pixel and stopping
+at pixels matching specified border `color`_. Uses current fuzz setting
+when determining `color`_ match::
+
+ void floodFillColor( const unsigned int x_,
+ const unsigned int y_,
+ const Color &fillColor_,
+ const Color &borderColor_ )
+
+ void floodFillColor( const Geometry &point_,
+ const Color &fillColor_,
+ const Color &borderColor_ )
+
+floodFillOpacity
+++++++++++++++++
+
+Flood-fill pixels matching `color`_ (within fuzz factor) of target
+pixel(x,y) with replacement opacity value using method::
+
+ void floodFillOpacity ( const unsigned int x_,
+ const unsigned int y_,
+ const unsigned int opacity_,
+ const PaintMethod method_ )
+
+floodFillTexture
+++++++++++++++++
+
+Flood-fill texture across pixels that match the `color`_ of the
+target pixel and are neighbors of the target pixel.
+Uses current fuzz setting when determining `color`_ match::
+
+ void floodFillTexture( const unsigned int x_,
+ const unsigned int y_,
+ const Image &texture_ )
+
+ void floodFillTexture( const Geometry &point_,
+ const Image &texture_ )
+
+Flood-fill texture across pixels starting at target-pixel and
+stopping at pixels matching specified border `color`_.
+Uses current fuzz setting when determining `color`_ match::
+
+ void floodFillTexture( const unsigned int x_,
+ const unsigned int y_,
+ const Image &texture_,
+ const Color &borderColor_ )
+
+ void floodFillTexture( const Geometry &point_,
+ const Image &texture_,
+ const Color &borderColor_ )
+
+flop
+++++
+
+Flop image (reflect each scanline in the horizontal direction)::
+
+ void flop ( void );
+
+frame
++++++
+
+Draw a decorative frame around the image::
+
+ void frame ( const Geometry &geometry_ = frameGeometryDefault )
+
+ void frame ( const unsigned int width_,
+ const unsigned int height_,
+ const int innerBevel_ = 6,
+ const int outerBevel_ = 6 )
+
+gamma
++++++
+
+Gamma correct the image or individual image channels::
+
+ void gamma ( const double gamma_ )
+
+ void gamma ( const double gammaRed_,
+ const double gammaGreen_,
+ const double gammaBlue_ )
+
+gaussianBlur
+++++++++++++
+
+Gaussian blur image. The number of neighbor pixels to be included in
+the convolution mask is specified by `width`. The standard deviation
+of the gaussian bell curve is specified by `sigma`::
+
+ void gaussianBlur ( const double width_, const double sigma_ )
+
+gaussianBlurChannel
++++++++++++++++++++
+
+Gaussian blur image channel. The number of neighbor pixels to be
+included in the convolution mask is specified by `width`. The
+standard deviation of the gaussian bell curve is specified by
+`sigma`::
+
+ void gaussianBlurChannel ( const ChannelType channel_,
+ const double width_,
+ const double sigma_ )
+
+implode
++++++++
+
+Implode image (special effect)::
+
+ void implode ( const double factor_ )
+
+haldClut
+++++++++
+
+Apply a color lookup table (Hald CLUT) to the image::
+
+ void haldClut ( const Image &clutImage_ )
+
+See `HaldClutImage <../api/hclut.html#haldclutimage>`_ for more details.
+
+label
++++++
+
+Assign a label to an image. Use this option to assign a specific label
+to the image. Optionally you can include the image filename, type,
+width, height, or scene number in the label by embedding `special
+format characters`_. If the first character of string is @, the image
+label is read from a file titled by the remaining characters in the
+string. When converting to Postscript, use this option to specify a
+header string to print above the image::
+
+ void label ( const std::string &label_ )
+
+level
++++++
+
+Level image to increase image contrast, and/or adjust image
+gamma. Adjust the levels of the image by scaling the colors falling
+between specified white and black points to the full available quantum
+range. The parameters provided represent the black, mid (gamma), and
+white points. The black point specifies the darkest color in the
+image. Colors darker than the black point are set to zero. Mid point
+(gamma) specifies a gamma correction to apply to the image. White
+point specifies the lightest color in the image. Colors brighter than
+the white point are set to the maximum quantum value. The black and
+white point have the valid range 0 to MaxRGB while mid (gamma) has a
+useful range of 0 to ten::
+
+ void level ( const double black_point,
+ const double white_point,
+ const double mid_point=1.0 )
+
+levelChannel
+++++++++++++
+
+Level image channel to increase image contrast, and/or adjust image
+gamma. Adjust the levels of the image channel by scaling the colors
+falling between specified white and black points to the full available
+quantum range. The parameters provided represent the black, mid
+(gamma), and white points. The black point specifies the darkest
+color in the image. Colors darker than the black point are set to
+zero. Mid point (gamma) specifies a gamma correction to apply to the
+image. White point specifies the lightest color in the image. Colors
+brighter than the white point are set to the maximum quantum
+value. The black and white point have the valid range 0 to MaxRGB
+while mid (gamma) has a useful range of 0 to ten::
+
+ void levelChannel ( const ChannelType channel,
+ const double black_point,
+ const double white_point,
+ const double mid_point=1.0 )
+
+magnify
++++++++
+
+Magnify image by integral size (double the dimensions)::
+
+ void magnify ( void )
+
+map
++++
+
+Remap image colors with closest color from a reference image. Set
+`dither` to true in to apply Floyd/Steinberg error diffusion to the
+image. By default, color reduction chooses an optimal set of colors
+that best represent the original image. Alternatively, you can choose
+a particular set of colors from an image file with this option::
+
+ void map ( const Image &mapImage_ ,
+ const bool dither_ = false )
+
+matteFloodfill
+++++++++++++++
+
+Floodfill designated area with a replacement opacity value::
+
+ void matteFloodfill ( const Color &target_ ,
+ const unsigned int opacity_,
+ const int x_, const int y_,
+ const PaintMethod method_ )
+
+medianFilter
+++++++++++++
+
+Filter image by replacing each pixel component with the median color
+in a circular neighborhood::
+
+ void medianFilter ( const double radius_ = 0.0 )
+
+minify
+++++++
+
+Reduce image by integral (half) size::
+
+ void minify ( void )
+
+modifyImage
++++++++++++
+
+Prepare to update image (copy if reference > 1). Normally Magick++'s
+implicit reference counting takes care of all instance management. In
+the rare case that the automatic instance management does not work,
+use this method to assure that there is only one reference to the
+image to be modified. It should be used in the cases where a
+GraphicsMagick C function is used directly on an image which may have
+multiple references::
+
+ void modifyImage ( void )
+
+modulate
+++++++++
+
+Modulate percent hue, saturation, and brightness of an image.
+Modulation of saturation and brightness is as a ratio of the current
+value (1.0 for no change). Modulation of hue is an absolute rotation
+of -180 degrees to +180 degrees from the current position
+corresponding to an argument range of 0 to 2.0 (1.0 for no change)::
+
+ void modulate ( const double brightness_,
+ const double saturation_,
+ const double hue_ )
+
+motionBlur
+++++++++++
+
+Motion blur image with specified blur factor. The `radius` parameter
+specifies the radius of the Gaussian, in pixels, not counting the
+center pixel. The `sigma` parameter specifies the standard
+deviation of the Laplacian, in pixels. The `angle` parameter
+specifies the angle the object appears to be comming from (zero
+degrees is from the right)::
+
+ void motionBlur ( const double radius_,
+ const double sigma_,
+ const double angle_ )
+
+negate
+++++++
+
+Negate colors in image. Set `grayscale` to only negate grayscale
+values in image::
+
+ void negate ( const bool grayscale_ = false )
+
+normalize
++++++++++
+
+Normalize image (increase contrast by normalizing the pixel values to
+span the full range of color values)::
+
+ void normalize ( void )
+
+oilPaint
+++++++++
+
+Oilpaint image (image looks like an oil painting)::
+
+ void oilPaint ( const double radius_ = 3.0 )
+
+opacity
++++++++
+
+Set or attenuate the opacity channel in the image. If the image pixels
+are opaque then they are set to the specified opacity value, otherwise
+they are blended with the supplied opacity value. The value of
+`opacity` ranges from 0 (completely opaque) to MaxRGB. The defines
+`OpaqueOpacity` and `TransparentOpacity` are available to specify
+completely opaque or completely transparent, respectively::
+
+ void opacity ( const unsigned int opacity_ )
+
+opaque
+++++++
+
+Change `color`_ of specified opaque pixel to specified pen `color`_::
+
+ void opaque ( const Color &opaqueColor_,
+ const Color &penColor_ )
+
+quantize
+++++++++
+
+Quantize image (reduce number of colors). Set `measureError` to true
+in order to calculate error attributes::
+
+ void quantize ( const bool measureError_ = false )
+
+quantumOperator
++++++++++++++++
+
+Apply an arithmetic or bitwise operator to the image pixel quantums::
+
+ void quantumOperator ( const ChannelType channel_,
+ const QuantumOperator operator_,
+ double rvalue_)
+
+ void quantumOperator ( const int x_,const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_,
+ const ChannelType channel_,
+ const QuantumOperator operator_,
+ const double rvalue_)
+
+process
++++++++
+
+Execute a named process module using an argc/argv syntax similar to
+that accepted by a C 'main' routine. An exception is thrown if the
+requested process module doesn't exist, fails to load, or fails during
+execution::
+
+ void process ( std::string name_,
+ const int argc_,
+ char **argv_ )
+
+raise
++++++
+
+Raise image (lighten or darken the edges of an image to give a 3-D
+raised or lowered effect)::
+
+ void raise ( const Geometry &geometry_ = "6x6+0+0",
+ const bool raisedFlag_ = false )
+
+randomThreshold
++++++++++++++++
+
+Random threshold image.
+
+Changes the value of individual pixels based on the intensity
+of each pixel compared to a random threshold. The result is a
+low-contrast, two color image. The `thresholds` argument is a
+geometry containing LOWxHIGH thresholds. If the string
+contains 2x2, 3x3, or 4x4, then an ordered dither of order 2,
+3, or 4 will be performed instead. If a `channel` argument is
+specified then only the specified channel is altered. This is
+a very fast alternative to 'quantize' based dithering::
+
+ void randomThreshold( const Geometry &thresholds_ )
+
+randomThresholdChannel
+++++++++++++++++++++++
+
+Random threshold image channel.
+
+Changes the value of individual pixels based on the intensity of each
+pixel compared to a random threshold. The result is a low-contrast,
+two color image. The `thresholds` argument is a geometry containing
+LOWxHIGH thresholds. If the string contains 2x2, 3x3, or 4x4, then an
+ordered dither of order 2, 3, or 4 will be performed instead. If a
+`channel` argument is specified then only the specified channel is
+altered. This is a very fast alternative to 'quantize' based
+dithering::
+
+ void randomThresholdChannel( const Geometry &thresholds_,
+ const ChannelType channel_ )
+
+
+reduceNoise
++++++++++++
+
+Reduce noise in image using a noise peak elimination filter::
+
+ void reduceNoise ( void )
+
+ void reduceNoise ( const double order_ )
+
+resize
+++++++
+
+Resize image, specifying geometry, filter, and blur (blur > 1.0 is
+more blurry and < 1.0 is sharper)::
+
+ void resize ( const Geometry &geometry_,
+ const FilterTypes filterType_,
+ const double blur_ )
+
+Resize image, specifying geometry and filter, with blur using Image
+default::
+
+ void resize ( const Geometry &geometry_,
+ const FilterTypes filterType_ )
+
+Resize image, specifying only geometry, with filter and blur obtained
+from Image default. Provides the same result as the `zoom` method::
+
+ void resize ( const Geometry &geometry_ );
+
+roll
+++++
+
+Roll image (rolls image vertically and horizontally) by specified
+number of columnms and rows)::
+
+ void roll ( const Geometry &roll_ )
+
+ void roll ( const unsigned int columns_,
+ const unsigned int rows_ )
+
+rotate
+++++++
+
+Rotate image counter-clockwise by specified number of degrees::
+
+ void rotate ( const double degrees_ )
+
+sample
+++++++
+
+Resize image by using pixel sampling algorithm::
+
+ void sample ( const Geometry &geometry_ )
+
+scale
++++++
+
+Resize image by using simple ratio algorithm which provides good
+quality::
+
+ void scale ( const Geometry &geometry_ )
+
+thumbnail
++++++++++
+
+Resize image using several algorithms to make smaller images very
+quickly. This is very useful to create thumbnails from large images
+but usually works well for any image resizing purpose::
+
+ void thumbnail ( const Geometry &geometry_ );
+
+segment
++++++++
+
+Segment (coalesce similar image components) by analyzing the
+histograms of the color components and identifying units that are
+homogeneous with the fuzzy c-means technique. A histogram is built
+for the image. This histogram is filtered to reduce noise and a
+second derivative of the histogram plot is built and used to identify
+potential cluster colors (peaks in the histogram). The cluster colors
+are then validated by scanning through all of the pixels to see how
+many pixels fall within each cluster. Some candidate cluster colors
+may not match any of the image pixels at all and should be discarded.
+Specify `clusterThreshold`, as the number of pixels matching a cluster
+color in order for the cluster to be considered
+valid. `SmoothingThreshold` eliminates noise in the second derivative
+of the histogram. As the value is increased, you can expect a smoother
+second derivative. The default is 1.5::
+
+ void segment ( const double clusterThreshold_ = 1.0,
+ const double smoothingThreshold_ = 1.5 )
+
+shade
++++++
+
+Shade image using distant light source. Specify `azimuth` and
+`elevation` as the position of the light source. By default, the
+shading results as a grayscale image.. Set `colorShading` to true to
+shade the red, green, and blue components of the image::
+
+ void shade ( const double azimuth_ = 30,
+ const double elevation_ = 30,
+ const bool colorShading_ = false )
+
+sharpen
++++++++
+
+Sharpen pixels in image. The `radius` parameter specifies the radius
+of the Gaussian, in pixels, not counting the center pixel. The
+`sigma` parameter specifies the standard deviation of the Laplacian,
+in pixels::
+
+ void sharpen ( const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+
+sharpenChannel
+++++++++++++++
+
+Sharpen pixels in image channel. The `radius` parameter specifies the
+radius of the Gaussian, in pixels, not counting the center pixel. The
+`sigma` parameter specifies the standard deviation of the Laplacian,
+in pixels::
+
+ void sharpenChannel ( const ChannelType channel_,
+ const double radius_ = 0.0,
+ const double sigma_ = 1.0 )
+
+shave
++++++
+
+Shave pixels from image edges::
+
+ void shave ( const Geometry &geometry_ )
+
+shear
++++++
+
+Shear image (create parallelogram by sliding image by X or Y
+axis). Shearing slides one edge of an image along the X or Y axis,
+creating a parallelogram. An X direction shear slides an edge along
+the X axis, while a Y direction shear slides an edge along the Y axis.
+The amount of the shear is controlled by a shear angle. For X
+direction shears, x degrees is measured relative to the Y axis, and
+similarly, for Y direction shears y degrees is measured relative to
+the X axis. Empty triangles left over from shearing the image are
+filled with the `color`_ defined as borderColor::
+
+ void shear ( const double xShearAngle_,
+ const double yShearAngle_ )
+
+solarize
+++++++++
+
+Solarize image (similar to effect seen when exposing a photographic
+film to light during the development process)::
+
+ void solarize ( const double factor_ = 50.0 )
+
+spread
+++++++
+
+Spread pixels randomly within image by specified ammount::
+
+ void spread ( const unsigned int amount_ = 3 )
+
+stegano
++++++++
+
+Add a digital watermark to the image (based on second image)::
+
+ void stegano ( const Image &watermark_ )
+
+stereo
+++++++
+
+Create an image which appears in stereo when viewed with red-blue
+glasses (Red image on left, blue on right)::
+
+ void stereo ( const Image &rightImage_ )
+
+strip
++++++
+
+Remove all profiles and text attributes from the image.
+
+ void strip ( void );
+
+swirl
++++++
+
+Swirl image (image pixels are rotated by degrees)::
+
+ void swirl ( const double degrees_ )
+
+texture
++++++++
+
+Channel a texture on pixels matching image background `color`_::
+
+ void texture ( const Image &texture_ )
+
+threshold
++++++++++
+
+Threshold image channels (below threshold becomes black, above
+threshold becomes white). The range of the threshold parameter is 0
+to MaxRGB::
+
+ void threshold ( const double threshold_ )
+
+transform
++++++++++
+
+Transform image based on image and crop geometries. Crop geometry is
+optional::
+
+ void transform ( const Geometry &imageGeometry_ )
+
+ void transform ( const Geometry &imageGeometry_,
+ const Geometry &cropGeometry_ )
+
+transparent
++++++++++++
+
+Add matte channel to image, setting pixels matching `color`_ to
+transparent::
+
+ void transparent ( const Color &color_ )
+
+trim
+++++
+
+Trim edges that are the background `color`_ from the image::
+
+ void trim ( void )
+
+type
+++++
+
+Convert the image representation to the specified type or retrieve the
+current image type. If the image is reduced to an inferior type, then
+image information may be lost (e.g. color changed to grayscale).
+
+Available enumerations for the `type` parameter:
+
+ BilevelType
+ black/white
+ GrayscaleType
+ grayscale
+ GrayscaleMatteType
+ grayscale with alpha (opacity) channel
+ PaletteType
+ colormapped
+ PaletteMatteType
+ colormapped with transparency
+ TrueColorType
+ true (full) color
+ TrueColorMatteType
+ true (full) color with alpha (opacity) channel
+ ColorSeparationType
+ Cyan, magenta, yellow, and black
+ ColorSeparationMatteType
+ Cyan, magenta, yellow, and black with alpha (opacity) channel
+ OptimizeType
+ Optimize the image type to best represent the existing pixels
+
+::
+
+ void type ( const ImageType type_ )
+
+ ImageType type ( void ) const
+
+unsharpmask
++++++++++++
+
+Replace image with a sharpened version of the original image using the
+unsharp mask algorithm.
+
+ `radius`
+ the radius of the Gaussian, in pixels, not counting the
+ center pixel.
+ `sigma`
+ the standard deviation of the Gaussian, in pixels.
+ `amount`
+ the percentage of the difference between the original and
+ the blur image that is added back into the original.
+ `threshold`
+ the threshold in pixels needed to apply the diffence amount.
+
+::
+
+ void unsharpmask ( const double radius_,
+ const double sigma_,
+ const double amount_,
+ const double threshold_ )
+
+unsharpmaskChannel
+++++++++++++++++++
+
+Replace image channel with a sharpened version of the original image
+using the unsharp mask algorithm.
+
+ `channel`
+ image channel to modify.
+ `radius`
+ the radius of the Gaussian, in pixels, not counting the
+ center pixel.
+ `sigma`
+ the standard deviation of the Gaussian, in pixels.
+ `amount`
+ the percentage of the difference between the original and
+ the blur image that is added back into the original.
+ `threshold`
+ the threshold in pixels needed to apply the diffence amount.
+
+::
+
+ void unsharpmaskChannel ( const ChannelType channel_,
+ const double radius_,
+ const double sigma_,
+ const double amount_,
+ const double threshold_ );
+
+wave
+++++
+
+Map image pixels to a sine wave::
+
+ void wave ( const double amplitude_ = 25.0,
+ const double wavelength_ = 150.0 )
+
+zoom
+++++
+
+Zoom (resize) image to specified size::
+
+ void zoom ( const Geometry &geometry_ )
+
+
+Set/Get Image Attributes
+------------------------
+
+Image attributes are set and obtained via methods in Image. Except for
+methods which accept pointer arguments (e.g. chromaBluePrimary) all
+methods return attributes by value.
+
+Image attributes are easily used. For example, to set the resolution
+of the TIFF file "file.tiff" to 150 dots-per-inch (DPI) in both the
+horizontal and vertical directions, you can use the following example
+code::
+
+ string filename("file.tiff");
+ Image image;
+ image.read(filename);
+ image.resolutionUnits(PixelsPerInchResolution);
+ image.density(Geometry(150,150)); // could also use image.density("150x150")
+ image.write(filename)
+
+The following image attribute methods are available:
+
+.. contents::
+ :local:
+
+adjoin
+++++++
+
+Join images into a single multi-image file::
+
+ void adjoin ( const bool flag_ )
+
+ bool adjoin ( void ) const
+
+antiAlias
++++++++++
+
+Control antialiasing of rendered Postscript and Postscript or TrueType
+fonts. Enabled by default::
+
+ void antiAlias( const bool flag_ )
+
+ bool antiAlias( void )
+
+animationDelay
+++++++++++++++
+
+Time in 1/100ths of a second (0 to 65535) which must expire before
+displaying the next image in an animated sequence. This option is
+useful for regulating the animation of a sequence of GIF images within
+Netscape::
+
+ void animationDelay ( const unsigned int delay_ )
+
+ unsigned int animationDelay ( void ) const
+
+animationIterations
++++++++++++++++++++
+
+Number of iterations to loop an animation (e.g. Netscape loop
+extension) for::
+
+ void animationIterations ( const unsigned int iterations_ )
+
+ unsigned int animationIterations ( void ) const
+
+attribute
++++++++++
+
+Access or update an arbitrary named image attribute. Any number of
+named attributes may be attached to the image. For example, the image
+comment is a named image attribute with the name "comment". If the
+named attribute already exists, the provided text is appended to the
+existing attribute text. Pass NULL to remove an existing text
+attribute, or to restart the text attribute from scratch.
+
+EXIF tags are attached to the image as named attributes. Use the
+syntax "EXIF:<tag>" to request an EXIF tag similar to
+"EXIF:DateTime"::
+
+ void attribute ( const std::string name_,
+ const char * value_ );
+
+ void attribute ( const std::string name_,
+ const std::string value_ )
+
+ std::string attribute ( const std::string name_ )
+
+backgroundColor
++++++++++++++++
+
+Image background `color`_::
+
+ void backgroundColor ( const Color &color_ )
+
+ Color backgroundColor ( void ) const
+
+backgroundTexture
++++++++++++++++++
+
+Image file name to use as the background texture. Does not modify
+image pixels::
+
+ void backgroundTexture (const std::string &backgroundTexture_ )
+
+ std::string backgroundTexture ( void ) const
+
+baseColumns
++++++++++++
+
+Base image width (before transformations)::
+
+ unsigned int baseColumns ( void ) const
+
+baseFilename
+++++++++++++
+
+Base image filename (before transformations)::
+
+ std::string baseFilename ( void ) const
+
+baseRows
+++++++++
+
+Base image height (before transformations)::
+
+ unsigned int baseRows ( void ) const
+
+borderColor
++++++++++++
+
+Image border `color`_::
+
+ void borderColor ( const Color &color_ )
+
+ Color borderColor ( void ) const
+
+boundingBox
++++++++++++
+
+Return smallest bounding box enclosing non-border pixels. The
+current fuzz value is used when discriminating between pixels.
+This is the crop bounding box used by ``crop(Geometry(0,0))``::
+
+ Geometry boundingBox ( void ) const
+
+boxColor
+++++++++
+
+Base `color`_ that annotation text is rendered on (default none)::
+
+ void boxColor ( const Color &boxColor_ )
+
+ Color boxColor ( void ) const
+
+cacheThreshold
+++++++++++++++
+
+Pixel cache threshold in megabytes. Once this memory threshold is
+exceeded, all subsequent pixels cache operations are to/from disk.
+This setting is shared by all Image objects::
+
+ static void cacheThreshold ( const unsigned int threshold_ )
+
+chromaBluePrimary
++++++++++++++++++
+
+Chromaticity blue primary point (e.g. x=0.15, y=0.06)::
+
+ void chromaBluePrimary ( const double x_, const double y_ )
+
+ void chromaBluePrimary ( double *x_, double *y_ ) const
+
+chromaGreenPrimary
+++++++++++++++++++
+
+Chromaticity green primary point (e.g. x=0.3, y=0.6)::
+
+ void chromaGreenPrimary ( const double x_, const double y_ )
+
+ void chromaGreenPrimary ( double *x_, double *y_ ) const
+
+chromaRedPrimary
+++++++++++++++++
+
+Chromaticity red primary point (e.g. x=0.64, y=0.33)::
+
+ void chromaRedPrimary ( const double x_, const double y_ )
+
+ void chromaRedPrimary ( double *x_, double *y_ ) const
+
+chromaWhitePoint
+++++++++++++++++
+
+Chromaticity white point (e.g. x=0.3127, y=0.329)::
+
+ void chromaWhitePoint ( const double x_, const double y_ )
+ void chromaWhitePoint ( double *x_, double *y_ ) const
+
+classType
++++++++++
+
+Image class (DirectClass or PseudoClass). NOTE: setting a DirectClass
+image to PseudoClass will result in the loss of color information if
+the number of colors in the image is greater than the maximum palette
+size (either 256 or 65536 entries depending on the value of
+QuantumDepth when ImageMagick was built)::
+
+ void classType ( const ClassType class_ )
+
+ ClassType classType ( void ) const
+
+clipMask
+++++++++
+
+Associate a clip mask image with the current image. The clip mask
+image must have the same dimensions as the current image or an
+exception is thrown. Clipping occurs wherever pixels are transparent
+in the clip mask image. Clipping Pass an invalid image to unset an
+existing clip mask::
+
+ void clipMask ( const Image & clipMask_ )
+
+ Image clipMask ( void ) const
+
+colorFuzz
++++++++++
+
+Colors within this distance are considered equal. A number of
+algorithms search for a target color. By default the color must be
+exact. Use this option to match colors that are close to the target
+color in RGB space::
+
+ void colorFuzz ( const double fuzz_ )
+
+ double colorFuzz ( void ) const
+
+colorMap
+++++++++
+
+`Color`_ at colormap position `index`::
+
+ void colorMap ( const unsigned int index_,
+ const Color &color_ )
+
+ Color colorMap ( const unsigned int index_ ) const
+
+colorMapSize
+++++++++++++
+
+Number of entries in the colormap. Setting the colormap size may
+extend or truncate the colormap. The maximum number of supported
+entries is specified by the MaxColormapSize constant, and is dependent
+on the value of QuantumDepth when GraphicsMagick is compiled. An
+exception is thrown if more entries are requested than may be
+supported. Care should be taken when truncating the colormap to ensure
+that the image colormap indexes reference valid colormap entries::
+
+ void colorMapSize ( const unsigned int entries_ )
+
+ unsigned int colorMapSize ( void )
+
+colorSpace
+++++++++++
+
+The colorspace (e.g. CMYK) used to represent the image pixel colors::
+
+ void colorSpace( const ColorspaceType colorSpace_ )
+
+ ColorspaceType colorSpace ( void ) const
+
+columns
++++++++
+
+Image width::
+
+ unsigned int columns ( void ) const
+
+comment
++++++++
+
+Image comment::
+
+ std::string comment ( void ) const
+
+compose
++++++++
+
+Composition operator to be used when composition is implicitly
+used (such as for image flattening)::
+
+ void compose (const CompositeOperator compose_)
+
+ CompositeOperator compose ( void ) const
+
+compressType
+++++++++++++
+
+Image compresion type. The default is the compression type of the
+input image file::
+
+ void compressType ( const CompressionType compressType_ )
+
+ CompressionType compressType ( void ) const
+
+debug
++++++
+
+Enable printing of debug messages from GraphicsMagick as it executes::
+
+ void debug ( const bool flag_ )
+
+ bool debug ( void ) const
+
+defineValue
++++++++++++
+
+Set or obtain a definition string to applied when encoding or decoding
+the specified format. The meanings of the definitions are format
+specific. The format is designated by the `magick` argument, the
+format-specific key is designated by `key`, and the associated value
+is specified by `value`. See the defineSet() method if the key must be
+removed entirely::
+
+ void defineValue ( const std::string &magick_,
+ const std::string &key_,
+ const std::string &value_ )
+
+ std::string defineValue ( const std::string &magick_,
+ const std::string &key_ ) const
+
+defineSet
++++++++++
+
+Set or obtain a definition flag to applied when encoding or decoding
+the specified format. Similar to the defineValue() method except that
+passing the `flag` value 'true' creates a value-less define with that
+format and key. Passing the `flag` value 'false' removes any existing
+matching definition. The method returns 'true' if a matching key
+exists, and 'false' if no matching key exists::
+
+ void defineSet ( const std::string &magick_,
+ const std::string &key_,
+ bool flag_ )
+
+ bool defineSet ( const std::string &magick_,
+ const std::string &key_ ) const
+
+density
++++++++
+
+Vertical and horizontal resolution in pixels of the image. This option
+specifies an image density when decoding a Postscript or Portable
+Document page. Often used with `psPageSize`::
+
+ void density ( const Geometry &geomery_ )
+
+ Geometry density ( void ) const
+
+Please note that the 'density' method suffers from a design problem in
+that the Geometry object only supports integer dimensions, but the
+underlying image resolution is a floating point value. This results
+in rounding off the value. Please see the xResolution() and
+yResolution() methods for a way to set and get the resolution in
+floating point.
+
+The resolution units may be obtained via the resolutionUnits() method.
+
+depth
++++++
+
+Image depth (bits allocated to red/green/blue components). Used to
+specify the bit depth when reading or writing raw images or when the
+output format supports multiple depths. Defaults to the quantum depth
+that GraphicsMagick is compiled with::
+
+ void depth ( const unsigned int depth_ )
+
+ unsigned int depth ( void ) const
+
+directory
++++++++++
+
+Tile names from within an image montage::
+
+ std::string directory ( void ) const
+
+endian
+++++++
+
+Endianness (`LSBEndian` like Intel, `MSBEndian` like SPARC, or
+`NativeEndian` for what this computer uses) for image formats which
+support endian-specific options::
+
+ void endian ( const EndianType endian_ )
+
+ EndianType endian ( void ) const
+
+fileName
+++++++++
+
+Image file name::
+
+ void fileName ( const std::string &fileName_ )
+
+ std::string fileName ( void ) const
+
+fileSize
+++++++++
+
+Number of bytes of the image on disk::
+
+ off_t fileSize ( void ) const
+
+fillColor
++++++++++
+
+`Color`_ to use when filling drawn objects::
+
+ void fillColor ( const Color &fillColor_ )
+
+ Color fillColor ( void ) const
+
+fillPattern
++++++++++++
+
+Pattern to use while filling drawn objects::
+
+ void fillPattern ( const Image &fillPattern_ )
+
+ Image fillPattern ( void ) const
+
+fillRule
+++++++++
+
+Rule to use when filling drawn objects::
+
+ void fillRule ( const FillRule &fillRule_ )
+
+ FillRule fillRule ( void ) const
+
+filterType
+++++++++++
+
+Filter to use when resizing image. The reduction filter employed has a
+sigificant effect on the time required to resize an image and the
+resulting quality. The default filter is Lanczos which has been shown
+to produce high quality results when reducing most images::
+
+ void filterType ( const FilterTypes filterType_ )
+
+ FilterTypes filterType ( void ) const
+
+font
+++++
+
+Text rendering font. If the font is a fully qualified X server font
+name, the font is obtained from an X server. To use a TrueType font,
+precede the TrueType filename with an @. Otherwise, specify a
+Postscript font name (e.g. "helvetica").::
+
+ void font ( const std::string &font_ )
+
+ std::string font ( void ) const
+
+fontPointsize
++++++++++++++
+
+Text rendering font point size::
+
+ void fontPointsize ( const double pointSize_ )
+
+ double fontPointsize ( void ) const
+
+fontTypeMetrics
++++++++++++++++
+
+Obtain font metrics (see `TypeMetric`_) for text string given current
+font, pointsize, and density settings. This information is necessary
+in order to do fancy layout of text::
+
+ void fontTypeMetrics( const std::string &text_,
+ TypeMetric *metrics )
+
+format
+++++++
+
+Long image format description::
+
+ std::string format ( void ) const
+
+formatExpression
+++++++++++++++++
+
+Format a string based on image properties similar to `identify`
+`-format`. For example, the format expression "%wx%h" is converted to
+a string containing image WIDTHxHEIGHT like "640x480"::
+
+ std::string formatExpression( const std::string expression )
+
+Please note that this method is not a const method (may modify the
+Image object and will assure a reference count of one) and it *may*
+throw an exception if there is an internal error.
+
+gamma
++++++
+
+Gamma level of the image. Gamma is a pow() function which converts
+between the linear light representation and the representation for the
+computer display. Most computer images are gamma corrected to 2.2
+(1/0.4545) so that each step results in a visually linear step on a
+computer or video display::
+
+ double gamma ( void ) const
+
+geometry
+++++++++
+
+Preferred size of the image when encoding::
+
+ Geometry geometry ( void ) const
+
+gifDisposeMethod
+++++++++++++++++
+
+GIF disposal method. This option (specific to the GIF file format) is
+used to control how successive frames are rendered (how the preceding
+frame is disposed of) when creating a GIF animation::
+
+ void gifDisposeMethod ( const unsigned int disposeMethod_ )
+
+ unsigned int gifDisposeMethod ( void ) const
+
+iccColorProfile
++++++++++++++++
+
+ICC color profile. Supplied via a `Blob`_ since Magick++/ and
+GraphicsMagick do not currently support formating this data structure
+directly.
+
+If there is not already an ICC color profile, the profile is merely
+attached to the image without transforming the pixels. If there is
+already an ICC color profile (the source profile), the pixels are
+translated according to the source and target profiles, and the
+existing profile is replaced with the target profile.
+
+Also see `renderingIntent`_, which allows specifying the rendering
+intent if the profile is executed.
+
+Specifications for ICC color profiles and their usage are available
+from the International Color Consortium for the format of ICC color
+profiles::
+
+ void iccColorProfile( const Blob &colorProfile_ )
+
+ Blob iccColorProfile( void ) const
+
+interlaceType
++++++++++++++
+
+The type of interlacing scheme (default `NoInterlace` ). This option
+is used to specify the type of interlacing scheme for raw image
+formats such as RGB or YUV. `NoInterlace` means do not interlace,
+`LineInterlace` uses scanline interlacing, and `PlaneInterlace` uses
+plane interlacing. `PartitionInterlace` is like `PlaneInterlace`
+except the different planes are saved to individual files (e.g.
+image.R, image.G, and image.B). Use `LineInterlace` or
+`PlaneInterlace` to create an interlaced GIF or progressive JPEG
+image::
+
+ void interlaceType ( const InterlaceType interlace_ )
+
+ InterlaceType interlaceType ( void ) const
+
+iptcProfile
++++++++++++
+
+IPTC profile. Supplied via a `Blob`_ since Magick++ and GraphicsMagick do
+not currently support formating this data structure
+directly. Specifications are available from the International Press
+Telecommunications Council for IPTC profiles::
+
+ void iptcProfile( const Blob& iptcProfile_ )
+
+ Blob iptcProfile( void ) const
+
+isValid
++++++++
+
+Does object contain valid image? Set to `false` in order to invalidate
+the image. Images constructed via the default constructor are invalid
+images and isValid() will return false::
+
+ void isValid ( const bool isValid_ )
+
+ bool isValid ( void ) const
+
+label
++++++
+
+Image label::
+
+ std::string label ( void ) const
+
+lineWidth
++++++++++
+
+Stroke width for drawing vector objects (default one)
+This method is now deprecated. Please use strokeWidth instead::
+
+ void lineWidth ( const double lineWidth_ )
+
+ double lineWidth ( void ) const
+
+magick
+++++++
+
+File type magick identifier (.e.g "GIF")::
+
+ void magick ( const std::string &magick_ )
+
+ std::string magick ( void ) const
+
+matte
++++++
+
+Image supports transparency (matte channel)::
+
+ void matte ( const bool matteFlag_ )
+
+ bool matte ( void ) const
+
+matteColor
+++++++++++
+
+Image matte (frame) `color`_::
+
+ void matteColor ( const Color &matteColor_ )
+
+ Color matteColor ( void ) const
+
+meanErrorPerPixel
++++++++++++++++++
+
+The mean error per pixel computed when an image is color reduced. This
+parameter is only valid if verbose is set to true and the image has
+just been quantized::
+
+ double meanErrorPerPixel ( void ) const
+
+modulusDepth
+++++++++++++
+
+Image modulus depth (minimum number of bits required to support
+red/green/blue components without loss of accuracy). The pixel modulus
+depth may be decreased by supplying a value which is less than the
+current value, updating the pixels (reducing accuracy) to the new
+depth. The pixel modulus depth can not be increased over the current
+value using this method::
+
+ void modulusDepth ( const unsigned int modulusDepth_ )
+
+ unsigned int modulusDepth ( void ) const
+
+monochrome
+++++++++++
+
+Transform image to black and white while color reducing (quantizing)::
+
+ void monochrome ( const bool monochromeFlag_ )
+
+ bool monochrome ( void ) const
+
+montageGeometry
++++++++++++++++
+
+Tile size and offset within an image montage. Only valid for montage
+images::
+
+ Geometry montageGeometry ( void ) const
+
+normalizedMaxError
+++++++++++++++++++
+
+The normalized max error per pixel computed when an image is color
+reduced. This parameter is only valid if verbose is set to true and
+the image has just been quantized::
+
+ double normalizedMaxError ( void ) const
+
+normalizedMeanError
++++++++++++++++++++
+
+The normalized mean error per pixel computed when an image is color
+reduced. This parameter is only valid if verbose is set to true and
+the image has just been quantized::
+
+ double normalizedMeanError ( void ) const
+
+orientation
++++++++++++
+
+Image orientation. Supported by some file formats such as DPX and
+TIFF. Useful for turning the right way up::
+
+ void orientation ( const OrientationType orientation_ )
+
+ OrientationType orientation ( void ) const
+
+page
+++++
+
+Preferred size and location of an image canvas.
+
+Use this option to specify the dimensions and position of the
+Postscript page in dots per inch or a TEXT page in pixels. This option
+is typically used in concert with density .
+
+Page may also be used to position a GIF image (such as for a scene in
+an animation)::
+
+ void page ( const Geometry &pageSize_ )
+
+ Geometry page ( void ) const
+
+pixelColor
+++++++++++
+
+Get/set pixel `color`_ at location x & y::
+
+ void pixelColor ( const unsigned int x_,
+ const unsigned int y_,
+ const Color &color_ )
+
+ Color pixelColor ( const unsigned int x_,
+ const unsigned int y_ ) const
+
+profile
++++++++
+
+Add or remove a named profile to/from the image. Remove the
+profile by passing an empty `Blob`_ (e.g. Blob()). Valid names are
+"*", "8BIM", "ICM", "IPTC", or a user/format-defined profile name::
+
+ void profile( const std::string name_,
+ const Blob &colorProfile_ )
+
+Retrieve a named profile from the image. Valid names are:
+"8BIM", "8BIMTEXT", "APP1", "APP1JPEG", "ICC", "ICM", & "IPTC"
+or an existing user/format-defined profile name::
+
+ Blob profile( const std::string name_ ) const
+
+quality
++++++++
+
+JPEG/MIFF/PNG compression level (default 75)::
+
+ void quality ( const unsigned int quality_ )
+
+ unsigned int quality ( void ) const
+
+quantizeColors
+++++++++++++++
+
+Maximum number of colors to quantize to::
+
+ void quantizeColors ( const unsigned int colors_ )
+
+ unsigned int quantizeColors ( void ) const
+
+quantizeColorSpace
+++++++++++++++++++
+
+Colorspace to quantize in (default RGB). Empirical evidence suggests
+that distances in color spaces such as YUV or YIQ correspond to
+perceptual color differences more closely than do distances in RGB
+space. These color spaces may give better results when color reducing
+an image::
+
+ void quantizeColorSpace ( const ColorspaceType colorSpace_ )
+
+ ColorspaceType quantizeColorSpace ( void ) const
+
+quantizeDither
+++++++++++++++
+
+Apply Floyd/Steinberg error diffusion to the image. The basic strategy
+of dithering is to trade intensity resolution for spatial resolution
+by averaging the intensities of several neighboring pixels. Images
+which suffer from severe contouring when reducing colors can be
+improved with this option. The quantizeColors or monochrome option
+must be set for this option to take effect::
+
+ void quantizeDither ( const bool ditherFlag_ )
+
+ bool quantizeDither ( void ) const
+
+quantizeTreeDepth
++++++++++++++++++
+
+Depth of the quantization color classification tree. Values of 0 or 1
+allow selection of the optimal tree depth for the color reduction
+algorithm. Values between 2 and 8 may be used to manually adjust the
+tree depth::
+
+ void quantizeTreeDepth ( const unsigned int treeDepth_ )
+
+ unsigned int quantizeTreeDepth ( void ) const
+
+quiet
++++++
+
+Determines if Warning exceptions will be thrown, or suppressed.
+The default is that warnings will be thrown (i.e. false)::
+
+ void quiet ( const bool quiet_ );
+ bool quiet ( void ) const;
+
+
+renderingIntent
++++++++++++++++
+
+The type of rendering intent (used when applying an ICC color
+profile using `iccColorProfile`_)::
+
+ void renderingIntent ( const RenderingIntent renderingIntent_ )
+
+ RenderingIntent renderingIntent ( void ) const
+
+repage
+++++++
+
+Reset the image page canvas and position::
+
+ void repage();
+
+resolutionUnits
++++++++++++++++
+
+Units of image resolution::
+
+ void resolutionUnits ( const ResolutionType resolutionUnits_ )
+
+ ResolutionType resolutionUnits ( void ) const
+
+rows
+++++
+
+The number of pixel rows in the image::
+
+ unsigned int rows ( void ) const
+
+scene
++++++
+
+Image scene number::
+
+ void scene ( const unsigned int scene_ )
+
+ unsigned int scene ( void ) const
+
+signature
++++++++++
+
+Image textual signature. Set `force` to true in order to re-calculate
+the signature regardless of whether the image data has been modified::
+
+ std::string signature ( const bool force_ = false ) const
+
+size
+++++
+
+Width and height of a raw image (an image which does not support width
+and height information). Size may also be used to affect the image
+size read from a multi-resolution format (e.g. Photo CD, JBIG, or
+JPEG::
+
+ void size ( const Geometry &geometry_ )
+
+ Geometry size ( void ) const
+
+statistics
+++++++++++
+
+Obtain image statistics. Statistics are normalized to the range
+of 0.0 to 1.0 and are output to the specified ImageStatistics
+structure::
+
+ void statistics ( ImageStatistics *statistics ) const
+
+strokeAntiAlias
++++++++++++++++
+
+Enable/disable stroke anti-aliasing::
+
+ void strokeAntiAlias( const bool flag_ )
+
+ bool strokeAntiAlias( void ) const
+
+strokeColor
++++++++++++
+
+`Color`_ to use when drawing object outlines::
+
+ void strokeColor ( const Color &strokeColor_ )
+
+ Color strokeColor ( void ) const
+
+strokeDashArray
++++++++++++++++
+
+Specify the pattern of dashes and gaps used to stroke paths. The
+strokeDashArray represents a zero-terminated array of numbers that
+specify the lengths of alternating dashes and gaps in pixels. If an
+odd number of values is provided, then the list of values is repeated
+to yield an even number of values. A typical `strokeDashArray` array
+might contain the members 5 3 2 0, where the zero value indicates the
+end of the pattern array::
+
+ void strokeDashArray ( const double* strokeDashArray_ )
+
+ const double* strokeDashArray ( void ) const
+
+strokeDashOffset
+++++++++++++++++
+
+While drawing using a dash pattern, specify distance into the
+dash pattern to start the dash (default 0)::
+
+ void strokeDashOffset ( const double strokeDashOffset_ )
+
+ double strokeDashOffset ( void ) const
+
+strokeLineCap
++++++++++++++
+
+Specify the shape to be used at the end of open subpaths when
+they are stroked. Values of LineCap are UndefinedCap, ButtCap,
+RoundCap, and SquareCap::
+
+ void strokeLineCap ( const LineCap lineCap_ )
+
+ LineCap strokeLineCap ( void ) const
+
+strokeLineJoin
+++++++++++++++
+
+Specify the shape to be used at the corners of paths (or other
+vector shapes) when they are stroked. Values of LineJoin are
+UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin::
+
+ void strokeLineJoin ( const LineJoin lineJoin_ )
+
+ LineJoin strokeLineJoin ( void ) const
+
+strokeMiterLimit
+++++++++++++++++
+
+Specify miter limit. When two line segments meet at a sharp
+angle and miter joins have been specified for 'lineJoin', it is
+possible for the miter to extend far beyond the thickness of
+the line stroking the path. The miterLimit' imposes a limit on
+the ratio of the miter length to the 'lineWidth'. The default
+value of this parameter is 4::
+
+ void strokeMiterLimit ( const unsigned int miterLimit_ )
+
+ unsigned int strokeMiterLimit ( void ) const
+
+strokePattern
++++++++++++++
+
+Pattern image to use while stroking object outlines::
+
+ void strokePattern ( const Image &strokePattern_ )
+
+ Image strokePattern ( void ) const
+
+strokeWidth
++++++++++++
+
+Stroke width for drawing vector objects (default one)::
+
+ void strokeWidth ( const double strokeWidth_ )
+
+ double strokeWidth ( void ) const
+
+subImage
+++++++++
+
+Subimage of an image sequence::
+
+ void subImage ( const unsigned int subImage_ )
+
+ unsigned int subImage ( void ) const
+
+subRange
+++++++++
+
+Number of images relative to the base image::
+
+ void subRange ( const unsigned int subRange_ )
+
+ unsigned int subRange ( void ) const
+
+textEncoding
+++++++++++++
+
+Annotation text encoding (e.g. "UTF-16")::
+
+ void textEncoding ( const std::string &encoding_ )
+
+ std::string textEncoding ( void ) const
+
+tileName
+++++++++
+
+Tile name::
+
+ void tileName ( const std::string &tileName_ )
+
+ std::string tileName ( void ) const
+
+totalColors
++++++++++++
+
+Number of colors in the image::
+
+ unsigned long totalColors ( void )
+
+transformOrigin
++++++++++++++++
+
+Origin of coordinate system to use when annotating with text or drawing::
+
+ void transformOrigin ( const double x_,const double y_ )
+
+transformRotation
++++++++++++++++++
+
+Rotation to use when annotating with text or drawing::
+
+ void transformRotation ( const double angle_ )
+
+transformReset
+++++++++++++++
+
+Reset transformation parameters to default::
+
+ void transformReset ( void )
+
+transformScale
+++++++++++++++
+
+Scale to use when annotating with text or drawing::
+
+ void transformScale ( const double sx_, const double sy_ )
+
+transformSkewX
+++++++++++++++
+
+Skew to use in X axis when annotating with text or drawing::
+
+ void transformSkewX ( const double skewx_ )
+
+transformSkewY
+++++++++++++++
+
+Skew to use in Y axis when annotating with text or drawing::
+
+ void transformSkewY ( const double skewy_ )
+
+verbose
++++++++
+
+Print detailed information about the image::
+
+ void verbose ( const bool verboseFlag_ )
+
+ bool verbose ( void ) const
+
+view
+++++
+
+FlashPix viewing parameters::
+
+ void view ( const std::string &view_ )
+
+ std::string view ( void ) const
+
+x11Display
+++++++++++
+
+X11 display to display to, obtain fonts from, or to capture
+image from::
+
+ void x11Display ( const std::string &display_ )
+
+ std::string x11Display ( void ) const
+
+xResolution
++++++++++++
+
+x resolution of the image::
+
+ void xResolution ( const double x_resolution )
+ double xResolution ( void ) const
+
+yResolution
++++++++++++
+
+y resolution of the image::
+
+ void yResolution ( const double y_resolution )
+ double yResolution ( void ) const
+
+
+Low-Level Image Pixel Access
+----------------------------
+
+Image pixels (of type `PixelPacket`_ ) may be accessed directly via
+the Image Pixel Cache . The image pixel cache is a rectangular window
+into the actual image pixels (which may be in memory, memory-mapped
+from a disk file, or entirely on disk). Two interfaces exist to access
+the Image Pixel Cache. The interface described here (part of the Image
+class) supports only one view at a time. See the `Pixels`_ class for a
+more abstract interface which supports simultaneous pixel views (up to
+the number of rows). As an analogy, the interface described here
+relates to the `Pixels`_ class as stdio's gets() relates to
+fgets(). The `Pixels`_ class provides the more general form of the
+interface.
+
+Obtain existing image pixels via getPixels(). Create a new pixel
+region using setPixels().
+
+In order to ensure that only the current generation of the image is
+modified, the Image's modifyImage() method should be invoked to reduce
+the reference count on the underlying image to one. If this is not
+done, then it is possible for a previous generation of the image to be
+modified due to the use of reference counting when copying or
+constructing an Image.
+
+Depending on the capabilities of the operating system, and the
+relationship of the window to the image, the pixel cache may be a copy
+of the pixels in the selected window, or it may be the actual image
+pixels. In any case calling syncPixels() insures that the base image
+is updated with the contents of the modified pixel cache. The method
+readPixels() supports copying foreign pixel data formats into the
+pixel cache according to the QuantumTypes. The method writePixels()
+supports copying the pixels in the cache to a foreign pixel
+representation according to the format specified by QuantumTypes.
+
+The pixel region is effectively a small image in which the pixels may
+be accessed, addressed, and updated, as shown in the following
+example:
+
+.. |pixel_cache| image:: Cache.png
+
+|pixel_cache|
+
+::
+
+ // Construct image based on an existing file
+ Image image("cow.png");
+
+ // Ensure that there are no other references to this image.
+ image.modifyImage();
+
+ // Set the image type to TrueColor DirectClass representation.
+ image.type(TrueColorType);
+
+ // Request pixel region with size 60x40, and top origin at 20x30
+ int columns = 60;
+ PixelPacket *pixel_cache = image.getPixels(20,30,columns,40);
+
+ // Set pixel at column 5, and row 10 in the pixel cache to red.
+ int column = 5;
+ int row = 10;
+ PixelPacket *pixel = pixel_cache+row*columns+column;
+ *pixel = Color("red");
+
+ // Save changes to underlying image .
+ image.syncPixels();
+
+ // Save updated image to file.
+ image.write("horse.png");
+
+The image cache supports the following methods:
+
+.. contents::
+ :local:
+
+getConstPixels
+++++++++++++++
+
+Transfers read-only pixels from the image to the pixel cache as
+defined by the specified region::
+
+ const PixelPacket* getConstPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ ) const
+
+getIndexes
+++++++++++
+
+Obtain mutable image pixel indexes (valid for PseudoClass images)::
+
+ IndexPacket* getIndexes ( void )
+
+getConstIndexes
++++++++++++++++
+
+Obtain immutable image pixel indexes (valid for PseudoClass images)::
+
+ const IndexPacket* getConstIndexes ( void ) const
+
+getPixels
++++++++++
+
+Transfers pixels from the image to the pixel cache as defined by the
+specified region. Modified pixels may be subsequently transferred back
+to the image via syncPixels. This method is valid for DirectClass
+images::
+
+ PixelPacket* getPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+
+setPixels
++++++++++
+
+Allocates a pixel cache region to store image pixels as defined by the
+region rectangle. This area is subsequently transferred from the
+pixel cache to the image via syncPixels::
+
+ PixelPacket* setPixels ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ )
+
+syncPixels
+++++++++++
+
+Transfers the image cache pixels to the image::
+
+ void syncPixels ( void )
+
+readPixels
+++++++++++
+
+Transfers one or more pixel components from a buffer or file into the
+image pixel cache of an image. Used to support image decoders::
+
+ void readPixels ( const QuantumType quantum_,
+ const unsigned char *source_ )
+
+writePixels
++++++++++++
+
+Transfers one or more pixel components from the image pixel cache to a
+buffer or file. Used to support image encoders::
+
+ void writePixels ( const QuantumType quantum_,
+ unsigned char *destination_ )
+
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| `Bob Friesenhahn`_ 1999 - 2017
+
diff --git a/www/Magick++/ImageDesign.html b/www/Magick++/ImageDesign.html
new file mode 100644
index 0000000..47eed0a
--- /dev/null
+++ b/www/Magick++/ImageDesign.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Image Data Structures</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-image-data-structures">
+<h1 class="title">Magick::Image Data Structures</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The class Magick::Image is a simple handle which points to a
+reference-counted image representation. This allows multiple
+Magick::Image instances to share the same image and attributes. At the
+point in time that the image data, or image attributes are modified
+and the current reference count is greater than one, the image data
+and attributes are copied to create a new image with a reference count
+of one and the reference count on the old image is decremented. If the
+reference count on the old image becomes zero, then the associated
+reference and data are deleted. This strategy represents a simple (but
+effective) form of garbage collection.</p>
+<img alt="Figure showing Image class design" src="Image.png" style="width: 910px; height: 490px;" />
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/ImageDesign.rst b/www/Magick++/ImageDesign.rst
new file mode 100644
index 0000000..b7bfdb2
--- /dev/null
+++ b/www/Magick++/ImageDesign.rst
@@ -0,0 +1,28 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=============================
+Magick::Image Data Structures
+=============================
+
+The class Magick::Image is a simple handle which points to a
+reference-counted image representation. This allows multiple
+Magick::Image instances to share the same image and attributes. At the
+point in time that the image data, or image attributes are modified
+and the current reference count is greater than one, the image data
+and attributes are copied to create a new image with a reference count
+of one and the reference count on the old image is decremented. If the
+reference count on the old image becomes zero, then the associated
+reference and data are deleted. This strategy represents a simple (but
+effective) form of garbage collection.
+
+.. image:: Image.png
+ :width: 910
+ :height: 490
+ :alt: Figure showing Image class design
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/Montage.html b/www/Magick++/Montage.html
new file mode 100644
index 0000000..308e6a4
--- /dev/null
+++ b/www/Magick++/Montage.html
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Montage Class</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-montage-class">
+<h1 class="title">Magick::Montage Class</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>A montage is a single image which is composed of thumbnail images
+composed in a uniform grid. The size of the montage image is
+determined by the size of the individual thumbnails and the number of
+rows and columns in the grid.</p>
+<p>The following illustration shows a montage consisting of three columns
+and two rows of thumbnails rendered on a gray background:</p>
+<img alt="Figure showing framed montage" class="align-center" src="montage-sample-framed.jpg" style="width: 378.0px; height: 238.0px;" />
+<p>Montages may be either &quot;plain&quot; (undecorated thumbnails) or &quot;framed&quot;
+(decorated thumbnails). In order to more easily understand the options
+supplied to MontageImages(), montage options are supplied by two
+different classes: Magick::Montage and Magick::MontageFramed.</p>
+<div class="section" id="plain-montages">
+<h1>Plain Montages</h1>
+<p>Magick::Montage is the base class to provide montage options and
+provides methods to set all options required to render simple
+(unframed) montages. See Magick::MontageFramedif you would like to
+create a framed montage.</p>
+<p>Unframed thumbnails consist of four components: the thumbnail image,
+the thumbnail border, an optional thumbnail shadow, and an optional
+thumbnail label area.</p>
+<img alt="Figure showing plain montage" class="align-center" src="thumbnail-anatomy-plain.jpg" style="width: 309.0px; height: 327.0px;" />
+<p>The following is the definition of the Magick::Montage class:</p>
+<pre class="literal-block">
+class Montage
+{
+public:
+ Montage( void );
+ virtual ~Montage( void );
+
+ // Specifies the background color that thumbnails are imaged upon.
+ void backgroundColor ( const Color &amp;backgroundColor_ );
+ Color backgroundColor ( void ) const;
+
+ // Specifies the image composition algorithm for thumbnails. This
+ // controls the algorithm by which the thumbnail image is placed
+ // on the background. Use of OverCompositeOp is recommended for
+ // use with images that have transparency. This option may have
+ // negative side-effects for images without transparency.
+ void compose ( CompositeOperator compose_ );
+ CompositeOperator compose ( void ) const;
+
+ // Specifies the image filename to be used for the generated
+ // montage images. To handle the case were multiple montage images
+ // are generated, a printf-style format may be embedded within the
+ // filename. For example, a filename specification of
+ // image%02d.miff names the montage images as image00.miff,
+ // image01.miff, etc.
+ void fileName( const std::string &amp;fileName_ );
+ std::string fileName( void ) const;
+
+ // Specifies the fill color to use for the label text.
+ void fillColor ( const Color &amp;fill_ );
+ Color fillColor ( void ) const;
+
+ // Specifies the thumbnail label font.
+ void font ( const std::string &amp;font_ );
+ std::string font ( void ) const;
+
+ // Specifies the size of the generated thumbnail.
+ void geometry ( const Geometry &amp;geometry_ );
+ Geometry geometry ( void ) const;
+
+ // Specifies the thumbnail positioning within the specified
+ // geometry area. If the thumbnail is smaller in any dimension
+ // than the geometry, then it is placed according to this
+ // specification
+ void gravity ( GravityType gravity_ );
+ GravityType gravity ( void ) const;
+
+ // Specifies the format used for the image label. Special format
+ // characters may be embedded in the format string to include
+ // information about the image.
+ void label( const std::string &amp;label_ );
+ std::string label( void ) const;
+
+ // Specifies the pen color to use for the label text (same as fill).
+ void penColor ( const Color &amp;pen_ );
+ Color penColor ( void ) const;
+
+ // Specifies the thumbnail label font size.
+ void pointSize ( unsigned int pointSize_ );
+ unsigned int pointSize ( void ) const;
+
+ // Enable/disable drop-shadow on thumbnails.
+ void shadow ( bool shadow_ );
+ bool shadow ( void ) const;
+
+ // Specifies the stroke color to use for the label text .
+ void strokeColor ( const Color &amp;stroke_ );
+ Color strokeColor ( void ) const;
+
+ // Specifies a texture image to use as montage background. The
+ // built-in textures &quot;granite:&quot; and &quot;plasma:&quot; are available. A
+ // texture is the same as a background image.
+ void texture ( const std::string &amp;texture_ );
+ std::string texture ( void ) const;
+
+ // Specifies the maximum number of montage columns and rows in the
+ // montage. The montage is built by filling out all cells in a row
+ // before advancing to the next row. Once the montage has reached
+ // the maximum number of columns and rows, a new montage image is
+ // started.
+ void tile ( const Geometry &amp;tile_ );
+ Geometry tile ( void ) const;
+
+ // Specifies the montage title
+ void title ( const std::string &amp;title_ );
+ std::string title ( void ) const;
+
+ // Specifies a montage color to set transparent. This option can
+ // be set the same as the background color in order for the
+ // thumbnails to appear without a background when rendered on an
+ // HTML page. For best effect, ensure that the transparent color
+ // selected does not occur in the rendered thumbnail colors.
+ void transparentColor ( const Color &amp;transparentColor_ );
+ Color transparentColor ( void ) const;
+
+};
+</pre>
+</div>
+<div class="section" id="framed-montages">
+<h1>Framed Montages</h1>
+<p>Magick::MontageFramed provides the means to specify montage options
+when it is desired to have decorative frames around the image
+thumbnails. MontageFramed inherits from Montage and therefore provides
+all the methods of Montage as well as those shown in the table
+&quot;MontageFramed Methods&quot;.</p>
+<p>Framed thumbnails consist of four components: the thumbnail image, the
+thumbnail frame, the thumbnail border, an optional thumbnail shadow,
+and an optional thumbnail label area.</p>
+<img alt="Figure showing anatomy of a framed montage" class="align-center" src="thumbnail-anatomy-framed.jpg" style="width: 350.0px; height: 345.0px;" />
+<p>The following is the definition of the Magick::MontageFramed class:</p>
+<pre class="literal-block">
+class MontageFramed : public Montage
+{
+public:
+ MontageFramed ( void );
+ /* virtual */ ~MontageFramed ( void );
+
+ // Specifies the background color within the thumbnail frame.
+ void borderColor ( const Color &amp;borderColor_ );
+ Color borderColor ( void ) const;
+
+ // Specifies the border (in pixels) to place between a thumbnail
+ // and its surrounding frame. This option only takes effect if
+ // thumbnail frames are enabled (via frameGeometry) and the
+ // thumbnail geometry specification doesn't also specify the
+ // thumbnail border width.
+ void borderWidth ( unsigned int borderWidth_ );
+ unsigned int borderWidth ( void ) const;
+
+ // Specifies the geometry specification for frame to place around
+ // thumbnail. If this parameter is not specified, then the montage
+ // is unframed.
+ void frameGeometry ( const Geometry &amp;frame_ );
+ Geometry frameGeometry ( void ) const;
+
+ // Specifies the thumbnail frame color.
+ void matteColor ( const Color &amp;matteColor_ );
+ Color matteColor ( void ) const;
+
+};
+</pre>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Montage.rst b/www/Magick++/Montage.rst
new file mode 100644
index 0000000..dc5ed5c
--- /dev/null
+++ b/www/Magick++/Montage.rst
@@ -0,0 +1,201 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=====================
+Magick::Montage Class
+=====================
+
+A montage is a single image which is composed of thumbnail images
+composed in a uniform grid. The size of the montage image is
+determined by the size of the individual thumbnails and the number of
+rows and columns in the grid.
+
+The following illustration shows a montage consisting of three columns
+and two rows of thumbnails rendered on a gray background:
+
+.. image:: montage-sample-framed.jpg
+ :width: 378px
+ :height: 238px
+ :scale: 100%
+ :align: center
+ :alt: Figure showing framed montage
+
+Montages may be either "plain" (undecorated thumbnails) or "framed"
+(decorated thumbnails). In order to more easily understand the options
+supplied to MontageImages(), montage options are supplied by two
+different classes: Magick::Montage and Magick::MontageFramed.
+
+Plain Montages
+--------------
+
+Magick::Montage is the base class to provide montage options and
+provides methods to set all options required to render simple
+(unframed) montages. See Magick::MontageFramedif you would like to
+create a framed montage.
+
+Unframed thumbnails consist of four components: the thumbnail image,
+the thumbnail border, an optional thumbnail shadow, and an optional
+thumbnail label area.
+
+.. image:: thumbnail-anatomy-plain.jpg
+ :width: 309px
+ :height: 327px
+ :scale: 100%
+ :align: center
+ :alt: Figure showing plain montage
+
+The following is the definition of the Magick::Montage class::
+
+ class Montage
+ {
+ public:
+ Montage( void );
+ virtual ~Montage( void );
+
+ // Specifies the background color that thumbnails are imaged upon.
+ void backgroundColor ( const Color &backgroundColor_ );
+ Color backgroundColor ( void ) const;
+
+ // Specifies the image composition algorithm for thumbnails. This
+ // controls the algorithm by which the thumbnail image is placed
+ // on the background. Use of OverCompositeOp is recommended for
+ // use with images that have transparency. This option may have
+ // negative side-effects for images without transparency.
+ void compose ( CompositeOperator compose_ );
+ CompositeOperator compose ( void ) const;
+
+ // Specifies the image filename to be used for the generated
+ // montage images. To handle the case were multiple montage images
+ // are generated, a printf-style format may be embedded within the
+ // filename. For example, a filename specification of
+ // image%02d.miff names the montage images as image00.miff,
+ // image01.miff, etc.
+ void fileName( const std::string &fileName_ );
+ std::string fileName( void ) const;
+
+ // Specifies the fill color to use for the label text.
+ void fillColor ( const Color &fill_ );
+ Color fillColor ( void ) const;
+
+ // Specifies the thumbnail label font.
+ void font ( const std::string &font_ );
+ std::string font ( void ) const;
+
+ // Specifies the size of the generated thumbnail.
+ void geometry ( const Geometry &geometry_ );
+ Geometry geometry ( void ) const;
+
+ // Specifies the thumbnail positioning within the specified
+ // geometry area. If the thumbnail is smaller in any dimension
+ // than the geometry, then it is placed according to this
+ // specification
+ void gravity ( GravityType gravity_ );
+ GravityType gravity ( void ) const;
+
+ // Specifies the format used for the image label. Special format
+ // characters may be embedded in the format string to include
+ // information about the image.
+ void label( const std::string &label_ );
+ std::string label( void ) const;
+
+ // Specifies the pen color to use for the label text (same as fill).
+ void penColor ( const Color &pen_ );
+ Color penColor ( void ) const;
+
+ // Specifies the thumbnail label font size.
+ void pointSize ( unsigned int pointSize_ );
+ unsigned int pointSize ( void ) const;
+
+ // Enable/disable drop-shadow on thumbnails.
+ void shadow ( bool shadow_ );
+ bool shadow ( void ) const;
+
+ // Specifies the stroke color to use for the label text .
+ void strokeColor ( const Color &stroke_ );
+ Color strokeColor ( void ) const;
+
+ // Specifies a texture image to use as montage background. The
+ // built-in textures "granite:" and "plasma:" are available. A
+ // texture is the same as a background image.
+ void texture ( const std::string &texture_ );
+ std::string texture ( void ) const;
+
+ // Specifies the maximum number of montage columns and rows in the
+ // montage. The montage is built by filling out all cells in a row
+ // before advancing to the next row. Once the montage has reached
+ // the maximum number of columns and rows, a new montage image is
+ // started.
+ void tile ( const Geometry &tile_ );
+ Geometry tile ( void ) const;
+
+ // Specifies the montage title
+ void title ( const std::string &title_ );
+ std::string title ( void ) const;
+
+ // Specifies a montage color to set transparent. This option can
+ // be set the same as the background color in order for the
+ // thumbnails to appear without a background when rendered on an
+ // HTML page. For best effect, ensure that the transparent color
+ // selected does not occur in the rendered thumbnail colors.
+ void transparentColor ( const Color &transparentColor_ );
+ Color transparentColor ( void ) const;
+
+ };
+
+Framed Montages
+---------------
+
+Magick::MontageFramed provides the means to specify montage options
+when it is desired to have decorative frames around the image
+thumbnails. MontageFramed inherits from Montage and therefore provides
+all the methods of Montage as well as those shown in the table
+"MontageFramed Methods".
+
+Framed thumbnails consist of four components: the thumbnail image, the
+thumbnail frame, the thumbnail border, an optional thumbnail shadow,
+and an optional thumbnail label area.
+
+.. image:: thumbnail-anatomy-framed.jpg
+ :width: 350px
+ :height: 345px
+ :scale: 100%
+ :align: center
+ :alt: Figure showing anatomy of a framed montage
+
+The following is the definition of the Magick::MontageFramed class::
+
+ class MontageFramed : public Montage
+ {
+ public:
+ MontageFramed ( void );
+ /* virtual */ ~MontageFramed ( void );
+
+ // Specifies the background color within the thumbnail frame.
+ void borderColor ( const Color &borderColor_ );
+ Color borderColor ( void ) const;
+
+ // Specifies the border (in pixels) to place between a thumbnail
+ // and its surrounding frame. This option only takes effect if
+ // thumbnail frames are enabled (via frameGeometry) and the
+ // thumbnail geometry specification doesn't also specify the
+ // thumbnail border width.
+ void borderWidth ( unsigned int borderWidth_ );
+ unsigned int borderWidth ( void ) const;
+
+ // Specifies the geometry specification for frame to place around
+ // thumbnail. If this parameter is not specified, then the montage
+ // is unframed.
+ void frameGeometry ( const Geometry &frame_ );
+ Geometry frameGeometry ( void ) const;
+
+ // Specifies the thumbnail frame color.
+ void matteColor ( const Color &matteColor_ );
+ Color matteColor ( void ) const;
+
+ };
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/PixelPacket.html b/www/Magick++/PixelPacket.html
new file mode 100644
index 0000000..dca9cf7
--- /dev/null
+++ b/www/Magick++/PixelPacket.html
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::PixelPacket Structure</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-pixelpacket-structure">
+<h1 class="title">Magick::PixelPacket Structure</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The PixelPacket structure is used to represent DirectClass pixels in
+GraphicsMagick. GraphicsMagick may be compiled to support 32, 64, or
+even 128 bit pixels. The size of PixelPacket is controlled by the
+value of the QuantumDepth define. The default build depth is 32 bit
+pixels, which provides minumum (&quot;web standard&quot;) accuracy, least memory
+consumption, and best performance. If deeper images need to be
+supported or more mathematical accuracy is desired, then
+GraphicsMagick may be compiled with QuantumDepth=16 or
+QuantumDepth=32.</p>
+<p>The following table shows the relationship between QuantumDepth, the
+type of Quantum, and the overall PixelPacket size:</p>
+<table border="1" class="docutils">
+<caption>Effect Of QuantumDepth Values</caption>
+<colgroup>
+<col width="28%" />
+<col width="35%" />
+<col width="37%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">QuantumDepth</th>
+<th class="head">Quantum Type</th>
+<th class="head">PixelPacket Size</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>8</td>
+<td>unsigned char</td>
+<td>32 bits</td>
+</tr>
+<tr><td>16</td>
+<td>unsigned short</td>
+<td>64 bits</td>
+</tr>
+<tr><td>32</td>
+<td>unsigned int</td>
+<td>128 bits</td>
+</tr>
+</tbody>
+</table>
+<p>The members of the PixelPacket structure, and their interpretation,
+are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>PixelPacket Structure Members</caption>
+<colgroup>
+<col width="10%" />
+<col width="10%" />
+<col width="19%" />
+<col width="31%" />
+<col width="28%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Member</th>
+<th class="head">Type</th>
+<th class="head" colspan="3">Interpretation</th>
+</tr>
+<tr><th class="head"></th>
+<th class="head">&nbsp;</th>
+<th class="head">RGBColorspace</th>
+<th class="head">RGBColorspace + matte</th>
+<th class="head">CMYKColorspace</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>red</td>
+<td>Quantum</td>
+<td>Red</td>
+<td>Red</td>
+<td>Cyan</td>
+</tr>
+<tr><td>green</td>
+<td>Quantum</td>
+<td>Green</td>
+<td>Green</td>
+<td>Magenta</td>
+</tr>
+<tr><td>blue</td>
+<td>Quantum</td>
+<td>Blue</td>
+<td>Blue</td>
+<td>Yellow</td>
+</tr>
+<tr><td>opacity</td>
+<td>Quantum</td>
+<td>Ignored</td>
+<td>Opacity</td>
+<td>Black</td>
+</tr>
+</tbody>
+</table>
+<p>Note that opacity is stored inverted from most other software
+(i.e. maximum value is completely transparent and minum value is
+totally opaque).</p>
+<p>Note that for CMYKColorspace + matte (CMYKA), the opacity is stored in
+the assocated IndexPacket.</p>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/PixelPacket.rst b/www/Magick++/PixelPacket.rst
new file mode 100644
index 0000000..94f2b5f
--- /dev/null
+++ b/www/Magick++/PixelPacket.rst
@@ -0,0 +1,57 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=============================
+Magick::PixelPacket Structure
+=============================
+
+The PixelPacket structure is used to represent DirectClass pixels in
+GraphicsMagick. GraphicsMagick may be compiled to support 32, 64, or
+even 128 bit pixels. The size of PixelPacket is controlled by the
+value of the QuantumDepth define. The default build depth is 32 bit
+pixels, which provides minumum ("web standard") accuracy, least memory
+consumption, and best performance. If deeper images need to be
+supported or more mathematical accuracy is desired, then
+GraphicsMagick may be compiled with QuantumDepth=16 or
+QuantumDepth=32.
+
+The following table shows the relationship between QuantumDepth, the
+type of Quantum, and the overall PixelPacket size:
+
+.. table:: Effect Of QuantumDepth Values
+
+ ============ =============== ================
+ QuantumDepth Quantum Type PixelPacket Size
+ ============ =============== ================
+ 8 unsigned char 32 bits
+ 16 unsigned short 64 bits
+ 32 unsigned int 128 bits
+ ============ =============== ================
+
+The members of the PixelPacket structure, and their interpretation,
+are shown in the following table:
+
+.. table:: PixelPacket Structure Members
+
+ ======= ======= ============= ===================== ===================
+ Member Type Interpretation
+ ------- ------- ---------------------------------------------------------
+ \ RGBColorspace RGBColorspace + matte CMYKColorspace
+ ======= ======= ============= ===================== ===================
+ red Quantum Red Red Cyan
+ green Quantum Green Green Magenta
+ blue Quantum Blue Blue Yellow
+ opacity Quantum Ignored Opacity Black
+ ======= ======= ============= ===================== ===================
+
+Note that opacity is stored inverted from most other software
+(i.e. maximum value is completely transparent and minum value is
+totally opaque).
+
+Note that for CMYKColorspace + matte (CMYKA), the opacity is stored in
+the assocated IndexPacket.
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
diff --git a/www/Magick++/Pixels.html b/www/Magick++/Pixels.html
new file mode 100644
index 0000000..23b858c
--- /dev/null
+++ b/www/Magick++/Pixels.html
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::Pixels</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-pixels">
+<h1 class="title">Magick::Pixels</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The Pixels class provides efficient access to raw image pixels. Image
+pixels (of type <a class="reference external" href="PixelPacket.html">PixelPacket</a>) may be accessed
+directly via the Image Pixel Cache. The image pixel cache is a
+rectangular window (a view) into the actual image pixels (which may be
+in memory, memory-mapped from a disk file, or entirely on
+disk). Obtain existing image pixels via get(). Create a new pixel
+region using set().</p>
+<p>Depending on the capabilities of the operating system, and the
+relationship of the window to the image, the pixel cache may be a copy
+of the pixels in the selected window, or it may be the actual image
+pixels. In any case calling sync() insures that the base image is
+updated with the contents of the modified pixel cache. The method
+decode()supports copying foreign pixel data formats into the pixel
+cache according to the QuantumTypes. The method encode() supports
+copying the pixels in the cache to a foreign pixel representation
+according to the format specified by QuantumTypes.</p>
+<p>Setting a view using the Pixels class does not cause the number of
+references to the underlying image to be reduced to one. Therefore, in
+order to ensure that only the current generation of the image is
+modified, the Image's modifyImage() method should be invoked to reduce
+the reference count on the underlying image to one. If this is not
+done, then it is possible for a previous generation of the image to be
+modified due to the use of reference counting when copying or
+constructing an Image.</p>
+<p>The PixelPacket* returned by the set and get methods, and the
+IndexPacket* returned by the indexes method point to pixel data
+managed by the Pixels class. The Pixels class is responsible for
+releasing resources associated with the pixel view. This means that
+the pointer should never be passed to delete() or free().</p>
+<img alt="Figure showing pixel cache access" class="align-center" src="Cache.png" style="width: 254.0px; height: 218.0px;" />
+<!-- Probably want bottom alignment for above (but not accepted by -->
+<!-- currently installed rst2html.py parser) -->
+<p>The pixel view is a small image in which the pixels may be accessed,
+addressed, and updated, as shown in the following example, which
+produces an image similar to the one on the right (minus lines and
+text):</p>
+<pre class="literal-block">
+// Create base image
+Image image(Geometry(254,218), &quot;white&quot;);
+
+// Set the image type to TrueColor DirectClass representation.
+image.type(TrueColorType);
+
+// Ensure that there is only one reference to underlying image
+// If this is not done, then image pixels will not be modified.
+image.modifyImage();
+
+// Allocate pixel view
+Pixels view(image);
+
+// Set all pixels in region anchored at 38x36, with size 160x230 to green.
+unsigned int columns = 196; unsigned int rows = 162;
+Color green(&quot;green&quot;);
+PixelPacket *pixels = view.get(38,36,columns,rows);
+for ( int row = 0; row &lt; rows ; ++row )
+for ( int column = 0; column &lt; columns ; ++column )
+*pixels++=green;
+
+// Save changes to image.
+view.sync();
+
+// Set all pixels in region anchored at 86x72, with size 108x67 to yellow.
+columns = 108; rows = 67;
+Color yellow(&quot;yellow&quot;);
+pixels = view.get(86,72,columns,rows);
+for ( int row = 0; row &lt; rows ; ++row )
+for ( int column = 0; column &lt; columns ; ++column )
+*pixels++=yellow;
+view.sync();
+
+// Set pixel at position 108,94 to red
+*(view.get(108,94,1,1)) = Color(&quot;red&quot;);
+
+// Save changes to image.
+view.sync();
+</pre>
+<p>The following is the definition of the Magick::Pixels class:</p>
+<pre class="literal-block">
+class Pixels
+{
+public:
+
+ // Construct pixel view using specified image.
+ Pixels( Magick::Image &amp;image_ );
+
+ // Destroy pixel view
+ ~Pixels( void );
+
+ // Transfer pixels from the image to the pixel view as defined by
+ // the specified region. Modified pixels may be subsequently
+ // transferred back to the image via sync.
+ PixelPacket* get ( const int x_, const int y_,
+ const unsigned int columns_,const unsigned int rows_ );
+
+ // Transfer read-only pixels from the image to the pixel view as
+ // defined by the specified region.
+ const PixelPacket* getConst ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ );
+
+ // Transfers the image view pixels to the image.
+ void sync ( void );
+
+ // Allocate a pixel view region to store image pixels as defined
+ // by the region rectangle. This area is subsequently transferred
+ // from the pixel view to the image via sync.
+ PixelPacket* set ( const int x_, const int y_,
+ const unsigned int columns_, const unsigned int rows_ );
+
+ // Return pixel colormap index array
+ IndexPacket* indexes ( void );
+
+ // Left ordinate of view
+ int x ( void ) const;
+
+ // Top ordinate of view
+ int y ( void ) const;
+
+ // Width of view
+ unsigned int columns ( void ) const;
+
+ // Height of view
+ unsigned int rows ( void ) const;
+
+};
+</pre>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/Pixels.rst b/www/Magick++/Pixels.rst
new file mode 100644
index 0000000..44dec5c
--- /dev/null
+++ b/www/Magick++/Pixels.rst
@@ -0,0 +1,149 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+==============
+Magick::Pixels
+==============
+
+The Pixels class provides efficient access to raw image pixels. Image
+pixels (of type `PixelPacket <PixelPacket.html>`_) may be accessed
+directly via the Image Pixel Cache. The image pixel cache is a
+rectangular window (a view) into the actual image pixels (which may be
+in memory, memory-mapped from a disk file, or entirely on
+disk). Obtain existing image pixels via get(). Create a new pixel
+region using set().
+
+Depending on the capabilities of the operating system, and the
+relationship of the window to the image, the pixel cache may be a copy
+of the pixels in the selected window, or it may be the actual image
+pixels. In any case calling sync() insures that the base image is
+updated with the contents of the modified pixel cache. The method
+decode()supports copying foreign pixel data formats into the pixel
+cache according to the QuantumTypes. The method encode() supports
+copying the pixels in the cache to a foreign pixel representation
+according to the format specified by QuantumTypes.
+
+Setting a view using the Pixels class does not cause the number of
+references to the underlying image to be reduced to one. Therefore, in
+order to ensure that only the current generation of the image is
+modified, the Image's modifyImage() method should be invoked to reduce
+the reference count on the underlying image to one. If this is not
+done, then it is possible for a previous generation of the image to be
+modified due to the use of reference counting when copying or
+constructing an Image.
+
+The PixelPacket* returned by the set and get methods, and the
+IndexPacket* returned by the indexes method point to pixel data
+managed by the Pixels class. The Pixels class is responsible for
+releasing resources associated with the pixel view. This means that
+the pointer should never be passed to delete() or free().
+
+.. image:: Cache.png
+ :width: 254px
+ :height: 218px
+ :scale: 100%
+ :align: center
+ :alt: Figure showing pixel cache access
+
+.. Probably want bottom alignment for above (but not accepted by
+.. currently installed rst2html.py parser)
+
+The pixel view is a small image in which the pixels may be accessed,
+addressed, and updated, as shown in the following example, which
+produces an image similar to the one on the right (minus lines and
+text)::
+
+ // Create base image
+ Image image(Geometry(254,218), "white");
+
+ // Set the image type to TrueColor DirectClass representation.
+ image.type(TrueColorType);
+
+ // Ensure that there is only one reference to underlying image
+ // If this is not done, then image pixels will not be modified.
+ image.modifyImage();
+
+ // Allocate pixel view
+ Pixels view(image);
+
+ // Set all pixels in region anchored at 38x36, with size 160x230 to green.
+ unsigned int columns = 196; unsigned int rows = 162;
+ Color green("green");
+ PixelPacket *pixels = view.get(38,36,columns,rows);
+ for ( int row = 0; row < rows ; ++row )
+ for ( int column = 0; column < columns ; ++column )
+ *pixels++=green;
+
+ // Save changes to image.
+ view.sync();
+
+ // Set all pixels in region anchored at 86x72, with size 108x67 to yellow.
+ columns = 108; rows = 67;
+ Color yellow("yellow");
+ pixels = view.get(86,72,columns,rows);
+ for ( int row = 0; row < rows ; ++row )
+ for ( int column = 0; column < columns ; ++column )
+ *pixels++=yellow;
+ view.sync();
+
+ // Set pixel at position 108,94 to red
+ *(view.get(108,94,1,1)) = Color("red");
+
+ // Save changes to image.
+ view.sync();
+
+The following is the definition of the Magick::Pixels class::
+
+ class Pixels
+ {
+ public:
+
+ // Construct pixel view using specified image.
+ Pixels( Magick::Image &image_ );
+
+ // Destroy pixel view
+ ~Pixels( void );
+
+ // Transfer pixels from the image to the pixel view as defined by
+ // the specified region. Modified pixels may be subsequently
+ // transferred back to the image via sync.
+ PixelPacket* get ( const int x_, const int y_,
+ const unsigned int columns_,const unsigned int rows_ );
+
+ // Transfer read-only pixels from the image to the pixel view as
+ // defined by the specified region.
+ const PixelPacket* getConst ( const int x_, const int y_,
+ const unsigned int columns_,
+ const unsigned int rows_ );
+
+ // Transfers the image view pixels to the image.
+ void sync ( void );
+
+ // Allocate a pixel view region to store image pixels as defined
+ // by the region rectangle. This area is subsequently transferred
+ // from the pixel view to the image via sync.
+ PixelPacket* set ( const int x_, const int y_,
+ const unsigned int columns_, const unsigned int rows_ );
+
+ // Return pixel colormap index array
+ IndexPacket* indexes ( void );
+
+ // Left ordinate of view
+ int x ( void ) const;
+
+ // Top ordinate of view
+ int y ( void ) const;
+
+ // Width of view
+ unsigned int columns ( void ) const;
+
+ // Height of view
+ unsigned int rows ( void ) const;
+
+ };
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/README.txt b/www/Magick++/README.txt
new file mode 100644
index 0000000..c4cb380
--- /dev/null
+++ b/www/Magick++/README.txt
@@ -0,0 +1,5 @@
+This directory contains the Magick++ documentation.
+
+The file NEWS.html is generated from Magick++ source directory via
+ txt2html -t 'Magick++ News' < NEWS > ../www/Magick++/NEWS.html
+using Seth Golub's fantastic txt2html translator.
diff --git a/www/Magick++/STL.html b/www/Magick++/STL.html
new file mode 100644
index 0000000..510d43a
--- /dev/null
+++ b/www/Magick++/STL.html
@@ -0,0 +1,1966 @@
+<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR"
+ content="Mozilla/4.78 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]">
+ <meta name="Author" content="Bob Friesenhahn">
+ <meta name="Description"
+ content="Documentation on Magick++'s STL support templates.">
+ <meta name="Keywords" content="STL,Magick++,GraphicsMagick">
+ <title>Magick++ STL Support</title>
+</head>
+<body text="#000000" bgcolor="#ffffff" link="#0000ff" vlink="#ff0000"
+ alink="#000088">
+<center>
+<h1> Magick++ STL Support</h1>
+</center>
+Magick++ provides a set of <a href="http://www.sgi.com/tech/stl/">Standard
+Template Libary</a> (<a href="http://www.sgi.com/tech/stl/">STL</a> )
+algorithms for operating across ranges of image frames in a container.
+It also provides a set of STL unary function objects to apply an
+operation on image frames in a container via an algorithm which uses
+unary function objects. A good example of a standard algorithm which is
+useful for processing containers of image frames is the STL <i><a
+ href="http://www.sgi.com/tech/stl/for_each.html"> for_each</a> </i>
+algorithm which invokes a unary function object on a range of container
+elements.
+<p>Magick++ uses a limited set of template argument types. The current
+template argument types are: </p>
+<blockquote><a href="http://www.sgi.com/tech/stl/Container.html">Container</a>
+ <blockquote>A container having the properties of a <a
+ href="http://www.sgi.com/tech/stl/BackInsertionSequence.html"> Back
+Insertion Sequence</a> . Sequences support forward iterators and Back
+Insertion Sequences support the additional abilty to append an element
+via push_back(). Common compatable container types are the STL &lt;<a
+ href="http://www.sgi.com/tech/stl/Vector.html"> vector</a> &gt; and &lt;<a
+ href="http://www.sgi.com/tech/stl/List.html">list</a> &gt; template
+containers. This template argument is usually used to represent an
+output container in which one or more image frames may be appended.
+Containers like STL &lt;<a href="http://www.sgi.com/tech/stl/Vector.html">vector</a>
+&gt; which have a given default <i>capacity</i> may need to have their <i>
+capacity</i> adjusted via r<i>eserve() </i>to a larger <i>capacity</i>
+in order to support the expected final <i>size</i> . Since Magick++
+images are very small, it is likely that the default capacity of STL &lt;<a
+ href="http://www.sgi.com/tech/stl/Vector.html"> vector</a> &gt; is
+sufficient for most situations.</blockquote>
+ <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+ <blockquote>An input iterator used to express a position in a
+container. These template arguments are typically used to represent a
+range of elements with f<i>irst_</i> representing the first element to
+be processed and <i> last_</i> representing the element to stop at. When
+processing the entire contents of a container, it is handy to know that
+STL containers usually provide the begin() and end() methods to return
+input interators which correspond with the first and last elements,
+respectively.</blockquote>
+</blockquote>
+The following is an example of how frames from a GIF animation <font
+ color="#000000"> "test_image_anim.gif" may be appended horizontally
+with the resulting image written to the file "appended_image.miff":</font>
+<p><tt><font color="#000066">#include &lt;list&gt;</font></tt> <br>
+<tt><font color="#000066">#include &lt;Magick++.h&gt;</font></tt> <br>
+<tt><font color="#000066">using namespace std;</font></tt> <br>
+<tt><font color="#000066">using namespace Magick;</font></tt> </p>
+<p><tt><font color="#000066">int main(int /*argc*/,char **/*argv*/)</font></tt> <br>
+<tt><font color="#000066">{</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp; list&lt;Image&gt; imageList;</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp; readImages( &amp;imageList,
+"test_image_anim.gif" );</font></tt> </p>
+<p><tt><font color="#000066">&nbsp;&nbsp; Image appended;</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp; appendImages( &amp;appended,
+imageList.begin(), imageList.end() );</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp; appended.write(
+"appended_image.miff" );</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp; return 0;</font></tt> <br>
+<tt><font color="#000066">}</font></tt> </p>
+<p>The available Magick++ specific STL algorithms for operating on
+sequences of image frames are shown in the following table: <br>
+&nbsp;
+<table border="1" width="100%">
+ <caption><b>Magick++ STL Algorithms For Image Sequences</b></caption> <tbody>
+ <tr>
+ <td>
+ <center><b>Algorithm</b></center>
+ </td>
+ <td>
+ <center><b>Signature</b></center>
+ </td>
+ <td>
+ <center><b>Description</b></center>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="animateImages"></a> <font size="-1">animateImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_</font></td>
+ <td><font size="-1">Animate a sequence of image frames. Image
+frames are displayed in succession, creating an animated effect. The
+animation options are taken from the first image frame. This feature is
+only supported under X11 at the moment.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="appendImages"></a> <font size="-1">appendImages</font></center>
+ </td>
+ <td><font size="-1"><a href="Image.html">Image</a>
+*appendedImage_, <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_, bool stack_ = false</font></td>
+ <td><font size="-1">Append a sequence of image frames, writing
+the result to <i>appendedImage_.</i> All the input image frames must
+have the same width or height. Image frames of the same width are
+stacked top-to-bottom. Image frames of the same height are stacked
+left-to-right. If the <i>stack_</i> parameter is false, rectangular
+image frames are stacked left-to-right otherwise top-to-bottom.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="averageImages"></a> <font size="-1">averageImages</font></center>
+ </td>
+ <td><font size="-1"><a href="Image.html">Image</a>
+*averagedImage_, <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_</font></td>
+ <td><font size="-1">Average a sequence of image frames, writing
+the result to <i>averagedImage_</i>. All the input image frames must
+be the same size in pixels.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="coalesceImages"></a> <font size="-1">coalesceImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/Container.html"> Container</a>
+*coalescedImages_, <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_</font><br>
+ </td>
+ <td><font size="-1">Create a coalesced image sequence obtained by
+"playing" the image sequence (observing page offsets and disposal
+methods) to create a new image sequence in which all frames are full
+size and completely rendered. Note that if the original image sequence
+relied on page offsets and disposal methods that the resulting sequence
+will be larger (perhaps much larger) then the original. This is useful
+for GIF animation sequences that have page offsets and disposal methods.
+The resuting image sequence is returned via <i>coalescedImages_.</i></font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="deconstructImages"></a> <font size="-1">deconstructImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/Container.html"> Container</a>
+*deconstructedImages_, <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_</font></td>
+ <td><font size="-1">Break down an image sequence into constituent
+parts.&nbsp; This is useful for creating GIF or MNG animation sequences.
+The input sequence is specified by <i>first_</i> and <i>last_</i>, and
+the deconstruted images are returned via <i>deconstructedImages_</i>.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="displayImages"></a> <font size="-1">displayImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_</font></td>
+ <td><font size="-1">Display a sequence of image frames. Through
+use of a pop-up menu, image frames may be selected in succession. This
+feature is fully supported under X11 but may have only limited support
+in other environments.</font> <br>
+ <font size="-1"><b><font color="#ff0000">Caution: </font></b> if
+an image format is is not compatable with the display visual (e.g. JPEG
+on a colormapped display) then the original image will be altered. Use a
+copy of the original if this is a problem.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="flattenImages"></a> <font size="-1">flattenImages</font></center>
+ </td>
+ <td><font size="-1"><a href="Image.html">Image</a>
+*flattendImage_, <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_</font></td>
+ <td><font size="-1">Merge a sequence of image frames which
+represent image layers into a single composited representation. The <i>flattendImage_</i>
+parameter points to an existing Image to update with the flattened
+image. This function is useful for combining Photoshop layers into a
+single image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="mapImages"></a> <font size="-1">mapImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_, const <a href="Image.html">Image</a> &amp; mapImage_, bool
+dither_,&nbsp; bool measureError_ = false</font></td>
+ <td><font size="-1">Replace the colors of a sequence of images
+with the closest color from a reference image. Set <i>dither_</i> to <i>true</i>
+to enable dithering.&nbsp; Set <i>measureError_</i> to <i>true</i> in
+order to evaluate quantization error.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="montageImages"></a> <font size="-1">montageImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/Container.html"> Container</a>
+*montageImages_, <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_, const <a href="Montage.html">Montage</a> &amp;montageOpts_</font></td>
+ <td><font size="-1">Create a composite image by combining several
+separate image frames. Multiple frames may be generated in the output
+container <i> montageImages_ </i>depending on the tile setting and the
+number of image frames montaged. Montage options are provided via the
+parameter <i>montageOpts_</i> . Options set in the first image frame (<a
+ href="Image.html#backgroundcolor"> backgroundColor,</a> <a
+ href="Image.html#bordercolor">borderColor</a> , <a
+ href="Image.html#mattecolor">matteColor</a> , <a
+ href="Image.html#fillcolor">fillColor,</a> <a
+ href="Image.html#strokecolor">strokeColor,</a> <a
+ href="Image.html#font">font,</a>
+and <a href="Image.html#fontpointsize">fontPointsize</a> ) are also used
+as options by <i>montageImages().</i></font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="morphImages"></a> <font size="-1">morphImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/Container.html"> Container</a>
+*morphedImages_, <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_, unsigned int frames_</font></td>
+ <td><font size="-1">Morph a seqence of image frames. This
+algorithm&nbsp; expands the number of image frames (output to the
+container <i>morphedImages_)</i> by adding the number of intervening
+frames specified by <i>frames_</i> such that the original frames morph
+(blend) into each other when played as an animation.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="mosaicImages"></a> <font size="-1">mosaicImages</font></center>
+ </td>
+ <td><font size="-1"><a href="Image.html">Image</a> *mosaicImage_, <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_</font></td>
+ <td><font size="-1">Inlay a number of images to form a single
+coherent picture. The <i>mosicImage_</i> argument is updated with a
+mosaic constructed from the image sequence represented by <i>first_</i>
+through <i>last_</i> .</font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="readImages"></a> <font size="-1">readImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/Container.html"> Container</a>
+*sequence_, const std::string &amp;imageSpec_</font></td>
+ <td><font size="-1">Read a sequence of image frames into existing
+container (appending to container <i>sequence_</i>) with image names
+specified in the string <i>imageSpec_</i>.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/Container.html"> Container</a>
+*sequence_, const <a href="Blob.html">Blob</a> &amp;blob_</font></td>
+ <td><font size="-1">Read a sequence of image frames into existing
+container (appending to container sequence_) from <a href="Blob.html">Blob</a>
+blob_.</font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="writeImages"></a> <font size="-1">writeImages</font></center>
+ </td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_, const std::string &amp;imageSpec_, bool adjoin_ = true</font></td>
+ <td><font size="-1">Write images in container to file specified
+by string <i>imageSpec_</i>. Set <i>adjoin_ </i>to false to write a
+set of image frames via a wildcard <i>imageSpec_ </i>(e.g.
+image%02d.miff).</font> <br>
+The wildcard must be one of <tt>%0Nd, %0No, or %0Nx</tt>. <br>
+ <font size="-1"><b><font color="#ff0000">Caution: </font></b> if
+an image format is selected which is capable of supporting fewer colors
+than the original image or quantization has been requested, the original
+image will be quantized to fewer colors. Use a copy of the original if
+this is a problem.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_, <a href="Blob.html">Blob</a> *blob_, bool adjoin_ = true</font></td>
+ <td><font size="-1">Write images in container to in-memory BLOB
+specified by <a href="Blob.html">Blob</a> blob_. Set adjoin_ to false to
+write a set of image frames via a wildcard imageSpec_ (e.g.
+image%02d.miff).</font> <br>
+ <font size="-1"><b><font color="#ff0000">Caution:</font></b> if an
+image format is selected which is capable of supporting fewer colors
+than the original image or quantization has been requested, the original
+image will be quantized to fewer colors. Use a copy of the original if
+this is a problem.</font></td>
+ </tr>
+ <tr>
+ <td><a name="quantizeImages"></a> <font size="-1">quantizeImages</font></td>
+ <td><font size="-1"><a
+ href="http://www.sgi.com/tech/stl/InputIterator.html"> InputIterator</a>
+first_, <a href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+last_, bool measureError_ = false</font></td>
+ <td><font size="-1">Quantize colors in images using current
+quantization settings. Set <i>measureError_</i> to <i>true</i> in order
+to measure quantization error.</font></td>
+ </tr>
+ </tbody>
+</table>
+<br>
+&nbsp; </p>
+<center>
+<h3> Magick++ Unary Function Objects</h3>
+</center>
+Magick++ unary function objects inherit from the STL unary_function
+template class . The STL unary_function template class is of the form
+<blockquote><tt><font color="#000099">unary_function&lt;Arg, Result&gt;</font></tt></blockquote>
+and expects that derived classes implement a method of the form:
+<blockquote><tt><font color="#000099">Result operator()( Arg argument_
+);</font></tt></blockquote>
+which is invoked by algorithms using the function object. In the case
+of unary function objects defined by Magick++, the invoked function
+looks like:
+<blockquote><tt><font color="#000099">void operator()( Image
+&amp;image_);</font></tt></blockquote>
+with a typical implementation looking similar to:
+<blockquote><tt><font color="#000099">void operator()( Image
+&amp;image_ )</font></tt> <br>
+ <tt><font color="#000099">&nbsp; {</font></tt> <br>
+ <tt><font color="#000099">&nbsp;&nbsp;&nbsp; image_.contrast(
+_sharpen );</font></tt> <br>
+ <tt><font color="#000099">&nbsp; }</font></tt></blockquote>
+where <i>contrast</i> is an Image method and <i>_sharpen </i>is an
+argument stored within the function object by its contructor. Since
+constructors may be polymorphic, a given function object may have
+several constructors and selects the appropriate Image method based on
+the arguments supplied.
+<p>In essence, unary function objects (as provided by Magick++) simply
+provide the means to construct an object which caches arguments for
+later use by an algorithm designed for use with unary function objects.
+There is a unary function object corresponding each algorithm provided
+by the <a href="Image.html"> Image</a> class and there is a contructor
+available compatable with each synonymous method in the Image class. </p>
+<p>The unary function objects that Magick++ provides to support
+manipulating images are shown in the following table: <br>
+&nbsp;
+<table border="1">
+ <caption><b>Magick++ Unary Function Objects For Image Manipulation</b></caption> <tbody>
+ <tr align="center">
+ <td><b>Function Object</b></td>
+ <td><b>Constructor Signatures(s)</b></td>
+ <td><b>Description</b></td>
+ </tr>
+ <tr>
+ <td valign="middle">
+ <div align="center"><a name="adaptiveThresholdImage"></a> <font
+ size="-1">adaptiveThresholdImage</font><br>
+ </div>
+ </td>
+ <td valign="middle"><font size="-1">unsigned int width, unsigned
+int height, unsigned offset = 0</font><br>
+ </td>
+ <td valign="top"><font size="-1">Apply adaptive thresholding to
+the image. Adaptive thresholding is useful if the ideal threshold level
+is not known in advance, or if the illumination gradient is not constant
+across the image. Adaptive thresholding works by evaulating the mean
+(average) of a pixel region (size specified by <i>width</i> and <i>height</i>)
+and using the mean as the thresholding value. In order to remove
+residual noise from the background, the threshold may be adjusted by
+subtracting a constant <i>offset</i> (default zero) from the mean to
+compute the threshold.</font><br>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="addNoiseImage"></a> <font size="-1">addNoiseImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#NoiseType">NoiseType</a>
+noiseType_</font></td>
+ <td><font size="-1">Add noise to image with specified noise type.</font></td>
+ </tr>
+ <tr>
+ <td style="vertical-align: middle;"><small><a
+ name="affineTransformImage"></a>affineTransformImage<br>
+ </small></td>
+ <td style="vertical-align: middle;"><small>const DrawableAffine
+&amp;affine_<br>
+ </small></td>
+ <td style="vertical-align: middle;"><small>Transform image by
+specified affine (or free transform) matrix.<br>
+ </small></td>
+ </tr>
+ <tr>
+ <td rowspan="4">
+ <center><a name="annotateImage"></a> <font size="-1">annotateImage</font></center>
+ </td>
+ <td><font size="-1">const std::string &amp;text_, const <a
+ href="Geometry.html"> Geometry</a> &amp;location_</font></td>
+ <td><font size="-1">Annotate with text using specified text,
+bounding area, placement gravity, and rotation. If <i>boundingArea_</i>
+is invalid, then bounding area is entire image.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">std::string text_, const <a
+ href="Geometry.html">Geometry</a> &amp;boundingArea_, <a
+ href="Enumerations.html#GravityType">GravityType</a> gravity_</font></td>
+ <td><font size="-1">Annotate using specified text, bounding area,
+and placement gravity. If <i>boundingArea_</i> is invalid, then
+bounding area is entire image.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const std::string &amp;text_, const <a
+ href="Geometry.html"> Geometry</a> &amp;boundingArea_, <a
+ href="Enumerations.html#GravityType">GravityType</a> gravity_, double
+degrees_,&nbsp;</font></td>
+ <td><font size="-1">Annotate with text using specified text,
+bounding area, placement gravity, and rotation. If <i>boundingArea_</i>
+is invalid, then bounding area is entire image.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const std::string &amp;text_, <a
+ href="Enumerations.html#GravityType"> GravityType</a> gravity_</font></td>
+ <td><font size="-1">Annotate with text (bounding area is entire
+image) and placement gravity.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="blurImage"></a> <font size="-1">blurImage</font></center>
+ </td>
+ <td><font size="-1">const double radius_ = 1, const double sigma_
+= 0.5</font></td>
+ <td><font size="-1">Blur image. The radius_ parameter specifies
+the radius of the Gaussian, in pixels, not counting the center
+pixel.&nbsp; The sigma_ parameter specifies the standard deviation of
+the Laplacian, in pixels.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="borderImage"></a> <font size="-1">borderImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_ = "6x6+0+0"</font></td>
+ <td><font size="-1">Border image (add border to image).&nbsp; The
+color of the border is specified by the <i>borderColor</i> attribute.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="charcoalImage"></a> <font size="-1">charcoalImage</font></center>
+ </td>
+ <td><font size="-1">const double radius_ = 1, const double sigma_
+= 0.5</font></td>
+ <td><font size="-1">Charcoal effect image (looks like charcoal
+sketch). The radius_ parameter specifies the radius of the Gaussian, in
+pixels, not counting the center pixel.&nbsp; The sigma_ parameter
+specifies the standard deviation of the Laplacian, in pixels.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="chopImage"></a> <font size="-1">chopImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_</font></td>
+ <td><font size="-1">Chop image (remove vertical or horizontal
+subregion of image)</font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="colorizeImage"></a> <font size="-1">colorizeImage</font></center>
+ </td>
+ <td><font size="-1">const unsigned int opacityRed_, const
+unsigned int opacityGreen_, const unsigned int opacityBlue_, const Color
+&amp;penColor_</font></td>
+ <td><font size="-1">Colorize image with pen color, using
+specified percent opacity for red, green, and blue quantums.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const unsigned int opacity_, const <a
+ href="Color.html"> Color</a> &amp;penColor_</font></td>
+ <td><font size="-1">Colorize image with pen color, using
+specified percent opacity.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="commentImage"></a> <font size="-1">commentImage</font></center>
+ </td>
+ <td><font size="-1">const std::string &amp;comment_</font></td>
+ <td><font size="-1">Comment image (add comment string to
+image).&nbsp; By default, each image is commented with its file name.
+Use&nbsp; this&nbsp; method to&nbsp; assign a specific comment to the
+image.&nbsp; Optionally you can include the image filename, type, width,
+height, or other&nbsp; image&nbsp; attributes by embedding <a
+ href="FormatCharacters.html">special format characters.</a> </font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="compositeImage"></a> <font size="-1">compositeImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Image.html">Image</a>
+&amp;compositeImage_, int xOffset_, int yOffset_, <a
+ href="Enumerations.html#CompositeOperator"> CompositeOperator</a>
+compose_ = <i>InCompositeOp</i></font></td>
+ <td rowspan="2"><font size="-1">Compose an image onto another at
+specified offset and using specified algorithm</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const <a href="Image.html">Image</a>
+&amp;compositeImage_, const Geometry &amp;offset_, <a
+ href="Enumerations.html#CompositeOperator"> CompositeOperator</a>
+compose_ = <i>InCompositeOp</i></font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="condenseImage"></a> <font size="-1">condenseImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Condense image (Re-run-length encode image in
+memory).</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="contrastImage"></a> <font size="-1">contrastImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int sharpen_</font></td>
+ <td><font size="-1">Contrast image (enhance intensity differences
+in image)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="cropImage"></a> <font size="-1">cropImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_</font></td>
+ <td><font size="-1">Crop image (subregion of original image)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="cycleColormapImage"></a> <font size="-1">cycleColormap-</font> <br>
+ <font size="-1">Image</font></center>
+ </td>
+ <td><font size="-1">int amount_</font></td>
+ <td><font size="-1">Cycle image colormap</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="despeckleImage"></a> <font size="-1">despeckleImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Despeckle image (reduce speckle noise)</font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="drawImage"></a> <font size="-1">drawImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Drawable.html">Drawable</a>
+&amp;drawable_</font></td>
+ <td><font size="-1">Draw shape or text on image.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const std::list&lt;<a href="Drawable.html">Drawable</a>
+&gt; &amp;drawable_</font></td>
+ <td><font size="-1">Draw shapes or text on image using a set of
+Drawable objects contained in an STL list. Use of this method improves
+drawing performance and allows batching draw objects together in a list
+for repeated use.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="edgeImage"></a> <font size="-1">edgeImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int radius_ = 0.0</font></td>
+ <td><font size="-1">Edge image (hilight edges in image).&nbsp;
+The radius is the radius of the pixel neighborhood.. Specify a radius
+of zero for automatic radius selection.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="embossImage"></a> <font size="-1">embossImage</font></center>
+ </td>
+ <td><font size="-1">const double radius_ = 1, const double sigma_
+= 0.5</font></td>
+ <td><font size="-1">Emboss image (hilight edges with 3D effect).
+The radius_ parameter specifies the radius of the Gaussian, in pixels,
+not counting the center pixel.&nbsp; The sigma_ parameter specifies the
+standard deviation of the Laplacian, in pixels.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="enhanceImage"></a> <font size="-1">enhanceImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Enhance image (minimize noise)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="equalizeImage"></a> <font size="-1">equalizeImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Equalize image (histogram equalization)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="flipImage"></a> <font size="-1">flipImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Flip image (reflect each scanline in the
+vertical direction)</font></td>
+ </tr>
+ <tr>
+ <td rowspan="4">
+ <center><a name="floodFillColorImage"></a> <font size="-1">floodFill-</font> <br>
+ <font size="-1">ColorImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int x_, unsigned int y_, const <a
+ href="Color.html"> Color</a> &amp;fillColor_</font></td>
+ <td rowspan="2"><font size="-1">Flood-fill color across pixels
+that match the color of the target pixel and are neighbors of the
+target pixel. Uses current fuzz setting when determining color match.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;point_, const <a href="Color.html">Color</a> &amp;fillColor_</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">unsigned int x_, unsigned int y_, const <a
+ href="Color.html"> Color</a> &amp;fillColor_, const <a href="Color.html">Color</a>
+&amp;borderColor_</font></td>
+ <td rowspan="2"><font size="-1">Flood-fill color across pixels
+starting at target-pixel and stopping at pixels matching specified
+border color. Uses current fuzz setting when determining color match.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;point_, const <a href="Color.html">Color</a> &amp;fillColor_, const <a
+ href="Color.html">Color</a> &amp;borderColor_</font></td>
+ </tr>
+ <tr>
+ <td rowspan="4">
+ <center><a name="floodFillTextureImage"></a> <font size="-1">floodFill-</font> <br>
+ <font size="-1">TextureImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int x_, unsigned int y_,&nbsp; const <a
+ href="Image.html"> Image</a> &amp;texture_</font></td>
+ <td rowspan="2"><font size="-1">Flood-fill texture across pixels
+that match the color of the target pixel and are neighbors of the
+target pixel. Uses current fuzz setting when determining color match.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;point_, const Image &amp;texture_</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">unsigned int x_, unsigned int y_, const Image
+&amp;texture_, const <a href="Color.html">Color</a> &amp;borderColor_</font></td>
+ <td rowspan="2"><font size="-1">Flood-fill texture across pixels
+starting at target-pixel and stopping at pixels matching specified
+border color. Uses current fuzz setting when determining color match.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;point_, const Image &amp;texture_, const <a href="Color.html">Color</a>
+&amp;borderColor_</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="flopImage"></a> <font size="-1">flopImage</font></center>
+ </td>
+ <td><font size="-1">void&nbsp;</font></td>
+ <td><font size="-1">Flop image (reflect each scanline in the
+horizontal direction)</font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="frameImage"></a> <font size="-1">frameImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_ = "25x25+6+6"</font></td>
+ <td rowspan="2"><font size="-1">Add decorative frame around image</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">unsigned int width_, unsigned int height_,
+int x_, int y_, int innerBevel_ = 0, int outerBevel_ = 0</font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="gammaImage"></a> <font size="-1">gammaImage</font></center>
+ </td>
+ <td><font size="-1">double gamma_</font></td>
+ <td><font size="-1">Gamma correct image (uniform red, green, and
+blue correction).</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">double gammaRed_, double gammaGreen_, double
+gammaBlue_</font></td>
+ <td><font size="-1">Gamma correct red, green, and blue channels
+of image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="gaussianBlur"></a> <font size="-1">gaussianBlurImage</font></center>
+ </td>
+ <td><font size="-1">double width_, double sigma_</font></td>
+ <td><font size="-1">Gaussian blur image. The number of neighbor
+pixels to be included in the convolution mask is specified by
+'width_'.&nbsp; For example, a width of one gives a (standard) 3x3
+convolution mask. The standard deviation of the gaussian bell curve is
+specified by 'sigma_'.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="implodeImage"></a> <font size="-1">implodeImage</font></center>
+ </td>
+ <td><font size="-1">double factor_</font></td>
+ <td><font size="-1">Implode image (special effect)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="labelImage"></a> <font size="-1">labelImage</font></center>
+ </td>
+ <td><font size="-1">const string &amp;label_</font></td>
+ <td><font size="-1">Assign a label to an image. Use this option
+to&nbsp; assign&nbsp; a&nbsp; specific label to the image. Optionally
+you can include the image filename, type, width, height, or scene
+number in the label by embedding&nbsp; <a href="FormatCharacters.html">special
+format characters.</a> If the first character of string is @, the image
+label is read from a file titled by the remaining characters in the
+string. When converting to Postscript, use this&nbsp; option to specify
+a header string to print above the image.</font></td>
+ </tr>
+ <tr>
+ <td style="text-align: center; vertical-align: middle;"><small><a
+ name="levelImage"></a>levelImage<br>
+ </small></td>
+ <td style="vertical-align: top;"><small>const double black_point,
+const double white_point, const double mid_point=1.0<br>
+ </small></td>
+ <td style="vertical-align: top;"><small>Level image. Adjust the
+levels of the image by scaling the colors falling between specified
+white and black points to the full available quantum range. The
+parameters provided represent the black, mid (gamma), and white
+points.&nbsp; The black point specifies the darkest color in the image.
+Colors darker than the black point are set to zero. Mid point (gamma)
+specifies a gamma correction to apply to the image. White point
+specifies the lightest color in the image.&nbsp; Colors brighter than
+the white point are set to the maximum quantum value. The black and
+white point have the valid range 0 to MaxRGB while mid (gamma) has a
+useful range of 0 to ten.</small></td>
+ </tr>
+ <tr>
+ <td style="text-align: center; vertical-align: middle;"><small><a
+ name="levelChannelImage"></a>levelChannelImage<br>
+ </small></td>
+ <td style="vertical-align: top;"><small>const Magick::ChannelType
+channel, const double black_point, const double white_point, const
+double mid_point=1.0<br>
+ </small></td>
+ <td style="vertical-align: top;"><small>Level image channel.
+Adjust the levels of the image channel by scaling the values falling
+between specified white and black points to the full available quantum
+range. The parameters provided represent the black, mid (gamma), and
+white points. The black point specifies the darkest color in the image.
+Colors darker than the black point are set to zero. Mid point (gamma)
+specifies a gamma correction to apply to the image. White point
+specifies the lightest color in the image. Colors brighter than the
+white point are set to the maximum quantum value. The black and white
+point have the valid range 0 to MaxRGB while mid (gamma) has a useful
+range of 0 to ten.</small></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="layerImage"></a> <font size="-1">layerImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#ChannelType">ChannelType</a>
+layer_</font></td>
+ <td><font size="-1">Extract layer from image. Use this option to
+extract a particular layer from&nbsp; the image.&nbsp; <i>MatteLayer</i>,&nbsp;
+for&nbsp; example, is useful for extracting the opacity values from an
+image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="magnifyImage"></a> <font size="-1">magnifyImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Magnify image by integral size</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="mapImage"></a> <font size="-1">mapImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Image.html">Image</a>
+&amp;mapImage_ , bool dither_ = false</font></td>
+ <td><font size="-1">Remap image colors with closest color from
+reference image. Set dither_ to <i>true</i> in to apply Floyd/Steinberg
+error diffusion to the image. By default, color reduction chooses an
+optimal&nbsp; set&nbsp; of colors that best represent the original
+image. Alternatively, you can&nbsp; choose&nbsp; a&nbsp;
+particular&nbsp; set&nbsp; of colors&nbsp; from&nbsp; an image file
+with this option.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="matteFloodfillImage"></a> <font size="-1">matteFloodfill-</font> <br>
+ <font size="-1">Image</font></center>
+ </td>
+ <td><font size="-1">const <a href="Color.html">Color</a>
+&amp;target_, unsigned int matte_, int x_, int y_, <a
+ href="Enumerations.html#PaintMethod"> PaintMethod</a> method_</font></td>
+ <td><font size="-1">Floodfill designated area with a matte value</font></td>
+ </tr>
+ <tr>
+ <td><a name="medianFilterImage"></a> <font size="-1">medianFilterImage</font></td>
+ <td><font size="-1">const double radius_ = 0.0</font></td>
+ <td><font size="-1">Filter image by replacing each pixel
+component with the median color in a circular neighborhood</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="minifyImage"></a> <font size="-1">minifyImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Reduce image by integral size</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="modulateImage"></a> <font size="-1">modulateImage</font></center>
+ </td>
+ <td><font size="-1">double brightness_, double saturation_,
+double hue_</font></td>
+ <td><font size="-1">Modulate percent hue, saturation, and
+brightness of an image.&nbsp;</font><font size="-1">Modulation of
+saturation and brightness is as a ratio of the current value (1.0 for no
+change). Modulation of hue is an absolute rotation of -180 degrees to
++180 degrees from the current position corresponding to an argument
+range of 0 to 2.0 (1.0 for no change).</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="negateImage"></a> <font size="-1">negateImage</font></center>
+ </td>
+ <td><font size="-1">bool grayscale_ = false</font></td>
+ <td><font size="-1">Negate colors in image.&nbsp; Replace every
+pixel with its complementary color (white becomes black, yellow becomes
+blue, etc.).&nbsp; Set grayscale to only negate grayscale values in
+image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="normalizeImage"></a> <font size="-1">normalizeImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Normalize image (increase contrast by
+normalizing the pixel values to span the full range of color values).</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="oilPaintImage"></a> <font size="-1">oilPaintImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int radius_ = 3</font></td>
+ <td><font size="-1">Oilpaint image (image looks like oil painting)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="opacityImage"></a> <font size="-1">opacityImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int opacity_</font></td>
+ <td><font size="-1">Set or attenuate the opacity channel in the
+image. If the image pixels are opaque then they are set to the specified
+opacity value, otherwise they are blended with the supplied opacity
+value.&nbsp; The value of opacity_ ranges from 0 (completely opaque) to <i>MaxRGB</i>.
+The defines <i>OpaqueOpacity</i> and <i>TransparentOpacity</i> are
+available to specify completely opaque or completely transparent,
+respectively.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="opaqueImage"></a> <font size="-1">opaqueImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Color.html">Color</a>
+&amp;opaqueColor_, const <a href="Color.html">Color</a> &amp;penColor_</font></td>
+ <td><font size="-1">Change color of pixels matching opaqueColor_
+to specified penColor_.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="quantizeImage"></a> <font size="-1">quantizeImage</font></center>
+ </td>
+ <td><font size="-1">bool measureError_ = false</font></td>
+ <td><font size="-1">Quantize image (reduce number of colors). Set
+measureError_ to true in order to calculate error attributes.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="raiseImage"></a> <font size="-1">raiseImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_ = "6x6+0+0",&nbsp; bool raisedFlag_ =&nbsp; false</font></td>
+ <td><font size="-1">Raise image (lighten or darken the edges of
+an image to give a 3-D raised or lowered effect)</font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="reduceNoiseImage"></a> <font size="-1">reduceNoise-</font> <br>
+ <font size="-1">Image</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td rowspan="2"><font size="-1">Reduce noise in image using a
+noise peak elimination filter.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">unsigned int order_</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="rollImage"></a> <font size="-1">rollImage</font></center>
+ </td>
+ <td><font size="-1">int columns_, int rows_</font></td>
+ <td><font size="-1">Roll image (rolls image vertically and
+horizontally) by specified number of columnms and rows)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="rotateImage"></a> <font size="-1">rotateImage</font></center>
+ </td>
+ <td><font size="-1">double degrees_</font></td>
+ <td><font size="-1">Rotate image counter-clockwise by specified
+number of degrees</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="sampleImage"></a> <font size="-1">sampleImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_&nbsp;</font></td>
+ <td><font size="-1">Resize image by using pixel sampling algorithm</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="scaleImage"></a> <font size="-1">scaleImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_</font></td>
+ <td><font size="-1">Resize image by using simple ratio algorithm</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="segmentImage"></a> <font size="-1">segmentImage</font></center>
+ </td>
+ <td><font size="-1">double clusterThreshold_ = 1.0,</font> <br>
+ <font size="-1">double smoothingThreshold_ = 1.5</font></td>
+ <td><font size="-1">Segment (coalesce similar image components)
+by analyzing the histograms of the color components and identifying
+units that are homogeneous with the fuzzy c-means technique. Also uses <i>quantizeColorSpace</i>
+and <i>verbose</i> image attributes. Specify <i>clusterThreshold_</i> ,
+as the number&nbsp; of&nbsp; pixels&nbsp; each cluster&nbsp; must exceed
+the cluster threshold to be considered valid. <i>SmoothingThreshold_</i>
+eliminates noise in the&nbsp; second derivative of the histogram. As the
+value is&nbsp; increased, you can&nbsp; expect&nbsp; a&nbsp; smoother
+second derivative.&nbsp; The default is 1.5.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="shadeImage"></a> <font size="-1">shadeImage</font></center>
+ </td>
+ <td><font size="-1">double azimuth_ = 30, double elevation_ = 30,</font> <br>
+ <font size="-1">bool colorShading_ = false</font></td>
+ <td><font size="-1">Shade image using distant light source.
+Specify <i> azimuth_</i> and <i>elevation_</i> as the&nbsp;
+position&nbsp; of&nbsp; the light source. By default, the shading
+results as a grayscale image.. Set c<i>olorShading_</i> to <i>true</i> to
+shade the red, green, and blue components of the image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="sharpenImage"></a> <font size="-1">sharpenImage</font></center>
+ </td>
+ <td><font size="-1">const double radius_ = 1, const double sigma_
+= 0.5</font></td>
+ <td><font size="-1">Sharpen pixels in image. The radius_
+parameter specifies the radius of the Gaussian, in pixels, not counting
+the center pixel.&nbsp; The sigma_ parameter specifies the standard
+deviation of the Laplacian, in pixels.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="shaveImage"></a> <font size="-1">shaveImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_</font></td>
+ <td><font size="-1">Shave pixels from image edges.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="shearImage"></a> <font size="-1">shearImage</font></center>
+ </td>
+ <td><font size="-1">double xShearAngle_, double yShearAngle_</font></td>
+ <td><font size="-1">Shear image (create parallelogram by sliding
+image by X or Y axis).&nbsp; Shearing slides one edge of an image along
+the X&nbsp; or&nbsp; Y axis,&nbsp; creating&nbsp; a
+parallelogram.&nbsp; An X direction shear slides an edge along the X
+axis, while&nbsp; a&nbsp; Y&nbsp; direction shear&nbsp; slides&nbsp; an
+edge along the Y axis.&nbsp; The amount of the shear is controlled by a
+shear angle.&nbsp; For X direction&nbsp; shears,&nbsp; x&nbsp; degrees
+is measured relative to the Y axis, and similarly, for Y direction
+shears&nbsp; y&nbsp; degrees is measured relative to the X axis. Empty
+triangles left over from shearing the&nbsp; image&nbsp; are filled&nbsp;
+with&nbsp; the&nbsp; color&nbsp; defined as <i>borderColor</i>.&nbsp;</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="solarizeImage"></a> <font size="-1">solarizeImage</font></center>
+ </td>
+ <td><font size="-1">double factor_</font></td>
+ <td><font size="-1">Solarize image (similar to effect seen when
+exposing a photographic film to light during the development process)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="spreadImage"></a> <font size="-1">spreadImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int amount_ = 3</font></td>
+ <td><font size="-1">Spread pixels randomly within image by
+specified amount</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="steganoImage"></a> <font size="-1">steganoImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Image.html">Image</a>
+&amp;watermark_</font></td>
+ <td><font size="-1">Add a digital watermark to the image (based
+on second image)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="stereoImage"></a> <font size="-1">stereoImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Image.html">Image</a>
+&amp;rightImage_</font></td>
+ <td><font size="-1">Create an image which appears in stereo when
+viewed with red-blue glasses (Red image on left, blue on right)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="swirlImage"></a> <font size="-1">swirlImage</font></center>
+ </td>
+ <td><font size="-1">double degrees_</font></td>
+ <td><font size="-1">Swirl image (image pixels are rotated by
+degrees)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="textureImage"></a> <font size="-1">textureImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Image.html">Image</a>
+&amp;texture_</font></td>
+ <td><font size="-1">Layer a texture on image background</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="thresholdImage"></a> <font size="-1">thresholdImage</font></center>
+ </td>
+ <td><font size="-1">double threshold_</font></td>
+ <td><font size="-1">Threshold image</font></td>
+ </tr>
+ <tr>
+ <td rowspan="2">
+ <center><a name="transformImage"></a> <font size="-1">transformImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;imageGeometry_</font></td>
+ <td rowspan="2"><font size="-1">Transform image based on image
+and crop geometries. Crop geometry is optional.</font></td>
+ </tr>
+ <tr>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;imageGeometry_, const <a href="Geometry.html">Geometry</a>
+&amp;cropGeometry_&nbsp;</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="transparentImage"></a> <font size="-1">transparentImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Color.html">Color</a>
+&amp;color_</font></td>
+ <td><font size="-1">Add matte image to image, setting pixels
+matching color to transparent.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="trimImage"></a> <font size="-1">trimImage</font></center>
+ </td>
+ <td><font size="-1">void</font></td>
+ <td><font size="-1">Trim edges that are the background color from
+the image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="waveImage"></a> <font size="-1">waveImage</font></center>
+ </td>
+ <td><font size="-1">double amplitude_ = 25.0, double wavelength_
+= 150.0</font></td>
+ <td><font size="-1">Alter an image along a sine wave.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="zoomImage"></a> <font size="-1">zoomImage</font></center>
+ </td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_</font></td>
+ <td><font size="-1">Zoom image to specified size.</font></td>
+ </tr>
+ </tbody>
+</table>
+</p>
+<p>Function objects are available to set attributes on image frames
+which are equivalent to methods in the Image object. These function
+objects allow setting an option across a range of image frames using f<tt>
+or_each()</tt>. </p>
+<p>The following code is an example of how the color 'red' may be set
+to transparent in a GIF animation: </p>
+<p><tt><font color="#000066">list&lt;image&gt; images;</font></tt> <br>
+<tt><font color="#000066">readImages( &amp;images, "animation.gif" );</font></tt> <br>
+<tt><font color="#000066">for_each ( images.begin(), images.end(),
+transparentImage( "red" )&nbsp; );</font></tt> <br>
+<tt><font color="#000066">writeImages( images.begin(), images.end(),
+"animation.gif" );</font></tt> </p>
+<p>The available function objects for setting image attributes are <br>
+&nbsp;
+<table border="1">
+ <caption style="font-weight: bold;">Image Attributes</caption> <tbody>
+ <tr>
+ <td>
+ <center><b>Attribute</b></center>
+ </td>
+ <td>
+ <center><b>Type</b></center>
+ </td>
+ <td>
+ <center><b>Constructor Signature(s)</b></center>
+ </td>
+ <td>
+ <center><b>Description</b></center>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="adjoinImage"></a> <font size="-1">adjoinImage</font></center>
+ </td>
+ <td><font size="-1">bool</font></td>
+ <td><font size="-1">bool flag_</font></td>
+ <td><font size="-1">Join images into a single multi-image file.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="antiAlias"></a> <font size="-1">antiAliasImage</font></center>
+ </td>
+ <td><font size="-1">bool</font></td>
+ <td><font size="-1">bool flag_</font></td>
+ <td><font size="-1">Control antialiasing of rendered Postscript
+and Postscript or TrueType fonts. Enabled by default.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="animationDelay"></a> <font size="-1">animation-</font> <br>
+ <font size="-1">DelayImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int (0 to 65535)</font></td>
+ <td><font size="-1">unsigned int delay_</font></td>
+ <td><font size="-1">Time in 1/100ths of a second (0 to 65535)
+which must expire before displaying the next image in an animated
+sequence. This option is useful for regulating the animation of a
+sequence&nbsp; of GIF images within Netscape.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="animationIterations"></a> <font size="-1">animation-</font> <br>
+ <font size="-1">IterationsImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int</font></td>
+ <td><font size="-1">unsigned int iterations_</font></td>
+ <td><font size="-1">Number of iterations to loop an animation
+(e.g. Netscape loop extension) for.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="backgroundColor"></a> <font size="-1">background-</font> <br>
+ <font size="-1">ColorImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Color.html">Color</a> </font></td>
+ <td><font size="-1">const <a href="Color.html">Color</a>
+&amp;color_</font></td>
+ <td><font size="-1">Image background color</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="backgroundTexture"></a> <font size="-1">background-</font> <br>
+ <font size="-1">TextureImage</font></center>
+ </td>
+ <td><font size="-1">std::string</font></td>
+ <td><font size="-1">const string &amp;texture_</font></td>
+ <td><font size="-1">Image to use as background texture.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="borderColor"></a> <font size="-1">borderColor-</font> <br>
+ <font size="-1">Image</font></center>
+ </td>
+ <td><font size="-1"><a href="Color.html">Color</a> </font></td>
+ <td><font size="-1">&nbsp;const <a href="Color.html">Color</a>
+&amp;color_</font></td>
+ <td><font size="-1">Image border color</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="boxColor"></a> <font size="-1">boxColorImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Color.html">Color</a> </font></td>
+ <td><font size="-1">const <a href="Color.html">Color</a>
+&amp;boxColor_</font></td>
+ <td><font size="-1">Base color that annotation text is rendered
+on.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="chromaBluePrimary"></a> <font size="-1">chroma-</font> <br>
+ <font size="-1">BluePrimaryImage</font></center>
+ </td>
+ <td><font size="-1">double x &amp; y</font></td>
+ <td><font size="-1">double x_, double y_</font></td>
+ <td><font size="-1">Chromaticity blue primary point (e.g. x=0.15,
+y=0.06)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="chromaGreenPrimary"></a> <font size="-1">chroma-</font> <br>
+ <font size="-1">GreenPrimaryImage</font></center>
+ </td>
+ <td><font size="-1">double x &amp; y</font></td>
+ <td><font size="-1">double x_, double y_</font></td>
+ <td><font size="-1">Chromaticity green primary point (e.g. x=0.3,
+y=0.6)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="chromaRedPrimary"></a> <font size="-1">chroma-</font> <br>
+ <font size="-1">RedPrimaryImage</font></center>
+ </td>
+ <td><font size="-1">double x &amp; y</font></td>
+ <td><font size="-1">double x_, double y_</font></td>
+ <td><font size="-1">Chromaticity red primary point (e.g. x=0.64,
+y=0.33)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="chromaWhitePoint"></a> <font size="-1">chroma-</font> <br>
+ <font size="-1">WhitePointImage</font></center>
+ </td>
+ <td><font size="-1">double x &amp; y</font></td>
+ <td><font size="-1">double x_, double y_</font></td>
+ <td><font size="-1">Chromaticity white point (e.g. x=0.3127,
+y=0.329)</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="colorFuzz"></a> <font size="-1">colorFuzzImage</font></center>
+ </td>
+ <td><font size="-1">double</font></td>
+ <td><font size="-1">double fuzz_</font></td>
+ <td><font size="-1">Colors within this distance are considered
+equal. A number of algorithms search for a target&nbsp; color. By
+default the color must be exact. Use this option to match colors that
+are close to the target color in RGB space.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="colorMap"></a> <font size="-1">colorMapImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Color.html">Color</a> </font></td>
+ <td><font size="-1">unsigned int index_, const <a
+ href="Color.html">Color</a> &amp;color_</font></td>
+ <td><font size="-1">Color at color-pallet index.</font></td>
+ </tr>
+ <tr>
+ <td><a name="colorSpaceImage"></a> <font size="-1">colorSpaceImage</font></td>
+ <td><font size="-1"><a href="Enumerations.html#ColorspaceType">ColorspaceType</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#ColorspaceType">ColorspaceType</a>
+colorSpace_</font></td>
+ <td><font size="-1">The colorspace (e.g. CMYK) used to represent
+the image pixel colors. Image pixels are always stored as RGB(A) except
+for the case of CMY(K).</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="composeImage"></a> <font size="-1">composeImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#CompositeOperator">CompositeOperator</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#CompositeOperator">CompositeOperator</a>
+compose_</font></td>
+ <td><font size="-1">Composition operator to be used when
+composition is implicitly used (such as for image flattening).</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="compressType"></a> <font size="-1">compressType-</font> <br>
+ <font size="-1">Image</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#CompressionType">CompressionType</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#CompressionType">CompressionType</a>
+compressType_</font></td>
+ <td><font size="-1">Image compresion type. The default is the
+compression type of the specified image file.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="density"></a> <font size="-1">densityImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Geometry.html">Geometry</a> &nbsp;
+(default 72x72)</font></td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;density_</font></td>
+ <td><font size="-1">Vertical and horizontal resolution in pixels
+of the image. This option specifies an image density when decoding a
+Postscript or Portable Document page. Often used with <i>psPageSize</i>.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="depth"></a> <font size="-1">depthImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int</font></td>
+ <td><font size="-1">unsigned int depth_</font></td>
+ <td><font size="-1">Image depth. Used to specify the bit depth
+when reading or writing&nbsp; raw images or thwn the output format
+supports multiple depths. Defaults to the quantum depth that
+GraphicsMagick is compiled with.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="endianImage"></a> <font size="-1">endianImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#EndianType">EndianType</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#EndianType">EndianType</a>
+endian_</font></td>
+ <td><font size="-1">Specify (or obtain) endian option for formats
+which support it.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="fileName"></a> <font size="-1">fileNameImage</font></center>
+ </td>
+ <td><font size="-1">std::string</font></td>
+ <td><font size="-1">const std::string &amp;fileName_</font></td>
+ <td><font size="-1">Image file name.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="fillColorImage"></a> <font size="-1">fillColorImage</font></center>
+ </td>
+ <td><font size="-1">Color</font></td>
+ <td><font size="-1">const Color &amp;fillColor_</font></td>
+ <td><font size="-1">Color to use when filling drawn objects</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="filterType"></a> <font size="-1">filterTypeImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#FilterTypes">FilterTypes</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#FilterTypes">FilterTypes</a>
+filterType_</font></td>
+ <td><font size="-1">Filter to use when resizing image. The
+reduction filter employed has a sigificant effect on the time required
+to resize an image and the resulting quality. The default filter is <i>Lanczos</i>
+which has been shown to produce good results when reducing images.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="font"></a> <font size="-1">fontImage</font></center>
+ </td>
+ <td><font size="-1">std::string</font></td>
+ <td><font size="-1">const std::string &amp;font_</font></td>
+ <td><font size="-1">Text rendering font. If the font is a fully
+qualified X server font name, the font is obtained from an X&nbsp;
+server. To use a TrueType font, precede the TrueType filename with an @.
+Otherwise, specify&nbsp; a&nbsp; Postscript font name (e.g.
+"helvetica").</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="fontPointsize"></a> <font size="-1">fontPointsize-</font> <br>
+ <font size="-1">Image</font></center>
+ </td>
+ <td><font size="-1">unsigned int</font></td>
+ <td><font size="-1">unsigned int pointSize_</font></td>
+ <td><font size="-1">Text rendering font point size</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="gifDisposeMethod"></a> <font size="-1">gifDispose-</font> <br>
+ <font size="-1">MethodImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int</font> <br>
+ <font size="-1">{ 0 = Disposal not specified,</font> <br>
+ <font size="-1">1 = Do not dispose of graphic,</font> <br>
+ <font size="-1">3 = Overwrite graphic with background color,</font> <br>
+ <font size="-1">4 = Overwrite graphic with previous graphic. }</font></td>
+ <td><font size="-1">unsigned int disposeMethod_</font></td>
+ <td><font size="-1">GIF disposal method. This option is used to
+control how successive frames are rendered (how the preceding frame is
+disposed of) when creating a GIF animation.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="interlaceType"></a> <font size="-1">interlace-</font> <br>
+ <font size="-1">TypeImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#InterlaceType">InterlaceType</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#InterlaceType">InterlaceType</a>
+interlace_</font></td>
+ <td><font size="-1">The type of interlacing scheme (default <i>NoInterlace</i>
+). This option is used to specify the type of&nbsp; interlacing
+scheme&nbsp; for&nbsp; raw&nbsp; image formats such as RGB or YUV. <i>NoInterlace</i>
+means do not&nbsp; interlace, <i>LineInterlace</i> uses scanline
+interlacing, and <i>PlaneInterlace</i> uses plane interlacing. <i>
+PartitionInterlace</i> is like <i>PlaneInterlace</i> except the&nbsp;
+different planes&nbsp; are saved&nbsp; to individual files (e.g.&nbsp;
+image.R, image.G, and image.B). Use <i>LineInterlace</i> or <i>PlaneInterlace</i>
+to create an interlaced GIF or progressive JPEG image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="isValidImage"></a> <font size="-1">isValidImage</font></center>
+ </td>
+ <td><font size="-1">bool</font></td>
+ <td><font size="-1">bool isValid_</font></td>
+ <td><font size="-1">Set image validity. Valid images become empty
+(inValid) if argument is false.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="label"></a> <font size="-1">labelImage</font></center>
+ </td>
+ <td><font size="-1">std::string</font></td>
+ <td><font size="-1">const std::string &amp;label_</font></td>
+ <td><font size="-1">Image label</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="lineWidth"></a> <font size="-1">lineWidthImage</font></center>
+ </td>
+ <td><font size="-1">double</font></td>
+ <td><font size="-1">double lineWidth_</font></td>
+ <td><font size="-1">Line width for drawing lines, circles,
+ellipses, etc. See <a href="Drawable.html">Drawable</a> .</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="magick"></a> <font size="-1">magickImage</font></center>
+ </td>
+ <td><font size="-1">std::string</font></td>
+ <td><font size="-1">&nbsp;const std::string &amp;magick_</font></td>
+ <td><font size="-1">Get image format (e.g. "GIF")</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="matte"></a> <font size="-1">matteImage</font></center>
+ </td>
+ <td><font size="-1">bool</font></td>
+ <td><font size="-1">bool matteFlag_</font></td>
+ <td><font size="-1">True if the image has transparency. If set
+True, store matte channel if&nbsp; the image has one otherwise create
+an opaque one.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="matteColor"></a> <font size="-1">matteColorImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Color.html">Color</a> </font></td>
+ <td><font size="-1">const <a href="Color.html">Color</a>
+&amp;matteColor_</font></td>
+ <td><font size="-1">Image matte (frame) color</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="monochrome"></a> <font size="-1">monochrome-</font> <br>
+ <font size="-1">Image</font></center>
+ </td>
+ <td><font size="-1">bool</font></td>
+ <td><font size="-1">bool flag_</font></td>
+ <td><font size="-1">Transform the image to black and white</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="pageImage"></a> <font size="-1">pageImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Geometry.html#PostscriptPageSize">Geometry</a> </font></td>
+ <td><font size="-1">const <a
+ href="Geometry.html#PostscriptPageSize">Geometry</a> &amp;pageSize_</font></td>
+ <td><font size="-1">Preferred size and location of an image
+canvas.</font>
+ <p><font size="-1">Use this option to specify the dimensions and
+position of the Postscript page in dots per inch or a TEXT page in
+pixels. This option is typically used in concert with <i><a
+ href="#density">density</a> </i>.</font> </p>
+ <p><font size="-1">Page may also be used to position a GIF image
+(such as for a scene in an animation)</font></p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="penColor"></a> <font size="-1">penColorImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Color.html">Color</a> </font></td>
+ <td><font size="-1">const <a href="Color.html">Color</a>
+&amp;penColor_</font></td>
+ <td><font size="-1">Pen color to use when annotating on or
+drawing on image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="penTexture"></a> <font size="-1">penTextureImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Image.html">Image</a> </font></td>
+ <td><font size="-1">const Image &amp; penTexture_</font></td>
+ <td><font size="-1">Texture image to paint with (similar to
+penColor).</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="pixelColor"></a> <font size="-1">pixelColorImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Color.html">Color</a> </font></td>
+ <td><font size="-1">unsigned int x_, unsigned int y_, const <a
+ href="Color.html"> Color</a> &amp;color_</font></td>
+ <td><font size="-1">Get/set pixel color at location x &amp; y.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="psPageSize"></a> <font size="-1">psPageSizeImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Geometry.html#PostscriptPageSize">Geometry</a> </font></td>
+ <td><font size="-1">const <a
+ href="Geometry.html#PostscriptPageSize">Geometry</a> &amp;pageSize_</font></td>
+ <td><font size="-1">Postscript page size. Use this&nbsp; option
+to specify the dimensions&nbsp; of the Postscript page in dots per inch
+or a TEXT page in pixels. This option is typically used in concert with <i>density</i>.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="quality"></a> <font size="-1">qualityImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int (0 to 100)</font></td>
+ <td><font size="-1">unsigned int quality_</font></td>
+ <td><font size="-1">JPEG/MIFF/PNG compression level (default 75).</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="quantizeColors"></a> <font size="-1">quantize-</font> <br>
+ <font size="-1">ColorsImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int</font></td>
+ <td><font size="-1">unsigned int colors_</font></td>
+ <td><font size="-1">Preferred number of colors in the image. The
+actual number of colors in the image may be less than your request, but
+never more. Images with less unique colors than specified with this
+option will have any duplicate or unused colors removed.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="quantizeColorSpace"></a> <font size="-1">quantize-</font> <br>
+ <font size="-1">ColorSpaceImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#ColorspaceType">ColorspaceType</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#ColorspaceType">ColorspaceType</a>
+colorSpace_</font></td>
+ <td><font size="-1">Colorspace to quantize colors in (default
+RGB). Empirical evidence suggests that distances in color spaces such
+as YUV or YIQ correspond to perceptual color differences more closely
+than do distances in RGB space. These color spaces may give better
+results when color reducing an image.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="quantizeDither"></a> <font size="-1">quantize-</font> <br>
+ <font size="-1">DitherImage</font></center>
+ </td>
+ <td><font size="-1">bool</font></td>
+ <td><font size="-1">bool flag_</font></td>
+ <td><font size="-1">Apply Floyd/Steinberg error diffusion to the
+image. The basic strategy of dithering is to&nbsp; trade&nbsp; intensity
+resolution&nbsp; for&nbsp; spatial&nbsp; resolution&nbsp; by&nbsp;
+averaging the intensities&nbsp; of&nbsp; several&nbsp;
+neighboring&nbsp; pixels. Images which&nbsp; suffer&nbsp; from&nbsp;
+severe&nbsp; contouring&nbsp; when&nbsp; reducing colors can be improved
+with this option. The quantizeColors or monochrome option must be set
+for this option to take effect.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="quantizeTreeDepth"></a> <font size="-1">quantize-</font> <br>
+ <font size="-1">TreeDepthImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int (0 to 8)</font></td>
+ <td><font size="-1">unsigned int treeDepth_</font></td>
+ <td><font size="-1">Depth of the quantization color
+classification tree. Values of 0 or 1 allow selection of the optimal
+tree depth for the color reduction algorithm. Values between 2 and 8 may
+be used to manually adjust the tree depth.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="renderingIntent"></a> <font size="-1">rendering-</font> <br>
+ <font size="-1">IntentImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#RenderingIntent">RenderingIntent</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#RenderingIntent">RenderingIntent</a>
+render_</font></td>
+ <td><font size="-1">The type of rendering intent</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="resolutionUnits"></a> <font size="-1">resolution-</font> <br>
+ <font size="-1">UnitsImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#ResolutionType">ResolutionType</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#ResolutionType">ResolutionType</a>
+units_</font></td>
+ <td><font size="-1">Units of image resolution</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="scene"></a> <font size="-1">sceneImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int</font></td>
+ <td><font size="-1">unsigned int scene_</font></td>
+ <td><font size="-1">Image scene number</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="size"></a> <font size="-1">sizeImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Geometry.html">Geometry</a> </font></td>
+ <td><font size="-1">const <a href="Geometry.html">Geometry</a>
+&amp;geometry_</font></td>
+ <td><font size="-1">Width and height of a raw image (an image
+which does not support width and height information).&nbsp; Size may
+also be used to affect the image size read from a multi-resolution
+format (e.g. Photo CD, JBIG, or JPEG.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="strokeColorImage"></a> <font size="-1">strokeColorImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Color.html">Color</a> </font></td>
+ <td><font size="-1">const <a href="Color.html">Color</a>
+&amp;strokeColor_</font></td>
+ <td><font size="-1">Color to use when drawing object outlines</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="subImage"></a> <font size="-1">subImageImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int</font></td>
+ <td><font size="-1">unsigned int subImage_</font></td>
+ <td><font size="-1">Subimage of an image sequence</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="subRange"></a> <font size="-1">subRangeImage</font></center>
+ </td>
+ <td><font size="-1">unsigned int</font></td>
+ <td><font size="-1">unsigned int subRange_</font></td>
+ <td><font size="-1">Number of images relative to the base image</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="tileName"></a> <font size="-1">tileNameImage</font></center>
+ </td>
+ <td><font size="-1">std::string</font></td>
+ <td><font size="-1">const std::string &amp;tileName_</font></td>
+ <td><font size="-1">Tile name</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="typeImage"></a> <font size="-1">typeImage</font></center>
+ </td>
+ <td><font size="-1"><a href="Enumerations.html#ImageType">ImageType</a> </font></td>
+ <td><font size="-1"><a href="Enumerations.html#ImageType">ImageType</a>
+type_</font></td>
+ <td><font size="-1">Image storage type.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="verbose"></a> <font size="-1">verboseImage</font></center>
+ </td>
+ <td><font size="-1">bool</font></td>
+ <td><font size="-1">bool verboseFlag_</font></td>
+ <td><font size="-1">Print detailed information about the image</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="view"></a> <font size="-1">viewImage</font></center>
+ </td>
+ <td><font size="-1">std::string</font></td>
+ <td><font size="-1">const std::string &amp;view_</font></td>
+ <td><font size="-1">FlashPix viewing parameters.</font></td>
+ </tr>
+ <tr>
+ <td>
+ <center><a name="x11Display"></a> <font size="-1">x11DisplayImage</font></center>
+ </td>
+ <td><font size="-1">std::string (e.g. "hostname:0.0")</font></td>
+ <td><font size="-1">const std::string &amp;display_</font></td>
+ <td><font size="-1">X11 display to display to, obtain fonts from,
+or to capture image from</font></td>
+ </tr>
+ </tbody>
+</table>
+<br>
+&nbsp; </p>
+<center>
+<h3> Query Image Format Support</h3>
+</center>
+Magick++ provides the&nbsp;<a name="coderInfoList"></a> <i>coderInfoList()</i>
+function to support obtaining information about the image formats
+supported by GraphicsMagick. Support for image formats in GraphicsMagick
+is provided by modules known as "coders". A user-provided container is
+updated based on a boolean truth-table match. The truth-table supports
+matching based on whether GraphicsMagick can read the format, write the
+format, or supports multiple frames for the format. A wildcard specifier
+is supported for any "don't care" field. The data obtained via
+coderInfoList() may be useful for preparing GUI dialog boxes or for
+deciding which output format to write based on support within the
+GraphicsMagick build.
+<p>The definition of coderInfoList is: </p>
+<p><tt><font color="#000066">&nbsp; class CoderInfo</font></tt> <br>
+<tt><font color="#000066">&nbsp; {</font></tt> <br>
+<tt><font color="#000066">&nbsp; public:</font></tt> </p>
+<p><tt><font color="#000066">&nbsp;&nbsp;&nbsp; enum MatchType {</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+AnyMatch,&nbsp; // match any coder</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TrueMatch, //
+match coder if true</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FalseMatch //
+match coder if false</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; };</font></tt> </p>
+<p><tt><font color="#000066">&nbsp;&nbsp;&nbsp; [ remaining CoderInfo
+methods ]</font></tt> </p>
+<p><tt><font color="#000066">&nbsp;&nbsp; }</font></tt> </p>
+<p><tt><font color="#000066">&nbsp; template &lt;class Container &gt;</font></tt> <br>
+<tt><font color="#000066">&nbsp; void coderInfoList( Container
+*container_,</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CoderInfo::MatchType isReadable_&nbsp;&nbsp; = CoderInfo::AnyMatch,</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CoderInfo::MatchType isWritable_&nbsp;&nbsp; = CoderInfo::AnyMatch,</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CoderInfo::MatchType isMultiFrame_ = CoderInfo::AnyMatch</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+);</font></tt> </p>
+<p>The following example shows how to retrieve a list of all of the
+coders which support reading images and print the coder attributes (all
+listed formats will be readable): </p>
+<p><tt><font color="#000066">&nbsp; list&lt;CoderInfo&gt; coderList;</font></tt> <br>
+<tt><font color="#000066">&nbsp; coderInfoList(
+&amp;coderList,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// Reference to output list</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CoderInfo::TrueMatch, // Match readable formats</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CoderInfo::AnyMatch,&nbsp; // Don't care about writable formats</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CoderInfo::AnyMatch); // Don't care about multi-frame support</font></tt> <br>
+<tt><font color="#000066">&nbsp; list&lt;CoderInfo&gt;::iterator entry
+= coderList.begin();</font></tt> <br>
+<tt><font color="#000066">&nbsp; while( entry != coderList.end() )</font></tt> <br>
+<tt><font color="#000066">&nbsp; {</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; cout &lt;&lt;
+entry-&gt;name() &lt;&lt; ": (" &lt;&lt; entry-&gt;description()
+&lt;&lt; ") : ";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; cout &lt;&lt; "Readable =
+";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; if (
+entry-&gt;isReadable() )</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt;
+"true";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; else</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt;
+"false";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; cout &lt;&lt; ", ";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; cout &lt;&lt; "Writable =
+";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; if (
+entry-&gt;isWritable() )</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt;
+"true";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; else</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt;
+"false";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; cout &lt;&lt; ", ";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; cout &lt;&lt; "Multiframe
+= ";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; if (
+entry-&gt;isMultiframe() )</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt;
+"true";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; else</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt;
+"false";</font></tt> <br>
+<tt><font color="#000066">&nbsp;&nbsp;&nbsp; cout &lt;&lt; endl;<br>
+&nbsp; &nbsp; entry ++;</font></tt><br>
+<tt><font color="#000066">&nbsp;&nbsp; }</font></tt>&nbsp;</p>
+<h3 style="text-align: center;">Obtaining A Color Histogram&nbsp; </h3>
+<p> &nbsp;Magick++ provides the <a name="colorHistogram"></a><span
+ style="font-weight: bold;">colorHistogram</span> template function to
+retrieve a color histogram from an image. A color histogram provides a
+count of how many times each color occurs in the image. The histogram is
+written into a user-provided container, which (for example) could be a <span
+ style="font-style: italic;">&lt;vector&gt;</span> or a <span
+ style="font-style: italic;">&lt;map&gt;</span>. &nbsp;When a
+&lt;map&gt; is used, the <span style="font-style: italic;">Color</span>
+is used as the key so that quick lookups of usage counts for colors may
+be performed. Writing into a <span style="font-style: italic;">&lt;map&gt;</span>
+may be slower than writing into a <span style="font-style: italic;">&lt;vector&gt;</span>
+since the <span style="font-style: italic;">&lt;map&gt;</span> sorts the
+entries (by color intensity) and checks for uniqueness. Each histogram
+entry is contained in type&nbsp;<span style="font-style: italic;">std::pair&lt;Magick::Color,unsigned
+long&gt;</span><span style="font-style: italic;"> </span>with the first
+member of the pair being a <span style="font-style: italic;">Color,</span>
+and the second member of the pair being an '<span
+ style="font-style: italic;">unsigned long</span>'. Use the <span
+ style="font-style: italic;">&lt;pair&gt;</span> "<span
+ style="font-style: italic;">first</span>" member to access the Color
+and the "<span style="font-style: italic;">second</span>" member to
+access&nbsp;the number of times the color occurs in the image.</p>
+<p>The template function declaration is as follows:<br>
+</p>
+<p><span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+template &lt;class Container &gt;</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+void colorHistogram( Container *histogram_, const Image image)</span><br>
+</p>
+<p>The following examples illustrate using both a &lt;map&gt; and a
+&lt;vector&gt; to retrieve the color histogram, and print out a
+formatted summary.<br>
+<br>
+Using &lt;map&gt;:<br>
+&nbsp; &nbsp; <br>
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+Image image("image.miff");</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+map&lt;Color,unsigned long&gt; histogram;</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+colorHistogram( &amp;histogram, image );</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+std::map&lt;Color,unsigned long&gt;::const_iterator p=histogram.begin();</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+while (p != histogram.end())</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp; {</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;cout &lt;&lt; setw(10) &lt;&lt; (int)p-&gt;second
+&lt;&lt; ": ("</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; setw(quantum_width)
+&lt;&lt; (int)p-&gt;first.redQuantum() &lt;&lt; ","</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; setw(quant</span><span
+ style="color: rgb(51, 51, 153); font-family: monospace;">um_width)
+&lt;&lt; (int)p-&gt;first.greenQuantum() &lt;&lt; ","</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; setw(quantum_width)
+&lt;&lt; (int)p-&gt;first.blueQuantum() &lt;&lt; ")"</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; endl;</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp; p++;</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp; }</span><br>
+<br>
+Using &lt;vector&gt;:<br>
+&nbsp; &nbsp; <br>
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+Image image("image.miff");</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+std::vector&lt;std::pair&lt;Color,unsigned long&gt; &gt; histogram;</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+colorHistogram( &amp;histogram, image );</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+std::vector&lt;std::pair&lt;Color,unsigned long&gt; &gt;::const_iterator
+p=histogram.begin();</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+while (p != histogram.end())</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp; {</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;cout &lt;&lt; setw(10) &lt;&lt; (int)p-&gt;second
+&lt;&lt; ": ("</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; setw(quantum_width)
+&lt;&lt; (int)p-&gt;first.redQuantum() &lt;&lt; ","</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; setw(quantum_width)
+&lt;&lt; (int)p-&gt;first.greenQuantum() &lt;&lt; ","</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; setw(quantum_width)
+&lt;&lt; (int)p-&gt;first.blueQuantum() &lt;&lt; ")"</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; endl;</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp;&nbsp; &nbsp;p++;</span><br
+ style="color: rgb(51, 51, 153); font-family: monospace;">
+<span style="color: rgb(51, 51, 153); font-family: monospace;">&nbsp;
+&nbsp; }</span><br>
+</p>
+<p><br>
+<br>
+</p>
+</body>
+</html>
diff --git a/www/Magick++/TypeMetric.html b/www/Magick++/TypeMetric.html
new file mode 100644
index 0000000..8e76b1b
--- /dev/null
+++ b/www/Magick++/TypeMetric.html
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick::TypeMetric</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-typemetric">
+<h1 class="title">Magick::TypeMetric</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The TypeMetric class provides the means to pass data from the Image
+class's TypeMetric method to the user. It provides information
+regarding font metrics such as ascent, descent, text width, text
+height, and maximum horizontal advance. The units of these font
+metrics are in pixels, and that the metrics are dependent on the
+current Image font (default Ghostscript's &quot;Helvetica&quot;), pointsize
+(default 12 points), and x/y resolution (default 72 DPI) settings.</p>
+<p>The pixel units may be converted to points (the standard
+resolution-independent measure used by the typesetting industry) via
+the following equation:</p>
+<pre class="literal-block">
+size_points = (size_pixels * 72)/resolution
+</pre>
+<p>where resolution is in dots-per-inch (DPI). This means that at the
+default image resolution, there is one pixel per point.</p>
+<p>Note that a font's pointsize is only a first-order approximation of
+the font height (ascender + descender) in points. The relationship
+between the specified pointsize and the rendered font height is
+determined by the font designer.</p>
+<p>See <a class="reference external" href="http://freetype.sourceforge.net/freetype2/docs/glyphs/index.html">FreeType Glyph Conventions</a>
+for a detailed description of font metrics related issues.</p>
+<p>The following is the definition of the Magick::TypeMetric class:</p>
+<pre class="literal-block">
+class MagickDLLDecl TypeMetric
+{
+ friend class Image;
+public:
+
+ TypeMetric ( void );
+ ~TypeMetric ( void );
+
+ // Ascent, the distance in pixels from the text baseline to the
+ // highest/upper grid coordinate used to place an outline point.
+ double ascent ( void ) const;
+
+ // Descent, the distance in pixels from the baseline to the lowest
+ // grid coordinate used to place an outline point. Always a
+ // negative value.
+ double descent ( void ) const;
+
+ // Text width in pixels.
+ double textWidth ( void ) const;
+
+ // Text height in pixels.
+ double textHeight ( void ) const;
+
+ // Maximum horizontal advance in pixels.
+ double maxHorizontalAdvance ( void ) const;
+
+};
+</pre>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/TypeMetric.rst b/www/Magick++/TypeMetric.rst
new file mode 100644
index 0000000..c6a7e16
--- /dev/null
+++ b/www/Magick++/TypeMetric.rst
@@ -0,0 +1,68 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+==================
+Magick::TypeMetric
+==================
+
+The TypeMetric class provides the means to pass data from the Image
+class's TypeMetric method to the user. It provides information
+regarding font metrics such as ascent, descent, text width, text
+height, and maximum horizontal advance. The units of these font
+metrics are in pixels, and that the metrics are dependent on the
+current Image font (default Ghostscript's "Helvetica"), pointsize
+(default 12 points), and x/y resolution (default 72 DPI) settings.
+
+The pixel units may be converted to points (the standard
+resolution-independent measure used by the typesetting industry) via
+the following equation::
+
+ size_points = (size_pixels * 72)/resolution
+
+where resolution is in dots-per-inch (DPI). This means that at the
+default image resolution, there is one pixel per point.
+
+Note that a font's pointsize is only a first-order approximation of
+the font height (ascender + descender) in points. The relationship
+between the specified pointsize and the rendered font height is
+determined by the font designer.
+
+See `FreeType Glyph Conventions
+<http://freetype.sourceforge.net/freetype2/docs/glyphs/index.html>`_
+for a detailed description of font metrics related issues.
+
+The following is the definition of the Magick::TypeMetric class::
+
+ class MagickDLLDecl TypeMetric
+ {
+ friend class Image;
+ public:
+
+ TypeMetric ( void );
+ ~TypeMetric ( void );
+
+ // Ascent, the distance in pixels from the text baseline to the
+ // highest/upper grid coordinate used to place an outline point.
+ double ascent ( void ) const;
+
+ // Descent, the distance in pixels from the baseline to the lowest
+ // grid coordinate used to place an outline point. Always a
+ // negative value.
+ double descent ( void ) const;
+
+ // Text width in pixels.
+ double textWidth ( void ) const;
+
+ // Text height in pixels.
+ double textHeight ( void ) const;
+
+ // Maximum horizontal advance in pixels.
+ double maxHorizontalAdvance ( void ) const;
+
+ };
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/gm-188x120t.png b/www/Magick++/gm-188x120t.png
new file mode 100644
index 0000000..a2b22f4
--- /dev/null
+++ b/www/Magick++/gm-188x120t.png
Binary files differ
diff --git a/www/Magick++/index.html b/www/Magick++/index.html
new file mode 100644
index 0000000..5f88a2d
--- /dev/null
+++ b/www/Magick++/index.html
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick++ API for GraphicsMagick</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-api-for-graphicsmagick">
+<h1 class="title">Magick++ API for GraphicsMagick</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
+<li><a class="reference internal" href="#api" id="id2">API</a></li>
+<li><a class="reference internal" href="#obtaining-magick" id="id3">Obtaining Magick++</a></li>
+<li><a class="reference internal" href="#installation" id="id4">Installation</a></li>
+<li><a class="reference internal" href="#usage" id="id5">Usage</a></li>
+<li><a class="reference internal" href="#reporting-bugs" id="id6">Reporting Bugs</a></li>
+</ul>
+</div>
+<div class="section" id="introduction">
+<h1><a class="toc-backref" href="#id1">Introduction</a></h1>
+<p><em>Magick++</em> is the object-oriented C++ API to the <a class="reference external" href="../index.html">GraphicsMagick</a>
+image-processing library, the most comprehensive open-source image
+processing package available. Read the <a class="reference external" href="ChangeLog.html">ChangeLog</a> for <em>Magick++</em>.</p>
+<p><em>Magick++</em> supports an object model which is inspired by <a class="reference external" href="../perl.html">PerlMagick</a>.
+Images support implicit reference counting so that copy constructors and
+assignment incur almost no cost. The cost of actually copying an image
+(if necessary) is done just before modification and this copy is managed
+automatically by <em>Magick++</em>. De-referenced copies are automatically
+deleted. The image objects support value (rather than pointer) semantics
+so it is trivial to support multiple generations of an image in memory at
+one time.</p>
+<p><em>Magick++</em> provides integrated support for the <a class="reference external" href="http://www.sgi.com/tech/stl/">Standard Template
+Library</a> (<cite>STL</cite>) which is part of the standard C++ language so that
+the powerful containers available (e.g. <a class="reference external" href="http://www.sgi.com/tech/stl/Deque.html">deque</a>, <a class="reference external" href="http://www.sgi.com/tech/stl/Vector.html">vector</a>, <a class="reference external" href="http://www.sgi.com/tech/stl/List.html">list</a>, and
+<a class="reference external" href="http://www.sgi.com/tech/stl/Map.html">map</a>) can be used to write programs similar to those possible with
+PERL &amp; <a class="reference external" href="../perl.html">PerlMagick</a>. STL-compatible template versions of
+GraphicsMagick's list-style operations are provided so that operations
+may be performed on multiple images stored in STL containers.</p>
+</div>
+<div class="section" id="api">
+<h1><a class="toc-backref" href="#id2">API</a></h1>
+<p><em>Magick++</em> provides a simple C++ API to the GraphicsMagick image
+processing library which supports reading and writing a huge number of
+image formats as well as supporting a broad spectrum of traditional image
+processing operations. The GraphicsMagick C API is complex and the data
+structures are not well documented. <em>Magick++</em> provides access to most of
+the features available from the C API but in a simple object-oriented and
+well-documented framework.</p>
+<p><em>Magick++</em> is intended to support commercial-grade application
+development. In order to avoid possible conflicts with the user's
+application, all symbols contained in <em>Magick++</em> (included by the header
+&lt;Magick++.h&gt;) are scoped to the namespace Magick. Symbols from the
+GraphicsMagick C library are imported under the MagickLib namespace to
+avoid possible conflicts and GraphicsMagick macros are only included
+within the <em>Magick++</em> implementation so they won't impact the user's
+application.</p>
+<p>The InitializeMagick() function <em>MUST</em> be invoked before constructing
+any Magick++ objects. This used to be optional, but now it is
+absolutely required. This function initalizes semaphores and
+configuration information necessary for the software to work
+correctly. Failing to invoke InitializeMagick() is likely to lead to
+a program crash or thrown assertion. If the program resides in the
+same directory as the GraphicsMagick files, then argv[0] may be passed
+as an argument so that GraphicsMagick knows where its files reside,
+otherwise NULL may be passed and GraphicsMagick will try to use other
+means (if necessary).</p>
+<p>The core class in <em>Magick++</em> is the <a class="reference external" href="Image.html">Image</a> class. The <a class="reference external" href="Image.html">Image</a> class
+provides methods to manipulate a single image frame (e.g. a JPEG image).
+Standard Template Library (<a class="reference external" href="STL.html">STL</a>) compatible algorithms and function
+objects are provided in order to manipulate multiple image frames or to
+read and write file formats which support multiple image frames (e.g. GIF
+animations, MPEG animations, and Postscript files).</p>
+<p>The <a class="reference external" href="Image.html">Image</a> class supports reference-counted memory management which
+supports the semantics of an intrinsic variable type (e.g. 'int') with an
+extremely efficient operator = and copy constructor (only a pointer is
+assigned) while ensuring that the image data is replicated as required so
+that it the image may be modified without impacting earlier generations.
+Since the <a class="reference external" href="Image.html">Image</a> class manages heap memory internally, images are best
+allocated via C++ automatic (stack-based) memory allocation. This support
+allows most programs using <em>Magick++</em> to be written without using any
+pointers, simplifying the implementation and avoiding the risks of using
+pointers. When a program uses automatic memory allocation to allocate
+<em>Magick++</em> images, that aspect of the program becomes naturally
+exception-safe and thread-safe.</p>
+<p>The image class uses a number of supportive classes in order to specify
+arguments. Colors are specified via the <a class="reference external" href="Color.html">Color</a> class. Colors specified
+in X11-style string form are implicitly converted to the <a class="reference external" href="Color.html">Color</a> class.
+Geometry arguments (those specifying width, height, and/or x and y
+offset) are specified via the <a class="reference external" href="Geometry.html">Geometry</a> class. Similar to the <a class="reference external" href="Color.html">Color</a>
+class, geometries specified as an X11-style string are implicitly
+converted to the <a class="reference external" href="Geometry.html">Geometry</a> class. Two dimensional drawable objects are
+specified via the <a class="reference external" href="Drawable.html">Drawable</a> class. Drawable objects may be provided as
+a single object or as a list of objects to be rendered using the current
+image options. <a class="reference external" href="Montage.html">Montage</a> options (a montage is a rendered grid of
+thumbnails in one image) are specified via the <a class="reference external" href="Montage.html">Montage</a> class.</p>
+<p>Errors are reported using C++ exceptions derived from the <a class="reference external" href="Exception.html">Exception</a>
+class, which is itself derived from the standard C++ exception class.
+Exceptions are reported synchronous with the operation and are caught by
+the first matching try block as the stack is unraveled. This allows a
+clean coding style in which multiple related <em>Magick++</em> commands may be
+executed with errors handled as a unit rather than line-by-line. Since
+the <a class="reference external" href="Image.html">Image</a> object provides reference-counted memory management,
+unreferenced images on the stack are automatically cleaned up, avoiding
+the potential for memory leaks.</p>
+<p>For ease of access, the documentation for the available user-level
+classes is available via the following table:</p>
+<table border="1" class="docutils">
+<caption><em>Magick++</em> User-Level Classes</caption>
+<colgroup>
+<col width="18%" />
+<col width="82%" />
+</colgroup>
+<tbody valign="top">
+<tr><td><a class="reference external" href="Blob.html">Blob</a></td>
+<td>Binary Large OBject container.</td>
+</tr>
+<tr><td><a class="reference external" href="CoderInfo.html">CoderInfo</a></td>
+<td>Report information about supported image formats (use with
+<a class="reference external" href="STL.html#coderInfoList">coderInfoList</a>())</td>
+</tr>
+<tr><td><a class="reference external" href="Color.html">Color</a></td>
+<td>Color specification.</td>
+</tr>
+<tr><td><a class="reference external" href="Drawable.html">Drawable</a></td>
+<td>Drawable shape (for input to 'draw').</td>
+</tr>
+<tr><td><a class="reference external" href="Exception.html">Exception</a></td>
+<td>C++ exception objects.</td>
+</tr>
+<tr><td><a class="reference external" href="Geometry.html">Geometry</a></td>
+<td>Geometry specification.</td>
+</tr>
+<tr><td><a class="reference external" href="Image.html">Image</a></td>
+<td>Image frame. This is the primary object in <em>Magick++</em>.</td>
+</tr>
+<tr><td><a class="reference external" href="Montage.html">Montage</a></td>
+<td>Montage options for montageImages().</td>
+</tr>
+<tr><td><a class="reference external" href="Pixels.html">Pixels</a></td>
+<td>Low-level access to image pixels.</td>
+</tr>
+<tr><td><a class="reference external" href="STL.html">STL</a></td>
+<td>STL algorithms and function objects for operating on
+containers of image frames.</td>
+</tr>
+<tr><td><a class="reference external" href="TypeMetric.html">TypeMetric</a></td>
+<td>Container for font type metrics (use with
+<a class="reference external" href="Image.html#fonttypemetrics">Image::fontTypeMetrics</a>).</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="obtaining-magick">
+<h1><a class="toc-backref" href="#id3">Obtaining Magick++</a></h1>
+<p><em>Magick++</em> is included as part of <a class="reference external" href="../index.html">GraphicsMagick</a> source releases and may
+be retrieved via <a class="reference external" href="../download.html">ftp</a> or <a class="reference external" href="../Hg.html">Mercurial</a>.</p>
+</div>
+<div class="section" id="installation">
+<h1><a class="toc-backref" href="#id4">Installation</a></h1>
+<p>Installation is very easy since <em>Magick++</em> is part of <a class="reference external" href="../index.html">GraphicsMagick</a> and
+is built by default. Once <a class="reference external" href="../index.html">GraphicsMagick</a> is built, then <em>Magick++</em> is
+available for use.</p>
+</div>
+<div class="section" id="usage">
+<h1><a class="toc-backref" href="#id5">Usage</a></h1>
+<p>A helper script named <em>GraphicsMagick++-config</em> is installed in the same
+directory as the GraphicsMagick <em>gm</em> program under Unix which assists
+with recalling compilation options required to compile and link programs
+which depend on <em>Magick++</em>. For example, the following command will
+compile and link the source file example.cpp to produce the executable
+example (notice that quotes are backward quotes):</p>
+<pre class="literal-block">
+c++ -o example example.cpp `GraphicsMagick++-config --cppflags --cxxflags
+ --ldflags --libs`
+</pre>
+<p>Windows users may get started by manually editing a project file for one
+of the <em>Magick++</em> demo programs.</p>
+<p>It is necessary to initialize the GraphicsMagick library prior to
+using the <em>Magick++</em> library. This initialization is performed by
+passing the path to the GraphicsMagick DLLs (assumed to be in the same
+directory as your program) to the InitializeMagick() function
+call. This is commonly performed by providing the path to your program
+(argv[0]) as shown in the following example:</p>
+<pre class="literal-block">
+int main( int /*argc*/, char ** argv)
+{
+ InitializeMagick(*argv);
+</pre>
+<p>If you don't have the path to your executable, then pass NULL and
+usually the library will be found anyway. Besides helping to find the
+GraphicsMagick DLL/library and configuration files, InitializeMagick()
+initializes all of the semaphores and data necessary for a
+multi-threaded program to be completely thread safe. This step used
+to be optional, but it is now absolutely required. Failure to
+initialize GraphicsMagick will result in an application crash.</p>
+</div>
+<div class="section" id="reporting-bugs">
+<h1><a class="toc-backref" href="#id6">Reporting Bugs</a></h1>
+<p>Please report any bugs via the <a class="reference external" href="http://sourceforge.net/projects/graphicsmagick/">GraphicsMagick Bug Tracker</a>. Questions
+regarding usage should be directed to <a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">Bob Friesenhahn</a>.</p>
+<p>Copyright © Bob Friesenhahn 1999 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/Magick++/index.rst b/www/Magick++/index.rst
new file mode 100644
index 0000000..ac84d77
--- /dev/null
+++ b/www/Magick++/index.rst
@@ -0,0 +1,226 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+===============================
+Magick++ API for GraphicsMagick
+===============================
+
+.. _GraphicsMagick : ../index.html
+.. _ChangeLog : ChangeLog.html
+.. _`Standard Template Library` : http://www.sgi.com/tech/stl/
+.. _deque : http://www.sgi.com/tech/stl/Deque.html
+.. _vector : http://www.sgi.com/tech/stl/Vector.html
+.. _list : http://www.sgi.com/tech/stl/List.html
+.. _map : http://www.sgi.com/tech/stl/Map.html
+.. _ftp : ../download.html
+.. _Mercurial: ../Hg.html
+.. _PerlMagick : ../perl.html
+.. _`GraphicsMagick Bug Tracker` : http://sourceforge.net/projects/graphicsmagick/
+.. _`Bob Friesenhahn` : mailto:bfriesen@simple.dallas.tx.us
+
+.. _Blob : Blob.html
+.. _CoderInfo : CoderInfo.html
+.. _Color : Color.html
+.. _Drawable : Drawable.html
+.. _Exception : Exception.html
+.. _Geometry : Geometry.html
+.. _Image : Image.html
+.. _Montage : Montage.html
+.. _Pixels : Pixels.html
+.. _STL : STL.html
+.. _TypeMetric : TypeMetric.html
+.. _`Image::fontTypeMetrics` : Image.html#fonttypemetrics
+.. _`algorithms and function objects` : STL.html
+.. _`coderInfoList` : STL.html#coderInfoList
+
+.. contents::
+
+Introduction
+------------
+
+*Magick++* is the object-oriented C++ API to the GraphicsMagick_
+image-processing library, the most comprehensive open-source image
+processing package available. Read the ChangeLog_ for *Magick++*.
+
+*Magick++* supports an object model which is inspired by PerlMagick_.
+Images support implicit reference counting so that copy constructors and
+assignment incur almost no cost. The cost of actually copying an image
+(if necessary) is done just before modification and this copy is managed
+automatically by *Magick++*. De-referenced copies are automatically
+deleted. The image objects support value (rather than pointer) semantics
+so it is trivial to support multiple generations of an image in memory at
+one time.
+
+*Magick++* provides integrated support for the `Standard Template
+Library`_ (`STL`) which is part of the standard C++ language so that
+the powerful containers available (e.g. deque_, vector_, list_, and
+map_) can be used to write programs similar to those possible with
+PERL & PerlMagick_. STL-compatible template versions of
+GraphicsMagick's list-style operations are provided so that operations
+may be performed on multiple images stored in STL containers.
+
+API
+---
+
+*Magick++* provides a simple C++ API to the GraphicsMagick image
+processing library which supports reading and writing a huge number of
+image formats as well as supporting a broad spectrum of traditional image
+processing operations. The GraphicsMagick C API is complex and the data
+structures are not well documented. *Magick++* provides access to most of
+the features available from the C API but in a simple object-oriented and
+well-documented framework.
+
+*Magick++* is intended to support commercial-grade application
+development. In order to avoid possible conflicts with the user's
+application, all symbols contained in *Magick++* (included by the header
+<Magick++.h>) are scoped to the namespace Magick. Symbols from the
+GraphicsMagick C library are imported under the MagickLib namespace to
+avoid possible conflicts and GraphicsMagick macros are only included
+within the *Magick++* implementation so they won't impact the user's
+application.
+
+The InitializeMagick() function *MUST* be invoked before constructing
+any Magick++ objects. This used to be optional, but now it is
+absolutely required. This function initalizes semaphores and
+configuration information necessary for the software to work
+correctly. Failing to invoke InitializeMagick() is likely to lead to
+a program crash or thrown assertion. If the program resides in the
+same directory as the GraphicsMagick files, then argv[0] may be passed
+as an argument so that GraphicsMagick knows where its files reside,
+otherwise NULL may be passed and GraphicsMagick will try to use other
+means (if necessary).
+
+The core class in *Magick++* is the `Image`_ class. The `Image`_ class
+provides methods to manipulate a single image frame (e.g. a JPEG image).
+Standard Template Library (`STL`_) compatible algorithms and function
+objects are provided in order to manipulate multiple image frames or to
+read and write file formats which support multiple image frames (e.g. GIF
+animations, MPEG animations, and Postscript files).
+
+The `Image`_ class supports reference-counted memory management which
+supports the semantics of an intrinsic variable type (e.g. 'int') with an
+extremely efficient operator = and copy constructor (only a pointer is
+assigned) while ensuring that the image data is replicated as required so
+that it the image may be modified without impacting earlier generations.
+Since the `Image`_ class manages heap memory internally, images are best
+allocated via C++ automatic (stack-based) memory allocation. This support
+allows most programs using *Magick++* to be written without using any
+pointers, simplifying the implementation and avoiding the risks of using
+pointers. When a program uses automatic memory allocation to allocate
+*Magick++* images, that aspect of the program becomes naturally
+exception-safe and thread-safe.
+
+The image class uses a number of supportive classes in order to specify
+arguments. Colors are specified via the `Color`_ class. Colors specified
+in X11-style string form are implicitly converted to the `Color`_ class.
+Geometry arguments (those specifying width, height, and/or x and y
+offset) are specified via the `Geometry`_ class. Similar to the `Color`_
+class, geometries specified as an X11-style string are implicitly
+converted to the `Geometry`_ class. Two dimensional drawable objects are
+specified via the `Drawable`_ class. Drawable objects may be provided as
+a single object or as a list of objects to be rendered using the current
+image options. `Montage`_ options (a montage is a rendered grid of
+thumbnails in one image) are specified via the `Montage`_ class.
+
+Errors are reported using C++ exceptions derived from the `Exception`_
+class, which is itself derived from the standard C++ exception class.
+Exceptions are reported synchronous with the operation and are caught by
+the first matching try block as the stack is unraveled. This allows a
+clean coding style in which multiple related *Magick++* commands may be
+executed with errors handled as a unit rather than line-by-line. Since
+the `Image`_ object provides reference-counted memory management,
+unreferenced images on the stack are automatically cleaned up, avoiding
+the potential for memory leaks.
+
+For ease of access, the documentation for the available user-level
+classes is available via the following table:
+
+
+.. table:: *Magick++* User-Level Classes
+
+ +-------------+----------------------------------------------------------+
+ |`Blob`_ |Binary Large OBject container. |
+ +-------------+----------------------------------------------------------+
+ |`CoderInfo`_ |Report information about supported image formats (use with|
+ | |`coderInfoList`_\(\)) |
+ +-------------+----------------------------------------------------------+
+ |`Color`_ |Color specification. |
+ +-------------+----------------------------------------------------------+
+ |`Drawable`_ |Drawable shape (for input to 'draw'). |
+ +-------------+----------------------------------------------------------+
+ |`Exception`_ |C++ exception objects. |
+ +-------------+----------------------------------------------------------+
+ |`Geometry`_ |Geometry specification. |
+ +-------------+----------------------------------------------------------+
+ |`Image`_ |Image frame. This is the primary object in *Magick++*. |
+ +-------------+----------------------------------------------------------+
+ |`Montage`_ |Montage options for montageImages(). |
+ +-------------+----------------------------------------------------------+
+ |`Pixels`_ |Low-level access to image pixels. |
+ +-------------+----------------------------------------------------------+
+ |`STL`_ |STL algorithms and function objects for operating on |
+ | |containers of image frames. |
+ +-------------+----------------------------------------------------------+
+ |`TypeMetric`_|Container for font type metrics \(use with |
+ | |`Image::fontTypeMetrics`_). |
+ +-------------+----------------------------------------------------------+
+
+Obtaining Magick++
+------------------
+
+*Magick++* is included as part of GraphicsMagick_ source releases and may
+be retrieved via `ftp`_ or `Mercurial`_.
+
+Installation
+------------
+
+Installation is very easy since *Magick++* is part of GraphicsMagick_ and
+is built by default. Once GraphicsMagick_ is built, then *Magick++* is
+available for use.
+
+Usage
+-----
+
+A helper script named *GraphicsMagick++-config* is installed in the same
+directory as the GraphicsMagick *gm* program under Unix which assists
+with recalling compilation options required to compile and link programs
+which depend on *Magick++*. For example, the following command will
+compile and link the source file example.cpp to produce the executable
+example (notice that quotes are backward quotes)::
+
+ c++ -o example example.cpp `GraphicsMagick++-config --cppflags --cxxflags
+ --ldflags --libs`
+
+Windows users may get started by manually editing a project file for one
+of the *Magick++* demo programs.
+
+It is necessary to initialize the GraphicsMagick library prior to
+using the *Magick++* library. This initialization is performed by
+passing the path to the GraphicsMagick DLLs (assumed to be in the same
+directory as your program) to the InitializeMagick() function
+call. This is commonly performed by providing the path to your program
+(argv[0]) as shown in the following example::
+
+ int main( int /*argc*/, char ** argv)
+ {
+ InitializeMagick(*argv);
+
+If you don't have the path to your executable, then pass NULL and
+usually the library will be found anyway. Besides helping to find the
+GraphicsMagick DLL/library and configuration files, InitializeMagick()
+initializes all of the semaphores and data necessary for a
+multi-threaded program to be completely thread safe. This step used
+to be optional, but it is now absolutely required. Failure to
+initialize GraphicsMagick will result in an application crash.
+
+Reporting Bugs
+--------------
+
+Please report any bugs via the `GraphicsMagick Bug Tracker`_. Questions
+regarding usage should be directed to `Bob Friesenhahn`_.
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| Bob Friesenhahn 1999 - 2017
+
diff --git a/www/Magick++/montage-sample-framed.jpg b/www/Magick++/montage-sample-framed.jpg
new file mode 100644
index 0000000..56197cc
--- /dev/null
+++ b/www/Magick++/montage-sample-framed.jpg
Binary files differ
diff --git a/www/Magick++/right_triangle.png b/www/Magick++/right_triangle.png
new file mode 100644
index 0000000..8deb402
--- /dev/null
+++ b/www/Magick++/right_triangle.png
Binary files differ
diff --git a/www/Magick++/thumbnail-anatomy-framed.fig b/www/Magick++/thumbnail-anatomy-framed.fig
new file mode 100644
index 0000000..f447acb
--- /dev/null
+++ b/www/Magick++/thumbnail-anatomy-framed.fig
@@ -0,0 +1,40 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+Letter
+100.00
+Single
+0
+1200 2
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4800 1200 4350 2250
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 5775 1200 5325 2025
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6525 4275 5250 4575
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3825 1200 3600 1875
+2 5 0 1 -1 -1 2 0 -1 0.000 0 0 -1 0 0 5
+ 0 thumbnail-sample-framed.jpg
+ 2700 1800 6300 1800 6300 5385 2700 5385 2700 1800
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6525 3075 6150 3150
+2 2 0 1 0 7 10 0 -1 0.000 0 0 -1 0 0 5
+ 1650 600 7425 600 7425 6300 1650 6300 1650 600
+4 1 -1 0 0 16 10 0.0000 4 120 480 5775 975 Thumb\001
+4 1 -1 0 0 16 10 0.0000 4 105 435 5775 1155 Frame\001
+4 1 -1 0 0 16 14 0.0000 4 165 2160 4500 5700 FRAMED THUMBNAIL\001
+4 1 -1 0 0 16 10 0.0000 4 120 480 3825 975 Thumb\001
+4 1 -1 0 0 16 10 0.0000 4 120 465 3825 1155 Border\001
+4 1 -1 0 0 16 10 0.0000 4 135 435 4800 1140 Image\001
+4 1 -1 0 0 16 10 0.0000 4 120 480 4800 975 Thumb\001
+4 1 -1 0 0 16 10 0.0000 4 120 480 6900 3000 Thumb\001
+4 1 -1 0 0 16 10 0.0000 4 120 570 6900 3180 Shadow\001
+4 1 -1 0 0 16 10 0.0000 4 120 480 6900 4200 Thumb\001
+4 1 -1 0 0 16 10 0.0000 4 120 390 6900 4380 Label\001
diff --git a/www/Magick++/thumbnail-anatomy-framed.jpg b/www/Magick++/thumbnail-anatomy-framed.jpg
new file mode 100644
index 0000000..a27e719
--- /dev/null
+++ b/www/Magick++/thumbnail-anatomy-framed.jpg
Binary files differ
diff --git a/www/Magick++/thumbnail-anatomy-plain.fig b/www/Magick++/thumbnail-anatomy-plain.fig
new file mode 100644
index 0000000..95bff11
--- /dev/null
+++ b/www/Magick++/thumbnail-anatomy-plain.fig
@@ -0,0 +1,35 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+Letter
+100.00
+Single
+-3
+1200 2
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3825 1200 3600 1875
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4950 1200 4575 2100
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6000 3900 4950 4350
+2 5 0 1 -1 -1 2 0 -1 0.000 0 0 -1 0 0 5
+ 0 thumbnail-sample-plain.jpg
+ 2700 1800 5850 1800 5850 4935 2700 4935 2700 1800
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6000 3075 5250 3375
+2 2 0 1 0 7 10 0 -1 0.000 0 0 -1 0 0 5
+ 1800 600 6900 600 6900 6000 1800 6000 1800 600
+4 1 -1 0 0 16 14 0.0000 4 165 1875 4275 5250 PLAIN THUMBNAIL\001
+4 1 -1 0 0 16 10 0.0000 4 120 480 3825 975 Thumb\001
+4 1 -1 0 0 16 10 0.0000 4 120 465 3825 1155 Border\001
+4 1 -1 0 0 16 10 0.0000 4 135 435 4950 1140 Image\001
+4 1 -1 0 0 16 10 0.0000 4 120 480 4950 975 Thumb\001
+4 1 -1 0 0 16 10 0.0000 4 120 570 6300 3180 Shadow\001
+4 1 -1 0 0 16 10 0.0000 4 120 480 6300 3000 Thumb\001
+4 1 -1 0 0 16 10 0.0000 4 120 390 6300 4005 Label\001
+4 1 -1 0 0 16 10 0.0000 4 120 480 6300 3825 Thumb\001
diff --git a/www/Magick++/thumbnail-anatomy-plain.jpg b/www/Magick++/thumbnail-anatomy-plain.jpg
new file mode 100644
index 0000000..011949a
--- /dev/null
+++ b/www/Magick++/thumbnail-anatomy-plain.jpg
Binary files differ
diff --git a/www/Magick++/thumbnail-sample-framed.jpg b/www/Magick++/thumbnail-sample-framed.jpg
new file mode 100644
index 0000000..dcab0a7
--- /dev/null
+++ b/www/Magick++/thumbnail-sample-framed.jpg
Binary files differ
diff --git a/www/Magick++/thumbnail-sample-plain.jpg b/www/Magick++/thumbnail-sample-plain.jpg
new file mode 100644
index 0000000..3ce49c8
--- /dev/null
+++ b/www/Magick++/thumbnail-sample-plain.jpg
Binary files differ
diff --git a/www/Makefile.am b/www/Makefile.am
new file mode 100644
index 0000000..5cfdde3
--- /dev/null
+++ b/www/Makefile.am
@@ -0,0 +1,326 @@
+# Copyright (C) 2008 - 2017 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building HTML files
+#
+
+WWWDIR=$(top_srcdir)/www
+
+# Install HTML files
+DOCDIRS = www www/api www/images www/Magick++ www/wand
+HTML_INSTALL_DATA_TARGETS = install-data-html
+install-data-html:
+ $(mkinstalldirs) $(DESTDIR)$(htmldir)
+ @for dir in $(DOCDIRS) ; do \
+ $(mkinstalldirs) $(DESTDIR)$(htmldir)/$$dir && \
+ for file in $(srcdir)/$$dir/*.* ; do \
+ case $$file in \
+ *.c | *.css | *.gif | *.html | *.ico | *.jpg | *.png ) \
+ echo "$(INSTALL_DATA) $$file $(DESTDIR)$(htmldir)/$$dir" ; \
+ $(INSTALL_DATA) "$$file" $(DESTDIR)$(htmldir)/$$dir ; \
+ ;; \
+ esac \
+ done ; \
+ done
+
+# Uninstall HTML files
+HTML_UNINSTALL_DATA_TARGETS = uninstall-data-html
+# rm -f $(DESTDIR)$(htmldir)/index.html
+uninstall-data-html:
+ for dir in $(DOCDIRS) ; do \
+ rm -f -r $(DESTDIR)$(htmldir)/$$dir ; \
+ done
+
+# These files are built from reStructuredText
+RST2HTML_TARGETS = \
+ $(WWWDIR)/ChangeLog-2001.html \
+ $(WWWDIR)/ChangeLog-2002.html \
+ $(WWWDIR)/ChangeLog-2003.html \
+ $(WWWDIR)/ChangeLog-2004.html \
+ $(WWWDIR)/ChangeLog-2005.html \
+ $(WWWDIR)/ChangeLog-2006.html \
+ $(WWWDIR)/ChangeLog-2007.html \
+ $(WWWDIR)/ChangeLog-2008.html \
+ $(WWWDIR)/ChangeLog-2009.html \
+ $(WWWDIR)/ChangeLog-2010.html \
+ $(WWWDIR)/ChangeLog-2011.html \
+ $(WWWDIR)/ChangeLog-2012.html \
+ $(WWWDIR)/ChangeLog-2013.html \
+ $(WWWDIR)/ChangeLog-2014.html \
+ $(WWWDIR)/ChangeLog-2015.html \
+ $(WWWDIR)/ChangeLog-2016.html \
+ $(WWWDIR)/Changelog.html \
+ $(WWWDIR)/Changes.html \
+ $(WWWDIR)/Copyright.html \
+ $(WWWDIR)/FAQ.html \
+ $(WWWDIR)/Hg.html \
+ $(WWWDIR)/INSTALL-unix.html \
+ $(WWWDIR)/INSTALL-windows.html \
+ $(WWWDIR)/ImageMagickObject.html \
+ $(WWWDIR)/Magick++/Blob.html \
+ $(WWWDIR)/Magick++/ChangeLog.html \
+ $(WWWDIR)/Magick++/CoderInfo.html \
+ $(WWWDIR)/Magick++/Color.html \
+ $(WWWDIR)/Magick++/Drawable.html \
+ $(WWWDIR)/Magick++/Enumerations.html \
+ $(WWWDIR)/Magick++/Exception.html \
+ $(WWWDIR)/Magick++/FormatCharacters.html \
+ $(WWWDIR)/Magick++/Geometry.html \
+ $(WWWDIR)/Magick++/Image.html \
+ $(WWWDIR)/Magick++/ImageDesign.html \
+ $(WWWDIR)/Magick++/Montage.html \
+ $(WWWDIR)/Magick++/PixelPacket.html \
+ $(WWWDIR)/Magick++/Pixels.html \
+ $(WWWDIR)/Magick++/TypeMetric.html \
+ $(WWWDIR)/Magick++/index.html \
+ $(WWWDIR)/NEWS.html \
+ $(WWWDIR)/OpenMP.html \
+ $(WWWDIR)/README.html \
+ $(WWWDIR)/api/api.html \
+ $(WWWDIR)/authors.html \
+ $(WWWDIR)/benchmarks.html \
+ $(WWWDIR)/bugs.html \
+ $(WWWDIR)/contribute.html \
+ $(WWWDIR)/download.html \
+ $(WWWDIR)/formats.html \
+ $(WWWDIR)/index.html \
+ $(WWWDIR)/links.html \
+ $(WWWDIR)/miff.html \
+ $(WWWDIR)/mission.html \
+ $(WWWDIR)/motion-picture.html \
+ $(WWWDIR)/perl.html \
+ $(WWWDIR)/process.html \
+ $(WWWDIR)/programming.html \
+ $(WWWDIR)/project.html \
+ $(WWWDIR)/quantize.html \
+ $(WWWDIR)/reference.html \
+ $(WWWDIR)/security.html \
+ $(WWWDIR)/thanks.html \
+ $(WWWDIR)/tools.html \
+ $(WWWDIR)/utilities.html \
+ $(WWWDIR)/wand/wand.html
+
+# These files are existing reStructuredText files
+WWW_RST_FILES = \
+ $(WWWDIR)/Changes.rst \
+ $(WWWDIR)/FAQ.rst \
+ $(WWWDIR)/Hg.rst \
+ $(WWWDIR)/ImageMagickObject.rst \
+ $(WWWDIR)/Magick++/Blob.rst \
+ $(WWWDIR)/Magick++/CoderInfo.rst \
+ $(WWWDIR)/Magick++/Color.rst \
+ $(WWWDIR)/Magick++/Drawable.rst \
+ $(WWWDIR)/Magick++/Enumerations.rst \
+ $(WWWDIR)/Magick++/Exception.rst \
+ $(WWWDIR)/Magick++/FormatCharacters.rst \
+ $(WWWDIR)/Magick++/Geometry.rst \
+ $(WWWDIR)/Magick++/Image.rst \
+ $(WWWDIR)/Magick++/ImageDesign.rst \
+ $(WWWDIR)/Magick++/Montage.rst \
+ $(WWWDIR)/Magick++/PixelPacket.rst \
+ $(WWWDIR)/Magick++/Pixels.rst \
+ $(WWWDIR)/Magick++/TypeMetric.rst \
+ $(WWWDIR)/Magick++/index.rst \
+ $(WWWDIR)/OpenMP.rst \
+ $(WWWDIR)/api/api.rst \
+ $(WWWDIR)/authors.rst \
+ $(WWWDIR)/benchmarks.rst \
+ $(WWWDIR)/bugs.rst \
+ $(WWWDIR)/contribute.rst \
+ $(WWWDIR)/download.rst \
+ $(WWWDIR)/formats.rst \
+ $(WWWDIR)/index.rst \
+ $(WWWDIR)/links.rst \
+ $(WWWDIR)/miff.rst \
+ $(WWWDIR)/mission.rst \
+ $(WWWDIR)/motion-picture.rst \
+ $(WWWDIR)/perl.rst \
+ $(WWWDIR)/process.rst \
+ $(WWWDIR)/programming.rst \
+ $(WWWDIR)/project.rst \
+ $(WWWDIR)/quantize.rst \
+ $(WWWDIR)/reference.rst \
+ $(WWWDIR)/security.rst \
+ $(WWWDIR)/thanks.rst \
+ $(WWWDIR)/tools.rst \
+ $(WWWDIR)/utilities.rst
+
+# These are the HTML files which are packaged
+WWW_HTML_FILES = \
+ $(WWWDIR)/ChangeLog-2001.html \
+ $(WWWDIR)/ChangeLog-2002.html \
+ $(WWWDIR)/ChangeLog-2003.html \
+ $(WWWDIR)/ChangeLog-2004.html \
+ $(WWWDIR)/ChangeLog-2005.html \
+ $(WWWDIR)/ChangeLog-2006.html \
+ $(WWWDIR)/ChangeLog-2007.html \
+ $(WWWDIR)/ChangeLog-2008.html \
+ $(WWWDIR)/ChangeLog-2009.html \
+ $(WWWDIR)/ChangeLog-2010.html \
+ $(WWWDIR)/ChangeLog-2011.html \
+ $(WWWDIR)/ChangeLog-2012.html \
+ $(WWWDIR)/ChangeLog-2013.html \
+ $(WWWDIR)/ChangeLog-2014.html \
+ $(WWWDIR)/ChangeLog-2015.html \
+ $(WWWDIR)/ChangeLog-2016.html \
+ $(WWWDIR)/Changelog.html \
+ $(WWWDIR)/Changes.html \
+ $(WWWDIR)/Copyright.html \
+ $(WWWDIR)/FAQ.html \
+ $(WWWDIR)/GraphicsMagick.html \
+ $(WWWDIR)/Hg.html \
+ $(WWWDIR)/INSTALL-unix.html \
+ $(WWWDIR)/INSTALL-windows.html \
+ $(WWWDIR)/ImageMagickObject.html \
+ $(WWWDIR)/ImageMagickObject.rst \
+ $(WWWDIR)/Magick++/Blob.html \
+ $(WWWDIR)/Magick++/ChangeLog.html \
+ $(WWWDIR)/Magick++/CoderInfo.html \
+ $(WWWDIR)/Magick++/Color.html \
+ $(WWWDIR)/Magick++/Drawable.html \
+ $(WWWDIR)/Magick++/Enumerations.html \
+ $(WWWDIR)/Magick++/Exception.html \
+ $(WWWDIR)/Magick++/FormatCharacters.html \
+ $(WWWDIR)/Magick++/Geometry.html \
+ $(WWWDIR)/Magick++/Image.html \
+ $(WWWDIR)/Magick++/ImageDesign.html \
+ $(WWWDIR)/Magick++/Montage.html \
+ $(WWWDIR)/Magick++/PixelPacket.html \
+ $(WWWDIR)/Magick++/Pixels.html \
+ $(WWWDIR)/Magick++/TypeMetric.html \
+ $(WWWDIR)/Magick++/index.html \
+ $(WWWDIR)/NEWS.html \
+ $(WWWDIR)/OpenMP.html \
+ $(WWWDIR)/README.html \
+ $(WWWDIR)/animate.html \
+ $(WWWDIR)/api/api.html \
+ $(WWWDIR)/authors.html \
+ $(WWWDIR)/benchmarks.html \
+ $(WWWDIR)/bugs.html \
+ $(WWWDIR)/color.html \
+ $(WWWDIR)/compare.html \
+ $(WWWDIR)/composite.html \
+ $(WWWDIR)/conjure.html \
+ $(WWWDIR)/contribute.html \
+ $(WWWDIR)/convert.html \
+ $(WWWDIR)/display.html \
+ $(WWWDIR)/docutils-api.css \
+ $(WWWDIR)/docutils-articles.css \
+ $(WWWDIR)/download.html \
+ $(WWWDIR)/formats.html \
+ $(WWWDIR)/gm.html \
+ $(WWWDIR)/identify.html \
+ $(WWWDIR)/import.html \
+ $(WWWDIR)/index.html \
+ $(WWWDIR)/links.html \
+ $(WWWDIR)/miff.html \
+ $(WWWDIR)/mission.html \
+ $(WWWDIR)/mogrify.html \
+ $(WWWDIR)/montage.html \
+ $(WWWDIR)/motion-picture.html \
+ $(WWWDIR)/perl.html \
+ $(WWWDIR)/process.html \
+ $(WWWDIR)/programming.html \
+ $(WWWDIR)/project.html \
+ $(WWWDIR)/quantize.html \
+ $(WWWDIR)/reference.html \
+ $(WWWDIR)/security.html \
+ $(WWWDIR)/thanks.html \
+ $(WWWDIR)/tools.html \
+ $(WWWDIR)/utilities.html\
+ $(WWWDIR)/wand/wand.html
+
+WWWW_EXTRA_DIST=$(WWW_HTML_FILES) $(WWW_RST_FILES)
+
+WWW_MAINTAINER_TARGETS=$(WWW_HTML_FILES) $(WWWDIR)/color.html
+
+if MAINTAINER_MODE
+
+NAMED_COLORS=$(top_srcdir)/scripts/named_colors.py
+RST2HTMLDECO=$(top_srcdir)/scripts/rst2htmldeco.py
+RELPATH=$(top_srcdir)/scripts/relpath.py
+OMP_DECIMAL_ALIGN=$(top_srcdir)/scripts/omp_decimal_align.py
+RST2HTML_COMMAND = $(RST2HTMLDECO) --cloak-email-addresses --link-stylesheet=docutils-articles.css
+
+$(RST2HTML_TARGETS) : \
+ $(top_srcdir)/scripts/html_fragments.py \
+ $(top_srcdir)/scripts/rst2htmldeco.py \
+ $(top_srcdir)/scripts/omp_decimal_align.py \
+ $(WWWDIR)/Makefile.am
+
+# Build HTML version of RST file
+$(top_srcdir)/www/%.html: $(top_srcdir)/%.txt
+ $(RST2HTMLDECO) --link-stylesheet=`$(RELPATH) $(top_srcdir)/www $@`docutils-articles.css \
+ --url-prefix=`$(RELPATH) $(top_srcdir)/www $@` $< $@
+
+$(top_srcdir)/%.html: $(top_srcdir)/%.rst
+ $(RST2HTMLDECO) --link-stylesheet=`$(RELPATH) $(top_srcdir)/www $@`docutils-articles.css \
+ --url-prefix=`$(RELPATH) $(top_srcdir)/www $@` $< | $(OMP_DECIMAL_ALIGN) > $@
+
+#
+# Build HTML version of ChangeLogs
+#
+CHANGELOG2RST=$(top_srcdir)/scripts/changelog2rst.sh
+
+$(top_srcdir)/www/Changelog.rst: $(top_srcdir)/ChangeLog
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2016.rst: $(top_srcdir)/ChangeLog.2016
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2015.rst: $(top_srcdir)/ChangeLog.2015
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2014.rst: $(top_srcdir)/ChangeLog.2014
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2013.rst: $(top_srcdir)/ChangeLog.2013
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2012.rst: $(top_srcdir)/ChangeLog.2012
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2011.rst: $(top_srcdir)/ChangeLog.2011
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2010.rst: $(top_srcdir)/ChangeLog.2010
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2009.rst: $(top_srcdir)/ChangeLog.2009
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2008.rst: $(top_srcdir)/ChangeLog.2008
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2007.rst: $(top_srcdir)/ChangeLog.2007
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2006.rst: $(top_srcdir)/ChangeLog.2006
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2005.rst: $(top_srcdir)/ChangeLog.2005
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2004.rst: $(top_srcdir)/ChangeLog.2004
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2003.rst: $(top_srcdir)/ChangeLog.2003
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2002.rst: $(top_srcdir)/ChangeLog.2002
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/ChangeLog-2001.rst: $(top_srcdir)/ChangeLog.2001
+ $(CHANGELOG2RST) < $^ > $@
+
+$(top_srcdir)/www/Magick++/ChangeLog.rst: $(top_srcdir)/Magick++/ChangeLog
+ $(CHANGELOG2RST) < $^ > $@
+
+# Build color.html
+$(WWWDIR)/color.html : $(NAMED_COLORS)
+ $(NAMED_COLORS) > $@
+
+endif # MAINTAINER_MODE
diff --git a/www/NEWS.html b/www/NEWS.html
new file mode 100644
index 0000000..8f00e47
--- /dev/null
+++ b/www/NEWS.html
@@ -0,0 +1,3295 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick News</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-news">
+<h1 class="title">GraphicsMagick News</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>This file was last updated on July 4, 2017</p>
+<p>Please note that this file records news for the associated development
+branch and that each development branch has its own NEWS file. See the
+ChangeLog file for full details.</p>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#july-4-2017" id="id4">1.3.26 (July 4, 2017)</a></li>
+<li><a class="reference internal" href="#september-5-2016" id="id5">1.3.25 (September 5, 2016)</a></li>
+<li><a class="reference internal" href="#may-30-2016" id="id6">1.3.24 (May 30, 2016)</a></li>
+<li><a class="reference internal" href="#november-7-2015" id="id7">1.3.23 (November 7, 2015)</a></li>
+<li><a class="reference internal" href="#october-4-2015" id="id8">1.3.22 (October 4, 2015)</a></li>
+<li><a class="reference internal" href="#february-28-2015" id="id9">1.3.21 (February 28, 2015)</a></li>
+<li><a class="reference internal" href="#august-16-2014" id="id10">1.3.20 (August 16, 2014)</a></li>
+<li><a class="reference internal" href="#december-31-2013" id="id11">1.3.19 (December 31, 2013)</a></li>
+<li><a class="reference internal" href="#march-10-2013" id="id12">1.3.18 (March 10, 2013)</a></li>
+<li><a class="reference internal" href="#october-13-2012" id="id13">1.3.17 (October 13, 2012)</a></li>
+<li><a class="reference internal" href="#june-24-2012" id="id14">1.3.16 (June 24, 2012)</a></li>
+<li><a class="reference internal" href="#april-28-2012" id="id15">1.3.15 (April 28, 2012)</a></li>
+<li><a class="reference internal" href="#february-25-2012" id="id16">1.3.14 (February 25, 2012)</a></li>
+<li><a class="reference internal" href="#december-24-2011" id="id17">1.3.13 (December 24, 2011)</a></li>
+<li><a class="reference internal" href="#march-8-2010" id="id18">1.3.12 (March 8, 2010)</a></li>
+<li><a class="reference internal" href="#february-21-2010" id="id19">1.3.11 (February 21, 2010)</a></li>
+<li><a class="reference internal" href="#february-10-2010" id="id20">1.3.10 (February 10, 2010)</a></li>
+<li><a class="reference internal" href="#february-4-2010" id="id21">1.3.9 (February 4, 2010)</a></li>
+<li><a class="reference internal" href="#january-21-2010" id="id22">1.3.8 (January 21, 2010)</a></li>
+<li><a class="reference internal" href="#september-17-2009" id="id23">1.3.7 (September 17, 2009)</a></li>
+<li><a class="reference internal" href="#july-25-2009" id="id24">1.3.6 (July 25, 2009)</a></li>
+<li><a class="reference internal" href="#january-26-2009" id="id25">1.3.5 (January 26, 2009)</a></li>
+<li><a class="reference internal" href="#january-13-2009" id="id26">1.3.4 (January 13, 2009)</a></li>
+<li><a class="reference internal" href="#december-9-2008" id="id27">1.3.3 (December 9, 2008)</a></li>
+<li><a class="reference internal" href="#november-29-2008" id="id28">1.3.2 (November 29, 2008)</a></li>
+<li><a class="reference internal" href="#november-17-2008" id="id29">1.3.1 (November 17, 2008)</a></li>
+<li><a class="reference internal" href="#november-9-2008" id="id30">1.3 (November 9, 2008)</a></li>
+<li><a class="reference internal" href="#april-29-2008" id="id31">1.2 (April 29, 2008)</a></li>
+<li><a class="reference internal" href="#released-april-4-2004" id="id32">1.1 (Released April 4, 2004)</a></li>
+<li><a class="reference internal" href="#released-in-may-2003" id="id33">1.0 (Released in May, 2003)</a></li>
+</ul>
+</div>
+<div class="section" id="july-4-2017">
+<h1><a class="toc-backref" href="#id4">1.3.26 (July 4, 2017)</a></h1>
+<p>Special Issues:</p>
+<ul class="simple">
+<li>None</li>
+</ul>
+<p>Security Fixes:</p>
+<ul class="simple">
+<li>DPX: Fix excessive use of memory (DOS issue) due to file header
+claiming large image dimensions but insufficient backing
+data. (CVE-2017-10799).</li>
+<li>JNG: Fix memory leak when reading invalid JNG image (CVE-2017-8350).</li>
+<li>MAT: Fix excessive use of memory (DOS issue) due to continuing
+processing with insufficient data and claimed large image
+size. Verify each file extent to make sure that it is within range
+of file size. (CVE-2017-10800).</li>
+<li>META: Fix heap overflow while parsing 8BIM chunk (CVE-2016-7800).</li>
+<li>PCX: Fix denial of service issue.</li>
+<li>RLE: Fix abnomally slow operation (denial of service issue) with
+intentionally corrupt colormapped file.</li>
+<li>PICT: Fix possible buffer overflow vulnerability given suitably
+truncated input file.</li>
+<li>PNG: Enforce spec requirement that the dimensions of the JPEG
+embedded in a JDAT chunk must match the JHDR dimensions
+(CVE-2016-9830).</li>
+<li>PNG: Avoid NULL dereference when MAGN chunk processing fails.</li>
+<li>SCT: Fix stack-buffer read overflow (underflow?) while reading SCT
+header.</li>
+<li>SGI: Fix denial of service issues. Delay large memory allocations
+until file header has fully passed sanity checks.</li>
+<li>TIFF: Fix out of bounds read when reading CMYKA TIFF which claims to
+have only 2 samples per pixel (CVE-2017-6335).</li>
+<li>TIFF: Fix out of bounds read when reading RGB TIFF which claims to
+have only 1 sample per pixel (CVE-2017-10794).</li>
+<li>WPG: Fix heap overflow (CVE-2016-7996). Fix assertion crash
+(CVE-2016-7997).</li>
+</ul>
+<p>Bug fixes:</p>
+<ul class="simple">
+<li>DifferenceImage(): Fix Fix all-black difference image if an input
+file is colormapped.</li>
+<li>EXIF orientation was not being properly detected for some files.</li>
+<li>-frame: The <cite>import</cite> command -frame handling was improperly
+implemented and was using already freed data.</li>
+<li>GIF: Fixes for &quot;Excessive LZW string data&quot; problem.</li>
+<li>Magick++: Bug fixes to PathSmoothCurvetoRel::operator() and
+PathSmoothCurvetoRel::operator().</li>
+<li>PAM: Support writing GRAYSCALE PAM format.</li>
+<li>PNG: Fix memory leaks.</li>
+<li>SVG: Fixed a memory leak. Fixed a possible null pointer dereference.</li>
+<li>TclMagick: Problem that TkMagick could not resolve functions from
+TclMagick under Linux is fixed.</li>
+<li>TclMagick: Fix parser validatation in magickCmd() to avoid crash
+given a syntax error.</li>
+<li>TIFF: Fix for reading old JPEG files (avoids &quot;Improper call to JPEG
+library in state 0. (LibJpeg).&quot;).</li>
+<li>TXT: Fixed memory leak.</li>
+<li>XCF: Error checking is improved.</li>
+</ul>
+<p>New Features:</p>
+<ul>
+<li><p class="first">EXIF rotation: Support is added such that the EXIF orientation tag
+is updated when the image is rotated.</p>
+</li>
+<li><p class="first">MAT: Now support reading multiple images from Matlab V4 format.</p>
+</li>
+<li><p class="first">Magick++: Orientation method now updates orientation in EXIF
+profile, if it exists.</p>
+</li>
+<li><p class="first">Magick++: Added Image attribute method which accepts a 'char <a href="#id1"><span class="problematic" id="id2">*</span></a>'
+argument, and will remove the attribute if the value argument is
+NULL.</p>
+<div class="system-message" id="id1">
+<p class="system-message-title">System Message: WARNING/2 (<tt class="docutils">/home/bfriesen/src/graphics/GM/NEWS.txt</tt>, line 114); <em><a href="#id2">backlink</a></em></p>
+<p>Inline emphasis start-string without end-string.</p>
+</div>
+</li>
+<li><p class="first">-orient: The -orient command line option now also updates the
+orientation in the EXIF profile, if it exists.</p>
+</li>
+<li><p class="first">PGX: Support PGX JPEG 2000 format for reading and writing (within
+the bounds of what JasPer supports).</p>
+</li>
+<li><p class="first">Wand API: Added MagickAutoOrientImage(),
+MagickGetImageOrientation(), MagickSetImageOrientation(),
+MagickRemoveImageOption(), and MagickClearException().</p>
+</li>
+</ul>
+<p>Feature improvements:</p>
+<ul class="simple">
+<li>None</li>
+</ul>
+<p>Windows Delegate Updates/Additions:</p>
+<ul class="simple">
+<li>TIFF: Updated to libtiff 4.0.8.</li>
+</ul>
+<p>Build Changes:</p>
+<ul class="simple">
+<li>TclMagick: Updated configure to use latest TEA tcl.m4 version 3.10.
+Support for AM_DISTCHECK_CONFIGURE_FLAGS so that 'make distcheck'
+remembers configuration options, and also to uninstall pkgIndex.tcl.</li>
+<li>VisualMagick Configure: A 'quantum' command line argument is added
+to set the default quantum depth in the wizard drop-down list. This
+This allows setting the quantum depth when the /nowizard argument
+was supplied.</li>
+</ul>
+<p>Behavior Changes:</p>
+<ul class="simple">
+<li>The installer for the Windows build no longer includes IMDisplay
+(simple display program), ImageMagickDLL, and PerlMagick for
+ActiveState Perl. These are still available to build from the
+source tree. All of these depend on proprietary components.</li>
+</ul>
+</div>
+<div class="section" id="september-5-2016">
+<h1><a class="toc-backref" href="#id5">1.3.25 (September 5, 2016)</a></h1>
+<p>Special Issues:</p>
+<ul class="simple">
+<li>None</li>
+</ul>
+<p>Security Fixes:</p>
+<ul class="simple">
+<li>EscapeParenthesis(): I was notified by Gustavo Grieco of a heap
+overflow in EscapeParenthesis() used in the text annotation code.
+While not being able to reproduce the issue, the implementation of
+this function is completely redone. This issue was assigned
+CVE-2016-7447 after the release.</li>
+<li>Utah RLE: Reject truncated/absurd files which caused huge memory
+allocations and/or consumed huge CPU. Problem was reported by
+Agostino Sarubbo based on testing with AFL. This issue was assigned
+CVE-2016-7448 after the release.</li>
+<li>SVG/MVG: Fix another case of CVE-2016-2317 (heap buffer overflow) in
+the MVG rendering code (also impacts SVG). This issue (remaining
+part) was assigned CVE-2016-7446 after the release.</li>
+<li>TIFF: Fix heap buffer read overflow while copying sized TIFF
+attributes. Problem was reported by Agostino Sarubbo based on
+testing with AFL. This issue was assigned CVE-2016-7449 after the
+release.</li>
+</ul>
+<p>Bug fixes:</p>
+<ul class="simple">
+<li>GetToken(): Fix obscure bug (read beyond end of string buffer)
+noticed while parsing a MVG file. This problem was reported by
+Gustavo Grieco.</li>
+<li>MVG rendering: Fix undesired hard errors when some objects were
+drawn outside of the image bounds. Requests to draw objects
+entirely outside of the image should be silently ignored.</li>
+<li>MVG/SVG rendering: Fix gradient size sanity checks which were
+causing gradient requests to fail. Due to a design weakness in that
+gradient images allocate resources rather than being computations at
+point of use, the maximum gradient image size is now hard-limited to
+5000x5000 pixels until the design problem is fixed. Some SVG icons
+(as small as 8x8 pixels) authored using Inkscape request absurdly
+huge gradients. Gradient sizes as large as 20,000x20,000 have been
+observed in SVG icon files delivered by packages on an Ubuntu Linux
+system.</li>
+<li>SVG: Fix some memory leaks which occur on parsing error.</li>
+</ul>
+<p>New Features:</p>
+<ul class="simple">
+<li>None</li>
+</ul>
+<p>Feature improvements:</p>
+<ul class="simple">
+<li>ElapsedTime(): Use clock_gettime() (when available with default
+linkage) to obtain elapsed time.</li>
+<li>DescribeImage(): Provide 6 digits of seconds precision in in elapsed
+time output. Previously the resolution was rounded up to a full
+second.</li>
+</ul>
+<p>Windows Delegate Updates/Additions:</p>
+<ul class="simple">
+<li>webp: Updated bundled libwebp to release 0.5.1.</li>
+<li>libxml: Updated bundled libxml2 to release 2.9.4.</li>
+<li>lcms: Updated bundled lcms2 to release 2.8.</li>
+<li>png: Update bundled libpng to release 1.6.24.</li>
+</ul>
+<p>Build Changes:</p>
+<ul class="simple">
+<li>OpenMP is properly configured for clang 3.8 using its own '-lomp'
+rather than '-lgomp'.</li>
+</ul>
+<p>Behavior Changes:</p>
+<ul class="simple">
+<li>SVG: Some SVG files may be rejected due to absurdly large gradient
+requests.</li>
+<li>The 'identify' and 'info' functionality only shows the pixel read
+rate if image was not read in 'ping' mode. Provide 6 digits of
+seconds precision in in elapsed time output.</li>
+</ul>
+</div>
+<div class="section" id="may-30-2016">
+<h1><a class="toc-backref" href="#id6">1.3.24 (May 30, 2016)</a></h1>
+<p>Special Issues:</p>
+<ul class="simple">
+<li>A shell exploit (CVE-2016-5118) was discovered associated with a
+filename syntax where file names starting with '|' are intepreted as
+shell commands executed via popen(). Insufficient sanitization in
+the SVG and MVG renderers allows such filenames to be passed through
+from potentially untrusted files. There might be other ways for
+untrusted inputs to produce such filenames. Due to this issue,
+support for the feature is removed entirely.</li>
+<li>A shell exploit was discovered associated with the gnuplot delegate
+and which is triggered by the 'gplt' entry in delegates.mgk. A
+remote exploit is possible if the attacker can cause a provided SVG
+or MVG file to be rendered (or the user opens a provided file). The
+gnuplot program must be installed in order for the exploit to be
+successful. It is strongly recommended to remove this entry in all
+delegates.mgk files.</li>
+<li>Due to <a class="reference external" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967">GCC bug 53967</a>, several key agorithms (e.g. convolution)
+may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+enabled for floating point math (<cite>-mfpmath=sse</cite>) if the GCC option
+<cite>-frename-registers</cite> is used. Default 32-bit builds do not
+experience the problem since they use '387 math. It is not clear in
+what version of GCC this problem started but it was not noticed by
+the developers until the GCC 4.6 timeframe. Other compilers do not
+suffer from this bug. Please lobby the GCC project to fix this
+embarrassing performance bug.</li>
+</ul>
+<p>Security Fixes:</p>
+<ul class="simple">
+<li>BLOB: Remove support for reading input from a shell command, or
+writing output to a shell command, by prefixing the specified
+filename (containing the command) with a '|'. This feature provided
+a remote shell execution opportunity.</li>
+<li>DIB: Fixed out of bounds reads. Added more header validations.</li>
+<li>JNG: File size limits are enforced.</li>
+<li>MAT: Fixed denial of service opportunity. Fix hang on corrupt deflate stream.</li>
+<li>META: Fixed out of bounds reads and writes.</li>
+<li>MIFF: Fixed thrown assertion.</li>
+<li>MSL: Ignore the file extension on MSL files. It is necessary to add
+a &quot;msl:&quot; prefix to MSL files to read the as an image.</li>
+<li>MVG: No longer assume that files ending with extension &quot;.mvg&quot; are
+MVG files. MVG parsing does more validity checking on its input.
+Assure that enough PrimitiveInfo structures are allocated in advance
+to support a given vector path (heap overflow problem).</li>
+<li>PCX: Fixed unreasonable memory allocation due to intentionally
+corrupt file.</li>
+<li>PDB: Fixed a heap buffer overflow and out of bounds read.</li>
+<li>PICT: Fixed an out of bounds write.</li>
+<li>PS: Ghostscript is now always run with -dSAFER for safer execution.</li>
+<li>PSD: Fixed segmentation violations, heap buffer overflows, and out
+of bounds writes.</li>
+<li>RLE: Fixed out of bounds reads and writes.</li>
+<li>ReadImages(): Fixed a possible infinite recursion due to a crafted input file.</li>
+<li>RotateImage(): Fixed thrown assertion.</li>
+<li>SGI: Fixed out of bounds writes.</li>
+<li>SUN: Fixed out of bounds reads and writes.</li>
+<li>SVG: Fixed heap and stack buffer overflows, as well as segmentation
+violations (CVE-2016-2317 and CVE-2016-2318). Also fixed endless
+loop, unexpectedly large memory allocation, divide by zero, and
+recursion issues.</li>
+<li>TIFF: Fixed an assertion while reading. Fixed benign heap overflow.</li>
+<li>TMP: Adding a &quot;tmp:&quot; prefix to a filename no longer removes the file
+since this seems dangerous.</li>
+<li>VIFF: Fix excessive memory allocation with intentionally corrupted input file.</li>
+<li>XCF: Fixed a heap buffer overflow.</li>
+<li>XPM: Fixed several heap buffer overflows, and out of bound
+reads/writes. Also fixed a case of excessive memory allocation.</li>
+<li>delegate.mgk: The default delegate.mgk file has been pared down in
+order to reduce security exposure.</li>
+<li>gnuplot ('gplt' delegate in delegates.mgk): Support for rendering
+gnuplot files is removed since the format is inherently insecure.</li>
+<li>File names: File names starting with a '|' character are no longer
+interpreted as shell commands to be executed as input or output.</li>
+</ul>
+<p>Bug fixes:</p>
+<ul class="simple">
+<li>BMP: Fix reading 24-bit Microsoft BMP which claims to have a
+colormap.</li>
+<li>FILE: <cite>file://</cite> URLs are properly supported now (they never worked
+before).</li>
+<li>JP2: It is now possible to write lossless JPEG 2000 &quot;JP2&quot; format.</li>
+<li>SVG: Support font-size &quot;medium&quot;.</li>
+</ul>
+<p>New Features:</p>
+<ul class="simple">
+<li>Blob I/O C APIs: Added signed versions of short and long Read/Write
+functions.</li>
+<li>FILE: <cite>file://</cite> URLs are properly supported now (they never worked
+before).</li>
+<li>MAT: Matlab V4 is now partially supported.</li>
+<li>Magick++: Added double-precision xResolution() and yResolution()
+methods to support setting the horizontal and vertical resolution
+with double floating point precision.</li>
+<li>Mogrify now supports a -preserve-timestamp option to preserve file
+access and modification timestamps.</li>
+</ul>
+<p>Feature improvements:</p>
+<p>Windows Delegate Updates/Additions:</p>
+<ul class="simple">
+<li>Updated bundled libpng to release 1.6.19.</li>
+<li>Updated bundled libwebp to release 0.4.4.</li>
+<li>Update bundled libxml2 to release 2.9.3.</li>
+<li>Update bundled freetype to release 2.6.2.</li>
+</ul>
+<p>Build Changes:</p>
+<ul class="simple">
+<li>Added <tt class="docutils literal"><span class="pre">--enable-broken-coders</span></tt> configure option to enable file
+format support which may be broken or cause security issues. The
+PSD format is now classified as &quot;broken&quot; (until it is fixed).</li>
+</ul>
+<p>Behavior Changes:</p>
+<ul class="simple">
+<li>PSD format is not included in the build by default.</li>
+<li>Files ending with &quot;.mvg&quot; and &quot;.msl&quot; are not assumed to be image
+files by default.</li>
+<li>File names starting with '|' are no longer treated as shell
+commands.</li>
+<li>Gnuplot and POV delegate support is removed from the default
+delegate.mgk file.</li>
+</ul>
+</div>
+<div class="section" id="november-7-2015">
+<h1><a class="toc-backref" href="#id7">1.3.23 (November 7, 2015)</a></h1>
+<p>Special Issues:</p>
+<ul class="simple">
+<li>Due to <a class="reference external" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967">GCC bug 53967</a>, several key agorithms (e.g. convolution)
+may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+enabled for floating point math (<cite>-mfpmath=sse</cite>) if the GCC option
+<cite>-frename-registers</cite> is used. Default 32-bit builds do not
+experience the problem since they use '387 math. It is not clear in
+what version of GCC this problem started but it was not noticed by
+the developers until the GCC 4.6 timeframe. Other compilers do not
+suffer from this bug. Please lobby the GCC project to fix this
+embarrassing performance bug.</li>
+</ul>
+<p>Security Fixes:</p>
+<ul class="simple">
+<li>ScaleImage(): While not strictly a security issue, requesting to
+scale an image while retaining the original number of rows will lead
+to a program crash or memory corruption due to double-free.</li>
+</ul>
+<p>Bug fixes:</p>
+<ul class="simple">
+<li>ScaleImage(): Fix problem with new width/height match original
+(regression added by 1.3.22).</li>
+<li>ScaleImage(): Fix double-free when new rows matches original rows
+(regression added by 1.3.22).</li>
+<li>MinGW build fix related to eliminating a sleep() macro which
+conflicts with a MinGW-provided inline sleep() function.</li>
+<li>PNG: Issue a warning instead of an error when attempting to read a
+PNG file containing a zero-length profile. This allows the file to
+be read.</li>
+<li>identify: Fix problem in that <cite>identify -format &quot;%A&quot;</cite> (to test if
+transparency is supported in image) does not always produce the
+correct results.</li>
+</ul>
+<p>New Features:</p>
+<ul class="simple">
+<li>None.</li>
+</ul>
+<p>Feature improvements:</p>
+<ul class="simple">
+<li>None.</li>
+</ul>
+<p>Performance Improvements:</p>
+<ul class="simple">
+<li>None.</li>
+</ul>
+<p>Windows Delegate Updates/Additions:</p>
+<ul class="simple">
+<li>None.</li>
+</ul>
+<p>Build Changes:</p>
+<ul class="simple">
+<li>Configure: Removed CFLAGS and LDFLAGS deduplication code which
+caused problems for user-provided CFLAGS and LDFLAGS which added and
+then removed compiler/linker options. Specifically, this fixes a
+problem with creating OS X universal builds.</li>
+<li>Configure: Add tests for 'ps2write' and 'eps2write' which are
+available in recent Ghostscript.</li>
+</ul>
+<p>Behavior Changes:</p>
+<ul class="simple">
+<li>None</li>
+</ul>
+</div>
+<div class="section" id="october-4-2015">
+<h1><a class="toc-backref" href="#id8">1.3.22 (October 4, 2015)</a></h1>
+<p>Thanks:</p>
+<ul class="simple">
+<li>Coverity: We thank Coverity for providing free service for free
+software projects, and thank Jodie Cunningham for getting the
+project set up in Coverity.</li>
+</ul>
+<p>Special Issues:</p>
+<ul class="simple">
+<li>Due to <a class="reference external" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967">GCC bug 53967</a>, several key agorithms (e.g. convolution)
+may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+enabled for floating point math (<cite>-mfpmath=sse</cite>) if the GCC option
+<cite>-frename-registers</cite> is used. Default 32-bit builds do not
+experience the problem since they use '387 math. It is not clear in
+what version of GCC this problem started but it was not noticed by
+the developers until the GCC 4.6 timeframe. Other compilers do not
+suffer from this bug. Please lobby the GCC project to fix this
+embarrassing performance bug.</li>
+<li>Magick++: Any libraries or applications using Magick++ should be
+rebuilt in order to use this new release. Libraries and
+applications will be able to continue to use prior versions of
+Magick++ without being re-built, while benefiting from updated C
+libraries, provided that the system supports library versioning.</li>
+</ul>
+<p>Security Fixes:</p>
+<ul class="simple">
+<li>General Coverity fixes. Some might have security consequences.</li>
+<li>Ghostscript options concatenation is more secure against buffer
+overflow.</li>
+<li>Windows: Built-in random number generator is now salted using
+CryptGenRandom(). This improves the robustness of the temporary
+file allocator.</li>
+</ul>
+<p>Bug fixes:</p>
+<ul class="simple">
+<li>Coverity Fixes: Large amounts of fixes due to Coverity static
+analysis. See the ChangeLog and Mercurial for details. Coverity now
+reports zero issues.</li>
+<li>General: Fix problems with reading filenames that include a colon.</li>
+<li>General: Fixed performance problem with sub-image path extraction
+when there are many files in the directory.</li>
+<li>General: Add missing options in utility help messages.</li>
+<li>BMP: Reader was wrongly rejecting RLE-compressed files as being too
+small (regression added in 1.3.21 release).</li>
+<li>BMP: Fix inverted alpha channel when writing BGRA8888 format.</li>
+<li>DrawAffineImage(): Fix problem with negative x offset.</li>
+<li>DrawAffineImage(): Fix problem that sometimes output rows are skipped when using OpenMP.</li>
+<li>EXIF: Properly validate GPS_OFFSET.</li>
+<li>-format: %Q now reports JPEG quality estimate if it is available.</li>
+<li>-geometry: Fix handling of area geometries in the form &quot;5000000&#64;&quot;.</li>
+<li>MagickGetImageGravity(): Prototype was missing in header files.</li>
+<li>MIFF: Memory leak fixes.</li>
+<li>MIFF: MIFF reader failed to read some MIFF headers properly.</li>
+<li>MIFF: Detect buffer overrun attempt while reading zip compressed data.</li>
+<li>PDF: Set image frame scene ids appropriately.</li>
+<li>PNG: Memory leak fixes.</li>
+<li>PS: Set image frame scene ids appropriately.</li>
+<li>PTIF: Mark reduced frames as SubfileType 0x2 instead of 0x1.</li>
+<li>SetImageProfile(): Avoid crash given NULL profile pointer.</li>
+<li>TIFF: Fix reading Old JPEG and YCbCr sample images from libtiff
+pics-3.8.0.tar.gz image file collection.</li>
+<li>TIFF: Disable matte channel for compression types which don't
+support it.</li>
+<li>XPM: Memory leak fixes.</li>
+<li>XWD: Memory leak fixes.</li>
+</ul>
+<p>New Features:</p>
+<ul class="simple">
+<li>GRAYA: New subformat for gray coder which supports alpha channel.
+Format specifiers &quot;R&quot;, &quot;G&quot;, &quot;B&quot;, &quot;A&quot;, &quot;C&quot;, &quot;M&quot;, and &quot;Y&quot; may now be
+used to save and restore the associated channel using the same raw
+format as &quot;GRAY&quot;.</li>
+<li>Magick++: Image::repage() method added to support resetting 'page'.</li>
+<li>PDF: Added '-define pdf:stop-on-error=true' optoin to cause PDF
+reading to quit immediately upon any error.</li>
+<li>Subframe specification: Now specific PS and PDF pages may be
+selected, including re-ordering.</li>
+</ul>
+<p>Feature improvements:</p>
+<ul class="simple">
+<li>PALM: Still a work in progress. Closer to working using netpbm's
+implementation as a reference.</li>
+</ul>
+<p>Performance Improvements:</p>
+<ul class="simple">
+<li>None.</li>
+</ul>
+<p>Windows Delegate Updates/Additions:</p>
+<ul class="simple">
+<li>dcraw: Update bundled dcraw to release 9.26.0.</li>
+<li>lcms: Update bundled lcms2 to release 2.7.</li>
+<li>png: Updated bundled libpng to release 1.6.17.</li>
+<li>tiff: Update bundled libtiff to release 4.0.6.</li>
+<li>ttf: Update bundled freetype to release 2.6.</li>
+<li>webp: Updated bundled libwebp to release 0.4.3.</li>
+<li>libxml: Update bundled libxml2 to release 2.9.2.</li>
+</ul>
+<p>Build Changes:</p>
+<ul class="simple">
+<li>lcms (&quot;Little CMS&quot;) v1 is no longer supported.</li>
+<li>VisualMagick: Remember and re-use already given paths.</li>
+</ul>
+<p>Behavior Changes:</p>
+<p>Magick++: adaptiveThreshold() now accepts a 'double' value and the
+previous version of the method (using 'unsigned int') is deprecated.
+The STL function-object equivalent of the deprecated method is removed
+entirely.</p>
+</div>
+<div class="section" id="february-28-2015">
+<h1><a class="toc-backref" href="#id9">1.3.21 (February 28, 2015)</a></h1>
+<p>Thanks:</p>
+<blockquote>
+<ul class="simple">
+<li>Gynvael Coldwind and Mateusz Jurczyk of the Google Security Team
+provided test files which allowed us to find and fix security
+problems in the software.</li>
+<li>Hanno Böck provided test files which allowed us to find and fix
+security problems in the software.</li>
+<li>Tobias Ospelt provided test files and advice which allowed us to
+find and fix security problems in the software.</li>
+<li>Michal Zalewski provided test files which allowed us to find and
+fix security problems in the software.</li>
+<li>Jodie Cunningham did lots of fuzzing to find issues and set up the
+project on Coverity for automatic analysis.</li>
+<li><a class="reference external" href="http://lcamtuf.coredump.cx/afl/">American fuzzy lop</a> was used to produce and discover many of the
+files which caused problems for the software.</li>
+<li><a class="reference external" href="https://code.google.com/p/address-sanitizer/">AddressSanitizer</a> (ASan) was used to detect and isolate memory
+access issues.</li>
+<li><a class="reference external" href="http://www.valgrind.org/">Valgrind</a> was used to detect and isolate memory access issues as
+well as memory leaks</li>
+</ul>
+</blockquote>
+<p>Special Issues:</p>
+<blockquote>
+<ul class="simple">
+<li>Due to <a class="reference external" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967">GCC bug 53967</a>, several key agorithms (e.g. convolution)
+may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+enabled for floating point math (<cite>-mfpmath=sse</cite>) if the GCC option
+<cite>-frename-registers</cite> is used. Default 32-bit builds do not
+experience the problem since they use '387 math. It is not clear
+in what version of GCC this problem started but it was not noticed
+by the developers until the GCC 4.6 timeframe. Other compilers do
+not suffer from this bug. Please lobby the GCC project to fix
+this embarrassing performance bug.</li>
+<li>Magick++: Any libraries or applications using Magick++ should be
+rebuilt in order to use this new release. Libraries and
+applications will be able to continue to use prior versions of
+Magick++ without being re-built, while benefiting from updated C
+libraries, provided that the system supports library versioning.</li>
+</ul>
+</blockquote>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Annotate: Some requestable text-substitution attributes caused a
+crash.</li>
+<li>All formats: Image dimensions are checked to assure that they are
+within limits before proceeding to read the image.</li>
+<li>BMP: Fix hang (endless loop) for certain files.</li>
+<li>DCM: Fix crash as well as small heap over-write.</li>
+<li>DPX: Fix crash due to DPX file reporting more elements than it
+has.</li>
+<li>MNG: Validate MHDR chunk length to avoid huge memory allocation
+and DOS.</li>
+<li>PCX: Fix for CVE-2014-8355. Validate file header in order to avoid
+buffer overun later.</li>
+<li>PDB: Detect arithmetic overflows when calculating buffer sizes.
+Fix crash in writer when image width is not even multiple of 16.
+Fix buffer overrun with 2 and 4-bit PDB image files.</li>
+<li>PNM: Validate PGM, PPM, and PAM header MaxValue parameter to avoid
+crash on poorly-formed input.</li>
+<li>PNG: Impose a 10-million limit on dimensions when reading a PNG
+file to avoid denial of service.</li>
+<li>PSD: Avoid problems caused by huge PSD colormap size.</li>
+<li>PSD: Fix small stack over-write if more than 99 layers are written
+to PSD format.</li>
+<li>PSD: Returns immediately if pixel limit was exceeded.</li>
+<li>RLE: URT RLE reader is now more robust with errant files.</li>
+<li>SUN: Header validation is now made fully robust, and arithmetic
+overflows in buffer-size calculations are detected to avoid heap
+overwrite.</li>
+<li>TIFF: Fix crashes for photometrics which may deliver one or three
+samples per pixel (was assuming always three).</li>
+<li>VIFF: Fixes to prevent buffer overflow. Validate colormap indexes.</li>
+<li>Windows delegates: Fix unexpected argument splitting when invoking
+an external delegate program via delegates.mgk.</li>
+<li>WPG: Fix use of NULL pointers. Fix buffer overflows.</li>
+<li>XPM: Detect truncated row and quit with error rather than
+over-running a buffer.</li>
+<li>XWD: Improve header validation. Added to UnstableCoderClass since
+the reader for this format should not be entrusted with
+untrustworthy input.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>CIN: Fix problem with text attribute values which are not NULL
+terminated. Validate sizes claimed by Cineon header.</li>
+<li>Coverity: Fixes for many issues detected by Coverity scan (see
+ChangeLog).</li>
+<li>DPX: Fix problem with text attribute values which are not NULL
+terminated.</li>
+<li>DPX: Fix severe corruption of little-endian 32-bit packed output.
+Corruption was severe enough that it would have been noticed
+immediately.</li>
+<li>Delegates: Fix possible memory leaks when invoking external
+application.</li>
+<li>FITS: Properly validate values provided by file header.</li>
+<li>GIF: Fix use of uninitialized data.</li>
+<li>JBIG: Fix memory leaks.</li>
+<li>JNG: Fix double-free error in error path.</li>
+<li>JPEG: Verify the number of output components before attempting to
+decode the image.</li>
+<li>Magick++: Image resolutionUnits() was not always returning correct
+value.</li>
+<li>Magick++: Locking has not been working properly since the code was
+written in 1998. Apparently the issue has not been significant
+enough to cause run-time issues.</li>
+<li>ICO: Windows icon reader is now much more robust.</li>
+<li>MIFF: Reader now quits with an error if zip or bzip2 stream is
+corrupted.</li>
+<li>MAT: Fix memory leaks.</li>
+<li>PALM: Reader now reads various input formats (up to version 2)
+correctly whereas it was crashing or otherwise malfunctioning
+before. More work remains, particularly in the writer.</li>
+<li>PCX: Eliminate memory leaks in error paths.</li>
+<li>PDB: In PDB writer, void possible under-allocation due to
+arthimetic overflow when allocating packets.</li>
+<li>PICT: Fix PICT reader crash with corrupted file.</li>
+<li>PNG: Fix double-free error in error path.</li>
+<li>PNG: Fixed handling of transparency when writing indexed PNG.</li>
+<li>PNG: Avoid reading beyond the end of a tEXt keyword.</li>
+<li>PSD: Fix error when reading PSDs files which have no layers.</li>
+<li>RLA: Fix possible crash due to file header.</li>
+<li>Signal Handling: Signal handling is now more robust and handles
+SIGSEGV and other critical signals. The sole purpose of the
+default signal handling is to remove any temporary files and quit.
+An informative message is printed for signals other than SIGINT.</li>
+<li>SUN: Sun raster reader was not completely robust. Now it is.</li>
+<li>SWF: Fix pixel cache access errors in 'ping' mode.</li>
+<li>Text annotation: An empty text string is no longer treated as an
+error.</li>
+<li>Text annotation: Fix regression added in 1.3.19 which caused
+spurious drawing errors to be produced while rendering with text
+when all of the text is off the left-hand side of the image.</li>
+<li>TIFF: Fix unreliable reading JBIG compressed files by forcing use
+of strip reader rather than sometimes using scanline reader (which
+libtiff's JBIG codec does not support).</li>
+<li>TIFF: Fix reading or writing planar min-is-white or min-is-black
+images with an associated alpha channel.</li>
+<li>WebP: WebP writer now writes truely lossless output when
+requested.</li>
+<li>identify / GetImageStatistics(): Failed to compute statistics for
+the Black channel of CMYK image files.</li>
+<li>VICAR: Fix problem with continuing to &quot;read&quot; data when there is no
+more data left to read.</li>
+<li>WMF: Fix memory leaks.</li>
+<li>WPG: Fix potential DOS due to long reads during an error
+condition.</li>
+<li>XPM: Avoid strncpy() of overlapping memory. Fixed memory leaks in
+error paths. Fixed bad memory access caused by empty file.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>compose: Supports composite operator names similar to the major
+*Magick brand, without losing any compatibility with previous
+naming.</li>
+<li>ICO: Windows ICO reader now supports reading PNG-encoded files.</li>
+<li>Magick++ Geometry: New methods limitPixels() and fillArea() to
+support '&#64;' and '^' geometry qualifiers. This enhancement breaks
+the ABI due to previous use of inline methods and no place to put
+the new flags.</li>
+<li>Magick++ Image::extent(): New method to place image on sized
+canvas of constant color using gravity.</li>
+<li>Magick++ Image::formatExpression(): New method format a string
+based on a format similar to command-line -format.</li>
+<li>Magick++ Image::resize(): New method to resize image specifying
+geometry, filter, and blur.</li>
+<li>Magick++ STL extentImage: New function object to invoke image
+extent method.</li>
+<li>Magick++ Image::quiet(). New method which blocks (ignores)
+warning exceptions when passed a 'true' argument.</li>
+<li>Resource limits: Added support for image Width and Height limits.
+Default image Width and Height limits are based on the range of a
+32-bit signed integer, even for 64-bit builds which may have
+sufficient numeric range to image an entire galaxy. Limits may be
+increased as desired.</li>
+<li>TIFF: Use define tiff:ignore-tags to ignore tags in 'corrupted'
+files with unknown and invalid tags. Use to read TIFF files which
+otherwise can not be read due to errors.</li>
+<li>TIFF: Use '-define tiff:report-warnings=true' to enable that
+warnings reported by libtiff are thrown as warning exceptions so
+that they may be caught or will be reported at the gm
+command-line.</li>
+<li>Windows Exceptions: A handler is registered (due to calling
+InitializeMagick()) to capture Windows Exceptions in a similar
+manner to the existing POSIX signal handler. If an application is
+using the library and wants to provide its own Windows exception
+handling, then it should make any changes after invoking
+InitializeMagick().</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Windows Delegate Updates/Additions:</p>
+<blockquote>
+<ul class="simple">
+<li>PNG: Update bundled libpng to 1.6.16. Resolves known security
+issues.</li>
+<li>FreeType: Update bundled Freetype to 2.5.4. Resolves known
+security issues.</li>
+<li>WebP: Update bundled WebP to 0.4.2 release.</li>
+<li>WebP is auto-linked in Visual Studio.</li>
+</ul>
+</blockquote>
+<p>Build Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>WebP is not included in the build when building with Visual Studio
+6 (1998 vintage compiler!) since it requires more modern C.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>AVI: Support for this format is removed since the implementation
+was worthless.</li>
+<li>TIFF: Now uses YCbCr encoding when JPEG compression is requested
+for an RGB image.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="august-16-2014">
+<h1><a class="toc-backref" href="#id10">1.3.20 (August 16, 2014)</a></h1>
+<p>Special Issues:</p>
+<blockquote>
+<ul class="simple">
+<li>Due to <a class="reference external" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967">GCC bug 53967</a>, several key agorithms (e.g. convolution)
+may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+enabled for floating point math (<cite>-mfpmath=sse</cite>) if the GCC option
+<cite>-frename-registers</cite> is used. Default 32-bit builds do not
+experience the problem since they use '387 math. It is not clear
+in what version of GCC this problem started but it was not noticed
+by the developers until the GCC 4.6 timeframe. Other compilers do
+not suffer from this bug. Please lobby the GCC project to fix
+this embarrassing performance bug.</li>
+</ul>
+</blockquote>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>No security issues were reported or fixed.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Compilation: No longer undefine __attribute__ since this may be
+used by system or compiler headers and cause problems.</li>
+<li>BMP: Alpha channel from BMP3 format was inverted.</li>
+<li>PNG: Fix round-trip repeatability issue (due to rounding
+algorithm) with modern versions of libpng. Prefer the less
+accurate method which does not alter the image.</li>
+<li>PNG: Fix some memory leaks in error-handling paths.</li>
+<li>PNM: Scaling of alpha in sub-ranged pixels is fixed.</li>
+<li>Wand API: Removed development debug fprintf which causes each
+drawing primitive to be printed to stderr.</li>
+<li>PS, PS2, PS3, PDF: Only use resolution from image or -density if
+units were properly specified. Without units, resolution is
+worthless.</li>
+<li>PS, PS2, PS3, PDF: Use resolution from image if it appears to be
+valid.</li>
+<li>WebP: Fix inverted return status which caused failure to be
+reported instead of success.</li>
+<li>Rotation clipping/shearing errors for short wide images at some
+angles are fixed.</li>
+<li>-geometry: Deal with resize geometry missing width or height
+(e.g. '640x' or 'x480') by substituting the missing value with one
+which preserves the image aspect ratio. This has been documented
+to be supported since almost the dawn of GraphicsMagick but was
+not actually supported until now.</li>
+<li>-geometry: Support '&gt;' and '&lt;' qualifiers with '&#64;' qualifier to
+specify if image should be resized if larger or lesser than given
+area specification.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>Wand API: MagickSetImageGravity() - New function to set image
+gravity.</li>
+<li>Wand API: MagickGetImageGravity() - New function to get image
+gravity.</li>
+<li>Wand API: MagickSetImageMatte() - New function to set the image
+matte channel enable flag.</li>
+<li>Wand API: MagickGetImageMatte() - New function to read the image
+matte channel enable flag.</li>
+<li>Wand API: MagickSetImageGeometry() - New function to set the image
+geometry string.</li>
+<li>Wand API: MagickGetImageGeometry() - New function to get the image
+geometry string.</li>
+<li>Wand API: MagickOperatorImageChannel() - New function to apply an
+operator to an image channel.</li>
+<li>Magick++ API: New Image::thumbnail() method for fast image
+resizing, particularly to make thumbnails.</li>
+<li>Core C API: Added SetLogMethod() to allow an application/library
+to specify a function to be called for logging.</li>
+<li>Clang/LLVM: Provide support for clang/llvm attribute and builtin
+specifiers similar to that provided for GCC.</li>
+<li>OpenMP: OpenMP native locking and thread specific data is
+supported via a configuration option (is not the default). This
+offers a &quot;pure&quot; OpenMP compilation mode. No real value for this
+compilation mode has been observed yet but it seems worthy to
+support.</li>
+<li>Coders: Added BrokenCoderClass to mark coders which often
+malfunction or are not very useful in their current condition.</li>
+<li>Composition: Added HardLight composition operator, which is now
+used by PSD and XCF formats, and available via command line,
+Magick++ API, PerlMagick API, and Wand API.</li>
+<li>Composition: Added ScreenCompositePixels composition operator.</li>
+<li>Composition: Added missing Photoshop separable compositing
+operations, Overlay, Exclusion, ColorBurn, ColorDodge, SoftLight,
+LinearBurn, LinearDodge, LinearLight, VividLight, PinLight,
+HardMix.</li>
+<li>+set: Command line utilities now support +set to remove an
+existing image attribute.</li>
+<li>-format: Support additional format specifiers 'g', 'A', 'C', 'D',
+'G', 'H', 'M', 'O', 'P', 'Q', 'T', 'U', 'W', 'X', and '&#64;', similar
+to the major brand.</li>
+<li>-operator: New quantum operators ThresholdBlackNegateQuantumOp and
+ThresholdWhiteNegateQuantumOp. These correspond to -operator
+&quot;Threshold-Black-Negate&quot; and &quot;Threshold-White-Negate&quot;.</li>
+<li>TIFF: Now support setting the TIFF &quot;Software&quot; tag for users who do
+not want to admit to using GraphicsMagick.</li>
+<li>WebP: All of the WebP encoder encoder options are now supported
+by -define arguments.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Pixel interpolation quality is greatly improved, with minimal
+impact on performance. Pixel interpolation now also works well
+given an alpha channel.</li>
+<li>WebP: WebP support is now prepared to compile with most WebP
+library versions and supports all features except for those
+pertaining to &quot;RIFF&quot; container support.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Non-integral image rotation performance has been improved by about
+40%, with lower memory usage as well.</li>
+<li>GradientImage: Update image is_grayscale and is_monochrome flags
+based on gradient color properties.</li>
+</ul>
+</blockquote>
+<p>Windows Delegate Updates/Additions:</p>
+<blockquote>
+<ul class="simple">
+<li>PNG: Libpng 1.6.12 - June 12, 2014.</li>
+<li>JPEG: libjpeg 9a of January 19, 2014.</li>
+<li>FreeType: FreeType 2.5.3 of March 6, 2014.</li>
+<li>WebP: webp 0.4.0 of January 20, 2013.</li>
+<li>zlib: zlib 1.2.8 of April 28, 2013.</li>
+</ul>
+</blockquote>
+<p>Build Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>--without-threads no longer disables use of OpenMP. Use the
+already existing option --disable-openmp to disable OpenMP.</li>
+<li>Makefiles: Include paths are now exceedingly pedantic to make sure
+that only the required directories are included.</li>
+<li>VisualMagick configure: Improve configure program so that it is
+possible to select QuantumDepth, OpenMP, and 64-bit build via
+configure dialog boxes as well as options on the command line.
+Also automatically detects and deals with similarly named files in
+subdirectories so that WebP support can now build successfully.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>MultiplyCompositePixels: Multiply composition now uses SVG
+interpretation of how alpha should be handled. No longer does a
+simple multiply of alpha channel.</li>
+<li>Composition: The Difference, Darken, Lighten, and HardLight
+composition operators were modified to support alpha in their
+computations.</li>
+<li>PNG: Using -optimize no longer triggers palette and depth
+optimizations since their implementations have been problematic.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="december-31-2013">
+<h1><a class="toc-backref" href="#id11">1.3.19 (December 31, 2013)</a></h1>
+<p>Special Issues:</p>
+<blockquote>
+<ul class="simple">
+<li>Due to <a class="reference external" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967">GCC bug 53967</a>, several key agorithms (e.g. convolution)
+may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+enabled for floating point math (<cite>-mfpmath=sse</cite>) if the GCC option
+<cite>-frename-registers</cite> is used. Default 32-bit builds do not
+experience the problem since they use '387 math. It is not clear
+in what version of GCC this problem started but it was not noticed
+by the developers until the GCC 4.6 timeframe. Other compilers do
+not suffer from this bug.</li>
+</ul>
+</blockquote>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>EPT: Fix crash observed when Ghostscript fails to produce useful
+output. This was particularly noticeable when Ghostscript was not
+installed. This crash could be used to cause denial of service.</li>
+<li>PNG: With libpng 1.6.X, avoid a crash while copying a PNG with a
+&quot;known incorrect ICC profile&quot;. This crash could be used to cause
+denial of service.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Build: Fix cross-compilation for MinGW64 on Linux build machine.</li>
+<li>Build: configure FreeType test no longer insists that
+&lt;freetype/freetype.h&gt; can be included.</li>
+<li>CMS profile: Only delete the CMS transform if it is non-null.
+Fixed assertion observed when lcms returned a null profile and
+GraphicsMagick attempted to deallocate it.</li>
+<li>Drawing: Improve error handling logic so that drawing returns
+quickly on pixel access errors rather than plowing on ahead. This
+avoids problems with SVGs which take seemingly forever to render.</li>
+<li>Drawing via C/C++ APIs: <cite>BevelJoin</cite> no longer causes a MVG parsing
+error.</li>
+<li>EPT: Fix crash observed when Ghostscript fails to produce useful
+output. This was particularly noticeable when Ghostscript was not
+installed.</li>
+<li>OpenMP: Revert use of omp_set_dynamic() since it caused
+performance issues when using GCC's GOMP implementation and the
+number of threads to use is specified.</li>
+<li>EXIF profile: Support the <cite>SubjectArea</cite> EXIF tag.</li>
+<li>MIFF writer: PseudoClass format was written incorrectly for depth
+greater than 8.</li>
+<li>MIFF writer: RLE compressed format used inverted alpha from the
+other subformats contrary to the MIFF specification.</li>
+<li>MIFF reader: Fixes to be able to read MIFF written by
+ImageMagick 6.X, including DirectClass grayscale images (except
+for RLE compressed).</li>
+<li>Mosaic: Fixed unsigned underflow problem with -mosaic when page
+offset is negative and exceeds image width or height, resulting in
+assertions, out of memory errors, or pixel cache limit errors.</li>
+<li>PDF: Consistently initialize Image page width and height to image
+width and height. While general to all of GraphicsMagick, this
+change is to assure that the PDF writer computes page dimensioning
+consistently. PDF page dimensioning was wrong if the image had
+been resized with -geometry &quot;100%&quot;.</li>
+<li>PAM: Fix MAXVAL scaling when reading PAM images. PAM was only
+working correctly for images with 256 or 64k levels.</li>
+<li>PNM: PGM &quot;P2&quot; format writer wrote bad output for 8-bit depth.</li>
+<li>PNG: With libpng 1.6.X, avoid a crash while copying a PNG with a
+&quot;known incorrect ICC profile&quot;.</li>
+<li>PNG: Q8 GM build now correctly reads 16-bit PNG files.</li>
+<li>TIFF writer: Try to avoid writing more than 32k strips per image
+by increasing rows-per-strip since some programs fail to read
+images with more than 32k strips per image.</li>
+<li>TIM reader: PSX TIM reports 8-bit depth (rather than 16).</li>
+<li>TTF font rendering: Improve FreeType rendering error logic so that
+rendering returns immediately on pixel access errors rather than
+plowing on ahead.</li>
+<li>TTF font rendering: Support rendering UTF-8 up to 21-bit code
+points. Was only supporting 16-bit code points.</li>
+<li>Wand API: DrawSetStrokeDashArray() / DrawGetStrokeDashArray(), fix
+failure to work properly due to this code path never being tested.</li>
+<li>Windows Ghostscript: 64-bit GraphicsMagick no longer requires both
+32-bit and 64-bit builds of Ghostscript to be installed in order
+to read Postscript and PDF formats.</li>
+<li>XPM reader: Reported depth now depends on the colormap rather than
+always claiming to be 16-bit.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>JPEG: Add support for writing 'XMP' profile.</li>
+<li>PNM: As a simple non-standard extension to the standard PNM and
+PAM formats, support writing and reading 32-bit sample depth.
+Writing such files is only supported by the Q32 build although
+they may be read by any build.</li>
+<li>WebP: Now supports reading and writing Google's WebP format. This
+feature is not currently supported by the Windows Visual Studio
+build.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Pixel composition based on BlendCompositePixel() is enhanced to
+completely eliminate under-color from the blending if the
+under-pixel is fully transparent. Also blends based on the
+average opacity of both pixels rather than only the over-pixel.
+This change did not result in any change in the GM test suite
+results but it is possible that there could be some negative
+impact from it. Please report any issues noticed which are due to
+this change.</li>
+<li>X11 <cite>display</cite>: For DirectClass image, use ThumbnailImage() rather
+than SampleImage() when creating the panner icon to improve the
+quality of the image.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>PNG: <cite>ping</cite> a PNG faster by avoiding reading the image data.</li>
+</ul>
+</blockquote>
+<p>Windows Delegate Updates:</p>
+<blockquote>
+<ul class="simple">
+<li>Updated IJG JPEG library to release 9.</li>
+<li>Updated PNG library to release 1.6.8.</li>
+<li>Updated lcms2 library to release 2.5.</li>
+<li>Updated libxml2 library to release 2.9.1.</li>
+<li>Updated FreeType library to release 2.5.2.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>MIFF: Now writes PseudoClass images correctly when depth is
+greater than 8. This impacts the reader, which will not be able
+to read previously written incorrect format correctly. Images
+like this should be very rare. The solution is to use an older
+GraphicsMagick version to convert such images to a valid storage
+format (with a depth of 8) so that they may be read with this
+version.</li>
+<li>MIFF: Now writes RLE-compressed RGBA images with correct
+alpha. This impacts the reader, which will not be able to read
+previously written incorrect format correctly. Images like this
+should be very rare. A solution is to use an older GraphicsMagick
+version to use a compression algorithm other than RLE so that they
+are read correctly with this version. Another solution is to
+process problematic images with '-operator Opacity Negate 0' to
+invert the alpha channel.</li>
+<li>TIFF: Returns DirectClass images by default for MINISWHITE and
+MINISBLACK TIFF formats (rather then colormapped).</li>
+<li>Windows: Also search c:gsfonts for Ghostscript font files. This
+search path is normally hard-coded into Ghostscript binaries and
+is a convenient place to put fonts so they may be shared by
+multiple Ghostscript versions.</li>
+<li>XPM: Now limits color resolution to 16-bits, even with Q32 build.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="march-10-2013">
+<h1><a class="toc-backref" href="#id12">1.3.18 (March 10, 2013)</a></h1>
+<p>Special Issues:</p>
+<blockquote>
+<ul class="simple">
+<li>Due to <a class="reference external" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53967">GCC bug 53967</a>, several key agorithms (e.g. convolution)
+may execute much faster (e.g. 2-3X) for x86-64 and/or when SSE is
+enabled for floating point math (<cite>-mfpmath=sse</cite>) if the GCC option
+<cite>-frename-registers</cite> is used. Default 32-bit builds do not
+experience the problem since they use '387 math. It is not clear
+in what version of GCC this problem started but it was not noticed
+by the developers until the GCC 4.6 timeframe. Other compilers do
+not suffer from this bug.</li>
+</ul>
+</blockquote>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed bug with format substitutions if input string ends with a
+single '%'.</li>
+<li>BMP: Fixed an old bug with decoding chromaticity primaries.</li>
+<li>PNG: Fixed reading of interlaced images. Fix reading of sub-8-bit
+palette and grayscale images. Some PNG sub-formats were written
+incorrectly. Fix crash in PNG8 writer if image colors happened to
+be non-zero but image was not actually colormapped.</li>
+<li>PNG: Configure script now also searches for libpng versions 16 and
+17.</li>
+<li>TIFF: Fix a crash which was noticed when writing RGBA separated
+(planar) format.</li>
+<li><cite>--enable-symbol-prefix</cite> was not prefixing all of the C
+symbols. Some core C library functions were not prefixed. This
+option applies to the Wand library API as well now.</li>
+<li>C API: When input is from a user-provided file descriptor, the
+file position is restored after reading the file header bytes.
+Previously the file position was rewound to the beginning of the
+file. This allows reading embedded image data from the current
+offset in a file, and allows continuing to use the stream after
+GraphicsMagick has returned the image.</li>
+<li>C API: It is now possible to invoke CloseBlob() multiple times.</li>
+<li>display: Display was supposed to respond to +/-usePixmap, but was
+not. It was responding to +/-use_pixmap. Now it responds to both.</li>
+<li>Windows/VisualMagick: Fix building GraphicsMagick with Intel ICC
+compiler driven by Visual Studio Professional 2012.</li>
+<li>Windows: Avoid a crash and produce a useful diagnostic if
+Ghostscript is needed but not yet installed.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>GM utility: New 'batch' command was contributed by Kenneth Xu
+which supports executing any number of other GM utility
+sub-commands in a single invocation in a sort of &quot;batch&quot; script.
+Input may be piped from standard input, from a specified file, or
+from a 'GM &gt;' command prompt. This utilities front-end allows any
+other program/script to drive 'gm' using a co-process model and
+speeds up execution by eliminating utility start-up/shut-down
+time.</li>
+<li>WIN64 (64-bit Windows): Windows 64-bit is now officially supported.</li>
+<li>convert/mogrify: Now support -auto-orient to automatically rotate
+the image upright for viewing based on its current orientation
+setting. Also support -orient to support setting the current
+image orientation. Please note that the orientation property of
+EXIF profiles is not yet updated so the EXIF profile will be wrong
+after using -auto-orient.</li>
+<li>C API: AutoOrientImage(), new function to automatically orient
+the image so that it is upright for normal viewing.</li>
+<li>Wand API: MagickGetImagePage()/MagickSetImagePage(), new functions
+to support getting and setting the image page size and offsets.</li>
+<li>PNG: Added PNG48 and PNG64 support. Added PNG00 support (png
+encoder that inherits its color-type and bit-depth from the input,
+if the input was a PNG datastream).</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>GraphicsMagick TAP tests may now be run stand-alone using Perl's
+'prove' TAP test driver.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Detection of glob specifications in file names is more efficient.</li>
+</ul>
+</blockquote>
+<p>Windows Delegate Updates:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>ltdl: Libltdl is no longer bundled. Libltdl must be previously
+installed on the system in order to build the modules
+configuration.</li>
+<li>AppendImages() now converts subsequent images to the colorspace of
+the first image, and no longer converts the first image to RGB.
+Instead, it is assumed the user knows what she/he is doing.</li>
+<li>SetImageColorRegion() no longer automatically converts the image
+to RGB. The user is responsible for assuring that the provided
+color is in the same colorspace as the image.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="october-13-2012">
+<h1><a class="toc-backref" href="#id13">1.3.17 (October 13, 2012)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>PNG: Fix for CVE-2012-3438. The Magick_png_malloc function in
+coders/png.c in GraphicsMagick 6.7.8-6 does not use the proper
+variable type for the allocation size, which might allow remote
+attackers to cause a denial of service (crash) via a crafted PNG
+file that triggers incorrect memory allocation.</li>
+<li>Automake (derived): Fix for CVE-2012-3386: The &quot;make distcheck&quot;
+rule in GNU Automake before 1.11.6 and 1.12.x before 1.12.2 grants
+world-writable permissions to the extraction directory, which
+introduces a race condition that allows local users to execute
+arbitrary code via unspecified vectors.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>PNG: Reading sub-8-bit palette images is fixed (images looked
+stretched).</li>
+<li>SVG: Fixed bug which allowed MVG and SVG files with long vector
+paths to crash the software.</li>
+<li>SVG: Ignore XML headers rather than rendering them as text.</li>
+<li>MVG/SVG/WMF/-draw: It is now possible to draw a plain ','
+character.</li>
+<li>WMF: Fixed a bug which caused wrong centered-text placement.</li>
+<li>import: Return status was inverted.</li>
+<li>configure: Don't force that liblzma is used just because libtiff
+is used.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>The configure script now supports a --enable-quantum-library-names
+option to enable that shared library name includes quantum depth
+to allow shared libraries with different quantum depths to
+co-exist in same directory (only one can be used for development).</li>
+<li>JNX: Support is added for reading the Garmin proprietary Image
+Format.</li>
+<li>BMP: Support an alpha channel in uncompressed 32-bit BMP.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li><cite>-lat</cite>: The adaptive threshold algorithm is replaced with a new
+algorithm which scales linearly (rather than quadratically) with
+area size.</li>
+<li>Tests: Test suite is re-written to use TAP-based tests.</li>
+<li>GIF: Reader tries to be better at detecting and reporting
+failures.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>-lat: Adaptive threshold is much faster with large area sizes.</li>
+</ul>
+</blockquote>
+<p>Windows Delegate Updates:</p>
+<blockquote>
+<ul class="simple">
+<li>Dcraw 9.16 is now included in the build (with JPEG and JPEG2000
+support).</li>
+<li>Libxml2 is updated to the 2.9.0 release.</li>
+<li>Libtiff is updated to the 4.0.3 release.</li>
+<li>Lcms2 is updated to the 2.4 release.</li>
+<li>Libpng is updated to the 1.5.13 release.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>Loading modules is only supported for the modules build.
+Previously any build using shared libraries could load modules.</li>
+<li>Bundled libltdl is now configured as 'installable' rather than
+'convenience'.</li>
+<li>-enhance: Only filter based on color channels (ignore opacity).</li>
+<li>BrowseDelegate: Web browser (for viewing help information) now
+defaults to 'xdg-open', but if it is not found, then configure
+will search for firefox, google-chrome, mozilla (in that order).</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="june-24-2012">
+<h1><a class="toc-backref" href="#id14">1.3.16 (June 24, 2012)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Don't translate 'comment' and 'label' attributes if the request is
+made while a file is being read. Only translate such attributes
+if they come from the command line or API user.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>SWT: SWT reader suffered from a number of implementation errors
+which caused it not to work any more. Works again.</li>
+<li>XBM: Fix memory leak observed when reading file in 'ping' mode.</li>
+<li>Support -trim on images which use a consistent (single color)
+transparent background. In this case, trim is done based on
+opacity rather than foreground color.</li>
+<li>Include &lt;sys/types.h&gt; in order to assure that 'size_t' and
+'ssize_t' are declared. This is necessary since
+MagickExtentImage() uses these types as part of its definition.</li>
+<li><cite>+repage</cite> was not working because parser was insisting that it
+should include an argument.</li>
+<li>-units was scaling existing resolution the wrong way around
+(i.e. multiplying rather than dividing).</li>
+<li>PerlMagick: Fix compilation with Perl 5.16.</li>
+<li>PingBlob(): PingBlob was not working for all cases. Is now based
+on BlobToImage() for assured reliability.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+None</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>MAT: Animated movies inside 4D matrices are loaded now.</li>
+<li>PDF: File base name is used as the document title.</li>
+<li>PNG: Fix issues observed specifically with libpng 1.5.10.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Pixel iterators should be more efficient now if the image uses a
+file-backed cache.</li>
+<li>Motion blur algorithm does scale well as cores are added so
+include OpenMP support for it by default.</li>
+</ul>
+</blockquote>
+<p>Windows Delegate Updates:</p>
+<blockquote>
+<ul class="simple">
+<li>JPEG: Updated to IJG 8d release.</li>
+<li>PNG: Updated to 1.5.11 release</li>
+<li>TIFF: Updated to 4.0.2 release.</li>
+<li>Zlib: Updated to 1.2.7 release.</li>
+<li>libxml2: Updated to 2.8.0 release.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+None</blockquote>
+</div>
+<div class="section" id="april-28-2012">
+<h1><a class="toc-backref" href="#id15">1.3.15 (April 28, 2012)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Libpng in Windows build is updated to 1.5.10 release. Provides a
+fix for CVE-2011-3048.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>PNG - fixed problem with bit depth when the encoder decides to
+write RGBA instead of indexed PNG.</li>
+<li>Fixed some temporary file leaks which were caused by the temporary
+file name being automatically extended to include a scene number,
+and therefore fail to be deleted.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>Added '+noise random' and '-operator noise-random' to 'convert'
+and 'mogrify'. This modulates the existing image data with
+uniformly random noise.</li>
+<li>Added -strip option in composite, convert, mogrify, and montage to
+remove all profiles and text attributes from the image.</li>
+<li>Added -repage option to composite, convert, mogrify, and montage
+subcommands to reset or adjust the current image page offsets
+based on a provided geometry specification.</li>
+<li>New C function StripImage() to remove all profiles and text
+attributes from the image.</li>
+<li>New C function ResetImagePage() to adjust the current image page
+canvas and position based on a relative page specification.</li>
+<li>C functions GenerateDifferentialNoise(), AddNoiseImageChannel(),
+QuantumOperatorRegionImage(), AddNoiseImage() updated to support
+RandomNoise enumeration.</li>
+<li>New C++ Image method strip(), and unary function stripImage() to
+remove all profiles and text attributes from the image.</li>
+<li>XCF format now respects image subimage and subrange members so
+that returned image layers may be selected.</li>
+<li>The INFO coder (e.g. output file &quot;info:-&quot;) now respects the
+-format option so that its output may be adjusted identically to
+how -format works for 'identify'.</li>
+<li>TclMagick now supports Random noise.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>C function ThumbnailImage() now allows the user to override the
+filter used, but still defaults to using the box filter.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>No longer add a printf-style scene formatting specification to
+filenames which do not have one and no longer automatically
+operate in 'adjoin' mode in such cases. If multiple numbered
+files are intended to be output, then add +adjoin to the command
+line and use an output filename specification similar to
+&quot;image-%d.jpg&quot;. Output files are now completely specified and
+predictable but this may break some existing usages which
+anticipate the automatic file numbering.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="february-25-2012">
+<h1><a class="toc-backref" href="#id16">1.3.14 (February 25, 2012)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Windows bundled libpng updated to the 1.5.9 release, which fixes
+the dire CVE-2011-3026 buffer overrun bug.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>EMF format : Fixed wrong module mapping which caused EMF reading
+to not work under Windows.</li>
+<li>TGA format: Assume that 32-bit TGA files have an alpha channel,
+even if they are not marked as such.</li>
+<li>XCF format: Fix reading XCF which is comprised of different sized
+layers.</li>
+<li>JPEG &amp; CineonLog: Convert RGB-compatible colorspaces
+(e.g. CineonLog) to RGB by default since that was the case prior
+to release 1.3.13.</li>
+<li>RAW formats: Small memory leak in dcraw module was fixed.</li>
+<li>Resize: ResizeImage() was ignoring its resize filter argument and
+was using the filter setting from the Image structure instead.</li>
+<li>The mirror virtual pixel method was broken.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>Open64 Compiler Suite: Version 5.0 is fully supported.</li>
+<li>Wand API: Added MagickExtentImage().</li>
+<li>MEF RAW: Mamiya Photo RAW &quot;MEF&quot; format is now supported.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>DPX format: Original file endianness is preserved by default.</li>
+<li>PNG library: Updated libpng to 1.5.9 release.</li>
+<li>TIFF library: Updated libtiff to 4.0.1 release.</li>
+<li>Zlib library: Updated to zlib 1.2.6 release.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Despeckle algorithm (-despeckle) is many times faster.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>DPX format: Original file endianness is preserved by default.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="december-24-2011">
+<h1><a class="toc-backref" href="#id17">1.3.13 (December 24, 2011)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+None</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>In I/O blob, don't rewind already open file handle passed to
+OpenBlob() since we don't know the intended state of this file
+handle, and because it prevents appending to an existing file.</li>
+<li>In AppendImageProfile(), don't leak profile buffer while appending
+a chunk to an existing profile.</li>
+<li>Fix deadlock in ClonePixelCache() which was caused by using the
+same semaphore pointer in the source and destination images.</li>
+<li>Removed bogus SyncBlob() code which sometimes caused a crash and
+was not useful.</li>
+<li>Fixed crash or hang which occured when the user entered CONTROL-C
+while threaded code was being executed.</li>
+<li>Fix core dump in AcquireOneCacheViewPixelInlined() when the image
+is in CMYK space.</li>
+<li>In MontageImages (montage), fix crash observed with &quot;-geometry
+x+0+0&quot;.</li>
+<li>The TIFF reader was crashing for images which use the
+TIFFTAG_OPIIMAGEID tag.</li>
+<li>AppendImages() (-append) was failing when only one image was
+provided.</li>
+<li>The <cite>animate</cite>, <cite>display</cite>, and <cite>identify</cite> commands now report any
+error only once, and then proceed to the next file name rather
+than quitting.</li>
+<li>Don't change the locale settings in InitializeMagick() since this
+may cause problems for international users. API users are still
+responsible for assuring that locale settings don't break floating
+point parsing and output (i.e. floating point decimal needs to be
+'.' rather than ',').</li>
+<li>RPM build is fixed (PerlMagick build was broken).</li>
+<li>RPM build installs documentation to expected places on Red Hat
+type systems.</li>
+<li>Fixes for usage with OpenSolaris.</li>
+<li>DESTDIR is supported by PerlMagick build.</li>
+<li>The matte channel was not being properly enabled or respected for
+TXT images.</li>
+<li>InitializeMagick() and DestroyMagick() are now fully thread safe.</li>
+<li>When a shear angle was zero, the shear request was being
+ignored entirely.</li>
+<li>In DispatchImage(), the <cite>K</cite> channel was always output as black for
+&quot;CMYK&quot; specification unless the image matte flag was True.</li>
+<li>MATLAB fixes.</li>
+<li>PNG fixes.</li>
+<li>PCL fixes for printing bi-level image on Konica-Minolta printers.</li>
+<li>EPT error handling fixes.</li>
+<li>JPEG reader was sometimes truncating large IPTC profiles.</li>
+<li>JPEG writer now handles errors properly rather than allowing
+libjpeg to exit the program (or hanging if driven by Magick++).</li>
+<li>JPEG reader now treats an unhandled EXP marker as a warning rather
+than a hard error.</li>
+<li>File open errors are now reliably reported.</li>
+<li>Improved rendering precision when using the drawing APIs.</li>
+<li>For the Magick++ Image backgroundColor(), borderColor(), and
+matteColor() methods, preserve the opacity part of the
+user-specified color.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>Add support for drawing text using a bitmap font.</li>
+<li>benchmark command supports a -stepthreads option to execute the
+specified command with an increasing number of threads to measure
+how an algorithm benefits from threading. This mode includes a
+column to show the speedup compared with one thread, and the
+Karp-Flatt metric</li>
+<li>Added support for invoking &quot;gs-cmyk&quot; and &quot;gs-cmyka&quot; entries in
+delegates.mgk when ColorSeparationType or ColorSeparationMatteType
+is requested. These cause Ghostscript to always output CMYK PAM
+format (even if the input file was not in CMYK format).</li>
+<li>EXIF profiles are preserved when writing JPEG files.</li>
+<li>The -mosaic command now respects the composition option specified
+by -compose as well as the image background color specified by
+-background.</li>
+<li>The TXT coder now supports multiple image frames.</li>
+<li>For image normalization (-normalize), add support for
+histogram-threshold setting to specify the percentage of the
+histogram to discard when computing image normalization parameters
+(default is 0.1%). For example <cite>-set histogram-threshold 0.01
+-normalize</cite>.</li>
+<li>Added an <cite>INFO</cite> coder which produces textual image description
+output similar to <cite>identify</cite> but may be used with convert like &quot;gm
+convert myfile info:-&quot;.</li>
+<li>Support application of the PDF crop box via '-define
+pdf:use-cropbox=true'.</li>
+<li>For PCL printer output, define pcl:fit-to-page in order for the
+printer to scale the image to fit the page.</li>
+<li>Added order dither 5x5, 6x6, and 7x7 circular dither patterns to
+create a halftone effect.</li>
+<li>PNM subformats are now reported as the specific subformat rather
+than just &quot;PNM&quot;.</li>
+<li>NetPBM's PAM format is now supported.</li>
+<li>MacPaint image format reader is added.</li>
+<li>Added TIFF LZMA compressor support.</li>
+<li>Added TIFF support for a tiff:group-three-options define to allow
+power-users to set the value of the GROUP3OPTIONS tag.</li>
+<li>New core C API function SetImageColorRegion() to set the constant
+pixel color for a specified region of the image.</li>
+<li>New Wand C API function MagickWriteImagesFile() to append images
+to a provided file handle.</li>
+<li>New Wand C API function MagickSetImageSavedType() to allow
+specifying the storage type used when saving the file (rather than
+changing the current image characteristics).</li>
+<li>In Wand C API, the functions NewPixelWand(), NewDrawingWand(), and
+NewMagickWand() invoke InitializeMagick() automatically in case
+user forgets to do so.</li>
+<li>New Wand C API function MagickSetFormat() to allow setting the
+file or blob format before it has been read.</li>
+<li>New Wand C API function MagickSetDepth() to set the depth used
+when reading from an image format which requires that the depth be
+specified in advance.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Now compiles properly with libpng 1.4.X and 1.5.X.</li>
+<li>Lcms 2.X is supported.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>TGA read performance improved.</li>
+<li>PNM read/write performance improved.</li>
+<li>Convolution (-convolve, -sharpen, -guassian, etc.) is faster.</li>
+<li>Adaptive threshold image (-lat) is faster.</li>
+<li>Image trimming (-trim) is faster.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>For DPX format and packed 10 bits, datums are now represented in
+the same (reversed) order for all RGB and YCbCr formats.
+Previously YCbCr 4:4:4 formats were not swapping the word datums
+because the only real-world files encountered did not swap the
+word datums.</li>
+<li>The -colors, -map, and -monochrome options now take effect
+immediately rather than at the end of all other processing.</li>
+<li>Removed non-standard multi-frame extension for SGI format.</li>
+<li>Windows install footprint is more consistent between DLL and
+static builds.</li>
+<li>LZMA compressed tarball is in 'xz' format rather than deprecated
+'lzma' format.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="march-8-2010">
+<h1><a class="toc-backref" href="#id18">1.3.12 (March 8, 2010)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Updated libpng Windows sources to 1.2.43 in order to resolve
+CVE-2010-0205 as it pertains to the GraphicsMagick Windows build.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Filter mode (write to stdout) was completely broken.</li>
+<li>Should now compile with libpng 1.4.</li>
+<li>Windows PerlMagick build identified itself as the wrong version.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>DCX output format is only written on request. Previously the PCX
+coder would automatically switch to DCX format if multiple frames
+would be written.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="february-21-2010">
+<h1><a class="toc-backref" href="#id19">1.3.11 (February 21, 2010)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed array underflow on systems using signed char which could
+result in a program crash due to extended characters in filenames
+or in certain file formats.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Fixed array underflow on systems using signed char which could
+result in a program crash due to extended characters in filenames
+or in certain file formats.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>Added a -thumbnail command to 'convert' and 'mogrify'. This is a
+faster way to scale down the image when speed is a primary
+concern.</li>
+<li>Added a -extent command to 'convert' and 'mogrify' which
+composites the image on top of a backing canvas image of solid
+color.</li>
+<li>Added support for -compose to the 'convert' and 'mogrify', which
+were documented to support it (but did not).</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Requests for 'Over' and 'Atop' composition are converted to a
+request for the (faster) 'Copy' composition when both images are
+opaque.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="february-10-2010">
+<h1><a class="toc-backref" href="#id20">1.3.10 (February 10, 2010)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>+adjoin was not working correctly for the case when only one image
+frame is present. With +adjoin and writing one frame to
+&quot;foo%d.jpg&quot; it was outputting &quot;foo%d.jpg&quot; rather than &quot;foo0.jpg&quot;.</li>
+<li>When drawing paths, memory allocation for the points was much
+larger than it needed to be (patch by Vladimir Lukianov).</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>To reiterate the change which first appeared in 1.3.9, there is no
+longer an implicit +adjoin if the output file name happens to
+contain a %d sequence, or there are multiple frames and the output
+file format only supports storing one frame. Specify +adjoin if
+scene number substition is desired in the output file names.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="february-4-2010">
+<h1><a class="toc-backref" href="#id21">1.3.9 (February 4, 2010)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Fix &quot;double free&quot; error when using gm import -frame.</li>
+<li>XPM does not support RGBA color syntax, so return RGB instead.</li>
+<li>The display '-update' option was only working in conjunction with
+the '-delay' option with a delay setting of 2 or greater.</li>
+<li>For formats which support multiple frames, output with +adjoin to
+filenames containing a scene specification (e.g. foo%02d.tiff) was
+resulting in wrong output file names.</li>
+<li>-convolve was crashing rather than reporting an error.</li>
+<li>Fixed crash if the number of OpenMP threads was reduced from the
+original value via '-limit threads' or omp_set_num_threads().</li>
+<li>-blur was not blurring the opacity channel for solid-color images.</li>
+<li>When installing HTML documentation, many files were included which
+are not part of the formatted documentation.</li>
+<li>Several deleted global string constants are restored with
+deprecated status in order to assure that symbols are not removed
+from the ABI.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>There is no longer an implicit 'adjoin' if an output filename
+contains an apparent scene specification (e.g. foo%02d.tiff) and
+multiple files are not needed to save the image.. It is necessary
+to use +adjoin. For example <tt class="docutils literal">gm convert foo.pdf +adjoin
+%02d.tiff</tt>.</li>
+<li>-flatten now applies the image background color under the first
+image in the list if it is not already opaque.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="january-21-2010">
+<h1><a class="toc-backref" href="#id22">1.3.8 (January 21, 2010)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Fix for CVE-2009-1882 &quot;Integer overflow in the XMakeImage
+function&quot;.</li>
+<li>Fix lockup due to hanging in loop while parsing malformed
+sub-image specification (SourceForge issue 2886560).</li>
+<li>Libltdl: Updated libtool to 2.2.6b in order to fix security issue.
+Resolves CVE-2009-3736 as it pertains to GraphicsMagick.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>-convolve, -recolor: Validate that user-provided matrix is square
+when parsing -convolve and -recolor commands in order to avoid a
+core dump.</li>
+<li>CALS: Reading images taller than the image width resulted in a
+failure.</li>
+<li>ConstituteImage(), DispatchImage(): 'A' and 'T' should indicate
+transparency and 'O' should indicate opacity. Behavior was
+inconsistent. In some cases 'O' meant transparency while in other
+cases it meant opacity. Also, in a few cases, matte was not
+getting enabled in the image as it should.</li>
+<li>DCRAW: Module name was not registered so modules based builds were
+not supporting formats provided via 'dcraw'.</li>
+<li>GetOptimalKernelWidth1D(), GetOptimalKernelWidth2D(): In the Q32
+build, convolution kernel size was estimated incorrectly for large
+sigmas on 32-bit systems due to arithmetic overflow. This could
+cause wrong results for -convolve, -blur, -sharpen, and other
+algorithms which use these functions.</li>
+<li>Image Size: Fixed the ability to pass the image size via the
+filename specification like &quot;myfile.jpg[640x480]&quot; rather than
+needing to use -size.</li>
+<li>IPTC: Blob data needed to be padded to an even size. Size is now
+correctly reported.</li>
+<li>IPTC: Returned IPTC string values were one character too short.</li>
+<li>Large Files: Large pixel cache files were not working under GNU
+Linux.</li>
+<li>JP2: Fixed some value scaling problems.</li>
+<li>JP2: Fix possible crash at exit when Jasper is used by a modules
+build.</li>
+<li>MPC: is_monochrome and is_grayscale flags were not managed
+properly for the MPC coder.</li>
+<li>PCL: Page was not always being ejected.</li>
+<li>PNG: The png8 encoder would fail when trying to write a 1-color
+image.</li>
+<li>PSD: PSD parser was confused by 0x0 pixel layers, resulting in
+image data corruption of all following layers.</li>
+<li>-rotate, -shear: Some internally-reported errors were potentially
+being lost.</li>
+<li>Subrange/stdin: Commands now support reading an image from stdin
+in conjunction with a subrange specification (e.g. &quot;-[1]&quot;).</li>
+<li>Magick++ STL ShadeImage: Implementation was completely botched.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>CALS Type 1 files may now be written (Work contributed by John
+Sergeant). CALS support is dependent on the TIFF library.</li>
+<li>GROUP4RAW encoder supports reading/writing RAW Group4 data.</li>
+<li>JP2: JPEG 2000 may now be written in arbitrary bit depths ranging
+from 2 to 16 rather than just 8 or 16.</li>
+<li>JPEG: IJG JPEG library version 7 is now supported.</li>
+<li>JPEG: Added jpeg:block-smoothing and jpeg:fancy-upsampling defines
+to control these JPEG library options.</li>
+<li>JPEG: Detect and apply colorspaces appropriately for ITU FAX JPEG.</li>
+<li>Resource Limits: There is now a &quot;threads&quot; resource limit which
+allows specifying the number of OpenMP threads which may be used,
+similar to the OMP_NUM_THREADS environment variable.</li>
+<li>TIFF: Allow CIELAB TIFF to be read.</li>
+<li>MagickGetImageAttribute()/MagickSetImageAttribute(): New Wand
+methods to support getting and setting an image attribute.
+Contributed by Mikko Koppanen.</li>
+<li>ClonePixelWand(): New Wand method to deep-copy an existing pixel
+wand.</li>
+<li>ClonePixelWands(): New Wand method to deep-copy an array of
+existing pixel wands.</li>
+<li>MagickCdlImage(): New Wand method to apply the ASC CDL to an
+image.</li>
+<li>MagickGetImageBoundingBox(): New Wand method to return the crop
+bounding box required to remove any solid-color border from the
+image.</li>
+<li>MagickGetImageFuzz(), MagickSetImageFuzz(): New Wand methods to
+get and set the color comparison fuzz factor.</li>
+<li>MagickHaldClutImage(): New Wand method to apply a Hald CLUT to an
+image.</li>
+<li>MagickSetResolution(): New Wand method to set the wand resolution.</li>
+<li>MagickSetResolutionUnits(): New Wand method to set the wand
+resolution units.</li>
+<li>Magick++: Allow Magick++ library to built as a DLL under MinGW and
+Cygwin. This requires a modern GCC in order for C++ exceptions to
+work.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Cygwin: Cygwin 1.7 is now supported.</li>
+<li>JPEG compression settings are preserved (if possible) when
+inserting JPEG blobs into formats which use JPEG.</li>
+<li>PDF: If the original file used JPEG compression, then use JPEG
+compression with original settings (if possible).</li>
+<li>TIFF: Update Windows build to use libtiff 3.9.2.</li>
+<li>X11 Display: Apply a checkerboard pattern underneath transparent
+images which use more than simple binary transparency.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Gamma: Performance is improved for Q8 and Q16 builds. Also
+preserve full precision in Q32 build.</li>
+<li>String data is dealt with a bit more efficiently (fewer
+allocations, less memory, and less CPU).</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>InitializeMagick() MUST be invoked prior to using any Magick API
+function. Failure to do so will likely lead to an immediate
+application crash. This is due to initialization and runtime
+changes intended to improve thread safety and efficiency.
+Previously it was only strongly recommended to invoke
+InitializeMagick().</li>
+<li>ConstituteImage(), DispatchImage(): 'A' and 'T' should indicate
+transparency and 'O' should indicate opacity. Behavior was
+inconsistent. In some cases 'O' meant transparency while in other
+cases it meant opacity. Also, in a few cases, matte was not
+getting enabled in the image as it should.</li>
+<li>colors.mgk: Is now empty to default and is optional. Previous
+content is now compiled into the library in an efficient way, but
+existing values may be modified, or new values added by adding
+entries to color.mgk.</li>
+<li>DisableSlowOpenMP is now the default. Use --enable-openmp-slow to
+enable OpenMP for algorithms which sometimes run slower rather
+than faster.</li>
+<li>magic.mgk: This configuration file is no longer used since this
+data is now compiled into the library in an efficient way.</li>
+<li>modules.mgk: Is now empty to default and is optional. Previous
+content is now compiled into the library in an efficient way, but
+existing values may be modified, or new values added by adding
+entries to modules.mgk.</li>
+<li>Third party executables not included in the Visual Studio build
+are no longer bundled in the GraphicsMagick installer. This means
+that hp2xx.exe, mpeg2dec.exe, and mpeg2enc.exe are no longer
+distributed.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="september-17-2009">
+<h1><a class="toc-backref" href="#id23">1.3.7 (September 17, 2009)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>PCX: Detect improper rows, columns, or depth. Fixes CVE-2008-1097
+&quot;Memory corruption in ImageMagick's PCX coder&quot;.</li>
+<li>DrawDashPolygon: Avoid a crash which sometimes occured with tiny
+polygons.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>JPEG: Profile chunks need to be concatenated in order to build
+the whole profile. This was not working so embedded profiles
+larger than 32K or maybe 64K were being corrupted. This bug was
+introduced in GraphicsMagick 1.2.</li>
+<li>Meta: Fix memory leaks.</li>
+<li>Meta: Work better with with IPTC record 2 blocks and deal better
+with IPTC embedded in an 8BIM profile. Fixes by John Sergeant.</li>
+<li>MPC: Fix crash when reading MPC and the input image is modified.</li>
+<li>PNG: Ensure that the opacity channel is properly initialized.</li>
+<li>-profile: Lowercase arguments were sometimes not working as
+expected.</li>
+<li>Topol: Topol reader actually works now and is included in test
+suite.</li>
+<li>TIFF: Read and write JPEG-compressed grayscale TIFF correctly.</li>
+<li>VisualMagick configure now works properly when output paths are
+specified.</li>
+<li>WMF: Eliminate memory leaks.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>MagickWand: New method MagickSetCompressionQuality() to allow
+setting the compression quality.</li>
+<li>MagickWand: New method CloneDrawingWand() to deep-copy a drawing
+wand.</li>
+<li>MagickWand: New method DrawGetException() to retrieve information
+regarding the last drawing wand exception (if any).</li>
+<li>MagickWand: New method DrawClearException() to clear a drawing wand
+exception.</li>
+<li>Magick++: New Image method cdl() to apply the ASC CDL.</li>
+<li>Magick++: New Image method colorMatrix() to apply a color matrix
+to the image channels.</li>
+<li>Magick++: New Image method haldClut() to apply a color lookup
+table (Hald CLUT) to the image.</li>
+<li>MSL/Conjure: Added a new 'profile' command which applies, adds, or
+removes one or more IPTC, ICC or generic profiles from a file.
+Work contributed by John Sergeant.</li>
+<li>Added a 'time' subcommand to provide Unix-style 'time' output when
+a 'time' capability is missing, or the reporting format is
+inconsistent. For example 'gm time convert ...'.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>ColorMatrixImage(): Add opaque opacity channel when needed.</li>
+<li>PDF &amp; PS: Use '-type palette' prior to input file name to cause
+Ghostscript to return a dithered colormapped image.</li>
+<li>PNG: Now compiles with libpng-1.4.0beta74 and later.</li>
+<li>TIFF: Libtiff in Windows build is upgraded to 3.9.1. This allows
+GraphicsMagick to read and write 16 and 24 bit float TIFF files.</li>
+<li>Windows code to find Ghostscript is rewritten from scratch.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Drawing of points, lines, and polygons (and complex shapes based
+on these) is now accelerated using OpenMP with excellent speed-up.</li>
+<li>ICC color transforms now see linear speedup from OpenMP.</li>
+<li>Rotate: For rotations of 90 or 270 degrees, tile sizes are
+selected more appropriately.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>No longer clear the exception structure at the start of
+ReadImage() and other similar functions since this sometimes masks
+errors. The API user is expected to make sure that the exception
+structure is clean prior to invoking a function.</li>
+<li>SVG: Writer is now disabled since it usually does not work properly.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="july-25-2009">
+<h1><a class="toc-backref" href="#id24">1.3.6 (July 25, 2009)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Composition was failing when the change image overlaps off the
+left side of the canvas.</li>
+<li>EPT, PDF, PS: PDF bounding box is sometimes incorrect or not
+globally applicable so don't specify bounding box when reading PDF
+files.</li>
+<li>OpenMP: Fix (benign) multi-thread cross-contentions (detected by
+valgrind's Helgrind).</li>
+<li>TIFF: Fix problem with reading one bit per sample RGB images.</li>
+<li>TIFF: Writer was using rows-per-strip of 8 when writing
+JPEG-compressed TIFF. This does not work for vertical
+subsampling, and some TIFF readers insist on 16. The
+rows-per-strip is now required to be a multiple of 16.</li>
+<li>TIFF: In some cases, the TIFF reader and writer were accessing
+planar TIFF in row-order rather than plane-order, which resulted
+in sever buffering problems in libtiff, and failure when
+compression was used.</li>
+<li>-write now works usefully as documented.</li>
+<li>Temporary file name generator was not random enough, resulting in
+some file name collisions for GraphicsMagick processes started at
+the same time.</li>
+<li>PerlMagick: Fixed Ping on a BLOB.</li>
+<li>GetImageDepth was leaking memory.</li>
+<li>Convert/mogrify -mask option was leaking memory.</li>
+<li>Mogrify -output-directory option was leaking memory.</li>
+<li>DPX: Fixed memory leak encountered when subsampling to 4:2:2.</li>
+<li>DPX: Values read received insuficient scaling, which round-tripped
+correctly, but rounded-down excessively if any image processing
+was applied.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>Added HRS reader for slow scan TV (contributed by Fojtik Jaroslav).</li>
+<li>Pthreads (POSIX threads) API may now be used under the WIN32 API.</li>
+<li>New access confirmation facility (MagickConfirmAccess) to allow
+the API user to monitor and/or block access to files and URLs.
+This allows the API user to implement a security policy based on
+actual accesses.</li>
+<li>New color matrix function (ColorMatrixImage) to apply a color
+matrix similar to Adobe Flash Flash.filters.colorMatrixFilter(),
+and Windows GDI+ ColorMatrix class, (order up to 5x5) to the image
+pixels. This is accessible via the -recolor command option.</li>
+<li>Added an IDENTITY coder to return a Hald identity CLUT image of
+specified order (e.g. &quot;identity:8&quot;).</li>
+<li>Added a Hald CLUT capability as described at
+<a class="reference external" href="http://www.quelsolaar.com/technology/clut.html">http://www.quelsolaar.com/technology/clut.html</a>. This allows a
+color transformation to be easily created and replicated on any
+number of images. The algorithm is accessed by the -hald-clut
+option of 'convert' and 'mogrify'. Original algorithm by Eskil
+Steenberg and adapted for GraphicsMagick by Clément Follet, with
+additional work by Bob Friesenhahn.</li>
+<li>Added support for the ASC CDL transform. Available as -asc-cdl
+via the 'convert' and 'mogrify' subcommands. Original
+implementation by Clément Follet but considerably re-worked by Bob
+Friesenhahn. Implementation passes the +/- 1 count accuracy
+requirement required by the ASC CDL SOP tests.</li>
+<li>Added support for reading CALS Type 1 format (contributed by John
+Sergeant). CALS is a standard raster format used by the US
+Department of Defense for storing blueprint images.</li>
+<li>Added a random number generation system based on George
+Marsaglia's multiply-with-carry generator. Somewhat slower than
+rand() but produces better random numbers with a period &gt;2^60.
+This is a much better random number generator than the C library
+rand() and the algorithm is integrated in a way which maximizes
+multi-thread performance.</li>
+<li>The 'compare' command now supports a -maximum-error option to
+specify the maximum image error so that it may be used to support
+boolean logic in automated test scripts.</li>
+<li>For OpenMP-builds, the '-list resource' output now indicates the
+number of threads which will be used.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Image resize now avoids adding &quot;halos&quot; around objects when
+resizing an image which contains transparency (patch contributed by
+Pavel Merdin).</li>
+<li>DICOM: The DICOM reader is completely re-written and is much more
+functional now. A few features (e.g. RLE compression) are still
+missing. This work is contributed by John Sergeant.</li>
+<li>EXIF: Unprintable characters in EXIF attribute strings are now
+returned using three-digit octal notation. Unknown tags are
+identified via their four-character hex value.</li>
+<li>PCL: PCL writer is rewritten to fix many bugs, add support for
+compression, add support for 8 bit PseudoClass images, and
+dramatically improve usability (work contributed by John Sergeant).</li>
+<li>TIFF: Allow the user to force the returned image to be TrueColor
+type for min-is-white and min-is-black TIFF files.</li>
+<li>TIFF: User can now specify the predictor using syntax like
+'-define tiff:predictor=2'.</li>
+<li>TIFF: User can now specify the rows-per-strip value when using
+JPEG compression.</li>
+<li>TXT: The TXT reader is now capable of reading image files written
+by the TXT writer, as well continuing to render ASCII text into an
+image (work contributed by Fojtik Jaroslav).</li>
+<li>Utilities &#64;file.txt syntax for including a list of files to use as
+an argument now really works as expected. This may be used to
+inject any other text into the command line as well. As a result,
+the 'mogrify' utility may be invoked on thousands of files at once
+while obtaining the list of files to process from a text file.</li>
+<li>The 'mogrify' utility now caches argument images so that they are
+loaded only once when mogrify is used to process multiple image
+files.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>-median and -noise now see reliable linear speedup as threads are
+added.</li>
+</ul>
+</blockquote>
+<p>Behavior Changes:</p>
+<blockquote>
+<ul class="simple">
+<li>PerlMagick is configured but no longer built by default.</li>
+<li>Use '-interlace Line' to produce an interlaced GIF, PNG, or
+progressive JPEG.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="january-26-2009">
+<h1><a class="toc-backref" href="#id25">1.3.5 (January 26, 2009)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>BMP and DIB formats were throwing an assertion for negative height
+values. This caused the process to crash.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Don't install Magick++ headers if C++ is disabled.</li>
+<li>Linux RPM SPEC file needs to always install the loadable module
+.la files or else the modules won't load.</li>
+<li>Windows runtime DLLs were for the wrong compiler version,
+resulting in failure to execute if the correct runtime DLLs are
+not available.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>FITS: Parsing is more robust.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>None</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="january-13-2009">
+<h1><a class="toc-backref" href="#id26">1.3.4 (January 13, 2009)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Now runs under Windows Vista (as a 32-bit application).</li>
+<li>Fix for colorspace transform math overflow in Q32 build.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>Windows build supports OpenMP and requires Windows 2000 or later
+(source code still supports Windows '98).</li>
+<li>Support large files under Windows.</li>
+<li>Support reading/writing 16 and 24 bit float TIFF files.</li>
+<li>Support reading/writing 64 bit integer TIFF files.</li>
+<li>Added &quot;Log&quot;, &quot;Max&quot;, &quot;Min&quot;, and &quot;Pow&quot; options to -operator.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Debug logging now properly prints 64-bit offset values.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Improve resource estimation for Microsoft Windows systems.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="december-9-2008">
+<h1><a class="toc-backref" href="#id27">1.3.3 (December 9, 2008)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>'identify' was throwing an assertion when used on colormapped
+files (this bug was introduced by 1.3.2).</li>
+<li>With the -segment option, eliminate trashing the image colors when
+used on huge images.</li>
+<li>'identify -format &quot;%c&quot;' now reports the entire comment regardless
+of size.</li>
+<li>Argument to -convolve is no longer arbitrarily truncated so huge
+convolution kernels may now be specified from the command line.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Image segmentation (-segment) is now accelerated using OpenMP and
+uses several other tactics to improve execution performance.</li>
+<li>'identify &quot;*&quot;' now successfully works in a 32-bit application when
+used in a directory containing a million files.</li>
+<li>'identify' now executes quickly when used on TIFF files.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="november-29-2008">
+<h1><a class="toc-backref" href="#id28">1.3.2 (November 29, 2008)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>-roll was failing for colormapped images.</li>
+<li>VID: Memory leak fix.</li>
+<li>PREVIEW: Solarize parameter was wrong.</li>
+<li>Delegates previously using 'spawn' needed an ampersand so that
+starting the child process does not hang the GUI.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>+profile now supports an exclusion syntax. For example <tt class="docutils literal">+profile
+<span class="pre">'!icm,*'</span></tt> removes all of the profiles except for the ICM profile.
+The new syntax also allows multiple profiles to be listed at once.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>AdaptiveThreshold, Blur, Convolve, and MotionBlur no longer
+process the opacity channel unless the image has one.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="november-17-2008">
+<h1><a class="toc-backref" href="#id29">1.3.1 (November 17, 2008)</a></h1>
+<p>Security Fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>None.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>RPM build, Fixes to successfully build binary RPMs for Red Hat
+Linux 4.</li>
+<li>MSL/conjure, Fix bug with attributes becoming appended to
+themselves. Fix memory leaks.</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>New --disable-openmp-slow configure option for disabling use of
+OpenMP for algorithms which may run slower on operating systems
+with crummy thread libraries.</li>
+<li>JPEG, Allow user to specify DCT encoding method via
+jpeg:dct-method define. Also allow control over whether huffman
+encoding is used via jpeg:optimize-coding define.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>OpenMP (parallel processing) improvements for these functions:<ul>
+<li>Rotate by 90 and 270 degrees (-rotate)</li>
+</ul>
+</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="november-9-2008">
+<h1><a class="toc-backref" href="#id30">1.3 (November 9, 2008)</a></h1>
+<p>Security fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>AVI reader: Re-worked to be more robust against crash or DOS.</li>
+<li>AVS reader: Re-worked to be more robust against crash or DOS.</li>
+<li>DCM reader: Re-worked to be more robust against crash or DOS.</li>
+<li>EPT reader: Re-worked to be more robust against crash or DOS.</li>
+<li>FITS reader: Re-worked to be more robust against crash or DOS.</li>
+<li>MTV reader: Re-worked to be more robust against crash or DOS.</li>
+<li>PALM reader: Re-worked to be more robust against crash or DOS.</li>
+<li>RLA reader: Re-worked to be more robust against crash or DOS.</li>
+<li>TGA reader: Re-worked to be more robust against crash or DOS.</li>
+<li>Avoid possible crash in GetImageCharacteristics() when substituting
+text in comment read from file.</li>
+<li>Cineon reader: Fixed crash with broken file from Sami Liedes.</li>
+<li>Palm reader: Fixed crash with broken files from Sami Liedes.</li>
+<li>PICT reader: Fixed crash with broken files from Sami Liedes.</li>
+<li>DPX reader: Validate file data better to avoid improper operation with
+intentionally (or accidentally) defective files.</li>
+<li>XCF reader: Fixed crash with broken files from Sami Liedes.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Libbz2 is now detected for MinGW.</li>
+<li>Install documentation under /usr/local/share/doc/GraphicsMagick by
+default, according to GNU conventions.</li>
+<li>In PerlMagick, Dissolve composition was not working right.</li>
+<li>FITS: Ensure that written format conforms to specification.</li>
+<li>TIFF:<ul>
+<li>Don't accidentially convert CMYK images to RGB.</li>
+<li>Eliminated a memory leak in the codec support detection code.</li>
+</ul>
+</li>
+<li>JPEG: Removed over-write of image-&gt;client_data.</li>
+<li>PDF: Try to properly deal with reading rotated PDFs.</li>
+<li>PNG: Fixed crash when writing PNG images with transparency and either
+optimize is requested, or the image is colormapped.</li>
+<li>Configure: Fixed the --enable-magick-compat configure option, which
+had stopped working.</li>
+<li>Configure: Fixed --without-magick-plus-plus so that it works again. This
+stopped working in the 1.2 release cycle.</li>
+<li>Configure: Fixed MagickLibVersion text string generation so that it
+is now correct when a component of the release number exceeds '9'.
+Now components can safely count up to '99' before there is a problem.</li>
+</ul>
+</blockquote>
+<p>Performance Improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>OpenMP (parallel processing) improvements for these functions:<ul>
+<li>Affine transform (-affine -transform)</li>
+<li>Average images (-average)</li>
+<li>Add noise (+noise)</li>
+<li>Black threshold (-black-threshold)</li>
+<li>Blur (-blur)</li>
+<li>Border (-border)</li>
+<li>Channel import, export, and depth-setting (-channel, -depth)</li>
+<li>Clip path</li>
+<li>Coalesce (-coalesce)</li>
+<li>Colorize (-colorize)</li>
+<li>Colorspace transformation (-colorspace)</li>
+<li>Compare images ('compare' command)</li>
+<li>Composition ('composite' command)</li>
+<li>Convolution (-convolve, -edge, -emboss, -gaussian, -sharpen)</li>
+<li>Contrast adjust (-contrast)</li>
+<li>Crop (-crop)</li>
+<li>CycleColormap (-cycle)</li>
+<li>Depth setting (-depth, -operator depth)</li>
+<li>Despeckle (-despeckle)</li>
+<li>Enhance (-enhance)</li>
+<li>Equalize (-equalize)</li>
+<li>Flatten (-flatten)</li>
+<li>Flip (-flip)</li>
+<li>Flop (-flop)</li>
+<li>Frame (-frame)</li>
+<li>Gamma adjust (-gamma, -operator gamma)</li>
+<li>Gradient</li>
+<li>Implode (-implode)</li>
+<li>Levels adjust image (-level)</li>
+<li>Local adaptive threshold (-lat)</li>
+<li>Median filter (-median)</li>
+<li>Minify image (-minify)</li>
+<li>Modulate image (-modulate)</li>
+<li>Morph image (-morph)</li>
+<li>Mosiac (-mosaic)</li>
+<li>Motion blur (-motion-blur)</li>
+<li>Negate image (-negate)</li>
+<li>Noise filter (-noise)</li>
+<li>Normalize image (-normalize)</li>
+<li>Oil Paint (-paint)</li>
+<li>Opaque (-opaque)</li>
+<li>Ordered dither (-ordered-dither)</li>
+<li>Operators (-operator)</li>
+<li>Profile adjust (ICC) (-profile)</li>
+<li>Random threshold (-random-threshold)</li>
+<li>Resize image (-resize)</li>
+<li>Raise image (-raise)</li>
+<li>Roll image (-roll)</li>
+<li>Rotate image (-rotate)</li>
+<li>Shade image (-shade)</li>
+<li>Shear image (-shear)</li>
+<li>Shave (-shave)</li>
+<li>Solarize image (-solarize)</li>
+<li>Spread image (-spread)</li>
+<li>Statistics computation (identify -verbose)</li>
+<li>Swirl (-swirl)</li>
+<li>Threshold channel (-threshold, -operator threshold)</li>
+<li>Threshold image (-threshold)</li>
+<li>Transparent (-transparent)</li>
+<li>Trim image (-trim)</li>
+<li>UnsharpMaskImage (-unsharp)</li>
+<li>Wave (-wave)</li>
+<li>White threshold (-white-threshold)</li>
+</ul>
+</li>
+<li>Improved coder management performance.</li>
+<li>XCF (GIMP) reader is much faster.</li>
+</ul>
+</blockquote>
+<p>New Features:</p>
+<blockquote>
+<ul class="simple">
+<li>Use MAGICK_CODER_STABILITY environment variable to enable a subset
+of the coders based on their stability classification.</li>
+<li>Use MAGICK_IO_FSYNC environment variable to cause written file to
+be synchronized to disk to avoid possible data loss on power fail.</li>
+<li>Added 'compare' command to statistically or visually compare two
+image files.</li>
+<li>Added new channel operators (-operator):<ul>
+<li>Assign</li>
+<li>Gamma</li>
+<li>Depth</li>
+<li>Negate</li>
+<li>Noise-Gaussian</li>
+<li>Noise-Impulse</li>
+<li>Noise-Laplacian</li>
+<li>Noise-Multiplicative</li>
+<li>Noise-Poisson</li>
+<li>Noise-Uniform</li>
+<li>Threshold</li>
+<li>ThresholdBlack</li>
+<li>ThresholdWhite</li>
+</ul>
+</li>
+<li>New composition operators (-compose):<ul>
+<li>CopyBlack</li>
+<li>CopyCyan</li>
+<li>CopyMagenta</li>
+<li>CopyYellow</li>
+<li>Divide</li>
+</ul>
+</li>
+<li>Added -motion-blur to motion blur the image.</li>
+<li>Mogrify and convert now support -black-threshold and -white-threshold.</li>
+<li>MAT: Now supports reading compressed files.</li>
+<li>FITS: Now supports 8, 16, 32 bit integer, float, and double images
+and writes correct FITS format.</li>
+<li>DCRAW: Coder proxy module allows reading digital camera files as if
+they were natively supported.</li>
+<li>New C API functions:<ul>
+<li>AddNoiseImageChannel(), add noise to an image channel.</li>
+<li>BlurImageChannel(), blur an image channel.</li>
+<li>GaussianBlurImageChannel(), gaussian blur an image channel.</li>
+<li>ImportImageChannelsMasked(), import selected image channels.</li>
+<li>SharpenImageChannel(), sharpen an image channel.</li>
+<li>UnsharpMaskImageChannel(), unsharpmask an image channel.</li>
+<li>New cache view interfaces to correct shortcomings of original
+ones. New interfaces are AcquireCacheViewPixels(),
+AcquireOneCacheViewPixel(), AcquireCacheViewIndexes(),
+GetCacheViewPixels(), SetCacheViewPixels(), and
+SyncCacheViewPixels(). The deprecated functions are
+AcquireCacheView(), GetCacheView(), SetCacheView(), and
+SyncCacheView().</li>
+<li>GetCacheViewRegion() reports region bounded by a cache view.</li>
+<li>GetCacheViewArea() reports area bounded by a cache view.</li>
+<li>ExportViewPixelArea() exports a cache view as formatted pixels.</li>
+<li>ImportViewPixelArea imports formatted pixels into a cache view.</li>
+</ul>
+</li>
+<li>Removed C API functions:<ul>
+<li>ReadStream()</li>
+<li>WriteStream()</li>
+</ul>
+</li>
+<li>Magick++ C++ API improvements<ul>
+<li>Color class no longer considers transparent black to be an invalid
+color.</li>
+<li>New Image methods addNoiseChannel(), blurChannel(),
+gaussianBlurChannel(), motionBlur(), randomThresholdChannel(),
+randomThresholdChannel(), sharpenChannel(), unsharpmaskChannel().</li>
+</ul>
+</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>-ordered-dither and -random-threshold may now be used to individually
+dither any named channel.</li>
+<li>Mogrify and convert now support -minify to halve the image size.</li>
+<li>Mogrify and convert now support -magnify to double the image size.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="april-29-2008">
+<h1><a class="toc-backref" href="#id31">1.2 (April 29, 2008)</a></h1>
+<p>Security fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Fixes for CERT security alert TA04-217A described at
+&quot;<a class="reference external" href="http://www.us-cert.gov/cas/techalerts/TA04-217A.html">http://www.us-cert.gov/cas/techalerts/TA04-217A.html</a>&quot;.</li>
+<li>AVI, BMP, &amp; DIB security fixes.</li>
+<li>PSD security fixes.</li>
+<li>P7 format security fix.</li>
+<li>Fix EXIF IFD stack overflow vulnerability.</li>
+<li>SGI security fix for RLE encoding (CVE-2006-4144)</li>
+<li>XCF security fix (CVE-2006-3743)</li>
+<li>PALM heap overflow fix (CVE-2006-5456)</li>
+<li>DCM security fix (CVE-2006-5456)</li>
+<li>Fix for shell command injection in delegate code via file names)
+(CVE-2005-4601). Delegate execution is much more secure now.</li>
+<li>Don't use filenames as printf specifications (CVE-2006-0082).</li>
+<li>Fix integer overflow in DCM coder (CVE-2007-1797).</li>
+<li>XWD integer overflow fix (CVE-2007-1797).</li>
+<li>Implementation has replaced usage of strcpy, strcat, and strncat
+with the more security conscious strlcat and strlcpy.</li>
+<li>DCM, DIB, XCF, XBM, and XWD security fix for integer overflow
+vulnerability (IDefense 09.19.07).</li>
+<li>Do not access X11 or invoke convenience or stealth delegate programs
+based on the file extension. In particular, these file extensions are
+rejected for consideration as a format specifier: 'autotrace',
+'browse', 'dcraw', 'edit', 'gs-color', 'gs-color+alpha', 'gs-gray',
+'gs-mono', 'launch', 'mpeg-encode', 'print', 'scan', 'show', 'win',
+'xc', and 'x'.</li>
+</ul>
+</blockquote>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>The configure script now searches for a web browser in the order
+mozilla, firefox, and finally netscape.</li>
+<li>When the user specifies the -units option, the current image
+resolution values are now re-scaled to match the new units.</li>
+<li>Properly determine Ghostscript font location for Ghostscript 8.0 and later.</li>
+<li>GraphicsMagick now successfully builds and passes all tests under
+Digital Unix 5.1, using the vendor compiler.</li>
+<li>Ghostscript sometimes displays an error message and fails, yet it
+returns a success error code to GraphicsMagick. Verify that
+Ghostscript has updated the output file before attempting to use it.</li>
+<li>Fixed a configure script syntax error when testing for trio.</li>
+<li>When requesting a list of formats, all of the modules in the module
+search path are considered. Previously only the modules in the same
+directory as the LOGO module were listed.</li>
+<li>Ensure that an image clip mask is respected by the negate algorithm.</li>
+<li>The BMP writer was sometimes writing incorrect BMP v4 files.</li>
+<li>Support reading and writing large PCX files.</li>
+<li>The Red Hat source RPM was failing to install the -config scripts
+with execute permissions.</li>
+<li>Fixed a bug which could cause possible truncation while cloning the
+image cache.</li>
+<li>Ensure that MIFF files indicate the compression which was actually used.</li>
+<li>Properly handle errors from libtiff so that corrupted images are not
+output.</li>
+<li>Fix for stripped-TIFF reader. Discard extra samples beyond alpha in
+scanline TIFFs.</li>
+<li>Endian option now controls TIFF byte-order rather than bit-order.</li>
+<li>TIFF writer can now write to pipes and other non-seekable output
+destinations.</li>
+<li>JBIG writer was writing empty files for some libjbig releases.</li>
+<li>Improved handling of corrupt GIF files.</li>
+<li>Handle large SUN format images.</li>
+<li>Properly compute image depth for 16-bit SGI image files.</li>
+<li>For the gmdisplay program, ensure that only RGB data is sent to Windows.</li>
+<li>Many memory leak fixes.</li>
+<li>PDF writer is fixed so that Ghoscript 8.5 doesn't warn about the output.</li>
+<li>PDF writer now writes proper output with CCITT compression.</li>
+<li>Properly use fseeko() and ftello() if they are available.</li>
+<li>Fixed a infinite loop bug in the XWD reader.</li>
+<li>Fix minor memory leak in ProfileImage().</li>
+<li>Fixed -level command parsing when a percent symbol is supplied within the
+argument rather than at the end.</li>
+<li>Fix pixel scaling problem caused by floating point
+rounding error (noticed under AIX).</li>
+<li>Fixed a memory leak in the GIF coder in the error return path.</li>
+<li>Fix for SourceForge bug id 1353744 &quot;MagickGetQuantumDepth doesn't work&quot;.</li>
+<li>Fix for SourceForge bug id 1315109 &quot;segfault in InitializeMagick(NULL)&quot;.</li>
+<li>Fix for SourceForge bug id 1391421 &quot;problem doing resize on 273x1 JPEG&quot;.</li>
+<li>Fix for SourceForge bug id 1510075 &quot;Failed to write PDF with JPEG compression&quot;.</li>
+<li>Fix for SourceForge bug id 1572357 &quot;GetOnePixel definition appears incorrect&quot;.</li>
+<li>Fix for SourceForge bug id 1576616 Fix includedir variable in pkg-config files&quot;.</li>
+<li>Fix for SourceForge bug id 1173713 &quot;segfault in ModifyCache&quot;.</li>
+<li>Fix for SourceForge bug id 1431805 &quot;clip art wpg files cause access violation
+in graphics magick&quot;.</li>
+<li>Fix for SourceForge bug id 1743141 &quot;Affine matrix option parsing&quot;.</li>
+<li>Fix for SourceForge bug id 1625477 &quot;Memory leak reading layered PSD Image&quot;.</li>
+<li>Fix for SourceForge bug id 1878992 &quot;literal square brackets in file
+name cause large delay and bug id 1783209 &quot;converting runs slowly
+when subimage is specified&quot;.</li>
+<li>Fix for SourceForge bug id 1883527 &quot;compression of tiff-file has no effect&quot;.</li>
+<li>Successfully read files in the form &quot;file[123]&quot;.</li>
+<li>Fix reading 12-bit grayscale JPEG.</li>
+<li>Set image depth appropriately when importing image from X11 display.</li>
+<li>Fix map resource tracking.</li>
+<li>Fix reading recent variants of ImageMagick's MIFF format.</li>
+<li>Output bilevel TIFF meeting the TIFF Class F specification.</li>
+</ul>
+</blockquote>
+<p>New Utilities:</p>
+<blockquote>
+<ul class="simple">
+<li>A 'benchmark' subcommand is now available to benchmark the
+performance of any other arbitrary subcommand (e.g. 'convert').</li>
+</ul>
+</blockquote>
+<p>Feature improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>LZW compression is now enabled by default.</li>
+<li>Support industry-standard subsampling notation like &quot;4:2:2&quot;.</li>
+<li>If gm is executed under a traditional alternate name (e.g.
+convert), it will invoke the appropriate sub-command. This allows
+use of hard links, symbolic links, or just copying 'gm' to the
+desired sub-command name in order to achieve 100% ImageMagick 5.5.2
+utility compatibility.</li>
+<li>Provide the --enable-magick-compat option when configuring to install
+ImageMagick utilities compatibility links.</li>
+<li>Identify -verbose output includes normalized (0.0-1.0) statistics.</li>
+<li>Identify and convert now print &quot;pixels per second&quot; rates to help
+evaluate performance.</li>
+<li>Added the identify +ping option to force reading the complete file.</li>
+<li>The display program now supports the +progress option to disable any
+visual progress indication (and hourglass cursor) while loading images.</li>
+<li>Support writing grayscale TGA files.</li>
+<li>Provide explicit support for Rec 601 and Rec 709 grayscale spaces.</li>
+<li>Include some support for a log RGB space based on the 2.048 density
+range as defined for the Cineon Digital Film System.</li>
+<li>Added utilities command-line support for industry standard subsampling
+notation like 4:4:4 and 4:2:2.</li>
+<li>Use MAGICK_IOBUF_SIZE to tune the size of the I/O buffer.</li>
+<li>Use -type Bilevel, Grayscale, TrueColor, or TrueColorMatte to
+influence the type of image that Ghostscript returns.</li>
+<li>Use '-define tiff:fill-order={msb2lsb|lsb2msb}' to control TIFF bit
+fill order.</li>
+<li>The -version option now dumps a feature list as well as the build
+options.</li>
+<li>The -endian option now supports the option 'native'.</li>
+<li>A -monitor is added to enable progress monitoring for the command line
+utilities.</li>
+<li>Use the -output-directory option to 'mogrify' to send output files to
+the specified directory.</li>
+<li>Use the -create-directories option in conjunction with
+-output-directory and 'mogrify' to create any necessary subdirectories.</li>
+<li>A Pixels resource limit is added. Use '-limit Pixels value' to limit
+the maximum number of pixels in an image to 'value'.</li>
+<li>The already supported option '-type Optimize' is now honored by
+formats that need to choose a subformat based on the properties of
+the image. Grueling tests of many/all pixels are not performed
+unless '-type Optimize' is supplied.</li>
+<li>Added a a -set option to the composite, convert, display, mogrify,
+import commands in order to allow setting an image attribute.</li>
+<li>Display utility no longer defaults to reading from standard input if
+stdin is not a tty.</li>
+<li>May now be configured to use the umem memory allocation library
+available in Solaris 9, Update 3 and later, or from the portable umem
+project.</li>
+</ul>
+</blockquote>
+<p>Coder additions/improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Replaced existing DPX &quot;support&quot; with all-new DPX support conforming
+to the SMPTE 268M-2003 standard.</li>
+<li>Cineon reader completely rewritten.</li>
+<li>TIFF coder is completely re-written. Now supports reading and
+writing RGB, CMYK, and grayscale, scanline-oriented TIFF images
+with arbitrary (1 to 32 bits) depth. Includes support for tiled
+TIFF, floating point TIFF, LogLuv TIFF, BigTIFF, arbitrary depths,
+and associated alpha.</li>
+<li>TIFF coder now supports retrieving and saving XMP profiles.</li>
+<li>MATLAB support is much improved and supports writing as well.</li>
+<li>WPG reader now supports CTM translations.</li>
+<li>ART format now supports writing.</li>
+<li>Support 32-bit raw RGB images.</li>
+<li>Support 32-bit raw CMYK images.</li>
+<li>Support 32-bit raw gray images.</li>
+<li>JP2 coder reads images in YCbCr colorspace and retrieves an embedded
+ICC ICM color profile if present.</li>
+</ul>
+</blockquote>
+<p>API enhancements:</p>
+<blockquote>
+<ul class="simple">
+<li>Added ExportImageChannel() and ImportImageChannel() APIs to support
+exporting and importing pixel regions with an arbitary range of (1
+to 32) bits per quantum.</li>
+<li>Added image leveling methods for Magick++.</li>
+<li>Generalized GetImageAttribute() support for retrieving wildcarded
+attributes so that an identify -format specification like
+<tt class="docutils literal"><span class="pre">&quot;%[dpx:*]&quot;</span></tt> works as expected.</li>
+<li>Incorporated changes changes necessary so that GraphicsMagick can
+work with the Ch C/C++ interpreter from SoftIntegration at
+<a class="reference external" href="http://www.softintegration.com/">http://www.softintegration.com/</a>.</li>
+<li>Added MagickAllocFunctions() to allow the API user to replace the
+underlying memory allocator functions.</li>
+<li>Added MagickMalloc() and deprecated AcquireMemory().</li>
+<li>Added MagickCloneMemory() and deprecated CloneMemory().</li>
+<li>Added MagickMallocArray() to safely allocate N items of size S.</li>
+<li>Added MagickRealloc() and deprecated ReacquireMemory().</li>
+<li>Added MagickFree() and deprecated LiberateMemory().</li>
+</ul>
+</blockquote>
+<p>Performance improvments:</p>
+<blockquote>
+<ul class="simple">
+<li>The DispatchImage() and ConstituteImage() functions incorporate
+special case code for BGR, BGRO, BGRP, RGB, RGBO, and I formats (8
+bit only) in order to improve performance dramatically.</li>
+<li>When writing very large JPEG images, don't enable Huffman compression
+since doing so requires libjpeg to buffer the entire image in memory.</li>
+<li>When using the 'identify' -verbose option, -verbose must be specified
+twice in order to obtain the color count. This makes normal use of
+-verbose much faster.</li>
+<li>Significantly improved read/write speed for bilevel and gray images.</li>
+<li>TIFF I/O is considerably faster.</li>
+<li>Postscript writer is 10-15X faster.</li>
+<li>PNM formats writer is 10-100X faster.</li>
+<li>Rotate by 90 or 270 degrees is 2-9X faster.</li>
+</ul>
+</blockquote>
+<p>Windows-specific improvements/changes:</p>
+<blockquote>
+<ul class="simple">
+<li>For the MinGW and Cygwin builds, the Magick++ library is forced to
+build as a static library since otherwise C++ exceptions don't work.</li>
+<li>MinGW cross-build is available from a Linux or FreeBSD host.</li>
+<li>Determine location of Ghostscript fonts only once in order to improve
+performance.</li>
+<li>Updated bzip2 to 1.0.4.</li>
+<li>Updated Jasper library to version 1.900.1.</li>
+<li>Updated jbigkit to 1.6</li>
+<li>Updated lcms to 1.17</li>
+<li>Updated libpng to 1.2.27.</li>
+<li>Updated libtiff to 3.8.2</li>
+<li>Updated zlib to 1.2.3.</li>
+<li>Libtiff supports LZW compression.</li>
+<li>X11 is no longer part of the default build and will not be included
+in the distributed install packages (but can still be built).</li>
+<li>Find latest Ghostscript which idenfies itself as &quot;GPL Ghostscript&quot;.</li>
+<li>Use GlobalMemoryStatusEx(), if available, to determine how much
+physical memory is available. Important for large-memory machines.</li>
+<li>Fixed NTreaddir() so that it does not write beyond its buffer.</li>
+<li>Fixed opendir() emulation function so it can't overwrite the stack.</li>
+<li>FlashPIX library sources are no longer distributed in the Windows
+source package and building FlashPIX is disabled by default.
+FlashPIX may still be built by adding the library (separately
+distributed).</li>
+<li>Fix bitmap handle leak in CropImageToHBITMAP() and ImageToHBITMAP().</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="released-april-4-2004">
+<h1><a class="toc-backref" href="#id32">1.1 (Released April 4, 2004)</a></h1>
+<p>Bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Semaphore fix which is necessary for proper multi-threaded operation.</li>
+<li>Configure script fix to ensure that -lfpx is not supplied to the C
+compiler during subsequent tests since this fails on some systems.</li>
+<li>Fix for East and West gravity computations.</li>
+<li>System error reports (errno) associated with an exception are now
+correctly obtained from the context existing when the exception was
+thrown rather than the context of the reporting function.</li>
+<li>JNG encoder fix. Files were being written with incorrect
+alpha_sample_value in the header. These can be repaired by reading
+them into GM 1.1 and rewriting them.</li>
+<li>XPM fix to module registration.</li>
+<li>PSD fix for index calculation when QuantumDepth&gt;8.</li>
+<li>Validate that geometry specifications only include allowed
+characters.</li>
+<li>SGI fix to save compression type while writing.</li>
+<li>EXIF attributes were not being retrieved when requested.</li>
+<li>Fix for bug when reading an image via a user-provided file
+descriptor.</li>
+<li>The reported image magick string is now always that of the original
+input file (it was sometimes being reported as the format produced by
+an intermediate delegate program).</li>
+<li>Fixes to color profiling of CMYK images.</li>
+<li>Memory leak fixed in DrawClipPath().</li>
+<li>Arc drawing is fixed.</li>
+<li>Command-line parsing bug under Linux due to Linux's sscanfs
+inability to parse strings like &quot;0x1&quot; as &quot;%fx%f&quot; is fixed.</li>
+<li>Scaling of 5 and 6-bit colors was slightly incorrect in BMP, AVI,
+DIB, and TIM datastreams.</li>
+<li>GM utility now reports an error rather than silently returning if
+an unsupported sub-command is provided.</li>
+<li>TIFF coder was writing 16-bit per sample RGB images incorrectly on
+little-endian CPUs.</li>
+</ul>
+</blockquote>
+<p>Performance improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>Texture tiling is now 7X faster.</li>
+<li>Color profile processing speed improvements for colormapped images.</li>
+</ul>
+</blockquote>
+<p>Utilities enhancements:</p>
+<blockquote>
+<ul class="simple">
+<li>For Unix, 'gm version' now includes a dump of the configure and
+build parameters.</li>
+<li>Logging of thrown exceptions is now supported. Use '-debug
+exception'. This is useful to learn when and where errors are
+reported.</li>
+<li>The -define option is added in order to support supplying
+additional options to coders without needing to add additional
+command line options or structure members.</li>
+<li>The output of 'gm identify -verbose' now provides a nice dump
+of EXIF data.</li>
+<li>The -sampling-factor option now accepts as many HxV pairs as
+there are JPEG components. Omitted ones default to 1x1.</li>
+<li>The convert and montage commands now support an -operator command to
+perform arithmetic and bitwise operations on specified image channels.</li>
+</ul>
+</blockquote>
+<p>Coder additions/improvements</p>
+<blockquote>
+<ul class="simple">
+<li>The META coder supports wide characters for the IPTC and 8BIM
+formats.</li>
+<li>The XTRN coder now supports wide characters.</li>
+<li>An &quot;IMAGE&quot; coder is provided which provides access to a large
+number of images (derived from XFig) suitable for use as patterns,
+or as test images.</li>
+<li>The &quot;PATTERN&quot; coder now returns an image pattern tiled to size
+(equivalent results to TILE:IMAGE:pattern). This is for ImageMagick
+compatibility.</li>
+<li>The CINEON coder now supports reading and writing images in CINEON
+&quot;CIN&quot; linear gray and RGB formats. The read support is still very
+weak, but it works for common images.</li>
+<li>The JPEG coder now estimates the original JPEG quality and sampling
+factors and will reuse these options when writing JPEG if the image
+is of the same type and the option &quot;-define JPEG:preserve-settings&quot;
+is supplied.</li>
+<li>The JPEG-2000 coder now supports all Jasper library arguments using
+command line syntax similar to '-define jp2:rate=0.5'.</li>
+<li>Reading and writting compressed SVG (SVGZ) is now supported.</li>
+<li>The TXT coder now observes depth when writing.</li>
+<li>The TIFF coder now outputs colormapped images with 1, 2, 4, and 8
+bits per sample in order to provide much smaller file sizes for
+images with very few colors.</li>
+<li>Many TIFF coder enhancements. Now reads colormapped and grayscale
+images at arbitrary (even odd) bits-per-sample sizes. Now properly
+supports an opacity channel (at any bits-per-sample value) for
+grayscale images. Bilevel grayscale images are treated similar to any
+other grayscale image unless CCITT FAX3/FAX4 compression is
+requested. Now allows the user to specify an arbitrary
+bits-per-sample value for grayscale images (even odd values) using
+&quot;-define tiff:bits-per-sample=value&quot;. Now automatically stores the
+image as TrueColor RGB pixels if the image compression is set to JPEG.
+TIFF files are now written in using the TIFF library's default endian
+order rather than always big endian.</li>
+<li>The WPG coder now renders embedded WMFs.</li>
+<li>The PS3 coder is completely re-written to work much better and
+support more features (see ChangeLog).</li>
+</ul>
+</blockquote>
+<p>Code structure enhancements:</p>
+<blockquote>
+<ul class="simple">
+<li>Error handling has been improved and validated through testing.
+Some errors were being lost, unnecessarily ignored, or reported as
+something else entirely.</li>
+<li>The number of error text messages to be maintained has been reduced
+by consolidating similar messages.</li>
+<li>The memory allocator functions have been replaced with similar
+macros in order to eliminate warnings with GCC 3.3, avoid
+accidentally casting away const, and allow memory debuggers to
+report memory allocations and frees against the correct functions.
+The previously-used functions remain in the library for the purpose
+of compatibility.</li>
+<li>&lt;magick/xwindow.h&gt; no longer depends on magick_config.h defines.</li>
+<li>The text string localization code has been replaced with a simpler
+version written by Bill Radcliffe.</li>
+<li>Added key,value &quot;map&quot; APIs (somewhat similar to C++'s &lt;map&gt;) for
+internal use.</li>
+</ul>
+</blockquote>
+<p>API enhancements:</p>
+<blockquote>
+<ul class="simple">
+<li>Incorporated John Cristy's Wand API's in a new GraphicsMagickWand
+library.</li>
+<li>API definition is no longer dependent on types which vary in size
+(e.g. size_t) depending on large file compilation options. This means
+that applications may now be compiled without any special large file
+options and still work properly with the library.</li>
+<li>Thrown exceptions (ExceptionInfo structure) now include source
+file, source line, function name, and current system error number.</li>
+<li>The GetMagickInfoArray() function is added to replace use of
+GetMagickInfo() for code which needs to access the coder list. This
+is necessary since invoking GetMagickInfo() may re-order the coder
+list, causing problems for code which traverses the list. Using
+GetMagickInfo() to access individual list elements is safe.</li>
+<li>Added the CopyException function to support copying exception info
+from one structure to another.</li>
+<li>Added the ReplaceImageInList function to replace an image in an
+image list.</li>
+<li>Added the DrawPeekGraphicContext function to access the current
+DrawInfo structure in the drawing context stack. Use of this
+function is not recommended since it voilates proper programming
+practices. It is added to support the Wand API's.</li>
+<li>GetImageDepth() now returns an integral value between 1 and
+QuantumDepth and is no longer limited to the values 8, 16, and 32.</li>
+<li>SetImageDepth() supports setting the image modulus depth to any
+integral value between 1 and QuantumDepth. This effects the effective
+numeric precision, not the storage depth, since the quantum storage
+type is still a Quantum.</li>
+<li>GetImageChannelDepth() supports retrieving the modulus depth for a
+specified channel.</li>
+<li>SetImageChannelDepth() supports setting the modulus depth for a
+specified channel.</li>
+<li>ProfileImage is updated to handle alpha channels and grayscale
+images.</li>
+<li>Added GetImageProfile() to retrieve a CMS profile from an image.</li>
+<li>Added SetImageProfile() to attach a CMS profile to an image without
+adjusting the image pixels.</li>
+<li>Added DeleteImageProfile() to remove a CMS profile from an image.</li>
+<li>ConstituteImage() and DispatchImage() now support 'T' (transparency),
+'O' (opacity), and 'P' (pad) options.</li>
+<li>CompositeImage() now supports CopyCyanCompositeOp,
+CopyMagentaCompositeOp, CopyYellowCompositeOp, and
+CopyBlackCompositeOp, composition operators.</li>
+<li>GetColorHistogram() obtains a color histogram for the image.</li>
+<li>QuantumOperatorImage() and QuantumOperatorRegionImage() support
+arithmetic and bitwise operations on specified image channels.</li>
+<li>The semaphore.h header is no longer installed or included in the
+API headers since these functions are private interfaces.</li>
+<li>Configure using --enable-symbol-prefix or define
+PREFIX_MAGICK_SYMBOLS to use the C preprocessor to prefix all library
+symbols with &quot;Gm&quot;. This prevents library symbol conflicts with other
+libraries.</li>
+</ul>
+</blockquote>
+<p>PerlMagick fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>Adjusted a number of function option names so that they match the
+documentation.</li>
+<li>Memory leak fixed.</li>
+<li>Reading files (e.g. GIF) via a file descriptor is fixed.</li>
+</ul>
+</blockquote>
+<p>Build improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>The TRIO library may be used to provide a replacement for vsnprintf
+if the C library doesn't provide it. This improves security on old
+systems.</li>
+<li>Configure only configures for C &amp; C++ languages.</li>
+<li>Configure now does a better job of figuring out how to build a
+thread-safe library across multiple operating systems.</li>
+<li>Configure incorporates a new mmap() test which tests the
+functionality which is needed so that mmap() is not unnecessarily
+rejected on a number of systems. This improves performance for large
+files on those systems.</li>
+<li>Configure/build fixes for IBM's AIX operating system.</li>
+</ul>
+</blockquote>
+<p>Windows-specific improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>The static install package now uses the &quot;uninstalled&quot;
+configuration so that it does not depend on the Windows registry in
+order to run. This allows files from the static install package to
+be copied to another computer without running an installer.</li>
+<li>The executable search path is extended at run-time to include the
+directory where the CORE DLLs reside in order to ensure that they
+are found.</li>
+<li>Adding the -t option to VisualMagick configure enables building
+all of the coders into one library in order to save build time and
+simplify linkage.</li>
+<li>The XTRN coder now supports wide characters.</li>
+<li>LCMS library updated to version 1.10.</li>
+<li>GMDisplay displays a checkerboard pattern behind transparent images.</li>
+<li>Support is provided for issuing log messages to the Windows standard
+logging system.</li>
+<li>Project files are now provided for use with Borland C++ Builder 6.0.</li>
+<li>Updated LCMS version to 1.12.</li>
+<li>Updated FreeType version to 2.1.5.</li>
+<li>Updated JBIG-KIT to version 1.5.</li>
+<li>Updated libpng to version 1.2.5.</li>
+<li>Updated libwmf to version 0.2.8.2.</li>
+<li>Updates zlib to version 1.2.1.</li>
+<li>ActivePerl 5.8.1 Build 807 now supported.</li>
+<li>GraphicsMagick now compiles using Visual Studio .NET 2003.</li>
+</ul>
+</blockquote>
+</div>
+<hr class="docutils" />
+<div class="section" id="released-in-may-2003">
+<h1><a class="toc-backref" href="#id33">1.0 (Released in May, 2003)</a></h1>
+<p>GraphicsMagick support services:</p>
+<blockquote>
+<ul class="simple">
+<li>Master web site at &quot;<a class="reference external" href="http://www.GraphicsMagick.org/">http://www.GraphicsMagick.org/</a>&quot;.</li>
+<li>Mailing lists, bug tracking, and forums available via
+&quot;<a class="reference external" href="https://sourceforge.net/projects/graphicsmagick/">https://sourceforge.net/projects/graphicsmagick/</a>&quot;.</li>
+<li>Mercurial Web via &quot;<a class="reference external" href="http://hg.code.sf.net/p/graphicsmagick/code/">http://hg.code.sf.net/p/graphicsmagick/code/</a>&quot;.</li>
+<li>Mercurial mirror via SourceForge (find instructions at
+&quot;<a class="reference external" href="http://www.graphicsmagick.org/Hg.html">http://www.graphicsmagick.org/Hg.html</a>&quot;).</li>
+<li>FTP via &quot;<a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick">ftp://ftp.graphicsmagick.org/pub/GraphicsMagick</a>&quot;.</li>
+</ul>
+</blockquote>
+<p>Project maintenance improvements:</p>
+<blockquote>
+<ul class="simple">
+<li>ChangeLog conforms to the GNU standard and all CVS commits include
+useful log messages.</li>
+<li>CVS commit messages posted to graphicsmagick-commit mail list.</li>
+<li>CVS commit messages contain CVSWeb URL references.</li>
+</ul>
+</blockquote>
+<p>Footprint changes from ImageMagick:</p>
+<blockquote>
+<ul class="simple">
+<li>Library -lMagick renamed to -lGraphicsMagick.</li>
+<li>Library -lMagick++ renamed to -lGraphicsMagick++.</li>
+<li>Utilities consolidated into a single 'gm' utility (e.g. use 'gm
+convert').</li>
+<li>Script Magick-config renamed to GraphicsMagick-config.</li>
+<li>Script Magick++-config renamed to GraphicsMagick++-config.</li>
+<li>Headers installed under ${PREFIX}/include/GraphicsMagick.</li>
+<li>PerlMagick namespace renamed from &quot;Image::Magick&quot; to &quot;Graphics::Magick&quot;.</li>
+<li>Pkgconfig files GraphicsMagick.pc and GraphicsMagick++.pc are
+installed in $libdir/pkgconfig to assist pkg-config users.</li>
+<li>Coder modules installed to lib/GraphicsMagick-1.0/modules-Q8/coders.</li>
+<li>Filter modules installed to lib/GraphicsMagick-1.0/modules-Q8/filters.</li>
+</ul>
+</blockquote>
+<p>Many performance enhancements:</p>
+<blockquote>
+<ul class="simple">
+<li>Default QuantumDepth is 8 since this is adequate for most purposes
+and more efficient than 16.</li>
+<li>The Magick++ demo (compiled with QuantumDepth=8 and -O2) runs about
+1.8X faster under SPARC/Solaris than the same demo with ImageMagick
+5.5.4.</li>
+<li>Colorspace transformations are much faster.</li>
+<li>Grayscale/monochrome image handling is much faster.</li>
+<li>PseudoClass image handling is faster.</li>
+<li>Text annotations using FreeType are much faster.</li>
+<li>Image file I/O is much faster.</li>
+<li>RLE-compressed MIFF reading much faster.</li>
+</ul>
+</blockquote>
+<p>Code structure enhancements:</p>
+<blockquote>
+<ul class="simple">
+<li>All utility support functions moved to magick/command.c in order to
+significantly reduce link dependencies, allowing statically-linked
+programs to be smaller.</li>
+<li>Use of MogrifyImage() eliminated except for by utilities.</li>
+<li>Re-builds due to changes to &lt;magick/image.h&gt; reduced by splitting the
+header into multiple headers.</li>
+<li>ISO C '99 typedefs (gm_int16_t, gm_uint16_t, gm_int32_t, gm_uint32_t,
+gm_int64_t, gm_uint64_t) are available for use.</li>
+</ul>
+</blockquote>
+<p>Feature enhancements:</p>
+<blockquote>
+<ul class="simple">
+<li>Module loader always enabled for shared builds to allow extension.</li>
+<li>Loading of arbitrary filter modules (via -process option) supported
+under Unix as well as Windows.</li>
+<li>SVG coder allows specifying size and initial background color.</li>
+<li>JPEG-2000 coder (JP2) updated to work with Jasper 1.7.</li>
+<li>HWB and HSL image colorspace translation support.</li>
+<li>JNG/MNG/PNG format support tracks ImageMagick version.</li>
+<li>BMP encoder can write 16-color indexed BMPs now as well as 2-color
+BMPs (not restricted to monochrome).</li>
+<li>TIFF decoder now includes optimized support for tiled and stripped
+TIFF.</li>
+<li>The -random-threshold option (RandomThresholdImage()) is added to
+threshold an image to bilevel using random thresholding.</li>
+</ul>
+</blockquote>
+<p>Major bug fixes:</p>
+<blockquote>
+<ul class="simple">
+<li>100% successful test completion at all quantum depths (8/16/32).</li>
+<li>A temporary file management subsystem is added to ensure that all
+temporary files are removed before program exit. Temporary files are
+created and used in a secure fashion to avoid the possibility that a
+&quot;trojan&quot; temporary file (e.g. a symbolic link, or a file containing
+unsafe content) is created before a delegate has the chance to write
+to it. The environment variable MAGICK_TMPDIR allows the user to
+specify where temporary files are created without altering where
+other programs create their temporary files. Temporary filenames are
+created in 8+3 format to hopefully be more acceptable to ralcgm.</li>
+<li>When dithering is disabled, don't dither when converting to a
+PseudoClass, grayscale, or monochrome image. Disabling dithering
+may cause these translations to be much faster.</li>
+<li>PICON format works with BLOBs.</li>
+<li>No longer removes input file when pinging a FlashPIX file.</li>
+<li>Arc drawing and texture fill fixes from ImageMagick.</li>
+<li>Sample, scale and affine fixes from ImageMagick.</li>
+<li>MIFF colormaps are now scaled properly while reading.</li>
+<li>CMYK translation works for QuantumDepth=32.</li>
+<li>ConstituteImage now works properly for grayscale images.</li>
+<li>Built-in tilde expansion and filename globbing now works properly.</li>
+<li>InitializeMagick now registers signal handlers to ensure that
+resources are released before program exit. This helps avoid
+temporary file leaks due to the user using &quot;CONTROL-C&quot;.</li>
+<li>The installed &lt;magick/magick_config.h&gt; header now only contains
+the few definitions required by the API headers. This should
+significantly reduce or eliminate conflicts with other package
+headers.</li>
+</ul>
+</blockquote>
+<p>Windows platform enhancements:</p>
+<blockquote>
+<ul class="simple">
+<li>Configure updated for Visual C++ 7.0.</li>
+<li>OLE object (ImageMagickObject) re-written to work with Visual C++ 7.0</li>
+<li>New function, CropImageToHBITMAP(), to return a region of the image
+as a Windows HBITMAP.</li>
+<li>Use vsnprintf to format strings under Windows (safer).</li>
+</ul>
+</blockquote>
+<hr class="docutils" />
+<p>On November 19, 2002, GraphicsMagick was created as a fork of
+ImageMagick, several days before the ImageMagick 5.5.2 release.</p>
+<p>The objectives of GraphicsMagick are to:</p>
+<blockquote>
+<ul class="simple">
+<li>Use an open development model.</li>
+<li>Encourage new developers to join the project.</li>
+<li>Avoid unnecessary source code &quot;churn&quot;.</li>
+<li>Establish and preserve a stable API.</li>
+<li>Use efficient coding practices which result in fast code.</li>
+<li>Improve memory efficiency.</li>
+<li>Use a release process which assures a working product.</li>
+<li>Maintain an accurate ChangeLog.</li>
+</ul>
+</blockquote>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/OpenMP.html b/www/OpenMP.html
new file mode 100644
index 0000000..d2ab11a
--- /dev/null
+++ b/www/OpenMP.html
@@ -0,0 +1,10115 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>OpenMP in GraphicsMagick</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="openmp-in-graphicsmagick">
+<h1 class="title">OpenMP in GraphicsMagick</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
+<li><a class="reference internal" href="#results" id="id2">Results</a><ul>
+<li><a class="reference internal" href="#openindiana-oi-151a7-intel-xeon-e5-2680-2-70ghz-gcc-4-7-1-x86-64" id="id3">OpenIndiana oi_151a7 / Intel Xeon E5-2680 2.70GHz / GCC 4.7.1 x86-64</a></li>
+<li><a class="reference internal" href="#ubuntu-linux-11-10-intel-xeon-e5649-open64-compiler" id="id4">Ubuntu Linux 11.10 / Intel Xeon E5649 / Open64 Compiler</a></li>
+<li><a class="reference internal" href="#ubuntu-linux-11-10-intel-xeon-e5649-gcc-compiler" id="id5">Ubuntu Linux 11.10 / Intel Xeon E5649 / GCC Compiler</a></li>
+<li><a class="reference internal" href="#ubuntu-linux-11-10-amd-opteron-6220-open64-compiler" id="id6">Ubuntu Linux 11.10 / AMD Opteron 6220 / Open64 Compiler</a></li>
+<li><a class="reference internal" href="#ubuntu-linux-11-10-amd-opteron-6220-gcc-compiler" id="id7">Ubuntu Linux 11.10 / AMD Opteron 6220 / GCC Compiler</a></li>
+<li><a class="reference internal" href="#sun-solaris-amd-opteron" id="id8">Sun Solaris / AMD Opteron</a></li>
+<li><a class="reference internal" href="#sun-solaris-ultrasparc-iii" id="id9">Sun Solaris / UltraSPARC III</a></li>
+<li><a class="reference internal" href="#ibm-aix-ibm-power5" id="id10">IBM AIX / IBM Power5+</a></li>
+<li><a class="reference internal" href="#apple-os-x-ibm-g5" id="id11">Apple OS-X/IBM G5</a></li>
+<li><a class="reference internal" href="#freebsd-intel-xeon" id="id12">FreeBSD / Intel Xeon</a></li>
+<li><a class="reference internal" href="#windows-xp-msvc-intel-core-2-quad" id="id13">Windows XP / MSVC / Intel Core 2 Quad</a></li>
+<li><a class="reference internal" href="#windows-7-mingw-intel-core-2-quad" id="id14">Windows 7 / MinGW / Intel Core 2 Quad</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="overview">
+<h1><a class="toc-backref" href="#id1">Overview</a></h1>
+<p>GraphicsMagick has been transformed to use <a class="reference external" href="http://openmp.org/">OpenMP</a> for the 1.3 release
+series. OpenMP is a portable framework for accelerating CPU-bound and
+memory-bound operations using multiple threads. OpenMP originates in
+the super-computing world and has been available in one form or
+another since the late '90s.</p>
+<p>Since GCC 4.2 has introduced excellent OpenMP support via <a class="reference external" href="http://gcc.gnu.org/onlinedocs/libgomp/">GOMP</a>,
+OpenMP has become available to the masses. Microsoft Visual Studio
+Professional 2005 and later support OpenMP so Windows users can
+benefit as well. Any multi-CPU and/or multi-core system is potentially
+a good candidate for use with OpenMP. Unfortunately, some older
+multi-CPU hardware is more suitable for multi-processing than
+multi-threading. Modern multi-core chipsets from AMD, Intel and
+Sun/Oracle perform very well with OpenMP.</p>
+<p>Most image processing routines are comprised of loops which iterate
+through the image pixels, image rows, or image regions. These loops are
+accelerated using OpenMP by executing portions of the total loops in
+different threads, and therefore on a different processor core. CPU-bound
+algorithms benefit most from OpenMP, but memory-bound algorithms may also
+benefit as well since the memory is accessed by different CPU cores, and
+sometimes the CPUs have their own path to memory. For example, the AMD
+Opteron is a NUMA (Non-Uniform Memory Architecture) design such that
+multi-CPU systems split the system memory across CPUs so each CPU adds
+more memory bandwidth as well.</p>
+<p>For severely CPU-bound algorithms, it is not uncommon to see a linear
+speed-up (within the constraints of <a class="reference external" href="http://en.wikipedia.org/wiki/Amdahl%27s_law">Amdahl's law</a>) due to the number
+of cores. For example, a two core system executes the algorithm twice
+as fast, and a four core system executes the algorithm four times as
+fast. Memory-bound algorithms scale based on the memory bandwith
+available to the cores. For example, memory-bound algorithms scale up
+to almost 1.5X on my four core Opteron system due to its NUMA
+architecture. Some systems/CPUs are able to immediately context switch
+to another thread if the core would be blocked waiting for memory,
+allowing multiple memory accesses to be pending at once, and thereby
+improving throughput. For example, typical speedup of 20-32X (average
+24X) has been observed on the Sun SPARC T2 CPU, which provides 8
+cores, with 8 virtual CPUs per core (64 threads).</p>
+<p>An approach used in GraphicsMagick is to recognize the various access
+patterns in the existing code, and re-write the algorithms (sometimes
+from scratch) to be based on a framework that we call &quot;pixel iterators&quot;.
+With this approach, the computation is restricted to a small unit (a
+callback function) with very well defined properties, and no knowledge as
+to how it is executed or where the data comes from. This approach removes
+the loops from the code and puts the loops in the framework, which may be
+adjusted based on experience. The continuing strategy will be to
+recognize design patterns and build frameworks which support those
+patterns. Sometimes algorithms are special/exotic enough that it is much
+easier to instrument the code for OpenMP rather than to attempt to fit
+the algorithm into a framework.</p>
+<p>Since OpenMP is based on multi-threading, multiple threads access the
+underlying pixel storage at once. The interface to this underlying
+storage is called the &quot;pixel cache&quot;. The original pixel cache code
+(derived from ImageMagick) was thread safe only to the extent that it
+allowed one thread per image. This code has now been re-written so that
+multiple threads may safely and efficiently work on the pixels in one
+image. The re-write also makes the pixel cache thread safe if a
+multi-threaded application uses an OpenMP-fortified library.</p>
+<p>The following is an example of per-core speed-up due to OpenMP on a
+four-core system. All the pixel quantum values have 30% gaussian
+noise added:</p>
+<pre class="literal-block">
+% gm benchmark -stepthreads 1 -duration 10 convert \
+ -size 2048x1080 pattern:granite -operator all Noise-Gaussian 30% null:
+Results: 1 threads 5 iter 11.07s user 11.07s total 0.452 iter/s (0.452 iter/s cpu) 1.00 speedup 1.000 karp-flatt
+Results: 2 threads 10 iter 22.16s user 11.11s total 0.900 iter/s (0.451 iter/s cpu) 1.99 speedup 0.004 karp-flatt
+Results: 3 threads 14 iter 31.06s user 10.47s total 1.337 iter/s (0.451 iter/s cpu) 2.96 speedup 0.007 karp-flatt
+Results: 4 threads 18 iter 40.01s user 10.24s total 1.758 iter/s (0.450 iter/s cpu) 3.89 speedup 0.009 karp-flatt
+</pre>
+<p>Note that the &quot;iter/s cpu&quot; value is a measure of the number of
+iterations given the amount of reported CPU time consumed. It is an
+effective measure of relative efficacy since its value should ideally
+not drop as iterations are added. The karp-flatt ratio is another
+useful metric for evaluating thread-speedup efficiency. In the above
+example, the total speedup was about 3.9X with only a slight loss of
+CPU efficiency as threads are added.</p>
+<p>According to the OpenMP specification, the OMP_NUM_THREADS evironment
+variable may be used to specify the number of threads available to the
+application. Typically this is set to the number of processor cores on
+the system but may be set lower to limit resource consumption or (in
+some cases) to improve execution efficiency. The GraphicsMagick
+commands also accept a <tt class="docutils literal"><span class="pre">-limit</span> threads limit</tt> type option for
+specifying the maximum number of threads to use.</p>
+</div>
+<div class="section" id="results">
+<h1><a class="toc-backref" href="#id2">Results</a></h1>
+<p>A simple scheme was developed in order to evaluate the performance
+boost with varying numbers of threads. GraphicsMagick's built-in
+benchmark facility is used. The selected algorithm is executed
+repeatedly until a specified amount of time has elapsed. The input
+image is generated on the fly by tiling a small image over a large
+area using a specification like <cite>-size 4000x3000 tile:model.pnm</cite>. It
+is important to note that the time to generate the input image is
+included in the benchmark timings so that even if an algorithm
+achieves perfect linear scaling, the measured difference is likely to
+be less than the number of cores used and the impact could be
+substantial if image generation is slow. Many modern CPUs increase
+the core frequency substantially (&quot;turbo mode&quot;) when only a few cores
+are being used and this unfairly penalizes the calculated per-thread
+speedup results which are based on the time to run with just one
+thread.</p>
+<p>A typical benchmark command using the built-in benchmark facility
+(-stepthreads requires GraphicsMagick 1.3.13 or later) looks like:</p>
+<pre class="literal-block">
+gm benchmark -stepthreads 1 -duration 5 convert \
+ -size 4000x3000 tile:model.pnm -median 2 null:
+</pre>
+<p>The first test executed is <cite>-noop</cite> since it does no work other than
+to generate the input image. This represents how fast it is possible
+to go based on how fast the input image may be generated.</p>
+<div class="section" id="openindiana-oi-151a7-intel-xeon-e5-2680-2-70ghz-gcc-4-7-1-x86-64">
+<h2><a class="toc-backref" href="#id3">OpenIndiana oi_151a7 / Intel Xeon E5-2680 2.70GHz / GCC 4.7.1 x86-64</a></h2>
+<!-- Last update: Sat Feb 16 15:53:21 CST 2013 -->
+<p>The following results were obtained from an Intel Xeon E5-2680 at
+2.70GHz. This CPU has 16 cores and 32 threads. GCC 4.7.1 was used to
+build the software. Please note that this CPU has a turbo-boost
+feature which clocks the CPU at 3.9GHz when only a few cores are
+active so the calculated speedup (based on performance with one
+thread) is reported at considerably less (e.g 60% less) than it would
+be based on all cores active:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On 16 core Intel Xeon E5-2680 CPU:</caption>
+<colgroup>
+<col width="45%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="8%" />
+<col width="4%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">4</th>
+<th class="head">8</th>
+<th class="head">12</th>
+<th class="head">16</th>
+<th class="head">20</th>
+<th class="head">24</th>
+<th class="head">25</th>
+<th class="head">32</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.76</td>
+<td class="decimal">6.50</td>
+<td class="decimal">8.76</td>
+<td class="decimal">10.62</td>
+<td class="decimal">10.68</td>
+<td class="decimal">12.23</td>
+<td class="decimal">13.61</td>
+<td class="decimal">15.00</td>
+<td class="decimal">6.496</td>
+<td>9</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.13</td>
+<td class="decimal">2.58</td>
+<td class="decimal">2.82</td>
+<td class="decimal">2.67</td>
+<td class="decimal">2.75</td>
+<td class="decimal">2.85</td>
+<td class="decimal">2.91</td>
+<td class="decimal">2.94</td>
+<td class="decimal">7.186</td>
+<td>9</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.47</td>
+<td class="decimal">3.12</td>
+<td class="decimal">3.64</td>
+<td class="decimal">3.33</td>
+<td class="decimal">3.57</td>
+<td class="decimal">3.69</td>
+<td class="decimal">3.79</td>
+<td class="decimal">3.87</td>
+<td class="decimal">6.587</td>
+<td>9</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.98</td>
+<td class="decimal">4.29</td>
+<td class="decimal">5.02</td>
+<td class="decimal">4.63</td>
+<td class="decimal">5.00</td>
+<td class="decimal">5.27</td>
+<td class="decimal">5.50</td>
+<td class="decimal">5.71</td>
+<td class="decimal">5.416</td>
+<td>9</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.64</td>
+<td class="decimal">3.48</td>
+<td class="decimal">3.90</td>
+<td class="decimal">3.72</td>
+<td class="decimal">3.85</td>
+<td class="decimal">4.00</td>
+<td class="decimal">4.07</td>
+<td class="decimal">4.09</td>
+<td class="decimal">3.435</td>
+<td>9</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.91</td>
+<td class="decimal">4.08</td>
+<td class="decimal">4.77</td>
+<td class="decimal">4.46</td>
+<td class="decimal">3.67</td>
+<td class="decimal">3.73</td>
+<td class="decimal">3.63</td>
+<td class="decimal">3.50</td>
+<td class="decimal">41.800</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.59</td>
+<td class="decimal">6.24</td>
+<td class="decimal">8.27</td>
+<td class="decimal">9.10</td>
+<td class="decimal">7.23</td>
+<td class="decimal">8.12</td>
+<td class="decimal">9.06</td>
+<td class="decimal">9.05</td>
+<td class="decimal">18.200</td>
+<td>5</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.51</td>
+<td class="decimal">5.59</td>
+<td class="decimal">7.37</td>
+<td class="decimal">5.86</td>
+<td class="decimal">6.49</td>
+<td class="decimal">7.07</td>
+<td class="decimal">7.82</td>
+<td class="decimal">7.57</td>
+<td class="decimal">24.303</td>
+<td>8</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.77</td>
+<td class="decimal">3.72</td>
+<td class="decimal">4.24</td>
+<td class="decimal">4.39</td>
+<td class="decimal">3.75</td>
+<td class="decimal">3.74</td>
+<td class="decimal">3.68</td>
+<td class="decimal">3.81</td>
+<td class="decimal">37.800</td>
+<td>5</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.74</td>
+<td class="decimal">3.68</td>
+<td class="decimal">4.01</td>
+<td class="decimal">3.36</td>
+<td class="decimal">3.86</td>
+<td class="decimal">3.84</td>
+<td class="decimal">3.81</td>
+<td class="decimal">3.57</td>
+<td class="decimal">34.263</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.82</td>
+<td class="decimal">3.83</td>
+<td class="decimal">4.31</td>
+<td class="decimal">3.78</td>
+<td class="decimal">3.82</td>
+<td class="decimal">4.00</td>
+<td class="decimal">3.78</td>
+<td class="decimal">3.74</td>
+<td class="decimal">36.200</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.67</td>
+<td class="decimal">3.97</td>
+<td class="decimal">4.24</td>
+<td class="decimal">4.01</td>
+<td class="decimal">3.60</td>
+<td class="decimal">4.05</td>
+<td class="decimal">3.86</td>
+<td class="decimal">3.69</td>
+<td class="decimal">35.657</td>
+<td>4</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.93</td>
+<td class="decimal">7.18</td>
+<td class="decimal">10.52</td>
+<td class="decimal">12.85</td>
+<td class="decimal">13.94</td>
+<td class="decimal">16.18</td>
+<td class="decimal">17.63</td>
+<td class="decimal">19.09</td>
+<td class="decimal">4.239</td>
+<td>9</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.96</td>
+<td class="decimal">7.19</td>
+<td class="decimal">10.54</td>
+<td class="decimal">13.38</td>
+<td class="decimal">14.19</td>
+<td class="decimal">16.09</td>
+<td class="decimal">17.56</td>
+<td class="decimal">18.37</td>
+<td class="decimal">4.078</td>
+<td>9</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.54</td>
+<td class="decimal">5.93</td>
+<td class="decimal">7.92</td>
+<td class="decimal">9.27</td>
+<td class="decimal">9.01</td>
+<td class="decimal">9.36</td>
+<td class="decimal">9.44</td>
+<td class="decimal">9.55</td>
+<td class="decimal">25.697</td>
+<td>9</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.09</td>
+<td class="decimal">4.81</td>
+<td class="decimal">5.45</td>
+<td class="decimal">5.87</td>
+<td class="decimal">5.89</td>
+<td class="decimal">5.93</td>
+<td class="decimal">5.86</td>
+<td class="decimal">5.66</td>
+<td class="decimal">3.605</td>
+<td>7</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.56</td>
+<td class="decimal">5.88</td>
+<td class="decimal">7.82</td>
+<td class="decimal">9.31</td>
+<td class="decimal">8.91</td>
+<td class="decimal">9.18</td>
+<td class="decimal">9.48</td>
+<td class="decimal">9.45</td>
+<td class="decimal">26.243</td>
+<td>8</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.35</td>
+<td class="decimal">5.23</td>
+<td class="decimal">6.65</td>
+<td class="decimal">7.43</td>
+<td class="decimal">7.73</td>
+<td class="decimal">7.97</td>
+<td class="decimal">8.24</td>
+<td class="decimal">8.53</td>
+<td class="decimal">8.858</td>
+<td>9</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.96</td>
+<td class="decimal">7.18</td>
+<td class="decimal">10.61</td>
+<td class="decimal">12.83</td>
+<td class="decimal">11.58</td>
+<td class="decimal">12.49</td>
+<td class="decimal">13.27</td>
+<td class="decimal">14.07</td>
+<td class="decimal">3.448</td>
+<td>9</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.70</td>
+<td class="decimal">6.64</td>
+<td class="decimal">9.49</td>
+<td class="decimal">11.44</td>
+<td class="decimal">11.73</td>
+<td class="decimal">12.63</td>
+<td class="decimal">13.45</td>
+<td class="decimal">14.23</td>
+<td class="decimal">16.168</td>
+<td>9</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.92</td>
+<td class="decimal">7.07</td>
+<td class="decimal">10.12</td>
+<td class="decimal">12.00</td>
+<td class="decimal">13.70</td>
+<td class="decimal">14.98</td>
+<td class="decimal">16.50</td>
+<td class="decimal">18.01</td>
+<td class="decimal">6.809</td>
+<td>9</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.98</td>
+<td class="decimal">7.26</td>
+<td class="decimal">10.79</td>
+<td class="decimal">12.57</td>
+<td class="decimal">14.19</td>
+<td class="decimal">15.91</td>
+<td class="decimal">17.95</td>
+<td class="decimal">19.60</td>
+<td class="decimal">2.136</td>
+<td>9</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.76</td>
+<td class="decimal">6.49</td>
+<td class="decimal">9.03</td>
+<td class="decimal">11.20</td>
+<td class="decimal">9.85</td>
+<td class="decimal">10.39</td>
+<td class="decimal">10.62</td>
+<td class="decimal">10.53</td>
+<td class="decimal">16.501</td>
+<td>5</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.74</td>
+<td class="decimal">6.50</td>
+<td class="decimal">9.07</td>
+<td class="decimal">10.68</td>
+<td class="decimal">9.78</td>
+<td class="decimal">11.05</td>
+<td class="decimal">11.48</td>
+<td class="decimal">11.88</td>
+<td class="decimal">17.600</td>
+<td>9</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.75</td>
+<td class="decimal">6.47</td>
+<td class="decimal">9.19</td>
+<td class="decimal">10.95</td>
+<td class="decimal">9.63</td>
+<td class="decimal">10.63</td>
+<td class="decimal">11.21</td>
+<td class="decimal">11.18</td>
+<td class="decimal">14.970</td>
+<td>8</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.93</td>
+<td class="decimal">7.07</td>
+<td class="decimal">10.42</td>
+<td class="decimal">12.80</td>
+<td class="decimal">13.83</td>
+<td class="decimal">16.23</td>
+<td class="decimal">18.33</td>
+<td class="decimal">20.46</td>
+<td class="decimal">5.523</td>
+<td>9</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.90</td>
+<td class="decimal">7.05</td>
+<td class="decimal">10.39</td>
+<td class="decimal">12.00</td>
+<td class="decimal">13.41</td>
+<td class="decimal">15.21</td>
+<td class="decimal">17.51</td>
+<td class="decimal">19.61</td>
+<td class="decimal">6.433</td>
+<td>9</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.692</td>
+<td>3</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.89</td>
+<td class="decimal">6.92</td>
+<td class="decimal">10.29</td>
+<td class="decimal">12.43</td>
+<td class="decimal">11.67</td>
+<td class="decimal">13.34</td>
+<td class="decimal">15.28</td>
+<td class="decimal">16.84</td>
+<td class="decimal">2.004</td>
+<td>9</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.77</td>
+<td class="decimal">6.90</td>
+<td class="decimal">10.26</td>
+<td class="decimal">10.85</td>
+<td class="decimal">12.79</td>
+<td class="decimal">14.49</td>
+<td class="decimal">16.79</td>
+<td class="decimal">18.54</td>
+<td class="decimal">0.723</td>
+<td>9</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.46</td>
+<td class="decimal">5.56</td>
+<td class="decimal">7.30</td>
+<td class="decimal">8.27</td>
+<td class="decimal">8.72</td>
+<td class="decimal">9.00</td>
+<td class="decimal">8.82</td>
+<td class="decimal">8.68</td>
+<td class="decimal">33.600</td>
+<td>7</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.72</td>
+<td class="decimal">6.47</td>
+<td class="decimal">8.66</td>
+<td class="decimal">10.12</td>
+<td class="decimal">8.89</td>
+<td class="decimal">10.24</td>
+<td class="decimal">11.31</td>
+<td class="decimal">11.14</td>
+<td class="decimal">15.706</td>
+<td>8</td>
+</tr>
+<tr><td>-motion-blur 0x3+30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">1.45</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.56</td>
+<td class="decimal">1.57</td>
+<td class="decimal">1.63</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.68</td>
+<td class="decimal">0.376</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.90</td>
+<td class="decimal">4.08</td>
+<td class="decimal">4.75</td>
+<td class="decimal">4.31</td>
+<td class="decimal">4.59</td>
+<td class="decimal">4.83</td>
+<td class="decimal">5.07</td>
+<td class="decimal">5.23</td>
+<td class="decimal">14.286</td>
+<td>9</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.91</td>
+<td class="decimal">7.04</td>
+<td class="decimal">9.88</td>
+<td class="decimal">11.53</td>
+<td class="decimal">14.10</td>
+<td class="decimal">16.69</td>
+<td class="decimal">19.02</td>
+<td class="decimal">21.41</td>
+<td class="decimal">2.462</td>
+<td>9</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.88</td>
+<td class="decimal">6.93</td>
+<td class="decimal">10.08</td>
+<td class="decimal">11.99</td>
+<td class="decimal">13.55</td>
+<td class="decimal">15.88</td>
+<td class="decimal">18.07</td>
+<td class="decimal">20.19</td>
+<td class="decimal">3.675</td>
+<td>9</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.99</td>
+<td class="decimal">4.23</td>
+<td class="decimal">5.04</td>
+<td class="decimal">4.63</td>
+<td class="decimal">5.02</td>
+<td class="decimal">5.36</td>
+<td class="decimal">5.63</td>
+<td class="decimal">5.85</td>
+<td class="decimal">14.427</td>
+<td>9</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.80</td>
+<td class="decimal">6.64</td>
+<td class="decimal">9.32</td>
+<td class="decimal">11.60</td>
+<td class="decimal">12.30</td>
+<td class="decimal">14.03</td>
+<td class="decimal">15.69</td>
+<td class="decimal">17.40</td>
+<td class="decimal">5.917</td>
+<td>9</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.87</td>
+<td class="decimal">6.85</td>
+<td class="decimal">9.86</td>
+<td class="decimal">11.97</td>
+<td class="decimal">13.35</td>
+<td class="decimal">15.51</td>
+<td class="decimal">17.48</td>
+<td class="decimal">19.42</td>
+<td class="decimal">4.582</td>
+<td>9</td>
+</tr>
+<tr><td>+noise Random</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.21</td>
+<td class="decimal">4.82</td>
+<td class="decimal">5.44</td>
+<td class="decimal">5.38</td>
+<td class="decimal">5.88</td>
+<td class="decimal">6.36</td>
+<td class="decimal">6.74</td>
+<td class="decimal">7.11</td>
+<td class="decimal">12.948</td>
+<td>9</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.90</td>
+<td class="decimal">6.96</td>
+<td class="decimal">10.03</td>
+<td class="decimal">12.31</td>
+<td class="decimal">11.52</td>
+<td class="decimal">13.19</td>
+<td class="decimal">15.22</td>
+<td class="decimal">16.81</td>
+<td class="decimal">1.984</td>
+<td>9</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.90</td>
+<td class="decimal">6.95</td>
+<td class="decimal">10.15</td>
+<td class="decimal">11.64</td>
+<td class="decimal">12.82</td>
+<td class="decimal">14.36</td>
+<td class="decimal">16.64</td>
+<td class="decimal">18.51</td>
+<td class="decimal">0.722</td>
+<td>9</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.63</td>
+<td class="decimal">3.58</td>
+<td class="decimal">3.82</td>
+<td class="decimal">3.14</td>
+<td class="decimal">3.16</td>
+<td class="decimal">3.14</td>
+<td class="decimal">3.21</td>
+<td class="decimal">3.06</td>
+<td class="decimal">47.000</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.71</td>
+<td class="decimal">3.70</td>
+<td class="decimal">4.69</td>
+<td class="decimal">4.02</td>
+<td class="decimal">4.20</td>
+<td class="decimal">4.28</td>
+<td class="decimal">4.19</td>
+<td class="decimal">4.54</td>
+<td class="decimal">37.400</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.39</td>
+<td class="decimal">3.00</td>
+<td class="decimal">3.15</td>
+<td class="decimal">3.21</td>
+<td class="decimal">3.23</td>
+<td class="decimal">3.16</td>
+<td class="decimal">3.07</td>
+<td class="decimal">2.93</td>
+<td class="decimal">39.521</td>
+<td>6</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.48</td>
+<td class="decimal">3.09</td>
+<td class="decimal">3.26</td>
+<td class="decimal">3.21</td>
+<td class="decimal">3.40</td>
+<td class="decimal">3.31</td>
+<td class="decimal">3.22</td>
+<td class="decimal">3.05</td>
+<td class="decimal">40.519</td>
+<td>6</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.99</td>
+<td class="decimal">7.27</td>
+<td class="decimal">10.81</td>
+<td class="decimal">12.16</td>
+<td class="decimal">14.98</td>
+<td class="decimal">17.81</td>
+<td class="decimal">20.17</td>
+<td class="decimal">23.13</td>
+<td class="decimal">2.637</td>
+<td>9</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.57</td>
+<td class="decimal">6.00</td>
+<td class="decimal">7.98</td>
+<td class="decimal">8.32</td>
+<td class="decimal">7.48</td>
+<td class="decimal">8.11</td>
+<td class="decimal">8.56</td>
+<td class="decimal">8.77</td>
+<td class="decimal">23.400</td>
+<td>9</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.92</td>
+<td class="decimal">7.06</td>
+<td class="decimal">10.36</td>
+<td class="decimal">13.32</td>
+<td class="decimal">13.81</td>
+<td class="decimal">16.09</td>
+<td class="decimal">18.24</td>
+<td class="decimal">19.57</td>
+<td class="decimal">6.733</td>
+<td>9</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.96</td>
+<td class="decimal">7.20</td>
+<td class="decimal">10.63</td>
+<td class="decimal">13.40</td>
+<td class="decimal">14.49</td>
+<td class="decimal">17.11</td>
+<td class="decimal">19.93</td>
+<td class="decimal">22.50</td>
+<td class="decimal">4.118</td>
+<td>9</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.94</td>
+<td class="decimal">7.14</td>
+<td class="decimal">10.51</td>
+<td class="decimal">13.07</td>
+<td class="decimal">14.56</td>
+<td class="decimal">17.02</td>
+<td class="decimal">19.79</td>
+<td class="decimal">22.00</td>
+<td class="decimal">5.325</td>
+<td>9</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.57</td>
+<td class="decimal">5.78</td>
+<td class="decimal">7.55</td>
+<td class="decimal">7.92</td>
+<td class="decimal">6.65</td>
+<td class="decimal">7.32</td>
+<td class="decimal">7.56</td>
+<td class="decimal">7.41</td>
+<td class="decimal">23.658</td>
+<td>5</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.01</td>
+<td class="decimal">4.25</td>
+<td class="decimal">4.95</td>
+<td class="decimal">5.04</td>
+<td class="decimal">5.28</td>
+<td class="decimal">5.32</td>
+<td class="decimal">5.05</td>
+<td class="decimal">4.84</td>
+<td class="decimal">37.649</td>
+<td>7</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.00</td>
+<td class="decimal">4.27</td>
+<td class="decimal">4.88</td>
+<td class="decimal">4.74</td>
+<td class="decimal">5.44</td>
+<td class="decimal">5.46</td>
+<td class="decimal">5.27</td>
+<td class="decimal">5.07</td>
+<td class="decimal">37.600</td>
+<td>7</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.86</td>
+<td class="decimal">4.33</td>
+<td class="decimal">5.03</td>
+<td class="decimal">4.83</td>
+<td class="decimal">5.03</td>
+<td class="decimal">5.52</td>
+<td class="decimal">5.29</td>
+<td class="decimal">4.96</td>
+<td class="decimal">38.048</td>
+<td>7</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.89</td>
+<td class="decimal">4.11</td>
+<td class="decimal">5.22</td>
+<td class="decimal">5.46</td>
+<td class="decimal">5.09</td>
+<td class="decimal">5.02</td>
+<td class="decimal">5.48</td>
+<td class="decimal">4.99</td>
+<td class="decimal">37.924</td>
+<td>8</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.72</td>
+<td class="decimal">6.37</td>
+<td class="decimal">9.20</td>
+<td class="decimal">11.02</td>
+<td class="decimal">9.32</td>
+<td class="decimal">10.39</td>
+<td class="decimal">11.41</td>
+<td class="decimal">12.51</td>
+<td class="decimal">15.415</td>
+<td>9</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.71</td>
+<td class="decimal">3.50</td>
+<td class="decimal">3.64</td>
+<td class="decimal">3.71</td>
+<td class="decimal">3.35</td>
+<td class="decimal">3.32</td>
+<td class="decimal">3.22</td>
+<td class="decimal">3.24</td>
+<td class="decimal">41.916</td>
+<td>5</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.94</td>
+<td class="decimal">4.06</td>
+<td class="decimal">4.57</td>
+<td class="decimal">3.95</td>
+<td class="decimal">4.79</td>
+<td class="decimal">5.05</td>
+<td class="decimal">5.02</td>
+<td class="decimal">4.86</td>
+<td class="decimal">31.800</td>
+<td>7</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.21</td>
+<td class="decimal">4.51</td>
+<td class="decimal">4.99</td>
+<td class="decimal">4.83</td>
+<td class="decimal">4.68</td>
+<td class="decimal">5.48</td>
+<td class="decimal">5.70</td>
+<td class="decimal">5.81</td>
+<td class="decimal">30.938</td>
+<td>9</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.09</td>
+<td class="decimal">4.57</td>
+<td class="decimal">5.16</td>
+<td class="decimal">4.98</td>
+<td class="decimal">4.70</td>
+<td class="decimal">5.27</td>
+<td class="decimal">5.81</td>
+<td class="decimal">5.35</td>
+<td class="decimal">31.000</td>
+<td>8</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.60</td>
+<td class="decimal">6.10</td>
+<td class="decimal">8.71</td>
+<td class="decimal">10.39</td>
+<td class="decimal">10.02</td>
+<td class="decimal">10.43</td>
+<td class="decimal">11.06</td>
+<td class="decimal">10.85</td>
+<td class="decimal">18.000</td>
+<td>8</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.35</td>
+<td class="decimal">5.38</td>
+<td class="decimal">6.78</td>
+<td class="decimal">7.28</td>
+<td class="decimal">6.94</td>
+<td class="decimal">6.83</td>
+<td class="decimal">6.80</td>
+<td class="decimal">7.03</td>
+<td class="decimal">25.050</td>
+<td>5</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.60</td>
+<td class="decimal">5.89</td>
+<td class="decimal">7.79</td>
+<td class="decimal">9.64</td>
+<td class="decimal">9.20</td>
+<td class="decimal">9.49</td>
+<td class="decimal">9.61</td>
+<td class="decimal">9.62</td>
+<td class="decimal">21.756</td>
+<td>5</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">4.03</td>
+<td class="decimal">7.13</td>
+<td class="decimal">10.06</td>
+<td class="decimal">12.30</td>
+<td class="decimal">11.74</td>
+<td class="decimal">12.21</td>
+<td class="decimal">12.52</td>
+<td class="decimal">10.46</td>
+<td class="decimal">8.203</td>
+<td>8</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.33</td>
+<td class="decimal">5.50</td>
+<td class="decimal">7.13</td>
+<td class="decimal">8.14</td>
+<td class="decimal">8.70</td>
+<td class="decimal">9.15</td>
+<td class="decimal">9.65</td>
+<td class="decimal">9.86</td>
+<td class="decimal">4.960</td>
+<td>9</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.44</td>
+<td class="decimal">5.42</td>
+<td class="decimal">6.99</td>
+<td class="decimal">7.95</td>
+<td class="decimal">8.42</td>
+<td class="decimal">8.81</td>
+<td class="decimal">9.06</td>
+<td class="decimal">9.26</td>
+<td class="decimal">2.103</td>
+<td>9</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.43</td>
+<td class="decimal">5.46</td>
+<td class="decimal">7.17</td>
+<td class="decimal">6.99</td>
+<td class="decimal">6.47</td>
+<td class="decimal">6.90</td>
+<td class="decimal">7.12</td>
+<td class="decimal">7.09</td>
+<td class="decimal">24.551</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.63</td>
+<td class="decimal">6.56</td>
+<td class="decimal">9.24</td>
+<td class="decimal">10.87</td>
+<td class="decimal">11.70</td>
+<td class="decimal">12.60</td>
+<td class="decimal">13.62</td>
+<td class="decimal">14.29</td>
+<td class="decimal">16.238</td>
+<td>9</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.83</td>
+<td class="decimal">7.09</td>
+<td class="decimal">10.40</td>
+<td class="decimal">13.24</td>
+<td class="decimal">13.52</td>
+<td class="decimal">15.05</td>
+<td class="decimal">16.48</td>
+<td class="decimal">17.93</td>
+<td class="decimal">6.759</td>
+<td>9</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.98</td>
+<td class="decimal">7.26</td>
+<td class="decimal">10.77</td>
+<td class="decimal">13.44</td>
+<td class="decimal">14.56</td>
+<td class="decimal">16.13</td>
+<td class="decimal">17.78</td>
+<td class="decimal">19.63</td>
+<td class="decimal">2.140</td>
+<td>9</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.02</td>
+<td class="decimal">4.78</td>
+<td class="decimal">5.94</td>
+<td class="decimal">6.63</td>
+<td class="decimal">6.91</td>
+<td class="decimal">7.09</td>
+<td class="decimal">7.29</td>
+<td class="decimal">7.42</td>
+<td class="decimal">3.036</td>
+<td>9</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.87</td>
+<td class="decimal">7.01</td>
+<td class="decimal">10.29</td>
+<td class="decimal">12.22</td>
+<td class="decimal">12.93</td>
+<td class="decimal">14.80</td>
+<td class="decimal">17.04</td>
+<td class="decimal">17.45</td>
+<td class="decimal">6.667</td>
+<td>9</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.34</td>
+<td class="decimal">2.50</td>
+<td class="decimal">2.55</td>
+<td class="decimal">2.77</td>
+<td class="decimal">3.13</td>
+<td class="decimal">3.19</td>
+<td class="decimal">3.47</td>
+<td class="decimal">4.06</td>
+<td class="decimal">21.074</td>
+<td>9</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.37</td>
+<td class="decimal">2.98</td>
+<td class="decimal">3.36</td>
+<td class="decimal">3.19</td>
+<td class="decimal">3.31</td>
+<td class="decimal">3.40</td>
+<td class="decimal">3.47</td>
+<td class="decimal">3.52</td>
+<td class="decimal">6.574</td>
+<td>9</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.65</td>
+<td class="decimal">3.47</td>
+<td class="decimal">3.95</td>
+<td class="decimal">4.24</td>
+<td class="decimal">3.93</td>
+<td class="decimal">4.12</td>
+<td class="decimal">4.26</td>
+<td class="decimal">4.28</td>
+<td class="decimal">6.000</td>
+<td>9</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.33</td>
+<td class="decimal">3.55</td>
+<td class="decimal">4.29</td>
+<td class="decimal">4.72</td>
+<td class="decimal">4.49</td>
+<td class="decimal">4.37</td>
+<td class="decimal">4.59</td>
+<td class="decimal">4.52</td>
+<td class="decimal">1.988</td>
+<td>5</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="ubuntu-linux-11-10-intel-xeon-e5649-open64-compiler">
+<h2><a class="toc-backref" href="#id4">Ubuntu Linux 11.10 / Intel Xeon E5649 / Open64 Compiler</a></h2>
+<!-- Last update: Wed Jan 18 22:04:57 CST 2012 -->
+<p>The following results were obtained from an Intel Xeon E5649 CPU at
+2.53GHz. This CPU has 12 cores and 24 threads. The free open source
+<a class="reference external" href="http://www.open64.net/home.html">Open64</a> 5.0 compiler was used to build the software. The <a class="reference external" href="http://www.open64.net/home.html">Open64</a>
+compiler produces very high performance code which exceeds GCC
+performance in most cases, and often quite dramatically so:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On 12 core Intel Xeon E5649 CPU:</caption>
+<colgroup>
+<col width="62%" />
+<col width="4%" />
+<col width="4%" />
+<col width="4%" />
+<col width="4%" />
+<col width="4%" />
+<col width="4%" />
+<col width="4%" />
+<col width="7%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">4</th>
+<th class="head">8</th>
+<th class="head">12</th>
+<th class="head">16</th>
+<th class="head">20</th>
+<th class="head">24</th>
+<th class="head">iter/s</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.31</td>
+<td class="decimal">1.41</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.44</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.43</td>
+<td class="decimal">82.635</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.74</td>
+<td class="decimal">5.59</td>
+<td class="decimal">5.35</td>
+<td class="decimal">5.78</td>
+<td class="decimal">5.95</td>
+<td class="decimal">7.56</td>
+<td class="decimal">4.175</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.03</td>
+<td class="decimal">2.50</td>
+<td class="decimal">2.58</td>
+<td class="decimal">2.83</td>
+<td class="decimal">2.86</td>
+<td class="decimal">2.89</td>
+<td class="decimal">39.641</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.15</td>
+<td class="decimal">4.35</td>
+<td class="decimal">5.05</td>
+<td class="decimal">4.94</td>
+<td class="decimal">5.22</td>
+<td class="decimal">5.30</td>
+<td class="decimal">5.631</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.35</td>
+<td class="decimal">5.17</td>
+<td class="decimal">6.14</td>
+<td class="decimal">5.79</td>
+<td class="decimal">6.32</td>
+<td class="decimal">6.63</td>
+<td class="decimal">4.873</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.54</td>
+<td class="decimal">5.90</td>
+<td class="decimal">7.48</td>
+<td class="decimal">6.90</td>
+<td class="decimal">7.84</td>
+<td class="decimal">8.56</td>
+<td class="decimal">3.937</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.97</td>
+<td class="decimal">4.26</td>
+<td class="decimal">5.04</td>
+<td class="decimal">4.72</td>
+<td class="decimal">5.15</td>
+<td class="decimal">5.51</td>
+<td class="decimal">2.303</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.25</td>
+<td class="decimal">2.72</td>
+<td class="decimal">2.60</td>
+<td class="decimal">2.85</td>
+<td class="decimal">2.81</td>
+<td class="decimal">2.76</td>
+<td class="decimal">40.319</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.07</td>
+<td class="decimal">4.67</td>
+<td class="decimal">5.69</td>
+<td class="decimal">5.69</td>
+<td class="decimal">6.31</td>
+<td class="decimal">6.90</td>
+<td class="decimal">33.600</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.71</td>
+<td class="decimal">6.71</td>
+<td class="decimal">9.20</td>
+<td class="decimal">7.66</td>
+<td class="decimal">9.07</td>
+<td class="decimal">10.41</td>
+<td class="decimal">14.343</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.59</td>
+<td class="decimal">6.13</td>
+<td class="decimal">8.09</td>
+<td class="decimal">6.65</td>
+<td class="decimal">7.80</td>
+<td class="decimal">8.82</td>
+<td class="decimal">19.960</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.08</td>
+<td class="decimal">4.66</td>
+<td class="decimal">5.72</td>
+<td class="decimal">5.69</td>
+<td class="decimal">6.22</td>
+<td class="decimal">6.85</td>
+<td class="decimal">33.267</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.07</td>
+<td class="decimal">4.56</td>
+<td class="decimal">5.72</td>
+<td class="decimal">5.70</td>
+<td class="decimal">6.21</td>
+<td class="decimal">6.92</td>
+<td class="decimal">33.665</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.08</td>
+<td class="decimal">4.65</td>
+<td class="decimal">5.72</td>
+<td class="decimal">5.72</td>
+<td class="decimal">6.27</td>
+<td class="decimal">6.95</td>
+<td class="decimal">33.800</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.03</td>
+<td class="decimal">4.68</td>
+<td class="decimal">5.60</td>
+<td class="decimal">5.47</td>
+<td class="decimal">6.29</td>
+<td class="decimal">6.95</td>
+<td class="decimal">33.800</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.70</td>
+<td class="decimal">7.15</td>
+<td class="decimal">10.51</td>
+<td class="decimal">9.69</td>
+<td class="decimal">11.90</td>
+<td class="decimal">13.65</td>
+<td class="decimal">4.150</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.69</td>
+<td class="decimal">7.13</td>
+<td class="decimal">10.42</td>
+<td class="decimal">9.41</td>
+<td class="decimal">11.49</td>
+<td class="decimal">13.38</td>
+<td class="decimal">4.348</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.21</td>
+<td class="decimal">5.48</td>
+<td class="decimal">7.22</td>
+<td class="decimal">6.10</td>
+<td class="decimal">6.83</td>
+<td class="decimal">7.76</td>
+<td class="decimal">13.861</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.52</td>
+<td class="decimal">6.00</td>
+<td class="decimal">7.68</td>
+<td class="decimal">6.48</td>
+<td class="decimal">7.64</td>
+<td class="decimal">8.46</td>
+<td class="decimal">23.000</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.67</td>
+<td class="decimal">3.33</td>
+<td class="decimal">4.09</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.27</td>
+<td class="decimal">4.65</td>
+<td class="decimal">1.359</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.46</td>
+<td class="decimal">5.74</td>
+<td class="decimal">7.97</td>
+<td class="decimal">7.33</td>
+<td class="decimal">8.46</td>
+<td class="decimal">9.36</td>
+<td class="decimal">13.000</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.26</td>
+<td class="decimal">4.87</td>
+<td class="decimal">6.02</td>
+<td class="decimal">4.75</td>
+<td class="decimal">5.46</td>
+<td class="decimal">5.90</td>
+<td class="decimal">4.615</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.55</td>
+<td class="decimal">7.00</td>
+<td class="decimal">10.30</td>
+<td class="decimal">7.83</td>
+<td class="decimal">9.73</td>
+<td class="decimal">11.39</td>
+<td class="decimal">1.731</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.58</td>
+<td class="decimal">6.31</td>
+<td class="decimal">8.60</td>
+<td class="decimal">6.20</td>
+<td class="decimal">7.20</td>
+<td class="decimal">8.23</td>
+<td class="decimal">7.570</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.61</td>
+<td class="decimal">6.79</td>
+<td class="decimal">9.73</td>
+<td class="decimal">5.94</td>
+<td class="decimal">7.48</td>
+<td class="decimal">8.73</td>
+<td class="decimal">3.220</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.57</td>
+<td class="decimal">6.81</td>
+<td class="decimal">9.79</td>
+<td class="decimal">5.55</td>
+<td class="decimal">6.89</td>
+<td class="decimal">8.22</td>
+<td class="decimal">1.077</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.70</td>
+<td class="decimal">6.81</td>
+<td class="decimal">9.44</td>
+<td class="decimal">8.58</td>
+<td class="decimal">10.32</td>
+<td class="decimal">11.62</td>
+<td class="decimal">13.412</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.73</td>
+<td class="decimal">6.80</td>
+<td class="decimal">9.31</td>
+<td class="decimal">8.42</td>
+<td class="decimal">10.20</td>
+<td class="decimal">11.52</td>
+<td class="decimal">13.439</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.76</td>
+<td class="decimal">6.69</td>
+<td class="decimal">9.42</td>
+<td class="decimal">8.50</td>
+<td class="decimal">10.19</td>
+<td class="decimal">11.66</td>
+<td class="decimal">12.103</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.80</td>
+<td class="decimal">7.28</td>
+<td class="decimal">6.16</td>
+<td class="decimal">9.46</td>
+<td class="decimal">11.91</td>
+<td class="decimal">12.17</td>
+<td class="decimal">5.088</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.79</td>
+<td class="decimal">7.29</td>
+<td class="decimal">5.21</td>
+<td class="decimal">8.93</td>
+<td class="decimal">11.33</td>
+<td class="decimal">12.82</td>
+<td class="decimal">7.677</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.56</td>
+<td class="decimal">6.24</td>
+<td class="decimal">8.34</td>
+<td class="decimal">7.31</td>
+<td class="decimal">8.72</td>
+<td class="decimal">9.84</td>
+<td class="decimal">4.094</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.99</td>
+<td class="decimal">4.41</td>
+<td class="decimal">6.32</td>
+<td class="decimal">7.54</td>
+<td class="decimal">6.38</td>
+<td class="decimal">5.53</td>
+<td class="decimal">0.641</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.23</td>
+<td class="decimal">4.20</td>
+<td class="decimal">7.70</td>
+<td class="decimal">8.93</td>
+<td class="decimal">8.00</td>
+<td class="decimal">7.10</td>
+<td class="decimal">0.268</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.30</td>
+<td class="decimal">4.97</td>
+<td class="decimal">6.36</td>
+<td class="decimal">5.95</td>
+<td class="decimal">6.46</td>
+<td class="decimal">7.12</td>
+<td class="decimal">24.400</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.79</td>
+<td class="decimal">6.86</td>
+<td class="decimal">9.62</td>
+<td class="decimal">8.55</td>
+<td class="decimal">10.16</td>
+<td class="decimal">11.63</td>
+<td class="decimal">13.147</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.29</td>
+<td class="decimal">5.24</td>
+<td class="decimal">6.40</td>
+<td class="decimal">6.73</td>
+<td class="decimal">7.23</td>
+<td class="decimal">7.74</td>
+<td class="decimal">13.690</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.51</td>
+<td class="decimal">6.91</td>
+<td class="decimal">10.01</td>
+<td class="decimal">9.49</td>
+<td class="decimal">11.56</td>
+<td class="decimal">13.34</td>
+<td class="decimal">2.308</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.56</td>
+<td class="decimal">6.92</td>
+<td class="decimal">10.00</td>
+<td class="decimal">11.08</td>
+<td class="decimal">13.47</td>
+<td class="decimal">15.35</td>
+<td class="decimal">3.393</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.24</td>
+<td class="decimal">5.05</td>
+<td class="decimal">6.22</td>
+<td class="decimal">5.73</td>
+<td class="decimal">6.25</td>
+<td class="decimal">6.75</td>
+<td class="decimal">12.525</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.65</td>
+<td class="decimal">6.90</td>
+<td class="decimal">9.80</td>
+<td class="decimal">10.03</td>
+<td class="decimal">11.93</td>
+<td class="decimal">13.53</td>
+<td class="decimal">4.762</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.67</td>
+<td class="decimal">6.91</td>
+<td class="decimal">9.78</td>
+<td class="decimal">10.24</td>
+<td class="decimal">12.07</td>
+<td class="decimal">13.74</td>
+<td class="decimal">4.960</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.06</td>
+<td class="decimal">3.40</td>
+<td class="decimal">6.48</td>
+<td class="decimal">7.08</td>
+<td class="decimal">6.79</td>
+<td class="decimal">8.25</td>
+<td class="decimal">0.701</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.23</td>
+<td class="decimal">5.30</td>
+<td class="decimal">7.80</td>
+<td class="decimal">8.73</td>
+<td class="decimal">8.63</td>
+<td class="decimal">10.03</td>
+<td class="decimal">0.301</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.60</td>
+<td class="decimal">3.45</td>
+<td class="decimal">3.93</td>
+<td class="decimal">4.43</td>
+<td class="decimal">4.59</td>
+<td class="decimal">4.69</td>
+<td class="decimal">50.000</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.21</td>
+<td class="decimal">4.71</td>
+<td class="decimal">5.73</td>
+<td class="decimal">7.13</td>
+<td class="decimal">7.75</td>
+<td class="decimal">7.92</td>
+<td class="decimal">41.118</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">2.12</td>
+<td class="decimal">2.07</td>
+<td class="decimal">2.25</td>
+<td class="decimal">2.21</td>
+<td class="decimal">2.17</td>
+<td class="decimal">44.821</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.53</td>
+<td class="decimal">1.66</td>
+<td class="decimal">1.59</td>
+<td class="decimal">1.31</td>
+<td class="decimal">44.910</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.34</td>
+<td class="decimal">2.95</td>
+<td class="decimal">2.98</td>
+<td class="decimal">3.17</td>
+<td class="decimal">3.08</td>
+<td class="decimal">2.54</td>
+<td class="decimal">42.400</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.16</td>
+<td class="decimal">4.85</td>
+<td class="decimal">5.98</td>
+<td class="decimal">7.39</td>
+<td class="decimal">8.25</td>
+<td class="decimal">8.46</td>
+<td class="decimal">40.200</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.11</td>
+<td class="decimal">2.13</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.21</td>
+<td class="decimal">2.17</td>
+<td class="decimal">30.279</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.49</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.42</td>
+<td class="decimal">1.40</td>
+<td class="decimal">1.38</td>
+<td class="decimal">1.33</td>
+<td class="decimal">43.114</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.34</td>
+<td class="decimal">2.55</td>
+<td class="decimal">2.18</td>
+<td class="decimal">2.01</td>
+<td class="decimal">44.800</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.24</td>
+<td class="decimal">4.94</td>
+<td class="decimal">6.28</td>
+<td class="decimal">7.72</td>
+<td class="decimal">8.84</td>
+<td class="decimal">8.89</td>
+<td class="decimal">39.400</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.03</td>
+<td class="decimal">2.02</td>
+<td class="decimal">2.55</td>
+<td class="decimal">2.52</td>
+<td class="decimal">2.20</td>
+<td class="decimal">44.800</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.03</td>
+<td class="decimal">1.93</td>
+<td class="decimal">2.25</td>
+<td class="decimal">2.51</td>
+<td class="decimal">2.46</td>
+<td class="decimal">44.311</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.98</td>
+<td class="decimal">4.27</td>
+<td class="decimal">5.29</td>
+<td class="decimal">6.08</td>
+<td class="decimal">6.75</td>
+<td class="decimal">6.64</td>
+<td class="decimal">40.519</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.43</td>
+<td class="decimal">1.51</td>
+<td class="decimal">1.43</td>
+<td class="decimal">1.86</td>
+<td class="decimal">1.85</td>
+<td class="decimal">1.52</td>
+<td class="decimal">45.020</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.10</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.43</td>
+<td class="decimal">2.61</td>
+<td class="decimal">2.54</td>
+<td class="decimal">44.511</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.13</td>
+<td class="decimal">2.60</td>
+<td class="decimal">2.68</td>
+<td class="decimal">3.28</td>
+<td class="decimal">3.36</td>
+<td class="decimal">3.39</td>
+<td class="decimal">52.695</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.07</td>
+<td class="decimal">2.50</td>
+<td class="decimal">2.74</td>
+<td class="decimal">3.26</td>
+<td class="decimal">3.30</td>
+<td class="decimal">3.31</td>
+<td class="decimal">51.497</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">1.94</td>
+<td class="decimal">1.83</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.32</td>
+<td class="decimal">2.34</td>
+<td class="decimal">43.200</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.57</td>
+<td class="decimal">7.06</td>
+<td class="decimal">10.48</td>
+<td class="decimal">9.85</td>
+<td class="decimal">12.11</td>
+<td class="decimal">14.18</td>
+<td class="decimal">2.495</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.63</td>
+<td class="decimal">6.26</td>
+<td class="decimal">8.52</td>
+<td class="decimal">7.59</td>
+<td class="decimal">8.98</td>
+<td class="decimal">9.91</td>
+<td class="decimal">19.323</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.73</td>
+<td class="decimal">7.24</td>
+<td class="decimal">10.53</td>
+<td class="decimal">10.67</td>
+<td class="decimal">13.09</td>
+<td class="decimal">15.17</td>
+<td class="decimal">5.400</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.63</td>
+<td class="decimal">7.15</td>
+<td class="decimal">10.59</td>
+<td class="decimal">11.83</td>
+<td class="decimal">14.61</td>
+<td class="decimal">16.87</td>
+<td class="decimal">3.762</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.75</td>
+<td class="decimal">7.27</td>
+<td class="decimal">10.70</td>
+<td class="decimal">11.10</td>
+<td class="decimal">13.66</td>
+<td class="decimal">15.89</td>
+<td class="decimal">5.894</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.64</td>
+<td class="decimal">6.39</td>
+<td class="decimal">8.75</td>
+<td class="decimal">9.50</td>
+<td class="decimal">10.98</td>
+<td class="decimal">12.11</td>
+<td class="decimal">22.465</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.19</td>
+<td class="decimal">4.65</td>
+<td class="decimal">5.63</td>
+<td class="decimal">6.10</td>
+<td class="decimal">6.71</td>
+<td class="decimal">7.06</td>
+<td class="decimal">36.128</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.19</td>
+<td class="decimal">4.65</td>
+<td class="decimal">5.58</td>
+<td class="decimal">6.08</td>
+<td class="decimal">6.57</td>
+<td class="decimal">6.93</td>
+<td class="decimal">35.458</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.19</td>
+<td class="decimal">4.76</td>
+<td class="decimal">5.62</td>
+<td class="decimal">6.21</td>
+<td class="decimal">6.84</td>
+<td class="decimal">7.20</td>
+<td class="decimal">36.853</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.19</td>
+<td class="decimal">4.65</td>
+<td class="decimal">5.54</td>
+<td class="decimal">5.93</td>
+<td class="decimal">6.03</td>
+<td class="decimal">6.06</td>
+<td class="decimal">31.076</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.68</td>
+<td class="decimal">6.79</td>
+<td class="decimal">9.19</td>
+<td class="decimal">8.53</td>
+<td class="decimal">10.29</td>
+<td class="decimal">11.53</td>
+<td class="decimal">8.893</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.83</td>
+<td class="decimal">3.96</td>
+<td class="decimal">4.71</td>
+<td class="decimal">5.24</td>
+<td class="decimal">5.18</td>
+<td class="decimal">5.33</td>
+<td class="decimal">38.200</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.32</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.13</td>
+<td class="decimal">1.22</td>
+<td class="decimal">1.23</td>
+<td class="decimal">1.19</td>
+<td class="decimal">76.248</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.25</td>
+<td class="decimal">4.93</td>
+<td class="decimal">6.43</td>
+<td class="decimal">5.86</td>
+<td class="decimal">6.65</td>
+<td class="decimal">7.09</td>
+<td class="decimal">30.600</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.37</td>
+<td class="decimal">5.41</td>
+<td class="decimal">7.00</td>
+<td class="decimal">6.53</td>
+<td class="decimal">7.53</td>
+<td class="decimal">8.16</td>
+<td class="decimal">27.745</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.43</td>
+<td class="decimal">5.43</td>
+<td class="decimal">6.98</td>
+<td class="decimal">6.46</td>
+<td class="decimal">7.35</td>
+<td class="decimal">8.03</td>
+<td class="decimal">27.745</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.68</td>
+<td class="decimal">6.66</td>
+<td class="decimal">9.16</td>
+<td class="decimal">7.26</td>
+<td class="decimal">7.96</td>
+<td class="decimal">8.36</td>
+<td class="decimal">8.023</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.31</td>
+<td class="decimal">5.37</td>
+<td class="decimal">6.72</td>
+<td class="decimal">5.78</td>
+<td class="decimal">6.72</td>
+<td class="decimal">6.58</td>
+<td class="decimal">17.460</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.65</td>
+<td class="decimal">6.34</td>
+<td class="decimal">8.81</td>
+<td class="decimal">6.86</td>
+<td class="decimal">8.14</td>
+<td class="decimal">9.21</td>
+<td class="decimal">12.375</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.46</td>
+<td class="decimal">5.58</td>
+<td class="decimal">7.34</td>
+<td class="decimal">5.40</td>
+<td class="decimal">5.41</td>
+<td class="decimal">5.28</td>
+<td class="decimal">2.890</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.26</td>
+<td class="decimal">5.36</td>
+<td class="decimal">7.05</td>
+<td class="decimal">7.34</td>
+<td class="decimal">7.95</td>
+<td class="decimal">8.82</td>
+<td class="decimal">2.724</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.94</td>
+<td class="decimal">4.55</td>
+<td class="decimal">5.50</td>
+<td class="decimal">5.17</td>
+<td class="decimal">5.21</td>
+<td class="decimal">5.28</td>
+<td class="decimal">0.786</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.47</td>
+<td class="decimal">2.65</td>
+<td class="decimal">2.59</td>
+<td class="decimal">2.71</td>
+<td class="decimal">2.76</td>
+<td class="decimal">0.047</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.30</td>
+<td class="decimal">5.00</td>
+<td class="decimal">6.51</td>
+<td class="decimal">6.62</td>
+<td class="decimal">7.06</td>
+<td class="decimal">8.07</td>
+<td class="decimal">17.659</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.60</td>
+<td class="decimal">6.37</td>
+<td class="decimal">8.65</td>
+<td class="decimal">6.11</td>
+<td class="decimal">7.22</td>
+<td class="decimal">8.29</td>
+<td class="decimal">7.602</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.71</td>
+<td class="decimal">6.73</td>
+<td class="decimal">9.75</td>
+<td class="decimal">5.99</td>
+<td class="decimal">7.39</td>
+<td class="decimal">8.82</td>
+<td class="decimal">3.208</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.61</td>
+<td class="decimal">6.84</td>
+<td class="decimal">9.88</td>
+<td class="decimal">5.61</td>
+<td class="decimal">6.95</td>
+<td class="decimal">8.31</td>
+<td class="decimal">1.077</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.82</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.99</td>
+<td class="decimal">4.34</td>
+<td class="decimal">4.06</td>
+<td class="decimal">4.16</td>
+<td class="decimal">1.213</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.12</td>
+<td class="decimal">2.46</td>
+<td class="decimal">2.40</td>
+<td class="decimal">2.65</td>
+<td class="decimal">2.61</td>
+<td class="decimal">2.56</td>
+<td class="decimal">45.200</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.85</td>
+<td class="decimal">7.22</td>
+<td class="decimal">5.07</td>
+<td class="decimal">9.34</td>
+<td class="decimal">11.86</td>
+<td class="decimal">13.54</td>
+<td class="decimal">8.627</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.50</td>
+<td class="decimal">3.19</td>
+<td class="decimal">3.57</td>
+<td class="decimal">3.84</td>
+<td class="decimal">3.77</td>
+<td class="decimal">3.84</td>
+<td class="decimal">43.000</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.66</td>
+<td class="decimal">3.17</td>
+<td class="decimal">3.41</td>
+<td class="decimal">3.37</td>
+<td class="decimal">3.53</td>
+<td class="decimal">52.600</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.56</td>
+<td class="decimal">5.92</td>
+<td class="decimal">7.83</td>
+<td class="decimal">7.37</td>
+<td class="decimal">8.71</td>
+<td class="decimal">9.69</td>
+<td class="decimal">23.260</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.27</td>
+<td class="decimal">4.71</td>
+<td class="decimal">5.64</td>
+<td class="decimal">5.48</td>
+<td class="decimal">5.81</td>
+<td class="decimal">6.14</td>
+<td class="decimal">5.190</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.42</td>
+<td class="decimal">5.33</td>
+<td class="decimal">6.52</td>
+<td class="decimal">6.19</td>
+<td class="decimal">6.94</td>
+<td class="decimal">7.36</td>
+<td class="decimal">4.600</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.79</td>
+<td class="decimal">6.78</td>
+<td class="decimal">8.35</td>
+<td class="decimal">7.67</td>
+<td class="decimal">8.87</td>
+<td class="decimal">10.14</td>
+<td class="decimal">7.859</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="ubuntu-linux-11-10-intel-xeon-e5649-gcc-compiler">
+<h2><a class="toc-backref" href="#id5">Ubuntu Linux 11.10 / Intel Xeon E5649 / GCC Compiler</a></h2>
+<!-- Last update: Fri Feb 15 08:54:04 CST 2013 -->
+<p>The following results were obtained from an Intel Xeon E5649 CPU at
+2.53GHz. This CPU has 12 cores and 24 threads. Ubtuntu's GCC 4.6.1
+compiler was used to build the software:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On 12 core Intel Xeon E5649 CPU:</caption>
+<colgroup>
+<col width="49%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="9%" />
+<col width="4%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">4</th>
+<th class="head">8</th>
+<th class="head">12</th>
+<th class="head">16</th>
+<th class="head">20</th>
+<th class="head">24</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.73</td>
+<td class="decimal">3.59</td>
+<td class="decimal">4.29</td>
+<td class="decimal">5.00</td>
+<td class="decimal">5.33</td>
+<td class="decimal">5.65</td>
+<td class="decimal">3.220</td>
+<td>7</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.54</td>
+<td class="decimal">2.98</td>
+<td class="decimal">3.23</td>
+<td class="decimal">3.47</td>
+<td class="decimal">3.57</td>
+<td class="decimal">3.63</td>
+<td class="decimal">4.200</td>
+<td>7</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.72</td>
+<td class="decimal">3.30</td>
+<td class="decimal">3.89</td>
+<td class="decimal">4.25</td>
+<td class="decimal">4.56</td>
+<td class="decimal">4.57</td>
+<td class="decimal">3.557</td>
+<td>7</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.94</td>
+<td class="decimal">3.94</td>
+<td class="decimal">4.47</td>
+<td class="decimal">5.10</td>
+<td class="decimal">5.74</td>
+<td class="decimal">5.72</td>
+<td class="decimal">2.745</td>
+<td>6</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.69</td>
+<td class="decimal">3.42</td>
+<td class="decimal">4.10</td>
+<td class="decimal">4.46</td>
+<td class="decimal">4.75</td>
+<td class="decimal">4.86</td>
+<td class="decimal">1.761</td>
+<td>7</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.77</td>
+<td class="decimal">3.34</td>
+<td class="decimal">3.68</td>
+<td class="decimal">3.97</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.15</td>
+<td class="decimal">17.000</td>
+<td>7</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.05</td>
+<td class="decimal">4.09</td>
+<td class="decimal">5.44</td>
+<td class="decimal">6.37</td>
+<td class="decimal">6.82</td>
+<td class="decimal">7.46</td>
+<td class="decimal">8.661</td>
+<td>7</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.08</td>
+<td class="decimal">3.49</td>
+<td class="decimal">4.52</td>
+<td class="decimal">5.32</td>
+<td class="decimal">6.09</td>
+<td class="decimal">5.97</td>
+<td class="decimal">11.776</td>
+<td>6</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.83</td>
+<td class="decimal">3.09</td>
+<td class="decimal">3.65</td>
+<td class="decimal">3.99</td>
+<td class="decimal">4.11</td>
+<td class="decimal">4.10</td>
+<td class="decimal">16.865</td>
+<td>6</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.82</td>
+<td class="decimal">3.09</td>
+<td class="decimal">3.73</td>
+<td class="decimal">4.05</td>
+<td class="decimal">4.11</td>
+<td class="decimal">4.18</td>
+<td class="decimal">17.131</td>
+<td>7</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.80</td>
+<td class="decimal">3.33</td>
+<td class="decimal">3.73</td>
+<td class="decimal">4.04</td>
+<td class="decimal">4.10</td>
+<td class="decimal">3.85</td>
+<td class="decimal">16.832</td>
+<td>6</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.78</td>
+<td class="decimal">3.33</td>
+<td class="decimal">3.75</td>
+<td class="decimal">4.05</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.16</td>
+<td class="decimal">17.063</td>
+<td>7</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.67</td>
+<td class="decimal">5.25</td>
+<td class="decimal">5.56</td>
+<td class="decimal">6.60</td>
+<td class="decimal">7.52</td>
+<td class="decimal">8.16</td>
+<td class="decimal">2.457</td>
+<td>7</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.67</td>
+<td class="decimal">5.24</td>
+<td class="decimal">5.58</td>
+<td class="decimal">6.59</td>
+<td class="decimal">7.89</td>
+<td class="decimal">8.16</td>
+<td class="decimal">2.481</td>
+<td>7</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.16</td>
+<td class="decimal">3.90</td>
+<td class="decimal">5.32</td>
+<td class="decimal">5.94</td>
+<td class="decimal">6.51</td>
+<td class="decimal">6.58</td>
+<td class="decimal">10.600</td>
+<td>7</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.20</td>
+<td class="decimal">3.61</td>
+<td class="decimal">3.77</td>
+<td class="decimal">3.82</td>
+<td class="decimal">3.89</td>
+<td class="decimal">3.68</td>
+<td class="decimal">1.156</td>
+<td>6</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.15</td>
+<td class="decimal">5.15</td>
+<td class="decimal">5.57</td>
+<td class="decimal">6.26</td>
+<td class="decimal">7.01</td>
+<td class="decimal">7.07</td>
+<td class="decimal">9.742</td>
+<td>7</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.02</td>
+<td class="decimal">4.24</td>
+<td class="decimal">5.24</td>
+<td class="decimal">5.88</td>
+<td class="decimal">6.52</td>
+<td class="decimal">6.64</td>
+<td class="decimal">4.215</td>
+<td>7</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.56</td>
+<td class="decimal">4.12</td>
+<td class="decimal">6.23</td>
+<td class="decimal">7.41</td>
+<td class="decimal">9.38</td>
+<td class="decimal">9.04</td>
+<td class="decimal">1.501</td>
+<td>6</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.46</td>
+<td class="decimal">4.92</td>
+<td class="decimal">6.65</td>
+<td class="decimal">7.74</td>
+<td class="decimal">8.97</td>
+<td class="decimal">9.21</td>
+<td class="decimal">6.561</td>
+<td>7</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.66</td>
+<td class="decimal">5.00</td>
+<td class="decimal">7.53</td>
+<td class="decimal">8.74</td>
+<td class="decimal">9.29</td>
+<td class="decimal">10.30</td>
+<td class="decimal">2.677</td>
+<td>7</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.70</td>
+<td class="decimal">5.86</td>
+<td class="decimal">7.39</td>
+<td class="decimal">8.54</td>
+<td class="decimal">9.60</td>
+<td class="decimal">10.49</td>
+<td class="decimal">0.839</td>
+<td>7</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.97</td>
+<td class="decimal">4.03</td>
+<td class="decimal">5.55</td>
+<td class="decimal">6.50</td>
+<td class="decimal">7.30</td>
+<td class="decimal">7.65</td>
+<td class="decimal">7.540</td>
+<td>7</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.97</td>
+<td class="decimal">4.36</td>
+<td class="decimal">5.76</td>
+<td class="decimal">6.55</td>
+<td class="decimal">7.59</td>
+<td class="decimal">7.78</td>
+<td class="decimal">7.570</td>
+<td>7</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.18</td>
+<td class="decimal">4.11</td>
+<td class="decimal">5.39</td>
+<td class="decimal">6.28</td>
+<td class="decimal">7.33</td>
+<td class="decimal">7.40</td>
+<td class="decimal">6.445</td>
+<td>7</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.30</td>
+<td class="decimal">4.32</td>
+<td class="decimal">5.43</td>
+<td class="decimal">6.74</td>
+<td class="decimal">7.55</td>
+<td class="decimal">8.07</td>
+<td class="decimal">3.187</td>
+<td>7</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.04</td>
+<td class="decimal">5.07</td>
+<td class="decimal">5.38</td>
+<td class="decimal">6.47</td>
+<td class="decimal">7.62</td>
+<td class="decimal">7.83</td>
+<td class="decimal">4.348</td>
+<td>7</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">1.03</td>
+<td class="decimal">1.03</td>
+<td class="decimal">1.03</td>
+<td class="decimal">1.02</td>
+<td class="decimal">1.02</td>
+<td class="decimal">1.211</td>
+<td>3</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.53</td>
+<td class="decimal">4.95</td>
+<td class="decimal">5.80</td>
+<td class="decimal">6.55</td>
+<td class="decimal">6.90</td>
+<td class="decimal">7.62</td>
+<td class="decimal">0.655</td>
+<td>7</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.68</td>
+<td class="decimal">5.32</td>
+<td class="decimal">5.32</td>
+<td class="decimal">7.35</td>
+<td class="decimal">9.90</td>
+<td class="decimal">9.10</td>
+<td class="decimal">0.307</td>
+<td>6</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.91</td>
+<td class="decimal">3.74</td>
+<td class="decimal">4.67</td>
+<td class="decimal">5.02</td>
+<td class="decimal">5.44</td>
+<td class="decimal">5.28</td>
+<td class="decimal">17.400</td>
+<td>6</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.18</td>
+<td class="decimal">3.89</td>
+<td class="decimal">5.41</td>
+<td class="decimal">6.40</td>
+<td class="decimal">7.50</td>
+<td class="decimal">7.64</td>
+<td class="decimal">7.255</td>
+<td>7</td>
+</tr>
+<tr><td>-motion-blur 0x3+30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.33</td>
+<td class="decimal">3.23</td>
+<td class="decimal">4.67</td>
+<td class="decimal">5.20</td>
+<td class="decimal">5.91</td>
+<td class="decimal">6.78</td>
+<td class="decimal">1.328</td>
+<td>7</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.22</td>
+<td class="decimal">2.61</td>
+<td class="decimal">3.00</td>
+<td class="decimal">3.21</td>
+<td class="decimal">3.43</td>
+<td class="decimal">3.44</td>
+<td class="decimal">5.871</td>
+<td>7</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.39</td>
+<td class="decimal">4.29</td>
+<td class="decimal">5.67</td>
+<td class="decimal">6.63</td>
+<td class="decimal">7.17</td>
+<td class="decimal">8.20</td>
+<td class="decimal">1.230</td>
+<td>7</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.44</td>
+<td class="decimal">4.29</td>
+<td class="decimal">5.41</td>
+<td class="decimal">6.34</td>
+<td class="decimal">7.22</td>
+<td class="decimal">7.78</td>
+<td class="decimal">1.689</td>
+<td>7</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.31</td>
+<td class="decimal">2.78</td>
+<td class="decimal">3.07</td>
+<td class="decimal">3.35</td>
+<td class="decimal">3.49</td>
+<td class="decimal">3.59</td>
+<td class="decimal">5.765</td>
+<td>7</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.42</td>
+<td class="decimal">4.91</td>
+<td class="decimal">5.29</td>
+<td class="decimal">5.99</td>
+<td class="decimal">6.64</td>
+<td class="decimal">7.08</td>
+<td class="decimal">2.534</td>
+<td>7</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.46</td>
+<td class="decimal">4.93</td>
+<td class="decimal">5.33</td>
+<td class="decimal">6.65</td>
+<td class="decimal">7.12</td>
+<td class="decimal">7.64</td>
+<td class="decimal">2.268</td>
+<td>7</td>
+</tr>
+<tr><td>+noise Random</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.67</td>
+<td class="decimal">3.14</td>
+<td class="decimal">3.71</td>
+<td class="decimal">4.13</td>
+<td class="decimal">4.33</td>
+<td class="decimal">4.51</td>
+<td class="decimal">5.029</td>
+<td>7</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.61</td>
+<td class="decimal">4.99</td>
+<td class="decimal">5.81</td>
+<td class="decimal">7.12</td>
+<td class="decimal">6.77</td>
+<td class="decimal">7.73</td>
+<td class="decimal">0.649</td>
+<td>7</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.77</td>
+<td class="decimal">5.70</td>
+<td class="decimal">5.43</td>
+<td class="decimal">7.60</td>
+<td class="decimal">10.10</td>
+<td class="decimal">9.40</td>
+<td class="decimal">0.303</td>
+<td>6</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.97</td>
+<td class="decimal">4.02</td>
+<td class="decimal">4.40</td>
+<td class="decimal">4.84</td>
+<td class="decimal">4.93</td>
+<td class="decimal">4.79</td>
+<td class="decimal">21.956</td>
+<td>6</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.92</td>
+<td class="decimal">3.90</td>
+<td class="decimal">4.99</td>
+<td class="decimal">5.52</td>
+<td class="decimal">5.60</td>
+<td class="decimal">5.56</td>
+<td class="decimal">19.960</td>
+<td>6</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.88</td>
+<td class="decimal">4.43</td>
+<td class="decimal">4.70</td>
+<td class="decimal">5.13</td>
+<td class="decimal">5.25</td>
+<td class="decimal">5.04</td>
+<td class="decimal">20.833</td>
+<td>6</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.95</td>
+<td class="decimal">4.01</td>
+<td class="decimal">4.58</td>
+<td class="decimal">4.69</td>
+<td class="decimal">4.87</td>
+<td class="decimal">4.71</td>
+<td class="decimal">21.400</td>
+<td>6</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.53</td>
+<td class="decimal">4.46</td>
+<td class="decimal">6.01</td>
+<td class="decimal">7.14</td>
+<td class="decimal">7.56</td>
+<td class="decimal">8.86</td>
+<td class="decimal">1.365</td>
+<td>7</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.10</td>
+<td class="decimal">3.62</td>
+<td class="decimal">4.79</td>
+<td class="decimal">5.53</td>
+<td class="decimal">6.32</td>
+<td class="decimal">6.27</td>
+<td class="decimal">11.730</td>
+<td>6</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.76</td>
+<td class="decimal">4.54</td>
+<td class="decimal">6.01</td>
+<td class="decimal">7.37</td>
+<td class="decimal">8.62</td>
+<td class="decimal">8.95</td>
+<td class="decimal">3.257</td>
+<td>7</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.62</td>
+<td class="decimal">4.26</td>
+<td class="decimal">6.14</td>
+<td class="decimal">7.10</td>
+<td class="decimal">7.67</td>
+<td class="decimal">8.98</td>
+<td class="decimal">2.011</td>
+<td>7</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.68</td>
+<td class="decimal">4.36</td>
+<td class="decimal">5.69</td>
+<td class="decimal">7.33</td>
+<td class="decimal">7.64</td>
+<td class="decimal">8.80</td>
+<td class="decimal">2.772</td>
+<td>7</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.18</td>
+<td class="decimal">3.52</td>
+<td class="decimal">4.65</td>
+<td class="decimal">5.34</td>
+<td class="decimal">5.70</td>
+<td class="decimal">6.10</td>
+<td class="decimal">12.079</td>
+<td>7</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.68</td>
+<td class="decimal">3.22</td>
+<td class="decimal">3.69</td>
+<td class="decimal">3.94</td>
+<td class="decimal">4.27</td>
+<td class="decimal">4.10</td>
+<td class="decimal">19.522</td>
+<td>6</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.69</td>
+<td class="decimal">3.21</td>
+<td class="decimal">3.80</td>
+<td class="decimal">4.08</td>
+<td class="decimal">4.10</td>
+<td class="decimal">4.14</td>
+<td class="decimal">18.887</td>
+<td>7</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.69</td>
+<td class="decimal">3.22</td>
+<td class="decimal">3.71</td>
+<td class="decimal">4.00</td>
+<td class="decimal">3.90</td>
+<td class="decimal">4.16</td>
+<td class="decimal">18.962</td>
+<td>7</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.69</td>
+<td class="decimal">3.21</td>
+<td class="decimal">3.78</td>
+<td class="decimal">4.01</td>
+<td class="decimal">4.07</td>
+<td class="decimal">4.06</td>
+<td class="decimal">18.563</td>
+<td>6</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.11</td>
+<td class="decimal">3.82</td>
+<td class="decimal">5.70</td>
+<td class="decimal">6.64</td>
+<td class="decimal">7.20</td>
+<td class="decimal">7.77</td>
+<td class="decimal">5.675</td>
+<td>7</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.60</td>
+<td class="decimal">2.85</td>
+<td class="decimal">3.31</td>
+<td class="decimal">3.52</td>
+<td class="decimal">3.54</td>
+<td class="decimal">3.53</td>
+<td class="decimal">20.000</td>
+<td>6</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.89</td>
+<td class="decimal">3.27</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.65</td>
+<td class="decimal">4.84</td>
+<td class="decimal">5.04</td>
+<td class="decimal">15.968</td>
+<td>7</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.98</td>
+<td class="decimal">3.27</td>
+<td class="decimal">4.24</td>
+<td class="decimal">4.83</td>
+<td class="decimal">4.94</td>
+<td class="decimal">5.20</td>
+<td class="decimal">14.200</td>
+<td>7</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.99</td>
+<td class="decimal">3.35</td>
+<td class="decimal">4.23</td>
+<td class="decimal">4.74</td>
+<td class="decimal">5.38</td>
+<td class="decimal">5.29</td>
+<td class="decimal">14.741</td>
+<td>6</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.15</td>
+<td class="decimal">4.28</td>
+<td class="decimal">5.25</td>
+<td class="decimal">5.48</td>
+<td class="decimal">5.37</td>
+<td class="decimal">5.18</td>
+<td class="decimal">5.039</td>
+<td>5</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.15</td>
+<td class="decimal">4.11</td>
+<td class="decimal">4.71</td>
+<td class="decimal">5.32</td>
+<td class="decimal">5.69</td>
+<td class="decimal">5.78</td>
+<td class="decimal">10.651</td>
+<td>7</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.05</td>
+<td class="decimal">3.92</td>
+<td class="decimal">5.00</td>
+<td class="decimal">5.70</td>
+<td class="decimal">6.12</td>
+<td class="decimal">6.08</td>
+<td class="decimal">7.466</td>
+<td>6</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.20</td>
+<td class="decimal">5.15</td>
+<td class="decimal">5.59</td>
+<td class="decimal">6.00</td>
+<td class="decimal">5.64</td>
+<td class="decimal">5.30</td>
+<td class="decimal">2.544</td>
+<td>5</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.27</td>
+<td class="decimal">4.81</td>
+<td class="decimal">6.14</td>
+<td class="decimal">7.29</td>
+<td class="decimal">8.04</td>
+<td class="decimal">8.48</td>
+<td class="decimal">2.662</td>
+<td>7</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.03</td>
+<td class="decimal">4.07</td>
+<td class="decimal">5.29</td>
+<td class="decimal">6.14</td>
+<td class="decimal">6.75</td>
+<td class="decimal">7.12</td>
+<td class="decimal">1.047</td>
+<td>7</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.92</td>
+<td class="decimal">3.46</td>
+<td class="decimal">4.41</td>
+<td class="decimal">5.02</td>
+<td class="decimal">5.11</td>
+<td class="decimal">5.50</td>
+<td class="decimal">10.516</td>
+<td>7</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.37</td>
+<td class="decimal">5.01</td>
+<td class="decimal">6.63</td>
+<td class="decimal">7.76</td>
+<td class="decimal">8.42</td>
+<td class="decimal">9.20</td>
+<td class="decimal">6.535</td>
+<td>7</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.68</td>
+<td class="decimal">5.50</td>
+<td class="decimal">6.84</td>
+<td class="decimal">8.47</td>
+<td class="decimal">10.48</td>
+<td class="decimal">10.58</td>
+<td class="decimal">2.750</td>
+<td>7</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.65</td>
+<td class="decimal">5.88</td>
+<td class="decimal">7.40</td>
+<td class="decimal">8.65</td>
+<td class="decimal">10.23</td>
+<td class="decimal">11.06</td>
+<td class="decimal">0.896</td>
+<td>7</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.95</td>
+<td class="decimal">3.79</td>
+<td class="decimal">4.76</td>
+<td class="decimal">5.24</td>
+<td class="decimal">5.55</td>
+<td class="decimal">5.82</td>
+<td class="decimal">1.460</td>
+<td>7</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.13</td>
+<td class="decimal">4.61</td>
+<td class="decimal">5.93</td>
+<td class="decimal">6.80</td>
+<td class="decimal">7.69</td>
+<td class="decimal">8.38</td>
+<td class="decimal">4.297</td>
+<td>7</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.99</td>
+<td class="decimal">3.49</td>
+<td class="decimal">4.46</td>
+<td class="decimal">5.04</td>
+<td class="decimal">5.59</td>
+<td class="decimal">5.51</td>
+<td class="decimal">14.343</td>
+<td>6</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.61</td>
+<td class="decimal">3.31</td>
+<td class="decimal">3.67</td>
+<td class="decimal">3.98</td>
+<td class="decimal">4.10</td>
+<td class="decimal">4.18</td>
+<td class="decimal">3.725</td>
+<td>7</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.90</td>
+<td class="decimal">3.61</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.59</td>
+<td class="decimal">4.96</td>
+<td class="decimal">4.93</td>
+<td class="decimal">3.214</td>
+<td>6</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.99</td>
+<td class="decimal">3.95</td>
+<td class="decimal">5.05</td>
+<td class="decimal">5.65</td>
+<td class="decimal">6.71</td>
+<td class="decimal">6.91</td>
+<td class="decimal">4.864</td>
+<td>7</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="ubuntu-linux-11-10-amd-opteron-6220-open64-compiler">
+<h2><a class="toc-backref" href="#id6">Ubuntu Linux 11.10 / AMD Opteron 6220 / Open64 Compiler</a></h2>
+<!-- Last update: Wed Dec 21 15:40:08 CST 2011 -->
+<p>The following results were obtained using an AMD Opteron 6220 CPU with
+AMD's branch of the Open64 Compiler. This system offered 16
+processing cores with a clock rate of 3GHz. This CPU agressively
+increases its clock rate with just a few threads running. This throws
+off the naive per-thread speedup calculation, which is based on the
+performance with just one thread. In spite of relatively low reported
+per-thread speed-up values, compare total performance with the test
+run using the GCC compiler:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On 16 core AMD Opteron 6220 CPU:</caption>
+<colgroup>
+<col width="65%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="8%" />
+<col width="4%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">4</th>
+<th class="head">8</th>
+<th class="head">12</th>
+<th class="head">16</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.14</td>
+<td class="decimal">1.10</td>
+<td class="decimal">0.97</td>
+<td class="decimal">55.100</td>
+<td>4</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.07</td>
+<td class="decimal">4.65</td>
+<td class="decimal">5.74</td>
+<td class="decimal">4.81</td>
+<td class="decimal">3.540</td>
+<td>15</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">2.02</td>
+<td class="decimal">2.07</td>
+<td class="decimal">1.88</td>
+<td class="decimal">25.050</td>
+<td>12</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.17</td>
+<td class="decimal">3.12</td>
+<td class="decimal">3.39</td>
+<td class="decimal">3.26</td>
+<td class="decimal">3.674</td>
+<td>13</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.38</td>
+<td class="decimal">3.66</td>
+<td class="decimal">4.21</td>
+<td class="decimal">4.46</td>
+<td class="decimal">3.431</td>
+<td>16</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.24</td>
+<td class="decimal">3.70</td>
+<td class="decimal">4.51</td>
+<td class="decimal">4.93</td>
+<td class="decimal">2.843</td>
+<td>16</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.20</td>
+<td class="decimal">2.88</td>
+<td class="decimal">3.43</td>
+<td class="decimal">3.60</td>
+<td class="decimal">1.488</td>
+<td>13</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">1.77</td>
+<td class="decimal">1.75</td>
+<td class="decimal">1.59</td>
+<td class="decimal">24.076</td>
+<td>5</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.40</td>
+<td class="decimal">3.48</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.18</td>
+<td class="decimal">22.732</td>
+<td>15</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.51</td>
+<td class="decimal">4.63</td>
+<td class="decimal">6.33</td>
+<td class="decimal">7.37</td>
+<td class="decimal">13.886</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.02</td>
+<td class="decimal">5.11</td>
+<td class="decimal">6.81</td>
+<td class="decimal">8.13</td>
+<td class="decimal">16.617</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.41</td>
+<td class="decimal">3.49</td>
+<td class="decimal">4.16</td>
+<td class="decimal">4.21</td>
+<td class="decimal">22.700</td>
+<td>15</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.41</td>
+<td class="decimal">3.51</td>
+<td class="decimal">4.17</td>
+<td class="decimal">4.24</td>
+<td class="decimal">22.854</td>
+<td>15</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.39</td>
+<td class="decimal">3.48</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.18</td>
+<td class="decimal">22.754</td>
+<td>15</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.40</td>
+<td class="decimal">3.47</td>
+<td class="decimal">4.14</td>
+<td class="decimal">4.19</td>
+<td class="decimal">22.732</td>
+<td>15</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.98</td>
+<td class="decimal">5.76</td>
+<td class="decimal">8.47</td>
+<td class="decimal">10.76</td>
+<td class="decimal">3.766</td>
+<td>16</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.99</td>
+<td class="decimal">5.74</td>
+<td class="decimal">8.45</td>
+<td class="decimal">10.86</td>
+<td class="decimal">3.953</td>
+<td>16</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.13</td>
+<td class="decimal">3.66</td>
+<td class="decimal">4.72</td>
+<td class="decimal">5.46</td>
+<td class="decimal">10.568</td>
+<td>16</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">2.84</td>
+<td class="decimal">3.51</td>
+<td class="decimal">3.24</td>
+<td class="decimal">19.522</td>
+<td>12</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.33</td>
+<td class="decimal">2.34</td>
+<td class="decimal">2.34</td>
+<td class="decimal">2.34</td>
+<td class="decimal">0.293</td>
+<td>12</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.35</td>
+<td class="decimal">4.20</td>
+<td class="decimal">5.61</td>
+<td class="decimal">6.32</td>
+<td class="decimal">9.633</td>
+<td>16</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">3.08</td>
+<td class="decimal">3.70</td>
+<td class="decimal">4.05</td>
+<td class="decimal">3.393</td>
+<td>16</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.56</td>
+<td class="decimal">5.06</td>
+<td class="decimal">7.51</td>
+<td class="decimal">9.89</td>
+<td class="decimal">1.602</td>
+<td>16</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.16</td>
+<td class="decimal">4.06</td>
+<td class="decimal">5.53</td>
+<td class="decimal">6.62</td>
+<td class="decimal">7.065</td>
+<td>16</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.31</td>
+<td class="decimal">4.36</td>
+<td class="decimal">6.16</td>
+<td class="decimal">8.32</td>
+<td class="decimal">3.287</td>
+<td>16</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.32</td>
+<td class="decimal">4.60</td>
+<td class="decimal">6.69</td>
+<td class="decimal">8.94</td>
+<td class="decimal">1.117</td>
+<td>16</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.84</td>
+<td class="decimal">5.11</td>
+<td class="decimal">7.02</td>
+<td class="decimal">8.23</td>
+<td class="decimal">12.202</td>
+<td>16</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.83</td>
+<td class="decimal">5.04</td>
+<td class="decimal">6.97</td>
+<td class="decimal">8.24</td>
+<td class="decimal">11.817</td>
+<td>16</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.86</td>
+<td class="decimal">5.14</td>
+<td class="decimal">6.87</td>
+<td class="decimal">8.05</td>
+<td class="decimal">10.050</td>
+<td>16</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.00</td>
+<td class="decimal">5.38</td>
+<td class="decimal">4.62</td>
+<td class="decimal">5.49</td>
+<td class="decimal">2.852</td>
+<td>13</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.90</td>
+<td class="decimal">5.49</td>
+<td class="decimal">3.97</td>
+<td class="decimal">4.70</td>
+<td class="decimal">5.556</td>
+<td>13</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.45</td>
+<td class="decimal">4.44</td>
+<td class="decimal">5.25</td>
+<td class="decimal">6.43</td>
+<td class="decimal">3.370</td>
+<td>16</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.12</td>
+<td class="decimal">5.36</td>
+<td class="decimal">7.82</td>
+<td class="decimal">9.23</td>
+<td class="decimal">0.849</td>
+<td>16</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.28</td>
+<td class="decimal">6.21</td>
+<td class="decimal">9.21</td>
+<td class="decimal">12.10</td>
+<td class="decimal">0.351</td>
+<td>16</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.04</td>
+<td class="decimal">3.42</td>
+<td class="decimal">4.34</td>
+<td class="decimal">4.74</td>
+<td class="decimal">16.200</td>
+<td>15</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.95</td>
+<td class="decimal">5.40</td>
+<td class="decimal">7.29</td>
+<td class="decimal">9.18</td>
+<td class="decimal">11.800</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.37</td>
+<td class="decimal">3.74</td>
+<td class="decimal">4.49</td>
+<td class="decimal">5.04</td>
+<td class="decimal">10.417</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.35</td>
+<td class="decimal">6.53</td>
+<td class="decimal">9.55</td>
+<td class="decimal">12.39</td>
+<td class="decimal">1.722</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.28</td>
+<td class="decimal">6.28</td>
+<td class="decimal">8.92</td>
+<td class="decimal">11.48</td>
+<td class="decimal">2.584</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.67</td>
+<td class="decimal">4.37</td>
+<td class="decimal">5.50</td>
+<td class="decimal">6.16</td>
+<td class="decimal">9.335</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.48</td>
+<td class="decimal">6.55</td>
+<td class="decimal">9.42</td>
+<td class="decimal">11.81</td>
+<td class="decimal">3.366</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.15</td>
+<td class="decimal">5.97</td>
+<td class="decimal">8.37</td>
+<td class="decimal">10.57</td>
+<td class="decimal">3.785</td>
+<td>16</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.13</td>
+<td class="decimal">5.99</td>
+<td class="decimal">7.66</td>
+<td class="decimal">9.85</td>
+<td class="decimal">0.896</td>
+<td>16</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.24</td>
+<td class="decimal">6.38</td>
+<td class="decimal">9.10</td>
+<td class="decimal">11.62</td>
+<td class="decimal">0.337</td>
+<td>16</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.05</td>
+<td class="decimal">2.83</td>
+<td class="decimal">3.14</td>
+<td class="decimal">3.18</td>
+<td class="decimal">29.341</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.08</td>
+<td class="decimal">2.75</td>
+<td class="decimal">3.03</td>
+<td class="decimal">2.76</td>
+<td class="decimal">25.375</td>
+<td>12</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.28</td>
+<td class="decimal">1.26</td>
+<td class="decimal">1.13</td>
+<td class="decimal">28.072</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.29</td>
+<td class="decimal">1.23</td>
+<td class="decimal">1.21</td>
+<td class="decimal">1.08</td>
+<td class="decimal">28.044</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.66</td>
+<td class="decimal">1.64</td>
+<td class="decimal">1.60</td>
+<td class="decimal">1.44</td>
+<td class="decimal">27.000</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.03</td>
+<td class="decimal">2.82</td>
+<td class="decimal">3.17</td>
+<td class="decimal">2.95</td>
+<td class="decimal">24.850</td>
+<td>12</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.47</td>
+<td class="decimal">1.36</td>
+<td class="decimal">1.37</td>
+<td class="decimal">1.24</td>
+<td class="decimal">22.455</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.30</td>
+<td class="decimal">1.28</td>
+<td class="decimal">1.15</td>
+<td class="decimal">27.672</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.29</td>
+<td class="decimal">1.27</td>
+<td class="decimal">1.13</td>
+<td class="decimal">28.000</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.06</td>
+<td class="decimal">2.72</td>
+<td class="decimal">3.00</td>
+<td class="decimal">2.72</td>
+<td class="decimal">25.424</td>
+<td>12</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.28</td>
+<td class="decimal">1.27</td>
+<td class="decimal">1.13</td>
+<td class="decimal">28.100</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.28</td>
+<td class="decimal">1.27</td>
+<td class="decimal">1.13</td>
+<td class="decimal">28.072</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.24</td>
+<td class="decimal">3.09</td>
+<td class="decimal">3.49</td>
+<td class="decimal">3.22</td>
+<td class="decimal">24.850</td>
+<td>12</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.22</td>
+<td class="decimal">1.16</td>
+<td class="decimal">1.14</td>
+<td class="decimal">1.02</td>
+<td class="decimal">28.372</td>
+<td>4</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.64</td>
+<td class="decimal">1.60</td>
+<td class="decimal">1.59</td>
+<td class="decimal">1.42</td>
+<td class="decimal">27.246</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.06</td>
+<td class="decimal">2.06</td>
+<td class="decimal">1.87</td>
+<td class="decimal">33.500</td>
+<td>11</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.05</td>
+<td class="decimal">2.06</td>
+<td class="decimal">1.85</td>
+<td class="decimal">32.900</td>
+<td>9</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.28</td>
+<td class="decimal">1.26</td>
+<td class="decimal">1.13</td>
+<td class="decimal">28.144</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.38</td>
+<td class="decimal">6.65</td>
+<td class="decimal">9.85</td>
+<td class="decimal">12.97</td>
+<td class="decimal">1.829</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.88</td>
+<td class="decimal">5.12</td>
+<td class="decimal">6.94</td>
+<td class="decimal">8.42</td>
+<td class="decimal">13.174</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.46</td>
+<td class="decimal">6.75</td>
+<td class="decimal">9.79</td>
+<td class="decimal">12.82</td>
+<td class="decimal">3.770</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.32</td>
+<td class="decimal">6.49</td>
+<td class="decimal">9.40</td>
+<td class="decimal">12.31</td>
+<td class="decimal">2.794</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.19</td>
+<td class="decimal">6.17</td>
+<td class="decimal">9.01</td>
+<td class="decimal">11.65</td>
+<td class="decimal">4.310</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.55</td>
+<td class="decimal">4.39</td>
+<td class="decimal">5.88</td>
+<td class="decimal">6.97</td>
+<td class="decimal">15.085</td>
+<td>16</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.43</td>
+<td class="decimal">2.97</td>
+<td class="decimal">3.05</td>
+<td class="decimal">2.84</td>
+<td class="decimal">22.832</td>
+<td>12</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.47</td>
+<td class="decimal">3.05</td>
+<td class="decimal">3.14</td>
+<td class="decimal">2.86</td>
+<td class="decimal">23.529</td>
+<td>12</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.96</td>
+<td class="decimal">3.04</td>
+<td class="decimal">2.84</td>
+<td class="decimal">22.877</td>
+<td>12</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.46</td>
+<td class="decimal">3.01</td>
+<td class="decimal">3.11</td>
+<td class="decimal">2.89</td>
+<td class="decimal">23.207</td>
+<td>12</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.41</td>
+<td class="decimal">4.70</td>
+<td class="decimal">6.53</td>
+<td class="decimal">7.88</td>
+<td class="decimal">5.373</td>
+<td>16</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.74</td>
+<td class="decimal">3.57</td>
+<td class="decimal">3.72</td>
+<td class="decimal">3.55</td>
+<td class="decimal">23.177</td>
+<td>10</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.21</td>
+<td class="decimal">1.15</td>
+<td class="decimal">1.12</td>
+<td class="decimal">0.98</td>
+<td class="decimal">54.945</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.91</td>
+<td class="decimal">4.66</td>
+<td class="decimal">5.99</td>
+<td class="decimal">6.21</td>
+<td class="decimal">21.457</td>
+<td>16</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.19</td>
+<td class="decimal">5.28</td>
+<td class="decimal">6.62</td>
+<td class="decimal">7.54</td>
+<td class="decimal">19.821</td>
+<td>16</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.12</td>
+<td class="decimal">5.10</td>
+<td class="decimal">6.46</td>
+<td class="decimal">7.54</td>
+<td class="decimal">19.880</td>
+<td>16</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.42</td>
+<td class="decimal">4.58</td>
+<td class="decimal">6.33</td>
+<td class="decimal">7.50</td>
+<td class="decimal">7.143</td>
+<td>16</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.51</td>
+<td class="decimal">4.22</td>
+<td class="decimal">5.49</td>
+<td class="decimal">6.23</td>
+<td class="decimal">13.686</td>
+<td>16</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.24</td>
+<td class="decimal">3.98</td>
+<td class="decimal">6.16</td>
+<td class="decimal">7.10</td>
+<td class="decimal">10.558</td>
+<td>16</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.58</td>
+<td class="decimal">4.82</td>
+<td class="decimal">6.56</td>
+<td class="decimal">7.39</td>
+<td class="decimal">2.778</td>
+<td>15</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.43</td>
+<td class="decimal">3.78</td>
+<td class="decimal">4.68</td>
+<td class="decimal">5.17</td>
+<td class="decimal">2.532</td>
+<td>16</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">3.01</td>
+<td class="decimal">3.55</td>
+<td class="decimal">3.79</td>
+<td class="decimal">0.856</td>
+<td>16</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.21</td>
+<td class="decimal">2.43</td>
+<td class="decimal">2.50</td>
+<td class="decimal">0.035</td>
+<td>14</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.86</td>
+<td class="decimal">4.85</td>
+<td class="decimal">6.38</td>
+<td class="decimal">6.93</td>
+<td class="decimal">10.789</td>
+<td>15</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.14</td>
+<td class="decimal">4.01</td>
+<td class="decimal">5.46</td>
+<td class="decimal">6.52</td>
+<td class="decimal">6.944</td>
+<td>16</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.33</td>
+<td class="decimal">4.37</td>
+<td class="decimal">6.23</td>
+<td class="decimal">8.34</td>
+<td class="decimal">3.284</td>
+<td>16</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.33</td>
+<td class="decimal">4.58</td>
+<td class="decimal">6.71</td>
+<td class="decimal">8.96</td>
+<td class="decimal">1.120</td>
+<td>16</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.93</td>
+<td class="decimal">3.48</td>
+<td class="decimal">3.72</td>
+<td class="decimal">1.157</td>
+<td>16</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">1.82</td>
+<td class="decimal">1.80</td>
+<td class="decimal">1.63</td>
+<td class="decimal">27.073</td>
+<td>9</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.18</td>
+<td class="decimal">5.52</td>
+<td class="decimal">5.62</td>
+<td class="decimal">7.33</td>
+<td class="decimal">5.627</td>
+<td>15</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.06</td>
+<td class="decimal">2.72</td>
+<td class="decimal">3.02</td>
+<td class="decimal">2.76</td>
+<td class="decimal">25.449</td>
+<td>12</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.27</td>
+<td class="decimal">2.45</td>
+<td class="decimal">2.31</td>
+<td class="decimal">32.635</td>
+<td>12</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.56</td>
+<td class="decimal">4.59</td>
+<td class="decimal">5.94</td>
+<td class="decimal">7.16</td>
+<td class="decimal">14.428</td>
+<td>16</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.30</td>
+<td class="decimal">3.43</td>
+<td class="decimal">3.87</td>
+<td class="decimal">4.30</td>
+<td class="decimal">3.593</td>
+<td>16</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.32</td>
+<td class="decimal">3.65</td>
+<td class="decimal">4.24</td>
+<td class="decimal">4.57</td>
+<td class="decimal">3.097</td>
+<td>16</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.01</td>
+<td class="decimal">5.18</td>
+<td class="decimal">6.51</td>
+<td class="decimal">8.31</td>
+<td class="decimal">5.765</td>
+<td>16</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="ubuntu-linux-11-10-amd-opteron-6220-gcc-compiler">
+<h2><a class="toc-backref" href="#id7">Ubuntu Linux 11.10 / AMD Opteron 6220 / GCC Compiler</a></h2>
+<!-- Last update: Wed Dec 21 15:40:08 CST 2011 -->
+<p>The following results were obtained using an AMD Opteron 6220 CPU.
+Ubtuntu's GCC 4.6.1 compiler was used to build the software.
+Ubtuntu's GCC has been found to offer less performance for this CPU
+(and for Intel Xeon) than the Open64 compiler. Compare these results
+with the Open64 results above. This system offers 16 processing cores
+with a clock rate of 3GHz:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On 16 core AMD Opteron 6220 CPU:</caption>
+<colgroup>
+<col width="65%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="8%" />
+<col width="4%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">4</th>
+<th class="head">8</th>
+<th class="head">12</th>
+<th class="head">16</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.05</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.07</td>
+<td class="decimal">29.341</td>
+<td>7</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.73</td>
+<td class="decimal">6.65</td>
+<td class="decimal">6.56</td>
+<td class="decimal">6.63</td>
+<td class="decimal">3.868</td>
+<td>15</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.37</td>
+<td class="decimal">2.97</td>
+<td class="decimal">2.82</td>
+<td class="decimal">3.18</td>
+<td class="decimal">23.752</td>
+<td>16</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.75</td>
+<td class="decimal">3.36</td>
+<td class="decimal">3.55</td>
+<td class="decimal">3.22</td>
+<td class="decimal">3.661</td>
+<td>14</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.89</td>
+<td class="decimal">3.69</td>
+<td class="decimal">4.11</td>
+<td class="decimal">4.07</td>
+<td class="decimal">3.156</td>
+<td>15</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.21</td>
+<td class="decimal">4.54</td>
+<td class="decimal">4.81</td>
+<td class="decimal">4.95</td>
+<td class="decimal">2.569</td>
+<td>15</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.30</td>
+<td class="decimal">3.07</td>
+<td class="decimal">3.32</td>
+<td class="decimal">3.47</td>
+<td class="decimal">1.252</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.03</td>
+<td class="decimal">2.39</td>
+<td class="decimal">2.21</td>
+<td class="decimal">2.36</td>
+<td class="decimal">21.627</td>
+<td>8</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.70</td>
+<td class="decimal">3.82</td>
+<td class="decimal">3.61</td>
+<td class="decimal">4.27</td>
+<td class="decimal">19.721</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.92</td>
+<td class="decimal">5.61</td>
+<td class="decimal">5.83</td>
+<td class="decimal">7.24</td>
+<td class="decimal">12.821</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.42</td>
+<td class="decimal">5.28</td>
+<td class="decimal">6.30</td>
+<td class="decimal">7.79</td>
+<td class="decimal">13.861</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.81</td>
+<td class="decimal">3.86</td>
+<td class="decimal">3.59</td>
+<td class="decimal">4.14</td>
+<td class="decimal">19.200</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.83</td>
+<td class="decimal">3.42</td>
+<td class="decimal">3.61</td>
+<td class="decimal">4.14</td>
+<td class="decimal">19.124</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.79</td>
+<td class="decimal">3.86</td>
+<td class="decimal">3.60</td>
+<td class="decimal">4.18</td>
+<td class="decimal">19.323</td>
+<td>16</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.83</td>
+<td class="decimal">3.43</td>
+<td class="decimal">3.62</td>
+<td class="decimal">4.24</td>
+<td class="decimal">19.522</td>
+<td>16</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.93</td>
+<td class="decimal">6.78</td>
+<td class="decimal">8.59</td>
+<td class="decimal">11.24</td>
+<td class="decimal">3.360</td>
+<td>16</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.89</td>
+<td class="decimal">7.11</td>
+<td class="decimal">8.65</td>
+<td class="decimal">11.17</td>
+<td class="decimal">3.429</td>
+<td>16</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.10</td>
+<td class="decimal">5.10</td>
+<td class="decimal">5.65</td>
+<td class="decimal">6.71</td>
+<td class="decimal">10.379</td>
+<td>16</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.68</td>
+<td class="decimal">3.80</td>
+<td class="decimal">3.49</td>
+<td class="decimal">4.15</td>
+<td class="decimal">14.371</td>
+<td>16</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.95</td>
+<td class="decimal">2.88</td>
+<td class="decimal">2.95</td>
+<td class="decimal">2.91</td>
+<td class="decimal">0.271</td>
+<td>4</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.37</td>
+<td class="decimal">5.61</td>
+<td class="decimal">6.39</td>
+<td class="decimal">7.68</td>
+<td class="decimal">9.182</td>
+<td>16</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.85</td>
+<td class="decimal">4.24</td>
+<td class="decimal">4.72</td>
+<td class="decimal">5.17</td>
+<td class="decimal">3.194</td>
+<td>16</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.73</td>
+<td class="decimal">7.18</td>
+<td class="decimal">8.20</td>
+<td class="decimal">9.45</td>
+<td class="decimal">1.597</td>
+<td>16</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.24</td>
+<td class="decimal">6.07</td>
+<td class="decimal">7.01</td>
+<td class="decimal">8.17</td>
+<td class="decimal">6.000</td>
+<td>16</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.80</td>
+<td class="decimal">6.83</td>
+<td class="decimal">7.92</td>
+<td class="decimal">8.97</td>
+<td class="decimal">2.358</td>
+<td>16</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.94</td>
+<td class="decimal">6.63</td>
+<td class="decimal">8.44</td>
+<td class="decimal">9.69</td>
+<td class="decimal">0.843</td>
+<td>16</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.11</td>
+<td class="decimal">5.53</td>
+<td class="decimal">5.86</td>
+<td class="decimal">7.56</td>
+<td class="decimal">8.893</td>
+<td>16</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.67</td>
+<td class="decimal">4.40</td>
+<td class="decimal">5.77</td>
+<td class="decimal">7.57</td>
+<td class="decimal">8.583</td>
+<td>16</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.60</td>
+<td class="decimal">4.67</td>
+<td class="decimal">6.19</td>
+<td class="decimal">7.80</td>
+<td class="decimal">7.400</td>
+<td>16</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">4.08</td>
+<td class="decimal">6.98</td>
+<td class="decimal">9.37</td>
+<td class="decimal">10.09</td>
+<td class="decimal">3.422</td>
+<td>16</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.49</td>
+<td class="decimal">6.20</td>
+<td class="decimal">8.38</td>
+<td class="decimal">9.22</td>
+<td class="decimal">4.582</td>
+<td>16</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.01</td>
+<td class="decimal">4.29</td>
+<td class="decimal">4.72</td>
+<td class="decimal">5.04</td>
+<td class="decimal">1.685</td>
+<td>16</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.86</td>
+<td class="decimal">6.61</td>
+<td class="decimal">8.01</td>
+<td class="decimal">9.08</td>
+<td class="decimal">0.672</td>
+<td>16</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.96</td>
+<td class="decimal">7.25</td>
+<td class="decimal">9.54</td>
+<td class="decimal">11.54</td>
+<td class="decimal">0.277</td>
+<td>16</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.01</td>
+<td class="decimal">4.46</td>
+<td class="decimal">4.58</td>
+<td class="decimal">5.17</td>
+<td class="decimal">15.200</td>
+<td>16</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.50</td>
+<td class="decimal">6.04</td>
+<td class="decimal">6.68</td>
+<td class="decimal">8.60</td>
+<td class="decimal">9.881</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.43</td>
+<td class="decimal">2.53</td>
+<td class="decimal">2.857</td>
+<td>15</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">4.55</td>
+<td class="decimal">7.58</td>
+<td class="decimal">9.16</td>
+<td class="decimal">10.87</td>
+<td class="decimal">1.152</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.74</td>
+<td class="decimal">5.98</td>
+<td class="decimal">7.58</td>
+<td class="decimal">8.95</td>
+<td class="decimal">1.378</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.10</td>
+<td class="decimal">2.48</td>
+<td class="decimal">2.64</td>
+<td class="decimal">2.79</td>
+<td class="decimal">2.846</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.48</td>
+<td class="decimal">5.32</td>
+<td class="decimal">6.32</td>
+<td class="decimal">7.27</td>
+<td class="decimal">1.775</td>
+<td>16</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.16</td>
+<td class="decimal">4.68</td>
+<td class="decimal">5.74</td>
+<td class="decimal">6.49</td>
+<td class="decimal">1.805</td>
+<td>16</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.99</td>
+<td class="decimal">6.85</td>
+<td class="decimal">8.46</td>
+<td class="decimal">9.42</td>
+<td class="decimal">0.678</td>
+<td>16</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.96</td>
+<td class="decimal">7.25</td>
+<td class="decimal">9.54</td>
+<td class="decimal">11.54</td>
+<td class="decimal">0.277</td>
+<td>16</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.47</td>
+<td class="decimal">3.10</td>
+<td class="decimal">3.08</td>
+<td class="decimal">3.60</td>
+<td class="decimal">24.303</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.66</td>
+<td class="decimal">3.17</td>
+<td class="decimal">3.27</td>
+<td class="decimal">3.80</td>
+<td class="decimal">21.912</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.01</td>
+<td class="decimal">2.31</td>
+<td class="decimal">2.12</td>
+<td class="decimal">2.38</td>
+<td class="decimal">24.600</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.27</td>
+<td class="decimal">2.05</td>
+<td class="decimal">2.23</td>
+<td class="decimal">24.303</td>
+<td>8</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.08</td>
+<td class="decimal">2.39</td>
+<td class="decimal">2.11</td>
+<td class="decimal">2.32</td>
+<td class="decimal">23.904</td>
+<td>8</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.69</td>
+<td class="decimal">3.31</td>
+<td class="decimal">3.35</td>
+<td class="decimal">3.91</td>
+<td class="decimal">21.357</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.15</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.06</td>
+<td class="decimal">20.400</td>
+<td>8</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.36</td>
+<td class="decimal">2.11</td>
+<td class="decimal">2.37</td>
+<td class="decimal">24.600</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.08</td>
+<td class="decimal">2.34</td>
+<td class="decimal">24.701</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.65</td>
+<td class="decimal">3.12</td>
+<td class="decimal">3.27</td>
+<td class="decimal">3.90</td>
+<td class="decimal">22.510</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.03</td>
+<td class="decimal">2.32</td>
+<td class="decimal">2.15</td>
+<td class="decimal">2.35</td>
+<td class="decimal">24.200</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.06</td>
+<td class="decimal">2.25</td>
+<td class="decimal">24.056</td>
+<td>8</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.71</td>
+<td class="decimal">3.35</td>
+<td class="decimal">3.58</td>
+<td class="decimal">4.10</td>
+<td class="decimal">20.758</td>
+<td>15</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.16</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.00</td>
+<td class="decimal">24.600</td>
+<td>8</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.14</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.27</td>
+<td class="decimal">2.53</td>
+<td class="decimal">24.502</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.16</td>
+<td class="decimal">2.54</td>
+<td class="decimal">2.36</td>
+<td class="decimal">2.47</td>
+<td class="decimal">24.206</td>
+<td>9</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.20</td>
+<td class="decimal">2.63</td>
+<td class="decimal">2.40</td>
+<td class="decimal">2.57</td>
+<td class="decimal">24.254</td>
+<td>8</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.37</td>
+<td class="decimal">2.13</td>
+<td class="decimal">2.35</td>
+<td class="decimal">24.400</td>
+<td>8</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.87</td>
+<td class="decimal">6.25</td>
+<td class="decimal">9.03</td>
+<td class="decimal">11.74</td>
+<td class="decimal">1.667</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.47</td>
+<td class="decimal">5.94</td>
+<td class="decimal">6.95</td>
+<td class="decimal">8.46</td>
+<td class="decimal">11.858</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.89</td>
+<td class="decimal">7.12</td>
+<td class="decimal">9.58</td>
+<td class="decimal">12.26</td>
+<td class="decimal">3.495</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">4.01</td>
+<td class="decimal">7.40</td>
+<td class="decimal">10.12</td>
+<td class="decimal">12.99</td>
+<td class="decimal">2.196</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.88</td>
+<td class="decimal">6.67</td>
+<td class="decimal">8.80</td>
+<td class="decimal">11.34</td>
+<td class="decimal">3.482</td>
+<td>16</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.49</td>
+<td class="decimal">5.22</td>
+<td class="decimal">6.51</td>
+<td class="decimal">8.17</td>
+<td class="decimal">13.069</td>
+<td>16</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.46</td>
+<td class="decimal">3.36</td>
+<td class="decimal">3.23</td>
+<td class="decimal">3.64</td>
+<td class="decimal">20.717</td>
+<td>16</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.51</td>
+<td class="decimal">3.24</td>
+<td class="decimal">3.24</td>
+<td class="decimal">3.67</td>
+<td class="decimal">20.833</td>
+<td>16</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.55</td>
+<td class="decimal">3.27</td>
+<td class="decimal">3.26</td>
+<td class="decimal">3.67</td>
+<td class="decimal">20.800</td>
+<td>16</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.53</td>
+<td class="decimal">3.40</td>
+<td class="decimal">3.28</td>
+<td class="decimal">3.70</td>
+<td class="decimal">20.875</td>
+<td>16</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.60</td>
+<td class="decimal">6.18</td>
+<td class="decimal">6.97</td>
+<td class="decimal">7.99</td>
+<td class="decimal">5.976</td>
+<td>16</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.66</td>
+<td class="decimal">3.77</td>
+<td class="decimal">3.86</td>
+<td class="decimal">4.44</td>
+<td class="decimal">20.833</td>
+<td>16</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">1.95</td>
+<td class="decimal">1.88</td>
+<td class="decimal">1.97</td>
+<td class="decimal">28.486</td>
+<td>7</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.87</td>
+<td class="decimal">3.98</td>
+<td class="decimal">4.03</td>
+<td class="decimal">5.02</td>
+<td class="decimal">20.800</td>
+<td>16</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.03</td>
+<td class="decimal">3.96</td>
+<td class="decimal">4.01</td>
+<td class="decimal">4.95</td>
+<td class="decimal">18.725</td>
+<td>16</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.02</td>
+<td class="decimal">3.59</td>
+<td class="decimal">3.94</td>
+<td class="decimal">4.96</td>
+<td class="decimal">18.812</td>
+<td>16</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.46</td>
+<td class="decimal">5.19</td>
+<td class="decimal">4.75</td>
+<td class="decimal">5.01</td>
+<td class="decimal">4.669</td>
+<td>8</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.42</td>
+<td class="decimal">4.51</td>
+<td class="decimal">5.62</td>
+<td class="decimal">6.53</td>
+<td class="decimal">10.609</td>
+<td>16</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.41</td>
+<td class="decimal">4.97</td>
+<td class="decimal">5.56</td>
+<td class="decimal">5.98</td>
+<td class="decimal">7.738</td>
+<td>14</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.50</td>
+<td class="decimal">6.01</td>
+<td class="decimal">6.48</td>
+<td class="decimal">7.37</td>
+<td class="decimal">2.820</td>
+<td>15</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.70</td>
+<td class="decimal">4.31</td>
+<td class="decimal">4.90</td>
+<td class="decimal">5.61</td>
+<td class="decimal">2.703</td>
+<td>16</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.51</td>
+<td class="decimal">3.58</td>
+<td class="decimal">3.94</td>
+<td class="decimal">4.17</td>
+<td class="decimal">0.958</td>
+<td>16</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.63</td>
+<td class="decimal">1.79</td>
+<td class="decimal">1.84</td>
+<td class="decimal">1.89</td>
+<td class="decimal">0.036</td>
+<td>14</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.38</td>
+<td class="decimal">5.44</td>
+<td class="decimal">6.78</td>
+<td class="decimal">8.08</td>
+<td class="decimal">9.722</td>
+<td>16</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.12</td>
+<td class="decimal">6.12</td>
+<td class="decimal">7.06</td>
+<td class="decimal">8.28</td>
+<td class="decimal">6.055</td>
+<td>16</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.74</td>
+<td class="decimal">6.71</td>
+<td class="decimal">7.83</td>
+<td class="decimal">8.86</td>
+<td class="decimal">2.339</td>
+<td>16</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.68</td>
+<td class="decimal">7.10</td>
+<td class="decimal">8.36</td>
+<td class="decimal">9.69</td>
+<td class="decimal">0.843</td>
+<td>16</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.32</td>
+<td class="decimal">3.29</td>
+<td class="decimal">3.64</td>
+<td class="decimal">3.93</td>
+<td class="decimal">1.308</td>
+<td>16</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.15</td>
+<td class="decimal">2.48</td>
+<td class="decimal">2.26</td>
+<td class="decimal">2.52</td>
+<td class="decimal">24.351</td>
+<td>16</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.91</td>
+<td class="decimal">5.95</td>
+<td class="decimal">8.09</td>
+<td class="decimal">9.76</td>
+<td class="decimal">4.391</td>
+<td>16</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.40</td>
+<td class="decimal">3.01</td>
+<td class="decimal">3.00</td>
+<td class="decimal">3.49</td>
+<td class="decimal">24.200</td>
+<td>16</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.27</td>
+<td class="decimal">2.68</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.55</td>
+<td class="decimal">24.551</td>
+<td>8</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.06</td>
+<td class="decimal">5.06</td>
+<td class="decimal">5.79</td>
+<td class="decimal">6.80</td>
+<td class="decimal">13.972</td>
+<td>16</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.78</td>
+<td class="decimal">3.80</td>
+<td class="decimal">4.03</td>
+<td class="decimal">4.27</td>
+<td class="decimal">3.282</td>
+<td>16</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.07</td>
+<td class="decimal">3.86</td>
+<td class="decimal">4.53</td>
+<td class="decimal">4.52</td>
+<td class="decimal">2.953</td>
+<td>15</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.47</td>
+<td class="decimal">6.10</td>
+<td class="decimal">7.61</td>
+<td class="decimal">8.76</td>
+<td class="decimal">4.902</td>
+<td>15</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="sun-solaris-amd-opteron">
+<h2><a class="toc-backref" href="#id8">Sun Solaris / AMD Opteron</a></h2>
+<!-- Last update: Wed Dec 21 16:11:28 CST 2011 -->
+<p>The following table shows the performance boost in GraphicsMagick
+1.4 as threads are added on a four-core AMD Opteron 3.0GHz system
+running Sun Solaris 10:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On Four Core AMD Operon System</caption>
+<colgroup>
+<col width="68%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="8%" />
+<col width="4%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">2</th>
+<th class="head">3</th>
+<th class="head">4</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.23</td>
+<td class="decimal">1.22</td>
+<td class="decimal">1.18</td>
+<td class="decimal">32.635</td>
+<td>2</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">2.92</td>
+<td class="decimal">3.12</td>
+<td class="decimal">0.971</td>
+<td>4</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.07</td>
+<td class="decimal">12.762</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.74</td>
+<td class="decimal">2.26</td>
+<td class="decimal">2.56</td>
+<td class="decimal">2.284</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">2.47</td>
+<td class="decimal">2.99</td>
+<td class="decimal">1.777</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.63</td>
+<td class="decimal">3.22</td>
+<td class="decimal">1.386</td>
+<td>4</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">2.56</td>
+<td class="decimal">3.08</td>
+<td class="decimal">0.763</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.39</td>
+<td class="decimal">1.53</td>
+<td class="decimal">1.49</td>
+<td class="decimal">13.772</td>
+<td>3</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">2.38</td>
+<td class="decimal">2.84</td>
+<td class="decimal">9.690</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.85</td>
+<td class="decimal">3.59</td>
+<td class="decimal">2.991</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.77</td>
+<td class="decimal">3.46</td>
+<td class="decimal">4.469</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.93</td>
+<td class="decimal">9.980</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.88</td>
+<td class="decimal">9.800</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.43</td>
+<td class="decimal">2.85</td>
+<td class="decimal">9.652</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.92</td>
+<td class="decimal">9.930</td>
+<td>4</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.94</td>
+<td class="decimal">3.88</td>
+<td class="decimal">0.539</td>
+<td>4</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.93</td>
+<td class="decimal">3.86</td>
+<td class="decimal">0.591</td>
+<td>4</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.73</td>
+<td class="decimal">3.45</td>
+<td class="decimal">3.689</td>
+<td>4</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">2.50</td>
+<td class="decimal">3.04</td>
+<td class="decimal">8.111</td>
+<td>4</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.51</td>
+<td class="decimal">2.84</td>
+<td class="decimal">2.85</td>
+<td class="decimal">0.254</td>
+<td>4</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.87</td>
+<td class="decimal">3.68</td>
+<td class="decimal">2.000</td>
+<td>4</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.56</td>
+<td class="decimal">3.15</td>
+<td class="decimal">1.536</td>
+<td>4</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.02</td>
+<td class="decimal">3.01</td>
+<td class="decimal">3.95</td>
+<td class="decimal">0.411</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.84</td>
+<td class="decimal">3.67</td>
+<td class="decimal">2.109</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.01</td>
+<td class="decimal">2.96</td>
+<td class="decimal">3.86</td>
+<td class="decimal">0.725</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.02</td>
+<td class="decimal">3.00</td>
+<td class="decimal">3.95</td>
+<td class="decimal">0.253</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.91</td>
+<td class="decimal">3.72</td>
+<td class="decimal">2.178</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.87</td>
+<td class="decimal">3.71</td>
+<td class="decimal">2.240</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.90</td>
+<td class="decimal">3.67</td>
+<td class="decimal">2.006</td>
+<td>4</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.88</td>
+<td class="decimal">3.64</td>
+<td class="decimal">0.880</td>
+<td>4</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.68</td>
+<td class="decimal">3.54</td>
+<td class="decimal">1.074</td>
+<td>4</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.91</td>
+<td class="decimal">3.75</td>
+<td class="decimal">1.015</td>
+<td>4</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.03</td>
+<td class="decimal">3.01</td>
+<td class="decimal">3.96</td>
+<td class="decimal">0.277</td>
+<td>4</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.93</td>
+<td class="decimal">3.89</td>
+<td class="decimal">0.105</td>
+<td>4</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.50</td>
+<td class="decimal">3.08</td>
+<td class="decimal">7.662</td>
+<td>4</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.89</td>
+<td class="decimal">3.71</td>
+<td class="decimal">2.367</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.64</td>
+<td class="decimal">3.35</td>
+<td class="decimal">2.616</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.04</td>
+<td class="decimal">3.01</td>
+<td class="decimal">3.98</td>
+<td class="decimal">0.322</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.01</td>
+<td class="decimal">2.97</td>
+<td class="decimal">3.87</td>
+<td class="decimal">0.518</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.66</td>
+<td class="decimal">3.36</td>
+<td class="decimal">2.449</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.86</td>
+<td class="decimal">3.68</td>
+<td class="decimal">1.093</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.94</td>
+<td class="decimal">3.78</td>
+<td class="decimal">0.836</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.01</td>
+<td class="decimal">2.96</td>
+<td class="decimal">3.91</td>
+<td class="decimal">0.270</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.04</td>
+<td class="decimal">3.00</td>
+<td class="decimal">3.96</td>
+<td class="decimal">0.103</td>
+<td>4</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">2.16</td>
+<td class="decimal">2.42</td>
+<td class="decimal">14.612</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.43</td>
+<td class="decimal">2.90</td>
+<td class="decimal">10.689</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.16</td>
+<td class="decimal">1.25</td>
+<td class="decimal">1.19</td>
+<td class="decimal">15.584</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.15</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.19</td>
+<td class="decimal">16.235</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.57</td>
+<td class="decimal">1.89</td>
+<td class="decimal">1.93</td>
+<td class="decimal">14.741</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">2.47</td>
+<td class="decimal">2.97</td>
+<td class="decimal">9.742</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.72</td>
+<td class="decimal">1.77</td>
+<td class="decimal">12.724</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.17</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.20</td>
+<td class="decimal">14.841</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.25</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.34</td>
+<td class="decimal">14.770</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.86</td>
+<td class="decimal">10.558</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.16</td>
+<td class="decimal">1.25</td>
+<td class="decimal">1.18</td>
+<td class="decimal">15.584</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.28</td>
+<td class="decimal">1.43</td>
+<td class="decimal">1.40</td>
+<td class="decimal">15.800</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">2.45</td>
+<td class="decimal">2.90</td>
+<td class="decimal">10.338</td>
+<td>4</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.15</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.19</td>
+<td class="decimal">15.637</td>
+<td>3</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.39</td>
+<td class="decimal">1.58</td>
+<td class="decimal">1.56</td>
+<td class="decimal">15.622</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.28</td>
+<td class="decimal">1.43</td>
+<td class="decimal">1.44</td>
+<td class="decimal">16.783</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.31</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.56</td>
+<td class="decimal">17.313</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.17</td>
+<td class="decimal">1.27</td>
+<td class="decimal">1.22</td>
+<td class="decimal">16.168</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.01</td>
+<td class="decimal">3.00</td>
+<td class="decimal">3.93</td>
+<td class="decimal">0.326</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.87</td>
+<td class="decimal">3.63</td>
+<td class="decimal">2.756</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.93</td>
+<td class="decimal">3.82</td>
+<td class="decimal">1.162</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.95</td>
+<td class="decimal">3.88</td>
+<td class="decimal">0.531</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.94</td>
+<td class="decimal">3.86</td>
+<td class="decimal">0.877</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.82</td>
+<td class="decimal">3.60</td>
+<td class="decimal">2.962</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.46</td>
+<td class="decimal">2.95</td>
+<td class="decimal">10.479</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.40</td>
+<td class="decimal">2.88</td>
+<td class="decimal">10.259</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.89</td>
+<td class="decimal">10.317</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">2.45</td>
+<td class="decimal">2.94</td>
+<td class="decimal">10.479</td>
+<td>4</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.93</td>
+<td class="decimal">3.85</td>
+<td class="decimal">1.139</td>
+<td>4</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">2.50</td>
+<td class="decimal">2.99</td>
+<td class="decimal">9.037</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.22</td>
+<td class="decimal">1.21</td>
+<td class="decimal">1.17</td>
+<td class="decimal">32.368</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.63</td>
+<td class="decimal">3.24</td>
+<td class="decimal">6.931</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">2.59</td>
+<td class="decimal">3.05</td>
+<td class="decimal">6.207</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.65</td>
+<td class="decimal">3.24</td>
+<td class="decimal">6.567</td>
+<td>4</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.53</td>
+<td class="decimal">2.21</td>
+<td class="decimal">2.74</td>
+<td class="decimal">0.954</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.64</td>
+<td class="decimal">2.38</td>
+<td class="decimal">3.03</td>
+<td class="decimal">3.210</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.47</td>
+<td class="decimal">3.06</td>
+<td class="decimal">2.157</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.48</td>
+<td class="decimal">2.12</td>
+<td class="decimal">2.61</td>
+<td class="decimal">0.384</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.97</td>
+<td class="decimal">0.463</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.76</td>
+<td class="decimal">2.34</td>
+<td class="decimal">2.93</td>
+<td class="decimal">0.205</td>
+<td>4</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.77</td>
+<td class="decimal">2.08</td>
+<td class="decimal">0.027</td>
+<td>4</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.69</td>
+<td class="decimal">3.37</td>
+<td class="decimal">3.575</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.87</td>
+<td class="decimal">3.68</td>
+<td class="decimal">2.115</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.01</td>
+<td class="decimal">2.97</td>
+<td class="decimal">3.87</td>
+<td class="decimal">0.735</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.02</td>
+<td class="decimal">2.98</td>
+<td class="decimal">3.94</td>
+<td class="decimal">0.252</td>
+<td>4</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">2.20</td>
+<td class="decimal">2.71</td>
+<td class="decimal">0.244</td>
+<td>4</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.40</td>
+<td class="decimal">1.59</td>
+<td class="decimal">1.58</td>
+<td class="decimal">15.569</td>
+<td>3</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">2.70</td>
+<td class="decimal">3.68</td>
+<td class="decimal">1.089</td>
+<td>4</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.75</td>
+<td class="decimal">2.28</td>
+<td class="decimal">2.64</td>
+<td class="decimal">12.961</td>
+<td>4</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.49</td>
+<td class="decimal">1.76</td>
+<td class="decimal">1.80</td>
+<td class="decimal">18.981</td>
+<td>4</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">2.66</td>
+<td class="decimal">3.38</td>
+<td class="decimal">4.433</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.85</td>
+<td class="decimal">1.907</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">2.54</td>
+<td class="decimal">3.09</td>
+<td class="decimal">1.487</td>
+<td>4</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.63</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.06</td>
+<td class="decimal">0.793</td>
+<td>4</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="sun-solaris-ultrasparc-iii">
+<h2><a class="toc-backref" href="#id9">Sun Solaris / UltraSPARC III</a></h2>
+<!-- Last update: Wed Dec 21 16:14:39 CST 2011 -->
+<p>The following table shows the performance boost as threads are added
+on 2 CPU Sun SPARC 1.2GHz workstation running Sun Solaris 10. This
+system obtains quite substantial benefit for most key algorithms:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On Two CPU SPARC System</caption>
+<colgroup>
+<col width="76%" />
+<col width="5%" />
+<col width="5%" />
+<col width="9%" />
+<col width="4%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">2</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.14</td>
+<td class="decimal">13.917</td>
+<td>2</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">0.158</td>
+<td>2</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.51</td>
+<td class="decimal">2.852</td>
+<td>2</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.77</td>
+<td class="decimal">0.347</td>
+<td>2</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">0.267</td>
+<td>2</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">0.187</td>
+<td>2</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.76</td>
+<td class="decimal">0.123</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.30</td>
+<td class="decimal">2.338</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">1.275</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">0.531</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">0.607</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">1.289</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">1.292</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">1.292</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">1.287</td>
+<td>2</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">0.077</td>
+<td>2</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">0.080</td>
+<td>2</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">0.521</td>
+<td>2</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.77</td>
+<td class="decimal">1.304</td>
+<td>2</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.50</td>
+<td class="decimal">0.030</td>
+<td>2</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">0.295</td>
+<td>2</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.77</td>
+<td class="decimal">0.223</td>
+<td>2</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">0.080</td>
+<td>2</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">0.278</td>
+<td>2</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">0.110</td>
+<td>2</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">0.034</td>
+<td>2</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">0.382</td>
+<td>2</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">0.382</td>
+<td>2</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">0.323</td>
+<td>2</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">0.159</td>
+<td>2</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">0.195</td>
+<td>2</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">0.201</td>
+<td>2</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">0.069</td>
+<td>2</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">0.027</td>
+<td>2</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">1.625</td>
+<td>2</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">0.283</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">0.321</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">0.056</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">0.090</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">0.305</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">0.164</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">0.096</td>
+<td>2</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">0.066</td>
+<td>2</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">0.026</td>
+<td>2</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">1.619</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">1.186</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.54</td>
+<td class="decimal">3.593</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.38</td>
+<td class="decimal">3.976</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.54</td>
+<td class="decimal">3.320</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">0.931</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.52</td>
+<td class="decimal">3.131</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.61</td>
+<td class="decimal">3.605</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">3.626</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.88</td>
+<td class="decimal">1.190</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.57</td>
+<td class="decimal">3.633</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.56</td>
+<td class="decimal">3.619</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">1.228</td>
+<td>2</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.49</td>
+<td class="decimal">3.755</td>
+<td>2</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.61</td>
+<td class="decimal">2.772</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">2.879</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">2.841</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.54</td>
+<td class="decimal">3.640</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">0.058</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">0.322</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">0.165</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">0.090</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">0.098</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">0.340</td>
+<td>2</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.76</td>
+<td class="decimal">1.468</td>
+<td>2</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.77</td>
+<td class="decimal">1.498</td>
+<td>2</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">1.493</td>
+<td>2</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">1.501</td>
+<td>2</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">0.140</td>
+<td>2</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">1.156</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.01</td>
+<td class="decimal">13.439</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">1.017</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">0.817</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">0.835</td>
+<td>2</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">0.257</td>
+<td>2</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">0.527</td>
+<td>2</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">0.382</td>
+<td>2</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">0.108</td>
+<td>2</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">0.148</td>
+<td>2</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.62</td>
+<td class="decimal">0.063</td>
+<td>2</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.33</td>
+<td class="decimal">0.004</td>
+<td>2</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">0.383</td>
+<td>2</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">0.278</td>
+<td>2</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">0.110</td>
+<td>2</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">0.034</td>
+<td>2</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.47</td>
+<td class="decimal">0.103</td>
+<td>2</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.51</td>
+<td class="decimal">3.288</td>
+<td>2</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">0.196</td>
+<td>2</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">1.487</td>
+<td>2</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">3.488</td>
+<td>2</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">0.565</td>
+<td>2</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">0.272</td>
+<td>2</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">0.219</td>
+<td>2</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">0.207</td>
+<td>2</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="ibm-aix-ibm-power5">
+<h2><a class="toc-backref" href="#id10">IBM AIX / IBM Power5+</a></h2>
+<!-- Last update: Mon Jul 20 19:15:49 CDT 2009 -->
+<p>The following table shows the boost on a four core IBM P5+ server
+system (IBM System p5 505 Express with (2) 2.1Ghz CPUs) running AIX:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On Four Core IBM P5+ System</caption>
+<colgroup>
+<col width="64%" />
+<col width="6%" />
+<col width="6%" />
+<col width="6%" />
+<col width="6%" />
+<col width="8%" />
+<col width="5%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">2</th>
+<th class="head">3</th>
+<th class="head">4</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.56</td>
+<td class="decimal">1.66</td>
+<td class="decimal">1.75</td>
+<td class="decimal">290.60</td>
+<td>4</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.54</td>
+<td class="decimal">3.13</td>
+<td class="decimal">2.48</td>
+<td>4</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.64</td>
+<td class="decimal">2.41</td>
+<td class="decimal">2.78</td>
+<td class="decimal">49.70</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.50</td>
+<td class="decimal">3.03</td>
+<td class="decimal">2.71</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.67</td>
+<td class="decimal">3.30</td>
+<td class="decimal">2.13</td>
+<td>4</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.68</td>
+<td class="decimal">3.35</td>
+<td class="decimal">0.96</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.52</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.59</td>
+<td class="decimal">67.00</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.70</td>
+<td class="decimal">2.47</td>
+<td class="decimal">2.93</td>
+<td class="decimal">17.17</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">2.38</td>
+<td class="decimal">2.97</td>
+<td class="decimal">8.20</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.56</td>
+<td class="decimal">2.88</td>
+<td class="decimal">7.84</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.94</td>
+<td class="decimal">17.20</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.30</td>
+<td class="decimal">2.49</td>
+<td class="decimal">3.04</td>
+<td class="decimal">17.20</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.92</td>
+<td class="decimal">17.10</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.50</td>
+<td class="decimal">3.04</td>
+<td class="decimal">17.20</td>
+<td>4</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.50</td>
+<td class="decimal">2.97</td>
+<td class="decimal">2.09</td>
+<td>4</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.50</td>
+<td class="decimal">2.99</td>
+<td class="decimal">2.15</td>
+<td>4</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.03</td>
+<td class="decimal">2.84</td>
+<td class="decimal">3.60</td>
+<td class="decimal">3.79</td>
+<td>4</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.77</td>
+<td class="decimal">3.55</td>
+<td class="decimal">11.75</td>
+<td>4</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.49</td>
+<td class="decimal">2.79</td>
+<td class="decimal">2.81</td>
+<td class="decimal">0.27</td>
+<td>4</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.42</td>
+<td class="decimal">3.31</td>
+<td class="decimal">3.07</td>
+<td class="decimal">3.00</td>
+<td>3</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.39</td>
+<td class="decimal">2.27</td>
+<td class="decimal">1.20</td>
+<td>3</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.10</td>
+<td class="decimal">2.93</td>
+<td class="decimal">3.08</td>
+<td class="decimal">0.74</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.05</td>
+<td class="decimal">2.91</td>
+<td class="decimal">3.40</td>
+<td class="decimal">1.79</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.86</td>
+<td class="decimal">3.70</td>
+<td class="decimal">0.79</td>
+<td>4</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.19</td>
+<td class="decimal">2.42</td>
+<td class="decimal">3.17</td>
+<td class="decimal">2.83</td>
+<td>4</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">2.20</td>
+<td class="decimal">3.08</td>
+<td class="decimal">3.00</td>
+<td>4</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.26</td>
+<td class="decimal">2.42</td>
+<td class="decimal">1.13</td>
+<td>4</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.03</td>
+<td class="decimal">1.32</td>
+<td class="decimal">2.86</td>
+<td class="decimal">0.79</td>
+<td>4</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.40</td>
+<td class="decimal">2.81</td>
+<td class="decimal">0.30</td>
+<td>4</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.83</td>
+<td class="decimal">3.67</td>
+<td class="decimal">9.72</td>
+<td>4</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.56</td>
+<td class="decimal">3.33</td>
+<td class="decimal">3.81</td>
+<td class="decimal">6.57</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.06</td>
+<td class="decimal">2.61</td>
+<td class="decimal">3.43</td>
+<td class="decimal">5.19</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.53</td>
+<td class="decimal">2.75</td>
+<td class="decimal">1.83</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.72</td>
+<td class="decimal">3.46</td>
+<td class="decimal">2.32</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">2.60</td>
+<td class="decimal">3.23</td>
+<td class="decimal">5.27</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">2.55</td>
+<td class="decimal">3.44</td>
+<td class="decimal">3.51</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">2.74</td>
+<td class="decimal">3.32</td>
+<td class="decimal">2.11</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.41</td>
+<td class="decimal">2.81</td>
+<td class="decimal">0.79</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.39</td>
+<td class="decimal">2.69</td>
+<td class="decimal">0.29</td>
+<td>4</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">2.20</td>
+<td class="decimal">2.72</td>
+<td class="decimal">36.40</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.69</td>
+<td class="decimal">1.49</td>
+<td class="decimal">5.30</td>
+<td class="decimal">14.82</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.70</td>
+<td class="decimal">1.64</td>
+<td class="decimal">1.92</td>
+<td class="decimal">160.20</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.30</td>
+<td class="decimal">1.87</td>
+<td class="decimal">1.84</td>
+<td class="decimal">166.40</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.75</td>
+<td class="decimal">1.81</td>
+<td class="decimal">1.88</td>
+<td class="decimal">134.00</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.79</td>
+<td class="decimal">3.59</td>
+<td class="decimal">15.64</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.27</td>
+<td class="decimal">1.64</td>
+<td class="decimal">1.63</td>
+<td class="decimal">102.20</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.70</td>
+<td class="decimal">149.00</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">1.75</td>
+<td class="decimal">1.77</td>
+<td class="decimal">145.20</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.71</td>
+<td class="decimal">3.59</td>
+<td class="decimal">15.57</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">1.73</td>
+<td class="decimal">1.88</td>
+<td class="decimal">165.20</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.25</td>
+<td class="decimal">1.79</td>
+<td class="decimal">1.84</td>
+<td class="decimal">163.00</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.72</td>
+<td class="decimal">3.49</td>
+<td class="decimal">16.73</td>
+<td>4</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.70</td>
+<td class="decimal">1.93</td>
+<td class="decimal">2.05</td>
+<td class="decimal">163.40</td>
+<td>4</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.03</td>
+<td class="decimal">113.00</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.08</td>
+<td class="decimal">117.60</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.17</td>
+<td class="decimal">117.00</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">1.74</td>
+<td class="decimal">1.86</td>
+<td class="decimal">164.00</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.56</td>
+<td class="decimal">3.11</td>
+<td class="decimal">2.09</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.65</td>
+<td class="decimal">3.36</td>
+<td class="decimal">5.54</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.80</td>
+<td class="decimal">3.60</td>
+<td class="decimal">3.70</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.73</td>
+<td class="decimal">3.49</td>
+<td class="decimal">2.35</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.74</td>
+<td class="decimal">3.33</td>
+<td class="decimal">2.12</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.69</td>
+<td class="decimal">3.52</td>
+<td class="decimal">5.40</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.39</td>
+<td class="decimal">53.49</td>
+<td>3</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.17</td>
+<td class="decimal">1.53</td>
+<td class="decimal">1.54</td>
+<td class="decimal">42.60</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.06</td>
+<td class="decimal">1.93</td>
+<td class="decimal">2.20</td>
+<td class="decimal">48.00</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.67</td>
+<td class="decimal">0.31</td>
+<td class="decimal">1.29</td>
+<td class="decimal">53.20</td>
+<td>2</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.18</td>
+<td class="decimal">2.18</td>
+<td class="decimal">5.64</td>
+<td>3</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.36</td>
+<td class="decimal">2.43</td>
+<td class="decimal">19.40</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.49</td>
+<td class="decimal">1.72</td>
+<td class="decimal">1.44</td>
+<td class="decimal">226.80</td>
+<td>3</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.60</td>
+<td class="decimal">3.26</td>
+<td class="decimal">10.63</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.74</td>
+<td class="decimal">2.58</td>
+<td class="decimal">3.19</td>
+<td class="decimal">7.16</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.02</td>
+<td class="decimal">3.01</td>
+<td class="decimal">6.57</td>
+<td>4</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">2.33</td>
+<td class="decimal">2.86</td>
+<td class="decimal">3.42</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.41</td>
+<td class="decimal">3.17</td>
+<td class="decimal">3.43</td>
+<td class="decimal">7.50</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.15</td>
+<td class="decimal">4.35</td>
+<td class="decimal">5.30</td>
+<td class="decimal">4.93</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.62</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.69</td>
+<td class="decimal">1.28</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">0.24</td>
+<td class="decimal">1.60</td>
+<td class="decimal">0.45</td>
+<td>2</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.12</td>
+<td class="decimal">1.21</td>
+<td class="decimal">1.25</td>
+<td class="decimal">0.03</td>
+<td>4</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.30</td>
+<td class="decimal">2.65</td>
+<td class="decimal">2.95</td>
+<td class="decimal">8.10</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">2.81</td>
+<td class="decimal">3.53</td>
+<td class="decimal">1.89</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">2.79</td>
+<td class="decimal">3.66</td>
+<td class="decimal">0.78</td>
+<td>4</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.61</td>
+<td class="decimal">2.06</td>
+<td class="decimal">2.03</td>
+<td class="decimal">1.16</td>
+<td>3</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">2.18</td>
+<td class="decimal">2.32</td>
+<td class="decimal">96.40</td>
+<td>4</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.38</td>
+<td class="decimal">2.88</td>
+<td class="decimal">3.09</td>
+<td>4</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.14</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.59</td>
+<td class="decimal">31.20</td>
+<td>4</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.30</td>
+<td class="decimal">2.57</td>
+<td class="decimal">23.06</td>
+<td>4</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">2.61</td>
+<td class="decimal">3.21</td>
+<td class="decimal">8.96</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">1.16</td>
+<td class="decimal">0.12</td>
+<td class="decimal">1.35</td>
+<td>2</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">2.65</td>
+<td class="decimal">3.39</td>
+<td class="decimal">1.83</td>
+<td>4</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">1.84</td>
+<td class="decimal">2.83</td>
+<td class="decimal">2.62</td>
+<td>4</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="apple-os-x-ibm-g5">
+<h2><a class="toc-backref" href="#id11">Apple OS-X/IBM G5</a></h2>
+<!-- Last update: Mon Jul 20 16:46:35 CDT 2009 -->
+<p>The following table shows the boost on a two core Apple PowerPC G5
+system (2.5GHz) running OS-X Leopard:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On Two Core PowerPC G5 System</caption>
+<colgroup>
+<col width="72%" />
+<col width="7%" />
+<col width="7%" />
+<col width="9%" />
+<col width="5%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">2</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">24.25</td>
+<td>2</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">1.76</td>
+<td>2</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.25</td>
+<td class="decimal">14.17</td>
+<td>2</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.70</td>
+<td>2</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">1.14</td>
+<td>2</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.76</td>
+<td class="decimal">0.56</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.11</td>
+<td class="decimal">16.07</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.47</td>
+<td class="decimal">9.38</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">5.53</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">5.61</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.46</td>
+<td class="decimal">9.36</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.42</td>
+<td class="decimal">9.07</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.47</td>
+<td class="decimal">9.34</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.48</td>
+<td class="decimal">9.38</td>
+<td>2</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">1.42</td>
+<td>2</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">1.41</td>
+<td>2</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.75</td>
+<td class="decimal">2.51</td>
+<td>2</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.40</td>
+<td class="decimal">8.43</td>
+<td>2</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.48</td>
+<td class="decimal">0.21</td>
+<td>2</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">2.60</td>
+<td>2</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">1.14</td>
+<td>2</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">0.65</td>
+<td>2</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.88</td>
+<td class="decimal">1.26</td>
+<td>2</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">0.46</td>
+<td>2</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.74</td>
+<td class="decimal">3.20</td>
+<td>2</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.74</td>
+<td class="decimal">2.95</td>
+<td>2</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.74</td>
+<td class="decimal">1.55</td>
+<td>2</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">1.92</td>
+<td>2</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.35</td>
+<td>2</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.88</td>
+<td class="decimal">0.42</td>
+<td>2</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.39</td>
+<td class="decimal">0.48</td>
+<td>2</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">0.26</td>
+<td>2</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">7.77</td>
+<td>2</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.75</td>
+<td class="decimal">4.04</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.60</td>
+<td class="decimal">3.44</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">0.99</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">1.43</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.62</td>
+<td class="decimal">3.23</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.76</td>
+<td class="decimal">1.98</td>
+<td>2</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">1.48</td>
+<td>2</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">0.59</td>
+<td>2</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">0.25</td>
+<td>2</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.23</td>
+<td class="decimal">15.11</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.56</td>
+<td class="decimal">8.28</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.98</td>
+<td class="decimal">19.16</td>
+<td>1</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.11</td>
+<td class="decimal">17.82</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.01</td>
+<td class="decimal">18.00</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">8.43</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">15.45</td>
+<td>1</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.01</td>
+<td class="decimal">18.69</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">18.80</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.56</td>
+<td class="decimal">8.05</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">19.00</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.99</td>
+<td class="decimal">19.16</td>
+<td>1</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">8.37</td>
+<td>2</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">18.56</td>
+<td>1</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.02</td>
+<td class="decimal">18.33</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.09</td>
+<td class="decimal">20.20</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.04</td>
+<td class="decimal">19.28</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.98</td>
+<td class="decimal">19.16</td>
+<td>1</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">1.07</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">3.99</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.26</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">1.59</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">1.66</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">4.31</td>
+<td>2</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.06</td>
+<td class="decimal">15.11</td>
+<td>2</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.14</td>
+<td class="decimal">14.97</td>
+<td>2</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.10</td>
+<td class="decimal">14.77</td>
+<td>2</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.08</td>
+<td class="decimal">15.25</td>
+<td>2</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">3.77</td>
+<td>2</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.30</td>
+<td class="decimal">11.90</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.02</td>
+<td class="decimal">23.90</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.67</td>
+<td class="decimal">6.68</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">6.65</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.66</td>
+<td class="decimal">6.59</td>
+<td>2</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.56</td>
+<td class="decimal">1.55</td>
+<td>2</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.76</td>
+<td class="decimal">3.73</td>
+<td>2</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.70</td>
+<td class="decimal">2.34</td>
+<td>2</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.67</td>
+<td class="decimal">0.49</td>
+<td>2</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.67</td>
+<td class="decimal">0.24</td>
+<td>2</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.26</td>
+<td class="decimal">0.05</td>
+<td>2</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.57</td>
+<td class="decimal">5.49</td>
+<td>2</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">1.26</td>
+<td>2</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">0.45</td>
+<td>2</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">0.28</td>
+<td>2</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.09</td>
+<td class="decimal">19.05</td>
+<td>2</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">2.10</td>
+<td>2</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.27</td>
+<td class="decimal">15.71</td>
+<td>2</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">6.55</td>
+<td>2</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.77</td>
+<td class="decimal">4.50</td>
+<td>2</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.66</td>
+<td class="decimal">1.46</td>
+<td>2</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.75</td>
+<td class="decimal">1.04</td>
+<td>2</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">2.17</td>
+<td>2</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="freebsd-intel-xeon">
+<h2><a class="toc-backref" href="#id12">FreeBSD / Intel Xeon</a></h2>
+<!-- Last update: Wed Dec 21 16:16:35 CST 2011 -->
+<p>The following shows the performance boost on a 2003 vintage 2-CPU
+hyperthreaded Intel Xeon system running at 2.4GHz. The operating
+system used is FreeBSD 8.0. Due to the hyperthreading support, this
+system thinks it has four CPUs even though it really only has two
+cores. This can lead to very strange results since sometimes it seems
+that the first two threads allocated may be from the same CPU,
+resulting in much less boost than expected, but obtaining full boost
+with four threads. While the threading on this system behaves poorly
+for &quot;fast&quot; algorithms, it is clear that OpenMP works well for &quot;slow&quot;
+algorithms, and some algorithms show clear benefit from
+hyperthreading:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost On Two CPU Xeon System</caption>
+<colgroup>
+<col width="68%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="8%" />
+<col width="4%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">2</th>
+<th class="head">3</th>
+<th class="head">4</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.253</td>
+<td>2</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">1.54</td>
+<td class="decimal">1.85</td>
+<td class="decimal">0.300</td>
+<td>4</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.08</td>
+<td class="decimal">1.15</td>
+<td class="decimal">1.09</td>
+<td class="decimal">2.023</td>
+<td>3</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.23</td>
+<td class="decimal">1.28</td>
+<td class="decimal">0.354</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.30</td>
+<td class="decimal">1.39</td>
+<td class="decimal">0.329</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.43</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.52</td>
+<td class="decimal">0.275</td>
+<td>4</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.39</td>
+<td class="decimal">1.32</td>
+<td class="decimal">1.35</td>
+<td class="decimal">0.171</td>
+<td>2</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.91</td>
+<td class="decimal">0.89</td>
+<td class="decimal">0.87</td>
+<td class="decimal">1.925</td>
+<td>1</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.39</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.49</td>
+<td class="decimal">1.571</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.77</td>
+<td class="decimal">1.64</td>
+<td class="decimal">2.03</td>
+<td class="decimal">0.856</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">1.72</td>
+<td class="decimal">2.04</td>
+<td class="decimal">1.187</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.39</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.53</td>
+<td class="decimal">1.602</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.36</td>
+<td class="decimal">1.36</td>
+<td class="decimal">1.54</td>
+<td class="decimal">1.618</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.38</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.580</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.38</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.54</td>
+<td class="decimal">1.616</td>
+<td>4</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.05</td>
+<td class="decimal">2.61</td>
+<td class="decimal">0.214</td>
+<td>4</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.57</td>
+<td class="decimal">0.221</td>
+<td>4</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.57</td>
+<td class="decimal">1.52</td>
+<td class="decimal">1.57</td>
+<td class="decimal">0.812</td>
+<td>4</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.37</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.082</td>
+<td>2</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.44</td>
+<td class="decimal">1.94</td>
+<td class="decimal">1.97</td>
+<td class="decimal">0.063</td>
+<td>4</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.56</td>
+<td class="decimal">1.64</td>
+<td class="decimal">0.812</td>
+<td>4</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.60</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.55</td>
+<td class="decimal">0.359</td>
+<td>2</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">1.69</td>
+<td class="decimal">2.09</td>
+<td class="decimal">0.115</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.75</td>
+<td class="decimal">1.56</td>
+<td class="decimal">1.69</td>
+<td class="decimal">0.477</td>
+<td>2</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.93</td>
+<td class="decimal">0.205</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">1.88</td>
+<td class="decimal">2.21</td>
+<td class="decimal">0.075</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.48</td>
+<td class="decimal">0.629</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">2.01</td>
+<td class="decimal">2.52</td>
+<td class="decimal">0.602</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.51</td>
+<td class="decimal">2.14</td>
+<td class="decimal">2.65</td>
+<td class="decimal">0.464</td>
+<td>4</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.51</td>
+<td class="decimal">0.233</td>
+<td>4</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.88</td>
+<td class="decimal">1.88</td>
+<td class="decimal">2.36</td>
+<td class="decimal">0.380</td>
+<td>4</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">1.23</td>
+<td class="decimal">1.34</td>
+<td class="decimal">0.305</td>
+<td>2</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.39</td>
+<td class="decimal">0.055</td>
+<td>2</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">2.20</td>
+<td class="decimal">0.022</td>
+<td>4</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.39</td>
+<td class="decimal">1.47</td>
+<td class="decimal">1.329</td>
+<td>2</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.28</td>
+<td class="decimal">0.717</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">2.03</td>
+<td class="decimal">2.49</td>
+<td class="decimal">0.394</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.53</td>
+<td class="decimal">2.37</td>
+<td class="decimal">2.86</td>
+<td class="decimal">0.163</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.76</td>
+<td class="decimal">2.98</td>
+<td class="decimal">0.185</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">2.43</td>
+<td class="decimal">2.58</td>
+<td class="decimal">0.400</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.65</td>
+<td class="decimal">0.286</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.41</td>
+<td class="decimal">3.12</td>
+<td class="decimal">0.159</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.75</td>
+<td class="decimal">1.68</td>
+<td class="decimal">1.71</td>
+<td class="decimal">0.048</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">1.60</td>
+<td class="decimal">2.20</td>
+<td class="decimal">0.022</td>
+<td>4</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.28</td>
+<td class="decimal">2.537</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.30</td>
+<td class="decimal">1.31</td>
+<td class="decimal">2.092</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.96</td>
+<td class="decimal">1.01</td>
+<td class="decimal">0.90</td>
+<td class="decimal">2.242</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.99</td>
+<td class="decimal">1.03</td>
+<td class="decimal">0.97</td>
+<td class="decimal">2.265</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.99</td>
+<td class="decimal">1.01</td>
+<td class="decimal">0.93</td>
+<td class="decimal">2.204</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.32</td>
+<td class="decimal">1.53</td>
+<td class="decimal">1.623</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.98</td>
+<td class="decimal">1.02</td>
+<td class="decimal">0.94</td>
+<td class="decimal">2.035</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.97</td>
+<td class="decimal">1.01</td>
+<td class="decimal">0.92</td>
+<td class="decimal">2.239</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.97</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.91</td>
+<td class="decimal">2.249</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.27</td>
+<td class="decimal">1.33</td>
+<td class="decimal">2.095</td>
+<td>2</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.98</td>
+<td class="decimal">1.01</td>
+<td class="decimal">0.92</td>
+<td class="decimal">2.233</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.97</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.92</td>
+<td class="decimal">2.242</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.39</td>
+<td class="decimal">2.101</td>
+<td>4</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.97</td>
+<td class="decimal">1.01</td>
+<td class="decimal">0.91</td>
+<td class="decimal">2.246</td>
+<td>3</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.99</td>
+<td class="decimal">1.01</td>
+<td class="decimal">0.93</td>
+<td class="decimal">2.246</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.08</td>
+<td class="decimal">1.09</td>
+<td class="decimal">1.07</td>
+<td class="decimal">2.655</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.10</td>
+<td class="decimal">1.12</td>
+<td class="decimal">1.10</td>
+<td class="decimal">2.576</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.96</td>
+<td class="decimal">1.02</td>
+<td class="decimal">0.91</td>
+<td class="decimal">2.276</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.48</td>
+<td class="decimal">2.20</td>
+<td class="decimal">2.86</td>
+<td class="decimal">0.189</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.36</td>
+<td class="decimal">0.587</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.06</td>
+<td class="decimal">2.64</td>
+<td class="decimal">0.383</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.24</td>
+<td class="decimal">2.92</td>
+<td class="decimal">0.242</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.17</td>
+<td class="decimal">2.84</td>
+<td class="decimal">0.213</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.28</td>
+<td class="decimal">0.578</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.56</td>
+<td class="decimal">1.613</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.47</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.58</td>
+<td class="decimal">1.643</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.60</td>
+<td class="decimal">1.653</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.19</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.61</td>
+<td class="decimal">1.665</td>
+<td>4</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.80</td>
+<td class="decimal">2.30</td>
+<td class="decimal">0.324</td>
+<td>4</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.58</td>
+<td class="decimal">1.72</td>
+<td class="decimal">1.86</td>
+<td class="decimal">1.422</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">3.267</td>
+<td>2</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.47</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.52</td>
+<td class="decimal">1.789</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.52</td>
+<td class="decimal">1.42</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.632</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.52</td>
+<td class="decimal">1.40</td>
+<td class="decimal">1.61</td>
+<td class="decimal">1.623</td>
+<td>4</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.54</td>
+<td class="decimal">1.39</td>
+<td class="decimal">0.208</td>
+<td>3</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.61</td>
+<td class="decimal">1.31</td>
+<td class="decimal">1.53</td>
+<td class="decimal">0.658</td>
+<td>2</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.60</td>
+<td class="decimal">1.39</td>
+<td class="decimal">1.55</td>
+<td class="decimal">0.361</td>
+<td>2</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.58</td>
+<td class="decimal">1.65</td>
+<td class="decimal">0.086</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.25</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.40</td>
+<td class="decimal">0.116</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.37</td>
+<td class="decimal">0.048</td>
+<td>4</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.33</td>
+<td class="decimal">0.012</td>
+<td>2</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">2.18</td>
+<td class="decimal">2.47</td>
+<td class="decimal">0.621</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.72</td>
+<td class="decimal">0.473</td>
+<td>2</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.12</td>
+<td class="decimal">1.76</td>
+<td class="decimal">1.90</td>
+<td class="decimal">0.201</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">1.76</td>
+<td class="decimal">2.21</td>
+<td class="decimal">0.075</td>
+<td>4</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.14</td>
+<td class="decimal">1.33</td>
+<td class="decimal">1.40</td>
+<td class="decimal">0.060</td>
+<td>4</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.97</td>
+<td class="decimal">1.01</td>
+<td class="decimal">0.90</td>
+<td class="decimal">2.272</td>
+<td>3</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.43</td>
+<td class="decimal">2.02</td>
+<td class="decimal">2.50</td>
+<td class="decimal">0.357</td>
+<td>4</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.19</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.12</td>
+<td class="decimal">2.220</td>
+<td>3</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.08</td>
+<td class="decimal">1.09</td>
+<td class="decimal">1.06</td>
+<td class="decimal">2.715</td>
+<td>3</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">1.75</td>
+<td class="decimal">2.14</td>
+<td class="decimal">1.091</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.47</td>
+<td class="decimal">0.320</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.40</td>
+<td class="decimal">1.41</td>
+<td class="decimal">1.54</td>
+<td class="decimal">0.296</td>
+<td>4</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">1.69</td>
+<td class="decimal">2.01</td>
+<td class="decimal">0.348</td>
+<td>4</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="windows-xp-msvc-intel-core-2-quad">
+<h2><a class="toc-backref" href="#id13">Windows XP / MSVC / Intel Core 2 Quad</a></h2>
+<!-- Last update: Sun Jan 29 16:17:01 CST 2012 -->
+<p>This system is Windows XP Professional (SP3) using the Visual Studio
+2008 compiler and a Q16 build. The system CPU is a 2.83 GHz Core 2
+Quad Processor (Q9550). This processor is a multi-chip module (MCM)
+based on two Core 2 CPUs bonded to a L3 cache in the same chip
+package.</p>
+<p>The following shows the performance boost for a Q16 build:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost on an Intel Core 2 Quad (Q9550) system</caption>
+<colgroup>
+<col width="68%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="5%" />
+<col width="8%" />
+<col width="4%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">2</th>
+<th class="head">3</th>
+<th class="head">4</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-noop</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.99</td>
+<td class="decimal">0.98</td>
+<td class="decimal">13.036</td>
+<td>1</td>
+</tr>
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.62</td>
+<td class="decimal">2.11</td>
+<td class="decimal">2.38</td>
+<td class="decimal">0.808</td>
+<td>4</td>
+</tr>
+<tr><td>-asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.09</td>
+<td class="decimal">1.17</td>
+<td class="decimal">1.18</td>
+<td class="decimal">8.271</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.62</td>
+<td class="decimal">2.12</td>
+<td class="decimal">2.47</td>
+<td class="decimal">1.551</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.25</td>
+<td class="decimal">2.62</td>
+<td class="decimal">1.378</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">2.40</td>
+<td class="decimal">2.78</td>
+<td class="decimal">1.091</td>
+<td>4</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.23</td>
+<td class="decimal">2.61</td>
+<td class="decimal">0.738</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace CMYK</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.06</td>
+<td class="decimal">1.07</td>
+<td class="decimal">1.11</td>
+<td class="decimal">7.309</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.23</td>
+<td class="decimal">2.56</td>
+<td class="decimal">4.711</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.56</td>
+<td class="decimal">3.15</td>
+<td class="decimal">3.418</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">2.45</td>
+<td class="decimal">2.97</td>
+<td class="decimal">4.332</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.77</td>
+<td class="decimal">2.23</td>
+<td class="decimal">2.55</td>
+<td class="decimal">4.655</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">2.19</td>
+<td class="decimal">2.52</td>
+<td class="decimal">4.711</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">2.21</td>
+<td class="decimal">2.48</td>
+<td class="decimal">4.613</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.75</td>
+<td class="decimal">2.23</td>
+<td class="decimal">2.55</td>
+<td class="decimal">4.712</td>
+<td>4</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.87</td>
+<td class="decimal">3.74</td>
+<td class="decimal">0.838</td>
+<td>4</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.87</td>
+<td class="decimal">3.74</td>
+<td class="decimal">0.849</td>
+<td>4</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.77</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.99</td>
+<td class="decimal">3.012</td>
+<td>4</td>
+</tr>
+<tr><td>-colorize 30%/20%/50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.70</td>
+<td class="decimal">2.31</td>
+<td class="decimal">2.70</td>
+<td class="decimal">4.036</td>
+<td>4</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.85</td>
+<td class="decimal">2.54</td>
+<td class="decimal">2.88</td>
+<td class="decimal">0.515</td>
+<td>4</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">2.67</td>
+<td class="decimal">3.37</td>
+<td class="decimal">1.751</td>
+<td>4</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">2.43</td>
+<td class="decimal">2.97</td>
+<td class="decimal">1.519</td>
+<td>4</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.90</td>
+<td class="decimal">3.80</td>
+<td class="decimal">0.600</td>
+<td>4</td>
+</tr>
+<tr><td>-fill none -stroke gold -draw 'circle 800,500 1100,800'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.59</td>
+<td class="decimal">9.938</td>
+<td>4</td>
+</tr>
+<tr><td>-fill green -stroke gold -draw 'circle 800,500 1100,800'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.42</td>
+<td class="decimal">1.63</td>
+<td class="decimal">1.76</td>
+<td class="decimal">9.312</td>
+<td>4</td>
+</tr>
+<tr><td>-fill none -stroke gold -draw 'rectangle 400,200 1100,800'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.18</td>
+<td class="decimal">1.32</td>
+<td class="decimal">1.37</td>
+<td class="decimal">11.400</td>
+<td>4</td>
+</tr>
+<tr><td>-fill blue -stroke gold -draw 'rectangle 400,200 1100,800'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.29</td>
+<td class="decimal">1.41</td>
+<td class="decimal">1.52</td>
+<td class="decimal">10.731</td>
+<td>4</td>
+</tr>
+<tr><td>-fill none -stroke gold -draw 'roundRectangle 400,200 1100,800 20,20'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.17</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.28</td>
+<td class="decimal">11.492</td>
+<td>4</td>
+</tr>
+<tr><td>-fill blue -stroke gold -draw 'roundRectangle 400,200 1100,800 20,20'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.23</td>
+<td class="decimal">1.36</td>
+<td class="decimal">1.43</td>
+<td class="decimal">10.831</td>
+<td>4</td>
+</tr>
+<tr><td>-fill none -stroke gold -draw 'polygon 400,200 1100,800 100,300'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.23</td>
+<td class="decimal">1.39</td>
+<td class="decimal">1.45</td>
+<td class="decimal">11.028</td>
+<td>4</td>
+</tr>
+<tr><td>-fill blue -stroke gold -draw 'polygon 400,200 1100,800 100,300'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.40</td>
+<td class="decimal">1.49</td>
+<td class="decimal">10.731</td>
+<td>4</td>
+</tr>
+<tr><td>-fill none -stroke gold -draw 'Bezier 400,200 1100,800 100,300'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.09</td>
+<td class="decimal">1.13</td>
+<td class="decimal">1.18</td>
+<td class="decimal">11.655</td>
+<td>4</td>
+</tr>
+<tr><td>-fill blue -stroke gold -draw 'Bezier 400,200 1100,800 100,300'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.13</td>
+<td class="decimal">1.18</td>
+<td class="decimal">1.22</td>
+<td class="decimal">11.563</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.88</td>
+<td class="decimal">2.65</td>
+<td class="decimal">3.36</td>
+<td class="decimal">1.883</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.90</td>
+<td class="decimal">3.76</td>
+<td class="decimal">0.884</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.91</td>
+<td class="decimal">3.82</td>
+<td class="decimal">0.298</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">2.66</td>
+<td class="decimal">3.28</td>
+<td class="decimal">2.286</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">2.57</td>
+<td class="decimal">3.22</td>
+<td class="decimal">2.193</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">2.17</td>
+<td class="decimal">2.53</td>
+<td class="decimal">1.378</td>
+<td>4</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">2.79</td>
+<td class="decimal">3.38</td>
+<td class="decimal">1.150</td>
+<td>4</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.78</td>
+<td class="decimal">3.57</td>
+<td class="decimal">1.214</td>
+<td>4</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.60</td>
+<td class="decimal">3.24</td>
+<td class="decimal">1.185</td>
+<td>4</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.68</td>
+<td class="decimal">3.47</td>
+<td class="decimal">0.253</td>
+<td>4</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.77</td>
+<td class="decimal">3.65</td>
+<td class="decimal">0.095</td>
+<td>4</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.69</td>
+<td class="decimal">2.17</td>
+<td class="decimal">2.55</td>
+<td class="decimal">5.415</td>
+<td>4</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.60</td>
+<td class="decimal">3.29</td>
+<td class="decimal">2.954</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">2.15</td>
+<td class="decimal">2.51</td>
+<td class="decimal">2.400</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">2.75</td>
+<td class="decimal">3.44</td>
+<td class="decimal">0.713</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.71</td>
+<td class="decimal">3.42</td>
+<td class="decimal">0.899</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.70</td>
+<td class="decimal">2.20</td>
+<td class="decimal">2.53</td>
+<td class="decimal">2.239</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">2.49</td>
+<td class="decimal">2.95</td>
+<td class="decimal">1.450</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">2.75</td>
+<td class="decimal">3.29</td>
+<td class="decimal">0.727</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.58</td>
+<td class="decimal">3.81</td>
+<td class="decimal">0.278</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.77</td>
+<td class="decimal">3.65</td>
+<td class="decimal">0.095</td>
+<td>4</td>
+</tr>
+<tr><td>-fill blue -fuzz 35% -opaque red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.51</td>
+<td class="decimal">1.60</td>
+<td class="decimal">9.771</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.27</td>
+<td class="decimal">2.71</td>
+<td class="decimal">5.497</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all And 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.05</td>
+<td class="decimal">1.08</td>
+<td class="decimal">1.09</td>
+<td class="decimal">8.600</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Assign 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">1.05</td>
+<td class="decimal">1.05</td>
+<td class="decimal">8.348</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Depth 6</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.09</td>
+<td class="decimal">1.08</td>
+<td class="decimal">1.12</td>
+<td class="decimal">8.520</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.70</td>
+<td class="decimal">5.497</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Gamma 0.7</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">1.08</td>
+<td class="decimal">1.10</td>
+<td class="decimal">8.271</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Negate 1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.02</td>
+<td class="decimal">1.04</td>
+<td class="decimal">1.06</td>
+<td class="decimal">8.398</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all LShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.08</td>
+<td class="decimal">1.07</td>
+<td class="decimal">1.09</td>
+<td class="decimal">8.600</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">2.29</td>
+<td class="decimal">2.71</td>
+<td class="decimal">5.498</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Or 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.02</td>
+<td class="decimal">1.06</td>
+<td class="decimal">1.09</td>
+<td class="decimal">8.612</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all RShift 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">1.09</td>
+<td class="decimal">1.09</td>
+<td class="decimal">8.574</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">2.31</td>
+<td class="decimal">2.73</td>
+<td class="decimal">5.333</td>
+<td>4</td>
+</tr>
+<tr><td>-operator red Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.04</td>
+<td class="decimal">1.06</td>
+<td class="decimal">1.09</td>
+<td class="decimal">8.746</td>
+<td>4</td>
+</tr>
+<tr><td>-operator gray Threshold 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.03</td>
+<td class="decimal">1.08</td>
+<td class="decimal">1.09</td>
+<td class="decimal">8.638</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Threshold-White 80%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.13</td>
+<td class="decimal">1.14</td>
+<td class="decimal">1.15</td>
+<td class="decimal">10.208</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Threshold-Black 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.16</td>
+<td class="decimal">1.13</td>
+<td class="decimal">1.18</td>
+<td class="decimal">10.000</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Xor 233</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.06</td>
+<td class="decimal">1.10</td>
+<td class="decimal">1.10</td>
+<td class="decimal">8.692</td>
+<td>3</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.90</td>
+<td class="decimal">3.54</td>
+<td class="decimal">0.757</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.61</td>
+<td class="decimal">3.23</td>
+<td class="decimal">3.200</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.91</td>
+<td class="decimal">2.76</td>
+<td class="decimal">3.53</td>
+<td class="decimal">1.866</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.90</td>
+<td class="decimal">3.48</td>
+<td class="decimal">0.944</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.88</td>
+<td class="decimal">3.77</td>
+<td class="decimal">0.867</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">2.57</td>
+<td class="decimal">3.18</td>
+<td class="decimal">3.429</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.26</td>
+<td class="decimal">1.28</td>
+<td class="decimal">1.32</td>
+<td class="decimal">7.308</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.27</td>
+<td class="decimal">1.30</td>
+<td class="decimal">1.35</td>
+<td class="decimal">7.438</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.25</td>
+<td class="decimal">1.30</td>
+<td class="decimal">1.35</td>
+<td class="decimal">7.400</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.29</td>
+<td class="decimal">1.33</td>
+<td class="decimal">7.354</td>
+<td>4</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.93</td>
+<td class="decimal">2.83</td>
+<td class="decimal">3.65</td>
+<td class="decimal">0.836</td>
+<td>4</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.58</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.25</td>
+<td class="decimal">6.634</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '1,0,0,0,1,0,0,0,1'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.01</td>
+<td class="decimal">1.01</td>
+<td class="decimal">13.000</td>
+<td>3</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.21</td>
+<td class="decimal">2.65</td>
+<td class="decimal">5.514</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.79</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.95</td>
+<td class="decimal">4.346</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.95</td>
+<td class="decimal">4.372</td>
+<td>4</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.65</td>
+<td class="decimal">2.25</td>
+<td class="decimal">2.65</td>
+<td class="decimal">1.751</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.71</td>
+<td class="decimal">2.23</td>
+<td class="decimal">2.63</td>
+<td class="decimal">4.834</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">2.31</td>
+<td class="decimal">2.69</td>
+<td class="decimal">2.499</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.36</td>
+<td class="decimal">2.58</td>
+<td class="decimal">0.715</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.75</td>
+<td class="decimal">2.07</td>
+<td class="decimal">0.723</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.49</td>
+<td class="decimal">1.55</td>
+<td class="decimal">1.76</td>
+<td class="decimal">0.311</td>
+<td>4</td>
+</tr>
+<tr><td>-segment 0.5x0.25</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.44</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.69</td>
+<td class="decimal">0.027</td>
+<td>4</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.67</td>
+<td class="decimal">2.20</td>
+<td class="decimal">2.55</td>
+<td class="decimal">4.085</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.64</td>
+<td class="decimal">3.36</td>
+<td class="decimal">1.877</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.90</td>
+<td class="decimal">3.76</td>
+<td class="decimal">0.879</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.91</td>
+<td class="decimal">3.83</td>
+<td class="decimal">0.299</td>
+<td>4</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.05</td>
+<td class="decimal">1.30</td>
+<td class="decimal">1.49</td>
+<td class="decimal">0.441</td>
+<td>4</td>
+</tr>
+<tr><td>-solarize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.06</td>
+<td class="decimal">1.12</td>
+<td class="decimal">1.12</td>
+<td class="decimal">8.322</td>
+<td>4</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.74</td>
+<td class="decimal">3.53</td>
+<td class="decimal">1.366</td>
+<td>4</td>
+</tr>
+<tr><td>-fuzz 35% -transparent red</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.32</td>
+<td class="decimal">1.42</td>
+<td class="decimal">1.43</td>
+<td class="decimal">8.322</td>
+<td>4</td>
+</tr>
+<tr><td>-trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.38</td>
+<td class="decimal">1.60</td>
+<td class="decimal">1.70</td>
+<td class="decimal">9.846</td>
+<td>4</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.69</td>
+<td class="decimal">2.30</td>
+<td class="decimal">2.77</td>
+<td class="decimal">5.200</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.69</td>
+<td class="decimal">2.17</td>
+<td class="decimal">2.60</td>
+<td class="decimal">1.333</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.73</td>
+<td class="decimal">2.32</td>
+<td class="decimal">2.63</td>
+<td class="decimal">1.160</td>
+<td>4</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.57</td>
+<td class="decimal">3.08</td>
+<td class="decimal">1.378</td>
+<td>4</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="windows-7-mingw-intel-core-2-quad">
+<h2><a class="toc-backref" href="#id14">Windows 7 / MinGW / Intel Core 2 Quad</a></h2>
+<!-- Last update: Sun Mar 9 10:39:14 CDT 2015 -->
+<p>GCC 4.8.2 (x86_64-win32-sjlj) from a build of the 'MinGW-w64'_ project
+was installed on the same Windows system with the 2.83 GHz Core 2 Quad
+Processor (Q9550) as described above. The build is a 32-bit build.
+This processor is a multi-chip module (MCM) based on two Core 2 CPUs
+bonded to a L3 cache in the same chip package.</p>
+<p>The following shows the performance boost for a Q16 build:</p>
+<table border="1" class="docutils">
+<caption>Performance Boost on an Intel Core 2 Quad (Q9550) system</caption>
+<colgroup>
+<col width="59%" />
+<col width="6%" />
+<col width="6%" />
+<col width="6%" />
+<col width="6%" />
+<col width="10%" />
+<col width="5%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Operation</th>
+<th class="head">1</th>
+<th class="head">2</th>
+<th class="head">3</th>
+<th class="head">4</th>
+<th class="head">iter/s</th>
+<th class="head">thds</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>-affine 1,0,0.785,1,0,0 -transform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.78</td>
+<td class="decimal">2.46</td>
+<td class="decimal">3.01</td>
+<td class="decimal">1.447</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.48</td>
+<td class="decimal">1.89</td>
+<td class="decimal">2.12</td>
+<td class="decimal">1.208</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">2.18</td>
+<td class="decimal">2.53</td>
+<td class="decimal">0.955</td>
+<td>4</td>
+</tr>
+<tr><td>-blur 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.75</td>
+<td class="decimal">2.44</td>
+<td class="decimal">2.96</td>
+<td class="decimal">0.668</td>
+<td>4</td>
+</tr>
+<tr><td>-charcoal 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.67</td>
+<td class="decimal">2.16</td>
+<td class="decimal">2.53</td>
+<td class="decimal">0.613</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace GRAY</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.38</td>
+<td class="decimal">1.60</td>
+<td class="decimal">1.71</td>
+<td class="decimal">7.689</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HSL</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">2.44</td>
+<td class="decimal">3.00</td>
+<td class="decimal">3.631</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace HWB</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.72</td>
+<td class="decimal">2.27</td>
+<td class="decimal">2.70</td>
+<td class="decimal">4.568</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace OHTA</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.31</td>
+<td class="decimal">1.63</td>
+<td class="decimal">1.72</td>
+<td class="decimal">7.673</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YCbCr</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.40</td>
+<td class="decimal">1.60</td>
+<td class="decimal">1.70</td>
+<td class="decimal">7.658</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YIQ</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.34</td>
+<td class="decimal">1.65</td>
+<td class="decimal">1.73</td>
+<td class="decimal">7.764</td>
+<td>4</td>
+</tr>
+<tr><td>-colorspace YUV</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.37</td>
+<td class="decimal">1.62</td>
+<td class="decimal">1.72</td>
+<td class="decimal">7.692</td>
+<td>4</td>
+</tr>
+<tr><td>-contrast -contrast -contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.84</td>
+<td class="decimal">3.70</td>
+<td class="decimal">0.858</td>
+<td>4</td>
+</tr>
+<tr><td>+contrast +contrast +contrast</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.84</td>
+<td class="decimal">3.69</td>
+<td class="decimal">0.872</td>
+<td>4</td>
+</tr>
+<tr><td>-convolve 1,1,1,1,4,1,1,1,1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.80</td>
+<td class="decimal">2.49</td>
+<td class="decimal">3.09</td>
+<td class="decimal">2.734</td>
+<td>4</td>
+</tr>
+<tr><td>-despeckle</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.64</td>
+<td class="decimal">2.09</td>
+<td class="decimal">2.30</td>
+<td class="decimal">0.561</td>
+<td>4</td>
+</tr>
+<tr><td>-edge 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.50</td>
+<td class="decimal">3.09</td>
+<td class="decimal">2.543</td>
+<td>4</td>
+</tr>
+<tr><td>-emboss 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.54</td>
+<td class="decimal">3.23</td>
+<td class="decimal">1.101</td>
+<td>4</td>
+</tr>
+<tr><td>-enhance</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.96</td>
+<td class="decimal">2.89</td>
+<td class="decimal">3.79</td>
+<td class="decimal">0.603</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.70</td>
+<td class="decimal">3.56</td>
+<td class="decimal">1.295</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.92</td>
+<td class="decimal">3.81</td>
+<td class="decimal">0.453</td>
+<td>4</td>
+</tr>
+<tr><td>-gaussian 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.97</td>
+<td class="decimal">3.94</td>
+<td class="decimal">0.134</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:8</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.52</td>
+<td class="decimal">3.00</td>
+<td class="decimal">2.981</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:10</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.52</td>
+<td class="decimal">3.10</td>
+<td class="decimal">3.046</td>
+<td>4</td>
+</tr>
+<tr><td>-hald-clut identity:14</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.48</td>
+<td class="decimal">3.00</td>
+<td class="decimal">2.564</td>
+<td>4</td>
+</tr>
+<tr><td>-implode 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.87</td>
+<td class="decimal">2.79</td>
+<td class="decimal">3.56</td>
+<td class="decimal">1.098</td>
+<td>4</td>
+</tr>
+<tr><td>-implode -1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.90</td>
+<td class="decimal">2.71</td>
+<td class="decimal">3.50</td>
+<td class="decimal">1.496</td>
+<td>4</td>
+</tr>
+<tr><td>-lat 10x10-5%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.00</td>
+<td class="decimal">0.98</td>
+<td class="decimal">0.98</td>
+<td class="decimal">1.459</td>
+<td>1</td>
+</tr>
+<tr><td>-median 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.93</td>
+<td class="decimal">3.60</td>
+<td class="decimal">0.270</td>
+<td>4</td>
+</tr>
+<tr><td>-median 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.04</td>
+<td class="decimal">2.93</td>
+<td class="decimal">4.00</td>
+<td class="decimal">0.108</td>
+<td>4</td>
+</tr>
+<tr><td>-minify</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.69</td>
+<td class="decimal">2.20</td>
+<td class="decimal">2.59</td>
+<td class="decimal">4.828</td>
+<td>4</td>
+</tr>
+<tr><td>-modulate 110/100/95</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.47</td>
+<td class="decimal">3.05</td>
+<td class="decimal">2.952</td>
+<td>4</td>
+</tr>
+<tr><td>-motion-blur 0x3+30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.91</td>
+<td class="decimal">3.73</td>
+<td class="decimal">0.351</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Uniform</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.51</td>
+<td class="decimal">1.87</td>
+<td class="decimal">2.15</td>
+<td class="decimal">3.175</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Gaussian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.85</td>
+<td class="decimal">3.66</td>
+<td class="decimal">0.487</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Multiplicative</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.94</td>
+<td class="decimal">2.81</td>
+<td class="decimal">3.60</td>
+<td class="decimal">0.760</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Impulse</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.11</td>
+<td class="decimal">3.189</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Laplacian</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.83</td>
+<td class="decimal">2.61</td>
+<td class="decimal">3.26</td>
+<td class="decimal">1.276</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Poisson</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.77</td>
+<td class="decimal">3.53</td>
+<td class="decimal">0.774</td>
+<td>4</td>
+</tr>
+<tr><td>+noise Random</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.62</td>
+<td class="decimal">2.11</td>
+<td class="decimal">2.48</td>
+<td class="decimal">2.614</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.92</td>
+<td class="decimal">3.89</td>
+<td class="decimal">0.292</td>
+<td>4</td>
+</tr>
+<tr><td>-noise 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.96</td>
+<td class="decimal">3.96</td>
+<td class="decimal">0.107</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Add 2%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.41</td>
+<td class="decimal">1.69</td>
+<td class="decimal">1.84</td>
+<td class="decimal">7.388</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Divide 2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.50</td>
+<td class="decimal">1.78</td>
+<td class="decimal">1.99</td>
+<td class="decimal">6.903</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Multiply 0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.43</td>
+<td class="decimal">1.75</td>
+<td class="decimal">1.94</td>
+<td class="decimal">7.077</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Subtract 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.47</td>
+<td class="decimal">1.70</td>
+<td class="decimal">1.86</td>
+<td class="decimal">7.239</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Gaussian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.99</td>
+<td class="decimal">2.96</td>
+<td class="decimal">3.89</td>
+<td class="decimal">0.521</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Impulse 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.66</td>
+<td class="decimal">2.18</td>
+<td class="decimal">2.59</td>
+<td class="decimal">4.603</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Laplacian 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.78</td>
+<td class="decimal">3.57</td>
+<td class="decimal">1.460</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Multiplicative 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.86</td>
+<td class="decimal">3.73</td>
+<td class="decimal">0.910</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Poisson 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.95</td>
+<td class="decimal">2.88</td>
+<td class="decimal">3.76</td>
+<td class="decimal">0.846</td>
+<td>4</td>
+</tr>
+<tr><td>-operator all Noise-Uniform 30%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">2.23</td>
+<td class="decimal">2.66</td>
+<td class="decimal">4.587</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 2x2</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.21</td>
+<td class="decimal">1.25</td>
+<td class="decimal">6.655</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.24</td>
+<td class="decimal">1.25</td>
+<td class="decimal">1.32</td>
+<td class="decimal">6.942</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither intensity 3x3</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.27</td>
+<td class="decimal">6.768</td>
+<td>4</td>
+</tr>
+<tr><td>-ordered-dither all 4x4</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.20</td>
+<td class="decimal">1.21</td>
+<td class="decimal">1.26</td>
+<td class="decimal">6.693</td>
+<td>4</td>
+</tr>
+<tr><td>-paint 0x1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.86</td>
+<td class="decimal">2.63</td>
+<td class="decimal">3.31</td>
+<td class="decimal">1.867</td>
+<td>4</td>
+</tr>
+<tr><td>-random-threshold all 20x80</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.35</td>
+<td class="decimal">1.46</td>
+<td class="decimal">1.55</td>
+<td class="decimal">6.865</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '0,0,1,0,1,0,1,0,0'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">2.13</td>
+<td class="decimal">2.45</td>
+<td class="decimal">5.251</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '0.9,0,0,0,0.9,0,0,0,1.2'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.55</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.25</td>
+<td class="decimal">6.084</td>
+<td>4</td>
+</tr>
+<tr><td>-recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07'</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.24</td>
+<td class="decimal">6.090</td>
+<td>4</td>
+</tr>
+<tr><td>-density 75x75 -resample 50x50</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">2.49</td>
+<td class="decimal">3.15</td>
+<td class="decimal">2.009</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 10%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.46</td>
+<td class="decimal">2.94</td>
+<td class="decimal">3.286</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 50%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.82</td>
+<td class="decimal">2.52</td>
+<td class="decimal">3.05</td>
+<td class="decimal">2.349</td>
+<td>4</td>
+</tr>
+<tr><td>-resize 150%</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.81</td>
+<td class="decimal">2.42</td>
+<td class="decimal">2.93</td>
+<td class="decimal">0.986</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 15</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.52</td>
+<td class="decimal">2.13</td>
+<td class="decimal">2.49</td>
+<td class="decimal">0.858</td>
+<td>4</td>
+</tr>
+<tr><td>-rotate 45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.68</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.37</td>
+<td class="decimal">0.519</td>
+<td>4</td>
+</tr>
+<tr><td>-shade 30x30</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.64</td>
+<td class="decimal">2.12</td>
+<td class="decimal">2.49</td>
+<td class="decimal">4.081</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x0.5</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.88</td>
+<td class="decimal">2.74</td>
+<td class="decimal">3.54</td>
+<td class="decimal">1.289</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x1.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.97</td>
+<td class="decimal">2.92</td>
+<td class="decimal">3.84</td>
+<td class="decimal">0.457</td>
+<td>4</td>
+</tr>
+<tr><td>-sharpen 0x2.0</td>
+<td class="decimal">1.00</td>
+<td class="decimal">2.00</td>
+<td class="decimal">2.97</td>
+<td class="decimal">3.94</td>
+<td class="decimal">0.134</td>
+<td>4</td>
+</tr>
+<tr><td>-shear 45x45</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.16</td>
+<td class="decimal">1.43</td>
+<td class="decimal">1.63</td>
+<td class="decimal">0.460</td>
+<td>4</td>
+</tr>
+<tr><td>-swirl 90</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.92</td>
+<td class="decimal">2.73</td>
+<td class="decimal">3.50</td>
+<td class="decimal">1.448</td>
+<td>4</td>
+</tr>
+<tr><td>-fuzz 5% -trim</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.63</td>
+<td class="decimal">2.04</td>
+<td class="decimal">2.37</td>
+<td class="decimal">5.900</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x0.5+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.59</td>
+<td class="decimal">1.98</td>
+<td class="decimal">2.23</td>
+<td class="decimal">1.110</td>
+<td>4</td>
+</tr>
+<tr><td>-unsharp 0x1.0+20+1</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.70</td>
+<td class="decimal">2.22</td>
+<td class="decimal">2.57</td>
+<td class="decimal">0.881</td>
+<td>4</td>
+</tr>
+<tr><td>-wave 25x150</td>
+<td class="decimal">1.00</td>
+<td class="decimal">1.84</td>
+<td class="decimal">2.60</td>
+<td class="decimal">3.27</td>
+<td class="decimal">1.918</td>
+<td>4</td>
+</tr>
+</tbody>
+</table>
+<hr class="docutils" />
+<div class="line-block">
+<div class="line">Copyright (C) 2008 - 2017 GraphicsMagick Group</div>
+</div>
+<p>This program is covered by multiple licenses, which are described in
+Copyright.txt. You should have received a copy of Copyright.txt with this
+package; otherwise see <a class="reference external" href="http://www.graphicsmagick.org/Copyright.html">http://www.graphicsmagick.org/Copyright.html</a>.</p>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/OpenMP.rst b/www/OpenMP.rst
new file mode 100644
index 0000000..1f03cec
--- /dev/null
+++ b/www/OpenMP.rst
@@ -0,0 +1,1490 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+.. _`Amdahl's law` : http://en.wikipedia.org/wiki/Amdahl%27s_law
+.. _`GOMP` : http://gcc.gnu.org/onlinedocs/libgomp/
+.. _`OpenMP` : http://openmp.org/
+.. _`Open64` : http://www.open64.net/home.html
+.. _'MinGW-w64' : http://mingw-w64.sourceforge.net/
+
+========================
+OpenMP in GraphicsMagick
+========================
+
+.. contents::
+ :local:
+
+Overview
+========
+
+GraphicsMagick has been transformed to use OpenMP_ for the 1.3 release
+series. OpenMP is a portable framework for accelerating CPU-bound and
+memory-bound operations using multiple threads. OpenMP originates in
+the super-computing world and has been available in one form or
+another since the late '90s.
+
+Since GCC 4.2 has introduced excellent OpenMP support via GOMP_,
+OpenMP has become available to the masses. Microsoft Visual Studio
+Professional 2005 and later support OpenMP so Windows users can
+benefit as well. Any multi-CPU and/or multi-core system is potentially
+a good candidate for use with OpenMP. Unfortunately, some older
+multi-CPU hardware is more suitable for multi-processing than
+multi-threading. Modern multi-core chipsets from AMD, Intel and
+Sun/Oracle perform very well with OpenMP.
+
+Most image processing routines are comprised of loops which iterate
+through the image pixels, image rows, or image regions. These loops are
+accelerated using OpenMP by executing portions of the total loops in
+different threads, and therefore on a different processor core. CPU-bound
+algorithms benefit most from OpenMP, but memory-bound algorithms may also
+benefit as well since the memory is accessed by different CPU cores, and
+sometimes the CPUs have their own path to memory. For example, the AMD
+Opteron is a NUMA (Non-Uniform Memory Architecture) design such that
+multi-CPU systems split the system memory across CPUs so each CPU adds
+more memory bandwidth as well.
+
+For severely CPU-bound algorithms, it is not uncommon to see a linear
+speed-up (within the constraints of `Amdahl's law`_) due to the number
+of cores. For example, a two core system executes the algorithm twice
+as fast, and a four core system executes the algorithm four times as
+fast. Memory-bound algorithms scale based on the memory bandwith
+available to the cores. For example, memory-bound algorithms scale up
+to almost 1.5X on my four core Opteron system due to its NUMA
+architecture. Some systems/CPUs are able to immediately context switch
+to another thread if the core would be blocked waiting for memory,
+allowing multiple memory accesses to be pending at once, and thereby
+improving throughput. For example, typical speedup of 20-32X (average
+24X) has been observed on the Sun SPARC T2 CPU, which provides 8
+cores, with 8 virtual CPUs per core (64 threads).
+
+An approach used in GraphicsMagick is to recognize the various access
+patterns in the existing code, and re-write the algorithms (sometimes
+from scratch) to be based on a framework that we call "pixel iterators".
+With this approach, the computation is restricted to a small unit (a
+callback function) with very well defined properties, and no knowledge as
+to how it is executed or where the data comes from. This approach removes
+the loops from the code and puts the loops in the framework, which may be
+adjusted based on experience. The continuing strategy will be to
+recognize design patterns and build frameworks which support those
+patterns. Sometimes algorithms are special/exotic enough that it is much
+easier to instrument the code for OpenMP rather than to attempt to fit
+the algorithm into a framework.
+
+Since OpenMP is based on multi-threading, multiple threads access the
+underlying pixel storage at once. The interface to this underlying
+storage is called the "pixel cache". The original pixel cache code
+(derived from ImageMagick) was thread safe only to the extent that it
+allowed one thread per image. This code has now been re-written so that
+multiple threads may safely and efficiently work on the pixels in one
+image. The re-write also makes the pixel cache thread safe if a
+multi-threaded application uses an OpenMP-fortified library.
+
+The following is an example of per-core speed-up due to OpenMP on a
+four-core system. All the pixel quantum values have 30% gaussian
+noise added::
+
+ % gm benchmark -stepthreads 1 -duration 10 convert \
+ -size 2048x1080 pattern:granite -operator all Noise-Gaussian 30% null:
+ Results: 1 threads 5 iter 11.07s user 11.07s total 0.452 iter/s (0.452 iter/s cpu) 1.00 speedup 1.000 karp-flatt
+ Results: 2 threads 10 iter 22.16s user 11.11s total 0.900 iter/s (0.451 iter/s cpu) 1.99 speedup 0.004 karp-flatt
+ Results: 3 threads 14 iter 31.06s user 10.47s total 1.337 iter/s (0.451 iter/s cpu) 2.96 speedup 0.007 karp-flatt
+ Results: 4 threads 18 iter 40.01s user 10.24s total 1.758 iter/s (0.450 iter/s cpu) 3.89 speedup 0.009 karp-flatt
+
+Note that the "iter/s cpu" value is a measure of the number of
+iterations given the amount of reported CPU time consumed. It is an
+effective measure of relative efficacy since its value should ideally
+not drop as iterations are added. The karp-flatt ratio is another
+useful metric for evaluating thread-speedup efficiency. In the above
+example, the total speedup was about 3.9X with only a slight loss of
+CPU efficiency as threads are added.
+
+According to the OpenMP specification, the OMP_NUM_THREADS evironment
+variable may be used to specify the number of threads available to the
+application. Typically this is set to the number of processor cores on
+the system but may be set lower to limit resource consumption or (in
+some cases) to improve execution efficiency. The GraphicsMagick
+commands also accept a ``-limit threads limit`` type option for
+specifying the maximum number of threads to use.
+
+Results
+=======
+
+A simple scheme was developed in order to evaluate the performance
+boost with varying numbers of threads. GraphicsMagick's built-in
+benchmark facility is used. The selected algorithm is executed
+repeatedly until a specified amount of time has elapsed. The input
+image is generated on the fly by tiling a small image over a large
+area using a specification like `-size 4000x3000 tile:model.pnm`. It
+is important to note that the time to generate the input image is
+included in the benchmark timings so that even if an algorithm
+achieves perfect linear scaling, the measured difference is likely to
+be less than the number of cores used and the impact could be
+substantial if image generation is slow. Many modern CPUs increase
+the core frequency substantially ("turbo mode") when only a few cores
+are being used and this unfairly penalizes the calculated per-thread
+speedup results which are based on the time to run with just one
+thread.
+
+A typical benchmark command using the built-in benchmark facility
+(-stepthreads requires GraphicsMagick 1.3.13 or later) looks like::
+
+ gm benchmark -stepthreads 1 -duration 5 convert \
+ -size 4000x3000 tile:model.pnm -median 2 null:
+
+The first test executed is `-noop` since it does no work other than
+to generate the input image. This represents how fast it is possible
+to go based on how fast the input image may be generated.
+
+OpenIndiana oi_151a7 / Intel Xeon E5-2680 2.70GHz / GCC 4.7.1 x86-64
+--------------------------------------------------------------------
+
+.. Last update: Sat Feb 16 15:53:21 CST 2013
+
+The following results were obtained from an Intel Xeon E5-2680 at
+2.70GHz. This CPU has 16 cores and 32 threads. GCC 4.7.1 was used to
+build the software. Please note that this CPU has a turbo-boost
+feature which clocks the CPU at 3.9GHz when only a few cores are
+active so the calculated speedup (based on performance with one
+thread) is reported at considerably less (e.g 60% less) than it would
+be based on all cores active:
+
+.. table:: Performance Boost On 16 core Intel Xeon E5-2680 CPU:
+
+ ============================================== ===== ===== ===== ===== ===== ===== ===== ===== ===== ======== ====
+ Operation 1 4 8 12 16 20 24 25 32 iter/s thds
+ ============================================== ===== ===== ===== ===== ===== ===== ===== ===== ===== ======== ====
+ -affine 1,0,0.785,1,0,0 -transform 1.00 3.76 6.50 8.76 10.62 10.68 12.23 13.61 15.00 6.496 9
+ -blur 0x0.5 1.00 2.13 2.58 2.82 2.67 2.75 2.85 2.91 2.94 7.186 9
+ -blur 0x1.0 1.00 2.47 3.12 3.64 3.33 3.57 3.69 3.79 3.87 6.587 9
+ -blur 0x2.0 1.00 2.98 4.29 5.02 4.63 5.00 5.27 5.50 5.71 5.416 9
+ -charcoal 0x1 1.00 2.64 3.48 3.90 3.72 3.85 4.00 4.07 4.09 3.435 9
+ -colorspace GRAY 1.00 2.91 4.08 4.77 4.46 3.67 3.73 3.63 3.50 41.800 4
+ -colorspace HSL 1.00 3.59 6.24 8.27 9.10 7.23 8.12 9.06 9.05 18.200 5
+ -colorspace HWB 1.00 3.51 5.59 7.37 5.86 6.49 7.07 7.82 7.57 24.303 8
+ -colorspace OHTA 1.00 2.77 3.72 4.24 4.39 3.75 3.74 3.68 3.81 37.800 5
+ -colorspace YCbCr 1.00 2.74 3.68 4.01 3.36 3.86 3.84 3.81 3.57 34.263 4
+ -colorspace YIQ 1.00 2.82 3.83 4.31 3.78 3.82 4.00 3.78 3.74 36.200 4
+ -colorspace YUV 1.00 2.67 3.97 4.24 4.01 3.60 4.05 3.86 3.69 35.657 4
+ -contrast -contrast -contrast 1.00 3.93 7.18 10.52 12.85 13.94 16.18 17.63 19.09 4.239 9
+ +contrast +contrast +contrast 1.00 3.96 7.19 10.54 13.38 14.19 16.09 17.56 18.37 4.078 9
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 3.54 5.93 7.92 9.27 9.01 9.36 9.44 9.55 25.697 9
+ -despeckle 1.00 3.09 4.81 5.45 5.87 5.89 5.93 5.86 5.66 3.605 7
+ -edge 0x1 1.00 3.56 5.88 7.82 9.31 8.91 9.18 9.48 9.45 26.243 8
+ -emboss 0x1 1.00 3.35 5.23 6.65 7.43 7.73 7.97 8.24 8.53 8.858 9
+ -enhance 1.00 3.96 7.18 10.61 12.83 11.58 12.49 13.27 14.07 3.448 9
+ -gaussian 0x0.5 1.00 3.70 6.64 9.49 11.44 11.73 12.63 13.45 14.23 16.168 9
+ -gaussian 0x1.0 1.00 3.92 7.07 10.12 12.00 13.70 14.98 16.50 18.01 6.809 9
+ -gaussian 0x2.0 1.00 3.98 7.26 10.79 12.57 14.19 15.91 17.95 19.60 2.136 9
+ -hald-clut identity:8 1.00 3.76 6.49 9.03 11.20 9.85 10.39 10.62 10.53 16.501 5
+ -hald-clut identity:10 1.00 3.74 6.50 9.07 10.68 9.78 11.05 11.48 11.88 17.600 9
+ -hald-clut identity:14 1.00 3.75 6.47 9.19 10.95 9.63 10.63 11.21 11.18 14.970 8
+ -implode 0.5 1.00 3.93 7.07 10.42 12.80 13.83 16.23 18.33 20.46 5.523 9
+ -implode -1 1.00 3.90 7.05 10.39 12.00 13.41 15.21 17.51 19.61 6.433 9
+ -lat 10x10-5% 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.692 3
+ -median 1 1.00 3.89 6.92 10.29 12.43 11.67 13.34 15.28 16.84 2.004 9
+ -median 2 1.00 3.77 6.90 10.26 10.85 12.79 14.49 16.79 18.54 0.723 9
+ -minify 1.00 3.46 5.56 7.30 8.27 8.72 9.00 8.82 8.68 33.600 7
+ -modulate 110/100/95 1.00 3.72 6.47 8.66 10.12 8.89 10.24 11.31 11.14 15.706 8
+ -motion-blur 0x3+30 1.00 1.72 1.45 1.48 1.56 1.57 1.63 1.62 1.68 0.376 2
+ +noise Uniform 1.00 2.90 4.08 4.75 4.31 4.59 4.83 5.07 5.23 14.286 9
+ +noise Gaussian 1.00 3.91 7.04 9.88 11.53 14.10 16.69 19.02 21.41 2.462 9
+ +noise Multiplicative 1.00 3.88 6.93 10.08 11.99 13.55 15.88 18.07 20.19 3.675 9
+ +noise Impulse 1.00 2.99 4.23 5.04 4.63 5.02 5.36 5.63 5.85 14.427 9
+ +noise Laplacian 1.00 3.80 6.64 9.32 11.60 12.30 14.03 15.69 17.40 5.917 9
+ +noise Poisson 1.00 3.87 6.85 9.86 11.97 13.35 15.51 17.48 19.42 4.582 9
+ +noise Random 1.00 3.21 4.82 5.44 5.38 5.88 6.36 6.74 7.11 12.948 9
+ -noise 1 1.00 3.90 6.96 10.03 12.31 11.52 13.19 15.22 16.81 1.984 9
+ -noise 2 1.00 3.90 6.95 10.15 11.64 12.82 14.36 16.64 18.51 0.722 9
+ -operator all Add 2% 1.00 2.63 3.58 3.82 3.14 3.16 3.14 3.21 3.06 47.000 4
+ -operator all Divide 2 1.00 2.71 3.70 4.69 4.02 4.20 4.28 4.19 4.54 37.400 4
+ -operator all Multiply 0.5 1.00 2.39 3.00 3.15 3.21 3.23 3.16 3.07 2.93 39.521 6
+ -operator all Subtract 10% 1.00 2.48 3.09 3.26 3.21 3.40 3.31 3.22 3.05 40.519 6
+ -operator all Noise-Gaussian 30% 1.00 3.99 7.27 10.81 12.16 14.98 17.81 20.17 23.13 2.637 9
+ -operator all Noise-Impulse 30% 1.00 3.57 6.00 7.98 8.32 7.48 8.11 8.56 8.77 23.400 9
+ -operator all Noise-Laplacian 30% 1.00 3.92 7.06 10.36 13.32 13.81 16.09 18.24 19.57 6.733 9
+ -operator all Noise-Multiplicative 30% 1.00 3.96 7.20 10.63 13.40 14.49 17.11 19.93 22.50 4.118 9
+ -operator all Noise-Poisson 30% 1.00 3.94 7.14 10.51 13.07 14.56 17.02 19.79 22.00 5.325 9
+ -operator all Noise-Uniform 30% 1.00 3.57 5.78 7.55 7.92 6.65 7.32 7.56 7.41 23.658 5
+ -ordered-dither all 2x2 1.00 3.01 4.25 4.95 5.04 5.28 5.32 5.05 4.84 37.649 7
+ -ordered-dither all 3x3 1.00 3.00 4.27 4.88 4.74 5.44 5.46 5.27 5.07 37.600 7
+ -ordered-dither intensity 3x3 1.00 2.86 4.33 5.03 4.83 5.03 5.52 5.29 4.96 38.048 7
+ -ordered-dither all 4x4 1.00 2.89 4.11 5.22 5.46 5.09 5.02 5.48 4.99 37.924 8
+ -paint 0x1 1.00 3.72 6.37 9.20 11.02 9.32 10.39 11.41 12.51 15.415 9
+ -random-threshold all 20x80 1.00 2.71 3.50 3.64 3.71 3.35 3.32 3.22 3.24 41.916 5
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 2.94 4.06 4.57 3.95 4.79 5.05 5.02 4.86 31.800 7
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 3.21 4.51 4.99 4.83 4.68 5.48 5.70 5.81 30.938 9
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 3.09 4.57 5.16 4.98 4.70 5.27 5.81 5.35 31.000 8
+ -density 75x75 -resample 50x50 1.00 3.60 6.10 8.71 10.39 10.02 10.43 11.06 10.85 18.000 8
+ -resize 10% 1.00 3.35 5.38 6.78 7.28 6.94 6.83 6.80 7.03 25.050 5
+ -resize 50% 1.00 3.60 5.89 7.79 9.64 9.20 9.49 9.61 9.62 21.756 5
+ -resize 150% 1.00 4.03 7.13 10.06 12.30 11.74 12.21 12.52 10.46 8.203 8
+ -rotate 15 1.00 3.33 5.50 7.13 8.14 8.70 9.15 9.65 9.86 4.960 9
+ -rotate 45 1.00 3.44 5.42 6.99 7.95 8.42 8.81 9.06 9.26 2.103 9
+ -shade 30x30 1.00 3.43 5.46 7.17 6.99 6.47 6.90 7.12 7.09 24.551 4
+ -sharpen 0x0.5 1.00 3.63 6.56 9.24 10.87 11.70 12.60 13.62 14.29 16.238 9
+ -sharpen 0x1.0 1.00 3.83 7.09 10.40 13.24 13.52 15.05 16.48 17.93 6.759 9
+ -sharpen 0x2.0 1.00 3.98 7.26 10.77 13.44 14.56 16.13 17.78 19.63 2.140 9
+ -shear 45x45 1.00 3.02 4.78 5.94 6.63 6.91 7.09 7.29 7.42 3.036 9
+ -swirl 90 1.00 3.87 7.01 10.29 12.22 12.93 14.80 17.04 17.45 6.667 9
+ -fuzz 5% -trim 1.00 2.34 2.50 2.55 2.77 3.13 3.19 3.47 4.06 21.074 9
+ -unsharp 0x0.5+20+1 1.00 2.37 2.98 3.36 3.19 3.31 3.40 3.47 3.52 6.574 9
+ -unsharp 0x1.0+20+1 1.00 2.65 3.47 3.95 4.24 3.93 4.12 4.26 4.28 6.000 9
+ -wave 25x150 1.00 2.33 3.55 4.29 4.72 4.49 4.37 4.59 4.52 1.988 5
+ ============================================== ===== ===== ===== ===== ===== ===== ===== ===== ===== ======== ====
+
+
+Ubuntu Linux 11.10 / Intel Xeon E5649 / Open64 Compiler
+--------------------------------------------------------
+
+.. Last update: Wed Jan 18 22:04:57 CST 2012
+
+The following results were obtained from an Intel Xeon E5649 CPU at
+2.53GHz. This CPU has 12 cores and 24 threads. The free open source
+`Open64`_ 5.0 compiler was used to build the software. The `Open64`_
+compiler produces very high performance code which exceeds GCC
+performance in most cases, and often quite dramatically so:
+
+.. table:: Performance Boost On 12 core Intel Xeon E5649 CPU:
+
+ ===================================================================== ===== ===== ===== ===== ===== ===== ===== ========
+ Operation 1 4 8 12 16 20 24 iter/s
+ ===================================================================== ===== ===== ===== ===== ===== ===== ===== ========
+ -noop 1.00 1.31 1.41 1.35 1.44 1.46 1.43 82.635
+ -affine 1,0,0.785,1,0,0 -transform 1.00 2.74 5.59 5.35 5.78 5.95 7.56 4.175
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 2.03 2.50 2.58 2.83 2.86 2.89 39.641
+ -blur 0x0.5 1.00 3.15 4.35 5.05 4.94 5.22 5.30 5.631
+ -blur 0x1.0 1.00 3.35 5.17 6.14 5.79 6.32 6.63 4.873
+ -blur 0x2.0 1.00 3.54 5.90 7.48 6.90 7.84 8.56 3.937
+ -charcoal 0x1 1.00 2.97 4.26 5.04 4.72 5.15 5.51 2.303
+ -colorspace CMYK 1.00 2.25 2.72 2.60 2.85 2.81 2.76 40.319
+ -colorspace GRAY 1.00 3.07 4.67 5.69 5.69 6.31 6.90 33.600
+ -colorspace HSL 1.00 3.71 6.71 9.20 7.66 9.07 10.41 14.343
+ -colorspace HWB 1.00 3.59 6.13 8.09 6.65 7.80 8.82 19.960
+ -colorspace OHTA 1.00 3.08 4.66 5.72 5.69 6.22 6.85 33.267
+ -colorspace YCbCr 1.00 3.07 4.56 5.72 5.70 6.21 6.92 33.665
+ -colorspace YIQ 1.00 3.08 4.65 5.72 5.72 6.27 6.95 33.800
+ -colorspace YUV 1.00 3.03 4.68 5.60 5.47 6.29 6.95 33.800
+ -contrast -contrast -contrast 1.00 3.70 7.15 10.51 9.69 11.90 13.65 4.150
+ +contrast +contrast +contrast 1.00 3.69 7.13 10.42 9.41 11.49 13.38 4.348
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 3.21 5.48 7.22 6.10 6.83 7.76 13.861
+ -colorize 30%/20%/50% 1.00 3.52 6.00 7.68 6.48 7.64 8.46 23.000
+ -despeckle 1.00 2.67 3.33 4.09 4.14 4.27 4.65 1.359
+ -edge 0x1 1.00 3.46 5.74 7.97 7.33 8.46 9.36 13.000
+ -emboss 0x1 1.00 3.26 4.87 6.02 4.75 5.46 5.90 4.615
+ -enhance 1.00 3.55 7.00 10.30 7.83 9.73 11.39 1.731
+ -gaussian 0x0.5 1.00 3.58 6.31 8.60 6.20 7.20 8.23 7.570
+ -gaussian 0x1.0 1.00 3.61 6.79 9.73 5.94 7.48 8.73 3.220
+ -gaussian 0x2.0 1.00 3.57 6.81 9.79 5.55 6.89 8.22 1.077
+ -hald-clut identity:8 1.00 3.70 6.81 9.44 8.58 10.32 11.62 13.412
+ -hald-clut identity:10 1.00 3.73 6.80 9.31 8.42 10.20 11.52 13.439
+ -hald-clut identity:14 1.00 3.76 6.69 9.42 8.50 10.19 11.66 12.103
+ -implode 0.5 1.00 3.80 7.28 6.16 9.46 11.91 12.17 5.088
+ -implode -1 1.00 3.79 7.29 5.21 8.93 11.33 12.82 7.677
+ -lat 10x10-5% 1.00 3.56 6.24 8.34 7.31 8.72 9.84 4.094
+ -median 1 1.00 2.99 4.41 6.32 7.54 6.38 5.53 0.641
+ -median 2 1.00 3.23 4.20 7.70 8.93 8.00 7.10 0.268
+ -minify 1.00 3.30 4.97 6.36 5.95 6.46 7.12 24.400
+ -modulate 110/100/95 1.00 3.79 6.86 9.62 8.55 10.16 11.63 13.147
+ +noise Uniform 1.00 3.29 5.24 6.40 6.73 7.23 7.74 13.690
+ +noise Gaussian 1.00 3.51 6.91 10.01 9.49 11.56 13.34 2.308
+ +noise Multiplicative 1.00 3.56 6.92 10.00 11.08 13.47 15.35 3.393
+ +noise Impulse 1.00 3.24 5.05 6.22 5.73 6.25 6.75 12.525
+ +noise Laplacian 1.00 3.65 6.90 9.80 10.03 11.93 13.53 4.762
+ +noise Poisson 1.00 3.67 6.91 9.78 10.24 12.07 13.74 4.960
+ -noise 1 1.00 3.06 3.40 6.48 7.08 6.79 8.25 0.701
+ -noise 2 1.00 3.23 5.30 7.80 8.73 8.63 10.03 0.301
+ -fill blue -fuzz 35% -opaque red 1.00 2.60 3.45 3.93 4.43 4.59 4.69 50.000
+ -operator all Add 2% 1.00 3.21 4.71 5.73 7.13 7.75 7.92 41.118
+ -operator all And 233 1.00 1.87 2.12 2.07 2.25 2.21 2.17 44.821
+ -operator all Assign 50% 1.00 1.48 1.62 1.53 1.66 1.59 1.31 44.910
+ -operator all Depth 6 1.00 2.34 2.95 2.98 3.17 3.08 2.54 42.400
+ -operator all Divide 2 1.00 3.16 4.85 5.98 7.39 8.25 8.46 40.200
+ -operator all Gamma 0.7 1.00 1.95 2.11 2.13 2.29 2.21 2.17 30.279
+ -operator all Negate 1.0 1.00 1.49 1.62 1.42 1.40 1.38 1.33 43.114
+ -operator all LShift 2 1.00 1.89 2.42 2.34 2.55 2.18 2.01 44.800
+ -operator all Multiply 0.5 1.00 3.24 4.94 6.28 7.72 8.84 8.89 39.400
+ -operator all Or 233 1.00 1.90 2.03 2.02 2.55 2.52 2.20 44.800
+ -operator all RShift 2 1.00 1.89 2.03 1.93 2.25 2.51 2.46 44.311
+ -operator all Subtract 10% 1.00 2.98 4.27 5.29 6.08 6.75 6.64 40.519
+ -operator red Threshold 50% 1.00 1.43 1.51 1.43 1.86 1.85 1.52 45.020
+ -operator gray Threshold 50% 1.00 1.95 2.10 1.99 2.43 2.61 2.54 44.511
+ -operator all Threshold-White 80% 1.00 2.13 2.60 2.68 3.28 3.36 3.39 52.695
+ -operator all Threshold-Black 10% 1.00 2.07 2.50 2.74 3.26 3.30 3.31 51.497
+ -operator all Xor 233 1.00 1.81 1.94 1.83 1.99 2.32 2.34 43.200
+ -operator all Noise-Gaussian 30% 1.00 3.57 7.06 10.48 9.85 12.11 14.18 2.495
+ -operator all Noise-Impulse 30% 1.00 3.63 6.26 8.52 7.59 8.98 9.91 19.323
+ -operator all Noise-Laplacian 30% 1.00 3.73 7.24 10.53 10.67 13.09 15.17 5.400
+ -operator all Noise-Multiplicative 30% 1.00 3.63 7.15 10.59 11.83 14.61 16.87 3.762
+ -operator all Noise-Poisson 30% 1.00 3.75 7.27 10.70 11.10 13.66 15.89 5.894
+ -operator all Noise-Uniform 30% 1.00 3.64 6.39 8.75 9.50 10.98 12.11 22.465
+ -ordered-dither all 2x2 1.00 3.19 4.65 5.63 6.10 6.71 7.06 36.128
+ -ordered-dither all 3x3 1.00 3.19 4.65 5.58 6.08 6.57 6.93 35.458
+ -ordered-dither intensity 3x3 1.00 3.19 4.76 5.62 6.21 6.84 7.20 36.853
+ -ordered-dither all 4x4 1.00 3.19 4.65 5.54 5.93 6.03 6.06 31.076
+ -paint 0x1 1.00 3.68 6.79 9.19 8.53 10.29 11.53 8.893
+ -random-threshold all 20x80 1.00 2.83 3.96 4.71 5.24 5.18 5.33 38.200
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.32 1.35 1.13 1.22 1.23 1.19 76.248
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 3.25 4.93 6.43 5.86 6.65 7.09 30.600
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 3.37 5.41 7.00 6.53 7.53 8.16 27.745
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 3.43 5.43 6.98 6.46 7.35 8.03 27.745
+ -density 75x75 -resample 50x50 1.00 3.68 6.66 9.16 7.26 7.96 8.36 8.023
+ -resize 10% 1.00 3.31 5.37 6.72 5.78 6.72 6.58 17.460
+ -resize 50% 1.00 3.65 6.34 8.81 6.86 8.14 9.21 12.375
+ -resize 150% 1.00 3.46 5.58 7.34 5.40 5.41 5.28 2.890
+ -rotate 15 1.00 3.26 5.36 7.05 7.34 7.95 8.82 2.724
+ -rotate 45 1.00 2.94 4.55 5.50 5.17 5.21 5.28 0.786
+ -segment 0.5x0.25 1.00 2.00 2.47 2.65 2.59 2.71 2.76 0.047
+ -shade 30x30 1.00 3.30 5.00 6.51 6.62 7.06 8.07 17.659
+ -sharpen 0x0.5 1.00 3.60 6.37 8.65 6.11 7.22 8.29 7.602
+ -sharpen 0x1.0 1.00 3.71 6.73 9.75 5.99 7.39 8.82 3.208
+ -sharpen 0x2.0 1.00 3.61 6.84 9.88 5.61 6.95 8.31 1.077
+ -shear 45x45 1.00 2.82 4.14 4.99 4.34 4.06 4.16 1.213
+ -solarize 50% 1.00 2.12 2.46 2.40 2.65 2.61 2.56 45.200
+ -swirl 90 1.00 3.85 7.22 5.07 9.34 11.86 13.54 8.627
+ -fuzz 35% -transparent red 1.00 2.50 3.19 3.57 3.84 3.77 3.84 43.000
+ -trim 1.00 2.29 2.66 3.17 3.41 3.37 3.53 52.600
+ -fuzz 5% -trim 1.00 3.56 5.92 7.83 7.37 8.71 9.69 23.260
+ -unsharp 0x0.5+20+1 1.00 3.27 4.71 5.64 5.48 5.81 6.14 5.190
+ -unsharp 0x1.0+20+1 1.00 3.42 5.33 6.52 6.19 6.94 7.36 4.600
+ -wave 25x150 1.00 3.79 6.78 8.35 7.67 8.87 10.14 7.859
+ ===================================================================== ===== ===== ===== ===== ===== ===== ===== ========
+
+
+Ubuntu Linux 11.10 / Intel Xeon E5649 / GCC Compiler
+-----------------------------------------------------
+
+.. Last update: Fri Feb 15 08:54:04 CST 2013
+
+The following results were obtained from an Intel Xeon E5649 CPU at
+2.53GHz. This CPU has 12 cores and 24 threads. Ubtuntu's GCC 4.6.1
+compiler was used to build the software:
+
+.. table:: Performance Boost On 12 core Intel Xeon E5649 CPU:
+
+ ============================================== ===== ===== ===== ===== ===== ===== ===== ======== ====
+ Operation 1 4 8 12 16 20 24 iter/s thds
+ ============================================== ===== ===== ===== ===== ===== ===== ===== ======== ====
+ -affine 1,0,0.785,1,0,0 -transform 1.00 2.73 3.59 4.29 5.00 5.33 5.65 3.220 7
+ -blur 0x0.5 1.00 2.54 2.98 3.23 3.47 3.57 3.63 4.200 7
+ -blur 0x1.0 1.00 2.72 3.30 3.89 4.25 4.56 4.57 3.557 7
+ -blur 0x2.0 1.00 2.94 3.94 4.47 5.10 5.74 5.72 2.745 6
+ -charcoal 0x1 1.00 2.69 3.42 4.10 4.46 4.75 4.86 1.761 7
+ -colorspace GRAY 1.00 2.77 3.34 3.68 3.97 4.14 4.15 17.000 7
+ -colorspace HSL 1.00 3.05 4.09 5.44 6.37 6.82 7.46 8.661 7
+ -colorspace HWB 1.00 3.08 3.49 4.52 5.32 6.09 5.97 11.776 6
+ -colorspace OHTA 1.00 2.83 3.09 3.65 3.99 4.11 4.10 16.865 6
+ -colorspace YCbCr 1.00 2.82 3.09 3.73 4.05 4.11 4.18 17.131 7
+ -colorspace YIQ 1.00 2.80 3.33 3.73 4.04 4.10 3.85 16.832 6
+ -colorspace YUV 1.00 2.78 3.33 3.75 4.05 4.14 4.16 17.063 7
+ -contrast -contrast -contrast 1.00 3.67 5.25 5.56 6.60 7.52 8.16 2.457 7
+ +contrast +contrast +contrast 1.00 3.67 5.24 5.58 6.59 7.89 8.16 2.481 7
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 3.16 3.90 5.32 5.94 6.51 6.58 10.600 7
+ -despeckle 1.00 3.20 3.61 3.77 3.82 3.89 3.68 1.156 6
+ -edge 0x1 1.00 3.15 5.15 5.57 6.26 7.01 7.07 9.742 7
+ -emboss 0x1 1.00 3.02 4.24 5.24 5.88 6.52 6.64 4.215 7
+ -enhance 1.00 3.56 4.12 6.23 7.41 9.38 9.04 1.501 6
+ -gaussian 0x0.5 1.00 3.46 4.92 6.65 7.74 8.97 9.21 6.561 7
+ -gaussian 0x1.0 1.00 3.66 5.00 7.53 8.74 9.29 10.30 2.677 7
+ -gaussian 0x2.0 1.00 3.70 5.86 7.39 8.54 9.60 10.49 0.839 7
+ -hald-clut identity:8 1.00 2.97 4.03 5.55 6.50 7.30 7.65 7.540 7
+ -hald-clut identity:10 1.00 2.97 4.36 5.76 6.55 7.59 7.78 7.570 7
+ -hald-clut identity:14 1.00 3.18 4.11 5.39 6.28 7.33 7.40 6.445 7
+ -implode 0.5 1.00 3.30 4.32 5.43 6.74 7.55 8.07 3.187 7
+ -implode -1 1.00 3.04 5.07 5.38 6.47 7.62 7.83 4.348 7
+ -lat 10x10-5% 1.00 1.03 1.03 1.03 1.03 1.02 1.02 1.211 3
+ -median 1 1.00 3.53 4.95 5.80 6.55 6.90 7.62 0.655 7
+ -median 2 1.00 3.68 5.32 5.32 7.35 9.90 9.10 0.307 6
+ -minify 1.00 2.91 3.74 4.67 5.02 5.44 5.28 17.400 6
+ -modulate 110/100/95 1.00 3.18 3.89 5.41 6.40 7.50 7.64 7.255 7
+ -motion-blur 0x3+30 1.00 3.33 3.23 4.67 5.20 5.91 6.78 1.328 7
+ +noise Uniform 1.00 2.22 2.61 3.00 3.21 3.43 3.44 5.871 7
+ +noise Gaussian 1.00 3.39 4.29 5.67 6.63 7.17 8.20 1.230 7
+ +noise Multiplicative 1.00 3.44 4.29 5.41 6.34 7.22 7.78 1.689 7
+ +noise Impulse 1.00 2.31 2.78 3.07 3.35 3.49 3.59 5.765 7
+ +noise Laplacian 1.00 3.42 4.91 5.29 5.99 6.64 7.08 2.534 7
+ +noise Poisson 1.00 3.46 4.93 5.33 6.65 7.12 7.64 2.268 7
+ +noise Random 1.00 2.67 3.14 3.71 4.13 4.33 4.51 5.029 7
+ -noise 1 1.00 3.61 4.99 5.81 7.12 6.77 7.73 0.649 7
+ -noise 2 1.00 3.77 5.70 5.43 7.60 10.10 9.40 0.303 6
+ -operator all Add 2% 1.00 2.97 4.02 4.40 4.84 4.93 4.79 21.956 6
+ -operator all Divide 2 1.00 2.92 3.90 4.99 5.52 5.60 5.56 19.960 6
+ -operator all Multiply 0.5 1.00 2.88 4.43 4.70 5.13 5.25 5.04 20.833 6
+ -operator all Subtract 10% 1.00 2.95 4.01 4.58 4.69 4.87 4.71 21.400 6
+ -operator all Noise-Gaussian 30% 1.00 3.53 4.46 6.01 7.14 7.56 8.86 1.365 7
+ -operator all Noise-Impulse 30% 1.00 3.10 3.62 4.79 5.53 6.32 6.27 11.730 6
+ -operator all Noise-Laplacian 30% 1.00 3.76 4.54 6.01 7.37 8.62 8.95 3.257 7
+ -operator all Noise-Multiplicative 30% 1.00 3.62 4.26 6.14 7.10 7.67 8.98 2.011 7
+ -operator all Noise-Poisson 30% 1.00 3.68 4.36 5.69 7.33 7.64 8.80 2.772 7
+ -operator all Noise-Uniform 30% 1.00 3.18 3.52 4.65 5.34 5.70 6.10 12.079 7
+ -ordered-dither all 2x2 1.00 2.68 3.22 3.69 3.94 4.27 4.10 19.522 6
+ -ordered-dither all 3x3 1.00 2.69 3.21 3.80 4.08 4.10 4.14 18.887 7
+ -ordered-dither intensity 3x3 1.00 2.69 3.22 3.71 4.00 3.90 4.16 18.962 7
+ -ordered-dither all 4x4 1.00 2.69 3.21 3.78 4.01 4.07 4.06 18.563 6
+ -paint 0x1 1.00 3.11 3.82 5.70 6.64 7.20 7.77 5.675 7
+ -random-threshold all 20x80 1.00 2.60 2.85 3.31 3.52 3.54 3.53 20.000 6
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 2.89 3.27 4.14 4.65 4.84 5.04 15.968 7
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 2.98 3.27 4.24 4.83 4.94 5.20 14.200 7
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 2.99 3.35 4.23 4.74 5.38 5.29 14.741 6
+ -density 75x75 -resample 50x50 1.00 3.15 4.28 5.25 5.48 5.37 5.18 5.039 5
+ -resize 10% 1.00 3.15 4.11 4.71 5.32 5.69 5.78 10.651 7
+ -resize 50% 1.00 3.05 3.92 5.00 5.70 6.12 6.08 7.466 6
+ -resize 150% 1.00 3.20 5.15 5.59 6.00 5.64 5.30 2.544 5
+ -rotate 15 1.00 3.27 4.81 6.14 7.29 8.04 8.48 2.662 7
+ -rotate 45 1.00 3.03 4.07 5.29 6.14 6.75 7.12 1.047 7
+ -shade 30x30 1.00 2.92 3.46 4.41 5.02 5.11 5.50 10.516 7
+ -sharpen 0x0.5 1.00 3.37 5.01 6.63 7.76 8.42 9.20 6.535 7
+ -sharpen 0x1.0 1.00 3.68 5.50 6.84 8.47 10.48 10.58 2.750 7
+ -sharpen 0x2.0 1.00 3.65 5.88 7.40 8.65 10.23 11.06 0.896 7
+ -shear 45x45 1.00 2.95 3.79 4.76 5.24 5.55 5.82 1.460 7
+ -swirl 90 1.00 3.13 4.61 5.93 6.80 7.69 8.38 4.297 7
+ -fuzz 5% -trim 1.00 2.99 3.49 4.46 5.04 5.59 5.51 14.343 6
+ -unsharp 0x0.5+20+1 1.00 2.61 3.31 3.67 3.98 4.10 4.18 3.725 7
+ -unsharp 0x1.0+20+1 1.00 2.90 3.61 4.14 4.59 4.96 4.93 3.214 6
+ -wave 25x150 1.00 2.99 3.95 5.05 5.65 6.71 6.91 4.864 7
+ ============================================== ===== ===== ===== ===== ===== ===== ===== ======== ====
+
+
+Ubuntu Linux 11.10 / AMD Opteron 6220 / Open64 Compiler
+--------------------------------------------------------
+
+.. Last update: Wed Dec 21 15:40:08 CST 2011
+
+The following results were obtained using an AMD Opteron 6220 CPU with
+AMD's branch of the Open64 Compiler. This system offered 16
+processing cores with a clock rate of 3GHz. This CPU agressively
+increases its clock rate with just a few threads running. This throws
+off the naive per-thread speedup calculation, which is based on the
+performance with just one thread. In spite of relatively low reported
+per-thread speed-up values, compare total performance with the test
+run using the GCC compiler:
+
+.. table:: Performance Boost On 16 core AMD Opteron 6220 CPU:
+
+ ===================================================================== ===== ===== ===== ===== ===== ======== ====
+ Operation 1 4 8 12 16 iter/s thds
+ ===================================================================== ===== ===== ===== ===== ===== ======== ====
+ -noop 1.00 1.20 1.14 1.10 0.97 55.100 4
+ -affine 1,0,0.785,1,0,0 -transform 1.00 2.07 4.65 5.74 4.81 3.540 15
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 1.93 2.02 2.07 1.88 25.050 12
+ -blur 0x0.5 1.00 2.17 3.12 3.39 3.26 3.674 13
+ -blur 0x1.0 1.00 2.38 3.66 4.21 4.46 3.431 16
+ -blur 0x2.0 1.00 2.24 3.70 4.51 4.93 2.843 16
+ -charcoal 0x1 1.00 2.20 2.88 3.43 3.60 1.488 13
+ -colorspace CMYK 1.00 1.78 1.77 1.75 1.59 24.076 5
+ -colorspace GRAY 1.00 2.40 3.48 4.14 4.18 22.732 15
+ -colorspace HSL 1.00 2.51 4.63 6.33 7.37 13.886 16
+ -colorspace HWB 1.00 3.02 5.11 6.81 8.13 16.617 16
+ -colorspace OHTA 1.00 2.41 3.49 4.16 4.21 22.700 15
+ -colorspace YCbCr 1.00 2.41 3.51 4.17 4.24 22.854 15
+ -colorspace YIQ 1.00 2.39 3.48 4.14 4.18 22.754 15
+ -colorspace YUV 1.00 2.40 3.47 4.14 4.19 22.732 15
+ -contrast -contrast -contrast 1.00 2.98 5.76 8.47 10.76 3.766 16
+ +contrast +contrast +contrast 1.00 2.99 5.74 8.45 10.86 3.953 16
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 2.13 3.66 4.72 5.46 10.568 16
+ -colorize 30%/20%/50% 1.00 1.78 2.84 3.51 3.24 19.522 12
+ -despeckle 1.00 2.33 2.34 2.34 2.34 0.293 12
+ -edge 0x1 1.00 2.35 4.20 5.61 6.32 9.633 16
+ -emboss 0x1 1.00 1.95 3.08 3.70 4.05 3.393 16
+ -enhance 1.00 2.56 5.06 7.51 9.89 1.602 16
+ -gaussian 0x0.5 1.00 2.16 4.06 5.53 6.62 7.065 16
+ -gaussian 0x1.0 1.00 2.31 4.36 6.16 8.32 3.287 16
+ -gaussian 0x2.0 1.00 2.32 4.60 6.69 8.94 1.117 16
+ -hald-clut identity:8 1.00 2.84 5.11 7.02 8.23 12.202 16
+ -hald-clut identity:10 1.00 2.83 5.04 6.97 8.24 11.817 16
+ -hald-clut identity:14 1.00 2.86 5.14 6.87 8.05 10.050 16
+ -implode 0.5 1.00 3.00 5.38 4.62 5.49 2.852 13
+ -implode -1 1.00 2.90 5.49 3.97 4.70 5.556 13
+ -lat 10x10-5% 1.00 2.45 4.44 5.25 6.43 3.370 16
+ -median 1 1.00 3.12 5.36 7.82 9.23 0.849 16
+ -median 2 1.00 3.28 6.21 9.21 12.10 0.351 16
+ -minify 1.00 2.04 3.42 4.34 4.74 16.200 15
+ -modulate 110/100/95 1.00 2.95 5.40 7.29 9.18 11.800 16
+ +noise Uniform 1.00 2.37 3.74 4.49 5.04 10.417 16
+ +noise Gaussian 1.00 3.35 6.53 9.55 12.39 1.722 16
+ +noise Multiplicative 1.00 3.28 6.28 8.92 11.48 2.584 16
+ +noise Impulse 1.00 2.67 4.37 5.50 6.16 9.335 16
+ +noise Laplacian 1.00 3.48 6.55 9.42 11.81 3.366 16
+ +noise Poisson 1.00 3.15 5.97 8.37 10.57 3.785 16
+ -noise 1 1.00 3.13 5.99 7.66 9.85 0.896 16
+ -noise 2 1.00 3.24 6.38 9.10 11.62 0.337 16
+ -fill blue -fuzz 35% -opaque red 1.00 2.05 2.83 3.14 3.18 29.341 16
+ -operator all Add 2% 1.00 2.08 2.75 3.03 2.76 25.375 12
+ -operator all And 233 1.00 1.33 1.28 1.26 1.13 28.072 4
+ -operator all Assign 50% 1.00 1.29 1.23 1.21 1.08 28.044 4
+ -operator all Depth 6 1.00 1.66 1.64 1.60 1.44 27.000 4
+ -operator all Divide 2 1.00 2.03 2.82 3.17 2.95 24.850 12
+ -operator all Gamma 0.7 1.00 1.47 1.36 1.37 1.24 22.455 4
+ -operator all Negate 1.0 1.00 1.34 1.30 1.28 1.15 27.672 4
+ -operator all LShift 2 1.00 1.34 1.29 1.27 1.13 28.000 4
+ -operator all Multiply 0.5 1.00 2.06 2.72 3.00 2.72 25.424 12
+ -operator all Or 233 1.00 1.34 1.28 1.27 1.13 28.100 4
+ -operator all RShift 2 1.00 1.34 1.28 1.27 1.13 28.072 4
+ -operator all Subtract 10% 1.00 2.24 3.09 3.49 3.22 24.850 12
+ -operator red Threshold 50% 1.00 1.22 1.16 1.14 1.02 28.372 4
+ -operator gray Threshold 50% 1.00 1.64 1.60 1.59 1.42 27.246 4
+ -operator all Threshold-White 80% 1.00 1.95 2.06 2.06 1.87 33.500 11
+ -operator all Threshold-Black 10% 1.00 1.94 2.05 2.06 1.85 32.900 9
+ -operator all Xor 233 1.00 1.33 1.28 1.26 1.13 28.144 4
+ -operator all Noise-Gaussian 30% 1.00 3.38 6.65 9.85 12.97 1.829 16
+ -operator all Noise-Impulse 30% 1.00 2.88 5.12 6.94 8.42 13.174 16
+ -operator all Noise-Laplacian 30% 1.00 3.46 6.75 9.79 12.82 3.770 16
+ -operator all Noise-Multiplicative 30% 1.00 3.32 6.49 9.40 12.31 2.794 16
+ -operator all Noise-Poisson 30% 1.00 3.19 6.17 9.01 11.65 4.310 16
+ -operator all Noise-Uniform 30% 1.00 2.55 4.39 5.88 6.97 15.085 16
+ -ordered-dither all 2x2 1.00 2.43 2.97 3.05 2.84 22.832 12
+ -ordered-dither all 3x3 1.00 2.47 3.05 3.14 2.86 23.529 12
+ -ordered-dither intensity 3x3 1.00 2.42 2.96 3.04 2.84 22.877 12
+ -ordered-dither all 4x4 1.00 2.46 3.01 3.11 2.89 23.207 12
+ -paint 0x1 1.00 2.41 4.70 6.53 7.88 5.373 16
+ -random-threshold all 20x80 1.00 2.74 3.57 3.72 3.55 23.177 10
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.21 1.15 1.12 0.98 54.945 4
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 2.91 4.66 5.99 6.21 21.457 16
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 3.19 5.28 6.62 7.54 19.821 16
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 3.12 5.10 6.46 7.54 19.880 16
+ -density 75x75 -resample 50x50 1.00 2.42 4.58 6.33 7.50 7.143 16
+ -resize 10% 1.00 2.51 4.22 5.49 6.23 13.686 16
+ -resize 50% 1.00 2.24 3.98 6.16 7.10 10.558 16
+ -resize 150% 1.00 2.58 4.82 6.56 7.39 2.778 15
+ -rotate 15 1.00 2.43 3.78 4.68 5.17 2.532 16
+ -rotate 45 1.00 1.98 3.01 3.55 3.79 0.856 16
+ -segment 0.5x0.25 1.00 1.86 2.21 2.43 2.50 0.035 14
+ -shade 30x30 1.00 2.86 4.85 6.38 6.93 10.789 15
+ -sharpen 0x0.5 1.00 2.14 4.01 5.46 6.52 6.944 16
+ -sharpen 0x1.0 1.00 2.33 4.37 6.23 8.34 3.284 16
+ -sharpen 0x2.0 1.00 2.33 4.58 6.71 8.96 1.120 16
+ -shear 45x45 1.00 1.97 2.93 3.48 3.72 1.157 16
+ -solarize 50% 1.00 1.82 1.82 1.80 1.63 27.073 9
+ -swirl 90 1.00 3.18 5.52 5.62 7.33 5.627 15
+ -fuzz 35% -transparent red 1.00 2.06 2.72 3.02 2.76 25.449 12
+ -trim 1.00 1.99 2.27 2.45 2.31 32.635 12
+ -fuzz 5% -trim 1.00 2.56 4.59 5.94 7.16 14.428 16
+ -unsharp 0x0.5+20+1 1.00 2.30 3.43 3.87 4.30 3.593 16
+ -unsharp 0x1.0+20+1 1.00 2.32 3.65 4.24 4.57 3.097 16
+ -wave 25x150 1.00 3.01 5.18 6.51 8.31 5.765 16
+ ===================================================================== ===== ===== ===== ===== ===== ======== ====
+
+
+Ubuntu Linux 11.10 / AMD Opteron 6220 / GCC Compiler
+-----------------------------------------------------
+
+.. Last update: Wed Dec 21 15:40:08 CST 2011
+
+The following results were obtained using an AMD Opteron 6220 CPU.
+Ubtuntu's GCC 4.6.1 compiler was used to build the software.
+Ubtuntu's GCC has been found to offer less performance for this CPU
+(and for Intel Xeon) than the Open64 compiler. Compare these results
+with the Open64 results above. This system offers 16 processing cores
+with a clock rate of 3GHz:
+
+.. table:: Performance Boost On 16 core AMD Opteron 6220 CPU:
+
+ ===================================================================== ===== ===== ===== ===== ===== ======== ====
+ Operation 1 4 8 12 16 iter/s thds
+ ===================================================================== ===== ===== ===== ===== ===== ======== ====
+ -noop 1.00 1.97 2.05 1.95 2.07 29.341 7
+ -affine 1,0,0.785,1,0,0 -transform 1.00 3.73 6.65 6.56 6.63 3.868 15
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 2.37 2.97 2.82 3.18 23.752 16
+ -blur 0x0.5 1.00 2.75 3.36 3.55 3.22 3.661 14
+ -blur 0x1.0 1.00 2.89 3.69 4.11 4.07 3.156 15
+ -blur 0x2.0 1.00 3.21 4.54 4.81 4.95 2.569 15
+ -charcoal 0x1 1.00 2.30 3.07 3.32 3.47 1.252 16
+ -colorspace CMYK 1.00 2.03 2.39 2.21 2.36 21.627 8
+ -colorspace GRAY 1.00 2.70 3.82 3.61 4.27 19.721 16
+ -colorspace HSL 1.00 2.92 5.61 5.83 7.24 12.821 16
+ -colorspace HWB 1.00 3.42 5.28 6.30 7.79 13.861 16
+ -colorspace OHTA 1.00 2.81 3.86 3.59 4.14 19.200 16
+ -colorspace YCbCr 1.00 2.83 3.42 3.61 4.14 19.124 16
+ -colorspace YIQ 1.00 2.79 3.86 3.60 4.18 19.323 16
+ -colorspace YUV 1.00 2.83 3.43 3.62 4.24 19.522 16
+ -contrast -contrast -contrast 1.00 3.93 6.78 8.59 11.24 3.360 16
+ +contrast +contrast +contrast 1.00 3.89 7.11 8.65 11.17 3.429 16
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 3.10 5.10 5.65 6.71 10.379 16
+ -colorize 30%/20%/50% 1.00 2.68 3.80 3.49 4.15 14.371 16
+ -despeckle 1.00 2.95 2.88 2.95 2.91 0.271 4
+ -edge 0x1 1.00 3.37 5.61 6.39 7.68 9.182 16
+ -emboss 0x1 1.00 2.85 4.24 4.72 5.17 3.194 16
+ -enhance 1.00 3.73 7.18 8.20 9.45 1.597 16
+ -gaussian 0x0.5 1.00 3.24 6.07 7.01 8.17 6.000 16
+ -gaussian 0x1.0 1.00 3.80 6.83 7.92 8.97 2.358 16
+ -gaussian 0x2.0 1.00 3.94 6.63 8.44 9.69 0.843 16
+ -hald-clut identity:8 1.00 3.11 5.53 5.86 7.56 8.893 16
+ -hald-clut identity:10 1.00 3.67 4.40 5.77 7.57 8.583 16
+ -hald-clut identity:14 1.00 3.60 4.67 6.19 7.80 7.400 16
+ -implode 0.5 1.00 4.08 6.98 9.37 10.09 3.422 16
+ -implode -1 1.00 3.49 6.20 8.38 9.22 4.582 16
+ -lat 10x10-5% 1.00 3.01 4.29 4.72 5.04 1.685 16
+ -median 1 1.00 3.86 6.61 8.01 9.08 0.672 16
+ -median 2 1.00 3.96 7.25 9.54 11.54 0.277 16
+ -minify 1.00 3.01 4.46 4.58 5.17 15.200 16
+ -modulate 110/100/95 1.00 3.50 6.04 6.68 8.60 9.881 16
+ +noise Uniform 1.00 2.00 2.29 2.43 2.53 2.857 15
+ +noise Gaussian 1.00 4.55 7.58 9.16 10.87 1.152 16
+ +noise Multiplicative 1.00 3.74 5.98 7.58 8.95 1.378 16
+ +noise Impulse 1.00 2.10 2.48 2.64 2.79 2.846 16
+ +noise Laplacian 1.00 3.48 5.32 6.32 7.27 1.775 16
+ +noise Poisson 1.00 3.16 4.68 5.74 6.49 1.805 16
+ -noise 1 1.00 3.99 6.85 8.46 9.42 0.678 16
+ -noise 2 1.00 3.96 7.25 9.54 11.54 0.277 16
+ -fill blue -fuzz 35% -opaque red 1.00 2.47 3.10 3.08 3.60 24.303 16
+ -operator all Add 2% 1.00 2.66 3.17 3.27 3.80 21.912 16
+ -operator all And 233 1.00 2.01 2.31 2.12 2.38 24.600 16
+ -operator all Assign 50% 1.00 1.95 2.27 2.05 2.23 24.303 8
+ -operator all Depth 6 1.00 2.08 2.39 2.11 2.32 23.904 8
+ -operator all Divide 2 1.00 2.69 3.31 3.35 3.91 21.357 16
+ -operator all Gamma 0.7 1.00 1.83 2.15 1.94 2.06 20.400 8
+ -operator all Negate 1.0 1.00 2.00 2.36 2.11 2.37 24.600 16
+ -operator all LShift 2 1.00 1.98 2.29 2.08 2.34 24.701 16
+ -operator all Multiply 0.5 1.00 2.65 3.12 3.27 3.90 22.510 16
+ -operator all Or 233 1.00 2.03 2.32 2.15 2.35 24.200 16
+ -operator all RShift 2 1.00 1.98 2.29 2.06 2.25 24.056 8
+ -operator all Subtract 10% 1.00 2.71 3.35 3.58 4.10 20.758 15
+ -operator red Threshold 50% 1.00 1.83 2.16 1.90 2.00 24.600 8
+ -operator gray Threshold 50% 1.00 2.14 2.44 2.27 2.53 24.502 16
+ -operator all Threshold-White 80% 1.00 2.16 2.54 2.36 2.47 24.206 9
+ -operator all Threshold-Black 10% 1.00 2.20 2.63 2.40 2.57 24.254 8
+ -operator all Xor 233 1.00 1.95 2.37 2.13 2.35 24.400 8
+ -operator all Noise-Gaussian 30% 1.00 3.87 6.25 9.03 11.74 1.667 16
+ -operator all Noise-Impulse 30% 1.00 3.47 5.94 6.95 8.46 11.858 16
+ -operator all Noise-Laplacian 30% 1.00 3.89 7.12 9.58 12.26 3.495 16
+ -operator all Noise-Multiplicative 30% 1.00 4.01 7.40 10.12 12.99 2.196 16
+ -operator all Noise-Poisson 30% 1.00 3.88 6.67 8.80 11.34 3.482 16
+ -operator all Noise-Uniform 30% 1.00 3.49 5.22 6.51 8.17 13.069 16
+ -ordered-dither all 2x2 1.00 2.46 3.36 3.23 3.64 20.717 16
+ -ordered-dither all 3x3 1.00 2.51 3.24 3.24 3.67 20.833 16
+ -ordered-dither intensity 3x3 1.00 2.55 3.27 3.26 3.67 20.800 16
+ -ordered-dither all 4x4 1.00 2.53 3.40 3.28 3.70 20.875 16
+ -paint 0x1 1.00 3.60 6.18 6.97 7.99 5.976 16
+ -random-threshold all 20x80 1.00 2.66 3.77 3.86 4.44 20.833 16
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.92 1.95 1.88 1.97 28.486 7
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 2.87 3.98 4.03 5.02 20.800 16
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 3.03 3.96 4.01 4.95 18.725 16
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 3.02 3.59 3.94 4.96 18.812 16
+ -density 75x75 -resample 50x50 1.00 3.46 5.19 4.75 5.01 4.669 8
+ -resize 10% 1.00 3.42 4.51 5.62 6.53 10.609 16
+ -resize 50% 1.00 3.41 4.97 5.56 5.98 7.738 14
+ -resize 150% 1.00 3.50 6.01 6.48 7.37 2.820 15
+ -rotate 15 1.00 2.70 4.31 4.90 5.61 2.703 16
+ -rotate 45 1.00 2.51 3.58 3.94 4.17 0.958 16
+ -segment 0.5x0.25 1.00 1.63 1.79 1.84 1.89 0.036 14
+ -shade 30x30 1.00 3.38 5.44 6.78 8.08 9.722 16
+ -sharpen 0x0.5 1.00 3.12 6.12 7.06 8.28 6.055 16
+ -sharpen 0x1.0 1.00 3.74 6.71 7.83 8.86 2.339 16
+ -sharpen 0x2.0 1.00 3.68 7.10 8.36 9.69 0.843 16
+ -shear 45x45 1.00 2.32 3.29 3.64 3.93 1.308 16
+ -solarize 50% 1.00 2.15 2.48 2.26 2.52 24.351 16
+ -swirl 90 1.00 3.91 5.95 8.09 9.76 4.391 16
+ -fuzz 35% -transparent red 1.00 2.40 3.01 3.00 3.49 24.200 16
+ -trim 1.00 2.27 2.68 2.44 2.55 24.551 8
+ -fuzz 5% -trim 1.00 3.06 5.06 5.79 6.80 13.972 16
+ -unsharp 0x0.5+20+1 1.00 2.78 3.80 4.03 4.27 3.282 16
+ -unsharp 0x1.0+20+1 1.00 3.07 3.86 4.53 4.52 2.953 15
+ -wave 25x150 1.00 3.47 6.10 7.61 8.76 4.902 15
+ ===================================================================== ===== ===== ===== ===== ===== ======== ====
+
+
+Sun Solaris / AMD Opteron
+-------------------------
+
+.. Last update: Wed Dec 21 16:11:28 CST 2011
+
+The following table shows the performance boost in GraphicsMagick
+1.4 as threads are added on a four-core AMD Opteron 3.0GHz system
+running Sun Solaris 10:
+
+.. table:: Performance Boost On Four Core AMD Operon System
+
+ ===================================================================== ===== ===== ===== ===== ======== ====
+ Operation 1 2 3 4 iter/s thds
+ ===================================================================== ===== ===== ===== ===== ======== ====
+ -noop 1.00 1.23 1.22 1.18 32.635 2
+ -affine 1,0,0.785,1,0,0 -transform 1.00 1.78 2.92 3.12 0.971 4
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 1.62 1.94 2.07 12.762 4
+ -blur 0x0.5 1.00 1.74 2.26 2.56 2.284 4
+ -blur 0x1.0 1.00 1.84 2.47 2.99 1.777 4
+ -blur 0x2.0 1.00 1.89 2.63 3.22 1.386 4
+ -charcoal 0x1 1.00 1.85 2.56 3.08 0.763 4
+ -colorspace CMYK 1.00 1.39 1.53 1.49 13.772 3
+ -colorspace GRAY 1.00 1.80 2.38 2.84 9.690 4
+ -colorspace HSL 1.00 1.96 2.85 3.59 2.991 4
+ -colorspace HWB 1.00 1.94 2.77 3.46 4.469 4
+ -colorspace OHTA 1.00 1.81 2.44 2.93 9.980 4
+ -colorspace YCbCr 1.00 1.81 2.44 2.88 9.800 4
+ -colorspace YIQ 1.00 1.81 2.43 2.85 9.652 4
+ -colorspace YUV 1.00 1.81 2.44 2.92 9.930 4
+ -contrast -contrast -contrast 1.00 2.00 2.94 3.88 0.539 4
+ +contrast +contrast +contrast 1.00 1.99 2.93 3.86 0.591 4
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 1.92 2.73 3.45 3.689 4
+ -colorize 30%/20%/50% 1.00 1.85 2.50 3.04 8.111 4
+ -despeckle 1.00 1.51 2.84 2.85 0.254 4
+ -edge 0x1 1.00 1.97 2.87 3.68 2.000 4
+ -emboss 0x1 1.00 1.86 2.56 3.15 1.536 4
+ -enhance 1.00 2.02 3.01 3.95 0.411 4
+ -gaussian 0x0.5 1.00 1.97 2.84 3.67 2.109 4
+ -gaussian 0x1.0 1.00 2.01 2.96 3.86 0.725 4
+ -gaussian 0x2.0 1.00 2.02 3.00 3.95 0.253 4
+ -hald-clut identity:8 1.00 1.99 2.91 3.72 2.178 4
+ -hald-clut identity:10 1.00 1.98 2.87 3.71 2.240 4
+ -hald-clut identity:14 1.00 1.97 2.90 3.67 2.006 4
+ -implode 0.5 1.00 1.90 2.88 3.64 0.880 4
+ -implode -1 1.00 1.89 2.68 3.54 1.074 4
+ -lat 10x10-5% 1.00 1.99 2.91 3.75 1.015 4
+ -median 1 1.00 2.03 3.01 3.96 0.277 4
+ -median 2 1.00 1.96 2.93 3.89 0.105 4
+ -minify 1.00 1.83 2.50 3.08 7.662 4
+ -modulate 110/100/95 1.00 1.98 2.89 3.71 2.367 4
+ +noise Uniform 1.00 1.90 2.64 3.35 2.616 4
+ +noise Gaussian 1.00 2.04 3.01 3.98 0.322 4
+ +noise Multiplicative 1.00 2.01 2.97 3.87 0.518 4
+ +noise Impulse 1.00 1.90 2.66 3.36 2.449 4
+ +noise Laplacian 1.00 1.98 2.86 3.68 1.093 4
+ +noise Poisson 1.00 1.99 2.94 3.78 0.836 4
+ -noise 1 1.00 2.01 2.96 3.91 0.270 4
+ -noise 2 1.00 2.04 3.00 3.96 0.103 4
+ -fill blue -fuzz 35% -opaque red 1.00 1.68 2.16 2.42 14.612 4
+ -operator all Add 2% 1.00 1.81 2.43 2.90 10.689 4
+ -operator all And 233 1.00 1.16 1.25 1.19 15.584 3
+ -operator all Assign 50% 1.00 1.15 1.24 1.19 16.235 3
+ -operator all Depth 6 1.00 1.57 1.89 1.93 14.741 4
+ -operator all Divide 2 1.00 1.84 2.47 2.97 9.742 4
+ -operator all Gamma 0.7 1.00 1.50 1.72 1.77 12.724 4
+ -operator all Negate 1.0 1.00 1.17 1.20 1.20 14.841 4
+ -operator all LShift 2 1.00 1.25 1.34 1.34 14.770 4
+ -operator all Multiply 0.5 1.00 1.81 2.42 2.86 10.558 4
+ -operator all Or 233 1.00 1.16 1.25 1.18 15.584 3
+ -operator all RShift 2 1.00 1.28 1.43 1.40 15.800 3
+ -operator all Subtract 10% 1.00 1.82 2.45 2.90 10.338 4
+ -operator red Threshold 50% 1.00 1.15 1.24 1.19 15.637 3
+ -operator gray Threshold 50% 1.00 1.39 1.58 1.56 15.622 3
+ -operator all Threshold-White 80% 1.00 1.28 1.43 1.44 16.783 4
+ -operator all Threshold-Black 10% 1.00 1.31 1.46 1.56 17.313 4
+ -operator all Xor 233 1.00 1.17 1.27 1.22 16.168 3
+ -operator all Noise-Gaussian 30% 1.00 2.01 3.00 3.93 0.326 4
+ -operator all Noise-Impulse 30% 1.00 1.96 2.87 3.63 2.756 4
+ -operator all Noise-Laplacian 30% 1.00 2.00 2.93 3.82 1.162 4
+ -operator all Noise-Multiplicative 30% 1.00 1.99 2.95 3.88 0.531 4
+ -operator all Noise-Poisson 30% 1.00 2.00 2.94 3.86 0.877 4
+ -operator all Noise-Uniform 30% 1.00 1.95 2.82 3.60 2.962 4
+ -ordered-dither all 2x2 1.00 1.83 2.46 2.95 10.479 4
+ -ordered-dither all 3x3 1.00 1.81 2.40 2.88 10.259 4
+ -ordered-dither intensity 3x3 1.00 1.82 2.44 2.89 10.317 4
+ -ordered-dither all 4x4 1.00 1.82 2.45 2.94 10.479 4
+ -paint 0x1 1.00 2.00 2.93 3.85 1.139 4
+ -random-threshold all 20x80 1.00 1.84 2.50 2.99 9.037 4
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.22 1.21 1.17 32.368 2
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 1.89 2.63 3.24 6.931 4
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 1.87 2.59 3.05 6.207 4
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 1.89 2.65 3.24 6.567 4
+ -density 75x75 -resample 50x50 1.00 1.53 2.21 2.74 0.954 4
+ -resize 10% 1.00 1.64 2.38 3.03 3.210 4
+ -resize 50% 1.00 1.71 2.47 3.06 2.157 4
+ -resize 150% 1.00 1.48 2.12 2.61 0.384 4
+ -rotate 15 1.00 1.72 2.44 2.97 0.463 4
+ -rotate 45 1.00 1.76 2.34 2.93 0.205 4
+ -segment 0.5x0.25 1.00 1.46 1.77 2.08 0.027 4
+ -shade 30x30 1.00 1.90 2.69 3.37 3.575 4
+ -sharpen 0x0.5 1.00 1.97 2.87 3.68 2.115 4
+ -sharpen 0x1.0 1.00 2.01 2.97 3.87 0.735 4
+ -sharpen 0x2.0 1.00 2.02 2.98 3.94 0.252 4
+ -shear 45x45 1.00 1.68 2.20 2.71 0.244 4
+ -solarize 50% 1.00 1.40 1.59 1.58 15.569 3
+ -swirl 90 1.00 1.91 2.70 3.68 1.089 4
+ -fuzz 35% -transparent red 1.00 1.75 2.28 2.64 12.961 4
+ -trim 1.00 1.49 1.76 1.80 18.981 4
+ -fuzz 5% -trim 1.00 1.85 2.66 3.38 4.433 4
+ -unsharp 0x0.5+20+1 1.00 1.79 2.42 2.85 1.907 4
+ -unsharp 0x1.0+20+1 1.00 1.87 2.54 3.09 1.487 4
+ -wave 25x150 1.00 1.63 2.00 2.06 0.793 4
+ ===================================================================== ===== ===== ===== ===== ======== ====
+
+
+Sun Solaris / UltraSPARC III
+----------------------------
+
+.. Last update: Wed Dec 21 16:14:39 CST 2011
+
+The following table shows the performance boost as threads are added
+on 2 CPU Sun SPARC 1.2GHz workstation running Sun Solaris 10. This
+system obtains quite substantial benefit for most key algorithms:
+
+.. table:: Performance Boost On Two CPU SPARC System
+
+ ===================================================================== ===== ===== ======== ====
+ Operation 1 2 iter/s thds
+ ===================================================================== ===== ===== ======== ====
+ -noop 1.00 1.14 13.917 2
+ -affine 1,0,0.785,1,0,0 -transform 1.00 1.95 0.158 2
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 1.51 2.852 2
+ -blur 0x0.5 1.00 1.77 0.347 2
+ -blur 0x1.0 1.00 1.83 0.267 2
+ -blur 0x2.0 1.00 1.87 0.187 2
+ -charcoal 0x1 1.00 1.76 0.123 2
+ -colorspace CMYK 1.00 1.30 2.338 2
+ -colorspace GRAY 1.00 1.80 1.275 2
+ -colorspace HSL 1.00 1.89 0.531 2
+ -colorspace HWB 1.00 1.90 0.607 2
+ -colorspace OHTA 1.00 1.78 1.289 2
+ -colorspace YCbCr 1.00 1.78 1.292 2
+ -colorspace YIQ 1.00 1.79 1.292 2
+ -colorspace YUV 1.00 1.78 1.287 2
+ -contrast -contrast -contrast 1.00 1.97 0.077 2
+ +contrast +contrast +contrast 1.00 1.95 0.080 2
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 1.90 0.521 2
+ -colorize 30%/20%/50% 1.00 1.77 1.304 2
+ -despeckle 1.00 1.50 0.030 2
+ -edge 0x1 1.00 1.90 0.295 2
+ -emboss 0x1 1.00 1.77 0.223 2
+ -enhance 1.00 2.00 0.080 2
+ -gaussian 0x0.5 1.00 1.92 0.278 2
+ -gaussian 0x1.0 1.00 1.96 0.110 2
+ -gaussian 0x2.0 1.00 2.00 0.034 2
+ -hald-clut identity:8 1.00 1.94 0.382 2
+ -hald-clut identity:10 1.00 1.93 0.382 2
+ -hald-clut identity:14 1.00 1.91 0.323 2
+ -implode 0.5 1.00 1.94 0.159 2
+ -implode -1 1.00 1.93 0.195 2
+ -lat 10x10-5% 1.00 1.90 0.201 2
+ -median 1 1.00 1.97 0.069 2
+ -median 2 1.00 1.93 0.027 2
+ -minify 1.00 1.81 1.625 2
+ -modulate 110/100/95 1.00 1.94 0.283 2
+ +noise Uniform 1.00 1.91 0.321 2
+ +noise Gaussian 1.00 2.00 0.056 2
+ +noise Multiplicative 1.00 1.96 0.090 2
+ +noise Impulse 1.00 1.89 0.305 2
+ +noise Laplacian 1.00 1.95 0.164 2
+ +noise Poisson 1.00 2.00 0.096 2
+ -noise 1 1.00 1.94 0.066 2
+ -noise 2 1.00 2.00 0.026 2
+ -fill blue -fuzz 35% -opaque red 1.00 1.79 1.619 2
+ -operator all Add 2% 1.00 1.87 1.186 2
+ -operator all And 233 1.00 1.54 3.593 2
+ -operator all Assign 50% 1.00 1.38 3.976 2
+ -operator all Depth 6 1.00 1.54 3.320 2
+ -operator all Divide 2 1.00 1.86 0.931 2
+ -operator all Gamma 0.7 1.00 1.52 3.131 2
+ -operator all Negate 1.0 1.00 1.61 3.605 2
+ -operator all LShift 2 1.00 1.59 3.626 2
+ -operator all Multiply 0.5 1.00 1.88 1.190 2
+ -operator all Or 233 1.00 1.57 3.633 2
+ -operator all RShift 2 1.00 1.56 3.619 2
+ -operator all Subtract 10% 1.00 1.83 1.228 2
+ -operator red Threshold 50% 1.00 1.49 3.755 2
+ -operator gray Threshold 50% 1.00 1.61 2.772 2
+ -operator all Threshold-White 80% 1.00 1.73 2.879 2
+ -operator all Threshold-Black 10% 1.00 1.68 2.841 2
+ -operator all Xor 233 1.00 1.54 3.640 2
+ -operator all Noise-Gaussian 30% 1.00 2.00 0.058 2
+ -operator all Noise-Impulse 30% 1.00 1.85 0.322 2
+ -operator all Noise-Laplacian 30% 1.00 1.90 0.165 2
+ -operator all Noise-Multiplicative 30% 1.00 1.96 0.090 2
+ -operator all Noise-Poisson 30% 1.00 1.96 0.098 2
+ -operator all Noise-Uniform 30% 1.00 1.84 0.340 2
+ -ordered-dither all 2x2 1.00 1.76 1.468 2
+ -ordered-dither all 3x3 1.00 1.77 1.498 2
+ -ordered-dither intensity 3x3 1.00 1.78 1.493 2
+ -ordered-dither all 4x4 1.00 1.78 1.501 2
+ -paint 0x1 1.00 1.97 0.140 2
+ -random-threshold all 20x80 1.00 1.83 1.156 2
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.01 13.439 2
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 1.87 1.017 2
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 1.86 0.817 2
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 1.89 0.835 2
+ -density 75x75 -resample 50x50 1.00 1.86 0.257 2
+ -resize 10% 1.00 1.80 0.527 2
+ -resize 50% 1.00 1.85 0.382 2
+ -resize 150% 1.00 1.86 0.108 2
+ -rotate 15 1.00 1.72 0.148 2
+ -rotate 45 1.00 1.62 0.063 2
+ -segment 0.5x0.25 1.00 1.33 0.004 2
+ -shade 30x30 1.00 1.92 0.383 2
+ -sharpen 0x0.5 1.00 1.93 0.278 2
+ -sharpen 0x1.0 1.00 1.96 0.110 2
+ -sharpen 0x2.0 1.00 2.00 0.034 2
+ -shear 45x45 1.00 1.47 0.103 2
+ -solarize 50% 1.00 1.51 3.288 2
+ -swirl 90 1.00 1.96 0.196 2
+ -fuzz 35% -transparent red 1.00 1.91 1.487 2
+ -trim 1.00 1.59 3.488 2
+ -fuzz 5% -trim 1.00 1.94 0.565 2
+ -unsharp 0x0.5+20+1 1.00 1.79 0.272 2
+ -unsharp 0x1.0+20+1 1.00 1.83 0.219 2
+ -wave 25x150 1.00 1.85 0.207 2
+ ===================================================================== ===== ===== ======== ====
+
+
+IBM AIX / IBM Power5+
+---------------------
+
+.. Last update: Mon Jul 20 19:15:49 CDT 2009
+
+The following table shows the boost on a four core IBM P5+ server
+system (IBM System p5 505 Express with (2) 2.1Ghz CPUs) running AIX:
+
+.. table:: Performance Boost On Four Core IBM P5+ System
+
+ ======================================================= ===== ===== ===== ===== ======= ====
+ Operation 1 2 3 4 iter/s thds
+ ======================================================= ===== ===== ===== ===== ======= ====
+ -noop 1.00 1.56 1.66 1.75 290.60 4
+ -affine 1,0,0.785,1,0,0 -transform 1.00 1.96 2.54 3.13 2.48 4
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 1.64 2.41 2.78 49.70 4
+ -blur 0x0.5 1.00 1.97 2.50 3.03 2.71 4
+ -blur 0x1.0 1.00 1.95 2.67 3.30 2.13 4
+ -charcoal 0x1 1.00 1.95 2.68 3.35 0.96 4
+ -colorspace CMYK 1.00 1.52 1.48 1.59 67.00 4
+ -colorspace GRAY 1.00 1.70 2.47 2.93 17.17 4
+ -colorspace HSL 1.00 1.59 2.38 2.97 8.20 4
+ -colorspace HWB 1.00 1.94 2.56 2.88 7.84 4
+ -colorspace OHTA 1.00 1.87 2.42 2.94 17.20 4
+ -colorspace YCbCr 1.00 1.30 2.49 3.04 17.20 4
+ -colorspace YIQ 1.00 1.90 2.29 2.92 17.10 4
+ -colorspace YUV 1.00 1.92 2.50 3.04 17.20 4
+ -contrast -contrast -contrast 1.00 1.99 2.50 2.97 2.09 4
+ +contrast +contrast +contrast 1.00 1.99 2.50 2.99 2.15 4
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 2.03 2.84 3.60 3.79 4
+ -colorize 30%/20%/50% 1.00 1.99 2.77 3.55 11.75 4
+ -despeckle 1.00 1.49 2.79 2.81 0.27 4
+ -edge 0x1 1.00 0.42 3.31 3.07 3.00 3
+ -emboss 0x1 1.00 1.81 2.39 2.27 1.20 3
+ -enhance 1.00 2.10 2.93 3.08 0.74 4
+ -gaussian 0x0.5 1.00 2.05 2.91 3.40 1.79 4
+ -gaussian 0x1.0 1.00 2.00 2.86 3.70 0.79 4
+ -implode 0.5 1.00 2.19 2.42 3.17 2.83 4
+ -implode -1 1.00 1.72 2.20 3.08 3.00 4
+ -lat 10x10-5% 1.00 2.00 2.26 2.42 1.13 4
+ -median 1 1.00 2.03 1.32 2.86 0.79 4
+ -median 2 1.00 1.99 2.40 2.81 0.30 4
+ -minify 1.00 1.97 2.83 3.67 9.72 4
+ -modulate 110/100/95 1.00 2.56 3.33 3.81 6.57 4
+ +noise Uniform 1.00 2.06 2.61 3.43 5.19 4
+ +noise Gaussian 1.00 1.99 2.53 2.75 1.83 4
+ +noise Multiplicative 1.00 1.99 2.72 3.46 2.32 4
+ +noise Impulse 1.00 1.79 2.60 3.23 5.27 4
+ +noise Laplacian 1.00 1.82 2.55 3.44 3.51 4
+ +noise Poisson 1.00 1.78 2.74 3.32 2.11 4
+ -noise 1 1.00 1.99 2.41 2.81 0.79 4
+ -noise 2 1.00 2.00 2.39 2.69 0.29 4
+ -fill blue -fuzz 35% -opaque red 1.00 1.03 2.20 2.72 36.40 4
+ -operator all Add 2% 1.00 2.69 1.49 5.30 14.82 4
+ -operator all And 233 1.00 1.70 1.64 1.92 160.20 4
+ -operator all Assign 50% 1.00 1.30 1.87 1.84 166.40 3
+ -operator all Depth 6 1.00 1.75 1.81 1.88 134.00 4
+ -operator all Divide 2 1.00 1.98 2.79 3.59 15.64 4
+ -operator all Gamma 0.7 1.00 1.27 1.64 1.63 102.20 3
+ -operator all Negate 1.0 1.00 1.68 1.50 1.70 149.00 4
+ -operator all LShift 2 1.00 1.68 1.75 1.77 145.20 4
+ -operator all Multiply 0.5 1.00 1.98 2.71 3.59 15.57 4
+ -operator all Or 233 1.00 1.71 1.73 1.88 165.20 4
+ -operator all RShift 2 1.00 1.25 1.79 1.84 163.00 4
+ -operator all Subtract 10% 1.00 1.96 2.72 3.49 16.73 4
+ -operator red Threshold 50% 1.00 1.70 1.93 2.05 163.40 4
+ -operator gray Threshold 50% 1.00 1.82 1.90 2.03 113.00 4
+ -operator all Threshold-White 80% 1.00 1.85 1.97 2.08 117.60 4
+ -operator all Threshold-Black 10% 1.00 1.78 1.97 2.17 117.00 4
+ -operator all Xor 233 1.00 1.71 1.74 1.86 164.00 4
+ -operator all Noise-Gaussian 30% 1.00 1.95 2.56 3.11 2.09 4
+ -operator all Noise-Impulse 30% 1.00 1.97 2.65 3.36 5.54 4
+ -operator all Noise-Laplacian 30% 1.00 2.00 2.80 3.60 3.70 4
+ -operator all Noise-Multiplicative 30% 1.00 1.95 2.73 3.49 2.35 4
+ -operator all Noise-Poisson 30% 1.00 2.00 2.74 3.33 2.12 4
+ -operator all Noise-Uniform 30% 1.00 1.95 2.69 3.52 5.40 4
+ -ordered-dither all 2x2 1.00 1.50 1.62 1.39 53.49 3
+ -ordered-dither all 3x3 1.00 1.17 1.53 1.54 42.60 4
+ -ordered-dither intensity 3x3 1.00 1.06 1.93 2.20 48.00 4
+ -ordered-dither all 4x4 1.00 1.67 0.31 1.29 53.20 2
+ -paint 0x1 1.00 1.71 2.18 2.18 5.64 3
+ -random-threshold all 20x80 1.00 1.90 2.36 2.43 19.40 4
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.49 1.72 1.44 226.80 3
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 1.89 2.60 3.26 10.63 4
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 1.74 2.58 3.19 7.16 4
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 1.81 2.02 3.01 6.57 4
+ -density 75x75 -resample 50x50 1.00 1.82 2.33 2.86 3.42 4
+ -resize 10% 1.00 2.41 3.17 3.43 7.50 4
+ -resize 50% 1.00 3.15 4.35 5.30 4.93 4
+ -resize 150% 1.00 1.62 2.29 2.69 1.28 4
+ -rotate 45 1.00 1.68 0.24 1.60 0.45 2
+ -segment 0.5x0.25 1.00 1.12 1.21 1.25 0.03 4
+ -shade 30x30 1.00 2.30 2.65 2.95 8.10 4
+ -sharpen 0x0.5 1.00 1.91 2.81 3.53 1.89 4
+ -sharpen 0x1.0 1.00 1.85 2.79 3.66 0.78 4
+ -shear 45x45 1.00 1.61 2.06 2.03 1.16 3
+ -solarize 50% 1.00 1.73 2.18 2.32 96.40 4
+ -swirl 90 1.00 1.86 2.38 2.88 3.09 4
+ -fuzz 35% -transparent red 1.00 2.14 2.29 2.59 31.20 4
+ -trim 1.00 1.92 2.30 2.57 23.06 4
+ -fuzz 5% -trim 1.00 1.91 2.61 3.21 8.96 4
+ -unsharp 0x0.5+20+1 1.00 1.92 1.16 0.12 1.35 2
+ -unsharp 0x1.0+20+1 1.00 1.85 2.65 3.39 1.83 4
+ -wave 25x150 1.00 1.71 1.84 2.83 2.62 4
+ ======================================================= ===== ===== ===== ===== ======= ====
+
+
+Apple OS-X/IBM G5
+-----------------
+
+.. Last update: Mon Jul 20 16:46:35 CDT 2009
+
+The following table shows the boost on a two core Apple PowerPC G5
+system (2.5GHz) running OS-X Leopard:
+
+.. table:: Performance Boost On Two Core PowerPC G5 System
+
+ ======================================================= ===== ===== ======= ====
+ Operation 1 2 iter/s thds
+ ======================================================= ===== ===== ======= ====
+ -noop 1.00 1.03 24.25 2
+ -affine 1,0,0.785,1,0,0 -transform 1.00 1.68 1.76 2
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 1.25 14.17 2
+ -blur 0x0.5 1.00 1.62 1.70 2
+ -blur 0x1.0 1.00 1.71 1.14 2
+ -charcoal 0x1 1.00 1.76 0.56 2
+ -colorspace CMYK 1.00 1.11 16.07 2
+ -colorspace GRAY 1.00 1.47 9.38 2
+ -colorspace HSL 1.00 1.72 5.53 2
+ -colorspace HWB 1.00 1.72 5.61 2
+ -colorspace OHTA 1.00 1.46 9.36 2
+ -colorspace YCbCr 1.00 1.42 9.07 2
+ -colorspace YIQ 1.00 1.47 9.34 2
+ -colorspace YUV 1.00 1.48 9.38 2
+ -contrast -contrast -contrast 1.00 1.89 1.42 2
+ +contrast +contrast +contrast 1.00 1.84 1.41 2
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 1.75 2.51 2
+ -colorize 30%/20%/50% 1.00 1.40 8.43 2
+ -despeckle 1.00 1.48 0.21 2
+ -edge 0x1 1.00 1.79 2.60 2
+ -emboss 0x1 1.00 1.80 1.14 2
+ -enhance 1.00 1.93 0.65 2
+ -gaussian 0x0.5 1.00 1.88 1.26 2
+ -gaussian 0x1.0 1.00 1.92 0.46 2
+ -hald-clut identity:8 1.00 1.74 3.20 2
+ -hald-clut identity:10 1.00 1.74 2.95 2
+ -hald-clut identity:14 1.00 1.74 1.55 2
+ -implode 0.5 1.00 1.79 1.92 2
+ -implode -1 1.00 1.71 2.35 2
+ -lat 10x10-5% 1.00 1.88 0.42 2
+ -median 1 1.00 1.39 0.48 2
+ -median 2 1.00 1.91 0.26 2
+ -minify 1.00 1.59 7.77 2
+ -modulate 110/100/95 1.00 1.75 4.04 2
+ +noise Uniform 1.00 1.60 3.44 2
+ +noise Gaussian 1.00 1.85 0.99 2
+ +noise Multiplicative 1.00 1.82 1.43 2
+ +noise Impulse 1.00 1.62 3.23 2
+ +noise Laplacian 1.00 1.76 1.98 2
+ +noise Poisson 1.00 1.81 1.48 2
+ -noise 1 1.00 1.78 0.59 2
+ -noise 2 1.00 1.90 0.25 2
+ -fill blue -fuzz 35% -opaque red 1.00 1.23 15.11 2
+ -operator all Add 2% 1.00 1.56 8.28 2
+ -operator all And 233 1.00 0.98 19.16 1
+ -operator all Assign 50% 1.00 1.11 17.82 2
+ -operator all Depth 6 1.00 1.01 18.00 2
+ -operator all Divide 2 1.00 1.59 8.43 2
+ -operator all Gamma 0.7 1.00 1.00 15.45 1
+ -operator all Negate 1.0 1.00 1.01 18.69 2
+ -operator all LShift 2 1.00 1.03 18.80 2
+ -operator all Multiply 0.5 1.00 1.56 8.05 2
+ -operator all Or 233 1.00 1.03 19.00 2
+ -operator all RShift 2 1.00 0.99 19.16 1
+ -operator all Subtract 10% 1.00 1.59 8.37 2
+ -operator red Threshold 50% 1.00 1.00 18.56 1
+ -operator gray Threshold 50% 1.00 1.02 18.33 2
+ -operator all Threshold-White 80% 1.00 1.09 20.20 2
+ -operator all Threshold-Black 10% 1.00 1.04 19.28 2
+ -operator all Xor 233 1.00 0.98 19.16 1
+ -operator all Noise-Gaussian 30% 1.00 1.92 1.07 2
+ -operator all Noise-Impulse 30% 1.00 1.72 3.99 2
+ -operator all Noise-Laplacian 30% 1.00 1.86 2.26 2
+ -operator all Noise-Multiplicative 30% 1.00 1.90 1.59 2
+ -operator all Noise-Poisson 30% 1.00 1.89 1.66 2
+ -operator all Noise-Uniform 30% 1.00 1.71 4.31 2
+ -ordered-dither all 2x2 1.00 1.06 15.11 2
+ -ordered-dither all 3x3 1.00 1.14 14.97 2
+ -ordered-dither intensity 3x3 1.00 1.10 14.77 2
+ -ordered-dither all 4x4 1.00 1.08 15.25 2
+ -paint 0x1 1.00 1.71 3.77 2
+ -random-threshold all 20x80 1.00 1.30 11.90 2
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.02 23.90 2
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 1.67 6.68 2
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 1.68 6.65 2
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 1.66 6.59 2
+ -density 75x75 -resample 50x50 1.00 1.56 1.55 2
+ -resize 10% 1.00 1.76 3.73 2
+ -resize 50% 1.00 1.70 2.34 2
+ -resize 150% 1.00 1.67 0.49 2
+ -rotate 45 1.00 1.67 0.24 2
+ -segment 0.5x0.25 1.00 1.26 0.05 2
+ -shade 30x30 1.00 1.57 5.49 2
+ -sharpen 0x0.5 1.00 1.84 1.26 2
+ -sharpen 0x1.0 1.00 1.90 0.45 2
+ -shear 45x45 1.00 1.68 0.28 2
+ -solarize 50% 1.00 1.09 19.05 2
+ -swirl 90 1.00 1.79 2.10 2
+ -fuzz 35% -transparent red 1.00 1.27 15.71 2
+ -trim 1.00 1.68 6.55 2
+ -fuzz 5% -trim 1.00 1.77 4.50 2
+ -unsharp 0x0.5+20+1 1.00 1.66 1.46 2
+ -unsharp 0x1.0+20+1 1.00 1.75 1.04 2
+ -wave 25x150 1.00 1.59 2.17 2
+ ======================================================= ===== ===== ======= ====
+
+
+FreeBSD / Intel Xeon
+--------------------
+
+.. Last update: Wed Dec 21 16:16:35 CST 2011
+
+The following shows the performance boost on a 2003 vintage 2-CPU
+hyperthreaded Intel Xeon system running at 2.4GHz. The operating
+system used is FreeBSD 8.0. Due to the hyperthreading support, this
+system thinks it has four CPUs even though it really only has two
+cores. This can lead to very strange results since sometimes it seems
+that the first two threads allocated may be from the same CPU,
+resulting in much less boost than expected, but obtaining full boost
+with four threads. While the threading on this system behaves poorly
+for "fast" algorithms, it is clear that OpenMP works well for "slow"
+algorithms, and some algorithms show clear benefit from
+hyperthreading:
+
+.. table:: Performance Boost On Two CPU Xeon System
+
+ ===================================================================== ===== ===== ===== ===== ======== ====
+ Operation 1 2 3 4 iter/s thds
+ ===================================================================== ===== ===== ===== ===== ======== ====
+ -noop 1.00 1.00 1.00 1.00 3.253 2
+ -affine 1,0,0.785,1,0,0 -transform 1.00 1.73 1.54 1.85 0.300 4
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 1.08 1.15 1.09 2.023 3
+ -blur 0x0.5 1.00 1.24 1.23 1.28 0.354 4
+ -blur 0x1.0 1.00 1.24 1.30 1.39 0.329 4
+ -blur 0x2.0 1.00 1.43 1.35 1.52 0.275 4
+ -charcoal 0x1 1.00 1.39 1.32 1.35 0.171 2
+ -colorspace CMYK 1.00 0.91 0.89 0.87 1.925 1
+ -colorspace GRAY 1.00 1.39 1.34 1.49 1.571 4
+ -colorspace HSL 1.00 1.77 1.64 2.03 0.856 4
+ -colorspace HWB 1.00 1.68 1.72 2.04 1.187 4
+ -colorspace OHTA 1.00 1.39 1.34 1.53 1.602 4
+ -colorspace YCbCr 1.00 1.36 1.36 1.54 1.618 4
+ -colorspace YIQ 1.00 1.38 1.34 1.50 1.580 4
+ -colorspace YUV 1.00 1.38 1.35 1.54 1.616 4
+ -contrast -contrast -contrast 1.00 1.95 2.05 2.61 0.214 4
+ +contrast +contrast +contrast 1.00 1.93 1.99 2.57 0.221 4
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 1.57 1.52 1.57 0.812 4
+ -colorize 30%/20%/50% 1.00 1.46 1.37 1.46 1.082 2
+ -despeckle 1.00 1.44 1.94 1.97 0.063 4
+ -edge 0x1 1.00 1.24 1.56 1.64 0.812 4
+ -emboss 0x1 1.00 1.60 1.48 1.55 0.359 2
+ -enhance 1.00 1.96 1.69 2.09 0.115 4
+ -gaussian 0x0.5 1.00 1.75 1.56 1.69 0.477 2
+ -gaussian 0x1.0 1.00 1.86 1.62 1.93 0.205 4
+ -gaussian 0x2.0 1.00 1.91 1.88 2.21 0.075 4
+ -hald-clut identity:8 1.00 1.85 2.00 2.48 0.629 4
+ -hald-clut identity:10 1.00 1.85 2.01 2.52 0.602 4
+ -hald-clut identity:14 1.00 1.51 2.14 2.65 0.464 4
+ -implode 0.5 1.00 1.92 1.92 2.51 0.233 4
+ -implode -1 1.00 1.88 1.88 2.36 0.380 4
+ -lat 10x10-5% 1.00 1.59 1.23 1.34 0.305 2
+ -median 1 1.00 1.96 1.46 1.39 0.055 2
+ -median 2 1.00 2.00 1.80 2.20 0.022 4
+ -minify 1.00 1.50 1.39 1.47 1.329 2
+ -modulate 110/100/95 1.00 1.83 1.83 2.28 0.717 4
+ +noise Uniform 1.00 1.78 2.03 2.49 0.394 4
+ +noise Gaussian 1.00 1.53 2.37 2.86 0.163 4
+ +noise Multiplicative 1.00 1.94 2.76 2.98 0.185 4
+ +noise Impulse 1.00 1.79 2.43 2.58 0.400 4
+ +noise Laplacian 1.00 1.84 2.42 2.65 0.286 4
+ +noise Poisson 1.00 1.92 2.41 3.12 0.159 4
+ -noise 1 1.00 0.75 1.68 1.71 0.048 4
+ -noise 2 1.00 2.00 1.60 2.20 0.022 4
+ -fill blue -fuzz 35% -opaque red 1.00 1.24 1.20 1.28 2.537 4
+ -operator all Add 2% 1.00 1.33 1.30 1.31 2.092 2
+ -operator all And 233 1.00 0.96 1.01 0.90 2.242 3
+ -operator all Assign 50% 1.00 0.99 1.03 0.97 2.265 3
+ -operator all Depth 6 1.00 0.99 1.01 0.93 2.204 3
+ -operator all Divide 2 1.00 1.50 1.32 1.53 1.623 4
+ -operator all Gamma 0.7 1.00 0.98 1.02 0.94 2.035 3
+ -operator all Negate 1.0 1.00 0.97 1.01 0.92 2.239 3
+ -operator all LShift 2 1.00 0.97 1.00 0.91 2.249 3
+ -operator all Multiply 0.5 1.00 1.34 1.27 1.33 2.095 2
+ -operator all Or 233 1.00 0.98 1.01 0.92 2.233 3
+ -operator all RShift 2 1.00 0.97 1.00 0.92 2.242 3
+ -operator all Subtract 10% 1.00 1.35 1.33 1.39 2.101 4
+ -operator red Threshold 50% 1.00 0.97 1.01 0.91 2.246 3
+ -operator gray Threshold 50% 1.00 0.99 1.01 0.93 2.246 3
+ -operator all Threshold-White 80% 1.00 1.08 1.09 1.07 2.655 3
+ -operator all Threshold-Black 10% 1.00 1.10 1.12 1.10 2.576 3
+ -operator all Xor 233 1.00 0.96 1.02 0.91 2.276 3
+ -operator all Noise-Gaussian 30% 1.00 1.48 2.20 2.86 0.189 4
+ -operator all Noise-Impulse 30% 1.00 1.86 1.86 2.36 0.587 4
+ -operator all Noise-Laplacian 30% 1.00 1.92 2.06 2.64 0.383 4
+ -operator all Noise-Multiplicative 30% 1.00 1.96 2.24 2.92 0.242 4
+ -operator all Noise-Poisson 30% 1.00 1.96 2.17 2.84 0.213 4
+ -operator all Noise-Uniform 30% 1.00 1.86 1.83 2.28 0.578 4
+ -ordered-dither all 2x2 1.00 1.46 1.48 1.56 1.613 4
+ -ordered-dither all 3x3 1.00 1.47 1.46 1.58 1.643 4
+ -ordered-dither intensity 3x3 1.00 1.48 1.48 1.60 1.653 4
+ -ordered-dither all 4x4 1.00 1.19 1.50 1.61 1.665 4
+ -paint 0x1 1.00 1.24 1.80 2.30 0.324 4
+ -random-threshold all 20x80 1.00 1.58 1.72 1.86 1.422 4
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.00 1.00 1.00 3.267 2
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 1.47 1.33 1.52 1.789 4
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 1.52 1.42 1.62 1.632 4
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 1.52 1.40 1.61 1.623 4
+ -density 75x75 -resample 50x50 1.00 1.33 1.54 1.39 0.208 3
+ -resize 10% 1.00 1.61 1.31 1.53 0.658 2
+ -resize 50% 1.00 1.60 1.39 1.55 0.361 2
+ -resize 150% 1.00 1.48 1.58 1.65 0.086 4
+ -rotate 15 1.00 1.25 1.34 1.40 0.116 4
+ -rotate 45 1.00 1.20 1.34 1.37 0.048 4
+ -segment 0.5x0.25 1.00 1.33 1.33 1.33 0.012 2
+ -shade 30x30 1.00 1.80 2.18 2.47 0.621 4
+ -sharpen 0x0.5 1.00 1.80 1.62 1.72 0.473 2
+ -sharpen 0x1.0 1.00 1.12 1.76 1.90 0.201 4
+ -sharpen 0x2.0 1.00 1.91 1.76 2.21 0.075 4
+ -shear 45x45 1.00 1.14 1.33 1.40 0.060 4
+ -solarize 50% 1.00 0.97 1.01 0.90 2.272 3
+ -swirl 90 1.00 1.43 2.02 2.50 0.357 4
+ -fuzz 35% -transparent red 1.00 1.19 1.20 1.12 2.220 3
+ -trim 1.00 1.08 1.09 1.06 2.715 3
+ -fuzz 5% -trim 1.00 1.73 1.75 2.14 1.091 4
+ -unsharp 0x0.5+20+1 1.00 1.35 1.35 1.47 0.320 4
+ -unsharp 0x1.0+20+1 1.00 1.40 1.41 1.54 0.296 4
+ -wave 25x150 1.00 1.81 1.69 2.01 0.348 4
+ ===================================================================== ===== ===== ===== ===== ======== ====
+
+Windows XP / MSVC / Intel Core 2 Quad
+-------------------------------------
+
+.. Last update: Sun Jan 29 16:17:01 CST 2012
+
+This system is Windows XP Professional (SP3) using the Visual Studio
+2008 compiler and a Q16 build. The system CPU is a 2.83 GHz Core 2
+Quad Processor (Q9550). This processor is a multi-chip module (MCM)
+based on two Core 2 CPUs bonded to a L3 cache in the same chip
+package.
+
+The following shows the performance boost for a Q16 build:
+
+.. table:: Performance Boost on an Intel Core 2 Quad (Q9550) system
+
+ ===================================================================== ===== ===== ===== ===== ======== ====
+ Operation 1 2 3 4 iter/s thds
+ ===================================================================== ===== ===== ===== ===== ======== ====
+ -noop 1.00 1.00 0.99 0.98 13.036 1
+ -affine 1,0,0.785,1,0,0 -transform 1.00 1.62 2.11 2.38 0.808 4
+ -asc-cdl 0.9,0.01,0.45:0.9,0.01,0.45:0.9,0.01,0.45:0.01 1.00 1.09 1.17 1.18 8.271 4
+ -blur 0x0.5 1.00 1.62 2.12 2.47 1.551 4
+ -blur 0x1.0 1.00 1.71 2.25 2.62 1.378 4
+ -blur 0x2.0 1.00 1.78 2.40 2.78 1.091 4
+ -charcoal 0x1 1.00 1.71 2.23 2.61 0.738 4
+ -colorspace CMYK 1.00 1.06 1.07 1.11 7.309 4
+ -colorspace GRAY 1.00 1.71 2.23 2.56 4.711 4
+ -colorspace HSL 1.00 1.83 2.56 3.15 3.418 4
+ -colorspace HWB 1.00 1.79 2.45 2.97 4.332 4
+ -colorspace OHTA 1.00 1.77 2.23 2.55 4.655 4
+ -colorspace YCbCr 1.00 1.72 2.19 2.52 4.711 4
+ -colorspace YIQ 1.00 1.73 2.21 2.48 4.613 4
+ -colorspace YUV 1.00 1.75 2.23 2.55 4.712 4
+ -contrast -contrast -contrast 1.00 1.95 2.87 3.74 0.838 4
+ +contrast +contrast +contrast 1.00 1.94 2.87 3.74 0.849 4
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 1.77 2.42 2.99 3.012 4
+ -colorize 30%/20%/50% 1.00 1.70 2.31 2.70 4.036 4
+ -despeckle 1.00 1.85 2.54 2.88 0.515 4
+ -edge 0x1 1.00 1.87 2.67 3.37 1.751 4
+ -emboss 0x1 1.00 1.79 2.43 2.97 1.519 4
+ -enhance 1.00 1.95 2.90 3.80 0.600 4
+ -fill none -stroke gold -draw 'circle 800,500 1100,800' 1.00 1.34 1.48 1.59 9.938 4
+ -fill green -stroke gold -draw 'circle 800,500 1100,800' 1.00 1.42 1.63 1.76 9.312 4
+ -fill none -stroke gold -draw 'rectangle 400,200 1100,800' 1.00 1.18 1.32 1.37 11.400 4
+ -fill blue -stroke gold -draw 'rectangle 400,200 1100,800' 1.00 1.29 1.41 1.52 10.731 4
+ -fill none -stroke gold -draw 'roundRectangle 400,200 1100,800 20,20' 1.00 1.17 1.24 1.28 11.492 4
+ -fill blue -stroke gold -draw 'roundRectangle 400,200 1100,800 20,20' 1.00 1.23 1.36 1.43 10.831 4
+ -fill none -stroke gold -draw 'polygon 400,200 1100,800 100,300' 1.00 1.23 1.39 1.45 11.028 4
+ -fill blue -stroke gold -draw 'polygon 400,200 1100,800 100,300' 1.00 1.24 1.40 1.49 10.731 4
+ -fill none -stroke gold -draw 'Bezier 400,200 1100,800 100,300' 1.00 1.09 1.13 1.18 11.655 4
+ -fill blue -stroke gold -draw 'Bezier 400,200 1100,800 100,300' 1.00 1.13 1.18 1.22 11.563 4
+ -gaussian 0x0.5 1.00 1.88 2.65 3.36 1.883 4
+ -gaussian 0x1.0 1.00 1.98 2.90 3.76 0.884 4
+ -gaussian 0x2.0 1.00 1.92 2.91 3.82 0.298 4
+ -hald-clut identity:8 1.00 1.87 2.66 3.28 2.286 4
+ -hald-clut identity:10 1.00 1.84 2.57 3.22 2.193 4
+ -hald-clut identity:14 1.00 1.68 2.17 2.53 1.378 4
+ -implode 0.5 1.00 1.93 2.79 3.38 1.150 4
+ -implode -1 1.00 1.92 2.78 3.57 1.214 4
+ -lat 10x10-5% 1.00 1.86 2.60 3.24 1.185 4
+ -median 1 1.00 1.97 2.68 3.47 0.253 4
+ -median 2 1.00 1.96 2.77 3.65 0.095 4
+ -minify 1.00 1.69 2.17 2.55 5.415 4
+ -modulate 110/100/95 1.00 1.83 2.60 3.29 2.954 4
+ +noise Uniform 1.00 1.68 2.15 2.51 2.400 4
+ +noise Gaussian 1.00 1.91 2.75 3.44 0.713 4
+ +noise Multiplicative 1.00 1.89 2.71 3.42 0.899 4
+ +noise Impulse 1.00 1.70 2.20 2.53 2.239 4
+ +noise Laplacian 1.00 1.82 2.49 2.95 1.450 4
+ +noise Poisson 1.00 1.91 2.75 3.29 0.727 4
+ -noise 1 1.00 1.96 2.58 3.81 0.278 4
+ -noise 2 1.00 1.96 2.77 3.65 0.095 4
+ -fill blue -fuzz 35% -opaque red 1.00 1.35 1.51 1.60 9.771 4
+ -operator all Add 2% 1.00 1.71 2.27 2.71 5.497 4
+ -operator all And 233 1.00 1.05 1.08 1.09 8.600 4
+ -operator all Assign 50% 1.00 1.03 1.05 1.05 8.348 3
+ -operator all Depth 6 1.00 1.09 1.08 1.12 8.520 4
+ -operator all Divide 2 1.00 1.73 2.29 2.70 5.497 4
+ -operator all Gamma 0.7 1.00 1.03 1.08 1.10 8.271 4
+ -operator all Negate 1.0 1.00 1.02 1.04 1.06 8.398 4
+ -operator all LShift 2 1.00 1.08 1.07 1.09 8.600 4
+ -operator all Multiply 0.5 1.00 1.73 2.29 2.71 5.498 4
+ -operator all Or 233 1.00 1.02 1.06 1.09 8.612 4
+ -operator all RShift 2 1.00 1.03 1.09 1.09 8.574 4
+ -operator all Subtract 10% 1.00 1.73 2.31 2.73 5.333 4
+ -operator red Threshold 50% 1.00 1.04 1.06 1.09 8.746 4
+ -operator gray Threshold 50% 1.00 1.03 1.08 1.09 8.638 4
+ -operator all Threshold-White 80% 1.00 1.13 1.14 1.15 10.208 4
+ -operator all Threshold-Black 10% 1.00 1.16 1.13 1.18 10.000 4
+ -operator all Xor 233 1.00 1.06 1.10 1.10 8.692 3
+ -operator all Noise-Gaussian 30% 1.00 1.97 2.90 3.54 0.757 4
+ -operator all Noise-Impulse 30% 1.00 1.86 2.61 3.23 3.200 4
+ -operator all Noise-Laplacian 30% 1.00 1.91 2.76 3.53 1.866 4
+ -operator all Noise-Multiplicative 30% 1.00 1.96 2.90 3.48 0.944 4
+ -operator all Noise-Poisson 30% 1.00 1.96 2.88 3.77 0.867 4
+ -operator all Noise-Uniform 30% 1.00 1.80 2.57 3.18 3.429 4
+ -ordered-dither all 2x2 1.00 1.26 1.28 1.32 7.308 4
+ -ordered-dither all 3x3 1.00 1.27 1.30 1.35 7.438 4
+ -ordered-dither intensity 3x3 1.00 1.25 1.30 1.35 7.400 4
+ -ordered-dither all 4x4 1.00 1.24 1.29 1.33 7.354 4
+ -paint 0x1 1.00 1.93 2.83 3.65 0.836 4
+ -random-threshold all 20x80 1.00 1.58 1.96 2.25 6.634 4
+ -recolor '1,0,0,0,1,0,0,0,1' 1.00 1.00 1.01 1.01 13.000 3
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 1.71 2.21 2.65 5.514 4
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 1.79 2.44 2.95 4.346 4
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 1.78 2.42 2.95 4.372 4
+ -density 75x75 -resample 50x50 1.00 1.65 2.25 2.65 1.751 4
+ -resize 10% 1.00 1.71 2.23 2.63 4.834 4
+ -resize 50% 1.00 1.72 2.31 2.69 2.499 4
+ -resize 150% 1.00 1.86 2.36 2.58 0.715 4
+ -rotate 15 1.00 1.50 1.75 2.07 0.723 4
+ -rotate 45 1.00 1.49 1.55 1.76 0.311 4
+ -segment 0.5x0.25 1.00 1.44 1.62 1.69 0.027 4
+ -shade 30x30 1.00 1.67 2.20 2.55 4.085 4
+ -sharpen 0x0.5 1.00 1.89 2.64 3.36 1.877 4
+ -sharpen 0x1.0 1.00 1.99 2.90 3.76 0.879 4
+ -sharpen 0x2.0 1.00 1.94 2.91 3.83 0.299 4
+ -shear 45x45 1.00 1.05 1.30 1.49 0.441 4
+ -solarize 50% 1.00 1.06 1.12 1.12 8.322 4
+ -swirl 90 1.00 1.89 2.74 3.53 1.366 4
+ -fuzz 35% -transparent red 1.00 1.32 1.42 1.43 8.322 4
+ -trim 1.00 1.38 1.60 1.70 9.846 4
+ -fuzz 5% -trim 1.00 1.69 2.30 2.77 5.200 4
+ -unsharp 0x0.5+20+1 1.00 1.69 2.17 2.60 1.333 4
+ -unsharp 0x1.0+20+1 1.00 1.73 2.32 2.63 1.160 4
+ -wave 25x150 1.00 1.83 2.57 3.08 1.378 4
+ ===================================================================== ===== ===== ===== ===== ======== ====
+
+
+Windows 7 / MinGW / Intel Core 2 Quad
+-------------------------------------
+
+.. Last update: Sun Mar 9 10:39:14 CDT 2015
+
+GCC 4.8.2 (x86_64-win32-sjlj) from a build of the 'MinGW-w64'_ project
+was installed on the same Windows system with the 2.83 GHz Core 2 Quad
+Processor (Q9550) as described above. The build is a 32-bit build.
+This processor is a multi-chip module (MCM) based on two Core 2 CPUs
+bonded to a L3 cache in the same chip package.
+
+The following shows the performance boost for a Q16 build:
+
+.. table:: Performance Boost on an Intel Core 2 Quad (Q9550) system
+
+
+ ============================================== ===== ===== ===== ===== ======== ====
+ Operation 1 2 3 4 iter/s thds
+ ============================================== ===== ===== ===== ===== ======== ====
+ -affine 1,0,0.785,1,0,0 -transform 1.00 1.78 2.46 3.01 1.447 4
+ -blur 0x0.5 1.00 1.48 1.89 2.12 1.208 4
+ -blur 0x1.0 1.00 1.68 2.18 2.53 0.955 4
+ -blur 0x2.0 1.00 1.75 2.44 2.96 0.668 4
+ -charcoal 0x1 1.00 1.67 2.16 2.53 0.613 4
+ -colorspace GRAY 1.00 1.38 1.60 1.71 7.689 4
+ -colorspace HSL 1.00 1.80 2.44 3.00 3.631 4
+ -colorspace HWB 1.00 1.72 2.27 2.70 4.568 4
+ -colorspace OHTA 1.00 1.31 1.63 1.72 7.673 4
+ -colorspace YCbCr 1.00 1.40 1.60 1.70 7.658 4
+ -colorspace YIQ 1.00 1.34 1.65 1.73 7.764 4
+ -colorspace YUV 1.00 1.37 1.62 1.72 7.692 4
+ -contrast -contrast -contrast 1.00 1.94 2.84 3.70 0.858 4
+ +contrast +contrast +contrast 1.00 1.92 2.84 3.69 0.872 4
+ -convolve 1,1,1,1,4,1,1,1,1 1.00 1.80 2.49 3.09 2.734 4
+ -despeckle 1.00 1.64 2.09 2.30 0.561 4
+ -edge 0x1 1.00 1.81 2.50 3.09 2.543 4
+ -emboss 0x1 1.00 1.86 2.54 3.23 1.101 4
+ -enhance 1.00 1.96 2.89 3.79 0.603 4
+ -gaussian 0x0.5 1.00 1.92 2.70 3.56 1.295 4
+ -gaussian 0x1.0 1.00 1.97 2.92 3.81 0.453 4
+ -gaussian 0x2.0 1.00 1.97 2.97 3.94 0.134 4
+ -hald-clut identity:8 1.00 1.83 2.52 3.00 2.981 4
+ -hald-clut identity:10 1.00 1.83 2.52 3.10 3.046 4
+ -hald-clut identity:14 1.00 1.81 2.48 3.00 2.564 4
+ -implode 0.5 1.00 1.87 2.79 3.56 1.098 4
+ -implode -1 1.00 1.90 2.71 3.50 1.496 4
+ -lat 10x10-5% 1.00 1.00 0.98 0.98 1.459 1
+ -median 1 1.00 1.97 2.93 3.60 0.270 4
+ -median 2 1.00 2.04 2.93 4.00 0.108 4
+ -minify 1.00 1.69 2.20 2.59 4.828 4
+ -modulate 110/100/95 1.00 1.83 2.47 3.05 2.952 4
+ -motion-blur 0x3+30 1.00 1.98 2.91 3.73 0.351 4
+ +noise Uniform 1.00 1.51 1.87 2.15 3.175 4
+ +noise Gaussian 1.00 1.95 2.85 3.66 0.487 4
+ +noise Multiplicative 1.00 1.94 2.81 3.60 0.760 4
+ +noise Impulse 1.00 1.50 1.86 2.11 3.189 4
+ +noise Laplacian 1.00 1.83 2.61 3.26 1.276 4
+ +noise Poisson 1.00 1.92 2.77 3.53 0.774 4
+ +noise Random 1.00 1.62 2.11 2.48 2.614 4
+ -noise 1 1.00 2.00 2.92 3.89 0.292 4
+ -noise 2 1.00 2.00 2.96 3.96 0.107 4
+ -operator all Add 2% 1.00 1.41 1.69 1.84 7.388 4
+ -operator all Divide 2 1.00 1.50 1.78 1.99 6.903 4
+ -operator all Multiply 0.5 1.00 1.43 1.75 1.94 7.077 4
+ -operator all Subtract 10% 1.00 1.47 1.70 1.86 7.239 4
+ -operator all Noise-Gaussian 30% 1.00 1.99 2.96 3.89 0.521 4
+ -operator all Noise-Impulse 30% 1.00 1.66 2.18 2.59 4.603 4
+ -operator all Noise-Laplacian 30% 1.00 1.86 2.78 3.57 1.460 4
+ -operator all Noise-Multiplicative 30% 1.00 1.95 2.86 3.73 0.910 4
+ -operator all Noise-Poisson 30% 1.00 1.95 2.88 3.76 0.846 4
+ -operator all Noise-Uniform 30% 1.00 1.68 2.23 2.66 4.587 4
+ -ordered-dither all 2x2 1.00 1.20 1.21 1.25 6.655 4
+ -ordered-dither all 3x3 1.00 1.24 1.25 1.32 6.942 4
+ -ordered-dither intensity 3x3 1.00 1.20 1.20 1.27 6.768 4
+ -ordered-dither all 4x4 1.00 1.20 1.21 1.26 6.693 4
+ -paint 0x1 1.00 1.86 2.63 3.31 1.867 4
+ -random-threshold all 20x80 1.00 1.35 1.46 1.55 6.865 4
+ -recolor '0,0,1,0,1,0,1,0,0' 1.00 1.68 2.13 2.45 5.251 4
+ -recolor '0.9,0,0,0,0.9,0,0,0,1.2' 1.00 1.55 1.97 2.25 6.084 4
+ -recolor '.22,.72,.07,.22,.72,.07,.22,.72,.07' 1.00 1.59 1.97 2.24 6.090 4
+ -density 75x75 -resample 50x50 1.00 1.84 2.49 3.15 2.009 4
+ -resize 10% 1.00 1.81 2.46 2.94 3.286 4
+ -resize 50% 1.00 1.82 2.52 3.05 2.349 4
+ -resize 150% 1.00 1.81 2.42 2.93 0.986 4
+ -rotate 15 1.00 1.52 2.13 2.49 0.858 4
+ -rotate 45 1.00 1.68 1.98 2.37 0.519 4
+ -shade 30x30 1.00 1.64 2.12 2.49 4.081 4
+ -sharpen 0x0.5 1.00 1.88 2.74 3.54 1.289 4
+ -sharpen 0x1.0 1.00 1.97 2.92 3.84 0.457 4
+ -sharpen 0x2.0 1.00 2.00 2.97 3.94 0.134 4
+ -shear 45x45 1.00 1.16 1.43 1.63 0.460 4
+ -swirl 90 1.00 1.92 2.73 3.50 1.448 4
+ -fuzz 5% -trim 1.00 1.63 2.04 2.37 5.900 4
+ -unsharp 0x0.5+20+1 1.00 1.59 1.98 2.23 1.110 4
+ -unsharp 0x1.0+20+1 1.00 1.70 2.22 2.57 0.881 4
+ -wave 25x150 1.00 1.84 2.60 3.27 1.918 4
+ ============================================== ===== ===== ===== ===== ======== ====
+
+
+--------------------------------------------------------------------------
+
+| Copyright (C) 2008 - 2017 GraphicsMagick Group
+
+This program is covered by multiple licenses, which are described in
+Copyright.txt. You should have received a copy of Copyright.txt with this
+package; otherwise see http://www.graphicsmagick.org/Copyright.html.
+
diff --git a/www/README.html b/www/README.html
new file mode 100644
index 0000000..9805021
--- /dev/null
+++ b/www/README.html
@@ -0,0 +1,382 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Installing GraphicsMagick</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="installing-graphicsmagick">
+<h1 class="title">Installing GraphicsMagick</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#executive-summary" id="id1">Executive Summary</a></li>
+<li><a class="reference internal" href="#availability" id="id2">Availability</a></li>
+<li><a class="reference internal" href="#documentation" id="id3">Documentation</a></li>
+<li><a class="reference internal" href="#installation" id="id4">Installation</a></li>
+<li><a class="reference internal" href="#add-on-libraries-programs" id="id5">Add-On Libraries &amp; Programs</a></li>
+</ul>
+</div>
+<div class="section" id="executive-summary">
+<h1><a class="toc-backref" href="#id1">Executive Summary</a></h1>
+<p>GraphicsMagick provides a comprehensive collection of utilities,
+programming interfaces, and GUIs, to support file format conversion,
+image processing, and 2D vector rendering.</p>
+<p>GraphicsMagick is originally based on ImageMagick from ImageMagick Studio
+(which was originally written by John Cristy at Dupont). The goal of
+GraphicsMagick is to provide the highest quality product possible while
+encouraging open and active participation from all interested developers.
+The GraphicsMagick usage license is designed to allow it to be used for
+any application, including proprietary or GPLed applications. Please see
+the file <a class="reference external" href="Copyright.html">Copyright.txt</a> for the GraphicsMagick licence.</p>
+</div>
+<div class="section" id="availability">
+<h1><a class="toc-backref" href="#id2">Availability</a></h1>
+<p>The master ftp site for GraphicsMagick distributions is
+<a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/">ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/</a>. Bandwidth on this
+site is very limited, so it is recommended to download from SourceForge
+at <a class="reference external" href="http://sourceforge.net/projects/graphicsmagick/files/">http://sourceforge.net/projects/graphicsmagick/files/</a> if
+possible.</p>
+<p>GraphicsMagick is a continual work in progress. The very latest code
+is available via the Mercurial distributed source control management
+tool (<a class="reference external" href="https://www.mercurial-scm.org/">https://www.mercurial-scm.org/</a>). GraphicsMagick may be retrieved
+via the following command:</p>
+<blockquote>
+hg clone <a class="reference external" href="http://hg.code.sf.net/p/graphicsmagick/code/">http://hg.code.sf.net/p/graphicsmagick/code/</a> GM</blockquote>
+<p>Mercurial provides a complete stand-alone repository which contains
+the full history of the GraphicsMagick project. You may use the
+cloned repository for your own purposes related to GraphicsMagick
+(e.g. manage local GraphicsMagick changes), and can easily pull
+GraphicsMagick updates from the main repository whenever you like.</p>
+</div>
+<div class="section" id="documentation">
+<h1><a class="toc-backref" href="#id3">Documentation</a></h1>
+<blockquote>
+Open the file index.html in a web browser, or refer to the gm(1) manual
+page. Also read the GraphicsMagick frequently asked questions in the
+file <a class="reference external" href="FAQ.html">www/FAQ.html</a>.</blockquote>
+</div>
+<div class="section" id="installation">
+<h1><a class="toc-backref" href="#id4">Installation</a></h1>
+<blockquote>
+<p>GraphicsMagick may be compiled from source code for virtually any
+modern Unix system (including Linux and MacOS X) and Microsoft Windows.
+Installation instructions may be found in the following files (or their
+HTML equivalents):</p>
+<ul>
+<li><p class="first">Unix / Linux / *BSD / MacOS-X / Cygwin / MinGW:</p>
+<p><a class="reference external" href="INSTALL-unix.html">Installation on Unix-like systems</a></p>
+</li>
+<li><p class="first">Microsoft Windows (Via &quot;setup&quot; style installer or from source code):</p>
+<p><a class="reference external" href="INSTALL-windows.html">Installation on Microsoft Windows</a></p>
+</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="add-on-libraries-programs">
+<h1><a class="toc-backref" href="#id5">Add-On Libraries &amp; Programs</a></h1>
+<p>To further enhance the capabilities of GraphicsMagick, you may want to
+get these programs or libraries. Note that these packages are already
+integrated into the GraphicsMagick Mercurial repository for use when
+building under Microsoft Windows:</p>
+<ul>
+<li><p class="first">GraphicsMagick requires the BZLIB library from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.bzip.org/">http://www.bzip.org/</a></p>
+</blockquote>
+<p>to read and write BZip compressed MIFF images.</p>
+</li>
+<li><p class="first">GraphicsMagick requires 'ralcgm' from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.agocg.ac.uk/train/cgm/ralcgm.htm">http://www.agocg.ac.uk/train/cgm/ralcgm.htm</a></p>
+</blockquote>
+<p>to read the Computer Graphics Metafile (CGM) image format. You also
+need Ghostscript and Ghostscript Fonts (see below).</p>
+</li>
+<li><p class="first">GraphicsMagick requires 'dcraw' from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.cybercom.net/~dcoffin/dcraw/">http://www.cybercom.net/~dcoffin/dcraw/</a></p>
+</blockquote>
+<p>to read raw images from digital cameras. Dcraw is invoked
+automatically when used to read files using a common RAW file format
+extension.</p>
+</li>
+<li><p class="first">GraphicsMagick requires 'fig2dev' provided in the transfig package
+from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.xfig.org/">http://www.xfig.org/</a></p>
+</blockquote>
+<p>to read the Fig image format. Ghostscript and Ghostscript Fonts (see
+below) are also required.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the FreeType software, version 2.0 or above,
+available as</p>
+<blockquote>
+<p><a class="reference external" href="http://www.freetype.org/">http://www.freetype.org/</a></p>
+</blockquote>
+<p>to annotate with TrueType and Postscript Type 1 fonts.</p>
+</li>
+<li><p class="first">GraphicsMagick requires Ghostscript software (version 9.04
+recommended) available from</p>
+<blockquote>
+<p><a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">http://pages.cs.wisc.edu/~ghost/</a></p>
+<blockquote>
+<p>or</p>
+</blockquote>
+<p><a class="reference external" href="http://sourceforge.net/projects/ghostscript/">http://sourceforge.net/projects/ghostscript/</a></p>
+</blockquote>
+<p>to read the Postscript or the Portable Document Format (PDF).</p>
+<p>Ghostscript Fonts are available from</p>
+<blockquote>
+<p><a class="reference external" href="https://sourceforge.net/projects/gs-fonts/">https://sourceforge.net/projects/gs-fonts/</a></p>
+</blockquote>
+<p>Ghostscript is available for use under both free (GPL) and
+commercial licenses. We are not lawyers so we can not provide
+advice as to when the commercial license from Artifex is required.
+Please make sure that you are aware of Ghostscript licencing and
+usage terms if you plan to use it in some sort of commercial
+situation.</p>
+<p>Ghostscript (release 7.0 and later) may optionally install a library
+(libgs) under Linux. If this library is installed, GraphicsMagick may
+be configured to use it. We do <strong>NOT</strong> recommend using this library
+under Unix type systems. The Ghostscript library does not support
+concurrency since only one instance of the interpreter is available.
+Unix systems will obtain better performance from executing Ghostscript as
+an external process since then multiple interpreters may execute at
+once on multiple CPU cores.</p>
+<p>If the Ghostscript library is used, then please be aware that
+Ghostscript provides its own modified version of libjpeg and
+libJasper while GraphicsMagick will be using these libraries as
+provided with the system. If Ghostscript is not using the same
+libraries, then identically named symbols may be used from the wrong
+code, causing confusion or a program crash. If conflicts cause JPEG
+to fail (JPEG returns an error regarding expected structure sizes),
+it may be necessary to use Ghostscript's copy of libjpeg for
+GraphicsMagick, and all delegate libraries which depend on libjpeg,
+or convince Ghostscript to build against an unmodified installed
+JPEG library (and lose compatibility with some Postscript files).</p>
+</li>
+<li><p class="first">GraphicsMagick requires hp2xx available from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.gnu.org/software/hp2xx/hp2xx.html">http://www.gnu.org/software/hp2xx/hp2xx.html</a></p>
+</blockquote>
+<p>to read the HP-GL image format. Note that HPGL is a plotter file
+format. HP printers usually accept PCL format rather than HPGL
+format. Ghostscript (see above) is also required.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the lcms library (2.0 or later) available
+from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.littlecms.com/">http://www.littlecms.com/</a></p>
+</blockquote>
+<p>to perform ICC CMS color management.</p>
+</li>
+<li><p class="first">GraphicsMagick requires Graphviz available from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.graphviz.org/">http://www.graphviz.org/</a></p>
+</blockquote>
+<p>to read Graphvis 'dot' digraph files (with extension dot).
+Ghostscript (see above) is also required.</p>
+</li>
+<li><p class="first">GraphicsMagick requires html2ps available from</p>
+<blockquote>
+<p><a class="reference external" href="http://user.it.uu.se/~jan/html2ps.html">http://user.it.uu.se/~jan/html2ps.html</a></p>
+</blockquote>
+<p>to rasterize HTML files. Ghostscript (see above) is also required.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the JBIG-Kit software available via
+HTTP from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.cl.cam.ac.uk/~mgk25/jbigkit/">http://www.cl.cam.ac.uk/~mgk25/jbigkit/</a></p>
+</blockquote>
+<p>to read and write the JBIG image format.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the WebP library version 0.1.99 (or later)
+available via HTTPS from</p>
+<blockquote>
+<p><a class="reference external" href="https://developers.google.com/speed/webp/">https://developers.google.com/speed/webp/</a></p>
+</blockquote>
+<p>to read and write the WebP image format.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the Independent JPEG Group's software
+available from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.ijg.org/">http://www.ijg.org/</a></p>
+</blockquote>
+<p>to read and write the JPEG v1 image format.</p>
+<p>Apply this JPEG patch to Independent JPEG Group's (6b release!)
+source distribution if you want to read lossless jpeg-encoded DICOM
+(medical) images:</p>
+<blockquote>
+<p><a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/delegates/ljpeg-6b.tar.gz">ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/delegates/ljpeg-6b.tar.gz</a></p>
+</blockquote>
+<p>Use of lossless JPEG is not encouraged. Unless you have a requirement
+to read lossless jpeg-encoded DICOM images, please disregard the patch.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the JasPer Project's JasPer library version
+1.701.0 (or later) available via http from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.ece.uvic.ca/~mdadams/jasper/">http://www.ece.uvic.ca/~mdadams/jasper/</a></p>
+</blockquote>
+<p>to read and write the JPEG-2000 format. Please note that JasPer 1.900.1
+may have a problem when used with GraphicsMagick's modules build. To
+solve this problem, edit the file src/libjasper/base/jas_init.c and
+comment out the line which invokes atexit().</p>
+</li>
+<li><p class="first">On Unix-type systems, Windows/MinGW, and Windows/Cygwin,
+GraphicsMagick requires libltdl from libtool in order to support
+building GraphicsMagick with dynamically loadable modules. Libtool
+is available via anonymous FTP from</p>
+<blockquote>
+<p><a class="reference external" href="ftp://ftp.gnu.org/pub/gnu/libtool/">ftp://ftp.gnu.org/pub/gnu/libtool/</a></p>
+</blockquote>
+</li>
+<li><p class="first">GraphicsMagick requires the MPEG utilities from the MPEG Software
+Simulation Group, which are available via anonymous FTP as</p>
+<blockquote>
+<p><a class="reference external" href="ftp://ftp.GraphicsMagick.org/pub/GraphicsMagick/delegates/mpeg2vidcodec_v12.tar.gz">ftp://ftp.GraphicsMagick.org/pub/GraphicsMagick/delegates/mpeg2vidcodec_v12.tar.gz</a></p>
+</blockquote>
+<p>to read or write the MPEG image format.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the LIBPNG library, version 1.0 or above, from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.libpng.org/pub/png/pngcode.html">http://www.libpng.org/pub/png/pngcode.html</a></p>
+</blockquote>
+<p>to read or write the PNG, MNG, or JNG image formats. LIBPNG depends
+upon the ZLIB library (see below).</p>
+</li>
+<li><p class="first">GraphicsMagick requires Sam Leffler's TIFF software available via
+HTTP at</p>
+<blockquote>
+<p><a class="reference external" href="http://www.simplesystems.org/libtiff/">http://www.simplesystems.org/libtiff/</a></p>
+</blockquote>
+<p>to read the TIFF image format. It in turn optionally requires the
+JPEG and ZLIB libraries. Libtiff 3.8.2 or later is recommended.</p>
+</li>
+<li><p class="first">GraphicsMagick may optionally use the TRIO library from</p>
+<blockquote>
+<p><a class="reference external" href="http://sourceforge.net/projects/ctrio/">http://sourceforge.net/projects/ctrio/</a></p>
+</blockquote>
+<p>to substitute for the vsnprintf function when the operating system
+does not provide one. Older operating systems (e.g. Solaris 2.5)
+may not provide a vsnprintf function. If vsnprintf (or the TRIO
+replacement) is not used, then vsprintf is used instead, which
+decreases the security of GraphicsMagick due to possible buffer
+overrun exploits.</p>
+</li>
+<li><p class="first">GraphicsMagick may optionally use the umem memory allocation library
+which is included in Sun's Solaris operating system or available from</p>
+<blockquote>
+<p><a class="reference external" href="https://labs.omniti.com/trac/portableumem">https://labs.omniti.com/trac/portableumem</a></p>
+</blockquote>
+<p>to provide enhanced versions of the standard memory allocation
+facilities. Use of umem may improve performance for multi-threaded
+programs and provides access to debugging features that detect memory
+leaks, buffer overruns, multiple frees, use of uninitialized data, use
+of freed data, and many other common programming errors.</p>
+</li>
+<li><p class="first">GraphicsMagick requires libwmflite from libwmf 0.2.5 (or later) from</p>
+<blockquote>
+<p><a class="reference external" href="http://sourceforge.net/projects/wvware/">http://sourceforge.net/projects/wvware/</a></p>
+</blockquote>
+<p>to render files in the Windows Meta File (WMF) metafile format
+(16-bit WMF files only, not 32-bit &quot;EMF&quot;). This is the format
+commonly used for Windows clipart (available on CD at your local
+computer or technical book store). WMF support requires the FreeType
+2 library in order to render TrueType and Postscript fonts.</p>
+<p>While GraphicsMagick uses the libwmflite (parser) component of the
+libwmf package which does not depend on any special libraries, the
+libwmf package as a whole depends on FreeType 2 and either the
+xmlsoft libxml, or expat libraries. Since GraphicsMagick already uses
+libxml (for reading SVG and to retrieve files via HTTP or FTP), it is
+recommended that the options '--without-expat --with-xml' be supplied
+to libwmf's configure script. If the other features of libwmf are
+not needed, then the '--disable-heavy' option may be used to only
+build libwmflite.</p>
+<p>GraphicsMagick's WMF renderer provides some of the finest WMF
+rendering available due its use of antialiased drawing algorithms.
+You may select a background color or texture image to render on. For
+example, &quot;-background '#ffffffff'&quot; renders on a transparent
+background while &quot;-texture plasma:fractal&quot; renders on a fractal image.</p>
+<blockquote>
+<p>A free set of Microsoft Windows fonts may be retrieved from
+<a class="reference external" href="http://sourceforge.net/projects/corefonts/">http://sourceforge.net/projects/corefonts/</a>. Note that the license
+for these fonts requires that they be distributed in the original
+.exe form, but the Linux folks have found ways to deal with that on
+non-Windows systems.</p>
+</blockquote>
+</li>
+<li><p class="first">GraphicsMagick requires an X server for the 'display', 'animate', and
+'import' functions to work properly. Unix systems usually provide an X
+server as part of their standard installation. For MacOS-X, X11 is a
+system install time option.</p>
+<p>A free X server for Microsoft Windows is included as part of
+Cygwin and may be selected from the Cygwin installer. Cygwin is
+available from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.cygwin.com/">http://www.cygwin.com/</a></p>
+</blockquote>
+<p>There is a nearly free X server available for Windows and Macintosh at</p>
+<blockquote>
+<p><a class="reference external" href="http://www.microimages.com/downloads/mix/">http://www.microimages.com/downloads/mix/</a></p>
+</blockquote>
+</li>
+<li><p class="first">GraphicsMagick requires libxml2 available from</p>
+<blockquote>
+<p><a class="reference external" href="http://xmlsoft.org/">http://xmlsoft.org/</a></p>
+</blockquote>
+<p>to read the SVG image format and to retrieve files from over a
+network via FTP and HTTP.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the liblzma library from XZ Utils available from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.tukaani.org/xz/">http://www.tukaani.org/xz/</a></p>
+</blockquote>
+<p>to support TIFF with LZMA compression and future LZMA-compression
+features (yet to be developed). The utilities from this package are
+also necessary in order to decompress GraphicsMagick packages
+distributed with &quot;.xz&quot; or &quot;.lzma&quot; extensions.</p>
+</li>
+<li><p class="first">GraphicsMagick requires the ZLIB library from</p>
+<blockquote>
+<p><a class="reference external" href="http://www.zlib.net/">http://www.zlib.net/</a></p>
+</blockquote>
+<p>to read or write the PNG or Zip compressed MIFF images.</p>
+</li>
+</ul>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/animate.html b/www/animate.html
new file mode 100644
index 0000000..eeb8de4
--- /dev/null
+++ b/www/animate.html
@@ -0,0 +1,943 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="animate"></a>gm animate
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#desc">Description</a>
+</dt>
+<dt>
+<a href="#exam">Examples</a>
+</dt>
+<dt>
+<a href="#opti">Options</a>
+</dt>
+<dt>
+<a href="#mous">Mouse Buttons</a>
+</dt>
+<dt>
+<a href="#comm">Command Widget</a>
+</dt>
+<dt>
+<a href="#keyb">Keyboard Accelerators</a>
+</dt>
+<dt>
+<a href="#xres">X Resources</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm animate</strong> <strong>[</strong> <em>options</em> <strong>...]</strong> <em>file</em> [ [
+<em>options</em> ...] <em>file</em> ...]
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Animate</strong> displays a sequence of images on any workstation display
+running an X server. <strong>animate</strong> first determines the hardware capabilities
+of the workstation. If the number of unique colors in an image is less
+than or equal to the number the workstation can support, the image is displayed
+in an X window. Otherwise the number of colors in the image is first reduced
+to match the color resolution of the workstation before it is displayed.
+<p>
+This means that a continuous-tone 24 bits-per-pixel image can display on
+a 8 bit pseudo-color device or monochrome device. In most instances the
+reduced color image closely resembles the original. Alternatively, a monochrome
+or pseudo-color image sequence can display on a continuous-tone 24 bits-per-pixel
+device.
+<p>
+To help prevent color flashing on X server visuals that have colormaps,
+<strong>animate</strong>
+creates a single colormap from the image sequence. This can be rather time
+consuming. You can speed this operation up by reducing the colors in the
+image before you "animate" them. Use <strong>mogrify</strong> to color reduce the
+images to a single colormap. See <strong>mogrify(1)</strong> for details. Alternatively,
+you can use a Standard Colormap; or a static, direct, or true color visual.
+You can define a Standard Colormap with <em>xstdcmap</em>. See <strong>xstdcmap(1)</strong>
+for details. This method is recommended for colormapped X server because
+it eliminates the need to compute a global colormap.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To animate a set of images of a cockatoo, use:
+<pre>
+ gm animate cockatoo.*
+</pre>
+<p>
+To animate a cockatoo image sequence while using the Standard Colormap
+<em>best</em>, use:
+<pre>
+ xstdcmap -best
+ gm animate -map best cockatoo.*
+</pre>
+<p>
+To animate an image of a cockatoo without a border centered on a backdrop,
+use:
+<br>&nbsp;<br>
+<pre>
+ gm animate +borderwidth -backdrop cockatoo.*
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-backdrop">-backdrop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the image centered on a backdrop.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -borderwidth <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-chop">-chop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixels from the interior of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colormap">-colormap</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the colormap type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-foreground">-foreground</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the foreground color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-iconGeometry">-iconGeometry</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the icon geometry</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -iconic
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>iconic animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-map">-map</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display image using this type.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -name
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pause">-pause</a> <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pause between animation loops [animate]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-remote">-remote</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform a X11 remote operation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scenes">-scenes</a> <i>&lt;value-value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>range of image scene numbers to read</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shared-memory">-shared-memory</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use shared memory</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-text-font">-text-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>font for writing fixed-width text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-title">-title</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign title to displayed image [<em>animate, display, montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-visual">-visual</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>animate images using this X visual type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-window">-window</a> <i>&lt;id&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image the background of a window</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<p>
+Any option you specify on the command line remains in effect for the group
+of images following it, until the group is terminated by the appearance of
+any option or <strong>-noop</strong>. For example, to animate three images, the first
+with 32 colors, the second with an unlimited number of colors, and the
+third with only 16 colors, use:
+<br>&nbsp;<br>
+<pre>
+ gm animate -colors 32 cockatoo.1 -noop cockatoo.2 -colors 16 cockatoo.3
+</pre>
+<p>
+<strong>Animate</strong> options can appear on the command line or in your X resources
+file. See <em>X(1)</em>. Options on the command line supersede values specified
+in your X resources file.
+<p>Image filenames may appear in any order on the command line if the image
+format is <em>MIFF</em> (refer to <strong>miff(5)</strong> and the
+<strong>scene</strong> keyword
+is specified in the image. Otherwise the images will display in the order
+they appear on the command line.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mous"></a>Mouse Buttons
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Press any button to map or unmap the Command widget. See the next section
+for more information about the Command widget.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comm"></a>Command Widget
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The Command widget lists a number of sub-menus and commands. They are
+<ul>
+<li><strong>Animate</strong>
+<ul>
+<li> Open
+<li> Play
+<li> Step
+<li> Repeat
+<li> Auto Reverse
+</ul>
+<li><strong>Speed</strong>
+<ul>
+<li> Faster
+<li> Slower
+</ul>
+<li><strong>Direction</strong>
+<ul>
+<li> Forward
+<li> Reverse
+</ul>
+<li><strong>Image Info</strong>
+<li><strong>Help</strong>
+<li><strong>Quit</strong>
+</ul>
+<p>
+Menu items with a indented triangle have a sub-menu. They are represented
+above as the indented items. To access a sub-menu item, move the pointer
+to the appropriate menu and press a button and drag. When you find the
+desired sub-menu item, release the button and the command is executed.
+Move the pointer away from the sub-menu if you decide not to execute a
+particular command.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="keyb"></a>Keyboard Accelerators
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt><strong>Ctl+O</strong></dt>
+<dd>Press to load an image from a file.</dd>
+<dt><strong>space</strong></dt>
+<dd>Press to display the next image in the sequence.</dd>
+<dt><strong>&lt;</strong></dt>
+<dd>Press to speed-up the display of the images. Refer to
+<strong>-delay</strong> for more information.</dd>
+<dt><strong>&gt;</strong></dt>
+<dd>Press to slow the display of the images. Refer to
+<strong>-delay</strong> for more information.</dd>
+<dt><strong>?</strong></dt>
+<dd>Press to display information about the image. Press
+any key or button to erase the information.</dd>
+<dd>This information is printed: image name; image size;
+and the total number of unique colors in the image.</dd>
+<dt><strong>F1</strong></dt>
+<dd>Press to display helpful information about <strong>animate(1)</strong>.</dd>
+<dt><strong>Ctl-q</strong></dt>
+<dd>Press to discard all images and exit program.</dd>
+</dl>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="xres"></a>X Resources
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Animate</strong> options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See <strong>X(1)</strong> for more information on X resources.
+<p>
+All <strong>animate</strong> options have a corresponding X resource. In addition,
+the <strong>animate</strong> program uses the following X resources:
+<dl>
+<dt><strong>background</strong> <strong>(</strong><em>class</em> <strong>Background)</strong></dt>
+<dd>
+Specifies the preferred color to use for the Image window background. The
+default is #ccc.</dd>
+<dt><strong>borderColor</strong> <strong>(</strong><em>class</em> <strong>BorderColor)</strong></dt>
+<dd>
+Specifies the preferred color to use for the Image window border. The default
+is #ccc.</dd>
+<dt><strong>borderWidth</strong> <strong>(</strong><em>class</em> <strong>BorderWidth)</strong></dt>
+<dd>
+Specifies the width in pixels of the Image window border. The default is
+2.</dd>
+<dt><strong>font</strong> <strong>(</strong><em>class</em> <strong>Font</strong> <strong>or</strong> <strong>FontList)</strong></dt>
+<dd>
+Specifies the name of the preferred font to use in normal formatted text.
+The default is 14 point <em>Helvetica</em>.</dd>
+<dt><strong>foreground</strong> <strong>(</strong><em>class</em> <strong>Foreground)</strong></dt>
+<dd>
+Specifies the preferred color to use for text within the Image window.
+The default is black.</dd>
+<dt><strong>geometry</strong> <strong>(</strong><em>class</em> <strong>geometry)</strong></dt>
+<dd>
+Specifies the preferred size and position of the image window. It is not
+necessarily obeyed by all window managers.
+Offsets, if present, are handled in <em>X(1)</em> style. A negative x offset is
+measured from the right edge of the screen to the right edge of the icon,
+and a negative y offset is measured from the bottom edge of the screen
+to the bottom edge of the icon.</dd>
+<dt><strong>iconGeometry</strong> <strong>(</strong><em>class</em> <strong>IconGeometry)</strong></dt>
+<dd>
+Specifies the preferred size and position of the application when iconified.
+It is not necessarily obeyed by all window managers.
+Offsets, if present, are handled in the same manner as in class Geometry.</dd>
+<dt><strong>iconic</strong> <strong>(</strong><em>class</em> <strong>Iconic)</strong></dt>
+<dd>
+This resource indicates that you would prefer that the application's windows
+initially not be visible as if the windows had be immediately iconified
+by you. Window managers may choose not to honor the application's request.</dd>
+<dt><strong>matteColor</strong> <strong>(</strong><em>class</em> <strong>MatteColor)</strong></dt>
+<dd>
+Specify the color of windows. It is used for the backgrounds of windows,
+menus, and notices. A 3D effect is achieved by using highlight and shadow
+colors derived from this color. Default value: #ddd.</dd>
+<dt><strong>name</strong> <strong>(</strong><em>class</em> <strong>Name)</strong></dt>
+<dd>
+This resource specifies the name under which resources for the application
+should be found. This resource is useful in shell aliases to distinguish
+between invocations of an application, without resorting to creating links
+to alter the executable file name. The default is the application name.</dd>
+<dt><strong>sharedMemory</strong> <strong>(</strong><em>class</em> <strong>SharedMemory)</strong></dt>
+<dd>
+This resource specifies whether animate should attempt use shared memory
+for pixmaps. ImageMagick must be compiled with shared memory support, and
+the display must support the MIT-SHM extension. Otherwise, this resource
+is ignored. The default is True.</dd>
+<dt><strong>text_font</strong> <strong>(</strong><em>class</em> <strong>textFont)</strong></dt>
+<dd>
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point <em>Courier</em>.</dd>
+<dt><strong>title</strong> <strong>(</strong><em>class</em> <strong>Title)</strong></dt>
+<dd>
+This resource specifies the title to be used for the Image window. This
+information is sometimes used by a window manager to provide some sort
+of header identifying the window. The default is the image file name.</dd>
+</dl>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
diff --git a/www/api/Makefile.am b/www/api/Makefile.am
new file mode 100644
index 0000000..a9d7f9a
--- /dev/null
+++ b/www/api/Makefile.am
@@ -0,0 +1,144 @@
+# Copyright (C) 2008-2011 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building API HTML files
+#
+
+wwwapidir = $(htmldir)/api
+
+WWWAPIDIR = $(top_srcdir)/www/api
+
+WWWAPI_HTML_TARGETS = \
+ $(WWWAPIDIR)/animate.html \
+ $(WWWAPIDIR)/annotate.html \
+ $(WWWAPIDIR)/attribute.html \
+ $(WWWAPIDIR)/average.html \
+ $(WWWAPIDIR)/blob.html \
+ $(WWWAPIDIR)/cdl.html \
+ $(WWWAPIDIR)/channel.html \
+ $(WWWAPIDIR)/color.html \
+ $(WWWAPIDIR)/colormap.html \
+ $(WWWAPIDIR)/compare.html \
+ $(WWWAPIDIR)/composite.html \
+ $(WWWAPIDIR)/confirm_access.html \
+ $(WWWAPIDIR)/constitute.html \
+ $(WWWAPIDIR)/decorate.html \
+ $(WWWAPIDIR)/deprecate.html \
+ $(WWWAPIDIR)/describe.html \
+ $(WWWAPIDIR)/display.html \
+ $(WWWAPIDIR)/draw.html \
+ $(WWWAPIDIR)/effect.html \
+ $(WWWAPIDIR)/enhance.html \
+ $(WWWAPIDIR)/error.html \
+ $(WWWAPIDIR)/export.html \
+ $(WWWAPIDIR)/fx.html \
+ $(WWWAPIDIR)/hclut.html \
+ $(WWWAPIDIR)/image.html \
+ $(WWWAPIDIR)/import.html \
+ $(WWWAPIDIR)/list.html \
+ $(WWWAPIDIR)/magick.html \
+ $(WWWAPIDIR)/memory.html \
+ $(WWWAPIDIR)/monitor.html \
+ $(WWWAPIDIR)/montage.html \
+ $(WWWAPIDIR)/operator.html \
+ $(WWWAPIDIR)/paint.html \
+ $(WWWAPIDIR)/pixel_cache.html \
+ $(WWWAPIDIR)/pixel_iterator.html \
+ $(WWWAPIDIR)/plasma.html \
+ $(WWWAPIDIR)/profile.html \
+ $(WWWAPIDIR)/quantize.html \
+ $(WWWAPIDIR)/registry.html \
+ $(WWWAPIDIR)/render.html \
+ $(WWWAPIDIR)/resize.html \
+ $(WWWAPIDIR)/resource.html \
+ $(WWWAPIDIR)/segment.html \
+ $(WWWAPIDIR)/shear.html \
+ $(WWWAPIDIR)/signature.html \
+ $(WWWAPIDIR)/statistics.html \
+ $(WWWAPIDIR)/texture.html \
+ $(WWWAPIDIR)/transform.html \
+ $(WWWAPIDIR)/types.html \
+ $(WWWAPIDIR)/widget.html
+
+WWWWAPI_FILES = \
+ www/api/animate.html \
+ www/api/annotate.html \
+ www/api/api_hyperlinks.rst \
+ www/api/attribute.html \
+ www/api/average.html \
+ www/api/blob.html \
+ www/api/cdl.html \
+ www/api/channel.html \
+ www/api/color.html \
+ www/api/colormap.html \
+ www/api/compare.html \
+ www/api/composite.html \
+ www/api/confirm_access.html \
+ www/api/constitute.html \
+ www/api/decorate.html \
+ www/api/deprecate.html \
+ www/api/describe.html \
+ www/api/display.html \
+ www/api/draw.html \
+ www/api/effect.html \
+ www/api/export.html \
+ www/api/enhance.html \
+ www/api/error.html \
+ www/api/fx.html \
+ www/api/hclut.html \
+ www/api/image.html \
+ www/api/import.html \
+ www/api/list.html \
+ www/api/magick.html \
+ www/api/memory.html \
+ www/api/monitor.html \
+ www/api/montage.html \
+ www/api/operator.html \
+ www/api/paint.html \
+ www/api/pixel_cache.html \
+ www/api/pixel_iterator.html \
+ www/api/plasma.html \
+ www/api/profile.html \
+ www/api/quantize.html \
+ www/api/registry.html \
+ www/api/render.html \
+ www/api/resize.html \
+ www/api/resource.html \
+ www/api/segment.html \
+ www/api/shear.html \
+ www/api/signature.html \
+ www/api/statistics.html \
+ www/api/texture.html \
+ www/api/transform.html \
+ www/api/types.html \
+ www/api/widget.html
+
+WWWAPI_EXTRA_DIST = \
+ $(WWWWAPI_FILES)
+
+WWWAPI_MAINTAINER_TARGETS = $(WWWAPI_HTML_TARGETS)
+
+if MAINTAINER_MODE
+
+if HasRST2HTML
+APIWHATIS = $(top_srcdir)/scripts/whatis.txt
+FORMATCAPI = $(top_srcdir)/scripts/format_c_api_doc.py
+
+APIRST2HTML_COMMAND = $(RST2HTMLDECO) \
+ --link-stylesheet=../docutils-articles.css`
+
+$(WWWAPI_HTML_TARGETS) : $(FORMATCAPI) $(RST2HTMLDECO) $(APIWHATIS) $(top_srcdir)/scripts/html_fragments.py $(top_srcdir)/www/api/Makefile.am $(top_srcdir)/www/api/api_hyperlinks.rst
+
+$(WWWAPIDIR)/%.apirst : $(top_srcdir)/magick/%.c
+ $(FORMATCAPI) --whatis-file $(APIWHATIS) $< $@
+
+$(WWWAPIDIR)/%.html : $(WWWAPIDIR)/%.apirst
+ $(RST2HTMLDECO) --link-stylesheet=`$(RELPATH) $(top_srcdir)/www $@`docutils-api.css \
+ --url-prefix=`$(RELPATH) $(top_srcdir)/www $@` $< $@
+
+endif # HasRST2HTML
+
+endif # MAINTAINER_MODE
diff --git a/www/api/animate.html b/www/api/animate.html
new file mode 100644
index 0000000..61d32b4
--- /dev/null
+++ b/www/api/animate.html
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>animate</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="animate">
+<h1 class="title">animate</h1>
+<h2 class="subtitle" id="interactively-animate-an-image-sequence">Interactively animate an image sequence</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#magickxanimatebackgroundimage" id="id3">MagickXAnimateBackgroundImage</a></li>
+<li><a class="reference internal" href="#magickxanimateimages" id="id4">MagickXAnimateImages</a></li>
+</ul>
+</div>
+<div class="section" id="magickxanimatebackgroundimage">
+<h1><a class="toc-backref" href="#id3">MagickXAnimateBackgroundImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXAnimateBackgroundImage( Display *display, <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>MagickXAnimateBackgroundImage() animates an image sequence in the background of
+a window.</p>
+<p>The format of the MagickXAnimateBackgroundImage method is:</p>
+<pre class="literal-block">
+void MagickXAnimateBackgroundImage( Display *display, <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>resource_info:</dt>
+<dd>Specifies a pointer to a X11 MagickXResourceInfo structure.</dd>
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickxanimateimages">
+<h1><a class="toc-backref" href="#id4">MagickXAnimateImages</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MagickXAnimateImages( Display *display, <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ char ** argv, const int argc, <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>MagickXAnimateImages() displays an image via X11.</p>
+<p>The format of the MagickXAnimateImages method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MagickXAnimateImages( Display *display, <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ char ** argv, const int argc, <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>resource_info:</dt>
+<dd>Specifies a pointer to a X11 MagickXResourceInfo structure.</dd>
+<dt>argv:</dt>
+<dd>Specifies the application's argument list.</dd>
+<dt>argc:</dt>
+<dd>Specifies the number of arguments.</dd>
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/annotate.html b/www/api/annotate.html
new file mode 100644
index 0000000..dd0cf82
--- /dev/null
+++ b/www/api/annotate.html
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>annotate</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="annotate">
+<h1 class="title">annotate</h1>
+<h2 class="subtitle" id="annotate-an-image-with-text">Annotate an image with text</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#annotateimage" id="id3">AnnotateImage</a></li>
+<li><a class="reference internal" href="#gettypemetrics" id="id4">GetTypeMetrics</a></li>
+</ul>
+</div>
+<div class="section" id="annotateimage">
+<h1><a class="toc-backref" href="#id3">AnnotateImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int AnnotateImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AnnotateImage() annotates an image with text. Optionally you can include
+any of the following bits of information about the image by embedding
+the appropriate special characters:</p>
+<p>%b file size
+%c comment
+%d directory
+%e filename extension
+%f filename
+%g page dimensions and offsets
+%h height
+%i input filename
+%k number of unique colors
+%l label
+%m magick
+%n number of scenes
+%o output filename
+%p page number
+%q image bit depth
+%r image type description
+%s scene number
+%t top of filename
+%w width
+%x horizontal resolution
+%y vertical resolution
+%A transparency supported
+%C compression type
+%D GIF disposal method
+%G Original width and height
+%H page height
+%M original filename specification
+%O page offset (x,y)
+%P page dimensions (width,height)
+%T time delay (in centi-seconds)
+%U resolution units
+%W page width
+%X page horizontal offset (x)
+%Y page vertical offset (y)
+%&#64; trim bounding box
+%[a] named attribute 'a'
+%# signature
+n newline
+r carriage return
+%% % (literal)</p>
+<p>The format of the AnnotateImage method is:</p>
+<pre class="literal-block">
+unsigned int AnnotateImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method AnnotateImage returns True if the image is annotated
+otherwise False.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>draw_info:</dt>
+<dd>The draw info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="gettypemetrics">
+<h1><a class="toc-backref" href="#id4">GetTypeMetrics</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int GetTypeMetrics( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info,
+ <a class="reference external" href="../api/types.html#typemetric">TypeMetric</a> *metrics );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>GetTypeMetrics() returns the following information for the specified font
+and text:</p>
+<p>o character width
+o character height
+o ascent
+o descent
+o text width
+o text height
+o maximum horizontal advance
+o underline position
+o underline thickness</p>
+<p>The format of the GetTypeMetrics method is:</p>
+<pre class="literal-block">
+unsigned int GetTypeMetrics( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info,
+ <a class="reference external" href="../api/types.html#typemetric">TypeMetric</a> *metrics );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>draw_info:</dt>
+<dd>The draw info.</dd>
+<dt>metrics:</dt>
+<dd>Return the font metrics in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/api.html b/www/api/api.html
new file mode 100644
index 0000000..e7c4449
--- /dev/null
+++ b/www/api/api.html
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Core C API</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-core-c-api">
+<h1 class="title">GraphicsMagick Core C API</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The GraphicsMagick core C library constitutes the implementation of
+GraphicsMagick and provides the lowest-level C language programming
+interface for GraphicsMagick. The core C API provides many functions
+to read, manipulate, write, or display an image. To invoke the
+functions, write your program in C (or C++) language while making
+calls to the core library functions and link with libGraphicsMagick.a,
+libGraphicsMagick.so, or GraphicsMagick.dll depending on your system.</p>
+<p>The API is divided into a number of categories. While reading this
+documentation, please reference the <a class="reference external" href="types.html">types</a> documentation as required:</p>
+<blockquote>
+<ul class="simple">
+<li><a class="reference external" href="animate.html">Animate</a>: Interactively animate an image sequence</li>
+<li><a class="reference external" href="annotate.html">Annotate</a>: Annotate an image with text</li>
+<li><a class="reference external" href="attribute.html">Attribute</a>: Access key, value image attributes</li>
+<li><a class="reference external" href="average.html">Average</a>: Average several images together</li>
+<li><a class="reference external" href="cdl.html">ASC CDL</a> : Apply ASC CDL to image</li>
+<li><a class="reference external" href="blob.html">Blob</a>: Read and write images to memory</li>
+<li><a class="reference external" href="channel.html">Channel</a>: Import and export image channels as well as compute channel depth</li>
+<li><a class="reference external" href="color.html">Color</a>: Methods to deal with image colors</li>
+<li><a class="reference external" href="colormap.html">Colormap</a>: Methods to deal with image colormaps</li>
+<li><a class="reference external" href="compare.html">Compare</a>: Compare images</li>
+<li><a class="reference external" href="composite.html">Composite</a>: Composite images</li>
+<li><a class="reference external" href="confirm_access.html">Confirm Access</a> : Confirm access to files and URLs.</li>
+<li><a class="reference external" href="constitute.html">Constitute</a>: Read, write, import, and export images</li>
+<li><a class="reference external" href="decorate.html">Decorate</a>: Add fancy borders to images</li>
+<li><a class="reference external" href="describe.html">Describe</a>: Describe an image</li>
+<li><a class="reference external" href="display.html">Display</a>: Interactively display and edit an image</li>
+<li><a class="reference external" href="draw.html">Draw</a>: Convenient methods to draw vectors and text</li>
+<li><a class="reference external" href="effect.html">Effect</a>:Threshold (various), blur, despeckle, edge, emboss, enhance,
+gaussian blur ...</li>
+<li><a class="reference external" href="enhance.html">Enhance</a>: Contrast, equalize, gamma, level, level channel, modulate, negate,
+and normalize</li>
+<li><a class="reference external" href="error.html">Error</a>: Error reporting methods</li>
+<li><a class="reference external" href="export.html">Export</a> : Export image pixels to common representations</li>
+<li><a class="reference external" href="fx.html">FX</a>: Special effects methods</li>
+<li><a class="reference external" href="hclut.html">Hald CLUT</a> : Apply Hald CLUT to image</li>
+<li><a class="reference external" href="image.html">Image</a>: Miscellaneous image methods</li>
+<li><a class="reference external" href="import.html">Import</a> : Import image pixels from common representations</li>
+<li><a class="reference external" href="list.html">List</a>: Manage image lists</li>
+<li><a class="reference external" href="magick.html">Magick</a>: Image format support interfaces</li>
+<li><a class="reference external" href="memory.html">Memory</a>: Memory allocation methods</li>
+<li><a class="reference external" href="monitor.html">Monitor</a>: Progress monitor callbacks</li>
+<li><a class="reference external" href="montage.html">Montage</a>: Create a montage of image thumbnails</li>
+<li><a class="reference external" href="operator.html">Operator</a>: Methods to apply mathematic or boolean operators to pixels</li>
+<li><a class="reference external" href="paint.html">Paint</a>: Fill pixel regions</li>
+<li><a class="reference external" href="pixel_cache.html">Pixel Cache</a>: Low-level access to image pixels</li>
+<li><a class="reference external" href="pixel_iterator.html">Pixel Iterator</a>: Pixel iterator design pattern support functions</li>
+<li><a class="reference external" href="plasma.html">Plasma</a>: Plasma fractal image generator</li>
+<li><a class="reference external" href="profile.html">Profile</a>: Attached profile access</li>
+<li><a class="reference external" href="quantize.html">Quantize</a>: Reduce image colors or assign image colors from colormap</li>
+<li><a class="reference external" href="registry.html">Registry</a>: Store and retrieve images in memory by ID</li>
+<li><a class="reference external" href="resize.html">Resize</a>: Resize an Image</li>
+<li><a class="reference external" href="resource.html">Resource</a>: Set and get resource limits</li>
+<li><a class="reference external" href="segment.html">Segment</a>: Coalese similar image colors</li>
+<li><a class="reference external" href="shear.html">Shear</a>: Rotate image, shear image, or apply a 2D affine transformation</li>
+<li><a class="reference external" href="signature.html">Signature</a>: Compute an image signature (checksum)</li>
+<li><a class="reference external" href="statistics.html">Statistics</a>: Compute image statistics</li>
+<li><a class="reference external" href="texture.html">Texture</a>: Create a tiled texture image or tile an image with a texture.</li>
+<li><a class="reference external" href="transform.html">Transform</a>: Chop, coalesce, deconstruct, flatten, flip, flop, mosiac, roll,
+or shave image</li>
+</ul>
+</blockquote>
+<p>Here are a few sample programs to get you started.</p>
+<p>This example program (convert.c) simply converts from one file name to
+another (and will automatically change formats based on file
+extension):</p>
+<pre class="literal-block">
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;time.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;magick/api.h&gt;
+
+int main ( int argc, char **argv )
+{
+ Image
+ *image = (Image *) NULL;
+
+ char
+ infile[MaxTextExtent],
+ outfile[MaxTextExtent];
+
+ int
+ arg = 1,
+ exit_status = 0;
+
+ ImageInfo
+ *imageInfo;
+
+ ExceptionInfo
+ exception;
+
+ InitializeMagick(NULL);
+ imageInfo=CloneImageInfo(0);
+ GetExceptionInfo(&amp;exception);
+
+ if (argc != 3)
+ {
+ (void) fprintf ( stderr, &quot;Usage: %s infile outfile\n&quot;, argv[0] );
+ (void) fflush(stderr);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ (void) strncpy(infile, argv[arg], MaxTextExtent-1 );
+ arg++;
+ (void) strncpy(outfile, argv[arg], MaxTextExtent-1 );
+
+ (void) strcpy(imageInfo-&gt;filename, infile);
+ image = ReadImage(imageInfo, &amp;exception);
+ if (image == (Image *) NULL)
+ {
+ CatchException(&amp;exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ (void) strcpy(image-&gt;filename, outfile);
+ if (!WriteImage (imageInfo,image))
+ {
+ CatchException(&amp;image-&gt;exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ program_exit:
+
+ if (image != (Image *) NULL)
+ DestroyImage(image);
+
+ if (imageInfo != (ImageInfo *) NULL)
+ DestroyImageInfo(imageInfo);
+ DestroyMagick();
+
+ return exit_status;
+}
+</pre>
+<p>This example program (demo.c) which reads multiple input files
+(possibly animation files) specified on the command line, resizes the
+image frames to 106x80, and writes the resulting animation to disk:</p>
+<pre class="literal-block">
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;time.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;magick/api.h&gt;
+
+int main(int argc,char **argv)
+{
+ ExceptionInfo
+ exception;
+
+ Image
+ *image,
+ *images,
+ *resize_image,
+ *thumbnails;
+
+ ImageInfo
+ *image_info;
+
+ int
+ i;
+
+ /*
+ Initialize the image info structure and read the list of files
+ provided by the user as a image sequence
+ */
+ InitializeMagick(*argv);
+ GetExceptionInfo(&amp;exception);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ images=NewImageList();
+ for (i=1; i&lt; argc-1; i++)
+ {
+ (void) strcpy(image_info-&gt;filename,argv[i]);
+ printf(&quot;Reading %s ...&quot;, image_info-&gt;filename);
+ image=ReadImage(image_info,&amp;exception);
+ printf(&quot; %lu frames\n&quot;, GetImageListLength(image));
+ if (exception.severity != UndefinedException)
+ CatchException(&amp;exception);
+ if (image)
+ (void) AppendImageToList(&amp;images,image);
+ }
+
+ if (!images)
+ {
+ printf(&quot;Failed to read any images!\n&quot;);
+ exit(1);
+ }
+ /*
+ Create a thumbnail image sequence
+ */
+ thumbnails=NewImageList();
+ while ((image=RemoveFirstImageFromList(&amp;images)) != (Image *) NULL)
+ {
+ resize_image=ResizeImage(image,106,80,LanczosFilter,1.0,&amp;exception);
+ DestroyImage(image);
+ if (resize_image == (Image *) NULL)
+ {
+ CatchException(&amp;exception);
+ continue;
+ }
+ (void) AppendImageToList(&amp;thumbnails,resize_image);
+ }
+ /*
+ Write the thumbnail image sequence to file
+ */
+ if (thumbnails)
+ {
+ (void) strcpy(thumbnails-&gt;filename,argv[argc-1]);
+ image_info-&gt;adjoin=MagickTrue;
+ printf(&quot;Writing %s ... %lu frames\n&quot;, thumbnails-&gt;filename,
+ GetImageListLength(thumbnails));
+ WriteImage(image_info,thumbnails);
+ }
+
+ /*
+ Release resources
+ */
+ DestroyImageList(thumbnails);
+ DestroyImageInfo(image_info);
+ DestroyExceptionInfo(&amp;exception);
+ DestroyMagick();
+ return(0);
+}
+</pre>
+<p>To compile on Unix, the command would look something like this:</p>
+<pre class="literal-block">
+gcc -o demo demo.c -O `GraphicsMagick-config --cppflags --ldflags --libs`
+</pre>
+<p>As a usage example, with the input files in1.gif, in2.png, and in3.jpg, create
+the animation file out.miff:</p>
+<pre class="literal-block">
+demo in1.gif in2.png in3.jpg out.miff
+</pre>
+<p>The resulting animation may be played on an X11 display using 'gm animate
+out.miff'.</p>
+<p>The GraphicsMagick-config script reproduces the options which were used to
+compile the GraphicsMagick utilities. Using compatible options ensures that
+your program will compile and run.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/api/api.rst b/www/api/api.rst
new file mode 100644
index 0000000..1bc70b0
--- /dev/null
+++ b/www/api/api.rst
@@ -0,0 +1,305 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=========================
+GraphicsMagick Core C API
+=========================
+
+.. _Animate : animate.html
+.. _Annotate : annotate.html
+.. _Attribute : attribute.html
+.. _Average : average.html
+.. _`ASC CDL` : cdl.html
+.. _Blob : blob.html
+.. _Channel : channel.html
+.. _Color : color.html
+.. _Colormap : colormap.html
+.. _Compare : compare.html
+.. _Composite : composite.html
+.. _Confirm Access : confirm_access.html
+.. _Constitute : constitute.html
+.. _Decorate : decorate.html
+.. _Describe : describe.html
+.. _Display : display.html
+.. _Draw : draw.html
+.. _Effect : effect.html
+.. _Enhance : enhance.html
+.. _Error : error.html
+.. _Export : export.html
+.. _FX : fx.html
+.. _`Hald CLUT` : hclut.html
+.. _Image : image.html
+.. _Import : import.html
+.. _List : list.html
+.. _Magick : magick.html
+.. _Memory : memory.html
+.. _Monitor : monitor.html
+.. _Montage : montage.html
+.. _Operator : operator.html
+.. _Paint : paint.html
+.. _Pixel Cache : pixel_cache.html
+.. _Pixel Iterator : pixel_iterator.html
+.. _Plasma : plasma.html
+.. _Profile : profile.html
+.. _Quantize : quantize.html
+.. _Registry : registry.html
+.. _Resize : resize.html
+.. _Resource : resource.html
+.. _Segment : segment.html
+.. _Shear : shear.html
+.. _Signature : signature.html
+.. _Statistics : statistics.html
+.. _Texture : texture.html
+.. _Transform : transform.html
+.. _types: types.html
+
+The GraphicsMagick core C library constitutes the implementation of
+GraphicsMagick and provides the lowest-level C language programming
+interface for GraphicsMagick. The core C API provides many functions
+to read, manipulate, write, or display an image. To invoke the
+functions, write your program in C (or C++) language while making
+calls to the core library functions and link with libGraphicsMagick.a,
+libGraphicsMagick.so, or GraphicsMagick.dll depending on your system.
+
+The API is divided into a number of categories. While reading this
+documentation, please reference the types_ documentation as required:
+
+ * Animate_: Interactively animate an image sequence
+ * Annotate_: Annotate an image with text
+ * Attribute_: Access key, value image attributes
+ * Average_: Average several images together
+ * `ASC CDL`_ : Apply ASC CDL to image
+ * Blob_: Read and write images to memory
+ * Channel_: Import and export image channels as well as compute channel depth
+ * Color_: Methods to deal with image colors
+ * Colormap_: Methods to deal with image colormaps
+ * Compare_: Compare images
+ * Composite_: Composite images
+ * `Confirm Access`_ : Confirm access to files and URLs.
+ * Constitute_: Read, write, import, and export images
+ * Decorate_: Add fancy borders to images
+ * Describe_: Describe an image
+ * Display_: Interactively display and edit an image
+ * Draw_: Convenient methods to draw vectors and text
+ * Effect_:Threshold (various), blur, despeckle, edge, emboss, enhance,
+ gaussian blur ...
+ * Enhance_: Contrast, equalize, gamma, level, level channel, modulate, negate,
+ and normalize
+ * Error_: Error reporting methods
+ * Export_ : Export image pixels to common representations
+ * FX_: Special effects methods
+ * `Hald CLUT`_ : Apply Hald CLUT to image
+ * Image_: Miscellaneous image methods
+ * Import_ : Import image pixels from common representations
+ * List_: Manage image lists
+ * Magick_: Image format support interfaces
+ * Memory_: Memory allocation methods
+ * Monitor_: Progress monitor callbacks
+ * Montage_: Create a montage of image thumbnails
+ * Operator_: Methods to apply mathematic or boolean operators to pixels
+ * Paint_: Fill pixel regions
+ * `Pixel Cache`_: Low-level access to image pixels
+ * `Pixel Iterator`_: Pixel iterator design pattern support functions
+ * Plasma_: Plasma fractal image generator
+ * Profile_: Attached profile access
+ * Quantize_: Reduce image colors or assign image colors from colormap
+ * Registry_: Store and retrieve images in memory by ID
+ * Resize_: Resize an Image
+ * Resource_: Set and get resource limits
+ * Segment_: Coalese similar image colors
+ * Shear_: Rotate image, shear image, or apply a 2D affine transformation
+ * Signature_: Compute an image signature (checksum)
+ * Statistics_: Compute image statistics
+ * Texture_: Create a tiled texture image or tile an image with a texture.
+ * Transform_: Chop, coalesce, deconstruct, flatten, flip, flop, mosiac, roll,
+ or shave image
+
+Here are a few sample programs to get you started.
+
+This example program (convert.c) simply converts from one file name to
+another (and will automatically change formats based on file
+extension)::
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <time.h>
+ #include <sys/types.h>
+ #include <magick/api.h>
+
+ int main ( int argc, char **argv )
+ {
+ Image
+ *image = (Image *) NULL;
+
+ char
+ infile[MaxTextExtent],
+ outfile[MaxTextExtent];
+
+ int
+ arg = 1,
+ exit_status = 0;
+
+ ImageInfo
+ *imageInfo;
+
+ ExceptionInfo
+ exception;
+
+ InitializeMagick(NULL);
+ imageInfo=CloneImageInfo(0);
+ GetExceptionInfo(&exception);
+
+ if (argc != 3)
+ {
+ (void) fprintf ( stderr, "Usage: %s infile outfile\n", argv[0] );
+ (void) fflush(stderr);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ (void) strncpy(infile, argv[arg], MaxTextExtent-1 );
+ arg++;
+ (void) strncpy(outfile, argv[arg], MaxTextExtent-1 );
+
+ (void) strcpy(imageInfo->filename, infile);
+ image = ReadImage(imageInfo, &exception);
+ if (image == (Image *) NULL)
+ {
+ CatchException(&exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ (void) strcpy(image->filename, outfile);
+ if (!WriteImage (imageInfo,image))
+ {
+ CatchException(&image->exception);
+ exit_status = 1;
+ goto program_exit;
+ }
+
+ program_exit:
+
+ if (image != (Image *) NULL)
+ DestroyImage(image);
+
+ if (imageInfo != (ImageInfo *) NULL)
+ DestroyImageInfo(imageInfo);
+ DestroyMagick();
+
+ return exit_status;
+ }
+
+This example program (demo.c) which reads multiple input files
+(possibly animation files) specified on the command line, resizes the
+image frames to 106x80, and writes the resulting animation to disk::
+
+ #include <stdio.h>
+ #include <string.h>
+ #include <time.h>
+ #include <sys/types.h>
+ #include <magick/api.h>
+
+ int main(int argc,char **argv)
+ {
+ ExceptionInfo
+ exception;
+
+ Image
+ *image,
+ *images,
+ *resize_image,
+ *thumbnails;
+
+ ImageInfo
+ *image_info;
+
+ int
+ i;
+
+ /*
+ Initialize the image info structure and read the list of files
+ provided by the user as a image sequence
+ */
+ InitializeMagick(*argv);
+ GetExceptionInfo(&exception);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ images=NewImageList();
+ for (i=1; i< argc-1; i++)
+ {
+ (void) strcpy(image_info->filename,argv[i]);
+ printf("Reading %s ...", image_info->filename);
+ image=ReadImage(image_info,&exception);
+ printf(" %lu frames\n", GetImageListLength(image));
+ if (exception.severity != UndefinedException)
+ CatchException(&exception);
+ if (image)
+ (void) AppendImageToList(&images,image);
+ }
+
+ if (!images)
+ {
+ printf("Failed to read any images!\n");
+ exit(1);
+ }
+ /*
+ Create a thumbnail image sequence
+ */
+ thumbnails=NewImageList();
+ while ((image=RemoveFirstImageFromList(&images)) != (Image *) NULL)
+ {
+ resize_image=ResizeImage(image,106,80,LanczosFilter,1.0,&exception);
+ DestroyImage(image);
+ if (resize_image == (Image *) NULL)
+ {
+ CatchException(&exception);
+ continue;
+ }
+ (void) AppendImageToList(&thumbnails,resize_image);
+ }
+ /*
+ Write the thumbnail image sequence to file
+ */
+ if (thumbnails)
+ {
+ (void) strcpy(thumbnails->filename,argv[argc-1]);
+ image_info->adjoin=MagickTrue;
+ printf("Writing %s ... %lu frames\n", thumbnails->filename,
+ GetImageListLength(thumbnails));
+ WriteImage(image_info,thumbnails);
+ }
+
+ /*
+ Release resources
+ */
+ DestroyImageList(thumbnails);
+ DestroyImageInfo(image_info);
+ DestroyExceptionInfo(&exception);
+ DestroyMagick();
+ return(0);
+ }
+
+To compile on Unix, the command would look something like this::
+
+ gcc -o demo demo.c -O `GraphicsMagick-config --cppflags --ldflags --libs`
+
+As a usage example, with the input files in1.gif, in2.png, and in3.jpg, create
+the animation file out.miff::
+
+ demo in1.gif in2.png in3.jpg out.miff
+
+The resulting animation may be played on an X11 display using 'gm animate
+out.miff'.
+
+The GraphicsMagick-config script reproduces the options which were used to
+compile the GraphicsMagick utilities. Using compatible options ensures that
+your program will compile and run.
+
+-------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
+
diff --git a/www/api/api_hyperlinks.rst b/www/api/api_hyperlinks.rst
new file mode 100644
index 0000000..2c6aada
--- /dev/null
+++ b/www/api/api_hyperlinks.rst
@@ -0,0 +1,55 @@
+.. _AffineMatrix: ../api/types.html#affinematrix
+.. _BlobInfo: ../api/types.html#blobinfo
+.. _Cache: ../api/types.html#cache
+.. _ChannelType: ../api/types.html#channeltype
+.. _ChromaticityInfo: ../api/types.html#chromaticityinfo
+.. _ClassType: ../api/types.html#classtype
+.. _ClipPathUnits: ../api/types.html#clippathunits
+.. _ColorPacket: ../api/types.html#colorPacket
+.. _ColorspaceType: ../api/types.html#colorspacetype
+.. _ComplianceType: ../api/types.html#compliancetype
+.. _CompositeOperator: ../api/types.html#compositeoperator
+.. _CompressionType: ../api/types.html#compressiontype
+.. _DecorationType: ../api/types.html#decorationtype
+.. _DrawContext: ../api/types.html#drawcontext
+.. _DrawInfo: ../api/types.html#drawinfo
+.. _ErrorHandler: ../api/types.html#errorhandler
+.. _ExceptionInfo: ../api/types.html#exceptioninfo
+.. _ExceptionType: ../api/types.html#exceptiontype
+.. _FillRule: ../api/types.html#fillrule
+.. _FilterTypes: ../api/types.html#filtertype
+.. _FrameInfo: ../api/types.html#frameinfo
+.. _GravityType: ../api/types.html#gravitytype
+.. _Image: ../api/types.html#image
+.. _ImageInfo: ../api/types.html#imageinfo
+.. _ImageType: ../api/types.html#imagetype
+.. _IndexPacket: ../api/types.html#indexpacket
+.. _InterlaceType: ../api/types.html#interlacetype
+.. _LayerType: ../api/types.html#layertype
+.. _MagickInfo: ../api/types.html#magickinfo
+.. _MonitorHandler: ../api/types.html#monitorhandler
+.. _MontageInfo: ../api/types.html#montageinfo
+.. _NoiseType: ../api/types.html#noisetype
+.. _PaintMethod: ../api/types.html#paintmethod
+.. _PixelPacket: ../api/types.html#pixelpacket
+.. _PointInfo: ../api/types.html#pointinfo
+.. _ProfileInfo: ../api/types.html#profileinfo
+.. _QuantizeInfo: ../api/types.html#quantizeinfo
+.. _Quantum: ../api/types.html#quantum
+.. _QuantumType: ../api/types.html#quantumtype
+.. _RectangleInfo: ../api/types.html#rectangleinfo
+.. _RegistryType: ../api/types.html#registrytype
+.. _RenderingIntent: ../api/types.html#renderingintent
+.. _ResolutionType: ../api/types.html#resolutiontype
+.. _ResourceType: ../api/types.html#resourcetype
+.. _SegmentInfo: ../api/types.html#segmentinfo
+.. _SignatureInfo: ../api/types.html#signatureinfo
+.. _StorageType: ../api/types.html#storagetype
+.. _StreamHandler: ../api/types.html#streamhandler
+.. _StretchType: ../api/types.html#stretchtype
+.. _StyleType: ../api/types.html#styletype
+.. _TypeMetric: ../api/types.html#typemetric
+.. _ViewInfo: ../api/types.html#viewinfo
+.. _VirtualPixelMethod: ../api/types.html#virtualpixelmethod
+.. _MagickXResourceInfo: ../api/types.html#magickxresourceinfo
+
diff --git a/www/api/attribute.html b/www/api/attribute.html
new file mode 100644
index 0000000..573c51d
--- /dev/null
+++ b/www/api/attribute.html
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>attribute</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="attribute">
+<h1 class="title">attribute</h1>
+<h2 class="subtitle" id="access-key-value-image-attributes">Access key,value image attributes</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#cloneimageattributes" id="id9">CloneImageAttributes</a></li>
+<li><a class="reference internal" href="#destroyimageattributes" id="id10">DestroyImageAttributes</a></li>
+<li><a class="reference internal" href="#getimageattribute" id="id11">GetImageAttribute</a></li>
+<li><a class="reference internal" href="#getimageclippingpathattribute" id="id12">GetImageClippingPathAttribute</a></li>
+<li><a class="reference internal" href="#setimageattribute" id="id13">SetImageAttribute</a></li>
+</ul>
+</div>
+<div class="section" id="cloneimageattributes">
+<h1><a class="toc-backref" href="#id9">CloneImageAttributes</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail CloneImageAttributes( <a class="reference external" href="../api/types.html#image">Image</a> *clone_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *original_image );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>CloneImageAttributes() copies the text attibutes from one image to another.
+Any text attributes in the destination image are preserved.
+CloneImageAttributes returns MagickPass if all of the attribututes are
+successfully cloned or MagickFail if there is a memory allocation error.</p>
+<p>The format of the CloneImageAttributes method is:</p>
+<pre class="literal-block">
+MagickPassFail CloneImageAttributes( <a class="reference external" href="../api/types.html#image">Image</a> *clone_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *original_image );
+</pre>
+<dl class="docutils">
+<dt>clone_image:</dt>
+<dd>The destination image.</dd>
+<dt>original_image:</dt>
+<dd>The source image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyimageattributes">
+<h1><a class="toc-backref" href="#id10">DestroyImageAttributes</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+DestroyImageAttributes( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>DestroyImageAttributes() deallocates memory associated with the image
+attribute list.</p>
+<p>The format of the DestroyImageAttributes method is:</p>
+<pre class="literal-block">
+DestroyImageAttributes( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimageattribute">
+<h1><a class="toc-backref" href="#id11">GetImageAttribute</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const ImageAttribute *GetImageAttribute( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *key );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>GetImageAttribute() searches the list of image attributes and returns
+a pointer to the attribute if it exists otherwise NULL.</p>
+<p>The format of the GetImageAttribute method is:</p>
+<pre class="literal-block">
+const ImageAttribute *GetImageAttribute( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *key );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>key:</dt>
+<dd>These character strings are the name of an image attribute to
+return.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimageclippingpathattribute">
+<h1><a class="toc-backref" href="#id12">GetImageClippingPathAttribute</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const ImageAttribute *GetImageClippingPathAttribute( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>Method GetImageClippingPathAttribute searches the list of image attributes
+and returns a pointer to a clipping path if it exists otherwise NULL.</p>
+<p>The format of the GetImageClippingPathAttribute method is:</p>
+<pre class="literal-block">
+const ImageAttribute *GetImageClippingPathAttribute( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>attribute:</dt>
+<dd>Method GetImageClippingPathAttribute returns the clipping
+path if it exists otherwise NULL.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimageattribute">
+<h1><a class="toc-backref" href="#id13">SetImageAttribute</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int SetImageAttribute( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *key, const char *value );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>SetImageAttribute() searches the list of image attributes and replaces the
+attribute value. If it is not found in the list, the attribute name
+and value is added to the list. If the attribute exists in the list,
+the value is concatenated to the attribute. SetImageAttribute returns
+True if the attribute is successfully concatenated or added to the list,
+otherwise False. If the value is NULL, the matching key is deleted
+from the list.</p>
+<p>There is special handling for the EXIF:Orientation attribute. Setting this
+attribute will also update the EXIF tag in the image's EXIF profile to the
+given value provided an EXIF profile exists and has an existing EXIF
+orientation tag and the attribute value is a valid orientation
+(see orientationType). The attribute value will be set regardless of
+whether the EXIF profile was successfully updated. The new
+EXIF:Orientation attribute replaces the existing value rather than
+being concatenated to it as when setting other attributes.
+The 'comment' and 'label' attributes are treated specially in that
+embedded format specifications are translated according to the formatting
+rules of TranslateText().</p>
+<p>The format of the SetImageAttribute method is:</p>
+<pre class="literal-block">
+unsigned int SetImageAttribute( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *key, const char *value );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>key,value:</dt>
+<dd>These character strings are the name and value of an image
+attribute to replace or add to the list.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/average.html b/www/api/average.html
new file mode 100644
index 0000000..07ac17f
--- /dev/null
+++ b/www/api/average.html
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>average</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="average">
+<h1 class="title">average</h1>
+<h2 class="subtitle" id="image-averaging-functions">Image averaging functions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#averageimages" id="id1">AverageImages</a></li>
+</ul>
+</div>
+<div class="section" id="averageimages">
+<h1><a class="toc-backref" href="#id1">AverageImages</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AverageImages( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>The Average() method takes a set of images and averages them together.
+Each image in the set must have the same width and height. Average()
+returns a single image with each corresponding pixel component of
+each image averaged. On failure, a NULL image is returned and
+exception describes the reason for the failure.</p>
+<p>The format of the AverageImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AverageImages( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image sequence.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/blob.html b/www/api/blob.html
new file mode 100644
index 0000000..e690eb6
--- /dev/null
+++ b/www/api/blob.html
@@ -0,0 +1,667 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>blob</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="blob">
+<h1 class="title">blob</h1>
+<h2 class="subtitle" id="read-or-write-formatted-images-in-memory-blobs">Read or write formatted images in memory (BLOBs)</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#attachblob" id="id43">AttachBlob</a></li>
+<li><a class="reference internal" href="#blobisseekable" id="id44">BlobIsSeekable</a></li>
+<li><a class="reference internal" href="#blobreservesize" id="id45">BlobReserveSize</a></li>
+<li><a class="reference internal" href="#blobtofile" id="id46">BlobToFile</a></li>
+<li><a class="reference internal" href="#blobtoimage" id="id47">BlobToImage</a></li>
+<li><a class="reference internal" href="#cloneblobinfo" id="id48">CloneBlobInfo</a></li>
+<li><a class="reference internal" href="#destroyblob" id="id49">DestroyBlob</a></li>
+<li><a class="reference internal" href="#destroyblobinfo" id="id50">DestroyBlobInfo</a></li>
+<li><a class="reference internal" href="#detachblob" id="id51">DetachBlob</a></li>
+<li><a class="reference internal" href="#filetoblob" id="id52">FileToBlob</a></li>
+<li><a class="reference internal" href="#getblobfilehandle" id="id53">GetBlobFileHandle</a></li>
+<li><a class="reference internal" href="#getblobinfo" id="id54">GetBlobInfo</a></li>
+<li><a class="reference internal" href="#getblobstatus" id="id55">GetBlobStatus</a></li>
+<li><a class="reference internal" href="#getblobstreamdata" id="id56">GetBlobStreamData</a></li>
+<li><a class="reference internal" href="#getblobtemporary" id="id57">GetBlobTemporary</a></li>
+<li><a class="reference internal" href="#getconfigureblob" id="id58">GetConfigureBlob</a></li>
+<li><a class="reference internal" href="#imagetoblob" id="id59">ImageToBlob</a></li>
+<li><a class="reference internal" href="#imagetofile" id="id60">ImageToFile</a></li>
+<li><a class="reference internal" href="#pingblob" id="id61">PingBlob</a></li>
+<li><a class="reference internal" href="#referenceblob" id="id62">ReferenceBlob</a></li>
+<li><a class="reference internal" href="#setblobclosable" id="id63">SetBlobClosable</a></li>
+<li><a class="reference internal" href="#setblobtemporary" id="id64">SetBlobTemporary</a></li>
+</ul>
+</div>
+<div class="section" id="attachblob">
+<h1><a class="toc-backref" href="#id43">AttachBlob</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void AttachBlob( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info, const void *blob, const size_t length );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AttachBlob() attaches a blob to the BlobInfo structure.</p>
+<p>The format of the AttachBlob method is:</p>
+<pre class="literal-block">
+void AttachBlob( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info, const void *blob, const size_t length );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>blob_info:</dt>
+<dd>Specifies a pointer to a BlobInfo structure.</dd>
+<dt>blob:</dt>
+<dd>The address of a character stream in one of the image formats
+understood by GraphicsMagick.</dd>
+<dt>length:</dt>
+<dd>This size_t integer reflects the length in bytes of the blob.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="blobisseekable">
+<h1><a class="toc-backref" href="#id44">BlobIsSeekable</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickBool BlobIsSeekable( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>BlobIsSeekable() returns MagickTrue if the blob supports seeks
+(SeekBlob() is functional).</p>
+<p>The format of the BlobIsSeekable method is:</p>
+<pre class="literal-block">
+MagickBool BlobIsSeekable( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Image to query</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="blobreservesize">
+<h1><a class="toc-backref" href="#id45">BlobReserveSize</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail BlobReserveSize( <a class="reference external" href="../api/types.html#image">Image</a> *image, magick_off_t size );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>BlobReserveSize() sets the output size of the blob or file. This is used
+as a means to minimize memory or filesystem fragmentation if the final
+output size is known in advance. While it is possible that file
+fragmentation is reduced, it is also possible that file write
+performance is reduced by changing a write operation to a read, modify,
+write operation.</p>
+<p>The format of the BlobReserveSize method is:</p>
+<pre class="literal-block">
+MagickPassFail BlobReserveSize( <a class="reference external" href="../api/types.html#image">Image</a> *image, magick_off_t size );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Image to update</dd>
+<dt>size:</dt>
+<dd>New output size.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="blobtofile">
+<h1><a class="toc-backref" href="#id46">BlobToFile</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail BlobToFile( const char *filename, const void *blob, const size_t length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>BlobToFile() writes a blob to a file. It returns MagickFail if an error
+occurs otherwise MagickPass.</p>
+<p>The format of the BlobToFile method is:</p>
+<pre class="literal-block">
+MagickPassFail BlobToFile( const char *filename, const void *blob, const size_t length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>BlobToFile returns MagickPass on success; otherwise, it
+returns MagickFail if an error occurs.</dd>
+<dt>filename:</dt>
+<dd>Write the blob to this file.</dd>
+<dt>blob:</dt>
+<dd>The address of a blob.</dd>
+<dt>length:</dt>
+<dd>This length in bytes of the blob.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="blobtoimage">
+<h1><a class="toc-backref" href="#id47">BlobToImage</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *BlobToImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const void *blob,
+ const size_t length, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>BlobToImage() implements direct to memory image formats. It returns the
+blob as an image.</p>
+<p>The format of the BlobToImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *BlobToImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const void *blob,
+ const size_t length, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>blob:</dt>
+<dd>The address of a character stream in one of the image formats
+understood by GraphicsMagick.</dd>
+<dt>length:</dt>
+<dd>This size_t integer reflects the length in bytes of the blob.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="cloneblobinfo">
+<h1><a class="toc-backref" href="#id48">CloneBlobInfo</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *CloneBlobInfo( const <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>CloneBlobInfo() makes a duplicate of the given blob info structure, or if
+blob info is NULL, a new one.</p>
+<p>The format of the CloneBlobInfo method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *CloneBlobInfo( const <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>clone_info:</dt>
+<dd>Method CloneBlobInfo returns a duplicate of the given
+blob info, or if blob info is NULL a new one.</dd>
+<dt>quantize_info:</dt>
+<dd>a structure of type info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyblob">
+<h1><a class="toc-backref" href="#id49">DestroyBlob</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyBlob( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>DestroyBlob() deallocates memory associated with a blob. The blob is
+a reference counted object so the object is only destroyed once its
+reference count decreases to zero.</p>
+<p>The format of the DestroyBlob method is:</p>
+<pre class="literal-block">
+void DestroyBlob( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyblobinfo">
+<h1><a class="toc-backref" href="#id50">DestroyBlobInfo</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyBlobInfo( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>DestroyBlobInfo() deallocates memory associated with an BlobInfo structure.
+The blob is a reference counted object so the object is only destroyed once
+its reference count decreases to zero. Use of DestroyBlob is preferred over
+this function since it assures that the blob is closed prior to destruction.</p>
+<p>This function is no longer used within GraphicsMagick.</p>
+<p>The format of the DestroyBlobInfo method is:</p>
+<pre class="literal-block">
+void DestroyBlobInfo( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>blob:</dt>
+<dd>Specifies a pointer to a BlobInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="detachblob">
+<h1><a class="toc-backref" href="#id51">DetachBlob</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DetachBlob( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>DetachBlob() detaches a blob from the BlobInfo structure.</p>
+<p>The format of the DetachBlob method is:</p>
+<pre class="literal-block">
+void DetachBlob( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>blob_info:</dt>
+<dd>Specifies a pointer to a BlobInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="filetoblob">
+<h1><a class="toc-backref" href="#id52">FileToBlob</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *FileToBlob( const char *filename, size_t *length, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>FileToBlob() returns the contents of a file in a buffer allocated via
+MagickMalloc() (which is equivalent to the system malloc() by default).
+The character '0' is appended to the buffer in case the buffer will be
+accessed as a string. The length of the buffer (not including the extra
+terminating '0' character) is returned via the 'length' parameter.
+If an error occurs, a NULL pointer is returned. The returned buffer
+must be freed by the user in a matter compatible with MagickMalloc()
+(e.g. via MagickFree()).</p>
+<p>The format of the FileToBlob method is:</p>
+<pre class="literal-block">
+void *FileToBlob( const char *filename, size_t *length, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>blob:</dt>
+<dd>FileToBlob() returns the contents of a file as a blob. If
+an error occurs NULL is returned.</dd>
+<dt>filename:</dt>
+<dd>The filename.</dd>
+<dt>length:</dt>
+<dd>This pointer to a size_t integer sets the initial length of the
+blob. On return, it reflects the actual length of the blob.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getblobfilehandle">
+<h1><a class="toc-backref" href="#id53">GetBlobFileHandle</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+FILE *GetBlobFileHandle( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>GetBlobFileHandle() returns the stdio file handle associated with the
+image blob. If there is no associated file handle, then a null pointer
+is returned.</p>
+<p>The format of the GetBlobFileHandle method is:</p>
+<pre class="literal-block">
+FILE *GetBlobFileHandle( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Image to query</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getblobinfo">
+<h1><a class="toc-backref" href="#id54">GetBlobInfo</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void GetBlobInfo( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>GetBlobInfo() initializes the BlobInfo structure.</p>
+<p>The format of the GetBlobInfo method is:</p>
+<pre class="literal-block">
+void GetBlobInfo( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>blob_info:</dt>
+<dd>Specifies a pointer to a BlobInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getblobstatus">
+<h1><a class="toc-backref" href="#id55">GetBlobStatus</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+int GetBlobStatus( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>GetBlobStatus() returns the blob error status.</p>
+<p>The format of the GetBlobStatus method is:</p>
+<pre class="literal-block">
+int GetBlobStatus( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getblobstreamdata">
+<h1><a class="toc-backref" href="#id56">GetBlobStreamData</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned char *GetBlobStreamData( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>GetBlobStreamData() returns the stream data for the image. The data is only
+available if the data is stored on the heap, or is memory mapped.
+Otherwise a NULL value is returned.</p>
+<p>The format of the GetBlobStreamData method is:</p>
+<pre class="literal-block">
+unsigned char *GetBlobStreamData( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getblobtemporary">
+<h1><a class="toc-backref" href="#id57">GetBlobTemporary</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickBool GetBlobTemporary( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>GetBlobTemporary() returns MagickTrue if the file associated with the blob
+is a temporary file and should be removed when the associated image is
+destroyed.</p>
+<p>The format of the GetBlobTemporary method is:</p>
+<pre class="literal-block">
+MagickBool GetBlobTemporary( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Image to query</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getconfigureblob">
+<h1><a class="toc-backref" href="#id58">GetConfigureBlob</a></h1>
+<div class="section" id="id29">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *GetConfigureBlob( const char *filename, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id30">
+<h2>Description</h2>
+<p>GetConfigureBlob() returns the specified configure file as a blob.</p>
+<p>The format of the GetConfigureBlob method is:</p>
+<pre class="literal-block">
+void *GetConfigureBlob( const char *filename, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>filename:</dt>
+<dd>The configure file name.</dd>
+<dt>path:</dt>
+<dd>return the full path information of the configure file.</dd>
+<dt>length:</dt>
+<dd>This pointer to a size_t integer sets the initial length of the
+blob. On return, it reflects the actual length of the blob.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="imagetoblob">
+<h1><a class="toc-backref" href="#id59">ImageToBlob</a></h1>
+<div class="section" id="id31">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *ImageToBlob( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image, size_t *length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id32">
+<h2>Description</h2>
+<p>ImageToBlob() implements direct to memory image formats. It returns the
+image as a formatted blob and its length. The magick member of the Image
+structure determines the format of the returned blob (GIF, JPEG, PNG,
+etc.). This function is the equivalent of WriteImage(), but writes the
+formatted &quot;file&quot; to a memory buffer rather than to an actual file.</p>
+<p>The format of the ImageToBlob method is:</p>
+<pre class="literal-block">
+void *ImageToBlob( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image, size_t *length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>length:</dt>
+<dd>This pointer to a size_t integer sets the initial length of the
+blob. On return, it reflects the actual length of the blob.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="imagetofile">
+<h1><a class="toc-backref" href="#id60">ImageToFile</a></h1>
+<div class="section" id="id33">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ImageToFile( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *filename,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id34">
+<h2>Description</h2>
+<p>ImageToFile() copies the input image from an open blob stream to a file.
+It returns False if an error occurs otherwise True. This function is used
+to handle coders which are unable to stream the data in using Blob I/O.
+Instead of streaming the data in, the data is streammed to a temporary
+file, and the coder accesses the temorary file directly.</p>
+<p>The format of the ImageToFile method is:</p>
+<pre class="literal-block">
+MagickPassFail ImageToFile( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *filename,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>ImageToFile returns MagickPass on success; otherwise, it
+returns MagickFail if an error occurs.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>filename:</dt>
+<dd>Write the image to this file.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pingblob">
+<h1><a class="toc-backref" href="#id61">PingBlob</a></h1>
+<div class="section" id="id35">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *PingBlob( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const void *blob, const size_t length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id36">
+<h2>Description</h2>
+<p>PingBlob() returns all the attributes of an image or image sequence except
+for the pixels. It is much faster and consumes far less memory than
+BlobToImage(). On failure, a NULL image is returned and exception
+describes the reason for the failure.</p>
+<p>The format of the PingBlob method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *PingBlob( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const void *blob, const size_t length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>blob:</dt>
+<dd>The address of a character stream in one of the image formats
+understood by GraphicsMagick.</dd>
+<dt>length:</dt>
+<dd>This size_t integer reflects the length in bytes of the blob.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="referenceblob">
+<h1><a class="toc-backref" href="#id62">ReferenceBlob</a></h1>
+<div class="section" id="id37">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> ReferenceBlob( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );
+</pre>
+</div>
+<div class="section" id="id38">
+<h2>Description</h2>
+<p>ReferenceBlob() increments the reference count associated with the pixel
+blob, returning a pointer to the blob.</p>
+<p>The format of the ReferenceBlob method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> ReferenceBlob( <a class="reference external" href="../api/types.html#blobinfo">BlobInfo</a> *blob_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>blob_info:</dt>
+<dd>The blob_info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setblobclosable">
+<h1><a class="toc-backref" href="#id63">SetBlobClosable</a></h1>
+<div class="section" id="id39">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void SetBlobClosable( <a class="reference external" href="../api/types.html#image">Image</a> *image, MagickBool closeable );
+</pre>
+</div>
+<div class="section" id="id40">
+<h2>Description</h2>
+<p>SetBlobClosable() enables closing the blob if MagickTrue is passed, and
+exempts the blob from being closed if False is passed. Blobs are closable
+by default (default MagickTrue).</p>
+<p>The format of the SetBlobClosable method is:</p>
+<pre class="literal-block">
+void SetBlobClosable( <a class="reference external" href="../api/types.html#image">Image</a> *image, MagickBool closeable );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Image to update</dd>
+<dt>closeable:</dt>
+<dd>Set to FALSE in order to disable closing the blob.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setblobtemporary">
+<h1><a class="toc-backref" href="#id64">SetBlobTemporary</a></h1>
+<div class="section" id="id41">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void SetBlobTemporary( <a class="reference external" href="../api/types.html#image">Image</a> *image, MagickBool isTemporary );
+</pre>
+</div>
+<div class="section" id="id42">
+<h2>Description</h2>
+<p>SetBlobTemporary() sets a boolean flag (default False) to specify if
+the file associated with the blob is a temporary file and should be
+removed when the associated image is destroyed.</p>
+<p>The format of the SetBlobTemporary method is:</p>
+<pre class="literal-block">
+void SetBlobTemporary( <a class="reference external" href="../api/types.html#image">Image</a> *image, MagickBool isTemporary );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Image to update</dd>
+<dt>isTemporary:</dt>
+<dd>Set to True to indicate that the file associated with
+the blob is temporary.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/cdl.html b/www/api/cdl.html
new file mode 100644
index 0000000..c46cb92
--- /dev/null
+++ b/www/api/cdl.html
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>cdl</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="cdl">
+<h1 class="title">cdl</h1>
+<h2 class="subtitle" id="apply-asc-cdl-transform-to-image">Apply ASC CDL transform to image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#cdlimage" id="id1">CdlImage</a></li>
+</ul>
+</div>
+<div class="section" id="cdlimage">
+<h1><a class="toc-backref" href="#id1">CdlImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail CdlImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *cdl );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>The CdlImage() method applies (&quot;bakes in&quot;) the ASC-CDL which is a format
+for the exchange of basic primary color grading information between
+equipment and software from different manufacturers. The format defines
+the math for three functions: slope, offset and power. Each function uses
+a number for the red, green, and blue color channels for a total of nine
+numbers comprising a single color decision. A tenth number for chrominance
+(saturation) has been proposed but is not yet standardized.</p>
+<p>The cdl argument string is comma delimited and is in the form (but
+without invervening spaces or line breaks):</p>
+<p>redslope, redoffset, redpower :
+greenslope, greenoffset, greenpower :
+blueslope, blueoffset, bluepower :
+saturation</p>
+<p>with the unity (no change) specification being:</p>
+<p>&quot;1.0,0.0,1.0:1.0,0.0,1.0:1.0,0.0,1.0:0.0&quot;</p>
+<p>See <a class="reference external" href="http://en.wikipedia.org/wiki/ASC_CDL">http://en.wikipedia.org/wiki/ASC_CDL</a> for more information.</p>
+<p>The format of the CdlImage method is:</p>
+<pre class="literal-block">
+MagickPassFail CdlImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *cdl );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>cdl:</dt>
+<dd>Define the coefficients for slope offset and power in the
+red green and blue channels, plus saturation.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/channel.html b/www/api/channel.html
new file mode 100644
index 0000000..d7e170f
--- /dev/null
+++ b/www/api/channel.html
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>channel</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="channel">
+<h1 class="title">channel</h1>
+<h2 class="subtitle" id="image-channel-functions">Image channel functions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#channelimage" id="id11">ChannelImage</a></li>
+<li><a class="reference internal" href="#exportimagechannel" id="id12">ExportImageChannel</a></li>
+<li><a class="reference internal" href="#getimagechanneldepth" id="id13">GetImageChannelDepth</a></li>
+<li><a class="reference internal" href="#importimagechannel" id="id14">ImportImageChannel</a></li>
+<li><a class="reference internal" href="#importimagechannelsmasked" id="id15">ImportImageChannelsMasked</a></li>
+<li><a class="reference internal" href="#setimagechanneldepth" id="id16">SetImageChannelDepth</a></li>
+</ul>
+</div>
+<div class="section" id="channelimage">
+<h1><a class="toc-backref" href="#id11">ChannelImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int ChannelImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Transform an image so that the resulting image is a grayscale image
+based on a specified image channel. The resulting image is returned in
+the RGB colorspace. This function does not force or assume an input
+image colorspace so it may be used to extract channels from images in
+colorspaces other than RGB or CMYK. For example, if the image is currently
+transformed to the HWB colorspace, the 'B' channel may be extracted by
+specifying RedChannel as the ChannelType argument.</p>
+<p>The format of the ChannelImage method is:</p>
+<pre class="literal-block">
+unsigned int ChannelImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to extract: Red, Cyan, Green, Magenta,
+Blue, Yellow, or Opacity.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="exportimagechannel">
+<h1><a class="toc-backref" href="#id12">ExportImageChannel</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ExportImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>ExportImageChannel() exports a specified image channel as a new image.</p>
+<p>The format of the ExportImageChannel method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ExportImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The source image.</dd>
+<dt>channel:</dt>
+<dd>The image channel to export</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagechanneldepth">
+<h1><a class="toc-backref" href="#id13">GetImageChannelDepth</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long GetImageChannelDepth( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>GetImageChannelDepth() returns the minimum bit depth required to store
+the specified image channel without actual loss of color resolution.
+Pixel components are stored in a Quantum, which is 8, 16, or 32 bits
+depending on the QuantumDepth value set when the software is compiled.
+GetImageChannelDepth() returns the smallest modulus storage size which
+supports the scale of the pixel within the range (i.e. no information is
+lost). As an example, the value one is returned for a bilevel channel
+since only one bit of resolution is required to represent a bilevel channel.</p>
+<p>The format of the GetImageChannelDepth method is:</p>
+<pre class="literal-block">
+unsigned long GetImageChannelDepth( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>Channel to test.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="importimagechannel">
+<h1><a class="toc-backref" href="#id14">ImportImageChannel</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ImportImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *source_image, <a class="reference external" href="../api/types.html#image">Image</a> *update_image,
+ const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>ImportImageChannel() imports an image into the specified image channel.</p>
+<p>The format of the ImportImageChannel method is:</p>
+<pre class="literal-block">
+MagickPassFail ImportImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *source_image, <a class="reference external" href="../api/types.html#image">Image</a> *update_image,
+ const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel );
+</pre>
+<dl class="docutils">
+<dt>source_image:</dt>
+<dd>The image to use as the replacement image channel.</dd>
+<dt>update_image:</dt>
+<dd>The image to import the channel into.</dd>
+<dt>channel:</dt>
+<dd>The image channel to import</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="importimagechannelsmasked">
+<h1><a class="toc-backref" href="#id15">ImportImageChannelsMasked</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ImportImageChannelsMasked( const <a class="reference external" href="../api/types.html#image">Image</a> *source_image,
+ <a class="reference external" href="../api/types.html#image">Image</a> *update_image,
+ const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channels );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>ImportImageChannelsMasked() imports all the channels from a source
+image to an update image, except for the channels specified.</p>
+<p>The format of the ImportImageChannelsMasked method is:</p>
+<pre class="literal-block">
+MagickPassFail ImportImageChannelsMasked( const <a class="reference external" href="../api/types.html#image">Image</a> *source_image,
+ <a class="reference external" href="../api/types.html#image">Image</a> *update_image,
+ const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channels );
+</pre>
+<dl class="docutils">
+<dt>source_image:</dt>
+<dd>The image from which to extract the replacement channels.</dd>
+<dt>update_image:</dt>
+<dd>The image to import the channels into.</dd>
+<dt>channel:</dt>
+<dd>The image channel to import</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimagechanneldepth">
+<h1><a class="toc-backref" href="#id16">SetImageChannelDepth</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail SetImageChannelDepth( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const unsigned int depth );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>SetImageChannelDepth() translates the pixel quantums in the specified
+channel so that if they are later divided to fit within the specified bit
+depth, that no additional information is lost (i.e. no remainder resulting
+from the division). Note that any subsequent image processing is likely
+to increase the effective depth of the image channels. A non-zero
+value is returned if the operation is successful. Check the exception
+member of image to determine the cause for any failure.</p>
+<p>The format of the SetImageChannelDepth method is:</p>
+<pre class="literal-block">
+MagickPassFail SetImageChannelDepth( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const unsigned int depth );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image to update.</dd>
+<dt>channel:</dt>
+<dd>Channel to modify.</dd>
+<dt>depth:</dt>
+<dd>Desired channel depth (range 1 to QuantumDepth)</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/color.html b/www/api/color.html
new file mode 100644
index 0000000..5ff43e7
--- /dev/null
+++ b/www/api/color.html
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>color</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="color">
+<h1 class="title">color</h1>
+<h2 class="subtitle" id="color-related-functions">Color related functions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#getcolorhistogram" id="id5">GetColorHistogram</a></li>
+<li><a class="reference internal" href="#getnumbercolors" id="id6">GetNumberColors</a></li>
+<li><a class="reference internal" href="#ispaletteimage" id="id7">IsPaletteImage</a></li>
+</ul>
+</div>
+<div class="section" id="getcolorhistogram">
+<h1><a class="toc-backref" href="#id5">GetColorHistogram</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+HistogramColorPacket *GetColorHistogram( const <a class="reference external" href="../api/types.html#image">Image</a> *, unsigned long *colors,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *);
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Method GetColorHistogram returns an array of HistogramColorPacket structures
+which specify the number of times each unique color occurs in the image.
+The referenced colors parameter is updated with the number of unique colors
+in the image. The returned array should be deallocated by the user once it
+is no longer ndded.</p>
+<p>The format of the GetColorHistogram method is:</p>
+<pre class="literal-block">
+HistogramColorPacket *GetColorHistogram( const <a class="reference external" href="../api/types.html#image">Image</a> *, unsigned long *colors,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *);
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>colors:</dt>
+<dd>The referenced value is updated with the with the number of
+unique colors.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getnumbercolors">
+<h1><a class="toc-backref" href="#id6">GetNumberColors</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long GetNumberColors( const <a class="reference external" href="../api/types.html#image">Image</a> *image, FILE *file,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>Method GetNumberColors returns the number of unique colors in an image.</p>
+<p>The format of the GetNumberColors method is:</p>
+<pre class="literal-block">
+unsigned long GetNumberColors( const <a class="reference external" href="../api/types.html#image">Image</a> *image, FILE *file,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>file:</dt>
+<dd>Write a histogram of the color distribution to this file handle.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="ispaletteimage">
+<h1><a class="toc-backref" href="#id7">IsPaletteImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickBool IsPaletteImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>Method IsPaletteImage returns True if the image is PseudoClass and has 256
+unique colors or less.</p>
+<p>The format of the IsPaletteImage method is:</p>
+<pre class="literal-block">
+MagickBool IsPaletteImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows.</p>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method IsPaletteImage returns True is the image is
+PseudoClass or has 256 color or less.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/colormap.html b/www/api/colormap.html
new file mode 100644
index 0000000..24bbeb9
--- /dev/null
+++ b/www/api/colormap.html
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>colormap</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="colormap">
+<h1 class="title">colormap</h1>
+<h2 class="subtitle" id="colormap-related-functions">Colormap related functions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#allocateimagecolormap" id="id5">AllocateImageColormap</a></li>
+<li><a class="reference internal" href="#cyclecolormapimage" id="id6">CycleColormapImage</a></li>
+<li><a class="reference internal" href="#replaceimagecolormap" id="id7">ReplaceImageColormap</a></li>
+</ul>
+</div>
+<div class="section" id="allocateimagecolormap">
+<h1><a class="toc-backref" href="#id5">AllocateImageColormap</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int AllocateImageColormap( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long colors );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AllocateImageColormap() allocates an image colormap and initializes
+it to a linear gray colorspace with increasing intensity. If the image
+already has a colormap, it is replaced. AllocateImageColormap() returns
+True if successful, otherwise False if there is not enough memory.</p>
+<p>The format of the AllocateImageColormap method is:</p>
+<pre class="literal-block">
+unsigned int AllocateImageColormap( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long colors );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>colors:</dt>
+<dd>The number of colors in the image colormap.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="cyclecolormapimage">
+<h1><a class="toc-backref" href="#id6">CycleColormapImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+CycleColormapImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const int amount );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>CycleColormap() displaces an image's colormap by a given number of
+positions. If you cycle the colormap a number of times you can produce
+a psychodelic effect.</p>
+<p>The format of the CycleColormapImage method is:</p>
+<pre class="literal-block">
+CycleColormapImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const int amount );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>amount:</dt>
+<dd>Offset the colormap this much.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="replaceimagecolormap">
+<h1><a class="toc-backref" href="#id7">ReplaceImageColormap</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ReplaceImageColormap( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *colormap,
+ const unsigned int colors );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>ReplaceImageColormap() replaces an existing image colormap with a new
+image colormap. The new image colormap is expected to contain all of the
+colors from the existing colormap. The existing colormap indexes are
+adjusted to conform with positions in the new colormap. If the new
+colormap contains duplicate entries, then the associated colormap index
+will point to the first entry found in the colormap and other matching
+entries will not be used. MagickPass is returned if the operation is
+successful, otherwise MagickFail is returned, and image-&gt;exception is
+updated with the cause of the failure.</p>
+<p>This function is useful in case colormap entries need to match across
+multiple images or otherwise occupy specific locations.</p>
+<p>The format of the ReplaceImageColormap method is:</p>
+<pre class="literal-block">
+MagickPassFail ReplaceImageColormap( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *colormap,
+ const unsigned int colors );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>image in which to replace colormap.</dd>
+<dt>colormap:</dt>
+<dd>new colormap.</dd>
+<dt>colors:</dt>
+<dd>number of colors in new colormap.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/compare.html b/www/api/compare.html
new file mode 100644
index 0000000..b9a4209
--- /dev/null
+++ b/www/api/compare.html
@@ -0,0 +1,300 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>compare</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="compare">
+<h1 class="title">compare</h1>
+<h2 class="subtitle" id="compare-images">Compare images</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#differenceimage" id="id13">DifferenceImage</a></li>
+<li><a class="reference internal" href="#getimagechanneldifference" id="id14">GetImageChannelDifference</a></li>
+<li><a class="reference internal" href="#getimagechanneldistortion" id="id15">GetImageChannelDistortion</a></li>
+<li><a class="reference internal" href="#getimagedistortion" id="id16">GetImageDistortion</a></li>
+<li><a class="reference internal" href="#isimagesequal" id="id17">IsImagesEqual</a></li>
+<li><a class="reference internal" href="#initializedifferenceimageoptions" id="id18">InitializeDifferenceImageOptions</a></li>
+<li><a class="reference internal" href="#initializedifferencestatistics" id="id19">InitializeDifferenceStatistics</a></li>
+</ul>
+</div>
+<div class="section" id="differenceimage">
+<h1><a class="toc-backref" href="#id13">DifferenceImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *DifferenceImage( const <a class="reference external" href="../api/types.html#image">Image</a> *reference_image, const <a class="reference external" href="../api/types.html#image">Image</a> *compare_image,
+ const DifferenceImageOptions *difference_options,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>DifferenceImage() returns an annotated difference image based on the
+the difference between a reference image and a compare image.</p>
+<p>The format of the DifferenceImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *DifferenceImage( const <a class="reference external" href="../api/types.html#image">Image</a> *reference_image, const <a class="reference external" href="../api/types.html#image">Image</a> *compare_image,
+ const DifferenceImageOptions *difference_options,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>reference_image:</dt>
+<dd>the reference image.</dd>
+<dt>compare_image:</dt>
+<dd>the comparison image.</dd>
+<dt>difference_options:</dt>
+<dd>options to use when differencing.</dd>
+<dt>channel:</dt>
+<dd>the channel(s) to compare.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagechanneldifference">
+<h1><a class="toc-backref" href="#id14">GetImageChannelDifference</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail GetImageChannelDifference( const <a class="reference external" href="../api/types.html#image">Image</a> *reference_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *compare_image,
+ const MetricType metric,
+ DifferenceStatistics *statistics,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>GetImageChannelDifference() updates a user provided statistics structure
+with per-channel, and totalized, difference statistics corresponding
+to a specified comparison metric.</p>
+<p>The format of the GetImageChannelDifference method is:</p>
+<pre class="literal-block">
+MagickPassFail GetImageChannelDifference( const <a class="reference external" href="../api/types.html#image">Image</a> *reference_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *compare_image,
+ const MetricType metric,
+ DifferenceStatistics *statistics,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>reference_image:</dt>
+<dd>the reference image.</dd>
+<dt>compare_image:</dt>
+<dd>the comparison image.</dd>
+<dt>metric:</dt>
+<dd>metric to use when differencing.</dd>
+<dt>statistics:</dt>
+<dd>the statistics structure to populate.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagechanneldistortion">
+<h1><a class="toc-backref" href="#id15">GetImageChannelDistortion</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail GetImageChannelDistortion( const <a class="reference external" href="../api/types.html#image">Image</a> *reference_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *compare_image,
+ const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const MetricType metric, double *distortion,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>GetImageChannelDistortion() updates a distortion parameter with the
+distortion (error) computed according to the specified comparison metric.
+The value returned is only for the channel specified.</p>
+<p>The format of the GetImageChannelDistortion method is:</p>
+<pre class="literal-block">
+MagickPassFail GetImageChannelDistortion( const <a class="reference external" href="../api/types.html#image">Image</a> *reference_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *compare_image,
+ const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const MetricType metric, double *distortion,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>reference_image:</dt>
+<dd>the reference image.</dd>
+<dt>compare_image:</dt>
+<dd>the comparison image.</dd>
+<dt>channel:</dt>
+<dd>the channel to obtain error data for.</dd>
+<dt>metric:</dt>
+<dd>metric to use when differencing.</dd>
+<dt>distortion:</dt>
+<dd>updated with the computed distortion.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagedistortion">
+<h1><a class="toc-backref" href="#id16">GetImageDistortion</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail GetImageDistortion( const <a class="reference external" href="../api/types.html#image">Image</a> *reference_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *compare_image, const MetricType metric,
+ double *distortion, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>GetImageDistortion() updates a distortion parameter with the distortion
+(error) computed according to the specified comparison metric. The value
+returned reflects all enabled channels.</p>
+<p>The format of the GetImageDistortion method is:</p>
+<pre class="literal-block">
+MagickPassFail GetImageDistortion( const <a class="reference external" href="../api/types.html#image">Image</a> *reference_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *compare_image, const MetricType metric,
+ double *distortion, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>reference_image:</dt>
+<dd>the reference image.</dd>
+<dt>compare_image:</dt>
+<dd>the comparison image.</dd>
+<dt>channel:</dt>
+<dd>the channel to obtain error data for.</dd>
+<dt>metric:</dt>
+<dd>metric to use when differencing.</dd>
+<dt>distortion:</dt>
+<dd>updated with the computed distortion.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="isimagesequal">
+<h1><a class="toc-backref" href="#id17">IsImagesEqual</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickBool IsImagesEqual( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *reference );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>IsImagesEqual() measures the difference between colors at each pixel
+location of two images. A value other than 0 means the colors match
+exactly. Otherwise an error measure is computed by summing over all
+pixels in an image the distance squared in RGB space between each image
+pixel and its corresponding pixel in the reference image. The error
+measure is assigned to these image members:</p>
+<p>o mean_error_per_pixel: The mean error for any single pixel in
+the image.</p>
+<p>o normalized_mean_error: The normalized mean quantization error for
+any single pixel in the image. This distance measure is normalized to
+a range between 0 and 1. It is independent of the range of red, green,
+and blue values in the image.</p>
+<p>o normalized_maximum_error: The normalized maximum quantization
+error for any single pixel in the image. This distance measure is
+normalized to a range between 0 and 1. It is independent of the range
+of red, green, and blue values in your image.</p>
+<p>A small normalized mean square error, accessed as
+image-&gt;normalized_mean_error, suggests the images are very similiar in
+spatial layout and color.</p>
+<p>The format of the IsImagesEqual method is:</p>
+<pre class="literal-block">
+MagickBool IsImagesEqual( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *reference );
+</pre>
+<p>A description of each parameter follows.</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>reference:</dt>
+<dd>The reference image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="initializedifferenceimageoptions">
+<h1><a class="toc-backref" href="#id18">InitializeDifferenceImageOptions</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void InitializeDifferenceImageOptions( DifferenceImageOptions *options,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>InitializeDifferenceImageOptions() assigns default options to a user-provided
+DifferenceImageOptions structure. This function should always be used
+to initialize the DifferenceImageOptions structure prior to making any
+changes to it.</p>
+<p>The format of the InitializeDifferenceImageOptions method is:</p>
+<pre class="literal-block">
+void InitializeDifferenceImageOptions( DifferenceImageOptions *options,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>options:</dt>
+<dd>pointer to DifferenceImageOptions structure to initialize.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="initializedifferencestatistics">
+<h1><a class="toc-backref" href="#id19">InitializeDifferenceStatistics</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void InitializeDifferenceStatistics( DifferenceStatistics *options,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>InitializeDifferenceStatistics() assigns default options to a user-provided
+DifferenceStatistics structure.</p>
+<p>The format of the InitializeDifferenceStatistics method is:</p>
+<pre class="literal-block">
+void InitializeDifferenceStatistics( DifferenceStatistics *options,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>options:</dt>
+<dd>pointer to DifferenceStatistics structure to initialize.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/composite.html b/www/api/composite.html
new file mode 100644
index 0000000..fc85811
--- /dev/null
+++ b/www/api/composite.html
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>composite</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="composite">
+<h1 class="title">composite</h1>
+<h2 class="subtitle" id="merge-image-pixels-using-a-specified-algorithm">Merge image pixels using a specified algorithm</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#compositeimage" id="id1">CompositeImage</a></li>
+</ul>
+</div>
+<div class="section" id="compositeimage">
+<h1><a class="toc-backref" href="#id1">CompositeImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail CompositeImage( <a class="reference external" href="../api/types.html#image">Image</a> *canvas_image, const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> compose,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *composite_image, const long x_offset,
+ const long y_offset );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>CompositeImage() composites the second image (composite_image) onto the
+first (canvas_image) at the specified offsets.</p>
+<p>The format of the CompositeImage method is:</p>
+<pre class="literal-block">
+MagickPassFail CompositeImage( <a class="reference external" href="../api/types.html#image">Image</a> *canvas_image, const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> compose,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *composite_image, const long x_offset,
+ const long y_offset );
+</pre>
+<dl class="docutils">
+<dt>canvas_image:</dt>
+<dd>The image to be updated.</dd>
+<dt>compose:</dt>
+<dd>This operator affects how the composite is applied to
+the image. Choose from one of these operators: AddCompositeOp,
+AtopCompositeOp, BumpmapCompositeOp, ClearCompositeOp,
+ColorizeCompositeOp, CopyBlackCompositeOp, CopyBlueCompositeOp,
+CopyCompositeOp, CopyCyanCompositeOp,CopyGreenCompositeOp,
+CopyMagentaCompositeOp, CopyOpacityCompositeOp, CopyRedCompositeOp,
+CopyYellowCompositeOp, DarkenCompositeOp, DifferenceCompositeOp,
+DisplaceCompositeOp, DissolveCompositeOp, DivideCompositeOp,
+HueCompositeOp, InCompositeOp, LightenCompositeOp, LuminizeCompositeOp,
+MinusCompositeOp, ModulateCompositeOp, MultiplyCompositeOp,
+NoCompositeOp, OutCompositeOp, OverlayCompositeOp, PlusCompositeOp,
+SaturateCompositeOp, ScreenCompositeOp, SubtractCompositeOp,
+ThresholdCompositeOp, XorCompositeOp, HardLightCompositeOp.</dd>
+<dt>composite_image:</dt>
+<dd>The composite image.</dd>
+<dt>x_offset:</dt>
+<dd>The column offset of the composited image.</dd>
+<dt>y_offset:</dt>
+<dd>The row offset of the composited image.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/confirm_access.html b/www/api/confirm_access.html
new file mode 100644
index 0000000..418c873
--- /dev/null
+++ b/www/api/confirm_access.html
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>confirm_access</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="confirm-access">
+<h1 class="title">confirm_access</h1>
+<h2 class="subtitle" id="access-confirmation-functions">Access confirmation functions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#magickconfirmaccess" id="id3">MagickConfirmAccess</a></li>
+<li><a class="reference internal" href="#magicksetconfirmaccesshandler" id="id4">MagickSetConfirmAccessHandler</a></li>
+</ul>
+</div>
+<div class="section" id="magickconfirmaccess">
+<h1><a class="toc-backref" href="#id3">MagickConfirmAccess</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail MagickConfirmAccess( const ConfirmAccessMode mode, const char *path,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>MagickConfirmAccess() calls the access confirmation handler method with
+parameters which describe the requested access mode and path/URL, as well
+as an ExceptionInfo structure to update with any error information. A
+user-provided callback (set by MagickSetConfirmAccessHandler()) is
+invoked. If the callback returns MagickFail, then this function also
+returns MagickFail, which is intended to determine if the operation may
+continue. The callback is expected to report the reason access is denied
+by filling out the ExceptionInfo structure. If the callback fails to do
+so, then a generic &quot;access denied&quot; error is reported.</p>
+<p>The format of the MagickConfirmAccess method is:</p>
+<pre class="literal-block">
+MagickPassFail MagickConfirmAccess( const ConfirmAccessMode mode, const char *path,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>mode:</dt>
+<dd>The type of access to be performed.</dd>
+<dt>path:</dt>
+<dd>The local path or URL requested to be accessed.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetconfirmaccesshandler">
+<h1><a class="toc-backref" href="#id4">MagickSetConfirmAccessHandler</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+ConfirmAccessHandler MagickSetConfirmAccessHandler( ConfirmAccessHandler handler );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>MagickSetConfirmAccessHandler() sets the access confirmation handler to
+the specified method and returns the previous access confirmation handler.
+This access confirmation handler is used to &quot;approve&quot; access to files and
+URLs. If the handler returns MagickFalse, then access is denied. This
+mechanism may be used to enforce security policies and/or may be used to
+monitor file and URL accesses.</p>
+<p>The format of the MagickSetConfirmAccessHandler method is:</p>
+<pre class="literal-block">
+ConfirmAccessHandler MagickSetConfirmAccessHandler( ConfirmAccessHandler handler );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>handler:</dt>
+<dd>Specifies a pointer to a method to handle access confirmation.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/constitute.html b/www/api/constitute.html
new file mode 100644
index 0000000..7e86691
--- /dev/null
+++ b/www/api/constitute.html
@@ -0,0 +1,355 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>constitute</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="constitute">
+<h1 class="title">constitute</h1>
+<h2 class="subtitle" id="read-or-write-an-image">Read or write an image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#constituteimage" id="id15">ConstituteImage</a></li>
+<li><a class="reference internal" href="#dispatchimage" id="id16">DispatchImage</a></li>
+<li><a class="reference internal" href="#pingimage" id="id17">PingImage</a></li>
+<li><a class="reference internal" href="#readimage" id="id18">ReadImage</a></li>
+<li><a class="reference internal" href="#readinlineimage" id="id19">ReadInlineImage</a></li>
+<li><a class="reference internal" href="#writeimage" id="id20">WriteImage</a></li>
+<li><a class="reference internal" href="#writeimages" id="id21">WriteImages</a></li>
+<li><a class="reference internal" href="#writeimagesfile" id="id22">WriteImagesFile</a></li>
+</ul>
+</div>
+<div class="section" id="constituteimage">
+<h1><a class="toc-backref" href="#id15">ConstituteImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ConstituteImage( const unsigned long width, const unsigned long height,
+ const char *map, const <a class="reference external" href="../api/types.html#storagetype">StorageType</a> type, const void *pixels,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>ConstituteImage() returns an Image corresponding to an image stored
+in a raw memory array format. The pixel data must be in scanline order
+top-to-bottom. The data can be unsigned char, unsigned short int, unsigned
+int, unsigned long, float, or double. Float and double require the pixels
+to be normalized to the range [0..1], otherwise the range is [0..MaxVal]
+where MaxVal is the maximum possible value for that type.</p>
+<p>Note that for most 32-bit architectures the size of an unsigned long is
+the same as unsigned int, but for 64-bit architectures observing the LP64
+standard, an unsigned long is 64 bits, while an unsigned int remains 32
+bits. This should be considered when deciding if the data should be
+described as &quot;Integer&quot; or &quot;Long&quot;.</p>
+<p>For example, to create a 640x480 image from unsigned red-green-blue
+character data, use</p>
+<p>image=ConstituteImage(640,480,&quot;RGB&quot;,CharPixel,pixels,&amp;exception);</p>
+<p>The format of the Constitute method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ConstituteImage( const unsigned long width, const unsigned long height,
+ const char *map, const <a class="reference external" href="../api/types.html#storagetype">StorageType</a> type, const void *pixels,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>width:</dt>
+<dd>width in pixels of the image.</dd>
+<dt>height:</dt>
+<dd>height in pixels of the image.</dd>
+<dt>map:</dt>
+<dd>This string reflects the expected ordering of the pixel array.
+It can be any combination or order of R = red, G = green, B = blue,
+A = alpha (same as Transparency), O = Opacity, T = Transparency,
+C = cyan, Y = yellow, M = magenta, K = black, or I = intensity
+(for grayscale). Specify &quot;P&quot; = pad, to skip over a quantum which is
+intentionally ignored. Creation of an alpha channel for CMYK images
+is currently not supported.</dd>
+<dt>type:</dt>
+<dd>Define the data type of the pixels. Float and double types are
+expected to be normalized [0..1] otherwise [0..MaxRGB]. Choose from
+these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
+or DoublePixel.</dd>
+<dt>pixels:</dt>
+<dd>This array of values contain the pixel components as defined by
+map and type. You must preallocate this array where the expected
+length varies depending on the values of width, height, map, and type.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="dispatchimage">
+<h1><a class="toc-backref" href="#id16">DispatchImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail DispatchImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x_offset, const long y_offset,
+ const unsigned long columns, const unsigned long rows,
+ const char *map, const <a class="reference external" href="../api/types.html#storagetype">StorageType</a> type, void *pixels,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>DispatchImage() extracts pixel data from an Image into a raw memory array.
+The pixel data is written in scanline order top-to-bottom using an
+arbitrary quantum order specified by 'map', and with quantum size
+specified by 'type'.</p>
+<p>The output array data may be unsigned char, unsigned short int, unsigned
+int, unsigned long, float, or double. Float and double require the pixels
+to be normalized to the range [0..1], otherwise the range is [0..MaxVal]
+where MaxVal is the maximum possible value for that type.</p>
+<p>The method returns MagickPass on success or MagickFail if an error is
+encountered.</p>
+<p>Suppose we want want to extract the first scanline of a 640x480 image as
+character data in red-green-blue order:</p>
+<p>DispatchImage(image,0,0,640,1,&quot;RGB&quot;,0,pixels,exception);</p>
+<p>The format of the DispatchImage method is:</p>
+<pre class="literal-block">
+MagickPassFail DispatchImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x_offset, const long y_offset,
+ const unsigned long columns, const unsigned long rows,
+ const char *map, const <a class="reference external" href="../api/types.html#storagetype">StorageType</a> type, void *pixels,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x_offset, y_offset, columns, rows:</dt>
+<dd>These values define the perimeter
+of a region of pixels you want to extract.</dd>
+<dt>map:</dt>
+<dd>This string reflects the expected ordering of the pixel array.
+It can be any combination or order of R = red, G = green, B = blue,
+A = alpha (same as Transparency), O = Opacity, T = Transparency,
+C = cyan, Y = yellow, M = magenta, K = black, I = intensity (for
+grayscale). Specify &quot;P&quot; = pad, to output a pad quantum. Pad quantums
+are zero-value.</dd>
+<dt>type:</dt>
+<dd>Define the data type of the pixels. Float and double types are
+expected to be normalized [0..1] otherwise [0..MaxRGB]. Choose from
+these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
+or DoublePixel.</dd>
+<dt>pixels:</dt>
+<dd>This array of values contain the pixel components as defined by
+map and type. You must preallocate this array where the expected
+length varies depending on the values of width, height, map, and type.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pingimage">
+<h1><a class="toc-backref" href="#id17">PingImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *PingImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>PingImage() returns all the attributes of an image or image sequence
+except for the pixels. It is much faster and consumes far less memory
+than ReadImage(). On failure, a NULL image is returned and exception
+describes the reason for the failure.</p>
+<p>The format of the PingImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *PingImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>Ping the image defined by the file or filename members of
+this structure.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="readimage">
+<h1><a class="toc-backref" href="#id18">ReadImage</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ReadImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>ReadImage() reads an image or image sequence from a file or file handle.
+The method returns a NULL if there is a memory shortage or if the image
+cannot be read. On failure, a NULL image is returned and exception
+describes the reason for the failure.</p>
+<p>The format of the ReadImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ReadImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>Read the image defined by the file or filename members of
+this structure.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="readinlineimage">
+<h1><a class="toc-backref" href="#id19">ReadInlineImage</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ReadInlineImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *content,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>ReadInlineImage() reads a Base64-encoded inline image or image sequence.
+The method returns a NULL if there is a memory shortage or if the image
+cannot be read. On failure, a NULL image is returned and exception
+describes the reason for the failure.</p>
+<p>The format of the ReadInlineImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ReadInlineImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *content,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>content:</dt>
+<dd>The image encoded in Base64.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="writeimage">
+<h1><a class="toc-backref" href="#id20">WriteImage</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int WriteImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>Use WriteImage() to write an image or an image sequence to a file or
+filehandle. If writing to a file on disk, the name is defined by the
+filename member of the image structure. Write() returns 0 is there is a
+memory shortage or if the image cannot be written. Check the exception
+member of image to determine the cause for any failure.</p>
+<p>The format of the WriteImage method is:</p>
+<pre class="literal-block">
+unsigned int WriteImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="writeimages">
+<h1><a class="toc-backref" href="#id21">WriteImages</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int WriteImages( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image,
+ const char *filename, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>WriteImages() writes an image sequence into one or more files. While
+WriteImage() will also write an image sequence, it is limited to writing
+the sequence into a single file using a format which supports multiple
+frames. WriteImages() does not have that limitation since it will
+generate multiple output files if necessary (or when requested). When
+ImageInfo's adjoin flag is set to MagickFalse, the file name is expected
+to include a printf-style formatting string for the frame number (e.g.
+&quot;image%02d.miff&quot;) so that the frames may be written.</p>
+<p>The format of the WriteImages method is:</p>
+<pre class="literal-block">
+unsigned int WriteImages( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image,
+ const char *filename, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>filename:</dt>
+<dd>The image filename.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="writeimagesfile">
+<h1><a class="toc-backref" href="#id22">WriteImagesFile</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int WriteImagesFile( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image, FILE *file,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>WriteImagesFile() writes an image or image sequence to a stdio
+FILE handle. This may be used to append an encoded image to an already
+existing appended image sequence if the file seek position is at the end
+of an existing file.</p>
+<p>The format of the WriteImagesFile method is:</p>
+<pre class="literal-block">
+unsigned int WriteImagesFile( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image, FILE *file,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>file:</dt>
+<dd>The open (and positioned) file handle.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/decorate.html b/www/api/decorate.html
new file mode 100644
index 0000000..c048b54
--- /dev/null
+++ b/www/api/decorate.html
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>decorate</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="decorate">
+<h1 class="title">decorate</h1>
+<h2 class="subtitle" id="add-decorative-frames-and-borders">Add decorative frames and borders</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#borderimage" id="id5">BorderImage</a></li>
+<li><a class="reference internal" href="#frameimage" id="id6">FrameImage</a></li>
+<li><a class="reference internal" href="#raiseimage" id="id7">RaiseImage</a></li>
+</ul>
+</div>
+<div class="section" id="borderimage">
+<h1><a class="toc-backref" href="#id5">BorderImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *BorderImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *border_info,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>BorderImage() surrounds the image with a border of the color defined by
+the bordercolor member of the image structure. The width and height
+of the border are defined by the corresponding members of the border_info
+structure.</p>
+<p>The format of the BorderImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *BorderImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *border_info,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>border_info:</dt>
+<dd>Define the width and height of the border.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="frameimage">
+<h1><a class="toc-backref" href="#id6">FrameImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *FrameImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#frameinfo">FrameInfo</a> *frame_info,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>FrameImage() adds a simulated three-dimensional border around the image.
+The color of the border is defined by the matte_color member of image.
+Members width and height of frame_info specify the border width of the
+vertical and horizontal sides of the frame. Members inner and outer
+indicate the width of the inner and outer shadows of the frame.</p>
+<p>The format of the FrameImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *FrameImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#frameinfo">FrameInfo</a> *frame_info,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>frame_info:</dt>
+<dd>Define the width and height of the frame and its bevels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="raiseimage">
+<h1><a class="toc-backref" href="#id7">RaiseImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int RaiseImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *raise_info,
+ const int raise_flag );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>RaiseImage() creates a simulated three-dimensional button-like effect
+by lightening and darkening the edges of the image. Members width and
+height of raise_info define the width of the vertical and horizontal
+edge of the effect.</p>
+<p>The format of the RaiseImage method is:</p>
+<pre class="literal-block">
+unsigned int RaiseImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *raise_info,
+ const int raise_flag );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>raise_info:</dt>
+<dd>Define the width and height of the raise area.</dd>
+<dt>raise_flag:</dt>
+<dd>A value other than zero creates a 3-D raise effect,
+otherwise it has a lowered effect.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/deprecate.html b/www/api/deprecate.html
new file mode 100644
index 0000000..13d5940
--- /dev/null
+++ b/www/api/deprecate.html
@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>deprecate</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="deprecate">
+<h1 class="title">deprecate</h1>
+<h2 class="subtitle" id="methods-which-should-no-longer-be-used">Methods which should no longer be used</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#acquirecacheview" id="id19">AcquireCacheView</a></li>
+<li><a class="reference internal" href="#acquirememory" id="id20">AcquireMemory</a></li>
+<li><a class="reference internal" href="#clonememory" id="id21">CloneMemory</a></li>
+<li><a class="reference internal" href="#getcacheview" id="id22">GetCacheView</a></li>
+<li><a class="reference internal" href="#liberatememory" id="id23">LiberateMemory</a></li>
+<li><a class="reference internal" href="#popimagepixels" id="id24">PopImagePixels</a></li>
+<li><a class="reference internal" href="#pushimagepixels" id="id25">PushImagePixels</a></li>
+<li><a class="reference internal" href="#reacquirememory" id="id26">ReacquireMemory</a></li>
+<li><a class="reference internal" href="#setcacheview" id="id27">SetCacheView</a></li>
+<li><a class="reference internal" href="#synccacheview" id="id28">SyncCacheView</a></li>
+</ul>
+</div>
+<div class="section" id="acquirecacheview">
+<h1><a class="toc-backref" href="#id19">AcquireCacheView</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AcquireCacheView( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Method AcquireCacheView gets pixels from the in-memory or disk pixel cache
+as defined by the geometry parameters for read-only access. A pointer to
+the pixels is returned if the pixels are transferred, otherwise NULL is
+returned.</p>
+<p>The format of the AcquireCacheView method is:</p>
+<pre class="literal-block">
+const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AcquireCacheView( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>Method AcquireCacheView returns a null pointer if an error
+occurs, otherwise a pointer to the view pixels.</dd>
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="acquirememory">
+<h1><a class="toc-backref" href="#id20">AcquireMemory</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *AcquireMemory( const size_t size );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>AcquireMemory() returns a pointer to a block of memory of at least size
+bytes suitably aligned for any use. NULL is returned if insufficient
+memory is available or the requested size is zero.</p>
+<p>The format of the AcquireMemory method is:</p>
+<pre class="literal-block">
+void *AcquireMemory( const size_t size );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>size:</dt>
+<dd>The size of the memory in bytes to allocate.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="clonememory">
+<h1><a class="toc-backref" href="#id21">CloneMemory</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *CloneMemory( void *destination, const void *source, const size_t size );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>CloneMemory() copies size bytes from memory area source to the
+destination. Copying between objects that overlap will take place
+correctly. It returns destination.</p>
+<p>The format of the CloneMemory method is:</p>
+<pre class="literal-block">
+void *CloneMemory( void *destination, const void *source, const size_t size );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>size:</dt>
+<dd>The size of the memory in bytes to allocate.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getcacheview">
+<h1><a class="toc-backref" href="#id22">GetCacheView</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetCacheView( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>GetCacheView() gets writeable pixels from the in-memory or disk pixel
+cache as defined by the geometry parameters. A pointer to the pixels
+is returned if the pixels are transferred, otherwise a NULL is returned.</p>
+<p>The format of the GetCacheView method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetCacheView( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>Method GetCacheView returns a null pointer if an error
+occurs, otherwise a pointer to the view pixels.</dd>
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="liberatememory">
+<h1><a class="toc-backref" href="#id23">LiberateMemory</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void LiberateMemory( void ** memory );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>LiberateMemory() frees memory that has already been allocated, and
+NULLs the pointer to it.</p>
+<p>The format of the LiberateMemory method is:</p>
+<pre class="literal-block">
+void LiberateMemory( void ** memory );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>memory:</dt>
+<dd>A pointer to a block of memory to free for reuse.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="popimagepixels">
+<h1><a class="toc-backref" href="#id24">PopImagePixels</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PopImagePixels( const <a class="reference external" href="../api/types.html#image">Image</a> *, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum,
+ unsigned char *destination );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>PopImagePixels() transfers one or more pixel components from the image pixel
+cache to a user supplied buffer. True is returned if the pixels are
+successfully transferred, otherwise False.</p>
+<p>The format of the PopImagePixels method is:</p>
+<pre class="literal-block">
+unsigned int PopImagePixels( const <a class="reference external" href="../api/types.html#image">Image</a> *, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum,
+ unsigned char *destination );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method PopImagePixels returns True if the pixels are
+successfully transferred, otherwise False.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>quantum:</dt>
+<dd>Declare which pixel components to transfer (RGB, RGBA, etc).</dd>
+<dt>destination:</dt>
+<dd>The components are transferred to this buffer.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pushimagepixels">
+<h1><a class="toc-backref" href="#id25">PushImagePixels</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PushImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ const unsigned char *source );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>PushImagePixels() transfers one or more pixel components from a user
+supplied buffer into the image pixel cache of an image. It returns True if
+the pixels are successfully transferred, otherwise False.</p>
+<p>The format of the PushImagePixels method is:</p>
+<pre class="literal-block">
+unsigned int PushImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ const unsigned char *source );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method PushImagePixels returns True if the pixels are
+successfully transferred, otherwise False.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>quantum_type:</dt>
+<dd>Declare which pixel components to transfer (red, green,
+blue, opacity, RGB, or RGBA).</dd>
+<dt>source:</dt>
+<dd>The pixel components are transferred from this buffer.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="reacquirememory">
+<h1><a class="toc-backref" href="#id26">ReacquireMemory</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void ReacquireMemory( void ** memory, const size_t size );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>ReacquireMemory() changes the size of the memory and returns a
+pointer to the (possibly moved) block. The contents will be unchanged
+up to the lesser of the new and old sizes.</p>
+<p>The format of the ReacquireMemory method is:</p>
+<pre class="literal-block">
+void ReacquireMemory( void ** memory, const size_t size );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>memory:</dt>
+<dd>A pointer to a memory allocation. On return the pointer
+may change but the contents of the original allocation will not.</dd>
+<dt>size:</dt>
+<dd>The new size of the allocated memory.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setcacheview">
+<h1><a class="toc-backref" href="#id27">SetCacheView</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *SetCacheView( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>SetCacheView() gets pixels from the in-memory or disk pixel cache as
+defined by the geometry parameters. A pointer to the pixels is returned
+if the pixels are transferred, otherwise a NULL is returned.</p>
+<p>The format of the SetCacheView method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *SetCacheView( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="synccacheview">
+<h1><a class="toc-backref" href="#id28">SyncCacheView</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail SyncCacheView( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>SyncCacheView() saves the view pixels to the in-memory or disk cache.
+The method returns MagickPass if the pixel region is synced, otherwise
+MagickFail.</p>
+<p>The format of the SyncCacheView method is:</p>
+<pre class="literal-block">
+MagickPassFail SyncCacheView( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/describe.html b/www/api/describe.html
new file mode 100644
index 0000000..d0b8a02
--- /dev/null
+++ b/www/api/describe.html
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>describe</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="describe">
+<h1 class="title">describe</h1>
+<h2 class="subtitle" id="methods-to-describe-an-image">Methods to describe an image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#describeimage" id="id1">DescribeImage</a></li>
+</ul>
+</div>
+<div class="section" id="describeimage">
+<h1><a class="toc-backref" href="#id1">DescribeImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DescribeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, FILE *file, const MagickBool verbose );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>DescribeImage() describes an image by printing its attributes to the file.
+Attributes include the image width, height, size, and others.</p>
+<p>The format of the DescribeImage method is:</p>
+<pre class="literal-block">
+void DescribeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, FILE *file, const MagickBool verbose );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>file:</dt>
+<dd>The file, typically stdout.</dd>
+<dt>verbose:</dt>
+<dd>A value other than zero prints more detailed information
+about the image. Values greater than one enable counting the number of
+colors in the image.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/display.html b/www/api/display.html
new file mode 100644
index 0000000..f229e8f
--- /dev/null
+++ b/www/api/display.html
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>display</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="display">
+<h1 class="title">display</h1>
+<h2 class="subtitle" id="interactively-display-and-edit-an-image">Interactively display and edit an image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#magickxdisplaybackgroundimage" id="id3">MagickXDisplayBackgroundImage</a></li>
+<li><a class="reference internal" href="#magickxdisplayimage" id="id4">MagickXDisplayImage</a></li>
+</ul>
+</div>
+<div class="section" id="magickxdisplaybackgroundimage">
+<h1><a class="toc-backref" href="#id3">MagickXDisplayBackgroundImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickXDisplayBackgroundImage( Display *display,
+ <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>MagickXDisplayBackgroundImage() displays an image in the background of a window.</p>
+<p>The format of the MagickXDisplayBackgroundImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickXDisplayBackgroundImage( Display *display,
+ <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>resource_info:</dt>
+<dd>Specifies a pointer to a X11 MagickXResourceInfo structure.</dd>
+<dt>image:</dt>
+<dd>Specifies a pointer to an Image structure; returned from
+ReadImage.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickxdisplayimage">
+<h1><a class="toc-backref" href="#id4">MagickXDisplayImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MagickXDisplayImage( Display *display, <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ char ** argv, int argc, <a class="reference external" href="../api/types.html#image">Image</a> ** image,
+ unsigned long *state );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>MagickXDisplayImage() displays an image via X11. A new image is created and
+returned if the user interactively transforms the displayed image.</p>
+<p>The format of the MagickXDisplayImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MagickXDisplayImage( Display *display, <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ char ** argv, int argc, <a class="reference external" href="../api/types.html#image">Image</a> ** image,
+ unsigned long *state );
+</pre>
+<dl class="docutils">
+<dt>nexus:</dt>
+<dd>Method MagickXDisplayImage returns an image when the
+user chooses 'Open Image' from the command menu or picks a tile
+from the image directory. Otherwise a null image is returned.</dd>
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>resource_info:</dt>
+<dd>Specifies a pointer to a X11 MagickXResourceInfo structure.</dd>
+<dt>argv:</dt>
+<dd>Specifies the application's argument list.</dd>
+<dt>argc:</dt>
+<dd>Specifies the number of arguments.</dd>
+<dt>image:</dt>
+<dd>Specifies an address to an address of an Image structure;
+returned from ReadImage.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/draw.html b/www/api/draw.html
new file mode 100644
index 0000000..34f1692
--- /dev/null
+++ b/www/api/draw.html
@@ -0,0 +1,3223 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>draw</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="draw">
+<h1 class="title">draw</h1>
+<h2 class="subtitle" id="user-friendly-methods-to-draw-on-an-image">User-friendly methods to draw on an image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#drawannotation" id="id225">DrawAnnotation</a></li>
+<li><a class="reference internal" href="#drawaffine" id="id226">DrawAffine</a></li>
+<li><a class="reference internal" href="#drawallocatecontext" id="id227">DrawAllocateContext</a></li>
+<li><a class="reference internal" href="#drawarc" id="id228">DrawArc</a></li>
+<li><a class="reference internal" href="#drawbezier" id="id229">DrawBezier</a></li>
+<li><a class="reference internal" href="#drawcircle" id="id230">DrawCircle</a></li>
+<li><a class="reference internal" href="#drawgetclippath" id="id231">DrawGetClipPath</a></li>
+<li><a class="reference internal" href="#drawsetclippath" id="id232">DrawSetClipPath</a></li>
+<li><a class="reference internal" href="#drawgetcliprule" id="id233">DrawGetClipRule</a></li>
+<li><a class="reference internal" href="#drawsetcliprule" id="id234">DrawSetClipRule</a></li>
+<li><a class="reference internal" href="#drawgetclipunits" id="id235">DrawGetClipUnits</a></li>
+<li><a class="reference internal" href="#drawsetclipunits" id="id236">DrawSetClipUnits</a></li>
+<li><a class="reference internal" href="#drawcolor" id="id237">DrawColor</a></li>
+<li><a class="reference internal" href="#drawcomment" id="id238">DrawComment</a></li>
+<li><a class="reference internal" href="#drawdestroycontext" id="id239">DrawDestroyContext</a></li>
+<li><a class="reference internal" href="#drawellipse" id="id240">DrawEllipse</a></li>
+<li><a class="reference internal" href="#drawgetfillcolor" id="id241">DrawGetFillColor</a></li>
+<li><a class="reference internal" href="#drawsetfillcolor" id="id242">DrawSetFillColor</a></li>
+<li><a class="reference internal" href="#drawsetfillcolorstring" id="id243">DrawSetFillColorString</a></li>
+<li><a class="reference internal" href="#drawsetfillpatternurl" id="id244">DrawSetFillPatternURL</a></li>
+<li><a class="reference internal" href="#drawgetfillopacity" id="id245">DrawGetFillOpacity</a></li>
+<li><a class="reference internal" href="#drawsetfillopacity" id="id246">DrawSetFillOpacity</a></li>
+<li><a class="reference internal" href="#drawgetfillrule" id="id247">DrawGetFillRule</a></li>
+<li><a class="reference internal" href="#drawsetfillrule" id="id248">DrawSetFillRule</a></li>
+<li><a class="reference internal" href="#drawgetfont" id="id249">DrawGetFont</a></li>
+<li><a class="reference internal" href="#drawsetfont" id="id250">DrawSetFont</a></li>
+<li><a class="reference internal" href="#drawgetfontfamily" id="id251">DrawGetFontFamily</a></li>
+<li><a class="reference internal" href="#drawsetfontfamily" id="id252">DrawSetFontFamily</a></li>
+<li><a class="reference internal" href="#drawgetfontsize" id="id253">DrawGetFontSize</a></li>
+<li><a class="reference internal" href="#drawsetfontsize" id="id254">DrawSetFontSize</a></li>
+<li><a class="reference internal" href="#drawgetfontstretch" id="id255">DrawGetFontStretch</a></li>
+<li><a class="reference internal" href="#drawsetfontstretch" id="id256">DrawSetFontStretch</a></li>
+<li><a class="reference internal" href="#drawgetfontstyle" id="id257">DrawGetFontStyle</a></li>
+<li><a class="reference internal" href="#drawsetfontstyle" id="id258">DrawSetFontStyle</a></li>
+<li><a class="reference internal" href="#drawgetfontweight" id="id259">DrawGetFontWeight</a></li>
+<li><a class="reference internal" href="#drawsetfontweight" id="id260">DrawSetFontWeight</a></li>
+<li><a class="reference internal" href="#drawgetgravity" id="id261">DrawGetGravity</a></li>
+<li><a class="reference internal" href="#drawsetgravity" id="id262">DrawSetGravity</a></li>
+<li><a class="reference internal" href="#drawcomposite" id="id263">DrawComposite</a></li>
+<li><a class="reference internal" href="#drawline" id="id264">DrawLine</a></li>
+<li><a class="reference internal" href="#drawmatte" id="id265">DrawMatte</a></li>
+<li><a class="reference internal" href="#drawpathclose" id="id266">DrawPathClose</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoabsolute" id="id267">DrawPathCurveToAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathcurvetorelative" id="id268">DrawPathCurveToRelative</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoquadraticbezierabsolute" id="id269">DrawPathCurveToQuadraticBezierAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoquadraticbezierrelative" id="id270">DrawPathCurveToQuadraticBezierRelative</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoquadraticbeziersmoothabsolute" id="id271">DrawPathCurveToQuadraticBezierSmoothAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoquadraticbeziersmoothrelative" id="id272">DrawPathCurveToQuadraticBezierSmoothRelative</a></li>
+<li><a class="reference internal" href="#drawpathcurvetosmoothabsolute" id="id273">DrawPathCurveToSmoothAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathcurvetosmoothrelative" id="id274">DrawPathCurveToSmoothRelative</a></li>
+<li><a class="reference internal" href="#drawpathellipticarcabsolute" id="id275">DrawPathEllipticArcAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathellipticarcrelative" id="id276">DrawPathEllipticArcRelative</a></li>
+<li><a class="reference internal" href="#drawpathfinish" id="id277">DrawPathFinish</a></li>
+<li><a class="reference internal" href="#drawpathlinetoabsolute" id="id278">DrawPathLineToAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathlinetorelative" id="id279">DrawPathLineToRelative</a></li>
+<li><a class="reference internal" href="#drawpathlinetohorizontalabsolute" id="id280">DrawPathLineToHorizontalAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathlinetohorizontalrelative" id="id281">DrawPathLineToHorizontalRelative</a></li>
+<li><a class="reference internal" href="#drawpathlinetoverticalabsolute" id="id282">DrawPathLineToVerticalAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathlinetoverticalrelative" id="id283">DrawPathLineToVerticalRelative</a></li>
+<li><a class="reference internal" href="#drawpathmovetoabsolute" id="id284">DrawPathMoveToAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathmovetorelative" id="id285">DrawPathMoveToRelative</a></li>
+<li><a class="reference internal" href="#drawpathstart" id="id286">DrawPathStart</a></li>
+<li><a class="reference internal" href="#drawpeekgraphiccontext" id="id287">DrawPeekGraphicContext</a></li>
+<li><a class="reference internal" href="#drawpoint" id="id288">DrawPoint</a></li>
+<li><a class="reference internal" href="#drawpolygon" id="id289">DrawPolygon</a></li>
+<li><a class="reference internal" href="#drawpolyline" id="id290">DrawPolyline</a></li>
+<li><a class="reference internal" href="#drawpopclippath" id="id291">DrawPopClipPath</a></li>
+<li><a class="reference internal" href="#drawpopdefs" id="id292">DrawPopDefs</a></li>
+<li><a class="reference internal" href="#drawpopgraphiccontext" id="id293">DrawPopGraphicContext</a></li>
+<li><a class="reference internal" href="#drawpoppattern" id="id294">DrawPopPattern</a></li>
+<li><a class="reference internal" href="#drawpushclippath" id="id295">DrawPushClipPath</a></li>
+<li><a class="reference internal" href="#drawpushdefs" id="id296">DrawPushDefs</a></li>
+<li><a class="reference internal" href="#drawpushgraphiccontext" id="id297">DrawPushGraphicContext</a></li>
+<li><a class="reference internal" href="#drawpushpattern" id="id298">DrawPushPattern</a></li>
+<li><a class="reference internal" href="#drawrectangle" id="id299">DrawRectangle</a></li>
+<li><a class="reference internal" href="#drawrender" id="id300">DrawRender</a></li>
+<li><a class="reference internal" href="#drawrotate" id="id301">DrawRotate</a></li>
+<li><a class="reference internal" href="#drawroundrectangle" id="id302">DrawRoundRectangle</a></li>
+<li><a class="reference internal" href="#drawscale" id="id303">DrawScale</a></li>
+<li><a class="reference internal" href="#drawskewx" id="id304">DrawSkewX</a></li>
+<li><a class="reference internal" href="#drawskewy" id="id305">DrawSkewY</a></li>
+<li><a class="reference internal" href="#drawsetstopcolor" id="id306">DrawSetStopColor</a></li>
+<li><a class="reference internal" href="#drawgetstrokecolor" id="id307">DrawGetStrokeColor</a></li>
+<li><a class="reference internal" href="#drawsetstrokecolor" id="id308">DrawSetStrokeColor</a></li>
+<li><a class="reference internal" href="#drawsetstrokecolorstring" id="id309">DrawSetStrokeColorString</a></li>
+<li><a class="reference internal" href="#drawsetstrokepatternurl" id="id310">DrawSetStrokePatternURL</a></li>
+<li><a class="reference internal" href="#drawgetstrokeantialias" id="id311">DrawGetStrokeAntialias</a></li>
+<li><a class="reference internal" href="#drawsetstrokeantialias" id="id312">DrawSetStrokeAntialias</a></li>
+<li><a class="reference internal" href="#drawgetstrokedasharray" id="id313">DrawGetStrokeDashArray</a></li>
+<li><a class="reference internal" href="#drawsetstrokedasharray" id="id314">DrawSetStrokeDashArray</a></li>
+<li><a class="reference internal" href="#drawgetstrokedashoffset" id="id315">DrawGetStrokeDashOffset</a></li>
+<li><a class="reference internal" href="#drawsetstrokedashoffset" id="id316">DrawSetStrokeDashOffset</a></li>
+<li><a class="reference internal" href="#drawgetstrokelinecap" id="id317">DrawGetStrokeLineCap</a></li>
+<li><a class="reference internal" href="#drawsetstrokelinecap" id="id318">DrawSetStrokeLineCap</a></li>
+<li><a class="reference internal" href="#drawgetstrokelinejoin" id="id319">DrawGetStrokeLineJoin</a></li>
+<li><a class="reference internal" href="#drawsetstrokelinejoin" id="id320">DrawSetStrokeLineJoin</a></li>
+<li><a class="reference internal" href="#drawgetstrokemiterlimit" id="id321">DrawGetStrokeMiterLimit</a></li>
+<li><a class="reference internal" href="#drawsetstrokemiterlimit" id="id322">DrawSetStrokeMiterLimit</a></li>
+<li><a class="reference internal" href="#drawgetstrokeopacity" id="id323">DrawGetStrokeOpacity</a></li>
+<li><a class="reference internal" href="#drawsetstrokeopacity" id="id324">DrawSetStrokeOpacity</a></li>
+<li><a class="reference internal" href="#drawgetstrokewidth" id="id325">DrawGetStrokeWidth</a></li>
+<li><a class="reference internal" href="#drawsetstrokewidth" id="id326">DrawSetStrokeWidth</a></li>
+<li><a class="reference internal" href="#drawgettextantialias" id="id327">DrawGetTextAntialias</a></li>
+<li><a class="reference internal" href="#drawsettextantialias" id="id328">DrawSetTextAntialias</a></li>
+<li><a class="reference internal" href="#drawgettextdecoration" id="id329">DrawGetTextDecoration</a></li>
+<li><a class="reference internal" href="#drawsettextdecoration" id="id330">DrawSetTextDecoration</a></li>
+<li><a class="reference internal" href="#drawgettextencoding" id="id331">DrawGetTextEncoding</a></li>
+<li><a class="reference internal" href="#drawsettextencoding" id="id332">DrawSetTextEncoding</a></li>
+<li><a class="reference internal" href="#drawgettextundercolor" id="id333">DrawGetTextUnderColor</a></li>
+<li><a class="reference internal" href="#drawsettextundercolor" id="id334">DrawSetTextUnderColor</a></li>
+<li><a class="reference internal" href="#drawsettextundercolorstring" id="id335">DrawSetTextUnderColorString</a></li>
+<li><a class="reference internal" href="#drawtranslate" id="id336">DrawTranslate</a></li>
+<li><a class="reference internal" href="#drawsetviewbox" id="id337">DrawSetViewbox</a></li>
+</ul>
+</div>
+<div class="section" id="drawannotation">
+<h1><a class="toc-backref" href="#id225">DrawAnnotation</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawAnnotation( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y,
+ const unsigned char *text );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>DrawAnnotation() draws text on the image.</p>
+<p>The format of the DrawAnnotation method is:</p>
+<pre class="literal-block">
+void DrawAnnotation( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y,
+ const unsigned char *text );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>x ordinate to left of text</dd>
+<dt>y:</dt>
+<dd>y ordinate to text baseline</dd>
+<dt>text:</dt>
+<dd>text to draw</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawaffine">
+<h1><a class="toc-backref" href="#id226">DrawAffine</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawAffine( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#affinematrix">AffineMatrix</a> *affine );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>DrawAffine() adjusts the current affine transformation matrix with
+the specified affine transformation matrix. Note that the current affine
+transform is adjusted rather than replaced.</p>
+<p>The format of the DrawAffine method is:</p>
+<pre class="literal-block">
+void DrawAffine( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#affinematrix">AffineMatrix</a> *affine );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>Drawing context</dd>
+<dt>affine:</dt>
+<dd>Affine matrix parameters</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawallocatecontext">
+<h1><a class="toc-backref" href="#id227">DrawAllocateContext</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> DrawAllocateContext( const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DrawAllocateContext() allocates an initial drawing context which is an
+opaque handle required by the remaining drawing methods.</p>
+<p>The format of the DrawAllocateContext method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> DrawAllocateContext( const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<dl class="docutils">
+<dt>draw_info:</dt>
+<dd>Initial drawing defaults. Set to NULL to use
+GraphicsMagick defaults.</dd>
+<dt>image:</dt>
+<dd>The image to draw on.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawarc">
+<h1><a class="toc-backref" href="#id228">DrawArc</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawArc( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double sx, const double sy, const double ex,
+ const double ey, const double sd, const double ed );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>DrawArc() draws an arc falling within a specified bounding rectangle on the
+image.</p>
+<p>The format of the DrawArc method is:</p>
+<pre class="literal-block">
+void DrawArc( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double sx, const double sy, const double ex,
+ const double ey, const double sd, const double ed );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>sx:</dt>
+<dd>starting x ordinate of bounding rectangle</dd>
+<dt>sy:</dt>
+<dd>starting y ordinate of bounding rectangle</dd>
+<dt>ex:</dt>
+<dd>ending x ordinate of bounding rectangle</dd>
+<dt>ey:</dt>
+<dd>ending y ordinate of bounding rectangle</dd>
+<dt>sd:</dt>
+<dd>starting degrees of rotation</dd>
+<dt>ed:</dt>
+<dd>ending degrees of rotation</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawbezier">
+<h1><a class="toc-backref" href="#id229">DrawBezier</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawBezier( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long num_coords,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>DrawBezier() draws a bezier curve through a set of points on the image.</p>
+<p>The format of the DrawBezier method is:</p>
+<pre class="literal-block">
+void DrawBezier( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long num_coords,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>num_coords:</dt>
+<dd>number of coordinates</dd>
+<dt>coordinates:</dt>
+<dd>coordinates</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawcircle">
+<h1><a class="toc-backref" href="#id230">DrawCircle</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawCircle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double ox, const double oy, const double px,
+ const double py );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>DrawCircle() draws a circle on the image.</p>
+<p>The format of the DrawCircle method is:</p>
+<pre class="literal-block">
+void DrawCircle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double ox, const double oy, const double px,
+ const double py );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>ox:</dt>
+<dd>origin x ordinate</dd>
+<dt>oy:</dt>
+<dd>origin y ordinate</dd>
+<dt>px:</dt>
+<dd>perimeter x ordinate</dd>
+<dt>py:</dt>
+<dd>perimeter y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetclippath">
+<h1><a class="toc-backref" href="#id231">DrawGetClipPath</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetClipPath( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>DrawGetClipPath() obtains the current clipping path ID. The value returned
+must be deallocated by the user when it is no longer needed.</p>
+<p>The format of the DrawGetClipPath method is:</p>
+<pre class="literal-block">
+char *DrawGetClipPath( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetclippath">
+<h1><a class="toc-backref" href="#id232">DrawSetClipPath</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetClipPath( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *clip_path );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>DrawSetClipPath() associates a named clipping path with the image. Only
+the areas drawn on by the clipping path will be modified as long as it
+remains in effect.</p>
+<p>The format of the DrawSetClipPath method is:</p>
+<pre class="literal-block">
+void DrawSetClipPath( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *clip_path );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>clip_path:</dt>
+<dd>name of clipping path to associate with image</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetcliprule">
+<h1><a class="toc-backref" href="#id233">DrawGetClipRule</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#fillrule">FillRule</a> DrawGetClipRule( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>DrawGetClipRule() returns the current polygon fill rule to be used by the
+clipping path.</p>
+<p>The format of the DrawGetClipRule method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#fillrule">FillRule</a> DrawGetClipRule( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetcliprule">
+<h1><a class="toc-backref" href="#id234">DrawSetClipRule</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetClipRule( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#fillrule">FillRule</a> fill_rule );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>DrawSetClipRule() set the polygon fill rule to be used by the clipping path.</p>
+<p>The format of the DrawSetClipRule method is:</p>
+<pre class="literal-block">
+void DrawSetClipRule( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#fillrule">FillRule</a> fill_rule );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>fill_rule:</dt>
+<dd>fill rule (EvenOddRule or NonZeroRule)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetclipunits">
+<h1><a class="toc-backref" href="#id235">DrawGetClipUnits</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#clippathunits">ClipPathUnits</a> DrawGetClipUnits( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>DrawGetClipUnits() returns the interpretation of clip path units.</p>
+<p>The format of the DrawGetClipUnits method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#clippathunits">ClipPathUnits</a> DrawGetClipUnits( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetclipunits">
+<h1><a class="toc-backref" href="#id236">DrawSetClipUnits</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetClipUnits( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#clippathunits">ClipPathUnits</a> clip_units );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>DrawSetClipUnits() sets the interpretation of clip path units.</p>
+<p>The format of the DrawSetClipUnits method is:</p>
+<pre class="literal-block">
+void DrawSetClipUnits( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#clippathunits">ClipPathUnits</a> clip_units );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>clip_units:</dt>
+<dd>units to use (UserSpace, UserSpaceOnUse, or ObjectBoundingBox)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawcolor">
+<h1><a class="toc-backref" href="#id237">DrawColor</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y,
+ const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> paintMethod );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>DrawColor() draws color on image using the current fill color, starting at
+specified position, and using specified paint method. The available paint
+methods are:</p>
+<p>PointMethod: Recolors the target pixel
+ReplaceMethod: Recolor any pixel that matches the target pixel.
+FloodfillMethod: Recolors target pixels and matching neighbors.
+FillToBorderMethod: Recolor target pixels and neighbors not matching border color.
+ResetMethod: Recolor all pixels.</p>
+<p>The format of the DrawColor method is:</p>
+<pre class="literal-block">
+void DrawColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y,
+ const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> paintMethod );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>x ordinate</dd>
+<dt>y:</dt>
+<dd>y ordinate</dd>
+<dt>paintMethod:</dt>
+<dd>paint method</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawcomment">
+<h1><a class="toc-backref" href="#id238">DrawComment</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawComment( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *comment );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>DrawComment() adds a comment to a vector output stream.</p>
+<p>The format of the DrawComment method is:</p>
+<pre class="literal-block">
+void DrawComment( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *comment );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>comment:</dt>
+<dd>comment text</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawdestroycontext">
+<h1><a class="toc-backref" href="#id239">DrawDestroyContext</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawDestroyContext( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>DrawDestroyContext() frees all resources associated with the drawing
+context. Once the drawing context has been freed, it should not be used
+any further unless it re-allocated.</p>
+<p>The format of the DrawDestroyContext method is:</p>
+<pre class="literal-block">
+void DrawDestroyContext( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context to destroy</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawellipse">
+<h1><a class="toc-backref" href="#id240">DrawEllipse</a></h1>
+<div class="section" id="id29">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawEllipse( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double ox, const double oy, const double rx,
+ const double ry, const double start, const double end );
+</pre>
+</div>
+<div class="section" id="id30">
+<h2>Description</h2>
+<p>DrawEllipse() draws an ellipse on the image.</p>
+<p>The format of the DrawEllipse method is:</p>
+<pre class="literal-block">
+void DrawEllipse( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double ox, const double oy, const double rx,
+ const double ry, const double start, const double end );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>ox:</dt>
+<dd>origin x ordinate</dd>
+<dt>oy:</dt>
+<dd>origin y ordinate</dd>
+<dt>rx:</dt>
+<dd>radius in x</dd>
+<dt>ry:</dt>
+<dd>radius in y</dd>
+<dt>start:</dt>
+<dd>starting rotation in degrees</dd>
+<dt>end:</dt>
+<dd>ending rotation in degrees</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfillcolor">
+<h1><a class="toc-backref" href="#id241">DrawGetFillColor</a></h1>
+<div class="section" id="id31">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> DrawGetFillColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id32">
+<h2>Description</h2>
+<p>DrawGetFillColor() returns the fill color used for drawing filled objects.</p>
+<p>The format of the DrawGetFillColor method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> DrawGetFillColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillcolor">
+<h1><a class="toc-backref" href="#id242">DrawSetFillColor</a></h1>
+<div class="section" id="id33">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *fill_color );
+</pre>
+</div>
+<div class="section" id="id34">
+<h2>Description</h2>
+<p>DrawSetFillColor() sets the fill color to be used for drawing filled objects.</p>
+<p>The format of the DrawSetFillColor method is:</p>
+<pre class="literal-block">
+void DrawSetFillColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *fill_color );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>fill_color:</dt>
+<dd>fill color</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillcolorstring">
+<h1><a class="toc-backref" href="#id243">DrawSetFillColorString</a></h1>
+<div class="section" id="id35">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillColorString( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *fill_color );
+</pre>
+</div>
+<div class="section" id="id36">
+<h2>Description</h2>
+<p>DrawSetFillColorString() sets the fill color to be used for drawing filled
+objects.</p>
+<p>The format of the DrawSetFillColorString method is:</p>
+<pre class="literal-block">
+void DrawSetFillColorString( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *fill_color );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>fill_color:</dt>
+<dd>fill color</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillpatternurl">
+<h1><a class="toc-backref" href="#id244">DrawSetFillPatternURL</a></h1>
+<div class="section" id="id37">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillPatternURL( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *fill_url );
+</pre>
+</div>
+<div class="section" id="id38">
+<h2>Description</h2>
+<p>DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
+objects. Only local URLs (&quot;#identifier&quot;) are supported at this time. These
+local URLs are normally created by defining a named fill pattern with
+DrawPushPattern/DrawPopPattern.</p>
+<p>The format of the DrawSetFillPatternURL method is:</p>
+<pre class="literal-block">
+void DrawSetFillPatternURL( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *fill_url );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>fill_url:</dt>
+<dd>URL to use to obtain fill pattern.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfillopacity">
+<h1><a class="toc-backref" href="#id245">DrawGetFillOpacity</a></h1>
+<div class="section" id="id39">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetFillOpacity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id40">
+<h2>Description</h2>
+<p>DrawGetFillOpacity() returns the opacity used when drawing using the fill
+color or fill texture. Fully opaque is 1.0.</p>
+<p>The format of the DrawGetFillOpacity method is:</p>
+<pre class="literal-block">
+double DrawGetFillOpacity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillopacity">
+<h1><a class="toc-backref" href="#id246">DrawSetFillOpacity</a></h1>
+<div class="section" id="id41">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillOpacity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double fill_opacity );
+</pre>
+</div>
+<div class="section" id="id42">
+<h2>Description</h2>
+<p>DrawSetFillOpacity() sets the opacity to use when drawing using the fill
+color or fill texture. Fully opaque is 1.0.</p>
+<p>The format of the DrawSetFillOpacity method is:</p>
+<pre class="literal-block">
+void DrawSetFillOpacity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double fill_opacity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>fill_opacity:</dt>
+<dd>fill opacity</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfillrule">
+<h1><a class="toc-backref" href="#id247">DrawGetFillRule</a></h1>
+<div class="section" id="id43">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#fillrule">FillRule</a> DrawGetFillRule( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id44">
+<h2>Description</h2>
+<p>DrawGetFillRule() returns the fill rule used while drawing polygons.</p>
+<p>The format of the DrawGetFillRule method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#fillrule">FillRule</a> DrawGetFillRule( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillrule">
+<h1><a class="toc-backref" href="#id248">DrawSetFillRule</a></h1>
+<div class="section" id="id45">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillRule( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#fillrule">FillRule</a> fill_rule );
+</pre>
+</div>
+<div class="section" id="id46">
+<h2>Description</h2>
+<p>DrawSetFillRule() sets the fill rule to use while drawing polygons.</p>
+<p>The format of the DrawSetFillRule method is:</p>
+<pre class="literal-block">
+void DrawSetFillRule( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#fillrule">FillRule</a> fill_rule );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>fill_rule:</dt>
+<dd>fill rule (EvenOddRule or NonZeroRule)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfont">
+<h1><a class="toc-backref" href="#id249">DrawGetFont</a></h1>
+<div class="section" id="id47">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetFont( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id48">
+<h2>Description</h2>
+<p>DrawGetFont() returns a null-terminaged string specifying the font used
+when annotating with text. The value returned must be freed by the user
+when no longer needed.</p>
+<p>The format of the DrawGetFont method is:</p>
+<pre class="literal-block">
+char *DrawGetFont( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfont">
+<h1><a class="toc-backref" href="#id250">DrawSetFont</a></h1>
+<div class="section" id="id49">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFont( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *font_name );
+</pre>
+</div>
+<div class="section" id="id50">
+<h2>Description</h2>
+<p>DrawSetFont() sets the fully-sepecified font to use when annotating with
+text.</p>
+<p>The format of the DrawSetFont method is:</p>
+<pre class="literal-block">
+void DrawSetFont( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *font_name );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>font_name:</dt>
+<dd>font name</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontfamily">
+<h1><a class="toc-backref" href="#id251">DrawGetFontFamily</a></h1>
+<div class="section" id="id51">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetFontFamily( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id52">
+<h2>Description</h2>
+<p>DrawGetFontFamily() returns the font family to use when annotating with text.
+The value returned must be freed by the user when it is no longer needed.</p>
+<p>The format of the DrawGetFontFamily method is:</p>
+<pre class="literal-block">
+char *DrawGetFontFamily( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontfamily">
+<h1><a class="toc-backref" href="#id252">DrawSetFontFamily</a></h1>
+<div class="section" id="id53">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontFamily( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *font_family );
+</pre>
+</div>
+<div class="section" id="id54">
+<h2>Description</h2>
+<p>DrawSetFontFamily() sets the font family to use when annotating with text.</p>
+<p>The format of the DrawSetFontFamily method is:</p>
+<pre class="literal-block">
+void DrawSetFontFamily( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *font_family );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>font_family:</dt>
+<dd>font family</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontsize">
+<h1><a class="toc-backref" href="#id253">DrawGetFontSize</a></h1>
+<div class="section" id="id55">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetFontSize( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id56">
+<h2>Description</h2>
+<p>DrawGetFontSize() returns the font pointsize used when annotating with text.</p>
+<p>The format of the DrawGetFontSize method is:</p>
+<pre class="literal-block">
+double DrawGetFontSize( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontsize">
+<h1><a class="toc-backref" href="#id254">DrawSetFontSize</a></h1>
+<div class="section" id="id57">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontSize( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double pointsize );
+</pre>
+</div>
+<div class="section" id="id58">
+<h2>Description</h2>
+<p>DrawSetFontSize() sets the font pointsize to use when annotating with text.</p>
+<p>The format of the DrawSetFontSize method is:</p>
+<pre class="literal-block">
+void DrawSetFontSize( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double pointsize );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>pointsize:</dt>
+<dd>text pointsize</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontstretch">
+<h1><a class="toc-backref" href="#id255">DrawGetFontStretch</a></h1>
+<div class="section" id="id59">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#stretchtype">StretchType</a> DrawGetFontStretch( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id60">
+<h2>Description</h2>
+<p>DrawGetFontStretch() returns the font stretch used when annotating with text.</p>
+<p>The format of the DrawGetFontStretch method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#stretchtype">StretchType</a> DrawGetFontStretch( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontstretch">
+<h1><a class="toc-backref" href="#id256">DrawSetFontStretch</a></h1>
+<div class="section" id="id61">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontStretch( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#stretchtype">StretchType</a> font_stretch );
+</pre>
+</div>
+<div class="section" id="id62">
+<h2>Description</h2>
+<p>DrawSetFontStretch() sets the font stretch to use when annotating with text.
+The AnyStretch enumeration acts as a wild-card &quot;don't care&quot; option.</p>
+<p>The format of the DrawSetFontStretch method is:</p>
+<pre class="literal-block">
+void DrawSetFontStretch( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#stretchtype">StretchType</a> font_stretch );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>font_stretch:</dt>
+<dd>font stretch (NormalStretch, UltraCondensedStretch,
+CondensedStretch, SemiCondensedStretch,
+SemiExpandedStretch, ExpandedStretch,
+ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontstyle">
+<h1><a class="toc-backref" href="#id257">DrawGetFontStyle</a></h1>
+<div class="section" id="id63">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#styletype">StyleType</a> DrawGetFontStyle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id64">
+<h2>Description</h2>
+<p>DrawGetFontStyle() returns the font style used when annotating with text.</p>
+<p>The format of the DrawGetFontStyle method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#styletype">StyleType</a> DrawGetFontStyle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontstyle">
+<h1><a class="toc-backref" href="#id258">DrawSetFontStyle</a></h1>
+<div class="section" id="id65">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontStyle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#styletype">StyleType</a> style );
+</pre>
+</div>
+<div class="section" id="id66">
+<h2>Description</h2>
+<p>DrawSetFontStyle() sets the font style to use when annotating with text.
+The AnyStyle enumeration acts as a wild-card &quot;don't care&quot; option.</p>
+<p>The format of the DrawSetFontStyle method is:</p>
+<pre class="literal-block">
+void DrawSetFontStyle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#styletype">StyleType</a> style );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>style:</dt>
+<dd>font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontweight">
+<h1><a class="toc-backref" href="#id259">DrawGetFontWeight</a></h1>
+<div class="section" id="id67">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long DrawGetFontWeight( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id68">
+<h2>Description</h2>
+<p>DrawGetFontWeight() returns the font weight used when annotating with text.</p>
+<p>The format of the DrawGetFontWeight method is:</p>
+<pre class="literal-block">
+unsigned long DrawGetFontWeight( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontweight">
+<h1><a class="toc-backref" href="#id260">DrawSetFontWeight</a></h1>
+<div class="section" id="id69">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontWeight( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long font_weight );
+</pre>
+</div>
+<div class="section" id="id70">
+<h2>Description</h2>
+<p>DrawSetFontWeight() sets the font weight to use when annotating with text.</p>
+<p>The format of the DrawSetFontWeight method is:</p>
+<pre class="literal-block">
+void DrawSetFontWeight( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long font_weight );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>font_weight:</dt>
+<dd>font weight (valid range 100-900)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetgravity">
+<h1><a class="toc-backref" href="#id261">DrawGetGravity</a></h1>
+<div class="section" id="id71">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#gravitytype">GravityType</a> DrawGetGravity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id72">
+<h2>Description</h2>
+<p>DrawGetGravity() returns the text placement gravity used when annotating
+with text.</p>
+<p>The format of the DrawGetGravity method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#gravitytype">GravityType</a> DrawGetGravity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetgravity">
+<h1><a class="toc-backref" href="#id262">DrawSetGravity</a></h1>
+<div class="section" id="id73">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetGravity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#gravitytype">GravityType</a> gravity );
+</pre>
+</div>
+<div class="section" id="id74">
+<h2>Description</h2>
+<p>DrawSetGravity() sets the text placement gravity to use when annotating
+with text.</p>
+<p>The format of the DrawSetGravity method is:</p>
+<pre class="literal-block">
+void DrawSetGravity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#gravitytype">GravityType</a> gravity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>gravity:</dt>
+<dd>positioning gravity (NorthWestGravity, NorthGravity,
+NorthEastGravity, WestGravity, CenterGravity,
+EastGravity, SouthWestGravity, SouthGravity,
+SouthEastGravity)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawcomposite">
+<h1><a class="toc-backref" href="#id263">DrawComposite</a></h1>
+<div class="section" id="id75">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawComposite( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> composite_operator,
+ const double x, const double y, const double width, const double height,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id76">
+<h2>Description</h2>
+<p>DrawComposite() composites an image onto the current image, using the
+specified composition operator, specified position, and at the specified
+size.</p>
+<p>The format of the DrawComposite method is:</p>
+<pre class="literal-block">
+void DrawComposite( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> composite_operator,
+ const double x, const double y, const double width, const double height,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>composite_operator:</dt>
+<dd>composition operator</dd>
+<dt>x:</dt>
+<dd>x ordinate of top left corner</dd>
+<dt>y:</dt>
+<dd>y ordinate of top left corner</dd>
+<dt>width:</dt>
+<dd>Width to resize image to prior to compositing. Specify zero to
+use existing width.</dd>
+<dt>height:</dt>
+<dd>Height to resize image to prior to compositing. Specify zero
+to use existing height.</dd>
+<dt>image:</dt>
+<dd>Image to composite</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawline">
+<h1><a class="toc-backref" href="#id264">DrawLine</a></h1>
+<div class="section" id="id77">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawLine( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double sx, const double sy, const double ex,
+ const double ey );
+</pre>
+</div>
+<div class="section" id="id78">
+<h2>Description</h2>
+<p>DrawLine() draws a line on the image using the current stroke color,
+stroke opacity, and stroke width.</p>
+<p>The format of the DrawLine method is:</p>
+<pre class="literal-block">
+void DrawLine( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double sx, const double sy, const double ex,
+ const double ey );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>sx:</dt>
+<dd>starting x ordinate</dd>
+<dt>sy:</dt>
+<dd>starting y ordinate</dd>
+<dt>ex:</dt>
+<dd>ending x ordinate</dd>
+<dt>ey:</dt>
+<dd>ending y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawmatte">
+<h1><a class="toc-backref" href="#id265">DrawMatte</a></h1>
+<div class="section" id="id79">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawMatte( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y,
+ const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> paint_method );
+</pre>
+</div>
+<div class="section" id="id80">
+<h2>Description</h2>
+<p>DrawMatte() paints on the image's opacity channel in order to set effected
+pixels to transparent. The available paint methods are:</p>
+<p>PointMethod: Select the target pixel
+ReplaceMethod: Select any pixel that matches the target pixel.
+FloodfillMethod: Select the target pixel and matching neighbors.
+FillToBorderMethod: Select the target pixel and neighbors not matching
+border color.
+ResetMethod: Select all pixels.</p>
+<p>The format of the DrawMatte method is:</p>
+<pre class="literal-block">
+void DrawMatte( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y,
+ const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> paint_method );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>x ordinate</dd>
+<dt>y:</dt>
+<dd>y ordinate</dd>
+</dl>
+<p>o paint_method:</p>
+</div>
+</div>
+<div class="section" id="drawpathclose">
+<h1><a class="toc-backref" href="#id266">DrawPathClose</a></h1>
+<div class="section" id="id81">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathClose( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id82">
+<h2>Description</h2>
+<p>DrawPathClose() adds a path element to the current path which closes the
+current subpath by drawing a straight line from the current point to the
+current subpath's most recent starting point (usually, the most recent
+moveto point).</p>
+<p>The format of the DrawPathClose method is:</p>
+<pre class="literal-block">
+void DrawPathClose( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoabsolute">
+<h1><a class="toc-backref" href="#id267">DrawPathCurveToAbsolute</a></h1>
+<div class="section" id="id83">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1, const double y1,
+ const double x2, const double y2, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id84">
+<h2>Description</h2>
+<p>DrawPathCurveToAbsolute() draws a cubic Bézier curve from the current
+point to (x,y) using (x1,y1) as the control point at the beginning of
+the curve and (x2,y2) as the control point at the end of the curve using
+absolute coordinates. At the end of the command, the new current point
+becomes the final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1, const double y1,
+ const double x2, const double y2, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x1:</dt>
+<dd>x ordinate of control point for curve beginning</dd>
+<dt>y1:</dt>
+<dd>y ordinate of control point for curve beginning</dd>
+<dt>x2:</dt>
+<dd>x ordinate of control point for curve ending</dd>
+<dt>y2:</dt>
+<dd>y ordinate of control point for curve ending</dd>
+<dt>x:</dt>
+<dd>x ordinate of the end of the curve</dd>
+<dt>y:</dt>
+<dd>y ordinate of the end of the curve</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetorelative">
+<h1><a class="toc-backref" href="#id268">DrawPathCurveToRelative</a></h1>
+<div class="section" id="id85">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1, const double y1,
+ const double x2, const double y2, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id86">
+<h2>Description</h2>
+<p>DrawPathCurveToRelative() draws a cubic Bézier curve from the current
+point to (x,y) using (x1,y1) as the control point at the beginning of
+the curve and (x2,y2) as the control point at the end of the curve using
+relative coordinates. At the end of the command, the new current point
+becomes the final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToRelative method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1, const double y1,
+ const double x2, const double y2, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x1:</dt>
+<dd>x ordinate of control point for curve beginning</dd>
+<dt>y1:</dt>
+<dd>y ordinate of control point for curve beginning</dd>
+<dt>x2:</dt>
+<dd>x ordinate of control point for curve ending</dd>
+<dt>y2:</dt>
+<dd>y ordinate of control point for curve ending</dd>
+<dt>x:</dt>
+<dd>x ordinate of the end of the curve</dd>
+<dt>y:</dt>
+<dd>y ordinate of the end of the curve</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoquadraticbezierabsolute">
+<h1><a class="toc-backref" href="#id269">DrawPathCurveToQuadraticBezierAbsolute</a></h1>
+<div class="section" id="id87">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1,
+ const double y1, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id88">
+<h2>Description</h2>
+<p>DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bézier curve
+from the current point to (x,y) using (x1,y1) as the control point using
+absolute coordinates. At the end of the command, the new current point
+becomes the final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToQuadraticBezierAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1,
+ const double y1, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x1:</dt>
+<dd>x ordinate of the control point</dd>
+<dt>y1:</dt>
+<dd>y ordinate of the control point</dd>
+<dt>x:</dt>
+<dd>x ordinate of final point</dd>
+<dt>y:</dt>
+<dd>y ordinate of final point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoquadraticbezierrelative">
+<h1><a class="toc-backref" href="#id270">DrawPathCurveToQuadraticBezierRelative</a></h1>
+<div class="section" id="id89">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1,
+ const double y1, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id90">
+<h2>Description</h2>
+<p>DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bézier curve
+from the current point to (x,y) using (x1,y1) as the control point using
+relative coordinates. At the end of the command, the new current point
+becomes the final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToQuadraticBezierRelative method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1,
+ const double y1, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x1:</dt>
+<dd>x ordinate of the control point</dd>
+<dt>y1:</dt>
+<dd>y ordinate of the control point</dd>
+<dt>x:</dt>
+<dd>x ordinate of final point</dd>
+<dt>y:</dt>
+<dd>y ordinate of final point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoquadraticbeziersmoothabsolute">
+<h1><a class="toc-backref" href="#id271">DrawPathCurveToQuadraticBezierSmoothAbsolute</a></h1>
+<div class="section" id="id91">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierSmoothAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id92">
+<h2>Description</h2>
+<p>DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
+Bézier curve (using absolute coordinates) from the current point to
+(x,y). The control point is assumed to be the reflection of the
+control point on the previous command relative to the current
+point. (If there is no previous command or if the previous command was
+not a DrawPathCurveToQuadraticBezierAbsolute,
+DrawPathCurveToQuadraticBezierRelative,
+DrawPathCurveToQuadraticBezierSmoothAbsolut or
+DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
+is coincident with the current point.). At the end of the command, the
+new current point becomes the final (x,y) coordinate pair used in the
+polybezier.</p>
+<p>The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierSmoothAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>x ordinate of final point</dd>
+<dt>y:</dt>
+<dd>y ordinate of final point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoquadraticbeziersmoothrelative">
+<h1><a class="toc-backref" href="#id272">DrawPathCurveToQuadraticBezierSmoothRelative</a></h1>
+<div class="section" id="id93">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierSmoothRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id94">
+<h2>Description</h2>
+<p>DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
+Bézier curve (using relative coordinates) from the current point to
+(x,y). The control point is assumed to be the reflection of the
+control point on the previous command relative to the current
+point. (If there is no previous command or if the previous command was
+not a DrawPathCurveToQuadraticBezierAbsolute,
+DrawPathCurveToQuadraticBezierRelative,
+DrawPathCurveToQuadraticBezierSmoothAbsolut or
+DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
+is coincident with the current point.). At the end of the command, the
+new current point becomes the final (x,y) coordinate pair used in the
+polybezier.</p>
+<p>The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierSmoothRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>x ordinate of final point</dd>
+<dt>y:</dt>
+<dd>y ordinate of final point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetosmoothabsolute">
+<h1><a class="toc-backref" href="#id273">DrawPathCurveToSmoothAbsolute</a></h1>
+<div class="section" id="id95">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToSmoothAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x2, const double y2,
+ const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id96">
+<h2>Description</h2>
+<p>DrawPathCurveToSmoothAbsolute() draws a cubic Bézier curve from the
+current point to (x,y) using absolute coordinates. The first control
+point is assumed to be the reflection of the second control point on
+the previous command relative to the current point. (If there is no
+previous command or if the previous command was not an
+DrawPathCurveToAbsolute, DrawPathCurveToRelative,
+DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
+the first control point is coincident with the current point.) (x2,y2)
+is the second control point (i.e., the control point at the end of the
+curve). At the end of the command, the new current point becomes the
+final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToSmoothAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToSmoothAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x2, const double y2,
+ const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x2:</dt>
+<dd>x ordinate of second control point</dd>
+<dt>y2:</dt>
+<dd>y ordinate of second control point</dd>
+<dt>x:</dt>
+<dd>x ordinate of termination point</dd>
+<dt>y:</dt>
+<dd>y ordinate of termination point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetosmoothrelative">
+<h1><a class="toc-backref" href="#id274">DrawPathCurveToSmoothRelative</a></h1>
+<div class="section" id="id97">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToSmoothRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x2, const double y2,
+ const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id98">
+<h2>Description</h2>
+<p>DrawPathCurveToSmoothRelative() draws a cubic Bézier curve from the
+current point to (x,y) using relative coordinates. The first control
+point is assumed to be the reflection of the second control point on
+the previous command relative to the current point. (If there is no
+previous command or if the previous command was not an
+DrawPathCurveToAbsolute, DrawPathCurveToRelative,
+DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
+the first control point is coincident with the current point.) (x2,y2)
+is the second control point (i.e., the control point at the end of the
+curve). At the end of the command, the new current point becomes the
+final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToSmoothRelative method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToSmoothRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x2, const double y2,
+ const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x2:</dt>
+<dd>x ordinate of second control point</dd>
+<dt>y2:</dt>
+<dd>y ordinate of second control point</dd>
+<dt>x:</dt>
+<dd>x ordinate of termination point</dd>
+<dt>y:</dt>
+<dd>y ordinate of termination point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathellipticarcabsolute">
+<h1><a class="toc-backref" href="#id275">DrawPathEllipticArcAbsolute</a></h1>
+<div class="section" id="id99">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathEllipticArcAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag, unsigned int sweep_flag,
+ const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id100">
+<h2>Description</h2>
+<p>DrawPathEllipticArcAbsolute() draws an elliptical arc from the current
+point to (x, y) using absolute coordinates. The size and orientation
+of the ellipse are defined by two radii (rx, ry) and an
+xAxisRotation, which indicates how the ellipse as a whole is rotated
+relative to the current coordinate system. The center (cx, cy) of the
+ellipse is calculated automatically to satisfy the constraints imposed
+by the other parameters. largeArcFlag and sweepFlag contribute to the
+automatic calculations and help determine how the arc is drawn. If
+largeArcFlag is true then draw the larger of the available arcs. If
+sweepFlag is true, then draw the arc matching a clock-wise rotation.</p>
+<p>The format of the DrawPathEllipticArcAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathEllipticArcAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag, unsigned int sweep_flag,
+ const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>rx:</dt>
+<dd>x radius</dd>
+<dt>ry:</dt>
+<dd>y radius</dd>
+<dt>x_axis_rotation:</dt>
+<dd>indicates how the ellipse as a whole is rotated
+relative to the current coordinate system</dd>
+<dt>large_arc_flag:</dt>
+<dd>If non-zero (true) then draw the larger of the
+available arcs</dd>
+<dt>sweep_flag:</dt>
+<dd>If non-zero (true) then draw the arc matching a
+clock-wise rotation</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathellipticarcrelative">
+<h1><a class="toc-backref" href="#id276">DrawPathEllipticArcRelative</a></h1>
+<div class="section" id="id101">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathEllipticArcRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag, unsigned int sweep_flag,
+ const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id102">
+<h2>Description</h2>
+<p>DrawPathEllipticArcRelative() draws an elliptical arc from the current
+point to (x, y) using relative coordinates. The size and orientation
+of the ellipse are defined by two radii (rx, ry) and an
+xAxisRotation, which indicates how the ellipse as a whole is rotated
+relative to the current coordinate system. The center (cx, cy) of the
+ellipse is calculated automatically to satisfy the constraints imposed
+by the other parameters. largeArcFlag and sweepFlag contribute to the
+automatic calculations and help determine how the arc is drawn. If
+largeArcFlag is true then draw the larger of the available arcs. If
+sweepFlag is true, then draw the arc matching a clock-wise rotation.</p>
+<p>The format of the DrawPathEllipticArcRelative method is:</p>
+<pre class="literal-block">
+void DrawPathEllipticArcRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag, unsigned int sweep_flag,
+ const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>rx:</dt>
+<dd>x radius</dd>
+<dt>ry:</dt>
+<dd>y radius</dd>
+<dt>x_axis_rotation:</dt>
+<dd>indicates how the ellipse as a whole is rotated
+relative to the current coordinate system</dd>
+<dt>large_arc_flag:</dt>
+<dd>If non-zero (true) then draw the larger of the
+available arcs</dd>
+<dt>sweep_flag:</dt>
+<dd>If non-zero (true) then draw the arc matching a
+clock-wise rotation</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathfinish">
+<h1><a class="toc-backref" href="#id277">DrawPathFinish</a></h1>
+<div class="section" id="id103">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathFinish( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id104">
+<h2>Description</h2>
+<p>DrawPathFinish() terminates the current path.</p>
+<p>The format of the DrawPathFinish method is:</p>
+<pre class="literal-block">
+void DrawPathFinish( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetoabsolute">
+<h1><a class="toc-backref" href="#id278">DrawPathLineToAbsolute</a></h1>
+<div class="section" id="id105">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id106">
+<h2>Description</h2>
+<p>DrawPathLineToAbsolute() draws a line path from the current point to the
+given coordinate using absolute coordinates. The coordinate then becomes
+the new current point.</p>
+<p>The format of the DrawPathLineToAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathLineToAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetorelative">
+<h1><a class="toc-backref" href="#id279">DrawPathLineToRelative</a></h1>
+<div class="section" id="id107">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id108">
+<h2>Description</h2>
+<p>DrawPathLineToRelative() draws a line path from the current point to the
+given coordinate using relative coordinates. The coordinate then becomes
+the new current point.</p>
+<p>The format of the DrawPathLineToRelative method is:</p>
+<pre class="literal-block">
+void DrawPathLineToRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetohorizontalabsolute">
+<h1><a class="toc-backref" href="#id280">DrawPathLineToHorizontalAbsolute</a></h1>
+<div class="section" id="id109">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToHorizontalAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x );
+</pre>
+</div>
+<div class="section" id="id110">
+<h2>Description</h2>
+<p>DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
+current point to the target point using absolute coordinates. The target
+point then becomes the new current point.</p>
+<p>The format of the DrawPathLineToHorizontalAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathLineToHorizontalAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetohorizontalrelative">
+<h1><a class="toc-backref" href="#id281">DrawPathLineToHorizontalRelative</a></h1>
+<div class="section" id="id111">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToHorizontalRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x );
+</pre>
+</div>
+<div class="section" id="id112">
+<h2>Description</h2>
+<p>DrawPathLineToHorizontalRelative() draws a horizontal line path from the
+current point to the target point using relative coordinates. The target
+point then becomes the new current point.</p>
+<p>The format of the DrawPathLineToHorizontalRelative method is:</p>
+<pre class="literal-block">
+void DrawPathLineToHorizontalRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetoverticalabsolute">
+<h1><a class="toc-backref" href="#id282">DrawPathLineToVerticalAbsolute</a></h1>
+<div class="section" id="id113">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToVerticalAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double y );
+</pre>
+</div>
+<div class="section" id="id114">
+<h2>Description</h2>
+<p>DrawPathLineToVerticalAbsolute() draws a vertical line path from the
+current point to the target point using absolute coordinates. The target
+point then becomes the new current point.</p>
+<p>The format of the DrawPathLineToVerticalAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathLineToVerticalAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetoverticalrelative">
+<h1><a class="toc-backref" href="#id283">DrawPathLineToVerticalRelative</a></h1>
+<div class="section" id="id115">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToVerticalRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double y );
+</pre>
+</div>
+<div class="section" id="id116">
+<h2>Description</h2>
+<p>DrawPathLineToVerticalRelative() draws a vertical line path from the
+current point to the target point using relative coordinates. The target
+point then becomes the new current point.</p>
+<p>The format of the DrawPathLineToVerticalRelative method is:</p>
+<pre class="literal-block">
+void DrawPathLineToVerticalRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathmovetoabsolute">
+<h1><a class="toc-backref" href="#id284">DrawPathMoveToAbsolute</a></h1>
+<div class="section" id="id117">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathMoveToAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id118">
+<h2>Description</h2>
+<p>DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
+using absolute coordinates. The current point then becomes the
+specified coordinate.</p>
+<p>The format of the DrawPathMoveToAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathMoveToAbsolute( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathmovetorelative">
+<h1><a class="toc-backref" href="#id285">DrawPathMoveToRelative</a></h1>
+<div class="section" id="id119">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathMoveToRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id120">
+<h2>Description</h2>
+<p>DrawPathMoveToRelative() starts a new sub-path at the given coordinate
+using relative coordinates. The current point then becomes the
+specified coordinate.</p>
+<p>The format of the DrawPathMoveToRelative method is:</p>
+<pre class="literal-block">
+void DrawPathMoveToRelative( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathstart">
+<h1><a class="toc-backref" href="#id286">DrawPathStart</a></h1>
+<div class="section" id="id121">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathStart( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id122">
+<h2>Description</h2>
+<p>DrawPathStart() declares the start of a path drawing list which is terminated
+by a matching DrawPathFinish() command. All other DrawPath commands must
+be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
+is because path drawing commands are subordinate commands and they do not
+function by themselves.</p>
+<p>The format of the DrawPathStart method is:</p>
+<pre class="literal-block">
+void DrawPathStart( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpeekgraphiccontext">
+<h1><a class="toc-backref" href="#id287">DrawPeekGraphicContext</a></h1>
+<div class="section" id="id123">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *DrawPeekGraphicContext( const <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id124">
+<h2>Description</h2>
+<p>DrawPeekGraphicContext() returns a copy of the the DrawInfo structure at
+the head of the drawing context stack. The user is responsible for
+deallocating the returned object using DestroyDrawInfo.</p>
+<p>The format of the DrawPeekGraphicContext method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *DrawPeekGraphicContext( const <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpoint">
+<h1><a class="toc-backref" href="#id288">DrawPoint</a></h1>
+<div class="section" id="id125">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPoint( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id126">
+<h2>Description</h2>
+<p>DrawPoint() draws a point using the current stroke color and stroke
+thickness at the specified coordinates.</p>
+<p>The format of the DrawPoint method is:</p>
+<pre class="literal-block">
+void DrawPoint( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>target x coordinate</dd>
+<dt>y:</dt>
+<dd>target y coordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpolygon">
+<h1><a class="toc-backref" href="#id289">DrawPolygon</a></h1>
+<div class="section" id="id127">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPolygon( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long num_coords,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+</div>
+<div class="section" id="id128">
+<h2>Description</h2>
+<p>DrawPolygon() draws a polygon using the current stroke, stroke width, and
+fill color or texture, using the specified array of coordinates.</p>
+<p>The format of the DrawPolygon method is:</p>
+<pre class="literal-block">
+void DrawPolygon( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long num_coords,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>num_coords:</dt>
+<dd>number of coordinates</dd>
+<dt>coordinates:</dt>
+<dd>coordinate array</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpolyline">
+<h1><a class="toc-backref" href="#id290">DrawPolyline</a></h1>
+<div class="section" id="id129">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPolyline( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long num_coords,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+</div>
+<div class="section" id="id130">
+<h2>Description</h2>
+<p>DrawPolyline() draws a polyline using the current stroke, stroke width, and
+fill color or texture, using the specified array of coordinates.</p>
+<p>The format of the DrawPolyline method is:</p>
+<pre class="literal-block">
+void DrawPolyline( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long num_coords,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>num_coords:</dt>
+<dd>number of coordinates</dd>
+<dt>coordinates:</dt>
+<dd>coordinate array</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpopclippath">
+<h1><a class="toc-backref" href="#id291">DrawPopClipPath</a></h1>
+<div class="section" id="id131">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPopClipPath( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id132">
+<h2>Description</h2>
+<p>DrawPopClipPath() terminates a clip path definition.</p>
+<p>The format of the DrawPopClipPath method is:</p>
+<pre class="literal-block">
+void DrawPopClipPath( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpopdefs">
+<h1><a class="toc-backref" href="#id292">DrawPopDefs</a></h1>
+<div class="section" id="id133">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPopDefs( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id134">
+<h2>Description</h2>
+<p>DrawPopDefs() terminates a definition list</p>
+<p>The format of the DrawPopDefs method is:</p>
+<pre class="literal-block">
+void DrawPopDefs( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpopgraphiccontext">
+<h1><a class="toc-backref" href="#id293">DrawPopGraphicContext</a></h1>
+<div class="section" id="id135">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPopGraphicContext( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id136">
+<h2>Description</h2>
+<p>DrawPopGraphicContext() destroys the current context returning to the
+previously pushed context. Multiple contexts may exist. It is an error
+to attempt to pop more contexts than have been pushed, and it is proper
+form to pop all contexts which have been pushed.</p>
+<p>The format of the DrawPopGraphicContext method is:</p>
+<pre class="literal-block">
+void DrawPopGraphicContext( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpoppattern">
+<h1><a class="toc-backref" href="#id294">DrawPopPattern</a></h1>
+<div class="section" id="id137">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPopPattern( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id138">
+<h2>Description</h2>
+<p>DrawPopPattern() terminates a pattern definition.</p>
+<p>The format of the DrawPopPattern method is:</p>
+<pre class="literal-block">
+void DrawPopPattern( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpushclippath">
+<h1><a class="toc-backref" href="#id295">DrawPushClipPath</a></h1>
+<div class="section" id="id139">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPushClipPath( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *clip_path_id );
+</pre>
+</div>
+<div class="section" id="id140">
+<h2>Description</h2>
+<p>DrawPushClipPath() starts a clip path definition which is comprized of
+any number of drawing commands and terminated by a DrawPopClipPath()
+command.</p>
+<p>The format of the DrawPushClipPath method is:</p>
+<pre class="literal-block">
+void DrawPushClipPath( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *clip_path_id );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>clip_path_id:</dt>
+<dd>string identifier to associate with the clip path for
+later use.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpushdefs">
+<h1><a class="toc-backref" href="#id296">DrawPushDefs</a></h1>
+<div class="section" id="id141">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPushDefs( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id142">
+<h2>Description</h2>
+<p>DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
+command create named elements (e.g. clip-paths, textures, etc.) which
+may safely be processed earlier for the sake of efficiency.</p>
+<p>The format of the DrawPushDefs method is:</p>
+<pre class="literal-block">
+void DrawPushDefs( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpushgraphiccontext">
+<h1><a class="toc-backref" href="#id297">DrawPushGraphicContext</a></h1>
+<div class="section" id="id143">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPushGraphicContext( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id144">
+<h2>Description</h2>
+<p>DrawPushGraphicContext() clones the current drawing context to create a
+new drawing context. The original drawing context(s) may be returned to
+by invoking DrawPopGraphicContext(). The contexts are stored on a context
+stack. For every Pop there must have already been an equivalent Push.</p>
+<p>The format of the DrawPushGraphicContext method is:</p>
+<pre class="literal-block">
+void DrawPushGraphicContext( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpushpattern">
+<h1><a class="toc-backref" href="#id298">DrawPushPattern</a></h1>
+<div class="section" id="id145">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPushPattern( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *pattern_id, const double x,
+ const double y, const double width, const double height );
+</pre>
+</div>
+<div class="section" id="id146">
+<h2>Description</h2>
+<p>DrawPushPattern() indicates that subsequent commands up to a
+DrawPopPattern() command comprise the definition of a named pattern.
+The pattern space is assigned top left corner coordinates, a width
+and height, and becomes its own drawing space. Anything which can
+be drawn may be used in a pattern definition.
+Named patterns may be used as stroke or brush definitions.</p>
+<p>The format of the DrawPushPattern method is:</p>
+<pre class="literal-block">
+void DrawPushPattern( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *pattern_id, const double x,
+ const double y, const double width, const double height );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>pattern_id:</dt>
+<dd>pattern identification for later reference</dd>
+<dt>x:</dt>
+<dd>x ordinate of top left corner</dd>
+<dt>y:</dt>
+<dd>y ordinate of top left corner</dd>
+<dt>width:</dt>
+<dd>width of pattern space</dd>
+<dt>height:</dt>
+<dd>height of pattern space</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawrectangle">
+<h1><a class="toc-backref" href="#id299">DrawRectangle</a></h1>
+<div class="section" id="id147">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawRectangle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1, const double y1, const double x2,
+ const double y2 );
+</pre>
+</div>
+<div class="section" id="id148">
+<h2>Description</h2>
+<p>DrawRectangle() draws a rectangle given two coordinates and using
+the current stroke, stroke width, and fill settings.</p>
+<p>The format of the DrawRectangle method is:</p>
+<pre class="literal-block">
+void DrawRectangle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x1, const double y1, const double x2,
+ const double y2 );
+</pre>
+<dl class="docutils">
+<dt>x1:</dt>
+<dd>x ordinate of first coordinate</dd>
+<dt>y1:</dt>
+<dd>y ordinate of first coordinate</dd>
+<dt>x2:</dt>
+<dd>x ordinate of second coordinate</dd>
+<dt>y2:</dt>
+<dd>y ordinate of second coordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawrender">
+<h1><a class="toc-backref" href="#id300">DrawRender</a></h1>
+<div class="section" id="id149">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+int DrawRender( const <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id150">
+<h2>Description</h2>
+<p>DrawRender() renders all preceding drawing commands onto the image.</p>
+<p>The format of the DrawRender method is:</p>
+<pre class="literal-block">
+int DrawRender( const <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawrotate">
+<h1><a class="toc-backref" href="#id301">DrawRotate</a></h1>
+<div class="section" id="id151">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawRotate( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double degrees );
+</pre>
+</div>
+<div class="section" id="id152">
+<h2>Description</h2>
+<p>DrawRotate() applies the specified rotation to the current coordinate
+space.</p>
+<p>The format of the DrawRotate method is:</p>
+<pre class="literal-block">
+void DrawRotate( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double degrees );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>degrees:</dt>
+<dd>degrees of rotation</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawroundrectangle">
+<h1><a class="toc-backref" href="#id302">DrawRoundRectangle</a></h1>
+<div class="section" id="id153">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawRoundRectangle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, double x1, double y1, double x2, double y2,
+ double rx, double ry );
+</pre>
+</div>
+<div class="section" id="id154">
+<h2>Description</h2>
+<p>DrawRoundRectangle() draws a rounted rectangle given two coordinates,
+x &amp; y corner radiuses and using the current stroke, stroke width,
+and fill settings.</p>
+<p>The format of the DrawRoundRectangle method is:</p>
+<pre class="literal-block">
+void DrawRoundRectangle( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, double x1, double y1, double x2, double y2,
+ double rx, double ry );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x1:</dt>
+<dd>x ordinate of first coordinate</dd>
+<dt>y1:</dt>
+<dd>y ordinate of first coordinate</dd>
+<dt>x2:</dt>
+<dd>x ordinate of second coordinate</dd>
+<dt>y2:</dt>
+<dd>y ordinate of second coordinate</dd>
+<dt>rx:</dt>
+<dd>radius of corner in horizontal direction</dd>
+<dt>ry:</dt>
+<dd>radius of corner in vertical direction</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawscale">
+<h1><a class="toc-backref" href="#id303">DrawScale</a></h1>
+<div class="section" id="id155">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawScale( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id156">
+<h2>Description</h2>
+<p>DrawScale() adjusts the scaling factor to apply in the horizontal and
+vertical directions to the current coordinate space.</p>
+<p>The format of the DrawScale method is:</p>
+<pre class="literal-block">
+void DrawScale( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>horizontal scale factor</dd>
+<dt>y:</dt>
+<dd>vertical scale factor</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawskewx">
+<h1><a class="toc-backref" href="#id304">DrawSkewX</a></h1>
+<div class="section" id="id157">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSkewX( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double degrees );
+</pre>
+</div>
+<div class="section" id="id158">
+<h2>Description</h2>
+<p>DrawSkewX() skews the current coordinate system in the horizontal
+direction.</p>
+<p>The format of the DrawSkewX method is:</p>
+<pre class="literal-block">
+void DrawSkewX( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double degrees );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>degrees:</dt>
+<dd>number of degrees to skew the coordinates</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawskewy">
+<h1><a class="toc-backref" href="#id305">DrawSkewY</a></h1>
+<div class="section" id="id159">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSkewY( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double degrees );
+</pre>
+</div>
+<div class="section" id="id160">
+<h2>Description</h2>
+<p>DrawSkewY() skews the current coordinate system in the vertical
+direction.</p>
+<p>The format of the DrawSkewY method is:</p>
+<pre class="literal-block">
+void DrawSkewY( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double degrees );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>degrees:</dt>
+<dd>number of degrees to skew the coordinates</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstopcolor">
+<h1><a class="toc-backref" href="#id306">DrawSetStopColor</a></h1>
+<div class="section" id="id161">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStopColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *stop_color,
+ const double offset );
+</pre>
+</div>
+<div class="section" id="id162">
+<h2>Description</h2>
+<p>DrawSetStopColor() sets the stop color and offset for gradients</p>
+<p>The format of the DrawSetStopColor method is:</p>
+<pre class="literal-block">
+void DrawSetStopColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *stop_color,
+ const double offset );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+<p>o stop_color:</p>
+<p>o offset:</p>
+</div>
+</div>
+<div class="section" id="drawgetstrokecolor">
+<h1><a class="toc-backref" href="#id307">DrawGetStrokeColor</a></h1>
+<div class="section" id="id163">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> DrawGetStrokeColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id164">
+<h2>Description</h2>
+<p>DrawGetStrokeColor() returns the color used for stroking object outlines.</p>
+<p>The format of the DrawGetStrokeColor method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> DrawGetStrokeColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokecolor">
+<h1><a class="toc-backref" href="#id308">DrawSetStrokeColor</a></h1>
+<div class="section" id="id165">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *stroke_color );
+</pre>
+</div>
+<div class="section" id="id166">
+<h2>Description</h2>
+<p>DrawSetStrokeColor() sets the color used for stroking object outlines.</p>
+<p>The format of the DrawSetStrokeColor method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *stroke_color );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>stroke_color:</dt>
+<dd>stroke color</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokecolorstring">
+<h1><a class="toc-backref" href="#id309">DrawSetStrokeColorString</a></h1>
+<div class="section" id="id167">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeColorString( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *stroke_color );
+</pre>
+</div>
+<div class="section" id="id168">
+<h2>Description</h2>
+<p>DrawSetStrokeColorString() sets the color used for stroking object outlines.</p>
+<p>The format of the DrawSetStrokeColorString method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeColorString( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *stroke_color );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>stroke_color:</dt>
+<dd>stroke color</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokepatternurl">
+<h1><a class="toc-backref" href="#id310">DrawSetStrokePatternURL</a></h1>
+<div class="section" id="id169">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokePatternURL( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *stroke_url );
+</pre>
+</div>
+<div class="section" id="id170">
+<h2>Description</h2>
+<p>DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.</p>
+<p>The format of the DrawSetStrokePatternURL method is:</p>
+<pre class="literal-block">
+void DrawSetStrokePatternURL( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *stroke_url );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>stroke_url:</dt>
+<dd>URL specifying pattern ID (e.g. &quot;#pattern_id&quot;)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokeantialias">
+<h1><a class="toc-backref" href="#id311">DrawGetStrokeAntialias</a></h1>
+<div class="section" id="id171">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DrawGetStrokeAntialias( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id172">
+<h2>Description</h2>
+<p>DrawGetStrokeAntialias() returns the current stroke antialias setting.
+Stroked outlines are antialiased by default. When antialiasing is disabled
+stroked pixels are thresholded to determine if the stroke color or
+underlying canvas color should be used.</p>
+<p>The format of the DrawGetStrokeAntialias method is:</p>
+<pre class="literal-block">
+unsigned int DrawGetStrokeAntialias( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokeantialias">
+<h1><a class="toc-backref" href="#id312">DrawSetStrokeAntialias</a></h1>
+<div class="section" id="id173">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeAntialias( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned int stroke_antialias );
+</pre>
+</div>
+<div class="section" id="id174">
+<h2>Description</h2>
+<p>DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
+Stroked outlines are antialiased by default. When antialiasing is disabled
+stroked pixels are thresholded to determine if the stroke color or
+underlying canvas color should be used.</p>
+<p>The format of the DrawSetStrokeAntialias method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeAntialias( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned int stroke_antialias );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>stroke_antialias:</dt>
+<dd>set to false (zero) to disable antialiasing</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokedasharray">
+<h1><a class="toc-backref" href="#id313">DrawGetStrokeDashArray</a></h1>
+<div class="section" id="id175">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double *DrawGetStrokeDashArray( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, unsigned long *num_elems );
+</pre>
+</div>
+<div class="section" id="id176">
+<h2>Description</h2>
+<p>DrawGetStrokeDashArray() returns an array representing the pattern of
+dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
+array must be freed once it is no longer required by the user.</p>
+<p>The format of the DrawGetStrokeDashArray method is:</p>
+<pre class="literal-block">
+double *DrawGetStrokeDashArray( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, unsigned long *num_elems );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>num_elems:</dt>
+<dd>address to place number of elements in dash array</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokedasharray">
+<h1><a class="toc-backref" href="#id314">DrawSetStrokeDashArray</a></h1>
+<div class="section" id="id177">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeDashArray( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long num_elems,
+ const double *dasharray );
+</pre>
+</div>
+<div class="section" id="id178">
+<h2>Description</h2>
+<p>DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
+stroke paths. The strokeDashArray represents an array of numbers that
+specify the lengths of alternating dashes and gaps in pixels. If an odd
+number of values is provided, then the list of values is repeated to yield
+an even number of values. To remove an existing dash array, pass a zero
+num_elems argument and null dasharray. A typical stroke dash array might
+contain the members 5 3 2.</p>
+<p>The format of the DrawSetStrokeDashArray method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeDashArray( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long num_elems,
+ const double *dasharray );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>num_elems:</dt>
+<dd>number of elements in dash array</dd>
+<dt>dasharray:</dt>
+<dd>dash array values</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokedashoffset">
+<h1><a class="toc-backref" href="#id315">DrawGetStrokeDashOffset</a></h1>
+<div class="section" id="id179">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetStrokeDashOffset( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id180">
+<h2>Description</h2>
+<p>DrawGetStrokeDashOffset() returns the offset into the dash pattern to
+start the dash.</p>
+<p>The format of the DrawGetStrokeDashOffset method is:</p>
+<pre class="literal-block">
+double DrawGetStrokeDashOffset( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokedashoffset">
+<h1><a class="toc-backref" href="#id316">DrawSetStrokeDashOffset</a></h1>
+<div class="section" id="id181">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeDashOffset( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double dash_offset );
+</pre>
+</div>
+<div class="section" id="id182">
+<h2>Description</h2>
+<p>DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
+start the dash.</p>
+<p>The format of the DrawSetStrokeDashOffset method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeDashOffset( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double dash_offset );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>dash_offset:</dt>
+<dd>dash offset</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokelinecap">
+<h1><a class="toc-backref" href="#id317">DrawGetStrokeLineCap</a></h1>
+<div class="section" id="id183">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+LineCap DrawGetStrokeLineCap( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id184">
+<h2>Description</h2>
+<p>DrawGetStrokeLineCap() returns the shape to be used at the end of
+open subpaths when they are stroked. Values of LineCap are
+UndefinedCap, ButtCap, RoundCap, and SquareCap.</p>
+<p>The format of the DrawGetStrokeLineCap method is:</p>
+<pre class="literal-block">
+LineCap DrawGetStrokeLineCap( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokelinecap">
+<h1><a class="toc-backref" href="#id318">DrawSetStrokeLineCap</a></h1>
+<div class="section" id="id185">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeLineCap( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const LineCap linecap );
+</pre>
+</div>
+<div class="section" id="id186">
+<h2>Description</h2>
+<p>DrawSetStrokeLineCap() specifies the shape to be used at the end of
+open subpaths when they are stroked. Values of LineCap are
+UndefinedCap, ButtCap, RoundCap, and SquareCap.</p>
+<p>The format of the DrawSetStrokeLineCap method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeLineCap( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const LineCap linecap );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>linecap:</dt>
+<dd>linecap style</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokelinejoin">
+<h1><a class="toc-backref" href="#id319">DrawGetStrokeLineJoin</a></h1>
+<div class="section" id="id187">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+LineJoin DrawGetStrokeLineJoin( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id188">
+<h2>Description</h2>
+<p>DrawGetStrokeLineJoin() returns the shape to be used at the
+corners of paths (or other vector shapes) when they are
+stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
+and BevelJoin.</p>
+<p>The format of the DrawGetStrokeLineJoin method is:</p>
+<pre class="literal-block">
+LineJoin DrawGetStrokeLineJoin( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokelinejoin">
+<h1><a class="toc-backref" href="#id320">DrawSetStrokeLineJoin</a></h1>
+<div class="section" id="id189">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeLineJoin( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const LineJoin linejoin );
+</pre>
+</div>
+<div class="section" id="id190">
+<h2>Description</h2>
+<p>DrawSetStrokeLineJoin() specifies the shape to be used at the
+corners of paths (or other vector shapes) when they are
+stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
+and BevelJoin.</p>
+<p>The format of the DrawSetStrokeLineJoin method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeLineJoin( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const LineJoin linejoin );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>linejoin:</dt>
+<dd>line join style</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokemiterlimit">
+<h1><a class="toc-backref" href="#id321">DrawGetStrokeMiterLimit</a></h1>
+<div class="section" id="id191">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long DrawGetStrokeMiterLimit( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id192">
+<h2>Description</h2>
+<p>DrawGetStrokeMiterLimit() returns the miter limit. When two line
+segments meet at a sharp angle and miter joins have been specified for
+'lineJoin', it is possible for the miter to extend far beyond the
+thickness of the line stroking the path. The miterLimit' imposes a
+limit on the ratio of the miter length to the 'lineWidth'.</p>
+<p>The format of the DrawGetStrokeMiterLimit method is:</p>
+<pre class="literal-block">
+unsigned long DrawGetStrokeMiterLimit( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokemiterlimit">
+<h1><a class="toc-backref" href="#id322">DrawSetStrokeMiterLimit</a></h1>
+<div class="section" id="id193">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeMiterLimit( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long miterlimit );
+</pre>
+</div>
+<div class="section" id="id194">
+<h2>Description</h2>
+<p>DrawSetStrokeMiterLimit() specifies the miter limit. When two line
+segments meet at a sharp angle and miter joins have been specified for
+'lineJoin', it is possible for the miter to extend far beyond the
+thickness of the line stroking the path. The miterLimit' imposes a
+limit on the ratio of the miter length to the 'lineWidth'.</p>
+<p>The format of the DrawSetStrokeMiterLimit method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeMiterLimit( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned long miterlimit );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>miterlimit:</dt>
+<dd>miter limit</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokeopacity">
+<h1><a class="toc-backref" href="#id323">DrawGetStrokeOpacity</a></h1>
+<div class="section" id="id195">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetStrokeOpacity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id196">
+<h2>Description</h2>
+<p>DrawGetStrokeOpacity() returns the opacity of stroked object outlines.</p>
+<p>The format of the DrawGetStrokeOpacity method is:</p>
+<pre class="literal-block">
+double DrawGetStrokeOpacity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokeopacity">
+<h1><a class="toc-backref" href="#id324">DrawSetStrokeOpacity</a></h1>
+<div class="section" id="id197">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeOpacity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double stroke_opacity );
+</pre>
+</div>
+<div class="section" id="id198">
+<h2>Description</h2>
+<p>DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.</p>
+<p>The format of the DrawSetStrokeOpacity method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeOpacity( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double stroke_opacity );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>stroke_opacity:</dt>
+<dd>stroke opacity. The value 1.0 is opaque.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokewidth">
+<h1><a class="toc-backref" href="#id325">DrawGetStrokeWidth</a></h1>
+<div class="section" id="id199">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetStrokeWidth( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id200">
+<h2>Description</h2>
+<p>DrawGetStrokeWidth() returns the width of the stroke used to draw object
+outlines.</p>
+<p>The format of the DrawGetStrokeWidth method is:</p>
+<pre class="literal-block">
+double DrawGetStrokeWidth( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokewidth">
+<h1><a class="toc-backref" href="#id326">DrawSetStrokeWidth</a></h1>
+<div class="section" id="id201">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeWidth( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double stroke_width );
+</pre>
+</div>
+<div class="section" id="id202">
+<h2>Description</h2>
+<p>DrawSetStrokeWidth() sets the width of the stroke used to draw object
+outlines.</p>
+<p>The format of the DrawSetStrokeWidth method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeWidth( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double stroke_width );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>stroke_width:</dt>
+<dd>stroke width</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgettextantialias">
+<h1><a class="toc-backref" href="#id327">DrawGetTextAntialias</a></h1>
+<div class="section" id="id203">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DrawGetTextAntialias( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id204">
+<h2>Description</h2>
+<p>DrawGetTextAntialias() returns the current text antialias setting, which
+determines whether text is antialiased. Text is antialiased by default.</p>
+<p>The format of the DrawGetTextAntialias method is:</p>
+<pre class="literal-block">
+unsigned int DrawGetTextAntialias( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextantialias">
+<h1><a class="toc-backref" href="#id328">DrawSetTextAntialias</a></h1>
+<div class="section" id="id205">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextAntialias( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned int text_antialias );
+</pre>
+</div>
+<div class="section" id="id206">
+<h2>Description</h2>
+<p>DrawSetTextAntialias() controls whether text is antialiased. Text is
+antialiased by default.</p>
+<p>The format of the DrawSetTextAntialias method is:</p>
+<pre class="literal-block">
+void DrawSetTextAntialias( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const unsigned int text_antialias );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>text_antialias:</dt>
+<dd>antialias boolean. Set to false (0) to disable
+antialiasing.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgettextdecoration">
+<h1><a class="toc-backref" href="#id329">DrawGetTextDecoration</a></h1>
+<div class="section" id="id207">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#decorationtype">DecorationType</a> DrawGetTextDecoration( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id208">
+<h2>Description</h2>
+<p>DrawGetTextDecoration() returns the decoration applied when annotating with
+text.</p>
+<p>The format of the DrawGetTextDecoration method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#decorationtype">DecorationType</a> DrawGetTextDecoration( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextdecoration">
+<h1><a class="toc-backref" href="#id330">DrawSetTextDecoration</a></h1>
+<div class="section" id="id209">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextDecoration( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#decorationtype">DecorationType</a> decoration );
+</pre>
+</div>
+<div class="section" id="id210">
+<h2>Description</h2>
+<p>DrawSetTextDecoration() specifies a decoration to be applied when
+annotating with text.</p>
+<p>The format of the DrawSetTextDecoration method is:</p>
+<pre class="literal-block">
+void DrawSetTextDecoration( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#decorationtype">DecorationType</a> decoration );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>decoration:</dt>
+<dd>text decoration. One of NoDecoration, UnderlineDecoration,
+OverlineDecoration, or LineThroughDecoration</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgettextencoding">
+<h1><a class="toc-backref" href="#id331">DrawGetTextEncoding</a></h1>
+<div class="section" id="id211">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetTextEncoding( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id212">
+<h2>Description</h2>
+<p>DrawGetTextEncoding() returns a null-terminated string which specifies the
+code set used for text annotations. The string must be freed by the user
+once it is no longer required.</p>
+<p>The format of the DrawGetTextEncoding method is:</p>
+<pre class="literal-block">
+char *DrawGetTextEncoding( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextencoding">
+<h1><a class="toc-backref" href="#id332">DrawSetTextEncoding</a></h1>
+<div class="section" id="id213">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextEncoding( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *encoding );
+</pre>
+</div>
+<div class="section" id="id214">
+<h2>Description</h2>
+<p>DrawSetTextEncoding() specifies specifies the code set to use for
+text annotations. The only character encoding which may be specified
+at this time is &quot;UTF-8&quot; for representing Unicode as a sequence of
+bytes. Specify an empty string to set text encoding to the system's
+default. Successful text annotation using Unicode may require fonts
+designed to support Unicode.</p>
+<p>The format of the DrawSetTextEncoding method is:</p>
+<pre class="literal-block">
+void DrawSetTextEncoding( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *encoding );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>encoding:</dt>
+<dd>character string specifying text encoding</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgettextundercolor">
+<h1><a class="toc-backref" href="#id333">DrawGetTextUnderColor</a></h1>
+<div class="section" id="id215">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> DrawGetTextUnderColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+</div>
+<div class="section" id="id216">
+<h2>Description</h2>
+<p>DrawGetTextUnderColor() returns the color of a background rectangle
+to place under text annotations.</p>
+<p>The format of the DrawGetTextUnderColor method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> DrawGetTextUnderColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextundercolor">
+<h1><a class="toc-backref" href="#id334">DrawSetTextUnderColor</a></h1>
+<div class="section" id="id217">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextUnderColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *under_color );
+</pre>
+</div>
+<div class="section" id="id218">
+<h2>Description</h2>
+<p>DrawSetTextUnderColor() specifies the color of a background rectangle
+to place under text annotations.</p>
+<p>The format of the DrawSetTextUnderColor method is:</p>
+<pre class="literal-block">
+void DrawSetTextUnderColor( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *under_color );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>under_color:</dt>
+<dd>text under color</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextundercolorstring">
+<h1><a class="toc-backref" href="#id335">DrawSetTextUnderColorString</a></h1>
+<div class="section" id="id219">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextUnderColorString( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *under_color );
+</pre>
+</div>
+<div class="section" id="id220">
+<h2>Description</h2>
+<p>DrawSetTextUnderColorString() specifies the color of a background rectangle
+to place under text annotations.</p>
+<p>The format of the DrawSetTextUnderColorString method is:</p>
+<pre class="literal-block">
+void DrawSetTextUnderColorString( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const char *under_color );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>under_color:</dt>
+<dd>text under color</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawtranslate">
+<h1><a class="toc-backref" href="#id336">DrawTranslate</a></h1>
+<div class="section" id="id221">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawTranslate( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id222">
+<h2>Description</h2>
+<p>DrawTranslate() applies a translation to the current coordinate
+system which moves the coordinate system origin to the specified
+coordinate.</p>
+<p>The format of the DrawTranslate method is:</p>
+<pre class="literal-block">
+void DrawTranslate( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x:</dt>
+<dd>new x ordinate for coordinate system origin</dd>
+<dt>y:</dt>
+<dd>new y ordinate for coordinate system origin</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetviewbox">
+<h1><a class="toc-backref" href="#id337">DrawSetViewbox</a></h1>
+<div class="section" id="id223">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetViewbox( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, unsigned long x1, unsigned long y1,
+ unsigned long x2, unsigned long y2 );
+</pre>
+</div>
+<div class="section" id="id224">
+<h2>Description</h2>
+<p>DrawSetViewbox() sets the overall canvas size to be recorded with the
+drawing vector data. Usually this will be specified using the same
+size as the canvas image. When the vector data is saved to SVG or MVG
+formats, the viewbox is use to specify the size of the canvas image that
+a viewer will render the vector data on.</p>
+<p>The format of the DrawSetViewbox method is:</p>
+<pre class="literal-block">
+void DrawSetViewbox( <a class="reference external" href="../api/types.html#drawcontext">DrawContext</a> context, unsigned long x1, unsigned long y1,
+ unsigned long x2, unsigned long y2 );
+</pre>
+<dl class="docutils">
+<dt>context:</dt>
+<dd>drawing context</dd>
+<dt>x1:</dt>
+<dd>left x ordinate</dd>
+<dt>y1:</dt>
+<dd>top y ordinate</dd>
+<dt>x2:</dt>
+<dd>right x ordinate</dd>
+<dt>y2:</dt>
+<dd>bottom y ordinate</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/effect.html b/www/api/effect.html
new file mode 100644
index 0000000..6d3c634
--- /dev/null
+++ b/www/api/effect.html
@@ -0,0 +1,920 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>effect</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="effect">
+<h1 class="title">effect</h1>
+<h2 class="subtitle" id="image-effects-methods">Image effects methods</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#adaptivethresholdimage" id="id51">AdaptiveThresholdImage</a></li>
+<li><a class="reference internal" href="#addnoiseimage" id="id52">AddNoiseImage</a></li>
+<li><a class="reference internal" href="#addnoiseimagechannel" id="id53">AddNoiseImageChannel</a></li>
+<li><a class="reference internal" href="#blackthresholdimage" id="id54">BlackThresholdImage</a></li>
+<li><a class="reference internal" href="#blurimage" id="id55">BlurImage</a></li>
+<li><a class="reference internal" href="#blurimagechannel" id="id56">BlurImageChannel</a></li>
+<li><a class="reference internal" href="#channelthresholdimage" id="id57">ChannelThresholdImage</a></li>
+<li><a class="reference internal" href="#convolveimage" id="id58">ConvolveImage</a></li>
+<li><a class="reference internal" href="#despeckleimage" id="id59">DespeckleImage</a></li>
+<li><a class="reference internal" href="#edgeimage" id="id60">EdgeImage</a></li>
+<li><a class="reference internal" href="#embossimage" id="id61">EmbossImage</a></li>
+<li><a class="reference internal" href="#enhanceimage" id="id62">EnhanceImage</a></li>
+<li><a class="reference internal" href="#gaussianblurimage" id="id63">GaussianBlurImage</a></li>
+<li><a class="reference internal" href="#gaussianblurimagechannel" id="id64">GaussianBlurImageChannel</a></li>
+<li><a class="reference internal" href="#medianfilterimage" id="id65">MedianFilterImage</a></li>
+<li><a class="reference internal" href="#motionblurimage" id="id66">MotionBlurImage</a></li>
+<li><a class="reference internal" href="#randomchannelthresholdimage" id="id67">RandomChannelThresholdImage</a></li>
+<li><a class="reference internal" href="#reducenoiseimage" id="id68">ReduceNoiseImage</a></li>
+<li><a class="reference internal" href="#shadeimage" id="id69">ShadeImage</a></li>
+<li><a class="reference internal" href="#sharpenimage" id="id70">SharpenImage</a></li>
+<li><a class="reference internal" href="#sharpenimagechannel" id="id71">SharpenImageChannel</a></li>
+<li><a class="reference internal" href="#spreadimage" id="id72">SpreadImage</a></li>
+<li><a class="reference internal" href="#thresholdimage" id="id73">ThresholdImage</a></li>
+<li><a class="reference internal" href="#unsharpmaskimage" id="id74">UnsharpMaskImage</a></li>
+<li><a class="reference internal" href="#unsharpmaskimagechannel" id="id75">UnsharpMaskImageChannel</a></li>
+<li><a class="reference internal" href="#whitethresholdimage" id="id76">WhiteThresholdImage</a></li>
+</ul>
+</div>
+<div class="section" id="adaptivethresholdimage">
+<h1><a class="toc-backref" href="#id51">AdaptiveThresholdImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AdaptiveThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long width,
+ const unsigned long height, const unsigned long unsigned long,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AdaptiveThresholdImage() selects an individual threshold for each pixel
+based on the range of intensity values in its local neighborhood. This
+allows for thresholding of an image whose global intensity histogram
+doesn't contain distinctive peaks.</p>
+<p>The format of the AdaptiveThresholdImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AdaptiveThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long width,
+ const unsigned long height, const unsigned long unsigned long,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>width:</dt>
+<dd>The width of the local neighborhood.</dd>
+<dt>height:</dt>
+<dd>The height of the local neighborhood.</dd>
+<dt>offset:</dt>
+<dd>The mean offset.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="addnoiseimage">
+<h1><a class="toc-backref" href="#id52">AddNoiseImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AddNoiseImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#noisetype">NoiseType</a> noise_type,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>AddNoiseImage() adds random noise to the image.</p>
+<p>The format of the AddNoiseImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AddNoiseImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#noisetype">NoiseType</a> noise_type,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>noise_type:</dt>
+<dd>The type of noise: Uniform, Gaussian, Multiplicative,
+Impulse, Laplacian, Poisson, or Random.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="addnoiseimagechannel">
+<h1><a class="toc-backref" href="#id53">AddNoiseImageChannel</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AddNoiseImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const <a class="reference external" href="../api/types.html#noisetype">NoiseType</a> noise_type, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>AddNoiseImageChannel() adds random noise to one image channel.</p>
+<p>The format of the AddNoiseImageChannel method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AddNoiseImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const <a class="reference external" href="../api/types.html#noisetype">NoiseType</a> noise_type, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>The image channel to apply noise to.</dd>
+<dt>noise_type:</dt>
+<dd>The type of noise: Uniform, Gaussian, Multiplicative,
+Impulse, Laplacian, Poisson, or Random.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="blackthresholdimage">
+<h1><a class="toc-backref" href="#id54">BlackThresholdImage</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail BlackThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *thresholds );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>BlackThresholdImage() adjusts the levels of image channels such that
+values below a specified threshold are set to the minimum value (black)
+while the remaining pixels are unchanged.</p>
+<p>The format of the BlackThresholdImage method is:</p>
+<pre class="literal-block">
+MagickPassFail BlackThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *thresholds );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>thresholds:</dt>
+<dd>Channel thresholds which are specified as a comma delimited
+list containing the thresholds for red, green, blue, and opacity. If
+the list contains a percent symbol (%) then all values are treated as
+a percentage of MaxRGB.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="blurimage">
+<h1><a class="toc-backref" href="#id55">BlurImage</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *BlurImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>BlurImage() blurs an image. We convolve the image with a Gaussian
+operator of the given radius and standard deviation (sigma).
+For reasonable results, the radius should be larger than sigma. Use a
+radius of 0 and BlurImage() selects a suitable radius for you.</p>
+<p>The format of the BlurImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *BlurImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="blurimagechannel">
+<h1><a class="toc-backref" href="#id56">BlurImageChannel</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *BlurImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>BlurImageChannel() blurs the specified image channel. We convolve the
+image channel with a Gaussian operator of the given radius and standard
+deviation (sigma). For reasonable results, the radius should be larger
+than sigma. Use a radius of 0 and BlurImageChannel() selects a suitable
+radius for you.</p>
+<p>The format of the BlurImageChannel method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *BlurImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>channel:</dt>
+<dd>The channel to blur.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="channelthresholdimage">
+<h1><a class="toc-backref" href="#id57">ChannelThresholdImage</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ChannelThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *threshold );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>ChannelThresholdImage() changes the value of individual pixels based on
+the level of each pixel channel. The result sets the affected channels
+to the minimum or maximum channel value. A negative threshold value
+disables thresholding for that channel. Append a percent symbol to
+have threshold values automatically scaled from a percentage to MaxRGB.</p>
+<p>Invoked by the '-threshold' option.</p>
+<p>The format of the ChannelThresholdImage method is:</p>
+<pre class="literal-block">
+MagickPassFail ChannelThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *threshold );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>threshold:</dt>
+<dd>define the threshold values, &lt;red&gt;{&lt;green&gt;,&lt;blue&gt;,&lt;opacity&gt;}{%}.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="convolveimage">
+<h1><a class="toc-backref" href="#id58">ConvolveImage</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ConvolveImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int order,
+ const double *kernel, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>ConvolveImage() applies a custom convolution kernel to the image.</p>
+<p>The format of the ConvolveImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ConvolveImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int order,
+ const double *kernel, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>order:</dt>
+<dd>The number of columns and rows in the filter kernel.</dd>
+<dt>kernel:</dt>
+<dd>An array of double representing the convolution kernel.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="despeckleimage">
+<h1><a class="toc-backref" href="#id59">DespeckleImage</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *DespeckleImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>Despeckle() reduces the speckle noise in an image while preserving the
+edges of the original image.</p>
+<p>The format of the DespeckleImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *DespeckleImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="edgeimage">
+<h1><a class="toc-backref" href="#id60">EdgeImage</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *EdgeImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>EdgeImage() finds edges in an image. Radius defines the radius of the
+convolution filter. Use a radius of 0 and Edge() selects a suitable
+radius for you.</p>
+<p>The format of the EdgeImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *EdgeImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>the radius of the pixel neighborhood.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="embossimage">
+<h1><a class="toc-backref" href="#id61">EmbossImage</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *EmbossImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>EmbossImage() returns a grayscale image with a three-dimensional effect.
+We convolve the image with a Gaussian operator of the given radius and
+standard deviation (sigma). For reasonable results, radius should be
+larger than sigma. Use a radius of 0 and Emboss() selects a suitable
+radius for you.</p>
+<p>The format of the EmbossImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *EmbossImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>the radius of the pixel neighborhood.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="enhanceimage">
+<h1><a class="toc-backref" href="#id62">EnhanceImage</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *EnhanceImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>EnhanceImage() applies a digital filter to the image color channels that
+improves the quality of a noisy image. The opacity channel is preserved
+but is otherwise ignored.</p>
+<p>The format of the EnhanceImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *EnhanceImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="gaussianblurimage">
+<h1><a class="toc-backref" href="#id63">GaussianBlurImage</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GaussianBlurImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>GaussianBlurImage() blurs an image. We convolve the image with a
+Gaussian operator of the given radius and standard deviation (sigma).
+For reasonable results, the radius should be larger than sigma. Use a
+radius of 0 and GaussianBlurImage() selects a suitable radius for you</p>
+<p>The format of the GaussianBlurImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GaussianBlurImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>blur_image:</dt>
+<dd>Method GaussianBlurImage returns a pointer to the image
+after it is blur. A null image is returned if there is a memory
+shortage.</dd>
+<dt>image:</dt>
+<dd>Image to blur.</dd>
+<dt>radius:</dt>
+<dd>the radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>the standard deviation of the Gaussian, in pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="gaussianblurimagechannel">
+<h1><a class="toc-backref" href="#id64">GaussianBlurImageChannel</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GaussianBlurImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>GaussianBlurImageChannel() blurs an image channel. We convolve the image
+with a Gaussian operator of the given radius and standard deviation
+(sigma). For reasonable results, the radius should be larger than sigma.
+Use a radius of 0 and GaussianBlurImage() selects a suitable radius for
+you.</p>
+<p>The format of the GaussianBlurImageChannel method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GaussianBlurImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>blur_image:</dt>
+<dd>Method GaussianBlurImage returns a pointer to the image
+after it is blur. A null image is returned if there is a memory
+shortage.</dd>
+<dt>image:</dt>
+<dd>Image to blur.</dd>
+<dt>channel:</dt>
+<dd>Channel to blur in image.</dd>
+<dt>radius:</dt>
+<dd>the radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>the standard deviation of the Gaussian, in pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="medianfilterimage">
+<h1><a class="toc-backref" href="#id65">MedianFilterImage</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MedianFilterImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>MedianFilterImage() applies a digital filter that improves the quality
+of a noisy image. Each pixel is replaced by the median in a set of
+neighboring pixels as defined by radius.</p>
+<p>The algorithm was contributed by Mike Edmonds and implements an insertion
+sort for selecting median color-channel values. For more on this algorithm
+see &quot;Skip Lists: A probabilistic Alternative to Balanced Trees&quot; by William
+Pugh in the June 1990 of Communications of the ACM.</p>
+<p>The format of the MedianFilterImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MedianFilterImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>The radius of the pixel neighborhood.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="motionblurimage">
+<h1><a class="toc-backref" href="#id66">MotionBlurImage</a></h1>
+<div class="section" id="id29">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MotionBlurImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ const double angle, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id30">
+<h2>Description</h2>
+<p>MotionBlurImage() simulates motion blur. We convolve the image with a
+Gaussian operator of the given radius and standard deviation (sigma).
+For reasonable results, radius should be larger than sigma. Use a
+radius of 0 and MotionBlurImage() selects a suitable radius for you.
+Angle gives the angle of the blurring motion (direction object appears
+to be coming from).</p>
+<p>Andrew Protano contributed this effect.</p>
+<p>The format of the MotionBlurImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MotionBlurImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ const double angle, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting
+the center pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>angle:</dt>
+<dd>Apply the effect along this angle.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="randomchannelthresholdimage">
+<h1><a class="toc-backref" href="#id67">RandomChannelThresholdImage</a></h1>
+<div class="section" id="id31">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int RandomChannelThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *channel,
+ const char *thresholds,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id32">
+<h2>Description</h2>
+<p>RandomChannelThresholdImage() changes the value of individual pixels based
+on the intensity of each pixel compared to a random threshold. The result
+is a low-contrast, two color image.</p>
+<p>The format of the RandomChannelThresholdImage method is:</p>
+<pre class="literal-block">
+unsigned int RandomChannelThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *channel,
+ const char *thresholds,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>The channel or channels to be thresholded.</dd>
+<dt>thresholds:</dt>
+<dd>a geometry string containing LOWxHIGH thresholds.
+If the string contains 2x2, 3x3, 4x4, 5x5, 6x6, or 7x7, then
+an ordered dither of order 2, 3, 4, 5, 6, or 7 will be performed
+instead.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="reducenoiseimage">
+<h1><a class="toc-backref" href="#id68">ReduceNoiseImage</a></h1>
+<div class="section" id="id33">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ReduceNoiseImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id34">
+<h2>Description</h2>
+<p>ReduceNoiseImage() smooths the contours of an image while still preserving
+edge information. The algorithm works by replacing each pixel with its
+neighbor closest in value. A neighbor is defined by radius. Use a radius
+of 0 and ReduceNoise() selects a suitable radius for you.</p>
+<p>The format of the ReduceNoiseImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ReduceNoiseImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>The radius of the pixel neighborhood.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="shadeimage">
+<h1><a class="toc-backref" href="#id69">ShadeImage</a></h1>
+<div class="section" id="id35">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ShadeImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int gray, double azimuth,
+ double elevation, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id36">
+<h2>Description</h2>
+<p>ShadeImage() shines a distant light on an image to create a
+three-dimensional effect. You control the positioning of the light with
+azimuth and elevation; azimuth is measured in degrees off the x axis
+and elevation is measured in pixels above the Z axis.</p>
+<p>The format of the ShadeImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ShadeImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int gray, double azimuth,
+ double elevation, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>gray:</dt>
+<dd>A value other than zero shades the intensity of each pixel.</dd>
+<dt>azimuth, elevation:</dt>
+<dd>Define the light source direction.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="sharpenimage">
+<h1><a class="toc-backref" href="#id70">SharpenImage</a></h1>
+<div class="section" id="id37">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SharpenImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id38">
+<h2>Description</h2>
+<p>SharpenImage() sharpens an image. We convolve the image with a
+Gaussian operator of the given radius and standard deviation (sigma).
+For reasonable results, radius should be larger than sigma. Use a
+radius of 0 and SharpenImage() selects a suitable radius for you.</p>
+<p>The format of the SharpenImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SharpenImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Laplacian, in pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="sharpenimagechannel">
+<h1><a class="toc-backref" href="#id71">SharpenImageChannel</a></h1>
+<div class="section" id="id39">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SharpenImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id40">
+<h2>Description</h2>
+<p>SharpenImageChannel() sharpens an image channel. We convolve the image
+channel with a Gaussian operator of the given radius and standard
+deviation (sigma). For reasonable results, radius should be larger than
+sigma. Use a radius of 0 and SharpenImageChannel() selects a suitable
+radius for you.</p>
+<p>The format of the SharpenImageChannel method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SharpenImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>The channel to sharpen.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Laplacian, in pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="spreadimage">
+<h1><a class="toc-backref" href="#id72">SpreadImage</a></h1>
+<div class="section" id="id41">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SpreadImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id42">
+<h2>Description</h2>
+<p>SpreadImage() is a special effects method that randomly displaces each
+pixel in a block defined by the radius parameter.</p>
+<p>The format of the SpreadImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SpreadImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>Choose a random pixel in a neighborhood of this extent.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="thresholdimage">
+<h1><a class="toc-backref" href="#id73">ThresholdImage</a></h1>
+<div class="section" id="id43">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const double threshold );
+</pre>
+</div>
+<div class="section" id="id44">
+<h2>Description</h2>
+<p>ThresholdImage() changes the value of individual pixels based on
+the intensity of each pixel compared to a specified threshold. Values
+greater than the threshold are set to the maximum quantum value, and
+values equal to or below the threshold are set to the minimum quantum
+value. The result is a high-contrast, two color image.</p>
+<p>The format of the ThresholdImage method is:</p>
+<pre class="literal-block">
+MagickPassFail ThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const double threshold );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>threshold:</dt>
+<dd>Define the threshold value</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="unsharpmaskimage">
+<h1><a class="toc-backref" href="#id74">UnsharpMaskImage</a></h1>
+<div class="section" id="id45">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *UnsharpMaskImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ const double amount, const double threshold,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id46">
+<h2>Description</h2>
+<p>UnsharpMaskImage() sharpens an image. We convolve the image with a
+Gaussian operator of the given radius and standard deviation (sigma).
+For reasonable results, radius should be larger than sigma. Use a radius
+of 0 and UnsharpMaskImage() selects a suitable radius for you.</p>
+<p>The format of the UnsharpMaskImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *UnsharpMaskImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ const double amount, const double threshold,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>amount:</dt>
+<dd>The percentage of the difference between the original and the
+blur image that is added back into the original.</dd>
+<dt>threshold:</dt>
+<dd>The threshold in pixels needed to apply the diffence amount.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="unsharpmaskimagechannel">
+<h1><a class="toc-backref" href="#id75">UnsharpMaskImageChannel</a></h1>
+<div class="section" id="id47">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *UnsharpMaskImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double radius, const double sigma, const double amount,
+ const double threshold, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id48">
+<h2>Description</h2>
+<p>UnsharpMaskImageChannel() sharpens an image channel. We convolve the
+image channel with a Gaussian operator of the given radius and standard
+deviation (sigma). For reasonable results, radius should be larger than
+sigma. Use a radius of 0 and UnsharpMaskImage() selects a suitable
+radius for you.</p>
+<p>The format of the UnsharpMaskImageChannel method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *UnsharpMaskImageChannel( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double radius, const double sigma, const double amount,
+ const double threshold, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>The channel to sharpen.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>amount:</dt>
+<dd>The percentage of the difference between the original and the
+blur image that is added back into the original.</dd>
+<dt>threshold:</dt>
+<dd>The threshold in pixels needed to apply the diffence amount.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="whitethresholdimage">
+<h1><a class="toc-backref" href="#id76">WhiteThresholdImage</a></h1>
+<div class="section" id="id49">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail WhiteThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *thresholds );
+</pre>
+</div>
+<div class="section" id="id50">
+<h2>Description</h2>
+<p>WhiteThresholdImage() adjusts the levels of image channels such that
+values above a specified threshold are set to the maximum value (white)
+while the remaining pixels are unchanged.</p>
+<p>The format of the WhiteThresholdImage method is:</p>
+<pre class="literal-block">
+MagickPassFail WhiteThresholdImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *thresholds );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>thresholds:</dt>
+<dd>Channel thresholds which are specified as a comma delimited
+list containing the thresholds for red, green, blue, and opacity. If
+the list contains a percent symbol (%) then all values are treated as
+a percentage of MaxRGB.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/enhance.html b/www/api/enhance.html
new file mode 100644
index 0000000..4229325
--- /dev/null
+++ b/www/api/enhance.html
@@ -0,0 +1,278 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>enhance</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="enhance">
+<h1 class="title">enhance</h1>
+<h2 class="subtitle" id="methods-to-enhance-or-adjust-an-image">Methods to enhance or adjust an image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#contrastimage" id="id15">ContrastImage</a></li>
+<li><a class="reference internal" href="#equalizeimage" id="id16">EqualizeImage</a></li>
+<li><a class="reference internal" href="#gammaimage" id="id17">GammaImage</a></li>
+<li><a class="reference internal" href="#levelimage" id="id18">LevelImage</a></li>
+<li><a class="reference internal" href="#levelimagechannel" id="id19">LevelImageChannel</a></li>
+<li><a class="reference internal" href="#modulateimage" id="id20">ModulateImage</a></li>
+<li><a class="reference internal" href="#negateimage" id="id21">NegateImage</a></li>
+<li><a class="reference internal" href="#normalizeimage" id="id22">NormalizeImage</a></li>
+</ul>
+</div>
+<div class="section" id="contrastimage">
+<h1><a class="toc-backref" href="#id15">ContrastImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int ContrastImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int sharpen );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>ContrastImage() enhances the intensity differences between the lighter and
+darker elements of the image. Set sharpen to a value other than 0 to
+increase the image contrast otherwise the contrast is reduced.</p>
+<p>The format of the ContrastImage method is:</p>
+<pre class="literal-block">
+unsigned int ContrastImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int sharpen );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>sharpen:</dt>
+<dd>Increase or decrease image contrast.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="equalizeimage">
+<h1><a class="toc-backref" href="#id16">EqualizeImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int EqualizeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>EqualizeImage() applies a histogram equalization to the image.</p>
+<p>The format of the EqualizeImage method is:</p>
+<pre class="literal-block">
+unsigned int EqualizeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="gammaimage">
+<h1><a class="toc-backref" href="#id17">GammaImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail GammaImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *level );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>Use GammaImage() to gamma-correct an image. The same image viewed on
+different devices will have perceptual differences in the way the
+image's intensities are represented on the screen. Specify individual
+gamma levels for the red, green, and blue channels (e.g. &quot;1.0,2.2,0.45&quot;),
+or adjust all three with a single gamma parameter. Values typically range
+from 0.45 to 2.6.</p>
+<p>You can also reduce the influence of a particular channel with a gamma
+value of 0.</p>
+<p>The format of the GammaImage method is:</p>
+<pre class="literal-block">
+MagickPassFail GammaImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *level );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>level:</dt>
+<dd>Define the level of gamma correction.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="levelimage">
+<h1><a class="toc-backref" href="#id18">LevelImage</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int LevelImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *level );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>LevelImage() adjusts the levels of an image by scaling the colors falling
+between specified white and black points to the full available quantum
+range. The parameters provided represent the black, mid (gamma), and white
+points. The black point specifies the darkest color in the image. Colors
+darker than the black point are set to zero. Mid point specifies a gamma
+correction to apply to the image. White point specifies the lightest color
+in the image. Colors brighter than the white point are set to the maximum
+quantum value.</p>
+<p>The format of the LevelImage method is:</p>
+<pre class="literal-block">
+unsigned int LevelImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *level );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>levels:</dt>
+<dd>Specify the levels as a string of the form &quot;black/mid/white&quot;
+(e.g. &quot;10,1.0,65000) where black and white have the range of 0-MaxRGB,
+and mid has the range 0-10.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="levelimagechannel">
+<h1><a class="toc-backref" href="#id19">LevelImageChannel</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail LevelImageChannel( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double black_point, const double mid_point,
+ const double white_point );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>LevelImageChannel() adjusts the levels of one or more channels by
+scaling the colors falling between specified white and black points to
+the full available quantum range. The parameters provided represent the
+black, mid (gamma), and white points. The black point specifies the
+darkest color in the image. Colors darker than the black point are set to
+zero. Mid point specifies a gamma correction to apply to the image.
+White point specifies the lightest color in the image. Colors brighter
+than the white point are set to the maximum quantum value.</p>
+<p>The format of the LevelImage method is:</p>
+<pre class="literal-block">
+MagickPassFail LevelImageChannel( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double black_point, const double mid_point,
+ const double white_point );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to level: Red, Cyan, Green, Magenta,
+Blue, Yellow, Opacity, or All.</dd>
+<dt>black_point, mid_point, white_point:</dt>
+<dd>Specify the levels where the black
+and white points have the range of 0-MaxRGB, and mid has the range 0-10.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="modulateimage">
+<h1><a class="toc-backref" href="#id20">ModulateImage</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int ModulateImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *modulate );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>ModulateImage() lets you control the brightness, saturation, and hue
+of an image. Modulate represents the brightness, saturation, and hue
+as one parameter (e.g. 90,150,100).</p>
+<p>The format of the ModulateImage method is:</p>
+<pre class="literal-block">
+unsigned int ModulateImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *modulate );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>modulate:</dt>
+<dd>Define the percent change in brightness, saturation, and
+hue.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="negateimage">
+<h1><a class="toc-backref" href="#id21">NegateImage</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int NegateImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int grayscale );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>Method NegateImage negates the colors in the reference image. The
+Grayscale option means that only grayscale values within the image are
+negated.</p>
+<p>The format of the NegateImage method is:</p>
+<pre class="literal-block">
+unsigned int NegateImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int grayscale );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="normalizeimage">
+<h1><a class="toc-backref" href="#id22">NormalizeImage</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int NormalizeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>The NormalizeImage() method enhances the contrast of a color image by
+adjusting the pixels color to span the entire range of colors available.</p>
+<p>The format of the NormalizeImage method is:</p>
+<pre class="literal-block">
+unsigned int NormalizeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/error.html b/www/api/error.html
new file mode 100644
index 0000000..acf02b1
--- /dev/null
+++ b/www/api/error.html
@@ -0,0 +1,421 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>error</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="error">
+<h1 class="title">error</h1>
+<h2 class="subtitle" id="error-reporting-methods">Error reporting methods</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#catchexception" id="id27">CatchException</a></li>
+<li><a class="reference internal" href="#copyexception" id="id28">CopyException</a></li>
+<li><a class="reference internal" href="#destroyexceptioninfo" id="id29">DestroyExceptionInfo</a></li>
+<li><a class="reference internal" href="#getexceptioninfo" id="id30">GetExceptionInfo</a></li>
+<li><a class="reference internal" href="#getlocaleexceptionmessage" id="id31">GetLocaleExceptionMessage</a></li>
+<li><a class="reference internal" href="#magickerror" id="id32">MagickError</a></li>
+<li><a class="reference internal" href="#magickfatalerror" id="id33">MagickFatalError</a></li>
+<li><a class="reference internal" href="#magickwarning" id="id34">MagickWarning</a></li>
+<li><a class="reference internal" href="#seterrorhandler" id="id35">SetErrorHandler</a></li>
+<li><a class="reference internal" href="#setexceptioninfo" id="id36">SetExceptionInfo</a></li>
+<li><a class="reference internal" href="#setfatalerrorhandler" id="id37">SetFatalErrorHandler</a></li>
+<li><a class="reference internal" href="#setwarninghandler" id="id38">SetWarningHandler</a></li>
+<li><a class="reference internal" href="#throwexception" id="id39">ThrowException</a></li>
+<li><a class="reference internal" href="#throwloggedexception" id="id40">ThrowLoggedException</a></li>
+</ul>
+</div>
+<div class="section" id="catchexception">
+<h1><a class="toc-backref" href="#id27">CatchException</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+CatchException( const <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>CatchException() returns if no exceptions is found otherwise it reports
+the exception as a warning, error, or fatal depending on the severity.</p>
+<p>The format of the CatchException method is:</p>
+<pre class="literal-block">
+CatchException( const <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>The exception info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="copyexception">
+<h1><a class="toc-backref" href="#id28">CopyException</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void CopyException( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *copy, const <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *original );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>CopyException() copies exception data from one ExceptionInfo structure
+to another.</p>
+<p>The format of the CopyException method is:</p>
+<pre class="literal-block">
+void CopyException( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *copy, const <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *original );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>copy:</dt>
+<dd>The exception to copy to.</dd>
+<dt>original:</dt>
+<dd>The exception to copy from.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyexceptioninfo">
+<h1><a class="toc-backref" href="#id29">DestroyExceptionInfo</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyExceptionInfo( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DestroyExceptionInfo() deallocates memory associated with exception.</p>
+<p>The format of the DestroyExceptionInfo method is:</p>
+<pre class="literal-block">
+void DestroyExceptionInfo( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>The exception info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getexceptioninfo">
+<h1><a class="toc-backref" href="#id30">GetExceptionInfo</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+GetExceptionInfo( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>GetExceptionInfo() initializes an exception to default values.</p>
+<p>The format of the GetExceptionInfo method is:</p>
+<pre class="literal-block">
+GetExceptionInfo( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>The exception info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getlocaleexceptionmessage">
+<h1><a class="toc-backref" href="#id31">GetLocaleExceptionMessage</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *GetLocaleExceptionMessage( const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> severity, const char *tag );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>GetLocaleExceptionMessage() converts a enumerated exception severity and tag
+to a message in the current locale.</p>
+<p>The format of the GetLocaleExceptionMessage method is:</p>
+<pre class="literal-block">
+const char *GetLocaleExceptionMessage( const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> severity, const char *tag );
+</pre>
+<dl class="docutils">
+<dt>severity:</dt>
+<dd>the severity of the exception.</dd>
+<dt>tag:</dt>
+<dd>the message tag.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickerror">
+<h1><a class="toc-backref" href="#id32">MagickError</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickError( const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> error, const char *reason, const char *description );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>Method MagickError calls the error handler methods with an error reason.</p>
+<p>The format of the MagickError method is:</p>
+<pre class="literal-block">
+void MagickError( const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> error, const char *reason, const char *description );
+</pre>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>Specifies the numeric error category.</dd>
+<dt>reason:</dt>
+<dd>Specifies the reason to display before terminating the
+program.</dd>
+<dt>description:</dt>
+<dd>Specifies any description to the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickfatalerror">
+<h1><a class="toc-backref" href="#id33">MagickFatalError</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickFatalError( const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> error, const char *reason,
+ const char *description );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>MagickFatalError() calls the fatal error handler methods with an error
+reason. The fatal error handler is not expected to return!</p>
+<p>The format of the MagickError method is:</p>
+<pre class="literal-block">
+void MagickFatalError( const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> error, const char *reason,
+ const char *description );
+</pre>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>Specifies the numeric error category.</dd>
+<dt>reason:</dt>
+<dd>Specifies the reason to display before terminating the
+program.</dd>
+<dt>description:</dt>
+<dd>Specifies any description to the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickwarning">
+<h1><a class="toc-backref" href="#id34">MagickWarning</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickWarning( const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> warning, const char *reason,
+ const char *description );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>Method MagickWarning calls the warning handler methods with a warning
+reason.</p>
+<p>The format of the MagickWarning method is:</p>
+<pre class="literal-block">
+void MagickWarning( const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> warning, const char *reason,
+ const char *description );
+</pre>
+<dl class="docutils">
+<dt>warning:</dt>
+<dd>The warning severity.</dd>
+<dt>reason:</dt>
+<dd>Define the reason for the warning.</dd>
+<dt>description:</dt>
+<dd>Describe the warning.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="seterrorhandler">
+<h1><a class="toc-backref" href="#id35">SetErrorHandler</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#errorhandler">ErrorHandler</a> SetErrorHandler( <a class="reference external" href="../api/types.html#errorhandler">ErrorHandler</a> handler );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>SetErrorHandler() sets the error handler to the specified method
+and returns the previous error handler.</p>
+<p>The format of the SetErrorHandler method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#errorhandler">ErrorHandler</a> SetErrorHandler( <a class="reference external" href="../api/types.html#errorhandler">ErrorHandler</a> handler );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>handler:</dt>
+<dd>The method to handle errors.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setexceptioninfo">
+<h1><a class="toc-backref" href="#id36">SetExceptionInfo</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+SetExceptionInfo( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception, <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> severity );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>SetExceptionInfo() set the exception severity.</p>
+<p>The format of the SetExceptionInfo method is:</p>
+<pre class="literal-block">
+SetExceptionInfo( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception, <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> severity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>The exception info.</dd>
+<dt>severity:</dt>
+<dd>The exception severity.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setfatalerrorhandler">
+<h1><a class="toc-backref" href="#id37">SetFatalErrorHandler</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+FatalErrorHandler SetFatalErrorHandler( FatalErrorHandler handler );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>SetFatalErrorHandler() sets the fatal error handler to the specified method
+and returns the previous fatal error handler.</p>
+<p>The format of the SetFatalErrorHandler method is:</p>
+<pre class="literal-block">
+FatalErrorHandler SetFatalErrorHandler( FatalErrorHandler handler );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>handler:</dt>
+<dd>The method to handle errors.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setwarninghandler">
+<h1><a class="toc-backref" href="#id38">SetWarningHandler</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#errorhandler">ErrorHandler</a> SetWarningHandler( <a class="reference external" href="../api/types.html#errorhandler">ErrorHandler</a> handler );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>SetWarningHandler() sets the warning handler to the specified method
+and returns the previous warning handler.</p>
+<p>The format of the SetWarningHandler method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#errorhandler">ErrorHandler</a> SetWarningHandler( <a class="reference external" href="../api/types.html#errorhandler">ErrorHandler</a> handler );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>handler:</dt>
+<dd>The method to handle warnings.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="throwexception">
+<h1><a class="toc-backref" href="#id39">ThrowException</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void ThrowException( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception, const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> severity,
+ const char *reason, const char *description );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>ThrowException() throws an exception with the specified severity code,
+reason, and optional description.</p>
+<p>The format of the ThrowException method is:</p>
+<pre class="literal-block">
+void ThrowException( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception, const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> severity,
+ const char *reason, const char *description );
+</pre>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>The exception.</dd>
+<dt>severity:</dt>
+<dd>The severity of the exception.</dd>
+<dt>reason:</dt>
+<dd>The reason of the exception.</dd>
+<dt>description:</dt>
+<dd>The exception description.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="throwloggedexception">
+<h1><a class="toc-backref" href="#id40">ThrowLoggedException</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void ThrowLoggedException( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception, const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> severity,
+ const char *reason, const char *description, const char *module,
+ const char *function, const unsigned long line ;
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>ThrowLoggedException() throws an exception with the specified severity code,
+reason, optional description, source filename, function name, and line
+number. If logging is enabled, the exception is also logged.</p>
+<p>The format of the ThrowLoggedException method is:</p>
+<pre class="literal-block">
+void ThrowLoggedException( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception, const <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> severity,
+ const char *reason, const char *description, const char *module,
+ const char *function, const unsigned long line ;
+</pre>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>The exception.</dd>
+<dt>severity:</dt>
+<dd>The severity of the exception.</dd>
+<dt>reason:</dt>
+<dd>The reason of the exception.</dd>
+<dt>description:</dt>
+<dd>The exception description.</dd>
+<dt>filename:</dt>
+<dd>The source module filename.</dd>
+<dt>function:</dt>
+<dd>The function name.</dd>
+<dt>line:</dt>
+<dd>The line number of the source module.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/export.html b/www/api/export.html
new file mode 100644
index 0000000..386b4f0
--- /dev/null
+++ b/www/api/export.html
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>export</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="export">
+<h1 class="title">export</h1>
+<h2 class="subtitle" id="export-image-pixels-into-common-representations">Export image pixels into common representations</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#exportimagepixelarea" id="id5">ExportImagePixelArea</a></li>
+<li><a class="reference internal" href="#exportviewpixelarea" id="id6">ExportViewPixelArea</a></li>
+<li><a class="reference internal" href="#exportpixelareaoptionsinit" id="id7">ExportPixelAreaOptionsInit</a></li>
+</ul>
+</div>
+<div class="section" id="exportimagepixelarea">
+<h1><a class="toc-backref" href="#id5">ExportImagePixelArea</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ExportImagePixelArea( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ unsigned int quantum_size, unsigned char *destination,
+ const ExportPixelAreaOptions *options,
+ ExportPixelAreaInfo *export_info );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>ExportImagePixelArea() transfers one or more pixel components from the
+default image pixel cache view to a user supplied buffer. By default,
+values are written in network (big-endian) byte/bit order. By setting
+the 'endian' member of ExportPixelAreaOptions, 16, 32 and 64-bit values
+may be output as little (LSBEndian), big (MSBEndian), or host native
+(NativeEndian) endian values. This function is quite powerful in that
+besides common native CPU type sizes, it can support any integer bit
+depth from 1 to 32 (e.g. 13), 64-bits as well as 32 and 64-bit float.</p>
+<p>MagickPass is returned if the pixels are successfully transferred,
+otherwise MagickFail.</p>
+<p>The format of the ExportImagePixelArea method is:</p>
+<pre class="literal-block">
+MagickPassFail ExportImagePixelArea( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ unsigned int quantum_size, unsigned char *destination,
+ const ExportPixelAreaOptions *options,
+ ExportPixelAreaInfo *export_info );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Returns MagickPass if the pixels are successfully transferred,
+otherwise MagickFail.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>quantum_type:</dt>
+<dd>Declare which pixel components to transfer (AlphaQuantum,
+BlackQuantum, BlueQuantum, CMYKAQuantum, CMYKQuantum, CyanQuantum,
+GrayAlphaQuantum, GrayQuantum, GreenQuantum, IndexAlphaQuantum,
+IndexQuantum, MagentaQuantum, RGBAQuantum, RGBQuantum,
+RedQuantum, YellowQuantum)</dd>
+<dt>quantum_size:</dt>
+<dd>Bits per quantum sample (range 1-32, and 64).</dd>
+<dt>destination:</dt>
+<dd>The components are transferred to this buffer. The user
+is responsible for ensuring that the destination buffer is large
+enough.</dd>
+<dt>options:</dt>
+<dd>Additional options specific to quantum_type (may be NULL).</dd>
+<dt>export_info :</dt>
+<dd>Populated with information regarding the pixels
+exported (may be NULL)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="exportviewpixelarea">
+<h1><a class="toc-backref" href="#id6">ExportViewPixelArea</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ExportViewPixelArea( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ unsigned int quantum_size, unsigned char *destination,
+ const ExportPixelAreaOptions *options,
+ ExportPixelAreaInfo *export_info );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>ExportViewPixelArea() transfers one or more pixel components from the
+specified image pixel cache view to a user supplied buffer. By default,
+values are written in network (big-endian) byte/bit order. By setting the
+'endian' member of ExportPixelAreaOptions, 16, 32 and 64-bit values may be
+output as little (LSBEndian), big (MSBEndian), or host native
+(NativeEndian) endian values. This function is quite powerful in that
+besides common native CPU type sizes, it can support any integer bit depth
+from 1 to 32 (e.g. 13), 64-bits as well as 32 and 64-bit float.</p>
+<p>MagickPass is returned if the pixels are successfully transferred,
+otherwise MagickFail.</p>
+<p>The format of the ExportViewPixelArea method is:</p>
+<pre class="literal-block">
+MagickPassFail ExportViewPixelArea( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ unsigned int quantum_size, unsigned char *destination,
+ const ExportPixelAreaOptions *options,
+ ExportPixelAreaInfo *export_info );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Returns MagickPass if the pixels are successfully transferred,
+otherwise MagickFail.</dd>
+<dt>view:</dt>
+<dd>The image pixel cache view.</dd>
+<dt>quantum_type:</dt>
+<dd>Declare which pixel components to transfer (AlphaQuantum,
+BlackQuantum, BlueQuantum, CMYKAQuantum, CMYKQuantum, CyanQuantum,
+GrayAlphaQuantum, GrayQuantum, GreenQuantum, IndexAlphaQuantum,
+IndexQuantum, MagentaQuantum, RGBAQuantum, RGBQuantum,
+RedQuantum, YellowQuantum)</dd>
+<dt>quantum_size:</dt>
+<dd>Bits per quantum sample (range 1-32, and 64).</dd>
+<dt>destination:</dt>
+<dd>The components are transferred to this buffer. The user
+is responsible for ensuring that the destination buffer is large
+enough.</dd>
+<dt>options:</dt>
+<dd>Additional options specific to quantum_type (may be NULL).</dd>
+<dt>export_info :</dt>
+<dd>Populated with information regarding the pixels
+exported (may be NULL)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="exportpixelareaoptionsinit">
+<h1><a class="toc-backref" href="#id7">ExportPixelAreaOptionsInit</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void ExportPixelAreaOptionsInit( ExportPixelAreaOptions *options );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>ExportPixelAreaOptionsInit() initializes the options structure which is
+optionally passed to ExportPixelArea()</p>
+<p>The format of the ExportPixelAreaOptionsInit method is:</p>
+<pre class="literal-block">
+void ExportPixelAreaOptionsInit( ExportPixelAreaOptions *options );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>options:</dt>
+<dd>Options structure to initialize.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/fx.html b/www/api/fx.html
new file mode 100644
index 0000000..bee0aba
--- /dev/null
+++ b/www/api/fx.html
@@ -0,0 +1,410 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>fx</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="fx">
+<h1 class="title">fx</h1>
+<h2 class="subtitle" id="image-special-effects-methods">Image special effects methods</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#charcoalimage" id="id21">CharcoalImage</a></li>
+<li><a class="reference internal" href="#colorizeimage" id="id22">ColorizeImage</a></li>
+<li><a class="reference internal" href="#colormatriximage" id="id23">ColorMatrixImage</a></li>
+<li><a class="reference internal" href="#implodeimage" id="id24">ImplodeImage</a></li>
+<li><a class="reference internal" href="#morphimages" id="id25">MorphImages</a></li>
+<li><a class="reference internal" href="#oilpaintimage" id="id26">OilPaintImage</a></li>
+<li><a class="reference internal" href="#solarizeimage" id="id27">SolarizeImage</a></li>
+<li><a class="reference internal" href="#steganoimage" id="id28">SteganoImage</a></li>
+<li><a class="reference internal" href="#stereoimage" id="id29">StereoImage</a></li>
+<li><a class="reference internal" href="#swirlimage" id="id30">SwirlImage</a></li>
+<li><a class="reference internal" href="#waveimage" id="id31">WaveImage</a></li>
+</ul>
+</div>
+<div class="section" id="charcoalimage">
+<h1><a class="toc-backref" href="#id21">CharcoalImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CharcoalImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Method CharcoalImage creates a new image that is a copy of an existing
+one with the edge highlighted. It allocates the memory necessary for the
+new Image structure and returns a pointer to the new image.</p>
+<p>The format of the CharcoalImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CharcoalImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius, const double sigma,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>charcoal_image:</dt>
+<dd>Method CharcoalImage returns a pointer to the image
+after it is embossed. A null image is returned if there is a memory
+shortage.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>the radius of the pixel neighborhood.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="colorizeimage">
+<h1><a class="toc-backref" href="#id22">ColorizeImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ColorizeImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *opacity,
+ const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>ColorizeImage() blends the fill color with each pixel in the image.
+A percentage blend is specified with opacity. Control the application
+of different color components by specifying a different percentage for
+each component (e.g. 90/100/10 is 90% red, 100% green, and 10% blue).</p>
+<p>The format of the ColorizeImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ColorizeImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *opacity,
+ const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>opacity:</dt>
+<dd>A character string indicating the level of opacity as a
+percentage.</dd>
+<dt>target:</dt>
+<dd>A color value.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="colormatriximage">
+<h1><a class="toc-backref" href="#id23">ColorMatrixImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ColorMatrixImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int order,
+ const double *color_matrix );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>ColorMatrixImage() applies a color matrix to the image channels. The
+user supplied matrix may be of order 1 to 5 (1x1 through 5x5) and is
+used to update the default identity matrix:</p>
+<p>1 0 0 0 0
+0 1 0 0 0
+0 0 1 0 0
+0 0 0 1 0
+0 0 0 0 1</p>
+<p>where the first four columns represent the ratio of the color (red,
+green, blue) and opacity components incorporated in the output summation.
+The first four rows represent the summations for red, green, blue, and
+opacity. The last row is a dummy row and is not used. The last column
+represents a constant value (expressed as a ratio of MaxRGB) to be
+added to the row summation. The following is a summary of how the
+matrix is applied:</p>
+<p>r' = r*m[0,0] + g*m[1,0] + b*m[2,0] + o*m[3,0] + MaxRGB*m[4,0]
+g' = r*m[0,1] + g*m[1,1] + b*m[2,1] + o*m[3,1] + MaxRGB*m[4,1]
+b' = r*m[0,2] + g*m[1,2] + b*m[2,2] + o*m[3,2] + MaxRGB*m[4,2]
+o' = r*m[0,3] + g*m[1,3] + b*m[2,3] + o*m[3,3] + MaxRGB*m[4,3]</p>
+<p>The format of the ColorMatrixImage method is:</p>
+<pre class="literal-block">
+MagickPassFail ColorMatrixImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int order,
+ const double *color_matrix );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>order:</dt>
+<dd>The number of columns and rows in the filter kernel.</dd>
+<dt>matrix:</dt>
+<dd>An array of double representing the matrix</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="implodeimage">
+<h1><a class="toc-backref" href="#id24">ImplodeImage</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ImplodeImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double amount,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>Method ImplodeImage creates a new image that is a copy of an existing
+one with the image pixels &quot;implode&quot; by the specified percentage. It
+allocates the memory necessary for the new Image structure and returns a
+pointer to the new image.</p>
+<p>The format of the ImplodeImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ImplodeImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double amount,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>implode_image:</dt>
+<dd>Method ImplodeImage returns a pointer to the image
+after it is implode. A null image is returned if there is a memory
+shortage.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>amount:</dt>
+<dd>Define the extent of the implosion.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="morphimages">
+<h1><a class="toc-backref" href="#id25">MorphImages</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MorphImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long number_frames,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>The MorphImages() method requires a minimum of two images. The first
+image is transformed into the second by a number of intervening images
+as specified by frames.</p>
+<p>The format of the MorphImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MorphImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long number_frames,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>number_frames:</dt>
+<dd>Define the number of in-between image to generate.
+The more in-between frames, the smoother the morph.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="oilpaintimage">
+<h1><a class="toc-backref" href="#id26">OilPaintImage</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *OilPaintImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>OilPaintImage() applies a special effect filter that simulates an oil
+painting. Each pixel is replaced by the most frequent color occurring
+in a circular region defined by radius.</p>
+<p>The format of the OilPaintImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *OilPaintImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double radius,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>radius:</dt>
+<dd>The radius of the circular neighborhood.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="solarizeimage">
+<h1><a class="toc-backref" href="#id27">SolarizeImage</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int SolarizeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const double threshold );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>SolarizeImage() applies a special effect to the image, similar to the effect
+achieved in a photo darkroom by selectively exposing areas of photo
+sensitive paper to light. Threshold ranges from 0 to MaxRGB and is a
+measure of the extent of the solarization. False is returned if an error
+is encountered.</p>
+<p>The format of the SolarizeImage method is:</p>
+<pre class="literal-block">
+unsigned int SolarizeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const double threshold );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>threshold:</dt>
+<dd>Define the extent of the solarization.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="steganoimage">
+<h1><a class="toc-backref" href="#id28">SteganoImage</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SteganoImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#image">Image</a> *watermark,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>Use SteganoImage() to hide a digital watermark within the image.
+Recover the hidden watermark later to prove that the authenticity of
+an image. Offset defines the start position within the image to hide
+the watermark.</p>
+<p>The format of the SteganoImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SteganoImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#image">Image</a> *watermark,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>watermark:</dt>
+<dd>The watermark image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="stereoimage">
+<h1><a class="toc-backref" href="#id29">StereoImage</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *StereoImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *offset_image,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>StereoImage() combines two images and produces a single image that is the
+composite of a left and right image of a stereo pair. Special red-green
+stereo glasses are required to view this effect.</p>
+<p>The format of the StereoImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *StereoImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *offset_image,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>stereo_image:</dt>
+<dd>Method StereoImage returns a pointer to the stereo
+image. A null image is returned if there is a memory shortage.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>offset_image:</dt>
+<dd>Another image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="swirlimage">
+<h1><a class="toc-backref" href="#id30">SwirlImage</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SwirlImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, double degrees, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>SwirlImage() swirls the pixels about the center of the image, where
+degrees indicates the sweep of the arc through which each pixel is moved.
+You get a more dramatic effect as the degrees move from 1 to 360.</p>
+<p>The format of the SwirlImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SwirlImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, double degrees, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>degrees:</dt>
+<dd>Define the tightness of the swirling effect.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="waveimage">
+<h1><a class="toc-backref" href="#id31">WaveImage</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *WaveImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double amplitude, const double wave_length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>The WaveImage() filter creates a &quot;ripple&quot; effect in the image by shifting
+the pixels vertically along a sine wave whose amplitude and wavelength
+is specified by the given parameters.</p>
+<p>The format of the WaveImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *WaveImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double amplitude, const double wave_length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>amplitude, frequency:</dt>
+<dd>Define the amplitude and wave_length of the
+sine wave.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/hclut.html b/www/api/hclut.html
new file mode 100644
index 0000000..54ad0dd
--- /dev/null
+++ b/www/api/hclut.html
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>hclut</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="hclut">
+<h1 class="title">hclut</h1>
+<h2 class="subtitle" id="apply-hald-clut-to-image">Apply Hald CLUT to image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#haldclutimage" id="id1">HaldClutImage</a></li>
+</ul>
+</div>
+<div class="section" id="haldclutimage">
+<h1><a class="toc-backref" href="#id1">HaldClutImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail HaldClutImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *clut );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>The HaldClutImage() method apply a color lookup table (Hald CLUT) to the
+image. The fundamental principle of the Hald CLUT algorithm is that
+application of an identity CLUT causes no change to the input image,
+but an identity CLUT image which has had its colors transformed in
+some way (e.g. in Adobe Photoshop) may be used to implement an identical
+transform on any other image.</p>
+<p>The minimum CLUT level is 2, and the maximum depends on available memory
+(largest successfully tested is 24). A CLUT image is required to have equal
+width and height. A CLUT of level 8 is an image of dimension 512x512, a CLUT
+of level 16 is an image of dimension 4096x4096. Interpolation is used so
+extremely large CLUT images are not required.</p>
+<p>GraphicsMagick provides an 'identity' coder which may be used to generate
+identity HLUTs. For example, reading from &quot;identity:8&quot; creates an identity
+CLUT of order 8.</p>
+<p>The Hald CLUT algorithm has been developed by Eskil Steenberg as described
+at <a class="reference external" href="http://www.quelsolaar.com/technology/clut.html">http://www.quelsolaar.com/technology/clut.html</a>, and was adapted for
+GraphicsMagick by Clément Follet with support from Cédric Lejeune of
+Workflowers.</p>
+<p>The format of the HaldClutImage method is:</p>
+<pre class="literal-block">
+MagickPassFail HaldClutImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *clut );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>clut:</dt>
+<dd>The color lookup table image</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/image.html b/www/api/image.html
new file mode 100644
index 0000000..0aa1d40
--- /dev/null
+++ b/www/api/image.html
@@ -0,0 +1,964 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>image</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="image">
+<h1 class="title">image</h1>
+<h2 class="subtitle" id="miscellaneous-image-methods">Miscellaneous image methods</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#accessdefinition" id="id64">AccessDefinition</a></li>
+<li><a class="reference internal" href="#adddefinition" id="id65">AddDefinition</a></li>
+<li><a class="reference internal" href="#adddefinitions" id="id66">AddDefinitions</a></li>
+<li><a class="reference internal" href="#allocateimage" id="id67">AllocateImage</a></li>
+<li><a class="reference internal" href="#allocatenextimage" id="id68">AllocateNextImage</a></li>
+<li><a class="reference internal" href="#animateimages" id="id69">AnimateImages</a></li>
+<li><a class="reference internal" href="#appendimages" id="id70">AppendImages</a></li>
+<li><a class="reference internal" href="#catchimageexception" id="id71">CatchImageException</a></li>
+<li><a class="reference internal" href="#clippathimage" id="id72">ClipPathImage</a></li>
+<li><a class="reference internal" href="#cloneimage" id="id73">CloneImage</a></li>
+<li><a class="reference internal" href="#cloneimageinfo" id="id74">CloneImageInfo</a></li>
+<li><a class="reference internal" href="#destroyimage" id="id75">DestroyImage</a></li>
+<li><a class="reference internal" href="#destroyimageinfo" id="id76">DestroyImageInfo</a></li>
+<li><a class="reference internal" href="#displayimages" id="id77">DisplayImages</a></li>
+<li><a class="reference internal" href="#getimageclipmask" id="id78">GetImageClipMask</a></li>
+<li><a class="reference internal" href="#getimageexception" id="id79">GetImageException</a></li>
+<li><a class="reference internal" href="#getimagegeometry" id="id80">GetImageGeometry</a></li>
+<li><a class="reference internal" href="#getimageinfo" id="id81">GetImageInfo</a></li>
+<li><a class="reference internal" href="#istaintimage" id="id82">IsTaintImage</a></li>
+<li><a class="reference internal" href="#modifyimage" id="id83">ModifyImage</a></li>
+<li><a class="reference internal" href="#referenceimage" id="id84">ReferenceImage</a></li>
+<li><a class="reference internal" href="#removedefinitions" id="id85">RemoveDefinitions</a></li>
+<li><a class="reference internal" href="#resetimagepage" id="id86">ResetImagePage</a></li>
+<li><a class="reference internal" href="#setimageex" id="id87">SetImageEx</a></li>
+<li><a class="reference internal" href="#setimage" id="id88">SetImage</a></li>
+<li><a class="reference internal" href="#setimagecolor" id="id89">SetImageColor</a></li>
+<li><a class="reference internal" href="#setimagecolorregion" id="id90">SetImageColorRegion</a></li>
+<li><a class="reference internal" href="#setimageclipmask" id="id91">SetImageClipMask</a></li>
+<li><a class="reference internal" href="#setimagedepth" id="id92">SetImageDepth</a></li>
+<li><a class="reference internal" href="#setimageopacity" id="id93">SetImageOpacity</a></li>
+<li><a class="reference internal" href="#setimagetype" id="id94">SetImageType</a></li>
+<li><a class="reference internal" href="#stripimage" id="id95">StripImage</a></li>
+</ul>
+</div>
+<div class="section" id="accessdefinition">
+<h1><a class="toc-backref" href="#id64">AccessDefinition</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *AccessDefinition( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *magick,
+ const char *key );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AccessDefinition() searches the definitions for an entry matching the
+specified magick and key. NULL is returned if no matching entry is found.</p>
+<p>The format of the AccessDefinition method is:</p>
+<pre class="literal-block">
+const char *AccessDefinition( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *magick,
+ const char *key );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>magick:</dt>
+<dd>Format ID. This is usually the same as the coder name.</dd>
+<dt>key:</dt>
+<dd>Key to search for.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="adddefinition">
+<h1><a class="toc-backref" href="#id65">AddDefinition</a></h1>
+<div class="section" id="id2">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail AddDefinition( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *magick, const char *key,
+ const char *value, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id3">
+<h2>Description</h2>
+<p>AddDefinition() adds a key/value definition to the current map of
+definitions in ImageInfo. Definitions may be used by coders/decoders
+that read and write images.</p>
+<p>The format of the AddDefinition method is:</p>
+<pre class="literal-block">
+MagickPassFail AddDefinition( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *magick, const char *key,
+ const char *value, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>magick:</dt>
+<dd>format/classification identifier</dd>
+<dt>key:</dt>
+<dd>subidentifier within format/classification</dd>
+<dt>value:</dt>
+<dd>definition value</dd>
+<dt>exception:</dt>
+<dd>Errors result in updates to this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="adddefinitions">
+<h1><a class="toc-backref" href="#id66">AddDefinitions</a></h1>
+<div class="section" id="id4">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail AddDefinitions( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *options );
+</pre>
+</div>
+<div class="section" id="id5">
+<h2>Description</h2>
+<p>AddDefinitions() adds definitions from a key/value based string to the current
+map of definitions in ImageInfo. Definitions may be used by coders/decoders
+that read and write images.</p>
+<p>The format of the AddDefinitions method is:</p>
+<pre class="literal-block">
+MagickPassFail AddDefinitions( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *options );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>options:</dt>
+<dd>List of key/value pairs to put in the definitions map. The
+format of the string is &quot;key1[=[value1]],key2[=[value2]],...&quot;. A missing
+value argument (with or without the equal sign) inserts an empty, zero
+length string as value for a key.</dd>
+<dt>exception:</dt>
+<dd>Errors result in updates to this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="allocateimage">
+<h1><a class="toc-backref" href="#id67">AllocateImage</a></h1>
+<div class="section" id="id6">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AllocateImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info );
+</pre>
+</div>
+<div class="section" id="id7">
+<h2>Description</h2>
+<p>AllocateImage() returns a pointer to an image structure initialized to
+default values.</p>
+<p>The format of the AllocateImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AllocateImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>Many of the image default values are set from this
+structure. For example, filename, compression, depth, background color,
+and others.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="allocatenextimage">
+<h1><a class="toc-backref" href="#id68">AllocateNextImage</a></h1>
+<div class="section" id="id8">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void AllocateNextImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id9">
+<h2>Description</h2>
+<p>Use AllocateNextImage() to initialize the next image in a sequence to
+default values. The next member of image points to the newly allocated
+image. If there is a memory shortage, next is assigned NULL.</p>
+<p>The format of the AllocateNextImage method is:</p>
+<pre class="literal-block">
+void AllocateNextImage( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>Many of the image default values are set from this
+structure. For example, filename, compression, depth, background color,
+and others.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="animateimages">
+<h1><a class="toc-backref" href="#id69">AnimateImages</a></h1>
+<div class="section" id="id10">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int AnimateImages( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id11">
+<h2>Description</h2>
+<p>AnimateImages() repeatedly displays an image sequence to any X window
+screen. It returns a value other than 0 if successful. Check the
+exception member of image to determine the reason for any failure.</p>
+<p>The format of the AnimateImages method is:</p>
+<pre class="literal-block">
+unsigned int AnimateImages( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="appendimages">
+<h1><a class="toc-backref" href="#id70">AppendImages</a></h1>
+<div class="section" id="id12">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AppendImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int stack,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id13">
+<h2>Description</h2>
+<p>The AppendImages() method takes a set of images and appends them to each
+other top-to-bottom if the stack parameter is true, otherwise left-to-right.</p>
+<p>The format of the AppendImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AppendImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int stack,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image sequence.</dd>
+<dt>stack:</dt>
+<dd>A value other than 0 stacks the images top-to-bottom.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="catchimageexception">
+<h1><a class="toc-backref" href="#id71">CatchImageException</a></h1>
+<div class="section" id="id14">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> CatchImageException( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id15">
+<h2>Description</h2>
+<p>CatchImageException() returns if no exceptions are found in the image
+sequence, otherwise it determines the most severe exception and reports
+it as a warning or error depending on the severity.</p>
+<p>The format of the CatchImageException method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> CatchImageException( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>An image sequence.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="clippathimage">
+<h1><a class="toc-backref" href="#id72">ClipPathImage</a></h1>
+<div class="section" id="id16">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int ClipPathImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *pathname,
+ const unsigned int inside );
+</pre>
+</div>
+<div class="section" id="id17">
+<h2>Description</h2>
+<p>ClipPathImage() sets the image clip mask based any clipping path information
+if it exists.</p>
+<p>The format of the ClipPathImage method is:</p>
+<pre class="literal-block">
+unsigned int ClipPathImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *pathname,
+ const unsigned int inside );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>pathname:</dt>
+<dd>name of clipping path resource. If name is preceded by #, use
+clipping path numbered by name.</dd>
+<dt>inside:</dt>
+<dd>if non-zero, later operations take effect inside clipping path.
+Otherwise later operations take effect outside clipping path.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="cloneimage">
+<h1><a class="toc-backref" href="#id73">CloneImage</a></h1>
+<div class="section" id="id18">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CloneImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns,
+ const unsigned long rows, const unsigned int orphan,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id19">
+<h2>Description</h2>
+<p>CloneImage() copies an image and returns the copy as a new image object.
+If the specified columns and rows is 0, an exact copy of the image is
+returned, otherwise the pixel data is undefined and must be initialized
+with the SetImagePixels() and SyncImagePixels() methods. On failure,
+a NULL image is returned and exception describes the reason for the
+failure.</p>
+<p>The format of the CloneImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CloneImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns,
+ const unsigned long rows, const unsigned int orphan,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the cloned image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the cloned image.</dd>
+<dt>orphan:</dt>
+<dd>With a value other than 0, the cloned image is an orphan. An
+orphan is a stand-alone image that is not assocated with an image list.
+In effect, the next and previous members of the cloned image is set to
+NULL.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="cloneimageinfo">
+<h1><a class="toc-backref" href="#id74">CloneImageInfo</a></h1>
+<div class="section" id="id20">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *CloneImageInfo( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info );
+</pre>
+</div>
+<div class="section" id="id21">
+<h2>Description</h2>
+<p>CloneImageInfo() makes a copy of the given image info structure. If
+NULL is specified, a new image info structure is created initialized to
+default values.</p>
+<p>The format of the CloneImageInfo method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *CloneImageInfo( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyimage">
+<h1><a class="toc-backref" href="#id75">DestroyImage</a></h1>
+<div class="section" id="id22">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id23">
+<h2>Description</h2>
+<p>DestroyImage() dereferences an image, deallocating memory associated with
+the image if the reference count becomes zero.</p>
+<p>The format of the DestroyImage method is:</p>
+<pre class="literal-block">
+void DestroyImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyimageinfo">
+<h1><a class="toc-backref" href="#id76">DestroyImageInfo</a></h1>
+<div class="section" id="id24">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyImageInfo( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info );
+</pre>
+</div>
+<div class="section" id="id25">
+<h2>Description</h2>
+<p>DestroyImageInfo() deallocates memory associated with a ImageInfo
+structure.</p>
+<p>The format of the DestroyImageInfo method is:</p>
+<pre class="literal-block">
+void DestroyImageInfo( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="displayimages">
+<h1><a class="toc-backref" href="#id77">DisplayImages</a></h1>
+<div class="section" id="id26">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DisplayImages( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id27">
+<h2>Description</h2>
+<p>DisplayImages() displays an image sequence to any X window screen. It
+returns a value other than 0 if successful. Check the exception member
+of image to determine the reason for any failure.</p>
+<p>The format of the DisplayImages method is:</p>
+<pre class="literal-block">
+unsigned int DisplayImages( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimageclipmask">
+<h1><a class="toc-backref" href="#id78">GetImageClipMask</a></h1>
+<div class="section" id="id28">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetImageClipMask( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id29">
+<h2>Description</h2>
+<p>GetImageClipMask returns a reference-counted copy of the current image
+clip mask. This copy must be deallocated using DestroyImage() once it is
+no longer needed. If the image does not have an associated clip mask,
+then NULL is returned. Use SetImageClipMask() to add a clip mask to an
+image, or remove a clip mask.</p>
+<p>If a component of the clip mask is set to TransparentOpacity (maximum
+value) then the corresponding image pixel component will not be updated
+when SyncImagePixels() is applied. The clip mask may be used to constrain
+the results of an image processing operation to a region of the image.
+Regions outside those allowed by the clip mask may be processed, but only
+pixel quantums allowed by the clip mask will actually be updated.</p>
+<p>The clip mask protects the DirectClass pixels and PseudoClass pixel indexes
+from modification. The clip mask does <em>not</em> protect the image colormap since
+the image colormap is globally shared by all pixels in a PseudoClass image.</p>
+<p>The format of the GetImageClipMask method is</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetImageClipMask( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A descripton of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Reason for failure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimageexception">
+<h1><a class="toc-backref" href="#id79">GetImageException</a></h1>
+<div class="section" id="id30">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void GetImageException( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id31">
+<h2>Description</h2>
+<p>GetImageException() traverses an image sequence and returns any
+error more severe than noted by the exception parameter.</p>
+<p>The format of the GetImageException method is:</p>
+<pre class="literal-block">
+void GetImageException( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Specifies a pointer to a list of one or more images.</dd>
+<dt>exception:</dt>
+<dd>return the highest severity exception.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagegeometry">
+<h1><a class="toc-backref" href="#id80">GetImageGeometry</a></h1>
+<div class="section" id="id32">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+int GetImageGeometry( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *geometry,
+ const unsigned int size_to_fit, <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *region_info );
+</pre>
+</div>
+<div class="section" id="id33">
+<h2>Description</h2>
+<p>GetImageGeometry() returns a region as defined by the geometry string with
+respect to the image and its gravity.</p>
+<p>The format of the GetImageGeometry method is:</p>
+<pre class="literal-block">
+int GetImageGeometry( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *geometry,
+ const unsigned int size_to_fit, <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *region_info );
+</pre>
+<dl class="docutils">
+<dt>flags:</dt>
+<dd>Method GetImageGeometry returns a bitmask that indicates
+which of the four values were located in the geometry string.</dd>
+<dt>geometry:</dt>
+<dd>The geometry (e.g. 100x100+10+10).</dd>
+<dt>size_to_fit:</dt>
+<dd>A value other than 0 means to scale the region so it
+fits within the specified width and height.</dd>
+<dt>region_info:</dt>
+<dd>The region as defined by the geometry string with
+respect to the image and its gravity.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimageinfo">
+<h1><a class="toc-backref" href="#id81">GetImageInfo</a></h1>
+<div class="section" id="id34">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void GetImageInfo( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info );
+</pre>
+</div>
+<div class="section" id="id35">
+<h2>Description</h2>
+<p>GetImageInfo() initializes image_info to default values.</p>
+<p>The format of the GetImageInfo method is:</p>
+<pre class="literal-block">
+void GetImageInfo( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="istaintimage">
+<h1><a class="toc-backref" href="#id82">IsTaintImage</a></h1>
+<div class="section" id="id36">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int IsTaintImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id37">
+<h2>Description</h2>
+<p>IsTaintImage() returns a value other than 0 if any pixel in the image
+has been altered since it was first constituted.</p>
+<p>The format of the IsTaintImage method is:</p>
+<pre class="literal-block">
+unsigned int IsTaintImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="modifyimage">
+<h1><a class="toc-backref" href="#id83">ModifyImage</a></h1>
+<div class="section" id="id38">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+ModifyImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id39">
+<h2>Description</h2>
+<p>ModifyImage() ensures that there is only a single reference to the image
+to be modified, updating the provided image pointer to point to a clone of
+the original image if necessary.</p>
+<p>The format of the ModifyImage method is:</p>
+<pre class="literal-block">
+ModifyImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="referenceimage">
+<h1><a class="toc-backref" href="#id84">ReferenceImage</a></h1>
+<div class="section" id="id40">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ReferenceImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id41">
+<h2>Description</h2>
+<p>ReferenceImage() increments the reference count associated with an image
+returning a pointer to the image.</p>
+<p>The format of the ReferenceImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ReferenceImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="removedefinitions">
+<h1><a class="toc-backref" href="#id85">RemoveDefinitions</a></h1>
+<div class="section" id="id42">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void RemoveDefinitions( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *options );
+</pre>
+</div>
+<div class="section" id="id43">
+<h2>Description</h2>
+<p>RemoveDefinitions() removes definitions from the current map of definitions
+in ImageInfo. Definitions may be used by coders/decoders that read and
+write images. RemoveDefinitions() returns true only if the specified keys
+are present in the map and are actually removed.</p>
+<p>The format of the RemoveDefinitions method is:</p>
+<pre class="literal-block">
+void RemoveDefinitions( <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const char *options );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>keys:</dt>
+<dd>List of keys to remove from the definitions map. The
+format of the string is &quot;key1,key2,...&quot;. A special key, '*', removes
+all the key/value pairs in the definitions map. This key always
+succeeds.</dd>
+<dt>exception:</dt>
+<dd>Errors result in updates to this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="resetimagepage">
+<h1><a class="toc-backref" href="#id86">ResetImagePage</a></h1>
+<div class="section" id="id44">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ResetImagePage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *page );
+</pre>
+</div>
+<div class="section" id="id45">
+<h2>Description</h2>
+<p>ResetImagePage adjusts the current page canvas and position based on a
+relative page specification.</p>
+<p>The format of the ResetImagePage method is:</p>
+<pre class="literal-block">
+MagickPassFail ResetImagePage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *page );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>page:</dt>
+<dd>Relative page offset adjustment</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimageex">
+<h1><a class="toc-backref" href="#id87">SetImageEx</a></h1>
+<div class="section" id="id46">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void SetImageEx( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> opacity, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id47">
+<h2>Description</h2>
+<p>SetImageEx() sets the red, green, and blue components of each pixel to
+the image background color and the opacity component to the specified
+level of transparency. The background color is defined by the
+background_color member of the image.</p>
+<p>The format of the SetImageEx method is:</p>
+<pre class="literal-block">
+void SetImageEx( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> opacity, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>opacity:</dt>
+<dd>Set each pixel to this level of transparency.</dd>
+<dt>exception:</dt>
+<dd>Report any exception here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimage">
+<h1><a class="toc-backref" href="#id88">SetImage</a></h1>
+<div class="section" id="id48">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void SetImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> opacity );
+</pre>
+</div>
+<div class="section" id="id49">
+<h2>Description</h2>
+<p>SetImage() sets the red, green, and blue components of each pixel to
+the image background color and the opacity component to the specified
+level of transparency. The background color is defined by the
+background_color member of the image. Any exception is reported to
+the image.</p>
+<p>The format of the SetImage method is:</p>
+<pre class="literal-block">
+void SetImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> opacity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>opacity:</dt>
+<dd>Set each pixel to this level of transparency.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimagecolor">
+<h1><a class="toc-backref" href="#id89">SetImageColor</a></h1>
+<div class="section" id="id50">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail SetImageColor( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *pixel );
+</pre>
+</div>
+<div class="section" id="id51">
+<h2>Description</h2>
+<p>SetImageColor() sets the red, green, blue and opacity components of each
+pixel to those from a specified pixel value.</p>
+<p>The format of the SetImageColor method is:</p>
+<pre class="literal-block">
+MagickPassFail SetImageColor( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *pixel );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>pixel:</dt>
+<dd>Set each pixel in the image to this pixel's color and transparency.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimagecolorregion">
+<h1><a class="toc-backref" href="#id90">SetImageColorRegion</a></h1>
+<div class="section" id="id52">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail SetImageColorRegion( <a class="reference external" href="../api/types.html#image">Image</a> *image, long x, long y, unsigned long width,
+ unsigned long height, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *pixel );
+</pre>
+</div>
+<div class="section" id="id53">
+<h2>Description</h2>
+<p>SetImageColorRegion() sets the red, green, blue and opacity components
+of each pixel in the specified region to those from a specified pixel
+value. Please note that it is assumed that the pixel value is in
+the same colorspace as the image.</p>
+<p>The format of the SetImageColorRegion method is:</p>
+<pre class="literal-block">
+MagickPassFail SetImageColorRegion( <a class="reference external" href="../api/types.html#image">Image</a> *image, long x, long y, unsigned long width,
+ unsigned long height, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *pixel );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>pixel:</dt>
+<dd>Set each pixel in the image to this pixel's color and transparency.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimageclipmask">
+<h1><a class="toc-backref" href="#id91">SetImageClipMask</a></h1>
+<div class="section" id="id54">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int SetImageClipMask( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *clip_mask );
+</pre>
+</div>
+<div class="section" id="id55">
+<h2>Description</h2>
+<p>SetImageClipMask() associates a clip mask with the image. The clip mask
+must be the same dimensions as the image.</p>
+<p>If a component of the clip mask is set to TransparentOpacity (maximum
+value) then the corresponding image pixel component will not be updated
+when SyncImagePixels() is applied. The clip mask may be used to constrain
+the results of an image processing operation to a region of the image.
+Regions outside those allowed by the clip mask may be processed, but only
+pixel quantums allowed by the clip mask will actually be updated.</p>
+<p>The clip mask protects the DirectClass pixels and PseudoClass pixel indexes
+from modification. The clip mask does <em>not</em> protect the image colormap since
+the image colormap is globally shared by all pixels in a PseudoClass image.</p>
+<p>The format of the SetImageClipMask method is:</p>
+<pre class="literal-block">
+unsigned int SetImageClipMask( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *clip_mask );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>clip_mask:</dt>
+<dd>The image clip mask.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimagedepth">
+<h1><a class="toc-backref" href="#id92">SetImageDepth</a></h1>
+<div class="section" id="id56">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int SetImageDepth( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long depth );
+</pre>
+</div>
+<div class="section" id="id57">
+<h2>Description</h2>
+<p>SetImageDepth() translates the pixel quantums across all of the channels
+so that if they are later divided to fit within the specified bit
+depth, that no additional information is lost (i.e. no remainder will
+result from the division). Note that any subsequent image processing is
+likely to increase the effective depth of the image channels. A non-zero
+value is returned if the operation is successful. Check the exception
+member of image to determine the cause for any failure.</p>
+<p>The format of the SetImageDepth method is:</p>
+<pre class="literal-block">
+unsigned int SetImageDepth( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long depth );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image to update.</dd>
+<dt>depth:</dt>
+<dd>Desired image depth (range 1 to QuantumDepth)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimageopacity">
+<h1><a class="toc-backref" href="#id93">SetImageOpacity</a></h1>
+<div class="section" id="id58">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void SetImageOpacity( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int opacity );
+</pre>
+</div>
+<div class="section" id="id59">
+<h2>Description</h2>
+<p>SetImageOpacity() attenuates the opacity channel of an image. If the
+image pixels are opaque, they are set to the specified opacity level.
+Otherwise, the pixel opacity values are blended with the supplied
+transparency value.</p>
+<p>The format of the SetImageOpacity method is:</p>
+<pre class="literal-block">
+void SetImageOpacity( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned int opacity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>opacity:</dt>
+<dd>The level of transparency: 0 is fully opaque and MaxRGB is
+fully transparent.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimagetype">
+<h1><a class="toc-backref" href="#id94">SetImageType</a></h1>
+<div class="section" id="id60">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+( void )SetImageType( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#imagetype">ImageType</a> image_type );
+</pre>
+</div>
+<div class="section" id="id61">
+<h2>Description</h2>
+<p>(void) SetImageType() sets the type of image. Choose from these types:</p>
+<p>BilevelType, GrayscaleType, GrayscaleMatteType, PaletteType,
+PaletteMatteType, TrueColorType, TrueColorMatteType,
+ColorSeparationType, ColorSeparationMatteType, OptimizeType</p>
+<p>The format of the (void) SetImageType method is:</p>
+<pre class="literal-block">
+( void )SetImageType( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#imagetype">ImageType</a> image_type );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>image_type:</dt>
+<dd>Image type.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="stripimage">
+<h1><a class="toc-backref" href="#id95">StripImage</a></h1>
+<div class="section" id="id62">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail StripImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id63">
+<h2>Description</h2>
+<p>StripImage removes all profiles and text attributes from the image.</p>
+<p>The format of the StripImage method is:</p>
+<pre class="literal-block">
+MagickPassFail StripImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/import.html b/www/api/import.html
new file mode 100644
index 0000000..efaf8f7
--- /dev/null
+++ b/www/api/import.html
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>import</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="import">
+<h1 class="title">import</h1>
+<h2 class="subtitle" id="import-image-pixels-from-common-representations">Import image pixels from common representations</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#importimagepixelarea" id="id5">ImportImagePixelArea</a></li>
+<li><a class="reference internal" href="#importviewpixelarea" id="id6">ImportViewPixelArea</a></li>
+<li><a class="reference internal" href="#importpixelareaoptionsinit" id="id7">ImportPixelAreaOptionsInit</a></li>
+</ul>
+</div>
+<div class="section" id="importimagepixelarea">
+<h1><a class="toc-backref" href="#id5">ImportImagePixelArea</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ImportImagePixelArea( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ const unsigned int quantum_size,
+ const unsigned char *source,
+ const ImportPixelAreaOptions *options,
+ ImportPixelAreaInfo *import_info );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>ImportImagePixelArea() transfers one or more pixel components from a user
+supplied buffer into the default image pixel cache view. By default,
+values are read in network (big-endian) byte/bit order. By setting the
+'endian' member of ExportPixelAreaOptions, 16, 32 and 64-bit values may
+be output as little (LSBEndian), big (MSBEndian), or host native
+(NativeEndian) endian values. This function is quite powerful in that
+besides common native CPU type sizes, it can support any integer bit
+depth from 1 to 32 (e.g. 13), 64-bits, as well as 32 and 64-bit float.</p>
+<p>MagickPass is returned if the pixels are successfully transferred,
+otherwise MagickFail.</p>
+<p>The format of the ImportImagePixelArea method is:</p>
+<pre class="literal-block">
+MagickPassFail ImportImagePixelArea( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ const unsigned int quantum_size,
+ const unsigned char *source,
+ const ImportPixelAreaOptions *options,
+ ImportPixelAreaInfo *import_info );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method PushImagePixels returns MagickPass if the pixels are
+successfully transferred, otherwise MagickFail.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>quantum_type:</dt>
+<dd>Declare which pixel components to transfer (AlphaQuantum,
+BlackQuantum, BlueQuantum, CMYKAQuantum, CMYKQuantum, CyanQuantum,
+GrayAlphaQuantum, GrayQuantum, GreenQuantum, IndexAlphaQuantum,
+IndexQuantum, MagentaQuantum, RGBAQuantum, RGBQuantum,
+RedQuantum, YellowQuantum)</dd>
+<dt>quantum_size:</dt>
+<dd>Bits per quantum sample (range 1-32, and 64).</dd>
+<dt>source:</dt>
+<dd>The pixel components are transferred from this buffer.</dd>
+<dt>options:</dt>
+<dd>Additional options specific to quantum_type (may be NULL).</dd>
+<dt>import_info :</dt>
+<dd>Populated with information regarding the pixels
+imported (may be NULL)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="importviewpixelarea">
+<h1><a class="toc-backref" href="#id6">ImportViewPixelArea</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ImportViewPixelArea( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ const unsigned int quantum_size,
+ const unsigned char *source,
+ const ImportPixelAreaOptions *options,
+ ImportPixelAreaInfo *import_info );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>ImportViewPixelArea() transfers one or more pixel components from a user
+supplied buffer into the specified image pixel cache view of an image. By
+default, values are read in network (big-endian) byte/bit order. By
+setting the 'endian' member of ExportPixelAreaOptions, 16, 32 and 64-bit
+values may be output as little (LSBEndian), big (MSBEndian), or host
+native (NativeEndian) endian values. This function is quite powerful in
+that besides common native CPU type sizes, it can support any integer bit
+depth from 1 to 32 (e.g. 13), 64-bits, as well as 32 and 64-bit float.</p>
+<p>MagickPass is returned if the pixels are successfully transferred,
+otherwise MagickFail.</p>
+<p>The format of the ImportViewPixelArea method is:</p>
+<pre class="literal-block">
+MagickPassFail ImportViewPixelArea( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const <a class="reference external" href="../api/types.html#quantumtype">QuantumType</a> quantum_type,
+ const unsigned int quantum_size,
+ const unsigned char *source,
+ const ImportPixelAreaOptions *options,
+ ImportPixelAreaInfo *import_info );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method PushImagePixels returns MagickPass if the pixels are
+successfully transferred, otherwise MagickFail.</dd>
+<dt>view:</dt>
+<dd>The pixel view to import pixels into.</dd>
+<dt>quantum_type:</dt>
+<dd>Declare which pixel components to transfer (AlphaQuantum,
+BlackQuantum, BlueQuantum, CMYKAQuantum, CMYKQuantum, CyanQuantum,
+GrayAlphaQuantum, GrayQuantum, GreenQuantum, IndexAlphaQuantum,
+IndexQuantum, MagentaQuantum, RGBAQuantum, RGBQuantum,
+RedQuantum, YellowQuantum)</dd>
+<dt>quantum_size:</dt>
+<dd>Bits per quantum sample (range 1-32, and 64).</dd>
+<dt>source:</dt>
+<dd>The pixel components are transferred from this buffer.</dd>
+<dt>options:</dt>
+<dd>Additional options specific to quantum_type (may be NULL).</dd>
+<dt>import_info :</dt>
+<dd>Populated with information regarding the pixels
+imported (may be NULL)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="importpixelareaoptionsinit">
+<h1><a class="toc-backref" href="#id7">ImportPixelAreaOptionsInit</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void ImportPixelAreaOptionsInit( ImportPixelAreaOptions *options );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>ImportPixelAreaOptionsInit() initializes the options structure which is
+optionally passed to ImportPixelArea()</p>
+<p>The format of the ImportPixelAreaOptionsInit method is:</p>
+<pre class="literal-block">
+void ImportPixelAreaOptionsInit( ImportPixelAreaOptions *options );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>options:</dt>
+<dd>Options structure to initialize.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/list.html b/www/api/list.html
new file mode 100644
index 0000000..f390b75
--- /dev/null
+++ b/www/api/list.html
@@ -0,0 +1,547 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>list</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="list">
+<h1 class="title">list</h1>
+<h2 class="subtitle" id="image-list-support">Image list support</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#appendimagetolist" id="id41">AppendImageToList</a></li>
+<li><a class="reference internal" href="#cloneimagelist" id="id42">CloneImageList</a></li>
+<li><a class="reference internal" href="#deleteimagefromlist" id="id43">DeleteImageFromList</a></li>
+<li><a class="reference internal" href="#destroyimagelist" id="id44">DestroyImageList</a></li>
+<li><a class="reference internal" href="#getfirstimageinlist" id="id45">GetFirstImageInList</a></li>
+<li><a class="reference internal" href="#getimagefromlist" id="id46">GetImageFromList</a></li>
+<li><a class="reference internal" href="#getimageindexinlist" id="id47">GetImageIndexInList</a></li>
+<li><a class="reference internal" href="#getimagelistlength" id="id48">GetImageListLength</a></li>
+<li><a class="reference internal" href="#getlastimageinlist" id="id49">GetLastImageInList</a></li>
+<li><a class="reference internal" href="#getnextimageinlist" id="id50">GetNextImageInList</a></li>
+<li><a class="reference internal" href="#getpreviousimageinlist" id="id51">GetPreviousImageInList</a></li>
+<li><a class="reference internal" href="#imagelisttoarray" id="id52">ImageListToArray</a></li>
+<li><a class="reference internal" href="#insertimageinlist" id="id53">InsertImageInList</a></li>
+<li><a class="reference internal" href="#newimagelist" id="id54">NewImageList</a></li>
+<li><a class="reference internal" href="#prependimagetolist" id="id55">PrependImageToList</a></li>
+<li><a class="reference internal" href="#removefirstimagefromlist" id="id56">RemoveFirstImageFromList</a></li>
+<li><a class="reference internal" href="#removelastimagefromlist" id="id57">RemoveLastImageFromList</a></li>
+<li><a class="reference internal" href="#replaceimageinlist" id="id58">ReplaceImageInList</a></li>
+<li><a class="reference internal" href="#reverseimagelist" id="id59">ReverseImageList</a></li>
+<li><a class="reference internal" href="#spliceimageintolist" id="id60">SpliceImageIntoList</a></li>
+<li><a class="reference internal" href="#splitimagelist" id="id61">SplitImageList</a></li>
+</ul>
+</div>
+<div class="section" id="appendimagetolist">
+<h1><a class="toc-backref" href="#id41">AppendImageToList</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+AppendImageToList( <a class="reference external" href="../api/types.html#image">Image</a> ** images, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AppendImageToList() appends an image to the end of the list.</p>
+<p>The format of the AppendImageToList method is:</p>
+<pre class="literal-block">
+AppendImageToList( <a class="reference external" href="../api/types.html#image">Image</a> ** images, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="cloneimagelist">
+<h1><a class="toc-backref" href="#id42">CloneImageList</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CloneImageList( const <a class="reference external" href="../api/types.html#image">Image</a> *images, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>CloneImageList() returns a duplicate of the image list.</p>
+<p>The format of the CloneImageList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CloneImageList( const <a class="reference external" href="../api/types.html#image">Image</a> *images, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="deleteimagefromlist">
+<h1><a class="toc-backref" href="#id43">DeleteImageFromList</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+DeleteImageFromList( <a class="reference external" href="../api/types.html#image">Image</a> ** images );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DeleteImageFromList() deletes an image from the list.</p>
+<p>The format of the DeleteImageFromList method is:</p>
+<pre class="literal-block">
+DeleteImageFromList( <a class="reference external" href="../api/types.html#image">Image</a> ** images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyimagelist">
+<h1><a class="toc-backref" href="#id44">DestroyImageList</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyImageList( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>DestroyImageList() destroys an image list.</p>
+<p>The format of the DestroyImageList method is:</p>
+<pre class="literal-block">
+void DestroyImageList( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image sequence.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getfirstimageinlist">
+<h1><a class="toc-backref" href="#id45">GetFirstImageInList</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetFirstImageInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>GetFirstImageInList() returns a pointer to the first image in the list</p>
+<p>The format of the GetFirstImageInList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetFirstImageInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagefromlist">
+<h1><a class="toc-backref" href="#id46">GetImageFromList</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetImageFromList( const <a class="reference external" href="../api/types.html#image">Image</a> *images, const long offset );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>GetImageFromList() returns an image at the specified offset from the list.</p>
+<p>The format of the GetImageFromList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetImageFromList( const <a class="reference external" href="../api/types.html#image">Image</a> *images, const long offset );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>offset:</dt>
+<dd>The position within the list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimageindexinlist">
+<h1><a class="toc-backref" href="#id47">GetImageIndexInList</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+long GetImageIndexInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>GetImageIndexInList() returns the offset in the list of the specified image.</p>
+<p>The format of the GetImageIndexInList method is:</p>
+<pre class="literal-block">
+long GetImageIndexInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagelistlength">
+<h1><a class="toc-backref" href="#id48">GetImageListLength</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long GetImageListLength( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>GetImageListLength() returns the length of the list (the number of images in
+the list).</p>
+<p>The format of the GetImageListLength method is:</p>
+<pre class="literal-block">
+unsigned long GetImageListLength( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getlastimageinlist">
+<h1><a class="toc-backref" href="#id49">GetLastImageInList</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetLastImageInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>GetLastImageInList() returns a pointer to the last image in the list</p>
+<p>The format of the GetLastImageInList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetLastImageInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getnextimageinlist">
+<h1><a class="toc-backref" href="#id50">GetNextImageInList</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetNextImageInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>GetNextImageInList() returns the next image in the list.</p>
+<p>The format of the GetNextImageInList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetNextImageInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getpreviousimageinlist">
+<h1><a class="toc-backref" href="#id51">GetPreviousImageInList</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetPreviousImageInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>GetPreviousImageInList() returns the previous image in the list.</p>
+<p>The format of the GetPreviousImageInList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetPreviousImageInList( const <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="imagelisttoarray">
+<h1><a class="toc-backref" href="#id52">ImageListToArray</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> ** ImageListToArray( const <a class="reference external" href="../api/types.html#image">Image</a> *images, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>ImageListToArray() is a convenience method that converts an image list to
+a sequential array. For example,</p>
+<p>group = ImageListToArray(images, exception);
+for (i = 0; i &lt; n; i++)
+puts(group[i]-&gt;filename);</p>
+<p>The format of the ImageListToArray method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> ** ImageListToArray( const <a class="reference external" href="../api/types.html#image">Image</a> *images, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image list.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="insertimageinlist">
+<h1><a class="toc-backref" href="#id53">InsertImageInList</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+InsertImageInList( <a class="reference external" href="../api/types.html#image">Image</a> ** images, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>InsertImageInList() inserts an image in the list.</p>
+<p>The format of the InsertImageInList method is:</p>
+<pre class="literal-block">
+InsertImageInList( <a class="reference external" href="../api/types.html#image">Image</a> ** images, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="newimagelist">
+<h1><a class="toc-backref" href="#id54">NewImageList</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *NewImageList( void );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>NewImageList() creates an empty image list.</p>
+<p>The format of the NewImageList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *NewImageList( void );
+</pre>
+</div>
+</div>
+<div class="section" id="prependimagetolist">
+<h1><a class="toc-backref" href="#id55">PrependImageToList</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+PrependImageToList( <a class="reference external" href="../api/types.html#image">Image</a> *images, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>PrependImageToList() prepends the image to the beginning of the list.</p>
+<p>The format of the PrependImageToList method is:</p>
+<pre class="literal-block">
+PrependImageToList( <a class="reference external" href="../api/types.html#image">Image</a> *images, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="removefirstimagefromlist">
+<h1><a class="toc-backref" href="#id56">RemoveFirstImageFromList</a></h1>
+<div class="section" id="id29">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *RemoveFirstImageFromList( <a class="reference external" href="../api/types.html#image">Image</a> ** images );
+</pre>
+</div>
+<div class="section" id="id30">
+<h2>Description</h2>
+<p>RemoveFirstImageFromList() removes an image from the beginning of the list.</p>
+<p>The format of the RemoveFirstImageFromList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *RemoveFirstImageFromList( <a class="reference external" href="../api/types.html#image">Image</a> ** images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="removelastimagefromlist">
+<h1><a class="toc-backref" href="#id57">RemoveLastImageFromList</a></h1>
+<div class="section" id="id31">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *RemoveLastImageFromList( <a class="reference external" href="../api/types.html#image">Image</a> ** images );
+</pre>
+</div>
+<div class="section" id="id32">
+<h2>Description</h2>
+<p>RemoveLastImageFromList() removes the last image from the list.</p>
+<p>The format of the RemoveLastImageFromList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *RemoveLastImageFromList( <a class="reference external" href="../api/types.html#image">Image</a> ** images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="replaceimageinlist">
+<h1><a class="toc-backref" href="#id58">ReplaceImageInList</a></h1>
+<div class="section" id="id33">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+ReplaceImageInList( <a class="reference external" href="../api/types.html#image">Image</a> ** images, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id34">
+<h2>Description</h2>
+<p>ReplaceImageInList() replaces an image in the list.</p>
+<p>The format of the ReplaceImageInList method is:</p>
+<pre class="literal-block">
+ReplaceImageInList( <a class="reference external" href="../api/types.html#image">Image</a> ** images, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="reverseimagelist">
+<h1><a class="toc-backref" href="#id59">ReverseImageList</a></h1>
+<div class="section" id="id35">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+ReverseImageList( const <a class="reference external" href="../api/types.html#image">Image</a> ** images );
+</pre>
+</div>
+<div class="section" id="id36">
+<h2>Description</h2>
+<p>ReverseImageList() reverses the image list.</p>
+<p>The format of the ReverseImageList method is:</p>
+<pre class="literal-block">
+ReverseImageList( const <a class="reference external" href="../api/types.html#image">Image</a> ** images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="spliceimageintolist">
+<h1><a class="toc-backref" href="#id60">SpliceImageIntoList</a></h1>
+<div class="section" id="id37">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+SpliceImageIntoList( <a class="reference external" href="../api/types.html#image">Image</a> ** images, const unsigned long length, <a class="reference external" href="../api/types.html#image">Image</a> *splice );
+</pre>
+</div>
+<div class="section" id="id38">
+<h2>Description</h2>
+<p>SpliceImageIntoList() removes 'length' images from the list and replaces
+them with the specified splice.</p>
+<p>The format of the SpliceImageIntoList method is:</p>
+<pre class="literal-block">
+SpliceImageIntoList( <a class="reference external" href="../api/types.html#image">Image</a> ** images, const unsigned long length, <a class="reference external" href="../api/types.html#image">Image</a> *splice );
+</pre>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+<dt>length:</dt>
+<dd>The length of the image list to remove.</dd>
+<dt>splice:</dt>
+<dd>Replace the removed image list with this list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="splitimagelist">
+<h1><a class="toc-backref" href="#id61">SplitImageList</a></h1>
+<div class="section" id="id39">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SplitImageList( <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id40">
+<h2>Description</h2>
+<p>SplitImageList() splits an image into two lists.</p>
+<p>The format of the SplitImageList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SplitImageList( <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>The image list.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/magick.html b/www/api/magick.html
new file mode 100644
index 0000000..4e5534b
--- /dev/null
+++ b/www/api/magick.html
@@ -0,0 +1,435 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>magick</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick">
+<h1 class="title">magick</h1>
+<h2 class="subtitle" id="image-format-support-interfaces">Image format support interfaces</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#destroymagick" id="id29">DestroyMagick</a></li>
+<li><a class="reference internal" href="#destroymagickinfo" id="id30">DestroyMagickInfo</a></li>
+<li><a class="reference internal" href="#destroymagickinfolist" id="id31">DestroyMagickInfoList</a></li>
+<li><a class="reference internal" href="#getimagemagick" id="id32">GetImageMagick</a></li>
+<li><a class="reference internal" href="#getmagickinfo" id="id33">GetMagickInfo</a></li>
+<li><a class="reference internal" href="#getmagickinfoarray" id="id34">GetMagickInfoArray</a></li>
+<li><a class="reference internal" href="#initializemagick" id="id35">InitializeMagick</a></li>
+<li><a class="reference internal" href="#ismagickconflict" id="id36">IsMagickConflict</a></li>
+<li><a class="reference internal" href="#listmagickinfo" id="id37">ListMagickInfo</a></li>
+<li><a class="reference internal" href="#listmodulemap" id="id38">ListModuleMap</a></li>
+<li><a class="reference internal" href="#magicktomime" id="id39">MagickToMime</a></li>
+<li><a class="reference internal" href="#registermagickinfo" id="id40">RegisterMagickInfo</a></li>
+<li><a class="reference internal" href="#panicdestroymagick" id="id41">PanicDestroyMagick</a></li>
+<li><a class="reference internal" href="#setmagickinfo" id="id42">SetMagickInfo</a></li>
+<li><a class="reference internal" href="#unregistermagickinfo" id="id43">UnregisterMagickInfo</a></li>
+</ul>
+</div>
+<div class="section" id="destroymagick">
+<h1><a class="toc-backref" href="#id29">DestroyMagick</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+DestroyMagick( void );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>DestroyMagick() destroys the GraphicsMagick environment, releasing all
+allocated semaphores, memory, and temporary files. This function
+should be invoked in the primary (original) thread of the application's
+process while shutting down, and only after any threads which might be
+using GraphicsMagick functions have terminated. Since GraphicsMagick
+uses threads internally via OpenMP, it is also necessary for any function
+calls into GraphicsMagick to have already returned so that OpenMP worker
+threads are quiesced and won't be accessing any semaphores or data
+structures which are destroyed by this function.</p>
+<p>The format of the DestroyMagick function is:</p>
+<pre class="literal-block">
+DestroyMagick( void );
+</pre>
+</div>
+</div>
+<div class="section" id="destroymagickinfo">
+<h1><a class="toc-backref" href="#id30">DestroyMagickInfo</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyMagickInfo( <a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> ** magick_info );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>DestroyMagickInfo() destroys a MagickInfo structure.</p>
+<p>The format of the DestroyMagickInfoList method is:</p>
+<pre class="literal-block">
+void DestroyMagickInfo( <a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> ** magick_info );
+</pre>
+</div>
+</div>
+<div class="section" id="destroymagickinfolist">
+<h1><a class="toc-backref" href="#id31">DestroyMagickInfoList</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyMagickInfoList( void );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DestroyMagickInfo() deallocates memory associated with the MagickInfo list.</p>
+<p>The format of the DestroyMagickInfoList method is:</p>
+<pre class="literal-block">
+void DestroyMagickInfoList( void );
+</pre>
+</div>
+</div>
+<div class="section" id="getimagemagick">
+<h1><a class="toc-backref" href="#id32">GetImageMagick</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *GetImageMagick( const unsigned char *magick, const size_t length );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>GetImageMagick() searches for an image format that matches the specified
+magick string. If one is found the name is returned otherwise NULL.</p>
+<p>The format of the GetImageMagick method is:</p>
+<pre class="literal-block">
+const char *GetImageMagick( const unsigned char *magick, const size_t length );
+</pre>
+<dl class="docutils">
+<dt>magick:</dt>
+<dd>The image format we are searching for.</dd>
+<dt>length:</dt>
+<dd>The length of the binary string.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getmagickinfo">
+<h1><a class="toc-backref" href="#id33">GetMagickInfo</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const <a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> *GetMagickInfo( const char *name, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>GetMagickInfo() returns a pointer MagickInfo structure that matches
+the specified name. If name is NULL, the head of the image format list
+is returned. It is not safe to traverse the list by using the previous and
+next pointers in the MagickInfo structure since the list contents or order
+may be altered while the list is being traversed. If the list must be
+traversed, access it via the GetMagickInfoArray function instead.</p>
+<p>If GraphicsMagick has not been initialized via InitializeMagick()
+then this function will not work.</p>
+<p>The format of the GetMagickInfo method is:</p>
+<pre class="literal-block">
+const <a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> *GetMagickInfo( const char *name, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>name:</dt>
+<dd>The image format we are looking for.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getmagickinfoarray">
+<h1><a class="toc-backref" href="#id34">GetMagickInfoArray</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> ** GetMagickInfoArray( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>GetMagickInfoArray() returns a sorted null-terminated array of MagickInfo
+pointers corresponding to the available format registrations. If necessarly
+all modules are loaded in order to return a complete list. This function
+should be used to access the entire list rather than GetMagickInfo since
+the list returned by GetMagickInfo may be re-ordered every time it is
+invoked. Once the returned array is no longer needed, the allocated array
+should be deallocated. Do not attempt to deallocate the MagickInfo
+structures based on pointers in the array!</p>
+<p>The format of the GetMagickList method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> ** GetMagickInfoArray( <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="initializemagick">
+<h1><a class="toc-backref" href="#id35">InitializeMagick</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+InitializeMagick( const char *path );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>InitializeMagick() initializes the GraphicsMagick environment.
+InitializeMagick() MUST be invoked by the using program before making
+use of GraphicsMagick functions or else the library will be unusable.</p>
+<p>This function should be invoked in the primary (original) thread of the
+application's process, and before starting any OpenMP threads, as part
+of program initialization.</p>
+<p>The format of the InitializeMagick function is:</p>
+<pre class="literal-block">
+InitializeMagick( const char *path );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>path:</dt>
+<dd>The execution path of the current GraphicsMagick client.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="ismagickconflict">
+<h1><a class="toc-backref" href="#id36">IsMagickConflict</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickBool IsMagickConflict( const char *magick );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>Method IsMagickConflict returns true if the image format conflicts with
+a logical drive (.e.g. X:).</p>
+<p>The format of the IsMagickConflict method is:</p>
+<pre class="literal-block">
+MagickBool IsMagickConflict( const char *magick );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method IsMagickConflict returns true if the image format
+conflicts with a logical drive.</dd>
+<dt>magick:</dt>
+<dd>Specifies the image format.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="listmagickinfo">
+<h1><a class="toc-backref" href="#id37">ListMagickInfo</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ListMagickInfo( FILE *file, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>ListMagickInfo() lists the image formats to a file.</p>
+<p>The format of the ListMagickInfo method is:</p>
+<pre class="literal-block">
+MagickPassFail ListMagickInfo( FILE *file, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows.</p>
+<dl class="docutils">
+<dt>file:</dt>
+<dd>A file handle.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="listmodulemap">
+<h1><a class="toc-backref" href="#id38">ListModuleMap</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ListModuleMap( FILE *file, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>Method ListModuleMap lists the module alias info to a file in the XML
+format used by modules.mgk. True is returned on success.</p>
+<p>The format of the ListModuleMap method is:</p>
+<pre class="literal-block">
+MagickPassFail ListModuleMap( FILE *file, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows.</p>
+<dl class="docutils">
+<dt>file:</dt>
+<dd>An pointer to a FILE.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicktomime">
+<h1><a class="toc-backref" href="#id39">MagickToMime</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *MagickToMime( const char *magick );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>Method MagickToMime returns the officially registered (or de facto) MIME
+media-type corresponding to a magick string. If there is no registered
+media-type, then the string &quot;image/x-magick&quot; (all lower case) is returned.
+The returned string must be deallocated by the user.</p>
+<p>The format of the MagickToMime method is:</p>
+<pre class="literal-block">
+char *MagickToMime( const char *magick );
+</pre>
+<p>A description of each parameter follows.</p>
+<dl class="docutils">
+<dt>magick:</dt>
+<dd>GraphicsMagick format specification &quot;magick&quot; tag.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="registermagickinfo">
+<h1><a class="toc-backref" href="#id40">RegisterMagickInfo</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> *RegisterMagickInfo( <a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> *magick_info );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>RegisterMagickInfo() adds attributes for a particular image format to the
+list of supported formats. The attributes include the image format name,
+a method to read and/or write the format, whether the format supports the
+saving of more than one frame to the same file or blob, whether the format
+supports native in-memory I/O, and a brief description of the format.</p>
+<p>The format of the RegisterMagickInfo method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> *RegisterMagickInfo( <a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> *magick_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>magick_info:</dt>
+<dd>The magick info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="panicdestroymagick">
+<h1><a class="toc-backref" href="#id41">PanicDestroyMagick</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void PanicDestroyMagick( void );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>PanicDestroyMagick() destroys only persistent allocations such as
+temporary files. Other allocations (e.g. semaphores and heap memory)
+remain allocated. This function is an alternative to DestroyMagick()
+which is async-safe so it may be invoked from signal handers, and
+may be invoked from thread context. No semaphores are taken and no
+additional heap memory is allocated by this function. The program
+must quit immediately after invoking this function.</p>
+<p>The format of the PanicDestroyMagick function is:</p>
+<pre class="literal-block">
+void PanicDestroyMagick( void );
+</pre>
+</div>
+</div>
+<div class="section" id="setmagickinfo">
+<h1><a class="toc-backref" href="#id42">SetMagickInfo</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> *SetMagickInfo( const char *name );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>Method SetMagickInfo allocates a MagickInfo structure and initializes the
+members to default values.</p>
+<p>The format of the SetMagickInfo method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#magickinfo">MagickInfo</a> *SetMagickInfo( const char *name );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>magick_info:</dt>
+<dd>Method SetMagickInfo returns the allocated and initialized
+MagickInfo structure.</dd>
+<dt>name:</dt>
+<dd>a character string that represents the image format associated
+with the MagickInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="unregistermagickinfo">
+<h1><a class="toc-backref" href="#id43">UnregisterMagickInfo</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int UnregisterMagickInfo( const char *name );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>Method UnregisterMagickInfo removes a name from the magick info list. It
+returns MagickFail if the name does not exist in the list otherwise
+MagickPass.</p>
+<p>The format of the UnregisterMagickInfo method is:</p>
+<pre class="literal-block">
+unsigned int UnregisterMagickInfo( const char *name );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method UnregisterMagickInfo returns False if the name does not
+exist in the list otherwise True.</dd>
+<dt>name:</dt>
+<dd>a character string that represents the image format we are
+looking for.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/memory.html b/www/api/memory.html
new file mode 100644
index 0000000..da567d5
--- /dev/null
+++ b/www/api/memory.html
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>memory</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="memory">
+<h1 class="title">memory</h1>
+<h2 class="subtitle" id="memory-allocation-deallocation-functions">Memory allocation/deallocation functions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#magickallocfunctions" id="id15">MagickAllocFunctions</a></li>
+<li><a class="reference internal" href="#magickmalloc" id="id16">MagickMalloc</a></li>
+<li><a class="reference internal" href="#magickmallocaligned" id="id17">MagickMallocAligned</a></li>
+<li><a class="reference internal" href="#magickmalloccleared" id="id18">MagickMallocCleared</a></li>
+<li><a class="reference internal" href="#magickclonememory" id="id19">MagickCloneMemory</a></li>
+<li><a class="reference internal" href="#magickrealloc" id="id20">MagickRealloc</a></li>
+<li><a class="reference internal" href="#magickfree" id="id21">MagickFree</a></li>
+<li><a class="reference internal" href="#magickfreealigned" id="id22">MagickFreeAligned</a></li>
+</ul>
+</div>
+<div class="section" id="magickallocfunctions">
+<h1><a class="toc-backref" href="#id15">MagickAllocFunctions</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickAllocFunctions( MagickFreeFunc free_func, MagickMallocFunc malloc_func,
+ MagickReallocFunc realloc_func );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>MagickAllocFunctions() provides a way for the user to supply a preferred
+free(), malloc(), and realloc() functions. Otherwise the default system
+versions are used. If an alternative allocator is to be used, this
+function should be invoked prior to invoking InitializeMagick().</p>
+<p>The format of the MagickAllocFunctions method is:</p>
+<pre class="literal-block">
+void MagickAllocFunctions( MagickFreeFunc free_func, MagickMallocFunc malloc_func,
+ MagickReallocFunc realloc_func );
+</pre>
+<dl class="docutils">
+<dt>free_func:</dt>
+<dd>Function to free memory.</dd>
+<dt>malloc_func:</dt>
+<dd>Function to allocate memory.</dd>
+<dt>realloc_func:</dt>
+<dd>Function to reallocate memory.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmalloc">
+<h1><a class="toc-backref" href="#id16">MagickMalloc</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *MagickMalloc( const size_t size );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>MagickMalloc() returns a pointer to a block of memory of at least size
+bytes suitably aligned for any use. NULL is returned if insufficient
+memory is available or the requested size is zero.</p>
+<p>The format of the MagickMalloc method is:</p>
+<pre class="literal-block">
+void *MagickMalloc( const size_t size );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>size:</dt>
+<dd>The size of the memory in bytes to allocate.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmallocaligned">
+<h1><a class="toc-backref" href="#id17">MagickMallocAligned</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *MagickMallocAligned( size_t alignment, const size_t size );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>MagickMallocAligned() allocates memory and returns a pointer to a
+block of memory capable of storing at least size bytes with the
+allocation's base address being an even multiple of alignment.
+The size of the buffer allocation is rounded up as required in
+order to consume a block of memory starting at least at the requested
+alignment and ending at at least the requested alignment.</p>
+<p>The requested alignment should be a power of 2 at least as large as
+sizeof a void pointer.</p>
+<p>NULL is returned if insufficient memory is available, the requested
+size is zero, or integer overflow was detected.</p>
+<p>This function is intended for allocating special-purpose buffers
+which benefit from specific alignment.</p>
+<p>The allocated memory should only be freed using MagickFreeAligned()
+and may not be reallocated.</p>
+<p>The format of the MagickMallocAligned method is:</p>
+<pre class="literal-block">
+void *MagickMallocAligned( size_t alignment, const size_t size );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>alignment:</dt>
+<dd>The alignment of the base and size of the allocated
+memory.</dd>
+<dt>size:</dt>
+<dd>The size of the memory in bytes to allocate.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmalloccleared">
+<h1><a class="toc-backref" href="#id18">MagickMallocCleared</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *MagickMallocCleared( const size_t size );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>MagickMallocCleared() returns a pointer to a block of memory of at least
+size bytes suitably aligned for any use. NULL is returned if insufficient
+memory is available or the requested size is zero. This version differs
+from MagickMalloc in that the allocated bytes are cleared to zero.</p>
+<p>The format of the MagickMallocCleared method is:</p>
+<pre class="literal-block">
+void *MagickMallocCleared( const size_t size );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>size:</dt>
+<dd>The size of the memory in bytes to allocate.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickclonememory">
+<h1><a class="toc-backref" href="#id19">MagickCloneMemory</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *MagickCloneMemory( void *destination, const void *source, const size_t size );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>MagickCloneMemory() copies size bytes from memory area source to the
+destination. Copying between objects that overlap will take place
+correctly. It returns destination.</p>
+<p>The format of the MagickCloneMemory method is:</p>
+<pre class="literal-block">
+void *MagickCloneMemory( void *destination, const void *source, const size_t size );
+</pre>
+<dl class="docutils">
+<dt>size:</dt>
+<dd>The size of the memory in bytes to allocate.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickrealloc">
+<h1><a class="toc-backref" href="#id20">MagickRealloc</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void *MagickRealloc( void *memory, const size_t size );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>MagickRealloc() changes the size of the memory and returns a pointer to
+the (possibly moved) block. The contents will be unchanged up to the
+lesser of the new and old sizes. If size is zero, then the memory is
+freed and a NULL value is returned. If the memory allocation fails, then
+the existing memory is freed, and a NULL value is returned.</p>
+<p>The format of the MagickRealloc method is:</p>
+<pre class="literal-block">
+void *MagickRealloc( void *memory, const size_t size );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>memory:</dt>
+<dd>A pointer to a memory allocation.</dd>
+<dt>size:</dt>
+<dd>The new size of the allocated memory.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickfree">
+<h1><a class="toc-backref" href="#id21">MagickFree</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickFree( void *memory );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>MagickFree() frees memory that has already been allocated by
+MagickMalloc() or other other other allocators directly compatible
+with the currently defined memory allocator (which defaults to the
+system malloc()). For convenience, a NULL argument is ignored.</p>
+<p>The format of the MagickFree method is:</p>
+<pre class="literal-block">
+void MagickFree( void *memory );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>memory:</dt>
+<dd>A pointer to a block of memory to free for reuse.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickfreealigned">
+<h1><a class="toc-backref" href="#id22">MagickFreeAligned</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickFreeAligned( void *memory );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>MagickFreeAligned() frees aligned memory that has previously been
+allocated via MagickMallocAligned(). For convenience, a NULL argument is
+ignored.</p>
+<p>This function exists in case the pointer allocated by
+MagickMallocAligned() can not be used directly with MagickFree().</p>
+<p>The format of the MagickFreeAligned method is:</p>
+<pre class="literal-block">
+void MagickFreeAligned( void *memory );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>memory:</dt>
+<dd>A pointer to a block of memory to free for reuse.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/monitor.html b/www/api/monitor.html
new file mode 100644
index 0000000..1b55312
--- /dev/null
+++ b/www/api/monitor.html
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>monitor</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="monitor">
+<h1 class="title">monitor</h1>
+<h2 class="subtitle" id="progress-monitor-support">Progress monitor support</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#magickmonitor" id="id5">MagickMonitor</a></li>
+<li><a class="reference internal" href="#magickmonitorformatted" id="id6">MagickMonitorFormatted</a></li>
+<li><a class="reference internal" href="#setmonitorhandler" id="id7">SetMonitorHandler</a></li>
+</ul>
+</div>
+<div class="section" id="magickmonitor">
+<h1><a class="toc-backref" href="#id5">MagickMonitor</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail MagickMonitor( const char *text, const magick_int64_t quantum,
+ const magick_uint64_t span, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>MagickMonitor() calls the monitor handler method with a text string that
+describes the task and a measure of completion. The method returns True
+on success otherwise False if an error is encountered, e.g. if there was a
+user interrupt.</p>
+<p>The format of the MagickMonitor method is:</p>
+<pre class="literal-block">
+MagickPassFail MagickMonitor( const char *text, const magick_int64_t quantum,
+ const magick_uint64_t span, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>text:</dt>
+<dd>Description of the task being performed.</dd>
+<dt>quantum:</dt>
+<dd>The position relative to the span parameter which represents
+how much progress has been made toward completing a task.</dd>
+<dt>span:</dt>
+<dd>The span relative to completing a task.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmonitorformatted">
+<h1><a class="toc-backref" href="#id6">MagickMonitorFormatted</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail MagickMonitorFormatted( const magick_int64_t quantum,
+ const magick_uint64_t span,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception, const char *format,
+ ... );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>MagickMonitorFormatted() calls the monitor handler method with a
+printf type format specification and variable argument list. Also
+passed are quantum and span values which provide a measure of
+completion. The method returns True on success otherwise False if
+an error is encountered, e.g. if there was a user interrupt.</p>
+<p>The format of the MagickMonitorFormatted method is:</p>
+<pre class="literal-block">
+MagickPassFail MagickMonitorFormatted( const magick_int64_t quantum,
+ const magick_uint64_t span,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception, const char *format,
+ ... );
+</pre>
+<dl class="docutils">
+<dt>quantum:</dt>
+<dd>The position relative to the span parameter which represents
+how much progress has been made toward completing a task.</dd>
+<dt>span:</dt>
+<dd>The span relative to completing a task.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+<dt>format:</dt>
+<dd>A string describing the format to use to write the remaining
+arguments.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setmonitorhandler">
+<h1><a class="toc-backref" href="#id7">SetMonitorHandler</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#monitorhandler">MonitorHandler</a> SetMonitorHandler( <a class="reference external" href="../api/types.html#monitorhandler">MonitorHandler</a> handler );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>SetMonitorHandler() sets the monitor handler to the specified method
+and returns the previous monitor handler.</p>
+<p>The format of the SetMonitorHandler method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#monitorhandler">MonitorHandler</a> SetMonitorHandler( <a class="reference external" href="../api/types.html#monitorhandler">MonitorHandler</a> handler );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>handler:</dt>
+<dd>Specifies a pointer to a method to handle monitors.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/montage.html b/www/api/montage.html
new file mode 100644
index 0000000..5ba6e8f
--- /dev/null
+++ b/www/api/montage.html
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>montage</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="montage">
+<h1 class="title">montage</h1>
+<h2 class="subtitle" id="create-a-thumbnail-image-mosaic">Create a thumbnail image mosaic</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#clonemontageinfo" id="id7">CloneMontageInfo</a></li>
+<li><a class="reference internal" href="#destroymontageinfo" id="id8">DestroyMontageInfo</a></li>
+<li><a class="reference internal" href="#getmontageinfo" id="id9">GetMontageInfo</a></li>
+<li><a class="reference internal" href="#montageimages" id="id10">MontageImages</a></li>
+</ul>
+</div>
+<div class="section" id="clonemontageinfo">
+<h1><a class="toc-backref" href="#id7">CloneMontageInfo</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *CloneMontageInfo( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info,
+ const <a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *montage_info );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>CloneMontageInfo() makes a copy of the given montage info structure. If
+NULL is specified, a new image info structure is created initialized to
+default values.</p>
+<p>The format of the CloneMontageInfo method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *CloneMontageInfo( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info,
+ const <a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *montage_info );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>montage_info:</dt>
+<dd>The montage info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroymontageinfo">
+<h1><a class="toc-backref" href="#id8">DestroyMontageInfo</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyMontageInfo( <a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *montage_info );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>DestroyMontageInfo() deallocates memory associated with montage_info.</p>
+<p>The format of the DestroyMontageInfo method is:</p>
+<pre class="literal-block">
+void DestroyMontageInfo( <a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *montage_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>montage_info:</dt>
+<dd>Specifies a pointer to an MontageInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getmontageinfo">
+<h1><a class="toc-backref" href="#id9">GetMontageInfo</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void GetMontageInfo( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *montage_info );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>GetMontageInfo() initializes montage_info to default values.</p>
+<p>The format of the GetMontageInfo method is:</p>
+<pre class="literal-block">
+void GetMontageInfo( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, <a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *montage_info );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>a structure of type ImageInfo.</dd>
+<dt>montage_info:</dt>
+<dd>Specifies a pointer to a MontageInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="montageimages">
+<h1><a class="toc-backref" href="#id10">MontageImages</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MontageImages( const <a class="reference external" href="../api/types.html#image">Image</a> *images, const <a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *montage_info,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>Montageimages() is a layout manager that lets you tile one or more
+thumbnails across an image canvas.</p>
+<p>The format of the MontageImages method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MontageImages( const <a class="reference external" href="../api/types.html#image">Image</a> *images, const <a class="reference external" href="../api/types.html#montageinfo">MontageInfo</a> *montage_info,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>images:</dt>
+<dd>Specifies a pointer to an array of Image structures.</dd>
+<dt>montage_info:</dt>
+<dd>Specifies a pointer to a MontageInfo structure.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/operator.html b/www/api/operator.html
new file mode 100644
index 0000000..9212b54
--- /dev/null
+++ b/www/api/operator.html
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>operator</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="operator">
+<h1 class="title">operator</h1>
+<h2 class="subtitle" id="methods-to-apply-mathematic-or-boolean-operators-to-pixels">Methods to apply mathematic or boolean operators to pixels.</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#quantumoperatorimage" id="id3">QuantumOperatorImage</a></li>
+<li><a class="reference internal" href="#quantumoperatorregionimage" id="id4">QuantumOperatorRegionImage</a></li>
+</ul>
+</div>
+<div class="section" id="quantumoperatorimage">
+<h1><a class="toc-backref" href="#id3">QuantumOperatorImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail QuantumOperatorImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ QuantumOperator operator, double rvalue );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>QuantumOperatorImage() performs the requested arithmetic,
+bitwise-logical, or value operation on the selected channels of
+the entire image. The AllChannels channel option operates on all
+color channels whereas the GrayChannel channel option treats the
+color channels as a grayscale intensity.</p>
+<p>These operations are on the DirectClass pixels of the image and do not
+update pixel indexes or colormap.</p>
+<p>The format of the QuantumOperatorImage method is:</p>
+<pre class="literal-block">
+MagickPassFail QuantumOperatorImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ QuantumOperator operator, double rvalue );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>Channel to operate on (RedChannel, CyanChannel,
+GreenChannel, MagentaChannel, BlueChannel, YellowChannel,
+OpacityChannel, BlackChannel, MatteChannel, AllChannels,
+GrayChannel). The AllChannels type only updates color
+channels. The GrayChannel type treats the color channels
+as if they represent an intensity.</dd>
+<dt>quantum_operator:</dt>
+<dd>Operator to use (AddQuantumOp, AndQuantumOp,
+AssignQuantumOp, DepthQuantumOp, DivideQuantumOp, GammaQuantumOp,
+LShiftQuantumOp, MultiplyQuantumOp, NegateQuantumOp,
+NoiseGaussianQuantumOp, NoiseImpulseQuantumOp,
+NoiseLaplacianQuantumOp, NoiseMultiplicativeQuantumOp,
+NoisePoissonQuantumOp, NoiseRandomQuantumOp, NoiseUniformQuantumOp,
+OrQuantumOp, RShiftQuantumOp, SubtractQuantumOp,
+ThresholdBlackQuantumOp, ThresholdQuantumOp, ThresholdWhiteQuantumOp,
+ThresholdBlackNegateQuantumOp, ThresholdWhiteNegateQuantumOp,
+XorQuantumOp).</dd>
+<dt>rvalue:</dt>
+<dd>Operator argument.</dd>
+<dt>exception:</dt>
+<dd>Updated with error description.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="quantumoperatorregionimage">
+<h1><a class="toc-backref" href="#id4">QuantumOperatorRegionImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail QuantumOperatorRegionImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, long x, long y,
+ unsigned long columns, unsigned long rows,
+ <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ QuantumOperator quantum_operator, double rvalue );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>QuantumOperatorRegionImage() performs the requested arithmetic,
+bitwise-logical, or value operation on the selected channels of
+the image over the specified region. The AllChannels channel option
+operates on all color channels whereas the GrayChannel channel option
+treats the color channels as a grayscale intensity.</p>
+<p>These operations are on the DirectClass pixels of the image and do not
+update pixel indexes or colormap.</p>
+<p>The format of the QuantumOperatorRegionImage method is:</p>
+<pre class="literal-block">
+MagickPassFail QuantumOperatorRegionImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, long x, long y,
+ unsigned long columns, unsigned long rows,
+ <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ QuantumOperator quantum_operator, double rvalue );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>channel:</dt>
+<dd>Channel to operate on (RedChannel, CyanChannel,
+GreenChannel, MagentaChannel, BlueChannel, YellowChannel,
+OpacityChannel, BlackChannel, MatteChannel, AllChannels,
+GrayChannel). The AllChannels type only updates color
+channels. The GrayChannel type treats the color channels
+as if they represent an intensity.</dd>
+<dt>x:</dt>
+<dd>Ordinate of left row of region.</dd>
+<dt>y:</dt>
+<dd>Orginate of top column of region.</dd>
+<dt>columns:</dt>
+<dd>Width of region.</dd>
+<dt>rows:</dt>
+<dd>Height of region.</dd>
+<dt>quantum_operator:</dt>
+<dd>Operator to use (AddQuantumOp,AndQuantumOp,
+AssignQuantumOp, DepthQuantumOp, DivideQuantumOp, GammaQuantumOp,
+LShiftQuantumOp, MultiplyQuantumOp, NegateQuantumOp,
+NoiseGaussianQuantumOp, NoiseImpulseQuantumOp,
+NoiseLaplacianQuantumOp, NoiseMultiplicativeQuantumOp,
+NoisePoissonQuantumOp, NoiseRandomQuantumOp, NoiseUniformQuantumOp,
+OrQuantumOp, RShiftQuantumOp, SubtractQuantumOp,
+ThresholdBlackQuantumOp, ThresholdQuantumOp, ThresholdWhiteQuantumOp,
+XorQuantumOp).</dd>
+<dt>rvalue:</dt>
+<dd>Operator argument.</dd>
+<dt>exception:</dt>
+<dd>Updated with error description.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/paint.html b/www/api/paint.html
new file mode 100644
index 0000000..acc0101
--- /dev/null
+++ b/www/api/paint.html
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>paint</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="paint">
+<h1 class="title">paint</h1>
+<h2 class="subtitle" id="methods-to-fill-image-pixel-regions">Methods to fill image pixel regions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#colorfloodfillimage" id="id7">ColorFloodfillImage</a></li>
+<li><a class="reference internal" href="#mattefloodfillimage" id="id8">MatteFloodfillImage</a></li>
+<li><a class="reference internal" href="#opaqueimage" id="id9">OpaqueImage</a></li>
+<li><a class="reference internal" href="#transparentimage" id="id10">TransparentImage</a></li>
+</ul>
+</div>
+<div class="section" id="colorfloodfillimage">
+<h1><a class="toc-backref" href="#id7">ColorFloodfillImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int ColorFloodfillImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info,
+ const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target, const long x_offset,
+ const long y_offset, const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> method );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>ColorFloodfill() changes the color value of any pixel that matches
+target and is an immediate neighbor. If the method FillToBorderMethod is
+specified, the color value is changed for any neighbor pixel that does not
+match the bordercolor member of image.</p>
+<p>By default target must match a particular pixel color exactly.
+However, in many cases two colors may differ by a small amount. The
+fuzz member of image defines how much tolerance is acceptable to
+consider two colors as the same. For example, set fuzz to 10 and the
+color red at intensities of 100 and 102 respectively are now
+interpreted as the same color for the purposes of the floodfill.</p>
+<p>The format of the ColorFloodfillImage method is:</p>
+<pre class="literal-block">
+unsigned int ColorFloodfillImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info,
+ const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target, const long x_offset,
+ const long y_offset, const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> method );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>draw_info:</dt>
+<dd>The draw info.</dd>
+<dt>target:</dt>
+<dd>The RGB value of the target color.</dd>
+<dt>x,y:</dt>
+<dd>The starting location of the operation.</dd>
+<dt>method:</dt>
+<dd>Choose either FloodfillMethod or FillToBorderMethod.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="mattefloodfillimage">
+<h1><a class="toc-backref" href="#id8">MatteFloodfillImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MatteFloodfillImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target,
+ const unsigned int opacity, const long x_offset,
+ const long y_offset, const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> method );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>MatteFloodfill() changes the transparency value of any pixel that matches
+target and is an immediate neighbor. If the method FillToBorderMethod
+is specified, the transparency value is changed for any neighbor pixel
+that does not match the bordercolor member of image.</p>
+<p>By default target must match a particular pixel transparency exactly.
+However, in many cases two transparency values may differ by a
+small amount. The fuzz member of image defines how much tolerance is
+acceptable to consider two transparency values as the same. For example,
+set fuzz to 10 and the opacity values of 100 and 102 respectively are
+now interpreted as the same value for the purposes of the floodfill.</p>
+<p>The format of the MatteFloodfillImage method is:</p>
+<pre class="literal-block">
+unsigned int MatteFloodfillImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target,
+ const unsigned int opacity, const long x_offset,
+ const long y_offset, const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> method );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>target:</dt>
+<dd>The RGB value of the target color.</dd>
+<dt>opacity:</dt>
+<dd>The level of transparency: 0 is fully opaque and MaxRGB is
+fully transparent.</dd>
+<dt>x,y:</dt>
+<dd>The starting location of the operation.</dd>
+<dt>method:</dt>
+<dd>Choose either FloodfillMethod or FillToBorderMethod.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="opaqueimage">
+<h1><a class="toc-backref" href="#id9">OpaqueImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int OpaqueImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target,
+ const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> fill );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>OpaqueImage() changes any pixel that matches color with the color
+defined by fill.</p>
+<p>By default color must match a particular pixel color exactly. However,
+in many cases two colors may differ by a small amount. Fuzz defines
+how much tolerance is acceptable to consider two colors as the same.
+For example, set fuzz to 10 and the color red at intensities of 100 and
+102 respectively are now interpreted as the same color.</p>
+<p>The format of the OpaqueImage method is:</p>
+<pre class="literal-block">
+unsigned int OpaqueImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target,
+ const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> fill );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>target:</dt>
+<dd>The RGB value of the target color.</dd>
+<dt>fill:</dt>
+<dd>The replacement color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="transparentimage">
+<h1><a class="toc-backref" href="#id10">TransparentImage</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int TransparentImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target,
+ const unsigned int opacity );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>TransparentImage() changes the opacity value associated with any pixel
+that matches color to the value defined by opacity.</p>
+<p>By default color must match a particular pixel color exactly. However,
+in many cases two colors may differ by a small amount. Fuzz defines
+how much tolerance is acceptable to consider two colors as the same.
+For example, set fuzz to 10 and the color red at intensities of 100 and
+102 respectively are now interpreted as the same color.</p>
+<p>The format of the TransparentImage method is:</p>
+<pre class="literal-block">
+unsigned int TransparentImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> target,
+ const unsigned int opacity );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>target:</dt>
+<dd>The RGB value of the target color.</dd>
+<dt>opacity:</dt>
+<dd>The replacement opacity value.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/pixel_cache.html b/www/api/pixel_cache.html
new file mode 100644
index 0000000..4ef7025
--- /dev/null
+++ b/www/api/pixel_cache.html
@@ -0,0 +1,1045 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>pixel_cache</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="pixel-cache">
+<h1 class="title">pixel_cache</h1>
+<h2 class="subtitle" id="image-pixel-cache-working-pixels">Image pixel cache (working pixels).</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#accesscacheviewpixels" id="id63">AccessCacheViewPixels</a></li>
+<li><a class="reference internal" href="#accessimmutableindexes" id="id64">AccessImmutableIndexes</a></li>
+<li><a class="reference internal" href="#accessmutableindexes" id="id65">AccessMutableIndexes</a></li>
+<li><a class="reference internal" href="#accessmutablepixels" id="id66">AccessMutablePixels</a></li>
+<li><a class="reference internal" href="#acquirecacheviewpixels" id="id67">AcquireCacheViewPixels</a></li>
+<li><a class="reference internal" href="#acquirecacheviewindexes" id="id68">AcquireCacheViewIndexes</a></li>
+<li><a class="reference internal" href="#acquireimagepixels" id="id69">AcquireImagePixels</a></li>
+<li><a class="reference internal" href="#acquireonecacheviewpixel" id="id70">AcquireOneCacheViewPixel</a></li>
+<li><a class="reference internal" href="#acquireonepixel" id="id71">AcquireOnePixel</a></li>
+<li><a class="reference internal" href="#acquireonepixelbyreference" id="id72">AcquireOnePixelByReference</a></li>
+<li><a class="reference internal" href="#checkimagepixellimits" id="id73">CheckImagePixelLimits</a></li>
+<li><a class="reference internal" href="#destroycacheinfo" id="id74">DestroyCacheInfo</a></li>
+<li><a class="reference internal" href="#destroyimagepixels" id="id75">DestroyImagePixels</a></li>
+<li><a class="reference internal" href="#getcacheviewpixels" id="id76">GetCacheViewPixels</a></li>
+<li><a class="reference internal" href="#getcacheviewimage" id="id77">GetCacheViewImage</a></li>
+<li><a class="reference internal" href="#getcacheviewindexes" id="id78">GetCacheViewIndexes</a></li>
+<li><a class="reference internal" href="#getimagepixels" id="id79">GetImagePixels</a></li>
+<li><a class="reference internal" href="#getimagepixelsex" id="id80">GetImagePixelsEx</a></li>
+<li><a class="reference internal" href="#getimagevirtualpixelmethod" id="id81">GetImageVirtualPixelMethod</a></li>
+<li><a class="reference internal" href="#getindexes" id="id82">GetIndexes</a></li>
+<li><a class="reference internal" href="#getonepixel" id="id83">GetOnePixel</a></li>
+<li><a class="reference internal" href="#getpixels" id="id84">GetPixels</a></li>
+<li><a class="reference internal" href="#modifycache" id="id85">ModifyCache</a></li>
+<li><a class="reference internal" href="#opencacheview" id="id86">OpenCacheView</a></li>
+<li><a class="reference internal" href="#referencecache" id="id87">ReferenceCache</a></li>
+<li><a class="reference internal" href="#setcacheviewpixels" id="id88">SetCacheViewPixels</a></li>
+<li><a class="reference internal" href="#setimagepixels" id="id89">SetImagePixels</a></li>
+<li><a class="reference internal" href="#setimagepixelsex" id="id90">SetImagePixelsEx</a></li>
+<li><a class="reference internal" href="#setimagevirtualpixelmethod" id="id91">SetImageVirtualPixelMethod</a></li>
+<li><a class="reference internal" href="#synccacheviewpixels" id="id92">SyncCacheViewPixels</a></li>
+<li><a class="reference internal" href="#syncimagepixels" id="id93">SyncImagePixels</a></li>
+<li><a class="reference internal" href="#syncimagepixelsex" id="id94">SyncImagePixelsEx</a></li>
+</ul>
+</div>
+<div class="section" id="accesscacheviewpixels">
+<h1><a class="toc-backref" href="#id63">AccessCacheViewPixels</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AccessCacheViewPixels( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Method AccessCacheViewPixels returns writeable pixels associated with
+the specified view.</p>
+<p>The format of the AccessCacheViewPixels method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AccessCacheViewPixels( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>indexes:</dt>
+<dd>Method AccessCacheViewPixels returns the pixels associated with
+the specified view.</dd>
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="accessimmutableindexes">
+<h1><a class="toc-backref" href="#id64">AccessImmutableIndexes</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const IndexPacket *AccessImmutableIndexes( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>AccessImmutableIndexes() returns the colormap indexes associated with
+the last call to AcquireImagePixels(). NULL is returned if colormap
+indexes are not available.</p>
+<p>The format of the AccessImmutableIndexes() method is:</p>
+<pre class="literal-block">
+const IndexPacket *AccessImmutableIndexes( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>indexes:</dt>
+<dd>The indexes associated with the last call to
+AcquireImagePixels().</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="accessmutableindexes">
+<h1><a class="toc-backref" href="#id65">AccessMutableIndexes</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+IndexPacket *AccessMutableIndexes( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>AccessMutableIndexes() returns the colormap indexes associated with
+the last call to SetImagePixels() or GetImagePixels(). NULL is returned
+if colormap indexes are not available.</p>
+<p>The format of the AccessMutagleIndexes() method is:</p>
+<pre class="literal-block">
+IndexPacket *AccessMutableIndexes( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>indexes:</dt>
+<dd>The indexes associated with the last call to
+AcquireImagePixels().</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="accessmutablepixels">
+<h1><a class="toc-backref" href="#id66">AccessMutablePixels</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AccessMutablePixels( <a class="reference external" href="../api/types.html#image">Image</a> image );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>AccessMutablePixels() returns the pixels associated with the last call to
+SetImagePixels() or GetImagePixels(). This is useful in order to access
+an already selected region without passing the geometry of the region.</p>
+<p>The format of the GetPixels() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AccessMutablePixels( <a class="reference external" href="../api/types.html#image">Image</a> image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>The pixels associated with the last call to SetImagePixels()
+or GetImagePixels().</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="acquirecacheviewpixels">
+<h1><a class="toc-backref" href="#id67">AcquireCacheViewPixels</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AcquireCacheViewPixels( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x,
+ const long y, const unsigned long columns,
+ const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>Method AcquireCacheViewPixels gets pixels from the in-memory or disk pixel
+cache as defined by the geometry parameters for read-only access. A
+pointer to the pixels is returned if the pixels are transferred, otherwise
+NULL is returned.</p>
+<p>The format of the AcquireCacheViewPixels method is:</p>
+<pre class="literal-block">
+const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AcquireCacheViewPixels( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x,
+ const long y, const unsigned long columns,
+ const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>Method AcquireCacheViewPixels returns a null pointer if an error
+occurs, otherwise a pointer to the view pixels.</dd>
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="acquirecacheviewindexes">
+<h1><a class="toc-backref" href="#id68">AcquireCacheViewIndexes</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const IndexPacket *AcquireCacheViewIndexes( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>Method AcquireCacheViewIndexes returns read-only indexes associated with
+the specified view.</p>
+<p>The format of the AcquireCacheViewIndexes method is:</p>
+<pre class="literal-block">
+const IndexPacket *AcquireCacheViewIndexes( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>indexes:</dt>
+<dd>Method AcquireCacheViewIndexes returns the indexes
+associated with the specified view.</dd>
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="acquireimagepixels">
+<h1><a class="toc-backref" href="#id69">AcquireImagePixels</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AcquireImagePixels( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>AcquireImagePixels() obtains a pixel region for read-only access. If the
+region is successfully accessed, a pointer to it is returned, otherwise
+NULL is returned. The returned pointer may point to a temporary working
+copy of the pixels or it may point to the original pixels in memory.
+Performance is maximized if the selected area is part of one row, or one
+or more full rows, since then there is opportunity to access the pixels
+in-place (without a copy) if the image is in RAM, or in a memory-mapped
+file. The returned pointer should <em>never</em> be deallocated by the user.</p>
+<p>Pixels accessed via the returned pointer represent a simple array of type
+PixelPacket. If the image storage class is PsudeoClass, call GetIndexes()
+after invoking GetImagePixels() to obtain the colormap indexes (of type
+IndexPacket) corresponding to the region.</p>
+<p>If you plan to modify the pixels, use GetImagePixels() instead.</p>
+<p>The format of the AcquireImagePixels() method is:</p>
+<pre class="literal-block">
+const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *AcquireImagePixels( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>AcquireImagePixels() returns a pointer to the pixels if they
+are transferred, otherwise a NULL is returned.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="acquireonecacheviewpixel">
+<h1><a class="toc-backref" href="#id70">AcquireOneCacheViewPixel</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail AcquireOneCacheViewPixel( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *pixel,
+ const long x, const long y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>Method AcquireOneCacheViewPixel gets one pixel from the in-memory or disk
+pixel cache as defined by the geometry parameters for read-only access.
+The image background color is returned if there is an error retrieving
+the pixel.</p>
+<p>The format of the AcquireOneCacheViewPixel method is:</p>
+<pre class="literal-block">
+MagickPassFail AcquireOneCacheViewPixel( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *pixel,
+ const long x, const long y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+<dt>pixel:</dt>
+<dd>Pointer to PixelPacket to update.</dd>
+<dt>x,y:</dt>
+<dd>Coordinate of pixel to retrieve</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="acquireonepixel">
+<h1><a class="toc-backref" href="#id71">AcquireOnePixel</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> AcquireOnePixel( const <a class="reference external" href="../api/types.html#image">Image</a> image, const long x, const long y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> exception );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>AcquireOnePixel() returns a single pixel at the specified (x,y) location.
+The image background color is returned if an error occurs. If errors
+are to be returned to the image, use GetOnePixel() instead. This function
+is convenient but performance will be poor if it is used too often.</p>
+<p>The format of the AcquireOnePixel() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> AcquireOnePixel( const <a class="reference external" href="../api/types.html#image">Image</a> image, const long x, const long y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> exception );
+</pre>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>AcquireOnePixel() returns a pixel at the specified (x,y)
+location.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x,y:</dt>
+<dd>These values define the location of the pixel to return.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="acquireonepixelbyreference">
+<h1><a class="toc-backref" href="#id72">AcquireOnePixelByReference</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail AcquireOnePixelByReference( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *pixel,
+ const long x, const long y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>AcquireOnePixelByReference() returns a single pixel at the specified (x,y)
+location. The image background color is returned if an error occurs. This
+function is convenient but performance will be poor if it is used too
+often.</p>
+<p>The format of the AcquireOnePixelByReference() method is:</p>
+<pre class="literal-block">
+MagickPassFail AcquireOnePixelByReference( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *pixel,
+ const long x, const long y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>AcquireOnePixel() returns a pixel at the specified (x,y)
+location.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>pixel:</dt>
+<dd>A reference to the pixel to update.</dd>
+<dt>x,y:</dt>
+<dd>These values define the location of the pixel to return.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="checkimagepixellimits">
+<h1><a class="toc-backref" href="#id73">CheckImagePixelLimits</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail CheckImagePixelLimits( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>CheckImagePixelLimits() verifies that image dimensions are within current
+limits. Returns MagickPass if image dimensions are within limits, or
+MagickFail (and updates exception) if dimensions exceed a limit.</p>
+<p>While this function is used within the pixel cache to prevent allocating
+an image which exceeds the limits, it may also be used to validate image
+dimensions obtained from file headers prior to allocating memory or doing
+further processing of the image. Such additional limits should be after
+any 'ping' mode processing so that the image dimensions can still be
+shown by 'identify'.</p>
+<p>The format of the CheckImagePixelLimits() method is:</p>
+<pre class="literal-block">
+MagickPassFail CheckImagePixelLimits( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Image to verify rows/columns.</dd>
+<dt>exception:</dt>
+<dd>Throw exception into this ExceptionInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroycacheinfo">
+<h1><a class="toc-backref" href="#id74">DestroyCacheInfo</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyCacheInfo( <a class="reference external" href="../api/types.html#cache">Cache</a> cache );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>DestroyCacheInfo() deallocates memory associated with the pixel cache.</p>
+<p>The format of the DestroyCacheInfo() method is:</p>
+<pre class="literal-block">
+void DestroyCacheInfo( <a class="reference external" href="../api/types.html#cache">Cache</a> cache );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>cache:</dt>
+<dd>Specifies a pointer to a Cache structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyimagepixels">
+<h1><a class="toc-backref" href="#id75">DestroyImagePixels</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>DestroyImagePixels() deallocates memory associated with the pixel cache.</p>
+<p>The format of the DestroyImagePixels() method is:</p>
+<pre class="literal-block">
+void DestroyImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getcacheviewpixels">
+<h1><a class="toc-backref" href="#id76">GetCacheViewPixels</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetCacheViewPixels( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>GetCacheViewPixels() gets writeable pixels from the in-memory or disk pixel
+cache as defined by the geometry parameters. A pointer to the pixels
+is returned if the pixels are transferred, otherwise a NULL is returned.</p>
+<p>The format of the GetCacheViewPixels method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetCacheViewPixels( <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>Method GetCacheViewPixels returns a null pointer if an error
+occurs, otherwise a pointer to the view pixels.</dd>
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+<dt>exception:</dt>
+<dd>Any errors are reported here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getcacheviewimage">
+<h1><a class="toc-backref" href="#id77">GetCacheViewImage</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetCacheViewImage( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>Method GetCacheViewImage returns the image which allocated the view.</p>
+<p>The format of the GetCacheViewImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetCacheViewImage( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Method GetCacheViewImage returns the image which allocated
+the view.</dd>
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getcacheviewindexes">
+<h1><a class="toc-backref" href="#id78">GetCacheViewIndexes</a></h1>
+<div class="section" id="id29">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+IndexPacket *GetCacheViewIndexes( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+</div>
+<div class="section" id="id30">
+<h2>Description</h2>
+<p>Method GetCacheViewIndexes returns writeable indexes associated with
+the specified view.</p>
+<p>The format of the GetCacheViewIndexes method is:</p>
+<pre class="literal-block">
+IndexPacket *GetCacheViewIndexes( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>indexes:</dt>
+<dd>Method GetCacheViewIndexes returns the indexes associated with
+the specified view.</dd>
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagepixels">
+<h1><a class="toc-backref" href="#id79">GetImagePixels</a></h1>
+<div class="section" id="id31">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id32">
+<h2>Description</h2>
+<p>GetImagePixels() obtains a pixel region for read/write access. If the
+region is successfully accessed, a pointer to a PixelPacket array
+representing the region is returned, otherwise NULL is returned.</p>
+<p>The returned pointer may point to a temporary working copy of the pixels
+or it may point to the original pixels in memory. Performance is maximized
+if the selected area is part of one row, or one or more full rows, since
+then there is opportunity to access the pixels in-place (without a copy)
+if the image is in RAM, or in a memory-mapped file. The returned pointer
+should <em>never</em> be deallocated by the user.</p>
+<p>Pixels accessed via the returned pointer represent a simple array of type
+PixelPacket. If the image storage class is PsudeoClass, call GetIndexes()
+after invoking GetImagePixels() to obtain the colormap indexes (of type
+IndexPacket) corresponding to the region. Once the PixelPacket (and/or
+IndexPacket) array has been updated, the changes must be saved back to
+the underlying image using SyncImagePixels() or they may be lost.</p>
+<p>The format of the GetImagePixels() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>GetImagePixels() returns a pointer to the pixels if they are
+transferred, otherwise a NULL is returned.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagepixelsex">
+<h1><a class="toc-backref" href="#id80">GetImagePixelsEx</a></h1>
+<div class="section" id="id33">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetImagePixelsEx( <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id34">
+<h2>Description</h2>
+<p>GetImagePixelsEx() obtains a pixel region for read/write access. It is
+similar to GetImagePixels() except that it reports any error information
+to a user provided exception structure.</p>
+<p>The format of the GetImagePixelsEx() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetImagePixelsEx( <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>GetImagePixelsEx() returns a pointer to the pixels if they are
+transferred, otherwise a NULL is returned.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+<dt>exception:</dt>
+<dd>Any error details are reported here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagevirtualpixelmethod">
+<h1><a class="toc-backref" href="#id81">GetImageVirtualPixelMethod</a></h1>
+<div class="section" id="id35">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#virtualpixelmethod">VirtualPixelMethod</a> GetImageVirtualPixelMethod( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id36">
+<h2>Description</h2>
+<p>GetImageVirtualPixelMethod() gets the &quot;virtual pixels&quot; method for the
+image. A virtual pixel is any pixel access that is outside the boundaries
+of the image cache.</p>
+<p>The format of the GetImageVirtualPixelMethod() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#virtualpixelmethod">VirtualPixelMethod</a> GetImageVirtualPixelMethod( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getindexes">
+<h1><a class="toc-backref" href="#id82">GetIndexes</a></h1>
+<div class="section" id="id37">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+IndexPacket *GetIndexes( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id38">
+<h2>Description</h2>
+<p>GetIndexes() returns the colormap indexes associated with the last call to
+SetImagePixels() or GetImagePixels(). NULL is returned if colormap indexes
+are not available.</p>
+<p>The format of the GetIndexes() method is:</p>
+<pre class="literal-block">
+IndexPacket *GetIndexes( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>indexes:</dt>
+<dd>GetIndexes() returns the indexes associated with the last
+call to SetImagePixels() or GetImagePixels().</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getonepixel">
+<h1><a class="toc-backref" href="#id83">GetOnePixel</a></h1>
+<div class="section" id="id39">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> GetOnePixel( const <a class="reference external" href="../api/types.html#image">Image</a> image, const long x, const long y );
+</pre>
+</div>
+<div class="section" id="id40">
+<h2>Description</h2>
+<p>GetOnePixel() returns a single pixel at the specified (x,y) location.
+The image background color is returned if an error occurs. This function
+is convenient but performance will be poor if it is used too often.
+GetOnePixel() is identical to AcquireOnePixel() except that exceptions
+are implicitly delivered to the image.</p>
+<p>The format of the GetOnePixel() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> GetOnePixel( const <a class="reference external" href="../api/types.html#image">Image</a> image, const long x, const long y );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x,y:</dt>
+<dd>These values define the location of the pixel to return.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getpixels">
+<h1><a class="toc-backref" href="#id84">GetPixels</a></h1>
+<div class="section" id="id41">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetPixels( const <a class="reference external" href="../api/types.html#image">Image</a> image );
+</pre>
+</div>
+<div class="section" id="id42">
+<h2>Description</h2>
+<p>GetPixels() returns the pixels associated with the last call to
+SetImagePixels() or GetImagePixels(). This is useful in order to access
+an already selected region without passing the geometry of the region.</p>
+<p>The format of the GetPixels() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *GetPixels( const <a class="reference external" href="../api/types.html#image">Image</a> image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>GetPixels() returns the pixels associated with the last call
+to SetImagePixels() or GetImagePixels().</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="modifycache">
+<h1><a class="toc-backref" href="#id85">ModifyCache</a></h1>
+<div class="section" id="id43">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail ModifyCache( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id44">
+<h2>Description</h2>
+<p>ModifyCache() ensures that there is only a single reference to the pixel
+cache to be modified, updating the provided cache pointer to point to
+a clone of the original pixel cache if necessary. This is used to
+implement copy on write.</p>
+<p>The format of the ModifyCache method is:</p>
+<pre class="literal-block">
+MagickPassFail ModifyCache( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Errors are reported here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="opencacheview">
+<h1><a class="toc-backref" href="#id86">OpenCacheView</a></h1>
+<div class="section" id="id45">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *OpenCacheView( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id46">
+<h2>Description</h2>
+<p>OpenCacheView() opens a view into the pixel cache.</p>
+<p>The format of the OpenCacheView method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *OpenCacheView( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="referencecache">
+<h1><a class="toc-backref" href="#id87">ReferenceCache</a></h1>
+<div class="section" id="id47">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#cache">Cache</a> ReferenceCache( <a class="reference external" href="../api/types.html#cache">Cache</a> cache_info );
+</pre>
+</div>
+<div class="section" id="id48">
+<h2>Description</h2>
+<p>ReferenceCache() increments the reference count associated with the pixel
+cache returning a pointer to the cache.</p>
+<p>The format of the ReferenceCache method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#cache">Cache</a> ReferenceCache( <a class="reference external" href="../api/types.html#cache">Cache</a> cache_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>cache_info:</dt>
+<dd>The cache_info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setcacheviewpixels">
+<h1><a class="toc-backref" href="#id88">SetCacheViewPixels</a></h1>
+<div class="section" id="id49">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *SetCacheViewPixels( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id50">
+<h2>Description</h2>
+<p>SetCacheViewPixels() gets pixels from the in-memory or disk pixel cache as
+defined by the geometry parameters. A pointer to the pixels is returned
+if the pixels are transferred, otherwise a NULL is returned.</p>
+<p>The format of the SetCacheViewPixels method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *SetCacheViewPixels( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+<dt>exception:</dt>
+<dd>Any errors are reported here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimagepixels">
+<h1><a class="toc-backref" href="#id89">SetImagePixels</a></h1>
+<div class="section" id="id51">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *SetImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id52">
+<h2>Description</h2>
+<p>SetImagePixels() initializes a pixel region for write-only access.
+If the region is successfully intialized a pointer to a PixelPacket
+array representing the region is returned, otherwise NULL is returned.
+The returned pointer may point to a temporary working buffer for the
+pixels or it may point to the final location of the pixels in memory.</p>
+<p>Write-only access means that any existing pixel values corresponding to
+the region are ignored. This is useful while the initial image is being
+created from scratch, or if the existing pixel values are to be
+completely replaced without need to refer to their pre-existing values.
+The application is free to read and write the pixel buffer returned by
+SetImagePixels() any way it pleases. SetImagePixels() does not initialize
+the pixel array values. Initializing pixel array values is the
+application's responsibility.</p>
+<p>Performance is maximized if the selected area is part of one row, or
+one or more full rows, since then there is opportunity to access the
+pixels in-place (without a copy) if the image is in RAM, or in a
+memory-mapped file. The returned pointer should <em>never</em> be deallocated
+by the user.</p>
+<p>Pixels accessed via the returned pointer represent a simple array of type
+PixelPacket. If the image storage class is PsudeoClass, call GetIndexes()
+after invoking GetImagePixels() to obtain the colormap indexes (of type
+IndexPacket) corresponding to the region. Once the PixelPacket (and/or
+IndexPacket) array has been updated, the changes must be saved back to
+the underlying image using SyncCacheNexus() or they may be lost.</p>
+<p>The format of the SetImagePixels() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *SetImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>SetImagePixels returns a pointer to the pixels if they are
+transferred, otherwise a NULL is returned.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimagepixelsex">
+<h1><a class="toc-backref" href="#id90">SetImagePixelsEx</a></h1>
+<div class="section" id="id53">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *SetImagePixelsEx( <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id54">
+<h2>Description</h2>
+<p>SetImagePixelsEx() initializes a pixel region for write-only access.
+It is similar to SetImagePixels() except that any exception information
+is written to a user provided exception structure.</p>
+<p>The format of the SetImagePixelsEx() method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *SetImagePixelsEx( <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>pixels:</dt>
+<dd>SetImagePixelsEx returns a pointer to the pixels if they are
+transferred, otherwise a NULL is returned.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x,y,columns,rows:</dt>
+<dd>These values define the perimeter of a region of
+pixels.</dd>
+<dt>exception:</dt>
+<dd>Any error details are reported here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimagevirtualpixelmethod">
+<h1><a class="toc-backref" href="#id91">SetImageVirtualPixelMethod</a></h1>
+<div class="section" id="id55">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+SetImageVirtualPixelMethod( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#virtualpixelmethod">VirtualPixelMethod</a> method );
+</pre>
+</div>
+<div class="section" id="id56">
+<h2>Description</h2>
+<p>SetImageVirtualPixelMethod() sets the &quot;virtual pixels&quot; method for the
+image. A virtual pixel is any pixel access that is outside the boundaries
+of the image cache.</p>
+<p>The format of the SetImageVirtualPixelMethod() method is:</p>
+<pre class="literal-block">
+SetImageVirtualPixelMethod( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#virtualpixelmethod">VirtualPixelMethod</a> method );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>type:</dt>
+<dd>choose from these access types:</dd>
+</dl>
+<p>EdgeVPType: the edge pixels of the image extend infinitely.
+Any pixel outside the image is assigned the same value as the
+pixel at the edge closest to it.</p>
+<p>TileVPType: the image extends periodically or tiled. The pixels
+wrap around the edges of the image.</p>
+<p>MirrorVPType: mirror the image at the boundaries.</p>
+<p>ConstantVPType: every value outside the image is a constant as
+defines by the pixel parameter.</p>
+</div>
+</div>
+<div class="section" id="synccacheviewpixels">
+<h1><a class="toc-backref" href="#id92">SyncCacheViewPixels</a></h1>
+<div class="section" id="id57">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail SyncCacheViewPixels( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id58">
+<h2>Description</h2>
+<p>SyncCacheViewPixels() saves the view pixels to the in-memory or disk cache.
+The method returns MagickPass if the pixel region is synced, otherwise
+MagickFail.</p>
+<p>The format of the SyncCacheViewPixels method is:</p>
+<pre class="literal-block">
+MagickPassFail SyncCacheViewPixels( const <a class="reference external" href="../api/types.html#viewinfo">ViewInfo</a> *view, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>view:</dt>
+<dd>The address of a structure of type ViewInfo.</dd>
+<dt>exception:</dt>
+<dd>Any errors are reported here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="syncimagepixels">
+<h1><a class="toc-backref" href="#id93">SyncImagePixels</a></h1>
+<div class="section" id="id59">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail SyncImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id60">
+<h2>Description</h2>
+<p>SyncImagePixels() saves the image pixels to the in-memory or disk cache.
+The method returns MagickPass if the pixel region is synced, otherwise MagickFail.</p>
+<p>The format of the SyncImagePixels() method is:</p>
+<pre class="literal-block">
+MagickPassFail SyncImagePixels( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>SyncImagePixels() returns MagickPass if the image pixels are
+transferred to the in-memory or disk cache otherwise MagickFail.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="syncimagepixelsex">
+<h1><a class="toc-backref" href="#id94">SyncImagePixelsEx</a></h1>
+<div class="section" id="id61">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail SyncImagePixelsEx( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id62">
+<h2>Description</h2>
+<p>SyncImagePixelsEx() saves the image pixels to the in-memory or disk cache.
+The method returns MagickPass if the pixel region is synced, otherwise
+MagickFail.</p>
+<p>The format of the SyncImagePixelsEx() method is:</p>
+<pre class="literal-block">
+MagickPassFail SyncImagePixelsEx( <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>SyncImagePixelsEx() returns MagickPass if the image pixels are
+transferred to the in-memory or disk cache otherwise MagickFail.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Any error details are reported here.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/pixel_iterator.html b/www/api/pixel_iterator.html
new file mode 100644
index 0000000..3b1c7dc
--- /dev/null
+++ b/www/api/pixel_iterator.html
@@ -0,0 +1,600 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>pixel_iterator</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="pixel-iterator">
+<h1 class="title">pixel_iterator</h1>
+<h2 class="subtitle" id="pixel-iterator-pattern-support-functions">Pixel iterator pattern support functions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#initializepixeliteratoroptions" id="id17">InitializePixelIteratorOptions</a></li>
+<li><a class="reference internal" href="#pixeliteratemonoread" id="id18">PixelIterateMonoRead</a></li>
+<li><a class="reference internal" href="#pixeliteratemonoset" id="id19">PixelIterateMonoSet</a></li>
+<li><a class="reference internal" href="#pixeliteratemonomodify" id="id20">PixelIterateMonoModify</a></li>
+<li><a class="reference internal" href="#pixeliteratedualread" id="id21">PixelIterateDualRead</a></li>
+<li><a class="reference internal" href="#pixeliteratedualmodify" id="id22">PixelIterateDualModify</a></li>
+<li><a class="reference internal" href="#pixeliteratedualnew" id="id23">PixelIterateDualNew</a></li>
+<li><a class="reference internal" href="#pixeliteratetriplemodify" id="id24">PixelIterateTripleModify</a></li>
+<li><a class="reference internal" href="#pixeliteratetriplenew" id="id25">PixelIterateTripleNew</a></li>
+</ul>
+</div>
+<div class="section" id="initializepixeliteratoroptions">
+<h1><a class="toc-backref" href="#id17">InitializePixelIteratorOptions</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void InitializePixelIteratorOptions( PixelIteratorOptions *options,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>InitializePixelIteratorOptions() assigns default options to a user-provided
+PixelIteratorOptions structure. This function should always be used
+to initialize the PixelIteratorOptions structure prior to making any
+changes to it.</p>
+<p>The format of the InitializePixelIteratorOptions method is:</p>
+<pre class="literal-block">
+void InitializePixelIteratorOptions( PixelIteratorOptions *options,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>options:</dt>
+<dd>pointer to PixelIteratorOptions structure to initialize.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixeliteratemonoread">
+<h1><a class="toc-backref" href="#id18">PixelIterateMonoRead</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PixelIterateMonoRead( PixelIteratorMonoReadCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>PixelIterateMonoRead() iterates through a region of an image and invokes a
+user-provided callback function (of type PixelRowIteratorMonoReadCallback)
+for a row of pixels. This is useful to support simple operations such as
+statistics computation.</p>
+<p>The format of the PixelIterateMonoRead method is:</p>
+<pre class="literal-block">
+MagickPassFail PixelIterateMonoRead( PixelIteratorMonoReadCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>call_back:</dt>
+<dd>A user-provided C callback function which is passed the
+address of pixels from the image.</dd>
+<dt>options:</dt>
+<dd>Pixel iterator execution options (may be NULL).</dd>
+<dt>description:</dt>
+<dd>textual description of operation being performed.</dd>
+<dt>mutable_data:</dt>
+<dd>User-provided mutable context data.</dd>
+<dt>immutable_data:</dt>
+<dd>User-provided immutable context data.</dd>
+<dt>x:</dt>
+<dd>The horizontal ordinate of the top left corner of the region.</dd>
+<dt>y:</dt>
+<dd>The vertical ordinate of the top left corner of the region.</dd>
+<dt>columns:</dt>
+<dd>Width of pixel region</dd>
+<dt>rows:</dt>
+<dd>Height of pixel region</dd>
+<dt>image:</dt>
+<dd>The address of the Image.</dd>
+<dt>exception:</dt>
+<dd>If an error is reported, this argument is updated with the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixeliteratemonoset">
+<h1><a class="toc-backref" href="#id19">PixelIterateMonoSet</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PixelIterateMonoSet( PixelIteratorMonoModifyback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>PixelIterateMonoSet() iterates through a region of an image and invokes
+a user-provided callback function (of type PixelIteratorMonoModifyCallback)
+to initialize a region of pixels from scratch. The difference from
+PixelIterateMonoModify() is that the output pixels are not initialized
+from the underlying store so it is more efficient when outputting a new
+image or when the existing pixels are intentionally discarded. This is
+useful for operations such as setting the pixel color.</p>
+<p>The format of the PixelIterateMonoSet method is:</p>
+<pre class="literal-block">
+MagickPassFail PixelIterateMonoSet( PixelIteratorMonoModifyback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const long x, const long y,
+ const unsigned long columns, const unsigned long rows,
+ <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>call_back:</dt>
+<dd>A user-provided C callback function which is passed the
+address of pixels to be initialized in the image.</dd>
+<dt>options:</dt>
+<dd>Pixel iterator execution options (may be NULL).</dd>
+<dt>description:</dt>
+<dd>textual description of operation being performed.</dd>
+<dt>mutable_data:</dt>
+<dd>User-provided mutable context data.</dd>
+<dt>immutable_data:</dt>
+<dd>User-provided immutable context data.</dd>
+<dt>x:</dt>
+<dd>The horizontal ordinate of the top left corner of the region.</dd>
+<dt>y:</dt>
+<dd>The vertical ordinate of the top left corner of the region.</dd>
+<dt>columns:</dt>
+<dd>Width of pixel region</dd>
+<dt>rows:</dt>
+<dd>Height of pixel region</dd>
+<dt>image:</dt>
+<dd>The address of the Image.</dd>
+<dt>exception:</dt>
+<dd>If an error is reported, this argument is updated with the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixeliteratemonomodify">
+<h1><a class="toc-backref" href="#id20">PixelIterateMonoModify</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PixelIterateMonoModify( PixelIteratorMonoModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const long x,
+ const long y, const unsigned long columns,
+ const unsigned long rows, <a class="reference external" href="../api/types.html#image">Image</a> *image,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>PixelIterateMonoModify() iterates through a region of an image and invokes
+a user-provided callback function (of type PixelIteratorMonoModifyCallback)
+to modify a region of pixels. This is useful to support simple operations
+such as level shifting, colorspace translation, or thresholding.</p>
+<p>The format of the PixelIterateMonoModify method is:</p>
+<pre class="literal-block">
+MagickPassFail PixelIterateMonoModify( PixelIteratorMonoModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const long x,
+ const long y, const unsigned long columns,
+ const unsigned long rows, <a class="reference external" href="../api/types.html#image">Image</a> *image,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>call_back:</dt>
+<dd>A user-provided C callback function which is passed the
+address of pixels from the image.</dd>
+<dt>options:</dt>
+<dd>Pixel iterator execution options (may be NULL).</dd>
+<dt>description:</dt>
+<dd>textual description of operation being performed.</dd>
+<dt>mutable_data:</dt>
+<dd>User-provided mutable context data.</dd>
+<dt>immutable_data:</dt>
+<dd>User-provided immutable context data.</dd>
+<dt>x:</dt>
+<dd>The horizontal ordinate of the top left corner of the region.</dd>
+<dt>y:</dt>
+<dd>The vertical ordinate of the top left corner of the region.</dd>
+<dt>columns:</dt>
+<dd>Width of pixel region</dd>
+<dt>rows:</dt>
+<dd>Height of pixel region</dd>
+<dt>image:</dt>
+<dd>The address of the Image.</dd>
+<dt>exception:</dt>
+<dd>If an error is reported, this argument is updated with the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixeliteratedualread">
+<h1><a class="toc-backref" href="#id21">PixelIterateDualRead</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PixelIterateDualRead( PixelIteratorDualReadCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const unsigned long columns,
+ const unsigned long rows, const <a class="reference external" href="../api/types.html#image">Image</a> *first_image,
+ const long first_x, const long first_y,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *second_image, const long second_x,
+ const long second_y, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception ); ;
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>PixelIterateDualRead() iterates through pixel regions of two images and
+invokes a user-provided callback function (of type
+PixelIteratorDualReadCallback) for each row of pixels. This is useful to
+support operations such as image comparison.</p>
+<p>The format of the PixelIterateDualRead method is:</p>
+<pre class="literal-block">
+MagickPassFail PixelIterateDualRead( PixelIteratorDualReadCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const unsigned long columns,
+ const unsigned long rows, const <a class="reference external" href="../api/types.html#image">Image</a> *first_image,
+ const long first_x, const long first_y,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *second_image, const long second_x,
+ const long second_y, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception ); ;
+</pre>
+<dl class="docutils">
+<dt>call_back:</dt>
+<dd>A user-provided C callback function which is passed the
+address of pixels from each image.</dd>
+<dt>options:</dt>
+<dd>Pixel iterator execution options (may be NULL).</dd>
+<dt>description:</dt>
+<dd>textual description of operation being performed.</dd>
+<dt>mutable_data:</dt>
+<dd>User-provided mutable context data.</dd>
+<dt>immutable_data:</dt>
+<dd>User-provided immutable context data.</dd>
+<dt>columns:</dt>
+<dd>Width of pixel region</dd>
+<dt>rows:</dt>
+<dd>Height of pixel region</dd>
+<dt>first_image:</dt>
+<dd>The address of the first Image.</dd>
+<dt>first_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the first region.</dd>
+<dt>first_y:</dt>
+<dd>The vertical ordinate of the top left corner of the first region.</dd>
+<dt>second_image:</dt>
+<dd>The address of the second Image.</dd>
+<dt>second_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the second region.</dd>
+<dt>second_y:</dt>
+<dd>The vertical ordinate of the top left corner of the second region.</dd>
+<dt>exception:</dt>
+<dd>If an error is reported, this argument is updated with the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixeliteratedualmodify">
+<h1><a class="toc-backref" href="#id22">PixelIterateDualModify</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PixelIterateDualModify( PixelIteratorDualModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source_image, const long source_x,
+ const long source_y, <a class="reference external" href="../api/types.html#image">Image</a> *update_image,
+ const long update_x, const long update_y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>PixelIterateDualModify() iterates through pixel regions of two images and
+invokes a user-provided callback function (of type
+PixelIteratorDualModifyCallback) for each row of pixels. This is useful to
+support operations such as composition.</p>
+<p>The format of the PixelIterateDualModify method is:</p>
+<pre class="literal-block">
+MagickPassFail PixelIterateDualModify( PixelIteratorDualModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source_image, const long source_x,
+ const long source_y, <a class="reference external" href="../api/types.html#image">Image</a> *update_image,
+ const long update_x, const long update_y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>call_back:</dt>
+<dd>A user-provided C callback function which reads from
+a region of source pixels and updates a region of destination pixels.</dd>
+<dt>options:</dt>
+<dd>Pixel iterator execution options (may be NULL).</dd>
+<dt>description:</dt>
+<dd>textual description of operation being performed.</dd>
+<dt>mutable_data:</dt>
+<dd>User-provided mutable context data.</dd>
+<dt>immutable_data:</dt>
+<dd>User-provided immutable context data.</dd>
+<dt>columns:</dt>
+<dd>Width of pixel region</dd>
+<dt>rows:</dt>
+<dd>Height of pixel region</dd>
+<dt>source_image:</dt>
+<dd>The address of the constant source Image.</dd>
+<dt>source_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the source region.</dd>
+<dt>source_y:</dt>
+<dd>The vertical ordinate of the top left corner of the source region.</dd>
+<dt>update_image:</dt>
+<dd>The address of the update Image.</dd>
+<dt>update_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the update region.</dd>
+<dt>update_y:</dt>
+<dd>The vertical ordinate of the top left corner of the update region.</dd>
+<dt>exception:</dt>
+<dd>If an error is reported, this argument is updated with the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixeliteratedualnew">
+<h1><a class="toc-backref" href="#id23">PixelIterateDualNew</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PixelIterateDualNew( PixelIteratorDualNewCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const unsigned long columns,
+ const unsigned long rows, const <a class="reference external" href="../api/types.html#image">Image</a> *source_image,
+ const long source_x, const long source_y,
+ <a class="reference external" href="../api/types.html#image">Image</a> *new_image, const long new_x,
+ const long new_y, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>PixelIterateDualNew() iterates through pixel regions of two images and
+invokes a user-provided callback function (of type
+PixelIteratorDualNewCallback) for each row of pixels. This is used if a
+new output image is created based on an input image. The difference from
+PixelIterateDualModify() is that the output pixels are not initialized so
+it is more efficient when outputting a new image.</p>
+<p>The format of the PixelIterateDualNew method is:</p>
+<pre class="literal-block">
+MagickPassFail PixelIterateDualNew( PixelIteratorDualNewCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data, const unsigned long columns,
+ const unsigned long rows, const <a class="reference external" href="../api/types.html#image">Image</a> *source_image,
+ const long source_x, const long source_y,
+ <a class="reference external" href="../api/types.html#image">Image</a> *new_image, const long new_x,
+ const long new_y, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>call_back:</dt>
+<dd>A user-provided C callback function which reads from
+a region of source pixels and initializes a region of destination pixels.</dd>
+<dt>options:</dt>
+<dd>Pixel iterator execution options (may be NULL).</dd>
+<dt>description:</dt>
+<dd>textual description of operation being performed.</dd>
+<dt>mutable_data:</dt>
+<dd>User-provided mutable context data.</dd>
+<dt>immutable_data:</dt>
+<dd>User-provided immutable context data.</dd>
+<dt>columns:</dt>
+<dd>Width of pixel region</dd>
+<dt>rows:</dt>
+<dd>Height of pixel region</dd>
+<dt>source_image:</dt>
+<dd>The address of the constant source Image.</dd>
+<dt>source_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the source region.</dd>
+<dt>source_y:</dt>
+<dd>The vertical ordinate of the top left corner of the source region.</dd>
+<dt>new_image:</dt>
+<dd>The address of the new Image.</dd>
+<dt>new_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the new region.</dd>
+<dt>new_y:</dt>
+<dd>The vertical ordinate of the top left corner of the new region.</dd>
+<dt>exception:</dt>
+<dd>If an error is reported, this argument is updated with the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixeliteratetriplemodify">
+<h1><a class="toc-backref" href="#id24">PixelIterateTripleModify</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PixelIterateTripleModify( PixelIteratorTripleModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source1_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source2_image, const long source_x,
+ const long source_y, <a class="reference external" href="../api/types.html#image">Image</a> *update_image,
+ const long update_x, const long update_y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>PixelIterateTripleModify() iterates through pixel regions of three images
+and invokes a user-provided callback function (of type
+PixelIteratorTripleModifyCallback) for each row of pixels. The first two
+images are read-only, while the third image is read-write for update.
+Access of the first two images is done lock-step using the same coordinates.
+This is useful to support operations such as image differencing.</p>
+<p>The format of the PixelIterateTripleModify method is:</p>
+<pre class="literal-block">
+MagickPassFail PixelIterateTripleModify( PixelIteratorTripleModifyCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source1_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source2_image, const long source_x,
+ const long source_y, <a class="reference external" href="../api/types.html#image">Image</a> *update_image,
+ const long update_x, const long update_y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>call_back:</dt>
+<dd>A user-provided C callback function which reads from
+a region of source pixels and updates a region of destination pixels.</dd>
+<dt>options:</dt>
+<dd>Pixel iterator execution options (may be NULL).</dd>
+<dt>description:</dt>
+<dd>textual description of operation being performed.</dd>
+<dt>mutable_data:</dt>
+<dd>User-provided mutable context data.</dd>
+<dt>immutable_data:</dt>
+<dd>User-provided immutable context data.</dd>
+<dt>columns:</dt>
+<dd>Width of pixel region</dd>
+<dt>rows:</dt>
+<dd>Height of pixel region</dd>
+<dt>source1_image:</dt>
+<dd>The address of the constant source 1 Image.</dd>
+<dt>source2_image:</dt>
+<dd>The address of the constant source 2 Image.</dd>
+<dt>source_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the source regions.</dd>
+<dt>source_y:</dt>
+<dd>The vertical ordinate of the top left corner of the source regions.</dd>
+<dt>update_image:</dt>
+<dd>The address of the update Image.</dd>
+<dt>update_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the update region.</dd>
+<dt>update_y:</dt>
+<dd>The vertical ordinate of the top left corner of the update region.</dd>
+<dt>exception:</dt>
+<dd>If an error is reported, this argument is updated with the reason.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixeliteratetriplenew">
+<h1><a class="toc-backref" href="#id25">PixelIterateTripleNew</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PixelIterateTripleNew( PixelIteratorTripleNewCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source1_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source2_image, const long source_x,
+ const long source_y, <a class="reference external" href="../api/types.html#image">Image</a> *new_image,
+ const long new_x, const long new_y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>PixelIterateTripleNew() iterates through pixel regions of three images
+and invokes a user-provided callback function (of type
+PixelIteratorTripleNewCallback) for each row of pixels. The first two
+images are read-only, while the third image is read-write for update.
+Access of the first two images is done lock-step using the same coordinates.
+This is used if a new output image is created based on two input images.
+The difference from PixelIterateTripleModify() is that the output pixels
+are not initialized so it is more efficient when outputting a new image.</p>
+<p>The format of the PixelIterateTripleNew method is:</p>
+<pre class="literal-block">
+MagickPassFail PixelIterateTripleNew( PixelIteratorTripleNewCallback call_back,
+ const PixelIteratorOptions *options,
+ const char *description, void *mutable_data,
+ const void *immutable_data,
+ const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source1_image,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *source2_image, const long source_x,
+ const long source_y, <a class="reference external" href="../api/types.html#image">Image</a> *new_image,
+ const long new_x, const long new_y,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>call_back:</dt>
+<dd>A user-provided C callback function which reads from
+a region of source pixels and initializes a region of destination pixels.</dd>
+<dt>options:</dt>
+<dd>Pixel iterator execution options (may be NULL).</dd>
+<dt>description:</dt>
+<dd>textual description of operation being performed.</dd>
+<dt>mutable_data:</dt>
+<dd>User-provided mutable context data.</dd>
+<dt>immutable_data:</dt>
+<dd>User-provided immutable context data.</dd>
+<dt>columns:</dt>
+<dd>Width of pixel region</dd>
+<dt>rows:</dt>
+<dd>Height of pixel region</dd>
+<dt>source1_image:</dt>
+<dd>The address of the constant source 1 Image.</dd>
+<dt>source2_image:</dt>
+<dd>The address of the constant source 2 Image.</dd>
+<dt>source_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the source regions.</dd>
+<dt>source_y:</dt>
+<dd>The vertical ordinate of the top left corner of the source regions.</dd>
+<dt>new_image:</dt>
+<dd>The address of the new Image.</dd>
+<dt>new_x:</dt>
+<dd>The horizontal ordinate of the top left corner of the new region.</dd>
+<dt>new_y:</dt>
+<dd>The vertical ordinate of the top left corner of the new region.</dd>
+<dt>exception:</dt>
+<dd>If an error is reported, this argument is updated with the reason.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/plasma.html b/www/api/plasma.html
new file mode 100644
index 0000000..0f58031
--- /dev/null
+++ b/www/api/plasma.html
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>plasma</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="plasma">
+<h1 class="title">plasma</h1>
+<h2 class="subtitle" id="create-a-plasma-fractal-image">Create a Plasma fractal image.</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#plasmaimage" id="id1">PlasmaImage</a></li>
+</ul>
+</div>
+<div class="section" id="plasmaimage">
+<h1><a class="toc-backref" href="#id1">PlasmaImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail PlasmaImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#segmentinfo">SegmentInfo</a> *segment,
+ unsigned long attenuate, unsigned long depth );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>PlasmaImage() initializes an image with plasma fractal values. The image
+must be initialized with a base color and the random number generator
+seeded before this method is called.</p>
+<p>The format of the PlasmaImage method is:</p>
+<pre class="literal-block">
+MagickPassFail PlasmaImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#segmentinfo">SegmentInfo</a> *segment,
+ unsigned long attenuate, unsigned long depth );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>segment:</dt>
+<dd>Define the region to apply plasma fractals values.</dd>
+<dt>attenuate:</dt>
+<dd>Define the plasma attenuation factor.</dd>
+<dt>depth:</dt>
+<dd>Limit the plasma recursion depth.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/profile.html b/www/api/profile.html
new file mode 100644
index 0000000..2701cb5
--- /dev/null
+++ b/www/api/profile.html
@@ -0,0 +1,320 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>profile</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="profile">
+<h1 class="title">profile</h1>
+<h2 class="subtitle" id="manipulate-embedded-profiles">Manipulate embedded profiles</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#allocateimageprofileiterator" id="id15">AllocateImageProfileIterator</a></li>
+<li><a class="reference internal" href="#appendimageprofile" id="id16">AppendImageProfile</a></li>
+<li><a class="reference internal" href="#deallocateimageprofileiterator" id="id17">DeallocateImageProfileIterator</a></li>
+<li><a class="reference internal" href="#deleteimageprofile" id="id18">DeleteImageProfile</a></li>
+<li><a class="reference internal" href="#getimageprofile" id="id19">GetImageProfile</a></li>
+<li><a class="reference internal" href="#nextimageprofile" id="id20">NextImageProfile</a></li>
+<li><a class="reference internal" href="#profileimage" id="id21">ProfileImage</a></li>
+<li><a class="reference internal" href="#setimageprofile" id="id22">SetImageProfile</a></li>
+</ul>
+</div>
+<div class="section" id="allocateimageprofileiterator">
+<h1><a class="toc-backref" href="#id15">AllocateImageProfileIterator</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+ImageProfileIterator AllocateImageProfileIterator( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AllocateImageProfileIterator allocates an iterator to traverse the
+image profile list. It is an error (i.e. will surely crash) to invoke
+DeleteImageProfile() on the profile that the iterator is currently
+referencing. However, it is safe to delete a profile that the iterator
+is not currently referencing. Inserting additional profiles does not
+invalidate the current iterator.</p>
+<p>The format of the AllocateImageProfileIterator method is:</p>
+<pre class="literal-block">
+ImageProfileIterator AllocateImageProfileIterator( const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="appendimageprofile">
+<h1><a class="toc-backref" href="#id16">AppendImageProfile</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MaickPassFail AppendImageProfile( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name,
+ const unsigned char *profile_chunk,
+ const size_t chunk_length );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>AppendImageProfile adds a named profile to the image. If a profile with the
+same name already exists, then the new profile data is appended to the
+existing profile. If a null profile address is supplied, then an existing
+profile is removed. The profile is copied into the image. Note that this
+function does not execute CMS color profiles. Any existing CMS color
+profile is simply added/updated. Use the ProfileImage() function in order
+to execute a CMS color profile.</p>
+<p>The format of the AppendImageProfile method is:</p>
+<pre class="literal-block">
+MaickPassFail AppendImageProfile( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name,
+ const unsigned char *profile_chunk,
+ const size_t chunk_length );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>name:</dt>
+<dd>Profile name. Valid names are &quot;8BIM&quot;, &quot;ICM&quot;, &quot;IPTC&quot;, XMP, or any
+unique text string.</dd>
+<dt>profile_chunk:</dt>
+<dd>Address of profile chunk to add or append. Pass zero
+to remove an existing profile.</dd>
+<dt>length:</dt>
+<dd>The length of the profile chunk to add or append.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="deallocateimageprofileiterator">
+<h1><a class="toc-backref" href="#id17">DeallocateImageProfileIterator</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DeallocateImageProfileIterator( ImageProfileIterator profile_iterator );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DeallocateImageProfileIterator deallocates an image profile iterator.</p>
+<p>The format of the DeallocateImageProfileIterator method is:</p>
+<pre class="literal-block">
+void DeallocateImageProfileIterator( ImageProfileIterator profile_iterator );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>profile_iterator:</dt>
+<dd>Profile iterator to deallocate.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="deleteimageprofile">
+<h1><a class="toc-backref" href="#id18">DeleteImageProfile</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DeleteImageProfile( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>DeleteImageProfile removes a named profile from the image.</p>
+<p>The format of the DeleteImageProfile method is:</p>
+<pre class="literal-block">
+unsigned int DeleteImageProfile( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>name:</dt>
+<dd>Profile name. Valid names are &quot;8BIM&quot;, &quot;ICM&quot;, &amp; &quot;IPTC&quot; or a
+generic profile name.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimageprofile">
+<h1><a class="toc-backref" href="#id19">GetImageProfile</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const unsigned char *GetImageProfile( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name,
+ size_t *length );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>GetImageProfile returns a pointer to the named image profile if it is
+present. A null pointer is returned if the named profile is not present.</p>
+<p>Older versions of this function stored profiles named &quot;8BIM&quot; and &quot;IPTC&quot;
+in the same storage location. This is no longer the case. However,
+GetImageProfile() will try the alternate name if the specifically
+requested profile name is not available.</p>
+<p>The format of the GetImageProfile method is:</p>
+<pre class="literal-block">
+const unsigned char *GetImageProfile( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name,
+ size_t *length );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>name:</dt>
+<dd>Profile name. Valid names are &quot;8BIM&quot;, &quot;ICM&quot;, &quot;IPTC&quot;, &quot;XMP&quot; or any
+unique text string.</dd>
+<dt>length:</dt>
+<dd>Updated with profile length if profile is present. Set to NULL
+if length is not needed.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="nextimageprofile">
+<h1><a class="toc-backref" href="#id20">NextImageProfile</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail NextImageProfile( ImageProfileIterator profile_iterator, const char ** name,
+ const unsigned char ** profile, size_t *length );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>NextImageProfile iterates forward to the next image profile. The profile
+name is returned along with the profile data, and length. If there are
+no more entries in the list, then MagickFail is returned.</p>
+<p>The format of the AllocateImageProfileIterator method is:</p>
+<pre class="literal-block">
+MagickPassFail NextImageProfile( ImageProfileIterator profile_iterator, const char ** name,
+ const unsigned char ** profile, size_t *length );
+</pre>
+<dl class="docutils">
+<dt>profile_iterator:</dt>
+<dd>Profile iterator.</dd>
+<dt>name:</dt>
+<dd>Address of pointer to update with address of name.</dd>
+<dt>profile:</dt>
+<dd>Address of pointer to update with location of profile data.</dd>
+<dt>length:</dt>
+<dd>Address of parameter to update with profile length.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="profileimage">
+<h1><a class="toc-backref" href="#id21">ProfileImage</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int ProfileImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name, unsigned char *profile,
+ const size_t length, unsigned int clone );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>ProfileImage() adds, applies, or removes a ICM, IPTC, or generic profile
+from an image. If the profile is NULL, it is removed from the image
+otherwise added (or applied). Use a name of '*' and a profile of NULL to
+remove all profiles from the image. Ownership of the profile is
+transferred to GraphicsMagick (it should not be altered or deallocated)
+unless the clone option is set to True.</p>
+<p>ICC ICM profiles are a special case and are handled as follows:</p>
+<p>If there is no ICM profile currently associated with the image, then
+the profile is simply associated with the image and the image pixels
+are not altered.</p>
+<p>If there is already a ICM profile associated with the image, then
+the colorspace transform described by the existing and new profiles
+is applied to the image pixels, and the new profile is associated
+with the image.</p>
+<p>The format of the ProfileImage method is:</p>
+<pre class="literal-block">
+unsigned int ProfileImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name, unsigned char *profile,
+ const size_t length, unsigned int clone );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>name:</dt>
+<dd>Name of profile to add or remove: ICM, IPTC, or generic profile.</dd>
+<dt>profile:</dt>
+<dd>The profile. Can not be 'const' due to 'clone' option but
+is treated as 'const' if 'clone' is set to MagickTrue.</dd>
+<dt>length:</dt>
+<dd>The length of the profile.</dd>
+<dt>clone:</dt>
+<dd>If set True, then copy the profile rather than taking
+ownership of it.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setimageprofile">
+<h1><a class="toc-backref" href="#id22">SetImageProfile</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int SetImageProfile( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name, const unsigned char *profile,
+ const size_t length );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>SetImageProfile adds a named profile to the image. If a profile with the
+same name already exists, then it is replaced. If a null profile address
+is supplied, then an existing profile is removed. The profile is copied
+into the image. Note that this function does not execute CMS color
+profiles. Any existing CMS color profile is simply replaced. Use the
+ProfileImage() function in order to execute a CMS color profile.</p>
+<p>Older versions of this function stored profiles named &quot;8BIM&quot; and &quot;IPTC&quot;
+in the same storage location. This is no longer the case. However,
+GetImageProfile() will try the alternate name if the specifically
+requested profile name is not available. Note that when trying to remove
+a profile, it may be necessary to remove both names in order for an
+&quot;IPTC&quot; profile to no longer be included in output file formats.</p>
+<p>The format of the SetImageProfile method is:</p>
+<pre class="literal-block">
+unsigned int SetImageProfile( <a class="reference external" href="../api/types.html#image">Image</a> *image, const char *name, const unsigned char *profile,
+ const size_t length );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>name:</dt>
+<dd>Profile name. Valid names are &quot;8BIM&quot;, &quot;ICM&quot;, &quot;IPTC&quot;, XMP, or any
+unique text string.</dd>
+<dt>profile:</dt>
+<dd>Address of profile to add. Pass zero to remove an existing
+profile.</dd>
+<dt>length:</dt>
+<dd>The length of the profile.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/quantize.html b/www/api/quantize.html
new file mode 100644
index 0000000..3af2262
--- /dev/null
+++ b/www/api/quantize.html
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>quantize</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="quantize">
+<h1 class="title">quantize</h1>
+<h2 class="subtitle" id="reduce-the-number-of-colors-in-an-image">Reduce the number of colors in an image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#clonequantizeinfo" id="id21">CloneQuantizeInfo</a></li>
+<li><a class="reference internal" href="#compressimagecolormap" id="id22">CompressImageColormap</a></li>
+<li><a class="reference internal" href="#destroyquantizeinfo" id="id23">DestroyQuantizeInfo</a></li>
+<li><a class="reference internal" href="#getimagequantizeerror" id="id24">GetImageQuantizeError</a></li>
+<li><a class="reference internal" href="#getquantizeinfo" id="id25">GetQuantizeInfo</a></li>
+<li><a class="reference internal" href="#grayscalepseudoclassimage" id="id26">GrayscalePseudoClassImage</a></li>
+<li><a class="reference internal" href="#mapimage" id="id27">MapImage</a></li>
+<li><a class="reference internal" href="#mapimages" id="id28">MapImages</a></li>
+<li><a class="reference internal" href="#orderedditherimage" id="id29">OrderedDitherImage</a></li>
+<li><a class="reference internal" href="#quantizeimage" id="id30">QuantizeImage</a></li>
+<li><a class="reference internal" href="#quantizeimages" id="id31">QuantizeImages</a></li>
+</ul>
+</div>
+<div class="section" id="clonequantizeinfo">
+<h1><a class="toc-backref" href="#id21">CloneQuantizeInfo</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *CloneQuantizeInfo( const <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>CloneQuantizeInfo() makes a duplicate of the given quantize info structure,
+or if quantize info is NULL, a new one.</p>
+<p>The format of the CloneQuantizeInfo method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *CloneQuantizeInfo( const <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>clone_info:</dt>
+<dd>Method CloneQuantizeInfo returns a duplicate of the given
+quantize info, or if image info is NULL a new one.</dd>
+<dt>quantize_info:</dt>
+<dd>a structure of type info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="compressimagecolormap">
+<h1><a class="toc-backref" href="#id22">CompressImageColormap</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void CompressImageColormap( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>CompressImageColormap() compresses an image colormap by removing any
+duplicate or unused color entries.</p>
+<p>The format of the CompressImageColormap method is:</p>
+<pre class="literal-block">
+void CompressImageColormap( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroyquantizeinfo">
+<h1><a class="toc-backref" href="#id23">DestroyQuantizeInfo</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+DestroyQuantizeInfo( <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DestroyQuantizeInfo() deallocates memory associated with an QuantizeInfo
+structure.</p>
+<p>The format of the DestroyQuantizeInfo method is:</p>
+<pre class="literal-block">
+DestroyQuantizeInfo( <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>quantize_info:</dt>
+<dd>Specifies a pointer to an QuantizeInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagequantizeerror">
+<h1><a class="toc-backref" href="#id24">GetImageQuantizeError</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int GetImageQuantizeError( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>GetImageQuantizeError() measures the difference between the original
+and quantized images. This difference is the total quantization error.
+The error is computed by summing over all pixels in an image the distance
+squared in RGB space between each reference pixel value and its quantized
+value. These values are computed:</p>
+<p>o mean_error_per_pixel: This value is the mean error for any single
+pixel in the image.</p>
+<p>o normalized_mean_square_error: This value is the normalized mean
+quantization error for any single pixel in the image. This distance
+measure is normalized to a range between 0 and 1. It is independent
+of the range of red, green, and blue values in the image.</p>
+<p>o normalized_maximum_square_error: This value is the normalized
+maximum quantization error for any single pixel in the image. This
+distance measure is normalized to a range between 0 and 1. It is
+independent of the range of red, green, and blue values in your image.</p>
+<p>The format of the GetImageQuantizeError method is:</p>
+<pre class="literal-block">
+unsigned int GetImageQuantizeError( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows.</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Specifies a pointer to an Image structure; returned from
+ReadImage.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getquantizeinfo">
+<h1><a class="toc-backref" href="#id25">GetQuantizeInfo</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+GetQuantizeInfo( <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>GetQuantizeInfo() initializes the QuantizeInfo structure.</p>
+<p>The format of the GetQuantizeInfo method is:</p>
+<pre class="literal-block">
+GetQuantizeInfo( <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>quantize_info:</dt>
+<dd>Specifies a pointer to a QuantizeInfo structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="grayscalepseudoclassimage">
+<h1><a class="toc-backref" href="#id26">GrayscalePseudoClassImage</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void GrayscalePseudoClassImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>GrayscalePseudoClassImage converts an image to a PseudoClass
+grayscale representation with an (optionally) compressed and sorted
+colormap. Colormap is ordered by increasing intensity.</p>
+<p>The format of the GrayscalePseudoClassImage method is:</p>
+<pre class="literal-block">
+void GrayscalePseudoClassImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>optimize_colormap:</dt>
+<dd>If true, produce an optimimal (compact) colormap.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="mapimage">
+<h1><a class="toc-backref" href="#id27">MapImage</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MapImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *map_image,
+ const unsigned int dither );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>MapImage() replaces the colors of an image with the closest color from a
+reference image.</p>
+<p>The format of the MapImage method is:</p>
+<pre class="literal-block">
+unsigned int MapImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *map_image,
+ const unsigned int dither );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Specifies a pointer to an Image structure.</dd>
+<dt>map_image:</dt>
+<dd>Specifies a pointer to an Image structure. Reduce
+image to a set of colors represented by this image.</dd>
+<dt>dither:</dt>
+<dd>Set this integer value to something other than zero to
+dither the quantized image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="mapimages">
+<h1><a class="toc-backref" href="#id28">MapImages</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MapImages( <a class="reference external" href="../api/types.html#image">Image</a> *images, <a class="reference external" href="../api/types.html#image">Image</a> *map_image, const unsigned int dither );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>MapImages() replaces the colors of a sequence of images with the closest
+color from a reference image. If the reference image does not contain a
+colormap, then a colormap will be created based on existing colors in the
+reference image. The order and number of colormap entries does not match
+the reference image. If the order and number of colormap entries needs to
+match the reference image, then the ReplaceImageColormap() function may be
+used after invoking MapImages() in order to apply the reference colormap.</p>
+<p>The format of the MapImage method is:</p>
+<pre class="literal-block">
+unsigned int MapImages( <a class="reference external" href="../api/types.html#image">Image</a> *images, <a class="reference external" href="../api/types.html#image">Image</a> *map_image, const unsigned int dither );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Specifies a pointer to a set of Image structures.</dd>
+<dt>map_image:</dt>
+<dd>Specifies a pointer to an Image structure. Reduce
+image to a set of colors represented by this image.</dd>
+<dt>dither:</dt>
+<dd>Set this integer value to something other than zero to
+dither the quantized image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="orderedditherimage">
+<h1><a class="toc-backref" href="#id29">OrderedDitherImage</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int OrderedDitherImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>OrderedDitherImage() uses the ordered dithering technique of reducing color
+images to monochrome using positional information to retain as much
+information as possible.</p>
+<p>The format of the OrderedDitherImage method is:</p>
+<pre class="literal-block">
+unsigned int OrderedDitherImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows.</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Specifies a pointer to an Image structure; returned from
+ReadImage.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="quantizeimage">
+<h1><a class="toc-backref" href="#id30">QuantizeImage</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int QuantizeImage( const <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>QuantizeImage() analyzes the colors within a reference image and chooses a
+fixed number of colors to represent the image. The goal of the algorithm
+is to minimize the color difference between the input and output image while
+minimizing the processing time.</p>
+<p>The format of the QuantizeImage method is:</p>
+<pre class="literal-block">
+unsigned int QuantizeImage( const <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<dl class="docutils">
+<dt>quantize_info:</dt>
+<dd>Specifies a pointer to an QuantizeInfo structure.</dd>
+<dt>image:</dt>
+<dd>Specifies a pointer to an Image structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="quantizeimages">
+<h1><a class="toc-backref" href="#id31">QuantizeImages</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int QuantizeImages( const <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info, <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>QuantizeImages() analyzes the colors within a set of reference images and
+chooses a fixed number of colors to represent the set. The goal of the
+algorithm is to minimize the color difference between the input and output
+images while minimizing the processing time.</p>
+<p>The format of the QuantizeImages method is:</p>
+<pre class="literal-block">
+unsigned int QuantizeImages( const <a class="reference external" href="../api/types.html#quantizeinfo">QuantizeInfo</a> *quantize_info, <a class="reference external" href="../api/types.html#image">Image</a> *images );
+</pre>
+<dl class="docutils">
+<dt>quantize_info:</dt>
+<dd>Specifies a pointer to an QuantizeInfo structure.</dd>
+<dt>images:</dt>
+<dd>Specifies a pointer to a list of Image structures.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/registry.html b/www/api/registry.html
new file mode 100644
index 0000000..4e75ade
--- /dev/null
+++ b/www/api/registry.html
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>registry</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="registry">
+<h1 class="title">registry</h1>
+<h2 class="subtitle" id="in-memory-image-registration-interface">In-memory image registration interface</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#deletemagickregistry" id="id7">DeleteMagickRegistry</a></li>
+<li><a class="reference internal" href="#getimagefrommagickregistry" id="id8">GetImageFromMagickRegistry</a></li>
+<li><a class="reference internal" href="#getmagickregistry" id="id9">GetMagickRegistry</a></li>
+<li><a class="reference internal" href="#setmagickregistry" id="id10">SetMagickRegistry</a></li>
+</ul>
+</div>
+<div class="section" id="deletemagickregistry">
+<h1><a class="toc-backref" href="#id7">DeleteMagickRegistry</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail DeleteMagickRegistry( const long id );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>DeleteMagickRegistry() deletes an entry in the registry as defined by the
+id. It returns MagickPass if the entry is deleted otherwise MagickFail if
+no entry is found in the registry that matches the id.</p>
+<p>The format of the DeleteMagickRegistry method is:</p>
+<pre class="literal-block">
+MagickPassFail DeleteMagickRegistry( const long id );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>id:</dt>
+<dd>The registry id.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getimagefrommagickregistry">
+<h1><a class="toc-backref" href="#id8">GetImageFromMagickRegistry</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetImageFromMagickRegistry( const char *name, long *id,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>GetImageFromMagickRegistry() gets an image from the registry as defined by
+its name. If the blob that matches the name is not found, NULL is returned.</p>
+<p>The format of the GetImageFromMagickRegistry method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *GetImageFromMagickRegistry( const char *name, long *id,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>name:</dt>
+<dd>The name of the image to retrieve from the registry.</dd>
+<dt>id:</dt>
+<dd>The registry id.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getmagickregistry">
+<h1><a class="toc-backref" href="#id9">GetMagickRegistry</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const void *GetMagickRegistry( const long id, <a class="reference external" href="../api/types.html#registrytype">RegistryType</a> *type, size_t *length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>GetMagickRegistry() gets a blob from the registry as defined by the id. If
+the blob that matches the id is not found, NULL is returned.</p>
+<p>The format of the GetMagickRegistry method is:</p>
+<pre class="literal-block">
+const void *GetMagickRegistry( const long id, <a class="reference external" href="../api/types.html#registrytype">RegistryType</a> *type, size_t *length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>id:</dt>
+<dd>The registry id.</dd>
+<dt>type:</dt>
+<dd>The registry type.</dd>
+<dt>length:</dt>
+<dd>The blob length in number of bytes.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setmagickregistry">
+<h1><a class="toc-backref" href="#id10">SetMagickRegistry</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+long SetMagickRegistry( const <a class="reference external" href="../api/types.html#registrytype">RegistryType</a> type, const void *blob, const size_t length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>SetMagickRegistry() sets a blob into the registry and returns a unique ID.
+If an error occurs, -1 is returned.</p>
+<p>The format of the SetMagickRegistry method is:</p>
+<pre class="literal-block">
+long SetMagickRegistry( const <a class="reference external" href="../api/types.html#registrytype">RegistryType</a> type, const void *blob, const size_t length,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>type:</dt>
+<dd>The registry type.</dd>
+<dt>blob:</dt>
+<dd>The address of a Binary Large OBject.</dd>
+<dt>length:</dt>
+<dd>For a registry type of ImageRegistryType use sizeof(Image)
+otherise the blob length in number of bytes.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/render.html b/www/api/render.html
new file mode 100644
index 0000000..515a81b
--- /dev/null
+++ b/www/api/render.html
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>render</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="render">
+<h1 class="title">render</h1>
+<h2 class="subtitle" id="low-level-methods-to-draw-on-an-image">Low-level methods to draw on an image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#clonedrawinfo" id="id11">CloneDrawInfo</a></li>
+<li><a class="reference internal" href="#destroydrawinfo" id="id12">DestroyDrawInfo</a></li>
+<li><a class="reference internal" href="#drawaffineimage" id="id13">DrawAffineImage</a></li>
+<li><a class="reference internal" href="#drawclippath" id="id14">DrawClipPath</a></li>
+<li><a class="reference internal" href="#drawimage" id="id15">DrawImage</a></li>
+<li><a class="reference internal" href="#drawpatternpath" id="id16">DrawPatternPath</a></li>
+</ul>
+</div>
+<div class="section" id="clonedrawinfo">
+<h1><a class="toc-backref" href="#id11">CloneDrawInfo</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *CloneDrawInfo( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>CloneDrawInfo() makes a copy of the given draw info structure. If NULL
+is specified, a new DrawInfo structure is created initialized to
+default values.</p>
+<p>The format of the CloneDrawInfo method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *CloneDrawInfo( const <a class="reference external" href="../api/types.html#imageinfo">ImageInfo</a> *image_info, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info );
+</pre>
+<dl class="docutils">
+<dt>image_info:</dt>
+<dd>The image info.</dd>
+<dt>draw_info:</dt>
+<dd>The draw info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroydrawinfo">
+<h1><a class="toc-backref" href="#id12">DestroyDrawInfo</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyDrawInfo( <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>DestroyDrawInfo() deallocates memory associated with an DrawInfo
+structure.</p>
+<p>The format of the DestroyDrawInfo method is:</p>
+<pre class="literal-block">
+void DestroyDrawInfo( <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>draw_info:</dt>
+<dd>The draw info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawaffineimage">
+<h1><a class="toc-backref" href="#id13">DrawAffineImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DrawAffineImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *composite,
+ const <a class="reference external" href="../api/types.html#affinematrix">AffineMatrix</a> *affine );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DrawAffineImage() composites the source over the destination image as
+dictated by the affine transform.</p>
+<p>The format of the DrawAffineImage method is:</p>
+<pre class="literal-block">
+unsigned int DrawAffineImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *composite,
+ const <a class="reference external" href="../api/types.html#affinematrix">AffineMatrix</a> *affine );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>image:</dt>
+<dd>The composite image.</dd>
+<dt>affine:</dt>
+<dd>The affine transform.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawclippath">
+<h1><a class="toc-backref" href="#id14">DrawClipPath</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail DrawClipPath( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info,
+ const char *name );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>DrawClipPath() draws the clip path on the image mask.</p>
+<p>The format of the DrawClipPath method is:</p>
+<pre class="literal-block">
+MagickPassFail DrawClipPath( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info,
+ const char *name );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>draw_info:</dt>
+<dd>The draw info.</dd>
+<dt>name:</dt>
+<dd>The name of the clip path.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawimage">
+<h1><a class="toc-backref" href="#id15">DrawImage</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail DrawImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>Use DrawImage() to draw a graphic primitive on your image. The primitive
+may be represented as a string or filename. Precede the filename with an
+&quot;at&quot; sign (&#64;) and the contents of the file are drawn on the image. You
+can affect how text is drawn by setting one or more members of the draw
+info structure.</p>
+<p>Note that this is a legacy interface. Authors of new code should consider
+using the Draw* methods defined by magick/draw.h since they are better
+documented and less error prone.</p>
+<p>The format of the DrawImage method is:</p>
+<pre class="literal-block">
+MagickPassFail DrawImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>draw_info:</dt>
+<dd>The draw info.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpatternpath">
+<h1><a class="toc-backref" href="#id16">DrawPatternPath</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail DrawPatternPath( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info,
+ const char *name, <a class="reference external" href="../api/types.html#image">Image</a> ** pattern );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>DrawPatternPath() draws a pattern.</p>
+<p>The format of the DrawPatternPath method is:</p>
+<pre class="literal-block">
+MagickPassFail DrawPatternPath( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info,
+ const char *name, <a class="reference external" href="../api/types.html#image">Image</a> ** pattern );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>draw_info:</dt>
+<dd>The draw info.</dd>
+<dt>name:</dt>
+<dd>The pattern name.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/resize.html b/www/api/resize.html
new file mode 100644
index 0000000..78259f1
--- /dev/null
+++ b/www/api/resize.html
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>resize</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="resize">
+<h1 class="title">resize</h1>
+<h2 class="subtitle" id="resize-an-image">Resize an image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#magnifyimage" id="id11">MagnifyImage</a></li>
+<li><a class="reference internal" href="#minifyimage" id="id12">MinifyImage</a></li>
+<li><a class="reference internal" href="#resizeimage" id="id13">ResizeImage</a></li>
+<li><a class="reference internal" href="#sampleimage" id="id14">SampleImage</a></li>
+<li><a class="reference internal" href="#scaleimage" id="id15">ScaleImage</a></li>
+<li><a class="reference internal" href="#thumbnailimage" id="id16">ThumbnailImage</a></li>
+</ul>
+</div>
+<div class="section" id="magnifyimage">
+<h1><a class="toc-backref" href="#id11">MagnifyImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MagnifyImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>MagnifyImage() is a convenience method that scales an image proportionally
+to twice its size.</p>
+<p>The format of the MagnifyImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MagnifyImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="minifyimage">
+<h1><a class="toc-backref" href="#id12">MinifyImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MinifyImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>MinifyImage() is a convenience method that scales an image proportionally
+to half its size.</p>
+<p>The format of the MinifyImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MinifyImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="resizeimage">
+<h1><a class="toc-backref" href="#id13">ResizeImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ResizeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#filtertype">FilterTypes</a> filter, const double blur,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>ResizeImage() scales an image to the desired dimensions with one of these
+filters:</p>
+<p>Bessel Blackman Box
+Catrom Cubic Gaussian
+Hanning Hermite Lanczos
+Mitchell Point Quandratic
+Sinc Triangle</p>
+<p>Most of the filters are FIR (finite impulse response), however, Bessel,
+Gaussian, and Sinc are IIR (infinite impulse response). Bessel and Sinc
+are windowed (brought down to zero) with the Blackman filter.</p>
+<p>ResizeImage() was inspired by Paul Heckbert's zoom program.</p>
+<p>The format of the ResizeImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ResizeImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns, const unsigned long rows,
+ const <a class="reference external" href="../api/types.html#filtertype">FilterTypes</a> filter, const double blur,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the scaled image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the scaled image.</dd>
+<dt>filter:</dt>
+<dd>Image filter to use.</dd>
+<dt>blur:</dt>
+<dd>The blur factor where &gt; 1 is blurry, &lt; 1 is sharp.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="sampleimage">
+<h1><a class="toc-backref" href="#id14">SampleImage</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SampleImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns,
+ const unsigned long rows, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>SampleImage() scales an image to the desired dimensions with pixel
+sampling. Unlike other scaling methods, this method does not introduce
+any additional color into the scaled image.</p>
+<p>The format of the SampleImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *SampleImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns,
+ const unsigned long rows, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the sampled image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the sampled image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="scaleimage">
+<h1><a class="toc-backref" href="#id15">ScaleImage</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ScaleImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns,
+ const unsigned long rows, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>ScaleImage() changes the size of an image to the given dimensions.</p>
+<p>The format of the ScaleImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ScaleImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns,
+ const unsigned long rows, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the scaled image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the scaled image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="thumbnailimage">
+<h1><a class="toc-backref" href="#id16">ThumbnailImage</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ThumbnailImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns,
+ const unsigned long rows, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>ThumbnailImage() changes the size of an image to the given dimensions.
+This method was designed by Bob Friesenhahn as a low cost thumbnail
+generator.</p>
+<p>The format of the ThumbnailImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ThumbnailImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const unsigned long columns,
+ const unsigned long rows, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the scaled image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the scaled image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/resource.html b/www/api/resource.html
new file mode 100644
index 0000000..fc95f8e
--- /dev/null
+++ b/www/api/resource.html
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>resource</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="resource">
+<h1 class="title">resource</h1>
+<h2 class="subtitle" id="set-resource-consumption-limits-e-g-memory">Set resource consumption limits (e.g. memory)</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#acquiremagickresource" id="id11">AcquireMagickResource</a></li>
+<li><a class="reference internal" href="#getmagickresource" id="id12">GetMagickResource</a></li>
+<li><a class="reference internal" href="#getmagickresourcelimit" id="id13">GetMagickResourceLimit</a></li>
+<li><a class="reference internal" href="#liberatemagickresource" id="id14">LiberateMagickResource</a></li>
+<li><a class="reference internal" href="#listmagickresourceinfo" id="id15">ListMagickResourceInfo</a></li>
+<li><a class="reference internal" href="#setmagickresourcelimit" id="id16">SetMagickResourceLimit</a></li>
+</ul>
+</div>
+<div class="section" id="acquiremagickresource">
+<h1><a class="toc-backref" href="#id11">AcquireMagickResource</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail AcquireMagickResource( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type, const magick_int64_t size );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AcquireMagickResource() acquires resources of the specified type. True is
+returned if the specified resource is available otherwise False.</p>
+<p>The format of the AcquireMagickResource() method is:</p>
+<pre class="literal-block">
+MagickPassFail AcquireMagickResource( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type, const magick_int64_t size );
+</pre>
+<dl class="docutils">
+<dt>type:</dt>
+<dd>The type of resource.</dd>
+<dt>size:</dt>
+<dd>The number of bytes needed from for this resource.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getmagickresource">
+<h1><a class="toc-backref" href="#id12">GetMagickResource</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+magick_uint64_t GetMagickResource( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>GetMagickResource() returns the current consumption level for the
+specified resource type.</p>
+<p>The format of the GetMagickResource() method is:</p>
+<pre class="literal-block">
+magick_uint64_t GetMagickResource( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>type:</dt>
+<dd>The type of resource.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getmagickresourcelimit">
+<h1><a class="toc-backref" href="#id13">GetMagickResourceLimit</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+magick_uint64_t GetMagickResourceLimit( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>GetMagickResourceLimit() returns the current maximum limit for the
+specified resource type.</p>
+<p>The format of the GetMagickResourceLimit() method is:</p>
+<pre class="literal-block">
+magick_uint64_t GetMagickResourceLimit( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>type:</dt>
+<dd>The type of resource.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="liberatemagickresource">
+<h1><a class="toc-backref" href="#id14">LiberateMagickResource</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void LiberateMagickResource( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type, const magick_int64_t size );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>LiberateMagickResource() liberates resources of the specified type.</p>
+<p>The format of the LiberateMagickResource() method is:</p>
+<pre class="literal-block">
+void LiberateMagickResource( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type, const magick_int64_t size );
+</pre>
+<dl class="docutils">
+<dt>type:</dt>
+<dd>The type of resource.</dd>
+<dt>size:</dt>
+<dd>The size of the resource.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="listmagickresourceinfo">
+<h1><a class="toc-backref" href="#id15">ListMagickResourceInfo</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int ListMagickResourceInfo( FILE *file, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>Method ListMagickResourceInfo lists the resource info to a file.</p>
+<p>The format of the ListMagickResourceInfo method is:</p>
+<pre class="literal-block">
+unsigned int ListMagickResourceInfo( FILE *file, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows.</p>
+<dl class="docutils">
+<dt>file:</dt>
+<dd>An pointer to a FILE.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="setmagickresourcelimit">
+<h1><a class="toc-backref" href="#id16">SetMagickResourceLimit</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void SetMagickResourceLimit( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type, const unsigned long limit );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>SetMagickResourceLimit() sets the limit for a particular resource. The
+units for resource types are as follows:</p>
+<p>DiskResource -- Bytes
+FileResource -- Open files
+MapResource -- Bytes
+MemoryResource -- Bytes
+PixelsResource -- Pixels
+ThreadsResource -- Threads
+WidthResource -- Pixels
+HeightResource -- Pixels</p>
+<p>The format of the SetMagickResourceLimit() method is:</p>
+<pre class="literal-block">
+void SetMagickResourceLimit( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type, const unsigned long limit );
+</pre>
+<dl class="docutils">
+<dt>type:</dt>
+<dd>The type of resource.</dd>
+<dt>limit:</dt>
+<dd>The maximum limit for the resource.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/segment.html b/www/api/segment.html
new file mode 100644
index 0000000..4ca77ec
--- /dev/null
+++ b/www/api/segment.html
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>segment</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="segment">
+<h1 class="title">segment</h1>
+<h2 class="subtitle" id="segment-and-image-with-thresholding-using-the-fuzzy-c-means-method">Segment and image with thresholding using the fuzzy c-means method</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#segmentimage" id="id1">SegmentImage</a></li>
+</ul>
+</div>
+<div class="section" id="segmentimage">
+<h1><a class="toc-backref" href="#id1">SegmentImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail SegmentImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> colorspace,
+ const unsigned int verbose, const double cluster_threshold,
+ const double smoothing_threshold );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Method SegmentImage segment an image by analyzing the histograms of the
+color components and identifying units that are homogeneous with the fuzzy
+c-means technique.</p>
+<p>Specify cluster threshold as the number of pixels in each cluster must
+exceed the the cluster threshold to be considered valid. Smoothing
+threshold eliminates noise in the second derivative of the histogram.
+As the value is increased, you can expect a smoother second derivative.
+The default is 1.5.</p>
+<p>The format of the SegmentImage method is:</p>
+<pre class="literal-block">
+MagickPassFail SegmentImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> colorspace,
+ const unsigned int verbose, const double cluster_threshold,
+ const double smoothing_threshold );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>Specifies a pointer to an Image structure; returned from
+ReadImage.</dd>
+<dt>colorspace:</dt>
+<dd>An unsigned integer value that indicates the colorspace.
+Empirical evidence suggests that distances in YUV or YIQ correspond to
+perceptual color differences more closely than do distances in RGB
+space. The image is then returned to RGB colorspace after color
+reduction.</dd>
+<dt>verbose:</dt>
+<dd>A value greater than zero prints detailed information about
+the identified classes.</dd>
+<dt>cluster_threshold:</dt>
+<dd>The minimum number of total pixels contained
+in a hexahedra before it can be considered valid (expressed as a
+percentage of total pixels). This is used to eliminate seldom
+used colors.</dd>
+<dt>smoothing_threshold:</dt>
+<dd>If the absolute value of a second derivative
+point is less than smoothing_threshold then that derivative point
+is ignored (i.e. set to 0) while evaluating zero crossings. This
+causes small variations (could be noise) to be ignored.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/shear.html b/www/api/shear.html
new file mode 100644
index 0000000..0bca62a
--- /dev/null
+++ b/www/api/shear.html
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>shear</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="shear">
+<h1 class="title">shear</h1>
+<h2 class="subtitle" id="rotate-image-shear-image-or-apply-a-2d-affine-transformation">Rotate image, shear image, or apply a 2D affine transformation</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#affinetransformimage" id="id7">AffineTransformImage</a></li>
+<li><a class="reference internal" href="#autoorientimage" id="id8">AutoOrientImage</a></li>
+<li><a class="reference internal" href="#rotateimage" id="id9">RotateImage</a></li>
+<li><a class="reference internal" href="#shearimage" id="id10">ShearImage</a></li>
+</ul>
+</div>
+<div class="section" id="affinetransformimage">
+<h1><a class="toc-backref" href="#id7">AffineTransformImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AffineTransformImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#affinematrix">AffineMatrix</a> *affine,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>AffineTransformImage() transforms an image as dictated by the affine matrix.
+It allocates the memory necessary for the new Image structure and returns
+a pointer to the new image.</p>
+<p>The format of the AffineTransformImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AffineTransformImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#affinematrix">AffineMatrix</a> *affine,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>affine:</dt>
+<dd>The affine transform.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="autoorientimage">
+<h1><a class="toc-backref" href="#id8">AutoOrientImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AutoOrientImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const OrientationType current_orientation,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>AutoOrientImage() returns an image adjusted so that its orientation is
+suitable for viewing (i.e. top-left orientation).</p>
+<p>The format of the AutoOrientImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *AutoOrientImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const OrientationType current_orientation,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>current_orientation:</dt>
+<dd>Current image orientation (normally same as
+image-&gt;orientation).</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="rotateimage">
+<h1><a class="toc-backref" href="#id9">RotateImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *RotateImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double degrees,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>Method RotateImage creates a new image that is a rotated copy of an
+existing one. Positive angles rotate counter-clockwise (right-hand rule),
+while negative angles rotate clockwise. Rotated images are usually larger
+than the originals and have 'empty' triangular corners. X axis. Empty
+triangles left over from shearing the image are filled with the color
+specified by the image background_color. RotateImage allocates the memory
+necessary for the new Image structure and returns a pointer to the new
+image.</p>
+<p>Method RotateImage is based on the paper &quot;A Fast Algorithm for General
+Raster Rotatation&quot; by Alan W. Paeth. RotateImage is adapted from a similar
+method based on the Paeth paper written by Michael Halle of the Spatial
+Imaging Group, MIT Media Lab.</p>
+<p>The format of the RotateImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *RotateImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double degrees,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method RotateImage returns a pointer to the image after
+rotating. A null image is returned if there is a memory shortage.</dd>
+<dt>image:</dt>
+<dd>The image; returned from
+ReadImage.</dd>
+<dt>degrees:</dt>
+<dd>Specifies the number of degrees to rotate the image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="shearimage">
+<h1><a class="toc-backref" href="#id10">ShearImage</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ShearImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double x_shear, const double y_shear,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>Method ShearImage creates a new image that is a shear_image copy of an
+existing one. Shearing slides one edge of an image along the X or Y
+axis, creating a parallelogram. An X direction shear slides an edge
+along the X axis, while a Y direction shear slides an edge along the Y
+axis. The amount of the shear is controlled by a shear angle. For X
+direction shears, x_shear is measured relative to the Y axis, and
+similarly, for Y direction shears y_shear is measured relative to the
+X axis. Empty triangles left over from shearing the image are filled
+with the color defined by the pixel at location (0,0). ShearImage
+allocates the memory necessary for the new Image structure and returns
+a pointer to the new image.</p>
+<p>Method ShearImage is based on the paper &quot;A Fast Algorithm for General
+Raster Rotatation&quot; by Alan W. Paeth.</p>
+<p>The format of the ShearImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ShearImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const double x_shear, const double y_shear,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method ShearImage returns a pointer to the image after
+rotating. A null image is returned if there is a memory shortage.</dd>
+<dt>image:</dt>
+<dd>The image; returned from
+ReadImage.</dd>
+<dt>x_shear, y_shear:</dt>
+<dd>Specifies the number of degrees to shear the image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/signature.html b/www/api/signature.html
new file mode 100644
index 0000000..8fc7c40
--- /dev/null
+++ b/www/api/signature.html
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>signature</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="signature">
+<h1 class="title">signature</h1>
+<h2 class="subtitle" id="add-a-digital-signature-to-the-image">Add a digital signature to the image</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#finalizesignature" id="id9">FinalizeSignature</a></li>
+<li><a class="reference internal" href="#getsignatureinfo" id="id10">GetSignatureInfo</a></li>
+<li><a class="reference internal" href="#signatureimage" id="id11">SignatureImage</a></li>
+<li><a class="reference internal" href="#transformsignature" id="id12">TransformSignature</a></li>
+<li><a class="reference internal" href="#updatesignature" id="id13">UpdateSignature</a></li>
+</ul>
+</div>
+<div class="section" id="finalizesignature">
+<h1><a class="toc-backref" href="#id9">FinalizeSignature</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+FinalizeSignature( <a class="reference external" href="../api/types.html#signatureinfo">SignatureInfo</a> *signature_info );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Method FinalizeSignature finalizes the SHA message digest computation.</p>
+<p>The format of the FinalizeSignature method is:</p>
+<pre class="literal-block">
+FinalizeSignature( <a class="reference external" href="../api/types.html#signatureinfo">SignatureInfo</a> *signature_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>signature_info:</dt>
+<dd>The address of a structure of type SignatureInfo.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="getsignatureinfo">
+<h1><a class="toc-backref" href="#id10">GetSignatureInfo</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+GetSignatureInfo( <a class="reference external" href="../api/types.html#signatureinfo">SignatureInfo</a> *signature_info );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>Method GetSignatureInfo initializes the SHA message digest structure.</p>
+<p>The format of the GetSignatureInfo method is:</p>
+<pre class="literal-block">
+GetSignatureInfo( <a class="reference external" href="../api/types.html#signatureinfo">SignatureInfo</a> *signature_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>signature_info:</dt>
+<dd>The address of a structure of type SignatureInfo.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="signatureimage">
+<h1><a class="toc-backref" href="#id11">SignatureImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int SignatureImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>SignatureImage() computes a message digest from an image pixel stream with
+an implementation of the NIST SHA-256 Message Digest algorithm. This
+signature uniquely identifies the image and is convenient for determining
+if an image has been modified or whether two images are identical.</p>
+<p>The format of the SignatureImage method is:</p>
+<pre class="literal-block">
+unsigned int SignatureImage( <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="transformsignature">
+<h1><a class="toc-backref" href="#id12">TransformSignature</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+TransformSignature( <a class="reference external" href="../api/types.html#signatureinfo">SignatureInfo</a> *signature_info );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>TransformSignature() transforms the SHA message digest.</p>
+<p>The format of the TransformSignature method is:</p>
+<pre class="literal-block">
+TransformSignature( <a class="reference external" href="../api/types.html#signatureinfo">SignatureInfo</a> *signature_info );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>signature_info:</dt>
+<dd>The address of a structure of type SignatureInfo.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="updatesignature">
+<h1><a class="toc-backref" href="#id13">UpdateSignature</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+UpdateSignature( <a class="reference external" href="../api/types.html#signatureinfo">SignatureInfo</a> *signature_info, const unsigned char *message,
+ const size_t length );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>UpdateSignature() updates the SHA message digest.</p>
+<p>The format of the UpdateSignature method is:</p>
+<pre class="literal-block">
+UpdateSignature( <a class="reference external" href="../api/types.html#signatureinfo">SignatureInfo</a> *signature_info, const unsigned char *message,
+ const size_t length );
+</pre>
+<dl class="docutils">
+<dt>signature_info:</dt>
+<dd>The address of a structure of type SignatureInfo.</dd>
+<dt>message:</dt>
+<dd>the message</dd>
+<dt>length:</dt>
+<dd>The length of the message.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/statistics.html b/www/api/statistics.html
new file mode 100644
index 0000000..d89ca35
--- /dev/null
+++ b/www/api/statistics.html
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>statistics</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="statistics">
+<h1 class="title">statistics</h1>
+<h2 class="subtitle" id="compute-image-statistics">Compute image statistics</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#getimagestatistics" id="id1">GetImageStatistics</a></li>
+</ul>
+</div>
+<div class="section" id="getimagestatistics">
+<h1><a class="toc-backref" href="#id1">GetImageStatistics</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail GetImageStatistics( const <a class="reference external" href="../api/types.html#image">Image</a> *image,
+ ImageStatistics *statistics <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>GetImageStatistics computes common statistics (currently maximum, minimum,
+mean and standard deviation) for the available image channels. The
+per-channel values are returned in an ImageStatistics structure. Statistics
+are normalized to the range 0.0 to 1.0. Multiply values by MaxRGB to obtain
+the statistics in quantum units. Statistics for non-existent channels are
+set to zero.</p>
+<p>The format of the GetImageStatistics method is:</p>
+<pre class="literal-block">
+MagickPassFail GetImageStatistics( const <a class="reference external" href="../api/types.html#image">Image</a> *image,
+ ImageStatistics *statistics <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>statistics:</dt>
+<dd>An ImageStatistics structure to update with statistics.</dd>
+<dt>exception:</dt>
+<dd>Any errors are reported here.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/texture.html b/www/api/texture.html
new file mode 100644
index 0000000..9202069
--- /dev/null
+++ b/www/api/texture.html
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>texture</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="texture">
+<h1 class="title">texture</h1>
+<h2 class="subtitle" id="image-texture-functions">Image texture functions</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#constitutetextureimage" id="id3">ConstituteTextureImage</a></li>
+<li><a class="reference internal" href="#textureimage" id="id4">TextureImage</a></li>
+</ul>
+</div>
+<div class="section" id="constitutetextureimage">
+<h1><a class="toc-backref" href="#id3">ConstituteTextureImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ConstituteTextureImage( unsigned long columns, unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *texture, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>ConstituteTextureImage() returns a new image canvas based on repeatedly
+tiling the texture image across and down the new image canvas. The
+returned image properties are similar to the texture image properties.</p>
+<p>The format of the TextureImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ConstituteTextureImage( unsigned long columns, unsigned long rows,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *texture, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>columns:</dt>
+<dd>The number of columns in the new image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the new image.</dd>
+<dt>texture:</dt>
+<dd>The texture image to layer on the background.</dd>
+<dt>exceptions:</dt>
+<dd>Any errors are reported here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="textureimage">
+<h1><a class="toc-backref" href="#id4">TextureImage</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail TextureImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *texture );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>TextureImage() repeatedly tiles the texture image across and down the image
+canvas. If the image canvas includes a matte channel, then the tile is
+alpha-composited &quot;under&quot; the image and the matte channel is removed.
+MagickFail is returned if an error is encountered.</p>
+<p>The format of the TextureImage method is:</p>
+<pre class="literal-block">
+MagickPassFail TextureImage( <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#image">Image</a> *texture );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>texture:</dt>
+<dd>This image is the texture to layer on the background.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/transform.html b/www/api/transform.html
new file mode 100644
index 0000000..4a32113
--- /dev/null
+++ b/www/api/transform.html
@@ -0,0 +1,400 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>transform</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="transform">
+<h1 class="title">transform</h1>
+<h2 class="subtitle" id="crop-flip-flop-roll-coalesce-etc">Crop, flip, flop, roll, coalesce, etc.</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#chopimage" id="id23">ChopImage</a></li>
+<li><a class="reference internal" href="#coalesceimages" id="id24">CoalesceImages</a></li>
+<li><a class="reference internal" href="#cropimage" id="id25">CropImage</a></li>
+<li><a class="reference internal" href="#deconstructimages" id="id26">DeconstructImages</a></li>
+<li><a class="reference internal" href="#extentimage" id="id27">ExtentImage</a></li>
+<li><a class="reference internal" href="#flattenimage" id="id28">FlattenImage</a></li>
+<li><a class="reference internal" href="#flipimage" id="id29">FlipImage</a></li>
+<li><a class="reference internal" href="#flopimage" id="id30">FlopImage</a></li>
+<li><a class="reference internal" href="#mosaicimages" id="id31">MosaicImages</a></li>
+<li><a class="reference internal" href="#rollimage" id="id32">RollImage</a></li>
+<li><a class="reference internal" href="#shaveimage" id="id33">ShaveImage</a></li>
+<li><a class="reference internal" href="#transformimage" id="id34">TransformImage</a></li>
+</ul>
+</div>
+<div class="section" id="chopimage">
+<h1><a class="toc-backref" href="#id23">ChopImage</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ChopImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image,
+ const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *chop_info <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Chop() removes a region of an image and collapses the image to occupy the
+removed portion.</p>
+<p>The format of the ChopImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ChopImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image,
+ const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *chop_info <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>chop_info:</dt>
+<dd>Define the region of the image to chop.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="coalesceimages">
+<h1><a class="toc-backref" href="#id24">CoalesceImages</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CoalesceImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>CoalesceImages() composites a set of images while respecting any page
+offsets and disposal methods. GIF, MIFF, and MNG animation sequences
+typically start with an image background and each subsequent image
+varies in size and offset. CoalesceImages() returns a new sequence
+where each image in the sequence is the same size as the first and
+composited with the next image in the sequence.</p>
+<p>The format of the CoalesceImages method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CoalesceImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image sequence.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="cropimage">
+<h1><a class="toc-backref" href="#id25">CropImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CropImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *geometry,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>Use CropImage() to extract a region of the image starting at the offset
+defined by geometry. As a special feature, if the geometry &quot;0x0&quot; is
+is passed, GetImageBoundingBox() is used to locate the edges of the
+image and the image is cropped (&quot;trimmed&quot;) to that boundary.</p>
+<p>The format of the CropImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *CropImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *geometry,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>geometry:</dt>
+<dd>Define the region of the image to crop with members
+x, y, width, and height.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="deconstructimages">
+<h1><a class="toc-backref" href="#id26">DeconstructImages</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *DeconstructImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>DeconstructImages() compares each image with the next in a sequence and
+returns the maximum bounding region of any pixel differences it discovers.</p>
+<p>The format of the DeconstructImages method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *DeconstructImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="extentimage">
+<h1><a class="toc-backref" href="#id27">ExtentImage</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ExtentImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *geometry,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>Use ExtentImage() to change the image dimensions as specified by geometry
+width and height. The existing image content is composited at the position
+specified by geometry x and y using the image compose method. Existing
+image content which falls outside the bounds of the new image dimensions
+is discarded.</p>
+<p>The format of the ExtentImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ExtentImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *geometry,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>geometry:</dt>
+<dd>Define the new image dimension with width and height, and
+the top left coordinate to place the existing image content with
+x and y.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="flattenimage">
+<h1><a class="toc-backref" href="#id28">FlattenImage</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *FlattenImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>Method FlattenImage merges a sequence of images. This is useful for
+combining Photoshop layers into a single image.</p>
+<p>The format of the FlattenImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *FlattenImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image sequence.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="flipimage">
+<h1><a class="toc-backref" href="#id29">FlipImage</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *FlipImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>FlipImage() creates a vertical mirror image by reflecting the pixels
+around the central x-axis.</p>
+<p>The format of the FlipImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *FlipImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="flopimage">
+<h1><a class="toc-backref" href="#id30">FlopImage</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *FlopImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>FlopImage() creates a horizontal mirror image by reflecting the pixels
+around the central y-axis.</p>
+<p>The format of the FlopImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *FlopImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="mosaicimages">
+<h1><a class="toc-backref" href="#id31">MosaicImages</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MosaicImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>MosaicImages() inlays an image sequence to form a single coherent picture.
+It returns a single image with each image in the sequence composited at
+the location defined by the page member of the image structure.</p>
+<p>The format of the MosaicImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *MosaicImages( const <a class="reference external" href="../api/types.html#image">Image</a> *image, <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="rollimage">
+<h1><a class="toc-backref" href="#id32">RollImage</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *RollImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x_offset, const long y_offset,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>RollImage() offsets an image as defined by x_offset and y_offset.</p>
+<p>The format of the RollImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *RollImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const long x_offset, const long y_offset,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>x_offset:</dt>
+<dd>The number of columns to roll in the horizontal direction.</dd>
+<dt>y_offset:</dt>
+<dd>The number of rows to roll in the vertical direction.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="shaveimage">
+<h1><a class="toc-backref" href="#id33">ShaveImage</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ShaveImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *shave_info,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>Method ShaveImage shaves pixels from the image edges. It allocates the
+memory necessary for the new Image structure and returns a pointer to the
+new image.</p>
+<p>The format of the ShaveImage method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#image">Image</a> *ShaveImage( const <a class="reference external" href="../api/types.html#image">Image</a> *image, const <a class="reference external" href="../api/types.html#rectangleinfo">RectangleInfo</a> *shave_info,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>shave_image:</dt>
+<dd>Method ShaveImage returns a pointer to the shaved
+image. A null image is returned if there is a memory shortage or
+if the image width or height is zero.</dd>
+<dt>image:</dt>
+<dd>The image.</dd>
+<dt>shave_info:</dt>
+<dd>Specifies a pointer to a RectangleInfo which defines the
+region of the image to shave.</dd>
+<dt>exception:</dt>
+<dd>Return any errors or warnings in this structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="transformimage">
+<h1><a class="toc-backref" href="#id34">TransformImage</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void TransformImage( <a class="reference external" href="../api/types.html#image">Image</a> ** image, const char *crop_geometry,
+ const char *image_geometry );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>TransformImage() is a convenience method that behaves like ResizeImage() or
+CropImage() but accepts scaling and/or cropping information as a region
+geometry specification. If the operation fails, the original image handle
+is returned.</p>
+<p>The format of the TransformImage method is:</p>
+<pre class="literal-block">
+void TransformImage( <a class="reference external" href="../api/types.html#image">Image</a> ** image, const char *crop_geometry,
+ const char *image_geometry );
+</pre>
+<dl class="docutils">
+<dt>image:</dt>
+<dd>The image The transformed image is returned as this parameter.</dd>
+<dt>crop_geometry:</dt>
+<dd>A crop geometry string. This geometry defines a
+subregion of the image to crop.</dd>
+<dt>image_geometry:</dt>
+<dd>An image geometry string. This geometry defines the
+final size of the image.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/types.html b/www/api/types.html
new file mode 100644
index 0000000..534c124
--- /dev/null
+++ b/www/api/types.html
@@ -0,0 +1,2844 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Types</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-types">
+<h1 class="title">GraphicsMagick Types</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#affinematrix" id="id1">AffineMatrix</a></li>
+<li><a class="reference internal" href="#blobinfo" id="id2">BlobInfo</a></li>
+<li><a class="reference internal" href="#cache" id="id3">Cache</a></li>
+<li><a class="reference internal" href="#channeltype" id="id4">ChannelType</a></li>
+<li><a class="reference internal" href="#chromaticityinfo" id="id5">ChromaticityInfo</a></li>
+<li><a class="reference internal" href="#classtype" id="id6">ClassType</a></li>
+<li><a class="reference internal" href="#clippathunits" id="id7">ClipPathUnits</a></li>
+<li><a class="reference internal" href="#colorpacket" id="id8">ColorPacket</a></li>
+<li><a class="reference internal" href="#colorspacetype" id="id9">ColorspaceType</a></li>
+<li><a class="reference internal" href="#compliancetype" id="id10">ComplianceType</a></li>
+<li><a class="reference internal" href="#compositeoperator" id="id11">CompositeOperator</a></li>
+<li><a class="reference internal" href="#compressiontype" id="id12">CompressionType</a></li>
+<li><a class="reference internal" href="#decorationtype" id="id13">DecorationType</a></li>
+<li><a class="reference internal" href="#drawcontext" id="id14">DrawContext</a></li>
+<li><a class="reference internal" href="#drawinfo" id="id15">DrawInfo</a></li>
+<li><a class="reference internal" href="#endiantype" id="id16">EndianType</a></li>
+<li><a class="reference internal" href="#errorhandler" id="id17">ErrorHandler</a></li>
+<li><a class="reference internal" href="#exceptioninfo" id="id18">ExceptionInfo</a></li>
+<li><a class="reference internal" href="#exceptiontype" id="id19">ExceptionType</a></li>
+<li><a class="reference internal" href="#fillrule" id="id20">FillRule</a></li>
+<li><a class="reference internal" href="#filtertypes" id="id21">FilterTypes</a></li>
+<li><a class="reference internal" href="#frameinfo" id="id22">FrameInfo</a></li>
+<li><a class="reference internal" href="#gravitytype" id="id23">GravityType</a></li>
+<li><a class="reference internal" href="#image" id="id24">Image</a></li>
+<li><a class="reference internal" href="#imageinfo" id="id25">ImageInfo</a></li>
+<li><a class="reference internal" href="#imagetype" id="id26">ImageType</a></li>
+<li><a class="reference internal" href="#indexpacket" id="id27">IndexPacket</a></li>
+<li><a class="reference internal" href="#interlacetype" id="id28">InterlaceType</a></li>
+<li><a class="reference internal" href="#layertype" id="id29">LayerType</a></li>
+<li><a class="reference internal" href="#magickinfo" id="id30">MagickInfo</a></li>
+<li><a class="reference internal" href="#monitorhandler" id="id31">MonitorHandler</a></li>
+<li><a class="reference internal" href="#montageinfo" id="id32">MontageInfo</a></li>
+<li><a class="reference internal" href="#noisetype" id="id33">NoiseType</a></li>
+<li><a class="reference internal" href="#orientationtype" id="id34">OrientationType</a></li>
+<li><a class="reference internal" href="#paintmethod" id="id35">PaintMethod</a></li>
+<li><a class="reference internal" href="#pixelpacket" id="id36">PixelPacket</a></li>
+<li><a class="reference internal" href="#pointinfo" id="id37">PointInfo</a></li>
+<li><a class="reference internal" href="#profileinfo" id="id38">ProfileInfo</a></li>
+<li><a class="reference internal" href="#quantizeinfo" id="id39">QuantizeInfo</a></li>
+<li><a class="reference internal" href="#quantum" id="id40">Quantum</a></li>
+<li><a class="reference internal" href="#quantumtype" id="id41">QuantumType</a></li>
+<li><a class="reference internal" href="#rectangleinfo" id="id42">RectangleInfo</a></li>
+<li><a class="reference internal" href="#registrytype" id="id43">RegistryType</a></li>
+<li><a class="reference internal" href="#renderingintent" id="id44">RenderingIntent</a></li>
+<li><a class="reference internal" href="#resolutiontype" id="id45">ResolutionType</a></li>
+<li><a class="reference internal" href="#resourcetype" id="id46">ResourceType</a></li>
+<li><a class="reference internal" href="#segmentinfo" id="id47">SegmentInfo</a></li>
+<li><a class="reference internal" href="#signatureinfo" id="id48">SignatureInfo</a></li>
+<li><a class="reference internal" href="#storagetype" id="id49">StorageType</a></li>
+<li><a class="reference internal" href="#streamhandler" id="id50">StreamHandler</a></li>
+<li><a class="reference internal" href="#stretchtype" id="id51">StretchType</a></li>
+<li><a class="reference internal" href="#styletype" id="id52">StyleType</a></li>
+<li><a class="reference internal" href="#typemetric" id="id53">TypeMetric</a></li>
+<li><a class="reference internal" href="#viewinfo" id="id54">ViewInfo</a></li>
+<li><a class="reference internal" href="#virtualpixelmethod" id="id55">VirtualPixelMethod</a></li>
+<li><a class="reference internal" href="#magickxresourceinfo" id="id56">MagickXResourceInfo</a></li>
+</ul>
+</div>
+<div class="section" id="affinematrix">
+<h1><a class="toc-backref" href="#id1">AffineMatrix</a></h1>
+<p>AffineMatrix defines a 2D affine matrix transform.</p>
+<pre class="literal-block">
+typedef struct _AffineMatrix
+{
+ double
+ sx,
+ rx,
+ ry,
+ sy,
+ tx,
+ ty;
+} AffineMatrix;
+</pre>
+</div>
+<div class="section" id="blobinfo">
+<h1><a class="toc-backref" href="#id2">BlobInfo</a></h1>
+<p>BlobInfo is an opaque pointer reference to the internal structure of an
+I/O blob handle.</p>
+</div>
+<div class="section" id="cache">
+<h1><a class="toc-backref" href="#id3">Cache</a></h1>
+<pre class="literal-block">
+typedef void
+ *Cache;
+</pre>
+</div>
+<div class="section" id="channeltype">
+<h1><a class="toc-backref" href="#id4">ChannelType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UndefinedChannel,
+ RedChannel, /* RGB Red channel */
+ CyanChannel, /* CMYK Cyan channel */
+ GreenChannel, /* RGB Green channel */
+ MagentaChannel, /* CMYK Magenta channel */
+ BlueChannel, /* RGB Blue channel */
+ YellowChannel, /* CMYK Yellow channel */
+ OpacityChannel, /* Opacity channel */
+ BlackChannel, /* CMYK Black (K) channel */
+ MatteChannel, /* Same as Opacity channel (deprecated) */
+ AllChannels, /* Color channels */
+ GrayChannel /* Color channels represent an intensity. */
+} ChannelType;
+</pre>
+</div>
+<div class="section" id="chromaticityinfo">
+<h1><a class="toc-backref" href="#id5">ChromaticityInfo</a></h1>
+<p>The ChromaticityInfo structure is used to represent chromaticity
+(colorspace primary coordinates in xy space) values for images in
+GraphicsMagick.</p>
+<p>The members of the ChromaticityInfo structure are shown in the following
+table:</p>
+<table border="1" class="docutils">
+<caption>ChromaticityInfo Structure Members</caption>
+<colgroup>
+<col width="20%" />
+<col width="12%" />
+<col width="68%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>red_primary</td>
+<td>PointInfo</td>
+<td>Chromaticity red primary point (e.g. x=0.64, y=0.33)</td>
+</tr>
+<tr><td>green_primary</td>
+<td>PointInfo</td>
+<td>Chromaticity green primary point (e.g. x=0.3, y=0.6)</td>
+</tr>
+<tr><td>blue_primary</td>
+<td>PointInfo</td>
+<td>Chromaticity blue primary point (e.g. x=0.15, y=0.06)</td>
+</tr>
+<tr><td>white_point</td>
+<td>PointInfo</td>
+<td>Chromaticity white point (e.g. x=0.3127, y=0.329)</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="classtype">
+<h1><a class="toc-backref" href="#id6">ClassType</a></h1>
+<p>ClassType enumeration specifies the image storage class.</p>
+<table border="1" class="docutils">
+<caption>ClassType</caption>
+<colgroup>
+<col width="17%" />
+<col width="83%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UndefinedClass</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>DirectClass</td>
+<td>Image is composed of pixels which represent literal color values.</td>
+</tr>
+<tr><td>PseudoClass</td>
+<td>Image is composed of pixels which specify an index in a color palette.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="clippathunits">
+<h1><a class="toc-backref" href="#id7">ClipPathUnits</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UserSpace,
+ UserSpaceOnUse,
+ ObjectBoundingBox
+} ClipPathUnits;
+</pre>
+</div>
+<div class="section" id="colorpacket">
+<h1><a class="toc-backref" href="#id8">ColorPacket</a></h1>
+<pre class="literal-block">
+typedef struct _ColorPacket
+{
+ PixelPacket
+ pixel;
+
+ unsigned short
+ index;
+
+ unsigned long
+ count;
+} ColorPacket;
+</pre>
+</div>
+<div class="section" id="colorspacetype">
+<h1><a class="toc-backref" href="#id9">ColorspaceType</a></h1>
+<p>The ColorspaceType enumeration is used to specify the colorspace that
+quantization (color reduction and mapping) is done under or to specify
+the colorspace when encoding an output image. Colorspaces are ways of
+describing colors to fit the requirements of a particular application
+(e.g. Television, offset printing, color monitors). Color reduction, by
+default, takes place in the RGBColorspace. Empirical evidence suggests
+that distances in color spaces such as YUVColorspace or YIQColorspace
+correspond to perceptual color differences more closely han do distances
+in RGB space. These color spaces may give better results when color
+reducing an image. Refer to quantize for more details.</p>
+<p>When encoding an output image, the colorspaces RGBColorspace,
+CMYKColorspace, and GRAYColorspace may be specified. The CMYKColorspace
+option is only applicable when writing TIFF, JPEG, and Adobe Photoshop
+bitmap (PSD) files.</p>
+<table border="1" class="docutils">
+<caption>ColorspaceType</caption>
+<colgroup>
+<col width="32%" />
+<col width="68%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedColorspace</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>RGBColorspace</td>
+<td>Red, Green, Blue colorspace.</td>
+</tr>
+<tr><td>GRAYColorspace</td>
+<td>Similar to Luma (Y) according to ITU-R 601</td>
+</tr>
+<tr><td>TransparentColorspace</td>
+<td>RGB which preserves the matte while quantizing colors.</td>
+</tr>
+<tr><td>OHTAColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>XYZColorspace</td>
+<td>CIE XYZ</td>
+</tr>
+<tr><td>YCCColorspace</td>
+<td>Kodak PhotoCD PhotoYCC</td>
+</tr>
+<tr><td>YIQColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>YPbPrColorspace</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>YUVColorspace</td>
+<td>YUV colorspace as used for computer video.</td>
+</tr>
+<tr><td>CMYKColorspace</td>
+<td>Cyan, Magenta, Yellow, Black colorspace.</td>
+</tr>
+<tr><td>sRGBColorspace</td>
+<td>Kodak PhotoCD sRGB</td>
+</tr>
+<tr><td>HSLColorspace</td>
+<td>Hue, saturation, luminosity</td>
+</tr>
+<tr><td>HWBColorspace</td>
+<td>Hue, whiteness, blackness</td>
+</tr>
+<tr><td>LABColorspace</td>
+<td>ITU LAB</td>
+</tr>
+<tr><td>CineonLogRGBColorspace</td>
+<td>RGB data with Cineon Log scaling, 2.048 density range</td>
+</tr>
+<tr><td>Rec601LumaColorspace</td>
+<td>Luma (Y) according to ITU-R 601</td>
+</tr>
+<tr><td>Rec601YCbCrColorspace</td>
+<td>YCbCr according to ITU-R 601</td>
+</tr>
+<tr><td>Rec709LumaColorspace</td>
+<td>Luma (Y) according to ITU-R 709</td>
+</tr>
+<tr><td>Rec709YCbCrColorspace</td>
+<td>YCbCr according to ITU-R 709</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="compliancetype">
+<h1><a class="toc-backref" href="#id10">ComplianceType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UndefinedCompliance = 0x0000,
+ NoCompliance = 0x0000,
+ SVGCompliance = 0x0001,
+ X11Compliance = 0x0002,
+ XPMCompliance = 0x0004,
+ AllCompliance = 0xffff
+} ComplianceType;
+</pre>
+</div>
+<div class="section" id="compositeoperator">
+<h1><a class="toc-backref" href="#id11">CompositeOperator</a></h1>
+<p>CompositeOperator is used to select the image composition algorithm used
+to compose a composite image with an image. By default, each of the
+composite image pixels are replaced by the corresponding image tile
+pixel. Specify CompositeOperator to select a different algorithm.</p>
+<p>The image compositor requires a matte, or alpha channel in the image for
+some operations. This extra channel usually defines a mask which
+represents a sort of a cookie-cutter for the image. This is the case when
+matte is 255 (full coverage) for pixels inside the shape, zero outside,
+and between zero and 255 on the boundary. For certain operations, if
+image does not have a matte channel, it is initialized with 0 for any
+pixel matching in color to pixel location (0,0), otherwise 255 (to work
+properly borderWidth must be 0).</p>
+<table border="1" class="docutils">
+<caption>CompositeOperator</caption>
+<colgroup>
+<col width="23%" />
+<col width="77%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Enumeration</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>UndefinedCompositeOp</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>OverCompositeOp</td>
+<td>The result is the union of the the two image shapes with the composite
+image obscuring image in the region of overlap.</td>
+</tr>
+<tr><td>InCompositeOp</td>
+<td>The result is a simply composite image cut by the shape of image. None of
+the image data of image is included in the result.</td>
+</tr>
+<tr><td>OutCompositeOp</td>
+<td>The resulting image is composite image with the shape of image cut out.</td>
+</tr>
+<tr><td>AtopCompositeOp</td>
+<td>The result is the same shape as image image, with composite image
+obscuring image there the image shapes overlap. Note that this differs
+from OverCompositeOp because the portion of composite image outside of
+image's shape does not appear in the result.</td>
+</tr>
+<tr><td>XorCompositeOp</td>
+<td>The result is the image data from both composite image and image that is
+outside the overlap region. The overlap region will be blank.</td>
+</tr>
+<tr><td>PlusCompositeOp</td>
+<td>The result is just the sum of the image data. Output values are cropped
+to 255 (no overflow). This operation is independent of the matte channels.</td>
+</tr>
+<tr><td>MinusCompositeOp</td>
+<td>The result of composite image - image, with overflow cropped to zero. The
+matte chanel is ignored (set to 255, full coverage).</td>
+</tr>
+<tr><td>AddCompositeOp</td>
+<td>The result of composite image + image, with overflow wrapping around (mod
+256).</td>
+</tr>
+<tr><td>SubtractCompositeOp</td>
+<td>The result of composite image - image, with underflow wrapping around (mod
+256). The add and subtract operators can be used to perform reversible
+transformations.</td>
+</tr>
+<tr><td>DifferenceCompositeOp</td>
+<td>The result of abs(composite image - image). This is useful for comparing
+two very similar images.</td>
+</tr>
+<tr><td>BumpmapCompositeOp</td>
+<td>The result image shaded by composite image.</td>
+</tr>
+<tr><td>CopyCompositeOp</td>
+<td>The resulting image is image replaced with composite image. Here the matte
+information is ignored.</td>
+</tr>
+<tr><td>CopyRedCompositeOp</td>
+<td>The resulting image is the red layer in image replaced with the red layer
+in composite image. The other layers are copied untouched.</td>
+</tr>
+<tr><td>CopyGreenCompositeOp</td>
+<td>The resulting image is the green layer in image replaced with the green
+layer in composite image. The other layers are copied untouched.</td>
+</tr>
+<tr><td>CopyBlueCompositeOp</td>
+<td>The resulting image is the blue layer in image replaced with the blue
+layer in composite image. The other layers are copied untouched.</td>
+</tr>
+<tr><td>CopyOpacityCompositeOp</td>
+<td>The resulting image is the matte layer in image replaced with the matte
+layer in composite image. The other layers are copied untouched.</td>
+</tr>
+<tr><td>ClearCompositeOp</td>
+<td>Pixels in the region are set to Transparent.</td>
+</tr>
+<tr><td>DissolveCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>DisplaceCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>ModulateCompositeOp</td>
+<td>Modulate brightness in HSL space.</td>
+</tr>
+<tr><td>ThresholdCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>NoCompositeOp</td>
+<td>Do nothing at all.</td>
+</tr>
+<tr><td>DarkenCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>LightenCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>HueCompositeOp</td>
+<td>Copy Hue channel (from HSL colorspace).</td>
+</tr>
+<tr><td>SaturateCompositeOp</td>
+<td>Copy Saturation channel (from HSL colorspace).</td>
+</tr>
+<tr><td>ColorizeCompositeOp</td>
+<td>Copy Hue and Saturation channels (from HSL colorspace).</td>
+</tr>
+<tr><td>LuminizeCompositeOp</td>
+<td>Copy Brightness channel (from HSL colorspace).</td>
+</tr>
+<tr><td>ScreenCompositeOp</td>
+<td>[Not yet implemented]</td>
+</tr>
+<tr><td>OverlayCompositeOp</td>
+<td>[Not yet implemented]</td>
+</tr>
+<tr><td>CopyCyanCompositeOp</td>
+<td>Copy the Cyan channel.</td>
+</tr>
+<tr><td>CopyMagentaCompositeOp</td>
+<td>Copy the Magenta channel.</td>
+</tr>
+<tr><td>CopyYellowCompositeOp</td>
+<td>Copy the Yellow channel.</td>
+</tr>
+<tr><td>CopyBlackCompositeOp</td>
+<td>Copy the Black channel.</td>
+</tr>
+<tr><td>DivideCompositeOp</td>
+<td>&nbsp;</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="compressiontype">
+<h1><a class="toc-backref" href="#id12">CompressionType</a></h1>
+<p>CompressionType is used to express the desired compression type when
+encoding an image. Be aware that most image types only support a sub-set
+of the available compression types. If the compression type specified is
+incompatable with the image, GraphicsMagick selects a compression type
+compatable with the image type.</p>
+<table border="1" class="docutils">
+<caption>CompressionType</caption>
+<colgroup>
+<col width="28%" />
+<col width="72%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UndefinedCompression</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>NoCompression</td>
+<td>No compression</td>
+</tr>
+<tr><td>BZipCompression</td>
+<td>BZip (Burrows-Wheeler block-sorting text compression algorithm and
+Huffman coding) as used by bzip2 utilities</td>
+</tr>
+<tr><td>FaxCompression</td>
+<td>CCITT Group 3 FAX compression</td>
+</tr>
+<tr><td>Group4Compression</td>
+<td>CCITT Group 4 FAX compression (used only for TIFF)</td>
+</tr>
+<tr><td>JPEGCompression</td>
+<td>JPEG compression</td>
+</tr>
+<tr><td>LosslessJPEGCompression</td>
+<td>Lossless JPEG compression</td>
+</tr>
+<tr><td>LZWCompression</td>
+<td>Lempel-Ziv-Welch (LZW) compression (caution, patented by Unisys)</td>
+</tr>
+<tr><td>RLECompression</td>
+<td>Run-Length encoded (RLE) compression</td>
+</tr>
+<tr><td>ZipCompression</td>
+<td>Lempel-Ziv compression (LZ77) as used in PKZIP and GNU gzip.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="decorationtype">
+<h1><a class="toc-backref" href="#id13">DecorationType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ NoDecoration,
+ UnderlineDecoration,
+ OverlineDecoration,
+ LineThroughDecoration
+} DecorationType;
+</pre>
+</div>
+<div class="section" id="drawcontext">
+<h1><a class="toc-backref" href="#id14">DrawContext</a></h1>
+<pre class="literal-block">
+typedef struct _DrawContext *DrawContext;
+</pre>
+</div>
+<div class="section" id="drawinfo">
+<h1><a class="toc-backref" href="#id15">DrawInfo</a></h1>
+<p>The DrawInfo structure is used to support annotating an image using
+drawing commands.</p>
+<table border="1" class="docutils">
+<caption>Methods Supporting DrawInfo</caption>
+<colgroup>
+<col width="23%" />
+<col width="77%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Method</td>
+<td>Description</td>
+</tr>
+<tr><td>GetDrawInfo()</td>
+<td>Allocate new structure with defaults set.</td>
+</tr>
+<tr><td>CloneDrawInfo()</td>
+<td>Copy existing structure, allocating new structure in the process.</td>
+</tr>
+<tr><td>DestroyDrawInfo()</td>
+<td>Deallocate structure, including any members.</td>
+</tr>
+<tr><td>DrawImage()</td>
+<td>Render primitives to image.</td>
+</tr>
+</tbody>
+</table>
+<p>The members of the DrawInfo structure are shown in the following table.
+The structure is initialized to reasonable defaults by first initializing
+the equivalent members of ImageInfo, and then initializing the entire
+structure using GetDrawInfo().</p>
+<table border="1" class="docutils">
+<caption>DrawInfo Structure Members Supporting DrawImage()</caption>
+<colgroup>
+<col width="16%" />
+<col width="14%" />
+<col width="69%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>affine</td>
+<td>AffineInfo</td>
+<td>Coordinate transformation (rotation, scaling, and translation).</td>
+</tr>
+<tr><td>border_color</td>
+<td>PixelPacket</td>
+<td>Border color</td>
+</tr>
+<tr><td>box</td>
+<td>PixelPacket</td>
+<td>Text solid background color.</td>
+</tr>
+<tr><td>decorate</td>
+<td>DecorationType</td>
+<td>Text decoration type.</td>
+</tr>
+<tr><td>density</td>
+<td>char *</td>
+<td>Text rendering density in DPI (effects scaling font according to
+pointsize). E.g. &quot;72x72&quot;</td>
+</tr>
+<tr><td>fill</td>
+<td>PixelPacket</td>
+<td>Object internal fill (within outline) color.</td>
+</tr>
+<tr><td>font</td>
+<td>char *</td>
+<td>Font to use when rendering text.</td>
+</tr>
+<tr><td>gravity</td>
+<td>GravityType</td>
+<td>Text placement preference (e.g. NorthWestGravity).</td>
+</tr>
+<tr><td>linewidth</td>
+<td>double</td>
+<td>Stroke (outline) drawing width in pixels.</td>
+</tr>
+<tr><td>pointsize</td>
+<td>double</td>
+<td>Font size (also see density).</td>
+</tr>
+<tr><td>primitive</td>
+<td>char *</td>
+<td>Space or new-line delimited list of text drawing primitives (e.g
+&quot;text 100,100 Cockatoo&quot;). See the table Drawing Primitives for the
+available drawing primitives.</td>
+</tr>
+<tr><td>stroke</td>
+<td>PixelPacket</td>
+<td>Object stroke (outline) color.</td>
+</tr>
+<tr><td>stroke_antialias</td>
+<td>unsigned int</td>
+<td>Set to True (non-zero) to obtain anti-aliased stroke rendering.</td>
+</tr>
+<tr><td>text_antialias</td>
+<td>unsigned int</td>
+<td>Set to True (non-zero) to obtain anti-aliased text rendering.</td>
+</tr>
+<tr><td>tile</td>
+<td>Image *</td>
+<td>Image texture to draw with. Use an image containing a single color
+(e.g. a 1x1 image) to draw in a solid color.</td>
+</tr>
+</tbody>
+</table>
+<p>Drawing Primitives</p>
+<p>The drawing primitives shown in the following table may be supplied as a
+space or new-line delimited list to the primitive member. Primitives
+which set drawing options effect the results from subsequent drawing
+operations. See the 'push graphic-context' and 'pop graphic-context'
+primitives for a way to control the propagation of drawing options.</p>
+<table border="1" class="docutils">
+<caption>Drawing Primitives</caption>
+<colgroup>
+<col width="16%" />
+<col width="28%" />
+<col width="56%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Primitive</td>
+<td>Arguments</td>
+<td>Purpose</td>
+</tr>
+<tr><td>affine</td>
+<td>sx,rx,ry,sy,tx,ty</td>
+<td>Apply coordinate transformations to support scaling
+(s), rotation (r), and translation (t). Angles are
+specified in radians. Equivalent to SVG matrix command
+which supplies a transformation matrix.</td>
+</tr>
+<tr><td>angle</td>
+<td>angle</td>
+<td>Specify object drawing angle.</td>
+</tr>
+<tr><td>arc</td>
+<td>startX,startY endX,endY
+startDegrees,endDegrees</td>
+<td>Draw an arc.</td>
+</tr>
+<tr><td>Bezier</td>
+<td>x1,y1, x2,y2, x3,y3, ...,
+xN,yN</td>
+<td>Draw a Bezier curve.</td>
+</tr>
+<tr><td>circle</td>
+<td>originX,originY
+perimX,perimY</td>
+<td>Draw a circle.</td>
+</tr>
+<tr><td>color</td>
+<td>x,y (point|replace|
+floodfill|filltoborder|
+reset)</td>
+<td>Set color in image according to specified colorization
+rule.</td>
+</tr>
+<tr><td>decorate</td>
+<td>(none|underline|overline|
+line-through)</td>
+<td>Specify text decoration.</td>
+</tr>
+<tr><td>ellipse</td>
+<td>originX,originY
+width,height
+arcStart,arcEnd</td>
+<td>Draw an ellipse.</td>
+</tr>
+<tr><td>fill</td>
+<td>colorspec</td>
+<td>Specifiy object filling color.</td>
+</tr>
+<tr><td>fill-opacity</td>
+<td>opacity</td>
+<td>Specify object fill opacity.</td>
+</tr>
+<tr><td>font</td>
+<td>fontname</td>
+<td>Specify text drawing font.</td>
+</tr>
+<tr><td>gravity</td>
+<td>(NorthWest,North,NorthEast,
+West,Center,East,
+SouthWest,South,SouthEast)</td>
+<td>Specify text positioning gravity.</td>
+</tr>
+<tr><td>image</td>
+<td>x,y width,height filename</td>
+<td>Composite image at position, scaled to specified width
+and height, and specified filename. If width or height
+is zero, scaling is not performed.</td>
+</tr>
+<tr><td>line</td>
+<td>startX,startY endX,endY</td>
+<td>Draw a line.</td>
+</tr>
+<tr><td>matte</td>
+<td>x,y (point|replace|
+floodfill|filltoborder|
+reset)</td>
+<td>Set matte in image according to specified colorization
+rule.</td>
+</tr>
+<tr><td>opacity</td>
+<td>fillOpacity strokeOpacity</td>
+<td>Specify drawing fill and stroke opacities.</td>
+</tr>
+<tr><td>path</td>
+<td>'SVG-compatible path
+arguments'</td>
+<td>Draw using SVG-compatible path drawing commands.</td>
+</tr>
+<tr><td>point</td>
+<td>x,y</td>
+<td>Set point to fill color.</td>
+</tr>
+<tr><td>pointsize</td>
+<td>pointsize</td>
+<td>Specify text drawing pointsize (scaled to density).</td>
+</tr>
+<tr><td>polygon</td>
+<td>x1,y1, x2,y2, x3,y3, ...,
+xN,yN</td>
+<td>Draw a polygon.</td>
+</tr>
+<tr><td>polyline</td>
+<td>x1,y1, x2,y2, x3,y3, ...,
+xN,yN</td>
+<td>Draw a polyline.</td>
+</tr>
+<tr><td>pop</td>
+<td>graphic-context</td>
+<td>Remove options set since previous &quot;push
+graphic-context&quot; command. Options revert to those in
+effect prior to pushing the graphic context.</td>
+</tr>
+<tr><td>push</td>
+<td>graphic-context</td>
+<td>Specify new graphic context.</td>
+</tr>
+<tr><td>rect</td>
+<td>upperLeftX,upperLeftY
+lowerRightX,lowerRightY</td>
+<td>Draw a rectangle.</td>
+</tr>
+<tr><td>rotate</td>
+<td>angle</td>
+<td>Specify coordiante space rotation. Subsequent objects
+are drawn with coordate space rotated by specified
+angle.</td>
+</tr>
+<tr><td>roundrectangle</td>
+<td>centerX,centerY
+width,hight
+cornerWidth,cornerHeight</td>
+<td>Draw a rectangle with rounded corners.</td>
+</tr>
+<tr><td>stroke</td>
+<td>colorspec</td>
+<td>Specify object stroke (outline) color.</td>
+</tr>
+<tr><td>stroke-antialias</td>
+<td>stroke_antialias (0 or 1)</td>
+<td>Specify if stroke should be antialiased or not.</td>
+</tr>
+<tr><td>stroke-dash</td>
+<td>value</td>
+<td>Specify pattern to be used when drawing stroke.</td>
+</tr>
+<tr><td>stroke-opacity</td>
+<td>opacity</td>
+<td>Specify opacity of stroke drawing color.</td>
+</tr>
+<tr><td>stroke-width</td>
+<td>linewidth</td>
+<td>Specify stroke (outline) width in pixels.</td>
+</tr>
+<tr><td>text</td>
+<td>x,y &quot;some text&quot;</td>
+<td>Draw text at position.</td>
+</tr>
+<tr><td>text-antialias</td>
+<td>text_antialias (0 or 1)</td>
+<td>Specify if rendered text is to be antialiased (blend
+edges).</td>
+</tr>
+<tr><td>scale</td>
+<td>x,y</td>
+<td>Specify scaling to be applied to coordintate space for
+subsequent drawing commands.</td>
+</tr>
+<tr><td>translate</td>
+<td>x,y</td>
+<td>Specify center of coordinate space to use for
+subsequent drawing commands.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="endiantype">
+<h1><a class="toc-backref" href="#id16">EndianType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UndefinedEndian,
+ LSBEndian, /* &quot;little&quot; endian */
+ MSBEndian, /* &quot;big&quot; endian */
+ NativeEndian /* native endian */
+} EndianType;
+</pre>
+</div>
+<div class="section" id="errorhandler">
+<h1><a class="toc-backref" href="#id17">ErrorHandler</a></h1>
+<pre class="literal-block">
+typedef void
+ (*ErrorHandler)(const ExceptionType,const char *,const char *);
+</pre>
+</div>
+<div class="section" id="exceptioninfo">
+<h1><a class="toc-backref" href="#id18">ExceptionInfo</a></h1>
+<pre class="literal-block">
+typedef struct _ExceptionInfo
+{
+ char
+ *reason,
+ *description;
+
+ ExceptionType
+ severity;
+
+ unsigned long
+ signature;
+} ExceptionInfo;
+</pre>
+</div>
+<div class="section" id="exceptiontype">
+<h1><a class="toc-backref" href="#id19">ExceptionType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UndefinedException,
+ WarningException = 300,
+ ResourceLimitWarning = 300,
+ TypeWarning = 305,
+ OptionWarning = 310,
+ DelegateWarning = 315,
+ MissingDelegateWarning = 320,
+ CorruptImageWarning = 325,
+ FileOpenWarning = 330,
+ BlobWarning = 335,
+ StreamWarning = 340,
+ CacheWarning = 345,
+ CoderWarning = 350,
+ ModuleWarning = 355,
+ DrawWarning = 360,
+ ImageWarning = 365,
+ XServerWarning = 380,
+ MonitorWarning = 385,
+ RegistryWarning = 390,
+ ConfigureWarning = 395,
+ ErrorException = 400,
+ ResourceLimitError = 400,
+ TypeError = 405,
+ OptionError = 410,
+ DelegateError = 415,
+ MissingDelegateError = 420,
+ CorruptImageError = 425,
+ FileOpenError = 430,
+ BlobError = 435,
+ StreamError = 440,
+ CacheError = 445,
+ CoderError = 450,
+ ModuleError = 455,
+ DrawError = 460,
+ ImageError = 465,
+ XServerError = 480,
+ MonitorError = 485,
+ RegistryError = 490,
+ ConfigureError = 495,
+ FatalErrorException = 700,
+ ResourceLimitFatalError = 700,
+ TypeFatalError = 705,
+ OptionFatalError = 710,
+ DelegateFatalError = 715,
+ MissingDelegateFatalError = 720,
+ CorruptImageFatalError = 725,
+ FileOpenFatalError = 730,
+ BlobFatalError = 735,
+ StreamFatalError = 740,
+ CacheFatalError = 745,
+ CoderFatalError = 750,
+ ModuleFatalError = 755,
+ DrawFatalError = 760,
+ ImageFatalError = 765,
+ XServerFatalError = 780,
+ MonitorFatalError = 785,
+ RegistryFatalError = 790,
+ ConfigureFatalError = 795
+} ExceptionType;
+</pre>
+</div>
+<div class="section" id="fillrule">
+<h1><a class="toc-backref" href="#id20">FillRule</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UndefinedRule,
+ EvenOddRule,
+ NonZeroRule
+} FillRule;
+</pre>
+</div>
+<div class="section" id="filtertypes">
+<h1><a class="toc-backref" href="#id21">FilterTypes</a></h1>
+<p>FilterTypes is used to adjust the filter algorithm used when resizing
+images. Different filters experience varying degrees of success with
+various images and can take significantly different amounts of processing
+time. GraphicsMagick uses the LanczosFilter by default since this filter
+has been shown to provide the best results for most images in a
+reasonable amount of time. Other filter types (e.g. TriangleFilter) may
+execute much faster but may show artifacts when the image is re-sized or
+around diagonal lines. The only way to be sure is to test the filter with
+sample images.</p>
+<table border="1" class="docutils">
+<caption>FilterTypes</caption>
+<colgroup>
+<col width="48%" />
+<col width="52%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UndefinedFilter</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>PointFilter</td>
+<td>Point Filter</td>
+</tr>
+<tr><td>BoxFilter</td>
+<td>Box Filter</td>
+</tr>
+<tr><td>TriangleFilter</td>
+<td>Triangle Filter</td>
+</tr>
+<tr><td>HermiteFilter</td>
+<td>Hermite Filter</td>
+</tr>
+<tr><td>HanningFilter</td>
+<td>Hanning Filter</td>
+</tr>
+<tr><td>HammingFilter</td>
+<td>Hamming Filter</td>
+</tr>
+<tr><td>BlackmanFilter</td>
+<td>Blackman Filter</td>
+</tr>
+<tr><td>GaussianFilter</td>
+<td>Gaussian Filter</td>
+</tr>
+<tr><td>QuadraticFilter</td>
+<td>Quadratic Filter</td>
+</tr>
+<tr><td>CubicFilter</td>
+<td>Cubic Filter</td>
+</tr>
+<tr><td>CatromFilter</td>
+<td>Catrom Filter</td>
+</tr>
+<tr><td>MitchellFilter</td>
+<td>Mitchell Filter</td>
+</tr>
+<tr><td>LanczosFilter</td>
+<td>Lanczos Filter</td>
+</tr>
+<tr><td>BesselFilter</td>
+<td>Bessel Filter</td>
+</tr>
+<tr><td>SincFilter</td>
+<td>Sinc Filter</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="frameinfo">
+<h1><a class="toc-backref" href="#id22">FrameInfo</a></h1>
+<pre class="literal-block">
+typedef struct _FrameInfo
+{
+ unsigned long
+ width,
+ height;
+
+ long
+ x,
+ y,
+ inner_bevel,
+ outer_bevel;
+} FrameInfo;
+</pre>
+</div>
+<div class="section" id="gravitytype">
+<h1><a class="toc-backref" href="#id23">GravityType</a></h1>
+<p>GravityType specifies positioning of an object (e.g. text, image) within
+a bounding region (e.g. an image). Gravity provides a convenient way to
+locate objects irrespective of the size of the bounding region, in other
+words, you don't need to provide absolute coordinates in order to
+position an object. A common default for gravity is NorthWestGravity.</p>
+<table border="1" class="docutils">
+<caption>GravityType</caption>
+<colgroup>
+<col width="27%" />
+<col width="73%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>ForgetGravity</td>
+<td>Don't use gravity.</td>
+</tr>
+<tr><td>NorthWestGravity</td>
+<td>Position object at top-left of region.</td>
+</tr>
+<tr><td>NorthGravity</td>
+<td>Postiion object at top-center of region</td>
+</tr>
+<tr><td>NorthEastGravity</td>
+<td>Position object at top-right of region</td>
+</tr>
+<tr><td>WestGravity</td>
+<td>Position object at left-center of region</td>
+</tr>
+<tr><td>CenterGravity</td>
+<td>Position object at center of region</td>
+</tr>
+<tr><td>EastGravity</td>
+<td>Position object at right-center of region</td>
+</tr>
+<tr><td>SouthWestGravity</td>
+<td>Position object at left-bottom of region</td>
+</tr>
+<tr><td>SouthGravity</td>
+<td>Position object at bottom-center of region</td>
+</tr>
+<tr><td>SouthEastGravity</td>
+<td>Position object at bottom-right of region</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="image">
+<h1><a class="toc-backref" href="#id24">Image</a></h1>
+<p>The Image structure represents an GraphicsMagick image. It is initially
+allocated by AllocateImage() and deallocated by DestroyImage(). The
+functions ReadImage(), ReadImages(), BlobToImage() and CreateImage()
+return a new image. Use CloneImage() to copy an image. An image consists
+of a structure containing image attributes as well as the image pixels.</p>
+<p>The image pixels are represented by the structure PixelPacket and are
+cached in-memory, or on disk, depending on the cache threshold setting.
+This cache is known as the &quot;pixel cache&quot;. Pixels in the cache may not be
+edited directly. They must first be made visible from the cache via a
+pixel view. A pixel view is a rectangular view of the pixels as defined
+by a starting coordinate, and a number of rows and columns. When
+considering the varying abilities of multiple platforms, the most
+reliably efficient pixel view is comprized of part, or all, of one image
+row.</p>
+<p>There are two means of accessing pixel views. When using the default
+view, the pixels are made visible and accessable by using the
+GetImagePixels() method which provides access to a specified region of
+the image. After the view has been updated, the pixels may be saved back
+to the cache in their original positions via SyncImagePixels(). In order
+to create an image with new contents, or to blindly overwrite existing
+contents, the method SetImagePixels() is used to reserve a pixel view
+corresponding to a region in the pixel cache. Once the pixel view has
+been updated, it may be written to the cache via SyncImagePixels(). The
+function GetIndexes() provides access to the image colormap, represented
+as an array of type IndexPacket.</p>
+<p>A more flexible interface to the image pixels is via the Cache View
+interface. This interface supports multiple pixel cache views (limited by
+the amount of available memory), each of which are identified by a handle
+(of type ViewInfo). Use OpenCacheView() to obtain a new cache view,
+CloseCacheView() to discard a cache view, GetCacheViewPixels() to access
+an existing pixel region, SetCacheView() to define a new pixel region,
+and SyncCacheViewPixels() to save the updated pixel region. The function
+GetCacheViewIndexes() provides access to the colormap indexes associated
+with the pixel view.</p>
+<p>When writing encoders and decoders for new image formats, it is
+convenient to have a high-level interface available which supports
+converting between external pixel representations and GraphicsMagick's
+own representation. Pixel components (red, green, blue, opacity, RGB, or
+RGBA) may be transferred from a user-supplied buffer into the default
+view by using ImportImagePixelArea(), or from an allocated view via
+ImportViewPixelArea(). Pixel components may be transferred from the
+default view into a user-supplied buffer by using ExportImagePixelArea(),
+or from an allocated view via ExportViewPixelArea(). Use of this
+high-level interface helps protect image coders from changes to
+GraphicsMagick's pixel representation and simplifies the implementation.</p>
+<p>The members of the Image structure are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>Image Structure Members</caption>
+<colgroup>
+<col width="31%" />
+<col width="18%" />
+<col width="51%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>background_color</td>
+<td>PixelPacket</td>
+<td>Image background color</td>
+</tr>
+<tr><td>blur</td>
+<td>double</td>
+<td>Blur factor to apply to the image when zooming</td>
+</tr>
+<tr><td>border_color</td>
+<td>PixelPacket</td>
+<td>Image border color</td>
+</tr>
+<tr><td>chromaticity</td>
+<td>ChromaticityInfo</td>
+<td>Red, green, blue, and white-point chromaticity
+values.</td>
+</tr>
+<tr><td>colormap</td>
+<td>PixelPacket *</td>
+<td>PseudoColor palette array.</td>
+</tr>
+<tr><td>colors</td>
+<td>unsigned int</td>
+<td>The desired number of colors. Used by
+QuantizeImage().</td>
+</tr>
+<tr><td>colorspace</td>
+<td>ColorspaceType</td>
+<td>Image pixel interpretation.If the colorspace is
+RGB the pixels are red, green, blue. If matte is
+true, then red, green, blue, and index. If it is
+CMYK, the pixels are cyan, yellow, magenta, black.
+Otherwise the colorspace is ignored.</td>
+</tr>
+<tr><td>columns</td>
+<td>unsigned int</td>
+<td>Image width</td>
+</tr>
+<tr><td>compression</td>
+<td>CompressionType</td>
+<td>Image compresion type. The default is the
+compression type of the specified image file.</td>
+</tr>
+<tr><td>delay</td>
+<td>unsigned int</td>
+<td>Time in 1/100ths of a second (0 to 65535) which
+must expire before displaying the next image in an
+animated sequence. This option is useful for
+regulating the animation of a sequence of GIF
+images within Netscape.</td>
+</tr>
+<tr><td>depth</td>
+<td>unsigned int</td>
+<td>Image depth. Number of encoding bits per sample.
+Usually 8 or 16, but sometimes 10 or 12.</td>
+</tr>
+<tr><td>directory</td>
+<td>char *</td>
+<td>Tile names from within an image montage. Only
+valid after calling MontageImages() or reading a
+MIFF file which contains a directory.</td>
+</tr>
+<tr><td>dispose</td>
+<td>unsigned int</td>
+<td>GIF disposal method. This option is used to
+control how successive frames are rendered (how
+the preceding frame is disposed of) when creating
+a GIF animation.</td>
+</tr>
+<tr><td>exception</td>
+<td>ExceptionInfo</td>
+<td>Record of any error which occurred when updating
+image.</td>
+</tr>
+<tr><td>filename</td>
+<td>char
+[MaxTextExtent]</td>
+<td>Image file name to read or write.</td>
+</tr>
+<tr><td>filter</td>
+<td>FilterTypes</td>
+<td>Filter to use when resizing image. The reduction
+filter employed has a significant effect on the
+time required to resize an image and the resulting
+quality. The default filter is Lanczos which has
+been shown to produce high quality results when
+reducing most images.</td>
+</tr>
+<tr><td>fuzz</td>
+<td>int</td>
+<td>Colors within this distance are considered equal.
+A number of algorithms search for a target color.
+By default the color must be exact. Use this
+option to match colors that are close to the
+target color in RGB space.</td>
+</tr>
+<tr><td>gamma</td>
+<td>double</td>
+<td>Gamma level of the image. The same color image
+displayed on two different workstations may look
+different due to differences in the display
+monitor. Use gamma correction to adjust for this
+color difference.</td>
+</tr>
+<tr><td>geometry</td>
+<td>char *</td>
+<td>Preferred size of the image when encoding.</td>
+</tr>
+<tr><td>interlace</td>
+<td>InterlaceType</td>
+<td>The type of interlacing scheme (default
+NoInterlace). This option is used to specify the
+type of interlacing scheme for raw image formats
+such as RGB or YUV. NoInterlace means do not
+interlace, LineInterlace uses scanline
+interlacing, and PlaneInterlace uses plane
+interlacing. PartitionInterlace is like
+PlaneInterlace except the different planes are
+saved to individual files (e.g. image.R, image.G,
+and image.B). Use LineInterlace or PlaneInterlace
+to create an interlaced GIF or progressive JPEG
+image.</td>
+</tr>
+<tr><td>iterations</td>
+<td>unsigned int</td>
+<td>Number of iterations to loop an animation (e.g.
+Netscape loop extension) for.</td>
+</tr>
+<tr><td>magick</td>
+<td>char
+[MaxTextExtent]</td>
+<td>Image encoding format (e.g. &quot;GIF&quot;).</td>
+</tr>
+<tr><td>magick_columns</td>
+<td>unsigned int</td>
+<td>Base image width (before transformations)</td>
+</tr>
+<tr><td>magick_filename</td>
+<td>char
+[MaxTextExtent]</td>
+<td>Base image filename (before transformations)</td>
+</tr>
+<tr><td>magick_rows</td>
+<td>unsigned int</td>
+<td>Base image height (before transformations)</td>
+</tr>
+<tr><td>matte</td>
+<td>unsigned int</td>
+<td>If non-zero, then the index member of pixels
+represents the alpha channel.</td>
+</tr>
+<tr><td>matte_color</td>
+<td>PixelPacket</td>
+<td>Image matte (transparent) color</td>
+</tr>
+<tr><td>montage</td>
+<td>char *</td>
+<td>Tile size and offset within an image montage. Only
+valid for montage images.</td>
+</tr>
+<tr><td>next</td>
+<td>struct _Image *</td>
+<td>Next image frame in sequence</td>
+</tr>
+<tr><td>offset</td>
+<td>int</td>
+<td>Number of initial bytes to skip over when reading
+raw image.</td>
+</tr>
+<tr><td>orientation</td>
+<td>OrientationType</td>
+<td>Orientation of the image. Specifies scanline
+orientation and starting coordinate of image.</td>
+</tr>
+<tr><td>page</td>
+<td>RectangleInfo</td>
+<td>Equivalent size of Postscript page.</td>
+</tr>
+<tr><td>previous</td>
+<td>struct _Image *</td>
+<td>Previous image frame in sequence.</td>
+</tr>
+<tr><td>rendering_intent</td>
+<td>RenderingIntent</td>
+<td>The type of rendering intent.</td>
+</tr>
+<tr><td>rows</td>
+<td>unsigned int</td>
+<td>Image height</td>
+</tr>
+<tr><td>scene</td>
+<td>unsigned int</td>
+<td>Image frame scene number.</td>
+</tr>
+<tr><td>storage_class</td>
+<td>ClassType</td>
+<td>Image storage class. If DirectClass then the image
+packets contain valid RGB or CMYK colors. If
+PseudoClass then the image has a colormap
+referenced by pixel's index member.</td>
+</tr>
+<tr><td>tile_info</td>
+<td>RectangleInfo</td>
+<td>Describes a tile within an image. For example, if
+your images is 640x480 you may only want 320x256
+with an offset of +128+64. It is used for raw
+formats such as RGB and CMYK as well as for TIFF.</td>
+</tr>
+<tr><td>timer</td>
+<td>TimerInfo</td>
+<td>Support for measuring actual (user + system) and
+elapsed execution time.</td>
+</tr>
+<tr><td>total_colors</td>
+<td>unsigned long</td>
+<td>The number of colors in the image after
+QuantizeImage(), or QuantizeImages() if the
+verbose flag was set before the call. Calculated
+by GetNumberColors().</td>
+</tr>
+<tr><td>units</td>
+<td>ResolutionType</td>
+<td>Units of image resolution</td>
+</tr>
+<tr><td>x_resolution</td>
+<td>double</td>
+<td>Horizontal resolution of the image</td>
+</tr>
+<tr><td>y_resolution</td>
+<td>double</td>
+<td>Vertical resolution of the image</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="imageinfo">
+<h1><a class="toc-backref" href="#id25">ImageInfo</a></h1>
+<p>The ImageInfo structure is used to supply option information to the
+functions AllocateImage(), AnimateImages(), BlobToImage(),
+CloneAnnotateInfo(), DisplayImages(), GetAnnotateInfo(), ImageToBlob(),
+PingImage(), ReadImage(), ReadImages(), and, WriteImage(). These
+functions update information in ImageInfo to reflect attributes of the
+current image.</p>
+<p>Use CloneImageInfo() to duplicate an existing ImageInfo structure or
+allocate a new one. Use DestroyImageInfo() to deallocate memory
+associated with an ImageInfo structure. Use GetImageInfo() to initialize
+an existing ImageInfo structure. Use SetImageInfo() to set image type
+information in the ImageInfo structure based on an existing image.</p>
+<p>The members of the ImageInfo structure are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>ImageInfo Structure Members</caption>
+<colgroup>
+<col width="16%" />
+<col width="15%" />
+<col width="68%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>adjoin</td>
+<td>unsigned int</td>
+<td>Join images into a single multi-image file.</td>
+</tr>
+<tr><td>antialias</td>
+<td>unsigned int</td>
+<td>Control antialiasing of rendered Postscript and Postscript or
+TrueType fonts. Enabled by default.</td>
+</tr>
+<tr><td>background_color</td>
+<td>PixelPacket</td>
+<td>Image background color.</td>
+</tr>
+<tr><td>border_color</td>
+<td>PixelPacket</td>
+<td>Image border color.</td>
+</tr>
+<tr><td>colorspace</td>
+<td>ColorspaceType</td>
+<td>Image pixel interpretation.If the colorspace is RGB the pixels are
+red, green, blue. If matte is true, then red, green, blue, and
+index. If it is CMYK, the pixels are cyan, yellow, magenta, black.
+Otherwise the colorspace is ignored.</td>
+</tr>
+<tr><td>compression</td>
+<td>CompressionType</td>
+<td>Image compresion type. The default is the compression type of the
+specified image file.</td>
+</tr>
+<tr><td>delay</td>
+<td>char *</td>
+<td>Time in 1/100ths of a second (0 to 65535) which must expire before
+displaying the next image in an animated sequence. This option is
+useful for regulating the animation of a sequence of GIF images
+within Netscape.</td>
+</tr>
+<tr><td>density</td>
+<td>char *</td>
+<td>Vertical and horizontal resolution in pixels of the image. This
+option specifies an image density when decoding a Postscript or
+Portable Document page. Often used with page.</td>
+</tr>
+<tr><td>depth</td>
+<td>unsigned int</td>
+<td>Image depth (8 or 16). QuantumLeap must be defined before a depth
+of 16 is valid.</td>
+</tr>
+<tr><td>dispose</td>
+<td>char *</td>
+<td>GIF disposal method. This option is used to control how successive
+frames are rendered (how the preceding frame is disposed of) when
+creating a GIF animation.</td>
+</tr>
+<tr><td>dither</td>
+<td>unsigned int</td>
+<td>Apply Floyd/Steinberg error diffusion to the image. The basic
+strategy of dithering is to trade intensity resolution for spatial
+resolution by averaging the intensities of several neighboring
+pixels. Images which suffer from severe contouring when reducing
+colors can be improved with this option. The colors or monochrome
+option must be set for this option to take effect.</td>
+</tr>
+<tr><td>file</td>
+<td>FILE *</td>
+<td>Stdio stream to read image from or write image to. If set,
+ImageMagick will read from or write to the stream rather than
+opening a file. Used by ReadImage() and WriteImage(). The stream is
+closed when the operation completes.</td>
+</tr>
+<tr><td>filename</td>
+<td>char
+[MaxTextExtent]</td>
+<td>Image file name to read or write.</td>
+</tr>
+<tr><td>fill</td>
+<td>PixelPacket</td>
+<td>Drawing object fill color.</td>
+</tr>
+<tr><td>font</td>
+<td>char *</td>
+<td>Text rendering font. If the font is a fully qualified X server font
+name, the font is obtained from an X server. To use a TrueType
+font, precede the TrueType filename with an &#64;. Otherwise, specify a
+Postscript font name (e.g. &quot;helvetica&quot;).</td>
+</tr>
+<tr><td>fuzz</td>
+<td>int</td>
+<td>Colors within this distance are considered equal. A number of
+algorithms search for a target color. By default the color must be
+exact. Use this option to match colors that are close to the target
+color in RGB space.</td>
+</tr>
+<tr><td>interlace</td>
+<td>InterlaceType</td>
+<td>The type of interlacing scheme (default NoInterlace). This option
+is used to specify the type of interlacing scheme for raw image
+formats such as RGB or YUV. NoInterlace means do not interlace,
+LineInterlace uses scanline interlacing, and PlaneInterlace uses
+plane interlacing. PartitionInterlace is like PlaneInterlace except
+the different planes are saved to individual files (e.g. image.R,
+image.G, and image.B). Use LineInterlace or PlaneInterlace to
+create an interlaced GIF or progressive JPEG image.</td>
+</tr>
+<tr><td>iterations</td>
+<td>char *</td>
+<td>Number of iterations to loop an animation (e.g. Netscape loop
+extension) for.</td>
+</tr>
+<tr><td>linewidth</td>
+<td>unsigned int</td>
+<td>Line width for drawing lines, circles, ellipses, etc.</td>
+</tr>
+<tr><td>magick</td>
+<td>char
+[MaxTextExtent]</td>
+<td>Image encoding format (e.g. &quot;GIF&quot;).</td>
+</tr>
+<tr><td>matte_color</td>
+<td>PixelPacket</td>
+<td>Image matte (transparent) color.</td>
+</tr>
+<tr><td>monochrome</td>
+<td>unsigned int</td>
+<td>Transform the image to black and white.</td>
+</tr>
+<tr><td>page</td>
+<td>char *</td>
+<td>Equivalent size of Postscript page.</td>
+</tr>
+<tr><td>ping</td>
+<td>unsigned int</td>
+<td>Set to True to read enough of the image to determine the image
+columns, rows, and filesize. The columns, rows, and size attributes
+are valid after invoking ReadImage() while ping is set. The image
+data is not valid after calling ReadImage() if ping is set.</td>
+</tr>
+<tr><td>pointsize</td>
+<td>double</td>
+<td>Text rendering font point size.</td>
+</tr>
+<tr><td>preview_type</td>
+<td>PreviewType</td>
+<td>Image manipulation preview option. Used by 'display'.</td>
+</tr>
+<tr><td>quality</td>
+<td>unsigned int</td>
+<td>JPEG/MIFF/PNG compression level (default 75).</td>
+</tr>
+<tr><td>server_name</td>
+<td>char *</td>
+<td>X11 display to display to obtain fonts from, or to capture image
+from.</td>
+</tr>
+<tr><td>size</td>
+<td>char *</td>
+<td>Width and height of a raw image (an image which does not support
+width and height information). Size may also be used to affect the
+image size read from a multi-resolution format (e.g. Photo CD,
+JBIG, or JPEG.</td>
+</tr>
+<tr><td>stroke</td>
+<td>PixelPacket</td>
+<td>Drawing object outline color.</td>
+</tr>
+<tr><td>subimage</td>
+<td>unsigned int</td>
+<td>Subimage of an image sequence.</td>
+</tr>
+<tr><td>subrange</td>
+<td>unsigned int</td>
+<td>Number of images relative to the base image.</td>
+</tr>
+<tr><td>texture</td>
+<td>char *</td>
+<td>Image filename to use as background texture.</td>
+</tr>
+<tr><td>tile</td>
+<td>char *</td>
+<td>Tile name.</td>
+</tr>
+<tr><td>units</td>
+<td>ResolutionType</td>
+<td>Units of image resolution.</td>
+</tr>
+<tr><td>verbose</td>
+<td>unsigned int</td>
+<td>Print detailed information about the image if True.</td>
+</tr>
+<tr><td>view</td>
+<td>char *</td>
+<td>FlashPix viewing parameters.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="imagetype">
+<h1><a class="toc-backref" href="#id26">ImageType</a></h1>
+<p>ImageType indicates the type classification of the image.</p>
+<table border="1" class="docutils">
+<caption>ImageType</caption>
+<colgroup>
+<col width="31%" />
+<col width="69%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UndefinedType</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>BilevelType</td>
+<td>Monochrome image</td>
+</tr>
+<tr><td>GrayscaleType</td>
+<td>Grayscale image</td>
+</tr>
+<tr><td>PaletteType</td>
+<td>Indexed color (palette) image</td>
+</tr>
+<tr><td>PaletteMatteType</td>
+<td>Indexed color (palette) image with opacity</td>
+</tr>
+<tr><td>TrueColorType</td>
+<td>Truecolor image</td>
+</tr>
+<tr><td>TrueColorMatteType</td>
+<td>Truecolor image with opacity</td>
+</tr>
+<tr><td>ColorSeparationType</td>
+<td>Cyan/Yellow/Magenta/Black (CYMK) image</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="indexpacket">
+<h1><a class="toc-backref" href="#id27">IndexPacket</a></h1>
+<p>IndexPacket is the type used for a colormap index. An array of type
+IndexPacket is used to represent an image in PseudoClass type. Currently
+supported IndexPacket underlying types are 'unsigned char' and 'unsigned
+short'. The type is selected at build time according to the QuantumDepth
+setting.</p>
+</div>
+<div class="section" id="interlacetype">
+<h1><a class="toc-backref" href="#id28">InterlaceType</a></h1>
+<p>InterlaceType specifies the ordering of the red, green, and blue pixel
+information in the image. Interlacing is usually used to make image
+information available to the user faster by taking advantage of the space
+vs time tradeoff. For example, interlacing allows images on the Web to be
+recognizable sooner and satellite images to accumulate/render with image
+resolution increasing over time.</p>
+<p>Use LineInterlace or PlaneInterlace to create an interlaced GIF or
+progressive JPEG image.</p>
+<table border="1" class="docutils">
+<caption>InterlaceType</caption>
+<colgroup>
+<col width="19%" />
+<col width="81%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UndefinedInterlace</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>NoInterlace</td>
+<td>Don't interlace image (RGBRGBRGBRGBRGBRGB...)</td>
+</tr>
+<tr><td>LineInterlace</td>
+<td>Use scanline interlacing (RRR...GGG...BBB...RRR...GGG...BBB...)</td>
+</tr>
+<tr><td>PlaneInterlace</td>
+<td>Use plane interlacing (RRRRRR...GGGGGG...BBBBBB...)</td>
+</tr>
+<tr><td>PartitionInterlace</td>
+<td>Similar to plane interlaing except that the different planes are saved to
+individual files (e.g. image.R, image.G, and image.B)</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="layertype">
+<h1><a class="toc-backref" href="#id29">LayerType</a></h1>
+<p>LayerType is used as an argument when doing color separations. Use
+LayerType when extracting a layer from an image. MatteLayer is useful for
+extracting the opacity values from an image.</p>
+<table border="1" class="docutils">
+<caption>LayerType</caption>
+<colgroup>
+<col width="28%" />
+<col width="72%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UndefinedLayer</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>RedLayer</td>
+<td>Select red layer</td>
+</tr>
+<tr><td>GreenLayer</td>
+<td>Select green layer</td>
+</tr>
+<tr><td>BlueLayer</td>
+<td>Select blue layer</td>
+</tr>
+<tr><td>MatteLayer</td>
+<td>Select matte (opacity values) layer</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="magickinfo">
+<h1><a class="toc-backref" href="#id30">MagickInfo</a></h1>
+<p>The MagickInfo structure is used by GraphicsMagick to register support
+for an image format. The MagickInfo structure is allocated with default
+parameters by calling SetMagickInfo(). Image formats are registered by
+calling RegisterMagickInfo() which adds the initial structure to a linked
+list (at which point it is owned by the list). A pointer to the structure
+describing a format may be obtained by calling GetMagickInfo(). Pass the
+argument NULL to obtain the first member of this list. A human-readable
+list of registered image formats may be printed to a file descriptor by
+calling ListMagickInfo().</p>
+<p>Support for formats may be provided as a module which is part of the
+GraphicsMagick library, provided by a module which is loaded dynamically
+at run-time, or directly by the linked program. Users of GraphicsMagick
+will normally want to create a loadable-module, or support encode/decode
+of an image format directly from within their program.</p>
+<p>Sample Module:</p>
+<p>The following shows sample code for a module called &quot;GIF&quot; (gif.c). Note
+that the names of the Register and Unregister call-back routines are
+calculated at run-time, and therefore must follow the rigid naming scheme
+RegisterFORMATImage and UnregisterFORMATImage, respectively, where FORMAT
+is the upper-cased name of the module file:</p>
+<pre class="literal-block">
+/* Read image */
+Image *ReadGIFImage(const ImageInfo *image_info)
+{
+ [ decode the image ... ]
+}
+
+/* Write image */
+unsigned int WriteGIFImage(const ImageInfo *image_info,Image *image)
+{
+ [ encode the image ... ]
+}
+
+/* Module call-back to register support for formats */
+void RegisterGIFImage(void)
+{
+ MagickInfo *entry;
+ entry=SetMagickInfo(&quot;GIF&quot;);
+ entry-&gt;decoder=ReadGIFImage;
+ entry-&gt;encoder=WriteGIFImage;
+ entry-&gt;description=&quot;CompuServe graphics interchange format&quot;;
+ entry-&gt;module=&quot;GIF&quot;;
+ RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo(&quot;GIF87&quot;);
+ entry-&gt;decoder=ReadGIFImage;
+ entry-&gt;encoder=WriteGIFImage;
+ entry-&gt;adjoin=False;
+ entry-&gt;description=&quot;CompuServe graphics interchange format (version 87a)&quot;;
+ entry-&gt;module=&quot;GIF&quot;;
+ RegisterMagickInfo(entry);
+}
+
+/* Module call-back to unregister support for formats */
+Export void UnregisterGIFImage(void)
+{
+ UnregisterMagickInfo(&quot;GIF&quot;);
+ UnregisterMagickInfo(&quot;GIF87&quot;);
+}
+</pre>
+<p>Sample Application Code</p>
+<p>Image format support provided within the user's application does not need
+to implement the RegisterFORMATImage and UnregisterFORMATImage call-back
+routines. Instead, the application takes responsibility for the
+registration itself. An example follows:</p>
+<pre class="literal-block">
+/* Read image */
+Image *ReadGIFImage(const ImageInfo *image_info)
+{
+ [ decode the image ... ]
+}
+/* Write image */
+unsigned int WriteGIFImage(const ImageInfo *image_info,Image *image)
+{
+ [ encode the image ... ]
+}
+#include &lt;stdio.h&gt;
+int main( void )
+{
+ struct MagickInfo* info;
+ info = SetMagickInfo(&quot;GIF&quot;);
+ if ( info == (MagickInfo*)NULL )
+ exit(1);
+ info-&gt;decoder = ReadGIFImage;
+ info-&gt;encoder = WriteGIFImage;
+ info-&gt;adjoin = False;
+ info-&gt;description = &quot;CompuServe graphics interchange format&quot;;
+ /* Add MagickInfo structure to list */
+ RegisterMagickInfo(info);
+ info = GetMagickInfo(&quot;GIF&quot;);
+ [ do something with info ... ]
+ ListMagickInfo( stdout );
+ return;
+}
+</pre>
+<p>MagickInfo Structure Definition</p>
+<p>The members of the MagickInfo structure are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>MagickInfo Structure Members</caption>
+<colgroup>
+<col width="12%" />
+<col width="20%" />
+<col width="67%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>adjoin</td>
+<td>unsigned int</td>
+<td>Set to non-zero (True) if this file format supports multi-frame
+images.</td>
+</tr>
+<tr><td>blob_support</td>
+<td>unsigned int</td>
+<td>Set to non-zero (True) if the encoder and decoder for this format
+supports operating on arbitrary BLOBs (rather than only disk
+files).</td>
+</tr>
+<tr><td>data</td>
+<td>void *</td>
+<td>User specified data. A way to pass any sort of data structure to
+the endoder/decoder. To set this, GetMagickInfo() must be called
+to first obtain a pointer to the registered structure since it can
+not be set via a RegisterMagickInfo() parameter.</td>
+</tr>
+<tr><td>decoder</td>
+<td>Image *(*decoder)
+(const ImageInfo
+*)</td>
+<td>Function to decode image data and return GraphicsMagick Image.</td>
+</tr>
+<tr><td>description</td>
+<td>char *</td>
+<td>Long form image format description (e.g. &quot;CompuServe graphics
+interchange format&quot;).</td>
+</tr>
+<tr><td>encoder</td>
+<td>unsigned int
+(*encoder)(const
+ImageInfo *, Image
+*)</td>
+<td>Function to encode image data with options passed via ImageInfo
+and image represented by Image.</td>
+</tr>
+<tr><td>module</td>
+<td>char *</td>
+<td>Name of module (e.g. &quot;GIF&quot;) which registered this format. Set to
+NULL if format is not registered by a module.</td>
+</tr>
+<tr><td>name</td>
+<td>const char *</td>
+<td>Magick string (e.g. &quot;GIF&quot;) which identifies this format.</td>
+</tr>
+<tr><td>next</td>
+<td>MagickInfo</td>
+<td>Next MagickInfo struct in linked-list. NULL if none.</td>
+</tr>
+<tr><td>previous</td>
+<td>MagickInfo</td>
+<td>Previous MagickInfo struct in linked-list. NULL if none.</td>
+</tr>
+<tr><td>raw</td>
+<td>unsigned int</td>
+<td>Image format does not contain size (must be specified in
+ImageInfo).</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="monitorhandler">
+<h1><a class="toc-backref" href="#id31">MonitorHandler</a></h1>
+<p>MonitorHandler is the function type to be used for the progress monitor
+callback. Its definition is as follows:</p>
+<pre class="literal-block">
+typedef unsigned int
+ (*MonitorHandler)(const char *text, const magick_int64_t quantum,
+ const magick_uint64_t span, ExceptionInfo *exception);
+</pre>
+<p>The operation of the monitor handler is described in the following table:</p>
+<table border="1" class="docutils">
+<caption>MonitorHandler Parameters</caption>
+<colgroup>
+<col width="25%" />
+<col width="25%" />
+<col width="49%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Parameter</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>return status</td>
+<td>unsigned int</td>
+<td>The progress monitor should normally return
+True (a non-zero value) if the operation is
+to continue. If the progress monitor returns
+false, then the operation is will be aborted.
+This mechanism allows a user to terminate a
+process which is taking too long to complete.</td>
+</tr>
+<tr><td>text</td>
+<td>const char *</td>
+<td>A description of the current operation being
+performed.</td>
+</tr>
+<tr><td>quantum</td>
+<td>const magick_int64_t</td>
+<td>A value within the range of 0 to span which
+indicates the degree of progress.</td>
+</tr>
+<tr><td>span</td>
+<td>const magick_uint64_t</td>
+<td>The total range that quantum will span.</td>
+</tr>
+<tr><td>exception</td>
+<td>exceptionInfo *</td>
+<td>If the progress monitor returns False (abort
+operation), it should also update the
+structure passed via the exception parameter
+so that an error message may be reported to
+the user.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="montageinfo">
+<h1><a class="toc-backref" href="#id32">MontageInfo</a></h1>
+<pre class="literal-block">
+typedef struct _MontageInfo
+{
+ char
+ *geometry,
+ *tile,
+ *title,
+ *frame,
+ *texture,
+ *font;
+
+ double
+ pointsize;
+
+ unsigned long
+ border_width;
+
+ unsigned int
+ shadow;
+
+ PixelPacket
+ fill,
+ stroke,
+ background_color,
+ border_color,
+ matte_color;
+
+ GravityType
+ gravity;
+
+ char
+ filename[MaxTextExtent];
+
+ unsigned long
+ signature;
+} MontageInfo;
+</pre>
+</div>
+<div class="section" id="noisetype">
+<h1><a class="toc-backref" href="#id33">NoiseType</a></h1>
+<p>NoiseType is used as an argument to select the type of noise to be added
+to the image.</p>
+<table border="1" class="docutils">
+<caption>NoiseType</caption>
+<colgroup>
+<col width="48%" />
+<col width="52%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UniformNoise</td>
+<td>Uniform noise</td>
+</tr>
+<tr><td>GaussianNoise</td>
+<td>Gaussian noise</td>
+</tr>
+<tr><td>MultiplicativeGaussianNoise</td>
+<td>Multiplicative Gaussian noise</td>
+</tr>
+<tr><td>ImpulseNoise</td>
+<td>Impulse noise</td>
+</tr>
+<tr><td>LaplacianNoise</td>
+<td>Laplacian noise</td>
+</tr>
+<tr><td>PoissonNoise</td>
+<td>Poisson noise</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="orientationtype">
+<h1><a class="toc-backref" href="#id34">OrientationType</a></h1>
+<p>OrientationType specifies the orientation of the image. Useful for when
+the image is produced via a different ordinate system, the camera was
+turned on its side, or the page was scanned sideways.</p>
+<table border="1" class="docutils">
+<caption>OrientationType</caption>
+<colgroup>
+<col width="25%" />
+<col width="29%" />
+<col width="45%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Scanline Direction</td>
+<td>Frame Direction</td>
+</tr>
+<tr><td>UndefinedOrientation</td>
+<td>Unknown</td>
+<td>Unknown</td>
+</tr>
+<tr><td>TopLeftOrientation</td>
+<td>Left to right</td>
+<td>Top to bottom</td>
+</tr>
+<tr><td>TopRightOrientation</td>
+<td>Right to left</td>
+<td>Top to bottom</td>
+</tr>
+<tr><td>BottomRightOrientation</td>
+<td>Right to left</td>
+<td>Bottom to top</td>
+</tr>
+<tr><td>BottomLeftOrientation</td>
+<td>Left to right</td>
+<td>Bottom to top</td>
+</tr>
+<tr><td>LeftTopOrientation</td>
+<td>Top to bottom</td>
+<td>Left to right</td>
+</tr>
+<tr><td>RightTopOrientation</td>
+<td>Top to bottom</td>
+<td>Right to left</td>
+</tr>
+<tr><td>RightBottomOrientation</td>
+<td>Bottom to top</td>
+<td>Right to left</td>
+</tr>
+<tr><td>LeftBottomOrientation</td>
+<td>Bottom to top</td>
+<td>Left to right</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="paintmethod">
+<h1><a class="toc-backref" href="#id35">PaintMethod</a></h1>
+<p>PaintMethod specifies how pixel colors are to be replaced in the image.
+It is used to select the pixel-filling algorithm employed.</p>
+<table border="1" class="docutils">
+<caption>PaintMethod</caption>
+<colgroup>
+<col width="19%" />
+<col width="81%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>PointMethod</td>
+<td>Replace pixel color at point.</td>
+</tr>
+<tr><td>ReplaceMethod</td>
+<td>Replace color for all image pixels matching color at point.</td>
+</tr>
+<tr><td>FloodfillMethod</td>
+<td>Replace color for pixels surrounding point until encountering pixel that fails
+to match color at point.</td>
+</tr>
+<tr><td>FillToBorderMethod</td>
+<td>Replace color for pixels surrounding point until encountering pixels matching
+border color.</td>
+</tr>
+<tr><td>ResetMethod</td>
+<td>Replace colors for all pixels in image with pen color.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="pixelpacket">
+<h1><a class="toc-backref" href="#id36">PixelPacket</a></h1>
+<p>The PixelPacket structure is used to represent DirectClass color pixels
+in GraphicsMagick. If the image is indicated as a PseudoClass image, its
+DirectClass representation is only valid immediately after calling
+SyncImage(). If an image is set as PseudoClass and the DirectClass
+representation is modified, the image should then be set as DirectClass.
+Use QuantizeImage() to restore the PseudoClass colormap if the
+DirectClass representation is modified.</p>
+<p>The members of the PixelPacket structure are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>PixelPacket Structure Members</caption>
+<colgroup>
+<col width="11%" />
+<col width="10%" />
+<col width="24%" />
+<col width="33%" />
+<col width="23%" />
+</colgroup>
+<tbody valign="top">
+<tr><td rowspan="2">Member</td>
+<td rowspan="2">Type</td>
+<td colspan="3">Interpretation</td>
+</tr>
+<tr><td>RGBColorspace (3)</td>
+<td>RGBColorspace + matte(3)</td>
+<td>CMYKColorspace</td>
+</tr>
+<tr><td>red</td>
+<td>Quantum</td>
+<td>Red</td>
+<td>Red</td>
+<td>Cyan</td>
+</tr>
+<tr><td>green</td>
+<td>Quantum</td>
+<td>Green</td>
+<td>Green</td>
+<td>Magenta</td>
+</tr>
+<tr><td>blue</td>
+<td>Quantum</td>
+<td>Blue</td>
+<td>Blue</td>
+<td>Yellow</td>
+</tr>
+<tr><td>opacity</td>
+<td>Quantum</td>
+<td>Ignored</td>
+<td>Opacity</td>
+<td>Black</td>
+</tr>
+</tbody>
+</table>
+<p>Notes:</p>
+<blockquote>
+<ol class="arabic simple">
+<li>Quantum is an unsigned short (MaxRGB=65535) if GraphicsMagick is
+built using -DQuantumDepth=16 Otherwise it is an unsigned char
+(MaxRGB=255).</li>
+<li>SyncImage() may be used to synchronize the DirectClass color pixels
+to the current PseudoClass colormap.</li>
+<li>For pixel representation purposes, all colorspaces are treated like
+RGBColorspace except for CMYKColorspace.</li>
+</ol>
+</blockquote>
+</div>
+<div class="section" id="pointinfo">
+<h1><a class="toc-backref" href="#id37">PointInfo</a></h1>
+<p>The PointInfo structure is used by the ChromaticityInfo structure to
+specify chromaticity point values. This defines the boundaries and gammut
+(range of included color) of the colorspace.</p>
+<p>The members of the PointInfo structure are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>PointInfo Structure Members</caption>
+<colgroup>
+<col width="31%" />
+<col width="25%" />
+<col width="44%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>x</td>
+<td>double</td>
+<td>X ordinate</td>
+</tr>
+<tr><td>y</td>
+<td>double</td>
+<td>Y ordinate</td>
+</tr>
+<tr><td>z</td>
+<td>double</td>
+<td>Z ordinate</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="profileinfo">
+<h1><a class="toc-backref" href="#id38">ProfileInfo</a></h1>
+<p>The ProfileInfo structure is used to represent ICC or IPCT profiles in
+GraphicsMagick (stored as an opaque BLOB).</p>
+<p>The members of the ProfileInfo structure are shown in the following table:</p>
+<table border="1" class="docutils">
+<caption>ProfileInfo Structure Members</caption>
+<colgroup>
+<col width="24%" />
+<col width="40%" />
+<col width="36%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>length</td>
+<td>unsigned int</td>
+<td>Profile length</td>
+</tr>
+<tr><td>info</td>
+<td>unsigned char *</td>
+<td>Profile data</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="quantizeinfo">
+<h1><a class="toc-backref" href="#id39">QuantizeInfo</a></h1>
+<p>The QuantizeInfo structure is used to support passing parameters to
+GraphicsMagick's color quantization (reduction) functions. Color
+quantization is the process of analyzing one or more images, and
+calculating a color palette which best approximates the image within a
+specified colorspace, and then adjusting the image pixels to use the
+calculated color palette. The maximum number of colors allowed in the
+color palette may be specified.</p>
+<table border="1" class="docutils">
+<caption>Methods Supporting QuantizeInfo</caption>
+<colgroup>
+<col width="20%" />
+<col width="80%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Method</td>
+<td>Description</td>
+</tr>
+<tr><td>GetQuantizeInfo()</td>
+<td>Allocate new structure with defaults set.</td>
+</tr>
+<tr><td>CloneQuantizeInfo()</td>
+<td>Copy existing structure, allocating new structure in the process.</td>
+</tr>
+<tr><td>DestroyQuantizeInfo
+()</td>
+<td>Deallocate structure, including any members.</td>
+</tr>
+<tr><td>QuantizeImage</td>
+<td>Analyzes the colors within a reference image and chooses a fixed number of
+colors to represent the image.</td>
+</tr>
+<tr><td>QuantizeImages</td>
+<td>Analyzes the colors within a set of reference images and chooses a fixed
+number of colors to represent the set.</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<caption>QuantizeInfo Structure Members</caption>
+<colgroup>
+<col width="13%" />
+<col width="14%" />
+<col width="72%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>colorspace</td>
+<td>ColorspaceType</td>
+<td>The colorspace to quantize in. Color reduction, by default, takes
+place in the RGB color space. Empirical evidence suggests that
+distances in color spaces such as YUV or YIQ correspond to
+perceptual color differences more closely than do distances in RGB
+space. The Transparent color space behaves uniquely in that it
+preserves the matte channel of the image if it exists.</td>
+</tr>
+<tr><td>dither</td>
+<td>unsigned int</td>
+<td>Set to True (non-zero) to apply Floyd/Steinberg error diffusion to the
+image. When the size of the color palette is less than the image
+colors, this trades off spacial resolution for color resolution by
+dithering to achieve a similar looking image.</td>
+</tr>
+<tr><td>measure_error</td>
+<td>unsigned int</td>
+<td>Set to True (non-zero) to calculate quantization errors when
+quantizing the image.</td>
+</tr>
+<tr><td>number_colors</td>
+<td>unsigned int</td>
+<td>Specify the maximum number of colors in the output image. Must be
+equal to, or less than MaxRGB, which is determined by the value of
+QuantumLeap when GraphicsMagick was compiled.</td>
+</tr>
+<tr><td>signature</td>
+<td>unsigned long</td>
+<td>???</td>
+</tr>
+<tr><td>tree_depth</td>
+<td>unsigned int</td>
+<td>Specify the tree depth to use while quantizing. The values zero and
+one support automatic tree depth determination. The tree depth may be
+forced via values ranging from two to eight. The ideal tree depth
+depends on the characteristics of the input image, and may be
+determined through experimentation.</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="quantum">
+<h1><a class="toc-backref" href="#id40">Quantum</a></h1>
+<p>Quantum is the base type ('unsigned char', 'unsigned short', 'unsigned
+int') used to store a pixel component (e.g. 'R' is one pixel component of
+an RGB pixel).</p>
+</div>
+<div class="section" id="quantumtype">
+<h1><a class="toc-backref" href="#id41">QuantumType</a></h1>
+<p>QuantumType is used to indicate the source or destination format of
+entire pixels, or components of pixels (&quot;Quantums&quot;) while they are being
+read, or written to, a pixel cache. The validity of these format
+specifications depends on whether the Image pixels are in RGB format,
+RGBA format, or CMYK format. The pixel Quantum size is determined by the
+Image depth (eight or sixteen bits).</p>
+<table border="1" class="docutils">
+<caption>RGB(A) Image Quantums</caption>
+<colgroup>
+<col width="18%" />
+<col width="82%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>IndexQuantum</td>
+<td>PseudoColor colormap indices (valid only for image with colormap)</td>
+</tr>
+<tr><td>RedQuantum</td>
+<td>Red pixel Quantum</td>
+</tr>
+<tr><td>GreenQuantum</td>
+<td>Green pixel Quantum</td>
+</tr>
+<tr><td>BlueQuantum</td>
+<td>Blue pixel Quantum</td>
+</tr>
+<tr><td>OpacityQuantum</td>
+<td>Opacity (Alpha) Quantum</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<caption>CMY(K) Image Quantum</caption>
+<colgroup>
+<col width="40%" />
+<col width="60%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>CyanQuantum</td>
+<td>Cyan pixel Quantum</td>
+</tr>
+<tr><td>MagentaQuantum</td>
+<td>Magenta pixel Quantum</td>
+</tr>
+<tr><td>YellowQuantum</td>
+<td>Yellow pixel Quantum</td>
+</tr>
+<tr><td>BlackQuantum</td>
+<td>Black pixel Quantum</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<caption>Grayscale Image Quantums</caption>
+<colgroup>
+<col width="58%" />
+<col width="42%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>GrayQuantum</td>
+<td>Gray pixel</td>
+</tr>
+<tr><td>GrayOpacityQuantum</td>
+<td>Pixel opacity</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<caption>Entire Pixels (Expressed in Byte Order)</caption>
+<colgroup>
+<col width="28%" />
+<col width="72%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>RGBQuantum</td>
+<td>RGB pixel (24 or 48 octets)</td>
+</tr>
+<tr><td>RGBAQuantum</td>
+<td>RGBA pixel (32 or 64 octets)</td>
+</tr>
+<tr><td>CMYKQuantum</td>
+<td>CMYK pixel (32 or 64 octets)</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="rectangleinfo">
+<h1><a class="toc-backref" href="#id42">RectangleInfo</a></h1>
+<p>The RectangleInfo structure is used to represent positioning information
+in GraphicsMagick.</p>
+<p>The members of the RectangleInfo structure are shown in the following
+table:</p>
+<table border="1" class="docutils">
+<caption>RectangleInfo Structure Members</caption>
+<colgroup>
+<col width="20%" />
+<col width="25%" />
+<col width="55%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Member</td>
+<td>Type</td>
+<td>Description</td>
+</tr>
+<tr><td>width</td>
+<td>unsigned int</td>
+<td>Rectangle width</td>
+</tr>
+<tr><td>height</td>
+<td>unsigned int</td>
+<td>Rectangle height</td>
+</tr>
+<tr><td>x</td>
+<td>int</td>
+<td>Rectangle horizontal offset</td>
+</tr>
+<tr><td>y</td>
+<td>int</td>
+<td>Rectangle vertical offset</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="registrytype">
+<h1><a class="toc-backref" href="#id43">RegistryType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UndefinedRegistryType,
+ ImageRegistryType,
+ ImageInfoRegistryType
+} RegistryType;
+</pre>
+</div>
+<div class="section" id="renderingintent">
+<h1><a class="toc-backref" href="#id44">RenderingIntent</a></h1>
+<p>Rendering intent is a concept defined by ICC Spec ICC.1:1998-09, &quot;File
+Format for Color Profiles&quot;. GraphicsMagick uses RenderingIntent in order
+to support ICC Color Profiles.</p>
+<p>From the specification: &quot;Rendering intent specifies the style of
+reproduction to be used during the evaluation of this profile in a
+sequence of profiles. It applies specifically to that profile in the
+sequence and not to the entire sequence. Typically, the user or
+application will set the rendering intent dynamically at runtime or
+embedding time.&quot;</p>
+<table border="1" class="docutils">
+<caption>RenderingIntent</caption>
+<colgroup>
+<col width="17%" />
+<col width="83%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UndefinedIntent</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>SaturationIntent</td>
+<td>A rendering intent that specifies the saturation of the pixels in the image is
+preserved perhaps at the expense of accuracy in hue and lightness.</td>
+</tr>
+<tr><td>PerceptualIntent</td>
+<td>A rendering intent that specifies the full gamut of the image is compressed or
+expanded to fill the gamut of the destination device. Gray balance is preserved
+but colorimetric accuracy might not be preserved.</td>
+</tr>
+<tr><td>AbsoluteIntent</td>
+<td>Absolute colorimetric</td>
+</tr>
+<tr><td>RelativeIntent</td>
+<td>Relative colorimetric</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="resolutiontype">
+<h1><a class="toc-backref" href="#id45">ResolutionType</a></h1>
+<p>By default, GraphicsMagick defines resolutions in pixels per inch.
+ResolutionType provides a means to adjust this.</p>
+<table border="1" class="docutils">
+<caption>ResolutionType</caption>
+<colgroup>
+<col width="30%" />
+<col width="70%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Enumeration</td>
+<td>Description</td>
+</tr>
+<tr><td>UndefinedResolution</td>
+<td>Unset value.</td>
+</tr>
+<tr><td>PixelsPerInchResolution</td>
+<td>Density specifications are specified in units of pixels per inch
+(english units).</td>
+</tr>
+<tr><td>PixelsPerCentimeterResolution</td>
+<td>Density specifications are specified in units of pixels per
+centimeter (metric units).</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="resourcetype">
+<h1><a class="toc-backref" href="#id46">ResourceType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UndefinedResource,
+ FileResource,
+ MemoryResource,
+ MapResource,
+ DiskResource
+} ResourceType;
+</pre>
+</div>
+<div class="section" id="segmentinfo">
+<h1><a class="toc-backref" href="#id47">SegmentInfo</a></h1>
+<pre class="literal-block">
+typedef struct _SegmentInfo
+{
+ double
+ x1,
+ y1,
+ x2,
+ y2;
+} SegmentInfo;
+</pre>
+</div>
+<div class="section" id="signatureinfo">
+<h1><a class="toc-backref" href="#id48">SignatureInfo</a></h1>
+<pre class="literal-block">
+typedef struct _SignatureInfo
+{
+ unsigned long
+ digest[8],
+ low_order,
+ high_order;
+
+ long
+ offset;
+
+ unsigned char
+ message[SignatureSize];
+} SignatureInfo;
+</pre>
+</div>
+<div class="section" id="storagetype">
+<h1><a class="toc-backref" href="#id49">StorageType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ CharPixel,
+ ShortPixel,
+ IntegerPixel,
+ LongPixel,
+ FloatPixel,
+ DoublePixel
+} StorageType;
+</pre>
+</div>
+<div class="section" id="streamhandler">
+<h1><a class="toc-backref" href="#id50">StreamHandler</a></h1>
+<pre class="literal-block">
+typedef unsigned int
+ (*StreamHandler)(const Image *,const void *,const size_t);
+</pre>
+</div>
+<div class="section" id="stretchtype">
+<h1><a class="toc-backref" href="#id51">StretchType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ NormalStretch,
+ UltraCondensedStretch,
+ ExtraCondensedStretch,
+ CondensedStretch,
+ SemiCondensedStretch,
+ SemiExpandedStretch,
+ ExpandedStretch,
+ ExtraExpandedStretch,
+ UltraExpandedStretch,
+ AnyStretch
+} StretchType;
+</pre>
+</div>
+<div class="section" id="styletype">
+<h1><a class="toc-backref" href="#id52">StyleType</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ NormalStyle,
+ ItalicStyle,
+ ObliqueStyle,
+ AnyStyle
+} StyleType;
+</pre>
+</div>
+<div class="section" id="typemetric">
+<h1><a class="toc-backref" href="#id53">TypeMetric</a></h1>
+<pre class="literal-block">
+typedef struct _TypeMetric
+{
+ PointInfo
+ pixels_per_em;
+
+ double
+ ascent,
+ descent,
+ width,
+ height,
+ max_advance;
+
+ SegmentInfo
+ bounds;
+
+ double
+ underline_position,
+ underline_thickness;
+} TypeMetric;
+</pre>
+</div>
+<div class="section" id="viewinfo">
+<h1><a class="toc-backref" href="#id54">ViewInfo</a></h1>
+<p>ViewInfo represents a handle to a pixel view, which represents a uniquely
+selectable rectangular region of pixels. The only limit on the number of
+views is the amount of available memory. Each Image contains a collection
+of default views (one view per thread) so that the image may be usefully
+accessed without needing to explicitly allocate pixel views.</p>
+<pre class="literal-block">
+typedef void *ViewInfo;
+</pre>
+</div>
+<div class="section" id="virtualpixelmethod">
+<h1><a class="toc-backref" href="#id55">VirtualPixelMethod</a></h1>
+<pre class="literal-block">
+typedef enum
+{
+ UndefinedVirtualPixelMethod,
+ ConstantVirtualPixelMethod,
+ EdgeVirtualPixelMethod,
+ MirrorVirtualPixelMethod,
+ TileVirtualPixelMethod
+} VirtualPixelMethod;
+</pre>
+</div>
+<div class="section" id="magickxresourceinfo">
+<h1><a class="toc-backref" href="#id56">MagickXResourceInfo</a></h1>
+<pre class="literal-block">
+typedef struct _XResourceInfo
+{
+ XrmDatabase
+ resource_database;
+
+ ImageInfo
+ *image_info;
+
+ QuantizeInfo
+ *quantize_info;
+
+ unsigned long
+ colors;
+
+ unsigned int
+ close_server,
+ backdrop;
+
+ char
+ *background_color,
+ *border_color;
+
+ char
+ *client_name;
+
+ XColormapType
+ colormap;
+
+ unsigned int
+ border_width,
+ color_recovery,
+ confirm_exit,
+ delay;
+
+ char
+ *display_gamma;
+
+ char
+ *font,
+ *font_name[MaxNumberFonts],
+ *foreground_color;
+
+ unsigned int
+ display_warnings,
+ gamma_correct;
+
+ char
+ *icon_geometry;
+
+ unsigned int
+ iconic,
+ immutable;
+
+ char
+ *image_geometry;
+
+ char
+ *map_type,
+ *matte_color,
+ *name;
+
+ unsigned int
+ magnify,
+ pause; char
+ *pen_colors[MaxNumberPens];
+
+ char
+ *text_font,
+ *title;
+
+ int
+ quantum;
+
+ unsigned int
+ update,
+ use_pixmap,
+ use_shared_memory;
+
+ unsigned long
+ undo_cache;
+
+ char
+ *visual_type,
+ *window_group,
+ *window_id,
+ *write_filename;
+
+ Image
+ *copy_image;
+
+ int
+ gravity;
+
+ char
+ home_directory[MaxTextExtent];
+} XResourceInfo;
+</pre>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/api/types.rst b/www/api/types.rst
new file mode 100644
index 0000000..32c6fc4
--- /dev/null
+++ b/www/api/types.rst
@@ -0,0 +1,2074 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+====================
+GraphicsMagick Types
+====================
+
+.. contents::
+ :local:
+
+
+AffineMatrix
+============
+
+AffineMatrix defines a 2D affine matrix transform.
+
+::
+
+ typedef struct _AffineMatrix
+ {
+ double
+ sx,
+ rx,
+ ry,
+ sy,
+ tx,
+ ty;
+ } AffineMatrix;
+
+BlobInfo
+========
+
+BlobInfo is an opaque pointer reference to the internal structure of an
+I/O blob handle.
+
+Cache
+=====
+
+::
+
+ typedef void
+ *Cache;
+
+ChannelType
+===========
+
+::
+
+ typedef enum
+ {
+ UndefinedChannel,
+ RedChannel, /* RGB Red channel */
+ CyanChannel, /* CMYK Cyan channel */
+ GreenChannel, /* RGB Green channel */
+ MagentaChannel, /* CMYK Magenta channel */
+ BlueChannel, /* RGB Blue channel */
+ YellowChannel, /* CMYK Yellow channel */
+ OpacityChannel, /* Opacity channel */
+ BlackChannel, /* CMYK Black (K) channel */
+ MatteChannel, /* Same as Opacity channel (deprecated) */
+ AllChannels, /* Color channels */
+ GrayChannel /* Color channels represent an intensity. */
+ } ChannelType;
+
+ChromaticityInfo
+================
+
+The ChromaticityInfo structure is used to represent chromaticity
+(colorspace primary coordinates in xy space) values for images in
+GraphicsMagick.
+
+The members of the ChromaticityInfo structure are shown in the following
+table:
+
+.. table:: ChromaticityInfo Structure Members
+
+ +-------------------+-----------+-----------------------------------------------------------------+
+ | Member | Type | Description |
+ +-------------------+-----------+-----------------------------------------------------------------+
+ |red_primary |PointInfo |Chromaticity red primary point (e.g. x=0.64, y=0.33) |
+ +-------------------+-----------+-----------------------------------------------------------------+
+ |green_primary |PointInfo |Chromaticity green primary point (e.g. x=0.3, y=0.6) |
+ +-------------------+-----------+-----------------------------------------------------------------+
+ |blue_primary |PointInfo |Chromaticity blue primary point (e.g. x=0.15, y=0.06) |
+ +-------------------+-----------+-----------------------------------------------------------------+
+ |white_point |PointInfo |Chromaticity white point (e.g. x=0.3127, y=0.329) |
+ +-------------------+-----------+-----------------------------------------------------------------+
+
+
+ClassType
+=========
+
+ClassType enumeration specifies the image storage class.
+
+.. table:: ClassType
+
+ +----------------+--------------------------------------------------------------------------------+
+ | Enumeration | Description |
+ +----------------+--------------------------------------------------------------------------------+
+ |UndefinedClass |Unset value. |
+ +----------------+--------------------------------------------------------------------------------+
+ |DirectClass |Image is composed of pixels which represent literal color values. |
+ +----------------+--------------------------------------------------------------------------------+
+ |PseudoClass |Image is composed of pixels which specify an index in a color palette. |
+ +----------------+--------------------------------------------------------------------------------+
+
+
+ClipPathUnits
+=============
+
+::
+
+ typedef enum
+ {
+ UserSpace,
+ UserSpaceOnUse,
+ ObjectBoundingBox
+ } ClipPathUnits;
+
+
+ColorPacket
+===========
+
+::
+
+ typedef struct _ColorPacket
+ {
+ PixelPacket
+ pixel;
+
+ unsigned short
+ index;
+
+ unsigned long
+ count;
+ } ColorPacket;
+
+
+ColorspaceType
+==============
+
+The ColorspaceType enumeration is used to specify the colorspace that
+quantization (color reduction and mapping) is done under or to specify
+the colorspace when encoding an output image. Colorspaces are ways of
+describing colors to fit the requirements of a particular application
+(e.g. Television, offset printing, color monitors). Color reduction, by
+default, takes place in the RGBColorspace. Empirical evidence suggests
+that distances in color spaces such as YUVColorspace or YIQColorspace
+correspond to perceptual color differences more closely han do distances
+in RGB space. These color spaces may give better results when color
+reducing an image. Refer to quantize for more details.
+
+When encoding an output image, the colorspaces RGBColorspace,
+CMYKColorspace, and GRAYColorspace may be specified. The CMYKColorspace
+option is only applicable when writing TIFF, JPEG, and Adobe Photoshop
+bitmap (PSD) files.
+
+
+.. table:: ColorspaceType
+
+ ========================= ======================================================
+ Enumeration Description
+ ========================= ======================================================
+ UndefinedColorspace Unset value.
+ RGBColorspace Red, Green, Blue colorspace.
+ GRAYColorspace Similar to Luma (Y) according to ITU-R 601
+ TransparentColorspace RGB which preserves the matte while quantizing colors.
+ OHTAColorspace
+ XYZColorspace CIE XYZ
+ YCCColorspace Kodak PhotoCD PhotoYCC
+ YIQColorspace
+ YPbPrColorspace
+ YUVColorspace YUV colorspace as used for computer video.
+ CMYKColorspace Cyan, Magenta, Yellow, Black colorspace.
+ sRGBColorspace Kodak PhotoCD sRGB
+ HSLColorspace Hue, saturation, luminosity
+ HWBColorspace Hue, whiteness, blackness
+ LABColorspace ITU LAB
+ CineonLogRGBColorspace RGB data with Cineon Log scaling, 2.048 density range
+ Rec601LumaColorspace Luma (Y) according to ITU-R 601
+ Rec601YCbCrColorspace YCbCr according to ITU-R 601
+ Rec709LumaColorspace Luma (Y) according to ITU-R 709
+ Rec709YCbCrColorspace YCbCr according to ITU-R 709
+ ========================= ======================================================
+
+ComplianceType
+==============
+
+::
+
+ typedef enum
+ {
+ UndefinedCompliance = 0x0000,
+ NoCompliance = 0x0000,
+ SVGCompliance = 0x0001,
+ X11Compliance = 0x0002,
+ XPMCompliance = 0x0004,
+ AllCompliance = 0xffff
+ } ComplianceType;
+
+
+CompositeOperator
+=================
+
+CompositeOperator is used to select the image composition algorithm used
+to compose a composite image with an image. By default, each of the
+composite image pixels are replaced by the corresponding image tile
+pixel. Specify CompositeOperator to select a different algorithm.
+
+The image compositor requires a matte, or alpha channel in the image for
+some operations. This extra channel usually defines a mask which
+represents a sort of a cookie-cutter for the image. This is the case when
+matte is 255 (full coverage) for pixels inside the shape, zero outside,
+and between zero and 255 on the boundary. For certain operations, if
+image does not have a matte channel, it is initialized with 0 for any
+pixel matching in color to pixel location (0,0), otherwise 255 (to work
+properly borderWidth must be 0).
+
+.. table:: CompositeOperator
+
+ ====================== ==========================================================================
+ Enumeration Description
+ ====================== ==========================================================================
+ UndefinedCompositeOp Unset value.
+ OverCompositeOp The result is the union of the the two image shapes with the composite
+ image obscuring image in the region of overlap.
+ InCompositeOp The result is a simply composite image cut by the shape of image. None of
+ the image data of image is included in the result.
+ OutCompositeOp The resulting image is composite image with the shape of image cut out.
+ AtopCompositeOp The result is the same shape as image image, with composite image
+ obscuring image there the image shapes overlap. Note that this differs
+ from OverCompositeOp because the portion of composite image outside of
+ image's shape does not appear in the result.
+ XorCompositeOp The result is the image data from both composite image and image that is
+ outside the overlap region. The overlap region will be blank.
+ PlusCompositeOp The result is just the sum of the image data. Output values are cropped
+ to 255 (no overflow). This operation is independent of the matte channels.
+ MinusCompositeOp The result of composite image - image, with overflow cropped to zero. The
+ matte chanel is ignored (set to 255, full coverage).
+ AddCompositeOp The result of composite image + image, with overflow wrapping around (mod
+ 256).
+ SubtractCompositeOp The result of composite image - image, with underflow wrapping around (mod
+ 256). The add and subtract operators can be used to perform reversible
+ transformations.
+ DifferenceCompositeOp The result of abs(composite image - image). This is useful for comparing
+ two very similar images.
+ BumpmapCompositeOp The result image shaded by composite image.
+ CopyCompositeOp The resulting image is image replaced with composite image. Here the matte
+ information is ignored.
+ CopyRedCompositeOp The resulting image is the red layer in image replaced with the red layer
+ in composite image. The other layers are copied untouched.
+ CopyGreenCompositeOp The resulting image is the green layer in image replaced with the green
+ layer in composite image. The other layers are copied untouched.
+ CopyBlueCompositeOp The resulting image is the blue layer in image replaced with the blue
+ layer in composite image. The other layers are copied untouched.
+ CopyOpacityCompositeOp The resulting image is the matte layer in image replaced with the matte
+ layer in composite image. The other layers are copied untouched.
+ ClearCompositeOp Pixels in the region are set to Transparent.
+ DissolveCompositeOp
+ DisplaceCompositeOp
+ ModulateCompositeOp Modulate brightness in HSL space.
+ ThresholdCompositeOp
+ NoCompositeOp Do nothing at all.
+ DarkenCompositeOp
+ LightenCompositeOp
+ HueCompositeOp Copy Hue channel (from HSL colorspace).
+ SaturateCompositeOp Copy Saturation channel (from HSL colorspace).
+ ColorizeCompositeOp Copy Hue and Saturation channels (from HSL colorspace).
+ LuminizeCompositeOp Copy Brightness channel (from HSL colorspace).
+ ScreenCompositeOp [Not yet implemented]
+ OverlayCompositeOp [Not yet implemented]
+ CopyCyanCompositeOp Copy the Cyan channel.
+ CopyMagentaCompositeOp Copy the Magenta channel.
+ CopyYellowCompositeOp Copy the Yellow channel.
+ CopyBlackCompositeOp Copy the Black channel.
+ DivideCompositeOp
+ ====================== ==========================================================================
+
+CompressionType
+===============
+
+CompressionType is used to express the desired compression type when
+encoding an image. Be aware that most image types only support a sub-set
+of the available compression types. If the compression type specified is
+incompatable with the image, GraphicsMagick selects a compression type
+compatable with the image type.
+
+
+.. table:: CompressionType
+
+ +---------------------------+---------------------------------------------------------------------+
+ | Enumeration | Description |
+ +---------------------------+---------------------------------------------------------------------+
+ |UndefinedCompression |Unset value. |
+ +---------------------------+---------------------------------------------------------------------+
+ |NoCompression |No compression |
+ +---------------------------+---------------------------------------------------------------------+
+ |BZipCompression |BZip (Burrows-Wheeler block-sorting text compression algorithm and |
+ | |Huffman coding) as used by bzip2 utilities |
+ +---------------------------+---------------------------------------------------------------------+
+ |FaxCompression |CCITT Group 3 FAX compression |
+ +---------------------------+---------------------------------------------------------------------+
+ |Group4Compression |CCITT Group 4 FAX compression (used only for TIFF) |
+ +---------------------------+---------------------------------------------------------------------+
+ |JPEGCompression |JPEG compression |
+ +---------------------------+---------------------------------------------------------------------+
+ |LosslessJPEGCompression |Lossless JPEG compression |
+ +---------------------------+---------------------------------------------------------------------+
+ |LZWCompression |Lempel-Ziv-Welch (LZW) compression (caution, patented by Unisys) |
+ +---------------------------+---------------------------------------------------------------------+
+ |RLECompression |Run-Length encoded (RLE) compression |
+ +---------------------------+---------------------------------------------------------------------+
+ |ZipCompression |Lempel-Ziv compression (LZ77) as used in PKZIP and GNU gzip. |
+ +---------------------------+---------------------------------------------------------------------+
+
+DecorationType
+==============
+
+::
+
+ typedef enum
+ {
+ NoDecoration,
+ UnderlineDecoration,
+ OverlineDecoration,
+ LineThroughDecoration
+ } DecorationType;
+
+
+
+DrawContext
+===========
+
+::
+
+ typedef struct _DrawContext *DrawContext;
+
+
+DrawInfo
+========
+
+The DrawInfo structure is used to support annotating an image using
+drawing commands.
+
+
+.. table:: Methods Supporting DrawInfo
+
+ +----------------------+--------------------------------------------------------------------------+
+ | Method | Description |
+ +----------------------+--------------------------------------------------------------------------+
+ |GetDrawInfo() |Allocate new structure with defaults set. |
+ +----------------------+--------------------------------------------------------------------------+
+ |CloneDrawInfo() |Copy existing structure, allocating new structure in the process. |
+ +----------------------+--------------------------------------------------------------------------+
+ |DestroyDrawInfo() |Deallocate structure, including any members. |
+ +----------------------+--------------------------------------------------------------------------+
+ |DrawImage() |Render primitives to image. |
+ +----------------------+--------------------------------------------------------------------------+
+
+The members of the DrawInfo structure are shown in the following table.
+The structure is initialized to reasonable defaults by first initializing
+the equivalent members of ImageInfo, and then initializing the entire
+structure using GetDrawInfo().
+
+
+.. table:: DrawInfo Structure Members Supporting DrawImage()
+
+ +----------------+--------------+--------------------------------------------------------------------+
+ | Member | Type | Description |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |affine |AffineInfo |Coordinate transformation (rotation, scaling, and translation). |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |border_color |PixelPacket |Border color |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |box |PixelPacket |Text solid background color. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |decorate |DecorationType|Text decoration type. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |density |char * |Text rendering density in DPI (effects scaling font according to |
+ | | |pointsize). E.g. "72x72" |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |fill |PixelPacket |Object internal fill (within outline) color. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |font |char * |Font to use when rendering text. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |gravity |GravityType |Text placement preference (e.g. NorthWestGravity). |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |linewidth |double |Stroke (outline) drawing width in pixels. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |pointsize |double |Font size (also see density). |
+ +----------------+--------------+--------------------------------------------------------------------+
+ | | |Space or new-line delimited list of text drawing primitives (e.g |
+ |primitive |char * |"text 100,100 Cockatoo"). See the table Drawing Primitives for the |
+ | | |available drawing primitives. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |stroke |PixelPacket |Object stroke (outline) color. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |stroke_antialias|unsigned int |Set to True (non-zero) to obtain anti-aliased stroke rendering. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |text_antialias |unsigned int |Set to True (non-zero) to obtain anti-aliased text rendering. |
+ +----------------+--------------+--------------------------------------------------------------------+
+ |tile |Image * |Image texture to draw with. Use an image containing a single color |
+ | | |(e.g. a 1x1 image) to draw in a solid color. |
+ +----------------+--------------+--------------------------------------------------------------------+
+
+Drawing Primitives
+
+The drawing primitives shown in the following table may be supplied as a
+space or new-line delimited list to the primitive member. Primitives
+which set drawing options effect the results from subsequent drawing
+operations. See the 'push graphic-context' and 'pop graphic-context'
+primitives for a way to control the propagation of drawing options.
+
+
+.. table:: Drawing Primitives
+
+ +----------------+----------------------------+-------------------------------------------------------+
+ | Primitive | Arguments | Purpose |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | | |Apply coordinate transformations to support scaling |
+ |affine |sx,rx,ry,sy,tx,ty |(s), rotation (r), and translation (t). Angles are |
+ | | |specified in radians. Equivalent to SVG matrix command |
+ | | |which supplies a transformation matrix. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |angle |angle |Specify object drawing angle. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |arc |startX,startY endX,endY |Draw an arc. |
+ | |startDegrees,endDegrees | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |Bezier |x1,y1, x2,y2, x3,y3, ..., |Draw a Bezier curve. |
+ | |xN,yN | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |circle |originX,originY |Draw a circle. |
+ | |perimX,perimY | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | |x,y (point|replace| |Set color in image according to specified colorization |
+ |color |floodfill|filltoborder| |rule. |
+ | |reset) | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |decorate |(none|underline|overline| |Specify text decoration. |
+ | |line-through) | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | |originX,originY | |
+ |ellipse |width,height |Draw an ellipse. |
+ | |arcStart,arcEnd | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |fill |colorspec |Specifiy object filling color. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |fill-opacity |opacity |Specify object fill opacity. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |font |fontname |Specify text drawing font. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | |(NorthWest,North,NorthEast, | |
+ |gravity |West,Center,East, |Specify text positioning gravity. |
+ | |SouthWest,South,SouthEast) | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | | |Composite image at position, scaled to specified width |
+ |image |x,y width,height filename |and height, and specified filename. If width or height |
+ | | |is zero, scaling is not performed. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |line |startX,startY endX,endY |Draw a line. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | |x,y (point|replace| |Set matte in image according to specified colorization |
+ |matte |floodfill|filltoborder| |rule. |
+ | |reset) | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |opacity |fillOpacity strokeOpacity |Specify drawing fill and stroke opacities. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |path |'SVG-compatible path |Draw using SVG-compatible path drawing commands. |
+ | |arguments' | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |point |x,y |Set point to fill color. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |pointsize |pointsize |Specify text drawing pointsize (scaled to density). |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |polygon |x1,y1, x2,y2, x3,y3, ..., |Draw a polygon. |
+ | |xN,yN | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |polyline |x1,y1, x2,y2, x3,y3, ..., |Draw a polyline. |
+ | |xN,yN | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | | |Remove options set since previous "push |
+ |pop |graphic-context |graphic-context" command. Options revert to those in |
+ | | |effect prior to pushing the graphic context. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |push |graphic-context |Specify new graphic context. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |rect |upperLeftX,upperLeftY |Draw a rectangle. |
+ | |lowerRightX,lowerRightY | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | | |Specify coordiante space rotation. Subsequent objects |
+ |rotate |angle |are drawn with coordate space rotated by specified |
+ | | |angle. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ | |centerX,centerY | |
+ |roundrectangle |width,hight |Draw a rectangle with rounded corners. |
+ | |cornerWidth,cornerHeight | |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |stroke |colorspec |Specify object stroke (outline) color. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |stroke-antialias|stroke_antialias (0 or 1) |Specify if stroke should be antialiased or not. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |stroke-dash |value |Specify pattern to be used when drawing stroke. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |stroke-opacity |opacity |Specify opacity of stroke drawing color. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |stroke-width |linewidth |Specify stroke (outline) width in pixels. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |text |x,y "some text" |Draw text at position. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |text-antialias |text_antialias (0 or 1) |Specify if rendered text is to be antialiased (blend |
+ | | |edges). |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |scale |x,y |Specify scaling to be applied to coordintate space for |
+ | | |subsequent drawing commands. |
+ +----------------+----------------------------+-------------------------------------------------------+
+ |translate |x,y |Specify center of coordinate space to use for |
+ | | |subsequent drawing commands. |
+ +----------------+----------------------------+-------------------------------------------------------+
+
+EndianType
+==========
+
+::
+
+ typedef enum
+ {
+ UndefinedEndian,
+ LSBEndian, /* "little" endian */
+ MSBEndian, /* "big" endian */
+ NativeEndian /* native endian */
+ } EndianType;
+
+ErrorHandler
+============
+
+::
+
+ typedef void
+ (*ErrorHandler)(const ExceptionType,const char *,const char *);
+
+
+ExceptionInfo
+=============
+
+::
+
+ typedef struct _ExceptionInfo
+ {
+ char
+ *reason,
+ *description;
+
+ ExceptionType
+ severity;
+
+ unsigned long
+ signature;
+ } ExceptionInfo;
+
+
+
+ExceptionType
+=============
+
+::
+
+ typedef enum
+ {
+ UndefinedException,
+ WarningException = 300,
+ ResourceLimitWarning = 300,
+ TypeWarning = 305,
+ OptionWarning = 310,
+ DelegateWarning = 315,
+ MissingDelegateWarning = 320,
+ CorruptImageWarning = 325,
+ FileOpenWarning = 330,
+ BlobWarning = 335,
+ StreamWarning = 340,
+ CacheWarning = 345,
+ CoderWarning = 350,
+ ModuleWarning = 355,
+ DrawWarning = 360,
+ ImageWarning = 365,
+ XServerWarning = 380,
+ MonitorWarning = 385,
+ RegistryWarning = 390,
+ ConfigureWarning = 395,
+ ErrorException = 400,
+ ResourceLimitError = 400,
+ TypeError = 405,
+ OptionError = 410,
+ DelegateError = 415,
+ MissingDelegateError = 420,
+ CorruptImageError = 425,
+ FileOpenError = 430,
+ BlobError = 435,
+ StreamError = 440,
+ CacheError = 445,
+ CoderError = 450,
+ ModuleError = 455,
+ DrawError = 460,
+ ImageError = 465,
+ XServerError = 480,
+ MonitorError = 485,
+ RegistryError = 490,
+ ConfigureError = 495,
+ FatalErrorException = 700,
+ ResourceLimitFatalError = 700,
+ TypeFatalError = 705,
+ OptionFatalError = 710,
+ DelegateFatalError = 715,
+ MissingDelegateFatalError = 720,
+ CorruptImageFatalError = 725,
+ FileOpenFatalError = 730,
+ BlobFatalError = 735,
+ StreamFatalError = 740,
+ CacheFatalError = 745,
+ CoderFatalError = 750,
+ ModuleFatalError = 755,
+ DrawFatalError = 760,
+ ImageFatalError = 765,
+ XServerFatalError = 780,
+ MonitorFatalError = 785,
+ RegistryFatalError = 790,
+ ConfigureFatalError = 795
+ } ExceptionType;
+
+
+FillRule
+========
+
+::
+
+ typedef enum
+ {
+ UndefinedRule,
+ EvenOddRule,
+ NonZeroRule
+ } FillRule;
+
+
+FilterTypes
+===========
+
+FilterTypes is used to adjust the filter algorithm used when resizing
+images. Different filters experience varying degrees of success with
+various images and can take significantly different amounts of processing
+time. GraphicsMagick uses the LanczosFilter by default since this filter
+has been shown to provide the best results for most images in a
+reasonable amount of time. Other filter types (e.g. TriangleFilter) may
+execute much faster but may show artifacts when the image is re-sized or
+around diagonal lines. The only way to be sure is to test the filter with
+sample images.
+
+.. table:: FilterTypes
+
+ +----------------------------------------------+--------------------------------------------------+
+ | Enumeration | Description |
+ +----------------------------------------------+--------------------------------------------------+
+ |UndefinedFilter |Unset value. |
+ +----------------------------------------------+--------------------------------------------------+
+ |PointFilter |Point Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |BoxFilter |Box Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |TriangleFilter |Triangle Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |HermiteFilter |Hermite Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |HanningFilter |Hanning Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |HammingFilter |Hamming Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |BlackmanFilter |Blackman Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |GaussianFilter |Gaussian Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |QuadraticFilter |Quadratic Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |CubicFilter |Cubic Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |CatromFilter |Catrom Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |MitchellFilter |Mitchell Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |LanczosFilter |Lanczos Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |BesselFilter |Bessel Filter |
+ +----------------------------------------------+--------------------------------------------------+
+ |SincFilter |Sinc Filter |
+ +----------------------------------------------+--------------------------------------------------+
+
+FrameInfo
+=========
+
+::
+
+ typedef struct _FrameInfo
+ {
+ unsigned long
+ width,
+ height;
+
+ long
+ x,
+ y,
+ inner_bevel,
+ outer_bevel;
+ } FrameInfo;
+
+
+GravityType
+===========
+
+GravityType specifies positioning of an object (e.g. text, image) within
+a bounding region (e.g. an image). Gravity provides a convenient way to
+locate objects irrespective of the size of the bounding region, in other
+words, you don't need to provide absolute coordinates in order to
+position an object. A common default for gravity is NorthWestGravity.
+
+
+.. table:: GravityType
+
+ +--------------------------+----------------------------------------------------------------------+
+ | Enumeration | Description |
+ +--------------------------+----------------------------------------------------------------------+
+ |ForgetGravity |Don't use gravity. |
+ +--------------------------+----------------------------------------------------------------------+
+ |NorthWestGravity |Position object at top-left of region. |
+ +--------------------------+----------------------------------------------------------------------+
+ |NorthGravity |Postiion object at top-center of region |
+ +--------------------------+----------------------------------------------------------------------+
+ |NorthEastGravity |Position object at top-right of region |
+ +--------------------------+----------------------------------------------------------------------+
+ |WestGravity |Position object at left-center of region |
+ +--------------------------+----------------------------------------------------------------------+
+ |CenterGravity |Position object at center of region |
+ +--------------------------+----------------------------------------------------------------------+
+ |EastGravity |Position object at right-center of region |
+ +--------------------------+----------------------------------------------------------------------+
+ |SouthWestGravity |Position object at left-bottom of region |
+ +--------------------------+----------------------------------------------------------------------+
+ |SouthGravity |Position object at bottom-center of region |
+ +--------------------------+----------------------------------------------------------------------+
+ |SouthEastGravity |Position object at bottom-right of region |
+ +--------------------------+----------------------------------------------------------------------+
+
+Image
+=====
+
+The Image structure represents an GraphicsMagick image. It is initially
+allocated by AllocateImage() and deallocated by DestroyImage(). The
+functions ReadImage(), ReadImages(), BlobToImage() and CreateImage()
+return a new image. Use CloneImage() to copy an image. An image consists
+of a structure containing image attributes as well as the image pixels.
+
+The image pixels are represented by the structure PixelPacket and are
+cached in-memory, or on disk, depending on the cache threshold setting.
+This cache is known as the "pixel cache". Pixels in the cache may not be
+edited directly. They must first be made visible from the cache via a
+pixel view. A pixel view is a rectangular view of the pixels as defined
+by a starting coordinate, and a number of rows and columns. When
+considering the varying abilities of multiple platforms, the most
+reliably efficient pixel view is comprized of part, or all, of one image
+row.
+
+There are two means of accessing pixel views. When using the default
+view, the pixels are made visible and accessable by using the
+GetImagePixels() method which provides access to a specified region of
+the image. After the view has been updated, the pixels may be saved back
+to the cache in their original positions via SyncImagePixels(). In order
+to create an image with new contents, or to blindly overwrite existing
+contents, the method SetImagePixels() is used to reserve a pixel view
+corresponding to a region in the pixel cache. Once the pixel view has
+been updated, it may be written to the cache via SyncImagePixels(). The
+function GetIndexes() provides access to the image colormap, represented
+as an array of type IndexPacket.
+
+A more flexible interface to the image pixels is via the Cache View
+interface. This interface supports multiple pixel cache views (limited by
+the amount of available memory), each of which are identified by a handle
+(of type ViewInfo). Use OpenCacheView() to obtain a new cache view,
+CloseCacheView() to discard a cache view, GetCacheViewPixels() to access
+an existing pixel region, SetCacheView() to define a new pixel region,
+and SyncCacheViewPixels() to save the updated pixel region. The function
+GetCacheViewIndexes() provides access to the colormap indexes associated
+with the pixel view.
+
+When writing encoders and decoders for new image formats, it is
+convenient to have a high-level interface available which supports
+converting between external pixel representations and GraphicsMagick's
+own representation. Pixel components (red, green, blue, opacity, RGB, or
+RGBA) may be transferred from a user-supplied buffer into the default
+view by using ImportImagePixelArea(), or from an allocated view via
+ImportViewPixelArea(). Pixel components may be transferred from the
+default view into a user-supplied buffer by using ExportImagePixelArea(),
+or from an allocated view via ExportViewPixelArea(). Use of this
+high-level interface helps protect image coders from changes to
+GraphicsMagick's pixel representation and simplifies the implementation.
+
+The members of the Image structure are shown in the following table:
+
+
+.. table:: Image Structure Members
+
+ +--------------------------------+------------------+----------------------------------------------------+
+ | Member | Type | Description |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | background_color | PixelPacket | Image background color |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | blur | double | Blur factor to apply to the image when zooming |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | border_color | PixelPacket | Image border color |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | chromaticity | ChromaticityInfo | Red, green, blue, and white-point chromaticity |
+ | | | values. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | colormap | PixelPacket * | PseudoColor palette array. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | colors | unsigned int | The desired number of colors. Used by |
+ | | | QuantizeImage(). |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | Image pixel interpretation.If the colorspace is |
+ | | | RGB the pixels are red, green, blue. If matte is |
+ | colorspace | ColorspaceType | true, then red, green, blue, and index. If it is |
+ | | | CMYK, the pixels are cyan, yellow, magenta, black. |
+ | | | Otherwise the colorspace is ignored. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | columns | unsigned int | Image width |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | compression | CompressionType | Image compresion type. The default is the |
+ | | | compression type of the specified image file. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | Time in 1/100ths of a second (0 to 65535) which |
+ | | | must expire before displaying the next image in an |
+ | delay | unsigned int | animated sequence. This option is useful for |
+ | | | regulating the animation of a sequence of GIF |
+ | | | images within Netscape. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | depth | unsigned int | Image depth. Number of encoding bits per sample. |
+ | | | Usually 8 or 16, but sometimes 10 or 12. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | Tile names from within an image montage. Only |
+ | directory | char * | valid after calling MontageImages() or reading a |
+ | | | MIFF file which contains a directory. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | GIF disposal method. This option is used to |
+ | dispose | unsigned int | control how successive frames are rendered (how |
+ | | | the preceding frame is disposed of) when creating |
+ | | | a GIF animation. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | exception | ExceptionInfo | Record of any error which occurred when updating |
+ | | | image. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | filename | char | Image file name to read or write. |
+ | | [MaxTextExtent] | |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | Filter to use when resizing image. The reduction |
+ | | | filter employed has a significant effect on the |
+ | filter | FilterTypes | time required to resize an image and the resulting |
+ | | | quality. The default filter is Lanczos which has |
+ | | | been shown to produce high quality results when |
+ | | | reducing most images. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | Colors within this distance are considered equal. |
+ | | | A number of algorithms search for a target color. |
+ | fuzz | int | By default the color must be exact. Use this |
+ | | | option to match colors that are close to the |
+ | | | target color in RGB space. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | Gamma level of the image. The same color image |
+ | | | displayed on two different workstations may look |
+ | gamma | double | different due to differences in the display |
+ | | | monitor. Use gamma correction to adjust for this |
+ | | | color difference. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | geometry | char * | Preferred size of the image when encoding. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | The type of interlacing scheme (default |
+ | | | NoInterlace). This option is used to specify the |
+ | | | type of interlacing scheme for raw image formats |
+ | | | such as RGB or YUV. NoInterlace means do not |
+ | | | interlace, LineInterlace uses scanline |
+ | interlace | InterlaceType | interlacing, and PlaneInterlace uses plane |
+ | | | interlacing. PartitionInterlace is like |
+ | | | PlaneInterlace except the different planes are |
+ | | | saved to individual files (e.g. image.R, image.G, |
+ | | | and image.B). Use LineInterlace or PlaneInterlace |
+ | | | to create an interlaced GIF or progressive JPEG |
+ | | | image. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | iterations | unsigned int | Number of iterations to loop an animation (e.g. |
+ | | | Netscape loop extension) for. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | magick | char | Image encoding format (e.g. "GIF"). |
+ | | [MaxTextExtent] | |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | magick_columns | unsigned int | Base image width (before transformations) |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | magick_filename | char | Base image filename (before transformations) |
+ | | [MaxTextExtent] | |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | magick_rows | unsigned int | Base image height (before transformations) |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | matte | unsigned int | If non-zero, then the index member of pixels |
+ | | | represents the alpha channel. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | matte_color | PixelPacket | Image matte (transparent) color |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | montage | char * | Tile size and offset within an image montage. Only |
+ | | | valid for montage images. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | next | struct _Image * | Next image frame in sequence |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | offset | int | Number of initial bytes to skip over when reading |
+ | | | raw image. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | orientation | OrientationType | Orientation of the image. Specifies scanline |
+ | | | orientation and starting coordinate of image. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | page | RectangleInfo | Equivalent size of Postscript page. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | previous | struct _Image * | Previous image frame in sequence. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | rendering_intent | RenderingIntent | The type of rendering intent. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | rows | unsigned int | Image height |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | scene | unsigned int | Image frame scene number. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | Image storage class. If DirectClass then the image |
+ | storage_class | ClassType | packets contain valid RGB or CMYK colors. If |
+ | | | PseudoClass then the image has a colormap |
+ | | | referenced by pixel's index member. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | Describes a tile within an image. For example, if |
+ | tile_info | RectangleInfo | your images is 640x480 you may only want 320x256 |
+ | | | with an offset of +128+64. It is used for raw |
+ | | | formats such as RGB and CMYK as well as for TIFF. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | timer | TimerInfo | Support for measuring actual (user + system) and |
+ | | | elapsed execution time. |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | | | The number of colors in the image after |
+ | total_colors | unsigned long | QuantizeImage(), or QuantizeImages() if the |
+ | | | verbose flag was set before the call. Calculated |
+ | | | by GetNumberColors(). |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | units | ResolutionType | Units of image resolution |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | x_resolution | double | Horizontal resolution of the image |
+ +--------------------------------+------------------+----------------------------------------------------+
+ | y_resolution | double | Vertical resolution of the image |
+ +--------------------------------+------------------+----------------------------------------------------+
+
+ImageInfo
+=========
+
+The ImageInfo structure is used to supply option information to the
+functions AllocateImage(), AnimateImages(), BlobToImage(),
+CloneAnnotateInfo(), DisplayImages(), GetAnnotateInfo(), ImageToBlob(),
+PingImage(), ReadImage(), ReadImages(), and, WriteImage(). These
+functions update information in ImageInfo to reflect attributes of the
+current image.
+
+Use CloneImageInfo() to duplicate an existing ImageInfo structure or
+allocate a new one. Use DestroyImageInfo() to deallocate memory
+associated with an ImageInfo structure. Use GetImageInfo() to initialize
+an existing ImageInfo structure. Use SetImageInfo() to set image type
+information in the ImageInfo structure based on an existing image.
+
+The members of the ImageInfo structure are shown in the following table:
+
+
+.. table:: ImageInfo Structure Members
+
+ +----------------+---------------+-------------------------------------------------------------------+
+ | Member | Type | Description |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |adjoin |unsigned int |Join images into a single multi-image file. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |antialias |unsigned int |Control antialiasing of rendered Postscript and Postscript or |
+ | | |TrueType fonts. Enabled by default. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |background_color|PixelPacket |Image background color. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |border_color |PixelPacket |Image border color. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Image pixel interpretation.If the colorspace is RGB the pixels are |
+ |colorspace |ColorspaceType |red, green, blue. If matte is true, then red, green, blue, and |
+ | | |index. If it is CMYK, the pixels are cyan, yellow, magenta, black. |
+ | | |Otherwise the colorspace is ignored. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |compression |CompressionType|Image compresion type. The default is the compression type of the |
+ | | |specified image file. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Time in 1/100ths of a second (0 to 65535) which must expire before |
+ |delay |char * |displaying the next image in an animated sequence. This option is |
+ | | |useful for regulating the animation of a sequence of GIF images |
+ | | |within Netscape. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Vertical and horizontal resolution in pixels of the image. This |
+ |density |char * |option specifies an image density when decoding a Postscript or |
+ | | |Portable Document page. Often used with page. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |depth |unsigned int |Image depth (8 or 16). QuantumLeap must be defined before a depth |
+ | | |of 16 is valid. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |GIF disposal method. This option is used to control how successive |
+ |dispose |char * |frames are rendered (how the preceding frame is disposed of) when |
+ | | |creating a GIF animation. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Apply Floyd/Steinberg error diffusion to the image. The basic |
+ | | |strategy of dithering is to trade intensity resolution for spatial |
+ |dither |unsigned int |resolution by averaging the intensities of several neighboring |
+ | | |pixels. Images which suffer from severe contouring when reducing |
+ | | |colors can be improved with this option. The colors or monochrome |
+ | | |option must be set for this option to take effect. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Stdio stream to read image from or write image to. If set, |
+ |file |FILE * |ImageMagick will read from or write to the stream rather than |
+ | | |opening a file. Used by ReadImage() and WriteImage(). The stream is|
+ | | |closed when the operation completes. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |filename |char |Image file name to read or write. |
+ | |[MaxTextExtent]| |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |fill |PixelPacket |Drawing object fill color. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Text rendering font. If the font is a fully qualified X server font|
+ |font |char * |name, the font is obtained from an X server. To use a TrueType |
+ | | |font, precede the TrueType filename with an @. Otherwise, specify a|
+ | | |Postscript font name (e.g. "helvetica"). |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Colors within this distance are considered equal. A number of |
+ |fuzz |int |algorithms search for a target color. By default the color must be |
+ | | |exact. Use this option to match colors that are close to the target|
+ | | |color in RGB space. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |The type of interlacing scheme (default NoInterlace). This option |
+ | | |is used to specify the type of interlacing scheme for raw image |
+ | | |formats such as RGB or YUV. NoInterlace means do not interlace, |
+ |interlace |InterlaceType |LineInterlace uses scanline interlacing, and PlaneInterlace uses |
+ | | |plane interlacing. PartitionInterlace is like PlaneInterlace except|
+ | | |the different planes are saved to individual files (e.g. image.R, |
+ | | |image.G, and image.B). Use LineInterlace or PlaneInterlace to |
+ | | |create an interlaced GIF or progressive JPEG image. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |iterations |char * |Number of iterations to loop an animation (e.g. Netscape loop |
+ | | |extension) for. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |linewidth |unsigned int |Line width for drawing lines, circles, ellipses, etc. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |magick |char |Image encoding format (e.g. "GIF"). |
+ | |[MaxTextExtent]| |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |matte_color |PixelPacket |Image matte (transparent) color. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |monochrome |unsigned int |Transform the image to black and white. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |page |char * |Equivalent size of Postscript page. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Set to True to read enough of the image to determine the image |
+ |ping |unsigned int |columns, rows, and filesize. The columns, rows, and size attributes|
+ | | |are valid after invoking ReadImage() while ping is set. The image |
+ | | |data is not valid after calling ReadImage() if ping is set. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |pointsize |double |Text rendering font point size. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |preview_type |PreviewType |Image manipulation preview option. Used by 'display'. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |quality |unsigned int |JPEG/MIFF/PNG compression level (default 75). |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |server_name |char * |X11 display to display to obtain fonts from, or to capture image |
+ | | |from. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ | | |Width and height of a raw image (an image which does not support |
+ |size |char * |width and height information). Size may also be used to affect the |
+ | | |image size read from a multi-resolution format (e.g. Photo CD, |
+ | | |JBIG, or JPEG. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |stroke |PixelPacket |Drawing object outline color. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |subimage |unsigned int |Subimage of an image sequence. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |subrange |unsigned int |Number of images relative to the base image. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |texture |char * |Image filename to use as background texture. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |tile |char * |Tile name. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |units |ResolutionType |Units of image resolution. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |verbose |unsigned int |Print detailed information about the image if True. |
+ +----------------+---------------+-------------------------------------------------------------------+
+ |view |char * |FlashPix viewing parameters. |
+ +----------------+---------------+-------------------------------------------------------------------+
+
+ImageType
+=========
+
+ImageType indicates the type classification of the image.
+
+.. table:: ImageType
+
+ +------------------------------+------------------------------------------------------------------+
+ | Enumeration | Description |
+ +------------------------------+------------------------------------------------------------------+
+ |UndefinedType |Unset value. |
+ +------------------------------+------------------------------------------------------------------+
+ |BilevelType |Monochrome image |
+ +------------------------------+------------------------------------------------------------------+
+ |GrayscaleType |Grayscale image |
+ +------------------------------+------------------------------------------------------------------+
+ |PaletteType |Indexed color (palette) image |
+ +------------------------------+------------------------------------------------------------------+
+ |PaletteMatteType |Indexed color (palette) image with opacity |
+ +------------------------------+------------------------------------------------------------------+
+ |TrueColorType |Truecolor image |
+ +------------------------------+------------------------------------------------------------------+
+ |TrueColorMatteType |Truecolor image with opacity |
+ +------------------------------+------------------------------------------------------------------+
+ |ColorSeparationType |Cyan/Yellow/Magenta/Black (CYMK) image |
+ +------------------------------+------------------------------------------------------------------+
+
+IndexPacket
+===========
+
+IndexPacket is the type used for a colormap index. An array of type
+IndexPacket is used to represent an image in PseudoClass type. Currently
+supported IndexPacket underlying types are 'unsigned char' and 'unsigned
+short'. The type is selected at build time according to the QuantumDepth
+setting.
+
+InterlaceType
+=============
+
+InterlaceType specifies the ordering of the red, green, and blue pixel
+information in the image. Interlacing is usually used to make image
+information available to the user faster by taking advantage of the space
+vs time tradeoff. For example, interlacing allows images on the Web to be
+recognizable sooner and satellite images to accumulate/render with image
+resolution increasing over time.
+
+Use LineInterlace or PlaneInterlace to create an interlaced GIF or
+progressive JPEG image.
+
+.. table:: InterlaceType
+
+ +------------------+------------------------------------------------------------------------------+
+ | Enumeration | Description |
+ +------------------+------------------------------------------------------------------------------+
+ |UndefinedInterlace|Unset value. |
+ +------------------+------------------------------------------------------------------------------+
+ |NoInterlace |Don't interlace image (RGBRGBRGBRGBRGBRGB...) |
+ +------------------+------------------------------------------------------------------------------+
+ |LineInterlace |Use scanline interlacing (RRR...GGG...BBB...RRR...GGG...BBB...) |
+ +------------------+------------------------------------------------------------------------------+
+ |PlaneInterlace |Use plane interlacing (RRRRRR...GGGGGG...BBBBBB...) |
+ +------------------+------------------------------------------------------------------------------+
+ |PartitionInterlace|Similar to plane interlaing except that the different planes are saved to |
+ | |individual files (e.g. image.R, image.G, and image.B) |
+ +------------------+------------------------------------------------------------------------------+
+
+LayerType
+=========
+
+LayerType is used as an argument when doing color separations. Use
+LayerType when extracting a layer from an image. MatteLayer is useful for
+extracting the opacity values from an image.
+
+.. table:: LayerType
+
+ +---------------------------+---------------------------------------------------------------------+
+ | Enumeration | Description |
+ +---------------------------+---------------------------------------------------------------------+
+ |UndefinedLayer |Unset value. |
+ +---------------------------+---------------------------------------------------------------------+
+ |RedLayer |Select red layer |
+ +---------------------------+---------------------------------------------------------------------+
+ |GreenLayer |Select green layer |
+ +---------------------------+---------------------------------------------------------------------+
+ |BlueLayer |Select blue layer |
+ +---------------------------+---------------------------------------------------------------------+
+ |MatteLayer |Select matte (opacity values) layer |
+ +---------------------------+---------------------------------------------------------------------+
+
+MagickInfo
+==========
+
+The MagickInfo structure is used by GraphicsMagick to register support
+for an image format. The MagickInfo structure is allocated with default
+parameters by calling SetMagickInfo(). Image formats are registered by
+calling RegisterMagickInfo() which adds the initial structure to a linked
+list (at which point it is owned by the list). A pointer to the structure
+describing a format may be obtained by calling GetMagickInfo(). Pass the
+argument NULL to obtain the first member of this list. A human-readable
+list of registered image formats may be printed to a file descriptor by
+calling ListMagickInfo().
+
+Support for formats may be provided as a module which is part of the
+GraphicsMagick library, provided by a module which is loaded dynamically
+at run-time, or directly by the linked program. Users of GraphicsMagick
+will normally want to create a loadable-module, or support encode/decode
+of an image format directly from within their program.
+
+Sample Module:
+
+The following shows sample code for a module called "GIF" (gif.c). Note
+that the names of the Register and Unregister call-back routines are
+calculated at run-time, and therefore must follow the rigid naming scheme
+RegisterFORMATImage and UnregisterFORMATImage, respectively, where FORMAT
+is the upper-cased name of the module file::
+
+ /* Read image */
+ Image *ReadGIFImage(const ImageInfo *image_info)
+ {
+ [ decode the image ... ]
+ }
+
+ /* Write image */
+ unsigned int WriteGIFImage(const ImageInfo *image_info,Image *image)
+ {
+ [ encode the image ... ]
+ }
+
+ /* Module call-back to register support for formats */
+ void RegisterGIFImage(void)
+ {
+ MagickInfo *entry;
+ entry=SetMagickInfo("GIF");
+ entry->decoder=ReadGIFImage;
+ entry->encoder=WriteGIFImage;
+ entry->description="CompuServe graphics interchange format";
+ entry->module="GIF";
+ RegisterMagickInfo(entry);
+
+ entry=SetMagickInfo("GIF87");
+ entry->decoder=ReadGIFImage;
+ entry->encoder=WriteGIFImage;
+ entry->adjoin=False;
+ entry->description="CompuServe graphics interchange format (version 87a)";
+ entry->module="GIF";
+ RegisterMagickInfo(entry);
+ }
+
+ /* Module call-back to unregister support for formats */
+ Export void UnregisterGIFImage(void)
+ {
+ UnregisterMagickInfo("GIF");
+ UnregisterMagickInfo("GIF87");
+ }
+
+Sample Application Code
+
+Image format support provided within the user's application does not need
+to implement the RegisterFORMATImage and UnregisterFORMATImage call-back
+routines. Instead, the application takes responsibility for the
+registration itself. An example follows::
+
+ /* Read image */
+ Image *ReadGIFImage(const ImageInfo *image_info)
+ {
+ [ decode the image ... ]
+ }
+ /* Write image */
+ unsigned int WriteGIFImage(const ImageInfo *image_info,Image *image)
+ {
+ [ encode the image ... ]
+ }
+ #include <stdio.h>
+ int main( void )
+ {
+ struct MagickInfo* info;
+ info = SetMagickInfo("GIF");
+ if ( info == (MagickInfo*)NULL )
+ exit(1);
+ info->decoder = ReadGIFImage;
+ info->encoder = WriteGIFImage;
+ info->adjoin = False;
+ info->description = "CompuServe graphics interchange format";
+ /* Add MagickInfo structure to list */
+ RegisterMagickInfo(info);
+ info = GetMagickInfo("GIF");
+ [ do something with info ... ]
+ ListMagickInfo( stdout );
+ return;
+ }
+
+MagickInfo Structure Definition
+
+The members of the MagickInfo structure are shown in the following table:
+
+.. table:: MagickInfo Structure Members
+
+ +------------+--------------------+------------------------------------------------------------------+
+ | Member | Type | Description |
+ +------------+--------------------+------------------------------------------------------------------+
+ |adjoin |unsigned int |Set to non-zero (True) if this file format supports multi-frame |
+ | | |images. |
+ +------------+--------------------+------------------------------------------------------------------+
+ | | |Set to non-zero (True) if the encoder and decoder for this format |
+ |blob_support|unsigned int |supports operating on arbitrary BLOBs (rather than only disk |
+ | | |files). |
+ +------------+--------------------+------------------------------------------------------------------+
+ | | |User specified data. A way to pass any sort of data structure to |
+ |data |void * |the endoder/decoder. To set this, GetMagickInfo() must be called |
+ | | |to first obtain a pointer to the registered structure since it can|
+ | | |not be set via a RegisterMagickInfo() parameter. |
+ +------------+--------------------+------------------------------------------------------------------+
+ | |Image \*(\*decoder) | |
+ |decoder |(const ImageInfo |Function to decode image data and return GraphicsMagick Image. |
+ | |\*) | |
+ +------------+--------------------+------------------------------------------------------------------+
+ |description |char * |Long form image format description (e.g. "CompuServe graphics |
+ | | |interchange format"). |
+ +------------+--------------------+------------------------------------------------------------------+
+ | |unsigned int | |
+ |encoder |(\*encoder)(const |Function to encode image data with options passed via ImageInfo |
+ | |ImageInfo \*, Image |and image represented by Image. |
+ | |\*) | |
+ +------------+--------------------+------------------------------------------------------------------+
+ |module |char * |Name of module (e.g. "GIF") which registered this format. Set to |
+ | | |NULL if format is not registered by a module. |
+ +------------+--------------------+------------------------------------------------------------------+
+ |name |const char * |Magick string (e.g. "GIF") which identifies this format. |
+ +------------+--------------------+------------------------------------------------------------------+
+ |next |MagickInfo |Next MagickInfo struct in linked-list. NULL if none. |
+ +------------+--------------------+------------------------------------------------------------------+
+ |previous |MagickInfo |Previous MagickInfo struct in linked-list. NULL if none. |
+ +------------+--------------------+------------------------------------------------------------------+
+ |raw |unsigned int |Image format does not contain size (must be specified in |
+ | | |ImageInfo). |
+ +------------+--------------------+------------------------------------------------------------------+
+
+MonitorHandler
+==============
+
+MonitorHandler is the function type to be used for the progress monitor
+callback. Its definition is as follows::
+
+ typedef unsigned int
+ (*MonitorHandler)(const char *text, const magick_int64_t quantum,
+ const magick_uint64_t span, ExceptionInfo *exception);
+
+The operation of the monitor handler is described in the following table:
+
+.. table:: MonitorHandler Parameters
+
+ +------------------------+------------------------+-----------------------------------------------+
+ | Parameter | Type | Description |
+ +------------------------+------------------------+-----------------------------------------------+
+ | return status | unsigned int | The progress monitor should normally return |
+ | | | True (a non-zero value) if the operation is |
+ | | | to continue. If the progress monitor returns |
+ | | | false, then the operation is will be aborted. |
+ | | | This mechanism allows a user to terminate a |
+ | | | process which is taking too long to complete. |
+ +------------------------+------------------------+-----------------------------------------------+
+ | text | const char * | A description of the current operation being |
+ | | | performed. |
+ +------------------------+------------------------+-----------------------------------------------+
+ | quantum | const magick_int64_t | A value within the range of 0 to span which |
+ | | | indicates the degree of progress. |
+ +------------------------+------------------------+-----------------------------------------------+
+ | span | const magick_uint64_t | The total range that quantum will span. |
+ +------------------------+------------------------+-----------------------------------------------+
+ | exception | exceptionInfo * | If the progress monitor returns False (abort |
+ | | | operation), it should also update the |
+ | | | structure passed via the exception parameter |
+ | | | so that an error message may be reported to |
+ | | | the user. |
+ +------------------------+------------------------+-----------------------------------------------+
+
+MontageInfo
+===========
+
+::
+
+ typedef struct _MontageInfo
+ {
+ char
+ *geometry,
+ *tile,
+ *title,
+ *frame,
+ *texture,
+ *font;
+
+ double
+ pointsize;
+
+ unsigned long
+ border_width;
+
+ unsigned int
+ shadow;
+
+ PixelPacket
+ fill,
+ stroke,
+ background_color,
+ border_color,
+ matte_color;
+
+ GravityType
+ gravity;
+
+ char
+ filename[MaxTextExtent];
+
+ unsigned long
+ signature;
+ } MontageInfo;
+
+
+NoiseType
+=========
+
+NoiseType is used as an argument to select the type of noise to be added
+to the image.
+
+.. table:: NoiseType
+
+ +----------------------------------------------+--------------------------------------------------+
+ | Enumeration | Description |
+ +----------------------------------------------+--------------------------------------------------+
+ |UniformNoise |Uniform noise |
+ +----------------------------------------------+--------------------------------------------------+
+ |GaussianNoise |Gaussian noise |
+ +----------------------------------------------+--------------------------------------------------+
+ |MultiplicativeGaussianNoise |Multiplicative Gaussian noise |
+ +----------------------------------------------+--------------------------------------------------+
+ |ImpulseNoise |Impulse noise |
+ +----------------------------------------------+--------------------------------------------------+
+ |LaplacianNoise |Laplacian noise |
+ +----------------------------------------------+--------------------------------------------------+
+ |PoissonNoise |Poisson noise |
+ +----------------------------------------------+--------------------------------------------------+
+
+OrientationType
+===============
+
+OrientationType specifies the orientation of the image. Useful for when
+the image is produced via a different ordinate system, the camera was
+turned on its side, or the page was scanned sideways.
+
+.. table:: OrientationType
+
+ +------------------------+----------------------------+-------------------------------------------+
+ | Enumeration | Scanline Direction | Frame Direction |
+ +------------------------+----------------------------+-------------------------------------------+
+ |UndefinedOrientation |Unknown |Unknown |
+ +------------------------+----------------------------+-------------------------------------------+
+ |TopLeftOrientation |Left to right |Top to bottom |
+ +------------------------+----------------------------+-------------------------------------------+
+ |TopRightOrientation |Right to left |Top to bottom |
+ +------------------------+----------------------------+-------------------------------------------+
+ |BottomRightOrientation |Right to left |Bottom to top |
+ +------------------------+----------------------------+-------------------------------------------+
+ |BottomLeftOrientation |Left to right |Bottom to top |
+ +------------------------+----------------------------+-------------------------------------------+
+ |LeftTopOrientation |Top to bottom |Left to right |
+ +------------------------+----------------------------+-------------------------------------------+
+ |RightTopOrientation |Top to bottom |Right to left |
+ +------------------------+----------------------------+-------------------------------------------+
+ |RightBottomOrientation |Bottom to top |Right to left |
+ +------------------------+----------------------------+-------------------------------------------+
+ |LeftBottomOrientation |Bottom to top |Left to right |
+ +------------------------+----------------------------+-------------------------------------------+
+
+PaintMethod
+===========
+
+PaintMethod specifies how pixel colors are to be replaced in the image.
+It is used to select the pixel-filling algorithm employed.
+
+.. table:: PaintMethod
+
+ +------------------+------------------------------------------------------------------------------+
+ | Enumeration | Description |
+ +------------------+------------------------------------------------------------------------------+
+ |PointMethod |Replace pixel color at point. |
+ +------------------+------------------------------------------------------------------------------+
+ |ReplaceMethod |Replace color for all image pixels matching color at point. |
+ +------------------+------------------------------------------------------------------------------+
+ |FloodfillMethod |Replace color for pixels surrounding point until encountering pixel that fails|
+ | |to match color at point. |
+ +------------------+------------------------------------------------------------------------------+
+ |FillToBorderMethod|Replace color for pixels surrounding point until encountering pixels matching |
+ | |border color. |
+ +------------------+------------------------------------------------------------------------------+
+ |ResetMethod |Replace colors for all pixels in image with pen color. |
+ +------------------+------------------------------------------------------------------------------+
+
+PixelPacket
+===========
+
+The PixelPacket structure is used to represent DirectClass color pixels
+in GraphicsMagick. If the image is indicated as a PseudoClass image, its
+DirectClass representation is only valid immediately after calling
+SyncImage(). If an image is set as PseudoClass and the DirectClass
+representation is modified, the image should then be set as DirectClass.
+Use QuantizeImage() to restore the PseudoClass colormap if the
+DirectClass representation is modified.
+
+The members of the PixelPacket structure are shown in the following table:
+
+
+.. table:: PixelPacket Structure Members
+
+ +----------+---------+----------------------------------------------------------------------------+
+ | | | Interpretation |
+ | Member | Type +----------------------+-------------------------------+---------------------+
+ | | | RGBColorspace (3) | RGBColorspace + matte(3) | CMYKColorspace |
+ +----------+---------+----------------------+-------------------------------+---------------------+
+ |red |Quantum |Red |Red |Cyan |
+ +----------+---------+----------------------+-------------------------------+---------------------+
+ |green |Quantum |Green |Green |Magenta |
+ +----------+---------+----------------------+-------------------------------+---------------------+
+ |blue |Quantum |Blue |Blue |Yellow |
+ +----------+---------+----------------------+-------------------------------+---------------------+
+ |opacity |Quantum |Ignored |Opacity |Black |
+ +----------+---------+----------------------+-------------------------------+---------------------+
+
+Notes:
+
+ 1. Quantum is an unsigned short (MaxRGB=65535) if GraphicsMagick is
+ built using -DQuantumDepth=16 Otherwise it is an unsigned char
+ (MaxRGB=255).
+
+ 2. SyncImage() may be used to synchronize the DirectClass color pixels
+ to the current PseudoClass colormap.
+
+ 3. For pixel representation purposes, all colorspaces are treated like
+ RGBColorspace except for CMYKColorspace.
+
+
+PointInfo
+=========
+
+The PointInfo structure is used by the ChromaticityInfo structure to
+specify chromaticity point values. This defines the boundaries and gammut
+(range of included color) of the colorspace.
+
+The members of the PointInfo structure are shown in the following table:
+
+
+.. table:: PointInfo Structure Members
+
+ +-----------------------------+------------------------+------------------------------------------+
+ | Member | Type | Description |
+ +-----------------------------+------------------------+------------------------------------------+
+ |x |double |X ordinate |
+ +-----------------------------+------------------------+------------------------------------------+
+ |y |double |Y ordinate |
+ +-----------------------------+------------------------+------------------------------------------+
+ |z |double |Z ordinate |
+ +-----------------------------+------------------------+------------------------------------------+
+
+ProfileInfo
+===========
+
+The ProfileInfo structure is used to represent ICC or IPCT profiles in
+GraphicsMagick (stored as an opaque BLOB).
+
+The members of the ProfileInfo structure are shown in the following table:
+
+.. table:: ProfileInfo Structure Members
+
+ +-----------------------+--------------------------------------+----------------------------------+
+ | Member | Type | Description |
+ +-----------------------+--------------------------------------+----------------------------------+
+ |length |unsigned int |Profile length |
+ +-----------------------+--------------------------------------+----------------------------------+
+ |info |unsigned char * |Profile data |
+ +-----------------------+--------------------------------------+----------------------------------+
+
+QuantizeInfo
+============
+
+The QuantizeInfo structure is used to support passing parameters to
+GraphicsMagick's color quantization (reduction) functions. Color
+quantization is the process of analyzing one or more images, and
+calculating a color palette which best approximates the image within a
+specified colorspace, and then adjusting the image pixels to use the
+calculated color palette. The maximum number of colors allowed in the
+color palette may be specified.
+
+
+.. table:: Methods Supporting QuantizeInfo
+
+ +-------------------+------------------------------------------------------------------------------+
+ | Method | Description |
+ +-------------------+------------------------------------------------------------------------------+
+ |GetQuantizeInfo() |Allocate new structure with defaults set. |
+ +-------------------+------------------------------------------------------------------------------+
+ |CloneQuantizeInfo()|Copy existing structure, allocating new structure in the process. |
+ +-------------------+------------------------------------------------------------------------------+
+ |DestroyQuantizeInfo|Deallocate structure, including any members. |
+ |() | |
+ +-------------------+------------------------------------------------------------------------------+
+ |QuantizeImage |Analyzes the colors within a reference image and chooses a fixed number of |
+ | |colors to represent the image. |
+ +-------------------+------------------------------------------------------------------------------+
+ |QuantizeImages |Analyzes the colors within a set of reference images and chooses a fixed |
+ | |number of colors to represent the set. |
+ +-------------------+------------------------------------------------------------------------------+
+
+.. table:: QuantizeInfo Structure Members
+
+ +-------------+--------------+----------------------------------------------------------------------+
+ | Member | Type | Description |
+ +-------------+--------------+----------------------------------------------------------------------+
+ | | |The colorspace to quantize in. Color reduction, by default, takes |
+ | | |place in the RGB color space. Empirical evidence suggests that |
+ |colorspace |ColorspaceType|distances in color spaces such as YUV or YIQ correspond to |
+ | | |perceptual color differences more closely than do distances in RGB |
+ | | |space. The Transparent color space behaves uniquely in that it |
+ | | |preserves the matte channel of the image if it exists. |
+ +-------------+--------------+----------------------------------------------------------------------+
+ | | |Set to True (non-zero) to apply Floyd/Steinberg error diffusion to the|
+ |dither |unsigned int |image. When the size of the color palette is less than the image |
+ | | |colors, this trades off spacial resolution for color resolution by |
+ | | |dithering to achieve a similar looking image. |
+ +-------------+--------------+----------------------------------------------------------------------+
+ |measure_error|unsigned int |Set to True (non-zero) to calculate quantization errors when |
+ | | |quantizing the image. |
+ +-------------+--------------+----------------------------------------------------------------------+
+ | | |Specify the maximum number of colors in the output image. Must be |
+ |number_colors|unsigned int |equal to, or less than MaxRGB, which is determined by the value of |
+ | | |QuantumLeap when GraphicsMagick was compiled. |
+ +-------------+--------------+----------------------------------------------------------------------+
+ |signature |unsigned long |??? |
+ +-------------+--------------+----------------------------------------------------------------------+
+ | | |Specify the tree depth to use while quantizing. The values zero and |
+ | | |one support automatic tree depth determination. The tree depth may be |
+ |tree_depth |unsigned int |forced via values ranging from two to eight. The ideal tree depth |
+ | | |depends on the characteristics of the input image, and may be |
+ | | |determined through experimentation. |
+ +-------------+--------------+----------------------------------------------------------------------+
+
+Quantum
+========
+
+Quantum is the base type ('unsigned char', 'unsigned short', 'unsigned
+int') used to store a pixel component (e.g. 'R' is one pixel component of
+an RGB pixel).
+
+
+QuantumType
+===========
+
+QuantumType is used to indicate the source or destination format of
+entire pixels, or components of pixels ("Quantums") while they are being
+read, or written to, a pixel cache. The validity of these format
+specifications depends on whether the Image pixels are in RGB format,
+RGBA format, or CMYK format. The pixel Quantum size is determined by the
+Image depth (eight or sixteen bits).
+
+.. table:: RGB(A) Image Quantums
+
+ +-----------------+-------------------------------------------------------------------------------+
+ | Enumeration | Description |
+ +-----------------+-------------------------------------------------------------------------------+
+ |IndexQuantum |PseudoColor colormap indices (valid only for image with colormap) |
+ +-----------------+-------------------------------------------------------------------------------+
+ |RedQuantum |Red pixel Quantum |
+ +-----------------+-------------------------------------------------------------------------------+
+ |GreenQuantum |Green pixel Quantum |
+ +-----------------+-------------------------------------------------------------------------------+
+ |BlueQuantum |Blue pixel Quantum |
+ +-----------------+-------------------------------------------------------------------------------+
+ |OpacityQuantum |Opacity (Alpha) Quantum |
+ +-----------------+-------------------------------------------------------------------------------+
+
+.. table:: CMY(K) Image Quantum
+
+ +--------------------------------------+----------------------------------------------------------+
+ | Enumeration | Description |
+ +--------------------------------------+----------------------------------------------------------+
+ |CyanQuantum |Cyan pixel Quantum |
+ +--------------------------------------+----------------------------------------------------------+
+ |MagentaQuantum |Magenta pixel Quantum |
+ +--------------------------------------+----------------------------------------------------------+
+ |YellowQuantum |Yellow pixel Quantum |
+ +--------------------------------------+----------------------------------------------------------+
+ |BlackQuantum |Black pixel Quantum |
+ +--------------------------------------+----------------------------------------------------------+
+
+.. table:: Grayscale Image Quantums
+
+ +--------------------------------------------------------+----------------------------------------+
+ | Enumeration | Description |
+ +--------------------------------------------------------+----------------------------------------+
+ |GrayQuantum |Gray pixel |
+ +--------------------------------------------------------+----------------------------------------+
+ |GrayOpacityQuantum |Pixel opacity |
+ +--------------------------------------------------------+----------------------------------------+
+
+.. table:: Entire Pixels (Expressed in Byte Order)
+
+ +---------------------------+---------------------------------------------------------------------+
+ | Enumeration | Description |
+ +---------------------------+---------------------------------------------------------------------+
+ |RGBQuantum |RGB pixel (24 or 48 octets) |
+ +---------------------------+---------------------------------------------------------------------+
+ |RGBAQuantum |RGBA pixel (32 or 64 octets) |
+ +---------------------------+---------------------------------------------------------------------+
+ |CMYKQuantum |CMYK pixel (32 or 64 octets) |
+ +---------------------------+---------------------------------------------------------------------+
+
+RectangleInfo
+=============
+
+The RectangleInfo structure is used to represent positioning information
+in GraphicsMagick.
+
+The members of the RectangleInfo structure are shown in the following
+table:
+
+.. table:: RectangleInfo Structure Members
+
+ +-------------------+------------------------+----------------------------------------------------+
+ | Member | Type | Description |
+ +-------------------+------------------------+----------------------------------------------------+
+ |width |unsigned int |Rectangle width |
+ +-------------------+------------------------+----------------------------------------------------+
+ |height |unsigned int |Rectangle height |
+ +-------------------+------------------------+----------------------------------------------------+
+ |x |int |Rectangle horizontal offset |
+ +-------------------+------------------------+----------------------------------------------------+
+ |y |int |Rectangle vertical offset |
+ +-------------------+------------------------+----------------------------------------------------+
+
+RegistryType
+============
+
+::
+
+ typedef enum
+ {
+ UndefinedRegistryType,
+ ImageRegistryType,
+ ImageInfoRegistryType
+ } RegistryType;
+
+
+RenderingIntent
+===============
+
+Rendering intent is a concept defined by ICC Spec ICC.1:1998-09, "File
+Format for Color Profiles". GraphicsMagick uses RenderingIntent in order
+to support ICC Color Profiles.
+
+From the specification: "Rendering intent specifies the style of
+reproduction to be used during the evaluation of this profile in a
+sequence of profiles. It applies specifically to that profile in the
+sequence and not to the entire sequence. Typically, the user or
+application will set the rendering intent dynamically at runtime or
+embedding time."
+
+.. table:: RenderingIntent
+
+ +----------------+--------------------------------------------------------------------------------+
+ | Enumeration | Description |
+ +----------------+--------------------------------------------------------------------------------+
+ |UndefinedIntent |Unset value. |
+ +----------------+--------------------------------------------------------------------------------+
+ |SaturationIntent|A rendering intent that specifies the saturation of the pixels in the image is |
+ | |preserved perhaps at the expense of accuracy in hue and lightness. |
+ +----------------+--------------------------------------------------------------------------------+
+ | |A rendering intent that specifies the full gamut of the image is compressed or |
+ |PerceptualIntent|expanded to fill the gamut of the destination device. Gray balance is preserved |
+ | |but colorimetric accuracy might not be preserved. |
+ +----------------+--------------------------------------------------------------------------------+
+ |AbsoluteIntent |Absolute colorimetric |
+ +----------------+--------------------------------------------------------------------------------+
+ |RelativeIntent |Relative colorimetric |
+ +----------------+--------------------------------------------------------------------------------+
+
+ResolutionType
+==============
+
+By default, GraphicsMagick defines resolutions in pixels per inch.
+ResolutionType provides a means to adjust this.
+
+.. table:: ResolutionType
+
+ +-----------------------------+-------------------------------------------------------------------+
+ | Enumeration | Description |
+ +-----------------------------+-------------------------------------------------------------------+
+ |UndefinedResolution |Unset value. |
+ +-----------------------------+-------------------------------------------------------------------+
+ |PixelsPerInchResolution |Density specifications are specified in units of pixels per inch |
+ | |(english units). |
+ +-----------------------------+-------------------------------------------------------------------+
+ |PixelsPerCentimeterResolution|Density specifications are specified in units of pixels per |
+ | |centimeter (metric units). |
+ +-----------------------------+-------------------------------------------------------------------+
+
+ResourceType
+============
+
+::
+
+ typedef enum
+ {
+ UndefinedResource,
+ FileResource,
+ MemoryResource,
+ MapResource,
+ DiskResource
+ } ResourceType;
+
+
+SegmentInfo
+===========
+
+::
+
+ typedef struct _SegmentInfo
+ {
+ double
+ x1,
+ y1,
+ x2,
+ y2;
+ } SegmentInfo;
+
+SignatureInfo
+=============
+
+::
+
+ typedef struct _SignatureInfo
+ {
+ unsigned long
+ digest[8],
+ low_order,
+ high_order;
+
+ long
+ offset;
+
+ unsigned char
+ message[SignatureSize];
+ } SignatureInfo;
+
+
+StorageType
+===========
+
+::
+
+ typedef enum
+ {
+ CharPixel,
+ ShortPixel,
+ IntegerPixel,
+ LongPixel,
+ FloatPixel,
+ DoublePixel
+ } StorageType;
+
+
+StreamHandler
+=============
+
+::
+
+ typedef unsigned int
+ (*StreamHandler)(const Image *,const void *,const size_t);
+
+StretchType
+===========
+
+::
+
+ typedef enum
+ {
+ NormalStretch,
+ UltraCondensedStretch,
+ ExtraCondensedStretch,
+ CondensedStretch,
+ SemiCondensedStretch,
+ SemiExpandedStretch,
+ ExpandedStretch,
+ ExtraExpandedStretch,
+ UltraExpandedStretch,
+ AnyStretch
+ } StretchType;
+
+
+StyleType
+=========
+
+::
+
+ typedef enum
+ {
+ NormalStyle,
+ ItalicStyle,
+ ObliqueStyle,
+ AnyStyle
+ } StyleType;
+
+
+TypeMetric
+==========
+
+::
+
+ typedef struct _TypeMetric
+ {
+ PointInfo
+ pixels_per_em;
+
+ double
+ ascent,
+ descent,
+ width,
+ height,
+ max_advance;
+
+ SegmentInfo
+ bounds;
+
+ double
+ underline_position,
+ underline_thickness;
+ } TypeMetric;
+
+
+ViewInfo
+========
+
+ViewInfo represents a handle to a pixel view, which represents a uniquely
+selectable rectangular region of pixels. The only limit on the number of
+views is the amount of available memory. Each Image contains a collection
+of default views (one view per thread) so that the image may be usefully
+accessed without needing to explicitly allocate pixel views.
+
+::
+
+ typedef void *ViewInfo;
+
+
+VirtualPixelMethod
+==================
+
+::
+
+ typedef enum
+ {
+ UndefinedVirtualPixelMethod,
+ ConstantVirtualPixelMethod,
+ EdgeVirtualPixelMethod,
+ MirrorVirtualPixelMethod,
+ TileVirtualPixelMethod
+ } VirtualPixelMethod;
+
+
+MagickXResourceInfo
+===================
+
+::
+
+ typedef struct _XResourceInfo
+ {
+ XrmDatabase
+ resource_database;
+
+ ImageInfo
+ *image_info;
+
+ QuantizeInfo
+ *quantize_info;
+
+ unsigned long
+ colors;
+
+ unsigned int
+ close_server,
+ backdrop;
+
+ char
+ *background_color,
+ *border_color;
+
+ char
+ *client_name;
+
+ XColormapType
+ colormap;
+
+ unsigned int
+ border_width,
+ color_recovery,
+ confirm_exit,
+ delay;
+
+ char
+ *display_gamma;
+
+ char
+ *font,
+ *font_name[MaxNumberFonts],
+ *foreground_color;
+
+ unsigned int
+ display_warnings,
+ gamma_correct;
+
+ char
+ *icon_geometry;
+
+ unsigned int
+ iconic,
+ immutable;
+
+ char
+ *image_geometry;
+
+ char
+ *map_type,
+ *matte_color,
+ *name;
+
+ unsigned int
+ magnify,
+ pause; char
+ *pen_colors[MaxNumberPens];
+
+ char
+ *text_font,
+ *title;
+
+ int
+ quantum;
+
+ unsigned int
+ update,
+ use_pixmap,
+ use_shared_memory;
+
+ unsigned long
+ undo_cache;
+
+ char
+ *visual_type,
+ *window_group,
+ *window_id,
+ *write_filename;
+
+ Image
+ *copy_image;
+
+ int
+ gravity;
+
+ char
+ home_directory[MaxTextExtent];
+ } XResourceInfo;
+
+-------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
+
diff --git a/www/api/widget.html b/www/api/widget.html
new file mode 100644
index 0000000..4f26808
--- /dev/null
+++ b/www/api/widget.html
@@ -0,0 +1,504 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>widget</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="widget">
+<h1 class="title">widget</h1>
+<h2 class="subtitle" id="x11-widgets">X11 Widgets</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#xcolorbrowserwidget" id="id25">XColorBrowserWidget</a></li>
+<li><a class="reference internal" href="#xcommandwidget" id="id26">XCommandWidget</a></li>
+<li><a class="reference internal" href="#xconfirmwidget" id="id27">XConfirmWidget</a></li>
+<li><a class="reference internal" href="#xdialogwidget" id="id28">XDialogWidget</a></li>
+<li><a class="reference internal" href="#xfilebrowserwidget" id="id29">XFileBrowserWidget</a></li>
+<li><a class="reference internal" href="#xfontbrowserwidget" id="id30">XFontBrowserWidget</a></li>
+<li><a class="reference internal" href="#xinfowidget" id="id31">XInfoWidget</a></li>
+<li><a class="reference internal" href="#xlistbrowserwidget" id="id32">XListBrowserWidget</a></li>
+<li><a class="reference internal" href="#xmenuwidget" id="id33">XMenuWidget</a></li>
+<li><a class="reference internal" href="#xmonitorwidget" id="id34">XMonitorWidget</a></li>
+<li><a class="reference internal" href="#xnoticewidget" id="id35">XNoticeWidget</a></li>
+<li><a class="reference internal" href="#xpreferenceswidget" id="id36">XPreferencesWidget</a></li>
+<li><a class="reference internal" href="#xtextviewwidget" id="id37">XTextViewWidget</a></li>
+</ul>
+</div>
+<div class="section" id="xcolorbrowserwidget">
+<h1><a class="toc-backref" href="#id25">XColorBrowserWidget</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXColorBrowserWidget( Display *display, MagickXWindows *windows, const char *action,
+ char *reply );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>Method MagickXColorBrowserWidget displays a Color Browser widget with a color
+query to the user. The user keys a reply and presses the Action or Cancel
+button to exit. The typed text is returned as the reply function parameter.</p>
+<p>The format of the MagickXColorBrowserWidget method is:</p>
+<pre class="literal-block">
+void MagickXColorBrowserWidget( Display *display, MagickXWindows *windows, const char *action,
+ char *reply );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>action:</dt>
+<dd>Specifies a pointer to the action of this widget.</dd>
+<dt>reply:</dt>
+<dd>The response from the user is returned in this parameter.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xcommandwidget">
+<h1><a class="toc-backref" href="#id26">XCommandWidget</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+int MagickXCommandWidget( Display *display, MagickXWindows *windows,
+ const char ** selections, XEvent *event );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>Method MagickXCommandWidget maps a menu and returns the command pointed to by
+the user when the button is released.</p>
+<p>The format of the MagickXCommandWidget method is:</p>
+<pre class="literal-block">
+int MagickXCommandWidget( Display *display, MagickXWindows *windows,
+ const char ** selections, XEvent *event );
+</pre>
+<dl class="docutils">
+<dt>selection_number:</dt>
+<dd>Specifies the number of the selection that the
+user choose.</dd>
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>selections:</dt>
+<dd>Specifies a pointer to one or more strings that comprise
+the choices in the menu.</dd>
+<dt>event:</dt>
+<dd>Specifies a pointer to a X11 XEvent structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xconfirmwidget">
+<h1><a class="toc-backref" href="#id27">XConfirmWidget</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+int MagickXConfirmWidget( Display *display, MagickXWindows *windows, const char *reason,
+ const char *description );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>Method MagickXConfirmWidget displays a Confirm widget with a notice to the user.
+The function returns -1 if Dismiss is pressed, 0 for Cancel, and 1 for
+Yes.</p>
+<p>The format of the MagickXConfirmWidget method is:</p>
+<pre class="literal-block">
+int MagickXConfirmWidget( Display *display, MagickXWindows *windows, const char *reason,
+ const char *description );
+</pre>
+<dl class="docutils">
+<dt>status:</dt>
+<dd>Method MagickXConfirmWidget returns True if the user presses Yes
+otherwise False is returned.</dd>
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>reason:</dt>
+<dd>Specifies the message to display before terminating the
+program.</dd>
+<dt>description:</dt>
+<dd>Specifies any description to the message.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xdialogwidget">
+<h1><a class="toc-backref" href="#id28">XDialogWidget</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+int MagickXDialogWidget( Display *display, MagickXWindows *windows, const char *action,
+ const char *query, char *reply );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>Method MagickXDialogWidget displays a Dialog widget with a query to the user.
+The user keys a reply and presses the Ok or Cancel button to exit. The
+typed text is returned as the reply function parameter.</p>
+<p>The format of the MagickXDialogWidget method is:</p>
+<pre class="literal-block">
+int MagickXDialogWidget( Display *display, MagickXWindows *windows, const char *action,
+ const char *query, char *reply );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>action:</dt>
+<dd>Specifies a pointer to the action of this widget.</dd>
+<dt>query:</dt>
+<dd>Specifies a pointer to the query to present to the user.</dd>
+<dt>reply:</dt>
+<dd>The response from the user is returned in this parameter.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xfilebrowserwidget">
+<h1><a class="toc-backref" href="#id29">XFileBrowserWidget</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXFileBrowserWidget( Display *display, MagickXWindows *windows, const char *action,
+ char *reply );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>Method MagickXFileBrowserWidget displays a File Browser widget with a file query
+to the user. The user keys a reply and presses the Action or Cancel button
+to exit. The typed text is returned as the reply function parameter.</p>
+<p>The format of the MagickXFileBrowserWidget method is:</p>
+<pre class="literal-block">
+void MagickXFileBrowserWidget( Display *display, MagickXWindows *windows, const char *action,
+ char *reply );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>action:</dt>
+<dd>Specifies a pointer to the action of this widget.</dd>
+<dt>reply:</dt>
+<dd>The response from the user is returned in this parameter.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xfontbrowserwidget">
+<h1><a class="toc-backref" href="#id30">XFontBrowserWidget</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXFontBrowserWidget( Display *display, MagickXWindows *windows, const char *action,
+ char *reply );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>Method MagickXFontBrowserWidget displays a Font Browser widget with a font query
+to the user. The user keys a reply and presses the Action or Cancel button
+to exit. The typed text is returned as the reply function parameter.</p>
+<p>The format of the MagickXFontBrowserWidget method is:</p>
+<pre class="literal-block">
+void MagickXFontBrowserWidget( Display *display, MagickXWindows *windows, const char *action,
+ char *reply );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>action:</dt>
+<dd>Specifies a pointer to the action of this widget.</dd>
+<dt>reply:</dt>
+<dd>The response from the user is returned in this parameter.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xinfowidget">
+<h1><a class="toc-backref" href="#id31">XInfoWidget</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXInfoWidget( Display *display, MagickXWindows *windows, const char *activity );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>Method MagickXInfoWidget displays text in the Info widget. The purpose is to
+inform the user that what activity is currently being performed (e.g.
+reading an image, rotating an image, etc.).</p>
+<p>The format of the MagickXInfoWidget method is:</p>
+<pre class="literal-block">
+void MagickXInfoWidget( Display *display, MagickXWindows *windows, const char *activity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>activity:</dt>
+<dd>This character string reflects the current activity and is
+displayed in the Info widget.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xlistbrowserwidget">
+<h1><a class="toc-backref" href="#id32">XListBrowserWidget</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXListBrowserWidget( Display *display, MagickXWindows *windows,
+ MagickXWindowInfo *window_info, const char ** list,
+ const char *action, const char *query, char *reply );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>Method MagickXListBrowserWidget displays a List Browser widget with a query to
+the user. The user keys a reply or select a reply from the list. Finally,
+the user presses the Action or Cancel button to exit. The typed text is
+returned as the reply function parameter.</p>
+<p>The format of the MagickXListBrowserWidget method is:</p>
+<pre class="literal-block">
+void MagickXListBrowserWidget( Display *display, MagickXWindows *windows,
+ MagickXWindowInfo *window_info, const char ** list,
+ const char *action, const char *query, char *reply );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>list:</dt>
+<dd>Specifies a pointer to an array of strings. The user can
+select from these strings as a possible reply value.</dd>
+<dt>action:</dt>
+<dd>Specifies a pointer to the action of this widget.</dd>
+<dt>query:</dt>
+<dd>Specifies a pointer to the query to present to the user.</dd>
+<dt>reply:</dt>
+<dd>The response from the user is returned in this parameter.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xmenuwidget">
+<h1><a class="toc-backref" href="#id33">XMenuWidget</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+int MagickXMenuWidget( Display *display, MagickXWindows *windows, const char *title,
+ const char ** selections, char *item );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>Method MagickXMenuWidget maps a menu and returns the command pointed to by the
+user when the button is released.</p>
+<p>The format of the MagickXMenuWidget method is:</p>
+<pre class="literal-block">
+int MagickXMenuWidget( Display *display, MagickXWindows *windows, const char *title,
+ const char ** selections, char *item );
+</pre>
+<dl class="docutils">
+<dt>selection_number:</dt>
+<dd>Specifies the number of the selection that the
+user choose.</dd>
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>title:</dt>
+<dd>Specifies a character string that describes the menu selections.</dd>
+<dt>selections:</dt>
+<dd>Specifies a pointer to one or more strings that comprise
+the choices in the menu.</dd>
+<dt>item:</dt>
+<dd>Specifies a character array. The item selected from the menu
+is returned here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xmonitorwidget">
+<h1><a class="toc-backref" href="#id34">XMonitorWidget</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXMonitorWidget( Display *display, MagickXWindows *windows, const char *task,
+ const magick_int64_t quantum, const magick_uint64_t span );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>Method MagickXMonitorWidget displays the progress a task is making in
+completing a task. A span of zero toggles the active status. An inactive
+state disables the progress monitor.</p>
+<p>The format of the MagickXMonitorWidget method is:</p>
+<pre class="literal-block">
+void MagickXMonitorWidget( Display *display, MagickXWindows *windows, const char *task,
+ const magick_int64_t quantum, const magick_uint64_t span );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>task:</dt>
+<dd>Identifies the task in progress.</dd>
+<dt>quantum:</dt>
+<dd>Specifies the quantum position within the span which represents
+how much progress has been made in completing a task.</dd>
+<dt>span:</dt>
+<dd>Specifies the span relative to completing a task.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xnoticewidget">
+<h1><a class="toc-backref" href="#id35">XNoticeWidget</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXNoticeWidget( Display *display, MagickXWindows *windows, const char *reason,
+ const char *description );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>Method MagickXNoticeWidget displays a Notice widget with a notice to the user.
+The function returns when the user presses the &quot;Dismiss&quot; button.</p>
+<p>The format of the MagickXNoticeWidget method is:</p>
+<pre class="literal-block">
+void MagickXNoticeWidget( Display *display, MagickXWindows *windows, const char *reason,
+ const char *description );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>reason:</dt>
+<dd>Specifies the message to display before terminating the
+program.</dd>
+<dt>description:</dt>
+<dd>Specifies any description to the message.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xpreferenceswidget">
+<h1><a class="toc-backref" href="#id36">XPreferencesWidget</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickXPreferencesWidget( Display *display,
+ <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ MagickXWindows *windows );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>Method MagickXPreferencesWidget displays a Preferences widget with program
+preferences. If the user presses the Apply button, the preferences are
+stored in a configuration file in the users' home directory.</p>
+<p>The format of the MagickXPreferencesWidget method is:</p>
+<pre class="literal-block">
+unsigned int MagickXPreferencesWidget( Display *display,
+ <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ MagickXWindows *windows );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>resource_info:</dt>
+<dd>Specifies a pointer to a X11 MagickXResourceInfo structure.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="xtextviewwidget">
+<h1><a class="toc-backref" href="#id37">XTextViewWidget</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickXTextViewWidget( Display *display, const <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ MagickXWindows *windows, const unsigned int mono,
+ const char *title, const char ** textlist );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>Method MagickXTextViewWidget displays text in a Text View widget.</p>
+<p>The format of the MagickXTextViewWidget method is:</p>
+<pre class="literal-block">
+void MagickXTextViewWidget( Display *display, const <a class="reference external" href="../api/types.html#magickxresourceinfo">MagickXResourceInfo</a> *resource_info,
+ MagickXWindows *windows, const unsigned int mono,
+ const char *title, const char ** textlist );
+</pre>
+<dl class="docutils">
+<dt>display:</dt>
+<dd>Specifies a connection to an X server; returned from
+XOpenDisplay.</dd>
+<dt>resource_info:</dt>
+<dd>Specifies a pointer to a X11 MagickXResourceInfo structure.</dd>
+<dt>window:</dt>
+<dd>Specifies a pointer to a MagickXWindows structure.</dd>
+<dt>mono:</dt>
+<dd>Use mono-spaced font when displaying text.</dd>
+<dt>title:</dt>
+<dd>This character string is displayed at the top of the widget
+window.</dd>
+<dt>textlist:</dt>
+<dd>This string list is displayed within the Text View widget.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/authors.html b/www/authors.html
new file mode 100644
index 0000000..75c6b3b
--- /dev/null
+++ b/www/authors.html
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Authors</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-authors">
+<h1 class="title">GraphicsMagick Authors</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The following people have contributed substantially to the development
+of GraphicsMagick. Please let us know if an author is missing, or a
+significant contribution was made and not recorded.</p>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#active-graphicsmagick-contributors" id="id1">Active GraphicsMagick Contributors</a></li>
+<li><a class="reference internal" href="#former-graphicsmagick-contributors" id="id2">Former GraphicsMagick Contributors</a></li>
+<li><a class="reference internal" href="#other-contributors-via-imagemagick" id="id3">Other Contributors (via ImageMagick)</a></li>
+</ul>
+</div>
+<div class="section" id="active-graphicsmagick-contributors">
+<h1><a class="toc-backref" href="#id1">Active GraphicsMagick Contributors</a></h1>
+<dl class="docutils">
+<dt>Bob Friesenhahn</dt>
+<dd>Principal maintainer of GraphicsMagick. Author of
+Magick++ (C++ API to ImageMagick and GraphicsMagick).
+Author of module loader facility, automatic file
+identification (magic) support, Unix/Cygwin/MinGW
+configure/make facility, Windows setup.exe style
+installer, WMF renderer, C API documentation formatter,
+and the C, C++, and Perl test suites used by ImageMagick
+and GraphicsMagick.</dd>
+<dt>Glenn Randers-Pehrson</dt>
+<dd>Contributed significantly to the utilities, including
+writing the 'gm' utility wrapper. Authored support for
+JNG, MNG, and PNG formats. Provided significant support
+for the BMP format. Significant improvements to the
+documentation, including creating a documentation
+authoring environment based on the &lt;imdoc&gt; format.
+Maintains the SourceForge mailing lists.</dd>
+<dt>Jaroslav Fojtik</dt>
+<dd>Authored the ART, CUT, HRZ, JNX, MAC, MATLAB, TOPOL,
+and WPG coder modules. Improved the FITS and TXT coder
+modules. VisualMagick 'configure' improvements and
+build testing/fixes for many versions of Microsoft
+Visual Studio.</dd>
+</dl>
+</div>
+<div class="section" id="former-graphicsmagick-contributors">
+<h1><a class="toc-backref" href="#id2">Former GraphicsMagick Contributors</a></h1>
+<dl class="docutils">
+<dt>Kenneth Xu</dt>
+<dd>Contributed the implementation of 'gm batch', a simple
+batch mode for GraphicsMagick.</dd>
+<dt>Troy Patteson</dt>
+<dd>Contributed a several significant patches to fix image
+rotation bugs and improve image rotation performance,
+as well as an improved bi-linear interpolation
+implementation.</dd>
+<dt>Sara Shafaei</dt>
+<dd>Contributed a number of Wand API functions as well as
+fixes for several composition operators.</dd>
+<dt>Brendan Lane</dt>
+<dd>Contributed a large number of new Photoshop
+composition operators and alpha-channel fixes for
+existing ones.</dd>
+<dt>Dirk Lemstra</dt>
+<dd>Contributed improvements to the VisualMagick configure
+program to support configuring more build options via
+the GUI dialogs and to deal with similarly named
+files.</dd>
+<dt>Roman Hiestand</dt>
+<dd>Contributed WebP coder improvements.</dd>
+<dt>Mike Chiarappa</dt>
+<dd>Created and maintains the Borland C++ Builder 6.0 build
+environment for GraphicsMagick.</dd>
+<dt>Daniel Kobras</dt>
+<dd>Provided many security patches and fixes from the Debian
+project.</dd>
+<dt>William Radcliffe</dt>
+<dd>Author of the VisualMagick project configure facility for
+Visual C++. Author of FlashPix module. Author of the
+ImageMagickObject COM object for Windows. Author of the
+EMF, XTRN, and META coders. Significant contributions to
+the MSL, JPEG, TIFF, SVG, and URL coders. Authored
+&quot;process&quot; module support. Wrote the micro-timer facility
+used by 'identify'. Ported module loader support to
+Windows. Significantly improved polygon rendering
+performance.</dd>
+<dt>Leonard Rosenthol</dt>
+<dd>Authored the 'conjure' utility and associated MSL
+execution environment. Provided MacOS support. Authored
+the CLIPBOARD, XCF, and PSD coders. Postscript and PDF
+expertise. Significant drawing enhancements including
+support for dash patterns, linecap stroking, clipping
+masks and a mask image.</dd>
+<dt>Lars Ruben Skyum</dt>
+<dd>Contributed the -clippath functionality, added
+-define support, improved color profile support,
+and re-wrote the PS3 coder.</dd>
+<dt>Rolf Schroedter</dt>
+<dd>Principal author of TclMagick.</dd>
+<dt>David N. Welton</dt>
+<dd>Co-author of TclMagick, particularly in the Unix environment.</dd>
+<dt>Mark Mitchell</dt>
+<dd>Contributed a new design for the web pages, including the
+formatting scripts, and converted many pages to the new
+format.</dd>
+<dt>Richard Nolde</dt>
+<dd>Contributed code for converting between native floating
+point types, and short (16/24) bit float types.</dd>
+<dt>Clément Follet</dt>
+<dd>Contributed Hald CLUT and ASC-CDL implementations.</dd>
+<dt>John Sergeant</dt>
+<dd>Re-wrote the HP PCL writer to work much better,
+including support for compression. Implemented
+support for CALS type 1 format. Re-wrote the DICOM
+reader.</dd>
+<dt>Roberto de Deus Barbosa Murta</dt>
+<dd>Contributed the adaptive threshold implementation
+(-lat), which executes in linear rather than quadratic
+time.</dd>
+</dl>
+</div>
+<div class="section" id="other-contributors-via-imagemagick">
+<h1><a class="toc-backref" href="#id3">Other Contributors (via ImageMagick)</a></h1>
+<dl class="docutils">
+<dt>John Cristy</dt>
+<dd>Creator, principal author, and principal maintainer of
+ImageMagick, from which GraphicsMagick is originally
+derived (from ImageMagick 5.5.2). Also the author of
+the Wand API to ImageMagick which is incorporated as
+a stand-alone library by GraphicsMagick.</dd>
+<dt>Kelly Bergougnoux</dt>
+<dd>Authored the initial Cineon coder (which has since been
+replaced).</dd>
+<dt>Christopher R. Hawks</dt>
+<dd>Authored the PALM coder.</dd>
+<dt>Francis J. Franklin</dt>
+<dd>Ported the WMF coder to the libwmf 0.2 API.</dd>
+<dt>Rick Mabry</dt>
+<dd>Contributed code to support filling drawn objects using a
+pattern image.</dd>
+<dt>Nathan Brown</dt>
+<dd>Original author of the JP2 coder.</dd>
+<dt>Kyle Shorter</dt>
+<dd>Original author of PerlMagick. Original author of the
+LOCALE coder.</dd>
+<dt>Markus Friedl</dt>
+<dd>Original author of Base64 encode/decode sources.</dd>
+<dt>David Harr</dt>
+<dd>Contributed (with Leonard Rosenthol) dash pattern,
+linecap stroking algorithm, and minor rendering
+improvements.</dd>
+<dt>Troy Edwards</dt>
+<dd>Authored the source RPM spec file for GraphicsMagick.</dd>
+<dt>Milan Votava</dt>
+<dd>Contributed support for Wireless BitMap, used in WAP -
+Wireless Access Protocol.</dd>
+<dt>Mike Edmonds</dt>
+<dd>Contributed the median filter algorithm.</dd>
+</dl>
+<hr class="docutils" />
+<div class="line-block">
+<div class="line">Copyright © GraphicsMagick Group 2002 - 2017</div>
+</div>
+<p>This program is covered by multiple licenses, which are described in
+Copyright.txt. You should have received a copy of Copyright.txt with this
+package; otherwise see <a class="reference external" href="http://www.graphicsmagick.org/Copyright.html">http://www.graphicsmagick.org/Copyright.html</a>.</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/authors.rst b/www/authors.rst
new file mode 100644
index 0000000..f9533d1
--- /dev/null
+++ b/www/authors.rst
@@ -0,0 +1,198 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+======================
+GraphicsMagick Authors
+======================
+
+The following people have contributed substantially to the development
+of GraphicsMagick. Please let us know if an author is missing, or a
+significant contribution was made and not recorded.
+
+.. contents::
+ :local:
+
+
+Active GraphicsMagick Contributors
+==================================
+
+Bob Friesenhahn
+ Principal maintainer of GraphicsMagick. Author of
+ Magick++ (C++ API to ImageMagick and GraphicsMagick).
+ Author of module loader facility, automatic file
+ identification (magic) support, Unix/Cygwin/MinGW
+ configure/make facility, Windows setup.exe style
+ installer, WMF renderer, C API documentation formatter,
+ and the C, C++, and Perl test suites used by ImageMagick
+ and GraphicsMagick.
+
+Glenn Randers-Pehrson
+ Contributed significantly to the utilities, including
+ writing the 'gm' utility wrapper. Authored support for
+ JNG, MNG, and PNG formats. Provided significant support
+ for the BMP format. Significant improvements to the
+ documentation, including creating a documentation
+ authoring environment based on the <imdoc> format.
+ Maintains the SourceForge mailing lists.
+
+Jaroslav Fojtik
+ Authored the ART, CUT, HRZ, JNX, MAC, MATLAB, TOPOL,
+ and WPG coder modules. Improved the FITS and TXT coder
+ modules. VisualMagick 'configure' improvements and
+ build testing/fixes for many versions of Microsoft
+ Visual Studio.
+
+
+Former GraphicsMagick Contributors
+==================================
+
+Kenneth Xu
+ Contributed the implementation of 'gm batch', a simple
+ batch mode for GraphicsMagick.
+
+Troy Patteson
+ Contributed a several significant patches to fix image
+ rotation bugs and improve image rotation performance,
+ as well as an improved bi-linear interpolation
+ implementation.
+
+Sara Shafaei
+ Contributed a number of Wand API functions as well as
+ fixes for several composition operators.
+
+Brendan Lane
+ Contributed a large number of new Photoshop
+ composition operators and alpha-channel fixes for
+ existing ones.
+
+Dirk Lemstra
+ Contributed improvements to the VisualMagick configure
+ program to support configuring more build options via
+ the GUI dialogs and to deal with similarly named
+ files.
+
+Roman Hiestand
+ Contributed WebP coder improvements.
+
+Mike Chiarappa
+ Created and maintains the Borland C++ Builder 6.0 build
+ environment for GraphicsMagick.
+
+Daniel Kobras
+ Provided many security patches and fixes from the Debian
+ project.
+
+William Radcliffe
+ Author of the VisualMagick project configure facility for
+ Visual C++. Author of FlashPix module. Author of the
+ ImageMagickObject COM object for Windows. Author of the
+ EMF, XTRN, and META coders. Significant contributions to
+ the MSL, JPEG, TIFF, SVG, and URL coders. Authored
+ "process" module support. Wrote the micro-timer facility
+ used by 'identify'. Ported module loader support to
+ Windows. Significantly improved polygon rendering
+ performance.
+
+Leonard Rosenthol
+ Authored the 'conjure' utility and associated MSL
+ execution environment. Provided MacOS support. Authored
+ the CLIPBOARD, XCF, and PSD coders. Postscript and PDF
+ expertise. Significant drawing enhancements including
+ support for dash patterns, linecap stroking, clipping
+ masks and a mask image.
+
+Lars Ruben Skyum
+ Contributed the -clippath functionality, added
+ -define support, improved color profile support,
+ and re-wrote the PS3 coder.
+
+Rolf Schroedter
+ Principal author of TclMagick.
+
+David N. Welton
+ Co-author of TclMagick, particularly in the Unix environment.
+
+Mark Mitchell
+ Contributed a new design for the web pages, including the
+ formatting scripts, and converted many pages to the new
+ format.
+
+Richard Nolde
+ Contributed code for converting between native floating
+ point types, and short (16/24) bit float types.
+
+Clment Follet
+ Contributed Hald CLUT and ASC-CDL implementations.
+
+John Sergeant
+ Re-wrote the HP PCL writer to work much better,
+ including support for compression. Implemented
+ support for CALS type 1 format. Re-wrote the DICOM
+ reader.
+
+Roberto de Deus Barbosa Murta
+ Contributed the adaptive threshold implementation
+ (-lat), which executes in linear rather than quadratic
+ time.
+
+
+Other Contributors (via ImageMagick)
+====================================
+
+John Cristy
+ Creator, principal author, and principal maintainer of
+ ImageMagick, from which GraphicsMagick is originally
+ derived (from ImageMagick 5.5.2). Also the author of
+ the Wand API to ImageMagick which is incorporated as
+ a stand-alone library by GraphicsMagick.
+
+Kelly Bergougnoux
+ Authored the initial Cineon coder (which has since been
+ replaced).
+
+Christopher R. Hawks
+ Authored the PALM coder.
+
+Francis J. Franklin
+ Ported the WMF coder to the libwmf 0.2 API.
+
+Rick Mabry
+ Contributed code to support filling drawn objects using a
+ pattern image.
+Nathan Brown
+ Original author of the JP2 coder.
+
+Kyle Shorter
+ Original author of PerlMagick. Original author of the
+ LOCALE coder.
+
+Markus Friedl
+ Original author of Base64 encode/decode sources.
+
+David Harr
+ Contributed (with Leonard Rosenthol) dash pattern,
+ linecap stroking algorithm, and minor rendering
+ improvements.
+
+Troy Edwards
+ Authored the source RPM spec file for GraphicsMagick.
+
+Milan Votava
+ Contributed support for Wireless BitMap, used in WAP -
+ Wireless Access Protocol.
+
+Mike Edmonds
+ Contributed the median filter algorithm.
+
+
+---------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+| Copyright |copy| GraphicsMagick Group 2002 - 2017
+
+This program is covered by multiple licenses, which are described in
+Copyright.txt. You should have received a copy of Copyright.txt with this
+package; otherwise see http://www.graphicsmagick.org/Copyright.html.
+
diff --git a/www/batch.html b/www/batch.html
new file mode 100644
index 0000000..9f54cc0
--- /dev/null
+++ b/www/batch.html
@@ -0,0 +1,276 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch"></a>gm batch
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+batch - execute multiple gm commands as a script
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#batch-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#batch-desc">Description</a>
+</dt>
+<dt>
+<a href="#batch-exam">Examples</a>
+</dt>
+<dt>
+<a href="#batch-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm batch</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <strong>[</strong> <em>script</em> <strong>]</strong>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>batch</strong> executes an arbitary number of the utility commands
+(e.g. <strong>convert</strong>) in the form of a simple linear batch script in
+order to improve execution efficiency, and/or to allow use as a
+subordinate co-process under the control of an arbitrary script or
+program.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p> To drive <strong>'gm batch'</strong> using a shell script (or a program
+written in any language), have the script/program send commands to 'gm
+batch' via its standard input. Specify that standard input should be
+used by using <strong>'-'</strong> as the file name. The following example
+converts all files matching '*.jpg' to TIFF format while rotating each
+file by 90 degrees and stripping all embedded profiles. The shell
+script syntax is standard Unix shell:
+<pre>
+ for file in *.jpg
+ do
+ outfile=`basename $file .jpg`.tiff
+ echo convert -verbose "'$file'" -rotate 90 \
+ +profile "'*'" "'$outfile'"
+ done | gm batch -echo on -feedback on -
+</pre>
+<p>
+We can accomplish the same as the previous example by putting all the
+commands in a text file and then specifying the name of the text file
+as the script to execute:
+<pre>
+ for file in *.jpg
+ do
+ outfile=`basename $file .jpg`.tiff
+ echo convert -verbose "'$file'" -rotate 90 \
+ +profile "'*'" "'$outfile'"
+ done &gt; script.txt
+ gm batch -echo on -feedback on script.txt
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed from left to right and must appear before any filename argument.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -echo <i>on|off</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>command echo on or off</td></tr></table>
+<p>
+Specify <strong>on</strong> to enable echoing commands to standard output as
+they are read or <strong>off</strong> to disable. The default is
+<strong>off</strong>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -escape <i>unix|windows</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Parse using unix or windows syntax</td></tr></table>
+<p>
+Commands must be parsed from the input stream and escaping needs to be
+used to protect spaces or quoting characters in the input. Specify
+<strong>unix</strong> to use unix-style command line parsing or <strong>windows</strong>
+for Microsoft Windows command shell style parsing. The default depends
+on if the software is compiled for Microsoft Windows or for a
+Unix-type system (including Cygwin on Microsoft Windows). It is
+recommended to use unix syntax because it is more powerful and more
+portable.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -fail <i>text</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>text to print if a command fails</td></tr></table>
+<p>
+When feedback is enabled, this specifies the text to print when the
+command fails. The default text is <strong>FAIL</strong>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -feedback <i>on|off</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable error feedback</td></tr></table>
+<p>
+Print text (see -pass and -fail options) feedback after each
+command to indicate the result, the default is <strong>off</strong>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<p>
+Prints batch command help.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pass <i>text</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>text to print if a command passes</td></tr></table>
+<p>
+When feedback is enabled, this specifies the text to print when the
+command passes. The default text is <strong>PASS</strong>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -prompt <i>text</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Prompt text to use for command line</td></tr></table>
+<p>
+If no filename argument was specified, a simple command prompt appears
+where you may enter GraphicsMagick commands. The default prompt is
+<strong>GM&gt;</strong>. Use this option to change the prompt to something else.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -stop-on-error <i>on|off</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify if command processing stops on error</td></tr></table>
+<p>
+Normally command processing continues if a command encounters an
+error. Specify <strong>-stop-on-error on</strong> to cause processing to quit
+immediately on error.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+</td></tr></table>
diff --git a/www/benchmark.html b/www/benchmark.html
new file mode 100644
index 0000000..9254484
--- /dev/null
+++ b/www/benchmark.html
@@ -0,0 +1,259 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="benchmark"></a>gm benchmark
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+benchmark - benchmark the execution of a gm command
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#bench-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#bench-desc">Description</a>
+</dt>
+<dt>
+<a href="#bench-exam">Examples</a>
+</dt>
+<dt>
+<a href="#bench-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm benchmark</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>command</em>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>benchmark</strong> executes an arbitrary <strong>gm</strong> utility command
+(e.g. <strong>convert</strong>) for one or more loops, and/or a specified
+execution time, and reports many execution metrics. For builds using
+OpenMP, a mode is provided to execute the benchmark with an increasing
+number of threads and provide a report of speedup and multi-thread
+execution efficiency. If <strong>benchmark</strong> is used to execute a
+command without any additional benchmark options, then the command is
+run once.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>To obtain benchmark information for a single execution of a
+command:
+<pre>
+ % gm benchmark convert input.ppm -gaussian 0x1 output.ppm
+ Results: 32 threads 1 iter 6.20s user 0.41s total 2.439 iter/s 0.161 iter/cpu
+</pre>
+<p>To obtain benchmark information from 100 iterations of the
+command:
+<pre>
+ % gm benchmark -iterations 100 convert input.ppm -gaussian 0x1 output.ppm
+ Results: 32 threads 100 iter 625.40s user 31.74s total 3.151 iter/s 0.160 iter/cpu
+</pre>
+<p>To obtain benchmark information by iterating the command until a
+specified amount of time (in seconds) has been consumed:
+<pre>
+ % gm benchmark -duration 30 convert input.ppm -gaussian 0x1 output.ppm
+ Results: 32 threads 91 iter 587.33s user 30.30s total 3.003 iter/s 0.155 iter/cpu
+</pre>
+<p>To obtain a full performance report with an increasing number of
+threads (1-32 threads, stepping the number of threads by four each
+time):
+<pre>
+ % gm benchmark -duration 3 -stepthreads 4 convert input.ppm -gaussian 0x2 output.ppm
+ Results: 1 threads 1 iter 8.84s user 8.84s total 0.113 iter/s 0.113 iter/cpu 1.00 speedup 1.000 karp-flatt
+ Results: 4 threads 2 iter 18.37s user 4.89s total 0.409 iter/s 0.109 iter/cpu 3.62 speedup 0.035 karp-flatt
+ Results: 8 threads 3 iter 29.81s user 4.09s total 0.733 iter/s 0.101 iter/cpu 6.48 speedup 0.033 karp-flatt
+ Results: 12 threads 3 iter 30.81s user 3.14s total 0.955 iter/s 0.097 iter/cpu 8.45 speedup 0.038 karp-flatt
+ Results: 16 threads 3 iter 35.02s user 3.01s total 0.997 iter/s 0.086 iter/cpu 8.81 speedup 0.054 karp-flatt
+ Results: 20 threads 4 iter 52.92s user 3.53s total 1.133 iter/s 0.076 iter/cpu 10.02 speedup 0.052 karp-flatt
+ Results: 24 threads 4 iter 60.66s user 3.39s total 1.180 iter/s 0.066 iter/cpu 10.43 speedup 0.057 karp-flatt
+ Results: 28 threads 4 iter 73.10s user 3.35s total 1.194 iter/s 0.055 iter/cpu 10.56 speedup 0.061 karp-flatt
+ Results: 32 threads 4 iter 82.10s user 3.09s total 1.294 iter/s 0.049 iter/cpu 11.44 speedup 0.058 karp-flatt
+</pre>
+<p>Here is the interpretation of the output:
+<ul>
+<li><strong>threads</strong> - number of threads used.
+<li><strong>iter</strong> - number of command iterations executed.
+<li><strong>user</strong> - total user time consumed.
+<li><strong>total</strong> - total elapsed time consumed.
+<li><strong>iter/s</strong> - number of command iterations per second.
+<li><strong>iter/cpu</strong> - amount of CPU time consumed per iteration.
+<li><strong>speedup</strong> - speedup compared with one thread.
+<li><strong>karp-flatt</strong> - Karp-Flatt measure of speedup efficiency.
+</ul>
+<p><em>Please note that the reported "speedup" is based on the
+execution time of just one thread. A preliminary warm-up pass is used
+before timing the first loop in order to ensure that the CPU is
+brought out of power-saving modes and that system caches are warmed
+up. Most modern CPUs provide a "turbo" mode where the CPU clock speed
+is increased (e.g. by a factor of two) when only one or two cores are
+active. If the CPU grows excessively hot (due to insufficient
+cooling), then it may dial back its clock rates as a form of thermal
+management. These factors result in an under-reporting of speedup
+compared to if "turbo" mode was disabled and the CPU does not need to
+worry about thermal management. The <strong>powertop</strong> utility available
+under Linux and Solaris provides a way to observe CPU core clock rates
+while a benchmark is running.</em>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p> Options are processed from left to right and must appear before
+any argument.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -duration <i>duration</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>duration to run benchmark</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Specify the number of seconds to run the benchmark. The command is
+executed repeatedly until the specified amount of time has
+elapsed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Prints benchmark command help.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -iterations <i>loops</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>number of command iterations</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Specify the number of iterations to run the benchmark. The command
+is executed repeatedly until the specified number of iterations has
+been reached.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -rawcsv
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Print results in CSV format</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Print results in a comma-separated value (CSV) format which is easy
+to parse for plotting or importing into a spreadsheet or database.
+The values reported are <strong>threads</strong>, <strong>iterations</strong>,
+<strong>user_time</strong>, and <strong>elapsed_time</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -stepthreads <i>step</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>execute a per-thread benchmark ramp</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"> Execute a per-thread benchmark ramp, incrementing the number of
+threads at each step by the specified value. The maximum number of
+threads is taken from the standard <tt>OMP_NUM_THREADS</tt>
+environment variable.</font></td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+</td></tr></table>
diff --git a/www/benchmarks.html b/www/benchmarks.html
new file mode 100644
index 0000000..21e58b6
--- /dev/null
+++ b/www/benchmarks.html
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick vs ImageMagick Benchmarks</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-vs-imagemagick-benchmarks">
+<h1 class="title">GraphicsMagick vs ImageMagick Benchmarks</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#foreword" id="id1">Foreword</a></li>
+<li><a class="reference internal" href="#strategy" id="id2">Strategy</a></li>
+<li><a class="reference internal" href="#the-benchmark" id="id3">The Benchmark</a></li>
+</ul>
+</div>
+<div class="section" id="foreword">
+<h1><a class="toc-backref" href="#id1">Foreword</a></h1>
+<p>This page used to document benchmark results which compared
+GraphicsMagick 1.3.8 performance to ImageMagick 6.5.8-10 performance.
+We found that GraphicsMagick was usually considerably faster at
+executing image processing operations from the command line than
+ImageMagick 6.5.8-10 was. One ImageMagick algorithm ran as much as 770
+times slower. GraphicsMagick clearly ran much more efficiently under
+Microsoft Windows.</p>
+<p>We now find that a simple head to head performance comparison between
+GraphicsMagick and recent ImageMagick is no longer possible because
+ImageMagick has changed the meanings of the existing arguments. In
+particular, we discovered that ImageMagick filter arguments producing
+convolution matrices are now producing lower-order convolution
+matrices representing perhaps an order of magnitude less work given
+the same arguments. The resulting images are visually substantially
+less filtered. Using the same command-line filter arguments causes
+GraphicsMagick to appear slower when it is actually doing far more
+work than ImageMagick.</p>
+<p>Due to it not being feasable to do a head to head performance
+measurement between GraphicsMagick and ImageMagick, we have decided to
+not post results at the moment. However, the strategy and a simple
+benchmark driver script are still provided for those who want to do
+their own performance comparisons between GraphicsMagick and
+ImageMagick.</p>
+</div>
+<div class="section" id="strategy">
+<h1><a class="toc-backref" href="#id2">Strategy</a></h1>
+<p>The benchmark focuses on the ability to process many medium sized
+HD-resolution (1920x1080 pixels) images. In order to prevent disk I/O
+from being a factor, we use a small input image and tile it to create
+a larger input image via the &quot;tile:&quot; coder. The processed image is
+sent to the &quot;null:&quot; coder so that file writes to a slow disk are also
+not a factor. Static executables are used and executed via full paths
+in order to minimize variability from the execution environment. In
+order to obtain accurate and useful timing, we use the bash shell to
+execute the command 40 times and see how long it takes. This is a very
+simple benchmark approach which is quite representative of the
+performance that the typical user observes.</p>
+<p>This new benchmark reveals the following performance criteria:</p>
+<blockquote>
+<ul class="simple">
+<li>Basic execution overhead of the software.</li>
+<li>Image processing algorithmic efficiency.</li>
+<li>Efficacy of OpenMP enhancements.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="the-benchmark">
+<h1><a class="toc-backref" href="#id3">The Benchmark</a></h1>
+<p>The benchmark is quite simple. It reads a list of commands to execute
+from a file named &quot;commands.txt&quot; and times how long it takes to
+execute each command 40 times using GraphicsMagick and ImageMagick.</p>
+<p>Here is the simple benchmark script:</p>
+<pre class="literal-block">
+#!/usr/bin/env bash
+#
+# Measure the performance between two 'convert' commands by
+# executing a subcommand through many iterations and seeing
+# the total time that it takes.
+#
+# Written by Bob Friesenhahn, October 2008
+#
+
+# GraphicsMagick
+convert1='/usr/local/bin/gm convert'
+#convert1='/c/Program\ Files/GraphicsMagick-1.3.8-Q16/gm.exe convert'
+
+# ImageMagick
+convert2='/usr/local/bin/convert'
+#convert2='/c/Program\ Files/ImageMagick-6.5.9-Q16/convert.exe'
+
+# Input file specification
+input_image='-size 1920x1080 tile:model.pnm'
+
+# Ouput file specification
+output_image=&quot;null:&quot;
+
+# Should not need to change any of the rest
+typeset -i iterations=40
+echo &quot;Convert-1: ${convert1}&quot;
+echo &quot;Version: `eval &quot;${convert1}&quot; -version | head -1`&quot;
+echo &quot;Convert-2: ${convert2}&quot;
+echo &quot;Version: `eval &quot;${convert2}&quot; -version | head -1`&quot;
+echo &quot;Date: `date`&quot;
+echo &quot;Host: `uname -n`&quot;
+echo &quot;OS: `uname -s`&quot;
+echo &quot;Release: `uname -r`&quot;
+echo &quot;Arch: `uname -p`&quot;
+echo &quot;Input File: ${input_image}&quot;
+echo &quot;Output File: ${output_image}&quot;
+echo &quot;Threads: ${OMP_NUM_THREADS:-1}&quot;
+echo &quot;Iterations: ${iterations}&quot;
+echo &quot;========================================================================================&quot;
+echo
+typeset -i count=0 i=0
+cat commands.txt | while read subcommand
+do
+ echo ${subcommand}
+
+ command1=&quot;${convert1} ${input_image} ${subcommand} ${output_image}&quot;
+ i=0
+ count=$iterations
+ time while ((i &lt; count))
+ do
+ eval &quot;${command1}&quot;
+ let i=i+1
+ done
+ sleep 1
+
+ command2=&quot;${convert2} ${input_image} ${subcommand} ${output_image}&quot;
+ i=0
+ count=$iterations
+ time while ((i &lt; count))
+ do
+ eval &quot;${command2}&quot;
+ let i=i+1
+ done
+
+ echo
+ sleep 1
+done 2&gt;&amp;1
+</pre>
+<hr class="docutils" />
+<div class="line-block">
+<div class="line">Copyright (C) 2008 - 2017 GraphicsMagick Group</div>
+</div>
+<p>This program is covered by multiple licenses, which are described in
+Copyright.txt. You should have received a copy of Copyright.txt with this
+package; otherwise see <a class="reference external" href="http://www.graphicsmagick.org/Copyright.html">http://www.graphicsmagick.org/Copyright.html</a>.</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/benchmarks.rst b/www/benchmarks.rst
new file mode 100644
index 0000000..727c295
--- /dev/null
+++ b/www/benchmarks.rst
@@ -0,0 +1,149 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=============================================================
+GraphicsMagick vs ImageMagick Benchmarks
+=============================================================
+
+.. contents::
+ :local:
+
+Foreword
+=========
+
+This page used to document benchmark results which compared
+GraphicsMagick 1.3.8 performance to ImageMagick 6.5.8-10 performance.
+We found that GraphicsMagick was usually considerably faster at
+executing image processing operations from the command line than
+ImageMagick 6.5.8-10 was. One ImageMagick algorithm ran as much as 770
+times slower. GraphicsMagick clearly ran much more efficiently under
+Microsoft Windows.
+
+We now find that a simple head to head performance comparison between
+GraphicsMagick and recent ImageMagick is no longer possible because
+ImageMagick has changed the meanings of the existing arguments. In
+particular, we discovered that ImageMagick filter arguments producing
+convolution matrices are now producing lower-order convolution
+matrices representing perhaps an order of magnitude less work given
+the same arguments. The resulting images are visually substantially
+less filtered. Using the same command-line filter arguments causes
+GraphicsMagick to appear slower when it is actually doing far more
+work than ImageMagick.
+
+Due to it not being feasable to do a head to head performance
+measurement between GraphicsMagick and ImageMagick, we have decided to
+not post results at the moment. However, the strategy and a simple
+benchmark driver script are still provided for those who want to do
+their own performance comparisons between GraphicsMagick and
+ImageMagick.
+
+Strategy
+========
+
+The benchmark focuses on the ability to process many medium sized
+HD-resolution (1920x1080 pixels) images. In order to prevent disk I/O
+from being a factor, we use a small input image and tile it to create
+a larger input image via the "tile:" coder. The processed image is
+sent to the "null:" coder so that file writes to a slow disk are also
+not a factor. Static executables are used and executed via full paths
+in order to minimize variability from the execution environment. In
+order to obtain accurate and useful timing, we use the bash shell to
+execute the command 40 times and see how long it takes. This is a very
+simple benchmark approach which is quite representative of the
+performance that the typical user observes.
+
+This new benchmark reveals the following performance criteria:
+
+ * Basic execution overhead of the software.
+
+ * Image processing algorithmic efficiency.
+
+ * Efficacy of OpenMP enhancements.
+
+The Benchmark
+=============
+
+The benchmark is quite simple. It reads a list of commands to execute
+from a file named "commands.txt" and times how long it takes to
+execute each command 40 times using GraphicsMagick and ImageMagick.
+
+Here is the simple benchmark script::
+
+ #!/usr/bin/env bash
+ #
+ # Measure the performance between two 'convert' commands by
+ # executing a subcommand through many iterations and seeing
+ # the total time that it takes.
+ #
+ # Written by Bob Friesenhahn, October 2008
+ #
+
+ # GraphicsMagick
+ convert1='/usr/local/bin/gm convert'
+ #convert1='/c/Program\ Files/GraphicsMagick-1.3.8-Q16/gm.exe convert'
+
+ # ImageMagick
+ convert2='/usr/local/bin/convert'
+ #convert2='/c/Program\ Files/ImageMagick-6.5.9-Q16/convert.exe'
+
+ # Input file specification
+ input_image='-size 1920x1080 tile:model.pnm'
+
+ # Ouput file specification
+ output_image="null:"
+
+ # Should not need to change any of the rest
+ typeset -i iterations=40
+ echo "Convert-1: ${convert1}"
+ echo "Version: `eval "${convert1}" -version | head -1`"
+ echo "Convert-2: ${convert2}"
+ echo "Version: `eval "${convert2}" -version | head -1`"
+ echo "Date: `date`"
+ echo "Host: `uname -n`"
+ echo "OS: `uname -s`"
+ echo "Release: `uname -r`"
+ echo "Arch: `uname -p`"
+ echo "Input File: ${input_image}"
+ echo "Output File: ${output_image}"
+ echo "Threads: ${OMP_NUM_THREADS:-1}"
+ echo "Iterations: ${iterations}"
+ echo "========================================================================================"
+ echo
+ typeset -i count=0 i=0
+ cat commands.txt | while read subcommand
+ do
+ echo ${subcommand}
+
+ command1="${convert1} ${input_image} ${subcommand} ${output_image}"
+ i=0
+ count=$iterations
+ time while ((i < count))
+ do
+ eval "${command1}"
+ let i=i+1
+ done
+ sleep 1
+
+ command2="${convert2} ${input_image} ${subcommand} ${output_image}"
+ i=0
+ count=$iterations
+ time while ((i < count))
+ do
+ eval "${command2}"
+ let i=i+1
+ done
+
+ echo
+ sleep 1
+ done 2>&1
+
+
+--------------------------------------------------------------------------
+
+| Copyright (C) 2008 - 2017 GraphicsMagick Group
+
+This program is covered by multiple licenses, which are described in
+Copyright.txt. You should have received a copy of Copyright.txt with this
+package; otherwise see http://www.graphicsmagick.org/Copyright.html.
+
diff --git a/www/bugs.html b/www/bugs.html
new file mode 100644
index 0000000..0f88f39
--- /dev/null
+++ b/www/bugs.html
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Bugs</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-bugs">
+<h1 class="title">GraphicsMagick Bugs</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The following bugs are known to exist in GraphicsMagick. Please report
+any additional bugs to the GraphicsMagick <a class="reference external" href="http://sourceforge.net/tracker/?group_id=73485">bug tracker</a> at SourceForge.</p>
+<blockquote>
+<ul class="simple">
+<li>BMP reader is not working for some obscure low-color packed files.</li>
+<li>DPX reader/writer does not properly handle subformats where row
+samples spill over the storage word boundary. This means that
+single-channel/grayscale 10-bit DPX files will only work for widths
+evenly divisible by three. (SF 1533184)</li>
+<li>PSD reader is not working for some files. Can fix by extracting the
+already rendered image from the PSD file rather than the layers.</li>
+<li>Scitex reader is not working for some files.</li>
+<li>SVG writer works only if you are particularly luckly.</li>
+<li>SVG reader mishandles basic units and many other syntax elements (SF
+1231547, 1298606).</li>
+<li>BlobToImage ignores the value of the 'magick' parameter. I don't know
+how to fix this due to how things work. (SF 1839932).</li>
+<li>Text annotation options do not work perfectly (SF 1539050, 1539052, 1539059)</li>
+</ul>
+</blockquote>
+</div>
+</body>
+</html>
diff --git a/www/bugs.rst b/www/bugs.rst
new file mode 100644
index 0000000..726c083
--- /dev/null
+++ b/www/bugs.rst
@@ -0,0 +1,33 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+===================
+GraphicsMagick Bugs
+===================
+
+The following bugs are known to exist in GraphicsMagick. Please report
+any additional bugs to the GraphicsMagick `bug tracker
+<http://sourceforge.net/tracker/?group_id=73485>`_ at SourceForge.
+
+ * BMP reader is not working for some obscure low-color packed files.
+
+ * DPX reader/writer does not properly handle subformats where row
+ samples spill over the storage word boundary. This means that
+ single-channel/grayscale 10-bit DPX files will only work for widths
+ evenly divisible by three. (SF 1533184)
+
+ * PSD reader is not working for some files. Can fix by extracting the
+ already rendered image from the PSD file rather than the layers.
+
+ * Scitex reader is not working for some files.
+
+ * SVG writer works only if you are particularly luckly.
+
+ * SVG reader mishandles basic units and many other syntax elements (SF
+ 1231547, 1298606).
+
+ * BlobToImage ignores the value of the 'magick' parameter. I don't know
+ how to fix this due to how things work. (SF 1839932).
+
+ * Text annotation options do not work perfectly (SF 1539050, 1539052, 1539059)
diff --git a/www/color.html b/www/color.html
new file mode 100644
index 0000000..4c54d26
--- /dev/null
+++ b/www/color.html
@@ -0,0 +1,335 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>GraphicsMagick Color Selections</title>
+ <meta name="description" content="GraphicsMagick is a robust collection of tools
+and libraries to read, write, and manipulate an image in any of the more
+popular image formats including GIF, JPEG, PNG, PDF, and Photo CD. With
+GraphicsMagick you can create GIFs dynamically making it suitable for Web
+applications. You can also resize, rotate, sharpen, color reduce, or add
+special effects to an image and save your completed work in the same or
+differing image format.">
+ <meta name="keywords" content="GraphicsMagick, Image Magick, Image
+Magic, PerlMagick, Perl Magick, Perl Magic, CineMagick, PixelMagick,
+Pixel Magic, WebMagick, Web Magic, visualization, image processing,
+software development, simulation, image, software, AniMagick, Animagic,
+Magick++">
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+ <style>
+ <!--
+ body {font-family: sans-serif;}
+ table.named-colors th, table.named-colors td { padding : .5ex; }
+ table.named-colors th { background-color : #E0E0E0; }
+ table.named-colors td.dark { text-align : center; color : white; }
+ table.named-colors td.light { text-align : center; color : black; }
+ -->
+ </style>
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="https://sourceforge.net/tracker/?group_id=73485" target="top_">Bugs</a></li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+
+<div class="document" id="graphicsmagick-programming-interfaces">
+<hr>
+<p>Here are some example color selections to choose from or define
+your own. GraphicsMagick understands color names or hex values (.e.g.
+white or #ffffff).
+</p>
+<table class="named-colors">
+<colgroup>
+<col width="20%" />
+<col width="40%" />
+<col width="20%" />
+<col width="20%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Name</th>
+<th class="head">Color</th>
+<th class="head">RGB</th>
+<th class="head">Hex</th>
+</tr>
+</thead>
+<tbody valign="top">
+
+<tr><td>aliceblue</td><td class="light" bgcolor="#f0f8ff">aliceblue</td><td>240, 248, 255</td><td>#f0f8ff</td></tr>
+<tr><td>antiquewhite</td><td class="light" bgcolor="#faebd7">antiquewhite</td><td>250, 235, 215</td><td>#faebd7</td></tr>
+<tr><td>aqua</td><td class="light" bgcolor="#00ffff">aqua</td><td>0, 255, 255</td><td>#00ffff</td></tr>
+<tr><td>aquamarine</td><td class="light" bgcolor="#7fffd4">aquamarine</td><td>127, 255, 212</td><td>#7fffd4</td></tr>
+<tr><td>azure</td><td class="light" bgcolor="#f0ffff">azure</td><td>240, 255, 255</td><td>#f0ffff</td></tr>
+<tr><td>beige</td><td class="light" bgcolor="#f5f5dc">beige</td><td>245, 245, 220</td><td>#f5f5dc</td></tr>
+<tr><td>bisque</td><td class="light" bgcolor="#ffe4c4">bisque</td><td>255, 228, 196</td><td>#ffe4c4</td></tr>
+<tr><td>black</td><td class="dark" bgcolor="#000000">black</td><td>0, 0, 0</td><td>#000000</td></tr>
+<tr><td>blanchedalmond</td><td class="light" bgcolor="#ffebcd">blanchedalmond</td><td>255, 235, 205</td><td>#ffebcd</td></tr>
+<tr><td>blue</td><td class="dark" bgcolor="#0000ff">blue</td><td>0, 0, 255</td><td>#0000ff</td></tr>
+<tr><td>blueviolet</td><td class="light" bgcolor="#8a2be2">blueviolet</td><td>138, 43, 226</td><td>#8a2be2</td></tr>
+<tr><td>brown</td><td class="dark" bgcolor="#a52a2a">brown</td><td>165, 42, 42</td><td>#a52a2a</td></tr>
+<tr><td>burlywood</td><td class="light" bgcolor="#deb887">burlywood</td><td>222, 184, 135</td><td>#deb887</td></tr>
+<tr><td>cadetblue</td><td class="light" bgcolor="#5f9ea0">cadetblue</td><td>95, 158, 160</td><td>#5f9ea0</td></tr>
+<tr><td>chartreuse</td><td class="light" bgcolor="#7fff00">chartreuse</td><td>127, 255, 0</td><td>#7fff00</td></tr>
+<tr><td>chocolate</td><td class="light" bgcolor="#d2691e">chocolate</td><td>210, 105, 30</td><td>#d2691e</td></tr>
+<tr><td>coral</td><td class="light" bgcolor="#ff7f50">coral</td><td>255, 127, 80</td><td>#ff7f50</td></tr>
+<tr><td>cornflowerblue</td><td class="light" bgcolor="#6495ed">cornflowerblue</td><td>100, 149, 237</td><td>#6495ed</td></tr>
+<tr><td>cornsilk</td><td class="light" bgcolor="#fff8dc">cornsilk</td><td>255, 248, 220</td><td>#fff8dc</td></tr>
+<tr><td>crimson</td><td class="dark" bgcolor="#dc143c">crimson</td><td>220, 20, 60</td><td>#dc143c</td></tr>
+<tr><td>cyan</td><td class="light" bgcolor="#00ffff">cyan</td><td>0, 255, 255</td><td>#00ffff</td></tr>
+<tr><td>darkblue</td><td class="dark" bgcolor="#00008b">darkblue</td><td>0, 0, 139</td><td>#00008b</td></tr>
+<tr><td>darkcyan</td><td class="dark" bgcolor="#008b8b">darkcyan</td><td>0, 139, 139</td><td>#008b8b</td></tr>
+<tr><td>darkgoldenrod</td><td class="light" bgcolor="#b8860b">darkgoldenrod</td><td>184, 134, 11</td><td>#b8860b</td></tr>
+<tr><td>darkgray</td><td class="light" bgcolor="#a9a9a9">darkgray</td><td>169, 169, 169</td><td>#a9a9a9</td></tr>
+<tr><td>darkgreen</td><td class="dark" bgcolor="#006400">darkgreen</td><td>0, 100, 0</td><td>#006400</td></tr>
+<tr><td>darkgrey</td><td class="light" bgcolor="#a9a9a9">darkgrey</td><td>169, 169, 169</td><td>#a9a9a9</td></tr>
+<tr><td>darkkhaki</td><td class="light" bgcolor="#bdb76b">darkkhaki</td><td>189, 183, 107</td><td>#bdb76b</td></tr>
+<tr><td>darkmagenta</td><td class="dark" bgcolor="#8b008b">darkmagenta</td><td>139, 0, 139</td><td>#8b008b</td></tr>
+<tr><td>darkolivegreen</td><td class="dark" bgcolor="#556b2f">darkolivegreen</td><td>85, 107, 47</td><td>#556b2f</td></tr>
+<tr><td>darkorange</td><td class="light" bgcolor="#ff8c00">darkorange</td><td>255, 140, 0</td><td>#ff8c00</td></tr>
+<tr><td>darkorchid</td><td class="light" bgcolor="#9932cc">darkorchid</td><td>153, 50, 204</td><td>#9932cc</td></tr>
+<tr><td>darkred</td><td class="dark" bgcolor="#8b0000">darkred</td><td>139, 0, 0</td><td>#8b0000</td></tr>
+<tr><td>darksalmon</td><td class="light" bgcolor="#e9967a">darksalmon</td><td>233, 150, 122</td><td>#e9967a</td></tr>
+<tr><td>darkseagreen</td><td class="light" bgcolor="#8fbc8f">darkseagreen</td><td>143, 188, 143</td><td>#8fbc8f</td></tr>
+<tr><td>darkslateblue</td><td class="dark" bgcolor="#483d8b">darkslateblue</td><td>72, 61, 139</td><td>#483d8b</td></tr>
+<tr><td>darkslategray</td><td class="dark" bgcolor="#2f4f4f">darkslategray</td><td>47, 79, 79</td><td>#2f4f4f</td></tr>
+<tr><td>darkslategrey</td><td class="dark" bgcolor="#2f4f4f">darkslategrey</td><td>47, 79, 79</td><td>#2f4f4f</td></tr>
+<tr><td>darkturquoise</td><td class="light" bgcolor="#00ced1">darkturquoise</td><td>0, 206, 209</td><td>#00ced1</td></tr>
+<tr><td>darkviolet</td><td class="light" bgcolor="#9400d3">darkviolet</td><td>148, 0, 211</td><td>#9400d3</td></tr>
+<tr><td>deeppink</td><td class="light" bgcolor="#ff1493">deeppink</td><td>255, 20, 147</td><td>#ff1493</td></tr>
+<tr><td>deepskyblue</td><td class="light" bgcolor="#00bfff">deepskyblue</td><td>0, 191, 255</td><td>#00bfff</td></tr>
+<tr><td>dimgray</td><td class="dark" bgcolor="#696969">dimgray</td><td>105, 105, 105</td><td>#696969</td></tr>
+<tr><td>dimgrey</td><td class="dark" bgcolor="#696969">dimgrey</td><td>105, 105, 105</td><td>#696969</td></tr>
+<tr><td>dodgerblue</td><td class="light" bgcolor="#1e90ff">dodgerblue</td><td>30, 144, 255</td><td>#1e90ff</td></tr>
+<tr><td>firebrick</td><td class="dark" bgcolor="#b22222">firebrick</td><td>178, 34, 34</td><td>#b22222</td></tr>
+<tr><td>floralwhite</td><td class="light" bgcolor="#fffaf0">floralwhite</td><td>255, 250, 240</td><td>#fffaf0</td></tr>
+<tr><td>forestgreen</td><td class="dark" bgcolor="#228b22">forestgreen</td><td>34, 139, 34</td><td>#228b22</td></tr>
+<tr><td>fractal</td><td class="light" bgcolor="#808080">fractal</td><td>128, 128, 128</td><td>#808080</td></tr>
+<tr><td>fuchsia</td><td class="light" bgcolor="#ff00ff">fuchsia</td><td>255, 0, 255</td><td>#ff00ff</td></tr>
+<tr><td>gainsboro</td><td class="light" bgcolor="#dcdcdc">gainsboro</td><td>220, 220, 220</td><td>#dcdcdc</td></tr>
+<tr><td>ghostwhite</td><td class="light" bgcolor="#f8f8ff">ghostwhite</td><td>248, 248, 255</td><td>#f8f8ff</td></tr>
+<tr><td>gold</td><td class="light" bgcolor="#ffd700">gold</td><td>255, 215, 0</td><td>#ffd700</td></tr>
+<tr><td>goldenrod</td><td class="light" bgcolor="#daa520">goldenrod</td><td>218, 165, 32</td><td>#daa520</td></tr>
+<tr><td>gray0</td><td class="dark" bgcolor="#000000">gray0</td><td>0, 0, 0</td><td>#000000</td></tr>
+<tr><td>gray1</td><td class="dark" bgcolor="#030303">gray1</td><td>3, 3, 3</td><td>#030303</td></tr>
+<tr><td>gray2</td><td class="dark" bgcolor="#050505">gray2</td><td>5, 5, 5</td><td>#050505</td></tr>
+<tr><td>gray3</td><td class="dark" bgcolor="#080808">gray3</td><td>8, 8, 8</td><td>#080808</td></tr>
+<tr><td>gray4</td><td class="dark" bgcolor="#0a0a0a">gray4</td><td>10, 10, 10</td><td>#0a0a0a</td></tr>
+<tr><td>gray5</td><td class="dark" bgcolor="#0d0d0d">gray5</td><td>13, 13, 13</td><td>#0d0d0d</td></tr>
+<tr><td>gray6</td><td class="dark" bgcolor="#0f0f0f">gray6</td><td>15, 15, 15</td><td>#0f0f0f</td></tr>
+<tr><td>gray7</td><td class="dark" bgcolor="#121212">gray7</td><td>18, 18, 18</td><td>#121212</td></tr>
+<tr><td>gray8</td><td class="dark" bgcolor="#141414">gray8</td><td>20, 20, 20</td><td>#141414</td></tr>
+<tr><td>gray9</td><td class="dark" bgcolor="#171717">gray9</td><td>23, 23, 23</td><td>#171717</td></tr>
+<tr><td>gray10</td><td class="dark" bgcolor="#1a1a1a">gray10</td><td>26, 26, 26</td><td>#1a1a1a</td></tr>
+<tr><td>gray11</td><td class="dark" bgcolor="#1c1c1c">gray11</td><td>28, 28, 28</td><td>#1c1c1c</td></tr>
+<tr><td>gray12</td><td class="dark" bgcolor="#1f1f1f">gray12</td><td>31, 31, 31</td><td>#1f1f1f</td></tr>
+<tr><td>gray13</td><td class="dark" bgcolor="#212121">gray13</td><td>33, 33, 33</td><td>#212121</td></tr>
+<tr><td>gray14</td><td class="dark" bgcolor="#242424">gray14</td><td>36, 36, 36</td><td>#242424</td></tr>
+<tr><td>gray15</td><td class="dark" bgcolor="#262626">gray15</td><td>38, 38, 38</td><td>#262626</td></tr>
+<tr><td>gray16</td><td class="dark" bgcolor="#292929">gray16</td><td>41, 41, 41</td><td>#292929</td></tr>
+<tr><td>gray17</td><td class="dark" bgcolor="#2b2b2b">gray17</td><td>43, 43, 43</td><td>#2b2b2b</td></tr>
+<tr><td>gray18</td><td class="dark" bgcolor="#2e2e2e">gray18</td><td>46, 46, 46</td><td>#2e2e2e</td></tr>
+<tr><td>gray19</td><td class="dark" bgcolor="#303030">gray19</td><td>48, 48, 48</td><td>#303030</td></tr>
+<tr><td>gray20</td><td class="dark" bgcolor="#333333">gray20</td><td>51, 51, 51</td><td>#333333</td></tr>
+<tr><td>gray21</td><td class="dark" bgcolor="#363636">gray21</td><td>54, 54, 54</td><td>#363636</td></tr>
+<tr><td>gray22</td><td class="dark" bgcolor="#383838">gray22</td><td>56, 56, 56</td><td>#383838</td></tr>
+<tr><td>gray23</td><td class="dark" bgcolor="#3b3b3b">gray23</td><td>59, 59, 59</td><td>#3b3b3b</td></tr>
+<tr><td>gray24</td><td class="dark" bgcolor="#3d3d3d">gray24</td><td>61, 61, 61</td><td>#3d3d3d</td></tr>
+<tr><td>gray25</td><td class="dark" bgcolor="#404040">gray25</td><td>64, 64, 64</td><td>#404040</td></tr>
+<tr><td>gray26</td><td class="dark" bgcolor="#424242">gray26</td><td>66, 66, 66</td><td>#424242</td></tr>
+<tr><td>gray27</td><td class="dark" bgcolor="#454545">gray27</td><td>69, 69, 69</td><td>#454545</td></tr>
+<tr><td>gray28</td><td class="dark" bgcolor="#474747">gray28</td><td>71, 71, 71</td><td>#474747</td></tr>
+<tr><td>gray29</td><td class="dark" bgcolor="#4a4a4a">gray29</td><td>74, 74, 74</td><td>#4a4a4a</td></tr>
+<tr><td>gray30</td><td class="dark" bgcolor="#4d4d4d">gray30</td><td>77, 77, 77</td><td>#4d4d4d</td></tr>
+<tr><td>gray31</td><td class="dark" bgcolor="#4f4f4f">gray31</td><td>79, 79, 79</td><td>#4f4f4f</td></tr>
+<tr><td>gray32</td><td class="dark" bgcolor="#525252">gray32</td><td>82, 82, 82</td><td>#525252</td></tr>
+<tr><td>gray33</td><td class="dark" bgcolor="#545454">gray33</td><td>84, 84, 84</td><td>#545454</td></tr>
+<tr><td>gray34</td><td class="dark" bgcolor="#575757">gray34</td><td>87, 87, 87</td><td>#575757</td></tr>
+<tr><td>gray35</td><td class="dark" bgcolor="#595959">gray35</td><td>89, 89, 89</td><td>#595959</td></tr>
+<tr><td>gray36</td><td class="dark" bgcolor="#5c5c5c">gray36</td><td>92, 92, 92</td><td>#5c5c5c</td></tr>
+<tr><td>gray37</td><td class="dark" bgcolor="#5e5e5e">gray37</td><td>94, 94, 94</td><td>#5e5e5e</td></tr>
+<tr><td>gray38</td><td class="dark" bgcolor="#616161">gray38</td><td>97, 97, 97</td><td>#616161</td></tr>
+<tr><td>gray39</td><td class="dark" bgcolor="#636363">gray39</td><td>99, 99, 99</td><td>#636363</td></tr>
+<tr><td>gray40</td><td class="dark" bgcolor="#666666">gray40</td><td>102, 102, 102</td><td>#666666</td></tr>
+<tr><td>gray41</td><td class="dark" bgcolor="#696969">gray41</td><td>105, 105, 105</td><td>#696969</td></tr>
+<tr><td>gray42</td><td class="light" bgcolor="#6b6b6b">gray42</td><td>107, 107, 107</td><td>#6b6b6b</td></tr>
+<tr><td>gray43</td><td class="light" bgcolor="#6e6e6e">gray43</td><td>110, 110, 110</td><td>#6e6e6e</td></tr>
+<tr><td>gray44</td><td class="light" bgcolor="#707070">gray44</td><td>112, 112, 112</td><td>#707070</td></tr>
+<tr><td>gray45</td><td class="light" bgcolor="#737373">gray45</td><td>115, 115, 115</td><td>#737373</td></tr>
+<tr><td>gray46</td><td class="light" bgcolor="#757575">gray46</td><td>117, 117, 117</td><td>#757575</td></tr>
+<tr><td>gray47</td><td class="light" bgcolor="#787878">gray47</td><td>120, 120, 120</td><td>#787878</td></tr>
+<tr><td>gray48</td><td class="light" bgcolor="#7a7a7a">gray48</td><td>122, 122, 122</td><td>#7a7a7a</td></tr>
+<tr><td>gray49</td><td class="light" bgcolor="#7d7d7d">gray49</td><td>125, 125, 125</td><td>#7d7d7d</td></tr>
+<tr><td>gray50</td><td class="light" bgcolor="#7f7f7f">gray50</td><td>127, 127, 127</td><td>#7f7f7f</td></tr>
+<tr><td>gray51</td><td class="light" bgcolor="#828282">gray51</td><td>130, 130, 130</td><td>#828282</td></tr>
+<tr><td>gray52</td><td class="light" bgcolor="#858585">gray52</td><td>133, 133, 133</td><td>#858585</td></tr>
+<tr><td>gray53</td><td class="light" bgcolor="#878787">gray53</td><td>135, 135, 135</td><td>#878787</td></tr>
+<tr><td>gray54</td><td class="light" bgcolor="#8a8a8a">gray54</td><td>138, 138, 138</td><td>#8a8a8a</td></tr>
+<tr><td>gray55</td><td class="light" bgcolor="#8c8c8c">gray55</td><td>140, 140, 140</td><td>#8c8c8c</td></tr>
+<tr><td>gray56</td><td class="light" bgcolor="#8f8f8f">gray56</td><td>143, 143, 143</td><td>#8f8f8f</td></tr>
+<tr><td>gray57</td><td class="light" bgcolor="#919191">gray57</td><td>145, 145, 145</td><td>#919191</td></tr>
+<tr><td>gray58</td><td class="light" bgcolor="#949494">gray58</td><td>148, 148, 148</td><td>#949494</td></tr>
+<tr><td>gray59</td><td class="light" bgcolor="#969696">gray59</td><td>150, 150, 150</td><td>#969696</td></tr>
+<tr><td>gray60</td><td class="light" bgcolor="#999999">gray60</td><td>153, 153, 153</td><td>#999999</td></tr>
+<tr><td>gray61</td><td class="light" bgcolor="#9c9c9c">gray61</td><td>156, 156, 156</td><td>#9c9c9c</td></tr>
+<tr><td>gray62</td><td class="light" bgcolor="#9e9e9e">gray62</td><td>158, 158, 158</td><td>#9e9e9e</td></tr>
+<tr><td>gray63</td><td class="light" bgcolor="#a1a1a1">gray63</td><td>161, 161, 161</td><td>#a1a1a1</td></tr>
+<tr><td>gray64</td><td class="light" bgcolor="#a3a3a3">gray64</td><td>163, 163, 163</td><td>#a3a3a3</td></tr>
+<tr><td>gray65</td><td class="light" bgcolor="#a6a6a6">gray65</td><td>166, 166, 166</td><td>#a6a6a6</td></tr>
+<tr><td>gray66</td><td class="light" bgcolor="#a8a8a8">gray66</td><td>168, 168, 168</td><td>#a8a8a8</td></tr>
+<tr><td>gray67</td><td class="light" bgcolor="#ababab">gray67</td><td>171, 171, 171</td><td>#ababab</td></tr>
+<tr><td>gray68</td><td class="light" bgcolor="#adadad">gray68</td><td>173, 173, 173</td><td>#adadad</td></tr>
+<tr><td>gray69</td><td class="light" bgcolor="#b0b0b0">gray69</td><td>176, 176, 176</td><td>#b0b0b0</td></tr>
+<tr><td>gray70</td><td class="light" bgcolor="#b3b3b3">gray70</td><td>179, 179, 179</td><td>#b3b3b3</td></tr>
+<tr><td>gray71</td><td class="light" bgcolor="#b5b5b5">gray71</td><td>181, 181, 181</td><td>#b5b5b5</td></tr>
+<tr><td>gray72</td><td class="light" bgcolor="#b8b8b8">gray72</td><td>184, 184, 184</td><td>#b8b8b8</td></tr>
+<tr><td>gray73</td><td class="light" bgcolor="#bababa">gray73</td><td>186, 186, 186</td><td>#bababa</td></tr>
+<tr><td>gray74</td><td class="light" bgcolor="#bdbdbd">gray74</td><td>189, 189, 189</td><td>#bdbdbd</td></tr>
+<tr><td>gray75</td><td class="light" bgcolor="#bfbfbf">gray75</td><td>191, 191, 191</td><td>#bfbfbf</td></tr>
+<tr><td>gray76</td><td class="light" bgcolor="#c2c2c2">gray76</td><td>194, 194, 194</td><td>#c2c2c2</td></tr>
+<tr><td>gray77</td><td class="light" bgcolor="#c4c4c4">gray77</td><td>196, 196, 196</td><td>#c4c4c4</td></tr>
+<tr><td>gray78</td><td class="light" bgcolor="#c7c7c7">gray78</td><td>199, 199, 199</td><td>#c7c7c7</td></tr>
+<tr><td>gray79</td><td class="light" bgcolor="#c9c9c9">gray79</td><td>201, 201, 201</td><td>#c9c9c9</td></tr>
+<tr><td>gray80</td><td class="light" bgcolor="#cccccc">gray80</td><td>204, 204, 204</td><td>#cccccc</td></tr>
+<tr><td>gray81</td><td class="light" bgcolor="#cfcfcf">gray81</td><td>207, 207, 207</td><td>#cfcfcf</td></tr>
+<tr><td>gray82</td><td class="light" bgcolor="#d1d1d1">gray82</td><td>209, 209, 209</td><td>#d1d1d1</td></tr>
+<tr><td>gray83</td><td class="light" bgcolor="#d4d4d4">gray83</td><td>212, 212, 212</td><td>#d4d4d4</td></tr>
+<tr><td>gray84</td><td class="light" bgcolor="#d6d6d6">gray84</td><td>214, 214, 214</td><td>#d6d6d6</td></tr>
+<tr><td>gray85</td><td class="light" bgcolor="#d9d9d9">gray85</td><td>217, 217, 217</td><td>#d9d9d9</td></tr>
+<tr><td>gray86</td><td class="light" bgcolor="#dbdbdb">gray86</td><td>219, 219, 219</td><td>#dbdbdb</td></tr>
+<tr><td>gray87</td><td class="light" bgcolor="#dedede">gray87</td><td>222, 222, 222</td><td>#dedede</td></tr>
+<tr><td>gray88</td><td class="light" bgcolor="#e0e0e0">gray88</td><td>224, 224, 224</td><td>#e0e0e0</td></tr>
+<tr><td>gray89</td><td class="light" bgcolor="#e3e3e3">gray89</td><td>227, 227, 227</td><td>#e3e3e3</td></tr>
+<tr><td>gray90</td><td class="light" bgcolor="#e5e5e5">gray90</td><td>229, 229, 229</td><td>#e5e5e5</td></tr>
+<tr><td>gray91</td><td class="light" bgcolor="#e8e8e8">gray91</td><td>232, 232, 232</td><td>#e8e8e8</td></tr>
+<tr><td>gray92</td><td class="light" bgcolor="#ebebeb">gray92</td><td>235, 235, 235</td><td>#ebebeb</td></tr>
+<tr><td>gray93</td><td class="light" bgcolor="#ededed">gray93</td><td>237, 237, 237</td><td>#ededed</td></tr>
+<tr><td>gray94</td><td class="light" bgcolor="#f0f0f0">gray94</td><td>240, 240, 240</td><td>#f0f0f0</td></tr>
+<tr><td>gray95</td><td class="light" bgcolor="#f2f2f2">gray95</td><td>242, 242, 242</td><td>#f2f2f2</td></tr>
+<tr><td>gray96</td><td class="light" bgcolor="#f5f5f5">gray96</td><td>245, 245, 245</td><td>#f5f5f5</td></tr>
+<tr><td>gray97</td><td class="light" bgcolor="#f7f7f7">gray97</td><td>247, 247, 247</td><td>#f7f7f7</td></tr>
+<tr><td>gray98</td><td class="light" bgcolor="#fafafa">gray98</td><td>250, 250, 250</td><td>#fafafa</td></tr>
+<tr><td>gray99</td><td class="light" bgcolor="#fcfcfc">gray99</td><td>252, 252, 252</td><td>#fcfcfc</td></tr>
+<tr><td>gray100</td><td class="light" bgcolor="#ffffff">gray100</td><td>255, 255, 255</td><td>#ffffff</td></tr>
+<tr><td>gray</td><td class="light" bgcolor="#7e7e7e">gray</td><td>126, 126, 126</td><td>#7e7e7e</td></tr>
+<tr><td>green</td><td class="dark" bgcolor="#008000">green</td><td>0, 128, 0</td><td>#008000</td></tr>
+<tr><td>greenyellow</td><td class="light" bgcolor="#adff2f">greenyellow</td><td>173, 255, 47</td><td>#adff2f</td></tr>
+<tr><td>grey</td><td class="light" bgcolor="#808080">grey</td><td>128, 128, 128</td><td>#808080</td></tr>
+<tr><td>honeydew</td><td class="light" bgcolor="#f0fff0">honeydew</td><td>240, 255, 240</td><td>#f0fff0</td></tr>
+<tr><td>hotpink</td><td class="light" bgcolor="#ff69b4">hotpink</td><td>255, 105, 180</td><td>#ff69b4</td></tr>
+<tr><td>indianred</td><td class="light" bgcolor="#cd5c5c">indianred</td><td>205, 92, 92</td><td>#cd5c5c</td></tr>
+<tr><td>indigo</td><td class="dark" bgcolor="#4b0082">indigo</td><td>75, 0, 130</td><td>#4b0082</td></tr>
+<tr><td>ivory</td><td class="light" bgcolor="#fffff0">ivory</td><td>255, 255, 240</td><td>#fffff0</td></tr>
+<tr><td>khaki</td><td class="light" bgcolor="#f0e68c">khaki</td><td>240, 230, 140</td><td>#f0e68c</td></tr>
+<tr><td>lavender</td><td class="light" bgcolor="#e6e6fa">lavender</td><td>230, 230, 250</td><td>#e6e6fa</td></tr>
+<tr><td>lavenderblush</td><td class="light" bgcolor="#fff0f5">lavenderblush</td><td>255, 240, 245</td><td>#fff0f5</td></tr>
+<tr><td>lawngreen</td><td class="light" bgcolor="#7cfc00">lawngreen</td><td>124, 252, 0</td><td>#7cfc00</td></tr>
+<tr><td>lemonchiffon</td><td class="light" bgcolor="#fffacd">lemonchiffon</td><td>255, 250, 205</td><td>#fffacd</td></tr>
+<tr><td>lightblue</td><td class="light" bgcolor="#add8e6">lightblue</td><td>173, 216, 230</td><td>#add8e6</td></tr>
+<tr><td>lightcoral</td><td class="light" bgcolor="#f08080">lightcoral</td><td>240, 128, 128</td><td>#f08080</td></tr>
+<tr><td>lightcyan</td><td class="light" bgcolor="#e0ffff">lightcyan</td><td>224, 255, 255</td><td>#e0ffff</td></tr>
+<tr><td>lightgoldenrodyellow</td><td class="light" bgcolor="#fafad2">lightgoldenrodyellow</td><td>250, 250, 210</td><td>#fafad2</td></tr>
+<tr><td>lightgray</td><td class="light" bgcolor="#d3d3d3">lightgray</td><td>211, 211, 211</td><td>#d3d3d3</td></tr>
+<tr><td>lightgreen</td><td class="light" bgcolor="#90ee90">lightgreen</td><td>144, 238, 144</td><td>#90ee90</td></tr>
+<tr><td>lightgrey</td><td class="light" bgcolor="#d3d3d3">lightgrey</td><td>211, 211, 211</td><td>#d3d3d3</td></tr>
+<tr><td>lightpink</td><td class="light" bgcolor="#ffb6c1">lightpink</td><td>255, 182, 193</td><td>#ffb6c1</td></tr>
+<tr><td>lightsalmon</td><td class="light" bgcolor="#ffa07a">lightsalmon</td><td>255, 160, 122</td><td>#ffa07a</td></tr>
+<tr><td>lightseagreen</td><td class="light" bgcolor="#20b2aa">lightseagreen</td><td>32, 178, 170</td><td>#20b2aa</td></tr>
+<tr><td>lightskyblue</td><td class="light" bgcolor="#87cefa">lightskyblue</td><td>135, 206, 250</td><td>#87cefa</td></tr>
+<tr><td>lightslategray</td><td class="light" bgcolor="#778899">lightslategray</td><td>119, 136, 153</td><td>#778899</td></tr>
+<tr><td>lightslategrey</td><td class="light" bgcolor="#778899">lightslategrey</td><td>119, 136, 153</td><td>#778899</td></tr>
+<tr><td>lightsteelblue</td><td class="light" bgcolor="#b0c4de">lightsteelblue</td><td>176, 196, 222</td><td>#b0c4de</td></tr>
+<tr><td>lightyellow</td><td class="light" bgcolor="#ffffe0">lightyellow</td><td>255, 255, 224</td><td>#ffffe0</td></tr>
+<tr><td>lime</td><td class="dark" bgcolor="#00ff00">lime</td><td>0, 255, 0</td><td>#00ff00</td></tr>
+<tr><td>limegreen</td><td class="dark" bgcolor="#32cd32">limegreen</td><td>50, 205, 50</td><td>#32cd32</td></tr>
+<tr><td>linen</td><td class="light" bgcolor="#faf0e6">linen</td><td>250, 240, 230</td><td>#faf0e6</td></tr>
+<tr><td>magenta</td><td class="light" bgcolor="#ff00ff">magenta</td><td>255, 0, 255</td><td>#ff00ff</td></tr>
+<tr><td>maroon</td><td class="dark" bgcolor="#800000">maroon</td><td>128, 0, 0</td><td>#800000</td></tr>
+<tr><td>mediumaquamarine</td><td class="light" bgcolor="#66cdaa">mediumaquamarine</td><td>102, 205, 170</td><td>#66cdaa</td></tr>
+<tr><td>mediumblue</td><td class="dark" bgcolor="#0000cd">mediumblue</td><td>0, 0, 205</td><td>#0000cd</td></tr>
+<tr><td>mediumorchid</td><td class="light" bgcolor="#ba55d3">mediumorchid</td><td>186, 85, 211</td><td>#ba55d3</td></tr>
+<tr><td>mediumpurple</td><td class="light" bgcolor="#9370db">mediumpurple</td><td>147, 112, 219</td><td>#9370db</td></tr>
+<tr><td>mediumseagreen</td><td class="light" bgcolor="#3cb371">mediumseagreen</td><td>60, 179, 113</td><td>#3cb371</td></tr>
+<tr><td>mediumslateblue</td><td class="light" bgcolor="#7b68ee">mediumslateblue</td><td>123, 104, 238</td><td>#7b68ee</td></tr>
+<tr><td>mediumspringgreen</td><td class="light" bgcolor="#00fa9a">mediumspringgreen</td><td>0, 250, 154</td><td>#00fa9a</td></tr>
+<tr><td>mediumturquoise</td><td class="light" bgcolor="#48d1cc">mediumturquoise</td><td>72, 209, 204</td><td>#48d1cc</td></tr>
+<tr><td>mediumvioletred</td><td class="light" bgcolor="#c71585">mediumvioletred</td><td>199, 21, 133</td><td>#c71585</td></tr>
+<tr><td>midnightblue</td><td class="dark" bgcolor="#191970">midnightblue</td><td>25, 25, 112</td><td>#191970</td></tr>
+<tr><td>mintcream</td><td class="light" bgcolor="#f5fffa">mintcream</td><td>245, 255, 250</td><td>#f5fffa</td></tr>
+<tr><td>mistyrose</td><td class="light" bgcolor="#ffe4e1">mistyrose</td><td>255, 228, 225</td><td>#ffe4e1</td></tr>
+<tr><td>moccasin</td><td class="light" bgcolor="#ffe4b5">moccasin</td><td>255, 228, 181</td><td>#ffe4b5</td></tr>
+<tr><td>navajowhite</td><td class="light" bgcolor="#ffdead">navajowhite</td><td>255, 222, 173</td><td>#ffdead</td></tr>
+<tr><td>navy</td><td class="dark" bgcolor="#000080">navy</td><td>0, 0, 128</td><td>#000080</td></tr>
+<tr><td>none</td><td class="dark" bgcolor="#000000">none</td><td>0, 0, 0</td><td>#000000</td></tr>
+<tr><td>oldlace</td><td class="light" bgcolor="#fdf5e6">oldlace</td><td>253, 245, 230</td><td>#fdf5e6</td></tr>
+<tr><td>olive</td><td class="dark" bgcolor="#808000">olive</td><td>128, 128, 0</td><td>#808000</td></tr>
+<tr><td>olivedrab</td><td class="dark" bgcolor="#6b8e23">olivedrab</td><td>107, 142, 35</td><td>#6b8e23</td></tr>
+<tr><td>orange</td><td class="light" bgcolor="#ffa500">orange</td><td>255, 165, 0</td><td>#ffa500</td></tr>
+<tr><td>orangered</td><td class="light" bgcolor="#ff4500">orangered</td><td>255, 69, 0</td><td>#ff4500</td></tr>
+<tr><td>orchid</td><td class="light" bgcolor="#da70d6">orchid</td><td>218, 112, 214</td><td>#da70d6</td></tr>
+<tr><td>palegoldenrod</td><td class="light" bgcolor="#eee8aa">palegoldenrod</td><td>238, 232, 170</td><td>#eee8aa</td></tr>
+<tr><td>palegreen</td><td class="light" bgcolor="#98fb98">palegreen</td><td>152, 251, 152</td><td>#98fb98</td></tr>
+<tr><td>paleturquoise</td><td class="light" bgcolor="#afeeee">paleturquoise</td><td>175, 238, 238</td><td>#afeeee</td></tr>
+<tr><td>palevioletred</td><td class="light" bgcolor="#db7093">palevioletred</td><td>219, 112, 147</td><td>#db7093</td></tr>
+<tr><td>papayawhip</td><td class="light" bgcolor="#ffefd5">papayawhip</td><td>255, 239, 213</td><td>#ffefd5</td></tr>
+<tr><td>peachpuff</td><td class="light" bgcolor="#ffdab9">peachpuff</td><td>255, 218, 185</td><td>#ffdab9</td></tr>
+<tr><td>peru</td><td class="light" bgcolor="#cd853f">peru</td><td>205, 133, 63</td><td>#cd853f</td></tr>
+<tr><td>pink</td><td class="light" bgcolor="#ffc0cb">pink</td><td>255, 192, 203</td><td>#ffc0cb</td></tr>
+<tr><td>plum</td><td class="light" bgcolor="#dda0dd">plum</td><td>221, 160, 221</td><td>#dda0dd</td></tr>
+<tr><td>powderblue</td><td class="light" bgcolor="#b0e0e6">powderblue</td><td>176, 224, 230</td><td>#b0e0e6</td></tr>
+<tr><td>purple</td><td class="dark" bgcolor="#800080">purple</td><td>128, 0, 128</td><td>#800080</td></tr>
+<tr><td>red</td><td class="dark" bgcolor="#ff0000">red</td><td>255, 0, 0</td><td>#ff0000</td></tr>
+<tr><td>rosybrown</td><td class="light" bgcolor="#bc8f8f">rosybrown</td><td>188, 143, 143</td><td>#bc8f8f</td></tr>
+<tr><td>royalblue</td><td class="light" bgcolor="#4169e1">royalblue</td><td>65, 105, 225</td><td>#4169e1</td></tr>
+<tr><td>saddlebrown</td><td class="dark" bgcolor="#8b4513">saddlebrown</td><td>139, 69, 19</td><td>#8b4513</td></tr>
+<tr><td>salmon</td><td class="light" bgcolor="#fa8072">salmon</td><td>250, 128, 114</td><td>#fa8072</td></tr>
+<tr><td>sandybrown</td><td class="light" bgcolor="#f4a460">sandybrown</td><td>244, 164, 96</td><td>#f4a460</td></tr>
+<tr><td>seagreen</td><td class="dark" bgcolor="#2e8b57">seagreen</td><td>46, 139, 87</td><td>#2e8b57</td></tr>
+<tr><td>seashell</td><td class="light" bgcolor="#fff5ee">seashell</td><td>255, 245, 238</td><td>#fff5ee</td></tr>
+<tr><td>sienna</td><td class="dark" bgcolor="#a0522d">sienna</td><td>160, 82, 45</td><td>#a0522d</td></tr>
+<tr><td>silver</td><td class="light" bgcolor="#c0c0c0">silver</td><td>192, 192, 192</td><td>#c0c0c0</td></tr>
+<tr><td>skyblue</td><td class="light" bgcolor="#87ceeb">skyblue</td><td>135, 206, 235</td><td>#87ceeb</td></tr>
+<tr><td>slateblue</td><td class="light" bgcolor="#6a5acd">slateblue</td><td>106, 90, 205</td><td>#6a5acd</td></tr>
+<tr><td>slategray</td><td class="light" bgcolor="#708090">slategray</td><td>112, 128, 144</td><td>#708090</td></tr>
+<tr><td>slategrey</td><td class="light" bgcolor="#708090">slategrey</td><td>112, 128, 144</td><td>#708090</td></tr>
+<tr><td>snow</td><td class="light" bgcolor="#fffafa">snow</td><td>255, 250, 250</td><td>#fffafa</td></tr>
+<tr><td>springgreen</td><td class="light" bgcolor="#00ff7f">springgreen</td><td>0, 255, 127</td><td>#00ff7f</td></tr>
+<tr><td>steelblue</td><td class="light" bgcolor="#4682b4">steelblue</td><td>70, 130, 180</td><td>#4682b4</td></tr>
+<tr><td>tan</td><td class="light" bgcolor="#d2b48c">tan</td><td>210, 180, 140</td><td>#d2b48c</td></tr>
+<tr><td>teal</td><td class="dark" bgcolor="#008080">teal</td><td>0, 128, 128</td><td>#008080</td></tr>
+<tr><td>thistle</td><td class="light" bgcolor="#d8bfd8">thistle</td><td>216, 191, 216</td><td>#d8bfd8</td></tr>
+<tr><td>tomato</td><td class="light" bgcolor="#ff6347">tomato</td><td>255, 99, 71</td><td>#ff6347</td></tr>
+<tr><td>turquoise</td><td class="light" bgcolor="#40e0d0">turquoise</td><td>64, 224, 208</td><td>#40e0d0</td></tr>
+<tr><td>violet</td><td class="light" bgcolor="#ee82ee">violet</td><td>238, 130, 238</td><td>#ee82ee</td></tr>
+<tr><td>wheat</td><td class="light" bgcolor="#f5deb3">wheat</td><td>245, 222, 179</td><td>#f5deb3</td></tr>
+<tr><td>white</td><td class="light" bgcolor="#ffffff">white</td><td>255, 255, 255</td><td>#ffffff</td></tr>
+<tr><td>whitesmoke</td><td class="light" bgcolor="#f5f5f5">whitesmoke</td><td>245, 245, 245</td><td>#f5f5f5</td></tr>
+<tr><td>yellow</td><td class="light" bgcolor="#ffff00">yellow</td><td>255, 255, 0</td><td>#ffff00</td></tr>
+<tr><td>yellowgreen</td><td class="light" bgcolor="#9acd32">yellowgreen</td><td>154, 205, 50</td><td>#9acd32</td></tr>
+
+</tbody>
+</table>
+</div>
+</body>
+</html>
+
diff --git a/www/compare.html b/www/compare.html
new file mode 100644
index 0000000..1d0126e
--- /dev/null
+++ b/www/compare.html
@@ -0,0 +1,419 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="compare"></a>gm compare
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+compare - compare two images.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#comp-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#comp-desc">Description</a>
+</dt>
+<dt>
+<a href="#comp-exam">Examples</a>
+</dt>
+<dt>
+<a href="#comp-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm compare</strong> <strong>[</strong> <em>options</em> <strong>... ]</strong> <em>reference-image</em>
+<strong>[</strong> <em>options</em> <strong>... ]</strong> <em>compare-image</em>
+<strong>[</strong> <em>options</em> <strong>... ]</strong>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>compare</strong> compares two similar images using a specified statistical
+method (see <strong>-metric</strong>) and/or by writing a difference image
+(<strong>-file</strong>), with the altered pixels annotated using a specified
+method (see <strong>-highlight-style</strong>) and color (see
+<strong>-highlight-color</strong>). <p><em>Reference-image</em> is the original
+image and <em>compare-image</em> is the (possibly) altered version, which
+should have the same dimensions as <em>reference-image</em>.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To compare two images using Mean Square Error (MSE) statistical analysis
+use:
+<pre>
+ compare -metric mse original.miff compare.miff
+</pre>
+<p>
+To create an annotated difference image use:
+<pre>
+ compare -highlight-style assign -highlight-color purple -file diff.miff original.miff compare.miff
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect only for the image that follows. All
+options are reset to their default values after each image is read.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-file">-file</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write annotated difference image to file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-highlight-color">-highlight-color</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixel annotation color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-highlight-style">-highlight-style</a> <i>&lt;style&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixel annotation style</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-maximum-error">-maximum-error</a> <i>&lt;limit&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the maximum amount of total image error</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -metric <i>&lt;metric&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>comparison metric (MAE, MSE, PAE, PSNR, RMSE)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
diff --git a/www/composite.html b/www/composite.html
new file mode 100644
index 0000000..e23ec89
--- /dev/null
+++ b/www/composite.html
@@ -0,0 +1,862 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="composite"></a>gm composite
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+composite - composite images together.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#comp-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#comp-desc">Description</a>
+</dt>
+<dt>
+<a href="#comp-exam">Examples</a>
+</dt>
+<dt>
+<a href="#comp-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm composite</strong> <strong>[</strong> <em>options</em> <strong>... ]</strong>
+<em>change-image base-image</em>
+<strong>[</strong> <em>mask-image</em> <strong>]</strong> <em>output-image</em>
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>composite</strong> composites (combines) images to create new images.
+<p><em>base-image</em> is the base image and <em>change-image</em> contains the changes.
+<em>ouput-image</em> is the result, and normally has the same dimensions
+as <em>base-image</em>.
+<br>&nbsp;<br>
+<p>
+The optional <em>mask-image</em> can be used to provide opacity information
+for <em>change-image</em> when it has none or if you want a different mask.
+A mask image is typically grayscale and the same size as
+<strong>base-image</strong>. If <em>mask-image</em> is not grayscale, it is converted
+to grayscale and the resulting intensities are used as opacity
+information.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To composite an image of a cockatoo with a perch, use:
+<pre>
+ gm composite cockatoo.miff perch.ras composite.miff
+</pre>
+<p>
+To compute the difference between images in a series, use:
+<pre>
+ gm composite -compose difference series.2 series.1 difference.miff
+</pre>
+<p>
+To composite an image of a cockatoo with a perch starting at location (100,150),
+use:
+<pre>
+ gm composite -geometry +100+150 cockatoo.miff perch.ras composite.miff
+</pre>
+<p>
+To tile a logo across your image of a cockatoo, use
+<pre>
+ gm convert +shade 30x60 cockatoo.miff mask.miff
+ gm composite -compose bumpmap -tile logo.png
+ cockatoo.miff mask.miff composite.miff
+</pre>
+<p>
+To composite a red, green, and blue color plane into a single composite image,
+try
+<pre>
+ gm composite -compose CopyGreen green.png red.png red-green.png
+ gm composite -compose CopyBlue blue.png red-green.png composite.png
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect only for the image that follows. All
+options are reset to their default values after each image is read.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blue-primary">-blue-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compose">-compose</a> <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-displace">-displace</a> <i>&lt;horizontal scale&gt;x&lt;vertical scale&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shift image pixels as defined by a displacement map</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dissolve">-dissolve</a> <i>&lt;percent&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>dissolve an image into another by the given percent</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gravity">-gravity</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-green-primary">-green-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-profile">-profile</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add ICM, IPTC, or generic profile to image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-recolor">-recolor</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a color translation matrix to image channels</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-red-primary">-red-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-render">-render</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-repage">-repage</a> <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scene">-scene</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stegano">-stegano</a> <i>&lt;offset&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>hide watermark within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stereo">-stereo</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite two images to create a stereo anaglyph</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strip">-strip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-units">-units</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the units of image resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-unsharp">-unsharp</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+&lt;amount&gt;</i>}<i></i>{<i>+&lt;threshold&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image with an unsharp mask operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -watermark <i>&lt;brightness&gt;x&lt;saturation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>percent brightness and saturation of a watermark</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-point">-white-point</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-write">-write</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write an intermediate image [<em>convert, composite</em>]</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
diff --git a/www/configure-target-setup.png b/www/configure-target-setup.png
new file mode 100644
index 0000000..2a21cef
--- /dev/null
+++ b/www/configure-target-setup.png
Binary files differ
diff --git a/www/conjure.html b/www/conjure.html
new file mode 100644
index 0000000..1ff6e93
--- /dev/null
+++ b/www/conjure.html
@@ -0,0 +1,470 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conjure"></a>gm conjure
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conj-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+conjure - process a Magick Scripting Language (MSL) script
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conj-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#conj-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#conj-desc">Description</a>
+</dt>
+<dt>
+<a href="#conj-opti">Options</a>
+</dt>
+<dt>
+<a href="#conj-msl">Magick Scripting Language</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conj-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm conjure</strong> <strong>[</strong> <em>options</em> <strong>]</strong> <em>script.msl</em>
+<strong>[ [</strong> <em>options</em> <strong>]</strong> <em>script.msl</em> <strong>]</strong>
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conj-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The Magick scripting language (MSL) will primarily benefit those that
+want to accomplish custom image processing tasks but do not wish to
+program, or those that do not have access to a Perl interpreter or a
+compiler. The interpreter is called conjure and here is an example
+script:
+<pre>
+ &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ &lt;image size="400x400" &gt;
+ &lt;read filename="image.gif" /&gt;
+ &lt;get width="base-width" height="base-height" /&gt;
+ &lt;resize geometry="%[dimensions]" /&gt;
+ &lt;get width="width" height="height" /&gt;
+ &lt;print output=
+ "Image sized from %[base-width]x%[base-height]
+ to %[width]x%[height].\n" /&gt;
+ &lt;write filename="image.png" /&gt;
+ &lt;/image&gt;
+</pre>
+<p>
+invoked with
+<pre>
+ gm conjure -dimensions 400x400 incantation.msl
+</pre>
+<p>
+All operations will closely follow the key/value pairs defined in
+PerlMagick, unless otherwise noted.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conj-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect, or if it is changed by a statement
+in the scripting language.
+<p>
+You can define your own keyword/value pairs on the command line.
+The script can then use this information when setting values by including
+%[keyword] in the string. For example, if you included
+"-dimensions 400x400" on the command line, as illustrated above,
+then any string
+containing "%[dimensions]" would have 400x400 substituted.
+The "%[string]" can be used either an entire string, such as
+geometry="%[dimensions]" or as a part of a string such as
+filename="%[basename].png".
+<p>
+The keyword can be any string except for the following reserved
+strings (in any upper, lower, or mixed case variant): <strong>debug</strong>,
+<strong>help</strong>, and <strong>verbose</strong>, whose usage is described below.
+<p>
+The value can be any string. If
+either the keyword or the value contains white space or any
+symbols that have special meanings to your shell such as "#",
+"|",
+or
+"%", enclose the string in quotation marks or use "\" to escape the white
+space and special symbols.
+<p>
+Keywords and values are case dependent. "Key",
+"key",
+and "KEY" would
+be three different keywords.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conj-msl"></a>Magick Scripting Language
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The Magick Scripting Language (MSL) presently defines the following
+elements and their attributes:
+<dl>
+<dt>&lt;image&gt;</dt>
+<dd>background, color, id, size</dd>
+<dd>
+Define a new image object. <strong>&lt;/image&gt;</strong> destroys it. Because of
+this, if you wish to reference multiple "subimages" (aka pages or
+layers), you can embed one <strong>image</strong> element inside of another. For
+example:
+</dd>
+<dd>
+<pre>
+ &lt;image&gt;
+ &lt;read filename="input.png" /&gt;
+ &lt;get width="base-width" height="base-height" /&gt;
+ &lt;image height="base-height" width="base-width"&gt;
+ &lt;image /&gt;
+ &lt;write filename="output.mng" /&gt;
+ &lt;/image&gt;
+</pre>
+</dd>
+<dd>
+<pre>
+ &lt;image size="400x400" /&gt;
+</pre>
+</dd>
+<dt>&lt;group&gt;</dt>
+<dd>
+Define a new group of image objects. By default, images are only
+valid for the life of their <strong>&lt;image&gt;</strong>element.
+</dd>
+<dd>
+<pre>
+ &lt;image&gt; -- creates the image
+ ..... -- do stuff with it
+ &lt;/image&gt; -- dispose of the image
+</pre>
+</dd>
+<dd>
+However, in a group, all images in that group will stay around for the
+life of the group:
+</dd>
+<dd>
+<pre>
+ &lt;group&gt; -- start a group
+ &lt;image&gt; -- create an image
+ .... -- do stuff
+ &lt;/image&gt; -- NOOP
+ &lt;image&gt; -- create another image
+ .... -- do more stuff
+ &lt;/image&gt; -- NOOP
+ &lt;write filename="image.mng" /&gt; -- output
+ &lt;/group&gt; -- dispose of both images
+</pre>
+</dd>
+<dt>&lt;read&gt;</dt>
+ <dd>filename</dd>
+<dd>
+Read a new image from a disk file.
+</dd>
+<dd>
+<pre>
+ &lt;read filename="image.gif" /&gt;
+</pre>
+</dd>
+<dd>
+To read two images use
+</dd>
+<dd>
+<pre>
+ &lt;read filename="image.gif" /&gt;
+ &lt;read filename="image.png /&gt;
+</pre>
+</dd>
+<dt>&lt;write&gt;</dt>
+ <dd>filename</dd>
+<dd>Write the image(s) to disk, either as
+a single multiple-image file or multiple ones if necessary.
+</dd>
+<dd>
+<pre>
+ &lt;write filename=image.tiff" /&gt;
+</pre>
+<dt>&lt;get&gt;</dt>
+<dd>Get any attribute recognized by
+PerlMagick's GetAttribute() and stores it as an image attribute for later
+use. Currently only <em>width</em> and <em>height</em> are supported.</dd>
+<dd>
+<pre>
+ &lt;get width="base-width" height="base-height" /&gt;
+ &lt;print output="Image size is %[base-width]x%[base-height].\n" /&gt;
+</pre>
+</dd>
+<dt>&lt;set&gt;</dt>
+<dd>background, bordercolor, clip-mask, colorspace, density,
+magick, mattecolor, opacity. Set an attribute recognized by
+PerlMagick's GetAttribute().</dd>
+<dt>&lt;profile&gt;</dt>
+ <dd>[profilename]</dd>
+<dd>
+Read one or more IPTC, ICC or generic profiles from file and assign to image
+</dd>
+<dd>
+<pre>
+ &lt;profile iptc="profile.iptc" generic="generic.dat" /&gt;
+</pre>
+</dd>
+<dd>
+To remove a specified profile use "!" as the filename eg
+</dd>
+<dd>
+<pre>
+ &lt;profile icm="!" iptc="profile.iptc" /&gt;
+</pre>
+</dd>
+<dt>&lt;border&gt;</dt>
+ <dd>fill, geometry, height, width</dd>
+<dt>&lt;blur&gt;</dt>
+ <dd>radius, sigma</dd>
+<dt>&lt;charcoal&gt;</dt>
+ <dd>radius, sigma</dd>
+<dt>&lt;chop&gt;</dt>
+ <dd>geometry, height, width, x, y</dd>
+<dt>&lt;crop&gt;</dt>
+ <dd>geometry, height, width, x, y</dd>
+<dt>&lt;composite&gt;</dt>
+ <dd>compose, geometry, gravity, image, x, y</dd>
+<dd>
+<pre>
+ &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ &lt;group&gt;
+ &lt;image id="image_01"&gt;
+ &lt;read filename="cloud3.gif"/&gt;
+ &lt;resize geometry="250x90"/&gt;
+ &lt;/image&gt;
+ &lt;image id="image_02"&gt;
+ &lt;read filename="cloud4.gif"/&gt;
+ &lt;resize geometry="190x100"/&gt;
+ &lt;/image&gt;
+ &lt;image&gt;
+ &lt;read filename="background.jpg"/&gt;
+ &lt;composite image="image_01" geometry="+740+470"/&gt;
+ &lt;composite image="image_02" geometry="+390+415"/&gt;
+ &lt;/image&gt;
+ &lt;write filename="result.png"/&gt;
+ &lt;/group&gt;
+</pre>
+</dd>
+<dt>&lt;despeckle&gt;</dt>
+<dt>&lt;emboss&gt;</dt>
+ <dd>radius, sigma</dd>
+<dt>&lt;enhance&gt;</dt>
+<dt>&lt;equalize&gt;</dt>
+<dt>&lt;edge&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;flip&gt;</dt>
+<dt>&lt;flop&gt;</dt>
+<dt>&lt;frame&gt;</dt>
+ <dd>fill, geometry, height, width, x, y, inner, outer</dd>
+<dt>&lt;flatten&gt;</dt>
+<dt>&lt;get&gt;</dt>
+ <dd>height, width</dd>
+<dt>&lt;gamma&gt;</dt>
+ <dd>red, green, blue</dd>
+<dt>&lt;image&gt;</dt>
+ <dd>background, color, id, size</dd>
+<dt>&lt;implode&gt;</dt>
+ <dd>amount</dd>
+<dt>&lt;magnify&gt;</dt>
+<dt>&lt;minify&gt;</dt>
+<dt>&lt;medianfilter&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;normalize&gt;</dt>
+<dt>&lt;oilpaint&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;print&gt;</dt>
+ <dd>output</dd>
+<dt>&lt;profile&gt;</dt>
+ <dd>[profilename]</dd>
+<dt>&lt;read&gt;</dt>
+<dt>&lt;resize&gt;</dt>
+ <dd>blur, filter, geometry, height, width</dd>
+<dt>&lt;roll&gt;</dt>
+ <dd>geometry, x, y</dd>
+<dt>&lt;rotate&gt;</dt>
+ <dd>degrees</dd>
+<dt>&lt;reducenoise&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;sample&gt;</dt>
+ <dd>geometry, height, width</dd>
+<dt>&lt;scale&gt;</dt>
+ <dd>geometry, height, width</dd>
+<dt>&lt;sharpen&gt;</dt>
+ <dd>radius, sigma</dd>
+<dt>&lt;shave&gt;</dt>
+ <dd>geometry, height, width</dd>
+<dt>&lt;shear&gt;</dt>
+ <dd>x, y</dd>
+<dt>&lt;solarize&gt;</dt>
+ <dd>threshold</dd>
+<dt>&lt;spread&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;stegano&gt;</dt>
+ <dd>image</dd>
+<dt>&lt;stereo&gt;</dt>
+ <dd>image</dd>
+<dt>&lt;swirl&gt;</dt>
+ <dd>degrees</dd>
+<dt>&lt;texture&gt;</dt>
+ <dd>image</dd>
+<dt>&lt;threshold&gt;</dt>
+ <dd>threshold</dd>
+<dt>&lt;transparent&gt;</dt>
+ <dd>color</dd>
+<dt>&lt;trim&gt;</dt>
+</dl>
+</td></tr></table>
diff --git a/www/contribute.html b/www/contribute.html
new file mode 100644
index 0000000..1c36ca4
--- /dev/null
+++ b/www/contribute.html
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Contributing to GraphicsMagick</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="contributing-to-graphicsmagick">
+<h1 class="title">Contributing to GraphicsMagick</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The future and success of GraphicsMagick depends on your contributions.
+By contributing to GraphicsMagick you will benefit from the
+features/fixes you contribute, can take pride in taking part in the
+development of a quality product, and you can tell your friends that you
+contribute to the GraphicsMagick project.</p>
+<p>There are a number of ways you can contribute:</p>
+<ul class="simple">
+<li>Submit bug reports to the GraphicsMagick bug tracking system at
+SourceForge.</li>
+<li>Submit patches to the GraphicsMagick patch submission system at
+SourceForge.</li>
+<li>Perform test builds on unusual systems and report the results.</li>
+<li>Submit ideas and proposed designs to the graphicsmagick-core
+mailing list.</li>
+<li>Create a new language interface, dependent library, or application.</li>
+<li>Join the GraphicsMagick Group as a full-fledged developer with CVS
+commit access.</li>
+</ul>
+<p>Regardless of how you choose to contribute, your contributions will be
+treated with the respect and value that they deserve.</p>
+<p>Becoming a member of the GraphicsMagick Group requires a majority vote
+from existing members. Your chances of being admitted to the group are
+increased significantly if you have a proven track-record of success on
+other open source projects, are a recognized expert in the field, or have
+already demonstrated your capabilities and commitment by contributing to
+the project in other ways. Please contact Bob Friesenhahn
+&lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt; in order to be considered for group
+membership.</p>
+<div class="section" id="areas-to-contribute">
+<h1>Areas To Contribute</h1>
+<p>The following are areas where significant contributions may be made to
+the GraphicsMagick project:</p>
+<ul class="simple">
+<li>Support building and distributing GraphicsMagick RPMs for Linux.</li>
+<li>Act as formal maintainer for the Gentoo Linux GraphicsMagick ebuild so
+that it is added back to Portage. This is not difficult since the
+ebuild has been actively maintained via the Gentoo bug tracking system.
+At the very least, registering a vote for the Gentoo bug may be helpful.
+See <a class="reference external" href="http://bugs.gentoo.org/show_bug.cgi?id=190372">http://bugs.gentoo.org/show_bug.cgi?id=190372</a>.</li>
+<li>Set up an FTP mirror site for GraphicsMagick.</li>
+<li>Create a language interface using SWIG &lt;<a class="reference external" href="http://www.swig.org/">http://www.swig.org/</a>&gt; to
+support scripting in Perl, Python, TCL/TK, Guile, MzScheme, Ruby,
+Java, PHP, and CHICKEN, based on a common implementation.</li>
+<li>Create a new utility command parser based on a separate LALR or
+XML-based syntax definition, and using an approach suitable to
+replace the existing error-prone command parsers in magick/command.c</li>
+<li>Create a vector encoder for EPS, Postscript, PDF, SVG
+&lt;<a class="reference external" href="http://www.w3.org/Graphics/SVG/">http://www.w3.org/Graphics/SVG/</a>&gt;, Macromedia Flash
+(SWF), WebCGM &lt;<a class="reference external" href="http://www.w3.org/Graphics/WebCGM/">http://www.w3.org/Graphics/WebCGM/</a>&gt;, or WMF.</li>
+<li>Create an OpenEXR coder based on the OpenEXR
+&lt;<a class="reference external" href="http://www.openexr.com/">http://www.openexr.com/</a>&gt; library from Industrial Light &amp; Magic.</li>
+<li>Create a <em>pstoedit</em> module to import Postscript, EPS, and PDF
+files as vector data using pstoedit &lt;<a class="reference external" href="http://www.pstoedit.net/">http://www.pstoedit.net/</a>&gt; which
+already includes a high-quality driver to render Postscript vectors via
+GraphicsMagick. This module could also export vector data in many
+formats using pstoedit's output drivers.</li>
+<li>Work on adding EXIF profile writing support which works for JPEG and
+TIFF formats.</li>
+<li>Add integrated Adobe XMP
+&lt;<a class="reference external" href="http://www.adobe.com/products/xmp/index.html">http://www.adobe.com/products/xmp/index.html</a>&gt; profile support for
+TIFF, JPEG, PNG, PDF, EPS, and Postscript.</li>
+<li>Port Erik Reinhard's super-cool Parameter Estimation For
+Photographic Tone Reproduction
+&lt;<a class="reference external" href="http://www.cs.ucf.edu/~reinhard/Reinhard02/">http://www.cs.ucf.edu/~reinhard/Reinhard02/</a>&gt; algorithm to
+GraphicsMagick.</li>
+<li>Create a replacement (using a portable Widget set such as FLTK) for the
+IMDisplay Windows GUI program and possibly the X11 'display' program.</li>
+<li>Create an interface between GraphicsMagick and OpenOffice.org.
+&lt;<a class="reference external" href="http://www.openoffice.org/">http://www.openoffice.org/</a>&gt; so that OpenOffice may load and save
+any format supported by GraphicsMagick. OpenOffice.org offers a
+separate SDK so there may be a number of other opportunities to
+explore.</li>
+<li>Complete the port of ralcgm to Windows so that it may be used as a
+delegate under Windows.</li>
+</ul>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/contribute.rst b/www/contribute.rst
new file mode 100644
index 0000000..2a0124c
--- /dev/null
+++ b/www/contribute.rst
@@ -0,0 +1,110 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+==============================
+Contributing to GraphicsMagick
+==============================
+
+The future and success of GraphicsMagick depends on your contributions.
+By contributing to GraphicsMagick you will benefit from the
+features/fixes you contribute, can take pride in taking part in the
+development of a quality product, and you can tell your friends that you
+contribute to the GraphicsMagick project.
+
+There are a number of ways you can contribute:
+
+* Submit bug reports to the GraphicsMagick bug tracking system at
+ SourceForge.
+
+* Submit patches to the GraphicsMagick patch submission system at
+ SourceForge.
+
+* Perform test builds on unusual systems and report the results.
+
+* Submit ideas and proposed designs to the graphicsmagick-core
+ mailing list.
+
+* Create a new language interface, dependent library, or application.
+
+* Join the GraphicsMagick Group as a full-fledged developer with CVS
+ commit access.
+
+Regardless of how you choose to contribute, your contributions will be
+treated with the respect and value that they deserve.
+
+Becoming a member of the GraphicsMagick Group requires a majority vote
+from existing members. Your chances of being admitted to the group are
+increased significantly if you have a proven track-record of success on
+other open source projects, are a recognized expert in the field, or have
+already demonstrated your capabilities and commitment by contributing to
+the project in other ways. Please contact Bob Friesenhahn
+<bfriesen@simple.dallas.tx.us> in order to be considered for group
+membership.
+
+Areas To Contribute
+-------------------
+
+The following are areas where significant contributions may be made to
+the GraphicsMagick project:
+
+* Support building and distributing GraphicsMagick RPMs for Linux.
+
+* Act as formal maintainer for the Gentoo Linux GraphicsMagick ebuild so
+ that it is added back to Portage. This is not difficult since the
+ ebuild has been actively maintained via the Gentoo bug tracking system.
+ At the very least, registering a vote for the Gentoo bug may be helpful.
+ See http://bugs.gentoo.org/show_bug.cgi?id=190372.
+
+* Set up an FTP mirror site for GraphicsMagick.
+
+* Create a language interface using SWIG <http://www.swig.org/> to
+ support scripting in Perl, Python, TCL/TK, Guile, MzScheme, Ruby,
+ Java, PHP, and CHICKEN, based on a common implementation.
+
+* Create a new utility command parser based on a separate LALR or
+ XML-based syntax definition, and using an approach suitable to
+ replace the existing error-prone command parsers in magick/command.c
+
+* Create a vector encoder for EPS, Postscript, PDF, SVG
+ <http://www.w3.org/Graphics/SVG/>, Macromedia Flash
+ (SWF), WebCGM <http://www.w3.org/Graphics/WebCGM/>, or WMF.
+
+* Create an OpenEXR coder based on the OpenEXR
+ <http://www.openexr.com/> library from Industrial Light & Magic.
+
+* Create a *pstoedit* module to import Postscript, EPS, and PDF
+ files as vector data using pstoedit <http://www.pstoedit.net/> which
+ already includes a high-quality driver to render Postscript vectors via
+ GraphicsMagick. This module could also export vector data in many
+ formats using pstoedit's output drivers.
+
+* Work on adding EXIF profile writing support which works for JPEG and
+ TIFF formats.
+
+* Add integrated Adobe XMP
+ <http://www.adobe.com/products/xmp/index.html> profile support for
+ TIFF, JPEG, PNG, PDF, EPS, and Postscript.
+
+* Port Erik Reinhard's super-cool Parameter Estimation For
+ Photographic Tone Reproduction
+ <http://www.cs.ucf.edu/~reinhard/Reinhard02/> algorithm to
+ GraphicsMagick.
+
+* Create a replacement (using a portable Widget set such as FLTK) for the
+ IMDisplay Windows GUI program and possibly the X11 'display' program.
+
+* Create an interface between GraphicsMagick and OpenOffice.org.
+ <http://www.openoffice.org/> so that OpenOffice may load and save
+ any format supported by GraphicsMagick. OpenOffice.org offers a
+ separate SDK so there may be a number of other opportunities to
+ explore.
+
+* Complete the port of ralcgm to Windows so that it may be used as a
+ delegate under Windows.
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/convert.html b/www/convert.html
new file mode 100644
index 0000000..2870a15
--- /dev/null
+++ b/www/convert.html
@@ -0,0 +1,1909 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a convert="top"></a>gm convert
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conv-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+convert - convert an image or sequence of images
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conv-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#conv-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#conv-desc">Description</a>
+</dt>
+<dt>
+<a href="#conv-exam">Examples</a>
+</dt>
+<dt>
+<a href="#conv-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conv-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm convert</strong> <strong>[</strong> <em>options</em> <strong>... ]</strong>
+<em>input_file <strong>[</strong> <em>options</em> <strong>... ]</strong> <em>output_file</em>
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conv-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Convert</strong> converts an input file using one image format to an output
+file with a differing image format. In addition, various types of image
+processing can be performed on the converted image during the conversion
+process. <strong>Convert</strong> recognizes the image formats listed in
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conv-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To make a thumbnail of a JPEG image, use:
+<pre>
+ gm convert -size 120x120 cockatoo.jpg -resize 120x120 +profile "*" thumbnail.jpg
+</pre>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In this example, <tt>'-size 120x120'</tt> gives a hint to the JPEG decoder
+that the image is going to be downscaled to 120x120, allowing it to run
+faster by avoiding returning full-resolution images to GraphicsMagick for
+the subsequent resizing operation. The
+<tt>'-resize 120x120'</tt> specifies the desired dimensions of the
+output image. It will be scaled so its largest dimension is 120 pixels. The
+<tt>'+profile "*"'</tt> removes any ICM, EXIF, IPTC, or other profiles
+that might be present in the input and aren't needed in the thumbnail.</font></td></tr></table>
+<p>
+To convert a <em>MIFF</em> image of a cockatoo to a SUN raster image, use:
+<pre>
+ gm convert cockatoo.miff sun:cockatoo.ras
+</pre>
+<p>
+To convert a multi-page <em>PostScript</em> document to individual FAX pages,
+use:
+<pre>
+ gm convert -monochrome document.ps fax:page
+</pre>
+<p>
+To convert a TIFF image to a <em>PostScript</em> A4 page with the image in
+the lower left-hand corner, use:
+<pre>
+ gm convert -page A4+0+0 image.tiff document.ps
+</pre>
+<p>
+To convert a raw Gray image with a 128 byte header to a portable graymap,
+use:
+<pre>
+ gm convert -depth 8 -size 768x512+128 gray:raw image.pgm
+</pre>
+<p>
+In this example, "raw" is the input file. Its format is "gray" and it
+has the dimensions and number of header bytes specified by the -size
+option and the sample depth specified by the
+-depth option. The output file is "image.pgm". The suffix ".pgm"
+specifies its format.
+<p>
+To convert a Photo CD image to a TIFF image, use:
+<pre>
+ gm convert -size 1536x1024 img0009.pcd image.tiff
+ gm convert img0009.pcd[4] image.tiff
+</pre>
+<p>
+To create a visual image directory of all your JPEG images, use:
+<pre>
+ gm convert 'vid:*.jpg' directory.miff
+</pre>
+<p>
+To annotate an image with blue text using font 12x24 at position (100,100),
+use:
+<pre>
+ gm convert -font helvetica -fill blue -draw "text 100,100 Cockatoo"
+ bird.jpg bird.miff
+</pre>
+<p>
+To tile a 640x480 image with a JPEG texture with bumps use:
+<pre>
+ gm convert -size 640x480 tile:bumps.jpg tiled.png
+</pre>
+<p>
+To surround an icon with an ornamental border to use with Mosaic(1), use:
+<pre>
+ gm convert -mattecolor "#697B8F" -frame 6x6 bird.jpg icon.png
+</pre>
+<p>
+To create a MNG animation from a DNA molecule sequence, use:
+<pre>
+ gm convert -delay 20 dna.* dna.mng
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conv-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or <strong>-noop</strong>.
+Some options only affect the decoding of images and others only the encoding.
+The latter can appear after the final group of input images.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-adjoin">-adjoin</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>join images into a single multi-image file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-affine">-affine</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>drawing transform matrix</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-antialias">-antialias</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixel aliasing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-append">-append</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>append a set of images</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details"></a> <i>-asc-cdl &lt;spec&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply ASC CDL color transform</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-auto-orient">-auto-orient</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>orient (rotate) image so it is upright</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-average">-average</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>average a set of images</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-black-threshold">-black-threshold</a> <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels below the threshold become black</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blue-primary">-blue-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blur">-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-border">-border</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with a border of color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-box">-box</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the color of the annotation bounding box</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-channel">-channel</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of channel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -charcoal <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate a charcoal drawing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-chop">-chop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixels from the interior of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-clip">-clip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply the clipping path, if one is present</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-coalesce">-coalesce</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>merge a sequence of images</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorize">-colorize</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colorize the image with the pen color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compose">-compose</a> <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-contrast">-contrast</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enhance or reduce the image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-convolve">-convolve</a> <i>&lt;kernel&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>convolve image with the specified convolution kernel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-cycle">-cycle</a> <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image colormap by amount</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-deconstruct">-deconstruct</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>break down an image sequence into constituent parts</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -despeckle
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>reduce the speckles within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-draw">-draw</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with one or more graphic primitives</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -edge <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>detect edges within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -emboss <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>emboss an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -enhance
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a digital filter to enhance a noisy image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -equalize
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform histogram equalization to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-extent">-extent</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite image on background color canvas image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fill">-fill</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flatten">-flatten</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>flatten a sequence of images</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flip">-flip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flop">-flop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-format">-format</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output formatted image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-frame">-frame</a> <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fuzz">-fuzz</a> <i>&lt;distance&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colors within this Euclidean distance are considered equal</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gaussian">-gaussian</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gravity">-gravity</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-green-primary">-green-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -hald-clut <i>&lt;clut&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a Hald CLUT to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -implode <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>implode image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-intent">-intent</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of rendering intent when managing the image color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-lat">-lat</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;offset&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform local adaptive thresholding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-level">-level</a> <i>&lt;black_point&gt;</i>{<i>,&lt;gamma&gt;</i>}<i></i>{<i>,&lt;white_point&gt;</i>}<i></i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>adjust the level of image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-list">-list</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of list</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-loop">-loop</a> <i>&lt;iterations&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add Netscape loop extension to your GIF animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-map">-map</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>choose a particular set of colors from this image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mask">-mask</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify a clipping mask</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -median <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a median filter to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -minify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>minify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-modulate">-modulate</a> <i>brightness[,saturation[,hue]]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>vary the brightness, saturation, and hue of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-morph">-morph</a> <i>&lt;frames&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>morphs an image sequence</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mosaic">-mosaic</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a mosaic from an image or an image sequence</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-motion-blur">-motion-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+angle</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Simulate motion blur</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noise">-noise</a> <i>&lt;radius|type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add or reduce noise in an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-normalize">-normalize</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform image to span the full range of color values</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-opaque">-opaque</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>change this color to the pen color within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-operator">-operator</a> <i>channel operator rvalue[%]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a mathematical, bitwise, or value operator to an image channel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-ordered-dither">-ordered-dither</a> <i>&lt;channeltype&gt; &lt;NxN&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>ordered dither the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-orient">-orient</a> <i>&lt;orientation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Set the image orientation attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-paint">-paint</a> <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate an oil painting</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pen">-pen</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>(This option has been replaced by the -fill option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -ping
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>efficiently determine image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-preview">-preview</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>image preview type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-process">-process</a> <i>&lt;command&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>process a sequence of images using a process module</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-profile">-profile</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add ICM, IPTC, or generic profile to image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-raise">-raise</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>lighten or darken image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-random-threshold">-random-threshold</a> <i>&lt;channeltype&gt; &lt;LOWxHIGH&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>random threshold the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-recolor">-recolor</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a color translation matrix to image channels</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-red-primary">-red-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-region">-region</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply options to a portion of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-render">-render</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-repage">-repage</a> <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resample">-resample</a> <i>&lt;horizontal&gt;x&lt;vertical&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Resample image to specified horizontal and vertical resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-roll">-roll</a> <i></i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>roll an image vertically or horizontally</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sample">-sample</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale image using pixel sampling</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scale">-scale</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scene">-scene</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-segment">-segment</a> <i>&lt;cluster threshold&gt;x&lt;smoothing threshold&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>segment an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shade">-shade</a> <i>&lt;azimuth&gt;x&lt;elevation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shade the image using a distant light source</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shave">-shave</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shave pixels from the image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shear">-shear</a> <i>&lt;x degrees&gt;x&lt;y degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shear the image along the X or Y axis</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-solarize">-solarize</a> <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>negate all pixels above the threshold level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-spread">-spread</a> <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image pixels by a random amount</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strip">-strip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stroke">-stroke</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when stroking a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strokewidth">-strokewidth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the stroke width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-swirl">-swirl</a> <i>&lt;degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>swirl image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-threshold">-threshold</a> <i>&lt;value&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>threshold the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tile image when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transform">-transform</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transparent">-transparent</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-units">-units</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the units of image resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-unsharp">-unsharp</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+&lt;amount&gt;</i>}<i></i>{<i>+&lt;threshold&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image with an unsharp mask operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -use-pixmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use the pixmap</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -view <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>FlashPix viewing parameters</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-virtual-pixel">-virtual-pixel</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify contents of "virtual pixels"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-wave">-wave</a> <i>&lt;amplitude&gt;x&lt;wavelength&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>alter an image along a sine wave</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-point">-white-point</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-threshold">-white-threshold</a> <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels above the threshold become white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-write">-write</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write an intermediate image [<em>convert, composite</em>]</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
diff --git a/www/display.html b/www/display.html
new file mode 100644
index 0000000..89b5ec9
--- /dev/null
+++ b/www/display.html
@@ -0,0 +1,3677 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="display"></a>gm display
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+display - display an image on any workstation running X
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<ul>
+<li>
+<a href="#disp-syno">Synopsis</a>
+<li>
+<a href="#disp-desc">Description</a>
+<li>
+<a href="#disp-exam">Examples</a>
+<li>
+<a href="#disp-opti">Options</a>
+<li>
+<a href="#disp-mous">Mouse Buttons</a>
+<li>
+<a href="#disp-comm">Command Widget</a>
+<li>
+<a href="#disp-keyb">Keyboard Accelerators</a>
+<li>
+<a href="#disp-xres">X Resources</a>
+<li>
+<a href="#disp-imlo">Image Loading</a>
+<li>
+<a href="#disp-visu">Visual Image Directory</a>
+<li>
+<a href="#disp-imcu">Image Cutting</a>
+<li>
+<a href="#disp-imco">Image Copying</a>
+<li>
+<a href="#disp-impas">Image Pasting</a>
+<li>
+<a href="#disp-imcr">Image Cropping</a>
+<li>
+<a href="#disp-imch">Image Chopping</a>
+<li>
+<a href="#disp-imro">Image Rotation</a>
+<li>
+<a href="#disp-segm">Image Segmentation</a>
+<li>
+<a href="#disp-iman">Image Annotation</a>
+<li>
+<a href="#disp-imcomp">Image Compositing</a>
+<li>
+<a href="#disp-cole">Color Editing</a>
+<li>
+<a href="#disp-matt">Matte (Transparent Channel) Editing</a>
+<li>
+<a href="#disp-imdr">Image Drawing</a>
+<li>
+<a href="#disp-regi">Region of Interest</a>
+<li>
+<a href="#disp-impa">Image Panning</a>
+<li>
+<a href="#disp-impa">User Preferences</a>
+</ul>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm display</strong> <strong>[</strong> <em>options</em> <strong>...]</strong> <em>file</em>
+<strong>[</strong><em>options</em><strong>...]</strong><em>file</em>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Display is a machine architecture independent
+image processing and display program. It can display an image on any workstation
+screen running an X server. <strong>Display</strong> can read and write
+<strong>many</strong>
+of the more popular image <a href="formats.html">formats</a> (e.g. <strong>JPEG</strong>,
+<strong>TIFF</strong>,
+<strong>PNM</strong>,
+<strong>Photo
+CD</strong>, etc.).
+<p>
+With <strong>display</strong>, you can perform these functions on an image:
+<dl>
+<dd><img SRC="images/ball.png" ALT="*">load an image from a file
+<dd><img SRC="images/ball.png" ALT="*">display the next image
+<dd><img SRC="images/ball.png" ALT="*">display the former image
+<dd><img SRC="images/ball.png" ALT="*">display a sequence of images as a slide show
+<dd><img SRC="images/ball.png" ALT="*">write the image to a file
+<dd><img SRC="images/ball.png" ALT="*">print the image to a <em>PostScript</em> printer
+<dd><img SRC="images/ball.png" ALT="*">delete the image file
+<dd><img SRC="images/ball.png" ALT="*">create a Visual Image Directory
+<dd><img SRC="images/ball.png" ALT="*">select the image to display by its thumbnail rather than name
+<dd><img SRC="images/ball.png" ALT="*">undo last image transformation
+<dd><img SRC="images/ball.png" ALT="*">copy a region of the image
+<dd><img SRC="images/ball.png" ALT="*">paste a region to the image
+<dd><img SRC="images/ball.png" ALT="*">restore the image to its original size
+<dd><img SRC="images/ball.png" ALT="*">refresh the image
+<dd><img SRC="images/ball.png" ALT="*">half the image size
+<dd><img SRC="images/ball.png" ALT="*">double the image size
+<dd><img SRC="images/ball.png" ALT="*">resize the image
+<dd><img SRC="images/ball.png" ALT="*">crop the image
+<dd><img SRC="images/ball.png" ALT="*">cut the image
+<dd><img SRC="images/ball.png" ALT="*">flop image in the horizontal direction
+<dd><img SRC="images/ball.png" ALT="*">flip image in the vertical direction
+<dd><img SRC="images/ball.png" ALT="*">rotate the image 90 degrees clockwise
+<dd><img SRC="images/ball.png" ALT="*">rotate the image 90 degrees counter-clockwise
+<dd><img SRC="images/ball.png" ALT="*">rotate the image
+<dd><img SRC="images/ball.png" ALT="*">shear the image
+<dd><img SRC="images/ball.png" ALT="*">roll the image
+<dd><img SRC="images/ball.png" ALT="*">trim the image edges
+<dd><img SRC="images/ball.png" ALT="*">invert the colors of the image
+<dd><img SRC="images/ball.png" ALT="*">vary the color brightness
+<dd><img SRC="images/ball.png" ALT="*">vary the color saturation
+<dd><img SRC="images/ball.png" ALT="*">vary the image hue
+<dd><img SRC="images/ball.png" ALT="*">gamma correct the image
+<dd><img SRC="images/ball.png" ALT="*">sharpen the image contrast
+<dd><img SRC="images/ball.png" ALT="*">dull the image contrast
+<dd><img SRC="images/ball.png" ALT="*">perform histogram equalization on the image
+<dd><img SRC="images/ball.png" ALT="*">perform histogram normalization on the image
+<dd><img SRC="images/ball.png" ALT="*">negate the image colors
+<dd><img SRC="images/ball.png" ALT="*">convert the image to grayscale
+<dd><img SRC="images/ball.png" ALT="*">set the maximum number of unique colors in the image
+<dd><img SRC="images/ball.png" ALT="*">reduce the speckles within an image
+<dd><img SRC="images/ball.png" ALT="*">eliminate peak noise from an image
+<dd><img SRC="images/ball.png" ALT="*">detect edges within the image
+<dd><img SRC="images/ball.png" ALT="*">emboss an image
+<dd><img SRC="images/ball.png" ALT="*">segment the image by color
+<dd><img SRC="images/ball.png" ALT="*">simulate an oil painting
+<dd><img SRC="images/ball.png" ALT="*">simulate a charcoal drawing
+<dd><img SRC="images/ball.png" ALT="*">annotate the image with text
+<dd><img SRC="images/ball.png" ALT="*">draw on the image
+<dd><img SRC="images/ball.png" ALT="*">edit an image pixel color
+<dd><img SRC="images/ball.png" ALT="*">edit the image matte information
+<dd><img SRC="images/ball.png" ALT="*">composite an image with another
+<dd><img SRC="images/ball.png" ALT="*">add a border to the image
+<dd><img SRC="images/ball.png" ALT="*">surround image with an ornamental border
+<dd><img SRC="images/ball.png" ALT="*">apply image processing techniques to a region of interest
+<dd><img SRC="images/ball.png" ALT="*">display information about the image
+<dd><img SRC="images/ball.png" ALT="*">zoom a portion of the image
+<dd><img SRC="images/ball.png" ALT="*">show a histogram of the image
+<dd><img SRC="images/ball.png" ALT="*">display image to background of a window
+<dd><img SRC="images/ball.png" ALT="*">set user preferences
+<dd><img SRC="images/ball.png" ALT="*">display information about this program
+<dd><img SRC="images/ball.png" ALT="*">discard all images and exit program
+<dd><img SRC="images/ball.png" ALT="*">change the level of magnification
+<dd><img SRC="images/ball.png" ALT="*">display images specified by a World Wide Web (WWW) uniform resource locator (URL)
+</dl>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To scale an image of a cockatoo to exactly 640 pixels in width and 480
+pixels in height and position the window at location (200,200), use:
+<pre>
+ gm display -geometry 640x480+200+200! cockatoo.miff
+</pre>
+<p>
+To display an image of a cockatoo without a border centered on a backdrop,
+use:
+<pre>
+ gm display +borderwidth -backdrop cockatoo.miff
+</pre>
+<p>
+To tile a slate texture onto the root window, use:
+<pre>
+ gm display -size 1280x1024 -window root slate.png
+</pre>
+<p>
+To display a visual image directory of all your JPEG images, use:
+<pre>
+ gm display 'vid:*.jpg'
+</pre>
+<p>
+To display a MAP image that is 640 pixels in width and 480 pixels in height
+with 256 colors, use:
+<pre>
+ gm display -size 640x480+256 cockatoo.map
+</pre>
+<p>
+To display an image of a cockatoo specified with a <strong>World Wide Web (WWW)</strong>
+uniform resource locator <strong>(URL)</strong>, use:
+<pre>
+ gm display ftp://wizards.dupont.com/images/cockatoo.jpg
+</pre>
+<p>
+To display histogram of an image, use:
+<pre>
+ gm gm convert file.jpg HISTOGRAM:- | gm display -
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect. For example to display three images,
+the first with 32 colors, the second with an unlimited number of colors,
+and the third with only 16 colors, use:
+<pre>
+ gm display -colors 32 cockatoo.miff -noop duck.miff -colors 16 macaw.miff
+</pre>
+<p>
+<strong>Display</strong> options can appear on the command line or in your X resources
+file. See <em>X(1)</em>. Options on the command line supersede values specified
+in your X resources file.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-backdrop">-backdrop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the image centered on a backdrop.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-border">-border</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with a border of color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -borderwidth <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colormap">-colormap</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the colormap type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-contrast">-contrast</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enhance or reduce the image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -despeckle
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>reduce the speckles within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -edge <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>detect edges within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -enhance
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a digital filter to enhance a noisy image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flip">-flip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flop">-flop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-foreground">-foreground</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the foreground color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-frame">-frame</a> <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-iconGeometry">-iconGeometry</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the icon geometry</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -iconic
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>iconic animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -immutable
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image immutable</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-map">-map</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display image using this type.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -name
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+progress">+progress</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>disable progress monitor and busy cursor</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-raise">-raise</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>lighten or darken image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-remote">-remote</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform a X11 remote operation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-roll">-roll</a> <i></i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>roll an image vertically or horizontally</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sample">-sample</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale image using pixel sampling</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scenes">-scenes</a> <i>&lt;value-value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>range of image scene numbers to read</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-segment">-segment</a> <i>&lt;cluster threshold&gt;x&lt;smoothing threshold&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>segment an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shared-memory">-shared-memory</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use shared memory</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-text-font">-text-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>font for writing fixed-width text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-title">-title</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign title to displayed image [<em>animate, display, montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-update">-update</a> <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+detect when image file is modified and redisplay.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -use-pixmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use the pixmap</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-visual">-visual</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>animate images using this X visual type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-window">-window</a> <i>&lt;id&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image the background of a window</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -window-group
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the window group</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-write">-write</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write the image to a file [<em>display</em>]</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-mous"></a>Mouse Buttons
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The effects of each button press is described below. Three buttons are
+required. If you have a two button mouse, button 1 and 3 are returned.
+Press <strong>ALT</strong> and button 3 to simulate button 2.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ 1
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Press this button to map or unmap the <a href="#disp-comm">Command
+widget</a> . See the next section for more information about the Command
+widget.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ 2
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Press and drag to define a region of the image to magnify.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ 3
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Press and drag to choose from a select set of <strong>display(1)</strong>
+commands. This button behaves differently if the image being displayed
+is a visual image directory. Choose a particular tile of the directory
+and press this button and drag to select a command from a pop-up menu.
+Choose from these menu items:</td></tr></table>
+<ul>
+<li>Open
+<li>Next
+<li>Former
+<li>Delete
+<li>Update
+</ul>
+<p>
+If you choose <strong>Open</strong>, the image represented by the tile is displayed.
+To return to the visual image directory, choose <strong>Next</strong> from the Command
+widget (refer to <a href="#disp-comm">Command Widget</a>).
+<strong>Next</strong> and <strong>Former</strong>
+moves to the next or former image respectively. Choose <strong>Delete</strong> to
+delete a particular image tile. Finally, choose <strong>Update</strong> to synchronize
+all the image tiles with their respective images. See
+<a href="montage.html">montage</a>
+and
+<a href="miff.html">miff</a> for more details.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-comm"></a>Command Widget
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The Command widget lists a number of sub-menus and commands. They are
+<ul>
+<li><strong>File</strong>
+<ul>
+<li>Open...
+<li>Next
+<li>Former
+<li>Select...
+<li>Save...
+<li>Print...
+<li>Delete...
+<li>Canvas...
+<li>Visual Directory...
+<li>Quit
+</ul>
+</ul>
+<ul>
+<li><strong>Edit</strong>
+<ul>
+<li>Undo
+<li>Redo
+<li>Cut
+<li>Copy
+<li>Paste
+</ul>
+</ul>
+<ul>
+<li><strong>View</strong>
+<ul>
+<li>Half Size
+<li>Original Size
+<li>Double Size
+<li>Resize...
+<li>Apply
+<li>Refresh
+<li>Restore
+</ul>
+</ul>
+<ul>
+<li><strong>Transform</strong>
+<ul>
+<li>Crop
+<li>Chop
+<li>Flop
+<li>Flip
+<li>Rotate Right
+<li>Rotate Left
+<li>Rotate...
+<li>Shear...
+<li>Roll...
+<li>Trim Edges
+</ul>
+</ul>
+<ul>
+<li><strong>Enhance</strong>
+<ul>
+<li>Hue...
+<li>Saturation...
+<li>Brightness...
+<li>Gamma...
+<li>Spiff...
+<li>Dull
+<li>Equalize
+<li>Normalize
+<li>Negate
+<li>GRAYscale
+<li>Quantize...
+</ul>
+</ul>
+<ul>
+<li><strong>Effects</strong>
+<ul>
+<li>Despeckle
+<li>Emboss
+<li>Reduce Noise
+<li>Add Noise
+<li>Sharpen...
+<li>Blur...
+<li>Threshold...
+<li>Edge Detect...
+<li>Spread...
+<li>Shade...
+<li>Raise...
+<li>Segment...
+</ul>
+</ul>
+<ul>
+<li><strong>F/X</strong>
+<ul>
+<li>Solarize...
+<li>Swirl...
+<li>Implode...
+<li>Wave...
+<li>Oil Paint...
+<li>Charcoal Draw...
+</ul>
+</ul>
+<ul>
+<li><strong>Image Edit</strong>
+<ul>
+<li>Annotate...
+<li>Draw...
+<li>Color...
+<li>Matte...
+<li>Composite...
+<li>Add Border...
+<li>Add Frame...
+<li>Comment...
+<li>Launch...
+<li>Region of Interest...
+</ul>
+</ul>
+<ul>
+<li><strong>Miscellany</strong>
+<ul>
+<li>Image Info
+<li>Zoom Image
+<li>Show Preview...
+<li>Show Histogram
+<li>Show Matte
+<li>Background...
+<li>Slide Show
+<li>Preferences...
+</ul>
+</ul>
+<ul>
+<li><strong>Help</strong>
+<ul>
+<li>Overview
+<li>Browse Documentation
+<li>About Display
+</ul>
+</ul>
+<p>
+Menu items with a indented triangle have a sub-menu. They are represented
+above as the indented items. To access a sub-menu item, move the pointer
+to the appropriate menu and press button 1 and drag. When you find the
+desired sub-menu item, release the button and the command is executed.
+Move the pointer away from the sub-menu if you decide not to execute a
+particular command.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-keyb"></a>Keyboard Accelerators
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Accelerators are one or two key presses that effect a particular command.
+The keyboard accelerators that
+<strong>display</strong> understands is:
+<pre>
+ Ctl+O Press to <a href="#disp-imlo">load</a> an image from a file.
+ space Press to display the next image.
+</pre>
+<p>
+If the image is a multi-paged document such as a
+<em>PostScript</em> document,
+you can skip ahead several pages by preceding this command with a number.
+For example to display the fourth page beyond the current page,
+press <tt>4space</tt>.
+<pre>
+ backspace Press to display the former image.
+</pre>
+<p>
+If the image is a multi-paged document such as a
+<em>PostScript</em> document,
+you can skip behind several pages by preceding this command with a number.
+For example to display the fourth page preceding the current page, press
+4n.
+<pre>
+ Ctl-S Press to save the image to a file.
+ Ctl-P Press to print the image to a
+ <em>PostScript</em> printer.
+ Ctl-D Press to delete an image file.
+ Ctl-N Press to create a blank canvas.
+ Ctl-Q Press to discard all images and exit program.
+ Ctl+Z Press to undo last image transformation.
+ Ctl+R Press to redo last image transformation.
+ Ctl-X Press to <a href="#disp-imcu">cut</a> a region of
+ the image.
+ Ctl-C Press to <a href="#disp-imco">copy</a> a region of
+ the image.
+ Ctl-V Press to <a href="#disp-impa">paste</a> a region to
+ the image.
+ &lt; Press to halve the image size.
+ . Press to return to the original image size.
+ &gt; Press to double the image size.
+ % Press to resize the image to a width and height
+ you specify.
+ Cmd-A Press to make any image transformations
+ permanent.
+ By default, any image size transformations are
+ applied to the original image to create the
+ image displayed on the X server. However, the
+ transformations are not permanent (i.e. the
+ original image does not change size only the
+ X image does). For example, if you press "&gt;"
+ the X image will appear to double in size, but
+ the original image will in fact remain the same
+ size. To force the original image to double in
+ size, press "&gt;" followed by "Cmd-A".
+ @ Press to refresh the image window.
+ C Press to <a href="#disp-imcr">crop</a> the image.
+ [ Press to <a href="#disp-imch">chop</a> the image.
+ H Press to flop image in the horizontal direction.
+ V Press to flip image in the vertical direction.
+ / Press to rotate the image 90 degrees clockwise.
+ \ Press to rotate the image 90 degrees
+ counter-clockwise.
+ * Press to <a href="#disp-imro">rotate</a> the image
+ the number of degrees you specify.
+ S Press to shear the image the number of degrees
+ you specify.
+ R Press to roll the image.
+ T Press to trim the image edges.
+ Shft-H Press to vary the color hue.
+ Shft-S Press to vary the color saturation.
+ Shft-L Press to vary the image brightness.
+ Shft-G Press to gamma correct the image.
+ Shft-C Press to spiff up the image contrast.
+ Shft-Z Press to dull the image contrast.
+ = Press to perform histogram equalization on
+ the image.
+ Shft-N Press to perform histogram normalization on
+ the image.
+ Shft-~ Press to negate the colors of the image.
+ . Press to convert the image colors to gray.
+ Shft-# Press to set the maximum number of unique
+ colors in the image.
+ F2 Press to reduce the speckles in an image.
+ F2 Press to emboss an image.
+ F4 Press to eliminate peak noise from an image.
+ F5 Press to add noise to an image.
+ F6 Press to sharpen an image.
+ F7 Press to blur image an image.
+ F8 Press to threshold the image.
+ F9 Press to detect edges within an image.
+ F10 Press to displace pixels by a random amount.
+ F11 Press to shade the image using a distant light
+ source.
+ F12 Press to lighten or darken image edges to
+ create a 3-D effect.
+ F13 Press to segment the image by color.
+ Meta-S Press to swirl image pixels about the center.
+ Meta-I Press to implode image pixels about the center.
+ Meta-W Press to alter an image along a sine wave.
+ Meta-P Press to simulate an oil painting.
+ Meta-C Press to simulate a charcoal drawing.
+ Alt-X Press to <a href="#disp-imcomp">composite</a> the image
+ with another.
+ Alt-A Press to <a href="#disp-iman">annotate</a> the image with text.
+ Alt-D Press to <a href="#disp-imdr">draw</a> a line on the image.
+ Alt-P Press to <a href="#disp-cole">edit an image pixel color</a>.
+ Alt-M Press to <a href="#disp-matt">edit the image matte</a> information.
+ Alt-X Press to <a href="#disp-imcomp">composite</a> the image with another.
+ Alt-A Press to add a border to the image.
+ Alt-F Press to add a ornamental frame to the image.
+ Alt-Shft-! Press to add an image comment.
+ Ctl-A Press to apply image processing techniques to a
+ region of interest.
+ Shft-? Press to display information about the image.
+ Shft-+ Press to map the zoom image window.
+ Shft-P Press to preview an image enhancement, effect,
+ or f/x.
+ F1 Press to display helpful information about
+ the "display" utility.
+ Find Press to browse documentation about
+ GraphicsMagick.
+ 1-9 Press to change the level of magnification.
+</pre>
+<p>
+Use the arrow keys to move the image one pixel up, down, left, or right
+within the magnify window. Be sure to first map the magnify window by pressing
+button 2.
+<p>
+Press ALT and one of the arrow keys to trim off one pixel from any side
+of the image.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-xres"></a>X Resources
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Display</strong> options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See <em>X(1)</em> for more information on X resources.
+<p>
+Most <strong>display</strong> options have a corresponding X resource. In addition,
+<strong>display</strong>
+uses the following X resources:
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ background <i>(class Background)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred color to use for the Image window background. The
+default is #ccc.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ borderColor <i>(class BorderColor)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred color to use for the Image window border. The default
+is #ccc.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ borderWidth <i>(class BorderWidth)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the width in pixels of the image window border. The default is
+2.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ browseCommand <i>(class browseCommand)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the name of the preferred browser when displaying GraphicsMagick
+documentation. The default is <tt>netscape %s</tt>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ confirmExit <i>(class ConfirmExit)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+<strong>Display</strong> pops up a dialog box to confirm exiting the program when
+exiting the program. Set this resource to <tt>False</tt> to exit without
+a confirmation.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ displayGamma <i>(class DisplayGamma)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the gamma of the X server.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+You can apply separate gamma values to the red, green, and blue channels
+of the image with a gamma value list delineated with slashes (i.e. 1.7/2.3/1.2).</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The default is 2.2.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ displayWarnings <i>(class DisplayWarnings)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+<strong>Display</strong> pops up a dialog box whenever a warning message occurs.
+Set this resource to <tt>False</tt> to ignore warning messages.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ font <i>(class FontList)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the name of the preferred font to use in normal formatted text.
+The default is 14 point Helvetica.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ font[1-9] <i>(class Font[1-9])</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the name of the preferred font to use when
+<a href="#disp-iman">annotating</a>
+the image window with text. The default fonts are fixed, variable, 5x8,
+6x10, 7x13bold, 8x13bold, 9x15bold, 10x20, and 12x24.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ foreground <i>(class Foreground)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred color to use for text within the image window.
+The default is black.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ gammaCorrect <i>(class gammaCorrect)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource, if true, will lighten or darken an image of known gamma
+to match the gamma of the display (see resource <strong>displayGamma</strong>). The
+default is True.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ geometry <i>(class Geometry)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred size and position of the image window. It is not
+necessarily obeyed by all window managers.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Offsets, if present, are handled in <em>X(1)</em> style. A negative x offset is
+measured from the right edge of the screen to the right edge of the icon,
+and a negative y offset is measured from the bottom edge of the screen
+to the bottom edge of the icon.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ iconGeometry <i>(class IconGeometry)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred size and position of the application when iconified.
+It is not necessarily obeyed by all window managers.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Offsets, if present, are handled in the same manner as in class Geometry.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ iconic <i>(class Iconic)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource indicates that you would prefer that the application's windows
+initially not be visible as if the windows had be immediately iconified
+by you. Window managers may choose not to honor the application's request.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ magnify <i>(class Magnify)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+specifies an integral factor by which the image should be enlarged. The
+default is 3.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This value only affects the magnification window which is invoked with
+<a href="#disp-mous">button</a>
+number 3 after the image is displayed.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ matteColor <i>(class MatteColor)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specify the color of windows. It is used for the backgrounds of windows,
+menus, and notices. A 3D effect is achieved by using highlight and shadow
+colors derived from this color. Default value: #697B8F.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ name <i>(class Name)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource specifies the name under which resources for the application
+should be found. This resource is useful in shell aliases to distinguish
+between invocations of an application, without resorting to creating links
+to alter the executable file name. The default is the application name.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ pen[1-9] <i>(class Pen[1-9])</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the color of the preferred font to use when
+<a href="#disp-iman">annotating</a>
+the image window with text. The default colors are black, blue, green,
+cyan, gray, red, magenta, yellow, and white.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ printCommand <i>(class PrintCommand)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This command is executed whenever Print is issued. In general, it is the
+command to print <em>PostScript</em> to your printer. Default value: <tt>lp
+-c -s %i</tt>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ sharedMemory <i>(class SharedMemory)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource specifies whether display should attempt use shared memory
+for pixmaps. GraphicsMagick must be compiled with shared memory support,
+and the display must support the MIT-SHM extension. Otherwise, this
+resource is ignored. The default is True.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ textFont <i>(class textFont)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point Courier.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ title <i>(class Title)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource specifies the title to be used for the image window. This
+information is sometimes used by a window manager to provide a header identifying
+the window. The default is the image file name.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ undoCache <i>(class UndoCache)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies, in mega-bytes, the amount of memory in the undo edit cache.
+Each time you modify the image it is saved in the undo edit cache as long
+as memory is available. You can subsequently <em>undo</em> one or more of
+these transformations. The default is 16 Megabytes.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ usePixmap <i>(class UsePixmap)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Images are maintained as a XImage by default. Set this resource to True
+to utilize a server Pixmap instead. This option is useful if your image
+exceeds the dimensions of your server screen and you intend to pan the
+image. Panning is much faster with Pixmaps than with a XImage. Pixmaps
+are considered a precious resource, use them with discretion.</td></tr></table>
+<p>
+To set the geometry of the Magnify or Pan or window, use the geometry resource.
+For example, to set the Pan window geometry to 256x256, use:
+<pre>
+ gm display.pan.geometry: 256x256
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imlo"></a>Image Loading
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To select an image to display, choose <strong>Open</strong> of the <strong>File</strong> sub-menu
+from the <a href="#disp-comm">Command widget</a>. A file browser is displayed.
+To choose a particular image file, move the pointer to the filename and
+press any button. The filename is copied to the text window. Next, press
+<strong>Open</strong>
+or press the <strong>RETURN</strong> key. Alternatively, you can type the image file
+name directly into the text window. To descend directories, choose a directory
+name and press the button twice quickly. A scrollbar allows a large list
+of filenames to be moved through the viewing area if it exceeds the size
+of the list area.
+<p>
+You can trim the list of file names by using shell globbing characters.
+For example, type <tt>*.jpg</tt> to list only files that end
+with <tt>.jpg</tt>.
+<p>
+To select your image from the X server screen instead of from a file, Choose
+<strong>Grab</strong> of the <strong>Open</strong> widget.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-visu"></a>Visual Image Directory
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To create a Visual Image Directory, choose Visual Directory of the <strong>File</strong>
+sub-menu from the <a href="#disp-comm">Command widget</a> . A file browser is
+displayed. To create a Visual Image Directory from all the images in the
+current directory, press <strong>Directory</strong> or press the <strong>RETURN key</strong>.
+Alternatively, you can select a set of image names by using shell globbing
+characters. For example, type <tt>*.jpg</tt> to include only files that
+end with <tt>.jpg</tt>. To descend directories, choose a directory name
+and press the button twice quickly. A scrollbar allows a large list of
+filenames to be moved through the viewing area if it exceeds the size of
+the list area.
+<p>
+After you select a set of files, they are turned into thumbnails and tiled
+onto a single image. Now move the pointer to a particular thumbnail and
+press <strong>button 3</strong> and drag. Finally, select Open. The image represented
+by the thumbnail is displayed at its full size. Choose <strong>Next</strong> from
+the <strong>File</strong> sub-menu of the Command widget to return to the Visual
+Image Directory.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imcu"></a>Image Cutting
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Note that cut information for image window is not retained for colormapped
+X server visuals (e.g. <em>StaticColor</em>,
+<em>StaticColor</em>, <em>GRAYScale</em>,
+<em>PseudoColor</em>).
+Correct cutting behavior may require a <em>TrueColor</em> or <em>DirectColor</em>
+visual or a <em>Standard Colormap</em>.
+<p>
+To begin, press choose <strong>Cut</strong> of the <strong>Edit</strong> sub-menu from the
+<a href="#disp-comm">Command
+widget</a>. Alternatively, press
+<strong>F3</strong> in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in cut mode. In cut mode, the Command widget has these
+options:
+<ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+To define a cut region, press button 1 and drag. The cut region is defined
+by a highlighted rectangle that expands or contracts as it follows the
+pointer. Once you are satisfied with the cut region, release the button.
+You are now in rectify mode. In rectify mode, the Command widget has these
+options:
+<ul>
+<li><strong>Cut</strong>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+You can make adjustments by moving the pointer to one of the cut rectangle
+corners, pressing a button, and dragging. Finally, press Cut to commit
+your copy region. To exit without cutting the image, press Dismiss.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imco"></a>Image Copying
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To begin, press choose <strong>Copy</strong> of the <strong>Edit</strong> sub-menu from the
+<a href="#disp-comm">Command
+widget</a>. Alternatively, press
+<strong>F4</strong> in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in copy mode. In copy mode, the Command widget has
+these options:
+<ul>
+<li>Help
+<li>Dismiss
+</ul>
+<p>
+To define a copy region, press button 1 and drag. The copy region is defined
+by a highlighted rectangle that expands or contracts as it follows the
+pointer. Once you are satisfied with the copy region, release the button.
+You are now in rectify mode. In rectify mode, the Command widget has these
+options:
+<ul>
+<li>Copy
+<li>Help
+<li>Dismiss
+</ul>
+<p>
+You can make adjustments by moving the pointer to one of the copy rectangle
+corners, pressing a button, and dragging. Finally, press Copy to commit
+your copy region. To exit without copying the image, press Dismiss.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-impas"></a>Image Pasting
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To begin, press choose <strong>Paste</strong> of the <strong>Edit</strong> sub-menu from the
+<a href="#disp-comm">Command
+widget</a>. Alternatively, press
+<strong>F5</strong> in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in Paste mode. To exit immediately, press Dismiss.
+In Paste mode, the Command widget has these options:
+<ul>
+<li><strong>Operators</strong>
+<ul>
+<li>over
+<li>in
+<li>out
+<li>atop
+<li>xor
+<li>plus
+<li>minus
+<li>add
+<li>subtract
+<li>difference
+<li>multiply
+<li>bumpmap
+<li>replace
+</ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+Choose a composite operation from the <strong>Operators</strong> sub-menu of the
+<a href="#disp-comm">Command
+widget</a>. How each operator behaves is described below. <em>image window</em>
+is the image currently displayed on your X server and <em>image</em> is the
+image obtained with the File Browser widget.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ over
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the union of the two image shapes, with <em>image</em> obscuring
+<em>image
+window</em> in the region of overlap.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ in
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is simply <em>image</em> cut by the shape of
+<em>image window</em>.
+None of the image data of image window is in the result.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ out
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The resulting image is <em>image</em> with the shape of
+<em>image window</em>
+cut out.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ atop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the same shape as <em>image window</em>, with
+<em>image</em>
+obscuring <em>image window</em> where the image shapes overlap. Note this
+differs from over because the portion of image outside
+<em>image window</em>'s
+shape does not appear in the result.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ xor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the image data from both <em>image</em> and
+<em>image window</em>
+that is outside the overlap region. The overlap region is blank.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ plus
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is just the sum of the image data. Output values are cropped
+to the maximum value (no overflow). This operation is independent of the
+matte channels.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ minus
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> - <em>image window</em>, with underflow cropped
+to zero. The matte channel is ignored (set to opaque, full coverage).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ add
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> + <em>image window</em>, with overflow wrapping
+around (mod MaxRGB+1).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ subtract
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> - <em>image window</em>, with underflow wrapping
+around (mod MaxRGB+1). The add and subtract operators can be used to perform
+reversible transformations.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ difference
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of abs(<em>image</em> - <em>image window</em>). This is useful for
+comparing two very similar images.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ multiply
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> * <em>image window</em>. This is useful for
+the creation of drop-shadows.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ bumpmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image window</em> shaded by <em>window</em>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ replace
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>The resulting image is <em>image window</em> replaced with
+<em>image</em>.
+Here the matte information is ignored.</td></tr></table>
+<p>
+The image compositor requires a matte, or alpha channel in the image for
+some operations. This extra channel usually defines a mask which represents
+a sort of a cookie-cutter for the image. This is the case when matte is
+255 (full coverage) for pixels inside the shape, zero outside, and between
+zero and 255 on the boundary. If image does not have a matte channel, it
+is initialized with 0 for any pixel matching in color to pixel location
+(0,0), otherwise 255. See <a href="#disp-matt">Matte Editing</a> for a method
+of defining a matte channel.
+<p>
+Note that matte information for image window is not retained for colormapped
+X server visuals (e.g. <em>StaticColor, StaticColor, GrayScale, PseudoColor</em>).
+Correct compositing behavior may require a
+<em>TrueColor</em> or <em>DirectColor</em>
+visual or a <em>Standard Colormap</em>.
+<p>
+Choosing a composite operator is optional. The default operator is replace.
+However, you must choose a location to composite your image and press button
+1. Press and hold the button before releasing and an outline of the image
+will appear to help you identify your location.
+<p>
+The actual colors of the pasted image is saved. However, the color that
+appears in image window may be different. For example, on a monochrome
+screen image window will appear black or white even though your pasted
+image may have many colors. If the image is saved to a file it is written
+with the correct colors. To assure the correct colors are saved in the
+final image, any <em>PseudoClass</em> image is promoted to <em>DirectClass</em>.
+To force a
+<em>PseudoClass</em> image to remain <em>PseudoClass</em>,
+use <strong>-colors</strong>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imcr"></a>Image Cropping
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To begin, press choose <strong>Crop</strong> of the <strong>Transform</strong> submenu from
+the <a href="#disp-comm">Command widget</a>. Alternatively,
+<a href="#disp-keyb">press</a> C in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in crop mode. In crop mode, the Command widget has
+these options:
+<ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+To define a cropping region, press button 1 and drag. The cropping region
+is defined by a highlighted rectangle that expands or contracts as it follows
+the pointer. Once you are satisfied with the cropping region, release the
+button. You are now in rectify mode. In rectify mode, the Command widget
+has these options:
+<ul>
+<li><strong>Crop</strong>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+You can make adjustments by moving the pointer to one of the cropping rectangle
+corners, pressing a button, and dragging. Finally, press Crop to commit
+your cropping region. To exit without cropping the image, press Dismiss.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imch"></a>Image Chopping
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+An image is chopped interactively. There is no command line argument to
+chop an image. To begin, choose <strong>Chop</strong> of the <strong>Transform</strong> sub-menu
+from the <a href="#disp-comm">Command widget</a>. Alternatively,
+<a href="#disp-keyb">press</a> [ in the Image window.
+<p>
+You are now in <strong>Chop</strong> mode. To exit immediately, press
+<strong>Dismiss</strong>.
+In Chop mode, the Command widget has these options:
+<ul>
+<li><strong>Direction</strong>
+<ul>
+<li>horizontal
+<li>vertical
+</ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+If the you choose the horizontal direction (this is the default), the area
+of the image between the two horizontal endpoints of the chop line is removed.
+Otherwise, the area of the image between the two vertical endpoints of
+the chop line is removed.
+<p>
+Select a location within the image window to begin your chop, press and
+hold any button. Next, move the pointer to another location in the image.
+As you move a line will connect the initial location and the pointer. When
+you release the button, the area within the image to chop is determined
+by which direction you choose from the Command widget.
+<p>
+To cancel the image chopping, move the pointer back to the starting point
+of the line and release the button.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imro"></a>Image Rotation
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Press the / key to rotate the image 90 degrees or \ to rotate -90 degrees.
+To interactively choose the degree of rotation, choose
+<strong>Rotate...</strong>
+of the <strong>Transform</strong> submenu from the <a href="#disp-comm">Command Widget</a>.
+Alternatively, <a href="#disp-keyb">press</a> * in the image window.
+<p>
+A small horizontal line is drawn next to the pointer. You are now in rotate
+mode. To exit immediately, press Dismiss. In rotate mode, the Command widget
+has these options:
+<ul>
+<li><strong>Pixel Color</strong>
+<ul>
+<li>black
+<li>blue
+<li>cyan
+<li>green
+<li>gray
+<li>red
+<li>magenta
+<li>yellow
+<li>white
+<li>Browser...
+</ul>
+<li><strong>Direction</strong>
+<ul>
+<li>horizontal
+<li>vertical
+</ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+Choose a background color from the Pixel Color sub-menu. Additional background
+colors can be specified with the color browser. You can change the menu
+colors by setting the <a href="#disp-xres">X resources</a> pen1 through pen9.
+<p>
+If you choose the color browser and press <strong>Grab</strong>, you can select the
+background color by moving the pointer to the desired color on the screen
+and press any button.
+<p>
+Choose a point in the image window and press this button and hold. Next,
+move the pointer to another location in the image. As you move a line connects
+the initial location and the pointer. When you release the button, the
+degree of image rotation is determined by the slope of the line you just
+drew. The slope is relative to the direction you choose from the Direction
+sub-menu of the Command widget.
+<p>
+To cancel the image rotation, move the pointer back to the starting point
+of the line and release the button.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-segm"></a>Image Segmentation
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Choose <strong>Effects-&gt;Segment</strong> to segment an image by analyzing the histograms
+of the color components and identifying units that are homogeneous with
+the fuzzy c-means technique. The scale-space filter analyzes the histograms
+of the three color components of the image and identifies a set of classes.
+The extents of each class is used to coarsely segment the image with thresholding.
+The color associated with each class is determined by the mean color of
+all pixels within the extents of a particular class. Finally, any unclassified
+pixels are assigned to the closest class with the fuzzy c-means technique.
+<p>The fuzzy c-Means algorithm can be summarized as follows:
+<ul>
+<li>
+Build a histogram, one for each color component of the image.
+<li>
+For each histogram, successively apply the scale-space filter and build
+an interval tree of zero crossings in the second derivative at each scale.
+Analyze this scale-space "fingerprint" to determine which peaks or valleys
+in the histogram are most predominant.
+<li>
+The fingerprint defines intervals on the axis of the histogram. Each interval
+contains either a minima or a maxima in the original signal. If each color
+component lies within the maxima interval, that pixel is considered "classified"
+and is assigned an unique class number.
+<li>
+Any pixel that fails to be classified in the above thresholding pass is
+classified using the fuzzy c-Means technique. It is assigned to one of
+the classes discovered in the histogram analysis phase.
+</ul>
+<p>
+The fuzzy c-Means technique attempts to cluster a pixel by finding the
+local minima of the generalized within group sum of squared error objective
+function. A pixel is assigned to the closest class of which the fuzzy membership
+has a maximum value.
+<p>
+For additional information see:
+<blockquote><em>Young Won Lim, Sang Uk Lee</em>, "<strong>On The Color Image Segmentation
+Algorithm Based on the Thresholding and the Fuzzy c-Means Techniques</strong>",
+Pattern Recognition, Volume 23, Number 9, pages 935-952, 1990.</blockquote>
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-iman"></a>Image Annotation
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+An image is annotated interactively. There is no command line argument
+to annotate an image. To begin, choose
+<strong>Annotate</strong> of the <strong>Image
+Edit</strong> sub-menu from the <a href="#disp-comm">Command widget</a>. Alternatively,
+<a href="#disp-keyb">press</a> a in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in annotate mode. To exit immediately, press Dismiss.
+In annotate mode, the Command widget has these options:
+<ul>
+<li>
+<strong>Font Name</strong>
+<ul>
+<li>
+fixed
+<li>
+variable
+<li>
+5x8
+<li>
+6x10
+<li>
+7x13bold
+<li>
+8x13bold
+<li>
+9x15bold
+<li>
+10x20
+<li>
+12x24
+<li>
+Browser...
+</ul>
+<li>
+<strong>Font Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+transparent
+<li>
+Browser...
+</ul>
+<li>
+<strong>Box Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+transparent
+<li>
+Browser...
+</ul>
+<li>
+<strong>Rotate Text</strong>
+<ul>
+<li>
+-90
+<li>
+-45
+<li>
+-30
+<li>
+0
+<li>
+30
+<li>
+45
+<li>
+90
+<li>
+180
+<li>
+Dialog...
+</ul>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+Choose a font name from the <strong>Font Name</strong> sub-menu. Additional font
+names can be specified with the font browser. You can change the menu names
+by setting the <a href="#disp-xres">X resources</a> font1 through font9.
+<p>
+Choose a font color from the <strong>Font Color</strong> sub-menu. Additional font
+colors can be specified with the color browser. You can change the menu
+colors by setting the <a href="#disp-xres">X resources</a> pen1 through pen9.
+<p>
+If you select the color browser and press <strong>Grab</strong>, you can choose the
+font color by moving the pointer to the desired color on the screen and
+press any button.
+<p>
+If you choose to rotate the text, choose <strong>Rotate Text</strong> from the menu
+and select an angle. Typically you will only want to rotate one line of
+text at a time. Depending on the angle you choose, subsequent lines may
+end up overwriting each other.
+<p>
+Choosing a font and its color is optional. The default font is fixed and
+the default color is black. However, you must choose a location to begin
+entering text and press a button. An underscore character will appear at
+the location of the pointer. The cursor changes to a pencil to indicate
+you are in text mode. To exit immediately, press Dismiss.
+<p>
+In text mode, any key presses will display the character at the location
+of the underscore and advance the underscore cursor. Enter your text and
+once completed press Apply to finish your image annotation. To correct
+errors press <strong>BACK SPACE</strong>. To delete an entire line of text, press
+<strong>DELETE</strong>.
+Any text that exceeds the boundaries of the image window is automatically
+continued onto the next line.
+<p>
+The actual color you request for the font is saved in the image. However,
+the color that appears in your Image window may be different. For example,
+on a monochrome screen the text will appear black or white even if you
+choose the color red as the font color. However, the image saved to a file
+with <strong>-write</strong> is written with red lettering. To assure the correct
+color text in the final image, any <em>PseudoClass</em> image is promoted
+to <em>DirectClass</em> (see miff(5)). To force a <em>PseudoClass</em> image
+to remain
+<em>PseudoClass</em>, use <strong>-colors</strong>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imcomp"></a>Image Compositing
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+An image composite is created interactively. <strong>There is no command line
+argument to composite an image</strong>. To begin, choose <strong>Composite</strong> of
+the <strong>Image Edit</strong> from the <a href="#disp-comm">Command widget</a>. Alternatively,
+<a href="#disp-keyb">press</a> x in the Image window.
+<p>
+First a popup window is displayed requesting you to enter an image name.
+Press <strong>Composite</strong>, <strong>Grab</strong> or type a file name. Press <strong>Cancel</strong>
+if you choose not to create a composite image. When you choose <strong>Grab</strong>,
+move the pointer to the desired window and press any button.
+<p>
+If the <strong>Composite</strong> image does not have any matte information, you
+are informed and the file browser is displayed again. Enter the name of
+a mask image. The image is typically grayscale and the same size as the
+composite image. If the image is not grayscale, it is converted to grayscale
+and the resulting intensities are used as matte information.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in composite mode. To exit immediately, press Dismiss.
+In composite mode, the Command widget has these options:
+<ul>
+<li>
+<strong>Operators</strong>
+<ul>
+<li>
+over
+<li>
+in
+<li>
+out
+<li>
+atop
+<li>
+xor
+<li>
+plus
+<li>
+minus
+<li>
+add
+<li>
+subtract
+<li>
+difference
+<li>
+bumpmap
+<li>
+replace
+</ul>
+<li>
+<strong>Blend</strong>
+<li>
+<strong>Displace</strong>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+Choose a composite operation from the Operators sub-menu of the Command
+widget. How each operator behaves is described below. image window is the
+image currently displayed on your X server and image is the image obtained
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ over
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the union of the two image shapes, with <em>image</em> obscuring
+<em>image
+window</em> in the region of overlap.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ in
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is simply <em>image</em> cut by the shape of
+<em>image window</em>.
+None of the image data of image window is in the result.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ out
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The resulting image is <em>image</em> with the shape of
+<em>image window</em>
+cut out.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ atop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the same shape as <em>image window</em>, with
+<em>image</em>
+obscuring <em>image window</em> where the image shapes overlap. Note this
+differs from over because the portion of image outside
+<em>image window</em>'s
+shape does not appear in the result.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ xor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the image data from both <em>image</em> and
+<em>image window</em>
+that is outside the overlap region. The overlap region is blank.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ plus
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is just the sum of the image data. Output values are cropped
+to 255 (no overflow). This operation is independent of the matte channels.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ minus
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> - <em>image window</em>, with underflow cropped
+to zero. The matte channel is ignored (set to 255, full coverage).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ add
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> + <em>image window</em>, with overflow wrapping
+around (mod 256).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ subtract
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> - <em>image window</em>, with underflow wrapping
+around (mod 256). The add and subtract operators can be used to perform
+reversible transformations.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ difference
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of abs(<em>image</em> - <em>image window</em>). This is useful for
+comparing two very similar images.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ bumpmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image window</em> shaded by <em>window</em>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ replace
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The resulting image is <em>image window</em> replaced with
+<em>image</em>.
+Here the matte information is ignored.</td></tr></table>
+<p>
+The image compositor requires a matte, or alpha channel in the image for
+some operations. This extra channel usually defines a mask which represents
+a sort of a cookie-cutter for the image. This is the case when matte is
+255 (full coverage) for pixels inside the shape, zero outside, and between
+zero and 255 on the boundary. If image does not have a matte channel, it
+is initialized with 0 for any pixel matching in color to pixel location
+(0,0), otherwise 255. See <a href="#disp-matt">Matte Editing</a> for a method
+of defining a matte channel.
+<p>
+If you choose <strong>blend</strong>, the composite operator becomes <strong>over</strong>.
+The image matte channel percent transparency is initialized to factor.
+The image window is initialized to (100-factor). Where factor is the value
+you specify in the Dialog widget.
+<p>
+<strong>Displace</strong> shifts the image pixels as defined by a displacement map.
+With this option, <em>image</em> is used as a displacement map. Black, within
+the displacement map, is a maximum positive displacement. White is a maximum
+negative displacement and middle gray is neutral. The displacement is scaled
+to determine the pixel shift. By default, the displacement applies in both
+the horizontal and vertical directions. However, if you specify
+<em>mask</em>,
+<em>image</em>
+is the horizontal X displacement and
+<em>mask</em> the vertical Y displacement.
+<p>
+Note that matte information for image window is not retained for colormapped
+X server visuals (e.g.
+<em>StaticColor, StaticColor, GrayScale, PseudoColor</em>).
+Correct compositing behavior may require a <em>TrueColor</em> or
+<em>DirectColor</em>
+visual or a <em>Standard Colormap</em>.
+<p>
+Choosing a composite operator is optional. The default operator is replace.
+However, you must choose a location to composite your image and press button
+1. Press and hold the button before releasing and an outline of the image
+will appear to help you identify your location.
+<p>
+The actual colors of the composite image is saved. However, the color that
+appears in image window may be different. For example, on a monochrome
+screen Image window will appear black or white even though your composited
+image may have many colors. If the image is saved to a file it is written
+with the correct colors. To assure the correct colors are saved in the
+final image, any PseudoClass image is promoted to <em>DirectClass</em> (see
+<a href="miff.html">miff</a>).
+To force a <em>PseudoClass</em> image to remain <em>PseudoClass</em>,
+use <strong>-colors</strong>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-cole"></a>Color Editing
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Changing the the color of a set of pixels is performed interactively. There
+is no command line argument to edit a pixel. To begin, choose <strong>Color</strong>
+from the <strong>Image Edit</strong> submenu of the <a href="#disp-comm">Command widget</a>.
+Alternatively, <a href="#disp-keyb">press</a> c in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in color edit mode. To exit immediately, press <strong>Dismiss</strong>.
+In color edit mode, the
+<strong>Command widget</strong> has these options:
+<ul>
+<li>
+<strong>Method</strong>
+<ul>
+<li>
+point
+<li>
+replace
+<li>
+floodfill
+<li>
+reset
+</ul>
+<li>
+<strong>Pixel Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+Browser...
+</ul>
+<li>
+<strong>Border Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+Browser...
+</ul>
+<li>
+<strong>Fuzz</strong>
+<ul>
+<li>
+0
+<li>
+2
+<li>
+4
+<li>
+8
+<li>
+16
+<li>Dialog...
+</ul>
+<li>
+<strong>Undo</strong>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+Choose a color editing method from the <strong>Method</strong> sub-menu of
+the <a href="#disp-comm">Command
+widget</a>. The <strong>point method</strong> recolors any pixel selected with the
+pointer unless the button is released. The <strong>replace method</strong> recolors
+any pixel that matches the color of the pixel you select with a button
+press. <strong>Floodfill</strong> recolors any pixel that matches the color of the
+pixel you select with a button press and is a neighbor.
+Whereas <strong>filltoborder</strong>
+changes the matte value of any neighbor pixel that is not the border color.
+Finally <strong>reset</strong> changes the entire image to the designated color.
+<p>
+Next, choose a pixel color from the <strong>Pixel Color</strong> sub-menu. Additional
+pixel colors can be specified with the color browser. You can change the
+menu colors by setting the <a href="#disp-xres">X resources</a> pen1 through
+pen9.
+<p>
+Now press button 1 to select a pixel within the Image window to change
+its color. Additional pixels may be recolored as prescribed by the method
+you choose. additional pixels by increasing the Delta value.
+<p>
+If the <strong>Magnify widget</strong> is mapped, it can be helpful in positioning
+your pointer within the image (refer to button 2). Alternatively you can
+select a pixel to recolor from within the <strong>Magnify widget</strong>. Move the
+pointer to the <strong>Magnify widget</strong> and position the pixel with the cursor
+control keys. Finally, press a button to recolor the selected pixel (or
+pixels).
+<p>
+The actual color you request for the pixels is saved in the image. However,
+the color that appears in your Image window may be different. For example,
+on a monochrome screen the pixel will appear black or white even if you
+choose the color red as the pixel color. However, the image saved to a
+file with -write is written with red pixels. To assure the correct color
+text in the final image, any <em>PseudoClass</em> image is promoted
+to <em>DirectClass</em>
+To force a <em>PseudoClass</em> image to remain
+<em>PseudoClass</em>, use <strong>-colors</strong>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-matt"></a>Matte Editing
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Matte information within an image is useful for some operations such as
+image <a href="#disp-imcomp">compositing</a>. This extra channel usually defines
+a mask which represents a sort of a cookie-cutter for the image. This is
+the case when matte is 255 (full coverage) for pixels inside the shape,
+zero outside, and between zero and 255 on the boundary.
+<p>
+Setting the matte information in an image is done interactively. There
+is no command line argument to edit a pixel. To begin, and choose <strong>Matte</strong>
+of the <strong>Image Edit</strong> sub-menu from the <a href="#disp-comm">Command widget</a>.
+<p>
+Alternatively, <a href="#disp-keyb">press</a> m in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in matte edit mode. To exit immediately, press Dismiss.
+In matte edit mode, the Command widget has these options:
+<ul>
+<li>
+<strong>Method</strong>
+<ul>
+<li>
+point
+<li>
+replace
+<li>
+floodfill
+<li>
+reset
+</ul>
+<li>
+<strong>Border Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+Browser...
+</ul>
+<li>
+<strong>Fuzz</strong>
+<ul>
+<li>
+0
+<li>
+2
+<li>
+4
+<li>
+8
+<li>
+16
+<li>Dialog...
+</ul>
+<li>
+<strong>Matte</strong>
+<li>
+<strong>Undo</strong>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+Choose a matte editing method from the <strong>Method</strong> sub-menu of the <a href="#disp-comm">Command
+widget</a>. The <strong>point method</strong> changes the matte value of the any
+pixel selected with the pointer until the button is released. The <strong>replace
+method</strong> changes the matte value of any pixel that matches the color
+of the pixel you select with a button press. <strong>Floodfill</strong> changes the
+matte value of any pixel that matches the color of the pixel you select
+with a button press and is a neighbor. Whereas
+<strong>filltoborder</strong> recolors
+any neighbor pixel that is not the border color. Finally <strong>reset</strong> changes
+the entire image to the designated matte value.
+<p>Choose <strong>Matte Value</strong> and a dialog appears requesting a matte value.
+Enter a value between <strong>0 and 255</strong>. This value is assigned as the matte
+value of the selected pixel or pixels.
+<p>Now, press any button to select a pixel within the Image window to change
+its matte value. You can change the matte value of additional pixels by
+increasing the Delta value. The Delta value is first added then subtracted
+from the red, green, and blue of the target color. Any pixels within the
+range also have their matte value updated.
+<p>If the <strong>Magnify widget</strong> is mapped, it can be helpful in positioning
+your pointer within the image (refer to button 2). Alternatively you can
+select a pixel to change the matte value from within the
+<strong>Magnify widget</strong>.
+Move the pointer to the <strong>Magnify widget</strong> and position the pixel with
+the cursor control keys. Finally, press a button to change the matte value
+of the selected pixel (or pixels).
+<p>Matte information is only valid in a <em>DirectClass image</em>. Therefore,
+any <em>PseudoClass</em> image is promoted to
+<em>DirectClass</em>. Note that
+matte information for <em>PseudoClass</em> is not retained for colormapped
+X server visuals (e.g. <em>StaticColor, StaticColor, GrayScale, PseudoColor</em>)
+unless you immediately save your image to a file (refer to Write). Correct
+matte editing behavior may require a <em>TrueColor</em> or <em>DirectColor</em>
+visual or a <em>Standard Colormap</em>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imdr"></a>Image Drawing
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+An image is drawn upon interactively. <strong>There is no command line argument
+to draw on an image</strong>. To begin, choose <strong>Draw</strong> of the Image <strong>Edit</strong>
+sub-menu from the <a href="#disp-comm">Command widget</a>.
+Alternatively, <a href="#disp-keyb">press</a> d in the image window.
+<p>
+The cursor changes to a crosshair to indicate you are in draw mode. To
+exit immediately, press Dismiss. In draw mode, the Command widget has these
+options:
+<ul>
+<li>
+<strong>Primitive</strong>
+<ul>
+<li>
+point
+<li>
+line
+<li>
+rectangle
+<li>
+fill rectangle
+<li>
+circle
+<li>
+fill circle
+<li>
+ellipse
+<li>
+fill ellipse
+<li>
+polygon
+<li>
+fill polygon
+</ul>
+<li>
+<strong>Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+transparent
+<li>
+Browser...
+</ul>
+<li>
+<strong>Stipple</strong>
+<ul>
+<li>
+Brick
+<li>
+Diagonal
+<li>
+Scales
+<li>
+Vertical
+<li>
+Wavy
+<li>
+Translucent
+<li>
+Opaque
+<li>
+Open...
+</ul>
+<li>
+<strong>Width</strong>
+<ul>
+<li>
+1
+<li>
+2
+<li>
+4
+<li>
+8
+<li>
+16
+<li>Dialog...
+</ul>
+<li>
+<strong>Undo</strong>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+Choose a drawing primitive from the <strong>Primitive</strong> sub-menu.
+<p>
+Next, choose a color from the <strong>Color</strong> sub-menu. Additional colors
+can be specified with the color browser. You can change the menu colors
+by setting the <a href="#disp-xres">X resources</a> pen1 through pen9. The transparent
+color updates the image matte channel and is useful for image compositing.
+<p>
+If you choose the color browser and press <strong>Grab</strong>, you can select the
+primitive color by moving the pointer to the desired color on the screen
+and press any button. The transparent color updates the image matte channel
+and is useful for image compositing.
+<p>
+Choose a stipple, if appropriate, from the <strong>Stipple</strong> sub-menu. Additional
+stipples can be specified with the file browser. Stipples obtained from
+the file browser must be on disk in the X11 bitmap format.
+<p>
+Choose a line width, if appropriate, from the <strong>Width</strong> sub-menu. To
+choose a specific width select the <strong>Dialog</strong> widget.
+<p>
+Choose a point in the image window and press button 1 and hold. Next, move
+the pointer to another location in the image. As you move, a line connects
+the initial location and the pointer. When you release the button, the
+image is updated with the primitive you just drew. For polygons, the image
+is updated when you press and release the button without moving the pointer.
+<p>
+To cancel image drawing, move the pointer back to the starting point of
+the line and release the button.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-regi"></a>Region of Interest
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To begin, press choose Region of Interest of the Pixel Transform sub-menu
+from the <a href="#disp-comm">Command widget</a>.
+Alternatively, <a href="#disp-keyb">press</a> R in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in region of interest mode. In region of interest mode,
+the Command widget has these options:
+<ul>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+To define a region of interest, press button 1 and drag. The region of
+interest is defined by a highlighted rectangle that expands or contracts
+as it follows the pointer. Once you are satisfied with the region of interest,
+release the button. You are now in apply mode. In apply mode the Command
+widget has these options:
+<ul>
+<li>
+<strong>File</strong>
+<ul>
+<li>
+Save...
+<li>
+Print...
+</ul>
+<li>
+<strong>Edit</strong>
+<ul>
+<li>
+Undo
+<li>
+Redo
+</ul>
+<li>
+<strong>Transform</strong>
+<ul>
+<li>
+Flip
+<li>
+Flop
+<li>
+Rotate Right
+<li>
+Rotate Left
+</ul>
+<li>
+<strong>Enhance</strong>
+<ul>
+<li>
+Hue...
+<li>
+Saturation...
+<li>
+Brightness...
+<li>
+Gamma...
+<li>
+Spiff
+<li>
+Dull
+<li>
+Equalize
+<li>
+Normalize
+<li>
+Negate
+<li>
+GRAYscale
+<li>
+Quantize...
+</ul>
+<li>
+<strong>Effects</strong>
+<ul>
+<li>
+Despeckle
+<li>
+Emboss
+<li>
+Reduce Noise
+<li>
+Add Noise
+<li>
+Sharpen...
+<li>
+Blur...
+<li>
+Threshold...
+<li>
+Edge Detect...
+<li>
+Spread...
+<li>
+Shade...
+<li>
+Raise...
+<li>
+Segment...
+</ul>
+</ul>
+<ul>
+<li>
+<strong>F/X</strong>
+<ul>
+<li>
+Solarize...
+<li>
+Swirl...
+<li>
+Implode...
+<li>
+Wave...
+<li>
+Oil Paint
+<li>
+Charcoal Draw...
+</ul>
+</ul>
+<ul>
+<li>
+<strong>Miscellany</strong>
+<ul>
+<li>
+Image Info
+<li>
+Zoom Image
+<li>
+Show Preview...
+<li>
+Show Histogram
+<li>
+Show Matte
+</ul>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+You can make adjustments to the region of interest by moving the pointer
+to one of the rectangle corners, pressing a button, and dragging. Finally,
+choose an image processing technique from the Command widget. You can choose
+more than one image processing technique to apply to an area. Alternatively,
+you can move the region of interest before applying another image processing
+technique. To exit, press Dismiss.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-impa"></a>Image Panning
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+When an image exceeds the width or height of the X server screen, display
+maps a small panning icon. The rectangle within the panning icon shows
+the area that is currently displayed in the the image window. To pan about
+the image, press any button and drag the pointer within the panning icon.
+The pan rectangle moves with the pointer and the image window is updated
+to reflect the location of the rectangle within the panning icon. When
+you have selected the area of the image you wish to view, release the button.
+<p>
+Use the arrow keys to pan the image one pixel up, down, left, or right
+within the image window.
+<p>
+The panning icon is withdrawn if the image becomes smaller than the dimensions
+of the X server screen.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-pref"></a>User Preferences
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Preferences affect the default behavior of <strong>display(1)</strong>. The preferences
+are either true or false and are stored in your home directory
+as <tt>.displayrc</tt>:
+<dl>
+<dt>
+<strong>display image centered on a backdrop</strong></dt>
+<dd>
+This backdrop covers the entire workstation screen and is useful for hiding
+other X window activity while viewing the image. The color of the backdrop
+is specified as the background color. Refer to <a href="#disp-xres">X Resources</a>
+for details.</dd>
+<dt>
+<strong>confirm on program exit</strong></dt>
+<dd>
+Ask for a confirmation before exiting the <strong>display(1)</strong> program.</dd>
+<dt>
+<strong>correct image for display gamma</strong></dt>
+<dd>
+If the image has a known gamma, the gamma is corrected to match that of
+the X server (see the <a href="#disp-xres">X Resource</a><strong> displayGamma</strong>).</dd>
+<dt>
+<strong>display warning messages</strong></dt>
+<dd>
+Display any warning messages.</dd>
+<dt>
+<strong>apply Floyd/Steinberg error diffusion to image</strong></dt>
+<dd>
+The basic strategy of dithering is to trade intensity resolution for spatial
+resolution by averaging the intensities of several neighboring pixels.
+Images which suffer from severe contouring when reducing colors can be
+improved with this preference.</dd>
+<dt>
+<strong>use a shared colormap for colormapped X visuals</strong></dt>
+<dd>
+This option only applies when the default X server visual is
+<em>PseudoColor</em>
+or <em>GRAYScale</em>. Refer to <strong>-visual</strong> for more details. By default,
+a shared colormap is allocated. The image shares colors with other X clients.
+Some image colors could be approximated, therefore your image may look
+very different than intended. Otherwise the image colors appear exactly
+as they are defined. However, other clients may go technicolor when the
+image colormap is installed.</dd>
+<dt>
+<strong>display images as an X server pixmap</strong></dt>
+<dd>
+Images are maintained as a XImage by default. Set this resource to True
+to utilize a server Pixmap instead. This option is useful if your image
+exceeds the dimensions of your server screen and you intend to pan the
+image. Panning is much faster with Pixmaps than with a XImage. Pixmaps
+are considered a precious resource, use them with discretion.</dd>
+</dl>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
diff --git a/www/docutils-api.css b/www/docutils-api.css
new file mode 100644
index 0000000..19a2ecf
--- /dev/null
+++ b/www/docutils-api.css
@@ -0,0 +1,640 @@
+body,
+p,
+td,
+th,
+ul,
+ol {
+ font-size : medium;
+ font-family : sans-serif;
+}
+
+body {
+ color : #000000;
+ text-align : left;
+ margin : 0;
+ background-color : #FFFFFF;
+ padding-bottom : 20px;
+}
+
+h1 {
+ font-size : 120%;
+}
+
+h2 {
+ font-size : 110%;
+}
+
+h3,
+h4 {
+ font-size : 105%;
+}
+
+a:link {
+ color : #007F40;
+ text-decoration : underline;
+}
+
+a:visited {
+ color : #006030;
+ text-decoration : underline;
+}
+
+a:hover {
+ color : #006030;
+}
+
+.small {
+ font-size : smaller;
+}
+
+.tiny {
+ font-size : smaller;
+}
+
+div.banner {
+ border-bottom : 1px solid #3A4841;
+ padding : 2ex 0 1ex 5em;
+ border-top : 1px solid #3A4841;
+ background : #75EFB2 url(images/banner_bg.png) repeat-x;
+ overflow : hidden;
+ margin : 0;
+}
+
+div.banner img {
+ vertical-align : middle;
+ margin-left : 0em;
+}
+
+div.banner form {
+ margin-left : 2em;
+ display : inline;
+ text-align : center;
+}
+
+div.banner .title {
+ color : #002A15;
+ font-size : 2.2em;
+ font-weight : bold;
+}
+
+div.banner .subtitle {
+ color : #002A15;
+ font-size : 1em;
+ font-weight : normal;
+ margin-left : 1em;
+}
+
+div.navmenu {
+ font-size : 90%;
+ border-bottom : 1px solid #75867E;
+ padding : 0;
+ margin : 0;
+ background-color : #005C30;
+ text-align : center;
+}
+
+div.navmenu ul {
+ padding : 5px;
+ margin : 0;
+}
+
+div.navmenu ul li {
+ padding : 0 .5em 0 .5em;
+ list-style-type : none;
+ margin : 0 0 0 4px;
+ display : inline;
+ text-align : center;
+}
+
+div.navmenu ul li a {
+ color : #FFFFFF;
+ text-decoration : none;
+}
+
+div.navmenu ul li a:hover {
+ border-bottom : 1px solid #FFFFFF;
+}
+
+div.document {
+ height : auto;
+ padding : 1em;
+ width : auto;
+ background : #FFFFFF;
+ max-width : 960px;
+ margin : 2ex 2em 1ex 2em;
+ line-height : 140%;
+ text-align : left;
+}
+
+div.document h1.title {
+ font-size : 140%;
+ padding : 0;
+ padding-bottom : .4ex;
+ font-weight : bold;
+ margin : 0 0 0.5em 0;
+ text-align : center;
+}
+
+div.document hr.end {
+ color : #808080;
+ width : 50%;
+ height : 1px;
+}
+
+hr.divider {
+ color : #A0A0A0;
+ clear : both;
+ height : 3px;
+ width : 62%;
+ border : none;
+ background-color : #A0A0A0;
+}
+
+div.footer {
+ color : #606060;
+ clear : both;
+ width : 100%;
+ background : #FFFFFF;
+ max-width : 960px;
+ padding-top : 1ex;
+ font-family : sans-serif;
+}
+
+div.footer p {
+ font-size : 9pt;
+ margin : .5ex 0 0 0;
+ text-align : left;
+}
+
+div.footer a {
+ color : #000000;
+ font-size : 9pt;
+ margin : 0 .5em 0 .5em;
+ text-decoration : none;
+}
+
+div.footer a:hover {
+ text-decoration : underline;
+}
+
+h2 {
+ font-size : 14pt;
+}
+
+h3 {
+ font-size : 12pt;
+}
+
+h4 {
+ font-size : 11pt;
+}
+
+h5,
+h6 {
+ font-size : 10pt;
+}
+
+a {
+ text-decoration : none;
+}
+
+a:hover {
+ text-decoration : underline;
+}
+
+h1 a:hover {
+ color : inherit;
+ background-color : inherit;
+}
+
+tt {
+ background-color : #C9EEDC;
+}
+
+dl.docutils dd {
+ margin-bottom : 1em;
+}
+
+dl.docutils dt {
+ padding-top : 0.1cm;
+ font-weight : bold;
+ padding-bottom : 0.1cm;
+}
+
+dl.docutils dt tt {
+ font-style : normal;
+}
+
+dl.docutils dt tt span {
+ background-color : #FFFFFF;
+}
+
+dl.docutils dt span {
+ padding-top : 0.2ex;
+ padding-bottom : 0.2ex;
+}
+
+hr {
+ width : 75%;
+ page-break-after : always;
+}
+
+li {
+ padding-top : 0.5ex;
+ padding-bottom : 0.5ex;
+}
+
+div.document h1.title {
+ font-weight : bold;
+ font-size : 1.5em;
+ text-align : center;
+ margin-top : 1ex;
+ padding-bottom : 1ex;
+}
+
+div.section div.section {
+ margin-left : 3em;
+}
+
+div.section h1 {
+ color : black;
+ margin-top : 3.5ex;
+ font-weight : bold;
+ font-size : 120%;
+ margin-bottom : 0.5ex;
+}
+
+div.section h1 a {
+ color : #224433;
+ font-size : inherit;
+ text-decoration : none;
+}
+
+div.section h1 a.toc-backref {
+ color : #104028;
+}
+
+h2.subtitle {
+ padding-top : 0cm;
+ font-size : 1.1em;
+ text-align : center;
+}
+
+div.section h2 {
+ color : black;
+ font-size : 110%;
+ margin-top : 2ex;
+ margin-bottom : 1ex;
+}
+
+div.section h2 a {
+ color : #426453;
+ font-size : inherit;
+ background-color : #FFFFFF;
+ text-decoration : none;
+}
+
+div.section h3 {
+ color : #224433;
+ font-size : inherit;
+}
+
+div.section h3 a {
+ color : #608070;
+ font-size : inherit;
+ background-color : #FFFFFF;
+ text-decoration : none;
+}
+
+a.toc-backref {
+ color : black;
+ text-decoration : none;
+}
+
+div.abstract {
+ margin : 2em 5em;
+}
+
+div.abstract p.topic-title {
+ font-weight : bold;
+ text-align : center;
+}
+
+div.admonition,
+div.attention,
+div.caution,
+div.danger,
+div.error,
+div.hint,
+div.important,
+div.note,
+div.tip,
+div.warning {
+ padding : 1em;
+ margin : 2em;
+ border : medium outset;
+}
+
+div.hint,
+div.note,
+div.tip {
+ margin : 1em;
+ padding-right : .5em;
+ padding-bottom : .5ex;
+ padding-top : .5ex;
+ border : 1pt solid #CCCCCC;
+ background-color : #BFD5CA;
+ padding-left : .5em;
+}
+
+div.attention p.admonition-title,
+div.caution p.admonition-title,
+div.danger p.admonition-title,
+div.error p.admonition-title,
+div.warning p.admonition-title div.hint p.admonition-title,
+div.important p.admonition-title,
+div.note p.admonition-title,
+div.tip p.admonition-title {
+ color : red;
+ font-size : 12pt;
+ font-weight : bold;
+ font-family : sans-serif;
+}
+
+div.hint p.admonition-title,
+div.important p.admonition-title,
+div.note p.admonition-title,
+div.tip p.admonition-title {
+ color : #70AD8E;
+ font-size : 11pt;
+ font-weight : bold;
+ font-family : sans-serif;
+}
+
+div.dedication {
+ margin : 2em 5em;
+ font-style : italic;
+ text-align : center;
+}
+
+div.contents p.topic-title {
+ color : black;
+ font-size : 16pt;
+ font-weight : bold;
+ font-style : normal;
+}
+
+div.dedication p.topic-title {
+ font-weight : bold;
+ font-style : normal;
+}
+
+div.figure {
+ margin-left : 2em;
+}
+
+div.footer,
+div.header {
+ font-size : smaller;
+ margin-bottom : 0.5ex;
+}
+
+div.system-messages {
+ margin : 5em;
+}
+
+div.system-messages h1 {
+ color : red;
+ font-size : 1em;
+}
+
+div.system-message {
+ padding : 1em;
+ border : medium outset;
+}
+
+div.system-message p.system-message-title {
+ color : red;
+ font-weight : bold;
+}
+
+div.topic {
+ margin : 2em;
+}
+
+div.line-block {
+ margin-top : 1ex;
+ border-left : 2pt solid #606060;
+ padding-left : .5em;
+ background-color : #FFFFFF;
+ margin-bottom : 1ex;
+}
+
+ul.simple {
+ padding-left : 0;
+ margin-left : 1.0em;
+ margin-bottom : 1em;
+}
+
+ol.simple {
+ margin-left : 1.0em;
+ margin-bottom : 1em;
+}
+
+ol.arabic {
+ list-style : decimal;
+}
+
+ol.loweralpha {
+ list-style : lower-alpha;
+}
+
+ol.upperalpha {
+ list-style : upper-alpha;
+}
+
+ol.lowerroman {
+ list-style : lower-roman;
+}
+
+ol.upperroman {
+ list-style : upper-roman;
+}
+
+p.caption {
+ font-style : italic;
+}
+
+p.credits {
+ font-size : smaller;
+ font-style : italic;
+}
+
+p.label {
+ white-space : nowrap;
+}
+
+p.topic-title {
+ font-weight : bold;
+}
+
+pre.address {
+ font-size : 10pt;
+ font-family : serif;
+ margin-top : 0;
+ margin-bottom : 0;
+}
+
+pre.line-block {
+ font-size : 10pt;
+ font-family : serif;
+}
+
+pre.literal-block,
+pre.doctest-block {
+ font-size : 10pt;
+ color : #000000;
+ border-width : 1px;
+ padding : 2pt;
+ border-color : #E0E0E0;
+ border-style : solid;
+ line-height : 13pt;
+ background-color : #E8F8F0;
+}
+
+pre.literal-block a
+{
+ text-decoration : none;
+}
+
+span.classifier {
+ font-style : oblique;
+}
+
+span.classifier-delimiter {
+ font-weight : bold;
+}
+
+span.interpreted {
+ font-family : arial,helvetica,sans-serif;
+}
+
+span.option-argument {
+ font-style : italic;
+}
+
+span.pre {
+ white-space : pre;
+}
+
+span.problematic {
+ color : red;
+}
+
+span.field-argument {
+ font-size : 10pt;
+}
+
+table.docutils {
+ font-size : 100%;
+ margin-bottom : 1ex;
+ width : auto;
+ margin-top : 1ex;
+ border : none;
+ background-color : #FFFFFF;
+}
+
+table.docutils caption {
+ font-weight : bold;
+}
+
+table.docutils th,
+table.docutils td {
+ padding : 6px;
+ border-color : #C8C8C8;
+ border-style : solid;
+ vertical-align : top;
+ text-align : left;
+}
+
+table.docutils th {
+ border-top : 1px solid black;
+ background-color : #80C6A3;
+ border-bottom : 1px solid black;
+}
+
+table.docutils td {
+ background-color : #F8F8F8;
+}
+
+table.citation {
+ border-left : solid thin gray;
+ padding-left : 0.5ex;
+}
+
+table.docinfo {
+ font-size : 90%;
+ border-right : none;
+ border-top : 1pt solid #DDDDDD;
+ border-bottom : 1pt solid #DDDDDD;
+ margin-top : 1em;
+ margin-left : 0em;
+ border-left : none;
+ margin-bottom : 2em;
+ background-color : #EEEEEE;
+}
+
+table.docinfo th,
+table.docinfo td {
+ border-style : none;
+ border : none;
+ background-color : #EEEEEE;
+ padding-left : 0.5em;
+}
+
+table.footnote {
+ text-align : left;
+ font-size : smaller;
+ border-left : solid thin black;
+ padding-left : 0.5ex;
+}
+
+table.footnote td {
+ background-color : #F0F0F0;
+}
+
+th.docinfo-name,
+th.field-name {
+ white-space : nowrap;
+ font-weight : bold;
+ background-color : #EEEEEE;
+ text-align : left;
+}
+
+h1 tt,
+h2 tt,
+h3 tt,
+h4 tt,
+h5 tt,
+h6 tt {
+ font-size : inherit;
+ background-color : inherit;
+}
+
+ul.auto-toc {
+ list-style-type : none;
+}
+
+img.align-left {
+}
+
+img.align-right {
+}
+
+/* Try to hide the page banner on portable devices */
+@media handheld
+{
+ div.banner {
+ display:none;
+ }
+}
diff --git a/www/docutils-articles.css b/www/docutils-articles.css
new file mode 100644
index 0000000..e527bdd
--- /dev/null
+++ b/www/docutils-articles.css
@@ -0,0 +1,678 @@
+body,
+p,
+td,
+th,
+ul,
+ol {
+ font-size : medium;
+ font-family : sans-serif;
+}
+
+body {
+ color : #000000;
+ text-align : left;
+ margin : 0;
+ background-color : #FFFFFF;
+ padding-bottom : 20px;
+}
+
+h1 {
+ font-size : 120%;
+}
+
+h2 {
+ font-size : 110%;
+}
+
+h3,
+h4 {
+ font-size : 105%;
+}
+
+a:link {
+ color : #007F40;
+ text-decoration : underline;
+}
+
+a:visited {
+ color : #006030;
+ text-decoration : underline;
+}
+
+a:hover {
+ color : #006030;
+}
+
+.small {
+ font-size : smaller;
+}
+
+.tiny {
+ font-size : smaller;
+}
+
+div.banner {
+ border-bottom : 1px solid #3A4841;
+ padding : 2ex 0 1ex 4%;
+ border-top : 1px solid #3A4841;
+ background : #fff url(images/banner_bg.png) repeat-x;
+ overflow : hidden;
+ margin : 0;
+}
+
+span.nowrap {
+ white-space:nowrap;
+ margin: 2ex 2% 0 0;
+}
+
+.right {
+ float: right;
+ width: auto;
+}
+
+div.banner img {
+ vertical-align : middle;
+ margin-left : 0em;
+}
+
+div.banner form {
+ margin-left : 2em;
+ display : inline;
+ text-align : center;
+}
+
+div.banner .title {
+ color : #002A15;
+ font-size : 2.2em;
+ font-weight : bold;
+}
+
+div.banner .subtitle {
+ color : #002A15;
+ font-size : 1em;
+ font-weight : normal;
+ margin-left : 1em;
+}
+
+div.navmenu {
+ font-size : 90%;
+ border-bottom : 1px solid #75867E;
+ padding : 0;
+ margin : 0;
+ background-color : #005C30;
+ text-align : center;
+}
+
+div.navmenu ul {
+ max-width : 960px;
+ padding : 5px;
+ margin : 0;
+}
+
+div.navmenu ul li {
+ padding : 0 .5em 0 .5em;
+ list-style-type : none;
+ margin : 0 0 0 4px;
+ display : inline;
+ text-align : center;
+}
+
+div.navmenu ul li a {
+ color : #FFFFFF;
+ text-decoration : none;
+}
+
+div.navmenu ul li a:hover {
+ border-bottom : 1px solid #FFFFFF;
+}
+
+div.document {
+ height : auto;
+ padding : 1em 1% 1em 1%;
+ width : auto;
+ background : #FFFFFF;
+ max-width : 960px;
+ margin : 2ex 3% 1ex 3%;
+ line-height : 140%;
+ text-align : left;
+}
+
+div.document h1.title {
+ font-size : 140%;
+ padding : 0;
+ padding-bottom : .4ex;
+ font-weight : bold;
+ margin : 0 0 0.5em 0;
+ text-align : center;
+}
+
+div.document hr.end {
+ color : #808080;
+ width : 50%;
+ height : 1px;
+}
+
+hr.divider {
+ color : #A0A0A0;
+ clear : both;
+ height : 3px;
+ width : 62%;
+ border : none;
+ background-color : #A0A0A0;
+}
+
+div.footer {
+ color : #606060;
+ clear : both;
+ width : 100%;
+ background : #FFFFFF;
+ max-width : 960px;
+ padding-top : 1ex;
+ font-family : sans-serif;
+}
+
+div.footer p {
+ font-size : 9pt;
+ margin : .5ex 0 0 0;
+ text-align : left;
+}
+
+div.footer a {
+ color : #000000;
+ font-size : 9pt;
+ margin : 0 .5em 0 .5em;
+ text-decoration : none;
+}
+
+div.footer a:hover {
+ text-decoration : underline;
+}
+
+h2 {
+ font-size : 14pt;
+}
+
+h3 {
+ font-size : 12pt;
+}
+
+h4 {
+ font-size : 11pt;
+}
+
+h5,
+h6 {
+ font-size : 10pt;
+}
+
+a {
+ text-decoration : none;
+}
+
+a:hover {
+ text-decoration : underline;
+}
+
+h1 a:hover {
+ color : inherit;
+ background-color : inherit;
+}
+
+tt {
+ background-color : #C9EEDC;
+}
+
+dl.docutils dd {
+ margin-bottom : 1em;
+}
+
+dl.docutils dt {
+ padding-top : 0.1cm;
+ font-weight : bold;
+ padding-bottom : 0.1cm;
+}
+
+dl.docutils dt tt {
+ font-style : normal;
+}
+
+dl.docutils dt tt span {
+ background-color : #FFFFFF;
+}
+
+dl.docutils dt span {
+ padding-top : 0.2ex;
+ padding-bottom : 0.2ex;
+}
+
+hr {
+ width : 75%;
+ page-break-after : always;
+}
+
+li {
+ padding-top : 0.5ex;
+ padding-bottom : 0.5ex;
+}
+
+div.document h1.title {
+ font-weight : bold;
+ font-size : 1.5em;
+ text-align : center;
+ margin-top : 1ex;
+ padding-bottom : 1ex;
+}
+
+div.section h1 {
+ color : black;
+ margin-top : 3.5ex;
+ font-weight : bold;
+ font-size : 120%;
+ margin-bottom : 0.5ex;
+}
+
+div.section h1 a {
+ color : #224433;
+ font-size : inherit;
+ text-decoration : none;
+}
+
+div.section h1 a.toc-backref {
+ color : #104028;
+}
+
+h2.subtitle {
+ padding-top : 0cm;
+ font-size : 1.1em;
+ text-align : center;
+}
+
+div.section h2 {
+ color : black;
+ font-size : 110%;
+ margin-top : 2ex;
+ margin-bottom : 1ex;
+}
+
+div.section h2 a {
+ color : #426453;
+ font-size : inherit;
+ background-color : #FFFFFF;
+ text-decoration : none;
+}
+
+div.section h3 {
+ color : #224433;
+ font-size : inherit;
+}
+
+div.section h3 a {
+ color : #608070;
+ font-size : inherit;
+ background-color : #FFFFFF;
+ text-decoration : none;
+}
+
+a.toc-backref {
+ color : black;
+ text-decoration : none;
+}
+
+div.abstract {
+ margin : 2em 5em;
+}
+
+div.abstract p.topic-title {
+ font-weight : bold;
+ text-align : center;
+}
+
+div.admonition,
+div.attention,
+div.caution,
+div.danger,
+div.error,
+div.hint,
+div.important,
+div.note,
+div.tip,
+div.warning {
+ padding : 1em;
+ margin : 2em;
+ border : medium outset;
+}
+
+div.hint,
+div.note,
+div.tip {
+ margin : 1em;
+ padding-right : .5em;
+ padding-bottom : .5ex;
+ padding-top : .5ex;
+ border : 1pt solid #CCCCCC;
+ background-color : #BFD5CA;
+ padding-left : .5em;
+}
+
+div.attention p.admonition-title,
+div.caution p.admonition-title,
+div.danger p.admonition-title,
+div.error p.admonition-title,
+div.warning p.admonition-title div.hint p.admonition-title,
+div.important p.admonition-title,
+div.note p.admonition-title,
+div.tip p.admonition-title {
+ color : red;
+ font-size : 12pt;
+ font-weight : bold;
+ font-family : sans-serif;
+}
+
+div.hint p.admonition-title,
+div.important p.admonition-title,
+div.note p.admonition-title,
+div.tip p.admonition-title {
+ color : #70AD8E;
+ font-size : 11pt;
+ font-weight : bold;
+ font-family : sans-serif;
+}
+
+div.dedication {
+ margin : 2em 5em;
+ font-style : italic;
+ text-align : center;
+}
+
+div.contents p.topic-title {
+ color : black;
+ font-size : 16pt;
+ font-weight : bold;
+ font-style : normal;
+}
+
+div.dedication p.topic-title {
+ font-weight : bold;
+ font-style : normal;
+}
+
+div.figure {
+ margin-left : 2em;
+}
+
+div.footer,
+div.header {
+ font-size : smaller;
+ margin-bottom : 0.5ex;
+}
+
+div.system-messages {
+ margin : 5em;
+}
+
+div.system-messages h1 {
+ color : red;
+ font-size : 1em;
+}
+
+div.system-message {
+ padding : 1em;
+ border : medium outset;
+}
+
+div.system-message p.system-message-title {
+ color : red;
+ font-weight : bold;
+}
+
+div.topic {
+ margin : 2em;
+}
+
+div.line-block {
+ margin-top : 1ex;
+ border-left : 2pt solid #606060;
+ padding-left : .5em;
+ background-color : #FFFFFF;
+ margin-bottom : 1ex;
+}
+
+ul.simple {
+ padding-left : 0;
+ margin-left : 1.0em;
+ margin-bottom : 1em;
+}
+
+ol.simple {
+ margin-left : 1.0em;
+ margin-bottom : 1em;
+}
+
+ol.arabic {
+ list-style : decimal;
+}
+
+ol.loweralpha {
+ list-style : lower-alpha;
+}
+
+ol.upperalpha {
+ list-style : upper-alpha;
+}
+
+ol.lowerroman {
+ list-style : lower-roman;
+}
+
+ol.upperroman {
+ list-style : upper-roman;
+}
+
+p.caption {
+ font-style : italic;
+}
+
+p.credits {
+ font-size : smaller;
+ font-style : italic;
+}
+
+p.label {
+ white-space : nowrap;
+}
+
+p.topic-title {
+ font-weight : bold;
+}
+
+pre.address {
+ font-size : 10pt;
+ font-family : serif;
+ margin-top : 0;
+ margin-bottom : 0;
+}
+
+pre.line-block {
+ font-size : 10pt;
+ font-family : serif;
+}
+
+pre.literal-block,
+pre.doctest-block {
+ font-size : 10pt;
+ color : #000000;
+ border-width : 1px;
+ padding : 2pt;
+ border-color : #E0E0E0;
+ border-style : solid;
+ line-height : 13pt;
+ background-color : #E8F8F0;
+ overflow:auto; /* auto scroll */
+}
+
+span.classifier {
+ font-style : oblique;
+}
+
+span.classifier-delimiter {
+ font-weight : bold;
+}
+
+span.interpreted {
+ font-family : arial,helvetica,sans-serif;
+}
+
+span.option-argument {
+ font-style : italic;
+}
+
+span.pre {
+ white-space : pre;
+}
+
+span.problematic {
+ color : red;
+}
+
+span.field-argument {
+ font-size : 10pt;
+}
+
+table.docutils {
+ /*table-layout:fixed;*/
+ font-size : 100%;
+ margin-bottom : 1ex;
+ /*width : auto;*/
+ width: 98%;
+ margin-top : 1ex;
+ border : none;
+ background-color : #FFFFFF;
+}
+
+table.docutils caption {
+ font-weight : bold;
+}
+
+table.docutils th,
+table.docutils td {
+ padding : 6px;
+ border-color : #C8C8C8;
+ border-style : solid;
+ vertical-align : top;
+}
+
+
+table.docutils th {
+ border-top : 1px solid black;
+ background-color : #80C6A3;
+ border-bottom : 1px solid black;
+}
+
+table.docutils td {
+ background-color : #F8F8F8;
+}
+
+table.docutils td.decimal {
+ background-color : #F8F8F8;
+ text-align : right;
+}
+
+table.citation {
+ border-left : solid thin gray;
+ padding-left : 0.5ex;
+}
+
+table.docinfo {
+ font-size : 90%;
+ border-right : none;
+ border-top : 1pt solid #DDDDDD;
+ border-bottom : 1pt solid #DDDDDD;
+ margin-top : 1em;
+ margin-left : 0em;
+ border-left : none;
+ margin-bottom : 2em;
+ background-color : #EEEEEE;
+}
+
+table.docinfo th,
+table.docinfo td {
+ border : none;
+ background-color : #EEEEEE;
+ padding-left : 0.5em;
+}
+
+table.footnote {
+ text-align : left;
+ font-size : smaller;
+ border-left : solid thin black;
+ padding-left : 0.5ex;
+}
+
+table.footnote td {
+ background-color : #F0F0F0;
+}
+
+th.docinfo-name,
+th.field-name {
+ white-space : nowrap;
+ font-weight : bold;
+ background-color : #EEEEEE;
+ text-align : left;
+}
+
+table.option-list {
+ border : none;
+ padding : 0;
+ background-color : #FFFFFF;
+ border-collapse : collapse;
+}
+
+table.option-list tr {
+ border : none;
+ margin : 0;
+ padding : 0;
+}
+
+table.option-list td {
+ border : none;
+ background-color : #FFFFFF;
+}
+
+table.option-list td.option-group {
+ background-color : #FFFFFF;
+}
+
+span.option {
+ font-weight : bold;
+ background-color : #E8F8F0;
+}
+
+kbd { font-family : monospace; }
+
+h1 tt,
+h2 tt,
+h3 tt,
+h4 tt,
+h5 tt,
+h6 tt {
+ font-size : inherit;
+ background-color : inherit;
+}
+
+ul.auto-toc {
+ list-style-type : none;
+}
+
+img.align-left {
+}
+
+img.align-right {
+}
+
+/* Try to hide the page banner on portable devices */
+@media handheld
+{
+ div.banner {
+ display:none;
+ }
+}
diff --git a/www/download.html b/www/download.html
new file mode 100644
index 0000000..8c6e74f
--- /dev/null
+++ b/www/download.html
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Download</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-download">
+<h1 class="title">GraphicsMagick Download</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#ftp-site-organization" id="id1">Ftp Site Organization</a></li>
+<li><a class="reference internal" href="#download-sites" id="id2">Download Sites</a></li>
+</ul>
+</div>
+<p>The source distribution of GraphicsMagick as well as pre-compiled
+binaries are available at the sites listed here (unless otherwise
+noted). At the moment, the fastest way to obtain formal releases is
+from the <a class="reference external" href="http://sourceforge.net/projects/graphicsmagick/files/">SourceForge Download</a> page since SourceForge has lots of
+bandwidth, and many mirror sites. Snapshot packages should usually be
+retrieved from the <a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/">GraphicsMagick FTP</a> site or one of its mirrors.
+There are mirrors of the ftp site in Czechoslovakia and Poland.</p>
+<div class="section" id="ftp-site-organization">
+<h1><a class="toc-backref" href="#id1">Ftp Site Organization</a></h1>
+<p>The organization of the GraphicsMagick directory on ftp sites is as
+follows:</p>
+<p><a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/">GraphicsMagick FTP</a></p>
+<blockquote>
+Contains the core GraphicsMagick sources in a file named similar to
+GraphicsMagick-1.3.tar.bz2, GraphicsMagick-1.3.tar.gz, or
+GraphicsMagick-1.3.tar.xz. These core sources are sufficient to
+compile a minimal GraphicsMagick on a Unix system (including
+MacOS-X), or under the Cygwin and MinGW environments for Windows.
+Additional development packages need to be installed in advance to
+support formats like JPEG and PNG.</blockquote>
+<p><a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/delegates/">delegates</a></p>
+<blockquote>
+Add on third-party libraries and applications which extend the
+formats supported by GraphicsMagick may be obtained from this
+directory. Windows users can usually ignore the contents of this
+directory since all common delegates are included in the Windows
+source and binaries packages.</blockquote>
+<p><a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/linux/">linux</a></p>
+<blockquote>
+Linux source RPM (SRPM) packages for Red Hat Linux, other Linux
+systems, or any system with RPM installed, may be found here.</blockquote>
+<p><a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/snapshots/">snapshots</a></p>
+<blockquote>
+Snapshots (between releases) copies of GraphicsMagick may be found
+here. New snapshots may be cut every few days as time
+permits. Quality may vary (but is usually excellent).</blockquote>
+<p><a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/windows/">windows</a></p>
+<blockquote>
+Installable binary packages and the extended source code package for
+use with Microsoft Visual C++ (including configured delegates and a
+Visual C++ workspace) may be found here.</blockquote>
+</div>
+<div class="section" id="download-sites">
+<h1><a class="toc-backref" href="#id2">Download Sites</a></h1>
+<p>Here are some known download sites for GraphicsMagick:</p>
+<blockquote>
+<p><a class="reference external" href="https://sourceforge.net/projects/graphicsmagick/files/">SourceForge file download</a> (http protocol)</p>
+<p><a class="reference external" href="http://78.108.103.11/MIRROR/ftp/GraphicsMagick/">Czechoslovakian ftp mirror</a> (http protocol)</p>
+<p><a class="reference external" href="ftp://ftp.icm.edu.pl/pub/unix/graphics/GraphicsMagick/">Polish ftp mirror via ftp</a> (ftp protocol)</p>
+<p><a class="reference external" href="http://ftp.icm.edu.pl/pub/unix/graphics/GraphicsMagick/">Polish ftp mirror via http</a> (http protocol)</p>
+</blockquote>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/download.rst b/www/download.rst
new file mode 100644
index 0000000..d74c1fe
--- /dev/null
+++ b/www/download.rst
@@ -0,0 +1,89 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=======================
+GraphicsMagick Download
+=======================
+
+.. _Bob Friesenhahn : mailto:bfriesen@graphicsmagick.org
+.. _GraphicsMagick FTP : ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/
+.. _delegates : ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/delegates/
+.. _linux : ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/linux/
+.. _snapshots : ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/snapshots/
+.. _windows : ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/windows/
+.. _Cygwin : http://www.cygwin.com/
+.. _MinGW : http://www.mingw.org/
+.. _SourceForge Download : http://sourceforge.net/projects/graphicsmagick/files/
+.. _ftp.graphicsmagick.org: ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/
+
+.. contents::
+ :local:
+
+The source distribution of GraphicsMagick as well as pre-compiled
+binaries are available at the sites listed here (unless otherwise
+noted). At the moment, the fastest way to obtain formal releases is
+from the `SourceForge Download`_ page since SourceForge has lots of
+bandwidth, and many mirror sites. Snapshot packages should usually be
+retrieved from the `GraphicsMagick FTP`_ site or one of its mirrors.
+There are mirrors of the ftp site in Czechoslovakia and Poland.
+
+Ftp Site Organization
+---------------------
+
+The organization of the GraphicsMagick directory on ftp sites is as
+follows:
+
+`GraphicsMagick FTP`_
+
+ Contains the core GraphicsMagick sources in a file named similar to
+ GraphicsMagick-1.3.tar.bz2, GraphicsMagick-1.3.tar.gz, or
+ GraphicsMagick-1.3.tar.xz. These core sources are sufficient to
+ compile a minimal GraphicsMagick on a Unix system (including
+ MacOS-X), or under the Cygwin and MinGW environments for Windows.
+ Additional development packages need to be installed in advance to
+ support formats like JPEG and PNG.
+
+`delegates`_
+
+ Add on third-party libraries and applications which extend the
+ formats supported by GraphicsMagick may be obtained from this
+ directory. Windows users can usually ignore the contents of this
+ directory since all common delegates are included in the Windows
+ source and binaries packages.
+
+`linux`_
+
+ Linux source RPM (SRPM) packages for Red Hat Linux, other Linux
+ systems, or any system with RPM installed, may be found here.
+
+`snapshots`_
+
+ Snapshots (between releases) copies of GraphicsMagick may be found
+ here. New snapshots may be cut every few days as time
+ permits. Quality may vary (but is usually excellent).
+
+`windows`_
+
+ Installable binary packages and the extended source code package for
+ use with Microsoft Visual C++ (including configured delegates and a
+ Visual C++ workspace) may be found here.
+
+Download Sites
+--------------
+
+Here are some known download sites for GraphicsMagick:
+
+ `SourceForge file download <https://sourceforge.net/projects/graphicsmagick/files/>`_ (http protocol)
+
+ `Czechoslovakian ftp mirror <http://78.108.103.11/MIRROR/ftp/GraphicsMagick/>`_ (http protocol)
+
+ `Polish ftp mirror via ftp <ftp://ftp.icm.edu.pl/pub/unix/graphics/GraphicsMagick/>`_ (ftp protocol)
+
+ `Polish ftp mirror via http <http://ftp.icm.edu.pl/pub/unix/graphics/GraphicsMagick/>`_ (http protocol)
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/favicon.ico b/www/favicon.ico
new file mode 100644
index 0000000..ae85737
--- /dev/null
+++ b/www/favicon.ico
Binary files differ
diff --git a/www/formats.html b/www/formats.html
new file mode 100644
index 0000000..7ebc96c
--- /dev/null
+++ b/www/formats.html
@@ -0,0 +1,1291 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Supported Formats</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-supported-formats">
+<h1 class="title">GraphicsMagick Supported Formats</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>GraphicsMagick uses an ASCII string known as &quot;magick&quot; (e.g. &quot;GIF&quot;) to
+identify file formats, algorithms acting as formats, built-in images, and
+embedded profile types. After a file has been read or &quot;pinged&quot;, the
+associated magick string is stored in the &quot;magick&quot; member of the Image
+structure, and is reported in the default output of 'gm identify'.</p>
+<p>GraphicsMagick supports reading over 88 major file formats (not including
+sub-formats). The following table provides a summary of the supported
+image formats.</p>
+<table border="1" class="docutils">
+<caption>Supported Image Formats</caption>
+<colgroup>
+<col width="14%" />
+<col width="6%" />
+<col width="28%" />
+<col width="52%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Format</td>
+<td>Mode</td>
+<td>Description</td>
+<td>Notes</td>
+</tr>
+<tr><td>ART</td>
+<td>RW</td>
+<td>PFS: 1st Publisher</td>
+<td>Format originally used on the Macintosh
+(MacPaint?) and later used for PFS: 1st
+Publisher clip art.</td>
+</tr>
+<tr><td>AVS</td>
+<td>RW</td>
+<td>AVS X image</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/bmp/egff.htm">BMP</a></td>
+<td>RW</td>
+<td>Microsoft Windows bitmap</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/cals/egff.htm">CALS</a></td>
+<td>R</td>
+<td>Continuous Acquisition
+and Life-cycle Support
+Type 1 image</td>
+<td>Specified in MIL-R-28002 and MIL-PRF-28002.
+Standard blueprint archive format as used by the
+US military to replace microfiche.</td>
+</tr>
+<tr><td><a class="reference external" href="motion-picture.html">CIN</a></td>
+<td>R</td>
+<td>Kodak Cineon</td>
+<td>Kodak Cineon Log format (4.5 draft).
+Precursor to SMPTE <a class="reference external" href="motion-picture.html">DPX</a></td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/cgm/egff.htm">CGM</a></td>
+<td>R</td>
+<td>Computer Graphics
+Metafile</td>
+<td>Requires <a class="reference external" href="http://www.agocg.ac.uk/train/cgm/ralcgm.htm">ralcgm</a> to render CGM files.</td>
+</tr>
+<tr><td>CMYK</td>
+<td>RW</td>
+<td>Raw cyan, magenta,
+yellow, and black samples</td>
+<td>Use -size, -depth, -endian, and -interlace to
+specify the image width, height, depth, byte
+order, and interlace.</td>
+</tr>
+<tr><td>CUR</td>
+<td>R</td>
+<td>Microsoft Cursor Icon</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>CUT</td>
+<td>R</td>
+<td>DR Halo</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>DCM</td>
+<td>R</td>
+<td>Digital Imaging and
+Communications in
+Medicine (<a class="reference external" href="http://dicom.nema.org/">DICOM</a>) image</td>
+<td>Used by the medical community for images like
+X-rays. See the NEMA <a class="reference external" href="http://dicom.nema.org/">DICOM</a> web site for more
+information. <a class="reference external" href="http://dicom.nema.org/">DICOM</a> is the basis for the
+<a class="reference external" href="http://www.geinspectiontechnologies.com/en/products/software/diconde.html">DICONDE</a> format.</td>
+</tr>
+<tr><td>DCX</td>
+<td>RW</td>
+<td>ZSoft IBM PC multi-page
+Paintbrush image</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>DIB</td>
+<td>RW</td>
+<td>Microsoft Windows Device
+Independent Bitmap</td>
+<td>DIB is a BMP file without the BMP header. Used
+to support embedded images in compound formats
+like WMF.</td>
+</tr>
+<tr><td><a class="reference external" href="motion-picture.html">DPX</a></td>
+<td>RW</td>
+<td>Digital Moving Picture
+Exchange</td>
+<td>RGB and grayscale are fully supported at 1, 8,
+10, 12, and 16 bits as per the <a class="reference external" href="http://www.smpte.org/">SMPTE</a> 268M-2003
+(V2.0) specification. This includes support for
+images stored in a planar (multi-element)
+configuration and Cineon Log RGB. Rec. 601 and
+709 YCbCr are fully supported with 4:4:4 and
+4:2:2 subsampling. <a class="reference external" href="motion-picture.html">DPX</a> is commonly used to
+store image frames in film and HDTV production.</td>
+</tr>
+<tr><td>EMF</td>
+<td>R</td>
+<td>Microsoft Enhanced
+Metafile (32-bit)</td>
+<td>Only available under Microsoft Windows.</td>
+</tr>
+<tr><td>EPDF</td>
+<td>RW</td>
+<td>Encapsulated Portable
+Document Format</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>EPI</td>
+<td>RW</td>
+<td>Adobe Encapsulated
+PostScript Interchange
+format</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>EPS</td>
+<td>RW</td>
+<td>Adobe Encapsulated
+PostScript</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>EPS2</td>
+<td>W</td>
+<td>Adobe Level II
+Encapsulated PostScript</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>EPS3</td>
+<td>W</td>
+<td>Adobe Level III
+Encapsulated PostScript</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>EPSF</td>
+<td>RW</td>
+<td>Adobe Encapsulated
+PostScript</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>EPSI</td>
+<td>RW</td>
+<td>Adobe Encapsulated
+PostScript Interchange
+format</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>EPT</td>
+<td>RW</td>
+<td>Adobe Encapsulated
+PostScript Interchange
+format with <a class="reference external" href="http://www.simplesystems.org/libtiff/">TIFF</a> preview</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>FAX</td>
+<td>RW</td>
+<td>Group 3 FAX</td>
+<td>Note that FAX machines use non-square pixels
+which are 1.5 times wider than they are tall but
+computer displays use square pixels, so FAX
+images may appear to be narrow unless they are
+explicitly resized using a resize specification
+of &quot;150x100%&quot;. Please note that this is <em>not</em> a
+<a class="reference external" href="http://www.simplesystems.org/libtiff/">TIFF</a> format.</td>
+</tr>
+<tr><td>FIG</td>
+<td>R</td>
+<td>FIG graphics format</td>
+<td>Requires TransFig.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.cv.nrao.edu/fits/">FITS</a></td>
+<td>RW</td>
+<td>Flexible Image Transport
+System</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>FPX</td>
+<td>RW</td>
+<td>FlashPix Format</td>
+<td>Requires FlashPix SDK.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/gif/egff.htm">GIF</a></td>
+<td>RW</td>
+<td>CompuServe Graphics
+Interchange Format</td>
+<td><p class="first">8-bit RGB PseudoColor with up to 256 palette
+entires. Specify the format &quot;GIF87&quot; to write the
+older version 87a of the format.</p>
+<p class="last">The PNG format provides a superior set of
+features to GIF. Consider using PNG format
+rather than GIF if clients are able to read PNG.</p>
+</td>
+</tr>
+<tr><td>GRAY</td>
+<td>RW</td>
+<td>Raw gray samples</td>
+<td>Use -size, -depth, and -endian to specify the
+image width, height, depth, and byte order.</td>
+</tr>
+<tr><td>GRAYA</td>
+<td>RW</td>
+<td>Raw gray samples + alpha</td>
+<td>Use -size, -depth, and -endian to specify the
+image width, height, depth, and byte order.</td>
+</tr>
+<tr><td>HPGL</td>
+<td>R</td>
+<td>HP-GL plotter language</td>
+<td>Requires <a class="reference external" href="http://www.gnu.org/software/hp2xx/hp2xx.html">hp2xx</a> 3.2.0 or later</td>
+</tr>
+<tr><td>HTML</td>
+<td>RW</td>
+<td>Hypertext Markup Language
+with a client-side image
+map</td>
+<td>Also known as &quot;HTM&quot;. Requires html2ps to read.</td>
+</tr>
+<tr><td>ICO</td>
+<td>R</td>
+<td>Microsoft icon</td>
+<td>Also known as &quot;ICON&quot;.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.jpeg.org/">JBIG</a></td>
+<td>RW</td>
+<td>Joint Bi-level Image
+experts Group file
+interchange format</td>
+<td>Also known as &quot;BIE&quot; and &quot;JBG&quot;. Requires
+<a class="reference external" href="http://www.cl.cam.ac.uk/~mgk25/jbigkit/">jbigkit</a> 1.0 or later</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.libmng.com/">JNG</a></td>
+<td>RW</td>
+<td><a class="reference external" href="http://www.jpeg.org/">JPEG</a> Network Graphics</td>
+<td><a class="reference external" href="http://www.jpeg.org/">JPEG</a> in a PNG-style wrapper with transparency.
+Requires libjpeg and libpng-1.0.2 or later,
+libpng-1.2.5 or later recommended.</td>
+</tr>
+<tr><td>JP2</td>
+<td>RW</td>
+<td>JPEG-2000 JP2 File Format
+Syntax</td>
+<td>Requires <a class="reference external" href="http://www.ece.uvic.ca/~mdadams/jasper/">jasper</a> 1.600.0 or later</td>
+</tr>
+<tr><td>JPC</td>
+<td>RW</td>
+<td>JPEG-2000 Code Stream
+Syntax</td>
+<td>Requires <a class="reference external" href="http://www.ece.uvic.ca/~mdadams/jasper/">jasper</a> 1.600.0 or later</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.jpeg.org/">JPEG</a></td>
+<td>RW</td>
+<td>Joint Photographic
+Experts Group JFIF format</td>
+<td>Requires jpegsrc.v6b.tar.gz</td>
+</tr>
+<tr><td>MAN</td>
+<td>R</td>
+<td>Unix reference manual
+pages</td>
+<td>Requires that GNU groff and Ghostcript are
+installed.</td>
+</tr>
+<tr><td>MAT</td>
+<td>RW</td>
+<td>MATLAB image format</td>
+<td>Coming from <a class="reference external" href="http://www.mathworks.com/">MathWorks</a> for storing matrices.
+Currently supported types are 2D matrices: byte,
+word, double, complex and 3D matrices containing
+RGB [x*y*3] byte, word.</td>
+</tr>
+<tr><td><a class="reference external" href="miff.html">MIFF</a></td>
+<td>RW</td>
+<td>Magick image file format</td>
+<td>ImageMagick's lossless image format (with
+ASCII header) which ensures that no image
+attributes understood by ImageMagick or
+GraphicsMagick are lost.</td>
+</tr>
+<tr><td>MONO</td>
+<td>RW</td>
+<td>Bi-level bitmap in
+least-significant-byte
+first order</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.libmng.com/">MNG</a></td>
+<td>RW</td>
+<td>Multiple-image Network
+Graphics</td>
+<td>Requires libpng-1.0.2 or later, libpng-1.2.5 or
+later recommended.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.mpeg.org/">MPEG</a></td>
+<td>RW</td>
+<td>Motion Picture Experts
+Group file interchange
+format (version 1)</td>
+<td>Requires mpeg2vidcodec_v12.tar.gz.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.mpeg.org/">M2V</a></td>
+<td>RW</td>
+<td>Motion Picture Experts
+Group file interchange
+format (version 2)</td>
+<td>Requires mpeg2vidcodec_v12.tar.gz.</td>
+</tr>
+<tr><td>MPC</td>
+<td>RW</td>
+<td>Magick Persistent Cache
+image file format</td>
+<td><p class="first">The native &quot;in-memory&quot; GraphicsMagick
+uncompressed file format. This file format is
+identical to that used by Open ImageMagick to
+represent images in memory and is read in &quot;zero
+time&quot; via memory mapping. The MPC format is not
+portable and is not suitable as an archive
+format. It is suitable as an intermediate format
+for high-performance image processing.</p>
+<p class="last">The MPC format requires two files to support one
+image. When writing the MPC format, a file with
+extension &quot;.mpc&quot; is used to store information
+about the image, while a file with extension
+<tt class="docutils literal">.cache</tt> stores the image pixels. The storage
+space required by a MPC image (or an image in
+memory) may be calculated by the equation
+(QuantumDepth*Rows*Columns*5)/8.</p>
+</td>
+</tr>
+<tr><td>MSL</td>
+<td>RW</td>
+<td>Magick Scripting Language</td>
+<td>MSL is the XML-based scripting language
+supported by the conjure utility.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/mtv/egff.htm">MTV</a></td>
+<td>RW</td>
+<td>MTV Raytracing image
+format</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>MVG</td>
+<td>RW</td>
+<td>Magick Vector Graphics.</td>
+<td>The native GraphicsMagick vector metafile
+format. A text file containing vector drawing
+commands accepted by <a class="reference external" href="convert.html">convert</a>'s -draw option.</td>
+</tr>
+<tr><td>OTB</td>
+<td>RW</td>
+<td>On-the-air Bitmap</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>P7</td>
+<td>RW</td>
+<td>Xv's Visual Schnauzer
+thumbnail format</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PALM</td>
+<td>RW</td>
+<td>Palm pixmap</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://netpbm.sourceforge.net/doc/pam.html">PAM</a></td>
+<td>RW</td>
+<td>Portable Arbitrary Map
+format</td>
+<td>Superset of PNM (PPM, PGM, PPM) raw type formats.
+Supports bilevel, gray, RGB, CMYK, alpha channel.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/pbm/egff.htm">PBM</a></td>
+<td>RW</td>
+<td>Portable bitmap format
+(black and white)</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PCD</td>
+<td>RW</td>
+<td>Photo CD</td>
+<td>The maximum resolution written is 768x512 pixels
+since larger images require huffman compression
+(which is not supported).</td>
+</tr>
+<tr><td>PCDS</td>
+<td>RW</td>
+<td>Photo CD</td>
+<td>Decode with the sRGB color tables.</td>
+</tr>
+<tr><td>PCL</td>
+<td>W</td>
+<td>HP Page Control Language</td>
+<td>For output to HP laser printers.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/pcx/egff.htm">PCX</a></td>
+<td>RW</td>
+<td>ZSoft IBM PC Paintbrush
+file</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PDB</td>
+<td>RW</td>
+<td>Palm Database ImageViewer
+Format</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PDF</td>
+<td>RW</td>
+<td>Portable Document Format</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>PFA</td>
+<td>R</td>
+<td>Postscript Type 1 font
+(ASCII)</td>
+<td>Opening as file returns a preview image.</td>
+</tr>
+<tr><td>PFB</td>
+<td>R</td>
+<td>Postscript Type 1 font
+(binary)</td>
+<td>Opening as file returns a preview image.</td>
+</tr>
+<tr><td>PGM</td>
+<td>RW</td>
+<td>Portable graymap format
+(gray scale)</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PICON</td>
+<td>RW</td>
+<td>Personal Icon</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PICT</td>
+<td>RW</td>
+<td>Apple Macintosh QuickDraw
+/PICT file</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PIX</td>
+<td>R</td>
+<td>Alias/Wavefront RLE image
+format</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PNG</td>
+<td>RW</td>
+<td>Portable Network Graphics</td>
+<td>Requires libpng-1.0.2 or later, libpng-1.2.5 or
+later recommended.</td>
+</tr>
+<tr><td>PNM</td>
+<td>RW</td>
+<td>Portable anymap</td>
+<td><p class="first">PNM is a family of formats supporting portable
+bitmaps (PBM) , graymaps (PGM), and pixmaps
+(PPM). There is no file format associated with
+pnm itself. If PNM is used as the output format
+specifier, then GraphicsMagick automatically
+selects the most appropriate format to represent
+the image.</p>
+<p class="last">The default is to write the binary version of
+the formats. Use '-quality 0' to write the
+ASCII version of the formats.</p>
+</td>
+</tr>
+<tr><td>PPM</td>
+<td>RW</td>
+<td>Portable pixmap format
+(color)</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PS</td>
+<td>RW</td>
+<td>Adobe PostScript file</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>PS2</td>
+<td>RW</td>
+<td>Adobe Level II PostScript
+file</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>PS3</td>
+<td>RW</td>
+<td>Adobe Level III
+PostScript file</td>
+<td>Requires <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a> to read.</td>
+</tr>
+<tr><td>PSD</td>
+<td>RW</td>
+<td>Adobe Photoshop bitmap
+file</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>PTIF</td>
+<td>RW</td>
+<td>Pyramid encoded <a class="reference external" href="http://www.simplesystems.org/libtiff/">TIFF</a></td>
+<td>Multi-resolution <a class="reference external" href="http://www.simplesystems.org/libtiff/">TIFF</a> containing successively
+smaller versions of the image down to the size
+of an icon. The desired sub-image size may be
+specified when reading via the -size option.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.photoworks.com/">PWP</a></td>
+<td>R</td>
+<td>Seattle File Works
+multi-image file</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>RAS</td>
+<td>R</td>
+<td><a class="reference external" href="http://www.topol.cz/english/share/index.php3">TopoL</a> (GIS)</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>RAD</td>
+<td>R</td>
+<td><a class="reference external" href="http://radsite.lbl.gov/radiance/HOME.html">Radiance</a> image file</td>
+<td>Requires that ra_ppm from the <a class="reference external" href="http://radsite.lbl.gov/radiance/HOME.html">Radiance</a> software
+package be installed.</td>
+</tr>
+<tr><td>RGB</td>
+<td>RW</td>
+<td>Raw red, green, and blue
+samples</td>
+<td>Use -size, -depth, -endian, and -interlace to
+specify the image width, height, depth, byte
+order, and interlace.</td>
+</tr>
+<tr><td>RGBA</td>
+<td>RW</td>
+<td>Raw red, green, and blue
+and matte samples</td>
+<td>Use -size, -depth, -endian, and -interlace to
+specify the image width, height, depth, byte
+order, and interlace.</td>
+</tr>
+<tr><td>RLA</td>
+<td>R</td>
+<td>Alias/Wavefront image
+file</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>RLE</td>
+<td>R</td>
+<td>Utah Run length encoded
+image file</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://oreilly.com/www/centers/gff/formats/scitex/">SCT</a></td>
+<td>R</td>
+<td>Scitex Continuous Tone
+Picture</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.algonet.se/~cyren/sfw/">SFW</a></td>
+<td>R</td>
+<td>Seattle File Works image</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>SGI</td>
+<td>RW</td>
+<td>Irix RGB image</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>SHTML</td>
+<td>W</td>
+<td>Hypertext Markup Language
+client-side image map</td>
+<td>Used to write HTML clickable image maps based on
+a the output of montage or a format which
+supports tiled images such as <a class="reference external" href="miff.html">MIFF</a>.</td>
+</tr>
+<tr><td>SUN</td>
+<td>RW</td>
+<td>SUN Rasterfile</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.w3.org/Graphics/SVG/">SVG</a></td>
+<td>RW</td>
+<td>Scalable Vector Graphics</td>
+<td>Requires <a class="reference external" href="http://xmlsoft.org/">libxml2</a> and <a class="reference external" href="http://www.freetype.org/">freetype2</a>. Note that <a class="reference external" href="http://www.w3.org/Graphics/SVG/">SVG</a>
+is a very complex specification so support is
+still not complete.</td>
+</tr>
+<tr><td>TGA</td>
+<td>RW</td>
+<td>Truevision Targa image</td>
+<td>Also known as formats &quot;ICB&quot;, &quot;VDA&quot;, and &quot;VST&quot;.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.simplesystems.org/libtiff/">TIFF</a></td>
+<td>RW</td>
+<td>Tagged Image File Format</td>
+<td>Also known as &quot;TIF&quot;. Requires tiff-v3.5.4.tar.gz
+or later. Note that since the Unisys LZW patent
+recently expired, libtiff may still require a
+separate LZW patch in order to support LZW. LZW
+is included in libtiff by default since v3.7.0.</td>
+</tr>
+<tr><td>TIM</td>
+<td>R</td>
+<td>PSX TIM file</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>TTF</td>
+<td>R</td>
+<td>TrueType font file</td>
+<td>Requires <a class="reference external" href="http://www.freetype.org/">freetype2</a>. Opening as file returns a
+preview image.</td>
+</tr>
+<tr><td>TXT</td>
+<td>RW</td>
+<td>Raw text file</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>UIL</td>
+<td>W</td>
+<td>X-Motif UIL table</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>UYVY</td>
+<td>RW</td>
+<td>Interleaved YUV raw image</td>
+<td>Use -size command line option to specify width
+and height.</td>
+</tr>
+<tr><td>VICAR</td>
+<td>RW</td>
+<td>VICAR rasterfile format</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/viff/egff.htm">VIFF</a></td>
+<td>RW</td>
+<td>Khoros Visualization
+Image File Format</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.openmobilealliance.org/Technical/wapindex.aspx">WBMP</a></td>
+<td>RW</td>
+<td>Wireless bitmap</td>
+<td>Support for uncompressed monochrome only.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/wmf/egff.htm">WMF</a></td>
+<td>&nbsp;</td>
+<td>Windows Metafile</td>
+<td>Requires libwmf. By default, renders WMF files
+using the dimensions specified by the metafile
+header. Use the -density option to adjust the
+output resolution, and thereby adjust the ouput
+size. The default output resolution is 72DPI so
+&quot;-density 144&quot; results in an image twice as
+large as the default. Use -background <a class="reference external" href="color.html">color</a> to
+specify the WMF background color (default white)
+or -texture filename to specify a background
+texture image.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/wpg/egff.htm">WPG</a></td>
+<td>R</td>
+<td>Word Perfect Graphics
+File</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/xbm/egff.htm">XBM</a></td>
+<td>RW</td>
+<td>X Windows system bitmap,
+black and white only</td>
+<td>Used by the X Windows System to store monochrome
+icons.</td>
+</tr>
+<tr><td>XCF</td>
+<td>R</td>
+<td>GIMP image</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/xpm/egff.htm">XPM</a></td>
+<td>RW</td>
+<td>X Windows system pixmap</td>
+<td>Also known as &quot;PM&quot;. Used by the X Windows System
+to store color icons.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.fileformat.info/format/xwd/egff.htm">XWD</a></td>
+<td>RW</td>
+<td>X Windows system window
+dump</td>
+<td>Used by the X Windows System to save/display
+screen dumps.</td>
+</tr>
+<tr><td>YUV</td>
+<td>RW</td>
+<td>CCIR 601 4:1:1</td>
+<td>Use -size command line option to specify width
+and height.</td>
+</tr>
+</tbody>
+</table>
+<p>GraphicsMagick supports a number of image format specifications which
+refer to images prepared via an algorithm, or input/output targets. The
+following table lists these pseudo image formats:</p>
+<table border="1" class="docutils">
+<caption>Pseudo Image Formats</caption>
+<colgroup>
+<col width="13%" />
+<col width="6%" />
+<col width="25%" />
+<col width="56%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Tag</td>
+<td>Mode</td>
+<td>Description</td>
+<td>Notes</td>
+</tr>
+<tr><td>CAPTION</td>
+<td>R</td>
+<td>Image caption</td>
+<td>Draws text on a canvas image with size specified by <cite>-size</cite>
+canvas color as specified by <cite>-background' (default white),
+and text stroke and fill colors as specified by `-stroke</cite>
+and <cite>-fill</cite>. Capable of supporting multi-line text.</td>
+</tr>
+<tr><td>CLIPBOARD</td>
+<td>RW</td>
+<td>Windows Clipboard</td>
+<td>Only available under Microsoft Windows.</td>
+</tr>
+<tr><td>FRACTAL</td>
+<td>R</td>
+<td>Plasma fractal image</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>GRADIENT</td>
+<td>R</td>
+<td>Gradual passing from
+one shade to another</td>
+<td><p class="first">Returns a rendered gradient image using the
+specified image size. Specify the desired
+shading as part of the filename. For example:</p>
+<blockquote class="last">
+<tt class="docutils literal"><span class="pre">gradient:red-blue</span></tt> or <tt class="docutils literal"><span class="pre">gradient:#F00-#00F</span></tt></blockquote>
+</td>
+</tr>
+<tr><td>HISTOGRAM</td>
+<td>W</td>
+<td>Histogram of the image</td>
+<td><p class="first">Generate an RGB histogram of the input image.
+The output format is always ImageMagick <a class="reference external" href="miff.html">MIFF</a>
+(regardless of file extension). For example:</p>
+<blockquote class="last">
+<tt class="docutils literal">gm convert file.tiff histogram:file.miff</tt></blockquote>
+</td>
+</tr>
+<tr><td>IDENTITY</td>
+<td>R</td>
+<td><a class="reference external" href="http://www.quelsolaar.com/technology/clut.html">Hald CLUT</a> identity
+image</td>
+<td>Generate a Hald CLUT identity image of a specified order.
+The order is specified as an argument like &quot;IDENTITY:8&quot;.
+The default order is eight, producing a 512x512 image.</td>
+</tr>
+<tr><td>INFO</td>
+<td>W</td>
+<td>Image descriptive
+information and
+statistics</td>
+<td>Writes descriptive information similar to 'identify'</td>
+</tr>
+<tr><td>LABEL</td>
+<td>R</td>
+<td>Text image format</td>
+<td>Specify the desired text as the filename (e.g.
+&quot;label:This is a label&quot;).</td>
+</tr>
+<tr><td>MAP</td>
+<td>RW</td>
+<td>Colormap intensities
+and indices</td>
+<td>Set -depth to set the sample size of the
+intensities; indices are 16-bit if colors &gt;
+256.</td>
+</tr>
+<tr><td>MATTE</td>
+<td>W</td>
+<td>MATTE format</td>
+<td>Write only.</td>
+</tr>
+<tr><td>NULL</td>
+<td>RW</td>
+<td>NULL image</td>
+<td>Useful for creating blank tiles with montage
+(use &quot;NULL:&quot;). Also useful as an output format
+when evaluating image read performance.</td>
+</tr>
+<tr><td>PLASMA</td>
+<td>R</td>
+<td>Plasma fractal image</td>
+<td><p class="first">Creates an image using the plasma fractal. For
+example:</p>
+<blockquote class="last">
+<tt class="docutils literal">gm convert <span class="pre">-size</span> 640x480 plasma: file.miff</tt></blockquote>
+</td>
+</tr>
+<tr><td>PREVIEW</td>
+<td>W</td>
+<td>Show a preview an image
+enhancement, effect, or
+f/x</td>
+<td><p class="first">Creates a preview montage of images prepared
+over a parameteric range in order to assist
+with parameter selection. Specify the desired
+preview type via the -preview option). The
+output file is always written in the
+ImageMagick <a class="reference external" href="miff.html">MIFF</a> format.</p>
+<p>For example:</p>
+<blockquote class="last">
+<tt class="docutils literal">gm convert file.tiff <span class="pre">-preview</span> gamma preview:file.miff</tt></blockquote>
+</td>
+</tr>
+<tr><td>PRINT</td>
+<td>W</td>
+<td>Send image to your
+computer printer</td>
+<td>Unix users may set the PRINTER (for 'lp') or
+LPDEST (for 'lpr') environment variables to
+select the desired printer.</td>
+</tr>
+<tr><td>SCAN</td>
+<td>R</td>
+<td>Import image from a
+scanner device</td>
+<td>Requires <a class="reference external" href="http://www.mostang.com/sane/">SANE</a> Specify the device name and path
+as the filename (e.g. &quot;scan:mustek:/dev/scanner&quot;).</td>
+</tr>
+<tr><td>STEGANO</td>
+<td>R</td>
+<td>Steganographic image</td>
+<td>Use -size command line option to specify width,
+height, and offset of the steganographic image</td>
+</tr>
+<tr><td>TILE</td>
+<td>R</td>
+<td>Tiled image</td>
+<td><p class="first">Create a tiled version of an image at by tiling
+a image. Use -size to specify the tiled image
+size. The image is specified similar to
+&quot;TILE:image.miff&quot;.
+For example:</p>
+<blockquote class="last">
+<tt class="docutils literal">gm convert <span class="pre">-size</span> 800x600 tile:image.jpg out.jpg</tt></blockquote>
+</td>
+</tr>
+<tr><td>VID</td>
+<td>RW</td>
+<td>Visual Image Directory</td>
+<td><p class="first">Used to create a thumbnailed directory (tiled
+thumbnails) of a set of images which may be
+used to select images to view via the display
+program, or saved to a <a class="reference external" href="miff.html">MIFF</a> or SHTML file.
+For example:</p>
+<blockquote class="last">
+<tt class="docutils literal">gm convert <span class="pre">vid:&quot;*.jpg&quot;</span> index.miff</tt></blockquote>
+</td>
+</tr>
+<tr><td>WIN</td>
+<td>RW</td>
+<td>Select image from or
+display image to your
+computer screen</td>
+<td><p class="first">Only supported under Microsoft Windows. For example:</p>
+<blockquote class="last">
+<tt class="docutils literal">gm convert file.jpg <span class="pre">-rotate</span> 90 win:</tt></blockquote>
+</td>
+</tr>
+<tr><td>X</td>
+<td>RW</td>
+<td>Select image from or
+display image to your X
+server screen</td>
+<td><p class="first">Also see the import and display programs. For example:</p>
+<blockquote class="last">
+<tt class="docutils literal">gm convert file.jpg <span class="pre">-rotate</span> 90 x:</tt></blockquote>
+</td>
+</tr>
+<tr><td>XC</td>
+<td>R</td>
+<td>Canvas image of
+specified color</td>
+<td><p class="first">Useful to create solid color &quot;canvas&quot; images.
+Use -size and -depth to specify the image
+width, height, and depth. Example XC color
+specifications include &quot;XC:red&quot; and &quot;XC:#
+FF0000&quot;. See the <a class="reference external" href="color.html">color</a> reference for the
+numeric values used for named colors. For example:</p>
+<blockquote class="last">
+<tt class="docutils literal">gm convert <span class="pre">-size</span> 640x480 xc:red red.jpg</tt></blockquote>
+</td>
+</tr>
+</tbody>
+</table>
+<p>GraphicsMagick includes a number of built-in (embedded) images which may
+be referenced as if they were an image file. The <tt class="docutils literal">IMAGE:</tt> format tag may
+be used via the syntax &quot;IMAGE:name&quot; to request an embedded image (e.g.
+<tt class="docutils literal">IMAGE:LOGO</tt>). For backwards compatibility, the image specifications
+<tt class="docutils literal">GRANITE:</tt>, <tt class="docutils literal">LOGO:</tt>, <tt class="docutils literal">NETSCAPE:</tt>, and <tt class="docutils literal">ROSE:</tt> may also be used to request
+images with those names.</p>
+<p>A new canvas image of a specified size may be created using one of these pattern
+images using a command similar to:</p>
+<pre class="literal-block">
+gm convert -size 640x480 PATTERN:BRICKS bricks.miff
+</pre>
+<p>The TILE: virtual image type may also be used similar to:</p>
+<pre class="literal-block">
+gm convert -size 640x480 TILE:IMAGE:BRICKS bricks.miff
+</pre>
+<table border="1" class="docutils">
+<caption>Built-In Images And Patterns</caption>
+<colgroup>
+<col width="22%" />
+<col width="37%" />
+<col width="41%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Name</td>
+<td>Description</td>
+<td>Notes/Sample</td>
+</tr>
+<tr><td>BRICKS</td>
+<td>16x16 brick pattern</td>
+<td><img alt="bricks" src="images/patterns/bricks.png" /></td>
+</tr>
+<tr><td>CHECKERBOARD</td>
+<td>30x30 checkerboard pattern</td>
+<td><img alt="checkerboard" src="images/patterns/checkerboard.png" /></td>
+</tr>
+<tr><td>CIRCLES</td>
+<td>16x16 circles pattern</td>
+<td><img alt="circles" src="images/patterns/circles.png" /></td>
+</tr>
+<tr><td>CROSSHATCH</td>
+<td>8x4 crosshatch pattern</td>
+<td><img alt="crosshatch" src="images/patterns/crosshatch.png" /></td>
+</tr>
+<tr><td>CROSSHATCH30</td>
+<td>8x4 crosshatch pattern with lines
+at 30 degrees.</td>
+<td><img alt="crosshatch30" src="images/patterns/crosshatch30.png" /></td>
+</tr>
+<tr><td>CROSSHATCH45</td>
+<td>8x4 crosshatch pattern with lines
+at 45 degrees.</td>
+<td><img alt="crosshatch45" src="images/patterns/crosshatch45.png" /></td>
+</tr>
+<tr><td>FISHSCALES</td>
+<td>16x8 fish scales pattern</td>
+<td><img alt="fishscales" src="images/patterns/fishscales.png" /></td>
+</tr>
+<tr><td>GRANITE</td>
+<td>128x128 granite texture pattern</td>
+<td><img alt="granite" src="images/patterns/granite.png" /></td>
+</tr>
+<tr><td>GRAY0</td>
+<td>32x32 0% intensity gray</td>
+<td><img alt="gray0" src="images/patterns/gray0.png" /></td>
+</tr>
+<tr><td>GRAY5</td>
+<td>32x32 5% intensity gray</td>
+<td><img alt="gray5" src="images/patterns/gray5.png" /></td>
+</tr>
+<tr><td>GRAY10</td>
+<td>32x32 10% intensity gray</td>
+<td><img alt="gray10" src="images/patterns/gray10.png" /></td>
+</tr>
+<tr><td>GRAY15</td>
+<td>32x32 15% intensity gray</td>
+<td><img alt="gray15" src="images/patterns/gray15.png" /></td>
+</tr>
+<tr><td>GRAY20</td>
+<td>32x32 20% intensity gray</td>
+<td><img alt="gray20" src="images/patterns/gray20.png" /></td>
+</tr>
+<tr><td>GRAY25</td>
+<td>32x32 25% intensity gray</td>
+<td><img alt="gray25" src="images/patterns/gray25.png" /></td>
+</tr>
+<tr><td>GRAY30</td>
+<td>32x32 30% intensity gray</td>
+<td><img alt="gray30" src="images/patterns/gray30.png" /></td>
+</tr>
+<tr><td>GRAY35</td>
+<td>32x32 35% intensity gray</td>
+<td><img alt="gray35" src="images/patterns/gray35.png" /></td>
+</tr>
+<tr><td>GRAY40</td>
+<td>32x32 40% intensity gray</td>
+<td><img alt="gray40" src="images/patterns/gray40.png" /></td>
+</tr>
+<tr><td>GRAY45</td>
+<td>32x32 45% intensity gray</td>
+<td><img alt="gray45" src="images/patterns/gray45.png" /></td>
+</tr>
+<tr><td>GRAY50</td>
+<td>32x32 50% intensity gray</td>
+<td><img alt="gray50" src="images/patterns/gray50.png" /></td>
+</tr>
+<tr><td>GRAY55</td>
+<td>32x32 55% intensity gray</td>
+<td><img alt="gray55" src="images/patterns/gray55.png" /></td>
+</tr>
+<tr><td>GRAY60</td>
+<td>32x32 60% intensity gray</td>
+<td><img alt="gray60" src="images/patterns/gray60.png" /></td>
+</tr>
+<tr><td>GRAY65</td>
+<td>32x32 65% intensity gray</td>
+<td><img alt="gray65" src="images/patterns/gray65.png" /></td>
+</tr>
+<tr><td>GRAY70</td>
+<td>32x32 70% intensity gray</td>
+<td><img alt="gray70" src="images/patterns/gray70.png" /></td>
+</tr>
+<tr><td>GRAY75</td>
+<td>32x32 75% intensity gray</td>
+<td><img alt="gray75" src="images/patterns/gray75.png" /></td>
+</tr>
+<tr><td>GRAY80</td>
+<td>32x32 80% intensity gray</td>
+<td><img alt="gray80" src="images/patterns/gray80.png" /></td>
+</tr>
+<tr><td>GRAY85</td>
+<td>32x32 85% intensity gray</td>
+<td><img alt="gray85" src="images/patterns/gray85.png" /></td>
+</tr>
+<tr><td>GRAY90</td>
+<td>32x32 90% intensity gray</td>
+<td><img alt="gray90" src="images/patterns/gray90.png" /></td>
+</tr>
+<tr><td>GRAY95</td>
+<td>32x32 95% intensity gray</td>
+<td><img alt="gray95" src="images/patterns/gray95.png" /></td>
+</tr>
+<tr><td>GRAY100</td>
+<td>32x32 100% intensity gray</td>
+<td><img alt="gray100" src="images/patterns/gray100.png" /></td>
+</tr>
+<tr><td>HEXAGONS</td>
+<td>30x18 hexagon pattern</td>
+<td><img alt="hexagons" src="images/patterns/hexagons.png" /></td>
+</tr>
+<tr><td>HORIZONTAL</td>
+<td>8x4 horizontal line pattern</td>
+<td><img alt="horizontal" src="images/patterns/horizontal.png" /></td>
+</tr>
+<tr><td>HORIZONTALSAW</td>
+<td>16x8 horizontal saw-tooth pattern</td>
+<td><img alt="horizontalsaw" src="images/patterns/horizontalsaw.png" /></td>
+</tr>
+<tr><td>HS_BDIAGONAL</td>
+<td>8x8 backward diagonal line pattern
+(45 degrees slope)</td>
+<td><img alt="hs_bdiagonal" src="images/patterns/hs_bdiagonal.png" /></td>
+</tr>
+<tr><td>HS_CROSS</td>
+<td>8x8 cross line pattern</td>
+<td><img alt="hs_cross" src="images/patterns/hs_cross.png" /></td>
+</tr>
+<tr><td>HS_DIAGCROSS</td>
+<td>8x8 diagonal line cross pattern
+(45 degrees slope)</td>
+<td><img alt="hs_diagcross" src="images/patterns/hs_diagcross.png" /></td>
+</tr>
+<tr><td>HS_FDIAGONAL</td>
+<td>8x8 forward diagonal line pattern
+(45 degrees slope)</td>
+<td><img alt="hs_fdiagonal" src="images/patterns/hs_fdiagonal.png" /></td>
+</tr>
+<tr><td>HS_HORIZONTAL</td>
+<td>8x8 horizontal line pattern</td>
+<td><img alt="hs_horizontal" src="images/patterns/hs_horizontal.png" /></td>
+</tr>
+<tr><td>HS_VERTICAL</td>
+<td>8x8 vertical line pattern</td>
+<td><img alt="hs_vertical" src="images/patterns/hs_vertical.png" /></td>
+</tr>
+<tr><td>LEFT30</td>
+<td>8x4 forward diagonal pattern (30
+degrees slope)</td>
+<td><img alt="left30" src="images/patterns/left30.png" /></td>
+</tr>
+<tr><td>LEFT45</td>
+<td>8x8 forward diagonal line pattern
+(45 degrees slope)</td>
+<td><img alt="left45" src="images/patterns/left45.png" /></td>
+</tr>
+<tr><td>LEFTSHINGLE</td>
+<td>24x24 left shingle pattern</td>
+<td><img alt="leftshingle" src="images/patterns/leftshingle.png" /></td>
+</tr>
+<tr><td>LOGO</td>
+<td>640x480, GraphicsMagick Logo</td>
+<td><img alt="logo" src="images/gm-125x80t.png" /></td>
+</tr>
+<tr><td>NETSCAPE</td>
+<td>216x144 image using colors in
+Netscape 216 (6x6x6 ) color cube.</td>
+<td>Most commonly used with the
+<a class="reference external" href="convert.html">convert</a>/<a class="reference external" href="mogrify.html">mogrify</a> -map option to
+create <em>web safe</em> images.</td>
+</tr>
+<tr><td>OCTAGONS</td>
+<td>16x16 octagons pattern</td>
+<td><img alt="octagons" src="images/patterns/octagons.png" /></td>
+</tr>
+<tr><td>RIGHT30</td>
+<td>8x4 backward diagonal line pattern
+(30 degrees)</td>
+<td><img alt="right30" src="images/patterns/right30.png" /></td>
+</tr>
+<tr><td>RIGHT45</td>
+<td>8x8 backward diagonal line pattern
+(30 degrees)</td>
+<td><img alt="right45" src="images/patterns/right45.png" /></td>
+</tr>
+<tr><td>RIGHTSHINGLE</td>
+<td>24x24 right shingle pattern</td>
+<td><img alt="rightshingle" src="images/patterns/rightshingle.png" /></td>
+</tr>
+<tr><td>ROSE</td>
+<td>70x46, Picture of a rose.</td>
+<td><img alt="rose" src="images/patterns/rose.png" /></td>
+</tr>
+<tr><td>SMALLFISHSCALES</td>
+<td>8x8 small fish scales pattern</td>
+<td><img alt="smallfishscales" src="images/patterns/smallfishscales.png" /></td>
+</tr>
+<tr><td>VERTICAL</td>
+<td>8x8 vertical line pattern</td>
+<td><img alt="vertical" src="images/patterns/vertical.png" /></td>
+</tr>
+<tr><td>VERTICALBRICKS</td>
+<td>16x16 vertical brick pattern</td>
+<td><img alt="verticalbricks" src="images/patterns/verticalbricks.png" /></td>
+</tr>
+<tr><td>VERTICALLEFTSHINGLE</td>
+<td>24x24 vertical left shingle
+pattern</td>
+<td><img alt="verticalleftshingle" src="images/patterns/verticalleftshingle.png" /></td>
+</tr>
+<tr><td>VERTICALRIGHTSHINGLE</td>
+<td>24x24 vertical right shingle
+pattern</td>
+<td><img alt="verticalrightshingle" src="images/patterns/verticalrightshingle.png" /></td>
+</tr>
+<tr><td>VERTICALSAW</td>
+<td>8x16 vertical saw-tooth pattern</td>
+<td><img alt="verticalsaw" src="images/patterns/verticalsaw.png" /></td>
+</tr>
+</tbody>
+</table>
+<p>GraphicsMagick provides a number of format identifiers which are used
+to add, remove, and save embedded profiles for images which can
+support embedded profiles. Image types which may contain embedded
+profiles are <a class="reference external" href="http://www.simplesystems.org/libtiff/">TIFF</a>, <a class="reference external" href="http://www.jpeg.org/">JPEG</a>, PDF, and PNG.</p>
+<table border="1" class="docutils">
+<caption>Supported Embedded Profile Formats</caption>
+<colgroup>
+<col width="19%" />
+<col width="6%" />
+<col width="27%" />
+<col width="48%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Format</td>
+<td>Mode</td>
+<td>Description</td>
+<td>Notes</td>
+</tr>
+<tr><td>8BIM</td>
+<td>RW</td>
+<td>Photoshop resource format
+(binary)</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>8BIMTEXT</td>
+<td>RW</td>
+<td>Photoshop resource format
+(ASCII)</td>
+<td>An ASCII representation of the 8BIM format.</td>
+</tr>
+<tr><td>APP1</td>
+<td>RW</td>
+<td>Raw application
+information</td>
+<td>&nbsp;</td>
+</tr>
+<tr><td>APP1JPEG</td>
+<td>RW</td>
+<td>Raw <a class="reference external" href="http://www.jpeg.org/">JPEG</a> binary data</td>
+<td>Profile in <a class="reference external" href="http://www.jpeg.org/">JPEG</a> wrapper.</td>
+</tr>
+<tr><td>ICC</td>
+<td>RW</td>
+<td>International Color
+Consortium color profile</td>
+<td>Also known as &quot;ICM&quot;. To read, use -profile with
+convert.</td>
+</tr>
+<tr><td>IPTC</td>
+<td>RW</td>
+<td>IPTC Newsphoto (binary)</td>
+<td>To read, use -profile with convert</td>
+</tr>
+<tr><td>IPTCTEXT</td>
+<td>RW</td>
+<td>IPTC Newsphoto (ASCII)</td>
+<td>An ASCII representation of the IPTC format.</td>
+</tr>
+</tbody>
+</table>
+<p>Support for some of the formats are delegated to libraries or external
+programs. The README describes where to find these distributions and
+any special configuration options required.</p>
+<p>To get a complete listing of the image formats which are supported on
+your system, type</p>
+<pre class="literal-block">
+gm convert -list format
+</pre>
+<p>On some platforms, GraphicsMagick automatically processes these
+extensions: .gz for Zip compression, .Z for Unix compression, and .bz2
+for block compression. For example, a PNM image called image.pnm.gz is
+automatically uncompressed while the image is read.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/formats.rst b/www/formats.rst
new file mode 100644
index 0000000..ddda975
--- /dev/null
+++ b/www/formats.rst
@@ -0,0 +1,815 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+================================
+GraphicsMagick Supported Formats
+================================
+
+.. _animate : animate.html
+.. _composite : composite.html
+.. _compare : compare.html
+.. _conjure : conjure.html
+.. _convert : convert.html
+.. _display : display.html
+.. _identify : identify.html
+.. _import : import.html
+.. _mogrify : mogrify.html
+.. _montage : montage.html
+
+.. _AVI : http://www.jmcgowan.com/avi.html
+.. _BMP : http://www.fileformat.info/format/bmp/egff.htm
+.. _color : color.html
+.. _CALS : http://www.fileformat.info/format/cals/egff.htm
+.. _CGM : http://www.fileformat.info/format/cgm/egff.htm
+.. _CIN : motion-picture.html
+.. _DICOM : http://dicom.nema.org/
+.. _DICONDE : http://www.geinspectiontechnologies.com/en/products/software/diconde.html
+.. _DPX : motion-picture.html
+.. _FIG : foo.bar
+.. _FITS : http://www.cv.nrao.edu/fits/
+.. _Ghostscript : http://pages.cs.wisc.edu/~ghost/
+.. _GIF : http://www.fileformat.info/format/gif/egff.htm
+.. _`Hald CLUT` : http://www.quelsolaar.com/technology/clut.html
+.. _JBIG : http://www.jpeg.org/
+.. _JNG : http://www.libmng.com/
+.. _JPEG : http://www.jpeg.org/
+.. _M2V : http://www.mpeg.org/
+.. _MIFF : miff.html
+.. _MNG : http://www.libmng.com/
+.. _MPEG : http://www.mpeg.org/
+.. _MTV : http://www.fileformat.info/format/mtv/egff.htm
+.. _MathWorks : http://www.mathworks.com/
+.. _PAM : http://netpbm.sourceforge.net/doc/pam.html
+.. _PBM : http://www.fileformat.info/format/pbm/egff.htm
+.. _PCX : http://www.fileformat.info/format/pcx/egff.htm
+.. _PWP : http://www.photoworks.com/
+.. _README : README.html
+.. _Radiance : http://radsite.lbl.gov/radiance/HOME.html
+.. _SANE : http://www.mostang.com/sane/
+.. _SCT : http://oreilly.com/www/centers/gff/formats/scitex/
+.. _SFW : http://www.algonet.se/~cyren/sfw/
+.. _SMPTE : http://www.smpte.org/
+.. _SVG : http://www.w3.org/Graphics/SVG/
+.. _TIFF : http://www.simplesystems.org/libtiff/
+.. _TopoL : http://www.topol.cz/english/share/index.php3
+.. _VIFF: http://www.fileformat.info/format/viff/egff.htm
+.. _WBMP : http://www.openmobilealliance.org/Technical/wapindex.aspx
+.. _WMF : http://www.fileformat.info/format/wmf/egff.htm
+.. _WPG : http://www.fileformat.info/format/wpg/egff.htm
+.. _XBM : http://www.fileformat.info/format/xbm/egff.htm
+.. _XPM : http://www.fileformat.info/format/xpm/egff.htm
+.. _XWD : http://www.fileformat.info/format/xwd/egff.htm
+.. _freetype2 : http://www.freetype.org/
+.. _hp2xx : http://www.gnu.org/software/hp2xx/hp2xx.html
+.. _html2ps : http://user.it.uu.se/~jan/
+.. _jasper : http://www.ece.uvic.ca/~mdadams/jasper/
+.. _jbigkit : http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+.. _libxml2 : http://xmlsoft.org/
+.. _mpeg2vidcodec : foo.bar
+.. _ralcgm : http://www.agocg.ac.uk/train/cgm/ralcgm.htm
+
+GraphicsMagick uses an ASCII string known as "magick" (e.g. "GIF") to
+identify file formats, algorithms acting as formats, built-in images, and
+embedded profile types. After a file has been read or "pinged", the
+associated magick string is stored in the "magick" member of the Image
+structure, and is reported in the default output of 'gm identify'.
+
+
+GraphicsMagick supports reading over 88 major file formats (not including
+sub-formats). The following table provides a summary of the supported
+image formats.
+
+.. table:: Supported Image Formats
+
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | Format | Mode | Description | Notes |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | Format originally used on the Macintosh |
+ | ART | RW | PFS: 1st Publisher | (MacPaint?) and later used for PFS: 1st |
+ | | | | Publisher clip art. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | AVS | RW | AVS X image | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | BMP_ | RW | Microsoft Windows bitmap | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | CALS_ | R | Continuous Acquisition | Specified in MIL-R-28002 and MIL-PRF-28002. |
+ | | | and Life-cycle Support | Standard blueprint archive format as used by the |
+ | | | Type 1 image | US military to replace microfiche. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | CIN_ | R | Kodak Cineon | Kodak Cineon Log format (4.5 draft). |
+ | | | | Precursor to SMPTE DPX_ |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | CGM_ | R | Computer Graphics | Requires ralcgm_ to render CGM files. |
+ | | | Metafile | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | CMYK | RW | Raw cyan, magenta, | Use -size, -depth, -endian, and -interlace to |
+ | | | yellow, and black samples | specify the image width, height, depth, byte |
+ | | | | order, and interlace. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | CUR | R | Microsoft Cursor Icon | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | CUT | R | DR Halo | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Digital Imaging and | Used by the medical community for images like |
+ | DCM | R | Communications in | X-rays. See the NEMA DICOM_ web site for more |
+ | | | Medicine (DICOM_) image | information. DICOM_ is the basis for the |
+ | | | | DICONDE_ format. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | DCX | RW | ZSoft IBM PC multi-page | |
+ | | | Paintbrush image | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Microsoft Windows Device | DIB is a BMP file without the BMP header. Used |
+ | DIB | RW | Independent Bitmap | to support embedded images in compound formats |
+ | | | | like WMF. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | RGB and grayscale are fully supported at 1, 8, |
+ | | | | 10, 12, and 16 bits as per the SMPTE_ 268M-2003 |
+ | | | | (V2.0) specification. This includes support for |
+ | DPX_ | RW | Digital Moving Picture | images stored in a planar (multi-element) |
+ | | | Exchange | configuration and Cineon Log RGB. Rec. 601 and |
+ | | | | 709 YCbCr are fully supported with 4:4:4 and |
+ | | | | 4:2:2 subsampling. DPX_ is commonly used to |
+ | | | | store image frames in film and HDTV production. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | EMF | R | Microsoft Enhanced | Only available under Microsoft Windows. |
+ | | | Metafile (32-bit) | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | EPDF | RW | Encapsulated Portable | |
+ | | | Document Format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Adobe Encapsulated | |
+ | EPI | RW | PostScript Interchange | Requires Ghostscript_ to read. |
+ | | | format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | EPS | RW | Adobe Encapsulated | Requires Ghostscript_ to read. |
+ | | | PostScript | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | EPS2 | W | Adobe Level II | Requires Ghostscript_ to read. |
+ | | | Encapsulated PostScript | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | EPS3 | W | Adobe Level III | Requires Ghostscript_ to read. |
+ | | | Encapsulated PostScript | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | EPSF | RW | Adobe Encapsulated | Requires Ghostscript_ to read. |
+ | | | PostScript | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Adobe Encapsulated | |
+ | EPSI | RW | PostScript Interchange | Requires Ghostscript_ to read. |
+ | | | format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Adobe Encapsulated | |
+ | EPT | RW | PostScript Interchange | Requires Ghostscript_ to read. |
+ | | | format with TIFF_ preview | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | Note that FAX machines use non-square pixels |
+ | | | | which are 1.5 times wider than they are tall but |
+ | | | | computer displays use square pixels, so FAX |
+ | FAX | RW | Group 3 FAX | images may appear to be narrow unless they are |
+ | | | | explicitly resized using a resize specification |
+ | | | | of "150x100%". Please note that this is *not* a |
+ | | | | TIFF_ format. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | FIG | R | FIG graphics format | Requires TransFig. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | FITS_ | RW | Flexible Image Transport | |
+ | | | System | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | FPX | RW | FlashPix Format | Requires FlashPix SDK. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | 8-bit RGB PseudoColor with up to 256 palette |
+ | | | | entires. Specify the format "GIF87" to write the |
+ | | | CompuServe Graphics | older version 87a of the format. |
+ | GIF_ | RW | Interchange Format | |
+ | | | | The PNG format provides a superior set of |
+ | | | | features to GIF. Consider using PNG format |
+ | | | | rather than GIF if clients are able to read PNG. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | GRAY | RW | Raw gray samples | Use -size, -depth, and -endian to specify the |
+ | | | | image width, height, depth, and byte order. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | GRAYA | RW | Raw gray samples + alpha | Use -size, -depth, and -endian to specify the |
+ | | | | image width, height, depth, and byte order. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | HPGL | R | HP-GL plotter language | Requires hp2xx_ 3.2.0 or later |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Hypertext Markup Language | |
+ | HTML | RW | with a client-side image | Also known as "HTM". Requires html2ps to read. |
+ | | | map | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | ICO | R | Microsoft icon | Also known as "ICON". |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Joint Bi-level Image | Also known as "BIE" and "JBG". Requires |
+ | JBIG_ | RW | experts Group file | jbigkit_ 1.0 or later |
+ | | | interchange format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | JPEG_ in a PNG-style wrapper with transparency. |
+ | JNG_ | RW | JPEG_ Network Graphics | Requires libjpeg and libpng-1.0.2 or later, |
+ | | | | libpng-1.2.5 or later recommended. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | JP2 | RW | JPEG-2000 JP2 File Format | Requires jasper_ 1.600.0 or later |
+ | | | Syntax | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | JPC | RW | JPEG-2000 Code Stream | Requires jasper_ 1.600.0 or later |
+ | | | Syntax | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | JPEG_ | RW | Joint Photographic | Requires jpegsrc.v6b.tar.gz |
+ | | | Experts Group JFIF format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | MAN | R | Unix reference manual | Requires that GNU groff and Ghostcript are |
+ | | | pages | installed. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | Coming from MathWorks_ for storing matrices. |
+ | | | | Currently supported types are 2D matrices: byte, |
+ | MAT | RW | MATLAB image format | word, double, complex and 3D matrices containing |
+ | | | | RGB [x*y*3] byte, word. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | ImageMagick's lossless image format (with |
+ | MIFF_ | RW | Magick image file format | ASCII header) which ensures that no image |
+ | | | | attributes understood by ImageMagick or |
+ | | | | GraphicsMagick are lost. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Bi-level bitmap in | |
+ | MONO | RW | least-significant-byte | |
+ | | | first order | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | MNG_ | RW | Multiple-image Network | Requires libpng-1.0.2 or later, libpng-1.2.5 or |
+ | | | Graphics | later recommended. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Motion Picture Experts | |
+ | MPEG_ | RW | Group file interchange | Requires mpeg2vidcodec_v12.tar.gz. |
+ | | | format (version 1) | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Motion Picture Experts | |
+ | M2V_ | RW | Group file interchange | Requires mpeg2vidcodec_v12.tar.gz. |
+ | | | format (version 2) | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | The native "in-memory" GraphicsMagick |
+ | | | | uncompressed file format. This file format is |
+ | | | | identical to that used by Open ImageMagick to |
+ | | | | represent images in memory and is read in "zero |
+ | | | | time" via memory mapping. The MPC format is not |
+ | | | | portable and is not suitable as an archive |
+ | | | | format. It is suitable as an intermediate format |
+ | | | Magick Persistent Cache | for high-performance image processing. |
+ | MPC | RW | image file format | |
+ | | | | The MPC format requires two files to support one |
+ | | | | image. When writing the MPC format, a file with |
+ | | | | extension ".mpc" is used to store information |
+ | | | | about the image, while a file with extension |
+ | | | | ``.cache`` stores the image pixels. The storage |
+ | | | | space required by a MPC image (or an image in |
+ | | | | memory) may be calculated by the equation |
+ | | | | (QuantumDepth*Rows*Columns*5)/8. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | MSL | RW | Magick Scripting Language | MSL is the XML-based scripting language |
+ | | | | supported by the conjure utility. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | MTV_ | RW | MTV Raytracing image | |
+ | | | format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | The native GraphicsMagick vector metafile |
+ | MVG | RW | Magick Vector Graphics. | format. A text file containing vector drawing |
+ | | | | commands accepted by convert_'s -draw option. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | OTB | RW | On-the-air Bitmap | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | P7 | RW | Xv's Visual Schnauzer | |
+ | | | thumbnail format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PALM | RW | Palm pixmap | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PAM_ | RW | Portable Arbitrary Map | Superset of PNM (PPM, PGM, PPM) raw type formats.|
+ | | | format | Supports bilevel, gray, RGB, CMYK, alpha channel.|
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PBM_ | RW | Portable bitmap format | |
+ | | | (black and white) | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | The maximum resolution written is 768x512 pixels |
+ | PCD | RW | Photo CD | since larger images require huffman compression |
+ | | | | (which is not supported). |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PCDS | RW | Photo CD | Decode with the sRGB color tables. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PCL | W | HP Page Control Language | For output to HP laser printers. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PCX_ | RW | ZSoft IBM PC Paintbrush | |
+ | | | file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PDB | RW | Palm Database ImageViewer | |
+ | | | Format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PDF | RW | Portable Document Format | Requires Ghostscript_ to read. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PFA | R | Postscript Type 1 font | Opening as file returns a preview image. |
+ | | | (ASCII) | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PFB | R | Postscript Type 1 font | Opening as file returns a preview image. |
+ | | | (binary) | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PGM | RW | Portable graymap format | |
+ | | | (gray scale) | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PICON | RW | Personal Icon | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PICT | RW | Apple Macintosh QuickDraw | |
+ | | | /PICT file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PIX | R | Alias/Wavefront RLE image | |
+ | | | format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PNG | RW | Portable Network Graphics | Requires libpng-1.0.2 or later, libpng-1.2.5 or |
+ | | | | later recommended. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | PNM is a family of formats supporting portable |
+ | | | | bitmaps (PBM) , graymaps (PGM), and pixmaps |
+ | | | | (PPM). There is no file format associated with |
+ | | | | pnm itself. If PNM is used as the output format |
+ | | | | specifier, then GraphicsMagick automatically |
+ | PNM | RW | Portable anymap | selects the most appropriate format to represent |
+ | | | | the image. |
+ | | | | |
+ | | | | The default is to write the binary version of |
+ | | | | the formats. Use '-quality 0' to write the |
+ | | | | ASCII version of the formats. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PPM | RW | Portable pixmap format | |
+ | | | (color) | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PS | RW | Adobe PostScript file | Requires Ghostscript_ to read. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PS2 | RW | Adobe Level II PostScript | Requires Ghostscript_ to read. |
+ | | | file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PS3 | RW | Adobe Level III | Requires Ghostscript_ to read. |
+ | | | PostScript file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PSD | RW | Adobe Photoshop bitmap | |
+ | | | file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | Multi-resolution TIFF_ containing successively |
+ | PTIF | RW | Pyramid encoded TIFF_ | smaller versions of the image down to the size |
+ | | | | of an icon. The desired sub-image size may be |
+ | | | | specified when reading via the -size option. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | PWP_ | R | Seattle File Works | |
+ | | | multi-image file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | RAS | R | TopoL_ (GIS) | |
+ | | | | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | RAD | R | Radiance_ image file | Requires that ra_ppm from the Radiance_ software |
+ | | | | package be installed. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | RGB | RW | Raw red, green, and blue | Use -size, -depth, -endian, and -interlace to |
+ | | | samples | specify the image width, height, depth, byte |
+ | | | | order, and interlace. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | RGBA | RW | Raw red, green, and blue | Use -size, -depth, -endian, and -interlace to |
+ | | | and matte samples | specify the image width, height, depth, byte |
+ | | | | order, and interlace. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | RLA | R | Alias/Wavefront image | |
+ | | | file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | RLE | R | Utah Run length encoded | |
+ | | | image file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | SCT_ | R | Scitex Continuous Tone | |
+ | | | Picture | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | SFW_ | R | Seattle File Works image | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | SGI | RW | Irix RGB image | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | Hypertext Markup Language | Used to write HTML clickable image maps based on |
+ | SHTML | W | client-side image map | a the output of montage or a format which |
+ | | | | supports tiled images such as MIFF_. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | SUN | RW | SUN Rasterfile | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | Requires libxml2_ and freetype2_. Note that SVG_ |
+ | SVG_ | RW | Scalable Vector Graphics | is a very complex specification so support is |
+ | | | | still not complete. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | TGA | RW | Truevision Targa image | Also known as formats "ICB", "VDA", and "VST". |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | Also known as "TIF". Requires tiff-v3.5.4.tar.gz |
+ | | | | or later. Note that since the Unisys LZW patent |
+ | TIFF_ | RW | Tagged Image File Format | recently expired, libtiff may still require a |
+ | | | | separate LZW patch in order to support LZW. LZW |
+ | | | | is included in libtiff by default since v3.7.0. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | TIM | R | PSX TIM file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | TTF | R | TrueType font file | Requires freetype2_. Opening as file returns a |
+ | | | | preview image. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | TXT | RW | Raw text file | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | UIL | W | X-Motif UIL table | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | UYVY | RW | Interleaved YUV raw image | Use -size command line option to specify width |
+ | | | | and height. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | VICAR | RW | VICAR rasterfile format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | VIFF_ | RW | Khoros Visualization | |
+ | | | Image File Format | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | WBMP_ | RW | Wireless bitmap | Support for uncompressed monochrome only. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | | | | Requires libwmf. By default, renders WMF files |
+ | | | | using the dimensions specified by the metafile |
+ | | | | header. Use the -density option to adjust the |
+ | | | | output resolution, and thereby adjust the ouput |
+ | WMF_ | | Windows Metafile | size. The default output resolution is 72DPI so |
+ | | | | "-density 144" results in an image twice as |
+ | | | | large as the default. Use -background color_ to |
+ | | | | specify the WMF background color (default white) |
+ | | | | or -texture filename to specify a background |
+ | | | | texture image. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | WPG_ | R | Word Perfect Graphics | |
+ | | | File | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | XBM_ | RW | X Windows system bitmap, | Used by the X Windows System to store monochrome |
+ | | | black and white only | icons. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | XCF | R | GIMP image | |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | XPM_ | RW | X Windows system pixmap | Also known as "PM". Used by the X Windows System |
+ | | | | to store color icons. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | XWD_ | RW | X Windows system window | Used by the X Windows System to save/display |
+ | | | dump | screen dumps. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+ | YUV | RW | CCIR 601 4:1:1 | Use -size command line option to specify width |
+ | | | | and height. |
+ +--------------+------+---------------------------+--------------------------------------------------+
+
+
+GraphicsMagick supports a number of image format specifications which
+refer to images prepared via an algorithm, or input/output targets. The
+following table lists these pseudo image formats:
+
+.. table:: Pseudo Image Formats
+
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | Tag | Mode | Description | Notes |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | CAPTION | R | Image caption | Draws text on a canvas image with size specified by `-size` |
+ | | | | canvas color as specified by `-background' (default white), |
+ | | | | and text stroke and fill colors as specified by `-stroke` |
+ | | | | and `-fill`. Capable of supporting multi-line text. |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | CLIPBOARD | RW | Windows Clipboard | Only available under Microsoft Windows. |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | FRACTAL | R | Plasma fractal image | |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | | Returns a rendered gradient image using the |
+ | GRADIENT | R | Gradual passing from | specified image size. Specify the desired |
+ | | | one shade to another | shading as part of the filename. For example: |
+ | | | | |
+ | | | | ``gradient:red-blue`` or ``gradient:#F00-#00F`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | | Generate an RGB histogram of the input image. |
+ | | | | The output format is always ImageMagick MIFF_ |
+ | HISTOGRAM | W | Histogram of the image | (regardless of file extension). For example: |
+ | | | | |
+ | | | | ``gm convert file.tiff histogram:file.miff`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | IDENTITY | R | `Hald CLUT`_ identity | Generate a Hald CLUT identity image of a specified order. |
+ | | | image | The order is specified as an argument like "IDENTITY:8". |
+ | | | | The default order is eight, producing a 512x512 image. |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | INFO | W | Image descriptive | Writes descriptive information similar to 'identify' |
+ | | | information and | |
+ | | | statistics | |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | LABEL | R | Text image format | Specify the desired text as the filename (e.g. |
+ | | | | "label:This is a label"). |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | Colormap intensities | Set -depth to set the sample size of the |
+ | MAP | RW | and indices | intensities; indices are 16-bit if colors > |
+ | | | | 256. |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | MATTE | W | MATTE format | Write only. |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | | Useful for creating blank tiles with montage |
+ | NULL | RW | NULL image | (use "NULL:"). Also useful as an output format |
+ | | | | when evaluating image read performance. |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | | Creates an image using the plasma fractal. For |
+ | PLASMA | R | Plasma fractal image | example: |
+ | | | | |
+ | | | | ``gm convert -size 640x480 plasma: file.miff`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | | Creates a preview montage of images prepared |
+ | | | | over a parameteric range in order to assist |
+ | | | | with parameter selection. Specify the desired |
+ | | | | preview type via the -preview option). The |
+ | | | Show a preview an image | output file is always written in the |
+ | PREVIEW | W | enhancement, effect, or | ImageMagick MIFF_ format. |
+ | | | f/x | |
+ | | | | For example: |
+ | | | | |
+ | | | | ``gm convert file.tiff -preview gamma preview:file.miff`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | Send image to your | Unix users may set the PRINTER (for 'lp') or |
+ | PRINT | W | computer printer | LPDEST (for 'lpr') environment variables to |
+ | | | | select the desired printer. |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | Import image from a | Requires SANE_ Specify the device name and path |
+ | SCAN | R | scanner device | as the filename (e.g. "scan:mustek:/dev/scanner"). |
+ | | | | |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | STEGANO | R | Steganographic image | Use -size command line option to specify width, |
+ | | | | height, and offset of the steganographic image |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | | Create a tiled version of an image at by tiling |
+ | TILE | R | Tiled image | a image. Use -size to specify the tiled image |
+ | | | | size. The image is specified similar to |
+ | | | | "TILE:image.miff". |
+ | | | | For example: |
+ | | | | |
+ | | | | ``gm convert -size 800x600 tile:image.jpg out.jpg`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | | Used to create a thumbnailed directory (tiled |
+ | VID | RW | Visual Image Directory | thumbnails) of a set of images which may be |
+ | | | | used to select images to view via the display |
+ | | | | program, or saved to a MIFF_ or SHTML file. |
+ | | | | For example: |
+ | | | | |
+ | | | | ``gm convert vid:"*.jpg" index.miff`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | Select image from or | |
+ | WIN | RW | display image to your | Only supported under Microsoft Windows. For example: |
+ | | | computer screen | |
+ | | | | ``gm convert file.jpg -rotate 90 win:`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | Select image from or | |
+ | X | RW | display image to your X | Also see the import and display programs. For example: |
+ | | | server screen | |
+ | | | | ``gm convert file.jpg -rotate 90 x:`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+ | | | | Useful to create solid color "canvas" images. |
+ | | | Canvas image of | Use -size and -depth to specify the image |
+ | XC | R | specified color | width, height, and depth. Example XC color |
+ | | | | specifications include "XC:red" and "XC:# |
+ | | | | FF0000". See the color_ reference for the |
+ | | | | numeric values used for named colors. For example: |
+ | | | | |
+ | | | | ``gm convert -size 640x480 xc:red red.jpg`` |
+ +--------------+------+---------------------------+-------------------------------------------------------------+
+
+
+GraphicsMagick includes a number of built-in (embedded) images which may
+be referenced as if they were an image file. The ``IMAGE:`` format tag may
+be used via the syntax "IMAGE:name" to request an embedded image (e.g.
+``IMAGE:LOGO``). For backwards compatibility, the image specifications
+``GRANITE:``, ``LOGO:``, ``NETSCAPE:``, and ``ROSE:`` may also be used to request
+images with those names.
+
+A new canvas image of a specified size may be created using one of these pattern
+images using a command similar to::
+
+ gm convert -size 640x480 PATTERN:BRICKS bricks.miff
+
+The TILE: virtual image type may also be used similar to::
+
+ gm convert -size 640x480 TILE:IMAGE:BRICKS bricks.miff
+
+.. |bricks| image:: images/patterns/bricks.png
+.. |circles| image:: images/patterns/circles.png
+.. |checkerboard| image:: images/patterns/checkerboard.png
+.. |crosshatch30| image:: images/patterns/crosshatch30.png
+.. |crosshatch45| image:: images/patterns/crosshatch45.png
+.. |crosshatch| image:: images/patterns/crosshatch.png
+.. |fishscales| image:: images/patterns/fishscales.png
+.. |granite| image:: images/patterns/granite.png
+.. |gray0| image:: images/patterns/gray0.png
+.. |gray100| image:: images/patterns/gray100.png
+.. |gray10| image:: images/patterns/gray10.png
+.. |gray15| image:: images/patterns/gray15.png
+.. |gray20| image:: images/patterns/gray20.png
+.. |gray25| image:: images/patterns/gray25.png
+.. |gray30| image:: images/patterns/gray30.png
+.. |gray35| image:: images/patterns/gray35.png
+.. |gray40| image:: images/patterns/gray40.png
+.. |gray45| image:: images/patterns/gray45.png
+.. |gray50| image:: images/patterns/gray50.png
+.. |gray55| image:: images/patterns/gray55.png
+.. |gray5| image:: images/patterns/gray5.png
+.. |gray60| image:: images/patterns/gray60.png
+.. |gray65| image:: images/patterns/gray65.png
+.. |gray70| image:: images/patterns/gray70.png
+.. |gray75| image:: images/patterns/gray75.png
+.. |gray80| image:: images/patterns/gray80.png
+.. |gray85| image:: images/patterns/gray85.png
+.. |gray90| image:: images/patterns/gray90.png
+.. |gray95| image:: images/patterns/gray95.png
+.. |hexagons| image:: images/patterns/hexagons.png
+.. |horizontalsaw| image:: images/patterns/horizontalsaw.png
+.. |horizontal| image:: images/patterns/horizontal.png
+.. |hs_bdiagonal| image:: images/patterns/hs_bdiagonal.png
+.. |hs_cross| image:: images/patterns/hs_cross.png
+.. |hs_diagcross| image:: images/patterns/hs_diagcross.png
+.. |hs_fdiagonal| image:: images/patterns/hs_fdiagonal.png
+.. |hs_horizontal| image:: images/patterns/hs_horizontal.png
+.. |hs_vertical| image:: images/patterns/hs_vertical.png
+.. |left30| image:: images/patterns/left30.png
+.. |left45| image:: images/patterns/left45.png
+.. |leftshingle| image:: images/patterns/leftshingle.png
+.. |logo| image:: images/gm-125x80t.png
+.. |octagons| image:: images/patterns/octagons.png
+.. |right30| image:: images/patterns/right30.png
+.. |right45| image:: images/patterns/right45.png
+.. |rightshingle| image:: images/patterns/rightshingle.png
+.. |rose| image:: images/patterns/rose.png
+.. |smallfishscales| image:: images/patterns/smallfishscales.png
+.. |verticalbricks| image:: images/patterns/verticalbricks.png
+.. |verticalleftshingle| image:: images/patterns/verticalleftshingle.png
+.. |verticalrightshingle| image:: images/patterns/verticalrightshingle.png
+.. |verticalsaw| image:: images/patterns/verticalsaw.png
+.. |vertical| image:: images/patterns/vertical.png
+
+.. table:: Built-In Images And Patterns
+
+ +----------------------+------------------------------------+----------------------------------------+
+ | Name | Description | Notes/Sample |
+ +----------------------+------------------------------------+----------------------------------------+
+ | BRICKS | 16x16 brick pattern | |bricks| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | CHECKERBOARD | 30x30 checkerboard pattern | |checkerboard| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | CIRCLES | 16x16 circles pattern | |circles| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | CROSSHATCH | 8x4 crosshatch pattern | |crosshatch| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | CROSSHATCH30 | 8x4 crosshatch pattern with lines | |crosshatch30| |
+ | | at 30 degrees. | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | CROSSHATCH45 | 8x4 crosshatch pattern with lines | |crosshatch45| |
+ | | at 45 degrees. | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | FISHSCALES | 16x8 fish scales pattern | |fishscales| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRANITE | 128x128 granite texture pattern | |granite| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY0 | 32x32 0% intensity gray | |gray0| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY5 | 32x32 5% intensity gray | |gray5| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY10 | 32x32 10% intensity gray | |gray10| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY15 | 32x32 15% intensity gray | |gray15| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY20 | 32x32 20% intensity gray | |gray20| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY25 | 32x32 25% intensity gray | |gray25| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY30 | 32x32 30% intensity gray | |gray30| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY35 | 32x32 35% intensity gray | |gray35| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY40 | 32x32 40% intensity gray | |gray40| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY45 | 32x32 45% intensity gray | |gray45| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY50 | 32x32 50% intensity gray | |gray50| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY55 | 32x32 55% intensity gray | |gray55| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY60 | 32x32 60% intensity gray | |gray60| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY65 | 32x32 65% intensity gray | |gray65| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY70 | 32x32 70% intensity gray | |gray70| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY75 | 32x32 75% intensity gray | |gray75| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY80 | 32x32 80% intensity gray | |gray80| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY85 | 32x32 85% intensity gray | |gray85| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY90 | 32x32 90% intensity gray | |gray90| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY95 | 32x32 95% intensity gray | |gray95| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | GRAY100 | 32x32 100% intensity gray | |gray100| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HEXAGONS | 30x18 hexagon pattern | |hexagons| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HORIZONTAL | 8x4 horizontal line pattern | |horizontal| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HORIZONTALSAW | 16x8 horizontal saw-tooth pattern | |horizontalsaw| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HS_BDIAGONAL | 8x8 backward diagonal line pattern | |hs_bdiagonal| |
+ | | (45 degrees slope) | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HS_CROSS | 8x8 cross line pattern | |hs_cross| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HS_DIAGCROSS | 8x8 diagonal line cross pattern | |hs_diagcross| |
+ | | (45 degrees slope) | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HS_FDIAGONAL | 8x8 forward diagonal line pattern | |hs_fdiagonal| |
+ | | (45 degrees slope) | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HS_HORIZONTAL | 8x8 horizontal line pattern | |hs_horizontal| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | HS_VERTICAL | 8x8 vertical line pattern | |hs_vertical| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | LEFT30 | 8x4 forward diagonal pattern (30 | |left30| |
+ | | degrees slope) | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | LEFT45 | 8x8 forward diagonal line pattern | |left45| |
+ | | (45 degrees slope) | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | LEFTSHINGLE | 24x24 left shingle pattern | |leftshingle| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | LOGO | 640x480, GraphicsMagick Logo | |logo| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | | 216x144 image using colors in | Most commonly used with the |
+ | NETSCAPE | Netscape 216 (6x6x6 ) color cube. | convert_/mogrify_ -map option to |
+ | | | create *web safe* images. |
+ +----------------------+------------------------------------+----------------------------------------+
+ | OCTAGONS | 16x16 octagons pattern | |octagons| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | RIGHT30 | 8x4 backward diagonal line pattern | |right30| |
+ | | (30 degrees) | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | RIGHT45 | 8x8 backward diagonal line pattern | |right45| |
+ | | (30 degrees) | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | RIGHTSHINGLE | 24x24 right shingle pattern | |rightshingle| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | ROSE | 70x46, Picture of a rose. | |rose| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | SMALLFISHSCALES | 8x8 small fish scales pattern | |smallfishscales| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | VERTICAL | 8x8 vertical line pattern | |vertical| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | VERTICALBRICKS | 16x16 vertical brick pattern | |verticalbricks| |
+ +----------------------+------------------------------------+----------------------------------------+
+ | VERTICALLEFTSHINGLE | 24x24 vertical left shingle | |verticalleftshingle| |
+ | | pattern | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | VERTICALRIGHTSHINGLE | 24x24 vertical right shingle | |verticalrightshingle| |
+ | | pattern | |
+ +----------------------+------------------------------------+----------------------------------------+
+ | VERTICALSAW | 8x16 vertical saw-tooth pattern | |verticalsaw| |
+ +----------------------+------------------------------------+----------------------------------------+
+
+GraphicsMagick provides a number of format identifiers which are used
+to add, remove, and save embedded profiles for images which can
+support embedded profiles. Image types which may contain embedded
+profiles are TIFF_, JPEG_, PDF, and PNG.
+
+
+.. table:: Supported Embedded Profile Formats
+
+ +-------------------+------+----------------------------+-------------------------------------------------+
+ | Format | Mode | Description | Notes |
+ +-------------------+------+----------------------------+-------------------------------------------------+
+ | 8BIM | RW | Photoshop resource format | |
+ | | | (binary) | |
+ +-------------------+------+----------------------------+-------------------------------------------------+
+ | 8BIMTEXT | RW | Photoshop resource format | An ASCII representation of the 8BIM format. |
+ | | | (ASCII) | |
+ +-------------------+------+----------------------------+-------------------------------------------------+
+ | APP1 | RW | Raw application | |
+ | | | information | |
+ +-------------------+------+----------------------------+-------------------------------------------------+
+ | APP1JPEG | RW | Raw JPEG_ binary data | Profile in JPEG_ wrapper. |
+ +-------------------+------+----------------------------+-------------------------------------------------+
+ | ICC | RW | International Color | Also known as "ICM". To read, use -profile with |
+ | | | Consortium color profile | convert. |
+ +-------------------+------+----------------------------+-------------------------------------------------+
+ | IPTC | RW | IPTC Newsphoto (binary) | To read, use -profile with convert |
+ +-------------------+------+----------------------------+-------------------------------------------------+
+ | IPTCTEXT | RW | IPTC Newsphoto (ASCII) | An ASCII representation of the IPTC format. |
+ +-------------------+------+----------------------------+-------------------------------------------------+
+
+
+Support for some of the formats are delegated to libraries or external
+programs. The README describes where to find these distributions and
+any special configuration options required.
+
+To get a complete listing of the image formats which are supported on
+your system, type
+
+::
+
+ gm convert -list format
+
+On some platforms, GraphicsMagick automatically processes these
+extensions: .gz for Zip compression, .Z for Unix compression, and .bz2
+for block compression. For example, a PNM image called image.pnm.gz is
+automatically uncompressed while the image is read.
+
+-----------------------------------------------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/gm.html b/www/gm.html
new file mode 100644
index 0000000..4d30281
--- /dev/null
+++ b/www/gm.html
@@ -0,0 +1,18054 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+gm - command-line utility to create, edit, compare, convert, or display images
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm animate</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file</em> <strong>[ [</strong>
+<em>options ...</em> <strong>]</strong> <em>file ...</em> <strong>]</strong>
+<p>
+<strong>gm batch</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <strong>[</strong> <em>script</em> <strong>]</strong>
+<p>
+<strong>gm benchmark</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> subcommand
+<p>
+<strong>gm compare</strong> <strong>[</strong> <em>options</em> <strong>... ]</strong> <em>reference-image</em>
+<strong>[</strong> <em>options</em> <strong>... ]</strong> <em>compare-image</em>
+<strong>[</strong> <em>options</em> <strong>... ]</strong>
+<p>
+<strong>gm composite</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>change-image base-image</em>
+<strong>[</strong> <em>mask-image</em> <strong>]</strong> <em>output-image</em>
+<p>
+<strong>gm conjure</strong> <strong>[</strong> <em>options</em> <strong>]</strong> <em>script.msl</em>
+<strong>[ [</strong> <em>options</em> <strong>]</strong> <em>script.msl</em> <strong>]</strong>
+<p>
+<strong>gm convert</strong> <strong>[ [</strong> <em>options ...</em> <strong>] [</strong> <em>input-file ...</em>
+<strong>] [</strong> <em>options ...</em> <strong>] ]</strong> <em>output-file</em>
+<p>
+<strong>gm display</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file ...</em>
+<strong>[ [</strong><em>options ...</em> <strong>]</strong><em>file ...</em> <strong>]</strong>
+<p>
+<strong>gm identify</strong> <em>file</em> <strong>[</strong> <em>file ...</em> <strong>]</strong>
+<p>
+<strong>gm import</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file</em>
+<p>
+<strong>gm mogrify</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file ...</em>
+<p>
+<strong>gm montage</strong> <strong>[</strong> <em>options ...</em> <strong>]</strong> <em>file</em> <strong>[ [</strong>
+<em>options ...</em> <strong>]</strong> <em>file ...</em> <strong>]</strong> <em>output-file</em>
+<p>
+<strong>gm time</strong> subcommand
+<p>
+<strong>gm version</strong>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p> GraphicsMagick's <strong>gm</strong> provides a suite of utilities for
+creating, comparing, converting, editing, and displaying images. All
+of the utilities are provided as sub-commands of a single <strong>gm</strong>
+executable:
+<p>
+<strong>animate</strong>
+displays an animation (e.g. a GIF file) on any workstation display
+running an <em>X</em> server.
+<p>
+<strong>batch</strong>
+executes an arbitary number of the utility commands
+(e.g. <strong>convert</strong>) in the form of a simple linear batch script in
+order to improve execution efficiency, and/or to allow use as a
+subordinate co-process under the control of an arbitrary script or
+program.
+<p>
+<strong>benchmark</strong>
+executes one of the other utility commands (e.g. <strong>convert</strong>) for a
+specified number of iterations, or execution time, and reports
+execution time and other profiling information such as CPU
+utilization. <strong>Benchmark</strong> provides various operating modes
+including executing the command with a varying number of threads, and
+alternate reporting formats such as comma-separated value (CSV).
+<p>
+<strong>compare</strong>
+compares two images and reports difference statistics according to
+specified metrics and/or outputs an image with a visual representation
+of the differences. It may also be used to test if images are similar
+within a particular range and specified metric, returning a truth
+value to the executing environment.
+<p>
+<strong>composite</strong>
+composites images (blends or merges images together) to create new images.
+<p>
+<strong>conjure</strong>
+interprets and executes scripts in
+the Magick Scripting Language (MSL).
+<p>
+<strong>convert</strong>
+converts an input file using one image format to an output file with
+the same or differing image format while applying an arbitrary number
+of image transformations.
+<p>
+<strong>display</strong>
+is a machine architecture independent image processing and display
+facility. It can display an image on any workstation display running
+an <em>X</em> server.
+<p>
+<strong>identify</strong>
+describes the format and characteristics of one or more image
+files. It will also report if an image is incomplete or corrupt.
+<p>
+<strong>import</strong>
+reads an image from any visible window on an <em>X</em> server and
+outputs it as an image file. You can capture a single window, the
+entire screen, or any rectangular portion of the screen.
+<p>
+<strong>mogrify</strong>
+transforms an image or a sequence of images. These transforms include
+<strong>image scaling</strong>, <strong>image rotation</strong>, <strong>color reduction</strong>,
+and others. The transmogrified image <strong>overwrites</strong> the original
+image.
+<p>
+<strong>montage</strong>
+creates a composite by combining several separate images. The images
+are tiled on the composite image with the name of the image optionally
+appearing just below the individual tile.
+<p>
+<strong>time</strong>
+executes a subcommand and reports the user, system, and total
+execution time consumed.
+<p>
+<strong>version</strong>
+reports the GraphicsMagick release version, maximum sample-depth,
+copyright notice, supported features, and the options used while
+building the software.
+<p>
+The <strong>GraphicsMagick</strong> utilities recognize the following image formats:
+<br>&nbsp;<br>
+<table border="0" cellspacing="0" cellpadding="2">
+<p>
+<tr><td><strong>Name</strong> </td><td><strong>Mode</strong></td><td><strong>Description</strong></td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">3FR </td><td>r--</td><td>Hasselblad Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">8BIM </td><td>rw-</td><td>Photoshop resource format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">8BIMTEXT </td><td>rw-</td><td>Photoshop resource text format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">8BIMWTEXT</td><td>rw-</td><td>Photoshop resource wide text format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">APP1 </td><td>rw-</td><td>Raw application information</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">APP1JPEG </td><td>rw-</td><td>Raw JPEG binary data</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ART </td><td>r--</td><td>PF1: 1st Publisher</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ARW </td><td>r--</td><td>Sony Alpha DSLR RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">AVS </td><td>rw+</td><td>AVS X image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">BIE </td><td>rw-</td><td>Joint Bi-level Image experts Group</td></tr>
+<tr><td> </td><td> </td><td>interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">BMP </td><td>rw+</td><td>Microsoft Windows bitmap image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">BMP2 </td><td>-w-</td><td>Microsoft Windows bitmap image v2</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">BMP3 </td><td>-w-</td><td>Microsoft Windows bitmap image v3</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CACHE </td><td>---</td><td>Magick Persistent Cache image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CALS </td><td>rw-</td><td>Continuous Acquisition and Life-cycle</td></tr>
+<tr><td> </td><td> </td><td>Support Type 1 image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CAPTION </td><td>r--</td><td>Caption (requires separate size info)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CIN </td><td>rw-</td><td>Kodak Cineon Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CMYK </td><td>rw-</td><td>Raw cyan, magenta, yellow, and black</td></tr>
+<tr><td> </td><td> </td><td>samples (8 or 16 bits, depending on</td></tr>
+<tr><td> </td><td> </td><td>the image depth)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CMYKA </td><td>rw-</td><td>Raw cyan, magenta, yellow, black, and</td></tr>
+<tr><td> </td><td> </td><td>matte samples (8 or 16 bits, depending</td></tr>
+<tr><td> </td><td> </td><td>on the image depth)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CR2 </td><td>r--</td><td>Canon Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CRW </td><td>r--</td><td>Canon Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CUR </td><td>r--</td><td>Microsoft Cursor Icon</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">CUT </td><td>r--</td><td>DR Halo</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DCM </td><td>r--</td><td>Digital Imaging and Communications in</td></tr>
+<tr><td> </td><td> </td><td>Medicine image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DCR </td><td>r--</td><td>Kodak Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DCX </td><td>rw+</td><td>ZSoft IBM PC multi-page Paintbrush</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DNG </td><td>r--</td><td>Adobe Digital Negative</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DPS </td><td>r--</td><td>Display PostScript Interpreter</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">DPX </td><td>rw-</td><td>Digital Moving Picture Exchange</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPDF </td><td>rw-</td><td>Encapsulated Portable Document Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPI </td><td>rw-</td><td>Adobe Encapsulated PostScript</td></tr>
+<tr><td> </td><td> </td><td>Interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPS </td><td>rw-</td><td>Adobe Encapsulated PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPS2 </td><td>-w-</td><td>Adobe Level II Encapsulated PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPS3 </td><td>-w-</td><td>Adobe Level III Encapsulated PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPSF </td><td>rw-</td><td>Adobe Encapsulated PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPSI </td><td>rw-</td><td>Adobe Encapsulated PostScript</td></tr>
+<tr><td> </td><td> </td><td>Interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPT </td><td>rw-</td><td>Adobe Encapsulated PostScript with MS-DOS</td></tr>
+<tr><td> </td><td> </td><td>TIFF preview</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPT2 </td><td>rw-</td><td>Adobe Level II Encapsulated PostScript</td></tr>
+<tr><td> </td><td> </td><td>with MS-DOS TIFF preview</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EPT3 </td><td>rw-</td><td>Adobe Level III Encapsulated PostScript</td></tr>
+<tr><td> </td><td> </td><td>with MS-DOS TIFF preview</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">EXIF </td><td>rw-</td><td>Exif digital camera binary data</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">FAX </td><td>rw+</td><td>Group 3 FAX (Not TIFF Group3 FAX!)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">FITS </td><td>rw-</td><td>Flexible Image Transport System</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">FRACTAL </td><td>r--</td><td>Plasma fractal image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">FPX </td><td>rw-</td><td>FlashPix Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">GIF </td><td>rw+</td><td>CompuServe graphics interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">GIF87 </td><td>rw-</td><td>CompuServe graphics interchange format</td></tr>
+<tr><td> </td><td> </td><td>(version 87a)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">GRADIENT </td><td>r--</td><td>Gradual passing from one shade to</td></tr>
+<tr><td> </td><td> </td><td>another</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">GRAY </td><td>rw+</td><td>Raw gray samples (8/16/32 bits,</td></tr>
+<tr><td> </td><td> </td><td>depending on the image depth)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">HISTOGRAM</td><td>-w-</td><td>Histogram of the image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">HRZ </td><td>r--</td><td>HRZ: Slow scan TV</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">HTML </td><td>-w-</td><td>Hypertext Markup Language and a</td></tr>
+<tr><td> </td><td> </td><td>client-side image map</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICB </td><td>rw+</td><td>Truevision Targa image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICC </td><td>rw-</td><td>ICC Color Profile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICM </td><td>rw-</td><td>ICC Color Profile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICO </td><td>r--</td><td>Microsoft icon</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">ICON </td><td>r--</td><td>Microsoft icon</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IDENTITY </td><td>r--</td><td>Hald CLUT identity image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IMAGE </td><td>r--</td><td>GraphicsMagick Embedded Image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">INFO </td><td>-w+</td><td>Image descriptive information and</td></tr>
+<tr><td> </td><td> </td><td> statistics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IPTC </td><td>rw-</td><td>IPTC Newsphoto</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IPTCTEXT </td><td>rw-</td><td>IPTC Newsphoto text format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">IPTCWTEXT</td><td>rw-</td><td>IPTC Newsphoto wide text format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JBG </td><td>rw+</td><td>Joint Bi-level Image experts Group</td></tr>
+<tr><td> </td><td> </td><td>interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JBIG </td><td>rw+</td><td>Joint Bi-level Image experts Group</td></tr>
+<tr><td> </td><td> </td><td>interchange format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JNG </td><td>rw-</td><td>JPEG Network Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JP2 </td><td>rw-</td><td>JPEG-2000 JP2 File Format Syntax</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JPC </td><td>rw-</td><td>JPEG-2000 Code Stream Syntax</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JPEG </td><td>rw-</td><td>Joint Photographic Experts Group</td></tr>
+<tr><td> </td><td> </td><td>JFIF format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">JPG </td><td>rw-</td><td>Joint Photographic Experts Group</td></tr>
+<tr><td> </td><td> </td><td>JFIF format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">K25 </td><td>r--</td><td>Kodak Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">KDC </td><td>r--</td><td>Kodak Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">LABEL </td><td>r--</td><td>Text image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">M2V </td><td>rw+</td><td>MPEG-2 Video Stream</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MAP </td><td>rw-</td><td>Colormap intensities and indices</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MAT </td><td>r--</td><td>MATLAB image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MATTE </td><td>-w+</td><td>MATTE format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MIFF </td><td>rw+</td><td>Magick Image File Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MNG </td><td>rw+</td><td>Multiple-image Network Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MONO </td><td>rw-</td><td>Bi-level bitmap in least-significant-</td></tr>
+<tr><td> </td><td> </td><td>-byte-first order</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MPC </td><td>rw+</td><td>Magick Persistent Cache image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MPEG </td><td>rw+</td><td>MPEG-1 Video Stream</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MPG </td><td>rw+</td><td>MPEG-1 Video Stream</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MRW </td><td>r--</td><td>Minolta Photo Raw</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MSL </td><td>r--</td><td>Magick Scripting Language</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MTV </td><td>rw+</td><td>MTV Raytracing image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">MVG </td><td>rw-</td><td>Magick Vector Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">NEF </td><td>r--</td><td>Nikon Electronic Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">NULL </td><td>r--</td><td>Constant image of uniform color</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">OTB </td><td>rw-</td><td>On-the-air bitmap</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">P7 </td><td>rw+</td><td>Xv thumbnail format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PAL </td><td>rw-</td><td>16bit/pixel interleaved YUV</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PALM </td><td>rw-</td><td>Palm Pixmap</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PBM </td><td>rw+</td><td>Portable bitmap format (black and white)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCD </td><td>rw-</td><td>Photo CD</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCDS </td><td>rw-</td><td>Photo CD</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCL </td><td>-w-</td><td>Page Control Language</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCT </td><td>rw-</td><td>Apple Macintosh QuickDraw/PICT</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PCX </td><td>rw-</td><td>ZSoft IBM PC Paintbrush</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PDB </td><td>rw+</td><td>Palm Database ImageViewer Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PDF </td><td>rw+</td><td>Portable Document Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PEF </td><td>r--</td><td>Pentax Electronic File</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PFA </td><td>r--</td><td>TrueType font</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PFB </td><td>r--</td><td>TrueType font</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PGM </td><td>rw+</td><td>Portable graymap format (gray scale)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PGX </td><td>r--</td><td>JPEG-2000 VM Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PICON </td><td>rw-</td><td>Personal Icon</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PICT </td><td>rw-</td><td>Apple Macintosh QuickDraw/PICT</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PIX </td><td>r--</td><td>Alias/Wavefront RLE image format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PLASMA </td><td>r--</td><td>Plasma fractal image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNG </td><td>rw-</td><td>Portable Network Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNG24 </td><td>rw-</td><td>Portable Network Graphics, 24 bit RGB</td></tr>
+<tr><td> </td><td> </td><td>opaque only</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNG32 </td><td>rw-</td><td>Portable Network Graphics, 32 bit RGBA</td></tr>
+<tr><td> </td><td> </td><td>semitransparency OK</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNG8 </td><td>rw-</td><td>Portable Network Graphics, 8-bit</td></tr>
+<tr><td> </td><td> </td><td>indexed, binary transparency only</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PNM </td><td>rw+</td><td>Portable anymap</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PPM </td><td>rw+</td><td>Portable pixmap format (color)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PREVIEW </td><td>-w-</td><td>Show a preview an image enhancement,</td></tr>
+<tr><td> </td><td> </td><td>effect, or f/x</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PS </td><td>rw+</td><td>Adobe PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PS2 </td><td>-w+</td><td>Adobe Level II PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PS3 </td><td>-w+</td><td>Adobe Level III PostScript</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PSD </td><td>rw-</td><td>Adobe Photoshop bitmap</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PTIF </td><td>rw-</td><td>Pyramid encoded TIFF</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">PWP </td><td>r--</td><td>Seattle Film Works</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RAF </td><td>r--</td><td>Fuji Photo RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RAS </td><td>rw+</td><td>SUN Rasterfile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RGB </td><td>rw+</td><td>Raw red, green, and blue samples</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RGBA </td><td>rw+</td><td>Raw red, green, blue, and matte samples</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RLA </td><td>r--</td><td>Alias/Wavefront image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">RLE </td><td>r--</td><td>Utah Run length encoded image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SCT </td><td>r--</td><td>Scitex HandShake</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SFW </td><td>r--</td><td>Seattle Film Works</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SGI </td><td>rw+</td><td>Irix RGB image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SHTML </td><td>-w-</td><td>Hypertext Markup Language and a</td></tr>
+<tr><td> </td><td> </td><td>client-side image map</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">STEGANO </td><td>r--</td><td>Steganographic image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SUN </td><td>rw+</td><td>SUN Rasterfile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">SVG </td><td>rw+</td><td>Scalable Vector Gaphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TEXT </td><td>rw+</td><td>Raw text</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TGA </td><td>rw+</td><td>Truevision Targa image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TIFF </td><td>rw+</td><td>Tagged Image File Format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TILE </td><td>r--</td><td>Tile image with a texture</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TIM </td><td>r--</td><td>PSX TIM</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TOPOL </td><td>r--</td><td>TOPOL X Image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TTF </td><td>r--</td><td>TrueType font</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">TXT </td><td>rw+</td><td>Raw text</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">UIL </td><td>-w-</td><td>X-Motif UIL table</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">UYVY </td><td>rw-</td><td>16bit/pixel interleaved YUV</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VDA </td><td>rw+</td><td>Truevision Targa image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VICAR </td><td>rw-</td><td>VICAR rasterfile format</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VID </td><td>rw+</td><td>Visual Image Directory</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VIFF </td><td>rw+</td><td>Khoros Visualization image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">VST </td><td>rw+</td><td>Truevision Targa image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">WBMP </td><td>rw-</td><td>Wireless Bitmap (level 0) image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">WMF </td><td>r--</td><td>Windows Metafile</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">WPG </td><td>r--</td><td>Word Perfect Graphics</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">X </td><td>rw-</td><td>X Image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">X3F </td><td>r--</td><td>Foveon X3 (Sigma/Polaroid) RAW</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XBM </td><td>rw-</td><td>X Windows system bitmap (black</td></tr>
+<tr><td> </td><td> </td><td>and white)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XC </td><td>r--</td><td>Constant image uniform color</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XCF </td><td>r--</td><td>GIMP image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XMP </td><td>rw-</td><td>Adobe XML metadata</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XPM </td><td>rw-</td><td>X Windows system pixmap (color)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XV </td><td>rw+</td><td>Khoros Visualization image</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">XWD </td><td>rw-</td><td>X Windows system window dump (color)</td></tr>
+<tr><td><dd><img SRC="images/ball.png" ALT="*">YUV </td><td>rw-</td><td>CCIR 601 4:1:1 or 4:2:2 (8-bit only)</td></tr>
+<tr><td> </td><td> </td><td></td></tr>
+<tr><td> Modes: </td><td> </td><td></td></tr>
+<tr><td> </td><td>r </td><td>Read</td></tr>
+<tr><td> </td><td>w </td><td>Write</td></tr>
+<tr><td> </td><td>+ </td><td>Multi-image</td></tr>
+<br>&nbsp;<br>
+</table>
+<p>
+<em>Support for some of these formats require additional programs or libraries.
+See <a href="README.html">README</a>
+in the source package for where to find optional additional software</em>.
+<p>
+Note, a format delineated with <tt>+</tt> means that if more than one
+image is specified, frames are combined into a single multi-image
+file. Use <strong>+adjoin</strong> if you want a single image produced for each
+frame.
+<p>
+Your installation might not support all of the formats in the list.
+To get an accurate listing of the formats supported by your particular
+configuration, run <tt>"gm convert -list format"</tt>.
+<p>
+Raw images are expected to have one byte per pixel unless <strong>gm</strong> is
+compiled in 16-bit quantum mode or in 32-bit quantum mode. Here, the
+raw data is expected to be stored two or four bytes per pixel,
+respectively, in most-significant-byte-first order. For example, you
+can tell if <strong>gm</strong> was compiled in 16-bit mode by typing "gm
+version" without any options, and looking for "Q:16" in the first line
+of output.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="files"></a>Files and Formats
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+By default, the image format is determined by its magic number, i.e., the
+first few bytes of the file. To specify
+a particular image format, precede the filename with an image format name
+and a colon (<em>i.e.</em><strong>ps:image</strong>) or specify the image type as the
+filename suffix (<em>i.e.</em><strong>image.ps</strong>).
+The magic number takes precedence over the filename suffix
+and the prefix takes precedence over the magic number and the suffix
+in input files.
+When a file is read, its magic number is stored in the "image-&gt;magick"
+string.
+In output files, the prefix takes precedence over the filename suffix,
+and the filename suffix takes precedence over the
+"image-&gt;magick" string.
+<br>&nbsp;<br>
+<p>To read the "built-in" formats (GRANITE, H, LOGO,
+NETSCAPE, PLASMA, and ROSE) use a prefix (including the colon) without a
+filename or suffix. To read the XC format, follow the colon with a color
+specification. To read the CAPTION format, follow the colon with a text
+string or with a filename prefixed with the at symbol (<strong>@</strong>).
+<br>&nbsp;<br>
+<p>
+When you specify <strong>X</strong> as your image type, the filename has special
+meaning. It specifies an X window by <strong>id, name</strong>, or
+<strong>root</strong>. If
+no filename is specified, the window is selected by clicking the mouse
+in the desired window.
+<p>
+Specify <em>input_file</em> as <strong>-</strong> for standard input,
+<em>output_file</em> as <strong>-</strong> for standard output.
+If <em>input_file</em> has the extension <strong>.Z</strong> or <strong>.gz</strong>, the
+file is uncompressed with <strong>uncompress</strong> or <strong>gunzip</strong>
+respectively.
+If <em>output_file</em> has the extension <strong>.Z</strong> or <strong>.gz</strong>,
+the file is compressed using with <em>compress</em> or <em>gzip</em> respectively.
+<p>
+Use an optional index enclosed in brackets after an input file name to
+specify a desired subimage of a multi-resolution image format like
+Photo CD (e.g. <tt>"img0001.pcd[4]"</tt>) or a range for MPEG images
+(e.g. <tt>"video.mpg[50-75]"</tt>). A subimage specification can be
+disjoint (e.g. <tt>"image.tiff[2,7,4]"</tt>). For raw images, specify
+a subimage with a geometry (e.g. <tt>-size 640x512</tt>
+<tt>"image.rgb[320x256+50+50]"</tt>). Surround the image name with
+quotation marks to prevent your shell from interpreting the square
+brackets. <p>Single images are written with the filename you
+specify. However, multi-part images (e.g., a multi-page PostScript
+document with <strong>+adjoin</strong> specified) may be written with the scene
+number included as part of the filename. In order to include the scene
+number in the filename, it is necessary to include a printf-style
+<tt>%d</tt> format specification in the file name and use the +adjoin
+option. For example,
+<pre>
+ image%02d.miff
+</pre>
+<p>
+writes files <em>image00.miff, image01.miff,</em> etc. Only a single
+specification is allowed within an output filename. If more than one
+specification is present, it will be ignored. It is best to embed the
+scene number in the base part of the file name, not in the extension,
+because the extension will not be a recognizeable image type.
+<p>
+When running a commandline utility, you can
+prepend an at sign <tt>@</tt> to a filename to read a list of image
+filenames from that file. This is convenient in the event you have too
+many image filenames to fit on the command line.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or <strong>-noop</strong>.
+Some options only affect the decoding of images and others only the encoding.
+The latter can appear after the final group of input images.
+<p>
+This is a combined list of the command-line options used by the
+GraphicsMagick utilities (<em>animate</em>, <em>compare</em>,
+<em>composite</em>, <em>convert</em>, <em>display</em>, <em>identify</em>,
+<em>import</em>, <em>mogrify</em> and <em>montage</em>).
+<br>&nbsp;<br>
+<p>
+In this document, angle brackets ("&lt;&gt;") enclose variables and curly
+brackets ("{}") enclose optional parameters. For example,
+"<strong>-fuzz &lt;distance&gt;{%}</strong>" means you can use the
+option <tt>"-fuzz 10"</tt>
+or <tt>"-fuzz 2%"</tt>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-adjoin"></a>-adjoin
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>join images into a single multi-image file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, all images of an image sequence are stored in the same
+file. However, some formats (e.g. JPEG) do not support storing more
+than one image per file and only the first frame in an image sequence
+will be saved unless the result is saved to separate files. Use
+<strong>+adjoin</strong> to force saving multiple frames to multiple numbered
+files. If <strong>+adjoin</strong> is used, then the output filename must
+include a printf style formatting specification for the numeric part
+of the filename. For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ image%02d.miff
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-affine"></a>-affine <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>drawing transform matrix</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option provides a transform matrix <tt>{sx,rx,ry,sy,tx,ty}</tt> for
+use by subsequent <strong>-draw</strong> or <strong>-transform</strong> options.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-antialias"></a>-antialias
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixel aliasing</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default antialiasing algorithms are used when drawing objects (e.g. lines)
+or rendering vector formats (e.g. WMF and Postscript). Use +antialias to
+disable use of antialiasing algorithms. Reasons to disable antialiasing
+include avoiding increasing colors in the image, or improving rendering speed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-append"></a>-append
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>append a set of images</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option creates a single image where the images in the original set
+are stacked top-to-bottom. If they are not of the same width,
+any narrow images will be expanded to fit using the background color.
+Use <strong>+append</strong> to stack images left-to-right. The set of images
+is terminated by the appearance of any option.
+If the <strong>-append</strong>
+option appears after all of the input images, all images are appended.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details"></a> <i>-asc-cdl &lt;spec&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply ASC CDL color transform</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Applies ("bakes in") the ASC CDL, which is a format for the exchange
+of basic primary color grading information between equipment and
+software from different manufacturers. The format defines the math for
+three functions: slope, offset and power. Each function uses a number
+for the red, green, and blue color channels for a total of nine
+numbers comprising a single color decision. The tenth number
+(optional) is for chromiance (saturation) as specified by ASC CDL
+1.2.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The argument string is comma delimited and is in the following form
+(but without invervening spaces or line breaks)</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ redslope,redoffset,redpower:
+ greenslope,greenoffset,greenpower:
+ blueslope,blueoffset,bluepower:
+ saturation
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+with the unity (no change) specification being:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ "1.0,0.0,1.0:1.0,0.0,1.0:1.0,0.0,1.0:1.0"
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-authenticate"></a>-authenticate <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to supply a password for decrypting an image or an
+image sequence, if it is being read from a format such as PDF that supports
+encryption. Encrypting images being written is not supported.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-auto-orient"></a>-auto-orient
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>orient (rotate) image so it is upright</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Adjusts the image orienation so that it is suitable for viewing. Uses
+the orientation tag obtained from the image file or as supplied by the
+<strong>-orient</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-average"></a>-average
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>average a set of images</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The set of images
+is terminated by the appearance of any option.
+If the <strong>-average</strong>
+option appears after all of the input images, all images are averaged.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-backdrop"></a>-backdrop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the image centered on a backdrop.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This backdrop covers the entire workstation screen and is useful for hiding
+other X window activity while viewing the image. The color of the backdrop
+is specified as the foreground color (X11 default is black).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Refer to
+"X Resources", below,
+for details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-background"></a>-background <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-black-threshold"></a>-black-threshold <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels below the threshold become black</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>-black-threshold</strong> to set pixels with values below the specified
+threshold to minimum value (black). If only one value is supplied, or the
+red, green, and blue values are identical, then intensity thresholding is
+used. If the color threshold values are not identical then channel-based
+thresholding is used, and color distortion will occur. Specify a negative
+value (e.g. -1) if you want a channel to be ignored but you do want to
+threshold a channel later in the list. If a percent (%) symbol is
+appended, then the values are treated as a percentage of maximum
+range.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-blue-primary"></a>-blue-primary <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-blur"></a>-blur <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Blur with the given radius and
+standard deviation (sigma).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-border"></a>-border <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with a border of color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details
+about the geometry specification.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-bordercolor"></a>-bordercolor <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -borderwidth <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-box"></a>-box <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the color of the annotation bounding box</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-draw</strong> for further
+details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-channel"></a>-channel <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of channel</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from: <strong>Red</strong>, <strong>Green</strong>, <strong>Blue</strong>, <strong>Opacity</strong>,
+<strong>Matte</strong>, <strong>Cyan</strong>, <strong>Magenta</strong>, <strong>Yellow</strong>, <strong>Black</strong>,
+or <strong>Gray</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to extract a particular <em>channel</em> from the image.
+<strong>Opacity</strong>,
+for example, is useful for extracting the opacity values from an image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -charcoal <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate a charcoal drawing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-chop"></a>-chop <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixels from the interior of an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>Width</em> and <em>height</em> give the number of columns and rows to remove,
+and <em>x</em> and <em>y</em> are offsets that give the location of the
+leftmost column and topmost row to remove.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <em>x</em> offset normally specifies the leftmost column to remove.
+If the <strong>-gravity</strong> option is present with <em>NorthEast, East,</em>
+or <em>SouthEast</em>
+gravity, it gives the distance leftward from the right edge
+of the image to the rightmost column to remove. Similarly, the <em>y</em> offset
+normally specifies the topmost row to remove, but if
+the <strong>-gravity</strong> option is present with <em>SouthWest, South,</em>
+or <em>SouthEast</em>
+gravity, it specifies the distance upward from the bottom edge of the
+image to the bottom row to remove.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-chop</strong> option removes entire rows and columns,
+and moves the remaining corner blocks leftward and upward to close the gaps.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-clip"></a>-clip
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply the clipping path, if one is present</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If a clipping path is present, it will be applied to subsequent operations.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, if you type the following command:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -clip -negate cockatoo.tif negated.tif
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+only the pixels within the clipping path are negated.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-clip</strong> feature requires the XML library. If the XML library
+is not present, the option is ignored.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-coalesce"></a>-coalesce
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>merge a sequence of images</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Each image N in the sequence after Image 0 is replaced with the image
+created by flattening images 0 through N.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The set of images
+is terminated by the appearance of any option.
+If the <strong>-coalesce</strong>
+option appears after all of the input images, all images are coalesced.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-colorize"></a>-colorize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colorize the image with the pen color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify the amount of colorization as a percentage. You can apply separate
+colorization values to the red, green, and blue channels of the image with
+a colorization value list delimited with slashes (e.g. 0/0/50).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-colorize</strong> option may be used in conjunction with <strong>-modulate</strong>
+to produce a nice sepia toned image like:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert input.ppm -modulate 115,0,100 \
+ -colorize 7,21,50 output.ppm.
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-colormap"></a>-colormap <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the colormap type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose between <strong>shared</strong> or <strong>private</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option only applies when the default X server visual is <em>PseudoColor</em>
+or <em>GRAYScale</em>. Refer to <strong>-visual</strong> for more details. By default,
+a shared colormap is allocated. The image shares colors with other X clients.
+Some image colors could be approximated, therefore your image may look
+very different than intended. Choose <strong>Private</strong> and the image colors
+appear exactly as they are defined. However, other clients may
+go <em>technicolor</em> when the image colormap is installed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-colors"></a>-colors <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The actual number of colors in the image may be less than your request,
+but never more. Note, this is a color reduction option. Images with less
+unique colors than specified with this option will have any duplicate or
+unused colors removed. The ordering of an existing color palette may be
+altered. When converting an image from color to grayscale, convert the
+image to the gray colorspace before reducing the number of colors since
+doing so is most efficient. Refer to &lt;a
+href="quantize.html"&gt;quantize</a> for more details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Note, options <strong>-dither</strong>, <strong>-colorspace</strong>, and <strong>-treedepth</strong>
+affect the color reduction algorithm.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-colorspace"></a>-colorspace <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are:
+<strong>CineonLog</strong>, <strong>CMYK</strong>, <strong>GRAY</strong>, <strong>HSL</strong>, <strong>HWB</strong>,
+<strong>OHTA</strong>, <strong>RGB</strong>, <strong>Rec601Luma</strong>, <strong>Rec709Luma</strong>,
+<strong>Rec601YCbCr</strong>, <strong>Rec709YCbCr</strong>, <strong>Transparent</strong>, <strong>XYZ</strong>,
+<strong>YCbCr</strong>, <strong>YIQ</strong>, <strong>YPbPr</strong>, or <strong>YUV</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Color reduction, by default, takes place in the RGB color space. Empirical
+evidence suggests that distances in color spaces such as YUV or YIQ correspond
+to perceptual color differences more closely than do distances in RGB space.
+These color spaces may give better results when color reducing an image.
+Refer to <a href="quantize.html">quantize</a> for more details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Two gray colorspaces are supported. The <strong>Rec601Luma</strong> space is
+based on the recommendations for legacy NTSC television (ITU-R
+BT.601-5). The <strong>Rec709Luma</strong> space is based on the
+recommendations for HDTV (Rec. ITU-R BT.709-5) and is suitable for use
+with computer graphics, and for contemporary CRT displays. The
+<strong>GRAY</strong> colorspace currently selects the <strong>Rec601Luma</strong>
+colorspace by default for backwards compatibly reasons. This default
+may be re-considered in the future.
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Two YCbCr colorspaces are supported. The <strong>Rec601YCbCr</strong> space is
+based on the recommendations for legacy NTSC television (ITU-R BT.601-5). The
+<strong>Rec709CbCr</strong> space is based on the recommendations for HDTV (Rec.
+ITU-R BT.709-5) and is suitable for suitable for use with computer
+graphics, and for contemporary CRT displays. The <strong>YCbCr</strong> colorspace
+specification is equivalent to<strong>Rec601YCbCr</strong>.
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>Transparent</strong> color space behaves uniquely in that it preserves
+the matte channel of the image if it exists.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-colors</strong> or <strong>-monochrome</strong> option, or saving to a file
+format which requires color reduction, is required for this option to
+take effect.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-comment"></a>-comment <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to assign a specific comment to the image, when writing
+to an image format that supports comments. You can include the
+image filename, type, width, height, or other image attribute by embedding
+special format characters listed under the <strong>-format</strong> option.
+The comment is not drawn on the image, but is embedded in the image
+datastream via a "Comment" tag or similar mechanism. If you want the
+comment to be visible on the image itself, use the <strong>-draw</strong> option
+instead.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -comment "%m:%f %wx%h"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+produces an image comment of <strong>MIFF:bird.miff 512x480</strong> for an image
+titled <strong>bird.miff</strong> and whose width is 512 and height is 480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the first character of <em>string</em> is <em>@</em>, the image comment
+is read from a file titled by the remaining characters in the string.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the -comment option appears multiple times, only the last comment is
+stored.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In PNG images, the comment is stored in a <strong>tEXt</strong> or <strong>zTXt</strong> chunk
+with the keyword "comment".</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-compose"></a>-compose <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The description of composition uses abstract terminology in order to
+allow the the description to be more clear, while avoiding constant
+values which are specific to a particular build configuration. Each image
+pixel is represented by red, green, and blue levels (which are equal for
+a gray pixel). MaxRGB is the maximum integral value which may be stored
+in the red, green, or blue channels of the image. Each image pixel may
+also optionally (if the image matte channel is enabled) have an
+associated level of opacity (ranging from opaque to transparent), which
+may be used to determine the influence of the pixel color when
+compositing the pixel with another image pixel. If the image matte
+channel is disabled, then all pixels in the image are treated as opaque.
+The color of an <em>opaque</em> pixel is fully visible while the color of a
+<em>transparent</em> pixel color is entirely absent (pixel color is ignored).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By definition, raster images have a rectangular shape. All image rows are
+of equal length, and all image columns have the same number of rows. By
+treating the opacity channel as a visual "mask" the rectangular image may
+be given a "shape" by treating the opacity channel as a cookie-cutter for
+the image. Pixels within the shape are opaque, while pixels outside the
+shape are transparent. Pixels on the boundary of the shape may be between
+opaque and transparent in order to provide antialiasing (visually smooth
+edges). The description of the composition operators use this concept of
+image "shape" in order to make the description of the operators easier to
+understand. While it is convenient to describe the operators in terms of
+"shapes" they are by no means limited to mask-style operations since they
+are based on continuous floating-point mathematics rather than simple
+boolean operations.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, the <em>Over</em> composite operator is used. The following
+composite operators are available:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Over
+ In
+ Out
+ Atop
+ Xor
+ Plus
+ Minus
+ Add
+ Subtract
+ Difference
+ Divide
+ Multiply
+ Bumpmap
+ Copy
+ CopyRed
+ CopyGreen
+ CopyBlue
+ CopyOpacity
+ CopyCyan
+ CopyMagenta
+ CopyYellow
+ CopyBlack
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The behavior of each operator is described below.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>Over</dt>
+<dd>The result will be the union of the two image shapes, with opaque areas
+of <em>change-image</em> obscuring <em>base-image</em> in the region of
+overlap.
+</dd>
+<dt>In</dt>
+<dd>The result is simply <em>change-image</em> cut by the shape of
+<em>base-image</em>. None of the image data of <em>base-image</em> will be in
+the result.
+</dd>
+<dt>Out</dt>
+<dd>The resulting image is <em>change-image</em> with the shape of
+<em>base-image</em> cut out.
+</dd>
+<dt>Atop</dt>
+<dd>The result is the same shape as <em>base-image</em>, with
+<em>change-image</em> obscuring <em>base-image</em> where the image shapes
+overlap. Note this differs from <strong>over</strong> because the portion of
+<em>change-image</em> outside <em>base-image</em>'s shape does not appear in
+the result.
+</dd>
+<dt>Xor</dt>
+<dd>The result is the image data from both <em>change-image</em> and
+<em>base-image</em> that is outside the overlap region. The overlap region
+will be blank.
+</dd>
+<dt>Plus</dt>
+<dd>The result is just the sum of the image data. Output values are cropped
+to MaxRGB (no overflow). This operation is independent of the matte
+channels.
+</dd>
+<dt>Minus</dt>
+<dd>The result of <em>change-image</em> - <em>base-image</em>, with underflow
+cropped to zero. The matte channel is ignored (set to opaque, full
+coverage).
+</dd>
+<dt>Add</dt>
+<dd>The result of <em>change-image</em> + <em>base-image</em>, with overflow
+wrapping around (<em>mod</em> MaxRGB+1).
+</dd>
+<dt>Subtract</dt>
+<dd>The result of <em>change-image</em> - <em>base-image</em>, with underflow
+wrapping around (<em>mod</em> MaxRGB+1). The <strong>add</strong> and <strong>subtract</strong>
+operators can be used to perform reversible transformations.
+</dd>
+<dt>Difference</dt>
+<dd>The result of abs(<em>change-image</em> - <em>base-image</em>). This is
+useful for comparing two very similar images.
+</dd>
+<dt>Divide</dt>
+<dd>The result of <em>change-image</em> / <em>base-image</em>. This is useful
+for improving the readability of text on unevenly illuminated photos (by
+using a gaussian blurred copy of change-image as base-image).
+</dd>
+<dt>Multiply</dt>
+<dd>The result of <em>change-image</em> * <em>base-image</em>. This is useful for
+the creation of drop-shadows.
+</dd>
+<dt>Bumpmap</dt>
+<dd>The result <em>base-image</em> shaded by <em>change-image</em>.
+</dd>
+<dt>Copy</dt>
+<dd>The resulting image is <em>base-image</em> replaced with
+<em>change-image</em>. Here the matte information is ignored.
+</dd>
+<dt>CopyRed</dt>
+<dd>The resulting image is the red channel in <em>base-image</em> replaced with
+the red channel in <em>change-image</em>. The other channels are copied
+untouched.
+</dd>
+<dt>CopyGreen</dt>
+<dd>The resulting image is the green channel in <em>base-image</em> replaced
+with the green channel in <em>change-image</em>. The other channels are
+copied untouched.
+</dd>
+<dt>CopyBlue</dt>
+<dd>The resulting image is the blue channel in <em>base-image</em> replaced
+with the blue channel in <em>change-image</em>. The other channels are
+copied untouched.
+</dd>
+<dt>CopyOpacity</dt>
+<dd>The resulting image is the opacity channel in <em>base-image</em> replaced
+with the opacity channel in <em>change-image</em>. The other channels are
+copied untouched.
+</dd>
+<dt>CopyCyan</dt>
+<dd>The resulting image is the cyan channel in <em>base-image</em> replaced
+with the cyan channel in <em>change-image</em>. The other channels are
+copied untouched. Use of this operator requires that base-image be in
+CMYK(A) colorspace.
+</dd>
+<dt>CopyMagenta</dt>
+<dd>The resulting image is the magenta channel in <em>base-image</em>
+replaced with the magenta channel in <em>change-image</em>. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace.
+</dd>
+<dt>CopyYellow</dt>
+<dd>The resulting image is the yellow channel in <em>base-image</em>
+replaced with the yellow channel in <em>change-image</em>. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace.
+</dd>
+<dt>CopyBlack</dt>
+<dd>The resulting image is the black channel in <em>base-image</em>
+replaced with the black channel in <em>change-image</em>. The other
+channels are copied untouched. Use of this operator requires that
+base-image be in CMYK(A) colorspace. If change-image is not in CMYK
+space, then the change-image pixel intensities are used.
+</dd>
+</dl>
+</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-compress"></a>-compress <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are: <em>None</em>, <em>BZip</em>, <em>Fax</em>,
+<em>Group4</em>,
+<em>JPEG</em>, <em>Lossless</em>,
+<em>LZW</em>, <em>RLE</em>, <em>Zip</em>, or <em>LZMA</em>.
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <strong>+compress</strong> to store the binary image in an uncompressed format.
+The default is the compression type of the specified image file.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>"Lossless"</em> refers to lossless JPEG, which is only available if
+the JPEG library has been patched to support it. Use of lossless JPEG is
+generally not recommended.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the <strong>-quality</strong> option to set the compression level to be used by
+JPEG, PNG, MIFF, and MPEG encoders. Use the <strong>-sampling-factor</strong>
+option to set the sampling factor to be used by the DPX, JPEG, MPEG, and
+YUV encoders for downsampling the chroma channels.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-contrast"></a>-contrast
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enhance or reduce the image contrast</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option enhances the intensity differences between the lighter and
+darker elements of the image. Use <strong>-contrast</strong> to enhance
+the image
+or <strong>+contrast</strong> to reduce the image contrast.
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For a more pronounced effect you can repeat the option:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert rose: -contrast -contrast rose_c2.png
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-convolve"></a>-convolve <i>&lt;kernel&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>convolve image with the specified convolution kernel</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The kernel is specified as a comma-separated list of floating point
+values, ordered left-to right, starting with the top row. The order of
+the kernel is determined by the square root of the number of entries.
+Presently only square kernels are supported.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-create-directories"></a>-create-directories
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create output directory if required</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option with <strong>-output-directory</strong> if the input paths contain
+subdirectories and it is desired to create similar subdirectories in the
+output directory. Without this option, <strong>mogrify</strong> will fail if the
+required output directory does not exist.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-crop"></a>-crop <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details
+about the geometry specification.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The width and height give the size of the image that remains after cropping,
+and <em>x</em> and <em>y</em> are offsets that give the location of the top left
+corner of the cropped
+image with respect to the original image. To specify the amount to be
+removed, use <strong>-shave</strong> instead.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the <em>x</em> and <em>y</em> offsets are present, a single image is
+generated, consisting of the pixels from the cropping region.
+The offsets specify the location of the upper left corner of
+the cropping region measured downward and rightward with respect to the
+upper left corner of the image.
+If the <strong>-gravity</strong> option is present with <em>NorthEast, East,</em>
+or <em>SouthEast</em>
+gravity, it gives the distance leftward from the right edge
+of the image to the right edge of the cropping region. Similarly, if
+the <strong>-gravity</strong> option is present with <em>SouthWest, South,</em>
+or <em>SouthEast</em>
+gravity, the distance is measured upward between the bottom
+edges.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the <em>x</em> and <em>y</em> offsets are omitted, a set of tiles of the
+specified geometry, covering the entire input image, is generated. The
+rightmost tiles and the bottom tiles are smaller if the
+specified geometry extends beyond the dimensions of the input image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-cycle"></a>-cycle <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image colormap by amount</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>Amount</em> defines the number of positions each colormap entry isshifted.
+</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <tt>events</tt> parameter specifies which events are to be logged. It
+can be either <tt>None</tt>, <tt>All</tt>, or a comma-separated list
+consisting of one or more of the following domains: <tt>Annotate</tt>,
+<tt>Blob</tt>, <tt>Cache</tt>, <tt>Coder</tt>, <tt>Configure</tt>,
+<tt>Deprecate</tt>, <tt>Error</tt>, <tt>Exception</tt>, <tt>Locale</tt>,
+<tt>Render</tt>,<tt>Resource</tt>, <tt>TemporaryFile</tt>,
+<tt>Transform</tt>, <tt>Warning</tt>, <tt>X11</tt>, or <tt>User</tt>.
+For example, to log cache and blob events, use</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -debug "Cache,Blob" rose: rose.png
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The "User" domain is normally empty, but developers can log "User" events
+in their private copy of GraphicsMagick.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the <strong>-log</strong> option to specify the format for debugging output.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+debug</strong> to turn off all logging.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+An alternative to using <strong>-debug</strong> is to use the <strong>MAGICK_DEBUG</strong>
+environment variable. The allowed values for the <strong>MAGICK_DEBUG</strong>
+environment variable are the same as for the <strong>-debug</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-deconstruct"></a>-deconstruct
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>break down an image sequence into constituent parts</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option compares each image with the next in a sequence and
+returns the maximum bounding region of any pixel differences it discovers.
+This method can undo a coalesced sequence returned by the
+<strong>-coalesce</strong> option, and is useful for removing redundant information
+from a GIF or MNG animation.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images
+is terminated by the appearance of any option.
+If the <strong>-deconstruct</strong>
+option appears after all of the input images, all images are deconstructed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-define"></a>-define <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">This option creates one or more definitions for coders and
+decoders to use while reading and writing image data. Definitions
+may be passed to coders and decoders to control options that are
+specific to certain image formats. If <em>value</em> is missing for a
+definition, an empty-valued definition of a flag will be created with
+that name. This is used to control on/off options. Use <tt>+define
+&lt;key&gt;,...</tt> to remove definitions previously created. Use
+<tt>+define "*"</tt> to remove all existing definitions.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The following definitions may be created:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>cineon:colorspace={rgb|cineonlog}</dt>
+<dd>Use the cineon:colorspace option when reading a Cineon file to
+specify the colorspace the Cineon file uses. This overrides the colorspace
+type implied by the DPX header (if any).
+</dd>
+<dt>dpx:bits-per-sample=&lt;value&gt;</dt>
+<dd>If the dpx:bits-per-sample key is defined, GraphicsMagick will write
+DPX images with the specified bits per sample, overriding any existing
+depth value. If this option is not specified, then the value is based on
+the existing image depth value from the original image file. The DPX
+standard supports bits per sample values of 1, 8, 10, 12, and 16. Many
+DPX readers demand a sample size of 10 bits with type A padding (see
+below).
+</dd>
+<dt>dpx:colorspace={rgb|cineonlog}</dt>
+<dd>Use the dpx:colorspace option when reading a DPX file to
+specify the colorspace the DPX file uses. This overrides the colorspace
+type implied by the DPX header (if any).
+</dd>
+<dt>dpx:packing-method={packed|a|b|lsbpad|msbpad}</dt>
+<dd>DPX samples are output within 32-bit words. They may be tightly
+packed end-to-end within the words ("packed"), padded with null bits to
+the right of the sample ("a" or "lsbpad), or padded with null bits to the
+left of the sample ("b" or "msbpad"). This option only has an effect for
+sample sizes of 10 or 12 bits. If samples are not packed, the DPX
+standard recommends type A padding. Many DPX readers demand a sample size
+of 10 bits with type A padding.
+</dd>
+<dt>dpx:pixel-endian={lsb|msb}</dt>
+<dd>Allows the user to specify the endian order of the pixels when
+reading or writing the DPX files. Sometimes this is useful if the file is
+(or must be) written incorrectly so that the file header and the pixels
+use different endianness.
+</dd>
+<dt>dpx:swap-samples={true|false}</dt>
+<dd>GraphicsMagick strives to adhere to the DPX standard but certain
+aspects of the standard can be quite confusing. As a result, some 10-bit
+DPX files have Red and Blue interchanged, or Cb and Cr interchanged due
+to an different interpretation of the standard, or getting the wires
+crossed. The swap-samples option may be supplied when reading or writing
+in order to read or write using the necessary sample order.
+</dd>
+<dt>jp2:rate=&lt;value&gt;</dt>
+<dd>Specify the compression factor to use while writing JPEG-2000
+files. The compression factor is the reciprocal of the compression
+ratio. The valid range is 0.0 to 1.0, with 1.0 indicating lossless
+compression. If defined, this value overrides the -quality
+setting. The default quality setting of 75 results in a rate value of
+0.06641.
+</dd>
+<dt>jpeg:block-smoothing={true|false}</dt>
+<dd>Enables or disables block smoothing when reading a JPEG file
+(default enabled).
+</dd>
+<dt>jpeg:dct-method=&lt;value&gt;</dt>
+<dd>Selects the IJG JPEG library DCT implementation to use. The
+encoding implementations vary in speed and encoding error. The
+available choices for <strong>value</strong> are <strong>islow</strong>, <strong>ifast</strong>,
+<strong>float</strong>, <strong>default</strong> and <strong>fastest</strong>. Note that
+<strong>fastest</strong> might not necessarily be fastest on your CPU, depending
+on the choices made when the JPEG library was built and how your CPU
+behaves.
+</dd>
+<dt>jpeg:fancy-upsampling={true|false}</dt>
+<dd>Enables or disables fancy upsampling when reading a JPEG file
+(default enabled).
+</dd>
+<dt>jpeg:optimize-coding={true|false}</dt>
+<dd>
+Selects if huffman encoding should be used. Huffman encoding is enabled
+by default, but may be disabled for very large images since it encoding
+requires that the entire image be buffered in memory. Huffman encoding
+produces smaller JPEG files at the expense of added compression time and
+memory consumption.
+</dd>
+<dt>jpeg:preserve-settings</dt>
+<dd>If the jpeg:preserve-settings flag is defined, the JPEG encoder will
+use the same "quality" and "sampling-factor" settings that were found
+in the input file, if the input was in JPEG format. These settings are
+also preserved if the input is a JPEG file and the output is a JNG
+file. If the colorspace of the output file differs from that of the
+input file, the quality setting is preserved but the sampling-factors
+are not.
+</dd>
+<dt>pcl:fit-to-page</dt>
+<dd>If the pcl:fit-to-page flag is defined, then the printer is
+requested to scale the image to fit the page size (width and/or
+height).</dd>
+<dt>pdf:use-cropbox={true|false}</dt>
+<dd>If the pdf:use-cropbox flag is set to <strong>true</strong>, then
+Ghostscript is requested to apply the PDF crop box.
+</dd>
+<dt>pdf:stop-on-error={true|false}</dt>
+<dd>If the pdf:stop-on-error flag is set to <strong>true</strong>, then
+Ghostscript is requested to stop processing the PDF when the first
+error is encountered. Otherwise it will attempt to process all
+requested pages.
+</dd>
+<dt>ps:imagemask</dt>
+<dd>If the ps:imagemask flag is defined, the PS3 and EPS3 coders will
+create Postscript files that render bilevel images with the Postscript
+imagemask operator instead of the image operator.
+</dd>
+<dt>tiff:alpha={unspecified|associated|unassociated}</dt>
+<dd>Specify the TIFF alpha channel type when reading or writing TIFF files,
+overriding the normal value. The default alpha channel type for new files
+is unspecified alpha. Existing alpha settings are preserved when
+converting from one TIFF file to another. When a TIFF file uses
+associated alpha, the image pixels are pre-multiplied (i.e. altered) with
+the alpha channel. Files with "associated" alpha appear as if they were
+alpha composited on a black background when the matte channel is
+disabled. If the unassociated alpha type is selected, then the alpha
+channel is saved without altering the pixels. Photoshop recognizes
+associated alpha as transparency information, if the file is saved with
+unassociated alpha, the alpha information is loaded as an independent
+channel. Note that for many years, ImageMagick and GraphicsMagick marked
+TIFF files as using associated alpha, without properly pre-multiplying
+the pixels.
+</dd>
+<dt>tiff:fill-order={msb2lsb|lsb2msb}</dt>
+<dd>If the tiff:fill-order key is defined, GraphicsMagick will use it to
+determine the bit fill order used while writing TIFF files. The normal default
+is "msb2lsb", which matches the native bit order of all modern CPUs. The
+only exception to this is when Group3 or Group4 FAX compression is
+requested since FAX machines send data in bit-reversed order and
+therefore RFC 2301 recommends using reverse order.
+</dd>
+<dt>tiff:group-three-options=&lt;value&gt;</dt>
+<dd>If the tiff:group-three-options key is defined, GraphicsMagick
+will use it to set the group3 options tag when writing
+group3-compressed TIFF. Please see the TIFF specification for the
+usage of this tag. The default value is 4.
+</dd>
+<dt>tiff:ignore-tags=&lt;tags&gt;</dt>
+<dd>If the tiff:ignore-tags key is defined, then it is used as a list
+of comma-delimited integer TIFF tag values to ignore while reading the
+TIFF file. This is useful in order to be able to read files which
+which otherwise fail to read due to problems with TIFF tags. Note
+that some TIFF tags are required in order to be able to read the image
+data at all.
+</dd>
+<dt>tiff:report-warnings={false|true}</dt>
+<dd>If the tiff:report-warnings key is defined and set to <strong>true</strong>,
+then TIFF warnings are reported as a warning exception rather than as
+a coder log message. Such warnings are reported after the image has
+been read or written. Most TIFF warnings are benign but sometimes
+they may help deduce problems with the TIFF file, or help detect that
+the TIFF file requires a special application to read successfully due
+to the use of proprietary or specialized extensions.
+</dd>
+<dt>tiff:sample-format={unsigned|ieeefp}</dt>
+<dd>If the tiff:sample-format key is defined, GraphicsMagick will use it to
+determine the sample format used while writing TIFF files. The default is
+"unsigned". Specify "ieeefp" in order to write floating-point TIFF
+files with float (32-bit) or double (64-bit) values. Use the
+tiff:bits-per-sample define to determine the type of floating-point value
+to use.
+</dd>
+<dt>tiff:max-sample-value=&lt;value&gt;</dt>
+<dd>If the tiff:max-sample-value key is defined, GraphicsMagick will use the
+assigned value as the maximum floating point value while reading or
+writing IEEE floating point TIFFs. Otherwise the maximum value is 1.0 or
+the value obtained from the file's SMaxSampleValue tag (if present). The
+floating point data is currently not scanned in advance to determine a
+best maximum sample value so if the range is not 1.0, or the
+SMaxSampleValue tag is not present, it may be necessary to
+(intelligently) use this parameter to properly read a file.
+</dd>
+<dt>tiff:min-sample-value=&lt;value&gt;</dt>
+<dd>If the tiff:min-sample-value key is defined, GraphicsMagick will use
+the assigned value as the minimum floating point value while reading or
+writing IEEE floating point TIFFs. Otherwise the minimum value is 0.0 or
+the value obtained from the file's SMinSampleValue tag (if present).
+</dd>
+<dt>tiff:bits-per-sample=&lt;value&gt;</dt>
+<dd>If the tiff:bits-per-sample key is defined, GraphicsMagick will write
+images with the specified bits per sample, overriding any existing depth
+value. Value may be any in the range of 1 to 32, or 64 when the default
+'unsigned' format is written, or 16/32/24/64 if IEEEFP format is written.
+Please note that the baseline TIFF 6.0 specification only requires
+readers to handle certain powers of two, and the values to be handled
+depend on the nature of the image (e.g. colormapped, grayscale, RGB, CMYK).
+</dd>
+<dt>tiff:samples-per-pixel=&lt;value&gt;</dt>
+<dd>If the tiff:samples-per-pixel key is defined to a value, the TIFF coder
+will write TIFF images with the defined samples per pixel, overriding any
+value stored in the image. This option should not normally be used.
+</dd>
+<dt>tiff:rows-per-strip=&lt;value&gt;</dt>
+<dd>Allows the user to specify the number of rows per TIFF strip.
+Rounded up to a multiple of 16 when using JPEG compression. Ignored when
+using tiles.
+</dd>
+<dt>tiff:strip-per-page=true</dt>
+<dd>Requests that the image is written in a single TIFF strip. This is
+normally the default when group3 or group4 compression is requested
+within reasonable limits. Requesting a single strip for large images may
+result in failure due to resource consumption in the writer or reader.
+</dd>
+<dt>tiff:tile</dt>
+<dd>Enable writing tiled TIFF (rather than stripped) using the default tile
+size. Tiled TIFF organizes the image as an array of smaller images
+(tiles) in order to enable random access.
+</dd>
+<dt>tiff:tile-geometry=&lt;width&gt;x&lt;height&gt;</dt>
+<dd>Specify the tile size to use while writing tiled TIFF. Width and
+height should be a multiple of 16. If the value is not a multiple of 16,
+then it will be rounded down. Enables tiled TIFF if it has not already
+been enabled. GraphicsMagick does not use tiled storage internally so
+tiles need to be converted back and forth from the internal
+scanline-oriented storage to tile-oriented storage. Testing with typical
+RGB images shows that useful square tile size values range from 128x128
+to 1024x1024. Large images which require using a disk-based pixel cache
+benefit from large tile sizes while images which fit in memory work well
+with smaller tile sizes.
+</dd>
+<dt>tiff:tile-width=&lt;width&gt;</dt>
+<dd>Specify the tile width to use while writing tiled TIFF. The tile height
+is then defaulted to an appropriate size. Width should be a multiple of
+16. If the value is not a multiple of 16, then it will be rounded down.
+Enables tiled TIFF if it has not already been enabled.
+</dd>
+<dt>tiff:tile-height=&lt;height&gt;</dt>
+<dd>Specify the tile height to use while writing tiled TIFF. The tile width
+is then defaulted to an appropriate size. Height should be a multiple of
+16. If the value is not a multiple of 16, then it will be rounded down.
+Enables tiled TIFF if it has not already been enabled.
+</dd>
+<dt>webp:lossless={true|false}</dt>
+<dd>Enable lossless encoding.
+</dd>
+<dt>webp:method={0-6}</dt>
+<dd>Quality/speed trade-off.
+</dd>
+<dt>webp:image-hint={default,graph,photo,picture}</dt>
+<dd>Hint for image type.
+</dd>
+<dt>webp:target-size=&lt;integer&gt;</dt>
+<dd>Target size in bytes.
+</dd>
+<dt>webp:target-psnr=&lt;float&gt;</dt>
+<dd>Minimal distortion to try to achieve.
+</dd>
+<dt>webp:segments={1-4}</dt>
+<dd>Maximum number of segments to use.
+</dd>
+<dt>webp:sns-strength={0-100}</dt>
+<dd>Spatial Noise Shaping.
+</dd>
+<dt>webp:filter-strength={0-100}</dt>
+<dd>Filter strength.
+</dd>
+<dt>webp:filter-sharpness={0-7}</dt>
+<dd>Filter sharpness.
+</dd>
+<dt>webp:filter-type={0,1}</dt>
+<dd>Filtering type. 0 = simple, 1 = strong (only used if
+filter-strength &gt; 0 or autofilter is enabled).
+</dd>
+<dt>webp:auto-filter={true|false}</dt>
+<dd>Auto adjust filter's strength.
+</dd>
+<dt>webp:alpha-compression=&lt;integer&gt;</dt>
+<dd>Algorithm for encoding the alpha plane (0 = none, 1 = compressed
+with WebP lossless). Default is 1.
+</dd>
+<dt>webp:alpha-filtering=&lt;integer&gt;</dt>
+<dd>Predictive filtering method for alpha plane. 0: none, 1: fast, 2:
+best. Default is 1.
+</dd>
+<dt>webp:alpha-quality={0-100}</dt>
+<dd>Between 0 (smallest size) and 100 (lossless). Default is 100.
+</dd>
+<dt>webp:pass=[1..10]</dt>
+<dd>Number of entropy-analysis passes.
+</dd>
+<dt>webp:show-compressed={true|false}</dt>
+<dd>Export the compressed picture back. In-loop filtering is not
+applied.
+</dd>
+<dt>webp:preprocessing=[0,1,2]</dt>
+<dd>0=none, 1=segment-smooth, 2=pseudo-random dithering
+</dd>
+<dt>webp:partitions=[0-3]</dt>
+<dd>log2(number of token partitions) in [0..3]. Default is 0 for
+easier progressive decoding.
+</dd>
+<dt>webp:partition-limit={0-100}</dt>
+<dd>Quality degradation allowed to fit the 512k limit on prediction
+modes coding (0: no degradation, 100: maximum possible
+degradation).
+</dd>
+<dt>webp:emulate-jpeg-size={true|false}</dt>
+<dd>If true, compression parameters will be remapped to better match
+the expected output size from JPEG compression. Generally, the output
+size will be similar but the degradation will be lower.
+</dd>
+<dt>webp:thread-level=&lt;integer&gt;</dt>
+<dd>If non-zero, try and use multi-threaded encoding.
+</dd>
+<dt>webp:low-memory={true|false}</dt>
+<dd>If set, reduce memory usage (but increase CPU use)
+</dd>
+</dl>
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, to create a postscript file that will render only the black
+pixels of a bilevel image, use:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert bilevel.tif -define ps:imagemask eps3:stencil.ps
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-delay"></a>-delay <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is useful for regulating the animation of image sequences
+<em>Delay/100</em> seconds must expire before the display
+of the next image. The default is no delay between each showing of the
+image sequence. The maximum delay is 65535.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can specify a delay range (e.g. <em>-delay 10-500</em>) which sets the
+minimum and maximum delay.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-density"></a>-density <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">This option specifies the image resolution to store while encoding a
+raster image or the canvas resolution while rendering (reading) vector
+formats such as Postscript, PDF, WMF, and SVG into a raster image. Image
+resolution provides the unit of measure to apply when rendering to an
+output device or raster image. The default unit of measure is in dots
+per inch (DPI). The <strong>-units</strong> option may be used to select dots per
+centimeter instead.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"> The default resolution is 72 dots per inch, which is equivalent to
+one point per pixel (Macintosh and Postscript standard). Computer
+screens are normally 72 or 96 dots per inch while printers typically
+support 150, 300, 600, or 1200 dots per inch. To determine the
+resolution of your display, use a ruler to measure the width of your
+screen in inches, and divide by the number of horizontal pixels (1024 on
+a 1024x768 display).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">If the file format supports it, this option may be used to update
+the stored image resolution. Note that Photoshop stores and obtains
+image resolution from a proprietary embedded profile. If this profile is
+not stripped from the image, then Photoshop will continue to treat the
+image using its former resolution, ignoring the image resolution
+specified in the standard file header.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">The density option is an attribute and does not alter the underlying
+raster image. It may be used to adjust the rendered size for desktop
+publishing purposes by adjusting the scale applied to the pixels. To
+resize the image so that it is the same size at a different resolution,
+use the <strong>-resample</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-depth"></a>-depth <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This is the number of bits of color to preserve in the image. Any value
+between 1 and <strong>QuantumDepth</strong> (build option) may be specified,
+although 8 or 16 are the most common values. Use this option to specify
+the depth of raw images whose depth is unknown such as GRAY, RGB, or
+CMYK, or to change the depth of any image after it has been read.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">The depth option is applied to the pixels immediately so it may be
+used as a form of simple compression by discarding the least significant
+bits. Reducing the depth in advance may speed up color quantization, and
+help create smaller file sizes when using a compression algorithm like
+LZW or ZIP.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -descend
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>obtain image by descending window hierarchy</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -despeckle
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>reduce the speckles within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-displace"></a>-displace <i>&lt;horizontal scale&gt;x&lt;vertical scale&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shift image pixels as defined by a displacement map</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+With this option, <em>composite image</em> is used as a displacement map. Black,
+within the displacement map, is a maximum positive displacement. White is a
+maximum negative displacement and middle gray is neutral. The displacement
+is scaled to determine the pixel shift. By default, the displacement applies
+in both the horizontal and vertical directions. However, if you specify
+<em>mask</em>, <em>composite image</em> is the horizontal X displacement and
+<em>mask</em> the vertical Y displacement.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-display"></a>-display <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is used with convert for
+obtaining image or font from this X server. See <em>X(1)</em>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-dispose"></a>-dispose <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The Disposal Method indicates the way in which the graphic is to
+be treated after being displayed.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Here are the valid methods:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Undefined No disposal specified.
+ None Do not dispose between frames.
+ Background Overwrite the image area with
+ the background color.
+ Previous Overwrite the image area with
+ what was there prior to rendering
+ the image.
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-dissolve"></a>-dissolve <i>&lt;percent&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>dissolve an image into another by the given percent</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The opacity of the composite image is multiplied by the given percent,
+then it is composited over the main image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-dither"></a>-dither
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The basic strategy of dithering is to trade intensity resolution for spatial
+resolution by averaging the intensities of several neighboring pixels.
+Images which suffer from severe contouring when reducing colors can be
+improved with this option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-colors</strong> or <strong>-monochrome</strong> option is required for this option
+to take effect.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+dither</strong> to turn off dithering and to render PostScript
+without text or graphic aliasing. Disabling dithering often (but not
+always) leads to decreased processing time.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-draw"></a>-draw <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with one or more graphic primitives</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to annotate an image with one or more graphic primitives.
+The primitives include shapes, text, transformations,
+and pixel operations. The shape primitives are</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ point x,y
+ line x0,y0 x1,y1
+ rectangle x0,y0 x1,y1
+ roundRectangle x0,y0 x1,y1 wc,hc
+ arc x0,y0 x1,y1 a0,a1
+ ellipse x0,y0 rx,ry a0,a1
+ circle x0,y0 x1,y1
+ polyline x0,y0 ... xn,yn
+ polygon x0,y0 ... xn,yn
+ Bezier x0,y0 ... xn,yn
+ path path specification
+ image operator x0,y0 w,h filename
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The text primitive is</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ text x0,y0 string
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The text gravity primitive is</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gravity NorthWest, North, NorthEast, West, Center,
+ East, SouthWest, South, or SouthEast
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The text gravity primitive only affects the placement of text and
+does not interact with the other primitives. It is equivalent to
+using the <strong>-gravity</strong> commandline option, except that it is
+limited in scope to the <strong>-draw</strong> option in which it appears.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The transformation primitives are</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ rotate degrees
+ translate dx,dy
+ scale sx,sy
+ skewX degrees
+ skewY degrees
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The pixel operation primitives are</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ color x0,y0 method
+ matte x0,y0 method
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The shape primitives are drawn in the color specified in the preceding
+<strong>-stroke</strong> option. Except for the <strong>line</strong> and <strong>point</strong>
+primitives, they are filled with the color specified in the preceding
+<strong>-fill</strong> option. For unfilled shapes, use <tt>-fill none</tt></font></td></tr></table>.
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Point</strong> requires a single coordinate.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Line</strong> requires a start and end coordinate.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Rectangle</strong>
+expects an upper left and lower right coordinate.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>RoundRectangle</strong> has the upper left and lower right coordinates
+and the width and height of the corners.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Circle</strong> has a center coordinate and a coordinate for
+the outer edge.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>Arc</strong> to inscribe an elliptical arc within
+a rectangle. Arcs require a start and end point as well as the degree
+of rotation (e.g. 130,30 200,100 45,90).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>Ellipse</strong> to draw a partial ellipse
+centered at the given point with the x-axis and y-axis radius
+and start and end of arc in degrees (e.g. 100,100 100,150 0,360).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Finally, <strong>polyline</strong> and <strong>polygon</strong> require
+three or more coordinates to define its boundaries.
+Coordinates are integers separated by an optional comma. For example,
+to define a circle centered at 100,100
+that extends to 150,150 use:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -draw 'circle 100,100 150,150'
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Paths</strong>
+(See <a href="http://www.w3.org/TR/SVG/paths.html">Paths</a>)
+represent an outline of an object which is defined in terms of
+moveto (set a new current point), lineto (draw a straight line),
+curveto (draw a curve using a cubic Bezier), arc (elliptical or
+circular arc) and closepath (close the current shape by drawing a line
+to the last moveto) elements. Compound paths (i.e., a path with
+subpaths, each consisting of a single moveto followed by one or more
+line or curve operations) are possible to allow effects such as
+"donut holes" in objects.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>image</strong> to composite an image with another image. Follow the
+image keyword with the composite operator, image location, image size,
+and filename:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -draw 'image Over 100,100 225,225 image.jpg'
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can use 0,0 for the image size, which means to use the actual
+dimensions found in the image header. Otherwise, it will
+be scaled to the given dimensions.
+See <strong>-compose</strong> for a description of the composite operators.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>text</strong> to annotate an image with text. Follow the text
+coordinates with a string. If the string has embedded spaces, enclose it
+in single or double quotes. Optionally you can include the image
+filename, type, width, height, or other image attribute by embedding
+special format character. See <strong>-comment</strong> for details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -draw 'text 100,100 "%m:%f %wx%h"'
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+annotates the image with <tt>MIFF:bird.miff 512x480</tt> for an image titled
+<tt>bird.miff</tt>
+and whose width is 512 and height is 480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the first character of <em>string</em> is <em>@</em>, the text is read from
+a file titled by the remaining characters in the string.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Rotate</strong> rotates subsequent shape primitives and text primitives about
+the origin of the main image. If the <strong>-region</strong> option precedes the
+<strong>-draw</strong> option, the origin for transformations is the upper left
+corner of the region.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Translate</strong> translates them.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Scale</strong> scales them.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>SkewX</strong> and <strong>SkewY</strong> skew them with respect to the origin of
+the main image or the region.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The transformations modify the current affine matrix, which is initialized
+from the initial affine matrix defined by the <strong>-affine</strong> option.
+Transformations are cumulative within the <strong>-draw</strong> option.
+The initial affine matrix is not affected; that matrix is only changed by the
+appearance of another <strong>-affine</strong> option. If another <strong>-draw</strong>
+option appears, the current affine matrix is reinitialized from
+the initial affine matrix.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>color</strong> to change the color of a pixel to the fill color (see
+<strong>-fill</strong>). Follow the pixel coordinate
+with a method:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ point
+ replace
+ floodfill
+ filltoborder
+ reset
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Consider the target pixel as that specified by your coordinate. The
+<strong>point</strong>
+method recolors the target pixel. The <strong>replace</strong> method recolors any
+pixel that matches the color of the target pixel.
+<strong>Floodfill</strong> recolors
+any pixel that matches the color of the target pixel and is a neighbor,
+whereas <strong>filltoborder</strong> recolors any neighbor pixel that is not the
+border color. Finally, <strong>reset</strong> recolors all pixels.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>matte</strong> to the change the pixel matte value to transparent. Follow
+the pixel coordinate with a method (see the <strong>color</strong> primitive for
+a description of methods). The <strong>point</strong> method changes the matte value
+of the target pixel. The <strong>replace</strong> method changes the matte value
+of any pixel that matches the color of the target pixel. <strong>Floodfill</strong>
+changes the matte value of any pixel that matches the color of the target
+pixel and is a neighbor, whereas
+<strong>filltoborder</strong> changes the matte
+value of any neighbor pixel that is not the border color (<strong>-bordercolor</strong>).
+Finally <strong>reset</strong> changes the matte value of all pixels.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can set the primitive color, font, and font bounding box
+color with
+<strong>-fill</strong>, <strong>-font</strong>, and <strong>-box</strong> respectively. Options
+are processed in command line order so be sure to use these
+options <em>before</em> the <strong>-draw</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -edge <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>detect edges within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -emboss <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>emboss an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-encoding"></a>-encoding <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from <em>AdobeCustom, AdobeExpert, AdobeStandard, AppleRoman,
+BIG5, GB2312, Latin 2, None, SJIScode, Symbol, Unicode, Wansung.</em></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-endian"></a>-endian <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>MSB</em> indicates big-endian (e.g. SPARC, Motorola 68K) while
+<em>LSB</em> indicates little-endian (e.g. Intel 'x86, VAX) byte
+ordering. <em>Native</em> indicates to use the normal ordering for the
+current CPU. This option currently only influences the CMYK, DPX,
+GRAY, RGB, and TIFF, formats.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+endian</strong> to revert to unspecified endianness.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -enhance
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a digital filter to enhance a noisy image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -equalize
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform histogram equalization to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-extent"></a>-extent <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite image on background color canvas image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option composites the image on a new background color
+(<strong>-background</strong>) canvas image of size &lt;width&gt;x&lt;height&gt;. The
+existing image content is composited at the position specified by
+geometry x and y offset and/or desired gravity (<strong>-gravity</strong>) using
+the current image compose (<strong>-compose</strong>) method. Image content
+which falls outside the bounds of the new image dimensions is
+discarded.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, this command creates a thumbnail of an image, and centers
+it on a red color backdrop image, offsetting the canvas ten pixels to
+the left and five pixels up, with respect to the thumbnail:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert infile.jpg -thumbnail 120x80 -background red -gravity center \
+ -extent 140x100-10-5 outfile.jpg
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This command reduces or expands a JPEG image to fit on an 800x600
+display: </font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -size 800x600 input.jpg \
+ -resize 800x600 -background black \
+ -compose Copy -gravity center \
+ -extent 800x600 \
+ -quality 92 output.jpg
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the aspect ratio of the input image isn't exactly 4:3, then the
+image is centered on an 800x600 black canvas. </font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-file"></a>-file <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write annotated difference image to file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If <strong>-file</strong> is specified, then an annotated difference image is
+generated and written to the specified file. Pixels which differ between
+the <strong>reference</strong> and <strong>compare</strong> images are modified from those in
+the <strong>compare</strong> image so that the changed pixels become more obvious.
+Some images may require use of an alternative highlight style (see
+<strong>-highlight-style</strong>) or highlight color (see <strong>-highlight-color</strong>)
+before the changes are obvious.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-fill"></a>-fill <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when filling a graphic primitive</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Colors are represented in GraphicsMagick in the same form used by SVG. Use "gm convert -list color" to list named colors:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ name (named color)
+ #RGB (hex numbers, 4 bits each)
+ #RRGGBB (8 bits each)
+ #RRRGGGBBB (12 bits each)
+ #RRRRGGGGBBBB (16 bits each)
+ #RGBA (4 bits each)
+ #RRGGBBAA (8 bits each)
+ #RRRGGGBBBAAA (12 bits each)
+ #RRRRGGGGBBBBAAAA (16 bits each)
+ rgb(r,g,b) (r,g,b are decimal numbers)
+ rgba(r,g,b,a) (r,g,b,a are decimal numbers)
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Enclose the color specification in quotation marks to prevent the "#"
+or the parentheses from being interpreted by your shell.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -fill blue ...
+ gm convert -fill "#ddddff" ...
+ gm convert -fill "rgb(65000,65000,65535)" ...
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The shorter forms are scaled up, if necessary by replication. For example,
+#3af, #33aaff, and #3333aaaaffff are all equivalent.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-draw</strong> for further details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-filter"></a>-filter <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to affect the resizing operation of an image (see
+<strong>-geometry</strong>).
+Choose from these filters (ordered by approximate increasing CPU
+time):</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Point
+ Box
+ Triangle
+ Hermite
+ Hanning
+ Hamming
+ Blackman
+ Gaussian
+ Quadratic
+ Cubic
+ Catrom
+ Mitchell
+ Lanczos
+ Bessel
+ Sinc
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default filter is automatically selected to provide the best quality
+while consuming a reasonable amount of time. The <strong>Mitchell</strong> filter
+is used if the image supports a palette, supports a matte channel, or is
+being enlarged, otherwise the <strong>Lanczos</strong> filter is used.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-flatten"></a>-flatten
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>flatten a sequence of images</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In some file formats (e.g. Photoshop's PSD) complex images may be
+represented by "layers" (independent images) which must be composited
+in order to obtain the final rendition. The <strong>-flatten</strong> option
+accomplishes this composition. The sequence of images is replaced by
+a single image created by compositing each image in turn, while
+respecting composition operators and page offsets. While
+<strong>-flatten</strong> is immediately useful for eliminating layers, it is
+also useful as a general-purpose composition tool.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images is terminated by the appearance of any option.
+If the <strong>-flatten</strong> option appears after all of the input images,
+all images are flattened. Also see <strong>-mosaic</strong> which is similar to
+<strong>-flatten</strong> except that it adds a suitably-sized canvas base
+image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, this composites an image on top of a 640x400 transparent
+black canvas image:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -size 640x300 xc:transparent \
+ -compose over -page +0-100 \
+ frame.png -flatten output.png
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+and this flattens a Photoshop PSD file:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert input.psd -flatten output.png
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-flip"></a>-flip
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+reflect the scanlines in the vertical direction.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-flop"></a>-flop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+reflect the scanlines in the horizontal direction.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-font"></a>-font <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can tag a font to specify whether it is a PostScript, TrueType, or X11
+font. For example, <tt>Arial.ttf</tt> is a TrueType font, <tt>ps:helvetica</tt>
+is PostScript, and <tt>x:fixed</tt> is X11.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-foreground"></a>-foreground <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the foreground color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-format"></a>-format <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image format type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used with the <strong>mogrify</strong> utility,
+this option will convert any image to the image format you specify.
+See <em>GraphicsMagick(1)</em> for a list of image format types supported by
+<strong>GraphicsMagick</strong>, or see the output of 'gm -list format'.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default the file is written to its original name. However, if the
+filename extension matches a supported format, the extension is replaced
+with the image format type specified with <strong>-format</strong>. For example,
+if you specify <em>tiff</em> as the format type and the input image
+filename is <em>image.gif</em>, the output image filename becomes
+<em>image.tiff</em>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-format"></a>-format <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output formatted image characteristics</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used with the <strong>identify</strong> utility, or the <strong>convert</strong>
+utility with output written to the 'info:-' file specification, use
+this option to print information about the image in a format of your
+choosing. You can include the image filename, type, width, height,
+Exif data, or other image attributes by embedding special format
+characters:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ %b file size
+ %c comment
+ %d directory
+ %e filename extension
+ %f filename
+ %g page dimensions and offsets
+ %h height
+ %i input filename
+ %k number of unique colors
+ %l label
+ %m magick
+ %n number of scenes
+ %o output filename
+ %p page number
+ %q image bit depth
+ %r image type description
+ %s scene number
+ %t top of filename
+ %u unique temporary filename
+ %w width
+ %x horizontal resolution
+ %y vertical resolution
+ %A transparency supported
+ %C compression type
+ %D GIF disposal method
+ %G Original width and height
+ %H page height
+ %M original filename specification
+ %O page offset (x,y)
+ %P page dimensions (width,height)
+ %Q compression quality
+ %T time delay (in centi-seconds)
+ %U resolution units
+ %W page width
+ %X page horizontal offset (x)
+ %Y page vertical offset (y)
+ %@ trim bounding box
+ %# signature
+ \n newline
+ \r carriage return
+ %% %
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -format "%m:%f %wx%h"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+displays <strong>MIFF:bird.miff 512x480</strong> for an image
+titled <strong>bird.miff</strong> and whose width is 512 and height is 480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the first character of <em>string</em> is <strong>@</strong>, the format
+is read from a file titled by the remaining characters in the string.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The values of image type (<strong>%p</strong>) which may be returned include:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Bilevel
+ Grayscale
+ GrayscaleMatte
+ Palette
+ PaletteMatte
+ TrueColor
+ TrueColorMatte
+ ColorSeparation
+ ColorSeparationMatte
+ Optimize
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can also use the following special formatting syntax to print Exif
+information contained in the file:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ %[EXIF:&lt;tag&gt;]
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Where "&lt;tag&gt;" may be one of the following:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ * (print all Exif tags, in keyword=data format)
+ ! (print all Exif tags, in tag_number format)
+ #hhhh (print data for Exif tag #hhhh)
+ ImageWidth
+ ImageLength
+ BitsPerSample
+ Compression
+ PhotometricInterpretation
+ FillOrder
+ DocumentName
+ ImageDescription
+ Make
+ Model
+ StripOffsets
+ Orientation
+ SamplesPerPixel
+ RowsPerStrip
+ StripByteCounts
+ XResolution
+ YResolution
+ PlanarConfiguration
+ ResolutionUnit
+ TransferFunction
+ Software
+ DateTime
+ Artist
+ WhitePoint
+ PrimaryChromaticities
+ TransferRange
+ JPEGProc
+ JPEGInterchangeFormat
+ JPEGInterchangeFormatLength
+ YCbCrCoefficients
+ YCbCrSubSampling
+ YCbCrPositioning
+ ReferenceBlackWhite
+ CFARepeatPatternDim
+ CFAPattern
+ BatteryLevel
+ Copyright
+ ExposureTime
+ FNumber
+ IPTC/NAA
+ ExifOffset
+ InterColorProfile
+ ExposureProgram
+ SpectralSensitivity
+ GPSInfo
+ ISOSpeedRatings
+ OECF
+ ExifVersion
+ DateTimeOriginal
+ DateTimeDigitized
+ ComponentsConfiguration
+ CompressedBitsPerPixel
+ ShutterSpeedValue
+ ApertureValue
+ BrightnessValue
+ ExposureBiasValue
+ MaxApertureValue
+ SubjectDistance
+ MeteringMode
+ LightSource
+ Flash
+ FocalLength
+ MakerNote
+ UserComment
+ SubSecTime
+ SubSecTimeOriginal
+ SubSecTimeDigitized
+ FlashPixVersion
+ ColorSpace
+ ExifImageWidth
+ ExifImageLength
+ InteroperabilityOffset
+ FlashEnergy
+ SpatialFrequencyResponse
+ FocalPlaneXResolution
+ FocalPlaneYResolution
+ FocalPlaneResolutionUnit
+ SubjectLocation
+ ExposureIndex
+ SensingMethod
+ FileSource
+ SceneType
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+JPEG specific information (from reading a JPEG file) may be obtained
+like this:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ %[JPEG-&lt;tag&gt;]
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Where "&lt;tag&gt;" may be one of the following:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ * (all JPEG-related tags, in
+ keyword=data format)
+ Quality IJG JPEG "quality" estimate
+ Colorspace JPEG colorspace numeric ID
+ Colorspace-Name JPEG colorspace name
+ Sampling-factors JPEG sampling factors
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Please note that JPEG has no notion of "quality" and that the quality
+metric used by, and estimated by the software is based on the quality
+metric established by IJG JPEG 6b. Other encoders (e.g. that used by
+Adobe Photoshop) use different encoding metrics.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Surround the format specification with quotation marks to prevent your shell
+from misinterpreting any spaces and square brackets.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-frame"></a>-frame <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details about the geometry
+specification. The <strong>-frame</strong> option is not affected by the
+<strong>-gravity</strong> option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color of the border is specified with the <strong>-mattecolor</strong>
+command line option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -frame
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>include the X window frame in the imported image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-fuzz"></a>-fuzz <i>&lt;distance&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colors within this Euclidean distance are considered equal</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A number of algorithms search for a target color. By default the color
+must be exact. Use this option to match colors that are close (in
+Euclidean distance) to the target color in RGB 3D space. For example,
+if you want to automatically trim the edges of an image with
+<strong>-trim</strong> but the image was scanned and the target background color
+may differ by a small amount. This option can account for these
+differences.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <em>distance</em> can be in absolute intensity units or, by appending
+<em>"%"</em>, as a percentage of the maximum possible intensity (255,
+65535, or 4294967295).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-gamma"></a>-gamma <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The same color image displayed on two different workstations may look
+different due to differences in the display monitor. Use gamma
+correction to adjust for this color difference. Reasonable values extend
+from <strong>0.8</strong> to <strong>2.3</strong>. Gamma less than 1.0 darkens the image and
+gamma greater than 1.0 lightens it. Large adjustments to image gamma may
+result in the loss of some image information if the pixel quantum size
+is only eight bits (quantum range 0 to 255).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can apply separate gamma values to the red, green, and blue channels
+of the image with a gamma value list delimited with slashes
+(e.g., <strong>1.7</strong>/<strong>2.3</strong>/<strong>1.2</strong>).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+gamma</strong> <em>value</em>
+to set the image gamma level without actually adjusting
+the image pixels. This option is useful if the image is of a known gamma
+but not set as an image attribute (e.g. PNG images).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-gaussian"></a>-gaussian <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the given radius and standard deviation (sigma).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-geometry"></a>-geometry <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-geometry</strong> option is used for a number of different
+purposes, depending on the utility it is used with.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the X11 commands ('animate', 'display', and 'import'), it
+specifies the preferred size and location of the Image window. By
+default, the window size is the image size and the location is chosen
+by you (or your window manager) when it is mapped.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"> For the 'import', 'convert', 'mogrify' utility commands it may be
+used to specify the desired size when resizing an image. In this
+case, symbols representing resize options may be appended to the
+geometry string to influence how the resize request is treated.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See later notes corresponding to usage by particular commands. The
+following notes apply to when <strong>-geometry</strong> is used to express a
+resize request, taking into account the current properties of the
+image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, the width and height are maximum values. That is, the
+image is expanded or contracted to fit the width and height value
+while maintaining the aspect ratio of the image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Append a ^ to the geometry so that the image aspect ratio is
+maintained when the image is resized, but the resulting width or
+height are treated as minimum values rather than maximum values.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Append a ! (exclamation point) to the geometry to force the image size to
+exactly the size you specify. For example, if you specify
+<tt>640x480!</tt> the image width is set to 640 pixels and height to
+480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If only the width is specified, without the trailing 'x', then height
+is set to width (e.g., <tt>-geometry 100</tt> is the same as
+<tt>-geometry 100x100</tt>). If only the width is specified but with
+the trailing 'x', then width assumes the value and the height is
+chosen to maintain the aspect ratio of the image. Similarly, if only
+the height is specified prefixed by 'x' (e.g., <tt>-geometry
+x256</tt>), the width is chosen to maintain the aspect ratio.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+To specify a percentage width or height instead, append %. The image size
+is multiplied by the width and height percentages to obtain the final image
+dimensions. To increase the size of an image, use a value greater than
+100 (e.g. 125%). To decrease an image's size, use a percentage less than
+100.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <tt>@</tt> to specify the maximum area in pixels of an image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <tt>&gt;</tt> to change the dimensions of the image <em>only</em> if
+its width or height exceeds the geometry specification. <tt>&lt;</tt> resizes
+the image <em>only</em> if both of its dimensions are less than the geometry
+specification. For example,
+if you specify <tt>'640x480&gt;'</tt> and the image size is 256x256, the image
+size does not change. However, if the image is 512x512 or 1024x1024, it is
+resized to 480x480. Enclose the geometry specification in quotation marks to
+prevent the <tt>&lt;</tt> or <tt>&gt;</tt> from being interpreted by your shell
+as a file redirection.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used with <em>animate</em> and <em>display</em>, offsets are handled in
+the same manner as in <em>X(1)</em> and the <strong>-gravity</strong> option is not used.
+If the <em>x</em> is negative, the offset is measured leftward
+from the right edge of the
+screen to the right edge of the image being displayed.
+Similarly, negative <em>y</em> is measured between the bottom edges. The
+offsets are not affected by "%"; they are always measured in pixels.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>composite</em> option, <strong>-geometry</strong>
+gives the dimensions of the image and its location with respect
+to the composite image. If the <strong>-gravity</strong> option is present
+with <em>NorthEast, East,</em> or <em>SouthEast</em> gravity, the <em>x</em>
+represents the distance from the right edge of the image to the right edge of
+the composite image. Similarly, if the <strong>-gravity</strong> option is present
+with <em>SouthWest, South,</em> or <em>SouthEast</em> gravity, <em>y</em>
+is measured between the bottom edges. Accordingly, a positive offset will
+never point in the direction outside of the image. The
+offsets are not affected by "%"; they are always measured in pixels.
+To specify the dimensions of the composite image, use the <strong>-resize</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>convert</em>, <em>import</em> or <em>mogrify</em> option,
+<strong>-geometry</strong> is synonymous with <strong>-resize</strong> and
+specifies the size of the output image. The offsets, if present, are ignored.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>montage</em> option, <strong>-geometry</strong> specifies the image
+size and border size for each tile; default is 256x256+0+0. Negative
+offsets (border dimensions) are meaningless. The <strong>-gravity</strong>
+option affects the placement of the image within the tile; the default
+gravity for this purpose is <em>Center</em>. If the "%" sign appears in
+the geometry specification, the tile size is the specified percentage of
+the original dimensions of the first tile.
+To specify the dimensions of the montage, use the <strong>-resize</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-gravity"></a>-gravity <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are: NorthWest, North,
+NorthEast, West, Center, East, SouthWest, South, SouthEast.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The direction you choose specifies where to position the text
+when annotating
+the image. For example <em>Center</em> gravity forces the text to be centered
+within the image. By default, the image gravity is <em>NorthWest</em>.
+See <strong>-draw</strong> for more details about graphic primitives. Only the
+text primitive is affected by the <strong>-gravity</strong> option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-gravity</strong> option is also used in concert with the <strong>-geometry</strong>
+option and other options that take <strong>&lt;geometry&gt;</strong> as a parameter, such
+as the <strong>-crop</strong> option. See <strong>-geometry</strong> for details of how the
+<strong>-gravity</strong> option interacts with the
+<strong>&lt;x&gt;</strong> and <strong>&lt;y&gt;</strong> parameters of a geometry
+specification.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as an option to <em>composite</em>, <strong>-gravity</strong>
+gives the direction that the image gravitates within the composite.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as an option to <em>montage</em>, <strong>-gravity</strong> gives the direction
+that an image gravitates within a tile. The default gravity is <em>Center</em>
+for this purpose.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-green-primary"></a>-green-primary <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -hald-clut <i>&lt;clut&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a Hald CLUT to the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A Hald CLUT ("Color Look-Up Table") is a special square color image
+which contains a look-up table for red, green, and blue. The size of
+the Hald CLUT image is determined by its order. The width (and
+height) of a Hald CLUT is the cube of the order. For example, a Hald
+CLUT of order 8 is 512x512 pixels (262,144 colors) and of order 16 is
+4096x4096 (16,777,216 colors). A special CLUT is the identity CLUT
+which which causes no change to the input image. In order to use the
+Hald CLUT, one takes an identity CLUT and adjusts its colors in some
+way. The modified CLUT can then be used to transform any number of
+images in an identical way.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+GraphicsMagick contains a built-in identity CLUT generator via the
+<strong>IDENTITY</strong> coder. For example reading from the file name
+</strong>IDENTITY:8</strong> returns an identity CLUT of order 8. Typical Hald
+CLUT identity images have an order of between 8 and 16. The default
+order for the <strong>IDENTITY</strong> CLUT generator is 8. Interpolation is
+used so it is not usually necessary for CLUT images to be very large.
+The PNG file format is ideal for storing Hald CLUT images because it
+compresses them very well.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-highlight-color"></a>-highlight-color <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixel annotation color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specifies the color to use when annotating difference pixels.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-highlight-style"></a>-highlight-style <i>&lt;style&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixel annotation style</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specifies the pixel difference annotation style used to draw attention to
+changed pixels. May be one of <strong>Assign</strong>, <strong>Threshold</strong>,
+<strong>Tint</strong>, or <strong>XOR</strong>; where <strong>Assign</strong> replaces the pixel with
+the highlight color (see <strong>-highlight-color</strong>), <strong>Threshold</strong>
+replaces the pixel with black or white based on the difference in
+intensity, <strong>Tint</strong> alpha tints the pixel with the highlight color,
+and <strong>XOR</strong> does an XOR between the pixel and the highlight color.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-iconGeometry"></a>-iconGeometry <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the icon geometry</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Offsets, if present in the geometry specification, are handled in
+the same manner as the <strong>-geometry</strong> option, using X11 style to handle
+negative offsets.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -iconic
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>iconic animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -immutable
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image immutable</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -implode <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>implode image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-intent"></a>-intent <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of rendering intent when managing the image color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to affect the the color management operation of an image (see
+<strong>-profile</strong>).
+Choose from these intents:
+<strong>Absolute, Perceptual, Relative, Saturation</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default intent is undefined.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-interlace"></a>-interlace <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are: <strong>None, Line, Plane,</strong>
+or <strong>Partition</strong>. The default is <strong>None</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is used to specify the type of interlacing scheme for raw image
+formats such as <strong>RGB</strong> or <strong>YUV</strong>.</font></td></tr></table><table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>None</strong> means do not interlace
+(RGBRGBRGBRGBRGBRGB...),</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Line</strong> uses scanline interlacing
+(RRR...GGG...BBB...RRR...GGG...BBB...),
+and</font></td></tr></table><table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Plane</strong> uses plane interlacing (RRRRRR...GGGGGG...BBBBBB...).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Partition</strong>
+is like plane except the different planes are saved to individual files
+(e.g. image.R, image.G, and image.B).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>Line</strong> to create an <strong>interlaced PNG</strong> or <strong> GIF</strong> or
+<strong>progressive JPEG</strong> image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-label"></a>-label <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to assign a specific label to the image, when writing
+to an image format that supports labels, such as TIFF, PNG, MIFF, or
+PostScript. You can include the the image filename, type, width, height,
+or other image attribute by embedding special format character. A label
+is not drawn on the image, but is embedded in the image datastream via
+a "Label" tag or similar mechanism. If you want the
+label to be visible on the image itself, use the <strong>-draw</strong> option.
+See <strong>-comment</strong> for details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -label "%m:%f %wx%h"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+produces an image label of <strong>MIFF:bird.miff 512x480</strong> for an image titled
+<strong>bird.miff</strong>
+and whose width is 512 and height is 480.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the first character of <em>string</em> is <em>@</em>, the image label is
+read from a file titled by the remaining characters in the string.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the -label option appears multiple times, only the last label is
+stored.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In PNG images, the label is stored in a <strong>tEXt</strong> or <strong>zTXt</strong> chunk
+with the keyword "label".</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When converting to <em>PostScript</em>, use this option to specify a header
+string to print above the image. Specify the label font with
+<strong>-font</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When creating a montage, by default the label associated with an image
+is displayed with the corresponding tile in the montage. Use the
+<strong>+label</strong> option to suppress this behavior.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-lat"></a>-lat <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;offset&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform local adaptive thresholding</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Perform local adaptive thresholding using the specified width, height,
+and offset. The offset is a distance in sample space from the mean,
+as an absolute integer ranging from 0 to the maximum sample value or
+as a percentage. If the percent option is supplied, then the offset
+is computed as a percentage of the quantum range. It is strongly
+recommended to use the percent option so that results are not
+sensitive to pixel quantum depth.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -colorspace gray -lat "10x10-5%"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+will help clarify a scanned grayscale or color document, producing a
+bi-level equivalent.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-level"></a>-level <i>&lt;black_point&gt;</i>{<i>,&lt;gamma&gt;</i>}<i></i>{<i>,&lt;white_point&gt;</i>}<i></i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>adjust the level of image contrast</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Give one, two or three values delimited with commas: black-point, gamma,
+white-point (e.g. 10,1.0,250 or 2%,0.5,98%). The black and white
+points range from 0 to MaxRGB or from 0 to 100%; if the white point is
+omitted it is set to MaxRGB-black_point. If a "%" sign is present
+anywhere in the string, the black and white points are percentages of
+MaxRGB. Gamma is an exponent that ranges from 0.1 to 10.; if it is
+omitted, the default of 1.0 (no gamma correction) is assumed. This
+interface works similar to Photoshop's "Image-&gt;Adjustments-&gt;Levels..."
+"Input Levels" interface.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-limit"></a>-limit <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, resource limits are estimated based on the available
+resources of the system. The resource limits are <strong>Disk</strong>, maximum
+total disk space consumed; <strong>File</strong>, maximum number of file
+descriptors allowed to be open at once; <strong>Map</strong>, maximum total
+number of file bytes which may be memory mapped; <strong>Memory</strong>,
+maximum total number of bytes of heap memory used for image storage;
+<strong>Pixels</strong>, maximum absolute image size (per image); <strong>Width</strong>,
+maximum image pixels width; <strong>Height</strong>, maximum image pixels
+height; and <strong>Threads</strong>, the maximum number of worker threads to
+use per OpenMP thread team.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+These resource limits are used to decide if (for a given image) the
+decoded image ("pixel cache") should be stored in heap memory (RAM),
+in a memory-mapped disk file, or in a disk file accessed via
+read/write I/O. The number of total pixels in one image, and/or the
+width/height, may also be limited in order to force the reading, or
+creation of images larger than the limit (in pixels) to intentionally
+fail. The disk limit establishes an overall limit since using the disk
+is the means of last resort. When the disk limit has been reached, no
+more images may be read.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The value argument is an absolute value, but may have standard binary
+suffix characters applied ('K', 'M', 'G', 'T', 'P', 'E') to apply a
+scaling to the value (based on a multiplier of 1024). Any additional
+characters are ignored. For example, <tt>'-limit Pixels 10MP'</tt> limits
+the maximum image size to 10 megapixels and <tt>'-limit memory 32MB
+-limit map 64MB'</tt> limits memory and memory mapped files to 32
+megabytes and 64 megabytes respectively.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Resource limits may also be set using environment variables. The
+environment variables <strong>MAGICK_LIMIT_DISK</strong>,
+<strong>MAGICK_LIMIT_FILES</strong>, <strong>MAGICK_LIMIT_MAP</strong>,
+<strong>MAGICK_LIMIT_MEMORY</strong>, <strong>MAGICK_LIMIT_PIXELS</strong>,
+<strong>MAGICK_LIMIT_WIDTH</strong>, <strong>MAGICK_LIMIT_HEIGHT</strong>,and
+<strong>OMP_NUM_THREADS</strong> may be used to set the limits for disk space,
+open files, memory mapped size, heap memory, per-image pixels, image
+width, image height, and threads respectively.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the option <tt>-list resource</tt> list the current limits.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -linewidth
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the line width for subsequent draw operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-list"></a>-list <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of list</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choices are: <strong>Color</strong>, <strong>Delegate</strong>, <strong>Format</strong>, <strong>Magic</strong>,
+<strong>Module</strong>, <strong>Resource</strong>, or <strong>Type</strong>. The <strong>Module</strong> option
+is only available if GraphicsMagick was built to support loadable modules.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option lists information about the GraphicsMagick configuration.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-log"></a>-log <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option specifies the format for the log printed when the <strong>-debug</strong>
+option is active.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can display the following components by embedding
+special format characters:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ %d domain
+ %e event
+ %f function
+ %l line
+ %m module
+ %p process ID
+ %r real CPU time
+ %t wall clock time
+ %u user CPU time
+ %% percent sign
+ \n newline
+ \r carriage return
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -debug coders -log "%u %m:%l %e" in.gif out.png
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default behavior is to print all of the components.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-loop"></a>-loop <i>&lt;iterations&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add Netscape loop extension to your GIF animation</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A value other than zero forces the animation to repeat itself up to
+<em>iterations</em>
+times.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The image size is doubled using linear interpolation.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The displayed image is magnified by <strong>factor</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-map"></a>-map <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>choose a particular set of colors from this image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+[<em>convert</em> or <em>mogrify</em>]</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, color reduction chooses an optimal set of colors that best
+represent the original image. Alternatively, you can choose a particular
+set of colors from an image file with this option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use
+<strong>+map</strong> to reduce
+all images in the image sequence that follows to a single optimal set of colors
+that best represent all the images. The sequence of images
+is terminated by the appearance of any option.
+If the <strong>+map</strong>
+option appears after all of the input images, all images are mapped.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-map"></a>-map <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display image using this type.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+[<em>animate</em> or <em>display</em>]</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from these <em>Standard Colormap</em> types:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ best
+ default
+ gray
+ red
+ green
+ blue
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <em>X server</em> must support the <em>Standard Colormap</em> you choose,
+otherwise an error occurs. Use <strong>list</strong> as the type and <strong>display</strong>
+searches the list of colormap types in <strong>top-to-bottom</strong> order until
+one is located. See <em>xstdcmap(1)</em> for one way of creating Standard
+Colormaps.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-mask"></a>-mask <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify a clipping mask</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The image read from the file is used as a clipping mask. It must have
+the same dimensions as the image being masked.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the mask image contains an opacity channel, the opacity of each
+pixel is used to define the mask. Otherwise, the intensity (gray
+level) of each pixel is used. Unmasked (black) pixels are modified
+while masked pixels (not black) are protected from alteration.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+mask</strong> to remove the clipping mask.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+It is not necessary to use <strong>-clip</strong> to activate the mask; <strong>-clip</strong>
+is implied by <strong>-mask</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-matte"></a>-matte
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the image does not have a matte channel, create an opaque one.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+matte</strong> to ignore the matte channel and to avoid writing a
+matte channel in the output file.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-mattecolor"></a>-mattecolor <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-maximum-error"></a>-maximum-error <i>&lt;limit&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the maximum amount of total image error</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specifies the maximum amount of total image error (based on comparison
+using a specified metric) before an error ("image difference exceeds
+limit") is reported. The error is reported via a non-zero command
+execution return status.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -median <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a median filter to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -metric <i>&lt;metric&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>comparison metric (MAE, MSE, PAE, PSNR, RMSE)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -minify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>minify the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The image size is halved using linear interpolation.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -mode <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>mode of operation</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The available montage modes are <strong>frame</strong> to place the images in a
+rectangular grid while adding a decorative frame with dropshadow,
+<strong>unframe</strong> to place undecorated images in a rectangular grid, and
+<strong>concatenate</strong> to pack the images closely together without any
+well-defined grid or decoration. </font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-modulate"></a>-modulate <i>brightness[,saturation[,hue]]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>vary the brightness, saturation, and hue of an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify the percent change in brightness, color saturation, and
+hue separated by commas. Default argument values are 100 percent,
+resulting in no change. For example, to increase the color brightness
+by 20% and decrease the color saturation by 10% and leave the hue
+unchanged, use: <strong>-modulate 120,90</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Hue is the percentage of absolute rotation from the current
+position. For example 50 results in a counter-clockwise rotation of 90
+degrees, 150 results in a clockwise rotation of 90 degrees, with 0 and
+200 both resulting in a rotation of 180 degrees.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A simple command-line progress indication is shown while the command is
+running. The process indication shows the operation currently being
+performed and the percent completed. Commands using X11 may replace the
+command line progress indication with a graphical one once an image has
+been displayed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-morph"></a>-morph <i>&lt;frames&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>morphs an image sequence</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Both the image pixels and size are linearly interpolated to give the appearance
+of a meta-morphosis from one image to the next.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images
+is terminated by the appearance of any option.
+If the <strong>-morph</strong>
+option appears after all of the input images, all images are morphed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-mosaic"></a>-mosaic
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a mosaic from an image or an image sequence</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-mosaic</strong> option provides a flexible way to composite one or
+more images onto a solid-color canvas image. It works similar to
+<strong>-flatten</strong> except that a base canvas image is automatically
+created with a suitable size given the image size, page dimensions,
+and page offsets of images to be composited. The color of the base
+canvas image may be set via the <strong>-background</strong> option. The
+default canvas color is 'white', but 'black' or 'transparent' may be
+more suitable depending on the composition algorithm requested.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-compose</strong> option may be used to specify the composition
+algorithm to use when compositing the subsequent image on the base
+canvas.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-page</strong> option can be used to establish the dimensions of the
+mosaic and to position the subsequent image within the mosaic. If the
+<strong>-page</strong> argument does not specify width and height, then the
+canvas dimensions are evaluated based on the image sizes and
+offsets.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images is terminated by the appearance of any option.
+If the <strong>-mosaic</strong> option appears after all of the input images,
+all images are included in the mosaic.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The following is an example of composing an image based on red, green,
+and blue layers extracted from a sequence of images and pasted on the
+canvas image at specified offsets:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -background black \
+ -compose CopyRed -page +0-100 red.png \
+ -compose CopyGreen -page +0+40 green.png \
+ -compose CopyBlue -page +0+180 blue.png \
+ -mosaic output.png
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-motion-blur"></a>-motion-blur <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+angle</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Simulate motion blur</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Simulate motion blur by convolving the image with a Gaussian operator of
+the given radius and standard deviation (sigma). For reasonable results,
+radius should be larger than sigma. If radius is zero, then a suitable
+radius is automatically selected based on sigma. The angle specifies the
+angle that the object is coming from (side which is blurred).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -name
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-negate"></a>-negate
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The red, green, and blue intensities of an image are negated.
+White becomes black,
+yellow becomes blue, etc.
+Use <strong>+negate</strong>
+to only negate the grayscale pixels of the image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-noise"></a>-noise <i>&lt;radius|type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add or reduce noise in an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The principal function of noise peak elimination filter is to smooth the
+objects within an image without losing edge information and without creating
+undesired structures. The central idea of the algorithm is to replace a
+pixel with its next neighbor in value within a pixel window, if this pixel
+has been found to be noise. A pixel is defined as noise if and only if
+this pixel is a maximum or minimum within the pixel window.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>radius</strong> to specify the width of the neighborhood.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+noise</strong> followed by a noise type to add noise to an image.
+The noise added modulates the existing image pixels. Choose from these
+noise types:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Uniform
+ Gaussian
+ Multiplicative
+ Impulse
+ Laplacian
+ Poisson
+ Random (uniform distribution)
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-noop"></a>-noop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-noop</strong> option can be used to terminate a group of images
+and reset all options to their default values, when no other option is
+desired.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-normalize"></a>-normalize
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform image to span the full range of color values</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This is a contrast enhancement technique based on the image histogram.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When computing the contrast enhancement values, the histogram edges
+are truncated so that the majority of the image pixels are considered
+in the constrast enhancement, and outliers (e.g. random noise or
+minute details) are ignored. The default is that 0.1 percent of the
+histogram entries are ignored. The percentage of the histogram to
+ignore may be specified by using the <strong>-set</strong> option with the
+<strong>histogram-threshold</strong> parameter similar to <strong>-set
+histogram-threshold 0.01</strong> to specify 0.01 percent. Use 0 percent
+to use the entire histogram, with possibly diminished contrast
+enhancement.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-opaque"></a>-opaque <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>change this color to the pen color within the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the
+<strong>-fill</strong> option. The color is replaced if it is identical to the
+target color, or close enough to the target color in a 3D space as
+defined by the Euclidean distance specified by <strong>-fuzz</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-fill</strong> and <strong>-fuzz</strong> for more details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-operator"></a>-operator <i>channel operator rvalue[%]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a mathematical, bitwise, or value operator to an image channel</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Apply a low-level mathematical, bitwise, or value operator to a selected
+image channel or all image channels. Operations which result in negative
+results are reset to zero, and operations which overflow the available
+range are reset to the maximum possible value.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Select a channel from: <strong>Red</strong>, <strong>Green</strong>, <strong>Blue</strong>,
+<strong>Opacity</strong>, <strong>Matte</strong>, <strong>Cyan</strong>, <strong>Magenta</strong>, <strong>Yellow</strong>,
+<strong>Black</strong>, <strong>All</strong>, or <strong>Gray</strong>. <strong>All</strong> only modifies the
+color channels and does not modify the <strong>Opacity</strong> channel. Except for
+the threshold operators, <strong>All</strong> operates on each channel
+independently so that operations are on a per-channel basis.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<strong>Gray</strong> treats the color channels as a grayscale intensity and
+performs the requested operation on the equivalent pixel intensity so the
+result is a gray image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Select an operator from <strong>Add</strong>, <strong>And</strong>, <strong>Assign</strong>,
+<strong>Depth</strong>, <strong>Divide</strong>, <strong>Gamma</strong>, <strong>Negate</strong>,
+<strong>LShift</strong>, <strong>Log</strong>, <strong>Max</strong>, <strong>Min</strong>, <strong>Multiply</strong>,
+<strong>Or</strong>, <strong>Pow</strong> <strong>RShift</strong>, <strong>Subtract</strong>,
+<strong>Threshold</strong>, <strong>Threshold-White</strong>,
+<strong>Threshold-White-Negate</strong>, <strong>Threshold-Black</strong>,
+<strong>Threshold-Black-Negate</strong>, <strong>Xor</strong>, <strong>Noise-Gaussian</strong>,
+<strong>Noise-Impulse</strong>, <strong>Noise-Laplacian</strong>,
+<strong>Noise-Multiplicative</strong>, <strong>Noise-Poisson</strong>,
+<strong>Noise-Random</strong>, and <strong>Noise-Uniform</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Rvalue may be any floating point or integer value. Normally rvalue will
+be in the range of 0 to MaxRGB, where MaxRGB is the largest quantum value
+supported by the GraphicsMagick build (255, 65535, or 4294967295) but
+values outside this range are useful for some arithmetic operations.
+Arguments to logical or bit-wise operations are rounded to a positive
+integral value prior to use. If a percent (<strong>%</strong>) symbol is appended
+to the argument, then the argument has a range of 0 to 100 percent.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The following is a description of the operators:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>Add</dt>
+<dd>Result is rvalue added to channel value.
+</dd>
+<dt>And</dt>
+<dd>Result is the logical AND of rvalue with channel value.
+</dd>
+<dt>Assign</dt>
+<dd>Result is rvalue.
+</dd>
+<dt>Depth</dt>
+<dd>Result is channel value adjusted so that it may be (approximately)
+stored in the specified number of bits without additional loss.
+</dd>
+<dt>Divide</dt>
+<dd>Result is channel value divided by rvalue.
+</dd>
+<dt>Gamma</dt>
+<dd>Result is channel value gamma adjusted by rvalue.
+</dd>
+<dt>LShift</dt>
+<dd>Result is channel value bitwise left shifted by rvalue bits.
+</dd>
+<dt>Log</dt>
+<dd>Result is computed as log(value*rvalue+1)/log(rvalue+1).
+</dd>
+<dt>Max</dt>
+<dd>Result is assigned to rvalue if rvalue is greater than value.
+</dd>
+<dt>Min</dt>
+<dd>Result is assigned to rvalue if rvalue is less than value.
+</dd>
+<dt>Multiply</dt>
+<dd>Result is channel value multiplied by rvalue.
+</dd>
+<dt>Negate</dt>
+<dd>Result is inverse of channel value (like a film negative). An rvalue
+must be supplied but is currently not used. Inverting the image twice
+results in the original image.
+</dd>
+<dt>Or</dt>
+<dd>Result is the logical OR of rvalue with channel value.
+</dd>
+<dt>Pow</dt>
+<dd>Result is computed as pow(value,rvalue). Similar to Gamma except that
+rvalue is not inverted.
+</dd>
+<dt>RShift</dt>
+<dd>Result is channel value bitwise right shifted by rvalue bits.
+</dd>
+<dt>Subtract</dt>
+<dd>Result is channel value minus rvalue.
+</dd>
+<dt>Threshold</dt>
+<dd>Result is maximum (white) if channel value is greater than rvalue,
+or minimum (black) if it is less than or equal to rvalue. If <strong>all</strong>
+channels are specified, then thresholding is done based on computed pixel
+intensity.
+</dd>
+<dt>Threshold-white</dt>
+<dd>Result is maximum (white) if channel value is greater than rvalue and
+is unchanged if it is less than or equal to rvalue. This can be used to
+remove apparent noise from the bright parts of an image. If <strong>all</strong>
+channels are specified, then thresholding is done based on computed pixel
+intensity.
+</dd>
+<dt>Threshold-White-Negate</dt>
+<dd>Result is set to black if channel value is greater than
+rvalue and is unchanged if it is less than or equal to rvalue. If
+<strong>all</strong> channels are specified, then thresholding is done based on
+computed pixel intensity.
+</dd>
+<dt>Threshold-black</dt>
+<dd>Result is minimum (black) if channel value is less than than rvalue
+and is unchanged if it is greater than or equal to rvalue. This can be
+used to remove apparent noise from the dark parts of an image. If
+<strong>all</strong> channels are specified, then thresholding is done based on
+computed pixel intensity.
+</dd>
+<dt>Threshold-Black-Negate</dt>
+<dd>Result is set to white if channel value is less than than
+rvalue and is unchanged if it is greater than or equal to rvalue. If
+<strong>all</strong> channels are specified, then thresholding is done based on
+computed pixel intensity.
+</dd>
+<dt>Xor</dt>
+<dd>Result is the logical XOR of rvalue with channel value. An
+interesting property of XOR is that performing the same operation twice
+results in the original value.
+</dd>
+<dt>Noise-Gaussian</dt>
+<dd>Result is the current channel value modulated with gaussian noise
+according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Impulse</dt>
+<dd>Result is the current channel value modulated with impulse noise
+according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Laplacian</dt>
+<dd>Result is the current channel value modulated with laplacian noise
+according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Multiplicative</dt>
+<dd>Result is the current channel value modulated with multiplicative
+gaussian noise according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Poisson</dt>
+<dd>Result is the current channel value modulated with poisson noise
+according to the intensity specified by rvalue.
+</dd>
+<dt>Noise-Random</dt>
+<dd>Result is the current channel value modulated with random (uniform
+distribution) noise according to the intensity specified by rvalue.
+The initial noise intensity (rvalue=1.0) is the range of one pixel
+quantum span.
+</dd>
+<dt>Noise-Uniform</dt>
+<dd>Result is the channel value with uniform noise applied according to
+the intensity specified by rvalue.
+</dd>
+</dl>
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+As an example, the <strong>Assign</strong> operator assigns a fixed value to a
+channel. For example, this command sets the red channel to the mid-range
+value:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert in.bmp -operator red assign "50%" out.bmp
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The following applies 50% thresholding to the image and returns a gray
+image:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert in.bmp -operator gray threshold "50%" out.bmp
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-ordered-dither"></a>-ordered-dither <i>&lt;channeltype&gt; &lt;NxN&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>ordered dither the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The channel or channels specified in the <strong>channeltype</strong> argument are
+reduced to binary, using an ordered dither method. The choices for
+<strong>channeltype</strong> are <strong>All</strong>, <strong>Intensity</strong>, <strong>Red</strong>,
+<strong>Green</strong>, <strong>Blue</strong>, <strong>Cyan</strong>, <strong>Magenta</strong>, <strong>Yellow</strong>,
+<strong>Black</strong>, and <strong>Opacity</strong></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When <strong>channeltype</strong> is "All", the color samples are dithered into
+a gray level and then that gray level is stored in the three color
+channels. Separately, the opacity channel is dithered into a bilevel
+opacity value which is stored in the opacity channel.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When <strong>channeltype</strong> is "Intensity", only the color samples are
+dithered. When <strong>channeltype</strong> is "opacity" or "matte", only the
+opacity channel is dithered. When a color channel is specified, only that
+channel is dithered.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The choices for N are 2 through 7. The image is divided into
+NxN pixel tiles. In each tile, some or all pixels are turned to
+white depending on their intensity. For each N, (N**2)+1 levels
+of gray can be represented. For N == 2, 3, or 4, the pixels
+are turned to white in an order that maximizes dispersion (i.e.,
+reduces granularity), while
+for N == 5, 6, and 7, they are turned to white in an order that
+creates a roughly circular black blob in the middle of each tile.
+An attractive "half-tone" looking image can be obtained by first
+rotating the image 45 degrees, performing a 5x5 ordered-dither
+operation, then rotating it back to the original orientation and
+cropping to the original image dimensions. If the original image
+is gamma-encoded, it is adviseable to convert it to linear intensity
+first, e.g., with the "-gamma 0.45455" option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-output-directory"></a>-output-directory <i>&lt;directory&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output files to directory</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use -output-directory to specify a directory under which to write the
+output files. Normally mogrify overwrites the input files but with this
+option the output files may be written to a different directory so that
+the input files are preserved. The algorithm used preserves all of the
+input path specification in the output path so that the user-specified
+input path (including any directory part) is appended to the output path.
+The user is responsible for creating the output directory.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-orient"></a>-orient <i>&lt;orientation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Set the image orientation attribute</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Sets the image orientation attribute. The image orientation attribute
+is compatible with the TIFF orientation tag (and the EXIF orientation
+tag). Accepted values are <strong>undefined</strong>, <strong>TopLeft</strong>,
+<strong>TopRight</strong>, <strong>BottomRight</strong>, <strong>BottomLeft</strong>,
+<strong>LeftTop</strong>, <strong>RightTop</strong>, <strong>RightBottom</strong>,
+<strong>LeftBottom</strong>, and hyphenated versions thereof
+(e.g. <strong>left-bottom</strong>). Please note that GraphicsMagick does not
+include an EXIF editor so if an EXIF profile is written to the output
+image, the value in the EXIF profile might not match the image. It is
+possible for an image file to indicate its orientation in several
+different ways simultaneously.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-page"></a>-page <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to specify the dimensions of the
+<em>PostScript</em> page
+in dots per inch or a TEXT page in pixels. The choices for a PostScript
+page are:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 11x17 792 1224
+ Ledger 1224 792
+ Legal 612 1008
+ Letter 612 792
+ LetterSmall 612 792
+ ArchE 2592 3456
+ ArchD 1728 2592
+ ArchC 1296 1728
+ ArchB 864 1296
+ ArchA 648 864
+ A0 2380 3368
+ A1 1684 2380
+ A2 1190 1684
+ A3 842 1190
+ A4 595 842
+ A4Small 595 842
+ A5 421 595
+ A6 297 421
+ A7 210 297
+ A8 148 210
+ A9 105 148
+ A10 74 105
+ B0 2836 4008
+ B1 2004 2836
+ B2 1418 2004
+ B3 1002 1418
+ B4 709 1002
+ B5 501 709
+ C0 2600 3677
+ C1 1837 2600
+ C2 1298 1837
+ C3 918 1298
+ C4 649 918
+ C5 459 649
+ C6 323 459
+ Flsa 612 936
+ Flse 612 936
+ HalfLetter 396 612
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For convenience you can specify the page size by media (e.g. A4, Ledger,
+etc.). Otherwise, <strong>-page</strong> behaves much like
+<strong>-geometry</strong> (e.g. <tt>-page letter+43+43&gt;</tt>).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is also used to place subimages when writing to a multi-image
+format that supports offsets, such as GIF89 and MNG. When used for this
+purpose the offsets are always measured from the
+top left corner of the canvas and are not affected by the <strong>-gravity</strong>
+option.
+To position a GIF or MNG image, use <strong>-page</strong><em>{+-}&lt;x&gt;{+-}&lt;y&gt;</em>
+(e.g. -page +100+200). When writing to a MNG file, a <strong>-page</strong>
+option appearing ahead of the first image in the sequence with nonzero
+width and height defines the width and height values that are written in
+the <strong>MHDR</strong> chunk. Otherwise, the MNG width and height are computed
+from the bounding box that contains all images in the sequence. When
+writing a GIF89 file, only the bounding box method is used to determine its
+dimensions.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For a PostScript page, the image is sized as in <strong>-geometry</strong> and positioned
+relative to the lower left hand corner of the page by
+{+-}&lt;<strong>x</strong><em>offset</em>&gt;{+-}&lt;<strong>y</strong>
+<em>offset&gt;</em>. Use
+<tt>-page 612x792&gt;</tt>, for example, to center the
+image within the page. If the image size exceeds the PostScript page, it
+is reduced to fit the page.
+The default gravity for the <strong>-page</strong>
+option is <em>NorthWest</em>, i.e., positive <strong>x</strong> and
+<strong>y</strong> <em>offset</em> are measured rightward and downward from the top
+left corner of the page, unless the <strong>-gravity</strong> option is present with
+a value other than <em>NorthWest</em>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default page dimensions for a TEXT image is 612x792.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option is used in concert with <strong>-density</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+page</strong> to remove the page settings for an image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-paint"></a>-paint <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate an oil painting</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Each pixel is replaced by the most frequent color in a circular neighborhood
+whose width is specified with <em>radius</em>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-pause"></a>-pause <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pause between animation loops [animate]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Pause for the specified number of seconds before repeating the
+animation.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-pause"></a>-pause <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pause between snapshots [import]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Pause for the specified number of seconds before taking the next
+snapshot.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-pen"></a>-pen <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>(This option has been replaced by the -fill option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -ping
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>efficiently determine image characteristics</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to disable reading the image pixels so that image
+characteristics such as the image dimensions may be obtained very
+quickly. For identify, use +ping to force reading the image pixels so
+that the pixel read rate may be included in the displayed information.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-preview"></a>-preview <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>image preview type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to affect the preview operation of an image (e.g.
+<tt>convert file.png -preview Gamma Preview:gamma.png</tt>). Choose
+from these previews:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ Rotate
+ Shear
+ Roll
+ Hue
+ Saturation
+ Brightness
+ Gamma
+ Spiff
+ Dull
+ Grayscale
+ Quantize
+ Despeckle
+ ReduceNoise
+ AddNoise
+ Sharpen
+ Blur
+ Threshold
+ EdgeDetect
+ Spread
+ Shade
+ Raise
+ Segment
+ Solarize
+ Swirl
+ Implode
+ Wave
+ OilPaint
+ CharcoalDrawing
+ JPEG
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default preview is <strong>JPEG</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-process"></a>-process <i>&lt;command&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>process a sequence of images using a process module</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The command argument has the form <strong>module=arg1,arg2,arg3,...,argN</strong>
+where <strong>module</strong> is the name of the module to invoke (e.g. "analyze")
+and arg1,arg2,arg3,...,argN are an arbitrary number of arguments to
+pass to the process module.</font></td></tr></table><table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The sequence of images
+is terminated by the appearance of any option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If the <strong>-process</strong>
+option appears after all of the input images, all images are processed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-profile"></a>-profile <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add ICM, IPTC, or generic profile to image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<tt>-profile filename</tt> adds an ICM (ICC color management), IPTC
+(newswire information), or a generic (including Exif) profile to the image
+</font></td></tr></table>.
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <tt>+profile icm</tt>, <tt>+profile iptc</tt>, or
+<tt>+profile profile_name</tt> to remove the respective profile.
+Multiple profiles may be listed, separated by commas. Profiles may be
+excluded from subsequent listed matches by preceding their name with
+an exclamation point. For example, <tt>+profile '!icm,*'</tt> strips
+all profiles except for the ICM profile. Use <tt>identify
+-verbose</tt> to find out what profiles are in the image file. Use
+<tt>+profile "*"</tt> to remove all profiles.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Writing the image to a format that does not support profiles will
+of course also cause all profiles to be removed. The JPEG and PNG
+formats will store any profiles that have been read and not removed.
+In JPEG they are stored in APP1 markers, and in PNG they are stored
+as hex-coded binary in compressed zTXt chunks, except for the iCC
+chunk which is stored in the iCCP chunk.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+To extract a profile, the <strong>-profile</strong> option is not used. Instead,
+simply write the file to an image
+format such as <em>APP1, 8BIM, ICM,</em> or <em>IPTC</em>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example, to extract the Exif data (which is stored in JPEG files
+in the <em>APP1</em> profile), use
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert cockatoo.jpg exifdata.app1
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Note that GraphicsMagick does not attempt to update any profile to
+reflect changes made to the image, e.g., rotation from portrait to landscape
+orientation, so it is possible that the preserved profile may contain
+invalid data.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-preserve-timestamp"></a>-preserve-timestamp
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preserve the original timestamps of the file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to preserve the original modification and access
+timestamps of the file, even if it has been modified.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details+progress"></a>+progress
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>disable progress monitor and busy cursor</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, when an image is displayed, a progress monitor bar is shown
+in the top left corner of an existing image display window, and the
+current cursor is replaced with an hourglass cursor. Use <strong>+progress</strong>
+to disable the progress monitor and busy cursor during display operations.
+While the progress monitor is disabled for all operations, the busy
+cursor continues to be enabled for non-display operations such as image
+processing. This option is useful for non-interactive display operations,
+or when a "clean" look is desired.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-quality"></a>-quality <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"> For the JPEG and MPEG image formats, quality is 0 (lowest image
+quality and highest compression) to 100 (best quality but least
+effective compression). The default quality is 75. Use the
+<strong>-sampling-factor</strong> option to specify the factors for chroma
+downsampling. To use the same quality value as that found by the JPEG
+decoder, use the <tt>-define jpeg:preserve-settings</tt> flag.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the MIFF image format, and the TIFF format while using ZIP
+compression, quality/10 is the zlib compression level, which is 0 (worst
+but fastest compression) to 9 (best but slowest). It has no effect on the
+image appearance, since the compression is always lossless.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the JPEG-2000 image format, quality is mapped using a non-linear
+equation to the compression ratio required by the Jasper library. This
+non-linear equation is intended to loosely approximate the quality
+provided by the JPEG v1 format. The default quality value 75 results in
+a request for 16:1 compression. The quality value 100 results in
+a request for non-lossy compression.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the MNG and PNG image formats, the quality value sets the zlib compression
+level (quality / 10) and filter-type (quality % 10). Compression levels
+range from 0 (fastest compression) to 100 (best but slowest). For compression
+level 0, the Huffman-only strategy is used, which is fastest but not
+necessarily the worst compression.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If
+filter-type is 4 or less, the specified filter-type is used for all scanlines:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 0: none
+ 1: sub
+ 2: up
+ 3: average
+ 4: Paeth
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If filter-type is 5, adaptive filtering is used when quality is greater
+than 50 and the image does not have a color map, otherwise no filtering
+is used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If filter-type is 6, adaptive filtering
+with <em>minimum-sum-of-absolute-values</em>
+is used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Only if the output is MNG, if filter-type is 7, the LOCO color transformation
+and adaptive filtering with <em>minimum-sum-of-absolute-values</em>
+are used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The default is quality is 75, which means nearly the best compression with
+adaptive filtering. The quality setting has no effect on the appearance
+of PNG and MNG images, since the compression is always lossless.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For further information, see the <a href="http://www.w3.org/TR/">PNG</a>
+specification.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When writing a JNG image with transparency, two quality values are required,
+one for the main image and one for the grayscale image that conveys the
+opacity channel. These are written as a single integer equal to the main
+image quality plus 1000 times the opacity quality. For example, if you
+want to use quality 75 for the main image and quality 90 to compress
+the opacity data, use <tt>-quality 90075</tt>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For the PNM family of formats (PNM, PGM, and PPM) specify a quality
+factor of zero in order to obtain the ASCII variant of the format. Note
+that -compress <em>none</em> used to be used to trigger ASCII output but
+provided the opposite result of what was expected as compared with other
+formats.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-raise"></a>-raise <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>lighten or darken image edges</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This will create a 3-D effect. See <strong>-geometry</strong> for details
+details about the geometry specification. Offsets are not used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>-raise</strong> to create a raised effect, otherwise use <strong>+raise</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-random-threshold"></a>-random-threshold <i>&lt;channeltype&gt; &lt;LOWxHIGH&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>random threshold the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The channel or channels specified in the &lt;channeltype&gt; argument are
+reduced to binary, using an random-threshold method. The choices for
+<strong>channeltype</strong> are <strong>All</strong>, <strong>Intensity</strong>, <strong>Red</strong>,
+<strong>Green</strong>, <strong>Blue</strong>, <strong>Cyan</strong>, <strong>Magenta</strong>, <strong>Yellow</strong>,
+<strong>Black</strong>, and <strong>Opacity</strong></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When <strong>channeltype</strong> is "All", the color samples are thresholded into
+a graylevel and then that gray level is stored in the three color
+channels. Separately, the opacity channel is thresholded into a bilevel
+opacity value which is stored in the opacity channel. For each pixel, a
+new random number is used to establish the threshold to be used. The
+threshold never exceeds the specified maximum (HIGH) and is never less
+than the specified minimum (LOW).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When <strong>channeltype</strong> is "intensity", only the color samples are
+thresholded. When <strong>channeltype</strong> is "opacity" or "matte", only the
+opacity channel is thresholded. The other named channels only threshold
+the associated channel.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-recolor"></a>-recolor <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a color translation matrix to image channels</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A user supplied color translation matrix (expressed as a text string)
+is used to translate/blend the image channels based on weightings in a
+supplied matrix which may be of order 3 (color channels only), 4
+(color channels plus opacity), or 5 (color channels plus opacity and
+offset). Values in the columns of the matrix (red, green, blue,
+opacity) are used as multipliers with the existing channel values and
+added together according to the rows of the matrix. Matrix values are
+floating point and may be negative. The offset column (column 5) is
+purely additive and is scaled such that 0.0 to 1.0 represents the
+maximum quantum range (but values are not limited to this range). The
+math for the color translation matrix is similar to that used by Adobe
+Flash except that the offset is scaled to 1.0 (divide Flash offset by
+255 for use with GraphicsMagick) so that the results are independent
+of quantum depth.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+An <strong>identity</strong> matrix exists for each matrix order which
+results in no change to the image. The translation matrix should be
+based on an alteration of the identity matrix.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Identity matrix of order 3</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 1 0 0
+ 0 1 0
+ 0 0 1
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+which may be formatted into a convenient matrix argument similar to
+(comma is treated as white space):</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -recolor "1 0 0, 0 1 0, 0 0 1"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Identity matrix of order 4</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 1 0 0 0
+ 0 1 0 0
+ 0 0 1 0
+ 0 0 0 1
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Identity matrix of order 5. The last row is required to exist
+for the purpose of parsing, but is otherwise not used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 1 0 0 0 0
+ 0 1 0 0 0
+ 0 0 1 0 0
+ 0 0 0 1 0
+ 0 0 0 0 1
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+As an example, an image wrongly in BGR channel order may be converted
+to RGB using this matrix (blue-&gt;red, red-&gt;blue):</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 0 0 1
+ 0 1 0
+ 1 0 0
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+and an RGB image using standard Rec.709 primaries may be converted
+to grayscale using this matrix of standard weighting factors:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 0.2126 0.7152 0.0722
+ 0.2126 0.7152 0.0722
+ 0.2126 0.7152 0.0722
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+and contrast may be reduced by scaling down by 80% and adding a 10%
+offset:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 0.8 0.0 0.0 0.0 0.1
+ 0.0 0.8 0.0 0.0 0.1
+ 0.0 0.0 0.8 0.0 0.1
+ 0.0 0.0 0.0 0.8 0.1
+ 0.0 0.0 0.0 0.0 1.0
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-red-primary"></a>-red-primary <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-region"></a>-region <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply options to a portion of the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <em>x</em> and <em>y</em> offsets are treated in the same manner as in <strong>-crop</strong></font></td></tr></table>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-remote"></a>-remote
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform a X11 remote operation</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-remote</strong> command sends a command to a "gm display" or "gm
+animate" which is already running. The only command recognized at this
+time is the name of an image file to load. This capability is very
+useful to load new images without needing to restart GraphicsMagick
+(e.g. for a slide-show or to use GraphicsMagick as the display engine
+for a different GUI). Also see the <strong>+progress</strong> option for a way
+to disable progress indication for a clean look while loading new images.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-render"></a>-render
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>+render</strong> to turn off rendering vector operations. This is
+useful when saving the result to vector formats such as MVG or SVG.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-repage"></a>-repage <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Adjust the current image page canvas and position based on a relative
+page specification. This option may be used to change the location of
+a subframe (e.g. part of an animation) prior to composition. If the
+geometry specification is absolute (includes a '!'), then the offset
+adjustment is absolute and there is no adjustment to page width and
+height, otherwise the page width and height values are also adjusted
+based on the current image dimensions. Use <strong>+repage</strong> to set the
+image page offsets to default.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-resample"></a>-resample <i>&lt;horizontal&gt;x&lt;vertical&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Resample image to specified horizontal and vertical resolution</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Resize the image so that its rendered size remains the same as the
+original at the specified target resolution. Either the current image
+resolution units or the previously set with <strong>-units</strong> are used to
+interpret the argument. For example, if a 300 DPI image renders at 3
+inches by 2 inches on a 300 DPI device, when the image has been
+resampled to 72 DPI, it will render at 3 inches by 2 inches on a 72
+DPI device. Note that only a small number of image formats
+(e.g. JPEG, PNG, and TIFF) are capable of storing the image
+resolution. For formats which do not support an image resolution, the
+original resolution of the image must be specified via <strong>-density</strong>
+on the command line prior to specifying the resample resolution.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Note that Photoshop stores and obtains image resolution from a
+proprietary embedded profile. If this profile exists in the image,
+then Photoshop will continue to treat the image using its former
+resolution, ignoring the image resolution specified in the standard
+file header.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Some image formats (e.g. PNG) require use of metric or english units
+so even if the original image used a particular unit system, if it is
+saved to a different format prior to resampling, then it may be
+necessary to specify the desired resolution units using <strong>-units</strong>
+since the original units may have been lost. In other words, do not
+assume that the resolution units are restored if the image has been
+saved to a file.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-resize"></a>-resize <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This is an alias for the <strong>-geometry</strong> option and it behaves in the
+same manner. If the <strong>-filter</strong> option precedes the <strong>-resize</strong>
+option, the specified filter is used.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+There are some exceptions:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>composite</em> option, <strong>-resize</strong> conveys the
+preferred size of the output image, while <strong>-geometry</strong> conveys the
+size and placement of the <em>composite image</em> within the main
+image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+When used as a <em>montage</em> option, <strong>-resize</strong> conveys the preferred
+size of the montage, while <strong>-geometry</strong> conveys
+information about the tiles.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-roll"></a>-roll <i></i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>roll an image vertically or horizontally</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details the geometry specification. The
+<em>x</em> and <em>y</em> offsets are not affected by the <strong>-gravity</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+A negative <em>x</em> offset rolls the image left-to-right. A negative
+<em>y</em> offset rolls the image top-to-bottom.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-rotate"></a>-rotate <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Positive angles rotate the image in a clockwise direction while
+negative angles rotate counter-clockwise.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <tt>&gt;</tt> to rotate the image only if its width exceeds the
+height. <tt>&lt;</tt> rotates the image <em>only</em> if its width is less
+than the height. For example, if you specify <tt>-rotate "-90&gt;"</tt>
+and the image size is 480x640, the image is not rotated. However, if
+the image is 640x480, it is rotated by -90 degrees. If you use
+<tt>&gt;</tt> or <tt>&lt;</tt>, enclose it in quotation marks to prevent it
+from being misinterpreted as a file redirection.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Empty triangles left over from rotating the image are filled with the
+color defined as <strong>background</strong> (class <strong>backgroundColor</strong>).
+The color is specified using the format described under the
+<strong>-fill</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-sample"></a>-sample <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale image using pixel sampling</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details about
+the geometry specification.
+<strong>-sample</strong> ignores the <strong>-filter</strong> selection if the <strong>-filter</strong> option
+is present. Offsets, if present in the geometry string, are ignored, and
+the <strong>-gravity</strong> option has no effect.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-sampling-factor"></a>-sampling-factor <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option specifies the sampling factors to be used by the DPX, JPEG,
+MPEG, or YUV encoders for chroma downsampling. The sampling factor must
+be specified while reading the raw YUV format since it is not preserved
+in the file header.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Industry-standard video subsampling notation such as "4:2:2" may also
+be used to specify the sampling factors. "4:2:2" is equivalent to a
+specification of "2x1"</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The JPEG decoder obtains the original sampling factors (and quality
+settings) when a JPEG file is read. To re-use the original sampling
+factors (and quality setting) when JPEG is output, use the <tt>-define
+jpeg:preserve-settings</tt> flag.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-scale"></a>-scale <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale the image.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-geometry</strong> for details about
+the geometry specification. <strong>-scale</strong> uses a simpler, faster algorithm,
+and it ignores the <strong>-filter</strong> selection if the <strong>-filter</strong> option
+is present. Offsets, if present in the geometry string, are ignored, and
+the <strong>-gravity</strong> option has no effect.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-scene"></a>-scene <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option sets the scene number of an image or the first image in
+an image sequence.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-scenes"></a>-scenes <i>&lt;value-value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>range of image scene numbers to read</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Each image in the range is read
+with the filename followed by a period (<strong>.</strong>) and the decimal scene
+number. You
+can change this behavior by embedding a <strong>%d, %0Nd, %o, %0No, %x, or %0Nx
+printf</strong> format specification in the file name. For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm montage -scenes 5-7 image.miff montage.miff
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+makes a montage of files image.miff.5, image.miff.6, and image.miff.7, and</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm animate -scenes 0-12 image%02d.miff
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+animates files image00.miff, image01.miff, through image12.miff.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-screen"></a>-screen
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the screen to capture</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option indicates that the GetImage request used to obtain the image
+should be done on the root window, rather than directly on the specified
+window. In this way, you can obtain pieces of other windows that overlap
+the specified window, and more importantly, you can capture menus or other
+popups that are independent windows but appear over the specified window.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-set"></a>-set <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Set a named image attribute. The attribute is set on the current
+(previously specified on command line) image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details+set"></a>+set <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Unset a named image attribute. The attribute is removed from the current
+(previously specified on command line) image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-segment"></a>-segment <i>&lt;cluster threshold&gt;x&lt;smoothing threshold&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>segment an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Segment an image by analyzing the histograms of the color components and
+identifying units that are homogeneous with the fuzzy c-means technique.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Segmentation is a very useful fast and and approximate color quantization
+algorithm for scanned printed pages or scanned cartoons. It may also be
+used as a special effect. Specify <em>cluster threshold</em> as the minimum
+percentage of total pixels in a cluster before it is considered valid.
+For huge images containing small detail, this may need to be a tiny
+fraction of a percent (e.g. 0.015) so that important detail is not lost.
+<em>Smoothing threshold</em> eliminates noise in the second derivative of
+the histogram. As the value is increased, you can expect a smoother
+second derivative. The default is 1.5. Add the <em>-verbose</em> option to
+see a dump of cluster statistics given the parameters used. The
+statistics may be used as a guide to help fine tune the options.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-shade"></a>-shade <i>&lt;azimuth&gt;x&lt;elevation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shade the image using a distant light source</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <em>azimuth</em> and <em>elevation</em> as the position of the light
+source. Use <strong>+shade</strong> to return the shading results as a grayscale
+image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -shadow <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shadow the montage</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-shared-memory"></a>-shared-memory
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use shared memory</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option specifies whether the utility should attempt to use shared
+memory for pixmaps. GraphicsMagick must be compiled with shared
+memory support, and the display must support the <em>MIT-SHM</em>
+extension. Otherwise, this option is ignored. The default is
+<strong>True</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-sharpen"></a>-sharpen <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use a Gaussian operator of the given radius and standard deviation
+(sigma).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-shave"></a>-shave <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shave pixels from the image edges</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify the width of the region to be removed from both
+sides of the image and the height of the regions to be removed from
+top and bottom.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-shear"></a>-shear <i>&lt;x degrees&gt;x&lt;y degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shear the image along the X or Y axis</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use the specified positive or negative shear angle.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Shearing slides one edge of an image along the X or Y axis, creating a
+parallelogram. An X direction shear slides an edge along the X axis,
+while a Y direction shear slides an edge along the Y axis. The amount
+of the shear is controlled by a shear angle. For X direction shears,
+<em>x degrees</em> is measured relative to the Y axis, and similarly,
+for Y direction shears <em>y degrees</em> is measured relative to the X
+axis.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Empty triangles left over from shearing the image are filled with the
+color defined as <strong>background</strong> (class <strong>backgroundColor</strong>).
+The color is specified using the format described under the
+<strong>-fill</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -silent
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>operate silently</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-size"></a>-size <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to specify the width and height of raw images whose
+dimensions are unknown such as <strong>GRAY</strong>, <strong>RGB</strong>, or
+<strong>CMYK</strong>. In addition to width and height, use <strong>-size</strong> with an
+offset to skip any header information in the image or tell the number
+of colors in a <strong>MAP</strong> image file, (e.g. -size 640x512+256).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For Photo CD images, choose from these sizes:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ 192x128
+ 384x256
+ 768x512
+ 1536x1024
+ 3072x2048
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Finally, use this option to choose a particular resolution layer of a JBIG
+or JPEG image (e.g. -size 1024x768).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-snaps"></a>-snaps <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>number of screen snapshots</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option
+to grab more than one image from the X server screen, to create
+an animation sequence.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-solarize"></a>-solarize <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>negate all pixels above the threshold level</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <em>factor</em> as the
+percent threshold of the intensity (0 - 99.9%).</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option produces a <em>solarization</em> effect seen when exposing a
+photographic film to light during the development process.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-spread"></a>-spread <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image pixels by a random amount</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>Amount</em> defines the size of the neighborhood around each pixel to
+choose a candidate pixel to swap.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-stegano"></a>-stegano <i>&lt;offset&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>hide watermark within an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use an offset to start the image hiding some number of pixels from the
+beginning of the image. Note this offset and the image size. You will
+need this information to recover the steganographic image
+(e.g. display -size 320x256+35 stegano:image.png).</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-stereo"></a>-stereo
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite two images to create a stereo anaglyph</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The left side of the stereo pair is saved as the red channel of the output
+image. The right side is saved as the green channel. Red-green stereo
+glasses are required to properly view the stereo image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-strip"></a>-strip
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+All embedded profiles and text attributes are stripped from the image.
+This is useful for images used for the web, or when output files need
+to be as small as possible</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Be careful not to use this option to remove author, copyright, and
+license information that you are required to retain when redistributing
+an image.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-stroke"></a>-stroke <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when stroking a graphic primitive</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-draw</strong> for further details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-strokewidth"></a>-strokewidth <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the stroke width</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+See <strong>-draw</strong> for further details.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-swirl"></a>-swirl <i>&lt;degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>swirl image pixels about the center</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>Degrees</em> defines the tightness of the swirl.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-text-font"></a>-text-font <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>font for writing fixed-width text</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point <em>Courier</em>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+You can tag a font to specify whether it is a PostScript, TrueType, or
+X11 font. For example, <tt>Courier.ttf</tt> is a TrueType font
+and <tt>x:fixed</tt> is X11.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-threshold"></a>-threshold <i>&lt;value&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>threshold the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Modify the image such that any pixel sample with an intensity value
+greater than the threshold is assigned the maximum intensity (white), or
+otherwise is assigned the minimum intensity (black). If a percent prefix
+is applied, then the threshold is a percentage of the available range.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+To efficiently create a black and white image from a color image, use</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -threshold 50% in.png out.png
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The optimum threshold value depends on the nature of the image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">In order to threshold individual channels, use the <strong>-operator</strong>
+subcommand with it's <strong>Threshold</strong>, <strong>Threshold-White</strong>, or
+<strong>Threshold-Black</strong> options.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-thumbnail"></a>-thumbnail <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-thumbnail</strong> command resizes the image as quickly as
+possible, with more concern for speed than resulting image quality.
+Regardless, resulting image quality should be acceptable for many
+uses. It is primarily intended to be used to generate smaller
+versions of the image, but may also be used to enlarge the image. The
+<strong>-thumbnail</strong> <strong>geometry</strong> argument observes the same syntax
+and rules as it does for <strong>-resize</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tile image when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>layout of images [<em>montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-title"></a>-title <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign title to displayed image [<em>animate, display, montage</em>]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use this option to assign a specific title to the image. This is
+assigned to the image window and is typically displayed in the window
+title bar. Optionally you can include the image filename, type,
+width, height, Exif data, or other image attribute by embedding
+special format characters described under the <strong>-format</strong>
+option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+For example,</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ -title "%m:%f %wx%h"
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+produces an image title of <tt>MIFF:bird.miff 512x480</tt> for an image
+titled <tt>bird.miff</tt> and whose width is 512 and height is 480.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-transform"></a>-transform
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option applies the transformation matrix from a previous
+<strong>-affine</strong> option.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -affine 2,2,-2,2,0,0 -transform bird.ppm bird.jpg
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-transparent"></a>-transparent <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The color is specified using the format described under the <strong>-fill</strong>
+option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-treedepth"></a>-treedepth <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Normally, this integer value is zero or one. A value of zero or one
+causes the use of an optimal tree depth for the color reduction
+algorithm</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+An optimal depth generally allows the best representation of the source
+image with the fastest computational speed and the least amount of memory.
+However, the default depth is inappropriate for some images. To assure
+the best representation, try values between 2 and 8 for this parameter.
+Refer to
+<a href="quantize.html">quantize</a> for more details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-colors</strong> or <strong>-monochrome</strong> option, or writing to an image
+format which requires color reduction, is required for this option to
+take effect.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-trim"></a>-trim
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option removes any edges that are exactly the same color as the
+corner pixels. Use <strong>-fuzz</strong> to make <strong>-trim</strong> remove edges that
+are nearly the same color as the corner pixels.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-type"></a>-type <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from:
+<strong>Bilevel</strong>, <strong>Grayscale</strong>, <strong>Palette</strong>,
+<strong>PaletteMatte</strong>, <strong>TrueColor</strong>, <strong>TrueColorMatte</strong>,
+<strong>ColorSeparation</strong>, <strong>ColorSeparationMatte</strong>, or <strong>Optimize</strong>.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Normally, when a format supports different subformats such as bilevel,
+grayscale, palette, truecolor, and truecolor+alpha, the encoder will try
+to choose a suitable subformat based on the nature of the image. The
+<strong>-type</strong> option may be used to tailor the output subformat. By
+default the output subformat is based on readily available image
+information and is usually similar to the input format.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <tt>-type Optimize</tt> in order to enable inspecting all pixels
+(if necessary) in order to find the most efficient subformat. Inspecting
+all of the pixels may be slow for very large images, particularly if they
+are stored in a disk cache. If an RGB image contains only gray pixels,
+then every pixel in the image must be inspected in order to decide that
+the image is actually grayscale!</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Sometimes a specific subformat is desired. For example, to force a JPEG
+image to be written in TrueColor RGB format even though only gray pixels
+are present, use</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert bird.pgm -type TrueColor bird.jpg
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Similarly, using <tt>-type TrueColorMatte</tt> will force the encoder to
+write an alpha channel even though the image is opaque, if the output
+format supports transparency.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Some pseudo-formats (e.g. the XC format) will respect the requested
+type if it occurs previously on the command line. For example, to obtain
+a DirectClass solid color canvas image rather than PsuedoClass, use</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert -size 640x480 -type TrueColor xc:red red.miff
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Likewise, specify <strong>-type</strong> <strong>Bilevel</strong>, <strong>Grayscale</strong>,
+<strong>TrueColor</strong>, or <strong>TrueColorMatte</strong> prior to reading a Postscript
+(or PDF file) in order to influence the type of image that Ghostcript
+returns. Reading performance will be dramatically improved for
+black/white Postscript if <strong>Bilevel</strong> is specified, and will be
+considerably faster if <strong>Grayscale</strong> is specified.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-update"></a>-update <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+detect when image file is modified and redisplay.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Suppose that while you are displaying an image the file that is currently
+displayed is over-written.
+<strong>display</strong> will automatically detect that
+the input file has been changed and update the displayed image accordingly.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-units"></a>-units <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the units of image resolution</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from: <strong>Undefined</strong>, <strong>PixelsPerInch</strong>, or
+<strong>PixelsPerCentimeter</strong>. This option is normally used in conjunction
+with the <strong>-density</strong> option.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-unsharp"></a>-unsharp <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+&lt;amount&gt;</i>}<i></i>{<i>+&lt;threshold&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image with an unsharp mask operator</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The <strong>-unsharp</strong> option sharpens an image. The image is convolved
+with a Gaussian operator of the given radius and standard deviation
+(sigma). For reasonable results, radius should be larger than sigma. Use
+a radius of 0 to have the method select a suitable radius.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The parameters are:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>radius</dt>
+<dd>
+The radius of the Gaussian, in pixels, not counting the center pixel (default 0).
+</dd>
+<dt>sigma</dt>
+<dd>
+The standard deviation of the Gaussian, in pixels (default 1.0).
+</dd>
+<dt>amount</dt>
+<dd>
+The percentage of the difference between the original and the blur image that
+is added back into the original (default 1.0).
+</dd>
+<dt>threshold</dt>
+<dd>
+The threshold, as a fraction of MaxRGB, needed to apply the difference
+amount (default 0.05).
+</dd>
+</dl>
+</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -use-pixmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use the pixmap</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-verbose"></a>-verbose
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This information is printed: image scene number; image name; image size;
+the image class (<em>DirectClass</em> or <em>PseudoClass</em>); the total
+number of unique colors; and the number of seconds to read and transform
+the image. If the image is <em>DirectClass</em>, the total number of unique
+colors is not displayed unless <strong>-verbose</strong> is specified twice since
+it may take quite a long time to compute, particularly for deep images.
+If the image is <em>PseudoClass</em> then its pixels are defined by indexes
+into a colormap. If the image is <em>DirectClass</em> then each pixel
+includes a complete and independent color specification.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If <strong>-colors</strong> is also specified, the total unique colors in the image
+and color reduction error values are printed. Refer to <a href="quantize.html">quantize</a>
+for a description of these values.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-version"></a>-version
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -view <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>FlashPix viewing parameters</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-virtual-pixel"></a>-virtual-pixel <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify contents of "virtual pixels"</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option
+defines "virtual pixels" for use in operations that can access pixels outside
+the boundaries of an image.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from these methods:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<dl>
+<dt>Constant</dt>
+<dd>
+Use the image background color.
+</dd>
+<dt>Edge</dt>
+<dd>
+Extend the edge pixel toward infinity (default).
+</dd>
+<dt>Mirror</dt>
+<dd>
+Mirror the image.
+</dd>
+<dt>Tile</dt>
+<dd>
+Tile the image.
+</dd>
+</dl>
+</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+This option affects operations that use
+virtual pixels such as <strong>-blur</strong>, <strong>-sharpen</strong>, <strong>-wave</strong>, etc.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-visual"></a>-visual <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>animate images using this X visual type</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Choose from these visual classes:</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ StaticGray
+ GrayScale
+ StaticColor
+ PseudoColor
+ TrueColor
+ DirectColor
+ default
+ visual id
+</pre></font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The X server must support the visual you choose, otherwise an error occurs.
+If a visual is not specified, the visual class that can display the most
+simultaneous colors on the default screen is chosen.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -watermark <i>&lt;brightness&gt;x&lt;saturation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>percent brightness and saturation of a watermark</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-wave"></a>-wave <i>&lt;amplitude&gt;x&lt;wavelength&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>alter an image along a sine wave</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Specify <em>amplitude</em> and <em>wavelength</em>
+of the wave.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-white-point"></a>-white-point <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-white-threshold"></a>-white-threshold <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels above the threshold become white</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>-white-threshold</strong> to set pixels with values above the specified
+threshold to maximum value (white). If only one value is supplied, or the
+red, green, and blue values are identical, then intensity thresholding is
+used. If the color threshold values are not identical then channel-based
+thresholding is used, and color distortion will occur. Specify a negative
+value (e.g. -1) if you want a channel to be ignored but you do want to
+threshold a channel later in the list. If a percent (%) symbol is
+appended, then the values are treated as a percentage of maximum
+range.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-window"></a>-window <i>&lt;id&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image the background of a window</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+<em>id</em> can be a window id or name. Specify <strong>root</strong> to
+select X's root window as the target window.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default the image is tiled onto the background of the target
+window. If <strong>backdrop</strong> or <strong>-geometry</strong> are
+specified, the image is surrounded by the background color. Refer to
+<strong>X RESOURCES</strong> for details.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The image will not display on the root window if the image has more
+unique colors than the target window colormap allows. Use
+<strong>-colors</strong> to reduce the number of colors.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -window-group
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the window group</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-write"></a>-write <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write an intermediate image [<em>convert, composite</em>]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The current image is written to the specified filename and then
+processing continues using that image. The following is an example of how
+several sizes of an image may be generated in one command (repeat as
+often as needed):</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ gm convert input.jpg -resize 50% -write input50.jpg \
+ -resize 25% input25.jpg
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a name="details-write"></a>-write <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write the image to a file [<em>display</em>]</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+If <em>filename</em> already exists, you will be prompted as to whether it should
+be overwritten.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+By default, the image is written in the format that it was read in as.
+To specify a particular image format, prefix <em>filename</em> with the
+image type and a colon (e.g., ps:image) or specify the image type as
+the filename suffix (e.g., image.ps). Specify file as - for standard
+output. If file has the extension <strong>.Z</strong> or <strong>.gz</strong>, the file
+size is <strong>compressed</strong> using compress or <strong>gzip</strong>
+respectively. Precede the image file name with | to pipe to a system
+command.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Use <strong>-compress</strong> to specify the type of image compression.</font></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+The equivalent X resource for this option is
+<strong>writeFilename</strong> (class <strong>WriteFilename</strong>).
+See
+"X Resources", below,
+for details.</font></td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="envi"></a>Environment
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ COLUMNS
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Output screen width. Used when formatting text for the screen. Many
+Unix systems keep this shell variable up to date, but it may need to be
+explicitly exported in order for GraphicsMagick to see it.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ DISPLAY
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>X11 display ID (host, display number, and screen in the form
+hostname:display.screen).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ HOME
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Location of user's home directory. GraphicsMagick searches for
+configuration files in $HOME/.magick if the directory exists. See
+<strong>MAGICK_CODER_MODULE_PATH</strong>, <strong>MAGICK_CONFIGURE_PATH</strong>, and
+<strong>MAGICK_FILTER_MODULE_PATH</strong> if more flexibility is needed.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_ACCESS_MONITOR
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>When set to <strong>TRUE</strong>, command line monitor mode (enabled by
+<strong>-monitor</strong>) will also show files accessed (including temporary
+files) and any external commands which are executed. This is useful
+for debugging, but also illustrates arguments made available to an
+access handler registered by the
+<strong>MagickSetConfirmAccessHandler()</strong> C library function.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_CODER_STABILITY
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>The minimum coder stability level before it will be used. The
+available levels are <strong>PRIMARY</strong>, <strong>STABLE</strong>, <strong>UNSTABLE</strong>,
+and <strong>BROKEN</strong>. The default minimum level is <strong>UNSTABLE</strong>,
+which means that all available working coders will be used. The
+purpose of this option is to reduce the security exposure (or apparent
+complexity) due to the huge number of formats supported. Coders at the
+<strong>PRIMARY</strong> level are commonly used formats with very well
+maintained implementations. Coders at the <strong>STABLE</strong> level are
+reasonably well maintained but represent less used formats. Coders at
+the <strong>UNSTABLE</strong> level either have weak implementations, the file
+format itself is weak, or the probability the coder will be needed is
+vanishingly small. Coders at the <strong>BROKEN</strong> level are known to
+often not work properly or might not be useful in their current state
+at all.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_CODER_MODULE_PATH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Search path to use when searching for image format coder modules.
+This path allows the user to arbitrarily extend the image formats
+supported by GraphicsMagick by adding loadable modules to an arbitrary
+location rather than copying them into the GraphicsMagick installation
+directory. The formatting of the search path is similar to operating
+system search paths (i.e. colon delimited for Unix, and semi-colon
+delimited for Microsoft Windows). This user specified search path is used
+before trying the default search path.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_CONFIGURE_PATH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Search path to use when searching for configuration (.mgk) files.
+The formatting of the search path is similar to operating system search
+paths (i.e. colon delimited for Unix, and semi-colon delimited for
+Microsoft Windows). This user specified search path is used before trying
+the default search path.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_DEBUG
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Debug options (see <strong>-debug</strong> for details). Setting debug
+options via an environment variable is currently necessary to see the
+complete initialization process.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_FILTER_MODULE_PATH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Search path to use when searching for filter process modules
+(invoked via <strong>-process</strong>). This path allows the user to arbitrarily
+extend GraphicsMagick's image processing functionality by adding loadable
+modules to an arbitrary location rather than copying them into the
+GraphicsMagick installation directory. The formatting of the search path
+is similar to operating system search paths (i.e. colon delimited for
+Unix, and semi-colon delimited for Microsoft Windows). This user
+specified search path is used before trying the default search path.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_GHOSTSCRIPT_PATH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>For Microsoft Windows, specify the path to the Ghostscript
+installation rather than searching for it via the Windows registry.
+This helps in case Ghostscript is not installed via the Ghostscript
+Windows installer or the user wants more control over the Ghostscript
+used.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_HOME
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Path to top of GraphicsMagick installation directory. Only observed
+by "uninstalled" builds of GraphicsMagick which do not have their location
+hard-coded or set by an installer.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_MMAP_READ
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>If <strong>MAGICK_MMAP_READ</strong> is set to <strong>TRUE</strong>, GraphicsMagick
+will attempt to memory-map the input file for reading. This usually
+substantially improves repeated read performance since the file is
+already in memory after the first time it has been read. However,
+testing shows that performance may be reduced for files accessed for
+the first time since data is accessed via page-faults (upon first
+access) and many operating systems fail to do sequential read-ahead of
+memory mapped files, and particularly if those files are accessed over
+a network. If many large input files are read, then enabling this
+option may harm performance by overloading the operating system's VM
+system as it then needs to free unmapped pages and map new ones.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_IO_FSYNC
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>If <strong>MAGICK_IO_FSYNC</strong> is set to <strong>TRUE</strong>, then GraphicsMagick
+will request that the output file is fully flushed and synchronized to
+disk when it is closed. This incurs a performance penalty, but has the
+benefit that if the power fails or the system crashes, the file should be
+valid on disk. If image files are referenced from a database, then this
+option helps assure that the files referenced by the database are
+valid.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_IOBUF_SIZE
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>The amount of I/O buffering (in bytes) to use when reading and
+writing encoded files. The default is 16384, which is observed to work
+well for many cases. The best value for a local filesystem is usually the
+the native filesystem block size (e.g. 4096, 8192, or even 131,072 for
+ZFS) in order to minimize the number of physical disk I/O operations.
+I/O performance to files accessed over a network may benefit
+significantly by tuning this option. Larger values are not necessarily
+better (they may be slower!), and there is rarely any benefit from using
+values larger than 32768. Use convert's <strong>-verbose</strong> option in order
+to evaluate read and write rates in pixels per second while keeping in
+mind that the operating system will try to cache files in RAM.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_DISK
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum amount of disk space allowed for use by the pixel cache.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_FILES
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum number of open files.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_MAP
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum size of a memory mapped file allocation. A memory mapped
+file consumes memory when the file is accessed, although the system
+may reclaim such memory when needed.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_MEMORY
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum amount of memory to allocate from the heap.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_PIXELS
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum number of total pixels (image rows times image colums) to
+allow for any image which is requested to be created or read. This is
+useful to place a limit on how large an image may be. If the input
+image file has image dimensions larger than the pixel limit, then the
+image memory allocation is denied and an error is returned
+immediately. This is a per-image limit and does not limit the total
+number of pixels due to multiple image frames/pages (e.g. multi-page
+document or an animation).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_WIDTH
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum pixel width of an image read, or created.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_LIMIT_HEIGHT
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Maximum pixel height of an image read, or created.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ MAGICK_TMPDIR
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Path to directory where GraphicsMagick should write temporary
+files. The default is to use the system default, or the location set by
+<strong>TMPDIR</strong>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ TMPDIR
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>For POSIX-compatible systems (Unix-compatible), the path to the
+directory where all applications should write temporary files.
+Overridden by <strong>MAGICK_TMPDIR</strong> if it is set.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ TMP <i>or TEMP</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>For Microsoft Windows, the path to the directory where applications
+should write temporary files. Overridden by <strong>MAGICK_TMPDIR</strong> if it
+is set.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ OMP_NUM_THREADS
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>As per the OpenMP standard, this specifies the number of threads to
+use in parallel regions. Some compilers default the number of threads to
+use to the number of processor cores available while others default to
+just one thread. See the OpenMP specification for other standard
+adjustments and your compiler's manual for vendor-specific settings.</td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="file"></a>Configuration Files
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>GraphicsMagick uses a number of XML format configuration files:
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ colors.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colors configuration file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ &lt;?xml version="1.0"?&gt;
+ &lt;colormap&gt;
+ &lt;color name="AliceBlue" red="240" green="248" blue="255"
+ compliance="SVG, X11, XPM" /&gt;
+ &lt;/colormap&gt;
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ delegates.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>delegates configuration file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ log.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>logging configuration file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ &lt;?xml version="1.0"?&gt;
+ &lt;magicklog&gt;
+ &lt;log events="None" /&gt;
+ &lt;log output="stdout" /&gt;
+ &lt;log filename="Magick-%d.log" /&gt;
+ &lt;log generations="3" /&gt;
+ &lt;log limit="2000" /&gt;
+ &lt;log format="%t %r %u %p %m/%f/%l/%d:\n %e" /&gt;
+ &lt;/magicklog&gt;
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ modules.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>loadable modules configuration file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ &lt;?xml version="1.0"?&gt;
+ &lt;modulemap&gt;
+ &lt;module magick="8BIM" name="META" /&gt;
+ &lt;/modulemap&gt;
+</pre></font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ type.mgk
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>master type (fonts) configuration file</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"><pre>
+ &lt;?xml version="1.0"?&gt;
+ &lt;typemap&gt;
+ &lt;<strong></strong>include file="type-windows.mgk" /&gt;
+ &lt;type
+ name="AvantGarde-Book"
+ fullname="AvantGarde Book"
+ family="AvantGarde"
+ foundry="URW"
+ weight="400"
+ style="normal"
+ stretch="normal"
+ format="type1"
+ metrics="/usr/local/share/ghostscript/fonts/a010013l.afm"
+ glyphs="/usr/local/share/ghostscript/fonts/a010013l.pfb"
+ /&gt;
+ &lt;/typemap&gt;
+</pre></font></td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="animate"></a>gm animate
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Animate</strong> displays a sequence of images on any workstation display
+running an X server. <strong>animate</strong> first determines the hardware capabilities
+of the workstation. If the number of unique colors in an image is less
+than or equal to the number the workstation can support, the image is displayed
+in an X window. Otherwise the number of colors in the image is first reduced
+to match the color resolution of the workstation before it is displayed.
+<p>
+This means that a continuous-tone 24 bits-per-pixel image can display on
+a 8 bit pseudo-color device or monochrome device. In most instances the
+reduced color image closely resembles the original. Alternatively, a monochrome
+or pseudo-color image sequence can display on a continuous-tone 24 bits-per-pixel
+device.
+<p>
+To help prevent color flashing on X server visuals that have colormaps,
+<strong>animate</strong>
+creates a single colormap from the image sequence. This can be rather time
+consuming. You can speed this operation up by reducing the colors in the
+image before you "animate" them. Use <strong>mogrify</strong> to color reduce the
+images to a single colormap. See <strong>mogrify(1)</strong> for details. Alternatively,
+you can use a Standard Colormap; or a static, direct, or true color visual.
+You can define a Standard Colormap with <em>xstdcmap</em>. See <strong>xstdcmap(1)</strong>
+for details. This method is recommended for colormapped X server because
+it eliminates the need to compute a global colormap.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To animate a set of images of a cockatoo, use:
+<pre>
+ gm animate cockatoo.*
+</pre>
+<p>
+To animate a cockatoo image sequence while using the Standard Colormap
+<em>best</em>, use:
+<pre>
+ xstdcmap -best
+ gm animate -map best cockatoo.*
+</pre>
+<p>
+To animate an image of a cockatoo without a border centered on a backdrop,
+use:
+<br>&nbsp;<br>
+<pre>
+ gm animate +borderwidth -backdrop cockatoo.*
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-backdrop">-backdrop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the image centered on a backdrop.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -borderwidth <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-chop">-chop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixels from the interior of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colormap">-colormap</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the colormap type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-foreground">-foreground</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the foreground color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-iconGeometry">-iconGeometry</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the icon geometry</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -iconic
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>iconic animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-map">-map</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display image using this type.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -name
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pause">-pause</a> <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pause between animation loops [animate]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-remote">-remote</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform a X11 remote operation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scenes">-scenes</a> <i>&lt;value-value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>range of image scene numbers to read</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shared-memory">-shared-memory</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use shared memory</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-text-font">-text-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>font for writing fixed-width text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-title">-title</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign title to displayed image [<em>animate, display, montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-visual">-visual</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>animate images using this X visual type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-window">-window</a> <i>&lt;id&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image the background of a window</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<p>
+Any option you specify on the command line remains in effect for the group
+of images following it, until the group is terminated by the appearance of
+any option or <strong>-noop</strong>. For example, to animate three images, the first
+with 32 colors, the second with an unlimited number of colors, and the
+third with only 16 colors, use:
+<br>&nbsp;<br>
+<pre>
+ gm animate -colors 32 cockatoo.1 -noop cockatoo.2
+ -colors 16 cockatoo.3
+</pre>
+<p>
+<strong>Animate</strong> options can appear on the command line or in your X resources
+file. See <em>X(1)</em>. Options on the command line supersede values specified
+in your X resources file.
+<p>Image filenames may appear in any order on the command line if the image
+format is <em>MIFF</em> (refer to <strong>miff(5)</strong> and the
+<strong>scene</strong> keyword
+is specified in the image. Otherwise the images will display in the order
+they appear on the command line.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mous"></a>Mouse Buttons
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Press any button to map or unmap the Command widget. See the next section
+for more information about the Command widget.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comm"></a>Command Widget
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The Command widget lists a number of sub-menus and commands. They are
+<ul>
+<li><strong>Animate</strong>
+<ul>
+<li> Open
+<li> Play
+<li> Step
+<li> Repeat
+<li> Auto Reverse
+</ul>
+<li><strong>Speed</strong>
+<ul>
+<li> Faster
+<li> Slower
+</ul>
+<li><strong>Direction</strong>
+<ul>
+<li> Forward
+<li> Reverse
+</ul>
+<li><strong>Image Info</strong>
+<li><strong>Help</strong>
+<li><strong>Quit</strong>
+</ul>
+<p>
+Menu items with a indented triangle have a sub-menu. They are represented
+above as the indented items. To access a sub-menu item, move the pointer
+to the appropriate menu and press a button and drag. When you find the
+desired sub-menu item, release the button and the command is executed.
+Move the pointer away from the sub-menu if you decide not to execute a
+particular command.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="keyb"></a>Keyboard Accelerators
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt><strong>Ctl+O</strong></dt>
+<dd>Press to load an image from a file.</dd>
+<dt><strong>space</strong></dt>
+<dd>Press to display the next image in the sequence.</dd>
+<dt><strong>&lt;</strong></dt>
+<dd>Press to speed-up the display of the images. Refer to
+<strong>-delay</strong> for more information.</dd>
+<dt><strong>&gt;</strong></dt>
+<dd>Press to slow the display of the images. Refer to
+<strong>-delay</strong> for more information.</dd>
+<dt><strong>?</strong></dt>
+<dd>Press to display information about the image. Press
+any key or button to erase the information.</dd>
+<dd>This information is printed: image name; image size;
+and the total number of unique colors in the image.</dd>
+<dt><strong>F1</strong></dt>
+<dd>Press to display helpful information about <strong>animate(1)</strong>.</dd>
+<dt><strong>Ctl-q</strong></dt>
+<dd>Press to discard all images and exit program.</dd>
+</dl>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="xres"></a>X Resources
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Animate</strong> options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See <strong>X(1)</strong> for more information on X resources.
+<p>
+All <strong>animate</strong> options have a corresponding X resource. In addition,
+the <strong>animate</strong> program uses the following X resources:
+<dl>
+<dt><strong>background</strong> <strong>(</strong><em>class</em> <strong>Background)</strong></dt>
+<dd>
+Specifies the preferred color to use for the Image window background. The
+default is #ccc.</dd>
+<dt><strong>borderColor</strong> <strong>(</strong><em>class</em> <strong>BorderColor)</strong></dt>
+<dd>
+Specifies the preferred color to use for the Image window border. The default
+is #ccc.</dd>
+<dt><strong>borderWidth</strong> <strong>(</strong><em>class</em> <strong>BorderWidth)</strong></dt>
+<dd>
+Specifies the width in pixels of the Image window border. The default is
+2.</dd>
+<dt><strong>font</strong> <strong>(</strong><em>class</em> <strong>Font</strong> <strong>or</strong> <strong>FontList)</strong></dt>
+<dd>
+Specifies the name of the preferred font to use in normal formatted text.
+The default is 14 point <em>Helvetica</em>.</dd>
+<dt><strong>foreground</strong> <strong>(</strong><em>class</em> <strong>Foreground)</strong></dt>
+<dd>
+Specifies the preferred color to use for text within the Image window.
+The default is black.</dd>
+<dt><strong>geometry</strong> <strong>(</strong><em>class</em> <strong>geometry)</strong></dt>
+<dd>
+Specifies the preferred size and position of the image window. It is not
+necessarily obeyed by all window managers.
+Offsets, if present, are handled in <em>X(1)</em> style. A negative x offset is
+measured from the right edge of the screen to the right edge of the icon,
+and a negative y offset is measured from the bottom edge of the screen
+to the bottom edge of the icon.</dd>
+<dt><strong>iconGeometry</strong> <strong>(</strong><em>class</em> <strong>IconGeometry)</strong></dt>
+<dd>
+Specifies the preferred size and position of the application when iconified.
+It is not necessarily obeyed by all window managers.
+Offsets, if present, are handled in the same manner as in class Geometry.</dd>
+<dt><strong>iconic</strong> <strong>(</strong><em>class</em> <strong>Iconic)</strong></dt>
+<dd>
+This resource indicates that you would prefer that the application's windows
+initially not be visible as if the windows had be immediately iconified
+by you. Window managers may choose not to honor the application's request.</dd>
+<dt><strong>matteColor</strong> <strong>(</strong><em>class</em> <strong>MatteColor)</strong></dt>
+<dd>
+Specify the color of windows. It is used for the backgrounds of windows,
+menus, and notices. A 3D effect is achieved by using highlight and shadow
+colors derived from this color. Default value: #ddd.</dd>
+<dt><strong>name</strong> <strong>(</strong><em>class</em> <strong>Name)</strong></dt>
+<dd>
+This resource specifies the name under which resources for the application
+should be found. This resource is useful in shell aliases to distinguish
+between invocations of an application, without resorting to creating links
+to alter the executable file name. The default is the application name.</dd>
+<dt><strong>sharedMemory</strong> <strong>(</strong><em>class</em> <strong>SharedMemory)</strong></dt>
+<dd>
+This resource specifies whether animate should attempt use shared memory
+for pixmaps. ImageMagick must be compiled with shared memory support, and
+the display must support the MIT-SHM extension. Otherwise, this resource
+is ignored. The default is True.</dd>
+<dt><strong>text_font</strong> <strong>(</strong><em>class</em> <strong>textFont)</strong></dt>
+<dd>
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point <em>Courier</em>.</dd>
+<dt><strong>title</strong> <strong>(</strong><em>class</em> <strong>Title)</strong></dt>
+<dd>
+This resource specifies the title to be used for the Image window. This
+information is sometimes used by a window manager to provide some sort
+of header identifying the window. The default is the image file name.</dd>
+</dl>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch"></a>gm batch
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>batch</strong> executes an arbitary number of the utility commands
+(e.g. <strong>convert</strong>) in the form of a simple linear batch script in
+order to improve execution efficiency, and/or to allow use as a
+subordinate co-process under the control of an arbitrary script or
+program.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p> To drive <strong>'gm batch'</strong> using a shell script (or a program
+written in any language), have the script/program send commands to 'gm
+batch' via its standard input. Specify that standard input should be
+used by using <strong>'-'</strong> as the file name. The following example
+converts all files matching '*.jpg' to TIFF format while rotating each
+file by 90 degrees and stripping all embedded profiles. The shell
+script syntax is standard Unix shell:
+<pre>
+ for file in *.jpg
+ do
+ outfile=`basename $file .jpg`.tiff
+ echo convert -verbose "'$file'" -rotate 90 \
+ +profile "'*'" "'$outfile'"
+ done | gm batch -echo on -feedback on -
+</pre>
+<p>
+We can accomplish the same as the previous example by putting all the
+commands in a text file and then specifying the name of the text file
+as the script to execute:
+<pre>
+ for file in *.jpg
+ do
+ outfile=`basename $file .jpg`.tiff
+ echo convert -verbose "'$file'" -rotate 90 \
+ +profile "'*'" "'$outfile'"
+ done &gt; script.txt
+ gm batch -echo on -feedback on script.txt
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="batch-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed from left to right and must appear before any filename argument.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -echo <i>on|off</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>command echo on or off</td></tr></table>
+<p>
+Specify <strong>on</strong> to enable echoing commands to standard output as
+they are read or <strong>off</strong> to disable. The default is
+<strong>off</strong>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -escape <i>unix|windows</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Parse using unix or windows syntax</td></tr></table>
+<p>
+Commands must be parsed from the input stream and escaping needs to be
+used to protect spaces or quoting characters in the input. Specify
+<strong>unix</strong> to use unix-style command line parsing or <strong>windows</strong>
+for Microsoft Windows command shell style parsing. The default depends
+on if the software is compiled for Microsoft Windows or for a
+Unix-type system (including Cygwin on Microsoft Windows). It is
+recommended to use unix syntax because it is more powerful and more
+portable.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -fail <i>text</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>text to print if a command fails</td></tr></table>
+<p>
+When feedback is enabled, this specifies the text to print when the
+command fails. The default text is <strong>FAIL</strong>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -feedback <i>on|off</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable error feedback</td></tr></table>
+<p>
+Print text (see -pass and -fail options) feedback after each
+command to indicate the result, the default is <strong>off</strong>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<p>
+Prints batch command help.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pass <i>text</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>text to print if a command passes</td></tr></table>
+<p>
+When feedback is enabled, this specifies the text to print when the
+command passes. The default text is <strong>PASS</strong>.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -prompt <i>text</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Prompt text to use for command line</td></tr></table>
+<p>
+If no filename argument was specified, a simple command prompt appears
+where you may enter GraphicsMagick commands. The default prompt is
+<strong>GM&gt;</strong>. Use this option to change the prompt to something else.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -stop-on-error <i>on|off</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify if command processing stops on error</td></tr></table>
+<p>
+Normally command processing continues if a command encounters an
+error. Specify <strong>-stop-on-error on</strong> to cause processing to quit
+immediately on error.
+</td></tr></table>
+</td></tr></table>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="benchmark"></a>gm benchmark
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>benchmark</strong> executes an arbitrary <strong>gm</strong> utility command
+(e.g. <strong>convert</strong>) for one or more loops, and/or a specified
+execution time, and reports many execution metrics. For builds using
+OpenMP, a mode is provided to execute the benchmark with an increasing
+number of threads and provide a report of speedup and multi-thread
+execution efficiency. If <strong>benchmark</strong> is used to execute a
+command without any additional benchmark options, then the command is
+run once.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>To obtain benchmark information for a single execution of a
+command:
+<pre>
+ gm benchmark convert input.ppm -gaussian 0x1 output.ppm
+</pre>
+<p>To obtain benchmark information from 100 iterations of the
+command:
+<pre>
+ gm benchmark -iterations 100 convert input.ppm \
+ -gaussian 0x1 output.ppm
+</pre>
+<p>To obtain benchmark information by iterating the command until a
+specified amount of time (in seconds) has been consumed:
+<pre>
+ gm benchmark -duration 30 convert input.ppm \
+ -gaussian 0x1 output.ppm
+</pre>
+<p>To obtain a full performance report with an increasing number of
+threads (1-32 threads, stepping the number of threads by four each
+time):
+<pre>
+ gm benchmark -duration 3 -stepthreads 4 convert \
+ input.ppm -gaussian 0x2 output.ppm
+</pre>
+<p>Here is the interpretation of the output:
+<ul>
+<li><strong>threads</strong> - number of threads used.
+<li><strong>iter</strong> - number of command iterations executed.
+<li><strong>user</strong> - total user time consumed.
+<li><strong>total</strong> - total elapsed time consumed.
+<li><strong>iter/s</strong> - number of command iterations per second.
+<li><strong>iter/cpu</strong> - amount of CPU time consumed per iteration.
+<li><strong>speedup</strong> - speedup compared with one thread.
+<li><strong>karp-flatt</strong> - Karp-Flatt measure of speedup efficiency.
+</ul>
+<p><em>Please note that the reported "speedup" is based on the
+execution time of just one thread. A preliminary warm-up pass is used
+before timing the first loop in order to ensure that the CPU is
+brought out of power-saving modes and that system caches are warmed
+up. Most modern CPUs provide a "turbo" mode where the CPU clock speed
+is increased (e.g. by a factor of two) when only one or two cores are
+active. If the CPU grows excessively hot (due to insufficient
+cooling), then it may dial back its clock rates as a form of thermal
+management. These factors result in an under-reporting of speedup
+compared to if "turbo" mode was disabled and the CPU does not need to
+worry about thermal management. The <strong>powertop</strong> utility available
+under Linux and Solaris provides a way to observe CPU core clock rates
+while a benchmark is running.</em>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="bench-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p> Options are processed from left to right and must appear before
+any argument.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -duration <i>duration</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>duration to run benchmark</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Specify the number of seconds to run the benchmark. The command is
+executed repeatedly until the specified amount of time has
+elapsed.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Prints benchmark command help.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -iterations <i>loops</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>number of command iterations</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Specify the number of iterations to run the benchmark. The command
+is executed repeatedly until the specified number of iterations has
+been reached.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -rawcsv
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Print results in CSV format</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">Print results in a comma-separated value (CSV) format which is easy
+to parse for plotting or importing into a spreadsheet or database.
+The values reported are <strong>threads</strong>, <strong>iterations</strong>,
+<strong>user_time</strong>, and <strong>elapsed_time</strong>.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -stepthreads <i>step</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>execute a per-thread benchmark ramp</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1"> Execute a per-thread benchmark ramp, incrementing the number of
+threads at each step by the specified value. The maximum number of
+threads is taken from the standard <tt>OMP_NUM_THREADS</tt>
+environment variable.</font></td></tr></table>
+</td></tr></table>
+</td></tr></table>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="compare"></a>gm compare
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>compare</strong> compares two similar images using a specified statistical
+method (see <strong>-metric</strong>) and/or by writing a difference image
+(<strong>-file</strong>), with the altered pixels annotated using a specified
+method (see <strong>-highlight-style</strong>) and color (see
+<strong>-highlight-color</strong>). <p><em>Reference-image</em> is the original
+image and <em>compare-image</em> is the (possibly) altered version, which
+should have the same dimensions as <em>reference-image</em>.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To compare two images using Mean Square Error (MSE) statistical analysis
+use:
+<pre>
+ gm compare -metric mse original.miff compare.miff
+</pre>
+<p>
+To create an annotated difference image use:
+<pre>
+ gm compare -highlight-style assign -highlight-color purple \
+ -file diff.miff original.miff compare.miff
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect only for the image that follows. All
+options are reset to their default values after each image is read.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-file">-file</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write annotated difference image to file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-highlight-color">-highlight-color</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixel annotation color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-highlight-style">-highlight-style</a> <i>&lt;style&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixel annotation style</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-maximum-error">-maximum-error</a> <i>&lt;limit&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the maximum amount of total image error</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -metric <i>&lt;metric&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>comparison metric (MAE, MSE, PAE, PSNR, RMSE)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+</td></tr></table>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="composite"></a>gm composite
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>composite</strong> composites (combines) images to create new images.
+<p><em>base-image</em> is the base image and <em>change-image</em> contains the changes.
+<em>ouput-image</em> is the result, and normally has the same dimensions
+as <em>base-image</em>.
+<br>&nbsp;<br>
+<p>
+The optional <em>mask-image</em> can be used to provide opacity information
+for <em>change-image</em> when it has none or if you want a different mask.
+A mask image is typically grayscale and the same size as
+<strong>base-image</strong>. If <em>mask-image</em> is not grayscale, it is converted
+to grayscale and the resulting intensities are used as opacity
+information.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To composite an image of a cockatoo with a perch, use:
+<pre>
+ gm composite cockatoo.miff perch.ras composite.miff
+</pre>
+<p>
+To compute the difference between images in a series, use:
+<pre>
+ gm composite -compose difference series.2 series.1
+ difference.miff
+</pre>
+<p>
+To composite an image of a cockatoo with a perch starting at location (100,150),
+use:
+<pre>
+ gm composite -geometry +100+150 cockatoo.miff
+ perch.ras composite.miff
+</pre>
+<p>
+To tile a logo across your image of a cockatoo, use
+<pre>
+ gm convert +shade 30x60 cockatoo.miff mask.miff
+ gm composite -compose bumpmap -tile logo.png
+ cockatoo.miff mask.miff composite.miff
+</pre>
+<p>
+To composite a red, green, and blue color plane into a single composite image,
+try
+<pre>
+ gm composite -compose CopyGreen green.png red.png
+ red-green.png
+ gm composite -compose CopyBlue blue.png red-green.png
+ gm composite.png
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="comp-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect only for the image that follows. All
+options are reset to their default values after each image is read.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blue-primary">-blue-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compose">-compose</a> <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-displace">-displace</a> <i>&lt;horizontal scale&gt;x&lt;vertical scale&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shift image pixels as defined by a displacement map</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dissolve">-dissolve</a> <i>&lt;percent&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>dissolve an image into another by the given percent</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gravity">-gravity</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-green-primary">-green-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-profile">-profile</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add ICM, IPTC, or generic profile to image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-recolor">-recolor</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a color translation matrix to image channels</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-red-primary">-red-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-render">-render</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-repage">-repage</a> <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scene">-scene</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stegano">-stegano</a> <i>&lt;offset&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>hide watermark within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stereo">-stereo</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite two images to create a stereo anaglyph</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strip">-strip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-units">-units</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the units of image resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-unsharp">-unsharp</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+&lt;amount&gt;</i>}<i></i>{<i>+&lt;threshold&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image with an unsharp mask operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -watermark <i>&lt;brightness&gt;x&lt;saturation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>percent brightness and saturation of a watermark</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-point">-white-point</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-write">-write</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write an intermediate image [<em>convert, composite</em>]</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+</td></tr></table>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conjure"></a>gm conjure
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The Magick scripting language (MSL) will primarily benefit those that
+want to accomplish custom image processing tasks but do not wish to
+program, or those that do not have access to a Perl interpreter or a
+compiler. The interpreter is called conjure and here is an example
+script:
+<pre>
+ &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ &lt;image size="400x400" &gt;
+ &lt;read filename="image.gif" /&gt;
+ &lt;get width="base-width" height="base-height" /&gt;
+ &lt;resize geometry="%[dimensions]" /&gt;
+ &lt;get width="width" height="height" /&gt;
+ &lt;print output=
+ "Image sized from %[base-width]x%[base-height]
+ to %[width]x%[height].\n" /&gt;
+ &lt;write filename="image.png" /&gt;
+ &lt;/image&gt;
+</pre>
+<p>
+invoked with
+<pre>
+ gm conjure -dimensions 400x400 incantation.msl
+</pre>
+<p>
+All operations will closely follow the key/value pairs defined in
+PerlMagick, unless otherwise noted.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conj-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect, or if it is changed by a statement
+in the scripting language.
+<p>
+You can define your own keyword/value pairs on the command line.
+The script can then use this information when setting values by including
+%[keyword] in the string. For example, if you included
+"-dimensions 400x400" on the command line, as illustrated above,
+then any string
+containing "%[dimensions]" would have 400x400 substituted.
+The "%[string]" can be used either an entire string, such as
+geometry="%[dimensions]" or as a part of a string such as
+filename="%[basename].png".
+<p>
+The keyword can be any string except for the following reserved
+strings (in any upper, lower, or mixed case variant): <strong>debug</strong>,
+<strong>help</strong>, and <strong>verbose</strong>, whose usage is described below.
+<p>
+The value can be any string. If
+either the keyword or the value contains white space or any
+symbols that have special meanings to your shell such as "#",
+"|",
+or
+"%", enclose the string in quotation marks or use "\" to escape the white
+space and special symbols.
+<p>
+Keywords and values are case dependent. "Key",
+"key",
+and "KEY" would
+be three different keywords.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conj-msl"></a>Magick Scripting Language
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The Magick Scripting Language (MSL) presently defines the following
+elements and their attributes:
+<dl>
+<dt>&lt;image&gt;</dt>
+<dd>background, color, id, size</dd>
+<dd>
+Define a new image object. <strong>&lt;/image&gt;</strong> destroys it. Because of
+this, if you wish to reference multiple "subimages" (aka pages or
+layers), you can embed one <strong>image</strong> element inside of another. For
+example:
+</dd>
+<dd>
+<pre>
+ &lt;image&gt;
+ &lt;read filename="input.png" /&gt;
+ &lt;get width="base-width" height="base-height" /&gt;
+ &lt;image height="base-height" width="base-width"&gt;
+ &lt;image /&gt;
+ &lt;write filename="output.mng" /&gt;
+ &lt;/image&gt;
+</pre>
+</dd>
+<dd>
+<pre>
+ &lt;image size="400x400" /&gt;
+</pre>
+</dd>
+<dt>&lt;group&gt;</dt>
+<dd>
+Define a new group of image objects. By default, images are only
+valid for the life of their <strong>&lt;image&gt;</strong>element.
+</dd>
+<dd>
+<pre>
+ &lt;image&gt; -- creates the image
+ ..... -- do stuff with it
+ &lt;/image&gt; -- dispose of the image
+</pre>
+</dd>
+<dd>
+However, in a group, all images in that group will stay around for the
+life of the group:
+</dd>
+<dd>
+<pre>
+ &lt;group&gt; -- start a group
+ &lt;image&gt; -- create an image
+ .... -- do stuff
+ &lt;/image&gt; -- NOOP
+ &lt;image&gt; -- create another image
+ .... -- do more stuff
+ &lt;/image&gt; -- NOOP
+ &lt;write filename="image.mng" /&gt; -- output
+ &lt;/group&gt; -- dispose of both images
+</pre>
+</dd>
+<dt>&lt;read&gt;</dt>
+ <dd>filename</dd>
+<dd>
+Read a new image from a disk file.
+</dd>
+<dd>
+<pre>
+ &lt;read filename="image.gif" /&gt;
+</pre>
+</dd>
+<dd>
+To read two images use
+</dd>
+<dd>
+<pre>
+ &lt;read filename="image.gif" /&gt;
+ &lt;read filename="image.png /&gt;
+</pre>
+</dd>
+<dt>&lt;write&gt;</dt>
+ <dd>filename</dd>
+<dd>Write the image(s) to disk, either as
+a single multiple-image file or multiple ones if necessary.
+</dd>
+<dd>
+<pre>
+ &lt;write filename=image.tiff" /&gt;
+</pre>
+<dt>&lt;get&gt;</dt>
+<dd>Get any attribute recognized by
+PerlMagick's GetAttribute() and stores it as an image attribute for later
+use. Currently only <em>width</em> and <em>height</em> are supported.</dd>
+<dd>
+<pre>
+ &lt;get width="base-width" height="base-height" /&gt;
+ &lt;print output="Image size is %[base-width]x%[base-height].\n" /&gt;
+</pre>
+</dd>
+<dt>&lt;set&gt;</dt>
+<dd>background, bordercolor, clip-mask, colorspace, density,
+magick, mattecolor, opacity. Set an attribute recognized by
+PerlMagick's GetAttribute().</dd>
+<dt>&lt;profile&gt;</dt>
+ <dd>[profilename]</dd>
+<dd>
+Read one or more IPTC, ICC or generic profiles from file and assign to image
+</dd>
+<dd>
+<pre>
+ &lt;profile iptc="profile.iptc" generic="generic.dat" /&gt;
+</pre>
+</dd>
+<dd>
+To remove a specified profile use "!" as the filename eg
+</dd>
+<dd>
+<pre>
+ &lt;profile icm="!" iptc="profile.iptc" /&gt;
+</pre>
+</dd>
+<dt>&lt;border&gt;</dt>
+ <dd>fill, geometry, height, width</dd>
+<dt>&lt;blur&gt;</dt>
+ <dd>radius, sigma</dd>
+<dt>&lt;charcoal&gt;</dt>
+ <dd>radius, sigma</dd>
+<dt>&lt;chop&gt;</dt>
+ <dd>geometry, height, width, x, y</dd>
+<dt>&lt;crop&gt;</dt>
+ <dd>geometry, height, width, x, y</dd>
+<dt>&lt;composite&gt;</dt>
+ <dd>compose, geometry, gravity, image, x, y</dd>
+<dd>
+<pre>
+ &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ &lt;group&gt;
+ &lt;image id="image_01"&gt;
+ &lt;read filename="cloud3.gif"/&gt;
+ &lt;resize geometry="250x90"/&gt;
+ &lt;/image&gt;
+ &lt;image id="image_02"&gt;
+ &lt;read filename="cloud4.gif"/&gt;
+ &lt;resize geometry="190x100"/&gt;
+ &lt;/image&gt;
+ &lt;image&gt;
+ &lt;read filename="background.jpg"/&gt;
+ &lt;composite image="image_01" geometry="+740+470"/&gt;
+ &lt;composite image="image_02" geometry="+390+415"/&gt;
+ &lt;/image&gt;
+ &lt;write filename="result.png"/&gt;
+ &lt;/group&gt;
+</pre>
+</dd>
+<dt>&lt;despeckle&gt;</dt>
+<dt>&lt;emboss&gt;</dt>
+ <dd>radius, sigma</dd>
+<dt>&lt;enhance&gt;</dt>
+<dt>&lt;equalize&gt;</dt>
+<dt>&lt;edge&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;flip&gt;</dt>
+<dt>&lt;flop&gt;</dt>
+<dt>&lt;frame&gt;</dt>
+ <dd>fill, geometry, height, width, x, y, inner, outer</dd>
+<dt>&lt;flatten&gt;</dt>
+<dt>&lt;get&gt;</dt>
+ <dd>height, width</dd>
+<dt>&lt;gamma&gt;</dt>
+ <dd>red, green, blue</dd>
+<dt>&lt;image&gt;</dt>
+ <dd>background, color, id, size</dd>
+<dt>&lt;implode&gt;</dt>
+ <dd>amount</dd>
+<dt>&lt;magnify&gt;</dt>
+<dt>&lt;minify&gt;</dt>
+<dt>&lt;medianfilter&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;normalize&gt;</dt>
+<dt>&lt;oilpaint&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;print&gt;</dt>
+ <dd>output</dd>
+<dt>&lt;profile&gt;</dt>
+ <dd>[profilename]</dd>
+<dt>&lt;read&gt;</dt>
+<dt>&lt;resize&gt;</dt>
+ <dd>blur, filter, geometry, height, width</dd>
+<dt>&lt;roll&gt;</dt>
+ <dd>geometry, x, y</dd>
+<dt>&lt;rotate&gt;</dt>
+ <dd>degrees</dd>
+<dt>&lt;reducenoise&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;sample&gt;</dt>
+ <dd>geometry, height, width</dd>
+<dt>&lt;scale&gt;</dt>
+ <dd>geometry, height, width</dd>
+<dt>&lt;sharpen&gt;</dt>
+ <dd>radius, sigma</dd>
+<dt>&lt;shave&gt;</dt>
+ <dd>geometry, height, width</dd>
+<dt>&lt;shear&gt;</dt>
+ <dd>x, y</dd>
+<dt>&lt;solarize&gt;</dt>
+ <dd>threshold</dd>
+<dt>&lt;spread&gt;</dt>
+ <dd>radius</dd>
+<dt>&lt;stegano&gt;</dt>
+ <dd>image</dd>
+<dt>&lt;stereo&gt;</dt>
+ <dd>image</dd>
+<dt>&lt;swirl&gt;</dt>
+ <dd>degrees</dd>
+<dt>&lt;texture&gt;</dt>
+ <dd>image</dd>
+<dt>&lt;threshold&gt;</dt>
+ <dd>threshold</dd>
+<dt>&lt;transparent&gt;</dt>
+ <dd>color</dd>
+<dt>&lt;trim&gt;</dt>
+</dl>
+</td></tr></table>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a convert="top"></a>gm convert
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Convert</strong> converts an input file using one image format to an output
+file with a differing image format. In addition, various types of image
+processing can be performed on the converted image during the conversion
+process. <strong>Convert</strong> recognizes the image formats listed in
+<em>GraphicsMagick(1)</em>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conv-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To make a thumbnail of a JPEG image, use:
+<pre>
+ gm convert -size 120x120 cockatoo.jpg -resize 120x120
+ +profile "*" thumbnail.jpg
+</pre>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In this example, <tt>'-size 120x120'</tt> gives a hint to the JPEG decoder
+that the image is going to be downscaled to 120x120, allowing it to run
+faster by avoiding returning full-resolution images to GraphicsMagick for
+the subsequent resizing operation. The
+<tt>'-resize 120x120'</tt> specifies the desired dimensions of the
+output image. It will be scaled so its largest dimension is 120 pixels. The
+<tt>'+profile "*"'</tt> removes any ICM, EXIF, IPTC, or other profiles
+that might be present in the input and aren't needed in the thumbnail.</font></td></tr></table>
+<p>
+To convert a <em>MIFF</em> image of a cockatoo to a SUN raster image, use:
+<pre>
+ gm convert cockatoo.miff sun:cockatoo.ras
+</pre>
+<p>
+To convert a multi-page <em>PostScript</em> document to individual FAX pages,
+use:
+<pre>
+ gm convert -monochrome document.ps fax:page
+</pre>
+<p>
+To convert a TIFF image to a <em>PostScript</em> A4 page with the image in
+the lower left-hand corner, use:
+<pre>
+ gm convert -page A4+0+0 image.tiff document.ps
+</pre>
+<p>
+To convert a raw Gray image with a 128 byte header to a portable graymap,
+use:
+<pre>
+ gm convert -depth 8 -size 768x512+128 gray:raw
+ image.pgm
+</pre>
+<p>
+In this example, "raw" is the input file. Its format is "gray" and it
+has the dimensions and number of header bytes specified by the -size
+option and the sample depth specified by the
+-depth option. The output file is "image.pgm". The suffix ".pgm"
+specifies its format.
+<p>
+To convert a Photo CD image to a TIFF image, use:
+<pre>
+ gm convert -size 1536x1024 img0009.pcd image.tiff
+ gm convert img0009.pcd[4] image.tiff
+</pre>
+<p>
+To create a visual image directory of all your JPEG images, use:
+<pre>
+ gm convert 'vid:*.jpg' directory.miff
+</pre>
+<p>
+To annotate an image with blue text using font 12x24 at position (100,100),
+use:
+<pre>
+ gm convert -font helvetica -fill blue
+ -draw "text 100,100 Cockatoo"
+ bird.jpg bird.miff
+</pre>
+<p>
+To tile a 640x480 image with a JPEG texture with bumps use:
+<pre>
+ gm convert -size 640x480 tile:bumps.jpg tiled.png
+</pre>
+<p>
+To surround an icon with an ornamental border to use with Mosaic(1), use:
+<pre>
+ gm convert -mattecolor "#697B8F" -frame 6x6 bird.jpg
+ icon.png
+</pre>
+<p>
+To create a MNG animation from a DNA molecule sequence, use:
+<pre>
+ gm convert -delay 20 dna.* dna.mng
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="conv-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or <strong>-noop</strong>.
+Some options only affect the decoding of images and others only the encoding.
+The latter can appear after the final group of input images.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-adjoin">-adjoin</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>join images into a single multi-image file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-affine">-affine</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>drawing transform matrix</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-antialias">-antialias</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixel aliasing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-append">-append</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>append a set of images</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details"></a> <i>-asc-cdl &lt;spec&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply ASC CDL color transform</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-auto-orient">-auto-orient</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>orient (rotate) image so it is upright</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-average">-average</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>average a set of images</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-black-threshold">-black-threshold</a> <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels below the threshold become black</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blue-primary">-blue-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blur">-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-border">-border</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with a border of color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-box">-box</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the color of the annotation bounding box</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-channel">-channel</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of channel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -charcoal <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate a charcoal drawing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-chop">-chop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixels from the interior of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-clip">-clip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply the clipping path, if one is present</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-coalesce">-coalesce</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>merge a sequence of images</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorize">-colorize</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colorize the image with the pen color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compose">-compose</a> <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-contrast">-contrast</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enhance or reduce the image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-convolve">-convolve</a> <i>&lt;kernel&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>convolve image with the specified convolution kernel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-cycle">-cycle</a> <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image colormap by amount</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-deconstruct">-deconstruct</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>break down an image sequence into constituent parts</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -despeckle
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>reduce the speckles within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-draw">-draw</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with one or more graphic primitives</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -edge <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>detect edges within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -emboss <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>emboss an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -enhance
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a digital filter to enhance a noisy image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -equalize
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform histogram equalization to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-extent">-extent</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite image on background color canvas image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fill">-fill</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flatten">-flatten</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>flatten a sequence of images</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flip">-flip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flop">-flop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-format">-format</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output formatted image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-frame">-frame</a> <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fuzz">-fuzz</a> <i>&lt;distance&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colors within this Euclidean distance are considered equal</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gaussian">-gaussian</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gravity">-gravity</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-green-primary">-green-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -hald-clut <i>&lt;clut&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a Hald CLUT to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -implode <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>implode image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-intent">-intent</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of rendering intent when managing the image color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-lat">-lat</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;offset&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform local adaptive thresholding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-level">-level</a> <i>&lt;black_point&gt;</i>{<i>,&lt;gamma&gt;</i>}<i></i>{<i>,&lt;white_point&gt;</i>}<i></i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>adjust the level of image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-list">-list</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of list</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-loop">-loop</a> <i>&lt;iterations&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add Netscape loop extension to your GIF animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-map">-map</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>choose a particular set of colors from this image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mask">-mask</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify a clipping mask</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -median <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a median filter to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -minify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>minify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-modulate">-modulate</a> <i>brightness[,saturation[,hue]]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>vary the brightness, saturation, and hue of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-morph">-morph</a> <i>&lt;frames&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>morphs an image sequence</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mosaic">-mosaic</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a mosaic from an image or an image sequence</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-motion-blur">-motion-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+angle</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Simulate motion blur</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noise">-noise</a> <i>&lt;radius|type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add or reduce noise in an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-normalize">-normalize</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform image to span the full range of color values</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-opaque">-opaque</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>change this color to the pen color within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-operator">-operator</a> <i>channel operator rvalue[%]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a mathematical, bitwise, or value operator to an image channel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-ordered-dither">-ordered-dither</a> <i>&lt;channeltype&gt; &lt;NxN&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>ordered dither the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-orient">-orient</a> <i>&lt;orientation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Set the image orientation attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-paint">-paint</a> <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate an oil painting</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pen">-pen</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>(This option has been replaced by the -fill option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -ping
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>efficiently determine image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-preview">-preview</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>image preview type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-process">-process</a> <i>&lt;command&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>process a sequence of images using a process module</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-profile">-profile</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add ICM, IPTC, or generic profile to image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-raise">-raise</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>lighten or darken image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-random-threshold">-random-threshold</a> <i>&lt;channeltype&gt; &lt;LOWxHIGH&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>random threshold the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-recolor">-recolor</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a color translation matrix to image channels</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-red-primary">-red-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-region">-region</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply options to a portion of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-render">-render</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-repage">-repage</a> <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resample">-resample</a> <i>&lt;horizontal&gt;x&lt;vertical&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Resample image to specified horizontal and vertical resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-roll">-roll</a> <i></i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>roll an image vertically or horizontally</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sample">-sample</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale image using pixel sampling</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scale">-scale</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scene">-scene</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-segment">-segment</a> <i>&lt;cluster threshold&gt;x&lt;smoothing threshold&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>segment an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shade">-shade</a> <i>&lt;azimuth&gt;x&lt;elevation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shade the image using a distant light source</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shave">-shave</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shave pixels from the image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shear">-shear</a> <i>&lt;x degrees&gt;x&lt;y degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shear the image along the X or Y axis</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-solarize">-solarize</a> <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>negate all pixels above the threshold level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-spread">-spread</a> <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image pixels by a random amount</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strip">-strip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stroke">-stroke</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when stroking a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strokewidth">-strokewidth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the stroke width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-swirl">-swirl</a> <i>&lt;degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>swirl image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-threshold">-threshold</a> <i>&lt;value&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>threshold the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tile image when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transform">-transform</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transparent">-transparent</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-units">-units</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the units of image resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-unsharp">-unsharp</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+&lt;amount&gt;</i>}<i></i>{<i>+&lt;threshold&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image with an unsharp mask operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -use-pixmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use the pixmap</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -view <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>FlashPix viewing parameters</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-virtual-pixel">-virtual-pixel</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify contents of "virtual pixels"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-wave">-wave</a> <i>&lt;amplitude&gt;x&lt;wavelength&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>alter an image along a sine wave</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-point">-white-point</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-threshold">-white-threshold</a> <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels above the threshold become white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-write">-write</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write an intermediate image [<em>convert, composite</em>]</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="display"></a>gm display
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Display is a machine architecture independent
+image processing and display program. It can display an image on any workstation
+screen running an X server. <strong>Display</strong> can read and write
+<strong>many</strong>
+of the more popular image <a href="formats.html">formats</a> (e.g. <strong>JPEG</strong>,
+<strong>TIFF</strong>,
+<strong>PNM</strong>,
+<strong>Photo
+CD</strong>, etc.).
+<p>
+With <strong>display</strong>, you can perform these functions on an image:
+<dl>
+<dd><img SRC="images/ball.png" ALT="*">load an image from a file
+<dd><img SRC="images/ball.png" ALT="*">display the next image
+<dd><img SRC="images/ball.png" ALT="*">display the former image
+<dd><img SRC="images/ball.png" ALT="*">display a sequence of images as a slide show
+<dd><img SRC="images/ball.png" ALT="*">write the image to a file
+<dd><img SRC="images/ball.png" ALT="*">print the image to a <em>PostScript</em> printer
+<dd><img SRC="images/ball.png" ALT="*">delete the image file
+<dd><img SRC="images/ball.png" ALT="*">create a Visual Image Directory
+<dd><img SRC="images/ball.png" ALT="*">select the image to display by its thumbnail rather than name
+<dd><img SRC="images/ball.png" ALT="*">undo last image transformation
+<dd><img SRC="images/ball.png" ALT="*">copy a region of the image
+<dd><img SRC="images/ball.png" ALT="*">paste a region to the image
+<dd><img SRC="images/ball.png" ALT="*">restore the image to its original size
+<dd><img SRC="images/ball.png" ALT="*">refresh the image
+<dd><img SRC="images/ball.png" ALT="*">half the image size
+<dd><img SRC="images/ball.png" ALT="*">double the image size
+<dd><img SRC="images/ball.png" ALT="*">resize the image
+<dd><img SRC="images/ball.png" ALT="*">crop the image
+<dd><img SRC="images/ball.png" ALT="*">cut the image
+<dd><img SRC="images/ball.png" ALT="*">flop image in the horizontal direction
+<dd><img SRC="images/ball.png" ALT="*">flip image in the vertical direction
+<dd><img SRC="images/ball.png" ALT="*">rotate the image 90 degrees clockwise
+<dd><img SRC="images/ball.png" ALT="*">rotate the image 90 degrees counter-clockwise
+<dd><img SRC="images/ball.png" ALT="*">rotate the image
+<dd><img SRC="images/ball.png" ALT="*">shear the image
+<dd><img SRC="images/ball.png" ALT="*">roll the image
+<dd><img SRC="images/ball.png" ALT="*">trim the image edges
+<dd><img SRC="images/ball.png" ALT="*">invert the colors of the image
+<dd><img SRC="images/ball.png" ALT="*">vary the color brightness
+<dd><img SRC="images/ball.png" ALT="*">vary the color saturation
+<dd><img SRC="images/ball.png" ALT="*">vary the image hue
+<dd><img SRC="images/ball.png" ALT="*">gamma correct the image
+<dd><img SRC="images/ball.png" ALT="*">sharpen the image contrast
+<dd><img SRC="images/ball.png" ALT="*">dull the image contrast
+<dd><img SRC="images/ball.png" ALT="*">perform histogram equalization on the image
+<dd><img SRC="images/ball.png" ALT="*">perform histogram normalization on the image
+<dd><img SRC="images/ball.png" ALT="*">negate the image colors
+<dd><img SRC="images/ball.png" ALT="*">convert the image to grayscale
+<dd><img SRC="images/ball.png" ALT="*">set the maximum number of unique colors in the image
+<dd><img SRC="images/ball.png" ALT="*">reduce the speckles within an image
+<dd><img SRC="images/ball.png" ALT="*">eliminate peak noise from an image
+<dd><img SRC="images/ball.png" ALT="*">detect edges within the image
+<dd><img SRC="images/ball.png" ALT="*">emboss an image
+<dd><img SRC="images/ball.png" ALT="*">segment the image by color
+<dd><img SRC="images/ball.png" ALT="*">simulate an oil painting
+<dd><img SRC="images/ball.png" ALT="*">simulate a charcoal drawing
+<dd><img SRC="images/ball.png" ALT="*">annotate the image with text
+<dd><img SRC="images/ball.png" ALT="*">draw on the image
+<dd><img SRC="images/ball.png" ALT="*">edit an image pixel color
+<dd><img SRC="images/ball.png" ALT="*">edit the image matte information
+<dd><img SRC="images/ball.png" ALT="*">composite an image with another
+<dd><img SRC="images/ball.png" ALT="*">add a border to the image
+<dd><img SRC="images/ball.png" ALT="*">surround image with an ornamental border
+<dd><img SRC="images/ball.png" ALT="*">apply image processing techniques to a region of interest
+<dd><img SRC="images/ball.png" ALT="*">display information about the image
+<dd><img SRC="images/ball.png" ALT="*">zoom a portion of the image
+<dd><img SRC="images/ball.png" ALT="*">show a histogram of the image
+<dd><img SRC="images/ball.png" ALT="*">display image to background of a window
+<dd><img SRC="images/ball.png" ALT="*">set user preferences
+<dd><img SRC="images/ball.png" ALT="*">display information about this program
+<dd><img SRC="images/ball.png" ALT="*">discard all images and exit program
+<dd><img SRC="images/ball.png" ALT="*">change the level of magnification
+<dd><img SRC="images/ball.png" ALT="*">display images specified by a World Wide Web (WWW) uniform resource locator (URL)
+</dl>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To scale an image of a cockatoo to exactly 640 pixels in width and 480
+pixels in height and position the window at location (200,200), use:
+<pre>
+ gm display -geometry 640x480+200+200! cockatoo.miff
+</pre>
+<p>
+To display an image of a cockatoo without a border centered on a backdrop,
+use:
+<pre>
+ gm display +borderwidth -backdrop cockatoo.miff
+</pre>
+<p>
+To tile a slate texture onto the root window, use:
+<pre>
+ gm display -size 1280x1024 -window root slate.png
+</pre>
+<p>
+To display a visual image directory of all your JPEG images, use:
+<pre>
+ gm display 'vid:*.jpg'
+</pre>
+<p>
+To display a MAP image that is 640 pixels in width and 480 pixels in height
+with 256 colors, use:
+<pre>
+ gm display -size 640x480+256 cockatoo.map
+</pre>
+<p>
+To display an image of a cockatoo specified with a <strong>World Wide Web (WWW)</strong>
+uniform resource locator <strong>(URL)</strong>, use:
+<pre>
+ gm display ftp://wizards.dupont.com/images/cockatoo.jpg
+</pre>
+<p>
+To display histogram of an image, use:
+<pre>
+ gm gm convert file.jpg HISTOGRAM:- | gm display -
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect. For example to display three images,
+the first with 32 colors, the second with an unlimited number of colors,
+and the third with only 16 colors, use:
+<pre>
+ gm display -colors 32 cockatoo.miff -noop duck.miff
+ -colors 16 macaw.miff
+</pre>
+<p>
+<strong>Display</strong> options can appear on the command line or in your X resources
+file. See <em>X(1)</em>. Options on the command line supersede values specified
+in your X resources file.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-backdrop">-backdrop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the image centered on a backdrop.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-border">-border</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with a border of color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -borderwidth <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colormap">-colormap</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the colormap type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-contrast">-contrast</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enhance or reduce the image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -despeckle
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>reduce the speckles within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -edge <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>detect edges within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -enhance
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a digital filter to enhance a noisy image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flip">-flip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flop">-flop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-foreground">-foreground</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>define the foreground color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-frame">-frame</a> <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-iconGeometry">-iconGeometry</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the icon geometry</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -iconic
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>iconic animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -immutable
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image immutable</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-map">-map</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display image using this type.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -name
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+progress">+progress</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>disable progress monitor and busy cursor</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-raise">-raise</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>lighten or darken image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-remote">-remote</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform a X11 remote operation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-roll">-roll</a> <i></i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>roll an image vertically or horizontally</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sample">-sample</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale image using pixel sampling</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scenes">-scenes</a> <i>&lt;value-value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>range of image scene numbers to read</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-segment">-segment</a> <i>&lt;cluster threshold&gt;x&lt;smoothing threshold&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>segment an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shared-memory">-shared-memory</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use shared memory</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-text-font">-text-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>font for writing fixed-width text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-title">-title</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign title to displayed image [<em>animate, display, montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-update">-update</a> <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+detect when image file is modified and redisplay.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -use-pixmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use the pixmap</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-visual">-visual</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>animate images using this X visual type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-window">-window</a> <i>&lt;id&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make image the background of a window</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -window-group
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the window group</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-write">-write</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>write the image to a file [<em>display</em>]</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-mous"></a>Mouse Buttons
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The effects of each button press is described below. Three buttons are
+required. If you have a two button mouse, button 1 and 3 are returned.
+Press <strong>ALT</strong> and button 3 to simulate button 2.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ 1
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Press this button to map or unmap the <a href="#disp-comm">Command
+widget</a> . See the next section for more information about the Command
+widget.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ 2
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Press and drag to define a region of the image to magnify.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ 3
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Press and drag to choose from a select set of <strong>display(1)</strong>
+commands. This button behaves differently if the image being displayed
+is a visual image directory. Choose a particular tile of the directory
+and press this button and drag to select a command from a pop-up menu.
+Choose from these menu items:</td></tr></table>
+<ul>
+<li>Open
+<li>Next
+<li>Former
+<li>Delete
+<li>Update
+</ul>
+<p>
+If you choose <strong>Open</strong>, the image represented by the tile is displayed.
+To return to the visual image directory, choose <strong>Next</strong> from the Command
+widget (refer to <a href="#disp-comm">Command Widget</a>).
+<strong>Next</strong> and <strong>Former</strong>
+moves to the next or former image respectively. Choose <strong>Delete</strong> to
+delete a particular image tile. Finally, choose <strong>Update</strong> to synchronize
+all the image tiles with their respective images. See
+<a href="montage.html">montage</a>
+and
+<a href="miff.html">miff</a> for more details.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-comm"></a>Command Widget
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+The Command widget lists a number of sub-menus and commands. They are
+<ul>
+<li><strong>File</strong>
+<ul>
+<li>Open...
+<li>Next
+<li>Former
+<li>Select...
+<li>Save...
+<li>Print...
+<li>Delete...
+<li>Canvas...
+<li>Visual Directory...
+<li>Quit
+</ul>
+</ul>
+<ul>
+<li><strong>Edit</strong>
+<ul>
+<li>Undo
+<li>Redo
+<li>Cut
+<li>Copy
+<li>Paste
+</ul>
+</ul>
+<ul>
+<li><strong>View</strong>
+<ul>
+<li>Half Size
+<li>Original Size
+<li>Double Size
+<li>Resize...
+<li>Apply
+<li>Refresh
+<li>Restore
+</ul>
+</ul>
+<ul>
+<li><strong>Transform</strong>
+<ul>
+<li>Crop
+<li>Chop
+<li>Flop
+<li>Flip
+<li>Rotate Right
+<li>Rotate Left
+<li>Rotate...
+<li>Shear...
+<li>Roll...
+<li>Trim Edges
+</ul>
+</ul>
+<ul>
+<li><strong>Enhance</strong>
+<ul>
+<li>Hue...
+<li>Saturation...
+<li>Brightness...
+<li>Gamma...
+<li>Spiff...
+<li>Dull
+<li>Equalize
+<li>Normalize
+<li>Negate
+<li>GRAYscale
+<li>Quantize...
+</ul>
+</ul>
+<ul>
+<li><strong>Effects</strong>
+<ul>
+<li>Despeckle
+<li>Emboss
+<li>Reduce Noise
+<li>Add Noise
+<li>Sharpen...
+<li>Blur...
+<li>Threshold...
+<li>Edge Detect...
+<li>Spread...
+<li>Shade...
+<li>Raise...
+<li>Segment...
+</ul>
+</ul>
+<ul>
+<li><strong>F/X</strong>
+<ul>
+<li>Solarize...
+<li>Swirl...
+<li>Implode...
+<li>Wave...
+<li>Oil Paint...
+<li>Charcoal Draw...
+</ul>
+</ul>
+<ul>
+<li><strong>Image Edit</strong>
+<ul>
+<li>Annotate...
+<li>Draw...
+<li>Color...
+<li>Matte...
+<li>Composite...
+<li>Add Border...
+<li>Add Frame...
+<li>Comment...
+<li>Launch...
+<li>Region of Interest...
+</ul>
+</ul>
+<ul>
+<li><strong>Miscellany</strong>
+<ul>
+<li>Image Info
+<li>Zoom Image
+<li>Show Preview...
+<li>Show Histogram
+<li>Show Matte
+<li>Background...
+<li>Slide Show
+<li>Preferences...
+</ul>
+</ul>
+<ul>
+<li><strong>Help</strong>
+<ul>
+<li>Overview
+<li>Browse Documentation
+<li>About Display
+</ul>
+</ul>
+<p>
+Menu items with a indented triangle have a sub-menu. They are represented
+above as the indented items. To access a sub-menu item, move the pointer
+to the appropriate menu and press button 1 and drag. When you find the
+desired sub-menu item, release the button and the command is executed.
+Move the pointer away from the sub-menu if you decide not to execute a
+particular command.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-keyb"></a>Keyboard Accelerators
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Accelerators are one or two key presses that effect a particular command.
+The keyboard accelerators that
+<strong>display</strong> understands is:
+<pre>
+ Ctl+O Press to <a href="#disp-imlo">load</a> an image from a file.
+ space Press to display the next image.
+</pre>
+<p>
+If the image is a multi-paged document such as a
+<em>PostScript</em> document,
+you can skip ahead several pages by preceding this command with a number.
+For example to display the fourth page beyond the current page,
+press <tt>4space</tt>.
+<pre>
+ backspace Press to display the former image.
+</pre>
+<p>
+If the image is a multi-paged document such as a
+<em>PostScript</em> document,
+you can skip behind several pages by preceding this command with a number.
+For example to display the fourth page preceding the current page, press
+4n.
+<pre>
+ Ctl-S Press to save the image to a file.
+ Ctl-P Press to print the image to a
+ <em>PostScript</em> printer.
+ Ctl-D Press to delete an image file.
+ Ctl-N Press to create a blank canvas.
+ Ctl-Q Press to discard all images and exit program.
+ Ctl+Z Press to undo last image transformation.
+ Ctl+R Press to redo last image transformation.
+ Ctl-X Press to <a href="#disp-imcu">cut</a> a region of
+ the image.
+ Ctl-C Press to <a href="#disp-imco">copy</a> a region of
+ the image.
+ Ctl-V Press to <a href="#disp-impa">paste</a> a region to
+ the image.
+ &lt; Press to halve the image size.
+ . Press to return to the original image size.
+ &gt; Press to double the image size.
+ % Press to resize the image to a width and height
+ you specify.
+ Cmd-A Press to make any image transformations
+ permanent.
+ By default, any image size transformations are
+ applied to the original image to create the
+ image displayed on the X server. However, the
+ transformations are not permanent (i.e. the
+ original image does not change size only the
+ X image does). For example, if you press "&gt;"
+ the X image will appear to double in size, but
+ the original image will in fact remain the same
+ size. To force the original image to double in
+ size, press "&gt;" followed by "Cmd-A".
+ @ Press to refresh the image window.
+ C Press to <a href="#disp-imcr">crop</a> the image.
+ [ Press to <a href="#disp-imch">chop</a> the image.
+ H Press to flop image in the horizontal direction.
+ V Press to flip image in the vertical direction.
+ / Press to rotate the image 90 degrees clockwise.
+ \ Press to rotate the image 90 degrees
+ counter-clockwise.
+ * Press to <a href="#disp-imro">rotate</a> the image
+ the number of degrees you specify.
+ S Press to shear the image the number of degrees
+ you specify.
+ R Press to roll the image.
+ T Press to trim the image edges.
+ Shft-H Press to vary the color hue.
+ Shft-S Press to vary the color saturation.
+ Shft-L Press to vary the image brightness.
+ Shft-G Press to gamma correct the image.
+ Shft-C Press to spiff up the image contrast.
+ Shft-Z Press to dull the image contrast.
+ = Press to perform histogram equalization on
+ the image.
+ Shft-N Press to perform histogram normalization on
+ the image.
+ Shft-~ Press to negate the colors of the image.
+ . Press to convert the image colors to gray.
+ Shft-# Press to set the maximum number of unique
+ colors in the image.
+ F2 Press to reduce the speckles in an image.
+ F2 Press to emboss an image.
+ F4 Press to eliminate peak noise from an image.
+ F5 Press to add noise to an image.
+ F6 Press to sharpen an image.
+ F7 Press to blur image an image.
+ F8 Press to threshold the image.
+ F9 Press to detect edges within an image.
+ F10 Press to displace pixels by a random amount.
+ F11 Press to shade the image using a distant light
+ source.
+ F12 Press to lighten or darken image edges to
+ create a 3-D effect.
+ F13 Press to segment the image by color.
+ Meta-S Press to swirl image pixels about the center.
+ Meta-I Press to implode image pixels about the center.
+ Meta-W Press to alter an image along a sine wave.
+ Meta-P Press to simulate an oil painting.
+ Meta-C Press to simulate a charcoal drawing.
+ Alt-X Press to <a href="#disp-imcomp">composite</a> the image
+ with another.
+ Alt-A Press to <a href="#disp-iman">annotate</a> the image with text.
+ Alt-D Press to <a href="#disp-imdr">draw</a> a line on the image.
+ Alt-P Press to <a href="#disp-cole">edit an image pixel color</a>.
+ Alt-M Press to <a href="#disp-matt">edit the image matte</a> information.
+ Alt-X Press to <a href="#disp-imcomp">composite</a> the image with another.
+ Alt-A Press to add a border to the image.
+ Alt-F Press to add a ornamental frame to the image.
+ Alt-Shft-! Press to add an image comment.
+ Ctl-A Press to apply image processing techniques to a
+ region of interest.
+ Shft-? Press to display information about the image.
+ Shft-+ Press to map the zoom image window.
+ Shft-P Press to preview an image enhancement, effect,
+ or f/x.
+ F1 Press to display helpful information about
+ the "display" utility.
+ Find Press to browse documentation about
+ GraphicsMagick.
+ 1-9 Press to change the level of magnification.
+</pre>
+<p>
+Use the arrow keys to move the image one pixel up, down, left, or right
+within the magnify window. Be sure to first map the magnify window by pressing
+button 2.
+<p>
+Press ALT and one of the arrow keys to trim off one pixel from any side
+of the image.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-xres"></a>X Resources
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Display</strong> options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See <em>X(1)</em> for more information on X resources.
+<p>
+Most <strong>display</strong> options have a corresponding X resource. In addition,
+<strong>display</strong>
+uses the following X resources:
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ background <i>(class Background)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred color to use for the Image window background. The
+default is #ccc.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ borderColor <i>(class BorderColor)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred color to use for the Image window border. The default
+is #ccc.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ borderWidth <i>(class BorderWidth)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the width in pixels of the image window border. The default is
+2.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ browseCommand <i>(class browseCommand)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the name of the preferred browser when displaying GraphicsMagick
+documentation. The default is <tt>netscape %s</tt>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ confirmExit <i>(class ConfirmExit)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+<strong>Display</strong> pops up a dialog box to confirm exiting the program when
+exiting the program. Set this resource to <tt>False</tt> to exit without
+a confirmation.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ displayGamma <i>(class DisplayGamma)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the gamma of the X server.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+You can apply separate gamma values to the red, green, and blue channels
+of the image with a gamma value list delineated with slashes (i.e. 1.7/2.3/1.2).</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The default is 2.2.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ displayWarnings <i>(class DisplayWarnings)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+<strong>Display</strong> pops up a dialog box whenever a warning message occurs.
+Set this resource to <tt>False</tt> to ignore warning messages.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ font <i>(class FontList)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the name of the preferred font to use in normal formatted text.
+The default is 14 point Helvetica.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ font[1-9] <i>(class Font[1-9])</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the name of the preferred font to use when
+<a href="#disp-iman">annotating</a>
+the image window with text. The default fonts are fixed, variable, 5x8,
+6x10, 7x13bold, 8x13bold, 9x15bold, 10x20, and 12x24.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ foreground <i>(class Foreground)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred color to use for text within the image window.
+The default is black.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ gammaCorrect <i>(class gammaCorrect)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource, if true, will lighten or darken an image of known gamma
+to match the gamma of the display (see resource <strong>displayGamma</strong>). The
+default is True.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ geometry <i>(class Geometry)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred size and position of the image window. It is not
+necessarily obeyed by all window managers.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Offsets, if present, are handled in <em>X(1)</em> style. A negative x offset is
+measured from the right edge of the screen to the right edge of the icon,
+and a negative y offset is measured from the bottom edge of the screen
+to the bottom edge of the icon.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ iconGeometry <i>(class IconGeometry)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the preferred size and position of the application when iconified.
+It is not necessarily obeyed by all window managers.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+Offsets, if present, are handled in the same manner as in class Geometry.</font></td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ iconic <i>(class Iconic)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource indicates that you would prefer that the application's windows
+initially not be visible as if the windows had be immediately iconified
+by you. Window managers may choose not to honor the application's request.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ magnify <i>(class Magnify)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+specifies an integral factor by which the image should be enlarged. The
+default is 3.</td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This value only affects the magnification window which is invoked with
+<a href="#disp-mous">button</a>
+number 3 after the image is displayed.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ matteColor <i>(class MatteColor)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specify the color of windows. It is used for the backgrounds of windows,
+menus, and notices. A 3D effect is achieved by using highlight and shadow
+colors derived from this color. Default value: #697B8F.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ name <i>(class Name)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource specifies the name under which resources for the application
+should be found. This resource is useful in shell aliases to distinguish
+between invocations of an application, without resorting to creating links
+to alter the executable file name. The default is the application name.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ pen[1-9] <i>(class Pen[1-9])</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the color of the preferred font to use when
+<a href="#disp-iman">annotating</a>
+the image window with text. The default colors are black, blue, green,
+cyan, gray, red, magenta, yellow, and white.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ printCommand <i>(class PrintCommand)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This command is executed whenever Print is issued. In general, it is the
+command to print <em>PostScript</em> to your printer. Default value: <tt>lp
+-c -s %i</tt>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ sharedMemory <i>(class SharedMemory)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource specifies whether display should attempt use shared memory
+for pixmaps. GraphicsMagick must be compiled with shared memory support,
+and the display must support the MIT-SHM extension. Otherwise, this
+resource is ignored. The default is True.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ textFont <i>(class textFont)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies the name of the preferred font to use in fixed (typewriter style)
+formatted text. The default is 14 point Courier.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ title <i>(class Title)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+This resource specifies the title to be used for the image window. This
+information is sometimes used by a window manager to provide a header identifying
+the window. The default is the image file name.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ undoCache <i>(class UndoCache)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Specifies, in mega-bytes, the amount of memory in the undo edit cache.
+Each time you modify the image it is saved in the undo edit cache as long
+as memory is available. You can subsequently <em>undo</em> one or more of
+these transformations. The default is 16 Megabytes.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ usePixmap <i>(class UsePixmap)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+Images are maintained as a XImage by default. Set this resource to True
+to utilize a server Pixmap instead. This option is useful if your image
+exceeds the dimensions of your server screen and you intend to pan the
+image. Panning is much faster with Pixmaps than with a XImage. Pixmaps
+are considered a precious resource, use them with discretion.</td></tr></table>
+<p>
+To set the geometry of the Magnify or Pan or window, use the geometry resource.
+For example, to set the Pan window geometry to 256x256, use:
+<pre>
+ gm display.pan.geometry: 256x256
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imlo"></a>Image Loading
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To select an image to display, choose <strong>Open</strong> of the <strong>File</strong> sub-menu
+from the <a href="#disp-comm">Command widget</a>. A file browser is displayed.
+To choose a particular image file, move the pointer to the filename and
+press any button. The filename is copied to the text window. Next, press
+<strong>Open</strong>
+or press the <strong>RETURN</strong> key. Alternatively, you can type the image file
+name directly into the text window. To descend directories, choose a directory
+name and press the button twice quickly. A scrollbar allows a large list
+of filenames to be moved through the viewing area if it exceeds the size
+of the list area.
+<p>
+You can trim the list of file names by using shell globbing characters.
+For example, type <tt>*.jpg</tt> to list only files that end
+with <tt>.jpg</tt>.
+<p>
+To select your image from the X server screen instead of from a file, Choose
+<strong>Grab</strong> of the <strong>Open</strong> widget.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-visu"></a>Visual Image Directory
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To create a Visual Image Directory, choose Visual Directory of the <strong>File</strong>
+sub-menu from the <a href="#disp-comm">Command widget</a> . A file browser is
+displayed. To create a Visual Image Directory from all the images in the
+current directory, press <strong>Directory</strong> or press the <strong>RETURN key</strong>.
+Alternatively, you can select a set of image names by using shell globbing
+characters. For example, type <tt>*.jpg</tt> to include only files that
+end with <tt>.jpg</tt>. To descend directories, choose a directory name
+and press the button twice quickly. A scrollbar allows a large list of
+filenames to be moved through the viewing area if it exceeds the size of
+the list area.
+<p>
+After you select a set of files, they are turned into thumbnails and tiled
+onto a single image. Now move the pointer to a particular thumbnail and
+press <strong>button 3</strong> and drag. Finally, select Open. The image represented
+by the thumbnail is displayed at its full size. Choose <strong>Next</strong> from
+the <strong>File</strong> sub-menu of the Command widget to return to the Visual
+Image Directory.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imcu"></a>Image Cutting
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Note that cut information for image window is not retained for colormapped
+X server visuals (e.g. <em>StaticColor</em>,
+<em>StaticColor</em>, <em>GRAYScale</em>,
+<em>PseudoColor</em>).
+Correct cutting behavior may require a <em>TrueColor</em> or <em>DirectColor</em>
+visual or a <em>Standard Colormap</em>.
+<p>
+To begin, press choose <strong>Cut</strong> of the <strong>Edit</strong> sub-menu from the
+<a href="#disp-comm">Command
+widget</a>. Alternatively, press
+<strong>F3</strong> in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in cut mode. In cut mode, the Command widget has these
+options:
+<ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+To define a cut region, press button 1 and drag. The cut region is defined
+by a highlighted rectangle that expands or contracts as it follows the
+pointer. Once you are satisfied with the cut region, release the button.
+You are now in rectify mode. In rectify mode, the Command widget has these
+options:
+<ul>
+<li><strong>Cut</strong>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+You can make adjustments by moving the pointer to one of the cut rectangle
+corners, pressing a button, and dragging. Finally, press Cut to commit
+your copy region. To exit without cutting the image, press Dismiss.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imco"></a>Image Copying
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To begin, press choose <strong>Copy</strong> of the <strong>Edit</strong> sub-menu from the
+<a href="#disp-comm">Command
+widget</a>. Alternatively, press
+<strong>F4</strong> in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in copy mode. In copy mode, the Command widget has
+these options:
+<ul>
+<li>Help
+<li>Dismiss
+</ul>
+<p>
+To define a copy region, press button 1 and drag. The copy region is defined
+by a highlighted rectangle that expands or contracts as it follows the
+pointer. Once you are satisfied with the copy region, release the button.
+You are now in rectify mode. In rectify mode, the Command widget has these
+options:
+<ul>
+<li>Copy
+<li>Help
+<li>Dismiss
+</ul>
+<p>
+You can make adjustments by moving the pointer to one of the copy rectangle
+corners, pressing a button, and dragging. Finally, press Copy to commit
+your copy region. To exit without copying the image, press Dismiss.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-impas"></a>Image Pasting
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To begin, press choose <strong>Paste</strong> of the <strong>Edit</strong> sub-menu from the
+<a href="#disp-comm">Command
+widget</a>. Alternatively, press
+<strong>F5</strong> in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in Paste mode. To exit immediately, press Dismiss.
+In Paste mode, the Command widget has these options:
+<ul>
+<li><strong>Operators</strong>
+<ul>
+<li>over
+<li>in
+<li>out
+<li>atop
+<li>xor
+<li>plus
+<li>minus
+<li>add
+<li>subtract
+<li>difference
+<li>multiply
+<li>bumpmap
+<li>replace
+</ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+Choose a composite operation from the <strong>Operators</strong> sub-menu of the
+<a href="#disp-comm">Command
+widget</a>. How each operator behaves is described below. <em>image window</em>
+is the image currently displayed on your X server and <em>image</em> is the
+image obtained with the File Browser widget.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ over
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the union of the two image shapes, with <em>image</em> obscuring
+<em>image
+window</em> in the region of overlap.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ in
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is simply <em>image</em> cut by the shape of
+<em>image window</em>.
+None of the image data of image window is in the result.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ out
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The resulting image is <em>image</em> with the shape of
+<em>image window</em>
+cut out.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ atop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the same shape as <em>image window</em>, with
+<em>image</em>
+obscuring <em>image window</em> where the image shapes overlap. Note this
+differs from over because the portion of image outside
+<em>image window</em>'s
+shape does not appear in the result.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ xor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the image data from both <em>image</em> and
+<em>image window</em>
+that is outside the overlap region. The overlap region is blank.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ plus
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is just the sum of the image data. Output values are cropped
+to the maximum value (no overflow). This operation is independent of the
+matte channels.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ minus
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> - <em>image window</em>, with underflow cropped
+to zero. The matte channel is ignored (set to opaque, full coverage).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ add
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> + <em>image window</em>, with overflow wrapping
+around (mod MaxRGB+1).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ subtract
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> - <em>image window</em>, with underflow wrapping
+around (mod MaxRGB+1). The add and subtract operators can be used to perform
+reversible transformations.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ difference
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of abs(<em>image</em> - <em>image window</em>). This is useful for
+comparing two very similar images.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ multiply
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> * <em>image window</em>. This is useful for
+the creation of drop-shadows.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ bumpmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image window</em> shaded by <em>window</em>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ replace
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>The resulting image is <em>image window</em> replaced with
+<em>image</em>.
+Here the matte information is ignored.</td></tr></table>
+<p>
+The image compositor requires a matte, or alpha channel in the image for
+some operations. This extra channel usually defines a mask which represents
+a sort of a cookie-cutter for the image. This is the case when matte is
+255 (full coverage) for pixels inside the shape, zero outside, and between
+zero and 255 on the boundary. If image does not have a matte channel, it
+is initialized with 0 for any pixel matching in color to pixel location
+(0,0), otherwise 255. See <a href="#disp-matt">Matte Editing</a> for a method
+of defining a matte channel.
+<p>
+Note that matte information for image window is not retained for colormapped
+X server visuals (e.g. <em>StaticColor, StaticColor, GrayScale, PseudoColor</em>).
+Correct compositing behavior may require a
+<em>TrueColor</em> or <em>DirectColor</em>
+visual or a <em>Standard Colormap</em>.
+<p>
+Choosing a composite operator is optional. The default operator is replace.
+However, you must choose a location to composite your image and press button
+1. Press and hold the button before releasing and an outline of the image
+will appear to help you identify your location.
+<p>
+The actual colors of the pasted image is saved. However, the color that
+appears in image window may be different. For example, on a monochrome
+screen image window will appear black or white even though your pasted
+image may have many colors. If the image is saved to a file it is written
+with the correct colors. To assure the correct colors are saved in the
+final image, any <em>PseudoClass</em> image is promoted to <em>DirectClass</em>.
+To force a
+<em>PseudoClass</em> image to remain <em>PseudoClass</em>,
+use <strong>-colors</strong>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imcr"></a>Image Cropping
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To begin, press choose <strong>Crop</strong> of the <strong>Transform</strong> submenu from
+the <a href="#disp-comm">Command widget</a>. Alternatively,
+<a href="#disp-keyb">press</a> C in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in crop mode. In crop mode, the Command widget has
+these options:
+<ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+To define a cropping region, press button 1 and drag. The cropping region
+is defined by a highlighted rectangle that expands or contracts as it follows
+the pointer. Once you are satisfied with the cropping region, release the
+button. You are now in rectify mode. In rectify mode, the Command widget
+has these options:
+<ul>
+<li><strong>Crop</strong>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+You can make adjustments by moving the pointer to one of the cropping rectangle
+corners, pressing a button, and dragging. Finally, press Crop to commit
+your cropping region. To exit without cropping the image, press Dismiss.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imch"></a>Image Chopping
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+An image is chopped interactively. There is no command line argument to
+chop an image. To begin, choose <strong>Chop</strong> of the <strong>Transform</strong> sub-menu
+from the <a href="#disp-comm">Command widget</a>. Alternatively,
+<a href="#disp-keyb">press</a> [ in the Image window.
+<p>
+You are now in <strong>Chop</strong> mode. To exit immediately, press
+<strong>Dismiss</strong>.
+In Chop mode, the Command widget has these options:
+<ul>
+<li><strong>Direction</strong>
+<ul>
+<li>horizontal
+<li>vertical
+</ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+If the you choose the horizontal direction (this is the default), the area
+of the image between the two horizontal endpoints of the chop line is removed.
+Otherwise, the area of the image between the two vertical endpoints of
+the chop line is removed.
+<p>
+Select a location within the image window to begin your chop, press and
+hold any button. Next, move the pointer to another location in the image.
+As you move a line will connect the initial location and the pointer. When
+you release the button, the area within the image to chop is determined
+by which direction you choose from the Command widget.
+<p>
+To cancel the image chopping, move the pointer back to the starting point
+of the line and release the button.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imro"></a>Image Rotation
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Press the / key to rotate the image 90 degrees or \ to rotate -90 degrees.
+To interactively choose the degree of rotation, choose
+<strong>Rotate...</strong>
+of the <strong>Transform</strong> submenu from the <a href="#disp-comm">Command Widget</a>.
+Alternatively, <a href="#disp-keyb">press</a> * in the image window.
+<p>
+A small horizontal line is drawn next to the pointer. You are now in rotate
+mode. To exit immediately, press Dismiss. In rotate mode, the Command widget
+has these options:
+<ul>
+<li><strong>Pixel Color</strong>
+<ul>
+<li>black
+<li>blue
+<li>cyan
+<li>green
+<li>gray
+<li>red
+<li>magenta
+<li>yellow
+<li>white
+<li>Browser...
+</ul>
+<li><strong>Direction</strong>
+<ul>
+<li>horizontal
+<li>vertical
+</ul>
+<li><strong>Help</strong>
+<li><strong>Dismiss</strong>
+</ul>
+<p>
+Choose a background color from the Pixel Color sub-menu. Additional background
+colors can be specified with the color browser. You can change the menu
+colors by setting the <a href="#disp-xres">X resources</a> pen1 through pen9.
+<p>
+If you choose the color browser and press <strong>Grab</strong>, you can select the
+background color by moving the pointer to the desired color on the screen
+and press any button.
+<p>
+Choose a point in the image window and press this button and hold. Next,
+move the pointer to another location in the image. As you move a line connects
+the initial location and the pointer. When you release the button, the
+degree of image rotation is determined by the slope of the line you just
+drew. The slope is relative to the direction you choose from the Direction
+sub-menu of the Command widget.
+<p>
+To cancel the image rotation, move the pointer back to the starting point
+of the line and release the button.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-iman"></a>Image Annotation
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+An image is annotated interactively. There is no command line argument
+to annotate an image. To begin, choose
+<strong>Annotate</strong> of the <strong>Image
+Edit</strong> sub-menu from the <a href="#disp-comm">Command widget</a>. Alternatively,
+<a href="#disp-keyb">press</a> a in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in annotate mode. To exit immediately, press Dismiss.
+In annotate mode, the Command widget has these options:
+<ul>
+<li>
+<strong>Font Name</strong>
+<ul>
+<li>
+fixed
+<li>
+variable
+<li>
+5x8
+<li>
+6x10
+<li>
+7x13bold
+<li>
+8x13bold
+<li>
+9x15bold
+<li>
+10x20
+<li>
+12x24
+<li>
+Browser...
+</ul>
+<li>
+<strong>Font Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+transparent
+<li>
+Browser...
+</ul>
+<li>
+<strong>Box Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+transparent
+<li>
+Browser...
+</ul>
+<li>
+<strong>Rotate Text</strong>
+<ul>
+<li>
+-90
+<li>
+-45
+<li>
+-30
+<li>
+0
+<li>
+30
+<li>
+45
+<li>
+90
+<li>
+180
+<li>
+Dialog...
+</ul>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+Choose a font name from the <strong>Font Name</strong> sub-menu. Additional font
+names can be specified with the font browser. You can change the menu names
+by setting the <a href="#disp-xres">X resources</a> font1 through font9.
+<p>
+Choose a font color from the <strong>Font Color</strong> sub-menu. Additional font
+colors can be specified with the color browser. You can change the menu
+colors by setting the <a href="#disp-xres">X resources</a> pen1 through pen9.
+<p>
+If you select the color browser and press <strong>Grab</strong>, you can choose the
+font color by moving the pointer to the desired color on the screen and
+press any button.
+<p>
+If you choose to rotate the text, choose <strong>Rotate Text</strong> from the menu
+and select an angle. Typically you will only want to rotate one line of
+text at a time. Depending on the angle you choose, subsequent lines may
+end up overwriting each other.
+<p>
+Choosing a font and its color is optional. The default font is fixed and
+the default color is black. However, you must choose a location to begin
+entering text and press a button. An underscore character will appear at
+the location of the pointer. The cursor changes to a pencil to indicate
+you are in text mode. To exit immediately, press Dismiss.
+<p>
+In text mode, any key presses will display the character at the location
+of the underscore and advance the underscore cursor. Enter your text and
+once completed press Apply to finish your image annotation. To correct
+errors press <strong>BACK SPACE</strong>. To delete an entire line of text, press
+<strong>DELETE</strong>.
+Any text that exceeds the boundaries of the image window is automatically
+continued onto the next line.
+<p>
+The actual color you request for the font is saved in the image. However,
+the color that appears in your Image window may be different. For example,
+on a monochrome screen the text will appear black or white even if you
+choose the color red as the font color. However, the image saved to a file
+with <strong>-write</strong> is written with red lettering. To assure the correct
+color text in the final image, any <em>PseudoClass</em> image is promoted
+to <em>DirectClass</em> (see miff(5)). To force a <em>PseudoClass</em> image
+to remain
+<em>PseudoClass</em>, use <strong>-colors</strong>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imcomp"></a>Image Compositing
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+An image composite is created interactively. <strong>There is no command line
+argument to composite an image</strong>. To begin, choose <strong>Composite</strong> of
+the <strong>Image Edit</strong> from the <a href="#disp-comm">Command widget</a>. Alternatively,
+<a href="#disp-keyb">press</a> x in the Image window.
+<p>
+First a popup window is displayed requesting you to enter an image name.
+Press <strong>Composite</strong>, <strong>Grab</strong> or type a file name. Press <strong>Cancel</strong>
+if you choose not to create a composite image. When you choose <strong>Grab</strong>,
+move the pointer to the desired window and press any button.
+<p>
+If the <strong>Composite</strong> image does not have any matte information, you
+are informed and the file browser is displayed again. Enter the name of
+a mask image. The image is typically grayscale and the same size as the
+composite image. If the image is not grayscale, it is converted to grayscale
+and the resulting intensities are used as matte information.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in composite mode. To exit immediately, press Dismiss.
+In composite mode, the Command widget has these options:
+<ul>
+<li>
+<strong>Operators</strong>
+<ul>
+<li>
+over
+<li>
+in
+<li>
+out
+<li>
+atop
+<li>
+xor
+<li>
+plus
+<li>
+minus
+<li>
+add
+<li>
+subtract
+<li>
+difference
+<li>
+bumpmap
+<li>
+replace
+</ul>
+<li>
+<strong>Blend</strong>
+<li>
+<strong>Displace</strong>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+Choose a composite operation from the Operators sub-menu of the Command
+widget. How each operator behaves is described below. image window is the
+image currently displayed on your X server and image is the image obtained
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ over
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the union of the two image shapes, with <em>image</em> obscuring
+<em>image
+window</em> in the region of overlap.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ in
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is simply <em>image</em> cut by the shape of
+<em>image window</em>.
+None of the image data of image window is in the result.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ out
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The resulting image is <em>image</em> with the shape of
+<em>image window</em>
+cut out.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ atop
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the same shape as <em>image window</em>, with
+<em>image</em>
+obscuring <em>image window</em> where the image shapes overlap. Note this
+differs from over because the portion of image outside
+<em>image window</em>'s
+shape does not appear in the result.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ xor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is the image data from both <em>image</em> and
+<em>image window</em>
+that is outside the overlap region. The overlap region is blank.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ plus
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result is just the sum of the image data. Output values are cropped
+to 255 (no overflow). This operation is independent of the matte channels.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ minus
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> - <em>image window</em>, with underflow cropped
+to zero. The matte channel is ignored (set to 255, full coverage).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ add
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> + <em>image window</em>, with overflow wrapping
+around (mod 256).</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ subtract
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image</em> - <em>image window</em>, with underflow wrapping
+around (mod 256). The add and subtract operators can be used to perform
+reversible transformations.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ difference
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of abs(<em>image</em> - <em>image window</em>). This is useful for
+comparing two very similar images.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ bumpmap
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The result of <em>image window</em> shaded by <em>window</em>.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ replace
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>
+The resulting image is <em>image window</em> replaced with
+<em>image</em>.
+Here the matte information is ignored.</td></tr></table>
+<p>
+The image compositor requires a matte, or alpha channel in the image for
+some operations. This extra channel usually defines a mask which represents
+a sort of a cookie-cutter for the image. This is the case when matte is
+255 (full coverage) for pixels inside the shape, zero outside, and between
+zero and 255 on the boundary. If image does not have a matte channel, it
+is initialized with 0 for any pixel matching in color to pixel location
+(0,0), otherwise 255. See <a href="#disp-matt">Matte Editing</a> for a method
+of defining a matte channel.
+<p>
+If you choose <strong>blend</strong>, the composite operator becomes <strong>over</strong>.
+The image matte channel percent transparency is initialized to factor.
+The image window is initialized to (100-factor). Where factor is the value
+you specify in the Dialog widget.
+<p>
+<strong>Displace</strong> shifts the image pixels as defined by a displacement map.
+With this option, <em>image</em> is used as a displacement map. Black, within
+the displacement map, is a maximum positive displacement. White is a maximum
+negative displacement and middle gray is neutral. The displacement is scaled
+to determine the pixel shift. By default, the displacement applies in both
+the horizontal and vertical directions. However, if you specify
+<em>mask</em>,
+<em>image</em>
+is the horizontal X displacement and
+<em>mask</em> the vertical Y displacement.
+<p>
+Note that matte information for image window is not retained for colormapped
+X server visuals (e.g.
+<em>StaticColor, StaticColor, GrayScale, PseudoColor</em>).
+Correct compositing behavior may require a <em>TrueColor</em> or
+<em>DirectColor</em>
+visual or a <em>Standard Colormap</em>.
+<p>
+Choosing a composite operator is optional. The default operator is replace.
+However, you must choose a location to composite your image and press button
+1. Press and hold the button before releasing and an outline of the image
+will appear to help you identify your location.
+<p>
+The actual colors of the composite image is saved. However, the color that
+appears in image window may be different. For example, on a monochrome
+screen Image window will appear black or white even though your composited
+image may have many colors. If the image is saved to a file it is written
+with the correct colors. To assure the correct colors are saved in the
+final image, any PseudoClass image is promoted to <em>DirectClass</em> (see
+<a href="miff.html">miff</a>).
+To force a <em>PseudoClass</em> image to remain <em>PseudoClass</em>,
+use <strong>-colors</strong>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-cole"></a>Color Editing
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Changing the the color of a set of pixels is performed interactively. There
+is no command line argument to edit a pixel. To begin, choose <strong>Color</strong>
+from the <strong>Image Edit</strong> submenu of the <a href="#disp-comm">Command widget</a>.
+Alternatively, <a href="#disp-keyb">press</a> c in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in color edit mode. To exit immediately, press <strong>Dismiss</strong>.
+In color edit mode, the
+<strong>Command widget</strong> has these options:
+<ul>
+<li>
+<strong>Method</strong>
+<ul>
+<li>
+point
+<li>
+replace
+<li>
+floodfill
+<li>
+reset
+</ul>
+<li>
+<strong>Pixel Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+Browser...
+</ul>
+<li>
+<strong>Border Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+Browser...
+</ul>
+<li>
+<strong>Fuzz</strong>
+<ul>
+<li>
+0
+<li>
+2
+<li>
+4
+<li>
+8
+<li>
+16
+<li>Dialog...
+</ul>
+<li>
+<strong>Undo</strong>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+Choose a color editing method from the <strong>Method</strong> sub-menu of
+the <a href="#disp-comm">Command
+widget</a>. The <strong>point method</strong> recolors any pixel selected with the
+pointer unless the button is released. The <strong>replace method</strong> recolors
+any pixel that matches the color of the pixel you select with a button
+press. <strong>Floodfill</strong> recolors any pixel that matches the color of the
+pixel you select with a button press and is a neighbor.
+Whereas <strong>filltoborder</strong>
+changes the matte value of any neighbor pixel that is not the border color.
+Finally <strong>reset</strong> changes the entire image to the designated color.
+<p>
+Next, choose a pixel color from the <strong>Pixel Color</strong> sub-menu. Additional
+pixel colors can be specified with the color browser. You can change the
+menu colors by setting the <a href="#disp-xres">X resources</a> pen1 through
+pen9.
+<p>
+Now press button 1 to select a pixel within the Image window to change
+its color. Additional pixels may be recolored as prescribed by the method
+you choose. additional pixels by increasing the Delta value.
+<p>
+If the <strong>Magnify widget</strong> is mapped, it can be helpful in positioning
+your pointer within the image (refer to button 2). Alternatively you can
+select a pixel to recolor from within the <strong>Magnify widget</strong>. Move the
+pointer to the <strong>Magnify widget</strong> and position the pixel with the cursor
+control keys. Finally, press a button to recolor the selected pixel (or
+pixels).
+<p>
+The actual color you request for the pixels is saved in the image. However,
+the color that appears in your Image window may be different. For example,
+on a monochrome screen the pixel will appear black or white even if you
+choose the color red as the pixel color. However, the image saved to a
+file with -write is written with red pixels. To assure the correct color
+text in the final image, any <em>PseudoClass</em> image is promoted
+to <em>DirectClass</em>
+To force a <em>PseudoClass</em> image to remain
+<em>PseudoClass</em>, use <strong>-colors</strong>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-matt"></a>Matte Editing
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Matte information within an image is useful for some operations such as
+image <a href="#disp-imcomp">compositing</a>. This extra channel usually defines
+a mask which represents a sort of a cookie-cutter for the image. This is
+the case when matte is 255 (full coverage) for pixels inside the shape,
+zero outside, and between zero and 255 on the boundary.
+<p>
+Setting the matte information in an image is done interactively. There
+is no command line argument to edit a pixel. To begin, and choose <strong>Matte</strong>
+of the <strong>Image Edit</strong> sub-menu from the <a href="#disp-comm">Command widget</a>.
+<p>
+Alternatively, <a href="#disp-keyb">press</a> m in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in matte edit mode. To exit immediately, press Dismiss.
+In matte edit mode, the Command widget has these options:
+<ul>
+<li>
+<strong>Method</strong>
+<ul>
+<li>
+point
+<li>
+replace
+<li>
+floodfill
+<li>
+reset
+</ul>
+<li>
+<strong>Border Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+Browser...
+</ul>
+<li>
+<strong>Fuzz</strong>
+<ul>
+<li>
+0
+<li>
+2
+<li>
+4
+<li>
+8
+<li>
+16
+<li>Dialog...
+</ul>
+<li>
+<strong>Matte</strong>
+<li>
+<strong>Undo</strong>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+Choose a matte editing method from the <strong>Method</strong> sub-menu of the <a href="#disp-comm">Command
+widget</a>. The <strong>point method</strong> changes the matte value of the any
+pixel selected with the pointer until the button is released. The <strong>replace
+method</strong> changes the matte value of any pixel that matches the color
+of the pixel you select with a button press. <strong>Floodfill</strong> changes the
+matte value of any pixel that matches the color of the pixel you select
+with a button press and is a neighbor. Whereas
+<strong>filltoborder</strong> recolors
+any neighbor pixel that is not the border color. Finally <strong>reset</strong> changes
+the entire image to the designated matte value.
+<p>Choose <strong>Matte Value</strong> and a dialog appears requesting a matte value.
+Enter a value between <strong>0 and 255</strong>. This value is assigned as the matte
+value of the selected pixel or pixels.
+<p>Now, press any button to select a pixel within the Image window to change
+its matte value. You can change the matte value of additional pixels by
+increasing the Delta value. The Delta value is first added then subtracted
+from the red, green, and blue of the target color. Any pixels within the
+range also have their matte value updated.
+<p>If the <strong>Magnify widget</strong> is mapped, it can be helpful in positioning
+your pointer within the image (refer to button 2). Alternatively you can
+select a pixel to change the matte value from within the
+<strong>Magnify widget</strong>.
+Move the pointer to the <strong>Magnify widget</strong> and position the pixel with
+the cursor control keys. Finally, press a button to change the matte value
+of the selected pixel (or pixels).
+<p>Matte information is only valid in a <em>DirectClass image</em>. Therefore,
+any <em>PseudoClass</em> image is promoted to
+<em>DirectClass</em>. Note that
+matte information for <em>PseudoClass</em> is not retained for colormapped
+X server visuals (e.g. <em>StaticColor, StaticColor, GrayScale, PseudoColor</em>)
+unless you immediately save your image to a file (refer to Write). Correct
+matte editing behavior may require a <em>TrueColor</em> or <em>DirectColor</em>
+visual or a <em>Standard Colormap</em>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-imdr"></a>Image Drawing
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+An image is drawn upon interactively. <strong>There is no command line argument
+to draw on an image</strong>. To begin, choose <strong>Draw</strong> of the Image <strong>Edit</strong>
+sub-menu from the <a href="#disp-comm">Command widget</a>.
+Alternatively, <a href="#disp-keyb">press</a> d in the image window.
+<p>
+The cursor changes to a crosshair to indicate you are in draw mode. To
+exit immediately, press Dismiss. In draw mode, the Command widget has these
+options:
+<ul>
+<li>
+<strong>Primitive</strong>
+<ul>
+<li>
+point
+<li>
+line
+<li>
+rectangle
+<li>
+fill rectangle
+<li>
+circle
+<li>
+fill circle
+<li>
+ellipse
+<li>
+fill ellipse
+<li>
+polygon
+<li>
+fill polygon
+</ul>
+<li>
+<strong>Color</strong>
+<ul>
+<li>
+black
+<li>
+blue
+<li>
+cyan
+<li>
+green
+<li>
+gray
+<li>
+red
+<li>
+magenta
+<li>
+yellow
+<li>
+white
+<li>
+transparent
+<li>
+Browser...
+</ul>
+<li>
+<strong>Stipple</strong>
+<ul>
+<li>
+Brick
+<li>
+Diagonal
+<li>
+Scales
+<li>
+Vertical
+<li>
+Wavy
+<li>
+Translucent
+<li>
+Opaque
+<li>
+Open...
+</ul>
+<li>
+<strong>Width</strong>
+<ul>
+<li>
+1
+<li>
+2
+<li>
+4
+<li>
+8
+<li>
+16
+<li>Dialog...
+</ul>
+<li>
+<strong>Undo</strong>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+Choose a drawing primitive from the <strong>Primitive</strong> sub-menu.
+<p>
+Next, choose a color from the <strong>Color</strong> sub-menu. Additional colors
+can be specified with the color browser. You can change the menu colors
+by setting the <a href="#disp-xres">X resources</a> pen1 through pen9. The transparent
+color updates the image matte channel and is useful for image compositing.
+<p>
+If you choose the color browser and press <strong>Grab</strong>, you can select the
+primitive color by moving the pointer to the desired color on the screen
+and press any button. The transparent color updates the image matte channel
+and is useful for image compositing.
+<p>
+Choose a stipple, if appropriate, from the <strong>Stipple</strong> sub-menu. Additional
+stipples can be specified with the file browser. Stipples obtained from
+the file browser must be on disk in the X11 bitmap format.
+<p>
+Choose a line width, if appropriate, from the <strong>Width</strong> sub-menu. To
+choose a specific width select the <strong>Dialog</strong> widget.
+<p>
+Choose a point in the image window and press button 1 and hold. Next, move
+the pointer to another location in the image. As you move, a line connects
+the initial location and the pointer. When you release the button, the
+image is updated with the primitive you just drew. For polygons, the image
+is updated when you press and release the button without moving the pointer.
+<p>
+To cancel image drawing, move the pointer back to the starting point of
+the line and release the button.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-regi"></a>Region of Interest
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To begin, press choose Region of Interest of the Pixel Transform sub-menu
+from the <a href="#disp-comm">Command widget</a>.
+Alternatively, <a href="#disp-keyb">press</a> R in the image window.
+<p>
+A small window appears showing the location of the cursor in the image
+window. You are now in region of interest mode. In region of interest mode,
+the Command widget has these options:
+<ul>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+To define a region of interest, press button 1 and drag. The region of
+interest is defined by a highlighted rectangle that expands or contracts
+as it follows the pointer. Once you are satisfied with the region of interest,
+release the button. You are now in apply mode. In apply mode the Command
+widget has these options:
+<ul>
+<li>
+<strong>File</strong>
+<ul>
+<li>
+Save...
+<li>
+Print...
+</ul>
+<li>
+<strong>Edit</strong>
+<ul>
+<li>
+Undo
+<li>
+Redo
+</ul>
+<li>
+<strong>Transform</strong>
+<ul>
+<li>
+Flip
+<li>
+Flop
+<li>
+Rotate Right
+<li>
+Rotate Left
+</ul>
+<li>
+<strong>Enhance</strong>
+<ul>
+<li>
+Hue...
+<li>
+Saturation...
+<li>
+Brightness...
+<li>
+Gamma...
+<li>
+Spiff
+<li>
+Dull
+<li>
+Equalize
+<li>
+Normalize
+<li>
+Negate
+<li>
+GRAYscale
+<li>
+Quantize...
+</ul>
+<li>
+<strong>Effects</strong>
+<ul>
+<li>
+Despeckle
+<li>
+Emboss
+<li>
+Reduce Noise
+<li>
+Add Noise
+<li>
+Sharpen...
+<li>
+Blur...
+<li>
+Threshold...
+<li>
+Edge Detect...
+<li>
+Spread...
+<li>
+Shade...
+<li>
+Raise...
+<li>
+Segment...
+</ul>
+</ul>
+<ul>
+<li>
+<strong>F/X</strong>
+<ul>
+<li>
+Solarize...
+<li>
+Swirl...
+<li>
+Implode...
+<li>
+Wave...
+<li>
+Oil Paint
+<li>
+Charcoal Draw...
+</ul>
+</ul>
+<ul>
+<li>
+<strong>Miscellany</strong>
+<ul>
+<li>
+Image Info
+<li>
+Zoom Image
+<li>
+Show Preview...
+<li>
+Show Histogram
+<li>
+Show Matte
+</ul>
+<li>
+<strong>Help</strong>
+<li>
+<strong>Dismiss</strong>
+</ul>
+<p>
+You can make adjustments to the region of interest by moving the pointer
+to one of the rectangle corners, pressing a button, and dragging. Finally,
+choose an image processing technique from the Command widget. You can choose
+more than one image processing technique to apply to an area. Alternatively,
+you can move the region of interest before applying another image processing
+technique. To exit, press Dismiss.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-impa"></a>Image Panning
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+When an image exceeds the width or height of the X server screen, display
+maps a small panning icon. The rectangle within the panning icon shows
+the area that is currently displayed in the the image window. To pan about
+the image, press any button and drag the pointer within the panning icon.
+The pan rectangle moves with the pointer and the image window is updated
+to reflect the location of the rectangle within the panning icon. When
+you have selected the area of the image you wish to view, release the button.
+<p>
+Use the arrow keys to pan the image one pixel up, down, left, or right
+within the image window.
+<p>
+The panning icon is withdrawn if the image becomes smaller than the dimensions
+of the X server screen.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="disp-pref"></a>User Preferences
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Preferences affect the default behavior of <strong>display(1)</strong>. The preferences
+are either true or false and are stored in your home directory
+as <tt>.displayrc</tt>:
+<dl>
+<dt>
+<strong>display image centered on a backdrop</strong></dt>
+<dd>
+This backdrop covers the entire workstation screen and is useful for hiding
+other X window activity while viewing the image. The color of the backdrop
+is specified as the background color. Refer to <a href="#disp-xres">X Resources</a>
+for details.</dd>
+<dt>
+<strong>confirm on program exit</strong></dt>
+<dd>
+Ask for a confirmation before exiting the <strong>display(1)</strong> program.</dd>
+<dt>
+<strong>correct image for display gamma</strong></dt>
+<dd>
+If the image has a known gamma, the gamma is corrected to match that of
+the X server (see the <a href="#disp-xres">X Resource</a><strong> displayGamma</strong>).</dd>
+<dt>
+<strong>display warning messages</strong></dt>
+<dd>
+Display any warning messages.</dd>
+<dt>
+<strong>apply Floyd/Steinberg error diffusion to image</strong></dt>
+<dd>
+The basic strategy of dithering is to trade intensity resolution for spatial
+resolution by averaging the intensities of several neighboring pixels.
+Images which suffer from severe contouring when reducing colors can be
+improved with this preference.</dd>
+<dt>
+<strong>use a shared colormap for colormapped X visuals</strong></dt>
+<dd>
+This option only applies when the default X server visual is
+<em>PseudoColor</em>
+or <em>GRAYScale</em>. Refer to <strong>-visual</strong> for more details. By default,
+a shared colormap is allocated. The image shares colors with other X clients.
+Some image colors could be approximated, therefore your image may look
+very different than intended. Otherwise the image colors appear exactly
+as they are defined. However, other clients may go technicolor when the
+image colormap is installed.</dd>
+<dt>
+<strong>display images as an X server pixmap</strong></dt>
+<dd>
+Images are maintained as a XImage by default. Set this resource to True
+to utilize a server Pixmap instead. This option is useful if your image
+exceeds the dimensions of your server screen and you intend to pan the
+image. Panning is much faster with Pixmaps than with a XImage. Pixmaps
+are considered a precious resource, use them with discretion.</dd>
+</dl>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="gm identify"></a>gm identify
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Identify</strong> describes the format and characteristics of one or
+more image files as internally supported by the software. It will also
+report if an image is incomplete or corrupt. The information
+displayed includes the scene number, the file name, the width and
+height of the image, whether the image is colormapped or not, the
+number of colors in the image, the number of bytes in the image, the
+format of the image (JPEG, PNM, etc.), and finally the number of
+seconds in both user time and elapsed time it took to read and process
+the image. If -verbose or +ping are provided as an option, the pixel
+read rate is also displayed. An example line output from
+<strong>identify</strong> follows:
+<pre>
+ images/aquarium.miff 640x480 PseudoClass 256c
+ 308135b MIFF 0.000u 0:01
+</pre>
+<p>
+If <tt>-verbose</tt> is set, expect additional output including any image
+comment:
+<br>&nbsp;<br>
+<pre>
+ Image: images/aquarium.miff
+ class: PseudoClass
+ colors: 256
+ signature: eb5dca81dd93ae7e6ffae99a527eb5dca8...
+ matte: False
+ geometry: 640x480
+ depth: 8
+ bytes: 308135
+ format: MIFF
+ comments:
+ Imported from MTV raster image: aquarium.mtv
+</pre>
+<p>
+For some formats, additional format-specific information about the file
+will be written if the <tt>-debug coder</tt> or <tt>-debug all</tt> option
+is used.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="ident-opti"></a>Identify options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images immediately
+following, until the set is terminated by the appearance of any option
+or <strong>-noop</strong>.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-format">-format</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output formatted image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -ping
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>efficiently determine image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="import"></a>gm import
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Import</strong> reads an image from any visible window on an X server and
+outputs it as an image file. You can capture a single window, the entire
+screen, or any rectangular portion of the screen.
+Use <em><a href="display.html">display</a></em>
+for redisplay, printing, editing, formatting, archiving, image processing,
+etc. of the captured image.
+<p>
+The target window can be specified by id, name, or may be selected
+by clicking the mouse in the desired window. If you press a button and
+then drag, a rectangle will form which expands and contracts as the mouse
+moves. To save the portion of the screen defined by the rectangle, just
+release the button. The keyboard bell is rung once at the beginning of
+the screen capture and twice when it completes.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="imp-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To select an X window or an area of the screen with the mouse and save it
+in the MIFF image format to a file entitled window.miff, use:
+<pre>
+ gm import window.miff
+</pre>
+<p>
+To select an X window or an area of the screen with the mouse and save it
+in the Encapsulated PostScript format to include in another document, use:
+<pre>
+ gm import figure.eps
+</pre>
+<p>
+To capture the entire X server screen in the JPEG image format in a file
+entitled root.jpeg, without using the mouse, use:
+<pre>
+ gm import -window root root.jpeg
+</pre>
+<p>
+To capture the 512x256 area at the upper right corner of the X server
+screen in the PNG image format in a well-compressed file entitled corner.png,
+without using the mouse, use:
+<pre>
+ gm import -window root -crop 512x256-0+0 -quality 90
+ corner.png
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="imp-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect.
+<p>
+<strong>Import</strong> options can appear on the command line or in your
+X resources file. See <em>X(1)</em>. Options on the command line supersede
+values specified in your X resources file.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -descend
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>obtain image by descending window hierarchy</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -frame
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>include the X window frame in the imported image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pause">-pause</a> <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pause between snapshots [import]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -ping
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>efficiently determine image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scene">-scene</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-screen">-screen</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the screen to capture</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -silent
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>operate silently</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-snaps">-snaps</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>number of screen snapshots</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transparent">-transparent</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+</td></tr></table>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mogrify"></a>gm mogrify
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Mogrify</strong> transforms an image or a sequence of images. These transforms
+include image scaling, image rotation, color reduction, and others. Each
+transmogrified image overwrites the corresponding original image, unless an
+option such as
+<strong>-format</strong> causes the output filename to be different from the input
+filename.
+<br>&nbsp;<br>
+The graphics formats supported by <strong>mogrify</strong> are listed in
+<em>GraphicsMagick(1)</em>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mog-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To convert all the TIFF files in a particular directory to JPEG, use:
+<pre>
+ gm mogrify -format jpeg *.tiff
+</pre>
+<p>
+To convert a directory full of JPEG images to thumbnails, use:
+<pre>
+ gm mogrify -size 120x120 *.jpg -resize 120x120 +profile "*"
+</pre>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In this example, <tt>'-size 120x120'</tt> gives a hint to the JPEG decoder
+that the images are going to be downscaled to 120x120, allowing it to run
+faster by avoiding returning full-resolution images to GraphicsMagick for
+the subsequent resizing operation. The
+<tt>'-resize 120x120'</tt> specifies the desired dimensions of the
+output images. It will be scaled so its largest dimension is 120 pixels. The
+<tt>'+profile "*"'</tt> removes any ICM, EXIF, IPTC, or other profiles
+that might be present in the input and aren't needed in the thumbnails.</font></td></tr></table>
+<p>
+To scale an image of a cockatoo to exactly 640 pixels in width and 480
+pixels in height, use:
+<pre>
+ gm mogrify -resize 640x480! cockatoo.miff
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mog-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or <strong>-noop</strong>.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-affine">-affine</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>drawing transform matrix</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-antialias">-antialias</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixel aliasing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details"></a> <i>-asc-cdl &lt;spec&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply ASC CDL color transform</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-auto-orient">-auto-orient</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>orient (rotate) image so it is upright</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-black-threshold">-black-threshold</a> <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels below the threshold become black</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blue-primary">-blue-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blur">-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-border">-border</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with a border of color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-channel">-channel</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of channel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -charcoal <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate a charcoal drawing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorize">-colorize</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colorize the image with the pen color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compose">-compose</a> <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-contrast">-contrast</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enhance or reduce the image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-convolve">-convolve</a> <i>&lt;kernel&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>convolve image with the specified convolution kernel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-create-directories">-create-directories</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create output directory if required</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-cycle">-cycle</a> <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image colormap by amount</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -despeckle
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>reduce the speckles within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-draw">-draw</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with one or more graphic primitives</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -edge <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>detect edges within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -emboss <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>emboss an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -enhance
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a digital filter to enhance a noisy image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -equalize
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform histogram equalization to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-extent">-extent</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite image on background color canvas image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fill">-fill</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flip">-flip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flop">-flop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-format">-format</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image format type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-frame">-frame</a> <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fuzz">-fuzz</a> <i>&lt;distance&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colors within this Euclidean distance are considered equal</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gaussian">-gaussian</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gravity">-gravity</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-green-primary">-green-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -hald-clut <i>&lt;clut&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a Hald CLUT to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -implode <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>implode image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-lat">-lat</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;offset&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform local adaptive thresholding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-level">-level</a> <i>&lt;black_point&gt;</i>{<i>,&lt;gamma&gt;</i>}<i></i>{<i>,&lt;white_point&gt;</i>}<i></i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>adjust the level of image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -linewidth
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the line width for subsequent draw operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-list">-list</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of list</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-loop">-loop</a> <i>&lt;iterations&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add Netscape loop extension to your GIF animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-map">-map</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>choose a particular set of colors from this image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mask">-mask</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify a clipping mask</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -median <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a median filter to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -minify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>minify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-modulate">-modulate</a> <i>brightness[,saturation[,hue]]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>vary the brightness, saturation, and hue of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-motion-blur">-motion-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+angle</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Simulate motion blur</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noise">-noise</a> <i>&lt;radius|type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add or reduce noise in an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-normalize">-normalize</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform image to span the full range of color values</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-opaque">-opaque</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>change this color to the pen color within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-operator">-operator</a> <i>channel operator rvalue[%]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a mathematical, bitwise, or value operator to an image channel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-ordered-dither">-ordered-dither</a> <i>&lt;channeltype&gt; &lt;NxN&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>ordered dither the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-output-directory">-output-directory</a> <i>&lt;directory&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output files to directory</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-orient">-orient</a> <i>&lt;orientation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Set the image orientation attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-paint">-paint</a> <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate an oil painting</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pen">-pen</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>(This option has been replaced by the -fill option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-profile">-profile</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add ICM, IPTC, or generic profile to image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-preserve-timestamp">-preserve-timestamp</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preserve the original timestamps of the file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-raise">-raise</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>lighten or darken image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-random-threshold">-random-threshold</a> <i>&lt;channeltype&gt; &lt;LOWxHIGH&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>random threshold the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-recolor">-recolor</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a color translation matrix to image channels</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-red-primary">-red-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-region">-region</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply options to a portion of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-render">-render</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-repage">-repage</a> <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resample">-resample</a> <i>&lt;horizontal&gt;x&lt;vertical&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Resample image to specified horizontal and vertical resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-roll">-roll</a> <i></i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>roll an image vertically or horizontally</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sample">-sample</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale image using pixel sampling</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scale">-scale</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scene">-scene</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-segment">-segment</a> <i>&lt;cluster threshold&gt;x&lt;smoothing threshold&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>segment an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shade">-shade</a> <i>&lt;azimuth&gt;x&lt;elevation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shade the image using a distant light source</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shave">-shave</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shave pixels from the image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shear">-shear</a> <i>&lt;x degrees&gt;x&lt;y degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shear the image along the X or Y axis</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-solarize">-solarize</a> <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>negate all pixels above the threshold level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-spread">-spread</a> <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image pixels by a random amount</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strip">-strip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stroke">-stroke</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when stroking a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strokewidth">-strokewidth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the stroke width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-swirl">-swirl</a> <i>&lt;degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>swirl image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-threshold">-threshold</a> <i>&lt;value&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>threshold the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tile image when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transform">-transform</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transparent">-transparent</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-units">-units</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the units of image resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-unsharp">-unsharp</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+&lt;amount&gt;</i>}<i></i>{<i>+&lt;threshold&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image with an unsharp mask operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -view <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>FlashPix viewing parameters</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-virtual-pixel">-virtual-pixel</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify contents of "virtual pixels"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-wave">-wave</a> <i>&lt;amplitude&gt;x&lt;wavelength&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>alter an image along a sine wave</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-point">-white-point</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-threshold">-white-threshold</a> <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels above the threshold become white</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="montage"></a>gm montage
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>montage</strong> creates a composite image by combining several separate
+images. The images are tiled on the composite image with the name of the
+image optionally appearing just below the individual tile.
+<p>
+The composite image is constructed in the following manner. First, each
+image specified on the command line, except for the last, is scaled to
+fit the maximum tile size. The maximum tile size by default is 120x120.
+It can be modified with the <strong>-geometry</strong> command line argument or X
+resource. See
+<strong>Options</strong>
+for more information on command line arguments. See
+<strong>X(1)</strong> for more information on X resources.
+Note that the maximum tile size need not be a square.
+<p>
+Next the composite image is initialized with the color specified by the
+<strong>-background</strong>
+command line argument or X resource. The width and height of the composite
+image is determined by the title specified, the maximum tile size, the
+number of tiles per row, the tile border width and height, the image border
+width, and the label height. The number of tiles per row specifies how
+many images are to appear in each row of the composite image. The default
+is to have 5 tiles in each row and 4 tiles in each column of the composite.
+A specific value is specified with <strong>-tile</strong>. The tile border width
+and height, and the image border width defaults to the value of the X resource
+<strong>-borderwidth</strong>. It can be changed with the <strong>-borderwidth</strong> or
+<strong>-geometry</strong> command line argument or X resource. The label height
+is determined by the font you specify with the <strong>-font</strong> command line
+argument or X resource. If you do not specify a font, a font is chosen
+that allows the name of the image to fit the maximum width of a tiled area.
+The label colors is determined by the <strong>-background</strong> and <strong>-fill</strong>
+command line argument or X resource. Note, that if the background and pen
+colors are the same, labels will not appear.
+<p>
+Initially, the composite image title is placed at the top if one is specified
+(refer to <strong>-fill</strong>). Next, each image is set onto the composite image,
+surrounded by its border color, with its name centered just below it. The
+individual images are left-justified within the width of the tiled area.
+The order of the images is the same as they appear on the command line
+unless the images have a scene keyword. If a scene number is specified
+in each image, then the images are tiled onto the composite in the order
+of their scene number. Finally, the last argument on the command line is
+the name assigned to the composite image. By default, the image is written
+in the <strong>MIFF</strong> format and can be viewed or printed with
+<em>display(1)</em>.
+<br>&nbsp;<br>
+<p>
+Note, that if the number of tiles exceeds the default number of 20 (5 per
+row, 4 per column), more than one composite image is created. To ensure
+a single image is produced, use <strong>-tile</strong> to increase the number of
+tiles to meet or exceed the number of input images.
+<p>
+Finally, to create one or more empty spaces in the sequence of tiles, use
+the <strong>"NULL:"</strong> image format.
+<p>
+Note, a composite MIFF image displayed to an X server with
+<strong>display</strong>
+behaves differently than other images. You can think of the composite as
+a visual image directory. Choose a particular tile of the composite and
+press a button to display it. See <strong>display(1)</strong> and <strong>miff(5)</strong>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To create a montage of a cockatoo, a parrot, and a hummingbird and write
+it to a file called birds, use:
+<pre>
+ gm montage cockatoo.miff parrot.miff hummingbird.miff
+ birds.miff
+</pre>
+<p>
+To tile several bird images so that they are at most 256 pixels in width
+and 192 pixels in height, surrounded by a red border, and separated by
+10 pixels of background color, use:
+<pre>
+ gm montage -geometry 256x192+10+10 -bordercolor red
+ birds.* montage.miff
+</pre>
+<p>
+To create an unlabeled parrot image, 640 by 480 pixels, and surrounded
+by a border of black, use:
+<pre>
+ gm montage -geometry 640x480 -bordercolor black
+ -label "" parrot.miff bird.miff
+</pre>
+<p>
+To create an image of an eagle with a textured background, use:
+<pre>
+ gm montage -texture bumps.jpg eagle.jpg eagle.png
+</pre>
+<p>
+To join several GIF images together without any extraneous graphics (e.g.
+no label, no shadowing, no surrounding tile frame), use:
+<pre>
+ gm montage +frame +shadow +label -tile 5x1
+ -geometry 50x50+0+0 *.png joined.png
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Any option you specify on the command line remains in effect for the group
+of images following it, until the group is terminated by the appearance of
+any option or <strong>-noop</strong>. For example, to make a montage of three images,
+the first with 32 colors, the second with an unlimited number of colors, and
+the third with only 16 colors, use:
+<br>&nbsp;<br>
+<pre>
+ gm montage -colors 32 cockatoo.1 -noop cockatoo.2
+ -colors 16 cockatoo.3 cockatoos.miff
+</pre>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-adjoin">-adjoin</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>join images into a single multi-image file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-affine">-affine</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>drawing transform matrix</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blue-primary">-blue-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blur">-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -borderwidth <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-chop">-chop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixels from the interior of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compose">-compose</a> <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-draw">-draw</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with one or more graphic primitives</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fill">-fill</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-frame">-frame</a> <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gravity">-gravity</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-green-primary">-green-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -mode <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>mode of operation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pen">-pen</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>(This option has been replaced by the -fill option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-red-primary">-red-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-render">-render</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-repage">-repage</a> <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scenes">-scenes</a> <i>&lt;value-value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>range of image scene numbers to read</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -shadow <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shadow the montage</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strip">-strip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stroke">-stroke</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when stroking a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strokewidth">-strokewidth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the stroke width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>layout of images [<em>montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-title">-title</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign title to displayed image [<em>animate, display, montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transform">-transform</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transparent">-transparent</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-point">-white-point</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-xres"></a>X Resources
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Montage</strong> options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See <strong>X(1)</strong> for more information on X resources.
+<p>
+All <strong>montage</strong> options have a corresponding X resource. In addition,
+<strong>montage</strong>
+uses the following X resources:
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ background <i>(class Background)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>background color</td></tr></table>
+<p>
+Specifies the preferred color to use for the composite image background.
+The default is #ccc.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ borderColor <i>(class BorderColor)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>border color</td></tr></table>
+<p>
+Specifies the preferred color to use for the composite image border. The
+default is #ccc.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ borderWidth <i>(class BorderWidth)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>border width</td></tr></table>
+<p>
+Specifies the width in pixels of the composite image border. The default
+is 2.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ font <i>(class Font)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>font to use</td></tr></table>
+<p>
+Specifies the name of the preferred font to use when displaying text within
+the composite image. The default is 9x15, fixed, or 5x8 determined by the
+composite image size.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ matteColor <i>(class MatteColor)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color of the frame</td></tr></table>
+<p>
+Specify the color of an image frame. A 3D effect is achieved by using highlight
+and shadow colors derived from this color. The default value is #697B8F.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ pen <i>(class Pen)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>text color</td></tr></table>
+<p>
+Specifies the preferred color to use for text within the composite image.
+The default is black.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ title <i>(class Title)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite image title</td></tr></table>
+<p>
+This resource specifies the title to be placed at the top of the composite
+image. The default is not to place a title at the top of the composite
+image.
+</td></tr></table>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time"></a>gm time
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>time</strong> executes an arbitrary <strong>gm</strong> utility command
+(e.g. <strong>convert</strong>) and reports the user and elapsed time. This
+provides way to measure command execution times similar to the Unix
+'time' command but in a portable and consistent way.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>To obtain time information for the execution of a
+command:
+<pre>
+% gm time convert input.ppm -gaussian 0x2 output.ppm
+convert input.ppm -gaussian 0x2 output.ppm 22.60s user 0.00s system 2354% cpu 0.960 total
+</pre>
+<p>Here is the interpretation of the above output:
+<ul>
+<li><strong>user</strong> - the total user time consumed.
+<li><strong>system</strong> - the total system time consumed.
+<li><strong>total</strong> - the total elapsed time consumed.
+</ul>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>The time command reqires no options other than the gm command to
+execute.
+</td></tr></table>
+</td></tr></table>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version"></a>gm version
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>version</strong> displays the software release version, build quantum
+(pixel sample) depth, web site URL, copyright notice, enabled features
+support, configuration parameters, and final build options used to
+build the software. The available information depends on how the
+software was configured and the host system.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>To display the version information:
+<pre>
+ % gm -version
+ GraphicsMagick 1.3.19 2013-12-31 Q16 http://www.GraphicsMagick.org/
+ Copyright (C) 2002-2013 GraphicsMagick Group.
+ Additional copyrights and licenses apply to this software.
+ See http://www.GraphicsMagick.org/www/Copyright.html for details.
+ Feature Support:
+ Thread Safe yes
+ Large Files (&gt; 32 bit) yes
+ Large Memory (&gt; 32 bit) no
+ BZIP yes
+ DPS no
+ FlashPix no
+ FreeType yes
+ Ghostscript (Library) no
+ JBIG no
+ JPEG-2000 yes
+ JPEG yes
+ Little CMS yes
+ Loadable Modules no
+ OpenMP yes (201107)
+ PNG yes
+ TIFF yes
+ TRIO no
+ UMEM yes
+ WMF no
+ X11 yes
+ XML yes
+ ZLIB yes
+ Host type: i386-pc-solaris2.11
+ Configured using the command:
+ ./configure ...
+ Final Build Parameters:
+ CC = ...
+ CFLAGS = ...
+ CPPFLAGS = ...
+ CXX = ...
+ CXXFLAGS = ...
+ LDFLAGS = ...
+ LIBS = ...
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>The version command does not currently support any options.
+</td></tr></table>
+</td></tr></table>
diff --git a/www/identify.html b/www/identify.html
new file mode 100644
index 0000000..3dd9065
--- /dev/null
+++ b/www/identify.html
@@ -0,0 +1,324 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="gm identify"></a>gm identify
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="ident-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+identify - describe an image or image sequence.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="ident-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#ident-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#ident-desc">Description</a>
+</dt>
+<dt>
+<a href="#ident-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="ident-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm identify</strong> <em>file</em> [ <em>file</em> ... ]
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="ident-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Identify</strong> describes the format and characteristics of one or
+more image files as internally supported by the software. It will also
+report if an image is incomplete or corrupt. The information
+displayed includes the scene number, the file name, the width and
+height of the image, whether the image is colormapped or not, the
+number of colors in the image, the number of bytes in the image, the
+format of the image (JPEG, PNM, etc.), and finally the number of
+seconds in both user time and elapsed time it took to read and process
+the image. If -verbose or +ping are provided as an option, the pixel
+read rate is also displayed. An example line output from
+<strong>identify</strong> follows:
+<pre>
+ images/aquarium.miff 640x480 PseudoClass 256c
+ 308135b MIFF 0.000u 0:01
+</pre>
+<p>
+If <tt>-verbose</tt> is set, expect additional output including any image
+comment:
+<br>&nbsp;<br>
+<pre>
+ Image: images/aquarium.miff
+ class: PseudoClass
+ colors: 256
+ signature: eb5dca81dd93ae7e6ffae99a527eb5dca8...
+ matte: False
+ geometry: 640x480
+ depth: 8
+ bytes: 308135
+ format: MIFF
+ comments:
+ Imported from MTV raster image: aquarium.mtv
+</pre>
+<p>
+For some formats, additional format-specific information about the file
+will be written if the <tt>-debug coder</tt> or <tt>-debug all</tt> option
+is used.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="ident-opti"></a>Identify options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images immediately
+following, until the set is terminated by the appearance of any option
+or <strong>-noop</strong>.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-format">-format</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output formatted image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -ping
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>efficiently determine image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
diff --git a/www/images/ball.png b/www/images/ball.png
new file mode 100644
index 0000000..449b0e2
--- /dev/null
+++ b/www/images/ball.png
Binary files differ
diff --git a/www/images/banner_bg.png b/www/images/banner_bg.png
new file mode 100644
index 0000000..8c910c2
--- /dev/null
+++ b/www/images/banner_bg.png
Binary files differ
diff --git a/www/images/gm-107x76.gif b/www/images/gm-107x76.gif
new file mode 100644
index 0000000..801a794
--- /dev/null
+++ b/www/images/gm-107x76.gif
Binary files differ
diff --git a/www/images/gm-107x76.png b/www/images/gm-107x76.png
new file mode 100644
index 0000000..3d1d77e
--- /dev/null
+++ b/www/images/gm-107x76.png
Binary files differ
diff --git a/www/images/gm-125x80t.png b/www/images/gm-125x80t.png
new file mode 100644
index 0000000..a981bae
--- /dev/null
+++ b/www/images/gm-125x80t.png
Binary files differ
diff --git a/www/images/patterns/bricks.png b/www/images/patterns/bricks.png
new file mode 100644
index 0000000..6358cf8
--- /dev/null
+++ b/www/images/patterns/bricks.png
Binary files differ
diff --git a/www/images/patterns/checkerboard.png b/www/images/patterns/checkerboard.png
new file mode 100644
index 0000000..2a59abe
--- /dev/null
+++ b/www/images/patterns/checkerboard.png
Binary files differ
diff --git a/www/images/patterns/circles.png b/www/images/patterns/circles.png
new file mode 100644
index 0000000..a2de169
--- /dev/null
+++ b/www/images/patterns/circles.png
Binary files differ
diff --git a/www/images/patterns/crosshatch.png b/www/images/patterns/crosshatch.png
new file mode 100644
index 0000000..b728f48
--- /dev/null
+++ b/www/images/patterns/crosshatch.png
Binary files differ
diff --git a/www/images/patterns/crosshatch30.png b/www/images/patterns/crosshatch30.png
new file mode 100644
index 0000000..8bbd0e1
--- /dev/null
+++ b/www/images/patterns/crosshatch30.png
Binary files differ
diff --git a/www/images/patterns/crosshatch45.png b/www/images/patterns/crosshatch45.png
new file mode 100644
index 0000000..534687f
--- /dev/null
+++ b/www/images/patterns/crosshatch45.png
Binary files differ
diff --git a/www/images/patterns/fishscales.png b/www/images/patterns/fishscales.png
new file mode 100644
index 0000000..7c310a6
--- /dev/null
+++ b/www/images/patterns/fishscales.png
Binary files differ
diff --git a/www/images/patterns/granite.png b/www/images/patterns/granite.png
new file mode 100644
index 0000000..3eecaff
--- /dev/null
+++ b/www/images/patterns/granite.png
Binary files differ
diff --git a/www/images/patterns/gray0.png b/www/images/patterns/gray0.png
new file mode 100644
index 0000000..df63edb
--- /dev/null
+++ b/www/images/patterns/gray0.png
Binary files differ
diff --git a/www/images/patterns/gray10.png b/www/images/patterns/gray10.png
new file mode 100644
index 0000000..24633c7
--- /dev/null
+++ b/www/images/patterns/gray10.png
Binary files differ
diff --git a/www/images/patterns/gray100.png b/www/images/patterns/gray100.png
new file mode 100644
index 0000000..66bfbc2
--- /dev/null
+++ b/www/images/patterns/gray100.png
Binary files differ
diff --git a/www/images/patterns/gray15.png b/www/images/patterns/gray15.png
new file mode 100644
index 0000000..9e24d51
--- /dev/null
+++ b/www/images/patterns/gray15.png
Binary files differ
diff --git a/www/images/patterns/gray20.png b/www/images/patterns/gray20.png
new file mode 100644
index 0000000..c8981c2
--- /dev/null
+++ b/www/images/patterns/gray20.png
Binary files differ
diff --git a/www/images/patterns/gray25.png b/www/images/patterns/gray25.png
new file mode 100644
index 0000000..867391b
--- /dev/null
+++ b/www/images/patterns/gray25.png
Binary files differ
diff --git a/www/images/patterns/gray30.png b/www/images/patterns/gray30.png
new file mode 100644
index 0000000..b37a759
--- /dev/null
+++ b/www/images/patterns/gray30.png
Binary files differ
diff --git a/www/images/patterns/gray35.png b/www/images/patterns/gray35.png
new file mode 100644
index 0000000..6d58343
--- /dev/null
+++ b/www/images/patterns/gray35.png
Binary files differ
diff --git a/www/images/patterns/gray40.png b/www/images/patterns/gray40.png
new file mode 100644
index 0000000..f079c9a
--- /dev/null
+++ b/www/images/patterns/gray40.png
Binary files differ
diff --git a/www/images/patterns/gray45.png b/www/images/patterns/gray45.png
new file mode 100644
index 0000000..3267ae3
--- /dev/null
+++ b/www/images/patterns/gray45.png
Binary files differ
diff --git a/www/images/patterns/gray5.png b/www/images/patterns/gray5.png
new file mode 100644
index 0000000..baa3bea
--- /dev/null
+++ b/www/images/patterns/gray5.png
Binary files differ
diff --git a/www/images/patterns/gray50.png b/www/images/patterns/gray50.png
new file mode 100644
index 0000000..ec34108
--- /dev/null
+++ b/www/images/patterns/gray50.png
Binary files differ
diff --git a/www/images/patterns/gray55.png b/www/images/patterns/gray55.png
new file mode 100644
index 0000000..90a597a
--- /dev/null
+++ b/www/images/patterns/gray55.png
Binary files differ
diff --git a/www/images/patterns/gray60.png b/www/images/patterns/gray60.png
new file mode 100644
index 0000000..7dd8e48
--- /dev/null
+++ b/www/images/patterns/gray60.png
Binary files differ
diff --git a/www/images/patterns/gray65.png b/www/images/patterns/gray65.png
new file mode 100644
index 0000000..70369b1
--- /dev/null
+++ b/www/images/patterns/gray65.png
Binary files differ
diff --git a/www/images/patterns/gray70.png b/www/images/patterns/gray70.png
new file mode 100644
index 0000000..26a497b
--- /dev/null
+++ b/www/images/patterns/gray70.png
Binary files differ
diff --git a/www/images/patterns/gray75.png b/www/images/patterns/gray75.png
new file mode 100644
index 0000000..059083b
--- /dev/null
+++ b/www/images/patterns/gray75.png
Binary files differ
diff --git a/www/images/patterns/gray80.png b/www/images/patterns/gray80.png
new file mode 100644
index 0000000..50a1e98
--- /dev/null
+++ b/www/images/patterns/gray80.png
Binary files differ
diff --git a/www/images/patterns/gray85.png b/www/images/patterns/gray85.png
new file mode 100644
index 0000000..4637990
--- /dev/null
+++ b/www/images/patterns/gray85.png
Binary files differ
diff --git a/www/images/patterns/gray90.png b/www/images/patterns/gray90.png
new file mode 100644
index 0000000..603bf4f
--- /dev/null
+++ b/www/images/patterns/gray90.png
Binary files differ
diff --git a/www/images/patterns/gray95.png b/www/images/patterns/gray95.png
new file mode 100644
index 0000000..44e4234
--- /dev/null
+++ b/www/images/patterns/gray95.png
Binary files differ
diff --git a/www/images/patterns/hexagons.png b/www/images/patterns/hexagons.png
new file mode 100644
index 0000000..e8decf7
--- /dev/null
+++ b/www/images/patterns/hexagons.png
Binary files differ
diff --git a/www/images/patterns/horizontal.png b/www/images/patterns/horizontal.png
new file mode 100644
index 0000000..05ffcf5
--- /dev/null
+++ b/www/images/patterns/horizontal.png
Binary files differ
diff --git a/www/images/patterns/horizontalsaw.png b/www/images/patterns/horizontalsaw.png
new file mode 100644
index 0000000..e843e95
--- /dev/null
+++ b/www/images/patterns/horizontalsaw.png
Binary files differ
diff --git a/www/images/patterns/hs_bdiagonal.png b/www/images/patterns/hs_bdiagonal.png
new file mode 100644
index 0000000..f91cf3e
--- /dev/null
+++ b/www/images/patterns/hs_bdiagonal.png
Binary files differ
diff --git a/www/images/patterns/hs_cross.png b/www/images/patterns/hs_cross.png
new file mode 100644
index 0000000..4e8c8c7
--- /dev/null
+++ b/www/images/patterns/hs_cross.png
Binary files differ
diff --git a/www/images/patterns/hs_diagcross.png b/www/images/patterns/hs_diagcross.png
new file mode 100644
index 0000000..187f0b8
--- /dev/null
+++ b/www/images/patterns/hs_diagcross.png
Binary files differ
diff --git a/www/images/patterns/hs_fdiagonal.png b/www/images/patterns/hs_fdiagonal.png
new file mode 100644
index 0000000..7b2f08e
--- /dev/null
+++ b/www/images/patterns/hs_fdiagonal.png
Binary files differ
diff --git a/www/images/patterns/hs_horizontal.png b/www/images/patterns/hs_horizontal.png
new file mode 100644
index 0000000..56ab041
--- /dev/null
+++ b/www/images/patterns/hs_horizontal.png
Binary files differ
diff --git a/www/images/patterns/hs_vertical.png b/www/images/patterns/hs_vertical.png
new file mode 100644
index 0000000..37bafbb
--- /dev/null
+++ b/www/images/patterns/hs_vertical.png
Binary files differ
diff --git a/www/images/patterns/left30.png b/www/images/patterns/left30.png
new file mode 100644
index 0000000..573677e
--- /dev/null
+++ b/www/images/patterns/left30.png
Binary files differ
diff --git a/www/images/patterns/left45.png b/www/images/patterns/left45.png
new file mode 100644
index 0000000..7b2f08e
--- /dev/null
+++ b/www/images/patterns/left45.png
Binary files differ
diff --git a/www/images/patterns/leftshingle.png b/www/images/patterns/leftshingle.png
new file mode 100644
index 0000000..b9fe822
--- /dev/null
+++ b/www/images/patterns/leftshingle.png
Binary files differ
diff --git a/www/images/patterns/octagons.png b/www/images/patterns/octagons.png
new file mode 100644
index 0000000..3e93a45
--- /dev/null
+++ b/www/images/patterns/octagons.png
Binary files differ
diff --git a/www/images/patterns/right30.png b/www/images/patterns/right30.png
new file mode 100644
index 0000000..b550d85
--- /dev/null
+++ b/www/images/patterns/right30.png
Binary files differ
diff --git a/www/images/patterns/right45.png b/www/images/patterns/right45.png
new file mode 100644
index 0000000..f91cf3e
--- /dev/null
+++ b/www/images/patterns/right45.png
Binary files differ
diff --git a/www/images/patterns/rightshingle.png b/www/images/patterns/rightshingle.png
new file mode 100644
index 0000000..2d679f0
--- /dev/null
+++ b/www/images/patterns/rightshingle.png
Binary files differ
diff --git a/www/images/patterns/rose.png b/www/images/patterns/rose.png
new file mode 100644
index 0000000..f002ecf
--- /dev/null
+++ b/www/images/patterns/rose.png
Binary files differ
diff --git a/www/images/patterns/smallfishscales.png b/www/images/patterns/smallfishscales.png
new file mode 100644
index 0000000..faf7405
--- /dev/null
+++ b/www/images/patterns/smallfishscales.png
Binary files differ
diff --git a/www/images/patterns/vertical.png b/www/images/patterns/vertical.png
new file mode 100644
index 0000000..3f83769
--- /dev/null
+++ b/www/images/patterns/vertical.png
Binary files differ
diff --git a/www/images/patterns/verticalbricks.png b/www/images/patterns/verticalbricks.png
new file mode 100644
index 0000000..d4d8c22
--- /dev/null
+++ b/www/images/patterns/verticalbricks.png
Binary files differ
diff --git a/www/images/patterns/verticalleftshingle.png b/www/images/patterns/verticalleftshingle.png
new file mode 100644
index 0000000..4c931b1
--- /dev/null
+++ b/www/images/patterns/verticalleftshingle.png
Binary files differ
diff --git a/www/images/patterns/verticalrightshingle.png b/www/images/patterns/verticalrightshingle.png
new file mode 100644
index 0000000..118c242
--- /dev/null
+++ b/www/images/patterns/verticalrightshingle.png
Binary files differ
diff --git a/www/images/patterns/verticalsaw.png b/www/images/patterns/verticalsaw.png
new file mode 100644
index 0000000..b6579f6
--- /dev/null
+++ b/www/images/patterns/verticalsaw.png
Binary files differ
diff --git a/www/images/right_triangle.png b/www/images/right_triangle.png
new file mode 100644
index 0000000..3bd8fd7
--- /dev/null
+++ b/www/images/right_triangle.png
Binary files differ
diff --git a/www/images/right_triangle_option.png b/www/images/right_triangle_option.png
new file mode 100644
index 0000000..3bd8fd7
--- /dev/null
+++ b/www/images/right_triangle_option.png
Binary files differ
diff --git a/www/import.html b/www/import.html
new file mode 100644
index 0000000..559c66f
--- /dev/null
+++ b/www/import.html
@@ -0,0 +1,671 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="import"></a>gm import
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="imp-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+import - capture some or all of an X server screen and save the image to
+a file.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="imp-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#imp-desc">Description</a>
+</dt>
+<dt>
+<a href="#imp-exam">Examples</a>
+</dt>
+<dt>
+<a href="#imp-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="imp-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm import</strong> <strong>[</strong> <em>options</em> <strong>... ]</strong> <em>file</em>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="imp-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Import</strong> reads an image from any visible window on an X server and
+outputs it as an image file. You can capture a single window, the entire
+screen, or any rectangular portion of the screen.
+Use <em><a href="display.html">display</a></em>
+for redisplay, printing, editing, formatting, archiving, image processing,
+etc. of the captured image.
+<p>
+The target window can be specified by id, name, or may be selected
+by clicking the mouse in the desired window. If you press a button and
+then drag, a rectangle will form which expands and contracts as the mouse
+moves. To save the portion of the screen defined by the rectangle, just
+release the button. The keyboard bell is rung once at the beginning of
+the screen capture and twice when it completes.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="imp-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To select an X window or an area of the screen with the mouse and save it
+in the MIFF image format to a file entitled window.miff, use:
+<pre>
+ gm import window.miff
+</pre>
+<p>
+To select an X window or an area of the screen with the mouse and save it
+in the Encapsulated PostScript format to include in another document, use:
+<pre>
+ gm import figure.eps
+</pre>
+<p>
+To capture the entire X server screen in the JPEG image format in a file
+entitled root.jpeg, without using the mouse, use:
+<pre>
+ gm import -window root root.jpeg
+</pre>
+<p>
+To capture the 512x256 area at the upper right corner of the X server
+screen in the PNG image format in a well-compressed file entitled corner.png,
+without using the mouse, use:
+<pre>
+ gm import -window root -crop 512x256-0+0 -quality 90
+ corner.png
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="imp-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect until it is explicitly changed by specifying
+the option again with a different effect.
+<p>
+<strong>Import</strong> options can appear on the command line or in your
+X resources file. See <em>X(1)</em>. Options on the command line supersede
+values specified in your X resources file.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -descend
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>obtain image by descending window hierarchy</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -frame
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>include the X window frame in the imported image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pause">-pause</a> <i>&lt;seconds&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pause between snapshots [import]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -ping
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>efficiently determine image characteristics</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scene">-scene</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-screen">-screen</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the screen to capture</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -silent
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>operate silently</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-snaps">-snaps</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>number of screen snapshots</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transparent">-transparent</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
diff --git a/www/index.html b/www/index.html
new file mode 100644
index 0000000..03952c0
--- /dev/null
+++ b/www/index.html
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Image Processing System</title>
+<meta content="GraphicsMagick is a robust collection of tools and libraries to read, write, and manipulate an image in any of the more popular image formats including GIF, JPEG, PNG, PDF, and WebP. With GraphicsMagick you can create GIFs dynamically making it suitable for Web applications. You can also resize, rotate, sharpen, color reduce, or add special effects to an image and save your completed work in the same or different image format. " name="description" />
+<meta content="GraphicsMagick, ImageMagick, PerlMagick, image processing, OpenMP software development library, image, photo, software, Magick++, TclMagick" name="keywords" />
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-image-processing-system">
+<h1 class="title">GraphicsMagick Image Processing System</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<table border="1" class="docutils">
+<colgroup>
+<col width="33%" />
+<col width="67%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Current Release</td>
+<td>1.3.26 (Released July 4, 2017) <a class="reference external" href="http://sourceforge.net/projects/graphicsmagick/files/">download release</a></td>
+</tr>
+<tr><td>Development Snapshots</td>
+<td>(Updated frequently) <a class="reference external" href="ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/snapshots/">download development snapshots</a></td>
+</tr>
+<tr><td>Mercurial Repository</td>
+<td>(Updated frequently) <a class="reference external" href="http://sourceforge.net/p/graphicsmagick/code/">visit Mercurial repository</a></td>
+</tr>
+</tbody>
+</table>
+<p>Check <a class="reference external" href="http://www.GraphicsMagick.org/">http://www.GraphicsMagick.org/</a> for the latest version of this page.</p>
+<p>GraphicsMagick is the swiss army knife of image processing. Comprised
+of 267K physical lines (according to David A. Wheeler's <a class="reference external" href="http://www.dwheeler.com/sloccount/">SLOCCount</a>)
+of source code in the base package (or 1,225K including 3rd party
+libraries) it provides a robust and efficient collection of tools and
+libraries which support reading, writing, and manipulating an image in
+over 88 major formats including important formats like DPX, GIF, JPEG,
+JPEG-2000, PNG, PDF, PNM, and TIFF.</p>
+<p>Image processing is multi-threaded (<a class="reference external" href="OpenMP.html">see the multi-thread benchmark
+results</a>) using <a class="reference external" href="http://www.openmp.org/">OpenMP</a> so that CPU-bound tasks scale linearly as
+processor cores are added. <a class="reference external" href="http://www.openmp.org/">OpenMP</a> support requires compilation with
+GCC 4.2 (or later), or use of any C compiler supporting at least the
+<a class="reference external" href="http://www.openmp.org/">OpenMP</a> 2.0 specification.</p>
+<p>GraphicsMagick is quite portable, and compiles under almost every general
+purpose operating system that runs on 32-bit or 64-bit CPUs.
+GraphicsMagick is available for virtually any Unix or Unix-like system,
+including Linux. It also runs under <a class="reference external" href="INSTALL-windows.html">Windows</a>
+2000 and later (Windows 2000, XP, Vista, 7, 8.X, 10), and MacOS-X.</p>
+<p>GraphicsMagick supports huge images and has been tested with
+gigapixel-size images. GraphicsMagick can create new images on the
+fly, making it suitable for building dynamic Web
+applications. GraphicsMagick may be used to resize, rotate, sharpen,
+color reduce, or add special effects to an image and save the result
+in the same or different image format. Image processing operations are
+available from the command line, as well as through C, C++, Lua, Perl,
+PHP, Python, Tcl, Ruby, Windows .NET, or Windows COM programming
+interfaces. With some modification, language extensions for
+ImageMagick may be used.</p>
+<p>GraphicsMagick is originally derived from <a class="reference external" href="http://www.imagemagick.org/">ImageMagick</a> 5.5.2 as of
+November 2002 but has been completely independent of the ImageMagick
+project since then. Since the fork from ImageMagick many improvements
+have been made (see <a class="reference external" href="NEWS.html">NEWS</a>) by many <a class="reference external" href="authors.html">authors</a> using an open
+development model but without breaking the API or utilities operation.</p>
+<p>Here are some reasons to prefer GraphicsMagick over ImageMagick:</p>
+<blockquote>
+<ul class="simple">
+<li>GM is more efficient so it gets the job done faster using fewer
+resources.</li>
+<li>GM is much smaller and lighter (3-5X smaller installation footprint).</li>
+<li>GM is used to process billions of files at the world's largest photo
+sites (e.g. <a class="reference external" href="http://www.kitchensoap.com/2009/04/03/slides-from-web20-expo-2009-and-somethin-else-interestin/">Flickr</a> and <a class="reference external" href="http://codeascraft.etsy.com/2010/07/09/batch-processing-millions-of-images/">Etsy</a>).</li>
+<li>GM does not conflict with other installed software.</li>
+<li>GM suffers from fewer security issues and exploits.</li>
+<li>GM <a class="reference external" href="http://www.valgrind.org/">valgrind</a>'s 100% clean (memcheck and helgrind).</li>
+<li>GM passes rigorous memory error testing using <cite>ASan_</cite>.</li>
+<li>GM comes with a comprehensive <a class="reference external" href="GraphicsMagick.html">manual page</a>.</li>
+<li>GM provides API and ABI stability and managed releases that you can
+count on.</li>
+<li>GM provides detailed yet comprehensible <a class="reference external" href="Changelog.html">ChangeLog</a> and <a class="reference external" href="NEWS.html">NEWS</a> files.</li>
+<li>GM is available for free, and may be used to support both open and
+proprietary applications.</li>
+<li>GM is distributed under an X11-style license (<a class="reference external" href="http://opensource.org/licenses/MIT">MIT License</a>),
+approved by the <a class="reference external" href="http://www.opensource.org/">Open Source Initiative</a>, recommended for use by
+the <a class="reference external" href="http://www.osscc.net/en/index.html">OSSCC</a>, and compatible with the <a class="reference external" href="http://www.fsf.org/licenses/licenses.html">GNU GPL</a>.</li>
+<li>GM source code is managed in <a class="reference external" href="https://www.mercurial-scm.org/">Mercurial</a>, a distributed source
+control management tool which supports management of local
+changes.</li>
+<li>GM has 0.00 (zero) defects per 1000 lines of code (293,341 total
+lines included) according to Coverity analysis on May 25, 2015.</li>
+<li>GM developers contribute to other free projects for the public good.</li>
+</ul>
+</blockquote>
+<p>GraphicsMagick is <a class="reference external" href="Copyright.html">copyrighted</a> by the GraphicsMagick
+Group as well as many others.</p>
+<p>Here are just a few examples of what GraphicsMagick can do:</p>
+<blockquote>
+<ul class="simple">
+<li>Convert an image from one format to another (e.g. TIFF to JPEG)</li>
+<li>Resize, rotate, sharpen, color reduce, or add special effects to an
+image</li>
+<li>Create a montage of image thumbnails</li>
+<li>Create a transparent image suitable for use on the Web</li>
+<li>Compare two images</li>
+<li>Turn a group of images into a GIF animation sequence</li>
+<li>Create a composite image by combining several separate images</li>
+<li>Draw shapes or text on an image</li>
+<li>Decorate an image with a border or frame</li>
+<li>Describe the format and characteristics of an image</li>
+</ul>
+</blockquote>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/index.rst b/www/index.rst
new file mode 100644
index 0000000..0413a07
--- /dev/null
+++ b/www/index.rst
@@ -0,0 +1,171 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+======================================
+GraphicsMagick Image Processing System
+======================================
+
+.. meta::
+ :description: GraphicsMagick is a robust collection of tools and libraries to read,
+ write, and manipulate an image in any of the more popular
+ image formats including GIF, JPEG, PNG, PDF, and WebP.
+ With GraphicsMagick you can create GIFs dynamically making it
+ suitable for Web applications. You can also resize, rotate,
+ sharpen, color reduce, or add special effects to an image and
+ save your completed work in the same or different image format.
+
+ :keywords: GraphicsMagick, ImageMagick, PerlMagick, image processing, OpenMP
+ software development library, image, photo, software, Magick++,
+ TclMagick
+
+
+.. _download GraphicsMagick release : http://sourceforge.net/projects/graphicsmagick/files/
+.. _`download development snapshots` : ftp://ftp.graphicsmagick.org/pub/GraphicsMagick/snapshots/
+.. _`visit Mercurial repository`: http://sourceforge.net/p/graphicsmagick/code/
+
+.. _programming : programming.html
+
+=========================== ========================================================
+Current Release 1.3.26 (Released July 4, 2017) `download release`__
+Development Snapshots (Updated frequently) `download development snapshots`__
+Mercurial Repository (Updated frequently) `visit Mercurial repository`__
+=========================== ========================================================
+
+__ `download GraphicsMagick release`_
+__ `download development snapshots`_
+__ `visit Mercurial repository`_
+
+
+Check http://www.GraphicsMagick.org/ for the latest version of this page.
+
+.. _FSF : http://www.fsf.org/
+.. _`GNU GPL` : http://www.fsf.org/licenses/licenses.html
+.. _ImageMagick : http://www.imagemagick.org/
+.. _Open Source Initiative : http://www.opensource.org/
+.. _`MIT License` : http://opensource.org/licenses/MIT
+.. _OSSCC : http://www.osscc.net/en/index.html
+.. _OpenMP : http://www.openmp.org/
+.. _`see the multi-thread benchmark results` : OpenMP.html
+.. _`ChangeLog` : Changelog.html
+.. _`Flickr` : http://www.kitchensoap.com/2009/04/03/slides-from-web20-expo-2009-and-somethin-else-interestin/
+.. _`Etsy` : http://codeascraft.etsy.com/2010/07/09/batch-processing-millions-of-images/
+.. _`John Allspaw's presentation` : http://www.kitchensoap.com/2009/04/03/slides-from-web20-expo-2009-and-somethin-else-interestin/
+.. _Mercurial : https://www.mercurial-scm.org/
+.. _`NEWS` : NEWS.html
+.. _`SLOCCount` : http://www.dwheeler.com/sloccount/
+.. _`authors` : authors.html
+.. _`benchmarks` : benchmarks.html
+.. _`manual page` : GraphicsMagick.html
+.. _`valgrind` : http://www.valgrind.org/
+.. _'ASan' : https://github.com/google/sanitizers/wiki/AddressSanitizer
+
+GraphicsMagick is the swiss army knife of image processing. Comprised
+of 267K physical lines (according to David A. Wheeler's `SLOCCount`_)
+of source code in the base package (or 1,225K including 3rd party
+libraries) it provides a robust and efficient collection of tools and
+libraries which support reading, writing, and manipulating an image in
+over 88 major formats including important formats like DPX, GIF, JPEG,
+JPEG-2000, PNG, PDF, PNM, and TIFF.
+
+Image processing is multi-threaded (`see the multi-thread benchmark
+results`_) using OpenMP_ so that CPU-bound tasks scale linearly as
+processor cores are added. OpenMP_ support requires compilation with
+GCC 4.2 (or later), or use of any C compiler supporting at least the
+OpenMP_ 2.0 specification.
+
+GraphicsMagick is quite portable, and compiles under almost every general
+purpose operating system that runs on 32-bit or 64-bit CPUs.
+GraphicsMagick is available for virtually any Unix or Unix-like system,
+including Linux. It also runs under `Windows <INSTALL-windows.html>`_
+2000 and later (Windows 2000, XP, Vista, 7, 8.X, 10), and MacOS-X.
+
+GraphicsMagick supports huge images and has been tested with
+gigapixel-size images. GraphicsMagick can create new images on the
+fly, making it suitable for building dynamic Web
+applications. GraphicsMagick may be used to resize, rotate, sharpen,
+color reduce, or add special effects to an image and save the result
+in the same or different image format. Image processing operations are
+available from the command line, as well as through C, C++, Lua, Perl,
+PHP, Python, Tcl, Ruby, Windows .NET, or Windows COM programming
+interfaces. With some modification, language extensions for
+ImageMagick may be used.
+
+GraphicsMagick is originally derived from ImageMagick_ 5.5.2 as of
+November 2002 but has been completely independent of the ImageMagick
+project since then. Since the fork from ImageMagick many improvements
+have been made (see `NEWS`_) by many `authors`_ using an open
+development model but without breaking the API or utilities operation.
+
+Here are some reasons to prefer GraphicsMagick over ImageMagick:
+
+ * GM is more efficient so it gets the job done faster using fewer
+ resources.
+
+ * GM is much smaller and lighter (3-5X smaller installation footprint).
+
+ * GM is used to process billions of files at the world's largest photo
+ sites (e.g. `Flickr`_ and `Etsy`_).
+
+ * GM does not conflict with other installed software.
+
+ * GM suffers from fewer security issues and exploits.
+
+ * GM `valgrind`_'s 100% clean (memcheck and helgrind).
+
+ * GM passes rigorous memory error testing using `ASan_`.
+
+ * GM comes with a comprehensive `manual page`_.
+
+ * GM provides API and ABI stability and managed releases that you can
+ count on.
+
+ * GM provides detailed yet comprehensible `ChangeLog`_ and `NEWS`_ files.
+
+ * GM is available for free, and may be used to support both open and
+ proprietary applications.
+
+ * GM is distributed under an X11-style license (`MIT License`_),
+ approved by the `Open Source Initiative`_, recommended for use by
+ the `OSSCC`_, and compatible with the `GNU GPL`_.
+
+ * GM source code is managed in Mercurial_, a distributed source
+ control management tool which supports management of local
+ changes.
+
+ * GM has 0.00 (zero) defects per 1000 lines of code (293,341 total
+ lines included) according to Coverity analysis on May 25, 2015.
+
+ * GM developers contribute to other free projects for the public good.
+
+GraphicsMagick is `copyrighted <Copyright.html>`_ by the GraphicsMagick
+Group as well as many others.
+
+Here are just a few examples of what GraphicsMagick can do:
+
+ * Convert an image from one format to another (e.g. TIFF to JPEG)
+
+ * Resize, rotate, sharpen, color reduce, or add special effects to an
+ image
+
+ * Create a montage of image thumbnails
+
+ * Create a transparent image suitable for use on the Web
+
+ * Compare two images
+
+ * Turn a group of images into a GIF animation sequence
+
+ * Create a composite image by combining several separate images
+
+ * Draw shapes or text on an image
+
+ * Decorate an image with a border or frame
+
+ * Describe the format and characteristics of an image
+
+------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/links.html b/www/links.html
new file mode 100644
index 0000000..b2bbfc6
--- /dev/null
+++ b/www/links.html
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Related Links</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="related-links">
+<h1 class="title">Related Links</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#graphicsmagick-topics" id="id6">GraphicsMagick Topics</a></li>
+<li><a class="reference internal" href="#graphicsmagick-vulnerabilities" id="id7">GraphicsMagick Vulnerabilities</a></li>
+<li><a class="reference internal" href="#image-processing-topics" id="id8">Image Processing Topics</a></li>
+<li><a class="reference internal" href="#color-technology-related-topics" id="id9">Color Technology Related Topics</a></li>
+<li><a class="reference internal" href="#gamma-related-topics" id="id10">Gamma Related Topics</a></li>
+<li><a class="reference internal" href="#tiff-related-topics" id="id11">TIFF Related Topics</a></li>
+<li><a class="reference internal" href="#jpeg-related-topics" id="id12">JPEG Related Topics</a></li>
+<li><a class="reference internal" href="#dicom-related-topics" id="id13">DICOM Related Topics</a></li>
+<li><a class="reference internal" href="#metadata-associated-data-topics" id="id14">Metadata (Associated Data) Topics</a></li>
+<li><a class="reference internal" href="#high-dynamic-range-topics" id="id15">High Dynamic Range Topics</a></li>
+<li><a class="reference internal" href="#motion-picture-links" id="id16">Motion Picture Links</a></li>
+<li><a class="reference internal" href="#video-topics" id="id17">Video Topics</a></li>
+<li><a class="reference internal" href="#other-software-packages" id="id18">Other Software Packages</a></li>
+<li><a class="reference internal" href="#stock-photos" id="id19">Stock Photos</a></li>
+</ul>
+</div>
+<div class="section" id="graphicsmagick-topics">
+<h1><a class="toc-backref" href="#id6">GraphicsMagick Topics</a></h1>
+<p><a class="reference external" href="http://directory.fsf.org/project/GraphicsMagick/">Free Software Foundation</a> GraphicsMagick Entry.</p>
+<p><a class="reference external" href="https://www.freshports.org/graphics/GraphicsMagick/">FreeBSD port</a> for GraphicsMagick.</p>
+<p><a class="reference external" href="http://pkgsrc.se/graphics/GraphicsMagick/">NetBSD/pkgsrc port</a> for GraphicsMagick.</p>
+<p><a class="reference external" href="http://freecode.com/projects/graphicsmagick">Free (code)</a> GraphicsMagick Entry. (Frozen Site).</p>
+<p><a class="reference external" href="http://dir.gmane.org/gmane.comp.video.graphicsmagick.announce">Gmane</a> GraphicsMagick Announce List.</p>
+<p><a class="reference external" href="http://bugs.gentoo.org/show_bug.cgi?id=190372">Gentoo Sunrise</a> Bug Tracker Entry.</p>
+<p><a class="reference external" href="https://bugzilla.redhat.com/buglist.cgi?component=GraphicsMagick&amp;product=Fedora">Red Hat Linux</a> GraphicsMagick related bugs.</p>
+<p>Debian <a class="reference external" href="http://packages.debian.org/search?keywords=GraphicsMagick&amp;amp;searchon=names&amp;amp;suite=all&amp;amp;section=main">GraphicsMagick packages</a>.</p>
+<p><a class="reference external" href="http://en.wikipedia.org/wiki/GraphicsMagick">WikiPedia</a> GraphicsMagick Entry.</p>
+<p><a class="reference external" href="http://www.openhub.net/p/GraphicsMagick">Black Duck | Open HUB</a> GraphicsMagick Entry.</p>
+<p><a class="reference external" href="http://sourceforge.net/projects/graphicsmagick/">SourceForge</a> GraphicsMagick Entry.</p>
+<p><a class="reference external" href="http://stackoverflow.com/questions/tagged/graphicsmagick?">GraphicsMagick questions on StackOverflow</a>.</p>
+<p><a class="reference external" href="https://abi-laboratory.pro/tracker/timeline/graphicsmagick/">GraphicsMagick ABI/API Changes</a>.</p>
+</div>
+<div class="section" id="graphicsmagick-vulnerabilities">
+<h1><a class="toc-backref" href="#id7">GraphicsMagick Vulnerabilities</a></h1>
+<p>Search the CVE site at MITRE for <a class="reference external" href="http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=GraphicsMagick">GraphicsMagick</a> vulnerabilities (seems to be stale).</p>
+<p>Seach SecurityFocus Bugtraq for <a class="reference external" href="http://www.securityfocus.com/bid">GraphicsMagick</a> vulnerabilities (select Vendor 'GraphicsMagick').</p>
+<p>Debian vulnerabilities in <a class="reference external" href="https://security-tracker.debian.org/tracker/source-package/graphicsmagick">GraphicsMagick</a>.</p>
+</div>
+<div class="section" id="image-processing-topics">
+<h1><a class="toc-backref" href="#id8">Image Processing Topics</a></h1>
+<p><a class="reference external" href="http://homepages.inf.ed.ac.uk/rbf/HIPR2/">HyperMedia Image Processing Reference</a>,
+A guide to image processing algorithms, many of which are supported by GraphicsMagick.</p>
+</div>
+<div class="section" id="color-technology-related-topics">
+<h1><a class="toc-backref" href="#id9">Color Technology Related Topics</a></h1>
+<p>Charles Poynton's <a class="reference external" href="http://www.poynton.com/Poynton-color.html">Color technology FAQs</a>,
+very useful documentation on color technologies.</p>
+<p><a class="reference external" href="http://www.color.org/">International Color Consortium</a>,
+the organization responsible for color profile standards.</p>
+<p><a class="reference external" href="http://www.argyllcms.com/">Argyll Color Management System</a>,
+a free experimental color management system.</p>
+<p><a class="reference external" href="http://www.littlecms.com/">Littlecms</a>,
+a free commercial-grade colormanagement engine in 100K (and used by GraphicsMagick).</p>
+<p><a class="reference external" href="http://www.brucelindbloom.com/">Bruce Lindbloom's Web Site</a>,
+offering interesting information related to color science and working spaces.</p>
+<p><a class="reference external" href="http://www.w3.org/Graphics/Color/sRGB.html">sRGB</a>,
+A standard default color space for the Internet.</p>
+<p><a class="reference external" href="http://www.anyhere.com/gward/hdrenc/hdr_encodings.html">High Dynamic Range Image Encodings</a>,
+an analysis by Greg Ward of various HDR encodings.</p>
+</div>
+<div class="section" id="gamma-related-topics">
+<h1><a class="toc-backref" href="#id10">Gamma Related Topics</a></h1>
+<p>While most computer images are encoded with a gamma of 2.2 (really 2.2
+to 2.6), GraphicsMagick does not attempt to convert images to
+linear-light before applying image processing operations since it is
+not possible to know for sure to know how to do so. Some algorithms
+such as resize, blur, and composition, will produce more accurate
+results when performed on images encoded in a linear-light scaled
+space.</p>
+<p>For a typical sRGB image encoded in a gamma-corrected space with gamma
+2.2, the option <tt class="docutils literal"><span class="pre">-gamma</span> 0.45</tt> (1/2.2 = 0.45) will remove that
+encoding for subsequent algorithms so that they are done in
+linear-light space. When processing is completed, then <tt class="docutils literal"><span class="pre">-gamma</span> 2.2</tt>
+will restore gamma-correction for viewing. It is recommended to use a
+Q16 or Q32 build of GraphicsMagick when doing this since linear-light
+space encoding is not efficient and will lose accuracy if stored with
+less than 14 bits per sample.</p>
+<p>The following documents and pages provide interesting information on
+gamma-related topics:</p>
+<p><a class="reference external" href="http://www.poynton.com/GammaFAQ.html">Charles Poynton's Gamma FAQ</a>,
+provides an excellent description of what gamma is, why it is good,
+and when you don't want it.</p>
+<p><a class="reference external" href="http://www.4p8.com/eric.brasseur/gamma.html">Gamma error in picture scaling</a>, provides a discussion
+of how image resize on gamma-corrected images can cause distortion.</p>
+</div>
+<div class="section" id="tiff-related-topics">
+<h1><a class="toc-backref" href="#id11">TIFF Related Topics</a></h1>
+<p><a class="reference external" href="http://www.simplesystems.org/libtiff/">LibTIFF</a>,
+Libtiff library and TIFF format mailing list.</p>
+<p>AWare Systems <a class="reference external" href="http://www.awaresystems.be/imaging/tiff.html">TIFF</a> site.
+Detailed TIFF-related information which goes beyond the TIFF specification,
+list archives for the libtiff mailing list, and information regarding the emerging Big TIFF format.</p>
+<p><a class="reference external" href="http://www.adobe.com/products/dng/index.html">Digital Negative (DNG)</a>,
+Adobe TIFF specification for digital camera raw images.</p>
+<p><a class="reference external" href="http://www.anyhere.com/gward/pixformat/tiffluv.html">LogLuv Encoding for TIFF Images</a>,
+A way to store HDR images using TIFF.</p>
+</div>
+<div class="section" id="jpeg-related-topics">
+<h1><a class="toc-backref" href="#id12">JPEG Related Topics</a></h1>
+<p><a class="reference external" href="http://www.ijg.org/">Independent JPEG Group</a> (home of IJG JPEG library).</p>
+<p><a class="reference external" href="http://jpegclub.org/">Guido Vollbeding's JPEG site</a>, including various patches to IJG JPEG release 6b.</p>
+</div>
+<div class="section" id="dicom-related-topics">
+<h1><a class="toc-backref" href="#id13">DICOM Related Topics</a></h1>
+<p><a class="reference external" href="http://www.dclunie.com/">David Clunie's Medical Image Format Site</a>,
+information about medical images.</p>
+</div>
+<div class="section" id="metadata-associated-data-topics">
+<h1><a class="toc-backref" href="#id14">Metadata (Associated Data) Topics</a></h1>
+<p><a class="reference external" href="http://www.adobe.com/products/xmp/index.html">Extensible Metadata Platform (XMP)</a>,
+Adobe's XML-based embedded metadata format.</p>
+<p><a class="reference external" href="http://www.exif.org/">EXIF</a>,
+Format for metadata in images, particularly JPEG files from digital cameras.</p>
+</div>
+<div class="section" id="high-dynamic-range-topics">
+<h1><a class="toc-backref" href="#id15">High Dynamic Range Topics</a></h1>
+<p><a class="reference external" href="http://www.anyhere.com/gward/hdrenc/hdr_encodings.html">High Dynamic Range Image Encodings</a>,
+An analsys by Greg Ward of various HDR encodings.</p>
+<p><a class="reference external" href="http://www.anyhere.com/gward/pixformat/tiffluv.html">LogLuv Encoding for TIFF Images</a>,
+A way to store HDR images using TIFF.</p>
+<p><a class="reference external" href="http://www.openexr.com/">OpenEXR</a>,
+library and sample tools for dealing with high dynamic-range (HDR) images.</p>
+</div>
+<div class="section" id="motion-picture-links">
+<h1><a class="toc-backref" href="#id16">Motion Picture Links</a></h1>
+<p><a class="reference external" href="http://www.lightillusion.com/home.htm">Light Illusion</a>,
+white papers by Steve Shaw regarding HD video cameras, log color spaces, and digital intermediate.</p>
+<p><a class="reference external" href="http://www.digitalintermediates.org/">Digital Intermediates</a>,
+site by Jack James dedicated to the digital intermediate industry.</p>
+<p><a class="reference external" href="http://www.dcimovies.com/">Digital Cinema Initiatives</a>,
+DCI offers the first complete specification for digital cinema delivery.</p>
+<p><a class="reference external" href="http://ingex.sourceforge.net/index.html">Ingex</a> Tapeless video &amp;
+audio capture, transcoding and network file serving. From the BBC.</p>
+</div>
+<div class="section" id="video-topics">
+<h1><a class="toc-backref" href="#id17">Video Topics</a></h1>
+<p><a class="reference external" href="http://www.fourcc.org/">Video Codecs and Pixel Formats</a>, offers a summary of YUV encoding formats.</p>
+</div>
+<div class="section" id="other-software-packages">
+<h1><a class="toc-backref" href="#id18">Other Software Packages</a></h1>
+<p><a class="reference external" href="http://dmmd.net/main_wp/visere/">DMMD Visere</a>,
+truly outstanding image viewing/browsing software for Microsoft Windows.
+Visere is based on GraphicsMagick.</p>
+<p><a class="reference external" href="http://www.cinepaint.org/">CinePaint</a>,
+GIMP-derived software targeted for the motion picture industry, and for other
+applications which require high color resolution.</p>
+<p><a class="reference external" href="http://elynxlab.free.fr/en/index.html">eLynx lab</a> High resolution image processing tool.</p>
+<p>The <a class="reference external" href="http://www.gimp.org/">GIMP</a>, interactive image editing software (like Photoshop).</p>
+<p><a class="reference external" href="http://www.imagemagick.org/">ImageMagick</a>, the ancestor of GraphicsMagick.</p>
+<p><a class="reference external" href="http://www.vips.ecs.soton.ac.uk/index.php?title=VIPS">VIPS</a>, an image processing system also useful with
+large images, and which comes with an unusual GUI.</p>
+<p><a class="reference external" href="http://freeimage.sourceforge.net/index.html">FreeImage</a>,
+a free image processing library.</p>
+<p><a class="reference external" href="http://rsbweb.nih.gov/ij/">ImageJ</a> Image Processing and Analysis in Java.</p>
+<p><a class="reference external" href="http://www.pstoedit.net/">Pstoedit</a>,
+A Postscript to editable vector translation utility.</p>
+<p><a class="reference external" href="http://ufraw.sourceforge.net/">UFRaw</a>,
+a utility to read and manipulate raw images from digital cameras.</p>
+<p><a class="reference external" href="http://lprof.sourceforge.net/index.html">LPROF</a>,
+an open source ICC profiler with graphical user interface.</p>
+<p><a class="reference external" href="http://gallery.menalto.com/">Gallery</a>,
+a facinating web-based photo album organizer. Works with GraphicsMagick!.</p>
+<p><a class="reference external" href="http://djv.sourceforge.net/">DJV Imaging</a>, professional movie
+playback and image processing software for the film and computer
+animation industries.</p>
+<p><a class="reference external" href="https://sites.google.com/site/openimageio/">OpenImageIO</a> library
+for reading and writing images, and a bunch of related classes,
+utilities, and applications.</p>
+</div>
+<div class="section" id="stock-photos">
+<h1><a class="toc-backref" href="#id19">Stock Photos</a></h1>
+<p><a class="reference external" href="http://www.morguefile.com/">MorgueFile</a>, Free high-resolution stock photo images.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/links.rst b/www/links.rst
new file mode 100644
index 0000000..0de1155
--- /dev/null
+++ b/www/links.rst
@@ -0,0 +1,251 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=====================
+Related Links
+=====================
+
+.. contents::
+
+GraphicsMagick Topics
+=====================
+
+`Free Software Foundation <http://directory.fsf.org/project/GraphicsMagick/>`_ GraphicsMagick Entry.
+
+`FreeBSD port <https://www.freshports.org/graphics/GraphicsMagick/>`_ for GraphicsMagick.
+
+`NetBSD/pkgsrc port <http://pkgsrc.se/graphics/GraphicsMagick/>`_ for GraphicsMagick.
+
+`Free (code) <http://freecode.com/projects/graphicsmagick>`_ GraphicsMagick Entry. (Frozen Site).
+
+`Gmane <http://dir.gmane.org/gmane.comp.video.graphicsmagick.announce>`_ GraphicsMagick Announce List.
+
+`Gentoo Sunrise <http://bugs.gentoo.org/show_bug.cgi?id=190372>`_ Bug Tracker Entry.
+
+`Red Hat Linux <https://bugzilla.redhat.com/buglist.cgi?component=GraphicsMagick&product=Fedora>`_ GraphicsMagick related bugs.
+
+Debian `GraphicsMagick packages <http://packages.debian.org/search?keywords=GraphicsMagick&amp;searchon=names&amp;suite=all&amp;section=main>`_.
+
+`WikiPedia <http://en.wikipedia.org/wiki/GraphicsMagick>`_ GraphicsMagick Entry.
+
+`Black Duck | Open HUB <http://www.openhub.net/p/GraphicsMagick>`_ GraphicsMagick Entry.
+
+`SourceForge <http://sourceforge.net/projects/graphicsmagick/>`_ GraphicsMagick Entry.
+
+`GraphicsMagick questions on StackOverflow <http://stackoverflow.com/questions/tagged/graphicsmagick?>`_.
+
+`GraphicsMagick ABI/API Changes <https://abi-laboratory.pro/tracker/timeline/graphicsmagick/>`_.
+
+
+GraphicsMagick Vulnerabilities
+==============================
+
+Search the CVE site at MITRE for `GraphicsMagick`__ vulnerabilities (seems to be stale).
+
+.. _CVE_GraphicsMagick : http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=GraphicsMagick
+
+__ CVE_GraphicsMagick_
+
+Seach SecurityFocus Bugtraq for `GraphicsMagick`__ vulnerabilities (select Vendor 'GraphicsMagick').
+
+__ Bugtraq_GraphicsMagick_
+
+.. _Bugtraq_GraphicsMagick : http://www.securityfocus.com/bid
+
+Debian vulnerabilities in `GraphicsMagick`__.
+
+.. _Debian_GraphicsMagick : https://security-tracker.debian.org/tracker/source-package/graphicsmagick
+
+__ Debian_GraphicsMagick_
+
+
+
+Image Processing Topics
+============================
+
+`HyperMedia Image Processing Reference <http://homepages.inf.ed.ac.uk/rbf/HIPR2/>`_,
+A guide to image processing algorithms, many of which are supported by GraphicsMagick.
+
+
+Color Technology Related Topics
+======================================
+
+Charles Poynton's `Color technology FAQs <http://www.poynton.com/Poynton-color.html>`_,
+very useful documentation on color technologies.
+
+`International Color Consortium <http://www.color.org/>`_,
+the organization responsible for color profile standards.
+
+`Argyll Color Management System <http://www.argyllcms.com/>`_,
+a free experimental color management system.
+
+`Littlecms <http://www.littlecms.com/>`_,
+a free commercial-grade colormanagement engine in 100K (and used by GraphicsMagick).
+
+`Bruce Lindbloom's Web Site <http://www.brucelindbloom.com/>`_,
+offering interesting information related to color science and working spaces.
+
+`sRGB <http://www.w3.org/Graphics/Color/sRGB.html>`_,
+A standard default color space for the Internet.
+
+`High Dynamic Range Image Encodings <http://www.anyhere.com/gward/hdrenc/hdr_encodings.html>`_,
+an analysis by Greg Ward of various HDR encodings.
+
+Gamma Related Topics
+======================================
+
+While most computer images are encoded with a gamma of 2.2 (really 2.2
+to 2.6), GraphicsMagick does not attempt to convert images to
+linear-light before applying image processing operations since it is
+not possible to know for sure to know how to do so. Some algorithms
+such as resize, blur, and composition, will produce more accurate
+results when performed on images encoded in a linear-light scaled
+space.
+
+For a typical sRGB image encoded in a gamma-corrected space with gamma
+2.2, the option ``-gamma 0.45`` (1/2.2 = 0.45) will remove that
+encoding for subsequent algorithms so that they are done in
+linear-light space. When processing is completed, then ``-gamma 2.2``
+will restore gamma-correction for viewing. It is recommended to use a
+Q16 or Q32 build of GraphicsMagick when doing this since linear-light
+space encoding is not efficient and will lose accuracy if stored with
+less than 14 bits per sample.
+
+The following documents and pages provide interesting information on
+gamma-related topics:
+
+`Charles Poynton's Gamma FAQ <http://www.poynton.com/GammaFAQ.html>`_,
+provides an excellent description of what gamma is, why it is good,
+and when you don't want it.
+
+`Gamma error in picture scaling
+<http://www.4p8.com/eric.brasseur/gamma.html>`_, provides a discussion
+of how image resize on gamma-corrected images can cause distortion.
+
+
+TIFF Related Topics
+============================
+
+`LibTIFF <http://www.simplesystems.org/libtiff/>`_,
+Libtiff library and TIFF format mailing list.
+
+AWare Systems `TIFF <http://www.awaresystems.be/imaging/tiff.html>`_ site.
+Detailed TIFF-related information which goes beyond the TIFF specification,
+list archives for the libtiff mailing list, and information regarding the emerging Big TIFF format.
+
+`Digital Negative (DNG) <http://www.adobe.com/products/dng/index.html>`_,
+Adobe TIFF specification for digital camera raw images.
+
+`LogLuv Encoding for TIFF Images <http://www.anyhere.com/gward/pixformat/tiffluv.html>`_,
+A way to store HDR images using TIFF.
+
+JPEG Related Topics
+==========================
+
+`Independent JPEG Group <http://www.ijg.org/>`_ (home of IJG JPEG library).
+
+`Guido Vollbeding's JPEG site <http://jpegclub.org/>`_, including various patches to IJG JPEG release 6b.
+
+DICOM Related Topics
+============================
+
+`David Clunie's Medical Image Format Site <http://www.dclunie.com/>`_,
+information about medical images.
+
+Metadata (Associated Data) Topics
+=========================================
+
+`Extensible Metadata Platform (XMP) <http://www.adobe.com/products/xmp/index.html>`_,
+Adobe's XML-based embedded metadata format.
+
+`EXIF <http://www.exif.org/>`_,
+Format for metadata in images, particularly JPEG files from digital cameras.
+
+High Dynamic Range Topics
+==========================
+
+`High Dynamic Range Image Encodings <http://www.anyhere.com/gward/hdrenc/hdr_encodings.html>`_,
+An analsys by Greg Ward of various HDR encodings.
+
+`LogLuv Encoding for TIFF Images <http://www.anyhere.com/gward/pixformat/tiffluv.html>`_,
+A way to store HDR images using TIFF.
+
+`OpenEXR <http://www.openexr.com/>`_,
+library and sample tools for dealing with high dynamic-range (HDR) images.
+
+Motion Picture Links
+=========================
+
+`Light Illusion <http://www.lightillusion.com/home.htm>`_,
+white papers by Steve Shaw regarding HD video cameras, log color spaces, and digital intermediate.
+
+`Digital Intermediates <http://www.digitalintermediates.org/>`_,
+site by Jack James dedicated to the digital intermediate industry.
+
+`Digital Cinema Initiatives <http://www.dcimovies.com/>`_,
+DCI offers the first complete specification for digital cinema delivery.
+
+`Ingex <http://ingex.sourceforge.net/index.html>`_ Tapeless video &
+audio capture, transcoding and network file serving. From the BBC.
+
+Video Topics
+=============
+
+`Video Codecs and Pixel Formats <http://www.fourcc.org/>`_, offers a summary of YUV encoding formats.
+
+Other Software Packages
+========================
+
+`DMMD Visere <http://dmmd.net/main_wp/visere/>`_,
+truly outstanding image viewing/browsing software for Microsoft Windows.
+Visere is based on GraphicsMagick.
+
+`CinePaint <http://www.cinepaint.org/>`_,
+GIMP-derived software targeted for the motion picture industry, and for other
+applications which require high color resolution.
+
+`eLynx lab <http://elynxlab.free.fr/en/index.html>`_ High resolution image processing tool.
+
+The `GIMP <http://www.gimp.org/>`_, interactive image editing software (like Photoshop).
+
+`ImageMagick <http://www.imagemagick.org/>`_, the ancestor of GraphicsMagick.
+
+`VIPS <http://www.vips.ecs.soton.ac.uk/index.php?title=VIPS>`_, an image processing system also useful with
+large images, and which comes with an unusual GUI.
+
+`FreeImage <http://freeimage.sourceforge.net/index.html>`_,
+a free image processing library.
+
+`ImageJ <http://rsbweb.nih.gov/ij/>`_ Image Processing and Analysis in Java.
+
+`Pstoedit <http://www.pstoedit.net/>`_,
+A Postscript to editable vector translation utility.
+
+`UFRaw <http://ufraw.sourceforge.net/>`_,
+a utility to read and manipulate raw images from digital cameras.
+
+`LPROF <http://lprof.sourceforge.net/index.html>`_,
+an open source ICC profiler with graphical user interface.
+
+`Gallery <http://gallery.menalto.com/>`_,
+a facinating web-based photo album organizer. Works with GraphicsMagick!.
+
+`DJV Imaging <http://djv.sourceforge.net/>`_, professional movie
+playback and image processing software for the film and computer
+animation industries.
+
+`OpenImageIO <https://sites.google.com/site/openimageio/>`_ library
+for reading and writing images, and a bunch of related classes,
+utilities, and applications.
+
+Stock Photos
+=============
+
+`MorgueFile <http://www.morguefile.com/>`_, Free high-resolution stock photo images.
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/magick.css b/www/magick.css
new file mode 100644
index 0000000..e0ad550
--- /dev/null
+++ b/www/magick.css
@@ -0,0 +1,176 @@
+/* magick.css -- standard style sheet */
+body, p, td, th, ul, ol {
+ font-family : sans-serif;
+ font-size : medium;
+}
+
+body {
+ color : #000000;
+ padding-bottom : 20px;
+ margin : 0;
+ background-color : #FFFFFF;
+ text-align : left;
+}
+
+
+h1 {
+ font-size : 120%;
+}
+
+h2 {
+ font-size : 110%;
+}
+
+h3, h4 {
+ font-size : 105%;
+}
+
+a:link {
+ text-decoration : underline;
+ color : #007F39;
+}
+
+a:visited {
+ text-decoration : underline;
+ color : #00602B;
+}
+
+a:hover {
+ color : #007F39;
+}
+
+.small {
+ font-size : smaller;
+}
+
+.tiny {
+ font-size : smaller;
+}
+
+div.banner {
+ padding : 2ex 0 1ex 5em;
+ overflow : hidden;
+ margin : 0;
+ background-color : #DFFFED;
+ border-bottom : 1px solid #3A4840;
+ border-top : 1px solid #3A4840;
+}
+
+div.banner img {
+ vertical-align : middle;
+ margin-left: 0em;
+}
+
+div.banner form {
+ margin-left: 2em;
+ text-align : center;
+ display : inline;
+}
+
+div.banner .title {
+ color : #3A604B;
+ font-size : 2.2em;
+ font-weight : bold;
+}
+
+div.banner .subtitle {
+ color : #023100;
+ font-size : 1em;
+ font-weight : normal;
+ margin-left : 1em;
+}
+
+div.navmenu {
+ font-size : 90%;
+ background-color : #3A604B;
+ border-bottom : 1px solid #75867D;
+ padding : 0;
+ margin : 0;
+ text-align : center;
+}
+
+div.navmenu ul {
+ padding : 5px;
+ margin : 0;
+}
+
+div.navmenu ul li {
+ padding : 0 .5em 0 .5em;
+ list-style-type : none;
+ margin : 0 0 0 4px;
+ display : inline;
+ text-align : center;
+}
+
+div.navmenu ul li a {
+ color : #FFFFFF;
+ text-decoration : none;
+}
+
+div.navmenu ul li a:hover {
+ border-bottom : 1px solid #FFFFFF;
+}
+
+div.main {
+ height : auto;
+ padding : 1em;
+ width : auto;
+ background : #FFFFFF;
+ max-width : 960px;
+ margin : 2ex 2em 1ex 3em;
+ text-align : left;
+ line-height: 140%;
+}
+
+div.main h1.title {
+ font-size : 140%;
+ text-align: center;
+ padding : 0;
+ padding-bottom : .4ex;
+ font-weight : bold;
+ margin : 0 0 0.5em 0;
+}
+
+div.main hr.end {
+ color : #808080;
+ width : 50%;
+ height : 1px;
+}
+
+hr.divider {
+ color : #A0A0A0;
+ border : none;
+ clear : both;
+ height : 3px;
+ width : 62%;
+ background-color : #A0A0A0;
+}
+
+div.footer {
+ color : #606060;
+ clear : both;
+ width : 100%;
+ background : #FFFFFF;
+ max-width : 960px;
+ padding-top : 1ex;
+ font-family : sans-serif;
+}
+
+div.footer p {
+ font-size : 9pt;
+ margin : .5ex 0 0 0;
+ text-align : left;
+}
+
+div.footer a {
+ color : #000000;
+ font-size : 9pt;
+ margin : 0 .5em 0 .5em;
+ text-decoration : none;
+}
+
+div.footer a:hover {
+ text-decoration : underline;
+}
+
+
diff --git a/www/miff.html b/www/miff.html
new file mode 100644
index 0000000..9a95aa3
--- /dev/null
+++ b/www/miff.html
@@ -0,0 +1,423 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>Magick Image File Format</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-image-file-format">
+<h1 class="title">Magick Image File Format</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>Magick Image File Format (MIFF) is a platform-independent format for
+storing bitmap images. MIFF was originally invented by John Cristy for
+ImageMagick, but is also a native format of GraphicsMagick. It is useful
+as an efficient lossless working file format which assures that all of
+the image attributes used by GraphicsMagick are preserved. Several
+lossless compression algorithms are available in order to save space.</p>
+<div class="section" id="description">
+<h1>Description</h1>
+<p>A MIFF image file consist of two sections. The first section is a header
+composed of keywords describing the image in text form. The next section
+is the binary image data. The header is separated from the image data by
+a : character immediately followed by a ctrl-Z.</p>
+<p>The MIFF header is composed entirely of LATIN-1 characters. The fields in
+the header are keyword and value combination in the keyword=value format,
+with each keyword and value separated by an equal sign (=). Each
+keyword=value combination is delimited by at least one control or
+whitespace character. Comments may appear in the header section and are
+always delimited by braces. The MIFF header always ends with a colon (:)
+character, followed by a ctrl-Z character. It is also common to precede
+the colon with a formfeed and a newline character. The formfeed prevents
+the listing of binary data when using more(1) under Unix where the ctrl-Z
+has the same effect with the type command on the Win32 command line.</p>
+<p>The following is a list of keyword=value combinations that may be found
+in a MIFF file:</p>
+<p>background-color=color</p>
+<p>border-color=color</p>
+<p>matte-color=color</p>
+<blockquote>
+these optional keywords reflects the image background, border, and
+matte colors respectively. A color can be a name (e.g. white) or a hex
+value (e.g. #ccc).</blockquote>
+<p>class=DirectClass</p>
+<p>class=PseudoClass</p>
+<blockquote>
+the type of binary image data stored in the MIFF file. If this keyword
+is not present, DirectClass image data is assumed.</blockquote>
+<p>colors=value</p>
+<blockquote>
+the number of colors in a DirectClass image. For a PseudoClass image,
+this keyword specifies the size of the colormap. If this keyword is not
+present in the header, and the image is PseudoClass, a linear 256 color
+grayscale colormap is used with the image data. The maximum number of
+colormap entries is 65535.</blockquote>
+<p>columns=value</p>
+<blockquote>
+the width of the image in pixels. This is a required keyword and has no
+default.</blockquote>
+<p>colorspace=RGB</p>
+<p>colorspace=CMYK</p>
+<blockquote>
+the colorspace of the pixel data. The default is RGB.</blockquote>
+<p>compression=BZip</p>
+<p>compression=RLE</p>
+<p>compression=Zip</p>
+<blockquote>
+the type of algorithm used to compress the image data. If this keyword
+is not present, the image data is assumed to be uncompressed.</blockquote>
+<p>delay &lt;1/100ths of a second&gt;</p>
+<blockquote>
+the interframe delay in an image sequence. The maximum delay is 65535.</blockquote>
+<p>depth=8</p>
+<p>depth=16</p>
+<p>depth=32</p>
+<blockquote>
+depth of a single color value representing values from 0 to 255 (depth
+8), 65535 (depth 16), or 4294967295 (depth 32). If this keyword is
+absent, a depth of 8 is assumed.</blockquote>
+<p>dispose value</p>
+<blockquote>
+<p>GIF disposal method. Here are the valid methods:</p>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="19%" />
+<col width="81%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Disposal</td>
+<td>Description</td>
+</tr>
+<tr><td>0</td>
+<td>No disposal specified.</td>
+</tr>
+<tr><td>1</td>
+<td>Do not dispose between frames.</td>
+</tr>
+<tr><td>2</td>
+<td>Overwrite frame with background color from
+header.</td>
+</tr>
+<tr><td>3</td>
+<td>Overwrite with previous frame.</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+</blockquote>
+<p>gamma=value</p>
+<blockquote>
+gamma of the image. If it is not specified, a gamma of 1.0 (linear
+brightness response) is assumed,</blockquote>
+<p>id=GraphicsMagick</p>
+<blockquote>
+identify the file as a MIFF-format image file. This keyword is required
+and has no default. Although this keyword can appear anywhere in the
+header, it should start as the first keyword of the header in column 1.
+This will allow programs like file(1) to easily identify the file as
+MIFF.</blockquote>
+<p>iterations value</p>
+<blockquote>
+the number of times an image sequence loops before stopping.</blockquote>
+<p>label={value}</p>
+<blockquote>
+this optional keyword defines a short title or caption for the image.
+If any whitespace appears in the label, it must be enclosed within
+double quotes.</blockquote>
+<p>matte=True</p>
+<p>matte=False</p>
+<blockquote>
+specifies whether a DirectClass image has matte data. Matte data is
+generally useful for image compositing. This keyword has no meaning for
+pseudocolor images.</blockquote>
+<p>montage=&lt;width&gt;x&lt;height&gt;{+-}&lt;xoffset&gt;{+-}&lt;yoffset&gt;</p>
+<blockquote>
+size and location of the individual tiles of a composite image. See
+X(1) for details about the geometry specification. Use this keyword
+when the image is a composite of a number of different tiles. A tile
+consists of an image and optionally a border and a label. &lt; width&gt; is
+the size in pixels of each individual tile in the horizontal direction
+and &lt;height&gt; is the size in the vertical direction. Each tile must have
+an equal number of pixels in width and equal in height. However, the
+width can differ from the height. &lt;xoffset&gt; is the offset in number of
+pixels from the vertical edge of the composite image where the first
+tile of a row begins and &lt;yoffset&gt; is the offset from the horizontal
+edge where the first tile of a column begins. If this keyword is
+specified, a directory of tile names must follow the image header. The
+format of the directory is explained below.</blockquote>
+<p>page=&lt;width&gt;x&lt;height&gt;{+-}&lt;xoffset&gt;{+-}&lt;yoffset&gt;</p>
+<blockquote>
+preferred size and location of an image canvas.</blockquote>
+<p>profile-icc=value</p>
+<blockquote>
+the number of bytes in the International Color Consortium color
+profile. The profile is defined by the ICC profile specification.</blockquote>
+<p>profile-iptc=value</p>
+<blockquote>
+the number of bytes in the IPTC Newsphoto profile. The profile is
+defined by the IPTC specification.</blockquote>
+<p>profile-name=value</p>
+<blockquote>
+the number of bytes in the generic profile name where name identifies
+the profile. Name is substituted with any LATIN-1 string to form a
+unique generic profile identifier.</blockquote>
+<p>red-primary=x,y</p>
+<p>green-primary=x,y</p>
+<p>blue-primary=x,y</p>
+<p>white-point=x,y</p>
+<blockquote>
+these optional keywords reflect the chromaticity primaries and white point.</blockquote>
+<p>rendering-intent=saturation</p>
+<p>rendering-intent=perceptual</p>
+<p>rendering-intent=absolute</p>
+<p>rendering-intent=relative</p>
+<blockquote>
+Rendering intent is the CSS-1 property that has been defined by the
+International Color Consortium.</blockquote>
+<p>resolution=&lt;x-resolution&gt;x&lt;y-resolution&gt;</p>
+<blockquote>
+vertical and horizontal resolution of the image. See units for the
+specific resolution units (e.g. pixels per inch).</blockquote>
+<p>rows=value</p>
+<blockquote>
+the height of the image in pixels. This is a required keyword and has
+no default.</blockquote>
+<p>scene=value</p>
+<blockquote>
+the sequence number for this MIFF image file. This optional keyword is
+used when a MIFF image file is one in a sequence of files used in an
+animation.</blockquote>
+<p>signature=value</p>
+<blockquote>
+this optional keyword contains a string that uniquely identifies the
+image pixel contents. NIST's SHA-256 message digest algorithm is
+recommended.</blockquote>
+<p>units=pixels-per-inch</p>
+<p>units=pixels-per-centimeter</p>
+<blockquote>
+image resolution units.</blockquote>
+<p>Other key value pairs are permitted. If a value contains whitespace it must be
+enclosed with braces as illustrated here:</p>
+<pre class="literal-block">
+id=GraphicsMagick
+class=PseudoClass colors=256
+compression=RLE
+columns=1280 rows=1024
+scene=1
+signature=d79e1c308aa5bbcdeea8ed63df412da9
+copyright={Copyright (c) 2000 Mortimer Snerd}
+&lt;FF&gt;
+:
+</pre>
+<p>Note that keyword=value combinations may be separated by newlines or
+spaces and may occur in any order within the header. Comments (within
+braces) may appear anywhere before the colon.</p>
+<p>The elements shown in the following table may appear after the header and
+before the image data. These elements appear in the order described in
+the following table if the keyword indicates that they exist.</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="21%" />
+<col width="21%" />
+<col width="57%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Element</td>
+<td>Keyword</td>
+<td>Description</td>
+</tr>
+<tr><td>Image
+directory</td>
+<td>montage</td>
+<td>The directory consists of a name for each
+tile of the composite image separated by
+a newline character. The list is
+terminated with a NULL character.</td>
+</tr>
+<tr><td>ICC Profile</td>
+<td>profile-icc</td>
+<td>Binary color profile.</td>
+</tr>
+<tr><td>IPTC Profile</td>
+<td>profile-iptc</td>
+<td>Binary IPTC Newsphoto profile.</td>
+</tr>
+<tr><td>Generic
+Profiles</td>
+<td>profile-&lt;name&gt;</td>
+<td>Binary generic profile. Multiple named
+generic profiles may exist.</td>
+</tr>
+</tbody>
+</table>
+<p>Next comes the binary image data itself. How the image data is formatted
+depends upon the class of the image as specified (or not specified) by
+the value of the class keyword in the header. All numeric values in the
+binary section are written with the most significant bytes occuring first
+(big-endian ordering).</p>
+<p>DirectClass images (class=DirectClass) are continuous-tone, images stored
+as RGB (red, green, blue), RGBA (red, green, blue, alpha), CMYK (cyan,
+yellow, magenta, black), and CMYKA (cyan, yellow, magenta, black, alpha)
+intensity values as defined by the colorspace and matte keywords. The
+size of each intensity value depends on the depth of the image. The
+depth, number of bytes, and numeric range of each value are shown in the
+following table:</p>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="21%" />
+<col width="41%" />
+<col width="38%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Depth</td>
+<td>Bytes Per
+Value</td>
+<td>Value Range</td>
+</tr>
+<tr><td>8</td>
+<td>1</td>
+<td>0..255</td>
+</tr>
+<tr><td>16</td>
+<td>2</td>
+<td>0..65535</td>
+</tr>
+<tr><td>32</td>
+<td>4</td>
+<td>0..4294967295</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<p>The alpha value (if it occurs) represents the degree of pixel opacity
+(zero is totally transparent).</p>
+<p>PseudoClass images (class=PseudoClass) are colormapped RGB images. The
+colormap is stored as a series of red, green, and blue pixel values. The
+size of each colormap value depends on the image depth, as shown in the
+following table:</p>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="19%" />
+<col width="22%" />
+<col width="31%" />
+<col width="28%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Depth</td>
+<td>Bytes Per
+Value</td>
+<td>Value Range</td>
+<td>Bytes Per
+Colormap Entry</td>
+</tr>
+<tr><td>8</td>
+<td>1</td>
+<td>0..255</td>
+<td>3</td>
+</tr>
+<tr><td>16</td>
+<td>2</td>
+<td>0..65535</td>
+<td>6</td>
+</tr>
+<tr><td>32</td>
+<td>4</td>
+<td>0..4294967295</td>
+<td>12</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<p>The number of colormap entries is defined by the colors keyword. The
+colormap data occurs immediately following the header (or image directory
+if the montage keyword is in the header). Immediately following the
+colormap data is the PseudoClass image data. PseudoClass image data is an
+array of index values into the color map. The number of bytes comprising
+the index value depends on the number of colors in the image. The
+following table shows the number of bytes in each colormap index as
+determined by the colors keyword:</p>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="31%" />
+<col width="31%" />
+<col width="38%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Colors</td>
+<td>Bytes Per
+Index</td>
+<td>Index Range</td>
+</tr>
+<tr><td>&lt;=256</td>
+<td>1</td>
+<td>0..255</td>
+</tr>
+<tr><td>&lt;=65535</td>
+<td>2</td>
+<td>0..65535</td>
+</tr>
+<tr><td>&lt;=4294967295</td>
+<td>4</td>
+<td>0..4294967295</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<p>If matte is true, each colormap index is immediately followed by an
+equally-sized alpha value. The alpha value represents the degree of pixel
+opacity (zero is totally transparent).</p>
+<p>The image data in a MIFF file may be uncompressed, runlength encoded, Zip
+compressed, or BZip compressed. The compression keyword in the header
+defines how the image data is compressed. Uncompressed pixels are stored
+one scanline at a time in row order. Runlength encoded compression counts
+runs of identical adjacent pixels and stores the pixels followed by a
+length byte (the number of identical pixels minus 1). Zip and BZip
+compression compresses each row of an image and precedes the compressed
+row with the length of compressed pixel bytes as a word in most
+significant byte first order.</p>
+<p>MIFF files may contain more than one image. Simply concatenate each
+individual image (composed of a header and image data) into one file.</p>
+</div>
+<div class="section" id="authors">
+<h1>Authors</h1>
+<p>John Cristy, <a class="reference external" href="mailto:magick-users&#37;&#52;&#48;imagemagick&#46;org">magick-users<span>&#64;</span>imagemagick<span>&#46;</span>org</a> ImageMagick Studio LLC.</p>
+<p>Maintained since 2002 by Bob Friesenhahn, GraphicsMagick Group.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/miff.rst b/www/miff.rst
new file mode 100644
index 0000000..73a82ef
--- /dev/null
+++ b/www/miff.rst
@@ -0,0 +1,359 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+========================
+Magick Image File Format
+========================
+
+Magick Image File Format (MIFF) is a platform-independent format for
+storing bitmap images. MIFF was originally invented by John Cristy for
+ImageMagick, but is also a native format of GraphicsMagick. It is useful
+as an efficient lossless working file format which assures that all of
+the image attributes used by GraphicsMagick are preserved. Several
+lossless compression algorithms are available in order to save space.
+
+Description
+===========
+
+A MIFF image file consist of two sections. The first section is a header
+composed of keywords describing the image in text form. The next section
+is the binary image data. The header is separated from the image data by
+a : character immediately followed by a ctrl-Z.
+
+The MIFF header is composed entirely of LATIN-1 characters. The fields in
+the header are keyword and value combination in the keyword=value format,
+with each keyword and value separated by an equal sign (=). Each
+keyword=value combination is delimited by at least one control or
+whitespace character. Comments may appear in the header section and are
+always delimited by braces. The MIFF header always ends with a colon (:)
+character, followed by a ctrl-Z character. It is also common to precede
+the colon with a formfeed and a newline character. The formfeed prevents
+the listing of binary data when using more(1) under Unix where the ctrl-Z
+has the same effect with the type command on the Win32 command line.
+
+The following is a list of keyword=value combinations that may be found
+in a MIFF file:
+
+background-color=color
+
+border-color=color
+
+matte-color=color
+
+ these optional keywords reflects the image background, border, and
+ matte colors respectively. A color can be a name (e.g. white) or a hex
+ value (e.g. #ccc).
+
+class=DirectClass
+
+class=PseudoClass
+
+ the type of binary image data stored in the MIFF file. If this keyword
+ is not present, DirectClass image data is assumed.
+
+colors=value
+
+ the number of colors in a DirectClass image. For a PseudoClass image,
+ this keyword specifies the size of the colormap. If this keyword is not
+ present in the header, and the image is PseudoClass, a linear 256 color
+ grayscale colormap is used with the image data. The maximum number of
+ colormap entries is 65535.
+
+columns=value
+
+ the width of the image in pixels. This is a required keyword and has no
+ default.
+
+colorspace=RGB
+
+colorspace=CMYK
+
+ the colorspace of the pixel data. The default is RGB.
+
+compression=BZip
+
+compression=RLE
+
+compression=Zip
+
+ the type of algorithm used to compress the image data. If this keyword
+ is not present, the image data is assumed to be uncompressed.
+
+delay <1/100ths of a second>
+
+ the interframe delay in an image sequence. The maximum delay is 65535.
+
+depth=8
+
+depth=16
+
+depth=32
+
+ depth of a single color value representing values from 0 to 255 (depth
+ 8), 65535 (depth 16), or 4294967295 (depth 32). If this keyword is
+ absent, a depth of 8 is assumed.
+
+dispose value
+
+ GIF disposal method. Here are the valid methods:
+
+ +-----------+------------------------------------------------+
+ | Disposal | Description |
+ +-----------+------------------------------------------------+
+ | 0 | No disposal specified. |
+ +-----------+------------------------------------------------+
+ | 1 | Do not dispose between frames. |
+ +-----------+------------------------------------------------+
+ | | Overwrite frame with background color from |
+ | 2 | header. |
+ +-----------+------------------------------------------------+
+ | 3 | Overwrite with previous frame. |
+ +-----------+------------------------------------------------+
+
+gamma=value
+
+ gamma of the image. If it is not specified, a gamma of 1.0 (linear
+ brightness response) is assumed,
+
+id=GraphicsMagick
+
+ identify the file as a MIFF-format image file. This keyword is required
+ and has no default. Although this keyword can appear anywhere in the
+ header, it should start as the first keyword of the header in column 1.
+ This will allow programs like file(1) to easily identify the file as
+ MIFF.
+
+iterations value
+
+ the number of times an image sequence loops before stopping.
+
+label={value}
+
+ this optional keyword defines a short title or caption for the image.
+ If any whitespace appears in the label, it must be enclosed within
+ double quotes.
+
+matte=True
+
+matte=False
+
+ specifies whether a DirectClass image has matte data. Matte data is
+ generally useful for image compositing. This keyword has no meaning for
+ pseudocolor images.
+
+montage=<width>x<height>{+-}<xoffset>{+-}<yoffset>
+
+ size and location of the individual tiles of a composite image. See
+ X(1) for details about the geometry specification. Use this keyword
+ when the image is a composite of a number of different tiles. A tile
+ consists of an image and optionally a border and a label. < width> is
+ the size in pixels of each individual tile in the horizontal direction
+ and <height> is the size in the vertical direction. Each tile must have
+ an equal number of pixels in width and equal in height. However, the
+ width can differ from the height. <xoffset> is the offset in number of
+ pixels from the vertical edge of the composite image where the first
+ tile of a row begins and <yoffset> is the offset from the horizontal
+ edge where the first tile of a column begins. If this keyword is
+ specified, a directory of tile names must follow the image header. The
+ format of the directory is explained below.
+
+page=<width>x<height>{+-}<xoffset>{+-}<yoffset>
+
+ preferred size and location of an image canvas.
+
+profile-icc=value
+
+ the number of bytes in the International Color Consortium color
+ profile. The profile is defined by the ICC profile specification.
+
+profile-iptc=value
+
+ the number of bytes in the IPTC Newsphoto profile. The profile is
+ defined by the IPTC specification.
+
+profile-name=value
+
+ the number of bytes in the generic profile name where name identifies
+ the profile. Name is substituted with any LATIN-1 string to form a
+ unique generic profile identifier.
+
+red-primary=x,y
+
+green-primary=x,y
+
+blue-primary=x,y
+
+white-point=x,y
+
+ these optional keywords reflect the chromaticity primaries and white point.
+
+rendering-intent=saturation
+
+rendering-intent=perceptual
+
+rendering-intent=absolute
+
+rendering-intent=relative
+
+ Rendering intent is the CSS-1 property that has been defined by the
+ International Color Consortium.
+
+resolution=<x-resolution>x<y-resolution>
+
+ vertical and horizontal resolution of the image. See units for the
+ specific resolution units (e.g. pixels per inch).
+
+rows=value
+
+ the height of the image in pixels. This is a required keyword and has
+ no default.
+
+scene=value
+
+ the sequence number for this MIFF image file. This optional keyword is
+ used when a MIFF image file is one in a sequence of files used in an
+ animation.
+
+signature=value
+
+ this optional keyword contains a string that uniquely identifies the
+ image pixel contents. NIST's SHA-256 message digest algorithm is
+ recommended.
+
+units=pixels-per-inch
+
+units=pixels-per-centimeter
+
+ image resolution units.
+
+Other key value pairs are permitted. If a value contains whitespace it must be
+enclosed with braces as illustrated here::
+
+ id=GraphicsMagick
+ class=PseudoClass colors=256
+ compression=RLE
+ columns=1280 rows=1024
+ scene=1
+ signature=d79e1c308aa5bbcdeea8ed63df412da9
+ copyright={Copyright (c) 2000 Mortimer Snerd}
+ <FF>
+ :
+
+Note that keyword=value combinations may be separated by newlines or
+spaces and may occur in any order within the header. Comments (within
+braces) may appear anywhere before the colon.
+
+The elements shown in the following table may appear after the header and
+before the image data. These elements appear in the order described in
+the following table if the keyword indicates that they exist.
+
++----------------+----------------+-------------------------------------------+
+| Element | Keyword | Description |
++----------------+----------------+-------------------------------------------+
+| Image | montage | The directory consists of a name for each |
+| directory | | tile of the composite image separated by |
+| | | a newline character. The list is |
+| | | terminated with a NULL character. |
++----------------+----------------+-------------------------------------------+
+| ICC Profile | profile-icc | Binary color profile. |
++----------------+----------------+-------------------------------------------+
+| IPTC Profile | profile-iptc | Binary IPTC Newsphoto profile. |
++----------------+----------------+-------------------------------------------+
+| Generic | profile-<name> | Binary generic profile. Multiple named |
+| Profiles | | generic profiles may exist. |
++----------------+----------------+-------------------------------------------+
+
+Next comes the binary image data itself. How the image data is formatted
+depends upon the class of the image as specified (or not specified) by
+the value of the class keyword in the header. All numeric values in the
+binary section are written with the most significant bytes occuring first
+(big-endian ordering).
+
+DirectClass images (class=DirectClass) are continuous-tone, images stored
+as RGB (red, green, blue), RGBA (red, green, blue, alpha), CMYK (cyan,
+yellow, magenta, black), and CMYKA (cyan, yellow, magenta, black, alpha)
+intensity values as defined by the colorspace and matte keywords. The
+size of each intensity value depends on the depth of the image. The
+depth, number of bytes, and numeric range of each value are shown in the
+following table:
+
+ +--------+----------------+---------------+
+ | Depth | Bytes Per | Value Range |
+ | | Value | |
+ +--------+----------------+---------------+
+ | 8 | 1 | 0..255 |
+ +--------+----------------+---------------+
+ | 16 | 2 | 0..65535 |
+ +--------+----------------+---------------+
+ | 32 | 4 | 0..4294967295 |
+ +--------+----------------+---------------+
+
+The alpha value (if it occurs) represents the degree of pixel opacity
+(zero is totally transparent).
+
+PseudoClass images (class=PseudoClass) are colormapped RGB images. The
+colormap is stored as a series of red, green, and blue pixel values. The
+size of each colormap value depends on the image depth, as shown in the
+following table:
+
+ +-----------+-------------+------------------+----------------+
+ | Depth | Bytes Per | Value Range | Bytes Per |
+ | | Value | | Colormap Entry |
+ +-----------+-------------+------------------+----------------+
+ | 8 | 1 | 0..255 | 3 |
+ +-----------+-------------+------------------+----------------+
+ | 16 | 2 | 0..65535 | 6 |
+ +-----------+-------------+------------------+----------------+
+ | 32 | 4 | 0..4294967295 | 12 |
+ +-----------+-------------+------------------+----------------+
+
+The number of colormap entries is defined by the colors keyword. The
+colormap data occurs immediately following the header (or image directory
+if the montage keyword is in the header). Immediately following the
+colormap data is the PseudoClass image data. PseudoClass image data is an
+array of index values into the color map. The number of bytes comprising
+the index value depends on the number of colors in the image. The
+following table shows the number of bytes in each colormap index as
+determined by the colors keyword:
+
+ +----------------+----------------+--------------------+
+ | Colors | Bytes Per | Index Range |
+ | | Index | |
+ +----------------+----------------+--------------------+
+ | <=256 | 1 | 0..255 |
+ +----------------+----------------+--------------------+
+ | <=65535 | 2 | 0..65535 |
+ +----------------+----------------+--------------------+
+ | <=4294967295 | 4 | 0..4294967295 |
+ +----------------+----------------+--------------------+
+
+If matte is true, each colormap index is immediately followed by an
+equally-sized alpha value. The alpha value represents the degree of pixel
+opacity (zero is totally transparent).
+
+The image data in a MIFF file may be uncompressed, runlength encoded, Zip
+compressed, or BZip compressed. The compression keyword in the header
+defines how the image data is compressed. Uncompressed pixels are stored
+one scanline at a time in row order. Runlength encoded compression counts
+runs of identical adjacent pixels and stores the pixels followed by a
+length byte (the number of identical pixels minus 1). Zip and BZip
+compression compresses each row of an image and precedes the compressed
+row with the length of compressed pixel bytes as a word in most
+significant byte first order.
+
+MIFF files may contain more than one image. Simply concatenate each
+individual image (composed of a header and image data) into one file.
+
+Authors
+=======
+
+John Cristy, magick-users@imagemagick.org ImageMagick Studio LLC.
+
+Maintained since 2002 by Bob Friesenhahn, GraphicsMagick Group.
+
+-------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/mission.html b/www/mission.html
new file mode 100644
index 0000000..4218f29
--- /dev/null
+++ b/www/mission.html
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Mission Statement</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-mission-statement">
+<h1 class="title">GraphicsMagick Mission Statement</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>In November, 2002, the GraphicsMagick project was formed as a branch from
+ImageMagick 5.5.2. The project was formed in order to develop a more
+&quot;stable&quot; form of ImageMagick which is suitable to be use as a base for
+other open source (and proprietary) applications. It was perceived that
+ImageMagick provided tremendous value, but also proved to be difficult to
+rely on as a stable application component since the ImageMagick
+interfaces often changed between releases, and there was no concept of
+shared library ABI stability. GraphicsMagick intends to resolve these
+issues while providing an appealing development environment to attract
+the best available developers.</p>
+<p>The objectives of the GraphicsMagick project are to:</p>
+<ul class="simple">
+<li>Use an open development model.</li>
+<li>Encourage new developers to join the project.</li>
+<li>Avoid unnecessary source code &quot;churn&quot;.</li>
+<li>Establish and preserve both a stable API, and stable ABI, making
+GraphicsMagick a stable component in Linux and BSD distributions.</li>
+<li>Use efficient coding practices which result in fast code.</li>
+<li>Improve memory efficiency.</li>
+<li>Use a release process which assures a working product.</li>
+<li>Prioritize bug-fixes over new feature enhancements.</li>
+<li>Maintain an accurate change log.</li>
+<li>Value, and respect the contributions of developers, and observe and
+respect the copyrights of other projects.</li>
+</ul>
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/mission.rst b/www/mission.rst
new file mode 100644
index 0000000..8cae978
--- /dev/null
+++ b/www/mission.rst
@@ -0,0 +1,47 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+================================
+GraphicsMagick Mission Statement
+================================
+
+In November, 2002, the GraphicsMagick project was formed as a branch from
+ImageMagick 5.5.2. The project was formed in order to develop a more
+"stable" form of ImageMagick which is suitable to be use as a base for
+other open source (and proprietary) applications. It was perceived that
+ImageMagick provided tremendous value, but also proved to be difficult to
+rely on as a stable application component since the ImageMagick
+interfaces often changed between releases, and there was no concept of
+shared library ABI stability. GraphicsMagick intends to resolve these
+issues while providing an appealing development environment to attract
+the best available developers.
+
+The objectives of the GraphicsMagick project are to:
+
+* Use an open development model.
+
+* Encourage new developers to join the project.
+
+* Avoid unnecessary source code "churn".
+
+* Establish and preserve both a stable API, and stable ABI, making
+ GraphicsMagick a stable component in Linux and BSD distributions.
+
+* Use efficient coding practices which result in fast code.
+
+* Improve memory efficiency.
+
+* Use a release process which assures a working product.
+
+* Prioritize bug-fixes over new feature enhancements.
+
+* Maintain an accurate change log.
+
+* Value, and respect the contributions of developers, and observe and
+ respect the copyrights of other projects.
+
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/mogrify.html b/www/mogrify.html
new file mode 100644
index 0000000..1bb34a5
--- /dev/null
+++ b/www/mogrify.html
@@ -0,0 +1,1713 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mogrify"></a>gm mogrify
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mog-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+mogrify - mogrify an image
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mog-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#mog-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#mog-desc">Description</a>
+</dt>
+<dt>
+<a href="#mog-exam">Examples</a>
+</dt>
+<dt>
+<a href="#mog-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mog-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm mogrify</strong> <strong>[</strong> <em>options</em> <strong>... ]</strong> <em>file ...</em>
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mog-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Mogrify</strong> transforms an image or a sequence of images. These transforms
+include image scaling, image rotation, color reduction, and others. Each
+transmogrified image overwrites the corresponding original image, unless an
+option such as
+<strong>-format</strong> causes the output filename to be different from the input
+filename.
+<br>&nbsp;<br>
+The graphics formats supported by <strong>mogrify</strong> are listed in
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mog-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To convert all the TIFF files in a particular directory to JPEG, use:
+<pre>
+ gm mogrify -format jpeg *.tiff
+</pre>
+<p>
+To convert a directory full of JPEG images to thumbnails, use:
+<pre>
+ gm mogrify -size 120x120 *.jpg -resize 120x120 +profile "*"
+</pre>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td><font size="-1">
+In this example, <tt>'-size 120x120'</tt> gives a hint to the JPEG decoder
+that the images are going to be downscaled to 120x120, allowing it to run
+faster by avoiding returning full-resolution images to GraphicsMagick for
+the subsequent resizing operation. The
+<tt>'-resize 120x120'</tt> specifies the desired dimensions of the
+output images. It will be scaled so its largest dimension is 120 pixels. The
+<tt>'+profile "*"'</tt> removes any ICM, EXIF, IPTC, or other profiles
+that might be present in the input and aren't needed in the thumbnails.</font></td></tr></table>
+<p>
+To scale an image of a cockatoo to exactly 640 pixels in width and 480
+pixels in height, use:
+<pre>
+ gm mogrify -resize 640x480! cockatoo.miff
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mog-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Options are processed in command line order. Any option you specify on
+the command line remains in effect for the set of images that follows,
+until the set is terminated by the appearance of any option or <strong>-noop</strong>.
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-affine">-affine</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>drawing transform matrix</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-antialias">-antialias</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixel aliasing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details"></a> <i>-asc-cdl &lt;spec&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply ASC CDL color transform</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-auto-orient">-auto-orient</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>orient (rotate) image so it is upright</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-black-threshold">-black-threshold</a> <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels below the threshold become black</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blue-primary">-blue-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blur">-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-border">-border</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with a border of color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-channel">-channel</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of channel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -charcoal <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate a charcoal drawing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorize">-colorize</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colorize the image with the pen color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compose">-compose</a> <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-contrast">-contrast</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enhance or reduce the image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-convolve">-convolve</a> <i>&lt;kernel&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>convolve image with the specified convolution kernel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-create-directories">-create-directories</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create output directory if required</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-cycle">-cycle</a> <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image colormap by amount</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-delay">-delay</a> <i>&lt;1/100ths of a second&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>display the next image after pausing</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -despeckle
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>reduce the speckles within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-draw">-draw</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with one or more graphic primitives</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -edge <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>detect edges within an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -emboss <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>emboss an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -enhance
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a digital filter to enhance a noisy image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -equalize
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform histogram equalization to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-extent">-extent</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite image on background color canvas image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fill">-fill</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flip">-flip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-flop">-flop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>create a "mirror image"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-format">-format</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image format type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-frame">-frame</a> <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fuzz">-fuzz</a> <i>&lt;distance&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>colors within this Euclidean distance are considered equal</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gaussian">-gaussian</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gravity">-gravity</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-green-primary">-green-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -hald-clut <i>&lt;clut&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a Hald CLUT to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -implode <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>implode image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-lat">-lat</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;offset&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>perform local adaptive thresholding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-level">-level</a> <i>&lt;black_point&gt;</i>{<i>,&lt;gamma&gt;</i>}<i></i>{<i>,&lt;white_point&gt;</i>}<i></i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>adjust the level of image contrast</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -linewidth
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the line width for subsequent draw operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-list">-list</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of list</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-loop">-loop</a> <i>&lt;iterations&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add Netscape loop extension to your GIF animation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -magnify
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>magnify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-map">-map</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>choose a particular set of colors from this image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mask">-mask</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify a clipping mask</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -median <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a median filter to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -minify <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>minify the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-modulate">-modulate</a> <i>brightness[,saturation[,hue]]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>vary the brightness, saturation, and hue of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-motion-blur">-motion-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+angle</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Simulate motion blur</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-negate">-negate</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>replace every pixel with its complementary color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noise">-noise</a> <i>&lt;radius|type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add or reduce noise in an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-normalize">-normalize</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform image to span the full range of color values</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-opaque">-opaque</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>change this color to the pen color within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-operator">-operator</a> <i>channel operator rvalue[%]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a mathematical, bitwise, or value operator to an image channel</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-ordered-dither">-ordered-dither</a> <i>&lt;channeltype&gt; &lt;NxN&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>ordered dither the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-output-directory">-output-directory</a> <i>&lt;directory&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>output files to directory</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-orient">-orient</a> <i>&lt;orientation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Set the image orientation attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-paint">-paint</a> <i>&lt;radius&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>simulate an oil painting</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pen">-pen</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>(This option has been replaced by the -fill option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-profile">-profile</a> <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add ICM, IPTC, or generic profile to image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-preserve-timestamp">-preserve-timestamp</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preserve the original timestamps of the file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-raise">-raise</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>lighten or darken image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-random-threshold">-random-threshold</a> <i>&lt;channeltype&gt; &lt;LOWxHIGH&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>random threshold the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-recolor">-recolor</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply a color translation matrix to image channels</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-red-primary">-red-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-region">-region</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply options to a portion of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-render">-render</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-repage">-repage</a> <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resample">-resample</a> <i>&lt;horizontal&gt;x&lt;vertical&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Resample image to specified horizontal and vertical resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-roll">-roll</a> <i></i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>roll an image vertically or horizontally</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sample">-sample</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale image using pixel sampling</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scale">-scale</a> <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>scale the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scene">-scene</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set scene number</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-set">-set</a> <i>&lt;attribute&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details+set">+set</a> <i>&lt;attribute&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>unset an image attribute</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-segment">-segment</a> <i>&lt;cluster threshold&gt;x&lt;smoothing threshold&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>segment an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shade">-shade</a> <i>&lt;azimuth&gt;x&lt;elevation&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shade the image using a distant light source</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shave">-shave</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shave pixels from the image edges</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-shear">-shear</a> <i>&lt;x degrees&gt;x&lt;y degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shear the image along the X or Y axis</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-solarize">-solarize</a> <i>&lt;factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>negate all pixels above the threshold level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-spread">-spread</a> <i>&lt;amount&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>displace image pixels by a random amount</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strip">-strip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stroke">-stroke</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when stroking a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strokewidth">-strokewidth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the stroke width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-swirl">-swirl</a> <i>&lt;degrees&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>swirl image pixels about the center</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-threshold">-threshold</a> <i>&lt;value&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>threshold the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tile image when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transform">-transform</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transparent">-transparent</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-units">-units</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the units of image resolution</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-unsharp">-unsharp</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>{<i>+&lt;amount&gt;</i>}<i></i>{<i>+&lt;threshold&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image with an unsharp mask operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -view <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>FlashPix viewing parameters</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-virtual-pixel">-virtual-pixel</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify contents of "virtual pixels"</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-wave">-wave</a> <i>&lt;amplitude&gt;x&lt;wavelength&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>alter an image along a sine wave</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-point">-white-point</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-threshold">-white-threshold</a> <i>red[,green][,blue][,opacity]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pixels above the threshold become white</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
diff --git a/www/montage.html b/www/montage.html
new file mode 100644
index 0000000..4f0d85b
--- /dev/null
+++ b/www/montage.html
@@ -0,0 +1,1167 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="montage"></a>gm montage
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+montage - create a composite image by combining several separate images
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#mont-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#mont-desc">Description</a>
+</dt>
+<dt>
+<a href="#mont-exam">Examples</a>
+</dt>
+<dt>
+<a href="#mont-opti">Options</a>
+</dt>
+<dt>
+<a href="#mont-xres">X Resources</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm montage</strong> <strong>[</strong> <em>options</em> <strong>...]</strong> <em>file</em> <strong>[ [</strong>
+<em>options</em> <strong>...]</strong> <em>file</em> <strong>...]</strong> <em>output_file</em>
+<br>&nbsp;<br>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>montage</strong> creates a composite image by combining several separate
+images. The images are tiled on the composite image with the name of the
+image optionally appearing just below the individual tile.
+<p>
+The composite image is constructed in the following manner. First, each
+image specified on the command line, except for the last, is scaled to
+fit the maximum tile size. The maximum tile size by default is 120x120.
+It can be modified with the <strong>-geometry</strong> command line argument or X
+resource. See
+<strong><a href="#mont-opti">Options</a></strong>
+for more information on command line arguments. See
+<strong>X(1)</strong> for more information on X resources.
+Note that the maximum tile size need not be a square.
+<p>
+Next the composite image is initialized with the color specified by the
+<strong>-background</strong>
+command line argument or X resource. The width and height of the composite
+image is determined by the title specified, the maximum tile size, the
+number of tiles per row, the tile border width and height, the image border
+width, and the label height. The number of tiles per row specifies how
+many images are to appear in each row of the composite image. The default
+is to have 5 tiles in each row and 4 tiles in each column of the composite.
+A specific value is specified with <strong>-tile</strong>. The tile border width
+and height, and the image border width defaults to the value of the X resource
+<strong>-borderwidth</strong>. It can be changed with the <strong>-borderwidth</strong> or
+<strong>-geometry</strong> command line argument or X resource. The label height
+is determined by the font you specify with the <strong>-font</strong> command line
+argument or X resource. If you do not specify a font, a font is chosen
+that allows the name of the image to fit the maximum width of a tiled area.
+The label colors is determined by the <strong>-background</strong> and <strong>-fill</strong>
+command line argument or X resource. Note, that if the background and pen
+colors are the same, labels will not appear.
+<p>
+Initially, the composite image title is placed at the top if one is specified
+(refer to <strong>-fill</strong>). Next, each image is set onto the composite image,
+surrounded by its border color, with its name centered just below it. The
+individual images are left-justified within the width of the tiled area.
+The order of the images is the same as they appear on the command line
+unless the images have a scene keyword. If a scene number is specified
+in each image, then the images are tiled onto the composite in the order
+of their scene number. Finally, the last argument on the command line is
+the name assigned to the composite image. By default, the image is written
+in the <strong>MIFF</strong> format and can be viewed or printed with
+<a href="display.html"><em>display(1)</em></a>.
+<br>&nbsp;<br>
+<p>
+Note, that if the number of tiles exceeds the default number of 20 (5 per
+row, 4 per column), more than one composite image is created. To ensure
+a single image is produced, use <strong>-tile</strong> to increase the number of
+tiles to meet or exceed the number of input images.
+<p>
+Finally, to create one or more empty spaces in the sequence of tiles, use
+the <strong>"NULL:"</strong> image format.
+<p>
+Note, a composite MIFF image displayed to an X server with
+<strong>display</strong>
+behaves differently than other images. You can think of the composite as
+a visual image directory. Choose a particular tile of the composite and
+press a button to display it. See <strong>display(1)</strong> and <strong>miff(5)</strong>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+To create a montage of a cockatoo, a parrot, and a hummingbird and write
+it to a file called birds, use:
+<pre>
+ gm montage cockatoo.miff parrot.miff hummingbird.miff birds.miff
+</pre>
+<p>
+To tile several bird images so that they are at most 256 pixels in width
+and 192 pixels in height, surrounded by a red border, and separated by
+10 pixels of background color, use:
+<pre>
+ gm montage -geometry 256x192+10+10 -bordercolor red birds.* montage.miff
+</pre>
+<p>
+To create an unlabeled parrot image, 640 by 480 pixels, and surrounded
+by a border of black, use:
+<pre>
+ gm montage -geometry 640x480 -bordercolor black -label "" parrot.miff
+bird.miff
+</pre>
+<p>
+To create an image of an eagle with a textured background, use:
+<pre>
+ gm montage -texture bumps.jpg eagle.jpg eagle.png
+</pre>
+<p>
+To join several GIF images together without any extraneous graphics (e.g.
+no label, no shadowing, no surrounding tile frame), use:
+<pre>
+ gm montage +frame +shadow +label -tile 5x1 -geometry 50x50+0+0 *.png joined.png
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+Any option you specify on the command line remains in effect for the group
+of images following it, until the group is terminated by the appearance of
+any option or <strong>-noop</strong>. For example, to make a montage of three images,
+the first with 32 colors, the second with an unlimited number of colors, and
+the third with only 16 colors, use:
+<br>&nbsp;<br>
+<pre>
+ gm montage -colors 32 cockatoo.1 -noop cockatoo.2 -colors 16 cockatoo.3
+cockatoos.miff
+</pre>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-adjoin">-adjoin</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>join images into a single multi-image file</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-affine">-affine</a> <i>&lt;matrix&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>drawing transform matrix</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-authenticate">-authenticate</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>decrypt image with this password</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-background">-background</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the background color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blue-primary">-blue-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blue chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-blur">-blur</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>blur the image with a Gaussian operator</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-bordercolor">-bordercolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border color</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -borderwidth <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the border width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-chop">-chop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove pixels from the interior of an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colors">-colors</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred number of colors in the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-colorspace">-colorspace</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of colorspace</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-comment">-comment</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with a comment</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compose">-compose</a> <i>&lt;operator&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image composition</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-compress">-compress</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of image compression</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-crop">-crop</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>preferred size and location of the cropped image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -debug <i>&lt;events&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>enable debug printout</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-define">-define</a> <i>&lt;key&gt;</i>{<i>=&lt;value&gt;</i>}<i>,...</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>add coder/decoder specific options</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-density">-density</a> <i>&lt;width&gt;x&lt;height&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>horizontal and vertical resolution in pixels of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-depth">-depth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>depth of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-display">-display</a> <i>&lt;host:display[.screen]&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specifies the X server to contact</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dispose">-dispose</a> <i>&lt;method&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>GIF disposal method</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-dither">-dither</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>apply Floyd/Steinberg error diffusion to the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-draw">-draw</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>annotate an image with one or more graphic primitives</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-encoding">-encoding</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the text encoding</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-endian">-endian</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify endianness (MSB, LSB, or Native) of image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-fill">-fill</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when filling a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-filter">-filter</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this type of filter when resizing an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-font">-font</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>use this font when annotating the image with text</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-frame">-frame</a> <i>&lt;width&gt;x&lt;height&gt;+&lt;outer bevel width&gt;+&lt;inner bevel width&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>surround the image with an ornamental border</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gamma">-gamma</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>level of gamma correction</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-geometry">-geometry</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>^</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify dimension, offset, and resize options.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-gravity">-gravity</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>direction primitive gravitates to when annotating the image.</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-green-primary">-green-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>green chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -help
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print usage instructions</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-interlace">-interlace</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the type of interlacing scheme</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-label">-label</a> <i>&lt;name&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign a label to an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-limit">-limit</a> <i>&lt;type&gt; &lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Disk, File, Map, Memory, Pixels, Width, Height or Threads resource limit</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-log">-log</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Specify format for debug log</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-matte">-matte</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>store matte channel if the image has one</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-mattecolor">-mattecolor</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>specify the color to be used with the <strong>-frame</strong> option</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -mode <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>mode of operation</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monitor
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>show progress indication</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -monochrome
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image to black and white</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-noop">-noop</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>NOOP (no option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-page">-page</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+-</i>}<i>&lt;x&gt;</i>{<i>+-</i>}<i>&lt;y&gt;</i>{<i>%</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>size and location of an image canvas</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-pen">-pen</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>(This option has been replaced by the -fill option)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -pointsize <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>pointsize of the PostScript, X11, or TrueType font</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-quality">-quality</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>JPEG/MIFF/PNG/TIFF compression level</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-red-primary">-red-primary</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>red chromaticity primary point</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-render">-render</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>render vector operations</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-repage">-repage</a> <i> &lt;width&gt;x&lt;height&gt;+xoff+yoff[!]</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>Adjust image page offsets</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-resize">-resize</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-rotate">-rotate</a> <i>&lt;degrees&gt;</i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>rotate the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sampling-factor">-sampling-factor</a> <i>&lt;horizontal_factor&gt;x&lt;vertical_factor&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chroma subsampling factors</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-scenes">-scenes</a> <i>&lt;value-value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>range of image scene numbers to read</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -shadow <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>shadow the montage</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-sharpen">-sharpen</a> <i>&lt;radius&gt;</i>{<i>x&lt;sigma&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>sharpen the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-size">-size</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>+offset</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>width and height of the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strip">-strip</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>remove all profiles and text attributes from the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-stroke">-stroke</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color to use when stroking a graphic primitive</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-strokewidth">-strokewidth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>set the stroke width</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -texture <i>&lt;filename&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>name of texture to tile onto the image background</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-thumbnail">-thumbnail</a> <i>&lt;width&gt;x&lt;height&gt;</i>{<i>%</i>}<i></i>{<i>@</i>}<i></i>{<i>!</i>}<i></i>{<i>&lt;</i>}<i></i>{<i>&gt;</i>}<i></i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>resize an image (quickly)</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ -tile <i>&lt;geometry&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>layout of images [<em>montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-title">-title</a> <i>&lt;string&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>assign title to displayed image [<em>animate, display, montage</em>]</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transform">-transform</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>transform the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-transparent">-transparent</a> <i>&lt;color&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>make this color transparent within the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-treedepth">-treedepth</a> <i>&lt;value&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>tree depth for the color reduction algorithm</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-trim">-trim</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>trim an image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-type">-type</a> <i>&lt;type&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>the image type</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-verbose">-verbose</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print detailed information about the image</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-version">-version</a>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>print GraphicsMagick version string</td></tr></table>
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ <a href="GraphicsMagick.html#details-white-point">-white-point</a> <i>&lt;x&gt;,&lt;y&gt;</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>chromaticity white point</td></tr></table>
+<p>
+For a more detailed description of each option, see
+Options, above.
+<a href="GraphicsMagick.html"><em>GraphicsMagick(1)</em></a>.
+<br>&nbsp;<br>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="mont-xres"></a>X Resources
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>Montage</strong> options can appear on the command line or in your X resource
+file. Options on the command line supersede values specified in your X
+resource file. See <strong>X(1)</strong> for more information on X resources.
+<p>
+All <strong>montage</strong> options have a corresponding X resource. In addition,
+<strong>montage</strong>
+uses the following X resources:
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ background <i>(class Background)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>background color</td></tr></table>
+<p>
+Specifies the preferred color to use for the composite image background.
+The default is #ccc.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ borderColor <i>(class BorderColor)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>border color</td></tr></table>
+<p>
+Specifies the preferred color to use for the composite image border. The
+default is #ccc.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ borderWidth <i>(class BorderWidth)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>border width</td></tr></table>
+<p>
+Specifies the width in pixels of the composite image border. The default
+is 2.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ font <i>(class Font)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>font to use</td></tr></table>
+<p>
+Specifies the name of the preferred font to use when displaying text within
+the composite image. The default is 9x15, fixed, or 5x8 determined by the
+composite image size.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ matteColor <i>(class MatteColor)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>color of the frame</td></tr></table>
+<p>
+Specify the color of an image frame. A 3D effect is achieved by using highlight
+and shadow colors derived from this color. The default value is #697B8F.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ pen <i>(class Pen)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>text color</td></tr></table>
+<p>
+Specifies the preferred color to use for text within the composite image.
+The default is black.
+<table BORDER=0 WIDTH="94%">
+<tr>
+<td width="3%"><br></td>
+<td ALIGN=LEFT BGCOLOR="#FFFFFF">
+<img SRC="images/right_triangle_option.png"
+ALT=">" BORDER=0 height=14
+width=15><b><font face="Helvetica, Arial"
+><font color="#00B04F"><font size="+1">
+ title <i>(class Title)</i>
+</font></font></font></b></td></tr></table>
+<table width="90%" border="0" cellspacing="0" cellpadding="8"> <tr><td width="6%"><br></td><td>composite image title</td></tr></table>
+<p>
+This resource specifies the title to be placed at the top of the composite
+image. The default is not to place a title at the top of the composite
+image.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
diff --git a/www/motion-picture.html b/www/motion-picture.html
new file mode 100644
index 0000000..2e83001
--- /dev/null
+++ b/www/motion-picture.html
@@ -0,0 +1,791 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Cineon and SMTPE DPX Support</title>
+<meta content="Describes GraphicsMagick's support for Cineon and SMPTE DPX formats. " name="description" />
+<meta content="GraphicsMagick, Cineon, DPX, SMPTE 268M, Motion Picture" name="keywords" />
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-cineon-and-smtpe-dpx-support">
+<h1 class="title">GraphicsMagick Cineon and SMTPE DPX Support</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
+<li><a class="reference internal" href="#applications" id="id2">Applications</a></li>
+<li><a class="reference internal" href="#dpx-features" id="id3">DPX features</a><ul>
+<li><a class="reference internal" href="#basic" id="id4">Basic</a></li>
+<li><a class="reference internal" href="#colorspaces" id="id5">Colorspaces</a></li>
+<li><a class="reference internal" href="#storage" id="id6">Storage</a></li>
+<li><a class="reference internal" href="#yet-to-be-supported" id="id7">Yet to be supported</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#using-graphicsmagick" id="id8">Using GraphicsMagick</a><ul>
+<li><a class="reference internal" href="#image-resize" id="id9">Image Resize</a></li>
+<li><a class="reference internal" href="#annotate-image" id="id10">Annotate Image</a></li>
+<li><a class="reference internal" href="#colorspace-transformation" id="id11">Colorspace Transformation</a></li>
+<li><a class="reference internal" href="#modifying-an-image-in-place" id="id12">Modifying An Image In-Place</a></li>
+<li><a class="reference internal" href="#creating-a-contact-sheet" id="id13">Creating A Contact Sheet</a></li>
+<li><a class="reference internal" href="#animating-a-sequence" id="id14">Animating A Sequence</a></li>
+<li><a class="reference internal" href="#displaying-one-image-frame" id="id15">Displaying One Image Frame</a></li>
+<li><a class="reference internal" href="#viewing-a-sequence" id="id16">Viewing A Sequence</a></li>
+<li><a class="reference internal" href="#using-the-batch-capability" id="id17">Using the Batch capability</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#options-and-attributes" id="id18">Options And Attributes</a><ul>
+<li><a class="reference internal" href="#command-options" id="id19">Command options</a></li>
+<li><a class="reference internal" href="#dpx-attributes" id="id20">DPX Attributes</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="introduction">
+<h1><a class="toc-backref" href="#id1">Introduction</a></h1>
+<p>GraphicsMagick supports legacy Legacy 10-bit Kodak Cineon format as
+well as high-grade support for <a class="reference external" href="http://www.smpte.org/">SMPTE</a> DPX Version 2.0 (<a class="reference external" href="http://www.smpte.org/">SMPTE</a>
+268M-2003). SMPTE DPX RGB and YCbCr colorspaces are supported. The
+DPX implementation supports 8, 10, 12, and 16 bits/sample and any
+arbitrary image pixel size. The Cineon implementation supports 8 and
+10 bits/sample.</p>
+<p>Film images are usually captured at <em>2K</em> resolution (82 pixels/mm),
+<em>4K</em> resolution (164 pixels/mm), or even <em>8K</em> resolution (328
+pixels/mm), where the actual resolution values approximate the
+horizontal dimension of the image. A table of <a class="reference external" href="http://www.surrealroad.com/digital/index.php/archives/2005/standard-data-resolutions/">typical pixel
+resolutions</a> for various film sizes may be found on the <a class="reference external" href="http://blog.surrealroad.com//">Surreal
+Road</a> site (table reproduced here for convenience). File sizes may be
+quite large and range in size from 8MB to as much as 180MB. The common
+10-bit <em>2K</em> format consumes 12MB of disk while a 10-bit <em>4K</em> scan
+consumes 50MB of disk.</p>
+<table border="1" class="docutils">
+<caption>Standard data resolutions</caption>
+<colgroup>
+<col width="57%" />
+<col width="13%" />
+<col width="18%" />
+<col width="13%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Format</th>
+<th class="head">Picture
+aspect
+ratio</th>
+<th class="head">Standard
+pixel
+resolution</th>
+<th class="head">Pixel
+aspect
+ratio</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>Apple iPod video</td>
+<td class="decimal">1.33</td>
+<td>320×240</td>
+<td class="decimal">1.0</td>
+</tr>
+<tr><td>Apple iPhone video</td>
+<td class="decimal">1.5</td>
+<td>480×320</td>
+<td class="decimal">1.0</td>
+</tr>
+<tr><td>Sony PlayStationPortable</td>
+<td class="decimal">1.76</td>
+<td>480×272</td>
+<td class="decimal">1.0</td>
+</tr>
+<tr><td>SD video (PAL, DV)</td>
+<td class="decimal">1.33</td>
+<td>720×576</td>
+<td class="decimal">1.067</td>
+</tr>
+<tr><td>SD video (NTSC, DV)</td>
+<td class="decimal">1.33</td>
+<td>720×486</td>
+<td class="decimal">0.9</td>
+</tr>
+<tr><td>SD video (PAL, square pixels)</td>
+<td class="decimal">1.33</td>
+<td>768×576</td>
+<td class="decimal">1.0</td>
+</tr>
+<tr><td>SD video (NTSC, square pixels)</td>
+<td class="decimal">1.33</td>
+<td>648×486</td>
+<td class="decimal">1.0</td>
+</tr>
+<tr><td>DVD video (NTSC, 4:3)</td>
+<td class="decimal">1.33</td>
+<td>720×480</td>
+<td class="decimal">0.9</td>
+</tr>
+<tr><td>DVD video (PAL, 4:3)</td>
+<td class="decimal">1.33</td>
+<td>720×576</td>
+<td class="decimal">1.067</td>
+</tr>
+<tr><td>DVD video (NTSC, 16:9)</td>
+<td class="decimal">1.78</td>
+<td>720×480</td>
+<td class="decimal">1.185</td>
+</tr>
+<tr><td>DVD video (PAL, 16:9)</td>
+<td class="decimal">1.78</td>
+<td>720×576</td>
+<td class="decimal">1.69</td>
+</tr>
+<tr><td>Blu-ray</td>
+<td class="decimal">1.78</td>
+<td>1920×1080</td>
+<td class="decimal">1.0</td>
+</tr>
+<tr><td>HD video &#64;720</td>
+<td class="decimal">1.78</td>
+<td>1280×720</td>
+<td class="decimal">1.0</td>
+</tr>
+<tr><td>HD video &#64;1080 (certain types)</td>
+<td class="decimal">1.78</td>
+<td>1440×1080</td>
+<td class="decimal">1.33</td>
+</tr>
+<tr><td>HD video &#64;1080</td>
+<td class="decimal">1.78</td>
+<td>1920×1080</td>
+<td class="decimal">1.0</td>
+</tr>
+<tr><td>DVC Pro HD &#64;59.94i</td>
+<td class="decimal">1.78</td>
+<td>1280×1080</td>
+<td class="decimal">1.5</td>
+</tr>
+<tr><td>16mm</td>
+<td class="decimal">1.37</td>
+<td>1712×1240</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Super-16</td>
+<td class="decimal">1.65</td>
+<td>2048×1240</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>“Academy” aperture (2k)</td>
+<td class="decimal">1.37</td>
+<td>1828×1332</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>“Academy” aperture (4k)</td>
+<td class="decimal">1.37</td>
+<td>3656×2664</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Cinemascope (Squeezed, 2k)</td>
+<td class="decimal">2.35</td>
+<td>1828×1556</td>
+<td class="decimal">2.00</td>
+</tr>
+<tr><td>Cinemascope (Squeezed, 4k)</td>
+<td class="decimal">2.35</td>
+<td>3656×2664</td>
+<td class="decimal">2.00</td>
+</tr>
+<tr><td>Cinemascope (Unsqueezed, 2k)</td>
+<td class="decimal">2.35</td>
+<td>2048×872</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Cinemascope (Unsqueezed, 4k)</td>
+<td class="decimal">2.35</td>
+<td>3656×1556</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Full Aperture (2k)</td>
+<td class="decimal">1.33</td>
+<td>2048×1556</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Full Aperture (4k)</td>
+<td class="decimal">1.33</td>
+<td>4096×3112</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>8-perf “VistaVision” (3k)</td>
+<td class="decimal">1.5</td>
+<td>3072×2048</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>8-perf “VistaVision” (6k)</td>
+<td class="decimal">1.5</td>
+<td>6144×4096</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Red (16:9, 4k)</td>
+<td class="decimal">1.78</td>
+<td>4096×2304</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Red (2:1, 4k)</td>
+<td class="decimal">2.0</td>
+<td>4096×2048</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Digital Cinema (2k)</td>
+<td class="decimal">1.9</td>
+<td>2048×1080</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>Digital Cinema (4k)</td>
+<td class="decimal">1.9</td>
+<td>4096×2160</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>UHDTV (&quot;4k&quot;)</td>
+<td class="decimal">1.78</td>
+<td>3840×2160</td>
+<td class="decimal">1.00</td>
+</tr>
+<tr><td>UHDTV (&quot;8k&quot;)</td>
+<td class="decimal">1.78</td>
+<td>7860×4320</td>
+<td class="decimal">1.00</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="applications">
+<h1><a class="toc-backref" href="#id2">Applications</a></h1>
+<p>The strength of GraphicsMagick versus specialized proprietary software
+are its cost (absolutely free!), open source availability (user is
+able to fix software flaws or tailor software to meet specific needs),
+general purpose image processing capabilities, deep image capabilities
+(up to 32-bits per sample), excellent performance, platform
+independence, lack of encumbering usage licenses, and robust
+implementation. Examples of areas where GraphicsMagick may be used
+are:</p>
+<blockquote>
+<ul class="simple">
+<li>View the image on a display.</li>
+<li>Scaling (for example, <em>4K</em> to <em>2K</em> or 1920x1080 HD with excellent quality)</li>
+<li>Cropping</li>
+<li>Rotation</li>
+<li>Filtering</li>
+<li>ICC ICM profile-based color management and transformations</li>
+<li>Gamma adjustment</li>
+<li>Color adjustment</li>
+<li>Conversion to grayscale</li>
+<li>Text annotations</li>
+<li>Compositions</li>
+<li>Drawing on images (for example drawing markers on image)</li>
+<li>Conversion to and from other formats (e.g. Kodak Cineon, TIFF, JPEG, SGI,
+Postscript, PNG, and PNM)</li>
+</ul>
+</blockquote>
+<p>GraphicsMagick's DPX file format support is very comprehensive. It
+goes beyond the DPX format support in other applications by striving
+to implement the complete DPX specification rather than just a few
+commonly used sub-formats. The capabilities of GraphicsMagick's DPX
+support are as follows:</p>
+</div>
+<div class="section" id="dpx-features">
+<h1><a class="toc-backref" href="#id3">DPX features</a></h1>
+<div class="section" id="basic">
+<h2><a class="toc-backref" href="#id4">Basic</a></h2>
+<blockquote>
+<ul class="simple">
+<li>Anything which can be read, can also be written.</li>
+<li>All DPX header information (including the user specific area) are
+stored as image attributes and restored when the image is written.</li>
+<li>Image source header information is updated appropriately.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="colorspaces">
+<h2><a class="toc-backref" href="#id5">Colorspaces</a></h2>
+<blockquote>
+<ul class="simple">
+<li>Linear RGB</li>
+<li>Cineon Log RGB (default density range = 2.048)</li>
+<li>Grayscale (Luma)</li>
+<li>Rec. 601 and Rec. 709 YCbCr (4:4:4 and 4:2:2). Below-black and
+above-white values are clipped.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="storage">
+<h2><a class="toc-backref" href="#id6">Storage</a></h2>
+<blockquote>
+<ul class="simple">
+<li>Bits per sample of 1, 8, 10, 12, and 16.</li>
+<li>Packed, or fill type A or B for 10/12 bits.</li>
+<li>All RGB-oriented element types (R, G, B, A, RGB, RGBA, ABGR).</li>
+<li>YCbCr</li>
+<li>Planar (multi-element) storage fully supported.</li>
+<li>Alpha may be stored in a separate element.</li>
+<li>Big and little endian storage.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="yet-to-be-supported">
+<h2><a class="toc-backref" href="#id7">Yet to be supported</a></h2>
+<blockquote>
+<ul class="simple">
+<li>Composite video.</li>
+<li>Floating point formats (32 and 64 bits)</li>
+<li>Depth channel (not supportable within GraphicsMagick).</li>
+<li>Studio (reduced range) YCbCr and RGB.</li>
+</ul>
+</blockquote>
+<p>The software is written efficiently so the performance when reading
+and writing files is limited by the performance of the file I/O
+subsystem. The software is designed to avoid seeking while reading
+and writing so that files may be read and written over pipes, or via a
+user provided file descriptor.</p>
+</div>
+</div>
+<div class="section" id="using-graphicsmagick">
+<h1><a class="toc-backref" href="#id8">Using GraphicsMagick</a></h1>
+<div class="section" id="image-resize">
+<h2><a class="toc-backref" href="#id9">Image Resize</a></h2>
+<p>GraphicsMagick is easy to use. The following is an example of scaling
+a <em>4K</em> 16 bit scan to a <em>2K</em> <em>Academy</em> 10 bit image using the <a class="reference external" href="convert.html">convert</a>
+command:</p>
+<pre class="literal-block">
+gm convert 4k.dpx -resize 1828x1556 -depth 10 2k.dpx
+</pre>
+<p>The above example uses the default resizing filters which are
+optimized for quality, but take longer than some other filters. The
+<em>box</em> resize filter provides reasonably good scaling in a reasonable
+amount of time:</p>
+<pre class="literal-block">
+gm convert 4k.dpx -filter box -resize 1828x1556 -depth 10 2k.dpx
+</pre>
+<p>The above example command takes about 4 seconds (on an Apple 2.5GHz G5
+PowerMac or Intel 2.4GHz Xeon) to down-convert from a 131MB <em>5K</em>
+(5232x4376) original 16-bit scan from a NorthLight scanner to a 11MB
+<em>2K</em> 10-bit working image. Operations on more typical <em>2K</em> images take
+about a quarter of a second.</p>
+</div>
+<div class="section" id="annotate-image">
+<h2><a class="toc-backref" href="#id10">Annotate Image</a></h2>
+<p>The following example shows how GraphicsMagick's resize capability may
+be combined with its powerful drawing capability to take a full size
+source image and produce a smaller (720x576) version which includes
+the image filename and timecode at the top of the image, and a logo
+<em>bug</em> image in the bottom right corner:</p>
+<pre class="literal-block">
+gm convert infile.dpx -resize '720x576!' \
+ -draw 'fill &quot;white&quot;;text-undercolor &quot;Blue&quot;;font &quot;Helvetica&quot;;font-size 18;\
+ text 10,20 &quot;%f (%[DPX:tv.time.code])&quot;;image atop 500,400 0,0 &quot;gm-125x80t.png&quot;' \
+ outfile.dpx
+</pre>
+<p>As may be seen, the argument to -draw can become extremely long, so to
+make things easy, the drawing commands may be placed in a simple text
+file and passed by reference to the draw comand:</p>
+<p>First lets check what we edited into our drawing command file:</p>
+<pre class="literal-block">
+% cat drawcmd.txt
+fill &quot;white&quot;
+text-undercolor &quot;Blue&quot;
+font &quot;Helvetica&quot;
+font-size 18
+text 10,20 &quot;%f (%[DPX:tv.time.code])&quot;
+image atop 500,400 &quot;0,0 &quot;gm-125x80t.png&quot;
+</pre>
+<p>and now we can apply it by passing the filename prefixed with a '&#64;' to the
+-draw command:</p>
+<pre class="literal-block">
+gm convert infile.dpx -resize '720x576!' -draw '&#64;drawcmd.txt' outfile.dpx
+</pre>
+<p>The <tt class="docutils literal">0,0</tt> in the image composition command argument says to use the
+image as is. If the composited image should be automatically resized,
+then simply replace the <tt class="docutils literal">0,0</tt> with the desired size.</p>
+<p>There are a number of powerful scripting environments for
+GraphicsMagick. One of these is RMagick (Ruby language interface to
+GraphicsMagick). In Ruby, the same effect may be obtained via a script
+that looks like:</p>
+<pre class="literal-block">
+#! /usr/local/bin/ruby -w
+require 'RMagick'
+include Magick
+img = Image.read('infile.dpx')[0]
+frog = Image.read('gm-125x80t.png')[0]
+gc = Draw.new
+gc.fill('white')
+gc.text_undercolor(&quot;Blue&quot;)
+gc.font(&quot;Helvetica&quot;)
+gc.font_size(18)
+gc.text(10, 20, &quot;%f (%[DPX:tv.time.code])&quot;)
+gc.composite(500, 400, 0, 0, frog, AtopCompositeOp)
+gc.draw(img)
+img.write('outfile.dpx')
+</pre>
+<p>In addition to Ruby, there are scripting interfaces for Perl, Python,
+Tcl, and Ch (C-like scripting language).</p>
+</div>
+<div class="section" id="colorspace-transformation">
+<h2><a class="toc-backref" href="#id11">Colorspace Transformation</a></h2>
+<p>To convert an RGB file to a 4:2:2 YCbCr file in Rec 709 space:</p>
+<pre class="literal-block">
+gm convert 2k.dpx -depth 10 -colorspace Rec709YCbCr -sampling-factor 4:2:2 2k-ycbcr.dpx
+</pre>
+</div>
+<div class="section" id="modifying-an-image-in-place">
+<h2><a class="toc-backref" href="#id12">Modifying An Image In-Place</a></h2>
+<p>Besides convert, which converts from one file to another, there is
+<a class="reference external" href="mogrify.html">mogrify</a> which transforms the file in place. A temporary file is used
+(if necessary) to ensure that the existing image file is not damaged
+if something goes wrong (e.g., not enough disk space). Note that
+unlike some applications supporting DPX/Cineon, when a file is modifed
+<em>in-place</em> , it is completely re-written. While GraphicsMagick makes
+every attempt to preserve header information, some previously existing
+features of the file (such as the offset to the pixel data) may
+change.</p>
+<p>A typical mogrify command is</p>
+<pre class="literal-block">
+gm mogrify -resize 1828x1556 -depth 10 file-0001.dpx file-0002.dpx
+</pre>
+<p>Multiple files may be specified on the command line so the same
+command may process hundreds of files in one invocation.</p>
+<p>Unix users can use the find and xargs programs to perform operations
+on any number of files:</p>
+<pre class="literal-block">
+find /assets/001 -name '*.dpx' -print | \
+ xargs gm mogrify -resize 1828x1556 -depth 10
+</pre>
+<p>Xargs works by pasting as many file names as possible on the end of
+the command provided to it.</p>
+<p>The GNU version of xargs provides an added benefit. It is able to run
+several commands in the background. This means that if your system has
+multiple CPUs, it can take advantage of all the CPUs while still using
+one command:</p>
+<pre class="literal-block">
+find /assets/001 -name '*.dpx' -print | \
+ xargs --max-procs 3 --max-args 25 gm mogrify -resize 1828x1556 -depth 10
+</pre>
+<p>The mogrify command supports the -output-directory option to sent
+files to a different directory than the input files. This allows
+processing a large number of files without overwriting the input
+files:</p>
+<pre class="literal-block">
+mkdir dest
+cd source
+gm mogrify -output-directory ../dest -resize 1828x1556 -depth 10 '*.dpx'
+</pre>
+<p>Note that the entire input file path specification is preserved when
+composing the output path so that the input file path is simply
+appended to the output directory path. Also, unless the
+-create-directories option is added, the user is responsible for
+creating any necessary destination directories. As an example of the
+path composition algorithm, if the input file name is specified as
+source/file.dpx and the output directory is specified as dest, then
+the output file path will be dest/source/file.dpx.</p>
+<p>Here is an incantation which recursively processes all DPX files under
+source and sends the result to a similar directory tree under dest.</p>
+<pre class="literal-block">
+mkdir dest
+cd source
+find . name '*.dpx' -print | xargs gm mogrify -output-directory ../dest \
+ -create-directories -resize 1828x1556 -depth 10
+</pre>
+</div>
+<div class="section" id="creating-a-contact-sheet">
+<h2><a class="toc-backref" href="#id13">Creating A Contact Sheet</a></h2>
+<p>GraphicsMagick may be used to create a contact sheet (grid of
+thumbnails with name and size) by using the <em>VID</em> pseudoformat which
+accepts a wildcarded argument of files (protected by quotes!) to
+read. The output files are buffered while files are being read so
+there is a practical limit to the number of files which may be
+processed at once. To output to a Postscript file:</p>
+<pre class="literal-block">
+gm convert &quot;vid:*.dpx&quot; &quot;contact-sheet.ps&quot;
+</pre>
+<p>or to a PDF file:</p>
+<pre class="literal-block">
+gm convert &quot;vid:*.dpx&quot; &quot;contact-sheet.pdf&quot;
+</pre>
+<p>or to a sequence of JPEG files ranging from contact-sheet-000.jpg to
+contact-sheet-999.jpg:</p>
+<pre class="literal-block">
+gm convert &quot;vid:*.dpx&quot; &quot;contact-sheet-%03d.jpg&quot;
+</pre>
+<p>or to a MIFF file which may be used to interactively browse the
+original files using 'gm display':</p>
+<pre class="literal-block">
+gm convert &quot;vid:*.dpx&quot; &quot;contact-sheet.miff&quot;
+</pre>
+</div>
+<div class="section" id="animating-a-sequence">
+<h2><a class="toc-backref" href="#id14">Animating A Sequence</a></h2>
+<p>GraphicsMagick may be used to animate an image sequence on an X11
+display using the <a class="reference external" href="animate.html">animate</a> subcommand. Frames are buffered in memory
+(pre-loaded into the X11 server) so the number of frames which may be
+animated at once is limited. GraphicsMagick has been used to animate
+1080P (1920x1080) images at 24 frames per second with at least 300
+frames in the sequence.More frames may be buffered on 64-bit
+systems. Many more frames may be animated by preparing a reduced set
+of frames in advance.</p>
+<p>To visualize an animation at 24 frames per second (delay (1/24)*100) use</p>
+<pre class="literal-block">
+gm animate -delay 4.17 'Frame_*.dpx'
+</pre>
+<p>In order to obtain a preview of a larger sequence, and if the frames
+are numbered, a broader span of time may be animated by selecting
+every 10^th frame (terminating with zero) to animate at 2.4 frames per
+second:</p>
+<pre class="literal-block">
+gm animate -delay 41.7 'Frame_*0.dpx'
+</pre>
+</div>
+<div class="section" id="displaying-one-image-frame">
+<h2><a class="toc-backref" href="#id15">Displaying One Image Frame</a></h2>
+<p>An image frame may be displayed on an X11 server using the <a class="reference external" href="display.html">display</a>
+subcommand. By default the name of the image file is displayed in the
+title bar. By specifying the format of the title, other useful
+information such as the time code (see the DPX Attributes section for
+more details) may be included in the window title:</p>
+<pre class="literal-block">
+gm display -title '%f (%[DPX:tv.time.code])' foo.dpx
+</pre>
+</div>
+<div class="section" id="viewing-a-sequence">
+<h2><a class="toc-backref" href="#id16">Viewing A Sequence</a></h2>
+<p>A sequence of images may be displayed on an X11 server using the
+<a class="reference external" href="display.html">display</a> subcommand. Unlike 'gm animate' there are no arbitrary limits
+when displaying a sequence this way. Unlike 'gm animate' the
+inter-frame delay can not be set to less than a second (100 ticks is
+one second).</p>
+<pre class="literal-block">
+gm display +progress -delay 100 'Frame_*.dpx'
+</pre>
+</div>
+<div class="section" id="using-the-batch-capability">
+<h2><a class="toc-backref" href="#id17">Using the Batch capability</a></h2>
+<p>A 'batch' command is provided (starting with the GraphicsMagick 1.3.18
+release) which supports executing an arbitrary number of
+GraphicsMagick commands from a file, or provided via standard input,
+while executing just one instance of GraphicsMagick. This provides
+for more efficiency and for use of GraphicsMagick as a co-process. An
+arbitrary script which produces the commands may continue to produce
+the commands as GraphicsMagick executes them. For example (Bourne
+shell script):</p>
+<pre class="literal-block">
+outdir=outdir
+mkdir $outdir
+find fromdir -name '*.dpx'| sort |
+while read infile
+do
+ outfile=$outdir/`basename $infile`
+ echo time convert $infile -gaussian 0x1 $outfile
+done | gm batch -
+</pre>
+</div>
+</div>
+<div class="section" id="options-and-attributes">
+<h1><a class="toc-backref" href="#id18">Options And Attributes</a></h1>
+<div class="section" id="command-options">
+<h2><a class="toc-backref" href="#id19">Command options</a></h2>
+<p>The following command options are particularly useful when dealing with
+DPX files:</p>
+<dl class="docutils">
+<dt>-colorspace {CineonLog|RGB|Gray|Rec601Luma|Rec709Luma|Rec601YCbCr|Rec709YCbCr}</dt>
+<dd>Specifies the colorspace to be used when saving the DPX
+file. CineonLog selects log encoding according to Kodak Cineon
+specifications. RGB selects linear RGB encoding. Gray selects
+linear gray encoding similar to RGB, but with a single
+channel. Rec601Luma requests that RGB is converted to a gray image
+using Rec601 Luma. Rec709Luma requests that RGB is converted to a
+gray image using Rec709Luma. Rec601YCbCr requests that the image
+is saved as YCbCr according to Rec601 (SDTV)
+specifications. Rec709CbCr requests that the image is saved as
+YCbCr according to Rec709 (HDTV) specifications.</dd>
+<dt>-endian {lsb|msb}</dt>
+<dd>Specifies the endian order to use when writing the DPX
+file. GraphicsMagick writes big-endian DPX files by default since
+they are the most portable. Other implementations may use the
+native order of the host CPU (e.g. little-endian when using an
+Intel 'x86 CPU).</dd>
+<dt>-depth &lt;value&gt;</dt>
+<dd>Specifies the number of bits to preserve in a color sample. By
+default the output file is written with the same number of bits as
+the input file. For example, if the input file is 16 bits, it may
+be reduced to 10 bits via '-depth 10'.</dd>
+<dt>-define dpx:bits-per-sample=&lt;value&gt;</dt>
+<dd>If the dpx:bits-per-sample key is defined, GraphicsMagick will
+write DPX images with the specified bits per sample, overriding
+any existing depth value. If this option is not specified, then
+the value is based on the existing image depth value from the
+original image file. The DPX standard supports bits per sample
+values of 1, 8, 10, 12, and 16. Many DPX readers demand a sample
+size of 10 bits with type A padding (see below).</dd>
+<dt>-define dpx:colorspace={rgb|cineonlog}</dt>
+<dd>Use the dpx:colorspace option when reading a DPX file to specify
+the colorspace the DPX file uses. This overrides the colorspace
+type implied by the DPX header (if any). Currently files with the
+transfer characteristic Printing Density are assumed to be log
+encoded density while files marked as Linear are assumed to be
+linear. Hint: use <tt class="docutils literal"><span class="pre">-define</span> dpx:colorspace=rgb</tt> in order to avoid
+the log to linear transformation for DPX files which use Printing
+Density.</dd>
+<dt>-define dpx:packing-method={packed|a|b|lsbpad|msbpad}</dt>
+<dd>DPX samples may be output within 32-bit words. They may be tightly
+packed end-to-end within the words (&quot;packed&quot;), padded with null
+bits to the right of the sample (&quot;a&quot; or &quot;lsbpad&quot;), or padded with
+null bits to the left of the sample (&quot;b&quot; or &quot;msbpad&quot;). This option
+only has an effect for sample sizes of 10 or 12 bits. If samples
+are not packed, the DPX standard recommends type A padding. Many
+DPX readers demand a sample size of 10 bits with type A padding.</dd>
+<dt>-define dpx:pixel-endian={lsb|msb}</dt>
+<dd>DPX pixels should use the endian order that the DPX header
+specifies. Sometimes there is a mis-match and the pixels use a
+different endian order than the file header specifies. For
+example, the file header may specify little endian, but the pixels
+are in big-endian order. To work around that use -define
+dpx-pixel-endian=msb when reading the file. Likewise, this option
+may be used to intentionally write the pixels using a different
+order than the header.</dd>
+<dt>-define dpx:swap-samples={true|false}</dt>
+<dd>GraphicsMagick strives to adhere to the DPX standard but certain
+aspects of the standard can be quite confusing. As a result, some
+10-bit DPX files have Red and Blue interchanged, or Cb and Cr
+interchanged due to an different interpretation of the standard,
+or getting the wires crossed. The swap-samples option may be
+supplied when reading or writing in order to read or write using
+the necessary sample order.</dd>
+<dt>-interlace plane</dt>
+<dd>By default, samples are stored contiguously in a single element
+when possible. Specifying '-interlace plane' causes each sample
+type (e.g. 'red') to be stored in its own image element. Planar
+storage is fully supported for grayscale (with alpha) and RGB. For
+YCbCr, chroma must be 4:2:2 subsampled in order to use planar
+storage. While planar storage offers a number of benefits, it
+seems that very few DPX-supporting applications support it.</dd>
+<dt>-sampling-factor 4:2:2</dt>
+<dd>Select 4:2:2subsampling when saving an image in YCbCr
+format. Subsampling is handled via a general-purpose image resize
+algorithm (lanczos) rather than a dedicated filter so subsampling
+is slow (but good).</dd>
+<dt>-set reference-white &lt;value&gt;</dt>
+<dd>Set the 90% white card level (default 685) for Cineon Log.</dd>
+<dt>-set reference-black &lt;value&gt;</dt>
+<dd>Set the 1% black card level (default 95) for Cineon Log.</dd>
+<dt>-set display-gamma &lt;value&gt;</dt>
+<dd>Set the display gamma (default 1.7) for Cineon Log.</dd>
+<dt>-set film-gamma &lt;value&gt;</dt>
+<dd>Set the film gamma (default 0.6) for Cineon Log.</dd>
+<dt>-set soft-clip-offset &lt;value&gt;</dt>
+<dd>Set the soft clip offset (default 0) when converting to <em>computer</em> RGB from
+Cineon Log.</dd>
+</dl>
+</div>
+<div class="section" id="dpx-attributes">
+<h2><a class="toc-backref" href="#id20">DPX Attributes</a></h2>
+<p>GraphicsMagick provides almost full access to DPX header
+attributes. DPX header attributes are shown in the output of 'gm
+identify -verbose' and may be set using the -define syntax
+(e.g. '-define dpx:mp.frame.position=2000') on the command line in
+order to add a value, or override an existing value. The attributes in
+the list below may be viewed or updated. The names are similar to the
+attribute descriptions from the DPX standard.</p>
+<pre class="literal-block">
+dpx:file.copyright
+dpx:file.creation.datetime
+dpx:file.creator
+dpx:file.encryption.key
+dpx:file.filename
+dpx:file.project.name
+dpx:file.version
+dpx:image.orientation
+dpx:mp.count
+dpx:mp.film.manufacturer.id
+dpx:mp.film.type
+dpx:mp.format
+dpx:mp.frame.id
+dpx:mp.frame.position
+dpx:mp.frame.rate
+dpx:mp.held.count
+dpx:mp.perfs.offset
+dpx:mp.prefix
+dpx:mp.sequence.length
+dpx:mp.shutter.angle
+dpx:mp.slate.info
+dpx:source.aspect.ratio.horizontal
+dpx:source.aspect.ratio.vertical
+dpx:source.border.validity.bottom
+dpx:source.border.validity.left
+dpx:source.border.validity.right
+dpx:source.border.validity.top
+dpx:source.creation.datetime
+dpx:source.device.name
+dpx:source.device.serialnumber
+dpx:source.filename
+dpx:source.scanned.size.x
+dpx:source.scanned.size.y
+dpx:source.x-center
+dpx:source.x-offset
+dpx:source.x-original-size
+dpx:source.y-center
+dpx:source.y-offset
+dpx:source.y-original-size
+dpx:tv.black.gain
+dpx:tv.black.level
+dpx:tv.breakpoint
+dpx:tv.field.number
+dpx:tv.gama
+dpx:tv.horizontal.sampling.rate
+dpx:tv.integration.time
+dpx:tv.interlace
+dpx:tv.sync.time
+dpx:tv.temporal.sampling.rate
+dpx:tv.time.code
+dpx:tv.user.bits
+dpx:tv.video.signal
+dpx:tv.white.level
+dpx:user.data.id
+</pre>
+<p>Specific header values from a DPX file may be displayed quickly using a command
+similar to:</p>
+<pre class="literal-block">
+gm identify -format '%[DPX:tv.time.code]' foo.dpx
+</pre>
+<p>Use</p>
+<pre class="literal-block">
+gm identify -format '%[dpx:*]' foo.dpx
+</pre>
+<p>to list all DPX header attributes.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/motion-picture.rst b/www/motion-picture.rst
new file mode 100644
index 0000000..6533f13
--- /dev/null
+++ b/www/motion-picture.rst
@@ -0,0 +1,643 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+===========================================
+GraphicsMagick Cineon and SMTPE DPX Support
+===========================================
+
+.. meta::
+ :description: Describes GraphicsMagick's support for Cineon and SMPTE
+ DPX formats.
+
+ :keywords: GraphicsMagick, Cineon, DPX, SMPTE 268M, Motion Picture
+
+.. _GraphicsMagick : index.html
+.. _SMPTE : http://www.smpte.org/
+.. _typical pixel resolutions : http://www.surrealroad.com/digital/index.php/archives/2005/standard-data-resolutions/
+.. _Surreal Road : http://blog.surrealroad.com//
+
+.. _animate : animate.html
+.. _composite : composite.html
+.. _compare : compare.html
+.. _conjure : conjure.html
+.. _convert : convert.html
+.. _display : display.html
+.. _identify : identify.html
+.. _import : import.html
+.. _mogrify : mogrify.html
+.. _montage : montage.html
+
+
+.. contents::
+ :local:
+
+Introduction
+============
+
+GraphicsMagick supports legacy Legacy 10-bit Kodak Cineon format as
+well as high-grade support for SMPTE_ DPX Version 2.0 (SMPTE_
+268M-2003). SMPTE DPX RGB and YCbCr colorspaces are supported. The
+DPX implementation supports 8, 10, 12, and 16 bits/sample and any
+arbitrary image pixel size. The Cineon implementation supports 8 and
+10 bits/sample.
+
+Film images are usually captured at *2K* resolution (82 pixels/mm),
+*4K* resolution (164 pixels/mm), or even *8K* resolution (328
+pixels/mm), where the actual resolution values approximate the
+horizontal dimension of the image. A table of `typical pixel
+resolutions`_ for various film sizes may be found on the `Surreal
+Road`_ site (table reproduced here for convenience). File sizes may be
+quite large and range in size from 8MB to as much as 180MB. The common
+10-bit *2K* format consumes 12MB of disk while a 10-bit *4K* scan
+consumes 50MB of disk.
+
+.. table:: Standard data resolutions
+
+ ================================ ======= ========== =======
+ Format Picture Standard Pixel
+ aspect pixel aspect
+ ratio resolution ratio
+ ================================ ======= ========== =======
+ Apple iPod video 1.33 320×240 1.0
+ Apple iPhone video 1.5 480×320 1.0
+ Sony PlayStationPortable 1.76 480×272 1.0
+ SD video (PAL, DV) 1.33 720×576 1.067
+ SD video (NTSC, DV) 1.33 720×486 0.9
+ SD video (PAL, square pixels) 1.33 768×576 1.0
+ SD video (NTSC, square pixels) 1.33 648×486 1.0
+ DVD video (NTSC, 4:3) 1.33 720×480 0.9
+ DVD video (PAL, 4:3) 1.33 720×576 1.067
+ DVD video (NTSC, 16:9) 1.78 720×480 1.185
+ DVD video (PAL, 16:9) 1.78 720×576 1.69
+ Blu-ray 1.78 1920×1080 1.0
+ HD video @720 1.78 1280×720 1.0
+ HD video @1080 (certain types) 1.78 1440×1080 1.33
+ HD video @1080 1.78 1920×1080 1.0
+ DVC Pro HD @59.94i 1.78 1280×1080 1.5
+ 16mm 1.37 1712×1240 1.00
+ Super-16 1.65 2048×1240 1.00
+ “Academy” aperture (2k) 1.37 1828×1332 1.00
+ “Academy” aperture (4k) 1.37 3656×2664 1.00
+ Cinemascope (Squeezed, 2k) 2.35 1828×1556 2.00
+ Cinemascope (Squeezed, 4k) 2.35 3656×2664 2.00
+ Cinemascope (Unsqueezed, 2k) 2.35 2048×872 1.00
+ Cinemascope (Unsqueezed, 4k) 2.35 3656×1556 1.00
+ Full Aperture (2k) 1.33 2048×1556 1.00
+ Full Aperture (4k) 1.33 4096×3112 1.00
+ 8-perf “VistaVision” (3k) 1.5 3072×2048 1.00
+ 8-perf “VistaVision” (6k) 1.5 6144×4096 1.00
+ Red (16:9, 4k) 1.78 4096×2304 1.00
+ Red (2:1, 4k) 2.0 4096×2048 1.00
+ Digital Cinema (2k) 1.9 2048×1080 1.00
+ Digital Cinema (4k) 1.9 4096×2160 1.00
+ UHDTV ("4k") 1.78 3840×2160 1.00
+ UHDTV ("8k") 1.78 7860×4320 1.00
+ ================================ ======= ========== =======
+
+Applications
+============
+
+The strength of GraphicsMagick versus specialized proprietary software
+are its cost (absolutely free!), open source availability (user is
+able to fix software flaws or tailor software to meet specific needs),
+general purpose image processing capabilities, deep image capabilities
+(up to 32-bits per sample), excellent performance, platform
+independence, lack of encumbering usage licenses, and robust
+implementation. Examples of areas where GraphicsMagick may be used
+are:
+
+ * View the image on a display.
+ * Scaling (for example, *4K* to *2K* or 1920x1080 HD with excellent quality)
+ * Cropping
+ * Rotation
+ * Filtering
+ * ICC ICM profile-based color management and transformations
+ * Gamma adjustment
+ * Color adjustment
+ * Conversion to grayscale
+ * Text annotations
+ * Compositions
+ * Drawing on images (for example drawing markers on image)
+ * Conversion to and from other formats (e.g. Kodak Cineon, TIFF, JPEG, SGI,
+ Postscript, PNG, and PNM)
+
+GraphicsMagick's DPX file format support is very comprehensive. It
+goes beyond the DPX format support in other applications by striving
+to implement the complete DPX specification rather than just a few
+commonly used sub-formats. The capabilities of GraphicsMagick's DPX
+support are as follows:
+
+DPX features
+============
+
+Basic
+-----
+
+ * Anything which can be read, can also be written.
+
+ * All DPX header information (including the user specific area) are
+ stored as image attributes and restored when the image is written.
+
+ * Image source header information is updated appropriately.
+
+Colorspaces
+-----------
+
+ * Linear RGB
+
+ * Cineon Log RGB (default density range = 2.048)
+
+ * Grayscale (Luma)
+
+ * Rec. 601 and Rec. 709 YCbCr (4:4:4 and 4:2:2). Below-black and
+ above-white values are clipped.
+
+Storage
+-------
+
+ * Bits per sample of 1, 8, 10, 12, and 16.
+
+ * Packed, or fill type A or B for 10/12 bits.
+
+ * All RGB-oriented element types (R, G, B, A, RGB, RGBA, ABGR).
+
+ * YCbCr
+
+ * Planar (multi-element) storage fully supported.
+
+ * Alpha may be stored in a separate element.
+
+ * Big and little endian storage.
+
+Yet to be supported
+-------------------
+
+ * Composite video.
+
+ * Floating point formats (32 and 64 bits)
+
+ * Depth channel (not supportable within GraphicsMagick).
+
+ * Studio (reduced range) YCbCr and RGB.
+
+The software is written efficiently so the performance when reading
+and writing files is limited by the performance of the file I/O
+subsystem. The software is designed to avoid seeking while reading
+and writing so that files may be read and written over pipes, or via a
+user provided file descriptor.
+
+Using GraphicsMagick
+====================
+
+Image Resize
+------------
+
+GraphicsMagick is easy to use. The following is an example of scaling
+a *4K* 16 bit scan to a *2K* *Academy* 10 bit image using the convert_
+command::
+
+ gm convert 4k.dpx -resize 1828x1556 -depth 10 2k.dpx
+
+The above example uses the default resizing filters which are
+optimized for quality, but take longer than some other filters. The
+*box* resize filter provides reasonably good scaling in a reasonable
+amount of time::
+
+ gm convert 4k.dpx -filter box -resize 1828x1556 -depth 10 2k.dpx
+
+The above example command takes about 4 seconds (on an Apple 2.5GHz G5
+PowerMac or Intel 2.4GHz Xeon) to down-convert from a 131MB *5K*
+(5232x4376) original 16-bit scan from a NorthLight scanner to a 11MB
+*2K* 10-bit working image. Operations on more typical *2K* images take
+about a quarter of a second.
+
+Annotate Image
+--------------
+
+The following example shows how GraphicsMagick's resize capability may
+be combined with its powerful drawing capability to take a full size
+source image and produce a smaller (720x576) version which includes
+the image filename and timecode at the top of the image, and a logo
+*bug* image in the bottom right corner::
+
+ gm convert infile.dpx -resize '720x576!' \
+ -draw 'fill "white";text-undercolor "Blue";font "Helvetica";font-size 18;\
+ text 10,20 "%f (%[DPX:tv.time.code])";image atop 500,400 0,0 "gm-125x80t.png"' \
+ outfile.dpx
+
+As may be seen, the argument to -draw can become extremely long, so to
+make things easy, the drawing commands may be placed in a simple text
+file and passed by reference to the draw comand:
+
+First lets check what we edited into our drawing command file::
+
+ % cat drawcmd.txt
+ fill "white"
+ text-undercolor "Blue"
+ font "Helvetica"
+ font-size 18
+ text 10,20 "%f (%[DPX:tv.time.code])"
+ image atop 500,400 "0,0 "gm-125x80t.png"
+
+and now we can apply it by passing the filename prefixed with a '@' to the
+-draw command::
+
+ gm convert infile.dpx -resize '720x576!' -draw '@drawcmd.txt' outfile.dpx
+
+The ``0,0`` in the image composition command argument says to use the
+image as is. If the composited image should be automatically resized,
+then simply replace the ``0,0`` with the desired size.
+
+There are a number of powerful scripting environments for
+GraphicsMagick. One of these is RMagick (Ruby language interface to
+GraphicsMagick). In Ruby, the same effect may be obtained via a script
+that looks like::
+
+ #! /usr/local/bin/ruby -w
+ require 'RMagick'
+ include Magick
+ img = Image.read('infile.dpx')[0]
+ frog = Image.read('gm-125x80t.png')[0]
+ gc = Draw.new
+ gc.fill('white')
+ gc.text_undercolor("Blue")
+ gc.font("Helvetica")
+ gc.font_size(18)
+ gc.text(10, 20, "%f (%[DPX:tv.time.code])")
+ gc.composite(500, 400, 0, 0, frog, AtopCompositeOp)
+ gc.draw(img)
+ img.write('outfile.dpx')
+
+In addition to Ruby, there are scripting interfaces for Perl, Python,
+Tcl, and Ch (C-like scripting language).
+
+Colorspace Transformation
+-------------------------
+
+To convert an RGB file to a 4:2:2 YCbCr file in Rec 709 space::
+
+ gm convert 2k.dpx -depth 10 -colorspace Rec709YCbCr -sampling-factor 4:2:2 2k-ycbcr.dpx
+
+Modifying An Image In-Place
+---------------------------
+
+Besides convert, which converts from one file to another, there is
+mogrify_ which transforms the file in place. A temporary file is used
+(if necessary) to ensure that the existing image file is not damaged
+if something goes wrong (e.g., not enough disk space). Note that
+unlike some applications supporting DPX/Cineon, when a file is modifed
+*in-place* , it is completely re-written. While GraphicsMagick makes
+every attempt to preserve header information, some previously existing
+features of the file (such as the offset to the pixel data) may
+change.
+
+A typical mogrify command is
+
+::
+
+ gm mogrify -resize 1828x1556 -depth 10 file-0001.dpx file-0002.dpx
+
+Multiple files may be specified on the command line so the same
+command may process hundreds of files in one invocation.
+
+Unix users can use the find and xargs programs to perform operations
+on any number of files::
+
+ find /assets/001 -name '*.dpx' -print | \
+ xargs gm mogrify -resize 1828x1556 -depth 10
+
+Xargs works by pasting as many file names as possible on the end of
+the command provided to it.
+
+The GNU version of xargs provides an added benefit. It is able to run
+several commands in the background. This means that if your system has
+multiple CPUs, it can take advantage of all the CPUs while still using
+one command::
+
+ find /assets/001 -name '*.dpx' -print | \
+ xargs --max-procs 3 --max-args 25 gm mogrify -resize 1828x1556 -depth 10
+
+The mogrify command supports the -output-directory option to sent
+files to a different directory than the input files. This allows
+processing a large number of files without overwriting the input
+files::
+
+ mkdir dest
+ cd source
+ gm mogrify -output-directory ../dest -resize 1828x1556 -depth 10 '*.dpx'
+
+Note that the entire input file path specification is preserved when
+composing the output path so that the input file path is simply
+appended to the output directory path. Also, unless the
+-create-directories option is added, the user is responsible for
+creating any necessary destination directories. As an example of the
+path composition algorithm, if the input file name is specified as
+source/file.dpx and the output directory is specified as dest, then
+the output file path will be dest/source/file.dpx.
+
+Here is an incantation which recursively processes all DPX files under
+source and sends the result to a similar directory tree under dest.
+
+::
+
+ mkdir dest
+ cd source
+ find . name '*.dpx' -print | xargs gm mogrify -output-directory ../dest \
+ -create-directories -resize 1828x1556 -depth 10
+
+Creating A Contact Sheet
+------------------------
+
+GraphicsMagick may be used to create a contact sheet (grid of
+thumbnails with name and size) by using the *VID* pseudoformat which
+accepts a wildcarded argument of files (protected by quotes!) to
+read. The output files are buffered while files are being read so
+there is a practical limit to the number of files which may be
+processed at once. To output to a Postscript file::
+
+ gm convert "vid:*.dpx" "contact-sheet.ps"
+
+or to a PDF file::
+
+ gm convert "vid:*.dpx" "contact-sheet.pdf"
+
+or to a sequence of JPEG files ranging from contact-sheet-000.jpg to
+contact-sheet-999.jpg::
+
+ gm convert "vid:*.dpx" "contact-sheet-%03d.jpg"
+
+or to a MIFF file which may be used to interactively browse the
+original files using 'gm display'::
+
+ gm convert "vid:*.dpx" "contact-sheet.miff"
+
+Animating A Sequence
+--------------------
+
+GraphicsMagick may be used to animate an image sequence on an X11
+display using the animate_ subcommand. Frames are buffered in memory
+(pre-loaded into the X11 server) so the number of frames which may be
+animated at once is limited. GraphicsMagick has been used to animate
+1080P (1920x1080) images at 24 frames per second with at least 300
+frames in the sequence.More frames may be buffered on 64-bit
+systems. Many more frames may be animated by preparing a reduced set
+of frames in advance.
+
+To visualize an animation at 24 frames per second (delay (1/24)*100) use
+
+::
+
+ gm animate -delay 4.17 'Frame_*.dpx'
+
+In order to obtain a preview of a larger sequence, and if the frames
+are numbered, a broader span of time may be animated by selecting
+every 10^th frame (terminating with zero) to animate at 2.4 frames per
+second::
+
+ gm animate -delay 41.7 'Frame_*0.dpx'
+
+Displaying One Image Frame
+--------------------------
+
+An image frame may be displayed on an X11 server using the display_
+subcommand. By default the name of the image file is displayed in the
+title bar. By specifying the format of the title, other useful
+information such as the time code (see the DPX Attributes section for
+more details) may be included in the window title::
+
+ gm display -title '%f (%[DPX:tv.time.code])' foo.dpx
+
+Viewing A Sequence
+------------------
+
+A sequence of images may be displayed on an X11 server using the
+display_ subcommand. Unlike 'gm animate' there are no arbitrary limits
+when displaying a sequence this way. Unlike 'gm animate' the
+inter-frame delay can not be set to less than a second (100 ticks is
+one second).
+
+::
+
+ gm display +progress -delay 100 'Frame_*.dpx'
+
+Using the Batch capability
+--------------------------
+
+A 'batch' command is provided (starting with the GraphicsMagick 1.3.18
+release) which supports executing an arbitrary number of
+GraphicsMagick commands from a file, or provided via standard input,
+while executing just one instance of GraphicsMagick. This provides
+for more efficiency and for use of GraphicsMagick as a co-process. An
+arbitrary script which produces the commands may continue to produce
+the commands as GraphicsMagick executes them. For example (Bourne
+shell script)::
+
+ outdir=outdir
+ mkdir $outdir
+ find fromdir -name '*.dpx'| sort |
+ while read infile
+ do
+ outfile=$outdir/`basename $infile`
+ echo time convert $infile -gaussian 0x1 $outfile
+ done | gm batch -
+
+
+Options And Attributes
+======================
+
+Command options
+---------------
+
+The following command options are particularly useful when dealing with
+DPX files:
+
+-colorspace {CineonLog|RGB|Gray|Rec601Luma|Rec709Luma|Rec601YCbCr|Rec709YCbCr}
+ Specifies the colorspace to be used when saving the DPX
+ file. CineonLog selects log encoding according to Kodak Cineon
+ specifications. RGB selects linear RGB encoding. Gray selects
+ linear gray encoding similar to RGB, but with a single
+ channel. Rec601Luma requests that RGB is converted to a gray image
+ using Rec601 Luma. Rec709Luma requests that RGB is converted to a
+ gray image using Rec709Luma. Rec601YCbCr requests that the image
+ is saved as YCbCr according to Rec601 (SDTV)
+ specifications. Rec709CbCr requests that the image is saved as
+ YCbCr according to Rec709 (HDTV) specifications.
+
+-endian {lsb|msb}
+ Specifies the endian order to use when writing the DPX
+ file. GraphicsMagick writes big-endian DPX files by default since
+ they are the most portable. Other implementations may use the
+ native order of the host CPU (e.g. little-endian when using an
+ Intel 'x86 CPU).
+
+-depth <value>
+ Specifies the number of bits to preserve in a color sample. By
+ default the output file is written with the same number of bits as
+ the input file. For example, if the input file is 16 bits, it may
+ be reduced to 10 bits via '-depth 10'.
+
+-define dpx:bits-per-sample=<value>
+ If the dpx:bits-per-sample key is defined, GraphicsMagick will
+ write DPX images with the specified bits per sample, overriding
+ any existing depth value. If this option is not specified, then
+ the value is based on the existing image depth value from the
+ original image file. The DPX standard supports bits per sample
+ values of 1, 8, 10, 12, and 16. Many DPX readers demand a sample
+ size of 10 bits with type A padding (see below).
+
+-define dpx:colorspace={rgb|cineonlog}
+ Use the dpx:colorspace option when reading a DPX file to specify
+ the colorspace the DPX file uses. This overrides the colorspace
+ type implied by the DPX header (if any). Currently files with the
+ transfer characteristic Printing Density are assumed to be log
+ encoded density while files marked as Linear are assumed to be
+ linear. Hint: use ``-define dpx:colorspace=rgb`` in order to avoid
+ the log to linear transformation for DPX files which use Printing
+ Density.
+
+-define dpx:packing-method={packed|a|b|lsbpad|msbpad}
+ DPX samples may be output within 32-bit words. They may be tightly
+ packed end-to-end within the words ("packed"), padded with null
+ bits to the right of the sample ("a" or "lsbpad"), or padded with
+ null bits to the left of the sample ("b" or "msbpad"). This option
+ only has an effect for sample sizes of 10 or 12 bits. If samples
+ are not packed, the DPX standard recommends type A padding. Many
+ DPX readers demand a sample size of 10 bits with type A padding.
+
+-define dpx:pixel-endian={lsb|msb}
+ DPX pixels should use the endian order that the DPX header
+ specifies. Sometimes there is a mis-match and the pixels use a
+ different endian order than the file header specifies. For
+ example, the file header may specify little endian, but the pixels
+ are in big-endian order. To work around that use -define
+ dpx-pixel-endian=msb when reading the file. Likewise, this option
+ may be used to intentionally write the pixels using a different
+ order than the header.
+
+-define dpx:swap-samples={true|false}
+ GraphicsMagick strives to adhere to the DPX standard but certain
+ aspects of the standard can be quite confusing. As a result, some
+ 10-bit DPX files have Red and Blue interchanged, or Cb and Cr
+ interchanged due to an different interpretation of the standard,
+ or getting the wires crossed. The swap-samples option may be
+ supplied when reading or writing in order to read or write using
+ the necessary sample order.
+
+-interlace plane
+ By default, samples are stored contiguously in a single element
+ when possible. Specifying '-interlace plane' causes each sample
+ type (e.g. 'red') to be stored in its own image element. Planar
+ storage is fully supported for grayscale (with alpha) and RGB. For
+ YCbCr, chroma must be 4:2:2 subsampled in order to use planar
+ storage. While planar storage offers a number of benefits, it
+ seems that very few DPX-supporting applications support it.
+
+-sampling-factor 4:2:2
+ Select 4:2:2subsampling when saving an image in YCbCr
+ format. Subsampling is handled via a general-purpose image resize
+ algorithm (lanczos) rather than a dedicated filter so subsampling
+ is slow (but good).
+
+-set reference-white <value>
+ Set the 90% white card level (default 685) for Cineon Log.
+
+-set reference-black <value>
+ Set the 1% black card level (default 95) for Cineon Log.
+
+-set display-gamma <value>
+ Set the display gamma (default 1.7) for Cineon Log.
+
+-set film-gamma <value>
+ Set the film gamma (default 0.6) for Cineon Log.
+
+-set soft-clip-offset <value>
+ Set the soft clip offset (default 0) when converting to *computer* RGB from
+ Cineon Log.
+
+DPX Attributes
+--------------
+
+GraphicsMagick provides almost full access to DPX header
+attributes. DPX header attributes are shown in the output of 'gm
+identify -verbose' and may be set using the -define syntax
+(e.g. '-define dpx:mp.frame.position=2000') on the command line in
+order to add a value, or override an existing value. The attributes in
+the list below may be viewed or updated. The names are similar to the
+attribute descriptions from the DPX standard.
+
+::
+
+ dpx:file.copyright
+ dpx:file.creation.datetime
+ dpx:file.creator
+ dpx:file.encryption.key
+ dpx:file.filename
+ dpx:file.project.name
+ dpx:file.version
+ dpx:image.orientation
+ dpx:mp.count
+ dpx:mp.film.manufacturer.id
+ dpx:mp.film.type
+ dpx:mp.format
+ dpx:mp.frame.id
+ dpx:mp.frame.position
+ dpx:mp.frame.rate
+ dpx:mp.held.count
+ dpx:mp.perfs.offset
+ dpx:mp.prefix
+ dpx:mp.sequence.length
+ dpx:mp.shutter.angle
+ dpx:mp.slate.info
+ dpx:source.aspect.ratio.horizontal
+ dpx:source.aspect.ratio.vertical
+ dpx:source.border.validity.bottom
+ dpx:source.border.validity.left
+ dpx:source.border.validity.right
+ dpx:source.border.validity.top
+ dpx:source.creation.datetime
+ dpx:source.device.name
+ dpx:source.device.serialnumber
+ dpx:source.filename
+ dpx:source.scanned.size.x
+ dpx:source.scanned.size.y
+ dpx:source.x-center
+ dpx:source.x-offset
+ dpx:source.x-original-size
+ dpx:source.y-center
+ dpx:source.y-offset
+ dpx:source.y-original-size
+ dpx:tv.black.gain
+ dpx:tv.black.level
+ dpx:tv.breakpoint
+ dpx:tv.field.number
+ dpx:tv.gama
+ dpx:tv.horizontal.sampling.rate
+ dpx:tv.integration.time
+ dpx:tv.interlace
+ dpx:tv.sync.time
+ dpx:tv.temporal.sampling.rate
+ dpx:tv.time.code
+ dpx:tv.user.bits
+ dpx:tv.video.signal
+ dpx:tv.white.level
+ dpx:user.data.id
+
+Specific header values from a DPX file may be displayed quickly using a command
+similar to::
+
+ gm identify -format '%[DPX:tv.time.code]' foo.dpx
+
+Use
+
+::
+
+ gm identify -format '%[dpx:*]' foo.dpx
+
+to list all DPX header attributes.
+
+-------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/perl.html b/www/perl.html
new file mode 100644
index 0000000..b47cb0d
--- /dev/null
+++ b/www/perl.html
@@ -0,0 +1,2043 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Perl API -- PerlMagick</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-perl-api-perlmagick">
+<h1 class="title">GraphicsMagick Perl API -- PerlMagick</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
+<li><a class="reference internal" href="#installation" id="id2">Installation</a><ul>
+<li><a class="reference internal" href="#unix" id="id3">UNIX</a></li>
+<li><a class="reference internal" href="#windows-xp-windows-8" id="id4">Windows XP - Windows 8</a></li>
+<li><a class="reference internal" href="#running-the-regression-tests" id="id5">Running the Regression Tests</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#overview" id="id6">Overview</a></li>
+<li><a class="reference internal" href="#example-script" id="id7">Example Script</a></li>
+<li><a class="reference internal" href="#read-or-write-an-image" id="id8">Read or Write an Image</a></li>
+<li><a class="reference internal" href="#manipulate-an-image" id="id9">Manipulate an Image</a></li>
+<li><a class="reference internal" href="#set-an-image-attribute" id="id10">Set an Image Attribute</a></li>
+<li><a class="reference internal" href="#get-an-image-attribute" id="id11">Get an Image Attribute</a></li>
+<li><a class="reference internal" href="#create-an-image-montage" id="id12">Create an Image Montage</a></li>
+<li><a class="reference internal" href="#working-with-blobs" id="id13">Working with Blobs</a></li>
+<li><a class="reference internal" href="#miscellaneous-methods" id="id14">Miscellaneous Methods</a></li>
+<li><a class="reference internal" href="#handling-errors" id="id15">Handling Errors</a></li>
+</ul>
+</div>
+<div class="section" id="introduction">
+<h1><a class="toc-backref" href="#id1">Introduction</a></h1>
+<p>PerlMagick is an objected-oriented Perl interface to GraphicsMagick. Use
+the module to read, manipulate, or write an image or image sequence from
+within a Perl script. This makes it very suitable for Web CGI scripts.
+You must have GraphicsMagick 1.0.0 or above and Perl version 5.005_02 or
+greater installed on your system for either of these utilities to work.
+There are a number of useful scripts available to show you the value of
+PerlMagick. The PerlMagick demo directory provides a number of sample
+demos.</p>
+</div>
+<div class="section" id="installation">
+<h1><a class="toc-backref" href="#id2">Installation</a></h1>
+<div class="section" id="unix">
+<h2><a class="toc-backref" href="#id3">UNIX</a></h2>
+<p>PerlMagick is installed by default by installing GraphicsMagick.
+Installing PerlMagick as a subordinate package of GraphicsMagick is the
+best way to avoid problems.</p>
+<p>For Unix, you typically need to be root to install the software. There
+are ways around this. Consult the Perl manual pages for more information.</p>
+</div>
+<div class="section" id="windows-xp-windows-8">
+<h2><a class="toc-backref" href="#id4">Windows XP - Windows 8</a></h2>
+<p>Please note that a nice GUI installer is available for GraphicsMagick.
+PerlMagick is included in this installer. If you are using the installer,
+then there is no need to compile PerlMagick.</p>
+<p>After GraphicsMagick has been compiled from the GraphicsMagick Windows
+source distribution using Microsoft Visual C++, PerlMagick may be
+manually built and installed by opening a CLI window and performing the
+following steps:</p>
+<pre class="literal-block">
+cd PerlMagick
+copy Makefile.nt Makefile.PL
+perl Makefile.PL
+nmake
+nmake install
+</pre>
+<p>See the PerlMagick Windows HowTo page for further installation
+instructions.</p>
+</div>
+<div class="section" id="running-the-regression-tests">
+<h2><a class="toc-backref" href="#id5">Running the Regression Tests</a></h2>
+<p>To verify a correct installation, type:</p>
+<pre class="literal-block">
+make test
+</pre>
+<p>Use nmake test under Windows. There are a few demonstration scripts
+available to exercise many of the functions PerlMagick can perform. Type</p>
+<pre class="literal-block">
+cd demo
+make
+</pre>
+<p>You are now ready to utilize the PerlMagick methods from within your Perl
+scripts.</p>
+</div>
+</div>
+<div class="section" id="overview">
+<h1><a class="toc-backref" href="#id6">Overview</a></h1>
+<p>Any script that wants to use PerlMagick methods must first define the
+methods within its namespace and instantiate an image object. Do this
+with</p>
+<pre class="literal-block">
+use Graphics::Magick;
+$image=Graphics::Magick-&gt;new;
+</pre>
+<p>Note that this differs from the ImageMagick version of PerlMagick which
+uses the namespace Image::Magick. Any PerlMagick code written for the
+ImageMagick version of PerlMagick requires a global substition of
+Image::Magick to Graphics::Magick in order to work with the
+GraphicsMagick version.</p>
+<p>The new() method takes the same parameters as SetAttribute . For example:</p>
+<pre class="literal-block">
+$image=Graphics::Magick-&gt;new(size=&gt;'384x256');
+</pre>
+<p>Next you will want to read an image or image sequence, manipulate it, and
+then display or write it. The input and output methods for PerlMagick are
+defined in Read or Write an Image. See Set an Image Attribute for methods
+that affect the way an image is read or written. Refer to Manipulate an
+Image for a list of methods to transform an image. Get an Image Attribute
+describes how to retrieve an attribute for an image. Refer to Create an
+Image Montage for details about tiling your images as thumbnails on a
+background. Finally, some methods do not neatly fit into any of the
+categories just mentioned. Review Miscellaneous Methods for a list of
+these methods.</p>
+<p>Once you are finished with a PerlMagick object you should consider
+destroying it. Each image in an image sequence is stored in either
+virtual memory or as a file in the system's temporary file directory.
+This can potentially add up to megabytes of memory or disk. Upon
+destroying a PerlMagick object, the memory is returned for use by other
+Perl methods. The recommended way to destroy an object is with undef</p>
+<pre class="literal-block">
+undef $image;
+</pre>
+<p>To delete all the images but retain the Graphics::Magick object use</p>
+<pre class="literal-block">
+&#64;$image = ();
+</pre>
+<p>and finally, to delete a single image from a multi-image sequence, use</p>
+<pre class="literal-block">
+undef $image-&gt;[x];
+</pre>
+<p>The next section illustrates how to use various PerlMagick methods to
+manipulate an image sequence.</p>
+<p>Some of the PerlMagick methods require external programs such as
+Ghostscript. This may require an explicit path in your PATH environment
+variable to work properly. For example,</p>
+<pre class="literal-block">
+$ENV{PATH}='/bin:/usr/bin:/usr/local/bin';
+</pre>
+</div>
+<div class="section" id="example-script">
+<h1><a class="toc-backref" href="#id7">Example Script</a></h1>
+<p>Here is an example script to get you started:</p>
+<pre class="literal-block">
+#!/usr/local/bin/perl
+use Graphics::Magick;
+my($image, $status);
+$image = Graphics::Magick-&gt;new;
+$status = $image-&gt;Read('girl.png', 'logo.png', 'rose.png');
+warn &quot;$status&quot; if &quot;$status&quot;;
+$status = $image-&gt;Crop(geometry=&gt;'100x100+100+100');
+warn &quot;$status&quot; if &quot;$status&quot;;
+$status = $image-&gt;Write('x.gif');
+warn &quot;$status&quot; if &quot;$status&quot;;
+</pre>
+<p>The script reads three images, crops them, and writes a single image as a
+GIF animation sequence. In many cases you may want to access individual
+images of a sequence. The next example illustrates how this is done:</p>
+<pre class="literal-block">
+#!/usr/local/bin/perl
+use Graphics::Magick;
+my($image, $p, $q);
+$image = new Graphics::Magick;
+$image-&gt;Read('x1.png');
+$image-&gt;Read('j*.jpg');
+$image-&gt;Read('k.miff[1, 5, 3]');
+$image-&gt;Contrast();
+for ($x = 0; $image-&gt;[x]; $x++)
+{
+ $image-&gt;[x]-&gt;Frame('100x200') if $image-&gt;[x]-&gt;Get('magick') eq 'GIF';
+ undef $image-&gt;[x] if $image-&gt;[x]-&gt;Get('columns') &lt; 100;
+}
+$p = $image-&gt;[1];
+$p-&gt;Draw(stroke=&gt;'red', primitive=&gt;'rectangle', points=&gt;'20,20 100,100');
+$q = $p-&gt;Montage();
+undef $image;
+$q-&gt;Write('x.miff');
+</pre>
+<p>Suppose you want to start out with a 100 by 100 pixel white canvas with a
+red pixel in the center. Try</p>
+<pre class="literal-block">
+$image = Graphics::Magick-&gt;new;
+$image-&gt;Set(size=&gt;'100x100');
+$image-&gt;ReadImage('xc:white');
+$image-&gt;Set('pixel[49,49]'=&gt;'red');
+</pre>
+<p>Or suppose you want to convert your color image to grayscale:</p>
+<pre class="literal-block">
+$image-&gt;Quantize(colorspace=&gt;'gray');
+</pre>
+<p>Here we annotate an image with a Taipai TrueType font:</p>
+<pre class="literal-block">
+$text = 'Works like magick!';
+$image-&gt;Annotate(font=&gt;'kai.ttf', pointsize=&gt;40, fill=&gt;'green', text=&gt;$text);
+</pre>
+<p>Other clever things you can do with a PerlMagick objects include</p>
+<pre class="literal-block">
+$i = $#$p&quot;+1&quot;; # return the number of images associated with object p
+push(&#64;$q, &#64;$p); # push the images from object p onto object q
+&#64;$p = (); # delete the images but not the object p
+$p-&gt;Convolve([1, 2, 1, 2, 4, 2, 1, 2, 1]); # 3x3 Gaussian kernel
+</pre>
+</div>
+<div class="section" id="read-or-write-an-image">
+<h1><a class="toc-backref" href="#id8">Read or Write an Image</a></h1>
+<p>Use the methods listed below to either read, write, or display an image
+or image sequence.</p>
+<table border="1" class="docutils">
+<caption>Read or Write Methods</caption>
+<colgroup>
+<col width="10%" />
+<col width="19%" />
+<col width="27%" />
+<col width="44%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Method</td>
+<td>Parameters</td>
+<td>Return Value</td>
+<td>Description</td>
+</tr>
+<tr><td>Read</td>
+<td>one or more
+filenames</td>
+<td>the number of
+images read</td>
+<td>read an image or image sequence</td>
+</tr>
+<tr><td>Write</td>
+<td>filename</td>
+<td>the number of
+images written</td>
+<td>write an image or image
+sequence</td>
+</tr>
+<tr><td>Display</td>
+<td>server name</td>
+<td>the number of
+images displayed</td>
+<td>display the image or image
+sequence to an X server</td>
+</tr>
+<tr><td>Animate</td>
+<td>server name</td>
+<td>the number of
+images animated</td>
+<td>animate image sequence to an X
+server</td>
+</tr>
+</tbody>
+</table>
+<p>For convenience, methods Write(), Display(), and Animate() can take any
+parameter that SetAttribute knows about. For example,</p>
+<pre class="literal-block">
+$image-&gt;Write(filename=&gt;'image.png', compression=&gt;'None');
+</pre>
+<p>Use - as the filename to method Read() to read from standard in or to
+method Write() to write to standard out:</p>
+<pre class="literal-block">
+binmode STDOUT;
+$image-&gt;Write('png:-');
+</pre>
+<dl class="docutils">
+<dt>To read an image from a disk file, use::</dt>
+<dd>$image = Graphics::Magick-&gt;new;
+$filename = 'test.gif';
+$status = $image-&gt;Read ($filename);</dd>
+</dl>
+<p>and to write the image back to the disk file, use:</p>
+<pre class="literal-block">
+$status = $image-&gt;Write($filename);
+</pre>
+<p>To read an image in the GIF format from a PERL filehandle, use:</p>
+<pre class="literal-block">
+$image = Graphics::Magick-&gt;new;
+open(IMAGE, 'image.gif');
+$status = $image-&gt;Read(file=&gt;\*IMAGE);
+close(IMAGE);
+</pre>
+<p>To write an image in the PNG format to a PERL filehandle, use:</p>
+<pre class="literal-block">
+$filename = &quot;image.png&quot;;
+open(IMAGE, &quot;&gt;$filename&quot;);
+$status = $image-&gt;Write(file=&gt;\*IMAGE, filename=&gt;$filename);
+close(IMAGE);
+</pre>
+<p>If %0Nd appears in the filename, it is interpreted as a printf format
+specification and the specification is replaced with the specified
+decimal encoding of the scene number. For example,</p>
+<pre class="literal-block">
+image%03d.miff
+</pre>
+<p>converts files image000.miff, image001.miff, etc.</p>
+<p>You can optionally add Image to any method name. For example, ReadImage()
+is an alias for method Read().</p>
+</div>
+<div class="section" id="manipulate-an-image">
+<h1><a class="toc-backref" href="#id9">Manipulate an Image</a></h1>
+<p>Once you create an image with, for example, method ReadImage() you may want
+to operate on it. Below is a list of all the image manipulations methods
+available to you with PerlMagick. There are examples of select PerlMagick
+methods. Here is an example call to an image manipulation method:</p>
+<pre class="literal-block">
+$image-&gt;Crop(geometry=&gt;'100x100&quot;+1&quot;0+20');
+$image-&gt;[x]-&gt;Frame(&quot;100x200&quot;);
+</pre>
+<p>Image method parameters are often redundant. For example, a 'geometry'
+string parameter (e.g. 800x600+10+20) is equivalent to the explicit use of
+width, height, x, and y, parameters.</p>
+<p>The following image manipulation methods are available:</p>
+<table border="1" class="docutils">
+<caption>Image Manipulation Methods</caption>
+<colgroup>
+<col width="24%" />
+<col width="46%" />
+<col width="30%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Method</td>
+<td>Parameters</td>
+<td>Description</td>
+</tr>
+<tr><td>AdaptiveThreshold</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer, offset
+=&gt;integer</td>
+<td>Local adaptive
+thresholding. Width
+and height specify
+the size of the local
+region while offset
+specifies the amount
+to subtract from the
+average of the
+region.</td>
+</tr>
+<tr><td>AddNoise</td>
+<td>noise=&gt;{Uniform, Gaussian,
+Multiplicative, Impulse,
+Laplacian, Poisson, Random}</td>
+<td>Add noise to an image
+across the red,
+green, and blue,
+channels. Set the
+image colorspace to
+GRAY to obtain
+intensity noise.</td>
+</tr>
+<tr><td>AffineTransform</td>
+<td>affine=&gt;array of float values,
+translate=&gt;float, float, scale=&gt;
+float, float, rotate=&gt;float,
+skewX=&gt;float, skewY=&gt;float</td>
+<td>Affine transform
+image</td>
+</tr>
+<tr><td>Annotate</td>
+<td>text=&gt;string, font=&gt;string,
+family=&gt;string, style=&gt;{Normal,
+Italic, Oblique, Any}, stretch=&gt;
+{Normal, UltraCondensed,
+ExtraCondensed, Condensed,
+SemiCondensed, SemiExpanded,
+Expanded, ExtraExpanded,
+UltraExpanded}, weight=&gt;integer,
+pointsize=&gt;integer, density=&gt;
+geometry, stroke=&gt; color name,
+strokewidth=&gt;integer, fill=&gt;color
+name, undercolor=&gt;color name,
+geometry=&gt;geometry, gravity=&gt;
+{NorthWest, North, NorthEast,
+West, Center, East, SouthWest,
+South, SouthEast}, antialias=&gt;
+{true, false}, x=&gt;integer, y=&gt;
+integer, affine=&gt;array of float
+values, translate=&gt;float, float,
+scale=&gt;float, float, rotate=&gt;
+float. skewX=&gt;float, skewY=&gt;
+float, align=&gt;{Left, Center,
+Right}, encoding=&gt;{UTF-8}</td>
+<td>annotate an image
+with text. See
+QueryFontMetrics to
+get font metrics
+without rendering any
+text.</td>
+</tr>
+<tr><td>Blur</td>
+<td>geometry=&gt;geometry, radius=&gt;
+double, sigma=&gt; double</td>
+<td>blur the image with a
+Gaussian operator of
+the given radius and
+standard deviation
+(sigma).</td>
+</tr>
+<tr><td>Border</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer, fill=&gt;
+color name</td>
+<td>surround the image
+with a border of
+color</td>
+</tr>
+<tr><td>Channel</td>
+<td>channel=&gt;{Red, Cyan, Green,
+Magenta, Blue, Yellow, Opacity,
+Black, Matte, All, Gray}</td>
+<td>extract a channel
+from the image</td>
+</tr>
+<tr><td>Charcoal</td>
+<td>order=&gt;integer</td>
+<td>simulate a charcoal
+drawing</td>
+</tr>
+<tr><td>Chop</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer, x=&gt;
+integer, y=&gt;integer</td>
+<td>chop an image</td>
+</tr>
+<tr><td>Coalesce</td>
+<td>&nbsp;</td>
+<td>merge a sequence of
+images</td>
+</tr>
+<tr><td>Clip</td>
+<td>&nbsp;</td>
+<td>apply any clipping
+path information as
+an image clip mask.</td>
+</tr>
+<tr><td>ColorFloodfill</td>
+<td>geometry=&gt;geometry, x=&gt;integer, y
+=&gt;integer , fill=&gt;color name,
+bordercolor=&gt; color name</td>
+<td>changes the color
+value of any pixel
+that matches the
+color of the target
+pixel and is a
+neighbor. If you
+specify a border
+color, the color
+value is changed for
+any neighbor pixel
+that is not that
+color.</td>
+</tr>
+<tr><td>Colorize</td>
+<td>fill=&gt;color name, opacity=&gt;string</td>
+<td>colorize the image
+with the fill color</td>
+</tr>
+<tr><td>Comment</td>
+<td>string</td>
+<td>add a comment to your
+image</td>
+</tr>
+<tr><td>Compare</td>
+<td>image=&gt;image-handle</td>
+<td>compare image to a
+reference image</td>
+</tr>
+<tr><td>Composite</td>
+<td>image=&gt;image-handle, compose=&gt;{
+Over, In, Out, Atop, Xor, Plus,
+Minus, Add, Subtract,
+Difference, Multiply, Bumpmap,
+Copy, CopyRed, CopyGreen,
+CopyBlue, CopyOpacity,
+Clear, Dissolve, Displace,
+Modulate, Threshold, No, Darken,
+Lighten, Hue, Saturate,
+Colorize, Luminize, Screen,
+Overlay, CopyCyan, CopyMagenta,
+CopyYellow, CopyBlack, Divide,
+HardLight},
+mask=&gt;
+image-handle, geometry=&gt;geometry,
+x=&gt;integer, y=&gt;integer, gravity=&gt;
+{NorthWest, North, NorthEast,
+West, Center, East, SouthWest,
+South, SouthEast}, opacity=&gt;
+integer, tile=&gt;{True, False},
+rotate=&gt;double, color=&gt;color name</td>
+<td>composite one image
+onto another</td>
+</tr>
+<tr><td>Contrast</td>
+<td>sharpen=&gt;{True, False}</td>
+<td>enhance or reduce the
+image contrast</td>
+</tr>
+<tr><td>Convolve</td>
+<td>coefficients=&gt;array of float
+values</td>
+<td>apply a convolution
+kernel to the image.
+Given a kernel order
+, you would supply
+order*order float
+values (e.g. 3x3
+implies 9 values).</td>
+</tr>
+<tr><td>Crop</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer, x=&gt;
+integer, y=&gt;integer</td>
+<td>crop an image</td>
+</tr>
+<tr><td>CycleColormap</td>
+<td>amount=&gt;integer</td>
+<td>displace image
+colormap by amount</td>
+</tr>
+<tr><td>Deconstruct</td>
+<td>&nbsp;</td>
+<td>break down an image
+sequence into
+constituent parts</td>
+</tr>
+<tr><td>Despeckle</td>
+<td>&nbsp;</td>
+<td>reduce the speckles
+within an image</td>
+</tr>
+<tr><td>Draw</td>
+<td>primitive=&gt;{point, line,
+rectangle, roundRectangle, arc,
+ellipse, circle, polyline,
+polygon, ,bezier, path, color,
+matte, text, image, &#64;filename},
+points=&gt;string , method=&gt;{Point,
+Replace, Floodfill, FillToBorder,
+Reset}, stroke=&gt; color name, fill
+=&gt;color name, tile=&gt;image-handle,
+strokewidth=&gt;float, antialias=&gt;
+{true, false}, bordercolor=&gt;color
+name, x=&gt; float, y=&gt;float, affine
+=&gt;array of float values,
+translate=&gt;float, float, scale=&gt;
+float, float, rotate=&gt;float.
+skewX=&gt;float, skewY=&gt; float</td>
+<td>annotate an image
+with one or more
+graphic primitives</td>
+</tr>
+<tr><td>Edge</td>
+<td>radius=&gt;double</td>
+<td>enhance edges within
+the image with a
+convolution filter of
+the given radius.</td>
+</tr>
+<tr><td>Emboss</td>
+<td>geometry=&gt;geometry, radius=&gt;
+double, sigma=&gt; double</td>
+<td>emboss the image with
+a convolution filter
+of the given radius
+and standard
+deviation (sigma).</td>
+</tr>
+<tr><td>Enhance</td>
+<td>&nbsp;</td>
+<td>apply a digital
+filter to enhance a
+noisy image</td>
+</tr>
+<tr><td>Equalize</td>
+<td>&nbsp;</td>
+<td>perform histogram
+equalization to the
+image</td>
+</tr>
+<tr><td>Flatten</td>
+<td>&nbsp;</td>
+<td>flatten a sequence of
+images</td>
+</tr>
+<tr><td>Flip</td>
+<td>&nbsp;</td>
+<td>create a mirror image
+by reflecting the
+image scanlines in
+the vertical
+direction</td>
+</tr>
+<tr><td>Flop</td>
+<td>&nbsp;</td>
+<td>create a mirror image
+by reflecting the
+image scanlines in
+the horizontal
+direction</td>
+</tr>
+<tr><td>Frame</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer, inner
+=&gt;integer, outer=&gt;integer, fill=&gt;
+color name</td>
+<td>surround the image
+with an ornamental
+border</td>
+</tr>
+<tr><td>Gamma</td>
+<td>gamma=&gt;string, red=&gt;double, green
+=&gt;double , blue=&gt;double</td>
+<td>gamma correct the
+image</td>
+</tr>
+<tr><td>Implode</td>
+<td>amount=&gt;double</td>
+<td>implode image pixels
+about the center</td>
+</tr>
+<tr><td>Label</td>
+<td>string</td>
+<td>assign a label to an
+image</td>
+</tr>
+<tr><td>Level</td>
+<td>level=&gt;string, 'black-point'=&gt;
+double, 'mid-point'=&gt;double,
+'white-point'=&gt;double</td>
+<td>adjust the level of
+image contrast</td>
+</tr>
+<tr><td>Magnify</td>
+<td>&nbsp;</td>
+<td>double the size of an
+image</td>
+</tr>
+<tr><td>Map</td>
+<td>image=&gt;image-handle, dither=&gt;
+{True, False}</td>
+<td>choose a particular
+set of colors from
+this image</td>
+</tr>
+<tr><td>MatteFloodfill</td>
+<td>geometry=&gt;geometry, x=&gt;integer, y
+=&gt;integer , matte=&gt;integer,
+bordercolor=&gt;color name</td>
+<td>changes the matte
+value of any pixel
+that matches the
+color of the target
+pixel and is a
+neighbor. If you
+specify a border
+color, the matte
+value is changed for
+any neighbor pixel
+that is not that
+color.</td>
+</tr>
+<tr><td>MedianFilter</td>
+<td>radius=&gt;double</td>
+<td>replace each pixel
+with the median
+intensity pixel of a
+neighborhood.</td>
+</tr>
+<tr><td>Minify</td>
+<td>&nbsp;</td>
+<td>half the size of an
+image</td>
+</tr>
+<tr><td>Modulate</td>
+<td>brightness=&gt;double, saturation=&gt;
+double, hue=&gt; double</td>
+<td>vary the brightness,
+saturation, and hue
+of an image by the
+specified percentage</td>
+</tr>
+<tr><td>MotionBlur</td>
+<td>geometry=&gt;geometry, radius=&gt;
+double, sigma=&gt; double, angle=&gt;
+double</td>
+<td>blur the image with a
+Gaussian operator of
+the given radius and
+standard deviation
+(sigma) at the given
+angle to simulate the
+effect of motion</td>
+</tr>
+<tr><td>Negate</td>
+<td>gray=&gt;{True, False}</td>
+<td>replace every pixel
+with its
+complementary color
+(white becomes black,
+yellow becomes blue,
+etc.)</td>
+</tr>
+<tr><td>Normalize</td>
+<td>&nbsp;</td>
+<td>transform image to
+span the full range
+of color values</td>
+</tr>
+<tr><td>OilPaint</td>
+<td>radius=&gt;integer</td>
+<td>simulate an oil
+painting</td>
+</tr>
+<tr><td>Opaque</td>
+<td>color=&gt;color name, fill=&gt; color
+name</td>
+<td>change this color to
+the fill color within
+the image</td>
+</tr>
+<tr><td>Quantize</td>
+<td>colors=&gt;integer, colorspace=&gt;
+{RGB, Gray, Transparent, OHTA,
+XYZ, YCbCr, YIQ, YPbPr, YUV,
+CMYK}, treedepth=&gt; integer,
+dither=&gt;{True, False},
+measure_error=&gt;{True, False},
+global_colormap=&gt;{True, False}</td>
+<td>preferred number of
+colors in the image</td>
+</tr>
+<tr><td>Profile</td>
+<td>name=&gt;{ICM, IPTC}, profile=&gt;blob</td>
+<td>add or remove ICC or
+IPTC image profile</td>
+</tr>
+<tr><td>Raise</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer, x=&gt;
+integer, y=&gt;integer, raise=&gt;
+{True, False}</td>
+<td>lighten or darken
+image edges to create
+a 3-D effect</td>
+</tr>
+<tr><td>ReduceNoise</td>
+<td>radius=&gt;double</td>
+<td>reduce noise in the
+image with a noise
+peak elimination
+filter</td>
+</tr>
+<tr><td>Resize</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer, filter
+=&gt;{Point, Box, Triangle, Hermite,
+Hanning, Hamming, Blackman,
+Gaussian, Quadratic, Cubic,
+Catrom, Mitchell, Lanczos,
+Bessel, Sinc}, blur=&gt;double</td>
+<td>scale image to
+desired size. Specify
+blur &gt; 1 for blurry
+or &lt; 1 for sharp</td>
+</tr>
+<tr><td>Roll</td>
+<td>geometry=&gt;geometry, x=&gt;integer, y
+=&gt;integer</td>
+<td>roll an image
+vertically or
+horizontally</td>
+</tr>
+<tr><td>Rotate</td>
+<td>degrees=&gt;double, color=&gt;color
+name</td>
+<td>rotate an image</td>
+</tr>
+<tr><td>Sample</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer</td>
+<td>scale image with
+pixel sampling</td>
+</tr>
+<tr><td>Scale</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer</td>
+<td>scale image to
+desired size</td>
+</tr>
+<tr><td>Segment</td>
+<td>colorspace=&gt;{RGB, Gray,
+Transparent, OHTA, XYZ, YCbCr,
+YCC, YIQ, YPbPr, YUV, CMYK},
+verbose={True, False}, cluster=&gt;
+double, smooth= double</td>
+<td>segment an image by
+analyzing the
+histograms of the
+color components and
+identifying units
+that are homogeneous</td>
+</tr>
+<tr><td>Shade</td>
+<td>geometry=&gt;geometry, azimuth=&gt;
+double, elevation=&gt; double, gray
+=&gt;{true, false}</td>
+<td>shade the image using
+a distant light
+source</td>
+</tr>
+<tr><td>Sharpen</td>
+<td>geometry=&gt;geometry, radius=&gt;
+double, sigma=&gt; double</td>
+<td>sharpen the image
+with a Gaussian
+operator of the given
+radius and standard
+deviation (sigma).</td>
+</tr>
+<tr><td>Shave</td>
+<td>geometry=&gt;geometry, width=&gt;
+integer, height=&gt; integer</td>
+<td>shave pixels from the
+image edges</td>
+</tr>
+<tr><td>Shear</td>
+<td>geometry=&gt;geometry, x=&gt;double, y
+=&gt;double color=&gt;color name</td>
+<td>shear the image along
+the X or Y axis by a
+positive or negative
+shear angle</td>
+</tr>
+<tr><td>Signature</td>
+<td>&nbsp;</td>
+<td>generate an SHA-256
+message digest for
+the image pixel
+stream</td>
+</tr>
+<tr><td>Solarize</td>
+<td>threshold=&gt;integer</td>
+<td>negate all pixels
+above the threshold
+level</td>
+</tr>
+<tr><td>Spread</td>
+<td>amount=&gt;integer</td>
+<td>displace image pixels
+by a random amount</td>
+</tr>
+<tr><td>Stereo</td>
+<td>image=&gt;image-handle</td>
+<td>composites two images
+and produces a single
+image that is the
+composite of a left
+and right image of a
+stereo pair</td>
+</tr>
+<tr><td>Stegano</td>
+<td>image=&gt;image-handle, offset=&gt;
+integer</td>
+<td>hide a digital
+watermark within the
+image</td>
+</tr>
+<tr><td>Swirl</td>
+<td>degrees=&gt;double</td>
+<td>swirl image pixels
+about the center</td>
+</tr>
+<tr><td>Texture</td>
+<td>texture=&gt;image-handle</td>
+<td>name of texture to
+tile onto the image
+background</td>
+</tr>
+<tr><td>Threshold</td>
+<td>threshold=&gt;string</td>
+<td>threshold the image</td>
+</tr>
+<tr><td>Transparent</td>
+<td>color=&gt;color name</td>
+<td>make this color
+transparent within
+the image</td>
+</tr>
+<tr><td>Trim</td>
+<td>&nbsp;</td>
+<td>remove edges that are
+the background color
+from the image</td>
+</tr>
+<tr><td>UnsharpMask</td>
+<td>geometry=&gt;geometry, radius=&gt;
+double, sigma=&gt; double, amount=&gt;
+double, threshold=&gt;double</td>
+<td>sharpen the image
+with the unsharp mask
+algorithm.</td>
+</tr>
+<tr><td>Wave</td>
+<td>geometry=&gt;geometry, amplitude=&gt;
+double, wavelength=&gt; double</td>
+<td>alter an image along
+a sine wave</td>
+</tr>
+</tbody>
+</table>
+<p>Note, that the geometry parameter is a short cut for the width and height
+parameters (e.g. geometry=&gt;'106x80' is equivalent to width=&gt;106,
+height=&gt;80).</p>
+<p>You can specify &#64;filename in both Annotate() and Draw(). This reads the
+text or graphic primitive instructions from a file on disk. For example,</p>
+<pre class="literal-block">
+$image-&gt;Draw(fill=&gt;'red', primitive=&gt;'rectangle',
+points=&gt;'20,20 100,100 40,40 200,200 60,60 300,300');
+</pre>
+<p>Is equivalent to</p>
+<pre class="literal-block">
+$image-&gt;Draw(fill=&gt;'red', primitive=&gt;'&#64;draw.txt');
+</pre>
+<p>Where draw.txt is a file on disk that contains this:</p>
+<pre class="literal-block">
+rectangle 20, 20 100, 100
+rectangle 40, 40 200, 200
+rectangle 60, 60 300, 300
+</pre>
+<p>The text parameter for methods, Annotate(), Comment(), Draw(), and
+Label() can include the image filename, type, width, height, or other
+image attribute by embedding these special format characters:</p>
+<pre class="literal-block">
+%b file size
+%d comment
+%d directory
+%e filename extension
+%f filename
+%h height
+%m magick
+%p page number
+%s scene number
+%t top of filename
+%w width
+%x x resolution
+%y y resolution
+\n newline
+\r carriage return
+</pre>
+<p>For example,</p>
+<pre class="literal-block">
+text=&gt;&quot;%m:%f %wx%h&quot;
+</pre>
+<p>produces an annotation of MIFF:bird.miff 512x480 for an image titled
+bird.miff and whose width is 512 and height is 480.</p>
+<p>You can optionally add Image to any method name. For example, TrimImage()
+is an alias for method Trim().</p>
+<p>Most of the attributes listed above have an analog in convert. See the
+documentation for a more detailed description of these attributes.</p>
+</div>
+<div class="section" id="set-an-image-attribute">
+<h1><a class="toc-backref" href="#id10">Set an Image Attribute</a></h1>
+<p>Use method Set() to set an image attribute. For example,</p>
+<pre class="literal-block">
+$image-&gt;Set(dither=&gt;'True');
+$image-&gt;[$x]-&gt;Set(delay=&gt;3);
+</pre>
+<p>And here is a list of all the image attributes you can set:</p>
+<table border="1" class="docutils">
+<caption>Image Attributes</caption>
+<colgroup>
+<col width="23%" />
+<col width="51%" />
+<col width="27%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Attribute</td>
+<td>Values</td>
+<td>Description</td>
+</tr>
+<tr><td>adjoin</td>
+<td>{True, False}</td>
+<td>join images into a
+single multi-image
+file</td>
+</tr>
+<tr><td>antialias</td>
+<td>{True, False}</td>
+<td>remove pixel
+aliasing</td>
+</tr>
+<tr><td>authenticate</td>
+<td>string</td>
+<td>decrypt image with
+this password.</td>
+</tr>
+<tr><td>background</td>
+<td>color name</td>
+<td>image background
+color</td>
+</tr>
+<tr><td>blue-primary</td>
+<td>x-value, y-value</td>
+<td>chromaticity blue
+primary point (e.g.
+0.15, 0.06)</td>
+</tr>
+<tr><td>bordercolor</td>
+<td>color name</td>
+<td>set the image
+border color</td>
+</tr>
+<tr><td>clip-mask</td>
+<td>image</td>
+<td>Associate a clip
+mask with the
+image.</td>
+</tr>
+<tr><td>colormap[i]</td>
+<td>color name</td>
+<td>color name (e.g.
+red) or hex value
+(e.g. #ccc) at
+position i</td>
+</tr>
+<tr><td>colorspace</td>
+<td>{RGB, CMYK}</td>
+<td>type of colorspace</td>
+</tr>
+<tr><td>comment</td>
+<td>string</td>
+<td>Append to the image
+comment.</td>
+</tr>
+<tr><td>compression</td>
+<td>{None, BZip, Fax, Group4, JPEG,
+LosslessJPEG, LZW, RLE, Zip, LZMA
+JPEG2000, JBIG1, JBIG2}</td>
+<td>type of image
+compression</td>
+</tr>
+<tr><td>debug</td>
+<td>{No, Configure, Annotate, Render,
+Transform, Locale, Coder, X11,
+Cache, Blob, Deprecate, User,
+Resource, TemporaryFile,
+Exception,All}</td>
+<td>log copious
+debugging
+information for
+one or more event
+types</td>
+</tr>
+<tr><td>delay</td>
+<td>integer</td>
+<td>this many 1/100ths
+of a second must
+expire before
+displaying the next
+image in a sequence</td>
+</tr>
+<tr><td>density</td>
+<td>geometry</td>
+<td>vertical and
+horizontal
+resolution in
+pixels of the image</td>
+</tr>
+<tr><td>disk-limit</td>
+<td>integer</td>
+<td>set disk resource
+limit in megabytes</td>
+</tr>
+<tr><td>dispose</td>
+<td>{Undefined, None, Background,
+Previous}</td>
+<td>GIF disposal method</td>
+</tr>
+<tr><td>dither</td>
+<td>{True, False}</td>
+<td>apply error
+diffusion to the
+image</td>
+</tr>
+<tr><td>display</td>
+<td>string</td>
+<td>specifies the X
+server to contact</td>
+</tr>
+<tr><td>endian</td>
+<td>{Undefined, LSB, MSB, Native}</td>
+<td>specifies the
+ordering of bytes
+in a multi-byte
+word. MSB is
+big-endian, LSB is
+little-endian, and
+Native is whatever
+the current host
+uses by default.</td>
+</tr>
+<tr><td>file</td>
+<td>filehandle</td>
+<td>set the image
+filehandle</td>
+</tr>
+<tr><td>filename</td>
+<td>string</td>
+<td>set the image
+filename</td>
+</tr>
+<tr><td>fill</td>
+<td>color</td>
+<td>The fill color
+paints any areas
+inside the outline
+of drawn shape.</td>
+</tr>
+<tr><td>font</td>
+<td>string</td>
+<td>use this font when
+annotating the
+image with text</td>
+</tr>
+<tr><td>fuzz</td>
+<td>integer</td>
+<td>colors within this
+distance are
+considered equal</td>
+</tr>
+<tr><td>gamma</td>
+<td>double</td>
+<td>gamma level of the
+image</td>
+</tr>
+<tr><td>Gravity</td>
+<td>{Forget, NorthWest, North,
+NorthEast, West, Center, East,
+SouthWest, South, SouthEast}</td>
+<td>type of image
+gravity</td>
+</tr>
+<tr><td>green-primary</td>
+<td>x-value, y-value</td>
+<td>chromaticity green
+primary point (e.g.
+0.3, 0.6)</td>
+</tr>
+<tr><td>index[x, y]</td>
+<td>string</td>
+<td>colormap index at
+position (x, y)</td>
+</tr>
+<tr><td>interlace</td>
+<td>{None, Line, Plane, Partition}</td>
+<td>the type of
+interlacing scheme</td>
+</tr>
+<tr><td>iterations</td>
+<td>integer</td>
+<td>add Netscape loop
+extension to your
+GIF animation</td>
+</tr>
+<tr><td>label</td>
+<td>string</td>
+<td>Append to the image
+label.</td>
+</tr>
+<tr><td>loop</td>
+<td>integer</td>
+<td>add Netscape loop
+extension to your
+GIF animation</td>
+</tr>
+<tr><td>magick</td>
+<td>string</td>
+<td>set the image
+format</td>
+</tr>
+<tr><td>matte</td>
+<td>{True, False}</td>
+<td>True if the image
+has transparency</td>
+</tr>
+<tr><td>mattecolor</td>
+<td>color name</td>
+<td>set the image matte
+color</td>
+</tr>
+<tr><td>map-limit</td>
+<td>integer</td>
+<td>set map resource
+limit in megabytes</td>
+</tr>
+<tr><td>memory-limit</td>
+<td>integer</td>
+<td>set memory resource
+limit in megabytes</td>
+</tr>
+<tr><td>monochrome</td>
+<td>{True, False}</td>
+<td>transform the image
+to black and white</td>
+</tr>
+<tr><td>page</td>
+<td>{ Letter, Tabloid, Ledger, Legal,
+Statement, Executive, A3, A4, A5,
+B4, B5, Folio, Quarto, 10x14} or
+geometry</td>
+<td>preferred size and
+location of an
+image canvas</td>
+</tr>
+<tr><td>pixel[x, y]</td>
+<td>string</td>
+<td>hex value (e.g. #
+ccc) at position (x
+, y)</td>
+</tr>
+<tr><td>pointsize</td>
+<td>integer</td>
+<td>pointsize of the
+Postscript or
+TrueType font</td>
+</tr>
+<tr><td>preview</td>
+<td>{ Rotate, Shear, Roll, Hue,
+Saturation, Brightness, Gamma,
+Spiff, Dull, Grayscale, Quantize,
+Despeckle, ReduceNoise, AddNoise,
+Sharpen, Blur, Threshold,
+EdgeDetect, Spread, Solarize, Shade,
+Raise, Segment, Swirl, Implode,
+Wave, OilPaint, Charcoal,
+JPEG}</td>
+<td>type of preview for
+the Preview image
+format</td>
+</tr>
+<tr><td>quality</td>
+<td>integer</td>
+<td>JPEG/MIFF/PNG
+compression level</td>
+</tr>
+<tr><td>red-primary</td>
+<td>x-value, y-value</td>
+<td>chromaticity red
+primary point (e.g.
+0.64, 0.33)</td>
+</tr>
+<tr><td>rendering-intent</td>
+<td>{Undefined, Saturation, Perceptual,
+Absolute, Relative}</td>
+<td>the type of
+rendering intent</td>
+</tr>
+<tr><td>sampling-factor</td>
+<td>geometry</td>
+<td>horizontal and
+vertical sampling
+factor</td>
+</tr>
+<tr><td>scene</td>
+<td>integer</td>
+<td>image scene number</td>
+</tr>
+<tr><td>subimage</td>
+<td>integer</td>
+<td>subimage of an
+image sequence</td>
+</tr>
+<tr><td>subrange</td>
+<td>integer</td>
+<td>number of images
+relative to the
+base image</td>
+</tr>
+<tr><td>server</td>
+<td>string</td>
+<td>specifies the X
+server to contact</td>
+</tr>
+<tr><td>size</td>
+<td>string</td>
+<td>width and height of
+a raw image</td>
+</tr>
+<tr><td>stroke</td>
+<td>color</td>
+<td>The stroke color
+paints along the
+outline of a shape.</td>
+</tr>
+<tr><td>tile</td>
+<td>string</td>
+<td>tile name</td>
+</tr>
+<tr><td>texture</td>
+<td>string</td>
+<td>name of texture to
+tile onto the image
+background</td>
+</tr>
+<tr><td>type</td>
+<td>{Bilevel, Grayscale, GrayscaleMatte,
+Palette, PaletteMatte, TrueColor,
+TrueColorMatte, ColorSeparation,
+ColorSeparationMatte, Optimize }</td>
+<td>image type</td>
+</tr>
+<tr><td>units</td>
+<td>{ Undefined, PixelsPerInch,
+PixelsPerCentimeters}</td>
+<td>units of image
+resolution</td>
+</tr>
+<tr><td>verbose</td>
+<td>{True, False}</td>
+<td>print detailed
+information about
+the image</td>
+</tr>
+<tr><td>virtual-pixel</td>
+<td>{Constant, Edge, Mirror, Tile}</td>
+<td>the virtual pixel
+method</td>
+</tr>
+<tr><td>white-point</td>
+<td>x-value, y-value</td>
+<td>chromaticity white
+point (e.g. 0.3127,
+0.329)</td>
+</tr>
+</tbody>
+</table>
+<p>Note, that the geometry parameter is a short cut for the width and height
+parameters (e.g. geometry=&gt;'106x80' is equivalent to width=&gt;106, height=&gt;
+80).</p>
+<p>SetAttribute() is an alias for method Set().</p>
+<p>Most of the attributes listed above have an analog in gm convert. See the
+gm documentation for a more detailed description of these attributes.</p>
+</div>
+<div class="section" id="get-an-image-attribute">
+<h1><a class="toc-backref" href="#id11">Get an Image Attribute</a></h1>
+<p>Use method Get() to get an image attribute. For example,</p>
+<pre class="literal-block">
+($a, $b, $c) = $image-&gt;Get('colorspace', 'magick', 'adjoin');
+$width = $image-&gt;[3]-&gt;Get('columns');
+</pre>
+<p>In addition to all the attributes listed in Set an Image Attribute , you
+can get these additional attributes:</p>
+<table border="1" class="docutils">
+<caption>Image Attributes</caption>
+<colgroup>
+<col width="18%" />
+<col width="14%" />
+<col width="68%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Attribute</td>
+<td>Values</td>
+<td>Description</td>
+</tr>
+<tr><td>base-columns</td>
+<td>integer</td>
+<td>base image width (before transformations)</td>
+</tr>
+<tr><td>base-filename</td>
+<td>string</td>
+<td>base image filename (before transformations)</td>
+</tr>
+<tr><td>base-rows</td>
+<td>integer</td>
+<td>base image height (before transformations)</td>
+</tr>
+<tr><td>class</td>
+<td>{Direct,
+Pseudo}</td>
+<td>image class</td>
+</tr>
+<tr><td>colors</td>
+<td>integer</td>
+<td>number of unique colors in the image</td>
+</tr>
+<tr><td>comment</td>
+<td>string</td>
+<td>image comment</td>
+</tr>
+<tr><td>columns</td>
+<td>integer</td>
+<td>image width</td>
+</tr>
+<tr><td>depth</td>
+<td>integer</td>
+<td>image depth</td>
+</tr>
+<tr><td>directory</td>
+<td>string</td>
+<td>tile names from within an image montage</td>
+</tr>
+<tr><td>error</td>
+<td>double</td>
+<td>the mean error per pixel computed with methods
+Compare() or Quantize()</td>
+</tr>
+<tr><td>filesize</td>
+<td>integer</td>
+<td>number of bytes of the image on disk</td>
+</tr>
+<tr><td>format</td>
+<td>string</td>
+<td>get the descriptive image format</td>
+</tr>
+<tr><td>geometry</td>
+<td>string</td>
+<td>image geometry</td>
+</tr>
+<tr><td>height</td>
+<td>integer</td>
+<td>the number of rows or height of an image</td>
+</tr>
+<tr><td>id</td>
+<td>integer</td>
+<td>GraphicsMagick registry id</td>
+</tr>
+<tr><td>label</td>
+<td>string</td>
+<td>image label</td>
+</tr>
+<tr><td>maximum-error</td>
+<td>double</td>
+<td>the normalized max error per pixel computed with
+methods Compare() or Quantize()</td>
+</tr>
+<tr><td>mean-error</td>
+<td>double</td>
+<td>the normalized mean error per pixel computed
+with methods Compare() or Quantize()</td>
+</tr>
+<tr><td>montage</td>
+<td>geometry</td>
+<td>tile size and offset within an image montage</td>
+</tr>
+<tr><td>rows</td>
+<td>integer</td>
+<td>the number of rows or height of an image</td>
+</tr>
+<tr><td>signature</td>
+<td>string</td>
+<td>SHA-256 message digest associated with the image
+pixel stream</td>
+</tr>
+<tr><td>taint</td>
+<td>{True,
+False}</td>
+<td>True if the image has been modified</td>
+</tr>
+<tr><td>width</td>
+<td>integer</td>
+<td>the number of columns or width of an image</td>
+</tr>
+<tr><td>x-resolution</td>
+<td>integer</td>
+<td>x resolution of the image</td>
+</tr>
+<tr><td>y-resolution</td>
+<td>integer</td>
+<td>y resolution of the image</td>
+</tr>
+</tbody>
+</table>
+<p>GetAttribute() is an alias for method Get().</p>
+<p>Most of the attributes listed above have an analog in convert. See the
+documentation for a more detailed description of these attributes.</p>
+</div>
+<div class="section" id="create-an-image-montage">
+<h1><a class="toc-backref" href="#id12">Create an Image Montage</a></h1>
+<p>Use method Montage() to create a composite image by combining several
+separate images. The images are tiled on the composite image with the
+name of the image optionally appearing just below the individual tile.
+For example,</p>
+<pre class="literal-block">
+$image-&gt;Montage(geometry=&gt;'160x160', tile=&gt;'2x2', texture=&gt;'granite:');
+</pre>
+<p>And here is a list of Montage() parameters you can set:</p>
+<table border="1" class="docutils">
+<caption>Montage Parameters</caption>
+<colgroup>
+<col width="15%" />
+<col width="52%" />
+<col width="32%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Parameter</td>
+<td>Values</td>
+<td>Description</td>
+</tr>
+<tr><td>background</td>
+<td>color name</td>
+<td>background color name</td>
+</tr>
+<tr><td>borderwidth</td>
+<td>integer</td>
+<td>image border width</td>
+</tr>
+<tr><td>compose</td>
+<td>{Over, In, Out, Atop, Xor, Plus,
+Minus, Add, Subtract, Difference,
+Bumpmap, Copy, Mask, Dissolve, Clear,
+Displace}</td>
+<td>composite operator</td>
+</tr>
+<tr><td>filename</td>
+<td>string</td>
+<td>name of montage image</td>
+</tr>
+<tr><td>fill</td>
+<td>color name</td>
+<td>fill color for
+annotations</td>
+</tr>
+<tr><td>font</td>
+<td>string</td>
+<td>X11 font name</td>
+</tr>
+<tr><td>frame</td>
+<td>geometry</td>
+<td>surround the image with
+an ornamental border</td>
+</tr>
+<tr><td>geometry</td>
+<td>geometry</td>
+<td>preferred tile and
+border size of each
+tile of the composite
+image</td>
+</tr>
+<tr><td>gravity</td>
+<td>{NorthWest, North, NorthEast, West,
+Center, East, SouthWest, South,
+SouthEast}</td>
+<td>direction image
+gravitates to within a
+tile</td>
+</tr>
+<tr><td>ICM</td>
+<td>blob</td>
+<td>color information
+profile</td>
+</tr>
+<tr><td>IPTC</td>
+<td>blob</td>
+<td>newswire information
+profile</td>
+</tr>
+<tr><td>label</td>
+<td>string</td>
+<td>assign a label to an
+image</td>
+</tr>
+<tr><td>mode</td>
+<td>{Frame, Unframe, Concatenate}</td>
+<td>thumbnail framing
+options</td>
+</tr>
+<tr><td>pointsize</td>
+<td>integer</td>
+<td>pointsize of the
+Postscript or TrueType
+font</td>
+</tr>
+<tr><td>shadow</td>
+<td>{True, False}</td>
+<td>add a shadow beneath a
+tile to simulate depth</td>
+</tr>
+<tr><td>stroke</td>
+<td>color name</td>
+<td>stroke color for
+annotations</td>
+</tr>
+<tr><td>texture</td>
+<td>string</td>
+<td>name of texture to tile
+onto the image
+background</td>
+</tr>
+<tr><td>tile</td>
+<td>geometry</td>
+<td>number of tiles per row
+and column</td>
+</tr>
+<tr><td>title</td>
+<td>string</td>
+<td>assign a title to the
+image montage</td>
+</tr>
+<tr><td>transparent</td>
+<td>string</td>
+<td>make this color
+transparent within the
+image</td>
+</tr>
+</tbody>
+</table>
+<p>Note, that the geometry parameter is a short cut for the width and height
+parameters (e.g. geometry=&gt;'106x80' is equivalent to width=&gt;106, height=&gt;
+80).</p>
+<p>MontageImage() is an alias for method Montage().</p>
+<p>Most of the attributes listed above have an analog in montage. See the
+documentation for a more detailed description of these attributes.</p>
+</div>
+<div class="section" id="working-with-blobs">
+<h1><a class="toc-backref" href="#id13">Working with Blobs</a></h1>
+<p>A blob contains data that directly represent a particular image format in
+memory instead of on disk. PerlMagick supports blobs in any of these
+image formats and provides methods to convert a blob to or from a
+particular image format.</p>
+<table border="1" class="docutils">
+<caption>Blob Methods</caption>
+<colgroup>
+<col width="16%" />
+<col width="14%" />
+<col width="34%" />
+<col width="36%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Method</td>
+<td>Parameters</td>
+<td>Return Value</td>
+<td>Description</td>
+</tr>
+<tr><td>ImageToBlob</td>
+<td>any image
+attribute</td>
+<td>an array of image data
+in the respective image
+format</td>
+<td>convert an image or image
+sequence to an array of
+blobs</td>
+</tr>
+<tr><td>BlobToImage</td>
+<td>one or
+more blobs</td>
+<td>the number of blobs
+converted to an image</td>
+<td>convert one or more blobs
+to an image</td>
+</tr>
+</tbody>
+</table>
+<p>ImageToBlob() returns the image data in their respective formats. You can
+then print it, save it to an ODBC database, write it to a file, or pipe
+it to a display program:</p>
+<pre class="literal-block">
+&#64;blobs = $image-&gt;ImageToBlob();
+open(DISPLAY,&quot;| display -&quot;) || die;
+binmode DISPLAY;
+print DISPLAY $blobs[0];
+close DISPLAY;
+</pre>
+<p>Method BlobToImage() returns an image or image sequence converted from
+the supplied blob:</p>
+<pre class="literal-block">
+&#64;blob=$db-&gt;GetImage();
+$image=Graphics::Magick-&gt;new(magick=&gt;'jpg');
+$image-&gt;BlobToImage(&#64;blob);
+</pre>
+</div>
+<div class="section" id="miscellaneous-methods">
+<h1><a class="toc-backref" href="#id14">Miscellaneous Methods</a></h1>
+<p>The Append() method append a set of images. For example,</p>
+<pre class="literal-block">
+$p = $image-&gt;Append(stack=&gt;{true,false});
+</pre>
+<p>appends all the images associated with object $image. By default, images
+are stacked left-to-right. Set stack to True to stack them top-to-bottom.</p>
+<p>The Average() method averages a set of images. For example,</p>
+<pre class="literal-block">
+$p = $image-&gt;Average();
+</pre>
+<p>averages all the images associated with object $image.</p>
+<p>The Clone() method copies a set of images. For example,</p>
+<pre class="literal-block">
+$p = $image-&gt;Clone();
+</pre>
+<p>copies all the images from object $q to $p. You can use this method for
+single or multi-image sequences.</p>
+<p>The Morph() method morphs a set of images. Both the image pixels and size
+are linearly interpolated to give the appearance of a meta-morphosis from
+one image to the next:</p>
+<pre class="literal-block">
+$p = $image-&gt;Morph(frames=&gt;integer);
+</pre>
+<p>where frames is the number of in-between images to generate. The default
+is 1.</p>
+<p>Mosaic() creates an mosaic from an image sequence.</p>
+<p>Method Mogrify() is a single entry point for the image manipulation
+methods (Manipulate an Image). The parameters are the name of a method
+followed by any parameters the method may require. For example, these
+calls are equivalent:</p>
+<pre class="literal-block">
+$image-&gt;Crop('340x256+0+0');
+$image-&gt;Mogrify('crop', '340x256+0+0');
+</pre>
+<p>Method MogrifyRegion() applies a transform to a region of the image. It
+is similar to Mogrify() but begins with the region geometry. For example,
+suppose you want to brighten a 100x100 region of your image at location
+(40, 50):</p>
+<pre class="literal-block">
+$image-&gt;MogrifyRegion('100x100+40+50', 'modulate', brightness=&gt;50);
+</pre>
+<p>Ping() is a convenience method that returns information about an image
+without having to read the image into memory. It returns the width,
+height, file size in bytes, and the file format of the image. You can
+specify more than one filename but only one filehandle:</p>
+<pre class="literal-block">
+($width, $height, $size, $format) = $image-&gt;Ping('logo.png');
+($width, $height, $size, $format) = $image-&gt;Ping(file=&gt;\*IMAGE);
+($width, $height, $size, $format) = $image-&gt;Ping(blob=&gt;&#64;blob);
+</pre>
+<p>This is a more efficient and less memory intensive way to query if an
+image exists and what its characteristics are.</p>
+<p>To have full control over text positioning you need font metric
+information. Use</p>
+<pre class="literal-block">
+($x_ppem, $y_ppem, $ascender, $descender, $width, $height, $max_advance) =
+$image-&gt;QueryFontMetrics(parameters);
+
+Where parameters is any parameter of the Annotate method. The
+'text' parameter must be specified since there can be no default for
+the text to render. The return values are
+
+* character width
+* character height
+* ascender
+* descender
+* text width
+* text height
+* maximum horizontal advance
+</pre>
+<p>Call QueryColor() with no parameters to return a list of known colors
+names or specify one or more color names to get these attributes: red,
+green, blue, and opacity value.</p>
+<pre class="literal-block">
+&#64;colors = $image-&gt;QueryColor();
+($red, $green, $blue, $opacity) = $image-&gt;QueryColor('cyan');
+($red, $green, $blue, $opacity) = $image-&gt;QueryColor('#716bae');
+</pre>
+<p>QueryColorname() accepts a color value and returns its respective name or
+hex value;</p>
+<pre class="literal-block">
+$name = $image-&gt;QueryColorname('rgba(80,60,0,0)');
+</pre>
+<p>Call QueryFont() with no parameters to return a list of known fonts or
+specify one or more font names to get these attributes: font name,
+description, family, style, stretch, weight, encoding, foundry, format,
+metrics, and glyphs values.</p>
+<pre class="literal-block">
+&#64;fonts = $image-&gt;QueryFont();
+$weight = ($image-&gt;QueryFont('Helvetica'))[5];
+</pre>
+<p>Call QueryFormat() with no parameters to return a list of known image
+formats or specify one or more format names to get these attributes:
+adjoin, blob support, raw, decoder, encoder, description, and module.</p>
+<pre class="literal-block">
+&#64;formats = $image-&gt;QueryFormat();
+($adjoin, $blob_support, $raw, $decoder, $encoder, $description, $module) = $image-&gt;QueryFormat('gif');
+</pre>
+<p>Use RemoteCommand() to send a command to an already running display or
+animate application. The only parameter is the name of the image file to
+display or animate.</p>
+<p>Finally, the Transform() method accepts a fully-qualified geometry
+specification for cropping or resizing one or more images. For example,</p>
+<pre class="literal-block">
+$p = $image-&gt;Transform(crop=&gt;'100x100');
+</pre>
+<p>You can optionally add Image to any method name above. For example,
+PingImage() is an alias for method Ping().</p>
+</div>
+<div class="section" id="handling-errors">
+<h1><a class="toc-backref" href="#id15">Handling Errors</a></h1>
+<p>All PerlMagick methods return an undefined string context upon success. If
+any problems occur, the error is returned as a string with an embedded
+numeric status code. A status code less than 400 is a warning. This means
+that the operation did not complete but was recoverable to some degree. A
+numeric code greater or equal to 400 is an error and indicates the
+operation failed completely. Here is how errors are returned for the
+different methods:</p>
+<blockquote>
+<ul>
+<li><p class="first">Methods which return a number (e.g. Read(), Write()):</p>
+<pre class="literal-block">
+$status = $image-&gt;Read(...);
+warn &quot;$status&quot; if &quot;$status&quot;; # print the error message
+$status =~ /(\d+)/;
+print $1; # print the error number
+print 0+$status; # print the number of images read
+</pre>
+</li>
+<li><p class="first">Methods which operate on an image (e.g. Resize(), Crop()):</p>
+<pre class="literal-block">
+$status = $image-&gt;Crop(...);
+warn &quot;$status&quot; if &quot;$status&quot;; # print the error message
+$status =~ /(\d+)/;
+print $1; # print the error number
+</pre>
+</li>
+<li><p class="first">Methods which return images (Average(), Montage(), Clone()) should be
+checked for errors this way:</p>
+<pre class="literal-block">
+$status = $image-&gt;Montage(...);
+warn &quot;$status&quot; if !ref($status); # print the error message
+$status =~ /(\d+)/;
+print $1; # print the error number
+</pre>
+</li>
+</ul>
+</blockquote>
+<p>Here is an example error message:</p>
+<pre class="literal-block">
+Error 400: Memory allocation failed
+</pre>
+<p>Below is a list of error and warning codes:</p>
+<table border="1" class="docutils">
+<caption>Error and Warning Codes</caption>
+<colgroup>
+<col width="6%" />
+<col width="31%" />
+<col width="63%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>Code</td>
+<td>Mnemonic</td>
+<td>Description</td>
+</tr>
+<tr><td>0</td>
+<td>Success</td>
+<td>method completed without an error or warning</td>
+</tr>
+<tr><td>300</td>
+<td>ResourceLimitWarning</td>
+<td>a program resource is exhausted (e.g. not
+enough memory)</td>
+</tr>
+<tr><td>305</td>
+<td>TypeWarning</td>
+<td>A font is unavailable; a substitution may
+have occurred</td>
+</tr>
+<tr><td>310</td>
+<td>OptionWarning</td>
+<td>a command-line option was malformed</td>
+</tr>
+<tr><td>315</td>
+<td>DelegateWarning</td>
+<td>an GraphicsMagick delegate returned a warning</td>
+</tr>
+<tr><td>320</td>
+<td>MissingDelegateWarning</td>
+<td>the image type can not be read or written
+because the appropriate Delegate is missing</td>
+</tr>
+<tr><td>325</td>
+<td>CorruptImageWarning</td>
+<td>the image file may be corrupt</td>
+</tr>
+<tr><td>330</td>
+<td>FileOpenWarning</td>
+<td>the image file could not be opened</td>
+</tr>
+<tr><td>335</td>
+<td>BlobWarning</td>
+<td>a binary large object could not be allocated</td>
+</tr>
+<tr><td>340</td>
+<td>StreamWarning</td>
+<td>there was a problem reading or writing from a
+stream</td>
+</tr>
+<tr><td>345</td>
+<td>CacheWarning</td>
+<td>pixels could not be saved to the pixel cache</td>
+</tr>
+<tr><td>350</td>
+<td>CoderWarning</td>
+<td>there was a problem with an image coder</td>
+</tr>
+<tr><td>355</td>
+<td>ModuleWarning</td>
+<td>there was a problem with an image module</td>
+</tr>
+<tr><td>360</td>
+<td>DrawWarning</td>
+<td>a drawing operation failed</td>
+</tr>
+<tr><td>365</td>
+<td>ImageWarning</td>
+<td>the operation could not complete due to an
+incompatible image</td>
+</tr>
+<tr><td>380</td>
+<td>XServerWarning</td>
+<td>an X resource is unavailable</td>
+</tr>
+<tr><td>385</td>
+<td>MonitorWarning</td>
+<td>there was a problem with prgress monitor</td>
+</tr>
+<tr><td>390</td>
+<td>RegistryWarning</td>
+<td>there was a problem getting or setting the
+registry</td>
+</tr>
+<tr><td>395</td>
+<td>ConfigureWarning</td>
+<td>there was a problem getting a configuration
+file</td>
+</tr>
+<tr><td>400</td>
+<td>ResourceLimitError</td>
+<td>a program resource is exhausted (e.g. not
+enough memory)</td>
+</tr>
+<tr><td>405</td>
+<td>TypeError</td>
+<td>A font is unavailable; a substitution may
+have occurred</td>
+</tr>
+<tr><td>410</td>
+<td>OptionError</td>
+<td>a command-line option was malformed</td>
+</tr>
+<tr><td>415</td>
+<td>DelegateError</td>
+<td>an GraphicsMagick delegate returned a warning</td>
+</tr>
+<tr><td>420</td>
+<td>MissingDelegateError</td>
+<td>the image type can not be read or written
+because the appropriate Delegate is missing</td>
+</tr>
+<tr><td>425</td>
+<td>CorruptImageError</td>
+<td>the image file may be corrupt</td>
+</tr>
+<tr><td>430</td>
+<td>FileOpenError</td>
+<td>the image file could not be opened</td>
+</tr>
+<tr><td>435</td>
+<td>BlobError</td>
+<td>a binary large object could not be allocated</td>
+</tr>
+<tr><td>440</td>
+<td>StreamError</td>
+<td>there was a problem reading or writing from a
+stream</td>
+</tr>
+<tr><td>445</td>
+<td>CacheError</td>
+<td>pixels could not be saved to the pixel cache</td>
+</tr>
+<tr><td>450</td>
+<td>CoderError</td>
+<td>there was a problem with an image coder</td>
+</tr>
+<tr><td>455</td>
+<td>ModuleError</td>
+<td>there was a problem with an image module</td>
+</tr>
+<tr><td>460</td>
+<td>DrawError</td>
+<td>a drawing operation failed</td>
+</tr>
+<tr><td>465</td>
+<td>ImageError</td>
+<td>the operation could not complete due to an
+incompatible image</td>
+</tr>
+<tr><td>480</td>
+<td>XServerError</td>
+<td>an X resource is unavailable</td>
+</tr>
+<tr><td>480</td>
+<td>MonitorError</td>
+<td>there was a progress monitor error</td>
+</tr>
+<tr><td>490</td>
+<td>RegistryError</td>
+<td>there was a problem getting or setting the
+registry</td>
+</tr>
+<tr><td>495</td>
+<td>ConfigureError</td>
+<td>there was a problem getting a configuration
+file</td>
+</tr>
+</tbody>
+</table>
+<p>The following illustrates how you can use a numeric status code:</p>
+<pre class="literal-block">
+$status = $image-&gt;Read('rose.png');
+$status =~ /(\d+)/;
+die &quot;unable to continue&quot; if ($1 == ResourceLimitError);
+</pre>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/perl.rst b/www/perl.rst
new file mode 100644
index 0000000..92d1de9
--- /dev/null
+++ b/www/perl.rst
@@ -0,0 +1,1502 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=====================================
+GraphicsMagick Perl API -- PerlMagick
+=====================================
+
+.. contents::
+ :local:
+
+Introduction
+============
+
+PerlMagick is an objected-oriented Perl interface to GraphicsMagick. Use
+the module to read, manipulate, or write an image or image sequence from
+within a Perl script. This makes it very suitable for Web CGI scripts.
+You must have GraphicsMagick 1.0.0 or above and Perl version 5.005_02 or
+greater installed on your system for either of these utilities to work.
+There are a number of useful scripts available to show you the value of
+PerlMagick. The PerlMagick demo directory provides a number of sample
+demos.
+
+Installation
+============
+
+UNIX
+----
+
+PerlMagick is installed by default by installing GraphicsMagick.
+Installing PerlMagick as a subordinate package of GraphicsMagick is the
+best way to avoid problems.
+
+For Unix, you typically need to be root to install the software. There
+are ways around this. Consult the Perl manual pages for more information.
+
+Windows XP - Windows 8
+----------------------
+
+Please note that a nice GUI installer is available for GraphicsMagick.
+PerlMagick is included in this installer. If you are using the installer,
+then there is no need to compile PerlMagick.
+
+After GraphicsMagick has been compiled from the GraphicsMagick Windows
+source distribution using Microsoft Visual C++, PerlMagick may be
+manually built and installed by opening a CLI window and performing the
+following steps::
+
+ cd PerlMagick
+ copy Makefile.nt Makefile.PL
+ perl Makefile.PL
+ nmake
+ nmake install
+
+See the PerlMagick Windows HowTo page for further installation
+instructions.
+
+Running the Regression Tests
+----------------------------
+
+To verify a correct installation, type::
+
+ make test
+
+Use nmake test under Windows. There are a few demonstration scripts
+available to exercise many of the functions PerlMagick can perform. Type
+
+::
+
+ cd demo
+ make
+
+You are now ready to utilize the PerlMagick methods from within your Perl
+scripts.
+
+Overview
+========
+
+Any script that wants to use PerlMagick methods must first define the
+methods within its namespace and instantiate an image object. Do this
+with
+
+::
+
+ use Graphics::Magick;
+ $image=Graphics::Magick->new;
+
+Note that this differs from the ImageMagick version of PerlMagick which
+uses the namespace Image::Magick. Any PerlMagick code written for the
+ImageMagick version of PerlMagick requires a global substition of
+Image::Magick to Graphics::Magick in order to work with the
+GraphicsMagick version.
+
+The new() method takes the same parameters as SetAttribute . For example::
+
+ $image=Graphics::Magick->new(size=>'384x256');
+
+Next you will want to read an image or image sequence, manipulate it, and
+then display or write it. The input and output methods for PerlMagick are
+defined in Read or Write an Image. See Set an Image Attribute for methods
+that affect the way an image is read or written. Refer to Manipulate an
+Image for a list of methods to transform an image. Get an Image Attribute
+describes how to retrieve an attribute for an image. Refer to Create an
+Image Montage for details about tiling your images as thumbnails on a
+background. Finally, some methods do not neatly fit into any of the
+categories just mentioned. Review Miscellaneous Methods for a list of
+these methods.
+
+Once you are finished with a PerlMagick object you should consider
+destroying it. Each image in an image sequence is stored in either
+virtual memory or as a file in the system's temporary file directory.
+This can potentially add up to megabytes of memory or disk. Upon
+destroying a PerlMagick object, the memory is returned for use by other
+Perl methods. The recommended way to destroy an object is with undef
+
+::
+
+ undef $image;
+
+To delete all the images but retain the Graphics::Magick object use
+
+::
+
+ @$image = ();
+
+and finally, to delete a single image from a multi-image sequence, use
+
+::
+
+ undef $image->[x];
+
+The next section illustrates how to use various PerlMagick methods to
+manipulate an image sequence.
+
+Some of the PerlMagick methods require external programs such as
+Ghostscript. This may require an explicit path in your PATH environment
+variable to work properly. For example,
+
+::
+
+ $ENV{PATH}='/bin:/usr/bin:/usr/local/bin';
+
+
+Example Script
+==============
+
+Here is an example script to get you started::
+
+ #!/usr/local/bin/perl
+ use Graphics::Magick;
+ my($image, $status);
+ $image = Graphics::Magick->new;
+ $status = $image->Read('girl.png', 'logo.png', 'rose.png');
+ warn "$status" if "$status";
+ $status = $image->Crop(geometry=>'100x100+100+100');
+ warn "$status" if "$status";
+ $status = $image->Write('x.gif');
+ warn "$status" if "$status";
+
+The script reads three images, crops them, and writes a single image as a
+GIF animation sequence. In many cases you may want to access individual
+images of a sequence. The next example illustrates how this is done::
+
+ #!/usr/local/bin/perl
+ use Graphics::Magick;
+ my($image, $p, $q);
+ $image = new Graphics::Magick;
+ $image->Read('x1.png');
+ $image->Read('j*.jpg');
+ $image->Read('k.miff[1, 5, 3]');
+ $image->Contrast();
+ for ($x = 0; $image->[x]; $x++)
+ {
+ $image->[x]->Frame('100x200') if $image->[x]->Get('magick') eq 'GIF';
+ undef $image->[x] if $image->[x]->Get('columns') < 100;
+ }
+ $p = $image->[1];
+ $p->Draw(stroke=>'red', primitive=>'rectangle', points=>'20,20 100,100');
+ $q = $p->Montage();
+ undef $image;
+ $q->Write('x.miff');
+
+Suppose you want to start out with a 100 by 100 pixel white canvas with a
+red pixel in the center. Try
+
+::
+
+ $image = Graphics::Magick->new;
+ $image->Set(size=>'100x100');
+ $image->ReadImage('xc:white');
+ $image->Set('pixel[49,49]'=>'red');
+
+Or suppose you want to convert your color image to grayscale::
+
+ $image->Quantize(colorspace=>'gray');
+
+Here we annotate an image with a Taipai TrueType font::
+
+ $text = 'Works like magick!';
+ $image->Annotate(font=>'kai.ttf', pointsize=>40, fill=>'green', text=>$text);
+
+Other clever things you can do with a PerlMagick objects include
+
+::
+
+ $i = $#$p"+1"; # return the number of images associated with object p
+ push(@$q, @$p); # push the images from object p onto object q
+ @$p = (); # delete the images but not the object p
+ $p->Convolve([1, 2, 1, 2, 4, 2, 1, 2, 1]); # 3x3 Gaussian kernel
+
+Read or Write an Image
+======================
+
+Use the methods listed below to either read, write, or display an image
+or image sequence.
+
+.. table:: Read or Write Methods
+
+ +-------+-------------+-------------------+-------------------------------+
+ |Method | Parameters | Return Value | Description |
+ +-------+-------------+-------------------+-------------------------------+
+ |Read |one or more |the number of |read an image or image sequence|
+ | |filenames |images read | |
+ +-------+-------------+-------------------+-------------------------------+
+ |Write |filename |the number of |write an image or image |
+ | | |images written |sequence |
+ +-------+-------------+-------------------+-------------------------------+
+ |Display|server name |the number of |display the image or image |
+ | | |images displayed |sequence to an X server |
+ +-------+-------------+-------------------+-------------------------------+
+ |Animate|server name |the number of |animate image sequence to an X |
+ | | |images animated |server |
+ +-------+-------------+-------------------+-------------------------------+
+
+For convenience, methods Write(), Display(), and Animate() can take any
+parameter that SetAttribute knows about. For example,
+
+::
+
+ $image->Write(filename=>'image.png', compression=>'None');
+
+Use - as the filename to method Read() to read from standard in or to
+method Write() to write to standard out::
+
+ binmode STDOUT;
+ $image->Write('png:-');
+
+To read an image from a disk file, use::
+ $image = Graphics::Magick->new;
+ $filename = 'test.gif';
+ $status = $image->Read ($filename);
+
+and to write the image back to the disk file, use::
+
+ $status = $image->Write($filename);
+
+To read an image in the GIF format from a PERL filehandle, use::
+
+ $image = Graphics::Magick->new;
+ open(IMAGE, 'image.gif');
+ $status = $image->Read(file=>\*IMAGE);
+ close(IMAGE);
+
+To write an image in the PNG format to a PERL filehandle, use::
+
+ $filename = "image.png";
+ open(IMAGE, ">$filename");
+ $status = $image->Write(file=>\*IMAGE, filename=>$filename);
+ close(IMAGE);
+
+If %0Nd appears in the filename, it is interpreted as a printf format
+specification and the specification is replaced with the specified
+decimal encoding of the scene number. For example,
+
+::
+
+ image%03d.miff
+
+converts files image000.miff, image001.miff, etc.
+
+You can optionally add Image to any method name. For example, ReadImage()
+is an alias for method Read().
+
+
+Manipulate an Image
+===================
+
+Once you create an image with, for example, method ReadImage() you may want
+to operate on it. Below is a list of all the image manipulations methods
+available to you with PerlMagick. There are examples of select PerlMagick
+methods. Here is an example call to an image manipulation method::
+
+ $image->Crop(geometry=>'100x100"+1"0+20');
+ $image->[x]->Frame("100x200");
+
+Image method parameters are often redundant. For example, a 'geometry'
+string parameter (e.g. 800x600+10+20) is equivalent to the explicit use of
+width, height, x, and y, parameters.
+
+The following image manipulation methods are available:
+
+.. table:: Image Manipulation Methods
+
+ +-----------------+---------------------------------+---------------------+
+ | Method | Parameters | Description |
+ +-----------------+---------------------------------+---------------------+
+ | | |Local adaptive |
+ | | |thresholding. Width |
+ | | |and height specify |
+ | |geometry=>geometry, width=> |the size of the local|
+ |AdaptiveThreshold|integer, height=> integer, offset|region while offset |
+ | |=>integer |specifies the amount |
+ | | |to subtract from the |
+ | | |average of the |
+ | | |region. |
+ +-----------------+---------------------------------+---------------------+
+ | | |Add noise to an image|
+ | | |across the red, |
+ | |noise=>{Uniform, Gaussian, |green, and blue, |
+ |AddNoise |Multiplicative, Impulse, |channels. Set the |
+ | |Laplacian, Poisson, Random} |image colorspace to |
+ | | |GRAY to obtain |
+ | | |intensity noise. |
+ +-----------------+---------------------------------+---------------------+
+ | |affine=>array of float values, | |
+ |AffineTransform |translate=>float, float, scale=> |Affine transform |
+ | |float, float, rotate=>float, |image |
+ | |skewX=>float, skewY=>float | |
+ +-----------------+---------------------------------+---------------------+
+ | |text=>string, font=>string, | |
+ | |family=>string, style=>{Normal, | |
+ | |Italic, Oblique, Any}, stretch=> | |
+ | |{Normal, UltraCondensed, | |
+ | |ExtraCondensed, Condensed, | |
+ | |SemiCondensed, SemiExpanded, | |
+ | |Expanded, ExtraExpanded, | |
+ | |UltraExpanded}, weight=>integer, | |
+ | |pointsize=>integer, density=> |annotate an image |
+ | |geometry, stroke=> color name, |with text. See |
+ | |strokewidth=>integer, fill=>color|QueryFontMetrics to |
+ |Annotate |name, undercolor=>color name, |get font metrics |
+ | |geometry=>geometry, gravity=> |without rendering any|
+ | |{NorthWest, North, NorthEast, |text. |
+ | |West, Center, East, SouthWest, | |
+ | |South, SouthEast}, antialias=> | |
+ | |{true, false}, x=>integer, y=> | |
+ | |integer, affine=>array of float | |
+ | |values, translate=>float, float, | |
+ | |scale=>float, float, rotate=> | |
+ | |float. skewX=>float, skewY=> | |
+ | |float, align=>{Left, Center, | |
+ | |Right}, encoding=>{UTF-8} | |
+ +-----------------+---------------------------------+---------------------+
+ | | |blur the image with a|
+ | |geometry=>geometry, radius=> |Gaussian operator of |
+ |Blur |double, sigma=> double |the given radius and |
+ | | |standard deviation |
+ | | |(sigma). |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, width=> |surround the image |
+ |Border |integer, height=> integer, fill=>|with a border of |
+ | |color name |color |
+ +-----------------+---------------------------------+---------------------+
+ | |channel=>{Red, Cyan, Green, |extract a channel |
+ |Channel |Magenta, Blue, Yellow, Opacity, |from the image |
+ | |Black, Matte, All, Gray} | |
+ +-----------------+---------------------------------+---------------------+
+ |Charcoal |order=>integer |simulate a charcoal |
+ | | |drawing |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, width=> | |
+ |Chop |integer, height=> integer, x=> |chop an image |
+ | |integer, y=>integer | |
+ +-----------------+---------------------------------+---------------------+
+ |Coalesce | |merge a sequence of |
+ | | |images |
+ +-----------------+---------------------------------+---------------------+
+ | | |apply any clipping |
+ |Clip | |path information as |
+ | | |an image clip mask. |
+ +-----------------+---------------------------------+---------------------+
+ | | |changes the color |
+ | | |value of any pixel |
+ | | |that matches the |
+ | | |color of the target |
+ | |geometry=>geometry, x=>integer, y|pixel and is a |
+ |ColorFloodfill |=>integer , fill=>color name, |neighbor. If you |
+ | |bordercolor=> color name |specify a border |
+ | | |color, the color |
+ | | |value is changed for |
+ | | |any neighbor pixel |
+ | | |that is not that |
+ | | |color. |
+ +-----------------+---------------------------------+---------------------+
+ |Colorize |fill=>color name, opacity=>string|colorize the image |
+ | | |with the fill color |
+ +-----------------+---------------------------------+---------------------+
+ |Comment |string |add a comment to your|
+ | | |image |
+ +-----------------+---------------------------------+---------------------+
+ |Compare |image=>image-handle |compare image to a |
+ | | |reference image |
+ +-----------------+---------------------------------+---------------------+
+ | |image=>image-handle, compose=>{ | |
+ | |Over, In, Out, Atop, Xor, Plus, | |
+ | |Minus, Add, Subtract, | |
+ | |Difference, Multiply, Bumpmap, | |
+ | |Copy, CopyRed, CopyGreen, | |
+ | |CopyBlue, CopyOpacity, | |
+ | |Clear, Dissolve, Displace, | |
+ | |Modulate, Threshold, No, Darken, | |
+ | |Lighten, Hue, Saturate, | |
+ |Composite |Colorize, Luminize, Screen, |composite one image |
+ | |Overlay, CopyCyan, CopyMagenta, |onto another |
+ | |CopyYellow, CopyBlack, Divide, | |
+ | |HardLight}, | |
+ | |mask=> | |
+ | |image-handle, geometry=>geometry,| |
+ | |x=>integer, y=>integer, gravity=>| |
+ | |{NorthWest, North, NorthEast, | |
+ | |West, Center, East, SouthWest, | |
+ | |South, SouthEast}, opacity=> | |
+ | |integer, tile=>{True, False}, | |
+ | |rotate=>double, color=>color name| |
+ +-----------------+---------------------------------+---------------------+
+ |Contrast |sharpen=>{True, False} |enhance or reduce the|
+ | | |image contrast |
+ +-----------------+---------------------------------+---------------------+
+ | | |apply a convolution |
+ | | |kernel to the image. |
+ | |coefficients=>array of float |Given a kernel order |
+ |Convolve |values |, you would supply |
+ | | |order*order float |
+ | | |values (e.g. 3x3 |
+ | | |implies 9 values). |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, width=> | |
+ |Crop |integer, height=> integer, x=> |crop an image |
+ | |integer, y=>integer | |
+ +-----------------+---------------------------------+---------------------+
+ |CycleColormap |amount=>integer |displace image |
+ | | |colormap by amount |
+ +-----------------+---------------------------------+---------------------+
+ | | |break down an image |
+ |Deconstruct | |sequence into |
+ | | |constituent parts |
+ +-----------------+---------------------------------+---------------------+
+ |Despeckle | |reduce the speckles |
+ | | |within an image |
+ +-----------------+---------------------------------+---------------------+
+ | |primitive=>{point, line, | |
+ | |rectangle, roundRectangle, arc, | |
+ | |ellipse, circle, polyline, | |
+ | |polygon, ,bezier, path, color, | |
+ | |matte, text, image, @filename}, | |
+ | |points=>string , method=>{Point, | |
+ | |Replace, Floodfill, FillToBorder,| |
+ | |Reset}, stroke=> color name, fill|annotate an image |
+ |Draw |=>color name, tile=>image-handle,|with one or more |
+ | |strokewidth=>float, antialias=> |graphic primitives |
+ | |{true, false}, bordercolor=>color| |
+ | |name, x=> float, y=>float, affine| |
+ | |=>array of float values, | |
+ | |translate=>float, float, scale=> | |
+ | |float, float, rotate=>float. | |
+ | |skewX=>float, skewY=> float | |
+ +-----------------+---------------------------------+---------------------+
+ | | |enhance edges within |
+ |Edge |radius=>double |the image with a |
+ | | |convolution filter of|
+ | | |the given radius. |
+ +-----------------+---------------------------------+---------------------+
+ | | |emboss the image with|
+ | |geometry=>geometry, radius=> |a convolution filter |
+ |Emboss |double, sigma=> double |of the given radius |
+ | | |and standard |
+ | | |deviation (sigma). |
+ +-----------------+---------------------------------+---------------------+
+ | | |apply a digital |
+ |Enhance | |filter to enhance a |
+ | | |noisy image |
+ +-----------------+---------------------------------+---------------------+
+ | | |perform histogram |
+ |Equalize | |equalization to the |
+ | | |image |
+ +-----------------+---------------------------------+---------------------+
+ |Flatten | |flatten a sequence of|
+ | | |images |
+ +-----------------+---------------------------------+---------------------+
+ | | |create a mirror image|
+ | | |by reflecting the |
+ |Flip | |image scanlines in |
+ | | |the vertical |
+ | | |direction |
+ +-----------------+---------------------------------+---------------------+
+ | | |create a mirror image|
+ | | |by reflecting the |
+ |Flop | |image scanlines in |
+ | | |the horizontal |
+ | | |direction |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, width=> |surround the image |
+ |Frame |integer, height=> integer, inner |with an ornamental |
+ | |=>integer, outer=>integer, fill=>|border |
+ | |color name | |
+ +-----------------+---------------------------------+---------------------+
+ |Gamma |gamma=>string, red=>double, green|gamma correct the |
+ | |=>double , blue=>double |image |
+ +-----------------+---------------------------------+---------------------+
+ |Implode |amount=>double |implode image pixels |
+ | | |about the center |
+ +-----------------+---------------------------------+---------------------+
+ |Label |string |assign a label to an |
+ | | |image |
+ +-----------------+---------------------------------+---------------------+
+ | |level=>string, 'black-point'=> |adjust the level of |
+ |Level |double, 'mid-point'=>double, |image contrast |
+ | |'white-point'=>double | |
+ +-----------------+---------------------------------+---------------------+
+ |Magnify | |double the size of an|
+ | | |image |
+ +-----------------+---------------------------------+---------------------+
+ | |image=>image-handle, dither=> |choose a particular |
+ |Map |{True, False} |set of colors from |
+ | | |this image |
+ +-----------------+---------------------------------+---------------------+
+ | | |changes the matte |
+ | | |value of any pixel |
+ | | |that matches the |
+ | | |color of the target |
+ | |geometry=>geometry, x=>integer, y|pixel and is a |
+ |MatteFloodfill |=>integer , matte=>integer, |neighbor. If you |
+ | |bordercolor=>color name |specify a border |
+ | | |color, the matte |
+ | | |value is changed for |
+ | | |any neighbor pixel |
+ | | |that is not that |
+ | | |color. |
+ +-----------------+---------------------------------+---------------------+
+ | | |replace each pixel |
+ |MedianFilter |radius=>double |with the median |
+ | | |intensity pixel of a |
+ | | |neighborhood. |
+ +-----------------+---------------------------------+---------------------+
+ |Minify | |half the size of an |
+ | | |image |
+ +-----------------+---------------------------------+---------------------+
+ | | |vary the brightness, |
+ |Modulate |brightness=>double, saturation=> |saturation, and hue |
+ | |double, hue=> double |of an image by the |
+ | | |specified percentage |
+ +-----------------+---------------------------------+---------------------+
+ | | |blur the image with a|
+ | | |Gaussian operator of |
+ | |geometry=>geometry, radius=> |the given radius and |
+ |MotionBlur |double, sigma=> double, angle=> |standard deviation |
+ | |double |(sigma) at the given |
+ | | |angle to simulate the|
+ | | |effect of motion |
+ +-----------------+---------------------------------+---------------------+
+ | | |replace every pixel |
+ | | |with its |
+ |Negate |gray=>{True, False} |complementary color |
+ | | |(white becomes black,|
+ | | |yellow becomes blue, |
+ | | |etc.) |
+ +-----------------+---------------------------------+---------------------+
+ | | |transform image to |
+ |Normalize | |span the full range |
+ | | |of color values |
+ +-----------------+---------------------------------+---------------------+
+ |OilPaint |radius=>integer |simulate an oil |
+ | | |painting |
+ +-----------------+---------------------------------+---------------------+
+ | |color=>color name, fill=> color |change this color to |
+ |Opaque |name |the fill color within|
+ | | |the image |
+ +-----------------+---------------------------------+---------------------+
+ | |colors=>integer, colorspace=> | |
+ | |{RGB, Gray, Transparent, OHTA, | |
+ | |XYZ, YCbCr, YIQ, YPbPr, YUV, |preferred number of |
+ |Quantize |CMYK}, treedepth=> integer, |colors in the image |
+ | |dither=>{True, False}, | |
+ | |measure_error=>{True, False}, | |
+ | |global_colormap=>{True, False} | |
+ +-----------------+---------------------------------+---------------------+
+ |Profile |name=>{ICM, IPTC}, profile=>blob |add or remove ICC or |
+ | | |IPTC image profile |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, width=> |lighten or darken |
+ |Raise |integer, height=> integer, x=> |image edges to create|
+ | |integer, y=>integer, raise=> |a 3-D effect |
+ | |{True, False} | |
+ +-----------------+---------------------------------+---------------------+
+ | | |reduce noise in the |
+ |ReduceNoise |radius=>double |image with a noise |
+ | | |peak elimination |
+ | | |filter |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, width=> | |
+ | |integer, height=> integer, filter|scale image to |
+ | |=>{Point, Box, Triangle, Hermite,|desired size. Specify|
+ |Resize |Hanning, Hamming, Blackman, |blur > 1 for blurry |
+ | |Gaussian, Quadratic, Cubic, |or < 1 for sharp |
+ | |Catrom, Mitchell, Lanczos, | |
+ | |Bessel, Sinc}, blur=>double | |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, x=>integer, y|roll an image |
+ |Roll |=>integer |vertically or |
+ | | |horizontally |
+ +-----------------+---------------------------------+---------------------+
+ |Rotate |degrees=>double, color=>color |rotate an image |
+ | |name | |
+ +-----------------+---------------------------------+---------------------+
+ |Sample |geometry=>geometry, width=> |scale image with |
+ | |integer, height=> integer |pixel sampling |
+ +-----------------+---------------------------------+---------------------+
+ |Scale |geometry=>geometry, width=> |scale image to |
+ | |integer, height=> integer |desired size |
+ +-----------------+---------------------------------+---------------------+
+ | |colorspace=>{RGB, Gray, |segment an image by |
+ | |Transparent, OHTA, XYZ, YCbCr, |analyzing the |
+ |Segment |YCC, YIQ, YPbPr, YUV, CMYK}, |histograms of the |
+ | |verbose={True, False}, cluster=> |color components and |
+ | |double, smooth= double |identifying units |
+ | | |that are homogeneous |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, azimuth=> |shade the image using|
+ |Shade |double, elevation=> double, gray |a distant light |
+ | |=>{true, false} |source |
+ +-----------------+---------------------------------+---------------------+
+ | | |sharpen the image |
+ | |geometry=>geometry, radius=> |with a Gaussian |
+ |Sharpen |double, sigma=> double |operator of the given|
+ | | |radius and standard |
+ | | |deviation (sigma). |
+ +-----------------+---------------------------------+---------------------+
+ |Shave |geometry=>geometry, width=> |shave pixels from the|
+ | |integer, height=> integer |image edges |
+ +-----------------+---------------------------------+---------------------+
+ | | |shear the image along|
+ |Shear |geometry=>geometry, x=>double, y |the X or Y axis by a |
+ | |=>double color=>color name |positive or negative |
+ | | |shear angle |
+ +-----------------+---------------------------------+---------------------+
+ | | |generate an SHA-256 |
+ |Signature | |message digest for |
+ | | |the image pixel |
+ | | |stream |
+ +-----------------+---------------------------------+---------------------+
+ | | |negate all pixels |
+ |Solarize |threshold=>integer |above the threshold |
+ | | |level |
+ +-----------------+---------------------------------+---------------------+
+ |Spread |amount=>integer |displace image pixels|
+ | | |by a random amount |
+ +-----------------+---------------------------------+---------------------+
+ | | |composites two images|
+ | | |and produces a single|
+ |Stereo |image=>image-handle |image that is the |
+ | | |composite of a left |
+ | | |and right image of a |
+ | | |stereo pair |
+ +-----------------+---------------------------------+---------------------+
+ | |image=>image-handle, offset=> |hide a digital |
+ |Stegano |integer |watermark within the |
+ | | |image |
+ +-----------------+---------------------------------+---------------------+
+ |Swirl |degrees=>double |swirl image pixels |
+ | | |about the center |
+ +-----------------+---------------------------------+---------------------+
+ | | |name of texture to |
+ |Texture |texture=>image-handle |tile onto the image |
+ | | |background |
+ +-----------------+---------------------------------+---------------------+
+ |Threshold |threshold=>string |threshold the image |
+ +-----------------+---------------------------------+---------------------+
+ | | |make this color |
+ |Transparent |color=>color name |transparent within |
+ | | |the image |
+ +-----------------+---------------------------------+---------------------+
+ | | |remove edges that are|
+ |Trim | |the background color |
+ | | |from the image |
+ +-----------------+---------------------------------+---------------------+
+ | |geometry=>geometry, radius=> |sharpen the image |
+ |UnsharpMask |double, sigma=> double, amount=> |with the unsharp mask|
+ | |double, threshold=>double |algorithm. |
+ +-----------------+---------------------------------+---------------------+
+ |Wave |geometry=>geometry, amplitude=> |alter an image along |
+ | |double, wavelength=> double |a sine wave |
+ +-----------------+---------------------------------+---------------------+
+
+Note, that the geometry parameter is a short cut for the width and height
+parameters (e.g. geometry=>'106x80' is equivalent to width=>106,
+height=>80).
+
+You can specify @filename in both Annotate() and Draw(). This reads the
+text or graphic primitive instructions from a file on disk. For example,
+
+::
+
+ $image->Draw(fill=>'red', primitive=>'rectangle',
+ points=>'20,20 100,100 40,40 200,200 60,60 300,300');
+
+Is equivalent to
+
+::
+
+ $image->Draw(fill=>'red', primitive=>'@draw.txt');
+
+Where draw.txt is a file on disk that contains this::
+
+ rectangle 20, 20 100, 100
+ rectangle 40, 40 200, 200
+ rectangle 60, 60 300, 300
+
+The text parameter for methods, Annotate(), Comment(), Draw(), and
+Label() can include the image filename, type, width, height, or other
+image attribute by embedding these special format characters::
+
+ %b file size
+ %d comment
+ %d directory
+ %e filename extension
+ %f filename
+ %h height
+ %m magick
+ %p page number
+ %s scene number
+ %t top of filename
+ %w width
+ %x x resolution
+ %y y resolution
+ \n newline
+ \r carriage return
+
+For example,
+
+::
+
+ text=>"%m:%f %wx%h"
+
+produces an annotation of MIFF:bird.miff 512x480 for an image titled
+bird.miff and whose width is 512 and height is 480.
+
+You can optionally add Image to any method name. For example, TrimImage()
+is an alias for method Trim().
+
+Most of the attributes listed above have an analog in convert. See the
+documentation for a more detailed description of these attributes.
+
+
+Set an Image Attribute
+======================
+
+Use method Set() to set an image attribute. For example,
+
+::
+
+ $image->Set(dither=>'True');
+ $image->[$x]->Set(delay=>3);
+
+And here is a list of all the image attributes you can set:
+
+.. table:: Image Attributes
+
+ +----------------+------------------------------------+-------------------+
+ | Attribute | Values | Description |
+ +----------------+------------------------------------+-------------------+
+ | | |join images into a |
+ |adjoin |{True, False} |single multi-image |
+ | | |file |
+ +----------------+------------------------------------+-------------------+
+ |antialias |{True, False} |remove pixel |
+ | | |aliasing |
+ +----------------+------------------------------------+-------------------+
+ |authenticate |string |decrypt image with |
+ | | |this password. |
+ +----------------+------------------------------------+-------------------+
+ |background |color name |image background |
+ | | |color |
+ +----------------+------------------------------------+-------------------+
+ | | |chromaticity blue |
+ |blue-primary |x-value, y-value |primary point (e.g.|
+ | | |0.15, 0.06) |
+ +----------------+------------------------------------+-------------------+
+ |bordercolor |color name |set the image |
+ | | |border color |
+ +----------------+------------------------------------+-------------------+
+ | | |Associate a clip |
+ |clip-mask |image |mask with the |
+ | | |image. |
+ +----------------+------------------------------------+-------------------+
+ | | |color name (e.g. |
+ |colormap[i] |color name |red) or hex value |
+ | | |(e.g. #ccc) at |
+ | | |position i |
+ +----------------+------------------------------------+-------------------+
+ |colorspace |{RGB, CMYK} |type of colorspace |
+ +----------------+------------------------------------+-------------------+
+ |comment |string |Append to the image|
+ | | |comment. |
+ +----------------+------------------------------------+-------------------+
+ |compression |{None, BZip, Fax, Group4, JPEG, |type of image |
+ | |LosslessJPEG, LZW, RLE, Zip, LZMA |compression |
+ | |JPEG2000, JBIG1, JBIG2} | |
+ +----------------+------------------------------------+-------------------+
+ | |{No, Configure, Annotate, Render, |log copious |
+ |debug |Transform, Locale, Coder, X11, |debugging |
+ | |Cache, Blob, Deprecate, User, |information for |
+ | |Resource, TemporaryFile, |one or more event |
+ | |Exception,All} |types |
+ +----------------+------------------------------------+-------------------+
+ | | |this many 1/100ths |
+ | | |of a second must |
+ |delay |integer |expire before |
+ | | |displaying the next|
+ | | |image in a sequence|
+ +----------------+------------------------------------+-------------------+
+ | | |vertical and |
+ |density |geometry |horizontal |
+ | | |resolution in |
+ | | |pixels of the image|
+ +----------------+------------------------------------+-------------------+
+ |disk-limit |integer |set disk resource |
+ | | |limit in megabytes |
+ +----------------+------------------------------------+-------------------+
+ |dispose |{Undefined, None, Background, |GIF disposal method|
+ | |Previous} | |
+ +----------------+------------------------------------+-------------------+
+ | | |apply error |
+ |dither |{True, False} |diffusion to the |
+ | | |image |
+ +----------------+------------------------------------+-------------------+
+ |display |string |specifies the X |
+ | | |server to contact |
+ +----------------+------------------------------------+-------------------+
+ |endian |{Undefined, LSB, MSB, Native} |specifies the |
+ | | |ordering of bytes |
+ | | |in a multi-byte |
+ | | |word. MSB is |
+ | | |big-endian, LSB is |
+ | | |little-endian, and |
+ | | |Native is whatever |
+ | | |the current host |
+ | | |uses by default. |
+ +----------------+------------------------------------+-------------------+
+ |file |filehandle |set the image |
+ | | |filehandle |
+ +----------------+------------------------------------+-------------------+
+ |filename |string |set the image |
+ | | |filename |
+ +----------------+------------------------------------+-------------------+
+ | | |The fill color |
+ |fill |color |paints any areas |
+ | | |inside the outline |
+ | | |of drawn shape. |
+ +----------------+------------------------------------+-------------------+
+ | | |use this font when |
+ |font |string |annotating the |
+ | | |image with text |
+ +----------------+------------------------------------+-------------------+
+ | | |colors within this |
+ |fuzz |integer |distance are |
+ | | |considered equal |
+ +----------------+------------------------------------+-------------------+
+ |gamma |double |gamma level of the |
+ | | |image |
+ +----------------+------------------------------------+-------------------+
+ | |{Forget, NorthWest, North, |type of image |
+ |Gravity |NorthEast, West, Center, East, |gravity |
+ | |SouthWest, South, SouthEast} | |
+ +----------------+------------------------------------+-------------------+
+ | | |chromaticity green |
+ |green-primary |x-value, y-value |primary point (e.g.|
+ | | |0.3, 0.6) |
+ +----------------+------------------------------------+-------------------+
+ |index[x, y] |string |colormap index at |
+ | | |position (x, y) |
+ +----------------+------------------------------------+-------------------+
+ |interlace |{None, Line, Plane, Partition} |the type of |
+ | | |interlacing scheme |
+ +----------------+------------------------------------+-------------------+
+ | | |add Netscape loop |
+ |iterations |integer |extension to your |
+ | | |GIF animation |
+ +----------------+------------------------------------+-------------------+
+ |label |string |Append to the image|
+ | | |label. |
+ +----------------+------------------------------------+-------------------+
+ | | |add Netscape loop |
+ |loop |integer |extension to your |
+ | | |GIF animation |
+ +----------------+------------------------------------+-------------------+
+ |magick |string |set the image |
+ | | |format |
+ +----------------+------------------------------------+-------------------+
+ |matte |{True, False} |True if the image |
+ | | |has transparency |
+ +----------------+------------------------------------+-------------------+
+ |mattecolor |color name |set the image matte|
+ | | |color |
+ +----------------+------------------------------------+-------------------+
+ |map-limit |integer |set map resource |
+ | | |limit in megabytes |
+ +----------------+------------------------------------+-------------------+
+ |memory-limit |integer |set memory resource|
+ | | |limit in megabytes |
+ +----------------+------------------------------------+-------------------+
+ |monochrome |{True, False} |transform the image|
+ | | |to black and white |
+ +----------------+------------------------------------+-------------------+
+ | |{ Letter, Tabloid, Ledger, Legal, |preferred size and |
+ |page |Statement, Executive, A3, A4, A5, |location of an |
+ | |B4, B5, Folio, Quarto, 10x14} or |image canvas |
+ | |geometry | |
+ +----------------+------------------------------------+-------------------+
+ | | |hex value (e.g. # |
+ |pixel[x, y] |string |ccc) at position (x|
+ | | |, y) |
+ +----------------+------------------------------------+-------------------+
+ | | |pointsize of the |
+ |pointsize |integer |Postscript or |
+ | | |TrueType font |
+ +----------------+------------------------------------+-------------------+
+ | |{ Rotate, Shear, Roll, Hue, | |
+ | |Saturation, Brightness, Gamma, | |
+ | |Spiff, Dull, Grayscale, Quantize, | |
+ | |Despeckle, ReduceNoise, AddNoise, |type of preview for|
+ |preview |Sharpen, Blur, Threshold, |the Preview image |
+ | |EdgeDetect, Spread, Solarize, Shade,|format |
+ | |Raise, Segment, Swirl, Implode, | |
+ | |Wave, OilPaint, Charcoal, | |
+ | |JPEG} | |
+ +----------------+------------------------------------+-------------------+
+ |quality |integer |JPEG/MIFF/PNG |
+ | | |compression level |
+ +----------------+------------------------------------+-------------------+
+ | | |chromaticity red |
+ |red-primary |x-value, y-value |primary point (e.g.|
+ | | |0.64, 0.33) |
+ +----------------+------------------------------------+-------------------+
+ |rendering-intent|{Undefined, Saturation, Perceptual, |the type of |
+ | |Absolute, Relative} |rendering intent |
+ +----------------+------------------------------------+-------------------+
+ | | |horizontal and |
+ |sampling-factor |geometry |vertical sampling |
+ | | |factor |
+ +----------------+------------------------------------+-------------------+
+ |scene |integer |image scene number |
+ +----------------+------------------------------------+-------------------+
+ |subimage |integer |subimage of an |
+ | | |image sequence |
+ +----------------+------------------------------------+-------------------+
+ | | |number of images |
+ |subrange |integer |relative to the |
+ | | |base image |
+ +----------------+------------------------------------+-------------------+
+ |server |string |specifies the X |
+ | | |server to contact |
+ +----------------+------------------------------------+-------------------+
+ |size |string |width and height of|
+ | | |a raw image |
+ +----------------+------------------------------------+-------------------+
+ | | |The stroke color |
+ |stroke |color |paints along the |
+ | | |outline of a shape.|
+ +----------------+------------------------------------+-------------------+
+ |tile |string |tile name |
+ +----------------+------------------------------------+-------------------+
+ | | |name of texture to |
+ |texture |string |tile onto the image|
+ | | |background |
+ +----------------+------------------------------------+-------------------+
+ | |{Bilevel, Grayscale, GrayscaleMatte,| |
+ |type |Palette, PaletteMatte, TrueColor, |image type |
+ | |TrueColorMatte, ColorSeparation, | |
+ | |ColorSeparationMatte, Optimize } | |
+ +----------------+------------------------------------+-------------------+
+ |units |{ Undefined, PixelsPerInch, |units of image |
+ | |PixelsPerCentimeters} |resolution |
+ +----------------+------------------------------------+-------------------+
+ | | |print detailed |
+ |verbose |{True, False} |information about |
+ | | |the image |
+ +----------------+------------------------------------+-------------------+
+ |virtual-pixel |{Constant, Edge, Mirror, Tile} |the virtual pixel |
+ | | |method |
+ +----------------+------------------------------------+-------------------+
+ | | |chromaticity white |
+ |white-point |x-value, y-value |point (e.g. 0.3127,|
+ | | |0.329) |
+ +----------------+------------------------------------+-------------------+
+
+Note, that the geometry parameter is a short cut for the width and height
+parameters (e.g. geometry=>'106x80' is equivalent to width=>106, height=>
+80).
+
+SetAttribute() is an alias for method Set().
+
+Most of the attributes listed above have an analog in gm convert. See the
+gm documentation for a more detailed description of these attributes.
+
+
+Get an Image Attribute
+======================
+
+Use method Get() to get an image attribute. For example,
+
+::
+
+ ($a, $b, $c) = $image->Get('colorspace', 'magick', 'adjoin');
+ $width = $image->[3]->Get('columns');
+
+In addition to all the attributes listed in Set an Image Attribute , you
+can get these additional attributes:
+
+.. table:: Image Attributes
+
+ +-------------+----------+------------------------------------------------+
+ | Attribute | Values | Description |
+ +-------------+----------+------------------------------------------------+
+ |base-columns |integer |base image width (before transformations) |
+ +-------------+----------+------------------------------------------------+
+ |base-filename|string |base image filename (before transformations) |
+ +-------------+----------+------------------------------------------------+
+ |base-rows |integer |base image height (before transformations) |
+ +-------------+----------+------------------------------------------------+
+ |class |{Direct, |image class |
+ | |Pseudo} | |
+ +-------------+----------+------------------------------------------------+
+ |colors |integer |number of unique colors in the image |
+ +-------------+----------+------------------------------------------------+
+ |comment |string |image comment |
+ +-------------+----------+------------------------------------------------+
+ |columns |integer |image width |
+ +-------------+----------+------------------------------------------------+
+ |depth |integer |image depth |
+ +-------------+----------+------------------------------------------------+
+ |directory |string |tile names from within an image montage |
+ +-------------+----------+------------------------------------------------+
+ |error |double |the mean error per pixel computed with methods |
+ | | |Compare() or Quantize() |
+ +-------------+----------+------------------------------------------------+
+ |filesize |integer |number of bytes of the image on disk |
+ +-------------+----------+------------------------------------------------+
+ |format |string |get the descriptive image format |
+ +-------------+----------+------------------------------------------------+
+ |geometry |string |image geometry |
+ +-------------+----------+------------------------------------------------+
+ |height |integer |the number of rows or height of an image |
+ +-------------+----------+------------------------------------------------+
+ |id |integer |GraphicsMagick registry id |
+ +-------------+----------+------------------------------------------------+
+ |label |string |image label |
+ +-------------+----------+------------------------------------------------+
+ |maximum-error|double |the normalized max error per pixel computed with|
+ | | |methods Compare() or Quantize() |
+ +-------------+----------+------------------------------------------------+
+ |mean-error |double |the normalized mean error per pixel computed |
+ | | |with methods Compare() or Quantize() |
+ +-------------+----------+------------------------------------------------+
+ |montage |geometry |tile size and offset within an image montage |
+ +-------------+----------+------------------------------------------------+
+ |rows |integer |the number of rows or height of an image |
+ +-------------+----------+------------------------------------------------+
+ |signature |string |SHA-256 message digest associated with the image|
+ | | |pixel stream |
+ +-------------+----------+------------------------------------------------+
+ |taint |{True, |True if the image has been modified |
+ | |False} | |
+ +-------------+----------+------------------------------------------------+
+ |width |integer |the number of columns or width of an image |
+ +-------------+----------+------------------------------------------------+
+ |x-resolution |integer |x resolution of the image |
+ +-------------+----------+------------------------------------------------+
+ |y-resolution |integer |y resolution of the image |
+ +-------------+----------+------------------------------------------------+
+
+GetAttribute() is an alias for method Get().
+
+Most of the attributes listed above have an analog in convert. See the
+documentation for a more detailed description of these attributes.
+
+
+Create an Image Montage
+=======================
+
+Use method Montage() to create a composite image by combining several
+separate images. The images are tiled on the composite image with the
+name of the image optionally appearing just below the individual tile.
+For example,
+
+::
+
+ $image->Montage(geometry=>'160x160', tile=>'2x2', texture=>'granite:');
+
+And here is a list of Montage() parameters you can set:
+
+.. table:: Montage Parameters
+
+ +-----------+-------------------------------------+-----------------------+
+ | Parameter | Values | Description |
+ +-----------+-------------------------------------+-----------------------+
+ |background |color name |background color name |
+ +-----------+-------------------------------------+-----------------------+
+ |borderwidth|integer |image border width |
+ +-----------+-------------------------------------+-----------------------+
+ | |{Over, In, Out, Atop, Xor, Plus, | |
+ |compose |Minus, Add, Subtract, Difference, |composite operator |
+ | |Bumpmap, Copy, Mask, Dissolve, Clear,| |
+ | |Displace} | |
+ +-----------+-------------------------------------+-----------------------+
+ |filename |string |name of montage image |
+ +-----------+-------------------------------------+-----------------------+
+ |fill |color name |fill color for |
+ | | |annotations |
+ +-----------+-------------------------------------+-----------------------+
+ |font |string |X11 font name |
+ +-----------+-------------------------------------+-----------------------+
+ |frame |geometry |surround the image with|
+ | | |an ornamental border |
+ +-----------+-------------------------------------+-----------------------+
+ | | |preferred tile and |
+ |geometry |geometry |border size of each |
+ | | |tile of the composite |
+ | | |image |
+ +-----------+-------------------------------------+-----------------------+
+ | |{NorthWest, North, NorthEast, West, |direction image |
+ |gravity |Center, East, SouthWest, South, |gravitates to within a |
+ | |SouthEast} |tile |
+ +-----------+-------------------------------------+-----------------------+
+ |ICM |blob |color information |
+ | | |profile |
+ +-----------+-------------------------------------+-----------------------+
+ |IPTC |blob |newswire information |
+ | | |profile |
+ +-----------+-------------------------------------+-----------------------+
+ |label |string |assign a label to an |
+ | | |image |
+ +-----------+-------------------------------------+-----------------------+
+ |mode |{Frame, Unframe, Concatenate} |thumbnail framing |
+ | | |options |
+ +-----------+-------------------------------------+-----------------------+
+ | | |pointsize of the |
+ |pointsize |integer |Postscript or TrueType |
+ | | |font |
+ +-----------+-------------------------------------+-----------------------+
+ |shadow |{True, False} |add a shadow beneath a |
+ | | |tile to simulate depth |
+ +-----------+-------------------------------------+-----------------------+
+ |stroke |color name |stroke color for |
+ | | |annotations |
+ +-----------+-------------------------------------+-----------------------+
+ | | |name of texture to tile|
+ |texture |string |onto the image |
+ | | |background |
+ +-----------+-------------------------------------+-----------------------+
+ |tile |geometry |number of tiles per row|
+ | | |and column |
+ +-----------+-------------------------------------+-----------------------+
+ |title |string |assign a title to the |
+ | | |image montage |
+ +-----------+-------------------------------------+-----------------------+
+ | | |make this color |
+ |transparent|string |transparent within the |
+ | | |image |
+ +-----------+-------------------------------------+-----------------------+
+
+Note, that the geometry parameter is a short cut for the width and height
+parameters (e.g. geometry=>'106x80' is equivalent to width=>106, height=>
+80).
+
+MontageImage() is an alias for method Montage().
+
+Most of the attributes listed above have an analog in montage. See the
+documentation for a more detailed description of these attributes.
+
+
+Working with Blobs
+==================
+
+A blob contains data that directly represent a particular image format in
+memory instead of on disk. PerlMagick supports blobs in any of these
+image formats and provides methods to convert a blob to or from a
+particular image format.
+
+.. table:: Blob Methods
+
+ +-----------+----------+------------------------+-------------------------+
+ | Method |Parameters| Return Value | Description |
+ +-----------+----------+------------------------+-------------------------+
+ | |any image |an array of image data |convert an image or image|
+ |ImageToBlob|attribute |in the respective image |sequence to an array of |
+ | | |format |blobs |
+ +-----------+----------+------------------------+-------------------------+
+ |BlobToImage|one or |the number of blobs |convert one or more blobs|
+ | |more blobs|converted to an image |to an image |
+ +-----------+----------+------------------------+-------------------------+
+
+ImageToBlob() returns the image data in their respective formats. You can
+then print it, save it to an ODBC database, write it to a file, or pipe
+it to a display program::
+
+ @blobs = $image->ImageToBlob();
+ open(DISPLAY,"| display -") || die;
+ binmode DISPLAY;
+ print DISPLAY $blobs[0];
+ close DISPLAY;
+
+Method BlobToImage() returns an image or image sequence converted from
+the supplied blob::
+
+ @blob=$db->GetImage();
+ $image=Graphics::Magick->new(magick=>'jpg');
+ $image->BlobToImage(@blob);
+
+Miscellaneous Methods
+=====================
+
+The Append() method append a set of images. For example,
+
+::
+
+ $p = $image->Append(stack=>{true,false});
+
+appends all the images associated with object $image. By default, images
+are stacked left-to-right. Set stack to True to stack them top-to-bottom.
+
+The Average() method averages a set of images. For example,
+
+::
+
+ $p = $image->Average();
+
+averages all the images associated with object $image.
+
+The Clone() method copies a set of images. For example,
+
+::
+
+ $p = $image->Clone();
+
+copies all the images from object $q to $p. You can use this method for
+single or multi-image sequences.
+
+The Morph() method morphs a set of images. Both the image pixels and size
+are linearly interpolated to give the appearance of a meta-morphosis from
+one image to the next::
+
+ $p = $image->Morph(frames=>integer);
+
+where frames is the number of in-between images to generate. The default
+is 1.
+
+Mosaic() creates an mosaic from an image sequence.
+
+Method Mogrify() is a single entry point for the image manipulation
+methods (Manipulate an Image). The parameters are the name of a method
+followed by any parameters the method may require. For example, these
+calls are equivalent::
+
+ $image->Crop('340x256+0+0');
+ $image->Mogrify('crop', '340x256+0+0');
+
+Method MogrifyRegion() applies a transform to a region of the image. It
+is similar to Mogrify() but begins with the region geometry. For example,
+suppose you want to brighten a 100x100 region of your image at location
+(40, 50)::
+
+ $image->MogrifyRegion('100x100+40+50', 'modulate', brightness=>50);
+
+Ping() is a convenience method that returns information about an image
+without having to read the image into memory. It returns the width,
+height, file size in bytes, and the file format of the image. You can
+specify more than one filename but only one filehandle::
+
+ ($width, $height, $size, $format) = $image->Ping('logo.png');
+ ($width, $height, $size, $format) = $image->Ping(file=>\*IMAGE);
+ ($width, $height, $size, $format) = $image->Ping(blob=>@blob);
+
+This is a more efficient and less memory intensive way to query if an
+image exists and what its characteristics are.
+
+To have full control over text positioning you need font metric
+information. Use
+
+::
+
+ ($x_ppem, $y_ppem, $ascender, $descender, $width, $height, $max_advance) =
+ $image->QueryFontMetrics(parameters);
+
+ Where parameters is any parameter of the Annotate method. The
+ 'text' parameter must be specified since there can be no default for
+ the text to render. The return values are
+
+ * character width
+ * character height
+ * ascender
+ * descender
+ * text width
+ * text height
+ * maximum horizontal advance
+
+Call QueryColor() with no parameters to return a list of known colors
+names or specify one or more color names to get these attributes: red,
+green, blue, and opacity value.
+
+::
+
+ @colors = $image->QueryColor();
+ ($red, $green, $blue, $opacity) = $image->QueryColor('cyan');
+ ($red, $green, $blue, $opacity) = $image->QueryColor('#716bae');
+
+QueryColorname() accepts a color value and returns its respective name or
+hex value;
+
+::
+
+ $name = $image->QueryColorname('rgba(80,60,0,0)');
+
+Call QueryFont() with no parameters to return a list of known fonts or
+specify one or more font names to get these attributes: font name,
+description, family, style, stretch, weight, encoding, foundry, format,
+metrics, and glyphs values.
+
+::
+
+ @fonts = $image->QueryFont();
+ $weight = ($image->QueryFont('Helvetica'))[5];
+
+Call QueryFormat() with no parameters to return a list of known image
+formats or specify one or more format names to get these attributes:
+adjoin, blob support, raw, decoder, encoder, description, and module.
+
+::
+
+ @formats = $image->QueryFormat();
+ ($adjoin, $blob_support, $raw, $decoder, $encoder, $description, $module) = $image->QueryFormat('gif');
+
+Use RemoteCommand() to send a command to an already running display or
+animate application. The only parameter is the name of the image file to
+display or animate.
+
+Finally, the Transform() method accepts a fully-qualified geometry
+specification for cropping or resizing one or more images. For example,
+
+::
+
+ $p = $image->Transform(crop=>'100x100');
+
+You can optionally add Image to any method name above. For example,
+PingImage() is an alias for method Ping().
+
+
+Handling Errors
+===============
+
+All PerlMagick methods return an undefined string context upon success. If
+any problems occur, the error is returned as a string with an embedded
+numeric status code. A status code less than 400 is a warning. This means
+that the operation did not complete but was recoverable to some degree. A
+numeric code greater or equal to 400 is an error and indicates the
+operation failed completely. Here is how errors are returned for the
+different methods:
+
+ + Methods which return a number (e.g. Read(), Write())::
+
+ $status = $image->Read(...);
+ warn "$status" if "$status"; # print the error message
+ $status =~ /(\d+)/;
+ print $1; # print the error number
+ print 0+$status; # print the number of images read
+
+ + Methods which operate on an image (e.g. Resize(), Crop())::
+
+ $status = $image->Crop(...);
+ warn "$status" if "$status"; # print the error message
+ $status =~ /(\d+)/;
+ print $1; # print the error number
+
+ + Methods which return images (Average(), Montage(), Clone()) should be
+ checked for errors this way::
+
+ $status = $image->Montage(...);
+ warn "$status" if !ref($status); # print the error message
+ $status =~ /(\d+)/;
+ print $1; # print the error number
+
+Here is an example error message::
+
+ Error 400: Memory allocation failed
+
+Below is a list of error and warning codes:
+
+.. table:: Error and Warning Codes
+
+ +----+----------------------+---------------------------------------------+
+ |Code| Mnemonic | Description |
+ +----+----------------------+---------------------------------------------+
+ |0 |Success |method completed without an error or warning |
+ +----+----------------------+---------------------------------------------+
+ |300 |ResourceLimitWarning |a program resource is exhausted (e.g. not |
+ | | |enough memory) |
+ +----+----------------------+---------------------------------------------+
+ |305 |TypeWarning |A font is unavailable; a substitution may |
+ | | |have occurred |
+ +----+----------------------+---------------------------------------------+
+ |310 |OptionWarning |a command-line option was malformed |
+ +----+----------------------+---------------------------------------------+
+ |315 |DelegateWarning |an GraphicsMagick delegate returned a warning|
+ +----+----------------------+---------------------------------------------+
+ |320 |MissingDelegateWarning|the image type can not be read or written |
+ | | |because the appropriate Delegate is missing |
+ +----+----------------------+---------------------------------------------+
+ |325 |CorruptImageWarning |the image file may be corrupt |
+ +----+----------------------+---------------------------------------------+
+ |330 |FileOpenWarning |the image file could not be opened |
+ +----+----------------------+---------------------------------------------+
+ |335 |BlobWarning |a binary large object could not be allocated |
+ +----+----------------------+---------------------------------------------+
+ |340 |StreamWarning |there was a problem reading or writing from a|
+ | | |stream |
+ +----+----------------------+---------------------------------------------+
+ |345 |CacheWarning |pixels could not be saved to the pixel cache |
+ +----+----------------------+---------------------------------------------+
+ |350 |CoderWarning |there was a problem with an image coder |
+ +----+----------------------+---------------------------------------------+
+ |355 |ModuleWarning |there was a problem with an image module |
+ +----+----------------------+---------------------------------------------+
+ |360 |DrawWarning |a drawing operation failed |
+ +----+----------------------+---------------------------------------------+
+ |365 |ImageWarning |the operation could not complete due to an |
+ | | |incompatible image |
+ +----+----------------------+---------------------------------------------+
+ |380 |XServerWarning |an X resource is unavailable |
+ +----+----------------------+---------------------------------------------+
+ |385 |MonitorWarning |there was a problem with prgress monitor |
+ +----+----------------------+---------------------------------------------+
+ |390 |RegistryWarning |there was a problem getting or setting the |
+ | | |registry |
+ +----+----------------------+---------------------------------------------+
+ |395 |ConfigureWarning |there was a problem getting a configuration |
+ | | |file |
+ +----+----------------------+---------------------------------------------+
+ |400 |ResourceLimitError |a program resource is exhausted (e.g. not |
+ | | |enough memory) |
+ +----+----------------------+---------------------------------------------+
+ |405 |TypeError |A font is unavailable; a substitution may |
+ | | |have occurred |
+ +----+----------------------+---------------------------------------------+
+ |410 |OptionError |a command-line option was malformed |
+ +----+----------------------+---------------------------------------------+
+ |415 |DelegateError |an GraphicsMagick delegate returned a warning|
+ +----+----------------------+---------------------------------------------+
+ |420 |MissingDelegateError |the image type can not be read or written |
+ | | |because the appropriate Delegate is missing |
+ +----+----------------------+---------------------------------------------+
+ |425 |CorruptImageError |the image file may be corrupt |
+ +----+----------------------+---------------------------------------------+
+ |430 |FileOpenError |the image file could not be opened |
+ +----+----------------------+---------------------------------------------+
+ |435 |BlobError |a binary large object could not be allocated |
+ +----+----------------------+---------------------------------------------+
+ |440 |StreamError |there was a problem reading or writing from a|
+ | | |stream |
+ +----+----------------------+---------------------------------------------+
+ |445 |CacheError |pixels could not be saved to the pixel cache |
+ +----+----------------------+---------------------------------------------+
+ |450 |CoderError |there was a problem with an image coder |
+ +----+----------------------+---------------------------------------------+
+ |455 |ModuleError |there was a problem with an image module |
+ +----+----------------------+---------------------------------------------+
+ |460 |DrawError |a drawing operation failed |
+ +----+----------------------+---------------------------------------------+
+ |465 |ImageError |the operation could not complete due to an |
+ | | |incompatible image |
+ +----+----------------------+---------------------------------------------+
+ |480 |XServerError |an X resource is unavailable |
+ +----+----------------------+---------------------------------------------+
+ |480 |MonitorError |there was a progress monitor error |
+ +----+----------------------+---------------------------------------------+
+ |490 |RegistryError |there was a problem getting or setting the |
+ | | |registry |
+ +----+----------------------+---------------------------------------------+
+ |495 |ConfigureError |there was a problem getting a configuration |
+ | | |file |
+ +----+----------------------+---------------------------------------------+
+
+The following illustrates how you can use a numeric status code::
+
+ $status = $image->Read('rose.png');
+ $status =~ /(\d+)/;
+ die "unable to continue" if ($1 == ResourceLimitError);
+
+
+-------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/process.html b/www/process.html
new file mode 100644
index 0000000..65a8b74
--- /dev/null
+++ b/www/process.html
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Development Process</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-development-process">
+<h1 class="title">GraphicsMagick Development Process</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>In order to ensure an orderly development process, and assure the highest
+quality releases, a development process has been established for
+GraphicsMagick.</p>
+<div class="section" id="phases-of-development">
+<h1>Phases of Development</h1>
+<p>Four major development phases have been identified. These are the
+feature development phase, snapshot phase, beta phase, and release
+phase. The phases used depend on the nature of preceding development.
+The Beta phase is usually skipped. The descriptions of these phases
+are as follows:</p>
+<div class="section" id="feature-development-phase">
+<h2>Feature Development Phase</h2>
+<blockquote>
+<p>The feature development phase is a time of rapid development and
+innovation. Work is normally done on Mercurial 'tip'. During the
+feature development phase, Mercurial is the only way to access the
+work in progress. Before updates are committed to Mercurial, they
+should be proven to compile on at least one architecture and pass
+the test suite ('make distcheck').</p>
+<p>Entry Criteria: There is a plan for feature development.</p>
+<p>Exit Criteria: Test suite passes on at least one machine.</p>
+</blockquote>
+</div>
+<div class="section" id="snapshot-phase">
+<h2>Snapshot Phase</h2>
+<blockquote>
+<p>The snapshot phase is entered when it is decided that the work is
+stable enough for non-developers to test. API and user interfaces
+should be stable before the snapshot phase begins in order to avoid
+confusion. Snapshot development is done on Mercurial 'tip'. Snapshot
+packages are identified by the date of the snapshot, and no Mercurial
+branching or tagging is performed to support the snapshot.</p>
+<p>Entry Criteria: Interfaces are stable, and code compiles and runs on
+multiple architectures.</p>
+<p>Exit Criteria: Code is release quality. The test suite must show
+100% completion for Q:8 and Q:16 quantum depths on at least three
+operating environments.</p>
+</blockquote>
+</div>
+<div class="section" id="beta-phase">
+<h2>Beta Phase</h2>
+<blockquote>
+<p>The Beta phase (usually only occuring at the beginning of a major
+release cycle) is entered when the work is feature complete, the
+package passes all tests, and it is considered time for versioned
+releases. As the first step of entering the beta phase, a release
+branch is created off of the trunk to support change sets for the
+release. The purpose of the beta phase is to wring out any remaining
+bugs prior to release. When a beta package is prepared, a release
+tag is applied to the associated release branch in Mercurial.</p>
+<p>Entry Criteria: Code is release quality.. The test suite must show
+100% completion for Q:8 and Q:16 quantum depths on at least three
+operating environments.</p>
+<p>Exit Criteria: The test suite must show 100% completion for Q:8, Q:16,
+and Q:32 quantum depths on at least three operating environments. The
+current beta package is determined to be sufficiently flawless for a
+final release.</p>
+</blockquote>
+</div>
+<div class="section" id="release-phase">
+<h2>Release Phase</h2>
+<blockquote>
+<p>The release phase is entered when the most recent Beta (or snapshot)
+is considered to be of acceptable quality for a release or bug-fixes
+have been prepared based on a previous release. At this time, a
+formal release tag is applied to the release branch, and release
+packages are created. Once a release tag has been applied to a
+release branch, that release branch is considered to be in release
+state and may only be used to prepare additional releases intended
+to correct bugs found in preceding releases. The initial release on
+a release branch has a two-digit (i.e. X.X) release
+designation. Bug-fix releases have a three-digit (i.e. X.X.X)
+release designation. A release designation may only be used once. If
+a problem is discovered with the release package, a new release
+number is assigned to support the corrected release package.</p>
+<p>Entry Criteria: The test suite must show 100% completion for Q:8, Q:16,
+and Q:32 quantum depths on at least three operating environments. The
+current beta package is determined to be sufficiently flawless for a
+final release.</p>
+<p>Exit Criteria: None</p>
+</blockquote>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/process.rst b/www/process.rst
new file mode 100644
index 0000000..7fcc20d
--- /dev/null
+++ b/www/process.rst
@@ -0,0 +1,102 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+==================================
+GraphicsMagick Development Process
+==================================
+
+In order to ensure an orderly development process, and assure the highest
+quality releases, a development process has been established for
+GraphicsMagick.
+
+Phases of Development
+---------------------
+
+Four major development phases have been identified. These are the
+feature development phase, snapshot phase, beta phase, and release
+phase. The phases used depend on the nature of preceding development.
+The Beta phase is usually skipped. The descriptions of these phases
+are as follows:
+
+Feature Development Phase
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ The feature development phase is a time of rapid development and
+ innovation. Work is normally done on Mercurial 'tip'. During the
+ feature development phase, Mercurial is the only way to access the
+ work in progress. Before updates are committed to Mercurial, they
+ should be proven to compile on at least one architecture and pass
+ the test suite ('make distcheck').
+
+ Entry Criteria: There is a plan for feature development.
+
+ Exit Criteria: Test suite passes on at least one machine.
+
+Snapshot Phase
+~~~~~~~~~~~~~~
+
+ The snapshot phase is entered when it is decided that the work is
+ stable enough for non-developers to test. API and user interfaces
+ should be stable before the snapshot phase begins in order to avoid
+ confusion. Snapshot development is done on Mercurial 'tip'. Snapshot
+ packages are identified by the date of the snapshot, and no Mercurial
+ branching or tagging is performed to support the snapshot.
+
+ Entry Criteria: Interfaces are stable, and code compiles and runs on
+ multiple architectures.
+
+ Exit Criteria: Code is release quality. The test suite must show
+ 100% completion for Q:8 and Q:16 quantum depths on at least three
+ operating environments.
+
+Beta Phase
+~~~~~~~~~~
+
+ The Beta phase (usually only occuring at the beginning of a major
+ release cycle) is entered when the work is feature complete, the
+ package passes all tests, and it is considered time for versioned
+ releases. As the first step of entering the beta phase, a release
+ branch is created off of the trunk to support change sets for the
+ release. The purpose of the beta phase is to wring out any remaining
+ bugs prior to release. When a beta package is prepared, a release
+ tag is applied to the associated release branch in Mercurial.
+
+ Entry Criteria: Code is release quality.. The test suite must show
+ 100% completion for Q:8 and Q:16 quantum depths on at least three
+ operating environments.
+
+ Exit Criteria: The test suite must show 100% completion for Q:8, Q:16,
+ and Q:32 quantum depths on at least three operating environments. The
+ current beta package is determined to be sufficiently flawless for a
+ final release.
+
+Release Phase
+~~~~~~~~~~~~~
+
+ The release phase is entered when the most recent Beta (or snapshot)
+ is considered to be of acceptable quality for a release or bug-fixes
+ have been prepared based on a previous release. At this time, a
+ formal release tag is applied to the release branch, and release
+ packages are created. Once a release tag has been applied to a
+ release branch, that release branch is considered to be in release
+ state and may only be used to prepare additional releases intended
+ to correct bugs found in preceding releases. The initial release on
+ a release branch has a two-digit (i.e. X.X) release
+ designation. Bug-fix releases have a three-digit (i.e. X.X.X)
+ release designation. A release designation may only be used once. If
+ a problem is discovered with the release package, a new release
+ number is assigned to support the corrected release package.
+
+ Entry Criteria: The test suite must show 100% completion for Q:8, Q:16,
+ and Q:32 quantum depths on at least three operating environments. The
+ current beta package is determined to be sufficiently flawless for a
+ final release.
+
+ Exit Criteria: None
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/programming.html b/www/programming.html
new file mode 100644
index 0000000..451eae5
--- /dev/null
+++ b/www/programming.html
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Programming Interfaces</title>
+<meta content="GraphicsMagick is a robust collection of tools and libraries to read, write, and manipulate an image in any of the more popular image formats including GIF, JPEG, PNG, PDF, and Photo CD. With GraphicsMagick you can create GIFs dynamically making it suitable for Web applications. You can also resize, rotate, sharpen, color reduce, or add special effects to an image and save your completed work in the same or differing image format. " name="description" />
+<meta content="GraphicsMagick, Image Magick, Image Magic, PerlMagick, Perl Magick, Perl Magic, image processing, software development, image, software, Magick++" name="keywords" />
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-programming-interfaces">
+<h1 class="title">GraphicsMagick Programming Interfaces</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>GraphicsMagick capabilities may be accessed from many languages and scripting
+environments via programming APIs as shown in the following table:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="23%" />
+<col width="77%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Language</th>
+<th class="head">Description</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td><a class="reference external" href="api/api.html">C Core</a></td>
+<td>C language API for the lowest-level core programming interface.</td>
+</tr>
+<tr><td><a class="reference external" href="wand/wand.html">C Wand</a></td>
+<td>C language API for the mid-level Wand API programming interface.</td>
+</tr>
+<tr><td><a class="reference external" href="Magick++/index.html">C++</a></td>
+<td>Magick++ provides an abstract object-oriented C++ interface.</td>
+</tr>
+<tr><td><a class="reference external" href="https://github.com/arcapos/luagraphicsmagick">Lua</a></td>
+<td>GraphicsMagick for Lua interfaces to GraphicsMagick's Wand API.</td>
+</tr>
+<tr><td><a class="reference external" href="http://aheckmann.github.com/gm/">node.js</a></td>
+<td>Graphicsmagick for node.js provides server-side support for
+Javascript programming with node.js.</td>
+</tr>
+<tr><td><a class="reference external" href="http://pecl.php.net/package/gmagick">PHP</a></td>
+<td>Gmagick provides a small and fast extension for PHP.</td>
+</tr>
+<tr><td><a class="reference external" href="perl.html">Perl</a></td>
+<td>PerlMagick provides an object-oriented Perl interface.</td>
+</tr>
+<tr><td><a class="reference external" href="https://github.com/hhatto/pgmagick">Python</a></td>
+<td>PgMagick provides the power and ease of the C++ API, but in Python.</td>
+</tr>
+<tr><td><a class="reference external" href="https://github.com/RedisLabsModules/graphicsmagick">Redis Module</a></td>
+<td>Image processing via redis APIs</td>
+</tr>
+<tr><td><a class="reference external" href="http://rmagick.rubyforge.org/">Ruby (RMagick)</a></td>
+<td>RMagick provides a native Ruby language extension</td>
+</tr>
+<tr><td><a class="reference external" href="https://github.com/minimagick/minimagick">Ruby (MiniMagick)</a></td>
+<td>MiniMagick provides a Ruby language extension via a command line
+wrapper.</td>
+</tr>
+<tr><td><a class="reference external" href="http://www.graphicsmagick.org/TclMagick/doc/">Tcl/Tk</a></td>
+<td>TclMagick provides a scripting environment based on Tcl or Tcl/Tk.</td>
+</tr>
+<tr><td><a class="reference external" href="https://graphicsmagick.codeplex.com/">Windows .NET</a></td>
+<td>GraphicsMagick.NET provides a Windows .NET programming interface,
+allowing use of GraphicsMagick features via a stand-alone package.</td>
+</tr>
+<tr><td><a class="reference external" href="ImageMagickObject.html">Windows OLE</a></td>
+<td>The ImageMagickObject OLE control supports utility-style access via
+a COM+ object.</td>
+</tr>
+</tbody>
+</table>
+<p><em>Some of these languages and scripting environments are supported by the
+GraphicsMagick Group while others are developed and supported by third parties.</em></p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/programming.rst b/www/programming.rst
new file mode 100644
index 0000000..e9fee7a
--- /dev/null
+++ b/www/programming.rst
@@ -0,0 +1,73 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=======================================
+GraphicsMagick Programming Interfaces
+=======================================
+
+.. meta::
+ :description: GraphicsMagick is a robust collection of tools and libraries to read,
+ write, and manipulate an image in any of the more popular
+ image formats including GIF, JPEG, PNG, PDF, and Photo CD.
+ With GraphicsMagick you can create GIFs dynamically making it
+ suitable for Web applications. You can also resize, rotate,
+ sharpen, color reduce, or add special effects to an image and
+ save your completed work in the same or differing image format.
+
+ :keywords: GraphicsMagick, Image Magick, Image Magic, PerlMagick, Perl Magick,
+ Perl Magic, image processing, software development, image, software,
+ Magick++
+
+
+.. _`C Core` : api/api.html
+.. _`C Wand` : wand/wand.html
+.. _C++ : Magick++/index.html
+.. _`node.js` : http://aheckmann.github.com/gm/
+.. _`Lua` : https://github.com/arcapos/luagraphicsmagick
+.. _PHP : http://pecl.php.net/package/gmagick
+.. _Perl : perl.html
+.. _Python: https://github.com/hhatto/pgmagick
+.. _`Redis Module` : https://github.com/RedisLabsModules/graphicsmagick
+.. _`Ruby (RMagick)` : http://rmagick.rubyforge.org/
+.. _`Ruby (MiniMagick)` : https://github.com/minimagick/minimagick
+.. _Tcl/Tk : http://www.graphicsmagick.org/TclMagick/doc/
+.. _Windows OLE : ImageMagickObject.html
+.. _`Windows .NET` : https://graphicsmagick.codeplex.com/
+
+
+
+GraphicsMagick capabilities may be accessed from many languages and scripting
+environments via programming APIs as shown in the following table:
+
+==================== ====================================================================
+Language Description
+==================== ====================================================================
+`C Core`_ C language API for the lowest-level core programming interface.
+`C Wand`_ C language API for the mid-level Wand API programming interface.
+`C++`_ Magick++ provides an abstract object-oriented C++ interface.
+`Lua`_ GraphicsMagick for Lua interfaces to GraphicsMagick's Wand API.
+`node.js`_ Graphicsmagick for node.js provides server-side support for
+ Javascript programming with node.js.
+PHP_ Gmagick provides a small and fast extension for PHP.
+Perl_ PerlMagick provides an object-oriented Perl interface.
+Python_ PgMagick provides the power and ease of the C++ API, but in Python.
+`Redis Module`_ Image processing via redis APIs
+`Ruby (RMagick)`_ RMagick provides a native Ruby language extension
+`Ruby (MiniMagick)`_ MiniMagick provides a Ruby language extension via a command line
+ wrapper.
+`Tcl/Tk`_ TclMagick provides a scripting environment based on Tcl or Tcl/Tk.
+`Windows .NET`_ GraphicsMagick.NET provides a Windows .NET programming interface,
+ allowing use of GraphicsMagick features via a stand-alone package.
+`Windows OLE`_ The ImageMagickObject OLE control supports utility-style access via
+ a COM+ object.
+==================== ====================================================================
+
+*Some of these languages and scripting environments are supported by the
+GraphicsMagick Group while others are developed and supported by third parties.*
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/project.html b/www/project.html
new file mode 100644
index 0000000..ae8f939
--- /dev/null
+++ b/www/project.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Project Information</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-project-information">
+<h1 class="title">GraphicsMagick Project Information</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p><a class="reference external" href="security.html">Security</a> - GraphicsMagick security (and how to report issues).</p>
+<p><a class="reference external" href="Changes.html">Change Logs</a> - Read the detailed change logs to see what changed.</p>
+<p><a class="reference external" href="Copyright.html">License</a> - Copyrights and usage terms for GraphicsMagick.</p>
+<p><a class="reference external" href="contribute.html">Contribute</a> - Contribute your work to the project.</p>
+<p><a class="reference external" href="https://sourceforge.net/p/graphicsmagick/_list/tickets">Bugs</a> - Report a bug.</p>
+<p><a class="reference external" href="process.html">Development Process</a> - Read about the project development process.</p>
+<p><a class="reference external" href="download.html">Download</a> - Download the source code or binaries.</p>
+<p><a class="reference external" href="FAQ.html">FAQ</a> - Answers for the questions asked the most often.</p>
+<p><a class="reference external" href="README.html">Install</a> - Read about how to install the software.</p>
+<p><a class="reference external" href="links.html">Links</a> - Some links we find useful.</p>
+<p><a class="reference external" href="https://sourceforge.net/p/graphicsmagick/mailman/">Mailing Lists</a> - Participate in discussions on our mailing lists.</p>
+<p><a class="reference external" href="mission.html">Mission</a> - Every project needs a mission statement.</p>
+<p><a class="reference external" href="NEWS.html">News</a> - Read the project news and release notes.</p>
+<p><a class="reference external" href="authors.html">Authors</a> - Read about those who provided source code or algorithms.</p>
+<p><a class="reference external" href="thanks.html">Thanks</a> - Read about those who helped in ways other than contributing code.</p>
+<p><a class="reference external" href="Hg.html">Source Control</a> - Source control is important. We now use Mercurial.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2012 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/project.rst b/www/project.rst
new file mode 100644
index 0000000..b5927c1
--- /dev/null
+++ b/www/project.rst
@@ -0,0 +1,62 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+==================================
+GraphicsMagick Project Information
+==================================
+
+.. _`Bugs` : https://sourceforge.net/p/graphicsmagick/_list/tickets
+.. _`Change Logs` : Changes.html
+.. _`Contribute` : contribute.html
+.. _`Development Process` : process.html
+.. _`Download` : download.html
+.. _`FAQ` : FAQ.html
+.. _`Install` : README.html
+.. _`License` : Copyright.html
+.. _`Links` : links.html
+.. _`Mailing Lists` : https://sourceforge.net/p/graphicsmagick/mailman/
+.. _`Mission` : mission.html
+.. _`News` : NEWS.html
+.. _`Source Control` : Hg.html
+.. _`Security` : security.html
+.. _`Authors` : authors.html
+.. _`Thanks` : thanks.html
+
+`Security`_ - GraphicsMagick security (and how to report issues).
+
+`Change Logs`_ - Read the detailed change logs to see what changed.
+
+`License`_ - Copyrights and usage terms for GraphicsMagick.
+
+`Contribute`_ - Contribute your work to the project.
+
+`Bugs`_ - Report a bug.
+
+`Development Process`_ - Read about the project development process.
+
+`Download`_ - Download the source code or binaries.
+
+`FAQ`_ - Answers for the questions asked the most often.
+
+`Install`_ - Read about how to install the software.
+
+`Links`_ - Some links we find useful.
+
+`Mailing Lists`_ - Participate in discussions on our mailing lists.
+
+`Mission`_ - Every project needs a mission statement.
+
+`News`_ - Read the project news and release notes.
+
+`Authors`_ - Read about those who provided source code or algorithms.
+
+`Thanks`_ - Read about those who helped in ways other than contributing code.
+
+`Source Control`_ - Source control is important. We now use Mercurial.
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2012 - 2017
diff --git a/www/quantize.html b/www/quantize.html
new file mode 100644
index 0000000..5d4eca4
--- /dev/null
+++ b/www/quantize.html
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Color Quantization</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-color-quantization">
+<h1 class="title">GraphicsMagick Color Quantization</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<blockquote>
+This document describes how GraphicsMagick performs color
+reduction on an image. To fully understand this document,
+you should have a knowledge of basic imaging techniques and
+the tree data structure and terminology.</blockquote>
+<div class="section" id="description">
+<h1>Description</h1>
+<p>For purposes of color allocation, an image is a set of n pixels, where
+each pixel is a point in RGB space. RGB space is a 3-dimensional vector
+space, and each pixel, p(i), is defined by an ordered triple of red,
+green, and blue coordinates, (r(i),g(i),b(i)).</p>
+<p>Each primary color component (red, green, or blue) represents an
+intensity which varies linearly from 0 to a maximum value, Cmax, which
+corresponds to full saturation of that color. Color allocation is defined
+over a domain consisting of the cube in RGB space with opposite vertices
+at (0,0,0) and (Cmax ,Cmax,Cmax). GraphicsMagick requires Cmax= 255.</p>
+<p>The algorithm maps this domain onto a tree in which each node represents
+a cube within that domain. In the following discussion, these cubes are
+defined by the coordinate of two opposite vertices: The vertex nearest
+the origin in RGB space and the vertex farthest from the origin.</p>
+<p>The tree's root node represents the the entire domain, (0,0,0) through
+(Cmax, Cmax,Cmax). Each lower level in the tree is generated by
+subdividing one node's cube into eight smaller cubes of equal size. This
+corresponds to bisecting the parent cube with planes passing through the
+midpoints of each edge.</p>
+<p>The basic algorithm operates in three phases:</p>
+<blockquote>
+<ul class="simple">
+<li>Classification,</li>
+<li>Reduction, and</li>
+<li>Assignment.</li>
+</ul>
+</blockquote>
+<p>Classification builds a color description tree for the image. Reduction
+collapses the tree until the number it represents, at most, is the number
+of colors desired in the output image. Assignment defines the output
+image's color map and sets each pixel's color by reclassification in the
+reduced tree. Our goal is to minimize the numerical discrepancies between
+the original colors and quantized colors. To learn more about
+quantization error, see Measuring Color Reduction Error later in this
+document.</p>
+<p>Classification begins by initializing a color description tree of
+sufficient depth to represent each possible input color in a leaf.
+However, it is impractical to generate a fully-formed color description
+tree in the classification phase for realistic values of Cmax. If color
+components in the input image are quantized to k-bit precision, so that
+Cmax = 2^k-1, the tree would need k levels below the root node to allow
+representing each possible input color in a leaf. This becomes
+prohibitive because the tree's:</p>
+<pre class="literal-block">
+total number of nodes = 1+Sum(8^i), i=1,k
+
+For k=8,
+Number of nodes= 1 + (8^1+8^2+....+8^8)
+8^8 - 1
+= 1 + 8.-----------
+8 - 1
+= 19,173,961
+</pre>
+<p>Therefore, to avoid building a fully populated tree, GraphicsMagick:</p>
+<ol class="arabic simple">
+<li>Initializes data structures for nodes only as they are needed;</li>
+<li>Chooses a maximum depth for the tree as a function of the desired
+number of colors in the output image (currently based-two logarithm
+of Cmax).</li>
+</ol>
+<p>For Cmax=255,</p>
+<pre class="literal-block">
+Maximum tree depth = log (256)
+2
+
+= log (256) / log (2)
+e e
+
+= 8
+</pre>
+<p>A tree of this depth generally allows the best representation of the
+source image with the fastest computational speed and the least amount of
+memory. However, the default depth is inappropriate for some images.
+Therefore, the caller can request a specific tree depth.</p>
+<p>For each pixel in the input image, classification scans downward from the
+root of the color description tree. At each level of the tree, it
+identifies the single node which represents a cube in RGB space
+containing the pixel's color. It updates the following data for each such
+node:</p>
+<blockquote>
+<dl class="docutils">
+<dt>n1:</dt>
+<dd>Number of pixels whose color is contained in the RGB cube which
+this node represents;</dd>
+<dt>n2:</dt>
+<dd>Number of pixels whose color is not represented in a node at lower
+depth in the tree; initially, n2=0 for all nodes except leaves of
+the tree.</dd>
+<dt>Sr,Sg,Sb:</dt>
+<dd>Sums of the red, green, and blue component values for all pixels
+not classified at a lower depth. The combination of these sums and
+n2 will ultimately characterize the mean color of a set of pixels
+represented by this node.</dd>
+<dt>E:</dt>
+<dd>The distance squared in RGB space between each pixel contained
+within a node and the nodes' center. This represents the
+quantization error for a node.</dd>
+</dl>
+</blockquote>
+<p>Reduction repeatedly prunes the tree until the number of nodes with n2 &gt;
+0 is less than or equal to the maximum number of colors allowed in the
+output image. On any given iteration over the tree, it selects those
+nodes whose E value is minimal for pruning and merges their color
+statistics upward. It uses a pruning threshold, Ep, to govern node
+selection as follows:</p>
+<pre class="literal-block">
+Ep = 0
+while number of nodes with (n2 &gt; 0) &gt; required maximum number of colors
+prune all nodes such that E &lt;= Ep
+Set Ep to minimum E in remaining nodes
+</pre>
+<p>This has the effect of minimizing any quantization error when merging two
+nodes together.</p>
+<p>When a node to be pruned has offspring, the pruning procedure invokes
+itself recursively in order to prune the tree from the leaves upward. The
+values of n2 ,Sr, Sg and Sb in a node being pruned are always added to
+the corresponding data in that node's parent. This retains the pruned
+node's color characteristics for later averaging.</p>
+<p>For each node, n2 pixels exist for which that node represents the
+smallest volume in RGB space containing those pixel's colors. When n2 &gt; 0
+the node will uniquely define a color in the output image. At the
+beginning of reduction, n2 = 0 for all nodes except the leaves of the
+tree which represent colors present in the input image.</p>
+<p>The other pixel count, n1, indicates the total number of colors within
+the cubic volume which the node represents. This includes n1 - n2 pixels
+whose colors should be defined by nodes at a lower level in the tree.</p>
+<p>Assignment generates the output image from the pruned tree. The output
+image consists of two parts:</p>
+<ol class="arabic simple">
+<li>A color map, which is an array of color descriptions (RGB triples)
+for each color present in the output image.</li>
+<li>A pixel array, which represents each pixel as an index into the
+color map array.</li>
+</ol>
+<p>First, the assignment phase makes one pass over the pruned color
+description tree to establish the image's color map. For each node with
+n2 &gt; 0, it divides Sr, Sg, and Sb by n2. This produces the mean color of
+all pixels that classify no lower than this node. Each of these colors
+becomes an entry in the color map.</p>
+<p>Finally, the assignment phase reclassifies each pixel in the pruned tree
+to identify the deepest node containing the pixel's color. The pixel's
+value in the pixel array becomes the index of this node's mean color in
+the color map.</p>
+<p>Empirical evidence suggests that the distances in color spaces such as
+YUV, or YIQ correspond to perceptual color differences more closely than
+do distances in RGB space. These color spaces may give better results
+when color reducing an image. Here the algorithm is as described except
+each pixel is a point in the alternate color space. For convenience, the
+color components are normalized to the range 0 to a maximum value, Cmax.
+The color reduction can then proceed as described.</p>
+</div>
+<div class="section" id="measuring-color-reduction-error">
+<h1>Measuring Color Reduction Error</h1>
+<p>Depending on the image, the color reduction error may be obvious or
+invisible. Images with high spatial frequencies (such as hair or grass)
+will show error much less than pictures with large smoothly shaded areas
+(such as faces). This is because the high-frequency contour edges
+introduced by the color reduction process are masked by the high
+frequencies in the image.</p>
+<p>To measure the difference between the original and color reduced images
+(the total color reduction error), GraphicsMagick sums over all pixels in
+an image the distance squared in RGB space between each original pixel
+value and its color reduced value. GraphicsMagick prints several error
+measurements including the mean error per pixel, the normalized mean
+error, and the normalized maximum error.</p>
+<p>The normalized error measurement can be used to compare images. In
+general, the closer the mean error is to zero the more the quantized
+image resembles the source image. Ideally, the error should be
+perceptually-based, since the human eye is the final judge of
+quantization quality.</p>
+<p>These errors are measured and printed when -verbose and -colorsare
+specified on the command line:</p>
+<blockquote>
+<dl class="docutils">
+<dt>mean error per pixel:</dt>
+<dd>is the mean error for any single pixel in the image.</dd>
+<dt>normalized mean square error:</dt>
+<dd>is the normalized mean square quantization error for any single
+pixel in the image.
+This distance measure is normalized to a range between 0 and 1. It
+is independent of the range of red, green, and blue values in the
+image.</dd>
+<dt>normalized maximum square error:</dt>
+<dd>is the largest normalized square quantization error for any single
+pixel in the image.
+This distance measure is normalized to a range between and blue
+values in the image.</dd>
+</dl>
+</blockquote>
+</div>
+<div class="section" id="authors">
+<h1>Authors</h1>
+<p>John Cristy, <a class="reference external" href="mailto:magick&#37;&#52;&#48;imagemagick&#46;org">magick<span>&#64;</span>imagemagick<span>&#46;</span>org</a>, ImageMagick Studio.</p>
+</div>
+<div class="section" id="acknowledgements">
+<h1>Acknowledgements</h1>
+<p>Paul Raveling, USC Information Sciences Institute, for the original idea
+of using space subdivision for the color reduction algorithm. With Paul's
+permission, this document is an adaptation from a document he wrote.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/quantize.rst b/www/quantize.rst
new file mode 100644
index 0000000..2eaf44f
--- /dev/null
+++ b/www/quantize.rst
@@ -0,0 +1,244 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=================================
+GraphicsMagick Color Quantization
+=================================
+
+ This document describes how GraphicsMagick performs color
+ reduction on an image. To fully understand this document,
+ you should have a knowledge of basic imaging techniques and
+ the tree data structure and terminology.
+
+Description
+===========
+
+For purposes of color allocation, an image is a set of n pixels, where
+each pixel is a point in RGB space. RGB space is a 3-dimensional vector
+space, and each pixel, p(i), is defined by an ordered triple of red,
+green, and blue coordinates, (r(i),g(i),b(i)).
+
+Each primary color component (red, green, or blue) represents an
+intensity which varies linearly from 0 to a maximum value, Cmax, which
+corresponds to full saturation of that color. Color allocation is defined
+over a domain consisting of the cube in RGB space with opposite vertices
+at (0,0,0) and (Cmax ,Cmax,Cmax). GraphicsMagick requires Cmax= 255.
+
+The algorithm maps this domain onto a tree in which each node represents
+a cube within that domain. In the following discussion, these cubes are
+defined by the coordinate of two opposite vertices: The vertex nearest
+the origin in RGB space and the vertex farthest from the origin.
+
+The tree's root node represents the the entire domain, (0,0,0) through
+(Cmax, Cmax,Cmax). Each lower level in the tree is generated by
+subdividing one node's cube into eight smaller cubes of equal size. This
+corresponds to bisecting the parent cube with planes passing through the
+midpoints of each edge.
+
+The basic algorithm operates in three phases:
+
+ * Classification,
+
+ * Reduction, and
+
+ * Assignment.
+
+Classification builds a color description tree for the image. Reduction
+collapses the tree until the number it represents, at most, is the number
+of colors desired in the output image. Assignment defines the output
+image's color map and sets each pixel's color by reclassification in the
+reduced tree. Our goal is to minimize the numerical discrepancies between
+the original colors and quantized colors. To learn more about
+quantization error, see Measuring Color Reduction Error later in this
+document.
+
+Classification begins by initializing a color description tree of
+sufficient depth to represent each possible input color in a leaf.
+However, it is impractical to generate a fully-formed color description
+tree in the classification phase for realistic values of Cmax. If color
+components in the input image are quantized to k-bit precision, so that
+Cmax = 2^k-1, the tree would need k levels below the root node to allow
+representing each possible input color in a leaf. This becomes
+prohibitive because the tree's::
+
+ total number of nodes = 1+Sum(8^i), i=1,k
+
+ For k=8,
+ Number of nodes= 1 + (8^1+8^2+....+8^8)
+ 8^8 - 1
+ = 1 + 8.-----------
+ 8 - 1
+ = 19,173,961
+
+Therefore, to avoid building a fully populated tree, GraphicsMagick:
+
+1. Initializes data structures for nodes only as they are needed;
+
+2. Chooses a maximum depth for the tree as a function of the desired
+ number of colors in the output image (currently based-two logarithm
+ of Cmax).
+
+For Cmax=255,
+
+::
+
+ Maximum tree depth = log (256)
+ 2
+
+ = log (256) / log (2)
+ e e
+
+ = 8
+
+A tree of this depth generally allows the best representation of the
+source image with the fastest computational speed and the least amount of
+memory. However, the default depth is inappropriate for some images.
+Therefore, the caller can request a specific tree depth.
+
+For each pixel in the input image, classification scans downward from the
+root of the color description tree. At each level of the tree, it
+identifies the single node which represents a cube in RGB space
+containing the pixel's color. It updates the following data for each such
+node:
+
+ n1:
+ Number of pixels whose color is contained in the RGB cube which
+ this node represents;
+
+ n2:
+ Number of pixels whose color is not represented in a node at lower
+ depth in the tree; initially, n2=0 for all nodes except leaves of
+ the tree.
+
+ Sr,Sg,Sb:
+ Sums of the red, green, and blue component values for all pixels
+ not classified at a lower depth. The combination of these sums and
+ n2 will ultimately characterize the mean color of a set of pixels
+ represented by this node.
+
+ E:
+ The distance squared in RGB space between each pixel contained
+ within a node and the nodes' center. This represents the
+ quantization error for a node.
+
+Reduction repeatedly prunes the tree until the number of nodes with n2 >
+0 is less than or equal to the maximum number of colors allowed in the
+output image. On any given iteration over the tree, it selects those
+nodes whose E value is minimal for pruning and merges their color
+statistics upward. It uses a pruning threshold, Ep, to govern node
+selection as follows::
+
+ Ep = 0
+ while number of nodes with (n2 > 0) > required maximum number of colors
+ prune all nodes such that E <= Ep
+ Set Ep to minimum E in remaining nodes
+
+This has the effect of minimizing any quantization error when merging two
+nodes together.
+
+When a node to be pruned has offspring, the pruning procedure invokes
+itself recursively in order to prune the tree from the leaves upward. The
+values of n2 ,Sr, Sg and Sb in a node being pruned are always added to
+the corresponding data in that node's parent. This retains the pruned
+node's color characteristics for later averaging.
+
+For each node, n2 pixels exist for which that node represents the
+smallest volume in RGB space containing those pixel's colors. When n2 > 0
+the node will uniquely define a color in the output image. At the
+beginning of reduction, n2 = 0 for all nodes except the leaves of the
+tree which represent colors present in the input image.
+
+The other pixel count, n1, indicates the total number of colors within
+the cubic volume which the node represents. This includes n1 - n2 pixels
+whose colors should be defined by nodes at a lower level in the tree.
+
+Assignment generates the output image from the pruned tree. The output
+image consists of two parts:
+
+1. A color map, which is an array of color descriptions (RGB triples)
+ for each color present in the output image.
+
+2. A pixel array, which represents each pixel as an index into the
+ color map array.
+
+First, the assignment phase makes one pass over the pruned color
+description tree to establish the image's color map. For each node with
+n2 > 0, it divides Sr, Sg, and Sb by n2. This produces the mean color of
+all pixels that classify no lower than this node. Each of these colors
+becomes an entry in the color map.
+
+Finally, the assignment phase reclassifies each pixel in the pruned tree
+to identify the deepest node containing the pixel's color. The pixel's
+value in the pixel array becomes the index of this node's mean color in
+the color map.
+
+Empirical evidence suggests that the distances in color spaces such as
+YUV, or YIQ correspond to perceptual color differences more closely than
+do distances in RGB space. These color spaces may give better results
+when color reducing an image. Here the algorithm is as described except
+each pixel is a point in the alternate color space. For convenience, the
+color components are normalized to the range 0 to a maximum value, Cmax.
+The color reduction can then proceed as described.
+
+
+Measuring Color Reduction Error
+===============================
+
+Depending on the image, the color reduction error may be obvious or
+invisible. Images with high spatial frequencies (such as hair or grass)
+will show error much less than pictures with large smoothly shaded areas
+(such as faces). This is because the high-frequency contour edges
+introduced by the color reduction process are masked by the high
+frequencies in the image.
+
+To measure the difference between the original and color reduced images
+(the total color reduction error), GraphicsMagick sums over all pixels in
+an image the distance squared in RGB space between each original pixel
+value and its color reduced value. GraphicsMagick prints several error
+measurements including the mean error per pixel, the normalized mean
+error, and the normalized maximum error.
+
+The normalized error measurement can be used to compare images. In
+general, the closer the mean error is to zero the more the quantized
+image resembles the source image. Ideally, the error should be
+perceptually-based, since the human eye is the final judge of
+quantization quality.
+
+These errors are measured and printed when -verbose and -colorsare
+specified on the command line:
+
+ mean error per pixel:
+ is the mean error for any single pixel in the image.
+
+ normalized mean square error:
+ is the normalized mean square quantization error for any single
+ pixel in the image.
+ This distance measure is normalized to a range between 0 and 1. It
+ is independent of the range of red, green, and blue values in the
+ image.
+
+ normalized maximum square error:
+ is the largest normalized square quantization error for any single
+ pixel in the image.
+ This distance measure is normalized to a range between and blue
+ values in the image.
+
+Authors
+=======
+
+John Cristy, magick@imagemagick.org, ImageMagick Studio.
+
+Acknowledgements
+================
+
+Paul Raveling, USC Information Sciences Institute, for the original idea
+of using space subdivision for the color reduction algorithm. With Paul's
+permission, this document is an adaptation from a document he wrote.
+
+-------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
+
diff --git a/www/reference.html b/www/reference.html
new file mode 100644
index 0000000..3476a39
--- /dev/null
+++ b/www/reference.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Reference Information</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-reference-information">
+<h1 class="title">GraphicsMagick Reference Information</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p><a class="reference external" href="color.html">Colors</a> - Reference of colors known by GraphicsMagick.</p>
+<p><a class="reference external" href="FAQ.html">FAQ</a> - Answers for the questions asked the most often.</p>
+<p><a class="reference external" href="formats.html">Formats</a> - File formats supported by GraphicsMagick.</p>
+<p><a class="reference external" href="miff.html">MIFF</a> - Magick Image File Format.</p>
+<p><a class="reference external" href="links.html">Links</a> - Some links we find useful.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2012 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/reference.rst b/www/reference.rst
new file mode 100644
index 0000000..47abe8c
--- /dev/null
+++ b/www/reference.rst
@@ -0,0 +1,29 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+====================================
+GraphicsMagick Reference Information
+====================================
+
+.. _`FAQ` : FAQ.html
+.. _Formats : formats.html
+.. _MIFF : miff.html
+.. _Links : links.html
+.. _`Colors` : color.html
+
+`Colors`_ - Reference of colors known by GraphicsMagick.
+
+`FAQ`_ - Answers for the questions asked the most often.
+
+Formats_ - File formats supported by GraphicsMagick.
+
+MIFF_ - Magick Image File Format.
+
+Links_ - Some links we find useful.
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2012 - 2017
diff --git a/www/security.html b/www/security.html
new file mode 100644
index 0000000..c54024a
--- /dev/null
+++ b/www/security.html
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Security</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-security">
+<h1 class="title">GraphicsMagick Security</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="section" id="background">
+<h1>Background</h1>
+<p>Although GraphicsMagick is image processing software, security is a
+very important consideration for GraphicsMagick. GraphicsMagick may
+be used to open files and URLs produced by an untrusted party. Given
+a suitable weakness (which we make every effort to prevent), an
+intentionally constructed file might be able to cause the software to
+crash, leak memory, request huge amounts memory, run forever, or in
+the worst case execute arbitrary code, including shell code.
+GraphicsMagick is very powerful and complex software supporting many
+capabilities and so untrusted parties should never be allowed to
+submit arbitrary requests into it.</p>
+<p>GraphicsMagick includes the ability to access arbitrary http and ftp
+URLs as well as local image, font, and SVG files. The SVG renderer
+supports read access to http and ftp URLs as well as local files
+according to the SVG specification. Since URLs and local file paths
+may be included in SVG files, untrusted SVG files may create a Server
+Side Request Forgery (<a class="reference external" href="https://cwe.mitre.org/data/definitions/918.html">SSRF</a>) vulnerability since URL requests are
+done by the computer executing the SVG, which may be in a realm of
+trust (e.g. inside the firewall and able to access &quot;localhost&quot;
+addresses).</p>
+<p>The GraphicsMagick project is continually striving to eliminate
+conditions in the software which might pose a risk for its users while
+not constraining what its users may do with the software.</p>
+</div>
+<div class="section" id="reporting-issues">
+<h1>Reporting Issues</h1>
+<p>If you become aware of a serious security issue with GraphicsMagick,
+then it may be addressed by email directly to the GraphicsMagick
+maintainers or to the <a class="reference external" href="mailto:graphicsmagick-security&#37;&#52;&#48;graphicsmagick&#46;org">GraphicsMagick Security</a> mail address. More
+minor issues are best addressed via the <a class="reference external" href="https://sourceforge.net/p/graphicsmagick/bugs/">GraphicsMagick Bug Tracker</a>
+at SourceForge.</p>
+<p>Reporting an issue will allow us to fix it so that future releases of
+the software won't suffer from the problem.</p>
+</div>
+<div class="section" id="safe-use-of-the-software">
+<h1>Safe Use Of The Software</h1>
+<p>You are the first line of defense when it comes to GraphicsMagick
+security!</p>
+<p>If you are operating a server which supports file uploads from
+untrusted users, or delivered via a network protocol such as http,
+ftp, or email, then you should take steps to assure that a problem
+with opening/processing the file does not place the whole server at
+risk. These are steps which can be taken:</p>
+<ol class="arabic">
+<li><p class="first">Subscribe to the <a class="reference external" href="https://lists.sourceforge.net/lists/listinfo/graphicsmagick-announce">graphicsmagick-announce</a> mailing list so that
+you are informed about new GraphicsMagick releases or special
+security bulletins.</p>
+</li>
+<li><p class="first">Make sure that GraphicsMagick is up to date as reported on the
+GraphicsMagick web site. Don't simply trust that packages from
+your operating system vendor are kept up to date or are updated to
+include security fixes. Keeping GraphicsMagick up to date might
+require that you compile GraphicsMagick yourself from source code.</p>
+</li>
+<li><p class="first">Execute the software in a <a class="reference external" href="https://en.wikipedia.org/wiki/Operating-system-level_virtualization">Container</a>, <a class="reference external" href="https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/jails.html">FreeBSD Jail</a>, <a class="reference external" href="https://illumos.org/man/5/zones">Solaris
+Zone</a>, or <a class="reference external" href="https://en.wikipedia.org/wiki/Chroot">chrooted</a> environment such that it can not cause harm
+to the system running it.</p>
+</li>
+<li><p class="first">Execute the software as a least-privileged user (e.g. 'nobody').</p>
+</li>
+<li><p class="first">Normalize input file names or any other external inputs so that
+they are under your control and not controlled by an untrusted
+party. This should include any file name specifications, which may
+include arbitrary 'glob' patterns (wildcards), requiring hours or
+days to complete if sufficiently close long file names exist.</p>
+</li>
+<li><p class="first">Enforce that uploaded files are passed to the expected reader. For
+example, the uploaded file &quot;file.jpg&quot; is forced to be read by the
+JPEG reader (rather than a reader selected based on header magic
+testing) by using the file name &quot;jpg:file.jpg&quot;. If the file is not
+really what was indicated, then an error is reported.</p>
+<p>GraphicsMagick supports a great many file types and auto-detects
+many file types based on their content rather than file extension.
+The file which pretends to be an ordinary PNG or JPEG file might be
+something else entirely. Note that even using independent file
+header testing may not be sufficient since it is possible to
+construct valid files with a header which appears to be several
+different types, but the first type which matches while testing the
+header will be selected.</p>
+</li>
+<li><p class="first">Apply resource limits via the <cite>-limit</cite> option or the
+<cite>MAGICK_LIMIT_*</cite> environment variables (e.g. <cite>export
+MAGICK_LIMIT_PIXELS=30Mp</cite>, <cite>export MAGICK_LIMIT_MEMORY=500Mb</cite>).
+Also consider setting resource limits using the <cite>ulimit</cite> command.</p>
+</li>
+<li><p class="first">Consider using the <cite>MAGICK_CODER_STABILITY</cite> environment variable to
+constrain the supported file formats to the subsets selected by
+<cite>PRIMARY</cite> or <cite>STABLE</cite>. After setting this environment variable
+(e.g. <cite>export MAGICK_CODER_STABILITY=PRIMARY</cite>), use <cite>gm
+convert -list format</cite> and verify that the format support you need
+is enabled. Selecting the <cite>PRIMARY</cite> or <cite>STABLE</cite> options blocks
+access of http and ftp URLs (<a class="reference external" href="https://cwe.mitre.org/data/definitions/918.html">SSRF</a> vulnerability), but does not
+block SVG renderer access to read local image files.</p>
+</li>
+</ol>
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/security.rst b/www/security.rst
new file mode 100644
index 0000000..7d5bed3
--- /dev/null
+++ b/www/security.rst
@@ -0,0 +1,128 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=======================
+GraphicsMagick Security
+=======================
+
+Background
+----------
+
+.. _`SSRF` : https://cwe.mitre.org/data/definitions/918.html
+
+Although GraphicsMagick is image processing software, security is a
+very important consideration for GraphicsMagick. GraphicsMagick may
+be used to open files and URLs produced by an untrusted party. Given
+a suitable weakness (which we make every effort to prevent), an
+intentionally constructed file might be able to cause the software to
+crash, leak memory, request huge amounts memory, run forever, or in
+the worst case execute arbitrary code, including shell code.
+GraphicsMagick is very powerful and complex software supporting many
+capabilities and so untrusted parties should never be allowed to
+submit arbitrary requests into it.
+
+GraphicsMagick includes the ability to access arbitrary http and ftp
+URLs as well as local image, font, and SVG files. The SVG renderer
+supports read access to http and ftp URLs as well as local files
+according to the SVG specification. Since URLs and local file paths
+may be included in SVG files, untrusted SVG files may create a Server
+Side Request Forgery (`SSRF`_) vulnerability since URL requests are
+done by the computer executing the SVG, which may be in a realm of
+trust (e.g. inside the firewall and able to access "localhost"
+addresses).
+
+The GraphicsMagick project is continually striving to eliminate
+conditions in the software which might pose a risk for its users while
+not constraining what its users may do with the software.
+
+Reporting Issues
+----------------
+
+.. _`GraphicsMagick Security`: mailto:graphicsmagick-security@graphicsmagick.org
+
+.. _`GraphicsMagick Bug Tracker`: https://sourceforge.net/p/graphicsmagick/bugs/
+
+If you become aware of a serious security issue with GraphicsMagick,
+then it may be addressed by email directly to the GraphicsMagick
+maintainers or to the `GraphicsMagick Security`_ mail address. More
+minor issues are best addressed via the `GraphicsMagick Bug Tracker`_
+at SourceForge.
+
+Reporting an issue will allow us to fix it so that future releases of
+the software won't suffer from the problem.
+
+
+Safe Use Of The Software
+------------------------
+
+.. _`graphicsmagick-announce` : https://lists.sourceforge.net/lists/listinfo/graphicsmagick-announce
+.. _`Container` : https://en.wikipedia.org/wiki/Operating-system-level_virtualization
+.. _`FreeBSD Jail` : https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/jails.html
+.. _`Solaris Zone` : https://illumos.org/man/5/zones
+.. _`chrooted` : https://en.wikipedia.org/wiki/Chroot
+
+You are the first line of defense when it comes to GraphicsMagick
+security!
+
+If you are operating a server which supports file uploads from
+untrusted users, or delivered via a network protocol such as http,
+ftp, or email, then you should take steps to assure that a problem
+with opening/processing the file does not place the whole server at
+risk. These are steps which can be taken:
+
+1. Subscribe to the `graphicsmagick-announce`_ mailing list so that
+ you are informed about new GraphicsMagick releases or special
+ security bulletins.
+
+2. Make sure that GraphicsMagick is up to date as reported on the
+ GraphicsMagick web site. Don't simply trust that packages from
+ your operating system vendor are kept up to date or are updated to
+ include security fixes. Keeping GraphicsMagick up to date might
+ require that you compile GraphicsMagick yourself from source code.
+
+3. Execute the software in a `Container`_, `FreeBSD Jail`_, `Solaris
+ Zone`_, or `chrooted`_ environment such that it can not cause harm
+ to the system running it.
+
+4. Execute the software as a least-privileged user (e.g. 'nobody').
+
+5. Normalize input file names or any other external inputs so that
+ they are under your control and not controlled by an untrusted
+ party. This should include any file name specifications, which may
+ include arbitrary 'glob' patterns (wildcards), requiring hours or
+ days to complete if sufficiently close long file names exist.
+
+6. Enforce that uploaded files are passed to the expected reader. For
+ example, the uploaded file "file.jpg" is forced to be read by the
+ JPEG reader (rather than a reader selected based on header magic
+ testing) by using the file name "jpg:file.jpg". If the file is not
+ really what was indicated, then an error is reported.
+
+ GraphicsMagick supports a great many file types and auto-detects
+ many file types based on their content rather than file extension.
+ The file which pretends to be an ordinary PNG or JPEG file might be
+ something else entirely. Note that even using independent file
+ header testing may not be sufficient since it is possible to
+ construct valid files with a header which appears to be several
+ different types, but the first type which matches while testing the
+ header will be selected.
+
+7. Apply resource limits via the `-limit` option or the
+ `MAGICK_LIMIT_*` environment variables (e.g. `export
+ MAGICK_LIMIT_PIXELS=30Mp`, `export MAGICK_LIMIT_MEMORY=500Mb`).
+ Also consider setting resource limits using the `ulimit` command.
+
+8. Consider using the `MAGICK_CODER_STABILITY` environment variable to
+ constrain the supported file formats to the subsets selected by
+ `PRIMARY` or `STABLE`. After setting this environment variable
+ (e.g. `export MAGICK_CODER_STABILITY=PRIMARY`), use `gm
+ convert -list format` and verify that the format support you need
+ is enabled. Selecting the `PRIMARY` or `STABLE` options blocks
+ access of http and ftp URLs (`SSRF`_ vulnerability), but does not
+ block SVG renderer access to read local image files.
+
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
diff --git a/www/smile.c b/www/smile.c
new file mode 100644
index 0000000..a21ca27
--- /dev/null
+++ b/www/smile.c
@@ -0,0 +1,174 @@
+/*
+ Display a smiley on your X server.
+*/
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include <magick/api.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+#undef class
+#endif
+
+#define smile_width 48
+#define smile_height 48
+static unsigned char
+ smile_bits[]=
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+ };
+
+int main(int argc,char **argv)
+{
+ Image
+ *image;
+
+ ImageInfo
+ *image_info;
+
+ int
+ y;
+
+ register int
+ x;
+
+ register PixelPacket
+ *q;
+
+ register unsigned char
+ *p;
+
+ /*
+ Allocate image structure.
+ */
+ InitializeMagick(*argv);
+ image_info=CloneImageInfo((ImageInfo *) NULL);
+ image=AllocateImage(image_info);
+ if (image == (Image *) NULL)
+ MagickError(ResourceLimitError,"Unable to display image",
+ "MemoryAllocationFailed");
+ /*
+ Initialize smiley image.
+ */
+ image->columns=smile_width;
+ image->rows=smile_height;
+ p=smile_bits;
+ for (y=0; y < image->rows; y++)
+ {
+ q=SetImagePixels(image,0,y,image->columns,1);
+ if (q == (PixelPacket *) NULL)
+ break;
+ for (x=0; x < image->columns; x++)
+ {
+ q->red=MaxRGB*(*p);
+ q->green=MaxRGB*(*p);
+ q->blue=MaxRGB*(*p);
+ p++;
+ q++;
+ }
+ if (!SyncImagePixels(image))
+ break;
+ }
+ /*
+ Display smilely image.
+ */
+ DisplayImages(image_info,image);
+ /*
+ Free resources.
+ */
+ DestroyImage(image);
+ DestroyImageInfo(image_info);
+ DestroyMagick();
+}
diff --git a/www/thanks.html b/www/thanks.html
new file mode 100644
index 0000000..3b8afe5
--- /dev/null
+++ b/www/thanks.html
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Thanks</title>
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-thanks">
+<h1 class="title">GraphicsMagick Thanks</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>We would like to thank the following organizations or individuals who
+may have not contributed code but contributed substantially in other
+ways:</p>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#fuzz-testing" id="id1">Fuzz Testing</a></li>
+<li><a class="reference internal" href="#security-analysis-reports" id="id2">Security Analysis/Reports</a></li>
+<li><a class="reference internal" href="#static-code-analysis" id="id3">Static Code Analysis</a></li>
+<li><a class="reference internal" href="#software-analysis-tools" id="id4">Software Analysis Tools</a></li>
+<li><a class="reference internal" href="#additional-acknowledgements" id="id5">Additional Acknowledgements</a></li>
+</ul>
+</div>
+<div class="section" id="fuzz-testing">
+<h1><a class="toc-backref" href="#id1">Fuzz Testing</a></h1>
+<blockquote>
+<ul class="simple">
+<li>Gustavo Grieco</li>
+<li>Agostino Sarubbo</li>
+<li>Jodie Cunningham</li>
+<li>Gynvael Coldwind and Mateusz Jurczyk of the Google Security Team</li>
+<li>Hanno Böck</li>
+<li>Tobias Ospelt</li>
+<li>Michal Zalewski</li>
+<li>Moshe Kaplan</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="security-analysis-reports">
+<h1><a class="toc-backref" href="#id2">Security Analysis/Reports</a></h1>
+<blockquote>
+<ul class="simple">
+<li>John Lightsey</li>
+<li>David Chan</li>
+<li>Federico Larumbe</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="static-code-analysis">
+<h1><a class="toc-backref" href="#id3">Static Code Analysis</a></h1>
+<blockquote>
+<ul class="simple">
+<li><a class="reference external" href="http://www.synopsys.com/software/coverity/">Coverity</a> was used (free of charge) to perform static code
+analysis of the software. After resolving many issues, there are
+now zero reported defects per 1000 lines of code.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="software-analysis-tools">
+<h1><a class="toc-backref" href="#id4">Software Analysis Tools</a></h1>
+<blockquote>
+<ul class="simple">
+<li><a class="reference external" href="http://lcamtuf.coredump.cx/afl/">American fuzzy lop</a> was used (by many) to produce and discover
+many of the files which caused problems for the software.</li>
+<li><a class="reference external" href="http://quickfuzz.org/">QuickFuzz</a> was used (by Gustavo Grieco) to discover issues in the
+SVG renderer. <a class="reference external" href="http://quickfuzz.org/">QuickFuzz</a> provides specific support for a set of
+file formats and is very good at chasing down and isolating
+weaknesses.</li>
+<li><a class="reference external" href="https://code.google.com/p/address-sanitizer/">AddressSanitizer</a> (ASan) was used to detect and isolate memory
+access issues.</li>
+<li><a class="reference external" href="http://www.valgrind.org/">Valgrind</a> was used to detect and isolate memory access issues as
+well as memory leaks.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="additional-acknowledgements">
+<h1><a class="toc-backref" href="#id5">Additional Acknowledgements</a></h1>
+<dl class="docutils">
+<dt>David Pensak, E. I. du Pont de Nemours and Company</dt>
+<dd>For providing the computing environment that made
+developing ImageMagick possible.</dd>
+<dt>Alexander Zimmermann</dt>
+<dd>Responsible for the ImageMagick Linux binary
+distributions for many years. His efforts are very much
+appreciated.</dd>
+<dt>Paul Heckbert, Carnegie Mellon University</dt>
+<dd>Image resizing is based on Paul Heckbert's Zoom program.</dd>
+<dt>Paul Raveling, USC Information Sciences Institute</dt>
+<dd>The spatial subdivision color reduction algorithm is
+based on his Img software.</dd>
+<dt>Michael Halle, Spatial Imaging Group at MIT</dt>
+<dd>For the initial implementation of Alan Paeth's image
+rotation algorithm.</dd>
+<dt>Peder Langlo, Hewlett Packard</dt>
+<dd>Made hundreds of suggestions and bug reports. Without
+Peder, this software would not be nearly as useful as it
+is today.</dd>
+<dt>Rod Bogart and John W. Peterson, University of Utah</dt>
+<dd>Image compositing is loosely based on rlecomp of the
+Utah Raster Toolkit.</dd>
+<dt>Alvy Ray Smith and Eric Ray Lyons</dt>
+<dd>HWB color transform and algorithm.</dd>
+<dt>Thomas R Crimmins</dt>
+<dd>Inventor of the eight hull algorithm used for speckle
+reduction.</dd>
+</dl>
+<hr class="docutils" />
+<div class="line-block">
+<div class="line">Copyright © GraphicsMagick Group 2002 - 2017</div>
+</div>
+<p>This program is covered by multiple licenses, which are described in
+Copyright.txt. You should have received a copy of Copyright.txt with this
+package; otherwise see <a class="reference external" href="http://www.graphicsmagick.org/Copyright.html">http://www.graphicsmagick.org/Copyright.html</a>.</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/thanks.rst b/www/thanks.rst
new file mode 100644
index 0000000..d2d8d7b
--- /dev/null
+++ b/www/thanks.rst
@@ -0,0 +1,127 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+======================
+GraphicsMagick Thanks
+======================
+
+We would like to thank the following organizations or individuals who
+may have not contributed code but contributed substantially in other
+ways:
+
+.. contents::
+ :local:
+
+Fuzz Testing
+------------
+
+ * Gustavo Grieco
+
+ * Agostino Sarubbo
+
+ * Jodie Cunningham
+
+ * Gynvael Coldwind and Mateusz Jurczyk of the Google Security Team
+
+ * Hanno Bck
+
+ * Tobias Ospelt
+
+ * Michal Zalewski
+
+ * Moshe Kaplan
+
+Security Analysis/Reports
+-------------------------
+
+ * John Lightsey
+
+ * David Chan
+
+ * Federico Larumbe
+
+Static Code Analysis
+--------------------
+
+.. _`Coverity` : http://www.synopsys.com/software/coverity/
+
+ * `Coverity`_ was used (free of charge) to perform static code
+ analysis of the software. After resolving many issues, there are
+ now zero reported defects per 1000 lines of code.
+
+Software Analysis Tools
+-----------------------
+
+.. _`AddressSanitizer` : https://code.google.com/p/address-sanitizer/
+
+.. _`Valgrind` : http://www.valgrind.org/
+
+.. _`American fuzzy lop` : http://lcamtuf.coredump.cx/afl/
+
+.. _`QuickFuzz` : http://quickfuzz.org/
+
+ * `American fuzzy lop`_ was used (by many) to produce and discover
+ many of the files which caused problems for the software.
+
+ * `QuickFuzz`_ was used (by Gustavo Grieco) to discover issues in the
+ SVG renderer. `QuickFuzz`_ provides specific support for a set of
+ file formats and is very good at chasing down and isolating
+ weaknesses.
+
+ * `AddressSanitizer`_ (ASan) was used to detect and isolate memory
+ access issues.
+
+ * `Valgrind`_ was used to detect and isolate memory access issues as
+ well as memory leaks.
+
+Additional Acknowledgements
+---------------------------
+
+David Pensak, E. I. du Pont de Nemours and Company
+ For providing the computing environment that made
+ developing ImageMagick possible.
+
+Alexander Zimmermann
+ Responsible for the ImageMagick Linux binary
+ distributions for many years. His efforts are very much
+ appreciated.
+
+Paul Heckbert, Carnegie Mellon University
+ Image resizing is based on Paul Heckbert's Zoom program.
+
+Paul Raveling, USC Information Sciences Institute
+ The spatial subdivision color reduction algorithm is
+ based on his Img software.
+
+Michael Halle, Spatial Imaging Group at MIT
+ For the initial implementation of Alan Paeth's image
+ rotation algorithm.
+
+Peder Langlo, Hewlett Packard
+ Made hundreds of suggestions and bug reports. Without
+ Peder, this software would not be nearly as useful as it
+ is today.
+
+Rod Bogart and John W. Peterson, University of Utah
+ Image compositing is loosely based on rlecomp of the
+ Utah Raster Toolkit.
+
+Alvy Ray Smith and Eric Ray Lyons
+ HWB color transform and algorithm.
+
+Thomas R Crimmins
+ Inventor of the eight hull algorithm used for speckle
+ reduction.
+
+
+---------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+| Copyright |copy| GraphicsMagick Group 2002 - 2017
+
+This program is covered by multiple licenses, which are described in
+Copyright.txt. You should have received a copy of Copyright.txt with this
+package; otherwise see http://www.graphicsmagick.org/Copyright.html.
+
diff --git a/www/time.html b/www/time.html
new file mode 100644
index 0000000..7608c7a
--- /dev/null
+++ b/www/time.html
@@ -0,0 +1,140 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time"></a>gm time
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+time - time the execution of a gm command
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#time-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#time-desc">Description</a>
+</dt>
+<dt>
+<a href="#time-exam">Examples</a>
+</dt>
+<dt>
+<a href="#time-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm time</strong> <em>command</em>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>time</strong> executes an arbitrary <strong>gm</strong> utility command
+(e.g. <strong>convert</strong>) and reports the user and elapsed time. This
+provides way to measure command execution times similar to the Unix
+'time' command but in a portable and consistent way.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>To obtain time information for the execution of a
+command:
+<pre>
+% gm time convert input.ppm -gaussian 0x2 output.ppm
+convert input.ppm -gaussian 0x2 output.ppm 22.60s user 0.00s system 2354% cpu 0.960 total
+</pre>
+<p>Here is the interpretation of the above output:
+<ul>
+<li><strong>user</strong> - the total user time consumed.
+<li><strong>system</strong> - the total system time consumed.
+<li><strong>total</strong> - the total elapsed time consumed.
+</ul>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="time-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>The time command reqires no options other than the gm command to
+execute.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+</td></tr></table>
diff --git a/www/tools.html b/www/tools.html
new file mode 100644
index 0000000..60fd658
--- /dev/null
+++ b/www/tools.html
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Tools</title>
+<meta content="GraphicsMagick is a robust collection of tools and libraries to read, write, and manipulate an image in any of the more popular image formats including GIF, JPEG, PNG, PDF, and Photo CD. With GraphicsMagick you can create GIFs dynamically making it suitable for Web applications. You can also resize, rotate, sharpen, color reduce, or add special effects to an image and save your completed work in the same or differing image format. " name="description" />
+<meta content="GraphicsMagick, Image Magick, Image Magic, PerlMagick, Perl Magick, Perl Magic, image processing, software development, image, software, Magick++" name="keywords" />
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-tools">
+<h1 class="title">GraphicsMagick Tools</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#animate-animate-a-sequence-of-images" id="id2">Animate: animate a sequence of images</a></li>
+<li><a class="reference internal" href="#compare-compare-two-images-using-statistics-and-or-visual-differencing" id="id3">Compare: compare two images using statistics and/or visual differencing</a></li>
+<li><a class="reference internal" href="#composite-composite-images-together" id="id4">Composite: composite images together</a></li>
+<li><a class="reference internal" href="#conjure-execute-a-magick-scripting-language-msl-xml-script" id="id5">Conjure: execute a Magick Scripting Language (MSL) XML script</a></li>
+<li><a class="reference internal" href="#convert-convert-an-image-or-sequence-of-images" id="id6">Convert: convert an image or sequence of images</a></li>
+<li><a class="reference internal" href="#display-display-an-image-on-a-workstation-running-x" id="id7">Display: display an image on a workstation running X</a></li>
+<li><a class="reference internal" href="#identify-describe-an-image-or-image-sequence" id="id8">Identify: describe an image or image sequence</a></li>
+<li><a class="reference internal" href="#import-capture-an-application-or-x-server-screen" id="id9">Import: capture an application or X server screen</a></li>
+<li><a class="reference internal" href="#mogrify-transform-an-image-or-sequence-of-images" id="id10">Mogrify: transform an image or sequence of images</a></li>
+<li><a class="reference internal" href="#montage-create-a-composite-image-in-a-grid-from-separate-images" id="id11">Montage: create a composite image (in a grid) from separate images</a></li>
+</ul>
+</div>
+<div class="section" id="animate-animate-a-sequence-of-images">
+<h1><a class="toc-backref" href="#id2">Animate: animate a sequence of images</a></h1>
+<p><a class="reference external" href="animate.html">Animate</a> displays a sequence of images or an animation on any display
+running an X server.</p>
+</div>
+<div class="section" id="compare-compare-two-images-using-statistics-and-or-visual-differencing">
+<h1><a class="toc-backref" href="#id3">Compare: compare two images using statistics and/or visual differencing</a></h1>
+<p><a class="reference external" href="compare.html">Compare</a> compares two images using either a specified standard
+statistical metric (MAE, MSE, PAE, PSNR, RMSE), or a specified visual
+differencing method (assign, threshold, tint, xor). The statistical
+comparison produces a textual display of metric values while the visual
+differencing method writes a difference image with the differences
+annotated using the specified algorithm. For example:</p>
+<pre class="literal-block">
+% gm convert input.jpg -blur 0x1.5 output.jpg
+% gm compare -metric MSE input.jpg output.jpg
+Image Difference (MeanSquaredError):
+ Normalized Absolute
+ ============ ==========
+ Red: 0.0014374614 94.2
+ Green: 0.0014396270 94.3
+ Blue: 0.0014464548 94.8
+ Total: 0.0014411811 94.4
+</pre>
+</div>
+<div class="section" id="composite-composite-images-together">
+<h1><a class="toc-backref" href="#id4">Composite: composite images together</a></h1>
+<p><a class="reference external" href="composite.html">Composite</a> blends and merges images to create new images.</p>
+</div>
+<div class="section" id="conjure-execute-a-magick-scripting-language-msl-xml-script">
+<h1><a class="toc-backref" href="#id5">Conjure: execute a Magick Scripting Language (MSL) XML script</a></h1>
+<p><a class="reference external" href="conjure.html">Conjure</a> interprets and executes scripts in the Magick Scripting Language
+(MSL). The interpreter is called conjure and here is an example script:</p>
+<pre class="literal-block">
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;image size=&quot;400x400&quot; &gt;
+ &lt;read filename=&quot;image.gif&quot; /&gt;
+ &lt;get width=&quot;base-width&quot; height=&quot;base-height&quot; /&gt;
+ &lt;resize geometry=&quot;%[dimensions]&quot; /&gt;
+ &lt;get width=&quot;width&quot; height=&quot;height&quot; /&gt;
+ &lt;print output=
+ &quot;Image sized from %[base-width]x%[base-height]
+ to %[width]x%[height].\n&quot; /&gt;
+ &lt;write filename=&quot;image.png&quot; /&gt;
+&lt;/image&gt;
+</pre>
+<p>which is invoked like</p>
+<pre class="literal-block">
+conjure -dimensions 400x400 incantation.msl
+</pre>
+<p>All operations closely follow the key/value pairs defined in the
+<a class="reference external" href="perl.html">PerlMagick</a> documentation, unless otherwise noted.</p>
+</div>
+<div class="section" id="convert-convert-an-image-or-sequence-of-images">
+<h1><a class="toc-backref" href="#id6">Convert: convert an image or sequence of images</a></h1>
+<p><a class="reference external" href="convert.html">Convert</a> converts an input file using one image format to an output file
+with using any of the supported writeable image formats. A large number
+of image processing operations may be performed on the image before it is
+written. By default, the input image format is determined by its magic
+number. To specify a particular image format, precede the filename with
+an image format name and a colon (i.e. ps:image) or specify the image
+type as the filename suffix (i.e. image.ps). Specify file as - for
+standard input or output. If file has the extension .Z, the file is
+decoded with uncompress. For example:</p>
+<pre class="literal-block">
+% gm convert input.jpg -rotate 90 rotated.tiff
+</pre>
+</div>
+<div class="section" id="display-display-an-image-on-a-workstation-running-x">
+<h1><a class="toc-backref" href="#id7">Display: display an image on a workstation running X</a></h1>
+<p><a class="reference external" href="display.html">Display</a> is a machine architecture independent image processing and
+display program. It can display an image on any workstation display
+running an X server. The image can be displayed as background image of
+any window.</p>
+</div>
+<div class="section" id="identify-describe-an-image-or-image-sequence">
+<h1><a class="toc-backref" href="#id8">Identify: describe an image or image sequence</a></h1>
+<p><a class="reference external" href="identify.html">Identify</a> describes the format and characteristics of one or more image
+files. It will also report if an image is incomplete or corrupt. The
+information displayed includes the scene number, the file name, the width
+and height of the image, whether the image is colormapped or not, the
+number of colors in the image, the number of bytes in the image, the
+format of the image (JPEG, PNM, etc.), and finally the number of seconds
+it took to read and process the image. For example:</p>
+<pre class="literal-block">
+% gm identify tiger-1200-rgb16.tiff
+tiger-1200-rgb16.tiff TIFF 9083x9450+0+0 DirectClass 16-bit 491.2M 0.000u 0:01
+</pre>
+</div>
+<div class="section" id="import-capture-an-application-or-x-server-screen">
+<h1><a class="toc-backref" href="#id9">Import: capture an application or X server screen</a></h1>
+<p><a class="reference external" href="import.html">Import</a> reads an image from any visible window on an X server and outputs
+it as an image file. You can capture a single window, the entire screen,
+or any rectangular portion of the screen.</p>
+<p>The target window can be specified by id, name, or may be selected by
+clicking the mouse in the desired window. If you press a button and then
+drag, a rectangle will form which expands and contracts as the mouse
+moves. To save the portion of the screen defined by the rectangle, just
+release the button. The keyboard bell is rung once at the beginning of
+the screen capture and twice when it completes. For example:</p>
+<pre class="literal-block">
+% gm import capture.tiff
+</pre>
+</div>
+<div class="section" id="mogrify-transform-an-image-or-sequence-of-images">
+<h1><a class="toc-backref" href="#id10">Mogrify: transform an image or sequence of images</a></h1>
+<p><a class="reference external" href="mogrify.html">Mogrify</a> transforms an image or a sequence of images &quot;in place&quot;. These
+transforms include image scaling, image rotation, color reduction, and
+others. The transmogrified image overwrites the original image. <a class="reference external" href="mogrify.html">Mogrify</a>
+is very similar to <a class="reference external" href="convert.html">Convert</a> except that it can operate on many images at
+once, and overwrites the input files by default. However, <a class="reference external" href="mogrify.html">Mogrify</a> may
+also be used to convert file formats, and send modified files to another
+directory. For example, the following reads several JPEG files and writes
+a rotated version of them in TIFF format:</p>
+<pre class="literal-block">
+% gm mogrify -rotate 90 -format tiff image1.jpg image2.jpg image3.jpg
+</pre>
+</div>
+<div class="section" id="montage-create-a-composite-image-in-a-grid-from-separate-images">
+<h1><a class="toc-backref" href="#id11">Montage: create a composite image (in a grid) from separate images</a></h1>
+<p><a class="reference external" href="montage.html">Montage</a> creates a composite by combining several separate images. The
+images are tiled on a composite image with the name of the image and its
+properties optionally appearing just below the individual tile.</p>
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/tools.rst b/www/tools.rst
new file mode 100644
index 0000000..1a57851
--- /dev/null
+++ b/www/tools.rst
@@ -0,0 +1,174 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=======================================
+GraphicsMagick Tools
+=======================================
+
+.. meta::
+ :description: GraphicsMagick is a robust collection of tools and libraries to read,
+ write, and manipulate an image in any of the more popular
+ image formats including GIF, JPEG, PNG, PDF, and Photo CD.
+ With GraphicsMagick you can create GIFs dynamically making it
+ suitable for Web applications. You can also resize, rotate,
+ sharpen, color reduce, or add special effects to an image and
+ save your completed work in the same or differing image format.
+
+ :keywords: GraphicsMagick, Image Magick, Image Magic, PerlMagick, Perl Magick,
+ Perl Magic, image processing, software development, image, software,
+ Magick++
+
+.. _programming : programming.html
+.. _Animate : animate.html
+.. _Compare : compare.html
+.. _Composite : composite.html
+.. _Compare : compare.html
+.. _Conjure : conjure.html
+.. _Convert : convert.html
+.. _Display : display.html
+.. _Identify : identify.html
+.. _Import : import.html
+.. _Mogrify : mogrify.html
+.. _Montage : montage.html
+.. _PerlMagick : perl.html
+
+.. contents::
+ :local:
+
+Animate: animate a sequence of images
+=====================================
+
+Animate_ displays a sequence of images or an animation on any display
+running an X server.
+
+Compare: compare two images using statistics and/or visual differencing
+=======================================================================
+
+Compare_ compares two images using either a specified standard
+statistical metric (MAE, MSE, PAE, PSNR, RMSE), or a specified visual
+differencing method (assign, threshold, tint, xor). The statistical
+comparison produces a textual display of metric values while the visual
+differencing method writes a difference image with the differences
+annotated using the specified algorithm. For example::
+
+ % gm convert input.jpg -blur 0x1.5 output.jpg
+ % gm compare -metric MSE input.jpg output.jpg
+ Image Difference (MeanSquaredError):
+ Normalized Absolute
+ ============ ==========
+ Red: 0.0014374614 94.2
+ Green: 0.0014396270 94.3
+ Blue: 0.0014464548 94.8
+ Total: 0.0014411811 94.4
+
+Composite: composite images together
+====================================
+
+Composite_ blends and merges images to create new images.
+
+Conjure: execute a Magick Scripting Language (MSL) XML script
+=============================================================
+
+Conjure_ interprets and executes scripts in the Magick Scripting Language
+(MSL). The interpreter is called conjure and here is an example script::
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <image size="400x400" >
+ <read filename="image.gif" />
+ <get width="base-width" height="base-height" />
+ <resize geometry="%[dimensions]" />
+ <get width="width" height="height" />
+ <print output=
+ "Image sized from %[base-width]x%[base-height]
+ to %[width]x%[height].\n" />
+ <write filename="image.png" />
+ </image>
+
+which is invoked like
+
+::
+
+ conjure -dimensions 400x400 incantation.msl
+
+All operations closely follow the key/value pairs defined in the
+PerlMagick_ documentation, unless otherwise noted.
+
+Convert: convert an image or sequence of images
+===============================================
+
+Convert_ converts an input file using one image format to an output file
+with using any of the supported writeable image formats. A large number
+of image processing operations may be performed on the image before it is
+written. By default, the input image format is determined by its magic
+number. To specify a particular image format, precede the filename with
+an image format name and a colon (i.e. ps:image) or specify the image
+type as the filename suffix (i.e. image.ps). Specify file as - for
+standard input or output. If file has the extension .Z, the file is
+decoded with uncompress. For example::
+
+ % gm convert input.jpg -rotate 90 rotated.tiff
+
+Display: display an image on a workstation running X
+====================================================
+
+Display_ is a machine architecture independent image processing and
+display program. It can display an image on any workstation display
+running an X server. The image can be displayed as background image of
+any window.
+
+Identify: describe an image or image sequence
+=============================================
+
+Identify_ describes the format and characteristics of one or more image
+files. It will also report if an image is incomplete or corrupt. The
+information displayed includes the scene number, the file name, the width
+and height of the image, whether the image is colormapped or not, the
+number of colors in the image, the number of bytes in the image, the
+format of the image (JPEG, PNM, etc.), and finally the number of seconds
+it took to read and process the image. For example::
+
+ % gm identify tiger-1200-rgb16.tiff
+ tiger-1200-rgb16.tiff TIFF 9083x9450+0+0 DirectClass 16-bit 491.2M 0.000u 0:01
+
+Import: capture an application or X server screen
+=================================================
+
+Import_ reads an image from any visible window on an X server and outputs
+it as an image file. You can capture a single window, the entire screen,
+or any rectangular portion of the screen.
+
+The target window can be specified by id, name, or may be selected by
+clicking the mouse in the desired window. If you press a button and then
+drag, a rectangle will form which expands and contracts as the mouse
+moves. To save the portion of the screen defined by the rectangle, just
+release the button. The keyboard bell is rung once at the beginning of
+the screen capture and twice when it completes. For example::
+
+ % gm import capture.tiff
+
+Mogrify: transform an image or sequence of images
+=================================================
+
+Mogrify_ transforms an image or a sequence of images "in place". These
+transforms include image scaling, image rotation, color reduction, and
+others. The transmogrified image overwrites the original image. Mogrify_
+is very similar to Convert_ except that it can operate on many images at
+once, and overwrites the input files by default. However, Mogrify_ may
+also be used to convert file formats, and send modified files to another
+directory. For example, the following reads several JPEG files and writes
+a rotated version of them in TIFF format::
+
+ % gm mogrify -rotate 90 -format tiff image1.jpg image2.jpg image3.jpg
+
+Montage: create a composite image (in a grid) from separate images
+==================================================================
+
+Montage_ creates a composite by combining several separate images. The
+images are tiled on a composite image with the name of the image and its
+properties optionally appearing just below the individual tile.
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
+
diff --git a/www/utilities.html b/www/utilities.html
new file mode 100644
index 0000000..6d64838
--- /dev/null
+++ b/www/utilities.html
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Utilities</title>
+<meta content="GraphicsMagick is a robust collection of tools and libraries to read, write, and manipulate an image in any of the more popular image formats including GIF, JPEG, PNG, PDF, and Photo CD. With GraphicsMagick you can create GIFs dynamically making it suitable for Web applications. You can also resize, rotate, sharpen, color reduce, or add special effects to an image and save your completed work in the same or differing image format. " name="description" />
+<meta content="GraphicsMagick, Image Magick, Image Magic, PerlMagick, Perl Magick, Perl Magic, image processing, software development, image, software, Magick++" name="keywords" />
+<link rel="stylesheet" href="docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="index.html">Home</a></li>
+<li><a href="project.html">Project</a></li>
+<li><a href="download.html">Download</a></li>
+<li><a href="README.html">Install</a></li>
+<li><a href="Hg.html">Source</a></li>
+<li><a href="NEWS.html">News</a> </li>
+<li><a href="utilities.html">Utilities</a></li>
+<li><a href="programming.html">Programming</a></li>
+<li><a href="reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-utilities">
+<h1 class="title">GraphicsMagick Utilities</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>GraphicsMagick provides a powerful command line utility <cite>gm</cite>, which
+may be used to access all GraphicsMagick functions. Gm uses a
+consistent set of options (<a class="reference external" href="GraphicsMagick.html">see options documentation</a>). GraphicsMagick provides access to major
+commands via a single executable command-line program; for example, to
+use the &quot;convert&quot; sub-command, type <tt class="docutils literal">gm convert ...</tt>. The available
+commands are as follows:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="17%" />
+<col width="83%" />
+</colgroup>
+<tbody valign="top">
+<tr><td><a class="reference external" href="animate.html">animate</a></td>
+<td>Animate a sequence of images</td>
+</tr>
+<tr><td><a class="reference external" href="batch.html">batch</a></td>
+<td>Executes an arbitary number of utility commands</td>
+</tr>
+<tr><td><a class="reference external" href="benchmark.html">benchmark</a></td>
+<td>Measure and report utility command performance.</td>
+</tr>
+<tr><td><a class="reference external" href="compare.html">compare</a></td>
+<td>Compare two images using statistics and/or visual differencing</td>
+</tr>
+<tr><td><a class="reference external" href="composite.html">composite</a></td>
+<td>Composite images together</td>
+</tr>
+<tr><td><a class="reference external" href="conjure.html">conjure</a></td>
+<td>Execute a Magick Scripting Language (MSL) XML script</td>
+</tr>
+<tr><td><a class="reference external" href="convert.html">convert</a></td>
+<td>Convert an image or sequence of images</td>
+</tr>
+<tr><td><a class="reference external" href="display.html">display</a></td>
+<td>Display an image on a workstation running X</td>
+</tr>
+<tr><td><a class="reference external" href="identify.html">identify</a></td>
+<td>Describe an image or image sequence</td>
+</tr>
+<tr><td><a class="reference external" href="import.html">import</a></td>
+<td>Capture an application or X server screen</td>
+</tr>
+<tr><td><a class="reference external" href="mogrify.html">mogrify</a></td>
+<td>Transform an image or sequence of images</td>
+</tr>
+<tr><td><a class="reference external" href="montage.html">montage</a></td>
+<td>Create a composite image (in a grid) from separate images</td>
+</tr>
+<tr><td><a class="reference external" href="time.html">time</a></td>
+<td>Time the execution of a utility command.</td>
+</tr>
+<tr><td><a class="reference external" href="version.html">version</a></td>
+<td>Report GraphicsMagick version, features, and build options.</td>
+</tr>
+</tbody>
+</table>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2002 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/utilities.rst b/www/utilities.rst
new file mode 100644
index 0000000..fe208c0
--- /dev/null
+++ b/www/utilities.rst
@@ -0,0 +1,70 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=======================================
+GraphicsMagick Utilities
+=======================================
+
+.. meta::
+ :description: GraphicsMagick is a robust collection of tools and libraries to read,
+ write, and manipulate an image in any of the more popular
+ image formats including GIF, JPEG, PNG, PDF, and Photo CD.
+ With GraphicsMagick you can create GIFs dynamically making it
+ suitable for Web applications. You can also resize, rotate,
+ sharpen, color reduce, or add special effects to an image and
+ save your completed work in the same or differing image format.
+
+ :keywords: GraphicsMagick, Image Magick, Image Magic, PerlMagick, Perl Magick,
+ Perl Magic, image processing, software development, image, software,
+ Magick++
+
+
+.. _animate : animate.html
+.. _batch: batch.html
+.. _benchmark: benchmark.html
+.. _compare : compare.html
+.. _composite : composite.html
+.. _conjure : conjure.html
+.. _convert : convert.html
+.. _display : display.html
+.. _identify : identify.html
+.. _import : import.html
+.. _mogrify : mogrify.html
+.. _montage : montage.html
+.. _programming : programming.html
+.. _time: time.html
+.. _version: version.html
+
+
+GraphicsMagick provides a powerful command line utility `gm`, which
+may be used to access all GraphicsMagick functions. Gm uses a
+consistent set of options (`see options documentation
+<GraphicsMagick.html>`_). GraphicsMagick provides access to major
+commands via a single executable command-line program; for example, to
+use the "convert" sub-command, type ``gm convert ...``. The available
+commands are as follows:
+
+=============== =========================================================================
+animate_ Animate a sequence of images
+batch_ Executes an arbitary number of utility commands
+benchmark_ Measure and report utility command performance.
+compare_ Compare two images using statistics and/or visual differencing
+composite_ Composite images together
+conjure_ Execute a Magick Scripting Language (MSL) XML script
+convert_ Convert an image or sequence of images
+display_ Display an image on a workstation running X
+identify_ Describe an image or image sequence
+import_ Capture an application or X server screen
+mogrify_ Transform an image or sequence of images
+montage_ Create a composite image (in a grid) from separate images
+time_ Time the execution of a utility command.
+version_ Report GraphicsMagick version, features, and build options.
+=============== =========================================================================
+
+--------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2002 - 2017
+
diff --git a/www/version.html b/www/version.html
new file mode 100644
index 0000000..2f92ee6
--- /dev/null
+++ b/www/version.html
@@ -0,0 +1,170 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=us-ascii">
+ <title>GraphicsMagick GM Utility</title>
+ <style type=text/css>
+ <!--
+ @page { size: 8.5in 11in }
+ TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
+ A:link { color: #00B04F }
+ A:visited { color: #007B37 }
+ -->
+ </style>
+
+</head>
+<body LANG="en-US" TEXT="#000000" LINK="#00B04F" VLINK="#007B37" BGCOLOR="#ffffff">
+<a name="top"></a>
+<table border=0 cellpadding=10 cellspacing=0 style="margin-top:-17px" width="100%"><tr><td>
+<br>&nbsp;<br>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version"></a>gm version
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-top"></a>NAME
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+version - display software version, feature, and build information
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-contents"></a>Contents
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<dl>
+<dt>
+<a href="#version-syno">Synopsis</a>
+</dt>
+<dt>
+<a href="#version-desc">Description</a>
+</dt>
+<dt>
+<a href="#version-exam">Examples</a>
+</dt>
+<dt>
+<a href="#version-opti">Options</a>
+</dt>
+</dl>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-syno"></a>Synopsis
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>gm version</strong>
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-desc"></a>Description
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>
+<strong>version</strong> displays the software release version, build quantum
+(pixel sample) depth, web site URL, copyright notice, enabled features
+support, configuration parameters, and final build options used to
+build the software. The available information depends on how the
+software was configured and the host system.
+</td></tr></table>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-exam"></a>Examples
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>To display the version information:
+<pre>
+ % gm -version
+ GraphicsMagick 1.3.19 2013-12-31 Q16 http://www.GraphicsMagick.org/
+ Copyright (C) 2002-2013 GraphicsMagick Group.
+ Additional copyrights and licenses apply to this software.
+ See http://www.GraphicsMagick.org/www/Copyright.html for details.
+ Feature Support:
+ Thread Safe yes
+ Large Files (&gt; 32 bit) yes
+ Large Memory (&gt; 32 bit) no
+ BZIP yes
+ DPS no
+ FlashPix no
+ FreeType yes
+ Ghostscript (Library) no
+ JBIG no
+ JPEG-2000 yes
+ JPEG yes
+ Little CMS yes
+ Loadable Modules no
+ OpenMP yes (201107)
+ PNG yes
+ TIFF yes
+ TRIO no
+ UMEM yes
+ WMF no
+ X11 yes
+ XML yes
+ ZLIB yes
+ Host type: i386-pc-solaris2.11
+ Configured using the command:
+ ./configure ...
+ Final Build Parameters:
+ CC = ...
+ CFLAGS = ...
+ CPPFLAGS = ...
+ CXX = ...
+ CXXFLAGS = ...
+ LDFLAGS = ...
+ LIBS = ...
+</pre>
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+<table BORDER=0 WIDTH="100%">
+<tr>
+<td ALIGN=LEFT bgcolor="#FFFFFF"><img
+SRC="images/right_triangle.png" ALT=">" BORDER=0
+height=14 width=15><b><font face="Helvetica, Arial"><font
+color="#00B04F"><font size="+1">
+<a NAME="version-opti"></a>Options
+</font></font></font></b></td></tr></table>
+<table width="94%" border="0" cellspacing="0" cellpadding="8">
+<tr><td width="3%"><br></td><td>
+<p>The version command does not currently support any options.
+</td></tr></table>
+ <p>
+<i><a href="#top">Back to Contents</a></i>
+&nbsp;</p>
+</td></tr></table>
diff --git a/www/wand/Makefile.am b/www/wand/Makefile.am
new file mode 100644
index 0000000..213c249
--- /dev/null
+++ b/www/wand/Makefile.am
@@ -0,0 +1,57 @@
+# Copyright (C) 2009 - 2012 GraphicsMagick Group
+
+# This program is covered by multiple licenses, which are described in
+# Copyright.txt. You should have received a copy of Copyright.txt with this
+# package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
+#
+# Makefile for building Wand API HTML files
+#
+
+wwwwandapidir = $(htmldir)/wand
+
+WWWWANDAPIDIR = $(top_srcdir)/www/wand
+
+WWWWANDAPI_HTML_TARGETS = \
+ $(WWWWANDAPIDIR)/drawing_wand.html \
+ $(WWWWANDAPIDIR)/magick_wand.html \
+ $(WWWWANDAPIDIR)/pixel_wand.html
+
+
+WWWWANDAPI_FILES = \
+ www/wand/drawing_wand.html \
+ www/wand/magick_wand.html \
+ www/wand/pixel_wand.html
+
+WWWWANDAPI_EXTRA_DIST = \
+ www/wand/wand.rst \
+ $(WWWWANDAPI_FILES)
+
+WWWWANDAPI_MAINTAINER_TARGETS = $(WWWWANDAPI_HTML_TARGETS)
+
+if MAINTAINER_MODE
+
+if HasRST2HTML
+#APIWHATIS = $(top_srcdir)/scripts/whatis.txt
+#FORMATCAPI = $(top_srcdir)/scripts/format_c_api_doc.py
+
+#APIRST2HTML_COMMAND = $(RST2HTMLDECO) \
+ --link-stylesheet=../docutils-articles.css`
+
+$(WWWWANDAPI_HTML_TARGETS) : $(FORMATCAPI) \
+ $(RST2HTMLDECO) \
+ $(APIWHATIS) \
+ $(top_srcdir)/scripts/html_fragments.py \
+ $(top_srcdir)/www/wand/Makefile.am \
+ $(top_srcdir)/www/api/api_hyperlinks.rst
+
+$(WWWWANDAPIDIR)/%.apirst : $(top_srcdir)/wand/%.c
+ $(FORMATCAPI) --whatis-file $(APIWHATIS) \
+ --include-rst ../api/api_hyperlinks.rst $< $@
+
+$(WWWWANDAPIDIR)/%.html : $(WWWWANDAPIDIR)/%.apirst
+ $(RST2HTMLDECO) --link-stylesheet=`$(RELPATH) $(top_srcdir)/www $@`docutils-api.css \
+ --url-prefix=`$(RELPATH) $(top_srcdir)/www $@` $< $@
+
+endif # HasRST2HTML
+
+endif # MAINTAINER_MODE
diff --git a/www/wand/drawing_wand.html b/www/wand/drawing_wand.html
new file mode 100644
index 0000000..596b9c9
--- /dev/null
+++ b/www/wand/drawing_wand.html
@@ -0,0 +1,3245 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>drawing_wand</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="drawing-wand">
+<h1 class="title">drawing_wand</h1>
+<h2 class="subtitle" id="wand-vector-drawing-interfaces">Wand vector drawing interfaces</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#clonedrawingwand" id="id227">CloneDrawingWand</a></li>
+<li><a class="reference internal" href="#destroydrawingwand" id="id228">DestroyDrawingWand</a></li>
+<li><a class="reference internal" href="#drawannotation" id="id229">DrawAnnotation</a></li>
+<li><a class="reference internal" href="#drawaffine" id="id230">DrawAffine</a></li>
+<li><a class="reference internal" href="#drawallocatewand" id="id231">DrawAllocateWand</a></li>
+<li><a class="reference internal" href="#drawarc" id="id232">DrawArc</a></li>
+<li><a class="reference internal" href="#drawbezier" id="id233">DrawBezier</a></li>
+<li><a class="reference internal" href="#drawcircle" id="id234">DrawCircle</a></li>
+<li><a class="reference internal" href="#drawclearexception" id="id235">DrawClearException</a></li>
+<li><a class="reference internal" href="#drawgetclippath" id="id236">DrawGetClipPath</a></li>
+<li><a class="reference internal" href="#drawsetclippath" id="id237">DrawSetClipPath</a></li>
+<li><a class="reference internal" href="#drawgetcliprule" id="id238">DrawGetClipRule</a></li>
+<li><a class="reference internal" href="#drawsetcliprule" id="id239">DrawSetClipRule</a></li>
+<li><a class="reference internal" href="#drawgetclipunits" id="id240">DrawGetClipUnits</a></li>
+<li><a class="reference internal" href="#drawgetexception" id="id241">DrawGetException</a></li>
+<li><a class="reference internal" href="#drawsetclipunits" id="id242">DrawSetClipUnits</a></li>
+<li><a class="reference internal" href="#drawcolor" id="id243">DrawColor</a></li>
+<li><a class="reference internal" href="#drawcomment" id="id244">DrawComment</a></li>
+<li><a class="reference internal" href="#drawellipse" id="id245">DrawEllipse</a></li>
+<li><a class="reference internal" href="#drawgetfillcolor" id="id246">DrawGetFillColor</a></li>
+<li><a class="reference internal" href="#drawsetfillcolor" id="id247">DrawSetFillColor</a></li>
+<li><a class="reference internal" href="#drawsetfillpatternurl" id="id248">DrawSetFillPatternURL</a></li>
+<li><a class="reference internal" href="#drawgetfillopacity" id="id249">DrawGetFillOpacity</a></li>
+<li><a class="reference internal" href="#drawsetfillopacity" id="id250">DrawSetFillOpacity</a></li>
+<li><a class="reference internal" href="#drawgetfillrule" id="id251">DrawGetFillRule</a></li>
+<li><a class="reference internal" href="#drawsetfillrule" id="id252">DrawSetFillRule</a></li>
+<li><a class="reference internal" href="#drawgetfont" id="id253">DrawGetFont</a></li>
+<li><a class="reference internal" href="#drawsetfont" id="id254">DrawSetFont</a></li>
+<li><a class="reference internal" href="#drawgetfontfamily" id="id255">DrawGetFontFamily</a></li>
+<li><a class="reference internal" href="#drawsetfontfamily" id="id256">DrawSetFontFamily</a></li>
+<li><a class="reference internal" href="#drawgetfontsize" id="id257">DrawGetFontSize</a></li>
+<li><a class="reference internal" href="#drawsetfontsize" id="id258">DrawSetFontSize</a></li>
+<li><a class="reference internal" href="#drawgetfontstretch" id="id259">DrawGetFontStretch</a></li>
+<li><a class="reference internal" href="#drawsetfontstretch" id="id260">DrawSetFontStretch</a></li>
+<li><a class="reference internal" href="#drawgetfontstyle" id="id261">DrawGetFontStyle</a></li>
+<li><a class="reference internal" href="#drawsetfontstyle" id="id262">DrawSetFontStyle</a></li>
+<li><a class="reference internal" href="#drawgetfontweight" id="id263">DrawGetFontWeight</a></li>
+<li><a class="reference internal" href="#drawsetfontweight" id="id264">DrawSetFontWeight</a></li>
+<li><a class="reference internal" href="#drawgetgravity" id="id265">DrawGetGravity</a></li>
+<li><a class="reference internal" href="#drawsetgravity" id="id266">DrawSetGravity</a></li>
+<li><a class="reference internal" href="#drawcomposite" id="id267">DrawComposite</a></li>
+<li><a class="reference internal" href="#drawline" id="id268">DrawLine</a></li>
+<li><a class="reference internal" href="#drawmatte" id="id269">DrawMatte</a></li>
+<li><a class="reference internal" href="#drawpathclose" id="id270">DrawPathClose</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoabsolute" id="id271">DrawPathCurveToAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathcurvetorelative" id="id272">DrawPathCurveToRelative</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoquadraticbezierabsolute" id="id273">DrawPathCurveToQuadraticBezierAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoquadraticbezierrelative" id="id274">DrawPathCurveToQuadraticBezierRelative</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoquadraticbeziersmoothabsolute" id="id275">DrawPathCurveToQuadraticBezierSmoothAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathcurvetoquadraticbeziersmoothrelative" id="id276">DrawPathCurveToQuadraticBezierSmoothRelative</a></li>
+<li><a class="reference internal" href="#drawpathcurvetosmoothabsolute" id="id277">DrawPathCurveToSmoothAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathcurvetosmoothrelative" id="id278">DrawPathCurveToSmoothRelative</a></li>
+<li><a class="reference internal" href="#drawpathellipticarcabsolute" id="id279">DrawPathEllipticArcAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathellipticarcrelative" id="id280">DrawPathEllipticArcRelative</a></li>
+<li><a class="reference internal" href="#drawpathfinish" id="id281">DrawPathFinish</a></li>
+<li><a class="reference internal" href="#drawpathlinetoabsolute" id="id282">DrawPathLineToAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathlinetorelative" id="id283">DrawPathLineToRelative</a></li>
+<li><a class="reference internal" href="#drawpathlinetohorizontalabsolute" id="id284">DrawPathLineToHorizontalAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathlinetohorizontalrelative" id="id285">DrawPathLineToHorizontalRelative</a></li>
+<li><a class="reference internal" href="#drawpathlinetoverticalabsolute" id="id286">DrawPathLineToVerticalAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathlinetoverticalrelative" id="id287">DrawPathLineToVerticalRelative</a></li>
+<li><a class="reference internal" href="#drawpathmovetoabsolute" id="id288">DrawPathMoveToAbsolute</a></li>
+<li><a class="reference internal" href="#drawpathmovetorelative" id="id289">DrawPathMoveToRelative</a></li>
+<li><a class="reference internal" href="#drawpathstart" id="id290">DrawPathStart</a></li>
+<li><a class="reference internal" href="#drawpeekgraphiccontext" id="id291">DrawPeekGraphicContext</a></li>
+<li><a class="reference internal" href="#drawpoint" id="id292">DrawPoint</a></li>
+<li><a class="reference internal" href="#drawpolygon" id="id293">DrawPolygon</a></li>
+<li><a class="reference internal" href="#drawpolyline" id="id294">DrawPolyline</a></li>
+<li><a class="reference internal" href="#drawpopclippath" id="id295">DrawPopClipPath</a></li>
+<li><a class="reference internal" href="#drawpopdefs" id="id296">DrawPopDefs</a></li>
+<li><a class="reference internal" href="#drawpopgraphiccontext" id="id297">DrawPopGraphicContext</a></li>
+<li><a class="reference internal" href="#drawpoppattern" id="id298">DrawPopPattern</a></li>
+<li><a class="reference internal" href="#drawpushclippath" id="id299">DrawPushClipPath</a></li>
+<li><a class="reference internal" href="#drawpushdefs" id="id300">DrawPushDefs</a></li>
+<li><a class="reference internal" href="#drawpushgraphiccontext" id="id301">DrawPushGraphicContext</a></li>
+<li><a class="reference internal" href="#drawpushpattern" id="id302">DrawPushPattern</a></li>
+<li><a class="reference internal" href="#drawrectangle" id="id303">DrawRectangle</a></li>
+<li><a class="reference internal" href="#drawrender" id="id304">DrawRender</a></li>
+<li><a class="reference internal" href="#drawrotate" id="id305">DrawRotate</a></li>
+<li><a class="reference internal" href="#drawroundrectangle" id="id306">DrawRoundRectangle</a></li>
+<li><a class="reference internal" href="#drawscale" id="id307">DrawScale</a></li>
+<li><a class="reference internal" href="#drawskewx" id="id308">DrawSkewX</a></li>
+<li><a class="reference internal" href="#drawskewy" id="id309">DrawSkewY</a></li>
+<li><a class="reference internal" href="#drawsetstopcolor" id="id310">DrawSetStopColor</a></li>
+<li><a class="reference internal" href="#drawgetstrokecolor" id="id311">DrawGetStrokeColor</a></li>
+<li><a class="reference internal" href="#drawsetstrokecolor" id="id312">DrawSetStrokeColor</a></li>
+<li><a class="reference internal" href="#drawsetstrokepatternurl" id="id313">DrawSetStrokePatternURL</a></li>
+<li><a class="reference internal" href="#drawgetstrokeantialias" id="id314">DrawGetStrokeAntialias</a></li>
+<li><a class="reference internal" href="#drawsetstrokeantialias" id="id315">DrawSetStrokeAntialias</a></li>
+<li><a class="reference internal" href="#drawgetstrokedasharray" id="id316">DrawGetStrokeDashArray</a></li>
+<li><a class="reference internal" href="#drawsetstrokedasharray" id="id317">DrawSetStrokeDashArray</a></li>
+<li><a class="reference internal" href="#drawgetstrokedashoffset" id="id318">DrawGetStrokeDashOffset</a></li>
+<li><a class="reference internal" href="#drawsetstrokedashoffset" id="id319">DrawSetStrokeDashOffset</a></li>
+<li><a class="reference internal" href="#drawgetstrokelinecap" id="id320">DrawGetStrokeLineCap</a></li>
+<li><a class="reference internal" href="#drawsetstrokelinecap" id="id321">DrawSetStrokeLineCap</a></li>
+<li><a class="reference internal" href="#drawgetstrokelinejoin" id="id322">DrawGetStrokeLineJoin</a></li>
+<li><a class="reference internal" href="#drawsetstrokelinejoin" id="id323">DrawSetStrokeLineJoin</a></li>
+<li><a class="reference internal" href="#drawgetstrokemiterlimit" id="id324">DrawGetStrokeMiterLimit</a></li>
+<li><a class="reference internal" href="#drawsetstrokemiterlimit" id="id325">DrawSetStrokeMiterLimit</a></li>
+<li><a class="reference internal" href="#drawgetstrokeopacity" id="id326">DrawGetStrokeOpacity</a></li>
+<li><a class="reference internal" href="#drawsetstrokeopacity" id="id327">DrawSetStrokeOpacity</a></li>
+<li><a class="reference internal" href="#drawgetstrokewidth" id="id328">DrawGetStrokeWidth</a></li>
+<li><a class="reference internal" href="#drawsetstrokewidth" id="id329">DrawSetStrokeWidth</a></li>
+<li><a class="reference internal" href="#drawgettextantialias" id="id330">DrawGetTextAntialias</a></li>
+<li><a class="reference internal" href="#drawsettextantialias" id="id331">DrawSetTextAntialias</a></li>
+<li><a class="reference internal" href="#drawgettextdecoration" id="id332">DrawGetTextDecoration</a></li>
+<li><a class="reference internal" href="#drawsettextdecoration" id="id333">DrawSetTextDecoration</a></li>
+<li><a class="reference internal" href="#drawgettextencoding" id="id334">DrawGetTextEncoding</a></li>
+<li><a class="reference internal" href="#drawsettextencoding" id="id335">DrawSetTextEncoding</a></li>
+<li><a class="reference internal" href="#drawgettextundercolor" id="id336">DrawGetTextUnderColor</a></li>
+<li><a class="reference internal" href="#drawsettextundercolor" id="id337">DrawSetTextUnderColor</a></li>
+<li><a class="reference internal" href="#drawtranslate" id="id338">DrawTranslate</a></li>
+<li><a class="reference internal" href="#drawsetviewbox" id="id339">DrawSetViewbox</a></li>
+<li><a class="reference internal" href="#newdrawingwand" id="id340">NewDrawingWand</a></li>
+</ul>
+</div>
+<div class="section" id="clonedrawingwand">
+<h1><a class="toc-backref" href="#id227">CloneDrawingWand</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+DrawingWand *CloneDrawingWand( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>CloneDrawingWand() returns a new drawing wand which is a full (deep) copy
+of an existing drawing wand.</p>
+<p>The format of the CloneDrawingWand method is:</p>
+<pre class="literal-block">
+DrawingWand *CloneDrawingWand( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand to copy</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroydrawingwand">
+<h1><a class="toc-backref" href="#id228">DestroyDrawingWand</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyDrawingWand( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>DestroyDrawingWand() frees all resources associated with the drawing
+wand. Once the drawing wand has been freed, it should not be used
+any further unless it re-allocated.</p>
+<p>The format of the DestroyDrawingWand method is:</p>
+<pre class="literal-block">
+void DestroyDrawingWand( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand to destroy.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawannotation">
+<h1><a class="toc-backref" href="#id229">DrawAnnotation</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawAnnotation( DrawingWand *drawing_wand, const double x, const double y,
+ const unsigned char *text );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DrawAnnotation() draws text on the image.</p>
+<p>The format of the DrawAnnotation method is:</p>
+<pre class="literal-block">
+void DrawAnnotation( DrawingWand *drawing_wand, const double x, const double y,
+ const unsigned char *text );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>x ordinate to left of text</dd>
+<dt>y:</dt>
+<dd>y ordinate to text baseline</dd>
+<dt>text:</dt>
+<dd>text to draw</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawaffine">
+<h1><a class="toc-backref" href="#id230">DrawAffine</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawAffine( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#affinematrix">AffineMatrix</a> *affine );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>DrawAffine() adjusts the current affine transformation matrix with
+the specified affine transformation matrix. Note that the current affine
+transform is adjusted rather than replaced.</p>
+<p>The format of the DrawAffine method is:</p>
+<pre class="literal-block">
+void DrawAffine( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#affinematrix">AffineMatrix</a> *affine );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>Drawing drawing_wand</dd>
+<dt>affine:</dt>
+<dd>Affine matrix parameters</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawallocatewand">
+<h1><a class="toc-backref" href="#id231">DrawAllocateWand</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+DrawingWand DrawAllocateWand( const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>DrawAllocateWand() allocates an initial drawing wand which is an
+opaque handle required by the remaining drawing methods.</p>
+<p>The format of the DrawAllocateWand method is:</p>
+<pre class="literal-block">
+DrawingWand DrawAllocateWand( const <a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *draw_info, <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>draw_info:</dt>
+<dd>Initial drawing defaults. Set to NULL to use
+ImageMagick defaults.</dd>
+<dt>image:</dt>
+<dd>The image to draw on.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawarc">
+<h1><a class="toc-backref" href="#id232">DrawArc</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawArc( DrawingWand *drawing_wand, const double sx, const double sy, const double ex,
+ const double ey, const double sd, const double ed );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>DrawArc() draws an arc falling within a specified bounding rectangle on the
+image.</p>
+<p>The format of the DrawArc method is:</p>
+<pre class="literal-block">
+void DrawArc( DrawingWand *drawing_wand, const double sx, const double sy, const double ex,
+ const double ey, const double sd, const double ed );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>sx:</dt>
+<dd>starting x ordinate of bounding rectangle</dd>
+<dt>sy:</dt>
+<dd>starting y ordinate of bounding rectangle</dd>
+<dt>ex:</dt>
+<dd>ending x ordinate of bounding rectangle</dd>
+<dt>ey:</dt>
+<dd>ending y ordinate of bounding rectangle</dd>
+<dt>sd:</dt>
+<dd>starting degrees of rotation</dd>
+<dt>ed:</dt>
+<dd>ending degrees of rotation</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawbezier">
+<h1><a class="toc-backref" href="#id233">DrawBezier</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawBezier( DrawingWand *drawing_wand, const unsigned long number_coordinates,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>DrawBezier() draws a bezier curve through a set of points on the image.</p>
+<p>The format of the DrawBezier method is:</p>
+<pre class="literal-block">
+void DrawBezier( DrawingWand *drawing_wand, const unsigned long number_coordinates,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>number_coordinates:</dt>
+<dd>number of coordinates</dd>
+<dt>coordinates:</dt>
+<dd>coordinates</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawcircle">
+<h1><a class="toc-backref" href="#id234">DrawCircle</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawCircle( DrawingWand *drawing_wand, const double ox, const double oy, const double px,
+ const double py );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>DrawCircle() draws a circle on the image.</p>
+<p>The format of the DrawCircle method is:</p>
+<pre class="literal-block">
+void DrawCircle( DrawingWand *drawing_wand, const double ox, const double oy, const double px,
+ const double py );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>ox:</dt>
+<dd>origin x ordinate</dd>
+<dt>oy:</dt>
+<dd>origin y ordinate</dd>
+<dt>px:</dt>
+<dd>perimeter x ordinate</dd>
+<dt>py:</dt>
+<dd>perimeter y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawclearexception">
+<h1><a class="toc-backref" href="#id235">DrawClearException</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail DrawClearException( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>DrawClearException() clears any existing exception from the drawing wand.</p>
+<p>The format of the DrawGetException method is:</p>
+<pre class="literal-block">
+MagickPassFail DrawClearException( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetclippath">
+<h1><a class="toc-backref" href="#id236">DrawGetClipPath</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetClipPath( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>DrawGetClipPath() obtains the current clipping path ID. The value returned
+must be deallocated by the user when it is no longer needed.</p>
+<p>The format of the DrawGetClipPath method is:</p>
+<pre class="literal-block">
+char *DrawGetClipPath( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetclippath">
+<h1><a class="toc-backref" href="#id237">DrawSetClipPath</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetClipPath( DrawingWand *drawing_wand, const char *clip_path );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>DrawSetClipPath() associates a named clipping path with the image. Only
+the areas drawn on by the clipping path will be modified as long as it
+remains in effect.</p>
+<p>The format of the DrawSetClipPath method is:</p>
+<pre class="literal-block">
+void DrawSetClipPath( DrawingWand *drawing_wand, const char *clip_path );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>clip_path:</dt>
+<dd>name of clipping path to associate with image</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetcliprule">
+<h1><a class="toc-backref" href="#id238">DrawGetClipRule</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#fillrule">FillRule</a> DrawGetClipRule( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>DrawGetClipRule() returns the current polygon fill rule to be used by the
+clipping path.</p>
+<p>The format of the DrawGetClipRule method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#fillrule">FillRule</a> DrawGetClipRule( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetcliprule">
+<h1><a class="toc-backref" href="#id239">DrawSetClipRule</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetClipRule( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#fillrule">FillRule</a> fill_rule );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>DrawSetClipRule() set the polygon fill rule to be used by the clipping path.</p>
+<p>The format of the DrawSetClipRule method is:</p>
+<pre class="literal-block">
+void DrawSetClipRule( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#fillrule">FillRule</a> fill_rule );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>fill_rule:</dt>
+<dd>fill rule (EvenOddRule or NonZeroRule)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetclipunits">
+<h1><a class="toc-backref" href="#id240">DrawGetClipUnits</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#clippathunits">ClipPathUnits</a> DrawGetClipUnits( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>DrawGetClipUnits() returns the interpretation of clip path units.</p>
+<p>The format of the DrawGetClipUnits method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#clippathunits">ClipPathUnits</a> DrawGetClipUnits( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetexception">
+<h1><a class="toc-backref" href="#id241">DrawGetException</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetException( const DrawingWand *drawing_wand, <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> *severity );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>DrawGetException() obtains error information associated with the last
+exception (if any). If an exception did occur, an allocated text string
+is returned which contains a detailed description of the exception. This
+string must be deallocated by the user once it is no longer needed.</p>
+<p>The format of the DrawGetException method is:</p>
+<pre class="literal-block">
+char *DrawGetException( const DrawingWand *drawing_wand, <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> *severity );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>severity:</dt>
+<dd>Enumeration corresponding to last thrown exception.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetclipunits">
+<h1><a class="toc-backref" href="#id242">DrawSetClipUnits</a></h1>
+<div class="section" id="id29">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetClipUnits( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#clippathunits">ClipPathUnits</a> clip_units );
+</pre>
+</div>
+<div class="section" id="id30">
+<h2>Description</h2>
+<p>DrawSetClipUnits() sets the interpretation of clip path units.</p>
+<p>The format of the DrawSetClipUnits method is:</p>
+<pre class="literal-block">
+void DrawSetClipUnits( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#clippathunits">ClipPathUnits</a> clip_units );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>clip_units:</dt>
+<dd>units to use (UserSpace, UserSpaceOnUse, or ObjectBoundingBox)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawcolor">
+<h1><a class="toc-backref" href="#id243">DrawColor</a></h1>
+<div class="section" id="id31">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawColor( DrawingWand *drawing_wand, const double x, const double y,
+ const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> paintMethod );
+</pre>
+</div>
+<div class="section" id="id32">
+<h2>Description</h2>
+<p>DrawColor() draws color on image using the current fill color, starting at
+specified position, and using specified paint method. The available paint
+methods are:</p>
+<p>PointMethod: Recolors the target pixel
+ReplaceMethod: Recolor any pixel that matches the target pixel.
+FloodfillMethod: Recolors target pixels and matching neighbors.
+FillToBorderMethod: Recolor target pixels and neighbors not matching
+ResetMethod: Recolor all pixels.</p>
+<p>The format of the DrawColor method is:</p>
+<pre class="literal-block">
+void DrawColor( DrawingWand *drawing_wand, const double x, const double y,
+ const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> paintMethod );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>x ordinate</dd>
+<dt>y:</dt>
+<dd>y ordinate</dd>
+<dt>paintMethod:</dt>
+<dd>paint method</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawcomment">
+<h1><a class="toc-backref" href="#id244">DrawComment</a></h1>
+<div class="section" id="id33">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawComment( DrawingWand *drawing_wand, const char *comment );
+</pre>
+</div>
+<div class="section" id="id34">
+<h2>Description</h2>
+<p>DrawComment() adds a comment to a vector output stream.</p>
+<p>The format of the DrawComment method is:</p>
+<pre class="literal-block">
+void DrawComment( DrawingWand *drawing_wand, const char *comment );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>comment:</dt>
+<dd>comment text</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawellipse">
+<h1><a class="toc-backref" href="#id245">DrawEllipse</a></h1>
+<div class="section" id="id35">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawEllipse( DrawingWand *drawing_wand, const double ox, const double oy, const double rx,
+ const double ry, const double start, const double end );
+</pre>
+</div>
+<div class="section" id="id36">
+<h2>Description</h2>
+<p>DrawEllipse() draws an ellipse on the image.</p>
+<p>The format of the DrawEllipse method is:</p>
+<pre class="literal-block">
+void DrawEllipse( DrawingWand *drawing_wand, const double ox, const double oy, const double rx,
+ const double ry, const double start, const double end );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>ox:</dt>
+<dd>origin x ordinate</dd>
+<dt>oy:</dt>
+<dd>origin y ordinate</dd>
+<dt>rx:</dt>
+<dd>radius in x</dd>
+<dt>ry:</dt>
+<dd>radius in y</dd>
+<dt>start:</dt>
+<dd>starting rotation in degrees</dd>
+<dt>end:</dt>
+<dd>ending rotation in degrees</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfillcolor">
+<h1><a class="toc-backref" href="#id246">DrawGetFillColor</a></h1>
+<div class="section" id="id37">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawGetFillColor( const DrawingWand *drawing_wand, PixelWand *fill_color );
+</pre>
+</div>
+<div class="section" id="id38">
+<h2>Description</h2>
+<p>DrawGetFillColor() returns the fill color used for drawing filled objects.</p>
+<p>The format of the DrawGetFillColor method is:</p>
+<pre class="literal-block">
+void DrawGetFillColor( const DrawingWand *drawing_wand, PixelWand *fill_color );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>fill_color:</dt>
+<dd>Return the fill color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillcolor">
+<h1><a class="toc-backref" href="#id247">DrawSetFillColor</a></h1>
+<div class="section" id="id39">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillColor( DrawingWand *drawing_wand, const PixelWand *fill_wand );
+</pre>
+</div>
+<div class="section" id="id40">
+<h2>Description</h2>
+<p>DrawSetFillColor() sets the fill color to be used for drawing filled objects.</p>
+<p>The format of the DrawSetFillColor method is:</p>
+<pre class="literal-block">
+void DrawSetFillColor( DrawingWand *drawing_wand, const PixelWand *fill_wand );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>fill_wand:</dt>
+<dd>fill wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillpatternurl">
+<h1><a class="toc-backref" href="#id248">DrawSetFillPatternURL</a></h1>
+<div class="section" id="id41">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillPatternURL( DrawingWand *drawing_wand, const char *fill_url );
+</pre>
+</div>
+<div class="section" id="id42">
+<h2>Description</h2>
+<p>DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
+objects. Only local URLs (&quot;#identifier&quot;) are supported at this time. These
+local URLs are normally created by defining a named fill pattern with
+DrawPushPattern/DrawPopPattern.</p>
+<p>The format of the DrawSetFillPatternURL method is:</p>
+<pre class="literal-block">
+void DrawSetFillPatternURL( DrawingWand *drawing_wand, const char *fill_url );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>fill_url:</dt>
+<dd>URL to use to obtain fill pattern.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfillopacity">
+<h1><a class="toc-backref" href="#id249">DrawGetFillOpacity</a></h1>
+<div class="section" id="id43">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetFillOpacity( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id44">
+<h2>Description</h2>
+<p>DrawGetFillOpacity() returns the opacity used when drawing using the fill
+color or fill texture. Fully opaque is 1.0.</p>
+<p>The format of the DrawGetFillOpacity method is:</p>
+<pre class="literal-block">
+double DrawGetFillOpacity( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillopacity">
+<h1><a class="toc-backref" href="#id250">DrawSetFillOpacity</a></h1>
+<div class="section" id="id45">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillOpacity( DrawingWand *drawing_wand, const double fill_opacity );
+</pre>
+</div>
+<div class="section" id="id46">
+<h2>Description</h2>
+<p>DrawSetFillOpacity() sets the opacity to use when drawing using the fill
+color or fill texture. Fully opaque is 1.0.</p>
+<p>The format of the DrawSetFillOpacity method is:</p>
+<pre class="literal-block">
+void DrawSetFillOpacity( DrawingWand *drawing_wand, const double fill_opacity );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>fill_opacity:</dt>
+<dd>fill opacity</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfillrule">
+<h1><a class="toc-backref" href="#id251">DrawGetFillRule</a></h1>
+<div class="section" id="id47">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#fillrule">FillRule</a> DrawGetFillRule( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id48">
+<h2>Description</h2>
+<p>DrawGetFillRule() returns the fill rule used while drawing polygons.</p>
+<p>The format of the DrawGetFillRule method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#fillrule">FillRule</a> DrawGetFillRule( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfillrule">
+<h1><a class="toc-backref" href="#id252">DrawSetFillRule</a></h1>
+<div class="section" id="id49">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFillRule( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#fillrule">FillRule</a> fill_rule );
+</pre>
+</div>
+<div class="section" id="id50">
+<h2>Description</h2>
+<p>DrawSetFillRule() sets the fill rule to use while drawing polygons.</p>
+<p>The format of the DrawSetFillRule method is:</p>
+<pre class="literal-block">
+void DrawSetFillRule( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#fillrule">FillRule</a> fill_rule );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>fill_rule:</dt>
+<dd>fill rule (EvenOddRule or NonZeroRule)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfont">
+<h1><a class="toc-backref" href="#id253">DrawGetFont</a></h1>
+<div class="section" id="id51">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetFont( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id52">
+<h2>Description</h2>
+<p>DrawGetFont() returns a null-terminaged string specifying the font used
+when annotating with text. The value returned must be freed by the user
+when no longer needed.</p>
+<p>The format of the DrawGetFont method is:</p>
+<pre class="literal-block">
+char *DrawGetFont( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfont">
+<h1><a class="toc-backref" href="#id254">DrawSetFont</a></h1>
+<div class="section" id="id53">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFont( DrawingWand *drawing_wand, const char *font_name );
+</pre>
+</div>
+<div class="section" id="id54">
+<h2>Description</h2>
+<p>DrawSetFont() sets the fully-sepecified font to use when annotating with
+text.</p>
+<p>The format of the DrawSetFont method is:</p>
+<pre class="literal-block">
+void DrawSetFont( DrawingWand *drawing_wand, const char *font_name );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>font_name:</dt>
+<dd>font name</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontfamily">
+<h1><a class="toc-backref" href="#id255">DrawGetFontFamily</a></h1>
+<div class="section" id="id55">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetFontFamily( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id56">
+<h2>Description</h2>
+<p>DrawGetFontFamily() returns the font family to use when annotating with text.
+The value returned must be freed by the user when it is no longer needed.</p>
+<p>The format of the DrawGetFontFamily method is:</p>
+<pre class="literal-block">
+char *DrawGetFontFamily( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontfamily">
+<h1><a class="toc-backref" href="#id256">DrawSetFontFamily</a></h1>
+<div class="section" id="id57">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontFamily( DrawingWand *drawing_wand, const char *font_family );
+</pre>
+</div>
+<div class="section" id="id58">
+<h2>Description</h2>
+<p>DrawSetFontFamily() sets the font family to use when annotating with text.</p>
+<p>The format of the DrawSetFontFamily method is:</p>
+<pre class="literal-block">
+void DrawSetFontFamily( DrawingWand *drawing_wand, const char *font_family );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>font_family:</dt>
+<dd>font family</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontsize">
+<h1><a class="toc-backref" href="#id257">DrawGetFontSize</a></h1>
+<div class="section" id="id59">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetFontSize( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id60">
+<h2>Description</h2>
+<p>DrawGetFontSize() returns the font pointsize used when annotating with text.</p>
+<p>The format of the DrawGetFontSize method is:</p>
+<pre class="literal-block">
+double DrawGetFontSize( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontsize">
+<h1><a class="toc-backref" href="#id258">DrawSetFontSize</a></h1>
+<div class="section" id="id61">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontSize( DrawingWand *drawing_wand, const double pointsize );
+</pre>
+</div>
+<div class="section" id="id62">
+<h2>Description</h2>
+<p>DrawSetFontSize() sets the font pointsize to use when annotating with text.</p>
+<p>The format of the DrawSetFontSize method is:</p>
+<pre class="literal-block">
+void DrawSetFontSize( DrawingWand *drawing_wand, const double pointsize );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>pointsize:</dt>
+<dd>text pointsize</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontstretch">
+<h1><a class="toc-backref" href="#id259">DrawGetFontStretch</a></h1>
+<div class="section" id="id63">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#stretchtype">StretchType</a> DrawGetFontStretch( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id64">
+<h2>Description</h2>
+<p>DrawGetFontStretch() returns the font stretch used when annotating with text.</p>
+<p>The format of the DrawGetFontStretch method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#stretchtype">StretchType</a> DrawGetFontStretch( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontstretch">
+<h1><a class="toc-backref" href="#id260">DrawSetFontStretch</a></h1>
+<div class="section" id="id65">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontStretch( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#stretchtype">StretchType</a> font_stretch );
+</pre>
+</div>
+<div class="section" id="id66">
+<h2>Description</h2>
+<p>DrawSetFontStretch() sets the font stretch to use when annotating with text.
+The AnyStretch enumeration acts as a wild-card &quot;don't care&quot; option.</p>
+<p>The format of the DrawSetFontStretch method is:</p>
+<pre class="literal-block">
+void DrawSetFontStretch( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#stretchtype">StretchType</a> font_stretch );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>font_stretch:</dt>
+<dd>font stretch (NormalStretch, UltraCondensedStretch,
+CondensedStretch, SemiCondensedStretch,
+SemiExpandedStretch, ExpandedStretch,
+ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontstyle">
+<h1><a class="toc-backref" href="#id261">DrawGetFontStyle</a></h1>
+<div class="section" id="id67">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#styletype">StyleType</a> DrawGetFontStyle( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id68">
+<h2>Description</h2>
+<p>DrawGetFontStyle() returns the font style used when annotating with text.</p>
+<p>The format of the DrawGetFontStyle method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#styletype">StyleType</a> DrawGetFontStyle( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontstyle">
+<h1><a class="toc-backref" href="#id262">DrawSetFontStyle</a></h1>
+<div class="section" id="id69">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontStyle( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#styletype">StyleType</a> style );
+</pre>
+</div>
+<div class="section" id="id70">
+<h2>Description</h2>
+<p>DrawSetFontStyle() sets the font style to use when annotating with text.
+The AnyStyle enumeration acts as a wild-card &quot;don't care&quot; option.</p>
+<p>The format of the DrawSetFontStyle method is:</p>
+<pre class="literal-block">
+void DrawSetFontStyle( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#styletype">StyleType</a> style );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>style:</dt>
+<dd>font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetfontweight">
+<h1><a class="toc-backref" href="#id263">DrawGetFontWeight</a></h1>
+<div class="section" id="id71">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long DrawGetFontWeight( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id72">
+<h2>Description</h2>
+<p>DrawGetFontWeight() returns the font weight used when annotating with text.</p>
+<p>The format of the DrawGetFontWeight method is:</p>
+<pre class="literal-block">
+unsigned long DrawGetFontWeight( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetfontweight">
+<h1><a class="toc-backref" href="#id264">DrawSetFontWeight</a></h1>
+<div class="section" id="id73">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetFontWeight( DrawingWand *drawing_wand, const unsigned long font_weight );
+</pre>
+</div>
+<div class="section" id="id74">
+<h2>Description</h2>
+<p>DrawSetFontWeight() sets the font weight to use when annotating with text.</p>
+<p>The format of the DrawSetFontWeight method is:</p>
+<pre class="literal-block">
+void DrawSetFontWeight( DrawingWand *drawing_wand, const unsigned long font_weight );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>font_weight:</dt>
+<dd>font weight (valid range 100-900)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetgravity">
+<h1><a class="toc-backref" href="#id265">DrawGetGravity</a></h1>
+<div class="section" id="id75">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#gravitytype">GravityType</a> DrawGetGravity( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id76">
+<h2>Description</h2>
+<p>DrawGetGravity() returns the text placement gravity used when annotating
+with text.</p>
+<p>The format of the DrawGetGravity method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#gravitytype">GravityType</a> DrawGetGravity( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetgravity">
+<h1><a class="toc-backref" href="#id266">DrawSetGravity</a></h1>
+<div class="section" id="id77">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetGravity( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#gravitytype">GravityType</a> gravity );
+</pre>
+</div>
+<div class="section" id="id78">
+<h2>Description</h2>
+<p>DrawSetGravity() sets the text placement gravity to use when annotating
+with text.</p>
+<p>The format of the DrawSetGravity method is:</p>
+<pre class="literal-block">
+void DrawSetGravity( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#gravitytype">GravityType</a> gravity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>gravity:</dt>
+<dd>positioning gravity (NorthWestGravity, NorthGravity,
+NorthEastGravity, WestGravity, CenterGravity,
+EastGravity, SouthWestGravity, SouthGravity,
+SouthEastGravity)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawcomposite">
+<h1><a class="toc-backref" href="#id267">DrawComposite</a></h1>
+<div class="section" id="id79">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawComposite( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> composite_operator,
+ const double x, const double y, const double width, const double height,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+</div>
+<div class="section" id="id80">
+<h2>Description</h2>
+<p>DrawComposite() composites an image onto the current image, using the
+specified composition operator, specified position, and at the specified
+size.</p>
+<p>The format of the DrawComposite method is:</p>
+<pre class="literal-block">
+void DrawComposite( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> composite_operator,
+ const double x, const double y, const double width, const double height,
+ const <a class="reference external" href="../api/types.html#image">Image</a> *image );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>composite_operator:</dt>
+<dd>composition operator</dd>
+<dt>x:</dt>
+<dd>x ordinate of top left corner</dd>
+<dt>y:</dt>
+<dd>y ordinate of top left corner</dd>
+<dt>width:</dt>
+<dd>Width to resize image to prior to compositing. Specify zero to
+use existing width.</dd>
+<dt>height:</dt>
+<dd>Height to resize image to prior to compositing. Specify zero
+to use existing height.</dd>
+<dt>image:</dt>
+<dd>Image to composite</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawline">
+<h1><a class="toc-backref" href="#id268">DrawLine</a></h1>
+<div class="section" id="id81">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawLine( DrawingWand *drawing_wand, const double sx, const double sy, const double ex,
+ const double ey );
+</pre>
+</div>
+<div class="section" id="id82">
+<h2>Description</h2>
+<p>DrawLine() draws a line on the image using the current stroke color,
+stroke opacity, and stroke width.</p>
+<p>The format of the DrawLine method is:</p>
+<pre class="literal-block">
+void DrawLine( DrawingWand *drawing_wand, const double sx, const double sy, const double ex,
+ const double ey );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>sx:</dt>
+<dd>starting x ordinate</dd>
+<dt>sy:</dt>
+<dd>starting y ordinate</dd>
+<dt>ex:</dt>
+<dd>ending x ordinate</dd>
+<dt>ey:</dt>
+<dd>ending y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawmatte">
+<h1><a class="toc-backref" href="#id269">DrawMatte</a></h1>
+<div class="section" id="id83">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawMatte( DrawingWand *drawing_wand, const double x, const double y,
+ const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> paint_method );
+</pre>
+</div>
+<div class="section" id="id84">
+<h2>Description</h2>
+<p>DrawMatte() paints on the image's opacity channel in order to set effected
+pixels to transparent.
+to influence the opacity of pixels. The available paint
+methods are:</p>
+<p>PointMethod: Select the target pixel
+ReplaceMethod: Select any pixel that matches the target pixel.
+FloodfillMethod: Select the target pixel and matching neighbors.
+FillToBorderMethod: Select the target pixel and neighbors not matching
+border color.
+ResetMethod: Select all pixels.</p>
+<p>The format of the DrawMatte method is:</p>
+<pre class="literal-block">
+void DrawMatte( DrawingWand *drawing_wand, const double x, const double y,
+ const <a class="reference external" href="../api/types.html#paintmethod">PaintMethod</a> paint_method );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>x ordinate</dd>
+<dt>y:</dt>
+<dd>y ordinate</dd>
+</dl>
+<p>o paint_method:</p>
+</div>
+</div>
+<div class="section" id="drawpathclose">
+<h1><a class="toc-backref" href="#id270">DrawPathClose</a></h1>
+<div class="section" id="id85">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathClose( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id86">
+<h2>Description</h2>
+<p>DrawPathClose() adds a path element to the current path which closes the
+current subpath by drawing a straight line from the current point to the
+current subpath's most recent starting point (usually, the most recent
+moveto point).</p>
+<p>The format of the DrawPathClose method is:</p>
+<pre class="literal-block">
+void DrawPathClose( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoabsolute">
+<h1><a class="toc-backref" href="#id271">DrawPathCurveToAbsolute</a></h1>
+<div class="section" id="id87">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToAbsolute( DrawingWand *drawing_wand, const double x1, const double y1,
+ const double x2, const double y2, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id88">
+<h2>Description</h2>
+<p>DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
+point to (x,y) using (x1,y1) as the control point at the beginning of
+the curve and (x2,y2) as the control point at the end of the curve using
+absolute coordinates. At the end of the command, the new current point
+becomes the final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToAbsolute( DrawingWand *drawing_wand, const double x1, const double y1,
+ const double x2, const double y2, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x1:</dt>
+<dd>x ordinate of control point for curve beginning</dd>
+<dt>y1:</dt>
+<dd>y ordinate of control point for curve beginning</dd>
+<dt>x2:</dt>
+<dd>x ordinate of control point for curve ending</dd>
+<dt>y2:</dt>
+<dd>y ordinate of control point for curve ending</dd>
+<dt>x:</dt>
+<dd>x ordinate of the end of the curve</dd>
+<dt>y:</dt>
+<dd>y ordinate of the end of the curve</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetorelative">
+<h1><a class="toc-backref" href="#id272">DrawPathCurveToRelative</a></h1>
+<div class="section" id="id89">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToRelative( DrawingWand *drawing_wand, const double x1, const double y1,
+ const double x2, const double y2, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id90">
+<h2>Description</h2>
+<p>DrawPathCurveToRelative() draws a cubic Bezier curve from the current
+point to (x,y) using (x1,y1) as the control point at the beginning of
+the curve and (x2,y2) as the control point at the end of the curve using
+relative coordinates. At the end of the command, the new current point
+becomes the final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToRelative method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToRelative( DrawingWand *drawing_wand, const double x1, const double y1,
+ const double x2, const double y2, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x1:</dt>
+<dd>x ordinate of control point for curve beginning</dd>
+<dt>y1:</dt>
+<dd>y ordinate of control point for curve beginning</dd>
+<dt>x2:</dt>
+<dd>x ordinate of control point for curve ending</dd>
+<dt>y2:</dt>
+<dd>y ordinate of control point for curve ending</dd>
+<dt>x:</dt>
+<dd>x ordinate of the end of the curve</dd>
+<dt>y:</dt>
+<dd>y ordinate of the end of the curve</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoquadraticbezierabsolute">
+<h1><a class="toc-backref" href="#id273">DrawPathCurveToQuadraticBezierAbsolute</a></h1>
+<div class="section" id="id91">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierAbsolute( DrawingWand *drawing_wand, const double x1,
+ const double y1, onst double x, const double y );
+</pre>
+</div>
+<div class="section" id="id92">
+<h2>Description</h2>
+<p>DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
+from the current point to (x,y) using (x1,y1) as the control point using
+absolute coordinates. At the end of the command, the new current point
+becomes the final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToQuadraticBezierAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierAbsolute( DrawingWand *drawing_wand, const double x1,
+ const double y1, onst double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x1:</dt>
+<dd>x ordinate of the control point</dd>
+<dt>y1:</dt>
+<dd>y ordinate of the control point</dd>
+<dt>x:</dt>
+<dd>x ordinate of final point</dd>
+<dt>y:</dt>
+<dd>y ordinate of final point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoquadraticbezierrelative">
+<h1><a class="toc-backref" href="#id274">DrawPathCurveToQuadraticBezierRelative</a></h1>
+<div class="section" id="id93">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierRelative( DrawingWand *drawing_wand, const double x1,
+ const double y1, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id94">
+<h2>Description</h2>
+<p>DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
+from the current point to (x,y) using (x1,y1) as the control point using
+relative coordinates. At the end of the command, the new current point
+becomes the final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToQuadraticBezierRelative method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierRelative( DrawingWand *drawing_wand, const double x1,
+ const double y1, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x1:</dt>
+<dd>x ordinate of the control point</dd>
+<dt>y1:</dt>
+<dd>y ordinate of the control point</dd>
+<dt>x:</dt>
+<dd>x ordinate of final point</dd>
+<dt>y:</dt>
+<dd>y ordinate of final point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoquadraticbeziersmoothabsolute">
+<h1><a class="toc-backref" href="#id275">DrawPathCurveToQuadraticBezierSmoothAbsolute</a></h1>
+<div class="section" id="id95">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierSmoothAbsolute( DrawingWand *drawing_wand, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id96">
+<h2>Description</h2>
+<p>DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
+Bezier curve (using absolute coordinates) from the current point to
+(x,y). The control point is assumed to be the reflection of the
+control point on the previous command relative to the current
+point. (If there is no previous command or if the previous command was
+not a DrawPathCurveToQuadraticBezierAbsolute,
+DrawPathCurveToQuadraticBezierRelative,
+DrawPathCurveToQuadraticBezierSmoothAbsolute or
+DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
+is coincident with the current point.). At the end of the command, the
+new current point becomes the final (x,y) coordinate pair used in the
+polybezier.</p>
+<p>The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierSmoothAbsolute( DrawingWand *drawing_wand, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>x ordinate of final point</dd>
+<dt>y:</dt>
+<dd>y ordinate of final point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetoquadraticbeziersmoothrelative">
+<h1><a class="toc-backref" href="#id276">DrawPathCurveToQuadraticBezierSmoothRelative</a></h1>
+<div class="section" id="id97">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierSmoothRelative( DrawingWand *drawing_wand, const double x,
+ const double y );
+</pre>
+</div>
+<div class="section" id="id98">
+<h2>Description</h2>
+<p>DrawPathCurveToQuadraticBezierSmoothRelative() draws a quadratic
+Bezier curve (using relative coordinates) from the current point to
+(x,y). The control point is assumed to be the reflection of the
+control point on the previous command relative to the current
+point. (If there is no previous command or if the previous command was
+not a DrawPathCurveToQuadraticBezierAbsolute,
+DrawPathCurveToQuadraticBezierRelative,
+DrawPathCurveToQuadraticBezierSmoothAbsolute or
+DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
+is coincident with the current point.). At the end of the command, the
+new current point becomes the final (x,y) coordinate pair used in the
+polybezier.</p>
+<p>The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToQuadraticBezierSmoothRelative( DrawingWand *drawing_wand, const double x,
+ const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>x ordinate of final point</dd>
+<dt>y:</dt>
+<dd>y ordinate of final point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetosmoothabsolute">
+<h1><a class="toc-backref" href="#id277">DrawPathCurveToSmoothAbsolute</a></h1>
+<div class="section" id="id99">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToSmoothAbsolute( DrawingWand *drawing_wand, const double x2const double y2,
+ const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id100">
+<h2>Description</h2>
+<p>DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
+current point to (x,y) using absolute coordinates. The first control
+point is assumed to be the reflection of the second control point on
+the previous command relative to the current point. (If there is no
+previous command or if the previous command was not an
+DrawPathCurveToAbsolute, DrawPathCurveToRelative,
+DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
+the first control point is coincident with the current point.) (x2,y2)
+is the second control point (i.e., the control point at the end of the
+curve). At the end of the command, the new current point becomes the
+final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToSmoothAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToSmoothAbsolute( DrawingWand *drawing_wand, const double x2const double y2,
+ const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x2:</dt>
+<dd>x ordinate of second control point</dd>
+<dt>y2:</dt>
+<dd>y ordinate of second control point</dd>
+<dt>x:</dt>
+<dd>x ordinate of termination point</dd>
+<dt>y:</dt>
+<dd>y ordinate of termination point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathcurvetosmoothrelative">
+<h1><a class="toc-backref" href="#id278">DrawPathCurveToSmoothRelative</a></h1>
+<div class="section" id="id101">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathCurveToSmoothRelative( DrawingWand *drawing_wand, const double x2,
+ const double y2, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id102">
+<h2>Description</h2>
+<p>DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the
+current point to (x,y) using relative coordinates. The first control
+point is assumed to be the reflection of the second control point on
+the previous command relative to the current point. (If there is no
+previous command or if the previous command was not an
+DrawPathCurveToAbsolute, DrawPathCurveToRelative,
+DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
+the first control point is coincident with the current point.) (x2,y2)
+is the second control point (i.e., the control point at the end of the
+curve). At the end of the command, the new current point becomes the
+final (x,y) coordinate pair used in the polybezier.</p>
+<p>The format of the DrawPathCurveToSmoothRelative method is:</p>
+<pre class="literal-block">
+void DrawPathCurveToSmoothRelative( DrawingWand *drawing_wand, const double x2,
+ const double y2, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x2:</dt>
+<dd>x ordinate of second control point</dd>
+<dt>y2:</dt>
+<dd>y ordinate of second control point</dd>
+<dt>x:</dt>
+<dd>x ordinate of termination point</dd>
+<dt>y:</dt>
+<dd>y ordinate of termination point</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathellipticarcabsolute">
+<h1><a class="toc-backref" href="#id279">DrawPathEllipticArcAbsolute</a></h1>
+<div class="section" id="id103">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathEllipticArcAbsolute( DrawingWand *drawing_wand, const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag, unsigned int sweep_flag,
+ const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id104">
+<h2>Description</h2>
+<p>DrawPathEllipticArcAbsolute() draws an elliptical arc from the current
+point to (x, y) using absolute coordinates. The size and orientation
+of the ellipse are defined by two radii (rx, ry) and an
+xAxisRotation, which indicates how the ellipse as a whole is rotated
+relative to the current coordinate system. The center (cx, cy) of the
+ellipse is calculated automatically to satisfy the constraints imposed
+by the other parameters. largeArcFlag and sweepFlag contribute to the
+automatic calculations and help determine how the arc is drawn. If
+largeArcFlag is true then draw the larger of the available arcs. If
+sweepFlag is true, then draw the arc matching a clock-wise rotation.</p>
+<p>The format of the DrawPathEllipticArcAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathEllipticArcAbsolute( DrawingWand *drawing_wand, const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag, unsigned int sweep_flag,
+ const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>rx:</dt>
+<dd>x radius</dd>
+<dt>ry:</dt>
+<dd>y radius</dd>
+<dt>x_axis_rotation:</dt>
+<dd>indicates how the ellipse as a whole is rotated
+relative to the current coordinate system</dd>
+<dt>large_arc_flag:</dt>
+<dd>If non-zero (true) then draw the larger of the
+available arcs</dd>
+<dt>sweep_flag:</dt>
+<dd>If non-zero (true) then draw the arc matching a
+clock-wise rotation</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathellipticarcrelative">
+<h1><a class="toc-backref" href="#id280">DrawPathEllipticArcRelative</a></h1>
+<div class="section" id="id105">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathEllipticArcRelative( DrawingWand *drawing_wand, const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag, unsigned int sweep_flag,
+ const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id106">
+<h2>Description</h2>
+<p>DrawPathEllipticArcRelative() draws an elliptical arc from the current
+point to (x, y) using relative coordinates. The size and orientation
+of the ellipse are defined by two radii (rx, ry) and an
+xAxisRotation, which indicates how the ellipse as a whole is rotated
+relative to the current coordinate system. The center (cx, cy) of the
+ellipse is calculated automatically to satisfy the constraints imposed
+by the other parameters. largeArcFlag and sweepFlag contribute to the
+automatic calculations and help determine how the arc is drawn. If
+largeArcFlag is true then draw the larger of the available arcs. If
+sweepFlag is true, then draw the arc matching a clock-wise rotation.</p>
+<p>The format of the DrawPathEllipticArcRelative method is:</p>
+<pre class="literal-block">
+void DrawPathEllipticArcRelative( DrawingWand *drawing_wand, const double rx, const double ry,
+ const double x_axis_rotation,
+ unsigned int large_arc_flag, unsigned int sweep_flag,
+ const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>rx:</dt>
+<dd>x radius</dd>
+<dt>ry:</dt>
+<dd>y radius</dd>
+<dt>x_axis_rotation:</dt>
+<dd>indicates how the ellipse as a whole is rotated
+relative to the current coordinate system</dd>
+<dt>large_arc_flag:</dt>
+<dd>If non-zero (true) then draw the larger of the
+available arcs</dd>
+<dt>sweep_flag:</dt>
+<dd>If non-zero (true) then draw the arc matching a
+clock-wise rotation</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathfinish">
+<h1><a class="toc-backref" href="#id281">DrawPathFinish</a></h1>
+<div class="section" id="id107">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathFinish( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id108">
+<h2>Description</h2>
+<p>DrawPathFinish() terminates the current path.</p>
+<p>The format of the DrawPathFinish method is:</p>
+<pre class="literal-block">
+void DrawPathFinish( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetoabsolute">
+<h1><a class="toc-backref" href="#id282">DrawPathLineToAbsolute</a></h1>
+<div class="section" id="id109">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToAbsolute( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id110">
+<h2>Description</h2>
+<p>DrawPathLineToAbsolute() draws a line path from the current point to the
+given coordinate using absolute coordinates. The coordinate then becomes
+the new current point.</p>
+<p>The format of the DrawPathLineToAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathLineToAbsolute( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetorelative">
+<h1><a class="toc-backref" href="#id283">DrawPathLineToRelative</a></h1>
+<div class="section" id="id111">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToRelative( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id112">
+<h2>Description</h2>
+<p>DrawPathLineToRelative() draws a line path from the current point to the
+given coordinate using relative coordinates. The coordinate then becomes
+the new current point.</p>
+<p>The format of the DrawPathLineToRelative method is:</p>
+<pre class="literal-block">
+void DrawPathLineToRelative( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetohorizontalabsolute">
+<h1><a class="toc-backref" href="#id284">DrawPathLineToHorizontalAbsolute</a></h1>
+<div class="section" id="id113">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToHorizontalAbsolute( DrawingWand *drawing_wand, const PathMode mode,
+ const double x );
+</pre>
+</div>
+<div class="section" id="id114">
+<h2>Description</h2>
+<p>DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
+current point to the target point using absolute coordinates. The target
+point then becomes the new current point.</p>
+<p>The format of the DrawPathLineToHorizontalAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathLineToHorizontalAbsolute( DrawingWand *drawing_wand, const PathMode mode,
+ const double x );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetohorizontalrelative">
+<h1><a class="toc-backref" href="#id285">DrawPathLineToHorizontalRelative</a></h1>
+<div class="section" id="id115">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToHorizontalRelative( DrawingWand *drawing_wand, const double x );
+</pre>
+</div>
+<div class="section" id="id116">
+<h2>Description</h2>
+<p>DrawPathLineToHorizontalRelative() draws a horizontal line path from the
+current point to the target point using relative coordinates. The target
+point then becomes the new current point.</p>
+<p>The format of the DrawPathLineToHorizontalRelative method is:</p>
+<pre class="literal-block">
+void DrawPathLineToHorizontalRelative( DrawingWand *drawing_wand, const double x );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetoverticalabsolute">
+<h1><a class="toc-backref" href="#id286">DrawPathLineToVerticalAbsolute</a></h1>
+<div class="section" id="id117">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToVerticalAbsolute( DrawingWand *drawing_wand, const double y );
+</pre>
+</div>
+<div class="section" id="id118">
+<h2>Description</h2>
+<p>DrawPathLineToVerticalAbsolute() draws a vertical line path from the
+current point to the target point using absolute coordinates. The target
+point then becomes the new current point.</p>
+<p>The format of the DrawPathLineToVerticalAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathLineToVerticalAbsolute( DrawingWand *drawing_wand, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathlinetoverticalrelative">
+<h1><a class="toc-backref" href="#id287">DrawPathLineToVerticalRelative</a></h1>
+<div class="section" id="id119">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathLineToVerticalRelative( DrawingWand *drawing_wand, const double y );
+</pre>
+</div>
+<div class="section" id="id120">
+<h2>Description</h2>
+<p>DrawPathLineToVerticalRelative() draws a vertical line path from the
+current point to the target point using relative coordinates. The target
+point then becomes the new current point.</p>
+<p>The format of the DrawPathLineToVerticalRelative method is:</p>
+<pre class="literal-block">
+void DrawPathLineToVerticalRelative( DrawingWand *drawing_wand, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathmovetoabsolute">
+<h1><a class="toc-backref" href="#id288">DrawPathMoveToAbsolute</a></h1>
+<div class="section" id="id121">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathMoveToAbsolute( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id122">
+<h2>Description</h2>
+<p>DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
+using absolute coordinates. The current point then becomes the
+specified coordinate.</p>
+<p>The format of the DrawPathMoveToAbsolute method is:</p>
+<pre class="literal-block">
+void DrawPathMoveToAbsolute( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathmovetorelative">
+<h1><a class="toc-backref" href="#id289">DrawPathMoveToRelative</a></h1>
+<div class="section" id="id123">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathMoveToRelative( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id124">
+<h2>Description</h2>
+<p>DrawPathMoveToRelative() starts a new sub-path at the given coordinate
+using relative coordinates. The current point then becomes the
+specified coordinate.</p>
+<p>The format of the DrawPathMoveToRelative method is:</p>
+<pre class="literal-block">
+void DrawPathMoveToRelative( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>target x ordinate</dd>
+<dt>y:</dt>
+<dd>target y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpathstart">
+<h1><a class="toc-backref" href="#id290">DrawPathStart</a></h1>
+<div class="section" id="id125">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPathStart( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id126">
+<h2>Description</h2>
+<p>DrawPathStart() declares the start of a path drawing list which is terminated
+by a matching DrawPathFinish() command. All other DrawPath commands must
+be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
+is because path drawing commands are subordinate commands and they do not
+function by themselves.</p>
+<p>The format of the DrawPathStart method is:</p>
+<pre class="literal-block">
+void DrawPathStart( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpeekgraphiccontext">
+<h1><a class="toc-backref" href="#id291">DrawPeekGraphicContext</a></h1>
+<div class="section" id="id127">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *DrawPeekGraphicContext( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id128">
+<h2>Description</h2>
+<p>DrawPeekGraphicContext() returns the current graphic drawing_wand.</p>
+<p>The format of the DrawPeekGraphicContext method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#drawinfo">DrawInfo</a> *DrawPeekGraphicContext( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpoint">
+<h1><a class="toc-backref" href="#id292">DrawPoint</a></h1>
+<div class="section" id="id129">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPoint( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id130">
+<h2>Description</h2>
+<p>DrawPoint() draws a point using the current stroke color and stroke
+thickness at the specified coordinates.</p>
+<p>The format of the DrawPoint method is:</p>
+<pre class="literal-block">
+void DrawPoint( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>target x coordinate</dd>
+<dt>y:</dt>
+<dd>target y coordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpolygon">
+<h1><a class="toc-backref" href="#id293">DrawPolygon</a></h1>
+<div class="section" id="id131">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPolygon( DrawingWand *drawing_wand, const unsigned long number_coordinates,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+</div>
+<div class="section" id="id132">
+<h2>Description</h2>
+<p>DrawPolygon() draws a polygon using the current stroke, stroke width, and
+fill color or texture, using the specified array of coordinates.</p>
+<p>The format of the DrawPolygon method is:</p>
+<pre class="literal-block">
+void DrawPolygon( DrawingWand *drawing_wand, const unsigned long number_coordinates,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>number_coordinates:</dt>
+<dd>number of coordinates</dd>
+<dt>coordinates:</dt>
+<dd>coordinate array</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpolyline">
+<h1><a class="toc-backref" href="#id294">DrawPolyline</a></h1>
+<div class="section" id="id133">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPolyline( DrawingWand *drawing_wand, const unsigned long number_coordinates,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+</div>
+<div class="section" id="id134">
+<h2>Description</h2>
+<p>DrawPolyline() draws a polyline using the current stroke, stroke width, and
+fill color or texture, using the specified array of coordinates.</p>
+<p>The format of the DrawPolyline method is:</p>
+<pre class="literal-block">
+void DrawPolyline( DrawingWand *drawing_wand, const unsigned long number_coordinates,
+ const <a class="reference external" href="../api/types.html#pointinfo">PointInfo</a> *coordinates );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>number_coordinates:</dt>
+<dd>number of coordinates</dd>
+<dt>coordinates:</dt>
+<dd>coordinate array</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpopclippath">
+<h1><a class="toc-backref" href="#id295">DrawPopClipPath</a></h1>
+<div class="section" id="id135">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPopClipPath( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id136">
+<h2>Description</h2>
+<p>DrawPopClipPath() terminates a clip path definition.</p>
+<p>The format of the DrawPopClipPath method is:</p>
+<pre class="literal-block">
+void DrawPopClipPath( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpopdefs">
+<h1><a class="toc-backref" href="#id296">DrawPopDefs</a></h1>
+<div class="section" id="id137">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPopDefs( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id138">
+<h2>Description</h2>
+<p>DrawPopDefs() terminates a definition list</p>
+<p>The format of the DrawPopDefs method is:</p>
+<pre class="literal-block">
+void DrawPopDefs( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpopgraphiccontext">
+<h1><a class="toc-backref" href="#id297">DrawPopGraphicContext</a></h1>
+<div class="section" id="id139">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPopGraphicContext( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id140">
+<h2>Description</h2>
+<p>DrawPopGraphicContext() destroys the current drawing_wand returning to the
+previously pushed drawing wand. Multiple drawing wand may exist. It is an
+error to attempt to pop more drawing_wands than have been pushed, and it is
+proper form to pop all drawing_wands which have been pushed.</p>
+<p>The format of the DrawPopGraphicContext method is:</p>
+<pre class="literal-block">
+void DrawPopGraphicContext( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpoppattern">
+<h1><a class="toc-backref" href="#id298">DrawPopPattern</a></h1>
+<div class="section" id="id141">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPopPattern( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id142">
+<h2>Description</h2>
+<p>DrawPopPattern() terminates a pattern definition.</p>
+<p>The format of the DrawPopPattern method is:</p>
+<pre class="literal-block">
+void DrawPopPattern( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpushclippath">
+<h1><a class="toc-backref" href="#id299">DrawPushClipPath</a></h1>
+<div class="section" id="id143">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPushClipPath( DrawingWand *drawing_wand, const char *clip_path_id );
+</pre>
+</div>
+<div class="section" id="id144">
+<h2>Description</h2>
+<p>DrawPushClipPath() starts a clip path definition which is comprized of
+any number of drawing commands and terminated by a DrawPopClipPath()
+command.</p>
+<p>The format of the DrawPushClipPath method is:</p>
+<pre class="literal-block">
+void DrawPushClipPath( DrawingWand *drawing_wand, const char *clip_path_id );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>clip_path_id:</dt>
+<dd>string identifier to associate with the clip path for
+later use.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpushdefs">
+<h1><a class="toc-backref" href="#id300">DrawPushDefs</a></h1>
+<div class="section" id="id145">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPushDefs( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id146">
+<h2>Description</h2>
+<p>DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
+command create named elements (e.g. clip-paths, textures, etc.) which
+may safely be processed earlier for the sake of efficiency.</p>
+<p>The format of the DrawPushDefs method is:</p>
+<pre class="literal-block">
+void DrawPushDefs( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpushgraphiccontext">
+<h1><a class="toc-backref" href="#id301">DrawPushGraphicContext</a></h1>
+<div class="section" id="id147">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPushGraphicContext( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id148">
+<h2>Description</h2>
+<p>DrawPushGraphicContext() clones the current drawing wand to create a
+new drawing wand. The original drawing drawing_wand(s) may be returned to
+by invoking DrawPopGraphicContext(). The drawing wands are stored on a
+drawing wand stack. For every Pop there must have already been an
+equivalent Push.</p>
+<p>The format of the DrawPushGraphicContext method is:</p>
+<pre class="literal-block">
+void DrawPushGraphicContext( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawpushpattern">
+<h1><a class="toc-backref" href="#id302">DrawPushPattern</a></h1>
+<div class="section" id="id149">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawPushPattern( DrawingWand *drawing_wand, const char *pattern_id, const double x,
+ const double y, const double width, const double height );
+</pre>
+</div>
+<div class="section" id="id150">
+<h2>Description</h2>
+<p>DrawPushPattern() indicates that subsequent commands up to a
+DrawPopPattern() command comprise the definition of a named pattern.
+The pattern space is assigned top left corner coordinates, a width
+and height, and becomes its own drawing space. Anything which can
+be drawn may be used in a pattern definition.
+Named patterns may be used as stroke or brush definitions.</p>
+<p>The format of the DrawPushPattern method is:</p>
+<pre class="literal-block">
+void DrawPushPattern( DrawingWand *drawing_wand, const char *pattern_id, const double x,
+ const double y, const double width, const double height );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>pattern_id:</dt>
+<dd>pattern identification for later reference</dd>
+<dt>x:</dt>
+<dd>x ordinate of top left corner</dd>
+<dt>y:</dt>
+<dd>y ordinate of top left corner</dd>
+<dt>width:</dt>
+<dd>width of pattern space</dd>
+<dt>height:</dt>
+<dd>height of pattern space</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawrectangle">
+<h1><a class="toc-backref" href="#id303">DrawRectangle</a></h1>
+<div class="section" id="id151">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawRectangle( DrawingWand *drawing_wand, const double x1, const double y1,
+ const double x2, const double y2 );
+</pre>
+</div>
+<div class="section" id="id152">
+<h2>Description</h2>
+<p>DrawRectangle() draws a rectangle given two coordinates and using
+the current stroke, stroke width, and fill settings.</p>
+<p>The format of the DrawRectangle method is:</p>
+<pre class="literal-block">
+void DrawRectangle( DrawingWand *drawing_wand, const double x1, const double y1,
+ const double x2, const double y2 );
+</pre>
+<dl class="docutils">
+<dt>x1:</dt>
+<dd>x ordinate of first coordinate</dd>
+<dt>y1:</dt>
+<dd>y ordinate of first coordinate</dd>
+<dt>x2:</dt>
+<dd>x ordinate of second coordinate</dd>
+<dt>y2:</dt>
+<dd>y ordinate of second coordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawrender">
+<h1><a class="toc-backref" href="#id304">DrawRender</a></h1>
+<div class="section" id="id153">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DrawRender( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id154">
+<h2>Description</h2>
+<p>DrawRender() renders all preceding drawing commands onto the image.
+This function is deprecated. Use MagickDrawImage() instead.</p>
+<p>The format of the DrawRender method is:</p>
+<pre class="literal-block">
+unsigned int DrawRender( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawrotate">
+<h1><a class="toc-backref" href="#id305">DrawRotate</a></h1>
+<div class="section" id="id155">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawRotate( DrawingWand *drawing_wand, const double degrees );
+</pre>
+</div>
+<div class="section" id="id156">
+<h2>Description</h2>
+<p>DrawRotate() applies the specified rotation to the current coordinate space.</p>
+<p>The format of the DrawRotate method is:</p>
+<pre class="literal-block">
+void DrawRotate( DrawingWand *drawing_wand, const double degrees );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>degrees:</dt>
+<dd>degrees of rotation</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawroundrectangle">
+<h1><a class="toc-backref" href="#id306">DrawRoundRectangle</a></h1>
+<div class="section" id="id157">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawRoundRectangle( DrawingWand *drawing_wand, double x1, double y1, double x2, double y2,
+ double rx, double ry );
+</pre>
+</div>
+<div class="section" id="id158">
+<h2>Description</h2>
+<p>DrawRoundRectangle() draws a rounted rectangle given two coordinates,
+x &amp; y corner radiuses and using the current stroke, stroke width,
+and fill settings.</p>
+<p>The format of the DrawRoundRectangle method is:</p>
+<pre class="literal-block">
+void DrawRoundRectangle( DrawingWand *drawing_wand, double x1, double y1, double x2, double y2,
+ double rx, double ry );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x1:</dt>
+<dd>x ordinate of first coordinate</dd>
+<dt>y1:</dt>
+<dd>y ordinate of first coordinate</dd>
+<dt>x2:</dt>
+<dd>x ordinate of second coordinate</dd>
+<dt>y2:</dt>
+<dd>y ordinate of second coordinate</dd>
+<dt>rx:</dt>
+<dd>radius of corner in horizontal direction</dd>
+<dt>ry:</dt>
+<dd>radius of corner in vertical direction</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawscale">
+<h1><a class="toc-backref" href="#id307">DrawScale</a></h1>
+<div class="section" id="id159">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawScale( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id160">
+<h2>Description</h2>
+<p>DrawScale() adjusts the scaling factor to apply in the horizontal and
+vertical directions to the current coordinate space.</p>
+<p>The format of the DrawScale method is:</p>
+<pre class="literal-block">
+void DrawScale( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>horizontal scale factor</dd>
+<dt>y:</dt>
+<dd>vertical scale factor</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawskewx">
+<h1><a class="toc-backref" href="#id308">DrawSkewX</a></h1>
+<div class="section" id="id161">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSkewX( DrawingWand *drawing_wand, const double degrees );
+</pre>
+</div>
+<div class="section" id="id162">
+<h2>Description</h2>
+<p>DrawSkewX() skews the current coordinate system in the horizontal
+direction.</p>
+<p>The format of the DrawSkewX method is:</p>
+<pre class="literal-block">
+void DrawSkewX( DrawingWand *drawing_wand, const double degrees );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>degrees:</dt>
+<dd>number of degrees to skew the coordinates</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawskewy">
+<h1><a class="toc-backref" href="#id309">DrawSkewY</a></h1>
+<div class="section" id="id163">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSkewY( DrawingWand *drawing_wand, const double degrees );
+</pre>
+</div>
+<div class="section" id="id164">
+<h2>Description</h2>
+<p>DrawSkewY() skews the current coordinate system in the vertical
+direction.</p>
+<p>The format of the DrawSkewY method is:</p>
+<pre class="literal-block">
+void DrawSkewY( DrawingWand *drawing_wand, const double degrees );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>degrees:</dt>
+<dd>number of degrees to skew the coordinates</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstopcolor">
+<h1><a class="toc-backref" href="#id310">DrawSetStopColor</a></h1>
+<div class="section" id="id165">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStopColor( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *stop_color,
+ const double offset );
+</pre>
+</div>
+<div class="section" id="id166">
+<h2>Description</h2>
+<p>DrawSetStopColor() sets the stop color and offset for gradients</p>
+<p>The format of the DrawSetStopColor method is:</p>
+<pre class="literal-block">
+void DrawSetStopColor( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *stop_color,
+ const double offset );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+<p>o stop_color:</p>
+<p>o offset:</p>
+</div>
+</div>
+<div class="section" id="drawgetstrokecolor">
+<h1><a class="toc-backref" href="#id311">DrawGetStrokeColor</a></h1>
+<div class="section" id="id167">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawGetStrokeColor( const DrawingWand *drawing_wand, ;
+</pre>
+</div>
+<div class="section" id="id168">
+<h2>Description</h2>
+<p>DrawGetStrokeColor() returns the color used for stroking object outlines.</p>
+<p>The format of the DrawGetStrokeColor method is:</p>
+<pre class="literal-block">
+void DrawGetStrokeColor( const DrawingWand *drawing_wand, ;
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>stroke_color:</dt>
+<dd>Return the stroke color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokecolor">
+<h1><a class="toc-backref" href="#id312">DrawSetStrokeColor</a></h1>
+<div class="section" id="id169">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeColor( DrawingWand *drawing_wand, const PixelWand *stroke_wand );
+</pre>
+</div>
+<div class="section" id="id170">
+<h2>Description</h2>
+<p>DrawSetStrokeColor() sets the color used for stroking object outlines.</p>
+<p>The format of the DrawSetStrokeColor method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeColor( DrawingWand *drawing_wand, const PixelWand *stroke_wand );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>stroke_wand:</dt>
+<dd>stroke wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokepatternurl">
+<h1><a class="toc-backref" href="#id313">DrawSetStrokePatternURL</a></h1>
+<div class="section" id="id171">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokePatternURL( DrawingWand *drawing_wand, const char *stroke_url );
+</pre>
+</div>
+<div class="section" id="id172">
+<h2>Description</h2>
+<p>DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.</p>
+<p>The format of the DrawSetStrokePatternURL method is:</p>
+<pre class="literal-block">
+void DrawSetStrokePatternURL( DrawingWand *drawing_wand, const char *stroke_url );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>stroke_url:</dt>
+<dd>URL specifying pattern ID (e.g. &quot;#pattern_id&quot;)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokeantialias">
+<h1><a class="toc-backref" href="#id314">DrawGetStrokeAntialias</a></h1>
+<div class="section" id="id173">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DrawGetStrokeAntialias( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id174">
+<h2>Description</h2>
+<p>DrawGetStrokeAntialias() returns the current stroke antialias setting.
+Stroked outlines are antialiased by default. When antialiasing is disabled
+stroked pixels are thresholded to determine if the stroke color or
+underlying canvas color should be used.</p>
+<p>The format of the DrawGetStrokeAntialias method is:</p>
+<pre class="literal-block">
+unsigned int DrawGetStrokeAntialias( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokeantialias">
+<h1><a class="toc-backref" href="#id315">DrawSetStrokeAntialias</a></h1>
+<div class="section" id="id175">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeAntialias( DrawingWand *drawing_wand,
+ const unsigned int stroke_antialias );
+</pre>
+</div>
+<div class="section" id="id176">
+<h2>Description</h2>
+<p>DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
+Stroked outlines are antialiased by default. When antialiasing is disabled
+stroked pixels are thresholded to determine if the stroke color or
+underlying canvas color should be used.</p>
+<p>The format of the DrawSetStrokeAntialias method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeAntialias( DrawingWand *drawing_wand,
+ const unsigned int stroke_antialias );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>stroke_antialias:</dt>
+<dd>set to false (zero) to disable antialiasing</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokedasharray">
+<h1><a class="toc-backref" href="#id316">DrawGetStrokeDashArray</a></h1>
+<div class="section" id="id177">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double *DrawGetStrokeDashArray( const DrawingWand *drawing_wand,
+ unsigned long *number_elements );
+</pre>
+</div>
+<div class="section" id="id178">
+<h2>Description</h2>
+<p>DrawGetStrokeDashArray() returns an array representing the pattern of
+dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
+array must be freed once it is no longer required by the user.</p>
+<p>The format of the DrawGetStrokeDashArray method is:</p>
+<pre class="literal-block">
+double *DrawGetStrokeDashArray( const DrawingWand *drawing_wand,
+ unsigned long *number_elements );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>number_elements:</dt>
+<dd>address to place number of elements in dash array</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokedasharray">
+<h1><a class="toc-backref" href="#id317">DrawSetStrokeDashArray</a></h1>
+<div class="section" id="id179">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeDashArray( DrawingWand *drawing_wand, const unsigned long number_elements,
+ const double *dash_array );
+</pre>
+</div>
+<div class="section" id="id180">
+<h2>Description</h2>
+<p>DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
+stroke paths. The stroke dash array represents an array of numbers that
+specify the lengths of alternating dashes and gaps in pixels. If an odd
+number of values is provided, then the list of values is repeated to yield
+an even number of values. To remove an existing dash array, pass a zero
+number_elements argument and null dash_array.
+A typical stroke dash array might contain the members 5 3 2.</p>
+<p>The format of the DrawSetStrokeDashArray method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeDashArray( DrawingWand *drawing_wand, const unsigned long number_elements,
+ const double *dash_array );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>number_elements:</dt>
+<dd>number of elements in dash array</dd>
+<dt>dash_array:</dt>
+<dd>dash array values</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokedashoffset">
+<h1><a class="toc-backref" href="#id318">DrawGetStrokeDashOffset</a></h1>
+<div class="section" id="id181">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetStrokeDashOffset( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id182">
+<h2>Description</h2>
+<p>DrawGetStrokeDashOffset() returns the offset into the dash pattern to
+start the dash.</p>
+<p>The format of the DrawGetStrokeDashOffset method is:</p>
+<pre class="literal-block">
+double DrawGetStrokeDashOffset( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokedashoffset">
+<h1><a class="toc-backref" href="#id319">DrawSetStrokeDashOffset</a></h1>
+<div class="section" id="id183">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeDashOffset( DrawingWand *drawing_wand, const double dash_offset );
+</pre>
+</div>
+<div class="section" id="id184">
+<h2>Description</h2>
+<p>DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
+start the dash.</p>
+<p>The format of the DrawSetStrokeDashOffset method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeDashOffset( DrawingWand *drawing_wand, const double dash_offset );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>dash_offset:</dt>
+<dd>dash offset</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokelinecap">
+<h1><a class="toc-backref" href="#id320">DrawGetStrokeLineCap</a></h1>
+<div class="section" id="id185">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+LineCap DrawGetStrokeLineCap( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id186">
+<h2>Description</h2>
+<p>DrawGetStrokeLineCap() returns the shape to be used at the end of
+open subpaths when they are stroked. Values of LineCap are
+UndefinedCap, ButtCap, RoundCap, and SquareCap.</p>
+<p>The format of the DrawGetStrokeLineCap method is:</p>
+<pre class="literal-block">
+LineCap DrawGetStrokeLineCap( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokelinecap">
+<h1><a class="toc-backref" href="#id321">DrawSetStrokeLineCap</a></h1>
+<div class="section" id="id187">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeLineCap( DrawingWand *drawing_wand, const LineCap linecap );
+</pre>
+</div>
+<div class="section" id="id188">
+<h2>Description</h2>
+<p>DrawSetStrokeLineCap() specifies the shape to be used at the end of
+open subpaths when they are stroked. Values of LineCap are
+UndefinedCap, ButtCap, RoundCap, and SquareCap.</p>
+<p>The format of the DrawSetStrokeLineCap method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeLineCap( DrawingWand *drawing_wand, const LineCap linecap );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>linecap:</dt>
+<dd>linecap style</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokelinejoin">
+<h1><a class="toc-backref" href="#id322">DrawGetStrokeLineJoin</a></h1>
+<div class="section" id="id189">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+LineJoin DrawGetStrokeLineJoin( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id190">
+<h2>Description</h2>
+<p>DrawGetStrokeLineJoin() returns the shape to be used at the
+corners of paths (or other vector shapes) when they are
+stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
+and BevelJoin.</p>
+<p>The format of the DrawGetStrokeLineJoin method is:</p>
+<pre class="literal-block">
+LineJoin DrawGetStrokeLineJoin( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokelinejoin">
+<h1><a class="toc-backref" href="#id323">DrawSetStrokeLineJoin</a></h1>
+<div class="section" id="id191">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeLineJoin( DrawingWand *drawing_wand, const LineJoin linejoin );
+</pre>
+</div>
+<div class="section" id="id192">
+<h2>Description</h2>
+<p>DrawSetStrokeLineJoin() specifies the shape to be used at the
+corners of paths (or other vector shapes) when they are
+stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
+and BevelJoin.</p>
+<p>The format of the DrawSetStrokeLineJoin method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeLineJoin( DrawingWand *drawing_wand, const LineJoin linejoin );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>linejoin:</dt>
+<dd>line join style</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokemiterlimit">
+<h1><a class="toc-backref" href="#id324">DrawGetStrokeMiterLimit</a></h1>
+<div class="section" id="id193">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long DrawGetStrokeMiterLimit( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id194">
+<h2>Description</h2>
+<p>DrawGetStrokeMiterLimit() returns the miter limit. When two line
+segments meet at a sharp angle and miter joins have been specified for
+'lineJoin', it is possible for the miter to extend far beyond the
+thickness of the line stroking the path. The miterLimit' imposes a
+limit on the ratio of the miter length to the 'lineWidth'.</p>
+<p>The format of the DrawGetStrokeMiterLimit method is:</p>
+<pre class="literal-block">
+unsigned long DrawGetStrokeMiterLimit( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokemiterlimit">
+<h1><a class="toc-backref" href="#id325">DrawSetStrokeMiterLimit</a></h1>
+<div class="section" id="id195">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeMiterLimit( DrawingWand *drawing_wand, const unsigned long miterlimit );
+</pre>
+</div>
+<div class="section" id="id196">
+<h2>Description</h2>
+<p>DrawSetStrokeMiterLimit() specifies the miter limit. When two line
+segments meet at a sharp angle and miter joins have been specified for
+'lineJoin', it is possible for the miter to extend far beyond the
+thickness of the line stroking the path. The miterLimit' imposes a
+limit on the ratio of the miter length to the 'lineWidth'.</p>
+<p>The format of the DrawSetStrokeMiterLimit method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeMiterLimit( DrawingWand *drawing_wand, const unsigned long miterlimit );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>miterlimit:</dt>
+<dd>miter limit</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokeopacity">
+<h1><a class="toc-backref" href="#id326">DrawGetStrokeOpacity</a></h1>
+<div class="section" id="id197">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetStrokeOpacity( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id198">
+<h2>Description</h2>
+<p>DrawGetStrokeOpacity() returns the opacity of stroked object outlines.</p>
+<p>The format of the DrawGetStrokeOpacity method is:</p>
+<pre class="literal-block">
+double DrawGetStrokeOpacity( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokeopacity">
+<h1><a class="toc-backref" href="#id327">DrawSetStrokeOpacity</a></h1>
+<div class="section" id="id199">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeOpacity( DrawingWand *drawing_wand, const double stroke_opacity );
+</pre>
+</div>
+<div class="section" id="id200">
+<h2>Description</h2>
+<p>DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.</p>
+<p>The format of the DrawSetStrokeOpacity method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeOpacity( DrawingWand *drawing_wand, const double stroke_opacity );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>stroke_opacity:</dt>
+<dd>stroke opacity. The value 1.0 is opaque.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgetstrokewidth">
+<h1><a class="toc-backref" href="#id328">DrawGetStrokeWidth</a></h1>
+<div class="section" id="id201">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double DrawGetStrokeWidth( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id202">
+<h2>Description</h2>
+<p>DrawGetStrokeWidth() returns the width of the stroke used to draw object
+outlines.</p>
+<p>The format of the DrawGetStrokeWidth method is:</p>
+<pre class="literal-block">
+double DrawGetStrokeWidth( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetstrokewidth">
+<h1><a class="toc-backref" href="#id329">DrawSetStrokeWidth</a></h1>
+<div class="section" id="id203">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetStrokeWidth( DrawingWand *drawing_wand, const double stroke_width );
+</pre>
+</div>
+<div class="section" id="id204">
+<h2>Description</h2>
+<p>DrawSetStrokeWidth() sets the width of the stroke used to draw object
+outlines.</p>
+<p>The format of the DrawSetStrokeWidth method is:</p>
+<pre class="literal-block">
+void DrawSetStrokeWidth( DrawingWand *drawing_wand, const double stroke_width );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>stroke_width:</dt>
+<dd>stroke width</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgettextantialias">
+<h1><a class="toc-backref" href="#id330">DrawGetTextAntialias</a></h1>
+<div class="section" id="id205">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DrawGetTextAntialias( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id206">
+<h2>Description</h2>
+<p>DrawGetTextAntialias() returns the current text antialias setting, which
+determines whether text is antialiased. Text is antialiased by default.</p>
+<p>The format of the DrawGetTextAntialias method is:</p>
+<pre class="literal-block">
+unsigned int DrawGetTextAntialias( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextantialias">
+<h1><a class="toc-backref" href="#id331">DrawSetTextAntialias</a></h1>
+<div class="section" id="id207">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextAntialias( DrawingWand *drawing_wand, const unsigned int text_antialias );
+</pre>
+</div>
+<div class="section" id="id208">
+<h2>Description</h2>
+<p>DrawSetTextAntialias() controls whether text is antialiased. Text is
+antialiased by default.</p>
+<p>The format of the DrawSetTextAntialias method is:</p>
+<pre class="literal-block">
+void DrawSetTextAntialias( DrawingWand *drawing_wand, const unsigned int text_antialias );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>text_antialias:</dt>
+<dd>antialias boolean. Set to false (0) to disable
+antialiasing.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgettextdecoration">
+<h1><a class="toc-backref" href="#id332">DrawGetTextDecoration</a></h1>
+<div class="section" id="id209">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#decorationtype">DecorationType</a> DrawGetTextDecoration( DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id210">
+<h2>Description</h2>
+<p>DrawGetTextDecoration() returns the decoration applied when annotating with
+text.</p>
+<p>The format of the DrawGetTextDecoration method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#decorationtype">DecorationType</a> DrawGetTextDecoration( DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextdecoration">
+<h1><a class="toc-backref" href="#id333">DrawSetTextDecoration</a></h1>
+<div class="section" id="id211">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextDecoration( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#decorationtype">DecorationType</a> decoration );
+</pre>
+</div>
+<div class="section" id="id212">
+<h2>Description</h2>
+<p>DrawSetTextDecoration() specifies a decoration to be applied when
+annotating with text.</p>
+<p>The format of the DrawSetTextDecoration method is:</p>
+<pre class="literal-block">
+void DrawSetTextDecoration( DrawingWand *drawing_wand, const <a class="reference external" href="../api/types.html#decorationtype">DecorationType</a> decoration );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>decoration:</dt>
+<dd>text decoration. One of NoDecoration, UnderlineDecoration,
+OverlineDecoration, or LineThroughDecoration</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgettextencoding">
+<h1><a class="toc-backref" href="#id334">DrawGetTextEncoding</a></h1>
+<div class="section" id="id213">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *DrawGetTextEncoding( const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id214">
+<h2>Description</h2>
+<p>DrawGetTextEncoding() returns a null-terminated string which specifies the
+code set used for text annotations. The string must be freed by the user
+once it is no longer required.</p>
+<p>The format of the DrawGetTextEncoding method is:</p>
+<pre class="literal-block">
+char *DrawGetTextEncoding( const DrawingWand *drawing_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextencoding">
+<h1><a class="toc-backref" href="#id335">DrawSetTextEncoding</a></h1>
+<div class="section" id="id215">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextEncoding( DrawingWand *drawing_wand, const char *encoding );
+</pre>
+</div>
+<div class="section" id="id216">
+<h2>Description</h2>
+<p>DrawSetTextEncoding() specifies specifies the code set to use for
+text annotations. The only character encoding which may be specified
+at this time is &quot;UTF-8&quot; for representing Unicode as a sequence of
+bytes. Specify an empty string to set text encoding to the system's
+default. Successful text annotation using Unicode may require fonts
+designed to support Unicode.</p>
+<p>The format of the DrawSetTextEncoding method is:</p>
+<pre class="literal-block">
+void DrawSetTextEncoding( DrawingWand *drawing_wand, const char *encoding );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>encoding:</dt>
+<dd>character string specifying text encoding</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawgettextundercolor">
+<h1><a class="toc-backref" href="#id336">DrawGetTextUnderColor</a></h1>
+<div class="section" id="id217">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawGetTextUnderColor( const DrawingWand *drawing_wand, PixelWand *under_color );
+</pre>
+</div>
+<div class="section" id="id218">
+<h2>Description</h2>
+<p>DrawGetTextUnderColor() returns the color of a background rectangle
+to place under text annotations.</p>
+<p>The format of the DrawGetTextUnderColor method is:</p>
+<pre class="literal-block">
+void DrawGetTextUnderColor( const DrawingWand *drawing_wand, PixelWand *under_color );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>under_color:</dt>
+<dd>Return the under color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsettextundercolor">
+<h1><a class="toc-backref" href="#id337">DrawSetTextUnderColor</a></h1>
+<div class="section" id="id219">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetTextUnderColor( DrawingWand *drawing_wand, const PixelWand *under_wand );
+</pre>
+</div>
+<div class="section" id="id220">
+<h2>Description</h2>
+<p>DrawSetTextUnderColor() specifies the color of a background rectangle
+to place under text annotations.</p>
+<p>The format of the DrawSetTextUnderColor method is:</p>
+<pre class="literal-block">
+void DrawSetTextUnderColor( DrawingWand *drawing_wand, const PixelWand *under_wand );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>under_wand.:</dt>
+<dd>text under wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawtranslate">
+<h1><a class="toc-backref" href="#id338">DrawTranslate</a></h1>
+<div class="section" id="id221">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawTranslate( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id222">
+<h2>Description</h2>
+<p>DrawTranslate() applies a translation to the current coordinate
+system which moves the coordinate system origin to the specified
+coordinate.</p>
+<p>The format of the DrawTranslate method is:</p>
+<pre class="literal-block">
+void DrawTranslate( DrawingWand *drawing_wand, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x:</dt>
+<dd>new x ordinate for coordinate system origin</dd>
+<dt>y:</dt>
+<dd>new y ordinate for coordinate system origin</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="drawsetviewbox">
+<h1><a class="toc-backref" href="#id339">DrawSetViewbox</a></h1>
+<div class="section" id="id223">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DrawSetViewbox( DrawingWand *drawing_wand, unsigned long x1, unsigned long y1,
+ unsigned long x2, unsigned long y2 );
+</pre>
+</div>
+<div class="section" id="id224">
+<h2>Description</h2>
+<p>DrawSetViewbox() sets the overall canvas size to be recorded with the
+drawing vector data. Usually this will be specified using the same
+size as the canvas image. When the vector data is saved to SVG or MVG
+formats, the viewbox is use to specify the size of the canvas image that
+a viewer will render the vector data on.</p>
+<p>The format of the DrawSetViewbox method is:</p>
+<pre class="literal-block">
+void DrawSetViewbox( DrawingWand *drawing_wand, unsigned long x1, unsigned long y1,
+ unsigned long x2, unsigned long y2 );
+</pre>
+<dl class="docutils">
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>x1:</dt>
+<dd>left x ordinate</dd>
+<dt>y1:</dt>
+<dd>top y ordinate</dd>
+<dt>x2:</dt>
+<dd>right x ordinate</dd>
+<dt>y2:</dt>
+<dd>bottom y ordinate</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="newdrawingwand">
+<h1><a class="toc-backref" href="#id340">NewDrawingWand</a></h1>
+<div class="section" id="id225">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+DrawingWand *NewDrawingWand( void );
+</pre>
+</div>
+<div class="section" id="id226">
+<h2>Description</h2>
+<p>NewDrawingWand() returns a drawing wand required for all other methods in
+the API.</p>
+<p>The format of the NewDrawingWand method is:</p>
+<pre class="literal-block">
+DrawingWand *NewDrawingWand( void );
+</pre>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/wand/magick_wand.html b/www/wand/magick_wand.html
new file mode 100644
index 0000000..0296feb
--- /dev/null
+++ b/www/wand/magick_wand.html
@@ -0,0 +1,6629 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>magick_wand</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="magick-wand">
+<h1 class="title">magick_wand</h1>
+<h2 class="subtitle" id="wand-image-processing-interfaces">Wand image processing interfaces</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#clonemagickwand" id="id463">CloneMagickWand</a></li>
+<li><a class="reference internal" href="#destroymagickwand" id="id464">DestroyMagickWand</a></li>
+<li><a class="reference internal" href="#magickadaptivethresholdimage" id="id465">MagickAdaptiveThresholdImage</a></li>
+<li><a class="reference internal" href="#magickaddimage" id="id466">MagickAddImage</a></li>
+<li><a class="reference internal" href="#magickaddnoiseimage" id="id467">MagickAddNoiseImage</a></li>
+<li><a class="reference internal" href="#magickaffinetransformimage" id="id468">MagickAffineTransformImage</a></li>
+<li><a class="reference internal" href="#magickannotateimage" id="id469">MagickAnnotateImage</a></li>
+<li><a class="reference internal" href="#magickanimateimages" id="id470">MagickAnimateImages</a></li>
+<li><a class="reference internal" href="#magickappendimages" id="id471">MagickAppendImages</a></li>
+<li><a class="reference internal" href="#magickautoorientimage" id="id472">MagickAutoOrientImage</a></li>
+<li><a class="reference internal" href="#magickaverageimages" id="id473">MagickAverageImages</a></li>
+<li><a class="reference internal" href="#magickblackthresholdimage" id="id474">MagickBlackThresholdImage</a></li>
+<li><a class="reference internal" href="#magickblurimage" id="id475">MagickBlurImage</a></li>
+<li><a class="reference internal" href="#magickborderimage" id="id476">MagickBorderImage</a></li>
+<li><a class="reference internal" href="#magickcdlimage" id="id477">MagickCdlImage</a></li>
+<li><a class="reference internal" href="#magickcharcoalimage" id="id478">MagickCharcoalImage</a></li>
+<li><a class="reference internal" href="#magickchopimage" id="id479">MagickChopImage</a></li>
+<li><a class="reference internal" href="#magickclearexception" id="id480">MagickClearException</a></li>
+<li><a class="reference internal" href="#magickclipimage" id="id481">MagickClipImage</a></li>
+<li><a class="reference internal" href="#magickclippathimage" id="id482">MagickClipPathImage</a></li>
+<li><a class="reference internal" href="#magickcoalesceimages" id="id483">MagickCoalesceImages</a></li>
+<li><a class="reference internal" href="#magickcolorfloodfillimage" id="id484">MagickColorFloodfillImage</a></li>
+<li><a class="reference internal" href="#magickcolorizeimage" id="id485">MagickColorizeImage</a></li>
+<li><a class="reference internal" href="#magickcommentimage" id="id486">MagickCommentImage</a></li>
+<li><a class="reference internal" href="#magickcompareimagechannels" id="id487">MagickCompareImageChannels</a></li>
+<li><a class="reference internal" href="#magickcompareimages" id="id488">MagickCompareImages</a></li>
+<li><a class="reference internal" href="#magickcompositeimage" id="id489">MagickCompositeImage</a></li>
+<li><a class="reference internal" href="#magickcontrastimage" id="id490">MagickContrastImage</a></li>
+<li><a class="reference internal" href="#magickconvolveimage" id="id491">MagickConvolveImage</a></li>
+<li><a class="reference internal" href="#magickcropimage" id="id492">MagickCropImage</a></li>
+<li><a class="reference internal" href="#magickcyclecolormapimage" id="id493">MagickCycleColormapImage</a></li>
+<li><a class="reference internal" href="#magickdeconstructimages" id="id494">MagickDeconstructImages</a></li>
+<li><a class="reference internal" href="#magickdescribeimage" id="id495">MagickDescribeImage</a></li>
+<li><a class="reference internal" href="#magickdespeckleimage" id="id496">MagickDespeckleImage</a></li>
+<li><a class="reference internal" href="#magickdisplayimage" id="id497">MagickDisplayImage</a></li>
+<li><a class="reference internal" href="#magickdisplayimages" id="id498">MagickDisplayImages</a></li>
+<li><a class="reference internal" href="#magickdrawimage" id="id499">MagickDrawImage</a></li>
+<li><a class="reference internal" href="#magickedgeimage" id="id500">MagickEdgeImage</a></li>
+<li><a class="reference internal" href="#magickembossimage" id="id501">MagickEmbossImage</a></li>
+<li><a class="reference internal" href="#magickenhanceimage" id="id502">MagickEnhanceImage</a></li>
+<li><a class="reference internal" href="#magickequalizeimage" id="id503">MagickEqualizeImage</a></li>
+<li><a class="reference internal" href="#magickextentimage" id="id504">MagickExtentImage</a></li>
+<li><a class="reference internal" href="#magickflattenimages" id="id505">MagickFlattenImages</a></li>
+<li><a class="reference internal" href="#magickflipimage" id="id506">MagickFlipImage</a></li>
+<li><a class="reference internal" href="#magickflopimage" id="id507">MagickFlopImage</a></li>
+<li><a class="reference internal" href="#magickframeimage" id="id508">MagickFrameImage</a></li>
+<li><a class="reference internal" href="#magickfximage" id="id509">MagickFxImage</a></li>
+<li><a class="reference internal" href="#magickfximagechannel" id="id510">MagickFxImageChannel</a></li>
+<li><a class="reference internal" href="#magickgammaimage" id="id511">MagickGammaImage</a></li>
+<li><a class="reference internal" href="#magickgammaimagechannel" id="id512">MagickGammaImageChannel</a></li>
+<li><a class="reference internal" href="#magickgetconfigureinfo" id="id513">MagickGetConfigureInfo</a></li>
+<li><a class="reference internal" href="#magickgetcopyright" id="id514">MagickGetCopyright</a></li>
+<li><a class="reference internal" href="#magickgetexception" id="id515">MagickGetException</a></li>
+<li><a class="reference internal" href="#magickgetfilename" id="id516">MagickGetFilename</a></li>
+<li><a class="reference internal" href="#magickgethomeurl" id="id517">MagickGetHomeURL</a></li>
+<li><a class="reference internal" href="#magickgetimage" id="id518">MagickGetImage</a></li>
+<li><a class="reference internal" href="#magickgetimageattribute" id="id519">MagickGetImageAttribute</a></li>
+<li><a class="reference internal" href="#magickgetimagebackgroundcolor" id="id520">MagickGetImageBackgroundColor</a></li>
+<li><a class="reference internal" href="#magickgetimageblueprimary" id="id521">MagickGetImageBluePrimary</a></li>
+<li><a class="reference internal" href="#magickgetimagebordercolor" id="id522">MagickGetImageBorderColor</a></li>
+<li><a class="reference internal" href="#magickgetimageboundingbox" id="id523">MagickGetImageBoundingBox</a></li>
+<li><a class="reference internal" href="#magickgetimagechanneldepth" id="id524">MagickGetImageChannelDepth</a></li>
+<li><a class="reference internal" href="#magickgetimagechannelextrema" id="id525">MagickGetImageChannelExtrema</a></li>
+<li><a class="reference internal" href="#magickgetimagechannelmean" id="id526">MagickGetImageChannelMean</a></li>
+<li><a class="reference internal" href="#magickgetimagecolormapcolor" id="id527">MagickGetImageColormapColor</a></li>
+<li><a class="reference internal" href="#magickgetimagecolors" id="id528">MagickGetImageColors</a></li>
+<li><a class="reference internal" href="#magickgetimagecolorspace" id="id529">MagickGetImageColorspace</a></li>
+<li><a class="reference internal" href="#magickgetimagecompose" id="id530">MagickGetImageCompose</a></li>
+<li><a class="reference internal" href="#magickgetimagecompression" id="id531">MagickGetImageCompression</a></li>
+<li><a class="reference internal" href="#magickgetimagedelay" id="id532">MagickGetImageDelay</a></li>
+<li><a class="reference internal" href="#magickgetimagedepth" id="id533">MagickGetImageDepth</a></li>
+<li><a class="reference internal" href="#magickgetimageextrema" id="id534">MagickGetImageExtrema</a></li>
+<li><a class="reference internal" href="#magickgetimagedispose" id="id535">MagickGetImageDispose</a></li>
+<li><a class="reference internal" href="#magickgetimagefilename" id="id536">MagickGetImageFilename</a></li>
+<li><a class="reference internal" href="#magickgetimageformat" id="id537">MagickGetImageFormat</a></li>
+<li><a class="reference internal" href="#magickgetimagefuzz" id="id538">MagickGetImageFuzz</a></li>
+<li><a class="reference internal" href="#magickgetimagegamma" id="id539">MagickGetImageGamma</a></li>
+<li><a class="reference internal" href="#magickgetimagegravity" id="id540">MagickGetImageGravity</a></li>
+<li><a class="reference internal" href="#magickgetimagegreenprimary" id="id541">MagickGetImageGreenPrimary</a></li>
+<li><a class="reference internal" href="#magickgetimageheight" id="id542">MagickGetImageHeight</a></li>
+<li><a class="reference internal" href="#magickgetimagehistogram" id="id543">MagickGetImageHistogram</a></li>
+<li><a class="reference internal" href="#magickgetimageindex" id="id544">MagickGetImageIndex</a></li>
+<li><a class="reference internal" href="#magickgetimageinterlacescheme" id="id545">MagickGetImageInterlaceScheme</a></li>
+<li><a class="reference internal" href="#magickgetimageiterations" id="id546">MagickGetImageIterations</a></li>
+<li><a class="reference internal" href="#magickgetimagemattecolor" id="id547">MagickGetImageMatteColor</a></li>
+<li><a class="reference internal" href="#magickgetimageorientation" id="id548">MagickGetImageOrientation</a></li>
+<li><a class="reference internal" href="#magickgetimagepage" id="id549">MagickGetImagePage</a></li>
+<li><a class="reference internal" href="#magickgetimagepixels" id="id550">MagickGetImagePixels</a></li>
+<li><a class="reference internal" href="#magickgetimageprofile" id="id551">MagickGetImageProfile</a></li>
+<li><a class="reference internal" href="#magickgetimageredprimary" id="id552">MagickGetImageRedPrimary</a></li>
+<li><a class="reference internal" href="#magickgetimagerenderingintent" id="id553">MagickGetImageRenderingIntent</a></li>
+<li><a class="reference internal" href="#magickgetimageresolution" id="id554">MagickGetImageResolution</a></li>
+<li><a class="reference internal" href="#magickgetimagescene" id="id555">MagickGetImageScene</a></li>
+<li><a class="reference internal" href="#magickgetimagesignature" id="id556">MagickGetImageSignature</a></li>
+<li><a class="reference internal" href="#magickgetimagesize" id="id557">MagickGetImageSize</a></li>
+<li><a class="reference internal" href="#magickgetimagetype" id="id558">MagickGetImageType</a></li>
+<li><a class="reference internal" href="#magickgetimagesavedtype" id="id559">MagickGetImageSavedType</a></li>
+<li><a class="reference internal" href="#magickgetimageunits" id="id560">MagickGetImageUnits</a></li>
+<li><a class="reference internal" href="#magickgetimagevirtualpixelmethod" id="id561">MagickGetImageVirtualPixelMethod</a></li>
+<li><a class="reference internal" href="#magickgetimagewhitepoint" id="id562">MagickGetImageWhitePoint</a></li>
+<li><a class="reference internal" href="#magickgetimagewidth" id="id563">MagickGetImageWidth</a></li>
+<li><a class="reference internal" href="#magickgetnumberimages" id="id564">MagickGetNumberImages</a></li>
+<li><a class="reference internal" href="#magickgetpackagename" id="id565">MagickGetPackageName</a></li>
+<li><a class="reference internal" href="#magickgetquantumdepth" id="id566">MagickGetQuantumDepth</a></li>
+<li><a class="reference internal" href="#magickgetreleasedate" id="id567">MagickGetReleaseDate</a></li>
+<li><a class="reference internal" href="#magickgetresourcelimit" id="id568">MagickGetResourceLimit</a></li>
+<li><a class="reference internal" href="#magickgetsamplingfactors" id="id569">MagickGetSamplingFactors</a></li>
+<li><a class="reference internal" href="#magickgetsize" id="id570">MagickGetSize</a></li>
+<li><a class="reference internal" href="#magickgetversion" id="id571">MagickGetVersion</a></li>
+<li><a class="reference internal" href="#magickhaldclutimage" id="id572">MagickHaldClutImage</a></li>
+<li><a class="reference internal" href="#magickhasnextimage" id="id573">MagickHasNextImage</a></li>
+<li><a class="reference internal" href="#magickhaspreviousimage" id="id574">MagickHasPreviousImage</a></li>
+<li><a class="reference internal" href="#magickimplodeimage" id="id575">MagickImplodeImage</a></li>
+<li><a class="reference internal" href="#magicklabelimage" id="id576">MagickLabelImage</a></li>
+<li><a class="reference internal" href="#magicklevelimage" id="id577">MagickLevelImage</a></li>
+<li><a class="reference internal" href="#magicklevelimagechannel" id="id578">MagickLevelImageChannel</a></li>
+<li><a class="reference internal" href="#magickmagnifyimage" id="id579">MagickMagnifyImage</a></li>
+<li><a class="reference internal" href="#magickmapimage" id="id580">MagickMapImage</a></li>
+<li><a class="reference internal" href="#magickmattefloodfillimage" id="id581">MagickMatteFloodfillImage</a></li>
+<li><a class="reference internal" href="#magickmedianfilterimage" id="id582">MagickMedianFilterImage</a></li>
+<li><a class="reference internal" href="#magickminifyimage" id="id583">MagickMinifyImage</a></li>
+<li><a class="reference internal" href="#magickmodulateimage" id="id584">MagickModulateImage</a></li>
+<li><a class="reference internal" href="#magickmontageimage" id="id585">MagickMontageImage</a></li>
+<li><a class="reference internal" href="#magickmorphimages" id="id586">MagickMorphImages</a></li>
+<li><a class="reference internal" href="#magickmosaicimages" id="id587">MagickMosaicImages</a></li>
+<li><a class="reference internal" href="#magickmotionblurimage" id="id588">MagickMotionBlurImage</a></li>
+<li><a class="reference internal" href="#magicknegateimage" id="id589">MagickNegateImage</a></li>
+<li><a class="reference internal" href="#magicknegateimagechannel" id="id590">MagickNegateImageChannel</a></li>
+<li><a class="reference internal" href="#magicknextimage" id="id591">MagickNextImage</a></li>
+<li><a class="reference internal" href="#magicknormalizeimage" id="id592">MagickNormalizeImage</a></li>
+<li><a class="reference internal" href="#magickoilpaintimage" id="id593">MagickOilPaintImage</a></li>
+<li><a class="reference internal" href="#magickopaqueimage" id="id594">MagickOpaqueImage</a></li>
+<li><a class="reference internal" href="#magickpingimage" id="id595">MagickPingImage</a></li>
+<li><a class="reference internal" href="#magickpreviewimages" id="id596">MagickPreviewImages</a></li>
+<li><a class="reference internal" href="#magickpreviousimage" id="id597">MagickPreviousImage</a></li>
+<li><a class="reference internal" href="#magickprofileimage" id="id598">MagickProfileImage</a></li>
+<li><a class="reference internal" href="#magickquantizeimage" id="id599">MagickQuantizeImage</a></li>
+<li><a class="reference internal" href="#magickquantizeimages" id="id600">MagickQuantizeImages</a></li>
+<li><a class="reference internal" href="#magickqueryfontmetrics" id="id601">MagickQueryFontMetrics</a></li>
+<li><a class="reference internal" href="#magickqueryfonts" id="id602">MagickQueryFonts</a></li>
+<li><a class="reference internal" href="#magickqueryformats" id="id603">MagickQueryFormats</a></li>
+<li><a class="reference internal" href="#magickradialblurimage" id="id604">MagickRadialBlurImage</a></li>
+<li><a class="reference internal" href="#magickraiseimage" id="id605">MagickRaiseImage</a></li>
+<li><a class="reference internal" href="#magickreadimage" id="id606">MagickReadImage</a></li>
+<li><a class="reference internal" href="#magickreadimageblob" id="id607">MagickReadImageBlob</a></li>
+<li><a class="reference internal" href="#magickreadimagefile" id="id608">MagickReadImageFile</a></li>
+<li><a class="reference internal" href="#magickreducenoiseimage" id="id609">MagickReduceNoiseImage</a></li>
+<li><a class="reference internal" href="#magickrelinquishmemory" id="id610">MagickRelinquishMemory</a></li>
+<li><a class="reference internal" href="#magickremoveimage" id="id611">MagickRemoveImage</a></li>
+<li><a class="reference internal" href="#magickremoveimageoption" id="id612">MagickRemoveImageOption</a></li>
+<li><a class="reference internal" href="#magickremoveimageprofile" id="id613">MagickRemoveImageProfile</a></li>
+<li><a class="reference internal" href="#magickresetiterator" id="id614">MagickResetIterator</a></li>
+<li><a class="reference internal" href="#magickresampleimage" id="id615">MagickResampleImage</a></li>
+<li><a class="reference internal" href="#magickresizeimage" id="id616">MagickResizeImage</a></li>
+<li><a class="reference internal" href="#magickrollimage" id="id617">MagickRollImage</a></li>
+<li><a class="reference internal" href="#magickrotateimage" id="id618">MagickRotateImage</a></li>
+<li><a class="reference internal" href="#magicksampleimage" id="id619">MagickSampleImage</a></li>
+<li><a class="reference internal" href="#magickscaleimage" id="id620">MagickScaleImage</a></li>
+<li><a class="reference internal" href="#magickseparateimagechannel" id="id621">MagickSeparateImageChannel</a></li>
+<li><a class="reference internal" href="#magicksetcompressionquality" id="id622">MagickSetCompressionQuality</a></li>
+<li><a class="reference internal" href="#magicksetdepth" id="id623">MagickSetDepth</a></li>
+<li><a class="reference internal" href="#magicksetfilename" id="id624">MagickSetFilename</a></li>
+<li><a class="reference internal" href="#magicksetformat" id="id625">MagickSetFormat</a></li>
+<li><a class="reference internal" href="#magicksetimage" id="id626">MagickSetImage</a></li>
+<li><a class="reference internal" href="#magicksetimageattribute" id="id627">MagickSetImageAttribute</a></li>
+<li><a class="reference internal" href="#magicksetimagebackgroundcolor" id="id628">MagickSetImageBackgroundColor</a></li>
+<li><a class="reference internal" href="#magicksetimageblueprimary" id="id629">MagickSetImageBluePrimary</a></li>
+<li><a class="reference internal" href="#magicksetimagebordercolor" id="id630">MagickSetImageBorderColor</a></li>
+<li><a class="reference internal" href="#magicksetimagecolormapcolor" id="id631">MagickSetImageColormapColor</a></li>
+<li><a class="reference internal" href="#magicksetimagecolorspace" id="id632">MagickSetImageColorspace</a></li>
+<li><a class="reference internal" href="#magicksetimagecompose" id="id633">MagickSetImageCompose</a></li>
+<li><a class="reference internal" href="#magicksetimagecompression" id="id634">MagickSetImageCompression</a></li>
+<li><a class="reference internal" href="#magicksetimagedelay" id="id635">MagickSetImageDelay</a></li>
+<li><a class="reference internal" href="#magicksetimagechanneldepth" id="id636">MagickSetImageChannelDepth</a></li>
+<li><a class="reference internal" href="#magicksetimagedepth" id="id637">MagickSetImageDepth</a></li>
+<li><a class="reference internal" href="#magicksetimagedispose" id="id638">MagickSetImageDispose</a></li>
+<li><a class="reference internal" href="#magicksetimagefilename" id="id639">MagickSetImageFilename</a></li>
+<li><a class="reference internal" href="#magicksetimageformat" id="id640">MagickSetImageFormat</a></li>
+<li><a class="reference internal" href="#magicksetimagefuzz" id="id641">MagickSetImageFuzz</a></li>
+<li><a class="reference internal" href="#magicksetimagegamma" id="id642">MagickSetImageGamma</a></li>
+<li><a class="reference internal" href="#magicksetimagegravity" id="id643">MagickSetImageGravity</a></li>
+<li><a class="reference internal" href="#magicksetimagegreenprimary" id="id644">MagickSetImageGreenPrimary</a></li>
+<li><a class="reference internal" href="#magicksetimageindex" id="id645">MagickSetImageIndex</a></li>
+<li><a class="reference internal" href="#magicksetimageinterlacescheme" id="id646">MagickSetImageInterlaceScheme</a></li>
+<li><a class="reference internal" href="#magicksetimageiterations" id="id647">MagickSetImageIterations</a></li>
+<li><a class="reference internal" href="#magicksetimagemattecolor" id="id648">MagickSetImageMatteColor</a></li>
+<li><a class="reference internal" href="#magicksetimageoption" id="id649">MagickSetImageOption</a></li>
+<li><a class="reference internal" href="#magicksetimageorientation" id="id650">MagickSetImageOrientation</a></li>
+<li><a class="reference internal" href="#magicksetimagepage" id="id651">MagickSetImagePage</a></li>
+<li><a class="reference internal" href="#magicksetimagepixels" id="id652">MagickSetImagePixels</a></li>
+<li><a class="reference internal" href="#magicksetimageprofile" id="id653">MagickSetImageProfile</a></li>
+<li><a class="reference internal" href="#magicksetimageredprimary" id="id654">MagickSetImageRedPrimary</a></li>
+<li><a class="reference internal" href="#magicksetimagerenderingintent" id="id655">MagickSetImageRenderingIntent</a></li>
+<li><a class="reference internal" href="#magicksetimageresolution" id="id656">MagickSetImageResolution</a></li>
+<li><a class="reference internal" href="#magicksetimagescene" id="id657">MagickSetImageScene</a></li>
+<li><a class="reference internal" href="#magicksetimagetype" id="id658">MagickSetImageType</a></li>
+<li><a class="reference internal" href="#magicksetimagesavedtype" id="id659">MagickSetImageSavedType</a></li>
+<li><a class="reference internal" href="#magicksetimageunits" id="id660">MagickSetImageUnits</a></li>
+<li><a class="reference internal" href="#magicksetimagevirtualpixelmethod" id="id661">MagickSetImageVirtualPixelMethod</a></li>
+<li><a class="reference internal" href="#magicksetinterlacescheme" id="id662">MagickSetInterlaceScheme</a></li>
+<li><a class="reference internal" href="#magicksetresolution" id="id663">MagickSetResolution</a></li>
+<li><a class="reference internal" href="#magicksetresolutionunits" id="id664">MagickSetResolutionUnits</a></li>
+<li><a class="reference internal" href="#magicksetresourcelimit" id="id665">MagickSetResourceLimit</a></li>
+<li><a class="reference internal" href="#magicksetsamplingfactors" id="id666">MagickSetSamplingFactors</a></li>
+<li><a class="reference internal" href="#magicksetsize" id="id667">MagickSetSize</a></li>
+<li><a class="reference internal" href="#magicksetimagewhitepoint" id="id668">MagickSetImageWhitePoint</a></li>
+<li><a class="reference internal" href="#magicksetpassphrase" id="id669">MagickSetPassphrase</a></li>
+<li><a class="reference internal" href="#magicksharpenimage" id="id670">MagickSharpenImage</a></li>
+<li><a class="reference internal" href="#magickshaveimage" id="id671">MagickShaveImage</a></li>
+<li><a class="reference internal" href="#magickshearimage" id="id672">MagickShearImage</a></li>
+<li><a class="reference internal" href="#magicksolarizeimage" id="id673">MagickSolarizeImage</a></li>
+<li><a class="reference internal" href="#magickspreadimage" id="id674">MagickSpreadImage</a></li>
+<li><a class="reference internal" href="#magicksteganoimage" id="id675">MagickSteganoImage</a></li>
+<li><a class="reference internal" href="#magickstereoimage" id="id676">MagickStereoImage</a></li>
+<li><a class="reference internal" href="#magickstripimage" id="id677">MagickStripImage</a></li>
+<li><a class="reference internal" href="#magickswirlimage" id="id678">MagickSwirlImage</a></li>
+<li><a class="reference internal" href="#magicktextureimage" id="id679">MagickTextureImage</a></li>
+<li><a class="reference internal" href="#magickthresholdimage" id="id680">MagickThresholdImage</a></li>
+<li><a class="reference internal" href="#magickthresholdimagechannel" id="id681">MagickThresholdImageChannel</a></li>
+<li><a class="reference internal" href="#magicktintimage" id="id682">MagickTintImage</a></li>
+<li><a class="reference internal" href="#magicktransformimage" id="id683">MagickTransformImage</a></li>
+<li><a class="reference internal" href="#magicktransparentimage" id="id684">MagickTransparentImage</a></li>
+<li><a class="reference internal" href="#magicktrimimage" id="id685">MagickTrimImage</a></li>
+<li><a class="reference internal" href="#magickunsharpmaskimage" id="id686">MagickUnsharpMaskImage</a></li>
+<li><a class="reference internal" href="#magickwaveimage" id="id687">MagickWaveImage</a></li>
+<li><a class="reference internal" href="#magickwhitethresholdimage" id="id688">MagickWhiteThresholdImage</a></li>
+<li><a class="reference internal" href="#magickwriteimage" id="id689">MagickWriteImage</a></li>
+<li><a class="reference internal" href="#magickwriteimagesfile" id="id690">MagickWriteImagesFile</a></li>
+<li><a class="reference internal" href="#magickwriteimageblob" id="id691">MagickWriteImageBlob</a></li>
+<li><a class="reference internal" href="#magickwriteimagefile" id="id692">MagickWriteImageFile</a></li>
+<li><a class="reference internal" href="#magickwriteimages" id="id693">MagickWriteImages</a></li>
+<li><a class="reference internal" href="#newmagickwand" id="id694">NewMagickWand</a></li>
+</ul>
+</div>
+<div class="section" id="clonemagickwand">
+<h1><a class="toc-backref" href="#id463">CloneMagickWand</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *CloneMagickWand( const MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>CloneMagickWand() makes an exact copy of the specified wand.</p>
+<p>The format of the CloneMagickWand method is:</p>
+<pre class="literal-block">
+MagickWand *CloneMagickWand( const MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand to clone.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroymagickwand">
+<h1><a class="toc-backref" href="#id464">DestroyMagickWand</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void DestroyMagickWand( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>DestroyMagickWand() deallocates memory associated with an MagickWand.</p>
+<p>The format of the DestroyMagickWand method is:</p>
+<pre class="literal-block">
+void DestroyMagickWand( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickadaptivethresholdimage">
+<h1><a class="toc-backref" href="#id465">MagickAdaptiveThresholdImage</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickAdaptiveThresholdImage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long offset );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>MagickAdaptiveThresholdImage() selects an individual threshold for each pixel
+based on the range of intensity values in its local neighborhood. This
+allows for thresholding of an image whose global intensity histogram
+doesn't contain distinctive peaks.</p>
+<p>The format of the MagickAdaptiveThresholdImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickAdaptiveThresholdImage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long offset );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>width:</dt>
+<dd>The width of the local neighborhood.</dd>
+<dt>height:</dt>
+<dd>The height of the local neighborhood.</dd>
+<dt>offset:</dt>
+<dd>The mean offset.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickaddimage">
+<h1><a class="toc-backref" href="#id466">MagickAddImage</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickAddImage( MagickWand *wand, const MagickWand *add_wand );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>MagickAddImage() adds the specified images at the current image location.</p>
+<p>The format of the MagickAddImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickAddImage( MagickWand *wand, const MagickWand *add_wand );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>insert:</dt>
+<dd>The splice wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickaddnoiseimage">
+<h1><a class="toc-backref" href="#id467">MagickAddNoiseImage</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickAddNoiseImage( MagickWand *wand, const <a class="reference external" href="../api/types.html#noisetype">NoiseType</a> noise_type );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>MagickAddNoiseImage() adds random noise to the image.</p>
+<p>The format of the MagickAddNoiseImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickAddNoiseImage( MagickWand *wand, const <a class="reference external" href="../api/types.html#noisetype">NoiseType</a> noise_type );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>noise_type:</dt>
+<dd>The type of noise: Uniform, Gaussian, Multiplicative,
+Impulse, Laplacian, Poisson, or Random.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickaffinetransformimage">
+<h1><a class="toc-backref" href="#id468">MagickAffineTransformImage</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickAffineTransformImage( MagickWand *wand, const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>MagickAffineTransformImage() transforms an image as dictated by the affine
+matrix of the drawing wand.</p>
+<p>The format of the MagickAffineTransformImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickAffineTransformImage( MagickWand *wand, const DrawingWand *drawing_wand );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>drawing_wand:</dt>
+<dd>The draw wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickannotateimage">
+<h1><a class="toc-backref" href="#id469">MagickAnnotateImage</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickAnnotateImage( MagickWand *wand, const DrawingWand *drawing_wand,
+ const double x, const double y, const double angle,
+ const char *text );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>MagickAnnotateImage() annotates an image with text.</p>
+<p>The format of the MagickAnnotateImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickAnnotateImage( MagickWand *wand, const DrawingWand *drawing_wand,
+ const double x, const double y, const double angle,
+ const char *text );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>drawing_wand:</dt>
+<dd>The draw wand.</dd>
+<dt>x:</dt>
+<dd>x ordinate to left of text</dd>
+<dt>y:</dt>
+<dd>y ordinate to text baseline</dd>
+<dt>angle:</dt>
+<dd>rotate text relative to this angle.</dd>
+<dt>text:</dt>
+<dd>text to draw</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickanimateimages">
+<h1><a class="toc-backref" href="#id470">MagickAnimateImages</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickAnimateImages( MagickWand *wand, const char *server_name );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>MagickAnimateImages() animates an image or image sequence.</p>
+<p>The format of the MagickAnimateImages method is:</p>
+<pre class="literal-block">
+unsigned int MagickAnimateImages( MagickWand *wand, const char *server_name );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>server_name:</dt>
+<dd>The X server name.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickappendimages">
+<h1><a class="toc-backref" href="#id471">MagickAppendImages</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickAppendImages( MagickWand *wand, const unsigned int stack );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>MagickAppendImages() append a set of images.</p>
+<p>The format of the MagickAppendImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickAppendImages( MagickWand *wand, const unsigned int stack );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>stack:</dt>
+<dd>By default, images are stacked left-to-right. Set stack to True
+to stack them top-to-bottom.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickautoorientimage">
+<h1><a class="toc-backref" href="#id472">MagickAutoOrientImage</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickAutoOrientImage( MagickWand *wand,
+ const OrientationType current_orientation,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>MagickAutoOrientImage() adjusts the current image so that its orientation
+is suitable for viewing (i.e. top-left orientation).</p>
+<p>The format of the MagickAutoOrientImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickAutoOrientImage( MagickWand *wand,
+ const OrientationType current_orientation,
+ <a class="reference external" href="../api/types.html#exceptioninfo">ExceptionInfo</a> *exception );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>current_orientation:</dt>
+<dd>Current image orientation. May be one of:
+TopLeftOrientation Left to right and Top to bottom
+TopRightOrientation Right to left and Top to bottom
+BottomRightOrientation Right to left and Bottom to top
+BottomLeftOrientation Left to right and Bottom to top
+LeftTopOrientation Top to bottom and Left to right
+RightTopOrientation Top to bottom and Right to left
+RightBottomOrientation Bottom to top and Right to left
+LeftBottomOrientation Bottom to top and Left to right
+UndefinedOrientation Current orientation is not known.
+Use orientation defined by the
+current image if any. Equivalent
+to MagickGetImageOrientation().</dd>
+</dl>
+<p>Returns True on success, False otherwise.</p>
+<p>Note that after successful auto-orientation the internal orientation will
+be set to TopLeftOrientation. However this internal value is only written
+to TIFF files. For JPEG files, there is currently no support for resetting
+the EXIF orientation tag to TopLeft so the JPEG should be stripped or EXIF
+profile removed if present to prevent saved auto-oriented images from being
+incorrectly rotated a second time by follow-on viewers that understand the
+EXIF orientation tag.</p>
+</div>
+</div>
+<div class="section" id="magickaverageimages">
+<h1><a class="toc-backref" href="#id473">MagickAverageImages</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickAverageImages( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>MagickAverageImages() average a set of images.</p>
+<p>The format of the MagickAverageImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickAverageImages( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickblackthresholdimage">
+<h1><a class="toc-backref" href="#id474">MagickBlackThresholdImage</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickBlackThresholdImage( MagickWand *wand, const PixelWand *threshold );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>MagickBlackThresholdImage() is like MagickThresholdImage() but forces all
+pixels below the threshold into black while leaving all pixels above the
+threshold unchanged.</p>
+<p>The format of the MagickBlackThresholdImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickBlackThresholdImage( MagickWand *wand, const PixelWand *threshold );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>threshold:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickblurimage">
+<h1><a class="toc-backref" href="#id475">MagickBlurImage</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickBlurImage( MagickWand *wand, const double radius, const double sigma );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>MagickBlurImage() blurs an image. We convolve the image with a Gaussian
+operator of the given radius and standard deviation (sigma).
+For reasonable results, the radius should be larger than sigma. Use a
+radius of 0 and BlurImage() selects a suitable radius for you.</p>
+<p>The format of the MagickBlurImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickBlurImage( MagickWand *wand, const double radius, const double sigma );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickborderimage">
+<h1><a class="toc-backref" href="#id476">MagickBorderImage</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickBorderImage( MagickWand *wand, const PixelWand *bordercolor,
+ const unsigned long width, const unsigned long height );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>MagickBorderImage() surrounds the image with a border of the color defined
+by the bordercolor pixel wand.</p>
+<p>The format of the MagickBorderImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickBorderImage( MagickWand *wand, const PixelWand *bordercolor,
+ const unsigned long width, const unsigned long height );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>bordercolor:</dt>
+<dd>The border color pixel wand.</dd>
+<dt>width:</dt>
+<dd>The border width.</dd>
+<dt>height:</dt>
+<dd>The border height.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcdlimage">
+<h1><a class="toc-backref" href="#id477">MagickCdlImage</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail MagickCdlImage( MagickWand *wand, const char *cdl );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>The MagickCdlImage() method applies (&quot;bakes in&quot;) the ASC-CDL which is a
+format for the exchange of basic primary color grading information between
+equipment and software from different manufacturers. The format defines
+the math for three functions: slope, offset and power. Each function uses
+a number for the red, green, and blue color channels for a total of nine
+numbers comprising a single color decision. A tenth number for chrominance
+(saturation) has been proposed but is not yet standardized.</p>
+<p>The cdl argument string is comma delimited and is in the form (but
+without invervening spaces or line breaks):</p>
+<p>redslope, redoffset, redpower :
+greenslope, greenoffset, greenpower :
+blueslope, blueoffset, bluepower :
+saturation</p>
+<p>with the unity (no change) specification being:</p>
+<p>&quot;1.0,0.0,1.0:1.0,0.0,1.0:1.0,0.0,1.0:0.0&quot;</p>
+<p>See <a class="reference external" href="http://en.wikipedia.org/wiki/ASC_CDL">http://en.wikipedia.org/wiki/ASC_CDL</a> for more information.</p>
+<p>The format of the MagickCdlImage method is:</p>
+<pre class="literal-block">
+MagickPassFail MagickCdlImage( MagickWand *wand, const char *cdl );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The image wand.</dd>
+<dt>cdl:</dt>
+<dd>Define the coefficients for slope offset and power in the
+red green and blue channels, plus saturation.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcharcoalimage">
+<h1><a class="toc-backref" href="#id478">MagickCharcoalImage</a></h1>
+<div class="section" id="id29">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickCharcoalImage( MagickWand *wand, const double radius, const double sigma );
+</pre>
+</div>
+<div class="section" id="id30">
+<h2>Description</h2>
+<p>MagickCharcoalImage() simulates a charcoal drawing.</p>
+<p>The format of the MagickCharcoalImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickCharcoalImage( MagickWand *wand, const double radius, const double sigma );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickchopimage">
+<h1><a class="toc-backref" href="#id479">MagickChopImage</a></h1>
+<div class="section" id="id31">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickChopImage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long x, const long y );
+</pre>
+</div>
+<div class="section" id="id32">
+<h2>Description</h2>
+<p>MagickChopImage() removes a region of an image and collapses the image to
+occupy the removed portion</p>
+<p>The format of the MagickChopImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickChopImage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long x, const long y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>width:</dt>
+<dd>The region width.</dd>
+<dt>height:</dt>
+<dd>The region height.</dd>
+<dt>x:</dt>
+<dd>The region x offset.</dd>
+<dt>y:</dt>
+<dd>The region y offset.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickclearexception">
+<h1><a class="toc-backref" href="#id480">MagickClearException</a></h1>
+<div class="section" id="id33">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickClearException( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id34">
+<h2>Description</h2>
+<p>MagickClearException() clears the last wand exception.</p>
+<p>The format of the MagickClearException method is:</p>
+<pre class="literal-block">
+void MagickClearException( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickclipimage">
+<h1><a class="toc-backref" href="#id481">MagickClipImage</a></h1>
+<div class="section" id="id35">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickClipImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id36">
+<h2>Description</h2>
+<p>MagickClipImage() clips along the first path from the 8BIM profile, if
+present.</p>
+<p>The format of the MagickClipImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickClipImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickclippathimage">
+<h1><a class="toc-backref" href="#id482">MagickClipPathImage</a></h1>
+<div class="section" id="id37">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickClipPathImage( MagickWand *wand, const char *pathname,
+ const unsigned int inside );
+</pre>
+</div>
+<div class="section" id="id38">
+<h2>Description</h2>
+<p>MagickClipPathImage() clips along the named paths from the 8BIM profile, if
+present. Later operations take effect inside the path. Id may be a number
+if preceded with #, to work on a numbered path, e.g., &quot;#1&quot; to use the first
+path.</p>
+<p>The format of the MagickClipPathImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickClipPathImage( MagickWand *wand, const char *pathname,
+ const unsigned int inside );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>pathname:</dt>
+<dd>name of clipping path resource. If name is preceded by #, use
+clipping path numbered by name.</dd>
+<dt>inside:</dt>
+<dd>if non-zero, later operations take effect inside clipping path.
+Otherwise later operations take effect outside clipping path.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcoalesceimages">
+<h1><a class="toc-backref" href="#id483">MagickCoalesceImages</a></h1>
+<div class="section" id="id39">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickCoalesceImages( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id40">
+<h2>Description</h2>
+<p>MagickCoalesceImages() composites a set of images while respecting any page
+offsets and disposal methods. GIF, MIFF, and MNG animation sequences
+typically start with an image background and each subsequent image
+varies in size and offset. MagickCoalesceImages() returns a new sequence
+where each image in the sequence is the same size as the first and
+composited with the next image in the sequence.</p>
+<p>The format of the MagickCoalesceImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickCoalesceImages( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcolorfloodfillimage">
+<h1><a class="toc-backref" href="#id484">MagickColorFloodfillImage</a></h1>
+<div class="section" id="id41">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickColorFloodfillImage( MagickWand *wand, const PixelWand *fill,
+ const double fuzz, const PixelWand *bordercolor,
+ const long x, const long y );
+</pre>
+</div>
+<div class="section" id="id42">
+<h2>Description</h2>
+<p>MagickColorFloodfillImage() changes the color value of any pixel that matches
+target and is an immediate neighbor. If the method FillToBorderMethod is
+specified, the color value is changed for any neighbor pixel that does not
+match the bordercolor member of image.</p>
+<p>The format of the MagickColorFloodfillImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickColorFloodfillImage( MagickWand *wand, const PixelWand *fill,
+ const double fuzz, const PixelWand *bordercolor,
+ const long x, const long y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>fill:</dt>
+<dd>The floodfill color pixel wand.</dd>
+<dt>fuzz:</dt>
+<dd>By default target must match a particular pixel color
+exactly. However, in many cases two colors may differ by a small amount.
+The fuzz member of image defines how much tolerance is acceptable to
+consider two colors as the same. For example, set fuzz to 10 and the
+color red at intensities of 100 and 102 respectively are now interpreted
+as the same color for the purposes of the floodfill.</dd>
+<dt>bordercolor:</dt>
+<dd>The border color pixel wand.</dd>
+<dt>x,y:</dt>
+<dd>The starting location of the operation.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcolorizeimage">
+<h1><a class="toc-backref" href="#id485">MagickColorizeImage</a></h1>
+<div class="section" id="id43">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickColorizeImage( MagickWand *wand, const PixelWand *colorize,
+ const PixelWand *opacity );
+</pre>
+</div>
+<div class="section" id="id44">
+<h2>Description</h2>
+<p>MagickColorizeImage() blends the fill color with each pixel in the image.</p>
+<p>The format of the MagickColorizeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickColorizeImage( MagickWand *wand, const PixelWand *colorize,
+ const PixelWand *opacity );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>colorize:</dt>
+<dd>The colorize pixel wand.</dd>
+<dt>opacity:</dt>
+<dd>The opacity pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcommentimage">
+<h1><a class="toc-backref" href="#id486">MagickCommentImage</a></h1>
+<div class="section" id="id45">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickCommentImage( MagickWand *wand, const char *comment );
+</pre>
+</div>
+<div class="section" id="id46">
+<h2>Description</h2>
+<p>MagickCommentImage() adds a comment to your image.</p>
+<p>The format of the MagickCommentImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickCommentImage( MagickWand *wand, const char *comment );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>comment:</dt>
+<dd>The image comment.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcompareimagechannels">
+<h1><a class="toc-backref" href="#id487">MagickCompareImageChannels</a></h1>
+<div class="section" id="id47">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickCompareImageChannels( MagickWand *wand, const MagickWand *reference,
+ const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel, const MetricType metric,
+ double *distortion );
+</pre>
+</div>
+<div class="section" id="id48">
+<h2>Description</h2>
+<p>MagickCompareImageChannels() compares one or more image channels and
+returns the specified distortion metric.</p>
+<p>The format of the MagickCompareImageChannels method is:</p>
+<pre class="literal-block">
+MagickWand *MagickCompareImageChannels( MagickWand *wand, const MagickWand *reference,
+ const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel, const MetricType metric,
+ double *distortion );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>reference:</dt>
+<dd>The reference wand.</dd>
+<dt>channel:</dt>
+<dd>The channel.</dd>
+<dt>metric:</dt>
+<dd>The metric.</dd>
+<dt>distortion:</dt>
+<dd>The computed distortion between the images.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcompareimages">
+<h1><a class="toc-backref" href="#id488">MagickCompareImages</a></h1>
+<div class="section" id="id49">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickCompareImages( MagickWand *wand, const MagickWand *reference,
+ const MetricType metric, double *distortion );
+</pre>
+</div>
+<div class="section" id="id50">
+<h2>Description</h2>
+<p>MagickCompareImage() compares one or more images and returns the specified
+distortion metric.</p>
+<p>The format of the MagickCompareImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickCompareImages( MagickWand *wand, const MagickWand *reference,
+ const MetricType metric, double *distortion );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>reference:</dt>
+<dd>The reference wand.</dd>
+<dt>metric:</dt>
+<dd>The metric.</dd>
+<dt>distortion:</dt>
+<dd>The computed distortion between the images.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcompositeimage">
+<h1><a class="toc-backref" href="#id489">MagickCompositeImage</a></h1>
+<div class="section" id="id51">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickCompositeImage( MagickWand *wand, const MagickWand *composite_wand,
+ const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> compose, const long x,
+ const long y );
+</pre>
+</div>
+<div class="section" id="id52">
+<h2>Description</h2>
+<p>MagickCompositeImage() composite one image onto another at the specified
+offset.</p>
+<p>The format of the MagickCompositeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickCompositeImage( MagickWand *wand, const MagickWand *composite_wand,
+ const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> compose, const long x,
+ const long y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>composite_image:</dt>
+<dd>The composite image.</dd>
+<dt>compose:</dt>
+<dd>This operator affects how the composite is applied to the
+image. The default is Over. Choose from these operators:</dd>
+</dl>
+<p>OverCompositeOp InCompositeOp OutCompositeOP
+AtopCompositeOP XorCompositeOP PlusCompositeOP
+MinusCompositeOP AddCompositeOP SubtractCompositeOP
+DifferenceCompositeOP BumpmapCompositeOP CopyCompositeOP
+DisplaceCompositeOP</p>
+<dl class="docutils">
+<dt>x_offset:</dt>
+<dd>The column offset of the composited image.</dd>
+<dt>y_offset:</dt>
+<dd>The row offset of the composited image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcontrastimage">
+<h1><a class="toc-backref" href="#id490">MagickContrastImage</a></h1>
+<div class="section" id="id53">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickContrastImage( MagickWand *wand, const unsigned int sharpen );
+</pre>
+</div>
+<div class="section" id="id54">
+<h2>Description</h2>
+<p>MagickContrastImage() enhances the intensity differences between the lighter
+and darker elements of the image. Set sharpen to a value other than 0 to
+increase the image contrast otherwise the contrast is reduced.</p>
+<p>The format of the MagickContrastImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickContrastImage( MagickWand *wand, const unsigned int sharpen );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>sharpen:</dt>
+<dd>Increase or decrease image contrast.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickconvolveimage">
+<h1><a class="toc-backref" href="#id491">MagickConvolveImage</a></h1>
+<div class="section" id="id55">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickConvolveImage( MagickWand *wand, const unsigned long order,
+ const double *kernel );
+</pre>
+</div>
+<div class="section" id="id56">
+<h2>Description</h2>
+<p>MagickConvolveImage() applies a custom convolution kernel to the image.</p>
+<p>The format of the MagickConvolveImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickConvolveImage( MagickWand *wand, const unsigned long order,
+ const double *kernel );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>order:</dt>
+<dd>The number of columns and rows in the filter kernel.</dd>
+<dt>kernel:</dt>
+<dd>An array of doubles representing the convolution kernel.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcropimage">
+<h1><a class="toc-backref" href="#id492">MagickCropImage</a></h1>
+<div class="section" id="id57">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickCropImage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long x, const long y );
+</pre>
+</div>
+<div class="section" id="id58">
+<h2>Description</h2>
+<p>MagickCropImage() extracts a region of the image.</p>
+<p>The format of the MagickCropImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickCropImage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long x, const long y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>width:</dt>
+<dd>The region width.</dd>
+<dt>height:</dt>
+<dd>The region height.</dd>
+<dt>x:</dt>
+<dd>The region x offset.</dd>
+<dt>y:</dt>
+<dd>The region y offset.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickcyclecolormapimage">
+<h1><a class="toc-backref" href="#id493">MagickCycleColormapImage</a></h1>
+<div class="section" id="id59">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickCycleColormapImage( MagickWand *wand, const long displace );
+</pre>
+</div>
+<div class="section" id="id60">
+<h2>Description</h2>
+<p>MagickCycleColormapImage() displaces an image's colormap by a given number
+of positions. If you cycle the colormap a number of times you can produce
+a psychodelic effect.</p>
+<p>The format of the MagickCycleColormapImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickCycleColormapImage( MagickWand *wand, const long displace );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>pixel_wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickdeconstructimages">
+<h1><a class="toc-backref" href="#id494">MagickDeconstructImages</a></h1>
+<div class="section" id="id61">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickDeconstructImages( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id62">
+<h2>Description</h2>
+<p>MagickDeconstructImages() compares each image with the next in a sequence
+and returns the maximum bounding region of any pixel differences it
+discovers.</p>
+<p>The format of the MagickDeconstructImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickDeconstructImages( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickdescribeimage">
+<h1><a class="toc-backref" href="#id495">MagickDescribeImage</a></h1>
+<div class="section" id="id63">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *MagickDescribeImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id64">
+<h2>Description</h2>
+<p>MagickDescribeImage() describes an image by formatting its attributes
+to an allocated string which must be freed by the user. Attributes
+include the image width, height, size, and others. The string is
+similar to the output of 'identify -verbose'.</p>
+<p>The format of the MagickDescribeImage method is:</p>
+<pre class="literal-block">
+const char *MagickDescribeImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickdespeckleimage">
+<h1><a class="toc-backref" href="#id496">MagickDespeckleImage</a></h1>
+<div class="section" id="id65">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickDespeckleImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id66">
+<h2>Description</h2>
+<p>MagickDespeckleImage() reduces the speckle noise in an image while
+perserving the edges of the original image.</p>
+<p>The format of the MagickDespeckleImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickDespeckleImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickdisplayimage">
+<h1><a class="toc-backref" href="#id497">MagickDisplayImage</a></h1>
+<div class="section" id="id67">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickDisplayImage( MagickWand *wand, const char *server_name );
+</pre>
+</div>
+<div class="section" id="id68">
+<h2>Description</h2>
+<p>MagickDisplayImage() displays an image.</p>
+<p>The format of the MagickDisplayImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickDisplayImage( MagickWand *wand, const char *server_name );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>server_name:</dt>
+<dd>The X server name.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickdisplayimages">
+<h1><a class="toc-backref" href="#id498">MagickDisplayImages</a></h1>
+<div class="section" id="id69">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickDisplayImages( MagickWand *wand, const char *server_name );
+</pre>
+</div>
+<div class="section" id="id70">
+<h2>Description</h2>
+<p>MagickDisplayImages() displays an image or image sequence.</p>
+<p>The format of the MagickDisplayImages method is:</p>
+<pre class="literal-block">
+unsigned int MagickDisplayImages( MagickWand *wand, const char *server_name );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>server_name:</dt>
+<dd>The X server name.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickdrawimage">
+<h1><a class="toc-backref" href="#id499">MagickDrawImage</a></h1>
+<div class="section" id="id71">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickDrawImage( MagickWand *wand, const DrawingWand *drawing_wand );
+</pre>
+</div>
+<div class="section" id="id72">
+<h2>Description</h2>
+<p>MagickDrawImage() draws vectors on the image as described by DrawingWand.</p>
+<p>The format of the MagickDrawImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickDrawImage( MagickWand *wand, const DrawingWand *drawing_wand );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>drawing_wand:</dt>
+<dd>The draw wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickedgeimage">
+<h1><a class="toc-backref" href="#id500">MagickEdgeImage</a></h1>
+<div class="section" id="id73">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickEdgeImage( MagickWand *wand, const double radius );
+</pre>
+</div>
+<div class="section" id="id74">
+<h2>Description</h2>
+<p>MagickEdgeImage() enhance edges within the image with a convolution filter
+of the given radius. Use a radius of 0 and Edge() selects a suitable
+radius for you.</p>
+<p>The format of the MagickEdgeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickEdgeImage( MagickWand *wand, const double radius );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>the radius of the pixel neighborhood.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickembossimage">
+<h1><a class="toc-backref" href="#id501">MagickEmbossImage</a></h1>
+<div class="section" id="id75">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickEmbossImage( MagickWand *wand, const double radius, const double sigma );
+</pre>
+</div>
+<div class="section" id="id76">
+<h2>Description</h2>
+<p>MagickEmbossImage() returns a grayscale image with a three-dimensional
+effect. We convolve the image with a Gaussian operator of the given radius
+and standard deviation (sigma). For reasonable results, radius should be
+larger than sigma. Use a radius of 0 and Emboss() selects a suitable
+radius for you.</p>
+<p>The format of the MagickEmbossImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickEmbossImage( MagickWand *wand, const double radius, const double sigma );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickenhanceimage">
+<h1><a class="toc-backref" href="#id502">MagickEnhanceImage</a></h1>
+<div class="section" id="id77">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickEnhanceImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id78">
+<h2>Description</h2>
+<p>MagickEnhanceImage() applies a digital filter that improves the quality of a
+noisy image.</p>
+<p>The format of the MagickEnhanceImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickEnhanceImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickequalizeimage">
+<h1><a class="toc-backref" href="#id503">MagickEqualizeImage</a></h1>
+<div class="section" id="id79">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickEqualizeImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id80">
+<h2>Description</h2>
+<p>MagickEqualizeImage() equalizes the image histogram.</p>
+<p>The format of the MagickEqualizeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickEqualizeImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickextentimage">
+<h1><a class="toc-backref" href="#id504">MagickExtentImage</a></h1>
+<div class="section" id="id81">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickExtentImage( MagickWand *wand, const size_t width, const size_t height,
+ const ssize_t x, const ssize_t y );
+</pre>
+</div>
+<div class="section" id="id82">
+<h2>Description</h2>
+<p>Use MagickExtentImage() to change the image dimensions as specified by
+geometry width and height. The existing image content is composited at
+the position specified by geometry x and y using the image compose method.
+Existing image content which falls outside the bounds of the new image
+dimensions is discarded.</p>
+<p>The format of the MagickExtentImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickExtentImage( MagickWand *wand, const size_t width, const size_t height,
+ const ssize_t x, const ssize_t y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>width:</dt>
+<dd>New image width</dd>
+<dt>height:</dt>
+<dd>New image height</dd>
+<dt>x, y:</dt>
+<dd>Top left composition coordinate to place existing image content
+on the new image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickflattenimages">
+<h1><a class="toc-backref" href="#id505">MagickFlattenImages</a></h1>
+<div class="section" id="id83">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickFlattenImages( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id84">
+<h2>Description</h2>
+<p>MagickFlattenImages() merges a sequence of images. This is useful for
+combining Photoshop layers into a single image.</p>
+<p>The format of the MagickFlattenImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickFlattenImages( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickflipimage">
+<h1><a class="toc-backref" href="#id506">MagickFlipImage</a></h1>
+<div class="section" id="id85">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickFlipImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id86">
+<h2>Description</h2>
+<p>MagickFlipImage() creates a vertical mirror image by reflecting the pixels
+around the central x-axis.</p>
+<p>The format of the MagickFlipImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickFlipImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickflopimage">
+<h1><a class="toc-backref" href="#id507">MagickFlopImage</a></h1>
+<div class="section" id="id87">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickFlopImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id88">
+<h2>Description</h2>
+<p>MagickFlopImage() creates a horizontal mirror image by reflecting the pixels
+around the central y-axis.</p>
+<p>The format of the MagickFlopImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickFlopImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickframeimage">
+<h1><a class="toc-backref" href="#id508">MagickFrameImage</a></h1>
+<div class="section" id="id89">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickFrameImage( MagickWand *wand, const PixelWand *matte_color,
+ const unsigned long width, const unsigned long height,
+ const long inner_bevel, const long outer_bevel );
+</pre>
+</div>
+<div class="section" id="id90">
+<h2>Description</h2>
+<p>MagickFrameImage() adds a simulated three-dimensional border around the
+image. The width and height specify the border width of the vertical and
+horizontal sides of the frame. The inner and outer bevels indicate the
+width of the inner and outer shadows of the frame.</p>
+<p>The format of the MagickFrameImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickFrameImage( MagickWand *wand, const PixelWand *matte_color,
+ const unsigned long width, const unsigned long height,
+ const long inner_bevel, const long outer_bevel );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>matte_color:</dt>
+<dd>The frame color pixel wand.</dd>
+<dt>width:</dt>
+<dd>The border width.</dd>
+<dt>height:</dt>
+<dd>The border height.</dd>
+<dt>inner_bevel:</dt>
+<dd>The inner bevel width.</dd>
+<dt>outer_bevel:</dt>
+<dd>The outer bevel width.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickfximage">
+<h1><a class="toc-backref" href="#id509">MagickFxImage</a></h1>
+<div class="section" id="id91">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickFxImage( MagickWand *wand, const char *expression );
+</pre>
+</div>
+<div class="section" id="id92">
+<h2>Description</h2>
+<p>MagickFxImage() evaluate expression for each pixel in the image.</p>
+<p>The format of the MagickFxImage method is:</p>
+<pre class="literal-block">
+MagickWand *MagickFxImage( MagickWand *wand, const char *expression );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>expression:</dt>
+<dd>The expression.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickfximagechannel">
+<h1><a class="toc-backref" href="#id510">MagickFxImageChannel</a></h1>
+<div class="section" id="id93">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickFxImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const char *expression );
+</pre>
+</div>
+<div class="section" id="id94">
+<h2>Description</h2>
+<p>MagickFxImageChannel() evaluate expression for each pixel in the specified
+channel.</p>
+<p>The format of the MagickFxImageChannel method is:</p>
+<pre class="literal-block">
+MagickWand *MagickFxImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const char *expression );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to level: RedChannel, GreenChannel,
+BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+BlackChannel.</dd>
+<dt>expression:</dt>
+<dd>The expression.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgammaimage">
+<h1><a class="toc-backref" href="#id511">MagickGammaImage</a></h1>
+<div class="section" id="id95">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGammaImage( MagickWand *wand, const double gamma );
+</pre>
+</div>
+<div class="section" id="id96">
+<h2>Description</h2>
+<p>Use MagickGammaImage() to gamma-correct an image. The same image viewed on
+different devices will have perceptual differences in the way the
+image's intensities are represented on the screen. Specify individual
+gamma levels for the red, green, and blue channels, or adjust all three
+with the gamma parameter. Values typically range from 0.8 to 2.3.</p>
+<p>You can also reduce the influence of a particular channel with a gamma
+value of 0.</p>
+<p>The format of the MagickGammaImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickGammaImage( MagickWand *wand, const double gamma );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>gamme:</dt>
+<dd>Define the level of gamma correction.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgammaimagechannel">
+<h1><a class="toc-backref" href="#id512">MagickGammaImageChannel</a></h1>
+<div class="section" id="id97">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGammaImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double gamma );
+</pre>
+</div>
+<div class="section" id="id98">
+<h2>Description</h2>
+<p>Use MagickGammaImageChannel() to gamma-correct a particular image channel.
+The same image viewed on different devices will have perceptual differences
+in the way the image's intensities are represented on the screen. Specify
+individual gamma levels for the red, green, and blue channels, or adjust all
+three with the gamma parameter. Values typically range from 0.8 to 2.3.</p>
+<p>You can also reduce the influence of a particular channel with a gamma
+value of 0.</p>
+<p>The format of the MagickGammaImageChannel method is:</p>
+<pre class="literal-block">
+unsigned int MagickGammaImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double gamma );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>The channel.</dd>
+<dt>level:</dt>
+<dd>Define the level of gamma correction.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetconfigureinfo">
+<h1><a class="toc-backref" href="#id513">MagickGetConfigureInfo</a></h1>
+<div class="section" id="id99">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *MagickGetConfigureInfo( MagickWand *wand, const char *name );
+</pre>
+</div>
+<div class="section" id="id100">
+<h2>Description</h2>
+<p>MagickGetConfigureInfo() returns ImageMagick configure attributes such as
+NAME, VERSION, LIB_VERSION, COPYRIGHT, etc.</p>
+<p>The format of the MagickGetConfigureInfo() method is:</p>
+<pre class="literal-block">
+char *MagickGetConfigureInfo( MagickWand *wand, const char *name );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>name:</dt>
+<dd>Return the attribute associated with this name.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetcopyright">
+<h1><a class="toc-backref" href="#id514">MagickGetCopyright</a></h1>
+<div class="section" id="id101">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *MagickGetCopyright( void );
+</pre>
+</div>
+<div class="section" id="id102">
+<h2>Description</h2>
+<p>MagickGetCopyright() returns the ImageMagick API copyright as a string.</p>
+<p>The format of the MagickGetCopyright method is:</p>
+<pre class="literal-block">
+const char *MagickGetCopyright( void );
+</pre>
+</div>
+</div>
+<div class="section" id="magickgetexception">
+<h1><a class="toc-backref" href="#id515">MagickGetException</a></h1>
+<div class="section" id="id103">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *MagickGetException( const MagickWand *wand, <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> *severity );
+</pre>
+</div>
+<div class="section" id="id104">
+<h2>Description</h2>
+<p>MagickGetException() returns the severity, reason, and description of any
+error that occurs when using other methods in this API.</p>
+<p>The format of the MagickGetException method is:</p>
+<pre class="literal-block">
+char *MagickGetException( const MagickWand *wand, <a class="reference external" href="../api/types.html#exceptiontype">ExceptionType</a> *severity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>severity:</dt>
+<dd>The severity of the error is returned here.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetfilename">
+<h1><a class="toc-backref" href="#id516">MagickGetFilename</a></h1>
+<div class="section" id="id105">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *MagickGetFilename( const MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id106">
+<h2>Description</h2>
+<p>MagickGetFilename() returns the filename associated with an image sequence.</p>
+<p>The format of the MagickGetFilename method is:</p>
+<pre class="literal-block">
+const char *MagickGetFilename( const MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgethomeurl">
+<h1><a class="toc-backref" href="#id517">MagickGetHomeURL</a></h1>
+<div class="section" id="id107">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *MagickGetHomeURL( void );
+</pre>
+</div>
+<div class="section" id="id108">
+<h2>Description</h2>
+<p>MagickGetHomeURL() returns the ImageMagick home URL.</p>
+<p>The format of the MagickGetHomeURL method is:</p>
+<pre class="literal-block">
+const char *MagickGetHomeURL( void );
+</pre>
+</div>
+</div>
+<div class="section" id="magickgetimage">
+<h1><a class="toc-backref" href="#id518">MagickGetImage</a></h1>
+<div class="section" id="id109">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickGetImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id110">
+<h2>Description</h2>
+<p>MagickGetImage() clones the image at the current image index.</p>
+<p>The format of the MagickGetImage method is:</p>
+<pre class="literal-block">
+MagickWand *MagickGetImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageattribute">
+<h1><a class="toc-backref" href="#id519">MagickGetImageAttribute</a></h1>
+<div class="section" id="id111">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *MagickGetImageAttribute( MagickWand *wand, const char *name );
+</pre>
+</div>
+<div class="section" id="id112">
+<h2>Description</h2>
+<p>MagickGetImageAttribute returns an image attribute as a string</p>
+<p>The format of the MagickGetImageAttribute method is:</p>
+<pre class="literal-block">
+char *MagickGetImageAttribute( MagickWand *wand, const char *name );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>name:</dt>
+<dd>The name of the attribute</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagebackgroundcolor">
+<h1><a class="toc-backref" href="#id520">MagickGetImageBackgroundColor</a></h1>
+<div class="section" id="id113">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageBackgroundColor( MagickWand *wand, PixelWand *background_color );
+</pre>
+</div>
+<div class="section" id="id114">
+<h2>Description</h2>
+<p>MagickGetImageBackgroundColor() returns the image background color.</p>
+<p>The format of the MagickGetImageBackgroundColor method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageBackgroundColor( MagickWand *wand, PixelWand *background_color );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>background_color:</dt>
+<dd>Return the background color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageblueprimary">
+<h1><a class="toc-backref" href="#id521">MagickGetImageBluePrimary</a></h1>
+<div class="section" id="id115">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageBluePrimary( MagickWand *wand, double *x, double *y );
+</pre>
+</div>
+<div class="section" id="id116">
+<h2>Description</h2>
+<p>MagickGetImageBluePrimary() returns the chromaticy blue primary point for the
+image.</p>
+<p>The format of the MagickGetImageBluePrimary method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageBluePrimary( MagickWand *wand, double *x, double *y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The chromaticity blue primary x-point.</dd>
+<dt>y:</dt>
+<dd>The chromaticity blue primary y-point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagebordercolor">
+<h1><a class="toc-backref" href="#id522">MagickGetImageBorderColor</a></h1>
+<div class="section" id="id117">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageBorderColor( MagickWand *wand, PixelWand *border_color );
+</pre>
+</div>
+<div class="section" id="id118">
+<h2>Description</h2>
+<p>MagickGetImageBorderColor() returns the image border color.</p>
+<p>The format of the MagickGetImageBorderColor method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageBorderColor( MagickWand *wand, PixelWand *border_color );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>border_color:</dt>
+<dd>Return the border color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageboundingbox">
+<h1><a class="toc-backref" href="#id523">MagickGetImageBoundingBox</a></h1>
+<div class="section" id="id119">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageBoundingBox( MagickWand *wand, const double fuzz,
+ unsigned long *width, unsigned long *height,
+ long *x, long *y );
+</pre>
+</div>
+<div class="section" id="id120">
+<h2>Description</h2>
+<p>MagickGetImageBoundingBox() obtains the crop bounding box required to
+remove a solid-color border from the image. Color quantums which differ
+less than the fuzz setting are considered to be the same. If a border is
+not detected, then the the original image dimensions are returned. The
+crop bounding box estimation uses the same algorithm as MagickTrimImage().</p>
+<p>The format of the MagickGetImageBoundingBox method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageBoundingBox( MagickWand *wand, const double fuzz,
+ unsigned long *width, unsigned long *height,
+ long *x, long *y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>fuzz:</dt>
+<dd>Color comparison fuzz factor. Use 0.0 for exact match.</dd>
+<dt>width:</dt>
+<dd>The crop width</dd>
+<dt>height:</dt>
+<dd>The crop height</dd>
+<dt>x:</dt>
+<dd>The crop x offset</dd>
+<dt>y:</dt>
+<dd>The crop y offset</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagechanneldepth">
+<h1><a class="toc-backref" href="#id524">MagickGetImageChannelDepth</a></h1>
+<div class="section" id="id121">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetImageChannelDepth( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel );
+</pre>
+</div>
+<div class="section" id="id122">
+<h2>Description</h2>
+<p>MagickGetImageChannelDepth() gets the depth for a particular image channel.</p>
+<p>The format of the MagickGetImageChannelDepth method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetImageChannelDepth( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to extract: RedChannel, GreenChannel,
+BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+BlackChannel.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagechannelextrema">
+<h1><a class="toc-backref" href="#id525">MagickGetImageChannelExtrema</a></h1>
+<div class="section" id="id123">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageChannelExtrema( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ unsigned long *minima, unsigned long *maxima );
+</pre>
+</div>
+<div class="section" id="id124">
+<h2>Description</h2>
+<p>MagickGetImageChannelExtrema() gets the extrema for one or more image
+channels.</p>
+<p>The format of the MagickGetImageChannelExtrema method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageChannelExtrema( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ unsigned long *minima, unsigned long *maxima );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to extract: RedChannel, GreenChannel,
+BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+or BlackChannel.</dd>
+<dt>minima:</dt>
+<dd>The minimum pixel value for the specified channel(s).</dd>
+<dt>maxima:</dt>
+<dd>The maximum pixel value for the specified channel(s).</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagechannelmean">
+<h1><a class="toc-backref" href="#id526">MagickGetImageChannelMean</a></h1>
+<div class="section" id="id125">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageChannelMean( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ double *mean, double *standard_deviation );
+</pre>
+</div>
+<div class="section" id="id126">
+<h2>Description</h2>
+<p>MagickGetImageChannelMean() gets the mean and standard deviation of one or
+more image channels.</p>
+<p>The format of the MagickGetImageChannelMean method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageChannelMean( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ double *mean, double *standard_deviation );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to extract: RedChannel, GreenChannel,
+BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+or BlackChannel.</dd>
+<dt>mean:</dt>
+<dd>The mean pixel value for the specified channel(s).</dd>
+<dt>standard_deviation:</dt>
+<dd>The standard deviation for the specified channel(s).</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagecolormapcolor">
+<h1><a class="toc-backref" href="#id527">MagickGetImageColormapColor</a></h1>
+<div class="section" id="id127">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageColormapColor( MagickWand *wand, const unsigned long index,
+ PixelWand *color );
+</pre>
+</div>
+<div class="section" id="id128">
+<h2>Description</h2>
+<p>MagickGetImageColormapColor() returns the color of the specified colormap
+index.</p>
+<p>The format of the MagickGetImageColormapColor method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageColormapColor( MagickWand *wand, const unsigned long index,
+ PixelWand *color );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>index:</dt>
+<dd>The offset into the image colormap.</dd>
+<dt>color:</dt>
+<dd>Return the colormap color in this wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagecolors">
+<h1><a class="toc-backref" href="#id528">MagickGetImageColors</a></h1>
+<div class="section" id="id129">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetImageColors( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id130">
+<h2>Description</h2>
+<p>MagickGetImageColors() gets the number of unique colors in the image.</p>
+<p>The format of the MagickGetImageColors method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetImageColors( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagecolorspace">
+<h1><a class="toc-backref" href="#id529">MagickGetImageColorspace</a></h1>
+<div class="section" id="id131">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> MagickGetImageColorspace( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id132">
+<h2>Description</h2>
+<p>MagickGetImageColorspace() gets the image colorspace.</p>
+<p>The format of the MagickGetImageColorspace method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> MagickGetImageColorspace( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagecompose">
+<h1><a class="toc-backref" href="#id530">MagickGetImageCompose</a></h1>
+<div class="section" id="id133">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> MagickGetImageCompose( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id134">
+<h2>Description</h2>
+<p>MagickGetImageCompose() returns the composite operator associated with the
+image.</p>
+<p>The format of the MagickGetImageCompose method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> MagickGetImageCompose( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagecompression">
+<h1><a class="toc-backref" href="#id531">MagickGetImageCompression</a></h1>
+<div class="section" id="id135">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#compressiontype">CompressionType</a> MagickGetImageCompression( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id136">
+<h2>Description</h2>
+<p>MagickGetImageCompression() gets the image compression.</p>
+<p>The format of the MagickGetImageCompression method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#compressiontype">CompressionType</a> MagickGetImageCompression( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagedelay">
+<h1><a class="toc-backref" href="#id532">MagickGetImageDelay</a></h1>
+<div class="section" id="id137">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetImageDelay( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id138">
+<h2>Description</h2>
+<p>MagickGetImageDelay() gets the image delay.</p>
+<p>The format of the MagickGetImageDelay method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetImageDelay( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagedepth">
+<h1><a class="toc-backref" href="#id533">MagickGetImageDepth</a></h1>
+<div class="section" id="id139">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetImageDepth( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id140">
+<h2>Description</h2>
+<p>MagickGetImageDepth() gets the image depth.</p>
+<p>The format of the MagickGetImageDepth method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetImageDepth( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageextrema">
+<h1><a class="toc-backref" href="#id534">MagickGetImageExtrema</a></h1>
+<div class="section" id="id141">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageExtrema( MagickWand *wand, unsigned long *min,
+ unsigned long *max );
+</pre>
+</div>
+<div class="section" id="id142">
+<h2>Description</h2>
+<p>MagickGetImageExtrema() gets the extrema for the image.</p>
+<p>The format of the MagickGetImageExtrema method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageExtrema( MagickWand *wand, unsigned long *min,
+ unsigned long *max );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>min:</dt>
+<dd>The minimum pixel value for the specified channel(s).</dd>
+<dt>max:</dt>
+<dd>The maximum pixel value for the specified channel(s).</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagedispose">
+<h1><a class="toc-backref" href="#id535">MagickGetImageDispose</a></h1>
+<div class="section" id="id143">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+DisposeType MagickGetImageDispose( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id144">
+<h2>Description</h2>
+<p>MagickGetImageDispose() gets the image disposal method.</p>
+<p>The format of the MagickGetImageDispose method is:</p>
+<pre class="literal-block">
+DisposeType MagickGetImageDispose( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagefilename">
+<h1><a class="toc-backref" href="#id536">MagickGetImageFilename</a></h1>
+<div class="section" id="id145">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char MagickGetImageFilename( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id146">
+<h2>Description</h2>
+<p>MagickGetImageFilename() returns the filename of a particular image in a
+sequence.</p>
+<p>The format of the MagickGetImageFilename method is:</p>
+<pre class="literal-block">
+const char MagickGetImageFilename( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageformat">
+<h1><a class="toc-backref" href="#id537">MagickGetImageFormat</a></h1>
+<div class="section" id="id147">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char MagickGetImageFormat( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id148">
+<h2>Description</h2>
+<p>MagickGetImageFormat() returns the format of a particular image in a
+sequence.</p>
+<p>The format of the MagickGetImageFormat method is:</p>
+<pre class="literal-block">
+const char MagickGetImageFormat( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagefuzz">
+<h1><a class="toc-backref" href="#id538">MagickGetImageFuzz</a></h1>
+<div class="section" id="id149">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double MagickGetImageFuzz( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id150">
+<h2>Description</h2>
+<p>MagickGetImageFuzz() returns the color comparison fuzz factor. Colors
+closer than the fuzz factor are considered to be the same when comparing
+colors. Note that some other functions such as MagickColorFloodfillImage()
+implicitly set this value.</p>
+<p>The format of the MagickGetImageFuzz method is:</p>
+<pre class="literal-block">
+double MagickGetImageFuzz( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagegamma">
+<h1><a class="toc-backref" href="#id539">MagickGetImageGamma</a></h1>
+<div class="section" id="id151">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double MagickGetImageGamma( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id152">
+<h2>Description</h2>
+<p>MagickGetImageGamma() gets the image gamma.</p>
+<p>The format of the MagickGetImageGamma method is:</p>
+<pre class="literal-block">
+double MagickGetImageGamma( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagegravity">
+<h1><a class="toc-backref" href="#id540">MagickGetImageGravity</a></h1>
+<div class="section" id="id153">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#gravitytype">GravityType</a> MagickGetImageGravity( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id154">
+<h2>Description</h2>
+<p>MagickGetImageGravity() gets the image gravity.</p>
+<p>The format of the MagickGetImageGravity method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#gravitytype">GravityType</a> MagickGetImageGravity( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagegreenprimary">
+<h1><a class="toc-backref" href="#id541">MagickGetImageGreenPrimary</a></h1>
+<div class="section" id="id155">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageGreenPrimary( MagickWand *wand, double *x, double *y );
+</pre>
+</div>
+<div class="section" id="id156">
+<h2>Description</h2>
+<p>MagickGetImageGreenPrimary() returns the chromaticy green primary point.</p>
+<p>The format of the MagickGetImageGreenPrimary method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageGreenPrimary( MagickWand *wand, double *x, double *y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The chromaticity green primary x-point.</dd>
+<dt>y:</dt>
+<dd>The chromaticity green primary y-point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageheight">
+<h1><a class="toc-backref" href="#id542">MagickGetImageHeight</a></h1>
+<div class="section" id="id157">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetImageHeight( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id158">
+<h2>Description</h2>
+<p>MagickGetImageHeight() returns the image height.</p>
+<p>The format of the MagickGetImageHeight method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetImageHeight( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagehistogram">
+<h1><a class="toc-backref" href="#id543">MagickGetImageHistogram</a></h1>
+<div class="section" id="id159">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+PixelWand *MagickGetImageHistogram( MagickWand *wand, unsigned long *number_colors );
+</pre>
+</div>
+<div class="section" id="id160">
+<h2>Description</h2>
+<p>MagickGetImageHistogram() returns the image histogram as an array of
+PixelWand wands.</p>
+<p>The format of the MagickGetImageHistogram method is:</p>
+<pre class="literal-block">
+PixelWand *MagickGetImageHistogram( MagickWand *wand, unsigned long *number_colors );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>number_colors:</dt>
+<dd>The number of unique colors in the image and the number
+of pixel wands returned.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageindex">
+<h1><a class="toc-backref" href="#id544">MagickGetImageIndex</a></h1>
+<div class="section" id="id161">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageIndex( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id162">
+<h2>Description</h2>
+<p>MagickGetImageIndex() returns the index of the current image.</p>
+<p>The format of the MagickGetImageIndex method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageIndex( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageinterlacescheme">
+<h1><a class="toc-backref" href="#id545">MagickGetImageInterlaceScheme</a></h1>
+<div class="section" id="id163">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#interlacetype">InterlaceType</a> MagickGetImageInterlaceScheme( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id164">
+<h2>Description</h2>
+<p>MagickGetImageInterlaceScheme() gets the image interlace scheme.</p>
+<p>The format of the MagickGetImageInterlaceScheme method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#interlacetype">InterlaceType</a> MagickGetImageInterlaceScheme( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageiterations">
+<h1><a class="toc-backref" href="#id546">MagickGetImageIterations</a></h1>
+<div class="section" id="id165">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetImageIterations( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id166">
+<h2>Description</h2>
+<p>MagickGetImageIterations() gets the image iterations.</p>
+<p>The format of the MagickGetImageIterations method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetImageIterations( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagemattecolor">
+<h1><a class="toc-backref" href="#id547">MagickGetImageMatteColor</a></h1>
+<div class="section" id="id167">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageMatteColor( MagickWand *wand, PixelWand *matte_color );
+</pre>
+</div>
+<div class="section" id="id168">
+<h2>Description</h2>
+<p>MagickGetImageMatteColor() returns the image matte color.</p>
+<p>The format of the MagickGetImageMatteColor method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageMatteColor( MagickWand *wand, PixelWand *matte_color );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>matte_color:</dt>
+<dd>Return the matte color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageorientation">
+<h1><a class="toc-backref" href="#id548">MagickGetImageOrientation</a></h1>
+<div class="section" id="id169">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+OrientationType MagickGetImageOrientation( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id170">
+<h2>Description</h2>
+<p>MagickGetImageOrientation() gets the image orientation type. May be one of:</p>
+<p>UndefinedOrientation Image orientation not specified or error.
+TopLeftOrientation Left to right and Top to bottom.
+TopRightOrientation Right to left and Top to bottom.
+BottomRightOrientation Right to left and Bottom to top.
+BottomLeftOrientation Left to right and Bottom to top.
+LeftTopOrientation Top to bottom and Left to right.
+RightTopOrientation Top to bottom and Right to left.
+RightBottomOrientation Bottom to top and Right to left.
+LeftBottomOrientation Bottom to top and Left to right.</p>
+<p>The format of the MagickGetImageOrientation method is:</p>
+<pre class="literal-block">
+OrientationType MagickGetImageOrientation( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagepage">
+<h1><a class="toc-backref" href="#id549">MagickGetImagePage</a></h1>
+<div class="section" id="id171">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickGetImagePage( MagickWand *wand, unsigned long *width, unsigned long *height, long *x,
+ long *y );
+</pre>
+</div>
+<div class="section" id="id172">
+<h2>Description</h2>
+<p>MagickGetImagePage() retrieves the image page size and offset used when
+placing (e.g. compositing) the image.</p>
+<p>The format of the MagickGetImagePage method is:</p>
+<pre class="literal-block">
+MagickGetImagePage( MagickWand *wand, unsigned long *width, unsigned long *height, long *x,
+ long *y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>width, height:</dt>
+<dd>The region size.</dd>
+<dt>x, y:</dt>
+<dd>Offset (from top left) on base canvas image on
+which to composite image data.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagepixels">
+<h1><a class="toc-backref" href="#id550">MagickGetImagePixels</a></h1>
+<div class="section" id="id173">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImagePixels( MagickWand *wand, const long x_offset, const long y_offset,
+ const unsigned long columns, const unsigned long rows,
+ const char *map, const <a class="reference external" href="../api/types.html#storagetype">StorageType</a> storage,
+ unsigned char *pixels );
+</pre>
+</div>
+<div class="section" id="id174">
+<h2>Description</h2>
+<p>MagickGetImagePixels() extracts pixel data from an image and returns it to
+you. The method returns False on success otherwise True if an error is
+encountered. The data is returned as char, short int, int, long, float,
+or double in the order specified by map.</p>
+<p>Suppose you want to extract the first scanline of a 640x480 image as
+character data in red-green-blue order:</p>
+<p>MagickGetImagePixels(wand,0,0,640,1,&quot;RGB&quot;,CharPixel,pixels);</p>
+<p>The format of the MagickGetImagePixels method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImagePixels( MagickWand *wand, const long x_offset, const long y_offset,
+ const unsigned long columns, const unsigned long rows,
+ const char *map, const <a class="reference external" href="../api/types.html#storagetype">StorageType</a> storage,
+ unsigned char *pixels );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x_offset, y_offset, columns, rows:</dt>
+<dd>These values define the perimeter
+of a region of pixels you want to extract.</dd>
+<dt>map:</dt>
+<dd>This string reflects the expected ordering of the pixel array.
+It can be any combination or order of R = red, G = green, B = blue,
+A = alpha, C = cyan, Y = yellow, M = magenta, K = black, or
+I = intensity (for grayscale).</dd>
+<dt>storage:</dt>
+<dd>Define the data type of the pixels. Float and double types are
+expected to be normalized [0..1] otherwise [0..MaxRGB]. Choose from
+these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
+or DoublePixel.</dd>
+<dt>pixels:</dt>
+<dd>This array of values contain the pixel components as defined by
+map and type. You must preallocate this array where the expected
+length varies depending on the values of width, height, map, and type.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageprofile">
+<h1><a class="toc-backref" href="#id551">MagickGetImageProfile</a></h1>
+<div class="section" id="id175">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned char *MagickGetImageProfile( MagickWand *wand, const char *name,
+ unsigned long *length );
+</pre>
+</div>
+<div class="section" id="id176">
+<h2>Description</h2>
+<p>MagickGetImageProfile() returns the named image profile.</p>
+<p>The format of the MagickGetImageProfile method is:</p>
+<pre class="literal-block">
+unsigned char *MagickGetImageProfile( MagickWand *wand, const char *name,
+ unsigned long *length );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>name:</dt>
+<dd>Name of profile to return: ICC, IPTC, or generic profile.</dd>
+<dt>length:</dt>
+<dd>The length of the profile.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageredprimary">
+<h1><a class="toc-backref" href="#id552">MagickGetImageRedPrimary</a></h1>
+<div class="section" id="id177">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageRedPrimary( MagickWand *wand, double *x, double *y );
+</pre>
+</div>
+<div class="section" id="id178">
+<h2>Description</h2>
+<p>MagickGetImageRedPrimary() returns the chromaticy red primary point.</p>
+<p>The format of the MagickGetImageRedPrimary method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageRedPrimary( MagickWand *wand, double *x, double *y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The chromaticity red primary x-point.</dd>
+<dt>y:</dt>
+<dd>The chromaticity red primary y-point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagerenderingintent">
+<h1><a class="toc-backref" href="#id553">MagickGetImageRenderingIntent</a></h1>
+<div class="section" id="id179">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#renderingintent">RenderingIntent</a> MagickGetImageRenderingIntent( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id180">
+<h2>Description</h2>
+<p>MagickGetImageRenderingIntent() gets the image rendering intent.</p>
+<p>The format of the MagickGetImageRenderingIntent method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#renderingintent">RenderingIntent</a> MagickGetImageRenderingIntent( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageresolution">
+<h1><a class="toc-backref" href="#id554">MagickGetImageResolution</a></h1>
+<div class="section" id="id181">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageResolution( MagickWand *wand, double *x, double *y );
+</pre>
+</div>
+<div class="section" id="id182">
+<h2>Description</h2>
+<p>MagickGetImageResolution() gets the image X &amp; Y resolution.</p>
+<p>The format of the MagickGetImageResolution method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageResolution( MagickWand *wand, double *x, double *y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The image x-resolution.</dd>
+<dt>y:</dt>
+<dd>The image y-resolution.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagescene">
+<h1><a class="toc-backref" href="#id555">MagickGetImageScene</a></h1>
+<div class="section" id="id183">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetImageScene( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id184">
+<h2>Description</h2>
+<p>MagickGetImageScene() gets the image scene.</p>
+<p>The format of the MagickGetImageScene method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetImageScene( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagesignature">
+<h1><a class="toc-backref" href="#id556">MagickGetImageSignature</a></h1>
+<div class="section" id="id185">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char MagickGetImageSignature( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id186">
+<h2>Description</h2>
+<p>MagickGetImageSignature() generates an SHA-256 message digest for the image
+pixel stream.</p>
+<p>The format of the MagickGetImageSignature method is:</p>
+<pre class="literal-block">
+const char MagickGetImageSignature( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagesize">
+<h1><a class="toc-backref" href="#id557">MagickGetImageSize</a></h1>
+<div class="section" id="id187">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickSizeType MagickGetImageSize( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id188">
+<h2>Description</h2>
+<p>MagickGetImageSize() returns the image size.</p>
+<p>The format of the MagickGetImageSize method is:</p>
+<pre class="literal-block">
+MagickSizeType MagickGetImageSize( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagetype">
+<h1><a class="toc-backref" href="#id558">MagickGetImageType</a></h1>
+<div class="section" id="id189">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#imagetype">ImageType</a> MagickGetImageType( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id190">
+<h2>Description</h2>
+<p>MagickGetImageType() gets the image type.</p>
+<p>The format of the MagickGetImageType method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#imagetype">ImageType</a> MagickGetImageType( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagesavedtype">
+<h1><a class="toc-backref" href="#id559">MagickGetImageSavedType</a></h1>
+<div class="section" id="id191">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#imagetype">ImageType</a> MagickGetImageSavedType( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id192">
+<h2>Description</h2>
+<p>MagickGetImageSavedType() gets the image type that will be used when the
+image is saved. This may be different to the current image type, returned
+by MagickGetImageType().</p>
+<p>The format of the MagickGetImageSavedType method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#imagetype">ImageType</a> MagickGetImageSavedType( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimageunits">
+<h1><a class="toc-backref" href="#id560">MagickGetImageUnits</a></h1>
+<div class="section" id="id193">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#resolutiontype">ResolutionType</a> MagickGetImageUnits( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id194">
+<h2>Description</h2>
+<p>MagickGetImageUnits() gets the image units of resolution.</p>
+<p>The format of the MagickGetImageUnits method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#resolutiontype">ResolutionType</a> MagickGetImageUnits( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagevirtualpixelmethod">
+<h1><a class="toc-backref" href="#id561">MagickGetImageVirtualPixelMethod</a></h1>
+<div class="section" id="id195">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#virtualpixelmethod">VirtualPixelMethod</a> MagickGetImageVirtualPixelMethod( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id196">
+<h2>Description</h2>
+<p>MagickGetImageVirtualPixelMethod() returns the virtual pixel method for the
+sepcified image.</p>
+<p>The format of the MagickGetImageVirtualPixelMethod method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#virtualpixelmethod">VirtualPixelMethod</a> MagickGetImageVirtualPixelMethod( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagewhitepoint">
+<h1><a class="toc-backref" href="#id562">MagickGetImageWhitePoint</a></h1>
+<div class="section" id="id197">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetImageWhitePoint( MagickWand *wand, double *x, double *y );
+</pre>
+</div>
+<div class="section" id="id198">
+<h2>Description</h2>
+<p>MagickGetImageWhitePoint() returns the chromaticy white point.</p>
+<p>The format of the MagickGetImageWhitePoint method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetImageWhitePoint( MagickWand *wand, double *x, double *y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The chromaticity white x-point.</dd>
+<dt>y:</dt>
+<dd>The chromaticity white y-point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetimagewidth">
+<h1><a class="toc-backref" href="#id563">MagickGetImageWidth</a></h1>
+<div class="section" id="id199">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetImageWidth( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id200">
+<h2>Description</h2>
+<p>MagickGetImageWidth() returns the image width.</p>
+<p>The format of the MagickGetImageWidth method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetImageWidth( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetnumberimages">
+<h1><a class="toc-backref" href="#id564">MagickGetNumberImages</a></h1>
+<div class="section" id="id201">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetNumberImages( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id202">
+<h2>Description</h2>
+<p>MagickGetNumberOfImages() returns the number of images associated with a
+magick wand.</p>
+<p>The format of the MagickGetNumberImages method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetNumberImages( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetpackagename">
+<h1><a class="toc-backref" href="#id565">MagickGetPackageName</a></h1>
+<div class="section" id="id203">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *MagickGetPackageName( void );
+</pre>
+</div>
+<div class="section" id="id204">
+<h2>Description</h2>
+<p>MagickGetPackageName() returns the ImageMagick package name.</p>
+<p>The format of the MagickGetPackageName method is:</p>
+<pre class="literal-block">
+const char *MagickGetPackageName( void );
+</pre>
+</div>
+</div>
+<div class="section" id="magickgetquantumdepth">
+<h1><a class="toc-backref" href="#id566">MagickGetQuantumDepth</a></h1>
+<div class="section" id="id205">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *MagickGetQuantumDepth( unsigned long *depth );
+</pre>
+</div>
+<div class="section" id="id206">
+<h2>Description</h2>
+<p>MagickGetQuantumDepth() returns the ImageMagick quantum depth.</p>
+<p>The format of the MagickGetQuantumDepth method is:</p>
+<pre class="literal-block">
+const char *MagickGetQuantumDepth( unsigned long *depth );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>depth:</dt>
+<dd>The quantum depth is returned as a number.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetreleasedate">
+<h1><a class="toc-backref" href="#id567">MagickGetReleaseDate</a></h1>
+<div class="section" id="id207">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *MagickGetReleaseDate( void );
+</pre>
+</div>
+<div class="section" id="id208">
+<h2>Description</h2>
+<p>MagickGetReleaseDate() returns the ImageMagick release date.</p>
+<p>The format of the MagickGetReleaseDate method is:</p>
+<pre class="literal-block">
+const char *MagickGetReleaseDate( void );
+</pre>
+</div>
+</div>
+<div class="section" id="magickgetresourcelimit">
+<h1><a class="toc-backref" href="#id568">MagickGetResourceLimit</a></h1>
+<div class="section" id="id209">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long MagickGetResourceLimit( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type );
+</pre>
+</div>
+<div class="section" id="id210">
+<h2>Description</h2>
+<p>MagickGetResourceLimit() returns the the specified resource in megabytes.</p>
+<p>The format of the MagickGetResourceLimit method is:</p>
+<pre class="literal-block">
+unsigned long MagickGetResourceLimit( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetsamplingfactors">
+<h1><a class="toc-backref" href="#id569">MagickGetSamplingFactors</a></h1>
+<div class="section" id="id211">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double *MagickGetSamplingFactors( MagickWand *wand, unsigned long *number_factors );
+</pre>
+</div>
+<div class="section" id="id212">
+<h2>Description</h2>
+<p>MagickGetSamplingFactors() gets the horizontal and vertical sampling factor.</p>
+<p>The format of the MagickGetSamplingFactors method is:</p>
+<pre class="literal-block">
+double *MagickGetSamplingFactors( MagickWand *wand, unsigned long *number_factors );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>number_factors:</dt>
+<dd>The number of factors in the returned array.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetsize">
+<h1><a class="toc-backref" href="#id570">MagickGetSize</a></h1>
+<div class="section" id="id213">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickGetSize( const MagickWand *wand, unsigned long *columns,
+ unsigned long *rows );
+</pre>
+</div>
+<div class="section" id="id214">
+<h2>Description</h2>
+<p>MagickGetSize() returns the size associated with the magick wand.</p>
+<p>The format of the MagickGetSize method is:</p>
+<pre class="literal-block">
+unsigned int MagickGetSize( const MagickWand *wand, unsigned long *columns,
+ unsigned long *rows );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>columns:</dt>
+<dd>The width in pixels.</dd>
+<dt>height:</dt>
+<dd>The height in pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickgetversion">
+<h1><a class="toc-backref" href="#id571">MagickGetVersion</a></h1>
+<div class="section" id="id215">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+const char *MagickGetVersion( unsigned long *version );
+</pre>
+</div>
+<div class="section" id="id216">
+<h2>Description</h2>
+<p>MagickGetVersion() returns the ImageMagick API version as a string and
+as a number.</p>
+<p>The format of the MagickGetVersion method is:</p>
+<pre class="literal-block">
+const char *MagickGetVersion( unsigned long *version );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>version:</dt>
+<dd>The ImageMagick version is returned as a number.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickhaldclutimage">
+<h1><a class="toc-backref" href="#id572">MagickHaldClutImage</a></h1>
+<div class="section" id="id217">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickPassFail MagickHaldClutImage( MagickWand *wand, const MagickWand *clut_wand );
+</pre>
+</div>
+<div class="section" id="id218">
+<h2>Description</h2>
+<p>The MagickHaldClutImage() method apply a color lookup table (Hald CLUT) to
+the image. The fundamental principle of the Hald CLUT algorithm is that
+application of an identity CLUT causes no change to the input image,
+but an identity CLUT image which has had its colors transformed in
+some way (e.g. in Adobe Photoshop) may be used to implement an identical
+transform on any other image.</p>
+<p>The minimum CLUT level is 2, and the maximum depends on available memory
+(largest successfully tested is 24). A CLUT image is required to have equal
+width and height. A CLUT of level 8 is an image of dimension 512x512, a CLUT
+of level 16 is an image of dimension 4096x4096. Interpolation is used so
+extremely large CLUT images are not required.</p>
+<p>GraphicsMagick provides an 'identity' coder which may be used to generate
+identity HLUTs. For example, reading from &quot;identity:8&quot; creates an identity
+CLUT of order 8.</p>
+<p>The Hald CLUT algorithm has been developed by Eskil Steenberg as described
+at <a class="reference external" href="http://www.quelsolaar.com/technology/clut.html">http://www.quelsolaar.com/technology/clut.html</a>, and was adapted for
+GraphicsMagick by Clément Follet with support from Cédric Lejeune of
+Workflowers.</p>
+<p>The format of the HaldClutImage method is:</p>
+<pre class="literal-block">
+MagickPassFail MagickHaldClutImage( MagickWand *wand, const MagickWand *clut_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The image wand.</dd>
+<dt>clut_wand:</dt>
+<dd>The color lookup table image wand</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickhasnextimage">
+<h1><a class="toc-backref" href="#id573">MagickHasNextImage</a></h1>
+<div class="section" id="id219">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickHasNextImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id220">
+<h2>Description</h2>
+<p>MagickHasNextImage() returns True if the wand has more images when
+traversing the list in the forward direction</p>
+<p>The format of the MagickHasNextImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickHasNextImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickhaspreviousimage">
+<h1><a class="toc-backref" href="#id574">MagickHasPreviousImage</a></h1>
+<div class="section" id="id221">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickHasPreviousImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id222">
+<h2>Description</h2>
+<p>MagickHasPreviousImage() returns True if the wand has more images when
+traversing the list in the reverse direction</p>
+<p>The format of the MagickHasPreviousImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickHasPreviousImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickimplodeimage">
+<h1><a class="toc-backref" href="#id575">MagickImplodeImage</a></h1>
+<div class="section" id="id223">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickImplodeImage( MagickWand *wand, const double radius );
+</pre>
+</div>
+<div class="section" id="id224">
+<h2>Description</h2>
+<p>MagickImplodeImage() creates a new image that is a copy of an existing
+one with the image pixels &quot;implode&quot; by the specified percentage. It
+allocates the memory necessary for the new Image structure and returns a
+pointer to the new image.</p>
+<p>The format of the MagickImplodeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickImplodeImage( MagickWand *wand, const double radius );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>amount:</dt>
+<dd>Define the extent of the implosion.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicklabelimage">
+<h1><a class="toc-backref" href="#id576">MagickLabelImage</a></h1>
+<div class="section" id="id225">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickLabelImage( MagickWand *wand, const char *label );
+</pre>
+</div>
+<div class="section" id="id226">
+<h2>Description</h2>
+<p>MagickLabelImage() adds a label to your image.</p>
+<p>The format of the MagickLabelImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickLabelImage( MagickWand *wand, const char *label );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>label:</dt>
+<dd>The image label.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicklevelimage">
+<h1><a class="toc-backref" href="#id577">MagickLevelImage</a></h1>
+<div class="section" id="id227">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickLevelImage( MagickWand *wand, const double black_point, const double gamma,
+ const double white_point );
+</pre>
+</div>
+<div class="section" id="id228">
+<h2>Description</h2>
+<p>MagickLevelImage() adjusts the levels of an image by scaling the colors
+falling between specified white and black points to the full available
+quantum range. The parameters provided represent the black, mid, and white
+points. The black point specifies the darkest color in the image. Colors
+darker than the black point are set to zero. Mid point specifies a gamma
+correction to apply to the image. White point specifies the lightest color
+in the image. Colors brighter than the white point are set to the maximum
+quantum value.</p>
+<p>The format of the MagickLevelImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickLevelImage( MagickWand *wand, const double black_point, const double gamma,
+ const double white_point );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>black_point:</dt>
+<dd>The black point.</dd>
+<dt>gamma:</dt>
+<dd>The gamma.</dd>
+<dt>white_point:</dt>
+<dd>The white point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicklevelimagechannel">
+<h1><a class="toc-backref" href="#id578">MagickLevelImageChannel</a></h1>
+<div class="section" id="id229">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickLevelImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double black_point, const double gamma,
+ const double white_point );
+</pre>
+</div>
+<div class="section" id="id230">
+<h2>Description</h2>
+<p>MagickLevelImageChannel() adjusts the levels of the specified channel of
+the reference image by scaling the colors falling between specified white
+and black points to the full available quantum range. The parameters
+provided represent the black, mid, and white points. The black point
+specifies the darkest color in the image. Colors darker than the black
+point are set to zero. Mid point specifies a gamma correction to apply
+to the image. White point specifies the lightest color in the image.
+Colors brighter than the white point are set to the maximum quantum value.</p>
+<p>The format of the MagickLevelImageChannel method is:</p>
+<pre class="literal-block">
+unsigned int MagickLevelImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double black_point, const double gamma,
+ const double white_point );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to level: RedChannel, GreenChannel,
+BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+BlackChannel.</dd>
+<dt>black_point:</dt>
+<dd>The black point.</dd>
+<dt>gamma:</dt>
+<dd>The gamma.</dd>
+<dt>white_point:</dt>
+<dd>The white point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmagnifyimage">
+<h1><a class="toc-backref" href="#id579">MagickMagnifyImage</a></h1>
+<div class="section" id="id231">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickMagnifyImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id232">
+<h2>Description</h2>
+<p>MagickMagnifyImage() is a convenience method that scales an image
+proportionally to twice its original size.</p>
+<p>The format of the MagickMagnifyImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickMagnifyImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmapimage">
+<h1><a class="toc-backref" href="#id580">MagickMapImage</a></h1>
+<div class="section" id="id233">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickMapImage( MagickWand *wand, const MagickWand *map_wand,
+ const unsigned int dither );
+</pre>
+</div>
+<div class="section" id="id234">
+<h2>Description</h2>
+<p>MagickMapImage() replaces the colors of an image with the closest color
+from a reference image.</p>
+<p>The format of the MagickMapImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickMapImage( MagickWand *wand, const MagickWand *map_wand,
+ const unsigned int dither );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>map:</dt>
+<dd>The map wand.</dd>
+<dt>dither:</dt>
+<dd>Set this integer value to something other than zero to dither
+the mapped image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmattefloodfillimage">
+<h1><a class="toc-backref" href="#id581">MagickMatteFloodfillImage</a></h1>
+<div class="section" id="id235">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickMatteFloodfillImage( MagickWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> opacity,
+ const double fuzz, const PixelWand *bordercolor,
+ const long x, const long y );
+</pre>
+</div>
+<div class="section" id="id236">
+<h2>Description</h2>
+<p>MagickMatteFloodfillImage() changes the transparency value of any pixel that
+matches target and is an immediate neighbor. If the method
+FillToBorderMethod is specified, the transparency value is changed for any
+neighbor pixel that does not match the bordercolor member of image.</p>
+<p>The format of the MagickMatteFloodfillImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickMatteFloodfillImage( MagickWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> opacity,
+ const double fuzz, const PixelWand *bordercolor,
+ const long x, const long y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>opacity:</dt>
+<dd>The opacity.</dd>
+<dt>fuzz:</dt>
+<dd>By default target must match a particular pixel color
+exactly. However, in many cases two colors may differ by a small amount.
+The fuzz member of image defines how much tolerance is acceptable to
+consider two colors as the same. For example, set fuzz to 10 and the
+color red at intensities of 100 and 102 respectively are now interpreted
+as the same color for the purposes of the floodfill.</dd>
+<dt>bordercolor:</dt>
+<dd>The border color pixel wand.</dd>
+<dt>x,y:</dt>
+<dd>The starting location of the operation.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmedianfilterimage">
+<h1><a class="toc-backref" href="#id582">MagickMedianFilterImage</a></h1>
+<div class="section" id="id237">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickMedianFilterImage( MagickWand *wand, const double radius );
+</pre>
+</div>
+<div class="section" id="id238">
+<h2>Description</h2>
+<p>MagickMedianFilterImage() applies a digital filter that improves the quality
+of a noisy image. Each pixel is replaced by the median in a set of
+neighboring pixels as defined by radius.</p>
+<p>The format of the MagickMedianFilterImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickMedianFilterImage( MagickWand *wand, const double radius );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the pixel neighborhood.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickminifyimage">
+<h1><a class="toc-backref" href="#id583">MagickMinifyImage</a></h1>
+<div class="section" id="id239">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickMinifyImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id240">
+<h2>Description</h2>
+<p>MagickMinifyImage() is a convenience method that scales an image
+proportionally to one-half its original size</p>
+<p>The format of the MagickMinifyImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickMinifyImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmodulateimage">
+<h1><a class="toc-backref" href="#id584">MagickModulateImage</a></h1>
+<div class="section" id="id241">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickModulateImage( MagickWand *wand, const double brightness,
+ const double saturation, const double hue );
+</pre>
+</div>
+<div class="section" id="id242">
+<h2>Description</h2>
+<p>MagickModulateImage() lets you control the brightness, saturation, and hue
+of an image.</p>
+<p>The format of the MagickModulateImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickModulateImage( MagickWand *wand, const double brightness,
+ const double saturation, const double hue );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>brightness:</dt>
+<dd>The percent change in brighness (-100 thru +100).</dd>
+<dt>saturation:</dt>
+<dd>The percent change in saturation (-100 thru +100)</dd>
+<dt>hue:</dt>
+<dd>The percent change in hue (-100 thru +100)</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmontageimage">
+<h1><a class="toc-backref" href="#id585">MagickMontageImage</a></h1>
+<div class="section" id="id243">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand MagickMontageImage( MagickWand *wand, const DrawingWand drawing_wand,
+ const char *tile_geometry, const char *thumbnail_geometry,
+ const MontageMode mode, const char *frame );
+</pre>
+</div>
+<div class="section" id="id244">
+<h2>Description</h2>
+<p>Use MagickMontageImage() to create a composite image by combining several
+separate images. The images are tiled on the composite image with the name
+of the image optionally appearing just below the individual tile.</p>
+<p>The format of the MagickMontageImage method is:</p>
+<pre class="literal-block">
+MagickWand MagickMontageImage( MagickWand *wand, const DrawingWand drawing_wand,
+ const char *tile_geometry, const char *thumbnail_geometry,
+ const MontageMode mode, const char *frame );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>drawing_wand:</dt>
+<dd>The drawing wand. The font name, size, and color are
+obtained from this wand.</dd>
+<dt>tile_geometry:</dt>
+<dd>the number of tiles per row and page (e.g. 6x4+0+0).</dd>
+<dt>thumbnail_geometry:</dt>
+<dd>Preferred image size and border size of each
+thumbnail (e.g. 120x120+4+3&gt;).</dd>
+<dt>mode:</dt>
+<dd>Thumbnail framing mode: Frame, Unframe, or Concatenate.</dd>
+<dt>frame:</dt>
+<dd>Surround the image with an ornamental border (e.g. 15x15+3+3).
+The frame color is that of the thumbnail's matte color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmorphimages">
+<h1><a class="toc-backref" href="#id586">MagickMorphImages</a></h1>
+<div class="section" id="id245">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickMorphImages( MagickWand *wand, const unsigned long number_frames );
+</pre>
+</div>
+<div class="section" id="id246">
+<h2>Description</h2>
+<p>MagickMorphImages() method morphs a set of images. Both the image pixels
+and size are linearly interpolated to give the appearance of a
+meta-morphosis from one image to the next.</p>
+<p>The format of the MagickMorphImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickMorphImages( MagickWand *wand, const unsigned long number_frames );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>number_frames:</dt>
+<dd>The number of in-between images to generate.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmosaicimages">
+<h1><a class="toc-backref" href="#id587">MagickMosaicImages</a></h1>
+<div class="section" id="id247">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickMosaicImages( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id248">
+<h2>Description</h2>
+<p>MagickMosaicImages() inlays an image sequence to form a single coherent
+picture. It returns a wand with each image in the sequence composited at
+the location defined by the page offset of the image.</p>
+<p>The format of the MagickMosaicImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickMosaicImages( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickmotionblurimage">
+<h1><a class="toc-backref" href="#id588">MagickMotionBlurImage</a></h1>
+<div class="section" id="id249">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickMotionBlurImage( MagickWand *wand, const double radius, const double sigma,
+ const double angle );
+</pre>
+</div>
+<div class="section" id="id250">
+<h2>Description</h2>
+<p>MagickMotionBlurImage() simulates motion blur. We convolve the image with a
+Gaussian operator of the given radius and standard deviation (sigma).
+For reasonable results, radius should be larger than sigma. Use a
+radius of 0 and MotionBlurImage() selects a suitable radius for you.
+Angle gives the angle of the blurring motion.</p>
+<p>The format of the MagickMotionBlurImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickMotionBlurImage( MagickWand *wand, const double radius, const double sigma,
+ const double angle );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting
+the center pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>angle:</dt>
+<dd>Apply the effect along this angle.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicknegateimage">
+<h1><a class="toc-backref" href="#id589">MagickNegateImage</a></h1>
+<div class="section" id="id251">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickNegateImage( MagickWand *wand, const unsigned int gray );
+</pre>
+</div>
+<div class="section" id="id252">
+<h2>Description</h2>
+<p>MagickNegateImage() negates the colors in the reference image. The
+Grayscale option means that only grayscale values within the image are
+negated.</p>
+<p>You can also reduce the influence of a particular channel with a gamma
+value of 0.</p>
+<p>The format of the MagickNegateImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickNegateImage( MagickWand *wand, const unsigned int gray );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>gray:</dt>
+<dd>If True, only negate grayscale pixels within the image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicknegateimagechannel">
+<h1><a class="toc-backref" href="#id590">MagickNegateImageChannel</a></h1>
+<div class="section" id="id253">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickNegateImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const unsigned int gray );
+</pre>
+</div>
+<div class="section" id="id254">
+<h2>Description</h2>
+<p>MagickNegateImageChannel() negates the colors in the specified channel of the
+reference image. The Grayscale option means that only grayscale values
+within the image are negated. Note that the Grayscale option has no
+effect for GraphicsMagick.</p>
+<p>You can also reduce the influence of a particular channel with a gamma
+value of 0.</p>
+<p>The format of the MagickNegateImageChannel method is:</p>
+<pre class="literal-block">
+unsigned int MagickNegateImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const unsigned int gray );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to extract: RedChannel, GreenChannel,
+BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+BlackChannel.</dd>
+<dt>gray:</dt>
+<dd>If True, only negate grayscale pixels within the image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicknextimage">
+<h1><a class="toc-backref" href="#id591">MagickNextImage</a></h1>
+<div class="section" id="id255">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickNextImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id256">
+<h2>Description</h2>
+<p>MagickNextImage() associates the next image in the image list with a magick
+wand. True is returned if the Wand iterated to a next image, or False is
+returned if the wand did not iterate to a next image.</p>
+<p>The format of the MagickNextImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickNextImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicknormalizeimage">
+<h1><a class="toc-backref" href="#id592">MagickNormalizeImage</a></h1>
+<div class="section" id="id257">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickNormalizeImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id258">
+<h2>Description</h2>
+<p>MagickNormalizeImage() enhances the contrast of a color image by adjusting
+the pixels color to span the entire range of colors available</p>
+<p>You can also reduce the influence of a particular channel with a gamma
+value of 0.</p>
+<p>The format of the MagickNormalizeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickNormalizeImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickoilpaintimage">
+<h1><a class="toc-backref" href="#id593">MagickOilPaintImage</a></h1>
+<div class="section" id="id259">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickOilPaintImage( MagickWand *wand, const double radius );
+</pre>
+</div>
+<div class="section" id="id260">
+<h2>Description</h2>
+<p>MagickOilPaintImage() applies a special effect filter that simulates an oil
+painting. Each pixel is replaced by the most frequent color occurring
+in a circular region defined by radius.</p>
+<p>The format of the MagickOilPaintImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickOilPaintImage( MagickWand *wand, const double radius );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the circular neighborhood.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickopaqueimage">
+<h1><a class="toc-backref" href="#id594">MagickOpaqueImage</a></h1>
+<div class="section" id="id261">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickOpaqueImage( MagickWand *wand, const PixelWand *target,
+ const PixelWand *fill, const double fuzz );
+</pre>
+</div>
+<div class="section" id="id262">
+<h2>Description</h2>
+<p>MagickOpaqueImage() changes any pixel that matches color with the color
+defined by fill.</p>
+<p>The format of the MagickOpaqueImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickOpaqueImage( MagickWand *wand, const PixelWand *target,
+ const PixelWand *fill, const double fuzz );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>target:</dt>
+<dd>Change this target color to the fill color within the image.</dd>
+<dt>fill:</dt>
+<dd>The fill pixel wand.</dd>
+<dt>fuzz:</dt>
+<dd>By default target must match a particular pixel color
+exactly. However, in many cases two colors may differ by a small amount.
+The fuzz member of image defines how much tolerance is acceptable to
+consider two colors as the same. For example, set fuzz to 10 and the
+color red at intensities of 100 and 102 respectively are now interpreted
+as the same color for the purposes of the floodfill.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickpingimage">
+<h1><a class="toc-backref" href="#id595">MagickPingImage</a></h1>
+<div class="section" id="id263">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickPingImage( MagickWand *wand, const char *filename );
+</pre>
+</div>
+<div class="section" id="id264">
+<h2>Description</h2>
+<p>MagickPingImage() is like MagickReadImage() except the only valid
+information returned is the image width, height, size, and format. It
+is designed to efficiently obtain this information from a file without
+reading the entire image sequence into memory.</p>
+<p>The format of the MagickPingImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickPingImage( MagickWand *wand, const char *filename );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>filename:</dt>
+<dd>The image filename.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickpreviewimages">
+<h1><a class="toc-backref" href="#id596">MagickPreviewImages</a></h1>
+<div class="section" id="id265">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickPreviewImages( MagickWand *wand, const PreviewType preview );
+</pre>
+</div>
+<div class="section" id="id266">
+<h2>Description</h2>
+<p>MagickPreviewImages() tiles 9 thumbnails of the specified image with an
+image processing operation applied at varying strengths. This is helpful
+to quickly pin-point an appropriate parameter for an image processing
+operation.</p>
+<p>The format of the MagickPreviewImages method is:</p>
+<pre class="literal-block">
+MagickWand *MagickPreviewImages( MagickWand *wand, const PreviewType preview );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>preview:</dt>
+<dd>The preview type.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickpreviousimage">
+<h1><a class="toc-backref" href="#id597">MagickPreviousImage</a></h1>
+<div class="section" id="id267">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickPreviousImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id268">
+<h2>Description</h2>
+<p>MagickPreviousImage() selects the previous image associated with a magick
+wand.</p>
+<p>The format of the MagickPreviousImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickPreviousImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickprofileimage">
+<h1><a class="toc-backref" href="#id598">MagickProfileImage</a></h1>
+<div class="section" id="id269">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickProfileImage( MagickWand *wand, const char *name,
+ const unsigned char *profile, const size_t length );
+</pre>
+</div>
+<div class="section" id="id270">
+<h2>Description</h2>
+<p>Use MagickProfileImage() to add or remove a ICC, IPTC, or generic profile
+from an image. If the profile is NULL, it is removed from the image
+otherwise added. Use a name of '*' and a profile of NULL to remove all
+profiles from the image.</p>
+<p>The format of the MagickProfileImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickProfileImage( MagickWand *wand, const char *name,
+ const unsigned char *profile, const size_t length );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>name:</dt>
+<dd>Name of profile to add or remove: ICC, IPTC, or generic profile.</dd>
+<dt>profile:</dt>
+<dd>The profile.</dd>
+<dt>length:</dt>
+<dd>The length of the profile.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickquantizeimage">
+<h1><a class="toc-backref" href="#id599">MagickQuantizeImage</a></h1>
+<div class="section" id="id271">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickQuantizeImage( MagickWand *wand, const unsigned long number_colors,
+ const <a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> colorspace,
+ const unsigned long treedepth, const unsigned int dither,
+ const unsigned int measure_error );
+</pre>
+</div>
+<div class="section" id="id272">
+<h2>Description</h2>
+<p>MagickQuantizeImage() analyzes the colors within a reference image and
+chooses a fixed number of colors to represent the image. The goal of the
+algorithm is to minimize the color difference between the input and output
+image while minimizing the processing time.</p>
+<p>The format of the MagickQuantizeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickQuantizeImage( MagickWand *wand, const unsigned long number_colors,
+ const <a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> colorspace,
+ const unsigned long treedepth, const unsigned int dither,
+ const unsigned int measure_error );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>number_colors:</dt>
+<dd>The number of colors.</dd>
+<dt>colorspace:</dt>
+<dd>Perform color reduction in this colorspace, typically
+RGBColorspace.</dd>
+<dt>treedepth:</dt>
+<dd>Normally, this integer value is zero or one. A zero or
+one tells Quantize to choose a optimal tree depth of Log4(number_colors).% A tree of this depth generally allows the best representation of the
+reference image with the least amount of memory and the fastest
+computational speed. In some cases, such as an image with low color
+dispersion (a few number of colors), a value other than
+Log4(number_colors) is required. To expand the color tree completely,
+use a value of 8.</dd>
+<dt>dither:</dt>
+<dd>A value other than zero distributes the difference between an
+original image and the corresponding color reduced algorithm to
+neighboring pixels along a Hilbert curve.</dd>
+<dt>measure_error:</dt>
+<dd>A value other than zero measures the difference between
+the original and quantized images. This difference is the total
+quantization error. The error is computed by summing over all pixels
+in an image the distance squared in RGB space between each reference
+pixel value and its quantized value.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickquantizeimages">
+<h1><a class="toc-backref" href="#id600">MagickQuantizeImages</a></h1>
+<div class="section" id="id273">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickQuantizeImages( MagickWand *wand, const unsigned long number_colors,
+ const <a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> colorspace,
+ const unsigned long treedepth, const unsigned int dither,
+ const unsigned int measure_error );
+</pre>
+</div>
+<div class="section" id="id274">
+<h2>Description</h2>
+<p>MagickQuantizeImage() analyzes the colors within a sequence of images and
+chooses a fixed number of colors to represent the image. The goal of the
+algorithm is to minimize the color difference between the input and output
+image while minimizing the processing time.</p>
+<p>The format of the MagickQuantizeImages method is:</p>
+<pre class="literal-block">
+unsigned int MagickQuantizeImages( MagickWand *wand, const unsigned long number_colors,
+ const <a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> colorspace,
+ const unsigned long treedepth, const unsigned int dither,
+ const unsigned int measure_error );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>number_colors:</dt>
+<dd>The number of colors.</dd>
+<dt>colorspace:</dt>
+<dd>Perform color reduction in this colorspace, typically
+RGBColorspace.</dd>
+<dt>treedepth:</dt>
+<dd>Normally, this integer value is zero or one. A zero or
+one tells Quantize to choose a optimal tree depth of Log4(number_colors).% A tree of this depth generally allows the best representation of the
+reference image with the least amount of memory and the fastest
+computational speed. In some cases, such as an image with low color
+dispersion (a few number of colors), a value other than
+Log4(number_colors) is required. To expand the color tree completely,
+use a value of 8.</dd>
+<dt>dither:</dt>
+<dd>A value other than zero distributes the difference between an
+original image and the corresponding color reduced algorithm to
+neighboring pixels along a Hilbert curve.</dd>
+<dt>measure_error:</dt>
+<dd>A value other than zero measures the difference between
+the original and quantized images. This difference is the total
+quantization error. The error is computed by summing over all pixels
+in an image the distance squared in RGB space between each reference
+pixel value and its quantized value.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickqueryfontmetrics">
+<h1><a class="toc-backref" href="#id601">MagickQueryFontMetrics</a></h1>
+<div class="section" id="id275">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double *MagickQueryFontMetrics( MagickWand *wand, const DrawingWand *drawing_wand,
+ const char *text );
+</pre>
+</div>
+<div class="section" id="id276">
+<h2>Description</h2>
+<p>MagickQueryFontMetrics() returns a 7 element array representing the
+following font metrics:</p>
+</div>
+<div class="section" id="element-description">
+<h2>Element Description</h2>
+<p>0 character width
+1 character height
+2 ascender
+3 descender
+4 text width
+5 text height
+6 maximum horizontal advance</p>
+<p>The format of the MagickQueryFontMetrics method is:</p>
+<pre class="literal-block">
+double *MagickQueryFontMetrics( MagickWand *wand, const DrawingWand *drawing_wand,
+ const char *text );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The Magick wand.</dd>
+<dt>drawing_wand:</dt>
+<dd>The drawing wand.</dd>
+<dt>text:</dt>
+<dd>The text.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickqueryfonts">
+<h1><a class="toc-backref" href="#id602">MagickQueryFonts</a></h1>
+<div class="section" id="id277">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char ** MagickQueryFonts( const char *pattern, unsigned long *number_fonts );
+</pre>
+</div>
+<div class="section" id="id278">
+<h2>Description</h2>
+<p>MagickQueryFonts() returns any font that match the specified pattern.</p>
+<p>The format of the MagickQueryFonts function is:</p>
+<pre class="literal-block">
+char ** MagickQueryFonts( const char *pattern, unsigned long *number_fonts );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>pattern:</dt>
+<dd>Specifies a pointer to a text string containing a pattern.</dd>
+<dt>number_fonts:</dt>
+<dd>This integer returns the number of fonts in the list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickqueryformats">
+<h1><a class="toc-backref" href="#id603">MagickQueryFormats</a></h1>
+<div class="section" id="id279">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char ** MagickQueryFormats( const char *pattern, unsigned long *number_formats );
+</pre>
+</div>
+<div class="section" id="id280">
+<h2>Description</h2>
+<p>MagickQueryFormats() returns any image formats that match the specified
+pattern.</p>
+<p>The format of the MagickQueryFormats function is:</p>
+<pre class="literal-block">
+char ** MagickQueryFormats( const char *pattern, unsigned long *number_formats );
+</pre>
+<dl class="docutils">
+<dt>pattern:</dt>
+<dd>Specifies a pointer to a text string containing a pattern.</dd>
+<dt>number_formats:</dt>
+<dd>This integer returns the number of image formats in the
+list.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickradialblurimage">
+<h1><a class="toc-backref" href="#id604">MagickRadialBlurImage</a></h1>
+<div class="section" id="id281">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickRadialBlurImage( MagickWand *wand, const double angle );
+</pre>
+</div>
+<div class="section" id="id282">
+<h2>Description</h2>
+<p>MagickRadialBlurImage() radial blurs an image.</p>
+<p>The format of the MagickRadialBlurImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickRadialBlurImage( MagickWand *wand, const double angle );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>angle:</dt>
+<dd>The angle of the blur in degrees.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickraiseimage">
+<h1><a class="toc-backref" href="#id605">MagickRaiseImage</a></h1>
+<div class="section" id="id283">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickRaiseImage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long x, const long y,
+ const unsigned int raise_flag );
+</pre>
+</div>
+<div class="section" id="id284">
+<h2>Description</h2>
+<p>MagickRaiseImage() creates a simulated three-dimensional button-like effect
+by lightening and darkening the edges of the image. Members width and
+height of raise_info define the width of the vertical and horizontal
+edge of the effect.</p>
+<p>The format of the MagickRaiseImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickRaiseImage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long x, const long y,
+ const unsigned int raise_flag );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>width,height,x,y:</dt>
+<dd>Define the dimensions of the area to raise.</dd>
+<dt>raise_flag:</dt>
+<dd>A value other than zero creates a 3-D raise effect,
+otherwise it has a lowered effect.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickreadimage">
+<h1><a class="toc-backref" href="#id606">MagickReadImage</a></h1>
+<div class="section" id="id285">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickReadImage( MagickWand *wand, const char *filename );
+</pre>
+</div>
+<div class="section" id="id286">
+<h2>Description</h2>
+<p>MagickReadImage() reads an image or image sequence.</p>
+<p>The format of the MagickReadImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickReadImage( MagickWand *wand, const char *filename );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>filename:</dt>
+<dd>The image filename.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickreadimageblob">
+<h1><a class="toc-backref" href="#id607">MagickReadImageBlob</a></h1>
+<div class="section" id="id287">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickReadImageBlob( MagickWand *wand, const unsigned char *blob,
+ const size_t length );
+</pre>
+</div>
+<div class="section" id="id288">
+<h2>Description</h2>
+<p>MagickReadImageBlob() reads an image or image sequence from a blob.</p>
+<p>The format of the MagickReadImageBlob method is:</p>
+<pre class="literal-block">
+unsigned int MagickReadImageBlob( MagickWand *wand, const unsigned char *blob,
+ const size_t length );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>blob:</dt>
+<dd>The blob.</dd>
+<dt>length:</dt>
+<dd>The blob length.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickreadimagefile">
+<h1><a class="toc-backref" href="#id608">MagickReadImageFile</a></h1>
+<div class="section" id="id289">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickReadImageFile( MagickWand *wand, FILE *file );
+</pre>
+</div>
+<div class="section" id="id290">
+<h2>Description</h2>
+<p>MagickReadImageFile() reads an image or image sequence from an open file
+descriptor.</p>
+<p>The format of the MagickReadImageFile method is:</p>
+<pre class="literal-block">
+unsigned int MagickReadImageFile( MagickWand *wand, FILE *file );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>file:</dt>
+<dd>The file descriptor.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickreducenoiseimage">
+<h1><a class="toc-backref" href="#id609">MagickReduceNoiseImage</a></h1>
+<div class="section" id="id291">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickReduceNoiseImage( MagickWand *wand, const double radius );
+</pre>
+</div>
+<div class="section" id="id292">
+<h2>Description</h2>
+<p>MagickReduceNoiseImage() smooths the contours of an image while still
+preserving edge information. The algorithm works by replacing each pixel
+with its neighbor closest in value. A neighbor is defined by radius. Use
+a radius of 0 and ReduceNoise() selects a suitable radius for you.</p>
+<p>The format of the MagickReduceNoiseImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickReduceNoiseImage( MagickWand *wand, const double radius );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the pixel neighborhood.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickrelinquishmemory">
+<h1><a class="toc-backref" href="#id610">MagickRelinquishMemory</a></h1>
+<div class="section" id="id293">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickRelinquishMemory( void *resource );
+</pre>
+</div>
+<div class="section" id="id294">
+<h2>Description</h2>
+<p>MagickRelinquishMemory() relinquishes memory resources returned by such
+methods as MagickDescribeImage(), MagickGetException(), etc.</p>
+<p>The format of the MagickRelinquishMemory method is:</p>
+<pre class="literal-block">
+unsigned int MagickRelinquishMemory( void *resource );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>resource:</dt>
+<dd>Relinquish the memory associated with this resource.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickremoveimage">
+<h1><a class="toc-backref" href="#id611">MagickRemoveImage</a></h1>
+<div class="section" id="id295">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickRemoveImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id296">
+<h2>Description</h2>
+<p>MagickRemoveImage() removes an image from the image list.</p>
+<p>The format of the MagickRemoveImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickRemoveImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickremoveimageoption">
+<h1><a class="toc-backref" href="#id612">MagickRemoveImageOption</a></h1>
+<div class="section" id="id297">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickRemoveImageOption( MagickWand *wand, const char *format,
+ const char *key );
+</pre>
+</div>
+<div class="section" id="id298">
+<h2>Description</h2>
+<p>MagickRemoveImageOption() removes an image format-specific option from the
+the image (.e.g MagickRemoveImageOption(wand,&quot;jpeg&quot;,&quot;preserve-settings&quot;).</p>
+<p>The format of the MagickRemoveImageOption method is:</p>
+<pre class="literal-block">
+unsigned int MagickRemoveImageOption( MagickWand *wand, const char *format,
+ const char *key );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>format:</dt>
+<dd>The image format.</dd>
+<dt>key:</dt>
+<dd>The key.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickremoveimageprofile">
+<h1><a class="toc-backref" href="#id613">MagickRemoveImageProfile</a></h1>
+<div class="section" id="id299">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned char *MagickRemoveImageProfile( MagickWand *wand, const char *name,
+ unsigned long *length );
+</pre>
+</div>
+<div class="section" id="id300">
+<h2>Description</h2>
+<p>MagickRemoveImageProfile() removes the named image profile and returns it.</p>
+<p>The format of the MagickRemoveImageProfile method is:</p>
+<pre class="literal-block">
+unsigned char *MagickRemoveImageProfile( MagickWand *wand, const char *name,
+ unsigned long *length );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>name:</dt>
+<dd>Name of profile to return: ICC, IPTC, or generic profile.</dd>
+<dt>length:</dt>
+<dd>The length of the profile.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickresetiterator">
+<h1><a class="toc-backref" href="#id614">MagickResetIterator</a></h1>
+<div class="section" id="id301">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+void MagickResetIterator( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id302">
+<h2>Description</h2>
+<p>MagickReset() resets the wand iterator. Use it in conjunction
+with MagickNextImage() to iterate over all the images in a wand
+container.</p>
+<p>The format of the MagickReset method is:</p>
+<pre class="literal-block">
+void MagickResetIterator( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickresampleimage">
+<h1><a class="toc-backref" href="#id615">MagickResampleImage</a></h1>
+<div class="section" id="id303">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickResampleImage( MagickWand *wand, const double x_resolution,
+ const double y_resolution, const <a class="reference external" href="../api/types.html#filtertype">FilterTypes</a> filter,
+ const double blur );
+</pre>
+</div>
+<div class="section" id="id304">
+<h2>Description</h2>
+<p>MagickResampleImage() resample image to desired resolution.</p>
+<p>Bessel Blackman Box
+Catrom Cubic Gaussian
+Hanning Hermite Lanczos
+Mitchell Point Quandratic
+Sinc Triangle</p>
+<p>Most of the filters are FIR (finite impulse response), however, Bessel,
+Gaussian, and Sinc are IIR (infinite impulse response). Bessel and Sinc
+are windowed (brought down to zero) with the Blackman filter.</p>
+<p>The format of the MagickResampleImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickResampleImage( MagickWand *wand, const double x_resolution,
+ const double y_resolution, const <a class="reference external" href="../api/types.html#filtertype">FilterTypes</a> filter,
+ const double blur );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x_resolution:</dt>
+<dd>The new image x resolution.</dd>
+<dt>y_resolution:</dt>
+<dd>The new image y resolution.</dd>
+<dt>filter:</dt>
+<dd>Image filter to use.</dd>
+<dt>blur:</dt>
+<dd>The blur factor where &gt; 1 is blurry, &lt; 1 is sharp.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickresizeimage">
+<h1><a class="toc-backref" href="#id616">MagickResizeImage</a></h1>
+<div class="section" id="id305">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickResizeImage( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows, const <a class="reference external" href="../api/types.html#filtertype">FilterTypes</a> filter,
+ const double blur );
+</pre>
+</div>
+<div class="section" id="id306">
+<h2>Description</h2>
+<p>MagickResizeImage() scales an image to the desired dimensions with one of
+these filters:</p>
+<p>Bessel Blackman Box
+Catrom Cubic Gaussian
+Hanning Hermite Lanczos
+Mitchell Point Quandratic
+Sinc Triangle</p>
+<p>Most of the filters are FIR (finite impulse response), however, Bessel,
+Gaussian, and Sinc are IIR (infinite impulse response). Bessel and Sinc
+are windowed (brought down to zero) with the Blackman filter.</p>
+<p>The format of the MagickResizeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickResizeImage( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows, const <a class="reference external" href="../api/types.html#filtertype">FilterTypes</a> filter,
+ const double blur );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the scaled image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the scaled image.</dd>
+<dt>filter:</dt>
+<dd>Image filter to use.</dd>
+<dt>blur:</dt>
+<dd>The blur factor where &gt; 1 is blurry, &lt; 1 is sharp.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickrollimage">
+<h1><a class="toc-backref" href="#id617">MagickRollImage</a></h1>
+<div class="section" id="id307">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickRollImage( MagickWand *wand, const long x_offset,
+ const unsigned long y_offset );
+</pre>
+</div>
+<div class="section" id="id308">
+<h2>Description</h2>
+<p>MagickRollImage() offsets an image as defined by x_offset and y_offset.</p>
+<p>The format of the MagickRollImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickRollImage( MagickWand *wand, const long x_offset,
+ const unsigned long y_offset );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x_offset:</dt>
+<dd>The x offset.</dd>
+<dt>y_offset:</dt>
+<dd>The y offset.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickrotateimage">
+<h1><a class="toc-backref" href="#id618">MagickRotateImage</a></h1>
+<div class="section" id="id309">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickRotateImage( MagickWand *wand, const PixelWand *background,
+ const double degrees );
+</pre>
+</div>
+<div class="section" id="id310">
+<h2>Description</h2>
+<p>MagickRotateImage() rotates an image the specified number of degrees. Empty
+triangles left over from rotating the image are filled with the
+background color.</p>
+<p>The format of the MagickRotateImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickRotateImage( MagickWand *wand, const PixelWand *background,
+ const double degrees );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>background:</dt>
+<dd>The background pixel wand.</dd>
+<dt>degrees:</dt>
+<dd>The number of degrees to rotate the image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksampleimage">
+<h1><a class="toc-backref" href="#id619">MagickSampleImage</a></h1>
+<div class="section" id="id311">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSampleImage( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id312">
+<h2>Description</h2>
+<p>MagickSampleImage() scales an image to the desired dimensions with pixel
+sampling. Unlike other scaling methods, this method does not introduce
+any additional color into the scaled image.</p>
+<p>The format of the MagickSampleImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickSampleImage( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the scaled image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the scaled image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickscaleimage">
+<h1><a class="toc-backref" href="#id620">MagickScaleImage</a></h1>
+<div class="section" id="id313">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickScaleImage( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id314">
+<h2>Description</h2>
+<p>MagickScaleImage() scales the size of an image to the given dimensions.</p>
+<p>The format of the MagickScaleImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickScaleImage( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the scaled image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the scaled image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickseparateimagechannel">
+<h1><a class="toc-backref" href="#id621">MagickSeparateImageChannel</a></h1>
+<div class="section" id="id315">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSeparateImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel );
+</pre>
+</div>
+<div class="section" id="id316">
+<h2>Description</h2>
+<p>MagickChannelImage() separates a channel from the image and returns a
+grayscale image. A channel is a particular color component of each pixel
+in the image.</p>
+<p>The format of the MagickChannelImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickSeparateImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to extract: RedChannel, GreenChannel,
+BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+BlackChannel.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetcompressionquality">
+<h1><a class="toc-backref" href="#id622">MagickSetCompressionQuality</a></h1>
+<div class="section" id="id317">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetCompressionQuality( MagickWand *wand, const unsigned long quality );
+</pre>
+</div>
+<div class="section" id="id318">
+<h2>Description</h2>
+<p>MagickSetCompressionQuality() sets the image quality factor, which
+determines compression options when saving the file.</p>
+<p>For the JPEG and MPEG image formats, quality is 0 (lowest image
+quality and highest compression) to 100 (best quality but least
+effective compression). The default quality is 75. Use the
+-sampling-factor option to specify the factors for chroma
+downsampling. To use the same quality value as that found by the
+JPEG decoder, use the -define jpeg:preserve-settings flag.</p>
+<p>For the MIFF image format, and the TIFF format while using ZIP
+compression, quality/10 is the zlib compres- sion level, which is 0
+(worst but fastest compression) to 9 (best but slowest). It has no
+effect on the image appearance, since the compression is always
+lossless.</p>
+<p>For the JPEG-2000 image format, quality is mapped using a non-linear
+equation to the compression ratio required by the Jasper library.
+This non-linear equation is intended to loosely approximate the
+quality provided by the JPEG v1 format. The default quality value 75
+results in a request for 16:1 compression. The quality value 100
+results in a request for non-lossy compres- sion.</p>
+<p>For the MNG and PNG image formats, the quality value sets the zlib
+compression level (quality / 10) and filter-type (quality % 10).
+Compression levels range from 0 (fastest compression) to 100 (best
+but slowest). For compression level 0, the Huffman-only strategy is
+used, which is fastest but not necessarily the worst compression. If
+filter-type is 4 or less, the specified filter-type is used for all
+scanlines:</p>
+<ol class="arabic simple" start="0">
+<li>none</li>
+<li>sub</li>
+<li>up</li>
+<li>average</li>
+<li>Paeth</li>
+</ol>
+<p>If filter-type is 5, adaptive filtering is used when quality is
+greater than 50 and the image does not have a color map, otherwise no
+filtering is used.</p>
+<p>If filter-type is 6, adaptive filtering with minimum-
+sum-of-absolute-values is used.</p>
+<p>Only if the output is MNG, if filter-type is 7, the LOCO color
+transformation and adaptive filtering with
+minimum-sum-of-absolute-values are used.</p>
+<p>The default is quality is 75, which means nearly the best compression
+with adaptive filtering. The quality setting has no effect on the
+appearance of PNG and MNG images, since the compression is always
+lossless.</p>
+<p>For further information, see the PNG specification.</p>
+<p>When writing a JNG image with transparency, two quality values are
+required, one for the main image and one for the grayscale image that
+conveys the opacity channel. These are written as a single integer
+equal to the main image quality plus 1000 times the opacity quality.
+For example, if you want to use quality 75 for the main image and
+quality 90 to compress the opacity data, use -quality 90075.</p>
+<p>For the PNM family of formats (PNM, PGM, and PPM) specify a quality
+factor of zero in order to obtain the ASCII variant of the
+format. Note that -compress none used to be used to trigger ASCII
+output but provided the opposite result of what was expected as
+compared with other formats.</p>
+<p>The format of the MagickSetCompressionQuality method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetCompressionQuality( MagickWand *wand, const unsigned long quality );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>delay:</dt>
+<dd>The image quality.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetdepth">
+<h1><a class="toc-backref" href="#id623">MagickSetDepth</a></h1>
+<div class="section" id="id319">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetDepth( MagickWand *wand, const size_t depth );
+</pre>
+</div>
+<div class="section" id="id320">
+<h2>Description</h2>
+<p>MagickSetDepth() sets the sample depth to be used when reading from a
+raw image or a format which requires that the depth be specified in
+advance by the user.</p>
+<p>The format of the MagickSetDepth method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetDepth( MagickWand *wand, const size_t depth );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>depth:</dt>
+<dd>The sample depth.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetfilename">
+<h1><a class="toc-backref" href="#id624">MagickSetFilename</a></h1>
+<div class="section" id="id321">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetFilename( MagickWand *wand, const char *filename );
+</pre>
+</div>
+<div class="section" id="id322">
+<h2>Description</h2>
+<p>MagickSetFilename() sets the filename before you read or write an image file.</p>
+<p>The format of the MagickSetFilename method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetFilename( MagickWand *wand, const char *filename );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>filename:</dt>
+<dd>The image filename.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetformat">
+<h1><a class="toc-backref" href="#id625">MagickSetFormat</a></h1>
+<div class="section" id="id323">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetFormat( MagickWand *wand, const char *format );
+</pre>
+</div>
+<div class="section" id="id324">
+<h2>Description</h2>
+<p>MagickSetFormat() sets the file or blob format (e.g. &quot;BMP&quot;) to be used
+when a file or blob is read. Usually this is not necessary because
+GraphicsMagick is able to auto-detect the format based on the file
+header (or the file extension), but some formats do not use a unique
+header or the selection may be ambigious. Use MagickSetImageFormat()
+to set the format to be used when a file or blob is to be written.</p>
+<p>The format of the MagickSetFormat method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetFormat( MagickWand *wand, const char *format );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>filename:</dt>
+<dd>The file or blob format.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimage">
+<h1><a class="toc-backref" href="#id626">MagickSetImage</a></h1>
+<div class="section" id="id325">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImage( MagickWand *wand, const MagickWand *set_wand );
+</pre>
+</div>
+<div class="section" id="id326">
+<h2>Description</h2>
+<p>MagickSetImage() replaces the last image returned by MagickSetImageIndex(),
+MagickNextImage(), MagickPreviousImage() with the images from the specified
+wand.</p>
+<p>The format of the MagickSetImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImage( MagickWand *wand, const MagickWand *set_wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>set_wand:</dt>
+<dd>The set_wand wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageattribute">
+<h1><a class="toc-backref" href="#id627">MagickSetImageAttribute</a></h1>
+<div class="section" id="id327">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageAttribute( MagickWand *wand, const char *name,
+ const char *value );
+</pre>
+</div>
+<div class="section" id="id328">
+<h2>Description</h2>
+<p>MagickSetImageAttribute sets an image attribute</p>
+<p>The format of the MagickSetImageAttribute method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageAttribute( MagickWand *wand, const char *name,
+ const char *value );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>name:</dt>
+<dd>The name of the attribute</dd>
+<dt>value:</dt>
+<dd>The value of the attribute</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagebackgroundcolor">
+<h1><a class="toc-backref" href="#id628">MagickSetImageBackgroundColor</a></h1>
+<div class="section" id="id329">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageBackgroundColor( MagickWand *wand, const PixelWand *background );
+</pre>
+</div>
+<div class="section" id="id330">
+<h2>Description</h2>
+<p>MagickSetImageBackgroundColor() sets the image background color.</p>
+<p>The format of the MagickSetImageBackgroundColor method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageBackgroundColor( MagickWand *wand, const PixelWand *background );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>background:</dt>
+<dd>The background pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageblueprimary">
+<h1><a class="toc-backref" href="#id629">MagickSetImageBluePrimary</a></h1>
+<div class="section" id="id331">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageBluePrimary( MagickWand *wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id332">
+<h2>Description</h2>
+<p>MagickSetImageBluePrimary() sets the image chromaticity blue primary point.</p>
+<p>The format of the MagickSetImageBluePrimary method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageBluePrimary( MagickWand *wand, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The blue primary x-point.</dd>
+<dt>y:</dt>
+<dd>The blue primary y-point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagebordercolor">
+<h1><a class="toc-backref" href="#id630">MagickSetImageBorderColor</a></h1>
+<div class="section" id="id333">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageBorderColor( MagickWand *wand, const PixelWand *border );
+</pre>
+</div>
+<div class="section" id="id334">
+<h2>Description</h2>
+<p>MagickSetImageBorderColor() sets the image border color.</p>
+<p>The format of the MagickSetImageBorderColor method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageBorderColor( MagickWand *wand, const PixelWand *border );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>border:</dt>
+<dd>The border pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagecolormapcolor">
+<h1><a class="toc-backref" href="#id631">MagickSetImageColormapColor</a></h1>
+<div class="section" id="id335">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageColormapColor( MagickWand *wand, const unsigned long index,
+ const PixelWand *color );
+</pre>
+</div>
+<div class="section" id="id336">
+<h2>Description</h2>
+<p>MagickSetImageColormapColor() sets the color of the specified colormap
+index.</p>
+<p>The format of the MagickSetImageColormapColor method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageColormapColor( MagickWand *wand, const unsigned long index,
+ const PixelWand *color );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>index:</dt>
+<dd>The offset into the image colormap.</dd>
+<dt>color:</dt>
+<dd>Return the colormap color in this wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagecolorspace">
+<h1><a class="toc-backref" href="#id632">MagickSetImageColorspace</a></h1>
+<div class="section" id="id337">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageColorspace( MagickWand *wand, const <a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> colorspace );
+</pre>
+</div>
+<div class="section" id="id338">
+<h2>Description</h2>
+<p>MagickSetImageColorspace() sets the image colorspace.</p>
+<p>The format of the MagickSetImageColorspace method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageColorspace( MagickWand *wand, const <a class="reference external" href="../api/types.html#colorspacetype">ColorspaceType</a> colorspace );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>colorspace:</dt>
+<dd>The image colorspace: UndefinedColorspace, RGBColorspace,
+GRAYColorspace, TransparentColorspace, OHTAColorspace, XYZColorspace,
+YCbCrColorspace, YCCColorspace, YIQColorspace, YPbPrColorspace,
+YPbPrColorspace, YUVColorspace, CMYKColorspace, sRGBColorspace,
+HSLColorspace, or HWBColorspace.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagecompose">
+<h1><a class="toc-backref" href="#id633">MagickSetImageCompose</a></h1>
+<div class="section" id="id339">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageCompose( MagickWand *wand, const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> compose );
+</pre>
+</div>
+<div class="section" id="id340">
+<h2>Description</h2>
+<p>MagickSetImageCompose() sets the image composite operator, useful for
+specifying how to composite the image thumbnail when using the
+MagickMontageImage() method.</p>
+<p>The format of the MagickSetImageCompose method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageCompose( MagickWand *wand, const <a class="reference external" href="../api/types.html#compositeoperator">CompositeOperator</a> compose );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>compose:</dt>
+<dd>The image composite operator.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagecompression">
+<h1><a class="toc-backref" href="#id634">MagickSetImageCompression</a></h1>
+<div class="section" id="id341">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageCompression( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#compressiontype">CompressionType</a> compression );
+</pre>
+</div>
+<div class="section" id="id342">
+<h2>Description</h2>
+<p>MagickSetImageCompression() sets the image compression.</p>
+<p>The format of the MagickSetImageCompression method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageCompression( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#compressiontype">CompressionType</a> compression );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>compression:</dt>
+<dd>The image compression type.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagedelay">
+<h1><a class="toc-backref" href="#id635">MagickSetImageDelay</a></h1>
+<div class="section" id="id343">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageDelay( MagickWand *wand, const unsigned long delay );
+</pre>
+</div>
+<div class="section" id="id344">
+<h2>Description</h2>
+<p>MagickSetImageDelay() sets the image delay.</p>
+<p>The format of the MagickSetImageDelay method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageDelay( MagickWand *wand, const unsigned long delay );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>delay:</dt>
+<dd>The image delay in 1/100th of a second.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagechanneldepth">
+<h1><a class="toc-backref" href="#id636">MagickSetImageChannelDepth</a></h1>
+<div class="section" id="id345">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageChannelDepth( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const unsigned long depth );
+</pre>
+</div>
+<div class="section" id="id346">
+<h2>Description</h2>
+<p>MagickSetImageChannelDepth() sets the depth of a particular image channel.</p>
+<p>The format of the MagickSetImageChannelDepth method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageChannelDepth( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const unsigned long depth );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>Identify which channel to extract: RedChannel, GreenChannel,
+BlueChannel, OpacityChannel, CyanChannel, MagentaChannel, YellowChannel,
+BlackChannel.</dd>
+<dt>depth:</dt>
+<dd>The image depth in bits.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagedepth">
+<h1><a class="toc-backref" href="#id637">MagickSetImageDepth</a></h1>
+<div class="section" id="id347">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageDepth( MagickWand *wand, const unsigned long depth );
+</pre>
+</div>
+<div class="section" id="id348">
+<h2>Description</h2>
+<p>MagickSetImageDepth() sets the image depth.</p>
+<p>The format of the MagickSetImageDepth method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageDepth( MagickWand *wand, const unsigned long depth );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>depth:</dt>
+<dd>The image depth in bits: 8, 16, or 32.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagedispose">
+<h1><a class="toc-backref" href="#id638">MagickSetImageDispose</a></h1>
+<div class="section" id="id349">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageDispose( MagickWand *wand, const DisposeType dispose );
+</pre>
+</div>
+<div class="section" id="id350">
+<h2>Description</h2>
+<p>MagickSetImageDispose() sets the image disposal method.</p>
+<p>The format of the MagickSetImageDispose method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageDispose( MagickWand *wand, const DisposeType dispose );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>dispose:</dt>
+<dd>The image disposeal type.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagefilename">
+<h1><a class="toc-backref" href="#id639">MagickSetImageFilename</a></h1>
+<div class="section" id="id351">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageFilename( MagickWand *wand, const char *filename );
+</pre>
+</div>
+<div class="section" id="id352">
+<h2>Description</h2>
+<p>MagickSetImageFilename() sets the filename of a particular image in a
+sequence.</p>
+<p>The format of the MagickSetImageFilename method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageFilename( MagickWand *wand, const char *filename );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>filename:</dt>
+<dd>The image filename.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageformat">
+<h1><a class="toc-backref" href="#id640">MagickSetImageFormat</a></h1>
+<div class="section" id="id353">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageFormat( MagickWand *wand, const char *format );
+</pre>
+</div>
+<div class="section" id="id354">
+<h2>Description</h2>
+<p>MagickSetImageFormat() sets the format of a particular image in a
+sequence. The format is designated by a magick string (e.g. &quot;GIF&quot;).</p>
+<p>The format of the MagickSetImageFormat method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageFormat( MagickWand *wand, const char *format );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>magick:</dt>
+<dd>The image format.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagefuzz">
+<h1><a class="toc-backref" href="#id641">MagickSetImageFuzz</a></h1>
+<div class="section" id="id355">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageFuzz( MagickWand *wand, const double fuzz );
+</pre>
+</div>
+<div class="section" id="id356">
+<h2>Description</h2>
+<p>MagickSetImageFuzz() sets the color comparison fuzz factor. Colors
+closer than the fuzz factor are considered to be the same when comparing
+colors. Note that some other functions such as MagickColorFloodfillImage()
+implicitly set this value.</p>
+<p>The format of the MagickSetImageFuzz method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageFuzz( MagickWand *wand, const double fuzz );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>fuzz:</dt>
+<dd>The color comparison fuzz factor</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagegamma">
+<h1><a class="toc-backref" href="#id642">MagickSetImageGamma</a></h1>
+<div class="section" id="id357">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageGamma( MagickWand *wand, const double gamma );
+</pre>
+</div>
+<div class="section" id="id358">
+<h2>Description</h2>
+<p>MagickSetImageGamma() sets the image gamma.</p>
+<p>The format of the MagickSetImageGamma method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageGamma( MagickWand *wand, const double gamma );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>gamma:</dt>
+<dd>The image gamma.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagegravity">
+<h1><a class="toc-backref" href="#id643">MagickSetImageGravity</a></h1>
+<div class="section" id="id359">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageGravity( MagickWand *wand, const <a class="reference external" href="../api/types.html#gravitytype">GravityType</a> );
+</pre>
+</div>
+<div class="section" id="id360">
+<h2>Description</h2>
+<p>MagickSetImageGravity() sets the image gravity. This is used
+when evaluating regions defined by a geometry and the image
+dimensions. It may be used in conjunction with operations which
+use a geometry parameter to adjust the x, y parameters of the
+final operation. Gravity is used in composition to determine where
+the image should be placed within the defined geometry region.
+It may be used with montage to effect placement of the image within
+the tile.</p>
+<p>The format of the MagickSetImageGravity method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageGravity( MagickWand *wand, const <a class="reference external" href="../api/types.html#gravitytype">GravityType</a> );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>gravity:</dt>
+<dd>The image gravity. Available values are ForgetGravity,
+NorthWestGravity, NorthGravity, NorthEastGravity, WestGravity,
+CenterGravity, EastGravity, SouthWestGravity, SouthGravity,
+SouthEastGravity, and StaticGravity</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagegreenprimary">
+<h1><a class="toc-backref" href="#id644">MagickSetImageGreenPrimary</a></h1>
+<div class="section" id="id361">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageGreenPrimary( MagickWand *wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id362">
+<h2>Description</h2>
+<p>MagickSetImageGreenPrimary() sets the image chromaticity green primary
+point.</p>
+<p>The format of the MagickSetImageGreenPrimary method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageGreenPrimary( MagickWand *wand, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The green primary x-point.</dd>
+<dt>y:</dt>
+<dd>The green primary y-point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageindex">
+<h1><a class="toc-backref" href="#id645">MagickSetImageIndex</a></h1>
+<div class="section" id="id363">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageIndex( MagickWand *wand, const long index );
+</pre>
+</div>
+<div class="section" id="id364">
+<h2>Description</h2>
+<p>MagickSetImageIndex() set the current image to the position of the list
+specified with the index parameter.</p>
+<p>The format of the MagickSetImageIndex method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageIndex( MagickWand *wand, const long index );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>index:</dt>
+<dd>The scene number.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageinterlacescheme">
+<h1><a class="toc-backref" href="#id646">MagickSetImageInterlaceScheme</a></h1>
+<div class="section" id="id365">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageInterlaceScheme( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#interlacetype">InterlaceType</a> interlace_scheme );
+</pre>
+</div>
+<div class="section" id="id366">
+<h2>Description</h2>
+<p>MagickSetImageInterlaceScheme() sets the image interlace scheme. Please
+use SetInterlaceScheme() instead to change the interlace scheme used when
+writing the image.</p>
+<p>The format of the MagickSetImageInterlaceScheme method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageInterlaceScheme( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#interlacetype">InterlaceType</a> interlace_scheme );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>interlace_scheme:</dt>
+<dd>The image interlace scheme: NoInterlace, LineInterlace,
+PlaneInterlace, PartitionInterlace.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageiterations">
+<h1><a class="toc-backref" href="#id647">MagickSetImageIterations</a></h1>
+<div class="section" id="id367">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageIterations( MagickWand *wand, const unsigned long iterations );
+</pre>
+</div>
+<div class="section" id="id368">
+<h2>Description</h2>
+<p>MagickSetImageIterations() sets the image iterations.</p>
+<p>The format of the MagickSetImageIterations method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageIterations( MagickWand *wand, const unsigned long iterations );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>delay:</dt>
+<dd>The image delay in 1/100th of a second.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagemattecolor">
+<h1><a class="toc-backref" href="#id648">MagickSetImageMatteColor</a></h1>
+<div class="section" id="id369">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageMatteColor( MagickWand *wand, const PixelWand *matte );
+</pre>
+</div>
+<div class="section" id="id370">
+<h2>Description</h2>
+<p>MagickSetImageMatteColor() sets the image matte color.</p>
+<p>The format of the MagickSetImageMatteColor method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageMatteColor( MagickWand *wand, const PixelWand *matte );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>matte:</dt>
+<dd>The matte pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageoption">
+<h1><a class="toc-backref" href="#id649">MagickSetImageOption</a></h1>
+<div class="section" id="id371">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageOption( MagickWand *wand, const char *format, const char *key,
+ const char *value );
+</pre>
+</div>
+<div class="section" id="id372">
+<h2>Description</h2>
+<p>MagickSetImageOption() associates one or options with a particular image
+format (.e.g MagickSetImageOption(wand,&quot;jpeg&quot;,&quot;preserve-settings&quot;,&quot;true&quot;).</p>
+<p>The format of the MagickSetImageOption method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageOption( MagickWand *wand, const char *format, const char *key,
+ const char *value );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>format:</dt>
+<dd>The image format.</dd>
+<dt>key:</dt>
+<dd>The key.</dd>
+<dt>value:</dt>
+<dd>The value.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageorientation">
+<h1><a class="toc-backref" href="#id650">MagickSetImageOrientation</a></h1>
+<div class="section" id="id373">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickSetImageOrientation( MagickWand *wand, OrientationType new_orientation );
+</pre>
+</div>
+<div class="section" id="id374">
+<h2>Description</h2>
+<p>MagickSetImageOrientation() sets the internal image orientation type.
+The EXIF orientation tag will be updated if present.</p>
+<p>The format of the MagickSetImageOrientation method is:</p>
+<pre class="literal-block">
+MagickSetImageOrientation( MagickWand *wand, OrientationType new_orientation );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>new_orientation:</dt>
+<dd>The new orientation of the image. One of:</dd>
+</dl>
+<p>UndefinedOrientation Image orientation not specified.
+TopLeftOrientation Left to right and Top to bottom.
+TopRightOrientation Right to left and Top to bottom.
+BottomRightOrientation Right to left and Bottom to top.
+BottomLeftOrientation Left to right and Bottom to top.
+LeftTopOrientation Top to bottom and Left to right.
+RightTopOrientation Top to bottom and Right to left.
+RightBottomOrientation Bottom to top and Right to left.
+LeftBottomOrientation Bottom to top and Left to right.</p>
+<p>Returns True on success, False otherwise.</p>
+</div>
+</div>
+<div class="section" id="magicksetimagepage">
+<h1><a class="toc-backref" href="#id651">MagickSetImagePage</a></h1>
+<div class="section" id="id375">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImagePage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long x, const long y );
+</pre>
+</div>
+<div class="section" id="id376">
+<h2>Description</h2>
+<p>MagickSetImagePage() sets the image page size and offset used when
+placing (e.g. compositing) the image. Pass all zeros for the
+default placement.</p>
+<p>The format of the MagickSetImagePage method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImagePage( MagickWand *wand, const unsigned long width,
+ const unsigned long height, const long x, const long y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>width, height:</dt>
+<dd>The region size.</dd>
+<dt>x, y:</dt>
+<dd>Offset (from top left) on base canvas image on
+which to composite image data.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagepixels">
+<h1><a class="toc-backref" href="#id652">MagickSetImagePixels</a></h1>
+<div class="section" id="id377">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImagePixels( MagickWand *wand, const long x_offset, const long y_offset,
+ const unsigned long columns, const unsigned long rows,
+ const char *map, const <a class="reference external" href="../api/types.html#storagetype">StorageType</a> storage,
+ unsigned char *pixels );
+</pre>
+</div>
+<div class="section" id="id378">
+<h2>Description</h2>
+<p>MagickSetImagePixels() accepts pixel data and stores it in the image at the
+location you specify. The method returns False on success otherwise True
+if an error is encountered. The pixel data can be either char, short int,
+int, long, float, or double in the order specified by map.</p>
+<p>Suppose your want want to upload the first scanline of a 640x480 image from
+character data in red-green-blue order:</p>
+<p>MagickSetImagePixels(wand,0,0,0,640,1,&quot;RGB&quot;,CharPixel,pixels);</p>
+<p>The format of the MagickSetImagePixels method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImagePixels( MagickWand *wand, const long x_offset, const long y_offset,
+ const unsigned long columns, const unsigned long rows,
+ const char *map, const <a class="reference external" href="../api/types.html#storagetype">StorageType</a> storage,
+ unsigned char *pixels );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x_offset, y_offset:</dt>
+<dd>Offset (from top left) on base canvas image on
+which to composite image data.</dd>
+<dt>columns, rows:</dt>
+<dd>Dimensions of image.</dd>
+<dt>map:</dt>
+<dd>This string reflects the expected ordering of the pixel array.
+It can be any combination or order of R = red, G = green, B = blue,
+A = alpha (same as Transparency), O = Opacity, T = Transparency,
+C = cyan, Y = yellow, M = magenta, K = black, or I = intensity
+(for grayscale). Specify &quot;P&quot; = pad, to skip over a quantum which is
+intentionally ignored. Creation of an alpha channel for CMYK images
+is currently not supported.</dd>
+<dt>storage:</dt>
+<dd>Define the data type of the pixels. Float and double types are
+expected to be normalized [0..1] otherwise [0..MaxRGB]. Choose from
+these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
+or DoublePixel.</dd>
+<dt>pixels:</dt>
+<dd>This array of values contain the pixel components as defined by
+map and type. You must preallocate this array where the expected
+length varies depending on the values of width, height, map, and type.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageprofile">
+<h1><a class="toc-backref" href="#id653">MagickSetImageProfile</a></h1>
+<div class="section" id="id379">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageProfile( MagickWand *wand, const char *name,
+ const unsigned char *profile,
+ const unsigned long length );
+</pre>
+</div>
+<div class="section" id="id380">
+<h2>Description</h2>
+<p>MagickSetImageProfile() adds a named profile to the magick wand. If a
+profile with the same name already exists, it is replaced. This method
+differs from the MagickProfileImage() method in that it does not apply any
+CMS color profiles.</p>
+<p>The format of the MagickSetImageProfile method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageProfile( MagickWand *wand, const char *name,
+ const unsigned char *profile,
+ const unsigned long length );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>name:</dt>
+<dd>Name of profile to add or remove: ICC, IPTC, or generic profile.</dd>
+<dt>profile:</dt>
+<dd>The profile.</dd>
+<dt>length:</dt>
+<dd>The length of the profile.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageredprimary">
+<h1><a class="toc-backref" href="#id654">MagickSetImageRedPrimary</a></h1>
+<div class="section" id="id381">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageRedPrimary( MagickWand *wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id382">
+<h2>Description</h2>
+<p>MagickSetImageRedPrimary() sets the image chromaticity red primary point.</p>
+<p>The format of the MagickSetImageRedPrimary method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageRedPrimary( MagickWand *wand, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The red primary x-point.</dd>
+<dt>y:</dt>
+<dd>The red primary y-point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagerenderingintent">
+<h1><a class="toc-backref" href="#id655">MagickSetImageRenderingIntent</a></h1>
+<div class="section" id="id383">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageRenderingIntent( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#renderingintent">RenderingIntent</a> rendering_intent );
+</pre>
+</div>
+<div class="section" id="id384">
+<h2>Description</h2>
+<p>MagickSetImageRenderingIntent() sets the image rendering intent.</p>
+<p>The format of the MagickSetImageRenderingIntent method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageRenderingIntent( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#renderingintent">RenderingIntent</a> rendering_intent );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>rendering_intent:</dt>
+<dd>The image rendering intent: UndefinedIntent,
+SaturationIntent, PerceptualIntent, AbsoluteIntent, or RelativeIntent.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageresolution">
+<h1><a class="toc-backref" href="#id656">MagickSetImageResolution</a></h1>
+<div class="section" id="id385">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageResolution( MagickWand *wand, const double x_resolution,
+ const doubtl y_resolution );
+</pre>
+</div>
+<div class="section" id="id386">
+<h2>Description</h2>
+<p>MagickSetImageResolution() sets the image resolution.</p>
+<p>The format of the MagickSetImageResolution method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageResolution( MagickWand *wand, const double x_resolution,
+ const doubtl y_resolution );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x_resolution:</dt>
+<dd>The image x resolution.</dd>
+<dt>y_resolution:</dt>
+<dd>The image y resolution.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagescene">
+<h1><a class="toc-backref" href="#id657">MagickSetImageScene</a></h1>
+<div class="section" id="id387">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageScene( MagickWand *wand, const unsigned long scene );
+</pre>
+</div>
+<div class="section" id="id388">
+<h2>Description</h2>
+<p>MagickSetImageScene() sets the image scene.</p>
+<p>The format of the MagickSetImageScene method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageScene( MagickWand *wand, const unsigned long scene );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>delay:</dt>
+<dd>The image scene number.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagetype">
+<h1><a class="toc-backref" href="#id658">MagickSetImageType</a></h1>
+<div class="section" id="id389">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageType( MagickWand *wand, const <a class="reference external" href="../api/types.html#imagetype">ImageType</a> image_type );
+</pre>
+</div>
+<div class="section" id="id390">
+<h2>Description</h2>
+<p>MagickSetImageType() sets the image type.</p>
+<p>The format of the MagickSetImageType method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageType( MagickWand *wand, const <a class="reference external" href="../api/types.html#imagetype">ImageType</a> image_type );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>image_type:</dt>
+<dd>The image type: UndefinedType, BilevelType, GrayscaleType,
+GrayscaleMatteType, PaletteType, PaletteMatteType, TrueColorType,
+TrueColorMatteType, ColorSeparationType, ColorSeparationMatteType,
+or OptimizeType.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagesavedtype">
+<h1><a class="toc-backref" href="#id659">MagickSetImageSavedType</a></h1>
+<div class="section" id="id391">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageSavedType( MagickWand *wand, const <a class="reference external" href="../api/types.html#imagetype">ImageType</a> image_type );
+</pre>
+</div>
+<div class="section" id="id392">
+<h2>Description</h2>
+<p>MagickSetImageSavedType() sets the image type that will be used when the
+image is saved.</p>
+<p>The format of the MagickSetImageSavedType method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageSavedType( MagickWand *wand, const <a class="reference external" href="../api/types.html#imagetype">ImageType</a> image_type );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>image_type:</dt>
+<dd>The image type: UndefinedType, BilevelType, GrayscaleType,
+GrayscaleMatteType, PaletteType, PaletteMatteType, TrueColorType,
+TrueColorMatteType, ColorSeparationType, ColorSeparationMatteType,
+or OptimizeType.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimageunits">
+<h1><a class="toc-backref" href="#id660">MagickSetImageUnits</a></h1>
+<div class="section" id="id393">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageUnits( MagickWand *wand, const <a class="reference external" href="../api/types.html#resolutiontype">ResolutionType</a> units );
+</pre>
+</div>
+<div class="section" id="id394">
+<h2>Description</h2>
+<p>MagickSetImageUnits() sets the image units of resolution.</p>
+<p>The format of the MagickSetImageUnits method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageUnits( MagickWand *wand, const <a class="reference external" href="../api/types.html#resolutiontype">ResolutionType</a> units );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>units:</dt>
+<dd>The image units of resolution : Undefinedresolution,
+PixelsPerInchResolution, or PixelsPerCentimeterResolution.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagevirtualpixelmethod">
+<h1><a class="toc-backref" href="#id661">MagickSetImageVirtualPixelMethod</a></h1>
+<div class="section" id="id395">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageVirtualPixelMethod( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#virtualpixelmethod">VirtualPixelMethod</a> method );
+</pre>
+</div>
+<div class="section" id="id396">
+<h2>Description</h2>
+<p>MagickSetImageVirtualPixelMethod() sets the image virtual pixel method.</p>
+<p>The format of the MagickSetImageVirtualPixelMethod method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageVirtualPixelMethod( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#virtualpixelmethod">VirtualPixelMethod</a> method );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>method:</dt>
+<dd>The image virtual pixel method : UndefinedVirtualPixelMethod,
+ConstantVirtualPixelMethod, EdgeVirtualPixelMethod,
+MirrorVirtualPixelMethod, or TileVirtualPixelMethod.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetinterlacescheme">
+<h1><a class="toc-backref" href="#id662">MagickSetInterlaceScheme</a></h1>
+<div class="section" id="id397">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetInterlaceScheme( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#interlacetype">InterlaceType</a> interlace_scheme );
+</pre>
+</div>
+<div class="section" id="id398">
+<h2>Description</h2>
+<p>MagickSetInterlaceScheme() sets the interlace scheme used when writing
+the image.</p>
+<p>The format of the MagickSetInterlaceScheme method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetInterlaceScheme( MagickWand *wand,
+ const <a class="reference external" href="../api/types.html#interlacetype">InterlaceType</a> interlace_scheme );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>interlace_scheme:</dt>
+<dd>The image interlace scheme: NoInterlace, LineInterlace,
+PlaneInterlace, PartitionInterlace.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetresolution">
+<h1><a class="toc-backref" href="#id663">MagickSetResolution</a></h1>
+<div class="section" id="id399">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetResolution( MagickWand *wand, const double x_resolution,
+ const double y_resolution );
+</pre>
+</div>
+<div class="section" id="id400">
+<h2>Description</h2>
+<p>MagickSetResolution() sets the resolution (density) of the magick wand.
+Set it before you read an EPS, PDF, or Postscript file in order to
+influence the size of the returned image, or after an image has already
+been created to influence the rendered image size when used with
+typesetting software.</p>
+<p>Also see MagickSetResolutionUnits() which specifies the units to use for
+the image resolution.</p>
+<p>The format of the MagickSetResolution method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetResolution( MagickWand *wand, const double x_resolution,
+ const double y_resolution );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x_resolution:</dt>
+<dd>The horizontal resolution</dd>
+<dt>y_resolution:</dt>
+<dd>The vertical reesolution</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetresolutionunits">
+<h1><a class="toc-backref" href="#id664">MagickSetResolutionUnits</a></h1>
+<div class="section" id="id401">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetResolutionUnits( MagickWand *wand, const <a class="reference external" href="../api/types.html#resolutiontype">ResolutionType</a> units );
+</pre>
+</div>
+<div class="section" id="id402">
+<h2>Description</h2>
+<p>MagickSetResolutionUnits() sets the resolution units of the magick wand.
+It should be used in conjunction with MagickSetResolution().
+This method works both before and after an image has been read.</p>
+<p>Also see MagickSetImageUnits() which specifies the units which apply to
+the image resolution setting after an image has been read.</p>
+<p>The format of the MagickSetResolutionUnits method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetResolutionUnits( MagickWand *wand, const <a class="reference external" href="../api/types.html#resolutiontype">ResolutionType</a> units );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>units:</dt>
+<dd>The image units of resolution : Undefinedresolution,
+PixelsPerInchResolution, or PixelsPerCentimeterResolution.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetresourcelimit">
+<h1><a class="toc-backref" href="#id665">MagickSetResourceLimit</a></h1>
+<div class="section" id="id403">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetResourceLimit( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type, const unsigned long *limit );
+</pre>
+</div>
+<div class="section" id="id404">
+<h2>Description</h2>
+<p>MagickSetResourceLimit() sets the limit for a particular resource in
+megabytes.</p>
+<p>The format of the MagickSetResourceLimit method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetResourceLimit( const <a class="reference external" href="../api/types.html#resourcetype">ResourceType</a> type, const unsigned long *limit );
+</pre>
+<dl class="docutils">
+<dt>type:</dt>
+<dd>The type of resource: DiskResource, FileResource, MapResource,
+MemoryResource, PixelsResource, ThreadsResource, WidthResource,
+HeightResource.</dd>
+</dl>
+<p>o The maximum limit for the resource.</p>
+</div>
+</div>
+<div class="section" id="magicksetsamplingfactors">
+<h1><a class="toc-backref" href="#id666">MagickSetSamplingFactors</a></h1>
+<div class="section" id="id405">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetSamplingFactors( MagickWand *wand, const unsigned long number_factors,
+ const double *sampling_factors );
+</pre>
+</div>
+<div class="section" id="id406">
+<h2>Description</h2>
+<p>MagickSetSamplingFactors() sets the image sampling factors.</p>
+<p>The format of the MagickSetSamplingFactors method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetSamplingFactors( MagickWand *wand, const unsigned long number_factors,
+ const double *sampling_factors );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>number_factoes:</dt>
+<dd>The number of factors.</dd>
+<dt>sampling_factors:</dt>
+<dd>An array of doubles representing the sampling factor
+for each color component (in RGB order).</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetsize">
+<h1><a class="toc-backref" href="#id667">MagickSetSize</a></h1>
+<div class="section" id="id407">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetSize( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id408">
+<h2>Description</h2>
+<p>MagickSetSize() sets the size of the magick wand. Set it before you
+read a raw image format such as RGB, GRAY, or CMYK.</p>
+<p>The format of the MagickSetSize method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetSize( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>columns:</dt>
+<dd>The width in pixels.</dd>
+<dt>height:</dt>
+<dd>The height in pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetimagewhitepoint">
+<h1><a class="toc-backref" href="#id668">MagickSetImageWhitePoint</a></h1>
+<div class="section" id="id409">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetImageWhitePoint( MagickWand *wand, const double x, const double y );
+</pre>
+</div>
+<div class="section" id="id410">
+<h2>Description</h2>
+<p>MagickSetImageWhitePoint() sets the image chromaticity white point.</p>
+<p>The format of the MagickSetImageWhitePoint method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetImageWhitePoint( MagickWand *wand, const double x, const double y );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>x:</dt>
+<dd>The white x-point.</dd>
+<dt>y:</dt>
+<dd>The white y-point.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksetpassphrase">
+<h1><a class="toc-backref" href="#id669">MagickSetPassphrase</a></h1>
+<div class="section" id="id411">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSetPassphrase( MagickWand *wand, const char *passphrase );
+</pre>
+</div>
+<div class="section" id="id412">
+<h2>Description</h2>
+<p>MagickSetPassphrase() sets the passphrase.</p>
+<p>The format of the MagickSetPassphrase method is:</p>
+<pre class="literal-block">
+unsigned int MagickSetPassphrase( MagickWand *wand, const char *passphrase );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>passphrase:</dt>
+<dd>The passphrase.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksharpenimage">
+<h1><a class="toc-backref" href="#id670">MagickSharpenImage</a></h1>
+<div class="section" id="id413">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSharpenImage( MagickWand *wand, const double radius, const double sigma );
+</pre>
+</div>
+<div class="section" id="id414">
+<h2>Description</h2>
+<p>MagickSharpenImage() sharpens an image. We convolve the image with a Gaussian
+operator of the given radius and standard deviation (sigma).
+For reasonable results, the radius should be larger than sigma. Use a
+radius of 0 and SharpenImage() selects a suitable radius for you.</p>
+<p>The format of the MagickSharpenImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickSharpenImage( MagickWand *wand, const double radius, const double sigma );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickshaveimage">
+<h1><a class="toc-backref" href="#id671">MagickShaveImage</a></h1>
+<div class="section" id="id415">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickShaveImage( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows );
+</pre>
+</div>
+<div class="section" id="id416">
+<h2>Description</h2>
+<p>MagickShaveImage() shaves pixels from the image edges. It allocates the
+memory necessary for the new Image structure and returns a pointer to the
+new image.</p>
+<p>The format of the MagickShaveImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickShaveImage( MagickWand *wand, const unsigned long columns,
+ const unsigned long rows );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>columns:</dt>
+<dd>The number of columns in the scaled image.</dd>
+<dt>rows:</dt>
+<dd>The number of rows in the scaled image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickshearimage">
+<h1><a class="toc-backref" href="#id672">MagickShearImage</a></h1>
+<div class="section" id="id417">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickShearImage( MagickWand *wand, const PixelWand *background,
+ const double x_shear, onst double y_shear );
+</pre>
+</div>
+<div class="section" id="id418">
+<h2>Description</h2>
+<p>MagickShearImage() slides one edge of an image along the X or Y axis,
+creating a parallelogram. An X direction shear slides an edge along the X
+axis, while a Y direction shear slides an edge along the Y axis. The amount
+of the shear is controlled by a shear angle. For X direction shears, x_shear
+is measured relative to the Y axis, and similarly, for Y direction shears
+y_shear is measured relative to the X axis. Empty triangles left over from
+shearing the image are filled with the background color.</p>
+<p>The format of the MagickShearImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickShearImage( MagickWand *wand, const PixelWand *background,
+ const double x_shear, onst double y_shear );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>background:</dt>
+<dd>The background pixel wand.</dd>
+<dt>x_shear:</dt>
+<dd>The number of degrees to shear the image.</dd>
+<dt>y_shear:</dt>
+<dd>The number of degrees to shear the image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksolarizeimage">
+<h1><a class="toc-backref" href="#id673">MagickSolarizeImage</a></h1>
+<div class="section" id="id419">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSolarizeImage( MagickWand *wand, const double threshold );
+</pre>
+</div>
+<div class="section" id="id420">
+<h2>Description</h2>
+<p>MagickSolarizeImage() applies a special effect to the image, similar to the
+effect achieved in a photo darkroom by selectively exposing areas of photo
+sensitive paper to light. Threshold ranges from 0 to MaxRGB and is a
+measure of the extent of the solarization.</p>
+<p>The format of the MagickSolarizeImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickSolarizeImage( MagickWand *wand, const double threshold );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>threshold:</dt>
+<dd>Define the extent of the solarization.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickspreadimage">
+<h1><a class="toc-backref" href="#id674">MagickSpreadImage</a></h1>
+<div class="section" id="id421">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSpreadImage( MagickWand *wand, const double radius );
+</pre>
+</div>
+<div class="section" id="id422">
+<h2>Description</h2>
+<p>MagickSpreadImage() is a special effects method that randomly displaces each
+pixel in a block defined by the radius parameter.</p>
+<p>The format of the MagickSpreadImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickSpreadImage( MagickWand *wand, const double radius );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>Choose a random pixel in a neighborhood of this extent.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicksteganoimage">
+<h1><a class="toc-backref" href="#id675">MagickSteganoImage</a></h1>
+<div class="section" id="id423">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickSteganoImage( MagickWand *wand, const MagickWand *watermark_wand,
+ const long offset );
+</pre>
+</div>
+<div class="section" id="id424">
+<h2>Description</h2>
+<p>Use MagickSteganoImage() to hide a digital watermark within the image.
+Recover the hidden watermark later to prove that the authenticity of
+an image. Offset defines the start position within the image to hide
+the watermark.</p>
+<p>The format of the MagickSteganoImage method is:</p>
+<pre class="literal-block">
+MagickWand *MagickSteganoImage( MagickWand *wand, const MagickWand *watermark_wand,
+ const long offset );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>watermark_wand:</dt>
+<dd>The watermark wand.</dd>
+<dt>offset:</dt>
+<dd>Start hiding at this offset into the image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickstereoimage">
+<h1><a class="toc-backref" href="#id676">MagickStereoImage</a></h1>
+<div class="section" id="id425">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickStereoImage( MagickWand *wand, const MagickWand *offset_wand );
+</pre>
+</div>
+<div class="section" id="id426">
+<h2>Description</h2>
+<p>MagickStereoImage() composites two images and produces a single image that
+is the composite of a left and right image of a stereo pair</p>
+<p>The format of the MagickStereoImage method is:</p>
+<pre class="literal-block">
+MagickWand *MagickStereoImage( MagickWand *wand, const MagickWand *offset_wand );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>offset_wand:</dt>
+<dd>Another image wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickstripimage">
+<h1><a class="toc-backref" href="#id677">MagickStripImage</a></h1>
+<div class="section" id="id427">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickStripImage( MagickWand *wand );
+</pre>
+</div>
+<div class="section" id="id428">
+<h2>Description</h2>
+<p>MagickStripImage() removes all profiles and text attributes from the image.</p>
+<p>The format of the MagickStripImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickStripImage( MagickWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickswirlimage">
+<h1><a class="toc-backref" href="#id678">MagickSwirlImage</a></h1>
+<div class="section" id="id429">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickSwirlImage( MagickWand *wand, const double degrees );
+</pre>
+</div>
+<div class="section" id="id430">
+<h2>Description</h2>
+<p>MagickSwirlImage() swirls the pixels about the center of the image, where
+degrees indicates the sweep of the arc through which each pixel is moved.
+You get a more dramatic effect as the degrees move from 1 to 360.</p>
+<p>The format of the MagickSwirlImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickSwirlImage( MagickWand *wand, const double degrees );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>degrees:</dt>
+<dd>Define the tightness of the swirling effect.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicktextureimage">
+<h1><a class="toc-backref" href="#id679">MagickTextureImage</a></h1>
+<div class="section" id="id431">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickTextureImage( MagickWand *wand, const MagickWand *texture_wand );
+</pre>
+</div>
+<div class="section" id="id432">
+<h2>Description</h2>
+<p>MagickTextureImage() repeatedly tiles the texture image across and down the
+image canvas.</p>
+<p>The format of the MagickTextureImage method is:</p>
+<pre class="literal-block">
+MagickWand *MagickTextureImage( MagickWand *wand, const MagickWand *texture_wand );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>texture_wand:</dt>
+<dd>The texture wand</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickthresholdimage">
+<h1><a class="toc-backref" href="#id680">MagickThresholdImage</a></h1>
+<div class="section" id="id433">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickThresholdImage( MagickWand *wand, const double threshold );
+</pre>
+</div>
+<div class="section" id="id434">
+<h2>Description</h2>
+<p>MagickThresholdImage() changes the value of individual pixels based on
+the intensity of each pixel compared to threshold. The result is a
+high-contrast, two color image.</p>
+<p>The format of the MagickThresholdImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickThresholdImage( MagickWand *wand, const double threshold );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>threshold:</dt>
+<dd>Define the threshold value.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickthresholdimagechannel">
+<h1><a class="toc-backref" href="#id681">MagickThresholdImageChannel</a></h1>
+<div class="section" id="id435">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickThresholdImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double threshold );
+</pre>
+</div>
+<div class="section" id="id436">
+<h2>Description</h2>
+<p>MagickThresholdImageChannel() changes the value of individual pixel
+component based on the intensity of each pixel compared to threshold. The
+result is a high-contrast, two color image.</p>
+<p>The format of the MagickThresholdImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickThresholdImageChannel( MagickWand *wand, const <a class="reference external" href="../api/types.html#channeltype">ChannelType</a> channel,
+ const double threshold );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>channel:</dt>
+<dd>The channel.</dd>
+<dt>threshold:</dt>
+<dd>Define the threshold value.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicktintimage">
+<h1><a class="toc-backref" href="#id682">MagickTintImage</a></h1>
+<div class="section" id="id437">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickTintImage( MagickWand *wand, const PixelWand *tint,
+ const PixelWand *opacity );
+</pre>
+</div>
+<div class="section" id="id438">
+<h2>Description</h2>
+<p>MagickTintImage() applies a color vector to each pixel in the image. The
+length of the vector is 0 for black and white and at its maximum for the
+midtones. The vector weighting function is
+f(x)=(1-(4.0*((x-0.5)*(x-0.5)))).</p>
+<p>The format of the MagickTintImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickTintImage( MagickWand *wand, const PixelWand *tint,
+ const PixelWand *opacity );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>tint:</dt>
+<dd>The tint pixel wand.</dd>
+<dt>opacity:</dt>
+<dd>The opacity pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicktransformimage">
+<h1><a class="toc-backref" href="#id683">MagickTransformImage</a></h1>
+<div class="section" id="id439">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand *MagickTransformImage( MagickWand *wand, const char *crop,
+ const char *geometry );
+</pre>
+</div>
+<div class="section" id="id440">
+<h2>Description</h2>
+<p>MagickTransformImage() is a convenience method that behaves like
+MagickResizeImage() or MagickCropImage() but accepts scaling and/or cropping
+information as a region geometry specification. If the operation fails, the
+original image handle is returned.</p>
+<p>The format of the MagickTransformImage method is:</p>
+<pre class="literal-block">
+MagickWand *MagickTransformImage( MagickWand *wand, const char *crop,
+ const char *geometry );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>crop:</dt>
+<dd>A crop geometry string. This geometry defines a subregion of the
+image to crop.</dd>
+<dt>geometry:</dt>
+<dd>An image geometry string. This geometry defines the final
+size of the image.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicktransparentimage">
+<h1><a class="toc-backref" href="#id684">MagickTransparentImage</a></h1>
+<div class="section" id="id441">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickTransparentImage( MagickWand *wand, const PixelWand *target,
+ const unsigned int opacity, const double fuzz );
+</pre>
+</div>
+<div class="section" id="id442">
+<h2>Description</h2>
+<p>MagickTransparentImage() changes any pixel that matches color with the color
+defined by fill.</p>
+<p>The format of the MagickTransparentImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickTransparentImage( MagickWand *wand, const PixelWand *target,
+ const unsigned int opacity, const double fuzz );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>target:</dt>
+<dd>Change this target color to specified opacity value within
+the image.</dd>
+<dt>opacity:</dt>
+<dd>The replacement opacity value.</dd>
+<dt>fuzz:</dt>
+<dd>By default target must match a particular pixel color
+exactly. However, in many cases two colors may differ by a small amount.
+The fuzz member of image defines how much tolerance is acceptable to
+consider two colors as the same. For example, set fuzz to 10 and the
+color red at intensities of 100 and 102 respectively are now interpreted
+as the same color for the purposes of the floodfill.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magicktrimimage">
+<h1><a class="toc-backref" href="#id685">MagickTrimImage</a></h1>
+<div class="section" id="id443">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickTrimImage( MagickWand *wand, const double fuzz );
+</pre>
+</div>
+<div class="section" id="id444">
+<h2>Description</h2>
+<p>MagickTrimImage() remove edges that are the background color from the image.</p>
+<p>The format of the MagickTrimImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickTrimImage( MagickWand *wand, const double fuzz );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>fuzz:</dt>
+<dd>By default target must match a particular pixel color
+exactly. However, in many cases two colors may differ by a small amount.
+The fuzz member of image defines how much tolerance is acceptable to
+consider two colors as the same. For example, set fuzz to 10 and the
+color red at intensities of 100 and 102 respectively are now interpreted
+as the same color for the purposes of the floodfill.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickunsharpmaskimage">
+<h1><a class="toc-backref" href="#id686">MagickUnsharpMaskImage</a></h1>
+<div class="section" id="id445">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickUnsharpMaskImage( MagickWand *wand, const double radius, const double sigma,
+ const double amount, const double threshold );
+</pre>
+</div>
+<div class="section" id="id446">
+<h2>Description</h2>
+<p>MagickUnsharpMaskImage() sharpens an image. We convolve the image with a
+Gaussian operator of the given radius and standard deviation (sigma).
+For reasonable results, radius should be larger than sigma. Use a radius
+of 0 and UnsharpMaskImage() selects a suitable radius for you.</p>
+<p>The format of the MagickUnsharpMaskImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickUnsharpMaskImage( MagickWand *wand, const double radius, const double sigma,
+ const double amount, const double threshold );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>radius:</dt>
+<dd>The radius of the Gaussian, in pixels, not counting the center
+pixel.</dd>
+<dt>sigma:</dt>
+<dd>The standard deviation of the Gaussian, in pixels.</dd>
+<dt>amount:</dt>
+<dd>The percentage of the difference between the original and the
+blur image that is added back into the original.</dd>
+<dt>threshold:</dt>
+<dd>The threshold in pixels needed to apply the diffence amount.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickwaveimage">
+<h1><a class="toc-backref" href="#id687">MagickWaveImage</a></h1>
+<div class="section" id="id447">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickWaveImage( MagickWand *wand, const double amplitude,
+ const double wave_length );
+</pre>
+</div>
+<div class="section" id="id448">
+<h2>Description</h2>
+<p>MagickWaveImage() creates a &quot;ripple&quot; effect in the image by shifting
+the pixels vertically along a sine wave whose amplitude and wavelength
+is specified by the given parameters.</p>
+<p>The format of the MagickWaveImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickWaveImage( MagickWand *wand, const double amplitude,
+ const double wave_length );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>amplitude, wave_length:</dt>
+<dd>Define the amplitude and wave length of the
+sine wave.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickwhitethresholdimage">
+<h1><a class="toc-backref" href="#id688">MagickWhiteThresholdImage</a></h1>
+<div class="section" id="id449">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickWhiteThresholdImage( MagickWand *wand, const PixelWand *threshold );
+</pre>
+</div>
+<div class="section" id="id450">
+<h2>Description</h2>
+<p>MagickWhiteThresholdImage() is like ThresholdImage() but forces all pixels
+above the threshold into white while leaving all pixels below the threshold
+unchanged.</p>
+<p>The format of the MagickWhiteThresholdImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickWhiteThresholdImage( MagickWand *wand, const PixelWand *threshold );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>threshold:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickwriteimage">
+<h1><a class="toc-backref" href="#id689">MagickWriteImage</a></h1>
+<div class="section" id="id451">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickWriteImage( MagickWand *wand, const char *filename );
+</pre>
+</div>
+<div class="section" id="id452">
+<h2>Description</h2>
+<p>MagickWriteImage() writes an image.</p>
+<p>The format of the MagickWriteImage method is:</p>
+<pre class="literal-block">
+unsigned int MagickWriteImage( MagickWand *wand, const char *filename );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>filename:</dt>
+<dd>The image filename.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickwriteimagesfile">
+<h1><a class="toc-backref" href="#id690">MagickWriteImagesFile</a></h1>
+<div class="section" id="id453">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickWriteImagesFile( MagickWand *wand, FILE *file, const unsigned int adjoin );
+</pre>
+</div>
+<div class="section" id="id454">
+<h2>Description</h2>
+<p>MagickWriteImagesFile() writes an image or image sequence to a stdio
+FILE handle. This may be used to append an encoded image to an already
+existing appended image sequence if the file seek position is at the end
+of an existing file.</p>
+<p>The format of the MagickWriteImages method is:</p>
+<pre class="literal-block">
+unsigned int MagickWriteImagesFile( MagickWand *wand, FILE *file, const unsigned int adjoin );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>file:</dt>
+<dd>The open (and positioned) file handle.</dd>
+<dt>adjoin:</dt>
+<dd>join images into a single multi-image file.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickwriteimageblob">
+<h1><a class="toc-backref" href="#id691">MagickWriteImageBlob</a></h1>
+<div class="section" id="id455">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned char *MagickWriteImageBlob( MagickWand *wand, size_t *length );
+</pre>
+</div>
+<div class="section" id="id456">
+<h2>Description</h2>
+<p>MagickWriteImageBlob() implements direct to memory image formats. It
+returns the image as a blob (a formatted &quot;file&quot; in memory) and its
+length, starting from the current position in the image sequence.
+Use MagickSetImageFormat() to set the format to write to the blob
+(GIF, JPEG, PNG, etc.).</p>
+<p>Use MagickResetIterator() on the wand if it is desired to write
+a sequence from the beginning and the iterator is not currently
+at the beginning.</p>
+<p>The format of the MagickWriteImageBlob method is:</p>
+<pre class="literal-block">
+unsigned char *MagickWriteImageBlob( MagickWand *wand, size_t *length );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>length:</dt>
+<dd>The length of the blob.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickwriteimagefile">
+<h1><a class="toc-backref" href="#id692">MagickWriteImageFile</a></h1>
+<div class="section" id="id457">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickWriteImageFile( MagickWand *wand, FILE *file );
+</pre>
+</div>
+<div class="section" id="id458">
+<h2>Description</h2>
+<p>MagickWriteImageFile() writes an image to an open file descriptor.</p>
+<p>The format of the MagickWandToFile method is:</p>
+<pre class="literal-block">
+unsigned int MagickWriteImageFile( MagickWand *wand, FILE *file );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>file:</dt>
+<dd>The file descriptor.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="magickwriteimages">
+<h1><a class="toc-backref" href="#id693">MagickWriteImages</a></h1>
+<div class="section" id="id459">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int MagickWriteImages( MagickWand *wand, const char *filename,
+ const unsigned int adjoin );
+</pre>
+</div>
+<div class="section" id="id460">
+<h2>Description</h2>
+<p>MagickWriteImages() writes an image or image sequence. If the wand
+represents an image sequence, then it is written starting at the first
+frame in the sequence.</p>
+<p>The format of the MagickWriteImages method is:</p>
+<pre class="literal-block">
+unsigned int MagickWriteImages( MagickWand *wand, const char *filename,
+ const unsigned int adjoin );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The magick wand.</dd>
+<dt>filename:</dt>
+<dd>The image filename.</dd>
+<dt>adjoin:</dt>
+<dd>join images into a single multi-image file.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="newmagickwand">
+<h1><a class="toc-backref" href="#id694">NewMagickWand</a></h1>
+<div class="section" id="id461">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+MagickWand NewMagickWand( void );
+</pre>
+</div>
+<div class="section" id="id462">
+<h2>Description</h2>
+<p>NewMagickWand() returns a wand required for all other methods in the API.</p>
+<p>The format of the NewMagickWand method is:</p>
+<pre class="literal-block">
+MagickWand NewMagickWand( void );
+</pre>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/wand/pixel_wand.html b/www/wand/pixel_wand.html
new file mode 100644
index 0000000..05ae709
--- /dev/null
+++ b/www/wand/pixel_wand.html
@@ -0,0 +1,1087 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>pixel_wand</title>
+<link rel="stylesheet" href="../docutils-api.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="pixel-wand">
+<h1 class="title">pixel_wand</h1>
+<h2 class="subtitle" id="wand-pixel-access-interfaces">Wand pixel access interfaces</h2>
+
+<div class="contents topic" id="contents">
+<p class="topic-title first">Contents</p>
+<ul class="simple">
+<li><a class="reference internal" href="#clonepixelwand" id="id85">ClonePixelWand</a></li>
+<li><a class="reference internal" href="#clonepixelwands" id="id86">ClonePixelWands</a></li>
+<li><a class="reference internal" href="#destroypixelwand" id="id87">DestroyPixelWand</a></li>
+<li><a class="reference internal" href="#newpixelwand" id="id88">NewPixelWand</a></li>
+<li><a class="reference internal" href="#newpixelwands" id="id89">NewPixelWands</a></li>
+<li><a class="reference internal" href="#pixelgetexception" id="id90">PixelGetException</a></li>
+<li><a class="reference internal" href="#pixelgetblack" id="id91">PixelGetBlack</a></li>
+<li><a class="reference internal" href="#pixelgetblackquantum" id="id92">PixelGetBlackQuantum</a></li>
+<li><a class="reference internal" href="#pixelgetblue" id="id93">PixelGetBlue</a></li>
+<li><a class="reference internal" href="#pixelgetbluequantum" id="id94">PixelGetBlueQuantum</a></li>
+<li><a class="reference internal" href="#pixelgetcolorasstring" id="id95">PixelGetColorAsString</a></li>
+<li><a class="reference internal" href="#pixelgetcolorcount" id="id96">PixelGetColorCount</a></li>
+<li><a class="reference internal" href="#pixelgetcyan" id="id97">PixelGetCyan</a></li>
+<li><a class="reference internal" href="#pixelgetcyanquantum" id="id98">PixelGetCyanQuantum</a></li>
+<li><a class="reference internal" href="#pixelgetgreen" id="id99">PixelGetGreen</a></li>
+<li><a class="reference internal" href="#pixelgetgreenquantum" id="id100">PixelGetGreenQuantum</a></li>
+<li><a class="reference internal" href="#pixelgetmagenta" id="id101">PixelGetMagenta</a></li>
+<li><a class="reference internal" href="#pixelgetmagentaquantum" id="id102">PixelGetMagentaQuantum</a></li>
+<li><a class="reference internal" href="#pixelgetopacity" id="id103">PixelGetOpacity</a></li>
+<li><a class="reference internal" href="#pixelgetopacityquantum" id="id104">PixelGetOpacityQuantum</a></li>
+<li><a class="reference internal" href="#pixelgetred" id="id105">PixelGetRed</a></li>
+<li><a class="reference internal" href="#pixelgetredquantum" id="id106">PixelGetRedQuantum</a></li>
+<li><a class="reference internal" href="#pixelgetyellow" id="id107">PixelGetYellow</a></li>
+<li><a class="reference internal" href="#pixelgetyellowquantum" id="id108">PixelGetYellowQuantum</a></li>
+<li><a class="reference internal" href="#pixelsetblack" id="id109">PixelSetBlack</a></li>
+<li><a class="reference internal" href="#pixelsetblackquantum" id="id110">PixelSetBlackQuantum</a></li>
+<li><a class="reference internal" href="#pixelsetblue" id="id111">PixelSetBlue</a></li>
+<li><a class="reference internal" href="#pixelsetbluequantum" id="id112">PixelSetBlueQuantum</a></li>
+<li><a class="reference internal" href="#pixelsetcolor" id="id113">PixelSetColor</a></li>
+<li><a class="reference internal" href="#pixelsetcolorcount" id="id114">PixelSetColorCount</a></li>
+<li><a class="reference internal" href="#pixelsetcyan" id="id115">PixelSetCyan</a></li>
+<li><a class="reference internal" href="#pixelsetcyanquantum" id="id116">PixelSetCyanQuantum</a></li>
+<li><a class="reference internal" href="#pixelsetgreen" id="id117">PixelSetGreen</a></li>
+<li><a class="reference internal" href="#pixelsetgreenquantum" id="id118">PixelSetGreenQuantum</a></li>
+<li><a class="reference internal" href="#pixelsetmagenta" id="id119">PixelSetMagenta</a></li>
+<li><a class="reference internal" href="#pixelsetmagentaquantum" id="id120">PixelSetMagentaQuantum</a></li>
+<li><a class="reference internal" href="#pixelsetopacity" id="id121">PixelSetOpacity</a></li>
+<li><a class="reference internal" href="#pixelsetopacityquantum" id="id122">PixelSetOpacityQuantum</a></li>
+<li><a class="reference internal" href="#pixelsetquantumcolor" id="id123">PixelSetQuantumColor</a></li>
+<li><a class="reference internal" href="#pixelsetred" id="id124">PixelSetRed</a></li>
+<li><a class="reference internal" href="#pixelsetredquantum" id="id125">PixelSetRedQuantum</a></li>
+<li><a class="reference internal" href="#pixelsetyellow" id="id126">PixelSetYellow</a></li>
+<li><a class="reference internal" href="#pixelsetyellowquantum" id="id127">PixelSetYellowQuantum</a></li>
+</ul>
+</div>
+<div class="section" id="clonepixelwand">
+<h1><a class="toc-backref" href="#id85">ClonePixelWand</a></h1>
+<div class="section" id="synopsis">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+PixelWand *ClonePixelWand( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="description">
+<h2>Description</h2>
+<p>ClonePixelWand() creates an exact copy of a PixelWand. PixelWand may not be
+a null pointer.</p>
+<p>The format of the ClonePixelWand method is:</p>
+<pre class="literal-block">
+PixelWand *ClonePixelWand( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand to clone.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="clonepixelwands">
+<h1><a class="toc-backref" href="#id86">ClonePixelWands</a></h1>
+<div class="section" id="id1">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+PixelWand ** ClonePixelWands( const PixelWand ** wands, const unsigned long number_wands );
+</pre>
+</div>
+<div class="section" id="id2">
+<h2>Description</h2>
+<p>ClonePixelWands creates a deep-copy an array of PixelWands.</p>
+<p>The format of the ClonePixelWands method is:</p>
+<pre class="literal-block">
+PixelWand ** ClonePixelWands( const PixelWand ** wands, const unsigned long number_wands );
+</pre>
+<dl class="docutils">
+<dt>wands:</dt>
+<dd>The pixel wands to clone.</dd>
+<dt>number_wands:</dt>
+<dd>The number of wands in the array</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="destroypixelwand">
+<h1><a class="toc-backref" href="#id87">DestroyPixelWand</a></h1>
+<div class="section" id="id3">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int DestroyPixelWand( PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id4">
+<h2>Description</h2>
+<p>DestroyPixelWand() deallocates resources associated with a PixelWand.</p>
+<p>The format of the DestroyPixelWand method is:</p>
+<pre class="literal-block">
+unsigned int DestroyPixelWand( PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="newpixelwand">
+<h1><a class="toc-backref" href="#id88">NewPixelWand</a></h1>
+<div class="section" id="id5">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+PixelWand NewPixelWand( void );
+</pre>
+</div>
+<div class="section" id="id6">
+<h2>Description</h2>
+<p>NewPixelWand() returns a new pixel wand.</p>
+<p>The format of the NewPixelWand method is:</p>
+<pre class="literal-block">
+PixelWand NewPixelWand( void );
+</pre>
+</div>
+</div>
+<div class="section" id="newpixelwands">
+<h1><a class="toc-backref" href="#id89">NewPixelWands</a></h1>
+<div class="section" id="id7">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+PixelWand NewPixelWands( const unsigned long number_wands );
+</pre>
+</div>
+<div class="section" id="id8">
+<h2>Description</h2>
+<p>NewPixelWands() returns an array of pixel wands.</p>
+<p>The format of the NewPixelWand method is:</p>
+<pre class="literal-block">
+PixelWand NewPixelWands( const unsigned long number_wands );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>number_wands:</dt>
+<dd>The number of wands.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetexception">
+<h1><a class="toc-backref" href="#id90">PixelGetException</a></h1>
+<div class="section" id="id9">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelGetException( PixelWand *wand, char ** description );
+</pre>
+</div>
+<div class="section" id="id10">
+<h2>Description</h2>
+<p>PixelGetException() returns the severity, reason, and description of any
+error that occurs when using the pixel wand methods.</p>
+<p>The format of the PixelGetException method is:</p>
+<pre class="literal-block">
+unsigned int PixelGetException( PixelWand *wand, char ** description );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>description:</dt>
+<dd>A description of the error.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetblack">
+<h1><a class="toc-backref" href="#id91">PixelGetBlack</a></h1>
+<div class="section" id="id11">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double PixelGetBlack( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id12">
+<h2>Description</h2>
+<p>PixelGetBlack() returns the normalized black color of the pixel wand.</p>
+<p>The format of the PixelGetBlack method is:</p>
+<pre class="literal-block">
+double PixelGetBlack( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetblackquantum">
+<h1><a class="toc-backref" href="#id92">PixelGetBlackQuantum</a></h1>
+<div class="section" id="id13">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetBlackQuantum( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id14">
+<h2>Description</h2>
+<p>PixelGetBlackQuantum() returns the black color of the pixel wand. The
+color is in the range of [0..MaxRGB]</p>
+<p>The format of the PixelGetBlackQuantum method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetBlackQuantum( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetblue">
+<h1><a class="toc-backref" href="#id93">PixelGetBlue</a></h1>
+<div class="section" id="id15">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double PixelGetBlue( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id16">
+<h2>Description</h2>
+<p>PixelGetBlue(const) returns the normalized blue color of the pixel wand.</p>
+<p>The format of the PixelGetBlue method is:</p>
+<pre class="literal-block">
+double PixelGetBlue( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetbluequantum">
+<h1><a class="toc-backref" href="#id94">PixelGetBlueQuantum</a></h1>
+<div class="section" id="id17">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetBlueQuantum( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id18">
+<h2>Description</h2>
+<p>PixelGetBlueQuantum(const ) returns the blue color of the pixel wand. The
+color is in the range of [0..MaxRGB]</p>
+<p>The format of the PixelGetBlueQuantum method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetBlueQuantum( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetcolorasstring">
+<h1><a class="toc-backref" href="#id95">PixelGetColorAsString</a></h1>
+<div class="section" id="id19">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+char *PixelGetColorAsString( PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id20">
+<h2>Description</h2>
+<p>PixelGetColorAsString() gets the color of the pixel wand.</p>
+<p>The format of the PixelGetColorAsString method is:</p>
+<pre class="literal-block">
+char *PixelGetColorAsString( PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetcolorcount">
+<h1><a class="toc-backref" href="#id96">PixelGetColorCount</a></h1>
+<div class="section" id="id21">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned long PixelGetColorCount( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id22">
+<h2>Description</h2>
+<p>PixelGetColorCount() returns the color count associated with this color.</p>
+<p>The format of the PixelGetColorCount method is:</p>
+<pre class="literal-block">
+unsigned long PixelGetColorCount( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetcyan">
+<h1><a class="toc-backref" href="#id97">PixelGetCyan</a></h1>
+<div class="section" id="id23">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double PixelGetCyan( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id24">
+<h2>Description</h2>
+<p>PixelGetCyan() returns the normalized cyan color of the pixel wand.</p>
+<p>The format of the PixelGetCyan method is:</p>
+<pre class="literal-block">
+double PixelGetCyan( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetcyanquantum">
+<h1><a class="toc-backref" href="#id98">PixelGetCyanQuantum</a></h1>
+<div class="section" id="id25">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetCyanQuantum( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id26">
+<h2>Description</h2>
+<p>PixelGetCyanQuantum() returns the cyan color of the pixel wand. The color
+is in the range of [0..MaxRGB]</p>
+<p>The format of the PixelGetCyanQuantum method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetCyanQuantum( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetgreen">
+<h1><a class="toc-backref" href="#id99">PixelGetGreen</a></h1>
+<div class="section" id="id27">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double PixelGetGreen( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id28">
+<h2>Description</h2>
+<p>PixelGetGreen(const ) returns the normalized green color of the pixel wand.</p>
+<p>The format of the PixelGetGreen method is:</p>
+<pre class="literal-block">
+double PixelGetGreen( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetgreenquantum">
+<h1><a class="toc-backref" href="#id100">PixelGetGreenQuantum</a></h1>
+<div class="section" id="id29">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetGreenQuantum( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id30">
+<h2>Description</h2>
+<p>PixelGetGreenQuantum(const ) returns the green color of the pixel wand. The
+color is in the range of [0..MaxRGB]</p>
+<p>The format of the PixelGetGreenQuantum method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetGreenQuantum( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetmagenta">
+<h1><a class="toc-backref" href="#id101">PixelGetMagenta</a></h1>
+<div class="section" id="id31">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double PixelGetMagenta( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id32">
+<h2>Description</h2>
+<p>PixelGetMagenta() returns the normalized magenta color of the pixel wand.</p>
+<p>The format of the PixelGetMagenta method is:</p>
+<pre class="literal-block">
+double PixelGetMagenta( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetmagentaquantum">
+<h1><a class="toc-backref" href="#id102">PixelGetMagentaQuantum</a></h1>
+<div class="section" id="id33">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetMagentaQuantum( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id34">
+<h2>Description</h2>
+<p>PixelGetMagentaQuantum() returns the magenta color of the pixel wand. The
+color is in the range of [0..MaxRGB]</p>
+<p>The format of the PixelGetMagentaQuantum method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetMagentaQuantum( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetopacity">
+<h1><a class="toc-backref" href="#id103">PixelGetOpacity</a></h1>
+<div class="section" id="id35">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double PixelGetOpacity( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id36">
+<h2>Description</h2>
+<p>PixelGetOpacity(const ) returns the normalized opacity color of the pixel
+wand.</p>
+<p>The format of the PixelGetOpacity method is:</p>
+<pre class="literal-block">
+double PixelGetOpacity( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetopacityquantum">
+<h1><a class="toc-backref" href="#id104">PixelGetOpacityQuantum</a></h1>
+<div class="section" id="id37">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetOpacityQuantum( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id38">
+<h2>Description</h2>
+<p>PixelGetOpacityQuantum(const ) returns the opacity color of the pixel wand.
+The color is in the range of [0..MaxRGB]</p>
+<p>The format of the PixelGetOpacityQuantum method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetOpacityQuantum( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetred">
+<h1><a class="toc-backref" href="#id105">PixelGetRed</a></h1>
+<div class="section" id="id39">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double PixelGetRed( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id40">
+<h2>Description</h2>
+<p>PixelGetRed(const ) returns the normalized red color of the pixel wand.</p>
+<p>The format of the PixelGetRed method is:</p>
+<pre class="literal-block">
+double PixelGetRed( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetredquantum">
+<h1><a class="toc-backref" href="#id106">PixelGetRedQuantum</a></h1>
+<div class="section" id="id41">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetRedQuantum( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id42">
+<h2>Description</h2>
+<p>PixelGetRedQuantum(const ) returns the red color of the pixel wand. The
+color is in the range of [0..MaxRGB]</p>
+<p>The format of the PixelGetRedQuantum method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetRedQuantum( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetyellow">
+<h1><a class="toc-backref" href="#id107">PixelGetYellow</a></h1>
+<div class="section" id="id43">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+double PixelGetYellow( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id44">
+<h2>Description</h2>
+<p>PixelGetYellow() returns the normalized yellow color of the pixel wand.</p>
+<p>The format of the PixelGetYellow method is:</p>
+<pre class="literal-block">
+double PixelGetYellow( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelgetyellowquantum">
+<h1><a class="toc-backref" href="#id108">PixelGetYellowQuantum</a></h1>
+<div class="section" id="id45">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetYellowQuantum( const PixelWand *wand );
+</pre>
+</div>
+<div class="section" id="id46">
+<h2>Description</h2>
+<p>PixelGetYellowQuantum() returns the yellow color of the pixel wand. The
+color is in the range of [0..MaxRGB]</p>
+<p>The format of the PixelGetYellowQuantum method is:</p>
+<pre class="literal-block">
+<a class="reference external" href="../api/types.html#quantum">Quantum</a> PixelGetYellowQuantum( const PixelWand *wand );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetblack">
+<h1><a class="toc-backref" href="#id109">PixelSetBlack</a></h1>
+<div class="section" id="id47">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetBlack( PixelWand *wand, const double black );
+</pre>
+</div>
+<div class="section" id="id48">
+<h2>Description</h2>
+<p>PixelSetBlack() sets the normalized black color of the pixel wand.</p>
+<p>The format of the PixelSetBlack method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetBlack( PixelWand *wand, const double black );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>black:</dt>
+<dd>The black color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetblackquantum">
+<h1><a class="toc-backref" href="#id110">PixelSetBlackQuantum</a></h1>
+<div class="section" id="id49">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetBlackQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> black );
+</pre>
+</div>
+<div class="section" id="id50">
+<h2>Description</h2>
+<p>PixelSetBlackQuantum() sets the black color of the pixel wand. The color
+must be in the range of [0..MaxRGB]</p>
+<p>The format of the PixelSetBlackQuantum method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetBlackQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> black );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>black:</dt>
+<dd>The black color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetblue">
+<h1><a class="toc-backref" href="#id111">PixelSetBlue</a></h1>
+<div class="section" id="id51">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetBlue( PixelWand *wand, const double blue );
+</pre>
+</div>
+<div class="section" id="id52">
+<h2>Description</h2>
+<p>PixelSetBlue() sets the normalized blue color of the pixel wand.</p>
+<p>The format of the PixelSetBlue method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetBlue( PixelWand *wand, const double blue );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>blue:</dt>
+<dd>The blue color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetbluequantum">
+<h1><a class="toc-backref" href="#id112">PixelSetBlueQuantum</a></h1>
+<div class="section" id="id53">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetBlueQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> blue );
+</pre>
+</div>
+<div class="section" id="id54">
+<h2>Description</h2>
+<p>PixelSetBlueQuantum() sets the blue color of the pixel wand. The color must
+be in the range of [0..MaxRGB]</p>
+<p>The format of the PixelSetBlueQuantum method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetBlueQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> blue );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>blue:</dt>
+<dd>The blue color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetcolor">
+<h1><a class="toc-backref" href="#id113">PixelSetColor</a></h1>
+<div class="section" id="id55">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetColor( PixelWand *wand, const char *color );
+</pre>
+</div>
+<div class="section" id="id56">
+<h2>Description</h2>
+<p>PixelSetColor() sets the color of the pixel wand with a string (e.g.
+&quot;blue&quot;, &quot;#0000ff&quot;, &quot;rgb(0,0,255)&quot;, etc.).</p>
+<p>The format of the PixelSetColor method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetColor( PixelWand *wand, const char *color );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>color:</dt>
+<dd>The pixel wand color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetcolorcount">
+<h1><a class="toc-backref" href="#id114">PixelSetColorCount</a></h1>
+<div class="section" id="id57">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetColorCount( PixelWand *wand, const unsigned long count );
+</pre>
+</div>
+<div class="section" id="id58">
+<h2>Description</h2>
+<p>PixelSetColorCount() sets the color count of the pixel wand.</p>
+<p>The format of the PixelSetColorCount method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetColorCount( PixelWand *wand, const unsigned long count );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>count:</dt>
+<dd>The number of this particular color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetcyan">
+<h1><a class="toc-backref" href="#id115">PixelSetCyan</a></h1>
+<div class="section" id="id59">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetCyan( PixelWand *wand, const double cyan );
+</pre>
+</div>
+<div class="section" id="id60">
+<h2>Description</h2>
+<p>PixelSetCyan() sets the normalized cyan color of the pixel wand.</p>
+<p>The format of the PixelSetCyan method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetCyan( PixelWand *wand, const double cyan );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>cyan:</dt>
+<dd>The cyan color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetcyanquantum">
+<h1><a class="toc-backref" href="#id116">PixelSetCyanQuantum</a></h1>
+<div class="section" id="id61">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetCyanQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> cyan );
+</pre>
+</div>
+<div class="section" id="id62">
+<h2>Description</h2>
+<p>PixelSetCyanQuantum() sets the cyan color of the pixel wand. The color must
+be in the range of [0..MaxRGB]</p>
+<p>The format of the PixelSetCyanQuantum method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetCyanQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> cyan );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>cyan:</dt>
+<dd>The cyan color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetgreen">
+<h1><a class="toc-backref" href="#id117">PixelSetGreen</a></h1>
+<div class="section" id="id63">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetGreen( PixelWand *wand, const double green );
+</pre>
+</div>
+<div class="section" id="id64">
+<h2>Description</h2>
+<p>PixelSetGreen() sets the normalized green color of the pixel wand.</p>
+<p>The format of the PixelSetGreen method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetGreen( PixelWand *wand, const double green );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>green:</dt>
+<dd>The green color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetgreenquantum">
+<h1><a class="toc-backref" href="#id118">PixelSetGreenQuantum</a></h1>
+<div class="section" id="id65">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetGreenQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> green );
+</pre>
+</div>
+<div class="section" id="id66">
+<h2>Description</h2>
+<p>PixelSetGreenQuantum() sets the green color of the pixel wand. The color must
+be in the range of [0..MaxRGB]</p>
+<p>The format of the PixelSetGreenQuantum method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetGreenQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> green );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>green:</dt>
+<dd>The green color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetmagenta">
+<h1><a class="toc-backref" href="#id119">PixelSetMagenta</a></h1>
+<div class="section" id="id67">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetMagenta( PixelWand *wand, const double magenta );
+</pre>
+</div>
+<div class="section" id="id68">
+<h2>Description</h2>
+<p>PixelSetMagenta() sets the normalized magenta color of the pixel wand.</p>
+<p>The format of the PixelSetMagenta method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetMagenta( PixelWand *wand, const double magenta );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>magenta:</dt>
+<dd>The magenta color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetmagentaquantum">
+<h1><a class="toc-backref" href="#id120">PixelSetMagentaQuantum</a></h1>
+<div class="section" id="id69">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetMagentaQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> magenta );
+</pre>
+</div>
+<div class="section" id="id70">
+<h2>Description</h2>
+<p>PixelSetMagentaQuantum() sets the magenta color of the pixel wand. The
+color must be in the range of [0..MaxRGB]</p>
+<p>The format of the PixelSetMagentaQuantum method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetMagentaQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> magenta );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>magenta:</dt>
+<dd>The magenta color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetopacity">
+<h1><a class="toc-backref" href="#id121">PixelSetOpacity</a></h1>
+<div class="section" id="id71">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetOpacity( PixelWand *wand, const double opacity );
+</pre>
+</div>
+<div class="section" id="id72">
+<h2>Description</h2>
+<p>PixelSetOpacity() sets the normalized opacity color of the pixel wand.</p>
+<p>The format of the PixelSetOpacity method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetOpacity( PixelWand *wand, const double opacity );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>opacity:</dt>
+<dd>The opacity value.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetopacityquantum">
+<h1><a class="toc-backref" href="#id122">PixelSetOpacityQuantum</a></h1>
+<div class="section" id="id73">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetOpacityQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> opacity );
+</pre>
+</div>
+<div class="section" id="id74">
+<h2>Description</h2>
+<p>PixelSetOpacityQuantum() sets the opacity color of the pixel wand. The
+color must be in the range of [0..MaxRGB]</p>
+<p>The format of the PixelSetOpacityQuantum method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetOpacityQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> opacity );
+</pre>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>opacity:</dt>
+<dd>The opacity value.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetquantumcolor">
+<h1><a class="toc-backref" href="#id123">PixelSetQuantumColor</a></h1>
+<div class="section" id="id75">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+PixelSetQuantumColor( PixelWand *wand, <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *color );
+</pre>
+</div>
+<div class="section" id="id76">
+<h2>Description</h2>
+<p>PixelSetQuantumColor() sets the color of the pixel wand.</p>
+<p>The format of the PixelSetQuantumColor method is:</p>
+<pre class="literal-block">
+PixelSetQuantumColor( PixelWand *wand, <a class="reference external" href="../api/types.html#pixelpacket">PixelPacket</a> *color );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>color:</dt>
+<dd>The pixel wand color (expressed as a PixelPacket).</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetred">
+<h1><a class="toc-backref" href="#id124">PixelSetRed</a></h1>
+<div class="section" id="id77">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetRed( PixelWand *wand, const double red );
+</pre>
+</div>
+<div class="section" id="id78">
+<h2>Description</h2>
+<p>PixelSetRed() sets the normalized red color of the pixel wand.</p>
+<p>The format of the PixelSetRed method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetRed( PixelWand *wand, const double red );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>red:</dt>
+<dd>The red color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetredquantum">
+<h1><a class="toc-backref" href="#id125">PixelSetRedQuantum</a></h1>
+<div class="section" id="id79">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetRedQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> red );
+</pre>
+</div>
+<div class="section" id="id80">
+<h2>Description</h2>
+<p>PixelSetRedQuantum() sets the red color of the pixel wand. The color must
+be in the range of [0..MaxRGB]</p>
+<p>The format of the PixelSetRedQuantum method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetRedQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> red );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>red:</dt>
+<dd>The red color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetyellow">
+<h1><a class="toc-backref" href="#id126">PixelSetYellow</a></h1>
+<div class="section" id="id81">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetYellow( PixelWand *wand, const double yellow );
+</pre>
+</div>
+<div class="section" id="id82">
+<h2>Description</h2>
+<p>PixelSetYellow() sets the normalized yellow color of the pixel wand.</p>
+<p>The format of the PixelSetYellow method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetYellow( PixelWand *wand, const double yellow );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>yellow:</dt>
+<dd>The yellow color.</dd>
+</dl>
+</div>
+</div>
+<div class="section" id="pixelsetyellowquantum">
+<h1><a class="toc-backref" href="#id127">PixelSetYellowQuantum</a></h1>
+<div class="section" id="id83">
+<h2>Synopsis</h2>
+<pre class="literal-block">
+unsigned int PixelSetYellowQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> yellow );
+</pre>
+</div>
+<div class="section" id="id84">
+<h2>Description</h2>
+<p>PixelSetYellowQuantum() sets the yellow color of the pixel wand. The color
+must be in the range of [0..MaxRGB]</p>
+<p>The format of the PixelSetYellowQuantum method is:</p>
+<pre class="literal-block">
+unsigned int PixelSetYellowQuantum( PixelWand *wand, const <a class="reference external" href="../api/types.html#quantum">Quantum</a> yellow );
+</pre>
+<p>A description of each parameter follows:</p>
+<dl class="docutils">
+<dt>wand:</dt>
+<dd>The pixel wand.</dd>
+<dt>yellow:</dt>
+<dd>The yellow color.</dd>
+</dl>
+</div>
+</div>
+</div>
+</body>
+</html>
diff --git a/www/wand/wand.html b/www/wand/wand.html
new file mode 100644
index 0000000..2968f18
--- /dev/null
+++ b/www/wand/wand.html
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.13.1: http://docutils.sourceforge.net/" />
+<title>GraphicsMagick Wand C API</title>
+<link rel="stylesheet" href="../docutils-articles.css" type="text/css" />
+</head>
+<body>
+
+<div class="banner">
+<img src="../images/gm-107x76.png" alt="GraphicMagick logo" width="107" height="76" />
+<span class="title">GraphicsMagick</span>
+<form action="http://www.google.com/search">
+ <input type="hidden" name="domains" value="www.graphicsmagick.org" />
+ <input type="hidden" name="sitesearch" value="www.graphicsmagick.org" />
+ <span class="nowrap"><input type="text" name="q" size="25" maxlength="255" />&nbsp;<input type="submit" name="sa" value="Search" /></span>
+</form>
+</div>
+
+<div class="navmenu">
+<ul>
+<li><a href="../index.html">Home</a></li>
+<li><a href="../project.html">Project</a></li>
+<li><a href="../download.html">Download</a></li>
+<li><a href="../README.html">Install</a></li>
+<li><a href="../Hg.html">Source</a></li>
+<li><a href="../NEWS.html">News</a> </li>
+<li><a href="../utilities.html">Utilities</a></li>
+<li><a href="../programming.html">Programming</a></li>
+<li><a href="../reference.html">Reference</a></li>
+</ul>
+</div>
+<div class="document" id="graphicsmagick-wand-c-api">
+<h1 class="title">GraphicsMagick Wand C API</h1>
+
+<!-- -*- mode: rst -*- -->
+<!-- This text is in reStucturedText format, so it may look a bit odd. -->
+<!-- See http://docutils.sourceforge.net/rst.html for details. -->
+<p>The GraphicsMagick Wand C library provides a mid-level abstract C
+language programming interface for GraphicsMagick. It is originally
+based on the Wand API provided in ImageMagick as of August 2003.
+After August 2003, ImageMagick changed its license to one unusable by
+GraphicsMagick so this version of the Wand library is not completely
+in sync with the current ImageMagick version.</p>
+<p>The API is divided into a number of categories. While reading this
+documentation, please reference the <a class="reference external" href="../api/types.html">types</a> documentation as required:</p>
+<blockquote>
+<ul class="simple">
+<li><a class="reference external" href="drawing_wand.html">Drawing</a>: Wand vector drawing interfaces.</li>
+<li><a class="reference external" href="magick_wand.html">Magick</a>: Wand image processing interfaces</li>
+<li><a class="reference external" href="pixel_wand.html">Pixel</a>: Wand pixel access/update interfaces</li>
+</ul>
+</blockquote>
+<p>The following is a simple example program which (assuming the program
+name is <cite>rotate</cite>) is executed similar to <cite>rotate infile outfile</cite>. It
+reads from file <cite>infile</cite>, rotates the image 30 degrees using a black
+background, and writes the result to file <cite>outfile</cite>:</p>
+<pre class="literal-block">
+#include &lt;stdlib.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;wand/magick_wand.h&gt;
+
+int main(int argc,char **argv)
+{
+ MagickWand *magick_wand;
+ MagickPassFail status = MagickPass;
+ const char *infile, *outfile;
+
+ if (argc != 3)
+ {
+ fprintf(stderr,&quot;Usage: %s: infile outfile\n&quot;,argv[0]);
+ return 1;
+ }
+
+ infile=argv[1];
+ outfile=argv[2];
+
+ // Initialize GraphicsMagick API
+ InitializeMagick(*argv);
+
+ // Allocate Wand handle
+ magick_wand=NewMagickWand();
+
+ // Read input image file
+ if (status == MagickPass)
+ {
+ status = MagickReadImage(magick_wand,infile);
+ }
+
+ // Rotate image clockwise 30 degrees with black background
+ if (status == MagickPass)
+ {
+ PixelWand *background;
+ background=NewPixelWand();
+ PixelSetColor(background,&quot;#000000&quot;);
+ status = MagickRotateImage(magick_wand,background,30);
+ DestroyPixelWand(background);
+ }
+
+ // Write output file
+ if (status == MagickPass)
+ {
+ status = MagickWriteImage(magick_wand,outfile);
+ }
+
+ // Diagnose any error
+ if (status != MagickPass)
+ {
+ char *description;
+ ExceptionType severity;
+
+ description=MagickGetException(magick_wand,&amp;severity);
+ (void) fprintf(stderr,&quot;%.1024s (severity %d)\n&quot;,
+ description,severity);
+ }
+
+ // Release Wand handle
+ DestroyMagickWand(magick_wand);
+
+ // Destroy GraphicsMagick API
+ DestroyMagick();
+
+ return (status == MagickPass ? 0 : 1);
+}
+</pre>
+<p>To compile on Unix, the command looks something like this:</p>
+<pre class="literal-block">
+gcc -o demo demo.c -O `GraphicsMagickWand-config --cppflags --ldflags --libs`
+</pre>
+<p>The GraphicsMagickWand-config script reproduces the options which were used to
+compile the GraphicsMagick wand library. Using compatible options ensures that
+your program will compile and run.</p>
+<hr class="docutils" />
+<p>Copyright © GraphicsMagick Group 2009 - 2017</p>
+</div>
+</body>
+</html>
diff --git a/www/wand/wand.rst b/www/wand/wand.rst
new file mode 100644
index 0000000..cb63896
--- /dev/null
+++ b/www/wand/wand.rst
@@ -0,0 +1,115 @@
+.. -*- mode: rst -*-
+.. This text is in reStucturedText format, so it may look a bit odd.
+.. See http://docutils.sourceforge.net/rst.html for details.
+
+=========================
+GraphicsMagick Wand C API
+=========================
+
+.. _Drawing : drawing_wand.html
+.. _Magick : magick_wand.html
+.. _Pixel : pixel_wand.html
+.. _types: ../api/types.html
+
+The GraphicsMagick Wand C library provides a mid-level abstract C
+language programming interface for GraphicsMagick. It is originally
+based on the Wand API provided in ImageMagick as of August 2003.
+After August 2003, ImageMagick changed its license to one unusable by
+GraphicsMagick so this version of the Wand library is not completely
+in sync with the current ImageMagick version.
+
+The API is divided into a number of categories. While reading this
+documentation, please reference the types_ documentation as required:
+
+ * Drawing_: Wand vector drawing interfaces.
+ * Magick_: Wand image processing interfaces
+ * Pixel_: Wand pixel access/update interfaces
+
+The following is a simple example program which (assuming the program
+name is `rotate`) is executed similar to `rotate infile outfile`. It
+reads from file `infile`, rotates the image 30 degrees using a black
+background, and writes the result to file `outfile`::
+
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <wand/magick_wand.h>
+
+ int main(int argc,char **argv)
+ {
+ MagickWand *magick_wand;
+ MagickPassFail status = MagickPass;
+ const char *infile, *outfile;
+
+ if (argc != 3)
+ {
+ fprintf(stderr,"Usage: %s: infile outfile\n",argv[0]);
+ return 1;
+ }
+
+ infile=argv[1];
+ outfile=argv[2];
+
+ // Initialize GraphicsMagick API
+ InitializeMagick(*argv);
+
+ // Allocate Wand handle
+ magick_wand=NewMagickWand();
+
+ // Read input image file
+ if (status == MagickPass)
+ {
+ status = MagickReadImage(magick_wand,infile);
+ }
+
+ // Rotate image clockwise 30 degrees with black background
+ if (status == MagickPass)
+ {
+ PixelWand *background;
+ background=NewPixelWand();
+ PixelSetColor(background,"#000000");
+ status = MagickRotateImage(magick_wand,background,30);
+ DestroyPixelWand(background);
+ }
+
+ // Write output file
+ if (status == MagickPass)
+ {
+ status = MagickWriteImage(magick_wand,outfile);
+ }
+
+ // Diagnose any error
+ if (status != MagickPass)
+ {
+ char *description;
+ ExceptionType severity;
+
+ description=MagickGetException(magick_wand,&severity);
+ (void) fprintf(stderr,"%.1024s (severity %d)\n",
+ description,severity);
+ }
+
+ // Release Wand handle
+ DestroyMagickWand(magick_wand);
+
+ // Destroy GraphicsMagick API
+ DestroyMagick();
+
+ return (status == MagickPass ? 0 : 1);
+ }
+
+
+To compile on Unix, the command looks something like this::
+
+ gcc -o demo demo.c -O `GraphicsMagickWand-config --cppflags --ldflags --libs`
+
+The GraphicsMagickWand-config script reproduces the options which were used to
+compile the GraphicsMagick wand library. Using compatible options ensures that
+your program will compile and run.
+
+-------------------------------------------------------------------------------
+
+.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
+
+Copyright |copy| GraphicsMagick Group 2009 - 2017
+